summaryrefslogtreecommitdiff
path: root/rust/kernel/str.rs
AgeCommit message (Expand)Author
2025-11-17rust: str: replace `kernel::c_str!` with C-StringsTamir Duberstein
2025-10-22rust: replace `CStr` with `core::ffi::CStr`Tamir Duberstein
2025-09-02rust: block: use `NullTerminatedFormatter`Andreas Hindborg
2025-09-02rust: str: introduce `kstrtobool` functionAndreas Hindborg
2025-09-02rust: str: introduce `NullTerminatedFormatter`Andreas Hindborg
2025-09-02rust: str: expose `str::{Formatter, RawFormatter}` publicly.Andreas Hindborg
2025-09-02rust: str: allow `str::Formatter` to format into `&mut [u8]`.Andreas Hindborg
2025-09-02rust: str: normalize imports in `str.rs`Andreas Hindborg
2025-07-21rust: kernel: use `core::ffi::CStr` method namesTamir Duberstein
2025-07-21rust: str: add `CStr` methods matching `core::ffi::CStr`Tamir Duberstein
2025-07-21rust: str: remove unnecessary qualificationTamir Duberstein
2025-07-21rust: use `kernel::{fmt,prelude::fmt!}`Tamir Duberstein
2025-07-21rust: kernel: remove `fmt!`, fix clippy::uninlined-format-argsTamir Duberstein
2025-06-22rust: enable `clippy::ref_as_ptr` lintTamir Duberstein
2025-06-22rust: enable `clippy::as_underscore` lintTamir Duberstein
2025-06-22rust: enable `clippy::ptr_as_ptr` lintTamir Duberstein
2025-05-27rust: str: take advantage of the `-> Result` support in KUnit `#[test]`'sMiguel Ojeda
2025-05-27rust: str: simplify KUnit tests `format!` macroMiguel Ojeda
2025-05-27rust: str: convert `rusttest` tests into KUnitMiguel Ojeda
2025-05-23rust: use absolute paths in macros referencing core and kernelIgor Korotin
2025-05-20rust: str: fix typo in commentJihed Chaibi
2025-05-18Merge tag 'alloc-next-v6.16-2025-05-13' of https://github.com/Rust-for-Linux/...Miguel Ojeda
2025-05-07rust: clean Rust 1.88.0's `clippy::uninlined_format_args` lintMiguel Ojeda
2025-04-23rust: alloc: replace `Vec::set_len` with `inc_len`Tamir Duberstein
2025-03-20rust: str: implement `strip_prefix` for `BStr`Andreas Hindborg
2025-03-20rust: str: implement `AsRef<BStr>` for `[u8]` and `BStr`Andreas Hindborg
2025-03-20rust: str: implement `Index` for `BStr`Andreas Hindborg
2025-03-20rust: str: implement `PartialEq` for `BStr`Andreas Hindborg
2025-01-13rust: str: replace unwraps with question mark operatorsDaniel Sedlak
2025-01-10rust: kbuild: run Clippy for `rusttest` codeMiguel Ojeda
2024-12-16rust: cleanup unnecessary castsGary Guo
2024-11-10rust: use custom FFI integer typesGary Guo
2024-10-15rust: str: test: replace `alloc::format`Danilo Krummrich
2024-10-15rust: treewide: switch to the kernel `Vec` typeDanilo Krummrich
2024-10-07rust: enable `clippy::undocumented_unsafe_blocks` lintMiguel Ojeda
2024-05-05rust: kernel: remove redundant importsMiguel Ojeda
2024-04-16rust: kernel: remove usage of `allocator_api` unstable featureWedson Almeida Filho
2024-04-16rust: alloc: update `VecExt` to take allocation flagsWedson Almeida Filho
2024-04-16kbuild: use the upstream `alloc` crateWedson Almeida Filho
2024-04-02rust: str: add {make,to}_{upper,lower}case() to CStringDanilo Krummrich
2024-02-25rust: str: implement `Display` and `Debug` for `BStr`Yutaro Ohno
2024-02-18rust: str: move SAFETY comment in front of unsafe blockValentin Obst
2024-02-18rust: str: use `NUL` instead of 0 in doc commentsValentin Obst
2024-02-18rust: kernel: fix multiple typos in documentationValentin Obst
2023-12-13rust: kernel: str: Implement Debug for CStringAsahi Lina
2023-07-19rust: str: make doctests compilable/testableMiguel Ojeda
2023-05-31rust: str: add conversion from `CStr` to `CString`Alice Ryhl
2023-04-06rust: str: fix requierments->requirements typoPatrick Blass
2022-12-04rust: str: add `fmt!` macroWedson Almeida Filho
2022-12-04rust: str: add `CString` typeWedson Almeida Filho
at' width='100%'> -rw-r--r--Documentation/admin-guide/iostats.rst6
-rw-r--r--Documentation/admin-guide/kdump/kdump.rst10
-rw-r--r--Documentation/admin-guide/kdump/vmcoreinfo.rst8
-rw-r--r--Documentation/admin-guide/kernel-parameters.txt117
-rw-r--r--Documentation/admin-guide/media/fimc.rst2
-rw-r--r--Documentation/admin-guide/media/i2c-cardlist.rst2
-rw-r--r--Documentation/admin-guide/media/imx7.rst2
-rw-r--r--Documentation/admin-guide/media/omap3isp.rst2
-rw-r--r--Documentation/admin-guide/media/omap4_camera.rst2
-rw-r--r--Documentation/admin-guide/media/vimc.rst13
-rw-r--r--Documentation/admin-guide/mm/damon/usage.rst380
-rw-r--r--Documentation/admin-guide/mm/pagemap.rst2
-rw-r--r--Documentation/admin-guide/mm/zswap.rst22
-rw-r--r--Documentation/admin-guide/perf/index.rst1
-rw-r--r--Documentation/admin-guide/pm/amd-pstate.rst26
-rw-r--r--Documentation/admin-guide/pm/intel_uncore_frequency_scaling.rst60
-rw-r--r--Documentation/admin-guide/pm/working-state.rst1
-rw-r--r--Documentation/admin-guide/reporting-issues.rst73
-rw-r--r--Documentation/admin-guide/reporting-regressions.rst451
-rw-r--r--Documentation/admin-guide/sysctl/kernel.rst92
-rw-r--r--Documentation/admin-guide/sysctl/net.rst9
-rw-r--r--Documentation/arm/marvell.rst2
-rw-r--r--Documentation/arm64/booting.rst10
-rw-r--r--Documentation/arm64/elf_hwcaps.rst5
-rw-r--r--Documentation/arm64/memory-tagging-extension.rst54
-rw-r--r--Documentation/arm64/silicon-errata.rst16
-rw-r--r--Documentation/asm-annotations.rst11
-rw-r--r--Documentation/block/biodoc.rst1164
-rw-r--r--Documentation/block/capability.rst2
-rw-r--r--Documentation/block/index.rst1
-rw-r--r--Documentation/bpf/bpf_prog_run.rst117
-rw-r--r--Documentation/bpf/btf.rst45
-rw-r--r--Documentation/bpf/index.rst1
-rw-r--r--Documentation/bpf/instruction-set.rst215
-rw-r--r--Documentation/bpf/verifier.rst2
-rw-r--r--Documentation/cdrom/packet-writing.rst4
-rw-r--r--Documentation/conf.py131
-rw-r--r--Documentation/core-api/entry.rst279
-rw-r--r--Documentation/core-api/index.rst8
-rw-r--r--Documentation/core-api/mm-api.rst19
-rw-r--r--Documentation/core-api/pin_user_pages.rst18
-rw-r--r--Documentation/cpu-freq/cpu-drivers.rst3
-rw-r--r--Documentation/dev-tools/kfence.rst12
-rw-r--r--Documentation/dev-tools/kselftest.rst8
-rw-r--r--Documentation/dev-tools/ktap.rst49
-rw-r--r--Documentation/dev-tools/kunit/usage.rst2
-rw-r--r--Documentation/dev-tools/sparse.rst2
-rw-r--r--Documentation/devicetree/bindings/arm/airoha.yaml28
-rw-r--r--Documentation/devicetree/bindings/arm/altera.yaml46
-rw-r--r--Documentation/devicetree/bindings/arm/amlogic.yaml12
-rw-r--r--Documentation/devicetree/bindings/arm/atmel-at91.yaml12
-rw-r--r--Documentation/devicetree/bindings/arm/bcm/bcm2835.yaml1
-rw-r--r--Documentation/devicetree/bindings/arm/cpus.yaml1
-rw-r--r--Documentation/devicetree/bindings/arm/freescale/fsl,layerscape-dcfg.txt2
-rw-r--r--Documentation/devicetree/bindings/arm/fsl.yaml24
-rw-r--r--Documentation/devicetree/bindings/arm/intel,socfpga.yaml26
-rw-r--r--Documentation/devicetree/bindings/arm/mediatek.yaml4
-rw-r--r--Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml1
-rw-r--r--Documentation/devicetree/bindings/arm/msm/qcom,llcc.yaml2
-rw-r--r--Documentation/devicetree/bindings/arm/mstar/mstar.yaml4
-rw-r--r--Documentation/devicetree/bindings/arm/npcm/nuvoton,gcr.yaml48
-rw-r--r--Documentation/devicetree/bindings/arm/omap/omap.txt3
-rw-r--r--Documentation/devicetree/bindings/arm/pmu.yaml2
-rw-r--r--Documentation/devicetree/bindings/arm/qcom.yaml29
-rw-r--r--Documentation/devicetree/bindings/arm/renesas.yaml9
-rw-r--r--Documentation/devicetree/bindings/arm/rockchip.yaml13
-rw-r--r--Documentation/devicetree/bindings/arm/samsung/samsung-boards.yaml2
-rw-r--r--Documentation/devicetree/bindings/arm/stm32/stm32.yaml6
-rw-r--r--Documentation/devicetree/bindings/arm/sunxi.yaml5
-rw-r--r--Documentation/devicetree/bindings/arm/tesla.yaml27
-rw-r--r--Documentation/devicetree/bindings/arm/ti/k3.yaml6
-rw-r--r--Documentation/devicetree/bindings/bus/nvidia,tegra210-aconnect.yaml1
-rw-r--r--Documentation/devicetree/bindings/clock/intc_stratix10.txt20
-rw-r--r--Documentation/devicetree/bindings/clock/intel,stratix10.yaml35
-rw-r--r--Documentation/devicetree/bindings/clock/mstar,msc313-cpupll.yaml45
-rw-r--r--Documentation/devicetree/bindings/clock/qoriq-clock.txt1
-rw-r--r--Documentation/devicetree/bindings/clock/tesla,fsd-clock.yaml198
-rw-r--r--Documentation/devicetree/bindings/display/bridge/analogix,anx7625.yaml36
-rw-r--r--Documentation/devicetree/bindings/display/bridge/ingenic,jz4780-hdmi.yaml82
-rw-r--r--Documentation/devicetree/bindings/display/bridge/lvds-codec.yaml3
-rw-r--r--Documentation/devicetree/bindings/display/bridge/renesas,lvds.yaml1
-rw-r--r--Documentation/devicetree/bindings/display/bridge/ti,sn65dsi83.yaml5
-rw-r--r--Documentation/devicetree/bindings/display/lvds.yaml (renamed from Documentation/devicetree/bindings/display/panel/lvds.yaml)35
-rw-r--r--Documentation/devicetree/bindings/display/mediatek/mediatek,aal.yaml77
-rw-r--r--Documentation/devicetree/bindings/display/mediatek/mediatek,ccorr.yaml76
-rw-r--r--Documentation/devicetree/bindings/display/mediatek/mediatek,color.yaml86
-rw-r--r--Documentation/devicetree/bindings/display/mediatek/mediatek,disp.txt219
-rw-r--r--Documentation/devicetree/bindings/display/mediatek/mediatek,dither.yaml76
-rw-r--r--Documentation/devicetree/bindings/display/mediatek/mediatek,dsc.yaml71
-rw-r--r--Documentation/devicetree/bindings/display/mediatek/mediatek,ethdr.yaml147
-rw-r--r--Documentation/devicetree/bindings/display/mediatek/mediatek,gamma.yaml77
-rw-r--r--Documentation/devicetree/bindings/display/mediatek/mediatek,merge.yaml110
-rw-r--r--Documentation/devicetree/bindings/display/mediatek/mediatek,mutex.yaml83
-rw-r--r--Documentation/devicetree/bindings/display/mediatek/mediatek,od.yaml53
-rw-r--r--Documentation/devicetree/bindings/display/mediatek/mediatek,ovl-2l.yaml78
-rw-r--r--Documentation/devicetree/bindings/display/mediatek/mediatek,ovl.yaml93
-rw-r--r--Documentation/devicetree/bindings/display/mediatek/mediatek,postmask.yaml69
-rw-r--r--Documentation/devicetree/bindings/display/mediatek/mediatek,rdma.yaml107
-rw-r--r--Documentation/devicetree/bindings/display/mediatek/mediatek,split.yaml58
-rw-r--r--Documentation/devicetree/bindings/display/mediatek/mediatek,ufoe.yaml61
-rw-r--r--Documentation/devicetree/bindings/display/mediatek/mediatek,wdma.yaml76
-rw-r--r--Documentation/devicetree/bindings/display/msm/dp-controller.yaml1
-rw-r--r--Documentation/devicetree/bindings/display/msm/dpu-msm8998.yaml219
-rw-r--r--Documentation/devicetree/bindings/display/msm/dpu-qcm2290.yaml215
-rw-r--r--Documentation/devicetree/bindings/display/msm/dsi-controller-main.yaml5
-rw-r--r--Documentation/devicetree/bindings/display/msm/dsi-phy-10nm.yaml36
-rw-r--r--Documentation/devicetree/bindings/display/panel/advantech,idk-1110wr.yaml19
-rw-r--r--Documentation/devicetree/bindings/display/panel/innolux,ee101ia-01d.yaml23
-rw-r--r--Documentation/devicetree/bindings/display/panel/mitsubishi,aa104xd12.yaml19
-rw-r--r--Documentation/devicetree/bindings/display/panel/mitsubishi,aa121td01.yaml19
-rw-r--r--Documentation/devicetree/bindings/display/panel/panel-lvds.yaml57
-rw-r--r--Documentation/devicetree/bindings/display/panel/panel-mipi-dbi-spi.yaml126
-rw-r--r--Documentation/devicetree/bindings/display/panel/panel-simple.yaml4
-rw-r--r--Documentation/devicetree/bindings/display/panel/sgd,gktw70sdae4se.yaml19
-rw-r--r--Documentation/devicetree/bindings/display/panel/sony,acx424akp.yaml11
-rw-r--r--Documentation/devicetree/bindings/display/simple-framebuffer.yaml12
-rw-r--r--Documentation/devicetree/bindings/display/solomon,ssd1307fb.yaml1
-rw-r--r--Documentation/devicetree/bindings/dma/nvidia,tegra210-adma.yaml4
-rw-r--r--Documentation/devicetree/bindings/extcon/maxim,max77843.yaml40
-rw-r--r--Documentation/devicetree/bindings/firmware/arm,scmi.yaml75
-rw-r--r--Documentation/devicetree/bindings/gpio/sifive,gpio.yaml1
-rw-r--r--Documentation/devicetree/bindings/gpu/arm,mali-bifrost.yaml15
-rw-r--r--Documentation/devicetree/bindings/hwmon/adi,adm1275.yaml68
-rw-r--r--Documentation/devicetree/bindings/hwmon/national,lm90.yaml4
-rw-r--r--Documentation/devicetree/bindings/hwmon/ti,tmp464.yaml114
-rw-r--r--Documentation/devicetree/bindings/i2c/i2c.txt4
-rw-r--r--Documentation/devicetree/bindings/interrupt-controller/amlogic,meson-gpio-intc.txt1
-rw-r--r--Documentation/devicetree/bindings/interrupt-controller/andestech,ativic32.txt19
-rw-r--r--Documentation/devicetree/bindings/interrupt-controller/apple,aic.yaml31
-rw-r--r--Documentation/devicetree/bindings/interrupt-controller/apple,aic2.yaml98
-rw-r--r--Documentation/devicetree/bindings/interrupt-controller/arm,gic.yaml1
-rw-r--r--Documentation/devicetree/bindings/interrupt-controller/qcom,mpm.yaml96
-rw-r--r--Documentation/devicetree/bindings/interrupt-controller/renesas,irqc.yaml1
-rw-r--r--Documentation/devicetree/bindings/interrupt-controller/sifive,plic-1.0.0.yaml33
-rw-r--r--Documentation/devicetree/bindings/interrupt-controller/st,stm32-exti.yaml1
-rw-r--r--Documentation/devicetree/bindings/media/amphion,vpu.yaml180
-rw-r--r--Documentation/devicetree/bindings/media/i2c/hynix,hi846.yaml6
-rw-r--r--Documentation/devicetree/bindings/media/i2c/isil,isl79987.yaml113
-rw-r--r--Documentation/devicetree/bindings/media/i2c/maxim,max9286.yaml275
-rw-r--r--Documentation/devicetree/bindings/media/mediatek,vcodec-decoder.yaml169
-rw-r--r--Documentation/devicetree/bindings/media/mediatek,vcodec-encoder.yaml179
-rw-r--r--Documentation/devicetree/bindings/media/mediatek,vcodec-subdev-decoder.yaml265
-rw-r--r--Documentation/devicetree/bindings/media/mediatek-jpeg-decoder.txt38
-rw-r--r--Documentation/devicetree/bindings/media/mediatek-jpeg-decoder.yaml80
-rw-r--r--Documentation/devicetree/bindings/media/mediatek-jpeg-encoder.txt35
-rw-r--r--Documentation/devicetree/bindings/media/mediatek-jpeg-encoder.yaml72
-rw-r--r--Documentation/devicetree/bindings/media/mediatek-mdp.txt8
-rw-r--r--Documentation/devicetree/bindings/media/mediatek-vcodec.txt131
-rw-r--r--Documentation/devicetree/bindings/media/microchip,csi2dc.yaml197
-rw-r--r--Documentation/devicetree/bindings/media/nxp,imx-mipi-csi2.yaml (renamed from Documentation/devicetree/bindings/media/nxp,imx7-mipi-csi2.yaml)2
-rw-r--r--Documentation/devicetree/bindings/media/nxp,imx7-csi.yaml1
-rw-r--r--Documentation/devicetree/bindings/media/nxp,imx8mq-vpu.yaml68
-rw-r--r--Documentation/devicetree/bindings/media/qcom,msm8916-camss.yaml10
-rw-r--r--Documentation/devicetree/bindings/media/qcom,msm8996-camss.yaml20
-rw-r--r--Documentation/devicetree/bindings/media/qcom,sdm660-camss.yaml20
-rw-r--r--Documentation/devicetree/bindings/media/qcom,sdm845-camss.yaml31
-rw-r--r--Documentation/devicetree/bindings/media/qcom,sm8250-camss.yaml463
-rw-r--r--Documentation/devicetree/bindings/media/renesas,csi2.yaml5
-rw-r--r--Documentation/devicetree/bindings/memory-controllers/ddr/jedec,lpddr2-timings.yaml135
-rw-r--r--Documentation/devicetree/bindings/memory-controllers/ddr/jedec,lpddr2.yaml23
-rw-r--r--Documentation/devicetree/bindings/memory-controllers/ddr/jedec,lpddr3-timings.yaml157
-rw-r--r--Documentation/devicetree/bindings/memory-controllers/ddr/jedec,lpddr3.yaml263
-rw-r--r--Documentation/devicetree/bindings/memory-controllers/ddr/lpddr2-timings.txt52
-rw-r--r--Documentation/devicetree/bindings/memory-controllers/ddr/lpddr3-timings.txt58
-rw-r--r--Documentation/devicetree/bindings/memory-controllers/ddr/lpddr3.txt107
-rw-r--r--Documentation/devicetree/bindings/memory-controllers/fsl/fsl,ifc.yaml113
-rw-r--r--Documentation/devicetree/bindings/memory-controllers/fsl/ifc.txt82
-rw-r--r--Documentation/devicetree/bindings/memory-controllers/mediatek,smi-common.yaml32
-rw-r--r--Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.yaml19
-rw-r--r--Documentation/devicetree/bindings/memory-controllers/renesas,rpc-if.yaml3
-rw-r--r--Documentation/devicetree/bindings/memory-controllers/samsung,exynos5422-dmc.yaml3
-rw-r--r--Documentation/devicetree/bindings/mfd/brcm,cru.yaml4
-rw-r--r--Documentation/devicetree/bindings/mfd/cirrus,lochnagar.yaml6
-rw-r--r--Documentation/devicetree/bindings/mfd/google,cros-ec.yaml31
-rw-r--r--Documentation/devicetree/bindings/mfd/max14577.txt147
-rw-r--r--Documentation/devicetree/bindings/mfd/max77802.txt25
-rw-r--r--Documentation/devicetree/bindings/mfd/maxim,max14577.yaml195
-rw-r--r--Documentation/devicetree/bindings/mfd/maxim,max77802.yaml194
-rw-r--r--Documentation/devicetree/bindings/mfd/maxim,max77843.yaml144
-rw-r--r--Documentation/devicetree/bindings/mfd/ti,j721e-system-controller.yaml2
-rw-r--r--Documentation/devicetree/bindings/mmc/allwinner,sun4i-a10-mmc.yaml7
-rw-r--r--Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.yaml1
-rw-r--r--Documentation/devicetree/bindings/mmc/litex,mmc.yaml78
-rw-r--r--Documentation/devicetree/bindings/mmc/mtk-sd.yaml3
-rw-r--r--Documentation/devicetree/bindings/mmc/renesas,sdhi.yaml7
-rw-r--r--Documentation/devicetree/bindings/mmc/sdhci-am654.yaml1
-rw-r--r--Documentation/devicetree/bindings/mmc/sdhci-msm.txt1
-rw-r--r--Documentation/devicetree/bindings/mtd/jedec,spi-nor.yaml3
-rw-r--r--Documentation/devicetree/bindings/nds32/andestech-boards40
-rw-r--r--Documentation/devicetree/bindings/nds32/atl2c.txt28
-rw-r--r--Documentation/devicetree/bindings/nds32/cpus.txt38
-rw-r--r--Documentation/devicetree/bindings/net/can/allwinner,sun4i-a10-can.yaml3
-rw-r--r--Documentation/devicetree/bindings/net/can/bosch,m_can.yaml9
-rw-r--r--Documentation/devicetree/bindings/net/can/microchip,mcp251xfd.yaml3
-rw-r--r--Documentation/devicetree/bindings/net/can/renesas,rcar-canfd.yaml2
-rw-r--r--Documentation/devicetree/bindings/net/can/tcan4x5x.txt2
-rw-r--r--Documentation/devicetree/bindings/net/can/xilinx,can.yaml161
-rw-r--r--Documentation/devicetree/bindings/net/can/xilinx_can.txt61
-rw-r--r--Documentation/devicetree/bindings/net/cdns,macb.yaml56
-rw-r--r--Documentation/devicetree/bindings/net/davicom,dm9051.yaml62
-rw-r--r--Documentation/devicetree/bindings/net/dsa/dsa-port.yaml2
-rw-r--r--Documentation/devicetree/bindings/net/dsa/microchip,ksz.yaml6
-rw-r--r--Documentation/devicetree/bindings/net/dsa/realtek-smi.txt240
-rw-r--r--Documentation/devicetree/bindings/net/dsa/realtek.yaml394
-rw-r--r--Documentation/devicetree/bindings/net/fsl-fman.txt22
-rw-r--r--Documentation/devicetree/bindings/net/marvell-armada-370-neta.txt1
-rw-r--r--Documentation/devicetree/bindings/net/mctp-i2c-controller.yaml92
-rw-r--r--Documentation/devicetree/bindings/net/mediatek-dwmac.txt91
-rw-r--r--Documentation/devicetree/bindings/net/mediatek-dwmac.yaml175
-rw-r--r--Documentation/devicetree/bindings/net/micrel.txt17
-rw-r--r--Documentation/devicetree/bindings/net/microchip,lan966x-switch.yaml2
-rw-r--r--Documentation/devicetree/bindings/net/microchip,sparx5-switch.yaml2
-rw-r--r--Documentation/devicetree/bindings/net/mscc-miim.txt2
-rw-r--r--Documentation/devicetree/bindings/net/qcom,ipa.yaml6
-rw-r--r--Documentation/devicetree/bindings/net/renesas,etheravb.yaml4
-rw-r--r--Documentation/devicetree/bindings/net/wireless/mediatek,mt76.yaml42
-rw-r--r--Documentation/devicetree/bindings/perf/marvell-cn10k-ddr.yaml37
-rw-r--r--Documentation/devicetree/bindings/perf/nds32v3-pmu.txt17
-rw-r--r--Documentation/devicetree/bindings/phy/fsl,lynx-28g.yaml40
-rw-r--r--Documentation/devicetree/bindings/phy/qcom,usb-hs-phy.txt1
-rw-r--r--Documentation/devicetree/bindings/phy/ti,omap-usb2.yaml2
-rw-r--r--Documentation/devicetree/bindings/phy/ti,tcan104x-can.yaml7
-rw-r--r--Documentation/devicetree/bindings/phy/transmit-amplitude.yaml103
-rw-r--r--Documentation/devicetree/bindings/pinctrl/cirrus,madera.yaml3
-rw-r--r--Documentation/devicetree/bindings/pinctrl/samsung,pinctrl-gpio-bank.yaml52
-rw-r--r--Documentation/devicetree/bindings/pinctrl/samsung,pinctrl-pins-cfg.yaml81
-rw-r--r--Documentation/devicetree/bindings/pinctrl/samsung,pinctrl-wakeup-interrupt.yaml106
-rw-r--r--Documentation/devicetree/bindings/pinctrl/samsung,pinctrl.yaml392
-rw-r--r--Documentation/devicetree/bindings/pinctrl/samsung-pinctrl.txt383
-rw-r--r--Documentation/devicetree/bindings/power/amlogic,meson-sec-pwrc.yaml3
-rw-r--r--Documentation/devicetree/bindings/power/fsl,imx-gpcv2.yaml2
-rw-r--r--Documentation/devicetree/bindings/power/mediatek,power-controller.yaml3
-rw-r--r--Documentation/devicetree/bindings/power/qcom,rpmpd.yaml1
-rw-r--r--Documentation/devicetree/bindings/power/renesas,rzg2l-sysc.yaml7
-rw-r--r--Documentation/devicetree/bindings/power/supply/maxim,max14577.yaml84
-rw-r--r--Documentation/devicetree/bindings/pwm/pwm-sifive.yaml1
-rw-r--r--Documentation/devicetree/bindings/regulator/max77802.txt111
-rw-r--r--Documentation/devicetree/bindings/regulator/maxim,max14577.yaml78
-rw-r--r--Documentation/devicetree/bindings/regulator/maxim,max77802.yaml85
-rw-r--r--Documentation/devicetree/bindings/regulator/maxim,max77843.yaml65
-rw-r--r--Documentation/devicetree/bindings/regulator/maxim,max8973.yaml5
-rw-r--r--Documentation/devicetree/bindings/regulator/pfuze100.yaml6
-rw-r--r--Documentation/devicetree/bindings/regulator/qcom,rpmh-regulator.yaml2
-rw-r--r--Documentation/devicetree/bindings/regulator/richtek,rt5190a-regulator.yaml141
-rw-r--r--Documentation/devicetree/bindings/regulator/ti,tps62360.yaml98
-rw-r--r--Documentation/devicetree/bindings/regulator/ti,tps62864.yaml63
-rw-r--r--Documentation/devicetree/bindings/regulator/tps62360-regulator.txt44
-rw-r--r--Documentation/devicetree/bindings/remoteproc/qcom,adsp.yaml16
-rw-r--r--Documentation/devicetree/bindings/riscv/sifive-l2-cache.yaml1
-rw-r--r--Documentation/devicetree/bindings/soc/imx/fsl,imx8mp-hsio-blk-ctrl.yaml78
-rw-r--r--Documentation/devicetree/bindings/soc/imx/fsl,imx8mq-vpu-blk-ctrl.yaml71
-rw-r--r--Documentation/devicetree/bindings/soc/mediatek/pwrap.txt1
-rw-r--r--Documentation/devicetree/bindings/soc/rockchip/grf.yaml1
-rw-r--r--Documentation/devicetree/bindings/soc/samsung/exynos-usi.yaml20
-rw-r--r--Documentation/devicetree/bindings/sound/allwinner,sun4i-a10-i2s.yaml5
-rw-r--r--Documentation/devicetree/bindings/sound/arndale.txt25
-rw-r--r--Documentation/devicetree/bindings/sound/audio-graph-port.yaml20
-rw-r--r--Documentation/devicetree/bindings/sound/awinic,aw8738.yaml54
-rw-r--r--Documentation/devicetree/bindings/sound/davinci-mcasp-audio.txt86
-rw-r--r--Documentation/devicetree/bindings/sound/davinci-mcasp-audio.yaml201
-rw-r--r--Documentation/devicetree/bindings/sound/fsl-asoc-card.txt3
-rw-r--r--Documentation/devicetree/bindings/sound/google,cros-ec-codec.yaml1
-rw-r--r--Documentation/devicetree/bindings/sound/google,sc7280-herobrine.yaml180
-rw-r--r--Documentation/devicetree/bindings/sound/microchip,pdmc.yaml100
-rw-r--r--Documentation/devicetree/bindings/sound/mt8195-afe-pcm.yaml10
-rw-r--r--Documentation/devicetree/bindings/sound/nvidia,tegra186-dspk.yaml4
-rw-r--r--Documentation/devicetree/bindings/sound/nvidia,tegra210-admaif.yaml4
-rw-r--r--Documentation/devicetree/bindings/sound/nvidia,tegra210-adx.yaml1
-rw-r--r--Documentation/devicetree/bindings/sound/nvidia,tegra210-ahub.yaml1
-rw-r--r--Documentation/devicetree/bindings/sound/nvidia,tegra210-amx.yaml3
-rw-r--r--Documentation/devicetree/bindings/sound/nvidia,tegra210-dmic.yaml1
-rw-r--r--Documentation/devicetree/bindings/sound/nvidia,tegra210-i2s.yaml1
-rw-r--r--Documentation/devicetree/bindings/sound/nvidia,tegra210-mixer.yaml1
-rw-r--r--Documentation/devicetree/bindings/sound/nvidia,tegra210-mvc.yaml1
-rw-r--r--Documentation/devicetree/bindings/sound/nvidia,tegra210-sfc.yaml1
-rw-r--r--Documentation/devicetree/bindings/sound/nvidia,tegra30-hda.yaml3
-rw-r--r--Documentation/devicetree/bindings/sound/qcom,lpass-cpu.yaml75
-rw-r--r--Documentation/devicetree/bindings/sound/qcom,lpass-rx-macro.yaml8
-rw-r--r--Documentation/devicetree/bindings/sound/qcom,lpass-tx-macro.yaml8
-rw-r--r--Documentation/devicetree/bindings/sound/qcom,lpass-va-macro.yaml8
-rw-r--r--Documentation/devicetree/bindings/sound/qcom,wcd938x.yaml4
-rw-r--r--Documentation/devicetree/bindings/sound/realtek,rt5682s.yaml8
-rw-r--r--Documentation/devicetree/bindings/sound/renesas,rsnd.yaml16
-rw-r--r--Documentation/devicetree/bindings/sound/renesas,rz-ssi.yaml3
-rw-r--r--Documentation/devicetree/bindings/sound/samsung,aries-wm8994.yaml4
-rw-r--r--Documentation/devicetree/bindings/sound/samsung,arndale.yaml45
-rw-r--r--Documentation/devicetree/bindings/sound/samsung,smdk-wm8994.txt14
-rw-r--r--Documentation/devicetree/bindings/sound/samsung,smdk5250.yaml38
-rw-r--r--Documentation/devicetree/bindings/sound/samsung,snow.yaml74
-rw-r--r--Documentation/devicetree/bindings/sound/samsung,tm2-audio.txt42
-rw-r--r--Documentation/devicetree/bindings/sound/samsung,tm2.yaml80
-rw-r--r--Documentation/devicetree/bindings/sound/simple-card.yaml53
-rw-r--r--Documentation/devicetree/bindings/sound/snow.txt31
-rw-r--r--Documentation/devicetree/bindings/sound/tas5805m.yaml56
-rw-r--r--Documentation/devicetree/bindings/sound/tlv320aic31xx.txt2
-rw-r--r--Documentation/devicetree/bindings/spi/mediatek,spi-mt65xx.yaml107
-rw-r--r--Documentation/devicetree/bindings/spi/mediatek,spi-mtk-nor.yaml4
-rw-r--r--Documentation/devicetree/bindings/spi/mediatek,spi-slave-mt27xx.yaml58
-rw-r--r--Documentation/devicetree/bindings/spi/microchip,mpfs-spi.yaml52
-rw-r--r--Documentation/devicetree/bindings/spi/nvidia,tegra210-quad.yaml3
-rw-r--r--Documentation/devicetree/bindings/spi/renesas,rspi.yaml4
-rw-r--r--Documentation/devicetree/bindings/spi/samsung,spi-peripheral-props.yaml33
-rw-r--r--Documentation/devicetree/bindings/spi/samsung,spi.yaml188
-rw-r--r--Documentation/devicetree/bindings/spi/spi-controller.yaml7
-rw-r--r--Documentation/devicetree/bindings/spi/spi-mt65xx.txt68
-rw-r--r--Documentation/devicetree/bindings/spi/spi-nxp-fspi.yaml3
-rw-r--r--Documentation/devicetree/bindings/spi/spi-peripheral-props.yaml31
-rw-r--r--Documentation/devicetree/bindings/spi/spi-pl022.yaml4
-rw-r--r--Documentation/devicetree/bindings/spi/spi-samsung.txt122
-rw-r--r--Documentation/devicetree/bindings/spi/spi-slave-mt27xx.txt33
-rw-r--r--Documentation/devicetree/bindings/spi/spi-sunplus-sp7021.yaml78
-rw-r--r--Documentation/devicetree/bindings/thermal/exynos-thermal.txt106
-rw-r--r--Documentation/devicetree/bindings/thermal/qcom-lmh.yaml1
-rw-r--r--Documentation/devicetree/bindings/thermal/qcom-tsens.yaml1
-rw-r--r--Documentation/devicetree/bindings/thermal/samsung,exynos-thermal.yaml184
-rw-r--r--Documentation/devicetree/bindings/timer/andestech,atcpit100-timer.txt33
-rw-r--r--Documentation/devicetree/bindings/timer/mediatek,mtk-timer.txt1
-rw-r--r--Documentation/devicetree/bindings/timer/nvidia,tegra-timer.yaml150
-rw-r--r--Documentation/devicetree/bindings/timer/nvidia,tegra20-timer.txt24
-rw-r--r--Documentation/devicetree/bindings/timer/nvidia,tegra210-timer.txt36
-rw-r--r--Documentation/devicetree/bindings/timer/nvidia,tegra30-timer.txt28
-rw-r--r--Documentation/devicetree/bindings/trivial-devices.yaml5
-rw-r--r--Documentation/devicetree/bindings/usb/dwc2.yaml9
-rw-r--r--Documentation/devicetree/bindings/usb/ti,j721e-usb.yaml2
-rw-r--r--Documentation/devicetree/bindings/usb/ti,keystone-dwc3.yaml2
-rw-r--r--Documentation/devicetree/bindings/vendor-prefixes.yaml20
-rw-r--r--Documentation/devicetree/bindings/watchdog/mtk-wdt.txt1
-rw-r--r--Documentation/driver-api/cxl/memory-devices.rst315
-rw-r--r--Documentation/driver-api/device-io.rst9
-rw-r--r--Documentation/driver-api/dma-buf.rst9
-rw-r--r--Documentation/driver-api/gpio/board.rst21
-rw-r--r--Documentation/driver-api/index.rst1
-rw-r--r--Documentation/driver-api/media/drivers/davinci-vpbe-devel.rst20
-rw-r--r--Documentation/driver-api/media/drivers/fimc-devel.rst14
-rw-r--r--Documentation/driver-api/media/v4l2-event.rst2
-rw-r--r--Documentation/driver-api/mtd/index.rst2
-rw-r--r--Documentation/driver-api/mtd/spi-intel.rst (renamed from Documentation/driver-api/mtd/intel-spi.rst)8
-rw-r--r--Documentation/driver-api/serial/driver.rst2
-rw-r--r--Documentation/driver-api/thermal/index.rst1
-rw-r--r--Documentation/driver-api/thermal/intel_dptf.rst272
-rw-r--r--Documentation/driver-api/vfio-pci-device-specific-driver-acceptance.rst35
-rw-r--r--Documentation/features/core/cBPF-JIT/arch-support.txt1
-rw-r--r--Documentation/features/core/eBPF-JIT/arch-support.txt1
-rw-r--r--Documentation/features/core/generic-idle-thread/arch-support.txt1
-rw-r--r--Documentation/features/core/jump-labels/arch-support.txt1
-rw-r--r--Documentation/features/core/thread-info-in-task/arch-support.txt1
-rw-r--r--Documentation/features/core/tracehook/arch-support.txt1
-rw-r--r--Documentation/features/debug/KASAN/arch-support.txt1
-rw-r--r--Documentation/features/debug/debug-vm-pgtable/arch-support.txt1
-rw-r--r--Documentation/features/debug/gcov-profile-all/arch-support.txt1
-rw-r--r--Documentation/features/debug/kcov/arch-support.txt1
-rw-r--r--Documentation/features/debug/kgdb/arch-support.txt1
-rw-r--r--Documentation/features/debug/kmemleak/arch-support.txt1
-rw-r--r--Documentation/features/debug/kprobes-on-ftrace/arch-support.txt1
-rw-r--r--Documentation/features/debug/kprobes/arch-support.txt1
-rw-r--r--Documentation/features/debug/kretprobes/arch-support.txt1
-rw-r--r--Documentation/features/debug/optprobes/arch-support.txt1
-rw-r--r--Documentation/features/debug/stackprotector/arch-support.txt1
-rw-r--r--Documentation/features/debug/uprobes/arch-support.txt1
-rw-r--r--Documentation/features/debug/user-ret-profiler/arch-support.txt1
-rw-r--r--Documentation/features/io/dma-contiguous/arch-support.txt1
-rw-r--r--Documentation/features/locking/cmpxchg-local/arch-support.txt1
-rw-r--r--Documentation/features/locking/lockdep/arch-support.txt1
-rw-r--r--Documentation/features/locking/queued-rwlocks/arch-support.txt1
-rw-r--r--Documentation/features/locking/queued-spinlocks/arch-support.txt1
-rw-r--r--Documentation/features/perf/kprobes-event/arch-support.txt1
-rw-r--r--Documentation/features/perf/perf-regs/arch-support.txt1
-rw-r--r--Documentation/features/perf/perf-stackdump/arch-support.txt1
-rw-r--r--Documentation/features/sched/membarrier-sync-core/arch-support.txt1
-rw-r--r--Documentation/features/sched/numa-balancing/arch-support.txt1
-rw-r--r--Documentation/features/seccomp/seccomp-filter/arch-support.txt1
-rw-r--r--Documentation/features/time/arch-tick-broadcast/arch-support.txt1
-rw-r--r--Documentation/features/time/clockevents/arch-support.txt1
-rw-r--r--Documentation/features/time/context-tracking/arch-support.txt1
-rw-r--r--Documentation/features/time/irq-time-acct/arch-support.txt1
-rw-r--r--Documentation/features/time/virt-cpuacct/arch-support.txt1
-rw-r--r--Documentation/features/vm/ELF-ASLR/arch-support.txt1
-rw-r--r--Documentation/features/vm/PG_uncached/arch-support.txt1
-rw-r--r--Documentation/features/vm/THP/arch-support.txt1
-rw-r--r--Documentation/features/vm/TLB/arch-support.txt1
-rw-r--r--Documentation/features/vm/huge-vmap/arch-support.txt1
-rw-r--r--Documentation/features/vm/ioremap_prot/arch-support.txt1
-rw-r--r--Documentation/features/vm/pte_special/arch-support.txt1
-rw-r--r--Documentation/filesystems/caching/netfs-api.rst7
-rw-r--r--Documentation/filesystems/dax.rst6
-rw-r--r--Documentation/filesystems/erofs.rst2
-rw-r--r--Documentation/filesystems/ext4/blocks.rst2
-rw-r--r--Documentation/filesystems/fscrypt.rst25
-rw-r--r--Documentation/filesystems/locking.rst48
-rw-r--r--Documentation/filesystems/netfs_library.rst16
-rw-r--r--Documentation/filesystems/porting.rst6
-rw-r--r--Documentation/filesystems/vfs.rst62
-rw-r--r--Documentation/firmware-guide/acpi/enumeration.rst111
-rw-r--r--Documentation/firmware-guide/acpi/gpio-properties.rst26
-rw-r--r--Documentation/gpu/drm-internals.rst6
-rw-r--r--Documentation/gpu/drm-kms-helpers.rst26
-rw-r--r--Documentation/gpu/drm-kms.rst6
-rw-r--r--Documentation/gpu/drm-mm.rst2
-rw-r--r--Documentation/gpu/i915.rst1
-rw-r--r--Documentation/gpu/todo.rst106
-rw-r--r--Documentation/gpu/vkms.rst2
-rw-r--r--Documentation/hwmon/aquacomputer_d5next.rst49
-rw-r--r--Documentation/hwmon/asus_ec_sensors.rst54
-rw-r--r--Documentation/hwmon/dell-smm-hwmon.rst180
-rw-r--r--Documentation/hwmon/index.rst3
-rw-r--r--Documentation/hwmon/lm70.rst7
-rw-r--r--Documentation/hwmon/max6639.rst2
-rw-r--r--Documentation/hwmon/pli1209bc.rst75
-rw-r--r--Documentation/hwmon/sch5627.rst4
-rw-r--r--Documentation/hwmon/sysfs-interface.rst4
-rw-r--r--Documentation/hwmon/tmp464.rst73
-rw-r--r--Documentation/hwmon/xdpe12284.rst12
-rw-r--r--Documentation/index.rst1
-rw-r--r--Documentation/kernel-hacking/locking.rst2
-rw-r--r--Documentation/locking/locktypes.rst2
-rw-r--r--Documentation/maintainer/maintainer-entry-profile.rst1
-rw-r--r--Documentation/networking/bonding.rst11
-rw-r--r--Documentation/networking/devlink/index.rst16
-rw-r--r--Documentation/networking/dsa/sja1105.rst27
-rw-r--r--Documentation/networking/ethtool-netlink.rst19
-rw-r--r--Documentation/networking/index.rst1
-rw-r--r--Documentation/networking/ip-sysctl.rst23
-rw-r--r--Documentation/networking/mctp.rst48
-rw-r--r--Documentation/networking/page_pool.rst56
-rw-r--r--Documentation/networking/smc-sysctl.rst23
-rw-r--r--Documentation/networking/timestamping.rst2
-rw-r--r--Documentation/process/applying-patches.rst28
-rw-r--r--Documentation/process/deprecated.rst20
-rw-r--r--Documentation/process/handling-regressions.rst746
-rw-r--r--Documentation/process/index.rst2
-rw-r--r--Documentation/process/researcher-guidelines.rst143
-rw-r--r--Documentation/process/submitting-patches.rst3
-rw-r--r--Documentation/scheduler/index.rst2
-rw-r--r--Documentation/scheduler/sched-debug.rst54
-rw-r--r--Documentation/scheduler/sched-domains.rst8
-rw-r--r--Documentation/scheduler/schedutil.rst (renamed from Documentation/scheduler/schedutil.txt)30
-rw-r--r--Documentation/security/SCTP.rst26
-rw-r--r--Documentation/security/keys/trusted-encrypted.rst25
-rw-r--r--Documentation/sound/designs/control-names.rst2
-rw-r--r--Documentation/sound/hd-audio/models.rst4
-rw-r--r--Documentation/sphinx/kerneldoc-preamble.sty226
-rw-r--r--Documentation/sphinx/kfigure.py134
-rw-r--r--Documentation/spi/pxa2xx.rst3
-rw-r--r--Documentation/tools/index.rst20
-rw-r--r--Documentation/tools/rtla/common_hist_options.rst2
-rw-r--r--Documentation/tools/rtla/common_options.rst19
-rw-r--r--Documentation/tools/rtla/common_osnoise_description.rst2
-rw-r--r--Documentation/tools/rtla/common_osnoise_options.rst10
-rw-r--r--Documentation/tools/rtla/common_timerlat_options.rst12
-rw-r--r--Documentation/tools/rtla/index.rst26
-rw-r--r--Documentation/tools/rtla/rtla-osnoise-hist.rst2
-rw-r--r--Documentation/trace/fprobe.rst174
-rw-r--r--Documentation/trace/index.rst2
-rw-r--r--Documentation/trace/osnoise-tracer.rst4
-rw-r--r--Documentation/trace/user_events.rst216
-rw-r--r--Documentation/translations/conf.py12
-rw-r--r--Documentation/translations/ja_JP/index.rst4
-rw-r--r--Documentation/translations/ko_KR/index.rst5
-rw-r--r--Documentation/translations/zh_CN/accounting/delay-accounting.rst62
-rw-r--r--Documentation/translations/zh_CN/admin-guide/index.rst124
-rw-r--r--Documentation/translations/zh_CN/admin-guide/mm/damon/index.rst28
-rw-r--r--Documentation/translations/zh_CN/admin-guide/mm/damon/reclaim.rst232
-rw-r--r--Documentation/translations/zh_CN/admin-guide/mm/damon/start.rst132
-rw-r--r--Documentation/translations/zh_CN/admin-guide/mm/damon/usage.rst286
-rw-r--r--Documentation/translations/zh_CN/admin-guide/mm/index.rst49
-rw-r--r--Documentation/translations/zh_CN/admin-guide/mm/ksm.rst148
-rw-r--r--Documentation/translations/zh_CN/core-api/index.rst2
-rw-r--r--Documentation/translations/zh_CN/core-api/rbtree.rst391
-rw-r--r--Documentation/translations/zh_CN/cpu-freq/cpu-drivers.rst2
-rw-r--r--Documentation/translations/zh_CN/devicetree/index.rst50
-rw-r--r--Documentation/translations/zh_CN/devicetree/of_unittest.rst189
-rw-r--r--Documentation/translations/zh_CN/devicetree/usage-model.rst330
-rw-r--r--Documentation/translations/zh_CN/index.rst21
-rw-r--r--Documentation/translations/zh_CN/peci/index.rst26
-rw-r--r--Documentation/translations/zh_CN/peci/peci.rst54
-rw-r--r--Documentation/translations/zh_CN/power/energy-model.rst190
-rw-r--r--Documentation/translations/zh_CN/power/index.rst56
-rw-r--r--Documentation/translations/zh_CN/power/opp.rst341
-rw-r--r--Documentation/translations/zh_CN/riscv/index.rst1
-rw-r--r--Documentation/translations/zh_CN/riscv/vm-layout.rst67
-rw-r--r--Documentation/translations/zh_CN/scheduler/index.rst9
-rw-r--r--Documentation/translations/zh_CN/scheduler/sched-energy.rst351
-rw-r--r--Documentation/translations/zh_CN/scheduler/sched-nice-design.rst99
-rw-r--r--Documentation/translations/zh_CN/scheduler/sched-stats.rst156
-rw-r--r--Documentation/translations/zh_CN/vm/active_mm.rst85
-rw-r--r--Documentation/translations/zh_CN/vm/balance.rst81
-rw-r--r--Documentation/translations/zh_CN/vm/damon/api.rst32
-rw-r--r--Documentation/translations/zh_CN/vm/damon/design.rst139
-rw-r--r--Documentation/translations/zh_CN/vm/damon/faq.rst48
-rw-r--r--Documentation/translations/zh_CN/vm/damon/index.rst33
-rw-r--r--Documentation/translations/zh_CN/vm/free_page_reporting.rst38
-rw-r--r--Documentation/translations/zh_CN/vm/highmem.rst128
-rw-r--r--Documentation/translations/zh_CN/vm/index.rst53
-rw-r--r--Documentation/translations/zh_CN/vm/ksm.rst70
-rw-r--r--Documentation/translations/zh_TW/index.rst4
-rw-r--r--Documentation/userspace-api/ioctl/ioctl-number.rst5
-rw-r--r--Documentation/userspace-api/media/lirc.h.rst.exceptions4
-rw-r--r--Documentation/userspace-api/media/rc/lirc-dev-intro.rst11
-rw-r--r--Documentation/userspace-api/media/rc/lirc-get-features.rst18
-rw-r--r--Documentation/userspace-api/media/v4l/ext-ctrls-codec-stateless.rst13
-rw-r--r--Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst16
-rw-r--r--Documentation/userspace-api/media/v4l/pixfmt-reserved.rst15
-rw-r--r--Documentation/userspace-api/media/v4l/pixfmt-rgb.rst2
-rw-r--r--Documentation/userspace-api/media/v4l/pixfmt-yuv-luma.rst4
-rw-r--r--Documentation/userspace-api/media/v4l/pixfmt-yuv-planar.rst45
-rw-r--r--Documentation/userspace-api/media/v4l/v4l2grab.c.rst2
-rw-r--r--Documentation/userspace-api/media/v4l/vidioc-qbuf.rst2
-rw-r--r--Documentation/virt/kvm/api.rst296
-rw-r--r--Documentation/virt/kvm/devices/vcpu.rst36
-rw-r--r--Documentation/virt/kvm/vcpu-requests.rst7
-rw-r--r--Documentation/virt/uml/user_mode_linux_howto_v2.rst6
-rw-r--r--Documentation/vm/damon/design.rst43
-rw-r--r--Documentation/vm/damon/faq.rst2
-rw-r--r--Documentation/vm/page_owner.rst10
-rw-r--r--Documentation/vm/page_table_check.rst2
-rw-r--r--Documentation/x86/index.rst1
-rw-r--r--Documentation/x86/intel-hfi.rst72
-rw-r--r--Documentation/x86/sva.rst53
-rw-r--r--MAINTAINERS608
-rw-r--r--Makefile4
-rw-r--r--arch/Kconfig90
-rw-r--r--arch/alpha/Kconfig2
-rw-r--r--arch/alpha/configs/defconfig1
-rw-r--r--arch/alpha/include/asm/hwrpb.h2
-rw-r--r--arch/alpha/include/asm/pgtable.h1
-rw-r--r--arch/alpha/include/asm/processor.h4
-rw-r--r--arch/alpha/include/asm/thread_info.h2
-rw-r--r--arch/alpha/include/asm/uaccess.h53
-rw-r--r--arch/alpha/include/asm/xor.h53
-rw-r--r--arch/alpha/include/uapi/asm/signal.h2
-rw-r--r--arch/alpha/include/uapi/asm/socket.h2
-rw-r--r--arch/alpha/mm/init.c6
-rw-r--r--arch/arc/Kconfig1
-rw-r--r--arch/arc/include/asm/hugepage.h1
-rw-r--r--arch/arc/include/asm/pgtable-levels.h1
-rw-r--r--arch/arc/include/asm/segment.h20
-rw-r--r--arch/arc/include/asm/thread_info.h3
-rw-r--r--arch/arc/include/asm/uaccess.h30
-rw-r--r--arch/arc/kernel/process.c2
-rw-r--r--arch/arm/Kconfig109
-rw-r--r--arch/arm/Kconfig.debug2
-rw-r--r--arch/arm/Makefile10
-rw-r--r--arch/arm/boot/compressed/Makefile6
-rw-r--r--arch/arm/boot/compressed/misc.c7
-rw-r--r--arch/arm/boot/dts/Makefile20
-rw-r--r--arch/arm/boot/dts/am335x-pdu001.dts2
-rw-r--r--arch/arm/boot/dts/am335x-sancloud-bbe-extended-wifi.dts113
-rw-r--r--arch/arm/boot/dts/am335x-wega.dtsi2
-rw-r--r--arch/arm/boot/dts/am43x-epos-evm.dts2
-rw-r--r--arch/arm/boot/dts/armada-370-c200-v2.dts388
-rw-r--r--arch/arm/boot/dts/armada-385-turris-omnia.dts3
-rw-r--r--arch/arm/boot/dts/armada-385.dtsi52
-rw-r--r--arch/arm/boot/dts/aspeed-bmc-ampere-mtjade.dts26
-rw-r--r--arch/arm/boot/dts/aspeed-bmc-asrock-romed8hm3.dts259
-rw-r--r--arch/arm/boot/dts/aspeed-bmc-facebook-bletchley.dts320
-rw-r--r--arch/arm/boot/dts/aspeed-bmc-ibm-everest.dts11
-rw-r--r--arch/arm/boot/dts/aspeed-bmc-ibm-rainier.dts33
-rw-r--r--arch/arm/boot/dts/aspeed-bmc-opp-tacoma.dts12
-rw-r--r--arch/arm/boot/dts/aspeed-bmc-quanta-s6q.dts610
-rw-r--r--arch/arm/boot/dts/aspeed-g6-pinctrl.dtsi2
-rw-r--r--arch/arm/boot/dts/at91-sam9x60ek.dts8
-rw-r--r--arch/arm/boot/dts/at91-sama7g5ek.dts32
-rw-r--r--arch/arm/boot/dts/bcm2711.dtsi51
-rw-r--r--arch/arm/boot/dts/bcm2835.dtsi17
-rw-r--r--arch/arm/boot/dts/bcm2836.dtsi50
-rw-r--r--arch/arm/boot/dts/bcm2837-rpi-zero-2-w.dts136
-rw-r--r--arch/arm/boot/dts/bcm2837.dtsi49
-rw-r--r--arch/arm/boot/dts/bcm47094-asus-rt-ac88u.dts76
-rw-r--r--arch/arm/boot/dts/bcm47094-luxul-xwr-3150-v1.dts8
-rw-r--r--arch/arm/boot/dts/bcm958625-meraki-alamo.dtsi3
-rw-r--r--arch/arm/boot/dts/bcm958625-meraki-kingpin.dtsi3
-rw-r--r--arch/arm/boot/dts/bcm958625-meraki-mx6x-common.dtsi10
-rw-r--r--arch/arm/boot/dts/dra7-l4.dtsi5
-rw-r--r--arch/arm/boot/dts/dra7.dtsi28
-rw-r--r--arch/arm/boot/dts/en7523-evb.dts35
-rw-r--r--arch/arm/boot/dts/en7523.dtsi138
-rw-r--r--arch/arm/boot/dts/exynos3250-artik5.dtsi10
-rw-r--r--arch/arm/boot/dts/exynos3250-monk.dts2
-rw-r--r--arch/arm/boot/dts/exynos3250-pinctrl.dtsi165
-rw-r--r--arch/arm/boot/dts/exynos3250-rinato.dts2
-rw-r--r--arch/arm/boot/dts/exynos3250.dtsi4
-rw-r--r--arch/arm/boot/dts/exynos4.dtsi6
-rw-r--r--arch/arm/boot/dts/exynos4210-i9100.dts30
-rw-r--r--arch/arm/boot/dts/exynos4210-origen.dts2
-rw-r--r--arch/arm/boot/dts/exynos4210-pinctrl.dtsi226
-rw-r--r--arch/arm/boot/dts/exynos4210-smdkv310.dts4
-rw-r--r--arch/arm/boot/dts/exynos4210-trats.dts6
-rw-r--r--arch/arm/boot/dts/exynos4210-universal_c210.dts14
-rw-r--r--arch/arm/boot/dts/exynos4210.dtsi2
-rw-r--r--arch/arm/boot/dts/exynos4412-galaxy-s3.dtsi4
-rw-r--r--arch/arm/boot/dts/exynos4412-itop-elite.dts2
-rw-r--r--arch/arm/boot/dts/exynos4412-itop-scp-core.dtsi2
-rw-r--r--arch/arm/boot/dts/exynos4412-midas.dtsi30
-rw-r--r--arch/arm/boot/dts/exynos4412-odroid-common.dtsi8
-rw-r--r--arch/arm/boot/dts/exynos4412-odroidx.dts2
-rw-r--r--arch/arm/boot/dts/exynos4412-origen.dts4
-rw-r--r--arch/arm/boot/dts/exynos4412-p4note.dtsi78
-rw-r--r--arch/arm/boot/dts/exynos4412-pinctrl.dtsi252
-rw-r--r--arch/arm/boot/dts/exynos4412-smdk4412.dts4
-rw-r--r--arch/arm/boot/dts/exynos4412.dtsi2
-rw-r--r--arch/arm/boot/dts/exynos5250-arndale.dts7
-rw-r--r--arch/arm/boot/dts/exynos5250-pinctrl.dtsi222
-rw-r--r--arch/arm/boot/dts/exynos5250-smdk5250.dts10
-rw-r--r--arch/arm/boot/dts/exynos5250-snow-common.dtsi27
-rw-r--r--arch/arm/boot/dts/exynos5250-snow-rev5.dts2
-rw-r--r--arch/arm/boot/dts/exynos5250-snow.dts2
-rw-r--r--arch/arm/boot/dts/exynos5250-spring.dts25
-rw-r--r--arch/arm/boot/dts/exynos5250.dtsi19
-rw-r--r--arch/arm/boot/dts/exynos5260-pinctrl.dtsi148
-rw-r--r--arch/arm/boot/dts/exynos5260-xyref5260.dts23
-rw-r--r--arch/arm/boot/dts/exynos5260.dtsi128
-rw-r--r--arch/arm/boot/dts/exynos5410-odroidxu.dts34
-rw-r--r--arch/arm/boot/dts/exynos5410-pinctrl.dtsi170
-rw-r--r--arch/arm/boot/dts/exynos5410-smdk5410.dts27
-rw-r--r--arch/arm/boot/dts/exynos5410.dtsi4
-rw-r--r--arch/arm/boot/dts/exynos5420-arndale-octa.dts12
-rw-r--r--arch/arm/boot/dts/exynos5420-chagall-wifi.dts75
-rw-r--r--arch/arm/boot/dts/exynos5420-galaxy-tab-common.dtsi691
-rw-r--r--arch/arm/boot/dts/exynos5420-klimt-wifi.dts75
-rw-r--r--arch/arm/boot/dts/exynos5420-peach-pit.dts99
-rw-r--r--arch/arm/boot/dts/exynos5420-pinctrl.dtsi194
-rw-r--r--arch/arm/boot/dts/exynos5420-smdk5420.dts19
-rw-r--r--arch/arm/boot/dts/exynos5420.dtsi26
-rw-r--r--arch/arm/boot/dts/exynos5422-odroid-core.dtsi4
-rw-r--r--arch/arm/boot/dts/exynos5422-odroidxu3-common.dtsi6
-rw-r--r--arch/arm/boot/dts/exynos5800-peach-pi.dts99
-rw-r--r--arch/arm/boot/dts/imx23-evk.dts1
-rw-r--r--arch/arm/boot/dts/imx28-tx28.dts2
-rw-r--r--arch/arm/boot/dts/imx28.dtsi2
-rw-r--r--arch/arm/boot/dts/imx51-ts4800.dts2
-rw-r--r--arch/arm/boot/dts/imx53-m53menlo.dts29
-rw-r--r--arch/arm/boot/dts/imx53-tx53.dtsi2
-rw-r--r--arch/arm/boot/dts/imx6dl-plym2m.dts131
-rw-r--r--arch/arm/boot/dts/imx6dl-prtvt7.dts203
-rw-r--r--arch/arm/boot/dts/imx6dl-victgo.dts121
-rw-r--r--arch/arm/boot/dts/imx6q-tbs2910.dts2
-rw-r--r--arch/arm/boot/dts/imx6qdl-dhcom-pdk2.dtsi3
-rw-r--r--arch/arm/boot/dts/imx6qdl-mba6.dtsi16
-rw-r--r--arch/arm/boot/dts/imx6qdl-mba6a.dtsi6
-rw-r--r--arch/arm/boot/dts/imx6qdl-mba6b.dtsi11
-rw-r--r--arch/arm/boot/dts/imx6qdl-phytec-pfla02.dtsi13
-rw-r--r--arch/arm/boot/dts/imx6qdl-phytec-phycore-som.dtsi10
-rw-r--r--arch/arm/boot/dts/imx6qdl-tqma6.dtsi14
-rw-r--r--arch/arm/boot/dts/imx6qdl-tqma6a.dtsi7
-rw-r--r--arch/arm/boot/dts/imx6qdl-tqma6b.dtsi7
-rw-r--r--arch/arm/boot/dts/imx6qdl-tx6-mb7.dtsi2
-rw-r--r--arch/arm/boot/dts/imx6qdl-udoo.dtsi5
-rw-r--r--arch/arm/boot/dts/imx6qdl-vicut1.dtsi12
-rw-r--r--arch/arm/boot/dts/imx6qp-sabresd.dts6
-rw-r--r--arch/arm/boot/dts/imx6sx-udoo-neo.dtsi74
-rw-r--r--arch/arm/boot/dts/imx6ul-tx6ul-mainboard.dts2
-rw-r--r--arch/arm/boot/dts/imx7-colibri-aster.dtsi2
-rw-r--r--arch/arm/boot/dts/imx7-colibri-eval-v3.dtsi2
-rw-r--r--arch/arm/boot/dts/imx7-colibri.dtsi4
-rw-r--r--arch/arm/boot/dts/imx7-mba7.dtsi2
-rw-r--r--arch/arm/boot/dts/imx7d-nitrogen7.dts2
-rw-r--r--arch/arm/boot/dts/imx7d-pico-hobbit.dts4
-rw-r--r--arch/arm/boot/dts/imx7d-pico-pi.dts4
-rw-r--r--arch/arm/boot/dts/imx7d-sdb.dts4
-rw-r--r--arch/arm/boot/dts/imx7d.dtsi86
-rw-r--r--arch/arm/boot/dts/imx7s-warp.dts4
-rw-r--r--arch/arm/boot/dts/imx7ulp.dtsi2
-rw-r--r--arch/arm/boot/dts/imxrt1050-pinfunc.h993
-rw-r--r--arch/arm/boot/dts/intel-ixp42x-gateway-7001.dts3
-rw-r--r--arch/arm/boot/dts/intel-ixp42x-netgear-wg302v1.dts (renamed from arch/arm/boot/dts/intel-ixp42x-netgear-wg302v2.dts)29
-rw-r--r--arch/arm/boot/dts/intel-ixp42x.dtsi2
-rw-r--r--arch/arm/boot/dts/iwg20d-q7-common.dtsi2
-rw-r--r--arch/arm/boot/dts/kirkwood-c200-v1.dts310
-rw-r--r--arch/arm/boot/dts/lan966x-pcb8291.dts64
-rw-r--r--arch/arm/boot/dts/lan966x.dtsi237
-rw-r--r--arch/arm/boot/dts/logicpd-torpedo-35xx-devkit.dts8
-rw-r--r--arch/arm/boot/dts/logicpd-torpedo-37xx-devkit.dts9
-rw-r--r--arch/arm/boot/dts/logicpd-torpedo-baseboard.dtsi41
-rw-r--r--arch/arm/boot/dts/meson.dtsi8
-rw-r--r--arch/arm/boot/dts/meson8.dtsi24
-rw-r--r--arch/arm/boot/dts/meson8b.dtsi24
-rw-r--r--arch/arm/boot/dts/mstar-infinity.dtsi34
-rw-r--r--arch/arm/boot/dts/mstar-infinity2m-ssd201-som2d01.dtsi20
-rw-r--r--arch/arm/boot/dts/mstar-infinity2m-ssd202d-100ask-dongshanpione.dts25
-rw-r--r--arch/arm/boot/dts/mstar-infinity2m-ssd202d-miyoo-mini.dts25
-rw-r--r--arch/arm/boot/dts/mstar-infinity2m-ssd202d-wirelesstag-ido-sbc2d06-v1b-22w.dts23
-rw-r--r--arch/arm/boot/dts/mstar-infinity2m-ssd202d-wirelesstag-ido-som2d01.dtsi28
-rw-r--r--arch/arm/boot/dts/mstar-infinity2m-ssd20xd.dtsi5
-rw-r--r--arch/arm/boot/dts/mstar-infinity2m.dtsi17
-rw-r--r--arch/arm/boot/dts/mstar-infinity3.dtsi58
-rw-r--r--arch/arm/boot/dts/mstar-v7.dtsi9
-rw-r--r--arch/arm/boot/dts/mt6582-prestigio-pmt5008-3g.dts43
-rw-r--r--arch/arm/boot/dts/mt6582.dtsi128
-rw-r--r--arch/arm/boot/dts/nuvoton-wpcm450-supermicro-x9sci-ln4f.dts43
-rw-r--r--arch/arm/boot/dts/nuvoton-wpcm450.dtsi384
-rw-r--r--arch/arm/boot/dts/omap3-beagle-ab4.dts47
-rw-r--r--arch/arm/boot/dts/omap3-beagle.dts33
-rw-r--r--arch/arm/boot/dts/omap3-devkit8000-common.dtsi18
-rw-r--r--arch/arm/boot/dts/omap3-devkit8000.dts33
-rw-r--r--arch/arm/boot/dts/openbmc-flash-layout-64.dtsi2
-rw-r--r--arch/arm/boot/dts/openbmc-flash-layout.dtsi2
-rw-r--r--arch/arm/boot/dts/ox810se-wd-mbwe.dts4
-rw-r--r--arch/arm/boot/dts/ox810se.dtsi18
-rw-r--r--arch/arm/boot/dts/qcom-apq8026-lg-lenok.dts132
-rw-r--r--arch/arm/boot/dts/qcom-apq8060-dragonboard.dts6
-rw-r--r--arch/arm/boot/dts/qcom-apq8064-asus-nexus7-flo.dts3
-rw-r--r--arch/arm/boot/dts/qcom-apq8064.dtsi19
-rw-r--r--arch/arm/boot/dts/qcom-ipq4019.dtsi4
-rw-r--r--arch/arm/boot/dts/qcom-mdm9615.dtsi3
-rw-r--r--arch/arm/boot/dts/qcom-msm8226.dtsi125
-rw-r--r--arch/arm/boot/dts/qcom-msm8660.dtsi3
-rw-r--r--arch/arm/boot/dts/qcom-msm8960-cdp.dts2
-rw-r--r--arch/arm/boot/dts/qcom-msm8960.dtsi30
-rw-r--r--arch/arm/boot/dts/qcom-pm8226.dtsi43
-rw-r--r--arch/arm/boot/dts/qcom-sdx55.dtsi4
-rw-r--r--arch/arm/boot/dts/r8a7740-armadillo800eva.dts2
-rw-r--r--arch/arm/boot/dts/r8a7742-iwg21d-q7-dbcm-ca.dts4
-rw-r--r--arch/arm/boot/dts/r8a7742-iwg21d-q7.dts4
-rw-r--r--arch/arm/boot/dts/r8a7742-iwg21m.dtsi2
-rw-r--r--arch/arm/boot/dts/r8a77470-iwg23s-sbc.dts2
-rw-r--r--arch/arm/boot/dts/r9a06g032-rzn1d400-db.dts5
-rw-r--r--arch/arm/boot/dts/r9a06g032.dtsi27
-rw-r--r--arch/arm/boot/dts/rk3188-px3-evb.dts2
-rw-r--r--arch/arm/boot/dts/rk322x.dtsi4
-rw-r--r--arch/arm/boot/dts/rk3288.dtsi3
-rw-r--r--arch/arm/boot/dts/rv1108-elgin-r1.dts1
-rw-r--r--arch/arm/boot/dts/rv1108-evb.dts1
-rw-r--r--arch/arm/boot/dts/s3c2416-pinctrl.dtsi60
-rw-r--r--arch/arm/boot/dts/s3c6410-mini6410.dts4
-rw-r--r--arch/arm/boot/dts/s3c64xx-pinctrl.dtsi210
-rw-r--r--arch/arm/boot/dts/s3c64xx.dtsi16
-rw-r--r--arch/arm/boot/dts/s5pv210-aquila.dts2
-rw-r--r--arch/arm/boot/dts/s5pv210-aries.dtsi40
-rw-r--r--arch/arm/boot/dts/s5pv210-fascinate4g.dts12
-rw-r--r--arch/arm/boot/dts/s5pv210-galaxys.dts16
-rw-r--r--arch/arm/boot/dts/s5pv210-pinctrl.dtsi226
-rw-r--r--arch/arm/boot/dts/sam9x60.dtsi10
-rw-r--r--arch/arm/boot/dts/sama5d2.dtsi11
-rw-r--r--arch/arm/boot/dts/sama5d3.dtsi6
-rw-r--r--arch/arm/boot/dts/sama5d4.dtsi9
-rw-r--r--arch/arm/boot/dts/sama7g5.dtsi243
-rw-r--r--arch/arm/boot/dts/socfpga_arria10_mercury_aa1.dts2
-rw-r--r--arch/arm/boot/dts/socfpga_arria10_socdk.dtsi2
-rw-r--r--arch/arm/boot/dts/socfpga_arria5_socdk.dts4
-rw-r--r--arch/arm/boot/dts/socfpga_cyclone5_chameleon96.dts2
-rw-r--r--arch/arm/boot/dts/socfpga_cyclone5_de0_nano_soc.dts2
-rw-r--r--arch/arm/boot/dts/socfpga_cyclone5_socdk.dts2
-rw-r--r--arch/arm/boot/dts/socfpga_cyclone5_sockit.dts2
-rw-r--r--arch/arm/boot/dts/socfpga_cyclone5_sodia.dts2
-rw-r--r--arch/arm/boot/dts/spear320-hmi.dts1
-rw-r--r--arch/arm/boot/dts/ste-ab8500.dtsi39
-rw-r--r--arch/arm/boot/dts/ste-ab8505.dtsi34
-rw-r--r--arch/arm/boot/dts/ste-href-ab8500.dtsi2
-rw-r--r--arch/arm/boot/dts/ste-href.dtsi25
-rw-r--r--arch/arm/boot/dts/ste-snowball.dts27
-rw-r--r--arch/arm/boot/dts/ste-ux500-samsung-codina.dts22
-rw-r--r--arch/arm/boot/dts/ste-ux500-samsung-gavini.dts22
-rw-r--r--arch/arm/boot/dts/ste-ux500-samsung-golden.dts22
-rw-r--r--arch/arm/boot/dts/ste-ux500-samsung-janice.dts24
-rw-r--r--arch/arm/boot/dts/ste-ux500-samsung-kyle.dts22
-rw-r--r--arch/arm/boot/dts/ste-ux500-samsung-skomer.dts26
-rw-r--r--arch/arm/boot/dts/stih407-clock.dtsi101
-rw-r--r--arch/arm/boot/dts/stih407-family.dtsi262
-rw-r--r--arch/arm/boot/dts/stih410-b2120.dts16
-rw-r--r--arch/arm/boot/dts/stih410-b2260.dts30
-rw-r--r--arch/arm/boot/dts/stih410-clock.dtsi100
-rw-r--r--arch/arm/boot/dts/stih410.dtsi52
-rw-r--r--arch/arm/boot/dts/stih418-b2199.dts22
-rw-r--r--arch/arm/boot/dts/stih418-clock.dtsi101
-rw-r--r--arch/arm/boot/dts/stih418.dtsi38
-rw-r--r--arch/arm/boot/dts/stihxxx-b2120.dtsi22
-rw-r--r--arch/arm/boot/dts/stm32429i-eval.dts12
-rw-r--r--arch/arm/boot/dts/stm32746g-eval.dts12
-rw-r--r--arch/arm/boot/dts/stm32f429-disco.dts12
-rw-r--r--arch/arm/boot/dts/stm32f429.dtsi57
-rw-r--r--arch/arm/boot/dts/stm32f469-disco.dts16
-rw-r--r--arch/arm/boot/dts/stm32f746-disco.dts12
-rw-r--r--arch/arm/boot/dts/stm32f746.dtsi47
-rw-r--r--arch/arm/boot/dts/stm32f769-disco.dts12
-rw-r--r--arch/arm/boot/dts/stm32mp13-pinctrl.dtsi81
-rw-r--r--arch/arm/boot/dts/stm32mp131.dtsi89
-rw-r--r--arch/arm/boot/dts/stm32mp135f-dk.dts7
-rw-r--r--arch/arm/boot/dts/stm32mp15-pinctrl.dtsi94
-rw-r--r--arch/arm/boot/dts/stm32mp151.dtsi37
-rw-r--r--arch/arm/boot/dts/stm32mp153.dtsi7
-rw-r--r--arch/arm/boot/dts/stm32mp157a-icore-stm32mp1-ctouch2.dts2
-rw-r--r--arch/arm/boot/dts/stm32mp157a-icore-stm32mp1-edimm2.2.dts2
-rw-r--r--arch/arm/boot/dts/stm32mp157a-iot-box.dts2
-rw-r--r--arch/arm/boot/dts/stm32mp157a-microgea-stm32mp1-microdev2.0-of7.dts4
-rw-r--r--arch/arm/boot/dts/stm32mp157a-microgea-stm32mp1-microdev2.0.dts4
-rw-r--r--arch/arm/boot/dts/stm32mp157a-stinger96.dtsi6
-rw-r--r--arch/arm/boot/dts/stm32mp157c-ed1.dts2
-rw-r--r--arch/arm/boot/dts/stm32mp157c-emsbc-argon.dts53
-rw-r--r--arch/arm/boot/dts/stm32mp157c-emstamp-argon.dtsi552
-rw-r--r--arch/arm/boot/dts/stm32mp157c-lxa-mc1.dts2
-rw-r--r--arch/arm/boot/dts/stm32mp157c-odyssey.dts2
-rw-r--r--arch/arm/boot/dts/stm32mp15xx-dhcom-drc02.dtsi4
-rw-r--r--arch/arm/boot/dts/stm32mp15xx-dhcom-pdk2.dtsi4
-rw-r--r--arch/arm/boot/dts/stm32mp15xx-dhcom-picoitx.dtsi4
-rw-r--r--arch/arm/boot/dts/stm32mp15xx-dhcom-som.dtsi3
-rw-r--r--arch/arm/boot/dts/stm32mp15xx-dhcor-avenger96.dtsi6
-rw-r--r--arch/arm/boot/dts/stm32mp15xx-dhcor-som.dtsi56
-rw-r--r--arch/arm/boot/dts/stm32mp15xx-dkx.dtsi4
-rw-r--r--arch/arm/boot/dts/sun7i-a20-haoyu-marsboard.dts182
-rw-r--r--arch/arm/boot/dts/sun8i-h3-nanopi-neo-air.dts28
-rw-r--r--arch/arm/boot/dts/sun8i-h3-nanopi-neo.dts4
-rw-r--r--arch/arm/boot/dts/sun8i-h3.dtsi2
-rw-r--r--arch/arm/boot/dts/sun8i-v3s.dtsi22
-rw-r--r--arch/arm/boot/dts/sunxi-h3-h5.dtsi18
-rw-r--r--arch/arm/boot/dts/tegra124-nyan-big-fhd.dts10
-rw-r--r--arch/arm/boot/dts/tegra124-nyan-big.dts15
-rw-r--r--arch/arm/boot/dts/tegra124-nyan-blaze.dts15
-rw-r--r--arch/arm/boot/dts/tegra124-venice2.dts14
-rw-r--r--arch/arm/boot/dts/tegra20-asus-tf101.dts12
-rw-r--r--arch/arm/boot/dts/tegra20-colibri.dtsi2
-rw-r--r--arch/arm/boot/dts/tegra20-paz00.dts6
-rw-r--r--arch/arm/boot/dts/tegra20-tamonten.dtsi6
-rw-r--r--arch/arm/boot/dts/tegra30-asus-tf700t.dts2
-rw-r--r--arch/arm/boot/dts/tegra30-asus-transformer-common.dtsi2
-rw-r--r--arch/arm/boot/dts/tegra30-colibri.dtsi2
-rw-r--r--arch/arm/boot/dts/tegra30-ouya.dts2
-rw-r--r--arch/arm/boot/dts/tegra30-pegatron-chagall.dts2
-rw-r--r--arch/arm/boot/dts/vf-colibri-eval-v3.dtsi2
-rw-r--r--arch/arm/configs/davinci_all_defconfig1
-rw-r--r--arch/arm/configs/exynos_defconfig1
-rw-r--r--arch/arm/configs/ezx_defconfig1
-rw-r--r--arch/arm/configs/imote2_defconfig1
-rw-r--r--arch/arm/configs/imxrt_defconfig35
-rw-r--r--arch/arm/configs/integrator_defconfig1
-rw-r--r--arch/arm/configs/iop32x_defconfig1
-rw-r--r--arch/arm/configs/keystone_defconfig1
-rw-r--r--arch/arm/configs/lart_defconfig1
-rw-r--r--arch/arm/configs/multi_v5_defconfig26
-rw-r--r--arch/arm/configs/multi_v7_defconfig63
-rw-r--r--arch/arm/configs/netwinder_defconfig1
-rw-r--r--arch/arm/configs/pxa_defconfig3
-rw-r--r--arch/arm/configs/sama7_defconfig31
-rw-r--r--arch/arm/configs/shmobile_defconfig4
-rw-r--r--arch/arm/configs/versatile_defconfig1
-rw-r--r--arch/arm/configs/viper_defconfig1
-rw-r--r--arch/arm/configs/zeus_defconfig1
-rw-r--r--arch/arm/crypto/aes-neonbs-core.S105
-rw-r--r--arch/arm/crypto/aes-neonbs-glue.c35
-rw-r--r--arch/arm/crypto/blake2s-shash.c4
-rw-r--r--arch/arm/include/asm/assembler.h216
-rw-r--r--arch/arm/include/asm/cacheflush.h12
-rw-r--r--arch/arm/include/asm/current.h46
-rw-r--r--arch/arm/include/asm/elf.h3
-rw-r--r--arch/arm/include/asm/entry-macro-multi.S40
-rw-r--r--arch/arm/include/asm/ftrace.h4
-rw-r--r--arch/arm/include/asm/hardware/entry-macro-iomd.S131
-rw-r--r--arch/arm/include/asm/insn.h17
-rw-r--r--arch/arm/include/asm/irq.h1
-rw-r--r--arch/arm/include/asm/mach/arch.h2
-rw-r--r--arch/arm/include/asm/mmu.h2
-rw-r--r--arch/arm/include/asm/mmu_context.h22
-rw-r--r--arch/arm/include/asm/page.h3
-rw-r--r--arch/arm/include/asm/paravirt_api_clock.h1
-rw-r--r--arch/arm/include/asm/percpu.h35
-rw-r--r--arch/arm/include/asm/pgtable-2level.h2
-rw-r--r--arch/arm/include/asm/processor.h1
-rw-r--r--arch/arm/include/asm/smp.h5
-rw-r--r--arch/arm/include/asm/spectre.h38
-rw-r--r--arch/arm/include/asm/stacktrace.h5
-rw-r--r--arch/arm/include/asm/switch_to.h3
-rw-r--r--arch/arm/include/asm/thread_info.h35
-rw-r--r--arch/arm/include/asm/tls.h31
-rw-r--r--arch/arm/include/asm/uaccess.h32
-rw-r--r--arch/arm/include/asm/v7m.h3
-rw-r--r--arch/arm/include/asm/vmlinux.lds.h43
-rw-r--r--arch/arm/include/asm/xor.h42
-rw-r--r--arch/arm/include/uapi/asm/signal.h2
-rw-r--r--arch/arm/kernel/Makefile3
-rw-r--r--arch/arm/kernel/asm-offsets.c3
-rw-r--r--arch/arm/kernel/entry-armv.S262
-rw-r--r--arch/arm/kernel/entry-common.S40
-rw-r--r--arch/arm/kernel/entry-ftrace.S128
-rw-r--r--arch/arm/kernel/entry-header.S47
-rw-r--r--arch/arm/kernel/entry-v7m.S39
-rw-r--r--arch/arm/kernel/ftrace.c62
-rw-r--r--arch/arm/kernel/head-common.S4
-rw-r--r--arch/arm/kernel/head.S7
-rw-r--r--arch/arm/kernel/irq.c61
-rw-r--r--arch/arm/kernel/kgdb.c36
-rw-r--r--arch/arm/kernel/module.c90
-rw-r--r--arch/arm/kernel/process.c7
-rw-r--r--arch/arm/kernel/return_address.c3
-rw-r--r--arch/arm/kernel/setup.c8
-rw-r--r--arch/arm/kernel/sleep.S13
-rw-r--r--arch/arm/kernel/smp.c11
-rw-r--r--arch/arm/kernel/spectre.c71
-rw-r--r--arch/arm/kernel/stacktrace.c3
-rw-r--r--arch/arm/kernel/swp_emulate.c2
-rw-r--r--arch/arm/kernel/traps.c158
-rw-r--r--arch/arm/kernel/unwind.c64
-rw-r--r--arch/arm/kernel/vmlinux.lds.S4
-rw-r--r--arch/arm/lib/backtrace-clang.S14
-rw-r--r--arch/arm/lib/backtrace.S8
-rw-r--r--arch/arm/lib/call_with_stack.S33
-rw-r--r--arch/arm/lib/copy_from_user.S13
-rw-r--r--arch/arm/lib/copy_template.S67
-rw-r--r--arch/arm/lib/copy_to_user.S13
-rw-r--r--arch/arm/lib/memcpy.S13
-rw-r--r--arch/arm/lib/memmove.S60
-rw-r--r--arch/arm/lib/memset.S7
-rw-r--r--arch/arm/lib/uaccess_with_memcpy.c10
-rw-r--r--arch/arm/lib/xor-neon.c12
-rw-r--r--arch/arm/mach-airoha/Makefile (renamed from arch/nds32/kernel/vdso/.gitignore)2
-rw-r--r--arch/arm/mach-airoha/airoha.c16
-rw-r--r--arch/arm/mach-at91/Kconfig1
-rw-r--r--arch/arm/mach-at91/pm.c27
-rw-r--r--arch/arm/mach-at91/pm_suspend.S4
-rw-r--r--arch/arm/mach-bcm/Kconfig1
-rw-r--r--arch/arm/mach-bcm/Makefile1
-rw-r--r--arch/arm/mach-dove/irq.c6
-rw-r--r--arch/arm/mach-exynos/firmware.c4
-rw-r--r--arch/arm/mach-exynos/mcpm-exynos.c6
-rw-r--r--arch/arm/mach-footbridge/common.c87
-rw-r--r--arch/arm/mach-footbridge/include/mach/entry-macro.S107
-rw-r--r--arch/arm/mach-footbridge/include/mach/hardware.h20
-rw-r--r--arch/arm/mach-footbridge/include/mach/io.h20
-rw-r--r--arch/arm/mach-imx/Kconfig7
-rw-r--r--arch/arm/mach-imx/Makefile2
-rw-r--r--arch/arm/mach-imx/mach-imxrt.c19
-rw-r--r--arch/arm/mach-integrator/Kconfig37
-rw-r--r--arch/arm/mach-integrator/hardware.h5
-rw-r--r--arch/arm/mach-iop32x/cp6.c10
-rw-r--r--arch/arm/mach-iop32x/include/mach/entry-macro.S31
-rw-r--r--arch/arm/mach-iop32x/include/mach/irqs.h2
-rw-r--r--arch/arm/mach-iop32x/iop3xx.h1
-rw-r--r--arch/arm/mach-iop32x/irq.c29
-rw-r--r--arch/arm/mach-iop32x/irqs.h60
-rw-r--r--arch/arm/mach-ixp4xx/Kconfig57
-rw-r--r--arch/arm/mach-ixp4xx/Makefile19
-rw-r--r--arch/arm/mach-ixp4xx/common-pci.c451
-rw-r--r--arch/arm/mach-ixp4xx/common.c448
-rw-r--r--arch/arm/mach-ixp4xx/gateway7001-pci.c61
-rw-r--r--arch/arm/mach-ixp4xx/gateway7001-setup.c113
-rw-r--r--arch/arm/mach-ixp4xx/goramo_mlr.c532
-rw-r--r--arch/arm/mach-ixp4xx/include/mach/hardware.h32
-rw-r--r--arch/arm/mach-ixp4xx/include/mach/io.h545
-rw-r--r--arch/arm/mach-ixp4xx/include/mach/ixp4xx-regs.h303
-rw-r--r--arch/arm/mach-ixp4xx/include/mach/platform.h102
-rw-r--r--arch/arm/mach-ixp4xx/include/mach/udc.h8
-rw-r--r--arch/arm/mach-ixp4xx/include/mach/uncompress.h4
-rw-r--r--arch/arm/mach-ixp4xx/irqs.h64
-rw-r--r--arch/arm/mach-mmp/sram.c22
-rw-r--r--arch/arm/mach-mstar/Kconfig2
-rw-r--r--arch/arm/mach-mv78xx0/irq.c3
-rw-r--r--arch/arm/mach-nspire/Kconfig1
-rw-r--r--arch/arm/mach-omap2/display.c2
-rw-r--r--arch/arm/mach-omap2/omap_hwmod.c4
-rw-r--r--arch/arm/mach-orion5x/Kconfig2
-rw-r--r--arch/arm/mach-orion5x/irq.c2
-rw-r--r--arch/arm/mach-pxa/Kconfig10
-rw-r--r--arch/arm/mach-pxa/Makefile2
-rw-r--r--arch/arm/mach-pxa/corgi.c26
-rw-r--r--arch/arm/mach-pxa/hx4700.c10
-rw-r--r--arch/arm/mach-pxa/icontrol.c26
-rw-r--r--arch/arm/mach-pxa/include/mach/uncompress.h5
-rw-r--r--arch/arm/mach-pxa/littleton.c10
-rw-r--r--arch/arm/mach-pxa/magician.c12
-rw-r--r--arch/arm/mach-pxa/poodle.c14
-rw-r--r--arch/arm/mach-pxa/spitz.c26
-rw-r--r--arch/arm/mach-pxa/stargate2.c1030
-rw-r--r--arch/arm/mach-pxa/z2.c20
-rw-r--r--arch/arm/mach-qcom/platsmp.c3
-rw-r--r--arch/arm/mach-rpc/fiq.S5
-rw-r--r--arch/arm/mach-rpc/include/mach/entry-macro.S13
-rw-r--r--arch/arm/mach-rpc/irq.c95
-rw-r--r--arch/arm/mach-s3c/Kconfig12
-rw-r--r--arch/arm/mach-s3c/devs.c77
-rw-r--r--arch/arm/mach-s3c/mach-crag6410-module.c13
-rw-r--r--arch/arm/mach-s3c/mach-crag6410.c13
-rw-r--r--arch/arm/mach-s3c/setup-spi-s3c64xx.c9
-rw-r--r--arch/arm/mach-s3c/spi-core-s3c24xx.h6
-rw-r--r--arch/arm/mach-shmobile/Kconfig2
-rw-r--r--arch/arm/mach-socfpga/Kconfig2
-rw-r--r--arch/arm/mach-spear/spear13xx.c2
-rw-r--r--arch/arm/mach-ux500/Kconfig2
-rw-r--r--arch/arm/mm/Kconfig12
-rw-r--r--arch/arm/mm/cache-v7.S40
-rw-r--r--arch/arm/mm/context.c3
-rw-r--r--arch/arm/mm/init.c43
-rw-r--r--arch/arm/mm/ioremap.c18
-rw-r--r--arch/arm/mm/mmu.c2
-rw-r--r--arch/arm/mm/proc-v7-bugs.c208
-rw-r--r--arch/arm/net/bpf_jit_32.c4
-rw-r--r--arch/arm/plat-orion/gpio.c8
-rw-r--r--arch/arm/plat-orion/include/plat/orion-gpio.h3
-rw-r--r--arch/arm/probes/kprobes/Makefile3
-rw-r--r--arch/arm/probes/kprobes/actions-common.c8
-rw-r--r--arch/arm/probes/kprobes/actions-thumb.c16
-rw-r--r--arch/arm/vdso/Makefile2
-rw-r--r--arch/arm64/Kconfig124
-rw-r--r--arch/arm64/Kconfig.platforms9
-rw-r--r--arch/arm64/boot/dts/Makefile1
-rw-r--r--arch/arm64/boot/dts/altera/socfpga_stratix10.dtsi24
-rw-r--r--arch/arm64/boot/dts/altera/socfpga_stratix10_socdk.dts3
-rw-r--r--arch/arm64/boot/dts/altera/socfpga_stratix10_socdk_nand.dts3
-rw-r--r--arch/arm64/boot/dts/amlogic/Makefile7
-rw-r--r--arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi49
-rw-r--r--arch/arm64/boot/dts/amlogic/meson-g12a-sei510.dts8
-rw-r--r--arch/arm64/boot/dts/amlogic/meson-g12b-odroid-n2.dtsi4
-rw-r--r--arch/arm64/boot/dts/amlogic/meson-gx.dtsi6
-rw-r--r--arch/arm64/boot/dts/amlogic/meson-gxl-s905d-vero4k-plus.dts117
-rw-r--r--arch/arm64/boot/dts/amlogic/meson-s4-s805x2-aq222.dts30
-rw-r--r--arch/arm64/boot/dts/amlogic/meson-s4.dtsi99
-rw-r--r--arch/arm64/boot/dts/amlogic/meson-sm1-a95xf3-air-gbit.dts129
-rw-r--r--arch/arm64/boot/dts/amlogic/meson-sm1-a95xf3-air.dts108
-rw-r--r--arch/arm64/boot/dts/amlogic/meson-sm1-ac2xx.dtsi300
-rw-r--r--arch/arm64/boot/dts/amlogic/meson-sm1-bananapi-m5.dts2
-rw-r--r--arch/arm64/boot/dts/amlogic/meson-sm1-h96-max.dts145
-rw-r--r--arch/arm64/boot/dts/amlogic/meson-sm1-odroid.dtsi2
-rw-r--r--arch/arm64/boot/dts/amlogic/meson-sm1-sei610.dts8
-rw-r--r--arch/arm64/boot/dts/amlogic/meson-sm1-x96-air-gbit.dts133
-rw-r--r--arch/arm64/boot/dts/amlogic/meson-sm1-x96-air.dts112
-rw-r--r--arch/arm64/boot/dts/amlogic/meson-sm1.dtsi27
-rw-r--r--arch/arm64/boot/dts/apple/t8103.dtsi24
-rw-r--r--arch/arm64/boot/dts/arm/Makefile2
-rw-r--r--arch/arm64/boot/dts/arm/juno-base.dtsi5
-rw-r--r--arch/arm64/boot/dts/arm/juno-r1-scmi.dts23
-rw-r--r--arch/arm64/boot/dts/arm/juno-r2-scmi.dts23
-rw-r--r--arch/arm64/boot/dts/arm/juno-scmi.dts9
-rw-r--r--arch/arm64/boot/dts/arm/juno-scmi.dtsi199
-rw-r--r--arch/arm64/boot/dts/broadcom/Makefile3
-rw-r--r--arch/arm64/boot/dts/broadcom/bcm2837-rpi-zero-2-w.dts2
-rw-r--r--arch/arm64/boot/dts/broadcom/bcm4908/bcm4908.dtsi161
-rw-r--r--arch/arm64/boot/dts/broadcom/northstar2/ns2-svk.dts8
-rw-r--r--arch/arm64/boot/dts/broadcom/northstar2/ns2.dtsi8
-rw-r--r--arch/arm64/boot/dts/broadcom/stingray/stingray.dtsi6
-rw-r--r--arch/arm64/boot/dts/exynos/Makefile8
-rw-r--r--arch/arm64/boot/dts/exynos/exynos5433-pinctrl.dtsi211
-rw-r--r--arch/arm64/boot/dts/exynos/exynos5433-tm2-common.dtsi276
-rw-r--r--arch/arm64/boot/dts/exynos/exynos5433.dtsi7
-rw-r--r--arch/arm64/boot/dts/exynos/exynos7-espresso.dts11
-rw-r--r--arch/arm64/boot/dts/exynos/exynos7-pinctrl.dtsi176
-rw-r--r--arch/arm64/boot/dts/exynos/exynos7.dtsi44
-rw-r--r--arch/arm64/boot/dts/exynos/exynos7885-jackpotlte.dts92
-rw-r--r--arch/arm64/boot/dts/exynos/exynos7885-pinctrl.dtsi855
-rw-r--r--arch/arm64/boot/dts/exynos/exynos7885.dtsi423
-rw-r--r--arch/arm64/boot/dts/exynos/exynos850-e850-96.dts195
-rw-r--r--arch/arm64/boot/dts/exynos/exynos850-pinctrl.dtsi663
-rw-r--r--arch/arm64/boot/dts/exynos/exynos850.dtsi701
-rw-r--r--arch/arm64/boot/dts/exynos/exynosautov9-pinctrl.dtsi50
-rw-r--r--arch/arm64/boot/dts/exynos/exynosautov9.dtsi2
-rw-r--r--arch/arm64/boot/dts/freescale/Makefile55
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-ls1028a-kontron-sl28.dts4
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-ls1028a-qds-13bb.dts146
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-ls1028a-qds-65bb.dts138
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-ls1028a-qds-7777.dts99
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-ls1028a-qds-85bb.dts134
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-ls1028a-qds-899b.dts86
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-ls1028a-qds-9999.dts97
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-ls1028a-qds.dts24
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi11
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi24
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi24
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-lx2160a-clearfog-itx.dtsi4
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi30
-rw-r--r--arch/arm64/boot/dts/freescale/imx8-ss-lsio.dtsi16
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mm-beacon-baseboard.dtsi57
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mm-emcon-avari.dts23
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mm-emcon-avari.dtsi139
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mm-emcon.dtsi627
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mm-evk.dtsi55
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mm-pinfunc.h7
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mm-prt8mm.dts304
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mm-tqma8mqml-mba8mx.dts19
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mm-tqma8mqml.dtsi5
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mm-venice-gw71xx.dtsi49
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mm-venice-gw72xx-0x-imx219.dts93
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mm-venice-gw72xx-0x-rs232-rts.dts53
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mm-venice-gw72xx-0x-rs422.dts61
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mm-venice-gw72xx-0x-rs485.dts61
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mm-venice-gw72xx.dtsi78
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mm-venice-gw73xx-0x-imx219.dts93
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mm-venice-gw73xx-0x-rs232-rts.dts53
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mm-venice-gw73xx-0x-rs422.dts61
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mm-venice-gw73xx-0x-rs485.dts61
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mm-venice-gw73xx.dtsi78
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mm-venice-gw7901.dts59
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mm-venice-gw7902.dts89
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mm-venice-gw7903.dts836
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mm-verdin-dahlia.dtsi150
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mm-verdin-dev.dtsi67
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mm-verdin-nonwifi-dahlia.dts18
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mm-verdin-nonwifi-dev.dts18
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mm-verdin-nonwifi.dtsi75
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mm-verdin-wifi-dahlia.dts18
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mm-verdin-wifi-dev.dts18
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mm-verdin-wifi.dtsi94
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mm-verdin.dtsi1264
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mm.dtsi69
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mn-venice-gw7902.dts51
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mn.dtsi104
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mp-evk.dts50
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mp-phycore-som.dtsi39
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mp.dtsi1
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mq-evk.dts39
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mq-librem5.dtsi5
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mq-mnt-reform2.dts144
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mq-tqma8mq.dtsi4
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mq.dtsi74
-rw-r--r--arch/arm64/boot/dts/freescale/imx8qm-ss-conn.dtsi4
-rw-r--r--arch/arm64/boot/dts/freescale/imx8qm-ss-lsio.dtsi8
-rw-r--r--arch/arm64/boot/dts/freescale/imx8qm.dtsi18
-rw-r--r--arch/arm64/boot/dts/freescale/imx8qxp-ss-adma.dtsi8
-rw-r--r--arch/arm64/boot/dts/freescale/imx8qxp-ss-lsio.dtsi8
-rw-r--r--arch/arm64/boot/dts/freescale/imx8ulp.dtsi2
-rw-r--r--arch/arm64/boot/dts/freescale/mba8mx.dtsi8
-rw-r--r--arch/arm64/boot/dts/intel/socfpga_agilex.dtsi9
-rw-r--r--arch/arm64/boot/dts/intel/socfpga_agilex_socdk.dts7
-rw-r--r--arch/arm64/boot/dts/intel/socfpga_agilex_socdk_nand.dts1
-rw-r--r--arch/arm64/boot/dts/intel/socfpga_n5x_socdk.dts10
-rw-r--r--arch/arm64/boot/dts/lg/lg1312.dtsi3
-rw-r--r--arch/arm64/boot/dts/lg/lg1313.dtsi3
-rw-r--r--arch/arm64/boot/dts/marvell/armada-3720-turris-mox.dts8
-rw-r--r--arch/arm64/boot/dts/marvell/armada-37xx.dtsi3
-rw-r--r--arch/arm64/boot/dts/mediatek/mt2712-evb.dts1
-rw-r--r--arch/arm64/boot/dts/mediatek/mt2712e.dtsi14
-rw-r--r--arch/arm64/boot/dts/mediatek/mt6358.dtsi12
-rw-r--r--arch/arm64/boot/dts/mediatek/mt7986a-rfb.dts3
-rw-r--r--arch/arm64/boot/dts/mediatek/mt7986a.dtsi68
-rw-r--r--arch/arm64/boot/dts/mediatek/mt7986b-rfb.dts3
-rw-r--r--arch/arm64/boot/dts/mediatek/mt8183.dtsi12
-rw-r--r--arch/arm64/boot/dts/mediatek/mt8192.dtsi299
-rw-r--r--arch/arm64/boot/dts/microchip/sparx5.dtsi5
-rw-r--r--arch/arm64/boot/dts/nvidia/Makefile11
-rw-r--r--arch/arm64/boot/dts/nvidia/tegra186.dtsi46
-rw-r--r--arch/arm64/boot/dts/nvidia/tegra194-p3509-0000.dtsi25
-rw-r--r--arch/arm64/boot/dts/nvidia/tegra194.dtsi56
-rw-r--r--arch/arm64/boot/dts/nvidia/tegra234-p3737-0000+p3701-0000.dts1824
-rw-r--r--arch/arm64/boot/dts/nvidia/tegra234.dtsi1010
-rw-r--r--arch/arm64/boot/dts/qcom/Makefile12
-rw-r--r--arch/arm64/boot/dts/qcom/apq8016-sbc.dts12
-rw-r--r--arch/arm64/boot/dts/qcom/ipq6018.dtsi13
-rw-r--r--arch/arm64/boot/dts/qcom/ipq8074.dtsi35
-rw-r--r--arch/arm64/boot/dts/qcom/msm8916-longcheer-l8150.dts23
-rw-r--r--arch/arm64/boot/dts/qcom/msm8916-samsung-j5.dts2
-rw-r--r--arch/arm64/boot/dts/qcom/msm8916.dtsi6
-rw-r--r--arch/arm64/boot/dts/qcom/msm8953.dtsi1326
-rw-r--r--arch/arm64/boot/dts/qcom/msm8992-lg-bullhead-rev-10.dts14
-rw-r--r--arch/arm64/boot/dts/qcom/msm8992-lg-bullhead-rev-101.dts14
-rw-r--r--arch/arm64/boot/dts/qcom/msm8992-lg-bullhead.dtsi (renamed from arch/arm64/boot/dts/qcom/msm8992-bullhead-rev-101.dts)2
-rw-r--r--arch/arm64/boot/dts/qcom/msm8994-huawei-angler-rev-101.dts (renamed from arch/arm64/boot/dts/qcom/msm8994-angler-rev-101.dts)0
-rw-r--r--arch/arm64/boot/dts/qcom/msm8994.dtsi7
-rw-r--r--arch/arm64/boot/dts/qcom/msm8996-mtp.dts2
-rw-r--r--arch/arm64/boot/dts/qcom/msm8996.dtsi34
-rw-r--r--arch/arm64/boot/dts/qcom/msm8998.dtsi56
-rw-r--r--arch/arm64/boot/dts/qcom/pm6150l.dtsi10
-rw-r--r--arch/arm64/boot/dts/qcom/pm8953.dtsi90
-rw-r--r--arch/arm64/boot/dts/qcom/pms405.dtsi4
-rw-r--r--arch/arm64/boot/dts/qcom/qcs404.dtsi4
-rw-r--r--arch/arm64/boot/dts/qcom/sc7180-trogdor-coachz.dtsi16
-rw-r--r--arch/arm64/boot/dts/qcom/sc7180-trogdor-homestar.dtsi16
-rw-r--r--arch/arm64/boot/dts/qcom/sc7180-trogdor.dtsi126
-rw-r--r--arch/arm64/boot/dts/qcom/sc7180.dtsi2
-rw-r--r--arch/arm64/boot/dts/qcom/sc7280-chrome-common.dtsi97
-rw-r--r--arch/arm64/boot/dts/qcom/sc7280-crd.dts12
-rw-r--r--arch/arm64/boot/dts/qcom/sc7280-herobrine-herobrine-r0.dts1352
-rw-r--r--arch/arm64/boot/dts/qcom/sc7280-herobrine-herobrine-r1.dts313
-rw-r--r--arch/arm64/boot/dts/qcom/sc7280-herobrine.dts14
-rw-r--r--arch/arm64/boot/dts/qcom/sc7280-herobrine.dtsi1105
-rw-r--r--arch/arm64/boot/dts/qcom/sc7280-idp-ec-h1.dtsi2
-rw-r--r--arch/arm64/boot/dts/qcom/sc7280-idp.dts20
-rw-r--r--arch/arm64/boot/dts/qcom/sc7280-idp.dtsi215
-rw-r--r--arch/arm64/boot/dts/qcom/sc7280-idp2.dts4
-rw-r--r--arch/arm64/boot/dts/qcom/sc7280-qcard.dtsi547
-rw-r--r--arch/arm64/boot/dts/qcom/sc7280.dtsi815
-rw-r--r--arch/arm64/boot/dts/qcom/sdm630.dtsi2
-rw-r--r--arch/arm64/boot/dts/qcom/sdm632-fairphone-fp3.dts183
-rw-r--r--arch/arm64/boot/dts/qcom/sdm632.dtsi81
-rw-r--r--arch/arm64/boot/dts/qcom/sdm845-cheza.dtsi2
-rw-r--r--arch/arm64/boot/dts/qcom/sdm845-db845c.dts7
-rw-r--r--arch/arm64/boot/dts/qcom/sdm845-oneplus-common.dtsi19
-rw-r--r--arch/arm64/boot/dts/qcom/sdm845-oneplus-enchilada.dts12
-rw-r--r--arch/arm64/boot/dts/qcom/sdm845-oneplus-fajita.dts12
-rw-r--r--arch/arm64/boot/dts/qcom/sdm845-shift-axolotl.dts736
-rw-r--r--arch/arm64/boot/dts/qcom/sdm845.dtsi115
-rw-r--r--arch/arm64/boot/dts/qcom/sdm850-lenovo-yoga-c630.dts38
-rw-r--r--arch/arm64/boot/dts/qcom/sdm850-samsung-w737.dts748
-rw-r--r--arch/arm64/boot/dts/qcom/sm6125.dtsi4
-rw-r--r--arch/arm64/boot/dts/qcom/sm7225-fairphone-fp4.dts9
-rw-r--r--arch/arm64/boot/dts/qcom/sm8150-microsoft-surface-duo.dts20
-rw-r--r--arch/arm64/boot/dts/qcom/sm8150.dtsi154
-rw-r--r--arch/arm64/boot/dts/qcom/sm8250.dtsi132
-rw-r--r--arch/arm64/boot/dts/qcom/sm8350.dtsi48
-rw-r--r--arch/arm64/boot/dts/qcom/sm8450-hdk.dts405
-rw-r--r--arch/arm64/boot/dts/qcom/sm8450-qrd.dts20
-rw-r--r--arch/arm64/boot/dts/qcom/sm8450.dtsi425
-rw-r--r--arch/arm64/boot/dts/renesas/Makefile3
-rw-r--r--arch/arm64/boot/dts/renesas/beacon-renesom-baseboard.dtsi9
-rw-r--r--arch/arm64/boot/dts/renesas/beacon-renesom-som.dtsi3
-rw-r--r--arch/arm64/boot/dts/renesas/gmsl-cameras.dtsi332
-rw-r--r--arch/arm64/boot/dts/renesas/hihope-common.dtsi2
-rw-r--r--arch/arm64/boot/dts/renesas/hihope-rzg2-ex-lvds.dtsi2
-rw-r--r--arch/arm64/boot/dts/renesas/r8a774a1.dtsi14
-rw-r--r--arch/arm64/boot/dts/renesas/r8a774b1-beacon-rzg2n-kit.dts2
-rw-r--r--arch/arm64/boot/dts/renesas/r8a774b1.dtsi4
-rw-r--r--arch/arm64/boot/dts/renesas/r8a774c0-ek874-idk-2121wr.dts2
-rw-r--r--arch/arm64/boot/dts/renesas/r8a774c0.dtsi10
-rw-r--r--arch/arm64/boot/dts/renesas/r8a774e1-beacon-rzg2h-kit.dts2
-rw-r--r--arch/arm64/boot/dts/renesas/r8a774e1.dtsi4
-rw-r--r--arch/arm64/boot/dts/renesas/r8a77951.dtsi26
-rw-r--r--arch/arm64/boot/dts/renesas/r8a77960.dtsi26
-rw-r--r--arch/arm64/boot/dts/renesas/r8a77961.dtsi43
-rw-r--r--arch/arm64/boot/dts/renesas/r8a77965.dtsi26
-rw-r--r--arch/arm64/boot/dts/renesas/r8a77970-eagle.dts102
-rw-r--r--arch/arm64/boot/dts/renesas/r8a77980-condor.dts191
-rw-r--r--arch/arm64/boot/dts/renesas/r8a77990.dtsi24
-rw-r--r--arch/arm64/boot/dts/renesas/r8a77995.dtsi24
-rw-r--r--arch/arm64/boot/dts/renesas/r8a779a0-falcon-csi-dsi.dtsi229
-rw-r--r--arch/arm64/boot/dts/renesas/r8a779a0.dtsi35
-rw-r--r--arch/arm64/boot/dts/renesas/r8a779f0-spider-cpu.dtsi28
-rw-r--r--arch/arm64/boot/dts/renesas/r8a779f0.dtsi86
-rw-r--r--arch/arm64/boot/dts/renesas/r9a07g044c1.dtsi32
-rw-r--r--arch/arm64/boot/dts/renesas/r9a07g044c2-smarc.dts91
-rw-r--r--arch/arm64/boot/dts/renesas/r9a07g044c2.dtsi20
-rw-r--r--arch/arm64/boot/dts/renesas/r9a07g044l2-smarc.dts2
-rw-r--r--arch/arm64/boot/dts/renesas/r9a07g054.dtsi491
-rw-r--r--arch/arm64/boot/dts/renesas/r9a07g054l1.dtsi25
-rw-r--r--arch/arm64/boot/dts/renesas/r9a07g054l2-smarc.dts26
-rw-r--r--arch/arm64/boot/dts/renesas/r9a07g054l2.dtsi13
-rw-r--r--arch/arm64/boot/dts/renesas/rz-smarc-common.dtsi207
-rw-r--r--arch/arm64/boot/dts/renesas/rzg2l-smarc-pinfunction.dtsi137
-rw-r--r--arch/arm64/boot/dts/renesas/rzg2l-smarc-som.dtsi2
-rw-r--r--arch/arm64/boot/dts/renesas/rzg2l-smarc.dtsi322
-rw-r--r--arch/arm64/boot/dts/renesas/rzg2lc-smarc-pinfunction.dtsi94
-rw-r--r--arch/arm64/boot/dts/renesas/rzg2lc-smarc-som.dtsi222
-rw-r--r--arch/arm64/boot/dts/renesas/rzg2lc-smarc.dtsi77
-rw-r--r--arch/arm64/boot/dts/renesas/ulcb-kf.dtsi141
-rw-r--r--arch/arm64/boot/dts/renesas/ulcb.dtsi20
-rw-r--r--arch/arm64/boot/dts/rockchip/Makefile3
-rw-r--r--arch/arm64/boot/dts/rockchip/px30.dtsi2
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3328-a1.dts1
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3328.dtsi2
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3399-firefly.dts11
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3399-gru-chromebook.dtsi2
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3399-gru.dtsi17
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3399-khadas-edge.dtsi2
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3399-leez-p710.dts2
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3399-orangepi.dts2
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3399-pinebook-pro.dts4
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3399-puma-haikou.dts1
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3399-puma.dtsi31
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3399-roc-pc.dtsi2
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtsi2
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dtsi2
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3399-sapphire.dtsi2
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3399.dtsi6
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3566-pinenote-v1.1.dts18
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3566-pinenote-v1.2.dts18
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3566-pinenote.dtsi639
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts138
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3568-bpi-r2-pro.dts457
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3568-evb1-v10.dts205
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3568.dtsi27
-rw-r--r--arch/arm64/boot/dts/rockchip/rk356x.dtsi261
-rw-r--r--arch/arm64/boot/dts/tesla/Makefile3
-rw-r--r--arch/arm64/boot/dts/tesla/fsd-evb.dts39
-rw-r--r--arch/arm64/boot/dts/tesla/fsd-pinctrl.dtsi335
-rw-r--r--arch/arm64/boot/dts/tesla/fsd.dtsi754
-rw-r--r--arch/arm64/boot/dts/ti/Makefile2
-rw-r--r--arch/arm64/boot/dts/ti/k3-am62-main.dtsi267
-rw-r--r--arch/arm64/boot/dts/ti/k3-am62-mcu.dtsi36
-rw-r--r--arch/arm64/boot/dts/ti/k3-am62-wakeup.dtsi41
-rw-r--r--arch/arm64/boot/dts/ti/k3-am62.dtsi105
-rw-r--r--arch/arm64/boot/dts/ti/k3-am625-sk.dts206
-rw-r--r--arch/arm64/boot/dts/ti/k3-am625.dtsi103
-rw-r--r--arch/arm64/boot/dts/ti/k3-am64-main.dtsi23
-rw-r--r--arch/arm64/boot/dts/ti/k3-am64.dtsi4
-rw-r--r--arch/arm64/boot/dts/ti/k3-am642-evm.dts4
-rw-r--r--arch/arm64/boot/dts/ti/k3-am642-sk.dts4
-rw-r--r--arch/arm64/boot/dts/ti/k3-am65-iot2050-common.dtsi2
-rw-r--r--arch/arm64/boot/dts/ti/k3-am65-main.dtsi5
-rw-r--r--arch/arm64/boot/dts/ti/k3-am65.dtsi1
-rw-r--r--arch/arm64/boot/dts/ti/k3-am654-base-board.dts8
-rw-r--r--arch/arm64/boot/dts/ti/k3-j7200-main.dtsi5
-rw-r--r--arch/arm64/boot/dts/ti/k3-j7200-som-p0.dtsi4
-rw-r--r--arch/arm64/boot/dts/ti/k3-j7200.dtsi1
-rw-r--r--arch/arm64/boot/dts/ti/k3-j721e-common-proc-board.dts4
-rw-r--r--arch/arm64/boot/dts/ti/k3-j721e-main.dtsi5
-rw-r--r--arch/arm64/boot/dts/ti/k3-j721e-sk.dts2
-rw-r--r--arch/arm64/boot/dts/ti/k3-j721e-som-p0.dtsi4
-rw-r--r--arch/arm64/boot/dts/ti/k3-j721e.dtsi1
-rw-r--r--arch/arm64/boot/dts/ti/k3-j721s2-common-proc-board.dts14
-rw-r--r--arch/arm64/boot/dts/ti/k3-j721s2-main.dtsi5
-rw-r--r--arch/arm64/boot/dts/ti/k3-j721s2-mcu-wakeup.dtsi4
-rw-r--r--arch/arm64/boot/dts/ti/k3-j721s2.dtsi23
-rw-r--r--arch/arm64/boot/dts/xilinx/zynqmp.dtsi84
-rw-r--r--arch/arm64/configs/defconfig156
-rw-r--r--arch/arm64/crypto/Kconfig2
-rw-r--r--arch/arm64/crypto/aes-glue.c22
-rw-r--r--arch/arm64/crypto/aes-modes.S18
-rw-r--r--arch/arm64/crypto/aes-neonbs-core.S264
-rw-r--r--arch/arm64/crypto/aes-neonbs-glue.c97
-rw-r--r--arch/arm64/crypto/sha3-ce-glue.c2
-rw-r--r--arch/arm64/crypto/sha512-armv8.pl2
-rw-r--r--arch/arm64/crypto/sha512-ce-glue.c2
-rw-r--r--arch/arm64/crypto/sm3-ce-glue.c28
-rw-r--r--arch/arm64/include/asm/apple_m1_pmu.h64
-rw-r--r--arch/arm64/include/asm/arch_gicv3.h23
-rw-r--r--arch/arm64/include/asm/archrandom.h45
-rw-r--r--arch/arm64/include/asm/asm_pointer_auth.h3
-rw-r--r--arch/arm64/include/asm/assembler.h58
-rw-r--r--arch/arm64/include/asm/cpufeature.h33
-rw-r--r--arch/arm64/include/asm/cputype.h25
-rw-r--r--arch/arm64/include/asm/debug-monitors.h12
-rw-r--r--arch/arm64/include/asm/el2_setup.h2
-rw-r--r--arch/arm64/include/asm/fixmap.h6
-rw-r--r--arch/arm64/include/asm/hwcap.h1
-rw-r--r--arch/arm64/include/asm/insn-def.h14
-rw-r--r--arch/arm64/include/asm/insn.h81
-rw-r--r--arch/arm64/include/asm/kvm_arm.h4
-rw-r--r--arch/arm64/include/asm/kvm_host.h50
-rw-r--r--arch/arm64/include/asm/kvm_hyp.h1
-rw-r--r--arch/arm64/include/asm/kvm_mmu.h4
-rw-r--r--arch/arm64/include/asm/linkage.h24
-rw-r--r--arch/arm64/include/asm/lse.h6
-rw-r--r--arch/arm64/include/asm/module.lds.h6
-rw-r--r--arch/arm64/include/asm/mte-def.h1
-rw-r--r--arch/arm64/include/asm/mte-kasan.h1
-rw-r--r--arch/arm64/include/asm/mte.h22
-rw-r--r--arch/arm64/include/asm/paravirt_api_clock.h1
-rw-r--r--arch/arm64/include/asm/perf_event.h312
-rw-r--r--arch/arm64/include/asm/pgtable-hwdef.h2
-rw-r--r--arch/arm64/include/asm/pgtable-prot.h4
-rw-r--r--arch/arm64/include/asm/pgtable.h11
-rw-r--r--arch/arm64/include/asm/preempt.h19
-rw-r--r--arch/arm64/include/asm/processor.h1
-rw-r--r--arch/arm64/include/asm/rwonce.h4
-rw-r--r--arch/arm64/include/asm/sections.h5
-rw-r--r--arch/arm64/include/asm/spectre.h7
-rw-r--r--arch/arm64/include/asm/string.h2
-rw-r--r--arch/arm64/include/asm/sysreg.h30
-rw-r--r--arch/arm64/include/asm/topology.h4
-rw-r--r--arch/arm64/include/asm/uaccess.h29
-rw-r--r--arch/arm64/include/asm/vectors.h73
-rw-r--r--arch/arm64/include/asm/xor.h21
-rw-r--r--arch/arm64/include/uapi/asm/hwcap.h1
-rw-r--r--arch/arm64/include/uapi/asm/kvm.h16
-rw-r--r--arch/arm64/kernel/Makefile1
-rw-r--r--arch/arm64/kernel/cpu_errata.c64
-rw-r--r--arch/arm64/kernel/cpufeature.c254
-rw-r--r--arch/arm64/kernel/cpuidle.c6
-rw-r--r--arch/arm64/kernel/cpuinfo.c1
-rw-r--r--arch/arm64/kernel/crash_core.c6
-rw-r--r--arch/arm64/kernel/elfcore.c134
-rw-r--r--arch/arm64/kernel/entry-common.c31
-rw-r--r--arch/arm64/kernel/entry.S223
-rw-r--r--arch/arm64/kernel/fpsimd.c8
-rw-r--r--arch/arm64/kernel/idreg-override.c16
-rw-r--r--arch/arm64/kernel/image-vars.h7
-rw-r--r--arch/arm64/kernel/mte.c36
-rw-r--r--arch/arm64/kernel/perf_event.c10
-rw-r--r--arch/arm64/kernel/process.c3
-rw-r--r--arch/arm64/kernel/proton-pack.c400
-rw-r--r--arch/arm64/kernel/setup.c3
-rw-r--r--arch/arm64/kernel/signal.c11
-rw-r--r--arch/arm64/kernel/stacktrace.c5
-rw-r--r--arch/arm64/kernel/sys_compat.c1
-rw-r--r--arch/arm64/kernel/traps.c3
-rw-r--r--arch/arm64/kernel/vdso/Makefile5
-rw-r--r--arch/arm64/kernel/vmlinux.lds.S2
-rw-r--r--arch/arm64/kvm/Makefile2
-rw-r--r--arch/arm64/kvm/arm.c193
-rw-r--r--arch/arm64/kvm/debug.c26
-rw-r--r--arch/arm64/kvm/fpsimd.c14
-rw-r--r--arch/arm64/kvm/guest.c2
-rw-r--r--arch/arm64/kvm/handle_exit.c10
-rw-r--r--arch/arm64/kvm/hyp/exception.c5
-rw-r--r--arch/arm64/kvm/hyp/hyp-entry.S9
-rw-r--r--arch/arm64/kvm/hyp/include/hyp/switch.h31
-rw-r--r--arch/arm64/kvm/hyp/include/nvhe/fixed_config.h5
-rw-r--r--arch/arm64/kvm/hyp/nvhe/Makefile3
-rw-r--r--arch/arm64/kvm/hyp/nvhe/cache.S5
-rw-r--r--arch/arm64/kvm/hyp/nvhe/list_debug.c54
-rw-r--r--arch/arm64/kvm/hyp/nvhe/mem_protect.c3
-rw-r--r--arch/arm64/kvm/hyp/nvhe/mm.c4
-rw-r--r--arch/arm64/kvm/hyp/nvhe/page_alloc.c4
-rw-r--r--arch/arm64/kvm/hyp/nvhe/stub.c22
-rw-r--r--arch/arm64/kvm/hyp/nvhe/sys_regs.c14
-rw-r--r--arch/arm64/kvm/hyp/pgtable.c18
-rw-r--r--arch/arm64/kvm/hyp/vgic-v3-sr.c3
-rw-r--r--arch/arm64/kvm/hyp/vhe/switch.c16
-rw-r--r--arch/arm64/kvm/hypercalls.c12
-rw-r--r--arch/arm64/kvm/mmio.c3
-rw-r--r--arch/arm64/kvm/mmu.c52
-rw-r--r--arch/arm64/kvm/pmu-emul.c141
-rw-r--r--arch/arm64/kvm/psci.c87
-rw-r--r--arch/arm64/kvm/sys_regs.c79
-rw-r--r--arch/arm64/kvm/vgic/vgic-mmio.c2
-rw-r--r--arch/arm64/kvm/vgic/vgic-v3.c17
-rw-r--r--arch/arm64/kvm/vgic/vgic.c2
-rw-r--r--arch/arm64/kvm/vmid.c196
-rw-r--r--arch/arm64/lib/clear_page.S5
-rw-r--r--arch/arm64/lib/copy_page.S5
-rw-r--r--arch/arm64/lib/crc32.S87
-rw-r--r--arch/arm64/lib/insn.c187
-rw-r--r--arch/arm64/lib/memchr.S5
-rw-r--r--arch/arm64/lib/memcmp.S6
-rw-r--r--arch/arm64/lib/memcpy.S21
-rw-r--r--arch/arm64/lib/memset.S12
-rw-r--r--arch/arm64/lib/mte.S4
-rw-r--r--arch/arm64/lib/strchr.S6
-rw-r--r--arch/arm64/lib/strcmp.S246
-rw-r--r--arch/arm64/lib/strlen.S6
-rw-r--r--arch/arm64/lib/strncmp.S241
-rw-r--r--arch/arm64/lib/strnlen.S6
-rw-r--r--arch/arm64/lib/strrchr.S5
-rw-r--r--arch/arm64/lib/xor-neon.c46
-rw-r--r--arch/arm64/mm/cache.S35
-rw-r--r--arch/arm64/mm/extable.c4
-rw-r--r--arch/arm64/mm/flush.c7
-rw-r--r--arch/arm64/mm/hugetlbpage.c39
-rw-r--r--arch/arm64/mm/init.c45
-rw-r--r--arch/arm64/mm/mmap.c17
-rw-r--r--arch/arm64/mm/mmu.c69
-rw-r--r--arch/arm64/mm/mteswap.c2
-rw-r--r--arch/arm64/mm/proc.S2
-rw-r--r--arch/arm64/net/bpf_jit.h44
-rw-r--r--arch/arm64/net/bpf_jit_comp.c246
-rw-r--r--arch/arm64/tools/Makefile10
-rw-r--r--arch/arm64/tools/cpucaps11
-rw-r--r--arch/csky/Kconfig1
-rw-r--r--arch/csky/include/asm/pgtable.h1
-rw-r--r--arch/csky/include/asm/processor.h2
-rw-r--r--arch/csky/include/asm/segment.h10
-rw-r--r--arch/csky/include/asm/thread_info.h2
-rw-r--r--arch/csky/include/asm/uaccess.h12
-rw-r--r--arch/csky/kernel/asm-offsets.c1
-rw-r--r--arch/csky/kernel/perf_callchain.c2
-rw-r--r--arch/csky/kernel/signal.c2
-rw-r--r--arch/h8300/Kconfig1
-rw-r--r--arch/h8300/include/asm/processor.h1
-rw-r--r--arch/h8300/include/asm/segment.h40
-rw-r--r--arch/h8300/include/asm/thread_info.h3
-rw-r--r--arch/h8300/include/uapi/asm/signal.h2
-rw-r--r--arch/h8300/kernel/entry.S1
-rw-r--r--arch/h8300/kernel/head_ram.S1
-rw-r--r--arch/h8300/mm/init.c6
-rw-r--r--arch/h8300/mm/memory.c1
-rw-r--r--arch/hexagon/Kconfig1
-rw-r--r--arch/hexagon/include/asm/pgtable.h5
-rw-r--r--arch/hexagon/include/asm/thread_info.h6
-rw-r--r--arch/hexagon/include/asm/uaccess.h25
-rw-r--r--arch/hexagon/kernel/process.c1
-rw-r--r--arch/hexagon/mm/init.c2
-rw-r--r--arch/ia64/Kconfig4
-rw-r--r--arch/ia64/configs/zx1_defconfig1
-rw-r--r--arch/ia64/include/asm/pgtable.h1
-rw-r--r--arch/ia64/include/asm/processor.h4
-rw-r--r--arch/ia64/include/asm/sal.h2
-rw-r--r--arch/ia64/include/asm/thread_info.h8
-rw-r--r--arch/ia64/include/asm/uaccess.h26
-rw-r--r--arch/ia64/include/asm/xor.h21
-rw-r--r--arch/ia64/include/uapi/asm/signal.h2
-rw-r--r--arch/ia64/kernel/topology.c10
-rw-r--r--arch/ia64/kernel/unaligned.c60
-rw-r--r--arch/ia64/mm/discontig.c11
-rw-r--r--arch/ia64/pci/fixup.c4
-rw-r--r--arch/m68k/68000/dragen2.c1
-rw-r--r--arch/m68k/68000/screen.h2
-rw-r--r--arch/m68k/68000/ucsimm.c9
-rw-r--r--arch/m68k/Kconfig2
-rw-r--r--arch/m68k/Kconfig.cpu1
-rw-r--r--arch/m68k/amiga/config.c1
-rw-r--r--arch/m68k/apollo/config.c1
-rw-r--r--arch/m68k/atari/config.c1
-rw-r--r--arch/m68k/atari/stdma.c1
-rw-r--r--arch/m68k/bvme6000/config.c2
-rw-r--r--arch/m68k/coldfire/device.c6
-rw-r--r--arch/m68k/coldfire/m5441x.c1
-rw-r--r--arch/m68k/configs/amiga_defconfig7
-rw-r--r--arch/m68k/configs/apollo_defconfig7
-rw-r--r--arch/m68k/configs/atari_defconfig6
-rw-r--r--arch/m68k/configs/bvme6000_defconfig6
-rw-r--r--arch/m68k/configs/hp300_defconfig7
-rw-r--r--arch/m68k/configs/mac_defconfig6
-rw-r--r--arch/m68k/configs/multi_defconfig7
-rw-r--r--arch/m68k/configs/mvme147_defconfig6
-rw-r--r--arch/m68k/configs/mvme16x_defconfig6
-rw-r--r--arch/m68k/configs/q40_defconfig6
-rw-r--r--arch/m68k/configs/sun3_defconfig9
-rw-r--r--arch/m68k/configs/sun3x_defconfig9
-rw-r--r--arch/m68k/emu/nfblock.c1
-rw-r--r--arch/m68k/hp300/config.c1
-rw-r--r--arch/m68k/include/asm/cmpxchg.h9
-rw-r--r--arch/m68k/include/asm/config.h33
-rw-r--r--arch/m68k/include/asm/current.h4
-rw-r--r--arch/m68k/include/asm/mcf_pgtable.h1
-rw-r--r--arch/m68k/include/asm/motorola_pgtable.h1
-rw-r--r--arch/m68k/include/asm/sun3_pgtable.h1
-rw-r--r--arch/m68k/include/asm/uaccess.h14
-rw-r--r--arch/m68k/include/uapi/asm/signal.h2
-rw-r--r--arch/m68k/kernel/setup_mm.c24
-rw-r--r--arch/m68k/mac/config.c1
-rw-r--r--arch/m68k/mm/fault.c2
-rw-r--r--arch/m68k/mvme147/config.c2
-rw-r--r--arch/m68k/mvme16x/config.c2
-rw-r--r--arch/m68k/q40/config.c1
-rw-r--r--arch/microblaze/Kconfig3
-rw-r--r--arch/microblaze/include/asm/irq.h3
-rw-r--r--arch/microblaze/include/asm/pgtable.h3
-rw-r--r--arch/microblaze/include/asm/thread_info.h6
-rw-r--r--arch/microblaze/include/asm/uaccess.h61
-rw-r--r--arch/microblaze/kernel/asm-offsets.c1
-rw-r--r--arch/microblaze/kernel/irq.c16
-rw-r--r--arch/microblaze/kernel/process.c1
-rw-r--r--arch/mips/boot/dts/ingenic/ci20.dts15
-rw-r--r--arch/mips/cavium-octeon/octeon-memcpy.S2
-rw-r--r--arch/mips/configs/cobalt_defconfig1
-rw-r--r--arch/mips/configs/decstation_64_defconfig1
-rw-r--r--arch/mips/configs/decstation_defconfig1
-rw-r--r--arch/mips/configs/decstation_r4k_defconfig1
-rw-r--r--arch/mips/configs/ip22_defconfig1
-rw-r--r--arch/mips/configs/ip32_defconfig1
-rw-r--r--arch/mips/configs/jazz_defconfig1
-rw-r--r--arch/mips/configs/malta_defconfig1
-rw-r--r--arch/mips/configs/malta_kvm_defconfig1
-rw-r--r--arch/mips/configs/maltaup_xpa_defconfig1
-rw-r--r--arch/mips/configs/rm200_defconfig1
-rw-r--r--arch/mips/configs/tb0219_defconfig1
-rw-r--r--arch/mips/configs/tb0226_defconfig1
-rw-r--r--arch/mips/configs/tb0287_defconfig1
-rw-r--r--arch/mips/configs/workpad_defconfig1
-rw-r--r--arch/mips/include/asm/asm.h4
-rw-r--r--arch/mips/include/asm/ftrace.h4
-rw-r--r--arch/mips/include/asm/pgtable.h10
-rw-r--r--arch/mips/include/asm/r4kcache.h4
-rw-r--r--arch/mips/include/asm/uaccess.h49
-rw-r--r--arch/mips/include/asm/unaligned-emul.h176
-rw-r--r--arch/mips/include/uapi/asm/shmbuf.h7
-rw-r--r--arch/mips/include/uapi/asm/signal.h2
-rw-r--r--arch/mips/include/uapi/asm/socket.h2
-rw-r--r--arch/mips/kernel/mips-r2-to-r6-emul.c104
-rw-r--r--arch/mips/kernel/r2300_fpu.S6
-rw-r--r--arch/mips/kernel/r4k_fpu.S2
-rw-r--r--arch/mips/kernel/relocate_kernel.S22
-rw-r--r--arch/mips/kernel/scall32-o32.S10
-rw-r--r--arch/mips/kernel/scall64-n32.S2
-rw-r--r--arch/mips/kernel/scall64-n64.S2
-rw-r--r--arch/mips/kernel/scall64-o32.S10
-rw-r--r--arch/mips/kernel/setup.c2
-rw-r--r--arch/mips/kernel/smp.c6
-rw-r--r--arch/mips/kernel/syscall.c8
-rw-r--r--arch/mips/kernel/topology.c5
-rw-r--r--arch/mips/kernel/unaligned.c17
-rw-r--r--arch/mips/kvm/mips.c50
-rw-r--r--arch/mips/kvm/vz.c12
-rw-r--r--arch/mips/lib/csum_partial.S4
-rw-r--r--arch/mips/lib/memcpy.S4
-rw-r--r--arch/mips/lib/memset.S2
-rw-r--r--arch/mips/lib/strncpy_user.S4
-rw-r--r--arch/mips/lib/strnlen_user.S2
-rw-r--r--arch/mips/loongson64/vbios_quirk.c9
-rw-r--r--arch/mips/ralink/mt7621.c36
-rw-r--r--arch/nds32/Kconfig102
-rw-r--r--arch/nds32/Kconfig.cpu218
-rw-r--r--arch/nds32/Makefile63
-rw-r--r--arch/nds32/boot/.gitignore2
-rw-r--r--arch/nds32/boot/Makefile16
-rw-r--r--arch/nds32/boot/dts/Makefile2
-rw-r--r--arch/nds32/boot/dts/ae3xx.dts90
-rw-r--r--arch/nds32/configs/defconfig104
-rw-r--r--arch/nds32/include/asm/Kbuild8
-rw-r--r--arch/nds32/include/asm/assembler.h39
-rw-r--r--arch/nds32/include/asm/barrier.h15
-rw-r--r--arch/nds32/include/asm/bitfield.h985
-rw-r--r--arch/nds32/include/asm/cache.h12
-rw-r--r--arch/nds32/include/asm/cache_info.h13
-rw-r--r--arch/nds32/include/asm/cacheflush.h53
-rw-r--r--arch/nds32/include/asm/current.h12
-rw-r--r--arch/nds32/include/asm/delay.h39
-rw-r--r--arch/nds32/include/asm/elf.h180
-rw-r--r--arch/nds32/include/asm/fixmap.h29
-rw-r--r--arch/nds32/include/asm/fpu.h126
-rw-r--r--arch/nds32/include/asm/fpuemu.h44
-rw-r--r--arch/nds32/include/asm/ftrace.h46
-rw-r--r--arch/nds32/include/asm/futex.h101
-rw-r--r--arch/nds32/include/asm/highmem.h65
-rw-r--r--arch/nds32/include/asm/io.h84
-rw-r--r--arch/nds32/include/asm/irqflags.h41
-rw-r--r--arch/nds32/include/asm/l2_cache.h137
-rw-r--r--arch/nds32/include/asm/linkage.h11
-rw-r--r--arch/nds32/include/asm/memory.h91
-rw-r--r--arch/nds32/include/asm/mmu.h12
-rw-r--r--arch/nds32/include/asm/mmu_context.h62
-rw-r--r--arch/nds32/include/asm/nds32.h82
-rw-r--r--arch/nds32/include/asm/nds32_fpu_inst.h109
-rw-r--r--arch/nds32/include/asm/page.h64
-rw-r--r--arch/nds32/include/asm/perf_event.h16
-rw-r--r--arch/nds32/include/asm/pgalloc.h62
-rw-r--r--arch/nds32/include/asm/pgtable.h377
-rw-r--r--arch/nds32/include/asm/pmu.h386
-rw-r--r--arch/nds32/include/asm/proc-fns.h44
-rw-r--r--arch/nds32/include/asm/processor.h104
-rw-r--r--arch/nds32/include/asm/ptrace.h77
-rw-r--r--arch/nds32/include/asm/sfp-machine.h158
-rw-r--r--arch/nds32/include/asm/shmparam.h19
-rw-r--r--arch/nds32/include/asm/stacktrace.h39
-rw-r--r--arch/nds32/include/asm/string.h17
-rw-r--r--arch/nds32/include/asm/suspend.h11
-rw-r--r--arch/nds32/include/asm/swab.h35
-rw-r--r--arch/nds32/include/asm/syscall.h142
-rw-r--r--arch/nds32/include/asm/syscalls.h14
-rw-r--r--arch/nds32/include/asm/thread_info.h76
-rw-r--r--arch/nds32/include/asm/tlb.h11
-rw-r--r--arch/nds32/include/asm/tlbflush.h46
-rw-r--r--arch/nds32/include/asm/uaccess.h286
-rw-r--r--arch/nds32/include/asm/unistd.h6
-rw-r--r--arch/nds32/include/asm/vdso.h24
-rw-r--r--arch/nds32/include/asm/vdso_datapage.h37
-rw-r--r--arch/nds32/include/asm/vdso_timer_info.h14
-rw-r--r--arch/nds32/include/asm/vermagic.h9
-rw-r--r--arch/nds32/include/asm/vmalloc.h4
-rw-r--r--arch/nds32/include/uapi/asm/auxvec.h19
-rw-r--r--arch/nds32/include/uapi/asm/byteorder.h13
-rw-r--r--arch/nds32/include/uapi/asm/cachectl.h14
-rw-r--r--arch/nds32/include/uapi/asm/fp_udfiex_crtl.h16
-rw-r--r--arch/nds32/include/uapi/asm/param.h11
-rw-r--r--arch/nds32/include/uapi/asm/ptrace.h25
-rw-r--r--arch/nds32/include/uapi/asm/sigcontext.h84
-rw-r--r--arch/nds32/include/uapi/asm/unistd.h16
-rw-r--r--arch/nds32/kernel/Makefile33
-rw-r--r--arch/nds32/kernel/asm-offsets.c28
-rw-r--r--arch/nds32/kernel/atl2c.c65
-rw-r--r--arch/nds32/kernel/cacheinfo.c49
-rw-r--r--arch/nds32/kernel/devtree.c19
-rw-r--r--arch/nds32/kernel/dma.c82
-rw-r--r--arch/nds32/kernel/ex-entry.S177
-rw-r--r--arch/nds32/kernel/ex-exit.S193
-rw-r--r--arch/nds32/kernel/ex-scall.S100
-rw-r--r--arch/nds32/kernel/fpu.c266
-rw-r--r--arch/nds32/kernel/ftrace.c278
-rw-r--r--arch/nds32/kernel/head.S197
-rw-r--r--arch/nds32/kernel/irq.c9
-rw-r--r--arch/nds32/kernel/module.c278
-rw-r--r--arch/nds32/kernel/nds32_ksyms.c25
-rw-r--r--arch/nds32/kernel/perf_event_cpu.c1500
-rw-r--r--arch/nds32/kernel/pm.c80
-rw-r--r--arch/nds32/kernel/process.c257
-rw-r--r--arch/nds32/kernel/ptrace.c118
-rw-r--r--arch/nds32/kernel/setup.c369
-rw-r--r--arch/nds32/kernel/signal.c384
-rw-r--r--arch/nds32/kernel/sleep.S131
-rw-r--r--arch/nds32/kernel/stacktrace.c53
-rw-r--r--arch/nds32/kernel/sys_nds32.c84
-rw-r--r--arch/nds32/kernel/syscall_table.c17
-rw-r--r--arch/nds32/kernel/time.c11
-rw-r--r--arch/nds32/kernel/traps.c354
-rw-r--r--arch/nds32/kernel/vdso.c231
-rw-r--r--arch/nds32/kernel/vdso/Makefile79
-rw-r--r--arch/nds32/kernel/vdso/datapage.S21
-rw-r--r--arch/nds32/kernel/vdso/gettimeofday.c269
-rw-r--r--arch/nds32/kernel/vdso/note.S11
-rw-r--r--arch/nds32/kernel/vdso/sigreturn.S19
-rw-r--r--arch/nds32/kernel/vdso/vdso.S18
-rw-r--r--arch/nds32/kernel/vdso/vdso.lds.S75
-rw-r--r--arch/nds32/kernel/vmlinux.lds.S70
-rw-r--r--arch/nds32/lib/Makefile4
-rw-r--r--arch/nds32/lib/clear_user.S42
-rw-r--r--arch/nds32/lib/copy_from_user.S45
-rw-r--r--arch/nds32/lib/copy_page.S40
-rw-r--r--arch/nds32/lib/copy_template.S69
-rw-r--r--arch/nds32/lib/copy_to_user.S45
-rw-r--r--arch/nds32/lib/memcpy.S30
-rw-r--r--arch/nds32/lib/memmove.S70
-rw-r--r--arch/nds32/lib/memset.S33
-rw-r--r--arch/nds32/lib/memzero.S18
-rw-r--r--arch/nds32/math-emu/Makefile10
-rw-r--r--arch/nds32/math-emu/faddd.c24
-rw-r--r--arch/nds32/math-emu/fadds.c24
-rw-r--r--arch/nds32/math-emu/fcmpd.c24
-rw-r--r--arch/nds32/math-emu/fcmps.c24
-rw-r--r--arch/nds32/math-emu/fd2s.c22
-rw-r--r--arch/nds32/math-emu/fd2si.c30
-rw-r--r--arch/nds32/math-emu/fd2siz.c30
-rw-r--r--arch/nds32/math-emu/fd2ui.c30
-rw-r--r--arch/nds32/math-emu/fd2uiz.c30
-rw-r--r--arch/nds32/math-emu/fdivd.c27
-rw-r--r--arch/nds32/math-emu/fdivs.c26
-rw-r--r--arch/nds32/math-emu/fmuld.c23
-rw-r--r--arch/nds32/math-emu/fmuls.c23
-rw-r--r--arch/nds32/math-emu/fnegd.c21
-rw-r--r--arch/nds32/math-emu/fnegs.c21
-rw-r--r--arch/nds32/math-emu/fpuemu.c406
-rw-r--r--arch/nds32/math-emu/fs2d.c23
-rw-r--r--arch/nds32/math-emu/fs2si.c29
-rw-r--r--arch/nds32/math-emu/fs2siz.c29
-rw-r--r--arch/nds32/math-emu/fs2ui.c29
-rw-r--r--arch/nds32/math-emu/fs2uiz.c30
-rw-r--r--arch/nds32/math-emu/fsi2d.c22
-rw-r--r--arch/nds32/math-emu/fsi2s.c22
-rw-r--r--arch/nds32/math-emu/fsqrtd.c21
-rw-r--r--arch/nds32/math-emu/fsqrts.c21
-rw-r--r--arch/nds32/math-emu/fsubd.c27
-rw-r--r--arch/nds32/math-emu/fsubs.c27
-rw-r--r--arch/nds32/math-emu/fui2d.c22
-rw-r--r--arch/nds32/math-emu/fui2s.c22
-rw-r--r--arch/nds32/mm/Makefile10
-rw-r--r--arch/nds32/mm/alignment.c578
-rw-r--r--arch/nds32/mm/cacheflush.c338
-rw-r--r--arch/nds32/mm/extable.c16
-rw-r--r--arch/nds32/mm/fault.c396
-rw-r--r--arch/nds32/mm/init.c263
-rw-r--r--arch/nds32/mm/mm-nds32.c96
-rw-r--r--arch/nds32/mm/mmap.c73
-rw-r--r--arch/nds32/mm/proc.c536
-rw-r--r--arch/nds32/mm/tlb.c50
-rw-r--r--arch/nios2/Kconfig1
-rw-r--r--arch/nios2/include/asm/pgtable.h1
-rw-r--r--arch/nios2/include/asm/thread_info.h9
-rw-r--r--arch/nios2/include/asm/uaccess.h105
-rw-r--r--arch/nios2/kernel/signal.c20
-rw-r--r--arch/openrisc/Kconfig1
-rw-r--r--arch/openrisc/include/asm/pgtable.h1
-rw-r--r--arch/openrisc/include/asm/thread_info.h7
-rw-r--r--arch/openrisc/include/asm/uaccess.h42
-rw-r--r--arch/openrisc/mm/init.c2
-rw-r--r--arch/parisc/Kconfig15
-rw-r--r--arch/parisc/Makefile37
-rw-r--r--arch/parisc/configs/generic-32bit_defconfig1
-rw-r--r--arch/parisc/include/asm/agp.h4
-rw-r--r--arch/parisc/include/asm/assembly.h6
-rw-r--r--arch/parisc/include/asm/bitops.h8
-rw-r--r--arch/parisc/include/asm/cache.h11
-rw-r--r--arch/parisc/include/asm/cacheflush.h15
-rw-r--r--arch/parisc/include/asm/current.h8
-rw-r--r--arch/parisc/include/asm/elf.h15
-rw-r--r--arch/parisc/include/asm/futex.h6
-rw-r--r--arch/parisc/include/asm/kprobes.h5
-rw-r--r--arch/parisc/include/asm/mmu.h6
-rw-r--r--arch/parisc/include/asm/mmu_context.h16
-rw-r--r--arch/parisc/include/asm/pgtable.h12
-rw-r--r--arch/parisc/include/asm/processor.h2
-rw-r--r--arch/parisc/include/asm/rt_sigframe.h10
-rw-r--r--arch/parisc/include/asm/special_insns.h4
-rw-r--r--arch/parisc/include/asm/tlbflush.h2
-rw-r--r--arch/parisc/include/asm/traps.h1
-rw-r--r--arch/parisc/include/asm/uaccess.h60
-rw-r--r--arch/parisc/include/asm/unistd.h4
-rw-r--r--arch/parisc/include/asm/vdso.h24
-rw-r--r--arch/parisc/include/uapi/asm/auxvec.h8
-rw-r--r--arch/parisc/include/uapi/asm/shmbuf.h2
-rw-r--r--arch/parisc/include/uapi/asm/signal.h2
-rw-r--r--arch/parisc/include/uapi/asm/socket.h2
-rw-r--r--arch/parisc/kernel/Makefile5
-rw-r--r--arch/parisc/kernel/alternative.c10
-rw-r--r--arch/parisc/kernel/asm-offsets.c9
-rw-r--r--arch/parisc/kernel/cache.c137
-rw-r--r--arch/parisc/kernel/entry.S72
-rw-r--r--arch/parisc/kernel/kprobes.c28
-rw-r--r--arch/parisc/kernel/pci-dma.c4
-rw-r--r--arch/parisc/kernel/signal.c229
-rw-r--r--arch/parisc/kernel/signal32.h19
-rw-r--r--arch/parisc/kernel/topology.c4
-rw-r--r--arch/parisc/kernel/traps.c12
-rw-r--r--arch/parisc/kernel/unaligned.c269
-rw-r--r--arch/parisc/kernel/vdso.c122
-rw-r--r--arch/parisc/kernel/vdso32/Makefile53
-rwxr-xr-xarch/parisc/kernel/vdso32/gen_vdso_offsets.sh (renamed from arch/nds32/kernel/vdso/gen_vdso_offsets.sh)6
-rw-r--r--arch/parisc/kernel/vdso32/note.S26
-rw-r--r--arch/parisc/kernel/vdso32/restart_syscall.S32
-rw-r--r--arch/parisc/kernel/vdso32/sigtramp.S195
-rw-r--r--arch/parisc/kernel/vdso32/vdso32.lds.S111
-rw-r--r--arch/parisc/kernel/vdso32/vdso32_wrapper.S14
-rw-r--r--arch/parisc/kernel/vdso64/Makefile48
-rwxr-xr-xarch/parisc/kernel/vdso64/gen_vdso_offsets.sh15
-rw-r--r--arch/parisc/kernel/vdso64/note.S2
-rw-r--r--arch/parisc/kernel/vdso64/restart_syscall.S3
-rw-r--r--arch/parisc/kernel/vdso64/sigtramp.S166
-rw-r--r--arch/parisc/kernel/vdso64/vdso64.lds.S109
-rw-r--r--arch/parisc/kernel/vdso64/vdso64_wrapper.S14
-rw-r--r--arch/parisc/lib/iomap.c18
-rw-r--r--arch/parisc/lib/memcpy.c16
-rw-r--r--arch/parisc/mm/fault.c89
-rw-r--r--arch/parisc/mm/init.c9
-rw-r--r--arch/powerpc/Kconfig1
-rw-r--r--arch/powerpc/configs/linkstation_defconfig1
-rw-r--r--arch/powerpc/configs/mvme5100_defconfig1
-rw-r--r--arch/powerpc/include/asm/agp.h4
-rw-r--r--arch/powerpc/include/asm/book3s/32/mmu-hash.h2
-rw-r--r--arch/powerpc/include/asm/book3s/32/pgtable.h5
-rw-r--r--arch/powerpc/include/asm/book3s/64/mmu.h2
-rw-r--r--arch/powerpc/include/asm/book3s/64/pgtable.h2
-rw-r--r--arch/powerpc/include/asm/checksum.h7
-rw-r--r--arch/powerpc/include/asm/fadump-internal.h5
-rw-r--r--arch/powerpc/include/asm/fixmap.h6
-rw-r--r--arch/powerpc/include/asm/hw_irq.h2
-rw-r--r--arch/powerpc/include/asm/kexec_ranges.h2
-rw-r--r--arch/powerpc/include/asm/kvm_book3s_64.h1
-rw-r--r--arch/powerpc/include/asm/kvm_host.h1
-rw-r--r--arch/powerpc/include/asm/mmu_context.h1
-rw-r--r--arch/powerpc/include/asm/nmi.h2
-rw-r--r--arch/powerpc/include/asm/nohash/32/hugetlb-8xx.h4
-rw-r--r--arch/powerpc/include/asm/nohash/32/pgtable.h8
-rw-r--r--arch/powerpc/include/asm/nohash/64/pgtable.h2
-rw-r--r--arch/powerpc/include/asm/ppc-opcode.h1
-rw-r--r--arch/powerpc/include/asm/syscall.h4
-rw-r--r--arch/powerpc/include/asm/thread_info.h2
-rw-r--r--arch/powerpc/include/asm/uaccess.h13
-rw-r--r--arch/powerpc/include/asm/xor_altivec.h25
-rw-r--r--arch/powerpc/include/uapi/asm/shmbuf.h5
-rw-r--r--arch/powerpc/include/uapi/asm/signal.h2
-rw-r--r--arch/powerpc/kernel/fadump.c8
-rw-r--r--arch/powerpc/kernel/head_book3s_32.S4
-rw-r--r--arch/powerpc/kernel/interrupt_64.S2
-rw-r--r--arch/powerpc/kernel/sysfs.c17
-rw-r--r--arch/powerpc/kernel/time.c5
-rw-r--r--arch/powerpc/kvm/book3s_hv.c3
-rw-r--r--arch/powerpc/kvm/book3s_hv_nested.c2
-rw-r--r--arch/powerpc/kvm/book3s_hv_uvmem.c4
-rw-r--r--arch/powerpc/lib/sstep.c6
-rw-r--r--arch/powerpc/lib/xor_vmx.c28
-rw-r--r--arch/powerpc/lib/xor_vmx.h27
-rw-r--r--arch/powerpc/lib/xor_vmx_glue.c32
-rw-r--r--arch/powerpc/mm/book3s32/mmu.c10
-rw-r--r--arch/powerpc/mm/book3s64/pgtable.c1
-rw-r--r--arch/powerpc/mm/kasan/book3s_32.c59
-rw-r--r--arch/powerpc/mm/pgtable.c9
-rw-r--r--arch/powerpc/net/bpf_jit_comp.c31
-rw-r--r--arch/powerpc/net/bpf_jit_comp32.c9
-rw-r--r--arch/powerpc/net/bpf_jit_comp64.c29
-rw-r--r--arch/powerpc/perf/core-book3s.c75
-rw-r--r--arch/riscv/Kconfig4
-rw-r--r--arch/riscv/Kconfig.erratas1
-rw-r--r--arch/riscv/Kconfig.socs4
-rw-r--r--arch/riscv/Makefile6
-rw-r--r--arch/riscv/boot/dts/canaan/k210.dtsi3
-rw-r--r--arch/riscv/configs/nommu_k210_sdcard_defconfig2
-rw-r--r--arch/riscv/include/asm/kvm_host.h1
-rw-r--r--arch/riscv/include/asm/kvm_vcpu_sbi.h5
-rw-r--r--arch/riscv/include/asm/page.h2
-rw-r--r--arch/riscv/include/asm/pgtable.h1
-rw-r--r--arch/riscv/include/asm/sbi.h27
-rw-r--r--arch/riscv/include/asm/uaccess.h33
-rw-r--r--arch/riscv/kernel/Makefile2
-rw-r--r--arch/riscv/kernel/cpu-hotplug.c2
-rw-r--r--arch/riscv/kernel/cpu_ops_sbi.c2
-rw-r--r--arch/riscv/kernel/entry.S10
-rw-r--r--arch/riscv/kernel/head.S11
-rw-r--r--arch/riscv/kernel/module.c21
-rw-r--r--arch/riscv/kernel/perf_callchain.c4
-rw-r--r--arch/riscv/kernel/sbi.c72
-rw-r--r--arch/riscv/kernel/setup.c3
-rw-r--r--arch/riscv/kernel/stacktrace.c9
-rw-r--r--arch/riscv/kernel/trace_irq.c27
-rw-r--r--arch/riscv/kernel/trace_irq.h11
-rw-r--r--arch/riscv/kvm/vcpu.c48
-rw-r--r--arch/riscv/kvm/vcpu_exit.c22
-rw-r--r--arch/riscv/kvm/vcpu_sbi.c19
-rw-r--r--arch/riscv/kvm/vcpu_sbi_base.c3
-rw-r--r--arch/riscv/kvm/vcpu_sbi_hsm.c18
-rw-r--r--arch/riscv/kvm/vcpu_sbi_replace.c44
-rw-r--r--arch/riscv/kvm/vcpu_sbi_v01.c20
-rw-r--r--arch/riscv/kvm/vcpu_switch.S60
-rw-r--r--arch/riscv/mm/Makefile3
-rw-r--r--arch/riscv/mm/extable.c6
-rw-r--r--arch/riscv/mm/init.c10
-rw-r--r--arch/riscv/mm/kasan_init.c8
-rw-r--r--arch/riscv/mm/physaddr.c4
-rw-r--r--arch/s390/Kconfig17
-rw-r--r--arch/s390/configs/debug_defconfig20
-rw-r--r--arch/s390/configs/defconfig16
-rw-r--r--arch/s390/configs/zfcpdump_defconfig3
-rw-r--r--arch/s390/hypfs/hypfs_vm.c6
-rw-r--r--arch/s390/include/asm/ccwgroup.h2
-rw-r--r--arch/s390/include/asm/chsc.h2
-rw-r--r--arch/s390/include/asm/ctl_reg.h2
-rw-r--r--arch/s390/include/asm/eadm.h2
-rw-r--r--arch/s390/include/asm/extable.h9
-rw-r--r--arch/s390/include/asm/fcx.h4
-rw-r--r--arch/s390/include/asm/ftrace.h10
-rw-r--r--arch/s390/include/asm/idals.h2
-rw-r--r--arch/s390/include/asm/kvm_host.h2
-rw-r--r--arch/s390/include/asm/page.h2
-rw-r--r--arch/s390/include/asm/ptrace.h2
-rw-r--r--arch/s390/include/asm/sclp.h2
-rw-r--r--arch/s390/include/asm/sysinfo.h6
-rw-r--r--arch/s390/include/asm/uaccess.h42
-rw-r--r--arch/s390/include/asm/uv.h1
-rw-r--r--arch/s390/include/uapi/asm/signal.h2
-rw-r--r--arch/s390/kernel/ftrace.c37
-rw-r--r--arch/s390/kernel/mcount.S9
-rw-r--r--arch/s390/kernel/module.c37
-rw-r--r--arch/s390/kernel/nmi.c27
-rw-r--r--arch/s390/kernel/numa.c7
-rw-r--r--arch/s390/kernel/setup.c2
-rw-r--r--arch/s390/kvm/gaccess.c250
-rw-r--r--arch/s390/kvm/gaccess.h84
-rw-r--r--arch/s390/kvm/intercept.c12
-rw-r--r--arch/s390/kvm/interrupt.c54
-rw-r--r--arch/s390/kvm/kvm-s390.c172
-rw-r--r--arch/s390/kvm/kvm-s390.h17
-rw-r--r--arch/s390/kvm/priv.c81
-rw-r--r--arch/s390/lib/Makefile3
-rw-r--r--arch/s390/lib/test_modules.c32
-rw-r--r--arch/s390/lib/test_modules.h53
-rw-r--r--arch/s390/lib/test_modules_helpers.c13
-rw-r--r--arch/s390/lib/uaccess.c81
-rw-r--r--arch/s390/lib/xor.c21
-rw-r--r--arch/sh/Kconfig2
-rw-r--r--arch/sh/configs/ap325rxa_defconfig1
-rw-r--r--arch/sh/configs/ecovec24_defconfig1
-rw-r--r--arch/sh/configs/landisk_defconfig1
-rw-r--r--arch/sh/configs/sdk7780_defconfig1
-rw-r--r--arch/sh/configs/se7724_defconfig1
-rw-r--r--arch/sh/configs/sh03_defconfig1
-rw-r--r--arch/sh/configs/sh7785lcr_32bit_defconfig1
-rw-r--r--arch/sh/configs/titan_defconfig1
-rw-r--r--arch/sh/include/asm/pgtable_32.h1
-rw-r--r--arch/sh/include/asm/processor.h1
-rw-r--r--arch/sh/include/asm/segment.h33
-rw-r--r--arch/sh/include/asm/thread_info.h4
-rw-r--r--arch/sh/include/asm/uaccess.h24
-rw-r--r--arch/sh/kernel/io_trapped.c9
-rw-r--r--arch/sh/kernel/process_32.c2
-rw-r--r--arch/sh/kernel/topology.c5
-rw-r--r--arch/sh/kernel/traps_32.c30
-rw-r--r--arch/sparc/Kconfig2
-rw-r--r--arch/sparc/include/asm/agp.h6
-rw-r--r--arch/sparc/include/asm/pgtable_32.h7
-rw-r--r--arch/sparc/include/asm/processor_32.h6
-rw-r--r--arch/sparc/include/asm/processor_64.h4
-rw-r--r--arch/sparc/include/asm/switch_to_64.h4
-rw-r--r--arch/sparc/include/asm/thread_info_64.h4
-rw-r--r--arch/sparc/include/asm/uaccess.h3
-rw-r--r--arch/sparc/include/asm/uaccess_32.h31
-rw-r--r--arch/sparc/include/asm/uaccess_64.h106
-rw-r--r--arch/sparc/include/asm/vio.h10
-rw-r--r--arch/sparc/include/asm/xor_32.h21
-rw-r--r--arch/sparc/include/asm/xor_64.h42
-rw-r--r--arch/sparc/include/uapi/asm/shmbuf.h5
-rw-r--r--arch/sparc/include/uapi/asm/signal.h3
-rw-r--r--arch/sparc/include/uapi/asm/socket.h2
-rw-r--r--arch/sparc/kernel/process_32.c2
-rw-r--r--arch/sparc/kernel/process_64.c12
-rw-r--r--arch/sparc/kernel/signal_32.c2
-rw-r--r--arch/sparc/kernel/sysfs.c12
-rw-r--r--arch/sparc/kernel/traps_64.c2
-rw-r--r--arch/sparc/lib/NGmemcpy.S3
-rw-r--r--arch/sparc/mm/hugetlbpage.c1
-rw-r--r--arch/sparc/mm/init_64.c7
-rw-r--r--arch/sparc/net/bpf_jit_comp_64.c2
-rw-r--r--arch/um/include/asm/pgtable.h1
-rw-r--r--arch/um/include/asm/uaccess.h7
-rw-r--r--arch/um/include/shared/net_kern.h2
-rw-r--r--arch/um/os-Linux/execvp.c1
-rw-r--r--arch/x86/Kbuild2
-rw-r--r--arch/x86/Kconfig29
-rw-r--r--arch/x86/boot/compressed/head_32.S3
-rw-r--r--arch/x86/boot/compressed/head_64.S3
-rw-r--r--arch/x86/coco/Makefile6
-rw-r--r--arch/x86/coco/core.c (renamed from arch/x86/kernel/cc_platform.c)56
-rw-r--r--arch/x86/crypto/Makefile3
-rw-r--r--arch/x86/crypto/aes_ctrby8_avx-x86_64.S63
-rw-r--r--arch/x86/crypto/aesni-intel_asm.S4
-rw-r--r--arch/x86/crypto/blake2s-shash.c4
-rw-r--r--arch/x86/crypto/blowfish_glue.c12
-rw-r--r--arch/x86/crypto/des3_ede_glue.c8
-rw-r--r--arch/x86/crypto/sm3-avx-asm_64.S517
-rw-r--r--arch/x86/crypto/sm3_avx_glue.c134
-rw-r--r--arch/x86/events/core.c2
-rw-r--r--arch/x86/events/intel/core.c68
-rw-r--r--arch/x86/events/intel/ds.c14
-rw-r--r--arch/x86/events/intel/lbr.c172
-rw-r--r--arch/x86/events/intel/pt.c76
-rw-r--r--arch/x86/events/intel/uncore.c2
-rw-r--r--arch/x86/events/intel/uncore.h3
-rw-r--r--arch/x86/events/intel/uncore_discovery.c20
-rw-r--r--arch/x86/events/intel/uncore_discovery.h4
-rw-r--r--arch/x86/events/intel/uncore_snb.c214
-rw-r--r--arch/x86/events/intel/uncore_snbep.c2
-rw-r--r--arch/x86/events/perf_event.h10
-rw-r--r--arch/x86/events/rapl.c9
-rw-r--r--arch/x86/include/asm/bug.h20
-rw-r--r--arch/x86/include/asm/coco.h32
-rw-r--r--arch/x86/include/asm/cpufeatures.h9
-rw-r--r--arch/x86/include/asm/cpumask.h10
-rw-r--r--arch/x86/include/asm/disabled-features.h7
-rw-r--r--arch/x86/include/asm/insn.h2
-rw-r--r--arch/x86/include/asm/intel_ds.h5
-rw-r--r--arch/x86/include/asm/intel_pt.h2
-rw-r--r--arch/x86/include/asm/kvm-x86-ops.h119
-rw-r--r--arch/x86/include/asm/kvm_host.h85
-rw-r--r--arch/x86/include/asm/microcode_amd.h2
-rw-r--r--arch/x86/include/asm/microcode_intel.h4
-rw-r--r--arch/x86/include/asm/msr-index.h9
-rw-r--r--arch/x86/include/asm/nospec-branch.h16
-rw-r--r--arch/x86/include/asm/page.h10
-rw-r--r--arch/x86/include/asm/paravirt_api_clock.h1
-rw-r--r--arch/x86/include/asm/paravirt_types.h4
-rw-r--r--arch/x86/include/asm/pci.h2
-rw-r--r--arch/x86/include/asm/pci_x86.h2
-rw-r--r--arch/x86/include/asm/perf_event.h2
-rw-r--r--arch/x86/include/asm/pgtable.h13
-rw-r--r--arch/x86/include/asm/preempt.h10
-rw-r--r--arch/x86/include/asm/processor.h2
-rw-r--r--arch/x86/include/asm/ptrace.h2
-rw-r--r--arch/x86/include/asm/set_memory.h2
-rw-r--r--arch/x86/include/asm/svm.h36
-rw-r--r--arch/x86/include/asm/text-patching.h1
-rw-r--r--arch/x86/include/asm/topology.h16
-rw-r--r--arch/x86/include/asm/uaccess.h35
-rw-r--r--arch/x86/include/asm/x86_init.h16
-rw-r--r--arch/x86/include/asm/xen/cpuid.h7
-rw-r--r--arch/x86/include/asm/xen/hypervisor.h14
-rw-r--r--arch/x86/include/asm/xor.h42
-rw-r--r--arch/x86/include/asm/xor_32.h42
-rw-r--r--arch/x86/include/asm/xor_avx.h21
-rw-r--r--arch/x86/include/uapi/asm/kvm.h3
-rw-r--r--arch/x86/include/uapi/asm/shmbuf.h6
-rw-r--r--arch/x86/include/uapi/asm/signal.h2
-rw-r--r--arch/x86/kernel/Makefile5
-rw-r--r--arch/x86/kernel/acpi/Makefile2
-rw-r--r--arch/x86/kernel/acpi/boot.c24
-rw-r--r--arch/x86/kernel/acpi/cppc.c103
-rw-r--r--arch/x86/kernel/acpi/cppc_msr.c49
-rw-r--r--arch/x86/kernel/acpi/sleep.c23
-rw-r--r--arch/x86/kernel/alternative.c42
-rw-r--r--arch/x86/kernel/cpu/amd.c35
-rw-r--r--arch/x86/kernel/cpu/aperfmperf.c6
-rw-r--r--arch/x86/kernel/cpu/bugs.c204
-rw-r--r--arch/x86/kernel/cpu/common.c79
-rw-r--r--arch/x86/kernel/cpu/mce/amd.c9
-rw-r--r--arch/x86/kernel/cpu/mce/core.c15
-rw-r--r--arch/x86/kernel/cpu/mce/intel.c41
-rw-r--r--arch/x86/kernel/cpu/mshyperv.c14
-rw-r--r--arch/x86/kernel/cpu/scattered.c1
-rw-r--r--arch/x86/kernel/cpu/sgx/encl.c59
-rw-r--r--arch/x86/kernel/cpu/sgx/main.c10
-rw-r--r--arch/x86/kernel/dumpstack.c6
-rw-r--r--arch/x86/kernel/e820.c41
-rw-r--r--arch/x86/kernel/early-quirks.c1
-rw-r--r--arch/x86/kernel/fpu/core.c7
-rw-r--r--arch/x86/kernel/fpu/regset.c9
-rw-r--r--arch/x86/kernel/fpu/xstate.c5
-rw-r--r--arch/x86/kernel/head64.c2
-rw-r--r--arch/x86/kernel/kdebugfs.c37
-rw-r--r--arch/x86/kernel/ksysfs.c77
-rw-r--r--arch/x86/kernel/kvm.c13
-rw-r--r--arch/x86/kernel/kvmclock.c3
-rw-r--r--arch/x86/kernel/module.c13
-rw-r--r--arch/x86/kernel/nmi.c1
-rw-r--r--arch/x86/kernel/process.c5
-rw-r--r--arch/x86/kernel/ptrace.c4
-rw-r--r--arch/x86/kernel/resource.c23
-rw-r--r--arch/x86/kernel/setup.c44
-rw-r--r--arch/x86/kernel/smpboot.c72
-rw-r--r--arch/x86/kernel/stacktrace.c2
-rw-r--r--arch/x86/kernel/topology.c5
-rw-r--r--arch/x86/kernel/traps.c56
-rw-r--r--arch/x86/kernel/x86_init.c16
-rw-r--r--arch/x86/kvm/Kconfig7
-rw-r--r--arch/x86/kvm/cpuid.c166
-rw-r--r--arch/x86/kvm/emulate.c103
-rw-r--r--arch/x86/kvm/hyperv.c242
-rw-r--r--arch/x86/kvm/hyperv.h6
-rw-r--r--arch/x86/kvm/i8259.c8
-rw-r--r--arch/x86/kvm/ioapic.c6
-rw-r--r--arch/x86/kvm/kvm_emulate.h6
-rw-r--r--arch/x86/kvm/kvm_onhyperv.c14
-rw-r--r--arch/x86/kvm/kvm_onhyperv.h14
-rw-r--r--arch/x86/kvm/lapic.c246
-rw-r--r--arch/x86/kvm/lapic.h17
-rw-r--r--arch/x86/kvm/mmu.h44
-rw-r--r--arch/x86/kvm/mmu/mmu.c517
-rw-r--r--arch/x86/kvm/mmu/mmu_audit.c303
-rw-r--r--arch/x86/kvm/mmu/mmu_internal.h15
-rw-r--r--arch/x86/kvm/mmu/mmutrace.h23
-rw-r--r--arch/x86/kvm/mmu/page_track.c7
-rw-r--r--arch/x86/kvm/mmu/paging_tmpl.h4
-rw-r--r--arch/x86/kvm/mmu/spte.c72
-rw-r--r--arch/x86/kvm/mmu/spte.h129
-rw-r--r--arch/x86/kvm/mmu/tdp_iter.c14
-rw-r--r--arch/x86/kvm/mmu/tdp_iter.h25
-rw-r--r--arch/x86/kvm/mmu/tdp_mmu.c986
-rw-r--r--arch/x86/kvm/mmu/tdp_mmu.h31
-rw-r--r--arch/x86/kvm/pmu.c7
-rw-r--r--arch/x86/kvm/pmu.h2
-rw-r--r--arch/x86/kvm/svm/avic.c274
-rw-r--r--arch/x86/kvm/svm/hyperv.h35
-rw-r--r--arch/x86/kvm/svm/nested.c86
-rw-r--r--arch/x86/kvm/svm/pmu.c2
-rw-r--r--arch/x86/kvm/svm/sev.c130
-rw-r--r--arch/x86/kvm/svm/svm.c422
-rw-r--r--arch/x86/kvm/svm/svm.h71
-rw-r--r--arch/x86/kvm/svm/svm_onhyperv.h37
-rw-r--r--arch/x86/kvm/trace.h20
-rw-r--r--arch/x86/kvm/vmx/capabilities.h1
-rw-r--r--arch/x86/kvm/vmx/evmcs.c4
-rw-r--r--arch/x86/kvm/vmx/evmcs.h48
-rw-r--r--arch/x86/kvm/vmx/nested.c114
-rw-r--r--arch/x86/kvm/vmx/nested.h3
-rw-r--r--arch/x86/kvm/vmx/pmu_intel.c9
-rw-r--r--arch/x86/kvm/vmx/posted_intr.c6
-rw-r--r--arch/x86/kvm/vmx/posted_intr.h4
-rw-r--r--arch/x86/kvm/vmx/vmcs12.c4
-rw-r--r--arch/x86/kvm/vmx/vmcs12.h6
-rw-r--r--arch/x86/kvm/vmx/vmx.c213
-rw-r--r--arch/x86/kvm/vmx/vmx.h5
-rw-r--r--arch/x86/kvm/x86.c452
-rw-r--r--arch/x86/kvm/x86.h54
-rw-r--r--arch/x86/kvm/xen.c111
-rw-r--r--arch/x86/lib/memcpy_64.S10
-rw-r--r--arch/x86/lib/memmove_64.S4
-rw-r--r--arch/x86/lib/memset_64.S6
-rw-r--r--arch/x86/lib/retpoline.S2
-rw-r--r--arch/x86/lib/usercopy.c2
-rw-r--r--arch/x86/lib/x86-opcode-map.txt111
-rw-r--r--arch/x86/mm/ioremap.c57
-rw-r--r--arch/x86/mm/maccess.c7
-rw-r--r--arch/x86/mm/mem_encrypt_amd.c72
-rw-r--r--arch/x86/mm/mem_encrypt_identity.c12
-rw-r--r--arch/x86/mm/numa.c33
-rw-r--r--arch/x86/mm/pat/set_memory.c31
-rw-r--r--arch/x86/net/bpf_jit_comp.c84
-rw-r--r--arch/x86/pci/fixup.c4
-rw-r--r--arch/x86/um/Kconfig1
-rw-r--r--arch/x86/um/user-offsets.c9
-rw-r--r--arch/x86/xen/enlighten_hvm.c22
-rw-r--r--arch/x86/xen/enlighten_pv.c4
-rw-r--r--arch/x86/xen/smp_pv.c26
-rw-r--r--arch/x86/xen/vga.c16
-rw-r--r--arch/xtensa/Kconfig2
-rw-r--r--arch/xtensa/include/asm/asm-uaccess.h71
-rw-r--r--arch/xtensa/include/asm/bootparam.h2
-rw-r--r--arch/xtensa/include/asm/current.h2
-rw-r--r--arch/xtensa/include/asm/pgtable.h1
-rw-r--r--arch/xtensa/include/asm/processor.h7
-rw-r--r--arch/xtensa/include/asm/stacktrace.h8
-rw-r--r--arch/xtensa/include/asm/thread_info.h3
-rw-r--r--arch/xtensa/include/asm/uaccess.h26
-rw-r--r--arch/xtensa/include/uapi/asm/shmbuf.h5
-rw-r--r--arch/xtensa/include/uapi/asm/signal.h2
-rw-r--r--arch/xtensa/kernel/asm-offsets.c3
-rw-r--r--arch/xtensa/kernel/irq.c3
-rw-r--r--arch/xtensa/platforms/iss/network.c2
-rw-r--r--arch/xtensa/platforms/iss/simdisk.c4
-rw-r--r--block/Kconfig13
-rw-r--r--block/Makefile3
-rw-r--r--block/bdev.c13
-rw-r--r--block/bfq-cgroup.c16
-rw-r--r--block/bfq-iosched.c41
-rw-r--r--block/bfq-iosched.h2
-rw-r--r--block/bfq-wf2q.c17
-rw-r--r--block/bio-integrity.c3
-rw-r--r--block/bio.c190
-rw-r--r--block/blk-cgroup-rwstat.h2
-rw-r--r--block/blk-cgroup.c20
-rw-r--r--block/blk-cgroup.h494
-rw-r--r--block/blk-core.c344
-rw-r--r--block/blk-crypto-fallback.c2
-rw-r--r--block/blk-crypto-internal.h12
-rw-r--r--block/blk-crypto-sysfs.c172
-rw-r--r--block/blk-crypto.c4
-rw-r--r--block/blk-flush.c4
-rw-r--r--block/blk-ia-ranges.c2
-rw-r--r--block/blk-iocost.c2
-rw-r--r--block/blk-iolatency.c4
-rw-r--r--block/blk-ioprio.c2
-rw-r--r--block/blk-lib.c39
-rw-r--r--block/blk-map.c2
-rw-r--r--block/blk-merge.c33
-rw-r--r--block/blk-mq-debugfs.c6
-rw-r--r--block/blk-mq-debugfs.h2
-rw-r--r--block/blk-mq-sched.c18
-rw-r--r--block/blk-mq-sysfs.c16
-rw-r--r--block/blk-mq-tag.c6
-rw-r--r--block/blk-mq.c344
-rw-r--r--block/blk-mq.h2
-rw-r--r--block/blk-rq-qos.h20
-rw-r--r--block/blk-sysfs.c44
-rw-r--r--block/blk-throttle.c110
-rw-r--r--block/blk-throttle.h19
-rw-r--r--block/blk-zoned.c14
-rw-r--r--block/blk.h10
-rw-r--r--block/bounce.c11
-rw-r--r--block/disk-events.c2
-rw-r--r--block/elevator.c18
-rw-r--r--block/fops.c73
-rw-r--r--block/genhd.c85
-rw-r--r--block/holder.c2
-rw-r--r--block/partitions/check.h1
-rw-r--r--block/partitions/core.c1
-rw-r--r--block/partitions/efi.h1
-rw-r--r--block/partitions/ldm.h1
-rw-r--r--block/sed-opal.c2
-rw-r--r--certs/system_keyring.c44
-rw-r--r--crypto/Kconfig25
-rw-r--r--crypto/af_alg.c3
-rw-r--r--crypto/algapi.c49
-rw-r--r--crypto/api.c20
-rw-r--r--crypto/asymmetric_keys/Kconfig21
-rw-r--r--crypto/asymmetric_keys/Makefile12
-rw-r--r--crypto/asymmetric_keys/asym_tpm.c957
-rw-r--r--crypto/asymmetric_keys/pkcs7_verify.c13
-rw-r--r--crypto/asymmetric_keys/public_key.c126
-rw-r--r--crypto/asymmetric_keys/signature.c2
-rw-r--r--crypto/asymmetric_keys/tpm.asn15
-rw-r--r--crypto/asymmetric_keys/tpm_parser.c102
-rw-r--r--crypto/asymmetric_keys/x509.asn12
-rw-r--r--crypto/asymmetric_keys/x509_cert_parser.c34
-rw-r--r--crypto/asymmetric_keys/x509_parser.h3
-rw-r--r--crypto/asymmetric_keys/x509_public_key.c24
-rw-r--r--crypto/async_tx/async_xor.c8
-rw-r--r--crypto/async_tx/raid6test.c4
-rw-r--r--crypto/authenc.c2
-rw-r--r--crypto/blake2s_generic.c4
-rw-r--r--crypto/cfb.c2
-rw-r--r--crypto/crypto_engine.c1
-rw-r--r--crypto/dh.c681
-rw-r--r--crypto/dh_helper.c42
-rw-r--r--crypto/hmac.c4
-rw-r--r--crypto/kpp.c29
-rw-r--r--crypto/lrw.c1
-rw-r--r--crypto/memneq.c22
-rw-r--r--crypto/rsa-pkcs1pad.c38
-rw-r--r--crypto/sm2.c40
-rw-r--r--crypto/sm3_generic.c142
-rw-r--r--crypto/tcrypt.c226
-rw-r--r--crypto/testmgr.c67
-rw-r--r--crypto/testmgr.h1456
-rw-r--r--crypto/xts.c1
-rw-r--r--drivers/accessibility/speakup/speakup_dectlk.c1
-rw-r--r--drivers/acpi/Kconfig3
-rw-r--r--drivers/acpi/Makefile3
-rw-r--r--drivers/acpi/acpi_lpss.c33
-rw-r--r--drivers/acpi/acpi_platform.c2
-rw-r--r--drivers/acpi/acpica/nswalk.c3
-rw-r--r--drivers/acpi/apei/bert.c10
-rw-r--r--drivers/acpi/apei/erst.c2
-rw-r--r--drivers/acpi/apei/ghes.c19
-rw-r--r--drivers/acpi/apei/hest.c2
-rw-r--r--drivers/acpi/arm64/Kconfig10
-rw-r--r--drivers/acpi/arm64/Makefile1
-rw-r--r--drivers/acpi/arm64/agdi.c116
-rw-r--r--drivers/acpi/arm64/iort.c14
-rw-r--r--drivers/acpi/battery.c12
-rw-r--r--drivers/acpi/bus.c46
-rw-r--r--drivers/acpi/cppc_acpi.c9
-rw-r--r--drivers/acpi/ec.c100
-rw-r--r--drivers/acpi/fan.h44
-rw-r--r--drivers/acpi/fan_attr.c137
-rw-r--r--drivers/acpi/fan_core.c (renamed from drivers/acpi/fan.c)204
-rw-r--r--drivers/acpi/internal.h2
-rw-r--r--drivers/acpi/osl.c19
-rw-r--r--drivers/acpi/pci_link.c2
-rw-r--r--drivers/acpi/pci_root.c3
-rw-r--r--drivers/acpi/processor_idle.c20
-rw-r--r--drivers/acpi/property.c29
-rw-r--r--drivers/acpi/scan.c31
-rw-r--r--drivers/acpi/sleep.c28
-rw-r--r--drivers/acpi/tables.c4
-rw-r--r--drivers/acpi/video_detect.c75
-rw-r--r--drivers/acpi/x86/s2idle.c12
-rw-r--r--drivers/acpi/x86/utils.c21
-rw-r--r--drivers/amba/bus.c73
-rw-r--r--drivers/ata/Kconfig8
-rw-r--r--drivers/ata/acard-ahci.c2
-rw-r--r--drivers/ata/ahci.c113
-rw-r--r--drivers/ata/ahci.h4
-rw-r--r--drivers/ata/ahci_brcm.c2
-rw-r--r--drivers/ata/ahci_ceva.c2
-rw-r--r--drivers/ata/ahci_da850.c2
-rw-r--r--drivers/ata/ahci_dm816.c2
-rw-r--r--drivers/ata/ahci_imx.c2
-rw-r--r--drivers/ata/ahci_mtk.c2
-rw-r--r--drivers/ata/ahci_mvebu.c2
-rw-r--r--drivers/ata/ahci_octeon.c2
-rw-r--r--drivers/ata/ahci_platform.c2
-rw-r--r--drivers/ata/ahci_qoriq.c4
-rw-r--r--drivers/ata/ahci_st.c2
-rw-r--r--drivers/ata/ahci_sunxi.c2
-rw-r--r--drivers/ata/ahci_xgene.c4
-rw-r--r--drivers/ata/ata_piix.c5
-rw-r--r--drivers/ata/libahci.c4
-rw-r--r--drivers/ata/libahci_platform.c3
-rw-r--r--drivers/ata/libata-acpi.c29
-rw-r--r--drivers/ata/libata-core.c47
-rw-r--r--drivers/ata/libata-eh.c49
-rw-r--r--drivers/ata/libata-sata.c10
-rw-r--r--drivers/ata/libata-scsi.c95
-rw-r--r--drivers/ata/libata-sff.c136
-rw-r--r--drivers/ata/libata.h2
-rw-r--r--drivers/ata/pata_arasan_cf.c3
-rw-r--r--drivers/ata/pata_artop.c31
-rw-r--r--drivers/ata/pata_atiixp.c4
-rw-r--r--drivers/ata/pata_cs5520.c5
-rw-r--r--drivers/ata/pata_ep93xx.c4
-rw-r--r--drivers/ata/pata_ftide010.c6
-rw-r--r--drivers/ata/pata_hpt366.c49
-rw-r--r--drivers/ata/pata_hpt37x.c133
-rw-r--r--drivers/ata/pata_hpt3x2n.c38
-rw-r--r--drivers/ata/pata_imx.c15
-rw-r--r--drivers/ata/pata_ixp4xx_cf.c2
-rw-r--r--drivers/ata/pata_macio.c24
-rw-r--r--drivers/ata/pata_mpc52xx.c7
-rw-r--r--drivers/ata/pata_ns87415.c4
-rw-r--r--drivers/ata/pata_octeon_cf.c10
-rw-r--r--drivers/ata/pata_of_platform.c2
-rw-r--r--drivers/ata/pata_pdc202xx_old.c2
-rw-r--r--drivers/ata/pata_platform.c20
-rw-r--r--drivers/ata/pata_pxa.c10
-rw-r--r--drivers/ata/pata_samsung_cf.c12
-rw-r--r--drivers/ata/pata_triflex.c5
-rw-r--r--drivers/ata/sata_fsl.c30
-rw-r--r--drivers/ata/sata_gemini.c6
-rw-r--r--drivers/ata/sata_highbank.c7
-rw-r--r--drivers/ata/sata_inic162x.c10
-rw-r--r--drivers/ata/sata_mv.c8
-rw-r--r--drivers/ata/sata_rcar.c35
-rw-r--r--drivers/ata/sata_svw.c10
-rw-r--r--drivers/ata/sata_vsc.c10
-rw-r--r--drivers/atm/eni.c2
-rw-r--r--drivers/atm/firestream.c2
-rw-r--r--drivers/atm/nicstar.c10
-rw-r--r--drivers/auxdisplay/lcd2s.c24
-rw-r--r--drivers/base/arch_topology.c45
-rw-r--r--drivers/base/class.c2
-rw-r--r--drivers/base/core.c2
-rw-r--r--drivers/base/cpu.c2
-rw-r--r--drivers/base/dd.c5
-rw-r--r--drivers/base/devtmpfs.c2
-rw-r--r--drivers/base/init.c1
-rw-r--r--drivers/base/memory.c147
-rw-r--r--drivers/base/node.c48
-rw-r--r--drivers/base/power/domain.c42
-rw-r--r--drivers/base/power/main.c16
-rw-r--r--drivers/base/power/runtime.c5
-rw-r--r--drivers/base/power/wakeirq.c2
-rw-r--r--drivers/base/power/wakeup.c45
-rw-r--r--drivers/base/regmap/internal.h2
-rw-r--r--drivers/base/regmap/regmap-irq.c26
-rw-r--r--drivers/base/regmap/regmap.c11
-rw-r--r--drivers/base/topology.c20
-rw-r--r--drivers/bcma/driver_chipcommon.c2
-rw-r--r--drivers/bcma/driver_chipcommon_pmu.c6
-rw-r--r--drivers/bcma/driver_gpio.c1
-rw-r--r--drivers/bcma/driver_pci_host.c6
-rw-r--r--drivers/bcma/main.c4
-rw-r--r--drivers/bcma/sprom.c4
-rw-r--r--drivers/block/aoe/aoeblk.c1
-rw-r--r--drivers/block/aoe/aoecmd.c5
-rw-r--r--drivers/block/drbd/drbd_actlog.c5
-rw-r--r--drivers/block/drbd/drbd_bitmap.c7
-rw-r--r--drivers/block/drbd/drbd_int.h4
-rw-r--r--drivers/block/drbd/drbd_receiver.c36
-rw-r--r--drivers/block/drbd/drbd_req.c8
-rw-r--r--drivers/block/drbd/drbd_worker.c10
-rw-r--r--drivers/block/floppy.c10
-rw-r--r--drivers/block/loop.c115
-rw-r--r--drivers/block/loop.h1
-rw-r--r--drivers/block/mtip32xx/mtip32xx.c7
-rw-r--r--drivers/block/mtip32xx/mtip32xx.h1
-rw-r--r--drivers/block/null_blk/main.c54
-rw-r--r--drivers/block/pktcdvd.c21
-rw-r--r--drivers/block/rbd.c2
-rw-r--r--drivers/block/rnbd/rnbd-clt.c28
-rw-r--r--drivers/block/rnbd/rnbd-clt.h1
-rw-r--r--drivers/block/rnbd/rnbd-proto.h4
-rw-r--r--drivers/block/rnbd/rnbd-srv-dev.c61
-rw-r--r--drivers/block/rnbd/rnbd-srv-dev.h18
-rw-r--r--drivers/block/rnbd/rnbd-srv-sysfs.c1
-rw-r--r--drivers/block/rnbd/rnbd-srv.c46
-rw-r--r--drivers/block/rnbd/rnbd-srv.h1
-rw-r--r--drivers/block/sunvdc.c1
-rw-r--r--drivers/block/virtio_blk.c94
-rw-r--r--drivers/block/xen-blkback/blkback.c25
-rw-r--r--drivers/block/xen-blkback/xenbus.c1
-rw-r--r--drivers/block/xen-blkfront.c70
-rw-r--r--drivers/block/zram/zram_drv.c26
-rw-r--r--drivers/bluetooth/Kconfig1
-rw-r--r--drivers/bluetooth/ath3k.c1
-rw-r--r--drivers/bluetooth/bcm203x.c1
-rw-r--r--drivers/bluetooth/btintel.c11
-rw-r--r--drivers/bluetooth/btintel.h1
-rw-r--r--drivers/bluetooth/btmrvl_debugfs.c2
-rw-r--r--drivers/bluetooth/btmrvl_sdio.c2
-rw-r--r--drivers/bluetooth/btmtk.c1
-rw-r--r--drivers/bluetooth/btmtk.h43
-rw-r--r--drivers/bluetooth/btmtksdio.c471
-rw-r--r--drivers/bluetooth/btmtkuart.c198
-rw-r--r--drivers/bluetooth/btrtl.c21
-rw-r--r--drivers/bluetooth/btusb.c100
-rw-r--r--drivers/bluetooth/hci_bcm.c46
-rw-r--r--drivers/bluetooth/hci_h5.c13
-rw-r--r--drivers/bluetooth/hci_ll.c2
-rw-r--r--drivers/bluetooth/hci_serdev.c3
-rw-r--r--drivers/bus/imx-weim.c135
-rw-r--r--drivers/bus/mhi/pci_generic.c2
-rw-r--r--drivers/bus/moxtet.c4
-rw-r--r--drivers/cdrom/gdrom.c1
-rw-r--r--drivers/char/agp/ati-agp.c8
-rw-r--r--drivers/char/agp/backend.c2
-rw-r--r--drivers/char/agp/frontend.c4
-rw-r--r--drivers/char/agp/nvidia-agp.c3
-rw-r--r--drivers/char/agp/sworks-agp.c5
-rw-r--r--drivers/char/agp/via-agp.c3
-rw-r--r--drivers/char/hw_random/Kconfig2
-rw-r--r--drivers/char/hw_random/atmel-rng.c148
-rw-r--r--drivers/char/hw_random/cavium-rng-vf.c2
-rw-r--r--drivers/char/hw_random/core.c162
-rw-r--r--drivers/char/hw_random/nomadik-rng.c4
-rw-r--r--drivers/char/hw_random/optee-rng.c6
-rw-r--r--drivers/char/random.c2858
-rw-r--r--drivers/char/tpm/st33zp24/i2c.c5
-rw-r--r--drivers/char/tpm/st33zp24/spi.c9
-rw-r--r--drivers/char/tpm/st33zp24/st33zp24.c3
-rw-r--r--drivers/char/tpm/st33zp24/st33zp24.h2
-rw-r--r--drivers/char/tpm/tpm-chip.c46
-rw-r--r--drivers/char/tpm/tpm-dev-common.c8
-rw-r--r--drivers/char/tpm/tpm.h2
-rw-r--r--drivers/char/tpm/tpm2-space.c73
-rw-r--r--drivers/char/tpm/tpm_tis_spi_main.c3
-rw-r--r--drivers/char/tpm/tpm_vtpm_proxy.c2
-rw-r--r--drivers/char/tpm/xen-tpmfront.c8
-rw-r--r--drivers/char/virtio_console.c7
-rw-r--r--drivers/clk/Kconfig2
-rw-r--r--drivers/clk/clk-lmk04832.c4
-rw-r--r--drivers/clk/clk-scmi.c71
-rw-r--r--drivers/clk/ingenic/jz4725b-cgu.c3
-rw-r--r--drivers/clk/qcom/dispcc-sc7180.c5
-rw-r--r--drivers/clk/qcom/dispcc-sc7280.c5
-rw-r--r--drivers/clk/qcom/dispcc-sm8250.c5
-rw-r--r--drivers/clk/qcom/gcc-msm8994.c106
-rw-r--r--drivers/clk/qcom/gdsc.c26
-rw-r--r--drivers/clk/qcom/gdsc.h8
-rw-r--r--drivers/clk/samsung/Kconfig9
-rw-r--r--drivers/clk/samsung/Makefile1
-rw-r--r--drivers/clk/samsung/clk-fsd.c1803
-rw-r--r--drivers/clk/samsung/clk-pll.c1
-rw-r--r--drivers/clk/samsung/clk-pll.h1
-rw-r--r--drivers/clocksource/Kconfig10
-rw-r--r--drivers/clocksource/Makefile1
-rw-r--r--drivers/clocksource/acpi_pm.c6
-rw-r--r--drivers/clocksource/arm_arch_timer.c13
-rw-r--r--drivers/clocksource/exynos_mct.c39
-rw-r--r--drivers/clocksource/timer-atcpit100.c266
-rw-r--r--drivers/clocksource/timer-imx-sysctr.c2
-rw-r--r--drivers/clocksource/timer-imx-tpm.c14
-rw-r--r--drivers/clocksource/timer-microchip-pit64b.c8
-rw-r--r--drivers/clocksource/timer-of.c6
-rw-r--r--drivers/clocksource/timer-ti-dm-systimer.c7
-rw-r--r--drivers/connector/cn_proc.c2
-rw-r--r--drivers/counter/counter-core.c15
-rw-r--r--drivers/counter/counter-sysfs.c17
-rw-r--r--drivers/cpufreq/amd-pstate-trace.h22
-rw-r--r--drivers/cpufreq/amd-pstate.c59
-rw-r--r--drivers/cpufreq/cpufreq.c4
-rw-r--r--drivers/cpufreq/cpufreq_conservative.c10
-rw-r--r--drivers/cpufreq/cpufreq_governor.c6
-rw-r--r--drivers/cpufreq/cpufreq_governor.h12
-rw-r--r--drivers/cpufreq/cpufreq_governor_attr_set.c5
-rw-r--r--drivers/cpufreq/cpufreq_ondemand.c10
-rw-r--r--drivers/cpufreq/intel_pstate.c38
-rw-r--r--drivers/cpufreq/longhaul.c4
-rw-r--r--drivers/cpufreq/powernow-k8.c6
-rw-r--r--drivers/cpufreq/qcom-cpufreq-hw.c11
-rw-r--r--drivers/cpuidle/cpuidle-haltpoll.c4
-rw-r--r--drivers/cpuidle/cpuidle-qcom-spm.c28
-rw-r--r--drivers/crypto/Kconfig10
-rw-r--r--drivers/crypto/Makefile2
-rw-r--r--drivers/crypto/allwinner/sun8i-ce/sun8i-ce-cipher.c3
-rw-r--r--drivers/crypto/allwinner/sun8i-ce/sun8i-ce-hash.c3
-rw-r--r--drivers/crypto/allwinner/sun8i-ss/sun8i-ss-cipher.c3
-rw-r--r--drivers/crypto/allwinner/sun8i-ss/sun8i-ss-core.c2
-rw-r--r--drivers/crypto/allwinner/sun8i-ss/sun8i-ss-hash.c3
-rw-r--r--drivers/crypto/amlogic/amlogic-gxl-cipher.c2
-rw-r--r--drivers/crypto/atmel-aes.c1
-rw-r--r--drivers/crypto/atmel-sha.c1
-rw-r--r--drivers/crypto/atmel-tdes.c1
-rw-r--r--drivers/crypto/caam/pdb.h2
-rw-r--r--drivers/crypto/cavium/nitrox/nitrox_mbx.c8
-rw-r--r--drivers/crypto/cavium/nitrox/nitrox_req.h2
-rw-r--r--drivers/crypto/cavium/zip/zip_main.c83
-rw-r--r--drivers/crypto/ccp/ccp-crypto-aes.c5
-rw-r--r--drivers/crypto/ccp/ccp-dmaengine.c16
-rw-r--r--drivers/crypto/ccp/sev-dev.c2
-rw-r--r--drivers/crypto/ccree/cc_buffer_mgr.c7
-rw-r--r--drivers/crypto/ccree/cc_cipher.c2
-rw-r--r--drivers/crypto/gemini/sl3516-ce-cipher.c6
-rw-r--r--drivers/crypto/hisilicon/hpre/hpre.h2
-rw-r--r--drivers/crypto/hisilicon/hpre/hpre_main.c19
-rw-r--r--drivers/crypto/hisilicon/qm.c72
-rw-r--r--drivers/crypto/hisilicon/sec2/sec.h2
-rw-r--r--drivers/crypto/hisilicon/sec2/sec_crypto.c43
-rw-r--r--drivers/crypto/hisilicon/sec2/sec_crypto.h6
-rw-r--r--drivers/crypto/hisilicon/sec2/sec_main.c80
-rw-r--r--drivers/crypto/hisilicon/sgl.c2
-rw-r--r--drivers/crypto/hisilicon/zip/zip.h2
-rw-r--r--drivers/crypto/hisilicon/zip/zip_main.c17
-rw-r--r--drivers/crypto/ixp4xx_crypto.c1
-rw-r--r--drivers/crypto/marvell/Kconfig1
-rw-r--r--drivers/crypto/marvell/octeontx/otx_cptvf_algs.c5
-rw-r--r--drivers/crypto/marvell/octeontx/otx_cptvf_main.c1
-rw-r--r--drivers/crypto/marvell/octeontx2/otx2_cpt_common.h1
-rw-r--r--drivers/crypto/marvell/octeontx2/otx2_cpt_mbox_common.c14
-rw-r--r--drivers/crypto/marvell/octeontx2/otx2_cptlf.h19
-rw-r--r--drivers/crypto/marvell/octeontx2/otx2_cptpf.h1
-rw-r--r--drivers/crypto/marvell/octeontx2/otx2_cptpf_main.c25
-rw-r--r--drivers/crypto/marvell/octeontx2/otx2_cptpf_mbox.c27
-rw-r--r--drivers/crypto/marvell/octeontx2/otx2_cptpf_ucode.c59
-rw-r--r--drivers/crypto/marvell/octeontx2/otx2_cptvf_algs.c17
-rw-r--r--drivers/crypto/mxs-dcp.c2
-rw-r--r--drivers/crypto/nx/nx-common-pseries.c4
-rw-r--r--drivers/crypto/omap-aes.c2
-rw-r--r--drivers/crypto/omap-sham.c2
-rw-r--r--drivers/crypto/qat/qat_4xxx/adf_4xxx_hw_data.c23
-rw-r--r--drivers/crypto/qat/qat_4xxx/adf_4xxx_hw_data.h24
-rw-r--r--drivers/crypto/qat/qat_4xxx/adf_drv.c7
-rw-r--r--drivers/crypto/qat/qat_common/Makefile1
-rw-r--r--drivers/crypto/qat/qat_common/adf_accel_devices.h2
-rw-r--r--drivers/crypto/qat/qat_common/adf_admin.c37
-rw-r--r--drivers/crypto/qat/qat_common/adf_common_drv.h4
-rw-r--r--drivers/crypto/qat/qat_common/adf_ctl_drv.c6
-rw-r--r--drivers/crypto/qat/qat_common/adf_gen4_hw_data.h14
-rw-r--r--drivers/crypto/qat/qat_common/adf_gen4_pfvf.c42
-rw-r--r--drivers/crypto/qat/qat_common/adf_gen4_pm.c137
-rw-r--r--drivers/crypto/qat/qat_common/adf_gen4_pm.h44
-rw-r--r--drivers/crypto/qat/qat_common/adf_init.c6
-rw-r--r--drivers/crypto/qat/qat_common/adf_isr.c42
-rw-r--r--drivers/crypto/qat/qat_common/adf_pfvf_vf_msg.c4
-rw-r--r--drivers/crypto/qat/qat_common/icp_qat_fw_init_admin.h1
-rw-r--r--drivers/crypto/qat/qat_common/qat_crypto.c7
-rw-r--r--drivers/crypto/qat/qat_common/qat_uclo.c9
-rw-r--r--drivers/crypto/qcom-rng.c17
-rw-r--r--drivers/crypto/rockchip/rk3288_crypto_skcipher.c1
-rw-r--r--drivers/crypto/ux500/cryp/cryp_core.c2
-rw-r--r--drivers/crypto/ux500/hash/hash_core.c2
-rw-r--r--drivers/crypto/vmx/Kconfig4
-rw-r--r--drivers/crypto/xilinx/Makefile1
-rw-r--r--drivers/crypto/xilinx/zynqmp-sha.c264
-rw-r--r--drivers/cxl/Kconfig44
-rw-r--r--drivers/cxl/Makefile6
-rw-r--r--drivers/cxl/acpi.c152
-rw-r--r--drivers/cxl/core/Makefile4
-rw-r--r--drivers/cxl/core/bus.c675
-rw-r--r--drivers/cxl/core/core.h2
-rw-r--r--drivers/cxl/core/hdm.c276
-rw-r--r--drivers/cxl/core/memdev.c44
-rw-r--r--drivers/cxl/core/pci.c96
-rw-r--r--drivers/cxl/core/pmem.c18
-rw-r--r--drivers/cxl/core/port.c1568
-rw-r--r--drivers/cxl/core/regs.c67
-rw-r--r--drivers/cxl/cxl.h197
-rw-r--r--drivers/cxl/cxlmem.h39
-rw-r--r--drivers/cxl/cxlpci.h75
-rw-r--r--drivers/cxl/mem.c228
-rw-r--r--drivers/cxl/pci.c383
-rw-r--r--drivers/cxl/pci.h34
-rw-r--r--drivers/cxl/pmem.c12
-rw-r--r--drivers/cxl/port.c76
-rw-r--r--drivers/dax/device.c3
-rw-r--r--drivers/dax/super.c4
-rw-r--r--drivers/dma-buf/dma-buf.c22
-rw-r--r--drivers/dma-buf/dma-fence-array.c14
-rw-r--r--drivers/dma-buf/dma-fence-chain.c15
-rw-r--r--drivers/dma-buf/dma-heap.c2
-rw-r--r--drivers/dma-buf/dma-resv.c82
-rw-r--r--drivers/dma-buf/heaps/cma_heap.c10
-rw-r--r--drivers/dma-buf/heaps/system_heap.c10
-rw-r--r--drivers/dma-buf/st-dma-resv.c26
-rw-r--r--drivers/dma-buf/udmabuf.c4
-rw-r--r--drivers/dma/at_xdmac.c4
-rw-r--r--drivers/dma/pl330.c4
-rw-r--r--drivers/dma/ptdma/ptdma-dev.c17
-rw-r--r--drivers/dma/sh/rcar-dmac.c9
-rw-r--r--drivers/dma/sh/shdma-base.c4
-rw-r--r--drivers/dma/stm32-dmamux.c4
-rw-r--r--drivers/edac/altera_edac.c42
-rw-r--r--drivers/edac/amd64_edac.c109
-rw-r--r--drivers/edac/amd64_edac.h24
-rw-r--r--drivers/edac/edac_device_sysfs.c31
-rw-r--r--drivers/edac/edac_mc.c6
-rw-r--r--drivers/edac/edac_pci_sysfs.c26
-rw-r--r--drivers/edac/xgene_edac.c2
-rw-r--r--drivers/firmware/Kconfig1
-rw-r--r--drivers/firmware/arm_scmi/Kconfig56
-rw-r--r--drivers/firmware/arm_scmi/Makefile8
-rw-r--r--drivers/firmware/arm_scmi/clock.c34
-rw-r--r--drivers/firmware/arm_scmi/common.h26
-rw-r--r--drivers/firmware/arm_scmi/driver.c236
-rw-r--r--drivers/firmware/arm_scmi/mailbox.c3
-rw-r--r--drivers/firmware/arm_scmi/optee.c567
-rw-r--r--drivers/firmware/arm_scmi/smc.c98
-rw-r--r--drivers/firmware/arm_scmi/virtio.c613
-rw-r--r--drivers/firmware/arm_sdei.c13
-rw-r--r--drivers/firmware/efi/apple-properties.c2
-rw-r--r--drivers/firmware/efi/efi-pstore.c2
-rw-r--r--drivers/firmware/efi/efi.c9
-rw-r--r--drivers/firmware/efi/libstub/arm64-stub.c6
-rw-r--r--drivers/firmware/efi/libstub/riscv-stub.c17
-rw-r--r--drivers/firmware/efi/mokvar-table.c2
-rw-r--r--drivers/firmware/efi/vars.c5
-rw-r--r--drivers/firmware/imx/rm.c45
-rw-r--r--drivers/firmware/imx/scu-pd.c4
-rw-r--r--drivers/firmware/qcom_scm.c215
-rw-r--r--drivers/firmware/qcom_scm.h7
-rw-r--r--drivers/firmware/sysfb_simplefb.c2
-rw-r--r--drivers/firmware/ti_sci.c2
-rw-r--r--drivers/firmware/xilinx/zynqmp.c26
-rw-r--r--drivers/gpio/gpio-74x164.c4
-rw-r--r--drivers/gpio/gpio-aggregator.c18
-rw-r--r--drivers/gpio/gpio-max3191x.c4
-rw-r--r--drivers/gpio/gpio-max7301.c4
-rw-r--r--drivers/gpio/gpio-mc33880.c4
-rw-r--r--drivers/gpio/gpio-mt7621.c1
-rw-r--r--drivers/gpio/gpio-omap.c7
-rw-r--r--drivers/gpio/gpio-pisosr.c4
-rw-r--r--drivers/gpio/gpio-rcar.c2
-rw-r--r--drivers/gpio/gpio-rockchip.c56
-rw-r--r--drivers/gpio/gpio-sifive.c2
-rw-r--r--drivers/gpio/gpio-sim.c23
-rw-r--r--drivers/gpio/gpio-tegra186.c16
-rw-r--r--drivers/gpio/gpio-tqmx86.c3
-rw-r--r--drivers/gpio/gpio-ts4900.c24
-rw-r--r--drivers/gpio/gpiolib-acpi.c6
-rw-r--r--drivers/gpio/gpiolib-cdev.c6
-rw-r--r--drivers/gpio/gpiolib-sysfs.c7
-rw-r--r--drivers/gpio/gpiolib.c20
-rw-r--r--drivers/gpio/gpiolib.h12
-rw-r--r--drivers/gpu/drm/Kconfig18
-rw-r--r--drivers/gpu/drm/Makefile15
-rw-r--r--drivers/gpu/drm/amd/amdgpu/Makefile6
-rw-r--r--drivers/gpu/drm/amd/amdgpu/aldebaran.c68
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu.h169
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c37
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h7
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_aldebaran.c3
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_arcturus.c3
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v10.c24
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v10_3.c35
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v7.c96
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v8.c24
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v9.c28
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v9.h10
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c76
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c2
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.h22
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_benchmark.c244
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_bios.c38
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c8
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c33
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_cs.h80
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_csa.c2
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c140
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.h2
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c164
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_device.c468
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c683
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_display.c43
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c244
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c43
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_fru_eeprom.c53
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c36
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_gart.h15
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c8
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c73
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.h25
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c166
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h14
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_gtt_mgr.c59
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_hdp.h14
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c4
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_ids.c4
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c12
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_job.c12
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_job.h9
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c126
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_mca.c45
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_mca.h20
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_mmhub.c68
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_mmhub.h14
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h5
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_nbio.c47
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_nbio.h12
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_object.c10
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_preempt_mgr.c65
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c131
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h9
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c548
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_ras.h80
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_ras_eeprom.c60
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_ras_eeprom.h4
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_reset.c64
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_reset.h40
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c6
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h65
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_rlc.h16
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.c53
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.h15
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c5
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_test.c250
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_trace.h21
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_trace_points.c1
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c421
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h21
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.h3
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_umc.c114
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_umc.h24
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c39
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.h4
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c117
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_vce.h7
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c142
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.h30
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c151
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h26
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c3
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c22
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h2
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c63
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.c143
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.h10
-rw-r--r--drivers/gpu/drm/amd/amdgpu/athub_v1_0.c13
-rw-r--r--drivers/gpu/drm/amd/amdgpu/athub_v2_0.c1
-rw-r--r--drivers/gpu/drm/amd/amdgpu/athub_v2_1.c1
-rw-r--r--drivers/gpu/drm/amd/amdgpu/atom.c4
-rw-r--r--drivers/gpu/drm/amd/amdgpu/atombios_dp.c2
-rw-r--r--drivers/gpu/drm/amd/amdgpu/cik.c2
-rw-r--r--drivers/gpu/drm/amd/amdgpu/dce_v10_0.c4
-rw-r--r--drivers/gpu/drm/amd/amdgpu/dce_v11_0.c4
-rw-r--r--drivers/gpu/drm/amd/amdgpu/dce_v6_0.c3
-rw-r--r--drivers/gpu/drm/amd/amdgpu/dce_v8_0.c4
-rw-r--r--drivers/gpu/drm/amd/amdgpu/df_v3_6.c6
-rw-r--r--drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c353
-rw-r--r--drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c230
-rw-r--r--drivers/gpu/drm/amd/amdgpu/gfx_v9_4.c24
-rw-r--r--drivers/gpu/drm/amd/amdgpu/gfx_v9_4.h2
-rw-r--r--drivers/gpu/drm/amd/amdgpu/gfx_v9_4_2.c25
-rw-r--r--drivers/gpu/drm/amd/amdgpu/gfx_v9_4_2.h2
-rw-r--r--drivers/gpu/drm/amd/amdgpu/gfxhub_v2_1.c7
-rw-r--r--drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c57
-rw-r--r--drivers/gpu/drm/amd/amdgpu/gmc_v6_0.c12
-rw-r--r--drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c13
-rw-r--r--drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c13
-rw-r--r--drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c104
-rw-r--r--drivers/gpu/drm/amd/amdgpu/hdp_v4_0.c18
-rw-r--r--drivers/gpu/drm/amd/amdgpu/hdp_v4_0.h2
-rw-r--r--drivers/gpu/drm/amd/amdgpu/jpeg_v3_0.c9
-rw-r--r--drivers/gpu/drm/amd/amdgpu/mca_v3_0.c108
-rw-r--r--drivers/gpu/drm/amd/amdgpu/mmhub_v1_0.c10
-rw-r--r--drivers/gpu/drm/amd/amdgpu/mmhub_v1_0.h2
-rw-r--r--drivers/gpu/drm/amd/amdgpu/mmhub_v1_7.c10
-rw-r--r--drivers/gpu/drm/amd/amdgpu/mmhub_v1_7.h2
-rw-r--r--drivers/gpu/drm/amd/amdgpu/mmhub_v2_3.c1
-rw-r--r--drivers/gpu/drm/amd/amdgpu/mmhub_v9_4.c10
-rw-r--r--drivers/gpu/drm/amd/amdgpu/mmhub_v9_4.h2
-rw-r--r--drivers/gpu/drm/amd/amdgpu/mxgpu_ai.c19
-rw-r--r--drivers/gpu/drm/amd/amdgpu/mxgpu_nv.c19
-rw-r--r--drivers/gpu/drm/amd/amdgpu/mxgpu_vi.c13
-rw-r--r--drivers/gpu/drm/amd/amdgpu/nbio_v7_2.c48
-rw-r--r--drivers/gpu/drm/amd/amdgpu/nbio_v7_4.c34
-rw-r--r--drivers/gpu/drm/amd/amdgpu/nbio_v7_4.h2
-rw-r--r--drivers/gpu/drm/amd/amdgpu/nv.c129
-rw-r--r--drivers/gpu/drm/amd/amdgpu/psp_gfx_if.h1
-rw-r--r--drivers/gpu/drm/amd/amdgpu/psp_v11_0.c4
-rw-r--r--drivers/gpu/drm/amd/amdgpu/psp_v13_0.c15
-rw-r--r--drivers/gpu/drm/amd/amdgpu/psp_v3_1.c1
-rw-r--r--drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c1
-rw-r--r--drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c1
-rw-r--r--drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c75
-rw-r--r--drivers/gpu/drm/amd/amdgpu/sdma_v4_4.c25
-rw-r--r--drivers/gpu/drm/amd/amdgpu/sdma_v4_4.h2
-rw-r--r--drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c9
-rw-r--r--drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c29
-rw-r--r--drivers/gpu/drm/amd/amdgpu/si.c2
-rw-r--r--drivers/gpu/drm/amd/amdgpu/smu_v11_0_i2c.c81
-rw-r--r--drivers/gpu/drm/amd/amdgpu/smu_v11_0_i2c.h6
-rw-r--r--drivers/gpu/drm/amd/amdgpu/soc15.c71
-rw-r--r--drivers/gpu/drm/amd/amdgpu/soc15_common.h8
-rw-r--r--drivers/gpu/drm/amd/amdgpu/ta_ras_if.h3
-rw-r--r--drivers/gpu/drm/amd/amdgpu/umc_v6_1.c30
-rw-r--r--drivers/gpu/drm/amd/amdgpu/umc_v6_1.h2
-rw-r--r--drivers/gpu/drm/amd/amdgpu/umc_v6_7.c225
-rw-r--r--drivers/gpu/drm/amd/amdgpu/umc_v6_7.h25
-rw-r--r--drivers/gpu/drm/amd/amdgpu/umc_v8_7.c166
-rw-r--r--drivers/gpu/drm/amd/amdgpu/umc_v8_7.h2
-rw-r--r--drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c14
-rw-r--r--drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c17
-rw-r--r--drivers/gpu/drm/amd/amdgpu/vcn_v2_0.c25
-rw-r--r--drivers/gpu/drm/amd/amdgpu/vcn_v2_5.c23
-rw-r--r--drivers/gpu/drm/amd/amdgpu/vcn_v3_0.c53
-rw-r--r--drivers/gpu/drm/amd/amdgpu/vi.c2
-rw-r--r--drivers/gpu/drm/amd/amdkfd/Makefile2
-rw-r--r--drivers/gpu/drm/amd/amdkfd/cik_event_interrupt.c2
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_chardev.c1585
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_crat.c8
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_crat.h5
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_dbgdev.c845
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_dbgdev.h230
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_dbgmgr.c158
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_dbgmgr.h293
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_debugfs.c5
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_device.c67
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c274
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.h62
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager_cik.c3
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager_v10.c12
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager_v9.c3
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager_vi.c3
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_doorbell.c3
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_events.c316
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_events.h3
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_flat_memory.c5
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_int_process_v9.c11
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_interrupt.c11
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_iommu.c15
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_iommu.h3
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue.c3
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue.h3
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_migrate.c55
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_module.c3
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.c67
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.h44
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_cik.c126
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v10.c155
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v9.c175
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_vi.c151
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_packet_manager.c11
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_packet_manager_v9.c52
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_packet_manager_vi.c29
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_pasid.c3
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_pm4_headers.h3
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_pm4_headers_ai.h3
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_pm4_headers_aldebaran.h3
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_pm4_headers_diq.h3
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_pm4_headers_vi.h7
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_pm4_opcodes.h3
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_priv.h197
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_process.c95
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c375
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_queue.c3
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_smi_events.c77
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_smi_events.h3
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_svm.c467
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_svm.h39
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_topology.c9
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_topology.h3
-rw-r--r--drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c215
-rw-r--r--drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h15
-rw-r--r--drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c136
-rw-r--r--drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.c4
-rw-r--r--drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c203
-rw-r--r--drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c293
-rw-r--r--drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.h14
-rw-r--r--drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_pp_smu.c248
-rw-r--r--drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_psr.c64
-rw-r--r--drivers/gpu/drm/amd/display/dc/Makefile8
-rw-r--r--drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c2
-rw-r--r--drivers/gpu/drm/amd/display/dc/bios/command_table.c6
-rw-r--r--drivers/gpu/drm/amd/display/dc/bios/command_table2.c4
-rw-r--r--drivers/gpu/drm/amd/display/dc/bios/command_table_helper2.c2
-rw-r--r--drivers/gpu/drm/amd/display/dc/clk_mgr/Makefile19
-rw-r--r--drivers/gpu/drm/amd/display/dc/clk_mgr/clk_mgr.c37
-rw-r--r--drivers/gpu/drm/amd/display/dc/clk_mgr/dce100/dce_clk_mgr.c2
-rw-r--r--drivers/gpu/drm/amd/display/dc/clk_mgr/dcn10/rv1_clk_mgr_vbios_smu.c3
-rw-r--r--drivers/gpu/drm/amd/display/dc/clk_mgr/dcn30/dcn30_clk_mgr.c20
-rw-r--r--drivers/gpu/drm/amd/display/dc/clk_mgr/dcn30/dcn30_clk_mgr_smu_msg.c9
-rw-r--r--drivers/gpu/drm/amd/display/dc/clk_mgr/dcn30/dcn30_clk_mgr_smu_msg.h67
-rw-r--r--drivers/gpu/drm/amd/display/dc/clk_mgr/dcn30/dcn30_smu11_driver_if.h74
-rw-r--r--drivers/gpu/drm/amd/display/dc/clk_mgr/dcn301/vg_clk_mgr.c16
-rw-r--r--drivers/gpu/drm/amd/display/dc/clk_mgr/dcn31/dcn31_clk_mgr.c28
-rw-r--r--drivers/gpu/drm/amd/display/dc/clk_mgr/dcn31/dcn31_smu.c27
-rw-r--r--drivers/gpu/drm/amd/display/dc/clk_mgr/dcn31/dcn31_smu.h2
-rw-r--r--drivers/gpu/drm/amd/display/dc/clk_mgr/dcn315/dcn315_clk_mgr.c620
-rw-r--r--drivers/gpu/drm/amd/display/dc/clk_mgr/dcn315/dcn315_clk_mgr.h (renamed from drivers/gpu/drm/amd/amdgpu/amdgpu_hdp.c)61
-rw-r--r--drivers/gpu/drm/amd/display/dc/clk_mgr/dcn315/dcn315_smu.c338
-rw-r--r--drivers/gpu/drm/amd/display/dc/clk_mgr/dcn315/dcn315_smu.h128
-rw-r--r--drivers/gpu/drm/amd/display/dc/clk_mgr/dcn316/dcn316_clk_mgr.c717
-rw-r--r--drivers/gpu/drm/amd/display/dc/clk_mgr/dcn316/dcn316_clk_mgr.h49
-rw-r--r--drivers/gpu/drm/amd/display/dc/clk_mgr/dcn316/dcn316_smu.c338
-rw-r--r--drivers/gpu/drm/amd/display/dc/clk_mgr/dcn316/dcn316_smu.h139
-rw-r--r--drivers/gpu/drm/amd/display/dc/core/dc.c146
-rw-r--r--drivers/gpu/drm/amd/display/dc/core/dc_link.c917
-rw-r--r--drivers/gpu/drm/amd/display/dc/core/dc_link_ddc.c5
-rw-r--r--drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c1737
-rw-r--r--drivers/gpu/drm/amd/display/dc/core/dc_link_dpcd.c2
-rw-r--r--drivers/gpu/drm/amd/display/dc/core/dc_link_enc_cfg.c31
-rw-r--r--drivers/gpu/drm/amd/display/dc/core/dc_link_hwss.c917
-rw-r--r--drivers/gpu/drm/amd/display/dc/core/dc_resource.c169
-rw-r--r--drivers/gpu/drm/amd/display/dc/core/dc_stream.c37
-rw-r--r--drivers/gpu/drm/amd/display/dc/dc.h50
-rw-r--r--drivers/gpu/drm/amd/display/dc/dc_dp_types.h88
-rw-r--r--drivers/gpu/drm/amd/display/dc/dc_helper.c60
-rw-r--r--drivers/gpu/drm/amd/display/dc/dc_hw_types.h1
-rw-r--r--drivers/gpu/drm/amd/display/dc/dc_link.h62
-rw-r--r--drivers/gpu/drm/amd/display/dc/dc_stream.h8
-rw-r--r--drivers/gpu/drm/amd/display/dc/dc_types.h7
-rw-r--r--drivers/gpu/drm/amd/display/dc/dce/dce_aux.c5
-rw-r--r--drivers/gpu/drm/amd/display/dc/dce/dce_clk_mgr.c2
-rw-r--r--drivers/gpu/drm/amd/display/dc/dce/dce_clock_source.c117
-rw-r--r--drivers/gpu/drm/amd/display/dc/dce/dce_clock_source.h9
-rw-r--r--drivers/gpu/drm/amd/display/dc/dce/dce_i2c.c26
-rw-r--r--drivers/gpu/drm/amd/display/dc/dce/dce_i2c.h6
-rw-r--r--drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c17
-rw-r--r--drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.h3
-rw-r--r--drivers/gpu/drm/amd/display/dc/dce/dmub_outbox.c25
-rw-r--r--drivers/gpu/drm/amd/display/dc/dce/dmub_outbox.h4
-rw-r--r--drivers/gpu/drm/amd/display/dc/dce/dmub_psr.c5
-rw-r--r--drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c193
-rw-r--r--drivers/gpu/drm/amd/display/dc/dce112/dce112_resource.c2
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.c1
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.c15
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.h4
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c27
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn10/dcn10_link_encoder.c18
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn10/dcn10_link_encoder.h3
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c77
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.h4
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn10/dcn10_stream_encoder.c15
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn10/dcn10_stream_encoder.h3
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn20/Makefile25
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dccg.h15
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hubp.c21
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c63
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c1376
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.h31
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn20/dcn20_stream_encoder.c2
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn201/dcn201_init.c1
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn21/Makefile25
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c564
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.h11
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dio_stream_encoder.c2
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dpp_cm.c2
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hubbub.c1
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c7
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c15
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn301/dcn301_hubbub.c1
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn301/dcn301_resource.c17
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn302/Makefile12
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn302/dcn302_resource.c320
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn302/dcn302_resource.h3
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn303/Makefile26
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn303/dcn303_resource.c331
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn303/dcn303_resource.h3
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dccg.c106
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dccg.h6
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dio_link_encoder.c9
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hpo_dp_stream_encoder.c11
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hpo_dp_stream_encoder.h9
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hubbub.c121
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hwseq.c28
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn31/dcn31_optc.c2
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn31/dcn31_optc.h2
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn31/dcn31_panel_cntl.c5
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.c20
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.h5
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn315/Makefile (renamed from drivers/gpu/drm/amd/display/dc/calcs/Makefile)36
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn315/dcn315_resource.c2284
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn315/dcn315_resource.h42
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn316/Makefile56
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn316/dcn316_resource.c2285
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn316/dcn316_resource.h42
-rw-r--r--drivers/gpu/drm/amd/display/dc/dm_helpers.h9
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml/Makefile16
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml/calcs/bw_fixed.c (renamed from drivers/gpu/drm/amd/display/dc/calcs/bw_fixed.c)0
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml/calcs/calcs_logger.h (renamed from drivers/gpu/drm/amd/display/dc/calcs/calcs_logger.h)0
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml/calcs/custom_float.c (renamed from drivers/gpu/drm/amd/display/dc/calcs/custom_float.c)0
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml/calcs/dce_calcs.c (renamed from drivers/gpu/drm/amd/display/dc/calcs/dce_calcs.c)52
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml/calcs/dcn_calc_auto.c (renamed from drivers/gpu/drm/amd/display/dc/calcs/dcn_calc_auto.c)0
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml/calcs/dcn_calc_auto.h (renamed from drivers/gpu/drm/amd/display/dc/calcs/dcn_calc_auto.h)0
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml/calcs/dcn_calc_math.c (renamed from drivers/gpu/drm/amd/display/dc/calcs/dcn_calc_math.c)0
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml/calcs/dcn_calcs.c (renamed from drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c)1
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml/dcn10/dcn10_fpu.c123
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml/dcn10/dcn10_fpu.h30
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml/dcn20/dcn20_fpu.c1926
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml/dcn20/dcn20_fpu.h51
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20.c2
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20v2.c2
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml/dcn21/display_rq_dlg_calc_21.c2
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml/dcn30/display_rq_dlg_calc_30.c2
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml/dcn301/dcn301_fpu.c2
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml/dcn301/dcn301_fpu.h2
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml/dcn302/dcn302_fpu.c357
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml/dcn302/dcn302_fpu.h32
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml/dcn303/dcn303_fpu.c362
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml/dcn303/dcn303_fpu.h32
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml/dcn31/display_mode_vba_31.c29
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml/display_mode_structs.h2
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.c24
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.h3
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml/display_rq_dlg_helpers.c3
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml/dml1_display_rq_dlg_calc.c4
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml/dsc/rc_calc_fpu.c2
-rw-r--r--drivers/gpu/drm/amd/display/dc/dsc/dc_dsc.c2
-rw-r--r--drivers/gpu/drm/amd/display/dc/gpio/Makefile8
-rw-r--r--drivers/gpu/drm/amd/display/dc/gpio/dcn30/hw_factory_dcn30.c4
-rw-r--r--drivers/gpu/drm/amd/display/dc/gpio/dcn30/hw_translate_dcn30.c4
-rw-r--r--drivers/gpu/drm/amd/display/dc/gpio/dcn315/hw_factory_dcn315.c260
-rw-r--r--drivers/gpu/drm/amd/display/dc/gpio/dcn315/hw_factory_dcn315.h31
-rw-r--r--drivers/gpu/drm/amd/display/dc/gpio/dcn315/hw_translate_dcn315.c374
-rw-r--r--drivers/gpu/drm/amd/display/dc/gpio/dcn315/hw_translate_dcn315.h33
-rw-r--r--drivers/gpu/drm/amd/display/dc/gpio/gpio_service.c6
-rw-r--r--drivers/gpu/drm/amd/display/dc/gpio/hw_factory.c5
-rw-r--r--drivers/gpu/drm/amd/display/dc/gpio/hw_translate.c5
-rw-r--r--drivers/gpu/drm/amd/display/dc/inc/core_types.h14
-rw-r--r--drivers/gpu/drm/amd/display/dc/inc/dc_link_dp.h56
-rw-r--r--drivers/gpu/drm/amd/display/dc/inc/hw/dccg.h4
-rw-r--r--drivers/gpu/drm/amd/display/dc/inc/hw/dchubbub.h2
-rw-r--r--drivers/gpu/drm/amd/display/dc/inc/hw/hubp.h1
-rw-r--r--drivers/gpu/drm/amd/display/dc/inc/hw/hw_shared.h2
-rw-r--r--drivers/gpu/drm/amd/display/dc/inc/hw/link_encoder.h5
-rw-r--r--drivers/gpu/drm/amd/display/dc/inc/hw/panel_cntl.h1
-rw-r--r--drivers/gpu/drm/amd/display/dc/inc/hw/stream_encoder.h10
-rw-r--r--drivers/gpu/drm/amd/display/dc/inc/hw/timing_generator.h2
-rw-r--r--drivers/gpu/drm/amd/display/dc/inc/hw_sequencer_private.h3
-rw-r--r--drivers/gpu/drm/amd/display/dc/inc/link_dpcd.h2
-rw-r--r--drivers/gpu/drm/amd/display/dc/inc/link_enc_cfg.h8
-rw-r--r--drivers/gpu/drm/amd/display/dc/inc/link_hwss.h86
-rw-r--r--drivers/gpu/drm/amd/display/dc/inc/reg_helper.h34
-rw-r--r--drivers/gpu/drm/amd/display/dc/inc/resource.h27
-rw-r--r--drivers/gpu/drm/amd/display/dc/irq/Makefile8
-rw-r--r--drivers/gpu/drm/amd/display/dc/irq/dcn20/irq_service_dcn20.c2
-rw-r--r--drivers/gpu/drm/amd/display/dc/irq/dcn201/irq_service_dcn201.c5
-rw-r--r--drivers/gpu/drm/amd/display/dc/irq/dcn21/irq_service_dcn21.c14
-rw-r--r--drivers/gpu/drm/amd/display/dc/irq/dcn30/irq_service_dcn30.c6
-rw-r--r--drivers/gpu/drm/amd/display/dc/irq/dcn315/irq_service_dcn315.c438
-rw-r--r--drivers/gpu/drm/amd/display/dc/irq/dcn315/irq_service_dcn315.h34
-rw-r--r--drivers/gpu/drm/amd/display/dc/link/Makefile30
-rw-r--r--drivers/gpu/drm/amd/display/dc/link/link_dp_trace.c146
-rw-r--r--drivers/gpu/drm/amd/display/dc/link/link_dp_trace.h57
-rw-r--r--drivers/gpu/drm/amd/display/dc/link/link_hwss_dio.c137
-rw-r--r--drivers/gpu/drm/amd/display/dc/link/link_hwss_dio.h53
-rw-r--r--drivers/gpu/drm/amd/display/dc/link/link_hwss_dpia.c51
-rw-r--r--drivers/gpu/drm/amd/display/dc/link/link_hwss_dpia.h34
-rw-r--r--drivers/gpu/drm/amd/display/dc/link/link_hwss_hpo_dp.c254
-rw-r--r--drivers/gpu/drm/amd/display/dc/link/link_hwss_hpo_dp.h35
-rw-r--r--drivers/gpu/drm/amd/display/dc/link/link_hwss_hpo_frl.c43
-rw-r--r--drivers/gpu/drm/amd/display/dc/link/link_hwss_hpo_frl.h34
-rw-r--r--drivers/gpu/drm/amd/display/dc/os_types.h2
-rw-r--r--drivers/gpu/drm/amd/display/dc/virtual/Makefile2
-rw-r--r--drivers/gpu/drm/amd/display/dc/virtual/virtual_link_encoder.c3
-rw-r--r--drivers/gpu/drm/amd/display/dc/virtual/virtual_link_hwss.c43
-rw-r--r--drivers/gpu/drm/amd/display/dc/virtual/virtual_link_hwss.h34
-rw-r--r--drivers/gpu/drm/amd/display/dmub/dmub_srv.h2
-rw-r--r--drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h153
-rw-r--r--drivers/gpu/drm/amd/display/dmub/src/Makefile2
-rw-r--r--drivers/gpu/drm/amd/display/dmub/src/dmub_dcn31.c2
-rw-r--r--drivers/gpu/drm/amd/display/dmub/src/dmub_dcn315.c62
-rw-r--r--drivers/gpu/drm/amd/display/dmub/src/dmub_dcn315.h68
-rw-r--r--drivers/gpu/drm/amd/display/dmub/src/dmub_dcn316.c62
-rw-r--r--drivers/gpu/drm/amd/display/dmub/src/dmub_dcn316.h33
-rw-r--r--drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c11
-rw-r--r--drivers/gpu/drm/amd/display/include/bios_parser_types.h2
-rw-r--r--drivers/gpu/drm/amd/display/include/dal_asic_id.h13
-rw-r--r--drivers/gpu/drm/amd/display/include/dal_types.h2
-rw-r--r--drivers/gpu/drm/amd/display/include/ddc_service_types.h7
-rw-r--r--drivers/gpu/drm/amd/display/include/dpcd_defs.h6
-rw-r--r--drivers/gpu/drm/amd/display/include/grph_object_ctrl_defs.h22
-rw-r--r--drivers/gpu/drm/amd/display/include/grph_object_defs.h2
-rw-r--r--drivers/gpu/drm/amd/display/include/grph_object_id.h2
-rw-r--r--drivers/gpu/drm/amd/display/include/link_service_types.h12
-rw-r--r--drivers/gpu/drm/amd/display/modules/hdcp/hdcp.h2
-rw-r--r--drivers/gpu/drm/amd/display/modules/inc/mod_info_packet.h3
-rw-r--r--drivers/gpu/drm/amd/display/modules/info_packet/info_packet.c25
-rw-r--r--drivers/gpu/drm/amd/include/amd_shared.h3
-rw-r--r--drivers/gpu/drm/amd/include/asic_reg/dcn/dcn_3_1_5_offset.h15191
-rw-r--r--drivers/gpu/drm/amd/include/asic_reg/dcn/dcn_3_1_5_sh_mask.h62061
-rw-r--r--drivers/gpu/drm/amd/include/asic_reg/dcn/dcn_3_1_6_offset.h15682
-rw-r--r--drivers/gpu/drm/amd/include/asic_reg/dcn/dcn_3_1_6_sh_mask.h62717
-rw-r--r--drivers/gpu/drm/amd/include/asic_reg/dpcs/dpcs_3_0_0_offset.h (renamed from drivers/gpu/drm/amd/include/asic_reg/dcn/dpcs_3_0_0_offset.h)7
-rw-r--r--drivers/gpu/drm/amd/include/asic_reg/dpcs/dpcs_3_0_0_sh_mask.h (renamed from drivers/gpu/drm/amd/include/asic_reg/dcn/dpcs_3_0_0_sh_mask.h)7
-rw-r--r--drivers/gpu/drm/amd/include/asic_reg/dpcs/dpcs_3_0_3_offset.h (renamed from drivers/gpu/drm/amd/include/asic_reg/dcn/dpcs_3_0_3_offset.h)0
-rw-r--r--drivers/gpu/drm/amd/include/asic_reg/dpcs/dpcs_3_0_3_sh_mask.h (renamed from drivers/gpu/drm/amd/include/asic_reg/dcn/dpcs_3_0_3_sh_mask.h)0
-rw-r--r--drivers/gpu/drm/amd/include/asic_reg/dpcs/dpcs_4_2_2_offset.h11957
-rw-r--r--drivers/gpu/drm/amd/include/asic_reg/dpcs/dpcs_4_2_2_sh_mask.h103633
-rw-r--r--drivers/gpu/drm/amd/include/asic_reg/dpcs/dpcs_4_2_3_offset.h11969
-rw-r--r--drivers/gpu/drm/amd/include/asic_reg/dpcs/dpcs_4_2_3_sh_mask.h136141
-rw-r--r--drivers/gpu/drm/amd/include/asic_reg/hdp/hdp_4_0_sh_mask.h2
-rw-r--r--drivers/gpu/drm/amd/include/asic_reg/mp/mp_13_0_5_offset.h455
-rw-r--r--drivers/gpu/drm/amd/include/asic_reg/mp/mp_13_0_5_sh_mask.h672
-rw-r--r--drivers/gpu/drm/amd/include/asic_reg/mp/mp_13_0_8_offset.h410
-rw-r--r--drivers/gpu/drm/amd/include/asic_reg/mp/mp_13_0_8_sh_mask.h603
-rw-r--r--drivers/gpu/drm/amd/include/asic_reg/umc/umc_6_7_0_offset.h6
-rw-r--r--drivers/gpu/drm/amd/include/kgd_kfd_interface.h9
-rw-r--r--drivers/gpu/drm/amd/include/kgd_pp_interface.h13
-rw-r--r--drivers/gpu/drm/amd/pm/Makefile13
-rw-r--r--drivers/gpu/drm/amd/pm/amdgpu_dpm.c2515
-rw-r--r--drivers/gpu/drm/amd/pm/amdgpu_dpm_internal.c95
-rw-r--r--drivers/gpu/drm/amd/pm/amdgpu_pm.c622
-rw-r--r--drivers/gpu/drm/amd/pm/inc/amdgpu_dpm.h374
-rw-r--r--drivers/gpu/drm/amd/pm/inc/amdgpu_dpm_internal.h32
-rw-r--r--drivers/gpu/drm/amd/pm/legacy-dpm/Makefile32
-rw-r--r--drivers/gpu/drm/amd/pm/legacy-dpm/cik_dpm.h (renamed from drivers/gpu/drm/amd/pm/powerplay/cik_dpm.h)0
-rw-r--r--drivers/gpu/drm/amd/pm/legacy-dpm/kv_dpm.c (renamed from drivers/gpu/drm/amd/pm/powerplay/kv_dpm.c)37
-rw-r--r--drivers/gpu/drm/amd/pm/legacy-dpm/kv_dpm.h (renamed from drivers/gpu/drm/amd/pm/powerplay/kv_dpm.h)0
-rw-r--r--drivers/gpu/drm/amd/pm/legacy-dpm/kv_smc.c (renamed from drivers/gpu/drm/amd/pm/powerplay/kv_smc.c)0
-rw-r--r--drivers/gpu/drm/amd/pm/legacy-dpm/legacy_dpm.c1081
-rw-r--r--drivers/gpu/drm/amd/pm/legacy-dpm/legacy_dpm.h38
-rw-r--r--drivers/gpu/drm/amd/pm/legacy-dpm/ppsmc.h (renamed from drivers/gpu/drm/amd/pm/powerplay/ppsmc.h)0
-rw-r--r--drivers/gpu/drm/amd/pm/legacy-dpm/r600_dpm.h (renamed from drivers/gpu/drm/amd/pm/powerplay/r600_dpm.h)0
-rw-r--r--drivers/gpu/drm/amd/pm/legacy-dpm/si_dpm.c (renamed from drivers/gpu/drm/amd/pm/powerplay/si_dpm.c)188
-rw-r--r--drivers/gpu/drm/amd/pm/legacy-dpm/si_dpm.h (renamed from drivers/gpu/drm/amd/pm/powerplay/si_dpm.h)15
-rw-r--r--drivers/gpu/drm/amd/pm/legacy-dpm/si_smc.c (renamed from drivers/gpu/drm/amd/pm/powerplay/si_smc.c)0
-rw-r--r--drivers/gpu/drm/amd/pm/legacy-dpm/sislands_smc.h (renamed from drivers/gpu/drm/amd/pm/powerplay/sislands_smc.h)0
-rw-r--r--drivers/gpu/drm/amd/pm/powerplay/Makefile4
-rw-r--r--drivers/gpu/drm/amd/pm/powerplay/amd_powerplay.c400
-rw-r--r--drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c8
-rw-r--r--drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu8_hwmgr.c10
-rw-r--r--drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_hwmgr.c68
-rw-r--r--drivers/gpu/drm/amd/pm/powerplay/inc/amd_powerplay.h (renamed from drivers/gpu/drm/amd/pm/inc/amd_powerplay.h)0
-rw-r--r--drivers/gpu/drm/amd/pm/powerplay/inc/cz_ppsmc.h (renamed from drivers/gpu/drm/amd/pm/inc/cz_ppsmc.h)0
-rw-r--r--drivers/gpu/drm/amd/pm/powerplay/inc/fiji_ppsmc.h (renamed from drivers/gpu/drm/amd/pm/inc/fiji_ppsmc.h)0
-rw-r--r--drivers/gpu/drm/amd/pm/powerplay/inc/hardwaremanager.h (renamed from drivers/gpu/drm/amd/pm/inc/hardwaremanager.h)0
-rw-r--r--drivers/gpu/drm/amd/pm/powerplay/inc/hwmgr.h (renamed from drivers/gpu/drm/amd/pm/inc/hwmgr.h)4
-rw-r--r--drivers/gpu/drm/amd/pm/powerplay/inc/polaris10_pwrvirus.h (renamed from drivers/gpu/drm/amd/pm/inc/polaris10_pwrvirus.h)0
-rw-r--r--drivers/gpu/drm/amd/pm/powerplay/inc/power_state.h (renamed from drivers/gpu/drm/amd/pm/inc/power_state.h)0
-rw-r--r--drivers/gpu/drm/amd/pm/powerplay/inc/pp_debug.h (renamed from drivers/gpu/drm/amd/pm/inc/pp_debug.h)0
-rw-r--r--drivers/gpu/drm/amd/pm/powerplay/inc/pp_endian.h (renamed from drivers/gpu/drm/amd/pm/inc/pp_endian.h)0
-rw-r--r--drivers/gpu/drm/amd/pm/powerplay/inc/pp_thermal.h (renamed from drivers/gpu/drm/amd/pm/inc/pp_thermal.h)0
-rw-r--r--drivers/gpu/drm/amd/pm/powerplay/inc/ppinterrupt.h (renamed from drivers/gpu/drm/amd/pm/inc/ppinterrupt.h)0
-rw-r--r--drivers/gpu/drm/amd/pm/powerplay/inc/rv_ppsmc.h (renamed from drivers/gpu/drm/amd/pm/inc/rv_ppsmc.h)0
-rw-r--r--drivers/gpu/drm/amd/pm/powerplay/inc/smu10.h (renamed from drivers/gpu/drm/amd/pm/inc/smu10.h)0
-rw-r--r--drivers/gpu/drm/amd/pm/powerplay/inc/smu10_driver_if.h (renamed from drivers/gpu/drm/amd/pm/inc/smu10_driver_if.h)0
-rw-r--r--drivers/gpu/drm/amd/pm/powerplay/inc/smu11_driver_if.h (renamed from drivers/gpu/drm/amd/pm/inc/smu11_driver_if.h)0
-rw-r--r--drivers/gpu/drm/amd/pm/powerplay/inc/smu7.h (renamed from drivers/gpu/drm/amd/pm/inc/smu7.h)0
-rw-r--r--drivers/gpu/drm/amd/pm/powerplay/inc/smu71.h (renamed from drivers/gpu/drm/amd/pm/inc/smu71.h)0
-rw-r--r--drivers/gpu/drm/amd/pm/powerplay/inc/smu71_discrete.h (renamed from drivers/gpu/drm/amd/pm/inc/smu71_discrete.h)0
-rw-r--r--drivers/gpu/drm/amd/pm/powerplay/inc/smu72.h (renamed from drivers/gpu/drm/amd/pm/inc/smu72.h)0
-rw-r--r--drivers/gpu/drm/amd/pm/powerplay/inc/smu72_discrete.h (renamed from drivers/gpu/drm/amd/pm/inc/smu72_discrete.h)0
-rw-r--r--drivers/gpu/drm/amd/pm/powerplay/inc/smu73.h (renamed from drivers/gpu/drm/amd/pm/inc/smu73.h)0
-rw-r--r--drivers/gpu/drm/amd/pm/powerplay/inc/smu73_discrete.h (renamed from drivers/gpu/drm/amd/pm/inc/smu73_discrete.h)0
-rw-r--r--drivers/gpu/drm/amd/pm/powerplay/inc/smu74.h (renamed from drivers/gpu/drm/amd/pm/inc/smu74.h)0
-rw-r--r--drivers/gpu/drm/amd/pm/powerplay/inc/smu74_discrete.h (renamed from drivers/gpu/drm/amd/pm/inc/smu74_discrete.h)0
-rw-r--r--drivers/gpu/drm/amd/pm/powerplay/inc/smu75.h (renamed from drivers/gpu/drm/amd/pm/inc/smu75.h)0
-rw-r--r--drivers/gpu/drm/amd/pm/powerplay/inc/smu75_discrete.h (renamed from drivers/gpu/drm/amd/pm/inc/smu75_discrete.h)0
-rw-r--r--drivers/gpu/drm/amd/pm/powerplay/inc/smu7_common.h (renamed from drivers/gpu/drm/amd/pm/inc/smu7_common.h)0
-rw-r--r--drivers/gpu/drm/amd/pm/powerplay/inc/smu7_discrete.h (renamed from drivers/gpu/drm/amd/pm/inc/smu7_discrete.h)0
-rw-r--r--drivers/gpu/drm/amd/pm/powerplay/inc/smu7_fusion.h (renamed from drivers/gpu/drm/amd/pm/inc/smu7_fusion.h)0
-rw-r--r--drivers/gpu/drm/amd/pm/powerplay/inc/smu7_ppsmc.h (renamed from drivers/gpu/drm/amd/pm/inc/smu7_ppsmc.h)0
-rw-r--r--drivers/gpu/drm/amd/pm/powerplay/inc/smu8.h (renamed from drivers/gpu/drm/amd/pm/inc/smu8.h)0
-rw-r--r--drivers/gpu/drm/amd/pm/powerplay/inc/smu8_fusion.h (renamed from drivers/gpu/drm/amd/pm/inc/smu8_fusion.h)0
-rw-r--r--drivers/gpu/drm/amd/pm/powerplay/inc/smu9.h (renamed from drivers/gpu/drm/amd/pm/inc/smu9.h)0
-rw-r--r--drivers/gpu/drm/amd/pm/powerplay/inc/smu9_driver_if.h (renamed from drivers/gpu/drm/amd/pm/inc/smu9_driver_if.h)0
-rw-r--r--drivers/gpu/drm/amd/pm/powerplay/inc/smu_ucode_xfer_cz.h (renamed from drivers/gpu/drm/amd/pm/inc/smu_ucode_xfer_cz.h)2
-rw-r--r--drivers/gpu/drm/amd/pm/powerplay/inc/smu_ucode_xfer_vi.h (renamed from drivers/gpu/drm/amd/pm/inc/smu_ucode_xfer_vi.h)0
-rw-r--r--drivers/gpu/drm/amd/pm/powerplay/inc/smumgr.h (renamed from drivers/gpu/drm/amd/pm/inc/smumgr.h)0
-rw-r--r--drivers/gpu/drm/amd/pm/powerplay/inc/tonga_ppsmc.h (renamed from drivers/gpu/drm/amd/pm/inc/tonga_ppsmc.h)0
-rw-r--r--drivers/gpu/drm/amd/pm/powerplay/inc/vega10_ppsmc.h (renamed from drivers/gpu/drm/amd/pm/inc/vega10_ppsmc.h)0
-rw-r--r--drivers/gpu/drm/amd/pm/powerplay/inc/vega12/smu9_driver_if.h (renamed from drivers/gpu/drm/amd/pm/inc/vega12/smu9_driver_if.h)0
-rw-r--r--drivers/gpu/drm/amd/pm/powerplay/inc/vega12_ppsmc.h (renamed from drivers/gpu/drm/amd/pm/inc/vega12_ppsmc.h)0
-rw-r--r--drivers/gpu/drm/amd/pm/powerplay/inc/vega20_ppsmc.h (renamed from drivers/gpu/drm/amd/pm/inc/vega20_ppsmc.h)0
-rw-r--r--drivers/gpu/drm/amd/pm/powerplay/smumgr/ci_smumgr.c4
-rw-r--r--drivers/gpu/drm/amd/pm/powerplay/smumgr/smu10_smumgr.c4
-rw-r--r--drivers/gpu/drm/amd/pm/powerplay/smumgr/smu7_smumgr.c11
-rw-r--r--drivers/gpu/drm/amd/pm/powerplay/smumgr/smu9_smumgr.c2
-rw-r--r--drivers/gpu/drm/amd/pm/powerplay/smumgr/vega20_smumgr.c8
-rw-r--r--drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c691
-rw-r--r--drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h (renamed from drivers/gpu/drm/amd/pm/inc/amdgpu_smu.h)66
-rw-r--r--drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/aldebaran_ppsmc.h (renamed from drivers/gpu/drm/amd/pm/inc/aldebaran_ppsmc.h)3
-rw-r--r--drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/arcturus_ppsmc.h (renamed from drivers/gpu/drm/amd/pm/inc/arcturus_ppsmc.h)0
-rw-r--r--drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu11_driver_if_arcturus.h (renamed from drivers/gpu/drm/amd/pm/inc/smu11_driver_if_arcturus.h)0
-rw-r--r--drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu11_driver_if_cyan_skillfish.h (renamed from drivers/gpu/drm/amd/pm/inc/smu11_driver_if_cyan_skillfish.h)0
-rw-r--r--drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu11_driver_if_navi10.h (renamed from drivers/gpu/drm/amd/pm/inc/smu11_driver_if_navi10.h)0
-rw-r--r--drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu11_driver_if_sienna_cichlid.h (renamed from drivers/gpu/drm/amd/pm/inc/smu11_driver_if_sienna_cichlid.h)82
-rw-r--r--drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu11_driver_if_vangogh.h (renamed from drivers/gpu/drm/amd/pm/inc/smu11_driver_if_vangogh.h)0
-rw-r--r--drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu12_driver_if.h (renamed from drivers/gpu/drm/amd/pm/inc/smu12_driver_if.h)0
-rw-r--r--drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu13_driver_if_aldebaran.h (renamed from drivers/gpu/drm/amd/pm/inc/smu13_driver_if_aldebaran.h)0
-rw-r--r--drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu13_driver_if_v13_0_5.h140
-rw-r--r--drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu13_driver_if_yellow_carp.h (renamed from drivers/gpu/drm/amd/pm/inc/smu13_driver_if_yellow_carp.h)0
-rw-r--r--drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu_v11_0_7_ppsmc.h (renamed from drivers/gpu/drm/amd/pm/inc/smu_v11_0_7_ppsmc.h)0
-rw-r--r--drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu_v11_0_ppsmc.h (renamed from drivers/gpu/drm/amd/pm/inc/smu_v11_0_ppsmc.h)0
-rw-r--r--drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu_v11_5_pmfw.h (renamed from drivers/gpu/drm/amd/pm/inc/smu_v11_5_pmfw.h)0
-rw-r--r--drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu_v11_5_ppsmc.h (renamed from drivers/gpu/drm/amd/pm/inc/smu_v11_5_ppsmc.h)0
-rw-r--r--drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu_v11_8_pmfw.h (renamed from drivers/gpu/drm/amd/pm/inc/smu_v11_8_pmfw.h)0
-rw-r--r--drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu_v11_8_ppsmc.h (renamed from drivers/gpu/drm/amd/pm/inc/smu_v11_8_ppsmc.h)0
-rw-r--r--drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu_v12_0_ppsmc.h (renamed from drivers/gpu/drm/amd/pm/inc/smu_v12_0_ppsmc.h)0
-rw-r--r--drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu_v13_0_1_pmfw.h (renamed from drivers/gpu/drm/amd/pm/inc/smu_v13_0_1_pmfw.h)0
-rw-r--r--drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu_v13_0_1_ppsmc.h (renamed from drivers/gpu/drm/amd/pm/inc/smu_v13_0_1_ppsmc.h)0
-rw-r--r--drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu_v13_0_5_pmfw.h126
-rw-r--r--drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu_v13_0_5_ppsmc.h74
-rw-r--r--drivers/gpu/drm/amd/pm/swsmu/inc/smu_11_0_cdr_table.h (renamed from drivers/gpu/drm/amd/pm/inc/smu_11_0_cdr_table.h)0
-rw-r--r--drivers/gpu/drm/amd/pm/swsmu/inc/smu_types.h (renamed from drivers/gpu/drm/amd/pm/inc/smu_types.h)6
-rw-r--r--drivers/gpu/drm/amd/pm/swsmu/inc/smu_v11_0.h (renamed from drivers/gpu/drm/amd/pm/inc/smu_v11_0.h)0
-rw-r--r--drivers/gpu/drm/amd/pm/swsmu/inc/smu_v11_0_7_pptable.h (renamed from drivers/gpu/drm/amd/pm/inc/smu_v11_0_7_pptable.h)0
-rw-r--r--drivers/gpu/drm/amd/pm/swsmu/inc/smu_v11_0_pptable.h (renamed from drivers/gpu/drm/amd/pm/inc/smu_v11_0_pptable.h)0
-rw-r--r--drivers/gpu/drm/amd/pm/swsmu/inc/smu_v12_0.h (renamed from drivers/gpu/drm/amd/pm/inc/smu_v12_0.h)0
-rw-r--r--drivers/gpu/drm/amd/pm/swsmu/inc/smu_v13_0.h (renamed from drivers/gpu/drm/amd/pm/inc/smu_v13_0.h)1
-rw-r--r--drivers/gpu/drm/amd/pm/swsmu/inc/smu_v13_0_pptable.h (renamed from drivers/gpu/drm/amd/pm/inc/smu_v13_0_pptable.h)0
-rw-r--r--drivers/gpu/drm/amd/pm/swsmu/smu11/arcturus_ppt.c102
-rw-r--r--drivers/gpu/drm/amd/pm/swsmu/smu11/cyan_skillfish_ppt.c80
-rw-r--r--drivers/gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c476
-rw-r--r--drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c539
-rw-r--r--drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.h8
-rw-r--r--drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c70
-rw-r--r--drivers/gpu/drm/amd/pm/swsmu/smu11/vangogh_ppt.c79
-rw-r--r--drivers/gpu/drm/amd/pm/swsmu/smu12/renoir_ppt.c28
-rw-r--r--drivers/gpu/drm/amd/pm/swsmu/smu12/smu_v12_0.c10
-rw-r--r--drivers/gpu/drm/amd/pm/swsmu/smu13/Makefile2
-rw-r--r--drivers/gpu/drm/amd/pm/swsmu/smu13/aldebaran_ppt.c133
-rw-r--r--drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c81
-rw-r--r--drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_5_ppt.c1057
-rw-r--r--drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_5_ppt.h29
-rw-r--r--drivers/gpu/drm/amd/pm/swsmu/smu13/yellow_carp_ppt.c47
-rw-r--r--drivers/gpu/drm/amd/pm/swsmu/smu_cmn.c264
-rw-r--r--drivers/gpu/drm/amd/pm/swsmu/smu_cmn.h16
-rw-r--r--drivers/gpu/drm/amd/pm/swsmu/smu_internal.h10
-rw-r--r--drivers/gpu/drm/arm/Kconfig1
-rw-r--r--drivers/gpu/drm/arm/display/komeda/d71/d71_component.c12
-rw-r--r--drivers/gpu/drm/arm/display/komeda/komeda_drv.c3
-rw-r--r--drivers/gpu/drm/arm/hdlcd_drv.c3
-rw-r--r--drivers/gpu/drm/arm/malidp_drv.c3
-rw-r--r--drivers/gpu/drm/armada/armada_drv.c3
-rw-r--r--drivers/gpu/drm/aspeed/aspeed_gfx.h1
-rw-r--r--drivers/gpu/drm/aspeed/aspeed_gfx_drv.c18
-rw-r--r--drivers/gpu/drm/ast/ast_dp501.c58
-rw-r--r--drivers/gpu/drm/ast/ast_drv.c18
-rw-r--r--drivers/gpu/drm/ast/ast_drv.h39
-rw-r--r--drivers/gpu/drm/ast/ast_main.c2
-rw-r--r--drivers/gpu/drm/ast/ast_mode.c426
-rw-r--r--drivers/gpu/drm/ast/ast_tables.h2
-rw-r--r--drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c3
-rw-r--r--drivers/gpu/drm/bridge/Kconfig14
-rw-r--r--drivers/gpu/drm/bridge/Makefile1
-rw-r--r--drivers/gpu/drm/bridge/adv7511/adv7511.h1
-rw-r--r--drivers/gpu/drm/bridge/adv7511/adv7511_drv.c31
-rw-r--r--drivers/gpu/drm/bridge/adv7511/adv7533.c2
-rw-r--r--drivers/gpu/drm/bridge/analogix/Kconfig4
-rw-r--r--drivers/gpu/drm/bridge/analogix/analogix-anx6345.c2
-rw-r--r--drivers/gpu/drm/bridge/analogix/analogix-anx78xx.c2
-rw-r--r--drivers/gpu/drm/bridge/analogix/analogix-i2c-dptx.c2
-rw-r--r--drivers/gpu/drm/bridge/analogix/analogix_dp_core.c4
-rw-r--r--drivers/gpu/drm/bridge/analogix/analogix_dp_core.h2
-rw-r--r--drivers/gpu/drm/bridge/analogix/anx7625.c577
-rw-r--r--drivers/gpu/drm/bridge/analogix/anx7625.h79
-rw-r--r--drivers/gpu/drm/bridge/cadence/Kconfig1
-rw-r--r--drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c20
-rw-r--r--drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.h2
-rw-r--r--drivers/gpu/drm/bridge/cdns-dsi.c1
-rw-r--r--drivers/gpu/drm/bridge/chipone-icn6211.c46
-rw-r--r--drivers/gpu/drm/bridge/ite-it6505.c3352
-rw-r--r--drivers/gpu/drm/bridge/ite-it66121.c3
-rw-r--r--drivers/gpu/drm/bridge/lontium-lt9611.c10
-rw-r--r--drivers/gpu/drm/bridge/lontium-lt9611uxc.c4
-rw-r--r--drivers/gpu/drm/bridge/nwl-dsi.c52
-rw-r--r--drivers/gpu/drm/bridge/panel.c12
-rw-r--r--drivers/gpu/drm/bridge/parade-ps8640.c33
-rw-r--r--drivers/gpu/drm/bridge/sii902x.c129
-rw-r--r--drivers/gpu/drm/bridge/sil-sii8620.c2
-rw-r--r--drivers/gpu/drm/bridge/synopsys/dw-hdmi.c21
-rw-r--r--drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c25
-rw-r--r--drivers/gpu/drm/bridge/tc358767.c2
-rw-r--r--drivers/gpu/drm/bridge/tc358775.c4
-rw-r--r--drivers/gpu/drm/bridge/ti-sn65dsi83.c53
-rw-r--r--drivers/gpu/drm/bridge/ti-sn65dsi86.c81
-rw-r--r--drivers/gpu/drm/dp/Makefile9
-rw-r--r--drivers/gpu/drm/dp/drm_dp.c (renamed from drivers/gpu/drm/drm_dp_helper.c)94
-rw-r--r--drivers/gpu/drm/dp/drm_dp_aux_bus.c (renamed from drivers/gpu/drm/drm_dp_aux_bus.c)4
-rw-r--r--drivers/gpu/drm/dp/drm_dp_aux_dev.c (renamed from drivers/gpu/drm/drm_dp_aux_dev.c)6
-rw-r--r--drivers/gpu/drm/dp/drm_dp_cec.c (renamed from drivers/gpu/drm/drm_dp_cec.c)2
-rw-r--r--drivers/gpu/drm/dp/drm_dp_dual_mode_helper.c (renamed from drivers/gpu/drm/drm_dp_dual_mode_helper.c)2
-rw-r--r--drivers/gpu/drm/dp/drm_dp_helper_internal.h33
-rw-r--r--drivers/gpu/drm/dp/drm_dp_helper_mod.c22
-rw-r--r--drivers/gpu/drm/dp/drm_dp_mst_topology.c (renamed from drivers/gpu/drm/drm_dp_mst_topology.c)8
-rw-r--r--drivers/gpu/drm/dp/drm_dp_mst_topology_internal.h (renamed from drivers/gpu/drm/drm_dp_mst_topology_internal.h)2
-rw-r--r--drivers/gpu/drm/drm_atomic.c12
-rw-r--r--drivers/gpu/drm/drm_atomic_state_helper.c25
-rw-r--r--drivers/gpu/drm/drm_atomic_uapi.c14
-rw-r--r--drivers/gpu/drm/drm_bridge_connector.c15
-rw-r--r--drivers/gpu/drm/drm_buddy.c785
-rw-r--r--drivers/gpu/drm/drm_cache.c29
-rw-r--r--drivers/gpu/drm/drm_client.c9
-rw-r--r--drivers/gpu/drm/drm_client_modeset.c3
-rw-r--r--drivers/gpu/drm/drm_color_mgmt.c4
-rw-r--r--drivers/gpu/drm/drm_connector.c3
-rw-r--r--drivers/gpu/drm/drm_crtc_helper_internal.h27
-rw-r--r--drivers/gpu/drm/drm_debugfs.c3
-rw-r--r--drivers/gpu/drm/drm_dsc.c2
-rw-r--r--drivers/gpu/drm/drm_edid.c109
-rw-r--r--drivers/gpu/drm/drm_fb_helper.c90
-rw-r--r--drivers/gpu/drm/drm_format_helper.c141
-rw-r--r--drivers/gpu/drm/drm_framebuffer.c6
-rw-r--r--drivers/gpu/drm/drm_gem.c33
-rw-r--r--drivers/gpu/drm/drm_gem_cma_helper.c10
-rw-r--r--drivers/gpu/drm/drm_gem_framebuffer_helper.c16
-rw-r--r--drivers/gpu/drm/drm_gem_shmem_helper.c22
-rw-r--r--drivers/gpu/drm/drm_gem_ttm_helper.c4
-rw-r--r--drivers/gpu/drm/drm_gem_vram_helper.c25
-rw-r--r--drivers/gpu/drm/drm_internal.h6
-rw-r--r--drivers/gpu/drm/drm_ioctl.c2
-rw-r--r--drivers/gpu/drm/drm_kms_helper_common.c14
-rw-r--r--drivers/gpu/drm/drm_mipi_dbi.c8
-rw-r--r--drivers/gpu/drm/drm_mode_object.c53
-rw-r--r--drivers/gpu/drm/drm_modes.c53
-rw-r--r--drivers/gpu/drm/drm_of.c17
-rw-r--r--drivers/gpu/drm/drm_panel_orientation_quirks.c18
-rw-r--r--drivers/gpu/drm/drm_plane.c32
-rw-r--r--drivers/gpu/drm/drm_prime.c4
-rw-r--r--drivers/gpu/drm/drm_privacy_screen.c8
-rw-r--r--drivers/gpu/drm/drm_privacy_screen_x86.c20
-rw-r--r--drivers/gpu/drm/drm_syncobj.c61
-rw-r--r--drivers/gpu/drm/etnaviv/etnaviv_drv.h2
-rw-r--r--drivers/gpu/drm/etnaviv/etnaviv_gem_prime.c8
-rw-r--r--drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c7
-rw-r--r--drivers/gpu/drm/etnaviv/etnaviv_sched.c2
-rw-r--r--drivers/gpu/drm/exynos/Kconfig1
-rw-r--r--drivers/gpu/drm/exynos/exynos7_drm_decon.c12
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_drv.c3
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_dsi.c19
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_fimc.c13
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_fimd.c55
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_gsc.c10
-rw-r--r--drivers/gpu/drm/exynos/exynos_mixer.c14
-rw-r--r--drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c3
-rw-r--r--drivers/gpu/drm/gma500/cdv_intel_dp.c14
-rw-r--r--drivers/gpu/drm/gma500/gma_display.c6
-rw-r--r--drivers/gpu/drm/gma500/intel_bios.c2
-rw-r--r--drivers/gpu/drm/gma500/mmu.c8
-rw-r--r--drivers/gpu/drm/gma500/psb_drv.c3
-rw-r--r--drivers/gpu/drm/gud/gud_pipe.c4
-rw-r--r--drivers/gpu/drm/hisilicon/hibmc/Kconfig2
-rw-r--r--drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c3
-rw-r--r--drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.c3
-rw-r--r--drivers/gpu/drm/hyperv/hyperv_drm_drv.c3
-rw-r--r--drivers/gpu/drm/hyperv/hyperv_drm_modeset.c5
-rw-r--r--drivers/gpu/drm/i915/Kconfig4
-rw-r--r--drivers/gpu/drm/i915/Kconfig.unstable8
-rw-r--r--drivers/gpu/drm/i915/Makefile8
-rw-r--r--drivers/gpu/drm/i915/display/g4x_dp.c18
-rw-r--r--drivers/gpu/drm/i915/display/g4x_hdmi.h2
-rw-r--r--drivers/gpu/drm/i915/display/hsw_ips.c271
-rw-r--r--drivers/gpu/drm/i915/display/hsw_ips.h26
-rw-r--r--drivers/gpu/drm/i915/display/i9xx_plane.c105
-rw-r--r--drivers/gpu/drm/i915/display/icl_dsi.c21
-rw-r--r--drivers/gpu/drm/i915/display/icl_dsi_regs.h342
-rw-r--r--drivers/gpu/drm/i915/display/intel_atomic.c14
-rw-r--r--drivers/gpu/drm/i915/display/intel_atomic.h2
-rw-r--r--drivers/gpu/drm/i915/display/intel_atomic_plane.c226
-rw-r--r--drivers/gpu/drm/i915/display/intel_atomic_plane.h15
-rw-r--r--drivers/gpu/drm/i915/display/intel_backlight.c3
-rw-r--r--drivers/gpu/drm/i915/display/intel_bios.c223
-rw-r--r--drivers/gpu/drm/i915/display/intel_bw.c181
-rw-r--r--drivers/gpu/drm/i915/display/intel_bw.h8
-rw-r--r--drivers/gpu/drm/i915/display/intel_cdclk.c67
-rw-r--r--drivers/gpu/drm/i915/display/intel_cdclk.h9
-rw-r--r--drivers/gpu/drm/i915/display/intel_color.c119
-rw-r--r--drivers/gpu/drm/i915/display/intel_combo_phy.c1
-rw-r--r--drivers/gpu/drm/i915/display/intel_combo_phy_regs.h162
-rw-r--r--drivers/gpu/drm/i915/display/intel_crt.h2
-rw-r--r--drivers/gpu/drm/i915/display/intel_crtc.c5
-rw-r--r--drivers/gpu/drm/i915/display/intel_cursor.c25
-rw-r--r--drivers/gpu/drm/i915/display/intel_ddi.c176
-rw-r--r--drivers/gpu/drm/i915/display/intel_ddi.h2
-rw-r--r--drivers/gpu/drm/i915/display/intel_ddi_buf_trans.c44
-rw-r--r--drivers/gpu/drm/i915/display/intel_de.h1
-rw-r--r--drivers/gpu/drm/i915/display/intel_display.c1578
-rw-r--r--drivers/gpu/drm/i915/display/intel_display.h47
-rw-r--r--drivers/gpu/drm/i915/display/intel_display_debugfs.c46
-rw-r--r--drivers/gpu/drm/i915/display/intel_display_power.c46
-rw-r--r--drivers/gpu/drm/i915/display/intel_display_power.h2
-rw-r--r--drivers/gpu/drm/i915/display/intel_display_trace.h1
-rw-r--r--drivers/gpu/drm/i915/display/intel_display_types.h55
-rw-r--r--drivers/gpu/drm/i915/display/intel_dmc.c14
-rw-r--r--drivers/gpu/drm/i915/display/intel_dmc.h2
-rw-r--r--drivers/gpu/drm/i915/display/intel_dp.c246
-rw-r--r--drivers/gpu/drm/i915/display/intel_dp.h2
-rw-r--r--drivers/gpu/drm/i915/display/intel_dp_aux.c8
-rw-r--r--drivers/gpu/drm/i915/display/intel_dp_aux.h4
-rw-r--r--drivers/gpu/drm/i915/display/intel_dp_hdcp.c4
-rw-r--r--drivers/gpu/drm/i915/display/intel_dp_link_training.c307
-rw-r--r--drivers/gpu/drm/i915/display/intel_dp_link_training.h6
-rw-r--r--drivers/gpu/drm/i915/display/intel_dp_mst.c35
-rw-r--r--drivers/gpu/drm/i915/display/intel_dpll.c12
-rw-r--r--drivers/gpu/drm/i915/display/intel_dpll.h1
-rw-r--r--drivers/gpu/drm/i915/display/intel_dpll_mgr.c80
-rw-r--r--drivers/gpu/drm/i915/display/intel_dpll_mgr.h49
-rw-r--r--drivers/gpu/drm/i915/display/intel_dpt.c37
-rw-r--r--drivers/gpu/drm/i915/display/intel_drrs.c115
-rw-r--r--drivers/gpu/drm/i915/display/intel_dsb.c2
-rw-r--r--drivers/gpu/drm/i915/display/intel_dsb.h2
-rw-r--r--drivers/gpu/drm/i915/display/intel_dsi.h4
-rw-r--r--drivers/gpu/drm/i915/display/intel_dsi_vbt.c40
-rw-r--r--drivers/gpu/drm/i915/display/intel_dvo_dev.h2
-rw-r--r--drivers/gpu/drm/i915/display/intel_fb_pin.c9
-rw-r--r--drivers/gpu/drm/i915/display/intel_fbc.c243
-rw-r--r--drivers/gpu/drm/i915/display/intel_fbc.h7
-rw-r--r--drivers/gpu/drm/i915/display/intel_fbdev.c29
-rw-r--r--drivers/gpu/drm/i915/display/intel_fbdev.h7
-rw-r--r--drivers/gpu/drm/i915/display/intel_fdi.c5
-rw-r--r--drivers/gpu/drm/i915/display/intel_gmbus.c23
-rw-r--r--drivers/gpu/drm/i915/display/intel_gmbus.h1
-rw-r--r--drivers/gpu/drm/i915/display/intel_hdcp.c3
-rw-r--r--drivers/gpu/drm/i915/display/intel_hdmi.c145
-rw-r--r--drivers/gpu/drm/i915/display/intel_hdmi.h7
-rw-r--r--drivers/gpu/drm/i915/display/intel_hotplug.c21
-rw-r--r--drivers/gpu/drm/i915/display/intel_lspcon.c148
-rw-r--r--drivers/gpu/drm/i915/display/intel_lvds.h2
-rw-r--r--drivers/gpu/drm/i915/display/intel_opregion.c134
-rw-r--r--drivers/gpu/drm/i915/display/intel_opregion.h10
-rw-r--r--drivers/gpu/drm/i915/display/intel_overlay.c5
-rw-r--r--drivers/gpu/drm/i915/display/intel_pch_display.c88
-rw-r--r--drivers/gpu/drm/i915/display/intel_pch_display.h8
-rw-r--r--drivers/gpu/drm/i915/display/intel_plane_initial.c14
-rw-r--r--drivers/gpu/drm/i915/display/intel_pps.c28
-rw-r--r--drivers/gpu/drm/i915/display/intel_pps.h2
-rw-r--r--drivers/gpu/drm/i915/display/intel_psr.c137
-rw-r--r--drivers/gpu/drm/i915/display/intel_sdvo.h2
-rw-r--r--drivers/gpu/drm/i915/display/intel_snps_phy.c238
-rw-r--r--drivers/gpu/drm/i915/display/intel_snps_phy_regs.h75
-rw-r--r--drivers/gpu/drm/i915/display/intel_sprite.c65
-rw-r--r--drivers/gpu/drm/i915/display/intel_tc.c31
-rw-r--r--drivers/gpu/drm/i915/display/intel_tc_phy_regs.h280
-rw-r--r--drivers/gpu/drm/i915/display/intel_vbt_defs.h34
-rw-r--r--drivers/gpu/drm/i915/display/intel_vdsc.c54
-rw-r--r--drivers/gpu/drm/i915/display/intel_vdsc.h1
-rw-r--r--drivers/gpu/drm/i915/display/intel_vga.c9
-rw-r--r--drivers/gpu/drm/i915/display/skl_universal_plane.c195
-rw-r--r--drivers/gpu/drm/i915/display/vlv_dsi.c34
-rw-r--r--drivers/gpu/drm/i915/display/vlv_dsi_pll.c1
-rw-r--r--drivers/gpu/drm/i915/display/vlv_dsi_pll_regs.h109
-rw-r--r--drivers/gpu/drm/i915/display/vlv_dsi_regs.h480
-rw-r--r--drivers/gpu/drm/i915/gem/i915_gem_clflush.c2
-rw-r--r--drivers/gpu/drm/i915/gem/i915_gem_context.c37
-rw-r--r--drivers/gpu/drm/i915/gem/i915_gem_context.h2
-rw-r--r--drivers/gpu/drm/i915/gem/i915_gem_create.c3
-rw-r--r--drivers/gpu/drm/i915/gem/i915_gem_create.h17
-rw-r--r--drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c9
-rw-r--r--drivers/gpu/drm/i915/gem/i915_gem_dmabuf.h18
-rw-r--r--drivers/gpu/drm/i915/gem/i915_gem_domain.c5
-rw-r--r--drivers/gpu/drm/i915/gem/i915_gem_domain.h15
-rw-r--r--drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c251
-rw-r--r--drivers/gpu/drm/i915/gem/i915_gem_internal.c1
-rw-r--r--drivers/gpu/drm/i915/gem/i915_gem_internal.h23
-rw-r--r--drivers/gpu/drm/i915/gem/i915_gem_mman.c41
-rw-r--r--drivers/gpu/drm/i915/gem/i915_gem_object.c25
-rw-r--r--drivers/gpu/drm/i915/gem/i915_gem_object.h4
-rw-r--r--drivers/gpu/drm/i915/gem/i915_gem_object_types.h67
-rw-r--r--drivers/gpu/drm/i915/gem/i915_gem_pages.c25
-rw-r--r--drivers/gpu/drm/i915/gem/i915_gem_pm.c3
-rw-r--r--drivers/gpu/drm/i915/gem/i915_gem_region.c16
-rw-r--r--drivers/gpu/drm/i915/gem/i915_gem_shmem.c22
-rw-r--r--drivers/gpu/drm/i915/gem/i915_gem_shrinker.c30
-rw-r--r--drivers/gpu/drm/i915/gem/i915_gem_stolen.c27
-rw-r--r--drivers/gpu/drm/i915/gem/i915_gem_throttle.c1
-rw-r--r--drivers/gpu/drm/i915/gem/i915_gem_tiling.c17
-rw-r--r--drivers/gpu/drm/i915/gem/i915_gem_tiling.h18
-rw-r--r--drivers/gpu/drm/i915/gem/i915_gem_ttm.c144
-rw-r--r--drivers/gpu/drm/i915/gem/i915_gem_ttm_move.c27
-rw-r--r--drivers/gpu/drm/i915/gem/i915_gem_userptr.c1
-rw-r--r--drivers/gpu/drm/i915/gem/i915_gem_userptr.h14
-rw-r--r--drivers/gpu/drm/i915/gem/selftests/huge_pages.c106
-rw-r--r--drivers/gpu/drm/i915/gem/selftests/i915_gem_client_blt.c28
-rw-r--r--drivers/gpu/drm/i915/gem/selftests/i915_gem_context.c12
-rw-r--r--drivers/gpu/drm/i915/gem/selftests/i915_gem_dmabuf.c6
-rw-r--r--drivers/gpu/drm/i915/gem/selftests/i915_gem_migrate.c192
-rw-r--r--drivers/gpu/drm/i915/gem/selftests/i915_gem_mman.c362
-rw-r--r--drivers/gpu/drm/i915/gem/selftests/i915_gem_object.c2
-rw-r--r--drivers/gpu/drm/i915/gem/selftests/igt_gem_utils.c1
-rw-r--r--drivers/gpu/drm/i915/gem/selftests/mock_context.c1
-rw-r--r--drivers/gpu/drm/i915/gem/selftests/mock_dmabuf.c6
-rw-r--r--drivers/gpu/drm/i915/gt/gen2_engine_cs.c2
-rw-r--r--drivers/gpu/drm/i915/gt/gen6_engine_cs.c1
-rw-r--r--drivers/gpu/drm/i915/gt/gen6_ppgtt.c23
-rw-r--r--drivers/gpu/drm/i915/gt/gen7_renderclear.c1
-rw-r--r--drivers/gpu/drm/i915/gt/gen8_engine_cs.c37
-rw-r--r--drivers/gpu/drm/i915/gt/gen8_ppgtt.c193
-rw-r--r--drivers/gpu/drm/i915/gt/intel_context.c4
-rw-r--r--drivers/gpu/drm/i915/gt/intel_context_sseu.c1
-rw-r--r--drivers/gpu/drm/i915/gt/intel_engine.h5
-rw-r--r--drivers/gpu/drm/i915/gt/intel_engine_cs.c182
-rw-r--r--drivers/gpu/drm/i915/gt/intel_engine_regs.h246
-rw-r--r--drivers/gpu/drm/i915/gt/intel_engine_types.h11
-rw-r--r--drivers/gpu/drm/i915/gt/intel_engine_user.c5
-rw-r--r--drivers/gpu/drm/i915/gt/intel_execlists_submission.c53
-rw-r--r--drivers/gpu/drm/i915/gt/intel_ggtt.c134
-rw-r--r--drivers/gpu/drm/i915/gt/intel_ggtt_fencing.c10
-rw-r--r--drivers/gpu/drm/i915/gt/intel_gpu_commands.h15
-rw-r--r--drivers/gpu/drm/i915/gt/intel_gt.c151
-rw-r--r--drivers/gpu/drm/i915/gt/intel_gt.h5
-rw-r--r--drivers/gpu/drm/i915/gt/intel_gt_buffer_pool.c1
-rw-r--r--drivers/gpu/drm/i915/gt/intel_gt_clock_utils.c2
-rw-r--r--drivers/gpu/drm/i915/gt/intel_gt_irq.c17
-rw-r--r--drivers/gpu/drm/i915/gt/intel_gt_pm_debugfs.c11
-rw-r--r--drivers/gpu/drm/i915/gt/intel_gt_pm_irq.c1
-rw-r--r--drivers/gpu/drm/i915/gt/intel_gt_regs.h1506
-rw-r--r--drivers/gpu/drm/i915/gt/intel_gt_types.h2
-rw-r--r--drivers/gpu/drm/i915/gt/intel_gtt.c36
-rw-r--r--drivers/gpu/drm/i915/gt/intel_gtt.h54
-rw-r--r--drivers/gpu/drm/i915/gt/intel_llc.c11
-rw-r--r--drivers/gpu/drm/i915/gt/intel_lrc.c59
-rw-r--r--drivers/gpu/drm/i915/gt/intel_lrc.h63
-rw-r--r--drivers/gpu/drm/i915/gt/intel_lrc_reg.h15
-rw-r--r--drivers/gpu/drm/i915/gt/intel_migrate.c196
-rw-r--r--drivers/gpu/drm/i915/gt/intel_mocs.c2
-rw-r--r--drivers/gpu/drm/i915/gt/intel_ppgtt.c39
-rw-r--r--drivers/gpu/drm/i915/gt/intel_rc6.c16
-rw-r--r--drivers/gpu/drm/i915/gt/intel_rc6.h2
-rw-r--r--drivers/gpu/drm/i915/gt/intel_region_lmem.c142
-rw-r--r--drivers/gpu/drm/i915/gt/intel_region_lmem.h3
-rw-r--r--drivers/gpu/drm/i915/gt/intel_renderstate.c2
-rw-r--r--drivers/gpu/drm/i915/gt/intel_reset.c29
-rw-r--r--drivers/gpu/drm/i915/gt/intel_ring.c2
-rw-r--r--drivers/gpu/drm/i915/gt/intel_ring_submission.c16
-rw-r--r--drivers/gpu/drm/i915/gt/intel_rps.c13
-rw-r--r--drivers/gpu/drm/i915/gt/intel_sseu.c20
-rw-r--r--drivers/gpu/drm/i915/gt/intel_sseu.h4
-rw-r--r--drivers/gpu/drm/i915/gt/intel_sseu_debugfs.c1
-rw-r--r--drivers/gpu/drm/i915/gt/intel_timeline.c5
-rw-r--r--drivers/gpu/drm/i915/gt/intel_workarounds.c179
-rw-r--r--drivers/gpu/drm/i915/gt/intel_workarounds_types.h2
-rw-r--r--drivers/gpu/drm/i915/gt/selftest_engine_pm.c1
-rw-r--r--drivers/gpu/drm/i915/gt/selftest_execlists.c1
-rw-r--r--drivers/gpu/drm/i915/gt/selftest_gt_pm.c1
-rw-r--r--drivers/gpu/drm/i915/gt/selftest_hangcheck.c4
-rw-r--r--drivers/gpu/drm/i915/gt/selftest_llc.c5
-rw-r--r--drivers/gpu/drm/i915/gt/selftest_lrc.c2
-rw-r--r--drivers/gpu/drm/i915/gt/selftest_migrate.c2
-rw-r--r--drivers/gpu/drm/i915/gt/selftest_reset.c2
-rw-r--r--drivers/gpu/drm/i915/gt/selftest_rps.c8
-rw-r--r--drivers/gpu/drm/i915/gt/selftest_timeline.c1
-rw-r--r--drivers/gpu/drm/i915/gt/selftest_workarounds.c1
-rw-r--r--drivers/gpu/drm/i915/gt/shmem_utils.c32
-rw-r--r--drivers/gpu/drm/i915/gt/shmem_utils.h3
-rw-r--r--drivers/gpu/drm/i915/gt/uc/abi/guc_actions_abi.h80
-rw-r--r--drivers/gpu/drm/i915/gt/uc/abi/guc_actions_slpc_abi.h1
-rw-r--r--drivers/gpu/drm/i915/gt/uc/abi/guc_errors_abi.h23
-rw-r--r--drivers/gpu/drm/i915/gt/uc/abi/guc_klvs_abi.h82
-rw-r--r--drivers/gpu/drm/i915/gt/uc/intel_guc.c128
-rw-r--r--drivers/gpu/drm/i915/gt/uc/intel_guc.h32
-rw-r--r--drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c426
-rw-r--r--drivers/gpu/drm/i915/gt/uc/intel_guc_ads.h3
-rw-r--r--drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c143
-rw-r--r--drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c39
-rw-r--r--drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h69
-rw-r--r--drivers/gpu/drm/i915/gt/uc/intel_guc_log.c32
-rw-r--r--drivers/gpu/drm/i915/gt/uc/intel_guc_log.h3
-rw-r--r--drivers/gpu/drm/i915/gt/uc/intel_guc_reg.h9
-rw-r--r--drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c12
-rw-r--r--drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c303
-rw-r--r--drivers/gpu/drm/i915/gt/uc/intel_huc.c1
-rw-r--r--drivers/gpu/drm/i915/gt/uc/intel_huc.h2
-rw-r--r--drivers/gpu/drm/i915/gt/uc/intel_uc.c31
-rw-r--r--drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c46
-rw-r--r--drivers/gpu/drm/i915/gt/uc/intel_uc_fw.h2
-rw-r--r--drivers/gpu/drm/i915/gt/uc/selftest_guc.c2
-rw-r--r--drivers/gpu/drm/i915/gt/uc/selftest_guc_multi_lrc.c4
-rw-r--r--drivers/gpu/drm/i915/gvt/aperture_gm.c3
-rw-r--r--drivers/gpu/drm/i915/gvt/cmd_parser.c4
-rw-r--r--drivers/gpu/drm/i915/gvt/display.c17
-rw-r--r--drivers/gpu/drm/i915/gvt/dmabuf.c26
-rw-r--r--drivers/gpu/drm/i915/gvt/edid.c1
-rw-r--r--drivers/gpu/drm/i915/gvt/execlist.c2
-rw-r--r--drivers/gpu/drm/i915/gvt/fb_decoder.c49
-rw-r--r--drivers/gpu/drm/i915/gvt/gtt.c74
-rw-r--r--drivers/gpu/drm/i915/gvt/gtt.h4
-rw-r--r--drivers/gpu/drm/i915/gvt/gvt.h2
-rw-r--r--drivers/gpu/drm/i915/gvt/handlers.c38
-rw-r--r--drivers/gpu/drm/i915/gvt/interrupt.c11
-rw-r--r--drivers/gpu/drm/i915/gvt/interrupt.h4
-rw-r--r--drivers/gpu/drm/i915/gvt/kvmgt.c17
-rw-r--r--drivers/gpu/drm/i915/gvt/mmio.c3
-rw-r--r--drivers/gpu/drm/i915/gvt/mmio_context.c6
-rw-r--r--drivers/gpu/drm/i915/gvt/mmio_context.h2
-rw-r--r--drivers/gpu/drm/i915/gvt/reg.h1
-rw-r--r--drivers/gpu/drm/i915/gvt/sched_policy.c2
-rw-r--r--drivers/gpu/drm/i915/gvt/scheduler.c2
-rw-r--r--drivers/gpu/drm/i915/gvt/scheduler.h2
-rw-r--r--drivers/gpu/drm/i915/gvt/vgpu.c4
-rw-r--r--drivers/gpu/drm/i915/i915_buddy.c466
-rw-r--r--drivers/gpu/drm/i915/i915_buddy.h143
-rw-r--r--drivers/gpu/drm/i915/i915_cmd_parser.c78
-rw-r--r--drivers/gpu/drm/i915/i915_cmd_parser.h26
-rw-r--r--drivers/gpu/drm/i915/i915_debugfs.c20
-rw-r--r--drivers/gpu/drm/i915/i915_driver.c46
-rw-r--r--drivers/gpu/drm/i915/i915_driver.h5
-rw-r--r--drivers/gpu/drm/i915/i915_drv.h446
-rw-r--r--drivers/gpu/drm/i915/i915_file_private.h108
-rw-r--r--drivers/gpu/drm/i915/i915_gem.c45
-rw-r--r--drivers/gpu/drm/i915/i915_gem_evict.c102
-rw-r--r--drivers/gpu/drm/i915/i915_gem_evict.h28
-rw-r--r--drivers/gpu/drm/i915/i915_gem_gtt.c17
-rw-r--r--drivers/gpu/drm/i915/i915_gem_gtt.h4
-rw-r--r--drivers/gpu/drm/i915/i915_getparam.c4
-rw-r--r--drivers/gpu/drm/i915/i915_getparam.h15
-rw-r--r--drivers/gpu/drm/i915/i915_gpu_error.c93
-rw-r--r--drivers/gpu/drm/i915/i915_gpu_error.h11
-rw-r--r--drivers/gpu/drm/i915/i915_ioc32.c1
-rw-r--r--drivers/gpu/drm/i915/i915_ioctl.c94
-rw-r--r--drivers/gpu/drm/i915/i915_ioctl.h14
-rw-r--r--drivers/gpu/drm/i915/i915_irq.c25
-rw-r--r--drivers/gpu/drm/i915/i915_irq.h1
-rw-r--r--drivers/gpu/drm/i915/i915_mitigations.c1
-rw-r--r--drivers/gpu/drm/i915/i915_mm.h4
-rw-r--r--drivers/gpu/drm/i915/i915_module.c7
-rw-r--r--drivers/gpu/drm/i915/i915_params.c5
-rw-r--r--drivers/gpu/drm/i915/i915_params.h1
-rw-r--r--drivers/gpu/drm/i915/i915_pci.c29
-rw-r--r--drivers/gpu/drm/i915/i915_perf.c152
-rw-r--r--drivers/gpu/drm/i915/i915_perf_oa_regs.h137
-rw-r--r--drivers/gpu/drm/i915/i915_perf_types.h2
-rw-r--r--drivers/gpu/drm/i915/i915_pmu.c2
-rw-r--r--drivers/gpu/drm/i915/i915_reg.h5295
-rw-r--r--drivers/gpu/drm/i915/i915_reg_defs.h128
-rw-r--r--drivers/gpu/drm/i915/i915_request.c14
-rw-r--r--drivers/gpu/drm/i915/i915_request.h6
-rw-r--r--drivers/gpu/drm/i915/i915_scatterlist.c11
-rw-r--r--drivers/gpu/drm/i915/i915_suspend.c1
-rw-r--r--drivers/gpu/drm/i915/i915_sysfs.c1
-rw-r--r--drivers/gpu/drm/i915/i915_ttm_buddy_manager.c186
-rw-r--r--drivers/gpu/drm/i915/i915_ttm_buddy_manager.h19
-rw-r--r--drivers/gpu/drm/i915/i915_utils.h15
-rw-r--r--drivers/gpu/drm/i915/i915_vgpu.c2
-rw-r--r--drivers/gpu/drm/i915/i915_vma.c657
-rw-r--r--drivers/gpu/drm/i915/i915_vma.h37
-rw-r--r--drivers/gpu/drm/i915/i915_vma_resource.c418
-rw-r--r--drivers/gpu/drm/i915/i915_vma_resource.h234
-rw-r--r--drivers/gpu/drm/i915/i915_vma_snapshot.c134
-rw-r--r--drivers/gpu/drm/i915/i915_vma_snapshot.h112
-rw-r--r--drivers/gpu/drm/i915/i915_vma_types.h19
-rw-r--r--drivers/gpu/drm/i915/intel_device_info.c39
-rw-r--r--drivers/gpu/drm/i915/intel_device_info.h14
-rw-r--r--drivers/gpu/drm/i915/intel_dram.c8
-rw-r--r--drivers/gpu/drm/i915/intel_mchbar_regs.h228
-rw-r--r--drivers/gpu/drm/i915/intel_memory_region.c10
-rw-r--r--drivers/gpu/drm/i915/intel_memory_region.h7
-rw-r--r--drivers/gpu/drm/i915/intel_pch.c3
-rw-r--r--drivers/gpu/drm/i915/intel_pch.h3
-rw-r--r--drivers/gpu/drm/i915/intel_pci_config.h85
-rw-r--r--drivers/gpu/drm/i915/intel_pcode.c32
-rw-r--r--drivers/gpu/drm/i915/intel_pcode.h12
-rw-r--r--drivers/gpu/drm/i915/intel_pm.c884
-rw-r--r--drivers/gpu/drm/i915/intel_pm.h2
-rw-r--r--drivers/gpu/drm/i915/intel_region_ttm.c21
-rw-r--r--drivers/gpu/drm/i915/intel_runtime_pm.c6
-rw-r--r--drivers/gpu/drm/i915/intel_runtime_pm.h1
-rw-r--r--drivers/gpu/drm/i915/intel_sbi.c1
-rw-r--r--drivers/gpu/drm/i915/intel_step.c17
-rw-r--r--drivers/gpu/drm/i915/intel_uncore.c101
-rw-r--r--drivers/gpu/drm/i915/intel_uncore.h4
-rw-r--r--drivers/gpu/drm/i915/intel_wopcm.c42
-rw-r--r--drivers/gpu/drm/i915/pxp/intel_pxp_irq.c1
-rw-r--r--drivers/gpu/drm/i915/pxp/intel_pxp_pm.h2
-rw-r--r--drivers/gpu/drm/i915/selftests/i915_buddy.c787
-rw-r--r--drivers/gpu/drm/i915/selftests/i915_gem.c11
-rw-r--r--drivers/gpu/drm/i915/selftests/i915_gem_evict.c29
-rw-r--r--drivers/gpu/drm/i915/selftests/i915_gem_gtt.c430
-rw-r--r--drivers/gpu/drm/i915/selftests/i915_mock_selftests.h1
-rw-r--r--drivers/gpu/drm/i915/selftests/i915_request.c120
-rw-r--r--drivers/gpu/drm/i915/selftests/i915_selftest.c1
-rw-r--r--drivers/gpu/drm/i915/selftests/i915_vma.c31
-rw-r--r--drivers/gpu/drm/i915/selftests/igt_flush_test.c2
-rw-r--r--drivers/gpu/drm/i915/selftests/igt_spinner.c1
-rw-r--r--drivers/gpu/drm/i915/selftests/intel_memory_region.c172
-rw-r--r--drivers/gpu/drm/i915/selftests/mock_gem_device.c13
-rw-r--r--drivers/gpu/drm/i915/selftests/mock_gtt.c21
-rw-r--r--drivers/gpu/drm/i915/selftests/mock_gtt.h3
-rw-r--r--drivers/gpu/drm/i915/selftests/mock_region.c13
-rw-r--r--drivers/gpu/drm/i915/selftests/mock_region.h3
-rw-r--r--drivers/gpu/drm/i915/vlv_sideband.c1
-rw-r--r--drivers/gpu/drm/i915/vlv_sideband.h2
-rw-r--r--drivers/gpu/drm/i915/vlv_sideband_reg.h180
-rw-r--r--drivers/gpu/drm/i915/vlv_suspend.c2
-rw-r--r--drivers/gpu/drm/imx/dcss/Kconfig1
-rw-r--r--drivers/gpu/drm/imx/dcss/dcss-drv.c3
-rw-r--r--drivers/gpu/drm/imx/imx-drm-core.c3
-rw-r--r--drivers/gpu/drm/imx/parallel-display.c8
-rw-r--r--drivers/gpu/drm/ingenic/ingenic-drm-drv.c75
-rw-r--r--drivers/gpu/drm/ingenic/ingenic-drm.h38
-rw-r--r--drivers/gpu/drm/kmb/kmb_drv.c3
-rw-r--r--drivers/gpu/drm/kmb/kmb_plane.c6
-rw-r--r--drivers/gpu/drm/lib/drm_random.c3
-rw-r--r--drivers/gpu/drm/lib/drm_random.h2
-rw-r--r--drivers/gpu/drm/lima/lima_gem.c4
-rw-r--r--drivers/gpu/drm/lima/lima_sched.c9
-rw-r--r--drivers/gpu/drm/mcde/mcde_drv.c3
-rw-r--r--drivers/gpu/drm/mediatek/mtk_disp_ovl.c8
-rw-r--r--drivers/gpu/drm/mediatek/mtk_disp_rdma.c9
-rw-r--r--drivers/gpu/drm/mediatek/mtk_drm_crtc.c27
-rw-r--r--drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c36
-rw-r--r--drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h1
-rw-r--r--drivers/gpu/drm/mediatek/mtk_drm_drv.c8
-rw-r--r--drivers/gpu/drm/mediatek/mtk_drm_gem.c7
-rw-r--r--drivers/gpu/drm/mediatek/mtk_drm_gem.h5
-rw-r--r--drivers/gpu/drm/mediatek/mtk_dsi.c200
-rw-r--r--drivers/gpu/drm/meson/meson_drv.c28
-rw-r--r--drivers/gpu/drm/meson/meson_osd_afbcd.c41
-rw-r--r--drivers/gpu/drm/meson/meson_osd_afbcd.h1
-rw-r--r--drivers/gpu/drm/mgag200/mgag200_drv.c20
-rw-r--r--drivers/gpu/drm/mgag200/mgag200_mode.c9
-rw-r--r--drivers/gpu/drm/mgag200/mgag200_pll.c6
-rw-r--r--drivers/gpu/drm/msm/Kconfig10
-rw-r--r--drivers/gpu/drm/msm/Makefile3
-rw-r--r--drivers/gpu/drm/msm/adreno/a2xx.xml.h26
-rw-r--r--drivers/gpu/drm/msm/adreno/a2xx_gpu.c1
-rw-r--r--drivers/gpu/drm/msm/adreno/a3xx.xml.h30
-rw-r--r--drivers/gpu/drm/msm/adreno/a3xx_gpu.c1
-rw-r--r--drivers/gpu/drm/msm/adreno/a4xx.xml.h112
-rw-r--r--drivers/gpu/drm/msm/adreno/a4xx_gpu.c1
-rw-r--r--drivers/gpu/drm/msm/adreno/a5xx.xml.h63
-rw-r--r--drivers/gpu/drm/msm/adreno/a5xx_gpu.c1
-rw-r--r--drivers/gpu/drm/msm/adreno/a6xx.xml.h674
-rw-r--r--drivers/gpu/drm/msm/adreno/a6xx_gmu.xml.h26
-rw-r--r--drivers/gpu/drm/msm/adreno/a6xx_gpu.c64
-rw-r--r--drivers/gpu/drm/msm/adreno/adreno_common.xml.h31
-rw-r--r--drivers/gpu/drm/msm/adreno/adreno_device.c19
-rw-r--r--drivers/gpu/drm/msm/adreno/adreno_gpu.c55
-rw-r--r--drivers/gpu/drm/msm/adreno/adreno_gpu.h8
-rw-r--r--drivers/gpu/drm/msm/adreno/adreno_pm4.xml.h46
-rw-r--r--drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c23
-rw-r--r--drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.h6
-rw-r--r--drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c22
-rw-r--r--drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c100
-rw-r--r--drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h28
-rw-r--r--drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h19
-rw-r--r--drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c39
-rw-r--r--drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c36
-rw-r--r--drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c610
-rw-r--r--drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h21
-rw-r--r--drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c6
-rw-r--r--drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h7
-rw-r--r--drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dspp.c11
-rw-r--r--drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c10
-rw-r--r--drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.h1
-rw-r--r--drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h11
-rw-r--r--drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.c4
-rw-r--r--drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c68
-rw-r--r--drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h5
-rw-r--r--drivers/gpu/drm/msm/disp/dpu1/dpu_mdss.c28
-rw-r--r--drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c5
-rw-r--r--drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h3
-rw-r--r--drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c107
-rw-r--r--drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h19
-rw-r--r--drivers/gpu/drm/msm/disp/mdp4/mdp4.xml.h37
-rw-r--r--drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c2
-rw-r--r--drivers/gpu/drm/msm/disp/mdp4/mdp4_plane.c19
-rw-r--r--drivers/gpu/drm/msm/disp/mdp5/mdp5.xml.h37
-rw-r--r--drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c8
-rw-r--r--drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c9
-rw-r--r--drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.h5
-rw-r--r--drivers/gpu/drm/msm/disp/mdp5/mdp5_mdss.c4
-rw-r--r--drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c37
-rw-r--r--drivers/gpu/drm/msm/disp/mdp5/mdp5_smp.c2
-rw-r--r--drivers/gpu/drm/msm/disp/mdp_common.xml.h37
-rw-r--r--drivers/gpu/drm/msm/dp/dp_audio.c2
-rw-r--r--drivers/gpu/drm/msm/dp/dp_aux.h2
-rw-r--r--drivers/gpu/drm/msm/dp/dp_catalog.c14
-rw-r--r--drivers/gpu/drm/msm/dp/dp_catalog.h2
-rw-r--r--drivers/gpu/drm/msm/dp/dp_clk_util.c (renamed from drivers/gpu/drm/msm/disp/dpu1/dpu_io_util.c)69
-rw-r--r--drivers/gpu/drm/msm/dp/dp_clk_util.h (renamed from drivers/gpu/drm/msm/disp/dpu1/dpu_io_util.h)8
-rw-r--r--drivers/gpu/drm/msm/dp/dp_ctrl.c104
-rw-r--r--drivers/gpu/drm/msm/dp/dp_ctrl.h8
-rw-r--r--drivers/gpu/drm/msm/dp/dp_debug.c28
-rw-r--r--drivers/gpu/drm/msm/dp/dp_display.c196
-rw-r--r--drivers/gpu/drm/msm/dp/dp_display.h2
-rw-r--r--drivers/gpu/drm/msm/dp/dp_drm.c21
-rw-r--r--drivers/gpu/drm/msm/dp/dp_panel.c5
-rw-r--r--drivers/gpu/drm/msm/dp/dp_parser.c38
-rw-r--r--drivers/gpu/drm/msm/dp/dp_parser.h4
-rw-r--r--drivers/gpu/drm/msm/dsi/dsi.c11
-rw-r--r--drivers/gpu/drm/msm/dsi/dsi.xml.h37
-rw-r--r--drivers/gpu/drm/msm/dsi/dsi_cfg.c23
-rw-r--r--drivers/gpu/drm/msm/dsi/dsi_cfg.h3
-rw-r--r--drivers/gpu/drm/msm/dsi/dsi_host.c8
-rw-r--r--drivers/gpu/drm/msm/dsi/dsi_manager.c65
-rw-r--r--drivers/gpu/drm/msm/dsi/dsi_phy_10nm.xml.h37
-rw-r--r--drivers/gpu/drm/msm/dsi/dsi_phy_14nm.xml.h37
-rw-r--r--drivers/gpu/drm/msm/dsi/dsi_phy_20nm.xml.h37
-rw-r--r--drivers/gpu/drm/msm/dsi/dsi_phy_28nm.xml.h37
-rw-r--r--drivers/gpu/drm/msm/dsi/dsi_phy_28nm_8960.xml.h37
-rw-r--r--drivers/gpu/drm/msm/dsi/dsi_phy_5nm.xml.h480
-rw-r--r--drivers/gpu/drm/msm/dsi/dsi_phy_7nm.xml.h43
-rw-r--r--drivers/gpu/drm/msm/dsi/mmss_cc.xml.h37
-rw-r--r--drivers/gpu/drm/msm/dsi/phy/dsi_phy.c18
-rw-r--r--drivers/gpu/drm/msm/dsi/phy/dsi_phy.h4
-rw-r--r--drivers/gpu/drm/msm/dsi/phy/dsi_phy_10nm.c122
-rw-r--r--drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c4
-rw-r--r--drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm.c4
-rw-r--r--drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm_8960.c4
-rw-r--r--drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c26
-rw-r--r--drivers/gpu/drm/msm/dsi/sfpb.xml.h37
-rw-r--r--drivers/gpu/drm/msm/edp/edp.h77
-rw-r--r--drivers/gpu/drm/msm/edp/edp_ctrl.c1373
-rw-r--r--drivers/gpu/drm/msm/hdmi/hdmi.c14
-rw-r--r--drivers/gpu/drm/msm/hdmi/hdmi.xml.h37
-rw-r--r--drivers/gpu/drm/msm/hdmi/hdmi_bridge.c11
-rw-r--r--drivers/gpu/drm/msm/hdmi/hdmi_phy.c2
-rw-r--r--drivers/gpu/drm/msm/hdmi/hdmi_phy_8996.c7
-rw-r--r--drivers/gpu/drm/msm/hdmi/hdmi_pll_8960.c2
-rw-r--r--drivers/gpu/drm/msm/hdmi/qfprom.xml.h37
-rw-r--r--drivers/gpu/drm/msm/msm_atomic.c15
-rw-r--r--drivers/gpu/drm/msm/msm_debugfs.c6
-rw-r--r--drivers/gpu/drm/msm/msm_drv.c199
-rw-r--r--drivers/gpu/drm/msm/msm_drv.h50
-rw-r--r--drivers/gpu/drm/msm/msm_fb.c43
-rw-r--r--drivers/gpu/drm/msm/msm_gem.h3
-rw-r--r--drivers/gpu/drm/msm/msm_gem_prime.c6
-rw-r--r--drivers/gpu/drm/msm/msm_gem_submit.c42
-rw-r--r--drivers/gpu/drm/msm/msm_gpu.c19
-rw-r--r--drivers/gpu/drm/msm/msm_gpu.h40
-rw-r--r--drivers/gpu/drm/msm/msm_gpu_devfreq.c51
-rw-r--r--drivers/gpu/drm/msm/msm_io_utils.c126
-rw-r--r--drivers/gpu/drm/msm/msm_rd.c8
-rw-r--r--drivers/gpu/drm/msm/msm_ringbuffer.c2
-rw-r--r--drivers/gpu/drm/msm/msm_submitqueue.c39
-rw-r--r--drivers/gpu/drm/mxsfb/mxsfb_drv.c15
-rw-r--r--drivers/gpu/drm/mxsfb/mxsfb_kms.c6
-rw-r--r--drivers/gpu/drm/nouveau/Kconfig1
-rw-r--r--drivers/gpu/drm/nouveau/dispnv50/disp.c2
-rw-r--r--drivers/gpu/drm/nouveau/dispnv50/wndw.c2
-rw-r--r--drivers/gpu/drm/nouveau/include/nvfw/hs.h2
-rw-r--r--drivers/gpu/drm/nouveau/include/nvif/list.h353
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_backlight.c6
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_connector.h2
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_display.c6
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_dmem.c3
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_dp.c17
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_encoder.h4
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_mem.c3
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_mem.h3
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_svm.c5
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_ttm.c13
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c317
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.h35
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/sorg94.c13
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/sorga102.c4
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgf119.c14
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgm107.c18
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/acr/hsfw.c9
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/bios/base.c2
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/i2c/aux.c5
-rw-r--r--drivers/gpu/drm/omapdrm/omap_drv.c3
-rw-r--r--drivers/gpu/drm/omapdrm/omap_gem_dmabuf.c1
-rw-r--r--drivers/gpu/drm/omapdrm/omap_plane.c22
-rw-r--r--drivers/gpu/drm/panel/Kconfig25
-rw-r--r--drivers/gpu/drm/panel/Makefile2
-rw-r--r--drivers/gpu/drm/panel/panel-abt-y030xx067a.c4
-rw-r--r--drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c8
-rw-r--r--drivers/gpu/drm/panel/panel-edp.c102
-rw-r--r--drivers/gpu/drm/panel/panel-ilitek-ili9322.c4
-rw-r--r--drivers/gpu/drm/panel/panel-ilitek-ili9341.c3
-rw-r--r--drivers/gpu/drm/panel/panel-innolux-ej030na.c4
-rw-r--r--drivers/gpu/drm/panel/panel-lg-lb035q02.c4
-rw-r--r--drivers/gpu/drm/panel/panel-lg-lg4573.c4
-rw-r--r--drivers/gpu/drm/panel/panel-nec-nl8048hl11.c4
-rw-r--r--drivers/gpu/drm/panel/panel-novatek-nt35560.c561
-rw-r--r--drivers/gpu/drm/panel/panel-novatek-nt39016.c4
-rw-r--r--drivers/gpu/drm/panel/panel-samsung-atna33xc20.c4
-rw-r--r--drivers/gpu/drm/panel/panel-samsung-db7430.c3
-rw-r--r--drivers/gpu/drm/panel/panel-samsung-ld9040.c4
-rw-r--r--drivers/gpu/drm/panel/panel-samsung-s6d27a1.c3
-rw-r--r--drivers/gpu/drm/panel/panel-samsung-s6e63m0-spi.c3
-rw-r--r--drivers/gpu/drm/panel/panel-simple.c37
-rw-r--r--drivers/gpu/drm/panel/panel-sitronix-st7789v.c4
-rw-r--r--drivers/gpu/drm/panel/panel-sony-acx424akp.c490
-rw-r--r--drivers/gpu/drm/panel/panel-sony-acx565akm.c4
-rw-r--r--drivers/gpu/drm/panel/panel-tpo-td028ttec1.c4
-rw-r--r--drivers/gpu/drm/panel/panel-tpo-td043mtea1.c4
-rw-r--r--drivers/gpu/drm/panel/panel-tpo-tpg110.c3
-rw-r--r--drivers/gpu/drm/panel/panel-widechips-ws2401.c3
-rw-r--r--drivers/gpu/drm/panfrost/panfrost_drv.c2
-rw-r--r--drivers/gpu/drm/panfrost/panfrost_features.h215
-rw-r--r--drivers/gpu/drm/panfrost/panfrost_gem.c1
-rw-r--r--drivers/gpu/drm/panfrost/panfrost_gem_shrinker.c2
-rw-r--r--drivers/gpu/drm/panfrost/panfrost_gpu.c35
-rw-r--r--drivers/gpu/drm/panfrost/panfrost_issues.h2
-rw-r--r--drivers/gpu/drm/panfrost/panfrost_job.c2
-rw-r--r--drivers/gpu/drm/panfrost/panfrost_mmu.c2
-rw-r--r--drivers/gpu/drm/panfrost/panfrost_perfcnt.c13
-rw-r--r--drivers/gpu/drm/panfrost/panfrost_regs.h3
-rw-r--r--drivers/gpu/drm/qxl/qxl_display.c8
-rw-r--r--drivers/gpu/drm/qxl/qxl_draw.c6
-rw-r--r--drivers/gpu/drm/qxl/qxl_drv.c31
-rw-r--r--drivers/gpu/drm/qxl/qxl_drv.h23
-rw-r--r--drivers/gpu/drm/qxl/qxl_ioctl.c41
-rw-r--r--drivers/gpu/drm/qxl/qxl_object.c8
-rw-r--r--drivers/gpu/drm/qxl/qxl_object.h4
-rw-r--r--drivers/gpu/drm/qxl/qxl_prime.c4
-rw-r--r--drivers/gpu/drm/radeon/atom.c3
-rw-r--r--drivers/gpu/drm/radeon/atombios_dp.c2
-rw-r--r--drivers/gpu/drm/radeon/atombios_encoders.c3
-rw-r--r--drivers/gpu/drm/radeon/cik.c2
-rw-r--r--drivers/gpu/drm/radeon/evergreen.c2
-rw-r--r--drivers/gpu/drm/radeon/ni.c2
-rw-r--r--drivers/gpu/drm/radeon/r600.c2
-rw-r--r--drivers/gpu/drm/radeon/radeon.h2
-rw-r--r--drivers/gpu/drm/radeon/radeon_connectors.c8
-rw-r--r--drivers/gpu/drm/radeon/radeon_device.c19
-rw-r--r--drivers/gpu/drm/radeon/radeon_display.c2
-rw-r--r--drivers/gpu/drm/radeon/radeon_dp_mst.c2
-rw-r--r--drivers/gpu/drm/radeon/radeon_gem.c1
-rw-r--r--drivers/gpu/drm/radeon/radeon_kms.c7
-rw-r--r--drivers/gpu/drm/radeon/radeon_mode.h4
-rw-r--r--drivers/gpu/drm/radeon/radeon_object.c34
-rw-r--r--drivers/gpu/drm/radeon/radeon_object.h4
-rw-r--r--drivers/gpu/drm/radeon/radeon_ttm.c22
-rw-r--r--drivers/gpu/drm/radeon/radeon_uvd.c13
-rw-r--r--drivers/gpu/drm/radeon/rv770.c2
-rw-r--r--drivers/gpu/drm/radeon/si.c2
-rw-r--r--drivers/gpu/drm/rcar-du/Makefile6
-rw-r--r--drivers/gpu/drm/rcar-du/rcar_du_drv.c18
-rw-r--r--drivers/gpu/drm/rcar-du/rcar_du_of.c323
-rw-r--r--drivers/gpu/drm/rcar-du/rcar_du_of.h20
-rw-r--r--drivers/gpu/drm/rcar-du/rcar_du_of_lvds_r8a7790.dts69
-rw-r--r--drivers/gpu/drm/rcar-du/rcar_du_of_lvds_r8a7791.dts43
-rw-r--r--drivers/gpu/drm/rcar-du/rcar_du_of_lvds_r8a7793.dts43
-rw-r--r--drivers/gpu/drm/rcar-du/rcar_du_of_lvds_r8a7795.dts43
-rw-r--r--drivers/gpu/drm/rcar-du/rcar_du_of_lvds_r8a7796.dts43
-rw-r--r--drivers/gpu/drm/rcar-du/rcar_du_plane.c13
-rw-r--r--drivers/gpu/drm/rcar-du/rcar_du_vsp.c10
-rw-r--r--drivers/gpu/drm/rcar-du/rcar_lvds.c1
-rw-r--r--drivers/gpu/drm/rockchip/Kconfig2
-rw-r--r--drivers/gpu/drm/rockchip/analogix_dp-rockchip.c4
-rw-r--r--drivers/gpu/drm/rockchip/cdn-dp-core.c30
-rw-r--r--drivers/gpu/drm/rockchip/cdn-dp-core.h6
-rw-r--r--drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c14
-rw-r--r--drivers/gpu/drm/rockchip/rockchip_drm_drv.c3
-rw-r--r--drivers/gpu/drm/rockchip/rockchip_drm_gem.c9
-rw-r--r--drivers/gpu/drm/rockchip/rockchip_drm_gem.h5
-rw-r--r--drivers/gpu/drm/rockchip/rockchip_lvds.c2
-rw-r--r--drivers/gpu/drm/rockchip/rockchip_rgb.c2
-rw-r--r--drivers/gpu/drm/rockchip/rockchip_vop_reg.c8
-rw-r--r--drivers/gpu/drm/scheduler/sched_main.c9
-rw-r--r--drivers/gpu/drm/selftests/Makefile3
-rw-r--r--drivers/gpu/drm/selftests/drm_buddy_selftests.h15
-rw-r--r--drivers/gpu/drm/selftests/test-drm_buddy.c992
-rw-r--r--drivers/gpu/drm/selftests/test-drm_dp_mst_helper.c8
-rw-r--r--drivers/gpu/drm/selftests/test-drm_framebuffer.c1
-rw-r--r--drivers/gpu/drm/selftests/test-drm_plane_helper.c4
-rw-r--r--drivers/gpu/drm/shmobile/shmob_drm_drv.c3
-rw-r--r--drivers/gpu/drm/solomon/Kconfig21
-rw-r--r--drivers/gpu/drm/solomon/Makefile2
-rw-r--r--drivers/gpu/drm/solomon/ssd130x-i2c.c116
-rw-r--r--drivers/gpu/drm/solomon/ssd130x.c843
-rw-r--r--drivers/gpu/drm/solomon/ssd130x.h76
-rw-r--r--drivers/gpu/drm/sprd/Kconfig1
-rw-r--r--drivers/gpu/drm/sprd/sprd_dpu.c5
-rw-r--r--drivers/gpu/drm/sprd/sprd_drm.c6
-rw-r--r--drivers/gpu/drm/sprd/sprd_dsi.c5
-rw-r--r--drivers/gpu/drm/sti/sti_cursor.c2
-rw-r--r--drivers/gpu/drm/sti/sti_drv.c3
-rw-r--r--drivers/gpu/drm/sti/sti_gdp.c2
-rw-r--r--drivers/gpu/drm/sti/sti_hqvdp.c2
-rw-r--r--drivers/gpu/drm/sti/sti_plane.c6
-rw-r--r--drivers/gpu/drm/sti/sti_plane.h1
-rw-r--r--drivers/gpu/drm/stm/drv.c8
-rw-r--r--drivers/gpu/drm/stm/dw_mipi_dsi-stm.c114
-rw-r--r--drivers/gpu/drm/stm/ltdc.c915
-rw-r--r--drivers/gpu/drm/stm/ltdc.h15
-rw-r--r--drivers/gpu/drm/sun4i/sun4i_drv.c3
-rw-r--r--drivers/gpu/drm/sun4i/sun4i_layer.c16
-rw-r--r--drivers/gpu/drm/sun4i/sun8i_mixer.h8
-rw-r--r--drivers/gpu/drm/tegra/Kconfig2
-rw-r--r--drivers/gpu/drm/tegra/dc.c50
-rw-r--r--drivers/gpu/drm/tegra/dc.h7
-rw-r--r--drivers/gpu/drm/tegra/dp.c13
-rw-r--r--drivers/gpu/drm/tegra/dpaux.c12
-rw-r--r--drivers/gpu/drm/tegra/drm.c3
-rw-r--r--drivers/gpu/drm/tegra/dsi.c4
-rw-r--r--drivers/gpu/drm/tegra/falcon.c2
-rw-r--r--drivers/gpu/drm/tegra/gem.c10
-rw-r--r--drivers/gpu/drm/tegra/hdmi.c34
-rw-r--r--drivers/gpu/drm/tegra/hub.c24
-rw-r--r--drivers/gpu/drm/tegra/plane.c73
-rw-r--r--drivers/gpu/drm/tegra/plane.h2
-rw-r--r--drivers/gpu/drm/tegra/sor.c2
-rw-r--r--drivers/gpu/drm/tidss/tidss_drv.c3
-rw-r--r--drivers/gpu/drm/tilcdc/tilcdc_drv.c7
-rw-r--r--drivers/gpu/drm/tiny/Kconfig15
-rw-r--r--drivers/gpu/drm/tiny/Makefile1
-rw-r--r--drivers/gpu/drm/tiny/arcpgu.c3
-rw-r--r--drivers/gpu/drm/tiny/bochs.c20
-rw-r--r--drivers/gpu/drm/tiny/cirrus.c25
-rw-r--r--drivers/gpu/drm/tiny/gm12u320.c7
-rw-r--r--drivers/gpu/drm/tiny/hx8357d.c4
-rw-r--r--drivers/gpu/drm/tiny/ili9163.c4
-rw-r--r--drivers/gpu/drm/tiny/ili9225.c4
-rw-r--r--drivers/gpu/drm/tiny/ili9341.c4
-rw-r--r--drivers/gpu/drm/tiny/ili9486.c4
-rw-r--r--drivers/gpu/drm/tiny/mi0283qt.c4
-rw-r--r--drivers/gpu/drm/tiny/panel-mipi-dbi.c396
-rw-r--r--drivers/gpu/drm/tiny/repaper.c28
-rw-r--r--drivers/gpu/drm/tiny/simpledrm.c25
-rw-r--r--drivers/gpu/drm/tiny/st7586.c4
-rw-r--r--drivers/gpu/drm/tiny/st7735r.c4
-rw-r--r--drivers/gpu/drm/ttm/ttm_bo_util.c23
-rw-r--r--drivers/gpu/drm/ttm/ttm_range_manager.c4
-rw-r--r--drivers/gpu/drm/ttm/ttm_resource.c113
-rw-r--r--drivers/gpu/drm/ttm/ttm_sys_manager.c3
-rw-r--r--drivers/gpu/drm/ttm/ttm_tt.c8
-rw-r--r--drivers/gpu/drm/tve200/tve200_drv.c3
-rw-r--r--drivers/gpu/drm/udl/udl_modeset.c3
-rw-r--r--drivers/gpu/drm/v3d/v3d_bo.c1
-rw-r--r--drivers/gpu/drm/v3d/v3d_debugfs.c11
-rw-r--r--drivers/gpu/drm/v3d/v3d_drv.c8
-rw-r--r--drivers/gpu/drm/v3d/v3d_gem.c6
-rw-r--r--drivers/gpu/drm/v3d/v3d_sched.c50
-rw-r--r--drivers/gpu/drm/vboxvideo/vbox_drv.c20
-rw-r--r--drivers/gpu/drm/vboxvideo/vbox_mode.c4
-rw-r--r--drivers/gpu/drm/vc4/vc4_bo.c2
-rw-r--r--drivers/gpu/drm/vc4/vc4_crtc.c9
-rw-r--r--drivers/gpu/drm/vc4/vc4_drv.c33
-rw-r--r--drivers/gpu/drm/vc4/vc4_dsi.c21
-rw-r--r--drivers/gpu/drm/vc4/vc4_hdmi.c195
-rw-r--r--drivers/gpu/drm/vc4/vc4_hdmi.h9
-rw-r--r--drivers/gpu/drm/vc4/vc4_regs.h3
-rw-r--r--drivers/gpu/drm/virtio/virtgpu_debugfs.c4
-rw-r--r--drivers/gpu/drm/virtio/virtgpu_gem.c3
-rw-r--r--drivers/gpu/drm/virtio/virtgpu_object.c1
-rw-r--r--drivers/gpu/drm/vkms/vkms_composer.c4
-rw-r--r--drivers/gpu/drm/vkms/vkms_drv.h8
-rw-r--r--drivers/gpu/drm/vkms/vkms_output.c29
-rw-r--r--drivers/gpu/drm/vkms/vkms_plane.c2
-rw-r--r--drivers/gpu/drm/vkms/vkms_writeback.c2
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_drv.c24
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_drv.h5
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c35
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_fence.c48
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_fence.h3
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_gmrid_manager.c4
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_kms.c2
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_system_manager.c3
-rw-r--r--drivers/gpu/drm/xen/xen_drm_front.c3
-rw-r--r--drivers/gpu/drm/xen/xen_drm_front_gem.c7
-rw-r--r--drivers/gpu/drm/xen/xen_drm_front_gem.h6
-rw-r--r--drivers/gpu/drm/xlnx/Kconfig1
-rw-r--r--drivers/gpu/drm/xlnx/zynqmp_dp.c2
-rw-r--r--drivers/gpu/drm/xlnx/zynqmp_dpsub.c3
-rw-r--r--drivers/gpu/host1x/dev.c8
-rw-r--r--drivers/gpu/host1x/syncpt.c35
-rw-r--r--drivers/gpu/ipu-v3/ipu-csi.c6
-rw-r--r--drivers/hid/amd-sfh-hid/amd_sfh_pcie.c76
-rw-r--r--drivers/hid/amd-sfh-hid/amd_sfh_pcie.h4
-rw-r--r--drivers/hid/amd-sfh-hid/hid_descriptor/amd_sfh_hid_desc.c4
-rw-r--r--drivers/hid/hid-apple.c16
-rw-r--r--drivers/hid/hid-debug.c5
-rw-r--r--drivers/hid/hid-elo.c6
-rw-r--r--drivers/hid/hid-ids.h1
-rw-r--r--drivers/hid/hid-input.c3
-rw-r--r--drivers/hid/hid-logitech-dj.c1
-rw-r--r--drivers/hid/hid-nintendo.c4
-rw-r--r--drivers/hid/hid-quirks.c1
-rw-r--r--drivers/hid/hid-thrustmaster.c8
-rw-r--r--drivers/hid/hid-vivaldi.c2
-rw-r--r--drivers/hid/i2c-hid/i2c-hid-of-goodix.c28
-rw-r--r--drivers/hid/uhid.c2
-rw-r--r--drivers/hv/channel_mgmt.c19
-rw-r--r--drivers/hv/hv_balloon.c9
-rw-r--r--drivers/hv/hv_common.c4
-rw-r--r--drivers/hv/hv_snapshot.c7
-rw-r--r--drivers/hv/hv_utils_transport.c2
-rw-r--r--drivers/hv/hyperv_vmbus.h14
-rw-r--r--drivers/hv/vmbus_drv.c13
-rw-r--r--drivers/hwmon/Kconfig49
-rw-r--r--drivers/hwmon/Makefile2
-rw-r--r--drivers/hwmon/adcxx.c4
-rw-r--r--drivers/hwmon/adt7310.c95
-rw-r--r--drivers/hwmon/adt7410.c82
-rw-r--r--drivers/hwmon/adt7470.c3
-rw-r--r--drivers/hwmon/adt7x10.c479
-rw-r--r--drivers/hwmon/adt7x10.h10
-rw-r--r--drivers/hwmon/aquacomputer_d5next.c379
-rw-r--r--drivers/hwmon/asus-ec-sensors.c716
-rw-r--r--drivers/hwmon/asus_wmi_ec_sensors.c3
-rw-r--r--drivers/hwmon/asus_wmi_sensors.c1
-rw-r--r--drivers/hwmon/axi-fan-control.c3
-rw-r--r--drivers/hwmon/dell-smm-hwmon.c84
-rw-r--r--drivers/hwmon/hwmon.c54
-rw-r--r--drivers/hwmon/lm70.c16
-rw-r--r--drivers/hwmon/lm83.c476
-rw-r--r--drivers/hwmon/lm90.c21
-rw-r--r--drivers/hwmon/max1111.c3
-rw-r--r--drivers/hwmon/max31722.c4
-rw-r--r--drivers/hwmon/max6639.c62
-rw-r--r--drivers/hwmon/mlxreg-fan.c84
-rw-r--r--drivers/hwmon/nct6775.c152
-rw-r--r--drivers/hwmon/ntc_thermistor.c2
-rw-r--r--drivers/hwmon/occ/common.c19
-rw-r--r--drivers/hwmon/occ/common.h2
-rw-r--r--drivers/hwmon/occ/sysfs.c46
-rw-r--r--drivers/hwmon/pmbus/Kconfig33
-rw-r--r--drivers/hwmon/pmbus/Makefile1
-rw-r--r--drivers/hwmon/pmbus/adm1275.c40
-rw-r--r--drivers/hwmon/pmbus/ir38064.c2
-rw-r--r--drivers/hwmon/pmbus/lm25066.c14
-rw-r--r--drivers/hwmon/pmbus/pli1209bc.c146
-rw-r--r--drivers/hwmon/pmbus/pmbus.h2
-rw-r--r--drivers/hwmon/pmbus/pmbus_core.c137
-rw-r--r--drivers/hwmon/pmbus/xdpe12284.c32
-rw-r--r--drivers/hwmon/powr1220.c235
-rw-r--r--drivers/hwmon/sch5627.c71
-rw-r--r--drivers/hwmon/sch5636.c10
-rw-r--r--drivers/hwmon/sch56xx-common.c44
-rw-r--r--drivers/hwmon/scpi-hwmon.c6
-rw-r--r--drivers/hwmon/tc654.c104
-rw-r--r--drivers/hwmon/tmp464.c712
-rw-r--r--drivers/hwmon/vexpress-hwmon.c6
-rw-r--r--drivers/hwtracing/coresight/coresight-config.h2
-rw-r--r--drivers/hwtracing/intel_th/msu.c4
-rw-r--r--drivers/i2c/busses/Kconfig6
-rw-r--r--drivers/i2c/busses/i2c-bcm2835.c11
-rw-r--r--drivers/i2c/busses/i2c-brcmstb.c2
-rw-r--r--drivers/i2c/busses/i2c-qcom-cci.c16
-rw-r--r--drivers/idle/intel_idle.c111
-rw-r--r--drivers/iio/accel/bma400_spi.c4
-rw-r--r--drivers/iio/accel/bmc150-accel-core.c5
-rw-r--r--drivers/iio/accel/bmc150-accel-spi.c4
-rw-r--r--drivers/iio/accel/bmi088-accel-spi.c4
-rw-r--r--drivers/iio/accel/fxls8962af-core.c12
-rw-r--r--drivers/iio/accel/fxls8962af-i2c.c2
-rw-r--r--drivers/iio/accel/fxls8962af-spi.c2
-rw-r--r--drivers/iio/accel/fxls8962af.h3
-rw-r--r--drivers/iio/accel/kxcjk-1013.c5
-rw-r--r--drivers/iio/accel/kxsd9-spi.c4
-rw-r--r--drivers/iio/accel/mma7455_spi.c4
-rw-r--r--drivers/iio/accel/mma9551.c5
-rw-r--r--drivers/iio/accel/mma9553.c5
-rw-r--r--drivers/iio/accel/sca3000.c4
-rw-r--r--drivers/iio/adc/ad7124.c2
-rw-r--r--drivers/iio/adc/ad7266.c4
-rw-r--r--drivers/iio/adc/ltc2496.c4
-rw-r--r--drivers/iio/adc/mcp320x.c4
-rw-r--r--drivers/iio/adc/mcp3911.c4
-rw-r--r--drivers/iio/adc/men_z188_adc.c9
-rw-r--r--drivers/iio/adc/ti-adc12138.c4
-rw-r--r--drivers/iio/adc/ti-ads7950.c4
-rw-r--r--drivers/iio/adc/ti-ads8688.c4
-rw-r--r--drivers/iio/adc/ti-tlc4541.c4
-rw-r--r--drivers/iio/adc/ti-tsc2046.c4
-rw-r--r--drivers/iio/addac/ad74413r.c17
-rw-r--r--drivers/iio/amplifiers/ad8366.c4
-rw-r--r--drivers/iio/common/ssp_sensors/ssp_dev.c4
-rw-r--r--drivers/iio/dac/ad5360.c4
-rw-r--r--drivers/iio/dac/ad5380.c4
-rw-r--r--drivers/iio/dac/ad5446.c4
-rw-r--r--drivers/iio/dac/ad5449.c4
-rw-r--r--drivers/iio/dac/ad5504.c4
-rw-r--r--drivers/iio/dac/ad5592r.c4
-rw-r--r--drivers/iio/dac/ad5624r_spi.c4
-rw-r--r--drivers/iio/dac/ad5686-spi.c4
-rw-r--r--drivers/iio/dac/ad5761.c4
-rw-r--r--drivers/iio/dac/ad5764.c4
-rw-r--r--drivers/iio/dac/ad5791.c4
-rw-r--r--drivers/iio/dac/ad8801.c4
-rw-r--r--drivers/iio/dac/ltc1660.c4
-rw-r--r--drivers/iio/dac/ltc2632.c4
-rw-r--r--drivers/iio/dac/mcp4922.c4
-rw-r--r--drivers/iio/dac/ti-dac082s085.c4
-rw-r--r--drivers/iio/dac/ti-dac7311.c3
-rw-r--r--drivers/iio/frequency/adf4350.c4
-rw-r--r--drivers/iio/frequency/admv1013.c2
-rw-r--r--drivers/iio/gyro/bmg160_core.c5
-rw-r--r--drivers/iio/gyro/bmg160_spi.c4
-rw-r--r--drivers/iio/gyro/fxas21002c_spi.c4
-rw-r--r--drivers/iio/health/afe4403.c4
-rw-r--r--drivers/iio/imu/adis16480.c7
-rw-r--r--drivers/iio/imu/kmx61.c5
-rw-r--r--drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c6
-rw-r--r--drivers/iio/industrialio-buffer.c14
-rw-r--r--drivers/iio/magnetometer/bmc150_magn.c5
-rw-r--r--drivers/iio/magnetometer/bmc150_magn_spi.c4
-rw-r--r--drivers/iio/magnetometer/hmc5843_spi.c4
-rw-r--r--drivers/iio/potentiometer/max5487.c4
-rw-r--r--drivers/iio/pressure/ms5611_spi.c4
-rw-r--r--drivers/iio/pressure/zpa2326_spi.c4
-rw-r--r--drivers/infiniband/core/addr.c1
-rw-r--r--drivers/infiniband/core/cache.c1
-rw-r--r--drivers/infiniband/core/cm.c2
-rw-r--r--drivers/infiniband/core/cma.c64
-rw-r--r--drivers/infiniband/core/cma_configfs.c1
-rw-r--r--drivers/infiniband/core/cq.c1
-rw-r--r--drivers/infiniband/core/iwpm_util.h1
-rw-r--r--drivers/infiniband/core/nldev.c3
-rw-r--r--drivers/infiniband/core/rw.c1
-rw-r--r--drivers/infiniband/core/sa_query.c1
-rw-r--r--drivers/infiniband/core/ucma.c34
-rw-r--r--drivers/infiniband/core/verbs.c9
-rw-r--r--drivers/infiniband/hw/hfi1/affinity.c5
-rw-r--r--drivers/infiniband/hw/hfi1/debugfs.c1
-rw-r--r--drivers/infiniband/hw/hfi1/device.c1
-rw-r--r--drivers/infiniband/hw/hfi1/fault.c1
-rw-r--r--drivers/infiniband/hw/hfi1/firmware.c1
-rw-r--r--drivers/infiniband/hw/hfi1/ipoib.h2
-rw-r--r--drivers/infiniband/hw/hfi1/ipoib_main.c27
-rw-r--r--drivers/infiniband/hw/hfi1/ipoib_tx.c38
-rw-r--r--drivers/infiniband/hw/hfi1/verbs.c3
-rw-r--r--drivers/infiniband/hw/hns/hns_roce_cmd.c97
-rw-r--r--drivers/infiniband/hw/hns/hns_roce_cmd.h8
-rw-r--r--drivers/infiniband/hw/hns/hns_roce_cq.c71
-rw-r--r--drivers/infiniband/hw/hns/hns_roce_device.h26
-rw-r--r--drivers/infiniband/hw/hns/hns_roce_hem.c4
-rw-r--r--drivers/infiniband/hw/hns/hns_roce_hw_v2.c458
-rw-r--r--drivers/infiniband/hw/hns/hns_roce_hw_v2.h20
-rw-r--r--drivers/infiniband/hw/hns/hns_roce_hw_v2_dfx.c5
-rw-r--r--drivers/infiniband/hw/hns/hns_roce_mr.c50
-rw-r--r--drivers/infiniband/hw/hns/hns_roce_srq.c106
-rw-r--r--drivers/infiniband/hw/irdma/cm.c68
-rw-r--r--drivers/infiniband/hw/irdma/cm.h7
-rw-r--r--drivers/infiniband/hw/irdma/ctrl.c602
-rw-r--r--drivers/infiniband/hw/irdma/defs.h8
-rw-r--r--drivers/infiniband/hw/irdma/hmc.c105
-rw-r--r--drivers/infiniband/hw/irdma/hmc.h53
-rw-r--r--drivers/infiniband/hw/irdma/hw.c192
-rw-r--r--drivers/infiniband/hw/irdma/i40iw_hw.c1
-rw-r--r--drivers/infiniband/hw/irdma/i40iw_if.c3
-rw-r--r--drivers/infiniband/hw/irdma/main.c29
-rw-r--r--drivers/infiniband/hw/irdma/main.h47
-rw-r--r--drivers/infiniband/hw/irdma/osdep.h41
-rw-r--r--drivers/infiniband/hw/irdma/pble.c77
-rw-r--r--drivers/infiniband/hw/irdma/pble.h25
-rw-r--r--drivers/infiniband/hw/irdma/protos.h90
-rw-r--r--drivers/infiniband/hw/irdma/puda.c132
-rw-r--r--drivers/infiniband/hw/irdma/puda.h43
-rw-r--r--drivers/infiniband/hw/irdma/status.h71
-rw-r--r--drivers/infiniband/hw/irdma/type.h113
-rw-r--r--drivers/infiniband/hw/irdma/uda.c40
-rw-r--r--drivers/infiniband/hw/irdma/uda.h46
-rw-r--r--drivers/infiniband/hw/irdma/uk.c122
-rw-r--r--drivers/infiniband/hw/irdma/user.h62
-rw-r--r--drivers/infiniband/hw/irdma/utils.c247
-rw-r--r--drivers/infiniband/hw/irdma/verbs.c391
-rw-r--r--drivers/infiniband/hw/irdma/verbs.h15
-rw-r--r--drivers/infiniband/hw/irdma/ws.c19
-rw-r--r--drivers/infiniband/hw/irdma/ws.h2
-rw-r--r--drivers/infiniband/hw/mlx4/alias_GUID.c1
-rw-r--r--drivers/infiniband/hw/mlx4/main.c2
-rw-r--r--drivers/infiniband/hw/mlx4/srq.c1
-rw-r--r--drivers/infiniband/hw/mlx5/cong.c3
-rw-r--r--drivers/infiniband/hw/mlx5/devx.c65
-rw-r--r--drivers/infiniband/hw/mlx5/ib_virt.c1
-rw-r--r--drivers/infiniband/hw/mlx5/main.c2
-rw-r--r--drivers/infiniband/hw/mlx5/mem.c1
-rw-r--r--drivers/infiniband/hw/mlx5/mlx5_ib.h12
-rw-r--r--drivers/infiniband/hw/mlx5/mr.c121
-rw-r--r--drivers/infiniband/hw/mlx5/odp.c19
-rw-r--r--drivers/infiniband/hw/mlx5/qp.c5
-rw-r--r--drivers/infiniband/hw/mlx5/qpc.c2
-rw-r--r--drivers/infiniband/hw/mlx5/srq.c1
-rw-r--r--drivers/infiniband/hw/mthca/mthca_main.c8
-rw-r--r--drivers/infiniband/hw/mthca/mthca_profile.c2
-rw-r--r--drivers/infiniband/hw/qib/qib_fs.c1
-rw-r--r--drivers/infiniband/hw/qib/qib_iba7220.c4
-rw-r--r--drivers/infiniband/hw/qib/qib_sysfs.c2
-rw-r--r--drivers/infiniband/hw/usnic/usnic_debugfs.c1
-rw-r--r--drivers/infiniband/hw/usnic/usnic_ib_qp_grp.c1
-rw-r--r--drivers/infiniband/hw/usnic/usnic_ib_sysfs.c1
-rw-r--r--drivers/infiniband/hw/usnic/usnic_ib_verbs.c1
-rw-r--r--drivers/infiniband/hw/usnic/usnic_transport.c1
-rw-r--r--drivers/infiniband/hw/usnic/usnic_vnic.c1
-rw-r--r--drivers/infiniband/hw/vmw_pvrdma/pvrdma_main.c10
-rw-r--r--drivers/infiniband/sw/rdmavt/qp.c2
-rw-r--r--drivers/infiniband/sw/rxe/rxe.c110
-rw-r--r--drivers/infiniband/sw/rxe/rxe.h1
-rw-r--r--drivers/infiniband/sw/rxe/rxe_av.c19
-rw-r--r--drivers/infiniband/sw/rxe/rxe_comp.c8
-rw-r--r--drivers/infiniband/sw/rxe/rxe_cq.c20
-rw-r--r--drivers/infiniband/sw/rxe/rxe_loc.h32
-rw-r--r--drivers/infiniband/sw/rxe/rxe_mcast.c542
-rw-r--r--drivers/infiniband/sw/rxe/rxe_mmap.c1
-rw-r--r--drivers/infiniband/sw/rxe/rxe_mr.c15
-rw-r--r--drivers/infiniband/sw/rxe/rxe_mw.c38
-rw-r--r--drivers/infiniband/sw/rxe/rxe_net.c41
-rw-r--r--drivers/infiniband/sw/rxe/rxe_pool.c433
-rw-r--r--drivers/infiniband/sw/rxe/rxe_pool.h105
-rw-r--r--drivers/infiniband/sw/rxe/rxe_qp.c57
-rw-r--r--drivers/infiniband/sw/rxe/rxe_queue.c10
-rw-r--r--drivers/infiniband/sw/rxe/rxe_recv.c26
-rw-r--r--drivers/infiniband/sw/rxe/rxe_req.c71
-rw-r--r--drivers/infiniband/sw/rxe/rxe_resp.c170
-rw-r--r--drivers/infiniband/sw/rxe/rxe_verbs.c108
-rw-r--r--drivers/infiniband/sw/rxe/rxe_verbs.h27
-rw-r--r--drivers/infiniband/sw/siw/siw.h7
-rw-r--r--drivers/infiniband/sw/siw/siw_qp_rx.c20
-rw-r--r--drivers/infiniband/sw/siw/siw_verbs.c3
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_netlink.c1
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_vlan.c1
-rw-r--r--drivers/infiniband/ulp/iser/iscsi_iser.h13
-rw-r--r--drivers/infiniband/ulp/iser/iser_initiator.c58
-rw-r--r--drivers/infiniband/ulp/iser/iser_memory.c69
-rw-r--r--drivers/infiniband/ulp/iser/iser_verbs.c3
-rw-r--r--drivers/infiniband/ulp/opa_vnic/opa_vnic_netdev.c1
-rw-r--r--drivers/infiniband/ulp/rtrs/rtrs-clt-sysfs.c3
-rw-r--r--drivers/infiniband/ulp/rtrs/rtrs-clt.c81
-rw-r--r--drivers/infiniband/ulp/rtrs/rtrs-clt.h1
-rw-r--r--drivers/infiniband/ulp/rtrs/rtrs.c1
-rw-r--r--drivers/infiniband/ulp/srp/ib_srp.c6
-rw-r--r--drivers/infiniband/ulp/srp/ib_srp.h11
-rw-r--r--drivers/input/input.c6
-rw-r--r--drivers/input/keyboard/Kconfig2
-rw-r--r--drivers/input/keyboard/applespi.c4
-rw-r--r--drivers/input/misc/adxl34x-spi.c4
-rw-r--r--drivers/input/mouse/elan_i2c_core.c64
-rw-r--r--drivers/input/mouse/psmouse-smbus.c10
-rw-r--r--drivers/input/rmi4/Kconfig2
-rw-r--r--drivers/input/tablet/aiptek.c10
-rw-r--r--drivers/input/touchscreen/Kconfig4
-rw-r--r--drivers/input/touchscreen/ads7846.c4
-rw-r--r--drivers/input/touchscreen/cyttsp4_spi.c4
-rw-r--r--drivers/input/touchscreen/goodix.c34
-rw-r--r--drivers/input/touchscreen/tsc2005.c4
-rw-r--r--drivers/input/touchscreen/wm97xx-core.c12
-rw-r--r--drivers/input/touchscreen/zinitix.c56
-rw-r--r--drivers/iommu/Kconfig6
-rw-r--r--drivers/iommu/Makefile2
-rw-r--r--drivers/iommu/amd/amd_iommu.h1
-rw-r--r--drivers/iommu/amd/amd_iommu_types.h1
-rw-r--r--drivers/iommu/amd/init.c12
-rw-r--r--drivers/iommu/amd/io_pgtable.c12
-rw-r--r--drivers/iommu/amd/iommu.c10
-rw-r--r--drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c5
-rw-r--r--drivers/iommu/intel/Kconfig2
-rw-r--r--drivers/iommu/intel/iommu.c6
-rw-r--r--drivers/iommu/intel/irq_remapping.c13
-rw-r--r--drivers/iommu/intel/svm.c9
-rw-r--r--drivers/iommu/ioasid.c38
-rw-r--r--drivers/iommu/iommu-sva-lib.c39
-rw-r--r--drivers/iommu/iommu-sva-lib.h7
-rw-r--r--drivers/iommu/iommu.c33
-rw-r--r--drivers/iommu/mtk_iommu.c34
-rw-r--r--drivers/iommu/mtk_iommu_v1.c42
-rw-r--r--drivers/iommu/omap-iommu.c2
-rw-r--r--drivers/iommu/tegra-smmu.c4
-rw-r--r--drivers/irqchip/Kconfig8
-rw-r--r--drivers/irqchip/Makefile2
-rw-r--r--drivers/irqchip/irq-apple-aic.c552
-rw-r--r--drivers/irqchip/irq-ativic32.c156
-rw-r--r--drivers/irqchip/irq-ftintc010.c1
-rw-r--r--drivers/irqchip/irq-gic-v3-its.c126
-rw-r--r--drivers/irqchip/irq-gic-v3.c2
-rw-r--r--drivers/irqchip/irq-gic.c104
-rw-r--r--drivers/irqchip/irq-imx-intmux.c8
-rw-r--r--drivers/irqchip/irq-loongson-pch-msi.c2
-rw-r--r--drivers/irqchip/irq-lpc32xx.c34
-rw-r--r--drivers/irqchip/irq-meson-gpio.c106
-rw-r--r--drivers/irqchip/irq-mvebu-pic.c28
-rw-r--r--drivers/irqchip/irq-nvic.c24
-rw-r--r--drivers/irqchip/irq-qcom-mpm.c461
-rw-r--r--drivers/irqchip/irq-realtek-rtl.c18
-rw-r--r--drivers/irqchip/irq-renesas-intc-irqpin.c3
-rw-r--r--drivers/irqchip/irq-renesas-irqc.c3
-rw-r--r--drivers/irqchip/irq-sifive-plic.c39
-rw-r--r--drivers/irqchip/irq-stm32-exti.c50
-rw-r--r--drivers/irqchip/irq-ts4800.c25
-rw-r--r--drivers/irqchip/irq-versatile-fpga.c46
-rw-r--r--drivers/irqchip/irq-xilinx-intc.c30
-rw-r--r--drivers/irqchip/qcom-pdc.c137
-rw-r--r--drivers/isdn/hardware/mISDN/hfcpci.c6
-rw-r--r--drivers/isdn/hardware/mISDN/mISDNipac.c2
-rw-r--r--drivers/isdn/hardware/mISDN/mISDNisar.c4
-rw-r--r--drivers/isdn/mISDN/dsp_pipeline.c6
-rw-r--r--drivers/leds/leds-cr0014114.c4
-rw-r--r--drivers/leds/leds-dac124s085.c4
-rw-r--r--drivers/leds/leds-el15203000.c4
-rw-r--r--drivers/leds/leds-spi-byte.c4
-rw-r--r--drivers/md/Kconfig1
-rw-r--r--drivers/md/bcache/btree.c6
-rw-r--r--drivers/md/bcache/io.c3
-rw-r--r--drivers/md/bcache/journal.c16
-rw-r--r--drivers/md/bcache/movinggc.c4
-rw-r--r--drivers/md/bcache/request.c26
-rw-r--r--drivers/md/bcache/super.c9
-rw-r--r--drivers/md/bcache/writeback.c21
-rw-r--r--drivers/md/dm-cache-policy-smq.c4
-rw-r--r--drivers/md/dm-cache-target.c43
-rw-r--r--drivers/md/dm-clone-target.c10
-rw-r--r--drivers/md/dm-core.h100
-rw-r--r--drivers/md/dm-crypt.c59
-rw-r--r--drivers/md/dm-delay.c5
-rw-r--r--drivers/md/dm-ima.c6
-rw-r--r--drivers/md/dm-integrity.c5
-rw-r--r--drivers/md/dm-io.c13
-rw-r--r--drivers/md/dm-ioctl.c2
-rw-r--r--drivers/md/dm-log-writes.c39
-rw-r--r--drivers/md/dm-mpath.c5
-rw-r--r--drivers/md/dm-rq.c33
-rw-r--r--drivers/md/dm-snap.c21
-rw-r--r--drivers/md/dm-stats.c34
-rw-r--r--drivers/md/dm-stats.h11
-rw-r--r--drivers/md/dm-table.c57
-rw-r--r--drivers/md/dm-thin-metadata.c28
-rw-r--r--drivers/md/dm-thin-metadata.h1
-rw-r--r--drivers/md/dm-thin.c56
-rw-r--r--drivers/md/dm-writecache.c7
-rw-r--r--drivers/md/dm-zoned-metadata.c30
-rw-r--r--drivers/md/dm-zoned-target.c4
-rw-r--r--drivers/md/dm-zoned.h9
-rw-r--r--drivers/md/dm.c829
-rw-r--r--drivers/md/md-faulty.c4
-rw-r--r--drivers/md/md-multipath.c13
-rw-r--r--drivers/md/md.c39
-rw-r--r--drivers/md/raid1-10.c5
-rw-r--r--drivers/md/raid1.c58
-rw-r--r--drivers/md/raid1.h1
-rw-r--r--drivers/md/raid10.c47
-rw-r--r--drivers/md/raid10.h1
-rw-r--r--drivers/md/raid5-cache.c42
-rw-r--r--drivers/md/raid5-ppl.c29
-rw-r--r--drivers/md/raid5.c29
-rw-r--r--drivers/media/Kconfig11
-rw-r--r--drivers/media/Makefile4
-rw-r--r--drivers/media/cec/platform/Makefile16
-rw-r--r--drivers/media/cec/platform/cros-ec/cros-ec-cec.c2
-rw-r--r--drivers/media/cec/platform/seco/seco-cec.c57
-rw-r--r--drivers/media/common/Kconfig16
-rw-r--r--drivers/media/common/Makefile7
-rw-r--r--drivers/media/common/saa7146/Kconfig2
-rw-r--r--drivers/media/common/videobuf2/Makefile8
-rw-r--r--drivers/media/common/videobuf2/videobuf2-dma-contig.c20
-rw-r--r--drivers/media/common/videobuf2/videobuf2-dma-sg.c9
-rw-r--r--drivers/media/common/videobuf2/videobuf2-vmalloc.c11
-rw-r--r--drivers/media/dvb-core/Kconfig2
-rw-r--r--drivers/media/dvb-frontends/Kconfig647
-rw-r--r--drivers/media/dvb-frontends/Makefile193
-rw-r--r--drivers/media/dvb-frontends/dib3000mc.c2
-rw-r--r--drivers/media/dvb-frontends/dib7000p.c4
-rw-r--r--drivers/media/dvb-frontends/si21xx.c2
-rw-r--r--drivers/media/dvb-frontends/stv0299.c9
-rw-r--r--drivers/media/dvb-frontends/tda8083.c2
-rw-r--r--drivers/media/firewire/Makefile2
-rw-r--r--drivers/media/i2c/Kconfig1909
-rw-r--r--drivers/media/i2c/Makefile192
-rw-r--r--drivers/media/i2c/adv7180.c10
-rw-r--r--drivers/media/i2c/adv7183.c51
-rw-r--r--drivers/media/i2c/adv748x/adv748x-csi2.c18
-rw-r--r--drivers/media/i2c/adv7511-v4l2.c3
-rw-r--r--drivers/media/i2c/adv7604.c2
-rw-r--r--drivers/media/i2c/adv7842.c2
-rw-r--r--drivers/media/i2c/ccs/Kconfig2
-rw-r--r--drivers/media/i2c/ccs/ccs-core.c1
-rw-r--r--drivers/media/i2c/cx25840/Kconfig2
-rw-r--r--drivers/media/i2c/dw9714.c42
-rw-r--r--drivers/media/i2c/et8ek8/Kconfig2
-rw-r--r--drivers/media/i2c/hi847.c3012
-rw-r--r--drivers/media/i2c/imx274.c2
-rw-r--r--drivers/media/i2c/isl7998x.c1628
-rw-r--r--drivers/media/i2c/m5mols/Kconfig2
-rw-r--r--drivers/media/i2c/m5mols/m5mols.h3
-rw-r--r--drivers/media/i2c/m5mols/m5mols_capture.c1
-rw-r--r--drivers/media/i2c/m5mols/m5mols_core.c29
-rw-r--r--drivers/media/i2c/max2175.c2
-rw-r--r--drivers/media/i2c/max9286.c125
-rw-r--r--drivers/media/i2c/ml86v7667.c5
-rw-r--r--drivers/media/i2c/mt9m001.c8
-rw-r--r--drivers/media/i2c/mt9m111.c15
-rw-r--r--drivers/media/i2c/noon010pc30.c75
-rw-r--r--drivers/media/i2c/og01a1b.c1128
-rw-r--r--drivers/media/i2c/ov08d10.c1528
-rw-r--r--drivers/media/i2c/ov2740.c8
-rw-r--r--drivers/media/i2c/ov5640.c14
-rw-r--r--drivers/media/i2c/ov5648.c16
-rw-r--r--drivers/media/i2c/ov5675.c32
-rw-r--r--drivers/media/i2c/ov5693.c9
-rw-r--r--drivers/media/i2c/ov6650.c206
-rw-r--r--drivers/media/i2c/ov8865.c12
-rw-r--r--drivers/media/i2c/ov9640.c8
-rw-r--r--drivers/media/i2c/saa7115.c2
-rw-r--r--drivers/media/i2c/tc358743.c26
-rw-r--r--drivers/media/i2c/tvp5150.c6
-rw-r--r--drivers/media/mc/mc-entity.c55
-rw-r--r--drivers/media/mmc/Kconfig1
-rw-r--r--drivers/media/pci/Kconfig31
-rw-r--r--drivers/media/pci/Makefile22
-rw-r--r--drivers/media/pci/bt8xx/Kconfig2
-rw-r--r--drivers/media/pci/bt8xx/bttv-driver.c4
-rw-r--r--drivers/media/pci/cobalt/Kconfig2
-rw-r--r--drivers/media/pci/cx18/Kconfig2
-rw-r--r--drivers/media/pci/cx18/cx18-driver.c4
-rw-r--r--drivers/media/pci/cx18/cx18-dvb.c2
-rw-r--r--drivers/media/pci/cx18/cx18-gpio.c2
-rw-r--r--drivers/media/pci/cx18/cx18-queue.h6
-rw-r--r--drivers/media/pci/cx23885/cx23885-cards.c2
-rw-r--r--drivers/media/pci/cx23885/cx23885-dvb.c2
-rw-r--r--drivers/media/pci/cx23885/cx23885-input.c2
-rw-r--r--drivers/media/pci/cx23885/cx23885-video.c2
-rw-r--r--drivers/media/pci/cx88/cx88-mpeg.c3
-rw-r--r--drivers/media/pci/cx88/cx88.h2
-rw-r--r--drivers/media/pci/dt3155/Kconfig2
-rw-r--r--drivers/media/pci/intel/ipu3/Kconfig2
-rw-r--r--drivers/media/pci/ivtv/Kconfig2
-rw-r--r--drivers/media/pci/ivtv/ivtv-driver.c2
-rw-r--r--drivers/media/pci/ivtv/ivtv-driver.h1
-rw-r--r--drivers/media/pci/ivtv/ivtv-gpio.c2
-rw-r--r--drivers/media/pci/ivtv/ivtv-ioctl.c10
-rw-r--r--drivers/media/pci/ivtv/ivtv-queue.h25
-rw-r--r--drivers/media/pci/ivtv/ivtv-streams.c11
-rw-r--r--drivers/media/pci/ivtv/ivtv-udma.h8
-rw-r--r--drivers/media/pci/meye/Kconfig2
-rw-r--r--drivers/media/pci/saa7134/saa7134-alsa.c4
-rw-r--r--drivers/media/pci/saa7134/saa7134-cards.c2
-rw-r--r--drivers/media/pci/saa7134/saa7134-dvb.c2
-rw-r--r--drivers/media/pci/saa7134/saa7134-video.c11
-rw-r--r--drivers/media/pci/saa7146/Kconfig6
-rw-r--r--drivers/media/pci/saa7164/saa7164-cmd.c1
-rw-r--r--drivers/media/pci/sta2x11/Kconfig2
-rw-r--r--drivers/media/pci/tw5864/Kconfig2
-rw-r--r--drivers/media/pci/tw68/Kconfig2
-rw-r--r--drivers/media/pci/tw686x/Kconfig2
-rw-r--r--drivers/media/platform/Kconfig696
-rw-r--r--drivers/media/platform/Makefile110
-rw-r--r--drivers/media/platform/allegro-dvt/Kconfig19
-rw-r--r--drivers/media/platform/amlogic/Kconfig5
-rw-r--r--drivers/media/platform/amlogic/Makefile (renamed from arch/nds32/kernel/.gitignore)2
-rw-r--r--drivers/media/platform/amlogic/meson-ge2d/Kconfig14
-rw-r--r--drivers/media/platform/amlogic/meson-ge2d/Makefile (renamed from drivers/media/platform/meson/ge2d/Makefile)0
-rw-r--r--drivers/media/platform/amlogic/meson-ge2d/ge2d-regs.h (renamed from drivers/media/platform/meson/ge2d/ge2d-regs.h)0
-rw-r--r--drivers/media/platform/amlogic/meson-ge2d/ge2d.c (renamed from drivers/media/platform/meson/ge2d/ge2d.c)24
-rw-r--r--drivers/media/platform/amphion/Kconfig22
-rw-r--r--drivers/media/platform/amphion/Makefile20
-rw-r--r--drivers/media/platform/amphion/vdec.c1656
-rw-r--r--drivers/media/platform/amphion/venc.c1358
-rw-r--r--drivers/media/platform/amphion/vpu.h362
-rw-r--r--drivers/media/platform/amphion/vpu_cmds.c433
-rw-r--r--drivers/media/platform/amphion/vpu_cmds.h25
-rw-r--r--drivers/media/platform/amphion/vpu_codec.h68
-rw-r--r--drivers/media/platform/amphion/vpu_color.c183
-rw-r--r--drivers/media/platform/amphion/vpu_core.c879
-rw-r--r--drivers/media/platform/amphion/vpu_core.h15
-rw-r--r--drivers/media/platform/amphion/vpu_dbg.c494
-rw-r--r--drivers/media/platform/amphion/vpu_defs.h187
-rw-r--r--drivers/media/platform/amphion/vpu_drv.c261
-rw-r--r--drivers/media/platform/amphion/vpu_helpers.c414
-rw-r--r--drivers/media/platform/amphion/vpu_helpers.h71
-rw-r--r--drivers/media/platform/amphion/vpu_imx8q.c271
-rw-r--r--drivers/media/platform/amphion/vpu_imx8q.h115
-rw-r--r--drivers/media/platform/amphion/vpu_malone.c1644
-rw-r--r--drivers/media/platform/amphion/vpu_malone.h44
-rw-r--r--drivers/media/platform/amphion/vpu_mbox.c118
-rw-r--r--drivers/media/platform/amphion/vpu_mbox.h16
-rw-r--r--drivers/media/platform/amphion/vpu_msgs.c385
-rw-r--r--drivers/media/platform/amphion/vpu_msgs.h14
-rw-r--r--drivers/media/platform/amphion/vpu_rpc.c259
-rw-r--r--drivers/media/platform/amphion/vpu_rpc.h461
-rw-r--r--drivers/media/platform/amphion/vpu_v4l2.c713
-rw-r--r--drivers/media/platform/amphion/vpu_v4l2.h55
-rw-r--r--drivers/media/platform/amphion/vpu_windsor.c1173
-rw-r--r--drivers/media/platform/amphion/vpu_windsor.h37
-rw-r--r--drivers/media/platform/aspeed/Kconfig13
-rw-r--r--drivers/media/platform/aspeed/Makefile2
-rw-r--r--drivers/media/platform/aspeed/aspeed-video.c (renamed from drivers/media/platform/aspeed-video.c)301
-rw-r--r--drivers/media/platform/atmel/Kconfig28
-rw-r--r--drivers/media/platform/atmel/Makefile4
-rw-r--r--drivers/media/platform/atmel/atmel-isc-base.c397
-rw-r--r--drivers/media/platform/atmel/atmel-isc-clk.c311
-rw-r--r--drivers/media/platform/atmel/atmel-isc.h11
-rw-r--r--drivers/media/platform/atmel/atmel-sama5d2-isc.c24
-rw-r--r--drivers/media/platform/atmel/atmel-sama7g5-isc.c32
-rw-r--r--drivers/media/platform/atmel/microchip-csi2dc.c792
-rw-r--r--drivers/media/platform/cadence/Kconfig16
-rw-r--r--drivers/media/platform/chips-media/Kconfig20
-rw-r--r--drivers/media/platform/chips-media/Makefile (renamed from drivers/media/platform/coda/Makefile)0
-rw-r--r--drivers/media/platform/chips-media/coda-bit.c (renamed from drivers/media/platform/coda/coda-bit.c)0
-rw-r--r--drivers/media/platform/chips-media/coda-common.c (renamed from drivers/media/platform/coda/coda-common.c)1
-rw-r--r--drivers/media/platform/chips-media/coda-gdi.c (renamed from drivers/media/platform/coda/coda-gdi.c)0
-rw-r--r--drivers/media/platform/chips-media/coda-h264.c (renamed from drivers/media/platform/coda/coda-h264.c)0
-rw-r--r--drivers/media/platform/chips-media/coda-jpeg.c (renamed from drivers/media/platform/coda/coda-jpeg.c)0
-rw-r--r--drivers/media/platform/chips-media/coda-mpeg2.c (renamed from drivers/media/platform/coda/coda-mpeg2.c)0
-rw-r--r--drivers/media/platform/chips-media/coda-mpeg4.c (renamed from drivers/media/platform/coda/coda-mpeg4.c)0
-rw-r--r--drivers/media/platform/chips-media/coda.h (renamed from drivers/media/platform/coda/coda.h)0
-rw-r--r--drivers/media/platform/chips-media/coda_regs.h (renamed from drivers/media/platform/coda/coda_regs.h)2
-rw-r--r--drivers/media/platform/chips-media/imx-vdoa.c (renamed from drivers/media/platform/coda/imx-vdoa.c)9
-rw-r--r--drivers/media/platform/chips-media/imx-vdoa.h (renamed from drivers/media/platform/coda/imx-vdoa.h)0
-rw-r--r--drivers/media/platform/chips-media/trace.h (renamed from drivers/media/platform/coda/trace.h)2
-rw-r--r--drivers/media/platform/intel/Kconfig14
-rw-r--r--drivers/media/platform/intel/Makefile2
-rw-r--r--drivers/media/platform/intel/pxa_camera.c (renamed from drivers/media/platform/pxa_camera.c)21
-rw-r--r--drivers/media/platform/marvell/Kconfig (renamed from drivers/media/platform/marvell-ccic/Kconfig)9
-rw-r--r--drivers/media/platform/marvell/Makefile (renamed from drivers/media/platform/marvell-ccic/Makefile)0
-rw-r--r--drivers/media/platform/marvell/cafe-driver.c (renamed from drivers/media/platform/marvell-ccic/cafe-driver.c)0
-rw-r--r--drivers/media/platform/marvell/mcam-core.c (renamed from drivers/media/platform/marvell-ccic/mcam-core.c)0
-rw-r--r--drivers/media/platform/marvell/mcam-core.h (renamed from drivers/media/platform/marvell-ccic/mcam-core.h)0
-rw-r--r--drivers/media/platform/marvell/mmp-driver.c (renamed from drivers/media/platform/marvell-ccic/mmp-driver.c)8
-rw-r--r--drivers/media/platform/mediatek/Kconfig8
-rw-r--r--drivers/media/platform/mediatek/Makefile5
-rw-r--r--drivers/media/platform/mediatek/jpeg/Kconfig16
-rw-r--r--drivers/media/platform/mediatek/jpeg/Makefile (renamed from drivers/media/platform/mtk-jpeg/Makefile)0
-rw-r--r--drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c (renamed from drivers/media/platform/mtk-jpeg/mtk_jpeg_core.c)47
-rw-r--r--drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.h (renamed from drivers/media/platform/mtk-jpeg/mtk_jpeg_core.h)2
-rw-r--r--drivers/media/platform/mediatek/jpeg/mtk_jpeg_dec_hw.c (renamed from drivers/media/platform/mtk-jpeg/mtk_jpeg_dec_hw.c)0
-rw-r--r--drivers/media/platform/mediatek/jpeg/mtk_jpeg_dec_hw.h (renamed from drivers/media/platform/mtk-jpeg/mtk_jpeg_dec_hw.h)0
-rw-r--r--drivers/media/platform/mediatek/jpeg/mtk_jpeg_dec_parse.c (renamed from drivers/media/platform/mtk-jpeg/mtk_jpeg_dec_parse.c)0
-rw-r--r--drivers/media/platform/mediatek/jpeg/mtk_jpeg_dec_parse.h (renamed from drivers/media/platform/mtk-jpeg/mtk_jpeg_dec_parse.h)0
-rw-r--r--drivers/media/platform/mediatek/jpeg/mtk_jpeg_dec_reg.h (renamed from drivers/media/platform/mtk-jpeg/mtk_jpeg_dec_reg.h)0
-rw-r--r--drivers/media/platform/mediatek/jpeg/mtk_jpeg_enc_hw.c (renamed from drivers/media/platform/mtk-jpeg/mtk_jpeg_enc_hw.c)0
-rw-r--r--drivers/media/platform/mediatek/jpeg/mtk_jpeg_enc_hw.h (renamed from drivers/media/platform/mtk-jpeg/mtk_jpeg_enc_hw.h)0
-rw-r--r--drivers/media/platform/mediatek/mdp/Kconfig17
-rw-r--r--drivers/media/platform/mediatek/mdp/Makefile (renamed from drivers/media/platform/mtk-mdp/Makefile)2
-rw-r--r--drivers/media/platform/mediatek/mdp/mtk_mdp_comp.c (renamed from drivers/media/platform/mtk-mdp/mtk_mdp_comp.c)40
-rw-r--r--drivers/media/platform/mediatek/mdp/mtk_mdp_comp.h (renamed from drivers/media/platform/mtk-mdp/mtk_mdp_comp.h)2
-rw-r--r--drivers/media/platform/mediatek/mdp/mtk_mdp_core.c (renamed from drivers/media/platform/mtk-mdp/mtk_mdp_core.c)3
-rw-r--r--drivers/media/platform/mediatek/mdp/mtk_mdp_core.h (renamed from drivers/media/platform/mtk-mdp/mtk_mdp_core.h)0
-rw-r--r--drivers/media/platform/mediatek/mdp/mtk_mdp_ipi.h (renamed from drivers/media/platform/mtk-mdp/mtk_mdp_ipi.h)0
-rw-r--r--drivers/media/platform/mediatek/mdp/mtk_mdp_m2m.c (renamed from drivers/media/platform/mtk-mdp/mtk_mdp_m2m.c)0
-rw-r--r--drivers/media/platform/mediatek/mdp/mtk_mdp_m2m.h (renamed from drivers/media/platform/mtk-mdp/mtk_mdp_m2m.h)0
-rw-r--r--drivers/media/platform/mediatek/mdp/mtk_mdp_regs.c (renamed from drivers/media/platform/mtk-mdp/mtk_mdp_regs.c)0
-rw-r--r--drivers/media/platform/mediatek/mdp/mtk_mdp_regs.h (renamed from drivers/media/platform/mtk-mdp/mtk_mdp_regs.h)0
-rw-r--r--drivers/media/platform/mediatek/mdp/mtk_mdp_vpu.c (renamed from drivers/media/platform/mtk-mdp/mtk_mdp_vpu.c)0
-rw-r--r--drivers/media/platform/mediatek/mdp/mtk_mdp_vpu.h (renamed from drivers/media/platform/mtk-mdp/mtk_mdp_vpu.h)0
-rw-r--r--drivers/media/platform/mediatek/vcodec/Kconfig36
-rw-r--r--drivers/media/platform/mediatek/vcodec/Makefile (renamed from drivers/media/platform/mtk-vcodec/Makefile)6
-rw-r--r--drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec.c (renamed from drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c)4
-rw-r--r--drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec.h (renamed from drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.h)1
-rw-r--r--drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_drv.c (renamed from drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c)199
-rw-r--r--drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_hw.c200
-rw-r--r--drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_hw.h56
-rw-r--r--drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_pm.c169
-rw-r--r--drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_pm.h19
-rw-r--r--drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_stateful.c (renamed from drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateful.c)2
-rw-r--r--drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_stateless.c (renamed from drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c)21
-rw-r--r--drivers/media/platform/mediatek/vcodec/mtk_vcodec_drv.h (renamed from drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h)77
-rw-r--r--drivers/media/platform/mediatek/vcodec/mtk_vcodec_enc.c (renamed from drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.c)1
-rw-r--r--drivers/media/platform/mediatek/vcodec/mtk_vcodec_enc.h (renamed from drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.h)0
-rw-r--r--drivers/media/platform/mediatek/vcodec/mtk_vcodec_enc_drv.c (renamed from drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c)22
-rw-r--r--drivers/media/platform/mediatek/vcodec/mtk_vcodec_enc_pm.c (renamed from drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.c)55
-rw-r--r--drivers/media/platform/mediatek/vcodec/mtk_vcodec_enc_pm.h (renamed from drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.h)3
-rw-r--r--drivers/media/platform/mediatek/vcodec/mtk_vcodec_fw.c (renamed from drivers/media/platform/mtk-vcodec/mtk_vcodec_fw.c)0
-rw-r--r--drivers/media/platform/mediatek/vcodec/mtk_vcodec_fw.h (renamed from drivers/media/platform/mtk-vcodec/mtk_vcodec_fw.h)2
-rw-r--r--drivers/media/platform/mediatek/vcodec/mtk_vcodec_fw_priv.h (renamed from drivers/media/platform/mtk-vcodec/mtk_vcodec_fw_priv.h)0
-rw-r--r--drivers/media/platform/mediatek/vcodec/mtk_vcodec_fw_scp.c (renamed from drivers/media/platform/mtk-vcodec/mtk_vcodec_fw_scp.c)0
-rw-r--r--drivers/media/platform/mediatek/vcodec/mtk_vcodec_fw_vpu.c (renamed from drivers/media/platform/mtk-vcodec/mtk_vcodec_fw_vpu.c)2
-rw-r--r--drivers/media/platform/mediatek/vcodec/mtk_vcodec_intr.c43
-rw-r--r--drivers/media/platform/mediatek/vcodec/mtk_vcodec_intr.h (renamed from drivers/media/platform/mtk-vcodec/mtk_vcodec_intr.h)5
-rw-r--r--drivers/media/platform/mediatek/vcodec/mtk_vcodec_util.c (renamed from drivers/media/platform/mtk-vcodec/mtk_vcodec_util.c)59
-rw-r--r--drivers/media/platform/mediatek/vcodec/mtk_vcodec_util.h (renamed from drivers/media/platform/mtk-vcodec/mtk_vcodec_util.h)8
-rw-r--r--drivers/media/platform/mediatek/vcodec/vdec/vdec_h264_if.c (renamed from drivers/media/platform/mtk-vcodec/vdec/vdec_h264_if.c)2
-rw-r--r--drivers/media/platform/mediatek/vcodec/vdec/vdec_h264_req_if.c (renamed from drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_if.c)2
-rw-r--r--drivers/media/platform/mediatek/vcodec/vdec/vdec_vp8_if.c (renamed from drivers/media/platform/mtk-vcodec/vdec/vdec_vp8_if.c)2
-rw-r--r--drivers/media/platform/mediatek/vcodec/vdec/vdec_vp9_if.c (renamed from drivers/media/platform/mtk-vcodec/vdec/vdec_vp9_if.c)2
-rw-r--r--drivers/media/platform/mediatek/vcodec/vdec_drv_base.h (renamed from drivers/media/platform/mtk-vcodec/vdec_drv_base.h)0
-rw-r--r--drivers/media/platform/mediatek/vcodec/vdec_drv_if.c (renamed from drivers/media/platform/mtk-vcodec/vdec_drv_if.c)21
-rw-r--r--drivers/media/platform/mediatek/vcodec/vdec_drv_if.h (renamed from drivers/media/platform/mtk-vcodec/vdec_drv_if.h)0
-rw-r--r--drivers/media/platform/mediatek/vcodec/vdec_ipi_msg.h (renamed from drivers/media/platform/mtk-vcodec/vdec_ipi_msg.h)16
-rw-r--r--drivers/media/platform/mediatek/vcodec/vdec_msg_queue.c290
-rw-r--r--drivers/media/platform/mediatek/vcodec/vdec_msg_queue.h153
-rw-r--r--drivers/media/platform/mediatek/vcodec/vdec_vpu_if.c (renamed from drivers/media/platform/mtk-vcodec/vdec_vpu_if.c)46
-rw-r--r--drivers/media/platform/mediatek/vcodec/vdec_vpu_if.h (renamed from drivers/media/platform/mtk-vcodec/vdec_vpu_if.h)22
-rw-r--r--drivers/media/platform/mediatek/vcodec/venc/venc_h264_if.c (renamed from drivers/media/platform/mtk-vcodec/venc/venc_h264_if.c)2
-rw-r--r--drivers/media/platform/mediatek/vcodec/venc/venc_vp8_if.c (renamed from drivers/media/platform/mtk-vcodec/venc/venc_vp8_if.c)2
-rw-r--r--drivers/media/platform/mediatek/vcodec/venc_drv_base.h (renamed from drivers/media/platform/mtk-vcodec/venc_drv_base.h)0
-rw-r--r--drivers/media/platform/mediatek/vcodec/venc_drv_if.c (renamed from drivers/media/platform/mtk-vcodec/venc_drv_if.c)0
-rw-r--r--drivers/media/platform/mediatek/vcodec/venc_drv_if.h (renamed from drivers/media/platform/mtk-vcodec/venc_drv_if.h)0
-rw-r--r--drivers/media/platform/mediatek/vcodec/venc_ipi_msg.h (renamed from drivers/media/platform/mtk-vcodec/venc_ipi_msg.h)0
-rw-r--r--drivers/media/platform/mediatek/vcodec/venc_vpu_if.c (renamed from drivers/media/platform/mtk-vcodec/venc_vpu_if.c)0
-rw-r--r--drivers/media/platform/mediatek/vcodec/venc_vpu_if.h (renamed from drivers/media/platform/mtk-vcodec/venc_vpu_if.h)0
-rw-r--r--drivers/media/platform/mediatek/vpu/Kconfig15
-rw-r--r--drivers/media/platform/mediatek/vpu/Makefile (renamed from drivers/media/platform/mtk-vpu/Makefile)0
-rw-r--r--drivers/media/platform/mediatek/vpu/mtk_vpu.c (renamed from drivers/media/platform/mtk-vpu/mtk_vpu.c)10
-rw-r--r--drivers/media/platform/mediatek/vpu/mtk_vpu.h (renamed from drivers/media/platform/mtk-vpu/mtk_vpu.h)0
-rw-r--r--drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c145
-rw-r--r--drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.h20
-rw-r--r--drivers/media/platform/mtk-vcodec/mtk_vcodec_intr.c45
-rw-r--r--drivers/media/platform/nvidia/Kconfig5
-rw-r--r--drivers/media/platform/nvidia/Makefile (renamed from arch/nds32/include/uapi/asm/Kbuild)3
-rw-r--r--drivers/media/platform/nvidia/tegra-vde/Kconfig17
-rw-r--r--drivers/media/platform/nvidia/tegra-vde/Makefile3
-rw-r--r--drivers/media/platform/nvidia/tegra-vde/dmabuf-cache.c (renamed from drivers/staging/media/tegra-vde/dmabuf-cache.c)2
-rw-r--r--drivers/media/platform/nvidia/tegra-vde/h264.c946
-rw-r--r--drivers/media/platform/nvidia/tegra-vde/iommu.c (renamed from drivers/staging/media/tegra-vde/iommu.c)2
-rw-r--r--drivers/media/platform/nvidia/tegra-vde/trace.h (renamed from drivers/staging/media/tegra-vde/trace.h)2
-rw-r--r--drivers/media/platform/nvidia/tegra-vde/v4l2.c1018
-rw-r--r--drivers/media/platform/nvidia/tegra-vde/vde.c551
-rw-r--r--drivers/media/platform/nvidia/tegra-vde/vde.h242
-rw-r--r--drivers/media/platform/nxp/Kconfig55
-rw-r--r--drivers/media/platform/nxp/Makefile8
-rw-r--r--drivers/media/platform/nxp/fsl-viu.c (renamed from drivers/media/platform/fsl-viu.c)2
-rw-r--r--drivers/media/platform/nxp/imx-jpeg/Kconfig (renamed from drivers/media/platform/imx-jpeg/Kconfig)3
-rw-r--r--drivers/media/platform/nxp/imx-jpeg/Makefile (renamed from drivers/media/platform/imx-jpeg/Makefile)0
-rw-r--r--drivers/media/platform/nxp/imx-jpeg/mxc-jpeg-hw.c (renamed from drivers/media/platform/imx-jpeg/mxc-jpeg-hw.c)0
-rw-r--r--drivers/media/platform/nxp/imx-jpeg/mxc-jpeg-hw.h (renamed from drivers/media/platform/imx-jpeg/mxc-jpeg-hw.h)0
-rw-r--r--drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c (renamed from drivers/media/platform/imx-jpeg/mxc-jpeg.c)63
-rw-r--r--drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.h (renamed from drivers/media/platform/imx-jpeg/mxc-jpeg.h)1
-rw-r--r--drivers/media/platform/nxp/imx-mipi-csis.c (renamed from drivers/staging/media/imx/imx7-mipi-csis.c)123
-rw-r--r--drivers/media/platform/nxp/imx-pxp.c (renamed from drivers/media/platform/imx-pxp.c)0
-rw-r--r--drivers/media/platform/nxp/imx-pxp.h (renamed from drivers/media/platform/imx-pxp.h)0
-rw-r--r--drivers/media/platform/nxp/mx2_emmaprp.c (renamed from drivers/media/platform/mx2_emmaprp.c)0
-rw-r--r--drivers/media/platform/qcom/Kconfig6
-rw-r--r--drivers/media/platform/qcom/Makefile (renamed from arch/nds32/Kbuild)5
-rw-r--r--drivers/media/platform/qcom/camss/Kconfig9
-rw-r--r--drivers/media/platform/qcom/camss/Makefile3
-rw-r--r--drivers/media/platform/qcom/camss/camss-csid-gen2.c (renamed from drivers/media/platform/qcom/camss/camss-csid-170.c)34
-rw-r--r--drivers/media/platform/qcom/camss/camss-csid.c91
-rw-r--r--drivers/media/platform/qcom/camss/camss-csid.h5
-rw-r--r--drivers/media/platform/qcom/camss/camss-csiphy-2ph-1-0.c19
-rw-r--r--drivers/media/platform/qcom/camss/camss-csiphy-3ph-1-0.c199
-rw-r--r--drivers/media/platform/qcom/camss/camss-csiphy.c42
-rw-r--r--drivers/media/platform/qcom/camss/camss-csiphy.h7
-rw-r--r--drivers/media/platform/qcom/camss/camss-ispif.c12
-rw-r--r--drivers/media/platform/qcom/camss/camss-vfe-170.c12
-rw-r--r--drivers/media/platform/qcom/camss/camss-vfe-480.c564
-rw-r--r--drivers/media/platform/qcom/camss/camss-vfe.c29
-rw-r--r--drivers/media/platform/qcom/camss/camss-vfe.h4
-rw-r--r--drivers/media/platform/qcom/camss/camss-video.c5
-rw-r--r--drivers/media/platform/qcom/camss/camss.c368
-rw-r--r--drivers/media/platform/qcom/camss/camss.h20
-rw-r--r--drivers/media/platform/qcom/venus/Kconfig14
-rw-r--r--drivers/media/platform/qcom/venus/core.h4
-rw-r--r--drivers/media/platform/qcom/venus/helpers.c2
-rw-r--r--drivers/media/platform/qcom/venus/hfi_cmds.c2
-rw-r--r--drivers/media/platform/qcom/venus/venc.c4
-rw-r--r--drivers/media/platform/qcom/venus/venc_ctrls.c6
-rw-r--r--drivers/media/platform/renesas/Kconfig121
-rw-r--r--drivers/media/platform/renesas/Makefile15
-rw-r--r--drivers/media/platform/renesas/rcar-fcp.c (renamed from drivers/media/platform/rcar-fcp.c)0
-rw-r--r--drivers/media/platform/renesas/rcar-isp.c (renamed from drivers/media/platform/rcar-isp.c)32
-rw-r--r--drivers/media/platform/renesas/rcar-vin/Kconfig (renamed from drivers/media/platform/rcar-vin/Kconfig)6
-rw-r--r--drivers/media/platform/renesas/rcar-vin/Makefile (renamed from drivers/media/platform/rcar-vin/Makefile)0
-rw-r--r--drivers/media/platform/renesas/rcar-vin/rcar-core.c (renamed from drivers/media/platform/rcar-vin/rcar-core.c)389
-rw-r--r--drivers/media/platform/renesas/rcar-vin/rcar-csi2.c (renamed from drivers/media/platform/rcar-vin/rcar-csi2.c)132
-rw-r--r--drivers/media/platform/renesas/rcar-vin/rcar-dma.c (renamed from drivers/media/platform/rcar-vin/rcar-dma.c)2
-rw-r--r--drivers/media/platform/renesas/rcar-vin/rcar-v4l2.c (renamed from drivers/media/platform/rcar-vin/rcar-v4l2.c)0
-rw-r--r--drivers/media/platform/renesas/rcar-vin/rcar-vin.h (renamed from drivers/media/platform/rcar-vin/rcar-vin.h)20
-rw-r--r--drivers/media/platform/renesas/rcar_drif.c (renamed from drivers/media/platform/rcar_drif.c)0
-rw-r--r--drivers/media/platform/renesas/rcar_fdp1.c (renamed from drivers/media/platform/rcar_fdp1.c)0
-rw-r--r--drivers/media/platform/renesas/rcar_jpu.c (renamed from drivers/media/platform/rcar_jpu.c)2
-rw-r--r--drivers/media/platform/renesas/renesas-ceu.c (renamed from drivers/media/platform/renesas-ceu.c)0
-rw-r--r--drivers/media/platform/renesas/sh_vou.c (renamed from drivers/media/platform/sh_vou.c)0
-rw-r--r--drivers/media/platform/renesas/vsp1/Makefile (renamed from drivers/media/platform/vsp1/Makefile)0
-rw-r--r--drivers/media/platform/renesas/vsp1/vsp1.h (renamed from drivers/media/platform/vsp1/vsp1.h)0
-rw-r--r--drivers/media/platform/renesas/vsp1/vsp1_brx.c (renamed from drivers/media/platform/vsp1/vsp1_brx.c)0
-rw-r--r--drivers/media/platform/renesas/vsp1/vsp1_brx.h (renamed from drivers/media/platform/vsp1/vsp1_brx.h)0
-rw-r--r--drivers/media/platform/renesas/vsp1/vsp1_clu.c (renamed from drivers/media/platform/vsp1/vsp1_clu.c)0
-rw-r--r--drivers/media/platform/renesas/vsp1/vsp1_clu.h (renamed from drivers/media/platform/vsp1/vsp1_clu.h)0
-rw-r--r--drivers/media/platform/renesas/vsp1/vsp1_dl.c (renamed from drivers/media/platform/vsp1/vsp1_dl.c)0
-rw-r--r--drivers/media/platform/renesas/vsp1/vsp1_dl.h (renamed from drivers/media/platform/vsp1/vsp1_dl.h)0
-rw-r--r--drivers/media/platform/renesas/vsp1/vsp1_drm.c (renamed from drivers/media/platform/vsp1/vsp1_drm.c)0
-rw-r--r--drivers/media/platform/renesas/vsp1/vsp1_drm.h (renamed from drivers/media/platform/vsp1/vsp1_drm.h)0
-rw-r--r--drivers/media/platform/renesas/vsp1/vsp1_drv.c (renamed from drivers/media/platform/vsp1/vsp1_drv.c)47
-rw-r--r--drivers/media/platform/renesas/vsp1/vsp1_entity.c (renamed from drivers/media/platform/vsp1/vsp1_entity.c)0
-rw-r--r--drivers/media/platform/renesas/vsp1/vsp1_entity.h (renamed from drivers/media/platform/vsp1/vsp1_entity.h)0
-rw-r--r--drivers/media/platform/renesas/vsp1/vsp1_hgo.c (renamed from drivers/media/platform/vsp1/vsp1_hgo.c)0
-rw-r--r--drivers/media/platform/renesas/vsp1/vsp1_hgo.h (renamed from drivers/media/platform/vsp1/vsp1_hgo.h)0
-rw-r--r--drivers/media/platform/renesas/vsp1/vsp1_hgt.c (renamed from drivers/media/platform/vsp1/vsp1_hgt.c)0
-rw-r--r--drivers/media/platform/renesas/vsp1/vsp1_hgt.h (renamed from drivers/media/platform/vsp1/vsp1_hgt.h)0
-rw-r--r--drivers/media/platform/renesas/vsp1/vsp1_histo.c (renamed from drivers/media/platform/vsp1/vsp1_histo.c)0
-rw-r--r--drivers/media/platform/renesas/vsp1/vsp1_histo.h (renamed from drivers/media/platform/vsp1/vsp1_histo.h)0
-rw-r--r--drivers/media/platform/renesas/vsp1/vsp1_hsit.c (renamed from drivers/media/platform/vsp1/vsp1_hsit.c)0
-rw-r--r--drivers/media/platform/renesas/vsp1/vsp1_hsit.h (renamed from drivers/media/platform/vsp1/vsp1_hsit.h)0
-rw-r--r--drivers/media/platform/renesas/vsp1/vsp1_lif.c (renamed from drivers/media/platform/vsp1/vsp1_lif.c)0
-rw-r--r--drivers/media/platform/renesas/vsp1/vsp1_lif.h (renamed from drivers/media/platform/vsp1/vsp1_lif.h)0
-rw-r--r--drivers/media/platform/renesas/vsp1/vsp1_lut.c (renamed from drivers/media/platform/vsp1/vsp1_lut.c)0
-rw-r--r--drivers/media/platform/renesas/vsp1/vsp1_lut.h (renamed from drivers/media/platform/vsp1/vsp1_lut.h)0
-rw-r--r--drivers/media/platform/renesas/vsp1/vsp1_pipe.c (renamed from drivers/media/platform/vsp1/vsp1_pipe.c)0
-rw-r--r--drivers/media/platform/renesas/vsp1/vsp1_pipe.h (renamed from drivers/media/platform/vsp1/vsp1_pipe.h)0
-rw-r--r--drivers/media/platform/renesas/vsp1/vsp1_regs.h (renamed from drivers/media/platform/vsp1/vsp1_regs.h)0
-rw-r--r--drivers/media/platform/renesas/vsp1/vsp1_rpf.c (renamed from drivers/media/platform/vsp1/vsp1_rpf.c)0
-rw-r--r--drivers/media/platform/renesas/vsp1/vsp1_rwpf.c (renamed from drivers/media/platform/vsp1/vsp1_rwpf.c)0
-rw-r--r--drivers/media/platform/renesas/vsp1/vsp1_rwpf.h (renamed from drivers/media/platform/vsp1/vsp1_rwpf.h)0
-rw-r--r--drivers/media/platform/renesas/vsp1/vsp1_sru.c (renamed from drivers/media/platform/vsp1/vsp1_sru.c)0
-rw-r--r--drivers/media/platform/renesas/vsp1/vsp1_sru.h (renamed from drivers/media/platform/vsp1/vsp1_sru.h)0
-rw-r--r--drivers/media/platform/renesas/vsp1/vsp1_uds.c (renamed from drivers/media/platform/vsp1/vsp1_uds.c)0
-rw-r--r--drivers/media/platform/renesas/vsp1/vsp1_uds.h (renamed from drivers/media/platform/vsp1/vsp1_uds.h)0
-rw-r--r--drivers/media/platform/renesas/vsp1/vsp1_uif.c (renamed from drivers/media/platform/vsp1/vsp1_uif.c)0
-rw-r--r--drivers/media/platform/renesas/vsp1/vsp1_uif.h (renamed from drivers/media/platform/vsp1/vsp1_uif.h)0
-rw-r--r--drivers/media/platform/renesas/vsp1/vsp1_video.c (renamed from drivers/media/platform/vsp1/vsp1_video.c)0
-rw-r--r--drivers/media/platform/renesas/vsp1/vsp1_video.h (renamed from drivers/media/platform/vsp1/vsp1_video.h)0
-rw-r--r--drivers/media/platform/renesas/vsp1/vsp1_wpf.c (renamed from drivers/media/platform/vsp1/vsp1_wpf.c)0
-rw-r--r--drivers/media/platform/rockchip/Kconfig6
-rw-r--r--drivers/media/platform/rockchip/Makefile (renamed from arch/nds32/Kconfig.debug)3
-rw-r--r--drivers/media/platform/rockchip/rga/Kconfig14
-rw-r--r--drivers/media/platform/rockchip/rkisp1/Kconfig19
-rw-r--r--drivers/media/platform/rockchip/rkisp1/rkisp1-capture.c28
-rw-r--r--drivers/media/platform/samsung/Kconfig10
-rw-r--r--drivers/media/platform/samsung/Makefile7
-rw-r--r--drivers/media/platform/samsung/exynos-gsc/Kconfig10
-rw-r--r--drivers/media/platform/samsung/exynos-gsc/Makefile (renamed from drivers/media/platform/exynos-gsc/Makefile)0
-rw-r--r--drivers/media/platform/samsung/exynos-gsc/gsc-core.c (renamed from drivers/media/platform/exynos-gsc/gsc-core.c)14
-rw-r--r--drivers/media/platform/samsung/exynos-gsc/gsc-core.h (renamed from drivers/media/platform/exynos-gsc/gsc-core.h)0
-rw-r--r--drivers/media/platform/samsung/exynos-gsc/gsc-m2m.c (renamed from drivers/media/platform/exynos-gsc/gsc-m2m.c)0
-rw-r--r--drivers/media/platform/samsung/exynos-gsc/gsc-regs.c (renamed from drivers/media/platform/exynos-gsc/gsc-regs.c)0
-rw-r--r--drivers/media/platform/samsung/exynos-gsc/gsc-regs.h (renamed from drivers/media/platform/exynos-gsc/gsc-regs.h)0
-rw-r--r--drivers/media/platform/samsung/exynos4-is/Kconfig (renamed from drivers/media/platform/exynos4-is/Kconfig)3
-rw-r--r--drivers/media/platform/samsung/exynos4-is/Makefile (renamed from drivers/media/platform/exynos4-is/Makefile)0
-rw-r--r--drivers/media/platform/samsung/exynos4-is/common.c (renamed from drivers/media/platform/exynos4-is/common.c)5
-rw-r--r--drivers/media/platform/samsung/exynos4-is/common.h (renamed from drivers/media/platform/exynos4-is/common.h)0
-rw-r--r--drivers/media/platform/samsung/exynos4-is/fimc-capture.c (renamed from drivers/media/platform/exynos4-is/fimc-capture.c)0
-rw-r--r--drivers/media/platform/samsung/exynos4-is/fimc-core.c (renamed from drivers/media/platform/exynos4-is/fimc-core.c)11
-rw-r--r--drivers/media/platform/samsung/exynos4-is/fimc-core.h (renamed from drivers/media/platform/exynos4-is/fimc-core.h)0
-rw-r--r--drivers/media/platform/samsung/exynos4-is/fimc-is-command.h (renamed from drivers/media/platform/exynos4-is/fimc-is-command.h)0
-rw-r--r--drivers/media/platform/samsung/exynos4-is/fimc-is-errno.c (renamed from drivers/media/platform/exynos4-is/fimc-is-errno.c)0
-rw-r--r--drivers/media/platform/samsung/exynos4-is/fimc-is-errno.h (renamed from drivers/media/platform/exynos4-is/fimc-is-errno.h)0
-rw-r--r--drivers/media/platform/samsung/exynos4-is/fimc-is-i2c.c (renamed from drivers/media/platform/exynos4-is/fimc-is-i2c.c)0
-rw-r--r--drivers/media/platform/samsung/exynos4-is/fimc-is-i2c.h (renamed from drivers/media/platform/exynos4-is/fimc-is-i2c.h)0
-rw-r--r--drivers/media/platform/samsung/exynos4-is/fimc-is-param.c (renamed from drivers/media/platform/exynos4-is/fimc-is-param.c)0
-rw-r--r--drivers/media/platform/samsung/exynos4-is/fimc-is-param.h (renamed from drivers/media/platform/exynos4-is/fimc-is-param.h)0
-rw-r--r--drivers/media/platform/samsung/exynos4-is/fimc-is-regs.c (renamed from drivers/media/platform/exynos4-is/fimc-is-regs.c)0
-rw-r--r--drivers/media/platform/samsung/exynos4-is/fimc-is-regs.h (renamed from drivers/media/platform/exynos4-is/fimc-is-regs.h)0
-rw-r--r--drivers/media/platform/samsung/exynos4-is/fimc-is-sensor.c (renamed from drivers/media/platform/exynos4-is/fimc-is-sensor.c)0
-rw-r--r--drivers/media/platform/samsung/exynos4-is/fimc-is-sensor.h (renamed from drivers/media/platform/exynos4-is/fimc-is-sensor.h)0
-rw-r--r--drivers/media/platform/samsung/exynos4-is/fimc-is.c (renamed from drivers/media/platform/exynos4-is/fimc-is.c)0
-rw-r--r--drivers/media/platform/samsung/exynos4-is/fimc-is.h (renamed from drivers/media/platform/exynos4-is/fimc-is.h)0
-rw-r--r--drivers/media/platform/samsung/exynos4-is/fimc-isp-video.c (renamed from drivers/media/platform/exynos4-is/fimc-isp-video.c)0
-rw-r--r--drivers/media/platform/samsung/exynos4-is/fimc-isp-video.h (renamed from drivers/media/platform/exynos4-is/fimc-isp-video.h)0
-rw-r--r--drivers/media/platform/samsung/exynos4-is/fimc-isp.c (renamed from drivers/media/platform/exynos4-is/fimc-isp.c)2
-rw-r--r--drivers/media/platform/samsung/exynos4-is/fimc-isp.h (renamed from drivers/media/platform/exynos4-is/fimc-isp.h)0
-rw-r--r--drivers/media/platform/samsung/exynos4-is/fimc-lite-reg.c (renamed from drivers/media/platform/exynos4-is/fimc-lite-reg.c)0
-rw-r--r--drivers/media/platform/samsung/exynos4-is/fimc-lite-reg.h (renamed from drivers/media/platform/exynos4-is/fimc-lite-reg.h)0
-rw-r--r--drivers/media/platform/samsung/exynos4-is/fimc-lite.c (renamed from drivers/media/platform/exynos4-is/fimc-lite.c)17
-rw-r--r--drivers/media/platform/samsung/exynos4-is/fimc-lite.h (renamed from drivers/media/platform/exynos4-is/fimc-lite.h)0
-rw-r--r--drivers/media/platform/samsung/exynos4-is/fimc-m2m.c (renamed from drivers/media/platform/exynos4-is/fimc-m2m.c)0
-rw-r--r--drivers/media/platform/samsung/exynos4-is/fimc-reg.c (renamed from drivers/media/platform/exynos4-is/fimc-reg.c)0
-rw-r--r--drivers/media/platform/samsung/exynos4-is/fimc-reg.h (renamed from drivers/media/platform/exynos4-is/fimc-reg.h)0
-rw-r--r--drivers/media/platform/samsung/exynos4-is/media-dev.c (renamed from drivers/media/platform/exynos4-is/media-dev.c)0
-rw-r--r--drivers/media/platform/samsung/exynos4-is/media-dev.h (renamed from drivers/media/platform/exynos4-is/media-dev.h)0
-rw-r--r--drivers/media/platform/samsung/exynos4-is/mipi-csis.c (renamed from drivers/media/platform/exynos4-is/mipi-csis.c)0
-rw-r--r--drivers/media/platform/samsung/exynos4-is/mipi-csis.h (renamed from drivers/media/platform/exynos4-is/mipi-csis.h)0
-rw-r--r--drivers/media/platform/samsung/s3c-camif/Kconfig15
-rw-r--r--drivers/media/platform/samsung/s3c-camif/Makefile (renamed from drivers/media/platform/s3c-camif/Makefile)0
-rw-r--r--drivers/media/platform/samsung/s3c-camif/camif-capture.c (renamed from drivers/media/platform/s3c-camif/camif-capture.c)0
-rw-r--r--drivers/media/platform/samsung/s3c-camif/camif-core.c (renamed from drivers/media/platform/s3c-camif/camif-core.c)0
-rw-r--r--drivers/media/platform/samsung/s3c-camif/camif-core.h (renamed from drivers/media/platform/s3c-camif/camif-core.h)0
-rw-r--r--drivers/media/platform/samsung/s3c-camif/camif-regs.c (renamed from drivers/media/platform/s3c-camif/camif-regs.c)0
-rw-r--r--drivers/media/platform/samsung/s3c-camif/camif-regs.h (renamed from drivers/media/platform/s3c-camif/camif-regs.h)0
-rw-r--r--drivers/media/platform/samsung/s5p-g2d/Kconfig11
-rw-r--r--drivers/media/platform/samsung/s5p-g2d/Makefile (renamed from drivers/media/platform/s5p-g2d/Makefile)0
-rw-r--r--drivers/media/platform/samsung/s5p-g2d/g2d-hw.c (renamed from drivers/media/platform/s5p-g2d/g2d-hw.c)0
-rw-r--r--drivers/media/platform/samsung/s5p-g2d/g2d-regs.h (renamed from drivers/media/platform/s5p-g2d/g2d-regs.h)0
-rw-r--r--drivers/media/platform/samsung/s5p-g2d/g2d.c (renamed from drivers/media/platform/s5p-g2d/g2d.c)10
-rw-r--r--drivers/media/platform/samsung/s5p-g2d/g2d.h (renamed from drivers/media/platform/s5p-g2d/g2d.h)0
-rw-r--r--drivers/media/platform/samsung/s5p-jpeg/Kconfig12
-rw-r--r--drivers/media/platform/samsung/s5p-jpeg/Makefile (renamed from drivers/media/platform/s5p-jpeg/Makefile)0
-rw-r--r--drivers/media/platform/samsung/s5p-jpeg/jpeg-core.c (renamed from drivers/media/platform/s5p-jpeg/jpeg-core.c)2
-rw-r--r--drivers/media/platform/samsung/s5p-jpeg/jpeg-core.h (renamed from drivers/media/platform/s5p-jpeg/jpeg-core.h)2
-rw-r--r--drivers/media/platform/samsung/s5p-jpeg/jpeg-hw-exynos3250.c (renamed from drivers/media/platform/s5p-jpeg/jpeg-hw-exynos3250.c)0
-rw-r--r--drivers/media/platform/samsung/s5p-jpeg/jpeg-hw-exynos3250.h (renamed from drivers/media/platform/s5p-jpeg/jpeg-hw-exynos3250.h)2
-rw-r--r--drivers/media/platform/samsung/s5p-jpeg/jpeg-hw-exynos4.c (renamed from drivers/media/platform/s5p-jpeg/jpeg-hw-exynos4.c)0
-rw-r--r--drivers/media/platform/samsung/s5p-jpeg/jpeg-hw-exynos4.h (renamed from drivers/media/platform/s5p-jpeg/jpeg-hw-exynos4.h)0
-rw-r--r--drivers/media/platform/samsung/s5p-jpeg/jpeg-hw-s5p.c (renamed from drivers/media/platform/s5p-jpeg/jpeg-hw-s5p.c)2
-rw-r--r--drivers/media/platform/samsung/s5p-jpeg/jpeg-hw-s5p.h (renamed from drivers/media/platform/s5p-jpeg/jpeg-hw-s5p.h)2
-rw-r--r--drivers/media/platform/samsung/s5p-jpeg/jpeg-regs.h (renamed from drivers/media/platform/s5p-jpeg/jpeg-regs.h)2
-rw-r--r--drivers/media/platform/samsung/s5p-mfc/Kconfig9
-rw-r--r--drivers/media/platform/samsung/s5p-mfc/Makefile (renamed from drivers/media/platform/s5p-mfc/Makefile)0
-rw-r--r--drivers/media/platform/samsung/s5p-mfc/regs-mfc-v10.h (renamed from drivers/media/platform/s5p-mfc/regs-mfc-v10.h)0
-rw-r--r--drivers/media/platform/samsung/s5p-mfc/regs-mfc-v6.h (renamed from drivers/media/platform/s5p-mfc/regs-mfc-v6.h)0
-rw-r--r--drivers/media/platform/samsung/s5p-mfc/regs-mfc-v7.h (renamed from drivers/media/platform/s5p-mfc/regs-mfc-v7.h)0
-rw-r--r--drivers/media/platform/samsung/s5p-mfc/regs-mfc-v8.h (renamed from drivers/media/platform/s5p-mfc/regs-mfc-v8.h)0
-rw-r--r--drivers/media/platform/samsung/s5p-mfc/regs-mfc.h (renamed from drivers/media/platform/s5p-mfc/regs-mfc.h)0
-rw-r--r--drivers/media/platform/samsung/s5p-mfc/s5p_mfc.c (renamed from drivers/media/platform/s5p-mfc/s5p_mfc.c)11
-rw-r--r--drivers/media/platform/samsung/s5p-mfc/s5p_mfc_cmd.c (renamed from drivers/media/platform/s5p-mfc/s5p_mfc_cmd.c)2
-rw-r--r--drivers/media/platform/samsung/s5p-mfc/s5p_mfc_cmd.h (renamed from drivers/media/platform/s5p-mfc/s5p_mfc_cmd.h)2
-rw-r--r--drivers/media/platform/samsung/s5p-mfc/s5p_mfc_cmd_v5.c (renamed from drivers/media/platform/s5p-mfc/s5p_mfc_cmd_v5.c)2
-rw-r--r--drivers/media/platform/samsung/s5p-mfc/s5p_mfc_cmd_v5.h (renamed from drivers/media/platform/s5p-mfc/s5p_mfc_cmd_v5.h)2
-rw-r--r--drivers/media/platform/samsung/s5p-mfc/s5p_mfc_cmd_v6.c (renamed from drivers/media/platform/s5p-mfc/s5p_mfc_cmd_v6.c)2
-rw-r--r--drivers/media/platform/samsung/s5p-mfc/s5p_mfc_cmd_v6.h (renamed from drivers/media/platform/s5p-mfc/s5p_mfc_cmd_v6.h)2
-rw-r--r--drivers/media/platform/samsung/s5p-mfc/s5p_mfc_common.h (renamed from drivers/media/platform/s5p-mfc/s5p_mfc_common.h)1
-rw-r--r--drivers/media/platform/samsung/s5p-mfc/s5p_mfc_ctrl.c (renamed from drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.c)2
-rw-r--r--drivers/media/platform/samsung/s5p-mfc/s5p_mfc_ctrl.h (renamed from drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.h)2
-rw-r--r--drivers/media/platform/samsung/s5p-mfc/s5p_mfc_debug.h (renamed from drivers/media/platform/s5p-mfc/s5p_mfc_debug.h)2
-rw-r--r--drivers/media/platform/samsung/s5p-mfc/s5p_mfc_dec.c (renamed from drivers/media/platform/s5p-mfc/s5p_mfc_dec.c)20
-rw-r--r--drivers/media/platform/samsung/s5p-mfc/s5p_mfc_dec.h (renamed from drivers/media/platform/s5p-mfc/s5p_mfc_dec.h)2
-rw-r--r--drivers/media/platform/samsung/s5p-mfc/s5p_mfc_enc.c (renamed from drivers/media/platform/s5p-mfc/s5p_mfc_enc.c)2
-rw-r--r--drivers/media/platform/samsung/s5p-mfc/s5p_mfc_enc.h (renamed from drivers/media/platform/s5p-mfc/s5p_mfc_enc.h)2
-rw-r--r--drivers/media/platform/samsung/s5p-mfc/s5p_mfc_intr.c (renamed from drivers/media/platform/s5p-mfc/s5p_mfc_intr.c)0
-rw-r--r--drivers/media/platform/samsung/s5p-mfc/s5p_mfc_intr.h (renamed from drivers/media/platform/s5p-mfc/s5p_mfc_intr.h)0
-rw-r--r--drivers/media/platform/samsung/s5p-mfc/s5p_mfc_iommu.h (renamed from drivers/media/platform/s5p-mfc/s5p_mfc_iommu.h)0
-rw-r--r--drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr.c (renamed from drivers/media/platform/s5p-mfc/s5p_mfc_opr.c)2
-rw-r--r--drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr.h (renamed from drivers/media/platform/s5p-mfc/s5p_mfc_opr.h)2
-rw-r--r--drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v5.c (renamed from drivers/media/platform/s5p-mfc/s5p_mfc_opr_v5.c)0
-rw-r--r--drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v5.h (renamed from drivers/media/platform/s5p-mfc/s5p_mfc_opr_v5.h)0
-rw-r--r--drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c (renamed from drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.c)2
-rw-r--r--drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.h (renamed from drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.h)2
-rw-r--r--drivers/media/platform/samsung/s5p-mfc/s5p_mfc_pm.c (renamed from drivers/media/platform/s5p-mfc/s5p_mfc_pm.c)2
-rw-r--r--drivers/media/platform/samsung/s5p-mfc/s5p_mfc_pm.h (renamed from drivers/media/platform/s5p-mfc/s5p_mfc_pm.h)2
-rw-r--r--drivers/media/platform/st/Kconfig6
-rw-r--r--drivers/media/platform/st/Makefile7
-rw-r--r--drivers/media/platform/st/sti/Kconfig5
-rw-r--r--drivers/media/platform/st/sti/Makefile6
-rw-r--r--drivers/media/platform/st/sti/bdisp/Kconfig10
-rw-r--r--drivers/media/platform/st/sti/bdisp/Makefile (renamed from drivers/media/platform/sti/bdisp/Makefile)0
-rw-r--r--drivers/media/platform/st/sti/bdisp/bdisp-debug.c (renamed from drivers/media/platform/sti/bdisp/bdisp-debug.c)0
-rw-r--r--drivers/media/platform/st/sti/bdisp/bdisp-filter.h (renamed from drivers/media/platform/sti/bdisp/bdisp-filter.h)0
-rw-r--r--drivers/media/platform/st/sti/bdisp/bdisp-hw.c (renamed from drivers/media/platform/sti/bdisp/bdisp-hw.c)0
-rw-r--r--drivers/media/platform/st/sti/bdisp/bdisp-reg.h (renamed from drivers/media/platform/sti/bdisp/bdisp-reg.h)0
-rw-r--r--drivers/media/platform/st/sti/bdisp/bdisp-v4l2.c (renamed from drivers/media/platform/sti/bdisp/bdisp-v4l2.c)10
-rw-r--r--drivers/media/platform/st/sti/bdisp/bdisp.h (renamed from drivers/media/platform/sti/bdisp/bdisp.h)0
-rw-r--r--drivers/media/platform/st/sti/c8sectpfe/Kconfig (renamed from drivers/media/platform/sti/c8sectpfe/Kconfig)1
-rw-r--r--drivers/media/platform/st/sti/c8sectpfe/Makefile (renamed from drivers/media/platform/sti/c8sectpfe/Makefile)0
-rw-r--r--drivers/media/platform/st/sti/c8sectpfe/c8sectpfe-common.c (renamed from drivers/media/platform/sti/c8sectpfe/c8sectpfe-common.c)0
-rw-r--r--drivers/media/platform/st/sti/c8sectpfe/c8sectpfe-common.h (renamed from drivers/media/platform/sti/c8sectpfe/c8sectpfe-common.h)0
-rw-r--r--drivers/media/platform/st/sti/c8sectpfe/c8sectpfe-core.c (renamed from drivers/media/platform/sti/c8sectpfe/c8sectpfe-core.c)0
-rw-r--r--drivers/media/platform/st/sti/c8sectpfe/c8sectpfe-core.h (renamed from drivers/media/platform/sti/c8sectpfe/c8sectpfe-core.h)0
-rw-r--r--drivers/media/platform/st/sti/c8sectpfe/c8sectpfe-debugfs.c (renamed from drivers/media/platform/sti/c8sectpfe/c8sectpfe-debugfs.c)0
-rw-r--r--drivers/media/platform/st/sti/c8sectpfe/c8sectpfe-debugfs.h (renamed from drivers/media/platform/sti/c8sectpfe/c8sectpfe-debugfs.h)0
-rw-r--r--drivers/media/platform/st/sti/c8sectpfe/c8sectpfe-dvb.c (renamed from drivers/media/platform/sti/c8sectpfe/c8sectpfe-dvb.c)0
-rw-r--r--drivers/media/platform/st/sti/c8sectpfe/c8sectpfe-dvb.h (renamed from drivers/media/platform/sti/c8sectpfe/c8sectpfe-dvb.h)0
-rw-r--r--drivers/media/platform/st/sti/delta/Kconfig36
-rw-r--r--drivers/media/platform/st/sti/delta/Makefile (renamed from drivers/media/platform/sti/delta/Makefile)0
-rw-r--r--drivers/media/platform/st/sti/delta/delta-cfg.h (renamed from drivers/media/platform/sti/delta/delta-cfg.h)0
-rw-r--r--drivers/media/platform/st/sti/delta/delta-debug.c (renamed from drivers/media/platform/sti/delta/delta-debug.c)0
-rw-r--r--drivers/media/platform/st/sti/delta/delta-debug.h (renamed from drivers/media/platform/sti/delta/delta-debug.h)0
-rw-r--r--drivers/media/platform/st/sti/delta/delta-ipc.c (renamed from drivers/media/platform/sti/delta/delta-ipc.c)0
-rw-r--r--drivers/media/platform/st/sti/delta/delta-ipc.h (renamed from drivers/media/platform/sti/delta/delta-ipc.h)0
-rw-r--r--drivers/media/platform/st/sti/delta/delta-mem.c (renamed from drivers/media/platform/sti/delta/delta-mem.c)0
-rw-r--r--drivers/media/platform/st/sti/delta/delta-mem.h (renamed from drivers/media/platform/sti/delta/delta-mem.h)0
-rw-r--r--drivers/media/platform/st/sti/delta/delta-mjpeg-dec.c (renamed from drivers/media/platform/sti/delta/delta-mjpeg-dec.c)0
-rw-r--r--drivers/media/platform/st/sti/delta/delta-mjpeg-fw.h (renamed from drivers/media/platform/sti/delta/delta-mjpeg-fw.h)0
-rw-r--r--drivers/media/platform/st/sti/delta/delta-mjpeg-hdr.c (renamed from drivers/media/platform/sti/delta/delta-mjpeg-hdr.c)0
-rw-r--r--drivers/media/platform/st/sti/delta/delta-mjpeg.h (renamed from drivers/media/platform/sti/delta/delta-mjpeg.h)0
-rw-r--r--drivers/media/platform/st/sti/delta/delta-v4l2.c (renamed from drivers/media/platform/sti/delta/delta-v4l2.c)0
-rw-r--r--drivers/media/platform/st/sti/delta/delta.h (renamed from drivers/media/platform/sti/delta/delta.h)0
-rw-r--r--drivers/media/platform/st/sti/hva/Kconfig26
-rw-r--r--drivers/media/platform/st/sti/hva/Makefile (renamed from drivers/media/platform/sti/hva/Makefile)0
-rw-r--r--drivers/media/platform/st/sti/hva/hva-debugfs.c (renamed from drivers/media/platform/sti/hva/hva-debugfs.c)0
-rw-r--r--drivers/media/platform/st/sti/hva/hva-h264.c (renamed from drivers/media/platform/sti/hva/hva-h264.c)0
-rw-r--r--drivers/media/platform/st/sti/hva/hva-hw.c (renamed from drivers/media/platform/sti/hva/hva-hw.c)0
-rw-r--r--drivers/media/platform/st/sti/hva/hva-hw.h (renamed from drivers/media/platform/sti/hva/hva-hw.h)0
-rw-r--r--drivers/media/platform/st/sti/hva/hva-mem.c (renamed from drivers/media/platform/sti/hva/hva-mem.c)0
-rw-r--r--drivers/media/platform/st/sti/hva/hva-mem.h (renamed from drivers/media/platform/sti/hva/hva-mem.h)0
-rw-r--r--drivers/media/platform/st/sti/hva/hva-v4l2.c (renamed from drivers/media/platform/sti/hva/hva-v4l2.c)0
-rw-r--r--drivers/media/platform/st/sti/hva/hva.h (renamed from drivers/media/platform/sti/hva/hva.h)0
-rw-r--r--drivers/media/platform/st/stm32/Kconfig31
-rw-r--r--drivers/media/platform/st/stm32/Makefile (renamed from drivers/media/platform/stm32/Makefile)0
-rw-r--r--drivers/media/platform/st/stm32/dma2d/dma2d-hw.c (renamed from drivers/media/platform/stm32/dma2d/dma2d-hw.c)0
-rw-r--r--drivers/media/platform/st/stm32/dma2d/dma2d-regs.h (renamed from drivers/media/platform/stm32/dma2d/dma2d-regs.h)0
-rw-r--r--drivers/media/platform/st/stm32/dma2d/dma2d.c (renamed from drivers/media/platform/stm32/dma2d/dma2d.c)9
-rw-r--r--drivers/media/platform/st/stm32/dma2d/dma2d.h (renamed from drivers/media/platform/stm32/dma2d/dma2d.h)0
-rw-r--r--drivers/media/platform/st/stm32/stm32-dcmi.c (renamed from drivers/media/platform/stm32/stm32-dcmi.c)53
-rw-r--r--drivers/media/platform/sunxi/Kconfig4
-rw-r--r--drivers/media/platform/sunxi/sun4i-csi/Kconfig3
-rw-r--r--drivers/media/platform/sunxi/sun4i-csi/sun4i_csi.h2
-rw-r--r--drivers/media/platform/sunxi/sun4i-csi/sun4i_dma.c2
-rw-r--r--drivers/media/platform/sunxi/sun6i-csi/Kconfig3
-rw-r--r--drivers/media/platform/sunxi/sun6i-csi/sun6i_video.c6
-rw-r--r--drivers/media/platform/sunxi/sun8i-di/Kconfig14
-rw-r--r--drivers/media/platform/sunxi/sun8i-rotate/Kconfig14
-rw-r--r--drivers/media/platform/ti/Kconfig69
-rw-r--r--drivers/media/platform/ti/Makefile7
-rw-r--r--drivers/media/platform/ti/am437x/Kconfig (renamed from drivers/media/platform/am437x/Kconfig)3
-rw-r--r--drivers/media/platform/ti/am437x/Makefile (renamed from drivers/media/platform/am437x/Makefile)0
-rw-r--r--drivers/media/platform/ti/am437x/am437x-vpfe.c (renamed from drivers/media/platform/am437x/am437x-vpfe.c)0
-rw-r--r--drivers/media/platform/ti/am437x/am437x-vpfe.h (renamed from drivers/media/platform/am437x/am437x-vpfe.h)0
-rw-r--r--drivers/media/platform/ti/am437x/am437x-vpfe_regs.h (renamed from drivers/media/platform/am437x/am437x-vpfe_regs.h)0
-rw-r--r--drivers/media/platform/ti/cal/Makefile3
-rw-r--r--drivers/media/platform/ti/cal/cal-camerarx.c (renamed from drivers/media/platform/ti-vpe/cal-camerarx.c)6
-rw-r--r--drivers/media/platform/ti/cal/cal-video.c (renamed from drivers/media/platform/ti-vpe/cal-video.c)3
-rw-r--r--drivers/media/platform/ti/cal/cal.c (renamed from drivers/media/platform/ti-vpe/cal.c)0
-rw-r--r--drivers/media/platform/ti/cal/cal.h (renamed from drivers/media/platform/ti-vpe/cal.h)0
-rw-r--r--drivers/media/platform/ti/cal/cal_regs.h (renamed from drivers/media/platform/ti-vpe/cal_regs.h)0
-rw-r--r--drivers/media/platform/ti/davinci/Kconfig (renamed from drivers/media/platform/davinci/Kconfig)18
-rw-r--r--drivers/media/platform/ti/davinci/Makefile (renamed from drivers/media/platform/davinci/Makefile)0
-rw-r--r--drivers/media/platform/ti/davinci/ccdc_hw_device.h (renamed from drivers/media/platform/davinci/ccdc_hw_device.h)0
-rw-r--r--drivers/media/platform/ti/davinci/dm355_ccdc.c (renamed from drivers/media/platform/davinci/dm355_ccdc.c)0
-rw-r--r--drivers/media/platform/ti/davinci/dm355_ccdc_regs.h (renamed from drivers/media/platform/davinci/dm355_ccdc_regs.h)0
-rw-r--r--drivers/media/platform/ti/davinci/dm644x_ccdc.c (renamed from drivers/media/platform/davinci/dm644x_ccdc.c)0
-rw-r--r--drivers/media/platform/ti/davinci/dm644x_ccdc_regs.h (renamed from drivers/media/platform/davinci/dm644x_ccdc_regs.h)0
-rw-r--r--drivers/media/platform/ti/davinci/isif.c (renamed from drivers/media/platform/davinci/isif.c)0
-rw-r--r--drivers/media/platform/ti/davinci/isif_regs.h (renamed from drivers/media/platform/davinci/isif_regs.h)0
-rw-r--r--drivers/media/platform/ti/davinci/vpbe.c (renamed from drivers/media/platform/davinci/vpbe.c)0
-rw-r--r--drivers/media/platform/ti/davinci/vpbe_display.c (renamed from drivers/media/platform/davinci/vpbe_display.c)0
-rw-r--r--drivers/media/platform/ti/davinci/vpbe_osd.c (renamed from drivers/media/platform/davinci/vpbe_osd.c)0
-rw-r--r--drivers/media/platform/ti/davinci/vpbe_osd_regs.h (renamed from drivers/media/platform/davinci/vpbe_osd_regs.h)0
-rw-r--r--drivers/media/platform/ti/davinci/vpbe_venc.c (renamed from drivers/media/platform/davinci/vpbe_venc.c)0
-rw-r--r--drivers/media/platform/ti/davinci/vpbe_venc_regs.h (renamed from drivers/media/platform/davinci/vpbe_venc_regs.h)0
-rw-r--r--drivers/media/platform/ti/davinci/vpfe_capture.c (renamed from drivers/media/platform/davinci/vpfe_capture.c)0
-rw-r--r--drivers/media/platform/ti/davinci/vpif.c (renamed from drivers/media/platform/davinci/vpif.c)123
-rw-r--r--drivers/media/platform/ti/davinci/vpif.h (renamed from drivers/media/platform/davinci/vpif.h)0
-rw-r--r--drivers/media/platform/ti/davinci/vpif_capture.c (renamed from drivers/media/platform/davinci/vpif_capture.c)27
-rw-r--r--drivers/media/platform/ti/davinci/vpif_capture.h (renamed from drivers/media/platform/davinci/vpif_capture.h)0
-rw-r--r--drivers/media/platform/ti/davinci/vpif_display.c (renamed from drivers/media/platform/davinci/vpif_display.c)24
-rw-r--r--drivers/media/platform/ti/davinci/vpif_display.h (renamed from drivers/media/platform/davinci/vpif_display.h)0
-rw-r--r--drivers/media/platform/ti/davinci/vpss.c (renamed from drivers/media/platform/davinci/vpss.c)0
-rw-r--r--drivers/media/platform/ti/omap/Kconfig (renamed from drivers/media/platform/omap/Kconfig)3
-rw-r--r--drivers/media/platform/ti/omap/Makefile (renamed from drivers/media/platform/omap/Makefile)0
-rw-r--r--drivers/media/platform/ti/omap/omap_vout.c (renamed from drivers/media/platform/omap/omap_vout.c)0
-rw-r--r--drivers/media/platform/ti/omap/omap_vout_vrfb.c (renamed from drivers/media/platform/omap/omap_vout_vrfb.c)0
-rw-r--r--drivers/media/platform/ti/omap/omap_vout_vrfb.h (renamed from drivers/media/platform/omap/omap_vout_vrfb.h)0
-rw-r--r--drivers/media/platform/ti/omap/omap_voutdef.h (renamed from drivers/media/platform/omap/omap_voutdef.h)0
-rw-r--r--drivers/media/platform/ti/omap/omap_voutlib.c (renamed from drivers/media/platform/omap/omap_voutlib.c)0
-rw-r--r--drivers/media/platform/ti/omap/omap_voutlib.h (renamed from drivers/media/platform/omap/omap_voutlib.h)0
-rw-r--r--drivers/media/platform/ti/omap3isp/Kconfig21
-rw-r--r--drivers/media/platform/ti/omap3isp/Makefile (renamed from drivers/media/platform/omap3isp/Makefile)0
-rw-r--r--drivers/media/platform/ti/omap3isp/cfa_coef_table.h (renamed from drivers/media/platform/omap3isp/cfa_coef_table.h)0
-rw-r--r--drivers/media/platform/ti/omap3isp/gamma_table.h (renamed from drivers/media/platform/omap3isp/gamma_table.h)0
-rw-r--r--drivers/media/platform/ti/omap3isp/isp.c (renamed from drivers/media/platform/omap3isp/isp.c)0
-rw-r--r--drivers/media/platform/ti/omap3isp/isp.h (renamed from drivers/media/platform/omap3isp/isp.h)0
-rw-r--r--drivers/media/platform/ti/omap3isp/ispccdc.c (renamed from drivers/media/platform/omap3isp/ispccdc.c)0
-rw-r--r--drivers/media/platform/ti/omap3isp/ispccdc.h (renamed from drivers/media/platform/omap3isp/ispccdc.h)0
-rw-r--r--drivers/media/platform/ti/omap3isp/ispccp2.c (renamed from drivers/media/platform/omap3isp/ispccp2.c)0
-rw-r--r--drivers/media/platform/ti/omap3isp/ispccp2.h (renamed from drivers/media/platform/omap3isp/ispccp2.h)0
-rw-r--r--drivers/media/platform/ti/omap3isp/ispcsi2.c (renamed from drivers/media/platform/omap3isp/ispcsi2.c)0
-rw-r--r--drivers/media/platform/ti/omap3isp/ispcsi2.h (renamed from drivers/media/platform/omap3isp/ispcsi2.h)0
-rw-r--r--drivers/media/platform/ti/omap3isp/ispcsiphy.c (renamed from drivers/media/platform/omap3isp/ispcsiphy.c)0
-rw-r--r--drivers/media/platform/ti/omap3isp/ispcsiphy.h (renamed from drivers/media/platform/omap3isp/ispcsiphy.h)0
-rw-r--r--drivers/media/platform/ti/omap3isp/isph3a.h (renamed from drivers/media/platform/omap3isp/isph3a.h)0
-rw-r--r--drivers/media/platform/ti/omap3isp/isph3a_aewb.c (renamed from drivers/media/platform/omap3isp/isph3a_aewb.c)0
-rw-r--r--drivers/media/platform/ti/omap3isp/isph3a_af.c (renamed from drivers/media/platform/omap3isp/isph3a_af.c)0
-rw-r--r--drivers/media/platform/ti/omap3isp/isphist.c (renamed from drivers/media/platform/omap3isp/isphist.c)0
-rw-r--r--drivers/media/platform/ti/omap3isp/isphist.h (renamed from drivers/media/platform/omap3isp/isphist.h)0
-rw-r--r--drivers/media/platform/ti/omap3isp/isppreview.c (renamed from drivers/media/platform/omap3isp/isppreview.c)0
-rw-r--r--drivers/media/platform/ti/omap3isp/isppreview.h (renamed from drivers/media/platform/omap3isp/isppreview.h)0
-rw-r--r--drivers/media/platform/ti/omap3isp/ispreg.h (renamed from drivers/media/platform/omap3isp/ispreg.h)0
-rw-r--r--drivers/media/platform/ti/omap3isp/ispresizer.c (renamed from drivers/media/platform/omap3isp/ispresizer.c)0
-rw-r--r--drivers/media/platform/ti/omap3isp/ispresizer.h (renamed from drivers/media/platform/omap3isp/ispresizer.h)0
-rw-r--r--drivers/media/platform/ti/omap3isp/ispstat.c (renamed from drivers/media/platform/omap3isp/ispstat.c)5
-rw-r--r--drivers/media/platform/ti/omap3isp/ispstat.h (renamed from drivers/media/platform/omap3isp/ispstat.h)0
-rw-r--r--drivers/media/platform/ti/omap3isp/ispvideo.c (renamed from drivers/media/platform/omap3isp/ispvideo.c)0
-rw-r--r--drivers/media/platform/ti/omap3isp/ispvideo.h (renamed from drivers/media/platform/omap3isp/ispvideo.h)0
-rw-r--r--drivers/media/platform/ti/omap3isp/luma_enhance_table.h (renamed from drivers/media/platform/omap3isp/luma_enhance_table.h)0
-rw-r--r--drivers/media/platform/ti/omap3isp/noise_filter_table.h (renamed from drivers/media/platform/omap3isp/noise_filter_table.h)0
-rw-r--r--drivers/media/platform/ti/omap3isp/omap3isp.h (renamed from drivers/media/platform/omap3isp/omap3isp.h)0
-rw-r--r--drivers/media/platform/ti/vpe/Makefile (renamed from drivers/media/platform/ti-vpe/Makefile)4
-rw-r--r--drivers/media/platform/ti/vpe/csc.c (renamed from drivers/media/platform/ti-vpe/csc.c)0
-rw-r--r--drivers/media/platform/ti/vpe/csc.h (renamed from drivers/media/platform/ti-vpe/csc.h)0
-rw-r--r--drivers/media/platform/ti/vpe/sc.c (renamed from drivers/media/platform/ti-vpe/sc.c)0
-rw-r--r--drivers/media/platform/ti/vpe/sc.h (renamed from drivers/media/platform/ti-vpe/sc.h)0
-rw-r--r--drivers/media/platform/ti/vpe/sc_coeff.h (renamed from drivers/media/platform/ti-vpe/sc_coeff.h)0
-rw-r--r--drivers/media/platform/ti/vpe/vpdma.c (renamed from drivers/media/platform/ti-vpe/vpdma.c)0
-rw-r--r--drivers/media/platform/ti/vpe/vpdma.h (renamed from drivers/media/platform/ti-vpe/vpdma.h)0
-rw-r--r--drivers/media/platform/ti/vpe/vpdma_priv.h (renamed from drivers/media/platform/ti-vpe/vpdma_priv.h)0
-rw-r--r--drivers/media/platform/ti/vpe/vpe.c (renamed from drivers/media/platform/ti-vpe/vpe.c)0
-rw-r--r--drivers/media/platform/ti/vpe/vpe_regs.h (renamed from drivers/media/platform/ti-vpe/vpe_regs.h)0
-rw-r--r--drivers/media/platform/via/Kconfig14
-rw-r--r--drivers/media/platform/via/Makefile2
-rw-r--r--drivers/media/platform/via/via-camera.c (renamed from drivers/media/platform/via-camera.c)0
-rw-r--r--drivers/media/platform/via/via-camera.h (renamed from drivers/media/platform/via-camera.h)0
-rw-r--r--drivers/media/platform/xilinx/Kconfig10
-rw-r--r--drivers/media/platform/xilinx/xilinx-csi2rxss.c106
-rw-r--r--drivers/media/radio/Kconfig348
-rw-r--r--drivers/media/radio/Makefile43
-rw-r--r--drivers/media/radio/radio-sf16fmi.c2
-rw-r--r--drivers/media/radio/si470x/Kconfig2
-rw-r--r--drivers/media/radio/wl128x/Kconfig2
-rw-r--r--drivers/media/radio/wl128x/fmdrv_common.c3
-rw-r--r--drivers/media/rc/Kconfig376
-rw-r--r--drivers/media/rc/Makefile47
-rw-r--r--drivers/media/rc/fintek-cir.c2
-rw-r--r--drivers/media/rc/gpio-ir-tx.c28
-rw-r--r--drivers/media/rc/igorplugusb.c2
-rw-r--r--drivers/media/rc/iguanair.c2
-rw-r--r--drivers/media/rc/ir-hix5hd2.c2
-rw-r--r--drivers/media/rc/ir-imon-decoder.c2
-rw-r--r--drivers/media/rc/ir-jvc-decoder.c2
-rw-r--r--drivers/media/rc/ir-mce_kbd-decoder.c2
-rw-r--r--drivers/media/rc/ir-nec-decoder.c2
-rw-r--r--drivers/media/rc/ir-rc5-decoder.c2
-rw-r--r--drivers/media/rc/ir-rc6-decoder.c2
-rw-r--r--drivers/media/rc/ir-rcmm-decoder.c2
-rw-r--r--drivers/media/rc/ir-sanyo-decoder.c4
-rw-r--r--drivers/media/rc/ir-sharp-decoder.c2
-rw-r--r--drivers/media/rc/ir-sony-decoder.c2
-rw-r--r--drivers/media/rc/ir-xmp-decoder.c2
-rw-r--r--drivers/media/rc/ir_toy.c2
-rw-r--r--drivers/media/rc/ite-cir.c2
-rw-r--r--drivers/media/rc/keymaps/Makefile34
-rw-r--r--drivers/media/rc/lirc_dev.c36
-rw-r--r--drivers/media/rc/meson-ir-tx.c2
-rw-r--r--drivers/media/rc/mtk-cir.c39
-rw-r--r--drivers/media/rc/nuvoton-cir.c2
-rw-r--r--drivers/media/rc/rc-core-priv.h2
-rw-r--r--drivers/media/rc/rc-ir-raw.c2
-rw-r--r--drivers/media/rc/rc-loopback.c6
-rw-r--r--drivers/media/rc/st_rc.c2
-rw-r--r--drivers/media/rc/sunxi-cir.c2
-rw-r--r--drivers/media/rc/winbond-cir.c2
-rw-r--r--drivers/media/spi/Kconfig26
-rw-r--r--drivers/media/spi/Makefile7
-rw-r--r--drivers/media/spi/cxd2880-spi.c4
-rw-r--r--drivers/media/spi/gs1662.c4
-rw-r--r--drivers/media/test-drivers/Kconfig8
-rw-r--r--drivers/media/test-drivers/Makefile14
-rw-r--r--drivers/media/test-drivers/vicodec/Kconfig2
-rw-r--r--drivers/media/test-drivers/vidtv/Kconfig1
-rw-r--r--drivers/media/test-drivers/vidtv/vidtv_s302m.c17
-rw-r--r--drivers/media/test-drivers/vimc/Kconfig3
-rw-r--r--drivers/media/test-drivers/vimc/vimc-capture.c9
-rw-r--r--drivers/media/test-drivers/vimc/vimc-common.h7
-rw-r--r--drivers/media/test-drivers/vimc/vimc-core.c10
-rw-r--r--drivers/media/test-drivers/vivid/Kconfig2
-rw-r--r--drivers/media/test-drivers/vivid/vivid-core.h5
-rw-r--r--drivers/media/test-drivers/vivid/vivid-ctrls.c32
-rw-r--r--drivers/media/test-drivers/vivid/vivid-kthread-cap.c10
-rw-r--r--drivers/media/test-drivers/vivid/vivid-kthread-out.c12
-rw-r--r--drivers/media/test-drivers/vivid/vivid-kthread-touch.c10
-rw-r--r--drivers/media/test-drivers/vivid/vivid-sdr-cap.c15
-rw-r--r--drivers/media/test-drivers/vivid/vivid-touch-cap.c2
-rw-r--r--drivers/media/tuners/Kconfig241
-rw-r--r--drivers/media/tuners/Makefile66
-rw-r--r--drivers/media/tuners/e4000.c6
-rw-r--r--drivers/media/tuners/fc2580.c6
-rw-r--r--drivers/media/tuners/msi001.c3
-rw-r--r--drivers/media/tuners/tuner-types.c2
-rw-r--r--drivers/media/tuners/xc2028-types.h (renamed from drivers/media/tuners/tuner-xc2028-types.h)6
-rw-r--r--drivers/media/tuners/xc2028.c (renamed from drivers/media/tuners/tuner-xc2028.c)6
-rw-r--r--drivers/media/tuners/xc2028.h (renamed from drivers/media/tuners/tuner-xc2028.h)2
-rw-r--r--drivers/media/tuners/xc4000.c2
-rw-r--r--drivers/media/usb/Kconfig33
-rw-r--r--drivers/media/usb/Makefile40
-rw-r--r--drivers/media/usb/airspy/Kconfig2
-rw-r--r--drivers/media/usb/au0828/Kconfig6
-rw-r--r--drivers/media/usb/cpia2/Kconfig2
-rw-r--r--drivers/media/usb/dvb-usb-v2/Kconfig34
-rw-r--r--drivers/media/usb/dvb-usb/Kconfig368
-rw-r--r--drivers/media/usb/dvb-usb/cxusb.c2
-rw-r--r--drivers/media/usb/dvb-usb/dib0700_devices.c2
-rw-r--r--drivers/media/usb/em28xx/em28xx-cards.c13
-rw-r--r--drivers/media/usb/em28xx/em28xx-i2c.c2
-rw-r--r--drivers/media/usb/em28xx/em28xx.h2
-rw-r--r--drivers/media/usb/go7007/s2250-board.c10
-rw-r--r--drivers/media/usb/go7007/snd-go7007.c2
-rw-r--r--drivers/media/usb/gspca/Kconfig121
-rw-r--r--drivers/media/usb/gspca/Makefile88
-rw-r--r--drivers/media/usb/gspca/gl860/Kconfig2
-rw-r--r--drivers/media/usb/gspca/jl2005bcd.c4
-rw-r--r--drivers/media/usb/gspca/m5602/Kconfig2
-rw-r--r--drivers/media/usb/gspca/pac7302.c1
-rw-r--r--drivers/media/usb/hackrf/Kconfig2
-rw-r--r--drivers/media/usb/hdpvr/Kconfig2
-rw-r--r--drivers/media/usb/hdpvr/hdpvr-video.c4
-rw-r--r--drivers/media/usb/msi2500/Kconfig2
-rw-r--r--drivers/media/usb/pvrusb2/Kconfig2
-rw-r--r--drivers/media/usb/pwc/Kconfig2
-rw-r--r--drivers/media/usb/pwc/pwc-uncompress.c2
-rw-r--r--drivers/media/usb/s2255/Kconfig2
-rw-r--r--drivers/media/usb/stk1160/stk1160-core.c2
-rw-r--r--drivers/media/usb/stk1160/stk1160-v4l.c16
-rw-r--r--drivers/media/usb/stk1160/stk1160-video.c142
-rw-r--r--drivers/media/usb/stk1160/stk1160.h23
-rw-r--r--drivers/media/usb/stkwebcam/Kconfig2
-rw-r--r--drivers/media/usb/stkwebcam/stk-webcam.c7
-rw-r--r--drivers/media/usb/tm6000/tm6000-cards.c2
-rw-r--r--drivers/media/usb/tm6000/tm6000-dvb.c2
-rw-r--r--drivers/media/usb/tm6000/tm6000-i2c.c2
-rw-r--r--drivers/media/usb/usbtv/Kconfig2
-rw-r--r--drivers/media/usb/uvc/Kconfig2
-rw-r--r--drivers/media/usb/uvc/uvc_driver.c9
-rw-r--r--drivers/media/usb/zr364xx/Kconfig2
-rw-r--r--drivers/media/v4l2-core/Kconfig12
-rw-r--r--drivers/media/v4l2-core/Makefile34
-rw-r--r--drivers/media/v4l2-core/tuner-core.c2
-rw-r--r--drivers/media/v4l2-core/v4l2-ctrls-core.c20
-rw-r--r--drivers/media/v4l2-core/v4l2-dev.c68
-rw-r--r--drivers/media/v4l2-core/v4l2-fwnode.c46
-rw-r--r--drivers/media/v4l2-core/v4l2-ioctl.c14
-rw-r--r--drivers/media/v4l2-core/v4l2-mem2mem.c53
-rw-r--r--drivers/media/v4l2-core/v4l2-subdev.c8
-rw-r--r--drivers/memory/brcmstb_dpfe.c2
-rw-r--r--drivers/memory/emif.c8
-rw-r--r--drivers/memory/fsl_ifc.c9
-rw-r--r--drivers/memory/mtk-smi.c71
-rw-r--r--drivers/memory/of_memory.c29
-rw-r--r--drivers/memory/tegra/Kconfig1
-rw-r--r--drivers/memory/tegra/tegra20-emc.c2
-rw-r--r--drivers/memory/tegra/tegra210-emc-core.c2
-rw-r--r--drivers/memory/tegra/tegra30-emc.c131
-rw-r--r--drivers/memstick/core/ms_block.c64
-rw-r--r--drivers/memstick/core/ms_block.h1
-rw-r--r--drivers/memstick/core/mspro_block.c57
-rw-r--r--drivers/mfd/arizona-spi.c4
-rw-r--r--drivers/mfd/da9052-spi.c3
-rw-r--r--drivers/mfd/ezx-pcap.c8
-rw-r--r--drivers/mfd/lpc_ich.c59
-rw-r--r--drivers/mfd/madera-spi.c4
-rw-r--r--drivers/mfd/mc13xxx-spi.c3
-rw-r--r--drivers/mfd/rsmu_spi.c4
-rw-r--r--drivers/mfd/stmpe-spi.c4
-rw-r--r--drivers/mfd/tps65912-spi.c4
-rw-r--r--drivers/misc/ad525x_dpot-spi.c3
-rw-r--r--drivers/misc/bcm-vk/bcm_vk.h2
-rw-r--r--drivers/misc/eeprom/at25.c4
-rw-r--r--drivers/misc/eeprom/ee1004.c3
-rw-r--r--drivers/misc/eeprom/eeprom_93xx46.c4
-rw-r--r--drivers/misc/fastrpc.c13
-rw-r--r--drivers/misc/habanalabs/include/common/cpucp_if.h6
-rw-r--r--drivers/misc/habanalabs/include/gaudi/gaudi_packets.h4
-rw-r--r--drivers/misc/habanalabs/include/goya/goya_packets.h4
-rw-r--r--drivers/misc/hi6421v600-irq.c6
-rw-r--r--drivers/misc/lattice-ecp3-config.c4
-rw-r--r--drivers/misc/lis3lv02d/lis3lv02d_spi.c4
-rw-r--r--drivers/misc/sgi-xp/xpnet.c2
-rw-r--r--drivers/mmc/core/block.c30
-rw-r--r--drivers/mmc/core/bus.c9
-rw-r--r--drivers/mmc/core/bus.h3
-rw-r--r--drivers/mmc/core/host.c24
-rw-r--r--drivers/mmc/core/mmc.c39
-rw-r--r--drivers/mmc/core/mmc_ops.c13
-rw-r--r--drivers/mmc/core/mmc_ops.h3
-rw-r--r--drivers/mmc/core/sd.c35
-rw-r--r--drivers/mmc/core/sdio.c5
-rw-r--r--drivers/mmc/core/sdio_bus.c7
-rw-r--r--drivers/mmc/host/Kconfig13
-rw-r--r--drivers/mmc/host/Makefile1
-rw-r--r--drivers/mmc/host/davinci_mmc.c12
-rw-r--r--drivers/mmc/host/dw_mmc-rockchip.c27
-rw-r--r--drivers/mmc/host/dw_mmc.c12
-rw-r--r--drivers/mmc/host/dw_mmc.h2
-rw-r--r--drivers/mmc/host/litex_mmc.c661
-rw-r--r--drivers/mmc/host/meson-gx-mmc.c15
-rw-r--r--drivers/mmc/host/mmc_spi.c3
-rw-r--r--drivers/mmc/host/moxart-mmc.c2
-rw-r--r--drivers/mmc/host/mtk-sd.c4
-rw-r--r--drivers/mmc/host/renesas_sdhi_internal_dmac.c2
-rw-r--r--drivers/mmc/host/rtsx_pci_sdmmc.c29
-rw-r--r--drivers/mmc/host/sdhci-of-at91.c6
-rw-r--r--drivers/mmc/host/sdhci-of-esdhc.c18
-rw-r--r--drivers/mmc/host/sdhci-pci-gli.c133
-rw-r--r--drivers/mmc/host/sdhci-tegra.c15
-rw-r--r--drivers/mmc/host/sdhci_am654.c28
-rw-r--r--drivers/mmc/host/sh_mmcif.c10
-rw-r--r--drivers/mmc/host/sunxi-mmc.c9
-rw-r--r--drivers/mmc/host/tmio_mmc.h4
-rw-r--r--drivers/mmc/host/wmt-sdmmc.c7
-rw-r--r--drivers/mtd/devices/mchp23k256.c4
-rw-r--r--drivers/mtd/devices/mchp48l640.c4
-rw-r--r--drivers/mtd/devices/mtd_dataflash.c4
-rw-r--r--drivers/mtd/devices/phram.c12
-rw-r--r--drivers/mtd/devices/sst25l.c4
-rw-r--r--drivers/mtd/mtdcore.c2
-rw-r--r--drivers/mtd/mtdswap.c2
-rw-r--r--drivers/mtd/nand/raw/Kconfig2
-rw-r--r--drivers/mtd/nand/raw/brcmnand/brcmnand.c2
-rw-r--r--drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c3
-rw-r--r--drivers/mtd/nand/raw/ingenic/ingenic_ecc.c7
-rw-r--r--drivers/mtd/nand/raw/qcom_nandc.c14
-rw-r--r--drivers/mtd/nand/raw/sharpsl.c1
-rw-r--r--drivers/mtd/parsers/qcomsmempart.c36
-rw-r--r--drivers/mtd/spi-nor/controllers/Kconfig36
-rw-r--r--drivers/mtd/spi-nor/controllers/Makefile3
-rw-r--r--drivers/mtd/spi-nor/controllers/intel-spi.h21
-rw-r--r--drivers/net/Makefile2
-rw-r--r--drivers/net/amt.c4
-rw-r--r--drivers/net/arcnet/com20020-pci.c3
-rw-r--r--drivers/net/bareudp.c19
-rw-r--r--drivers/net/bonding/bond_3ad.c33
-rw-r--r--drivers/net/bonding/bond_alb.c31
-rw-r--r--drivers/net/bonding/bond_main.c333
-rw-r--r--drivers/net/bonding/bond_netlink.c59
-rw-r--r--drivers/net/bonding/bond_options.c74
-rw-r--r--drivers/net/bonding/bond_procfs.c1
-rw-r--r--drivers/net/bonding/bond_sysfs_slave.c8
-rw-r--r--drivers/net/caif/caif_serial.c2
-rw-r--r--drivers/net/can/c_can/c_can_ethtool.c9
-rw-r--r--drivers/net/can/dev/bittiming.c20
-rw-r--r--drivers/net/can/dev/dev.c2
-rw-r--r--drivers/net/can/flexcan/flexcan-core.c1
-rw-r--r--drivers/net/can/flexcan/flexcan.h2
-rw-r--r--drivers/net/can/m_can/m_can.c6
-rw-r--r--drivers/net/can/m_can/tcan4x5x-core.c4
-rw-r--r--drivers/net/can/m_can/tcan4x5x-regmap.c2
-rw-r--r--drivers/net/can/rcar/rcar_canfd.c359
-rw-r--r--drivers/net/can/slcan.c2
-rw-r--r--drivers/net/can/softing/softing_main.c5
-rw-r--r--drivers/net/can/spi/hi311x.c10
-rw-r--r--drivers/net/can/spi/mcp251x.c8
-rw-r--r--drivers/net/can/spi/mcp251xfd/Makefile2
-rw-r--r--drivers/net/can/spi/mcp251xfd/mcp251xfd-chip-fifo.c4
-rw-r--r--drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c353
-rw-r--r--drivers/net/can/spi/mcp251xfd/mcp251xfd-dump.c4
-rw-r--r--drivers/net/can/spi/mcp251xfd/mcp251xfd-ethtool.c143
-rw-r--r--drivers/net/can/spi/mcp251xfd/mcp251xfd-ram.c153
-rw-r--r--drivers/net/can/spi/mcp251xfd/mcp251xfd-ram.h62
-rw-r--r--drivers/net/can/spi/mcp251xfd/mcp251xfd-regmap.c24
-rw-r--r--drivers/net/can/spi/mcp251xfd/mcp251xfd-ring.c417
-rw-r--r--drivers/net/can/spi/mcp251xfd/mcp251xfd-rx.c22
-rw-r--r--drivers/net/can/spi/mcp251xfd/mcp251xfd-tef.c6
-rw-r--r--drivers/net/can/spi/mcp251xfd/mcp251xfd.h96
-rw-r--r--drivers/net/can/usb/etas_es58x/es58x_core.c9
-rw-r--r--drivers/net/can/usb/etas_es58x/es58x_core.h8
-rw-r--r--drivers/net/can/usb/etas_es58x/es58x_fd.c6
-rw-r--r--drivers/net/can/usb/gs_usb.c456
-rw-r--r--drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c4
-rw-r--r--drivers/net/can/usb/ucan.c4
-rw-r--r--drivers/net/can/vcan.c2
-rw-r--r--drivers/net/can/vxcan.c21
-rw-r--r--drivers/net/can/xilinx_can.c9
-rw-r--r--drivers/net/dsa/Kconfig14
-rw-r--r--drivers/net/dsa/Makefile3
-rw-r--r--drivers/net/dsa/b53/b53_common.c87
-rw-r--r--drivers/net/dsa/b53/b53_priv.h25
-rw-r--r--drivers/net/dsa/b53/b53_serdes.c19
-rw-r--r--drivers/net/dsa/b53/b53_serdes.h5
-rw-r--r--drivers/net/dsa/b53/b53_spi.c4
-rw-r--r--drivers/net/dsa/b53/b53_srab.c35
-rw-r--r--drivers/net/dsa/bcm_sf2.c61
-rw-r--r--drivers/net/dsa/dsa_loop.c3
-rw-r--r--drivers/net/dsa/hirschmann/hellcreek.c9
-rw-r--r--drivers/net/dsa/hirschmann/hellcreek_hwtstamp.c2
-rw-r--r--drivers/net/dsa/lan9303-core.c29
-rw-r--r--drivers/net/dsa/lantiq_gswip.c76
-rw-r--r--drivers/net/dsa/microchip/ksz8.h1
-rw-r--r--drivers/net/dsa/microchip/ksz8795.c92
-rw-r--r--drivers/net/dsa/microchip/ksz8795_reg.h4
-rw-r--r--drivers/net/dsa/microchip/ksz8795_spi.c15
-rw-r--r--drivers/net/dsa/microchip/ksz9477.c156
-rw-r--r--drivers/net/dsa/microchip/ksz9477_i2c.c1
-rw-r--r--drivers/net/dsa/microchip/ksz9477_reg.h3
-rw-r--r--drivers/net/dsa/microchip/ksz9477_spi.c16
-rw-r--r--drivers/net/dsa/microchip/ksz_common.c47
-rw-r--r--drivers/net/dsa/microchip/ksz_common.h15
-rw-r--r--drivers/net/dsa/mt7530.c23
-rw-r--r--drivers/net/dsa/mv88e6xxx/chip.c947
-rw-r--r--drivers/net/dsa/mv88e6xxx/chip.h51
-rw-r--r--drivers/net/dsa/mv88e6xxx/devlink.c94
-rw-r--r--drivers/net/dsa/mv88e6xxx/global1.h11
-rw-r--r--drivers/net/dsa/mv88e6xxx/global1_vtu.c316
-rw-r--r--drivers/net/dsa/mv88e6xxx/global2.h3
-rw-r--r--drivers/net/dsa/mv88e6xxx/global2_scratch.c28
-rw-r--r--drivers/net/dsa/mv88e6xxx/hwtstamp.c2
-rw-r--r--drivers/net/dsa/mv88e6xxx/port.c41
-rw-r--r--drivers/net/dsa/mv88e6xxx/port.h16
-rw-r--r--drivers/net/dsa/mv88e6xxx/serdes.c81
-rw-r--r--drivers/net/dsa/mv88e6xxx/serdes.h5
-rw-r--r--drivers/net/dsa/mv88e6xxx/smi.c35
-rw-r--r--drivers/net/dsa/ocelot/felix.c843
-rw-r--r--drivers/net/dsa/ocelot/felix.h9
-rw-r--r--drivers/net/dsa/ocelot/felix_vsc9959.c52
-rw-r--r--drivers/net/dsa/ocelot/seville_vsc9953.c53
-rw-r--r--drivers/net/dsa/qca/ar9331.c48
-rw-r--r--drivers/net/dsa/qca8k.c1582
-rw-r--r--drivers/net/dsa/qca8k.h54
-rw-r--r--drivers/net/dsa/realtek-smi-core.c523
-rw-r--r--drivers/net/dsa/realtek/Kconfig40
-rw-r--r--drivers/net/dsa/realtek/Makefile6
-rw-r--r--drivers/net/dsa/realtek/realtek-mdio.c290
-rw-r--r--drivers/net/dsa/realtek/realtek-smi.c581
-rw-r--r--drivers/net/dsa/realtek/realtek.h (renamed from drivers/net/dsa/realtek-smi-core.h)91
-rw-r--r--drivers/net/dsa/realtek/rtl8365mb.c (renamed from drivers/net/dsa/rtl8365mb.c)734
-rw-r--r--drivers/net/dsa/realtek/rtl8366-core.c (renamed from drivers/net/dsa/rtl8366.c)164
-rw-r--r--drivers/net/dsa/realtek/rtl8366rb.c (renamed from drivers/net/dsa/rtl8366rb.c)460
-rw-r--r--drivers/net/dsa/sja1105/sja1105_flower.c47
-rw-r--r--drivers/net/dsa/sja1105/sja1105_main.c202
-rw-r--r--drivers/net/dsa/sja1105/sja1105_ptp.c2
-rw-r--r--drivers/net/dsa/sja1105/sja1105_vl.c16
-rw-r--r--drivers/net/dsa/vitesse-vsc73xx-spi.c6
-rw-r--r--drivers/net/dsa/xrs700x/xrs700x.c32
-rw-r--r--drivers/net/ethernet/3com/typhoon.c30
-rw-r--r--drivers/net/ethernet/8390/etherh.c6
-rw-r--r--drivers/net/ethernet/8390/mcf8390.c12
-rw-r--r--drivers/net/ethernet/Kconfig1
-rw-r--r--drivers/net/ethernet/Makefile1
-rw-r--r--drivers/net/ethernet/agere/et131x.c14
-rw-r--r--drivers/net/ethernet/altera/altera_sgdma.c2
-rw-r--r--drivers/net/ethernet/altera/altera_tse_main.c8
-rw-r--r--drivers/net/ethernet/amazon/ena/ena_netdev.c5
-rw-r--r--drivers/net/ethernet/amd/declance.c4
-rw-r--r--drivers/net/ethernet/amd/xgbe/xgbe-drv.c14
-rw-r--r--drivers/net/ethernet/amd/xgbe/xgbe-pci.c3
-rw-r--r--drivers/net/ethernet/apm/xgene/xgene_enet_main.c12
-rw-r--r--drivers/net/ethernet/aquantia/atlantic/aq_filters.c6
-rw-r--r--drivers/net/ethernet/arc/emac_mdio.c5
-rw-r--r--drivers/net/ethernet/asix/ax88796c_main.c6
-rw-r--r--drivers/net/ethernet/atheros/alx/main.c5
-rw-r--r--drivers/net/ethernet/atheros/atl1c/atl1c_main.c4
-rw-r--r--drivers/net/ethernet/broadcom/bcm63xx_enet.c16
-rw-r--r--drivers/net/ethernet/broadcom/bgmac-platform.c23
-rw-r--r--drivers/net/ethernet/broadcom/bnx2.c2
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x.h4
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c28
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c6
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c18
-rw-r--r--drivers/net/ethernet/broadcom/bnxt/bnxt.c130
-rw-r--r--drivers/net/ethernet/broadcom/bnxt/bnxt.h20
-rw-r--r--drivers/net/ethernet/broadcom/bnxt/bnxt_dcb.c3
-rw-r--r--drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.c83
-rw-r--r--drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.h2
-rw-r--r--drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c73
-rw-r--r--drivers/net/ethernet/broadcom/bnxt/bnxt_hsi.h499
-rw-r--r--drivers/net/ethernet/broadcom/bnxt/bnxt_hwrm.c12
-rw-r--r--drivers/net/ethernet/broadcom/bnxt/bnxt_hwrm.h2
-rw-r--r--drivers/net/ethernet/broadcom/bnxt/bnxt_ptp.c152
-rw-r--r--drivers/net/ethernet/broadcom/bnxt/bnxt_ptp.h5
-rw-r--r--drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c4
-rw-r--r--drivers/net/ethernet/broadcom/bnxt/bnxt_vfr.c22
-rw-r--r--drivers/net/ethernet/broadcom/genet/bcmgenet.c12
-rw-r--r--drivers/net/ethernet/broadcom/genet/bcmgenet_wol.c7
-rw-r--r--drivers/net/ethernet/broadcom/sb1250-mac.c4
-rw-r--r--drivers/net/ethernet/cadence/macb.h4
-rw-r--r--drivers/net/ethernet/cadence/macb_main.c90
-rw-r--r--drivers/net/ethernet/cavium/thunder/thunder_bgx.c3
-rw-r--r--drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c1
-rw-r--r--drivers/net/ethernet/chelsio/cxgb3/t3_hw.c2
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_matchall.c59
-rw-r--r--drivers/net/ethernet/cortina/gemini.c8
-rw-r--r--drivers/net/ethernet/davicom/Kconfig31
-rw-r--r--drivers/net/ethernet/davicom/Makefile1
-rw-r--r--drivers/net/ethernet/davicom/dm9051.c1260
-rw-r--r--drivers/net/ethernet/davicom/dm9051.h162
-rw-r--r--drivers/net/ethernet/dec/tulip/pnic.c2
-rw-r--r--drivers/net/ethernet/dlink/sundance.c60
-rw-r--r--drivers/net/ethernet/ezchip/nps_enet.c1
-rw-r--r--drivers/net/ethernet/faraday/Kconfig12
-rw-r--r--drivers/net/ethernet/faraday/ftgmac100.c243
-rw-r--r--drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c443
-rw-r--r--drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h32
-rw-r--r--drivers/net/ethernet/freescale/dpaa2/dpaa2-ethtool.c2
-rw-r--r--drivers/net/ethernet/freescale/dpaa2/dpaa2-mac.c171
-rw-r--r--drivers/net/ethernet/freescale/dpaa2/dpaa2-mac.h8
-rw-r--r--drivers/net/ethernet/freescale/dpaa2/dpaa2-switch-flower.c4
-rw-r--r--drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c5
-rw-r--r--drivers/net/ethernet/freescale/dpaa2/dpmac-cmd.h12
-rw-r--r--drivers/net/ethernet/freescale/dpaa2/dpmac.c54
-rw-r--r--drivers/net/ethernet/freescale/dpaa2/dpmac.h5
-rw-r--r--drivers/net/ethernet/freescale/dpaa2/dpni-cmd.h6
-rw-r--r--drivers/net/ethernet/freescale/dpaa2/dpni.c2
-rw-r--r--drivers/net/ethernet/freescale/dpaa2/dpni.h6
-rw-r--r--drivers/net/ethernet/freescale/enetc/enetc.h38
-rw-r--r--drivers/net/ethernet/freescale/enetc/enetc_cbdr.c41
-rw-r--r--drivers/net/ethernet/freescale/enetc/enetc_hw.h2
-rw-r--r--drivers/net/ethernet/freescale/enetc/enetc_mdio.c2
-rw-r--r--drivers/net/ethernet/freescale/enetc/enetc_pf.c14
-rw-r--r--drivers/net/ethernet/freescale/enetc/enetc_qos.c150
-rw-r--r--drivers/net/ethernet/freescale/fec_main.c2
-rw-r--r--drivers/net/ethernet/freescale/fec_mpc52xx.c12
-rw-r--r--drivers/net/ethernet/freescale/fec_ptp.c1
-rw-r--r--drivers/net/ethernet/freescale/gianfar_ethtool.c1
-rw-r--r--drivers/net/ethernet/freescale/xgmac_mdio.c93
-rw-r--r--drivers/net/ethernet/fungible/Kconfig28
-rw-r--r--drivers/net/ethernet/fungible/Makefile7
-rw-r--r--drivers/net/ethernet/fungible/funcore/Makefile5
-rw-r--r--drivers/net/ethernet/fungible/funcore/fun_dev.c843
-rw-r--r--drivers/net/ethernet/fungible/funcore/fun_dev.h150
-rw-r--r--drivers/net/ethernet/fungible/funcore/fun_hci.h1202
-rw-r--r--drivers/net/ethernet/fungible/funcore/fun_queue.c601
-rw-r--r--drivers/net/ethernet/fungible/funcore/fun_queue.h175
-rw-r--r--drivers/net/ethernet/fungible/funeth/Kconfig17
-rw-r--r--drivers/net/ethernet/fungible/funeth/Makefile10
-rw-r--r--drivers/net/ethernet/fungible/funeth/fun_port.h97
-rw-r--r--drivers/net/ethernet/fungible/funeth/funeth.h171
-rw-r--r--drivers/net/ethernet/fungible/funeth/funeth_devlink.c40
-rw-r--r--drivers/net/ethernet/fungible/funeth/funeth_devlink.h13
-rw-r--r--drivers/net/ethernet/fungible/funeth/funeth_ethtool.c1162
-rw-r--r--drivers/net/ethernet/fungible/funeth/funeth_ktls.c155
-rw-r--r--drivers/net/ethernet/fungible/funeth/funeth_ktls.h30
-rw-r--r--drivers/net/ethernet/fungible/funeth/funeth_main.c2091
-rw-r--r--drivers/net/ethernet/fungible/funeth/funeth_rx.c826
-rw-r--r--drivers/net/ethernet/fungible/funeth/funeth_trace.h117
-rw-r--r--drivers/net/ethernet/fungible/funeth/funeth_tx.c763
-rw-r--r--drivers/net/ethernet/fungible/funeth/funeth_txrx.h264
-rw-r--r--drivers/net/ethernet/google/gve/gve.h2
-rw-r--r--drivers/net/ethernet/google/gve/gve_adminq.c2
-rw-r--r--drivers/net/ethernet/google/gve/gve_main.c12
-rw-r--r--drivers/net/ethernet/google/gve/gve_rx.c6
-rw-r--r--drivers/net/ethernet/google/gve/gve_rx_dqo.c2
-rw-r--r--drivers/net/ethernet/hisilicon/hns/hns_ethtool.c4
-rw-r--r--drivers/net/ethernet/hisilicon/hns3/hnae3.h1
-rw-r--r--drivers/net/ethernet/hisilicon/hns3/hns3_enet.c79
-rw-r--r--drivers/net/ethernet/hisilicon/hns3/hns3_enet.h6
-rw-r--r--drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c2
-rw-r--r--drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c11
-rw-r--r--drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h13
-rw-r--r--drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c2
-rw-r--r--drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c14
-rw-r--r--drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h8
-rw-r--r--drivers/net/ethernet/i825xx/ether1.c4
-rw-r--r--drivers/net/ethernet/i825xx/sun3_82586.h4
-rw-r--r--drivers/net/ethernet/ibm/ibmvnic.c465
-rw-r--r--drivers/net/ethernet/ibm/ibmvnic.h9
-rw-r--r--drivers/net/ethernet/intel/e1000e/e1000.h4
-rw-r--r--drivers/net/ethernet/intel/e1000e/hw.h1
-rw-r--r--drivers/net/ethernet/intel/e1000e/ich8lan.c28
-rw-r--r--drivers/net/ethernet/intel/e1000e/ich8lan.h1
-rw-r--r--drivers/net/ethernet/intel/e1000e/netdev.c87
-rw-r--r--drivers/net/ethernet/intel/e1000e/phy.c8
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e.h14
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_adminq.c92
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_common.c155
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_debugfs.c11
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_ethtool.c4
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_main.c113
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_nvm.c5
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_prototype.h25
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_register.h3
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_txrx.c36
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_txrx.h5
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c160
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.h6
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_xsk.c23
-rw-r--r--drivers/net/ethernet/intel/iavf/iavf.h29
-rw-r--r--drivers/net/ethernet/intel/iavf/iavf_common.c4
-rw-r--r--drivers/net/ethernet/intel/iavf/iavf_main.c498
-rw-r--r--drivers/net/ethernet/intel/iavf/iavf_status.h2
-rw-r--r--drivers/net/ethernet/intel/iavf/iavf_txrx.c62
-rw-r--r--drivers/net/ethernet/intel/iavf/iavf_virtchnl.c258
-rw-r--r--drivers/net/ethernet/intel/ice/Makefile15
-rw-r--r--drivers/net/ethernet/intel/ice/ice.h53
-rw-r--r--drivers/net/ethernet/intel/ice/ice_adminq_cmd.h276
-rw-r--r--drivers/net/ethernet/intel/ice/ice_arfs.h3
-rw-r--r--drivers/net/ethernet/intel/ice/ice_base.c21
-rw-r--r--drivers/net/ethernet/intel/ice/ice_common.c107
-rw-r--r--drivers/net/ethernet/intel/ice/ice_common.h13
-rw-r--r--drivers/net/ethernet/intel/ice/ice_dcb.h1
-rw-r--r--drivers/net/ethernet/intel/ice/ice_dcb_lib.c8
-rw-r--r--drivers/net/ethernet/intel/ice/ice_eswitch.c171
-rw-r--r--drivers/net/ethernet/intel/ice/ice_ethtool.c31
-rw-r--r--drivers/net/ethernet/intel/ice/ice_flex_pipe.c345
-rw-r--r--drivers/net/ethernet/intel/ice/ice_flex_pipe.h15
-rw-r--r--drivers/net/ethernet/intel/ice/ice_flex_type.h46
-rw-r--r--drivers/net/ethernet/intel/ice/ice_flow.c1
-rw-r--r--drivers/net/ethernet/intel/ice/ice_flow.h2
-rw-r--r--drivers/net/ethernet/intel/ice/ice_fltr.c37
-rw-r--r--drivers/net/ethernet/intel/ice/ice_fltr.h10
-rw-r--r--drivers/net/ethernet/intel/ice/ice_gnss.c376
-rw-r--r--drivers/net/ethernet/intel/ice/ice_gnss.h50
-rw-r--r--drivers/net/ethernet/intel/ice/ice_idc.c14
-rw-r--r--drivers/net/ethernet/intel/ice/ice_idc_int.h1
-rw-r--r--drivers/net/ethernet/intel/ice/ice_lag.c34
-rw-r--r--drivers/net/ethernet/intel/ice/ice_lan_tx_rx.h3
-rw-r--r--drivers/net/ethernet/intel/ice/ice_lib.c602
-rw-r--r--drivers/net/ethernet/intel/ice/ice_lib.h22
-rw-r--r--drivers/net/ethernet/intel/ice/ice_main.c538
-rw-r--r--drivers/net/ethernet/intel/ice/ice_osdep.h12
-rw-r--r--drivers/net/ethernet/intel/ice/ice_pf_vsi_vlan_ops.c38
-rw-r--r--drivers/net/ethernet/intel/ice/ice_pf_vsi_vlan_ops.h13
-rw-r--r--drivers/net/ethernet/intel/ice/ice_protocol_type.h22
-rw-r--r--drivers/net/ethernet/intel/ice/ice_ptp.c13
-rw-r--r--drivers/net/ethernet/intel/ice/ice_ptp_hw.c31
-rw-r--r--drivers/net/ethernet/intel/ice/ice_ptp_hw.h7
-rw-r--r--drivers/net/ethernet/intel/ice/ice_repr.c111
-rw-r--r--drivers/net/ethernet/intel/ice/ice_repr.h1
-rw-r--r--drivers/net/ethernet/intel/ice/ice_sriov.c2185
-rw-r--r--drivers/net/ethernet/intel/ice/ice_sriov.h163
-rw-r--r--drivers/net/ethernet/intel/ice/ice_switch.c998
-rw-r--r--drivers/net/ethernet/intel/ice/ice_switch.h33
-rw-r--r--drivers/net/ethernet/intel/ice/ice_tc_lib.c156
-rw-r--r--drivers/net/ethernet/intel/ice/ice_tc_lib.h3
-rw-r--r--drivers/net/ethernet/intel/ice/ice_trace.h24
-rw-r--r--drivers/net/ethernet/intel/ice/ice_txrx.c58
-rw-r--r--drivers/net/ethernet/intel/ice/ice_txrx.h13
-rw-r--r--drivers/net/ethernet/intel/ice/ice_txrx_lib.c24
-rw-r--r--drivers/net/ethernet/intel/ice/ice_txrx_lib.h30
-rw-r--r--drivers/net/ethernet/intel/ice/ice_type.h20
-rw-r--r--drivers/net/ethernet/intel/ice/ice_vf_lib.c1029
-rw-r--r--drivers/net/ethernet/intel/ice/ice_vf_lib.h290
-rw-r--r--drivers/net/ethernet/intel/ice/ice_vf_lib_private.h40
-rw-r--r--drivers/net/ethernet/intel/ice/ice_vf_mbx.c532
-rw-r--r--drivers/net/ethernet/intel/ice/ice_vf_mbx.h52
-rw-r--r--drivers/net/ethernet/intel/ice/ice_vf_vsi_vlan_ops.c211
-rw-r--r--drivers/net/ethernet/intel/ice/ice_vf_vsi_vlan_ops.h19
-rw-r--r--drivers/net/ethernet/intel/ice/ice_virtchnl.c (renamed from drivers/net/ethernet/intel/ice/ice_virtchnl_pf.c)3986
-rw-r--r--drivers/net/ethernet/intel/ice/ice_virtchnl.h82
-rw-r--r--drivers/net/ethernet/intel/ice/ice_virtchnl_allowlist.c10
-rw-r--r--drivers/net/ethernet/intel/ice/ice_virtchnl_fdir.c14
-rw-r--r--drivers/net/ethernet/intel/ice/ice_virtchnl_fdir.h1
-rw-r--r--drivers/net/ethernet/intel/ice/ice_virtchnl_pf.h346
-rw-r--r--drivers/net/ethernet/intel/ice/ice_vlan.h18
-rw-r--r--drivers/net/ethernet/intel/ice/ice_vlan_mode.c439
-rw-r--r--drivers/net/ethernet/intel/ice/ice_vlan_mode.h13
-rw-r--r--drivers/net/ethernet/intel/ice/ice_vsi_vlan_lib.c707
-rw-r--r--drivers/net/ethernet/intel/ice/ice_vsi_vlan_lib.h32
-rw-r--r--drivers/net/ethernet/intel/ice/ice_vsi_vlan_ops.c103
-rw-r--r--drivers/net/ethernet/intel/ice/ice_vsi_vlan_ops.h29
-rw-r--r--drivers/net/ethernet/intel/ice/ice_xsk.c396
-rw-r--r--drivers/net/ethernet/intel/ice/ice_xsk.h28
-rw-r--r--drivers/net/ethernet/intel/igb/igb_ethtool.c4
-rw-r--r--drivers/net/ethernet/intel/igb/igb_main.c38
-rw-r--r--drivers/net/ethernet/intel/igb/igb_ptp.c6
-rw-r--r--drivers/net/ethernet/intel/igbvf/netdev.c22
-rw-r--r--drivers/net/ethernet/intel/igc/igc_main.c35
-rw-r--r--drivers/net/ethernet/intel/igc/igc_phy.c4
-rw-r--r--drivers/net/ethernet/intel/ixgb/ixgb_main.c19
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe.h6
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe_common.c36
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c21
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe_main.c63
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe_mbx.h2
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c207
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.h4
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe_type.h10
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe_xsk.c33
-rw-r--r--drivers/net/ethernet/intel/ixgbevf/ixgbevf.h2
-rw-r--r--drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c46
-rw-r--r--drivers/net/ethernet/intel/ixgbevf/mbx.h2
-rw-r--r--drivers/net/ethernet/intel/ixgbevf/vf.c42
-rw-r--r--drivers/net/ethernet/intel/ixgbevf/vf.h1
-rw-r--r--drivers/net/ethernet/jme.c3
-rw-r--r--drivers/net/ethernet/lantiq_xrx200.c2
-rw-r--r--drivers/net/ethernet/litex/Kconfig2
-rw-r--r--drivers/net/ethernet/marvell/mv643xx_eth.c38
-rw-r--r--drivers/net/ethernet/marvell/mvneta.c331
-rw-r--r--drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c6
-rw-r--r--drivers/net/ethernet/marvell/octeontx2/af/cgx.c249
-rw-r--r--drivers/net/ethernet/marvell/octeontx2/af/cgx.h13
-rw-r--r--drivers/net/ethernet/marvell/octeontx2/af/lmac_common.h13
-rw-r--r--drivers/net/ethernet/marvell/octeontx2/af/mbox.h20
-rw-r--r--drivers/net/ethernet/marvell/octeontx2/af/npc.h6
-rw-r--r--drivers/net/ethernet/marvell/octeontx2/af/npc_profile.h70
-rw-r--r--drivers/net/ethernet/marvell/octeontx2/af/ptp.c131
-rw-r--r--drivers/net/ethernet/marvell/octeontx2/af/ptp.h2
-rw-r--r--drivers/net/ethernet/marvell/octeontx2/af/rpm.c290
-rw-r--r--drivers/net/ethernet/marvell/octeontx2/af/rpm.h34
-rw-r--r--drivers/net/ethernet/marvell/octeontx2/af/rvu.c7
-rw-r--r--drivers/net/ethernet/marvell/octeontx2/af/rvu.h4
-rw-r--r--drivers/net/ethernet/marvell/octeontx2/af/rvu_cgx.c131
-rw-r--r--drivers/net/ethernet/marvell/octeontx2/af/rvu_cpt.c1
-rw-r--r--drivers/net/ethernet/marvell/octeontx2/af/rvu_debugfs.c2
-rw-r--r--drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c37
-rw-r--r--drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c22
-rw-r--r--drivers/net/ethernet/marvell/octeontx2/af/rvu_npc_fs.c20
-rw-r--r--drivers/net/ethernet/marvell/octeontx2/nic/Makefile3
-rw-r--r--drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c79
-rw-r--r--drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h22
-rw-r--r--drivers/net/ethernet/marvell/octeontx2/nic/otx2_dcbnl.c170
-rw-r--r--drivers/net/ethernet/marvell/octeontx2/nic/otx2_ethtool.c30
-rw-r--r--drivers/net/ethernet/marvell/octeontx2/nic/otx2_flows.c50
-rw-r--r--drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c82
-rw-r--r--drivers/net/ethernet/marvell/octeontx2/nic/otx2_ptp.c8
-rw-r--r--drivers/net/ethernet/marvell/octeontx2/nic/otx2_ptp.h15
-rw-r--r--drivers/net/ethernet/marvell/octeontx2/nic/otx2_tc.c48
-rw-r--r--drivers/net/ethernet/marvell/octeontx2/nic/otx2_txrx.c6
-rw-r--r--drivers/net/ethernet/marvell/octeontx2/nic/otx2_vf.c55
-rw-r--r--drivers/net/ethernet/marvell/prestera/prestera.h5
-rw-r--r--drivers/net/ethernet/marvell/prestera/prestera_acl.c124
-rw-r--r--drivers/net/ethernet/marvell/prestera/prestera_acl.h30
-rw-r--r--drivers/net/ethernet/marvell/prestera/prestera_flow.c5
-rw-r--r--drivers/net/ethernet/marvell/prestera/prestera_flow.h3
-rw-r--r--drivers/net/ethernet/marvell/prestera/prestera_flower.c87
-rw-r--r--drivers/net/ethernet/marvell/prestera/prestera_flower.h1
-rw-r--r--drivers/net/ethernet/marvell/prestera/prestera_hw.c55
-rw-r--r--drivers/net/ethernet/marvell/prestera/prestera_hw.h6
-rw-r--r--drivers/net/ethernet/marvell/prestera/prestera_main.c14
-rw-r--r--drivers/net/ethernet/marvell/prestera/prestera_router.c412
-rw-r--r--drivers/net/ethernet/marvell/prestera/prestera_router_hw.c132
-rw-r--r--drivers/net/ethernet/marvell/prestera/prestera_router_hw.h44
-rw-r--r--drivers/net/ethernet/mediatek/mtk_star_emac.c2
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/en_rx.c3
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/en_tx.c1
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/Makefile11
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/alloc.c64
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/cmd.c380
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/cq.c18
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/debugfs.c59
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/devlink.c10
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en.h55
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en/params.c106
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en/params.h3
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en/ptp.c3
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en/qos.c45
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en/qos.h1
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en/rep/bond.c32
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en/rep/bridge.c6
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en/rep/tc.c4
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en/rss.c4
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en/selq.c231
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en/selq.h51
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en/tc/act/accept.c8
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en/tc/act/act.c80
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en/tc/act/act.h34
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en/tc/act/csum.c5
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en/tc/act/ct.c34
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en/tc/act/drop.c6
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en/tc/act/goto.c15
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en/tc/act/mark.c3
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en/tc/act/mirred.c26
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en/tc/act/mirred_nic.c6
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en/tc/act/mpls.c27
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en/tc/act/pedit.c64
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en/tc/act/pedit.h2
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en/tc/act/ptype.c3
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en/tc/act/redirect_ingress.c11
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en/tc/act/sample.c40
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en/tc/act/sample.h14
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en/tc/act/trap.c8
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en/tc/act/tun.c6
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en/tc/act/vlan.c32
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en/tc/act/vlan.h1
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en/tc/act/vlan_mangle.c11
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en/tc/ct_fs.h49
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en/tc/ct_fs_dmfs.c79
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en/tc/ct_fs_smfs.c372
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en/tc/post_act.c68
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en/tc/post_act.h8
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en/tc/sample.c89
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en/tc/sample.h6
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en/tc_ct.c209
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en/tc_ct.h6
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en/tc_priv.h22
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun_encap.c78
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun_encap.h6
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun_mplsoudp.c33
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en/tir.c3
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en/txrx.h58
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en/xdp.c216
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en/xdp.h16
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en/xsk/rx.c16
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en/xsk/setup.c2
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en/xsk/tx.c5
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en_accel/en_accel.h9
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c1
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_rxtx.c13
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_rxtx.h9
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls_tx.c6
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en_accel/tls_rxtx.c2
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c12
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c2
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en_main.c170
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en_rep.c36
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en_rep.h14
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en_rx.c256
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en_selftest.c1
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en_stats.c84
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en_stats.h28
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en_tc.c871
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en_tc.h39
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en_tx.c130
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/eq.c10
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/esw/acl/ingress_ofld.c87
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/esw/acl/ofld.h15
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/esw/bridge.c4
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/esw/diag/bridge_tracepoint.h2
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/esw/indir_table.c2
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/esw/qos.c2
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/eswitch.h20
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c184
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads_termtbl.c6
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/fpga/core.c1
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/fs_cmd.c14
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/fs_cmd.h3
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/fs_core.c27
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/fs_core.h7
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/fw.c1
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c59
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/fw_reset.h3
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/health.c1
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/lag/lag.c142
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/lag/lag.h2
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/lag/mp.c13
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/lib/fs_chains.c9
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/lib/hv_vhca.h7
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/lib/port_tun.c1
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/lib/smfs.c68
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/lib/smfs.h36
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/lib/vxlan.c1
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/main.c62
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/mcg.c1
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.h2
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/mr.c1
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/pagealloc.c41
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/pci_irq.c4
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/pd.c1
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/port.c66
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/rl.c1
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/sriov.c17
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/steering/dr_action.c24
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/steering/dr_dbg.c17
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/steering/dr_domain.c2
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/steering/dr_icm_pool.c173
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/steering/dr_matcher.c57
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/steering/dr_rule.c71
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/steering/dr_send.c34
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/steering/dr_ste.c161
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/steering/dr_ste.h7
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/steering/dr_ste_v0.c10
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/steering/dr_ste_v1.c253
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/steering/dr_ste_v1.h94
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/steering/dr_ste_v2.c231
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/steering/dr_table.c23
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/steering/dr_types.h46
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/steering/fs_dr.c44
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/steering/mlx5dr.h10
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/uar.c9
-rw-r--r--drivers/net/ethernet/mellanox/mlxsw/core.c143
-rw-r--r--drivers/net/ethernet/mellanox/mlxsw/core.h17
-rw-r--r--drivers/net/ethernet/mellanox/mlxsw/core_acl_flex_actions.c77
-rw-r--r--drivers/net/ethernet/mellanox/mlxsw/core_acl_flex_actions.h3
-rw-r--r--drivers/net/ethernet/mellanox/mlxsw/core_env.c159
-rw-r--r--drivers/net/ethernet/mellanox/mlxsw/core_env.h3
-rw-r--r--drivers/net/ethernet/mellanox/mlxsw/core_hwmon.c79
-rw-r--r--drivers/net/ethernet/mellanox/mlxsw/core_thermal.c66
-rw-r--r--drivers/net/ethernet/mellanox/mlxsw/minimal.c10
-rw-r--r--drivers/net/ethernet/mellanox/mlxsw/reg.h76
-rw-r--r--drivers/net/ethernet/mellanox/mlxsw/resources.h2
-rw-r--r--drivers/net/ethernet/mellanox/mlxsw/spectrum.c178
-rw-r--r--drivers/net/ethernet/mellanox/mlxsw/spectrum.h32
-rw-r--r--drivers/net/ethernet/mellanox/mlxsw/spectrum1_kvdl.c5
-rw-r--r--drivers/net/ethernet/mellanox/mlxsw/spectrum2_acl_tcam.c12
-rw-r--r--drivers/net/ethernet/mellanox/mlxsw/spectrum_acl.c91
-rw-r--r--drivers/net/ethernet/mellanox/mlxsw/spectrum_dpipe.c4
-rw-r--r--drivers/net/ethernet/mellanox/mlxsw/spectrum_ethtool.c28
-rw-r--r--drivers/net/ethernet/mellanox/mlxsw/spectrum_flower.c53
-rw-r--r--drivers/net/ethernet/mellanox/mlxsw/spectrum_ptp.c3
-rw-r--r--drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c305
-rw-r--r--drivers/net/ethernet/mellanox/mlxsw/spectrum_router.h6
-rw-r--r--drivers/net/ethernet/mellanox/mlxsw/spectrum_span.c3
-rw-r--r--drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c6
-rw-r--r--drivers/net/ethernet/micrel/ks8851_spi.c6
-rw-r--r--drivers/net/ethernet/micrel/ksz884x.c9
-rw-r--r--drivers/net/ethernet/microchip/enc28j60.c6
-rw-r--r--drivers/net/ethernet/microchip/encx24j600.c4
-rw-r--r--drivers/net/ethernet/microchip/lan743x_ethtool.c380
-rw-r--r--drivers/net/ethernet/microchip/lan743x_main.c276
-rw-r--r--drivers/net/ethernet/microchip/lan743x_main.h221
-rw-r--r--drivers/net/ethernet/microchip/lan743x_ptp.c566
-rw-r--r--drivers/net/ethernet/microchip/lan743x_ptp.h10
-rw-r--r--drivers/net/ethernet/microchip/lan966x/Kconfig1
-rw-r--r--drivers/net/ethernet/microchip/lan966x/Makefile3
-rw-r--r--drivers/net/ethernet/microchip/lan966x/lan966x_ethtool.c34
-rw-r--r--drivers/net/ethernet/microchip/lan966x/lan966x_mac.c11
-rw-r--r--drivers/net/ethernet/microchip/lan966x/lan966x_main.c154
-rw-r--r--drivers/net/ethernet/microchip/lan966x/lan966x_main.h56
-rw-r--r--drivers/net/ethernet/microchip/lan966x/lan966x_mdb.c45
-rw-r--r--drivers/net/ethernet/microchip/lan966x/lan966x_phylink.c9
-rw-r--r--drivers/net/ethernet/microchip/lan966x/lan966x_ptp.c618
-rw-r--r--drivers/net/ethernet/microchip/lan966x/lan966x_regs.h121
-rw-r--r--drivers/net/ethernet/microchip/lan966x/lan966x_switchdev.c85
-rw-r--r--drivers/net/ethernet/microchip/sparx5/Makefile3
-rw-r--r--drivers/net/ethernet/microchip/sparx5/sparx5_ethtool.c36
-rw-r--r--drivers/net/ethernet/microchip/sparx5/sparx5_fdma.c2
-rw-r--r--drivers/net/ethernet/microchip/sparx5/sparx5_mactable.c44
-rw-r--r--drivers/net/ethernet/microchip/sparx5/sparx5_main.c26
-rw-r--r--drivers/net/ethernet/microchip/sparx5/sparx5_main.h94
-rw-r--r--drivers/net/ethernet/microchip/sparx5/sparx5_main_regs.h335
-rw-r--r--drivers/net/ethernet/microchip/sparx5/sparx5_netdev.c42
-rw-r--r--drivers/net/ethernet/microchip/sparx5/sparx5_packet.c39
-rw-r--r--drivers/net/ethernet/microchip/sparx5/sparx5_pgid.c60
-rw-r--r--drivers/net/ethernet/microchip/sparx5/sparx5_phylink.c10
-rw-r--r--drivers/net/ethernet/microchip/sparx5/sparx5_ptp.c685
-rw-r--r--drivers/net/ethernet/microchip/sparx5/sparx5_switchdev.c251
-rw-r--r--drivers/net/ethernet/microchip/sparx5/sparx5_vlan.c20
-rw-r--r--drivers/net/ethernet/microsoft/mana/gdma_main.c4
-rw-r--r--drivers/net/ethernet/microsoft/mana/mana.h15
-rw-r--r--drivers/net/ethernet/microsoft/mana/mana_en.c70
-rw-r--r--drivers/net/ethernet/microsoft/mana/mana_ethtool.c35
-rw-r--r--drivers/net/ethernet/moxa/moxart_ether.c4
-rw-r--r--drivers/net/ethernet/mscc/ocelot.c685
-rw-r--r--drivers/net/ethernet/mscc/ocelot.h18
-rw-r--r--drivers/net/ethernet/mscc/ocelot_flower.c54
-rw-r--r--drivers/net/ethernet/mscc/ocelot_io.c13
-rw-r--r--drivers/net/ethernet/mscc/ocelot_mrp.c64
-rw-r--r--drivers/net/ethernet/mscc/ocelot_net.c251
-rw-r--r--drivers/net/ethernet/mscc/ocelot_police.c41
-rw-r--r--drivers/net/ethernet/mscc/ocelot_police.h5
-rw-r--r--drivers/net/ethernet/mscc/ocelot_vcap.c66
-rw-r--r--drivers/net/ethernet/netronome/nfp/Makefile8
-rw-r--r--drivers/net/ethernet/netronome/nfp/flower/action.c58
-rw-r--r--drivers/net/ethernet/netronome/nfp/flower/cmsg.h9
-rw-r--r--drivers/net/ethernet/netronome/nfp/flower/main.c4
-rw-r--r--drivers/net/ethernet/netronome/nfp/flower/main.h49
-rw-r--r--drivers/net/ethernet/netronome/nfp/flower/offload.c16
-rw-r--r--drivers/net/ethernet/netronome/nfp/flower/qos_conf.c470
-rw-r--r--drivers/net/ethernet/netronome/nfp/flower/tunnel_conf.c28
-rw-r--r--drivers/net/ethernet/netronome/nfp/nfd3/dp.c1350
-rw-r--r--drivers/net/ethernet/netronome/nfp/nfd3/nfd3.h106
-rw-r--r--drivers/net/ethernet/netronome/nfp/nfd3/rings.c275
-rw-r--r--drivers/net/ethernet/netronome/nfp/nfd3/xsk.c408
-rw-r--r--drivers/net/ethernet/netronome/nfp/nfdk/dp.c1524
-rw-r--r--drivers/net/ethernet/netronome/nfp/nfdk/nfdk.h129
-rw-r--r--drivers/net/ethernet/netronome/nfp/nfdk/rings.c195
-rw-r--r--drivers/net/ethernet/netronome/nfp/nfp_app.c2
-rw-r--r--drivers/net/ethernet/netronome/nfp/nfp_app.h12
-rw-r--r--drivers/net/ethernet/netronome/nfp/nfp_devlink.c58
-rw-r--r--drivers/net/ethernet/netronome/nfp/nfp_main.c43
-rw-r--r--drivers/net/ethernet/netronome/nfp/nfp_main.h8
-rw-r--r--drivers/net/ethernet/netronome/nfp/nfp_net.h204
-rw-r--r--drivers/net/ethernet/netronome/nfp/nfp_net_common.c2132
-rw-r--r--drivers/net/ethernet/netronome/nfp/nfp_net_ctrl.h87
-rw-r--r--drivers/net/ethernet/netronome/nfp/nfp_net_debugfs.c66
-rw-r--r--drivers/net/ethernet/netronome/nfp/nfp_net_dp.c442
-rw-r--r--drivers/net/ethernet/netronome/nfp/nfp_net_dp.h215
-rw-r--r--drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c18
-rw-r--r--drivers/net/ethernet/netronome/nfp/nfp_net_main.c51
-rw-r--r--drivers/net/ethernet/netronome/nfp/nfp_net_repr.c4
-rw-r--r--drivers/net/ethernet/netronome/nfp/nfp_net_sriov.h3
-rw-r--r--drivers/net/ethernet/netronome/nfp/nfp_net_xsk.c170
-rw-r--r--drivers/net/ethernet/netronome/nfp/nfp_net_xsk.h41
-rw-r--r--drivers/net/ethernet/netronome/nfp/nfp_netvf_main.c32
-rw-r--r--drivers/net/ethernet/netronome/nfp/nfp_port.c17
-rw-r--r--drivers/net/ethernet/netronome/nfp/nfp_port.h5
-rw-r--r--drivers/net/ethernet/netronome/nfp/nfpcore/nfp6000_pcie.c29
-rw-r--r--drivers/net/ethernet/netronome/nfp/nfpcore/nfp6000_pcie.h3
-rw-r--r--drivers/net/ethernet/netronome/nfp/nfpcore/nfp_cpp.h4
-rw-r--r--drivers/net/ethernet/netronome/nfp/nfpcore/nfp_cpplib.c9
-rw-r--r--drivers/net/ethernet/netronome/nfp/nfpcore/nfp_dev.c49
-rw-r--r--drivers/net/ethernet/netronome/nfp/nfpcore/nfp_dev.h34
-rw-r--r--drivers/net/ethernet/netronome/nfp/nfpcore/nfp_nsp.c2
-rw-r--r--drivers/net/ethernet/ni/nixge.c5
-rw-r--r--drivers/net/ethernet/nxp/lpc_eth.c5
-rw-r--r--drivers/net/ethernet/packetengines/yellowfin.c2
-rw-r--r--drivers/net/ethernet/pensando/ionic/ionic.h7
-rw-r--r--drivers/net/ethernet/pensando/ionic/ionic_bus_pci.c17
-rw-r--r--drivers/net/ethernet/pensando/ionic/ionic_dev.c164
-rw-r--r--drivers/net/ethernet/pensando/ionic/ionic_dev.h6
-rw-r--r--drivers/net/ethernet/pensando/ionic/ionic_ethtool.c6
-rw-r--r--drivers/net/ethernet/pensando/ionic/ionic_if.h6
-rw-r--r--drivers/net/ethernet/pensando/ionic/ionic_lif.c206
-rw-r--r--drivers/net/ethernet/pensando/ionic/ionic_lif.h2
-rw-r--r--drivers/net/ethernet/pensando/ionic/ionic_main.c125
-rw-r--r--drivers/net/ethernet/pensando/ionic/ionic_rx_filter.c37
-rw-r--r--drivers/net/ethernet/pensando/ionic/ionic_stats.c1
-rw-r--r--drivers/net/ethernet/pensando/ionic/ionic_txrx.c67
-rw-r--r--drivers/net/ethernet/qlogic/qed/qed_dev.c3
-rw-r--r--drivers/net/ethernet/qlogic/qed/qed_init_fw_funcs.c2
-rw-r--r--drivers/net/ethernet/qlogic/qed/qed_mcp.c90
-rw-r--r--drivers/net/ethernet/qlogic/qed/qed_mcp.h38
-rw-r--r--drivers/net/ethernet/qlogic/qed/qed_mfw_hsi.h2
-rw-r--r--drivers/net/ethernet/qlogic/qed/qed_sriov.c47
-rw-r--r--drivers/net/ethernet/qlogic/qed/qed_sriov.h1
-rw-r--r--drivers/net/ethernet/qlogic/qed/qed_vf.c7
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c2
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c3
-rw-r--r--drivers/net/ethernet/qualcomm/qca_spi.c6
-rw-r--r--drivers/net/ethernet/qualcomm/qca_uart.c2
-rw-r--r--drivers/net/ethernet/qualcomm/rmnet/rmnet_handlers.c2
-rw-r--r--drivers/net/ethernet/qualcomm/rmnet/rmnet_map_data.c4
-rw-r--r--drivers/net/ethernet/realtek/r8169_main.c94
-rw-r--r--drivers/net/ethernet/realtek/r8169_phy_config.c71
-rw-r--r--drivers/net/ethernet/renesas/ravb_main.c15
-rw-r--r--drivers/net/ethernet/renesas/sh_eth.c18
-rw-r--r--drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c8
-rw-r--r--drivers/net/ethernet/seeq/ether3.c4
-rw-r--r--drivers/net/ethernet/sfc/ef10.c26
-rw-r--r--drivers/net/ethernet/sfc/ef100_nic.c9
-rw-r--r--drivers/net/ethernet/sfc/efx_channels.c63
-rw-r--r--drivers/net/ethernet/sfc/mcdi.c2
-rw-r--r--drivers/net/ethernet/sfc/net_driver.h2
-rw-r--r--drivers/net/ethernet/sfc/nic_common.h5
-rw-r--r--drivers/net/ethernet/sfc/rx_common.c18
-rw-r--r--drivers/net/ethernet/sfc/rx_common.h6
-rw-r--r--drivers/net/ethernet/sfc/siena.c8
-rw-r--r--drivers/net/ethernet/smsc/smc911x.c8
-rw-r--r--drivers/net/ethernet/socionext/netsec.c2
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c9
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/dwmac-mediatek.c388
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c37
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c32
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/dwmac-visconti.c51
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h1
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/stmmac.h4
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c19
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/stmmac_hwtstamp.c23
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/stmmac_main.c228
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c25
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/stmmac_selftests.c8
-rw-r--r--drivers/net/ethernet/sun/cassini.c23
-rw-r--r--drivers/net/ethernet/sun/niu.c2
-rw-r--r--drivers/net/ethernet/sun/sunhme.c6
-rw-r--r--drivers/net/ethernet/ti/am65-cpsw-ethtool.c56
-rw-r--r--drivers/net/ethernet/ti/am65-cpsw-nuss.c228
-rw-r--r--drivers/net/ethernet/ti/am65-cpsw-nuss.h5
-rw-r--r--drivers/net/ethernet/ti/am65-cpsw-switchdev.c4
-rw-r--r--drivers/net/ethernet/ti/cpsw_ethtool.c6
-rw-r--r--drivers/net/ethernet/ti/cpsw_priv.c2
-rw-r--r--drivers/net/ethernet/ti/cpsw_switchdev.c4
-rw-r--r--drivers/net/ethernet/ti/cpts.c4
-rw-r--r--drivers/net/ethernet/ti/davinci_emac.c25
-rw-r--r--drivers/net/ethernet/ti/davinci_mdio.c2
-rw-r--r--drivers/net/ethernet/ti/netcp_core.c2
-rw-r--r--drivers/net/ethernet/tundra/tsi108_eth.c35
-rw-r--r--drivers/net/ethernet/vertexcom/mse102x.c6
-rw-r--r--drivers/net/ethernet/wiznet/w5100-spi.c4
-rw-r--r--drivers/net/ethernet/wiznet/w5100.c2
-rw-r--r--drivers/net/ethernet/xilinx/Kconfig2
-rw-r--r--drivers/net/ethernet/xilinx/ll_temac.h4
-rw-r--r--drivers/net/ethernet/xilinx/ll_temac_main.c9
-rw-r--r--drivers/net/ethernet/xilinx/xilinx_axienet.h20
-rw-r--r--drivers/net/ethernet/xilinx/xilinx_axienet_main.c608
-rw-r--r--drivers/net/ethernet/xilinx/xilinx_emaclite.c6
-rw-r--r--drivers/net/ethernet/xscale/Kconfig4
-rw-r--r--drivers/net/ethernet/xscale/ixp4xx_eth.c85
-rw-r--r--drivers/net/ethernet/xscale/ptp_ixp46x.c1
-rw-r--r--drivers/net/fjes/fjes_main.c5
-rw-r--r--drivers/net/geneve.c89
-rw-r--r--drivers/net/gtp.c567
-rw-r--r--drivers/net/hamradio/6pack.c4
-rw-r--r--drivers/net/hamradio/baycom_epp.c4
-rw-r--r--drivers/net/hamradio/dmascc.c7
-rw-r--r--drivers/net/hamradio/yam.c4
-rw-r--r--drivers/net/hyperv/netvsc.c25
-rw-r--r--drivers/net/hyperv/netvsc_drv.c3
-rw-r--r--drivers/net/ieee802154/adf7242.c4
-rw-r--r--drivers/net/ieee802154/at86rf230.c17
-rw-r--r--drivers/net/ieee802154/atusb.c186
-rw-r--r--drivers/net/ieee802154/ca8210.c11
-rw-r--r--drivers/net/ieee802154/cc2520.c4
-rw-r--r--drivers/net/ieee802154/mac802154_hwsim.c3
-rw-r--r--drivers/net/ieee802154/mcr20a.c8
-rw-r--r--drivers/net/ieee802154/mrf24j40.c4
-rw-r--r--drivers/net/ipa/Kconfig2
-rw-r--r--drivers/net/ipa/gsi_trans.c11
-rw-r--r--drivers/net/ipa/gsi_trans.h10
-rw-r--r--drivers/net/ipa/ipa_data-v3.1.c2
-rw-r--r--drivers/net/ipa/ipa_data-v3.5.1.c2
-rw-r--r--drivers/net/ipa/ipa_data-v4.11.c2
-rw-r--r--drivers/net/ipa/ipa_data-v4.2.c2
-rw-r--r--drivers/net/ipa/ipa_data-v4.5.c2
-rw-r--r--drivers/net/ipa/ipa_data-v4.9.c2
-rw-r--r--drivers/net/ipa/ipa_data.h2
-rw-r--r--drivers/net/ipa/ipa_endpoint.c217
-rw-r--r--drivers/net/ipa/ipa_endpoint.h8
-rw-r--r--drivers/net/ipa/ipa_power.c230
-rw-r--r--drivers/net/ipa/ipa_power.h7
-rw-r--r--drivers/net/ipa/ipa_uc.c5
-rw-r--r--drivers/net/ipvlan/ipvlan_core.c2
-rw-r--r--drivers/net/loopback.c6
-rw-r--r--drivers/net/macsec.c39
-rw-r--r--drivers/net/macvlan.c22
-rw-r--r--drivers/net/macvtap.c6
-rw-r--r--drivers/net/mctp/Kconfig12
-rw-r--r--drivers/net/mctp/Makefile1
-rw-r--r--drivers/net/mctp/mctp-i2c.c1082
-rw-r--r--drivers/net/mctp/mctp-serial.c11
-rw-r--r--drivers/net/mdio/mdio-aspeed.c1
-rw-r--r--drivers/net/mdio/mdio-ipq4019.c6
-rw-r--r--drivers/net/mdio/mdio-mscc-miim.c76
-rw-r--r--drivers/net/mdio/mdio-mux.c4
-rw-r--r--drivers/net/mdio/mdio-xgene.c3
-rw-r--r--drivers/net/mhi_net.c2
-rw-r--r--drivers/net/net_failover.c2
-rw-r--r--drivers/net/netdevsim/Makefile2
-rw-r--r--drivers/net/netdevsim/dev.c102
-rw-r--r--drivers/net/netdevsim/fib.c4
-rw-r--r--drivers/net/netdevsim/hwstats.c486
-rw-r--r--drivers/net/netdevsim/netdevsim.h25
-rw-r--r--drivers/net/ntb_netdev.c2
-rw-r--r--drivers/net/pcs/pcs-xpcs.c41
-rw-r--r--drivers/net/phy/Kconfig1
-rw-r--r--drivers/net/phy/aquantia_main.c4
-rw-r--r--drivers/net/phy/at803x.c172
-rw-r--r--drivers/net/phy/broadcom.c1
-rw-r--r--drivers/net/phy/dp83640.c19
-rw-r--r--drivers/net/phy/dp83822.c2
-rw-r--r--drivers/net/phy/marvell.c25
-rw-r--r--drivers/net/phy/mediatek-ge.c3
-rw-r--r--drivers/net/phy/meson-gxl.c31
-rw-r--r--drivers/net/phy/micrel.c1103
-rw-r--r--drivers/net/phy/microchip_t1.c359
-rw-r--r--drivers/net/phy/mscc/mscc_main.c3
-rw-r--r--drivers/net/phy/mscc/mscc_ptp.c2
-rw-r--r--drivers/net/phy/nxp-c45-tja11xx.c2
-rw-r--r--drivers/net/phy/phy-core.c22
-rw-r--r--drivers/net/phy/phy_device.c25
-rw-r--r--drivers/net/phy/phylink.c90
-rw-r--r--drivers/net/phy/sfp-bus.c11
-rw-r--r--drivers/net/phy/sfp.c48
-rw-r--r--drivers/net/phy/spi_ks8995.c4
-rw-r--r--drivers/net/plip/plip.c2
-rw-r--r--drivers/net/rionet.c2
-rw-r--r--drivers/net/sb1000.c2
-rw-r--r--drivers/net/slip/slip.c2
-rw-r--r--drivers/net/tap.c38
-rw-r--r--drivers/net/team/team.c5
-rw-r--r--drivers/net/tun.c102
-rw-r--r--drivers/net/usb/Kconfig1
-rw-r--r--drivers/net/usb/asix.h10
-rw-r--r--drivers/net/usb/asix_common.c81
-rw-r--r--drivers/net/usb/asix_devices.c104
-rw-r--r--drivers/net/usb/ax88179_178a.c68
-rw-r--r--drivers/net/usb/cdc_ether.c12
-rw-r--r--drivers/net/usb/cdc_mbim.c6
-rw-r--r--drivers/net/usb/cdc_ncm.c8
-rw-r--r--drivers/net/usb/gl620a.c2
-rw-r--r--drivers/net/usb/hso.c2
-rw-r--r--drivers/net/usb/ipheth.c6
-rw-r--r--drivers/net/usb/lan78xx.c7
-rw-r--r--drivers/net/usb/qmi_wwan.c2
-rw-r--r--drivers/net/usb/smsc95xx.c53
-rw-r--r--drivers/net/usb/sr9700.c2
-rw-r--r--drivers/net/usb/zaurus.c12
-rw-r--r--drivers/net/veth.c207
-rw-r--r--drivers/net/virtio_net.c3
-rw-r--r--drivers/net/vrf.c9
-rw-r--r--drivers/net/vxlan/Makefile7
-rw-r--r--drivers/net/vxlan/vxlan_core.c (renamed from drivers/net/vxlan.c)495
-rw-r--r--drivers/net/vxlan/vxlan_multicast.c272
-rw-r--r--drivers/net/vxlan/vxlan_private.h162
-rw-r--r--drivers/net/vxlan/vxlan_vnifilter.c999
-rw-r--r--drivers/net/wan/Kconfig3
-rw-r--r--drivers/net/wan/ixp4xx_hss.c39
-rw-r--r--drivers/net/wan/lmc/lmc_main.c3
-rw-r--r--drivers/net/wan/slic_ds26522.c3
-rw-r--r--drivers/net/wireguard/device.c38
-rw-r--r--drivers/net/wireless/ath/ar5523/ar5523.c2
-rw-r--r--drivers/net/wireless/ath/ath10k/core.c16
-rw-r--r--drivers/net/wireless/ath/ath10k/htt.c153
-rw-r--r--drivers/net/wireless/ath/ath10k/htt.h296
-rw-r--r--drivers/net/wireless/ath/ath10k/htt_rx.c331
-rw-r--r--drivers/net/wireless/ath/ath10k/htt_tx.c36
-rw-r--r--drivers/net/wireless/ath/ath10k/hw.c15
-rw-r--r--drivers/net/wireless/ath/ath10k/hw.h27
-rw-r--r--drivers/net/wireless/ath/ath10k/rx_desc.h40
-rw-r--r--drivers/net/wireless/ath/ath10k/snoc.c17
-rw-r--r--drivers/net/wireless/ath/ath10k/swap.h2
-rw-r--r--drivers/net/wireless/ath/ath10k/txrx.c2
-rw-r--r--drivers/net/wireless/ath/ath10k/wmi.c35
-rw-r--r--drivers/net/wireless/ath/ath10k/wow.c7
-rw-r--r--drivers/net/wireless/ath/ath11k/ahb.c6
-rw-r--r--drivers/net/wireless/ath/ath11k/ce.h2
-rw-r--r--drivers/net/wireless/ath/ath11k/core.c15
-rw-r--r--drivers/net/wireless/ath/ath11k/core.h12
-rw-r--r--drivers/net/wireless/ath/ath11k/dbring.c19
-rw-r--r--drivers/net/wireless/ath/ath11k/debugfs.c515
-rw-r--r--drivers/net/wireless/ath/ath11k/debugfs.h180
-rw-r--r--drivers/net/wireless/ath/ath11k/dp.h13
-rw-r--r--drivers/net/wireless/ath/ath11k/dp_rx.c357
-rw-r--r--drivers/net/wireless/ath/ath11k/dp_tx.c35
-rw-r--r--drivers/net/wireless/ath/ath11k/hal_desc.h1
-rw-r--r--drivers/net/wireless/ath/ath11k/hal_rx.c471
-rw-r--r--drivers/net/wireless/ath/ath11k/hal_rx.h143
-rw-r--r--drivers/net/wireless/ath/ath11k/hw.c23
-rw-r--r--drivers/net/wireless/ath/ath11k/hw.h3
-rw-r--r--drivers/net/wireless/ath/ath11k/mac.c116
-rw-r--r--drivers/net/wireless/ath/ath11k/mhi.c5
-rw-r--r--drivers/net/wireless/ath/ath11k/pci.c10
-rw-r--r--drivers/net/wireless/ath/ath11k/peer.c40
-rw-r--r--drivers/net/wireless/ath/ath11k/qmi.c15
-rw-r--r--drivers/net/wireless/ath/ath11k/qmi.h1
-rw-r--r--drivers/net/wireless/ath/ath11k/reg.c25
-rw-r--r--drivers/net/wireless/ath/ath11k/rx_desc.h6
-rw-r--r--drivers/net/wireless/ath/ath11k/spectral.c2
-rw-r--r--drivers/net/wireless/ath/ath11k/wmi.c300
-rw-r--r--drivers/net/wireless/ath/ath11k/wmi.h132
-rw-r--r--drivers/net/wireless/ath/ath5k/ath5k.h4
-rw-r--r--drivers/net/wireless/ath/ath5k/dma.c23
-rw-r--r--drivers/net/wireless/ath/ath5k/eeprom.c3
-rw-r--r--drivers/net/wireless/ath/ath6kl/txrx.c2
-rw-r--r--drivers/net/wireless/ath/ath6kl/usb.c1
-rw-r--r--drivers/net/wireless/ath/ath6kl/wmi.c22
-rw-r--r--drivers/net/wireless/ath/ath6kl/wmi.h38
-rw-r--r--drivers/net/wireless/ath/ath9k/ath9k.h3
-rw-r--r--drivers/net/wireless/ath/ath9k/eeprom.c6
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_hst.c5
-rw-r--r--drivers/net/wireless/ath/ath9k/mci.c2
-rw-r--r--drivers/net/wireless/ath/ath9k/rng.c72
-rw-r--r--drivers/net/wireless/ath/carl9170/carl9170.h1
-rw-r--r--drivers/net/wireless/ath/carl9170/fwdesc.h2
-rw-r--r--drivers/net/wireless/ath/carl9170/main.c61
-rw-r--r--drivers/net/wireless/ath/carl9170/wlan.h2
-rw-r--r--drivers/net/wireless/ath/dfs_pattern_detector.c6
-rw-r--r--drivers/net/wireless/ath/regd.c10
-rw-r--r--drivers/net/wireless/ath/spectral_common.h4
-rw-r--r--drivers/net/wireless/ath/wcn36xx/main.c107
-rw-r--r--drivers/net/wireless/ath/wcn36xx/smd.c2
-rw-r--r--drivers/net/wireless/ath/wcn36xx/txrx.c36
-rw-r--r--drivers/net/wireless/ath/wcn36xx/wcn36xx.h14
-rw-r--r--drivers/net/wireless/ath/wil6210/txrx.c2
-rw-r--r--drivers/net/wireless/ath/wil6210/wmi.c2
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcdc.c4
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c35
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c2
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c18
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h2
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c3
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c8
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil.c34
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil.h28
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h2
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c10
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.h2
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c5
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c10
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c20
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c78
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmfmac/proto.h6
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c2
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmfmac/xtlv.h2
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h2
-rw-r--r--drivers/net/wireless/cisco/airo.c2
-rw-r--r--drivers/net/wireless/intel/Makefile1
-rw-r--r--drivers/net/wireless/intel/iwlwifi/Kconfig14
-rw-r--r--drivers/net/wireless/intel/iwlwifi/cfg/22000.c55
-rw-r--r--drivers/net/wireless/intel/iwlwifi/dvm/mac80211.c2
-rw-r--r--drivers/net/wireless/intel/iwlwifi/dvm/main.c1
-rw-r--r--drivers/net/wireless/intel/iwlwifi/dvm/rx.c7
-rw-r--r--drivers/net/wireless/intel/iwlwifi/fw/acpi.c240
-rw-r--r--drivers/net/wireless/intel/iwlwifi/fw/acpi.h39
-rw-r--r--drivers/net/wireless/intel/iwlwifi/fw/api/commands.h18
-rw-r--r--drivers/net/wireless/intel/iwlwifi/fw/api/config.h33
-rw-r--r--drivers/net/wireless/intel/iwlwifi/fw/api/datapath.h148
-rw-r--r--drivers/net/wireless/intel/iwlwifi/fw/api/dbg-tlv.h37
-rw-r--r--drivers/net/wireless/intel/iwlwifi/fw/api/debug.h19
-rw-r--r--drivers/net/wireless/intel/iwlwifi/fw/api/filter.h88
-rw-r--r--drivers/net/wireless/intel/iwlwifi/fw/api/mac-cfg.h34
-rw-r--r--drivers/net/wireless/intel/iwlwifi/fw/api/mac.h127
-rw-r--r--drivers/net/wireless/intel/iwlwifi/fw/api/nvm-reg.h52
-rw-r--r--drivers/net/wireless/intel/iwlwifi/fw/api/phy.h16
-rw-r--r--drivers/net/wireless/intel/iwlwifi/fw/api/power.h27
-rw-r--r--drivers/net/wireless/intel/iwlwifi/fw/api/rfi.h10
-rw-r--r--drivers/net/wireless/intel/iwlwifi/fw/api/rs.h7
-rw-r--r--drivers/net/wireless/intel/iwlwifi/fw/api/tx.h7
-rw-r--r--drivers/net/wireless/intel/iwlwifi/fw/api/txq.h4
-rw-r--r--drivers/net/wireless/intel/iwlwifi/fw/dbg.c331
-rw-r--r--drivers/net/wireless/intel/iwlwifi/fw/dbg.h5
-rw-r--r--drivers/net/wireless/intel/iwlwifi/fw/debugfs.c4
-rw-r--r--drivers/net/wireless/intel/iwlwifi/fw/file.h38
-rw-r--r--drivers/net/wireless/intel/iwlwifi/fw/img.c7
-rw-r--r--drivers/net/wireless/intel/iwlwifi/fw/img.h14
-rw-r--r--drivers/net/wireless/intel/iwlwifi/fw/init.c5
-rw-r--r--drivers/net/wireless/intel/iwlwifi/fw/paging.c4
-rw-r--r--drivers/net/wireless/intel/iwlwifi/fw/pnvm.c22
-rw-r--r--drivers/net/wireless/intel/iwlwifi/fw/rs.c33
-rw-r--r--drivers/net/wireless/intel/iwlwifi/fw/runtime.h5
-rw-r--r--drivers/net/wireless/intel/iwlwifi/fw/smem.c4
-rw-r--r--drivers/net/wireless/intel/iwlwifi/fw/uefi.c12
-rw-r--r--drivers/net/wireless/intel/iwlwifi/iwl-config.h17
-rw-r--r--drivers/net/wireless/intel/iwlwifi/iwl-context-info-gen3.h4
-rw-r--r--drivers/net/wireless/intel/iwlwifi/iwl-csr.h6
-rw-r--r--drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c72
-rw-r--r--drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.h4
-rw-r--r--drivers/net/wireless/intel/iwlwifi/iwl-drv.c183
-rw-r--r--drivers/net/wireless/intel/iwlwifi/iwl-drv.h2
-rw-r--r--drivers/net/wireless/intel/iwlwifi/iwl-eeprom-read.c12
-rw-r--r--drivers/net/wireless/intel/iwlwifi/iwl-fh.h30
-rw-r--r--drivers/net/wireless/intel/iwlwifi/iwl-io.c18
-rw-r--r--drivers/net/wireless/intel/iwlwifi/iwl-modparams.h5
-rw-r--r--drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c46
-rw-r--r--drivers/net/wireless/intel/iwlwifi/iwl-phy-db.c4
-rw-r--r--drivers/net/wireless/intel/iwlwifi/iwl-prph.h13
-rw-r--r--drivers/net/wireless/intel/iwlwifi/iwl-trans.c12
-rw-r--r--drivers/net/wireless/intel/iwlwifi/iwl-trans.h59
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mei/main.c55
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mei/net.c7
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/d3.c29
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c232
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/ftm-initiator.c25
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/ftm-responder.c24
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/fw.c407
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c50
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c602
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/mvm.h32
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/offloading.c3
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/ops.c35
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/phy-ctxt.c43
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/quota.c2
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/rfi.c13
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/rs-fw.c32
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/rs.c2
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/rx.c6
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c7
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/scan.c294
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/sta.c313
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/sta.h3
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/time-event.c20
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/tt.c11
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/tx.c22
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/utils.c40
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/vendor-cmd.c5
-rw-r--r--drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info-gen3.c5
-rw-r--r--drivers/net/wireless/intel/iwlwifi/pcie/drv.c38
-rw-r--r--drivers/net/wireless/intel/iwlwifi/pcie/internal.h46
-rw-r--r--drivers/net/wireless/intel/iwlwifi/pcie/rx.c112
-rw-r--r--drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c3
-rw-r--r--drivers/net/wireless/intel/iwlwifi/pcie/trans.c54
-rw-r--r--drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c4
-rw-r--r--drivers/net/wireless/intel/iwlwifi/pcie/tx.c14
-rw-r--r--drivers/net/wireless/intel/iwlwifi/queue/tx.c101
-rw-r--r--drivers/net/wireless/intel/iwlwifi/queue/tx.h21
-rw-r--r--drivers/net/wireless/intersil/p54/p54spi.c4
-rw-r--r--drivers/net/wireless/mac80211_hwsim.c423
-rw-r--r--drivers/net/wireless/marvell/libertas/if_spi.c4
-rw-r--r--drivers/net/wireless/marvell/libertas/rx.c4
-rw-r--r--drivers/net/wireless/marvell/mwifiex/uap_cmd.c2
-rw-r--r--drivers/net/wireless/marvell/mwifiex/uap_txrx.c2
-rw-r--r--drivers/net/wireless/marvell/mwifiex/util.c2
-rw-r--r--drivers/net/wireless/mediatek/mt76/dma.c14
-rw-r--r--drivers/net/wireless/mediatek/mt76/mac80211.c63
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt76.h36
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7603/dma.c2
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7603/mac.c14
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7603/main.c3
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7615/debugfs.c29
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7615/init.c1
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7615/mac.c194
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7615/main.c36
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7615/mcu.c236
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7615/mmio.c1
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7615/mt7615.h23
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7615/sdio.c15
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7615/usb.c91
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7615/usb_mcu.c36
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt76_connac.h76
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c422
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h118
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt76x0/usb.c2
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt76x02.h3
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt76x02_dfs.c5
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt76x02_mac.c27
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt76x02_mmio.c30
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt76x02_regs.h2
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt76x2/usb.c2
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7915/Kconfig13
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7915/Makefile1
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7915/debugfs.c225
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7915/dma.c466
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7915/eeprom.c188
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7915/eeprom.h54
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7915/init.c310
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7915/mac.c777
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7915/mac.h15
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7915/main.c152
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7915/mcu.c1533
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7915/mcu.h63
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7915/mmio.c691
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h130
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7915/pci.c259
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7915/regs.h893
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7915/soc.c1212
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7915/testmode.c106
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7921/Kconfig11
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7921/Makefile2
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7921/debugfs.c65
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7921/dma.c121
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7921/init.c70
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7921/mac.c209
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7921/mac.h4
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7921/main.c70
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7921/mcu.c313
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h63
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7921/pci.c126
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7921/pci_mac.c48
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7921/pci_mcu.c20
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7921/regs.h64
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7921/sdio.c22
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7921/sdio_mac.c89
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7921/sdio_mcu.c40
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7921/usb.c306
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7921/usb_mac.c252
-rw-r--r--drivers/net/wireless/mediatek/mt76/sdio.c14
-rw-r--r--drivers/net/wireless/mediatek/mt76/sdio.h2
-rw-r--r--drivers/net/wireless/mediatek/mt76/sdio_txrx.c28
-rw-r--r--drivers/net/wireless/mediatek/mt76/testmode.c5
-rw-r--r--drivers/net/wireless/mediatek/mt76/usb.c125
-rw-r--r--drivers/net/wireless/microchip/wilc1000/spi.c9
-rw-r--r--drivers/net/wireless/ray_cs.c6
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/cam.c2
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8192ce/phy.c32
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8192cu/sw.c1
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8821ae/dm.c6
-rw-r--r--drivers/net/wireless/realtek/rtw88/coex.c298
-rw-r--r--drivers/net/wireless/realtek/rtw88/coex.h5
-rw-r--r--drivers/net/wireless/realtek/rtw88/debug.c6
-rw-r--r--drivers/net/wireless/realtek/rtw88/debug.h1
-rw-r--r--drivers/net/wireless/realtek/rtw88/fw.c59
-rw-r--r--drivers/net/wireless/realtek/rtw88/fw.h9
-rw-r--r--drivers/net/wireless/realtek/rtw88/mac80211.c13
-rw-r--r--drivers/net/wireless/realtek/rtw88/main.c127
-rw-r--r--drivers/net/wireless/realtek/rtw88/main.h52
-rw-r--r--drivers/net/wireless/realtek/rtw88/rtw8723d.c1
-rw-r--r--drivers/net/wireless/realtek/rtw88/rtw8821c.c4
-rw-r--r--drivers/net/wireless/realtek/rtw88/rtw8822b.c5
-rw-r--r--drivers/net/wireless/realtek/rtw88/rtw8822c.c47
-rw-r--r--drivers/net/wireless/realtek/rtw88/sar.c8
-rw-r--r--drivers/net/wireless/realtek/rtw88/tx.c2
-rw-r--r--drivers/net/wireless/realtek/rtw89/Kconfig4
-rw-r--r--drivers/net/wireless/realtek/rtw89/Makefile13
-rw-r--r--drivers/net/wireless/realtek/rtw89/cam.c40
-rw-r--r--drivers/net/wireless/realtek/rtw89/cam.h5
-rw-r--r--drivers/net/wireless/realtek/rtw89/coex.c41
-rw-r--r--drivers/net/wireless/realtek/rtw89/core.c679
-rw-r--r--drivers/net/wireless/realtek/rtw89/core.h291
-rw-r--r--drivers/net/wireless/realtek/rtw89/debug.c93
-rw-r--r--drivers/net/wireless/realtek/rtw89/debug.h1
-rw-r--r--drivers/net/wireless/realtek/rtw89/efuse.c160
-rw-r--r--drivers/net/wireless/realtek/rtw89/fw.c686
-rw-r--r--drivers/net/wireless/realtek/rtw89/fw.h491
-rw-r--r--drivers/net/wireless/realtek/rtw89/mac.c646
-rw-r--r--drivers/net/wireless/realtek/rtw89/mac.h84
-rw-r--r--drivers/net/wireless/realtek/rtw89/mac80211.c147
-rw-r--r--drivers/net/wireless/realtek/rtw89/pci.c361
-rw-r--r--drivers/net/wireless/realtek/rtw89/pci.h81
-rw-r--r--drivers/net/wireless/realtek/rtw89/phy.c521
-rw-r--r--drivers/net/wireless/realtek/rtw89/phy.h75
-rw-r--r--drivers/net/wireless/realtek/rtw89/reg.h217
-rw-r--r--drivers/net/wireless/realtek/rtw89/rtw8852a.c79
-rw-r--r--drivers/net/wireless/realtek/rtw89/rtw8852a.h2
-rw-r--r--drivers/net/wireless/realtek/rtw89/rtw8852a_rfk.c86
-rw-r--r--drivers/net/wireless/realtek/rtw89/rtw8852a_rfk_table.c2744
-rw-r--r--drivers/net/wireless/realtek/rtw89/rtw8852a_rfk_table.h49
-rw-r--r--drivers/net/wireless/realtek/rtw89/rtw8852ae.c46
-rw-r--r--drivers/net/wireless/realtek/rtw89/rtw8852c.c529
-rw-r--r--drivers/net/wireless/realtek/rtw89/rtw8852c.h76
-rw-r--r--drivers/net/wireless/realtek/rtw89/rtw8852ce.c43
-rw-r--r--drivers/net/wireless/realtek/rtw89/txrx.h3
-rw-r--r--drivers/net/wireless/st/cw1200/cw1200_spi.c4
-rw-r--r--drivers/net/wireless/st/cw1200/queue.c3
-rw-r--r--drivers/net/wireless/st/cw1200/wsm.c2
-rw-r--r--drivers/net/wireless/ti/wl1251/spi.c4
-rw-r--r--drivers/net/wireless/ti/wlcore/spi.c4
-rw-r--r--drivers/net/wireless/zydas/zd1201.c3
-rw-r--r--drivers/net/wwan/iosm/iosm_ipc_debugfs.c5
-rw-r--r--drivers/net/wwan/iosm/iosm_ipc_imem.c54
-rw-r--r--drivers/net/wwan/iosm/iosm_ipc_imem.h7
-rw-r--r--drivers/net/wwan/iosm/iosm_ipc_mmio.c6
-rw-r--r--drivers/net/wwan/iosm/iosm_ipc_mmio.h6
-rw-r--r--drivers/net/wwan/iosm/iosm_ipc_mux.c21
-rw-r--r--drivers/net/wwan/iosm/iosm_ipc_mux.h133
-rw-r--r--drivers/net/wwan/iosm/iosm_ipc_mux_codec.c742
-rw-r--r--drivers/net/wwan/iosm/iosm_ipc_mux_codec.h142
-rw-r--r--drivers/net/wwan/iosm/iosm_ipc_pcie.c1
-rw-r--r--drivers/net/wwan/iosm/iosm_ipc_pcie.h1
-rw-r--r--drivers/net/wwan/qcom_bam_dmux.c2
-rw-r--r--drivers/net/wwan/wwan_core.c36
-rw-r--r--drivers/net/xen-netback/xenbus.c14
-rw-r--r--drivers/net/xen-netfront.c93
-rw-r--r--drivers/nfc/nfcmrvl/spi.c3
-rw-r--r--drivers/nfc/port100.c2
-rw-r--r--drivers/nfc/st-nci/spi.c4
-rw-r--r--drivers/nfc/st-nci/vendor_cmds.c2
-rw-r--r--drivers/nfc/st21nfca/i2c.c3
-rw-r--r--drivers/nfc/st21nfca/vendor_cmds.c4
-rw-r--r--drivers/nfc/st95hf/core.c4
-rw-r--r--drivers/nfc/trf7970a.c4
-rw-r--r--drivers/ntb/hw/intel/ntb_hw_gen4.c17
-rw-r--r--drivers/ntb/hw/intel/ntb_hw_gen4.h16
-rw-r--r--drivers/ntb/msi.c6
-rw-r--r--drivers/nvdimm/blk.c8
-rw-r--r--drivers/nvdimm/btt.c11
-rw-r--r--drivers/nvdimm/btt_devs.c1
-rw-r--r--drivers/nvdimm/bus.c1
-rw-r--r--drivers/nvdimm/nd-core.h2
-rw-r--r--drivers/nvdimm/nd_virtio.c6
-rw-r--r--drivers/nvdimm/pfn_devs.c1
-rw-r--r--drivers/nvdimm/pmem.h1
-rw-r--r--drivers/nvme/host/Kconfig8
-rw-r--r--drivers/nvme/host/Makefile2
-rw-r--r--drivers/nvme/host/constants.c185
-rw-r--r--drivers/nvme/host/core.c299
-rw-r--r--drivers/nvme/host/fabrics.c12
-rw-r--r--drivers/nvme/host/fabrics.h1
-rw-r--r--drivers/nvme/host/fc.c22
-rw-r--r--drivers/nvme/host/ioctl.c38
-rw-r--r--drivers/nvme/host/multipath.c34
-rw-r--r--drivers/nvme/host/nvme.h47
-rw-r--r--drivers/nvme/host/pci.c21
-rw-r--r--drivers/nvme/host/rdma.c118
-rw-r--r--drivers/nvme/host/tcp.c125
-rw-r--r--drivers/nvme/target/admin-cmd.c6
-rw-r--r--drivers/nvme/target/configfs.c66
-rw-r--r--drivers/nvme/target/core.c12
-rw-r--r--drivers/nvme/target/fc.c16
-rw-r--r--drivers/nvme/target/io-cmd-bdev.c27
-rw-r--r--drivers/nvme/target/io-cmd-file.c17
-rw-r--r--drivers/nvme/target/loop.c6
-rw-r--r--drivers/nvme/target/nvmet.h4
-rw-r--r--drivers/nvme/target/passthru.c10
-rw-r--r--drivers/nvme/target/rdma.c8
-rw-r--r--drivers/nvme/target/tcp.c6
-rw-r--r--drivers/nvme/target/zns.c20
-rw-r--r--drivers/nvmem/core.c2
-rw-r--r--drivers/of/fdt.c2
-rw-r--r--drivers/of/of_reserved_mem.c9
-rw-r--r--drivers/of/unittest.c16
-rw-r--r--drivers/parisc/ccio-dma.c3
-rw-r--r--drivers/parisc/sba_iommu.c3
-rw-r--r--drivers/pci/controller/cadence/pci-j721e.c85
-rw-r--r--drivers/pci/controller/dwc/pcie-kirin.c31
-rw-r--r--drivers/pci/controller/pci-hyperv.c13
-rw-r--r--drivers/pci/controller/pci-mvebu.c3
-rw-r--r--drivers/pci/controller/pcie-apple.c2
-rw-r--r--drivers/pci/controller/pcie-mt7621.c11
-rw-r--r--drivers/pci/controller/vmd.c14
-rw-r--r--drivers/pci/iov.c43
-rw-r--r--drivers/pci/msi/irqdomain.c4
-rw-r--r--drivers/pci/msi/legacy.c1
-rw-r--r--drivers/pci/msi/msi.c3
-rw-r--r--drivers/pci/pci-driver.c35
-rw-r--r--drivers/pci/pcie/portdrv_core.c47
-rw-r--r--drivers/pci/quirks.c14
-rw-r--r--drivers/pcmcia/Kconfig2
-rw-r--r--drivers/pcmcia/Makefile1
-rw-r--r--drivers/pcmcia/pxa2xx_stargate2.c137
-rw-r--r--drivers/perf/Kconfig16
-rw-r--r--drivers/perf/Makefile2
-rw-r--r--drivers/perf/apple_m1_cpu_pmu.c584
-rw-r--r--drivers/perf/arm-cci.c2
-rw-r--r--drivers/perf/arm-ccn.c10
-rw-r--r--drivers/perf/arm-cmn.c23
-rw-r--r--drivers/perf/arm_pmu.c6
-rw-r--r--drivers/perf/hisilicon/hisi_uncore_pmu.c2
-rw-r--r--drivers/perf/marvell_cn10k_ddr_pmu.c758
-rw-r--r--drivers/perf/marvell_cn10k_tad_pmu.c2
-rw-r--r--drivers/perf/thunderx2_pmu.c6
-rw-r--r--drivers/perf/xgene_pmu.c8
-rw-r--r--drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c3
-rw-r--r--drivers/phy/broadcom/Kconfig3
-rw-r--r--drivers/phy/broadcom/phy-brcm-usb.c38
-rw-r--r--drivers/phy/cadence/phy-cadence-sierra.c35
-rw-r--r--drivers/phy/freescale/Kconfig10
-rw-r--r--drivers/phy/freescale/Makefile1
-rw-r--r--drivers/phy/freescale/phy-fsl-lynx-28g.c623
-rw-r--r--drivers/phy/mediatek/phy-mtk-tphy.c2
-rw-r--r--drivers/phy/phy-core-mipi-dphy.c4
-rw-r--r--drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c3
-rw-r--r--drivers/phy/st/phy-stm32-usbphyc.c2
-rw-r--r--drivers/phy/ti/phy-j721e-wiz.c1
-rw-r--r--drivers/phy/xilinx/phy-zynqmp.c11
-rw-r--r--drivers/pinctrl/Makefile2
-rw-r--r--drivers/pinctrl/bcm/Kconfig1
-rw-r--r--drivers/pinctrl/bcm/pinctrl-bcm2835.c23
-rw-r--r--drivers/pinctrl/intel/pinctrl-cherryview.c5
-rw-r--r--drivers/pinctrl/intel/pinctrl-intel.c64
-rw-r--r--drivers/pinctrl/intel/pinctrl-tigerlake.c1
-rw-r--r--drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c25
-rw-r--r--drivers/pinctrl/pinctrl-k210.c4
-rw-r--r--drivers/pinctrl/pinctrl-microchip-sgpio.c3
-rw-r--r--drivers/pinctrl/pinctrl-starfive.c6
-rw-r--r--drivers/pinctrl/pinctrl-thunderbay.c90
-rw-r--r--drivers/pinctrl/pinctrl-zynqmp.c10
-rw-r--r--drivers/pinctrl/samsung/pinctrl-exynos-arm64.c2
-rw-r--r--drivers/pinctrl/samsung/pinctrl-exynos.c4
-rw-r--r--drivers/pinctrl/samsung/pinctrl-samsung.c87
-rw-r--r--drivers/pinctrl/sunxi/pinctrl-sun50i-h616.c8
-rw-r--r--drivers/pinctrl/sunxi/pinctrl-sunxi.c15
-rw-r--r--drivers/platform/chrome/Kconfig11
-rw-r--r--drivers/platform/chrome/Makefile1
-rw-r--r--drivers/platform/chrome/chromeos_privacy_screen.c153
-rw-r--r--drivers/platform/chrome/cros_ec.c4
-rw-r--r--drivers/platform/chrome/cros_ec.h2
-rw-r--r--drivers/platform/chrome/cros_ec_i2c.c4
-rw-r--r--drivers/platform/chrome/cros_ec_lpc.c4
-rw-r--r--drivers/platform/chrome/cros_ec_spi.c4
-rw-r--r--drivers/platform/olpc/olpc-xo175-ec.c4
-rw-r--r--drivers/platform/surface/Kconfig1
-rw-r--r--drivers/platform/surface/surface3_power.c13
-rw-r--r--drivers/platform/x86/Kconfig12
-rw-r--r--drivers/platform/x86/Makefile2
-rw-r--r--drivers/platform/x86/amd-pmc.c57
-rw-r--r--drivers/platform/x86/asus-tf103c-dock.c4
-rw-r--r--drivers/platform/x86/asus-wmi.c2
-rw-r--r--drivers/platform/x86/i2c-multi-instantiate.c174
-rw-r--r--drivers/platform/x86/intel/crystal_cove_charger.c26
-rw-r--r--drivers/platform/x86/intel/int3472/tps68470_board_data.c3
-rw-r--r--drivers/platform/x86/intel/speed_select_if/isst_if_common.c97
-rw-r--r--drivers/platform/x86/serial-multi-instantiate.c348
-rw-r--r--drivers/platform/x86/thinkpad_acpi.c28
-rw-r--r--drivers/platform/x86/touchscreen_dmi.c24
-rw-r--r--drivers/platform/x86/x86-android-tablets.c105
-rw-r--r--drivers/pnp/driver.c2
-rw-r--r--drivers/pnp/pnpacpi/core.c4
-rw-r--r--drivers/power/supply/bq256xx_charger.c3
-rw-r--r--drivers/power/supply/cw2015_battery.c2
-rw-r--r--drivers/powercap/Kconfig8
-rw-r--r--drivers/powercap/Makefile1
-rw-r--r--drivers/powercap/dtpm.c333
-rw-r--r--drivers/powercap/dtpm_cpu.c55
-rw-r--r--drivers/powercap/dtpm_devfreq.c203
-rw-r--r--drivers/powercap/dtpm_subsys.h22
-rw-r--r--drivers/ptp/ptp_clock.c11
-rw-r--r--drivers/ptp/ptp_idt82p33.c344
-rw-r--r--drivers/ptp/ptp_idt82p33.h151
-rw-r--r--drivers/ptp/ptp_ocp.c1713
-rw-r--r--drivers/ptp/ptp_pch.c195
-rw-r--r--drivers/ptp/ptp_sysfs.c4
-rw-r--r--drivers/ptp/ptp_vclock.c56
-rw-r--r--drivers/regulator/Kconfig20
-rw-r--r--drivers/regulator/Makefile2
-rw-r--r--drivers/regulator/core.c13
-rw-r--r--drivers/regulator/da9121-regulator.c16
-rw-r--r--drivers/regulator/max20086-regulator.c3
-rw-r--r--drivers/regulator/max8973-regulator.c2
-rw-r--r--drivers/regulator/qcom-rpmh-regulator.c37
-rw-r--r--drivers/regulator/qcom_smd-regulator.c4
-rw-r--r--drivers/regulator/rpi-panel-attiny-regulator.c291
-rw-r--r--drivers/regulator/rt5190a-regulator.c513
-rw-r--r--drivers/regulator/sc2731-regulator.c2
-rw-r--r--drivers/regulator/ti-abb-regulator.c6
-rw-r--r--drivers/regulator/tps6286x-regulator.c159
-rw-r--r--drivers/regulator/vctrl-regulator.c5
-rw-r--r--drivers/regulator/virtual.c41
-rw-r--r--drivers/regulator/wm8350-regulator.c2
-rw-r--r--drivers/remoteproc/Kconfig4
-rw-r--r--drivers/remoteproc/qcom_q6v5.c1
-rw-r--r--drivers/remoteproc/qcom_q6v5_mss.c7
-rw-r--r--drivers/remoteproc/qcom_q6v5_pas.c36
-rw-r--r--drivers/rpmsg/rpmsg_char.c22
-rw-r--r--drivers/rtc/rtc-ds1302.c3
-rw-r--r--drivers/rtc/rtc-ds1305.c4
-rw-r--r--drivers/rtc/rtc-ds1343.c4
-rw-r--r--drivers/s390/block/dasd_int.h1
-rw-r--r--drivers/s390/block/scm_blk.c1
-rw-r--r--drivers/s390/block/scm_blk.h1
-rw-r--r--drivers/s390/cio/device.c2
-rw-r--r--drivers/s390/net/ctcm_fsms.c2
-rw-r--r--drivers/s390/net/ctcm_main.c2
-rw-r--r--drivers/s390/net/lcs.c8
-rw-r--r--drivers/s390/net/netiucv.c6
-rw-r--r--drivers/s390/net/qeth_core_main.c2
-rw-r--r--drivers/s390/net/qeth_l3_main.c1
-rw-r--r--drivers/scsi/dpt/dpti_i2o.h2
-rw-r--r--drivers/scsi/elx/libefc_sli/sli4.h20
-rw-r--r--drivers/scsi/fnic/fnic_scsi.c13
-rw-r--r--drivers/scsi/lpfc/lpfc.h1
-rw-r--r--drivers/scsi/lpfc/lpfc_attr.c3
-rw-r--r--drivers/scsi/lpfc/lpfc_els.c20
-rw-r--r--drivers/scsi/lpfc/lpfc_nportdisc.c5
-rw-r--r--drivers/scsi/mpi3mr/mpi3mr.h2
-rw-r--r--drivers/scsi/mpt3sas/mpt3sas_base.c5
-rw-r--r--drivers/scsi/qedi/qedi_fw.c6
-rw-r--r--drivers/scsi/qla2xxx/qla_bsg.h4
-rw-r--r--drivers/scsi/qla2xxx/qla_def.h2
-rw-r--r--drivers/scsi/qla2xxx/qla_edif_bsg.h4
-rw-r--r--drivers/scsi/qla2xxx/qla_fw.h2
-rw-r--r--drivers/scsi/qla4xxx/ql4_fw.h2
-rw-r--r--drivers/scsi/scsi_debug.c1
-rw-r--r--drivers/scsi/scsi_lib.c2
-rw-r--r--drivers/scsi/scsicam.c1
-rw-r--r--drivers/scsi/sd.c115
-rw-r--r--drivers/scsi/sd.h12
-rw-r--r--drivers/scsi/sg.c5
-rw-r--r--drivers/scsi/sr.c131
-rw-r--r--drivers/scsi/sr.h6
-rw-r--r--drivers/scsi/st.c1
-rw-r--r--drivers/scsi/st.h1
-rw-r--r--drivers/scsi/ufs/ufshcd.c2
-rw-r--r--drivers/scsi/ufs/ufshpb.c4
-rw-r--r--drivers/scsi/xen-scsifront.c3
-rw-r--r--drivers/soc/Kconfig1
-rw-r--r--drivers/soc/Makefile1
-rw-r--r--drivers/soc/amlogic/meson-secure-pwrc.c22
-rw-r--r--drivers/soc/aspeed/aspeed-lpc-ctrl.c7
-rw-r--r--drivers/soc/atmel/soc.c3
-rw-r--r--drivers/soc/atmel/soc.h1
-rw-r--r--drivers/soc/fsl/dpio/qbman-portal.c8
-rw-r--r--drivers/soc/fsl/guts.c14
-rw-r--r--drivers/soc/fsl/qe/qe.c4
-rw-r--r--drivers/soc/fsl/qe/qe_io.c2
-rw-r--r--drivers/soc/imx/gpcv2.c3
-rw-r--r--drivers/soc/imx/imx8m-blk-ctrl.c66
-rw-r--r--drivers/soc/imx/soc-imx.c3
-rw-r--r--drivers/soc/ixp4xx/Kconfig1
-rw-r--r--drivers/soc/ixp4xx/ixp4xx-npe.c33
-rw-r--r--drivers/soc/mediatek/mt8167-pm-domains.h16
-rw-r--r--drivers/soc/mediatek/mt8173-pm-domains.h22
-rw-r--r--drivers/soc/mediatek/mt8183-mmsys.h2
-rw-r--r--drivers/soc/mediatek/mt8183-pm-domains.h32
-rw-r--r--drivers/soc/mediatek/mt8186-mmsys.h115
-rw-r--r--drivers/soc/mediatek/mt8186-pm-domains.h344
-rw-r--r--drivers/soc/mediatek/mt8192-mmsys.h3
-rw-r--r--drivers/soc/mediatek/mt8192-pm-domains.h44
-rw-r--r--drivers/soc/mediatek/mt8195-pm-domains.h613
-rw-r--r--drivers/soc/mediatek/mtk-infracfg.c19
-rw-r--r--drivers/soc/mediatek/mtk-mmsys.c18
-rw-r--r--drivers/soc/mediatek/mtk-mmsys.h3
-rw-r--r--drivers/soc/mediatek/mtk-mutex.c45
-rw-r--r--drivers/soc/mediatek/mtk-pm-domains.c17
-rw-r--r--drivers/soc/mediatek/mtk-pm-domains.h8
-rw-r--r--drivers/soc/mediatek/mtk-pmic-wrap.c71
-rw-r--r--drivers/soc/mediatek/mtk-scpsys.c15
-rw-r--r--drivers/soc/microchip/Kconfig10
-rw-r--r--drivers/soc/microchip/Makefile1
-rw-r--r--drivers/soc/microchip/mpfs-sys-controller.c196
-rw-r--r--drivers/soc/qcom/apr.c1
-rw-r--r--drivers/soc/qcom/llcc-qcom.c107
-rw-r--r--drivers/soc/qcom/mdt_loader.c232
-rw-r--r--drivers/soc/qcom/ocmem.c1
-rw-r--r--drivers/soc/qcom/qcom_aoss.c8
-rw-r--r--drivers/soc/qcom/rpmpd.c20
-rw-r--r--drivers/soc/qcom/socinfo.c12
-rw-r--r--drivers/soc/renesas/Kconfig12
-rw-r--r--drivers/soc/renesas/renesas-soc.c68
-rw-r--r--drivers/soc/rockchip/Kconfig8
-rw-r--r--drivers/soc/rockchip/Makefile1
-rw-r--r--drivers/soc/rockchip/dtpm.c65
-rw-r--r--drivers/soc/samsung/Kconfig2
-rw-r--r--drivers/soc/samsung/exynos-chipid.c2
-rw-r--r--drivers/soc/tegra/fuse/fuse-tegra.c24
-rw-r--r--drivers/soc/tegra/pmc.c16
-rw-r--r--drivers/soc/ti/k3-ringacc.c15
-rw-r--r--drivers/soc/ti/k3-socinfo.c1
-rw-r--r--drivers/soc/ti/smartreflex.c13
-rw-r--r--drivers/soc/ti/wkup_m3_ipc.c4
-rw-r--r--drivers/soundwire/dmi-quirks.c2
-rw-r--r--drivers/spi/Kconfig50
-rw-r--r--drivers/spi/Makefile4
-rw-r--r--drivers/spi/spi-amd.c87
-rw-r--r--drivers/spi/spi-ath79.c34
-rw-r--r--drivers/spi/spi-bcm-qspi.c2
-rw-r--r--drivers/spi/spi-bcm2835aux.c21
-rw-r--r--drivers/spi/spi-bitbang-txrx.h66
-rw-r--r--drivers/spi/spi-cadence-xspi.c4
-rw-r--r--drivers/spi/spi-fsi.c10
-rw-r--r--drivers/spi/spi-geni-qcom.c7
-rw-r--r--drivers/spi/spi-gpio.c42
-rw-r--r--drivers/spi/spi-intel-pci.c (renamed from drivers/mtd/spi-nor/controllers/intel-spi-pci.c)50
-rw-r--r--drivers/spi/spi-intel-platform.c (renamed from drivers/mtd/spi-nor/controllers/intel-spi-platform.c)21
-rw-r--r--drivers/spi/spi-intel.c (renamed from drivers/mtd/spi-nor/controllers/intel-spi.c)850
-rw-r--r--drivers/spi/spi-intel.h19
-rw-r--r--drivers/spi/spi-lantiq-ssc.c8
-rw-r--r--drivers/spi/spi-mem.c6
-rw-r--r--drivers/spi/spi-meson-spicc.c5
-rw-r--r--drivers/spi/spi-mpc512x-psc.c47
-rw-r--r--drivers/spi/spi-mt65xx.c136
-rw-r--r--drivers/spi/spi-mtk-nor.c71
-rw-r--r--drivers/spi/spi-npcm-fiu.c14
-rw-r--r--drivers/spi/spi-pic32.c9
-rw-r--r--drivers/spi/spi-pxa2xx-pci.c320
-rw-r--r--drivers/spi/spi-pxa2xx.c68
-rw-r--r--drivers/spi/spi-qup.c5
-rw-r--r--drivers/spi/spi-rockchip-sfc.c4
-rw-r--r--drivers/spi/spi-rockchip.c135
-rw-r--r--drivers/spi/spi-s3c24xx.c47
-rw-r--r--drivers/spi/spi-s3c64xx.c80
-rw-r--r--drivers/spi/spi-slave-system-control.c3
-rw-r--r--drivers/spi/spi-slave-time.c3
-rw-r--r--drivers/spi/spi-st-ssc4.c31
-rw-r--r--drivers/spi/spi-stm32-qspi.c47
-rw-r--r--drivers/spi/spi-stm32.c9
-rw-r--r--drivers/spi/spi-sun4i.c2
-rw-r--r--drivers/spi/spi-sunplus-sp7021.c584
-rw-r--r--drivers/spi/spi-tegra114.c4
-rw-r--r--drivers/spi/spi-tegra20-slink.c8
-rw-r--r--drivers/spi/spi-tegra210-quad.c341
-rw-r--r--drivers/spi/spi-tle62x0.c3
-rw-r--r--drivers/spi/spi-topcliff-pch.c15
-rw-r--r--drivers/spi/spi-uniphier.c18
-rw-r--r--drivers/spi/spi-zynq-qspi.c3
-rw-r--r--drivers/spi/spi-zynqmp-gqspi.c5
-rw-r--r--drivers/spi/spi.c291
-rw-r--r--drivers/spi/spidev.c35
-rw-r--r--drivers/staging/fbtft/fb_st7789v.c2
-rw-r--r--drivers/staging/fbtft/fbtft-core.c1
-rw-r--r--drivers/staging/fbtft/fbtft.h97
-rw-r--r--drivers/staging/gdm724x/gdm_lte.c7
-rw-r--r--drivers/staging/greybus/gpio.c5
-rw-r--r--drivers/staging/media/Kconfig2
-rw-r--r--drivers/staging/media/Makefile1
-rw-r--r--drivers/staging/media/atomisp/Kconfig2
-rw-r--r--drivers/staging/media/atomisp/i2c/Kconfig14
-rw-r--r--drivers/staging/media/atomisp/pci/atomisp_acc.c28
-rw-r--r--drivers/staging/media/atomisp/pci/atomisp_compat_css20.c4
-rw-r--r--drivers/staging/media/atomisp/pci/atomisp_gmin_platform.c148
-rw-r--r--drivers/staging/media/atomisp/pci/atomisp_v4l2.c21
-rw-r--r--drivers/staging/media/atomisp/pci/hmm/hmm.c7
-rw-r--r--drivers/staging/media/atomisp/pci/ia_css_acc_types.h5
-rw-r--r--drivers/staging/media/atomisp/pci/ia_css_env.h9
-rw-r--r--drivers/staging/media/atomisp/pci/ia_css_event_public.h33
-rw-r--r--drivers/staging/media/atomisp/pci/ia_css_irq.h77
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/macc/macc1_5/ia_css_macc1_5.host.c2
-rw-r--r--drivers/staging/media/atomisp/pci/runtime/debug/interface/ia_css_debug.h31
-rw-r--r--drivers/staging/media/atomisp/pci/sh_css_firmware.c4
-rw-r--r--drivers/staging/media/hantro/Kconfig2
-rw-r--r--drivers/staging/media/hantro/TODO7
-rw-r--r--drivers/staging/media/hantro/hantro.h1
-rw-r--r--drivers/staging/media/hantro/hantro_drv.c52
-rw-r--r--drivers/staging/media/hantro/hantro_g2_hevc_dec.c27
-rw-r--r--drivers/staging/media/hantro/hantro_h1_jpeg_enc.c41
-rw-r--r--drivers/staging/media/hantro/hantro_h1_regs.h2
-rw-r--r--drivers/staging/media/hantro/hantro_hw.h13
-rw-r--r--drivers/staging/media/hantro/hantro_jpeg.c86
-rw-r--r--drivers/staging/media/hantro/hantro_jpeg.h2
-rw-r--r--drivers/staging/media/hantro/hantro_v4l2.c77
-rw-r--r--drivers/staging/media/hantro/imx8m_vpu_hw.c62
-rw-r--r--drivers/staging/media/hantro/rockchip_vpu2_hw_jpeg_enc.c44
-rw-r--r--drivers/staging/media/hantro/rockchip_vpu_hw.c6
-rw-r--r--drivers/staging/media/hantro/sunxi_vpu_hw.c4
-rw-r--r--drivers/staging/media/imx/Kconfig2
-rw-r--r--drivers/staging/media/imx/Makefile1
-rw-r--r--drivers/staging/media/imx/TODO25
-rw-r--r--drivers/staging/media/imx/imx-media-csi.c7
-rw-r--r--drivers/staging/media/imx/imx6-mipi-csi2.c25
-rw-r--r--drivers/staging/media/imx/imx7-media-csi.c64
-rw-r--r--drivers/staging/media/imx/imx8mq-mipi-csi2.c81
-rw-r--r--drivers/staging/media/ipu3/Kconfig2
-rw-r--r--drivers/staging/media/max96712/Kconfig2
-rw-r--r--drivers/staging/media/max96712/max96712.c2
-rw-r--r--drivers/staging/media/meson/vdec/Kconfig2
-rw-r--r--drivers/staging/media/meson/vdec/esparser.c7
-rw-r--r--drivers/staging/media/meson/vdec/vdec_helpers.c8
-rw-r--r--drivers/staging/media/meson/vdec/vdec_helpers.h4
-rw-r--r--drivers/staging/media/meson/vdec/vdec_platform.c12
-rw-r--r--drivers/staging/media/omap4iss/Kconfig2
-rw-r--r--drivers/staging/media/rkvdec/Kconfig2
-rw-r--r--drivers/staging/media/sunxi/cedrus/Kconfig2
-rw-r--r--drivers/staging/media/sunxi/cedrus/cedrus.c2
-rw-r--r--drivers/staging/media/sunxi/cedrus/cedrus.h3
-rw-r--r--drivers/staging/media/sunxi/cedrus/cedrus_dec.c4
-rw-r--r--drivers/staging/media/sunxi/cedrus/cedrus_h264.c2
-rw-r--r--drivers/staging/media/sunxi/cedrus/cedrus_h265.c4
-rw-r--r--drivers/staging/media/sunxi/cedrus/cedrus_hw.c25
-rw-r--r--drivers/staging/media/sunxi/cedrus/cedrus_hw.h2
-rw-r--r--drivers/staging/media/tegra-vde/Kconfig10
-rw-r--r--drivers/staging/media/tegra-vde/Makefile3
-rw-r--r--drivers/staging/media/tegra-vde/TODO4
-rw-r--r--drivers/staging/media/tegra-vde/uapi.h73
-rw-r--r--drivers/staging/media/tegra-vde/vde.c1358
-rw-r--r--drivers/staging/media/tegra-vde/vde.h125
-rw-r--r--drivers/staging/media/tegra-video/Kconfig2
-rw-r--r--drivers/staging/media/zoran/Kconfig40
-rw-r--r--drivers/staging/media/zoran/Makefile8
-rw-r--r--drivers/staging/media/zoran/videocodec.c68
-rw-r--r--drivers/staging/media/zoran/videocodec.h4
-rw-r--r--drivers/staging/media/zoran/zoran.h18
-rw-r--r--drivers/staging/media/zoran/zoran_card.c398
-rw-r--r--drivers/staging/media/zoran/zoran_device.c15
-rw-r--r--drivers/staging/media/zoran/zoran_device.h2
-rw-r--r--drivers/staging/media/zoran/zoran_driver.c56
-rw-r--r--drivers/staging/media/zoran/zr36016.c25
-rw-r--r--drivers/staging/media/zoran/zr36016.h2
-rw-r--r--drivers/staging/media/zoran/zr36050.c24
-rw-r--r--drivers/staging/media/zoran/zr36050.h2
-rw-r--r--drivers/staging/media/zoran/zr36060.c23
-rw-r--r--drivers/staging/media/zoran/zr36060.h2
-rw-r--r--drivers/staging/most/video/Kconfig2
-rw-r--r--drivers/staging/pi433/pi433_if.c4
-rw-r--r--drivers/staging/r8188eu/include/rtw_cmd.h10
-rw-r--r--drivers/staging/rtl8712/rtl871x_cmd.h8
-rw-r--r--drivers/staging/rtl8723bs/core/rtw_mlme_ext.c7
-rw-r--r--drivers/staging/rtl8723bs/core/rtw_recv.c10
-rw-r--r--drivers/staging/rtl8723bs/core/rtw_sta_mgt.c22
-rw-r--r--drivers/staging/rtl8723bs/core/rtw_xmit.c16
-rw-r--r--drivers/staging/rtl8723bs/hal/rtl8723bs_xmit.c2
-rw-r--r--drivers/staging/rtl8723bs/include/ieee80211.h2
-rw-r--r--drivers/staging/rtl8723bs/include/rtw_cmd.h2
-rw-r--r--drivers/staging/rtl8723bs/include/rtw_mlme.h8
-rw-r--r--drivers/staging/vc04_services/bcm2835-camera/Kconfig2
-rw-r--r--drivers/staging/vc04_services/include/linux/raspberrypi/vchiq.h2
-rw-r--r--drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c20
-rw-r--r--drivers/staging/wfx/bus_spi.c3
-rw-r--r--drivers/staging/wlan-ng/p80211netdev.c4
-rw-r--r--drivers/target/target_core_iblock.c12
-rw-r--r--drivers/target/target_core_pscsi.c1
-rw-r--r--drivers/tee/amdtee/call.c2
-rw-r--r--drivers/tee/amdtee/shm_pool.c55
-rw-r--r--drivers/tee/optee/Kconfig8
-rw-r--r--drivers/tee/optee/call.c2
-rw-r--r--drivers/tee/optee/core.c22
-rw-r--r--drivers/tee/optee/device.c5
-rw-r--r--drivers/tee/optee/ffa_abi.c153
-rw-r--r--drivers/tee/optee/notif.c2
-rw-r--r--drivers/tee/optee/optee_private.h12
-rw-r--r--drivers/tee/optee/smc_abi.c179
-rw-r--r--drivers/tee/tee_core.c5
-rw-r--r--drivers/tee/tee_private.h15
-rw-r--r--drivers/tee/tee_shm.c320
-rw-r--r--drivers/tee/tee_shm_pool.c162
-rw-r--r--drivers/thermal/broadcom/brcmstb_thermal.c2
-rw-r--r--drivers/thermal/intel/Kconfig14
-rw-r--r--drivers/thermal/intel/Makefile1
-rw-r--r--drivers/thermal/intel/int340x_thermal/acpi_thermal_rel.c23
-rw-r--r--drivers/thermal/intel/int340x_thermal/int3400_thermal.c157
-rw-r--r--drivers/thermal/intel/intel_hfi.c569
-rw-r--r--drivers/thermal/intel/intel_hfi.h17
-rw-r--r--drivers/thermal/intel/intel_powerclamp.c9
-rw-r--r--drivers/thermal/intel/therm_throt.c22
-rw-r--r--drivers/thermal/qcom/lmh.c62
-rw-r--r--drivers/thermal/qcom/tsens.c5
-rw-r--r--drivers/thermal/tegra/tegra-bpmp-thermal.c13
-rw-r--r--drivers/thermal/thermal_netlink.c58
-rw-r--r--drivers/thermal/thermal_netlink.h14
-rw-r--r--drivers/thermal/ti-soc-thermal/ti-thermal-common.c12
-rw-r--r--drivers/tty/n_gsm.c65
-rw-r--r--drivers/tty/n_tty.c10
-rw-r--r--drivers/tty/rpmsg_tty.c40
-rw-r--r--drivers/tty/serial/8250/8250_gsc.c2
-rw-r--r--drivers/tty/serial/8250/8250_of.c11
-rw-r--r--drivers/tty/serial/8250/8250_pci.c100
-rw-r--r--drivers/tty/serial/8250/8250_pericom.c2
-rw-r--r--drivers/tty/serial/8250/8250_port.c61
-rw-r--r--drivers/tty/serial/amba-pl011.c11
-rw-r--r--drivers/tty/serial/max3100.c5
-rw-r--r--drivers/tty/serial/max310x.c3
-rw-r--r--drivers/tty/serial/sc16is7xx.c7
-rw-r--r--drivers/tty/serial/serial_core.c34
-rw-r--r--drivers/tty/serial/stm32-usart.c14
-rw-r--r--drivers/tty/tty_io.c2
-rw-r--r--drivers/tty/vt/vt_ioctl.c3
-rw-r--r--drivers/usb/cdns3/drd.c6
-rw-r--r--drivers/usb/class/usbtmc.c13
-rw-r--r--drivers/usb/common/ulpi.c17
-rw-r--r--drivers/usb/core/hcd-pci.c4
-rw-r--r--drivers/usb/core/hcd.c14
-rw-r--r--drivers/usb/core/port.c9
-rw-r--r--drivers/usb/core/urb.c12
-rw-r--r--drivers/usb/dwc2/core.h2
-rw-r--r--drivers/usb/dwc2/drd.c6
-rw-r--r--drivers/usb/dwc2/gadget.c2
-rw-r--r--drivers/usb/dwc3/dwc3-pci.c21
-rw-r--r--drivers/usb/dwc3/dwc3-xilinx.c25
-rw-r--r--drivers/usb/dwc3/gadget.c15
-rw-r--r--drivers/usb/gadget/Kconfig2
-rw-r--r--drivers/usb/gadget/composite.c3
-rw-r--r--drivers/usb/gadget/function/f_fs.c56
-rw-r--r--drivers/usb/gadget/function/f_mass_storage.c1
-rw-r--r--drivers/usb/gadget/function/f_sourcesink.c1
-rw-r--r--drivers/usb/gadget/function/f_uac2.c4
-rw-r--r--drivers/usb/gadget/function/rndis.c18
-rw-r--r--drivers/usb/gadget/function/rndis.h1
-rw-r--r--drivers/usb/gadget/legacy/Kconfig2
-rw-r--r--drivers/usb/gadget/legacy/raw_gadget.c2
-rw-r--r--drivers/usb/gadget/udc/at91_udc.c2
-rw-r--r--drivers/usb/gadget/udc/core.c3
-rw-r--r--drivers/usb/gadget/udc/max3420_udc.c4
-rw-r--r--drivers/usb/gadget/udc/renesas_usb3.c2
-rw-r--r--drivers/usb/gadget/udc/udc-xilinx.c6
-rw-r--r--drivers/usb/host/max3421-hcd.c3
-rw-r--r--drivers/usb/host/xen-hcd.c26
-rw-r--r--drivers/usb/host/xhci-plat.c3
-rw-r--r--drivers/usb/host/xhci.c28
-rw-r--r--drivers/usb/misc/usb251xb.c4
-rw-r--r--drivers/usb/musb/omap2430.c1
-rw-r--r--drivers/usb/serial/ch341.c2
-rw-r--r--drivers/usb/serial/cp210x.c2
-rw-r--r--drivers/usb/serial/ftdi_sio.c3
-rw-r--r--drivers/usb/serial/ftdi_sio_ids.h3
-rw-r--r--drivers/usb/serial/option.c14
-rw-r--r--drivers/usb/storage/unusual_devs.h10
-rw-r--r--drivers/usb/typec/port-mapper.c10
-rw-r--r--drivers/usb/typec/tcpm/tcpci.c26
-rw-r--r--drivers/usb/typec/tcpm/tcpci.h1
-rw-r--r--drivers/usb/typec/tcpm/tcpm.c7
-rw-r--r--drivers/usb/typec/tipd/core.c7
-rw-r--r--drivers/usb/typec/ucsi/ucsi_ccg.c2
-rw-r--r--drivers/vdpa/mlx5/net/mlx5_vnet.c34
-rw-r--r--drivers/vdpa/vdpa.c2
-rw-r--r--drivers/vdpa/vdpa_user/iova_domain.c2
-rw-r--r--drivers/vdpa/virtio_pci/vp_vdpa.c2
-rw-r--r--drivers/vfio/pci/Kconfig5
-rw-r--r--drivers/vfio/pci/Makefile4
-rw-r--r--drivers/vfio/pci/hisilicon/Kconfig15
-rw-r--r--drivers/vfio/pci/hisilicon/Makefile4
-rw-r--r--drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c1326
-rw-r--r--drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.h116
-rw-r--r--drivers/vfio/pci/mlx5/Kconfig10
-rw-r--r--drivers/vfio/pci/mlx5/Makefile4
-rw-r--r--drivers/vfio/pci/mlx5/cmd.c259
-rw-r--r--drivers/vfio/pci/mlx5/cmd.h36
-rw-r--r--drivers/vfio/pci/mlx5/main.c676
-rw-r--r--drivers/vfio/pci/vfio_pci.c1
-rw-r--r--drivers/vfio/pci/vfio_pci_core.c162
-rw-r--r--drivers/vfio/pci/vfio_pci_rdwr.c2
-rw-r--r--drivers/vfio/vfio.c296
-rw-r--r--drivers/vhost/iotlb.c11
-rw-r--r--drivers/vhost/net.c1
-rw-r--r--drivers/vhost/vdpa.c2
-rw-r--r--drivers/vhost/vhost.c11
-rw-r--r--drivers/vhost/vsock.c24
-rw-r--r--drivers/video/backlight/ams369fg06.c3
-rw-r--r--drivers/video/backlight/corgi_lcd.c3
-rw-r--r--drivers/video/backlight/ili922x.c3
-rw-r--r--drivers/video/backlight/l4f00242t03.c3
-rw-r--r--drivers/video/backlight/lm3630a_bl.c1
-rw-r--r--drivers/video/backlight/lms501kf03.c3
-rw-r--r--drivers/video/backlight/ltv350qv.c3
-rw-r--r--drivers/video/backlight/qcom-wled.c1
-rw-r--r--drivers/video/backlight/tdo24m.c3
-rw-r--r--drivers/video/backlight/tosa_lcd.c4
-rw-r--r--drivers/video/backlight/vgg2432a4.c4
-rw-r--r--drivers/video/console/Kconfig22
-rw-r--r--drivers/video/fbdev/Kconfig2
-rw-r--r--drivers/video/fbdev/asiliantfb.c2
-rw-r--r--drivers/video/fbdev/atafb.c35
-rw-r--r--drivers/video/fbdev/atmel_lcdfb.c11
-rw-r--r--drivers/video/fbdev/aty/aty128fb.c10
-rw-r--r--drivers/video/fbdev/aty/mach64_ct.c4
-rw-r--r--drivers/video/fbdev/aty/mach64_gx.c2
-rw-r--r--drivers/video/fbdev/au1100fb.c2
-rw-r--r--drivers/video/fbdev/au1100fb.h2
-rw-r--r--drivers/video/fbdev/au1200fb.c4
-rw-r--r--drivers/video/fbdev/broadsheetfb.c1
-rw-r--r--drivers/video/fbdev/cirrusfb.c16
-rw-r--r--drivers/video/fbdev/controlfb.c2
-rw-r--r--drivers/video/fbdev/core/bitblit.c16
-rw-r--r--drivers/video/fbdev/core/cfbimgblt.c107
-rw-r--r--drivers/video/fbdev/core/fb_defio.c57
-rw-r--r--drivers/video/fbdev/core/fbcon.c554
-rw-r--r--drivers/video/fbdev/core/fbcon.h72
-rw-r--r--drivers/video/fbdev/core/fbcon_ccw.c28
-rw-r--r--drivers/video/fbdev/core/fbcon_cw.c28
-rw-r--r--drivers/video/fbdev/core/fbcon_rotate.h9
-rw-r--r--drivers/video/fbdev/core/fbcon_ud.c37
-rw-r--r--drivers/video/fbdev/core/fbcvt.c53
-rw-r--r--drivers/video/fbdev/core/fbmem.c39
-rw-r--r--drivers/video/fbdev/core/sysfillrect.c16
-rw-r--r--drivers/video/fbdev/core/sysimgblt.c49
-rw-r--r--drivers/video/fbdev/core/tileblit.c16
-rw-r--r--drivers/video/fbdev/da8xx-fb.c7
-rw-r--r--drivers/video/fbdev/hyperv_fb.c16
-rw-r--r--drivers/video/fbdev/imxfb.c2
-rw-r--r--drivers/video/fbdev/kyro/STG4000InitDevice.c2
-rw-r--r--drivers/video/fbdev/matrox/matroxfb_base.c2
-rw-r--r--drivers/video/fbdev/mb862xx/mb862xxfb_accel.c2
-rw-r--r--drivers/video/fbdev/metronomefb.c1
-rw-r--r--drivers/video/fbdev/mmp/hw/mmp_ctrl.c3
-rw-r--r--drivers/video/fbdev/nvidia/nv_i2c.c2
-rw-r--r--drivers/video/fbdev/ocfb.c2
-rw-r--r--drivers/video/fbdev/offb.c2
-rw-r--r--drivers/video/fbdev/omap/lcd_ams_delta.c16
-rw-r--r--drivers/video/fbdev/omap/lcd_mipid.c4
-rw-r--r--drivers/video/fbdev/omap/omapfb_main.c13
-rw-r--r--drivers/video/fbdev/omap2/omapfb/displays/connector-dvi.c1
-rw-r--r--drivers/video/fbdev/omap2/omapfb/displays/panel-dsi-cm.c8
-rw-r--r--drivers/video/fbdev/omap2/omapfb/displays/panel-lgphilips-lb035q02.c11
-rw-r--r--drivers/video/fbdev/omap2/omapfb/displays/panel-nec-nl8048hl11.c4
-rw-r--r--drivers/video/fbdev/omap2/omapfb/displays/panel-sharp-ls037v7dw01.c7
-rw-r--r--drivers/video/fbdev/omap2/omapfb/displays/panel-sony-acx565akm.c6
-rw-r--r--drivers/video/fbdev/omap2/omapfb/displays/panel-tpo-td028ttec1.c4
-rw-r--r--drivers/video/fbdev/omap2/omapfb/displays/panel-tpo-td043mtea1.c11
-rw-r--r--drivers/video/fbdev/omap2/omapfb/dss/display-sysfs.c3
-rw-r--r--drivers/video/fbdev/omap2/omapfb/dss/manager-sysfs.c3
-rw-r--r--drivers/video/fbdev/omap2/omapfb/dss/overlay-sysfs.c3
-rw-r--r--drivers/video/fbdev/omap2/omapfb/omapfb-main.c1
-rw-r--r--drivers/video/fbdev/pxa168fb.c15
-rw-r--r--drivers/video/fbdev/pxa3xx-gcu.c10
-rw-r--r--drivers/video/fbdev/s3c-fb.c22
-rw-r--r--drivers/video/fbdev/savage/savagefb.h1
-rw-r--r--drivers/video/fbdev/savage/savagefb_driver.c7
-rw-r--r--drivers/video/fbdev/simplefb.c65
-rw-r--r--drivers/video/fbdev/sis/sis_main.c2
-rw-r--r--drivers/video/fbdev/skeletonfb.c12
-rw-r--r--drivers/video/fbdev/sm712fb.c46
-rw-r--r--drivers/video/fbdev/smscufx.c3
-rw-r--r--drivers/video/fbdev/ssd1307fb.c7
-rw-r--r--drivers/video/fbdev/stifb.c45
-rw-r--r--drivers/video/fbdev/udlfb.c9
-rw-r--r--drivers/video/fbdev/vga16fb.c5
-rw-r--r--drivers/video/fbdev/via/lcd.c2
-rw-r--r--drivers/video/fbdev/via/viafbdev.c10
-rw-r--r--drivers/video/fbdev/w100fb.c15
-rw-r--r--drivers/virt/Kconfig11
-rw-r--r--drivers/virt/Makefile1
-rw-r--r--drivers/virt/vmgenid.c100
-rw-r--r--drivers/virtio/Kconfig1
-rw-r--r--drivers/virtio/virtio.c56
-rw-r--r--drivers/virtio/virtio_mem.c9
-rw-r--r--drivers/virtio/virtio_vdpa.c2
-rw-r--r--drivers/visorbus/vbuschannel.h2
-rw-r--r--drivers/xen/gntalloc.c25
-rw-r--r--drivers/xen/grant-table.c71
-rw-r--r--drivers/xen/pci.c2
-rw-r--r--drivers/xen/pvcalls-front.c8
-rw-r--r--drivers/xen/xenbus/xenbus_client.c24
-rw-r--r--fs/9p/fid.c9
-rw-r--r--fs/9p/vfs_addr.c37
-rw-r--r--fs/9p/vfs_inode.c2
-rw-r--r--fs/Kconfig8
-rw-r--r--fs/Kconfig.binfmt13
-rw-r--r--fs/Makefile2
-rw-r--r--fs/adfs/inode.c3
-rw-r--r--fs/adfs/super.c2
-rw-r--r--fs/affs/file.c6
-rw-r--r--fs/affs/super.c2
-rw-r--r--fs/afs/dir.c18
-rw-r--r--fs/afs/file.c28
-rw-r--r--fs/afs/internal.h6
-rw-r--r--fs/afs/super.c2
-rw-r--r--fs/afs/write.c19
-rw-r--r--fs/aio.c2
-rw-r--r--fs/befs/linuxvfs.c2
-rw-r--r--fs/bfs/file.c3
-rw-r--r--fs/bfs/inode.c2
-rw-r--r--fs/binfmt_elf.c180
-rw-r--r--fs/binfmt_elf_fdpic.c20
-rw-r--r--fs/binfmt_elf_test.c64
-rw-r--r--fs/binfmt_flat.c7
-rw-r--r--fs/binfmt_misc.c6
-rw-r--r--fs/btrfs/backref.c7
-rw-r--r--fs/btrfs/block-group.c75
-rw-r--r--fs/btrfs/block-group.h1
-rw-r--r--fs/btrfs/btrfs_inode.h42
-rw-r--r--fs/btrfs/check-integrity.c1
-rw-r--r--fs/btrfs/compression.c63
-rw-r--r--fs/btrfs/compression.h10
-rw-r--r--fs/btrfs/ctree.c108
-rw-r--r--fs/btrfs/ctree.h104
-rw-r--r--fs/btrfs/delalloc-space.c18
-rw-r--r--fs/btrfs/dev-replace.c18
-rw-r--r--fs/btrfs/disk-io.c286
-rw-r--r--fs/btrfs/disk-io.h2
-rw-r--r--fs/btrfs/extent-io-tree.h4
-rw-r--r--fs/btrfs/extent-tree.c158
-rw-r--r--fs/btrfs/extent_io.c102
-rw-r--r--fs/btrfs/extent_map.c6
-rw-r--r--fs/btrfs/extent_map.h8
-rw-r--r--fs/btrfs/file-item.c76
-rw-r--r--fs/btrfs/file.c176
-rw-r--r--fs/btrfs/free-space-tree.c2
-rw-r--r--fs/btrfs/inode.c1301
-rw-r--r--fs/btrfs/ioctl.c665
-rw-r--r--fs/btrfs/lzo.c20
-rw-r--r--fs/btrfs/ordered-data.c132
-rw-r--r--fs/btrfs/ordered-data.h25
-rw-r--r--fs/btrfs/print-tree.c5
-rw-r--r--fs/btrfs/qgroup.c100
-rw-r--r--fs/btrfs/reflink.c43
-rw-r--r--fs/btrfs/relocation.c24
-rw-r--r--fs/btrfs/root-tree.c15
-rw-r--r--fs/btrfs/scrub.c2
-rw-r--r--fs/btrfs/send.c15
-rw-r--r--fs/btrfs/send.h2
-rw-r--r--fs/btrfs/space-info.c5
-rw-r--r--fs/btrfs/subpage.c2
-rw-r--r--fs/btrfs/super.c96
-rw-r--r--fs/btrfs/sysfs.c15
-rw-r--r--fs/btrfs/tests/extent-map-tests.c2
-rw-r--r--fs/btrfs/transaction.c120
-rw-r--r--fs/btrfs/transaction.h5
-rw-r--r--fs/btrfs/tree-checker.c68
-rw-r--r--fs/btrfs/tree-log.c1030
-rw-r--r--fs/btrfs/tree-log.h7
-rw-r--r--fs/btrfs/volumes.c147
-rw-r--r--fs/btrfs/volumes.h7
-rw-r--r--fs/btrfs/zoned.c167
-rw-r--r--fs/buffer.c118
-rw-r--r--fs/cachefiles/interface.c2
-rw-r--r--fs/cachefiles/io.c59
-rw-r--r--fs/cachefiles/xattr.c23
-rw-r--r--fs/ceph/addr.c345
-rw-r--r--fs/ceph/cache.h13
-rw-r--r--fs/ceph/caps.c71
-rw-r--r--fs/ceph/debugfs.c5
-rw-r--r--fs/ceph/dir.c17
-rw-r--r--fs/ceph/file.c92
-rw-r--r--fs/ceph/inode.c67
-rw-r--r--fs/ceph/locks.c8
-rw-r--r--fs/ceph/mds_client.c69
-rw-r--r--fs/ceph/mds_client.h15
-rw-r--r--fs/ceph/metric.c63
-rw-r--r--fs/ceph/metric.h63
-rw-r--r--fs/ceph/snap.c263
-rw-r--r--fs/ceph/strings.c1
-rw-r--r--fs/ceph/super.c8
-rw-r--r--fs/ceph/super.h10
-rw-r--r--fs/ceph/xattr.c13
-rw-r--r--fs/cifs/cifs_swn.c6
-rw-r--r--fs/cifs/cifsacl.c9
-rw-r--r--fs/cifs/cifsfs.c17
-rw-r--r--fs/cifs/cifsproto.h3
-rw-r--r--fs/cifs/connect.c99
-rw-r--r--fs/cifs/dfs_cache.c2
-rw-r--r--fs/cifs/file.c270
-rw-r--r--fs/cifs/fs_context.c4
-rw-r--r--fs/cifs/fscache.c126
-rw-r--r--fs/cifs/fscache.h79
-rw-r--r--fs/cifs/inode.c8
-rw-r--r--fs/cifs/ntlmssp.h2
-rw-r--r--fs/cifs/sess.c17
-rw-r--r--fs/cifs/smb1ops.c4
-rw-r--r--fs/cifs/smb2ops.c18
-rw-r--r--fs/cifs/transport.c5
-rw-r--r--fs/cifs/xattr.c2
-rw-r--r--fs/coda/file.c1
-rw-r--r--fs/coda/inode.c2
-rw-r--r--fs/compat_binfmt_elf.c2
-rw-r--r--fs/configfs/dir.c20
-rw-r--r--fs/coredump.c86
-rw-r--r--fs/crypto/bio.c13
-rw-r--r--fs/crypto/crypto.c8
-rw-r--r--fs/crypto/inline_crypt.c93
-rw-r--r--fs/dax.c3
-rw-r--r--fs/dcache.c3
-rw-r--r--fs/devpts/inode.c2
-rw-r--r--fs/direct-io.c5
-rw-r--r--fs/ecryptfs/mmap.c5
-rw-r--r--fs/ecryptfs/super.c2
-rw-r--r--fs/efs/super.c2
-rw-r--r--fs/erofs/data.c20
-rw-r--r--fs/erofs/dir.c21
-rw-r--r--fs/erofs/erofs_fs.h5
-rw-r--r--fs/erofs/inode.c4
-rw-r--r--fs/erofs/internal.h4
-rw-r--r--fs/erofs/namei.c54
-rw-r--r--fs/erofs/super.c40
-rw-r--r--fs/erofs/sysfs.c8
-rw-r--r--fs/erofs/zdata.c302
-rw-r--r--fs/erofs/zmap.c78
-rw-r--r--fs/exec.c38
-rw-r--r--fs/exfat/inode.c3
-rw-r--r--fs/exfat/super.c2
-rw-r--r--fs/ext2/ialloc.c5
-rw-r--r--fs/ext2/inode.c9
-rw-r--r--fs/ext2/super.c2
-rw-r--r--fs/ext4/acl.c8
-rw-r--r--fs/ext4/balloc.c1
-rw-r--r--fs/ext4/block_validity.c26
-rw-r--r--fs/ext4/ext4.h38
-rw-r--r--fs/ext4/ext4_jbd2.h2
-rw-r--r--fs/ext4/extents.c17
-rw-r--r--fs/ext4/fast_commit.c306
-rw-r--r--fs/ext4/fast_commit.h6
-rw-r--r--fs/ext4/file.c10
-rw-r--r--fs/ext4/hash.c2
-rw-r--r--fs/ext4/indirect.c2
-rw-r--r--fs/ext4/inline.c32
-rw-r--r--fs/ext4/inode.c173
-rw-r--r--fs/ext4/ioctl.c10
-rw-r--r--fs/ext4/mballoc.c371
-rw-r--r--fs/ext4/migrate.c2
-rw-r--r--fs/ext4/namei.c41
-rw-r--r--fs/ext4/orphan.c4
-rw-r--r--fs/ext4/page-io.c13
-rw-r--r--fs/ext4/readpage.c8
-rw-r--r--fs/ext4/resize.c7
-rw-r--r--fs/ext4/super.c115
-rw-r--r--fs/ext4/sysfs.c8
-rw-r--r--fs/ext4/xattr.c6
-rw-r--r--fs/f2fs/Kconfig7
-rw-r--r--fs/f2fs/acl.c21
-rw-r--r--fs/f2fs/checkpoint.c89
-rw-r--r--fs/f2fs/compress.c17
-rw-r--r--fs/f2fs/data.c234
-rw-r--r--fs/f2fs/debug.c25
-rw-r--r--fs/f2fs/dir.c22
-rw-r--r--fs/f2fs/f2fs.h175
-rw-r--r--fs/f2fs/file.c175
-rw-r--r--fs/f2fs/gc.c53
-rw-r--r--fs/f2fs/hash.c2
-rw-r--r--fs/f2fs/inline.c4
-rw-r--r--fs/f2fs/inode.c7
-rw-r--r--fs/f2fs/namei.c82
-rw-r--r--fs/f2fs/node.c121
-rw-r--r--fs/f2fs/node.h3
-rw-r--r--fs/f2fs/recovery.c39
-rw-r--r--fs/f2fs/segment.c81
-rw-r--r--fs/f2fs/segment.h5
-rw-r--r--fs/f2fs/super.c115
-rw-r--r--fs/f2fs/sysfs.c50
-rw-r--r--fs/f2fs/verity.c4
-rw-r--r--fs/f2fs/xattr.c12
-rw-r--r--fs/fat/dir.c2
-rw-r--r--fs/fat/inode.c5
-rw-r--r--fs/file_table.c6
-rw-r--r--fs/freevxfs/vxfs_super.c2
-rw-r--r--fs/fs-writeback.c46
-rw-r--r--fs/fscache/io.c28
-rw-r--r--fs/fuse/control.c17
-rw-r--r--fs/fuse/dax.c3
-rw-r--r--fs/fuse/dev.c20
-rw-r--r--fs/fuse/dir.c2
-rw-r--r--fs/fuse/file.c34
-rw-r--r--fs/fuse/fuse_i.h1
-rw-r--r--fs/fuse/inode.c5
-rw-r--r--fs/fuse/ioctl.c9
-rw-r--r--fs/fuse/virtio_fs.c1
-rw-r--r--fs/gfs2/aops.c43
-rw-r--r--fs/gfs2/file.c7
-rw-r--r--fs/gfs2/glock.c3
-rw-r--r--fs/gfs2/lops.c8
-rw-r--r--fs/gfs2/meta_io.c10
-rw-r--r--fs/gfs2/ops_fstype.c4
-rw-r--r--fs/gfs2/super.c2
-rw-r--r--fs/gfs2/sys.c2
-rw-r--r--fs/hfs/inode.c6
-rw-r--r--fs/hfs/mdb.c2
-rw-r--r--fs/hfs/super.c2
-rw-r--r--fs/hfsplus/inode.c6
-rw-r--r--fs/hfsplus/super.c2
-rw-r--r--fs/hfsplus/wrapper.c5
-rw-r--r--fs/hostfs/hostfs_kern.c5
-rw-r--r--fs/hpfs/file.c3
-rw-r--r--fs/hpfs/super.c2
-rw-r--r--fs/hugetlbfs/inode.c4
-rw-r--r--fs/inode.c2
-rw-r--r--fs/internal.h9
-rw-r--r--fs/io-wq.c114
-rw-r--r--fs/io_uring.c1312
-rw-r--r--fs/ioctl.c4
-rw-r--r--fs/iomap/buffered-io.c124
-rw-r--r--fs/iomap/direct-io.c14
-rw-r--r--fs/iomap/fiemap.c1
-rw-r--r--fs/iomap/trace.h2
-rw-r--r--fs/isofs/inode.c2
-rw-r--r--fs/jbd2/commit.c21
-rw-r--r--fs/jbd2/journal.c10
-rw-r--r--fs/jbd2/transaction.c126
-rw-r--r--fs/jffs2/super.c2
-rw-r--r--fs/jfs/inode.c3
-rw-r--r--fs/jfs/jfs_logmgr.c11
-rw-r--r--fs/jfs/jfs_metapage.c23
-rw-r--r--fs/jfs/super.c2
-rw-r--r--fs/ksmbd/auth.c27
-rw-r--r--fs/ksmbd/ksmbd_netlink.h2
-rw-r--r--fs/ksmbd/ntlmssp.h6
-rw-r--r--fs/ksmbd/smb2pdu.c45
-rw-r--r--fs/ksmbd/smb2pdu.h8
-rw-r--r--fs/ksmbd/smb_common.c5
-rw-r--r--fs/ksmbd/transport_rdma.c4
-rw-r--r--fs/ksmbd/vfs.c1
-rw-r--r--fs/ksmbd/vfs.h1
-rw-r--r--fs/ksmbd/xattr.h2
-rw-r--r--fs/libfs.c25
-rw-r--r--fs/lockd/svc.c24
-rw-r--r--fs/lockd/svcsubs.c18
-rw-r--r--fs/minix/inode.c8
-rw-r--r--fs/mpage.c82
-rw-r--r--fs/namei.c10
-rw-r--r--fs/namespace.c200
-rw-r--r--fs/nfs/blocklayout/blocklayout.c26
-rw-r--r--fs/nfs/blocklayout/rpc_pipefs.c1
-rw-r--r--fs/nfs/callback.c66
-rw-r--r--fs/nfs/callback.h2
-rw-r--r--fs/nfs/callback_proc.c2
-rw-r--r--fs/nfs/callback_xdr.c18
-rw-r--r--fs/nfs/client.c9
-rw-r--r--fs/nfs/dir.c170
-rw-r--r--fs/nfs/file.c32
-rw-r--r--fs/nfs/filelayout/filelayout.h2
-rw-r--r--fs/nfs/filelayout/filelayoutdev.c4
-rw-r--r--fs/nfs/inode.c11
-rw-r--r--fs/nfs/internal.h1
-rw-r--r--fs/nfs/nfs3proc.c5
-rw-r--r--fs/nfs/nfs42proc.c13
-rw-r--r--fs/nfs/nfs4_fs.h14
-rw-r--r--fs/nfs/nfs4client.c5
-rw-r--r--fs/nfs/nfs4namespace.c19
-rw-r--r--fs/nfs/nfs4proc.c203
-rw-r--r--fs/nfs/nfs4state.c7
-rw-r--r--fs/nfs/nfs4xdr.c49
-rw-r--r--fs/nfs/sysfs.c3
-rw-r--r--fs/nfs/write.c22
-rw-r--r--fs/nfsd/Kconfig12
-rw-r--r--fs/nfsd/Makefile3
-rw-r--r--fs/nfsd/blocklayout.c1
-rw-r--r--fs/nfsd/filecache.c7
-rw-r--r--fs/nfsd/flexfilelayout.c2
-rw-r--r--fs/nfsd/nfs3proc.c19
-rw-r--r--fs/nfsd/nfs3xdr.c4
-rw-r--r--fs/nfsd/nfs4layouts.c2
-rw-r--r--fs/nfsd/nfs4proc.c13
-rw-r--r--fs/nfsd/nfs4state.c24
-rw-r--r--fs/nfsd/nfs4xdr.c20
-rw-r--r--fs/nfsd/nfscache.c33
-rw-r--r--fs/nfsd/nfsctl.c15
-rw-r--r--fs/nfsd/nfsd.h2
-rw-r--r--fs/nfsd/nfsfh.c4
-rw-r--r--fs/nfsd/nfsfh.h20
-rw-r--r--fs/nfsd/nfsproc.c2
-rw-r--r--fs/nfsd/nfssvc.c25
-rw-r--r--fs/nfsd/trace.h121
-rw-r--r--fs/nfsd/vfs.c67
-rw-r--r--fs/nfsd/vfs.h6
-rw-r--r--fs/nfsd/xdr.h2
-rw-r--r--fs/nilfs2/inode.c40
-rw-r--r--fs/nilfs2/mdt.c3
-rw-r--r--fs/nilfs2/segbuf.c63
-rw-r--r--fs/nilfs2/super.c2
-rw-r--r--fs/notify/fanotify/fanotify_user.c9
-rw-r--r--fs/ntfs/aops.c21
-rw-r--r--fs/ntfs/inode.c6
-rw-r--r--fs/ntfs3/fsntfs.c36
-rw-r--r--fs/ntfs3/inode.c2
-rw-r--r--fs/ntfs3/super.c2
-rw-r--r--fs/ocfs2/alloc.c2
-rw-r--r--fs/ocfs2/aops.c6
-rw-r--r--fs/ocfs2/cluster/heartbeat.c4
-rw-r--r--fs/ocfs2/cluster/nodemanager.c2
-rw-r--r--fs/ocfs2/dir.c4
-rw-r--r--fs/ocfs2/dlmfs/dlmfs.c2
-rw-r--r--fs/ocfs2/file.c13
-rw-r--r--fs/ocfs2/inode.c2
-rw-r--r--fs/ocfs2/localalloc.c6
-rw-r--r--fs/ocfs2/namei.c2
-rw-r--r--fs/ocfs2/ocfs2.h4
-rw-r--r--fs/ocfs2/quota_global.c2
-rw-r--r--fs/ocfs2/stack_user.c18
-rw-r--r--fs/ocfs2/stackglue.c13
-rw-r--r--fs/ocfs2/suballoc.c25
-rw-r--r--fs/ocfs2/super.c24
-rw-r--r--fs/ocfs2/xattr.c2
-rw-r--r--fs/omfs/file.c3
-rw-r--r--fs/openpromfs/inode.c2
-rw-r--r--fs/orangefs/inode.c121
-rw-r--r--fs/orangefs/super.c2
-rw-r--r--fs/overlayfs/copy_up.c16
-rw-r--r--fs/overlayfs/super.c2
-rw-r--r--fs/pipe.c24
-rw-r--r--fs/proc/base.c8
-rw-r--r--fs/proc/inode.c2
-rw-r--r--fs/proc/page.c1
-rw-r--r--fs/proc/task_mmu.c49
-rw-r--r--fs/proc/vmcore.c43
-rw-r--r--fs/pstore/platform.c38
-rw-r--r--fs/pstore/ram_core.c4
-rw-r--r--fs/qnx4/inode.c2
-rw-r--r--fs/qnx6/inode.c2
-rw-r--r--fs/quota/dquot.c11
-rw-r--r--fs/read_write.c34
-rw-r--r--fs/reiserfs/inode.c40
-rw-r--r--fs/reiserfs/journal.c4
-rw-r--r--fs/reiserfs/super.c2
-rw-r--r--fs/remap_range.c23
-rw-r--r--fs/romfs/super.c2
-rw-r--r--fs/splice.c24
-rw-r--r--fs/squashfs/block.c11
-rw-r--r--fs/squashfs/super.c2
-rw-r--r--fs/stat.c49
-rw-r--r--fs/super.c19
-rw-r--r--fs/sync.c18
-rw-r--r--fs/sysv/inode.c2
-rw-r--r--fs/sysv/itree.c3
-rw-r--r--fs/tracefs/inode.c5
-rw-r--r--fs/ubifs/file.c34
-rw-r--r--fs/ubifs/super.c2
-rw-r--r--fs/udf/file.c3
-rw-r--r--fs/udf/inode.c12
-rw-r--r--fs/udf/super.c2
-rw-r--r--fs/ufs/inode.c3
-rw-r--r--fs/ufs/super.c2
-rw-r--r--fs/unicode/Kconfig18
-rw-r--r--fs/unicode/Makefile6
-rw-r--r--fs/userfaultfd.c11
-rw-r--r--fs/vboxsf/file.c2
-rw-r--r--fs/vboxsf/super.c2
-rw-r--r--fs/vboxsf/utils.c1
-rw-r--r--fs/xfs/libxfs/xfs_btree.c2
-rw-r--r--fs/xfs/libxfs/xfs_dir2.c36
-rw-r--r--fs/xfs/libxfs/xfs_dir2.h8
-rw-r--r--fs/xfs/libxfs/xfs_dir2_priv.h5
-rw-r--r--fs/xfs/scrub/attr.h2
-rw-r--r--fs/xfs/xfs_aops.c23
-rw-r--r--fs/xfs/xfs_bio_io.c14
-rw-r--r--fs/xfs/xfs_bmap_item.c2
-rw-r--r--fs/xfs/xfs_bmap_util.c9
-rw-r--r--fs/xfs/xfs_buf.c52
-rw-r--r--fs/xfs/xfs_buf_item.c5
-rw-r--r--fs/xfs/xfs_extfree_item.c2
-rw-r--r--fs/xfs/xfs_file.c86
-rw-r--r--fs/xfs/xfs_fsmap.c4
-rw-r--r--fs/xfs/xfs_icache.c12
-rw-r--r--fs/xfs/xfs_inode.c100
-rw-r--r--fs/xfs/xfs_inode.h11
-rw-r--r--fs/xfs/xfs_inode_item.c12
-rw-r--r--fs/xfs/xfs_ioctl.c4
-rw-r--r--fs/xfs/xfs_iops.c118
-rw-r--r--fs/xfs/xfs_log.c19
-rw-r--r--fs/xfs/xfs_log_cil.c24
-rw-r--r--fs/xfs/xfs_pnfs.c45
-rw-r--r--fs/xfs/xfs_qm.c8
-rw-r--r--fs/xfs/xfs_refcount_item.c2
-rw-r--r--fs/xfs/xfs_reflink.c5
-rw-r--r--fs/xfs/xfs_rmap_item.c2
-rw-r--r--fs/xfs/xfs_super.c13
-rw-r--r--fs/xfs/xfs_trace.h8
-rw-r--r--fs/xfs/xfs_trans.c90
-rw-r--r--fs/xfs/xfs_trans.h6
-rw-r--r--fs/xfs/xfs_trans_ail.c47
-rw-r--r--fs/xfs/xfs_trans_priv.h3
-rw-r--r--fs/zonefs/super.c15
-rw-r--r--include/acpi/acpi_bus.h2
-rw-r--r--include/acpi/actypes.h4
-rw-r--r--include/acpi/apei.h4
-rw-r--r--include/acpi/platform/aclinux.h5
-rw-r--r--include/asm-generic/access_ok.h48
-rw-r--r--include/asm-generic/bitops/instrumented-atomic.h12
-rw-r--r--include/asm-generic/bitops/instrumented-non-atomic.h16
-rw-r--r--include/asm-generic/hyperv-tlfs.h7
-rw-r--r--include/asm-generic/tlb.h4
-rw-r--r--include/asm-generic/uaccess.h46
-rw-r--r--include/asm-generic/vmlinux.lds.h11
-rw-r--r--include/asm-generic/xor.h84
-rw-r--r--include/clocksource/arm_arch_timer.h1
-rw-r--r--include/crypto/algapi.h10
-rw-r--r--include/crypto/asym_tpm_subtype.h19
-rw-r--r--include/crypto/dh.h26
-rw-r--r--include/crypto/internal/blake2s.h40
-rw-r--r--include/crypto/internal/kpp.h158
-rw-r--r--include/crypto/sm3.h34
-rw-r--r--include/drm/bridge/dw_mipi_dsi.h4
-rw-r--r--include/drm/dp/drm_dp_aux_bus.h (renamed from include/drm/drm_dp_aux_bus.h)0
-rw-r--r--include/drm/dp/drm_dp_dual_mode_helper.h (renamed from include/drm/drm_dp_dual_mode_helper.h)0
-rw-r--r--include/drm/dp/drm_dp_helper.h (renamed from include/drm/drm_dp_helper.h)35
-rw-r--r--include/drm/dp/drm_dp_mst_helper.h (renamed from include/drm/drm_dp_mst_helper.h)2
-rw-r--r--include/drm/drm_bridge.h7
-rw-r--r--include/drm/drm_buddy.h159
-rw-r--r--include/drm/drm_cache.h6
-rw-r--r--include/drm/drm_client.h7
-rw-r--r--include/drm/drm_connector.h25
-rw-r--r--include/drm/drm_crtc.h12
-rw-r--r--include/drm/drm_dsc.h2
-rw-r--r--include/drm/drm_edid.h4
-rw-r--r--include/drm/drm_format_helper.h4
-rw-r--r--include/drm/drm_gem.h6
-rw-r--r--include/drm/drm_gem_atomic_helper.h6
-rw-r--r--include/drm/drm_gem_cma_helper.h6
-rw-r--r--include/drm/drm_gem_framebuffer_helper.h8
-rw-r--r--include/drm/drm_gem_shmem_helper.h14
-rw-r--r--include/drm/drm_gem_ttm_helper.h6
-rw-r--r--include/drm/drm_gem_vram_helper.h9
-rw-r--r--include/drm/drm_mipi_dbi.h10
-rw-r--r--include/drm/drm_mode_config.h18
-rw-r--r--include/drm/drm_mode_object.h7
-rw-r--r--include/drm/drm_modes.h8
-rw-r--r--include/drm/drm_modeset_lock.h1
-rw-r--r--include/drm/drm_module.h125
-rw-r--r--include/drm/drm_panel.h8
-rw-r--r--include/drm/drm_plane.h5
-rw-r--r--include/drm/drm_prime.h6
-rw-r--r--include/drm/drm_privacy_screen_driver.h13
-rw-r--r--include/drm/gpu_scheduler.h3
-rw-r--r--include/drm/i915_pciids.h6
-rw-r--r--include/drm/ttm/ttm_bo_api.h10
-rw-r--r--include/drm/ttm/ttm_kmap_iter.h10
-rw-r--r--include/drm/ttm/ttm_resource.h35
-rw-r--r--include/dt-bindings/clock/at91.h1
-rw-r--r--include/dt-bindings/clock/dra7.h14
-rw-r--r--include/dt-bindings/clock/fsd-clk.h150
-rw-r--r--include/dt-bindings/clock/r9a06g032-sysctrl.h1
-rw-r--r--include/dt-bindings/clock/r9a07g054-cpg.h229
-rw-r--r--include/dt-bindings/clock/tegra234-clock.h135
-rw-r--r--include/dt-bindings/interrupt-controller/apple-aic.h2
-rw-r--r--include/dt-bindings/memory/tegra234-mc.h75
-rw-r--r--include/dt-bindings/pinctrl/k3.h3
-rw-r--r--include/dt-bindings/power/imx8mp-power.h35
-rw-r--r--include/dt-bindings/power/imx8mq-power.h3
-rw-r--r--include/dt-bindings/power/meson-s4-power.h19
-rw-r--r--include/dt-bindings/power/mt8186-power.h32
-rw-r--r--include/dt-bindings/power/mt8195-power.h46
-rw-r--r--include/dt-bindings/power/qcom-rpmpd.h5
-rw-r--r--include/dt-bindings/power/tegra234-powergate.h22
-rw-r--r--include/dt-bindings/regulator/richtek,rt5190a-regulator.h15
-rw-r--r--include/dt-bindings/regulator/ti,tps62864.h9
-rw-r--r--include/dt-bindings/reset/tegra234-reset.h45
-rw-r--r--include/dt-bindings/sound/microchip,pdmc.h13
-rw-r--r--include/dt-bindings/sound/tlv320aic31xx-micbias.h9
-rw-r--r--include/dt-bindings/sound/tlv320aic31xx.h14
-rw-r--r--include/keys/system_keyring.h14
-rw-r--r--include/kunit/assert.h220
-rw-r--r--include/kunit/test.h745
-rw-r--r--include/kvm/arm_pmu.h5
-rw-r--r--include/kvm/arm_psci.h9
-rw-r--r--include/linux/acpi.h7
-rw-r--r--include/linux/acpi_agdi.h13
-rw-r--r--include/linux/amba/bus.h21
-rw-r--r--include/linux/arch_topology.h4
-rw-r--r--include/linux/arm-smccc.h5
-rw-r--r--include/linux/arm_sdei.h2
-rw-r--r--include/linux/ata.h2
-rw-r--r--include/linux/atomic/atomic-arch-fallback.h38
-rw-r--r--include/linux/backing-dev-defs.h8
-rw-r--r--include/linux/backing-dev.h50
-rw-r--r--include/linux/binfmts.h15
-rw-r--r--include/linux/bio.h38
-rw-r--r--include/linux/bitfield.h3
-rw-r--r--include/linux/blk-cgroup.h461
-rw-r--r--include/linux/blk-mq.h6
-rw-r--r--include/linux/blk_types.h10
-rw-r--r--include/linux/blkdev.h302
-rw-r--r--include/linux/bpf-cgroup.h24
-rw-r--r--include/linux/bpf.h151
-rw-r--r--include/linux/bpf_local_storage.h7
-rw-r--r--include/linux/bpf_types.h1
-rw-r--r--include/linux/bpf_verifier.h11
-rw-r--r--include/linux/btf.h85
-rw-r--r--include/linux/btf_ids.h13
-rw-r--r--include/linux/buffer_head.h9
-rw-r--r--include/linux/cacheflush.h2
-rw-r--r--include/linux/can/bittiming.h6
-rw-r--r--include/linux/ceph/ceph_fs.h5
-rw-r--r--include/linux/ceph/libceph.h2
-rw-r--r--include/linux/ceph/messenger.h5
-rw-r--r--include/linux/cgroup.h5
-rw-r--r--include/linux/cgroup_api.h1
-rw-r--r--include/linux/clk/at91_pmc.h4
-rw-r--r--include/linux/cma.h10
-rw-r--r--include/linux/compiler-clang.h25
-rw-r--r--include/linux/compiler-gcc.h7
-rw-r--r--include/linux/compiler.h21
-rw-r--r--include/linux/compiler_types.h18
-rw-r--r--include/linux/coredump.h20
-rw-r--r--include/linux/cpufreq.h8
-rw-r--r--include/linux/cpuhotplug.h3
-rw-r--r--include/linux/cpumask.h18
-rw-r--r--include/linux/cpumask_api.h1
-rw-r--r--include/linux/crypto.h9
-rw-r--r--include/linux/damon.h87
-rw-r--r--include/linux/device-mapper.h9
-rw-r--r--include/linux/dma-buf-map.h4
-rw-r--r--include/linux/dma-buf.h12
-rw-r--r--include/linux/dma-fence-array.h15
-rw-r--r--include/linux/dma-fence-chain.h18
-rw-r--r--include/linux/dma-fence.h38
-rw-r--r--include/linux/dma-resv.h17
-rw-r--r--include/linux/dsa/8021q.h26
-rw-r--r--include/linux/dsa/tag_qca.h82
-rw-r--r--include/linux/dtpm.h36
-rw-r--r--include/linux/elfcore.h4
-rw-r--r--include/linux/entry-common.h15
-rw-r--r--include/linux/etherdevice.h5
-rw-r--r--include/linux/ethtool.h8
-rw-r--r--include/linux/fault-inject.h2
-rw-r--r--include/linux/fb.h4
-rw-r--r--include/linux/filter.h36
-rw-r--r--include/linux/firmware/imx/svc/rm.h5
-rw-r--r--include/linux/firmware/xlnx-zynqmp.h8
-rw-r--r--include/linux/fprobe.h105
-rw-r--r--include/linux/fs.h159
-rw-r--r--include/linux/fs_api.h1
-rw-r--r--include/linux/fscache.h8
-rw-r--r--include/linux/fscrypt.h18
-rw-r--r--include/linux/fsnotify.h49
-rw-r--r--include/linux/ftrace.h14
-rw-r--r--include/linux/genhd.h291
-rw-r--r--include/linux/gfp.h10
-rw-r--r--include/linux/gfp_api.h1
-rw-r--r--include/linux/greybus/greybus_manifest.h4
-rw-r--r--include/linux/greybus/hd.h2
-rw-r--r--include/linux/greybus/module.h2
-rw-r--r--include/linux/hashtable_api.h1
-rw-r--r--include/linux/highmem-internal.h10
-rw-r--r--include/linux/hisi_acc_qm.h (renamed from drivers/crypto/hisilicon/qm.h)49
-rw-r--r--include/linux/hmm.h9
-rw-r--r--include/linux/hrtimer_api.h1
-rw-r--r--include/linux/huge_mm.h59
-rw-r--r--include/linux/hugetlb.h13
-rw-r--r--include/linux/hw_random.h2
-rw-r--r--include/linux/hwmon.h2
-rw-r--r--include/linux/hyperv.h1
-rw-r--r--include/linux/i3c/ccc.h6
-rw-r--r--include/linux/ieee80211.h347
-rw-r--r--include/linux/if_arp.h1
-rw-r--r--include/linux/if_bridge.h20
-rw-r--r--include/linux/if_hsr.h16
-rw-r--r--include/linux/if_macvlan.h1
-rw-r--r--include/linux/if_vlan.h6
-rw-r--r--include/linux/inetdevice.h1
-rw-r--r--include/linux/init.h11
-rw-r--r--include/linux/interrupt.h11
-rw-r--r--include/linux/io_uring.h5
-rw-r--r--include/linux/ioasid.h21
-rw-r--r--include/linux/iomap.h7
-rw-r--r--include/linux/iosys-map.h459
-rw-r--r--include/linux/ipv6.h9
-rw-r--r--include/linux/irq.h9
-rw-r--r--include/linux/irqchip/versatile-fpga.h14
-rw-r--r--include/linux/irqdesc.h1
-rw-r--r--include/linux/irqdomain.h15
-rw-r--r--include/linux/jbd2.h20
-rw-r--r--include/linux/jump_label.h13
-rw-r--r--include/linux/kasan-enabled.h35
-rw-r--r--include/linux/kasan.h23
-rw-r--r--include/linux/kernel.h7
-rw-r--r--include/linux/kexec.h12
-rw-r--r--include/linux/kfence.h2
-rw-r--r--include/linux/kobject_api.h1
-rw-r--r--include/linux/kprobes.h3
-rw-r--r--include/linux/kref_api.h1
-rw-r--r--include/linux/ksm.h6
-rw-r--r--include/linux/kthread.h22
-rw-r--r--include/linux/ktime_api.h1
-rw-r--r--include/linux/kvm_host.h116
-rw-r--r--include/linux/libata.h13
-rw-r--r--include/linux/linkage.h67
-rw-r--r--include/linux/linkmode.h5
-rw-r--r--include/linux/list_lru.h17
-rw-r--r--include/linux/llist_api.h1
-rw-r--r--include/linux/local_lock_internal.h6
-rw-r--r--include/linux/lockdep_api.h1
-rw-r--r--include/linux/log2.h4
-rw-r--r--include/linux/lsm_hook_defs.h4
-rw-r--r--include/linux/lsm_hooks.h5
-rw-r--r--include/linux/memcontrol.h51
-rw-r--r--include/linux/memory.h12
-rw-r--r--include/linux/memory_hotplug.h124
-rw-r--r--include/linux/memremap.h27
-rw-r--r--include/linux/mfd/idt82p33_reg.h3
-rw-r--r--include/linux/mfd/lpc_ich.h2
-rw-r--r--include/linux/migrate.h8
-rw-r--r--include/linux/mii.h50
-rw-r--r--include/linux/mlx5/cq.h2
-rw-r--r--include/linux/mlx5/driver.h64
-rw-r--r--include/linux/mlx5/fs.h1
-rw-r--r--include/linux/mlx5/mlx5_ifc.h192
-rw-r--r--include/linux/mlx5/port.h2
-rw-r--r--include/linux/mlx5/qp.h5
-rw-r--r--include/linux/mm.h334
-rw-r--r--include/linux/mm_api.h1
-rw-r--r--include/linux/mm_inline.h108
-rw-r--r--include/linux/mm_types.h34
-rw-r--r--include/linux/mmzone.h22
-rw-r--r--include/linux/mod_devicetable.h2
-rw-r--r--include/linux/mutex_api.h1
-rw-r--r--include/linux/net/intel/i40e_client.h10
-rw-r--r--include/linux/net/intel/iidc.h4
-rw-r--r--include/linux/netdevice.h180
-rw-r--r--include/linux/netfilter.h1
-rw-r--r--include/linux/netfilter/nf_conntrack_pptp.h38
-rw-r--r--include/linux/netfilter_netdev.h4
-rw-r--r--include/linux/netfs.h7
-rw-r--r--include/linux/netlink.h9
-rw-r--r--include/linux/nfs.h8
-rw-r--r--include/linux/nfs_fs.h13
-rw-r--r--include/linux/nfs_fs_sb.h5
-rw-r--r--include/linux/nfs_xdr.h5
-rw-r--r--include/linux/node.h25
-rw-r--r--include/linux/nvme-fc-driver.h2
-rw-r--r--include/linux/nvme-tcp.h1
-rw-r--r--include/linux/nvme.h11
-rw-r--r--include/linux/nvmem-provider.h4
-rw-r--r--include/linux/overflow.h114
-rw-r--r--include/linux/page-flags.h92
-rw-r--r--include/linux/page_table_check.h19
-rw-r--r--include/linux/pageblock-flags.h7
-rw-r--r--include/linux/pagemap.h182
-rw-r--r--include/linux/part_stat.h2
-rw-r--r--include/linux/pci.h15
-rw-r--r--include/linux/pci_ids.h7
-rw-r--r--include/linux/pcs/pcs-xpcs.h3
-rw-r--r--include/linux/perf/arm_pmu.h2
-rw-r--r--include/linux/perf_event.h17
-rw-r--r--include/linux/perf_event_api.h1
-rw-r--r--include/linux/pgtable.h1
-rw-r--r--include/linux/pgtable_api.h1
-rw-r--r--include/linux/phy.h7
-rw-r--r--include/linux/phylink.h4
-rw-r--r--include/linux/pid_namespace.h5
-rw-r--r--include/linux/platform_data/brcmfmac.h2
-rw-r--r--include/linux/platform_data/cros_ec_commands.h2
-rw-r--r--include/linux/platform_data/eth_ixp4xx.h21
-rw-r--r--include/linux/platform_data/spi-s3c64xx.h14
-rw-r--r--include/linux/platform_data/wan_ixp4xx_hss.h17
-rw-r--r--include/linux/platform_data/x86/spi-intel.h (renamed from include/linux/platform_data/x86/intel-spi.h)12
-rw-r--r--include/linux/pm.h8
-rw-r--r--include/linux/pm_runtime.h4
-rw-r--r--include/linux/posix-timers.h2
-rw-r--r--include/linux/psi.h14
-rw-r--r--include/linux/psi_types.h4
-rw-r--r--include/linux/pstore.h6
-rw-r--r--include/linux/ptp_classify.h15
-rw-r--r--include/linux/ptrace_api.h1
-rw-r--r--include/linux/qcom_scm.h16
-rw-r--r--include/linux/quota.h2
-rw-r--r--include/linux/raid/xor.h21
-rw-r--r--include/linux/random.h41
-rw-r--r--include/linux/randomize_kstack.h21
-rw-r--r--include/linux/rcupdate.h4
-rw-r--r--include/linux/rcutiny.h3
-rw-r--r--include/linux/rcutree.h4
-rw-r--r--include/linux/rcuwait.h6
-rw-r--r--include/linux/rcuwait_api.h1
-rw-r--r--include/linux/ref_tracker.h4
-rw-r--r--include/linux/refcount_api.h1
-rw-r--r--include/linux/regmap.h6
-rw-r--r--include/linux/resource.h2
-rw-r--r--include/linux/rethook.h100
-rw-r--r--include/linux/rfkill.h5
-rw-r--r--include/linux/rmap.h76
-rw-r--r--include/linux/rtnetlink.h3
-rw-r--r--include/linux/rwsem.h2
-rw-r--r--include/linux/sbitmap.h51
-rw-r--r--include/linux/sched.h44
-rw-r--r--include/linux/sched/affinity.h1
-rw-r--r--include/linux/sched/cond_resched.h1
-rw-r--r--include/linux/sched/deadline.h2
-rw-r--r--include/linux/sched/isolation.h43
-rw-r--r--include/linux/sched/mm.h26
-rw-r--r--include/linux/sched/posix-timers.h1
-rw-r--r--include/linux/sched/rseq_api.h1
-rw-r--r--include/linux/sched/sysctl.h14
-rw-r--r--include/linux/sched/task.h4
-rw-r--r--include/linux/sched/task_flags.h1
-rw-r--r--include/linux/sched/task_stack.h2
-rw-r--r--include/linux/sched/thread_info_api.h1
-rw-r--r--include/linux/sched/topology.h1
-rw-r--r--include/linux/sched_clock.h2
-rw-r--r--include/linux/scmi_protocol.h15
-rw-r--r--include/linux/security.h8
-rw-r--r--include/linux/seqlock_api.h1
-rw-r--r--include/linux/shmem_fs.h1
-rw-r--r--include/linux/skbuff.h246
-rw-r--r--include/linux/skmsg.h29
-rw-r--r--include/linux/slab.h9
-rw-r--r--include/linux/soc/ixp4xx/cpu.h26
-rw-r--r--include/linux/soc/ixp4xx/npe.h2
-rw-r--r--include/linux/soc/mediatek/infracfg.h133
-rw-r--r--include/linux/soc/qcom/llcc-qcom.h9
-rw-r--r--include/linux/soc/qcom/mdt_loader.h17
-rw-r--r--include/linux/soc/ti/ti_sci_protocol.h2
-rw-r--r--include/linux/socket.h1
-rw-r--r--include/linux/softirq.h1
-rw-r--r--include/linux/sort.h2
-rw-r--r--include/linux/spi/pxa2xx_spi.h1
-rw-r--r--include/linux/spi/s3c24xx.h5
-rw-r--r--include/linux/spi/spi.h41
-rw-r--r--include/linux/spinlock_api.h1
-rw-r--r--include/linux/ssb/ssb_driver_gige.h2
-rw-r--r--include/linux/stddef.h6
-rw-r--r--include/linux/string_helpers.h20
-rw-r--r--include/linux/sunrpc/svc.h26
-rw-r--r--include/linux/sunrpc/svc_xprt.h13
-rw-r--r--include/linux/sunrpc/xdr.h2
-rw-r--r--include/linux/sunrpc/xprt.h1
-rw-r--r--include/linux/suspend.h15
-rw-r--r--include/linux/swait_api.h1
-rw-r--r--include/linux/swap.h17
-rw-r--r--include/linux/syscalls.h4
-rw-r--r--include/linux/syscalls_api.h1
-rw-r--r--include/linux/sysctl.h2
-rw-r--r--include/linux/tcp.h1
-rw-r--r--include/linux/tee_drv.h138
-rw-r--r--include/linux/thread_info.h5
-rw-r--r--include/linux/topology.h3
-rw-r--r--include/linux/trace_events.h53
-rw-r--r--include/linux/types.h1
-rw-r--r--include/linux/u64_stats_sync_api.h1
-rw-r--r--include/linux/uaccess.h61
-rw-r--r--include/linux/udp.h5
-rw-r--r--include/linux/uio.h17
-rw-r--r--include/linux/usb/role.h6
-rw-r--r--include/linux/vdpa.h18
-rw-r--r--include/linux/vfio.h53
-rw-r--r--include/linux/vfio_pci_core.h13
-rw-r--r--include/linux/virtio.h1
-rw-r--r--include/linux/virtio_config.h3
-rw-r--r--include/linux/vm_event_item.h3
-rw-r--r--include/linux/vmalloc.h9
-rw-r--r--include/linux/wait_api.h1
-rw-r--r--include/linux/watch_queue.h3
-rw-r--r--include/linux/workqueue_api.h1
-rw-r--r--include/linux/wwan.h2
-rw-r--r--include/linux/xarray.h9
-rw-r--r--include/media/hevc-ctrls.h6
-rw-r--r--include/media/i2c/m5mols.h4
-rw-r--r--include/media/i2c/noon010pc30.h4
-rw-r--r--include/media/media-entity.h25
-rw-r--r--include/media/mipi-csi2.h45
-rw-r--r--include/media/rc-core.h12
-rw-r--r--include/media/v4l2-fwnode.h61
-rw-r--r--include/media/v4l2-mediabus.h104
-rw-r--r--include/media/v4l2-subdev.h13
-rw-r--r--include/net/addrconf.h6
-rw-r--r--include/net/af_vsock.h3
-rw-r--r--include/net/arp.h1
-rw-r--r--include/net/ax25.h24
-rw-r--r--include/net/bluetooth/bluetooth.h19
-rw-r--r--include/net/bluetooth/hci.h10
-rw-r--r--include/net/bluetooth/hci_core.h25
-rw-r--r--include/net/bluetooth/mgmt.h18
-rw-r--r--include/net/bond_3ad.h2
-rw-r--r--include/net/bond_options.h31
-rw-r--r--include/net/bonding.h44
-rw-r--r--include/net/cfg80211.h97
-rw-r--r--include/net/cfg802154.h10
-rw-r--r--include/net/checksum.h54
-rw-r--r--include/net/devlink.h19
-rw-r--r--include/net/dsa.h204
-rw-r--r--include/net/dst_metadata.h14
-rw-r--r--include/net/esp.h2
-rw-r--r--include/net/flow.h6
-rw-r--r--include/net/flow_offload.h21
-rw-r--r--include/net/gro.h57
-rw-r--r--include/net/gtp.h42
-rw-r--r--include/net/ieee80211_radiotap.h4
-rw-r--r--include/net/if_inet6.h2
-rw-r--r--include/net/inet_connection_sock.h8
-rw-r--r--include/net/inet_dscp.h57
-rw-r--r--include/net/inet_frag.h2
-rw-r--r--include/net/inet_timewait_sock.h8
-rw-r--r--include/net/ioam6.h2
-rw-r--r--include/net/ip.h24
-rw-r--r--include/net/ip6_fib.h15
-rw-r--r--include/net/ip_fib.h3
-rw-r--r--include/net/ipv6.h26
-rw-r--r--include/net/ipv6_frag.h1
-rw-r--r--include/net/mac80211.h37
-rw-r--r--include/net/mac802154.h12
-rw-r--r--include/net/mctp.h28
-rw-r--r--include/net/mptcp.h6
-rw-r--r--include/net/ndisc.h9
-rw-r--r--include/net/neighbour.h18
-rw-r--r--include/net/net_namespace.h8
-rw-r--r--include/net/netfilter/nf_conntrack.h1
-rw-r--r--include/net/netfilter/nf_conntrack_acct.h1
-rw-r--r--include/net/netfilter/nf_conntrack_bpf.h23
-rw-r--r--include/net/netfilter/nf_conntrack_ecache.h15
-rw-r--r--include/net/netfilter/nf_conntrack_extend.h18
-rw-r--r--include/net/netfilter/nf_conntrack_helper.h1
-rw-r--r--include/net/netfilter/nf_conntrack_labels.h3
-rw-r--r--include/net/netfilter/nf_conntrack_seqadj.h3
-rw-r--r--include/net/netfilter/nf_conntrack_timeout.h20
-rw-r--r--include/net/netfilter/nf_conntrack_timestamp.h13
-rw-r--r--include/net/netfilter/nf_flow_table.h24
-rw-r--r--include/net/netfilter/nf_queue.h2
-rw-r--r--include/net/netfilter/nf_tables.h24
-rw-r--r--include/net/netfilter/nf_tables_core.h9
-rw-r--r--include/net/netfilter/nf_tables_offload.h2
-rw-r--r--include/net/netfilter/nft_fib.h3
-rw-r--r--include/net/netfilter/nft_meta.h3
-rw-r--r--include/net/netns/core.h1
-rw-r--r--include/net/netns/ipv4.h14
-rw-r--r--include/net/netns/ipv6.h9
-rw-r--r--include/net/netns/smc.h6
-rw-r--r--include/net/netns/xfrm.h6
-rw-r--r--include/net/page_pool.h133
-rw-r--r--include/net/pkt_cls.h11
-rw-r--r--include/net/pkt_sched.h6
-rw-r--r--include/net/request_sock.h2
-rw-r--r--include/net/route.h2
-rw-r--r--include/net/sch_generic.h5
-rw-r--r--include/net/sock.h32
-rw-r--r--include/net/switchdev.h72
-rw-r--r--include/net/tc_act/tc_police.h30
-rw-r--r--include/net/tc_act/tc_vlan.h10
-rw-r--r--include/net/tcp.h28
-rw-r--r--include/net/tls.h2
-rw-r--r--include/net/udplite.h43
-rw-r--r--include/net/vxlan.h54
-rw-r--r--include/net/xdp.h122
-rw-r--r--include/net/xdp_sock_drv.h5
-rw-r--r--include/net/xfrm.h54
-rw-r--r--include/net/xsk_buff_pool.h1
-rw-r--r--include/ras/ras_event.h1
-rw-r--r--include/rdma/ib.h2
-rw-r--r--include/scsi/scsi_cmnd.h9
-rw-r--r--include/scsi/scsi_driver.h9
-rw-r--r--include/soc/at91/sama7-ddr.h15
-rw-r--r--include/soc/bcm2835/raspberrypi-firmware.h1
-rw-r--r--include/soc/fsl/dpaa2-fd.h3
-rw-r--r--include/soc/fsl/qe/immap_qe.h3
-rw-r--r--include/soc/fsl/qe/qe_tdm.h4
-rw-r--r--include/soc/fsl/qe/ucc_fast.h2
-rw-r--r--include/soc/fsl/qe/ucc_slow.h2
-rw-r--r--include/soc/mediatek/smi.h20
-rw-r--r--include/soc/microchip/mpfs.h4
-rw-r--r--include/soc/mscc/ocelot.h113
-rw-r--r--include/soc/mscc/ocelot_vcap.h18
-rw-r--r--include/soc/tegra/bpmp-abi.h2
-rw-r--r--include/sound/hda_codec.h11
-rw-r--r--include/sound/hda_verbs.h2
-rw-r--r--include/sound/hdaudio.h3
-rw-r--r--include/sound/hdaudio_ext.h51
-rw-r--r--include/sound/intel-nhlt.h22
-rw-r--r--include/sound/pcm.h16
-rw-r--r--include/sound/simple_card_utils.h12
-rw-r--r--include/sound/soc-acpi.h29
-rw-r--r--include/sound/soc-dapm.h1
-rw-r--r--include/sound/sof.h8
-rw-r--r--include/sound/sof/channel_map.h4
-rw-r--r--include/sound/sof/dai.h5
-rw-r--r--include/sound/sof/header.h2
-rw-r--r--include/sound/sof/info.h1
-rw-r--r--include/sound/sof/topology.h10
-rw-r--r--include/trace/bpf_probe.h6
-rw-r--r--include/trace/define_custom_trace.h77
-rw-r--r--include/trace/events/block.h49
-rw-r--r--include/trace/events/btrfs.h1
-rw-r--r--include/trace/events/cachefiles.h2
-rw-r--r--include/trace/events/compaction.h26
-rw-r--r--include/trace/events/ext4.h328
-rw-r--r--include/trace/events/io_uring.h333
-rw-r--r--include/trace/events/mctp.h5
-rw-r--r--include/trace/events/mptcp.h4
-rw-r--r--include/trace/events/net.h14
-rw-r--r--include/trace/events/random.h233
-rw-r--r--include/trace/events/rcu.h9
-rw-r--r--include/trace/events/sched.h11
-rw-r--r--include/trace/events/scmi.h28
-rw-r--r--include/trace/events/skb.h47
-rw-r--r--include/trace/events/sunrpc.h314
-rw-r--r--include/trace/events/vmscan.h10
-rw-r--r--include/trace/events/writeback.h28
-rw-r--r--include/trace/perf.h11
-rw-r--r--include/trace/stages/init.h37
-rw-r--r--include/trace/stages/stage1_defines.h51
-rw-r--r--include/trace/stages/stage2_defines.h54
-rw-r--r--include/trace/stages/stage3_defines.h135
-rw-r--r--include/trace/stages/stage4_defines.h63
-rw-r--r--include/trace/stages/stage5_defines.h89
-rw-r--r--include/trace/stages/stage6_defines.h106
-rw-r--r--include/trace/stages/stage7_defines.h36
-rw-r--r--include/trace/trace_custom_events.h221
-rw-r--r--include/trace/trace_events.h500
-rw-r--r--include/uapi/asm-generic/shmbuf.h4
-rw-r--r--include/uapi/asm-generic/signal.h2
-rw-r--r--include/uapi/asm-generic/socket.h2
-rw-r--r--include/uapi/drm/amdgpu_drm.h21
-rw-r--r--include/uapi/drm/drm_mode.h88
-rw-r--r--include/uapi/drm/i915_drm.h45
-rw-r--r--include/uapi/drm/msm_drm.h32
-rw-r--r--include/uapi/drm/panfrost_drm.h4
-rw-r--r--include/uapi/linux/android/binder.h4
-rw-r--r--include/uapi/linux/bpf.h163
-rw-r--r--include/uapi/linux/btrfs.h133
-rw-r--r--include/uapi/linux/btrfs_tree.h3
-rw-r--r--include/uapi/linux/can/isotp.h28
-rw-r--r--include/uapi/linux/cyclades.h35
-rw-r--r--include/uapi/linux/dm-ioctl.h4
-rw-r--r--include/uapi/linux/elf.h10
-rw-r--r--include/uapi/linux/ethtool_netlink.h8
-rw-r--r--include/uapi/linux/fsmap.h2
-rw-r--r--include/uapi/linux/gtp.h1
-rw-r--r--include/uapi/linux/hyperv.h11
-rw-r--r--include/uapi/linux/if_addr.h9
-rw-r--r--include/uapi/linux/if_bridge.h18
-rw-r--r--include/uapi/linux/if_ether.h2
-rw-r--r--include/uapi/linux/if_link.h91
-rw-r--r--include/uapi/linux/if_tunnel.h4
-rw-r--r--include/uapi/linux/input-event-codes.h4
-rw-r--r--include/uapi/linux/io_uring.h17
-rw-r--r--include/uapi/linux/ioam6_iptunnel.h9
-rw-r--r--include/uapi/linux/kexec.h4
-rw-r--r--include/uapi/linux/kfd_ioctl.h98
-rw-r--r--include/uapi/linux/kvm.h23
-rw-r--r--include/uapi/linux/lirc.h16
-rw-r--r--include/uapi/linux/magic.h1
-rw-r--r--include/uapi/linux/mctp.h18
-rw-r--r--include/uapi/linux/mptcp.h1
-rw-r--r--include/uapi/linux/mroute6.h1
-rw-r--r--include/uapi/linux/net_dropmon.h1
-rw-r--r--include/uapi/linux/netfilter/nf_conntrack_common.h2
-rw-r--r--include/uapi/linux/netfilter/nfnetlink_queue.h1
-rw-r--r--include/uapi/linux/nl80211.h97
-rw-r--r--include/uapi/linux/nvme_ioctl.h6
-rw-r--r--include/uapi/linux/omap3isp.h21
-rw-r--r--include/uapi/linux/openvswitch.h22
-rw-r--r--include/uapi/linux/perf_event.h4
-rw-r--r--include/uapi/linux/pkt_cls.h15
-rw-r--r--include/uapi/linux/psci.h4
-rw-r--r--include/uapi/linux/reiserfs_xattr.h2
-rw-r--r--include/uapi/linux/rfkill.h14
-rw-r--r--include/uapi/linux/rseq.h20
-rw-r--r--include/uapi/linux/rtnetlink.h14
-rw-r--r--include/uapi/linux/smc.h15
-rw-r--r--include/uapi/linux/smc_diag.h11
-rw-r--r--include/uapi/linux/socket.h4
-rw-r--r--include/uapi/linux/thermal.h6
-rw-r--r--include/uapi/linux/types.h6
-rw-r--r--include/uapi/linux/user_events.h116
-rw-r--r--include/uapi/linux/userfaultfd.h8
-rw-r--r--include/uapi/linux/v4l2-controls.h8
-rw-r--r--include/uapi/linux/vfio.h406
-rw-r--r--include/uapi/linux/videodev2.h2
-rw-r--r--include/uapi/linux/xfrm.h6
-rw-r--r--include/uapi/sound/asound.h4
-rw-r--r--include/uapi/sound/sof/abi.h4
-rw-r--r--include/uapi/xen/gntdev.h8
-rw-r--r--include/video/samsung_fimd.h4
-rw-r--r--include/xen/grant_table.h19
-rw-r--r--include/xen/xenbus_dev.h2
-rw-r--r--init/Kconfig5
-rw-r--r--init/Makefile3
-rw-r--r--init/do_mounts.c1
-rw-r--r--init/main.c18
-rw-r--r--ipc/mqueue.c2
-rw-r--r--ipc/sem.c4
-rw-r--r--kernel/Kconfig.preempt15
-rw-r--r--kernel/async.c3
-rw-r--r--kernel/audit.c62
-rw-r--r--kernel/audit.h4
-rw-r--r--kernel/auditsc.c89
-rw-r--r--kernel/bpf/Kconfig5
-rw-r--r--kernel/bpf/arraymap.c4
-rw-r--r--kernel/bpf/bpf_inode_storage.c9
-rw-r--r--kernel/bpf/bpf_iter.c20
-rw-r--r--kernel/bpf/bpf_local_storage.c60
-rw-r--r--kernel/bpf/bpf_lsm.c23
-rw-r--r--kernel/bpf/bpf_task_storage.c10
-rw-r--r--kernel/bpf/btf.c686
-rw-r--r--kernel/bpf/cgroup.c187
-rw-r--r--kernel/bpf/core.c364
-rw-r--r--kernel/bpf/cpumap.c8
-rw-r--r--kernel/bpf/devmap.c3
-rw-r--r--kernel/bpf/hashtab.c2
-rw-r--r--kernel/bpf/helpers.c47
-rw-r--r--kernel/bpf/inode.c39
-rw-r--r--kernel/bpf/local_storage.c2
-rw-r--r--kernel/bpf/preload/Kconfig7
-rw-r--r--kernel/bpf/preload/Makefile41
-rw-r--r--kernel/bpf/preload/bpf_preload.h8
-rw-r--r--kernel/bpf/preload/bpf_preload_kern.c126
-rw-r--r--kernel/bpf/preload/bpf_preload_umd_blob.S7
-rw-r--r--kernel/bpf/preload/iterators/Makefile6
-rw-r--r--kernel/bpf/preload/iterators/bpf_preload_common.h13
-rw-r--r--kernel/bpf/preload/iterators/iterators.c94
-rw-r--r--kernel/bpf/preload/iterators/iterators.lskel.h425
-rw-r--r--kernel/bpf/preload/iterators/iterators.skel.h412
-rw-r--r--kernel/bpf/reuseport_array.c2
-rw-r--r--kernel/bpf/ringbuf.c2
-rw-r--r--kernel/bpf/stackmap.c73
-rw-r--r--kernel/bpf/syscall.c100
-rw-r--r--kernel/bpf/trampoline.c13
-rw-r--r--kernel/bpf/verifier.c468
-rw-r--r--kernel/capability.c1
-rw-r--r--kernel/cgroup/cgroup-v1.c16
-rw-r--r--kernel/cgroup/cgroup.c27
-rw-r--r--kernel/cgroup/cpuset.c93
-rw-r--r--kernel/cgroup/freezer.c2
-rw-r--r--kernel/cgroup/rstat.c18
-rw-r--r--kernel/configs/debug.config1
-rw-r--r--kernel/cpu.c15
-rw-r--r--kernel/cred.c9
-rw-r--r--kernel/dma/contiguous.c4
-rw-r--r--kernel/dma/mapping.c2
-rw-r--r--kernel/dma/swiotlb.c22
-rw-r--r--kernel/entry/common.c37
-rw-r--r--kernel/events/callchain.c4
-rw-r--r--kernel/events/core.c297
-rw-r--r--kernel/events/uprobes.c13
-rw-r--r--kernel/exit.c19
-rw-r--r--kernel/fork.c315
-rw-r--r--kernel/futex/core.c2
-rw-r--r--kernel/irq/chip.c29
-rw-r--r--kernel/irq/cpuhotplug.c4
-rw-r--r--kernel/irq/debugfs.c8
-rw-r--r--kernel/irq/irqdesc.c27
-rw-r--r--kernel/irq/irqdomain.c9
-rw-r--r--kernel/irq/manage.c4
-rw-r--r--kernel/kallsyms.c4
-rw-r--r--kernel/kcov.c98
-rw-r--r--kernel/ksysfs.c3
-rw-r--r--kernel/kthread.c9
-rw-r--r--kernel/locking/lockdep.c47
-rw-r--r--kernel/locking/lockdep_internals.h6
-rw-r--r--kernel/locking/lockdep_proc.c51
-rw-r--r--kernel/locking/percpu-rwsem.c5
-rw-r--r--kernel/locking/rwsem.c2
-rw-r--r--kernel/module.c27
-rw-r--r--kernel/module_decompress.c2
-rw-r--r--kernel/padata.c2
-rw-r--r--kernel/panic.c37
-rw-r--r--kernel/power/hibernate.c7
-rw-r--r--kernel/power/main.c5
-rw-r--r--kernel/power/process.c2
-rw-r--r--kernel/power/snapshot.c21
-rw-r--r--kernel/power/suspend.c2
-rw-r--r--kernel/power/suspend_test.c8
-rw-r--r--kernel/power/swap.c14
-rw-r--r--kernel/power/wakelock.c11
-rw-r--r--kernel/printk/printk.c85
-rw-r--r--kernel/printk/printk_ringbuffer.c52
-rw-r--r--kernel/printk/printk_ringbuffer.h2
-rw-r--r--kernel/printk/sysctl.c2
-rw-r--r--kernel/rcu/rcu_segcblist.h4
-rw-r--r--kernel/rcu/rcutorture.c41
-rw-r--r--kernel/rcu/tasks.h14
-rw-r--r--kernel/rcu/tree.c331
-rw-r--r--kernel/rcu/tree.h18
-rw-r--r--kernel/rcu/tree_exp.h5
-rw-r--r--kernel/rcu/tree_nocb.h18
-rw-r--r--kernel/rcu/tree_plugin.h37
-rw-r--r--kernel/rcu/tree_stall.h35
-rw-r--r--kernel/rcu/update.c7
-rw-r--r--kernel/resource.c41
-rw-r--r--kernel/rseq.c8
-rw-r--r--kernel/sched/Makefile28
-rw-r--r--kernel/sched/autogroup.c26
-rw-r--r--kernel/sched/autogroup.h6
-rw-r--r--kernel/sched/build_policy.c52
-rw-r--r--kernel/sched/build_utility.c109
-rw-r--r--kernel/sched/clock.c44
-rw-r--r--kernel/sched/completion.c2
-rw-r--r--kernel/sched/core.c532
-rw-r--r--kernel/sched/core_sched.c5
-rw-r--r--kernel/sched/cpuacct.c12
-rw-r--r--kernel/sched/cpudeadline.c3
-rw-r--r--kernel/sched/cpufreq.c3
-rw-r--r--kernel/sched/cpufreq_schedutil.c20
-rw-r--r--kernel/sched/cpupri.c1
-rw-r--r--kernel/sched/cputime.c1
-rw-r--r--kernel/sched/deadline.c155
-rw-r--r--kernel/sched/debug.c11
-rw-r--r--kernel/sched/fair.c231
-rw-r--r--kernel/sched/idle.c3
-rw-r--r--kernel/sched/isolation.c163
-rw-r--r--kernel/sched/loadavg.c1
-rw-r--r--kernel/sched/membarrier.c10
-rw-r--r--kernel/sched/pelt.c4
-rw-r--r--kernel/sched/pelt.h4
-rw-r--r--kernel/sched/psi.c206
-rw-r--r--kernel/sched/rt.c51
-rw-r--r--kernel/sched/sched.h354
-rw-r--r--kernel/sched/stats.c1
-rw-r--r--kernel/sched/stats.h4
-rw-r--r--kernel/sched/stop_task.c1
-rw-r--r--kernel/sched/swait.c1
-rw-r--r--kernel/sched/topology.c268
-rw-r--r--kernel/sched/wait.c1
-rw-r--r--kernel/sched/wait_bit.c2
-rw-r--r--kernel/seccomp.c10
-rw-r--r--kernel/signal.c45
-rw-r--r--kernel/softirq.c10
-rw-r--r--kernel/stackleak.c5
-rw-r--r--kernel/stacktrace.c3
-rw-r--r--kernel/static_call.c1
-rw-r--r--kernel/sys.c158
-rw-r--r--kernel/sysctl.c20
-rw-r--r--kernel/taskstats.c5
-rw-r--r--kernel/time/Kconfig9
-rw-r--r--kernel/time/clocksource.c8
-rw-r--r--kernel/time/posix-cpu-timers.c12
-rw-r--r--kernel/time/tick-sched.c77
-rw-r--r--kernel/time/tick-sched.h4
-rw-r--r--kernel/torture.c6
-rw-r--r--kernel/trace/Kconfig48
-rw-r--r--kernel/trace/Makefile3
-rw-r--r--kernel/trace/blktrace.c26
-rw-r--r--kernel/trace/bpf_trace.c357
-rw-r--r--kernel/trace/fgraph.c4
-rw-r--r--kernel/trace/fprobe.c332
-rw-r--r--kernel/trace/ftrace.c69
-rw-r--r--kernel/trace/rethook.c317
-rw-r--r--kernel/trace/trace.c92
-rw-r--r--kernel/trace/trace.h3
-rw-r--r--kernel/trace/trace_eprobe.c16
-rw-r--r--kernel/trace/trace_events.c104
-rw-r--r--kernel/trace/trace_events_hist.c49
-rw-r--r--kernel/trace/trace_events_synth.c14
-rw-r--r--kernel/trace/trace_events_trigger.c73
-rw-r--r--kernel/trace/trace_events_user.c1690
-rw-r--r--kernel/trace/trace_kprobe.c2
-rw-r--r--kernel/trace/trace_osnoise.c88
-rw-r--r--kernel/trace/trace_probe.c10
-rw-r--r--kernel/trace/trace_probe.h1
-rw-r--r--kernel/trace/trace_sched_switch.c3
-rw-r--r--kernel/trace/trace_sched_wakeup.c1
-rw-r--r--kernel/trace/trace_selftest.c6
-rw-r--r--kernel/ucount.c5
-rw-r--r--kernel/user_namespace.c14
-rw-r--r--kernel/watch_queue.c25
-rw-r--r--kernel/watchdog.c2
-rw-r--r--kernel/workqueue.c62
-rw-r--r--lib/Kconfig1
-rw-r--r--lib/Kconfig.debug235
-rw-r--r--lib/Kconfig.kcsan11
-rw-r--r--lib/Kconfig.kfence12
-rw-r--r--lib/Kconfig.ubsan12
-rw-r--r--lib/Makefile8
-rw-r--r--lib/bitmap.c24
-rw-r--r--lib/crc32.c14
-rw-r--r--lib/crc32test.c2
-rw-r--r--lib/crypto/Kconfig3
-rw-r--r--lib/crypto/Makefile3
-rw-r--r--lib/crypto/blake2s.c4
-rw-r--r--lib/crypto/sm3.c246
-rw-r--r--lib/iov_iter.c2
-rw-r--r--lib/kunit/assert.c80
-rw-r--r--lib/kunit/kunit-example-test.c42
-rw-r--r--lib/kunit/test.c35
-rw-r--r--lib/kunit/try-catch.c3
-rw-r--r--lib/list-test.c61
-rw-r--r--lib/mpi/mpi-bit.c1
-rw-r--r--lib/overflow_kunit.c (renamed from lib/test_overflow.c)518
-rw-r--r--lib/raid6/test/Makefile4
-rw-r--r--lib/raid6/test/test.c1
-rw-r--r--lib/raid6/vpermxor.uc2
-rw-r--r--lib/random32.c14
-rw-r--r--lib/ref_tracker.c19
-rw-r--r--lib/sbitmap.c48
-rw-r--r--lib/sort.c40
-rw-r--r--lib/stackinit_kunit.c (renamed from lib/test_stackinit.c)269
-rw-r--r--lib/strncpy_from_user.c2
-rw-r--r--lib/strnlen_user.c2
-rw-r--r--lib/test_fprobe.c174
-rw-r--r--lib/test_hmm.c4
-rw-r--r--lib/test_kasan.c10
-rw-r--r--lib/test_lockup.c11
-rw-r--r--lib/ubsan.c10
-rw-r--r--lib/vsprintf.c59
-rw-r--r--lib/xarray.c10
-rw-r--r--mm/Kconfig22
-rw-r--r--mm/Makefile1
-rw-r--r--mm/backing-dev.c57
-rw-r--r--mm/cma.c31
-rw-r--r--mm/cma.h1
-rw-r--r--mm/compaction.c60
-rw-r--r--mm/damon/Kconfig19
-rw-r--r--mm/damon/Makefile7
-rw-r--r--mm/damon/core-test.h21
-rw-r--r--mm/damon/core.c190
-rw-r--r--mm/damon/dbgfs-test.h85
-rw-r--r--mm/damon/dbgfs.c222
-rw-r--r--mm/damon/ops-common.c (renamed from mm/damon/prmtv-common.c)2
-rw-r--r--mm/damon/ops-common.h (renamed from mm/damon/prmtv-common.h)0
-rw-r--r--mm/damon/paddr.c98
-rw-r--r--mm/damon/reclaim.c9
-rw-r--r--mm/damon/sysfs.c2596
-rw-r--r--mm/damon/vaddr-test.h8
-rw-r--r--mm/damon/vaddr.c43
-rw-r--r--mm/debug.c18
-rw-r--r--mm/debug_vm_pgtable.c2
-rw-r--r--mm/early_ioremap.c1
-rw-r--r--mm/fadvise.c5
-rw-r--r--mm/filemap.c84
-rw-r--r--mm/folio-compat.c13
-rw-r--r--mm/gup.c637
-rw-r--r--mm/highmem.c9
-rw-r--r--mm/hmm.c3
-rw-r--r--mm/huge_memory.c219
-rw-r--r--mm/hugetlb.c49
-rw-r--r--mm/hugetlb_vmemmap.c68
-rw-r--r--mm/hwpoison-inject.c7
-rw-r--r--mm/init-mm.c4
-rw-r--r--mm/internal.h136
-rw-r--r--mm/kasan/report.c10
-rw-r--r--mm/kfence/Makefile2
-rw-r--r--mm/kfence/core.c144
-rw-r--r--mm/kfence/kfence_test.c11
-rw-r--r--mm/khugepaged.c52
-rw-r--r--mm/kmemleak.c13
-rw-r--r--mm/ksm.c38
-rw-r--r--mm/list_lru.c422
-rw-r--r--mm/maccess.c125
-rw-r--r--mm/madvise.c115
-rw-r--r--mm/memblock.c10
-rw-r--r--mm/memcontrol.c542
-rw-r--r--mm/memfd.c40
-rw-r--r--mm/memory-failure.c162
-rw-r--r--mm/memory.c153
-rw-r--r--mm/memory_hotplug.c145
-rw-r--r--mm/mempolicy.c31
-rw-r--r--mm/memremap.c68
-rw-r--r--mm/migrate.c986
-rw-r--r--mm/migrate_device.c773
-rw-r--r--mm/mlock.c641
-rw-r--r--mm/mmap.c50
-rw-r--r--mm/mmzone.c14
-rw-r--r--mm/mprotect.c17
-rw-r--r--mm/mremap.c4
-rw-r--r--mm/oom_kill.c5
-rw-r--r--mm/page-writeback.c48
-rw-r--r--mm/page_alloc.c414
-rw-r--r--mm/page_idle.c30
-rw-r--r--mm/page_io.c32
-rw-r--r--mm/page_isolation.c2
-rw-r--r--mm/page_table_check.c65
-rw-r--r--mm/page_vma_mapped.c58
-rw-r--r--mm/percpu-stats.c2
-rw-r--r--mm/ptdump.c16
-rw-r--r--mm/readahead.c232
-rw-r--r--mm/rmap.c597
-rw-r--r--mm/secretmem.c2
-rw-r--r--mm/shmem.c48
-rw-r--r--mm/slab.c39
-rw-r--r--mm/slab.h25
-rw-r--r--mm/slab_common.c2
-rw-r--r--mm/slob.c8
-rw-r--r--mm/slub.c172
-rw-r--r--mm/sparse-vmemmap.c70
-rw-r--r--mm/sparse.c2
-rw-r--r--mm/swap.c198
-rw-r--r--mm/swap_cgroup.c4
-rw-r--r--mm/swap_state.c4
-rw-r--r--mm/swapfile.c1
-rw-r--r--mm/truncate.c153
-rw-r--r--mm/usercopy.c39
-rw-r--r--mm/userfaultfd.c17
-rw-r--r--mm/util.c90
-rw-r--r--mm/vmalloc.c102
-rw-r--r--mm/vmscan.c445
-rw-r--r--mm/vmstat.c19
-rw-r--r--mm/workingset.c32
-rw-r--r--mm/zswap.c15
-rw-r--r--net/6lowpan/core.c1
-rw-r--r--net/8021q/vlan.h2
-rw-r--r--net/8021q/vlan_dev.c7
-rw-r--r--net/8021q/vlan_netlink.c7
-rw-r--r--net/8021q/vlanproc.c2
-rw-r--r--net/9p/trans_xen.c14
-rw-r--r--net/Kconfig13
-rw-r--r--net/ax25/af_ax25.c47
-rw-r--r--net/ax25/ax25_dev.c28
-rw-r--r--net/ax25/ax25_route.c18
-rw-r--r--net/ax25/ax25_subr.c20
-rw-r--r--net/batman-adv/bat_iv_ogm.c2
-rw-r--r--net/batman-adv/bat_v_elp.c2
-rw-r--r--net/batman-adv/bat_v_ogm.c2
-rw-r--r--net/batman-adv/bridge_loop_avoidance.c3
-rw-r--r--net/batman-adv/distributed-arp-table.c2
-rw-r--r--net/batman-adv/gateway_client.c1
-rw-r--r--net/batman-adv/hard-interface.c35
-rw-r--r--net/batman-adv/main.c2
-rw-r--r--net/batman-adv/main.h2
-rw-r--r--net/batman-adv/multicast.c3
-rw-r--r--net/batman-adv/network-coding.c2
-rw-r--r--net/batman-adv/originator.c2
-rw-r--r--net/batman-adv/send.c2
-rw-r--r--net/batman-adv/soft-interface.c2
-rw-r--r--net/batman-adv/tp_meter.c2
-rw-r--r--net/batman-adv/translation-table.c2
-rw-r--r--net/batman-adv/tvlv.c2
-rw-r--r--net/bluetooth/6lowpan.c3
-rw-r--r--net/bluetooth/af_bluetooth.c4
-rw-r--r--net/bluetooth/bnep/core.c2
-rw-r--r--net/bluetooth/eir.h20
-rw-r--r--net/bluetooth/hci_conn.c3
-rw-r--r--net/bluetooth/hci_core.c6
-rw-r--r--net/bluetooth/hci_event.c111
-rw-r--r--net/bluetooth/hci_sync.c104
-rw-r--r--net/bluetooth/l2cap_core.c2
-rw-r--r--net/bluetooth/mgmt.c282
-rw-r--r--net/bluetooth/mgmt_util.c3
-rw-r--r--net/bluetooth/msft.c183
-rw-r--r--net/bpf/bpf_dummy_struct_ops.c6
-rw-r--r--net/bpf/test_run.c629
-rw-r--r--net/bpfilter/bpfilter_kern.c2
-rw-r--r--net/bridge/Makefile2
-rw-r--r--net/bridge/br.c20
-rw-r--r--net/bridge/br_arp_nd_proxy.c4
-rw-r--r--net/bridge/br_forward.c2
-rw-r--r--net/bridge/br_input.c28
-rw-r--r--net/bridge/br_mst.c357
-rw-r--r--net/bridge/br_multicast.c4
-rw-r--r--net/bridge/br_netlink.c50
-rw-r--r--net/bridge/br_private.h67
-rw-r--r--net/bridge/br_stp.c6
-rw-r--r--net/bridge/br_switchdev.c141
-rw-r--r--net/bridge/br_vlan.c146
-rw-r--r--net/bridge/br_vlan_options.c20
-rw-r--r--net/bridge/netfilter/nf_conntrack_bridge.c7
-rw-r--r--net/bridge/netfilter/nft_meta_bridge.c5
-rw-r--r--net/bridge/netfilter/nft_reject_bridge.c9
-rw-r--r--net/caif/caif_dev.c2
-rw-r--r--net/caif/chnl_net.c2
-rw-r--r--net/can/af_can.c2
-rw-r--r--net/can/gw.c25
-rw-r--r--net/can/isotp.c332
-rw-r--r--net/can/j1939/transport.c2
-rw-r--r--net/ceph/ceph_common.c7
-rw-r--r--net/ceph/messenger.c4
-rw-r--r--net/ceph/messenger_v1.c54
-rw-r--r--net/ceph/messenger_v2.c242
-rw-r--r--net/core/bpf_sk_storage.c23
-rw-r--r--net/core/dev.c687
-rw-r--r--net/core/devlink.c234
-rw-r--r--net/core/drop_monitor.c113
-rw-r--r--net/core/filter.c453
-rw-r--r--net/core/flow_dissector.c18
-rw-r--r--net/core/gro.c41
-rw-r--r--net/core/gro_cells.c38
-rw-r--r--net/core/link_watch.c6
-rw-r--r--net/core/neighbour.c24
-rw-r--r--net/core/net-procfs.c38
-rw-r--r--net/core/net-sysfs.c8
-rw-r--r--net/core/net_namespace.c20
-rw-r--r--net/core/page_pool.c102
-rw-r--r--net/core/ptp_classifier.c12
-rw-r--r--net/core/rtnetlink.c553
-rw-r--r--net/core/skbuff.c72
-rw-r--r--net/core/skmsg.c19
-rw-r--r--net/core/sock.c30
-rw-r--r--net/core/sock_map.c77
-rw-r--r--net/core/sysctl_net_core.c20
-rw-r--r--net/core/utils.c4
-rw-r--r--net/core/xdp.c82
-rw-r--r--net/dcb/dcbnl.c44
-rw-r--r--net/dccp/dccp.h5
-rw-r--r--net/dccp/ipv4.c6
-rw-r--r--net/dccp/ipv6.c6
-rw-r--r--net/dccp/minisocks.c1
-rw-r--r--net/decnet/dn_nsp_out.c3
-rw-r--r--net/dsa/dsa.c101
-rw-r--r--net/dsa/dsa2.c181
-rw-r--r--net/dsa/dsa_priv.h115
-rw-r--r--net/dsa/master.c11
-rw-r--r--net/dsa/port.c538
-rw-r--r--net/dsa/slave.c797
-rw-r--r--net/dsa/switch.c426
-rw-r--r--net/dsa/tag_8021q.c323
-rw-r--r--net/dsa/tag_dsa.c19
-rw-r--r--net/dsa/tag_lan9303.c21
-rw-r--r--net/dsa/tag_ocelot_8021q.c11
-rw-r--r--net/dsa/tag_qca.c85
-rw-r--r--net/dsa/tag_rtl8_4.c152
-rw-r--r--net/dsa/tag_sja1105.c28
-rw-r--r--net/ethtool/netlink.h2
-rw-r--r--net/ethtool/rings.c30
-rw-r--r--net/hsr/hsr_debugfs.c40
-rw-r--r--net/hsr/hsr_device.c12
-rw-r--r--net/hsr/hsr_forward.c7
-rw-r--r--net/hsr/hsr_framereg.c209
-rw-r--r--net/hsr/hsr_framereg.h14
-rw-r--r--net/hsr/hsr_main.h30
-rw-r--r--net/hsr/hsr_netlink.c4
-rw-r--r--net/ieee802154/6lowpan/core.c1
-rw-r--r--net/ieee802154/6lowpan/reassembly.c1
-rw-r--r--net/ieee802154/nl-phy.c4
-rw-r--r--net/ieee802154/nl802154.c8
-rw-r--r--net/ipv4/af_inet.c5
-rw-r--r--net/ipv4/arp.c11
-rw-r--r--net/ipv4/bpf_tcp_ca.c28
-rw-r--r--net/ipv4/devinet.c7
-rw-r--r--net/ipv4/esp4.c7
-rw-r--r--net/ipv4/esp4_offload.c6
-rw-r--r--net/ipv4/fib_frontend.c45
-rw-r--r--net/ipv4/fib_lookup.h10
-rw-r--r--net/ipv4/fib_rules.c19
-rw-r--r--net/ipv4/fib_semantics.c66
-rw-r--r--net/ipv4/fib_trie.c87
-rw-r--r--net/ipv4/icmp.c91
-rw-r--r--net/ipv4/inet_connection_sock.c8
-rw-r--r--net/ipv4/inet_fragment.c1
-rw-r--r--net/ipv4/inet_hashtables.c53
-rw-r--r--net/ipv4/inet_timewait_sock.c75
-rw-r--r--net/ipv4/ip_forward.c2
-rw-r--r--net/ipv4/ip_fragment.c1
-rw-r--r--net/ipv4/ip_input.c32
-rw-r--r--net/ipv4/ip_options.c31
-rw-r--r--net/ipv4/ip_output.c48
-rw-r--r--net/ipv4/ipmr.c22
-rw-r--r--net/ipv4/netfilter/Kconfig4
-rw-r--r--net/ipv4/netfilter/nf_nat_h323.c8
-rw-r--r--net/ipv4/netfilter/nf_nat_pptp.c24
-rw-r--r--net/ipv4/netfilter/nft_dup_ipv4.c1
-rw-r--r--net/ipv4/netfilter/nft_fib_ipv4.c2
-rw-r--r--net/ipv4/netfilter/nft_reject_ipv4.c1
-rw-r--r--net/ipv4/nexthop.c12
-rw-r--r--net/ipv4/ping.c11
-rw-r--r--net/ipv4/proc.c4
-rw-r--r--net/ipv4/raw.c5
-rw-r--r--net/ipv4/route.c65
-rw-r--r--net/ipv4/sysctl_net_ipv4.c27
-rw-r--r--net/ipv4/tcp.c114
-rw-r--r--net/ipv4/tcp_bbr.c18
-rw-r--r--net/ipv4/tcp_bpf.c14
-rw-r--r--net/ipv4/tcp_cong.c2
-rw-r--r--net/ipv4/tcp_cubic.c17
-rw-r--r--net/ipv4/tcp_dctcp.c18
-rw-r--r--net/ipv4/tcp_input.c55
-rw-r--r--net/ipv4/tcp_ipv4.c174
-rw-r--r--net/ipv4/tcp_minisocks.c7
-rw-r--r--net/ipv4/tcp_output.c58
-rw-r--r--net/ipv4/udp.c22
-rw-r--r--net/ipv4/udp_tunnel_nic.c2
-rw-r--r--net/ipv4/xfrm4_policy.c4
-rw-r--r--net/ipv6/addrconf.c275
-rw-r--r--net/ipv6/af_inet6.c24
-rw-r--r--net/ipv6/esp6.c10
-rw-r--r--net/ipv6/esp6_offload.c6
-rw-r--r--net/ipv6/exthdrs.c8
-rw-r--r--net/ipv6/fib6_rules.c30
-rw-r--r--net/ipv6/icmp.c62
-rw-r--r--net/ipv6/inet6_hashtables.c5
-rw-r--r--net/ipv6/ioam6.c19
-rw-r--r--net/ipv6/ioam6_iptunnel.c59
-rw-r--r--net/ipv6/ip6_fib.c23
-rw-r--r--net/ipv6/ip6_flowlabel.c4
-rw-r--r--net/ipv6/ip6_input.c3
-rw-r--r--net/ipv6/ip6_offload.c7
-rw-r--r--net/ipv6/ip6_output.c129
-rw-r--r--net/ipv6/ip6_tunnel.c16
-rw-r--r--net/ipv6/ip6mr.c55
-rw-r--r--net/ipv6/ipv6_sockglue.c6
-rw-r--r--net/ipv6/mcast.c34
-rw-r--r--net/ipv6/ndisc.c55
-rw-r--r--net/ipv6/netfilter.c5
-rw-r--r--net/ipv6/netfilter/Kconfig4
-rw-r--r--net/ipv6/netfilter/Makefile3
-rw-r--r--net/ipv6/netfilter/nf_conntrack_reasm.c1
-rw-r--r--net/ipv6/netfilter/nf_flow_table_ipv6.c0
-rw-r--r--net/ipv6/netfilter/nft_dup_ipv6.c1
-rw-r--r--net/ipv6/netfilter/nft_fib_ipv6.c2
-rw-r--r--net/ipv6/netfilter/nft_reject_ipv6.c1
-rw-r--r--net/ipv6/ping.c29
-rw-r--r--net/ipv6/reassembly.c1
-rw-r--r--net/ipv6/route.c81
-rw-r--r--net/ipv6/tcp_ipv6.c104
-rw-r--r--net/ipv6/udp.c114
-rw-r--r--net/ipv6/xfrm6_output.c16
-rw-r--r--net/ipv6/xfrm6_policy.c4
-rw-r--r--net/iucv/iucv.c2
-rw-r--r--net/key/af_key.c4
-rw-r--r--net/l3mdev/l3mdev.c43
-rw-r--r--net/llc/af_llc.c8
-rw-r--r--net/mac80211/Makefile3
-rw-r--r--net/mac80211/agg-rx.c20
-rw-r--r--net/mac80211/agg-tx.c10
-rw-r--r--net/mac80211/airtime.c15
-rw-r--r--net/mac80211/cfg.c139
-rw-r--r--net/mac80211/chan.c5
-rw-r--r--net/mac80211/debugfs.c2
-rw-r--r--net/mac80211/debugfs_key.c2
-rw-r--r--net/mac80211/debugfs_netdev.c4
-rw-r--r--net/mac80211/eht.c76
-rw-r--r--net/mac80211/ieee80211_i.h40
-rw-r--r--net/mac80211/main.c14
-rw-r--r--net/mac80211/mesh.c9
-rw-r--r--net/mac80211/mlme.c414
-rw-r--r--net/mac80211/rc80211_minstrel_ht.c2
-rw-r--r--net/mac80211/rx.c16
-rw-r--r--net/mac80211/sta_info.c3
-rw-r--r--net/mac80211/status.c14
-rw-r--r--net/mac80211/tx.c24
-rw-r--r--net/mac80211/util.c299
-rw-r--r--net/mac80211/vht.c38
-rw-r--r--net/mctp/af_mctp.c189
-rw-r--r--net/mctp/device.c34
-rw-r--r--net/mctp/neigh.c2
-rw-r--r--net/mctp/route.c160
-rw-r--r--net/mctp/test/route-test.c157
-rw-r--r--net/mctp/test/utils.c1
-rw-r--r--net/mpls/af_mpls.c2
-rw-r--r--net/mptcp/mib.c6
-rw-r--r--net/mptcp/mib.h6
-rw-r--r--net/mptcp/options.c82
-rw-r--r--net/mptcp/pm.c19
-rw-r--r--net/mptcp/pm_netlink.c248
-rw-r--r--net/mptcp/protocol.c23
-rw-r--r--net/mptcp/protocol.h38
-rw-r--r--net/mptcp/sockopt.c2
-rw-r--r--net/mptcp/subflow.c112
-rw-r--r--net/netfilter/Makefile5
-rw-r--r--net/netfilter/core.c8
-rw-r--r--net/netfilter/ipvs/ip_vs_xmit.c6
-rw-r--r--net/netfilter/nf_conntrack_acct.c19
-rw-r--r--net/netfilter/nf_conntrack_bpf.c258
-rw-r--r--net/netfilter/nf_conntrack_core.c198
-rw-r--r--net/netfilter/nf_conntrack_ecache.c47
-rw-r--r--net/netfilter/nf_conntrack_extend.c132
-rw-r--r--net/netfilter/nf_conntrack_helper.c21
-rw-r--r--net/netfilter/nf_conntrack_labels.c20
-rw-r--r--net/netfilter/nf_conntrack_netbios_ns.c5
-rw-r--r--net/netfilter/nf_conntrack_netlink.c39
-rw-r--r--net/netfilter/nf_conntrack_pptp.c60
-rw-r--r--net/netfilter/nf_conntrack_proto_sctp.c9
-rw-r--r--net/netfilter/nf_conntrack_proto_tcp.c59
-rw-r--r--net/netfilter/nf_conntrack_seqadj.c16
-rw-r--r--net/netfilter/nf_conntrack_timeout.c50
-rw-r--r--net/netfilter/nf_conntrack_timestamp.c20
-rw-r--r--net/netfilter/nf_dup_netdev.c2
-rw-r--r--net/netfilter/nf_flow_table_core.c30
-rw-r--r--net/netfilter/nf_flow_table_inet.c17
-rw-r--r--net/netfilter/nf_flow_table_ip.c84
-rw-r--r--net/netfilter/nf_flow_table_offload.c39
-rw-r--r--net/netfilter/nf_nat_core.c71
-rw-r--r--net/netfilter/nf_queue.c36
-rw-r--r--net/netfilter/nf_synproxy_core.c24
-rw-r--r--net/netfilter/nf_tables_api.c144
-rw-r--r--net/netfilter/nf_tables_core.c18
-rw-r--r--net/netfilter/nf_tables_offload.c3
-rw-r--r--net/netfilter/nfnetlink_cttimeout.c11
-rw-r--r--net/netfilter/nfnetlink_log.c6
-rw-r--r--net/netfilter/nfnetlink_queue.c33
-rw-r--r--net/netfilter/nft_bitwise.c24
-rw-r--r--net/netfilter/nft_byteorder.c11
-rw-r--r--net/netfilter/nft_cmp.c105
-rw-r--r--net/netfilter/nft_compat.c10
-rw-r--r--net/netfilter/nft_connlimit.c12
-rw-r--r--net/netfilter/nft_counter.c1
-rw-r--r--net/netfilter/nft_ct.c56
-rw-r--r--net/netfilter/nft_dup_netdev.c7
-rw-r--r--net/netfilter/nft_dynset.c1
-rw-r--r--net/netfilter/nft_exthdr.c131
-rw-r--r--net/netfilter/nft_fib.c42
-rw-r--r--net/netfilter/nft_fib_inet.c1
-rw-r--r--net/netfilter/nft_fib_netdev.c1
-rw-r--r--net/netfilter/nft_flow_offload.c14
-rw-r--r--net/netfilter/nft_fwd_netdev.c10
-rw-r--r--net/netfilter/nft_hash.c36
-rw-r--r--net/netfilter/nft_immediate.c24
-rw-r--r--net/netfilter/nft_last.c1
-rw-r--r--net/netfilter/nft_limit.c20
-rw-r--r--net/netfilter/nft_log.c1
-rw-r--r--net/netfilter/nft_lookup.c12
-rw-r--r--net/netfilter/nft_masq.c3
-rw-r--r--net/netfilter/nft_meta.c19
-rw-r--r--net/netfilter/nft_nat.c2
-rw-r--r--net/netfilter/nft_numgen.c22
-rw-r--r--net/netfilter/nft_objref.c2
-rw-r--r--net/netfilter/nft_osf.c25
-rw-r--r--net/netfilter/nft_payload.c21
-rw-r--r--net/netfilter/nft_queue.c2
-rw-r--r--net/netfilter/nft_quota.c1
-rw-r--r--net/netfilter/nft_range.c1
-rw-r--r--net/netfilter/nft_redir.c3
-rw-r--r--net/netfilter/nft_reject_inet.c1
-rw-r--r--net/netfilter/nft_reject_netdev.c1
-rw-r--r--net/netfilter/nft_rt.c1
-rw-r--r--net/netfilter/nft_socket.c28
-rw-r--r--net/netfilter/nft_synproxy.c5
-rw-r--r--net/netfilter/nft_tproxy.c1
-rw-r--r--net/netfilter/nft_tunnel.c28
-rw-r--r--net/netfilter/nft_xfrm.c28
-rw-r--r--net/netfilter/xt_socket.c4
-rw-r--r--net/netlabel/netlabel_kapi.c2
-rw-r--r--net/netlink/af_netlink.c2
-rw-r--r--net/nfc/llcp.h1
-rw-r--r--net/nfc/llcp_core.c9
-rw-r--r--net/nfc/llcp_sock.c49
-rw-r--r--net/openvswitch/actions.c46
-rw-r--r--net/openvswitch/conntrack.c118
-rw-r--r--net/openvswitch/datapath.c18
-rw-r--r--net/openvswitch/datapath.h2
-rw-r--r--net/openvswitch/flow.c143
-rw-r--r--net/openvswitch/flow.h14
-rw-r--r--net/openvswitch/flow_netlink.c37
-rw-r--r--net/openvswitch/vport.c2
-rw-r--r--net/packet/af_packet.c25
-rw-r--r--net/phonet/af_phonet.c8
-rw-r--r--net/rfkill/core.c48
-rw-r--r--net/rxrpc/call_event.c8
-rw-r--r--net/rxrpc/output.c2
-rw-r--r--net/sched/act_api.c17
-rw-r--r--net/sched/act_bpf.c2
-rw-r--r--net/sched/act_ct.c146
-rw-r--r--net/sched/act_police.c62
-rw-r--r--net/sched/act_vlan.c13
-rw-r--r--net/sched/cls_api.c60
-rw-r--r--net/sched/cls_bpf.c2
-rw-r--r--net/sched/cls_flower.c116
-rw-r--r--net/sched/sch_api.c24
-rw-r--r--net/sched/sch_generic.c29
-rw-r--r--net/sched/sch_htb.c20
-rw-r--r--net/sctp/diag.c9
-rw-r--r--net/sctp/sm_statefuns.c8
-rw-r--r--net/smc/Makefile1
-rw-r--r--net/smc/af_smc.c441
-rw-r--r--net/smc/smc.h37
-rw-r--r--net/smc/smc_cdc.c24
-rw-r--r--net/smc/smc_core.c7
-rw-r--r--net/smc/smc_diag.c2
-rw-r--r--net/smc/smc_netlink.c15
-rw-r--r--net/smc/smc_pnet.c53
-rw-r--r--net/smc/smc_pnet.h2
-rw-r--r--net/smc/smc_sysctl.c65
-rw-r--r--net/smc/smc_sysctl.h33
-rw-r--r--net/smc/smc_tx.c154
-rw-r--r--net/smc/smc_tx.h3
-rw-r--r--net/socket.c6
-rw-r--r--net/sunrpc/auth_gss/auth_gss.c10
-rw-r--r--net/sunrpc/auth_gss/gss_generic_token.c6
-rw-r--r--net/sunrpc/clnt.c5
-rw-r--r--net/sunrpc/rpc_pipe.c6
-rw-r--r--net/sunrpc/svc.c50
-rw-r--r--net/sunrpc/svc_xprt.c72
-rw-r--r--net/sunrpc/svcauth.c2
-rw-r--r--net/sunrpc/svcauth_unix.c60
-rw-r--r--net/sunrpc/sysfs.c52
-rw-r--r--net/sunrpc/xprt.c4
-rw-r--r--net/sunrpc/xprtrdma/backchannel.c4
-rw-r--r--net/sunrpc/xprtrdma/frwr_ops.c4
-rw-r--r--net/sunrpc/xprtrdma/rpc_rdma.c4
-rw-r--r--net/sunrpc/xprtrdma/svc_rdma_backchannel.c2
-rw-r--r--net/sunrpc/xprtrdma/transport.c4
-rw-r--r--net/sunrpc/xprtrdma/verbs.c26
-rw-r--r--net/sunrpc/xprtsock.c9
-rw-r--r--net/switchdev/switchdev.c232
-rw-r--r--net/tipc/bearer.c14
-rw-r--r--net/tipc/crypto.c2
-rw-r--r--net/tipc/link.c14
-rw-r--r--net/tipc/monitor.c2
-rw-r--r--net/tipc/msg.h23
-rw-r--r--net/tipc/name_distr.c2
-rw-r--r--net/tipc/name_table.c2
-rw-r--r--net/tipc/node.c13
-rw-r--r--net/tipc/socket.c5
-rw-r--r--net/tls/tls_device.c62
-rw-r--r--net/tls/tls_main.c15
-rw-r--r--net/tls/tls_sw.c3
-rw-r--r--net/unix/af_unix.c272
-rw-r--r--net/vmw_vsock/af_vsock.c10
-rw-r--r--net/vmw_vsock/virtio_transport.c7
-rw-r--r--net/vmw_vsock/vmci_transport.c5
-rw-r--r--net/wireless/Makefile2
-rw-r--r--net/wireless/chan.c91
-rw-r--r--net/wireless/core.c17
-rw-r--r--net/wireless/nl80211.c152
-rw-r--r--net/wireless/pmsr.c4
-rw-r--r--net/wireless/reg.c6
-rw-r--r--net/wireless/scan.c9
-rw-r--r--net/wireless/util.c141
-rw-r--r--net/xdp/xsk.c82
-rw-r--r--net/xdp/xsk_buff_pool.c7
-rw-r--r--net/xdp/xsk_queue.h19
-rw-r--r--net/xfrm/xfrm_device.c22
-rw-r--r--net/xfrm/xfrm_interface.c9
-rw-r--r--net/xfrm/xfrm_policy.c24
-rw-r--r--net/xfrm/xfrm_state.c29
-rw-r--r--net/xfrm/xfrm_user.c70
-rw-r--r--samples/Kconfig15
-rw-r--r--samples/Makefile2
-rw-r--r--samples/bpf/map_perf_test_user.c2
-rw-r--r--samples/bpf/xdp1_user.c24
-rw-r--r--samples/bpf/xdp_adjust_tail_user.c25
-rw-r--r--samples/bpf/xdp_fwd_user.c19
-rw-r--r--samples/bpf/xdp_redirect_cpu.bpf.c8
-rw-r--r--samples/bpf/xdp_redirect_cpu_user.c2
-rw-r--r--samples/bpf/xdp_redirect_map.bpf.c2
-rw-r--r--samples/bpf/xdp_redirect_map_multi.bpf.c2
-rw-r--r--samples/bpf/xdp_router_ipv4_user.c27
-rw-r--r--samples/bpf/xdp_rxq_info_user.c34
-rw-r--r--samples/bpf/xdp_sample_pkts_user.c8
-rw-r--r--samples/bpf/xdp_sample_user.c11
-rw-r--r--samples/bpf/xdp_sample_user.h2
-rw-r--r--samples/bpf/xdp_tx_iptunnel_user.c27
-rw-r--r--samples/bpf/xdpsock_ctrl_proc.c2
-rw-r--r--samples/bpf/xdpsock_user.c16
-rw-r--r--samples/bpf/xsk_fwd.c4
-rw-r--r--samples/fprobe/Makefile3
-rw-r--r--samples/fprobe/fprobe_example.c120
-rw-r--r--samples/seccomp/dropper.c9
-rw-r--r--samples/trace_events/Makefile2
-rw-r--r--samples/trace_events/trace_custom_sched.c60
-rw-r--r--samples/trace_events/trace_custom_sched.h96
-rw-r--r--samples/user_events/Makefile5
-rw-r--r--samples/user_events/example.c91
-rw-r--r--scripts/Makefile2
-rw-r--r--scripts/Makefile.clang1
-rw-r--r--scripts/Makefile.extrawarn1
-rw-r--r--scripts/Makefile.gcc-plugins2
-rwxr-xr-xscripts/atomic/fallbacks/read_acquire11
-rwxr-xr-xscripts/atomic/fallbacks/set_release7
-rwxr-xr-xscripts/bpf_doc.py124
-rwxr-xr-xscripts/checkpatch.pl31
-rw-r--r--scripts/dtc/libfdt/fdt.h4
-rw-r--r--scripts/gcc-plugins/stackleak_plugin.c29
-rw-r--r--scripts/kconfig/confdata.c25
-rw-r--r--scripts/kconfig/preprocess.c2
-rwxr-xr-xscripts/kernel-doc354
-rwxr-xr-xscripts/mkcompile_h17
-rwxr-xr-xscripts/pahole-flags.sh5
-rwxr-xr-xscripts/pahole-version.sh13
-rwxr-xr-xscripts/recordmcount.pl3
-rw-r--r--scripts/spelling.txt16
-rw-r--r--security/Kconfig.hardening10
-rw-r--r--security/device_cgroup.c2
-rw-r--r--security/integrity/Kconfig13
-rw-r--r--security/integrity/Makefile1
-rw-r--r--security/integrity/digsig.c15
-rw-r--r--security/integrity/digsig_asymmetric.c15
-rw-r--r--security/integrity/evm/evm_main.c2
-rw-r--r--security/integrity/ima/ima_api.c12
-rw-r--r--security/integrity/ima/ima_fs.c33
-rw-r--r--security/integrity/ima/ima_init.c5
-rw-r--r--security/integrity/ima/ima_main.c66
-rw-r--r--security/integrity/ima/ima_policy.c13
-rw-r--r--security/integrity/ima/ima_template.c10
-rw-r--r--security/integrity/ima/ima_template_lib.c7
-rw-r--r--security/integrity/integrity.h31
-rw-r--r--security/integrity/integrity_audit.c2
-rw-r--r--security/integrity/platform_certs/keyring_handler.c18
-rw-r--r--security/integrity/platform_certs/keyring_handler.h5
-rw-r--r--security/integrity/platform_certs/load_uefi.c4
-rw-r--r--security/integrity/platform_certs/machine_keyring.c77
-rw-r--r--security/keys/Kconfig19
-rw-r--r--security/keys/dh.c2
-rw-r--r--security/keys/encrypted-keys/encrypted.c71
-rw-r--r--security/keys/keyctl_pkey.c14
-rw-r--r--security/keys/trusted-keys/trusted_core.c6
-rw-r--r--security/keys/trusted-keys/trusted_tee.c23
-rw-r--r--security/security.c39
-rw-r--r--security/selinux/hooks.c299
-rw-r--r--security/selinux/ibpkey.c2
-rw-r--r--security/selinux/ima.c8
-rw-r--r--security/selinux/include/policycap.h21
-rw-r--r--security/selinux/include/policycap_names.h5
-rw-r--r--security/selinux/include/security.h31
-rw-r--r--security/selinux/netnode.c9
-rw-r--r--security/selinux/netport.c2
-rw-r--r--security/selinux/nlmsgtab.c6
-rw-r--r--security/selinux/selinuxfs.c4
-rw-r--r--security/selinux/ss/avtab.c6
-rw-r--r--security/selinux/ss/conditional.c5
-rw-r--r--security/selinux/ss/ebitmap.c1
-rw-r--r--security/selinux/ss/ebitmap.h6
-rw-r--r--security/selinux/ss/mls.c1
-rw-r--r--security/selinux/ss/policydb.c4
-rw-r--r--security/selinux/ss/services.c10
-rw-r--r--security/selinux/ss/sidtab.c4
-rw-r--r--security/selinux/xfrm.c2
-rw-r--r--security/smack/smack_lsm.c2
-rw-r--r--security/tomoyo/audit.c2
-rw-r--r--security/tomoyo/common.c19
-rw-r--r--security/tomoyo/common.h1
-rw-r--r--security/tomoyo/load_policy.c4
-rw-r--r--sound/core/Kconfig2
-rw-r--r--sound/core/memalloc.c15
-rw-r--r--sound/core/oss/pcm_oss.c40
-rw-r--r--sound/core/oss/pcm_plugin.c5
-rw-r--r--sound/core/pcm.c2
-rw-r--r--sound/core/pcm_lib.c4
-rw-r--r--sound/core/pcm_memory.c11
-rw-r--r--sound/core/pcm_native.c110
-rw-r--r--sound/core/seq/oss/seq_oss_init.c5
-rw-r--r--sound/firewire/fcp.c4
-rw-r--r--sound/hda/ext/hdac_ext_controller.c31
-rw-r--r--sound/hda/hdac_i915.c4
-rw-r--r--sound/hda/intel-dsp-config.c36
-rw-r--r--sound/hda/intel-nhlt.c22
-rw-r--r--sound/hda/intel-sdw-acpi.c7
-rw-r--r--sound/mips/snd-n64.c9
-rw-r--r--sound/pci/Kconfig4
-rw-r--r--sound/pci/ac97/ac97_codec.c4
-rw-r--r--sound/pci/ca0106/ca0106.h18
-rw-r--r--sound/pci/ca0106/ca0106_main.c70
-rw-r--r--sound/pci/ca0106/ca0106_mixer.c16
-rw-r--r--sound/pci/cmipci.c3
-rw-r--r--sound/pci/echoaudio/midi.c2
-rw-r--r--sound/pci/hda/Kconfig19
-rw-r--r--sound/pci/hda/cs35l41_hda_spi.c4
-rw-r--r--sound/pci/hda/hda_auto_parser.c2
-rw-r--r--sound/pci/hda/hda_codec.c98
-rw-r--r--sound/pci/hda/hda_generic.c17
-rw-r--r--sound/pci/hda/hda_generic.h3
-rw-r--r--sound/pci/hda/hda_intel.c29
-rw-r--r--sound/pci/hda/hda_local.h2
-rw-r--r--sound/pci/hda/hda_tegra.c33
-rw-r--r--sound/pci/hda/patch_hdmi.c275
-rw-r--r--sound/pci/hda/patch_realtek.c141
-rw-r--r--sound/pci/lola/lola_mixer.c2
-rw-r--r--sound/soc/amd/Kconfig1
-rw-r--r--sound/soc/amd/acp-config.c9
-rw-r--r--sound/soc/amd/acp-pcm-dma.c11
-rw-r--r--sound/soc/amd/acp/Kconfig10
-rw-r--r--sound/soc/amd/acp/Makefile4
-rw-r--r--sound/soc/amd/acp/acp-legacy-mach.c38
-rw-r--r--sound/soc/amd/acp/acp-mach-common.c54
-rw-r--r--sound/soc/amd/acp/acp-mach.h1
-rw-r--r--sound/soc/amd/acp/acp-pci.c160
-rw-r--r--sound/soc/amd/acp/acp-pdm.c193
-rw-r--r--sound/soc/amd/acp/acp-renoir.c189
-rw-r--r--sound/soc/amd/acp/acp-sof-mach.c18
-rw-r--r--sound/soc/amd/acp/amd.h23
-rw-r--r--sound/soc/amd/acp/chip_offset_byte.h26
-rw-r--r--sound/soc/amd/mach-config.h1
-rw-r--r--sound/soc/amd/raven/acp3x-pcm-dma.c11
-rw-r--r--sound/soc/amd/raven/acp3x.h2
-rw-r--r--sound/soc/amd/renoir/acp3x-pdm-dma.c10
-rw-r--r--sound/soc/amd/renoir/rn-pci-acp3x.c7
-rw-r--r--sound/soc/amd/renoir/rn_acp3x.h3
-rw-r--r--sound/soc/amd/vangogh/acp5x-i2s.c26
-rw-r--r--sound/soc/amd/vangogh/acp5x-mach.c37
-rw-r--r--sound/soc/amd/vangogh/acp5x-pcm-dma.c78
-rw-r--r--sound/soc/amd/vangogh/acp5x.h31
-rw-r--r--sound/soc/amd/vangogh/pci-acp5x.c4
-rw-r--r--sound/soc/atmel/Kconfig16
-rw-r--r--sound/soc/atmel/Makefile2
-rw-r--r--sound/soc/atmel/atmel_ssc_dai.c5
-rw-r--r--sound/soc/atmel/mchp-pdmc.c1083
-rw-r--r--sound/soc/atmel/mchp-spdifrx.c2
-rw-r--r--sound/soc/atmel/mikroe-proto.c20
-rw-r--r--sound/soc/atmel/sam9g20_wm8731.c1
-rw-r--r--sound/soc/atmel/sam9x5_wm8731.c13
-rw-r--r--sound/soc/codecs/Kconfig39
-rw-r--r--sound/soc/codecs/Makefile6
-rw-r--r--sound/soc/codecs/adau1761-spi.c3
-rw-r--r--sound/soc/codecs/adau1781-spi.c3
-rw-r--r--sound/soc/codecs/ak4613.c11
-rw-r--r--sound/soc/codecs/aw8738.c104
-rw-r--r--sound/soc/codecs/bt-sco.c8
-rw-r--r--sound/soc/codecs/cpcap.c2
-rw-r--r--sound/soc/codecs/cs35l41-spi.c4
-rw-r--r--sound/soc/codecs/cs35l41.c16
-rw-r--r--sound/soc/codecs/cs4265.c3
-rw-r--r--sound/soc/codecs/cs42l42.c179
-rw-r--r--sound/soc/codecs/cs42l42.h16
-rw-r--r--sound/soc/codecs/cs42l51-i2c.c4
-rw-r--r--sound/soc/codecs/cs42l51.c11
-rw-r--r--sound/soc/codecs/cs42l51.h2
-rw-r--r--sound/soc/codecs/es7134.c2
-rw-r--r--sound/soc/codecs/es7241.c30
-rw-r--r--sound/soc/codecs/es8316.c4
-rw-r--r--sound/soc/codecs/es8328.c16
-rw-r--r--sound/soc/codecs/hdac_hda.c9
-rw-r--r--sound/soc/codecs/hdmi-codec.c2
-rw-r--r--sound/soc/codecs/inno_rk3036.c6
-rw-r--r--sound/soc/codecs/isabelle.c6
-rw-r--r--sound/soc/codecs/lm49453.c10
-rw-r--r--sound/soc/codecs/lpass-macro-common.c67
-rw-r--r--sound/soc/codecs/lpass-macro-common.h17
-rw-r--r--sound/soc/codecs/lpass-rx-macro.c200
-rw-r--r--sound/soc/codecs/lpass-tx-macro.c180
-rw-r--r--sound/soc/codecs/lpass-va-macro.c120
-rw-r--r--sound/soc/codecs/lpass-wsa-macro.c159
-rw-r--r--sound/soc/codecs/max9759.c3
-rw-r--r--sound/soc/codecs/max98088.c24
-rw-r--r--sound/soc/codecs/max98095.c36
-rw-r--r--sound/soc/codecs/max98371.c4
-rw-r--r--sound/soc/codecs/max98390.c10
-rw-r--r--sound/soc/codecs/max98390.h2
-rw-r--r--sound/soc/codecs/max9850.c8
-rw-r--r--sound/soc/codecs/max9860.c6
-rw-r--r--sound/soc/codecs/max9867.c14
-rw-r--r--sound/soc/codecs/max98925.c13
-rw-r--r--sound/soc/codecs/max98926.c4
-rw-r--r--sound/soc/codecs/max98927.c12
-rw-r--r--sound/soc/codecs/max98927.h2
-rw-r--r--sound/soc/codecs/mc13783.c15
-rw-r--r--sound/soc/codecs/ml26124.c7
-rw-r--r--sound/soc/codecs/msm8916-wcd-analog.c22
-rw-r--r--sound/soc/codecs/msm8916-wcd-digital.c5
-rw-r--r--sound/soc/codecs/nau8821.c1
-rw-r--r--sound/soc/codecs/pcm1681.c4
-rw-r--r--sound/soc/codecs/pcm186x.c19
-rw-r--r--sound/soc/codecs/pcm3060.c14
-rw-r--r--sound/soc/codecs/pcm3060.h2
-rw-r--r--sound/soc/codecs/pcm3168a-spi.c4
-rw-r--r--sound/soc/codecs/pcm3168a.c172
-rw-r--r--sound/soc/codecs/pcm512x-spi.c3
-rw-r--r--sound/soc/codecs/pcm512x.c32
-rw-r--r--sound/soc/codecs/rk817_codec.c6
-rw-r--r--sound/soc/codecs/rt1308-sdw.c73
-rw-r--r--sound/soc/codecs/rt5640.c3
-rw-r--r--sound/soc/codecs/rt5663.c2
-rw-r--r--sound/soc/codecs/rt5668.c12
-rw-r--r--sound/soc/codecs/rt5682-i2c.c15
-rw-r--r--sound/soc/codecs/rt5682.c34
-rw-r--r--sound/soc/codecs/rt5682.h2
-rw-r--r--sound/soc/codecs/rt5682s.c83
-rw-r--r--sound/soc/codecs/rt5682s.h1
-rw-r--r--sound/soc/codecs/si476x.c2
-rw-r--r--sound/soc/codecs/sti-sas.c6
-rw-r--r--sound/soc/codecs/tas2770.c7
-rw-r--r--sound/soc/codecs/tas5805m.c567
-rw-r--r--sound/soc/codecs/tlv320adc3xxx.c155
-rw-r--r--sound/soc/codecs/tlv320aic31xx.c2
-rw-r--r--sound/soc/codecs/tlv320aic32x4-spi.c4
-rw-r--r--sound/soc/codecs/tlv320aic3x-spi.c4
-rw-r--r--sound/soc/codecs/tscs42xx.c6
-rw-r--r--sound/soc/codecs/tscs454.c28
-rw-r--r--sound/soc/codecs/twl4030.c12
-rw-r--r--sound/soc/codecs/uda1334.c2
-rw-r--r--sound/soc/codecs/uda134x.c6
-rw-r--r--sound/soc/codecs/uda1380.c10
-rw-r--r--sound/soc/codecs/wcd-mbhc-v2.c26
-rw-r--r--sound/soc/codecs/wcd934x.c12
-rw-r--r--sound/soc/codecs/wcd938x-sdw.c1
-rw-r--r--sound/soc/codecs/wcd938x.c68
-rw-r--r--sound/soc/codecs/wl1273.c4
-rw-r--r--sound/soc/codecs/wm0010.c4
-rw-r--r--sound/soc/codecs/wm8350.c28
-rw-r--r--sound/soc/codecs/wm8731.c6
-rw-r--r--sound/soc/codecs/wm8804-spi.c3
-rw-r--r--sound/soc/codecs/wm8960.c13
-rw-r--r--sound/soc/codecs/wm8962.c21
-rw-r--r--sound/soc/codecs/wm8971.c5
-rw-r--r--sound/soc/codecs/wm_adsp.c165
-rw-r--r--sound/soc/codecs/wm_adsp.h1
-rw-r--r--sound/soc/codecs/wsa881x.c53
-rw-r--r--sound/soc/dwc/dwc-i2s.c17
-rw-r--r--sound/soc/fsl/fsl-asoc-card.c7
-rw-r--r--sound/soc/fsl/fsl_aud2htx.c2
-rw-r--r--sound/soc/fsl/fsl_esai.c2
-rw-r--r--sound/soc/fsl/fsl_rpmsg.c2
-rw-r--r--sound/soc/fsl/fsl_sai.c111
-rw-r--r--sound/soc/fsl/fsl_sai.h10
-rw-r--r--sound/soc/fsl/fsl_spdif.c97
-rw-r--r--sound/soc/fsl/fsl_spdif.h14
-rw-r--r--sound/soc/fsl/fsl_ssi.c2
-rw-r--r--sound/soc/fsl/imx-es8328.c1
-rw-r--r--sound/soc/fsl/imx-pcm-dma.c2
-rw-r--r--sound/soc/fsl/imx-pcm.h7
-rw-r--r--sound/soc/fsl/pcm030-audio-fabric.c11
-rw-r--r--sound/soc/generic/audio-graph-card2.c4
-rw-r--r--sound/soc/generic/simple-card-utils.c187
-rw-r--r--sound/soc/generic/simple-card.c26
-rw-r--r--sound/soc/intel/Kconfig12
-rw-r--r--sound/soc/intel/Makefile1
-rw-r--r--sound/soc/intel/atom/sst-mfld-dsp.h4
-rw-r--r--sound/soc/intel/avs/Makefile6
-rw-r--r--sound/soc/intel/avs/avs.h247
-rw-r--r--sound/soc/intel/avs/cldma.c316
-rw-r--r--sound/soc/intel/avs/cldma.h29
-rw-r--r--sound/soc/intel/avs/core.c61
-rw-r--r--sound/soc/intel/avs/dsp.c302
-rw-r--r--sound/soc/intel/avs/ipc.c382
-rw-r--r--sound/soc/intel/avs/loader.c608
-rw-r--r--sound/soc/intel/avs/messages.c695
-rw-r--r--sound/soc/intel/avs/messages.h752
-rw-r--r--sound/soc/intel/avs/registers.h75
-rw-r--r--sound/soc/intel/avs/utils.c301
-rw-r--r--sound/soc/intel/boards/Kconfig77
-rw-r--r--sound/soc/intel/boards/Makefile12
-rw-r--r--sound/soc/intel/boards/bdw-rt5650.c2
-rw-r--r--sound/soc/intel/boards/bdw-rt5677.c2
-rw-r--r--sound/soc/intel/boards/broadwell.c2
-rw-r--r--sound/soc/intel/boards/bxt_da7219_max98357a.c2
-rw-r--r--sound/soc/intel/boards/bxt_rt298.c2
-rw-r--r--sound/soc/intel/boards/bytcht_cx2072x.c2
-rw-r--r--sound/soc/intel/boards/bytcht_da7213.c2
-rw-r--r--sound/soc/intel/boards/bytcht_es8316.c4
-rw-r--r--sound/soc/intel/boards/bytcr_rt5640.c2
-rw-r--r--sound/soc/intel/boards/bytcr_rt5651.c2
-rw-r--r--sound/soc/intel/boards/bytcr_wm5102.c2
-rw-r--r--sound/soc/intel/boards/cht_bsw_max98090_ti.c4
-rw-r--r--sound/soc/intel/boards/cht_bsw_nau8824.c4
-rw-r--r--sound/soc/intel/boards/cht_bsw_rt5645.c2
-rw-r--r--sound/soc/intel/boards/cht_bsw_rt5672.c2
-rw-r--r--sound/soc/intel/boards/glk_rt5682_max98357a.c2
-rw-r--r--sound/soc/intel/boards/haswell.c2
-rw-r--r--sound/soc/intel/boards/sof_cirrus_common.c163
-rw-r--r--sound/soc/intel/boards/sof_cirrus_common.h25
-rw-r--r--sound/soc/intel/boards/sof_es8336.c134
-rw-r--r--sound/soc/intel/boards/sof_realtek_common.c107
-rw-r--r--sound/soc/intel/boards/sof_realtek_common.h4
-rw-r--r--sound/soc/intel/boards/sof_rt5682.c56
-rw-r--r--sound/soc/intel/boards/sof_sdw.c2
-rw-r--r--sound/soc/intel/boards/sof_ssp_amp.c483
-rw-r--r--sound/soc/intel/catpt/pcm.c6
-rw-r--r--sound/soc/intel/common/soc-acpi-intel-adl-match.c63
-rw-r--r--sound/soc/intel/common/soc-acpi-intel-bxt-match.c18
-rw-r--r--sound/soc/intel/common/soc-acpi-intel-byt-match.c13
-rw-r--r--sound/soc/intel/common/soc-acpi-intel-cht-match.c12
-rw-r--r--sound/soc/intel/common/soc-acpi-intel-cml-match.c23
-rw-r--r--sound/soc/intel/common/soc-acpi-intel-cnl-match.c18
-rw-r--r--sound/soc/intel/common/soc-acpi-intel-ehl-match.c1
-rw-r--r--sound/soc/intel/common/soc-acpi-intel-glk-match.c18
-rw-r--r--sound/soc/intel/common/soc-acpi-intel-hda-match.c2
-rw-r--r--sound/soc/intel/common/soc-acpi-intel-hsw-bdw-match.c5
-rw-r--r--sound/soc/intel/common/soc-acpi-intel-icl-match.c5
-rw-r--r--sound/soc/intel/common/soc-acpi-intel-jsl-match.c19
-rw-r--r--sound/soc/intel/common/soc-acpi-intel-tgl-match.c31
-rw-r--r--sound/soc/intel/skylake/skl-topology.h2
-rw-r--r--sound/soc/intel/skylake/skl.c1
-rw-r--r--sound/soc/mediatek/Kconfig2
-rw-r--r--sound/soc/mediatek/mt8183/mt8183-da7219-max98357.c23
-rw-r--r--sound/soc/mediatek/mt8183/mt8183-mt6358-ts3a227-max98357.c6
-rw-r--r--sound/soc/mediatek/mt8192/mt8192-mt6359-rt1015-rt5682.c18
-rw-r--r--sound/soc/mediatek/mt8195/mt8195-afe-clk.c282
-rw-r--r--sound/soc/mediatek/mt8195/mt8195-afe-clk.h11
-rw-r--r--sound/soc/mediatek/mt8195/mt8195-afe-pcm.c23
-rw-r--r--sound/soc/mediatek/mt8195/mt8195-mt6359-rt1019-rt5682.c4
-rw-r--r--sound/soc/mxs/mxs-saif.c5
-rw-r--r--sound/soc/mxs/mxs-sgtl5000.c3
-rw-r--r--sound/soc/pxa/Kconfig9
-rw-r--r--sound/soc/pxa/Makefile2
-rw-r--r--sound/soc/pxa/imote2.c99
-rw-r--r--sound/soc/qcom/Kconfig26
-rw-r--r--sound/soc/qcom/Makefile6
-rw-r--r--sound/soc/qcom/lpass-cdc-dma.c301
-rw-r--r--sound/soc/qcom/lpass-cpu.c253
-rw-r--r--sound/soc/qcom/lpass-lpaif-reg.h127
-rw-r--r--sound/soc/qcom/lpass-platform.c643
-rw-r--r--sound/soc/qcom/lpass-sc7280.c438
-rw-r--r--sound/soc/qcom/lpass.h142
-rw-r--r--sound/soc/qcom/qdsp6/q6apm-dai.c7
-rw-r--r--sound/soc/qcom/sc7280.c284
-rw-r--r--sound/soc/rockchip/rk3399_gru_sound.c20
-rw-r--r--sound/soc/rockchip/rockchip_i2s.c15
-rw-r--r--sound/soc/rockchip/rockchip_i2s_tdm.c2
-rw-r--r--sound/soc/samsung/i2s.c4
-rw-r--r--sound/soc/samsung/idma.c5
-rw-r--r--sound/soc/samsung/midas_wm1811.c1
-rw-r--r--sound/soc/sh/fsi.c19
-rw-r--r--sound/soc/sh/rz-ssi.c109
-rw-r--r--sound/soc/soc-acpi.c7
-rw-r--r--sound/soc/soc-compress.c5
-rw-r--r--sound/soc/soc-core.c3
-rw-r--r--sound/soc/soc-dapm.c15
-rw-r--r--sound/soc/soc-generic-dmaengine-pcm.c20
-rw-r--r--sound/soc/soc-ops.c70
-rw-r--r--sound/soc/soc-pcm.c18
-rw-r--r--sound/soc/soc-topology.c103
-rw-r--r--sound/soc/sof/Kconfig33
-rw-r--r--sound/soc/sof/Makefile18
-rw-r--r--sound/soc/sof/amd/acp-dsp-offset.h1
-rw-r--r--sound/soc/sof/amd/acp-ipc.c22
-rw-r--r--sound/soc/sof/amd/acp-loader.c9
-rw-r--r--sound/soc/sof/amd/acp-pcm.c15
-rw-r--r--sound/soc/sof/amd/acp-stream.c3
-rw-r--r--sound/soc/sof/amd/acp-trace.c38
-rw-r--r--sound/soc/sof/amd/acp.c29
-rw-r--r--sound/soc/sof/amd/acp.h9
-rw-r--r--sound/soc/sof/amd/renoir.c1
-rw-r--r--sound/soc/sof/compress.c274
-rw-r--r--sound/soc/sof/control.c545
-rw-r--r--sound/soc/sof/core.c73
-rw-r--r--sound/soc/sof/debug.c567
-rw-r--r--sound/soc/sof/imx/imx8.c4
-rw-r--r--sound/soc/sof/imx/imx8m.c3
-rw-r--r--sound/soc/sof/intel/Kconfig19
-rw-r--r--sound/soc/sof/intel/apl.c15
-rw-r--r--sound/soc/sof/intel/bdw.c2
-rw-r--r--sound/soc/sof/intel/byt.c4
-rw-r--r--sound/soc/sof/intel/cnl.c21
-rw-r--r--sound/soc/sof/intel/hda-dai.c204
-rw-r--r--sound/soc/sof/intel/hda-dsp.c20
-rw-r--r--sound/soc/sof/intel/hda-ipc.c18
-rw-r--r--sound/soc/sof/intel/hda-loader.c129
-rw-r--r--sound/soc/sof/intel/hda-pcm.c31
-rw-r--r--sound/soc/sof/intel/hda-probes.c104
-rw-r--r--sound/soc/sof/intel/hda-stream.c122
-rw-r--r--sound/soc/sof/intel/hda-trace.c23
-rw-r--r--sound/soc/sof/intel/hda.c308
-rw-r--r--sound/soc/sof/intel/hda.h90
-rw-r--r--sound/soc/sof/intel/icl.c15
-rw-r--r--sound/soc/sof/intel/pci-tgl.c2
-rw-r--r--sound/soc/sof/intel/pci-tng.c3
-rw-r--r--sound/soc/sof/intel/tgl.c15
-rw-r--r--sound/soc/sof/iomem-utils.c (renamed from sound/soc/sof/utils.c)61
-rw-r--r--sound/soc/sof/ipc.c142
-rw-r--r--sound/soc/sof/ipc3-control.c594
-rw-r--r--sound/soc/sof/ipc3-ops.h21
-rw-r--r--sound/soc/sof/ipc3-pcm.c372
-rw-r--r--sound/soc/sof/ipc3-topology.c2393
-rw-r--r--sound/soc/sof/ipc3.c45
-rw-r--r--sound/soc/sof/ops.h68
-rw-r--r--sound/soc/sof/pcm.c353
-rw-r--r--sound/soc/sof/pm.c93
-rw-r--r--sound/soc/sof/sof-audio.c546
-rw-r--r--sound/soc/sof/sof-audio.h235
-rw-r--r--sound/soc/sof/sof-client-ipc-flood-test.c396
-rw-r--r--sound/soc/sof/sof-client-ipc-msg-injector.c192
-rw-r--r--sound/soc/sof/sof-client-probes.c821
-rw-r--r--sound/soc/sof/sof-client-probes.h31
-rw-r--r--sound/soc/sof/sof-client.c469
-rw-r--r--sound/soc/sof/sof-client.h67
-rw-r--r--sound/soc/sof/sof-pci-dev.c16
-rw-r--r--sound/soc/sof/sof-priv.h221
-rw-r--r--sound/soc/sof/sof-probes.c364
-rw-r--r--sound/soc/sof/sof-probes.h38
-rw-r--r--sound/soc/sof/sof-utils.c77
-rw-r--r--sound/soc/sof/sof-utils.h19
-rw-r--r--sound/soc/sof/stream-ipc.c9
-rw-r--r--sound/soc/sof/topology.c2888
-rw-r--r--sound/soc/sof/trace.c21
-rw-r--r--sound/soc/sti/uniperif_player.c6
-rw-r--r--sound/soc/sti/uniperif_reader.c2
-rw-r--r--sound/soc/sunxi/sun4i-i2s.c68
-rw-r--r--sound/soc/tegra/tegra20_spdif.c2
-rw-r--r--sound/soc/tegra/tegra210_ahub.c146
-rw-r--r--sound/soc/tegra/tegra210_ahub.h4
-rw-r--r--sound/soc/ti/davinci-i2s.c5
-rw-r--r--sound/soc/ti/omap-dmic.c2
-rw-r--r--sound/soc/xilinx/xlnx_formatter_pcm.c52
-rw-r--r--sound/soc/xilinx/xlnx_i2s.c147
-rw-r--r--sound/sound_core.c30
-rw-r--r--sound/spi/at73c213.c31
-rw-r--r--sound/usb/implicit.c4
-rw-r--r--sound/usb/mixer.c13
-rw-r--r--sound/usb/mixer_maps.c10
-rw-r--r--sound/usb/mixer_quirks.c7
-rw-r--r--sound/usb/mixer_s1810c.c2
-rw-r--r--sound/usb/mixer_scarlett_gen2.c177
-rw-r--r--sound/usb/quirks-table.h2
-rw-r--r--sound/x86/intel_hdmi_audio.c13
-rw-r--r--tools/arch/arm64/include/uapi/asm/kvm.h6
-rw-r--r--tools/arch/x86/include/asm/cpufeatures.h4
-rw-r--r--tools/arch/x86/include/asm/insn.h2
-rw-r--r--tools/arch/x86/include/asm/msr-index.h1
-rw-r--r--tools/arch/x86/include/uapi/asm/kvm.h3
-rw-r--r--tools/arch/x86/lib/memcpy_64.S10
-rw-r--r--tools/arch/x86/lib/memset_64.S6
-rw-r--r--tools/arch/x86/lib/x86-opcode-map.txt111
-rw-r--r--tools/bpf/bpftool/Documentation/bpftool-gen.rst115
-rw-r--r--tools/bpf/bpftool/Documentation/bpftool.rst13
-rw-r--r--tools/bpf/bpftool/Documentation/common_options.rst13
-rw-r--r--tools/bpf/bpftool/Makefile34
-rw-r--r--tools/bpf/bpftool/bash-completion/bpftool18
-rw-r--r--tools/bpf/bpftool/btf.c2
-rw-r--r--tools/bpf/bpftool/cgroup.c6
-rw-r--r--tools/bpf/bpftool/common.c46
-rw-r--r--tools/bpf/bpftool/feature.c141
-rw-r--r--tools/bpf/bpftool/gen.c1367
-rw-r--r--tools/bpf/bpftool/link.c3
-rw-r--r--tools/bpf/bpftool/main.c31
-rw-r--r--tools/bpf/bpftool/main.h8
-rw-r--r--tools/bpf/bpftool/map.c44
-rw-r--r--tools/bpf/bpftool/net.c2
-rw-r--r--tools/bpf/bpftool/pids.c11
-rw-r--r--tools/bpf/bpftool/prog.c52
-rw-r--r--tools/bpf/bpftool/skeleton/pid_iter.bpf.c22
-rw-r--r--tools/bpf/bpftool/skeleton/pid_iter.h2
-rw-r--r--tools/bpf/bpftool/struct_ops.c4
-rw-r--r--tools/bpf/bpftool/xlated_dumper.c5
-rw-r--r--tools/bpf/resolve_btfids/Makefile12
-rw-r--r--tools/bpf/runqslower/runqslower.bpf.c2
-rw-r--r--tools/bpf/runqslower/runqslower.c2
-rw-r--r--tools/bpf/runqslower/runqslower.h2
-rw-r--r--tools/cgroup/memcg_slabinfo.py30
-rw-r--r--tools/include/asm/barrier.h2
-rw-r--r--tools/include/linux/types.h5
-rw-r--r--tools/include/uapi/linux/bpf.h155
-rw-r--r--tools/include/uapi/linux/if_link.h1
-rw-r--r--tools/include/uapi/linux/kvm.h12
-rw-r--r--tools/include/uapi/linux/lirc.h229
-rw-r--r--tools/include/uapi/linux/perf_event.h10
-rw-r--r--tools/include/uapi/linux/prctl.h3
-rw-r--r--tools/include/uapi/sound/asound.h11
-rw-r--r--tools/lib/bpf/Makefile4
-rw-r--r--tools/lib/bpf/bpf.c22
-rw-r--r--tools/lib/bpf/bpf.h20
-rw-r--r--tools/lib/bpf/bpf_helpers.h2
-rw-r--r--tools/lib/bpf/bpf_tracing.h103
-rw-r--r--tools/lib/bpf/btf.c31
-rw-r--r--tools/lib/bpf/btf.h34
-rw-r--r--tools/lib/bpf/btf_dump.c11
-rw-r--r--tools/lib/bpf/gen_loader.c15
-rw-r--r--tools/lib/bpf/hashmap.c3
-rw-r--r--tools/lib/bpf/libbpf.c934
-rw-r--r--tools/lib/bpf/libbpf.h234
-rw-r--r--tools/lib/bpf/libbpf.map18
-rw-r--r--tools/lib/bpf/libbpf_internal.h17
-rw-r--r--tools/lib/bpf/libbpf_legacy.h26
-rw-r--r--tools/lib/bpf/libbpf_version.h2
-rw-r--r--tools/lib/bpf/netlink.c180
-rw-r--r--tools/lib/bpf/relo_core.c79
-rw-r--r--tools/lib/bpf/relo_core.h42
-rw-r--r--tools/lib/bpf/skel_internal.h253
-rw-r--r--tools/lib/bpf/xsk.c15
-rw-r--r--tools/lib/perf/include/internal/cpumap.h6
-rw-r--r--tools/lib/perf/include/perf/cpumap.h5
-rw-r--r--tools/lib/perf/include/perf/event.h2
-rw-r--r--tools/lib/perf/libperf.map1
-rw-r--r--tools/lib/perf/mmap.c98
-rw-r--r--tools/lib/perf/tests/test-cpumap.c11
-rw-r--r--tools/lib/perf/tests/test-evlist.c5
-rw-r--r--tools/lib/perf/tests/test-evsel.c5
-rw-r--r--tools/lib/subcmd/subcmd-util.h11
-rw-r--r--tools/memory-model/Documentation/explanation.txt51
-rw-r--r--tools/objtool/arch/x86/decode.c11
-rw-r--r--tools/objtool/check.c2
-rw-r--r--tools/perf/arch/nds32/Build1
-rw-r--r--tools/perf/arch/nds32/util/Build1
-rw-r--r--tools/perf/arch/nds32/util/header.c29
-rw-r--r--tools/perf/arch/x86/tests/insn-x86-dat-32.c918
-rw-r--r--tools/perf/arch/x86/tests/insn-x86-dat-64.c1426
-rw-r--r--tools/perf/arch/x86/tests/insn-x86-dat-src.c1189
-rw-r--r--tools/perf/arch/x86/util/evlist.c2
-rw-r--r--tools/perf/bench/epoll-ctl.c2
-rw-r--r--tools/perf/builtin-ftrace.c45
-rw-r--r--tools/perf/builtin-script.c2
-rw-r--r--tools/perf/builtin-trace.c23
-rw-r--r--tools/perf/tests/attr/README2
-rw-r--r--tools/perf/tests/attr/test-record-graph-default2
-rw-r--r--tools/perf/tests/attr/test-record-graph-default-aarch649
-rw-r--r--tools/perf/tests/attr/test-record-graph-fp2
-rw-r--r--tools/perf/tests/attr/test-record-graph-fp-aarch649
-rw-r--r--tools/perf/tests/llvm.c2
-rw-r--r--tools/perf/tests/sigtrap.c15
-rwxr-xr-xtools/perf/trace/beauty/prctl_option.sh2
-rw-r--r--tools/perf/util/annotate.c1
-rw-r--r--tools/perf/util/bpf-loader.c77
-rw-r--r--tools/perf/util/bpf_counter_cgroup.c2
-rw-r--r--tools/perf/util/bpf_map.c28
-rw-r--r--tools/perf/util/branch.c4
-rw-r--r--tools/perf/util/cs-etm.c16
-rw-r--r--tools/perf/util/data.c7
-rw-r--r--tools/perf/util/evlist-hybrid.c4
-rw-r--r--tools/perf/util/evlist.c28
-rw-r--r--tools/perf/util/include/linux/linkage.h52
-rw-r--r--tools/perf/util/machine.c2
-rw-r--r--tools/perf/util/map_symbol.h1
-rw-r--r--tools/perf/util/parse-events.c8
-rw-r--r--tools/perf/util/perf_event_attr_fprintf.c2
-rw-r--r--tools/perf/util/session.c3
-rw-r--r--tools/perf/util/sort.c4
-rw-r--r--tools/perf/util/stat-display.c19
-rw-r--r--tools/perf/util/symbol.c2
-rw-r--r--tools/perf/util/synthetic-events.c19
-rw-r--r--tools/power/cpupower/Makefile6
-rw-r--r--tools/power/cpupower/TODO (renamed from tools/power/cpupower/ToDo)0
-rw-r--r--tools/power/cpupower/lib/acpi_cppc.c59
-rw-r--r--tools/power/cpupower/lib/acpi_cppc.h21
-rw-r--r--tools/power/cpupower/lib/cpufreq.c23
-rw-r--r--tools/power/cpupower/lib/cpufreq.h12
-rw-r--r--tools/power/cpupower/man/cpupower-frequency-info.13
-rw-r--r--tools/power/cpupower/man/cpupower-idle-set.12
-rw-r--r--tools/power/cpupower/utils/cpufreq-info.c87
-rw-r--r--tools/power/cpupower/utils/helpers/amd.c77
-rw-r--r--tools/power/cpupower/utils/helpers/cpuid.c13
-rw-r--r--tools/power/cpupower/utils/helpers/helpers.h22
-rw-r--r--tools/power/cpupower/utils/helpers/misc.c60
-rwxr-xr-xtools/power/x86/amd_pstate_tracer/amd_pstate_trace.py354
-rw-r--r--tools/power/x86/intel-speed-select/Build2
-rw-r--r--tools/power/x86/intel-speed-select/Makefile10
-rw-r--r--tools/power/x86/intel-speed-select/hfi-events.c309
-rw-r--r--tools/power/x86/intel-speed-select/isst-config.c54
-rw-r--r--tools/power/x86/intel-speed-select/isst-daemon.c244
-rw-r--r--tools/power/x86/intel-speed-select/isst.h13
-rwxr-xr-xtools/power/x86/intel_pstate_tracer/intel_pstate_tracer.py260
-rw-r--r--tools/power/x86/turbostat/turbostat.c2
-rw-r--r--tools/scripts/Makefile.include6
-rw-r--r--tools/testing/cxl/Kbuild22
-rw-r--r--tools/testing/cxl/mock_acpi.c74
-rw-r--r--tools/testing/cxl/mock_mem.c10
-rw-r--r--tools/testing/cxl/mock_pmem.c24
-rw-r--r--tools/testing/cxl/test/cxl.c330
-rw-r--r--tools/testing/cxl/test/mem.c19
-rw-r--r--tools/testing/cxl/test/mock.c91
-rw-r--r--tools/testing/cxl/test/mock.h8
-rwxr-xr-xtools/testing/kunit/kunit.py24
-rw-r--r--tools/testing/kunit/kunit_kernel.py1
-rwxr-xr-xtools/testing/kunit/run_checks.py2
-rw-r--r--tools/testing/scatterlist/linux/mm.h3
-rw-r--r--tools/testing/selftests/.gitignore1
-rw-r--r--tools/testing/selftests/Makefile37
-rw-r--r--tools/testing/selftests/alsa/mixer-test.c412
-rw-r--r--tools/testing/selftests/arm64/abi/syscall-abi.c1
-rw-r--r--tools/testing/selftests/arm64/fp/sve-ptrace.c15
-rw-r--r--tools/testing/selftests/arm64/mte/check_gcr_el1_cswitch.c11
-rw-r--r--tools/testing/selftests/arm64/mte/check_user_mem.c193
-rw-r--r--tools/testing/selftests/arm64/signal/test_signals.h1
-rw-r--r--tools/testing/selftests/arm64/signal/test_signals_utils.c34
-rw-r--r--tools/testing/selftests/arm64/signal/test_signals_utils.h2
-rw-r--r--tools/testing/selftests/bpf/.gitignore2
-rw-r--r--tools/testing/selftests/bpf/Makefile29
-rw-r--r--tools/testing/selftests/bpf/README.rst12
-rw-r--r--tools/testing/selftests/bpf/benchs/bench_ringbufs.c2
-rw-r--r--tools/testing/selftests/bpf/benchs/bench_trigger.c6
-rw-r--r--tools/testing/selftests/bpf/bpf_testmod/bpf_testmod.c60
-rw-r--r--tools/testing/selftests/bpf/cap_helpers.c67
-rw-r--r--tools/testing/selftests/bpf/cap_helpers.h19
-rw-r--r--tools/testing/selftests/bpf/config5
-rwxr-xr-xtools/testing/selftests/bpf/ima_setup.sh35
-rw-r--r--tools/testing/selftests/bpf/network_helpers.c86
-rw-r--r--tools/testing/selftests/bpf/network_helpers.h9
-rw-r--r--tools/testing/selftests/bpf/prog_tests/align.c218
-rw-r--r--tools/testing/selftests/bpf/prog_tests/atomics.c149
-rw-r--r--tools/testing/selftests/bpf/prog_tests/attach_probe.c18
-rw-r--r--tools/testing/selftests/bpf/prog_tests/bind_perm.c64
-rw-r--r--tools/testing/selftests/bpf/prog_tests/bpf_cookie.c195
-rw-r--r--tools/testing/selftests/bpf/prog_tests/bpf_iter.c20
-rw-r--r--tools/testing/selftests/bpf/prog_tests/bpf_iter_setsockopt_unix.c100
-rw-r--r--tools/testing/selftests/bpf/prog_tests/bpf_mod_race.c230
-rw-r--r--tools/testing/selftests/bpf/prog_tests/bpf_nf.c52
-rw-r--r--tools/testing/selftests/bpf/prog_tests/btf.c25
-rw-r--r--tools/testing/selftests/bpf/prog_tests/btf_dump.c54
-rw-r--r--tools/testing/selftests/bpf/prog_tests/btf_tag.c207
-rw-r--r--tools/testing/selftests/bpf/prog_tests/cgroup_attach_autodetach.c2
-rw-r--r--tools/testing/selftests/bpf/prog_tests/cgroup_attach_multi.c14
-rw-r--r--tools/testing/selftests/bpf/prog_tests/cgroup_attach_override.c2
-rw-r--r--tools/testing/selftests/bpf/prog_tests/cgroup_getset_retval.c481
-rw-r--r--tools/testing/selftests/bpf/prog_tests/check_mtu.c40
-rw-r--r--tools/testing/selftests/bpf/prog_tests/cls_redirect.c10
-rw-r--r--tools/testing/selftests/bpf/prog_tests/core_kern.c16
-rw-r--r--tools/testing/selftests/bpf/prog_tests/core_kern_overflow.c13
-rw-r--r--tools/testing/selftests/bpf/prog_tests/core_reloc.c63
-rw-r--r--tools/testing/selftests/bpf/prog_tests/custom_sec_handlers.c176
-rw-r--r--tools/testing/selftests/bpf/prog_tests/dummy_st_ops.c27
-rw-r--r--tools/testing/selftests/bpf/prog_tests/fentry_fexit.c24
-rw-r--r--tools/testing/selftests/bpf/prog_tests/fentry_test.c7
-rw-r--r--tools/testing/selftests/bpf/prog_tests/fexit_bpf2bpf.c34
-rw-r--r--tools/testing/selftests/bpf/prog_tests/fexit_stress.c22
-rw-r--r--tools/testing/selftests/bpf/prog_tests/fexit_test.c7
-rw-r--r--tools/testing/selftests/bpf/prog_tests/find_vma.c30
-rw-r--r--tools/testing/selftests/bpf/prog_tests/flow_dissector.c33
-rw-r--r--tools/testing/selftests/bpf/prog_tests/flow_dissector_load_bytes.c24
-rw-r--r--tools/testing/selftests/bpf/prog_tests/for_each.c32
-rw-r--r--tools/testing/selftests/bpf/prog_tests/get_func_args_test.c12
-rw-r--r--tools/testing/selftests/bpf/prog_tests/get_func_ip_test.c10
-rw-r--r--tools/testing/selftests/bpf/prog_tests/get_stackid_cannot_attach.c2
-rw-r--r--tools/testing/selftests/bpf/prog_tests/global_data.c32
-rw-r--r--tools/testing/selftests/bpf/prog_tests/global_data_init.c2
-rw-r--r--tools/testing/selftests/bpf/prog_tests/global_func_args.c14
-rw-r--r--tools/testing/selftests/bpf/prog_tests/kfree_skb.c16
-rw-r--r--tools/testing/selftests/bpf/prog_tests/kfunc_call.c46
-rw-r--r--tools/testing/selftests/bpf/prog_tests/kprobe_multi_test.c323
-rw-r--r--tools/testing/selftests/bpf/prog_tests/ksyms_module.c27
-rw-r--r--tools/testing/selftests/bpf/prog_tests/l4lb_all.c35
-rw-r--r--tools/testing/selftests/bpf/prog_tests/log_buf.c6
-rw-r--r--tools/testing/selftests/bpf/prog_tests/map_lock.c15
-rw-r--r--tools/testing/selftests/bpf/prog_tests/map_ptr.c16
-rw-r--r--tools/testing/selftests/bpf/prog_tests/modify_return.c33
-rw-r--r--tools/testing/selftests/bpf/prog_tests/obj_name.c2
-rw-r--r--tools/testing/selftests/bpf/prog_tests/perf_branches.c4
-rw-r--r--tools/testing/selftests/bpf/prog_tests/perf_link.c2
-rw-r--r--tools/testing/selftests/bpf/prog_tests/pkt_access.c26
-rw-r--r--tools/testing/selftests/bpf/prog_tests/pkt_md_access.c14
-rw-r--r--tools/testing/selftests/bpf/prog_tests/prog_run_opts.c77
-rw-r--r--tools/testing/selftests/bpf/prog_tests/prog_run_xattr.c83
-rw-r--r--tools/testing/selftests/bpf/prog_tests/queue_stack_map.c46
-rw-r--r--tools/testing/selftests/bpf/prog_tests/raw_tp_test_run.c64
-rw-r--r--tools/testing/selftests/bpf/prog_tests/raw_tp_writable_test_run.c16
-rw-r--r--tools/testing/selftests/bpf/prog_tests/send_signal.c17
-rw-r--r--tools/testing/selftests/bpf/prog_tests/signal_pending.c23
-rw-r--r--tools/testing/selftests/bpf/prog_tests/skb_ctx.c81
-rw-r--r--tools/testing/selftests/bpf/prog_tests/skb_helpers.c16
-rw-r--r--tools/testing/selftests/bpf/prog_tests/sock_fields.c58
-rw-r--r--tools/testing/selftests/bpf/prog_tests/sockmap_basic.c86
-rw-r--r--tools/testing/selftests/bpf/prog_tests/sockmap_listen.c12
-rw-r--r--tools/testing/selftests/bpf/prog_tests/sockopt_sk.c4
-rw-r--r--tools/testing/selftests/bpf/prog_tests/spinlock.c14
-rw-r--r--tools/testing/selftests/bpf/prog_tests/stacktrace_build_id_nmi.c2
-rw-r--r--tools/testing/selftests/bpf/prog_tests/stacktrace_map_skip.c63
-rw-r--r--tools/testing/selftests/bpf/prog_tests/subprogs.c77
-rw-r--r--tools/testing/selftests/bpf/prog_tests/subskeleton.c78
-rw-r--r--tools/testing/selftests/bpf/prog_tests/syscall.c10
-rw-r--r--tools/testing/selftests/bpf/prog_tests/tailcalls.c274
-rw-r--r--tools/testing/selftests/bpf/prog_tests/task_pt_regs.c16
-rw-r--r--tools/testing/selftests/bpf/prog_tests/tc_redirect.c523
-rw-r--r--tools/testing/selftests/bpf/prog_tests/test_bpf_syscall_macro.c73
-rw-r--r--tools/testing/selftests/bpf/prog_tests/test_ima.c149
-rw-r--r--tools/testing/selftests/bpf/prog_tests/test_profiler.c14
-rw-r--r--tools/testing/selftests/bpf/prog_tests/test_skb_pkt_end.c15
-rw-r--r--tools/testing/selftests/bpf/prog_tests/timer.c7
-rw-r--r--tools/testing/selftests/bpf/prog_tests/timer_crash.c32
-rw-r--r--tools/testing/selftests/bpf/prog_tests/timer_mim.c7
-rw-r--r--tools/testing/selftests/bpf/prog_tests/trace_ext.c28
-rw-r--r--tools/testing/selftests/bpf/prog_tests/xdp.c34
-rw-r--r--tools/testing/selftests/bpf/prog_tests/xdp_adjust_frags.c146
-rw-r--r--tools/testing/selftests/bpf/prog_tests/xdp_adjust_tail.c251
-rw-r--r--tools/testing/selftests/bpf/prog_tests/xdp_attach.c29
-rw-r--r--tools/testing/selftests/bpf/prog_tests/xdp_bpf2bpf.c141
-rw-r--r--tools/testing/selftests/bpf/prog_tests/xdp_cpumap_attach.c72
-rw-r--r--tools/testing/selftests/bpf/prog_tests/xdp_devmap_attach.c63
-rw-r--r--tools/testing/selftests/bpf/prog_tests/xdp_do_redirect.c201
-rw-r--r--tools/testing/selftests/bpf/prog_tests/xdp_info.c14
-rw-r--r--tools/testing/selftests/bpf/prog_tests/xdp_link.c26
-rw-r--r--tools/testing/selftests/bpf/prog_tests/xdp_noinline.c44
-rw-r--r--tools/testing/selftests/bpf/prog_tests/xdp_perf.c19
-rw-r--r--tools/testing/selftests/bpf/progs/atomics.c28
-rw-r--r--tools/testing/selftests/bpf/progs/bloom_filter_bench.c7
-rw-r--r--tools/testing/selftests/bpf/progs/bloom_filter_map.c5
-rw-r--r--tools/testing/selftests/bpf/progs/bpf_iter_setsockopt_unix.c60
-rw-r--r--tools/testing/selftests/bpf/progs/bpf_iter_task.c54
-rw-r--r--tools/testing/selftests/bpf/progs/bpf_iter_unix.c2
-rw-r--r--tools/testing/selftests/bpf/progs/bpf_loop.c9
-rw-r--r--tools/testing/selftests/bpf/progs/bpf_loop_bench.c3
-rw-r--r--tools/testing/selftests/bpf/progs/bpf_misc.h19
-rw-r--r--tools/testing/selftests/bpf/progs/bpf_mod_race.c100
-rw-r--r--tools/testing/selftests/bpf/progs/bpf_syscall_macro.c84
-rw-r--r--tools/testing/selftests/bpf/progs/bpf_tracing_net.h2
-rw-r--r--tools/testing/selftests/bpf/progs/btf_type_tag_percpu.c66
-rw-r--r--tools/testing/selftests/bpf/progs/btf_type_tag_user.c40
-rw-r--r--tools/testing/selftests/bpf/progs/cgroup_getset_retval_getsockopt.c45
-rw-r--r--tools/testing/selftests/bpf/progs/cgroup_getset_retval_setsockopt.c52
-rw-r--r--tools/testing/selftests/bpf/progs/core_kern.c16
-rw-r--r--tools/testing/selftests/bpf/progs/core_kern_overflow.c22
-rw-r--r--tools/testing/selftests/bpf/progs/fexit_sleep.c9
-rw-r--r--tools/testing/selftests/bpf/progs/freplace_cls_redirect.c12
-rw-r--r--tools/testing/selftests/bpf/progs/ima.c66
-rw-r--r--tools/testing/selftests/bpf/progs/kfunc_call_race.c14
-rw-r--r--tools/testing/selftests/bpf/progs/kfunc_call_test.c52
-rw-r--r--tools/testing/selftests/bpf/progs/kprobe_multi.c100
-rw-r--r--tools/testing/selftests/bpf/progs/ksym_race.c13
-rw-r--r--tools/testing/selftests/bpf/progs/local_storage.c19
-rw-r--r--tools/testing/selftests/bpf/progs/perfbuf_bench.c3
-rw-r--r--tools/testing/selftests/bpf/progs/ringbuf_bench.c3
-rw-r--r--tools/testing/selftests/bpf/progs/sample_map_ret0.c24
-rw-r--r--tools/testing/selftests/bpf/progs/sockmap_parse_prog.c2
-rw-r--r--tools/testing/selftests/bpf/progs/sockopt_sk.c35
-rw-r--r--tools/testing/selftests/bpf/progs/stacktrace_map_skip.c68
-rw-r--r--tools/testing/selftests/bpf/progs/test_bpf_nf.c118
-rw-r--r--tools/testing/selftests/bpf/progs/test_btf_decl_tag.c (renamed from tools/testing/selftests/bpf/progs/btf_decl_tag.c)0
-rw-r--r--tools/testing/selftests/bpf/progs/test_btf_haskv.c3
-rw-r--r--tools/testing/selftests/bpf/progs/test_btf_newkv.c3
-rw-r--r--tools/testing/selftests/bpf/progs/test_btf_nokv.c12
-rw-r--r--tools/testing/selftests/bpf/progs/test_custom_sec_handlers.c63
-rw-r--r--tools/testing/selftests/bpf/progs/test_probe_user.c15
-rw-r--r--tools/testing/selftests/bpf/progs/test_ringbuf.c3
-rw-r--r--tools/testing/selftests/bpf/progs/test_send_signal_kern.c2
-rw-r--r--tools/testing/selftests/bpf/progs/test_sk_lookup.c15
-rw-r--r--tools/testing/selftests/bpf/progs/test_skb_cgroup_id_kern.c12
-rw-r--r--tools/testing/selftests/bpf/progs/test_sock_fields.c63
-rw-r--r--tools/testing/selftests/bpf/progs/test_sockmap_kern.h26
-rw-r--r--tools/testing/selftests/bpf/progs/test_sockmap_progs_query.c24
-rw-r--r--tools/testing/selftests/bpf/progs/test_subskeleton.c28
-rw-r--r--tools/testing/selftests/bpf/progs/test_subskeleton_lib.c61
-rw-r--r--tools/testing/selftests/bpf/progs/test_subskeleton_lib2.c16
-rw-r--r--tools/testing/selftests/bpf/progs/test_tc_dtime.c349
-rw-r--r--tools/testing/selftests/bpf/progs/test_tc_edt.c12
-rw-r--r--tools/testing/selftests/bpf/progs/test_tcp_check_syncookie_kern.c12
-rw-r--r--tools/testing/selftests/bpf/progs/test_xdp_adjust_tail_grow.c10
-rw-r--r--tools/testing/selftests/bpf/progs/test_xdp_adjust_tail_shrink.c32
-rw-r--r--tools/testing/selftests/bpf/progs/test_xdp_bpf2bpf.c2
-rw-r--r--tools/testing/selftests/bpf/progs/test_xdp_do_redirect.c100
-rw-r--r--tools/testing/selftests/bpf/progs/test_xdp_update_frags.c42
-rw-r--r--tools/testing/selftests/bpf/progs/test_xdp_with_cpumap_frags_helpers.c27
-rw-r--r--tools/testing/selftests/bpf/progs/test_xdp_with_cpumap_helpers.c8
-rw-r--r--tools/testing/selftests/bpf/progs/test_xdp_with_devmap_frags_helpers.c27
-rw-r--r--tools/testing/selftests/bpf/progs/test_xdp_with_devmap_helpers.c9
-rw-r--r--tools/testing/selftests/bpf/progs/timer_crash.c54
-rw-r--r--tools/testing/selftests/bpf/progs/trace_printk.c3
-rw-r--r--tools/testing/selftests/bpf/progs/trace_vprintk.c3
-rw-r--r--tools/testing/selftests/bpf/progs/trigger_bench.c9
-rw-r--r--tools/testing/selftests/bpf/progs/xdp_redirect_multi_kern.c2
-rw-r--r--tools/testing/selftests/bpf/test_cgroup_storage.c2
-rw-r--r--tools/testing/selftests/bpf/test_cpp.cpp90
-rwxr-xr-xtools/testing/selftests/bpf/test_lirc_mode2.sh5
-rw-r--r--tools/testing/selftests/bpf/test_lirc_mode2_user.c1
-rw-r--r--tools/testing/selftests/bpf/test_lru_map.c15
-rwxr-xr-xtools/testing/selftests/bpf/test_lwt_ip_encap.sh10
-rwxr-xr-xtools/testing/selftests/bpf/test_lwt_seg6local.sh170
-rw-r--r--tools/testing/selftests/bpf/test_maps.c2
-rw-r--r--tools/testing/selftests/bpf/test_sock_addr.c6
-rw-r--r--tools/testing/selftests/bpf/test_sockmap.c4
-rwxr-xr-xtools/testing/selftests/bpf/test_tcp_check_syncookie.sh5
-rwxr-xr-xtools/testing/selftests/bpf/test_tunnel.sh2
-rw-r--r--tools/testing/selftests/bpf/test_verifier.c136
-rwxr-xr-xtools/testing/selftests/bpf/test_xdp_meta.sh38
-rwxr-xr-xtools/testing/selftests/bpf/test_xdp_redirect.sh30
-rwxr-xr-xtools/testing/selftests/bpf/test_xdp_redirect_multi.sh60
-rwxr-xr-xtools/testing/selftests/bpf/test_xdp_veth.sh39
-rwxr-xr-xtools/testing/selftests/bpf/test_xdp_vlan.sh66
-rw-r--r--tools/testing/selftests/bpf/trace_helpers.c77
-rw-r--r--tools/testing/selftests/bpf/trace_helpers.h3
-rw-r--r--tools/testing/selftests/bpf/verifier/atomic_invalid.c6
-rw-r--r--tools/testing/selftests/bpf/verifier/bounds.c4
-rw-r--r--tools/testing/selftests/bpf/verifier/bounds_deduction.c2
-rw-r--r--tools/testing/selftests/bpf/verifier/calls.c183
-rw-r--r--tools/testing/selftests/bpf/verifier/ctx.c12
-rw-r--r--tools/testing/selftests/bpf/verifier/direct_packet_access.c2
-rw-r--r--tools/testing/selftests/bpf/verifier/helper_access_var_len.c6
-rw-r--r--tools/testing/selftests/bpf/verifier/jmp32.c16
-rw-r--r--tools/testing/selftests/bpf/verifier/precise.c4
-rw-r--r--tools/testing/selftests/bpf/verifier/raw_stack.c4
-rw-r--r--tools/testing/selftests/bpf/verifier/ref_tracking.c6
-rw-r--r--tools/testing/selftests/bpf/verifier/search_pruning.c2
-rw-r--r--tools/testing/selftests/bpf/verifier/sock.c83
-rw-r--r--tools/testing/selftests/bpf/verifier/spill_fill.c38
-rw-r--r--tools/testing/selftests/bpf/verifier/unpriv.c4
-rw-r--r--tools/testing/selftests/bpf/verifier/value_illegal_alu.c4
-rw-r--r--tools/testing/selftests/bpf/verifier/value_ptr_arith.c4
-rw-r--r--tools/testing/selftests/bpf/verifier/var_off.c2
-rwxr-xr-xtools/testing/selftests/bpf/vmtest.sh2
-rw-r--r--tools/testing/selftests/bpf/xdp_redirect_multi.c8
-rw-r--r--tools/testing/selftests/bpf/xdping.c4
-rw-r--r--tools/testing/selftests/bpf/xdpxceiver.c85
-rw-r--r--tools/testing/selftests/bpf/xdpxceiver.h2
-rw-r--r--tools/testing/selftests/cgroup/cgroup_util.c15
-rw-r--r--tools/testing/selftests/cgroup/cgroup_util.h1
-rw-r--r--tools/testing/selftests/cgroup/test_memcontrol.c78
-rw-r--r--tools/testing/selftests/clone3/clone3.c2
-rwxr-xr-xtools/testing/selftests/cpufreq/main.sh2
-rw-r--r--tools/testing/selftests/damon/Makefile1
-rw-r--r--tools/testing/selftests/damon/sysfs.sh306
-rwxr-xr-xtools/testing/selftests/drivers/net/mlxsw/hw_stats_l3.sh31
-rwxr-xr-xtools/testing/selftests/drivers/net/mlxsw/spectrum/resource_scale.sh2
-rw-r--r--tools/testing/selftests/drivers/net/mlxsw/tc_police_scale.sh3
-rwxr-xr-xtools/testing/selftests/drivers/net/netdevsim/hw_stats_l3.sh421
-rw-r--r--tools/testing/selftests/exec/.gitignore2
-rw-r--r--tools/testing/selftests/exec/Makefile7
-rwxr-xr-xtools/testing/selftests/exec/binfmt_script.py (renamed from tools/testing/selftests/exec/binfmt_script)0
-rw-r--r--tools/testing/selftests/exec/null-argv.c78
-rw-r--r--tools/testing/selftests/ftrace/test.d/ftrace/func_set_ftrace_file.tc2
-rw-r--r--tools/testing/selftests/futex/Makefile4
-rw-r--r--tools/testing/selftests/futex/functional/Makefile6
-rw-r--r--tools/testing/selftests/ir/ir_loopback.c10
-rw-r--r--tools/testing/selftests/kselftest/runner.sh30
-rw-r--r--tools/testing/selftests/kselftest_harness.h4
-rw-r--r--tools/testing/selftests/kvm/.gitignore4
-rw-r--r--tools/testing/selftests/kvm/Makefile8
-rw-r--r--tools/testing/selftests/kvm/aarch64/arch_timer.c7
-rw-r--r--tools/testing/selftests/kvm/aarch64/debug-exceptions.c58
-rw-r--r--tools/testing/selftests/kvm/aarch64/get-reg-list.c1
-rw-r--r--tools/testing/selftests/kvm/aarch64/vgic_irq.c49
-rw-r--r--tools/testing/selftests/kvm/dirty_log_perf_test.c23
-rw-r--r--tools/testing/selftests/kvm/include/kvm_util_base.h9
-rw-r--r--tools/testing/selftests/kvm/include/s390x/processor.h8
-rw-r--r--tools/testing/selftests/kvm/include/x86_64/apic.h1
-rw-r--r--tools/testing/selftests/kvm/include/x86_64/evmcs.h150
-rw-r--r--tools/testing/selftests/kvm/include/x86_64/processor.h6
-rw-r--r--tools/testing/selftests/kvm/include/x86_64/svm.h9
-rw-r--r--tools/testing/selftests/kvm/include/x86_64/svm_util.h6
-rw-r--r--tools/testing/selftests/kvm/lib/aarch64/gic_v3.c12
-rw-r--r--tools/testing/selftests/kvm/lib/aarch64/vgic.c13
-rw-r--r--tools/testing/selftests/kvm/lib/kvm_util.c94
-rw-r--r--tools/testing/selftests/kvm/lib/x86_64/processor.c27
-rw-r--r--tools/testing/selftests/kvm/lib/x86_64/svm.c6
-rw-r--r--tools/testing/selftests/kvm/max_guest_memory_test.c292
-rw-r--r--tools/testing/selftests/kvm/s390x/memop.c732
-rw-r--r--tools/testing/selftests/kvm/s390x/tprot.c227
-rw-r--r--tools/testing/selftests/kvm/set_memory_region_test.c35
-rw-r--r--tools/testing/selftests/kvm/x86_64/amx_test.c2
-rw-r--r--tools/testing/selftests/kvm/x86_64/evmcs_test.c64
-rw-r--r--tools/testing/selftests/kvm/x86_64/hyperv_cpuid.c29
-rw-r--r--tools/testing/selftests/kvm/x86_64/hyperv_svm_test.c175
-rw-r--r--tools/testing/selftests/kvm/x86_64/pmu_event_filter_test.c33
-rw-r--r--tools/testing/selftests/kvm/x86_64/sev_migrate_tests.c125
-rw-r--r--tools/testing/selftests/kvm/x86_64/smm_test.c1
-rw-r--r--tools/testing/selftests/kvm/x86_64/xapic_state_test.c150
-rw-r--r--tools/testing/selftests/landlock/Makefile2
-rw-r--r--tools/testing/selftests/lkdtm/config2
-rw-r--r--tools/testing/selftests/memfd/memfd_test.c1
-rw-r--r--tools/testing/selftests/mincore/mincore_selftest.c20
-rw-r--r--tools/testing/selftests/mount_setattr/mount_setattr_test.c4
-rw-r--r--tools/testing/selftests/net/.gitignore2
-rw-r--r--tools/testing/selftests/net/Makefile5
-rw-r--r--tools/testing/selftests/net/af_unix/test_unix_oob.c6
-rwxr-xr-xtools/testing/selftests/net/cmsg_ipv6.sh156
-rw-r--r--tools/testing/selftests/net/cmsg_sender.c506
-rw-r--r--tools/testing/selftests/net/cmsg_so_mark.c67
-rwxr-xr-xtools/testing/selftests/net/cmsg_so_mark.sh32
-rwxr-xr-xtools/testing/selftests/net/cmsg_time.sh83
-rwxr-xr-xtools/testing/selftests/net/fcnal-test.sh2
-rwxr-xr-xtools/testing/selftests/net/fib_rule_tests.sh86
-rwxr-xr-xtools/testing/selftests/net/fib_tests.sh147
-rw-r--r--tools/testing/selftests/net/forwarding/Makefile1
-rwxr-xr-xtools/testing/selftests/net/forwarding/bridge_locked_port.sh176
-rwxr-xr-xtools/testing/selftests/net/forwarding/bridge_vlan_aware.sh5
-rwxr-xr-xtools/testing/selftests/net/forwarding/bridge_vlan_unaware.sh5
-rw-r--r--tools/testing/selftests/net/forwarding/fib_offload_lib.sh12
-rw-r--r--tools/testing/selftests/net/forwarding/forwarding.config.sample2
-rwxr-xr-xtools/testing/selftests/net/forwarding/hw_stats_l3.sh332
-rw-r--r--tools/testing/selftests/net/forwarding/lib.sh69
-rwxr-xr-xtools/testing/selftests/net/forwarding/pedit_ip.sh201
-rwxr-xr-xtools/testing/selftests/net/forwarding/tc_police.sh52
-rw-r--r--tools/testing/selftests/net/ioam6_parser.c5
-rw-r--r--tools/testing/selftests/net/mptcp/Makefile2
-rwxr-xr-xtools/testing/selftests/net/mptcp/diag.sh44
-rwxr-xr-xtools/testing/selftests/net/mptcp/mptcp_connect.sh23
-rwxr-xr-xtools/testing/selftests/net/mptcp/mptcp_join.sh2763
-rwxr-xr-xtools/testing/selftests/net/mptcp/pm_netlink.sh18
-rw-r--r--tools/testing/selftests/net/mptcp/pm_nl_ctl.c88
-rw-r--r--tools/testing/selftests/net/mptcp/settings2
-rwxr-xr-xtools/testing/selftests/net/pmtu.sh162
-rw-r--r--tools/testing/selftests/net/psock_fanout.c5
-rw-r--r--tools/testing/selftests/net/reuseport_bpf_numa.c2
-rwxr-xr-xtools/testing/selftests/net/rtnetlink.sh4
-rwxr-xr-xtools/testing/selftests/net/test_vxlan_vnifiltering.sh579
-rw-r--r--tools/testing/selftests/net/timestamping.c4
-rw-r--r--tools/testing/selftests/net/toeplitz.c6
-rw-r--r--tools/testing/selftests/net/txtimestamp.c6
-rw-r--r--tools/testing/selftests/netfilter/.gitignore1
-rw-r--r--tools/testing/selftests/netfilter/Makefile5
-rw-r--r--tools/testing/selftests/netfilter/connect_close.c136
-rwxr-xr-xtools/testing/selftests/netfilter/nft_concat_range.sh74
-rwxr-xr-xtools/testing/selftests/netfilter/nft_fib.sh1
-rwxr-xr-xtools/testing/selftests/netfilter/nft_nat.sh157
-rwxr-xr-xtools/testing/selftests/netfilter/nft_queue.sh19
-rwxr-xr-xtools/testing/selftests/netfilter/nft_synproxy.sh117
-rwxr-xr-xtools/testing/selftests/netfilter/nft_zones_many.sh12
-rw-r--r--tools/testing/selftests/openat2/Makefile2
-rw-r--r--tools/testing/selftests/openat2/helpers.h12
-rw-r--r--tools/testing/selftests/openat2/openat2_test.c12
-rw-r--r--tools/testing/selftests/perf_events/sigtrap_threads.c17
-rw-r--r--tools/testing/selftests/pidfd/pidfd.h13
-rw-r--r--tools/testing/selftests/pidfd/pidfd_fdinfo_test.c22
-rw-r--r--tools/testing/selftests/pidfd/pidfd_test.c6
-rw-r--r--tools/testing/selftests/pidfd/pidfd_wait.c5
-rw-r--r--tools/testing/selftests/ptp/testptp.c18
-rwxr-xr-xtools/testing/selftests/rcutorture/bin/console-badness.sh2
-rwxr-xr-xtools/testing/selftests/rcutorture/bin/kvm-again.sh4
-rwxr-xr-xtools/testing/selftests/rcutorture/bin/kvm-check-branches.sh4
-rwxr-xr-xtools/testing/selftests/rcutorture/bin/kvm-end-run-stats.sh4
-rwxr-xr-xtools/testing/selftests/rcutorture/bin/kvm-find-errors.sh6
-rwxr-xr-xtools/testing/selftests/rcutorture/bin/kvm-recheck-rcu.sh2
-rwxr-xr-xtools/testing/selftests/rcutorture/bin/kvm-remote.sh25
-rwxr-xr-xtools/testing/selftests/rcutorture/bin/kvm.sh16
-rwxr-xr-xtools/testing/selftests/rcutorture/bin/parse-console.sh10
-rwxr-xr-xtools/testing/selftests/rcutorture/bin/torture.sh38
-rw-r--r--tools/testing/selftests/rcutorture/configs/rcu/RUDE012
-rw-r--r--tools/testing/selftests/rcutorture/configs/rcu/SRCU-N.boot1
-rw-r--r--tools/testing/selftests/rcutorture/configs/rcu/SRCU-P.boot2
-rw-r--r--tools/testing/selftests/rcutorture/configs/rcu/TRACE012
-rw-r--r--tools/testing/selftests/rseq/Makefile2
-rw-r--r--tools/testing/selftests/rseq/basic_percpu_ops_test.c2
-rw-r--r--tools/testing/selftests/rseq/compiler.h30
-rw-r--r--tools/testing/selftests/rseq/param_test.c8
-rw-r--r--tools/testing/selftests/rseq/rseq-abi.h151
-rw-r--r--tools/testing/selftests/rseq/rseq-arm.h110
-rw-r--r--tools/testing/selftests/rseq/rseq-arm64.h79
-rw-r--r--tools/testing/selftests/rseq/rseq-generic-thread-pointer.h25
-rw-r--r--tools/testing/selftests/rseq/rseq-mips.h71
-rw-r--r--tools/testing/selftests/rseq/rseq-ppc-thread-pointer.h30
-rw-r--r--tools/testing/selftests/rseq/rseq-ppc.h128
-rw-r--r--tools/testing/selftests/rseq/rseq-s390.h55
-rw-r--r--tools/testing/selftests/rseq/rseq-skip.h2
-rw-r--r--tools/testing/selftests/rseq/rseq-thread-pointer.h19
-rw-r--r--tools/testing/selftests/rseq/rseq-x86-thread-pointer.h40
-rw-r--r--tools/testing/selftests/rseq/rseq-x86.h200
-rw-r--r--tools/testing/selftests/rseq/rseq.c164
-rw-r--r--tools/testing/selftests/rseq/rseq.h30
-rw-r--r--tools/testing/selftests/rtc/rtctest.c66
-rw-r--r--tools/testing/selftests/rtc/settings2
-rw-r--r--tools/testing/selftests/seccomp/Makefile2
-rw-r--r--tools/testing/selftests/sgx/Makefile2
-rw-r--r--tools/testing/selftests/sgx/load.c9
-rw-r--r--tools/testing/selftests/sgx/main.c9
-rw-r--r--tools/testing/selftests/tc-testing/tdc_config.py2
-rw-r--r--tools/testing/selftests/tpm2/tpm2.py31
-rw-r--r--tools/testing/selftests/tpm2/tpm2_tests.py45
-rw-r--r--tools/testing/selftests/user_events/Makefile9
-rw-r--r--tools/testing/selftests/user_events/dyn_test.c130
-rw-r--r--tools/testing/selftests/user_events/ftrace_test.c452
-rw-r--r--tools/testing/selftests/user_events/perf_test.c168
-rw-r--r--tools/testing/selftests/user_events/settings1
-rw-r--r--tools/testing/selftests/vDSO/vdso_config.h4
-rw-r--r--tools/testing/selftests/vDSO/vdso_test_abi.c135
-rw-r--r--tools/testing/selftests/vm/.gitignore1
-rw-r--r--tools/testing/selftests/vm/Makefile15
-rw-r--r--tools/testing/selftests/vm/hugepage-mremap.c26
-rw-r--r--tools/testing/selftests/vm/hugepage-vmemmap.c144
-rw-r--r--tools/testing/selftests/vm/map_fixed_noreplace.c49
-rwxr-xr-xtools/testing/selftests/vm/run_vmtests.sh14
-rw-r--r--tools/testing/selftests/vm/transhuge-stress.c35
-rw-r--r--tools/testing/selftests/vm/userfaultfd.c15
-rw-r--r--tools/testing/selftests/x86/Makefile6
-rwxr-xr-xtools/testing/selftests/x86/check_cc.sh2
-rwxr-xr-xtools/testing/selftests/zram/zram.sh15
-rwxr-xr-xtools/testing/selftests/zram/zram01.sh33
-rwxr-xr-xtools/testing/selftests/zram/zram02.sh1
-rwxr-xr-xtools/testing/selftests/zram/zram_lib.sh134
-rw-r--r--tools/testing/vsock/vsock_test.c215
-rw-r--r--tools/tracing/Makefile18
-rw-r--r--tools/tracing/rtla/Makefile6
-rw-r--r--tools/tracing/rtla/src/osnoise.c88
-rw-r--r--tools/tracing/rtla/src/osnoise.h8
-rw-r--r--tools/tracing/rtla/src/osnoise_hist.c106
-rw-r--r--tools/tracing/rtla/src/osnoise_top.c99
-rw-r--r--tools/tracing/rtla/src/timerlat_hist.c119
-rw-r--r--tools/tracing/rtla/src/timerlat_top.c110
-rw-r--r--tools/tracing/rtla/src/trace.c353
-rw-r--r--tools/tracing/rtla/src/trace.h23
-rw-r--r--tools/tracing/rtla/src/utils.c37
-rw-r--r--tools/tracing/rtla/src/utils.h1
-rw-r--r--tools/virtio/linux/mm_types.h3
-rw-r--r--tools/virtio/virtio_test.c1
-rw-r--r--usr/include/Makefile9
-rw-r--r--virt/kvm/Kconfig2
-rw-r--r--virt/kvm/eventfd.c8
-rw-r--r--virt/kvm/kvm_main.c52
9769 files changed, 829602 insertions, 166687 deletions
diff --git a/.mailmap b/.mailmap
index b157f88ce26a..97ccdf147111 100644
--- a/.mailmap
+++ b/.mailmap
@@ -70,6 +70,7 @@ Boris Brezillon <bbrezillon@kernel.org> <boris.brezillon@bootlin.com>
Boris Brezillon <bbrezillon@kernel.org> <boris.brezillon@free-electrons.com>
Brian Avery <b.avery@hp.com>
Brian King <brking@us.ibm.com>
+Brian Silverman <bsilver16384@gmail.com> <brian.silverman@bluerivertech.com>
Changbin Du <changbin.du@intel.com> <changbin.du@gmail.com>
Changbin Du <changbin.du@intel.com> <changbin.du@intel.com>
Chao Yu <chao@kernel.org> <chao2.yu@samsung.com>
@@ -79,6 +80,9 @@ Chris Chiu <chris.chiu@canonical.com> <chiu@endlessos.org>
Christian Borntraeger <borntraeger@linux.ibm.com> <borntraeger@de.ibm.com>
Christian Borntraeger <borntraeger@linux.ibm.com> <cborntra@de.ibm.com>
Christian Borntraeger <borntraeger@linux.ibm.com> <borntrae@de.ibm.com>
+Christian Brauner <brauner@kernel.org> <christian@brauner.io>
+Christian Brauner <brauner@kernel.org> <christian.brauner@canonical.com>
+Christian Brauner <brauner@kernel.org> <christian.brauner@ubuntu.com>
Christophe Ricard <christophe.ricard@gmail.com>
Christoph Hellwig <hch@lst.de>
Colin Ian King <colin.king@intel.com> <colin.king@canonical.com>
@@ -183,6 +187,8 @@ Jiri Slaby <jirislaby@kernel.org> <jslaby@novell.com>
Jiri Slaby <jirislaby@kernel.org> <jslaby@suse.com>
Jiri Slaby <jirislaby@kernel.org> <jslaby@suse.cz>
Jiri Slaby <jirislaby@kernel.org> <xslaby@fi.muni.cz>
+Jisheng Zhang <jszhang@kernel.org> <jszhang@marvell.com>
+Jisheng Zhang <jszhang@kernel.org> <Jisheng.Zhang@synaptics.com>
Johan Hovold <johan@kernel.org> <jhovold@gmail.com>
Johan Hovold <johan@kernel.org> <johan@hovoldconsulting.com>
John Paul Adrian Glaubitz <glaubitz@physik.fu-berlin.de>
@@ -212,6 +218,7 @@ Koushik <raghavendra.koushik@neterion.com>
Krishna Manikandan <quic_mkrishn@quicinc.com> <mkrishn@codeaurora.org>
Krzysztof Kozlowski <krzk@kernel.org> <k.kozlowski.k@gmail.com>
Krzysztof Kozlowski <krzk@kernel.org> <k.kozlowski@samsung.com>
+Krzysztof Kozlowski <krzk@kernel.org> <krzysztof.kozlowski@canonical.com>
Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Kuogee Hsieh <quic_khsieh@quicinc.com> <khsieh@codeaurora.org>
Leonardo Bras <leobras.c@gmail.com> <leonardo@linux.ibm.com>
@@ -329,6 +336,9 @@ Rémi Denis-Courmont <rdenis@simphalempin.com>
Ricardo Ribalda <ribalda@kernel.org> <ricardo@ribalda.com>
Ricardo Ribalda <ribalda@kernel.org> Ricardo Ribalda Delgado <ribalda@kernel.org>
Ricardo Ribalda <ribalda@kernel.org> <ricardo.ribalda@gmail.com>
+Roman Gushchin <roman.gushchin@linux.dev> <guro@fb.com>
+Roman Gushchin <roman.gushchin@linux.dev> <guroan@gmail.com>
+Roman Gushchin <roman.gushchin@linux.dev> <klamm@yandex-team.ru>
Ross Zwisler <zwisler@kernel.org> <ross.zwisler@linux.intel.com>
Rudolf Marek <R.Marek@sh.cvut.cz>
Rui Saraiva <rmps@joel.ist.utl.pt>
diff --git a/CREDITS b/CREDITS
index b97256d5bc24..7e85a53b6a88 100644
--- a/CREDITS
+++ b/CREDITS
@@ -895,6 +895,12 @@ S: 3000 FORE Drive
S: Warrendale, Pennsylvania 15086
S: USA
+N: Ludovic Desroches
+E: ludovic.desroches@microchip.com
+D: Maintainer for ARM/Microchip (AT91) SoC support
+D: Author of ADC, pinctrl, XDMA and SDHCI drivers for this platform
+S: France
+
N: Martin Devera
E: devik@cdi.cz
W: http://luxik.cdi.cz/~devik/qos/
diff --git a/Documentation/ABI/obsolete/procfs-i8k b/Documentation/ABI/obsolete/procfs-i8k
new file mode 100644
index 000000000000..32df4d5bdd15
--- /dev/null
+++ b/Documentation/ABI/obsolete/procfs-i8k
@@ -0,0 +1,10 @@
+What: /proc/i8k
+Date: November 2001
+KernelVersion: 2.4.14
+Contact: Pali Rohár <pali@kernel.org>
+Description: Legacy interface for getting/setting sensor information like
+ fan speed, temperature, serial number, hotkey status etc
+ on Dell Laptops.
+ Since the driver is now using the standard hwmon sysfs interface,
+ the procfs interface is deprecated.
+Users: https://github.com/vitorafsr/i8kutils
diff --git a/Documentation/ABI/stable/sysfs-block b/Documentation/ABI/stable/sysfs-block
index 8dd3e84a8aad..e8797cd09aff 100644
--- a/Documentation/ABI/stable/sysfs-block
+++ b/Documentation/ABI/stable/sysfs-block
@@ -155,6 +155,55 @@ Description:
last zone of the device which may be smaller.
+What: /sys/block/<disk>/queue/crypto/
+Date: February 2022
+Contact: linux-block@vger.kernel.org
+Description:
+ The presence of this subdirectory of /sys/block/<disk>/queue/
+ indicates that the device supports inline encryption. This
+ subdirectory contains files which describe the inline encryption
+ capabilities of the device. For more information about inline
+ encryption, refer to Documentation/block/inline-encryption.rst.
+
+
+What: /sys/block/<disk>/queue/crypto/max_dun_bits
+Date: February 2022
+Contact: linux-block@vger.kernel.org
+Description:
+ [RO] This file shows the maximum length, in bits, of data unit
+ numbers accepted by the device in inline encryption requests.
+
+
+What: /sys/block/<disk>/queue/crypto/modes/<mode>
+Date: February 2022
+Contact: linux-block@vger.kernel.org
+Description:
+ [RO] For each crypto mode (i.e., encryption/decryption
+ algorithm) the device supports with inline encryption, a file
+ will exist at this location. It will contain a hexadecimal
+ number that is a bitmask of the supported data unit sizes, in
+ bytes, for that crypto mode.
+
+ Currently, the crypto modes that may be supported are:
+
+ * AES-256-XTS
+ * AES-128-CBC-ESSIV
+ * Adiantum
+
+ For example, if a device supports AES-256-XTS inline encryption
+ with data unit sizes of 512 and 4096 bytes, the file
+ /sys/block/<disk>/queue/crypto/modes/AES-256-XTS will exist and
+ will contain "0x1200".
+
+
+What: /sys/block/<disk>/queue/crypto/num_keyslots
+Date: February 2022
+Contact: linux-block@vger.kernel.org
+Description:
+ [RO] This file shows the number of keyslots the device has for
+ use with inline encryption.
+
+
What: /sys/block/<disk>/queue/dax
Date: June 2016
Contact: linux-block@vger.kernel.org
diff --git a/Documentation/ABI/stable/sysfs-devices-system-cpu b/Documentation/ABI/stable/sysfs-devices-system-cpu
index 3965ce504484..902392d7eddf 100644
--- a/Documentation/ABI/stable/sysfs-devices-system-cpu
+++ b/Documentation/ABI/stable/sysfs-devices-system-cpu
@@ -86,6 +86,10 @@ What: /sys/devices/system/cpu/cpuX/topology/die_cpus
Description: internal kernel map of CPUs within the same die.
Values: hexadecimal bitmask.
+What: /sys/devices/system/cpu/cpuX/topology/ppin
+Description: per-socket protected processor inventory number
+Values: hexadecimal.
+
What: /sys/devices/system/cpu/cpuX/topology/die_cpus_list
Description: human-readable list of CPUs within the same die.
The format is like 0-3, 8-11, 14,17.
diff --git a/Documentation/ABI/testing/debugfs-hisi-hpre b/Documentation/ABI/testing/debugfs-hisi-hpre
index b4be5f1db4b7..396de7bc735d 100644
--- a/Documentation/ABI/testing/debugfs-hisi-hpre
+++ b/Documentation/ABI/testing/debugfs-hisi-hpre
@@ -1,140 +1,150 @@
-What: /sys/kernel/debug/hisi_hpre/<bdf>/cluster[0-3]/regs
-Date: Sep 2019
-Contact: linux-crypto@vger.kernel.org
-Description: Dump debug registers from the HPRE cluster.
+What: /sys/kernel/debug/hisi_hpre/<bdf>/cluster[0-3]/regs
+Date: Sep 2019
+Contact: linux-crypto@vger.kernel.org
+Description: Dump debug registers from the HPRE cluster.
Only available for PF.
-What: /sys/kernel/debug/hisi_hpre/<bdf>/cluster[0-3]/cluster_ctrl
-Date: Sep 2019
-Contact: linux-crypto@vger.kernel.org
-Description: Write the HPRE core selection in the cluster into this file,
+What: /sys/kernel/debug/hisi_hpre/<bdf>/cluster[0-3]/cluster_ctrl
+Date: Sep 2019
+Contact: linux-crypto@vger.kernel.org
+Description: Write the HPRE core selection in the cluster into this file,
and then we can read the debug information of the core.
Only available for PF.
-What: /sys/kernel/debug/hisi_hpre/<bdf>/rdclr_en
-Date: Sep 2019
-Contact: linux-crypto@vger.kernel.org
-Description: HPRE cores debug registers read clear control. 1 means enable
+What: /sys/kernel/debug/hisi_hpre/<bdf>/rdclr_en
+Date: Sep 2019
+Contact: linux-crypto@vger.kernel.org
+Description: HPRE cores debug registers read clear control. 1 means enable
register read clear, otherwise 0. Writing to this file has no
functional effect, only enable or disable counters clear after
reading of these registers.
Only available for PF.
-What: /sys/kernel/debug/hisi_hpre/<bdf>/current_qm
-Date: Sep 2019
-Contact: linux-crypto@vger.kernel.org
-Description: One HPRE controller has one PF and multiple VFs, each function
+What: /sys/kernel/debug/hisi_hpre/<bdf>/current_qm
+Date: Sep 2019
+Contact: linux-crypto@vger.kernel.org
+Description: One HPRE controller has one PF and multiple VFs, each function
has a QM. Select the QM which below qm refers to.
Only available for PF.
-What: /sys/kernel/debug/hisi_hpre/<bdf>/regs
-Date: Sep 2019
-Contact: linux-crypto@vger.kernel.org
-Description: Dump debug registers from the HPRE.
+What: /sys/kernel/debug/hisi_hpre/<bdf>/alg_qos
+Date: Jun 2021
+Contact: linux-crypto@vger.kernel.org
+Description: The <bdf> is related the function for PF and VF.
+ HPRE driver supports to configure each function's QoS, the driver
+ supports to write <bdf> value to alg_qos in the host. Such as
+ "echo <bdf> value > alg_qos". The qos value is 1~1000, means
+ 1/1000~1000/1000 of total QoS. The driver reading alg_qos to
+ get related QoS in the host and VM, Such as "cat alg_qos".
+
+What: /sys/kernel/debug/hisi_hpre/<bdf>/regs
+Date: Sep 2019
+Contact: linux-crypto@vger.kernel.org
+Description: Dump debug registers from the HPRE.
Only available for PF.
-What: /sys/kernel/debug/hisi_hpre/<bdf>/qm/regs
-Date: Sep 2019
-Contact: linux-crypto@vger.kernel.org
-Description: Dump debug registers from the QM.
+What: /sys/kernel/debug/hisi_hpre/<bdf>/qm/regs
+Date: Sep 2019
+Contact: linux-crypto@vger.kernel.org
+Description: Dump debug registers from the QM.
Available for PF and VF in host. VF in guest currently only
has one debug register.
-What: /sys/kernel/debug/hisi_hpre/<bdf>/qm/current_q
-Date: Sep 2019
-Contact: linux-crypto@vger.kernel.org
-Description: One QM may contain multiple queues. Select specific queue to
+What: /sys/kernel/debug/hisi_hpre/<bdf>/qm/current_q
+Date: Sep 2019
+Contact: linux-crypto@vger.kernel.org
+Description: One QM may contain multiple queues. Select specific queue to
show its debug registers in above regs.
Only available for PF.
-What: /sys/kernel/debug/hisi_hpre/<bdf>/qm/clear_enable
-Date: Sep 2019
-Contact: linux-crypto@vger.kernel.org
-Description: QM debug registers(regs) read clear control. 1 means enable
+What: /sys/kernel/debug/hisi_hpre/<bdf>/qm/clear_enable
+Date: Sep 2019
+Contact: linux-crypto@vger.kernel.org
+Description: QM debug registers(regs) read clear control. 1 means enable
register read clear, otherwise 0.
Writing to this file has no functional effect, only enable or
disable counters clear after reading of these registers.
Only available for PF.
-What: /sys/kernel/debug/hisi_hpre/<bdf>/qm/err_irq
-Date: Apr 2020
-Contact: linux-crypto@vger.kernel.org
-Description: Dump the number of invalid interrupts for
+What: /sys/kernel/debug/hisi_hpre/<bdf>/qm/err_irq
+Date: Apr 2020
+Contact: linux-crypto@vger.kernel.org
+Description: Dump the number of invalid interrupts for
QM task completion.
Available for both PF and VF, and take no other effect on HPRE.
-What: /sys/kernel/debug/hisi_hpre/<bdf>/qm/aeq_irq
-Date: Apr 2020
-Contact: linux-crypto@vger.kernel.org
-Description: Dump the number of QM async event queue interrupts.
+What: /sys/kernel/debug/hisi_hpre/<bdf>/qm/aeq_irq
+Date: Apr 2020
+Contact: linux-crypto@vger.kernel.org
+Description: Dump the number of QM async event queue interrupts.
Available for both PF and VF, and take no other effect on HPRE.
-What: /sys/kernel/debug/hisi_hpre/<bdf>/qm/abnormal_irq
-Date: Apr 2020
-Contact: linux-crypto@vger.kernel.org
-Description: Dump the number of interrupts for QM abnormal event.
+What: /sys/kernel/debug/hisi_hpre/<bdf>/qm/abnormal_irq
+Date: Apr 2020
+Contact: linux-crypto@vger.kernel.org
+Description: Dump the number of interrupts for QM abnormal event.
Available for both PF and VF, and take no other effect on HPRE.
-What: /sys/kernel/debug/hisi_hpre/<bdf>/qm/create_qp_err
-Date: Apr 2020
-Contact: linux-crypto@vger.kernel.org
-Description: Dump the number of queue allocation errors.
+What: /sys/kernel/debug/hisi_hpre/<bdf>/qm/create_qp_err
+Date: Apr 2020
+Contact: linux-crypto@vger.kernel.org
+Description: Dump the number of queue allocation errors.
Available for both PF and VF, and take no other effect on HPRE.
-What: /sys/kernel/debug/hisi_hpre/<bdf>/qm/mb_err
-Date: Apr 2020
-Contact: linux-crypto@vger.kernel.org
-Description: Dump the number of failed QM mailbox commands.
+What: /sys/kernel/debug/hisi_hpre/<bdf>/qm/mb_err
+Date: Apr 2020
+Contact: linux-crypto@vger.kernel.org
+Description: Dump the number of failed QM mailbox commands.
Available for both PF and VF, and take no other effect on HPRE.
-What: /sys/kernel/debug/hisi_hpre/<bdf>/qm/status
-Date: Apr 2020
-Contact: linux-crypto@vger.kernel.org
-Description: Dump the status of the QM.
+What: /sys/kernel/debug/hisi_hpre/<bdf>/qm/status
+Date: Apr 2020
+Contact: linux-crypto@vger.kernel.org
+Description: Dump the status of the QM.
Four states: initiated, started, stopped and closed.
Available for both PF and VF, and take no other effect on HPRE.
-What: /sys/kernel/debug/hisi_hpre/<bdf>/hpre_dfx/send_cnt
-Date: Apr 2020
-Contact: linux-crypto@vger.kernel.org
-Description: Dump the total number of sent requests.
+What: /sys/kernel/debug/hisi_hpre/<bdf>/hpre_dfx/send_cnt
+Date: Apr 2020
+Contact: linux-crypto@vger.kernel.org
+Description: Dump the total number of sent requests.
Available for both PF and VF, and take no other effect on HPRE.
-What: /sys/kernel/debug/hisi_hpre/<bdf>/hpre_dfx/recv_cnt
-Date: Apr 2020
-Contact: linux-crypto@vger.kernel.org
-Description: Dump the total number of received requests.
+What: /sys/kernel/debug/hisi_hpre/<bdf>/hpre_dfx/recv_cnt
+Date: Apr 2020
+Contact: linux-crypto@vger.kernel.org
+Description: Dump the total number of received requests.
Available for both PF and VF, and take no other effect on HPRE.
-What: /sys/kernel/debug/hisi_hpre/<bdf>/hpre_dfx/send_busy_cnt
-Date: Apr 2020
-Contact: linux-crypto@vger.kernel.org
-Description: Dump the total number of requests sent
+What: /sys/kernel/debug/hisi_hpre/<bdf>/hpre_dfx/send_busy_cnt
+Date: Apr 2020
+Contact: linux-crypto@vger.kernel.org
+Description: Dump the total number of requests sent
with returning busy.
Available for both PF and VF, and take no other effect on HPRE.
-What: /sys/kernel/debug/hisi_hpre/<bdf>/hpre_dfx/send_fail_cnt
-Date: Apr 2020
-Contact: linux-crypto@vger.kernel.org
-Description: Dump the total number of completed but error requests.
+What: /sys/kernel/debug/hisi_hpre/<bdf>/hpre_dfx/send_fail_cnt
+Date: Apr 2020
+Contact: linux-crypto@vger.kernel.org
+Description: Dump the total number of completed but error requests.
Available for both PF and VF, and take no other effect on HPRE.
-What: /sys/kernel/debug/hisi_hpre/<bdf>/hpre_dfx/invalid_req_cnt
-Date: Apr 2020
-Contact: linux-crypto@vger.kernel.org
-Description: Dump the total number of invalid requests being received.
+What: /sys/kernel/debug/hisi_hpre/<bdf>/hpre_dfx/invalid_req_cnt
+Date: Apr 2020
+Contact: linux-crypto@vger.kernel.org
+Description: Dump the total number of invalid requests being received.
Available for both PF and VF, and take no other effect on HPRE.
-What: /sys/kernel/debug/hisi_hpre/<bdf>/hpre_dfx/overtime_thrhld
-Date: Apr 2020
-Contact: linux-crypto@vger.kernel.org
-Description: Set the threshold time for counting the request which is
+What: /sys/kernel/debug/hisi_hpre/<bdf>/hpre_dfx/overtime_thrhld
+Date: Apr 2020
+Contact: linux-crypto@vger.kernel.org
+Description: Set the threshold time for counting the request which is
processed longer than the threshold.
0: disable(default), 1: 1 microsecond.
Available for both PF and VF, and take no other effect on HPRE.
-What: /sys/kernel/debug/hisi_hpre/<bdf>/hpre_dfx/over_thrhld_cnt
-Date: Apr 2020
-Contact: linux-crypto@vger.kernel.org
-Description: Dump the total number of time out requests.
+What: /sys/kernel/debug/hisi_hpre/<bdf>/hpre_dfx/over_thrhld_cnt
+Date: Apr 2020
+Contact: linux-crypto@vger.kernel.org
+Description: Dump the total number of time out requests.
Available for both PF and VF, and take no other effect on HPRE.
diff --git a/Documentation/ABI/testing/debugfs-hisi-sec b/Documentation/ABI/testing/debugfs-hisi-sec
index 85feb4408e0f..2bf84ced484b 100644
--- a/Documentation/ABI/testing/debugfs-hisi-sec
+++ b/Documentation/ABI/testing/debugfs-hisi-sec
@@ -1,113 +1,123 @@
-What: /sys/kernel/debug/hisi_sec2/<bdf>/clear_enable
-Date: Oct 2019
-Contact: linux-crypto@vger.kernel.org
-Description: Enabling/disabling of clear action after reading
+What: /sys/kernel/debug/hisi_sec2/<bdf>/clear_enable
+Date: Oct 2019
+Contact: linux-crypto@vger.kernel.org
+Description: Enabling/disabling of clear action after reading
the SEC debug registers.
0: disable, 1: enable.
Only available for PF, and take no other effect on SEC.
-What: /sys/kernel/debug/hisi_sec2/<bdf>/current_qm
-Date: Oct 2019
-Contact: linux-crypto@vger.kernel.org
-Description: One SEC controller has one PF and multiple VFs, each function
+What: /sys/kernel/debug/hisi_sec2/<bdf>/current_qm
+Date: Oct 2019
+Contact: linux-crypto@vger.kernel.org
+Description: One SEC controller has one PF and multiple VFs, each function
has a QM. This file can be used to select the QM which below
qm refers to.
Only available for PF.
-What: /sys/kernel/debug/hisi_sec2/<bdf>/qm/qm_regs
-Date: Oct 2019
-Contact: linux-crypto@vger.kernel.org
-Description: Dump of QM related debug registers.
+What: /sys/kernel/debug/hisi_sec2/<bdf>/alg_qos
+Date: Jun 2021
+Contact: linux-crypto@vger.kernel.org
+Description: The <bdf> is related the function for PF and VF.
+ SEC driver supports to configure each function's QoS, the driver
+ supports to write <bdf> value to alg_qos in the host. Such as
+ "echo <bdf> value > alg_qos". The qos value is 1~1000, means
+ 1/1000~1000/1000 of total QoS. The driver reading alg_qos to
+ get related QoS in the host and VM, Such as "cat alg_qos".
+
+What: /sys/kernel/debug/hisi_sec2/<bdf>/qm/qm_regs
+Date: Oct 2019
+Contact: linux-crypto@vger.kernel.org
+Description: Dump of QM related debug registers.
Available for PF and VF in host. VF in guest currently only
has one debug register.
-What: /sys/kernel/debug/hisi_sec2/<bdf>/qm/current_q
-Date: Oct 2019
-Contact: linux-crypto@vger.kernel.org
-Description: One QM of SEC may contain multiple queues. Select specific
+What: /sys/kernel/debug/hisi_sec2/<bdf>/qm/current_q
+Date: Oct 2019
+Contact: linux-crypto@vger.kernel.org
+Description: One QM of SEC may contain multiple queues. Select specific
queue to show its debug registers in above 'regs'.
Only available for PF.
-What: /sys/kernel/debug/hisi_sec2/<bdf>/qm/clear_enable
-Date: Oct 2019
-Contact: linux-crypto@vger.kernel.org
-Description: Enabling/disabling of clear action after reading
+What: /sys/kernel/debug/hisi_sec2/<bdf>/qm/clear_enable
+Date: Oct 2019
+Contact: linux-crypto@vger.kernel.org
+Description: Enabling/disabling of clear action after reading
the SEC's QM debug registers.
0: disable, 1: enable.
Only available for PF, and take no other effect on SEC.
-What: /sys/kernel/debug/hisi_sec2/<bdf>/qm/err_irq
-Date: Apr 2020
-Contact: linux-crypto@vger.kernel.org
-Description: Dump the number of invalid interrupts for
+What: /sys/kernel/debug/hisi_sec2/<bdf>/qm/err_irq
+Date: Apr 2020
+Contact: linux-crypto@vger.kernel.org
+Description: Dump the number of invalid interrupts for
QM task completion.
Available for both PF and VF, and take no other effect on SEC.
-What: /sys/kernel/debug/hisi_sec2/<bdf>/qm/aeq_irq
-Date: Apr 2020
-Contact: linux-crypto@vger.kernel.org
-Description: Dump the number of QM async event queue interrupts.
+What: /sys/kernel/debug/hisi_sec2/<bdf>/qm/aeq_irq
+Date: Apr 2020
+Contact: linux-crypto@vger.kernel.org
+Description: Dump the number of QM async event queue interrupts.
Available for both PF and VF, and take no other effect on SEC.
-What: /sys/kernel/debug/hisi_sec2/<bdf>/qm/abnormal_irq
-Date: Apr 2020
-Contact: linux-crypto@vger.kernel.org
-Description: Dump the number of interrupts for QM abnormal event.
+What: /sys/kernel/debug/hisi_sec2/<bdf>/qm/abnormal_irq
+Date: Apr 2020
+Contact: linux-crypto@vger.kernel.org
+Description: Dump the number of interrupts for QM abnormal event.
Available for both PF and VF, and take no other effect on SEC.
-What: /sys/kernel/debug/hisi_sec2/<bdf>/qm/create_qp_err
-Date: Apr 2020
-Contact: linux-crypto@vger.kernel.org
-Description: Dump the number of queue allocation errors.
+What: /sys/kernel/debug/hisi_sec2/<bdf>/qm/create_qp_err
+Date: Apr 2020
+Contact: linux-crypto@vger.kernel.org
+Description: Dump the number of queue allocation errors.
Available for both PF and VF, and take no other effect on SEC.
-What: /sys/kernel/debug/hisi_sec2/<bdf>/qm/mb_err
-Date: Apr 2020
-Contact: linux-crypto@vger.kernel.org
-Description: Dump the number of failed QM mailbox commands.
+What: /sys/kernel/debug/hisi_sec2/<bdf>/qm/mb_err
+Date: Apr 2020
+Contact: linux-crypto@vger.kernel.org
+Description: Dump the number of failed QM mailbox commands.
Available for both PF and VF, and take no other effect on SEC.
-What: /sys/kernel/debug/hisi_sec2/<bdf>/qm/status
-Date: Apr 2020
-Contact: linux-crypto@vger.kernel.org
-Description: Dump the status of the QM.
+What: /sys/kernel/debug/hisi_sec2/<bdf>/qm/status
+Date: Apr 2020
+Contact: linux-crypto@vger.kernel.org
+Description: Dump the status of the QM.
Four states: initiated, started, stopped and closed.
Available for both PF and VF, and take no other effect on SEC.
-What: /sys/kernel/debug/hisi_sec2/<bdf>/sec_dfx/send_cnt
-Date: Apr 2020
-Contact: linux-crypto@vger.kernel.org
-Description: Dump the total number of sent requests.
+What: /sys/kernel/debug/hisi_sec2/<bdf>/sec_dfx/send_cnt
+Date: Apr 2020
+Contact: linux-crypto@vger.kernel.org
+Description: Dump the total number of sent requests.
Available for both PF and VF, and take no other effect on SEC.
-What: /sys/kernel/debug/hisi_sec2/<bdf>/sec_dfx/recv_cnt
-Date: Apr 2020
-Contact: linux-crypto@vger.kernel.org
-Description: Dump the total number of received requests.
+What: /sys/kernel/debug/hisi_sec2/<bdf>/sec_dfx/recv_cnt
+Date: Apr 2020
+Contact: linux-crypto@vger.kernel.org
+Description: Dump the total number of received requests.
Available for both PF and VF, and take no other effect on SEC.
-What: /sys/kernel/debug/hisi_sec2/<bdf>/sec_dfx/send_busy_cnt
-Date: Apr 2020
-Contact: linux-crypto@vger.kernel.org
-Description: Dump the total number of requests sent with returning busy.
+What: /sys/kernel/debug/hisi_sec2/<bdf>/sec_dfx/send_busy_cnt
+Date: Apr 2020
+Contact: linux-crypto@vger.kernel.org
+Description: Dump the total number of requests sent with returning busy.
Available for both PF and VF, and take no other effect on SEC.
-What: /sys/kernel/debug/hisi_sec2/<bdf>/sec_dfx/err_bd_cnt
-Date: Apr 2020
-Contact: linux-crypto@vger.kernel.org
-Description: Dump the total number of BD type error requests
+What: /sys/kernel/debug/hisi_sec2/<bdf>/sec_dfx/err_bd_cnt
+Date: Apr 2020
+Contact: linux-crypto@vger.kernel.org
+Description: Dump the total number of BD type error requests
to be received.
Available for both PF and VF, and take no other effect on SEC.
-What: /sys/kernel/debug/hisi_sec2/<bdf>/sec_dfx/invalid_req_cnt
-Date: Apr 2020
-Contact: linux-crypto@vger.kernel.org
-Description: Dump the total number of invalid requests being received.
+What: /sys/kernel/debug/hisi_sec2/<bdf>/sec_dfx/invalid_req_cnt
+Date: Apr 2020
+Contact: linux-crypto@vger.kernel.org
+Description: Dump the total number of invalid requests being received.
Available for both PF and VF, and take no other effect on SEC.
-What: /sys/kernel/debug/hisi_sec2/<bdf>/sec_dfx/done_flag_cnt
-Date: Apr 2020
-Contact: linux-crypto@vger.kernel.org
-Description: Dump the total number of completed but marked error requests
+What: /sys/kernel/debug/hisi_sec2/<bdf>/sec_dfx/done_flag_cnt
+Date: Apr 2020
+Contact: linux-crypto@vger.kernel.org
+Description: Dump the total number of completed but marked error requests
to be received.
Available for both PF and VF, and take no other effect on SEC.
diff --git a/Documentation/ABI/testing/debugfs-hisi-zip b/Documentation/ABI/testing/debugfs-hisi-zip
index 3034a2bf99ca..bf1258bc6495 100644
--- a/Documentation/ABI/testing/debugfs-hisi-zip
+++ b/Documentation/ABI/testing/debugfs-hisi-zip
@@ -1,114 +1,124 @@
-What: /sys/kernel/debug/hisi_zip/<bdf>/comp_core[01]/regs
-Date: Nov 2018
-Contact: linux-crypto@vger.kernel.org
-Description: Dump of compression cores related debug registers.
+What: /sys/kernel/debug/hisi_zip/<bdf>/comp_core[01]/regs
+Date: Nov 2018
+Contact: linux-crypto@vger.kernel.org
+Description: Dump of compression cores related debug registers.
Only available for PF.
-What: /sys/kernel/debug/hisi_zip/<bdf>/decomp_core[0-5]/regs
-Date: Nov 2018
-Contact: linux-crypto@vger.kernel.org
-Description: Dump of decompression cores related debug registers.
+What: /sys/kernel/debug/hisi_zip/<bdf>/decomp_core[0-5]/regs
+Date: Nov 2018
+Contact: linux-crypto@vger.kernel.org
+Description: Dump of decompression cores related debug registers.
Only available for PF.
-What: /sys/kernel/debug/hisi_zip/<bdf>/clear_enable
-Date: Nov 2018
-Contact: linux-crypto@vger.kernel.org
-Description: Compression/decompression core debug registers read clear
+What: /sys/kernel/debug/hisi_zip/<bdf>/clear_enable
+Date: Nov 2018
+Contact: linux-crypto@vger.kernel.org
+Description: Compression/decompression core debug registers read clear
control. 1 means enable register read clear, otherwise 0.
Writing to this file has no functional effect, only enable or
disable counters clear after reading of these registers.
Only available for PF.
-What: /sys/kernel/debug/hisi_zip/<bdf>/current_qm
-Date: Nov 2018
-Contact: linux-crypto@vger.kernel.org
-Description: One ZIP controller has one PF and multiple VFs, each function
+What: /sys/kernel/debug/hisi_zip/<bdf>/current_qm
+Date: Nov 2018
+Contact: linux-crypto@vger.kernel.org
+Description: One ZIP controller has one PF and multiple VFs, each function
has a QM. Select the QM which below qm refers to.
Only available for PF.
-What: /sys/kernel/debug/hisi_zip/<bdf>/qm/regs
-Date: Nov 2018
-Contact: linux-crypto@vger.kernel.org
-Description: Dump of QM related debug registers.
+What: /sys/kernel/debug/hisi_zip/<bdf>/alg_qos
+Date: Jun 2021
+Contact: linux-crypto@vger.kernel.org
+Description: The <bdf> is related the function for PF and VF.
+ ZIP driver supports to configure each function's QoS, the driver
+ supports to write <bdf> value to alg_qos in the host. Such as
+ "echo <bdf> value > alg_qos". The qos value is 1~1000, means
+ 1/1000~1000/1000 of total QoS. The driver reading alg_qos to
+ get related QoS in the host and VM, Such as "cat alg_qos".
+
+What: /sys/kernel/debug/hisi_zip/<bdf>/qm/regs
+Date: Nov 2018
+Contact: linux-crypto@vger.kernel.org
+Description: Dump of QM related debug registers.
Available for PF and VF in host. VF in guest currently only
has one debug register.
-What: /sys/kernel/debug/hisi_zip/<bdf>/qm/current_q
-Date: Nov 2018
-Contact: linux-crypto@vger.kernel.org
-Description: One QM may contain multiple queues. Select specific queue to
+What: /sys/kernel/debug/hisi_zip/<bdf>/qm/current_q
+Date: Nov 2018
+Contact: linux-crypto@vger.kernel.org
+Description: One QM may contain multiple queues. Select specific queue to
show its debug registers in above regs.
Only available for PF.
-What: /sys/kernel/debug/hisi_zip/<bdf>/qm/clear_enable
-Date: Nov 2018
-Contact: linux-crypto@vger.kernel.org
-Description: QM debug registers(regs) read clear control. 1 means enable
+What: /sys/kernel/debug/hisi_zip/<bdf>/qm/clear_enable
+Date: Nov 2018
+Contact: linux-crypto@vger.kernel.org
+Description: QM debug registers(regs) read clear control. 1 means enable
register read clear, otherwise 0.
Writing to this file has no functional effect, only enable or
disable counters clear after reading of these registers.
Only available for PF.
-What: /sys/kernel/debug/hisi_zip/<bdf>/qm/err_irq
-Date: Apr 2020
-Contact: linux-crypto@vger.kernel.org
-Description: Dump the number of invalid interrupts for
+What: /sys/kernel/debug/hisi_zip/<bdf>/qm/err_irq
+Date: Apr 2020
+Contact: linux-crypto@vger.kernel.org
+Description: Dump the number of invalid interrupts for
QM task completion.
Available for both PF and VF, and take no other effect on ZIP.
-What: /sys/kernel/debug/hisi_zip/<bdf>/qm/aeq_irq
-Date: Apr 2020
-Contact: linux-crypto@vger.kernel.org
-Description: Dump the number of QM async event queue interrupts.
+What: /sys/kernel/debug/hisi_zip/<bdf>/qm/aeq_irq
+Date: Apr 2020
+Contact: linux-crypto@vger.kernel.org
+Description: Dump the number of QM async event queue interrupts.
Available for both PF and VF, and take no other effect on ZIP.
-What: /sys/kernel/debug/hisi_zip/<bdf>/qm/abnormal_irq
-Date: Apr 2020
-Contact: linux-crypto@vger.kernel.org
-Description: Dump the number of interrupts for QM abnormal event.
+What: /sys/kernel/debug/hisi_zip/<bdf>/qm/abnormal_irq
+Date: Apr 2020
+Contact: linux-crypto@vger.kernel.org
+Description: Dump the number of interrupts for QM abnormal event.
Available for both PF and VF, and take no other effect on ZIP.
-What: /sys/kernel/debug/hisi_zip/<bdf>/qm/create_qp_err
-Date: Apr 2020
-Contact: linux-crypto@vger.kernel.org
-Description: Dump the number of queue allocation errors.
+What: /sys/kernel/debug/hisi_zip/<bdf>/qm/create_qp_err
+Date: Apr 2020
+Contact: linux-crypto@vger.kernel.org
+Description: Dump the number of queue allocation errors.
Available for both PF and VF, and take no other effect on ZIP.
-What: /sys/kernel/debug/hisi_zip/<bdf>/qm/mb_err
-Date: Apr 2020
-Contact: linux-crypto@vger.kernel.org
-Description: Dump the number of failed QM mailbox commands.
+What: /sys/kernel/debug/hisi_zip/<bdf>/qm/mb_err
+Date: Apr 2020
+Contact: linux-crypto@vger.kernel.org
+Description: Dump the number of failed QM mailbox commands.
Available for both PF and VF, and take no other effect on ZIP.
-What: /sys/kernel/debug/hisi_zip/<bdf>/qm/status
-Date: Apr 2020
-Contact: linux-crypto@vger.kernel.org
-Description: Dump the status of the QM.
+What: /sys/kernel/debug/hisi_zip/<bdf>/qm/status
+Date: Apr 2020
+Contact: linux-crypto@vger.kernel.org
+Description: Dump the status of the QM.
Four states: initiated, started, stopped and closed.
Available for both PF and VF, and take no other effect on ZIP.
-What: /sys/kernel/debug/hisi_zip/<bdf>/zip_dfx/send_cnt
-Date: Apr 2020
-Contact: linux-crypto@vger.kernel.org
-Description: Dump the total number of sent requests.
+What: /sys/kernel/debug/hisi_zip/<bdf>/zip_dfx/send_cnt
+Date: Apr 2020
+Contact: linux-crypto@vger.kernel.org
+Description: Dump the total number of sent requests.
Available for both PF and VF, and take no other effect on ZIP.
-What: /sys/kernel/debug/hisi_zip/<bdf>/zip_dfx/recv_cnt
-Date: Apr 2020
-Contact: linux-crypto@vger.kernel.org
-Description: Dump the total number of received requests.
+What: /sys/kernel/debug/hisi_zip/<bdf>/zip_dfx/recv_cnt
+Date: Apr 2020
+Contact: linux-crypto@vger.kernel.org
+Description: Dump the total number of received requests.
Available for both PF and VF, and take no other effect on ZIP.
-What: /sys/kernel/debug/hisi_zip/<bdf>/zip_dfx/send_busy_cnt
-Date: Apr 2020
-Contact: linux-crypto@vger.kernel.org
-Description: Dump the total number of requests received
+What: /sys/kernel/debug/hisi_zip/<bdf>/zip_dfx/send_busy_cnt
+Date: Apr 2020
+Contact: linux-crypto@vger.kernel.org
+Description: Dump the total number of requests received
with returning busy.
Available for both PF and VF, and take no other effect on ZIP.
-What: /sys/kernel/debug/hisi_zip/<bdf>/zip_dfx/err_bd_cnt
-Date: Apr 2020
-Contact: linux-crypto@vger.kernel.org
-Description: Dump the total number of BD type error requests
+What: /sys/kernel/debug/hisi_zip/<bdf>/zip_dfx/err_bd_cnt
+Date: Apr 2020
+Contact: linux-crypto@vger.kernel.org
+Description: Dump the total number of BD type error requests
to be received.
Available for both PF and VF, and take no other effect on ZIP.
diff --git a/Documentation/ABI/testing/sysfs-bus-cxl b/Documentation/ABI/testing/sysfs-bus-cxl
index 0b6a2e6e8fbb..7c2b846521f3 100644
--- a/Documentation/ABI/testing/sysfs-bus-cxl
+++ b/Documentation/ABI/testing/sysfs-bus-cxl
@@ -1,3 +1,12 @@
+What: /sys/bus/cxl/flush
+Date: Januarry, 2022
+KernelVersion: v5.18
+Contact: linux-cxl@vger.kernel.org
+Description:
+ (WO) If userspace manually unbinds a port the kernel schedules
+ all descendant memdevs for unbind. Writing '1' to this attribute
+ flushes that work.
+
What: /sys/bus/cxl/devices/memX/firmware_version
Date: December, 2020
KernelVersion: v5.12
@@ -25,6 +34,24 @@ Description:
identically named field in the Identify Memory Device Output
Payload in the CXL-2.0 specification.
+What: /sys/bus/cxl/devices/memX/serial
+Date: January, 2022
+KernelVersion: v5.18
+Contact: linux-cxl@vger.kernel.org
+Description:
+ (RO) 64-bit serial number per the PCIe Device Serial Number
+ capability. Mandatory for CXL devices, see CXL 2.0 8.1.12.2
+ Memory Device PCIe Capabilities and Extended Capabilities.
+
+What: /sys/bus/cxl/devices/memX/numa_node
+Date: January, 2022
+KernelVersion: v5.18
+Contact: linux-cxl@vger.kernel.org
+Description:
+ (RO) If NUMA is enabled and the platform has affinitized the
+ host PCI device for this memory device, emit the CPU node
+ affinity for this device.
+
What: /sys/bus/cxl/devices/*/devtype
Date: June, 2021
KernelVersion: v5.14
@@ -34,6 +61,15 @@ Description:
the same value communicated in the DEVTYPE environment variable
for uevents for devices on the "cxl" bus.
+What: /sys/bus/cxl/devices/*/modalias
+Date: December, 2021
+KernelVersion: v5.18
+Contact: linux-cxl@vger.kernel.org
+Description:
+ CXL device objects export the modalias attribute which mirrors
+ the same value communicated in the MODALIAS environment variable
+ for uevents for devices on the "cxl" bus.
+
What: /sys/bus/cxl/devices/portX/uport
Date: June, 2021
KernelVersion: v5.14
diff --git a/Documentation/ABI/testing/sysfs-class-hwmon b/Documentation/ABI/testing/sysfs-class-hwmon
index 1f20687def44..653d4c75eddb 100644
--- a/Documentation/ABI/testing/sysfs-class-hwmon
+++ b/Documentation/ABI/testing/sysfs-class-hwmon
@@ -9,6 +9,14 @@ Description:
RO
+What: /sys/class/hwmon/hwmonX/label
+Description:
+ A descriptive label that allows to uniquely identify a
+ device within the system.
+ The contents of the label are free-form.
+
+ RO
+
What: /sys/class/hwmon/hwmonX/update_interval
Description:
The interval at which the chip will update readings.
diff --git a/Documentation/ABI/testing/sysfs-class-power b/Documentation/ABI/testing/sysfs-class-power
index fde21d900420..859501366777 100644
--- a/Documentation/ABI/testing/sysfs-class-power
+++ b/Documentation/ABI/testing/sysfs-class-power
@@ -468,6 +468,7 @@ Description:
auto: Charge normally, respect thresholds
inhibit-charge: Do not charge while AC is attached
force-discharge: Force discharge while AC is attached
+ ================ ====================================
What: /sys/class/power_supply/<supply_name>/technology
Date: May 2007
diff --git a/Documentation/ABI/testing/sysfs-class-thermal b/Documentation/ABI/testing/sysfs-class-thermal
index 2c52bb1f864c..8eee37982b2a 100644
--- a/Documentation/ABI/testing/sysfs-class-thermal
+++ b/Documentation/ABI/testing/sysfs-class-thermal
@@ -203,7 +203,7 @@ Description:
- for generic ACPI: should be "Fan", "Processor" or "LCD"
- for memory controller device on intel_menlow platform:
- should be "Memory controller".
+ should be "Memory controller".
RO, Required
diff --git a/Documentation/ABI/testing/sysfs-devices-system-cpu b/Documentation/ABI/testing/sysfs-devices-system-cpu
index 61f5676a7429..2ad01cad7f1c 100644
--- a/Documentation/ABI/testing/sysfs-devices-system-cpu
+++ b/Documentation/ABI/testing/sysfs-devices-system-cpu
@@ -73,6 +73,7 @@ What: /sys/devices/system/cpu/cpuX/topology/core_id
/sys/devices/system/cpu/cpuX/topology/physical_package_id
/sys/devices/system/cpu/cpuX/topology/thread_siblings
/sys/devices/system/cpu/cpuX/topology/thread_siblings_list
+ /sys/devices/system/cpu/cpuX/topology/ppin
Date: December 2008
Contact: Linux kernel mailing list <linux-kernel@vger.kernel.org>
Description: CPU topology files that describe a logical CPU's relationship
@@ -103,6 +104,11 @@ Description: CPU topology files that describe a logical CPU's relationship
thread_siblings_list: human-readable list of cpuX's hardware
threads within the same core as cpuX
+ ppin: human-readable Protected Processor Identification
+ Number of the socket the cpu# belongs to. There should be
+ one per physical_package_id. File is readable only to
+ admin.
+
See Documentation/admin-guide/cputopology.rst for more information.
@@ -662,6 +668,7 @@ Description: Preferred MTE tag checking mode
================ ==============================================
"sync" Prefer synchronous mode
+ "asymm" Prefer asymmetric mode
"async" Prefer asynchronous mode
================ ==============================================
diff --git a/Documentation/ABI/testing/sysfs-driver-aspeed-uart-routing b/Documentation/ABI/testing/sysfs-driver-aspeed-uart-routing
index b363827da437..910df0e5815a 100644
--- a/Documentation/ABI/testing/sysfs-driver-aspeed-uart-routing
+++ b/Documentation/ABI/testing/sysfs-driver-aspeed-uart-routing
@@ -1,4 +1,4 @@
-What: /sys/bus/platform/drivers/aspeed-uart-routing/*/uart*
+What: /sys/bus/platform/drivers/aspeed-uart-routing/\*/uart\*
Date: September 2021
Contact: Oskar Senft <osk@google.com>
Chia-Wei Wang <chiawei_wang@aspeedtech.com>
@@ -9,7 +9,7 @@ Description: Selects the RX source of the UARTx device.
depends on the selected file.
e.g.
- cat /sys/bus/platform/drivers/aspeed-uart-routing/*.uart_routing/uart1
+ cat /sys/bus/platform/drivers/aspeed-uart-routing/\*.uart_routing/uart1
[io1] io2 io3 io4 uart2 uart3 uart4 io6
In this case, UART1 gets its input from IO1 (physical serial port 1).
@@ -17,7 +17,7 @@ Description: Selects the RX source of the UARTx device.
Users: OpenBMC. Proposed changes should be mailed to
openbmc@lists.ozlabs.org
-What: /sys/bus/platform/drivers/aspeed-uart-routing/*/io*
+What: /sys/bus/platform/drivers/aspeed-uart-routing/\*/io\*
Date: September 2021
Contact: Oskar Senft <osk@google.com>
Chia-Wei Wang <chiawei_wang@aspeedtech.com>
diff --git a/Documentation/ABI/testing/sysfs-fs-f2fs b/Documentation/ABI/testing/sysfs-fs-f2fs
index 2416b03ff283..9b583dd0298b 100644
--- a/Documentation/ABI/testing/sysfs-fs-f2fs
+++ b/Documentation/ABI/testing/sysfs-fs-f2fs
@@ -55,8 +55,9 @@ Description: Controls the in-place-update policy.
0x04 F2FS_IPU_UTIL
0x08 F2FS_IPU_SSR_UTIL
0x10 F2FS_IPU_FSYNC
- 0x20 F2FS_IPU_ASYNC,
+ 0x20 F2FS_IPU_ASYNC
0x40 F2FS_IPU_NOCACHE
+ 0x80 F2FS_IPU_HONOR_OPU_WRITE
==== =================
Refer segment.h for details.
@@ -98,6 +99,33 @@ Description: Controls the issue rate of discard commands that consist of small
checkpoint is triggered, and issued during the checkpoint.
By default, it is disabled with 0.
+What: /sys/fs/f2fs/<disk>/max_discard_request
+Date: December 2021
+Contact: "Konstantin Vyshetsky" <vkon@google.com>
+Description: Controls the number of discards a thread will issue at a time.
+ Higher number will allow the discard thread to finish its work
+ faster, at the cost of higher latency for incomming I/O.
+
+What: /sys/fs/f2fs/<disk>/min_discard_issue_time
+Date: December 2021
+Contact: "Konstantin Vyshetsky" <vkon@google.com>
+Description: Controls the interval the discard thread will wait between
+ issuing discard requests when there are discards to be issued and
+ no I/O aware interruptions occur.
+
+What: /sys/fs/f2fs/<disk>/mid_discard_issue_time
+Date: December 2021
+Contact: "Konstantin Vyshetsky" <vkon@google.com>
+Description: Controls the interval the discard thread will wait between
+ issuing discard requests when there are discards to be issued and
+ an I/O aware interruption occurs.
+
+What: /sys/fs/f2fs/<disk>/max_discard_issue_time
+Date: December 2021
+Contact: "Konstantin Vyshetsky" <vkon@google.com>
+Description: Controls the interval the discard thread will wait when there are
+ no discard operations to be issued.
+
What: /sys/fs/f2fs/<disk>/discard_granularity
Date: July 2017
Contact: "Chao Yu" <yuchao0@huawei.com>
@@ -269,11 +297,16 @@ Description: Shows current reserved blocks in system, it may be temporarily
What: /sys/fs/f2fs/<disk>/gc_urgent
Date: August 2017
Contact: "Jaegeuk Kim" <jaegeuk@kernel.org>
-Description: Do background GC aggressively when set. When gc_urgent = 1,
- background thread starts to do GC by given gc_urgent_sleep_time
- interval. When gc_urgent = 2, F2FS will lower the bar of
- checking idle in order to process outstanding discard commands
- and GC a little bit aggressively. It is set to 0 by default.
+Description: Do background GC aggressively when set. Set to 0 by default.
+ gc urgent high(1): does GC forcibly in a period of given
+ gc_urgent_sleep_time and ignores I/O idling check. uses greedy
+ GC approach and turns SSR mode on.
+ gc urgent low(2): lowers the bar of checking I/O idling in
+ order to process outstanding discard commands and GC a
+ little bit aggressively. uses cost benefit GC approach.
+ gc urgent mid(3): does GC forcibly in a period of given
+ gc_urgent_sleep_time and executes a mid level of I/O idling check.
+ uses cost benefit GC approach.
What: /sys/fs/f2fs/<disk>/gc_urgent_sleep_time
Date: August 2017
@@ -430,6 +463,7 @@ Description: Show status of f2fs superblock in real time.
0x800 SBI_QUOTA_SKIP_FLUSH skip flushing quota in current CP
0x1000 SBI_QUOTA_NEED_REPAIR quota file may be corrupted
0x2000 SBI_IS_RESIZEFS resizefs is in process
+ 0x4000 SBI_IS_FREEZING freefs is in process
====== ===================== =================================
What: /sys/fs/f2fs/<disk>/ckpt_thread_ioprio
@@ -503,7 +537,7 @@ Date: July 2021
Contact: "Daeho Jeong" <daehojeong@google.com>
Description: Show how many segments have been reclaimed by GC during a specific
GC mode (0: GC normal, 1: GC idle CB, 2: GC idle greedy,
- 3: GC idle AT, 4: GC urgent high, 5: GC urgent low)
+ 3: GC idle AT, 4: GC urgent high, 5: GC urgent low 6: GC urgent mid)
You can re-initialize this value to "0".
What: /sys/fs/f2fs/<disk>/gc_segment_mode
@@ -540,3 +574,9 @@ Contact: "Daeho Jeong" <daehojeong@google.com>
Description: You can set the trial count limit for GC urgent high mode with this value.
If GC thread gets to the limit, the mode will turn back to GC normal mode.
By default, the value is zero, which means there is no limit like before.
+
+What: /sys/fs/f2fs/<disk>/max_roll_forward_node_blocks
+Date: January 2022
+Contact: "Jaegeuk Kim" <jaegeuk@kernel.org>
+Description: Controls max # of node block writes to be used for roll forward
+ recovery. This can limit the roll forward recovery time.
diff --git a/Documentation/ABI/testing/sysfs-kernel-mm-damon b/Documentation/ABI/testing/sysfs-kernel-mm-damon
new file mode 100644
index 000000000000..9e282065cbcf
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-kernel-mm-damon
@@ -0,0 +1,274 @@
+what: /sys/kernel/mm/damon/
+Date: Mar 2022
+Contact: SeongJae Park <sj@kernel.org>
+Description: Interface for Data Access MONitoring (DAMON). Contains files
+ for controlling DAMON. For more details on DAMON itself,
+ please refer to Documentation/admin-guide/mm/damon/index.rst.
+
+What: /sys/kernel/mm/damon/admin/
+Date: Mar 2022
+Contact: SeongJae Park <sj@kernel.org>
+Description: Interface for privileged users of DAMON. Contains files for
+ controlling DAMON that aimed to be used by privileged users.
+
+What: /sys/kernel/mm/damon/admin/kdamonds/nr_kdamonds
+Date: Mar 2022
+Contact: SeongJae Park <sj@kernel.org>
+Description: Writing a number 'N' to this file creates the number of
+ directories for controlling each DAMON worker thread (kdamond)
+ named '0' to 'N-1' under the kdamonds/ directory.
+
+What: /sys/kernel/mm/damon/admin/kdamonds/<K>/state
+Date: Mar 2022
+Contact: SeongJae Park <sj@kernel.org>
+Description: Writing 'on' or 'off' to this file makes the kdamond starts or
+ stops, respectively. Reading the file returns the keywords
+ based on the current status. Writing 'update_schemes_stats' to
+ the file updates contents of schemes stats files of the
+ kdamond.
+
+What: /sys/kernel/mm/damon/admin/kdamonds/<K>/pid
+Date: Mar 2022
+Contact: SeongJae Park <sj@kernel.org>
+Description: Reading this file returns the pid of the kdamond if it is
+ running.
+
+What: /sys/kernel/mm/damon/admin/kdamonds/<K>/contexts/nr_contexts
+Date: Mar 2022
+Contact: SeongJae Park <sj@kernel.org>
+Description: Writing a number 'N' to this file creates the number of
+ directories for controlling each DAMON context named '0' to
+ 'N-1' under the contexts/ directory.
+
+What: /sys/kernel/mm/damon/admin/kdamonds/<K>/contexts/<C>/operations
+Date: Mar 2022
+Contact: SeongJae Park <sj@kernel.org>
+Description: Writing a keyword for a monitoring operations set ('vaddr' for
+ virtual address spaces monitoring, and 'paddr' for the physical
+ address space monitoring) to this file makes the context to use
+ the operations set. Reading the file returns the keyword for
+ the operations set the context is set to use.
+
+What: /sys/kernel/mm/damon/admin/kdamonds/<K>/contexts/<C>/monitoring_attrs/intervals/sample_us
+Date: Mar 2022
+Contact: SeongJae Park <sj@kernel.org>
+Description: Writing a value to this file sets the sampling interval of the
+ DAMON context in microseconds as the value. Reading this file
+ returns the value.
+
+What: /sys/kernel/mm/damon/admin/kdamonds/<K>/contexts/<C>/monitoring_attrs/intervals/aggr_us
+Date: Mar 2022
+Contact: SeongJae Park <sj@kernel.org>
+Description: Writing a value to this file sets the aggregation interval of
+ the DAMON context in microseconds as the value. Reading this
+ file returns the value.
+
+What: /sys/kernel/mm/damon/admin/kdamonds/<K>/contexts/<C>/monitoring_attrs/intervals/update_us
+Date: Mar 2022
+Contact: SeongJae Park <sj@kernel.org>
+Description: Writing a value to this file sets the update interval of the
+ DAMON context in microseconds as the value. Reading this file
+ returns the value.
+
+What: /sys/kernel/mm/damon/admin/kdamonds/<K>/contexts/<C>/monitoring_attrs/nr_regions/min
+
+WDate: Mar 2022
+Contact: SeongJae Park <sj@kernel.org>
+Description: Writing a value to this file sets the minimum number of
+ monitoring regions of the DAMON context as the value. Reading
+ this file returns the value.
+
+What: /sys/kernel/mm/damon/admin/kdamonds/<K>/contexts/<C>/monitoring_attrs/nr_regions/max
+Date: Mar 2022
+Contact: SeongJae Park <sj@kernel.org>
+Description: Writing a value to this file sets the maximum number of
+ monitoring regions of the DAMON context as the value. Reading
+ this file returns the value.
+
+What: /sys/kernel/mm/damon/admin/kdamonds/<K>/contexts/<C>/targets/nr_targets
+Date: Mar 2022
+Contact: SeongJae Park <sj@kernel.org>
+Description: Writing a number 'N' to this file creates the number of
+ directories for controlling each DAMON target of the context
+ named '0' to 'N-1' under the contexts/ directory.
+
+What: /sys/kernel/mm/damon/admin/kdamonds/<K>/contexts/<C>/targets/<T>/pid_target
+Date: Mar 2022
+Contact: SeongJae Park <sj@kernel.org>
+Description: Writing to and reading from this file sets and gets the pid of
+ the target process if the context is for virtual address spaces
+ monitoring, respectively.
+
+What: /sys/kernel/mm/damon/admin/kdamonds/<K>/contexts/<C>/targets/<T>/regions/nr_regions
+Date: Mar 2022
+Contact: SeongJae Park <sj@kernel.org>
+Description: Writing a number 'N' to this file creates the number of
+ directories for setting each DAMON target memory region of the
+ context named '0' to 'N-1' under the regions/ directory. In
+ case of the virtual address space monitoring, DAMON
+ automatically sets the target memory region based on the target
+ processes' mappings.
+
+What: /sys/kernel/mm/damon/admin/kdamonds/<K>/contexts/<C>/targets/<T>/regions/<R>/start
+Date: Mar 2022
+Contact: SeongJae Park <sj@kernel.org>
+Description: Writing to and reading from this file sets and gets the start
+ address of the monitoring region.
+
+What: /sys/kernel/mm/damon/admin/kdamonds/<K>/contexts/<C>/targets/<T>/regions/<R>/end
+Date: Mar 2022
+Contact: SeongJae Park <sj@kernel.org>
+Description: Writing to and reading from this file sets and gets the end
+ address of the monitoring region.
+
+What: /sys/kernel/mm/damon/admin/kdamonds/<K>/contexts/<C>/schemes/nr_schemes
+Date: Mar 2022
+Contact: SeongJae Park <sj@kernel.org>
+Description: Writing a number 'N' to this file creates the number of
+ directories for controlling each DAMON-based operation scheme
+ of the context named '0' to 'N-1' under the schemes/ directory.
+
+What: /sys/kernel/mm/damon/admin/kdamonds/<K>/contexts/<C>/schemes/<S>/action
+Date: Mar 2022
+Contact: SeongJae Park <sj@kernel.org>
+Description: Writing to and reading from this file sets and gets the action
+ of the scheme.
+
+What: /sys/kernel/mm/damon/admin/kdamonds/<K>/contexts/<C>/schemes/<S>/access_pattern/sz/min
+Date: Mar 2022
+Contact: SeongJae Park <sj@kernel.org>
+Description: Writing to and reading from this file sets and gets the mimimum
+ size of the scheme's target regions in bytes.
+
+What: /sys/kernel/mm/damon/admin/kdamonds/<K>/contexts/<C>/schemes/<S>/access_pattern/sz/max
+Date: Mar 2022
+Contact: SeongJae Park <sj@kernel.org>
+Description: Writing to and reading from this file sets and gets the maximum
+ size of the scheme's target regions in bytes.
+
+What: /sys/kernel/mm/damon/admin/kdamonds/<K>/contexts/<C>/schemes/<S>/access_pattern/nr_accesses/min
+Date: Mar 2022
+Contact: SeongJae Park <sj@kernel.org>
+Description: Writing to and reading from this file sets and gets the manimum
+ 'nr_accesses' of the scheme's target regions.
+
+What: /sys/kernel/mm/damon/admin/kdamonds/<K>/contexts/<C>/schemes/<S>/access_pattern/nr_accesses/max
+Date: Mar 2022
+Contact: SeongJae Park <sj@kernel.org>
+Description: Writing to and reading from this file sets and gets the maximum
+ 'nr_accesses' of the scheme's target regions.
+
+What: /sys/kernel/mm/damon/admin/kdamonds/<K>/contexts/<C>/schemes/<S>/access_pattern/age/min
+Date: Mar 2022
+Contact: SeongJae Park <sj@kernel.org>
+Description: Writing to and reading from this file sets and gets the minimum
+ 'age' of the scheme's target regions.
+
+What: /sys/kernel/mm/damon/admin/kdamonds/<K>/contexts/<C>/schemes/<S>/access_pattern/age/max
+Date: Mar 2022
+Contact: SeongJae Park <sj@kernel.org>
+Description: Writing to and reading from this file sets and gets the maximum
+ 'age' of the scheme's target regions.
+
+What: /sys/kernel/mm/damon/admin/kdamonds/<K>/contexts/<C>/schemes/<S>/quotas/ms
+Date: Mar 2022
+Contact: SeongJae Park <sj@kernel.org>
+Description: Writing to and reading from this file sets and gets the time
+ quota of the scheme in milliseconds.
+
+What: /sys/kernel/mm/damon/admin/kdamonds/<K>/contexts/<C>/schemes/<S>/quotas/bytes
+Date: Mar 2022
+Contact: SeongJae Park <sj@kernel.org>
+Description: Writing to and reading from this file sets and gets the size
+ quota of the scheme in bytes.
+
+What: /sys/kernel/mm/damon/admin/kdamonds/<K>/contexts/<C>/schemes/<S>/quotas/reset_interval_ms
+Date: Mar 2022
+Contact: SeongJae Park <sj@kernel.org>
+Description: Writing to and reading from this file sets and gets the quotas
+ charge reset interval of the scheme in milliseconds.
+
+What: /sys/kernel/mm/damon/admin/kdamonds/<K>/contexts/<C>/schemes/<S>/quotas/weights/sz_permil
+Date: Mar 2022
+Contact: SeongJae Park <sj@kernel.org>
+Description: Writing to and reading from this file sets and gets the
+ under-quota limit regions prioritization weight for 'size' in
+ permil.
+
+What: /sys/kernel/mm/damon/admin/kdamonds/<K>/contexts/<C>/schemes/<S>/quotas/weights/nr_accesses_permil
+Date: Mar 2022
+Contact: SeongJae Park <sj@kernel.org>
+Description: Writing to and reading from this file sets and gets the
+ under-quota limit regions prioritization weight for
+ 'nr_accesses' in permil.
+
+What: /sys/kernel/mm/damon/admin/kdamonds/<K>/contexts/<C>/schemes/<S>/quotas/weights/age_permil
+Date: Mar 2022
+Contact: SeongJae Park <sj@kernel.org>
+Description: Writing to and reading from this file sets and gets the
+ under-quota limit regions prioritization weight for 'age' in
+ permil.
+
+What: /sys/kernel/mm/damon/admin/kdamonds/<K>/contexts/<C>/schemes/<S>/watermarks/metric
+Date: Mar 2022
+Contact: SeongJae Park <sj@kernel.org>
+Description: Writing to and reading from this file sets and gets the metric
+ of the watermarks for the scheme. The writable/readable
+ keywords for this file are 'none' for disabling the watermarks
+ feature, or 'free_mem_rate' for the system's global free memory
+ rate in permil.
+
+What: /sys/kernel/mm/damon/admin/kdamonds/<K>/contexts/<C>/schemes/<S>/watermarks/interval_us
+Date: Mar 2022
+Contact: SeongJae Park <sj@kernel.org>
+Description: Writing to and reading from this file sets and gets the metric
+ check interval of the watermarks for the scheme in
+ microseconds.
+
+What: /sys/kernel/mm/damon/admin/kdamonds/<K>/contexts/<C>/schemes/<S>/watermarks/high
+Date: Mar 2022
+Contact: SeongJae Park <sj@kernel.org>
+Description: Writing to and reading from this file sets and gets the high
+ watermark of the scheme in permil.
+
+What: /sys/kernel/mm/damon/admin/kdamonds/<K>/contexts/<C>/schemes/<S>/watermarks/mid
+Date: Mar 2022
+Contact: SeongJae Park <sj@kernel.org>
+Description: Writing to and reading from this file sets and gets the mid
+ watermark of the scheme in permil.
+
+What: /sys/kernel/mm/damon/admin/kdamonds/<K>/contexts/<C>/schemes/<S>/watermarks/low
+Date: Mar 2022
+Contact: SeongJae Park <sj@kernel.org>
+Description: Writing to and reading from this file sets and gets the low
+ watermark of the scheme in permil.
+
+What: /sys/kernel/mm/damon/admin/kdamonds/<K>/contexts/<C>/schemes/<S>/stats/nr_tried
+Date: Mar 2022
+Contact: SeongJae Park <sj@kernel.org>
+Description: Reading this file returns the number of regions that the action
+ of the scheme has tried to be applied.
+
+What: /sys/kernel/mm/damon/admin/kdamonds/<K>/contexts/<C>/schemes/<S>/stats/sz_tried
+Date: Mar 2022
+Contact: SeongJae Park <sj@kernel.org>
+Description: Reading this file returns the total size of regions that the
+ action of the scheme has tried to be applied in bytes.
+
+What: /sys/kernel/mm/damon/admin/kdamonds/<K>/contexts/<C>/schemes/<S>/stats/nr_applied
+Date: Mar 2022
+Contact: SeongJae Park <sj@kernel.org>
+Description: Reading this file returns the number of regions that the action
+ of the scheme has successfully applied.
+
+What: /sys/kernel/mm/damon/admin/kdamonds/<K>/contexts/<C>/schemes/<S>/stats/sz_applied
+Date: Mar 2022
+Contact: SeongJae Park <sj@kernel.org>
+Description: Reading this file returns the total size of regions that the
+ action of the scheme has successfully applied in bytes.
+
+What: /sys/kernel/mm/damon/admin/kdamonds/<K>/contexts/<C>/schemes/<S>/stats/qt_exceeds
+Date: Mar 2022
+Contact: SeongJae Park <sj@kernel.org>
+Description: Reading this file returns the number of the exceed events of
+ the scheme's quotas.
diff --git a/Documentation/ABI/testing/sysfs-timecard b/Documentation/ABI/testing/sysfs-timecard
index 97f6773794a5..220478156297 100644
--- a/Documentation/ABI/testing/sysfs-timecard
+++ b/Documentation/ABI/testing/sysfs-timecard
@@ -37,8 +37,15 @@ Description: (RO) Set of available destinations (sinks) for a SMA
PPS2 signal is sent to the PPS2 selector
TS1 signal is sent to timestamper 1
TS2 signal is sent to timestamper 2
+ TS3 signal is sent to timestamper 3
+ TS4 signal is sent to timestamper 4
IRIG signal is sent to the IRIG-B module
DCF signal is sent to the DCF module
+ FREQ1 signal is sent to frequency counter 1
+ FREQ2 signal is sent to frequency counter 2
+ FREQ3 signal is sent to frequency counter 3
+ FREQ4 signal is sent to frequency counter 4
+ None signal input is disabled
===== ================================================
What: /sys/class/timecard/ocpN/available_sma_outputs
@@ -50,10 +57,16 @@ Description: (RO) Set of available sources for a SMA output signal.
10Mhz output is from the 10Mhz reference clock
PHC output PPS is from the PHC clock
MAC output PPS is from the Miniature Atomic Clock
- GNSS output PPS is from the GNSS module
+ GNSS1 output PPS is from the first GNSS module
GNSS2 output PPS is from the second GNSS module
IRIG output is from the PHC, in IRIG-B format
DCF output is from the PHC, in DCF format
+ GEN1 output is from frequency generator 1
+ GEN2 output is from frequency generator 2
+ GEN3 output is from frequency generator 3
+ GEN4 output is from frequency generator 4
+ GND output is GND
+ VCC output is VCC
===== ================================================
What: /sys/class/timecard/ocpN/clock_source
@@ -63,6 +76,97 @@ Description: (RW) Contains the current synchronization source used by
the PHC. May be changed by writing one of the listed
values from the available_clock_sources attribute set.
+What: /sys/class/timecard/ocpN/clock_status_drift
+Date: March 2022
+Contact: Jonathan Lemon <jonathan.lemon@gmail.com>
+Description: (RO) Contains the current drift value used by the firmware
+ for internal disciplining of the atomic clock.
+
+What: /sys/class/timecard/ocpN/clock_status_offset
+Date: March 2022
+Contact: Jonathan Lemon <jonathan.lemon@gmail.com>
+Description: (RO) Contains the current offset value used by the firmware
+ for internal disciplining of the atomic clock.
+
+What: /sys/class/timecard/ocpN/freqX
+Date: March 2022
+Contact: Jonathan Lemon <jonathan.lemon@gmail.com>
+Description: (RO) Optional directory containing the sysfs nodes for
+ frequency counter <X>.
+
+What: /sys/class/timecard/ocpN/freqX/frequency
+Date: March 2022
+Contact: Jonathan Lemon <jonathan.lemon@gmail.com>
+Description: (RO) Contains the measured frequency over the specified
+ measurement period.
+
+What: /sys/class/timecard/ocpN/freqX/seconds
+Date: March 2022
+Contact: Jonathan Lemon <jonathan.lemon@gmail.com>
+Description: (RW) Specifies the number of seconds from 0-255 that the
+ frequency should be measured over. Write 0 to disable.
+
+What: /sys/class/timecard/ocpN/genX
+Date: March 2022
+Contact: Jonathan Lemon <jonathan.lemon@gmail.com>
+Description: (RO) Optional directory containing the sysfs nodes for
+ frequency generator <X>.
+
+What: /sys/class/timecard/ocpN/genX/duty
+Date: March 2022
+Contact: Jonathan Lemon <jonathan.lemon@gmail.com>
+Description: (RO) Specifies the signal duty cycle as a percentage from 1-99.
+
+What: /sys/class/timecard/ocpN/genX/period
+Date: March 2022
+Contact: Jonathan Lemon <jonathan.lemon@gmail.com>
+Description: (RO) Specifies the signal period in nanoseconds.
+
+What: /sys/class/timecard/ocpN/genX/phase
+Date: March 2022
+Contact: Jonathan Lemon <jonathan.lemon@gmail.com>
+Description: (RO) Specifies the signal phase offset in nanoseconds.
+
+What: /sys/class/timecard/ocpN/genX/polarity
+Date: March 2022
+Contact: Jonathan Lemon <jonathan.lemon@gmail.com>
+Description: (RO) Specifies the signal polarity, either 1 or 0.
+
+What: /sys/class/timecard/ocpN/genX/running
+Date: March 2022
+Contact: Jonathan Lemon <jonathan.lemon@gmail.com>
+Description: (RO) Either 0 or 1, showing if the signal generator is running.
+
+What: /sys/class/timecard/ocpN/genX/start
+Date: March 2022
+Contact: Jonathan Lemon <jonathan.lemon@gmail.com>
+Description: (RO) Shows the time in <sec>.<nsec> that the signal generator
+ started running.
+
+What: /sys/class/timecard/ocpN/genX/signal
+Date: March 2022
+Contact: Jonathan Lemon <jonathan.lemon@gmail.com>
+Description: (RW) Used to start the signal generator, and summarize
+ the current status.
+
+ The signal generator may be started by writing the signal
+ period, followed by the optional signal values. If the
+ optional values are not provided, they default to the current
+ settings, which may be obtained from the other sysfs nodes.
+
+ period [duty [phase [polarity]]]
+
+ echo 500000000 > signal # 1/2 second period
+ echo 1000000 40 100 > signal
+ echo 0 > signal # turn off generator
+
+ Period and phase are specified in nanoseconds. Duty cycle is
+ a percentage from 1-99. Polarity is 1 or 0.
+
+ Reading this node will return:
+
+ period duty phase polarity start_time
+
What: /sys/class/timecard/ocpN/gnss_sync
Date: September 2021
Contact: Jonathan Lemon <jonathan.lemon@gmail.com>
@@ -126,6 +230,16 @@ Description: (RW) These attributes specify the direction of the signal
The 10Mhz reference clock input is currently only valid
on SMA1 and may not be combined with other destination sinks.
+What: /sys/class/timecard/ocpN/tod_correction
+Date: March 2022
+Contact: Jonathan Lemon <jonathan.lemon@gmail.com>
+Description: (RW) The incoming GNSS signal is in UTC time, and the NMEA
+ format messages do not provide a TAI offset. This sets the
+ correction value for the incoming time.
+
+ If UBX_LS is enabled, this should be 0, and the offset is
+ taken from the UBX-NAV-TIMELS message.
+
What: /sys/class/timecard/ocpN/ts_window_adjust
Date: September 2021
Contact: Jonathan Lemon <jonathan.lemon@gmail.com>
diff --git a/Documentation/Makefile b/Documentation/Makefile
index 9f4bd42cef18..64d44c1ecad3 100644
--- a/Documentation/Makefile
+++ b/Documentation/Makefile
@@ -26,7 +26,7 @@ SPHINX_CONF = conf.py
PAPER =
BUILDDIR = $(obj)/output
PDFLATEX = xelatex
-LATEXOPTS = -interaction=batchmode
+LATEXOPTS = -interaction=batchmode -no-shell-escape
ifeq ($(KBUILD_VERBOSE),0)
SPHINXOPTS += "-q"
diff --git a/Documentation/accounting/psi.rst b/Documentation/accounting/psi.rst
index f2b3439edcc2..860fe651d645 100644
--- a/Documentation/accounting/psi.rst
+++ b/Documentation/accounting/psi.rst
@@ -92,7 +92,8 @@ Triggers can be set on more than one psi metric and more than one trigger
for the same psi metric can be specified. However for each trigger a separate
file descriptor is required to be able to poll it separately from others,
therefore for each trigger a separate open() syscall should be made even
-when opening the same psi interface file.
+when opening the same psi interface file. Write operations to a file descriptor
+with an already existing psi trigger will fail with EBUSY.
Monitors activate only when system enters stall state for the monitored
psi metric and deactivates upon exit from the stall state. While system is
diff --git a/Documentation/admin-guide/acpi/fan_performance_states.rst b/Documentation/admin-guide/acpi/fan_performance_states.rst
index 98fe5c333121..b9e4b4d146c1 100644
--- a/Documentation/admin-guide/acpi/fan_performance_states.rst
+++ b/Documentation/admin-guide/acpi/fan_performance_states.rst
@@ -60,3 +60,31 @@ For example::
When a given field is not populated or its value provided by the platform
firmware is invalid, the "not-defined" string is shown instead of the value.
+
+ACPI Fan Fine Grain Control
+=============================
+
+When _FIF object specifies support for fine grain control, then fan speed
+can be set from 0 to 100% with the recommended minimum "step size" via
+_FSL object. User can adjust fan speed using thermal sysfs cooling device.
+
+Here use can look at fan performance states for a reference speed (speed_rpm)
+and set it by changing cooling device cur_state. If the fine grain control
+is supported then user can also adjust to some other speeds which are
+not defined in the performance states.
+
+The support of fine grain control is presented via sysfs attribute
+"fine_grain_control". If fine grain control is present, this attribute
+will show "1" otherwise "0".
+
+This sysfs attribute is presented in the same directory as performance states.
+
+ACPI Fan Performance Feedback
+=============================
+
+The optional _FST object provides status information for the fan device.
+This includes field to provide current fan speed in revolutions per minute
+at which the fan is rotating.
+
+This speed is presented in the sysfs using the attribute "fan_speed_rpm",
+in the same directory as performance states.
diff --git a/Documentation/admin-guide/blockdev/zram.rst b/Documentation/admin-guide/blockdev/zram.rst
index 3e11926a4df9..54fe63745ed8 100644
--- a/Documentation/admin-guide/blockdev/zram.rst
+++ b/Documentation/admin-guide/blockdev/zram.rst
@@ -315,8 +315,8 @@ To use the feature, admin should set up backing device via::
echo /dev/sda5 > /sys/block/zramX/backing_dev
-before disksize setting. It supports only partition at this moment.
-If admin wants to use incompressible page writeback, they could do via::
+before disksize setting. It supports only partitions at this moment.
+If admin wants to use incompressible page writeback, they could do it via::
echo huge > /sys/block/zramX/writeback
@@ -341,9 +341,9 @@ Admin can request writeback of those idle pages at right timing via::
echo idle > /sys/block/zramX/writeback
-With the command, zram writeback idle pages from memory to the storage.
+With the command, zram will writeback idle pages from memory to the storage.
-If admin want to write a specific page in zram device to backing device,
+If an admin wants to write a specific page in zram device to the backing device,
they could write a page index into the interface.
echo "page_index=1251" > /sys/block/zramX/writeback
@@ -354,7 +354,7 @@ to guarantee storage health for entire product life.
To overcome the concern, zram supports "writeback_limit" feature.
The "writeback_limit_enable"'s default value is 0 so that it doesn't limit
-any writeback. IOW, if admin wants to apply writeback budget, he should
+any writeback. IOW, if admin wants to apply writeback budget, they should
enable writeback_limit_enable via::
$ echo 1 > /sys/block/zramX/writeback_limit_enable
@@ -365,7 +365,7 @@ until admin sets the budget via /sys/block/zramX/writeback_limit.
(If admin doesn't enable writeback_limit_enable, writeback_limit's value
assigned via /sys/block/zramX/writeback_limit is meaningless.)
-If admin want to limit writeback as per-day 400M, he could do it
+If admin wants to limit writeback as per-day 400M, they could do it
like below::
$ MB_SHIFT=20
@@ -375,16 +375,16 @@ like below::
$ echo 1 > /sys/block/zram0/writeback_limit_enable
If admins want to allow further write again once the budget is exhausted,
-he could do it like below::
+they could do it like below::
$ echo $((400<<MB_SHIFT>>4K_SHIFT)) > \
/sys/block/zram0/writeback_limit
-If admin wants to see remaining writeback budget since last set::
+If an admin wants to see the remaining writeback budget since last set::
$ cat /sys/block/zramX/writeback_limit
-If admin want to disable writeback limit, he could do::
+If an admin wants to disable writeback limit, they could do::
$ echo 0 > /sys/block/zramX/writeback_limit_enable
@@ -393,7 +393,7 @@ system reboot, echo 1 > /sys/block/zramX/reset) so keeping how many of
writeback happened until you reset the zram to allocate extra writeback
budget in next setting is user's job.
-If admin wants to measure writeback count in a certain period, he could
+If admin wants to measure writeback count in a certain period, they could
know it via /sys/block/zram0/bd_stat's 3rd column.
memory tracking
diff --git a/Documentation/admin-guide/cgroup-v1/memory.rst b/Documentation/admin-guide/cgroup-v1/memory.rst
index faac50149a22..2cc502a75ef6 100644
--- a/Documentation/admin-guide/cgroup-v1/memory.rst
+++ b/Documentation/admin-guide/cgroup-v1/memory.rst
@@ -64,6 +64,7 @@ Brief summary of control files.
threads
cgroup.procs show list of processes
cgroup.event_control an interface for event_fd()
+ This knob is not available on CONFIG_PREEMPT_RT systems.
memory.usage_in_bytes show current usage for memory
(See 5.5 for details)
memory.memsw.usage_in_bytes show current usage for memory+Swap
@@ -75,6 +76,7 @@ Brief summary of control files.
memory.max_usage_in_bytes show max memory usage recorded
memory.memsw.max_usage_in_bytes show max memory+Swap usage recorded
memory.soft_limit_in_bytes set/show soft limit of memory usage
+ This knob is not available on CONFIG_PREEMPT_RT systems.
memory.stat show various statistics
memory.use_hierarchy set/show hierarchical account enabled
This knob is deprecated and shouldn't be
diff --git a/Documentation/admin-guide/cgroup-v2.rst b/Documentation/admin-guide/cgroup-v2.rst
index 5aa368d165da..69d7a6983f78 100644
--- a/Documentation/admin-guide/cgroup-v2.rst
+++ b/Documentation/admin-guide/cgroup-v2.rst
@@ -1301,6 +1301,11 @@ PAGE_SIZE multiple when read back.
Amount of memory used to cache filesystem data,
including tmpfs and shared memory.
+ kernel (npn)
+ Amount of total kernel memory, including
+ (kernel_stack, pagetables, percpu, vmalloc, slab) in
+ addition to other kernel memory use cases.
+
kernel_stack
Amount of memory allocated to kernel stacks.
diff --git a/Documentation/admin-guide/gpio/index.rst b/Documentation/admin-guide/gpio/index.rst
index 7db367572f30..f6861ca16ffe 100644
--- a/Documentation/admin-guide/gpio/index.rst
+++ b/Documentation/admin-guide/gpio/index.rst
@@ -10,6 +10,7 @@ gpio
gpio-aggregator
sysfs
gpio-mockup
+ gpio-sim
.. only:: subproject and html
diff --git a/Documentation/admin-guide/hw-vuln/spectre.rst b/Documentation/admin-guide/hw-vuln/spectre.rst
index a2b22d5640ec..9e9556826450 100644
--- a/Documentation/admin-guide/hw-vuln/spectre.rst
+++ b/Documentation/admin-guide/hw-vuln/spectre.rst
@@ -60,8 +60,8 @@ privileged data touched during the speculative execution.
Spectre variant 1 attacks take advantage of speculative execution of
conditional branches, while Spectre variant 2 attacks use speculative
execution of indirect branches to leak privileged memory.
-See :ref:`[1] <spec_ref1>` :ref:`[5] <spec_ref5>` :ref:`[7] <spec_ref7>`
-:ref:`[10] <spec_ref10>` :ref:`[11] <spec_ref11>`.
+See :ref:`[1] <spec_ref1>` :ref:`[5] <spec_ref5>` :ref:`[6] <spec_ref6>`
+:ref:`[7] <spec_ref7>` :ref:`[10] <spec_ref10>` :ref:`[11] <spec_ref11>`.
Spectre variant 1 (Bounds Check Bypass)
---------------------------------------
@@ -131,6 +131,19 @@ steer its indirect branch speculations to gadget code, and measure the
speculative execution's side effects left in level 1 cache to infer the
victim's data.
+Yet another variant 2 attack vector is for the attacker to poison the
+Branch History Buffer (BHB) to speculatively steer an indirect branch
+to a specific Branch Target Buffer (BTB) entry, even if the entry isn't
+associated with the source address of the indirect branch. Specifically,
+the BHB might be shared across privilege levels even in the presence of
+Enhanced IBRS.
+
+Currently the only known real-world BHB attack vector is via
+unprivileged eBPF. Therefore, it's highly recommended to not enable
+unprivileged eBPF, especially when eIBRS is used (without retpolines).
+For a full mitigation against BHB attacks, it's recommended to use
+retpolines (or eIBRS combined with retpolines).
+
Attack scenarios
----------------
@@ -364,13 +377,15 @@ The possible values in this file are:
- Kernel status:
- ==================================== =================================
- 'Not affected' The processor is not vulnerable
- 'Vulnerable' Vulnerable, no mitigation
- 'Mitigation: Full generic retpoline' Software-focused mitigation
- 'Mitigation: Full AMD retpoline' AMD-specific software mitigation
- 'Mitigation: Enhanced IBRS' Hardware-focused mitigation
- ==================================== =================================
+ ======================================== =================================
+ 'Not affected' The processor is not vulnerable
+ 'Mitigation: None' Vulnerable, no mitigation
+ 'Mitigation: Retpolines' Use Retpoline thunks
+ 'Mitigation: LFENCE' Use LFENCE instructions
+ 'Mitigation: Enhanced IBRS' Hardware-focused mitigation
+ 'Mitigation: Enhanced IBRS + Retpolines' Hardware-focused + Retpolines
+ 'Mitigation: Enhanced IBRS + LFENCE' Hardware-focused + LFENCE
+ ======================================== =================================
- Firmware status: Show if Indirect Branch Restricted Speculation (IBRS) is
used to protect against Spectre variant 2 attacks when calling firmware (x86 only).
@@ -583,12 +598,13 @@ kernel command line.
Specific mitigations can also be selected manually:
- retpoline
- replace indirect branches
- retpoline,generic
- google's original retpoline
- retpoline,amd
- AMD-specific minimal thunk
+ retpoline auto pick between generic,lfence
+ retpoline,generic Retpolines
+ retpoline,lfence LFENCE; indirect branch
+ retpoline,amd alias for retpoline,lfence
+ eibrs enhanced IBRS
+ eibrs,retpoline enhanced IBRS + Retpolines
+ eibrs,lfence enhanced IBRS + LFENCE
Not specifying this option is equivalent to
spectre_v2=auto.
@@ -599,7 +615,7 @@ kernel command line.
spectre_v2=off. Spectre variant 1 mitigations
cannot be disabled.
-For spectre_v2_user see :doc:`/admin-guide/kernel-parameters`.
+For spectre_v2_user see Documentation/admin-guide/kernel-parameters.txt
Mitigation selection guide
--------------------------
@@ -681,7 +697,7 @@ AMD white papers:
.. _spec_ref6:
-[6] `Software techniques for managing speculation on AMD processors <https://developer.amd.com/wp-content/resources/90343-B_SoftwareTechniquesforManagingSpeculation_WP_7-18Update_FNL.pdf>`_.
+[6] `Software techniques for managing speculation on AMD processors <https://developer.amd.com/wp-content/resources/Managing-Speculation-on-AMD-Processors.pdf>`_.
ARM white papers:
diff --git a/Documentation/admin-guide/index.rst b/Documentation/admin-guide/index.rst
index 1bedab498104..5bfafcbb9562 100644
--- a/Documentation/admin-guide/index.rst
+++ b/Documentation/admin-guide/index.rst
@@ -35,6 +35,7 @@ problems and bugs in particular.
:maxdepth: 1
reporting-issues
+ reporting-regressions
security-bugs
bug-hunting
bug-bisect
diff --git a/Documentation/admin-guide/iostats.rst b/Documentation/admin-guide/iostats.rst
index 9b14b0c2c9c4..609a3201fd4e 100644
--- a/Documentation/admin-guide/iostats.rst
+++ b/Documentation/admin-guide/iostats.rst
@@ -76,7 +76,7 @@ Field 3 -- # of sectors read (unsigned long)
Field 4 -- # of milliseconds spent reading (unsigned int)
This is the total number of milliseconds spent by all reads (as
- measured from __make_request() to end_that_request_last()).
+ measured from blk_mq_alloc_request() to __blk_mq_end_request()).
Field 5 -- # of writes completed (unsigned long)
This is the total number of writes completed successfully.
@@ -89,7 +89,7 @@ Field 7 -- # of sectors written (unsigned long)
Field 8 -- # of milliseconds spent writing (unsigned int)
This is the total number of milliseconds spent by all writes (as
- measured from __make_request() to end_that_request_last()).
+ measured from blk_mq_alloc_request() to __blk_mq_end_request()).
Field 9 -- # of I/Os currently in progress (unsigned int)
The only field that should go to zero. Incremented as requests are
@@ -120,7 +120,7 @@ Field 14 -- # of sectors discarded (unsigned long)
Field 15 -- # of milliseconds spent discarding (unsigned int)
This is the total number of milliseconds spent by all discards (as
- measured from __make_request() to end_that_request_last()).
+ measured from blk_mq_alloc_request() to __blk_mq_end_request()).
Field 16 -- # of flush requests completed
This is the total number of flush requests completed successfully.
diff --git a/Documentation/admin-guide/kdump/kdump.rst b/Documentation/admin-guide/kdump/kdump.rst
index cb30ca3df27c..a748e7eb4429 100644
--- a/Documentation/admin-guide/kdump/kdump.rst
+++ b/Documentation/admin-guide/kdump/kdump.rst
@@ -146,9 +146,9 @@ System kernel config options
CONFIG_SYSFS=y
Note that "sysfs file system support" might not appear in the "Pseudo
- filesystems" menu if "Configure standard kernel features (for small
- systems)" is not enabled in "General Setup." In this case, check the
- .config file itself to ensure that sysfs is turned on, as follows::
+ filesystems" menu if "Configure standard kernel features (expert users)"
+ is not enabled in "General Setup." In this case, check the .config file
+ itself to ensure that sysfs is turned on, as follows::
grep 'CONFIG_SYSFS' .config
@@ -533,6 +533,10 @@ the following command::
cp /proc/vmcore <dump-file>
+or use scp to write out the dump file between hosts on a network, e.g::
+
+ scp /proc/vmcore remote_username@remote_ip:<dump-file>
+
You can also use makedumpfile utility to write out the dump file
with specified options to filter out unwanted contents, e.g::
diff --git a/Documentation/admin-guide/kdump/vmcoreinfo.rst b/Documentation/admin-guide/kdump/vmcoreinfo.rst
index 3861a25faae1..8419019b6a88 100644
--- a/Documentation/admin-guide/kdump/vmcoreinfo.rst
+++ b/Documentation/admin-guide/kdump/vmcoreinfo.rst
@@ -494,6 +494,14 @@ architecture which is used to lookup the page-tables for the Virtual
addresses in the higher VA range (refer to ARMv8 ARM document for
more details).
+MODULES_VADDR|MODULES_END|VMALLOC_START|VMALLOC_END|VMEMMAP_START|VMEMMAP_END
+-----------------------------------------------------------------------------
+
+Used to get the correct ranges:
+ MODULES_VADDR ~ MODULES_END-1 : Kernel module space.
+ VMALLOC_START ~ VMALLOC_END-1 : vmalloc() / ioremap() space.
+ VMEMMAP_START ~ VMEMMAP_END-1 : vmemmap region, used for struct page array.
+
arm
===
diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
index f5a27f067db9..b7ccaa2ea867 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -724,6 +724,12 @@
hvc<n> Use the hypervisor console device <n>. This is for
both Xen and PowerPC hypervisors.
+ { null | "" }
+ Use to disable console output, i.e., to have kernel
+ console messages discarded.
+ This must be the only console= parameter used on the
+ kernel command line.
+
If the device connected to the port is not a TTY but a braille
device, prepend "brl," before the device type, for instance
console=brl,ttyS0
@@ -944,6 +950,30 @@
dump out devices still on the deferred probe list after
retrying.
+ dell_smm_hwmon.ignore_dmi=
+ [HW] Continue probing hardware even if DMI data
+ indicates that the driver is running on unsupported
+ hardware.
+
+ dell_smm_hwmon.force=
+ [HW] Activate driver even if SMM BIOS signature does
+ not match list of supported models and enable otherwise
+ blacklisted features.
+
+ dell_smm_hwmon.power_status=
+ [HW] Report power status in /proc/i8k
+ (disabled by default).
+
+ dell_smm_hwmon.restricted=
+ [HW] Allow controlling fans only if SYS_ADMIN
+ capability is set.
+
+ dell_smm_hwmon.fan_mult=
+ [HW] Factor to multiply fan speed with.
+
+ dell_smm_hwmon.fan_max=
+ [HW] Maximum configurable fan speed.
+
dfltcc= [HW,S390]
Format: { on | off | def_only | inf_only | always }
on: s390 zlib hardware support for compression on
@@ -1435,6 +1465,14 @@
as early as possible in order to facilitate early
boot debugging.
+ ftrace_boot_snapshot
+ [FTRACE] On boot up, a snapshot will be taken of the
+ ftrace ring buffer that can be read at:
+ /sys/kernel/tracing/snapshot.
+ This is useful if you need tracing information from kernel
+ boot up that is likely to be overridden by user space
+ start up functionality.
+
ftrace_dump_on_oops[=orig_cpu]
[FTRACE] will dump the trace buffers on oops.
If no parameter is passed, ftrace will dump
@@ -1625,7 +1663,7 @@
[KNL] Reguires CONFIG_HUGETLB_PAGE_FREE_VMEMMAP
enabled.
Allows heavy hugetlb users to free up some more
- memory (6 * PAGE_SIZE for each 2MB hugetlb page).
+ memory (7 * PAGE_SIZE for each 2MB hugetlb page).
Format: { on | off (default) }
on: enable the feature
@@ -1703,17 +1741,6 @@
i810= [HW,DRM]
- i8k.ignore_dmi [HW] Continue probing hardware even if DMI data
- indicates that the driver is running on unsupported
- hardware.
- i8k.force [HW] Activate i8k driver even if SMM BIOS signature
- does not match list of supported models.
- i8k.power_status
- [HW] Report power status in /proc/i8k
- (disabled by default)
- i8k.restricted [HW] Allow controlling fans only if SYS_ADMIN
- capability is set.
-
i915.invert_brightness=
[DRM] Invert the sense of the variable that is used to
set the brightness of the panel backlight. Normally a
@@ -2339,13 +2366,35 @@
kvm.ignore_msrs=[KVM] Ignore guest accesses to unhandled MSRs.
Default is 0 (don't ignore, but inject #GP)
+ kvm.eager_page_split=
+ [KVM,X86] Controls whether or not KVM will try to
+ proactively split all huge pages during dirty logging.
+ Eager page splitting reduces interruptions to vCPU
+ execution by eliminating the write-protection faults
+ and MMU lock contention that would otherwise be
+ required to split huge pages lazily.
+
+ VM workloads that rarely perform writes or that write
+ only to a small region of VM memory may benefit from
+ disabling eager page splitting to allow huge pages to
+ still be used for reads.
+
+ The behavior of eager page splitting depends on whether
+ KVM_DIRTY_LOG_INITIALLY_SET is enabled or disabled. If
+ disabled, all huge pages in a memslot will be eagerly
+ split when dirty logging is enabled on that memslot. If
+ enabled, eager page splitting will be performed during
+ the KVM_CLEAR_DIRTY ioctl, and only for the pages being
+ cleared.
+
+ Eager page splitting currently only supports splitting
+ huge pages mapped by the TDP MMU.
+
+ Default is Y (on).
+
kvm.enable_vmware_backdoor=[KVM] Support VMware backdoor PV interface.
Default is false (don't support).
- kvm.mmu_audit= [KVM] This is a R/W parameter which allows audit
- KVM MMU at runtime.
- Default is 0 (off)
-
kvm.nx_huge_pages=
[KVM] Controls the software workaround for the
X86_BUG_ITLB_MULTIHIT bug.
@@ -2827,6 +2876,9 @@
For details see: Documentation/admin-guide/hw-vuln/mds.rst
+ mem=nn[KMG] [HEXAGON] Set the memory size.
+ Must be specified, otherwise memory size will be 0.
+
mem=nn[KMG] [KNL,BOOT] Force usage of a specific amount of memory
Amount of memory to be used in cases as follows:
@@ -2834,6 +2886,13 @@
2 when the kernel is not able to see the whole system memory;
3 memory that lies after 'mem=' boundary is excluded from
the hypervisor, then assigned to KVM guests.
+ 4 to limit the memory available for kdump kernel.
+
+ [ARC,MICROBLAZE] - the limit applies only to low memory,
+ high memory is not affected.
+
+ [ARM64] - only limits memory covered by the linear
+ mapping. The NOMAP regions are not affected.
[X86] Work as limiting max address. Use together
with memmap= to avoid physical address space collisions.
@@ -2844,6 +2903,14 @@
in above case 3, memory may need be hot added after boot
if system memory of hypervisor is not sufficient.
+ mem=nn[KMG]@ss[KMG]
+ [ARM,MIPS] - override the memory layout reported by
+ firmware.
+ Define a memory region of size nn[KMG] starting at
+ ss[KMG].
+ Multiple different regions can be specified with
+ multiple mem= parameters on the command line.
+
mem=nopentium [BUGS=X86-32] Disable usage of 4MB pages for kernel
memory.
@@ -3485,8 +3552,7 @@
difficult since unequal pointers can no longer be
compared. However, if this command-line option is
specified, then all normal pointers will have their true
- value printed. Pointers printed via %pK may still be
- hashed. This option should only be specified when
+ value printed. This option should only be specified when
debugging the kernel. Please do not use on production
kernels.
@@ -3726,6 +3792,11 @@
bit 3: print locks info if CONFIG_LOCKDEP is on
bit 4: print ftrace buffer
bit 5: print all printk messages in buffer
+ bit 6: print all CPUs backtrace (if available in the arch)
+ *Be aware* that this option may print a _lot_ of lines,
+ so there are risks of losing older messages in the log.
+ Use this option carefully, maybe worth to setup a
+ bigger log buffer with "log_buf_len" along with this.
panic_on_taint= Bitmask for conditionally calling panic() in add_taint()
Format: <hex>[,nousertaint]
@@ -4504,6 +4575,8 @@
(the least-favored priority). Otherwise, when
RCU_BOOST is not set, valid values are 0-99 and
the default is zero (non-realtime operation).
+ When RCU_NOCB_CPU is set, also adjust the
+ priority of NOCB callback kthreads.
rcutree.rcu_nocb_gp_stride= [KNL]
Set the number of NOCB callback kthreads in
@@ -5361,8 +5434,12 @@
Specific mitigations can also be selected manually:
retpoline - replace indirect branches
- retpoline,generic - google's original retpoline
- retpoline,amd - AMD-specific minimal thunk
+ retpoline,generic - Retpolines
+ retpoline,lfence - LFENCE; indirect branch
+ retpoline,amd - alias for retpoline,lfence
+ eibrs - enhanced IBRS
+ eibrs,retpoline - enhanced IBRS + Retpolines
+ eibrs,lfence - enhanced IBRS + LFENCE
Not specifying this option is equivalent to
spectre_v2=auto.
diff --git a/Documentation/admin-guide/media/fimc.rst b/Documentation/admin-guide/media/fimc.rst
index 56b149d9a527..267ef52fe387 100644
--- a/Documentation/admin-guide/media/fimc.rst
+++ b/Documentation/admin-guide/media/fimc.rst
@@ -14,7 +14,7 @@ data from LCD controller (FIMD) through the SoC internal writeback data
path. There are multiple FIMC instances in the SoCs (up to 4), having
slightly different capabilities, like pixel alignment constraints, rotator
availability, LCD writeback support, etc. The driver is located at
-drivers/media/platform/exynos4-is directory.
+drivers/media/platform/samsung/exynos4-is directory.
Supported SoCs
--------------
diff --git a/Documentation/admin-guide/media/i2c-cardlist.rst b/Documentation/admin-guide/media/i2c-cardlist.rst
index db17f39b56cf..ef3b5fff3b01 100644
--- a/Documentation/admin-guide/media/i2c-cardlist.rst
+++ b/Documentation/admin-guide/media/i2c-cardlist.rst
@@ -284,7 +284,7 @@ tda9887 TDA 9885/6/7 analog IF demodulator
tea5761 TEA 5761 radio tuner
tea5767 TEA 5767 radio tuner
tua9001 Infineon TUA9001 silicon tuner
-tuner-xc2028 XCeive xc2028/xc3028 tuners
+xc2028 XCeive xc2028/xc3028 tuners
xc4000 Xceive XC4000 silicon tuner
xc5000 Xceive XC5000 silicon tuner
============ ==================================================
diff --git a/Documentation/admin-guide/media/imx7.rst b/Documentation/admin-guide/media/imx7.rst
index 4785ae8ac978..2fa27718f52a 100644
--- a/Documentation/admin-guide/media/imx7.rst
+++ b/Documentation/admin-guide/media/imx7.rst
@@ -33,7 +33,7 @@ reference manual [#f1]_.
Entities
--------
-imx7-mipi-csi2
+imx-mipi-csi2
--------------
This is the MIPI CSI-2 receiver entity. It has one sink pad to receive the pixel
diff --git a/Documentation/admin-guide/media/omap3isp.rst b/Documentation/admin-guide/media/omap3isp.rst
index bc447bbec7ce..f32e7375a1a2 100644
--- a/Documentation/admin-guide/media/omap3isp.rst
+++ b/Documentation/admin-guide/media/omap3isp.rst
@@ -17,7 +17,7 @@ Introduction
------------
This file documents the Texas Instruments OMAP 3 Image Signal Processor (ISP)
-driver located under drivers/media/platform/omap3isp. The original driver was
+driver located under drivers/media/platform/ti/omap3isp. The original driver was
written by Texas Instruments but since that it has been rewritten (twice) at
Nokia.
diff --git a/Documentation/admin-guide/media/omap4_camera.rst b/Documentation/admin-guide/media/omap4_camera.rst
index 24db4222d36d..2ada9b1e6897 100644
--- a/Documentation/admin-guide/media/omap4_camera.rst
+++ b/Documentation/admin-guide/media/omap4_camera.rst
@@ -25,7 +25,7 @@ As of Revision AB, the ISS is described in detail in section 8.
This driver is supporting **only** the CSI2-A/B interfaces for now.
It makes use of the Media Controller framework [#f2]_, and inherited most of the
-code from OMAP3 ISP driver (found under drivers/media/platform/omap3isp/\*),
+code from OMAP3 ISP driver (found under drivers/media/platform/ti/omap3isp/\*),
except that it doesn't need an IOMMU now for ISS buffers memory mapping.
Supports usage of MMAP buffers only (for now).
diff --git a/Documentation/admin-guide/media/vimc.rst b/Documentation/admin-guide/media/vimc.rst
index 180507d455f2..0b07f05dde25 100644
--- a/Documentation/admin-guide/media/vimc.rst
+++ b/Documentation/admin-guide/media/vimc.rst
@@ -76,3 +76,16 @@ vimc-capture:
* 1 Pad sink
* 1 Pad source
+
+Module options
+--------------
+
+Vimc has a module parameter to configure the driver.
+
+* ``allocator=<unsigned int>``
+
+ memory allocator selection, default is 0. It specifies the way buffers
+ will be allocated.
+
+ - 0: vmalloc
+ - 1: dma-contig
diff --git a/Documentation/admin-guide/mm/damon/usage.rst b/Documentation/admin-guide/mm/damon/usage.rst
index 59b84904a854..592ea9a50881 100644
--- a/Documentation/admin-guide/mm/damon/usage.rst
+++ b/Documentation/admin-guide/mm/damon/usage.rst
@@ -4,7 +4,7 @@
Detailed Usages
===============
-DAMON provides below three interfaces for different users.
+DAMON provides below interfaces for different users.
- *DAMON user space tool.*
`This <https://github.com/awslabs/damo>`_ is for privileged people such as
@@ -14,17 +14,21 @@ DAMON provides below three interfaces for different users.
virtual and physical address spaces monitoring. For more detail, please
refer to its `usage document
<https://github.com/awslabs/damo/blob/next/USAGE.md>`_.
-- *debugfs interface.*
- :ref:`This <debugfs_interface>` is for privileged user space programmers who
+- *sysfs interface.*
+ :ref:`This <sysfs_interface>` is for privileged user space programmers who
want more optimized use of DAMON. Using this, users can use DAMON’s major
- features by reading from and writing to special debugfs files. Therefore,
- you can write and use your personalized DAMON debugfs wrapper programs that
- reads/writes the debugfs files instead of you. The `DAMON user space tool
+ features by reading from and writing to special sysfs files. Therefore,
+ you can write and use your personalized DAMON sysfs wrapper programs that
+ reads/writes the sysfs files instead of you. The `DAMON user space tool
<https://github.com/awslabs/damo>`_ is one example of such programs. It
supports both virtual and physical address spaces monitoring. Note that this
interface provides only simple :ref:`statistics <damos_stats>` for the
monitoring results. For detailed monitoring results, DAMON provides a
:ref:`tracepoint <tracepoint>`.
+- *debugfs interface.*
+ :ref:`This <debugfs_interface>` is almost identical to :ref:`sysfs interface
+ <sysfs_interface>`. This will be removed after next LTS kernel is released,
+ so users should move to the :ref:`sysfs interface <sysfs_interface>`.
- *Kernel Space Programming Interface.*
:doc:`This </vm/damon/api>` is for kernel space programmers. Using this,
users can utilize every feature of DAMON most flexibly and efficiently by
@@ -32,6 +36,340 @@ DAMON provides below three interfaces for different users.
DAMON for various address spaces. For detail, please refer to the interface
:doc:`document </vm/damon/api>`.
+.. _sysfs_interface:
+
+sysfs Interface
+===============
+
+DAMON sysfs interface is built when ``CONFIG_DAMON_SYSFS`` is defined. It
+creates multiple directories and files under its sysfs directory,
+``<sysfs>/kernel/mm/damon/``. You can control DAMON by writing to and reading
+from the files under the directory.
+
+For a short example, users can monitor the virtual address space of a given
+workload as below. ::
+
+ # cd /sys/kernel/mm/damon/admin/
+ # echo 1 > kdamonds/nr && echo 1 > kdamonds/0/contexts/nr
+ # echo vaddr > kdamonds/0/contexts/0/operations
+ # echo 1 > kdamonds/0/contexts/0/targets/nr
+ # echo $(pidof <workload>) > kdamonds/0/contexts/0/targets/0/pid
+ # echo on > kdamonds/0/state
+
+Files Hierarchy
+---------------
+
+The files hierarchy of DAMON sysfs interface is shown below. In the below
+figure, parents-children relations are represented with indentations, each
+directory is having ``/`` suffix, and files in each directory are separated by
+comma (","). ::
+
+ /sys/kernel/mm/damon/admin
+ │ kdamonds/nr_kdamonds
+ │ │ 0/state,pid
+ │ │ │ contexts/nr_contexts
+ │ │ │ │ 0/operations
+ │ │ │ │ │ monitoring_attrs/
+ │ │ │ │ │ │ intervals/sample_us,aggr_us,update_us
+ │ │ │ │ │ │ nr_regions/min,max
+ │ │ │ │ │ targets/nr_targets
+ │ │ │ │ │ │ 0/pid_target
+ │ │ │ │ │ │ │ regions/nr_regions
+ │ │ │ │ │ │ │ │ 0/start,end
+ │ │ │ │ │ │ │ │ ...
+ │ │ │ │ │ │ ...
+ │ │ │ │ │ schemes/nr_schemes
+ │ │ │ │ │ │ 0/action
+ │ │ │ │ │ │ │ access_pattern/
+ │ │ │ │ │ │ │ │ sz/min,max
+ │ │ │ │ │ │ │ │ nr_accesses/min,max
+ │ │ │ │ │ │ │ │ age/min,max
+ │ │ │ │ │ │ │ quotas/ms,bytes,reset_interval_ms
+ │ │ │ │ │ │ │ │ weights/sz_permil,nr_accesses_permil,age_permil
+ │ │ │ │ │ │ │ watermarks/metric,interval_us,high,mid,low
+ │ │ │ │ │ │ │ stats/nr_tried,sz_tried,nr_applied,sz_applied,qt_exceeds
+ │ │ │ │ │ │ ...
+ │ │ │ │ ...
+ │ │ ...
+
+Root
+----
+
+The root of the DAMON sysfs interface is ``<sysfs>/kernel/mm/damon/``, and it
+has one directory named ``admin``. The directory contains the files for
+privileged user space programs' control of DAMON. User space tools or deamons
+having the root permission could use this directory.
+
+kdamonds/
+---------
+
+The monitoring-related information including request specifications and results
+are called DAMON context. DAMON executes each context with a kernel thread
+called kdamond, and multiple kdamonds could run in parallel.
+
+Under the ``admin`` directory, one directory, ``kdamonds``, which has files for
+controlling the kdamonds exist. In the beginning, this directory has only one
+file, ``nr_kdamonds``. Writing a number (``N``) to the file creates the number
+of child directories named ``0`` to ``N-1``. Each directory represents each
+kdamond.
+
+kdamonds/<N>/
+-------------
+
+In each kdamond directory, two files (``state`` and ``pid``) and one directory
+(``contexts``) exist.
+
+Reading ``state`` returns ``on`` if the kdamond is currently running, or
+``off`` if it is not running. Writing ``on`` or ``off`` makes the kdamond be
+in the state. Writing ``update_schemes_stats`` to ``state`` file updates the
+contents of stats files for each DAMON-based operation scheme of the kdamond.
+For details of the stats, please refer to :ref:`stats section
+<sysfs_schemes_stats>`.
+
+If the state is ``on``, reading ``pid`` shows the pid of the kdamond thread.
+
+``contexts`` directory contains files for controlling the monitoring contexts
+that this kdamond will execute.
+
+kdamonds/<N>/contexts/
+----------------------
+
+In the beginning, this directory has only one file, ``nr_contexts``. Writing a
+number (``N``) to the file creates the number of child directories named as
+``0`` to ``N-1``. Each directory represents each monitoring context. At the
+moment, only one context per kdamond is supported, so only ``0`` or ``1`` can
+be written to the file.
+
+contexts/<N>/
+-------------
+
+In each context directory, one file (``operations``) and three directories
+(``monitoring_attrs``, ``targets``, and ``schemes``) exist.
+
+DAMON supports multiple types of monitoring operations, including those for
+virtual address space and the physical address space. You can set and get what
+type of monitoring operations DAMON will use for the context by writing one of
+below keywords to, and reading from the file.
+
+ - vaddr: Monitor virtual address spaces of specific processes
+ - paddr: Monitor the physical address space of the system
+
+contexts/<N>/monitoring_attrs/
+------------------------------
+
+Files for specifying attributes of the monitoring including required quality
+and efficiency of the monitoring are in ``monitoring_attrs`` directory.
+Specifically, two directories, ``intervals`` and ``nr_regions`` exist in this
+directory.
+
+Under ``intervals`` directory, three files for DAMON's sampling interval
+(``sample_us``), aggregation interval (``aggr_us``), and update interval
+(``update_us``) exist. You can set and get the values in micro-seconds by
+writing to and reading from the files.
+
+Under ``nr_regions`` directory, two files for the lower-bound and upper-bound
+of DAMON's monitoring regions (``min`` and ``max``, respectively), which
+controls the monitoring overhead, exist. You can set and get the values by
+writing to and rading from the files.
+
+For more details about the intervals and monitoring regions range, please refer
+to the Design document (:doc:`/vm/damon/design`).
+
+contexts/<N>/targets/
+---------------------
+
+In the beginning, this directory has only one file, ``nr_targets``. Writing a
+number (``N``) to the file creates the number of child directories named ``0``
+to ``N-1``. Each directory represents each monitoring target.
+
+targets/<N>/
+------------
+
+In each target directory, one file (``pid_target``) and one directory
+(``regions``) exist.
+
+If you wrote ``vaddr`` to the ``contexts/<N>/operations``, each target should
+be a process. You can specify the process to DAMON by writing the pid of the
+process to the ``pid_target`` file.
+
+targets/<N>/regions
+-------------------
+
+When ``vaddr`` monitoring operations set is being used (``vaddr`` is written to
+the ``contexts/<N>/operations`` file), DAMON automatically sets and updates the
+monitoring target regions so that entire memory mappings of target processes
+can be covered. However, users could want to set the initial monitoring region
+to specific address ranges.
+
+In contrast, DAMON do not automatically sets and updates the monitoring target
+regions when ``paddr`` monitoring operations set is being used (``paddr`` is
+written to the ``contexts/<N>/operations``). Therefore, users should set the
+monitoring target regions by themselves in the case.
+
+For such cases, users can explicitly set the initial monitoring target regions
+as they want, by writing proper values to the files under this directory.
+
+In the beginning, this directory has only one file, ``nr_regions``. Writing a
+number (``N``) to the file creates the number of child directories named ``0``
+to ``N-1``. Each directory represents each initial monitoring target region.
+
+regions/<N>/
+------------
+
+In each region directory, you will find two files (``start`` and ``end``). You
+can set and get the start and end addresses of the initial monitoring target
+region by writing to and reading from the files, respectively.
+
+contexts/<N>/schemes/
+---------------------
+
+For usual DAMON-based data access aware memory management optimizations, users
+would normally want the system to apply a memory management action to a memory
+region of a specific access pattern. DAMON receives such formalized operation
+schemes from the user and applies those to the target memory regions. Users
+can get and set the schemes by reading from and writing to files under this
+directory.
+
+In the beginning, this directory has only one file, ``nr_schemes``. Writing a
+number (``N``) to the file creates the number of child directories named ``0``
+to ``N-1``. Each directory represents each DAMON-based operation scheme.
+
+schemes/<N>/
+------------
+
+In each scheme directory, four directories (``access_pattern``, ``quotas``,
+``watermarks``, and ``stats``) and one file (``action``) exist.
+
+The ``action`` file is for setting and getting what action you want to apply to
+memory regions having specific access pattern of the interest. The keywords
+that can be written to and read from the file and their meaning are as below.
+
+ - ``willneed``: Call ``madvise()`` for the region with ``MADV_WILLNEED``
+ - ``cold``: Call ``madvise()`` for the region with ``MADV_COLD``
+ - ``pageout``: Call ``madvise()`` for the region with ``MADV_PAGEOUT``
+ - ``hugepage``: Call ``madvise()`` for the region with ``MADV_HUGEPAGE``
+ - ``nohugepage``: Call ``madvise()`` for the region with ``MADV_NOHUGEPAGE``
+ - ``stat``: Do nothing but count the statistics
+
+schemes/<N>/access_pattern/
+---------------------------
+
+The target access pattern of each DAMON-based operation scheme is constructed
+with three ranges including the size of the region in bytes, number of
+monitored accesses per aggregate interval, and number of aggregated intervals
+for the age of the region.
+
+Under the ``access_pattern`` directory, three directories (``sz``,
+``nr_accesses``, and ``age``) each having two files (``min`` and ``max``)
+exist. You can set and get the access pattern for the given scheme by writing
+to and reading from the ``min`` and ``max`` files under ``sz``,
+``nr_accesses``, and ``age`` directories, respectively.
+
+schemes/<N>/quotas/
+-------------------
+
+Optimal ``target access pattern`` for each ``action`` is workload dependent, so
+not easy to find. Worse yet, setting a scheme of some action too aggressive
+can cause severe overhead. To avoid such overhead, users can limit time and
+size quota for each scheme. In detail, users can ask DAMON to try to use only
+up to specific time (``time quota``) for applying the action, and to apply the
+action to only up to specific amount (``size quota``) of memory regions having
+the target access pattern within a given time interval (``reset interval``).
+
+When the quota limit is expected to be exceeded, DAMON prioritizes found memory
+regions of the ``target access pattern`` based on their size, access frequency,
+and age. For personalized prioritization, users can set the weights for the
+three properties.
+
+Under ``quotas`` directory, three files (``ms``, ``bytes``,
+``reset_interval_ms``) and one directory (``weights``) having three files
+(``sz_permil``, ``nr_accesses_permil``, and ``age_permil``) in it exist.
+
+You can set the ``time quota`` in milliseconds, ``size quota`` in bytes, and
+``reset interval`` in milliseconds by writing the values to the three files,
+respectively. You can also set the prioritization weights for size, access
+frequency, and age in per-thousand unit by writing the values to the three
+files under the ``weights`` directory.
+
+schemes/<N>/watermarks/
+-----------------------
+
+To allow easy activation and deactivation of each scheme based on system
+status, DAMON provides a feature called watermarks. The feature receives five
+values called ``metric``, ``interval``, ``high``, ``mid``, and ``low``. The
+``metric`` is the system metric such as free memory ratio that can be measured.
+If the metric value of the system is higher than the value in ``high`` or lower
+than ``low`` at the memoent, the scheme is deactivated. If the value is lower
+than ``mid``, the scheme is activated.
+
+Under the watermarks directory, five files (``metric``, ``interval_us``,
+``high``, ``mid``, and ``low``) for setting each value exist. You can set and
+get the five values by writing to the files, respectively.
+
+Keywords and meanings of those that can be written to the ``metric`` file are
+as below.
+
+ - none: Ignore the watermarks
+ - free_mem_rate: System's free memory rate (per thousand)
+
+The ``interval`` should written in microseconds unit.
+
+.. _sysfs_schemes_stats:
+
+schemes/<N>/stats/
+------------------
+
+DAMON counts the total number and bytes of regions that each scheme is tried to
+be applied, the two numbers for the regions that each scheme is successfully
+applied, and the total number of the quota limit exceeds. This statistics can
+be used for online analysis or tuning of the schemes.
+
+The statistics can be retrieved by reading the files under ``stats`` directory
+(``nr_tried``, ``sz_tried``, ``nr_applied``, ``sz_applied``, and
+``qt_exceeds``), respectively. The files are not updated in real time, so you
+should ask DAMON sysfs interface to updte the content of the files for the
+stats by writing a special keyword, ``update_schemes_stats`` to the relevant
+``kdamonds/<N>/state`` file.
+
+Example
+~~~~~~~
+
+Below commands applies a scheme saying "If a memory region of size in [4KiB,
+8KiB] is showing accesses per aggregate interval in [0, 5] for aggregate
+interval in [10, 20], page out the region. For the paging out, use only up to
+10ms per second, and also don't page out more than 1GiB per second. Under the
+limitation, page out memory regions having longer age first. Also, check the
+free memory rate of the system every 5 seconds, start the monitoring and paging
+out when the free memory rate becomes lower than 50%, but stop it if the free
+memory rate becomes larger than 60%, or lower than 30%". ::
+
+ # cd <sysfs>/kernel/mm/damon/admin
+ # # populate directories
+ # echo 1 > kdamonds/nr_kdamonds; echo 1 > kdamonds/0/contexts/nr_contexts;
+ # echo 1 > kdamonds/0/contexts/0/schemes/nr_schemes
+ # cd kdamonds/0/contexts/0/schemes/0
+ # # set the basic access pattern and the action
+ # echo 4096 > access_patterns/sz/min
+ # echo 8192 > access_patterns/sz/max
+ # echo 0 > access_patterns/nr_accesses/min
+ # echo 5 > access_patterns/nr_accesses/max
+ # echo 10 > access_patterns/age/min
+ # echo 20 > access_patterns/age/max
+ # echo pageout > action
+ # # set quotas
+ # echo 10 > quotas/ms
+ # echo $((1024*1024*1024)) > quotas/bytes
+ # echo 1000 > quotas/reset_interval_ms
+ # # set watermark
+ # echo free_mem_rate > watermarks/metric
+ # echo 5000000 > watermarks/interval_us
+ # echo 600 > watermarks/high
+ # echo 500 > watermarks/mid
+ # echo 300 > watermarks/low
+
+Please note that it's highly recommended to use user space tools like `damo
+<https://github.com/awslabs/damo>`_ rather than manually reading and writing
+the files as above. Above is only for an example.
.. _debugfs_interface:
@@ -47,7 +385,7 @@ Attributes
----------
Users can get and set the ``sampling interval``, ``aggregation interval``,
-``regions update interval``, and min/max number of monitoring target regions by
+``update interval``, and min/max number of monitoring target regions by
reading from and writing to the ``attrs`` file. To know about the monitoring
attributes in detail, please refer to the :doc:`/vm/damon/design`. For
example, below commands set those values to 5 ms, 100 ms, 1,000 ms, 10 and
@@ -108,24 +446,28 @@ In such cases, users can explicitly set the initial monitoring target regions
as they want, by writing proper values to the ``init_regions`` file. Each line
of the input should represent one region in below form.::
- <target id> <start address> <end address>
+ <target idx> <start address> <end address>
-The ``target id`` should already in ``target_ids`` file, and the regions should
-be passed in address order. For example, below commands will set a couple of
-address ranges, ``1-100`` and ``100-200`` as the initial monitoring target
-region of process 42, and another couple of address ranges, ``20-40`` and
-``50-100`` as that of process 4242.::
+The ``target idx`` should be the index of the target in ``target_ids`` file,
+starting from ``0``, and the regions should be passed in address order. For
+example, below commands will set a couple of address ranges, ``1-100`` and
+``100-200`` as the initial monitoring target region of pid 42, which is the
+first one (index ``0``) in ``target_ids``, and another couple of address
+ranges, ``20-40`` and ``50-100`` as that of pid 4242, which is the second one
+(index ``1``) in ``target_ids``.::
# cd <debugfs>/damon
- # echo "42 1 100
- 42 100 200
- 4242 20 40
- 4242 50 100" > init_regions
+ # cat target_ids
+ 42 4242
+ # echo "0 1 100
+ 0 100 200
+ 1 20 40
+ 1 50 100" > init_regions
Note that this sets the initial monitoring target regions only. In case of
virtual memory monitoring, DAMON will automatically updates the boundary of the
-regions after one ``regions update interval``. Therefore, users should set the
-``regions update interval`` large enough in this case, if they don't want the
+regions after one ``update interval``. Therefore, users should set the
+``update interval`` large enough in this case, if they don't want the
update.
diff --git a/Documentation/admin-guide/mm/pagemap.rst b/Documentation/admin-guide/mm/pagemap.rst
index bfc28704856c..6e2e416af783 100644
--- a/Documentation/admin-guide/mm/pagemap.rst
+++ b/Documentation/admin-guide/mm/pagemap.rst
@@ -23,7 +23,7 @@ There are four components to pagemap:
* Bit 56 page exclusively mapped (since 4.2)
* Bit 57 pte is uffd-wp write-protected (since 5.13) (see
:ref:`Documentation/admin-guide/mm/userfaultfd.rst <userfaultfd>`)
- * Bits 57-60 zero
+ * Bits 58-60 zero
* Bit 61 page is file-page or shared-anon (since 3.5)
* Bit 62 page swapped
* Bit 63 page present
diff --git a/Documentation/admin-guide/mm/zswap.rst b/Documentation/admin-guide/mm/zswap.rst
index 8edb8d578caf..6e6f7b0d6562 100644
--- a/Documentation/admin-guide/mm/zswap.rst
+++ b/Documentation/admin-guide/mm/zswap.rst
@@ -130,9 +130,25 @@ attribute, e.g.::
echo 1 > /sys/module/zswap/parameters/same_filled_pages_enabled
When zswap same-filled page identification is disabled at runtime, it will stop
-checking for the same-value filled pages during store operation. However, the
-existing pages which are marked as same-value filled pages remain stored
-unchanged in zswap until they are either loaded or invalidated.
+checking for the same-value filled pages during store operation.
+In other words, every page will be then considered non-same-value filled.
+However, the existing pages which are marked as same-value filled pages remain
+stored unchanged in zswap until they are either loaded or invalidated.
+
+In some circumstances it might be advantageous to make use of just the zswap
+ability to efficiently store same-filled pages without enabling the whole
+compressed page storage.
+In this case the handling of non-same-value pages by zswap (enabled by default)
+can be disabled by setting the ``non_same_filled_pages_enabled`` attribute
+to 0, e.g. ``zswap.non_same_filled_pages_enabled=0``.
+It can also be enabled and disabled at runtime using the sysfs
+``non_same_filled_pages_enabled`` attribute, e.g.::
+
+ echo 1 > /sys/module/zswap/parameters/non_same_filled_pages_enabled
+
+Disabling both ``zswap.same_filled_pages_enabled`` and
+``zswap.non_same_filled_pages_enabled`` effectively disables accepting any new
+pages by zswap.
To prevent zswap from shrinking pool when zswap is full and there's a high
pressure on swap (this will result in flipping pages in and out zswap pool
diff --git a/Documentation/admin-guide/perf/index.rst b/Documentation/admin-guide/perf/index.rst
index 5a8f2529a033..69b23f087c05 100644
--- a/Documentation/admin-guide/perf/index.rst
+++ b/Documentation/admin-guide/perf/index.rst
@@ -8,6 +8,7 @@ Performance monitor support
:maxdepth: 1
hisi-pmu
+ hisi-pcie-pmu
imx-ddr
qcom_l2_pmu
qcom_l3_pmu
diff --git a/Documentation/admin-guide/pm/amd-pstate.rst b/Documentation/admin-guide/pm/amd-pstate.rst
index 2f066df4ee9c..1923cb25073b 100644
--- a/Documentation/admin-guide/pm/amd-pstate.rst
+++ b/Documentation/admin-guide/pm/amd-pstate.rst
@@ -369,6 +369,32 @@ governor (for the policies it is attached to), or by the ``CPUFreq`` core (for t
policies with other scaling governors).
+Tracer Tool
+-------------
+
+``amd_pstate_tracer.py`` can record and parse ``amd-pstate`` trace log, then
+generate performance plots. This utility can be used to debug and tune the
+performance of ``amd-pstate`` driver. The tracer tool needs to import intel
+pstate tracer.
+
+Tracer tool located in ``linux/tools/power/x86/amd_pstate_tracer``. It can be
+used in two ways. If trace file is available, then directly parse the file
+with command ::
+
+ ./amd_pstate_trace.py [-c cpus] -t <trace_file> -n <test_name>
+
+Or generate trace file with root privilege, then parse and plot with command ::
+
+ sudo ./amd_pstate_trace.py [-c cpus] -n <test_name> -i <interval> [-m kbytes]
+
+The test result can be found in ``results/test_name``. Following is the example
+about part of the output. ::
+
+ common_cpu common_secs common_usecs min_perf des_perf max_perf freq mperf apef tsc load duration_ms sample_num elapsed_time common_comm
+ CPU_005 712 116384 39 49 166 0.7565 9645075 2214891 38431470 25.1 11.646 469 2.496 kworker/5:0-40
+ CPU_006 712 116408 39 49 166 0.6769 8950227 1839034 37192089 24.06 11.272 470 2.496 kworker/6:0-1264
+
+
Reference
===========
diff --git a/Documentation/admin-guide/pm/intel_uncore_frequency_scaling.rst b/Documentation/admin-guide/pm/intel_uncore_frequency_scaling.rst
new file mode 100644
index 000000000000..09169d935835
--- /dev/null
+++ b/Documentation/admin-guide/pm/intel_uncore_frequency_scaling.rst
@@ -0,0 +1,60 @@
+.. SPDX-License-Identifier: GPL-2.0
+.. include:: <isonum.txt>
+
+==============================
+Intel Uncore Frequency Scaling
+==============================
+
+:Copyright: |copy| 2022 Intel Corporation
+
+:Author: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
+
+Introduction
+------------
+
+The uncore can consume significant amount of power in Intel's Xeon servers based
+on the workload characteristics. To optimize the total power and improve overall
+performance, SoCs have internal algorithms for scaling uncore frequency. These
+algorithms monitor workload usage of uncore and set a desirable frequency.
+
+It is possible that users have different expectations of uncore performance and
+want to have control over it. The objective is similar to allowing users to set
+the scaling min/max frequencies via cpufreq sysfs to improve CPU performance.
+Users may have some latency sensitive workloads where they do not want any
+change to uncore frequency. Also, users may have workloads which require
+different core and uncore performance at distinct phases and they may want to
+use both cpufreq and the uncore scaling interface to distribute power and
+improve overall performance.
+
+Sysfs Interface
+---------------
+
+To control uncore frequency, a sysfs interface is provided in the directory:
+`/sys/devices/system/cpu/intel_uncore_frequency/`.
+
+There is one directory for each package and die combination as the scope of
+uncore scaling control is per die in multiple die/package SoCs or per
+package for single die per package SoCs. The name represents the
+scope of control. For example: 'package_00_die_00' is for package id 0 and
+die 0.
+
+Each package_*_die_* contains the following attributes:
+
+``initial_max_freq_khz``
+ Out of reset, this attribute represent the maximum possible frequency.
+ This is a read-only attribute. If users adjust max_freq_khz,
+ they can always go back to maximum using the value from this attribute.
+
+``initial_min_freq_khz``
+ Out of reset, this attribute represent the minimum possible frequency.
+ This is a read-only attribute. If users adjust min_freq_khz,
+ they can always go back to minimum using the value from this attribute.
+
+``max_freq_khz``
+ This attribute is used to set the maximum uncore frequency.
+
+``min_freq_khz``
+ This attribute is used to set the minimum uncore frequency.
+
+``current_freq_khz``
+ This attribute is used to get the current uncore frequency.
diff --git a/Documentation/admin-guide/pm/working-state.rst b/Documentation/admin-guide/pm/working-state.rst
index 5d2757e2de65..ee45887811ff 100644
--- a/Documentation/admin-guide/pm/working-state.rst
+++ b/Documentation/admin-guide/pm/working-state.rst
@@ -15,3 +15,4 @@ Working-State Power Management
cpufreq_drivers
intel_epb
intel-speed-select
+ intel_uncore_frequency_scaling
diff --git a/Documentation/admin-guide/reporting-issues.rst b/Documentation/admin-guide/reporting-issues.rst
index d7ac13f789cc..ec62151fe672 100644
--- a/Documentation/admin-guide/reporting-issues.rst
+++ b/Documentation/admin-guide/reporting-issues.rst
@@ -1,14 +1,5 @@
.. SPDX-License-Identifier: (GPL-2.0+ OR CC-BY-4.0)
-..
- If you want to distribute this text under CC-BY-4.0 only, please use 'The
- Linux kernel developers' for author attribution and link this as source:
- https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/plain/Documentation/admin-guide/reporting-issues.rst
-..
- Note: Only the content of this RST file as found in the Linux kernel sources
- is available under CC-BY-4.0, as versions of this text that were processed
- (for example by the kernel's build system) might contain content taken from
- files which use a more restrictive license.
-
+.. See the bottom of this file for additional redistribution information.
Reporting issues
++++++++++++++++
@@ -395,22 +386,16 @@ fixed as soon as possible, hence there are 'issues of high priority' that get
handled slightly differently in the reporting process. Three type of cases
qualify: regressions, security issues, and really severe problems.
-You deal with a 'regression' if something that worked with an older version of
-the Linux kernel does not work with a newer one or somehow works worse with it.
-It thus is a regression when a WiFi driver that did a fine job with Linux 5.7
-somehow misbehaves with 5.8 or doesn't work at all. It's also a regression if
-an application shows erratic behavior with a newer kernel, which might happen
-due to incompatible changes in the interface between the kernel and the
-userland (like procfs and sysfs). Significantly reduced performance or
-increased power consumption also qualify as regression. But keep in mind: the
-new kernel needs to be built with a configuration that is similar to the one
-from the old kernel (see below how to achieve that). That's because the kernel
-developers sometimes can not avoid incompatibilities when implementing new
-features; but to avoid regressions such features have to be enabled explicitly
-during build time configuration.
+You deal with a regression if some application or practical use case running
+fine with one Linux kernel works worse or not at all with a newer version
+compiled using a similar configuration. The document
+Documentation/admin-guide/reporting-regressions.rst explains this in more
+detail. It also provides a good deal of other information about regressions you
+might want to be aware of; it for example explains how to add your issue to the
+list of tracked regressions, to ensure it won't fall through the cracks.
What qualifies as security issue is left to your judgment. Consider reading
-'Documentation/admin-guide/security-bugs.rst' before proceeding, as it
+Documentation/admin-guide/security-bugs.rst before proceeding, as it
provides additional details how to best handle security issues.
An issue is a 'really severe problem' when something totally unacceptably bad
@@ -517,7 +502,7 @@ line starting with 'CPU:'. It should end with 'Not tainted' if the kernel was
not tainted when it noticed the problem; it was tainted if you see 'Tainted:'
followed by a few spaces and some letters.
-If your kernel is tainted, study 'Documentation/admin-guide/tainted-kernels.rst'
+If your kernel is tainted, study Documentation/admin-guide/tainted-kernels.rst
to find out why. Try to eliminate the reason. Often it's caused by one these
three things:
@@ -1043,7 +1028,7 @@ down the culprit, as maintainers often won't have the time or setup at hand to
reproduce it themselves.
To find the change there is a process called 'bisection' which the document
-'Documentation/admin-guide/bug-bisect.rst' describes in detail. That process
+Documentation/admin-guide/bug-bisect.rst describes in detail. That process
will often require you to build about ten to twenty kernel images, trying to
reproduce the issue with each of them before building the next. Yes, that takes
some time, but don't worry, it works a lot quicker than most people assume.
@@ -1073,10 +1058,11 @@ When dealing with regressions make sure the issue you face is really caused by
the kernel and not by something else, as outlined above already.
In the whole process keep in mind: an issue only qualifies as regression if the
-older and the newer kernel got built with a similar configuration. The best way
-to archive this: copy the configuration file (``.config``) from the old working
-kernel freshly to each newer kernel version you try. Afterwards run ``make
-olddefconfig`` to adjust it for the needs of the new version.
+older and the newer kernel got built with a similar configuration. This can be
+achieved by using ``make olddefconfig``, as explained in more detail by
+Documentation/admin-guide/reporting-regressions.rst; that document also
+provides a good deal of other information about regressions you might want to be
+aware of.
Write and send the report
@@ -1283,7 +1269,7 @@ them when sending the report by mail. If you filed it in a bug tracker, forward
the report's text to these addresses; but on top of it put a small note where
you mention that you filed it with a link to the ticket.
-See 'Documentation/admin-guide/security-bugs.rst' for more information.
+See Documentation/admin-guide/security-bugs.rst for more information.
Duties after the report went out
@@ -1571,7 +1557,7 @@ Once your report is out your might get asked to do a proper one, as it allows to
pinpoint the exact change that causes the issue (which then can easily get
reverted to fix the issue quickly). Hence consider to do a proper bisection
right away if time permits. See the section 'Special care for regressions' and
-the document 'Documentation/admin-guide/bug-bisect.rst' for details how to
+the document Documentation/admin-guide/bug-bisect.rst for details how to
perform one. In case of a successful bisection add the author of the culprit to
the recipients; also CC everyone in the signed-off-by chain, which you find at
the end of its commit message.
@@ -1594,7 +1580,7 @@ Some fixes are too complex
Even small and seemingly obvious code-changes sometimes introduce new and
totally unexpected problems. The maintainers of the stable and longterm kernels
are very aware of that and thus only apply changes to these kernels that are
-within rules outlined in 'Documentation/process/stable-kernel-rules.rst'.
+within rules outlined in Documentation/process/stable-kernel-rules.rst.
Complex or risky changes for example do not qualify and thus only get applied
to mainline. Other fixes are easy to get backported to the newest stable and
@@ -1756,10 +1742,23 @@ art will lay some groundwork to improve the situation over time.
..
- This text is maintained by Thorsten Leemhuis <linux@leemhuis.info>. If you
- spot a typo or small mistake, feel free to let him know directly and he'll
- fix it. You are free to do the same in a mostly informal way if you want
- to contribute changes to the text, but for copyright reasons please CC
+ end-of-content
+..
+ This document is maintained by Thorsten Leemhuis <linux@leemhuis.info>. If
+ you spot a typo or small mistake, feel free to let him know directly and
+ he'll fix it. You are free to do the same in a mostly informal way if you
+ want to contribute changes to the text, but for copyright reasons please CC
linux-doc@vger.kernel.org and "sign-off" your contribution as
Documentation/process/submitting-patches.rst outlines in the section "Sign
your work - the Developer's Certificate of Origin".
+..
+ This text is available under GPL-2.0+ or CC-BY-4.0, as stated at the top
+ of the file. If you want to distribute this text under CC-BY-4.0 only,
+ please use "The Linux kernel developers" for author attribution and link
+ this as source:
+ https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/plain/Documentation/admin-guide/reporting-issues.rst
+..
+ Note: Only the content of this RST file as found in the Linux kernel sources
+ is available under CC-BY-4.0, as versions of this text that were processed
+ (for example by the kernel's build system) might contain content taken from
+ files which use a more restrictive license.
diff --git a/Documentation/admin-guide/reporting-regressions.rst b/Documentation/admin-guide/reporting-regressions.rst
new file mode 100644
index 000000000000..d8adccdae23f
--- /dev/null
+++ b/Documentation/admin-guide/reporting-regressions.rst
@@ -0,0 +1,451 @@
+.. SPDX-License-Identifier: (GPL-2.0+ OR CC-BY-4.0)
+.. [see the bottom of this file for redistribution information]
+
+Reporting regressions
++++++++++++++++++++++
+
+"*We don't cause regressions*" is the first rule of Linux kernel development;
+Linux founder and lead developer Linus Torvalds established it himself and
+ensures it's obeyed.
+
+This document describes what the rule means for users and how the Linux kernel's
+development model ensures to address all reported regressions; aspects relevant
+for kernel developers are left to Documentation/process/handling-regressions.rst.
+
+
+The important bits (aka "TL;DR")
+================================
+
+#. It's a regression if something running fine with one Linux kernel works worse
+ or not at all with a newer version. Note, the newer kernel has to be compiled
+ using a similar configuration; the detailed explanations below describes this
+ and other fine print in more detail.
+
+#. Report your issue as outlined in Documentation/admin-guide/reporting-issues.rst,
+ it already covers all aspects important for regressions and repeated
+ below for convenience. Two of them are important: start your report's subject
+ with "[REGRESSION]" and CC or forward it to `the regression mailing list
+ <https://lore.kernel.org/regressions/>`_ (regressions@lists.linux.dev).
+
+#. Optional, but recommended: when sending or forwarding your report, make the
+ Linux kernel regression tracking bot "regzbot" track the issue by specifying
+ when the regression started like this::
+
+ #regzbot introduced v5.13..v5.14-rc1
+
+
+All the details on Linux kernel regressions relevant for users
+==============================================================
+
+
+The important basics
+--------------------
+
+
+What is a "regression" and what is the "no regressions rule"?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+It's a regression if some application or practical use case running fine with
+one Linux kernel works worse or not at all with a newer version compiled using a
+similar configuration. The "no regressions rule" forbids this to take place; if
+it happens by accident, developers that caused it are expected to quickly fix
+the issue.
+
+It thus is a regression when a WiFi driver from Linux 5.13 works fine, but with
+5.14 doesn't work at all, works significantly slower, or misbehaves somehow.
+It's also a regression if a perfectly working application suddenly shows erratic
+behavior with a newer kernel version; such issues can be caused by changes in
+procfs, sysfs, or one of the many other interfaces Linux provides to userland
+software. But keep in mind, as mentioned earlier: 5.14 in this example needs to
+be built from a configuration similar to the one from 5.13. This can be achieved
+using ``make olddefconfig``, as explained in more detail below.
+
+Note the "practical use case" in the first sentence of this section: developers
+despite the "no regressions" rule are free to change any aspect of the kernel
+and even APIs or ABIs to userland, as long as no existing application or use
+case breaks.
+
+Also be aware the "no regressions" rule covers only interfaces the kernel
+provides to the userland. It thus does not apply to kernel-internal interfaces
+like the module API, which some externally developed drivers use to hook into
+the kernel.
+
+How do I report a regression?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Just report the issue as outlined in
+Documentation/admin-guide/reporting-issues.rst, it already describes the
+important points. The following aspects outlined there are especially relevant
+for regressions:
+
+ * When checking for existing reports to join, also search the `archives of the
+ Linux regressions mailing list <https://lore.kernel.org/regressions/>`_ and
+ `regzbot's web-interface <https://linux-regtracking.leemhuis.info/regzbot/>`_.
+
+ * Start your report's subject with "[REGRESSION]".
+
+ * In your report, clearly mention the last kernel version that worked fine and
+ the first broken one. Ideally try to find the exact change causing the
+ regression using a bisection, as explained below in more detail.
+
+ * Remember to let the Linux regressions mailing list
+ (regressions@lists.linux.dev) know about your report:
+
+ * If you report the regression by mail, CC the regressions list.
+
+ * If you report your regression to some bug tracker, forward the submitted
+ report by mail to the regressions list while CCing the maintainer and the
+ mailing list for the subsystem in question.
+
+ If it's a regression within a stable or longterm series (e.g.
+ v5.15.3..v5.15.5), remember to CC the `Linux stable mailing list
+ <https://lore.kernel.org/stable/>`_ (stable@vger.kernel.org).
+
+ In case you performed a successful bisection, add everyone to the CC the
+ culprit's commit message mentions in lines starting with "Signed-off-by:".
+
+When CCing for forwarding your report to the list, consider directly telling the
+aforementioned Linux kernel regression tracking bot about your report. To do
+that, include a paragraph like this in your mail::
+
+ #regzbot introduced: v5.13..v5.14-rc1
+
+Regzbot will then consider your mail a report for a regression introduced in the
+specified version range. In above case Linux v5.13 still worked fine and Linux
+v5.14-rc1 was the first version where you encountered the issue. If you
+performed a bisection to find the commit that caused the regression, specify the
+culprit's commit-id instead::
+
+ #regzbot introduced: 1f2e3d4c5d
+
+Placing such a "regzbot command" is in your interest, as it will ensure the
+report won't fall through the cracks unnoticed. If you omit this, the Linux
+kernel's regressions tracker will take care of telling regzbot about your
+regression, as long as you send a copy to the regressions mailing lists. But the
+regression tracker is just one human which sometimes has to rest or occasionally
+might even enjoy some time away from computers (as crazy as that might sound).
+Relying on this person thus will result in an unnecessary delay before the
+regressions becomes mentioned `on the list of tracked and unresolved Linux
+kernel regressions <https://linux-regtracking.leemhuis.info/regzbot/>`_ and the
+weekly regression reports sent by regzbot. Such delays can result in Linus
+Torvalds being unaware of important regressions when deciding between "continue
+development or call this finished and release the final?".
+
+Are really all regressions fixed?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Nearly all of them are, as long as the change causing the regression (the
+"culprit commit") is reliably identified. Some regressions can be fixed without
+this, but often it's required.
+
+Who needs to find the root cause of a regression?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Developers of the affected code area should try to locate the culprit on their
+own. But for them that's often impossible to do with reasonable effort, as quite
+a lot of issues only occur in a particular environment outside the developer's
+reach -- for example, a specific hardware platform, firmware, Linux distro,
+system's configuration, or application. That's why in the end it's often up to
+the reporter to locate the culprit commit; sometimes users might even need to
+run additional tests afterwards to pinpoint the exact root cause. Developers
+should offer advice and reasonably help where they can, to make this process
+relatively easy and achievable for typical users.
+
+How can I find the culprit?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Perform a bisection, as roughly outlined in
+Documentation/admin-guide/reporting-issues.rst and described in more detail by
+Documentation/admin-guide/bug-bisect.rst. It might sound like a lot of work, but
+in many cases finds the culprit relatively quickly. If it's hard or
+time-consuming to reliably reproduce the issue, consider teaming up with other
+affected users to narrow down the search range together.
+
+Who can I ask for advice when it comes to regressions?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Send a mail to the regressions mailing list (regressions@lists.linux.dev) while
+CCing the Linux kernel's regression tracker (regressions@leemhuis.info); if the
+issue might better be dealt with in private, feel free to omit the list.
+
+
+Additional details about regressions
+------------------------------------
+
+
+What is the goal of the "no regressions rule"?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Users should feel safe when updating kernel versions and not have to worry
+something might break. This is in the interest of the kernel developers to make
+updating attractive: they don't want users to stay on stable or longterm Linux
+series that are either abandoned or more than one and a half years old. That's
+in everybody's interest, as `those series might have known bugs, security
+issues, or other problematic aspects already fixed in later versions
+<http://www.kroah.com/log/blog/2018/08/24/what-stable-kernel-should-i-use/>`_.
+Additionally, the kernel developers want to make it simple and appealing for
+users to test the latest pre-release or regular release. That's also in
+everybody's interest, as it's a lot easier to track down and fix problems, if
+they are reported shortly after being introduced.
+
+Is the "no regressions" rule really adhered in practice?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+It's taken really seriously, as can be seen by many mailing list posts from
+Linux creator and lead developer Linus Torvalds, some of which are quoted in
+Documentation/process/handling-regressions.rst.
+
+Exceptions to this rule are extremely rare; in the past developers almost always
+turned out to be wrong when they assumed a particular situation was warranting
+an exception.
+
+Who ensures the "no regressions" is actually followed?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The subsystem maintainers should take care of that, which are watched and
+supported by the tree maintainers -- e.g. Linus Torvalds for mainline and
+Greg Kroah-Hartman et al. for various stable/longterm series.
+
+All of them are helped by people trying to ensure no regression report falls
+through the cracks. One of them is Thorsten Leemhuis, who's currently acting as
+the Linux kernel's "regressions tracker"; to facilitate this work he relies on
+regzbot, the Linux kernel regression tracking bot. That's why you want to bring
+your report on the radar of these people by CCing or forwarding each report to
+the regressions mailing list, ideally with a "regzbot command" in your mail to
+get it tracked immediately.
+
+How quickly are regressions normally fixed?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Developers should fix any reported regression as quickly as possible, to provide
+affected users with a solution in a timely manner and prevent more users from
+running into the issue; nevertheless developers need to take enough time and
+care to ensure regression fixes do not cause additional damage.
+
+The answer thus depends on various factors like the impact of a regression, its
+age, or the Linux series in which it occurs. In the end though, most regressions
+should be fixed within two weeks.
+
+Is it a regression, if the issue can be avoided by updating some software?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Almost always: yes. If a developer tells you otherwise, ask the regression
+tracker for advice as outlined above.
+
+Is it a regression, if a newer kernel works slower or consumes more energy?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Yes, but the difference has to be significant. A five percent slow-down in a
+micro-benchmark thus is unlikely to qualify as regression, unless it also
+influences the results of a broad benchmark by more than one percent. If in
+doubt, ask for advice.
+
+Is it a regression, if an external kernel module breaks when updating Linux?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+No, as the "no regression" rule is about interfaces and services the Linux
+kernel provides to the userland. It thus does not cover building or running
+externally developed kernel modules, as they run in kernel-space and hook into
+the kernel using internal interfaces occasionally changed.
+
+How are regressions handled that are caused by security fixes?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+In extremely rare situations security issues can't be fixed without causing
+regressions; those fixes are given way, as they are the lesser evil in the end.
+Luckily this middling almost always can be avoided, as key developers for the
+affected area and often Linus Torvalds himself try very hard to fix security
+issues without causing regressions.
+
+If you nevertheless face such a case, check the mailing list archives if people
+tried their best to avoid the regression. If not, report it; if in doubt, ask
+for advice as outlined above.
+
+What happens if fixing a regression is impossible without causing another?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Sadly these things happen, but luckily not very often; if they occur, expert
+developers of the affected code area should look into the issue to find a fix
+that avoids regressions or at least their impact. If you run into such a
+situation, do what was outlined already for regressions caused by security
+fixes: check earlier discussions if people already tried their best and ask for
+advice if in doubt.
+
+A quick note while at it: these situations could be avoided, if people would
+regularly give mainline pre-releases (say v5.15-rc1 or -rc3) from each
+development cycle a test run. This is best explained by imagining a change
+integrated between Linux v5.14 and v5.15-rc1 which causes a regression, but at
+the same time is a hard requirement for some other improvement applied for
+5.15-rc1. All these changes often can simply be reverted and the regression thus
+solved, if someone finds and reports it before 5.15 is released. A few days or
+weeks later this solution can become impossible, as some software might have
+started to rely on aspects introduced by one of the follow-up changes: reverting
+all changes would then cause a regression for users of said software and thus is
+out of the question.
+
+Is it a regression, if some feature I relied on was removed months ago?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+It is, but often it's hard to fix such regressions due to the aspects outlined
+in the previous section. It hence needs to be dealt with on a case-by-case
+basis. This is another reason why it's in everybody's interest to regularly test
+mainline pre-releases.
+
+Does the "no regression" rule apply if I seem to be the only affected person?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+It does, but only for practical usage: the Linux developers want to be free to
+remove support for hardware only to be found in attics and museums anymore.
+
+Note, sometimes regressions can't be avoided to make progress -- and the latter
+is needed to prevent Linux from stagnation. Hence, if only very few users seem
+to be affected by a regression, it for the greater good might be in their and
+everyone else's interest to lettings things pass. Especially if there is an
+easy way to circumvent the regression somehow, for example by updating some
+software or using a kernel parameter created just for this purpose.
+
+Does the regression rule apply for code in the staging tree as well?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Not according to the `help text for the configuration option covering all
+staging code <https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/staging/Kconfig>`_,
+which since its early days states::
+
+ Please note that these drivers are under heavy development, may or
+ may not work, and may contain userspace interfaces that most likely
+ will be changed in the near future.
+
+The staging developers nevertheless often adhere to the "no regressions" rule,
+but sometimes bend it to make progress. That's for example why some users had to
+deal with (often negligible) regressions when a WiFi driver from the staging
+tree was replaced by a totally different one written from scratch.
+
+Why do later versions have to be "compiled with a similar configuration"?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Because the Linux kernel developers sometimes integrate changes known to cause
+regressions, but make them optional and disable them in the kernel's default
+configuration. This trick allows progress, as the "no regressions" rule
+otherwise would lead to stagnation.
+
+Consider for example a new security feature blocking access to some kernel
+interfaces often abused by malware, which at the same time are required to run a
+few rarely used applications. The outlined approach makes both camps happy:
+people using these applications can leave the new security feature off, while
+everyone else can enable it without running into trouble.
+
+How to create a configuration similar to the one of an older kernel?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Start your machine with a known-good kernel and configure the newer Linux
+version with ``make olddefconfig``. This makes the kernel's build scripts pick
+up the configuration file (the ".config" file) from the running kernel as base
+for the new one you are about to compile; afterwards they set all new
+configuration options to their default value, which should disable new features
+that might cause regressions.
+
+Can I report a regression I found with pre-compiled vanilla kernels?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You need to ensure the newer kernel was compiled with a similar configuration
+file as the older one (see above), as those that built them might have enabled
+some known-to-be incompatible feature for the newer kernel. If in doubt, report
+the matter to the kernel's provider and ask for advice.
+
+
+More about regression tracking with "regzbot"
+---------------------------------------------
+
+What is regression tracking and why should I care about it?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Rules like "no regressions" need someone to ensure they are followed, otherwise
+they are broken either accidentally or on purpose. History has shown this to be
+true for Linux kernel development as well. That's why Thorsten Leemhuis, the
+Linux Kernel's regression tracker, and some people try to ensure all regression
+are fixed by keeping an eye on them until they are resolved. Neither of them are
+paid for this, that's why the work is done on a best effort basis.
+
+Why and how are Linux kernel regressions tracked using a bot?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Tracking regressions completely manually has proven to be quite hard due to the
+distributed and loosely structured nature of Linux kernel development process.
+That's why the Linux kernel's regression tracker developed regzbot to facilitate
+the work, with the long term goal to automate regression tracking as much as
+possible for everyone involved.
+
+Regzbot works by watching for replies to reports of tracked regressions.
+Additionally, it's looking out for posted or committed patches referencing such
+reports with "Link:" tags; replies to such patch postings are tracked as well.
+Combined this data provides good insights into the current state of the fixing
+process.
+
+How to see which regressions regzbot tracks currently?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Check out `regzbot's web-interface <https://linux-regtracking.leemhuis.info/regzbot/>`_.
+
+What kind of issues are supposed to be tracked by regzbot?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The bot is meant to track regressions, hence please don't involve regzbot for
+regular issues. But it's okay for the Linux kernel's regression tracker if you
+involve regzbot to track severe issues, like reports about hangs, corrupted
+data, or internal errors (Panic, Oops, BUG(), warning, ...).
+
+How to change aspects of a tracked regression?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+By using a 'regzbot command' in a direct or indirect reply to the mail with the
+report. The easiest way to do that: find the report in your "Sent" folder or the
+mailing list archive and reply to it using your mailer's "Reply-all" function.
+In that mail, use one of the following commands in a stand-alone paragraph (IOW:
+use blank lines to separate one or multiple of these commands from the rest of
+the mail's text).
+
+ * Update when the regression started to happen, for example after performing a
+ bisection::
+
+ #regzbot introduced: 1f2e3d4c5d
+
+ * Set or update the title::
+
+ #regzbot title: foo
+
+ * Monitor a discussion or bugzilla.kernel.org ticket where additions aspects of
+ the issue or a fix are discussed:::
+
+ #regzbot monitor: https://lore.kernel.org/r/30th.anniversary.repost@klaava.Helsinki.FI/
+ #regzbot monitor: https://bugzilla.kernel.org/show_bug.cgi?id=123456789
+
+ * Point to a place with further details of interest, like a mailing list post
+ or a ticket in a bug tracker that are slightly related, but about a different
+ topic::
+
+ #regzbot link: https://bugzilla.kernel.org/show_bug.cgi?id=123456789
+
+ * Mark a regression as invalid::
+
+ #regzbot invalid: wasn't a regression, problem has always existed
+
+Regzbot supports a few other commands primarily used by developers or people
+tracking regressions. They and more details about the aforementioned regzbot
+commands can be found in the `getting started guide
+<https://gitlab.com/knurd42/regzbot/-/blob/main/docs/getting_started.md>`_ and
+the `reference documentation <https://gitlab.com/knurd42/regzbot/-/blob/main/docs/reference.md>`_
+for regzbot.
+
+..
+ end-of-content
+..
+ This text is available under GPL-2.0+ or CC-BY-4.0, as stated at the top
+ of the file. If you want to distribute this text under CC-BY-4.0 only,
+ please use "The Linux kernel developers" for author attribution and link
+ this as source:
+ https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/plain/Documentation/admin-guide/reporting-regressions.rst
+..
+ Note: Only the content of this RST file as found in the Linux kernel sources
+ is available under CC-BY-4.0, as versions of this text that were processed
+ (for example by the kernel's build system) might contain content taken from
+ files which use a more restrictive license.
diff --git a/Documentation/admin-guide/sysctl/kernel.rst b/Documentation/admin-guide/sysctl/kernel.rst
index d359bcfadd39..1144ea3229a3 100644
--- a/Documentation/admin-guide/sysctl/kernel.rst
+++ b/Documentation/admin-guide/sysctl/kernel.rst
@@ -595,65 +595,33 @@ Documentation/admin-guide/kernel-parameters.rst).
numa_balancing
==============
-Enables/disables automatic page fault based NUMA memory
-balancing. Memory is moved automatically to nodes
-that access it often.
+Enables/disables and configures automatic page fault based NUMA memory
+balancing. Memory is moved automatically to nodes that access it often.
+The value to set can be the result of ORing the following:
-Enables/disables automatic NUMA memory balancing. On NUMA machines, there
-is a performance penalty if remote memory is accessed by a CPU. When this
-feature is enabled the kernel samples what task thread is accessing memory
-by periodically unmapping pages and later trapping a page fault. At the
-time of the page fault, it is determined if the data being accessed should
-be migrated to a local memory node.
+= =================================
+0 NUMA_BALANCING_DISABLED
+1 NUMA_BALANCING_NORMAL
+2 NUMA_BALANCING_MEMORY_TIERING
+= =================================
+
+Or NUMA_BALANCING_NORMAL to optimize page placement among different
+NUMA nodes to reduce remote accessing. On NUMA machines, there is a
+performance penalty if remote memory is accessed by a CPU. When this
+feature is enabled the kernel samples what task thread is accessing
+memory by periodically unmapping pages and later trapping a page
+fault. At the time of the page fault, it is determined if the data
+being accessed should be migrated to a local memory node.
The unmapping of pages and trapping faults incur additional overhead that
ideally is offset by improved memory locality but there is no universal
guarantee. If the target workload is already bound to NUMA nodes then this
-feature should be disabled. Otherwise, if the system overhead from the
-feature is too high then the rate the kernel samples for NUMA hinting
-faults may be controlled by the `numa_balancing_scan_period_min_ms,
-numa_balancing_scan_delay_ms, numa_balancing_scan_period_max_ms,
-numa_balancing_scan_size_mb`_, and numa_balancing_settle_count sysctls.
-
-
-numa_balancing_scan_period_min_ms, numa_balancing_scan_delay_ms, numa_balancing_scan_period_max_ms, numa_balancing_scan_size_mb
-===============================================================================================================================
-
-
-Automatic NUMA balancing scans tasks address space and unmaps pages to
-detect if pages are properly placed or if the data should be migrated to a
-memory node local to where the task is running. Every "scan delay" the task
-scans the next "scan size" number of pages in its address space. When the
-end of the address space is reached the scanner restarts from the beginning.
-
-In combination, the "scan delay" and "scan size" determine the scan rate.
-When "scan delay" decreases, the scan rate increases. The scan delay and
-hence the scan rate of every task is adaptive and depends on historical
-behaviour. If pages are properly placed then the scan delay increases,
-otherwise the scan delay decreases. The "scan size" is not adaptive but
-the higher the "scan size", the higher the scan rate.
-
-Higher scan rates incur higher system overhead as page faults must be
-trapped and potentially data must be migrated. However, the higher the scan
-rate, the more quickly a tasks memory is migrated to a local node if the
-workload pattern changes and minimises performance impact due to remote
-memory accesses. These sysctls control the thresholds for scan delays and
-the number of pages scanned.
-
-``numa_balancing_scan_period_min_ms`` is the minimum time in milliseconds to
-scan a tasks virtual memory. It effectively controls the maximum scanning
-rate for each task.
-
-``numa_balancing_scan_delay_ms`` is the starting "scan delay" used for a task
-when it initially forks.
-
-``numa_balancing_scan_period_max_ms`` is the maximum time in milliseconds to
-scan a tasks virtual memory. It effectively controls the minimum scanning
-rate for each task.
-
-``numa_balancing_scan_size_mb`` is how many megabytes worth of pages are
-scanned for a given scan.
+feature should be disabled.
+Or NUMA_BALANCING_MEMORY_TIERING to optimize page placement among
+different types of memory (represented as different NUMA nodes) to
+place the hot pages in the fast memory. This is implemented based on
+unmapping and page fault too.
oops_all_cpu_backtrace
======================
@@ -795,6 +763,8 @@ bit 1 print system memory info
bit 2 print timer info
bit 3 print locks info if ``CONFIG_LOCKDEP`` is on
bit 4 print ftrace buffer
+bit 5 print all printk messages in buffer
+bit 6 print all CPUs backtrace (if available in the arch)
===== ============================================
So for example to print tasks and memory info on panic, user can::
@@ -1029,23 +999,17 @@ This is a directory, with the following entries:
* ``poolsize``: the entropy pool size, in bits;
* ``urandom_min_reseed_secs``: obsolete (used to determine the minimum
- number of seconds between urandom pool reseeding).
+ number of seconds between urandom pool reseeding). This file is
+ writable for compatibility purposes, but writing to it has no effect
+ on any RNG behavior.
* ``uuid``: a UUID generated every time this is retrieved (this can
thus be used to generate UUIDs at will);
* ``write_wakeup_threshold``: when the entropy count drops below this
(as a number of bits), processes waiting to write to ``/dev/random``
- are woken up.
-
-If ``drivers/char/random.c`` is built with ``ADD_INTERRUPT_BENCH``
-defined, these additional entries are present:
-
-* ``add_interrupt_avg_cycles``: the average number of cycles between
- interrupts used to feed the pool;
-
-* ``add_interrupt_avg_deviation``: the standard deviation seen on the
- number of cycles between interrupts used to feed the pool.
+ are woken up. This file is writable for compatibility purposes, but
+ writing to it has no effect on any RNG behavior.
randomize_va_space
diff --git a/Documentation/admin-guide/sysctl/net.rst b/Documentation/admin-guide/sysctl/net.rst
index 4150f74c521a..f86b5e1623c6 100644
--- a/Documentation/admin-guide/sysctl/net.rst
+++ b/Documentation/admin-guide/sysctl/net.rst
@@ -365,6 +365,15 @@ new netns has been created.
Default : 0 (for compatibility reasons)
+txrehash
+--------
+
+Controls default hash rethink behaviour on listening socket when SO_TXREHASH
+option is set to SOCK_TXREHASH_DEFAULT (i. e. not overridden by setsockopt).
+
+If set to 1 (default), hash rethink is performed on listening socket.
+If set to 0, hash rethink is not performed.
+
2. /proc/sys/net/unix - Parameters for Unix domain sockets
----------------------------------------------------------
diff --git a/Documentation/arm/marvell.rst b/Documentation/arm/marvell.rst
index 9485a5a2e2e9..2f41caa0096c 100644
--- a/Documentation/arm/marvell.rst
+++ b/Documentation/arm/marvell.rst
@@ -266,10 +266,12 @@ Avanta family
-------------
Flavors:
+ - 88F6500
- 88F6510
- 88F6530P
- 88F6550
- 88F6560
+ - 88F6601
Homepage:
https://web.archive.org/web/20181005145041/http://www.marvell.com/broadband/
diff --git a/Documentation/arm64/booting.rst b/Documentation/arm64/booting.rst
index 52d060caf8bb..29884b261aa9 100644
--- a/Documentation/arm64/booting.rst
+++ b/Documentation/arm64/booting.rst
@@ -10,9 +10,9 @@ This document is based on the ARM booting document by Russell King and
is relevant to all public releases of the AArch64 Linux kernel.
The AArch64 exception model is made up of a number of exception levels
-(EL0 - EL3), with EL0 and EL1 having a secure and a non-secure
-counterpart. EL2 is the hypervisor level and exists only in non-secure
-mode. EL3 is the highest priority level and exists only in secure mode.
+(EL0 - EL3), with EL0, EL1 and EL2 having a secure and a non-secure
+counterpart. EL2 is the hypervisor level, EL3 is the highest priority
+level and exists only in secure mode. Both are architecturally optional.
For the purposes of this document, we will use the term `boot loader`
simply to define all software that executes on the CPU(s) before control
@@ -167,8 +167,8 @@ Before jumping into the kernel, the following conditions must be met:
All forms of interrupts must be masked in PSTATE.DAIF (Debug, SError,
IRQ and FIQ).
- The CPU must be in either EL2 (RECOMMENDED in order to have access to
- the virtualisation extensions) or non-secure EL1.
+ The CPU must be in non-secure state, either in EL2 (RECOMMENDED in order
+ to have access to the virtualisation extensions), or in EL1.
- Caches, MMUs
diff --git a/Documentation/arm64/elf_hwcaps.rst b/Documentation/arm64/elf_hwcaps.rst
index b72ff17d600a..a8f30963e550 100644
--- a/Documentation/arm64/elf_hwcaps.rst
+++ b/Documentation/arm64/elf_hwcaps.rst
@@ -259,6 +259,11 @@ HWCAP2_RPRES
Functionality implied by ID_AA64ISAR2_EL1.RPRES == 0b0001.
+HWCAP2_MTE3
+
+ Functionality implied by ID_AA64PFR1_EL1.MTE == 0b0011, as described
+ by Documentation/arm64/memory-tagging-extension.rst.
+
4. Unused AT_HWCAP bits
-----------------------
diff --git a/Documentation/arm64/memory-tagging-extension.rst b/Documentation/arm64/memory-tagging-extension.rst
index 7b99c8f428eb..dd27f78d7608 100644
--- a/Documentation/arm64/memory-tagging-extension.rst
+++ b/Documentation/arm64/memory-tagging-extension.rst
@@ -76,6 +76,9 @@ configurable behaviours:
with ``.si_code = SEGV_MTEAERR`` and ``.si_addr = 0`` (the faulting
address is unknown).
+- *Asymmetric* - Reads are handled as for synchronous mode while writes
+ are handled as for asynchronous mode.
+
The user can select the above modes, per thread, using the
``prctl(PR_SET_TAGGED_ADDR_CTRL, flags, 0, 0, 0)`` system call where ``flags``
contains any number of the following values in the ``PR_MTE_TCF_MASK``
@@ -91,8 +94,9 @@ mode is specified, the program will run in that mode. If multiple
modes are specified, the mode is selected as described in the "Per-CPU
preferred tag checking modes" section below.
-The current tag check fault mode can be read using the
-``prctl(PR_GET_TAGGED_ADDR_CTRL, 0, 0, 0, 0)`` system call.
+The current tag check fault configuration can be read using the
+``prctl(PR_GET_TAGGED_ADDR_CTRL, 0, 0, 0, 0)`` system call. If
+multiple modes were requested then all will be reported.
Tag checking can also be disabled for a user thread by setting the
``PSTATE.TCO`` bit with ``MSR TCO, #1``.
@@ -139,18 +143,25 @@ tag checking mode as the CPU's preferred tag checking mode.
The preferred tag checking mode for each CPU is controlled by
``/sys/devices/system/cpu/cpu<N>/mte_tcf_preferred``, to which a
-privileged user may write the value ``async`` or ``sync``. The default
-preferred mode for each CPU is ``async``.
+privileged user may write the value ``async``, ``sync`` or ``asymm``. The
+default preferred mode for each CPU is ``async``.
To allow a program to potentially run in the CPU's preferred tag
checking mode, the user program may set multiple tag check fault mode
bits in the ``flags`` argument to the ``prctl(PR_SET_TAGGED_ADDR_CTRL,
-flags, 0, 0, 0)`` system call. If the CPU's preferred tag checking
-mode is in the task's set of provided tag checking modes (this will
-always be the case at present because the kernel only supports two
-tag checking modes, but future kernels may support more modes), that
-mode will be selected. Otherwise, one of the modes in the task's mode
-set will be selected in a currently unspecified manner.
+flags, 0, 0, 0)`` system call. If both synchronous and asynchronous
+modes are requested then asymmetric mode may also be selected by the
+kernel. If the CPU's preferred tag checking mode is in the task's set
+of provided tag checking modes, that mode will be selected. Otherwise,
+one of the modes in the task's mode will be selected by the kernel
+from the task's mode set using the preference order:
+
+ 1. Asynchronous
+ 2. Asymmetric
+ 3. Synchronous
+
+Note that there is no way for userspace to request multiple modes and
+also disable asymmetric mode.
Initial process state
---------------------
@@ -213,6 +224,29 @@ address ABI control and MTE configuration of a process as per the
Documentation/arm64/tagged-address-abi.rst and above. The corresponding
``regset`` is 1 element of 8 bytes (``sizeof(long))``).
+Core dump support
+-----------------
+
+The allocation tags for user memory mapped with ``PROT_MTE`` are dumped
+in the core file as additional ``PT_ARM_MEMTAG_MTE`` segments. The
+program header for such segment is defined as:
+
+:``p_type``: ``PT_ARM_MEMTAG_MTE``
+:``p_flags``: 0
+:``p_offset``: segment file offset
+:``p_vaddr``: segment virtual address, same as the corresponding
+ ``PT_LOAD`` segment
+:``p_paddr``: 0
+:``p_filesz``: segment size in file, calculated as ``p_mem_sz / 32``
+ (two 4-bit tags cover 32 bytes of memory)
+:``p_memsz``: segment size in memory, same as the corresponding
+ ``PT_LOAD`` segment
+:``p_align``: 0
+
+The tags are stored in the core file at ``p_offset`` as two 4-bit tags
+in a byte. With the tag granule of 16 bytes, a 4K page requires 128
+bytes in the core file.
+
Example of correct usage
========================
diff --git a/Documentation/arm64/silicon-errata.rst b/Documentation/arm64/silicon-errata.rst
index 5342e895fb60..466cb9e89047 100644
--- a/Documentation/arm64/silicon-errata.rst
+++ b/Documentation/arm64/silicon-errata.rst
@@ -52,6 +52,12 @@ stable kernels.
| Allwinner | A64/R18 | UNKNOWN1 | SUN50I_ERRATUM_UNKNOWN1 |
+----------------+-----------------+-----------------+-----------------------------+
+----------------+-----------------+-----------------+-----------------------------+
+| ARM | Cortex-A510 | #2064142 | ARM64_ERRATUM_2064142 |
++----------------+-----------------+-----------------+-----------------------------+
+| ARM | Cortex-A510 | #2038923 | ARM64_ERRATUM_2038923 |
++----------------+-----------------+-----------------+-----------------------------+
+| ARM | Cortex-A510 | #1902691 | ARM64_ERRATUM_1902691 |
++----------------+-----------------+-----------------+-----------------------------+
| ARM | Cortex-A53 | #826319 | ARM64_ERRATUM_826319 |
+----------------+-----------------+-----------------+-----------------------------+
| ARM | Cortex-A53 | #827319 | ARM64_ERRATUM_827319 |
@@ -92,12 +98,20 @@ stable kernels.
+----------------+-----------------+-----------------+-----------------------------+
| ARM | Cortex-A77 | #1508412 | ARM64_ERRATUM_1508412 |
+----------------+-----------------+-----------------+-----------------------------+
+| ARM | Cortex-A510 | #2051678 | ARM64_ERRATUM_2051678 |
++----------------+-----------------+-----------------+-----------------------------+
+| ARM | Cortex-A510 | #2077057 | ARM64_ERRATUM_2077057 |
++----------------+-----------------+-----------------+-----------------------------+
| ARM | Cortex-A710 | #2119858 | ARM64_ERRATUM_2119858 |
+----------------+-----------------+-----------------+-----------------------------+
| ARM | Cortex-A710 | #2054223 | ARM64_ERRATUM_2054223 |
+----------------+-----------------+-----------------+-----------------------------+
| ARM | Cortex-A710 | #2224489 | ARM64_ERRATUM_2224489 |
+----------------+-----------------+-----------------+-----------------------------+
+| ARM | Cortex-X2 | #2119858 | ARM64_ERRATUM_2119858 |
++----------------+-----------------+-----------------+-----------------------------+
+| ARM | Cortex-X2 | #2224489 | ARM64_ERRATUM_2224489 |
++----------------+-----------------+-----------------+-----------------------------+
| ARM | Neoverse-N1 | #1188873,1418040| ARM64_ERRATUM_1418040 |
+----------------+-----------------+-----------------+-----------------------------+
| ARM | Neoverse-N1 | #1349291 | N/A |
@@ -122,7 +136,7 @@ stable kernels.
+----------------+-----------------+-----------------+-----------------------------+
| Cavium | ThunderX ITS | #23144 | CAVIUM_ERRATUM_23144 |
+----------------+-----------------+-----------------+-----------------------------+
-| Cavium | ThunderX GICv3 | #23154 | CAVIUM_ERRATUM_23154 |
+| Cavium | ThunderX GICv3 | #23154,38545 | CAVIUM_ERRATUM_23154 |
+----------------+-----------------+-----------------+-----------------------------+
| Cavium | ThunderX GICv3 | #38539 | N/A |
+----------------+-----------------+-----------------+-----------------------------+
diff --git a/Documentation/asm-annotations.rst b/Documentation/asm-annotations.rst
index f4bf0f6395fb..a64f2ca469d4 100644
--- a/Documentation/asm-annotations.rst
+++ b/Documentation/asm-annotations.rst
@@ -130,14 +130,13 @@ denoting a range of code via ``SYM_*_START/END`` annotations.
In fact, this kind of annotation corresponds to the now deprecated ``ENTRY``
and ``ENDPROC`` macros.
-* ``SYM_FUNC_START_ALIAS`` and ``SYM_FUNC_START_LOCAL_ALIAS`` serve for those
- who decided to have two or more names for one function. The typical use is::
+* ``SYM_FUNC_ALIAS``, ``SYM_FUNC_ALIAS_LOCAL``, and ``SYM_FUNC_ALIAS_WEAK`` can
+ be used to define multiple names for a function. The typical use is::
- SYM_FUNC_START_ALIAS(__memset)
- SYM_FUNC_START(memset)
+ SYM_FUNC_START(__memset)
... asm insns ...
- SYM_FUNC_END(memset)
- SYM_FUNC_END_ALIAS(__memset)
+ SYN_FUNC_END(__memset)
+ SYM_FUNC_ALIAS(memset, __memset)
In this example, one can call ``__memset`` or ``memset`` with the same
result, except the debug information for the instructions is generated to
diff --git a/Documentation/block/biodoc.rst b/Documentation/block/biodoc.rst
deleted file mode 100644
index 2098477851a4..000000000000
--- a/Documentation/block/biodoc.rst
+++ /dev/null
@@ -1,1164 +0,0 @@
-=====================================================
-Notes on the Generic Block Layer Rewrite in Linux 2.5
-=====================================================
-
-.. note::
-
- It seems that there are lot of outdated stuff here. This seems
- to be written somewhat as a task list. Yet, eventually, something
- here might still be useful.
-
-Notes Written on Jan 15, 2002:
-
- - Jens Axboe <jens.axboe@oracle.com>
- - Suparna Bhattacharya <suparna@in.ibm.com>
-
-Last Updated May 2, 2002
-
-September 2003: Updated I/O Scheduler portions
- - Nick Piggin <npiggin@kernel.dk>
-
-Introduction
-============
-
-These are some notes describing some aspects of the 2.5 block layer in the
-context of the bio rewrite. The idea is to bring out some of the key
-changes and a glimpse of the rationale behind those changes.
-
-Please mail corrections & suggestions to suparna@in.ibm.com.
-
-Credits
-=======
-
-2.5 bio rewrite:
- - Jens Axboe <jens.axboe@oracle.com>
-
-Many aspects of the generic block layer redesign were driven by and evolved
-over discussions, prior patches and the collective experience of several
-people. See sections 8 and 9 for a list of some related references.
-
-The following people helped with review comments and inputs for this
-document:
-
- - Christoph Hellwig <hch@infradead.org>
- - Arjan van de Ven <arjanv@redhat.com>
- - Randy Dunlap <rdunlap@xenotime.net>
- - Andre Hedrick <andre@linux-ide.org>
-
-The following people helped with fixes/contributions to the bio patches
-while it was still work-in-progress:
-
- - David S. Miller <davem@redhat.com>
-
-
-.. Description of Contents:
-
- 1. Scope for tuning of logic to various needs
- 1.1 Tuning based on device or low level driver capabilities
- - Per-queue parameters
- - Highmem I/O support
- - I/O scheduler modularization
- 1.2 Tuning based on high level requirements/capabilities
- 1.2.1 Request Priority/Latency
- 1.3 Direct access/bypass to lower layers for diagnostics and special
- device operations
- 1.3.1 Pre-built commands
- 2. New flexible and generic but minimalist i/o structure or descriptor
- (instead of using buffer heads at the i/o layer)
- 2.1 Requirements/Goals addressed
- 2.2 The bio struct in detail (multi-page io unit)
- 2.3 Changes in the request structure
- 3. Using bios
- 3.1 Setup/teardown (allocation, splitting)
- 3.2 Generic bio helper routines
- 3.2.1 Traversing segments and completion units in a request
- 3.2.2 Setting up DMA scatterlists
- 3.2.3 I/O completion
- 3.2.4 Implications for drivers that do not interpret bios (don't handle
- multiple segments)
- 3.3 I/O submission
- 4. The I/O scheduler
- 5. Scalability related changes
- 5.1 Granular locking: Removal of io_request_lock
- 5.2 Prepare for transition to 64 bit sector_t
- 6. Other Changes/Implications
- 6.1 Partition re-mapping handled by the generic block layer
- 7. A few tips on migration of older drivers
- 8. A list of prior/related/impacted patches/ideas
- 9. Other References/Discussion Threads
-
-
-Bio Notes
-=========
-
-Let us discuss the changes in the context of how some overall goals for the
-block layer are addressed.
-
-1. Scope for tuning the generic logic to satisfy various requirements
-=====================================================================
-
-The block layer design supports adaptable abstractions to handle common
-processing with the ability to tune the logic to an appropriate extent
-depending on the nature of the device and the requirements of the caller.
-One of the objectives of the rewrite was to increase the degree of tunability
-and to enable higher level code to utilize underlying device/driver
-capabilities to the maximum extent for better i/o performance. This is
-important especially in the light of ever improving hardware capabilities
-and application/middleware software designed to take advantage of these
-capabilities.
-
-1.1 Tuning based on low level device / driver capabilities
-----------------------------------------------------------
-
-Sophisticated devices with large built-in caches, intelligent i/o scheduling
-optimizations, high memory DMA support, etc may find some of the
-generic processing an overhead, while for less capable devices the
-generic functionality is essential for performance or correctness reasons.
-Knowledge of some of the capabilities or parameters of the device should be
-used at the generic block layer to take the right decisions on
-behalf of the driver.
-
-How is this achieved ?
-
-Tuning at a per-queue level:
-
-i. Per-queue limits/values exported to the generic layer by the driver
-
-Various parameters that the generic i/o scheduler logic uses are set at
-a per-queue level (e.g maximum request size, maximum number of segments in
-a scatter-gather list, logical block size)
-
-Some parameters that were earlier available as global arrays indexed by
-major/minor are now directly associated with the queue. Some of these may
-move into the block device structure in the future. Some characteristics
-have been incorporated into a queue flags field rather than separate fields
-in themselves. There are blk_queue_xxx functions to set the parameters,
-rather than update the fields directly
-
-Some new queue property settings:
-
- blk_queue_bounce_limit(q, u64 dma_address)
- Enable I/O to highmem pages, dma_address being the
- limit. No highmem default.
-
- blk_queue_max_sectors(q, max_sectors)
- Sets two variables that limit the size of the request.
-
- - The request queue's max_sectors, which is a soft size in
- units of 512 byte sectors, and could be dynamically varied
- by the core kernel.
-
- - The request queue's max_hw_sectors, which is a hard limit
- and reflects the maximum size request a driver can handle
- in units of 512 byte sectors.
-
- The default for both max_sectors and max_hw_sectors is
- 255. The upper limit of max_sectors is 1024.
-
- blk_queue_max_phys_segments(q, max_segments)
- Maximum physical segments you can handle in a request. 128
- default (driver limit). (See 3.2.2)
-
- blk_queue_max_hw_segments(q, max_segments)
- Maximum dma segments the hardware can handle in a request. 128
- default (host adapter limit, after dma remapping).
- (See 3.2.2)
-
- blk_queue_max_segment_size(q, max_seg_size)
- Maximum size of a clustered segment, 64kB default.
-
- blk_queue_logical_block_size(q, logical_block_size)
- Lowest possible sector size that the hardware can operate
- on, 512 bytes default.
-
-New queue flags:
-
- - QUEUE_FLAG_CLUSTER (see 3.2.2)
- - QUEUE_FLAG_QUEUED (see 3.2.4)
-
-
-ii. High-mem i/o capabilities are now considered the default
-
-The generic bounce buffer logic, present in 2.4, where the block layer would
-by default copyin/out i/o requests on high-memory buffers to low-memory buffers
-assuming that the driver wouldn't be able to handle it directly, has been
-changed in 2.5. The bounce logic is now applied only for memory ranges
-for which the device cannot handle i/o. A driver can specify this by
-setting the queue bounce limit for the request queue for the device
-(blk_queue_bounce_limit()). This avoids the inefficiencies of the copyin/out
-where a device is capable of handling high memory i/o.
-
-In order to enable high-memory i/o where the device is capable of supporting
-it, the pci dma mapping routines and associated data structures have now been
-modified to accomplish a direct page -> bus translation, without requiring
-a virtual address mapping (unlike the earlier scheme of virtual address
--> bus translation). So this works uniformly for high-memory pages (which
-do not have a corresponding kernel virtual address space mapping) and
-low-memory pages.
-
-Note: Please refer to Documentation/core-api/dma-api-howto.rst for a discussion
-on PCI high mem DMA aspects and mapping of scatter gather lists, and support
-for 64 bit PCI.
-
-Special handling is required only for cases where i/o needs to happen on
-pages at physical memory addresses beyond what the device can support. In these
-cases, a bounce bio representing a buffer from the supported memory range
-is used for performing the i/o with copyin/copyout as needed depending on
-the type of the operation. For example, in case of a read operation, the
-data read has to be copied to the original buffer on i/o completion, so a
-callback routine is set up to do this, while for write, the data is copied
-from the original buffer to the bounce buffer prior to issuing the
-operation. Since an original buffer may be in a high memory area that's not
-mapped in kernel virtual addr, a kmap operation may be required for
-performing the copy, and special care may be needed in the completion path
-as it may not be in irq context. Special care is also required (by way of
-GFP flags) when allocating bounce buffers, to avoid certain highmem
-deadlock possibilities.
-
-It is also possible that a bounce buffer may be allocated from high-memory
-area that's not mapped in kernel virtual addr, but within the range that the
-device can use directly; so the bounce page may need to be kmapped during
-copy operations. [Note: This does not hold in the current implementation,
-though]
-
-There are some situations when pages from high memory may need to
-be kmapped, even if bounce buffers are not necessary. For example a device
-may need to abort DMA operations and revert to PIO for the transfer, in
-which case a virtual mapping of the page is required. For SCSI it is also
-done in some scenarios where the low level driver cannot be trusted to
-handle a single sg entry correctly. The driver is expected to perform the
-kmaps as needed on such occasions as appropriate. A driver could also use
-the blk_queue_bounce() routine on its own to bounce highmem i/o to low
-memory for specific requests if so desired.
-
-iii. The i/o scheduler algorithm itself can be replaced/set as appropriate
-
-As in 2.4, it is possible to plugin a brand new i/o scheduler for a particular
-queue or pick from (copy) existing generic schedulers and replace/override
-certain portions of it. The 2.5 rewrite provides improved modularization
-of the i/o scheduler. There are more pluggable callbacks, e.g for init,
-add request, extract request, which makes it possible to abstract specific
-i/o scheduling algorithm aspects and details outside of the generic loop.
-It also makes it possible to completely hide the implementation details of
-the i/o scheduler from block drivers.
-
-I/O scheduler wrappers are to be used instead of accessing the queue directly.
-See section 4. The I/O scheduler for details.
-
-1.2 Tuning Based on High level code capabilities
-------------------------------------------------
-
-i. Application capabilities for raw i/o
-
-This comes from some of the high-performance database/middleware
-requirements where an application prefers to make its own i/o scheduling
-decisions based on an understanding of the access patterns and i/o
-characteristics
-
-ii. High performance filesystems or other higher level kernel code's
-capabilities
-
-Kernel components like filesystems could also take their own i/o scheduling
-decisions for optimizing performance. Journalling filesystems may need
-some control over i/o ordering.
-
-What kind of support exists at the generic block layer for this ?
-
-The flags and rw fields in the bio structure can be used for some tuning
-from above e.g indicating that an i/o is just a readahead request, or priority
-settings (currently unused). As far as user applications are concerned they
-would need an additional mechanism either via open flags or ioctls, or some
-other upper level mechanism to communicate such settings to block.
-
-1.2.1 Request Priority/Latency
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-Todo/Under discussion::
-
- Arjan's proposed request priority scheme allows higher levels some broad
- control (high/med/low) over the priority of an i/o request vs other pending
- requests in the queue. For example it allows reads for bringing in an
- executable page on demand to be given a higher priority over pending write
- requests which haven't aged too much on the queue. Potentially this priority
- could even be exposed to applications in some manner, providing higher level
- tunability. Time based aging avoids starvation of lower priority
- requests. Some bits in the bi_opf flags field in the bio structure are
- intended to be used for this priority information.
-
-
-1.3 Direct Access to Low level Device/Driver Capabilities (Bypass mode)
------------------------------------------------------------------------
-
-(e.g Diagnostics, Systems Management)
-
-There are situations where high-level code needs to have direct access to
-the low level device capabilities or requires the ability to issue commands
-to the device bypassing some of the intermediate i/o layers.
-These could, for example, be special control commands issued through ioctl
-interfaces, or could be raw read/write commands that stress the drive's
-capabilities for certain kinds of fitness tests. Having direct interfaces at
-multiple levels without having to pass through upper layers makes
-it possible to perform bottom up validation of the i/o path, layer by
-layer, starting from the media.
-
-The normal i/o submission interfaces, e.g submit_bio, could be bypassed
-for specially crafted requests which such ioctl or diagnostics
-interfaces would typically use, and the elevator add_request routine
-can instead be used to directly insert such requests in the queue or preferably
-the blk_do_rq routine can be used to place the request on the queue and
-wait for completion. Alternatively, sometimes the caller might just
-invoke a lower level driver specific interface with the request as a
-parameter.
-
-If the request is a means for passing on special information associated with
-the command, then such information is associated with the request->special
-field (rather than misuse the request->buffer field which is meant for the
-request data buffer's virtual mapping).
-
-For passing request data, the caller must build up a bio descriptor
-representing the concerned memory buffer if the underlying driver interprets
-bio segments or uses the block layer end*request* functions for i/o
-completion. Alternatively one could directly use the request->buffer field to
-specify the virtual address of the buffer, if the driver expects buffer
-addresses passed in this way and ignores bio entries for the request type
-involved. In the latter case, the driver would modify and manage the
-request->buffer, request->sector and request->nr_sectors or
-request->current_nr_sectors fields itself rather than using the block layer
-end_request or end_that_request_first completion interfaces.
-(See 2.3 or Documentation/block/request.rst for a brief explanation of
-the request structure fields)
-
-::
-
- [TBD: end_that_request_last should be usable even in this case;
- Perhaps an end_that_direct_request_first routine could be implemented to make
- handling direct requests easier for such drivers; Also for drivers that
- expect bios, a helper function could be provided for setting up a bio
- corresponding to a data buffer]
-
- <JENS: I dont understand the above, why is end_that_request_first() not
- usable? Or _last for that matter. I must be missing something>
-
- <SUP: What I meant here was that if the request doesn't have a bio, then
- end_that_request_first doesn't modify nr_sectors or current_nr_sectors,
- and hence can't be used for advancing request state settings on the
- completion of partial transfers. The driver has to modify these fields
- directly by hand.
- This is because end_that_request_first only iterates over the bio list,
- and always returns 0 if there are none associated with the request.
- _last works OK in this case, and is not a problem, as I mentioned earlier
- >
-
-1.3.1 Pre-built Commands
-^^^^^^^^^^^^^^^^^^^^^^^^
-
-A request can be created with a pre-built custom command to be sent directly
-to the device. The cmd block in the request structure has room for filling
-in the command bytes. (i.e rq->cmd is now 16 bytes in size, and meant for
-command pre-building, and the type of the request is now indicated
-through rq->flags instead of via rq->cmd)
-
-The request structure flags can be set up to indicate the type of request
-in such cases (REQ_PC: direct packet command passed to driver, REQ_BLOCK_PC:
-packet command issued via blk_do_rq, REQ_SPECIAL: special request).
-
-It can help to pre-build device commands for requests in advance.
-Drivers can now specify a request prepare function (q->prep_rq_fn) that the
-block layer would invoke to pre-build device commands for a given request,
-or perform other preparatory processing for the request. This is routine is
-called by elv_next_request(), i.e. typically just before servicing a request.
-(The prepare function would not be called for requests that have RQF_DONTPREP
-enabled)
-
-Aside:
- Pre-building could possibly even be done early, i.e before placing the
- request on the queue, rather than construct the command on the fly in the
- driver while servicing the request queue when it may affect latencies in
- interrupt context or responsiveness in general. One way to add early
- pre-building would be to do it whenever we fail to merge on a request.
- Now REQ_NOMERGE is set in the request flags to skip this one in the future,
- which means that it will not change before we feed it to the device. So
- the pre-builder hook can be invoked there.
-
-
-2. Flexible and generic but minimalist i/o structure/descriptor
-===============================================================
-
-2.1 Reason for a new structure and requirements addressed
----------------------------------------------------------
-
-Prior to 2.5, buffer heads were used as the unit of i/o at the generic block
-layer, and the low level request structure was associated with a chain of
-buffer heads for a contiguous i/o request. This led to certain inefficiencies
-when it came to large i/o requests and readv/writev style operations, as it
-forced such requests to be broken up into small chunks before being passed
-on to the generic block layer, only to be merged by the i/o scheduler
-when the underlying device was capable of handling the i/o in one shot.
-Also, using the buffer head as an i/o structure for i/os that didn't originate
-from the buffer cache unnecessarily added to the weight of the descriptors
-which were generated for each such chunk.
-
-The following were some of the goals and expectations considered in the
-redesign of the block i/o data structure in 2.5.
-
-1. Should be appropriate as a descriptor for both raw and buffered i/o -
- avoid cache related fields which are irrelevant in the direct/page i/o path,
- or filesystem block size alignment restrictions which may not be relevant
- for raw i/o.
-2. Ability to represent high-memory buffers (which do not have a virtual
- address mapping in kernel address space).
-3. Ability to represent large i/os w/o unnecessarily breaking them up (i.e
- greater than PAGE_SIZE chunks in one shot)
-4. At the same time, ability to retain independent identity of i/os from
- different sources or i/o units requiring individual completion (e.g. for
- latency reasons)
-5. Ability to represent an i/o involving multiple physical memory segments
- (including non-page aligned page fragments, as specified via readv/writev)
- without unnecessarily breaking it up, if the underlying device is capable of
- handling it.
-6. Preferably should be based on a memory descriptor structure that can be
- passed around different types of subsystems or layers, maybe even
- networking, without duplication or extra copies of data/descriptor fields
- themselves in the process
-7. Ability to handle the possibility of splits/merges as the structure passes
- through layered drivers (lvm, md, evms), with minimal overhead.
-
-The solution was to define a new structure (bio) for the block layer,
-instead of using the buffer head structure (bh) directly, the idea being
-avoidance of some associated baggage and limitations. The bio structure
-is uniformly used for all i/o at the block layer ; it forms a part of the
-bh structure for buffered i/o, and in the case of raw/direct i/o kiobufs are
-mapped to bio structures.
-
-2.2 The bio struct
-------------------
-
-The bio structure uses a vector representation pointing to an array of tuples
-of <page, offset, len> to describe the i/o buffer, and has various other
-fields describing i/o parameters and state that needs to be maintained for
-performing the i/o.
-
-Notice that this representation means that a bio has no virtual address
-mapping at all (unlike buffer heads).
-
-::
-
- struct bio_vec {
- struct page *bv_page;
- unsigned short bv_len;
- unsigned short bv_offset;
- };
-
- /*
- * main unit of I/O for the block layer and lower layers (ie drivers)
- */
- struct bio {
- struct bio *bi_next; /* request queue link */
- struct block_device *bi_bdev; /* target device */
- unsigned long bi_flags; /* status, command, etc */
- unsigned long bi_opf; /* low bits: r/w, high: priority */
-
- unsigned int bi_vcnt; /* how may bio_vec's */
- struct bvec_iter bi_iter; /* current index into bio_vec array */
-
- unsigned int bi_size; /* total size in bytes */
- unsigned short bi_hw_segments; /* segments after DMA remapping */
- unsigned int bi_max; /* max bio_vecs we can hold
- used as index into pool */
- struct bio_vec *bi_io_vec; /* the actual vec list */
- bio_end_io_t *bi_end_io; /* bi_end_io (bio) */
- atomic_t bi_cnt; /* pin count: free when it hits zero */
- void *bi_private;
- };
-
-With this multipage bio design:
-
-- Large i/os can be sent down in one go using a bio_vec list consisting
- of an array of <page, offset, len> fragments (similar to the way fragments
- are represented in the zero-copy network code)
-- Splitting of an i/o request across multiple devices (as in the case of
- lvm or raid) is achieved by cloning the bio (where the clone points to
- the same bi_io_vec array, but with the index and size accordingly modified)
-- A linked list of bios is used as before for unrelated merges [#]_ - this
- avoids reallocs and makes independent completions easier to handle.
-- Code that traverses the req list can find all the segments of a bio
- by using rq_for_each_segment. This handles the fact that a request
- has multiple bios, each of which can have multiple segments.
-- Drivers which can't process a large bio in one shot can use the bi_iter
- field to keep track of the next bio_vec entry to process.
- (e.g a 1MB bio_vec needs to be handled in max 128kB chunks for IDE)
- [TBD: Should preferably also have a bi_voffset and bi_vlen to avoid modifying
- bi_offset an len fields]
-
-.. [#]
-
- unrelated merges -- a request ends up containing two or more bios that
- didn't originate from the same place.
-
-bi_end_io() i/o callback gets called on i/o completion of the entire bio.
-
-At a lower level, drivers build a scatter gather list from the merged bios.
-The scatter gather list is in the form of an array of <page, offset, len>
-entries with their corresponding dma address mappings filled in at the
-appropriate time. As an optimization, contiguous physical pages can be
-covered by a single entry where <page> refers to the first page and <len>
-covers the range of pages (up to 16 contiguous pages could be covered this
-way). There is a helper routine (blk_rq_map_sg) which drivers can use to build
-the sg list.
-
-Note: Right now the only user of bios with more than one page is ll_rw_kio,
-which in turn means that only raw I/O uses it (direct i/o may not work
-right now). The intent however is to enable clustering of pages etc to
-become possible. The pagebuf abstraction layer from SGI also uses multi-page
-bios, but that is currently not included in the stock development kernels.
-The same is true of Andrew Morton's work-in-progress multipage bio writeout
-and readahead patches.
-
-2.3 Changes in the Request Structure
-------------------------------------
-
-The request structure is the structure that gets passed down to low level
-drivers. The block layer make_request function builds up a request structure,
-places it on the queue and invokes the drivers request_fn. The driver makes
-use of block layer helper routine elv_next_request to pull the next request
-off the queue. Control or diagnostic functions might bypass block and directly
-invoke underlying driver entry points passing in a specially constructed
-request structure.
-
-Only some relevant fields (mainly those which changed or may be referred
-to in some of the discussion here) are listed below, not necessarily in
-the order in which they occur in the structure (see include/linux/blkdev.h)
-Refer to Documentation/block/request.rst for details about all the request
-structure fields and a quick reference about the layers which are
-supposed to use or modify those fields::
-
- struct request {
- struct list_head queuelist; /* Not meant to be directly accessed by
- the driver.
- Used by q->elv_next_request_fn
- rq->queue is gone
- */
- .
- .
- unsigned char cmd[16]; /* prebuilt command data block */
- unsigned long flags; /* also includes earlier rq->cmd settings */
- .
- .
- sector_t sector; /* this field is now of type sector_t instead of int
- preparation for 64 bit sectors */
- .
- .
-
- /* Number of scatter-gather DMA addr+len pairs after
- * physical address coalescing is performed.
- */
- unsigned short nr_phys_segments;
-
- /* Number of scatter-gather addr+len pairs after
- * physical and DMA remapping hardware coalescing is performed.
- * This is the number of scatter-gather entries the driver
- * will actually have to deal with after DMA mapping is done.
- */
- unsigned short nr_hw_segments;
-
- /* Various sector counts */
- unsigned long nr_sectors; /* no. of sectors left: driver modifiable */
- unsigned long hard_nr_sectors; /* block internal copy of above */
- unsigned int current_nr_sectors; /* no. of sectors left in the
- current segment:driver modifiable */
- unsigned long hard_cur_sectors; /* block internal copy of the above */
- .
- .
- int tag; /* command tag associated with request */
- void *special; /* same as before */
- char *buffer; /* valid only for low memory buffers up to
- current_nr_sectors */
- .
- .
- struct bio *bio, *biotail; /* bio list instead of bh */
- struct request_list *rl;
- }
-
-See the req_ops and req_flag_bits definitions for an explanation of the various
-flags available. Some bits are used by the block layer or i/o scheduler.
-
-The behaviour of the various sector counts are almost the same as before,
-except that since we have multi-segment bios, current_nr_sectors refers
-to the numbers of sectors in the current segment being processed which could
-be one of the many segments in the current bio (i.e i/o completion unit).
-The nr_sectors value refers to the total number of sectors in the whole
-request that remain to be transferred (no change). The purpose of the
-hard_xxx values is for block to remember these counts every time it hands
-over the request to the driver. These values are updated by block on
-end_that_request_first, i.e. every time the driver completes a part of the
-transfer and invokes block end*request helpers to mark this. The
-driver should not modify these values. The block layer sets up the
-nr_sectors and current_nr_sectors fields (based on the corresponding
-hard_xxx values and the number of bytes transferred) and updates it on
-every transfer that invokes end_that_request_first. It does the same for the
-buffer, bio, bio->bi_iter fields too.
-
-The buffer field is just a virtual address mapping of the current segment
-of the i/o buffer in cases where the buffer resides in low-memory. For high
-memory i/o, this field is not valid and must not be used by drivers.
-
-Code that sets up its own request structures and passes them down to
-a driver needs to be careful about interoperation with the block layer helper
-functions which the driver uses. (Section 1.3)
-
-3. Using bios
-=============
-
-3.1 Setup/Teardown
-------------------
-
-There are routines for managing the allocation, and reference counting, and
-freeing of bios (bio_alloc, bio_get, bio_put).
-
-This makes use of Ingo Molnar's mempool implementation, which enables
-subsystems like bio to maintain their own reserve memory pools for guaranteed
-deadlock-free allocations during extreme VM load. For example, the VM
-subsystem makes use of the block layer to writeout dirty pages in order to be
-able to free up memory space, a case which needs careful handling. The
-allocation logic draws from the preallocated emergency reserve in situations
-where it cannot allocate through normal means. If the pool is empty and it
-can wait, then it would trigger action that would help free up memory or
-replenish the pool (without deadlocking) and wait for availability in the pool.
-If it is in IRQ context, and hence not in a position to do this, allocation
-could fail if the pool is empty. In general mempool always first tries to
-perform allocation without having to wait, even if it means digging into the
-pool as long it is not less that 50% full.
-
-On a free, memory is released to the pool or directly freed depending on
-the current availability in the pool. The mempool interface lets the
-subsystem specify the routines to be used for normal alloc and free. In the
-case of bio, these routines make use of the standard slab allocator.
-
-The caller of bio_alloc is expected to taken certain steps to avoid
-deadlocks, e.g. avoid trying to allocate more memory from the pool while
-already holding memory obtained from the pool.
-
-::
-
- [TBD: This is a potential issue, though a rare possibility
- in the bounce bio allocation that happens in the current code, since
- it ends up allocating a second bio from the same pool while
- holding the original bio ]
-
-Memory allocated from the pool should be released back within a limited
-amount of time (in the case of bio, that would be after the i/o is completed).
-This ensures that if part of the pool has been used up, some work (in this
-case i/o) must already be in progress and memory would be available when it
-is over. If allocating from multiple pools in the same code path, the order
-or hierarchy of allocation needs to be consistent, just the way one deals
-with multiple locks.
-
-The bio_alloc routine also needs to allocate the bio_vec_list (bvec_alloc())
-for a non-clone bio. There are the 6 pools setup for different size biovecs,
-so bio_alloc(gfp_mask, nr_iovecs) will allocate a vec_list of the
-given size from these slabs.
-
-The bio_get() routine may be used to hold an extra reference on a bio prior
-to i/o submission, if the bio fields are likely to be accessed after the
-i/o is issued (since the bio may otherwise get freed in case i/o completion
-happens in the meantime).
-
-The bio_clone_fast() routine may be used to duplicate a bio, where the clone
-shares the bio_vec_list with the original bio (i.e. both point to the
-same bio_vec_list). This would typically be used for splitting i/o requests
-in lvm or md.
-
-3.2 Generic bio helper Routines
--------------------------------
-
-3.2.1 Traversing segments and completion units in a request
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-The macro rq_for_each_segment() should be used for traversing the bios
-in the request list (drivers should avoid directly trying to do it
-themselves). Using these helpers should also make it easier to cope
-with block changes in the future.
-
-::
-
- struct req_iterator iter;
- rq_for_each_segment(bio_vec, rq, iter)
- /* bio_vec is now current segment */
-
-I/O completion callbacks are per-bio rather than per-segment, so drivers
-that traverse bio chains on completion need to keep that in mind. Drivers
-which don't make a distinction between segments and completion units would
-need to be reorganized to support multi-segment bios.
-
-3.2.2 Setting up DMA scatterlists
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-The blk_rq_map_sg() helper routine would be used for setting up scatter
-gather lists from a request, so a driver need not do it on its own.
-
- nr_segments = blk_rq_map_sg(q, rq, scatterlist);
-
-The helper routine provides a level of abstraction which makes it easier
-to modify the internals of request to scatterlist conversion down the line
-without breaking drivers. The blk_rq_map_sg routine takes care of several
-things like collapsing physically contiguous segments (if QUEUE_FLAG_CLUSTER
-is set) and correct segment accounting to avoid exceeding the limits which
-the i/o hardware can handle, based on various queue properties.
-
-- Prevents a clustered segment from crossing a 4GB mem boundary
-- Avoids building segments that would exceed the number of physical
- memory segments that the driver can handle (phys_segments) and the
- number that the underlying hardware can handle at once, accounting for
- DMA remapping (hw_segments) (i.e. IOMMU aware limits).
-
-Routines which the low level driver can use to set up the segment limits:
-
-blk_queue_max_hw_segments() : Sets an upper limit of the maximum number of
-hw data segments in a request (i.e. the maximum number of address/length
-pairs the host adapter can actually hand to the device at once)
-
-blk_queue_max_phys_segments() : Sets an upper limit on the maximum number
-of physical data segments in a request (i.e. the largest sized scatter list
-a driver could handle)
-
-3.2.3 I/O completion
-^^^^^^^^^^^^^^^^^^^^
-
-The existing generic block layer helper routines end_request,
-end_that_request_first and end_that_request_last can be used for i/o
-completion (and setting things up so the rest of the i/o or the next
-request can be kicked of) as before. With the introduction of multi-page
-bio support, end_that_request_first requires an additional argument indicating
-the number of sectors completed.
-
-3.2.4 Implications for drivers that do not interpret bios
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-(don't handle multiple segments)
-
-Drivers that do not interpret bios e.g those which do not handle multiple
-segments and do not support i/o into high memory addresses (require bounce
-buffers) and expect only virtually mapped buffers, can access the rq->buffer
-field. As before the driver should use current_nr_sectors to determine the
-size of remaining data in the current segment (that is the maximum it can
-transfer in one go unless it interprets segments), and rely on the block layer
-end_request, or end_that_request_first/last to take care of all accounting
-and transparent mapping of the next bio segment when a segment boundary
-is crossed on completion of a transfer. (The end*request* functions should
-be used if only if the request has come down from block/bio path, not for
-direct access requests which only specify rq->buffer without a valid rq->bio)
-
-3.3 I/O Submission
-------------------
-
-The routine submit_bio() is used to submit a single io. Higher level i/o
-routines make use of this:
-
-(a) Buffered i/o:
-
-The routine submit_bh() invokes submit_bio() on a bio corresponding to the
-bh, allocating the bio if required. ll_rw_block() uses submit_bh() as before.
-
-(b) Kiobuf i/o (for raw/direct i/o):
-
-The ll_rw_kio() routine breaks up the kiobuf into page sized chunks and
-maps the array to one or more multi-page bios, issuing submit_bio() to
-perform the i/o on each of these.
-
-The embedded bh array in the kiobuf structure has been removed and no
-preallocation of bios is done for kiobufs. [The intent is to remove the
-blocks array as well, but it's currently in there to kludge around direct i/o.]
-Thus kiobuf allocation has switched back to using kmalloc rather than vmalloc.
-
-Todo/Observation:
-
- A single kiobuf structure is assumed to correspond to a contiguous range
- of data, so brw_kiovec() invokes ll_rw_kio for each kiobuf in a kiovec.
- So right now it wouldn't work for direct i/o on non-contiguous blocks.
- This is to be resolved. The eventual direction is to replace kiobuf
- by kvec's.
-
- Badari Pulavarty has a patch to implement direct i/o correctly using
- bio and kvec.
-
-
-(c) Page i/o:
-
-Todo/Under discussion:
-
- Andrew Morton's multi-page bio patches attempt to issue multi-page
- writeouts (and reads) from the page cache, by directly building up
- large bios for submission completely bypassing the usage of buffer
- heads. This work is still in progress.
-
- Christoph Hellwig had some code that uses bios for page-io (rather than
- bh). This isn't included in bio as yet. Christoph was also working on a
- design for representing virtual/real extents as an entity and modifying
- some of the address space ops interfaces to utilize this abstraction rather
- than buffer_heads. (This is somewhat along the lines of the SGI XFS pagebuf
- abstraction, but intended to be as lightweight as possible).
-
-(d) Direct access i/o:
-
-Direct access requests that do not contain bios would be submitted differently
-as discussed earlier in section 1.3.
-
-Aside:
-
- Kvec i/o:
-
- Ben LaHaise's aio code uses a slightly different structure instead
- of kiobufs, called a kvec_cb. This contains an array of <page, offset, len>
- tuples (very much like the networking code), together with a callback function
- and data pointer. This is embedded into a brw_cb structure when passed
- to brw_kvec_async().
-
- Now it should be possible to directly map these kvecs to a bio. Just as while
- cloning, in this case rather than PRE_BUILT bio_vecs, we set the bi_io_vec
- array pointer to point to the veclet array in kvecs.
-
- TBD: In order for this to work, some changes are needed in the way multi-page
- bios are handled today. The values of the tuples in such a vector passed in
- from higher level code should not be modified by the block layer in the course
- of its request processing, since that would make it hard for the higher layer
- to continue to use the vector descriptor (kvec) after i/o completes. Instead,
- all such transient state should either be maintained in the request structure,
- and passed on in some way to the endio completion routine.
-
-
-4. The I/O scheduler
-====================
-
-I/O scheduler, a.k.a. elevator, is implemented in two layers. Generic dispatch
-queue and specific I/O schedulers. Unless stated otherwise, elevator is used
-to refer to both parts and I/O scheduler to specific I/O schedulers.
-
-Block layer implements generic dispatch queue in `block/*.c`.
-The generic dispatch queue is responsible for requeueing, handling non-fs
-requests and all other subtleties.
-
-Specific I/O schedulers are responsible for ordering normal filesystem
-requests. They can also choose to delay certain requests to improve
-throughput or whatever purpose. As the plural form indicates, there are
-multiple I/O schedulers. They can be built as modules but at least one should
-be built inside the kernel. Each queue can choose different one and can also
-change to another one dynamically.
-
-A block layer call to the i/o scheduler follows the convention elv_xxx(). This
-calls elevator_xxx_fn in the elevator switch (block/elevator.c). Oh, xxx
-and xxx might not match exactly, but use your imagination. If an elevator
-doesn't implement a function, the switch does nothing or some minimal house
-keeping work.
-
-4.1. I/O scheduler API
-----------------------
-
-The functions an elevator may implement are: (* are mandatory)
-
-=============================== ================================================
-elevator_merge_fn called to query requests for merge with a bio
-
-elevator_merge_req_fn called when two requests get merged. the one
- which gets merged into the other one will be
- never seen by I/O scheduler again. IOW, after
- being merged, the request is gone.
-
-elevator_merged_fn called when a request in the scheduler has been
- involved in a merge. It is used in the deadline
- scheduler for example, to reposition the request
- if its sorting order has changed.
-
-elevator_allow_merge_fn called whenever the block layer determines
- that a bio can be merged into an existing
- request safely. The io scheduler may still
- want to stop a merge at this point if it
- results in some sort of conflict internally,
- this hook allows it to do that. Note however
- that two *requests* can still be merged at later
- time. Currently the io scheduler has no way to
- prevent that. It can only learn about the fact
- from elevator_merge_req_fn callback.
-
-elevator_dispatch_fn* fills the dispatch queue with ready requests.
- I/O schedulers are free to postpone requests by
- not filling the dispatch queue unless @force
- is non-zero. Once dispatched, I/O schedulers
- are not allowed to manipulate the requests -
- they belong to generic dispatch queue.
-
-elevator_add_req_fn* called to add a new request into the scheduler
-
-elevator_former_req_fn
-elevator_latter_req_fn These return the request before or after the
- one specified in disk sort order. Used by the
- block layer to find merge possibilities.
-
-elevator_completed_req_fn called when a request is completed.
-
-elevator_set_req_fn
-elevator_put_req_fn Must be used to allocate and free any elevator
- specific storage for a request.
-
-elevator_activate_req_fn Called when device driver first sees a request.
- I/O schedulers can use this callback to
- determine when actual execution of a request
- starts.
-elevator_deactivate_req_fn Called when device driver decides to delay
- a request by requeueing it.
-
-elevator_init_fn*
-elevator_exit_fn Allocate and free any elevator specific storage
- for a queue.
-=============================== ================================================
-
-4.2 Request flows seen by I/O schedulers
-----------------------------------------
-
-All requests seen by I/O schedulers strictly follow one of the following three
-flows.
-
- set_req_fn ->
-
- i. add_req_fn -> (merged_fn ->)* -> dispatch_fn -> activate_req_fn ->
- (deactivate_req_fn -> activate_req_fn ->)* -> completed_req_fn
- ii. add_req_fn -> (merged_fn ->)* -> merge_req_fn
- iii. [none]
-
- -> put_req_fn
-
-4.3 I/O scheduler implementation
---------------------------------
-
-The generic i/o scheduler algorithm attempts to sort/merge/batch requests for
-optimal disk scan and request servicing performance (based on generic
-principles and device capabilities), optimized for:
-
-i. improved throughput
-ii. improved latency
-iii. better utilization of h/w & CPU time
-
-Characteristics:
-
-i. Binary tree
-AS and deadline i/o schedulers use red black binary trees for disk position
-sorting and searching, and a fifo linked list for time-based searching. This
-gives good scalability and good availability of information. Requests are
-almost always dispatched in disk sort order, so a cache is kept of the next
-request in sort order to prevent binary tree lookups.
-
-This arrangement is not a generic block layer characteristic however, so
-elevators may implement queues as they please.
-
-ii. Merge hash
-AS and deadline use a hash table indexed by the last sector of a request. This
-enables merging code to quickly look up "back merge" candidates, even when
-multiple I/O streams are being performed at once on one disk.
-
-"Front merges", a new request being merged at the front of an existing request,
-are far less common than "back merges" due to the nature of most I/O patterns.
-Front merges are handled by the binary trees in AS and deadline schedulers.
-
-iii. Plugging the queue to batch requests in anticipation of opportunities for
- merge/sort optimizations
-
-Plugging is an approach that the current i/o scheduling algorithm resorts to so
-that it collects up enough requests in the queue to be able to take
-advantage of the sorting/merging logic in the elevator. If the
-queue is empty when a request comes in, then it plugs the request queue
-(sort of like plugging the bath tub of a vessel to get fluid to build up)
-till it fills up with a few more requests, before starting to service
-the requests. This provides an opportunity to merge/sort the requests before
-passing them down to the device. There are various conditions when the queue is
-unplugged (to open up the flow again), either through a scheduled task or
-could be on demand. For example wait_on_buffer sets the unplugging going
-through sync_buffer() running blk_run_address_space(mapping). Or the caller
-can do it explicity through blk_unplug(bdev). So in the read case,
-the queue gets explicitly unplugged as part of waiting for completion on that
-buffer.
-
-Aside:
- This is kind of controversial territory, as it's not clear if plugging is
- always the right thing to do. Devices typically have their own queues,
- and allowing a big queue to build up in software, while letting the device be
- idle for a while may not always make sense. The trick is to handle the fine
- balance between when to plug and when to open up. Also now that we have
- multi-page bios being queued in one shot, we may not need to wait to merge
- a big request from the broken up pieces coming by.
-
-4.4 I/O contexts
-----------------
-
-I/O contexts provide a dynamically allocated per process data area. They may
-be used in I/O schedulers, and in the block layer (could be used for IO statis,
-priorities for example). See `*io_context` in block/ll_rw_blk.c, and as-iosched.c
-for an example of usage in an i/o scheduler.
-
-
-5. Scalability related changes
-==============================
-
-5.1 Granular Locking: io_request_lock replaced by a per-queue lock
-------------------------------------------------------------------
-
-The global io_request_lock has been removed as of 2.5, to avoid
-the scalability bottleneck it was causing, and has been replaced by more
-granular locking. The request queue structure has a pointer to the
-lock to be used for that queue. As a result, locking can now be
-per-queue, with a provision for sharing a lock across queues if
-necessary (e.g the scsi layer sets the queue lock pointers to the
-corresponding adapter lock, which results in a per host locking
-granularity). The locking semantics are the same, i.e. locking is
-still imposed by the block layer, grabbing the lock before
-request_fn execution which it means that lots of older drivers
-should still be SMP safe. Drivers are free to drop the queue
-lock themselves, if required. Drivers that explicitly used the
-io_request_lock for serialization need to be modified accordingly.
-Usually it's as easy as adding a global lock::
-
- static DEFINE_SPINLOCK(my_driver_lock);
-
-and passing the address to that lock to blk_init_queue().
-
-5.2 64 bit sector numbers (sector_t prepares for 64 bit support)
-----------------------------------------------------------------
-
-The sector number used in the bio structure has been changed to sector_t,
-which could be defined as 64 bit in preparation for 64 bit sector support.
-
-6. Other Changes/Implications
-=============================
-
-6.1 Partition re-mapping handled by the generic block layer
------------------------------------------------------------
-
-In 2.5 some of the gendisk/partition related code has been reorganized.
-Now the generic block layer performs partition-remapping early and thus
-provides drivers with a sector number relative to whole device, rather than
-having to take partition number into account in order to arrive at the true
-sector number. The routine blk_partition_remap() is invoked by
-submit_bio_noacct even before invoking the queue specific ->submit_bio,
-so the i/o scheduler also gets to operate on whole disk sector numbers. This
-should typically not require changes to block drivers, it just never gets
-to invoke its own partition sector offset calculations since all bios
-sent are offset from the beginning of the device.
-
-
-7. A Few Tips on Migration of older drivers
-===========================================
-
-Old-style drivers that just use CURRENT and ignores clustered requests,
-may not need much change. The generic layer will automatically handle
-clustered requests, multi-page bios, etc for the driver.
-
-For a low performance driver or hardware that is PIO driven or just doesn't
-support scatter-gather changes should be minimal too.
-
-The following are some points to keep in mind when converting old drivers
-to bio.
-
-Drivers should use elv_next_request to pick up requests and are no longer
-supposed to handle looping directly over the request list.
-(struct request->queue has been removed)
-
-Now end_that_request_first takes an additional number_of_sectors argument.
-It used to handle always just the first buffer_head in a request, now
-it will loop and handle as many sectors (on a bio-segment granularity)
-as specified.
-
-Now bh->b_end_io is replaced by bio->bi_end_io, but most of the time the
-right thing to use is bio_endio(bio) instead.
-
-If the driver is dropping the io_request_lock from its request_fn strategy,
-then it just needs to replace that with q->queue_lock instead.
-
-As described in Sec 1.1, drivers can set max sector size, max segment size
-etc per queue now. Drivers that used to define their own merge functions i
-to handle things like this can now just use the blk_queue_* functions at
-blk_init_queue time.
-
-Drivers no longer have to map a {partition, sector offset} into the
-correct absolute location anymore, this is done by the block layer, so
-where a driver received a request ala this before::
-
- rq->rq_dev = mk_kdev(3, 5); /* /dev/hda5 */
- rq->sector = 0; /* first sector on hda5 */
-
-it will now see::
-
- rq->rq_dev = mk_kdev(3, 0); /* /dev/hda */
- rq->sector = 123128; /* offset from start of disk */
-
-As mentioned, there is no virtual mapping of a bio. For DMA, this is
-not a problem as the driver probably never will need a virtual mapping.
-Instead it needs a bus mapping (dma_map_page for a single segment or
-use dma_map_sg for scatter gather) to be able to ship it to the driver. For
-PIO drivers (or drivers that need to revert to PIO transfer once in a
-while (IDE for example)), where the CPU is doing the actual data
-transfer a virtual mapping is needed. If the driver supports highmem I/O,
-(Sec 1.1, (ii) ) it needs to use kmap_atomic or similar to temporarily map
-a bio into the virtual address space.
-
-
-8. Prior/Related/Impacted patches
-=================================
-
-8.1. Earlier kiobuf patches (sct/axboe/chait/hch/mkp)
------------------------------------------------------
-
-- orig kiobuf & raw i/o patches (now in 2.4 tree)
-- direct kiobuf based i/o to devices (no intermediate bh's)
-- page i/o using kiobuf
-- kiobuf splitting for lvm (mkp)
-- elevator support for kiobuf request merging (axboe)
-
-8.2. Zero-copy networking (Dave Miller)
----------------------------------------
-
-8.3. SGI XFS - pagebuf patches - use of kiobufs
------------------------------------------------
-8.4. Multi-page pioent patch for bio (Christoph Hellwig)
---------------------------------------------------------
-8.5. Direct i/o implementation (Andrea Arcangeli) since 2.4.10-pre11
---------------------------------------------------------------------
-8.6. Async i/o implementation patch (Ben LaHaise)
--------------------------------------------------
-8.7. EVMS layering design (IBM EVMS team)
------------------------------------------
-8.8. Larger page cache size patch (Ben LaHaise) and Large page size (Daniel Phillips)
--------------------------------------------------------------------------------------
-
- => larger contiguous physical memory buffers
-
-8.9. VM reservations patch (Ben LaHaise)
-----------------------------------------
-8.10. Write clustering patches ? (Marcelo/Quintela/Riel ?)
-----------------------------------------------------------
-8.11. Block device in page cache patch (Andrea Archangeli) - now in 2.4.10+
----------------------------------------------------------------------------
-8.12. Multiple block-size transfers for faster raw i/o (Shailabh Nagar, Badari)
--------------------------------------------------------------------------------
-8.13 Priority based i/o scheduler - prepatches (Arjan van de Ven)
-------------------------------------------------------------------
-8.14 IDE Taskfile i/o patch (Andre Hedrick)
---------------------------------------------
-8.15 Multi-page writeout and readahead patches (Andrew Morton)
----------------------------------------------------------------
-8.16 Direct i/o patches for 2.5 using kvec and bio (Badari Pulavarthy)
------------------------------------------------------------------------
-
-9. Other References
-===================
-
-9.1 The Splice I/O Model
-------------------------
-
-Larry McVoy (and subsequent discussions on lkml, and Linus' comments - Jan 2001
-
-9.2 Discussions about kiobuf and bh design
-------------------------------------------
-
-On lkml between sct, linus, alan et al - Feb-March 2001 (many of the
-initial thoughts that led to bio were brought up in this discussion thread)
-
-9.3 Discussions on mempool on lkml - Dec 2001.
-----------------------------------------------
diff --git a/Documentation/block/capability.rst b/Documentation/block/capability.rst
index 160a5148b915..2ae7f064736a 100644
--- a/Documentation/block/capability.rst
+++ b/Documentation/block/capability.rst
@@ -7,4 +7,4 @@ This file documents the sysfs file ``block/<disk>/capability``.
``capability`` is a bitfield, printed in hexadecimal, indicating which
capabilities a specific block device supports:
-.. kernel-doc:: include/linux/genhd.h
+.. kernel-doc:: include/linux/blkdev.h
diff --git a/Documentation/block/index.rst b/Documentation/block/index.rst
index 3a41495dd77b..68f115f2b1c6 100644
--- a/Documentation/block/index.rst
+++ b/Documentation/block/index.rst
@@ -8,7 +8,6 @@ Block
:maxdepth: 1
bfq-iosched
- biodoc
biovecs
blk-mq
capability
diff --git a/Documentation/bpf/bpf_prog_run.rst b/Documentation/bpf/bpf_prog_run.rst
new file mode 100644
index 000000000000..4868c909df5c
--- /dev/null
+++ b/Documentation/bpf/bpf_prog_run.rst
@@ -0,0 +1,117 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+===================================
+Running BPF programs from userspace
+===================================
+
+This document describes the ``BPF_PROG_RUN`` facility for running BPF programs
+from userspace.
+
+.. contents::
+ :local:
+ :depth: 2
+
+
+Overview
+--------
+
+The ``BPF_PROG_RUN`` command can be used through the ``bpf()`` syscall to
+execute a BPF program in the kernel and return the results to userspace. This
+can be used to unit test BPF programs against user-supplied context objects, and
+as way to explicitly execute programs in the kernel for their side effects. The
+command was previously named ``BPF_PROG_TEST_RUN``, and both constants continue
+to be defined in the UAPI header, aliased to the same value.
+
+The ``BPF_PROG_RUN`` command can be used to execute BPF programs of the
+following types:
+
+- ``BPF_PROG_TYPE_SOCKET_FILTER``
+- ``BPF_PROG_TYPE_SCHED_CLS``
+- ``BPF_PROG_TYPE_SCHED_ACT``
+- ``BPF_PROG_TYPE_XDP``
+- ``BPF_PROG_TYPE_SK_LOOKUP``
+- ``BPF_PROG_TYPE_CGROUP_SKB``
+- ``BPF_PROG_TYPE_LWT_IN``
+- ``BPF_PROG_TYPE_LWT_OUT``
+- ``BPF_PROG_TYPE_LWT_XMIT``
+- ``BPF_PROG_TYPE_LWT_SEG6LOCAL``
+- ``BPF_PROG_TYPE_FLOW_DISSECTOR``
+- ``BPF_PROG_TYPE_STRUCT_OPS``
+- ``BPF_PROG_TYPE_RAW_TRACEPOINT``
+- ``BPF_PROG_TYPE_SYSCALL``
+
+When using the ``BPF_PROG_RUN`` command, userspace supplies an input context
+object and (for program types operating on network packets) a buffer containing
+the packet data that the BPF program will operate on. The kernel will then
+execute the program and return the results to userspace. Note that programs will
+not have any side effects while being run in this mode; in particular, packets
+will not actually be redirected or dropped, the program return code will just be
+returned to userspace. A separate mode for live execution of XDP programs is
+provided, documented separately below.
+
+Running XDP programs in "live frame mode"
+-----------------------------------------
+
+The ``BPF_PROG_RUN`` command has a separate mode for running live XDP programs,
+which can be used to execute XDP programs in a way where packets will actually
+be processed by the kernel after the execution of the XDP program as if they
+arrived on a physical interface. This mode is activated by setting the
+``BPF_F_TEST_XDP_LIVE_FRAMES`` flag when supplying an XDP program to
+``BPF_PROG_RUN``.
+
+The live packet mode is optimised for high performance execution of the supplied
+XDP program many times (suitable for, e.g., running as a traffic generator),
+which means the semantics are not quite as straight-forward as the regular test
+run mode. Specifically:
+
+- When executing an XDP program in live frame mode, the result of the execution
+ will not be returned to userspace; instead, the kernel will perform the
+ operation indicated by the program's return code (drop the packet, redirect
+ it, etc). For this reason, setting the ``data_out`` or ``ctx_out`` attributes
+ in the syscall parameters when running in this mode will be rejected. In
+ addition, not all failures will be reported back to userspace directly;
+ specifically, only fatal errors in setup or during execution (like memory
+ allocation errors) will halt execution and return an error. If an error occurs
+ in packet processing, like a failure to redirect to a given interface,
+ execution will continue with the next repetition; these errors can be detected
+ via the same trace points as for regular XDP programs.
+
+- Userspace can supply an ifindex as part of the context object, just like in
+ the regular (non-live) mode. The XDP program will be executed as though the
+ packet arrived on this interface; i.e., the ``ingress_ifindex`` of the context
+ object will point to that interface. Furthermore, if the XDP program returns
+ ``XDP_PASS``, the packet will be injected into the kernel networking stack as
+ though it arrived on that ifindex, and if it returns ``XDP_TX``, the packet
+ will be transmitted *out* of that same interface. Do note, though, that
+ because the program execution is not happening in driver context, an
+ ``XDP_TX`` is actually turned into the same action as an ``XDP_REDIRECT`` to
+ that same interface (i.e., it will only work if the driver has support for the
+ ``ndo_xdp_xmit`` driver op).
+
+- When running the program with multiple repetitions, the execution will happen
+ in batches. The batch size defaults to 64 packets (which is same as the
+ maximum NAPI receive batch size), but can be specified by userspace through
+ the ``batch_size`` parameter, up to a maximum of 256 packets. For each batch,
+ the kernel executes the XDP program repeatedly, each invocation getting a
+ separate copy of the packet data. For each repetition, if the program drops
+ the packet, the data page is immediately recycled (see below). Otherwise, the
+ packet is buffered until the end of the batch, at which point all packets
+ buffered this way during the batch are transmitted at once.
+
+- When setting up the test run, the kernel will initialise a pool of memory
+ pages of the same size as the batch size. Each memory page will be initialised
+ with the initial packet data supplied by userspace at ``BPF_PROG_RUN``
+ invocation. When possible, the pages will be recycled on future program
+ invocations, to improve performance. Pages will generally be recycled a full
+ batch at a time, except when a packet is dropped (by return code or because
+ of, say, a redirection error), in which case that page will be recycled
+ immediately. If a packet ends up being passed to the regular networking stack
+ (because the XDP program returns ``XDP_PASS``, or because it ends up being
+ redirected to an interface that injects it into the stack), the page will be
+ released and a new one will be allocated when the pool is empty.
+
+ When recycling, the page content is not rewritten; only the packet boundary
+ pointers (``data``, ``data_end`` and ``data_meta``) in the context object will
+ be reset to the original values. This means that if a program rewrites the
+ packet contents, it has to be prepared to see either the original content or
+ the modified version on subsequent invocations.
diff --git a/Documentation/bpf/btf.rst b/Documentation/bpf/btf.rst
index 1ebf4c5c7ddc..7940da9bc6c1 100644
--- a/Documentation/bpf/btf.rst
+++ b/Documentation/bpf/btf.rst
@@ -503,6 +503,19 @@ valid index (starting from 0) pointing to a member or an argument.
* ``info.vlen``: 0
* ``type``: the type with ``btf_type_tag`` attribute
+Currently, ``BTF_KIND_TYPE_TAG`` is only emitted for pointer types.
+It has the following btf type chain:
+::
+
+ ptr -> [type_tag]*
+ -> [const | volatile | restrict | typedef]*
+ -> base_type
+
+Basically, a pointer type points to zero or more
+type_tag, then zero or more const/volatile/restrict/typedef
+and finally the base type. The base type is one of
+int, ptr, array, struct, union, enum, func_proto and float types.
+
3. BTF Kernel API
=================
@@ -565,18 +578,15 @@ A map can be created with ``btf_fd`` and specified key/value type id.::
In libbpf, the map can be defined with extra annotation like below:
::
- struct bpf_map_def SEC("maps") btf_map = {
- .type = BPF_MAP_TYPE_ARRAY,
- .key_size = sizeof(int),
- .value_size = sizeof(struct ipv_counts),
- .max_entries = 4,
- };
- BPF_ANNOTATE_KV_PAIR(btf_map, int, struct ipv_counts);
+ struct {
+ __uint(type, BPF_MAP_TYPE_ARRAY);
+ __type(key, int);
+ __type(value, struct ipv_counts);
+ __uint(max_entries, 4);
+ } btf_map SEC(".maps");
-Here, the parameters for macro BPF_ANNOTATE_KV_PAIR are map name, key and
-value types for the map. During ELF parsing, libbpf is able to extract
-key/value type_id's and assign them to BPF_MAP_CREATE attributes
-automatically.
+During ELF parsing, libbpf is able to extract key/value type_id's and assign
+them to BPF_MAP_CREATE attributes automatically.
.. _BPF_Prog_Load:
@@ -824,13 +834,12 @@ structure has bitfields. For example, for the following map,::
___A b1:4;
enum A b2:4;
};
- struct bpf_map_def SEC("maps") tmpmap = {
- .type = BPF_MAP_TYPE_ARRAY,
- .key_size = sizeof(__u32),
- .value_size = sizeof(struct tmp_t),
- .max_entries = 1,
- };
- BPF_ANNOTATE_KV_PAIR(tmpmap, int, struct tmp_t);
+ struct {
+ __uint(type, BPF_MAP_TYPE_ARRAY);
+ __type(key, int);
+ __type(value, struct tmp_t);
+ __uint(max_entries, 1);
+ } tmpmap SEC(".maps");
bpftool is able to pretty print like below:
::
diff --git a/Documentation/bpf/index.rst b/Documentation/bpf/index.rst
index ef5c996547ec..96056a7447c7 100644
--- a/Documentation/bpf/index.rst
+++ b/Documentation/bpf/index.rst
@@ -21,6 +21,7 @@ that goes into great technical depth about the BPF Architecture.
helpers
programs
maps
+ bpf_prog_run
classic_vs_extended.rst
bpf_licensing
test_debug
diff --git a/Documentation/bpf/instruction-set.rst b/Documentation/bpf/instruction-set.rst
index 3704836fe6df..5300837ac2c9 100644
--- a/Documentation/bpf/instruction-set.rst
+++ b/Documentation/bpf/instruction-set.rst
@@ -22,7 +22,13 @@ necessary across calls.
Instruction encoding
====================
-eBPF uses 64-bit instructions with the following encoding:
+eBPF has two instruction encodings:
+
+ * the basic instruction encoding, which uses 64 bits to encode an instruction
+ * the wide instruction encoding, which appends a second 64-bit immediate value
+ (imm64) after the basic instruction for a total of 128 bits.
+
+The basic instruction encoding looks as follows:
============= ======= =============== ==================== ============
32 bits (MSB) 16 bits 4 bits 4 bits 8 bits (LSB)
@@ -82,9 +88,9 @@ BPF_ALU uses 32-bit wide operands while BPF_ALU64 uses 64-bit wide operands for
otherwise identical operations.
The code field encodes the operation as below:
- ======== ===== ==========================
+ ======== ===== =================================================
code value description
- ======== ===== ==========================
+ ======== ===== =================================================
BPF_ADD 0x00 dst += src
BPF_SUB 0x10 dst -= src
BPF_MUL 0x20 dst \*= src
@@ -98,8 +104,8 @@ The code field encodes the operation as below:
BPF_XOR 0xa0 dst ^= src
BPF_MOV 0xb0 dst = src
BPF_ARSH 0xc0 sign extending shift right
- BPF_END 0xd0 endianness conversion
- ======== ===== ==========================
+ BPF_END 0xd0 byte swap operations (see separate section below)
+ ======== ===== =================================================
BPF_ADD | BPF_X | BPF_ALU means::
@@ -118,6 +124,42 @@ BPF_XOR | BPF_K | BPF_ALU64 means::
src_reg = src_reg ^ imm32
+Byte swap instructions
+----------------------
+
+The byte swap instructions use an instruction class of ``BFP_ALU`` and a 4-bit
+code field of ``BPF_END``.
+
+The byte swap instructions instructions operate on the destination register
+only and do not use a separate source register or immediate value.
+
+The 1-bit source operand field in the opcode is used to to select what byte
+order the operation convert from or to:
+
+ ========= ===== =================================================
+ source value description
+ ========= ===== =================================================
+ BPF_TO_LE 0x00 convert between host byte order and little endian
+ BPF_TO_BE 0x08 convert between host byte order and big endian
+ ========= ===== =================================================
+
+The imm field encodes the width of the swap operations. The following widths
+are supported: 16, 32 and 64.
+
+Examples:
+
+``BPF_ALU | BPF_TO_LE | BPF_END`` with imm = 16 means::
+
+ dst_reg = htole16(dst_reg)
+
+``BPF_ALU | BPF_TO_BE | BPF_END`` with imm = 64 means::
+
+ dst_reg = htobe64(dst_reg)
+
+``BPF_FROM_LE`` and ``BPF_FROM_BE`` exist as aliases for ``BPF_TO_LE`` and
+``BPF_TO_LE`` respetively.
+
+
Jump instructions
-----------------
@@ -176,63 +218,96 @@ The mode modifier is one of:
============= ===== ====================================
mode modifier value description
============= ===== ====================================
- BPF_IMM 0x00 used for 64-bit mov
- BPF_ABS 0x20 legacy BPF packet access
- BPF_IND 0x40 legacy BPF packet access
- BPF_MEM 0x60 all normal load and store operations
+ BPF_IMM 0x00 64-bit immediate instructions
+ BPF_ABS 0x20 legacy BPF packet access (absolute)
+ BPF_IND 0x40 legacy BPF packet access (indirect)
+ BPF_MEM 0x60 regular load and store operations
BPF_ATOMIC 0xc0 atomic operations
============= ===== ====================================
-BPF_MEM | <size> | BPF_STX means::
+
+Regular load and store operations
+---------------------------------
+
+The ``BPF_MEM`` mode modifier is used to encode regular load and store
+instructions that transfer data between a register and memory.
+
+``BPF_MEM | <size> | BPF_STX`` means::
*(size *) (dst_reg + off) = src_reg
-BPF_MEM | <size> | BPF_ST means::
+``BPF_MEM | <size> | BPF_ST`` means::
*(size *) (dst_reg + off) = imm32
-BPF_MEM | <size> | BPF_LDX means::
+``BPF_MEM | <size> | BPF_LDX`` means::
dst_reg = *(size *) (src_reg + off)
-Where size is one of: BPF_B or BPF_H or BPF_W or BPF_DW.
+Where size is one of: ``BPF_B``, ``BPF_H``, ``BPF_W``, or ``BPF_DW``.
Atomic operations
-----------------
-eBPF includes atomic operations, which use the immediate field for extra
-encoding::
+Atomic operations are operations that operate on memory and can not be
+interrupted or corrupted by other access to the same memory region
+by other eBPF programs or means outside of this specification.
+
+All atomic operations supported by eBPF are encoded as store operations
+that use the ``BPF_ATOMIC`` mode modifier as follows:
+
+ * ``BPF_ATOMIC | BPF_W | BPF_STX`` for 32-bit operations
+ * ``BPF_ATOMIC | BPF_DW | BPF_STX`` for 64-bit operations
+ * 8-bit and 16-bit wide atomic operations are not supported.
- .imm = BPF_ADD, .code = BPF_ATOMIC | BPF_W | BPF_STX: lock xadd *(u32 *)(dst_reg + off16) += src_reg
- .imm = BPF_ADD, .code = BPF_ATOMIC | BPF_DW | BPF_STX: lock xadd *(u64 *)(dst_reg + off16) += src_reg
+The imm field is used to encode the actual atomic operation.
+Simple atomic operation use a subset of the values defined to encode
+arithmetic operations in the imm field to encode the atomic operation:
-The basic atomic operations supported are::
+ ======== ===== ===========
+ imm value description
+ ======== ===== ===========
+ BPF_ADD 0x00 atomic add
+ BPF_OR 0x40 atomic or
+ BPF_AND 0x50 atomic and
+ BPF_XOR 0xa0 atomic xor
+ ======== ===== ===========
- BPF_ADD
- BPF_AND
- BPF_OR
- BPF_XOR
-Each having equivalent semantics with the ``BPF_ADD`` example, that is: the
-memory location addresed by ``dst_reg + off`` is atomically modified, with
-``src_reg`` as the other operand. If the ``BPF_FETCH`` flag is set in the
-immediate, then these operations also overwrite ``src_reg`` with the
-value that was in memory before it was modified.
+``BPF_ATOMIC | BPF_W | BPF_STX`` with imm = BPF_ADD means::
-The more special operations are::
+ *(u32 *)(dst_reg + off16) += src_reg
- BPF_XCHG
+``BPF_ATOMIC | BPF_DW | BPF_STX`` with imm = BPF ADD means::
-This atomically exchanges ``src_reg`` with the value addressed by ``dst_reg +
-off``. ::
+ *(u64 *)(dst_reg + off16) += src_reg
- BPF_CMPXCHG
+``BPF_XADD`` is a deprecated name for ``BPF_ATOMIC | BPF_ADD``.
-This atomically compares the value addressed by ``dst_reg + off`` with
-``R0``. If they match it is replaced with ``src_reg``. In either case, the
-value that was there before is zero-extended and loaded back to ``R0``.
+In addition to the simple atomic operations, there also is a modifier and
+two complex atomic operations:
-Note that 1 and 2 byte atomic operations are not supported.
+ =========== ================ ===========================
+ imm value description
+ =========== ================ ===========================
+ BPF_FETCH 0x01 modifier: return old value
+ BPF_XCHG 0xe0 | BPF_FETCH atomic exchange
+ BPF_CMPXCHG 0xf0 | BPF_FETCH atomic compare and exchange
+ =========== ================ ===========================
+
+The ``BPF_FETCH`` modifier is optional for simple atomic operations, and
+always set for the complex atomic operations. If the ``BPF_FETCH`` flag
+is set, then the operation also overwrites ``src_reg`` with the value that
+was in memory before it was modified.
+
+The ``BPF_XCHG`` operation atomically exchanges ``src_reg`` with the value
+addressed by ``dst_reg + off``.
+
+The ``BPF_CMPXCHG`` operation atomically compares the value addressed by
+``dst_reg + off`` with ``R0``. If they match, the value addressed by
+``dst_reg + off`` is replaced with ``src_reg``. In either case, the
+value that was at ``dst_reg + off`` before the operation is zero-extended
+and loaded back to ``R0``.
Clang can generate atomic instructions by default when ``-mcpu=v3`` is
enabled. If a lower version for ``-mcpu`` is set, the only atomic instruction
@@ -240,40 +315,52 @@ Clang can generate is ``BPF_ADD`` *without* ``BPF_FETCH``. If you need to enable
the atomics features, while keeping a lower ``-mcpu`` version, you can use
``-Xclang -target-feature -Xclang +alu32``.
-You may encounter ``BPF_XADD`` - this is a legacy name for ``BPF_ATOMIC``,
-referring to the exclusive-add operation encoded when the immediate field is
-zero.
+64-bit immediate instructions
+-----------------------------
-16-byte instructions
---------------------
+Instructions with the ``BPF_IMM`` mode modifier use the wide instruction
+encoding for an extra imm64 value.
-eBPF has one 16-byte instruction: ``BPF_LD | BPF_DW | BPF_IMM`` which consists
-of two consecutive ``struct bpf_insn`` 8-byte blocks and interpreted as single
-instruction that loads 64-bit immediate value into a dst_reg.
+There is currently only one such instruction.
-Packet access instructions
---------------------------
+``BPF_LD | BPF_DW | BPF_IMM`` means::
-eBPF has two non-generic instructions: (BPF_ABS | <size> | BPF_LD) and
-(BPF_IND | <size> | BPF_LD) which are used to access packet data.
+ dst_reg = imm64
-They had to be carried over from classic BPF to have strong performance of
-socket filters running in eBPF interpreter. These instructions can only
-be used when interpreter context is a pointer to ``struct sk_buff`` and
-have seven implicit operands. Register R6 is an implicit input that must
-contain pointer to sk_buff. Register R0 is an implicit output which contains
-the data fetched from the packet. Registers R1-R5 are scratch registers
-and must not be used to store the data across BPF_ABS | BPF_LD or
-BPF_IND | BPF_LD instructions.
-These instructions have implicit program exit condition as well. When
-eBPF program is trying to access the data beyond the packet boundary,
-the interpreter will abort the execution of the program. JIT compilers
-therefore must preserve this property. src_reg and imm32 fields are
-explicit inputs to these instructions.
+Legacy BPF Packet access instructions
+-------------------------------------
-For example, BPF_IND | BPF_W | BPF_LD means::
+eBPF has special instructions for access to packet data that have been
+carried over from classic BPF to retain the performance of legacy socket
+filters running in the eBPF interpreter.
- R0 = ntohl(*(u32 *) (((struct sk_buff *) R6)->data + src_reg + imm32))
+The instructions come in two forms: ``BPF_ABS | <size> | BPF_LD`` and
+``BPF_IND | <size> | BPF_LD``.
-and R1 - R5 are clobbered.
+These instructions are used to access packet data and can only be used when
+the program context is a pointer to networking packet. ``BPF_ABS``
+accesses packet data at an absolute offset specified by the immediate data
+and ``BPF_IND`` access packet data at an offset that includes the value of
+a register in addition to the immediate data.
+
+These instructions have seven implicit operands:
+
+ * Register R6 is an implicit input that must contain pointer to a
+ struct sk_buff.
+ * Register R0 is an implicit output which contains the data fetched from
+ the packet.
+ * Registers R1-R5 are scratch registers that are clobbered after a call to
+ ``BPF_ABS | BPF_LD`` or ``BPF_IND`` | BPF_LD instructions.
+
+These instructions have an implicit program exit condition as well. When an
+eBPF program is trying to access the data beyond the packet boundary, the
+program execution will be aborted.
+
+``BPF_ABS | BPF_W | BPF_LD`` means::
+
+ R0 = ntohl(*(u32 *) (((struct sk_buff *) R6)->data + imm32))
+
+``BPF_IND | BPF_W | BPF_LD`` means::
+
+ R0 = ntohl(*(u32 *) (((struct sk_buff *) R6)->data + src_reg + imm32))
diff --git a/Documentation/bpf/verifier.rst b/Documentation/bpf/verifier.rst
index fae5f6273bac..d4326caf01f9 100644
--- a/Documentation/bpf/verifier.rst
+++ b/Documentation/bpf/verifier.rst
@@ -329,7 +329,7 @@ Program with unreachable instructions::
BPF_EXIT_INSN(),
};
-Error:
+Error::
unreachable insn 1
diff --git a/Documentation/cdrom/packet-writing.rst b/Documentation/cdrom/packet-writing.rst
index c5c957195a5a..43db58c50d29 100644
--- a/Documentation/cdrom/packet-writing.rst
+++ b/Documentation/cdrom/packet-writing.rst
@@ -11,7 +11,7 @@ Getting started quick
- Compile and install kernel and modules, reboot.
- You need the udftools package (pktsetup, mkudffs, cdrwtool).
- Download from http://sourceforge.net/projects/linux-udf/
+ Download from https://github.com/pali/udftools
- Grab a new CD-RW disc and format it (assuming CD-RW is hdc, substitute
as appropriate)::
@@ -102,7 +102,7 @@ Using the pktcdvd sysfs interface
Since Linux 2.6.20, the pktcdvd module has a sysfs interface
and can be controlled by it. For example the "pktcdvd" tool uses
-this interface. (see http://tom.ist-im-web.de/download/pktcdvd )
+this interface. (see http://tom.ist-im-web.de/linux/software/pktcdvd )
"pktcdvd" works similar to "pktsetup", e.g.::
diff --git a/Documentation/conf.py b/Documentation/conf.py
index f07f2e9b9f2c..072ee31a301d 100644
--- a/Documentation/conf.py
+++ b/Documentation/conf.py
@@ -409,135 +409,25 @@ latex_elements = {
# Additional stuff for the LaTeX preamble.
'preamble': '''
- % Prevent column squeezing of tabulary.
- \\setlength{\\tymin}{20em}
% Use some font with UTF-8 support with XeLaTeX
\\usepackage{fontspec}
\\setsansfont{DejaVu Sans}
\\setromanfont{DejaVu Serif}
\\setmonofont{DejaVu Sans Mono}
- % Adjust \\headheight for fancyhdr
- \\addtolength{\\headheight}{1.6pt}
- \\addtolength{\\topmargin}{-1.6pt}
- ''',
+ ''',
}
-# Translations have Asian (CJK) characters which are only displayed if
-# xeCJK is used
-
-latex_elements['preamble'] += '''
- \\IfFontExistsTF{Noto Sans CJK SC}{
- % This is needed for translations
- \\usepackage{xeCJK}
- \\IfFontExistsTF{Noto Serif CJK SC}{
- \\setCJKmainfont{Noto Serif CJK SC}[AutoFakeSlant]
- }{
- \\setCJKmainfont{Noto Sans CJK SC}[AutoFakeSlant]
- }
- \\setCJKsansfont{Noto Sans CJK SC}[AutoFakeSlant]
- \\setCJKmonofont{Noto Sans Mono CJK SC}[AutoFakeSlant]
- % CJK Language-specific font choices
- \\IfFontExistsTF{Noto Serif CJK SC}{
- \\newCJKfontfamily[SCmain]\\scmain{Noto Serif CJK SC}[AutoFakeSlant]
- \\newCJKfontfamily[SCserif]\\scserif{Noto Serif CJK SC}[AutoFakeSlant]
- }{
- \\newCJKfontfamily[SCmain]\\scmain{Noto Sans CJK SC}[AutoFakeSlant]
- \\newCJKfontfamily[SCserif]\\scserif{Noto Sans CJK SC}[AutoFakeSlant]
- }
- \\newCJKfontfamily[SCsans]\\scsans{Noto Sans CJK SC}[AutoFakeSlant]
- \\newCJKfontfamily[SCmono]\\scmono{Noto Sans Mono CJK SC}[AutoFakeSlant]
- \\IfFontExistsTF{Noto Serif CJK TC}{
- \\newCJKfontfamily[TCmain]\\tcmain{Noto Serif CJK TC}[AutoFakeSlant]
- \\newCJKfontfamily[TCserif]\\tcserif{Noto Serif CJK TC}[AutoFakeSlant]
- }{
- \\newCJKfontfamily[TCmain]\\tcmain{Noto Sans CJK TC}[AutoFakeSlant]
- \\newCJKfontfamily[TCserif]\\tcserif{Noto Sans CJK TC}[AutoFakeSlant]
- }
- \\newCJKfontfamily[TCsans]\\tcsans{Noto Sans CJK TC}[AutoFakeSlant]
- \\newCJKfontfamily[TCmono]\\tcmono{Noto Sans Mono CJK TC}[AutoFakeSlant]
- \\IfFontExistsTF{Noto Serif CJK KR}{
- \\newCJKfontfamily[KRmain]\\krmain{Noto Serif CJK KR}[AutoFakeSlant]
- \\newCJKfontfamily[KRserif]\\krserif{Noto Serif CJK KR}[AutoFakeSlant]
- }{
- \\newCJKfontfamily[KRmain]\\krmain{Noto Sans CJK KR}[AutoFakeSlant]
- \\newCJKfontfamily[KRserif]\\krserif{Noto Sans CJK KR}[AutoFakeSlant]
- }
- \\newCJKfontfamily[KRsans]\\krsans{Noto Sans CJK KR}[AutoFakeSlant]
- \\newCJKfontfamily[KRmono]\\krmono{Noto Sans Mono CJK KR}[AutoFakeSlant]
- \\IfFontExistsTF{Noto Serif CJK JP}{
- \\newCJKfontfamily[JPmain]\\jpmain{Noto Serif CJK JP}[AutoFakeSlant]
- \\newCJKfontfamily[JPserif]\\jpserif{Noto Serif CJK JP}[AutoFakeSlant]
- }{
- \\newCJKfontfamily[JPmain]\\jpmain{Noto Sans CJK JP}[AutoFakeSlant]
- \\newCJKfontfamily[JPserif]\\jpserif{Noto Sans CJK JP}[AutoFakeSlant]
- }
- \\newCJKfontfamily[JPsans]\\jpsans{Noto Sans CJK JP}[AutoFakeSlant]
- \\newCJKfontfamily[JPmono]\\jpmono{Noto Sans Mono CJK JP}[AutoFakeSlant]
- % Dummy commands for Sphinx < 2.3 (no 'extrapackages' support)
- \\providecommand{\\onehalfspacing}{}
- \\providecommand{\\singlespacing}{}
- % Define custom macros to on/off CJK
- \\newcommand{\\kerneldocCJKon}{\\makexeCJKactive\\onehalfspacing}
- \\newcommand{\\kerneldocCJKoff}{\\makexeCJKinactive\\singlespacing}
- \\newcommand{\\kerneldocBeginSC}{%
- \\begingroup%
- \\scmain%
- }
- \\newcommand{\\kerneldocEndSC}{\\endgroup}
- \\newcommand{\\kerneldocBeginTC}{%
- \\begingroup%
- \\tcmain%
- \\renewcommand{\\CJKrmdefault}{TCserif}%
- \\renewcommand{\\CJKsfdefault}{TCsans}%
- \\renewcommand{\\CJKttdefault}{TCmono}%
- }
- \\newcommand{\\kerneldocEndTC}{\\endgroup}
- \\newcommand{\\kerneldocBeginKR}{%
- \\begingroup%
- \\xeCJKDeclareCharClass{HalfLeft}{`“,`‘}%
- \\xeCJKDeclareCharClass{HalfRight}{`â€,`’}%
- \\krmain%
- \\renewcommand{\\CJKrmdefault}{KRserif}%
- \\renewcommand{\\CJKsfdefault}{KRsans}%
- \\renewcommand{\\CJKttdefault}{KRmono}%
- \\xeCJKsetup{CJKspace = true} % For inter-phrase space
- }
- \\newcommand{\\kerneldocEndKR}{\\endgroup}
- \\newcommand{\\kerneldocBeginJP}{%
- \\begingroup%
- \\xeCJKDeclareCharClass{HalfLeft}{`“,`‘}%
- \\xeCJKDeclareCharClass{HalfRight}{`â€,`’}%
- \\jpmain%
- \\renewcommand{\\CJKrmdefault}{JPserif}%
- \\renewcommand{\\CJKsfdefault}{JPsans}%
- \\renewcommand{\\CJKttdefault}{JPmono}%
- }
- \\newcommand{\\kerneldocEndJP}{\\endgroup}
- % Single spacing in literal blocks
- \\fvset{baselinestretch=1}
- % To customize \\sphinxtableofcontents
- \\usepackage{etoolbox}
- % Inactivate CJK after tableofcontents
- \\apptocmd{\\sphinxtableofcontents}{\\kerneldocCJKoff}{}{}
- }{ % No CJK font found
- % Custom macros to on/off CJK (Dummy)
- \\newcommand{\\kerneldocCJKon}{}
- \\newcommand{\\kerneldocCJKoff}{}
- \\newcommand{\\kerneldocBeginSC}{}
- \\newcommand{\\kerneldocEndSC}{}
- \\newcommand{\\kerneldocBeginTC}{}
- \\newcommand{\\kerneldocEndTC}{}
- \\newcommand{\\kerneldocBeginKR}{}
- \\newcommand{\\kerneldocEndKR}{}
- \\newcommand{\\kerneldocBeginJP}{}
- \\newcommand{\\kerneldocEndJP}{}
- }
-'''
-
# Fix reference escape troubles with Sphinx 1.4.x
if major == 1:
latex_elements['preamble'] += '\\renewcommand*{\\DUrole}[2]{ #2 }\n'
+
+# Load kerneldoc specific LaTeX settings
+latex_elements['preamble'] += '''
+ % Load kerneldoc specific LaTeX settings
+ \\input{kerneldoc-preamble.sty}
+'''
+
# With Sphinx 1.6, it is possible to change the Bg color directly
# by using:
# \definecolor{sphinxnoteBgColor}{RGB}{204,255,255}
@@ -599,6 +489,11 @@ for fn in os.listdir('.'):
# If false, no module index is generated.
#latex_domain_indices = True
+# Additional LaTeX stuff to be copied to build directory
+latex_additional_files = [
+ 'sphinx/kerneldoc-preamble.sty',
+]
+
# -- Options for manual page output ---------------------------------------
diff --git a/Documentation/core-api/entry.rst b/Documentation/core-api/entry.rst
new file mode 100644
index 000000000000..e12f22ab33c7
--- /dev/null
+++ b/Documentation/core-api/entry.rst
@@ -0,0 +1,279 @@
+Entry/exit handling for exceptions, interrupts, syscalls and KVM
+================================================================
+
+All transitions between execution domains require state updates which are
+subject to strict ordering constraints. State updates are required for the
+following:
+
+ * Lockdep
+ * RCU / Context tracking
+ * Preemption counter
+ * Tracing
+ * Time accounting
+
+The update order depends on the transition type and is explained below in
+the transition type sections: `Syscalls`_, `KVM`_, `Interrupts and regular
+exceptions`_, `NMI and NMI-like exceptions`_.
+
+Non-instrumentable code - noinstr
+---------------------------------
+
+Most instrumentation facilities depend on RCU, so intrumentation is prohibited
+for entry code before RCU starts watching and exit code after RCU stops
+watching. In addition, many architectures must save and restore register state,
+which means that (for example) a breakpoint in the breakpoint entry code would
+overwrite the debug registers of the initial breakpoint.
+
+Such code must be marked with the 'noinstr' attribute, placing that code into a
+special section inaccessible to instrumentation and debug facilities. Some
+functions are partially instrumentable, which is handled by marking them
+noinstr and using instrumentation_begin() and instrumentation_end() to flag the
+instrumentable ranges of code:
+
+.. code-block:: c
+
+ noinstr void entry(void)
+ {
+ handle_entry(); // <-- must be 'noinstr' or '__always_inline'
+ ...
+
+ instrumentation_begin();
+ handle_context(); // <-- instrumentable code
+ instrumentation_end();
+
+ ...
+ handle_exit(); // <-- must be 'noinstr' or '__always_inline'
+ }
+
+This allows verification of the 'noinstr' restrictions via objtool on
+supported architectures.
+
+Invoking non-instrumentable functions from instrumentable context has no
+restrictions and is useful to protect e.g. state switching which would
+cause malfunction if instrumented.
+
+All non-instrumentable entry/exit code sections before and after the RCU
+state transitions must run with interrupts disabled.
+
+Syscalls
+--------
+
+Syscall-entry code starts in assembly code and calls out into low-level C code
+after establishing low-level architecture-specific state and stack frames. This
+low-level C code must not be instrumented. A typical syscall handling function
+invoked from low-level assembly code looks like this:
+
+.. code-block:: c
+
+ noinstr void syscall(struct pt_regs *regs, int nr)
+ {
+ arch_syscall_enter(regs);
+ nr = syscall_enter_from_user_mode(regs, nr);
+
+ instrumentation_begin();
+ if (!invoke_syscall(regs, nr) && nr != -1)
+ result_reg(regs) = __sys_ni_syscall(regs);
+ instrumentation_end();
+
+ syscall_exit_to_user_mode(regs);
+ }
+
+syscall_enter_from_user_mode() first invokes enter_from_user_mode() which
+establishes state in the following order:
+
+ * Lockdep
+ * RCU / Context tracking
+ * Tracing
+
+and then invokes the various entry work functions like ptrace, seccomp, audit,
+syscall tracing, etc. After all that is done, the instrumentable invoke_syscall
+function can be invoked. The instrumentable code section then ends, after which
+syscall_exit_to_user_mode() is invoked.
+
+syscall_exit_to_user_mode() handles all work which needs to be done before
+returning to user space like tracing, audit, signals, task work etc. After
+that it invokes exit_to_user_mode() which again handles the state
+transition in the reverse order:
+
+ * Tracing
+ * RCU / Context tracking
+ * Lockdep
+
+syscall_enter_from_user_mode() and syscall_exit_to_user_mode() are also
+available as fine grained subfunctions in cases where the architecture code
+has to do extra work between the various steps. In such cases it has to
+ensure that enter_from_user_mode() is called first on entry and
+exit_to_user_mode() is called last on exit.
+
+Do not nest syscalls. Nested systcalls will cause RCU and/or context tracking
+to print a warning.
+
+KVM
+---
+
+Entering or exiting guest mode is very similar to syscalls. From the host
+kernel point of view the CPU goes off into user space when entering the
+guest and returns to the kernel on exit.
+
+kvm_guest_enter_irqoff() is a KVM-specific variant of exit_to_user_mode()
+and kvm_guest_exit_irqoff() is the KVM variant of enter_from_user_mode().
+The state operations have the same ordering.
+
+Task work handling is done separately for guest at the boundary of the
+vcpu_run() loop via xfer_to_guest_mode_handle_work() which is a subset of
+the work handled on return to user space.
+
+Do not nest KVM entry/exit transitions because doing so is nonsensical.
+
+Interrupts and regular exceptions
+---------------------------------
+
+Interrupts entry and exit handling is slightly more complex than syscalls
+and KVM transitions.
+
+If an interrupt is raised while the CPU executes in user space, the entry
+and exit handling is exactly the same as for syscalls.
+
+If the interrupt is raised while the CPU executes in kernel space the entry and
+exit handling is slightly different. RCU state is only updated when the
+interrupt is raised in the context of the CPU's idle task. Otherwise, RCU will
+already be watching. Lockdep and tracing have to be updated unconditionally.
+
+irqentry_enter() and irqentry_exit() provide the implementation for this.
+
+The architecture-specific part looks similar to syscall handling:
+
+.. code-block:: c
+
+ noinstr void interrupt(struct pt_regs *regs, int nr)
+ {
+ arch_interrupt_enter(regs);
+ state = irqentry_enter(regs);
+
+ instrumentation_begin();
+
+ irq_enter_rcu();
+ invoke_irq_handler(regs, nr);
+ irq_exit_rcu();
+
+ instrumentation_end();
+
+ irqentry_exit(regs, state);
+ }
+
+Note that the invocation of the actual interrupt handler is within a
+irq_enter_rcu() and irq_exit_rcu() pair.
+
+irq_enter_rcu() updates the preemption count which makes in_hardirq()
+return true, handles NOHZ tick state and interrupt time accounting. This
+means that up to the point where irq_enter_rcu() is invoked in_hardirq()
+returns false.
+
+irq_exit_rcu() handles interrupt time accounting, undoes the preemption
+count update and eventually handles soft interrupts and NOHZ tick state.
+
+In theory, the preemption count could be updated in irqentry_enter(). In
+practice, deferring this update to irq_enter_rcu() allows the preemption-count
+code to be traced, while also maintaining symmetry with irq_exit_rcu() and
+irqentry_exit(), which are described in the next paragraph. The only downside
+is that the early entry code up to irq_enter_rcu() must be aware that the
+preemption count has not yet been updated with the HARDIRQ_OFFSET state.
+
+Note that irq_exit_rcu() must remove HARDIRQ_OFFSET from the preemption count
+before it handles soft interrupts, whose handlers must run in BH context rather
+than irq-disabled context. In addition, irqentry_exit() might schedule, which
+also requires that HARDIRQ_OFFSET has been removed from the preemption count.
+
+Even though interrupt handlers are expected to run with local interrupts
+disabled, interrupt nesting is common from an entry/exit perspective. For
+example, softirq handling happens within an irqentry_{enter,exit}() block with
+local interrupts enabled. Also, although uncommon, nothing prevents an
+interrupt handler from re-enabling interrupts.
+
+Interrupt entry/exit code doesn't strictly need to handle reentrancy, since it
+runs with local interrupts disabled. But NMIs can happen anytime, and a lot of
+the entry code is shared between the two.
+
+NMI and NMI-like exceptions
+---------------------------
+
+NMIs and NMI-like exceptions (machine checks, double faults, debug
+interrupts, etc.) can hit any context and must be extra careful with
+the state.
+
+State changes for debug exceptions and machine-check exceptions depend on
+whether these exceptions happened in user-space (breakpoints or watchpoints) or
+in kernel mode (code patching). From user-space, they are treated like
+interrupts, while from kernel mode they are treated like NMIs.
+
+NMIs and other NMI-like exceptions handle state transitions without
+distinguishing between user-mode and kernel-mode origin.
+
+The state update on entry is handled in irqentry_nmi_enter() which updates
+state in the following order:
+
+ * Preemption counter
+ * Lockdep
+ * RCU / Context tracking
+ * Tracing
+
+The exit counterpart irqentry_nmi_exit() does the reverse operation in the
+reverse order.
+
+Note that the update of the preemption counter has to be the first
+operation on enter and the last operation on exit. The reason is that both
+lockdep and RCU rely on in_nmi() returning true in this case. The
+preemption count modification in the NMI entry/exit case must not be
+traced.
+
+Architecture-specific code looks like this:
+
+.. code-block:: c
+
+ noinstr void nmi(struct pt_regs *regs)
+ {
+ arch_nmi_enter(regs);
+ state = irqentry_nmi_enter(regs);
+
+ instrumentation_begin();
+ nmi_handler(regs);
+ instrumentation_end();
+
+ irqentry_nmi_exit(regs);
+ }
+
+and for e.g. a debug exception it can look like this:
+
+.. code-block:: c
+
+ noinstr void debug(struct pt_regs *regs)
+ {
+ arch_nmi_enter(regs);
+
+ debug_regs = save_debug_regs();
+
+ if (user_mode(regs)) {
+ state = irqentry_enter(regs);
+
+ instrumentation_begin();
+ user_mode_debug_handler(regs, debug_regs);
+ instrumentation_end();
+
+ irqentry_exit(regs, state);
+ } else {
+ state = irqentry_nmi_enter(regs);
+
+ instrumentation_begin();
+ kernel_mode_debug_handler(regs, debug_regs);
+ instrumentation_end();
+
+ irqentry_nmi_exit(regs, state);
+ }
+ }
+
+There is no combined irqentry_nmi_if_kernel() function available as the
+above cannot be handled in an exception-agnostic way.
+
+NMIs can happen in any context. For example, an NMI-like exception triggered
+while handling an NMI. So NMI entry code has to be reentrant and state updates
+need to handle nesting.
diff --git a/Documentation/core-api/index.rst b/Documentation/core-api/index.rst
index 5de2c7a4b1b3..972d46a5ddf6 100644
--- a/Documentation/core-api/index.rst
+++ b/Documentation/core-api/index.rst
@@ -44,6 +44,14 @@ Library functionality that is used throughout the kernel.
timekeeping
errseq
+Low level entry and exit
+========================
+
+.. toctree::
+ :maxdepth: 1
+
+ entry
+
Concurrency primitives
======================
diff --git a/Documentation/core-api/mm-api.rst b/Documentation/core-api/mm-api.rst
index 395835f9289f..f5b2f92822c8 100644
--- a/Documentation/core-api/mm-api.rst
+++ b/Documentation/core-api/mm-api.rst
@@ -58,15 +58,30 @@ Virtually Contiguous Mappings
File Mapping and Page Cache
===========================
-.. kernel-doc:: mm/readahead.c
- :export:
+Filemap
+-------
.. kernel-doc:: mm/filemap.c
:export:
+Readahead
+---------
+
+.. kernel-doc:: mm/readahead.c
+ :doc: Readahead Overview
+
+.. kernel-doc:: mm/readahead.c
+ :export:
+
+Writeback
+---------
+
.. kernel-doc:: mm/page-writeback.c
:export:
+Truncate
+--------
+
.. kernel-doc:: mm/truncate.c
:export:
diff --git a/Documentation/core-api/pin_user_pages.rst b/Documentation/core-api/pin_user_pages.rst
index fcf605be43d0..b18416f4500f 100644
--- a/Documentation/core-api/pin_user_pages.rst
+++ b/Documentation/core-api/pin_user_pages.rst
@@ -55,18 +55,18 @@ flags the caller provides. The caller is required to pass in a non-null struct
pages* array, and the function then pins pages by incrementing each by a special
value: GUP_PIN_COUNTING_BIAS.
-For huge pages (and in fact, any compound page of more than 2 pages), the
-GUP_PIN_COUNTING_BIAS scheme is not used. Instead, an exact form of pin counting
-is achieved, by using the 3rd struct page in the compound page. A new struct
-page field, hpage_pinned_refcount, has been added in order to support this.
+For compound pages, the GUP_PIN_COUNTING_BIAS scheme is not used. Instead,
+an exact form of pin counting is achieved, by using the 2nd struct page
+in the compound page. A new struct page field, compound_pincount, has
+been added in order to support this.
This approach for compound pages avoids the counting upper limit problems that
are discussed below. Those limitations would have been aggravated severely by
huge pages, because each tail page adds a refcount to the head page. And in
-fact, testing revealed that, without a separate hpage_pinned_refcount field,
+fact, testing revealed that, without a separate compound_pincount field,
page overflows were seen in some huge page stress tests.
-This also means that huge pages and compound pages (of order > 1) do not suffer
+This also means that huge pages and compound pages do not suffer
from the false positives problem that is mentioned below.::
Function
@@ -264,9 +264,9 @@ place.)
Other diagnostics
=================
-dump_page() has been enhanced slightly, to handle these new counting fields, and
-to better report on compound pages in general. Specifically, for compound pages
-with order > 1, the exact (hpage_pinned_refcount) pincount is reported.
+dump_page() has been enhanced slightly, to handle these new counting
+fields, and to better report on compound pages in general. Specifically,
+for compound pages, the exact (compound_pincount) pincount is reported.
References
==========
diff --git a/Documentation/cpu-freq/cpu-drivers.rst b/Documentation/cpu-freq/cpu-drivers.rst
index 3b32336a7803..d84ededb66f9 100644
--- a/Documentation/cpu-freq/cpu-drivers.rst
+++ b/Documentation/cpu-freq/cpu-drivers.rst
@@ -75,6 +75,9 @@ And optionally
.resume - A pointer to a per-policy resume function which is called
with interrupts disabled and _before_ the governor is started again.
+ .ready - A pointer to a per-policy ready function which is called after
+ the policy is fully initialized.
+
.attr - A pointer to a NULL-terminated list of "struct freq_attr" which
allow to export values to sysfs.
diff --git a/Documentation/dev-tools/kfence.rst b/Documentation/dev-tools/kfence.rst
index ac6b89d1a8c3..936f6aaa75c8 100644
--- a/Documentation/dev-tools/kfence.rst
+++ b/Documentation/dev-tools/kfence.rst
@@ -41,6 +41,18 @@ guarded by KFENCE. The default is configurable via the Kconfig option
``CONFIG_KFENCE_SAMPLE_INTERVAL``. Setting ``kfence.sample_interval=0``
disables KFENCE.
+The sample interval controls a timer that sets up KFENCE allocations. By
+default, to keep the real sample interval predictable, the normal timer also
+causes CPU wake-ups when the system is completely idle. This may be undesirable
+on power-constrained systems. The boot parameter ``kfence.deferrable=1``
+instead switches to a "deferrable" timer which does not force CPU wake-ups on
+idle systems, at the risk of unpredictable sample intervals. The default is
+configurable via the Kconfig option ``CONFIG_KFENCE_DEFERRABLE``.
+
+.. warning::
+ The KUnit test suite is very likely to fail when using a deferrable timer
+ since it currently causes very unpredictable sample intervals.
+
The KFENCE memory pool is of fixed size, and if the pool is exhausted, no
further KFENCE allocations occur. With ``CONFIG_KFENCE_NUM_OBJECTS`` (default
255), the number of available guarded objects can be controlled. Each object
diff --git a/Documentation/dev-tools/kselftest.rst b/Documentation/dev-tools/kselftest.rst
index dcefee707ccd..a833ecf12fbc 100644
--- a/Documentation/dev-tools/kselftest.rst
+++ b/Documentation/dev-tools/kselftest.rst
@@ -7,6 +7,14 @@ directory. These are intended to be small tests to exercise individual code
paths in the kernel. Tests are intended to be run after building, installing
and booting a kernel.
+Kselftest from mainline can be run on older stable kernels. Running tests
+from mainline offers the best coverage. Several test rings run mainline
+kselftest suite on stable releases. The reason is that when a new test
+gets added to test existing code to regression test a bug, we should be
+able to run that test on an older kernel. Hence, it is important to keep
+code that can still test an older kernel and make sure it skips the test
+gracefully on newer releases.
+
You can find additional information on Kselftest framework, how to
write new tests using the framework on Kselftest wiki:
diff --git a/Documentation/dev-tools/ktap.rst b/Documentation/dev-tools/ktap.rst
index 878530cb9c27..5ee735c6687f 100644
--- a/Documentation/dev-tools/ktap.rst
+++ b/Documentation/dev-tools/ktap.rst
@@ -1,8 +1,8 @@
.. SPDX-License-Identifier: GPL-2.0
-========================================
-The Kernel Test Anything Protocol (KTAP)
-========================================
+===================================================
+The Kernel Test Anything Protocol (KTAP), version 1
+===================================================
TAP, or the Test Anything Protocol is a format for specifying test results used
by a number of projects. It's website and specification are found at this `link
@@ -68,7 +68,7 @@ Test case result lines
Test case result lines indicate the final status of a test.
They are required and must have the format:
-.. code-block::
+.. code-block:: none
<result> <number> [<description>][ # [<directive>] [<diagnostic data>]]
@@ -117,32 +117,32 @@ separator.
Example result lines include:
-.. code-block::
+.. code-block:: none
ok 1 test_case_name
The test "test_case_name" passed.
-.. code-block::
+.. code-block:: none
not ok 1 test_case_name
The test "test_case_name" failed.
-.. code-block::
+.. code-block:: none
ok 1 test # SKIP necessary dependency unavailable
The test "test" was SKIPPED with the diagnostic message "necessary dependency
unavailable".
-.. code-block::
+.. code-block:: none
not ok 1 test # TIMEOUT 30 seconds
The test "test" timed out, with diagnostic data "30 seconds".
-.. code-block::
+.. code-block:: none
ok 5 check return code # rcode=0
@@ -174,6 +174,13 @@ There may be lines within KTAP output that do not follow the format of one of
the four formats for lines described above. This is allowed, however, they will
not influence the status of the tests.
+This is an important difference from TAP. Kernel tests may print messages
+to the system console or a log file. Both of these destinations may contain
+messages either from unrelated kernel or userspace activity, or kernel
+messages from non-test code that is invoked by the test. The kernel code
+invoked by the test likely is not aware that a test is in progress and
+thus can not print the message as a diagnostic message.
+
Nested tests
------------
@@ -186,13 +193,16 @@ starting with another KTAP version line and test plan, and end with the overall
result. If one of the subtests fail, for example, the parent test should also
fail.
-Additionally, all result lines in a subtest should be indented. One level of
+Additionally, all lines in a subtest should be indented. One level of
indentation is two spaces: " ". The indentation should begin at the version
line and should end before the parent test's result line.
+"Unknown lines" are not considered to be lines in a subtest and thus are
+allowed to be either indented or not indented.
+
An example of a test with two nested subtests:
-.. code-block::
+.. code-block:: none
KTAP version 1
1..1
@@ -205,7 +215,7 @@ An example of a test with two nested subtests:
An example format with multiple levels of nested testing:
-.. code-block::
+.. code-block:: none
KTAP version 1
1..2
@@ -224,10 +234,15 @@ An example format with multiple levels of nested testing:
Major differences between TAP and KTAP
--------------------------------------
-Note the major differences between the TAP and KTAP specification:
-- yaml and json are not recommended in diagnostic messages
-- TODO directive not recognized
-- KTAP allows for an arbitrary number of tests to be nested
+================================================== ========= ===============
+Feature TAP KTAP
+================================================== ========= ===============
+yaml and json in diagnosic message ok not recommended
+TODO directive ok not recognized
+allows an arbitrary number of tests to be nested no yes
+"Unknown lines" are in category of "Anything else" yes no
+"Unknown lines" are incorrect allowed
+================================================== ========= ===============
The TAP14 specification does permit nested tests, but instead of using another
nested version line, uses a line of the form
@@ -235,7 +250,7 @@ nested version line, uses a line of the form
Example KTAP output
--------------------
-.. code-block::
+.. code-block:: none
KTAP version 1
1..1
diff --git a/Documentation/dev-tools/kunit/usage.rst b/Documentation/dev-tools/kunit/usage.rst
index 76af931a332c..1c83e7d60a8a 100644
--- a/Documentation/dev-tools/kunit/usage.rst
+++ b/Documentation/dev-tools/kunit/usage.rst
@@ -242,7 +242,7 @@ example:
int rectangle_area(struct shape *this)
{
- struct rectangle *self = container_of(this, struct shape, parent);
+ struct rectangle *self = container_of(this, struct rectangle, parent);
return self->length * self->width;
};
diff --git a/Documentation/dev-tools/sparse.rst b/Documentation/dev-tools/sparse.rst
index 02102be7ff49..dc791c8d84d1 100644
--- a/Documentation/dev-tools/sparse.rst
+++ b/Documentation/dev-tools/sparse.rst
@@ -100,3 +100,5 @@ have already built it.
The optional make variable CF can be used to pass arguments to sparse. The
build system passes -Wbitwise to sparse automatically.
+
+Note that sparse defines the __CHECKER__ preprocessor symbol.
diff --git a/Documentation/devicetree/bindings/arm/airoha.yaml b/Documentation/devicetree/bindings/arm/airoha.yaml
new file mode 100644
index 000000000000..fc19b1a6f37b
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/airoha.yaml
@@ -0,0 +1,28 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/arm/airoha.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Airoha SoC based Platforms Device Tree Bindings
+
+maintainers:
+ - Felix Fietkau <nbd@nbd.name>
+ - John Crispin <john@phrozen.org>
+
+description:
+ Boards with an Airoha SoC shall have the following properties.
+
+properties:
+ $nodename:
+ const: '/'
+ compatible:
+ oneOf:
+ - items:
+ - enum:
+ - airoha,en7523-evb
+ - const: airoha,en7523
+
+additionalProperties: true
+
+...
diff --git a/Documentation/devicetree/bindings/arm/altera.yaml b/Documentation/devicetree/bindings/arm/altera.yaml
index c15c92fdf2ed..5e2017c0a051 100644
--- a/Documentation/devicetree/bindings/arm/altera.yaml
+++ b/Documentation/devicetree/bindings/arm/altera.yaml
@@ -13,12 +13,46 @@ properties:
$nodename:
const: "/"
compatible:
- items:
- - enum:
- - altr,socfpga-cyclone5
- - altr,socfpga-arria5
- - altr,socfpga-arria10
- - const: altr,socfpga
+ oneOf:
+ - description: Arria 5 boards
+ items:
+ - enum:
+ - altr,socfpga-arria5-socdk
+ - const: altr,socfpga-arria5
+ - const: altr,socfpga
+
+ - description: Arria 10 boards
+ items:
+ - enum:
+ - altr,socfpga-arria10-socdk
+ - enclustra,mercury-aa1
+ - const: altr,socfpga-arria10
+ - const: altr,socfpga
+
+ - description: Cyclone 5 boards
+ items:
+ - enum:
+ - altr,socfpga-cyclone5-socdk
+ - denx,mcvevk
+ - ebv,socrates
+ - macnica,sodia
+ - novtech,chameleon96
+ - samtec,vining
+ - terasic,de0-atlas
+ - terasic,socfpga-cyclone5-sockit
+ - const: altr,socfpga-cyclone5
+ - const: altr,socfpga
+
+ - description: Stratix 10 boards
+ items:
+ - enum:
+ - altr,socfpga-stratix10-socdk
+ - const: altr,socfpga-stratix10
+
+ - description: SoCFPGA VT
+ items:
+ - const: altr,socfpga-vt
+ - const: altr,socfpga
additionalProperties: true
diff --git a/Documentation/devicetree/bindings/arm/amlogic.yaml b/Documentation/devicetree/bindings/arm/amlogic.yaml
index 36081734f720..61a6cabb375b 100644
--- a/Documentation/devicetree/bindings/arm/amlogic.yaml
+++ b/Documentation/devicetree/bindings/arm/amlogic.yaml
@@ -108,6 +108,7 @@ properties:
- amlogic,p230
- amlogic,p231
- libretech,aml-s905d-pc
+ - osmc,vero4k-plus
- phicomm,n1
- smartlabs,sml5442tw
- videostrong,gxl-kii-pro
@@ -170,9 +171,14 @@ properties:
- description: Boards with the Amlogic Meson SM1 S905X3/D3/Y3 SoC
items:
- enum:
+ - amediatech,x96-air
+ - amediatech,x96-air-gbit
- bananapi,bpi-m5
+ - cyx,a95xf3-air
+ - cyx,a95xf3-air-gbit
- hardkernel,odroid-c4
- hardkernel,odroid-hc4
+ - haochuangyi,h96-max
- khadas,vim3l
- seirobotics,sei610
- const: amlogic,sm1
@@ -183,6 +189,12 @@ properties:
- amlogic,ad401
- const: amlogic,a1
+ - description: Boards with the Amlogic Meson S4 S805X2 SoC
+ items:
+ - enum:
+ - amlogic,aq222
+ - const: amlogic,s4
+
additionalProperties: true
...
diff --git a/Documentation/devicetree/bindings/arm/atmel-at91.yaml b/Documentation/devicetree/bindings/arm/atmel-at91.yaml
index c612e1f48dba..4e495e03264b 100644
--- a/Documentation/devicetree/bindings/arm/atmel-at91.yaml
+++ b/Documentation/devicetree/bindings/arm/atmel-at91.yaml
@@ -8,7 +8,8 @@ title: Atmel AT91 device tree bindings.
maintainers:
- Alexandre Belloni <alexandre.belloni@bootlin.com>
- - Ludovic Desroches <ludovic.desroches@microchip.com>
+ - Claudiu Beznea <claudiu.beznea@microchip.com>
+ - Nicolas Ferre <nicolas.ferre@microchip.com>
description: |
Boards with a SoC of the Atmel AT91 or SMART family shall have the following
@@ -174,6 +175,15 @@ properties:
- const: microchip,lan9668
- const: microchip,lan966
+ - description: Kontron KSwitch D10 MMT series
+ items:
+ - enum:
+ - kontron,kswitch-d10-mmt-8g
+ - kontron,kswitch-d10-mmt-6g-2gs
+ - const: kontron,s1921
+ - const: microchip,lan9668
+ - const: microchip,lan966
+
- items:
- enum:
- atmel,sams70j19
diff --git a/Documentation/devicetree/bindings/arm/bcm/bcm2835.yaml b/Documentation/devicetree/bindings/arm/bcm/bcm2835.yaml
index 5dc48241efb3..8051a75c2c79 100644
--- a/Documentation/devicetree/bindings/arm/bcm/bcm2835.yaml
+++ b/Documentation/devicetree/bindings/arm/bcm/bcm2835.yaml
@@ -51,6 +51,7 @@ properties:
- raspberrypi,3-model-b-plus
- raspberrypi,3-compute-module
- raspberrypi,3-compute-module-lite
+ - raspberrypi,model-zero-2-w
- const: brcm,bcm2837
additionalProperties: true
diff --git a/Documentation/devicetree/bindings/arm/cpus.yaml b/Documentation/devicetree/bindings/arm/cpus.yaml
index 0dcebc48ea22..3aad1b93742c 100644
--- a/Documentation/devicetree/bindings/arm/cpus.yaml
+++ b/Documentation/devicetree/bindings/arm/cpus.yaml
@@ -173,6 +173,7 @@ properties:
- nvidia,tegra194-carmel
- qcom,krait
- qcom,kryo
+ - qcom,kryo250
- qcom,kryo260
- qcom,kryo280
- qcom,kryo385
diff --git a/Documentation/devicetree/bindings/arm/freescale/fsl,layerscape-dcfg.txt b/Documentation/devicetree/bindings/arm/freescale/fsl,layerscape-dcfg.txt
index b5cb374dc47d..10a91cc8b997 100644
--- a/Documentation/devicetree/bindings/arm/freescale/fsl,layerscape-dcfg.txt
+++ b/Documentation/devicetree/bindings/arm/freescale/fsl,layerscape-dcfg.txt
@@ -8,7 +8,7 @@ Required properties:
- compatible: Should contain a chip-specific compatible string,
Chip-specific strings are of the form "fsl,<chip>-dcfg",
The following <chip>s are known to be supported:
- ls1012a, ls1021a, ls1043a, ls1046a, ls2080a.
+ ls1012a, ls1021a, ls1043a, ls1046a, ls2080a, lx2160a
- reg : should contain base address and length of DCFG memory-mapped registers
diff --git a/Documentation/devicetree/bindings/arm/fsl.yaml b/Documentation/devicetree/bindings/arm/fsl.yaml
index 97f6eebad76a..08bdd30e511c 100644
--- a/Documentation/devicetree/bindings/arm/fsl.yaml
+++ b/Documentation/devicetree/bindings/arm/fsl.yaml
@@ -762,6 +762,7 @@ properties:
- enum:
- beacon,imx8mm-beacon-kit # i.MX8MM Beacon Development Kit
- boundary,imx8mm-nitrogen8mm # i.MX8MM Nitrogen Board
+ - emtrion,emcon-mx8mm-avari # emCON-MX8MM SoM on Avari Base
- fsl,imx8mm-ddr4-evk # i.MX8MM DDR4 EVK Board
- fsl,imx8mm-evk # i.MX8MM EVK Board
- gw,imx8mm-gw71xx-0x # i.MX8MM Gateworks Development Kit
@@ -769,8 +770,13 @@ properties:
- gw,imx8mm-gw73xx-0x # i.MX8MM Gateworks Development Kit
- gw,imx8mm-gw7901 # i.MX8MM Gateworks Board
- gw,imx8mm-gw7902 # i.MX8MM Gateworks Board
+ - gw,imx8mm-gw7903 # i.MX8MM Gateworks Board
- kontron,imx8mm-n801x-som # i.MX8MM Kontron SL (N801X) SOM
+ - toradex,verdin-imx8mm # Verdin iMX8M Mini Modules
+ - toradex,verdin-imx8mm-nonwifi # Verdin iMX8M Mini Modules without Wi-Fi / BT
+ - toradex,verdin-imx8mm-wifi # Verdin iMX8M Mini Wi-Fi / BT Modules
- variscite,var-som-mx8mm # i.MX8MM Variscite VAR-SOM-MX8MM module
+ - prt,prt8mm # i.MX8MM Protonic PRT8MM Board
- const: fsl,imx8mm
- description: Engicam i.Core MX8M Mini SoM based boards
@@ -787,6 +793,24 @@ properties:
- const: kontron,imx8mm-n801x-som
- const: fsl,imx8mm
+ - description: Toradex Boards with Verdin iMX8M Mini Modules
+ items:
+ - enum:
+ - toradex,verdin-imx8mm-nonwifi-dahlia # Verdin iMX8M Mini Module on Dahlia
+ - toradex,verdin-imx8mm-nonwifi-dev # Verdin iMX8M Mini Module on Verdin Development Board
+ - const: toradex,verdin-imx8mm-nonwifi # Verdin iMX8M Mini Module without Wi-Fi / BT
+ - const: toradex,verdin-imx8mm # Verdin iMX8M Mini Module
+ - const: fsl,imx8mm
+
+ - description: Toradex Boards with Verdin iMX8M Mini Wi-Fi / BT Modules
+ items:
+ - enum:
+ - toradex,verdin-imx8mm-wifi-dahlia # Verdin iMX8M Mini Wi-Fi / BT Module on Dahlia
+ - toradex,verdin-imx8mm-wifi-dev # Verdin iMX8M Mini Wi-Fi / BT M. on Verdin Development B.
+ - const: toradex,verdin-imx8mm-wifi # Verdin iMX8M Mini Wi-Fi / BT Module
+ - const: toradex,verdin-imx8mm # Verdin iMX8M Mini Module
+ - const: fsl,imx8mm
+
- description: Variscite VAR-SOM-MX8MM based boards
items:
- const: variscite,var-som-mx8mm-symphony
diff --git a/Documentation/devicetree/bindings/arm/intel,socfpga.yaml b/Documentation/devicetree/bindings/arm/intel,socfpga.yaml
new file mode 100644
index 000000000000..6e043459fcd5
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/intel,socfpga.yaml
@@ -0,0 +1,26 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/arm/intel,socfpga.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Intel SoCFPGA platform device tree bindings
+
+maintainers:
+ - Dinh Nguyen <dinguyen@kernel.org>
+
+properties:
+ $nodename:
+ const: "/"
+ compatible:
+ oneOf:
+ - description: AgileX boards
+ items:
+ - enum:
+ - intel,n5x-socdk
+ - intel,socfpga-agilex-socdk
+ - const: intel,socfpga-agilex
+
+additionalProperties: true
+
+...
diff --git a/Documentation/devicetree/bindings/arm/mediatek.yaml b/Documentation/devicetree/bindings/arm/mediatek.yaml
index 0ffe1acf1344..ab0593c77321 100644
--- a/Documentation/devicetree/bindings/arm/mediatek.yaml
+++ b/Documentation/devicetree/bindings/arm/mediatek.yaml
@@ -32,6 +32,10 @@ properties:
- const: mediatek,mt6580
- items:
- enum:
+ - prestigio,pmt5008-3g
+ - const: mediatek,mt6582
+ - items:
+ - enum:
- fairphone,fp1
- mundoreader,bq-aquaris5
- const: mediatek,mt6589
diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml b/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml
index 763c62323a74..b31d90dc9eb4 100644
--- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml
+++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml
@@ -29,6 +29,7 @@ properties:
- mediatek,mt8167-mmsys
- mediatek,mt8173-mmsys
- mediatek,mt8183-mmsys
+ - mediatek,mt8186-mmsys
- mediatek,mt8192-mmsys
- mediatek,mt8365-mmsys
- const: syscon
diff --git a/Documentation/devicetree/bindings/arm/msm/qcom,llcc.yaml b/Documentation/devicetree/bindings/arm/msm/qcom,llcc.yaml
index 03882aac8d2d..30fcbe2ad8a3 100644
--- a/Documentation/devicetree/bindings/arm/msm/qcom,llcc.yaml
+++ b/Documentation/devicetree/bindings/arm/msm/qcom,llcc.yaml
@@ -27,6 +27,8 @@ properties:
- qcom,sm6350-llcc
- qcom,sm8150-llcc
- qcom,sm8250-llcc
+ - qcom,sm8350-llcc
+ - qcom,sm8450-llcc
reg:
items:
diff --git a/Documentation/devicetree/bindings/arm/mstar/mstar.yaml b/Documentation/devicetree/bindings/arm/mstar/mstar.yaml
index a316eef1b728..8892eb6bd3ef 100644
--- a/Documentation/devicetree/bindings/arm/mstar/mstar.yaml
+++ b/Documentation/devicetree/bindings/arm/mstar/mstar.yaml
@@ -23,8 +23,12 @@ properties:
- description: infinity2m boards
items:
- enum:
+ - 100ask,dongshanpione # 100ask DongShanPiOne
- honestar,ssd201htv2 # Honestar SSD201_HT_V2 devkit
- m5stack,unitv2 # M5Stack UnitV2
+ - miyoo,miyoo-mini # Miyoo Mini
+ - wirelesstag,ido-som2d01 # Wireless Tag IDO-SOM2D01
+ - wirelesstag,ido-sbc2d06-v1b-22w # Wireless Tag IDO-SBC2D06-1VB-22W
- const: mstar,infinity2m
- description: infinity3 boards
diff --git a/Documentation/devicetree/bindings/arm/npcm/nuvoton,gcr.yaml b/Documentation/devicetree/bindings/arm/npcm/nuvoton,gcr.yaml
new file mode 100644
index 000000000000..fcb211add7d3
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/npcm/nuvoton,gcr.yaml
@@ -0,0 +1,48 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/arm/npcm/nuvoton,gcr.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Global Control Registers block in Nuvoton SoCs
+
+maintainers:
+ - Jonathan Neuschäfer <j.neuschaefer@gmx.net>
+
+description:
+ The Global Control Registers (GCR) are a block of registers in Nuvoton SoCs
+ that expose misc functionality such as chip model and version information or
+ pinmux settings.
+
+properties:
+ compatible:
+ items:
+ - enum:
+ - nuvoton,wpcm450-gcr
+ - nuvoton,npcm750-gcr
+ - const: syscon
+ - const: simple-mfd
+
+ reg:
+ maxItems: 1
+
+required:
+ - compatible
+ - reg
+
+additionalProperties:
+ type: object
+
+examples:
+ - |
+ gcr: syscon@800000 {
+ compatible = "nuvoton,npcm750-gcr", "syscon", "simple-mfd";
+ reg = <0x800000 0x1000>;
+
+ mux-controller {
+ compatible = "mmio-mux";
+ #mux-control-cells = <1>;
+ mux-reg-masks = <0x38 0x07>;
+ idle-states = <2>;
+ };
+ };
diff --git a/Documentation/devicetree/bindings/arm/omap/omap.txt b/Documentation/devicetree/bindings/arm/omap/omap.txt
index e77635c5422c..fa8b31660cad 100644
--- a/Documentation/devicetree/bindings/arm/omap/omap.txt
+++ b/Documentation/devicetree/bindings/arm/omap/omap.txt
@@ -119,6 +119,9 @@ Boards (incomplete list of examples):
- OMAP3 BeagleBoard : Low cost community board
compatible = "ti,omap3-beagle", "ti,omap3430", "ti,omap3"
+- OMAP3 BeagleBoard A to B4 : Early BeagleBoard revisions A to B4 with a timer quirk
+ compatible = "ti,omap3-beagle-ab4", "ti,omap3-beagle", "ti,omap3430", "ti,omap3"
+
- OMAP3 Tobi with Overo : Commercial expansion board with daughter board
compatible = "gumstix,omap3-overo-tobi", "gumstix,omap3-overo", "ti,omap3430", "ti,omap3"
diff --git a/Documentation/devicetree/bindings/arm/pmu.yaml b/Documentation/devicetree/bindings/arm/pmu.yaml
index 981bac451698..7a04b8aaaec3 100644
--- a/Documentation/devicetree/bindings/arm/pmu.yaml
+++ b/Documentation/devicetree/bindings/arm/pmu.yaml
@@ -20,6 +20,8 @@ properties:
items:
- enum:
- apm,potenza-pmu
+ - apple,firestorm-pmu
+ - apple,icestorm-pmu
- arm,armv8-pmuv3 # Only for s/w models
- arm,arm1136-pmu
- arm,arm1176-pmu
diff --git a/Documentation/devicetree/bindings/arm/qcom.yaml b/Documentation/devicetree/bindings/arm/qcom.yaml
index 370aab274cd1..129cdd246223 100644
--- a/Documentation/devicetree/bindings/arm/qcom.yaml
+++ b/Documentation/devicetree/bindings/arm/qcom.yaml
@@ -42,13 +42,13 @@ description: |
sc7180
sc7280
sdm630
+ sdm632
sdm660
sdm845
sdx55
sdx65
sm7225
sm8150
- sdx65
sm8250
sm8350
sm8450
@@ -173,7 +173,21 @@ properties:
- const: qcom,apq8094
- items:
- - const: qcom,msm8996-mtp
+ - enum:
+ - arrow,apq8096-db820c
+ - inforce,ifc6640
+ - const: qcom,apq8096-sbc
+ - const: qcom,apq8096
+
+ - items:
+ - enum:
+ - qcom,msm8996-mtp
+ - sony,dora-row
+ - sony,kagura-row
+ - sony,keyaki-row
+ - xiaomi,gemini
+ - xiaomi,scorpio
+ - const: qcom,msm8996
- items:
- enum:
@@ -213,6 +227,11 @@ properties:
- items:
- enum:
+ - fairphone,fp3
+ - const: qcom,sdm632
+
+ - items:
+ - enum:
- xiaomi,lavender
- const: qcom,sdm660
@@ -230,11 +249,6 @@ properties:
- items:
- enum:
- - qcom,sdx65-mtp
- - const: qcom,sdx65
-
- - items:
- - enum:
- qcom,ipq6018-cp01
- qcom,ipq6018-cp01-c1
- const: qcom,ipq6018
@@ -268,6 +282,7 @@ properties:
- items:
- enum:
+ - qcom,sm8450-hdk
- qcom,sm8450-qrd
- const: qcom,sm8450
diff --git a/Documentation/devicetree/bindings/arm/renesas.yaml b/Documentation/devicetree/bindings/arm/renesas.yaml
index 6a9350ee690b..fa435d6fda77 100644
--- a/Documentation/devicetree/bindings/arm/renesas.yaml
+++ b/Documentation/devicetree/bindings/arm/renesas.yaml
@@ -421,6 +421,15 @@ properties:
- renesas,r9a07g044l2 # Dual Cortex-A55 RZ/G2L
- const: renesas,r9a07g044
+ - description: RZ/V2L (R9A07G054)
+ items:
+ - enum:
+ - renesas,smarc-evk # SMARC EVK
+ - enum:
+ - renesas,r9a07g054l1 # Single Cortex-A55 RZ/V2L
+ - renesas,r9a07g054l2 # Dual Cortex-A55 RZ/V2L
+ - const: renesas,r9a07g054
+
additionalProperties: true
...
diff --git a/Documentation/devicetree/bindings/arm/rockchip.yaml b/Documentation/devicetree/bindings/arm/rockchip.yaml
index 4aed16176434..eece92f83a2d 100644
--- a/Documentation/devicetree/bindings/arm/rockchip.yaml
+++ b/Documentation/devicetree/bindings/arm/rockchip.yaml
@@ -481,6 +481,14 @@ properties:
- const: pine64,pinebook-pro
- const: rockchip,rk3399
+ - description: Pine64 PineNote
+ items:
+ - enum:
+ - pine64,pinenote-v1.1
+ - pine64,pinenote-v1.2
+ - const: pine64,pinenote
+ - const: rockchip,rk3566
+
- description: Pine64 Rock64
items:
- const: pine64,rock64
@@ -651,6 +659,11 @@ properties:
- const: rockchip,rk3568-evb1-v10
- const: rockchip,rk3568
+ - description: Rockchip RK3568 Banana Pi R2 Pro
+ items:
+ - const: rockchip,rk3568-bpi-r2pro
+ - const: rockchip,rk3568
+
additionalProperties: true
...
diff --git a/Documentation/devicetree/bindings/arm/samsung/samsung-boards.yaml b/Documentation/devicetree/bindings/arm/samsung/samsung-boards.yaml
index 052cd94113d4..faea33e4f731 100644
--- a/Documentation/devicetree/bindings/arm/samsung/samsung-boards.yaml
+++ b/Documentation/devicetree/bindings/arm/samsung/samsung-boards.yaml
@@ -140,6 +140,8 @@ properties:
items:
- enum:
- insignal,arndale-octa # Insignal Arndale Octa
+ - samsung,chagall-wifi # Samsung SM-T800
+ - samsung,klimt-wifi # Samsung SM-T700
- samsung,smdk5420 # Samsung SMDK5420 eval
- const: samsung,exynos5420
- const: samsung,exynos5
diff --git a/Documentation/devicetree/bindings/arm/stm32/stm32.yaml b/Documentation/devicetree/bindings/arm/stm32/stm32.yaml
index b07720ea9611..fa0a1b84122e 100644
--- a/Documentation/devicetree/bindings/arm/stm32/stm32.yaml
+++ b/Documentation/devicetree/bindings/arm/stm32/stm32.yaml
@@ -28,6 +28,12 @@ properties:
- enum:
- st,stm32mp153
- st,stm32mp157
+
+ - description: emtrion STM32MP1 Argon based Boards
+ items:
+ - const: emtrion,stm32mp157c-emsbc-argon
+ - const: emtrion,stm32mp157c-emstamp-argon
+ - const: st,stm32mp157
- items:
- enum:
- st,stm32f429i-disco
diff --git a/Documentation/devicetree/bindings/arm/sunxi.yaml b/Documentation/devicetree/bindings/arm/sunxi.yaml
index c8a3102c0fde..086c68771d2b 100644
--- a/Documentation/devicetree/bindings/arm/sunxi.yaml
+++ b/Documentation/devicetree/bindings/arm/sunxi.yaml
@@ -444,6 +444,11 @@ properties:
- const: haoyu,a10-marsboard
- const: allwinner,sun4i-a10
+ - description: HAOYU Electronics Marsboard A20
+ items:
+ - const: haoyu,a20-marsboard
+ - const: allwinner,sun7i-a20
+
- description: MapleBoard MP130
items:
- const: mapleboard,mp130
diff --git a/Documentation/devicetree/bindings/arm/tesla.yaml b/Documentation/devicetree/bindings/arm/tesla.yaml
new file mode 100644
index 000000000000..09856da657dc
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/tesla.yaml
@@ -0,0 +1,27 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/arm/tesla.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Tesla Full Self Driving(FSD) platforms device tree bindings
+
+maintainers:
+ - Alim Akhtar <alim.akhtar@samsung.com>
+ - linux-fsd@tesla.com
+
+properties:
+ $nodename:
+ const: '/'
+ compatible:
+ oneOf:
+
+ - description: FSD SoC board
+ items:
+ - enum:
+ - tesla,fsd-evb # Tesla FSD Evaluation
+ - const: tesla,fsd
+
+additionalProperties: true
+
+...
diff --git a/Documentation/devicetree/bindings/arm/ti/k3.yaml b/Documentation/devicetree/bindings/arm/ti/k3.yaml
index b03c10fa2e7a..61c6ab4f52e2 100644
--- a/Documentation/devicetree/bindings/arm/ti/k3.yaml
+++ b/Documentation/devicetree/bindings/arm/ti/k3.yaml
@@ -46,6 +46,12 @@ properties:
- ti,j7200-evm
- const: ti,j7200
+ - description: K3 AM625 SoC
+ items:
+ - enum:
+ - ti,am625-sk
+ - const: ti,am625
+
- description: K3 AM642 SoC
items:
- enum:
diff --git a/Documentation/devicetree/bindings/bus/nvidia,tegra210-aconnect.yaml b/Documentation/devicetree/bindings/bus/nvidia,tegra210-aconnect.yaml
index 7b1a08c62aef..d3ed048c9521 100644
--- a/Documentation/devicetree/bindings/bus/nvidia,tegra210-aconnect.yaml
+++ b/Documentation/devicetree/bindings/bus/nvidia,tegra210-aconnect.yaml
@@ -21,6 +21,7 @@ properties:
- const: nvidia,tegra210-aconnect
- items:
- enum:
+ - nvidia,tegra234-aconnect
- nvidia,tegra186-aconnect
- nvidia,tegra194-aconnect
- const: nvidia,tegra210-aconnect
diff --git a/Documentation/devicetree/bindings/clock/intc_stratix10.txt b/Documentation/devicetree/bindings/clock/intc_stratix10.txt
deleted file mode 100644
index 9f4ec5cb5c6b..000000000000
--- a/Documentation/devicetree/bindings/clock/intc_stratix10.txt
+++ /dev/null
@@ -1,20 +0,0 @@
-Device Tree Clock bindings for Intel's SoCFPGA Stratix10 platform
-
-This binding uses the common clock binding[1].
-
-[1] Documentation/devicetree/bindings/clock/clock-bindings.txt
-
-Required properties:
-- compatible : shall be
- "intel,stratix10-clkmgr"
-
-- reg : shall be the control register offset from CLOCK_MANAGER's base for the clock.
-
-- #clock-cells : from common clock binding, shall be set to 1.
-
-Example:
- clkmgr: clock-controller@ffd10000 {
- compatible = "intel,stratix10-clkmgr";
- reg = <0xffd10000 0x1000>;
- #clock-cells = <1>;
- };
diff --git a/Documentation/devicetree/bindings/clock/intel,stratix10.yaml b/Documentation/devicetree/bindings/clock/intel,stratix10.yaml
new file mode 100644
index 000000000000..f506e3db9782
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/intel,stratix10.yaml
@@ -0,0 +1,35 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/intel,stratix10.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Intel SoCFPGA Stratix10 platform clock controller binding
+
+maintainers:
+ - Dinh Nguyen <dinguyen@kernel.org>
+
+properties:
+ compatible:
+ const: intel,stratix10-clkmgr
+
+ '#clock-cells':
+ const: 1
+
+ reg:
+ maxItems: 1
+
+required:
+ - compatible
+ - reg
+ - '#clock-cells'
+
+additionalProperties: false
+
+examples:
+ - |
+ clock-controller@ffd10000 {
+ compatible = "intel,stratix10-clkmgr";
+ reg = <0xffd10000 0x1000>;
+ #clock-cells = <1>;
+ };
diff --git a/Documentation/devicetree/bindings/clock/mstar,msc313-cpupll.yaml b/Documentation/devicetree/bindings/clock/mstar,msc313-cpupll.yaml
new file mode 100644
index 000000000000..a9ad7ab5230c
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/mstar,msc313-cpupll.yaml
@@ -0,0 +1,45 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/mstar,msc313-cpupll.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: MStar/Sigmastar MSC313 CPU PLL
+
+maintainers:
+ - Daniel Palmer <daniel@thingy.jp>
+
+description: |
+ The MStar/SigmaStar MSC313 and later ARMv7 chips have a scalable
+ PLL that can be used as the clock source for the CPU(s).
+
+properties:
+ compatible:
+ const: mstar,msc313-cpupll
+
+ "#clock-cells":
+ const: 1
+
+ clocks:
+ maxItems: 1
+
+ reg:
+ maxItems: 1
+
+required:
+ - compatible
+ - "#clock-cells"
+ - clocks
+ - reg
+
+additionalProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/clock/mstar-msc313-mpll.h>
+ cpupll: cpupll@206400 {
+ compatible = "mstar,msc313-cpupll";
+ reg = <0x206400 0x200>;
+ #clock-cells = <1>;
+ clocks = <&mpll MSTAR_MSC313_MPLL_DIV2>;
+ };
diff --git a/Documentation/devicetree/bindings/clock/qoriq-clock.txt b/Documentation/devicetree/bindings/clock/qoriq-clock.txt
index f7d48f23da44..10119d9ef4b1 100644
--- a/Documentation/devicetree/bindings/clock/qoriq-clock.txt
+++ b/Documentation/devicetree/bindings/clock/qoriq-clock.txt
@@ -44,6 +44,7 @@ Required properties:
* "fsl,ls1046a-clockgen"
* "fsl,ls1088a-clockgen"
* "fsl,ls2080a-clockgen"
+ * "fsl,lx2160a-clockgen"
Chassis-version clock strings include:
* "fsl,qoriq-clockgen-1.0": for chassis 1.0 clocks
* "fsl,qoriq-clockgen-2.0": for chassis 2.0 clocks
diff --git a/Documentation/devicetree/bindings/clock/tesla,fsd-clock.yaml b/Documentation/devicetree/bindings/clock/tesla,fsd-clock.yaml
new file mode 100644
index 000000000000..dc808e2f8327
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/tesla,fsd-clock.yaml
@@ -0,0 +1,198 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/tesla,fsd-clock.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Tesla FSD (Full Self-Driving) SoC clock controller
+
+maintainers:
+ - Alim Akhtar <alim.akhtar@samsung.com>
+ - linux-fsd@tesla.com
+
+description: |
+ FSD clock controller consist of several clock management unit
+ (CMU), which generates clocks for various inteernal SoC blocks.
+ The root clock comes from external OSC clock (24 MHz).
+
+ All available clocks are defined as preprocessor macros in
+ 'dt-bindings/clock/fsd-clk.h' header.
+
+properties:
+ compatible:
+ enum:
+ - tesla,fsd-clock-cmu
+ - tesla,fsd-clock-imem
+ - tesla,fsd-clock-peric
+ - tesla,fsd-clock-fsys0
+ - tesla,fsd-clock-fsys1
+ - tesla,fsd-clock-mfc
+ - tesla,fsd-clock-cam_csi
+
+ clocks:
+ minItems: 1
+ maxItems: 6
+
+ clock-names:
+ minItems: 1
+ maxItems: 6
+
+ "#clock-cells":
+ const: 1
+
+ reg:
+ maxItems: 1
+
+allOf:
+ - if:
+ properties:
+ compatible:
+ contains:
+ const: tesla,fsd-clock-cmu
+ then:
+ properties:
+ clocks:
+ items:
+ - description: External reference clock (24 MHz)
+ clock-names:
+ items:
+ - const: fin_pll
+
+ - if:
+ properties:
+ compatible:
+ contains:
+ const: tesla,fsd-clock-imem
+ then:
+ properties:
+ clocks:
+ items:
+ - description: External reference clock (24 MHz)
+ - description: IMEM TCU clock (from CMU_CMU)
+ - description: IMEM bus clock (from CMU_CMU)
+ - description: IMEM DMA clock (from CMU_CMU)
+ clock-names:
+ items:
+ - const: fin_pll
+ - const: dout_cmu_imem_tcuclk
+ - const: dout_cmu_imem_aclk
+ - const: dout_cmu_imem_dmaclk
+
+ - if:
+ properties:
+ compatible:
+ contains:
+ const: tesla,fsd-clock-peric
+ then:
+ properties:
+ clocks:
+ items:
+ - description: External reference clock (24 MHz)
+ - description: Shared0 PLL div4 clock (from CMU_CMU)
+ - description: PERIC shared1 div36 clock (from CMU_CMU)
+ - description: PERIC shared0 div3 TBU clock (from CMU_CMU)
+ - description: PERIC shared0 div20 clock (from CMU_CMU)
+ - description: PERIC shared1 div4 DMAclock (from CMU_CMU)
+ clock-names:
+ items:
+ - const: fin_pll
+ - const: dout_cmu_pll_shared0_div4
+ - const: dout_cmu_peric_shared1div36
+ - const: dout_cmu_peric_shared0div3_tbuclk
+ - const: dout_cmu_peric_shared0div20
+ - const: dout_cmu_peric_shared1div4_dmaclk
+
+ - if:
+ properties:
+ compatible:
+ contains:
+ const: tesla,fsd-clock-fsys0
+ then:
+ properties:
+ clocks:
+ items:
+ - description: External reference clock (24 MHz)
+ - description: Shared0 PLL div6 clock (from CMU_CMU)
+ - description: FSYS0 shared1 div4 clock (from CMU_CMU)
+ - description: FSYS0 shared0 div4 clock (from CMU_CMU)
+ clock-names:
+ items:
+ - const: fin_pll
+ - const: dout_cmu_pll_shared0_div6
+ - const: dout_cmu_fsys0_shared1div4
+ - const: dout_cmu_fsys0_shared0div4
+
+ - if:
+ properties:
+ compatible:
+ contains:
+ const: tesla,fsd-clock-fsys1
+ then:
+ properties:
+ clocks:
+ items:
+ - description: External reference clock (24 MHz)
+ - description: FSYS1 shared0 div8 clock (from CMU_CMU)
+ - description: FSYS1 shared0 div4 clock (from CMU_CMU)
+ clock-names:
+ items:
+ - const: fin_pll
+ - const: dout_cmu_fsys1_shared0div8
+ - const: dout_cmu_fsys1_shared0div4
+
+ - if:
+ properties:
+ compatible:
+ contains:
+ const: tesla,fsd-clock-mfc
+ then:
+ properties:
+ clocks:
+ items:
+ - description: External reference clock (24 MHz)
+ clock-names:
+ items:
+ - const: fin_pll
+
+ - if:
+ properties:
+ compatible:
+ contains:
+ const: tesla,fsd-clock-cam_csi
+ then:
+ properties:
+ clocks:
+ items:
+ - description: External reference clock (24 MHz)
+ clock-names:
+ items:
+ - const: fin_pll
+
+required:
+ - compatible
+ - "#clock-cells"
+ - clocks
+ - clock-names
+ - reg
+
+additionalProperties: false
+
+examples:
+ # Clock controller node for CMU_FSYS1
+ - |
+ #include <dt-bindings/clock/fsd-clk.h>
+
+ clock_fsys1: clock-controller@16810000 {
+ compatible = "tesla,fsd-clock-fsys1";
+ reg = <0x16810000 0x3000>;
+ #clock-cells = <1>;
+
+ clocks = <&fin_pll>,
+ <&clock_cmu DOUT_CMU_FSYS1_SHARED0DIV8>,
+ <&clock_cmu DOUT_CMU_FSYS1_SHARED0DIV4>;
+ clock-names = "fin_pll",
+ "dout_cmu_fsys1_shared0div8",
+ "dout_cmu_fsys1_shared0div4";
+ };
+
+...
diff --git a/Documentation/devicetree/bindings/display/bridge/analogix,anx7625.yaml b/Documentation/devicetree/bindings/display/bridge/analogix,anx7625.yaml
index 1d3e88daca04..35a48515836e 100644
--- a/Documentation/devicetree/bindings/display/bridge/analogix,anx7625.yaml
+++ b/Documentation/devicetree/bindings/display/bridge/analogix,anx7625.yaml
@@ -83,6 +83,9 @@ properties:
type: boolean
description: let the driver enable audio HDMI codec function or not.
+ aux-bus:
+ $ref: /schemas/display/dp-aux-bus.yaml#
+
ports:
$ref: /schemas/graph.yaml#/properties/ports
@@ -91,22 +94,7 @@ properties:
$ref: /schemas/graph.yaml#/$defs/port-base
unevaluatedProperties: false
description:
- MIPI DSI/DPI input.
-
- properties:
- endpoint:
- $ref: /schemas/media/video-interfaces.yaml#
- type: object
- additionalProperties: false
-
- properties:
- remote-endpoint: true
-
- bus-type:
- enum: [1, 5]
- default: 1
-
- data-lanes: true
+ Video port for MIPI DSI input.
port@1:
$ref: /schemas/graph.yaml#/properties/port
@@ -155,8 +143,6 @@ examples:
reg = <0>;
anx7625_in: endpoint {
remote-endpoint = <&mipi_dsi>;
- bus-type = <5>;
- data-lanes = <0 1 2 3>;
};
};
@@ -167,5 +153,19 @@ examples:
};
};
};
+
+ aux-bus {
+ panel {
+ compatible = "innolux,n125hce-gn1";
+ power-supply = <&pp3300_disp_x>;
+ backlight = <&backlight_lcd0>;
+
+ port {
+ panel_in: endpoint {
+ remote-endpoint = <&anx7625_out>;
+ };
+ };
+ };
+ };
};
};
diff --git a/Documentation/devicetree/bindings/display/bridge/ingenic,jz4780-hdmi.yaml b/Documentation/devicetree/bindings/display/bridge/ingenic,jz4780-hdmi.yaml
new file mode 100644
index 000000000000..b8219eab4475
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/bridge/ingenic,jz4780-hdmi.yaml
@@ -0,0 +1,82 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/bridge/ingenic,jz4780-hdmi.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Bindings for Ingenic JZ4780 HDMI Transmitter
+
+maintainers:
+ - H. Nikolaus Schaller <hns@goldelico.com>
+
+description: |
+ The HDMI Transmitter in the Ingenic JZ4780 is a Synopsys DesignWare HDMI 1.4
+ TX controller IP with accompanying PHY IP.
+
+allOf:
+ - $ref: synopsys,dw-hdmi.yaml#
+
+properties:
+ compatible:
+ const: ingenic,jz4780-dw-hdmi
+
+ reg-io-width:
+ const: 4
+
+ clocks:
+ maxItems: 2
+
+ ports:
+ $ref: /schemas/graph.yaml#/properties/ports
+
+ properties:
+ port@0:
+ $ref: /schemas/graph.yaml#/properties/port
+ description: Input from LCD controller output.
+
+ port@1:
+ $ref: /schemas/graph.yaml#/properties/port
+ description: Link to the HDMI connector.
+
+required:
+ - compatible
+ - clocks
+ - clock-names
+ - ports
+ - reg-io-width
+
+unevaluatedProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/clock/ingenic,jz4780-cgu.h>
+
+ hdmi: hdmi@10180000 {
+ compatible = "ingenic,jz4780-dw-hdmi";
+ reg = <0x10180000 0x8000>;
+ reg-io-width = <4>;
+ ddc-i2c-bus = <&i2c4>;
+ interrupt-parent = <&intc>;
+ interrupts = <3>;
+ clocks = <&cgu JZ4780_CLK_AHB0>, <&cgu JZ4780_CLK_HDMI>;
+ clock-names = "iahb", "isfr";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ hdmi_in: port@0 {
+ reg = <0>;
+ dw_hdmi_in: endpoint {
+ remote-endpoint = <&jz4780_lcd_out>;
+ };
+ };
+ hdmi_out: port@1 {
+ reg = <1>;
+ dw_hdmi_out: endpoint {
+ remote-endpoint = <&hdmi_con>;
+ };
+ };
+ };
+ };
+
+...
diff --git a/Documentation/devicetree/bindings/display/bridge/lvds-codec.yaml b/Documentation/devicetree/bindings/display/bridge/lvds-codec.yaml
index 5079c1cc337b..3a8614e0f627 100644
--- a/Documentation/devicetree/bindings/display/bridge/lvds-codec.yaml
+++ b/Documentation/devicetree/bindings/display/bridge/lvds-codec.yaml
@@ -39,6 +39,7 @@ properties:
- const: lvds-encoder # Generic LVDS encoder compatible fallback
- items:
- enum:
+ - ti,ds90cf364a # For the DS90CF364A FPD-Link LVDS Receiver
- ti,ds90cf384a # For the DS90CF384A FPD-Link LVDS Receiver
- const: lvds-decoder # Generic LVDS decoders compatible fallback
- enum:
@@ -67,7 +68,7 @@ properties:
- vesa-24
description: |
The color signals mapping order. See details in
- Documentation/devicetree/bindings/display/panel/lvds.yaml
+ Documentation/devicetree/bindings/display/lvds.yaml
port@1:
$ref: /schemas/graph.yaml#/properties/port
diff --git a/Documentation/devicetree/bindings/display/bridge/renesas,lvds.yaml b/Documentation/devicetree/bindings/display/bridge/renesas,lvds.yaml
index acfc327f70a7..a51baf8a4c76 100644
--- a/Documentation/devicetree/bindings/display/bridge/renesas,lvds.yaml
+++ b/Documentation/devicetree/bindings/display/bridge/renesas,lvds.yaml
@@ -28,6 +28,7 @@ properties:
- renesas,r8a7793-lvds # for R-Car M2-N compatible LVDS encoders
- renesas,r8a7795-lvds # for R-Car H3 compatible LVDS encoders
- renesas,r8a7796-lvds # for R-Car M3-W compatible LVDS encoders
+ - renesas,r8a77961-lvds # for R-Car M3-W+ compatible LVDS encoders
- renesas,r8a77965-lvds # for R-Car M3-N compatible LVDS encoders
- renesas,r8a77970-lvds # for R-Car V3M compatible LVDS encoders
- renesas,r8a77980-lvds # for R-Car V3H compatible LVDS encoders
diff --git a/Documentation/devicetree/bindings/display/bridge/ti,sn65dsi83.yaml b/Documentation/devicetree/bindings/display/bridge/ti,sn65dsi83.yaml
index b446d0f0f1b4..48a97bb3e2e0 100644
--- a/Documentation/devicetree/bindings/display/bridge/ti,sn65dsi83.yaml
+++ b/Documentation/devicetree/bindings/display/bridge/ti,sn65dsi83.yaml
@@ -32,6 +32,9 @@ properties:
maxItems: 1
description: GPIO specifier for bridge_en pin (active high).
+ vcc-supply:
+ description: A 1.8V power supply (see regulator/regulator.yaml).
+
ports:
$ref: /schemas/graph.yaml#/properties/ports
@@ -91,7 +94,6 @@ properties:
required:
- compatible
- reg
- - enable-gpios
- ports
allOf:
@@ -133,6 +135,7 @@ examples:
reg = <0x2d>;
enable-gpios = <&gpio2 1 GPIO_ACTIVE_HIGH>;
+ vcc-supply = <&reg_sn65dsi83_1v8>;
ports {
#address-cells = <1>;
diff --git a/Documentation/devicetree/bindings/display/panel/lvds.yaml b/Documentation/devicetree/bindings/display/lvds.yaml
index 49460c9dceea..7cd2ce7e9c33 100644
--- a/Documentation/devicetree/bindings/display/panel/lvds.yaml
+++ b/Documentation/devicetree/bindings/display/lvds.yaml
@@ -1,10 +1,10 @@
# SPDX-License-Identifier: GPL-2.0
%YAML 1.2
---
-$id: http://devicetree.org/schemas/display/panel/lvds.yaml#
+$id: http://devicetree.org/schemas/display/lvds.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
-title: LVDS Display Panel
+title: LVDS Display Common Properties
maintainers:
- Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
@@ -13,8 +13,8 @@ maintainers:
description: |+
LVDS is a physical layer specification defined in ANSI/TIA/EIA-644-A. Multiple
incompatible data link layers have been used over time to transmit image data
- to LVDS panels. This bindings supports display panels compatible with the
- following specifications.
+ to LVDS devices. This bindings supports devices compatible with the following
+ specifications.
[JEIDA] "Digital Interface Standards for Monitor", JEIDA-59-1999, February
1999 (Version 1.0), Japan Electronic Industry Development Association (JEIDA)
@@ -26,18 +26,7 @@ description: |+
Device compatible with those specifications have been marketed under the
FPD-Link and FlatLink brands.
-allOf:
- - $ref: panel-common.yaml#
-
properties:
- compatible:
- contains:
- const: panel-lvds
- description:
- Shall contain "panel-lvds" in addition to a mandatory panel-specific
- compatible string defined in individual panel bindings. The "panel-lvds"
- value shall never be used on its own.
-
data-mapping:
enum:
- jeida-18
@@ -96,22 +85,6 @@ properties:
If set, reverse the bit order described in the data mappings below on all
data lanes, transmitting bits for slots 6 to 0 instead of 0 to 6.
- port: true
- ports: true
-
-required:
- - compatible
- - data-mapping
- - width-mm
- - height-mm
- - panel-timing
-
-oneOf:
- - required:
- - port
- - required:
- - ports
-
additionalProperties: true
...
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,aal.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,aal.yaml
new file mode 100644
index 000000000000..225f9dd726d2
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,aal.yaml
@@ -0,0 +1,77 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/mediatek/mediatek,aal.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Mediatek display adaptive ambient light processor
+
+maintainers:
+ - Chun-Kuang Hu <chunkuang.hu@kernel.org>
+ - Philipp Zabel <p.zabel@pengutronix.de>
+
+description: |
+ Mediatek display adaptive ambient light processor, namely AAL,
+ is responsible for backlight power saving and sunlight visibility improving.
+ AAL device node must be siblings to the central MMSYS_CONFIG node.
+ For a description of the MMSYS_CONFIG binding, see
+ Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml
+ for details.
+
+properties:
+ compatible:
+ oneOf:
+ - items:
+ - const: mediatek,mt8173-disp-aal
+ - items:
+ - enum:
+ - mediatek,mt2712-disp-aal
+ - mediatek,mt8183-disp-aal
+ - mediatek,mt8192-disp-aal
+ - mediatek,mt8195-disp-aal
+ - enum:
+ - mediatek,mt8173-disp-aal
+
+ reg:
+ maxItems: 1
+
+ interrupts:
+ maxItems: 1
+
+ power-domains:
+ description: A phandle and PM domain specifier as defined by bindings of
+ the power controller specified by phandle. See
+ Documentation/devicetree/bindings/power/power-domain.yaml for details.
+
+ clocks:
+ items:
+ - description: AAL Clock
+
+ mediatek,gce-client-reg:
+ description: The register of client driver can be configured by gce with
+ 4 arguments defined in this property, such as phandle of gce, subsys id,
+ register offset and size. Each GCE subsys id is mapping to a client
+ defined in the header include/dt-bindings/gce/<chip>-gce.h.
+ $ref: /schemas/types.yaml#/definitions/phandle-array
+ maxItems: 1
+
+required:
+ - compatible
+ - reg
+ - interrupts
+ - power-domains
+ - clocks
+
+additionalProperties: false
+
+examples:
+ - |
+
+ aal@14015000 {
+ compatible = "mediatek,mt8173-disp-aal";
+ reg = <0 0x14015000 0 0x1000>;
+ interrupts = <GIC_SPI 189 IRQ_TYPE_LEVEL_LOW>;
+ power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
+ clocks = <&mmsys CLK_MM_DISP_AAL>;
+ mediatek,gce-client-reg = <&gce SUBSYS_1401XXXX 0x5000 0x1000>;
+ };
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,ccorr.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,ccorr.yaml
new file mode 100644
index 000000000000..6894b6999412
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,ccorr.yaml
@@ -0,0 +1,76 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/mediatek/mediatek,ccorr.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Mediatek display color correction
+
+maintainers:
+ - Chun-Kuang Hu <chunkuang.hu@kernel.org>
+ - Philipp Zabel <p.zabel@pengutronix.de>
+
+description: |
+ Mediatek display color correction, namely CCORR, reproduces correct color
+ on panels with different color gamut.
+ CCORR device node must be siblings to the central MMSYS_CONFIG node.
+ For a description of the MMSYS_CONFIG binding, see
+ Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml
+ for details.
+
+properties:
+ compatible:
+ oneOf:
+ - items:
+ - const: mediatek,mt8183-disp-ccorr
+ - items:
+ - const: mediatek,mt8192-disp-ccorr
+ - items:
+ - enum:
+ - mediatek,mt8195-disp-ccorr
+ - enum:
+ - mediatek,mt8192-disp-ccorr
+
+ reg:
+ maxItems: 1
+
+ interrupts:
+ maxItems: 1
+
+ power-domains:
+ description: A phandle and PM domain specifier as defined by bindings of
+ the power controller specified by phandle. See
+ Documentation/devicetree/bindings/power/power-domain.yaml for details.
+
+ clocks:
+ items:
+ - description: CCORR Clock
+
+ mediatek,gce-client-reg:
+ description: The register of client driver can be configured by gce with
+ 4 arguments defined in this property, such as phandle of gce, subsys id,
+ register offset and size. Each GCE subsys id is mapping to a client
+ defined in the header include/dt-bindings/gce/<chip>-gce.h.
+ $ref: /schemas/types.yaml#/definitions/phandle-array
+ maxItems: 1
+
+required:
+ - compatible
+ - reg
+ - interrupts
+ - power-domains
+ - clocks
+
+additionalProperties: false
+
+examples:
+ - |
+
+ ccorr0: ccorr@1400f000 {
+ compatible = "mediatek,mt8183-disp-ccorr";
+ reg = <0 0x1400f000 0 0x1000>;
+ interrupts = <GIC_SPI 232 IRQ_TYPE_LEVEL_LOW>;
+ power-domains = <&spm MT8183_POWER_DOMAIN_DISP>;
+ clocks = <&mmsys CLK_MM_DISP_CCORR0>;
+ mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0xf000 0x1000>;
+ };
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,color.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,color.yaml
new file mode 100644
index 000000000000..bc83155b3b4c
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,color.yaml
@@ -0,0 +1,86 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/mediatek/mediatek,color.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Mediatek display color processor
+
+maintainers:
+ - Chun-Kuang Hu <chunkuang.hu@kernel.org>
+ - Philipp Zabel <p.zabel@pengutronix.de>
+
+description: |
+ Mediatek display color processor, namely COLOR, provides hue, luma and
+ saturation adjustments to get better picture quality and to have one panel
+ resemble the other in their output characteristics.
+ COLOR device node must be siblings to the central MMSYS_CONFIG node.
+ For a description of the MMSYS_CONFIG binding, see
+ Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml
+ for details.
+
+properties:
+ compatible:
+ oneOf:
+ - items:
+ - const: mediatek,mt2701-disp-color
+ - items:
+ - const: mediatek,mt8167-disp-color
+ - items:
+ - const: mediatek,mt8173-disp-color
+ - items:
+ - enum:
+ - mediatek,mt7623-disp-color
+ - mediatek,mt2712-disp-color
+ - enum:
+ - mediatek,mt2701-disp-color
+ - items:
+ - enum:
+ - mediatek,mt8183-disp-color
+ - mediatek,mt8192-disp-color
+ - mediatek,mt8195-disp-color
+ - enum:
+ - mediatek,mt8173-disp-color
+ reg:
+ maxItems: 1
+
+ interrupts:
+ maxItems: 1
+
+ power-domains:
+ description: A phandle and PM domain specifier as defined by bindings of
+ the power controller specified by phandle. See
+ Documentation/devicetree/bindings/power/power-domain.yaml for details.
+
+ clocks:
+ items:
+ - description: COLOR Clock
+
+ mediatek,gce-client-reg:
+ description: The register of client driver can be configured by gce with
+ 4 arguments defined in this property, such as phandle of gce, subsys id,
+ register offset and size. Each GCE subsys id is mapping to a client
+ defined in the header include/dt-bindings/gce/<chip>-gce.h.
+ $ref: /schemas/types.yaml#/definitions/phandle-array
+ maxItems: 1
+
+required:
+ - compatible
+ - reg
+ - interrupts
+ - power-domains
+ - clocks
+
+additionalProperties: false
+
+examples:
+ - |
+
+ color0: color@14013000 {
+ compatible = "mediatek,mt8173-disp-color";
+ reg = <0 0x14013000 0 0x1000>;
+ interrupts = <GIC_SPI 187 IRQ_TYPE_LEVEL_LOW>;
+ power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
+ clocks = <&mmsys CLK_MM_DISP_COLOR0>;
+ mediatek,gce-client-reg = <&gce SUBSYS_1401XXXX 0x3000 0x1000>;
+ };
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,disp.txt b/Documentation/devicetree/bindings/display/mediatek/mediatek,disp.txt
deleted file mode 100644
index 78044c340e20..000000000000
--- a/Documentation/devicetree/bindings/display/mediatek/mediatek,disp.txt
+++ /dev/null
@@ -1,219 +0,0 @@
-Mediatek display subsystem
-==========================
-
-The Mediatek display subsystem consists of various DISP function blocks in the
-MMSYS register space. The connections between them can be configured by output
-and input selectors in the MMSYS_CONFIG register space. Pixel clock and start
-of frame signal are distributed to the other function blocks by a DISP_MUTEX
-function block.
-
-All DISP device tree nodes must be siblings to the central MMSYS_CONFIG node.
-For a description of the MMSYS_CONFIG binding, see
-Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml.
-
-DISP function blocks
-====================
-
-A display stream starts at a source function block that reads pixel data from
-memory and ends with a sink function block that drives pixels on a display
-interface, or writes pixels back to memory. All DISP function blocks have
-their own register space, interrupt, and clock gate. The blocks that can
-access memory additionally have to list the IOMMU and local arbiter they are
-connected to.
-
-For a description of the display interface sink function blocks, see
-Documentation/devicetree/bindings/display/mediatek/mediatek,dsi.txt and
-Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.yaml.
-
-Required properties (all function blocks):
-- compatible: "mediatek,<chip>-disp-<function>", one of
- "mediatek,<chip>-disp-ovl" - overlay (4 layers, blending, csc)
- "mediatek,<chip>-disp-ovl-2l" - overlay (2 layers, blending, csc)
- "mediatek,<chip>-disp-rdma" - read DMA / line buffer
- "mediatek,<chip>-disp-wdma" - write DMA
- "mediatek,<chip>-disp-ccorr" - color correction
- "mediatek,<chip>-disp-color" - color processor
- "mediatek,<chip>-disp-dither" - dither
- "mediatek,<chip>-disp-aal" - adaptive ambient light controller
- "mediatek,<chip>-disp-gamma" - gamma correction
- "mediatek,<chip>-disp-merge" - merge streams from two RDMA sources
- "mediatek,<chip>-disp-postmask" - control round corner for display frame
- "mediatek,<chip>-disp-split" - split stream to two encoders
- "mediatek,<chip>-disp-ufoe" - data compression engine
- "mediatek,<chip>-dsi" - DSI controller, see mediatek,dsi.txt
- "mediatek,<chip>-dpi" - DPI controller, see mediatek,dpi.txt
- "mediatek,<chip>-disp-mutex" - display mutex
- "mediatek,<chip>-disp-od" - overdrive
- the supported chips are mt2701, mt7623, mt2712, mt8167, mt8173, mt8183 and mt8192.
-- reg: Physical base address and length of the function block register space
-- interrupts: The interrupt signal from the function block (required, except for
- merge and split function blocks).
-- clocks: device clocks
- See Documentation/devicetree/bindings/clock/clock-bindings.txt for details.
- For most function blocks this is just a single clock input. Only the DSI and
- DPI controller nodes have multiple clock inputs. These are documented in
- mediatek,dsi.txt and mediatek,dpi.txt, respectively.
- An exception is that the mt8183 mutex is always free running with no clocks property.
-
-Required properties (DMA function blocks):
-- compatible: Should be one of
- "mediatek,<chip>-disp-ovl"
- "mediatek,<chip>-disp-rdma"
- "mediatek,<chip>-disp-wdma"
- the supported chips are mt2701, mt8167 and mt8173.
-- larb: Should contain a phandle pointing to the local arbiter device as defined
- in Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.yaml
-- iommus: Should point to the respective IOMMU block with master port as
- argument, see Documentation/devicetree/bindings/iommu/mediatek,iommu.yaml
- for details.
-
-Optional properties (RDMA function blocks):
-- mediatek,rdma-fifo-size: rdma fifo size may be different even in same SOC, add this
- property to the corresponding rdma
- the value is the Max value which defined in hardware data sheet.
- mediatek,rdma-fifo-size of mt8173-rdma0 is 8K
- mediatek,rdma-fifo-size of mt8183-rdma0 is 5K
- mediatek,rdma-fifo-size of mt8183-rdma1 is 2K
-
-Examples:
-
-mmsys: clock-controller@14000000 {
- compatible = "mediatek,mt8173-mmsys", "syscon";
- reg = <0 0x14000000 0 0x1000>;
- power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
- #clock-cells = <1>;
-};
-
-ovl0: ovl@1400c000 {
- compatible = "mediatek,mt8173-disp-ovl";
- reg = <0 0x1400c000 0 0x1000>;
- interrupts = <GIC_SPI 180 IRQ_TYPE_LEVEL_LOW>;
- power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
- clocks = <&mmsys CLK_MM_DISP_OVL0>;
- iommus = <&iommu M4U_PORT_DISP_OVL0>;
- mediatek,larb = <&larb0>;
-};
-
-ovl1: ovl@1400d000 {
- compatible = "mediatek,mt8173-disp-ovl";
- reg = <0 0x1400d000 0 0x1000>;
- interrupts = <GIC_SPI 181 IRQ_TYPE_LEVEL_LOW>;
- power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
- clocks = <&mmsys CLK_MM_DISP_OVL1>;
- iommus = <&iommu M4U_PORT_DISP_OVL1>;
- mediatek,larb = <&larb4>;
-};
-
-rdma0: rdma@1400e000 {
- compatible = "mediatek,mt8173-disp-rdma";
- reg = <0 0x1400e000 0 0x1000>;
- interrupts = <GIC_SPI 182 IRQ_TYPE_LEVEL_LOW>;
- power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
- clocks = <&mmsys CLK_MM_DISP_RDMA0>;
- iommus = <&iommu M4U_PORT_DISP_RDMA0>;
- mediatek,larb = <&larb0>;
- mediatek,rdma-fifosize = <8192>;
-};
-
-rdma1: rdma@1400f000 {
- compatible = "mediatek,mt8173-disp-rdma";
- reg = <0 0x1400f000 0 0x1000>;
- interrupts = <GIC_SPI 183 IRQ_TYPE_LEVEL_LOW>;
- power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
- clocks = <&mmsys CLK_MM_DISP_RDMA1>;
- iommus = <&iommu M4U_PORT_DISP_RDMA1>;
- mediatek,larb = <&larb4>;
-};
-
-rdma2: rdma@14010000 {
- compatible = "mediatek,mt8173-disp-rdma";
- reg = <0 0x14010000 0 0x1000>;
- interrupts = <GIC_SPI 184 IRQ_TYPE_LEVEL_LOW>;
- power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
- clocks = <&mmsys CLK_MM_DISP_RDMA2>;
- iommus = <&iommu M4U_PORT_DISP_RDMA2>;
- mediatek,larb = <&larb4>;
-};
-
-wdma0: wdma@14011000 {
- compatible = "mediatek,mt8173-disp-wdma";
- reg = <0 0x14011000 0 0x1000>;
- interrupts = <GIC_SPI 185 IRQ_TYPE_LEVEL_LOW>;
- power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
- clocks = <&mmsys CLK_MM_DISP_WDMA0>;
- iommus = <&iommu M4U_PORT_DISP_WDMA0>;
- mediatek,larb = <&larb0>;
-};
-
-wdma1: wdma@14012000 {
- compatible = "mediatek,mt8173-disp-wdma";
- reg = <0 0x14012000 0 0x1000>;
- interrupts = <GIC_SPI 186 IRQ_TYPE_LEVEL_LOW>;
- power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
- clocks = <&mmsys CLK_MM_DISP_WDMA1>;
- iommus = <&iommu M4U_PORT_DISP_WDMA1>;
- mediatek,larb = <&larb4>;
-};
-
-color0: color@14013000 {
- compatible = "mediatek,mt8173-disp-color";
- reg = <0 0x14013000 0 0x1000>;
- interrupts = <GIC_SPI 187 IRQ_TYPE_LEVEL_LOW>;
- power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
- clocks = <&mmsys CLK_MM_DISP_COLOR0>;
-};
-
-color1: color@14014000 {
- compatible = "mediatek,mt8173-disp-color";
- reg = <0 0x14014000 0 0x1000>;
- interrupts = <GIC_SPI 188 IRQ_TYPE_LEVEL_LOW>;
- power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
- clocks = <&mmsys CLK_MM_DISP_COLOR1>;
-};
-
-aal@14015000 {
- compatible = "mediatek,mt8173-disp-aal";
- reg = <0 0x14015000 0 0x1000>;
- interrupts = <GIC_SPI 189 IRQ_TYPE_LEVEL_LOW>;
- power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
- clocks = <&mmsys CLK_MM_DISP_AAL>;
-};
-
-gamma@14016000 {
- compatible = "mediatek,mt8173-disp-gamma";
- reg = <0 0x14016000 0 0x1000>;
- interrupts = <GIC_SPI 190 IRQ_TYPE_LEVEL_LOW>;
- power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
- clocks = <&mmsys CLK_MM_DISP_GAMMA>;
-};
-
-ufoe@1401a000 {
- compatible = "mediatek,mt8173-disp-ufoe";
- reg = <0 0x1401a000 0 0x1000>;
- interrupts = <GIC_SPI 191 IRQ_TYPE_LEVEL_LOW>;
- power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
- clocks = <&mmsys CLK_MM_DISP_UFOE>;
-};
-
-dsi0: dsi@1401b000 {
- /* See mediatek,dsi.txt for details */
-};
-
-dpi0: dpi@1401d000 {
- /* See mediatek,dpi.txt for details */
-};
-
-mutex: mutex@14020000 {
- compatible = "mediatek,mt8173-disp-mutex";
- reg = <0 0x14020000 0 0x1000>;
- interrupts = <GIC_SPI 169 IRQ_TYPE_LEVEL_LOW>;
- power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
- clocks = <&mmsys CLK_MM_MUTEX_32K>;
-};
-
-od@14023000 {
- compatible = "mediatek,mt8173-disp-od";
- reg = <0 0x14023000 0 0x1000>;
- power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
- clocks = <&mmsys CLK_MM_DISP_OD>;
-};
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,dither.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,dither.yaml
new file mode 100644
index 000000000000..9d89297f5f1d
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,dither.yaml
@@ -0,0 +1,76 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/mediatek/mediatek,dither.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Mediatek display dither processor
+
+maintainers:
+ - Chun-Kuang Hu <chunkuang.hu@kernel.org>
+ - Philipp Zabel <p.zabel@pengutronix.de>
+
+description: |
+ Mediatek display dither processor, namely DITHER, works by approximating
+ unavailable colors with available colors and by mixing and matching available
+ colors to mimic unavailable ones.
+ DITHER device node must be siblings to the central MMSYS_CONFIG node.
+ For a description of the MMSYS_CONFIG binding, see
+ Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml
+ for details.
+
+properties:
+ compatible:
+ oneOf:
+ - items:
+ - const: mediatek,mt8183-disp-dither
+ - items:
+ - enum:
+ - mediatek,mt8192-disp-dither
+ - mediatek,mt8195-disp-dither
+ - enum:
+ - mediatek,mt8183-disp-dither
+
+ reg:
+ maxItems: 1
+
+ interrupts:
+ maxItems: 1
+
+ power-domains:
+ description: A phandle and PM domain specifier as defined by bindings of
+ the power controller specified by phandle. See
+ Documentation/devicetree/bindings/power/power-domain.yaml for details.
+
+ clocks:
+ items:
+ - description: DITHER Clock
+
+ mediatek,gce-client-reg:
+ description: The register of client driver can be configured by gce with
+ 4 arguments defined in this property, such as phandle of gce, subsys id,
+ register offset and size. Each GCE subsys id is mapping to a client
+ defined in the header include/dt-bindings/gce/<chip>-gce.h.
+ $ref: /schemas/types.yaml#/definitions/phandle-array
+ maxItems: 1
+
+required:
+ - compatible
+ - reg
+ - interrupts
+ - power-domains
+ - clocks
+
+additionalProperties: false
+
+examples:
+ - |
+
+ dither0: dither@14012000 {
+ compatible = "mediatek,mt8183-disp-dither";
+ reg = <0 0x14012000 0 0x1000>;
+ interrupts = <GIC_SPI 235 IRQ_TYPE_LEVEL_LOW>;
+ power-domains = <&spm MT8183_POWER_DOMAIN_DISP>;
+ clocks = <&mmsys CLK_MM_DISP_DITHER0>;
+ mediatek,gce-client-reg = <&gce SUBSYS_1401XXXX 0x2000 0x1000>;
+ };
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,dsc.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,dsc.yaml
new file mode 100644
index 000000000000..1ec083eff824
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,dsc.yaml
@@ -0,0 +1,71 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/mediatek/mediatek,dsc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: mediatek display DSC controller
+
+maintainers:
+ - Chun-Kuang Hu <chunkuang.hu@kernel.org>
+ - Philipp Zabel <p.zabel@pengutronix.de>
+
+description: |
+ The DSC standard is a specification of the algorithms used for
+ compressing and decompressing image display streams, including
+ the specification of the syntax and semantics of the compressed
+ video bit stream. DSC is designed for real-time systems with
+ real-time compression, transmission, decompression and Display.
+
+properties:
+ compatible:
+ oneOf:
+ - items:
+ - const: mediatek,mt8195-disp-dsc
+
+ reg:
+ maxItems: 1
+
+ interrupts:
+ maxItems: 1
+
+ clocks:
+ items:
+ - description: DSC Wrapper Clock
+
+ power-domains:
+ description: A phandle and PM domain specifier as defined by bindings of
+ the power controller specified by phandle. See
+ Documentation/devicetree/bindings/power/power-domain.yaml for details.
+
+ mediatek,gce-client-reg:
+ description:
+ The register of client driver can be configured by gce with 4 arguments
+ defined in this property, such as phandle of gce, subsys id,
+ register offset and size.
+ Each subsys id is mapping to a base address of display function blocks
+ register which is defined in the gce header
+ include/dt-bindings/gce/<chip>-gce.h.
+ $ref: /schemas/types.yaml#/definitions/phandle-array
+ maxItems: 1
+
+required:
+ - compatible
+ - reg
+ - interrupts
+ - power-domains
+ - clocks
+
+additionalProperties: false
+
+examples:
+ - |
+
+ dsc0: disp_dsc_wrap@1c009000 {
+ compatible = "mediatek,mt8195-disp-dsc";
+ reg = <0 0x1c009000 0 0x1000>;
+ interrupts = <GIC_SPI 645 IRQ_TYPE_LEVEL_HIGH 0>;
+ power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS0>;
+ clocks = <&vdosys0 CLK_VDO0_DSC_WRAP0>;
+ mediatek,gce-client-reg = <&gce1 SUBSYS_1c00XXXX 0x9000 0x1000>;
+ };
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,ethdr.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,ethdr.yaml
new file mode 100644
index 000000000000..131eed5eeeb7
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,ethdr.yaml
@@ -0,0 +1,147 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/mediatek/mediatek,ethdr.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Mediatek Ethdr Device Tree Bindings
+
+maintainers:
+ - Chun-Kuang Hu <chunkuang.hu@kernel.org>
+ - Philipp Zabel <p.zabel@pengutronix.de>
+
+description: |
+ ETHDR is designed for HDR video and graphics conversion in the external display path.
+ It handles multiple HDR input types and performs tone mapping, color space/color
+ format conversion, and then combine different layers, output the required HDR or
+ SDR signal to the subsequent display path. This engine is composed of two video
+ frontends, two graphic frontends, one video backend and a mixer. ETHDR has two
+ DMA function blocks, DS and ADL. These two function blocks read the pre-programmed
+ registers from DRAM and set them to HW in the v-blanking period.
+
+properties:
+ compatible:
+ items:
+ - const: mediatek,mt8195-disp-ethdr
+ reg:
+ maxItems: 7
+ reg-names:
+ items:
+ - const: mixer
+ - const: vdo_fe0
+ - const: vdo_fe1
+ - const: gfx_fe0
+ - const: gfx_fe1
+ - const: vdo_be
+ - const: adl_ds
+ interrupts:
+ minItems: 1
+ iommus:
+ description: The compatible property is DMA function blocks.
+ Should point to the respective IOMMU block with master port as argument,
+ see Documentation/devicetree/bindings/iommu/mediatek,iommu.yaml for
+ details.
+ minItems: 1
+ maxItems: 2
+ clocks:
+ items:
+ - description: mixer clock
+ - description: video frontend 0 clock
+ - description: video frontend 1 clock
+ - description: graphic frontend 0 clock
+ - description: graphic frontend 1 clock
+ - description: video backend clock
+ - description: autodownload and menuload clock
+ - description: video frontend 0 async clock
+ - description: video frontend 1 async clock
+ - description: graphic frontend 0 async clock
+ - description: graphic frontend 1 async clock
+ - description: video backend async clock
+ - description: ethdr top clock
+ clock-names:
+ items:
+ - const: mixer
+ - const: vdo_fe0
+ - const: vdo_fe1
+ - const: gfx_fe0
+ - const: gfx_fe1
+ - const: vdo_be
+ - const: adl_ds
+ - const: vdo_fe0_async
+ - const: vdo_fe1_async
+ - const: gfx_fe0_async
+ - const: gfx_fe1_async
+ - const: vdo_be_async
+ - const: ethdr_top
+ power-domains:
+ maxItems: 1
+ resets:
+ maxItems: 5
+ mediatek,gce-client-reg:
+ $ref: /schemas/types.yaml#/definitions/phandle-array
+ description: The register of display function block to be set by gce.
+ There are 4 arguments in this property, gce node, subsys id, offset and
+ register size. The subsys id is defined in the gce header of each chips
+ include/include/dt-bindings/gce/<chip>-gce.h, mapping to the register of
+ display function block.
+
+required:
+ - compatible
+ - reg
+ - clocks
+ - clock-names
+ - interrupts
+ - power-domains
+
+additionalProperties: false
+
+examples:
+ - |
+
+ disp_ethdr@1c114000 {
+ compatible = "mediatek,mt8195-disp-ethdr";
+ reg = <0 0x1c114000 0 0x1000>,
+ <0 0x1c115000 0 0x1000>,
+ <0 0x1c117000 0 0x1000>,
+ <0 0x1c119000 0 0x1000>,
+ <0 0x1c11A000 0 0x1000>,
+ <0 0x1c11B000 0 0x1000>,
+ <0 0x1c11C000 0 0x1000>;
+ reg-names = "mixer", "vdo_fe0", "vdo_fe1", "gfx_fe0", "gfx_fe1",
+ "vdo_be", "adl_ds";
+ mediatek,gce-client-reg = <&gce0 SUBSYS_1c11XXXX 0x4000 0x1000>,
+ <&gce0 SUBSYS_1c11XXXX 0x5000 0x1000>,
+ <&gce0 SUBSYS_1c11XXXX 0x7000 0x1000>,
+ <&gce0 SUBSYS_1c11XXXX 0x9000 0x1000>,
+ <&gce0 SUBSYS_1c11XXXX 0xA000 0x1000>,
+ <&gce0 SUBSYS_1c11XXXX 0xB000 0x1000>,
+ <&gce0 SUBSYS_1c11XXXX 0xC000 0x1000>;
+ clocks = <&vdosys1 CLK_VDO1_DISP_MIXER>,
+ <&vdosys1 CLK_VDO1_HDR_VDO_FE0>,
+ <&vdosys1 CLK_VDO1_HDR_VDO_FE1>,
+ <&vdosys1 CLK_VDO1_HDR_GFX_FE0>,
+ <&vdosys1 CLK_VDO1_HDR_GFX_FE1>,
+ <&vdosys1 CLK_VDO1_HDR_VDO_BE>,
+ <&vdosys1 CLK_VDO1_26M_SLOW>,
+ <&vdosys1 CLK_VDO1_HDR_VDO_FE0_DL_ASYNC>,
+ <&vdosys1 CLK_VDO1_HDR_VDO_FE1_DL_ASYNC>,
+ <&vdosys1 CLK_VDO1_HDR_GFX_FE0_DL_ASYNC>,
+ <&vdosys1 CLK_VDO1_HDR_GFX_FE1_DL_ASYNC>,
+ <&vdosys1 CLK_VDO1_HDR_VDO_BE_DL_ASYNC>,
+ <&topckgen CLK_TOP_ETHDR_SEL>;
+ clock-names = "mixer", "vdo_fe0", "vdo_fe1", "gfx_fe0", "gfx_fe1",
+ "vdo_be", "adl_ds", "vdo_fe0_async", "vdo_fe1_async",
+ "gfx_fe0_async", "gfx_fe1_async","vdo_be_async",
+ "ethdr_top";
+ power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS1>;
+ iommus = <&iommu_vpp M4U_PORT_L3_HDR_DS>,
+ <&iommu_vpp M4U_PORT_L3_HDR_ADL>;
+ interrupts = <GIC_SPI 517 IRQ_TYPE_LEVEL_HIGH 0>; /* disp mixer */
+ resets = <&vdosys1 MT8195_VDOSYS1_SW1_RST_B_HDR_VDO_FE0_DL_ASYNC>,
+ <&vdosys1 MT8195_VDOSYS1_SW1_RST_B_HDR_VDO_FE1_DL_ASYNC>,
+ <&vdosys1 MT8195_VDOSYS1_SW1_RST_B_HDR_GFX_FE0_DL_ASYNC>,
+ <&vdosys1 MT8195_VDOSYS1_SW1_RST_B_HDR_GFX_FE1_DL_ASYNC>,
+ <&vdosys1 MT8195_VDOSYS1_SW1_RST_B_HDR_VDO_BE_DL_ASYNC>;
+ };
+
+...
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,gamma.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,gamma.yaml
new file mode 100644
index 000000000000..247baad147b3
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,gamma.yaml
@@ -0,0 +1,77 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/mediatek/mediatek,gamma.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Mediatek display gamma correction
+
+maintainers:
+ - Chun-Kuang Hu <chunkuang.hu@kernel.org>
+ - Philipp Zabel <p.zabel@pengutronix.de>
+
+description: |
+ Mediatek display gamma correction, namely GAMMA, provides a nonlinear
+ operation used to adjust luminance in display system.
+ GAMMA device node must be siblings to the central MMSYS_CONFIG node.
+ For a description of the MMSYS_CONFIG binding, see
+ Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml
+ for details.
+
+properties:
+ compatible:
+ oneOf:
+ - items:
+ - const: mediatek,mt8173-disp-gamma
+ - items:
+ - const: mediatek,mt8183-disp-gamma
+ - items:
+ - enum:
+ - mediatek,mt8192-disp-gamma
+ - mediatek,mt8195-disp-gamma
+ - enum:
+ - mediatek,mt8183-disp-gamma
+
+ reg:
+ maxItems: 1
+
+ interrupts:
+ maxItems: 1
+
+ power-domains:
+ description: A phandle and PM domain specifier as defined by bindings of
+ the power controller specified by phandle. See
+ Documentation/devicetree/bindings/power/power-domain.yaml for details.
+
+ clocks:
+ items:
+ - description: GAMMA Clock
+
+ mediatek,gce-client-reg:
+ description: The register of client driver can be configured by gce with
+ 4 arguments defined in this property, such as phandle of gce, subsys id,
+ register offset and size. Each GCE subsys id is mapping to a client
+ defined in the header include/dt-bindings/gce/<chip>-gce.h.
+ $ref: /schemas/types.yaml#/definitions/phandle-array
+ maxItems: 1
+
+required:
+ - compatible
+ - reg
+ - interrupts
+ - power-domains
+ - clocks
+
+additionalProperties: false
+
+examples:
+ - |
+
+ gamma@14016000 {
+ compatible = "mediatek,mt8173-disp-gamma";
+ reg = <0 0x14016000 0 0x1000>;
+ interrupts = <GIC_SPI 190 IRQ_TYPE_LEVEL_LOW>;
+ power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
+ clocks = <&mmsys CLK_MM_DISP_GAMMA>;
+ mediatek,gce-client-reg = <&gce SUBSYS_1401XXXX 0x6000 0x1000>;
+ };
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,merge.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,merge.yaml
new file mode 100644
index 000000000000..d5cd69b7f501
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,merge.yaml
@@ -0,0 +1,110 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/mediatek/mediatek,merge.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Mediatek display merge
+
+maintainers:
+ - Chun-Kuang Hu <chunkuang.hu@kernel.org>
+ - Philipp Zabel <p.zabel@pengutronix.de>
+
+description: |
+ Mediatek display merge, namely MERGE, is used to merge two slice-per-line
+ inputs into one side-by-side output.
+ MERGE device node must be siblings to the central MMSYS_CONFIG node.
+ For a description of the MMSYS_CONFIG binding, see
+ Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml
+ for details.
+
+properties:
+ compatible:
+ oneOf:
+ - items:
+ - const: mediatek,mt8173-disp-merge
+ - items:
+ - const: mediatek,mt8195-disp-merge
+
+ reg:
+ maxItems: 1
+
+ interrupts:
+ maxItems: 1
+
+ power-domains:
+ description: A phandle and PM domain specifier as defined by bindings of
+ the power controller specified by phandle. See
+ Documentation/devicetree/bindings/power/power-domain.yaml for details.
+
+ clocks:
+ maxItems: 2
+ items:
+ - description: MERGE Clock
+ - description: MERGE Async Clock
+ Controlling the synchronous process between MERGE and other display
+ function blocks cross clock domain.
+
+ clock-names:
+ maxItems: 2
+ items:
+ - const: merge
+ - const: merge_async
+
+ mediatek,merge-fifo-en:
+ description:
+ The setting of merge fifo is mainly provided for the display latency
+ buffer to ensure that the back-end panel display data will not be
+ underrun, a little more data is needed in the fifo.
+ According to the merge fifo settings, when the water level is detected
+ to be insufficient, it will trigger RDMA sending ultra and preulra
+ command to SMI to speed up the data rate.
+ type: boolean
+
+ mediatek,merge-mute:
+ description: Support mute function. Mute the content of merge output.
+ type: boolean
+
+ mediatek,gce-client-reg:
+ description: The register of client driver can be configured by gce with
+ 4 arguments defined in this property, such as phandle of gce, subsys id,
+ register offset and size. Each GCE subsys id is mapping to a client
+ defined in the header include/dt-bindings/gce/<chip>-gce.h.
+ $ref: /schemas/types.yaml#/definitions/phandle-array
+ maxItems: 1
+
+ resets:
+ description: reset controller
+ See Documentation/devicetree/bindings/reset/reset.txt for details.
+ maxItems: 1
+
+required:
+ - compatible
+ - reg
+ - power-domains
+ - clocks
+
+additionalProperties: false
+
+examples:
+ - |
+
+ merge@14017000 {
+ compatible = "mediatek,mt8173-disp-merge";
+ reg = <0 0x14017000 0 0x1000>;
+ power-domains = <&spm MT8173_POWER_DOMAIN_MM>;
+ clocks = <&mmsys CLK_MM_DISP_MERGE>;
+ };
+
+ merge5: disp_vpp_merge5@1c110000 {
+ compatible = "mediatek,mt8195-disp-merge";
+ reg = <0 0x1c110000 0 0x1000>;
+ interrupts = <GIC_SPI 507 IRQ_TYPE_LEVEL_HIGH 0>;
+ clocks = <&vdosys1 CLK_VDO1_VPP_MERGE4>,
+ <&vdosys1 CLK_VDO1_MERGE4_DL_ASYNC>;
+ clock-names = "merge","merge_async";
+ power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS1>;
+ mediatek,gce-client-reg = <&gce1 SUBSYS_1c11XXXX 0x0000 0x1000>;
+ mediatek,merge-fifo-en = <1>;
+ resets = <&vdosys1 MT8195_VDOSYS1_SW0_RST_B_MERGE4_DL_ASYNC>;
+ };
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,mutex.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,mutex.yaml
new file mode 100644
index 000000000000..6eca525eced0
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,mutex.yaml
@@ -0,0 +1,83 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/mediatek/mediatek,mutex.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Mediatek mutex
+
+maintainers:
+ - Chun-Kuang Hu <chunkuang.hu@kernel.org>
+ - Philipp Zabel <p.zabel@pengutronix.de>
+
+description: |
+ Mediatek mutex, namely MUTEX, is used to send the triggers signals called
+ Start Of Frame (SOF) / End Of Frame (EOF) to each sub-modules on the display
+ data path or MDP data path.
+ In some SoC, such as mt2701, MUTEX could be a hardware mutex which protects
+ the shadow register.
+ MUTEX device node must be siblings to the central MMSYS_CONFIG node.
+ For a description of the MMSYS_CONFIG binding, see
+ Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml
+ for details.
+
+properties:
+ compatible:
+ oneOf:
+ - items:
+ - const: mediatek,mt2701-disp-mutex
+ - items:
+ - const: mediatek,mt2712-disp-mutex
+ - items:
+ - const: mediatek,mt8167-disp-mutex
+ - items:
+ - const: mediatek,mt8173-disp-mutex
+ - items:
+ - const: mediatek,mt8183-disp-mutex
+ - items:
+ - const: mediatek,mt8192-disp-mutex
+ - items:
+ - const: mediatek,mt8195-disp-mutex
+ reg:
+ maxItems: 1
+
+ interrupts:
+ maxItems: 1
+
+ power-domains:
+ description: A phandle and PM domain specifier as defined by bindings of
+ the power controller specified by phandle. See
+ Documentation/devicetree/bindings/power/power-domain.yaml for details.
+
+ clocks:
+ items:
+ - description: MUTEX Clock
+
+ mediatek,gce-events:
+ description:
+ The event id which is mapping to the specific hardware event signal
+ to gce. The event id is defined in the gce header
+ include/dt-bindings/gce/<chip>-gce.h of each chips.
+ $ref: /schemas/types.yaml#/definitions/phandle-array
+
+required:
+ - compatible
+ - reg
+ - interrupts
+ - power-domains
+ - clocks
+
+additionalProperties: false
+
+examples:
+ - |
+
+ mutex: mutex@14020000 {
+ compatible = "mediatek,mt8173-disp-mutex";
+ reg = <0 0x14020000 0 0x1000>;
+ interrupts = <GIC_SPI 169 IRQ_TYPE_LEVEL_LOW>;
+ power-domains = <&spm MT8173_POWER_DOMAIN_MM>;
+ clocks = <&mmsys CLK_MM_MUTEX_32K>;
+ mediatek,gce-events = <CMDQ_EVENT_MUTEX0_STREAM_EOF>,
+ <CMDQ_EVENT_MUTEX1_STREAM_EOF>;
+ };
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,od.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,od.yaml
new file mode 100644
index 000000000000..7519db315217
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,od.yaml
@@ -0,0 +1,53 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/mediatek/mediatek,od.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Mediatek display overdirve
+
+maintainers:
+ - Chun-Kuang Hu <chunkuang.hu@kernel.org>
+ - Philipp Zabel <p.zabel@pengutronix.de>
+
+description: |
+ Mediatek display overdrive, namely OD, increases the transition values
+ of pixels between consecutive frames to make LCD rotate faster.
+ OD device node must be siblings to the central MMSYS_CONFIG node.
+ For a description of the MMSYS_CONFIG binding, see
+ Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml
+ for details.
+
+properties:
+ compatible:
+ oneOf:
+ - items:
+ - const: mediatek,mt2712-disp-od
+ - items:
+ - const: mediatek,mt8173-disp-od
+
+ reg:
+ maxItems: 1
+
+ interrupts:
+ maxItems: 1
+
+ clocks:
+ items:
+ - description: OD Clock
+
+required:
+ - compatible
+ - reg
+ - clocks
+
+additionalProperties: false
+
+examples:
+ - |
+
+ od@14023000 {
+ compatible = "mediatek,mt8173-disp-od";
+ reg = <0 0x14023000 0 0x1000>;
+ clocks = <&mmsys CLK_MM_DISP_OD>;
+ };
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,ovl-2l.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,ovl-2l.yaml
new file mode 100644
index 000000000000..e3cef99d0f98
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,ovl-2l.yaml
@@ -0,0 +1,78 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/mediatek/mediatek,ovl-2l.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Mediatek display overlay 2 layer
+
+maintainers:
+ - Chun-Kuang Hu <chunkuang.hu@kernel.org>
+ - Philipp Zabel <p.zabel@pengutronix.de>
+
+description: |
+ Mediatek display overlay 2 layer, namely OVL-2L, provides 2 more layer
+ for OVL.
+ OVL-2L device node must be siblings to the central MMSYS_CONFIG node.
+ For a description of the MMSYS_CONFIG binding, see
+ Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml
+ for details.
+
+properties:
+ compatible:
+ oneOf:
+ - items:
+ - const: mediatek,mt8183-disp-ovl-2l
+ - items:
+ - const: mediatek,mt8192-disp-ovl-2l
+
+ reg:
+ maxItems: 1
+
+ interrupts:
+ maxItems: 1
+
+ power-domains:
+ description: A phandle and PM domain specifier as defined by bindings of
+ the power controller specified by phandle. See
+ Documentation/devicetree/bindings/power/power-domain.yaml for details.
+
+ clocks:
+ items:
+ - description: OVL-2L Clock
+
+ iommus:
+ description:
+ This property should point to the respective IOMMU block with master port as argument,
+ see Documentation/devicetree/bindings/iommu/mediatek,iommu.yaml for details.
+
+ mediatek,gce-client-reg:
+ description: The register of client driver can be configured by gce with
+ 4 arguments defined in this property, such as phandle of gce, subsys id,
+ register offset and size. Each GCE subsys id is mapping to a client
+ defined in the header include/dt-bindings/gce/<chip>-gce.h.
+ $ref: /schemas/types.yaml#/definitions/phandle-array
+ maxItems: 1
+
+required:
+ - compatible
+ - reg
+ - interrupts
+ - power-domains
+ - clocks
+ - iommus
+
+additionalProperties: false
+
+examples:
+ - |
+
+ ovl_2l0: ovl@14009000 {
+ compatible = "mediatek,mt8183-disp-ovl-2l";
+ reg = <0 0x14009000 0 0x1000>;
+ interrupts = <GIC_SPI 226 IRQ_TYPE_LEVEL_LOW>;
+ power-domains = <&spm MT8183_POWER_DOMAIN_DISP>;
+ clocks = <&mmsys CLK_MM_DISP_OVL0_2L>;
+ iommus = <&iommu M4U_PORT_DISP_2L_OVL0_LARB0>;
+ mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0x9000 0x1000>;
+ };
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,ovl.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,ovl.yaml
new file mode 100644
index 000000000000..93d5c68a2dbd
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,ovl.yaml
@@ -0,0 +1,93 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/mediatek/mediatek,ovl.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Mediatek display overlay
+
+maintainers:
+ - Chun-Kuang Hu <chunkuang.hu@kernel.org>
+ - Philipp Zabel <p.zabel@pengutronix.de>
+
+description: |
+ Mediatek display overlay, namely OVL, can do alpha blending from
+ the memory.
+ OVL device node must be siblings to the central MMSYS_CONFIG node.
+ For a description of the MMSYS_CONFIG binding, see
+ Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml
+ for details.
+
+properties:
+ compatible:
+ oneOf:
+ - items:
+ - const: mediatek,mt2701-disp-ovl
+ - items:
+ - const: mediatek,mt8173-disp-ovl
+ - items:
+ - const: mediatek,mt8183-disp-ovl
+ - items:
+ - const: mediatek,mt8192-disp-ovl
+ - items:
+ - enum:
+ - mediatek,mt7623-disp-ovl
+ - mediatek,mt2712-disp-ovl
+ - enum:
+ - mediatek,mt2701-disp-ovl
+ - items:
+ - enum:
+ - mediatek,mt8195-disp-ovl
+ - enum:
+ - mediatek,mt8183-disp-ovl
+
+ reg:
+ maxItems: 1
+
+ interrupts:
+ maxItems: 1
+
+ power-domains:
+ description: A phandle and PM domain specifier as defined by bindings of
+ the power controller specified by phandle. See
+ Documentation/devicetree/bindings/power/power-domain.yaml for details.
+
+ clocks:
+ items:
+ - description: OVL Clock
+
+ iommus:
+ description:
+ This property should point to the respective IOMMU block with master port as argument,
+ see Documentation/devicetree/bindings/iommu/mediatek,iommu.yaml for details.
+
+ mediatek,gce-client-reg:
+ description: The register of client driver can be configured by gce with
+ 4 arguments defined in this property, such as phandle of gce, subsys id,
+ register offset and size. Each GCE subsys id is mapping to a client
+ defined in the header include/dt-bindings/gce/<chip>-gce.h.
+ $ref: /schemas/types.yaml#/definitions/phandle-array
+ maxItems: 1
+
+required:
+ - compatible
+ - reg
+ - interrupts
+ - power-domains
+ - clocks
+ - iommu
+
+additionalProperties: false
+
+examples:
+ - |
+
+ ovl0: ovl@1400c000 {
+ compatible = "mediatek,mt8173-disp-ovl";
+ reg = <0 0x1400c000 0 0x1000>;
+ interrupts = <GIC_SPI 180 IRQ_TYPE_LEVEL_LOW>;
+ power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
+ clocks = <&mmsys CLK_MM_DISP_OVL0>;
+ iommus = <&iommu M4U_PORT_DISP_OVL0>;
+ mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0xc000 0x1000>;
+ };
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,postmask.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,postmask.yaml
new file mode 100644
index 000000000000..6ac1da2e8871
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,postmask.yaml
@@ -0,0 +1,69 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/mediatek/mediatek,postmask.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Mediatek display postmask
+
+maintainers:
+ - Chun-Kuang Hu <chunkuang.hu@kernel.org>
+ - Philipp Zabel <p.zabel@pengutronix.de>
+
+description: |
+ Mediatek display postmask, namely POSTMASK, provides round corner pattern
+ generation.
+ POSTMASK device node must be siblings to the central MMSYS_CONFIG node.
+ For a description of the MMSYS_CONFIG binding, see
+ Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml
+ for details.
+
+properties:
+ compatible:
+ oneOf:
+ - items:
+ - const: mediatek,mt8192-disp-postmask
+
+ reg:
+ maxItems: 1
+
+ interrupts:
+ maxItems: 1
+
+ power-domains:
+ description: A phandle and PM domain specifier as defined by bindings of
+ the power controller specified by phandle. See
+ Documentation/devicetree/bindings/power/power-domain.yaml for details.
+
+ clocks:
+ items:
+ - description: POSTMASK Clock
+
+ mediatek,gce-client-reg:
+ description: The register of client driver can be configured by gce with
+ 4 arguments defined in this property, such as phandle of gce, subsys id,
+ register offset and size. Each GCE subsys id is mapping to a client
+ defined in the header include/dt-bindings/gce/<chip>-gce.h.
+ $ref: /schemas/types.yaml#/definitions/phandle-array
+ maxItems: 1
+
+required:
+ - compatible
+ - reg
+ - interrupts
+ - power-domains
+ - clocks
+
+additionalProperties: false
+
+examples:
+ - |
+
+ postmask0: postmask@1400d000 {
+ compatible = "mediatek,mt8192-disp-postmask";
+ reg = <0 0x1400d000 0 0x1000>;
+ interrupts = <GIC_SPI 262 IRQ_TYPE_LEVEL_HIGH 0>;
+ power-domains = <&scpsys MT8192_POWER_DOMAIN_DISP>;
+ clocks = <&mmsys CLK_MM_DISP_POSTMASK0>;
+ mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0xd000 0x1000>;
+ };
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,rdma.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,rdma.yaml
new file mode 100644
index 000000000000..b56e22fbcd52
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,rdma.yaml
@@ -0,0 +1,107 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/mediatek/mediatek,rdma.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Mediatek Read Direct Memory Access
+
+maintainers:
+ - Chun-Kuang Hu <chunkuang.hu@kernel.org>
+ - Philipp Zabel <p.zabel@pengutronix.de>
+
+description: |
+ Mediatek Read Direct Memory Access(RDMA) component used to read the
+ data into DMA. It provides real time data to the back-end panel
+ driver, such as DSI, DPI and DP_INTF.
+ It contains one line buffer to store the sufficient pixel data.
+ RDMA device node must be siblings to the central MMSYS_CONFIG node.
+ For a description of the MMSYS_CONFIG binding, see
+ Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml
+ for details.
+
+properties:
+ compatible:
+ oneOf:
+ - items:
+ - const: mediatek,mt2701-disp-rdma
+ - items:
+ - const: mediatek,mt8173-disp-rdma
+ - items:
+ - const: mediatek,mt8183-disp-rdma
+ - items:
+ - const: mediatek,mt8195-disp-rdma
+ - items:
+ - enum:
+ - mediatek,mt7623-disp-rdma
+ - mediatek,mt2712-disp-rdma
+ - enum:
+ - mediatek,mt2701-disp-rdma
+ - items:
+ - enum:
+ - mediatek,mt8192-disp-rdma
+ - enum:
+ - mediatek,mt8183-disp-rdma
+
+ reg:
+ maxItems: 1
+
+ interrupts:
+ maxItems: 1
+
+ power-domains:
+ description: A phandle and PM domain specifier as defined by bindings of
+ the power controller specified by phandle. See
+ Documentation/devicetree/bindings/power/power-domain.yaml for details.
+
+ clocks:
+ items:
+ - description: RDMA Clock
+
+ iommus:
+ description:
+ This property should point to the respective IOMMU block with master port as argument,
+ see Documentation/devicetree/bindings/iommu/mediatek,iommu.yaml for details.
+
+ mediatek,rdma-fifo-size:
+ description:
+ rdma fifo size may be different even in same SOC, add this property to the
+ corresponding rdma.
+ The value below is the Max value which defined in hardware data sheet
+ mediatek,rdma-fifo-size of mt8173-rdma0 is 8K
+ mediatek,rdma-fifo-size of mt8183-rdma0 is 5K
+ mediatek,rdma-fifo-size of mt8183-rdma1 is 2K
+ $ref: /schemas/types.yaml#/definitions/uint32
+ enum: [8192, 5120, 2048]
+
+ mediatek,gce-client-reg:
+ description: The register of client driver can be configured by gce with
+ 4 arguments defined in this property, such as phandle of gce, subsys id,
+ register offset and size. Each GCE subsys id is mapping to a client
+ defined in the header include/dt-bindings/gce/<chip>-gce.h.
+ $ref: /schemas/types.yaml#/definitions/phandle-array
+ maxItems: 1
+
+required:
+ - compatible
+ - reg
+ - interrupts
+ - power-domains
+ - clocks
+ - iommus
+
+additionalProperties: false
+
+examples:
+ - |
+
+ rdma0: rdma@1400e000 {
+ compatible = "mediatek,mt8173-disp-rdma";
+ reg = <0 0x1400e000 0 0x1000>;
+ interrupts = <GIC_SPI 182 IRQ_TYPE_LEVEL_LOW>;
+ power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
+ clocks = <&mmsys CLK_MM_DISP_RDMA0>;
+ iommus = <&iommu M4U_PORT_DISP_RDMA0>;
+ mediatek,rdma-fifosize = <8192>;
+ mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0xe000 0x1000>;
+ };
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,split.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,split.yaml
new file mode 100644
index 000000000000..4f08e89c1067
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,split.yaml
@@ -0,0 +1,58 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/mediatek/mediatek,split.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Mediatek display split
+
+maintainers:
+ - Chun-Kuang Hu <chunkuang.hu@kernel.org>
+ - Philipp Zabel <p.zabel@pengutronix.de>
+
+description: |
+ Mediatek display split, namely SPLIT, is used to split stream to two
+ encoders.
+ SPLIT device node must be siblings to the central MMSYS_CONFIG node.
+ For a description of the MMSYS_CONFIG binding, see
+ Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml
+ for details.
+
+properties:
+ compatible:
+ oneOf:
+ - items:
+ - const: mediatek,mt8173-disp-split
+
+ reg:
+ maxItems: 1
+
+ interrupts:
+ maxItems: 1
+
+ power-domains:
+ description: A phandle and PM domain specifier as defined by bindings of
+ the power controller specified by phandle. See
+ Documentation/devicetree/bindings/power/power-domain.yaml for details.
+
+ clocks:
+ items:
+ - description: SPLIT Clock
+
+required:
+ - compatible
+ - reg
+ - power-domains
+ - clocks
+
+additionalProperties: false
+
+examples:
+ - |
+
+ split0: split@14018000 {
+ compatible = "mediatek,mt8173-disp-split";
+ reg = <0 0x14018000 0 0x1000>;
+ power-domains = <&spm MT8173_POWER_DOMAIN_MM>;
+ clocks = <&mmsys CLK_MM_DISP_SPLIT0>;
+ };
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,ufoe.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,ufoe.yaml
new file mode 100644
index 000000000000..6e8748529e73
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,ufoe.yaml
@@ -0,0 +1,61 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/mediatek/mediatek,ufoe.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Mediatek display UFOe
+
+maintainers:
+ - Chun-Kuang Hu <chunkuang.hu@kernel.org>
+ - Philipp Zabel <p.zabel@pengutronix.de>
+
+description: |
+ Mediatek display UFOe stands for Unified Frame Optimization engine.
+ UFOe can cut the data rate for DSI port which may lead to reduce power
+ consumption.
+ UFOe device node must be siblings to the central MMSYS_CONFIG node.
+ For a description of the MMSYS_CONFIG binding, see
+ Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml
+ for details.
+
+properties:
+ compatible:
+ oneOf:
+ - items:
+ - const: mediatek,mt8173-disp-ufoe
+
+ reg:
+ maxItems: 1
+
+ interrupts:
+ maxItems: 1
+
+ power-domains:
+ description: A phandle and PM domain specifier as defined by bindings of
+ the power controller specified by phandle. See
+ Documentation/devicetree/bindings/power/power-domain.yaml for details.
+
+ clocks:
+ items:
+ - description: UFOe Clock
+
+required:
+ - compatible
+ - reg
+ - interrupts
+ - power-domains
+ - clocks
+
+additionalProperties: false
+
+examples:
+ - |
+
+ ufoe@1401a000 {
+ compatible = "mediatek,mt8173-disp-ufoe";
+ reg = <0 0x1401a000 0 0x1000>;
+ interrupts = <GIC_SPI 191 IRQ_TYPE_LEVEL_LOW>;
+ power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
+ clocks = <&mmsys CLK_MM_DISP_UFOE>;
+ };
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,wdma.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,wdma.yaml
new file mode 100644
index 000000000000..f9f00a518edf
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,wdma.yaml
@@ -0,0 +1,76 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/mediatek/mediatek,wdma.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Mediatek Write Direct Memory Access
+
+maintainers:
+ - Chun-Kuang Hu <chunkuang.hu@kernel.org>
+ - Philipp Zabel <p.zabel@pengutronix.de>
+
+description: |
+ Mediatek Write Direct Memory Access(WDMA) component used to write
+ the data into DMA.
+ WDMA device node must be siblings to the central MMSYS_CONFIG node.
+ For a description of the MMSYS_CONFIG binding, see
+ Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml
+ for details.
+
+properties:
+ compatible:
+ oneOf:
+ - items:
+ - const: mediatek,mt8173-disp-wdma
+
+ reg:
+ maxItems: 1
+
+ interrupts:
+ maxItems: 1
+
+ power-domains:
+ description: A phandle and PM domain specifier as defined by bindings of
+ the power controller specified by phandle. See
+ Documentation/devicetree/bindings/power/power-domain.yaml for details.
+
+ clocks:
+ items:
+ - description: WDMA Clock
+
+ iommus:
+ description:
+ This property should point to the respective IOMMU block with master port as argument,
+ see Documentation/devicetree/bindings/iommu/mediatek,iommu.yaml for details.
+
+ mediatek,gce-client-reg:
+ description: The register of client driver can be configured by gce with
+ 4 arguments defined in this property, such as phandle of gce, subsys id,
+ register offset and size. Each GCE subsys id is mapping to a client
+ defined in the header include/dt-bindings/gce/<chip>-gce.h.
+ $ref: /schemas/types.yaml#/definitions/phandle-array
+ maxItems: 1
+
+required:
+ - compatible
+ - reg
+ - interrupts
+ - power-domains
+ - clocks
+ - iommus
+
+additionalProperties: false
+
+examples:
+ - |
+
+ wdma0: wdma@14011000 {
+ compatible = "mediatek,mt8173-disp-wdma";
+ reg = <0 0x14011000 0 0x1000>;
+ interrupts = <GIC_SPI 185 IRQ_TYPE_LEVEL_LOW>;
+ power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
+ clocks = <&mmsys CLK_MM_DISP_WDMA0>;
+ iommus = <&iommu M4U_PORT_DISP_WDMA0>;
+ mediatek,gce-client-reg = <&gce SUBSYS_1401XXXX 0x1000 0x1000>;
+ };
diff --git a/Documentation/devicetree/bindings/display/msm/dp-controller.yaml b/Documentation/devicetree/bindings/display/msm/dp-controller.yaml
index 5457612ab136..cd05cfd76536 100644
--- a/Documentation/devicetree/bindings/display/msm/dp-controller.yaml
+++ b/Documentation/devicetree/bindings/display/msm/dp-controller.yaml
@@ -21,6 +21,7 @@ properties:
- qcom,sc7280-edp
- qcom,sc8180x-dp
- qcom,sc8180x-edp
+ - qcom,sm8350-dp
reg:
items:
diff --git a/Documentation/devicetree/bindings/display/msm/dpu-msm8998.yaml b/Documentation/devicetree/bindings/display/msm/dpu-msm8998.yaml
new file mode 100644
index 000000000000..2df64afb76e6
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/msm/dpu-msm8998.yaml
@@ -0,0 +1,219 @@
+# SPDX-License-Identifier: GPL-2.0-only or BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/msm/dpu-msm8998.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Qualcomm Display DPU dt properties for MSM8998 target
+
+maintainers:
+ - AngeloGioacchino Del Regno <angelogioacchino.delregno@somainline.org>
+
+description: |
+ Device tree bindings for MSM Mobile Display Subsystem(MDSS) that encapsulates
+ sub-blocks like DPU display controller, DSI and DP interfaces etc. Device tree
+ bindings of MDSS and DPU are mentioned for MSM8998 target.
+
+properties:
+ compatible:
+ items:
+ - const: qcom,msm8998-mdss
+
+ reg:
+ maxItems: 1
+
+ reg-names:
+ const: mdss
+
+ power-domains:
+ maxItems: 1
+
+ clocks:
+ items:
+ - description: Display AHB clock
+ - description: Display AXI clock
+ - description: Display core clock
+
+ clock-names:
+ items:
+ - const: iface
+ - const: bus
+ - const: core
+
+ interrupts:
+ maxItems: 1
+
+ interrupt-controller: true
+
+ "#address-cells": true
+
+ "#size-cells": true
+
+ "#interrupt-cells":
+ const: 1
+
+ iommus:
+ items:
+ - description: Phandle to apps_smmu node with SID mask for Hard-Fail port0
+
+ ranges: true
+
+patternProperties:
+ "^display-controller@[0-9a-f]+$":
+ type: object
+ description: Node containing the properties of DPU.
+
+ properties:
+ compatible:
+ items:
+ - const: qcom,msm8998-dpu
+
+ reg:
+ items:
+ - description: Address offset and size for mdp register set
+ - description: Address offset and size for regdma register set
+ - description: Address offset and size for vbif register set
+ - description: Address offset and size for non-realtime vbif register set
+
+ reg-names:
+ items:
+ - const: mdp
+ - const: regdma
+ - const: vbif
+ - const: vbif_nrt
+
+ clocks:
+ items:
+ - description: Display ahb clock
+ - description: Display axi clock
+ - description: Display mem-noc clock
+ - description: Display core clock
+ - description: Display vsync clock
+
+ clock-names:
+ items:
+ - const: iface
+ - const: bus
+ - const: mnoc
+ - const: core
+ - const: vsync
+
+ interrupts:
+ maxItems: 1
+
+ power-domains:
+ maxItems: 1
+
+ operating-points-v2: true
+ ports:
+ $ref: /schemas/graph.yaml#/properties/ports
+ description: |
+ Contains the list of output ports from DPU device. These ports
+ connect to interfaces that are external to the DPU hardware,
+ such as DSI, DP etc. Each output port contains an endpoint that
+ describes how it is connected to an external interface.
+
+ properties:
+ port@0:
+ $ref: /schemas/graph.yaml#/properties/port
+ description: DPU_INTF1 (DSI1)
+
+ port@1:
+ $ref: /schemas/graph.yaml#/properties/port
+ description: DPU_INTF2 (DSI2)
+
+ required:
+ - port@0
+ - port@1
+
+ required:
+ - compatible
+ - reg
+ - reg-names
+ - clocks
+ - interrupts
+ - power-domains
+ - operating-points-v2
+ - ports
+
+required:
+ - compatible
+ - reg
+ - reg-names
+ - power-domains
+ - clocks
+ - interrupts
+ - interrupt-controller
+ - iommus
+ - ranges
+
+additionalProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/clock/qcom,mmcc-msm8998.h>
+ #include <dt-bindings/interrupt-controller/arm-gic.h>
+ #include <dt-bindings/power/qcom-rpmpd.h>
+
+ mdss: display-subsystem@c900000 {
+ compatible = "qcom,msm8998-mdss";
+ reg = <0x0c900000 0x1000>;
+ reg-names = "mdss";
+
+ clocks = <&mmcc MDSS_AHB_CLK>,
+ <&mmcc MDSS_AXI_CLK>,
+ <&mmcc MDSS_MDP_CLK>;
+ clock-names = "iface", "bus", "core";
+
+ #address-cells = <1>;
+ #interrupt-cells = <1>;
+ #size-cells = <1>;
+
+ interrupts = <GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-controller;
+ iommus = <&mmss_smmu 0>;
+
+ power-domains = <&mmcc MDSS_GDSC>;
+ ranges;
+
+ display-controller@c901000 {
+ compatible = "qcom,msm8998-dpu";
+ reg = <0x0c901000 0x8f000>,
+ <0x0c9a8e00 0xf0>,
+ <0x0c9b0000 0x2008>,
+ <0x0c9b8000 0x1040>;
+ reg-names = "mdp", "regdma", "vbif", "vbif_nrt";
+
+ clocks = <&mmcc MDSS_AHB_CLK>,
+ <&mmcc MDSS_AXI_CLK>,
+ <&mmcc MNOC_AHB_CLK>,
+ <&mmcc MDSS_MDP_CLK>,
+ <&mmcc MDSS_VSYNC_CLK>;
+ clock-names = "iface", "bus", "mnoc", "core", "vsync";
+
+ interrupt-parent = <&mdss>;
+ interrupts = <0>;
+ operating-points-v2 = <&mdp_opp_table>;
+ power-domains = <&rpmpd MSM8998_VDDMX>;
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+ dpu_intf1_out: endpoint {
+ remote-endpoint = <&dsi0_in>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+ dpu_intf2_out: endpoint {
+ remote-endpoint = <&dsi1_in>;
+ };
+ };
+ };
+ };
+ };
+...
diff --git a/Documentation/devicetree/bindings/display/msm/dpu-qcm2290.yaml b/Documentation/devicetree/bindings/display/msm/dpu-qcm2290.yaml
new file mode 100644
index 000000000000..d31483a78eab
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/msm/dpu-qcm2290.yaml
@@ -0,0 +1,215 @@
+# SPDX-License-Identifier: GPL-2.0-only or BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/msm/dpu-qcm2290.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Qualcomm Display DPU dt properties for QCM2290 target
+
+maintainers:
+ - Loic Poulain <loic.poulain@linaro.org>
+
+description: |
+ Device tree bindings for MSM Mobile Display Subsystem(MDSS) that encapsulates
+ sub-blocks like DPU display controller and DSI. Device tree bindings of MDSS
+ and DPU are mentioned for QCM2290 target.
+
+properties:
+ compatible:
+ items:
+ - const: qcom,qcm2290-mdss
+
+ reg:
+ maxItems: 1
+
+ reg-names:
+ const: mdss
+
+ power-domains:
+ maxItems: 1
+
+ clocks:
+ items:
+ - description: Display AHB clock from gcc
+ - description: Display AXI clock
+ - description: Display core clock
+
+ clock-names:
+ items:
+ - const: iface
+ - const: bus
+ - const: core
+
+ interrupts:
+ maxItems: 1
+
+ interrupt-controller: true
+
+ "#address-cells": true
+
+ "#size-cells": true
+
+ "#interrupt-cells":
+ const: 1
+
+ iommus:
+ items:
+ - description: Phandle to apps_smmu node with SID mask for Hard-Fail port0
+ - description: Phandle to apps_smmu node with SID mask for Hard-Fail port1
+
+ ranges: true
+
+ interconnects:
+ items:
+ - description: Interconnect path specifying the port ids for data bus
+
+ interconnect-names:
+ const: mdp0-mem
+
+patternProperties:
+ "^display-controller@[0-9a-f]+$":
+ type: object
+ description: Node containing the properties of DPU.
+
+ properties:
+ compatible:
+ items:
+ - const: qcom,qcm2290-dpu
+
+ reg:
+ items:
+ - description: Address offset and size for mdp register set
+ - description: Address offset and size for vbif register set
+
+ reg-names:
+ items:
+ - const: mdp
+ - const: vbif
+
+ clocks:
+ items:
+ - description: Display AXI clock from gcc
+ - description: Display AHB clock from dispcc
+ - description: Display core clock from dispcc
+ - description: Display lut clock from dispcc
+ - description: Display vsync clock from dispcc
+
+ clock-names:
+ items:
+ - const: bus
+ - const: iface
+ - const: core
+ - const: lut
+ - const: vsync
+
+ interrupts:
+ maxItems: 1
+
+ power-domains:
+ maxItems: 1
+
+ operating-points-v2: true
+
+ ports:
+ $ref: /schemas/graph.yaml#/properties/ports
+ description: |
+ Contains the list of output ports from DPU device. These ports
+ connect to interfaces that are external to the DPU hardware,
+ such as DSI. Each output port contains an endpoint that
+ describes how it is connected to an external interface.
+
+ properties:
+ port@0:
+ $ref: /schemas/graph.yaml#/properties/port
+ description: DPU_INTF1 (DSI1)
+
+ required:
+ - port@0
+
+ required:
+ - compatible
+ - reg
+ - reg-names
+ - clocks
+ - interrupts
+ - power-domains
+ - operating-points-v2
+ - ports
+
+required:
+ - compatible
+ - reg
+ - reg-names
+ - power-domains
+ - clocks
+ - interrupts
+ - interrupt-controller
+ - iommus
+ - ranges
+
+additionalProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/clock/qcom,dispcc-qcm2290.h>
+ #include <dt-bindings/clock/qcom,gcc-qcm2290.h>
+ #include <dt-bindings/interrupt-controller/arm-gic.h>
+ #include <dt-bindings/interconnect/qcom,qcm2290.h>
+ #include <dt-bindings/power/qcom-rpmpd.h>
+
+ mdss: mdss@5e00000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "qcom,qcm2290-mdss", "qcom,mdss";
+ reg = <0x05e00000 0x1000>;
+ reg-names = "mdss";
+ power-domains = <&dispcc MDSS_GDSC>;
+ clocks = <&gcc GCC_DISP_AHB_CLK>,
+ <&gcc GCC_DISP_HF_AXI_CLK>,
+ <&dispcc DISP_CC_MDSS_MDP_CLK>;
+ clock-names = "iface", "bus", "core";
+
+ interrupts = <GIC_SPI 186 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-controller;
+ #interrupt-cells = <1>;
+
+ interconnects = <&mmrt_virt MASTER_MDP0 &bimc SLAVE_EBI1>;
+ interconnect-names = "mdp0-mem";
+
+ iommus = <&apps_smmu 0x420 0x2>,
+ <&apps_smmu 0x421 0x0>;
+ ranges;
+
+ mdss_mdp: mdp@5e01000 {
+ compatible = "qcom,qcm2290-dpu";
+ reg = <0x05e01000 0x8f000>,
+ <0x05eb0000 0x2008>;
+ reg-names = "mdp", "vbif";
+
+ clocks = <&gcc GCC_DISP_HF_AXI_CLK>,
+ <&dispcc DISP_CC_MDSS_AHB_CLK>,
+ <&dispcc DISP_CC_MDSS_MDP_CLK>,
+ <&dispcc DISP_CC_MDSS_MDP_LUT_CLK>,
+ <&dispcc DISP_CC_MDSS_VSYNC_CLK>;
+ clock-names = "bus", "iface", "core", "lut", "vsync";
+
+ operating-points-v2 = <&mdp_opp_table>;
+ power-domains = <&rpmpd QCM2290_VDDCX>;
+
+ interrupt-parent = <&mdss>;
+ interrupts = <0>;
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+ dpu_intf1_out: endpoint {
+ remote-endpoint = <&dsi0_in>;
+ };
+ };
+ };
+ };
+ };
+...
diff --git a/Documentation/devicetree/bindings/display/msm/dsi-controller-main.yaml b/Documentation/devicetree/bindings/display/msm/dsi-controller-main.yaml
index 35426fde8610..7095ec3c890d 100644
--- a/Documentation/devicetree/bindings/display/msm/dsi-controller-main.yaml
+++ b/Documentation/devicetree/bindings/display/msm/dsi-controller-main.yaml
@@ -14,8 +14,9 @@ allOf:
properties:
compatible:
- items:
- - const: qcom,mdss-dsi-ctrl
+ enum:
+ - qcom,mdss-dsi-ctrl
+ - qcom,dsi-ctrl-6g-qcm2290
reg:
maxItems: 1
diff --git a/Documentation/devicetree/bindings/display/msm/dsi-phy-10nm.yaml b/Documentation/devicetree/bindings/display/msm/dsi-phy-10nm.yaml
index 4399715953e1..2d5a766d028f 100644
--- a/Documentation/devicetree/bindings/display/msm/dsi-phy-10nm.yaml
+++ b/Documentation/devicetree/bindings/display/msm/dsi-phy-10nm.yaml
@@ -35,6 +35,38 @@ properties:
Connected to DSI0_MIPI_DSI_PLL_VDDA0P9 pin for sc7180 target and
connected to VDDA_MIPI_DSI_0_PLL_0P9 pin for sdm845 target
+ qcom,phy-rescode-offset-top:
+ $ref: /schemas/types.yaml#/definitions/int8-array
+ minItems: 5
+ maxItems: 5
+ description:
+ Integer array of offset for pull-up legs rescode for all five lanes.
+ To offset the drive strength from the calibrated value in an increasing
+ manner, -32 is the weakest and +31 is the strongest.
+ items:
+ minimum: -32
+ maximum: 31
+
+ qcom,phy-rescode-offset-bot:
+ $ref: /schemas/types.yaml#/definitions/int8-array
+ minItems: 5
+ maxItems: 5
+ description:
+ Integer array of offset for pull-down legs rescode for all five lanes.
+ To offset the drive strength from the calibrated value in a decreasing
+ manner, -32 is the weakest and +31 is the strongest.
+ items:
+ minimum: -32
+ maximum: 31
+
+ qcom,phy-drive-ldo-level:
+ $ref: "/schemas/types.yaml#/definitions/uint32"
+ description:
+ The PHY LDO has an amplitude tuning feature to adjust the LDO output
+ for the HSTX drive. Use supported levels (mV) to offset the drive level
+ from the default value.
+ enum: [ 375, 400, 425, 450, 475, 500 ]
+
required:
- compatible
- reg
@@ -64,5 +96,9 @@ examples:
clocks = <&dispcc DISP_CC_MDSS_AHB_CLK>,
<&rpmhcc RPMH_CXO_CLK>;
clock-names = "iface", "ref";
+
+ qcom,phy-rescode-offset-top = /bits/ 8 <0 0 0 0 0>;
+ qcom,phy-rescode-offset-bot = /bits/ 8 <0 0 0 0 0>;
+ qcom,phy-drive-ldo-level = <400>;
};
...
diff --git a/Documentation/devicetree/bindings/display/panel/advantech,idk-1110wr.yaml b/Documentation/devicetree/bindings/display/panel/advantech,idk-1110wr.yaml
index 93878c2cd370..3a8c2c11f9bd 100644
--- a/Documentation/devicetree/bindings/display/panel/advantech,idk-1110wr.yaml
+++ b/Documentation/devicetree/bindings/display/panel/advantech,idk-1110wr.yaml
@@ -11,13 +11,23 @@ maintainers:
- Thierry Reding <thierry.reding@gmail.com>
allOf:
- - $ref: lvds.yaml#
+ - $ref: panel-common.yaml#
+ - $ref: /schemas/display/lvds.yaml/#
+
+select:
+ properties:
+ compatible:
+ contains:
+ const: advantech,idk-1110wr
+
+ required:
+ - compatible
properties:
compatible:
items:
- const: advantech,idk-1110wr
- - {} # panel-lvds, but not listed here to avoid false select
+ - const: panel-lvds
data-mapping:
const: jeida-24
@@ -35,6 +45,11 @@ additionalProperties: false
required:
- compatible
+ - data-mapping
+ - width-mm
+ - height-mm
+ - panel-timing
+ - port
examples:
- |+
diff --git a/Documentation/devicetree/bindings/display/panel/innolux,ee101ia-01d.yaml b/Documentation/devicetree/bindings/display/panel/innolux,ee101ia-01d.yaml
index a69681e724cb..566e11f6bfc0 100644
--- a/Documentation/devicetree/bindings/display/panel/innolux,ee101ia-01d.yaml
+++ b/Documentation/devicetree/bindings/display/panel/innolux,ee101ia-01d.yaml
@@ -11,15 +11,26 @@ maintainers:
- Thierry Reding <thierry.reding@gmail.com>
allOf:
- - $ref: lvds.yaml#
+ - $ref: panel-common.yaml#
+ - $ref: /schemas/display/lvds.yaml/#
+
+select:
+ properties:
+ compatible:
+ contains:
+ const: innolux,ee101ia-01d
+
+ required:
+ - compatible
properties:
compatible:
items:
- const: innolux,ee101ia-01d
- - {} # panel-lvds, but not listed here to avoid false select
+ - const: panel-lvds
backlight: true
+ data-mapping: true
enable-gpios: true
power-supply: true
width-mm: true
@@ -27,5 +38,13 @@ properties:
panel-timing: true
port: true
+required:
+ - compatible
+ - data-mapping
+ - width-mm
+ - height-mm
+ - panel-timing
+ - port
+
additionalProperties: false
...
diff --git a/Documentation/devicetree/bindings/display/panel/mitsubishi,aa104xd12.yaml b/Documentation/devicetree/bindings/display/panel/mitsubishi,aa104xd12.yaml
index b5e7ee230fa6..5cf3c588f46d 100644
--- a/Documentation/devicetree/bindings/display/panel/mitsubishi,aa104xd12.yaml
+++ b/Documentation/devicetree/bindings/display/panel/mitsubishi,aa104xd12.yaml
@@ -11,13 +11,23 @@ maintainers:
- Thierry Reding <thierry.reding@gmail.com>
allOf:
- - $ref: lvds.yaml#
+ - $ref: panel-common.yaml#
+ - $ref: /schemas/display/lvds.yaml/#
+
+select:
+ properties:
+ compatible:
+ contains:
+ const: mitsubishi,aa104xd12
+
+ required:
+ - compatible
properties:
compatible:
items:
- const: mitsubishi,aa104xd12
- - {} # panel-lvds, but not listed here to avoid false select
+ - const: panel-lvds
vcc-supply:
description: Reference to the regulator powering the panel VCC pins.
@@ -39,6 +49,11 @@ additionalProperties: false
required:
- compatible
- vcc-supply
+ - data-mapping
+ - width-mm
+ - height-mm
+ - panel-timing
+ - port
examples:
- |+
diff --git a/Documentation/devicetree/bindings/display/panel/mitsubishi,aa121td01.yaml b/Documentation/devicetree/bindings/display/panel/mitsubishi,aa121td01.yaml
index 977c50a85b67..54750cc5440d 100644
--- a/Documentation/devicetree/bindings/display/panel/mitsubishi,aa121td01.yaml
+++ b/Documentation/devicetree/bindings/display/panel/mitsubishi,aa121td01.yaml
@@ -11,13 +11,23 @@ maintainers:
- Thierry Reding <thierry.reding@gmail.com>
allOf:
- - $ref: lvds.yaml#
+ - $ref: panel-common.yaml#
+ - $ref: /schemas/display/lvds.yaml/#
+
+select:
+ properties:
+ compatible:
+ contains:
+ const: mitsubishi,aa121td01
+
+ required:
+ - compatible
properties:
compatible:
items:
- const: mitsubishi,aa121td01
- - {} # panel-lvds, but not listed here to avoid false select
+ - const: panel-lvds
vcc-supply:
description: Reference to the regulator powering the panel VCC pins.
@@ -39,6 +49,11 @@ additionalProperties: false
required:
- compatible
- vcc-supply
+ - data-mapping
+ - width-mm
+ - height-mm
+ - panel-timing
+ - port
examples:
- |+
diff --git a/Documentation/devicetree/bindings/display/panel/panel-lvds.yaml b/Documentation/devicetree/bindings/display/panel/panel-lvds.yaml
new file mode 100644
index 000000000000..fcc50db6a812
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/panel/panel-lvds.yaml
@@ -0,0 +1,57 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/panel/panel-lvds.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Generic LVDS Display Panel Device Tree Bindings
+
+maintainers:
+ - Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
+ - Thierry Reding <thierry.reding@gmail.com>
+
+allOf:
+ - $ref: panel-common.yaml#
+ - $ref: /schemas/display/lvds.yaml/#
+
+select:
+ properties:
+ compatible:
+ contains:
+ const: panel-lvds
+
+ not:
+ properties:
+ compatible:
+ contains:
+ enum:
+ - advantech,idk-1110wr
+ - advantech,idk-2121wr
+ - innolux,ee101ia-01d
+ - mitsubishi,aa104xd12
+ - mitsubishi,aa121td01
+ - sgd,gktw70sdae4se
+
+ required:
+ - compatible
+
+properties:
+ compatible:
+ items:
+ - enum:
+ - auo,b101ew05
+ - tbs,a711-panel
+
+ - const: panel-lvds
+
+unevaluatedProperties: false
+
+required:
+ - compatible
+ - data-mapping
+ - width-mm
+ - height-mm
+ - panel-timing
+ - port
+
+...
diff --git a/Documentation/devicetree/bindings/display/panel/panel-mipi-dbi-spi.yaml b/Documentation/devicetree/bindings/display/panel/panel-mipi-dbi-spi.yaml
new file mode 100644
index 000000000000..f29789994b18
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/panel/panel-mipi-dbi-spi.yaml
@@ -0,0 +1,126 @@
+# SPDX-License-Identifier: (GPL-2.0-only or BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/panel/panel-mipi-dbi-spi.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: MIPI DBI SPI Panel
+
+maintainers:
+ - Noralf Trønnes <noralf@tronnes.org>
+
+description: |
+ This binding is for display panels using a MIPI DBI compatible controller
+ in SPI mode.
+
+ The MIPI Alliance Standard for Display Bus Interface defines the electrical
+ and logical interfaces for display controllers historically used in mobile
+ phones. The standard defines 4 display architecture types and this binding is
+ for type 1 which has full frame memory. There are 3 interface types in the
+ standard and type C is the serial interface.
+
+ The standard defines the following interface signals for type C:
+ - Power:
+ - Vdd: Power supply for display module
+ - Vddi: Logic level supply for interface signals
+ Combined into one in this binding called: power-supply
+ - Interface:
+ - CSx: Chip select
+ - SCL: Serial clock
+ - Dout: Serial out
+ - Din: Serial in
+ - SDA: Bidrectional in/out
+ - D/CX: Data/command selection, high=data, low=command
+ Called dc-gpios in this binding.
+ - RESX: Reset when low
+ Called reset-gpios in this binding.
+
+ The type C interface has 3 options:
+
+ - Option 1: 9-bit mode and D/CX as the 9th bit
+ | Command | the next command or following data |
+ |<0><D7><D6><D5><D4><D3><D2><D1><D0>|<D/CX><D7><D6><D5><D4><D3><D2><D1><D0>|
+
+ - Option 2: 16-bit mode and D/CX as a 9th bit
+ | Command or data |
+ |<X><X><X><X><X><X><X><D/CX><D7><D6><D5><D4><D3><D2><D1><D0>|
+
+ - Option 3: 8-bit mode and D/CX as a separate interface line
+ | Command or data |
+ |<D7><D6><D5><D4><D3><D2><D1><D0>|
+
+ The panel resolution is specified using the panel-timing node properties
+ hactive (width) and vactive (height). The other mandatory panel-timing
+ properties should be set to zero except clock-frequency which can be
+ optionally set to inform about the actual pixel clock frequency.
+
+ If the panel is wired to the controller at an offset specify this using
+ hback-porch (x-offset) and vback-porch (y-offset).
+
+allOf:
+ - $ref: panel-common.yaml#
+ - $ref: /schemas/spi/spi-peripheral-props.yaml#
+
+properties:
+ compatible:
+ items:
+ - enum:
+ - sainsmart18
+ - const: panel-mipi-dbi-spi
+
+ write-only:
+ type: boolean
+ description:
+ Controller is not readable (ie. Din (MISO on the SPI interface) is not
+ wired up).
+
+ dc-gpios:
+ maxItems: 1
+ description: |
+ Controller data/command selection (D/CX) in 4-line SPI mode.
+ If not set, the controller is in 3-line SPI mode.
+
+required:
+ - compatible
+ - reg
+ - panel-timing
+
+unevaluatedProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/gpio/gpio.h>
+
+ spi {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ display@0{
+ compatible = "sainsmart18", "panel-mipi-dbi-spi";
+ reg = <0>;
+ spi-max-frequency = <40000000>;
+
+ dc-gpios = <&gpio 24 GPIO_ACTIVE_HIGH>;
+ reset-gpios = <&gpio 25 GPIO_ACTIVE_HIGH>;
+ write-only;
+
+ backlight = <&backlight>;
+
+ width-mm = <35>;
+ height-mm = <28>;
+
+ panel-timing {
+ hactive = <160>;
+ vactive = <128>;
+ hback-porch = <0>;
+ vback-porch = <0>;
+ clock-frequency = <0>;
+ hfront-porch = <0>;
+ hsync-len = <0>;
+ vfront-porch = <0>;
+ vsync-len = <0>;
+ };
+ };
+ };
+
+...
diff --git a/Documentation/devicetree/bindings/display/panel/panel-simple.yaml b/Documentation/devicetree/bindings/display/panel/panel-simple.yaml
index 62f5f050c1bc..1eb9dd4f8f58 100644
--- a/Documentation/devicetree/bindings/display/panel/panel-simple.yaml
+++ b/Documentation/devicetree/bindings/display/panel/panel-simple.yaml
@@ -222,6 +222,8 @@ properties:
- logictechno,lttd800480070-l6wh-rt
# Mitsubishi "AA070MC01 7.0" WVGA TFT LCD panel
- mitsubishi,aa070mc01-ca1
+ # Multi-Inno Technology Co.,Ltd MI0700S4T-6 7" 800x480 TFT Resistive Touch Module
+ - multi-inno,mi0700s4t-6
# Multi-Inno Technology Co.,Ltd MI1010AIT-1CP 10.1" 1280x800 LVDS IPS Cap Touch Mod.
- multi-inno,mi1010ait-1cp
# NEC LCD Technologies, Ltd. 12.1" WXGA (1280x800) LVDS TFT LCD panel
@@ -282,6 +284,8 @@ properties:
- sharp,lq101k1ly04
# Sharp 12.3" (2400x1600 pixels) TFT LCD panel
- sharp,lq123p1jx31
+ # Sharp 14" (1920x1080 pixels) TFT LCD panel
+ - sharp,lq140m1jw46
# Sharp LS020B1DD01D 2.0" HQVGA TFT LCD panel
- sharp,ls020b1dd01d
# Shelly SCA07010-BFN-LNN 7.0" WVGA TFT LCD panel
diff --git a/Documentation/devicetree/bindings/display/panel/sgd,gktw70sdae4se.yaml b/Documentation/devicetree/bindings/display/panel/sgd,gktw70sdae4se.yaml
index e63a570ae59d..44e02decdf3a 100644
--- a/Documentation/devicetree/bindings/display/panel/sgd,gktw70sdae4se.yaml
+++ b/Documentation/devicetree/bindings/display/panel/sgd,gktw70sdae4se.yaml
@@ -11,13 +11,23 @@ maintainers:
- Thierry Reding <thierry.reding@gmail.com>
allOf:
- - $ref: lvds.yaml#
+ - $ref: panel-common.yaml#
+ - $ref: /schemas/display/lvds.yaml/#
+
+select:
+ properties:
+ compatible:
+ contains:
+ const: sgd,gktw70sdae4se
+
+ required:
+ - compatible
properties:
compatible:
items:
- const: sgd,gktw70sdae4se
- - {} # panel-lvds, but not listed here to avoid false select
+ - const: panel-lvds
data-mapping:
const: jeida-18
@@ -35,6 +45,11 @@ additionalProperties: false
required:
- compatible
+ - port
+ - data-mapping
+ - width-mm
+ - height-mm
+ - panel-timing
examples:
- |+
diff --git a/Documentation/devicetree/bindings/display/panel/sony,acx424akp.yaml b/Documentation/devicetree/bindings/display/panel/sony,acx424akp.yaml
index 78d060097052..059cc6dbcfca 100644
--- a/Documentation/devicetree/bindings/display/panel/sony,acx424akp.yaml
+++ b/Documentation/devicetree/bindings/display/panel/sony,acx424akp.yaml
@@ -4,7 +4,12 @@
$id: http://devicetree.org/schemas/display/panel/sony,acx424akp.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
-title: Sony ACX424AKP 4" 480x864 AMOLED panel
+title: Sony ACX424AKP/ACX424AKM 4" 480x864/480x854 AMOLED panel
+
+description: The Sony ACX424AKP and ACX424AKM are panels built around
+ the Novatek NT35560 display controller. The only difference is that
+ the AKM is configured to use 10 pixels less in the Y axis than the
+ AKP.
maintainers:
- Linus Walleij <linus.walleij@linaro.org>
@@ -14,7 +19,9 @@ allOf:
properties:
compatible:
- const: sony,acx424akp
+ enum:
+ - sony,acx424akp
+ - sony,acx424akm
reg: true
reset-gpios: true
vddi-supply:
diff --git a/Documentation/devicetree/bindings/display/simple-framebuffer.yaml b/Documentation/devicetree/bindings/display/simple-framebuffer.yaml
index 44a29d813f14..27ba4323d221 100644
--- a/Documentation/devicetree/bindings/display/simple-framebuffer.yaml
+++ b/Documentation/devicetree/bindings/display/simple-framebuffer.yaml
@@ -52,11 +52,13 @@ description: |+
properties:
compatible:
- items:
- - enum:
- - apple,simple-framebuffer
- - allwinner,simple-framebuffer
- - amlogic,simple-framebuffer
+ oneOf:
+ - items:
+ - enum:
+ - apple,simple-framebuffer
+ - allwinner,simple-framebuffer
+ - amlogic,simple-framebuffer
+ - const: simple-framebuffer
- const: simple-framebuffer
reg:
diff --git a/Documentation/devicetree/bindings/display/solomon,ssd1307fb.yaml b/Documentation/devicetree/bindings/display/solomon,ssd1307fb.yaml
index 2ed2a7d0ca2f..9baafd0c42dd 100644
--- a/Documentation/devicetree/bindings/display/solomon,ssd1307fb.yaml
+++ b/Documentation/devicetree/bindings/display/solomon,ssd1307fb.yaml
@@ -8,6 +8,7 @@ title: Solomon SSD1307 OLED Controller Framebuffer
maintainers:
- Maxime Ripard <mripard@kernel.org>
+ - Javier Martinez Canillas <javierm@redhat.com>
properties:
compatible:
diff --git a/Documentation/devicetree/bindings/dma/nvidia,tegra210-adma.yaml b/Documentation/devicetree/bindings/dma/nvidia,tegra210-adma.yaml
index 5c2e2f156e31..fef804565b88 100644
--- a/Documentation/devicetree/bindings/dma/nvidia,tegra210-adma.yaml
+++ b/Documentation/devicetree/bindings/dma/nvidia,tegra210-adma.yaml
@@ -23,7 +23,9 @@ properties:
- nvidia,tegra210-adma
- nvidia,tegra186-adma
- items:
- - const: nvidia,tegra194-adma
+ - enum:
+ - nvidia,tegra234-adma
+ - nvidia,tegra194-adma
- const: nvidia,tegra186-adma
reg:
diff --git a/Documentation/devicetree/bindings/extcon/maxim,max77843.yaml b/Documentation/devicetree/bindings/extcon/maxim,max77843.yaml
new file mode 100644
index 000000000000..f9ffe3d6f957
--- /dev/null
+++ b/Documentation/devicetree/bindings/extcon/maxim,max77843.yaml
@@ -0,0 +1,40 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/extcon/maxim,max77843.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Maxim MAX77843 MicroUSB and Companion Power Management IC Extcon
+
+maintainers:
+ - Chanwoo Choi <cw00.choi@samsung.com>
+ - Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>
+
+description: |
+ This is a part of device tree bindings for Maxim MAX77843 MicroUSB
+ Integrated Circuit (MUIC).
+
+ See also Documentation/devicetree/bindings/mfd/maxim,max77843.yaml for
+ additional information and example.
+
+properties:
+ compatible:
+ const: maxim,max77843-muic
+
+ connector:
+ $ref: /schemas/connector/usb-connector.yaml#
+
+ ports:
+ $ref: /schemas/graph.yaml#/properties/port
+ description:
+ Any connector to the data bus of this controller should be modelled using
+ the OF graph bindings specified
+ properties:
+ port:
+ $ref: /schemas/graph.yaml#/properties/port
+
+required:
+ - compatible
+ - connector
+
+additionalProperties: false
diff --git a/Documentation/devicetree/bindings/firmware/arm,scmi.yaml b/Documentation/devicetree/bindings/firmware/arm,scmi.yaml
index 5c4c6782e052..590743883802 100644
--- a/Documentation/devicetree/bindings/firmware/arm,scmi.yaml
+++ b/Documentation/devicetree/bindings/firmware/arm,scmi.yaml
@@ -38,6 +38,9 @@ properties:
The virtio transport only supports a single device.
items:
- const: arm,scmi-virtio
+ - description: SCMI compliant firmware with OP-TEE transport
+ items:
+ - const: linaro,scmi-optee
interrupts:
description:
@@ -78,11 +81,24 @@ properties:
'#size-cells':
const: 0
+ atomic-threshold-us:
+ description:
+ An optional time value, expressed in microseconds, representing, on this
+ platform, the threshold above which any SCMI command, advertised to have
+ an higher-than-threshold execution latency, should not be considered for
+ atomic mode of operation, even if requested.
+ default: 0
+
arm,smc-id:
$ref: /schemas/types.yaml#/definitions/uint32
description:
SMC id required when using smc or hvc transports
+ linaro,optee-channel-id:
+ $ref: /schemas/types.yaml#/definitions/uint32
+ description:
+ Channel specifier required when using OP-TEE transport.
+
protocol@11:
type: object
properties:
@@ -195,6 +211,12 @@ patternProperties:
minItems: 1
maxItems: 2
+ linaro,optee-channel-id:
+ $ref: /schemas/types.yaml#/definitions/uint32
+ description:
+ Channel specifier required when using OP-TEE transport and
+ protocol has a dedicated communication channel.
+
required:
- reg
@@ -226,6 +248,16 @@ else:
- arm,smc-id
- shmem
+ else:
+ if:
+ properties:
+ compatible:
+ contains:
+ const: linaro,scmi-optee
+ then:
+ required:
+ - linaro,optee-channel-id
+
examples:
- |
firmware {
@@ -240,6 +272,8 @@ examples:
#address-cells = <1>;
#size-cells = <0>;
+ atomic-threshold-us = <10000>;
+
scmi_devpd: protocol@11 {
reg = <0x11>;
#power-domain-cells = <1>;
@@ -340,7 +374,48 @@ examples:
reg = <0x11>;
#power-domain-cells = <1>;
};
+ };
+ };
+
+ - |
+ firmware {
+ scmi {
+ compatible = "linaro,scmi-optee";
+ linaro,optee-channel-id = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ scmi_dvfs1: protocol@13 {
+ reg = <0x13>;
+ linaro,optee-channel-id = <1>;
+ shmem = <&cpu_optee_lpri0>;
+ #clock-cells = <1>;
+ };
+
+ scmi_clk0: protocol@14 {
+ reg = <0x14>;
+ #clock-cells = <1>;
+ };
+ };
+ };
+
+ soc {
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ sram@51000000 {
+ compatible = "mmio-sram";
+ reg = <0x0 0x51000000 0x0 0x10000>;
+
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0 0x0 0x51000000 0x10000>;
+
+ cpu_optee_lpri0: optee-sram-section@0 {
+ compatible = "arm,scmi-shmem";
+ reg = <0x0 0x80>;
+ };
};
};
diff --git a/Documentation/devicetree/bindings/gpio/sifive,gpio.yaml b/Documentation/devicetree/bindings/gpio/sifive,gpio.yaml
index e04349567eeb..427c5873f96a 100644
--- a/Documentation/devicetree/bindings/gpio/sifive,gpio.yaml
+++ b/Documentation/devicetree/bindings/gpio/sifive,gpio.yaml
@@ -7,7 +7,6 @@ $schema: http://devicetree.org/meta-schemas/core.yaml#
title: SiFive GPIO controller
maintainers:
- - Yash Shah <yash.shah@sifive.com>
- Paul Walmsley <paul.walmsley@sifive.com>
properties:
diff --git a/Documentation/devicetree/bindings/gpu/arm,mali-bifrost.yaml b/Documentation/devicetree/bindings/gpu/arm,mali-bifrost.yaml
index 63a08f3f321d..4d6bfae0653c 100644
--- a/Documentation/devicetree/bindings/gpu/arm,mali-bifrost.yaml
+++ b/Documentation/devicetree/bindings/gpu/arm,mali-bifrost.yaml
@@ -159,6 +159,21 @@ allOf:
power-domains:
maxItems: 1
sram-supply: false
+ - if:
+ properties:
+ compatible:
+ contains:
+ const: rockchip,rk3568-mali
+ then:
+ properties:
+ clocks:
+ minItems: 2
+ clock-names:
+ items:
+ - const: gpu
+ - const: bus
+ required:
+ - clock-names
examples:
- |
diff --git a/Documentation/devicetree/bindings/hwmon/adi,adm1275.yaml b/Documentation/devicetree/bindings/hwmon/adi,adm1275.yaml
index 223393d7cafd..ab87f51c5aef 100644
--- a/Documentation/devicetree/bindings/hwmon/adi,adm1275.yaml
+++ b/Documentation/devicetree/bindings/hwmon/adi,adm1275.yaml
@@ -37,6 +37,72 @@ properties:
description:
Shunt resistor value in micro-Ohm.
+ adi,volt-curr-sample-average:
+ description: |
+ Number of samples to be used to report voltage and current values.
+ $ref: /schemas/types.yaml#/definitions/uint32
+ enum: [1, 2, 4, 8, 16, 32, 64, 128]
+
+ adi,power-sample-average:
+ description: |
+ Number of samples to be used to report power values.
+ $ref: /schemas/types.yaml#/definitions/uint32
+ enum: [1, 2, 4, 8, 16, 32, 64, 128]
+
+allOf:
+ - if:
+ properties:
+ compatible:
+ contains:
+ enum:
+ - adi,adm1075
+ - adi,adm1276
+ then:
+ properties:
+ adi,volt-curr-sample-average:
+ default: 128
+ adi,power-sample-average: false
+
+ - if:
+ properties:
+ compatible:
+ contains:
+ enum:
+ - adi,adm1275
+ then:
+ properties:
+ adi,volt-curr-sample-average:
+ default: 16
+ adi,power-sample-average: false
+
+ - if:
+ properties:
+ compatible:
+ contains:
+ enum:
+ - adi,adm1272
+ then:
+ properties:
+ adi,volt-curr-sample-average:
+ default: 128
+ adi,power-sample-average:
+ default: 128
+
+ - if:
+ properties:
+ compatible:
+ contains:
+ enum:
+ - adi,adm1278
+ - adi,adm1293
+ - adi,adm1294
+ then:
+ properties:
+ adi,volt-curr-sample-average:
+ default: 128
+ adi,power-sample-average:
+ default: 1
+
required:
- compatible
- reg
@@ -53,5 +119,7 @@ examples:
compatible = "adi,adm1272";
reg = <0x10>;
shunt-resistor-micro-ohms = <500>;
+ adi,volt-curr-sample-average = <128>;
+ adi,power-sample-average = <128>;
};
};
diff --git a/Documentation/devicetree/bindings/hwmon/national,lm90.yaml b/Documentation/devicetree/bindings/hwmon/national,lm90.yaml
index 6e1d54ff5d5b..30db92977937 100644
--- a/Documentation/devicetree/bindings/hwmon/national,lm90.yaml
+++ b/Documentation/devicetree/bindings/hwmon/national,lm90.yaml
@@ -60,7 +60,6 @@ additionalProperties: false
examples:
- |
- #include <dt-bindings/gpio/tegra-gpio.h>
#include <dt-bindings/interrupt-controller/irq.h>
i2c {
@@ -71,8 +70,7 @@ examples:
compatible = "onnn,nct1008";
reg = <0x4c>;
vcc-supply = <&palmas_ldo6_reg>;
- interrupt-parent = <&gpio>;
- interrupts = <TEGRA_GPIO(O, 4) IRQ_TYPE_LEVEL_LOW>;
+ interrupts = <4 IRQ_TYPE_LEVEL_LOW>;
#thermal-sensor-cells = <1>;
};
};
diff --git a/Documentation/devicetree/bindings/hwmon/ti,tmp464.yaml b/Documentation/devicetree/bindings/hwmon/ti,tmp464.yaml
new file mode 100644
index 000000000000..801ca9ba7d34
--- /dev/null
+++ b/Documentation/devicetree/bindings/hwmon/ti,tmp464.yaml
@@ -0,0 +1,114 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/hwmon/ti,tmp464.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: TMP464 and TMP468 temperature sensors
+
+maintainers:
+ - Agathe Porte <agathe.porte@nokia.com>
+
+description: |
+ ±0.0625°C Remote and Local temperature sensor
+ https://www.ti.com/lit/ds/symlink/tmp464.pdf
+ https://www.ti.com/lit/ds/symlink/tmp468.pdf
+
+properties:
+ compatible:
+ enum:
+ - ti,tmp464
+ - ti,tmp468
+
+ reg:
+ maxItems: 1
+
+ '#address-cells':
+ const: 1
+
+ '#size-cells':
+ const: 0
+
+required:
+ - compatible
+ - reg
+
+additionalProperties: false
+
+patternProperties:
+ "^channel@([0-8])$":
+ type: object
+ description: |
+ Represents channels of the device and their specific configuration.
+
+ properties:
+ reg:
+ description: |
+ The channel number. 0 is local channel, 1-8 are remote channels.
+ items:
+ minimum: 0
+ maximum: 8
+
+ label:
+ description: |
+ A descriptive name for this channel, like "ambient" or "psu".
+
+ ti,n-factor:
+ description: |
+ The value (two's complement) to be programmed in the channel specific N correction register.
+ For remote channels only.
+ $ref: /schemas/types.yaml#/definitions/int32
+ items:
+ minimum: -128
+ maximum: 127
+
+ required:
+ - reg
+
+ additionalProperties: false
+
+examples:
+ - |
+ i2c {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ sensor@4b {
+ compatible = "ti,tmp464";
+ reg = <0x4b>;
+ };
+ };
+ - |
+ i2c {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ sensor@4b {
+ compatible = "ti,tmp464";
+ reg = <0x4b>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ channel@0 {
+ reg = <0x0>;
+ label = "local";
+ };
+
+ channel@1 {
+ reg = <0x1>;
+ ti,n-factor = <(-10)>;
+ label = "external";
+ };
+
+ channel@2 {
+ reg = <0x2>;
+ ti,n-factor = <0x10>;
+ label = "somelabel";
+ };
+
+ channel@3 {
+ reg = <0x3>;
+ status = "disabled";
+ };
+ };
+ };
diff --git a/Documentation/devicetree/bindings/i2c/i2c.txt b/Documentation/devicetree/bindings/i2c/i2c.txt
index b864916e087f..fc3dd7ec0445 100644
--- a/Documentation/devicetree/bindings/i2c/i2c.txt
+++ b/Documentation/devicetree/bindings/i2c/i2c.txt
@@ -95,6 +95,10 @@ wants to support one of the below features, it should adapt these bindings.
- smbus-alert
states that the optional SMBus-Alert feature apply to this bus.
+- mctp-controller
+ indicates that the system is accessible via this bus as an endpoint for
+ MCTP over I2C transport.
+
Required properties (per child device)
--------------------------------------
diff --git a/Documentation/devicetree/bindings/interrupt-controller/amlogic,meson-gpio-intc.txt b/Documentation/devicetree/bindings/interrupt-controller/amlogic,meson-gpio-intc.txt
index 23b18b92c558..bde63f8f090e 100644
--- a/Documentation/devicetree/bindings/interrupt-controller/amlogic,meson-gpio-intc.txt
+++ b/Documentation/devicetree/bindings/interrupt-controller/amlogic,meson-gpio-intc.txt
@@ -18,6 +18,7 @@ Required properties:
"amlogic,meson-g12a-gpio-intc" for G12A SoCs (S905D2, S905X2, S905Y2)
"amlogic,meson-sm1-gpio-intc" for SM1 SoCs (S905D3, S905X3, S905Y3)
"amlogic,meson-a1-gpio-intc" for A1 SoCs (A113L)
+ "amlogic,meson-s4-gpio-intc" for S4 SoCs (S802X2, S905Y4, S805X2G, S905W2)
- reg : Specifies base physical address and size of the registers.
- interrupt-controller : Identifies the node as an interrupt controller.
- #interrupt-cells : Specifies the number of cells needed to encode an
diff --git a/Documentation/devicetree/bindings/interrupt-controller/andestech,ativic32.txt b/Documentation/devicetree/bindings/interrupt-controller/andestech,ativic32.txt
deleted file mode 100644
index f4b4193d830e..000000000000
--- a/Documentation/devicetree/bindings/interrupt-controller/andestech,ativic32.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-* Andestech Internal Vector Interrupt Controller
-
-The Internal Vector Interrupt Controller (IVIC) is a basic interrupt controller
-suitable for a simpler SoC platform not requiring a more sophisticated and
-bigger External Vector Interrupt Controller.
-
-
-Main node required properties:
-
-- compatible : should at least contain "andestech,ativic32".
-- interrupt-controller : Identifies the node as an interrupt controller
-- #interrupt-cells: 1 cells and refer to interrupt-controller/interrupts
-
-Examples:
- intc: interrupt-controller {
- compatible = "andestech,ativic32";
- #interrupt-cells = <1>;
- interrupt-controller;
- };
diff --git a/Documentation/devicetree/bindings/interrupt-controller/apple,aic.yaml b/Documentation/devicetree/bindings/interrupt-controller/apple,aic.yaml
index 97359024709a..85c85b694217 100644
--- a/Documentation/devicetree/bindings/interrupt-controller/apple,aic.yaml
+++ b/Documentation/devicetree/bindings/interrupt-controller/apple,aic.yaml
@@ -56,6 +56,8 @@ properties:
- 1: virtual HV timer
- 2: physical guest timer
- 3: virtual guest timer
+ - 4: 'efficient' CPU PMU
+ - 5: 'performance' CPU PMU
The 3rd cell contains the interrupt flags. This is normally
IRQ_TYPE_LEVEL_HIGH (4).
@@ -68,6 +70,35 @@ properties:
power-domains:
maxItems: 1
+ affinities:
+ type: object
+ additionalProperties: false
+ description:
+ FIQ affinity can be expressed as a single "affinities" node,
+ containing a set of sub-nodes, one per FIQ with a non-default
+ affinity.
+ patternProperties:
+ "^.+-affinity$":
+ type: object
+ additionalProperties: false
+ properties:
+ apple,fiq-index:
+ description:
+ The interrupt number specified as a FIQ, and for which
+ the affinity is not the default.
+ $ref: /schemas/types.yaml#/definitions/uint32
+ maximum: 5
+
+ cpus:
+ $ref: /schemas/types.yaml#/definitions/phandle-array
+ description:
+ Should be a list of phandles to CPU nodes (as described in
+ Documentation/devicetree/bindings/arm/cpus.yaml).
+
+ required:
+ - fiq-index
+ - cpus
+
required:
- compatible
- '#interrupt-cells'
diff --git a/Documentation/devicetree/bindings/interrupt-controller/apple,aic2.yaml b/Documentation/devicetree/bindings/interrupt-controller/apple,aic2.yaml
new file mode 100644
index 000000000000..47a78a167aba
--- /dev/null
+++ b/Documentation/devicetree/bindings/interrupt-controller/apple,aic2.yaml
@@ -0,0 +1,98 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/interrupt-controller/apple,aic2.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Apple Interrupt Controller 2
+
+maintainers:
+ - Hector Martin <marcan@marcan.st>
+
+description: |
+ The Apple Interrupt Controller 2 is a simple interrupt controller present on
+ Apple ARM SoC platforms starting with t600x (M1 Pro and Max).
+
+ It provides the following features:
+
+ - Level-triggered hardware IRQs wired to SoC blocks
+ - Single mask bit per IRQ
+ - Automatic masking on event delivery (auto-ack)
+ - Software triggering (ORed with hw line)
+ - Automatic prioritization (single event/ack register per CPU, lower IRQs =
+ higher priority)
+ - Automatic masking on ack
+ - Support for multiple dies
+
+ This device also represents the FIQ interrupt sources on platforms using AIC,
+ which do not go through a discrete interrupt controller. It also handles
+ FIQ-based Fast IPIs.
+
+properties:
+ compatible:
+ items:
+ - const: apple,t6000-aic
+ - const: apple,aic2
+
+ interrupt-controller: true
+
+ '#interrupt-cells':
+ const: 4
+ description: |
+ The 1st cell contains the interrupt type:
+ - 0: Hardware IRQ
+ - 1: FIQ
+
+ The 2nd cell contains the die ID.
+
+ The next cell contains the interrupt number.
+ - HW IRQs: interrupt number
+ - FIQs:
+ - 0: physical HV timer
+ - 1: virtual HV timer
+ - 2: physical guest timer
+ - 3: virtual guest timer
+
+ The last cell contains the interrupt flags. This is normally
+ IRQ_TYPE_LEVEL_HIGH (4).
+
+ reg:
+ items:
+ - description: Address and size of the main AIC2 registers.
+ - description: Address and size of the AIC2 Event register.
+
+ reg-names:
+ items:
+ - const: core
+ - const: event
+
+ power-domains:
+ maxItems: 1
+
+required:
+ - compatible
+ - '#interrupt-cells'
+ - interrupt-controller
+ - reg
+ - reg-names
+
+additionalProperties: false
+
+allOf:
+ - $ref: /schemas/interrupt-controller.yaml#
+
+examples:
+ - |
+ soc {
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ aic: interrupt-controller@28e100000 {
+ compatible = "apple,t6000-aic", "apple,aic2";
+ #interrupt-cells = <4>;
+ interrupt-controller;
+ reg = <0x2 0x8e100000 0x0 0xc000>,
+ <0x2 0x8e10c000 0x0 0x4>;
+ reg-names = "core", "event";
+ };
+ };
diff --git a/Documentation/devicetree/bindings/interrupt-controller/arm,gic.yaml b/Documentation/devicetree/bindings/interrupt-controller/arm,gic.yaml
index ba282f4c9fd0..62219a5c21c5 100644
--- a/Documentation/devicetree/bindings/interrupt-controller/arm,gic.yaml
+++ b/Documentation/devicetree/bindings/interrupt-controller/arm,gic.yaml
@@ -58,6 +58,7 @@ properties:
- enum:
- nvidia,tegra186-agic
- nvidia,tegra194-agic
+ - nvidia,tegra234-agic
- const: nvidia,tegra210-agic
interrupt-controller: true
diff --git a/Documentation/devicetree/bindings/interrupt-controller/qcom,mpm.yaml b/Documentation/devicetree/bindings/interrupt-controller/qcom,mpm.yaml
new file mode 100644
index 000000000000..509d20c091af
--- /dev/null
+++ b/Documentation/devicetree/bindings/interrupt-controller/qcom,mpm.yaml
@@ -0,0 +1,96 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/interrupt-controller/qcom,mpm.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Qualcom MPM Interrupt Controller
+
+maintainers:
+ - Shawn Guo <shawn.guo@linaro.org>
+
+description:
+ Qualcomm Technologies Inc. SoCs based on the RPM architecture have a
+ MSM Power Manager (MPM) that is in always-on domain. In addition to managing
+ resources during sleep, the hardware also has an interrupt controller that
+ monitors the interrupts when the system is asleep, wakes up the APSS when
+ one of these interrupts occur and replays it to GIC interrupt controller
+ after GIC becomes operational.
+
+allOf:
+ - $ref: /schemas/interrupt-controller.yaml#
+
+properties:
+ compatible:
+ items:
+ - const: qcom,mpm
+
+ reg:
+ maxItems: 1
+ description:
+ Specifies the base address and size of vMPM registers in RPM MSG RAM.
+
+ interrupts:
+ maxItems: 1
+ description:
+ Specify the IRQ used by RPM to wakeup APSS.
+
+ mboxes:
+ maxItems: 1
+ description:
+ Specify the mailbox used to notify RPM for writing vMPM registers.
+
+ interrupt-controller: true
+
+ '#interrupt-cells':
+ const: 2
+ description:
+ The first cell is the MPM pin number for the interrupt, and the second
+ is the trigger type.
+
+ qcom,mpm-pin-count:
+ description:
+ Specify the total MPM pin count that a SoC supports.
+ $ref: /schemas/types.yaml#/definitions/uint32
+
+ qcom,mpm-pin-map:
+ description:
+ A set of MPM pin numbers and the corresponding GIC SPIs.
+ $ref: /schemas/types.yaml#/definitions/uint32-matrix
+ items:
+ items:
+ - description: MPM pin number
+ - description: GIC SPI number for the MPM pin
+
+required:
+ - compatible
+ - reg
+ - interrupts
+ - mboxes
+ - interrupt-controller
+ - '#interrupt-cells'
+ - qcom,mpm-pin-count
+ - qcom,mpm-pin-map
+
+additionalProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/interrupt-controller/arm-gic.h>
+ mpm: interrupt-controller@45f01b8 {
+ compatible = "qcom,mpm";
+ interrupts = <GIC_SPI 197 IRQ_TYPE_EDGE_RISING>;
+ reg = <0x45f01b8 0x1000>;
+ mboxes = <&apcs_glb 1>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ interrupt-parent = <&intc>;
+ qcom,mpm-pin-count = <96>;
+ qcom,mpm-pin-map = <2 275>,
+ <5 296>,
+ <12 422>,
+ <24 79>,
+ <86 183>,
+ <90 260>,
+ <91 260>;
+ };
diff --git a/Documentation/devicetree/bindings/interrupt-controller/renesas,irqc.yaml b/Documentation/devicetree/bindings/interrupt-controller/renesas,irqc.yaml
index 79d0358e2f61..620f01775e42 100644
--- a/Documentation/devicetree/bindings/interrupt-controller/renesas,irqc.yaml
+++ b/Documentation/devicetree/bindings/interrupt-controller/renesas,irqc.yaml
@@ -36,6 +36,7 @@ properties:
- renesas,intc-ex-r8a77980 # R-Car V3H
- renesas,intc-ex-r8a77990 # R-Car E3
- renesas,intc-ex-r8a77995 # R-Car D3
+ - renesas,intc-ex-r8a779a0 # R-Car V3U
- const: renesas,irqc
'#interrupt-cells':
diff --git a/Documentation/devicetree/bindings/interrupt-controller/sifive,plic-1.0.0.yaml b/Documentation/devicetree/bindings/interrupt-controller/sifive,plic-1.0.0.yaml
index 28b6b17fe4b2..27092c6a86c4 100644
--- a/Documentation/devicetree/bindings/interrupt-controller/sifive,plic-1.0.0.yaml
+++ b/Documentation/devicetree/bindings/interrupt-controller/sifive,plic-1.0.0.yaml
@@ -35,6 +35,10 @@ description:
contains a specific memory layout, which is documented in chapter 8 of the
SiFive U5 Coreplex Series Manual <https://static.dev.sifive.com/U54-MC-RVCoreIP.pdf>.
+ The thead,c900-plic is different from sifive,plic-1.0.0 in opensbi, the
+ T-HEAD PLIC implementation requires setting a delegation bit to allow access
+ from S-mode. So add thead,c900-plic to distinguish them.
+
maintainers:
- Sagar Kadam <sagar.kadam@sifive.com>
- Paul Walmsley <paul.walmsley@sifive.com>
@@ -42,12 +46,17 @@ maintainers:
properties:
compatible:
- items:
- - enum:
- - sifive,fu540-c000-plic
- - starfive,jh7100-plic
- - canaan,k210-plic
- - const: sifive,plic-1.0.0
+ oneOf:
+ - items:
+ - enum:
+ - sifive,fu540-c000-plic
+ - starfive,jh7100-plic
+ - canaan,k210-plic
+ - const: sifive,plic-1.0.0
+ - items:
+ - enum:
+ - allwinner,sun20i-d1-plic
+ - const: thead,c900-plic
reg:
maxItems: 1
@@ -62,6 +71,7 @@ properties:
interrupts-extended:
minItems: 1
+ maxItems: 15872
description:
Specifies which contexts are connected to the PLIC, with "-1" specifying
that a context is not present. Each node pointed to should be a
@@ -90,12 +100,11 @@ examples:
#interrupt-cells = <1>;
compatible = "sifive,fu540-c000-plic", "sifive,plic-1.0.0";
interrupt-controller;
- interrupts-extended = <
- &cpu0_intc 11
- &cpu1_intc 11 &cpu1_intc 9
- &cpu2_intc 11 &cpu2_intc 9
- &cpu3_intc 11 &cpu3_intc 9
- &cpu4_intc 11 &cpu4_intc 9>;
+ interrupts-extended = <&cpu0_intc 11>,
+ <&cpu1_intc 11>, <&cpu1_intc 9>,
+ <&cpu2_intc 11>, <&cpu2_intc 9>,
+ <&cpu3_intc 11>, <&cpu3_intc 9>,
+ <&cpu4_intc 11>, <&cpu4_intc 9>;
reg = <0xc000000 0x4000000>;
riscv,ndev = <10>;
};
diff --git a/Documentation/devicetree/bindings/interrupt-controller/st,stm32-exti.yaml b/Documentation/devicetree/bindings/interrupt-controller/st,stm32-exti.yaml
index d19c881b4abc..e44daa09b137 100644
--- a/Documentation/devicetree/bindings/interrupt-controller/st,stm32-exti.yaml
+++ b/Documentation/devicetree/bindings/interrupt-controller/st,stm32-exti.yaml
@@ -20,6 +20,7 @@ properties:
- items:
- enum:
- st,stm32mp1-exti
+ - st,stm32mp13-exti
- const: syscon
"#interrupt-cells":
diff --git a/Documentation/devicetree/bindings/media/amphion,vpu.yaml b/Documentation/devicetree/bindings/media/amphion,vpu.yaml
new file mode 100644
index 000000000000..a9d80eaeeeb6
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/amphion,vpu.yaml
@@ -0,0 +1,180 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/media/amphion,vpu.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Amphion VPU codec IP
+
+maintainers:
+ - Ming Qian <ming.qian@nxp.com>
+ - Shijie Qin <shijie.qin@nxp.com>
+
+description: |-
+ The Amphion MXC video encoder(Windsor) and decoder(Malone) accelerators present
+ on NXP i.MX8Q SoCs.
+
+properties:
+ $nodename:
+ pattern: "^vpu@[0-9a-f]+$"
+
+ compatible:
+ items:
+ - enum:
+ - nxp,imx8qm-vpu
+ - nxp,imx8qxp-vpu
+
+ reg:
+ maxItems: 1
+
+ power-domains:
+ maxItems: 1
+
+ "#address-cells":
+ const: 1
+
+ "#size-cells":
+ const: 1
+
+ ranges: true
+
+patternProperties:
+ "^mailbox@[0-9a-f]+$":
+ description:
+ Each vpu encoder or decoder correspond a MU, which used for communication
+ between driver and firmware. Implement via mailbox on driver.
+ $ref: ../mailbox/fsl,mu.yaml#
+
+
+ "^vpu_core@[0-9a-f]+$":
+ description:
+ Each core correspond a decoder or encoder, need to configure them
+ separately. NXP i.MX8QM SoC has one decoder and two encoder, i.MX8QXP SoC
+ has one decoder and one encoder.
+ type: object
+
+ properties:
+ compatible:
+ items:
+ - enum:
+ - nxp,imx8q-vpu-decoder
+ - nxp,imx8q-vpu-encoder
+
+ reg:
+ maxItems: 1
+
+ power-domains:
+ maxItems: 1
+
+ mbox-names:
+ items:
+ - const: tx0
+ - const: tx1
+ - const: rx
+
+ mboxes:
+ description:
+ List of phandle of 2 MU channels for tx, 1 MU channel for rx.
+ maxItems: 3
+
+ memory-region:
+ description:
+ Phandle to the reserved memory nodes to be associated with the
+ remoteproc device. The reserved memory nodes should be carveout nodes,
+ and should be defined as per the bindings in
+ Documentation/devicetree/bindings/reserved-memory/reserved-memory.txt
+ items:
+ - description: region reserved for firmware image sections.
+ - description: region used for RPC shared memory between firmware and
+ driver.
+
+ required:
+ - compatible
+ - reg
+ - power-domains
+ - mbox-names
+ - mboxes
+ - memory-region
+
+ additionalProperties: false
+
+required:
+ - compatible
+ - reg
+ - power-domains
+
+additionalProperties: false
+
+examples:
+ # Device node example for i.MX8QM platform:
+ - |
+ #include <dt-bindings/firmware/imx/rsrc.h>
+
+ vpu: vpu@2c000000 {
+ compatible = "nxp,imx8qm-vpu";
+ ranges = <0x2c000000 0x2c000000 0x2000000>;
+ reg = <0x2c000000 0x1000000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ power-domains = <&pd IMX_SC_R_VPU>;
+
+ mu_m0: mailbox@2d000000 {
+ compatible = "fsl,imx6sx-mu";
+ reg = <0x2d000000 0x20000>;
+ interrupts = <0 472 4>;
+ #mbox-cells = <2>;
+ power-domains = <&pd IMX_SC_R_VPU_MU_0>;
+ };
+
+ mu1_m0: mailbox@2d020000 {
+ compatible = "fsl,imx6sx-mu";
+ reg = <0x2d020000 0x20000>;
+ interrupts = <0 473 4>;
+ #mbox-cells = <2>;
+ power-domains = <&pd IMX_SC_R_VPU_MU_1>;
+ };
+
+ mu2_m0: mailbox@2d040000 {
+ compatible = "fsl,imx6sx-mu";
+ reg = <0x2d040000 0x20000>;
+ interrupts = <0 474 4>;
+ #mbox-cells = <2>;
+ power-domains = <&pd IMX_SC_R_VPU_MU_2>;
+ };
+
+ vpu_core0: vpu_core@2d080000 {
+ compatible = "nxp,imx8q-vpu-decoder";
+ reg = <0x2d080000 0x10000>;
+ power-domains = <&pd IMX_SC_R_VPU_DEC_0>;
+ mbox-names = "tx0", "tx1", "rx";
+ mboxes = <&mu_m0 0 0>,
+ <&mu_m0 0 1>,
+ <&mu_m0 1 0>;
+ memory-region = <&decoder_boot>, <&decoder_rpc>;
+ };
+
+ vpu_core1: vpu_core@2d090000 {
+ compatible = "nxp,imx8q-vpu-encoder";
+ reg = <0x2d090000 0x10000>;
+ power-domains = <&pd IMX_SC_R_VPU_ENC_0>;
+ mbox-names = "tx0", "tx1", "rx";
+ mboxes = <&mu1_m0 0 0>,
+ <&mu1_m0 0 1>,
+ <&mu1_m0 1 0>;
+ memory-region = <&encoder1_boot>, <&encoder1_rpc>;
+ };
+
+ vpu_core2: vpu_core@2d0a0000 {
+ reg = <0x2d0a0000 0x10000>;
+ compatible = "nxp,imx8q-vpu-encoder";
+ power-domains = <&pd IMX_SC_R_VPU_ENC_1>;
+ mbox-names = "tx0", "tx1", "rx";
+ mboxes = <&mu2_m0 0 0>,
+ <&mu2_m0 0 1>,
+ <&mu2_m0 1 0>;
+ memory-region = <&encoder2_boot>, <&encoder2_rpc>;
+ };
+ };
+
+...
diff --git a/Documentation/devicetree/bindings/media/i2c/hynix,hi846.yaml b/Documentation/devicetree/bindings/media/i2c/hynix,hi846.yaml
index 85a8877c2f38..1e2df8cf2937 100644
--- a/Documentation/devicetree/bindings/media/i2c/hynix,hi846.yaml
+++ b/Documentation/devicetree/bindings/media/i2c/hynix,hi846.yaml
@@ -49,7 +49,8 @@ properties:
description: Definition of the regulator used for the VDDD power supply.
port:
- $ref: /schemas/graph.yaml#/properties/port
+ $ref: /schemas/graph.yaml#/$defs/port-base
+ unevaluatedProperties: false
properties:
endpoint:
@@ -68,8 +69,11 @@ properties:
- const: 1
- const: 2
+ link-frequencies: true
+
required:
- data-lanes
+ - link-frequencies
required:
- compatible
diff --git a/Documentation/devicetree/bindings/media/i2c/isil,isl79987.yaml b/Documentation/devicetree/bindings/media/i2c/isil,isl79987.yaml
new file mode 100644
index 000000000000..034a6e3466af
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/i2c/isil,isl79987.yaml
@@ -0,0 +1,113 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/media/i2c/isil,isl79987.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Intersil ISL79987 Analog to MIPI CSI-2 decoder
+
+maintainers:
+ - Michael Tretter <m.tretter@pengutronix.de>
+ - Marek Vasut <marex@denx.de>
+
+description:
+ The Intersil ISL79987 is an analog to MIPI CSI-2 decoder which is capable of
+ receiving up to four analog stream and multiplexing them into up to four MIPI
+ CSI-2 virtual channels, using one MIPI clock lane and 1/2 data lanes.
+
+properties:
+ compatible:
+ enum:
+ - isil,isl79987
+
+ reg:
+ maxItems: 1
+
+ reset-gpios:
+ maxItems: 1
+ description:
+ A GPIO spec for the RSTB pin (active high)
+
+ powerdown-gpios:
+ maxItems: 1
+ description:
+ A GPIO spec for the Power Down pin (active high)
+
+ ports:
+ $ref: /schemas/graph.yaml#/properties/ports
+ properties:
+ port@0:
+ $ref: /schemas/graph.yaml#/$defs/port-base
+ unevaluatedProperties: false
+ description: Output port
+
+ properties:
+ endpoint:
+ $ref: /schemas/media/video-interfaces.yaml#
+ unevaluatedProperties: false
+
+ properties:
+ data-lanes:
+ minItems: 1
+ maxItems: 2
+
+ required:
+ - data-lanes
+
+ patternProperties:
+ "^port@[1-4]$":
+ $ref: /schemas/graph.yaml#/properties/port
+ description: Input ports
+
+ required:
+ - port@0
+
+additionalProperties: false
+
+required:
+ - compatible
+ - reg
+ - ports
+
+examples:
+ - |
+ #include <dt-bindings/gpio/gpio.h>
+
+ i2c {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ isl7998x_mipi@44 {
+ compatible = "isil,isl79987";
+ reg = <0x44>;
+ powerdown-gpios = <&gpio3 27 GPIO_ACTIVE_HIGH>;
+ reset-gpios = <&gpio3 28 GPIO_ACTIVE_HIGH>;
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+ isl79987_out: endpoint {
+ remote-endpoint = <&mipi_csi2_in>;
+ data-lanes = <1 2>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+ endpoint {
+ remote-endpoint = <&camera_0>;
+ };
+ };
+
+ port@2 {
+ reg = <2>;
+ endpoint {
+ remote-endpoint = <&camera_1>;
+ };
+ };
+ };
+ };
+ };
diff --git a/Documentation/devicetree/bindings/media/i2c/maxim,max9286.yaml b/Documentation/devicetree/bindings/media/i2c/maxim,max9286.yaml
index 02f656e78700..90315e217003 100644
--- a/Documentation/devicetree/bindings/media/i2c/maxim,max9286.yaml
+++ b/Documentation/devicetree/bindings/media/i2c/maxim,max9286.yaml
@@ -70,6 +70,28 @@ properties:
a remote serializer whose high-threshold noise immunity is not enabled
is 100000 micro volts
+ maxim,gpio-poc:
+ $ref: '/schemas/types.yaml#/definitions/uint32-array'
+ minItems: 2
+ maxItems: 2
+ description: |
+ Index of the MAX9286 gpio output line (0 or 1) that controls Power over
+ Coax to the cameras and its associated polarity flag.
+
+ The property accepts an array of two unsigned integers, the first being
+ the gpio line index (0 or 1) and the second being the gpio line polarity
+ flag (GPIO_ACTIVE_HIGH or GPIO_ACTIVE_LOW) as defined in
+ <include/dt-bindings/gpio/gpio.h>.
+
+ When the remote cameras power is controlled by one of the MAX9286 gpio
+ lines, this property has to be used to specify which line among the two
+ available ones controls the remote camera power enablement.
+
+ When this property is used it is not possible to register a gpio
+ controller as the gpio lines are controlled directly by the MAX9286 and
+ not available for consumers, nor the 'poc-supply' property should be
+ specified.
+
ports:
$ref: /schemas/graph.yaml#/properties/ports
@@ -165,7 +187,16 @@ required:
- reg
- ports
- i2c-mux
- - gpio-controller
+
+# If 'maxim,gpio-poc' is present, then 'poc-supply' and 'gpio-controller'
+# are not allowed.
+if:
+ required:
+ - maxim,gpio-poc
+then:
+ properties:
+ poc-supply: false
+ gpio-controller: false
additionalProperties: false
@@ -174,140 +205,174 @@ examples:
#include <dt-bindings/gpio/gpio.h>
i2c@e66d8000 {
- #address-cells = <1>;
- #size-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
- reg = <0 0xe66d8000>;
+ reg = <0 0xe66d8000>;
- gmsl-deserializer@2c {
- compatible = "maxim,max9286";
- reg = <0x2c>;
- poc-supply = <&camera_poc_12v>;
- enable-gpios = <&gpio 13 GPIO_ACTIVE_HIGH>;
+ gmsl-deserializer@2c {
+ compatible = "maxim,max9286";
+ reg = <0x2c>;
+ poc-supply = <&camera_poc_12v>;
+ enable-gpios = <&gpio 13 GPIO_ACTIVE_HIGH>;
- gpio-controller;
- #gpio-cells = <2>;
+ gpio-controller;
+ #gpio-cells = <2>;
- maxim,reverse-channel-microvolt = <170000>;
+ maxim,reverse-channel-microvolt = <170000>;
- ports {
- #address-cells = <1>;
- #size-cells = <0>;
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
- port@0 {
- reg = <0>;
+ port@0 {
+ reg = <0>;
- max9286_in0: endpoint {
- remote-endpoint = <&rdacm20_out0>;
- };
- };
+ max9286_in0: endpoint {
+ remote-endpoint = <&rdacm20_out0>;
+ };
+ };
- port@1 {
- reg = <1>;
+ port@1 {
+ reg = <1>;
- max9286_in1: endpoint {
- remote-endpoint = <&rdacm20_out1>;
- };
- };
+ max9286_in1: endpoint {
+ remote-endpoint = <&rdacm20_out1>;
+ };
+ };
- port@2 {
- reg = <2>;
+ port@2 {
+ reg = <2>;
- max9286_in2: endpoint {
- remote-endpoint = <&rdacm20_out2>;
- };
- };
+ max9286_in2: endpoint {
+ remote-endpoint = <&rdacm20_out2>;
+ };
+ };
- port@3 {
- reg = <3>;
+ port@3 {
+ reg = <3>;
- max9286_in3: endpoint {
- remote-endpoint = <&rdacm20_out3>;
- };
- };
+ max9286_in3: endpoint {
+ remote-endpoint = <&rdacm20_out3>;
+ };
+ };
- port@4 {
- reg = <4>;
+ port@4 {
+ reg = <4>;
- max9286_out: endpoint {
- data-lanes = <1 2 3 4>;
- remote-endpoint = <&csi40_in>;
+ max9286_out: endpoint {
+ data-lanes = <1 2 3 4>;
+ remote-endpoint = <&csi40_in>;
+ };
+ };
};
- };
- };
- i2c-mux {
- #address-cells = <1>;
- #size-cells = <0>;
+ i2c-mux {
+ #address-cells = <1>;
+ #size-cells = <0>;
- i2c@0 {
- #address-cells = <1>;
- #size-cells = <0>;
- reg = <0>;
+ i2c@0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0>;
- camera@51 {
- compatible = "imi,rdacm20";
- reg = <0x51>, <0x61>;
+ camera@51 {
+ compatible = "imi,rdacm20";
+ reg = <0x51>, <0x61>;
- port {
- rdacm20_out0: endpoint {
- remote-endpoint = <&max9286_in0>;
- };
- };
+ port {
+ rdacm20_out0: endpoint {
+ remote-endpoint = <&max9286_in0>;
+ };
+ };
- };
- };
+ };
+ };
- i2c@1 {
- #address-cells = <1>;
- #size-cells = <0>;
- reg = <1>;
+ i2c@1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <1>;
+
+ camera@52 {
+ compatible = "imi,rdacm20";
+ reg = <0x52>, <0x62>;
+
+ port {
+ rdacm20_out1: endpoint {
+ remote-endpoint = <&max9286_in1>;
+ };
+ };
+ };
+ };
- camera@52 {
- compatible = "imi,rdacm20";
- reg = <0x52>, <0x62>;
+ i2c@2 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <2>;
+
+ camera@53 {
+ compatible = "imi,rdacm20";
+ reg = <0x53>, <0x63>;
+
+ port {
+ rdacm20_out2: endpoint {
+ remote-endpoint = <&max9286_in2>;
+ };
+ };
+ };
+ };
- port {
- rdacm20_out1: endpoint {
- remote-endpoint = <&max9286_in1>;
+ i2c@3 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <3>;
+
+ camera@54 {
+ compatible = "imi,rdacm20";
+ reg = <0x54>, <0x64>;
+
+ port {
+ rdacm20_out3: endpoint {
+ remote-endpoint = <&max9286_in3>;
+ };
+ };
+ };
};
- };
};
- };
-
- i2c@2 {
- #address-cells = <1>;
- #size-cells = <0>;
- reg = <2>;
-
- camera@53 {
- compatible = "imi,rdacm20";
- reg = <0x53>, <0x63>;
+ };
- port {
- rdacm20_out2: endpoint {
- remote-endpoint = <&max9286_in2>;
+ /*
+ * Example of a deserializer that controls the camera Power over Coax
+ * through one of its gpio lines.
+ */
+ gmsl-deserializer@6c {
+ compatible = "maxim,max9286";
+ reg = <0x6c>;
+ enable-gpios = <&gpio 14 GPIO_ACTIVE_HIGH>;
+
+ /*
+ * The remote camera power is controlled by MAX9286 GPIO line #0.
+ * No 'poc-supply' nor 'gpio-controller' are specified.
+ */
+ maxim,gpio-poc = <0 GPIO_ACTIVE_LOW>;
+
+ /*
+ * Do not describe connections as they're the same as in the previous
+ * example.
+ */
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@4 {
+ reg = <4>;
};
- };
};
- };
- i2c@3 {
- #address-cells = <1>;
- #size-cells = <0>;
- reg = <3>;
-
- camera@54 {
- compatible = "imi,rdacm20";
- reg = <0x54>, <0x64>;
-
- port {
- rdacm20_out3: endpoint {
- remote-endpoint = <&max9286_in3>;
- };
- };
+ i2c-mux {
+ #address-cells = <1>;
+ #size-cells = <0>;
};
- };
};
- };
};
diff --git a/Documentation/devicetree/bindings/media/mediatek,vcodec-decoder.yaml b/Documentation/devicetree/bindings/media/mediatek,vcodec-decoder.yaml
new file mode 100644
index 000000000000..9b179bb44dfb
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/mediatek,vcodec-decoder.yaml
@@ -0,0 +1,169 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/media/mediatek,vcodec-decoder.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Mediatek Video Decode Accelerator
+
+maintainers:
+ - Yunfei Dong <yunfei.dong@mediatek.com>
+
+description: |+
+ Mediatek Video Decode is the video decode hardware present in Mediatek
+ SoCs which supports high resolution decoding functionalities.
+
+properties:
+ compatible:
+ enum:
+ - mediatek,mt8173-vcodec-dec
+ - mediatek,mt8183-vcodec-dec
+
+ reg:
+ maxItems: 12
+
+ interrupts:
+ maxItems: 1
+
+ clocks:
+ maxItems: 8
+
+ clock-names:
+ items:
+ - const: vcodecpll
+ - const: univpll_d2
+ - const: clk_cci400_sel
+ - const: vdec_sel
+ - const: vdecpll
+ - const: vencpll
+ - const: venc_lt_sel
+ - const: vdec_bus_clk_src
+
+ assigned-clocks: true
+
+ assigned-clock-parents: true
+
+ assigned-clock-rates: true
+
+ power-domains:
+ maxItems: 1
+
+ iommus:
+ minItems: 1
+ maxItems: 32
+ description: |
+ List of the hardware port in respective IOMMU block for current Socs.
+ Refer to bindings/iommu/mediatek,iommu.yaml.
+
+ dma-ranges:
+ maxItems: 1
+ description: |
+ Describes the physical address space of IOMMU maps to memory.
+
+ mediatek,vpu:
+ $ref: /schemas/types.yaml#/definitions/phandle
+ maxItems: 1
+ description:
+ Describes point to vpu.
+
+ mediatek,scp:
+ $ref: /schemas/types.yaml#/definitions/phandle
+ maxItems: 1
+ description:
+ Describes point to scp.
+
+required:
+ - compatible
+ - reg
+ - interrupts
+ - clocks
+ - clock-names
+ - iommus
+ - assigned-clocks
+ - assigned-clock-parents
+
+allOf:
+ - if:
+ properties:
+ compatible:
+ contains:
+ enum:
+ - mediatek,mt8183-vcodec-dec
+
+ then:
+ required:
+ - mediatek,scp
+
+ - if:
+ properties:
+ compatible:
+ contains:
+ enum:
+ - mediatek,mt8173-vcodec-dec
+
+ then:
+ required:
+ - mediatek,vpu
+
+additionalProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/interrupt-controller/arm-gic.h>
+ #include <dt-bindings/clock/mt8173-clk.h>
+ #include <dt-bindings/memory/mt8173-larb-port.h>
+ #include <dt-bindings/interrupt-controller/irq.h>
+ #include <dt-bindings/power/mt8173-power.h>
+
+ vcodec_dec: vcodec@16000000 {
+ compatible = "mediatek,mt8173-vcodec-dec";
+ reg = <0x16000000 0x100>, /*VDEC_SYS*/
+ <0x16020000 0x1000>, /*VDEC_MISC*/
+ <0x16021000 0x800>, /*VDEC_LD*/
+ <0x16021800 0x800>, /*VDEC_TOP*/
+ <0x16022000 0x1000>, /*VDEC_CM*/
+ <0x16023000 0x1000>, /*VDEC_AD*/
+ <0x16024000 0x1000>, /*VDEC_AV*/
+ <0x16025000 0x1000>, /*VDEC_PP*/
+ <0x16026800 0x800>, /*VP8_VD*/
+ <0x16027000 0x800>, /*VP6_VD*/
+ <0x16027800 0x800>, /*VP8_VL*/
+ <0x16028400 0x400>; /*VP9_VD*/
+ interrupts = <GIC_SPI 204 IRQ_TYPE_LEVEL_LOW>;
+ iommus = <&iommu M4U_PORT_HW_VDEC_MC_EXT>,
+ <&iommu M4U_PORT_HW_VDEC_PP_EXT>,
+ <&iommu M4U_PORT_HW_VDEC_AVC_MV_EXT>,
+ <&iommu M4U_PORT_HW_VDEC_PRED_RD_EXT>,
+ <&iommu M4U_PORT_HW_VDEC_PRED_WR_EXT>,
+ <&iommu M4U_PORT_HW_VDEC_UFO_EXT>,
+ <&iommu M4U_PORT_HW_VDEC_VLD_EXT>,
+ <&iommu M4U_PORT_HW_VDEC_VLD2_EXT>;
+ mediatek,vpu = <&vpu>;
+ power-domains = <&scpsys MT8173_POWER_DOMAIN_VDEC>;
+ clocks = <&apmixedsys CLK_APMIXED_VCODECPLL>,
+ <&topckgen CLK_TOP_UNIVPLL_D2>,
+ <&topckgen CLK_TOP_CCI400_SEL>,
+ <&topckgen CLK_TOP_VDEC_SEL>,
+ <&topckgen CLK_TOP_VCODECPLL>,
+ <&apmixedsys CLK_APMIXED_VENCPLL>,
+ <&topckgen CLK_TOP_VENC_LT_SEL>,
+ <&topckgen CLK_TOP_VCODECPLL_370P5>;
+ clock-names = "vcodecpll",
+ "univpll_d2",
+ "clk_cci400_sel",
+ "vdec_sel",
+ "vdecpll",
+ "vencpll",
+ "venc_lt_sel",
+ "vdec_bus_clk_src";
+ assigned-clocks = <&topckgen CLK_TOP_VENC_LT_SEL>,
+ <&topckgen CLK_TOP_CCI400_SEL>,
+ <&topckgen CLK_TOP_VDEC_SEL>,
+ <&apmixedsys CLK_APMIXED_VCODECPLL>,
+ <&apmixedsys CLK_APMIXED_VENCPLL>;
+ assigned-clock-parents = <&topckgen CLK_TOP_VCODECPLL_370P5>,
+ <&topckgen CLK_TOP_UNIVPLL_D2>,
+ <&topckgen CLK_TOP_VCODECPLL>;
+ assigned-clock-rates = <0>, <0>, <0>, <1482000000>, <800000000>;
+ };
diff --git a/Documentation/devicetree/bindings/media/mediatek,vcodec-encoder.yaml b/Documentation/devicetree/bindings/media/mediatek,vcodec-encoder.yaml
new file mode 100644
index 000000000000..e7b65a91c92c
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/mediatek,vcodec-encoder.yaml
@@ -0,0 +1,179 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/media/mediatek,vcodec-encoder.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Mediatek Video Encode Accelerator
+
+maintainers:
+ - Yunfei Dong <yunfei.dong@mediatek.com>
+
+description: |+
+ Mediatek Video Encode is the video encode hardware present in Mediatek
+ SoCs which supports high resolution encoding functionalities.
+
+properties:
+ compatible:
+ enum:
+ - mediatek,mt8173-vcodec-enc-vp8
+ - mediatek,mt8173-vcodec-enc
+ - mediatek,mt8183-vcodec-enc
+ - mediatek,mt8192-vcodec-enc
+ - mediatek,mt8195-vcodec-enc
+
+ reg:
+ maxItems: 1
+
+ interrupts:
+ maxItems: 1
+
+ clocks:
+ minItems: 1
+ maxItems: 5
+
+ clock-names:
+ minItems: 1
+ maxItems: 5
+
+ assigned-clocks: true
+
+ assigned-clock-parents: true
+
+ iommus:
+ minItems: 1
+ maxItems: 32
+ description: |
+ List of the hardware port in respective IOMMU block for current Socs.
+ Refer to bindings/iommu/mediatek,iommu.yaml.
+
+ dma-ranges:
+ maxItems: 1
+ description: |
+ Describes the physical address space of IOMMU maps to memory.
+
+ mediatek,vpu:
+ $ref: /schemas/types.yaml#/definitions/phandle
+ maxItems: 1
+ description:
+ Describes point to vpu.
+
+ mediatek,scp:
+ $ref: /schemas/types.yaml#/definitions/phandle
+ maxItems: 1
+ description:
+ Describes point to scp.
+
+required:
+ - compatible
+ - reg
+ - interrupts
+ - clocks
+ - clock-names
+ - iommus
+ - assigned-clocks
+ - assigned-clock-parents
+
+allOf:
+ - if:
+ properties:
+ compatible:
+ contains:
+ enum:
+ - mediatek,mt8183-vcodec-enc
+ - mediatek,mt8192-vcodec-enc
+
+ then:
+ required:
+ - mediatek,scp
+
+ - if:
+ properties:
+ compatible:
+ contains:
+ enum:
+ - mediatek,mt8173-vcodec-enc-vp8
+ - mediatek,mt8173-vcodec-enc
+
+ then:
+ required:
+ - mediatek,vpu
+
+ - if:
+ properties:
+ compatible:
+ enum:
+ - mediatek,mt8173-vcodec-enc
+ - mediatek,mt8192-vcodec-enc
+ - mediatek,mt8173-vcodec-enc
+
+ then:
+ properties:
+ clock:
+ items:
+ minItems: 1
+ maxItems: 1
+ clock-names:
+ items:
+ - const: venc_sel
+ else: # for vp8 hw decoder
+ properties:
+ clock:
+ items:
+ minItems: 1
+ maxItems: 1
+ clock-names:
+ items:
+ - const: venc_lt_sel
+
+additionalProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/interrupt-controller/arm-gic.h>
+ #include <dt-bindings/clock/mt8173-clk.h>
+ #include <dt-bindings/memory/mt8173-larb-port.h>
+ #include <dt-bindings/interrupt-controller/irq.h>
+
+ vcodec_enc_avc: vcodec@18002000 {
+ compatible = "mediatek,mt8173-vcodec-enc";
+ reg = <0x18002000 0x1000>;
+ interrupts = <GIC_SPI 198 IRQ_TYPE_LEVEL_LOW>;
+ iommus = <&iommu M4U_PORT_VENC_RCPU>,
+ <&iommu M4U_PORT_VENC_REC>,
+ <&iommu M4U_PORT_VENC_BSDMA>,
+ <&iommu M4U_PORT_VENC_SV_COMV>,
+ <&iommu M4U_PORT_VENC_RD_COMV>,
+ <&iommu M4U_PORT_VENC_CUR_LUMA>,
+ <&iommu M4U_PORT_VENC_CUR_CHROMA>,
+ <&iommu M4U_PORT_VENC_REF_LUMA>,
+ <&iommu M4U_PORT_VENC_REF_CHROMA>,
+ <&iommu M4U_PORT_VENC_NBM_RDMA>,
+ <&iommu M4U_PORT_VENC_NBM_WDMA>;
+ mediatek,vpu = <&vpu>;
+ clocks = <&topckgen CLK_TOP_VENC_SEL>;
+ clock-names = "venc_sel";
+ assigned-clocks = <&topckgen CLK_TOP_VENC_SEL>;
+ assigned-clock-parents = <&topckgen CLK_TOP_VCODECPLL>;
+ };
+
+ vcodec_enc_vp8: vcodec@19002000 {
+ compatible = "mediatek,mt8173-vcodec-enc-vp8";
+ reg = <0x19002000 0x1000>; /* VENC_LT_SYS */
+ interrupts = <GIC_SPI 202 IRQ_TYPE_LEVEL_LOW>;
+ iommus = <&iommu M4U_PORT_VENC_RCPU_SET2>,
+ <&iommu M4U_PORT_VENC_REC_FRM_SET2>,
+ <&iommu M4U_PORT_VENC_BSDMA_SET2>,
+ <&iommu M4U_PORT_VENC_SV_COMA_SET2>,
+ <&iommu M4U_PORT_VENC_RD_COMA_SET2>,
+ <&iommu M4U_PORT_VENC_CUR_LUMA_SET2>,
+ <&iommu M4U_PORT_VENC_CUR_CHROMA_SET2>,
+ <&iommu M4U_PORT_VENC_REF_LUMA_SET2>,
+ <&iommu M4U_PORT_VENC_REC_CHROMA_SET2>;
+ mediatek,vpu = <&vpu>;
+ clocks = <&topckgen CLK_TOP_VENC_LT_SEL>;
+ clock-names = "venc_lt_sel";
+ assigned-clocks = <&topckgen CLK_TOP_VENC_LT_SEL>;
+ assigned-clock-parents = <&topckgen CLK_TOP_VCODECPLL_370P5>;
+ };
diff --git a/Documentation/devicetree/bindings/media/mediatek,vcodec-subdev-decoder.yaml b/Documentation/devicetree/bindings/media/mediatek,vcodec-subdev-decoder.yaml
new file mode 100644
index 000000000000..d587fc3e39fb
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/mediatek,vcodec-subdev-decoder.yaml
@@ -0,0 +1,265 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+
+%YAML 1.2
+---
+$id: "http://devicetree.org/schemas/media/mediatek,vcodec-subdev-decoder.yaml#"
+$schema: "http://devicetree.org/meta-schemas/core.yaml#"
+
+title: Mediatek Video Decode Accelerator With Multi Hardware
+
+maintainers:
+ - Yunfei Dong <yunfei.dong@mediatek.com>
+
+description: |
+ Mediatek Video Decode is the video decode hardware present in Mediatek
+ SoCs which supports high resolution decoding functionalities. Required
+ parent and child device node.
+
+ About the Decoder Hardware Block Diagram, please check below:
+
+ +---------------------------------+------------------------------------+
+ | | |
+ | input -> lat HW -> lat buffer --|--> lat buffer -> core HW -> output |
+ | || | || |
+ +------------||-------------------+---------------------||-------------+
+ lat workqueue | core workqueue <parent>
+ -------------||-----------------------------------------||------------------
+ || || <child>
+ \/ <----------------HW index-------------->\/
+ +------------------------------------------------------+
+ | enable/disable |
+ | clk power irq iommu |
+ | (lat/lat soc/core0/core1) |
+ +------------------------------------------------------+
+
+ As above, there are parent and child devices, child mean each hardware. The child device
+ controls the information of each hardware independent which include clk/power/irq.
+
+ There are two workqueues in parent device: lat workqueue and core workqueue. They are used
+ to lat and core hardware deocder. Lat workqueue need to get input bitstream and lat buffer,
+ then enable lat to decode, writing the result to lat buffer, dislabe hardware when lat decode
+ done. Core workqueue need to get lat buffer and output buffer, then enable core to decode,
+ writing the result to output buffer, disable hardware when core decode done. These two
+ hardwares will decode each frame cyclically.
+
+ For the smi common may not the same for each hardware, can't combine all hardware in one node,
+ or leading to iommu fault when access dram data.
+
+properties:
+ compatible:
+ const: mediatek,mt8192-vcodec-dec
+
+ reg:
+ maxItems: 1
+
+ iommus:
+ minItems: 1
+ maxItems: 32
+ description: |
+ List of the hardware port in respective IOMMU block for current Socs.
+ Refer to bindings/iommu/mediatek,iommu.yaml.
+
+ mediatek,scp:
+ $ref: /schemas/types.yaml#/definitions/phandle
+ maxItems: 1
+ description: |
+ The node of system control processor (SCP), using
+ the remoteproc & rpmsg framework.
+
+ dma-ranges:
+ maxItems: 1
+ description: |
+ Describes the physical address space of IOMMU maps to memory.
+
+ "#address-cells":
+ const: 1
+
+ "#size-cells":
+ const: 1
+
+ ranges: true
+
+# Required child node:
+patternProperties:
+ '^vcodec-lat@[0-9a-f]+$':
+ type: object
+
+ properties:
+ compatible:
+ const: mediatek,mtk-vcodec-lat
+
+ reg:
+ maxItems: 1
+
+ interrupts:
+ maxItems: 1
+
+ iommus:
+ minItems: 1
+ maxItems: 32
+ description: |
+ List of the hardware port in respective IOMMU block for current Socs.
+ Refer to bindings/iommu/mediatek,iommu.yaml.
+
+ clocks:
+ maxItems: 5
+
+ clock-names:
+ items:
+ - const: sel
+ - const: soc-vdec
+ - const: soc-lat
+ - const: vdec
+ - const: top
+
+ assigned-clocks:
+ maxItems: 1
+
+ assigned-clock-parents:
+ maxItems: 1
+
+ power-domains:
+ maxItems: 1
+
+ required:
+ - compatible
+ - reg
+ - interrupts
+ - iommus
+ - clocks
+ - clock-names
+ - assigned-clocks
+ - assigned-clock-parents
+ - power-domains
+
+ additionalProperties: false
+
+ '^vcodec-core@[0-9a-f]+$':
+ type: object
+
+ properties:
+ compatible:
+ const: mediatek,mtk-vcodec-core
+
+ reg:
+ maxItems: 1
+
+ interrupts:
+ maxItems: 1
+
+ iommus:
+ minItems: 1
+ maxItems: 32
+ description: |
+ List of the hardware port in respective IOMMU block for current Socs.
+ Refer to bindings/iommu/mediatek,iommu.yaml.
+
+ clocks:
+ maxItems: 5
+
+ clock-names:
+ items:
+ - const: sel
+ - const: soc-vdec
+ - const: soc-lat
+ - const: vdec
+ - const: top
+
+ assigned-clocks:
+ maxItems: 1
+
+ assigned-clock-parents:
+ maxItems: 1
+
+ power-domains:
+ maxItems: 1
+
+ required:
+ - compatible
+ - reg
+ - interrupts
+ - iommus
+ - clocks
+ - clock-names
+ - assigned-clocks
+ - assigned-clock-parents
+ - power-domains
+
+ additionalProperties: false
+
+required:
+ - compatible
+ - reg
+ - iommus
+ - mediatek,scp
+ - dma-ranges
+ - ranges
+
+additionalProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/interrupt-controller/arm-gic.h>
+ #include <dt-bindings/memory/mt8192-larb-port.h>
+ #include <dt-bindings/interrupt-controller/irq.h>
+ #include <dt-bindings/clock/mt8192-clk.h>
+ #include <dt-bindings/power/mt8192-power.h>
+
+ video-codec@16000000 {
+ compatible = "mediatek,mt8192-vcodec-dec";
+ mediatek,scp = <&scp>;
+ iommus = <&iommu0 M4U_PORT_L4_VDEC_MC_EXT>;
+ dma-ranges = <0x1 0x0 0x0 0x40000000 0x0 0xfff00000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0 0x16000000 0x40000>;
+ reg = <0x16000000 0x1000>; /* VDEC_SYS */
+ vcodec-lat@10000 {
+ compatible = "mediatek,mtk-vcodec-lat";
+ reg = <0x10000 0x800>;
+ interrupts = <GIC_SPI 426 IRQ_TYPE_LEVEL_HIGH 0>;
+ iommus = <&iommu0 M4U_PORT_L5_VDEC_LAT0_VLD_EXT>,
+ <&iommu0 M4U_PORT_L5_VDEC_LAT0_VLD2_EXT>,
+ <&iommu0 M4U_PORT_L5_VDEC_LAT0_AVC_MV_EXT>,
+ <&iommu0 M4U_PORT_L5_VDEC_LAT0_PRED_RD_EXT>,
+ <&iommu0 M4U_PORT_L5_VDEC_LAT0_TILE_EXT>,
+ <&iommu0 M4U_PORT_L5_VDEC_LAT0_WDMA_EXT>,
+ <&iommu0 M4U_PORT_L5_VDEC_LAT0_RG_CTRL_DMA_EXT>,
+ <&iommu0 M4U_PORT_L5_VDEC_UFO_ENC_EXT>;
+ clocks = <&topckgen CLK_TOP_VDEC_SEL>,
+ <&vdecsys_soc CLK_VDEC_SOC_VDEC>,
+ <&vdecsys_soc CLK_VDEC_SOC_LAT>,
+ <&vdecsys_soc CLK_VDEC_SOC_LARB1>,
+ <&topckgen CLK_TOP_MAINPLL_D4>;
+ clock-names = "sel", "soc-vdec", "soc-lat", "vdec", "top";
+ assigned-clocks = <&topckgen CLK_TOP_VDEC_SEL>;
+ assigned-clock-parents = <&topckgen CLK_TOP_MAINPLL_D4>;
+ power-domains = <&spm MT8192_POWER_DOMAIN_VDEC>;
+ };
+
+ vcodec-core@25000 {
+ compatible = "mediatek,mtk-vcodec-core";
+ reg = <0x25000 0x1000>;
+ interrupts = <GIC_SPI 425 IRQ_TYPE_LEVEL_HIGH 0>;
+ iommus = <&iommu0 M4U_PORT_L4_VDEC_MC_EXT>,
+ <&iommu0 M4U_PORT_L4_VDEC_UFO_EXT>,
+ <&iommu0 M4U_PORT_L4_VDEC_PP_EXT>,
+ <&iommu0 M4U_PORT_L4_VDEC_PRED_RD_EXT>,
+ <&iommu0 M4U_PORT_L4_VDEC_PRED_WR_EXT>,
+ <&iommu0 M4U_PORT_L4_VDEC_PPWRAP_EXT>,
+ <&iommu0 M4U_PORT_L4_VDEC_TILE_EXT>,
+ <&iommu0 M4U_PORT_L4_VDEC_VLD_EXT>,
+ <&iommu0 M4U_PORT_L4_VDEC_VLD2_EXT>,
+ <&iommu0 M4U_PORT_L4_VDEC_AVC_MV_EXT>,
+ <&iommu0 M4U_PORT_L4_VDEC_RG_CTRL_DMA_EXT>;
+ clocks = <&topckgen CLK_TOP_VDEC_SEL>,
+ <&vdecsys CLK_VDEC_VDEC>,
+ <&vdecsys CLK_VDEC_LAT>,
+ <&vdecsys CLK_VDEC_LARB1>,
+ <&topckgen CLK_TOP_MAINPLL_D4>;
+ clock-names = "sel", "soc-vdec", "soc-lat", "vdec", "top";
+ assigned-clocks = <&topckgen CLK_TOP_VDEC_SEL>;
+ assigned-clock-parents = <&topckgen CLK_TOP_MAINPLL_D4>;
+ power-domains = <&spm MT8192_POWER_DOMAIN_VDEC2>;
+ };
+ };
diff --git a/Documentation/devicetree/bindings/media/mediatek-jpeg-decoder.txt b/Documentation/devicetree/bindings/media/mediatek-jpeg-decoder.txt
deleted file mode 100644
index 39c1028b2dfb..000000000000
--- a/Documentation/devicetree/bindings/media/mediatek-jpeg-decoder.txt
+++ /dev/null
@@ -1,38 +0,0 @@
-* Mediatek JPEG Decoder
-
-Mediatek JPEG Decoder is the JPEG decode hardware present in Mediatek SoCs
-
-Required properties:
-- compatible : must be one of the following string:
- "mediatek,mt8173-jpgdec"
- "mediatek,mt7623-jpgdec", "mediatek,mt2701-jpgdec"
- "mediatek,mt2701-jpgdec"
-- reg : physical base address of the jpeg decoder registers and length of
- memory mapped region.
-- interrupts : interrupt number to the interrupt controller.
-- clocks: device clocks, see
- Documentation/devicetree/bindings/clock/clock-bindings.txt for details.
-- clock-names: must contain "jpgdec-smi" and "jpgdec".
-- power-domains: a phandle to the power domain, see
- Documentation/devicetree/bindings/power/power_domain.txt for details.
-- mediatek,larb: must contain the local arbiters in the current Socs, see
- Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.yaml
- for details.
-- iommus: should point to the respective IOMMU block with master port as
- argument, see Documentation/devicetree/bindings/iommu/mediatek,iommu.yaml
- for details.
-
-Example:
- jpegdec: jpegdec@15004000 {
- compatible = "mediatek,mt2701-jpgdec";
- reg = <0 0x15004000 0 0x1000>;
- interrupts = <GIC_SPI 143 IRQ_TYPE_LEVEL_LOW>;
- clocks = <&imgsys CLK_IMG_JPGDEC_SMI>,
- <&imgsys CLK_IMG_JPGDEC>;
- clock-names = "jpgdec-smi",
- "jpgdec";
- power-domains = <&scpsys MT2701_POWER_DOMAIN_ISP>;
- mediatek,larb = <&larb2>;
- iommus = <&iommu MT2701_M4U_PORT_JPGDEC_WDMA>,
- <&iommu MT2701_M4U_PORT_JPGDEC_BSDMA>;
- };
diff --git a/Documentation/devicetree/bindings/media/mediatek-jpeg-decoder.yaml b/Documentation/devicetree/bindings/media/mediatek-jpeg-decoder.yaml
new file mode 100644
index 000000000000..052e752157b4
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/mediatek-jpeg-decoder.yaml
@@ -0,0 +1,80 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/media/mediatek-jpeg-decoder.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: MediaTek JPEG Decoder Device Tree Bindings
+
+maintainers:
+ - Xia Jiang <xia.jiang@mediatek.com>
+
+description: |-
+ Mediatek JPEG Decoder is the JPEG decode hardware present in Mediatek SoCs
+
+properties:
+ compatible:
+ oneOf:
+ - items:
+ - enum:
+ - mediatek,mt8173-jpgdec
+ - mediatek,mt2701-jpgdec
+ - items:
+ - enum:
+ - mediatek,mt7623-jpgdec
+ - const: mediatek,mt2701-jpgdec
+
+ reg:
+ maxItems: 1
+
+ interrupts:
+ maxItems: 1
+
+ clocks:
+ maxItems: 2
+ minItems: 2
+
+ clock-names:
+ items:
+ - const: jpgdec-smi
+ - const: jpgdec
+
+ power-domains:
+ maxItems: 1
+
+ iommus:
+ maxItems: 2
+ description: |
+ Points to the respective IOMMU block with master port as argument, see
+ Documentation/devicetree/bindings/iommu/mediatek,iommu.yaml for details.
+ Ports are according to the HW.
+
+required:
+ - compatible
+ - reg
+ - interrupts
+ - clocks
+ - clock-names
+ - power-domains
+ - iommus
+
+additionalProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/clock/mt2701-clk.h>
+ #include <dt-bindings/interrupt-controller/arm-gic.h>
+ #include <dt-bindings/memory/mt2701-larb-port.h>
+ #include <dt-bindings/power/mt2701-power.h>
+ jpegdec: jpegdec@15004000 {
+ compatible = "mediatek,mt2701-jpgdec";
+ reg = <0x15004000 0x1000>;
+ interrupts = <GIC_SPI 143 IRQ_TYPE_LEVEL_LOW>;
+ clocks = <&imgsys CLK_IMG_JPGDEC_SMI>,
+ <&imgsys CLK_IMG_JPGDEC>;
+ clock-names = "jpgdec-smi",
+ "jpgdec";
+ power-domains = <&scpsys MT2701_POWER_DOMAIN_ISP>;
+ iommus = <&iommu MT2701_M4U_PORT_JPGDEC_WDMA>,
+ <&iommu MT2701_M4U_PORT_JPGDEC_BSDMA>;
+ };
diff --git a/Documentation/devicetree/bindings/media/mediatek-jpeg-encoder.txt b/Documentation/devicetree/bindings/media/mediatek-jpeg-encoder.txt
deleted file mode 100644
index 5e53c6ab52d0..000000000000
--- a/Documentation/devicetree/bindings/media/mediatek-jpeg-encoder.txt
+++ /dev/null
@@ -1,35 +0,0 @@
-* MediaTek JPEG Encoder
-
-MediaTek JPEG Encoder is the JPEG encode hardware present in MediaTek SoCs
-
-Required properties:
-- compatible : "mediatek,mt2701-jpgenc"
- followed by "mediatek,mtk-jpgenc"
-- reg : physical base address of the JPEG encoder registers and length of
- memory mapped region.
-- interrupts : interrupt number to the interrupt controller.
-- clocks: device clocks, see
- Documentation/devicetree/bindings/clock/clock-bindings.txt for details.
-- clock-names: must contain "jpgenc". It is the clock of JPEG encoder.
-- power-domains: a phandle to the power domain, see
- Documentation/devicetree/bindings/power/power_domain.txt for details.
-- mediatek,larb: must contain the local arbiters in the current SoCs, see
- Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.yaml
- for details.
-- iommus: should point to the respective IOMMU block with master port as
- argument, see Documentation/devicetree/bindings/iommu/mediatek,iommu.yaml
- for details.
-
-Example:
- jpegenc: jpegenc@1500a000 {
- compatible = "mediatek,mt2701-jpgenc",
- "mediatek,mtk-jpgenc";
- reg = <0 0x1500a000 0 0x1000>;
- interrupts = <GIC_SPI 141 IRQ_TYPE_LEVEL_LOW>;
- clocks = <&imgsys CLK_IMG_VENC>;
- clock-names = "jpgenc";
- power-domains = <&scpsys MT2701_POWER_DOMAIN_ISP>;
- mediatek,larb = <&larb2>;
- iommus = <&iommu MT2701_M4U_PORT_JPGENC_RDMA>,
- <&iommu MT2701_M4U_PORT_JPGENC_BSDMA>;
- };
diff --git a/Documentation/devicetree/bindings/media/mediatek-jpeg-encoder.yaml b/Documentation/devicetree/bindings/media/mediatek-jpeg-encoder.yaml
new file mode 100644
index 000000000000..8bfdfdfaba59
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/mediatek-jpeg-encoder.yaml
@@ -0,0 +1,72 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/media/mediatek-jpeg-encoder.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: MediaTek JPEG Encoder Device Tree Bindings
+
+maintainers:
+ - Xia Jiang <xia.jiang@mediatek.com>
+
+description: |-
+ MediaTek JPEG Encoder is the JPEG encode hardware present in MediaTek SoCs
+
+properties:
+ compatible:
+ items:
+ - enum:
+ - mediatek,mt2701-jpgenc
+ - mediatek,mt8183-jpgenc
+ - const: mediatek,mtk-jpgenc
+ reg:
+ maxItems: 1
+
+ interrupts:
+ maxItems: 1
+
+ clocks:
+ maxItems: 1
+
+ clock-names:
+ items:
+ - const: jpgenc
+
+ power-domains:
+ maxItems: 1
+
+ iommus:
+ maxItems: 2
+ description: |
+ Points to the respective IOMMU block with master port as argument, see
+ Documentation/devicetree/bindings/iommu/mediatek,iommu.yaml for details.
+ Ports are according to the HW.
+
+required:
+ - compatible
+ - reg
+ - interrupts
+ - clocks
+ - clock-names
+ - power-domains
+ - iommus
+
+additionalProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/clock/mt2701-clk.h>
+ #include <dt-bindings/interrupt-controller/arm-gic.h>
+ #include <dt-bindings/memory/mt2701-larb-port.h>
+ #include <dt-bindings/power/mt2701-power.h>
+ jpegenc: jpegenc@1500a000 {
+ compatible = "mediatek,mt2701-jpgenc",
+ "mediatek,mtk-jpgenc";
+ reg = <0x1500a000 0x1000>;
+ interrupts = <GIC_SPI 141 IRQ_TYPE_LEVEL_LOW>;
+ clocks = <&imgsys CLK_IMG_VENC>;
+ clock-names = "jpgenc";
+ power-domains = <&scpsys MT2701_POWER_DOMAIN_ISP>;
+ iommus = <&iommu MT2701_M4U_PORT_JPGENC_RDMA>,
+ <&iommu MT2701_M4U_PORT_JPGENC_BSDMA>;
+ };
diff --git a/Documentation/devicetree/bindings/media/mediatek-mdp.txt b/Documentation/devicetree/bindings/media/mediatek-mdp.txt
index caa24943da33..53ef26e2c857 100644
--- a/Documentation/devicetree/bindings/media/mediatek-mdp.txt
+++ b/Documentation/devicetree/bindings/media/mediatek-mdp.txt
@@ -27,9 +27,6 @@ Required properties (DMA function blocks, child node):
- iommus: should point to the respective IOMMU block with master port as
argument, see Documentation/devicetree/bindings/iommu/mediatek,iommu.yaml
for details.
-- mediatek,larb: must contain the local arbiters in the current Socs, see
- Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.yaml
- for details.
Example:
mdp_rdma0: rdma@14001000 {
@@ -40,7 +37,6 @@ Example:
<&mmsys CLK_MM_MUTEX_32K>;
power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
iommus = <&iommu M4U_PORT_MDP_RDMA0>;
- mediatek,larb = <&larb0>;
mediatek,vpu = <&vpu>;
};
@@ -51,7 +47,6 @@ Example:
<&mmsys CLK_MM_MUTEX_32K>;
power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
iommus = <&iommu M4U_PORT_MDP_RDMA1>;
- mediatek,larb = <&larb4>;
};
mdp_rsz0: rsz@14003000 {
@@ -81,7 +76,6 @@ Example:
clocks = <&mmsys CLK_MM_MDP_WDMA>;
power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
iommus = <&iommu M4U_PORT_MDP_WDMA>;
- mediatek,larb = <&larb0>;
};
mdp_wrot0: wrot@14007000 {
@@ -90,7 +84,6 @@ Example:
clocks = <&mmsys CLK_MM_MDP_WROT0>;
power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
iommus = <&iommu M4U_PORT_MDP_WROT0>;
- mediatek,larb = <&larb0>;
};
mdp_wrot1: wrot@14008000 {
@@ -99,5 +92,4 @@ Example:
clocks = <&mmsys CLK_MM_MDP_WROT1>;
power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
iommus = <&iommu M4U_PORT_MDP_WROT1>;
- mediatek,larb = <&larb4>;
};
diff --git a/Documentation/devicetree/bindings/media/mediatek-vcodec.txt b/Documentation/devicetree/bindings/media/mediatek-vcodec.txt
deleted file mode 100644
index 665a9508708e..000000000000
--- a/Documentation/devicetree/bindings/media/mediatek-vcodec.txt
+++ /dev/null
@@ -1,131 +0,0 @@
-Mediatek Video Codec
-
-Mediatek Video Codec is the video codec hw present in Mediatek SoCs which
-supports high resolution encoding and decoding functionalities.
-
-Required properties:
-- compatible : must be one of the following string:
- "mediatek,mt8173-vcodec-enc-vp8" for mt8173 vp8 encoder.
- "mediatek,mt8173-vcodec-enc" for mt8173 avc encoder.
- "mediatek,mt8183-vcodec-enc" for MT8183 encoder.
- "mediatek,mt8173-vcodec-dec" for MT8173 decoder.
- "mediatek,mt8192-vcodec-enc" for MT8192 encoder.
- "mediatek,mt8183-vcodec-dec" for MT8183 decoder.
- "mediatek,mt8195-vcodec-enc" for MT8195 encoder.
-- reg : Physical base address of the video codec registers and length of
- memory mapped region.
-- interrupts : interrupt number to the cpu.
-- mediatek,larb : must contain the local arbiters in the current Socs.
-- clocks : list of clock specifiers, corresponding to entries in
- the clock-names property.
-- clock-names: avc encoder must contain "venc_sel", vp8 encoder must
- contain "venc_lt_sel", decoder must contain "vcodecpll", "univpll_d2",
- "clk_cci400_sel", "vdec_sel", "vdecpll", "vencpll", "venc_lt_sel",
- "vdec_bus_clk_src".
-- iommus : should point to the respective IOMMU block with master port as
- argument, see Documentation/devicetree/bindings/iommu/mediatek,iommu.yaml
- for details.
-- dma-ranges : describes the dma address range space that the codec hw access.
-One of the two following nodes:
-- mediatek,vpu : the node of the video processor unit, if using VPU.
-- mediatek,scp : the node of the SCP unit, if using SCP.
-
-
-Example:
-
-vcodec_dec: vcodec@16000000 {
- compatible = "mediatek,mt8173-vcodec-dec";
- reg = <0 0x16000000 0 0x100>, /*VDEC_SYS*/
- <0 0x16020000 0 0x1000>, /*VDEC_MISC*/
- <0 0x16021000 0 0x800>, /*VDEC_LD*/
- <0 0x16021800 0 0x800>, /*VDEC_TOP*/
- <0 0x16022000 0 0x1000>, /*VDEC_CM*/
- <0 0x16023000 0 0x1000>, /*VDEC_AD*/
- <0 0x16024000 0 0x1000>, /*VDEC_AV*/
- <0 0x16025000 0 0x1000>, /*VDEC_PP*/
- <0 0x16026800 0 0x800>, /*VP8_VD*/
- <0 0x16027000 0 0x800>, /*VP6_VD*/
- <0 0x16027800 0 0x800>, /*VP8_VL*/
- <0 0x16028400 0 0x400>; /*VP9_VD*/
- interrupts = <GIC_SPI 204 IRQ_TYPE_LEVEL_LOW>;
- mediatek,larb = <&larb1>;
- iommus = <&iommu M4U_PORT_HW_VDEC_MC_EXT>,
- <&iommu M4U_PORT_HW_VDEC_PP_EXT>,
- <&iommu M4U_PORT_HW_VDEC_AVC_MV_EXT>,
- <&iommu M4U_PORT_HW_VDEC_PRED_RD_EXT>,
- <&iommu M4U_PORT_HW_VDEC_PRED_WR_EXT>,
- <&iommu M4U_PORT_HW_VDEC_UFO_EXT>,
- <&iommu M4U_PORT_HW_VDEC_VLD_EXT>,
- <&iommu M4U_PORT_HW_VDEC_VLD2_EXT>;
- mediatek,vpu = <&vpu>;
- power-domains = <&scpsys MT8173_POWER_DOMAIN_VDEC>;
- clocks = <&apmixedsys CLK_APMIXED_VCODECPLL>,
- <&topckgen CLK_TOP_UNIVPLL_D2>,
- <&topckgen CLK_TOP_CCI400_SEL>,
- <&topckgen CLK_TOP_VDEC_SEL>,
- <&topckgen CLK_TOP_VCODECPLL>,
- <&apmixedsys CLK_APMIXED_VENCPLL>,
- <&topckgen CLK_TOP_VENC_LT_SEL>,
- <&topckgen CLK_TOP_VCODECPLL_370P5>;
- clock-names = "vcodecpll",
- "univpll_d2",
- "clk_cci400_sel",
- "vdec_sel",
- "vdecpll",
- "vencpll",
- "venc_lt_sel",
- "vdec_bus_clk_src";
- assigned-clocks = <&topckgen CLK_TOP_VENC_LT_SEL>,
- <&topckgen CLK_TOP_CCI400_SEL>,
- <&topckgen CLK_TOP_VDEC_SEL>,
- <&apmixedsys CLK_APMIXED_VCODECPLL>,
- <&apmixedsys CLK_APMIXED_VENCPLL>;
- assigned-clock-parents = <&topckgen CLK_TOP_VCODECPLL_370P5>,
- <&topckgen CLK_TOP_UNIVPLL_D2>,
- <&topckgen CLK_TOP_VCODECPLL>;
- assigned-clock-rates = <0>, <0>, <0>, <1482000000>, <800000000>;
- };
-
-vcodec_enc_avc: vcodec@18002000 {
- compatible = "mediatek,mt8173-vcodec-enc";
- reg = <0 0x18002000 0 0x1000>;
- interrupts = <GIC_SPI 198 IRQ_TYPE_LEVEL_LOW>;
- iommus = <&iommu M4U_PORT_VENC_RCPU>,
- <&iommu M4U_PORT_VENC_REC>,
- <&iommu M4U_PORT_VENC_BSDMA>,
- <&iommu M4U_PORT_VENC_SV_COMV>,
- <&iommu M4U_PORT_VENC_RD_COMV>,
- <&iommu M4U_PORT_VENC_CUR_LUMA>,
- <&iommu M4U_PORT_VENC_CUR_CHROMA>,
- <&iommu M4U_PORT_VENC_REF_LUMA>,
- <&iommu M4U_PORT_VENC_REF_CHROMA>,
- <&iommu M4U_PORT_VENC_NBM_RDMA>,
- <&iommu M4U_PORT_VENC_NBM_WDMA>;
- mediatek,larb = <&larb3>;
- mediatek,vpu = <&vpu>;
- clocks = <&topckgen CLK_TOP_VENC_SEL>;
- clock-names = "venc_sel";
- assigned-clocks = <&topckgen CLK_TOP_VENC_SEL>;
- assigned-clock-parents = <&topckgen CLK_TOP_VCODECPLL>;
- };
-
-vcodec_enc_vp8: vcodec@19002000 {
- compatible = "mediatek,mt8173-vcodec-enc-vp8";
- reg = <0 0x19002000 0 0x1000>; /* VENC_LT_SYS */
- interrupts = <GIC_SPI 202 IRQ_TYPE_LEVEL_LOW>;
- iommus = <&iommu M4U_PORT_VENC_RCPU_SET2>,
- <&iommu M4U_PORT_VENC_REC_FRM_SET2>,
- <&iommu M4U_PORT_VENC_BSDMA_SET2>,
- <&iommu M4U_PORT_VENC_SV_COMA_SET2>,
- <&iommu M4U_PORT_VENC_RD_COMA_SET2>,
- <&iommu M4U_PORT_VENC_CUR_LUMA_SET2>,
- <&iommu M4U_PORT_VENC_CUR_CHROMA_SET2>,
- <&iommu M4U_PORT_VENC_REF_LUMA_SET2>,
- <&iommu M4U_PORT_VENC_REC_CHROMA_SET2>;
- mediatek,larb = <&larb5>;
- mediatek,vpu = <&vpu>;
- clocks = <&topckgen CLK_TOP_VENC_LT_SEL>;
- clock-names = "venc_lt_sel";
- assigned-clocks = <&topckgen CLK_TOP_VENC_LT_SEL>;
- assigned-clock-parents = <&topckgen CLK_TOP_VCODECPLL_370P5>;
- };
diff --git a/Documentation/devicetree/bindings/media/microchip,csi2dc.yaml b/Documentation/devicetree/bindings/media/microchip,csi2dc.yaml
new file mode 100644
index 000000000000..e8544fb2d034
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/microchip,csi2dc.yaml
@@ -0,0 +1,197 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/media/microchip,csi2dc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Microchip CSI2 Demux Controller (CSI2DC)
+
+maintainers:
+ - Eugen Hristev <eugen.hristev@microchip.com>
+
+description:
+ CSI2DC - Camera Serial Interface 2 Demux Controller
+
+ CSI2DC is a hardware block that receives incoming data from either from an
+ IDI interface or from a parallel bus interface.
+ It filters IDI packets based on their data type and virtual channel
+ identifier, then converts the byte stream to a pixel stream into a cross
+ clock domain towards a parallel interface that can be read by a sensor
+ controller.
+ IDI interface is Synopsys proprietary.
+ CSI2DC can act a simple bypass bridge if the incoming data is coming from
+ a parallel interface.
+
+ CSI2DC provides two pipes, one video pipe and one data pipe. Video pipe
+ is connected at the output to a sensor controller and the data pipe is
+ accessible as a DMA slave port to a DMA controller.
+
+ CSI2DC supports a single 'port' node as a sink port with either Synopsys
+ 32-bit IDI interface or a parallel interface.
+
+ CSI2DC supports one 'port' node as source port with parallel interface.
+ This is called video pipe.
+ This port has an 'endpoint' that can be connected to a sink port of another
+ controller (next in pipeline).
+
+ CSI2DC also supports direct access to the data through AHB, via DMA channel,
+ called data pipe.
+ For data pipe to be available, a dma controller and a dma channel must be
+ referenced.
+
+properties:
+ compatible:
+ const: microchip,sama7g5-csi2dc
+
+ reg:
+ maxItems: 1
+
+ clocks:
+ minItems: 2
+ maxItems: 2
+
+ clock-names:
+ description:
+ CSI2DC must have two clocks to function correctly. One clock is the
+ peripheral clock for the inside functionality of the hardware block.
+ This is named 'pclk'. The second clock must be the cross domain clock,
+ in which CSI2DC will perform clock crossing. This clock must be fed
+ by the next controller in pipeline, which usually is a sensor controller.
+ Normally this clock should be given by this sensor controller who
+ is also a clock source. This clock is named 'scck', sensor controller clock.
+ items:
+ - const: pclk
+ - const: scck
+
+ dmas:
+ maxItems: 1
+
+ dma-names:
+ const: rx
+
+ ports:
+ $ref: /schemas/graph.yaml#/properties/ports
+
+ properties:
+ port@0:
+ $ref: /schemas/graph.yaml#/$defs/port-base
+ description:
+ Input port node, single endpoint describing the input port.
+
+ properties:
+ endpoint:
+ $ref: video-interfaces.yaml#
+ unevaluatedProperties: false
+ description: Endpoint connected to input device
+
+ properties:
+ bus-type:
+ enum: [4, 5, 6]
+ default: 4
+
+ bus-width:
+ enum: [8, 9, 10, 11, 12, 13, 14]
+ default: 14
+
+ clock-noncontinuous:
+ type: boolean
+ description:
+ Presence of this boolean property decides whether clock is
+ continuous or noncontinuous.
+
+ remote-endpoint: true
+
+ port@1:
+ $ref: /schemas/graph.yaml#/$defs/port-base
+ description:
+ Output port node, single endpoint describing the output port.
+
+ properties:
+ endpoint:
+ unevaluatedProperties: false
+ $ref: video-interfaces.yaml#
+ description: Endpoint connected to output device
+
+ properties:
+ bus-type:
+ enum: [5, 6]
+ default: 5
+
+ bus-width:
+ enum: [8, 9, 10, 11, 12, 13, 14]
+ default: 14
+
+ remote-endpoint: true
+
+ required:
+ - port@0
+ - port@1
+
+additionalProperties: false
+
+required:
+ - compatible
+ - reg
+ - clocks
+ - clock-names
+ - ports
+
+examples:
+ # Example for connecting to a parallel sensor controller block (video pipe)
+ # and the input is received from Synopsys IDI interface
+ - |
+ csi2dc@e1404000 {
+ compatible = "microchip,sama7g5-csi2dc";
+ reg = <0xe1404000 0x500>;
+ clocks = <&pclk>, <&scck>;
+ clock-names = "pclk", "scck";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ port@0 {
+ reg = <0>; /* must be 0, first child port */
+ csi2dc_in: endpoint { /* input from IDI interface */
+ bus-type = <4>; /* MIPI CSI2 D-PHY */
+ remote-endpoint = <&csi2host_out>;
+ };
+ };
+
+ port@1 {
+ reg = <1>; /* must be 1, second child port */
+ csi2dc_out: endpoint {
+ remote-endpoint = <&xisc_in>; /* output to sensor controller */
+ };
+ };
+ };
+ };
+
+ # Example for connecting to a DMA master as an AHB slave
+ # and the input is received from Synopsys IDI interface
+ - |
+ #include <dt-bindings/dma/at91.h>
+ csi2dc@e1404000 {
+ compatible = "microchip,sama7g5-csi2dc";
+ reg = <0xe1404000 0x500>;
+ clocks = <&pclk>, <&scck>;
+ clock-names = "pclk", "scck";
+ dmas = <&dma0 AT91_XDMAC_DT_PERID(34)>;
+ dma-names = "rx";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ port@0 {
+ reg = <0>; /* must be 0, first child port */
+ csi2dc_input: endpoint { /* input from IDI interface */
+ remote-endpoint = <&csi2host_out>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+ };
+ };
+ };
+
+...
diff --git a/Documentation/devicetree/bindings/media/nxp,imx7-mipi-csi2.yaml b/Documentation/devicetree/bindings/media/nxp,imx-mipi-csi2.yaml
index e2e6e9aa0fe6..36b135bf9f2a 100644
--- a/Documentation/devicetree/bindings/media/nxp,imx7-mipi-csi2.yaml
+++ b/Documentation/devicetree/bindings/media/nxp,imx-mipi-csi2.yaml
@@ -1,7 +1,7 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
-$id: http://devicetree.org/schemas/media/nxp,imx7-mipi-csi2.yaml#
+$id: http://devicetree.org/schemas/media/nxp,imx-mipi-csi2.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: NXP i.MX7 and i.MX8 MIPI CSI-2 receiver
diff --git a/Documentation/devicetree/bindings/media/nxp,imx7-csi.yaml b/Documentation/devicetree/bindings/media/nxp,imx7-csi.yaml
index 5922a2795167..4f7b78265336 100644
--- a/Documentation/devicetree/bindings/media/nxp,imx7-csi.yaml
+++ b/Documentation/devicetree/bindings/media/nxp,imx7-csi.yaml
@@ -17,6 +17,7 @@ properties:
compatible:
oneOf:
- enum:
+ - fsl,imx8mq-csi
- fsl,imx7-csi
- fsl,imx6ul-csi
- items:
diff --git a/Documentation/devicetree/bindings/media/nxp,imx8mq-vpu.yaml b/Documentation/devicetree/bindings/media/nxp,imx8mq-vpu.yaml
index 762be3f96ce9..7dc13a4b1805 100644
--- a/Documentation/devicetree/bindings/media/nxp,imx8mq-vpu.yaml
+++ b/Documentation/devicetree/bindings/media/nxp,imx8mq-vpu.yaml
@@ -5,7 +5,7 @@
$id: "http://devicetree.org/schemas/media/nxp,imx8mq-vpu.yaml#"
$schema: "http://devicetree.org/meta-schemas/core.yaml#"
-title: Hantro G1/G2 VPU codecs implemented on i.MX8MQ SoCs
+title: Hantro G1/G2 VPU codecs implemented on i.MX8M SoCs
maintainers:
- Philipp Zabel <p.zabel@pengutronix.de>
@@ -15,33 +15,21 @@ description:
properties:
compatible:
- const: nxp,imx8mq-vpu
+ oneOf:
+ - const: nxp,imx8mq-vpu
+ deprecated: true
+ - const: nxp,imx8mq-vpu-g1
+ - const: nxp,imx8mq-vpu-g2
+ - const: nxp,imx8mm-vpu-g1
reg:
- maxItems: 3
-
- reg-names:
- items:
- - const: g1
- - const: g2
- - const: ctrl
+ maxItems: 1
interrupts:
- maxItems: 2
-
- interrupt-names:
- items:
- - const: g1
- - const: g2
+ maxItems: 1
clocks:
- maxItems: 3
-
- clock-names:
- items:
- - const: g1
- - const: g2
- - const: bus
+ maxItems: 1
power-domains:
maxItems: 1
@@ -49,31 +37,33 @@ properties:
required:
- compatible
- reg
- - reg-names
- interrupts
- - interrupt-names
- clocks
- - clock-names
additionalProperties: false
examples:
- |
#include <dt-bindings/clock/imx8mq-clock.h>
+ #include <dt-bindings/power/imx8mq-power.h>
+ #include <dt-bindings/interrupt-controller/arm-gic.h>
+
+ vpu_g1: video-codec@38300000 {
+ compatible = "nxp,imx8mq-vpu-g1";
+ reg = <0x38300000 0x10000>;
+ interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX8MQ_CLK_VPU_G1_ROOT>;
+ power-domains = <&vpu_blk_ctrl IMX8MQ_VPUBLK_PD_G1>;
+ };
+ - |
+ #include <dt-bindings/clock/imx8mq-clock.h>
+ #include <dt-bindings/power/imx8mq-power.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
- vpu: video-codec@38300000 {
- compatible = "nxp,imx8mq-vpu";
- reg = <0x38300000 0x10000>,
- <0x38310000 0x10000>,
- <0x38320000 0x10000>;
- reg-names = "g1", "g2", "ctrl";
- interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>;
- interrupt-names = "g1", "g2";
- clocks = <&clk IMX8MQ_CLK_VPU_G1_ROOT>,
- <&clk IMX8MQ_CLK_VPU_G2_ROOT>,
- <&clk IMX8MQ_CLK_VPU_DEC_ROOT>;
- clock-names = "g1", "g2", "bus";
- power-domains = <&pgc_vpu>;
+ vpu_g2: video-codec@38300000 {
+ compatible = "nxp,imx8mq-vpu-g2";
+ reg = <0x38310000 0x10000>;
+ interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX8MQ_CLK_VPU_G2_ROOT>;
+ power-domains = <&vpu_blk_ctrl IMX8MQ_VPUBLK_PD_G2>;
};
diff --git a/Documentation/devicetree/bindings/media/qcom,msm8916-camss.yaml b/Documentation/devicetree/bindings/media/qcom,msm8916-camss.yaml
index 304908072d72..12ec3e1ea869 100644
--- a/Documentation/devicetree/bindings/media/qcom,msm8916-camss.yaml
+++ b/Documentation/devicetree/bindings/media/qcom,msm8916-camss.yaml
@@ -83,10 +83,6 @@ properties:
unevaluatedProperties: false
properties:
- clock-lanes:
- items:
- - const: 1
-
data-lanes:
description:
An array of physical data lanes indexes.
@@ -99,7 +95,6 @@ properties:
maxItems: 4
required:
- - clock-lanes
- data-lanes
port@1:
@@ -114,16 +109,11 @@ properties:
unevaluatedProperties: false
properties:
- clock-lanes:
- items:
- - const: 1
-
data-lanes:
minItems: 1
maxItems: 4
required:
- - clock-lanes
- data-lanes
reg:
diff --git a/Documentation/devicetree/bindings/media/qcom,msm8996-camss.yaml b/Documentation/devicetree/bindings/media/qcom,msm8996-camss.yaml
index 38be41e932f0..6aeb3d6d02d5 100644
--- a/Documentation/devicetree/bindings/media/qcom,msm8996-camss.yaml
+++ b/Documentation/devicetree/bindings/media/qcom,msm8996-camss.yaml
@@ -105,10 +105,6 @@ properties:
unevaluatedProperties: false
properties:
- clock-lanes:
- items:
- - const: 7
-
data-lanes:
description:
An array of physical data lanes indexes.
@@ -121,7 +117,6 @@ properties:
maxItems: 4
required:
- - clock-lanes
- data-lanes
port@1:
@@ -136,16 +131,11 @@ properties:
unevaluatedProperties: false
properties:
- clock-lanes:
- items:
- - const: 7
-
data-lanes:
minItems: 1
maxItems: 4
required:
- - clock-lanes
- data-lanes
port@2:
@@ -160,16 +150,11 @@ properties:
unevaluatedProperties: false
properties:
- clock-lanes:
- items:
- - const: 7
-
data-lanes:
minItems: 1
maxItems: 4
required:
- - clock-lanes
- data-lanes
port@3:
@@ -184,16 +169,11 @@ properties:
unevaluatedProperties: false
properties:
- clock-lanes:
- items:
- - const: 7
-
data-lanes:
minItems: 1
maxItems: 4
required:
- - clock-lanes
- data-lanes
reg:
diff --git a/Documentation/devicetree/bindings/media/qcom,sdm660-camss.yaml b/Documentation/devicetree/bindings/media/qcom,sdm660-camss.yaml
index 841a1aafdd13..338ab28d5f3b 100644
--- a/Documentation/devicetree/bindings/media/qcom,sdm660-camss.yaml
+++ b/Documentation/devicetree/bindings/media/qcom,sdm660-camss.yaml
@@ -111,16 +111,11 @@ properties:
unevaluatedProperties: false
properties:
- clock-lanes:
- items:
- - const: 7
-
data-lanes:
minItems: 1
maxItems: 4
required:
- - clock-lanes
- data-lanes
port@1:
@@ -135,16 +130,11 @@ properties:
unevaluatedProperties: false
properties:
- clock-lanes:
- items:
- - const: 7
-
data-lanes:
minItems: 1
maxItems: 4
required:
- - clock-lanes
- data-lanes
port@2:
@@ -159,16 +149,11 @@ properties:
unevaluatedProperties: false
properties:
- clock-lanes:
- items:
- - const: 7
-
data-lanes:
minItems: 1
maxItems: 4
required:
- - clock-lanes
- data-lanes
port@3:
@@ -183,16 +168,11 @@ properties:
unevaluatedProperties: false
properties:
- clock-lanes:
- items:
- - const: 7
-
data-lanes:
minItems: 1
maxItems: 4
required:
- - clock-lanes
- data-lanes
reg:
diff --git a/Documentation/devicetree/bindings/media/qcom,sdm845-camss.yaml b/Documentation/devicetree/bindings/media/qcom,sdm845-camss.yaml
index 9ca5dfa7f226..f9a003882f84 100644
--- a/Documentation/devicetree/bindings/media/qcom,sdm845-camss.yaml
+++ b/Documentation/devicetree/bindings/media/qcom,sdm845-camss.yaml
@@ -105,15 +105,11 @@ properties:
unevaluatedProperties: false
properties:
- clock-lanes:
- maxItems: 1
-
data-lanes:
minItems: 1
maxItems: 4
required:
- - clock-lanes
- data-lanes
port@1:
@@ -128,16 +124,11 @@ properties:
unevaluatedProperties: false
properties:
- clock-lanes:
- items:
- - const: 7
-
data-lanes:
minItems: 1
maxItems: 4
required:
- - clock-lanes
- data-lanes
port@2:
@@ -152,15 +143,11 @@ properties:
unevaluatedProperties: false
properties:
- clock-lanes:
- maxItems: 1
-
data-lanes:
minItems: 1
maxItems: 4
required:
- - clock-lanes
- data-lanes
port@3:
@@ -175,15 +162,11 @@ properties:
unevaluatedProperties: false
properties:
- clock-lanes:
- maxItems: 1
-
data-lanes:
minItems: 1
maxItems: 4
required:
- - clock-lanes
- data-lanes
reg:
@@ -203,9 +186,13 @@ properties:
- const: vfe1
- const: vfe_lite
- vdda-supply:
+ vdda-phy-supply:
+ description:
+ Phandle to a regulator supply to PHY core block.
+
+ vdda-pll-supply:
description:
- Definition of the regulator used as analog power supply.
+ Phandle to 1.8V regulator supply to PHY refclk pll block.
required:
- clock-names
@@ -217,7 +204,8 @@ required:
- power-domains
- reg
- reg-names
- - vdda-supply
+ - vdda-phy-supply
+ - vdda-pll-supply
additionalProperties: false
@@ -361,7 +349,8 @@ examples:
"vfe1",
"vfe_lite";
- vdda-supply = <&reg_2v8>;
+ vdda-phy-supply = <&vreg_l1a_0p875>;
+ vdda-pll-supply = <&vreg_l26a_1p2>;
ports {
#address-cells = <1>;
diff --git a/Documentation/devicetree/bindings/media/qcom,sm8250-camss.yaml b/Documentation/devicetree/bindings/media/qcom,sm8250-camss.yaml
new file mode 100644
index 000000000000..07a2af12f37d
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/qcom,sm8250-camss.yaml
@@ -0,0 +1,463 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+
+%YAML 1.2
+---
+$id: "http://devicetree.org/schemas/media/qcom,sm8250-camss.yaml#"
+$schema: "http://devicetree.org/meta-schemas/core.yaml#"
+
+title: Qualcomm CAMSS ISP
+
+maintainers:
+ - Robert Foss <robert.foss@linaro.org>
+
+description: |
+ The CAMSS IP is a CSI decoder and ISP present on Qualcomm platforms.
+
+properties:
+ compatible:
+ const: qcom,sm8250-camss
+
+ clocks:
+ minItems: 37
+ maxItems: 37
+
+ clock-names:
+ items:
+ - const: cam_ahb_clk
+ - const: cam_hf_axi
+ - const: cam_sf_axi
+ - const: camnoc_axi
+ - const: camnoc_axi_src
+ - const: core_ahb
+ - const: cpas_ahb
+ - const: csiphy0
+ - const: csiphy0_timer
+ - const: csiphy1
+ - const: csiphy1_timer
+ - const: csiphy2
+ - const: csiphy2_timer
+ - const: csiphy3
+ - const: csiphy3_timer
+ - const: csiphy4
+ - const: csiphy4_timer
+ - const: csiphy5
+ - const: csiphy5_timer
+ - const: slow_ahb_src
+ - const: vfe0_ahb
+ - const: vfe0_axi
+ - const: vfe0
+ - const: vfe0_cphy_rx
+ - const: vfe0_csid
+ - const: vfe0_areg
+ - const: vfe1_ahb
+ - const: vfe1_axi
+ - const: vfe1
+ - const: vfe1_cphy_rx
+ - const: vfe1_csid
+ - const: vfe1_areg
+ - const: vfe_lite_ahb
+ - const: vfe_lite_axi
+ - const: vfe_lite
+ - const: vfe_lite_cphy_rx
+ - const: vfe_lite_csid
+
+ interrupts:
+ minItems: 14
+ maxItems: 14
+
+ interrupt-names:
+ items:
+ - const: csiphy0
+ - const: csiphy1
+ - const: csiphy2
+ - const: csiphy3
+ - const: csiphy4
+ - const: csiphy5
+ - const: csid0
+ - const: csid1
+ - const: csid2
+ - const: csid3
+ - const: vfe0
+ - const: vfe1
+ - const: vfe_lite0
+ - const: vfe_lite1
+
+ iommus:
+ minItems: 8
+ maxItems: 8
+
+ interconnects:
+ minItems: 4
+ maxItems: 4
+
+ interconnect-names:
+ items:
+ - const: cam_ahb
+ - const: cam_hf_0_mnoc
+ - const: cam_sf_0_mnoc
+ - const: cam_sf_icp_mnoc
+
+ power-domains:
+ items:
+ - description: IFE0 GDSC - Image Front End, Global Distributed Switch Controller.
+ - description: IFE1 GDSC - Image Front End, Global Distributed Switch Controller.
+ - description: Titan GDSC - Titan ISP Block, Global Distributed Switch Controller.
+
+ ports:
+ $ref: /schemas/graph.yaml#/properties/ports
+
+ description:
+ CSI input ports.
+
+ properties:
+ port@0:
+ $ref: /schemas/graph.yaml#/$defs/port-base
+ unevaluatedProperties: false
+ description:
+ Input port for receiving CSI data.
+
+ properties:
+ endpoint:
+ $ref: video-interfaces.yaml#
+ unevaluatedProperties: false
+
+ properties:
+ clock-lanes:
+ maxItems: 1
+
+ data-lanes:
+ minItems: 1
+ maxItems: 4
+
+ required:
+ - clock-lanes
+ - data-lanes
+
+ port@1:
+ $ref: /schemas/graph.yaml#/$defs/port-base
+ unevaluatedProperties: false
+ description:
+ Input port for receiving CSI data.
+
+ properties:
+ endpoint:
+ $ref: video-interfaces.yaml#
+ unevaluatedProperties: false
+
+ properties:
+ clock-lanes:
+ maxItems: 1
+
+ data-lanes:
+ minItems: 1
+ maxItems: 4
+
+ required:
+ - clock-lanes
+ - data-lanes
+
+ port@2:
+ $ref: /schemas/graph.yaml#/$defs/port-base
+ unevaluatedProperties: false
+ description:
+ Input port for receiving CSI data.
+
+ properties:
+ endpoint:
+ $ref: video-interfaces.yaml#
+ unevaluatedProperties: false
+
+ properties:
+ clock-lanes:
+ maxItems: 1
+
+ data-lanes:
+ minItems: 1
+ maxItems: 4
+
+ required:
+ - clock-lanes
+ - data-lanes
+
+ port@3:
+ $ref: /schemas/graph.yaml#/$defs/port-base
+ unevaluatedProperties: false
+ description:
+ Input port for receiving CSI data.
+
+ properties:
+ endpoint:
+ $ref: video-interfaces.yaml#
+ unevaluatedProperties: false
+
+ properties:
+ clock-lanes:
+ maxItems: 1
+
+ data-lanes:
+ minItems: 1
+ maxItems: 4
+
+ required:
+ - clock-lanes
+ - data-lanes
+
+ port@4:
+ $ref: /schemas/graph.yaml#/$defs/port-base
+ unevaluatedProperties: false
+ description:
+ Input port for receiving CSI data.
+
+ properties:
+ endpoint:
+ $ref: video-interfaces.yaml#
+ unevaluatedProperties: false
+
+ properties:
+ clock-lanes:
+ maxItems: 1
+
+ data-lanes:
+ minItems: 1
+ maxItems: 4
+
+ required:
+ - clock-lanes
+ - data-lanes
+
+ port@5:
+ $ref: /schemas/graph.yaml#/$defs/port-base
+ unevaluatedProperties: false
+ description:
+ Input port for receiving CSI data.
+
+ properties:
+ endpoint:
+ $ref: video-interfaces.yaml#
+ unevaluatedProperties: false
+
+ properties:
+ clock-lanes:
+ maxItems: 1
+
+ data-lanes:
+ minItems: 1
+ maxItems: 4
+
+ required:
+ - clock-lanes
+ - data-lanes
+
+ reg:
+ minItems: 10
+ maxItems: 10
+
+ reg-names:
+ items:
+ - const: csiphy0
+ - const: csiphy1
+ - const: csiphy2
+ - const: csiphy3
+ - const: csiphy4
+ - const: csiphy5
+ - const: vfe0
+ - const: vfe1
+ - const: vfe_lite0
+ - const: vfe_lite1
+
+ vdda-phy-supply:
+ description:
+ Phandle to a regulator supply to PHY core block.
+
+ vdda-pll-supply:
+ description:
+ Phandle to 1.8V regulator supply to PHY refclk pll block.
+
+required:
+ - clock-names
+ - clocks
+ - compatible
+ - interconnects
+ - interconnect-names
+ - interrupts
+ - interrupt-names
+ - iommus
+ - power-domains
+ - reg
+ - reg-names
+ - vdda-phy-supply
+ - vdda-pll-supply
+
+additionalProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/interrupt-controller/arm-gic.h>
+ #include <dt-bindings/clock/qcom,camcc-sm8250.h>
+ #include <dt-bindings/interconnect/qcom,sm8250.h>
+ #include <dt-bindings/clock/qcom,gcc-sm8250.h>
+ #include <dt-bindings/power/qcom-rpmpd.h>
+
+ soc {
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ camss: camss@ac6a000 {
+ compatible = "qcom,sm8250-camss";
+
+ reg = <0 0xac6a000 0 0x2000>,
+ <0 0xac6c000 0 0x2000>,
+ <0 0xac6e000 0 0x1000>,
+ <0 0xac70000 0 0x1000>,
+ <0 0xac72000 0 0x1000>,
+ <0 0xac74000 0 0x1000>,
+ <0 0xacb4000 0 0xd000>,
+ <0 0xacc3000 0 0xd000>,
+ <0 0xacd9000 0 0x2200>,
+ <0 0xacdb200 0 0x2200>;
+ reg-names = "csiphy0",
+ "csiphy1",
+ "csiphy2",
+ "csiphy3",
+ "csiphy4",
+ "csiphy5",
+ "vfe0",
+ "vfe1",
+ "vfe_lite0",
+ "vfe_lite1";
+
+ vdda-phy-supply = <&vreg_l5a_0p88>;
+ vdda-pll-supply = <&vreg_l9a_1p2>;
+
+ interrupts = <GIC_SPI 477 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 478 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 479 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 448 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 89 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 464 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 466 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 468 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 359 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 465 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 467 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 469 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 360 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "csiphy0",
+ "csiphy1",
+ "csiphy2",
+ "csiphy3",
+ "csiphy4",
+ "csiphy5",
+ "csid0",
+ "csid1",
+ "csid2",
+ "csid3",
+ "vfe0",
+ "vfe1",
+ "vfe_lite0",
+ "vfe_lite1";
+
+ power-domains = <&camcc IFE_0_GDSC>,
+ <&camcc IFE_1_GDSC>,
+ <&camcc TITAN_TOP_GDSC>;
+
+ clocks = <&gcc GCC_CAMERA_AHB_CLK>,
+ <&gcc GCC_CAMERA_HF_AXI_CLK>,
+ <&gcc GCC_CAMERA_SF_AXI_CLK>,
+ <&camcc CAM_CC_CAMNOC_AXI_CLK>,
+ <&camcc CAM_CC_CAMNOC_AXI_CLK_SRC>,
+ <&camcc CAM_CC_CORE_AHB_CLK>,
+ <&camcc CAM_CC_CPAS_AHB_CLK>,
+ <&camcc CAM_CC_CSIPHY0_CLK>,
+ <&camcc CAM_CC_CSI0PHYTIMER_CLK>,
+ <&camcc CAM_CC_CSIPHY1_CLK>,
+ <&camcc CAM_CC_CSI1PHYTIMER_CLK>,
+ <&camcc CAM_CC_CSIPHY2_CLK>,
+ <&camcc CAM_CC_CSI2PHYTIMER_CLK>,
+ <&camcc CAM_CC_CSIPHY3_CLK>,
+ <&camcc CAM_CC_CSI3PHYTIMER_CLK>,
+ <&camcc CAM_CC_CSIPHY4_CLK>,
+ <&camcc CAM_CC_CSI4PHYTIMER_CLK>,
+ <&camcc CAM_CC_CSIPHY5_CLK>,
+ <&camcc CAM_CC_CSI5PHYTIMER_CLK>,
+ <&camcc CAM_CC_SLOW_AHB_CLK_SRC>,
+ <&camcc CAM_CC_IFE_0_AHB_CLK>,
+ <&camcc CAM_CC_IFE_0_AXI_CLK>,
+ <&camcc CAM_CC_IFE_0_CLK>,
+ <&camcc CAM_CC_IFE_0_CPHY_RX_CLK>,
+ <&camcc CAM_CC_IFE_0_CSID_CLK>,
+ <&camcc CAM_CC_IFE_0_AREG_CLK>,
+ <&camcc CAM_CC_IFE_1_AHB_CLK>,
+ <&camcc CAM_CC_IFE_1_AXI_CLK>,
+ <&camcc CAM_CC_IFE_1_CLK>,
+ <&camcc CAM_CC_IFE_1_CPHY_RX_CLK>,
+ <&camcc CAM_CC_IFE_1_CSID_CLK>,
+ <&camcc CAM_CC_IFE_1_AREG_CLK>,
+ <&camcc CAM_CC_IFE_LITE_AHB_CLK>,
+ <&camcc CAM_CC_IFE_LITE_AXI_CLK>,
+ <&camcc CAM_CC_IFE_LITE_CLK>,
+ <&camcc CAM_CC_IFE_LITE_CPHY_RX_CLK>,
+ <&camcc CAM_CC_IFE_LITE_CSID_CLK>;
+ clock-names = "cam_ahb_clk",
+ "cam_hf_axi",
+ "cam_sf_axi",
+ "camnoc_axi",
+ "camnoc_axi_src",
+ "core_ahb",
+ "cpas_ahb",
+ "csiphy0",
+ "csiphy0_timer",
+ "csiphy1",
+ "csiphy1_timer",
+ "csiphy2",
+ "csiphy2_timer",
+ "csiphy3",
+ "csiphy3_timer",
+ "csiphy4",
+ "csiphy4_timer",
+ "csiphy5",
+ "csiphy5_timer",
+ "slow_ahb_src",
+ "vfe0_ahb",
+ "vfe0_axi",
+ "vfe0",
+ "vfe0_cphy_rx",
+ "vfe0_csid",
+ "vfe0_areg",
+ "vfe1_ahb",
+ "vfe1_axi",
+ "vfe1",
+ "vfe1_cphy_rx",
+ "vfe1_csid",
+ "vfe1_areg",
+ "vfe_lite_ahb",
+ "vfe_lite_axi",
+ "vfe_lite",
+ "vfe_lite_cphy_rx",
+ "vfe_lite_csid";
+
+ iommus = <&apps_smmu 0x800 0x400>,
+ <&apps_smmu 0x801 0x400>,
+ <&apps_smmu 0x840 0x400>,
+ <&apps_smmu 0x841 0x400>,
+ <&apps_smmu 0xC00 0x400>,
+ <&apps_smmu 0xC01 0x400>,
+ <&apps_smmu 0xC40 0x400>,
+ <&apps_smmu 0xC41 0x400>;
+
+ interconnects = <&gem_noc MASTER_AMPSS_M0 &config_noc SLAVE_CAMERA_CFG>,
+ <&mmss_noc MASTER_CAMNOC_HF &mc_virt SLAVE_EBI_CH0>,
+ <&mmss_noc MASTER_CAMNOC_SF &mc_virt SLAVE_EBI_CH0>,
+ <&mmss_noc MASTER_CAMNOC_ICP &mc_virt SLAVE_EBI_CH0>;
+ interconnect-names = "cam_ahb",
+ "cam_hf_0_mnoc",
+ "cam_sf_0_mnoc",
+ "cam_sf_icp_mnoc";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ };
+ };
diff --git a/Documentation/devicetree/bindings/media/renesas,csi2.yaml b/Documentation/devicetree/bindings/media/renesas,csi2.yaml
index e6a036721082..b520d6c5c102 100644
--- a/Documentation/devicetree/bindings/media/renesas,csi2.yaml
+++ b/Documentation/devicetree/bindings/media/renesas,csi2.yaml
@@ -67,7 +67,10 @@ properties:
maxItems: 1
data-lanes:
- maxItems: 1
+ minItems: 1
+ maxItems: 4
+ items:
+ maximum: 4
required:
- clock-lanes
diff --git a/Documentation/devicetree/bindings/memory-controllers/ddr/jedec,lpddr2-timings.yaml b/Documentation/devicetree/bindings/memory-controllers/ddr/jedec,lpddr2-timings.yaml
new file mode 100644
index 000000000000..f3e62ee07126
--- /dev/null
+++ b/Documentation/devicetree/bindings/memory-controllers/ddr/jedec,lpddr2-timings.yaml
@@ -0,0 +1,135 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/memory-controllers/ddr/jedec,lpddr2-timings.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: LPDDR2 SDRAM AC timing parameters for a given speed-bin
+
+maintainers:
+ - Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>
+
+properties:
+ compatible:
+ const: jedec,lpddr2-timings
+
+ max-freq:
+ $ref: /schemas/types.yaml#/definitions/uint32
+ description: |
+ Maximum DDR clock frequency for the speed-bin, in Hz.
+
+ min-freq:
+ $ref: /schemas/types.yaml#/definitions/uint32
+ description: |
+ Minimum DDR clock frequency for the speed-bin, in Hz.
+
+ tCKESR:
+ $ref: /schemas/types.yaml#/definitions/uint32
+ description: |
+ CKE minimum pulse width during SELF REFRESH (low pulse width during
+ SELF REFRESH) in pico seconds.
+
+ tDQSCK-max:
+ $ref: /schemas/types.yaml#/definitions/uint32
+ description: |
+ DQS output data access time from CK_t/CK_c in pico seconds.
+
+ tDQSCK-max-derated:
+ $ref: /schemas/types.yaml#/definitions/uint32
+ description: |
+ DQS output data access time from CK_t/CK_c, temperature de-rated, in pico
+ seconds.
+
+ tFAW:
+ $ref: /schemas/types.yaml#/definitions/uint32
+ description: |
+ Four-bank activate window in pico seconds.
+
+ tRAS-max-ns:
+ description: |
+ Row active time in nano seconds.
+
+ tRAS-min:
+ $ref: /schemas/types.yaml#/definitions/uint32
+ description: |
+ Row active time in pico seconds.
+
+ tRCD:
+ $ref: /schemas/types.yaml#/definitions/uint32
+ description: |
+ RAS-to-CAS delay in pico seconds.
+
+ tRPab:
+ $ref: /schemas/types.yaml#/definitions/uint32
+ description: |
+ Row precharge time (all banks) in pico seconds.
+
+ tRRD:
+ $ref: /schemas/types.yaml#/definitions/uint32
+ description: |
+ Active bank A to active bank B in pico seconds.
+
+ tRTP:
+ $ref: /schemas/types.yaml#/definitions/uint32
+ description: |
+ Internal READ to PRECHARGE command delay in pico seconds.
+
+ tWR:
+ $ref: /schemas/types.yaml#/definitions/uint32
+ description: |
+ WRITE recovery time in pico seconds.
+
+ tWTR:
+ $ref: /schemas/types.yaml#/definitions/uint32
+ description: |
+ Internal WRITE-to-READ command delay in pico seconds.
+
+ tXP:
+ $ref: /schemas/types.yaml#/definitions/uint32
+ description: |
+ Exit power-down to next valid command delay in pico seconds.
+
+ tZQCL:
+ $ref: /schemas/types.yaml#/definitions/uint32
+ description: |
+ Long calibration time in pico seconds.
+
+ tZQCS:
+ $ref: /schemas/types.yaml#/definitions/uint32
+ description: |
+ Short calibration time in pico seconds.
+
+ tZQinit:
+ $ref: /schemas/types.yaml#/definitions/uint32
+ description: |
+ Initialization calibration time in pico seconds.
+
+required:
+ - compatible
+ - min-freq
+ - max-freq
+
+additionalProperties: false
+
+examples:
+ - |
+ timings {
+ compatible = "jedec,lpddr2-timings";
+ min-freq = <10000000>;
+ max-freq = <400000000>;
+ tCKESR = <15000>;
+ tDQSCK-max = <5500>;
+ tFAW = <50000>;
+ tRAS-max-ns = <70000>;
+ tRAS-min = <42000>;
+ tRPab = <21000>;
+ tRCD = <18000>;
+ tRRD = <10000>;
+ tRTP = <7500>;
+ tWR = <15000>;
+ tWTR = <7500>;
+ tXP = <7500>;
+ tZQCL = <360000>;
+ tZQCS = <90000>;
+ tZQinit = <1000000>;
+ };
diff --git a/Documentation/devicetree/bindings/memory-controllers/ddr/jedec,lpddr2.yaml b/Documentation/devicetree/bindings/memory-controllers/ddr/jedec,lpddr2.yaml
index 25ed0266f6dd..dd2141cad866 100644
--- a/Documentation/devicetree/bindings/memory-controllers/ddr/jedec,lpddr2.yaml
+++ b/Documentation/devicetree/bindings/memory-controllers/ddr/jedec,lpddr2.yaml
@@ -30,12 +30,26 @@ properties:
maximum: 255
description: |
Revision 1 value of SDRAM chip. Obtained from device datasheet.
+ Property is deprecated, use revision-id instead.
+ deprecated: true
revision-id2:
$ref: /schemas/types.yaml#/definitions/uint32
maximum: 255
description: |
Revision 2 value of SDRAM chip. Obtained from device datasheet.
+ Property is deprecated, use revision-id instead.
+ deprecated: true
+
+ revision-id:
+ $ref: /schemas/types.yaml#/definitions/uint32-array
+ description: |
+ Revision IDs read from Mode Register 6 and 7. One byte per uint32 cell (i.e. <MR6 MR7>).
+ minItems: 2
+ maxItems: 2
+ items:
+ minimum: 0
+ maximum: 255
density:
$ref: /schemas/types.yaml#/definitions/uint32
@@ -142,14 +156,12 @@ properties:
patternProperties:
"^lpddr2-timings":
- type: object
+ $ref: jedec,lpddr2-timings.yaml
description: |
The lpddr2 node may have one or more child nodes of type "lpddr2-timings".
"lpddr2-timings" provides AC timing parameters of the device for
a given speed-bin. The user may provide the timings for as many
- speed-bins as is required. Please see Documentation/devicetree/
- bindings/memory-controllers/ddr/lpddr2-timings.txt for more information
- on "lpddr2-timings".
+ speed-bins as is required.
required:
- compatible
@@ -164,8 +176,7 @@ examples:
compatible = "elpida,ECB240ABACN", "jedec,lpddr2-s4";
density = <2048>;
io-width = <32>;
- revision-id1 = <1>;
- revision-id2 = <0>;
+ revision-id = <1 0>;
tRPab-min-tck = <3>;
tRCD-min-tck = <3>;
diff --git a/Documentation/devicetree/bindings/memory-controllers/ddr/jedec,lpddr3-timings.yaml b/Documentation/devicetree/bindings/memory-controllers/ddr/jedec,lpddr3-timings.yaml
new file mode 100644
index 000000000000..97c3e988af5f
--- /dev/null
+++ b/Documentation/devicetree/bindings/memory-controllers/ddr/jedec,lpddr3-timings.yaml
@@ -0,0 +1,157 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/memory-controllers/ddr/jedec,lpddr3-timings.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: LPDDR3 SDRAM AC timing parameters for a given speed-bin
+
+maintainers:
+ - Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>
+
+properties:
+ compatible:
+ const: jedec,lpddr3-timings
+
+ reg:
+ maxItems: 1
+ description: |
+ Maximum DDR clock frequency for the speed-bin, in Hz.
+ Property is deprecated, use max-freq.
+ deprecated: true
+
+ max-freq:
+ $ref: /schemas/types.yaml#/definitions/uint32
+ description: |
+ Maximum DDR clock frequency for the speed-bin, in Hz.
+
+ min-freq:
+ $ref: /schemas/types.yaml#/definitions/uint32
+ description: |
+ Minimum DDR clock frequency for the speed-bin, in Hz.
+
+ tCKE:
+ $ref: /schemas/types.yaml#/definitions/uint32
+ description: |
+ CKE minimum pulse width (HIGH and LOW pulse width) in pico seconds.
+
+ tCKESR:
+ $ref: /schemas/types.yaml#/definitions/uint32
+ description: |
+ CKE minimum pulse width during SELF REFRESH (low pulse width during
+ SELF REFRESH) in pico seconds.
+
+ tFAW:
+ $ref: /schemas/types.yaml#/definitions/uint32
+ description: |
+ Four-bank activate window in pico seconds.
+
+ tMRD:
+ $ref: /schemas/types.yaml#/definitions/uint32
+ description: |
+ Mode register set command delay in pico seconds.
+
+ tR2R-C2C:
+ $ref: /schemas/types.yaml#/definitions/uint32
+ description: |
+ Additional READ-to-READ delay in chip-to-chip cases in pico seconds.
+
+ tRAS:
+ $ref: /schemas/types.yaml#/definitions/uint32
+ description: |
+ Row active time in pico seconds.
+
+ tRC:
+ $ref: /schemas/types.yaml#/definitions/uint32
+ description: |
+ ACTIVATE-to-ACTIVATE command period in pico seconds.
+
+ tRCD:
+ $ref: /schemas/types.yaml#/definitions/uint32
+ description: |
+ RAS-to-CAS delay in pico seconds.
+
+ tRFC:
+ $ref: /schemas/types.yaml#/definitions/uint32
+ description: |
+ Refresh Cycle time in pico seconds.
+
+ tRPab:
+ $ref: /schemas/types.yaml#/definitions/uint32
+ description: |
+ Row precharge time (all banks) in pico seconds.
+
+ tRPpb:
+ $ref: /schemas/types.yaml#/definitions/uint32
+ description: |
+ Row precharge time (single banks) in pico seconds.
+
+ tRRD:
+ $ref: /schemas/types.yaml#/definitions/uint32
+ description: |
+ Active bank A to active bank B in pico seconds.
+
+ tRTP:
+ $ref: /schemas/types.yaml#/definitions/uint32
+ description: |
+ Internal READ to PRECHARGE command delay in pico seconds.
+
+ tW2W-C2C:
+ $ref: /schemas/types.yaml#/definitions/uint32
+ description: |
+ Additional WRITE-to-WRITE delay in chip-to-chip cases in pico seconds.
+
+ tWR:
+ $ref: /schemas/types.yaml#/definitions/uint32
+ description: |
+ WRITE recovery time in pico seconds.
+
+ tWTR:
+ $ref: /schemas/types.yaml#/definitions/uint32
+ description: |
+ Internal WRITE-to-READ command delay in pico seconds.
+
+ tXP:
+ $ref: /schemas/types.yaml#/definitions/uint32
+ description: |
+ Exit power-down to next valid command delay in pico seconds.
+
+ tXSR:
+ $ref: /schemas/types.yaml#/definitions/uint32
+ description: |
+ SELF REFRESH exit to next valid command delay in pico seconds.
+
+required:
+ - compatible
+ - min-freq
+ - max-freq
+
+additionalProperties: false
+
+examples:
+ - |
+ lpddr3 {
+ timings {
+ compatible = "jedec,lpddr3-timings";
+ max-freq = <800000000>;
+ min-freq = <100000000>;
+ tCKE = <3750>;
+ tCKESR = <3750>;
+ tFAW = <25000>;
+ tMRD = <7000>;
+ tR2R-C2C = <0>;
+ tRAS = <23000>;
+ tRC = <33750>;
+ tRCD = <10000>;
+ tRFC = <65000>;
+ tRPab = <12000>;
+ tRPpb = <12000>;
+ tRRD = <6000>;
+ tRTP = <3750>;
+ tW2W-C2C = <0>;
+ tWR = <7500>;
+ tWTR = <3750>;
+ tXP = <3750>;
+ tXSR = <70000>;
+ };
+ };
diff --git a/Documentation/devicetree/bindings/memory-controllers/ddr/jedec,lpddr3.yaml b/Documentation/devicetree/bindings/memory-controllers/ddr/jedec,lpddr3.yaml
new file mode 100644
index 000000000000..c542f32c39fa
--- /dev/null
+++ b/Documentation/devicetree/bindings/memory-controllers/ddr/jedec,lpddr3.yaml
@@ -0,0 +1,263 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/memory-controllers/ddr/jedec,lpddr3.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: LPDDR3 SDRAM compliant to JEDEC JESD209-3
+
+maintainers:
+ - Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>
+
+properties:
+ compatible:
+ items:
+ - enum:
+ - samsung,K3QF2F20DB
+ - const: jedec,lpddr3
+
+ '#address-cells':
+ const: 1
+ deprecated: true
+
+ density:
+ $ref: /schemas/types.yaml#/definitions/uint32
+ description: |
+ Density in megabits of SDRAM chip.
+ enum:
+ - 4096
+ - 8192
+ - 16384
+ - 32768
+
+ io-width:
+ $ref: /schemas/types.yaml#/definitions/uint32
+ description: |
+ IO bus width in bits of SDRAM chip.
+ enum:
+ - 32
+ - 16
+
+ manufacturer-id:
+ $ref: /schemas/types.yaml#/definitions/uint32
+ description: |
+ Manufacturer ID value read from Mode Register 5. The property is
+ deprecated, manufacturer should be derived from the compatible.
+ deprecated: true
+
+ revision-id:
+ $ref: /schemas/types.yaml#/definitions/uint32-array
+ minItems: 2
+ maxItems: 2
+ items:
+ maximum: 255
+ description: |
+ Revision value of SDRAM chip read from Mode Registers 6 and 7.
+
+ '#size-cells':
+ const: 0
+ deprecated: true
+
+ tCKE-min-tck:
+ $ref: /schemas/types.yaml#/definitions/uint32
+ maximum: 15
+ description: |
+ CKE minimum pulse width (HIGH and LOW pulse width) in terms of number
+ of clock cycles.
+
+ tCKESR-min-tck:
+ $ref: /schemas/types.yaml#/definitions/uint32
+ maximum: 15
+ description: |
+ CKE minimum pulse width during SELF REFRESH (low pulse width during
+ SELF REFRESH) in terms of number of clock cycles.
+
+ tDQSCK-min-tck:
+ $ref: /schemas/types.yaml#/definitions/uint32
+ maximum: 15
+ description: |
+ DQS output data access time from CK_t/CK_c in terms of number of clock
+ cycles.
+
+ tFAW-min-tck:
+ $ref: /schemas/types.yaml#/definitions/uint32
+ maximum: 63
+ description: |
+ Four-bank activate window in terms of number of clock cycles.
+
+ tMRD-min-tck:
+ $ref: /schemas/types.yaml#/definitions/uint32
+ maximum: 15
+ description: |
+ Mode register set command delay in terms of number of clock cycles.
+
+ tR2R-C2C-min-tck:
+ $ref: /schemas/types.yaml#/definitions/uint32
+ enum: [0, 1]
+ description: |
+ Additional READ-to-READ delay in chip-to-chip cases in terms of number
+ of clock cycles.
+
+ tRAS-min-tck:
+ $ref: /schemas/types.yaml#/definitions/uint32
+ maximum: 63
+ description: |
+ Row active time in terms of number of clock cycles.
+
+ tRC-min-tck:
+ $ref: /schemas/types.yaml#/definitions/uint32
+ maximum: 63
+ description: |
+ ACTIVATE-to-ACTIVATE command period in terms of number of clock cycles.
+
+ tRCD-min-tck:
+ $ref: /schemas/types.yaml#/definitions/uint32
+ maximum: 15
+ description: |
+ RAS-to-CAS delay in terms of number of clock cycles.
+
+ tRFC-min-tck:
+ $ref: /schemas/types.yaml#/definitions/uint32
+ maximum: 255
+ description: |
+ Refresh Cycle time in terms of number of clock cycles.
+
+ tRL-min-tck:
+ $ref: /schemas/types.yaml#/definitions/uint32
+ maximum: 15
+ description: |
+ READ data latency in terms of number of clock cycles.
+
+ tRPab-min-tck:
+ $ref: /schemas/types.yaml#/definitions/uint32
+ maximum: 15
+ description: |
+ Row precharge time (all banks) in terms of number of clock cycles.
+
+ tRPpb-min-tck:
+ $ref: /schemas/types.yaml#/definitions/uint32
+ maximum: 15
+ description: |
+ Row precharge time (single banks) in terms of number of clock cycles.
+
+ tRRD-min-tck:
+ $ref: /schemas/types.yaml#/definitions/uint32
+ maximum: 15
+ description: |
+ Active bank A to active bank B in terms of number of clock cycles.
+
+ tRTP-min-tck:
+ $ref: /schemas/types.yaml#/definitions/uint32
+ maximum: 15
+ description: |
+ Internal READ to PRECHARGE command delay in terms of number of clock
+ cycles.
+
+ tW2W-C2C-min-tck:
+ $ref: /schemas/types.yaml#/definitions/uint32
+ enum: [0, 1]
+ description: |
+ Additional WRITE-to-WRITE delay in chip-to-chip cases in terms of number
+ of clock cycles.
+
+ tWL-min-tck:
+ $ref: /schemas/types.yaml#/definitions/uint32
+ maximum: 15
+ description: |
+ WRITE data latency in terms of number of clock cycles.
+
+ tWR-min-tck:
+ $ref: /schemas/types.yaml#/definitions/uint32
+ maximum: 15
+ description: |
+ WRITE recovery time in terms of number of clock cycles.
+
+ tWTR-min-tck:
+ $ref: /schemas/types.yaml#/definitions/uint32
+ maximum: 15
+ description: |
+ Internal WRITE-to-READ command delay in terms of number of clock cycles.
+
+ tXP-min-tck:
+ $ref: /schemas/types.yaml#/definitions/uint32
+ maximum: 255
+ description: |
+ Exit power-down to next valid command delay in terms of number of clock
+ cycles.
+
+ tXSR-min-tck:
+ $ref: /schemas/types.yaml#/definitions/uint32
+ maximum: 1023
+ description: |
+ SELF REFRESH exit to next valid command delay in terms of number of clock
+ cycles.
+
+patternProperties:
+ "^timings((-[0-9])+|(@[0-9a-f]+))?$":
+ $ref: jedec,lpddr3-timings.yaml
+ description: |
+ The lpddr3 node may have one or more child nodes with timings.
+ Each timing node provides AC timing parameters of the device for a given
+ speed-bin. The user may provide the timings for as many speed-bins as is
+ required.
+
+required:
+ - compatible
+ - density
+ - io-width
+
+additionalProperties: false
+
+examples:
+ - |
+ lpddr3 {
+ compatible = "samsung,K3QF2F20DB", "jedec,lpddr3";
+ density = <16384>;
+ io-width = <32>;
+
+ tCKE-min-tck = <2>;
+ tCKESR-min-tck = <2>;
+ tDQSCK-min-tck = <5>;
+ tFAW-min-tck = <5>;
+ tMRD-min-tck = <5>;
+ tR2R-C2C-min-tck = <0>;
+ tRAS-min-tck = <5>;
+ tRC-min-tck = <6>;
+ tRCD-min-tck = <3>;
+ tRFC-min-tck = <17>;
+ tRL-min-tck = <14>;
+ tRPab-min-tck = <2>;
+ tRPpb-min-tck = <2>;
+ tRRD-min-tck = <2>;
+ tRTP-min-tck = <2>;
+ tW2W-C2C-min-tck = <0>;
+ tWL-min-tck = <8>;
+ tWR-min-tck = <7>;
+ tWTR-min-tck = <2>;
+ tXP-min-tck = <2>;
+ tXSR-min-tck = <12>;
+
+ timings {
+ compatible = "jedec,lpddr3-timings";
+ max-freq = <800000000>;
+ min-freq = <100000000>;
+ tCKE = <3750>;
+ tCKESR = <3750>;
+ tFAW = <25000>;
+ tMRD = <7000>;
+ tR2R-C2C = <0>;
+ tRAS = <23000>;
+ tRC = <33750>;
+ tRCD = <10000>;
+ tRFC = <65000>;
+ tRPab = <12000>;
+ tRPpb = <12000>;
+ tRRD = <6000>;
+ tRTP = <3750>;
+ tW2W-C2C = <0>;
+ tWR = <7500>;
+ tWTR = <3750>;
+ tXP = <3750>;
+ tXSR = <70000>;
+ };
+ };
diff --git a/Documentation/devicetree/bindings/memory-controllers/ddr/lpddr2-timings.txt b/Documentation/devicetree/bindings/memory-controllers/ddr/lpddr2-timings.txt
deleted file mode 100644
index 9ceb19e0c7fd..000000000000
--- a/Documentation/devicetree/bindings/memory-controllers/ddr/lpddr2-timings.txt
+++ /dev/null
@@ -1,52 +0,0 @@
-* AC timing parameters of LPDDR2(JESD209-2) memories for a given speed-bin
-
-Required properties:
-- compatible : Should be "jedec,lpddr2-timings"
-- min-freq : minimum DDR clock frequency for the speed-bin. Type is <u32>
-- max-freq : maximum DDR clock frequency for the speed-bin. Type is <u32>
-
-Optional properties:
-
-The following properties represent AC timing parameters from the memory
-data-sheet of the device for a given speed-bin. All these properties are
-of type <u32> and the default unit is ps (pico seconds). Parameters with
-a different unit have a suffix indicating the unit such as 'tRAS-max-ns'
-- tRCD
-- tWR
-- tRAS-min
-- tRRD
-- tWTR
-- tXP
-- tRTP
-- tDQSCK-max
-- tFAW
-- tZQCS
-- tZQinit
-- tRPab
-- tZQCL
-- tCKESR
-- tRAS-max-ns
-- tDQSCK-max-derated
-
-Example:
-
-timings_elpida_ECB240ABACN_400mhz: lpddr2-timings@0 {
- compatible = "jedec,lpddr2-timings";
- min-freq = <10000000>;
- max-freq = <400000000>;
- tRPab = <21000>;
- tRCD = <18000>;
- tWR = <15000>;
- tRAS-min = <42000>;
- tRRD = <10000>;
- tWTR = <7500>;
- tXP = <7500>;
- tRTP = <7500>;
- tCKESR = <15000>;
- tDQSCK-max = <5500>;
- tFAW = <50000>;
- tZQCS = <90000>;
- tZQCL = <360000>;
- tZQinit = <1000000>;
- tRAS-max-ns = <70000>;
-};
diff --git a/Documentation/devicetree/bindings/memory-controllers/ddr/lpddr3-timings.txt b/Documentation/devicetree/bindings/memory-controllers/ddr/lpddr3-timings.txt
deleted file mode 100644
index 84705e50a3fd..000000000000
--- a/Documentation/devicetree/bindings/memory-controllers/ddr/lpddr3-timings.txt
+++ /dev/null
@@ -1,58 +0,0 @@
-* AC timing parameters of LPDDR3 memories for a given speed-bin.
-
-The structures are based on LPDDR2 and extended where needed.
-
-Required properties:
-- compatible : Should be "jedec,lpddr3-timings"
-- min-freq : minimum DDR clock frequency for the speed-bin. Type is <u32>
-- reg : maximum DDR clock frequency for the speed-bin. Type is <u32>
-
-Optional properties:
-
-The following properties represent AC timing parameters from the memory
-data-sheet of the device for a given speed-bin. All these properties are
-of type <u32> and the default unit is ps (pico seconds).
-- tRFC
-- tRRD
-- tRPab
-- tRPpb
-- tRCD
-- tRC
-- tRAS
-- tWTR
-- tWR
-- tRTP
-- tW2W-C2C
-- tR2R-C2C
-- tFAW
-- tXSR
-- tXP
-- tCKE
-- tCKESR
-- tMRD
-
-Example:
-
-timings_samsung_K3QF2F20DB_800mhz: lpddr3-timings@800000000 {
- compatible = "jedec,lpddr3-timings";
- reg = <800000000>; /* workaround: it shows max-freq */
- min-freq = <100000000>;
- tRFC = <65000>;
- tRRD = <6000>;
- tRPab = <12000>;
- tRPpb = <12000>;
- tRCD = <10000>;
- tRC = <33750>;
- tRAS = <23000>;
- tWTR = <3750>;
- tWR = <7500>;
- tRTP = <3750>;
- tW2W-C2C = <0>;
- tR2R-C2C = <0>;
- tFAW = <25000>;
- tXSR = <70000>;
- tXP = <3750>;
- tCKE = <3750>;
- tCKESR = <3750>;
- tMRD = <7000>;
-};
diff --git a/Documentation/devicetree/bindings/memory-controllers/ddr/lpddr3.txt b/Documentation/devicetree/bindings/memory-controllers/ddr/lpddr3.txt
deleted file mode 100644
index 031af5fb0379..000000000000
--- a/Documentation/devicetree/bindings/memory-controllers/ddr/lpddr3.txt
+++ /dev/null
@@ -1,107 +0,0 @@
-* LPDDR3 SDRAM memories compliant to JEDEC JESD209-3C
-
-Required properties:
-- compatible : Should be "<vendor>,<type>", and generic value "jedec,lpddr3".
- Example "<vendor>,<type>" values:
- "samsung,K3QF2F20DB"
-
-- density : <u32> representing density in Mb (Mega bits)
-- io-width : <u32> representing bus width. Possible values are 8, 16, 32, 64
-- #address-cells: Must be set to 1
-- #size-cells: Must be set to 0
-
-Optional properties:
-
-- manufacturer-id : <u32> Manufacturer ID value read from Mode Register 5
-- revision-id : <u32 u32> Revision IDs read from Mode Registers 6 and 7
-
-The following optional properties represent the minimum value of some AC
-timing parameters of the DDR device in terms of number of clock cycles.
-These values shall be obtained from the device data-sheet.
-- tRFC-min-tck
-- tRRD-min-tck
-- tRPab-min-tck
-- tRPpb-min-tck
-- tRCD-min-tck
-- tRC-min-tck
-- tRAS-min-tck
-- tWTR-min-tck
-- tWR-min-tck
-- tRTP-min-tck
-- tW2W-C2C-min-tck
-- tR2R-C2C-min-tck
-- tWL-min-tck
-- tDQSCK-min-tck
-- tRL-min-tck
-- tFAW-min-tck
-- tXSR-min-tck
-- tXP-min-tck
-- tCKE-min-tck
-- tCKESR-min-tck
-- tMRD-min-tck
-
-Child nodes:
-- The lpddr3 node may have one or more child nodes of type "lpddr3-timings".
- "lpddr3-timings" provides AC timing parameters of the device for
- a given speed-bin. Please see
- Documentation/devicetree/bindings/memory-controllers/ddr/lpddr3-timings.txt
- for more information on "lpddr3-timings"
-
-Example:
-
-samsung_K3QF2F20DB: lpddr3 {
- compatible = "samsung,K3QF2F20DB", "jedec,lpddr3";
- density = <16384>;
- io-width = <32>;
- manufacturer-id = <1>;
- revision-id = <123 234>;
- #address-cells = <1>;
- #size-cells = <0>;
-
- tRFC-min-tck = <17>;
- tRRD-min-tck = <2>;
- tRPab-min-tck = <2>;
- tRPpb-min-tck = <2>;
- tRCD-min-tck = <3>;
- tRC-min-tck = <6>;
- tRAS-min-tck = <5>;
- tWTR-min-tck = <2>;
- tWR-min-tck = <7>;
- tRTP-min-tck = <2>;
- tW2W-C2C-min-tck = <0>;
- tR2R-C2C-min-tck = <0>;
- tWL-min-tck = <8>;
- tDQSCK-min-tck = <5>;
- tRL-min-tck = <14>;
- tFAW-min-tck = <5>;
- tXSR-min-tck = <12>;
- tXP-min-tck = <2>;
- tCKE-min-tck = <2>;
- tCKESR-min-tck = <2>;
- tMRD-min-tck = <5>;
-
- timings_samsung_K3QF2F20DB_800mhz: lpddr3-timings@800000000 {
- compatible = "jedec,lpddr3-timings";
- /* workaround: 'reg' shows max-freq */
- reg = <800000000>;
- min-freq = <100000000>;
- tRFC = <65000>;
- tRRD = <6000>;
- tRPab = <12000>;
- tRPpb = <12000>;
- tRCD = <10000>;
- tRC = <33750>;
- tRAS = <23000>;
- tWTR = <3750>;
- tWR = <7500>;
- tRTP = <3750>;
- tW2W-C2C = <0>;
- tR2R-C2C = <0>;
- tFAW = <25000>;
- tXSR = <70000>;
- tXP = <3750>;
- tCKE = <3750>;
- tCKESR = <3750>;
- tMRD = <7000>;
- };
-}
diff --git a/Documentation/devicetree/bindings/memory-controllers/fsl/fsl,ifc.yaml b/Documentation/devicetree/bindings/memory-controllers/fsl/fsl,ifc.yaml
new file mode 100644
index 000000000000..3be1db30bf41
--- /dev/null
+++ b/Documentation/devicetree/bindings/memory-controllers/fsl/fsl,ifc.yaml
@@ -0,0 +1,113 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/memory-controllers/fsl/fsl,ifc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: FSL/NXP Integrated Flash Controller
+
+maintainers:
+ - Li Yang <leoyang.li@nxp.com>
+
+description: |
+ NXP's integrated flash controller (IFC) is an advanced version of the
+ enhanced local bus controller which includes similar programming and signal
+ interfaces with an extended feature set. The IFC provides access to multiple
+ external memory types, such as NAND flash (SLC and MLC), NOR flash, EPROM,
+ SRAM and other memories where address and data are shared on a bus.
+
+properties:
+ $nodename:
+ pattern: "^memory-controller@[0-9a-f]+$"
+
+ compatible:
+ const: fsl,ifc
+
+ "#address-cells":
+ enum: [2, 3]
+ description: |
+ Should be either two or three. The first cell is the chipselect
+ number, and the remaining cells are the offset into the chipselect.
+
+ "#size-cells":
+ enum: [1, 2]
+ description: |
+ Either one or two, depending on how large each chipselect can be.
+
+ reg:
+ maxItems: 1
+
+ interrupts:
+ minItems: 1
+ maxItems: 2
+ description: |
+ IFC may have one or two interrupts. If two interrupt specifiers are
+ present, the first is the "common" interrupt (CM_EVTER_STAT), and the
+ second is the NAND interrupt (NAND_EVTER_STAT). If there is only one,
+ that interrupt reports both types of event.
+
+ little-endian:
+ type: boolean
+ description: |
+ If this property is absent, the big-endian mode will be in use as default
+ for registers.
+
+ ranges:
+ description: |
+ Each range corresponds to a single chipselect, and covers the entire
+ access window as configured.
+
+patternProperties:
+ "^.*@[a-f0-9]+(,[a-f0-9]+)+$":
+ type: object
+ description: |
+ Child device nodes describe the devices connected to IFC such as NOR (e.g.
+ cfi-flash) and NAND (fsl,ifc-nand). There might be board specific devices
+ like FPGAs, CPLDs, etc.
+
+ required:
+ - compatible
+ - reg
+
+required:
+ - compatible
+ - reg
+ - interrupts
+
+additionalProperties: false
+
+examples:
+ - |
+ soc {
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ memory-controller@ffe1e000 {
+ compatible = "fsl,ifc";
+ #address-cells = <2>;
+ #size-cells = <1>;
+ reg = <0x0 0xffe1e000 0 0x2000>;
+ interrupts = <16 2 19 2>;
+ little-endian;
+
+ /* NOR, NAND Flashes and CPLD on board */
+ ranges = <0x0 0x0 0x0 0xee000000 0x02000000>,
+ <0x1 0x0 0x0 0xffa00000 0x00010000>,
+ <0x3 0x0 0x0 0xffb00000 0x00020000>;
+
+ flash@0,0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "cfi-flash";
+ reg = <0x0 0x0 0x2000000>;
+ bank-width = <2>;
+ device-width = <1>;
+
+ partition@0 {
+ /* 32MB for user data */
+ reg = <0x0 0x02000000>;
+ label = "NOR Data";
+ };
+ };
+ };
+ };
diff --git a/Documentation/devicetree/bindings/memory-controllers/fsl/ifc.txt b/Documentation/devicetree/bindings/memory-controllers/fsl/ifc.txt
deleted file mode 100644
index 89427b018ba7..000000000000
--- a/Documentation/devicetree/bindings/memory-controllers/fsl/ifc.txt
+++ /dev/null
@@ -1,82 +0,0 @@
-Integrated Flash Controller
-
-Properties:
-- name : Should be ifc
-- compatible : should contain "fsl,ifc". The version of the integrated
- flash controller can be found in the IFC_REV register at
- offset zero.
-
-- #address-cells : Should be either two or three. The first cell is the
- chipselect number, and the remaining cells are the
- offset into the chipselect.
-- #size-cells : Either one or two, depending on how large each chipselect
- can be.
-- reg : Offset and length of the register set for the device
-- interrupts: IFC may have one or two interrupts. If two interrupt
- specifiers are present, the first is the "common"
- interrupt (CM_EVTER_STAT), and the second is the NAND
- interrupt (NAND_EVTER_STAT). If there is only one,
- that interrupt reports both types of event.
-
-- little-endian : If this property is absent, the big-endian mode will
- be in use as default for registers.
-
-- ranges : Each range corresponds to a single chipselect, and covers
- the entire access window as configured.
-
-Child device nodes describe the devices connected to IFC such as NOR (e.g.
-cfi-flash) and NAND (fsl,ifc-nand). There might be board specific devices
-like FPGAs, CPLDs, etc.
-
-Example:
-
- ifc@ffe1e000 {
- compatible = "fsl,ifc", "simple-bus";
- #address-cells = <2>;
- #size-cells = <1>;
- reg = <0x0 0xffe1e000 0 0x2000>;
- interrupts = <16 2 19 2>;
- little-endian;
-
- /* NOR, NAND Flashes and CPLD on board */
- ranges = <0x0 0x0 0x0 0xee000000 0x02000000
- 0x1 0x0 0x0 0xffa00000 0x00010000
- 0x3 0x0 0x0 0xffb00000 0x00020000>;
-
- flash@0,0 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "cfi-flash";
- reg = <0x0 0x0 0x2000000>;
- bank-width = <2>;
- device-width = <1>;
-
- partition@0 {
- /* 32MB for user data */
- reg = <0x0 0x02000000>;
- label = "NOR Data";
- };
- };
-
- flash@1,0 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "fsl,ifc-nand";
- reg = <0x1 0x0 0x10000>;
-
- partition@0 {
- /* This location must not be altered */
- /* 1MB for u-boot Bootloader Image */
- reg = <0x0 0x00100000>;
- label = "NAND U-Boot Image";
- read-only;
- };
- };
-
- cpld@3,0 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "fsl,p1010rdb-cpld";
- reg = <0x3 0x0 0x000001f>;
- };
- };
diff --git a/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-common.yaml b/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-common.yaml
index 3a82b0b27fa0..a98b359bf909 100644
--- a/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-common.yaml
+++ b/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-common.yaml
@@ -16,7 +16,7 @@ description: |
MediaTek SMI have two generations of HW architecture, here is the list
which generation the SoCs use:
generation 1: mt2701 and mt7623.
- generation 2: mt2712, mt6779, mt8167, mt8173, mt8183, mt8192 and mt8195.
+ generation 2: mt2712, mt6779, mt8167, mt8173, mt8183, mt8186, mt8192 and mt8195.
There's slight differences between the two SMI, for generation 2, the
register which control the iommu port is at each larb's register base. But
@@ -35,6 +35,7 @@ properties:
- mediatek,mt8167-smi-common
- mediatek,mt8173-smi-common
- mediatek,mt8183-smi-common
+ - mediatek,mt8186-smi-common
- mediatek,mt8192-smi-common
- mediatek,mt8195-smi-common-vdo
- mediatek,mt8195-smi-common-vpp
@@ -88,10 +89,9 @@ allOf:
- mediatek,mt2701-smi-common
then:
properties:
- clock:
- items:
- minItems: 3
- maxItems: 3
+ clocks:
+ minItems: 3
+ maxItems: 3
clock-names:
items:
- const: apb
@@ -108,10 +108,9 @@ allOf:
required:
- mediatek,smi
properties:
- clock:
- items:
- minItems: 3
- maxItems: 3
+ clocks:
+ minItems: 3
+ maxItems: 3
clock-names:
items:
- const: apb
@@ -127,16 +126,16 @@ allOf:
enum:
- mediatek,mt6779-smi-common
- mediatek,mt8183-smi-common
+ - mediatek,mt8186-smi-common
- mediatek,mt8192-smi-common
- mediatek,mt8195-smi-common-vdo
- mediatek,mt8195-smi-common-vpp
then:
properties:
- clock:
- items:
- minItems: 4
- maxItems: 4
+ clocks:
+ minItems: 4
+ maxItems: 4
clock-names:
items:
- const: apb
@@ -146,10 +145,9 @@ allOf:
else: # for gen2 HW that don't have gals
properties:
- clock:
- items:
- minItems: 2
- maxItems: 2
+ clocks:
+ minItems: 2
+ maxItems: 2
clock-names:
items:
- const: apb
diff --git a/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.yaml b/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.yaml
index eaeff1ada7f8..4db8690829cd 100644
--- a/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.yaml
+++ b/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.yaml
@@ -23,6 +23,7 @@ properties:
- mediatek,mt8167-smi-larb
- mediatek,mt8173-smi-larb
- mediatek,mt8183-smi-larb
+ - mediatek,mt8186-smi-larb
- mediatek,mt8192-smi-larb
- mediatek,mt8195-smi-larb
@@ -75,15 +76,16 @@ allOf:
compatible:
enum:
- mediatek,mt8183-smi-larb
+ - mediatek,mt8186-smi-larb
- mediatek,mt8195-smi-larb
then:
properties:
- clock:
- items:
- minItems: 3
- maxItems: 3
+ clocks:
+ minItems: 2
+ maxItems: 3
clock-names:
+ minItems: 2
items:
- const: apb
- const: smi
@@ -91,10 +93,9 @@ allOf:
else:
properties:
- clock:
- items:
- minItems: 2
- maxItems: 2
+ clocks:
+ minItems: 2
+ maxItems: 2
clock-names:
items:
- const: apb
@@ -108,7 +109,7 @@ allOf:
- mediatek,mt2701-smi-larb
- mediatek,mt2712-smi-larb
- mediatek,mt6779-smi-larb
- - mediatek,mt8167-smi-larb
+ - mediatek,mt8186-smi-larb
- mediatek,mt8192-smi-larb
- mediatek,mt8195-smi-larb
diff --git a/Documentation/devicetree/bindings/memory-controllers/renesas,rpc-if.yaml b/Documentation/devicetree/bindings/memory-controllers/renesas,rpc-if.yaml
index 294f1036420d..9a6dbf54b540 100644
--- a/Documentation/devicetree/bindings/memory-controllers/renesas,rpc-if.yaml
+++ b/Documentation/devicetree/bindings/memory-controllers/renesas,rpc-if.yaml
@@ -40,7 +40,8 @@ properties:
- items:
- enum:
- renesas,r9a07g044-rpc-if # RZ/G2{L,LC}
- - const: renesas,rzg2l-rpc-if # RZ/G2L family
+ - renesas,r9a07g054-rpc-if # RZ/V2L
+ - const: renesas,rzg2l-rpc-if
reg:
items:
diff --git a/Documentation/devicetree/bindings/memory-controllers/samsung,exynos5422-dmc.yaml b/Documentation/devicetree/bindings/memory-controllers/samsung,exynos5422-dmc.yaml
index fe8639dcffab..044127788695 100644
--- a/Documentation/devicetree/bindings/memory-controllers/samsung,exynos5422-dmc.yaml
+++ b/Documentation/devicetree/bindings/memory-controllers/samsung,exynos5422-dmc.yaml
@@ -51,8 +51,7 @@ properties:
$ref: '/schemas/types.yaml#/definitions/phandle'
description: |
phandle of the connected DRAM memory device. For more information please
- refer to documentation file:
- Documentation/devicetree/bindings/memory-controllers/ddr/lpddr3.txt
+ refer to jedec,lpddr3.yaml.
operating-points-v2: true
diff --git a/Documentation/devicetree/bindings/mfd/brcm,cru.yaml b/Documentation/devicetree/bindings/mfd/brcm,cru.yaml
index be4a2df71c25..b85819fbb07c 100644
--- a/Documentation/devicetree/bindings/mfd/brcm,cru.yaml
+++ b/Documentation/devicetree/bindings/mfd/brcm,cru.yaml
@@ -39,7 +39,7 @@ patternProperties:
'^phy@[a-f0-9]+$':
$ref: ../phy/bcm-ns-usb2-phy.yaml
- '^pin-controller@[a-f0-9]+$':
+ '^pinctrl@[a-f0-9]+$':
$ref: ../pinctrl/brcm,ns-pinmux.yaml
'^syscon@[a-f0-9]+$':
@@ -94,7 +94,7 @@ examples:
reg = <0x180 0x4>;
};
- pin-controller@1c0 {
+ pinctrl@1c0 {
compatible = "brcm,bcm4708-pinmux";
reg = <0x1c0 0x24>;
reg-names = "cru_gpio_control";
diff --git a/Documentation/devicetree/bindings/mfd/cirrus,lochnagar.yaml b/Documentation/devicetree/bindings/mfd/cirrus,lochnagar.yaml
index c00ad3e21c21..ad285cb480c9 100644
--- a/Documentation/devicetree/bindings/mfd/cirrus,lochnagar.yaml
+++ b/Documentation/devicetree/bindings/mfd/cirrus,lochnagar.yaml
@@ -126,7 +126,7 @@ properties:
clock-frequency:
const: 12288000
- lochnagar-pinctrl:
+ pinctrl:
type: object
$ref: /schemas/pinctrl/cirrus,lochnagar.yaml#
@@ -255,7 +255,7 @@ required:
- reg
- reset-gpios
- lochnagar-clk
- - lochnagar-pinctrl
+ - pinctrl
additionalProperties: false
@@ -293,7 +293,7 @@ examples:
clock-frequency = <32768>;
};
- lochnagar-pinctrl {
+ pinctrl {
compatible = "cirrus,lochnagar-pinctrl";
gpio-controller;
diff --git a/Documentation/devicetree/bindings/mfd/google,cros-ec.yaml b/Documentation/devicetree/bindings/mfd/google,cros-ec.yaml
index d1f53bd449f7..4caadf73fc4a 100644
--- a/Documentation/devicetree/bindings/mfd/google,cros-ec.yaml
+++ b/Documentation/devicetree/bindings/mfd/google,cros-ec.yaml
@@ -31,7 +31,7 @@ properties:
controller-data:
description:
- SPI controller data, see bindings/spi/spi-samsung.txt
+ SPI controller data, see bindings/spi/samsung,spi-peripheral-props.yaml
type: object
google,cros-ec-spi-pre-delay:
@@ -148,18 +148,21 @@ patternProperties:
required:
- compatible
-if:
- properties:
- compatible:
- contains:
- enum:
- - google,cros-ec-i2c
- - google,cros-ec-rpmsg
-then:
- properties:
- google,cros-ec-spi-pre-delay: false
- google,cros-ec-spi-msg-delay: false
- spi-max-frequency: false
+allOf:
+ - if:
+ properties:
+ compatible:
+ contains:
+ enum:
+ - google,cros-ec-i2c
+ - google,cros-ec-rpmsg
+ then:
+ properties:
+ google,cros-ec-spi-pre-delay: false
+ google,cros-ec-spi-msg-delay: false
+ spi-max-frequency: false
+ else:
+ $ref: /schemas/spi/spi-peripheral-props.yaml
additionalProperties: false
@@ -200,7 +203,7 @@ examples:
spi-max-frequency = <5000000>;
proximity {
- compatible = "google,cros-ec-mkbp-proximity";
+ compatible = "google,cros-ec-mkbp-proximity";
};
cbas {
diff --git a/Documentation/devicetree/bindings/mfd/max14577.txt b/Documentation/devicetree/bindings/mfd/max14577.txt
deleted file mode 100644
index be11943a0560..000000000000
--- a/Documentation/devicetree/bindings/mfd/max14577.txt
+++ /dev/null
@@ -1,147 +0,0 @@
-Maxim MAX14577/77836 Multi-Function Device
-
-MAX14577 is a Multi-Function Device with Micro-USB Interface Circuit, Li+
-Battery Charger and SFOUT LDO output for powering USB devices. It is
-interfaced to host controller using I2C.
-
-MAX77836 additionally contains PMIC (with two LDO regulators) and Fuel Gauge.
-For the description of Fuel Gauge low SOC alert interrupt see:
-../power/supply/max17040_battery.txt
-
-
-Required properties:
-- compatible : Must be "maxim,max14577" or "maxim,max77836".
-- reg : I2C slave address for the max14577 chip (0x25 for max14577/max77836)
-- interrupts : IRQ line for the chip.
-
-
-Required nodes:
- - charger :
- Node for configuring the charger driver.
- Required properties:
- - compatible : "maxim,max14577-charger"
- or "maxim,max77836-charger"
- - maxim,fast-charge-uamp : Current in uA for Fast Charge;
- Valid values:
- - for max14577: 90000 - 950000;
- - for max77836: 45000 - 475000;
- - maxim,eoc-uamp : Current in uA for End-Of-Charge mode;
- Valid values:
- - for max14577: 50000 - 200000;
- - for max77836: 5000 - 100000;
- - maxim,ovp-uvolt : OverVoltage Protection Threshold in uV;
- In an overvoltage condition, INT asserts and charging
- stops. Valid values:
- - 6000000, 6500000, 7000000, 7500000;
- - maxim,constant-uvolt : Battery Constant Voltage in uV;
- Valid values:
- - 4000000 - 4280000 (step by 20000);
- - 4350000;
-
-
-Optional nodes:
-- max14577-muic/max77836-muic :
- Node used only by extcon consumers.
- Required properties:
- - compatible : "maxim,max14577-muic" or "maxim,max77836-muic"
-
-- regulators :
- Required properties:
- - compatible : "maxim,max14577-regulator"
- or "maxim,max77836-regulator"
-
- May contain a sub-node per regulator from the list below. Each
- sub-node should contain the constraints and initialization information
- for that regulator. See regulator.txt for a description of standard
- properties for these sub-nodes.
-
- List of valid regulator names:
- - for max14577: CHARGER, SAFEOUT.
- - for max77836: CHARGER, SAFEOUT, LDO1, LDO2.
-
- The SAFEOUT is a fixed voltage regulator so there is no need to specify
- voltages for it.
-
-
-Example:
-
-#include <dt-bindings/interrupt-controller/irq.h>
-
-max14577@25 {
- compatible = "maxim,max14577";
- reg = <0x25>;
- interrupt-parent = <&gpx1>;
- interrupts = <5 IRQ_TYPE_LEVEL_LOW>;
-
- muic: max14577-muic {
- compatible = "maxim,max14577-muic";
- };
-
- regulators {
- compatible = "maxim,max14577-regulator";
-
- SAFEOUT {
- regulator-name = "SAFEOUT";
- };
- CHARGER {
- regulator-name = "CHARGER";
- regulator-min-microamp = <90000>;
- regulator-max-microamp = <950000>;
- regulator-boot-on;
- };
- };
-
- charger {
- compatible = "maxim,max14577-charger";
-
- maxim,constant-uvolt = <4350000>;
- maxim,fast-charge-uamp = <450000>;
- maxim,eoc-uamp = <50000>;
- maxim,ovp-uvolt = <6500000>;
- };
-};
-
-
-max77836@25 {
- compatible = "maxim,max77836";
- reg = <0x25>;
- interrupt-parent = <&gpx1>;
- interrupts = <5 IRQ_TYPE_LEVEL_LOW>;
-
- muic: max77836-muic {
- compatible = "maxim,max77836-muic";
- };
-
- regulators {
- compatible = "maxim,max77836-regulator";
-
- SAFEOUT {
- regulator-name = "SAFEOUT";
- };
- CHARGER {
- regulator-name = "CHARGER";
- regulator-min-microamp = <90000>;
- regulator-max-microamp = <950000>;
- regulator-boot-on;
- };
- LDO1 {
- regulator-name = "LDO1";
- regulator-min-microvolt = <2700000>;
- regulator-max-microvolt = <2700000>;
- };
- LDO2 {
- regulator-name = "LDO2";
- regulator-min-microvolt = <800000>;
- regulator-max-microvolt = <3950000>;
- };
- };
-
- charger {
- compatible = "maxim,max77836-charger";
-
- maxim,constant-uvolt = <4350000>;
- maxim,fast-charge-uamp = <225000>;
- maxim,eoc-uamp = <7500>;
- maxim,ovp-uvolt = <6500000>;
- };
-};
diff --git a/Documentation/devicetree/bindings/mfd/max77802.txt b/Documentation/devicetree/bindings/mfd/max77802.txt
deleted file mode 100644
index 09decac20d91..000000000000
--- a/Documentation/devicetree/bindings/mfd/max77802.txt
+++ /dev/null
@@ -1,25 +0,0 @@
-Maxim MAX77802 multi-function device
-
-The Maxim MAX77802 is a Power Management IC (PMIC) that contains 10 high
-efficiency Buck regulators, 32 Low-DropOut (LDO) regulators used to power
-up application processors and peripherals, a 2-channel 32kHz clock outputs,
-a Real-Time-Clock (RTC) and a I2C interface to program the individual
-regulators, clocks outputs and the RTC.
-
-Bindings for the built-in 32k clock generator block and
-regulators are defined in ../clk/maxim,max77802.txt and
-../regulator/max77802.txt respectively.
-
-Required properties:
-- compatible : Must be "maxim,max77802"
-- reg : Specifies the I2C slave address of PMIC block.
-- interrupts : I2C device IRQ line connected to the main SoC.
-
-Example:
-
- max77802: pmic@9 {
- compatible = "maxim,max77802";
- interrupt-parent = <&intc>;
- interrupts = <26 IRQ_TYPE_NONE>;
- reg = <0x09>;
- };
diff --git a/Documentation/devicetree/bindings/mfd/maxim,max14577.yaml b/Documentation/devicetree/bindings/mfd/maxim,max14577.yaml
new file mode 100644
index 000000000000..27870b8760a6
--- /dev/null
+++ b/Documentation/devicetree/bindings/mfd/maxim,max14577.yaml
@@ -0,0 +1,195 @@
+# SPDX-License-Identifier: GPL-2.0-only
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/mfd/maxim,max14577.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Maxim MAX14577/MAX77836 MicroUSB and Companion Power Management IC
+
+maintainers:
+ - Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>
+
+description: |
+ This is a part of device tree bindings for Maxim MAX14577/MAX77836 MicroUSB
+ Integrated Circuit (MUIC).
+
+ The Maxim MAX14577 is a MicroUSB and Companion Power Management IC which
+ includes voltage safeout regulators, charger and MicroUSB management IC.
+
+ The Maxim MAX77836 is a MicroUSB and Companion Power Management IC which
+ includes voltage safeout and LDO regulators, charger, fuel-gauge and MicroUSB
+ management IC.
+
+properties:
+ compatible:
+ enum:
+ - maxim,max14577
+ - maxim,max77836
+
+ interrupts:
+ maxItems: 1
+
+ reg:
+ maxItems: 1
+
+ wakeup-source: true
+
+ charger:
+ $ref: /schemas/power/supply/maxim,max14577.yaml
+
+ extcon:
+ type: object
+ properties:
+ compatible:
+ enum:
+ - maxim,max14577-muic
+ - maxim,max77836-muic
+
+ required:
+ - compatible
+
+ regulators:
+ $ref: /schemas/regulator/maxim,max14577.yaml
+
+required:
+ - compatible
+ - interrupts
+ - reg
+ - charger
+
+allOf:
+ - if:
+ properties:
+ compatible:
+ contains:
+ const: maxim,max14577
+ then:
+ properties:
+ charger:
+ properties:
+ compatible:
+ const: maxim,max14577-charger
+ extcon:
+ properties:
+ compatible:
+ const: maxim,max14577-muic
+ regulator:
+ properties:
+ compatible:
+ const: maxim,max14577-regulator
+ else:
+ properties:
+ charger:
+ properties:
+ compatible:
+ const: maxim,max77836-charger
+ extcon:
+ properties:
+ compatible:
+ const: maxim,max77836-muic
+ regulator:
+ properties:
+ compatible:
+ const: maxim,max77836-regulator
+
+additionalProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/interrupt-controller/irq.h>
+
+ i2c {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pmic@25 {
+ compatible = "maxim,max14577";
+ reg = <0x25>;
+ interrupt-parent = <&gpx1>;
+ interrupts = <5 IRQ_TYPE_LEVEL_LOW>;
+
+ extcon {
+ compatible = "maxim,max14577-muic";
+ };
+
+ regulators {
+ compatible = "maxim,max14577-regulator";
+
+ SAFEOUT {
+ regulator-name = "SAFEOUT";
+ };
+
+ CHARGER {
+ regulator-name = "CHARGER";
+ regulator-min-microamp = <90000>;
+ regulator-max-microamp = <950000>;
+ regulator-boot-on;
+ };
+ };
+
+ charger {
+ compatible = "maxim,max14577-charger";
+
+ maxim,constant-uvolt = <4350000>;
+ maxim,fast-charge-uamp = <450000>;
+ maxim,eoc-uamp = <50000>;
+ maxim,ovp-uvolt = <6500000>;
+ };
+ };
+ };
+
+ - |
+ #include <dt-bindings/interrupt-controller/irq.h>
+
+ i2c {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pmic@25 {
+ compatible = "maxim,max77836";
+ interrupt-parent = <&gpx1>;
+ interrupts = <5 IRQ_TYPE_NONE>;
+ reg = <0x25>;
+ wakeup-source;
+
+ extcon {
+ compatible = "maxim,max77836-muic";
+ };
+
+ regulators {
+ compatible = "maxim,max77836-regulator";
+
+ SAFEOUT {
+ regulator-name = "SAFEOUT";
+ };
+
+ CHARGER {
+ regulator-name = "CHARGER";
+ regulator-min-microamp = <45000>;
+ regulator-max-microamp = <475000>;
+ regulator-boot-on;
+ };
+
+ LDO1 {
+ regulator-name = "MOT_2.7V";
+ regulator-min-microvolt = <1100000>;
+ regulator-max-microvolt = <2700000>;
+ };
+
+ LDO2 {
+ regulator-name = "UNUSED_LDO2";
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <3950000>;
+ };
+ };
+
+ charger {
+ compatible = "maxim,max77836-charger";
+
+ maxim,constant-uvolt = <4350000>;
+ maxim,fast-charge-uamp = <225000>;
+ maxim,eoc-uamp = <7500>;
+ maxim,ovp-uvolt = <6500000>;
+ };
+ };
+ };
diff --git a/Documentation/devicetree/bindings/mfd/maxim,max77802.yaml b/Documentation/devicetree/bindings/mfd/maxim,max77802.yaml
new file mode 100644
index 000000000000..baa1346ac5d5
--- /dev/null
+++ b/Documentation/devicetree/bindings/mfd/maxim,max77802.yaml
@@ -0,0 +1,194 @@
+# SPDX-License-Identifier: GPL-2.0-only
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/mfd/maxim,max77802.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Maxim MAX77802 Power Management IC
+
+maintainers:
+ - Javier Martinez Canillas <javier@dowhile0.org>
+ - Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>
+
+description: |
+ This is a part of device tree bindings for Maxim MAX77802 Power Management
+ Integrated Circuit (PMIC).
+
+ The Maxim MAX77802 is a Power Management IC which includes voltage and
+ current regulators (10 high efficiency Buck regulators and 32 Low-DropOut
+ (LDO)), RTC and clock outputs.
+
+ The MAX77802 provides two 32.768khz clock outputs that can be controlled
+ (gated/ungated) over I2C. The clock IDs are defined as preprocessor macros
+ in dt-bindings/clock/maxim,max77802.h.
+
+properties:
+ compatible:
+ const: maxim,max77802
+
+ '#clock-cells':
+ const: 1
+
+ interrupts:
+ maxItems: 1
+
+ reg:
+ maxItems: 1
+
+ regulators:
+ $ref: /schemas/regulator/maxim,max77802.yaml
+ description:
+ List of child nodes that specify the regulators.
+
+ inb1-supply:
+ description: Power supply for buck1
+ inb2-supply:
+ description: Power supply for buck2
+ inb3-supply:
+ description: Power supply for buck3
+ inb4-supply:
+ description: Power supply for buck4
+ inb5-supply:
+ description: Power supply for buck5
+ inb6-supply:
+ description: Power supply for buck6
+ inb7-supply:
+ description: Power supply for buck7
+ inb8-supply:
+ description: Power supply for buck8
+ inb9-supply:
+ description: Power supply for buck9
+ inb10-supply:
+ description: Power supply for buck10
+
+ inl1-supply:
+ description: Power supply for LDO8, LDO15
+ inl2-supply:
+ description: Power supply for LDO17, LDO27, LDO30, LDO35
+ inl3-supply:
+ description: Power supply for LDO3, LDO5, LDO7, LDO7
+ inl4-supply:
+ description: Power supply for LDO10, LDO11, LDO13, LDO14
+ inl5-supply:
+ description: Power supply for LDO9, LDO19
+ inl6-supply:
+ description: Power supply for LDO4, LDO21, LDO24, LDO33
+ inl7-supply:
+ description: Power supply for LDO18, LDO20, LDO28, LDO29
+ inl9-supply:
+ description: Power supply for LDO12, LDO23, LDO25, LDO26, LDO32, LDO34
+ inl10-supply:
+ description: Power supply for LDO1, LDO2
+
+ wakeup-source: true
+
+required:
+ - compatible
+ - '#clock-cells'
+ - reg
+
+additionalProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/interrupt-controller/irq.h>
+ #include <dt-bindings/regulator/maxim,max77802.h>
+
+ i2c {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pmic@9 {
+ compatible = "maxim,max77802";
+ interrupt-parent = <&gpx3>;
+ interrupts = <1 IRQ_TYPE_NONE>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&max77802_irq>, <&pmic_selb>,
+ <&pmic_dvs_1>, <&pmic_dvs_2>, <&pmic_dvs_3>;
+ wakeup-source;
+ reg = <0x9>;
+ #clock-cells = <1>;
+
+ inb1-supply = <&tps65090_dcdc2>;
+ inb2-supply = <&tps65090_dcdc1>;
+ inb3-supply = <&tps65090_dcdc2>;
+ inb4-supply = <&tps65090_dcdc2>;
+ inb5-supply = <&tps65090_dcdc1>;
+ inb6-supply = <&tps65090_dcdc2>;
+ inb7-supply = <&tps65090_dcdc1>;
+ inb8-supply = <&tps65090_dcdc1>;
+ inb9-supply = <&tps65090_dcdc1>;
+ inb10-supply = <&tps65090_dcdc1>;
+
+ inl1-supply = <&buck5_reg>;
+ inl2-supply = <&buck7_reg>;
+ inl3-supply = <&buck9_reg>;
+ inl4-supply = <&buck9_reg>;
+ inl5-supply = <&buck9_reg>;
+ inl6-supply = <&tps65090_dcdc2>;
+ inl7-supply = <&buck9_reg>;
+ inl9-supply = <&tps65090_dcdc2>;
+ inl10-supply = <&buck7_reg>;
+
+ regulators {
+ BUCK1 {
+ regulator-name = "vdd_mif";
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1300000>;
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-ramp-delay = <12500>;
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ BUCK2 {
+ regulator-name = "vdd_arm";
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1500000>;
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-ramp-delay = <12500>;
+ regulator-coupled-with = <&buck3_reg>;
+ regulator-coupled-max-spread = <300000>;
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ // ...
+
+ BUCK10 {
+ regulator-name = "vdd_1v8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ };
+ };
+
+ LDO1 {
+ regulator-name = "vdd_1v0";
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1000000>;
+ regulator-always-on;
+ regulator-initial-mode = <MAX77802_OPMODE_NORMAL>;
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-mode = <MAX77802_OPMODE_LP>;
+ };
+ };
+
+ // ...
+
+ LDO35 {
+ regulator-name = "ldo_35";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ };
+ };
+ };
+ };
diff --git a/Documentation/devicetree/bindings/mfd/maxim,max77843.yaml b/Documentation/devicetree/bindings/mfd/maxim,max77843.yaml
new file mode 100644
index 000000000000..61a0f9dcb983
--- /dev/null
+++ b/Documentation/devicetree/bindings/mfd/maxim,max77843.yaml
@@ -0,0 +1,144 @@
+# SPDX-License-Identifier: GPL-2.0-only
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/mfd/maxim,max77843.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Maxim MAX77843 MicroUSB and Companion Power Management IC
+
+maintainers:
+ - Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>
+
+description: |
+ This is a part of device tree bindings for Maxim MAX77843 MicroUSB
+ Integrated Circuit (MUIC).
+
+ The Maxim MAX77843 is a MicroUSB and Companion Power Management IC which
+ includes voltage current regulators, charger, fuel-gauge, haptic motor driver
+ and MicroUSB management IC.
+
+properties:
+ compatible:
+ const: maxim,max77843
+
+ interrupts:
+ maxItems: 1
+
+ reg:
+ maxItems: 1
+
+ extcon:
+ $ref: /schemas/extcon/maxim,max77843.yaml
+
+ motor-driver:
+ type: object
+ properties:
+ compatible:
+ const: maxim,max77843-haptic
+
+ haptic-supply:
+ description: Power supply to the haptic motor
+
+ pwms:
+ maxItems: 1
+
+ required:
+ - compatible
+ - haptic-supply
+ - pwms
+
+ regulators:
+ $ref: /schemas/regulator/maxim,max77843.yaml
+
+required:
+ - compatible
+ - interrupts
+ - reg
+
+additionalProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/interrupt-controller/irq.h>
+
+ i2c {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pmic@66 {
+ compatible = "maxim,max77843";
+ interrupt-parent = <&gpa1>;
+ interrupts = <5 IRQ_TYPE_EDGE_FALLING>;
+ reg = <0x66>;
+
+ extcon {
+ compatible = "maxim,max77843-muic";
+
+ connector {
+ compatible = "samsung,usb-connector-11pin",
+ "usb-b-connector";
+ label = "micro-USB";
+ type = "micro";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ /*
+ * TODO: The DTS this is based on does not have
+ * port@0 which is a required property. The ports
+ * look incomplete and need fixing.
+ * Add a disabled port just to satisfy dtschema.
+ */
+ reg = <0>;
+ status = "disabled";
+ };
+
+ port@3 {
+ reg = <3>;
+ endpoint {
+ remote-endpoint = <&mhl_to_musb_con>;
+ };
+ };
+ };
+ };
+
+ ports {
+ port {
+ endpoint {
+ remote-endpoint = <&usb_to_muic>;
+ };
+ };
+ };
+ };
+
+ regulators {
+ compatible = "maxim,max77843-regulator";
+
+ SAFEOUT1 {
+ regulator-name = "SAFEOUT1";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <4950000>;
+ };
+
+ SAFEOUT2 {
+ regulator-name = "SAFEOUT2";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <4950000>;
+ };
+
+ CHARGER {
+ regulator-name = "CHARGER";
+ regulator-min-microamp = <100000>;
+ regulator-max-microamp = <3150000>;
+ };
+ };
+
+ motor-driver {
+ compatible = "maxim,max77843-haptic";
+ haptic-supply = <&ldo38_reg>;
+ pwms = <&pwm 0 33670 0>;
+ };
+ };
+ };
diff --git a/Documentation/devicetree/bindings/mfd/ti,j721e-system-controller.yaml b/Documentation/devicetree/bindings/mfd/ti,j721e-system-controller.yaml
index 272832e9f8f2..fa86691ebf16 100644
--- a/Documentation/devicetree/bindings/mfd/ti,j721e-system-controller.yaml
+++ b/Documentation/devicetree/bindings/mfd/ti,j721e-system-controller.yaml
@@ -20,7 +20,7 @@ description: |
maintainers:
- Kishon Vijay Abraham I <kishon@ti.com>
- - Roger Quadros <rogerq@ti.com
+ - Roger Quadros <rogerq@kernel.org>
properties:
compatible:
diff --git a/Documentation/devicetree/bindings/mmc/allwinner,sun4i-a10-mmc.yaml b/Documentation/devicetree/bindings/mmc/allwinner,sun4i-a10-mmc.yaml
index 4f62ad6ce50c..7803597b6366 100644
--- a/Documentation/devicetree/bindings/mmc/allwinner,sun4i-a10-mmc.yaml
+++ b/Documentation/devicetree/bindings/mmc/allwinner,sun4i-a10-mmc.yaml
@@ -24,6 +24,7 @@ properties:
- const: allwinner,sun7i-a20-mmc
- const: allwinner,sun8i-a83t-emmc
- const: allwinner,sun9i-a80-mmc
+ - const: allwinner,sun20i-d1-mmc
- const: allwinner,sun50i-a64-emmc
- const: allwinner,sun50i-a64-mmc
- const: allwinner,sun50i-a100-emmc
@@ -50,11 +51,17 @@ properties:
- const: allwinner,sun50i-h6-mmc
- const: allwinner,sun50i-a64-mmc
- items:
+ - const: allwinner,sun20i-d1-emmc
+ - const: allwinner,sun50i-a100-emmc
+ - items:
- const: allwinner,sun50i-h616-emmc
- const: allwinner,sun50i-a100-emmc
- items:
- const: allwinner,sun50i-h616-mmc
- const: allwinner,sun50i-a100-mmc
+ - items:
+ - const: allwinner,suniv-f1c100s-mmc
+ - const: allwinner,sun7i-a20-mmc
reg:
maxItems: 1
diff --git a/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.yaml b/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.yaml
index 17acbc665f5a..7dbbcae9485c 100644
--- a/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.yaml
+++ b/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.yaml
@@ -47,6 +47,7 @@ properties:
- const: fsl,imx7d-usdhc
- items:
- enum:
+ - fsl,imx93-usdhc
- fsl,imx8ulp-usdhc
- const: fsl,imx8mm-usdhc
diff --git a/Documentation/devicetree/bindings/mmc/litex,mmc.yaml b/Documentation/devicetree/bindings/mmc/litex,mmc.yaml
new file mode 100644
index 000000000000..ef9e0da44bf8
--- /dev/null
+++ b/Documentation/devicetree/bindings/mmc/litex,mmc.yaml
@@ -0,0 +1,78 @@
+# SPDX-License-Identifier: GPL-2.0-or-later OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/mmc/litex,mmc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: LiteX LiteSDCard device
+
+maintainers:
+ - Gabriel Somlo <gsomlo@gmail.com>
+
+description: |
+ LiteSDCard is a small footprint, configurable SDCard core for FPGA based
+ system on chips.
+
+ The hardware source is Open Source and can be found on at
+ https://github.com/enjoy-digital/litesdcard/.
+
+allOf:
+ - $ref: mmc-controller.yaml#
+
+properties:
+ compatible:
+ const: litex,mmc
+
+ reg:
+ items:
+ - description: PHY registers
+ - description: CORE registers
+ - description: DMA Reader buffer
+ - description: DMA Writer buffer
+ - description: IRQ registers
+ minItems: 4
+
+ reg-names:
+ items:
+ - const: phy
+ - const: core
+ - const: reader
+ - const: writer
+ - const: irq
+ minItems: 4
+
+ clocks:
+ maxItems: 1
+ description:
+ Handle to reference clock.
+
+ vmmc-supply:
+ description:
+ Handle to fixed-voltage supply for the card power.
+
+ interrupts:
+ maxItems: 1
+
+required:
+ - compatible
+ - reg
+ - reg-names
+ - clocks
+ - vmmc-supply
+
+additionalProperties: false
+
+examples:
+ - |
+ mmc: mmc@12005000 {
+ compatible = "litex,mmc";
+ reg = <0x12005000 0x100>,
+ <0x12003800 0x100>,
+ <0x12003000 0x100>,
+ <0x12004800 0x100>,
+ <0x12004000 0x100>;
+ reg-names = "phy", "core", "reader", "writer", "irq";
+ clocks = <&reference_clk>;
+ vmmc-supply = <&vreg_mmc>;
+ interrupts = <4>;
+ };
diff --git a/Documentation/devicetree/bindings/mmc/mtk-sd.yaml b/Documentation/devicetree/bindings/mmc/mtk-sd.yaml
index faf89b0c918f..297ada03e3de 100644
--- a/Documentation/devicetree/bindings/mmc/mtk-sd.yaml
+++ b/Documentation/devicetree/bindings/mmc/mtk-sd.yaml
@@ -30,6 +30,9 @@ properties:
- const: mediatek,mt7623-mmc
- const: mediatek,mt2701-mmc
- items:
+ - const: mediatek,mt8186-mmc
+ - const: mediatek,mt8183-mmc
+ - items:
- const: mediatek,mt8192-mmc
- const: mediatek,mt8183-mmc
- items:
diff --git a/Documentation/devicetree/bindings/mmc/renesas,sdhi.yaml b/Documentation/devicetree/bindings/mmc/renesas,sdhi.yaml
index 9ce6e06c19db..9ac4986988c5 100644
--- a/Documentation/devicetree/bindings/mmc/renesas,sdhi.yaml
+++ b/Documentation/devicetree/bindings/mmc/renesas,sdhi.yaml
@@ -57,7 +57,9 @@ properties:
- renesas,sdhi-r8a77990 # R-Car E3
- renesas,sdhi-r8a77995 # R-Car D3
- renesas,sdhi-r8a779a0 # R-Car V3U
+ - renesas,sdhi-r9a07g043 # RZ/G2UL
- renesas,sdhi-r9a07g044 # RZ/G2{L,LC}
+ - renesas,sdhi-r9a07g054 # RZ/V2L
- const: renesas,rcar-gen3-sdhi # R-Car Gen3 or RZ/G2
reg:
@@ -107,7 +109,10 @@ allOf:
properties:
compatible:
contains:
- const: renesas,sdhi-r9a07g044
+ enum:
+ - renesas,sdhi-r9a07g043
+ - renesas,sdhi-r9a07g044
+ - renesas,sdhi-r9a07g054
then:
properties:
clocks:
diff --git a/Documentation/devicetree/bindings/mmc/sdhci-am654.yaml b/Documentation/devicetree/bindings/mmc/sdhci-am654.yaml
index 9fbf16b3bc8d..0566493c4def 100644
--- a/Documentation/devicetree/bindings/mmc/sdhci-am654.yaml
+++ b/Documentation/devicetree/bindings/mmc/sdhci-am654.yaml
@@ -21,6 +21,7 @@ properties:
- const: ti,j721e-sdhci-4bit
- const: ti,am64-sdhci-8bit
- const: ti,am64-sdhci-4bit
+ - const: ti,am62-sdhci
- items:
- const: ti,j7200-sdhci-8bit
- const: ti,j721e-sdhci-8bit
diff --git a/Documentation/devicetree/bindings/mmc/sdhci-msm.txt b/Documentation/devicetree/bindings/mmc/sdhci-msm.txt
index 6a8cc261bf61..6216ed777343 100644
--- a/Documentation/devicetree/bindings/mmc/sdhci-msm.txt
+++ b/Documentation/devicetree/bindings/mmc/sdhci-msm.txt
@@ -14,6 +14,7 @@ Required properties:
full compatible strings with SoC and version:
"qcom,apq8084-sdhci", "qcom,sdhci-msm-v4"
"qcom,msm8226-sdhci", "qcom,sdhci-msm-v4"
+ "qcom,msm8953-sdhci", "qcom,sdhci-msm-v4"
"qcom,msm8974-sdhci", "qcom,sdhci-msm-v4"
"qcom,msm8916-sdhci", "qcom,sdhci-msm-v4"
"qcom,msm8992-sdhci", "qcom,sdhci-msm-v4"
diff --git a/Documentation/devicetree/bindings/mtd/jedec,spi-nor.yaml b/Documentation/devicetree/bindings/mtd/jedec,spi-nor.yaml
index 39421f7233e4..4abfb4cfc157 100644
--- a/Documentation/devicetree/bindings/mtd/jedec,spi-nor.yaml
+++ b/Documentation/devicetree/bindings/mtd/jedec,spi-nor.yaml
@@ -47,7 +47,8 @@ properties:
identified by the JEDEC READ ID opcode (0x9F).
reg:
- maxItems: 1
+ minItems: 1
+ maxItems: 2
spi-max-frequency: true
spi-rx-bus-width: true
diff --git a/Documentation/devicetree/bindings/nds32/andestech-boards b/Documentation/devicetree/bindings/nds32/andestech-boards
deleted file mode 100644
index f5d75693e3c7..000000000000
--- a/Documentation/devicetree/bindings/nds32/andestech-boards
+++ /dev/null
@@ -1,40 +0,0 @@
-Andestech(nds32) AE3XX Platform
------------------------------------------------------------------------------
-The AE3XX prototype demonstrates the AE3XX example platform on the FPGA. It
-is composed of one Andestech(nds32) processor and AE3XX.
-
-Required properties (in root node):
-- compatible = "andestech,ae3xx";
-
-Example:
-/dts-v1/;
-/ {
- compatible = "andestech,ae3xx";
- #address-cells = <1>;
- #size-cells = <1>;
- interrupt-parent = <&intc>;
-};
-
-Andestech(nds32) AG101P Platform
------------------------------------------------------------------------------
-AG101P is a generic SoC Platform IP that works with any of Andestech(nds32)
-processors to provide a cost-effective and high performance solution for
-majority of embedded systems in variety of application domains. Users may
-simply attach their IP on one of the system buses together with certain glue
-logics to complete a SoC solution for a specific application. With
-comprehensive simulation and design environments, users may evaluate the
-system performance of their applications and track bugs of their designs
-efficiently. The optional hardware development platform further provides real
-system environment for early prototyping and software/hardware co-development.
-
-Required properties (in root node):
- compatible = "andestech,ag101p";
-
-Example:
-/dts-v1/;
-/ {
- compatible = "andestech,ag101p";
- #address-cells = <1>;
- #size-cells = <1>;
- interrupt-parent = <&intc>;
-};
diff --git a/Documentation/devicetree/bindings/nds32/atl2c.txt b/Documentation/devicetree/bindings/nds32/atl2c.txt
deleted file mode 100644
index da8ab8e7ae9b..000000000000
--- a/Documentation/devicetree/bindings/nds32/atl2c.txt
+++ /dev/null
@@ -1,28 +0,0 @@
-* Andestech L2 cache Controller
-
-The level-2 cache controller plays an important role in reducing memory latency
-for high performance systems, such as thoese designs with AndesCore processors.
-Level-2 cache controller in general enhances overall system performance
-signigicantly and the system power consumption might be reduced as well by
-reducing DRAM accesses.
-
-This binding specifies what properties must be available in the device tree
-representation of an Andestech L2 cache controller.
-
-Required properties:
- - compatible:
- Usage: required
- Value type: <string>
- Definition: "andestech,atl2c"
- - reg : Physical base address and size of cache controller's memory mapped
- - cache-unified : Specifies the cache is a unified cache.
- - cache-level : Should be set to 2 for a level 2 cache.
-
-* Example
-
- cache-controller@e0500000 {
- compatible = "andestech,atl2c";
- reg = <0xe0500000 0x1000>;
- cache-unified;
- cache-level = <2>;
- };
diff --git a/Documentation/devicetree/bindings/nds32/cpus.txt b/Documentation/devicetree/bindings/nds32/cpus.txt
deleted file mode 100644
index 6f9e311b6589..000000000000
--- a/Documentation/devicetree/bindings/nds32/cpus.txt
+++ /dev/null
@@ -1,38 +0,0 @@
-* Andestech Processor Binding
-
-This binding specifies what properties must be available in the device tree
-representation of a Andestech Processor Core, which is the root node in the
-tree.
-
-Required properties:
-
- - compatible:
- Usage: required
- Value type: <string>
- Definition: Should be "andestech,<core_name>", "andestech,nds32v3" as fallback.
- Must contain "andestech,nds32v3" as the most generic value, in addition to
- one of the following identifiers for a particular CPU core:
- "andestech,n13"
- "andestech,n15"
- "andestech,d15"
- "andestech,n10"
- "andestech,d10"
- - device_type
- Usage: required
- Value type: <string>
- Definition: must be "cpu"
- - reg: Contains CPU index.
- - clock-frequency: Contains the clock frequency for CPU, in Hz.
-
-* Examples
-
-/ {
- cpus {
- cpu@0 {
- device_type = "cpu";
- compatible = "andestech,n13", "andestech,nds32v3";
- reg = <0x0>;
- clock-frequency = <60000000>
- };
- };
-};
diff --git a/Documentation/devicetree/bindings/net/can/allwinner,sun4i-a10-can.yaml b/Documentation/devicetree/bindings/net/can/allwinner,sun4i-a10-can.yaml
index c93fe9d3ea82..3c51b2d02957 100644
--- a/Documentation/devicetree/bindings/net/can/allwinner,sun4i-a10-can.yaml
+++ b/Documentation/devicetree/bindings/net/can/allwinner,sun4i-a10-can.yaml
@@ -10,6 +10,9 @@ maintainers:
- Chen-Yu Tsai <wens@csie.org>
- Maxime Ripard <mripard@kernel.org>
+allOf:
+ - $ref: can-controller.yaml#
+
properties:
compatible:
oneOf:
diff --git a/Documentation/devicetree/bindings/net/can/bosch,m_can.yaml b/Documentation/devicetree/bindings/net/can/bosch,m_can.yaml
index 401ab7cdb379..b7f9803c1c6d 100644
--- a/Documentation/devicetree/bindings/net/can/bosch,m_can.yaml
+++ b/Documentation/devicetree/bindings/net/can/bosch,m_can.yaml
@@ -9,7 +9,10 @@ title: Bosch MCAN controller Bindings
description: Bosch MCAN controller for CAN bus
maintainers:
- - Sriram Dash <sriram.dash@samsung.com>
+ - Chandrasekar Ramakrishnan <rcsekar@samsung.com>
+
+allOf:
+ - $ref: can-controller.yaml#
properties:
compatible:
@@ -66,8 +69,8 @@ properties:
M_CAN includes the following elements according to user manual:
11-bit Filter 0-128 elements / 0-128 words
29-bit Filter 0-64 elements / 0-128 words
- Rx FIFO 0 0-64 elements / 0-1152 words
- Rx FIFO 1 0-64 elements / 0-1152 words
+ Rx FIFO 0 0-64 elements / 0-1152 words
+ Rx FIFO 1 0-64 elements / 0-1152 words
Rx Buffers 0-64 elements / 0-1152 words
Tx Event FIFO 0-32 elements / 0-64 words
Tx Buffers 0-32 elements / 0-576 words
diff --git a/Documentation/devicetree/bindings/net/can/microchip,mcp251xfd.yaml b/Documentation/devicetree/bindings/net/can/microchip,mcp251xfd.yaml
index 2a884c1fe0e0..b3826af6bd6e 100644
--- a/Documentation/devicetree/bindings/net/can/microchip,mcp251xfd.yaml
+++ b/Documentation/devicetree/bindings/net/can/microchip,mcp251xfd.yaml
@@ -11,6 +11,9 @@ title:
maintainers:
- Marc Kleine-Budde <mkl@pengutronix.de>
+allOf:
+ - $ref: can-controller.yaml#
+
properties:
compatible:
oneOf:
diff --git a/Documentation/devicetree/bindings/net/can/renesas,rcar-canfd.yaml b/Documentation/devicetree/bindings/net/can/renesas,rcar-canfd.yaml
index 546c6e6d2fb0..91a3554ca950 100644
--- a/Documentation/devicetree/bindings/net/can/renesas,rcar-canfd.yaml
+++ b/Documentation/devicetree/bindings/net/can/renesas,rcar-canfd.yaml
@@ -35,6 +35,8 @@ properties:
- renesas,r9a07g044-canfd # RZ/G2{L,LC}
- const: renesas,rzg2l-canfd # RZ/G2L family
+ - const: renesas,r8a779a0-canfd # R-Car V3U
+
reg:
maxItems: 1
diff --git a/Documentation/devicetree/bindings/net/can/tcan4x5x.txt b/Documentation/devicetree/bindings/net/can/tcan4x5x.txt
index 0968b40aef1e..e3501bfa22e9 100644
--- a/Documentation/devicetree/bindings/net/can/tcan4x5x.txt
+++ b/Documentation/devicetree/bindings/net/can/tcan4x5x.txt
@@ -31,7 +31,7 @@ tcan4x5x: tcan4x5x@0 {
#address-cells = <1>;
#size-cells = <1>;
spi-max-frequency = <10000000>;
- bosch,mram-cfg = <0x0 0 0 32 0 0 1 1>;
+ bosch,mram-cfg = <0x0 0 0 16 0 0 1 1>;
interrupt-parent = <&gpio1>;
interrupts = <14 IRQ_TYPE_LEVEL_LOW>;
device-state-gpios = <&gpio3 21 GPIO_ACTIVE_HIGH>;
diff --git a/Documentation/devicetree/bindings/net/can/xilinx,can.yaml b/Documentation/devicetree/bindings/net/can/xilinx,can.yaml
new file mode 100644
index 000000000000..65af8183cb9c
--- /dev/null
+++ b/Documentation/devicetree/bindings/net/can/xilinx,can.yaml
@@ -0,0 +1,161 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/net/can/xilinx,can.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title:
+ Xilinx Axi CAN/Zynq CANPS controller
+
+maintainers:
+ - Appana Durga Kedareswara rao <appana.durga.rao@xilinx.com>
+
+properties:
+ compatible:
+ enum:
+ - xlnx,zynq-can-1.0
+ - xlnx,axi-can-1.00.a
+ - xlnx,canfd-1.0
+ - xlnx,canfd-2.0
+
+ reg:
+ maxItems: 1
+
+ interrupts:
+ maxItems: 1
+
+ clocks:
+ minItems: 1
+ maxItems: 2
+
+ clock-names:
+ maxItems: 2
+
+ power-domains:
+ maxItems: 1
+
+ tx-fifo-depth:
+ $ref: "/schemas/types.yaml#/definitions/uint32"
+ description: CAN Tx fifo depth (Zynq, Axi CAN).
+
+ rx-fifo-depth:
+ $ref: "/schemas/types.yaml#/definitions/uint32"
+ description: CAN Rx fifo depth (Zynq, Axi CAN, CAN FD in sequential Rx mode)
+
+ tx-mailbox-count:
+ $ref: "/schemas/types.yaml#/definitions/uint32"
+ description: CAN Tx mailbox buffer count (CAN FD)
+
+required:
+ - compatible
+ - reg
+ - interrupts
+ - clocks
+ - clock-names
+
+unevaluatedProperties: false
+
+allOf:
+ - $ref: can-controller.yaml#
+ - if:
+ properties:
+ compatible:
+ contains:
+ enum:
+ - xlnx,zynq-can-1.0
+
+ then:
+ properties:
+ clock-names:
+ items:
+ - const: can_clk
+ - const: pclk
+ required:
+ - tx-fifo-depth
+ - rx-fifo-depth
+
+ - if:
+ properties:
+ compatible:
+ contains:
+ enum:
+ - xlnx,axi-can-1.00.a
+
+ then:
+ properties:
+ clock-names:
+ items:
+ - const: can_clk
+ - const: s_axi_aclk
+ required:
+ - tx-fifo-depth
+ - rx-fifo-depth
+
+ - if:
+ properties:
+ compatible:
+ contains:
+ enum:
+ - xlnx,canfd-1.0
+ - xlnx,canfd-2.0
+
+ then:
+ properties:
+ clock-names:
+ items:
+ - const: can_clk
+ - const: s_axi_aclk
+ required:
+ - tx-mailbox-count
+ - rx-fifo-depth
+
+examples:
+ - |
+ #include <dt-bindings/interrupt-controller/arm-gic.h>
+
+ can@e0008000 {
+ compatible = "xlnx,zynq-can-1.0";
+ reg = <0xe0008000 0x1000>;
+ clocks = <&clkc 19>, <&clkc 36>;
+ clock-names = "can_clk", "pclk";
+ interrupts = <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-parent = <&intc>;
+ tx-fifo-depth = <0x40>;
+ rx-fifo-depth = <0x40>;
+ };
+
+ - |
+ can@40000000 {
+ compatible = "xlnx,axi-can-1.00.a";
+ reg = <0x40000000 0x10000>;
+ clocks = <&clkc 0>, <&clkc 1>;
+ clock-names = "can_clk", "s_axi_aclk";
+ interrupt-parent = <&intc>;
+ interrupts = <GIC_SPI 59 IRQ_TYPE_EDGE_RISING>;
+ tx-fifo-depth = <0x40>;
+ rx-fifo-depth = <0x40>;
+ };
+
+ - |
+ can@40000000 {
+ compatible = "xlnx,canfd-1.0";
+ reg = <0x40000000 0x2000>;
+ clocks = <&clkc 0>, <&clkc 1>;
+ clock-names = "can_clk", "s_axi_aclk";
+ interrupt-parent = <&intc>;
+ interrupts = <GIC_SPI 59 IRQ_TYPE_EDGE_RISING>;
+ tx-mailbox-count = <0x20>;
+ rx-fifo-depth = <0x20>;
+ };
+
+ - |
+ can@ff060000 {
+ compatible = "xlnx,canfd-2.0";
+ reg = <0xff060000 0x6000>;
+ clocks = <&clkc 0>, <&clkc 1>;
+ clock-names = "can_clk", "s_axi_aclk";
+ interrupt-parent = <&intc>;
+ interrupts = <GIC_SPI 59 IRQ_TYPE_EDGE_RISING>;
+ tx-mailbox-count = <0x20>;
+ rx-fifo-depth = <0x40>;
+ };
diff --git a/Documentation/devicetree/bindings/net/can/xilinx_can.txt b/Documentation/devicetree/bindings/net/can/xilinx_can.txt
deleted file mode 100644
index 100cc40b8510..000000000000
--- a/Documentation/devicetree/bindings/net/can/xilinx_can.txt
+++ /dev/null
@@ -1,61 +0,0 @@
-Xilinx Axi CAN/Zynq CANPS controller Device Tree Bindings
----------------------------------------------------------
-
-Required properties:
-- compatible : Should be:
- - "xlnx,zynq-can-1.0" for Zynq CAN controllers
- - "xlnx,axi-can-1.00.a" for Axi CAN controllers
- - "xlnx,canfd-1.0" for CAN FD controllers
- - "xlnx,canfd-2.0" for CAN FD 2.0 controllers
-- reg : Physical base address and size of the controller
- registers map.
-- interrupts : Property with a value describing the interrupt
- number.
-- clock-names : List of input clock names
- - "can_clk", "pclk" (For CANPS),
- - "can_clk", "s_axi_aclk" (For AXI CAN and CAN FD).
- (See clock bindings for details).
-- clocks : Clock phandles (see clock bindings for details).
-- tx-fifo-depth : Can Tx fifo depth (Zynq, Axi CAN).
-- rx-fifo-depth : Can Rx fifo depth (Zynq, Axi CAN, CAN FD in
- sequential Rx mode).
-- tx-mailbox-count : Can Tx mailbox buffer count (CAN FD).
-- rx-mailbox-count : Can Rx mailbox buffer count (CAN FD in mailbox Rx
- mode).
-
-
-Example:
-
-For Zynq CANPS Dts file:
- zynq_can_0: can@e0008000 {
- compatible = "xlnx,zynq-can-1.0";
- clocks = <&clkc 19>, <&clkc 36>;
- clock-names = "can_clk", "pclk";
- reg = <0xe0008000 0x1000>;
- interrupts = <0 28 4>;
- interrupt-parent = <&intc>;
- tx-fifo-depth = <0x40>;
- rx-fifo-depth = <0x40>;
- };
-For Axi CAN Dts file:
- axi_can_0: axi-can@40000000 {
- compatible = "xlnx,axi-can-1.00.a";
- clocks = <&clkc 0>, <&clkc 1>;
- clock-names = "can_clk","s_axi_aclk" ;
- reg = <0x40000000 0x10000>;
- interrupt-parent = <&intc>;
- interrupts = <0 59 1>;
- tx-fifo-depth = <0x40>;
- rx-fifo-depth = <0x40>;
- };
-For CAN FD Dts file:
- canfd_0: canfd@40000000 {
- compatible = "xlnx,canfd-1.0";
- clocks = <&clkc 0>, <&clkc 1>;
- clock-names = "can_clk", "s_axi_aclk";
- reg = <0x40000000 0x2000>;
- interrupt-parent = <&intc>;
- interrupts = <0 59 1>;
- tx-mailbox-count = <0x20>;
- rx-fifo-depth = <0x20>;
- };
diff --git a/Documentation/devicetree/bindings/net/cdns,macb.yaml b/Documentation/devicetree/bindings/net/cdns,macb.yaml
index 8dd06db34169..6cd3d853dcba 100644
--- a/Documentation/devicetree/bindings/net/cdns,macb.yaml
+++ b/Documentation/devicetree/bindings/net/cdns,macb.yaml
@@ -81,6 +81,25 @@ properties:
phy-handle: true
+ phys:
+ maxItems: 1
+
+ phy-names:
+ const: sgmii-phy
+ description:
+ Required with ZynqMP SoC when in SGMII mode.
+ Should reference PS-GTR generic PHY device for this controller
+ instance. See ZynqMP example.
+
+ resets:
+ maxItems: 1
+ description:
+ Recommended with ZynqMP, specify reset control for this
+ controller instance with zynqmp-reset driver.
+
+ reset-names:
+ maxItems: 1
+
fixed-link: true
iommus:
@@ -157,3 +176,40 @@ examples:
reset-gpios = <&pioE 6 1>;
};
};
+
+ - |
+ #include <dt-bindings/clock/xlnx-zynqmp-clk.h>
+ #include <dt-bindings/power/xlnx-zynqmp-power.h>
+ #include <dt-bindings/reset/xlnx-zynqmp-resets.h>
+ #include <dt-bindings/phy/phy.h>
+
+ bus {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ gem1: ethernet@ff0c0000 {
+ compatible = "cdns,zynqmp-gem", "cdns,gem";
+ interrupt-parent = <&gic>;
+ interrupts = <0 59 4>, <0 59 4>;
+ reg = <0x0 0xff0c0000 0x0 0x1000>;
+ clocks = <&zynqmp_clk LPD_LSBUS>, <&zynqmp_clk GEM1_REF>,
+ <&zynqmp_clk GEM1_TX>, <&zynqmp_clk GEM1_RX>,
+ <&zynqmp_clk GEM_TSU>;
+ clock-names = "pclk", "hclk", "tx_clk", "rx_clk", "tsu_clk";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ #stream-id-cells = <1>;
+ iommus = <&smmu 0x875>;
+ power-domains = <&zynqmp_firmware PD_ETH_1>;
+ resets = <&zynqmp_reset ZYNQMP_RESET_GEM1>;
+ reset-names = "gem1_rst";
+ status = "okay";
+ phy-mode = "sgmii";
+ phy-names = "sgmii-phy";
+ phys = <&psgtr 1 PHY_TYPE_SGMII 1 1>;
+ fixed-link {
+ speed = <1000>;
+ full-duplex;
+ pause;
+ };
+ };
+ };
diff --git a/Documentation/devicetree/bindings/net/davicom,dm9051.yaml b/Documentation/devicetree/bindings/net/davicom,dm9051.yaml
new file mode 100644
index 000000000000..52e852fef753
--- /dev/null
+++ b/Documentation/devicetree/bindings/net/davicom,dm9051.yaml
@@ -0,0 +1,62 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/net/davicom,dm9051.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Davicom DM9051 SPI Ethernet Controller
+
+maintainers:
+ - Joseph CHANG <josright123@gmail.com>
+
+description: |
+ The DM9051 is a fully integrated and cost-effective low pin count single
+ chip Fast Ethernet controller with a Serial Peripheral Interface (SPI).
+
+allOf:
+ - $ref: ethernet-controller.yaml#
+
+properties:
+ compatible:
+ const: davicom,dm9051
+
+ reg:
+ maxItems: 1
+
+ spi-max-frequency:
+ maximum: 45000000
+
+ interrupts:
+ maxItems: 1
+
+ local-mac-address: true
+
+ mac-address: true
+
+required:
+ - compatible
+ - reg
+ - spi-max-frequency
+ - interrupts
+
+additionalProperties: false
+
+examples:
+ # Raspberry Pi platform
+ - |
+ /* for Raspberry Pi with pin control stuff for GPIO irq */
+ #include <dt-bindings/interrupt-controller/irq.h>
+ #include <dt-bindings/gpio/gpio.h>
+ spi {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ ethernet@0 {
+ compatible = "davicom,dm9051";
+ reg = <0>; /* spi chip select */
+ local-mac-address = [00 00 00 00 00 00];
+ interrupt-parent = <&gpio>;
+ interrupts = <26 IRQ_TYPE_LEVEL_LOW>;
+ spi-max-frequency = <31200000>;
+ };
+ };
diff --git a/Documentation/devicetree/bindings/net/dsa/dsa-port.yaml b/Documentation/devicetree/bindings/net/dsa/dsa-port.yaml
index 702df848a71d..e60867c7c571 100644
--- a/Documentation/devicetree/bindings/net/dsa/dsa-port.yaml
+++ b/Documentation/devicetree/bindings/net/dsa/dsa-port.yaml
@@ -51,6 +51,8 @@ properties:
- edsa
- ocelot
- ocelot-8021q
+ - rtl8_4
+ - rtl8_4t
- seville
phy-handle: true
diff --git a/Documentation/devicetree/bindings/net/dsa/microchip,ksz.yaml b/Documentation/devicetree/bindings/net/dsa/microchip,ksz.yaml
index 84985f53bffd..184152087b60 100644
--- a/Documentation/devicetree/bindings/net/dsa/microchip,ksz.yaml
+++ b/Documentation/devicetree/bindings/net/dsa/microchip,ksz.yaml
@@ -42,6 +42,12 @@ properties:
description:
Set if the output SYNCLKO frequency should be set to 125MHz instead of 25MHz.
+ microchip,synclko-disable:
+ $ref: /schemas/types.yaml#/definitions/flag
+ description:
+ Set if the output SYNCLKO clock should be disabled. Do not mix with
+ microchip,synclko-125.
+
required:
- compatible
- reg
diff --git a/Documentation/devicetree/bindings/net/dsa/realtek-smi.txt b/Documentation/devicetree/bindings/net/dsa/realtek-smi.txt
deleted file mode 100644
index 7959ec237983..000000000000
--- a/Documentation/devicetree/bindings/net/dsa/realtek-smi.txt
+++ /dev/null
@@ -1,240 +0,0 @@
-Realtek SMI-based Switches
-==========================
-
-The SMI "Simple Management Interface" is a two-wire protocol using
-bit-banged GPIO that while it reuses the MDIO lines MCK and MDIO does
-not use the MDIO protocol. This binding defines how to specify the
-SMI-based Realtek devices.
-
-Required properties:
-
-- compatible: must be exactly one of:
- "realtek,rtl8365mb" (4+1 ports)
- "realtek,rtl8366"
- "realtek,rtl8366rb" (4+1 ports)
- "realtek,rtl8366s" (4+1 ports)
- "realtek,rtl8367"
- "realtek,rtl8367b"
- "realtek,rtl8368s" (8 port)
- "realtek,rtl8369"
- "realtek,rtl8370" (8 port)
-
-Required properties:
-- mdc-gpios: GPIO line for the MDC clock line.
-- mdio-gpios: GPIO line for the MDIO data line.
-- reset-gpios: GPIO line for the reset signal.
-
-Optional properties:
-- realtek,disable-leds: if the LED drivers are not used in the
- hardware design this will disable them so they are not turned on
- and wasting power.
-
-Required subnodes:
-
-- interrupt-controller
-
- This defines an interrupt controller with an IRQ line (typically
- a GPIO) that will demultiplex and handle the interrupt from the single
- interrupt line coming out of one of the SMI-based chips. It most
- importantly provides link up/down interrupts to the PHY blocks inside
- the ASIC.
-
-Required properties of interrupt-controller:
-
-- interrupt: parent interrupt, see interrupt-controller/interrupts.txt
-- interrupt-controller: see interrupt-controller/interrupts.txt
-- #address-cells: should be <0>
-- #interrupt-cells: should be <1>
-
-- mdio
-
- This defines the internal MDIO bus of the SMI device, mostly for the
- purpose of being able to hook the interrupts to the right PHY and
- the right PHY to the corresponding port.
-
-Required properties of mdio:
-
-- compatible: should be set to "realtek,smi-mdio" for all SMI devices
-
-See net/mdio.txt for additional MDIO bus properties.
-
-See net/dsa/dsa.txt for a list of additional required and optional properties
-and subnodes of DSA switches.
-
-Examples:
-
-An example for the RTL8366RB:
-
-switch {
- compatible = "realtek,rtl8366rb";
- /* 22 = MDIO (has input reads), 21 = MDC (clock, output only) */
- mdc-gpios = <&gpio0 21 GPIO_ACTIVE_HIGH>;
- mdio-gpios = <&gpio0 22 GPIO_ACTIVE_HIGH>;
- reset-gpios = <&gpio0 14 GPIO_ACTIVE_LOW>;
-
- switch_intc: interrupt-controller {
- /* GPIO 15 provides the interrupt */
- interrupt-parent = <&gpio0>;
- interrupts = <15 IRQ_TYPE_LEVEL_LOW>;
- interrupt-controller;
- #address-cells = <0>;
- #interrupt-cells = <1>;
- };
-
- ports {
- #address-cells = <1>;
- #size-cells = <0>;
- reg = <0>;
- port@0 {
- reg = <0>;
- label = "lan0";
- phy-handle = <&phy0>;
- };
- port@1 {
- reg = <1>;
- label = "lan1";
- phy-handle = <&phy1>;
- };
- port@2 {
- reg = <2>;
- label = "lan2";
- phy-handle = <&phy2>;
- };
- port@3 {
- reg = <3>;
- label = "lan3";
- phy-handle = <&phy3>;
- };
- port@4 {
- reg = <4>;
- label = "wan";
- phy-handle = <&phy4>;
- };
- port@5 {
- reg = <5>;
- label = "cpu";
- ethernet = <&gmac0>;
- phy-mode = "rgmii";
- fixed-link {
- speed = <1000>;
- full-duplex;
- };
- };
- };
-
- mdio {
- compatible = "realtek,smi-mdio", "dsa-mdio";
- #address-cells = <1>;
- #size-cells = <0>;
-
- phy0: phy@0 {
- reg = <0>;
- interrupt-parent = <&switch_intc>;
- interrupts = <0>;
- };
- phy1: phy@1 {
- reg = <1>;
- interrupt-parent = <&switch_intc>;
- interrupts = <1>;
- };
- phy2: phy@2 {
- reg = <2>;
- interrupt-parent = <&switch_intc>;
- interrupts = <2>;
- };
- phy3: phy@3 {
- reg = <3>;
- interrupt-parent = <&switch_intc>;
- interrupts = <3>;
- };
- phy4: phy@4 {
- reg = <4>;
- interrupt-parent = <&switch_intc>;
- interrupts = <12>;
- };
- };
-};
-
-An example for the RTL8365MB-VC:
-
-switch {
- compatible = "realtek,rtl8365mb";
- mdc-gpios = <&gpio1 16 GPIO_ACTIVE_HIGH>;
- mdio-gpios = <&gpio1 17 GPIO_ACTIVE_HIGH>;
- reset-gpios = <&gpio5 0 GPIO_ACTIVE_LOW>;
-
- switch_intc: interrupt-controller {
- interrupt-parent = <&gpio5>;
- interrupts = <1 IRQ_TYPE_LEVEL_LOW>;
- interrupt-controller;
- #address-cells = <0>;
- #interrupt-cells = <1>;
- };
-
- ports {
- #address-cells = <1>;
- #size-cells = <0>;
- reg = <0>;
- port@0 {
- reg = <0>;
- label = "swp0";
- phy-handle = <&ethphy0>;
- };
- port@1 {
- reg = <1>;
- label = "swp1";
- phy-handle = <&ethphy1>;
- };
- port@2 {
- reg = <2>;
- label = "swp2";
- phy-handle = <&ethphy2>;
- };
- port@3 {
- reg = <3>;
- label = "swp3";
- phy-handle = <&ethphy3>;
- };
- port@6 {
- reg = <6>;
- label = "cpu";
- ethernet = <&fec1>;
- phy-mode = "rgmii";
- tx-internal-delay-ps = <2000>;
- rx-internal-delay-ps = <2000>;
-
- fixed-link {
- speed = <1000>;
- full-duplex;
- pause;
- };
- };
- };
-
- mdio {
- compatible = "realtek,smi-mdio";
- #address-cells = <1>;
- #size-cells = <0>;
-
- ethphy0: phy@0 {
- reg = <0>;
- interrupt-parent = <&switch_intc>;
- interrupts = <0>;
- };
- ethphy1: phy@1 {
- reg = <1>;
- interrupt-parent = <&switch_intc>;
- interrupts = <1>;
- };
- ethphy2: phy@2 {
- reg = <2>;
- interrupt-parent = <&switch_intc>;
- interrupts = <2>;
- };
- ethphy3: phy@3 {
- reg = <3>;
- interrupt-parent = <&switch_intc>;
- interrupts = <3>;
- };
- };
-};
diff --git a/Documentation/devicetree/bindings/net/dsa/realtek.yaml b/Documentation/devicetree/bindings/net/dsa/realtek.yaml
new file mode 100644
index 000000000000..8756060895a8
--- /dev/null
+++ b/Documentation/devicetree/bindings/net/dsa/realtek.yaml
@@ -0,0 +1,394 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/net/dsa/realtek.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Realtek switches for unmanaged switches
+
+allOf:
+ - $ref: dsa.yaml#
+
+maintainers:
+ - Linus Walleij <linus.walleij@linaro.org>
+
+description:
+ Realtek advertises these chips as fast/gigabit switches or unmanaged
+ switches. They can be controlled using different interfaces, like SMI,
+ MDIO or SPI.
+
+ The SMI "Simple Management Interface" is a two-wire protocol using
+ bit-banged GPIO that while it reuses the MDIO lines MCK and MDIO does
+ not use the MDIO protocol. This binding defines how to specify the
+ SMI-based Realtek devices. The realtek-smi driver is a platform driver
+ and it must be inserted inside a platform node.
+
+ The MDIO-connected switches use MDIO protocol to access their registers.
+ The realtek-mdio driver is an MDIO driver and it must be inserted inside
+ an MDIO node.
+
+properties:
+ compatible:
+ enum:
+ - realtek,rtl8365mb
+ - realtek,rtl8366
+ - realtek,rtl8366rb
+ - realtek,rtl8366s
+ - realtek,rtl8367
+ - realtek,rtl8367b
+ - realtek,rtl8367rb
+ - realtek,rtl8367s
+ - realtek,rtl8368s
+ - realtek,rtl8369
+ - realtek,rtl8370
+ description: |
+ realtek,rtl8365mb: 4+1 ports
+ realtek,rtl8366: 5+1 ports
+ realtek,rtl8366rb: 5+1 ports
+ realtek,rtl8366s: 5+1 ports
+ realtek,rtl8367:
+ realtek,rtl8367b:
+ realtek,rtl8367rb: 5+2 ports
+ realtek,rtl8367s: 5+2 ports
+ realtek,rtl8368s: 8 ports
+ realtek,rtl8369: 8+1 ports
+ realtek,rtl8370: 8+2 ports
+
+ mdc-gpios:
+ description: GPIO line for the MDC clock line.
+ maxItems: 1
+
+ mdio-gpios:
+ description: GPIO line for the MDIO data line.
+ maxItems: 1
+
+ reset-gpios:
+ description: GPIO to be used to reset the whole device
+ maxItems: 1
+
+ realtek,disable-leds:
+ type: boolean
+ description: |
+ if the LED drivers are not used in the hardware design,
+ this will disable them so they are not turned on
+ and wasting power.
+
+ interrupt-controller:
+ type: object
+ description: |
+ This defines an interrupt controller with an IRQ line (typically
+ a GPIO) that will demultiplex and handle the interrupt from the single
+ interrupt line coming out of one of the Realtek switch chips. It most
+ importantly provides link up/down interrupts to the PHY blocks inside
+ the ASIC.
+
+ properties:
+
+ interrupt-controller: true
+
+ interrupts:
+ maxItems: 1
+ description:
+ A single IRQ line from the switch, either active LOW or HIGH
+
+ '#address-cells':
+ const: 0
+
+ '#interrupt-cells':
+ const: 1
+
+ required:
+ - interrupt-controller
+ - '#address-cells'
+ - '#interrupt-cells'
+
+ mdio:
+ $ref: /schemas/net/mdio.yaml#
+ unevaluatedProperties: false
+
+ properties:
+ compatible:
+ const: realtek,smi-mdio
+
+if:
+ required:
+ - reg
+
+then:
+ not:
+ required:
+ - mdc-gpios
+ - mdio-gpios
+ - mdio
+
+ properties:
+ mdc-gpios: false
+ mdio-gpios: false
+ mdio: false
+
+else:
+ required:
+ - mdc-gpios
+ - mdio-gpios
+ - mdio
+ - reset-gpios
+
+required:
+ - compatible
+
+ # - mdc-gpios
+ # - mdio-gpios
+ # - reset-gpios
+ # - mdio
+
+unevaluatedProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/gpio/gpio.h>
+ #include <dt-bindings/interrupt-controller/irq.h>
+
+ platform {
+ switch {
+ compatible = "realtek,rtl8366rb";
+ /* 22 = MDIO (has input reads), 21 = MDC (clock, output only) */
+ mdc-gpios = <&gpio0 21 GPIO_ACTIVE_HIGH>;
+ mdio-gpios = <&gpio0 22 GPIO_ACTIVE_HIGH>;
+ reset-gpios = <&gpio0 14 GPIO_ACTIVE_LOW>;
+
+ switch_intc1: interrupt-controller {
+ /* GPIO 15 provides the interrupt */
+ interrupt-parent = <&gpio0>;
+ interrupts = <15 IRQ_TYPE_LEVEL_LOW>;
+ interrupt-controller;
+ #address-cells = <0>;
+ #interrupt-cells = <1>;
+ };
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ port@0 {
+ reg = <0>;
+ label = "lan0";
+ phy-handle = <&phy0>;
+ };
+ port@1 {
+ reg = <1>;
+ label = "lan1";
+ phy-handle = <&phy1>;
+ };
+ port@2 {
+ reg = <2>;
+ label = "lan2";
+ phy-handle = <&phy2>;
+ };
+ port@3 {
+ reg = <3>;
+ label = "lan3";
+ phy-handle = <&phy3>;
+ };
+ port@4 {
+ reg = <4>;
+ label = "wan";
+ phy-handle = <&phy4>;
+ };
+ port@5 {
+ reg = <5>;
+ label = "cpu";
+ ethernet = <&gmac0>;
+ phy-mode = "rgmii";
+ fixed-link {
+ speed = <1000>;
+ full-duplex;
+ };
+ };
+ };
+
+ mdio {
+ compatible = "realtek,smi-mdio";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ phy0: ethernet-phy@0 {
+ reg = <0>;
+ interrupt-parent = <&switch_intc1>;
+ interrupts = <0>;
+ };
+ phy1: ethernet-phy@1 {
+ reg = <1>;
+ interrupt-parent = <&switch_intc1>;
+ interrupts = <1>;
+ };
+ phy2: ethernet-phy@2 {
+ reg = <2>;
+ interrupt-parent = <&switch_intc1>;
+ interrupts = <2>;
+ };
+ phy3: ethernet-phy@3 {
+ reg = <3>;
+ interrupt-parent = <&switch_intc1>;
+ interrupts = <3>;
+ };
+ phy4: ethernet-phy@4 {
+ reg = <4>;
+ interrupt-parent = <&switch_intc1>;
+ interrupts = <12>;
+ };
+ };
+ };
+ };
+
+ - |
+ #include <dt-bindings/gpio/gpio.h>
+ #include <dt-bindings/interrupt-controller/irq.h>
+
+ platform {
+ switch {
+ compatible = "realtek,rtl8365mb";
+ mdc-gpios = <&gpio1 16 GPIO_ACTIVE_HIGH>;
+ mdio-gpios = <&gpio1 17 GPIO_ACTIVE_HIGH>;
+ reset-gpios = <&gpio5 0 GPIO_ACTIVE_LOW>;
+
+ switch_intc2: interrupt-controller {
+ interrupt-parent = <&gpio5>;
+ interrupts = <1 IRQ_TYPE_LEVEL_LOW>;
+ interrupt-controller;
+ #address-cells = <0>;
+ #interrupt-cells = <1>;
+ };
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ port@0 {
+ reg = <0>;
+ label = "swp0";
+ phy-handle = <&ethphy0>;
+ };
+ port@1 {
+ reg = <1>;
+ label = "swp1";
+ phy-handle = <&ethphy1>;
+ };
+ port@2 {
+ reg = <2>;
+ label = "swp2";
+ phy-handle = <&ethphy2>;
+ };
+ port@3 {
+ reg = <3>;
+ label = "swp3";
+ phy-handle = <&ethphy3>;
+ };
+ port@6 {
+ reg = <6>;
+ label = "cpu";
+ ethernet = <&fec1>;
+ phy-mode = "rgmii";
+ tx-internal-delay-ps = <2000>;
+ rx-internal-delay-ps = <2000>;
+
+ fixed-link {
+ speed = <1000>;
+ full-duplex;
+ pause;
+ };
+ };
+ };
+
+ mdio {
+ compatible = "realtek,smi-mdio";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ ethphy0: ethernet-phy@0 {
+ reg = <0>;
+ interrupt-parent = <&switch_intc2>;
+ interrupts = <0>;
+ };
+ ethphy1: ethernet-phy@1 {
+ reg = <1>;
+ interrupt-parent = <&switch_intc2>;
+ interrupts = <1>;
+ };
+ ethphy2: ethernet-phy@2 {
+ reg = <2>;
+ interrupt-parent = <&switch_intc2>;
+ interrupts = <2>;
+ };
+ ethphy3: ethernet-phy@3 {
+ reg = <3>;
+ interrupt-parent = <&switch_intc2>;
+ interrupts = <3>;
+ };
+ };
+ };
+ };
+
+ - |
+ #include <dt-bindings/gpio/gpio.h>
+ #include <dt-bindings/interrupt-controller/irq.h>
+
+ mdio {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ switch@29 {
+ compatible = "realtek,rtl8367s";
+ reg = <29>;
+
+ reset-gpios = <&gpio2 20 GPIO_ACTIVE_LOW>;
+
+ switch_intc3: interrupt-controller {
+ interrupt-parent = <&gpio0>;
+ interrupts = <11 IRQ_TYPE_EDGE_FALLING>;
+ interrupt-controller;
+ #address-cells = <0>;
+ #interrupt-cells = <1>;
+ };
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+ label = "lan4";
+ };
+
+ port@1 {
+ reg = <1>;
+ label = "lan3";
+ };
+
+ port@2 {
+ reg = <2>;
+ label = "lan2";
+ };
+
+ port@3 {
+ reg = <3>;
+ label = "lan1";
+ };
+
+ port@4 {
+ reg = <4>;
+ label = "wan";
+ };
+
+ port@7 {
+ reg = <7>;
+ ethernet = <&ethernet>;
+ phy-mode = "rgmii";
+ tx-internal-delay-ps = <2000>;
+ rx-internal-delay-ps = <0>;
+
+ fixed-link {
+ speed = <1000>;
+ full-duplex;
+ };
+ };
+ };
+ };
+ };
diff --git a/Documentation/devicetree/bindings/net/fsl-fman.txt b/Documentation/devicetree/bindings/net/fsl-fman.txt
index 020337f3c05f..801efc7d6818 100644
--- a/Documentation/devicetree/bindings/net/fsl-fman.txt
+++ b/Documentation/devicetree/bindings/net/fsl-fman.txt
@@ -388,14 +388,24 @@ PROPERTIES
Value type: <prop-encoded-array>
Definition: A standard property.
-- bus-frequency
+- clocks
+ Usage: optional
+ Value type: <phandle>
+ Definition: A reference to the input clock of the controller
+ from which the MDC frequency is derived.
+
+- clock-frequency
Usage: optional
Value type: <u32>
- Definition: Specifies the external MDIO bus clock speed to
- be used, if different from the standard 2.5 MHz.
- This may be due to the standard speed being unsupported (e.g.
- due to a hardware problem), or to advertise that all relevant
- components in the system support a faster speed.
+ Definition: Specifies the external MDC frequency, in Hertz, to
+ be used. Requires that the input clock is specified in the
+ "clocks" property. See also: mdio.yaml.
+
+- suppress-preamble
+ Usage: optional
+ Value type: <boolean>
+ Definition: Disable generation of preamble bits. See also:
+ mdio.yaml.
- interrupts
Usage: required for external MDIO
diff --git a/Documentation/devicetree/bindings/net/marvell-armada-370-neta.txt b/Documentation/devicetree/bindings/net/marvell-armada-370-neta.txt
index 691f886cfc4a..2bf31572b08d 100644
--- a/Documentation/devicetree/bindings/net/marvell-armada-370-neta.txt
+++ b/Documentation/devicetree/bindings/net/marvell-armada-370-neta.txt
@@ -5,6 +5,7 @@ Required properties:
"marvell,armada-370-neta"
"marvell,armada-xp-neta"
"marvell,armada-3700-neta"
+ "marvell,armada-ac5-neta"
- reg: address and length of the register set for the device.
- interrupts: interrupt for the device
- phy: See ethernet.txt file in the same directory.
diff --git a/Documentation/devicetree/bindings/net/mctp-i2c-controller.yaml b/Documentation/devicetree/bindings/net/mctp-i2c-controller.yaml
new file mode 100644
index 000000000000..afd11c9422fa
--- /dev/null
+++ b/Documentation/devicetree/bindings/net/mctp-i2c-controller.yaml
@@ -0,0 +1,92 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/net/mctp-i2c-controller.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: MCTP I2C transport binding
+
+maintainers:
+ - Matt Johnston <matt@codeconstruct.com.au>
+
+description: |
+ An mctp-i2c-controller defines a local MCTP endpoint on an I2C controller.
+ MCTP I2C is specified by DMTF DSP0237.
+
+ An mctp-i2c-controller must be attached to an I2C adapter which supports
+ slave functionality. I2C busses (either directly or as subordinate mux
+ busses) are attached to the mctp-i2c-controller with a 'mctp-controller'
+ property on each used bus. Each mctp-controller I2C bus will be presented
+ to the host system as a separate MCTP I2C instance.
+
+properties:
+ compatible:
+ const: mctp-i2c-controller
+
+ reg:
+ minimum: 0x40000000
+ maximum: 0x4000007f
+ description: |
+ 7 bit I2C address of the local endpoint.
+ I2C_OWN_SLAVE_ADDRESS (1<<30) flag must be set.
+
+additionalProperties: false
+
+required:
+ - compatible
+ - reg
+
+examples:
+ - |
+ // Basic case of a single I2C bus
+ #include <dt-bindings/i2c/i2c.h>
+
+ i2c {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ mctp-controller;
+
+ mctp@30 {
+ compatible = "mctp-i2c-controller";
+ reg = <(0x30 | I2C_OWN_SLAVE_ADDRESS)>;
+ };
+ };
+
+ - |
+ // Mux topology with multiple MCTP-handling busses under
+ // a single mctp-i2c-controller.
+ // i2c1 and i2c6 can have MCTP devices, i2c5 does not.
+ #include <dt-bindings/i2c/i2c.h>
+
+ i2c1: i2c {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ mctp-controller;
+
+ mctp@50 {
+ compatible = "mctp-i2c-controller";
+ reg = <(0x50 | I2C_OWN_SLAVE_ADDRESS)>;
+ };
+ };
+
+ i2c-mux {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ i2c-parent = <&i2c1>;
+
+ i2c5: i2c@0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0>;
+ eeprom@33 {
+ reg = <0x33>;
+ };
+ };
+
+ i2c6: i2c@1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <1>;
+ mctp-controller;
+ };
+ };
diff --git a/Documentation/devicetree/bindings/net/mediatek-dwmac.txt b/Documentation/devicetree/bindings/net/mediatek-dwmac.txt
deleted file mode 100644
index afbcaebf062e..000000000000
--- a/Documentation/devicetree/bindings/net/mediatek-dwmac.txt
+++ /dev/null
@@ -1,91 +0,0 @@
-MediaTek DWMAC glue layer controller
-
-This file documents platform glue layer for stmmac.
-Please see stmmac.txt for the other unchanged properties.
-
-The device node has following properties.
-
-Required properties:
-- compatible: Should be "mediatek,mt2712-gmac" for MT2712 SoC
-- reg: Address and length of the register set for the device
-- interrupts: Should contain the MAC interrupts
-- interrupt-names: Should contain a list of interrupt names corresponding to
- the interrupts in the interrupts property, if available.
- Should be "macirq" for the main MAC IRQ
-- clocks: Must contain a phandle for each entry in clock-names.
-- clock-names: The name of the clock listed in the clocks property. These are
- "axi", "apb", "mac_main", "ptp_ref", "rmii_internal" for MT2712 SoC.
-- mac-address: See ethernet.txt in the same directory
-- phy-mode: See ethernet.txt in the same directory
-- mediatek,pericfg: A phandle to the syscon node that control ethernet
- interface and timing delay.
-
-Optional properties:
-- mediatek,tx-delay-ps: TX clock delay macro value. Default is 0.
- It should be defined for RGMII/MII interface.
- It should be defined for RMII interface when the reference clock is from MT2712 SoC.
-- mediatek,rx-delay-ps: RX clock delay macro value. Default is 0.
- It should be defined for RGMII/MII interface.
- It should be defined for RMII interface.
-Both delay properties need to be a multiple of 170 for RGMII interface,
-or will round down. Range 0~31*170.
-Both delay properties need to be a multiple of 550 for MII/RMII interface,
-or will round down. Range 0~31*550.
-
-- mediatek,rmii-rxc: boolean property, if present indicates that the RMII
- reference clock, which is from external PHYs, is connected to RXC pin
- on MT2712 SoC.
- Otherwise, is connected to TXC pin.
-- mediatek,rmii-clk-from-mac: boolean property, if present indicates that
- MT2712 SoC provides the RMII reference clock, which outputs to TXC pin only.
-- mediatek,txc-inverse: boolean property, if present indicates that
- 1. tx clock will be inversed in MII/RGMII case,
- 2. tx clock inside MAC will be inversed relative to reference clock
- which is from external PHYs in RMII case, and it rarely happen.
- 3. the reference clock, which outputs to TXC pin will be inversed in RMII case
- when the reference clock is from MT2712 SoC.
-- mediatek,rxc-inverse: boolean property, if present indicates that
- 1. rx clock will be inversed in MII/RGMII case.
- 2. reference clock will be inversed when arrived at MAC in RMII case, when
- the reference clock is from external PHYs.
- 3. the inside clock, which be sent to MAC, will be inversed in RMII case when
- the reference clock is from MT2712 SoC.
-- assigned-clocks: mac_main and ptp_ref clocks
-- assigned-clock-parents: parent clocks of the assigned clocks
-
-Example:
- eth: ethernet@1101c000 {
- compatible = "mediatek,mt2712-gmac";
- reg = <0 0x1101c000 0 0x1300>;
- interrupts = <GIC_SPI 237 IRQ_TYPE_LEVEL_LOW>;
- interrupt-names = "macirq";
- phy-mode ="rgmii-rxid";
- mac-address = [00 55 7b b5 7d f7];
- clock-names = "axi",
- "apb",
- "mac_main",
- "ptp_ref",
- "rmii_internal";
- clocks = <&pericfg CLK_PERI_GMAC>,
- <&pericfg CLK_PERI_GMAC_PCLK>,
- <&topckgen CLK_TOP_ETHER_125M_SEL>,
- <&topckgen CLK_TOP_ETHER_50M_SEL>,
- <&topckgen CLK_TOP_ETHER_50M_RMII_SEL>;
- assigned-clocks = <&topckgen CLK_TOP_ETHER_125M_SEL>,
- <&topckgen CLK_TOP_ETHER_50M_SEL>,
- <&topckgen CLK_TOP_ETHER_50M_RMII_SEL>;
- assigned-clock-parents = <&topckgen CLK_TOP_ETHERPLL_125M>,
- <&topckgen CLK_TOP_APLL1_D3>,
- <&topckgen CLK_TOP_ETHERPLL_50M>;
- power-domains = <&scpsys MT2712_POWER_DOMAIN_AUDIO>;
- mediatek,pericfg = <&pericfg>;
- mediatek,tx-delay-ps = <1530>;
- mediatek,rx-delay-ps = <1530>;
- mediatek,rmii-rxc;
- mediatek,txc-inverse;
- mediatek,rxc-inverse;
- snps,txpbl = <1>;
- snps,rxpbl = <1>;
- snps,reset-gpio = <&pio 87 GPIO_ACTIVE_LOW>;
- snps,reset-active-low;
- };
diff --git a/Documentation/devicetree/bindings/net/mediatek-dwmac.yaml b/Documentation/devicetree/bindings/net/mediatek-dwmac.yaml
new file mode 100644
index 000000000000..901944683322
--- /dev/null
+++ b/Documentation/devicetree/bindings/net/mediatek-dwmac.yaml
@@ -0,0 +1,175 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/net/mediatek-dwmac.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: MediaTek DWMAC glue layer controller
+
+maintainers:
+ - Biao Huang <biao.huang@mediatek.com>
+
+description:
+ This file documents platform glue layer for stmmac.
+
+# We need a select here so we don't match all nodes with 'snps,dwmac'
+select:
+ properties:
+ compatible:
+ contains:
+ enum:
+ - mediatek,mt2712-gmac
+ - mediatek,mt8195-gmac
+ required:
+ - compatible
+
+allOf:
+ - $ref: "snps,dwmac.yaml#"
+
+properties:
+ compatible:
+ oneOf:
+ - items:
+ - enum:
+ - mediatek,mt2712-gmac
+ - const: snps,dwmac-4.20a
+ - items:
+ - enum:
+ - mediatek,mt8195-gmac
+ - const: snps,dwmac-5.10a
+
+ clocks:
+ minItems: 5
+ items:
+ - description: AXI clock
+ - description: APB clock
+ - description: MAC Main clock
+ - description: PTP clock
+ - description: RMII reference clock provided by MAC
+ - description: MAC clock gate
+
+ clock-names:
+ minItems: 5
+ items:
+ - const: axi
+ - const: apb
+ - const: mac_main
+ - const: ptp_ref
+ - const: rmii_internal
+ - const: mac_cg
+
+ mediatek,pericfg:
+ $ref: /schemas/types.yaml#/definitions/phandle
+ description:
+ The phandle to the syscon node that control ethernet
+ interface and timing delay.
+
+ mediatek,tx-delay-ps:
+ description:
+ The internal TX clock delay (provided by this driver) in nanoseconds.
+ For MT2712 RGMII interface, Allowed value need to be a multiple of 170,
+ or will round down. Range 0~31*170.
+ For MT2712 RMII/MII interface, Allowed value need to be a multiple of 550,
+ or will round down. Range 0~31*550.
+ For MT8195 RGMII/RMII/MII interface, Allowed value need to be a multiple of 290,
+ or will round down. Range 0~31*290.
+
+ mediatek,rx-delay-ps:
+ description:
+ The internal RX clock delay (provided by this driver) in nanoseconds.
+ For MT2712 RGMII interface, Allowed value need to be a multiple of 170,
+ or will round down. Range 0~31*170.
+ For MT2712 RMII/MII interface, Allowed value need to be a multiple of 550,
+ or will round down. Range 0~31*550.
+ For MT8195 RGMII/RMII/MII interface, Allowed value need to be a multiple
+ of 290, or will round down. Range 0~31*290.
+
+ mediatek,rmii-rxc:
+ type: boolean
+ description:
+ If present, indicates that the RMII reference clock, which is from external
+ PHYs, is connected to RXC pin. Otherwise, is connected to TXC pin.
+
+ mediatek,rmii-clk-from-mac:
+ type: boolean
+ description:
+ If present, indicates that MAC provides the RMII reference clock, which
+ outputs to TXC pin only.
+
+ mediatek,txc-inverse:
+ type: boolean
+ description:
+ If present, indicates that
+ 1. tx clock will be inversed in MII/RGMII case,
+ 2. tx clock inside MAC will be inversed relative to reference clock
+ which is from external PHYs in RMII case, and it rarely happen.
+ 3. the reference clock, which outputs to TXC pin will be inversed in RMII case
+ when the reference clock is from MAC.
+
+ mediatek,rxc-inverse:
+ type: boolean
+ description:
+ If present, indicates that
+ 1. rx clock will be inversed in MII/RGMII case.
+ 2. reference clock will be inversed when arrived at MAC in RMII case, when
+ the reference clock is from external PHYs.
+ 3. the inside clock, which be sent to MAC, will be inversed in RMII case when
+ the reference clock is from MAC.
+
+ mediatek,mac-wol:
+ type: boolean
+ description:
+ If present, indicates that MAC supports WOL(Wake-On-LAN), and MAC WOL will be enabled.
+ Otherwise, PHY WOL is perferred.
+
+required:
+ - compatible
+ - reg
+ - interrupts
+ - interrupt-names
+ - clocks
+ - clock-names
+ - phy-mode
+ - mediatek,pericfg
+
+unevaluatedProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/clock/mt2712-clk.h>
+ #include <dt-bindings/gpio/gpio.h>
+ #include <dt-bindings/interrupt-controller/arm-gic.h>
+ #include <dt-bindings/interrupt-controller/irq.h>
+ #include <dt-bindings/power/mt2712-power.h>
+
+ eth: ethernet@1101c000 {
+ compatible = "mediatek,mt2712-gmac", "snps,dwmac-4.20a";
+ reg = <0x1101c000 0x1300>;
+ interrupts = <GIC_SPI 237 IRQ_TYPE_LEVEL_LOW>;
+ interrupt-names = "macirq";
+ phy-mode ="rgmii-rxid";
+ mac-address = [00 55 7b b5 7d f7];
+ clock-names = "axi",
+ "apb",
+ "mac_main",
+ "ptp_ref",
+ "rmii_internal";
+ clocks = <&pericfg CLK_PERI_GMAC>,
+ <&pericfg CLK_PERI_GMAC_PCLK>,
+ <&topckgen CLK_TOP_ETHER_125M_SEL>,
+ <&topckgen CLK_TOP_ETHER_50M_SEL>,
+ <&topckgen CLK_TOP_ETHER_50M_RMII_SEL>;
+ assigned-clocks = <&topckgen CLK_TOP_ETHER_125M_SEL>,
+ <&topckgen CLK_TOP_ETHER_50M_SEL>,
+ <&topckgen CLK_TOP_ETHER_50M_RMII_SEL>;
+ assigned-clock-parents = <&topckgen CLK_TOP_ETHERPLL_125M>,
+ <&topckgen CLK_TOP_APLL1_D3>,
+ <&topckgen CLK_TOP_ETHERPLL_50M>;
+ power-domains = <&scpsys MT2712_POWER_DOMAIN_AUDIO>;
+ mediatek,pericfg = <&pericfg>;
+ mediatek,tx-delay-ps = <1530>;
+ snps,txpbl = <1>;
+ snps,rxpbl = <1>;
+ snps,reset-gpio = <&pio 87 GPIO_ACTIVE_LOW>;
+ snps,reset-delays-us = <0 10000 10000>;
+ };
diff --git a/Documentation/devicetree/bindings/net/micrel.txt b/Documentation/devicetree/bindings/net/micrel.txt
index 8d157f0295a5..c5ab62c39133 100644
--- a/Documentation/devicetree/bindings/net/micrel.txt
+++ b/Documentation/devicetree/bindings/net/micrel.txt
@@ -45,3 +45,20 @@ Optional properties:
In fiber mode, auto-negotiation is disabled and the PHY can only work in
100base-fx (full and half duplex) modes.
+
+ - lan8814,ignore-ts: If present the PHY will not support timestamping.
+
+ This option acts as check whether Timestamping is supported by
+ hardware or not. LAN8814 phy support hardware tmestamping.
+
+ - lan8814,latency_rx_10: Configures Latency value of phy in ingress at 10 Mbps.
+
+ - lan8814,latency_tx_10: Configures Latency value of phy in egress at 10 Mbps.
+
+ - lan8814,latency_rx_100: Configures Latency value of phy in ingress at 100 Mbps.
+
+ - lan8814,latency_tx_100: Configures Latency value of phy in egress at 100 Mbps.
+
+ - lan8814,latency_rx_1000: Configures Latency value of phy in ingress at 1000 Mbps.
+
+ - lan8814,latency_tx_1000: Configures Latency value of phy in egress at 1000 Mbps.
diff --git a/Documentation/devicetree/bindings/net/microchip,lan966x-switch.yaml b/Documentation/devicetree/bindings/net/microchip,lan966x-switch.yaml
index e79e4e166ad8..13812768b923 100644
--- a/Documentation/devicetree/bindings/net/microchip,lan966x-switch.yaml
+++ b/Documentation/devicetree/bindings/net/microchip,lan966x-switch.yaml
@@ -38,6 +38,7 @@ properties:
- description: register based extraction
- description: frame dma based extraction
- description: analyzer interrupt
+ - description: ptp interrupt
interrupt-names:
minItems: 1
@@ -45,6 +46,7 @@ properties:
- const: xtr
- const: fdma
- const: ana
+ - const: ptp
resets:
items:
diff --git a/Documentation/devicetree/bindings/net/microchip,sparx5-switch.yaml b/Documentation/devicetree/bindings/net/microchip,sparx5-switch.yaml
index 347b912a46bb..6c86d3d85e99 100644
--- a/Documentation/devicetree/bindings/net/microchip,sparx5-switch.yaml
+++ b/Documentation/devicetree/bindings/net/microchip,sparx5-switch.yaml
@@ -53,12 +53,14 @@ properties:
items:
- description: register based extraction
- description: frame dma based extraction
+ - description: ptp interrupt
interrupt-names:
minItems: 1
items:
- const: xtr
- const: fdma
+ - const: ptp
resets:
items:
diff --git a/Documentation/devicetree/bindings/net/mscc-miim.txt b/Documentation/devicetree/bindings/net/mscc-miim.txt
index 7104679cf59d..70e0cb1ee485 100644
--- a/Documentation/devicetree/bindings/net/mscc-miim.txt
+++ b/Documentation/devicetree/bindings/net/mscc-miim.txt
@@ -2,7 +2,7 @@ Microsemi MII Management Controller (MIIM) / MDIO
=================================================
Properties:
-- compatible: must be "mscc,ocelot-miim"
+- compatible: must be "mscc,ocelot-miim" or "microchip,lan966x-miim"
- reg: The base address of the MDIO bus controller register bank. Optionally, a
second register bank can be defined if there is an associated reset register
for internal PHYs
diff --git a/Documentation/devicetree/bindings/net/qcom,ipa.yaml b/Documentation/devicetree/bindings/net/qcom,ipa.yaml
index b86edf67ce62..58ecc62adfaa 100644
--- a/Documentation/devicetree/bindings/net/qcom,ipa.yaml
+++ b/Documentation/devicetree/bindings/net/qcom,ipa.yaml
@@ -107,6 +107,10 @@ properties:
- const: imem
- const: config
+ qcom,qmp:
+ $ref: /schemas/types.yaml#/definitions/phandle
+ description: phandle to the AOSS side-channel message RAM
+
qcom,smem-states:
$ref: /schemas/types.yaml#/definitions/phandle-array
description: State bits used in by the AP to signal the modem.
@@ -222,6 +226,8 @@ examples:
"imem",
"config";
+ qcom,qmp = <&aoss_qmp>;
+
qcom,smem-states = <&ipa_smp2p_out 0>,
<&ipa_smp2p_out 1>;
qcom,smem-state-names = "ipa-clock-enabled-valid",
diff --git a/Documentation/devicetree/bindings/net/renesas,etheravb.yaml b/Documentation/devicetree/bindings/net/renesas,etheravb.yaml
index bda821065a2b..ee2ccacc39ff 100644
--- a/Documentation/devicetree/bindings/net/renesas,etheravb.yaml
+++ b/Documentation/devicetree/bindings/net/renesas,etheravb.yaml
@@ -45,8 +45,10 @@ properties:
- items:
- enum:
+ - renesas,r9a07g043-gbeth # RZ/G2UL
- renesas,r9a07g044-gbeth # RZ/G2{L,LC}
- - const: renesas,rzg2l-gbeth # RZ/G2L
+ - renesas,r9a07g054-gbeth # RZ/V2L
+ - const: renesas,rzg2l-gbeth # RZ/{G2L,G2UL,V2L} family
reg: true
diff --git a/Documentation/devicetree/bindings/net/wireless/mediatek,mt76.yaml b/Documentation/devicetree/bindings/net/wireless/mediatek,mt76.yaml
index 269cd63fb544..3216c999f0e1 100644
--- a/Documentation/devicetree/bindings/net/wireless/mediatek,mt76.yaml
+++ b/Documentation/devicetree/bindings/net/wireless/mediatek,mt76.yaml
@@ -18,7 +18,7 @@ description: |
wireless device. The node is expected to be specified as a child
node of the PCI controller to which the wireless chip is connected.
Alternatively, it can specify the wireless part of the MT7628/MT7688
- or MT7622 SoC.
+ or MT7622/MT7986 SoC.
allOf:
- $ref: ieee80211.yaml#
@@ -29,9 +29,13 @@ properties:
- mediatek,mt76
- mediatek,mt7628-wmac
- mediatek,mt7622-wmac
+ - mediatek,mt7986-wmac
reg:
- maxItems: 1
+ minItems: 1
+ maxItems: 3
+ description:
+ MT7986 should contain 3 regions consys, dcm, and sku, in this order.
interrupts:
maxItems: 1
@@ -39,6 +43,17 @@ properties:
power-domains:
maxItems: 1
+ memory-region:
+ maxItems: 1
+
+ resets:
+ maxItems: 1
+ description:
+ Specify the consys reset for mt7986.
+
+ reset-name:
+ const: consys
+
mediatek,infracfg:
$ref: /schemas/types.yaml#/definitions/phandle
description:
@@ -69,6 +84,15 @@ properties:
calibration data is generic and specific calibration data should be
pulled from the OTP ROM
+ mediatek,disable-radar-background:
+ type: boolean
+ description:
+ Disable/enable radar/CAC detection running on a dedicated offchannel
+ chain available on some hw.
+ Background radar/CAC detection allows to avoid the CAC downtime
+ switching on a different channel during CAC detection on the selected
+ radar channel.
+
led:
type: object
$ref: /schemas/leds/common.yaml#
@@ -165,7 +189,7 @@ required:
- compatible
- reg
-additionalProperties: false
+unevaluatedProperties: false
examples:
- |
@@ -231,3 +255,15 @@ examples:
power-domains = <&scpsys 3>;
};
+
+ - |
+ wifi@18000000 {
+ compatible = "mediatek,mt7986-wmac";
+ resets = <&watchdog 23>;
+ reset-names = "consys";
+ reg = <0x18000000 0x1000000>,
+ <0x10003000 0x1000>,
+ <0x11d10000 0x1000>;
+ interrupts = <GIC_SPI 213 IRQ_TYPE_LEVEL_HIGH>;
+ memory-region = <&wmcpu_emi>;
+ };
diff --git a/Documentation/devicetree/bindings/perf/marvell-cn10k-ddr.yaml b/Documentation/devicetree/bindings/perf/marvell-cn10k-ddr.yaml
new file mode 100644
index 000000000000..a18dd0a8c43a
--- /dev/null
+++ b/Documentation/devicetree/bindings/perf/marvell-cn10k-ddr.yaml
@@ -0,0 +1,37 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/perf/marvell-cn10k-ddr.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Marvell CN10K DDR performance monitor
+
+maintainers:
+ - Bharat Bhushan <bbhushan2@marvell.com>
+
+properties:
+ compatible:
+ items:
+ - enum:
+ - marvell,cn10k-ddr-pmu
+
+ reg:
+ maxItems: 1
+
+required:
+ - compatible
+ - reg
+
+additionalProperties: false
+
+examples:
+ - |
+ bus {
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ pmu@87e1c0000000 {
+ compatible = "marvell,cn10k-ddr-pmu";
+ reg = <0x87e1 0xc0000000 0x0 0x10000>;
+ };
+ };
diff --git a/Documentation/devicetree/bindings/perf/nds32v3-pmu.txt b/Documentation/devicetree/bindings/perf/nds32v3-pmu.txt
deleted file mode 100644
index 1bd15785b4ae..000000000000
--- a/Documentation/devicetree/bindings/perf/nds32v3-pmu.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-* NDS32 Performance Monitor Units
-
-NDS32 core have a PMU for counting cpu and cache events like cache misses.
-The NDS32 PMU representation in the device tree should be done as under:
-
-Required properties:
-
-- compatible :
- "andestech,nds32v3-pmu"
-
-- interrupts : The interrupt number for NDS32 PMU is 13.
-
-Example:
-pmu{
- compatible = "andestech,nds32v3-pmu";
- interrupts = <13>;
-}
diff --git a/Documentation/devicetree/bindings/phy/fsl,lynx-28g.yaml b/Documentation/devicetree/bindings/phy/fsl,lynx-28g.yaml
new file mode 100644
index 000000000000..4d91e2f4f247
--- /dev/null
+++ b/Documentation/devicetree/bindings/phy/fsl,lynx-28g.yaml
@@ -0,0 +1,40 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/phy/fsl,lynx-28g.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Freescale Lynx 28G SerDes PHY binding
+
+maintainers:
+ - Ioana Ciornei <ioana.ciornei@nxp.com>
+
+properties:
+ compatible:
+ enum:
+ - fsl,lynx-28g
+
+ reg:
+ maxItems: 1
+
+ "#phy-cells":
+ const: 1
+
+required:
+ - compatible
+ - reg
+ - "#phy-cells"
+
+additionalProperties: false
+
+examples:
+ - |
+ soc {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ serdes_1: phy@1ea0000 {
+ compatible = "fsl,lynx-28g";
+ reg = <0x0 0x1ea0000 0x0 0x1e30>;
+ #phy-cells = <1>;
+ };
+ };
diff --git a/Documentation/devicetree/bindings/phy/qcom,usb-hs-phy.txt b/Documentation/devicetree/bindings/phy/qcom,usb-hs-phy.txt
index b3b75c1e6285..6814dccb390c 100644
--- a/Documentation/devicetree/bindings/phy/qcom,usb-hs-phy.txt
+++ b/Documentation/devicetree/bindings/phy/qcom,usb-hs-phy.txt
@@ -9,6 +9,7 @@ PROPERTIES
following:
"qcom,usb-hs-phy-apq8064"
+ "qcom,usb-hs-phy-msm8226"
"qcom,usb-hs-phy-msm8916"
"qcom,usb-hs-phy-msm8974"
diff --git a/Documentation/devicetree/bindings/phy/ti,omap-usb2.yaml b/Documentation/devicetree/bindings/phy/ti,omap-usb2.yaml
index cbbf5e8b1197..f78d3246fbdc 100644
--- a/Documentation/devicetree/bindings/phy/ti,omap-usb2.yaml
+++ b/Documentation/devicetree/bindings/phy/ti,omap-usb2.yaml
@@ -8,7 +8,7 @@ title: OMAP USB2 PHY
maintainers:
- Kishon Vijay Abraham I <kishon@ti.com>
- - Roger Quadros <rogerq@ti.com>
+ - Roger Quadros <rogerq@kernel.org>
properties:
compatible:
diff --git a/Documentation/devicetree/bindings/phy/ti,tcan104x-can.yaml b/Documentation/devicetree/bindings/phy/ti,tcan104x-can.yaml
index 6107880e5246..02b76f15e717 100644
--- a/Documentation/devicetree/bindings/phy/ti,tcan104x-can.yaml
+++ b/Documentation/devicetree/bindings/phy/ti,tcan104x-can.yaml
@@ -37,6 +37,12 @@ properties:
max bit rate supported in bps
minimum: 1
+ mux-states:
+ description:
+ mux controller node to route the signals from controller to
+ transceiver.
+ maxItems: 1
+
required:
- compatible
- '#phy-cells'
@@ -53,4 +59,5 @@ examples:
max-bitrate = <5000000>;
standby-gpios = <&wakeup_gpio1 16 GPIO_ACTIVE_LOW>;
enable-gpios = <&main_gpio1 67 GPIO_ACTIVE_HIGH>;
+ mux-states = <&mux0 1>;
};
diff --git a/Documentation/devicetree/bindings/phy/transmit-amplitude.yaml b/Documentation/devicetree/bindings/phy/transmit-amplitude.yaml
new file mode 100644
index 000000000000..51492fe738ec
--- /dev/null
+++ b/Documentation/devicetree/bindings/phy/transmit-amplitude.yaml
@@ -0,0 +1,103 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/phy/transmit-amplitude.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Common PHY and network PCS transmit amplitude property binding
+
+description:
+ Binding describing the peak-to-peak transmit amplitude for common PHYs
+ and network PCSes.
+
+maintainers:
+ - Marek Behún <kabel@kernel.org>
+
+properties:
+ tx-p2p-microvolt:
+ description:
+ Transmit amplitude voltages in microvolts, peak-to-peak. If this property
+ contains multiple values for various PHY modes, the
+ 'tx-p2p-microvolt-names' property must be provided and contain
+ corresponding mode names.
+
+ tx-p2p-microvolt-names:
+ description: |
+ Names of the modes corresponding to voltages in the 'tx-p2p-microvolt'
+ property. Required only if multiple voltages are provided.
+
+ If a value of 'default' is provided, the system should use it for any PHY
+ mode that is otherwise not defined here. If 'default' is not provided, the
+ system should use manufacturer default value.
+ minItems: 1
+ maxItems: 16
+ items:
+ enum:
+ - default
+
+ # ethernet modes
+ - sgmii
+ - qsgmii
+ - xgmii
+ - 1000base-x
+ - 2500base-x
+ - 5gbase-r
+ - rxaui
+ - xaui
+ - 10gbase-kr
+ - usxgmii
+ - 10gbase-r
+ - 25gbase-r
+
+ # PCIe modes
+ - pcie
+ - pcie1
+ - pcie2
+ - pcie3
+ - pcie4
+ - pcie5
+ - pcie6
+
+ # USB modes
+ - usb
+ - usb-ls
+ - usb-fs
+ - usb-hs
+ - usb-ss
+ - usb-ss+
+ - usb-4
+
+ # storage modes
+ - sata
+ - ufs-hs
+ - ufs-hs-a
+ - ufs-hs-b
+
+ # display modes
+ - lvds
+ - dp
+ - dp-rbr
+ - dp-hbr
+ - dp-hbr2
+ - dp-hbr3
+ - dp-uhbr-10
+ - dp-uhbr-13.5
+ - dp-uhbr-20
+
+ # camera modes
+ - mipi-dphy
+ - mipi-dphy-univ
+ - mipi-dphy-v2.5-univ
+
+dependencies:
+ tx-p2p-microvolt-names: [ tx-p2p-microvolt ]
+
+additionalProperties: true
+
+examples:
+ - |
+ phy: phy {
+ #phy-cells = <1>;
+ tx-p2p-microvolt = <915000>, <1100000>, <1200000>;
+ tx-p2p-microvolt-names = "2500base-x", "usb-hs", "usb-ss";
+ };
diff --git a/Documentation/devicetree/bindings/pinctrl/cirrus,madera.yaml b/Documentation/devicetree/bindings/pinctrl/cirrus,madera.yaml
index c85f759ae5a3..8a90d8273767 100644
--- a/Documentation/devicetree/bindings/pinctrl/cirrus,madera.yaml
+++ b/Documentation/devicetree/bindings/pinctrl/cirrus,madera.yaml
@@ -107,9 +107,6 @@ properties:
additionalProperties: false
-allOf:
- - $ref: "pinctrl.yaml#"
-
required:
- pinctrl-0
- pinctrl-names
diff --git a/Documentation/devicetree/bindings/pinctrl/samsung,pinctrl-gpio-bank.yaml b/Documentation/devicetree/bindings/pinctrl/samsung,pinctrl-gpio-bank.yaml
new file mode 100644
index 000000000000..f73348c54748
--- /dev/null
+++ b/Documentation/devicetree/bindings/pinctrl/samsung,pinctrl-gpio-bank.yaml
@@ -0,0 +1,52 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pinctrl/samsung,pinctrl-gpio-bank.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Samsung S3C/S5P/Exynos SoC pin controller - gpio bank
+
+maintainers:
+ - Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>
+ - Sylwester Nawrocki <s.nawrocki@samsung.com>
+ - Tomasz Figa <tomasz.figa@gmail.com>
+
+description: |
+ This is a part of device tree bindings for Samsung S3C/S5P/Exynos SoC pin
+ controller.
+
+ GPIO bank description for Samsung S3C/S5P/Exynos SoC pin controller.
+
+ See also Documentation/devicetree/bindings/pinctrl/samsung,pinctrl.yaml for
+ additional information and example.
+
+properties:
+ '#gpio-cells':
+ const: 2
+
+ gpio-controller: true
+
+ '#interrupt-cells':
+ description:
+ For GPIO banks supporting external GPIO interrupts or external wake-up
+ interrupts.
+ const: 2
+
+ interrupt-controller:
+ description:
+ For GPIO banks supporting external GPIO interrupts or external wake-up
+ interrupts.
+
+ interrupts:
+ description:
+ For GPIO banks supporting direct external wake-up interrupts (without
+ multiplexing). Number of interrupts must match number of wake-up capable
+ pins of this bank.
+ minItems: 1
+ maxItems: 8
+
+required:
+ - '#gpio-cells'
+ - gpio-controller
+
+additionalProperties: false
diff --git a/Documentation/devicetree/bindings/pinctrl/samsung,pinctrl-pins-cfg.yaml b/Documentation/devicetree/bindings/pinctrl/samsung,pinctrl-pins-cfg.yaml
new file mode 100644
index 000000000000..c71939ac8b63
--- /dev/null
+++ b/Documentation/devicetree/bindings/pinctrl/samsung,pinctrl-pins-cfg.yaml
@@ -0,0 +1,81 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pinctrl/samsung,pinctrl-pins-cfg.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Samsung S3C/S5P/Exynos SoC pin controller - pins configuration
+
+maintainers:
+ - Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>
+ - Sylwester Nawrocki <s.nawrocki@samsung.com>
+ - Tomasz Figa <tomasz.figa@gmail.com>
+
+description: |
+ This is a part of device tree bindings for Samsung S3C/S5P/Exynos SoC pin
+ controller.
+
+ Pins configuration for Samsung S3C/S5P/Exynos SoC pin controller.
+
+ The values used for config properties should be derived from the hardware
+ manual and these values are programmed as-is into the pin pull up/down and
+ driver strength register of the pin-controller.
+ See also include/dt-bindings/pinctrl/samsung.h with useful constants.
+
+ See also Documentation/devicetree/bindings/pinctrl/samsung,pinctrl.yaml for
+ additional information and example.
+
+properties:
+ samsung,pins:
+ description: |
+ List of pins to configure. For initial and sleep states, the maximum
+ number is one pin. In other cases there is no upper limit.
+
+ The pins should use lowercase names matching hardware manual, e.g. for
+ GPA0 bank: gpa0-0, gpa0-1, gpa0-2.
+ $ref: /schemas/types.yaml#/definitions/string-array
+
+ samsung,pin-function:
+ description: |
+ The pin function selection that should be applied on the pins listed in the
+ child node is specified using the "samsung,pin-function" property. The value
+ of this property that should be applied to each of the pins listed in the
+ "samsung,pins" property should be picked from the hardware manual of the SoC
+ for the specified pin group. This property is optional in the child node if
+ no specific function selection is desired for the pins listed in the child
+ node. The value of this property is used as-is to program the pin-controller
+ function selector register of the pin-bank.
+ $ref: /schemas/types.yaml#/definitions/uint32
+ minimum: 0
+ maximum: 15
+
+ samsung,pin-drv:
+ description: Drive strength configuration.
+ $ref: /schemas/types.yaml#/definitions/uint32
+ minimum: 0
+ maximum: 15
+
+ samsung,pin-pud:
+ description: Pull up/down configuration.
+ $ref: /schemas/types.yaml#/definitions/uint32
+ enum: [0, 1, 2, 3]
+
+ samsung,pin-val:
+ description: Initial value of pin output buffer.
+ $ref: /schemas/types.yaml#/definitions/uint32
+ enum: [0, 1]
+
+ samsung,pin-con-pdn:
+ description: Function in power down mode.
+ $ref: /schemas/types.yaml#/definitions/uint32
+ enum: [0, 1, 2, 3]
+
+ samsung,pin-pud-pdn:
+ description: Pull up/down configuration in power down mode.
+ $ref: /schemas/types.yaml#/definitions/uint32
+ enum: [0, 1, 2, 3]
+
+required:
+ - samsung,pins
+
+additionalProperties: false
diff --git a/Documentation/devicetree/bindings/pinctrl/samsung,pinctrl-wakeup-interrupt.yaml b/Documentation/devicetree/bindings/pinctrl/samsung,pinctrl-wakeup-interrupt.yaml
new file mode 100644
index 000000000000..a822f70f5702
--- /dev/null
+++ b/Documentation/devicetree/bindings/pinctrl/samsung,pinctrl-wakeup-interrupt.yaml
@@ -0,0 +1,106 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pinctrl/samsung,pinctrl-wakeup-interrupt.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Samsung S3C/S5P/Exynos SoC pin controller - wake-up interrupt controller
+
+maintainers:
+ - Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>
+ - Sylwester Nawrocki <s.nawrocki@samsung.com>
+ - Tomasz Figa <tomasz.figa@gmail.com>
+
+description: |
+ This is a part of device tree bindings for Samsung S3C/S5P/Exynos SoC pin
+ controller.
+
+ External wake-up interrupts for Samsung S3C/S5P/Exynos SoC pin controller.
+ For S3C24xx, S3C64xx, S5PV210 and Exynos4210 compatible wake-up interrupt
+ controllers, only one pin-controller device node can include external wake-up
+ interrupts child node (in other words, only one External wake-up interrupts
+ pin-controller is supported).
+ For newer controllers, multiple pin-controller device node can include
+ external wake-up interrupts child node.
+
+ See also Documentation/devicetree/bindings/pinctrl/samsung,pinctrl.yaml for
+ additional information and example.
+
+properties:
+ compatible:
+ enum:
+ - samsung,s3c2410-wakeup-eint
+ - samsung,s3c2412-wakeup-eint
+ - samsung,s3c64xx-wakeup-eint
+ - samsung,s5pv210-wakeup-eint
+ - samsung,exynos4210-wakeup-eint
+ - samsung,exynos7-wakeup-eint
+ - samsung,exynos850-wakeup-eint
+ - samsung,exynosautov9-wakeup-eint
+
+ interrupts:
+ description:
+ Interrupt used by multiplexed external wake-up interrupts.
+ minItems: 1
+ maxItems: 6
+
+required:
+ - compatible
+
+allOf:
+ - if:
+ properties:
+ compatible:
+ contains:
+ enum:
+ - samsung,s3c2410-wakeup-eint
+ - samsung,s3c2412-wakeup-eint
+ then:
+ properties:
+ interrupts:
+ minItems: 6
+ maxItems: 6
+ required:
+ - interrupts
+
+ - if:
+ properties:
+ compatible:
+ contains:
+ const: samsung,s3c64xx-wakeup-eint
+ then:
+ properties:
+ interrupts:
+ minItems: 4
+ maxItems: 4
+ required:
+ - interrupts
+
+ - if:
+ properties:
+ compatible:
+ contains:
+ enum:
+ - samsung,s5pv210-wakeup-eint
+ - samsung,exynos4210-wakeup-eint
+ - samsung,exynos7-wakeup-eint
+ then:
+ properties:
+ interrupts:
+ minItems: 1
+ maxItems: 1
+ required:
+ - interrupts
+
+ - if:
+ properties:
+ compatible:
+ contains:
+ enum:
+ - samsung,exynos850-wakeup-eint
+ - samsung,exynosautov9-wakeup-eint
+ then:
+ properties:
+ interrupts: false
+
+additionalProperties: false
diff --git a/Documentation/devicetree/bindings/pinctrl/samsung,pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/samsung,pinctrl.yaml
new file mode 100644
index 000000000000..28f0851d07bb
--- /dev/null
+++ b/Documentation/devicetree/bindings/pinctrl/samsung,pinctrl.yaml
@@ -0,0 +1,392 @@
+# SPDX-License-Identifier: GPL-2.0-only
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pinctrl/samsung,pinctrl.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Samsung S3C/S5P/Exynos SoC pin controller
+
+maintainers:
+ - Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>
+ - Sylwester Nawrocki <s.nawrocki@samsung.com>
+ - Tomasz Figa <tomasz.figa@gmail.com>
+
+description: |
+ This is a part of device tree bindings for Samsung S3C/S5P/Exynos SoC pin
+ controller.
+
+ Pin group settings (like drive strength, pull up/down) are available as
+ macros in include/dt-bindings/pinctrl/samsung.h.
+
+ All the pin controller nodes should be represented in the aliases node using
+ the following format 'pinctrl{n}' where n is a unique number for the alias.
+
+ The controller supports three types of interrupts::
+ - External GPIO interrupts (see interrupts property in pin controller node);
+
+ - External wake-up interrupts - multiplexed (capable of waking up the system
+ see interrupts property in external wake-up interrupt controller node -
+ samsung,pinctrl-wakeup-interrupt.yaml);
+
+ - External wake-up interrupts - direct (capable of waking up the system, see
+ interrupts property in every bank of pin controller with external wake-up
+ interrupt controller - samsung,pinctrl-gpio-bank.yaml).
+
+properties:
+ $nodename:
+ pattern: "^pinctrl(@.*)?"
+
+ compatible:
+ enum:
+ - samsung,s3c2412-pinctrl
+ - samsung,s3c2416-pinctrl
+ - samsung,s3c2440-pinctrl
+ - samsung,s3c2450-pinctrl
+ - samsung,s3c64xx-pinctrl
+ - samsung,s5pv210-pinctrl
+ - samsung,exynos3250-pinctrl
+ - samsung,exynos4210-pinctrl
+ - samsung,exynos4x12-pinctrl
+ - samsung,exynos5250-pinctrl
+ - samsung,exynos5260-pinctrl
+ - samsung,exynos5410-pinctrl
+ - samsung,exynos5420-pinctrl
+ - samsung,exynos5433-pinctrl
+ - samsung,exynos7-pinctrl
+ - samsung,exynos7885-pinctrl
+ - samsung,exynos850-pinctrl
+ - samsung,exynosautov9-pinctrl
+
+ interrupts:
+ description:
+ Required for GPIO banks supporting external GPIO interrupts.
+ maxItems: 1
+
+ power-domains:
+ maxItems: 1
+
+ reg:
+ description:
+ Second base address of the pin controller if the specific registers of
+ the pin controller are separated into the different base address.
+ Only certain banks of certain pin controller might need it.
+ minItems: 1
+ maxItems: 2
+
+ wakeup-interrupt-controller:
+ $ref: samsung,pinctrl-wakeup-interrupt.yaml
+
+patternProperties:
+ "^[a-z]+[0-9]*-gpio-bank$":
+ description:
+ Pin banks of the controller are represented by child nodes of the
+ controller node. Bank name is taken from name of the node.
+ $ref: samsung,pinctrl-gpio-bank.yaml
+
+ "^[a-z0-9-]+-pins$":
+ oneOf:
+ - $ref: samsung,pinctrl-pins-cfg.yaml
+ required:
+ - samsung,pins
+ - type: object
+ patternProperties:
+ "^[a-z0-9-]+-pins$":
+ $ref: samsung,pinctrl-pins-cfg.yaml
+
+ additionalProperties: false
+
+ "^(initial|sleep)-state$":
+ patternProperties:
+ "^(pin-[a-z0-9-]+|[a-z0-9-]+-pin)$":
+ $ref: samsung,pinctrl-pins-cfg.yaml
+
+ properties:
+ samsung,pins:
+ description: See samsung,pinctrl-pins-cfg.yaml
+ $ref: /schemas/types.yaml#/definitions/string-array
+ maxItems: 1
+
+ required:
+ - samsung,pins
+
+ unevaluatedProperties: false
+
+required:
+ - compatible
+ - reg
+
+allOf:
+ - $ref: "pinctrl.yaml#"
+ - if:
+ properties:
+ compatible:
+ contains:
+ const: samsung,exynos5433-pinctrl
+ then:
+ properties:
+ reg:
+ minItems: 1
+ maxItems: 2
+ else:
+ properties:
+ reg:
+ minItems: 1
+ maxItems: 1
+
+additionalProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/pinctrl/samsung.h>
+
+ pinctrl@7f008000 {
+ compatible = "samsung,s3c64xx-pinctrl";
+ reg = <0x7f008000 0x1000>;
+ interrupt-parent = <&vic1>;
+ interrupts = <21>;
+
+ wakeup-interrupt-controller {
+ compatible = "samsung,s3c64xx-wakeup-eint";
+ interrupts-extended = <&vic0 0>,
+ <&vic0 1>,
+ <&vic1 0>,
+ <&vic1 1>;
+ };
+
+ /* Pin bank with external GPIO or muxed external wake-up interrupts */
+ gpa-gpio-bank {
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ // ...
+
+ uart0-data-pins {
+ samsung,pins = "gpa-0", "gpa-1";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+ samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
+ };
+
+ // ...
+ };
+
+ - |
+ #include <dt-bindings/interrupt-controller/arm-gic.h>
+ #include <dt-bindings/pinctrl/samsung.h>
+
+ pinctrl@11400000 {
+ compatible = "samsung,exynos4210-pinctrl";
+ reg = <0x11400000 0x1000>;
+ interrupts = <GIC_SPI 47 IRQ_TYPE_LEVEL_HIGH>;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&sleep0>;
+
+ /* Pin bank with external GPIO or muxed external wake-up interrupts */
+ gpa0-gpio-bank {
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ // ...
+
+ uart0-data-pins {
+ samsung,pins = "gpa0-0", "gpa0-1";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+ samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+ };
+
+ // ...
+
+ sleep0: sleep-state {
+ gpa0-0-pin {
+ samsung,pins = "gpa0-0";
+ samsung,pin-con-pdn = <EXYNOS_PIN_PDN_INPUT>;
+ samsung,pin-pud-pdn = <EXYNOS_PIN_PULL_NONE>;
+ };
+
+ gpa0-1-pin {
+ samsung,pins = "gpa0-1";
+ samsung,pin-con-pdn = <EXYNOS_PIN_PDN_OUT0>;
+ samsung,pin-pud-pdn = <EXYNOS_PIN_PULL_NONE>;
+ };
+
+ // ...
+ };
+ };
+
+ - |
+ #include <dt-bindings/interrupt-controller/arm-gic.h>
+ #include <dt-bindings/pinctrl/samsung.h>
+
+ pinctrl@11000000 {
+ compatible = "samsung,exynos4210-pinctrl";
+ reg = <0x11000000 0x1000>;
+ interrupts = <GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>;
+
+ wakeup-interrupt-controller {
+ compatible = "samsung,exynos4210-wakeup-eint";
+ interrupt-parent = <&gic>;
+ interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ /* Pin bank with external GPIO or muxed external wake-up interrupts */
+ gpj0-gpio-bank {
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ /* Pin bank without external interrupts */
+ gpy0-gpio-bank {
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ /* Pin bank with external direct wake-up interrupts */
+ gpx0-gpio-bank {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ interrupt-parent = <&gic>;
+ interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>;
+ #interrupt-cells = <2>;
+ };
+
+ // ...
+
+ sd0-clk-pins {
+ samsung,pins = "gpk0-0";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+ samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
+ };
+
+ sd4-bus-width8-pins {
+ part-1-pins {
+ samsung,pins = "gpk0-3", "gpk0-4",
+ "gpk0-5", "gpk0-6";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+ samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
+ };
+
+ part-2-pins {
+ samsung,pins = "gpk1-3", "gpk1-4",
+ "gpk1-5", "gpk1-6";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_4>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+ samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
+ };
+ };
+
+ // ...
+
+ otg-gp-pins {
+ samsung,pins = "gpx3-3";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+ samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+ samsung,pin-val = <0>;
+ };
+ };
+
+ - |
+ #include <dt-bindings/interrupt-controller/arm-gic.h>
+ #include <dt-bindings/pinctrl/samsung.h>
+
+ pinctrl@10580000 {
+ compatible = "samsung,exynos5433-pinctrl";
+ reg = <0x10580000 0x1a20>, <0x11090000 0x100>;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&initial_alive>;
+
+ wakeup-interrupt-controller {
+ compatible = "samsung,exynos7-wakeup-eint";
+ interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ /* Pin bank with external direct wake-up interrupts */
+ gpa0-gpio-bank {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ interrupt-parent = <&gic>;
+ interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>;
+ #interrupt-cells = <2>;
+ };
+
+ // ...
+
+ te-irq-pins {
+ samsung,pins = "gpf1-3";
+ samsung,pin-function = <0xf>;
+ };
+
+ // ..
+
+ initial_alive: initial-state {
+ gpa0-0-pin {
+ samsung,pins = "gpa0-0";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
+ samsung,pin-drv = <EXYNOS5433_PIN_DRV_FAST_SR1>;
+ };
+
+ // ...
+ };
+ };
+
+ - |
+ #include <dt-bindings/interrupt-controller/arm-gic.h>
+ #include <dt-bindings/pinctrl/samsung.h>
+
+ pinctrl@114b0000 {
+ compatible = "samsung,exynos5433-pinctrl";
+ reg = <0x114b0000 0x1000>;
+ interrupts = <GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>;
+ power-domains = <&pd_aud>;
+
+ /* Pin bank with external GPIO or muxed external wake-up interrupts */
+ gpz0-gpio-bank {
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ // ...
+
+ i2s0-bus-pins {
+ samsung,pins = "gpz0-0", "gpz0-1", "gpz0-2", "gpz0-3",
+ "gpz0-4", "gpz0-5", "gpz0-6";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+ samsung,pin-drv = <EXYNOS5433_PIN_DRV_FAST_SR1>;
+ };
+
+ // ...
+ };
diff --git a/Documentation/devicetree/bindings/pinctrl/samsung-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/samsung-pinctrl.txt
deleted file mode 100644
index 9e70edceb21b..000000000000
--- a/Documentation/devicetree/bindings/pinctrl/samsung-pinctrl.txt
+++ /dev/null
@@ -1,383 +0,0 @@
-Samsung GPIO and Pin Mux/Config controller
-
-Samsung's ARM based SoC's integrates a GPIO and Pin mux/config hardware
-controller. It controls the input/output settings on the available pads/pins
-and also provides ability to multiplex and configure the output of various
-on-chip controllers onto these pads.
-
-Required Properties:
-- compatible: should be one of the following.
- - "samsung,s3c2412-pinctrl": for S3C2412-compatible pin-controller,
- - "samsung,s3c2416-pinctrl": for S3C2416-compatible pin-controller,
- - "samsung,s3c2440-pinctrl": for S3C2440-compatible pin-controller,
- - "samsung,s3c2450-pinctrl": for S3C2450-compatible pin-controller,
- - "samsung,s3c64xx-pinctrl": for S3C64xx-compatible pin-controller,
- - "samsung,s5pv210-pinctrl": for S5PV210-compatible pin-controller,
- - "samsung,exynos3250-pinctrl": for Exynos3250 compatible pin-controller.
- - "samsung,exynos4210-pinctrl": for Exynos4210 compatible pin-controller.
- - "samsung,exynos4x12-pinctrl": for Exynos4x12 compatible pin-controller.
- - "samsung,exynos5250-pinctrl": for Exynos5250 compatible pin-controller.
- - "samsung,exynos5260-pinctrl": for Exynos5260 compatible pin-controller.
- - "samsung,exynos5410-pinctrl": for Exynos5410 compatible pin-controller.
- - "samsung,exynos5420-pinctrl": for Exynos5420 compatible pin-controller.
- - "samsung,exynos5433-pinctrl": for Exynos5433 compatible pin-controller.
- - "samsung,exynos7-pinctrl": for Exynos7 compatible pin-controller.
- - "samsung,exynos7885-pinctrl": for Exynos7885 compatible pin-controller.
- - "samsung,exynos850-pinctrl": for Exynos850 compatible pin-controller.
- - "samsung,exynosautov9-pinctrl": for ExynosAutov9 compatible pin-controller.
-
-- reg: Base address of the pin controller hardware module and length of
- the address space it occupies.
-
- - reg: Second base address of the pin controller if the specific registers
- of the pin controller are separated into the different base address.
-
- Eg: GPF[1-5] of Exynos5433 are separated into the two base address.
- - First base address is for GPAx and GPF[1-5] external interrupt
- registers.
- - Second base address is for GPF[1-5] pinctrl registers.
-
- pinctrl_0: pinctrl@10580000 {
- compatible = "samsung,exynos5433-pinctrl";
- reg = <0x10580000 0x1a20>, <0x11090000 0x100>;
-
- wakeup-interrupt-controller {
- compatible = "samsung,exynos7-wakeup-eint";
- interrupts = <0 16 0>;
- };
- };
-
-- Pin banks as child nodes: Pin banks of the controller are represented by child
- nodes of the controller node. Bank name is taken from name of the node. Each
- bank node must contain following properties:
-
- - gpio-controller: identifies the node as a gpio controller and pin bank.
- - #gpio-cells: number of cells in GPIO specifier. Since the generic GPIO
- binding is used, the amount of cells must be specified as 2. See the below
- mentioned gpio binding representation for description of particular cells.
-
- Eg: <&gpx2 6 0>
- <[phandle of the gpio controller node]
- [pin number within the gpio controller]
- [flags]>
-
- Values for gpio specifier:
- - Pin number: is a value between 0 to 7.
- - Flags: 0 - Active High
- 1 - Active Low
-
-- Pin mux/config groups as child nodes: The pin mux (selecting pin function
- mode) and pin config (pull up/down, driver strength) settings are represented
- as child nodes of the pin-controller node. There should be at least one
- child node and there is no limit on the count of these child nodes. It is
- also possible for a child node to consist of several further child nodes
- to allow grouping multiple pinctrl groups into one. The format of second
- level child nodes is exactly the same as for first level ones and is
- described below.
-
- The child node should contain a list of pin(s) on which a particular pin
- function selection or pin configuration (or both) have to applied. This
- list of pins is specified using the property name "samsung,pins". There
- should be at least one pin specified for this property and there is no upper
- limit on the count of pins that can be specified. The pins are specified
- using pin names which are derived from the hardware manual of the SoC. As
- an example, the pins in GPA0 bank of the pin controller can be represented
- as "gpa0-0", "gpa0-1", "gpa0-2" and so on. The names should be in lower case.
- The format of the pin names should be (as per the hardware manual)
- "[pin bank name]-[pin number within the bank]".
-
- The pin function selection that should be applied on the pins listed in the
- child node is specified using the "samsung,pin-function" property. The value
- of this property that should be applied to each of the pins listed in the
- "samsung,pins" property should be picked from the hardware manual of the SoC
- for the specified pin group. This property is optional in the child node if
- no specific function selection is desired for the pins listed in the child
- node. The value of this property is used as-is to program the pin-controller
- function selector register of the pin-bank.
-
- The child node can also optionally specify one or more of the pin
- configuration that should be applied on all the pins listed in the
- "samsung,pins" property of the child node. The following pin configuration
- properties are supported.
-
- - samsung,pin-val: Initial value of pin output buffer.
- - samsung,pin-pud: Pull up/down configuration.
- - samsung,pin-drv: Drive strength configuration.
- - samsung,pin-pud-pdn: Pull up/down configuration in power down mode.
- - samsung,pin-drv-pdn: Drive strength configuration in power down mode.
-
- The values specified by these config properties should be derived from the
- hardware manual and these values are programmed as-is into the pin
- pull up/down and driver strength register of the pin-controller.
-
- Note: A child should include at least a pin function selection property or
- pin configuration property (one or more) or both.
-
- The client nodes that require a particular pin function selection and/or
- pin configuration should use the bindings listed in the "pinctrl-bindings.txt"
- file.
-
-External GPIO and Wakeup Interrupts:
-
-The controller supports two types of external interrupts over gpio. The first
-is the external gpio interrupt and second is the external wakeup interrupts.
-The difference between the two is that the external wakeup interrupts can be
-used as system wakeup events.
-
-A. External GPIO Interrupts: For supporting external gpio interrupts, the
- following properties should be specified in the pin-controller device node.
-
- - interrupts: interrupt specifier for the controller. The format and value of
- the interrupt specifier depends on the interrupt parent for the controller.
-
- In addition, following properties must be present in node of every bank
- of pins supporting GPIO interrupts:
-
- - interrupt-controller: identifies the controller node as interrupt-parent.
- - #interrupt-cells: the value of this property should be 2.
- - First Cell: represents the external gpio interrupt number local to the
- external gpio interrupt space of the controller.
- - Second Cell: flags to identify the type of the interrupt
- - 1 = rising edge triggered
- - 2 = falling edge triggered
- - 3 = rising and falling edge triggered
- - 4 = high level triggered
- - 8 = low level triggered
-
-B. External Wakeup Interrupts: For supporting external wakeup interrupts, a
- child node representing the external wakeup interrupt controller should be
- included in the pin-controller device node.
-
- Only one pin-controller device node can include external wakeup interrupts
- child node (in other words, only one External Wakeup Interrupts
- pin-controller is supported).
-
- This child node should include following properties:
-
- - compatible: identifies the type of the external wakeup interrupt controller
- The possible values are:
- - samsung,s3c2410-wakeup-eint: represents wakeup interrupt controller
- found on Samsung S3C24xx SoCs except S3C2412 and S3C2413,
- - samsung,s3c2412-wakeup-eint: represents wakeup interrupt controller
- found on Samsung S3C2412 and S3C2413 SoCs,
- - samsung,s3c64xx-wakeup-eint: represents wakeup interrupt controller
- found on Samsung S3C64xx SoCs,
- - samsung,s5pv210-wakeup-eint: represents wakeup interrupt controller
- found on Samsung S5Pv210 SoCs,
- - samsung,exynos4210-wakeup-eint: represents wakeup interrupt controller
- found on Samsung Exynos4210 and S5PC110/S5PV210 SoCs.
- - samsung,exynos7-wakeup-eint: represents wakeup interrupt controller
- found on Samsung Exynos7 SoC.
- - interrupts: interrupt used by multiplexed wakeup interrupts.
-
- In addition, following properties must be present in node of every bank
- of pins supporting wake-up interrupts:
-
- - interrupt-controller: identifies the node as interrupt-parent.
- - #interrupt-cells: the value of this property should be 2
- - First Cell: represents the external wakeup interrupt number local to
- the external wakeup interrupt space of the controller.
- - Second Cell: flags to identify the type of the interrupt
- - 1 = rising edge triggered
- - 2 = falling edge triggered
- - 3 = rising and falling edge triggered
- - 4 = high level triggered
- - 8 = low level triggered
-
- Node of every bank of pins supporting direct wake-up interrupts (without
- multiplexing) must contain following properties:
-
- - interrupts: interrupts of the interrupt parent which are used for external
- wakeup interrupts from pins of the bank, must contain interrupts for all
- pins of the bank.
-
-Aliases:
-
-All the pin controller nodes should be represented in the aliases node using
-the following format 'pinctrl{n}' where n is a unique number for the alias.
-
-Aliases for controllers compatible with "samsung,exynos7-pinctrl":
-- pinctrl0: pin controller of ALIVE block,
-- pinctrl1: pin controller of BUS0 block,
-- pinctrl2: pin controller of NFC block,
-- pinctrl3: pin controller of TOUCH block,
-- pinctrl4: pin controller of FF block,
-- pinctrl5: pin controller of ESE block,
-- pinctrl6: pin controller of FSYS0 block,
-- pinctrl7: pin controller of FSYS1 block,
-- pinctrl8: pin controller of BUS1 block,
-- pinctrl9: pin controller of AUDIO block,
-
-Example: A pin-controller node with pin banks:
-
- pinctrl_0: pinctrl@11400000 {
- compatible = "samsung,exynos4210-pinctrl";
- reg = <0x11400000 0x1000>;
- interrupts = <0 47 0>;
-
- /* ... */
-
- /* Pin bank without external interrupts */
- gpy0: gpy0 {
- gpio-controller;
- #gpio-cells = <2>;
- };
-
- /* ... */
-
- /* Pin bank with external GPIO or muxed wake-up interrupts */
- gpj0: gpj0 {
- gpio-controller;
- #gpio-cells = <2>;
-
- interrupt-controller;
- #interrupt-cells = <2>;
- };
-
- /* ... */
-
- /* Pin bank with external direct wake-up interrupts */
- gpx0: gpx0 {
- gpio-controller;
- #gpio-cells = <2>;
-
- interrupt-controller;
- interrupt-parent = <&gic>;
- interrupts = <0 16 0>, <0 17 0>, <0 18 0>, <0 19 0>,
- <0 20 0>, <0 21 0>, <0 22 0>, <0 23 0>;
- #interrupt-cells = <2>;
- };
-
- /* ... */
- };
-
-Example 1: A pin-controller node with pin groups.
-
- #include <dt-bindings/pinctrl/samsung.h>
-
- pinctrl_0: pinctrl@11400000 {
- compatible = "samsung,exynos4210-pinctrl";
- reg = <0x11400000 0x1000>;
- interrupts = <0 47 0>;
-
- /* ... */
-
- uart0_data: uart0-data {
- samsung,pins = "gpa0-0", "gpa0-1";
- samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
- samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
- samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
- };
-
- uart0_fctl: uart0-fctl {
- samsung,pins = "gpa0-2", "gpa0-3";
- samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
- samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
- samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
- };
-
- uart1_data: uart1-data {
- samsung,pins = "gpa0-4", "gpa0-5";
- samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
- samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
- samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
- };
-
- uart1_fctl: uart1-fctl {
- samsung,pins = "gpa0-6", "gpa0-7";
- samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
- samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
- samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
- };
-
- i2c2_bus: i2c2-bus {
- samsung,pins = "gpa0-6", "gpa0-7";
- samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
- samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
- samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
- };
-
- sd4_bus8: sd4-bus-width8 {
- part-1 {
- samsung,pins = "gpk0-3", "gpk0-4",
- "gpk0-5", "gpk0-6";
- samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
- samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
- samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
- };
- part-2 {
- samsung,pins = "gpk1-3", "gpk1-4",
- "gpk1-5", "gpk1-6";
- samsung,pin-function = <EXYNOS_PIN_FUNC_4>;
- samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
- samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
- };
- };
- };
-
-Example 2: A pin-controller node with external wakeup interrupt controller node.
-
- pinctrl_1: pinctrl@11000000 {
- compatible = "samsung,exynos4210-pinctrl";
- reg = <0x11000000 0x1000>;
- interrupts = <0 46 0>
-
- /* ... */
-
- wakeup-interrupt-controller {
- compatible = "samsung,exynos4210-wakeup-eint";
- interrupt-parent = <&gic>;
- interrupts = <0 32 0>;
- };
- };
-
-Example 3: A uart client node that supports 'default' and 'flow-control' states.
-
- uart@13800000 {
- compatible = "samsung,exynos4210-uart";
- reg = <0x13800000 0x100>;
- interrupts = <0 52 0>;
- pinctrl-names = "default", "flow-control;
- pinctrl-0 = <&uart0_data>;
- pinctrl-1 = <&uart0_data>, <&uart0_fctl>;
- };
-
-Example 4: Set up the default pin state for uart controller.
-
- static int s3c24xx_serial_probe(struct platform_device *pdev) {
- struct pinctrl *pinctrl;
-
- /* ... */
-
- pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
- }
-
-Example 5: A display port client node that supports 'default' pinctrl state
- and gpio binding.
-
- display-port-controller {
- /* ... */
-
- samsung,hpd-gpio = <&gpx2 6 0>;
- pinctrl-names = "default";
- pinctrl-0 = <&dp_hpd>;
- };
-
-Example 6: Request the gpio for display port controller
-
- static int exynos_dp_probe(struct platform_device *pdev)
- {
- int hpd_gpio, ret;
- struct device *dev = &pdev->dev;
- struct device_node *dp_node = dev->of_node;
-
- /* ... */
-
- hpd_gpio = of_get_named_gpio(dp_node, "samsung,hpd-gpio", 0);
-
- /* ... */
-
- ret = devm_gpio_request_one(&pdev->dev, hpd_gpio, GPIOF_IN,
- "hpd_gpio");
- /* ... */
- }
diff --git a/Documentation/devicetree/bindings/power/amlogic,meson-sec-pwrc.yaml b/Documentation/devicetree/bindings/power/amlogic,meson-sec-pwrc.yaml
index 5dae04d2936c..7657721a4e96 100644
--- a/Documentation/devicetree/bindings/power/amlogic,meson-sec-pwrc.yaml
+++ b/Documentation/devicetree/bindings/power/amlogic,meson-sec-pwrc.yaml
@@ -12,13 +12,14 @@ maintainers:
- Jianxin Pan <jianxin.pan@amlogic.com>
description: |+
- Secure Power Domains used in Meson A1/C1 SoCs, and should be the child node
+ Secure Power Domains used in Meson A1/C1/S4 SoCs, and should be the child node
of secure-monitor.
properties:
compatible:
enum:
- amlogic,meson-a1-pwrc
+ - amlogic,meson-s4-pwrc
"#power-domain-cells":
const: 1
diff --git a/Documentation/devicetree/bindings/power/fsl,imx-gpcv2.yaml b/Documentation/devicetree/bindings/power/fsl,imx-gpcv2.yaml
index 01bdda167eef..747622bdc57b 100644
--- a/Documentation/devicetree/bindings/power/fsl,imx-gpcv2.yaml
+++ b/Documentation/devicetree/bindings/power/fsl,imx-gpcv2.yaml
@@ -28,6 +28,7 @@ properties:
- fsl,imx8mn-gpc
- fsl,imx8mq-gpc
- fsl,imx8mm-gpc
+ - fsl,imx8mp-gpc
reg:
maxItems: 1
@@ -57,6 +58,7 @@ properties:
include/dt-bindings/power/imx7-power.h for fsl,imx7d-gpc and
include/dt-bindings/power/imx8m-power.h for fsl,imx8mq-gpc
include/dt-bindings/power/imx8mm-power.h for fsl,imx8mm-gpc
+ include/dt-bindings/power/imx8mp-power.h for fsl,imx8mp-gpc
maxItems: 1
clocks:
diff --git a/Documentation/devicetree/bindings/power/mediatek,power-controller.yaml b/Documentation/devicetree/bindings/power/mediatek,power-controller.yaml
index f234a756c193..135c6f722091 100644
--- a/Documentation/devicetree/bindings/power/mediatek,power-controller.yaml
+++ b/Documentation/devicetree/bindings/power/mediatek,power-controller.yaml
@@ -26,7 +26,9 @@ properties:
- mediatek,mt8167-power-controller
- mediatek,mt8173-power-controller
- mediatek,mt8183-power-controller
+ - mediatek,mt8186-power-controller
- mediatek,mt8192-power-controller
+ - mediatek,mt8195-power-controller
'#power-domain-cells':
const: 1
@@ -64,6 +66,7 @@ patternProperties:
"include/dt-bindings/power/mt8173-power.h" - for MT8173 type power domain.
"include/dt-bindings/power/mt8183-power.h" - for MT8183 type power domain.
"include/dt-bindings/power/mt8192-power.h" - for MT8192 type power domain.
+ "include/dt-bindings/power/mt8195-power.h" - for MT8195 type power domain.
maxItems: 1
clocks:
diff --git a/Documentation/devicetree/bindings/power/qcom,rpmpd.yaml b/Documentation/devicetree/bindings/power/qcom,rpmpd.yaml
index f48bc41d81ec..940e97b565bf 100644
--- a/Documentation/devicetree/bindings/power/qcom,rpmpd.yaml
+++ b/Documentation/devicetree/bindings/power/qcom,rpmpd.yaml
@@ -17,6 +17,7 @@ properties:
compatible:
enum:
- qcom,mdm9607-rpmpd
+ - qcom,msm8226-rpmpd
- qcom,msm8916-rpmpd
- qcom,msm8939-rpmpd
- qcom,msm8953-rpmpd
diff --git a/Documentation/devicetree/bindings/power/renesas,rzg2l-sysc.yaml b/Documentation/devicetree/bindings/power/renesas,rzg2l-sysc.yaml
index 84ddc772b003..bb433e75a0ee 100644
--- a/Documentation/devicetree/bindings/power/renesas,rzg2l-sysc.yaml
+++ b/Documentation/devicetree/bindings/power/renesas,rzg2l-sysc.yaml
@@ -4,14 +4,14 @@
$id: "http://devicetree.org/schemas/power/renesas,rzg2l-sysc.yaml#"
$schema: "http://devicetree.org/meta-schemas/core.yaml#"
-title: Renesas RZ/G2L System Controller (SYSC)
+title: Renesas RZ/{G2L,V2L} System Controller (SYSC)
maintainers:
- Geert Uytterhoeven <geert+renesas@glider.be>
description:
- The RZ/G2L System Controller (SYSC) performs system control of the LSI and
- supports following functions,
+ The RZ/{G2L,V2L} System Controller (SYSC) performs system control of the LSI
+ and supports following functions,
- External terminal state capture function
- 34-bit address space access function
- Low power consumption control
@@ -21,6 +21,7 @@ properties:
compatible:
enum:
- renesas,r9a07g044-sysc # RZ/G2{L,LC}
+ - renesas,r9a07g054-sysc # RZ/V2L
reg:
maxItems: 1
diff --git a/Documentation/devicetree/bindings/power/supply/maxim,max14577.yaml b/Documentation/devicetree/bindings/power/supply/maxim,max14577.yaml
new file mode 100644
index 000000000000..3978b48299de
--- /dev/null
+++ b/Documentation/devicetree/bindings/power/supply/maxim,max14577.yaml
@@ -0,0 +1,84 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/power/supply/maxim,max14577.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Maxim MAX14577/MAX77836 MicroUSB and Companion Power Management IC Charger
+
+maintainers:
+ - Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>
+
+description: |
+ This is a part of device tree bindings for Maxim MAX14577/MAX77836 MicroUSB
+ Integrated Circuit (MUIC).
+
+ See also Documentation/devicetree/bindings/mfd/maxim,max14577.yaml for
+ additional information and example.
+
+properties:
+ compatible:
+ enum:
+ - maxim,max14577-charger
+ - maxim,max77836-charger
+
+ maxim,constant-uvolt:
+ description:
+ Battery Constant Voltage in uV
+ $ref: /schemas/types.yaml#/definitions/uint32
+ minimum: 4000000
+ maximum: 4350000
+
+ maxim,eoc-uamp:
+ description: |
+ Current in uA for End-Of-Charge mode.
+ MAX14577: 50000-20000
+ MAX77836: 5000-100000
+ $ref: /schemas/types.yaml#/definitions/uint32
+
+ maxim,fast-charge-uamp:
+ description: |
+ Current in uA for Fast Charge
+ MAX14577: 90000-950000
+ MAX77836: 45000-475000
+ $ref: /schemas/types.yaml#/definitions/uint32
+
+ maxim,ovp-uvolt:
+ description:
+ OverVoltage Protection Threshold in uV; In an overvoltage condition, INT
+ asserts and charging stops.
+ $ref: /schemas/types.yaml#/definitions/uint32
+ enum: [6000000, 6500000, 7000000, 7500000]
+
+required:
+ - compatible
+ - maxim,constant-uvolt
+ - maxim,eoc-uamp
+ - maxim,fast-charge-uamp
+ - maxim,ovp-uvolt
+
+allOf:
+ - if:
+ properties:
+ compatible:
+ contains:
+ const: maxim,max14577-charger
+ then:
+ properties:
+ maxim,eoc-uamp:
+ minimum: 50000
+ maximum: 200000
+ maxim,fast-charge-uamp:
+ minimum: 90000
+ maximum: 950000
+ else:
+ # max77836
+ properties:
+ maxim,eoc-uamp:
+ minimum: 5000
+ maximum: 100000
+ maxim,fast-charge-uamp:
+ minimum: 45000
+ maximum: 475000
+
+additionalProperties: false
diff --git a/Documentation/devicetree/bindings/pwm/pwm-sifive.yaml b/Documentation/devicetree/bindings/pwm/pwm-sifive.yaml
index 84e66913d042..db41cd7bf150 100644
--- a/Documentation/devicetree/bindings/pwm/pwm-sifive.yaml
+++ b/Documentation/devicetree/bindings/pwm/pwm-sifive.yaml
@@ -8,7 +8,6 @@ $schema: http://devicetree.org/meta-schemas/core.yaml#
title: SiFive PWM controller
maintainers:
- - Yash Shah <yash.shah@sifive.com>
- Sagar Kadam <sagar.kadam@sifive.com>
- Paul Walmsley <paul.walmsley@sifive.com>
diff --git a/Documentation/devicetree/bindings/regulator/max77802.txt b/Documentation/devicetree/bindings/regulator/max77802.txt
deleted file mode 100644
index b82943d83677..000000000000
--- a/Documentation/devicetree/bindings/regulator/max77802.txt
+++ /dev/null
@@ -1,111 +0,0 @@
-Binding for Maxim MAX77802 regulators
-
-This is a part of device tree bindings of MAX77802 multi-function device.
-More information can be found in bindings/mfd/max77802.txt file.
-
-The MAX77802 PMIC has 10 high-efficiency Buck and 32 Low-dropout (LDO)
-regulators that can be controlled over I2C.
-
-Following properties should be present in main device node of the MFD chip.
-
-Optional properties:
-- inb1-supply: The input supply for BUCK1
-- inb2-supply: The input supply for BUCK2
-- inb3-supply: The input supply for BUCK3
-- inb4-supply: The input supply for BUCK4
-- inb5-supply: The input supply for BUCK5
-- inb6-supply: The input supply for BUCK6
-- inb7-supply: The input supply for BUCK7
-- inb8-supply: The input supply for BUCK8
-- inb9-supply: The input supply for BUCK9
-- inb10-supply: The input supply for BUCK10
-- inl1-supply: The input supply for LDO8 and LDO15
-- inl2-supply: The input supply for LDO17, LDO27, LDO30 and LDO35
-- inl3-supply: The input supply for LDO3, LDO5, LDO6 and LDO7
-- inl4-supply: The input supply for LDO10, LDO11, LDO13 and LDO14
-- inl5-supply: The input supply for LDO9 and LDO19
-- inl6-supply: The input supply for LDO4, LDO21, LDO24 and LDO33
-- inl7-supply: The input supply for LDO18, LDO20, LDO28 and LDO29
-- inl9-supply: The input supply for LDO12, LDO23, LDO25, LDO26, LDO32 and LDO34
-- inl10-supply: The input supply for LDO1 and LDO2
-
-Optional nodes:
-- regulators : The regulators of max77802 have to be instantiated
- under subnode named "regulators" using the following format.
-
- regulator-name {
- standard regulator constraints....
- };
- refer Documentation/devicetree/bindings/regulator/regulator.txt
-
-The regulator node name should be initialized with a string to get matched
-with their hardware counterparts as follow. The valid names are:
-
- -LDOn : for LDOs, where n can lie in ranges 1-15, 17-21, 23-30
- and 32-35.
- example: LDO1, LDO2, LDO35.
- -BUCKn : for BUCKs, where n can lie in range 1 to 10.
- example: BUCK1, BUCK5, BUCK10.
-
-The max77802 regulator supports two different operating modes: Normal and Low
-Power Mode. Some regulators support the modes to be changed at startup or by
-the consumers during normal operation while others only support to change the
-mode during system suspend. The standard regulator suspend states binding can
-be used to configure the regulator operating mode.
-
-The regulators that support the standard "regulator-initial-mode" property,
-changing their mode during normal operation are: LDOs 1, 3, 20 and 21.
-
-The possible values for "regulator-initial-mode" and "regulator-mode" are:
- 1: Normal regulator voltage output mode.
- 3: Low Power which reduces the quiescent current down to only 1uA
-
-The valid modes list is defined in the dt-bindings/regulator/maxim,max77802.h
-header and can be included by device tree source files.
-
-The standard "regulator-mode" property can only be used for regulators that
-support changing their mode to Low Power Mode during suspend. These regulators
-are: BUCKs 2-4 and LDOs 1-35. Also, it only takes effect if the regulator has
-been enabled for the given suspend state using "regulator-on-in-suspend" and
-has not been disabled for that state using "regulator-off-in-suspend".
-
-Example:
-
- max77802@9 {
- compatible = "maxim,max77802";
- interrupt-parent = <&wakeup_eint>;
- interrupts = <26 0>;
- reg = <0x09>;
- #address-cells = <1>;
- #size-cells = <0>;
-
- inb1-supply = <&parent_reg>;
-
- regulators {
- ldo1_reg: LDO1 {
- regulator-name = "vdd_1v0";
- regulator-min-microvolt = <1000000>;
- regulator-max-microvolt = <1000000>;
- regulator-always-on;
- regulator-initial-mode = <MAX77802_OPMODE_LP>;
- };
-
- ldo11_reg: LDO11 {
- regulator-name = "vdd_ldo11";
- regulator-min-microvolt = <1900000>;
- regulator-max-microvolt = <1900000>;
- regulator-always-on;
- regulator-state-mem {
- regulator-on-in-suspend;
- regulator-mode = <MAX77802_OPMODE_LP>;
- };
- };
-
- buck1_reg: BUCK1 {
- regulator-name = "vdd_mif";
- regulator-min-microvolt = <950000>;
- regulator-max-microvolt = <1300000>;
- regulator-always-on;
- regulator-boot-on;
- };
- };
diff --git a/Documentation/devicetree/bindings/regulator/maxim,max14577.yaml b/Documentation/devicetree/bindings/regulator/maxim,max14577.yaml
new file mode 100644
index 000000000000..16f01886a601
--- /dev/null
+++ b/Documentation/devicetree/bindings/regulator/maxim,max14577.yaml
@@ -0,0 +1,78 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/regulator/maxim,max14577.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Maxim MAX14577/MAX77836 MicroUSB and Companion Power Management IC regulators
+
+maintainers:
+ - Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>
+
+description: |
+ This is a part of device tree bindings for Maxim MAX14577/MAX77836 MicroUSB
+ Integrated Circuit (MUIC).
+
+ See also Documentation/devicetree/bindings/mfd/maxim,max14577.yaml for
+ additional information and example.
+
+properties:
+ compatible:
+ enum:
+ - maxim,max14577-regulator
+ - maxim,max77836-regulator
+
+ CHARGER:
+ type: object
+ $ref: regulator.yaml#
+ unevaluatedProperties: false
+ description: |
+ Current regulator.
+
+ properties:
+ regulator-min-microvolt: false
+ regulator-max-microvolt: false
+
+ SAFEOUT:
+ type: object
+ $ref: regulator.yaml#
+ unevaluatedProperties: false
+ description: |
+ Safeout LDO regulator (fixed voltage).
+
+ properties:
+ regulator-min-microamp: false
+ regulator-max-microamp: false
+ regulator-min-microvolt:
+ const: 4900000
+ regulator-max-microvolt:
+ const: 4900000
+
+patternProperties:
+ "^LDO[12]$":
+ type: object
+ $ref: regulator.yaml#
+ unevaluatedProperties: false
+ description: |
+ Current regulator.
+
+ properties:
+ regulator-min-microamp: false
+ regulator-max-microamp: false
+ regulator-min-microvolt:
+ minimum: 800000
+ regulator-max-microvolt:
+ maximum: 3950000
+
+allOf:
+ - if:
+ properties:
+ compatible:
+ contains:
+ const: maxim,max14577-regulator
+ then:
+ properties:
+ LDO1: false
+ LDO2: false
+
+additionalProperties: false
diff --git a/Documentation/devicetree/bindings/regulator/maxim,max77802.yaml b/Documentation/devicetree/bindings/regulator/maxim,max77802.yaml
new file mode 100644
index 000000000000..f2b4dd15a0f3
--- /dev/null
+++ b/Documentation/devicetree/bindings/regulator/maxim,max77802.yaml
@@ -0,0 +1,85 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/regulator/maxim,max77802.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Maxim MAX77802 Power Management IC regulators
+
+maintainers:
+ - Javier Martinez Canillas <javier@dowhile0.org>
+ - Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>
+
+description: |
+ This is a part of device tree bindings for Maxim MAX77802 Power Management
+ Integrated Circuit (PMIC).
+
+ The Maxim MAX77686 provides 10 high-efficiency Buck and 32 Low-DropOut (LDO)
+ regulators.
+
+ See also Documentation/devicetree/bindings/mfd/maxim,max77802.yaml for
+ additional information and example.
+
+ Certain regulators support "regulator-initial-mode" and "regulator-mode".
+ The valid modes list is defined in the dt-bindings/regulator/maxim,max77802.h
+ and their meaning is::
+ 1 - Normal regulator voltage output mode.
+ 3 - Low Power which reduces the quiescent current down to only 1uA
+
+ The standard "regulator-mode" property can only be used for regulators that
+ support changing their mode to Low Power Mode during suspend. These
+ regulators are:: bucks 2-4 and LDOs 1-35. Also, it only takes effect if the
+ regulator has been enabled for the given suspend state using
+ "regulator-on-in-suspend" and has not been disabled for that state using
+ "regulator-off-in-suspend".
+
+patternProperties:
+ # LDO1, LDO3, LDO20, LDO21
+ "^LDO([13]|2[01])$":
+ type: object
+ $ref: regulator.yaml#
+ unevaluatedProperties: false
+ description:
+ LDOs supporting the regulator-initial-mode property and changing their
+ mode during normal operation.
+
+ # LDO2, LDO4-15, LDO17-19, LDO23-30, LDO32-35
+ "^LDO([24-9]|1[0-5789]|2[3-9]|3[02345])$":
+ type: object
+ $ref: regulator.yaml#
+ unevaluatedProperties: false
+ description:
+ LDOs supporting the regulator-mode property (changing mode to Low Power
+ Mode during suspend).
+
+ properties:
+ regulator-initial-mode: false
+
+ # buck2-4
+ "^BUCK[2-4]$":
+ type: object
+ $ref: regulator.yaml#
+ unevaluatedProperties: false
+ description:
+ bucks supporting the regulator-mode property (changing mode to Low Power
+ Mode during suspend).
+
+ properties:
+ regulator-initial-mode: false
+
+ # buck1, buck5-10
+ "^BUCK([15-9]|10)$":
+ type: object
+ $ref: regulator.yaml#
+ unevaluatedProperties: false
+
+ properties:
+ regulator-initial-mode: false
+
+ patternProperties:
+ regulator-state-(standby|mem|disk):
+ type: object
+ properties:
+ regulator-mode: false
+
+additionalProperties: false
diff --git a/Documentation/devicetree/bindings/regulator/maxim,max77843.yaml b/Documentation/devicetree/bindings/regulator/maxim,max77843.yaml
new file mode 100644
index 000000000000..a963025e96c1
--- /dev/null
+++ b/Documentation/devicetree/bindings/regulator/maxim,max77843.yaml
@@ -0,0 +1,65 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/regulator/maxim,max77843.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Maxim MAX77843 MicroUSB and Companion Power Management IC regulators
+
+maintainers:
+ - Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>
+
+description: |
+ This is a part of device tree bindings for Maxim MAX77843 MicroUSB Integrated
+ Circuit (MUIC).
+
+ See also Documentation/devicetree/bindings/mfd/maxim,max77843.yaml for
+ additional information and example.
+
+properties:
+ compatible:
+ const: maxim,max77843-regulator
+
+ CHARGER:
+ type: object
+ $ref: regulator.yaml#
+ additionalProperties: false
+ description: |
+ Current regulator.
+
+ properties:
+ regulator-name: true
+ regulator-always-on: true
+ regulator-boot-on: true
+ regulator-min-microamp:
+ minimum: 100000
+ regulator-max-microamp:
+ maximum: 3150000
+
+ required:
+ - regulator-name
+
+patternProperties:
+ "^SAFEOUT[12]$":
+ type: object
+ $ref: regulator.yaml#
+ additionalProperties: false
+ description: |
+ Safeout LDO regulator.
+
+ properties:
+ regulator-name: true
+ regulator-always-on: true
+ regulator-boot-on: true
+ regulator-min-microvolt:
+ minimum: 3300000
+ regulator-max-microvolt:
+ maximum: 4950000
+
+ required:
+ - regulator-name
+
+required:
+ - compatible
+
+additionalProperties: false
diff --git a/Documentation/devicetree/bindings/regulator/maxim,max8973.yaml b/Documentation/devicetree/bindings/regulator/maxim,max8973.yaml
index 35c53e27f78c..5898dcf10f06 100644
--- a/Documentation/devicetree/bindings/regulator/maxim,max8973.yaml
+++ b/Documentation/devicetree/bindings/regulator/maxim,max8973.yaml
@@ -113,7 +113,7 @@ examples:
};
- |
- #include <dt-bindings/gpio/tegra-gpio.h>
+ #include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/interrupt-controller/irq.h>
i2c {
@@ -123,8 +123,7 @@ examples:
regulator@1b {
compatible = "maxim,max77621";
reg = <0x1b>;
- interrupt-parent = <&gpio>;
- interrupts = <TEGRA_GPIO(Y, 1) IRQ_TYPE_LEVEL_LOW>;
+ interrupts = <1 IRQ_TYPE_LEVEL_LOW>;
regulator-always-on;
regulator-boot-on;
diff --git a/Documentation/devicetree/bindings/regulator/pfuze100.yaml b/Documentation/devicetree/bindings/regulator/pfuze100.yaml
index f578e72778a7..a26bbd68b729 100644
--- a/Documentation/devicetree/bindings/regulator/pfuze100.yaml
+++ b/Documentation/devicetree/bindings/regulator/pfuze100.yaml
@@ -70,7 +70,11 @@ properties:
$ref: "regulator.yaml#"
type: object
- "^(vsnvs|vref|vrefddr|swbst|coin)$":
+ "^vldo[1-4]$":
+ $ref: "regulator.yaml#"
+ type: object
+
+ "^(vsnvs|vref|vrefddr|swbst|coin|v33|vccsd)$":
$ref: "regulator.yaml#"
type: object
diff --git a/Documentation/devicetree/bindings/regulator/qcom,rpmh-regulator.yaml b/Documentation/devicetree/bindings/regulator/qcom,rpmh-regulator.yaml
index 5c73d3f639c7..e28ee9e46788 100644
--- a/Documentation/devicetree/bindings/regulator/qcom,rpmh-regulator.yaml
+++ b/Documentation/devicetree/bindings/regulator/qcom,rpmh-regulator.yaml
@@ -48,6 +48,7 @@ description: |
For PMI8998, bob
For PMR735A, smps1 - smps3, ldo1 - ldo7
For PMX55, smps1 - smps7, ldo1 - ldo16
+ For PMX65, smps1 - smps8, ldo1 - ldo21
properties:
compatible:
@@ -70,6 +71,7 @@ properties:
- qcom,pmm8155au-rpmh-regulators
- qcom,pmr735a-rpmh-regulators
- qcom,pmx55-rpmh-regulators
+ - qcom,pmx65-rpmh-regulators
qcom,pmic-id:
description: |
diff --git a/Documentation/devicetree/bindings/regulator/richtek,rt5190a-regulator.yaml b/Documentation/devicetree/bindings/regulator/richtek,rt5190a-regulator.yaml
new file mode 100644
index 000000000000..28725c5467fc
--- /dev/null
+++ b/Documentation/devicetree/bindings/regulator/richtek,rt5190a-regulator.yaml
@@ -0,0 +1,141 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/regulator/richtek,rt5190a-regulator.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Richtek RT5190A PMIC Regulator
+
+maintainers:
+ - ChiYuan Huang <cy_huang@richtek.com>
+
+description: |
+ The RT5190A integrates 1 channel buck controller, 3 channels high efficiency
+ synchronous buck converters, 1 LDO, I2C control interface and peripherial
+ logical control.
+
+ It also supports mute AC OFF depop sound and quick setting storage while
+ input power is removed.
+
+properties:
+ compatible:
+ enum:
+ - richtek,rt5190a
+
+ reg:
+ maxItems: 1
+
+ interrupts:
+ maxItems: 1
+
+ vin2-supply:
+ description: phandle to buck2 input voltage.
+
+ vin3-supply:
+ description: phandle to buck3 input voltage.
+
+ vin4-supply:
+ description: phandle to buck4 input voltage.
+
+ vinldo-supply:
+ description: phandle to ldo input voltage
+
+ richtek,mute-enable:
+ description: |
+ The mute function uses 'mutein', 'muteout', and 'vdet' pins as the control
+ signal. When enabled, The normal behavior is to bypass the 'mutein' signal
+ 'muteout'. But if the power source removal is detected from 'vdet',
+ whatever the 'mutein' signal is, it will pull down the 'muteout' to force
+ speakers mute. this function is commonly used to prevent the speaker pop
+ noise during AC power turned off in the modern TV system design.
+ type: boolean
+
+ regulators:
+ type: object
+
+ patternProperties:
+ "^buck[1-4]$|^ldo$":
+ type: object
+ $ref: regulator.yaml#
+ description: |
+ regulator description for buck1 and buck4.
+
+ properties:
+ regulator-allowed-modes:
+ description: |
+ buck operating mode, only buck1/4 support mode operating.
+ 0: auto mode
+ 1: force pwm mode
+ items:
+ enum: [0, 1]
+
+ richtek,latchup-enable:
+ type: boolean
+ description: |
+ If specified, undervolt protection mode changes from the default
+ hiccup to latchup.
+
+ unevaluatedProperties: false
+
+ additionalProperties: false
+
+required:
+ - compatible
+ - reg
+ - regulators
+
+additionalProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/interrupt-controller/irq.h>
+ #include <dt-bindings/regulator/richtek,rt5190a-regulator.h>
+
+ i2c {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pmic@64 {
+ compatible = "richtek,rt5190a";
+ reg = <0x64>;
+ interrupts-extended = <&gpio26 0 IRQ_TYPE_LEVEL_LOW>;
+ vin2-supply = <&rt5190_buck1>;
+ vin3-supply = <&rt5190_buck1>;
+ vin4-supply = <&rt5190_buck1>;
+
+ regulators {
+ rt5190_buck1: buck1 {
+ regulator-name = "rt5190a-buck1";
+ regulator-min-microvolt = <5090000>;
+ regulator-max-microvolt = <5090000>;
+ regulator-allowed-modes = <RT5190A_OPMODE_AUTO RT5190A_OPMODE_FPWM>;
+ regulator-boot-on;
+ };
+ buck2 {
+ regulator-name = "rt5190a-buck2";
+ regulator-min-microvolt = <600000>;
+ regulator-max-microvolt = <1400000>;
+ regulator-boot-on;
+ };
+ buck3 {
+ regulator-name = "rt5190a-buck3";
+ regulator-min-microvolt = <600000>;
+ regulator-max-microvolt = <1400000>;
+ regulator-boot-on;
+ };
+ buck4 {
+ regulator-name = "rt5190a-buck4";
+ regulator-min-microvolt = <850000>;
+ regulator-max-microvolt = <850000>;
+ regulator-allowed-modes = <RT5190A_OPMODE_AUTO RT5190A_OPMODE_FPWM>;
+ regulator-boot-on;
+ };
+ ldo {
+ regulator-name = "rt5190a-ldo";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-boot-on;
+ };
+ };
+ };
+ };
diff --git a/Documentation/devicetree/bindings/regulator/ti,tps62360.yaml b/Documentation/devicetree/bindings/regulator/ti,tps62360.yaml
new file mode 100644
index 000000000000..12aeddedde05
--- /dev/null
+++ b/Documentation/devicetree/bindings/regulator/ti,tps62360.yaml
@@ -0,0 +1,98 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/regulator/ti,tps62360.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Texas Instruments TPS6236x Voltage Regulators
+
+maintainers:
+ - Laxman Dewangan <ldewangan@nvidia.com>
+
+description: |
+ The TPS6236x are a family of step down dc-dc converter with
+ an input voltage range of 2.5V to 5.5V. The devices provide
+ up to 3A peak load current, and an output voltage range of
+ 0.77V to 1.4V (TPS62360/62) and 0.5V to 1.77V (TPS62361B/63).
+
+ Datasheet is available at:
+ https://www.ti.com/lit/gpn/tps62360
+
+allOf:
+ - $ref: "regulator.yaml#"
+
+properties:
+ compatible:
+ enum:
+ - ti,tps62360
+ - ti,tps62361
+ - ti,tps62362
+ - ti,tps62363
+
+ reg:
+ maxItems: 1
+
+ ti,vsel0-gpio:
+ description: |
+ GPIO for controlling VSEL0 line. If this property
+ is missing, then assume that there is no GPIO for
+ VSEL0 control.
+ maxItems: 1
+
+ ti,vsel1-gpio:
+ description: |
+ GPIO for controlling VSEL1 line. If this property
+ is missing, then assume that there is no GPIO for
+ VSEL1 control.
+ maxItems: 1
+
+ ti,enable-vout-discharge:
+ description: Enable output discharge.
+ type: boolean
+
+ ti,enable-pull-down:
+ description: Enable pull down.
+ type: boolean
+
+ ti,vsel0-state-high:
+ description: |
+ Initial state of VSEL0 input is high. If this property
+ is missing, then assume the state as low.
+ type: boolean
+
+ ti,vsel1-state-high:
+ description: |
+ Initial state of VSEL1 input is high. If this property
+ is missing, then assume the state as low.
+ type: boolean
+
+required:
+ - compatible
+ - reg
+
+unevaluatedProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/gpio/gpio.h>
+ i2c {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ regulator@60 {
+ compatible = "ti,tps62361";
+ reg = <0x60>;
+ regulator-name = "tps62361-vout";
+ regulator-min-microvolt = <500000>;
+ regulator-max-microvolt = <1500000>;
+ regulator-boot-on;
+ ti,vsel0-gpio = <&gpio1 16 GPIO_ACTIVE_HIGH>;
+ ti,vsel1-gpio = <&gpio1 17 GPIO_ACTIVE_HIGH>;
+ ti,vsel0-state-high;
+ ti,vsel1-state-high;
+ ti,enable-pull-down;
+ ti,enable-vout-discharge;
+ };
+ };
+
+...
diff --git a/Documentation/devicetree/bindings/regulator/ti,tps62864.yaml b/Documentation/devicetree/bindings/regulator/ti,tps62864.yaml
new file mode 100644
index 000000000000..0f29c75f42ea
--- /dev/null
+++ b/Documentation/devicetree/bindings/regulator/ti,tps62864.yaml
@@ -0,0 +1,63 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/regulator/ti,tps62864.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: TI TPS62864/TPS6286/TPS62868/TPS62869 voltage regulator
+
+maintainers:
+ - Vincent Whitchurch <vincent.whitchurch@axis.com>
+
+properties:
+ compatible:
+ enum:
+ - ti,tps62864
+ - ti,tps62866
+ - ti,tps62868
+ - ti,tps62869
+
+ reg:
+ maxItems: 1
+
+ regulators:
+ type: object
+
+ properties:
+ "SW":
+ type: object
+ $ref: regulator.yaml#
+ unevaluatedProperties: false
+
+ additionalProperties: false
+
+required:
+ - compatible
+ - reg
+ - regulators
+
+additionalProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/regulator/ti,tps62864.h>
+ i2c {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ regulator@48 {
+ compatible = "ti,tps62864";
+ reg = <0x48>;
+
+ regulators {
+ SW {
+ regulator-name = "+0.85V";
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <890000>;
+ regulator-initial-mode = <TPS62864_MODE_FPWM>;
+ };
+ };
+ };
+ };
+
+...
diff --git a/Documentation/devicetree/bindings/regulator/tps62360-regulator.txt b/Documentation/devicetree/bindings/regulator/tps62360-regulator.txt
deleted file mode 100644
index 1b20c3dbcdb8..000000000000
--- a/Documentation/devicetree/bindings/regulator/tps62360-regulator.txt
+++ /dev/null
@@ -1,44 +0,0 @@
-TPS62360 Voltage regulators
-
-Required properties:
-- compatible: Must be one of the following.
- "ti,tps62360"
- "ti,tps62361",
- "ti,tps62362",
- "ti,tps62363",
-- reg: I2C slave address
-
-Optional properties:
-- ti,enable-vout-discharge: Enable output discharge. This is boolean value.
-- ti,enable-pull-down: Enable pull down. This is boolean value.
-- ti,vsel0-gpio: GPIO for controlling VSEL0 line.
- If this property is missing, then assume that there is no GPIO
- for vsel0 control.
-- ti,vsel1-gpio: Gpio for controlling VSEL1 line.
- If this property is missing, then assume that there is no GPIO
- for vsel1 control.
-- ti,vsel0-state-high: Initial state of vsel0 input is high.
- If this property is missing, then assume the state as low (0).
-- ti,vsel1-state-high: Initial state of vsel1 input is high.
- If this property is missing, then assume the state as low (0).
-
-Any property defined as part of the core regulator binding, defined in
-regulator.txt, can also be used.
-
-Example:
-
- abc: tps62360 {
- compatible = "ti,tps62361";
- reg = <0x60>;
- regulator-name = "tps62361-vout";
- regulator-min-microvolt = <500000>;
- regulator-max-microvolt = <1500000>;
- regulator-boot-on
- ti,vsel0-gpio = <&gpio1 16 0>;
- ti,vsel1-gpio = <&gpio1 17 0>;
- ti,vsel0-state-high;
- ti,vsel1-state-high;
- ti,enable-pull-down;
- ti,enable-force-pwm;
- ti,enable-vout-discharge;
- };
diff --git a/Documentation/devicetree/bindings/remoteproc/qcom,adsp.yaml b/Documentation/devicetree/bindings/remoteproc/qcom,adsp.yaml
index c635c181d2c2..64c182428e94 100644
--- a/Documentation/devicetree/bindings/remoteproc/qcom,adsp.yaml
+++ b/Documentation/devicetree/bindings/remoteproc/qcom,adsp.yaml
@@ -47,6 +47,10 @@ properties:
- qcom,sm8350-cdsp-pas
- qcom,sm8350-slpi-pas
- qcom,sm8350-mpss-pas
+ - qcom,sm8450-adsp-pas
+ - qcom,sm8450-cdsp-pas
+ - qcom,sm8450-mpss-pas
+ - qcom,sm8450-slpi-pas
reg:
maxItems: 1
@@ -175,6 +179,10 @@ allOf:
- qcom,sm8350-cdsp-pas
- qcom,sm8350-slpi-pas
- qcom,sm8350-mpss-pas
+ - qcom,sm8450-adsp-pas
+ - qcom,sm8450-cdsp-pas
+ - qcom,sm8450-slpi-pas
+ - qcom,sm8450-mpss-pas
then:
properties:
clocks:
@@ -283,6 +291,9 @@ allOf:
- qcom,sm8350-adsp-pas
- qcom,sm8350-cdsp-pas
- qcom,sm8350-slpi-pas
+ - qcom,sm8450-adsp-pas
+ - qcom,sm8450-cdsp-pas
+ - qcom,sm8450-slpi-pas
then:
properties:
interrupts:
@@ -312,6 +323,7 @@ allOf:
- qcom,sm6350-mpss-pas
- qcom,sm8150-mpss-pas
- qcom,sm8350-mpss-pas
+ - qcom,sm8450-mpss-pas
then:
properties:
interrupts:
@@ -434,6 +446,7 @@ allOf:
- qcom,sm6350-mpss-pas
- qcom,sm8150-mpss-pas
- qcom,sm8350-mpss-pas
+ - qcom,sm8450-mpss-pas
then:
properties:
power-domains:
@@ -458,6 +471,8 @@ allOf:
- qcom,sm8250-slpi-pas
- qcom,sm8350-adsp-pas
- qcom,sm8350-slpi-pas
+ - qcom,sm8450-adsp-pas
+ - qcom,sm8450-slpi-pas
then:
properties:
power-domains:
@@ -475,6 +490,7 @@ allOf:
contains:
enum:
- qcom,sm8350-cdsp-pas
+ - qcom,sm8450-cdsp-pas
then:
properties:
power-domains:
diff --git a/Documentation/devicetree/bindings/riscv/sifive-l2-cache.yaml b/Documentation/devicetree/bindings/riscv/sifive-l2-cache.yaml
index 2b1f91603897..e2d330bd4608 100644
--- a/Documentation/devicetree/bindings/riscv/sifive-l2-cache.yaml
+++ b/Documentation/devicetree/bindings/riscv/sifive-l2-cache.yaml
@@ -9,7 +9,6 @@ title: SiFive L2 Cache Controller
maintainers:
- Sagar Kadam <sagar.kadam@sifive.com>
- - Yash Shah <yash.shah@sifive.com>
- Paul Walmsley <paul.walmsley@sifive.com>
description:
diff --git a/Documentation/devicetree/bindings/soc/imx/fsl,imx8mp-hsio-blk-ctrl.yaml b/Documentation/devicetree/bindings/soc/imx/fsl,imx8mp-hsio-blk-ctrl.yaml
new file mode 100644
index 000000000000..c1e29d94f40e
--- /dev/null
+++ b/Documentation/devicetree/bindings/soc/imx/fsl,imx8mp-hsio-blk-ctrl.yaml
@@ -0,0 +1,78 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/soc/imx/fsl,imx8mp-hsio-blk-ctrl.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: NXP i.MX8MP HSIO blk-ctrl
+
+maintainers:
+ - Lucas Stach <l.stach@pengutronix.de>
+
+description:
+ The i.MX8MP HSIO blk-ctrl is a top-level peripheral providing access to
+ the NoC and ensuring proper power sequencing of the high-speed IO
+ (USB an PCIe) peripherals located in the HSIO domain of the SoC.
+
+properties:
+ compatible:
+ items:
+ - const: fsl,imx8mp-hsio-blk-ctrl
+ - const: syscon
+
+ reg:
+ maxItems: 1
+
+ '#power-domain-cells':
+ const: 1
+
+ power-domains:
+ minItems: 6
+ maxItems: 6
+
+ power-domain-names:
+ items:
+ - const: bus
+ - const: usb
+ - const: usb-phy1
+ - const: usb-phy2
+ - const: pcie
+ - const: pcie-phy
+
+ clocks:
+ minItems: 2
+ maxItems: 2
+
+ clock-names:
+ items:
+ - const: usb
+ - const: pcie
+
+required:
+ - compatible
+ - reg
+ - power-domains
+ - power-domain-names
+ - clocks
+ - clock-names
+
+additionalProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/clock/imx8mp-clock.h>
+ #include <dt-bindings/power/imx8mp-power.h>
+
+ hsio_blk_ctrl: blk-ctrl@32f10000 {
+ compatible = "fsl,imx8mp-hsio-blk-ctrl", "syscon";
+ reg = <0x32f10000 0x24>;
+ clocks = <&clk IMX8MP_CLK_USB_ROOT>,
+ <&clk IMX8MP_CLK_PCIE_ROOT>;
+ clock-names = "usb", "pcie";
+ power-domains = <&pgc_hsiomix>, <&pgc_hsiomix>,
+ <&pgc_usb1_phy>, <&pgc_usb2_phy>,
+ <&pgc_hsiomix>, <&pgc_pcie_phy>;
+ power-domain-names = "bus", "usb", "usb-phy1",
+ "usb-phy2", "pcie", "pcie-phy";
+ #power-domain-cells = <1>;
+ };
diff --git a/Documentation/devicetree/bindings/soc/imx/fsl,imx8mq-vpu-blk-ctrl.yaml b/Documentation/devicetree/bindings/soc/imx/fsl,imx8mq-vpu-blk-ctrl.yaml
new file mode 100644
index 000000000000..7263ebedf09f
--- /dev/null
+++ b/Documentation/devicetree/bindings/soc/imx/fsl,imx8mq-vpu-blk-ctrl.yaml
@@ -0,0 +1,71 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/soc/imx/fsl,imx8mq-vpu-blk-ctrl.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: NXP i.MX8MQ VPU blk-ctrl
+
+maintainers:
+ - Lucas Stach <l.stach@pengutronix.de>
+
+description:
+ The i.MX8MQ VPU blk-ctrl is a top-level peripheral providing access to
+ the NoC and ensuring proper power sequencing of the VPU peripherals
+ located in the VPU domain of the SoC.
+
+properties:
+ compatible:
+ items:
+ - const: fsl,imx8mq-vpu-blk-ctrl
+
+ reg:
+ maxItems: 1
+
+ '#power-domain-cells':
+ const: 1
+
+ power-domains:
+ minItems: 3
+ maxItems: 3
+
+ power-domain-names:
+ items:
+ - const: bus
+ - const: g1
+ - const: g2
+
+ clocks:
+ minItems: 2
+ maxItems: 2
+
+ clock-names:
+ items:
+ - const: g1
+ - const: g2
+
+required:
+ - compatible
+ - reg
+ - power-domains
+ - power-domain-names
+ - clocks
+ - clock-names
+
+additionalProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/clock/imx8mq-clock.h>
+ #include <dt-bindings/power/imx8mq-power.h>
+
+ vpu_blk_ctrl: blk-ctrl@38320000 {
+ compatible = "fsl,imx8mq-vpu-blk-ctrl";
+ reg = <0x38320000 0x100>;
+ power-domains = <&pgc_vpu>, <&pgc_vpu>, <&pgc_vpu>;
+ power-domain-names = "bus", "g1", "g2";
+ clocks = <&clk IMX8MQ_CLK_VPU_G1_ROOT>,
+ <&clk IMX8MQ_CLK_VPU_G2_ROOT>;
+ clock-names = "g1", "g2";
+ #power-domain-cells = <1>;
+ };
diff --git a/Documentation/devicetree/bindings/soc/mediatek/pwrap.txt b/Documentation/devicetree/bindings/soc/mediatek/pwrap.txt
index d74a7a5ae9f2..214a34633824 100644
--- a/Documentation/devicetree/bindings/soc/mediatek/pwrap.txt
+++ b/Documentation/devicetree/bindings/soc/mediatek/pwrap.txt
@@ -27,6 +27,7 @@ Required properties in pwrap device node.
"mediatek,mt8135-pwrap" for MT8135 SoCs
"mediatek,mt8173-pwrap" for MT8173 SoCs
"mediatek,mt8183-pwrap" for MT8183 SoCs
+ "mediatek,mt8186-pwrap" for MT8186 SoCs
"mediatek,mt8195-pwrap" for MT8195 SoCs
"mediatek,mt8516-pwrap" for MT8516 SoCs
- interrupts: IRQ for pwrap in SOC
diff --git a/Documentation/devicetree/bindings/soc/rockchip/grf.yaml b/Documentation/devicetree/bindings/soc/rockchip/grf.yaml
index dfebf425ca49..b2ba7bed89b2 100644
--- a/Documentation/devicetree/bindings/soc/rockchip/grf.yaml
+++ b/Documentation/devicetree/bindings/soc/rockchip/grf.yaml
@@ -15,6 +15,7 @@ properties:
- items:
- enum:
- rockchip,rk3288-sgrf
+ - rockchip,rk3568-usb2phy-grf
- rockchip,rv1108-usbgrf
- const: syscon
- items:
diff --git a/Documentation/devicetree/bindings/soc/samsung/exynos-usi.yaml b/Documentation/devicetree/bindings/soc/samsung/exynos-usi.yaml
index 273f2d95a043..ea9c233052f3 100644
--- a/Documentation/devicetree/bindings/soc/samsung/exynos-usi.yaml
+++ b/Documentation/devicetree/bindings/soc/samsung/exynos-usi.yaml
@@ -17,13 +17,6 @@ description: |
child nodes, each representing a serial sub-node device. The mode setting
selects which particular function will be used.
- Refer to next bindings documentation for information on protocol subnodes that
- can exist under USI node:
-
- [1] Documentation/devicetree/bindings/serial/samsung_uart.yaml
- [2] Documentation/devicetree/bindings/i2c/i2c-exynos5.txt
- [3] Documentation/devicetree/bindings/spi/spi-samsung.txt
-
properties:
$nodename:
pattern: "^usi@[0-9a-f]+$"
@@ -71,10 +64,17 @@ properties:
This property is optional.
patternProperties:
- # All other properties should be child nodes
- "^(serial|spi|i2c)@[0-9a-f]+$":
+ "^i2c@[0-9a-f]+$":
+ $ref: /schemas/i2c/i2c-exynos5.yaml
+ description: Child node describing underlying I2C
+
+ "^serial@[0-9a-f]+$":
+ $ref: /schemas/serial/samsung_uart.yaml
+ description: Child node describing underlying UART/serial
+
+ "^spi@[0-9a-f]+$":
type: object
- description: Child node describing underlying USI serial protocol
+ description: Child node describing underlying SPI
required:
- compatible
diff --git a/Documentation/devicetree/bindings/sound/allwinner,sun4i-a10-i2s.yaml b/Documentation/devicetree/bindings/sound/allwinner,sun4i-a10-i2s.yaml
index 7d48ea094c66..c21c807b667c 100644
--- a/Documentation/devicetree/bindings/sound/allwinner,sun4i-a10-i2s.yaml
+++ b/Documentation/devicetree/bindings/sound/allwinner,sun4i-a10-i2s.yaml
@@ -31,6 +31,10 @@ properties:
- const: allwinner,sun50i-a64-i2s
- const: allwinner,sun8i-h3-i2s
- const: allwinner,sun50i-h6-i2s
+ - const: allwinner,sun50i-r329-i2s
+ - items:
+ - const: allwinner,sun20i-d1-i2s
+ - const: allwinner,sun50i-r329-i2s
reg:
maxItems: 1
@@ -67,6 +71,7 @@ allOf:
- allwinner,sun8i-h3-i2s
- allwinner,sun50i-a64-codec-i2s
- allwinner,sun50i-h6-i2s
+ - allwinner,sun50i-r329-i2s
then:
required:
diff --git a/Documentation/devicetree/bindings/sound/arndale.txt b/Documentation/devicetree/bindings/sound/arndale.txt
deleted file mode 100644
index 17530120ccfc..000000000000
--- a/Documentation/devicetree/bindings/sound/arndale.txt
+++ /dev/null
@@ -1,25 +0,0 @@
-Audio Binding for Arndale boards
-
-Required properties:
-- compatible : Can be one of the following:
- "samsung,arndale-rt5631",
- "samsung,arndale-wm1811"
-
-- samsung,audio-cpu: The phandle of the Samsung I2S controller
-- samsung,audio-codec: The phandle of the audio codec
-
-Optional:
-- samsung,model: The name of the sound-card
-
-Arndale Boards has many audio daughter cards, one of them is
-rt5631/alc5631. Below example shows audio bindings for rt5631/
-alc5631 based codec.
-
-Example:
-
-sound {
- compatible = "samsung,arndale-rt5631";
-
- samsung,audio-cpu = <&i2s0>
- samsung,audio-codec = <&rt5631>;
-};
diff --git a/Documentation/devicetree/bindings/sound/audio-graph-port.yaml b/Documentation/devicetree/bindings/sound/audio-graph-port.yaml
index 476dcb49ece6..5c368674d11a 100644
--- a/Documentation/devicetree/bindings/sound/audio-graph-port.yaml
+++ b/Documentation/devicetree/bindings/sound/audio-graph-port.yaml
@@ -71,4 +71,24 @@ patternProperties:
description: CPU to Codec rate channels.
$ref: /schemas/types.yaml#/definitions/uint32
+ dai-tdm-slot-width-map:
+ description: Mapping of sample widths to slot widths. For hardware
+ that cannot support a fixed slot width or a slot width always
+ equal to sample width. A matrix of one or more 3-tuples.
+ $ref: /schemas/types.yaml#/definitions/uint32-matrix
+ items:
+ items:
+ -
+ description: Sample width in bits
+ minimum: 8
+ maximum: 64
+ -
+ description: Slot width in bits
+ minimum: 8
+ maximum: 256
+ -
+ description: Slot count
+ minimum: 1
+ maximum: 64
+
additionalProperties: true
diff --git a/Documentation/devicetree/bindings/sound/awinic,aw8738.yaml b/Documentation/devicetree/bindings/sound/awinic,aw8738.yaml
new file mode 100644
index 000000000000..dce86dafe382
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/awinic,aw8738.yaml
@@ -0,0 +1,54 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/sound/awinic,aw8738.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Awinic AW8738 Audio Amplifier
+
+maintainers:
+ - Stephan Gerhold <stephan@gerhold.net>
+
+description:
+ The Awinic AW8738 is a simple audio amplifier with different operation modes
+ (set using one-wire pulse control). The mode configures the speaker-guard
+ function (primarily the power limit for the amplifier).
+
+allOf:
+ - $ref: name-prefix.yaml#
+
+properties:
+ compatible:
+ const: awinic,aw8738
+
+ mode-gpios:
+ description:
+ GPIO used for one-wire pulse control. The pin is typically called SHDN
+ (active-low), but this is misleading since it is actually more than
+ just a simple shutdown/enable control.
+ maxItems: 1
+
+ awinic,mode:
+ description: Operation mode (number of pulses for one-wire pulse control)
+ $ref: /schemas/types.yaml#/definitions/uint32
+ minimum: 1
+ maximum: 7
+
+ sound-name-prefix: true
+
+required:
+ - compatible
+ - mode-gpios
+ - awinic,mode
+
+additionalProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/gpio/gpio.h>
+ audio-amplifier {
+ compatible = "awinic,aw8738";
+ mode-gpios = <&msmgpio 114 GPIO_ACTIVE_HIGH>;
+ awinic,mode = <5>;
+ sound-name-prefix = "Speaker Amp";
+ };
diff --git a/Documentation/devicetree/bindings/sound/davinci-mcasp-audio.txt b/Documentation/devicetree/bindings/sound/davinci-mcasp-audio.txt
deleted file mode 100644
index bd863bd69501..000000000000
--- a/Documentation/devicetree/bindings/sound/davinci-mcasp-audio.txt
+++ /dev/null
@@ -1,86 +0,0 @@
-Texas Instruments McASP controller
-
-Required properties:
-- compatible :
- "ti,dm646x-mcasp-audio" : for DM646x platforms
- "ti,da830-mcasp-audio" : for both DA830 & DA850 platforms
- "ti,am33xx-mcasp-audio" : for AM33xx platforms (AM33xx, AM43xx, TI81xx)
- "ti,dra7-mcasp-audio" : for DRA7xx platforms
- "ti,omap4-mcasp-audio" : for OMAP4
-
-- reg : Should contain reg specifiers for the entries in the reg-names property.
-- reg-names : Should contain:
- * "mpu" for the main registers (required). For compatibility with
- existing software, it is recommended this is the first entry.
- * "dat" for separate data port register access (optional).
-- op-mode : I2S/DIT ops mode. 0 for I2S mode. 1 for DIT mode used for S/PDIF,
- IEC60958-1, and AES-3 formats.
-- tdm-slots : Slots for TDM operation. Indicates number of channels transmitted
- or received over one serializer.
-- serial-dir : A list of serializer configuration. Each entry is a number
- indication for serializer pin direction.
- (0 - INACTIVE, 1 - TX, 2 - RX)
-- dmas: two element list of DMA controller phandles and DMA request line
- ordered pairs.
-- dma-names: identifier string for each DMA request line in the dmas property.
- These strings correspond 1:1 with the ordered pairs in dmas. The dma
- identifiers must be "rx" and "tx".
-
-Optional properties:
-
-- ti,hwmods : Must be "mcasp<n>", n is controller instance starting 0
-- tx-num-evt : FIFO levels.
-- rx-num-evt : FIFO levels.
-- dismod : Specify the drive on TX pin during inactive slots
- 0 : 3-state
- 2 : logic low
- 3 : logic high
- Defaults to 'logic low' when the property is not present
-- sram-size-playback : size of sram to be allocated during playback
-- sram-size-capture : size of sram to be allocated during capture
-- interrupts : Interrupt numbers for McASP
-- interrupt-names : Known interrupt names are "tx" and "rx"
-- pinctrl-0: Should specify pin control group used for this controller.
-- pinctrl-names: Should contain only one value - "default", for more details
- please refer to pinctrl-bindings.txt
-- fck_parent : Should contain a valid clock name which will be used as parent
- for the McASP fck
-- auxclk-fs-ratio: When McASP is bus master indicates the ratio between AUCLK
- and FS rate if applicable:
- AUCLK rate = auxclk-fs-ratio * FS rate
-
-Optional GPIO support:
-If any McASP pin need to be used as GPIO then the McASP node must have:
-...
- gpio-controller
- #gpio-cells = <2>;
-...
-
-When requesting a GPIO, the first parameter is the PIN index in McASP_P*
-registers.
-For example to request the AXR2 pin of mcasp8:
-function-gpios = <&mcasp8 2 0>;
-
-Or to request the ACLKR pin of mcasp8:
-function-gpios = <&mcasp8 29 0>;
-
-For generic gpio information, please refer to bindings/gpio/gpio.txt
-
-Example:
-
-mcasp0: mcasp0@1d00000 {
- compatible = "ti,da830-mcasp-audio";
- reg = <0x100000 0x3000>;
- reg-names "mpu";
- interrupts = <82>, <83>;
- interrupt-names = "tx", "rx";
- op-mode = <0>; /* MCASP_IIS_MODE */
- tdm-slots = <2>;
- serial-dir = <
- 0 0 0 0 /* 0: INACTIVE, 1: TX, 2: RX */
- 0 0 0 0
- 0 0 0 1
- 2 0 0 0 >;
- tx-num-evt = <1>;
- rx-num-evt = <1>;
-};
diff --git a/Documentation/devicetree/bindings/sound/davinci-mcasp-audio.yaml b/Documentation/devicetree/bindings/sound/davinci-mcasp-audio.yaml
new file mode 100644
index 000000000000..f46c66bc6b2d
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/davinci-mcasp-audio.yaml
@@ -0,0 +1,201 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/sound/davinci-mcasp-audio.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: McASP Controller for TI SoCs
+
+maintainers:
+ - Jayesh Choudhary <j-choudhary@ti.com>
+
+properties:
+ compatible:
+ enum:
+ - ti,dm646x-mcasp-audio
+ - ti,da830-mcasp-audio
+ - ti,am33xx-mcasp-audio
+ - ti,dra7-mcasp-audio
+ - ti,omap4-mcasp-audio
+
+ reg:
+ minItems: 1
+ items:
+ - description: CFG registers
+ - description: data registers
+
+ reg-names:
+ minItems: 1
+ items:
+ - const: mpu
+ - const: dat
+
+ op-mode:
+ $ref: /schemas/types.yaml#/definitions/uint32
+ description: 0 - I2S or 1 - DIT operation mode
+ enum:
+ - 0
+ - 1
+
+ tdm-slots:
+ $ref: /schemas/types.yaml#/definitions/uint32
+ description:
+ number of channels over one serializer
+ the property is ignored in DIT mode
+ minimum: 2
+ maximum: 32
+
+ serial-dir:
+ description:
+ A list of serializer configuration
+ Entry is indication for serializer pin direction
+ 0 - Inactive, 1 - TX, 2 - RX
+ All AXR pins should be present in the array even if inactive
+ $ref: /schemas/types.yaml#/definitions/uint32-array
+ minItems: 1
+ maxItems: 25
+ items:
+ minimum: 0
+ maximum: 2
+
+ dmas:
+ minItems: 1
+ items:
+ - description: transmission DMA channel
+ - description: reception DMA channel
+
+ dma-names:
+ minItems: 1
+ items:
+ - const: tx
+ - const: rx
+
+ ti,hwmods:
+ $ref: /schemas/types.yaml#/definitions/string
+ description: Name of hwmod associated with McASP
+ maxItems: 1
+ deprecated: true
+
+ tx-num-evt:
+ $ref: /schemas/types.yaml#/definitions/uint32
+ description:
+ configures WFIFO threshold
+ 0 disables the FIFO use
+ if property is missing, then also FIFO use is disabled
+
+ rx-num-evt:
+ $ref: /schemas/types.yaml#/definitions/uint32
+ description:
+ configures RFIFO threshold
+ 0 disables the FIFO use
+ if property is missing, then also FIFO use is disabled
+
+ dismod:
+ $ref: /schemas/types.yaml#/definitions/uint32
+ description:
+ specify the drive on TX pin during inactive time slots
+ 0 - 3-state, 2 - logic low, 3 - logic high
+ enum:
+ - 0
+ - 2
+ - 3
+ default: 2
+
+ interrupts:
+ anyOf:
+ - minItems: 1
+ items:
+ - description: TX interrupt
+ - description: RX interrupt
+ - items:
+ - description: common/combined interrupt
+
+ interrupt-names:
+ oneOf:
+ - minItems: 1
+ items:
+ - const: tx
+ - const: rx
+ - const: common
+
+ fck_parent:
+ $ref: /schemas/types.yaml#/definitions/string
+ description: parent clock name for McASP fck
+ maxItems: 1
+
+ auxclk-fs-ratio:
+ $ref: /schemas/types.yaml#/definitions/uint32
+ description: ratio of AUCLK and FS rate if applicable
+
+ gpio-controller: true
+
+ "#gpio-cells":
+ const: 2
+
+ clocks:
+ minItems: 1
+ items:
+ - description: functional clock
+ - description: module specific optional ahclkx clock
+ - description: module specific optional ahclkr clock
+
+ clock-names:
+ minItems: 1
+ items:
+ - const: fck
+ - const: ahclkx
+ - const: ahclkr
+
+ power-domains:
+ description: phandle to the corresponding power-domain
+ maxItems: 1
+
+ "#sound-dai-cells":
+ const: 0
+
+ port:
+ description: connection for when McASP is used via graph card
+ type: object
+
+required:
+ - compatible
+ - reg
+ - reg-names
+ - dmas
+ - dma-names
+ - interrupts
+ - interrupt-names
+
+allOf:
+ - if:
+ properties:
+ opmode:
+ enum:
+ - 0
+
+ then:
+ required:
+ - tdm-slots
+
+additionalProperties: false
+
+examples:
+ - |
+ mcasp0: mcasp0@1d00000 {
+ compatible = "ti,da830-mcasp-audio";
+ reg = <0x100000 0x3000>;
+ reg-names = "mpu";
+ interrupts = <82>, <83>;
+ interrupt-names = "tx", "rx";
+ op-mode = <0>; /* MCASP_IIS_MODE */
+ tdm-slots = <2>;
+ dmas = <&main_udmap 0xc400>, <&main_udmap 0x4400>;
+ dma-names = "tx", "rx";
+ serial-dir = <
+ 0 0 0 0 /* 0: INACTIVE, 1: TX, 2: RX */
+ 0 0 0 0
+ 0 0 0 1
+ 2 0 0 0 >;
+ tx-num-evt = <1>;
+ rx-num-evt = <1>;
+ };
diff --git a/Documentation/devicetree/bindings/sound/fsl-asoc-card.txt b/Documentation/devicetree/bindings/sound/fsl-asoc-card.txt
index 23d83fa7609f..8b4f4015cfe4 100644
--- a/Documentation/devicetree/bindings/sound/fsl-asoc-card.txt
+++ b/Documentation/devicetree/bindings/sound/fsl-asoc-card.txt
@@ -40,6 +40,8 @@ The compatible list for this generic sound card currently:
"fsl,imx-audio-tlv320aic32x4"
+ "fsl,imx-audio-tlv320aic31xx"
+
"fsl,imx-audio-si476x"
"fsl,imx-audio-wm8958"
@@ -82,6 +84,7 @@ Optional properties:
- dai-format : audio format, for details see simple-card.yaml.
- frame-inversion : dai-link uses frame clock inversion, for details see simple-card.yaml.
- bitclock-inversion : dai-link uses bit clock inversion, for details see simple-card.yaml.
+ - mclk-id : main clock id, specific for each card configuration.
Optional unless SSI is selected as a CPU DAI:
diff --git a/Documentation/devicetree/bindings/sound/google,cros-ec-codec.yaml b/Documentation/devicetree/bindings/sound/google,cros-ec-codec.yaml
index 77adbebed824..c3e9f3485449 100644
--- a/Documentation/devicetree/bindings/sound/google,cros-ec-codec.yaml
+++ b/Documentation/devicetree/bindings/sound/google,cros-ec-codec.yaml
@@ -8,6 +8,7 @@ title: Audio codec controlled by ChromeOS EC
maintainers:
- Cheng-Yi Chiang <cychiang@chromium.org>
+ - Tzung-Bi Shih <tzungbi@google.com>
description: |
Google's ChromeOS EC codec is a digital mic codec provided by the
diff --git a/Documentation/devicetree/bindings/sound/google,sc7280-herobrine.yaml b/Documentation/devicetree/bindings/sound/google,sc7280-herobrine.yaml
new file mode 100644
index 000000000000..869b40363af8
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/google,sc7280-herobrine.yaml
@@ -0,0 +1,180 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/sound/google,sc7280-herobrine.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Google SC7280-Herobrine ASoC sound card driver
+
+maintainers:
+ - Srinivasa Rao Mandadapu <srivasam@codeaurora.org>
+ - Judy Hsiao <judyhsiao@chromium.org>
+
+description:
+ This binding describes the SC7280 sound card which uses LPASS for audio.
+
+properties:
+ compatible:
+ enum:
+ - google,sc7280-herobrine
+
+ audio-routing:
+ $ref: /schemas/types.yaml#/definitions/non-unique-string-array
+ description:
+ A list of the connections between audio components. Each entry is a
+ pair of strings, the first being the connection's sink, the second
+ being the connection's source.
+
+ model:
+ $ref: /schemas/types.yaml#/definitions/string
+ description: User specified audio sound card name
+
+ "#address-cells":
+ const: 1
+
+ "#size-cells":
+ const: 0
+
+patternProperties:
+ "^dai-link@[0-9a-f]$":
+ description:
+ Each subnode represents a dai link. Subnodes of each dai links would be
+ cpu/codec dais.
+
+ type: object
+
+ properties:
+ link-name:
+ description: Indicates dai-link name and PCM stream name.
+ $ref: /schemas/types.yaml#/definitions/string
+ maxItems: 1
+
+ reg:
+ maxItems: 1
+ description: dai link address.
+
+ cpu:
+ description: Holds subnode which indicates cpu dai.
+ type: object
+ properties:
+ sound-dai: true
+
+ required:
+ - sound-dai
+
+ additionalProperties: false
+
+ codec:
+ description: Holds subnode which indicates codec dai.
+ type: object
+ properties:
+ sound-dai: true
+
+ required:
+ - sound-dai
+
+ additionalProperties: false
+
+ required:
+ - link-name
+ - cpu
+ - codec
+ - reg
+
+ additionalProperties: false
+
+required:
+ - compatible
+ - model
+ - "#address-cells"
+ - "#size-cells"
+
+additionalProperties: false
+
+examples:
+
+ - |
+ #include <dt-bindings/sound/qcom,lpass.h>
+ sound {
+ compatible = "google,sc7280-herobrine";
+ model = "sc7280-wcd938x-max98360a-4dmic";
+
+ audio-routing =
+ "IN1_HPHL", "HPHL_OUT",
+ "IN2_HPHR", "HPHR_OUT",
+ "AMIC1", "MIC BIAS1",
+ "AMIC2", "MIC BIAS2",
+ "VA DMIC0", "MIC BIAS3",
+ "VA DMIC1", "MIC BIAS3",
+ "VA DMIC2", "MIC BIAS4",
+ "VA DMIC3", "MIC BIAS4",
+ "TX SWR_ADC0", "ADC1_OUTPUT",
+ "TX SWR_ADC1", "ADC2_OUTPUT",
+ "TX SWR_ADC2", "ADC3_OUTPUT",
+ "TX SWR_DMIC0", "DMIC1_OUTPUT",
+ "TX SWR_DMIC1", "DMIC2_OUTPUT",
+ "TX SWR_DMIC2", "DMIC3_OUTPUT",
+ "TX SWR_DMIC3", "DMIC4_OUTPUT";
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ dai-link@0 {
+ link-name = "WCD Playback";
+ reg = <LPASS_CDC_DMA_RX0>;
+ cpu {
+ sound-dai = <&lpass_cpu LPASS_CDC_DMA_RX0>;
+ };
+
+ codec {
+ sound-dai = <&wcd938x 0>, <&swr0 0>, <&rxmacro 0>;
+ };
+ };
+ dai-link@1 {
+ link-name = "WCD Capture";
+ reg = <LPASS_CDC_DMA_TX3>;
+ cpu {
+ sound-dai = <&lpass_cpu LPASS_CDC_DMA_TX3>;
+ };
+
+ codec {
+ sound-dai = <&wcd938x 1>, <&swr1 0>, <&txmacro 0>;
+ };
+ };
+
+ dai-link@2 {
+ link-name = "MI2S Playback";
+ reg = <MI2S_SECONDARY>;
+ cpu {
+ sound-dai = <&lpass_cpu MI2S_SECONDARY>;
+ };
+
+ codec {
+ sound-dai = <&max98360a>;
+ };
+ };
+
+ dai-link@3 {
+ link-name = "DMIC Capture";
+ reg = <LPASS_CDC_DMA_VA_TX0>;
+ cpu {
+ sound-dai = <&lpass_cpu LPASS_CDC_DMA_VA_TX0>;
+ };
+
+ codec {
+ sound-dai = <&vamacro 0>;
+ };
+ };
+
+ dai-link@5 {
+ link-name = "DP Playback";
+ reg = <LPASS_DP_RX>;
+ cpu {
+ sound-dai = <&lpass_cpu LPASS_DP_RX>;
+ };
+
+ codec {
+ sound-dai = <&mdss_dp>;
+ };
+ };
+ };
diff --git a/Documentation/devicetree/bindings/sound/microchip,pdmc.yaml b/Documentation/devicetree/bindings/sound/microchip,pdmc.yaml
new file mode 100644
index 000000000000..04414eb4ada9
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/microchip,pdmc.yaml
@@ -0,0 +1,100 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/sound/microchip,pdmc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Microchip Pulse Density Microphone Controller
+
+maintainers:
+ - Codrin Ciubotariu <codrin.ciubotariu@microchip.com>
+
+description:
+ The Microchip Pulse Density Microphone Controller (PDMC) interfaces up to 4
+ digital microphones having Pulse Density Modulated (PDM) outputs.
+
+properties:
+ compatible:
+ const: microchip,sama7g5-pdmc
+
+ reg:
+ maxItems: 1
+
+ "#sound-dai-cells":
+ const: 0
+
+ interrupts:
+ maxItems: 1
+
+ clocks:
+ items:
+ - description: Peripheral Bus Clock
+ - description: Generic Clock
+
+ clock-names:
+ items:
+ - const: pclk
+ - const: gclk
+
+ dmas:
+ description: RX DMA Channel
+ maxItems: 1
+
+ dma-names:
+ const: rx
+
+ microchip,mic-pos:
+ description: |
+ Position of PDM microphones on the DS line and the sampling edge (rising
+ or falling) of the CLK line. A microphone is represented as a pair of DS
+ line and the sampling edge. The first microphone is mapped to channel 0,
+ the second to channel 1, etc.
+ $ref: /schemas/types.yaml#/definitions/uint32-matrix
+ items:
+ items:
+ - description: value for DS line
+ - description: value for sampling edge
+ anyOf:
+ - enum:
+ - [0, 0]
+ - [0, 1]
+ - [1, 0]
+ - [1, 1]
+ minItems: 1
+ maxItems: 4
+ uniqueItems: true
+
+required:
+ - compatible
+ - reg
+ - "#sound-dai-cells"
+ - interrupts
+ - clocks
+ - clock-names
+ - dmas
+ - dma-names
+ - microchip,mic-pos
+
+additionalProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/clock/at91.h>
+ #include <dt-bindings/dma/at91.h>
+ #include <dt-bindings/interrupt-controller/arm-gic.h>
+ #include <dt-bindings/sound/microchip,pdmc.h>
+
+ pdmc: sound@e1608000 {
+ compatible = "microchip,sama7g5-pdmc";
+ reg = <0xe1608000 0x4000>;
+ #sound-dai-cells = <0>;
+ interrupts = <GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>;
+ dmas = <&dma0 AT91_XDMAC_DT_PERID(37)>;
+ dma-names = "rx";
+ clocks = <&pmc PMC_TYPE_PERIPHERAL 68>, <&pmc PMC_TYPE_GCK 68>;
+ clock-names = "pclk", "gclk";
+ microchip,mic-pos = <MCHP_PDMC_DS0 MCHP_PDMC_CLK_POSITIVE>,
+ <MCHP_PDMC_DS0 MCHP_PDMC_CLK_NEGATIVE>,
+ <MCHP_PDMC_DS1 MCHP_PDMC_CLK_POSITIVE>,
+ <MCHP_PDMC_DS1 MCHP_PDMC_CLK_NEGATIVE>;
+ };
diff --git a/Documentation/devicetree/bindings/sound/mt8195-afe-pcm.yaml b/Documentation/devicetree/bindings/sound/mt8195-afe-pcm.yaml
index 6d0975b33d15..4452a4070eff 100644
--- a/Documentation/devicetree/bindings/sound/mt8195-afe-pcm.yaml
+++ b/Documentation/devicetree/bindings/sound/mt8195-afe-pcm.yaml
@@ -19,6 +19,12 @@ properties:
interrupts:
maxItems: 1
+ resets:
+ maxItems: 1
+
+ reset-names:
+ const: audiosys
+
memory-region:
maxItems: 1
description: |
@@ -127,6 +133,8 @@ required:
- compatible
- reg
- interrupts
+ - resets
+ - reset-names
- mediatek,topckgen
- power-domains
- clocks
@@ -144,6 +152,8 @@ examples:
compatible = "mediatek,mt8195-audio";
reg = <0x10890000 0x10000>;
interrupts = <GIC_SPI 822 IRQ_TYPE_LEVEL_HIGH 0>;
+ resets = <&watchdog 14>;
+ reset-names = "audiosys";
mediatek,topckgen = <&topckgen>;
power-domains = <&spm 7>; //MT8195_POWER_DOMAIN_AUDIO
memory-region = <&snd_dma_mem_reserved>;
diff --git a/Documentation/devicetree/bindings/sound/nvidia,tegra186-dspk.yaml b/Documentation/devicetree/bindings/sound/nvidia,tegra186-dspk.yaml
index 0912d3e3fd8e..73b98b2f3543 100644
--- a/Documentation/devicetree/bindings/sound/nvidia,tegra186-dspk.yaml
+++ b/Documentation/devicetree/bindings/sound/nvidia,tegra186-dspk.yaml
@@ -28,7 +28,9 @@ properties:
oneOf:
- const: nvidia,tegra186-dspk
- items:
- - const: nvidia,tegra194-dspk
+ - enum:
+ - nvidia,tegra234-dspk
+ - nvidia,tegra194-dspk
- const: nvidia,tegra186-dspk
reg:
diff --git a/Documentation/devicetree/bindings/sound/nvidia,tegra210-admaif.yaml b/Documentation/devicetree/bindings/sound/nvidia,tegra210-admaif.yaml
index 19eaacc3f12a..372043edd98f 100644
--- a/Documentation/devicetree/bindings/sound/nvidia,tegra210-admaif.yaml
+++ b/Documentation/devicetree/bindings/sound/nvidia,tegra210-admaif.yaml
@@ -27,7 +27,9 @@ properties:
- nvidia,tegra210-admaif
- nvidia,tegra186-admaif
- items:
- - const: nvidia,tegra194-admaif
+ - enum:
+ - nvidia,tegra234-admaif
+ - nvidia,tegra194-admaif
- const: nvidia,tegra186-admaif
reg:
diff --git a/Documentation/devicetree/bindings/sound/nvidia,tegra210-adx.yaml b/Documentation/devicetree/bindings/sound/nvidia,tegra210-adx.yaml
index c4ba12ea3611..8d8dc7fb3f0c 100644
--- a/Documentation/devicetree/bindings/sound/nvidia,tegra210-adx.yaml
+++ b/Documentation/devicetree/bindings/sound/nvidia,tegra210-adx.yaml
@@ -30,6 +30,7 @@ properties:
- const: nvidia,tegra210-adx
- items:
- enum:
+ - nvidia,tegra234-adx
- nvidia,tegra194-adx
- nvidia,tegra186-adx
- const: nvidia,tegra210-adx
diff --git a/Documentation/devicetree/bindings/sound/nvidia,tegra210-ahub.yaml b/Documentation/devicetree/bindings/sound/nvidia,tegra210-ahub.yaml
index df81d208184a..4727f1e42c53 100644
--- a/Documentation/devicetree/bindings/sound/nvidia,tegra210-ahub.yaml
+++ b/Documentation/devicetree/bindings/sound/nvidia,tegra210-ahub.yaml
@@ -26,6 +26,7 @@ properties:
- enum:
- nvidia,tegra210-ahub
- nvidia,tegra186-ahub
+ - nvidia,tegra234-ahub
- items:
- const: nvidia,tegra194-ahub
- const: nvidia,tegra186-ahub
diff --git a/Documentation/devicetree/bindings/sound/nvidia,tegra210-amx.yaml b/Documentation/devicetree/bindings/sound/nvidia,tegra210-amx.yaml
index bb2111afe5a8..f9e4fc6e0c47 100644
--- a/Documentation/devicetree/bindings/sound/nvidia,tegra210-amx.yaml
+++ b/Documentation/devicetree/bindings/sound/nvidia,tegra210-amx.yaml
@@ -31,6 +31,9 @@ properties:
- const: nvidia,tegra186-amx
- const: nvidia,tegra210-amx
- const: nvidia,tegra194-amx
+ - items:
+ - const: nvidia,tegra234-amx
+ - const: nvidia,tegra194-amx
reg:
maxItems: 1
diff --git a/Documentation/devicetree/bindings/sound/nvidia,tegra210-dmic.yaml b/Documentation/devicetree/bindings/sound/nvidia,tegra210-dmic.yaml
index 62db982bb01d..bcb496d3ace5 100644
--- a/Documentation/devicetree/bindings/sound/nvidia,tegra210-dmic.yaml
+++ b/Documentation/devicetree/bindings/sound/nvidia,tegra210-dmic.yaml
@@ -28,6 +28,7 @@ properties:
- const: nvidia,tegra210-dmic
- items:
- enum:
+ - nvidia,tegra234-dmic
- nvidia,tegra194-dmic
- nvidia,tegra186-dmic
- const: nvidia,tegra210-dmic
diff --git a/Documentation/devicetree/bindings/sound/nvidia,tegra210-i2s.yaml b/Documentation/devicetree/bindings/sound/nvidia,tegra210-i2s.yaml
index f954be636697..6188f561f878 100644
--- a/Documentation/devicetree/bindings/sound/nvidia,tegra210-i2s.yaml
+++ b/Documentation/devicetree/bindings/sound/nvidia,tegra210-i2s.yaml
@@ -28,6 +28,7 @@ properties:
- const: nvidia,tegra210-i2s
- items:
- enum:
+ - nvidia,tegra234-i2s
- nvidia,tegra194-i2s
- nvidia,tegra186-i2s
- const: nvidia,tegra210-i2s
diff --git a/Documentation/devicetree/bindings/sound/nvidia,tegra210-mixer.yaml b/Documentation/devicetree/bindings/sound/nvidia,tegra210-mixer.yaml
index 428f3c851941..ee1e1d2da79a 100644
--- a/Documentation/devicetree/bindings/sound/nvidia,tegra210-mixer.yaml
+++ b/Documentation/devicetree/bindings/sound/nvidia,tegra210-mixer.yaml
@@ -28,6 +28,7 @@ properties:
- const: nvidia,tegra210-amixer
- items:
- enum:
+ - nvidia,tegra234-amixer
- nvidia,tegra194-amixer
- nvidia,tegra186-amixer
- const: nvidia,tegra210-amixer
diff --git a/Documentation/devicetree/bindings/sound/nvidia,tegra210-mvc.yaml b/Documentation/devicetree/bindings/sound/nvidia,tegra210-mvc.yaml
index e2f5a8591d8f..c9888c553e78 100644
--- a/Documentation/devicetree/bindings/sound/nvidia,tegra210-mvc.yaml
+++ b/Documentation/devicetree/bindings/sound/nvidia,tegra210-mvc.yaml
@@ -31,6 +31,7 @@ properties:
- const: nvidia,tegra210-mvc
- items:
- enum:
+ - nvidia,tegra234-mvc
- nvidia,tegra194-mvc
- nvidia,tegra186-mvc
- const: nvidia,tegra210-mvc
diff --git a/Documentation/devicetree/bindings/sound/nvidia,tegra210-sfc.yaml b/Documentation/devicetree/bindings/sound/nvidia,tegra210-sfc.yaml
index 41ad65173548..8579306fc56f 100644
--- a/Documentation/devicetree/bindings/sound/nvidia,tegra210-sfc.yaml
+++ b/Documentation/devicetree/bindings/sound/nvidia,tegra210-sfc.yaml
@@ -28,6 +28,7 @@ properties:
- const: nvidia,tegra210-sfc
- items:
- enum:
+ - nvidia,tegra234-sfc
- nvidia,tegra194-sfc
- nvidia,tegra186-sfc
- const: nvidia,tegra210-sfc
diff --git a/Documentation/devicetree/bindings/sound/nvidia,tegra30-hda.yaml b/Documentation/devicetree/bindings/sound/nvidia,tegra30-hda.yaml
index 2c913aa44fee..12c31b4b99e1 100644
--- a/Documentation/devicetree/bindings/sound/nvidia,tegra30-hda.yaml
+++ b/Documentation/devicetree/bindings/sound/nvidia,tegra30-hda.yaml
@@ -23,6 +23,7 @@ properties:
- const: nvidia,tegra30-hda
- items:
- enum:
+ - nvidia,tegra234-hda
- nvidia,tegra194-hda
- nvidia,tegra186-hda
- nvidia,tegra210-hda
@@ -41,9 +42,11 @@ properties:
maxItems: 1
clocks:
+ minItems: 2
maxItems: 3
clock-names:
+ minItems: 2
items:
- const: hda
- const: hda2hdmi
diff --git a/Documentation/devicetree/bindings/sound/qcom,lpass-cpu.yaml b/Documentation/devicetree/bindings/sound/qcom,lpass-cpu.yaml
index 1e23c0e20bc1..2c81efb5fa37 100644
--- a/Documentation/devicetree/bindings/sound/qcom,lpass-cpu.yaml
+++ b/Documentation/devicetree/bindings/sound/qcom,lpass-cpu.yaml
@@ -22,35 +22,41 @@ properties:
- qcom,lpass-cpu
- qcom,apq8016-lpass-cpu
- qcom,sc7180-lpass-cpu
+ - qcom,sc7280-lpass-cpu
reg:
- maxItems: 2
+ minItems: 2
+ maxItems: 6
description: LPAIF core registers
reg-names:
- maxItems: 2
+ minItems: 2
+ maxItems: 6
clocks:
minItems: 3
- maxItems: 6
+ maxItems: 7
clock-names:
minItems: 3
- maxItems: 6
+ maxItems: 7
interrupts:
- maxItems: 2
+ minItems: 2
+ maxItems: 4
description: LPAIF DMA buffer interrupt
interrupt-names:
- maxItems: 2
+ minItems: 2
+ maxItems: 4
qcom,adsp:
$ref: /schemas/types.yaml#/definitions/phandle
description: Phandle for the audio DSP node
iommus:
- maxItems: 2
+ minItems: 2
+ maxItems: 3
description: Phandle to apps_smmu node with sid mask
power-domains:
@@ -69,7 +75,7 @@ patternProperties:
"^dai-link@[0-9a-f]$":
type: object
description: |
- LPASS CPU dai node for each I2S device. Bindings of each node
+ LPASS CPU dai node for each I2S device or Soundwire device. Bindings of each node
depends on the specific driver providing the functionality and
properties.
properties:
@@ -174,6 +180,59 @@ allOf:
- iommus
- power-domains
+ - if:
+ properties:
+ compatible:
+ contains:
+ const: qcom,sc7280-lpass-cpu
+
+ then:
+ properties:
+ clock-names:
+ oneOf:
+ - items: #for I2S
+ - const: aon_cc_audio_hm_h
+ - const: core_cc_sysnoc_mport_core
+ - const: core_cc_ext_if1_ibit
+ - items: #for Soundwire
+ - const: aon_cc_audio_hm_h
+ - const: audio_cc_codec_mem0
+ - const: audio_cc_codec_mem1
+ - const: audio_cc_codec_mem2
+ - items: #for HDMI
+ - const: aon_cc_audio_hm_h
+
+ reg-names:
+ anyOf:
+ - items: #for I2S
+ - const: lpass-lpaif
+ - items: #for I2S and HDMI
+ - const: lpass-hdmiif
+ - const: lpass-lpaif
+ - items: #for I2S, soundwire and HDMI
+ - const: lpass-hdmiif
+ - const: lpass-lpaif
+ - const: lpass-rxtx-cdc-dma-lpm
+ - const: lpass-rxtx-lpaif
+ - const: lpass-va-lpaif
+ - const: lpass-va-cdc-dma-lpm
+ interrupt-names:
+ anyOf:
+ - items: #for I2S
+ - const: lpass-irq-lpaif
+ - items: #for I2S and HDMI
+ - const: lpass-irq-lpaif
+ - const: lpass-irq-hdmi
+ - items: #for I2S, soundwire and HDMI
+ - const: lpass-irq-lpaif
+ - const: lpass-irq-hdmi
+ - const: lpass-irq-vaif
+ - const: lpass-irq-rxtxif
+
+ required:
+ - iommus
+ - power-domains
+
examples:
- |
#include <dt-bindings/sound/sc7180-lpass.h>
diff --git a/Documentation/devicetree/bindings/sound/qcom,lpass-rx-macro.yaml b/Documentation/devicetree/bindings/sound/qcom,lpass-rx-macro.yaml
index bc762b39c68a..6127df5836c2 100644
--- a/Documentation/devicetree/bindings/sound/qcom,lpass-rx-macro.yaml
+++ b/Documentation/devicetree/bindings/sound/qcom,lpass-rx-macro.yaml
@@ -39,6 +39,14 @@ properties:
items:
- const: mclk
+ power-domains:
+ maxItems: 2
+
+ power-domain-names:
+ items:
+ - const: macro
+ - const: dcodec
+
required:
- compatible
- reg
diff --git a/Documentation/devicetree/bindings/sound/qcom,lpass-tx-macro.yaml b/Documentation/devicetree/bindings/sound/qcom,lpass-tx-macro.yaml
index 74f53864e7a7..3f0f99cb18ca 100644
--- a/Documentation/devicetree/bindings/sound/qcom,lpass-tx-macro.yaml
+++ b/Documentation/devicetree/bindings/sound/qcom,lpass-tx-macro.yaml
@@ -39,6 +39,14 @@ properties:
items:
- const: mclk
+ power-domains:
+ maxItems: 2
+
+ power-domain-names:
+ items:
+ - const: macro
+ - const: dcodec
+
qcom,dmic-sample-rate:
description: dmic sample rate
$ref: /schemas/types.yaml#/definitions/uint32
diff --git a/Documentation/devicetree/bindings/sound/qcom,lpass-va-macro.yaml b/Documentation/devicetree/bindings/sound/qcom,lpass-va-macro.yaml
index 99f2c3687fbd..9868a5ebe27e 100644
--- a/Documentation/devicetree/bindings/sound/qcom,lpass-va-macro.yaml
+++ b/Documentation/devicetree/bindings/sound/qcom,lpass-va-macro.yaml
@@ -37,6 +37,14 @@ properties:
items:
- const: fsgen
+ power-domains:
+ maxItems: 2
+
+ power-domain-names:
+ items:
+ - const: macro
+ - const: dcodec
+
qcom,dmic-sample-rate:
description: dmic sample rate
$ref: /schemas/types.yaml#/definitions/uint32
diff --git a/Documentation/devicetree/bindings/sound/qcom,wcd938x.yaml b/Documentation/devicetree/bindings/sound/qcom,wcd938x.yaml
index cb74ce40c2e6..7bf1a5fffcd2 100644
--- a/Documentation/devicetree/bindings/sound/qcom,wcd938x.yaml
+++ b/Documentation/devicetree/bindings/sound/qcom,wcd938x.yaml
@@ -23,6 +23,10 @@ properties:
description: GPIO spec for reset line to use
maxItems: 1
+ us-euro-gpios:
+ description: GPIO spec for swapping gnd and mic segments
+ maxItems: 1
+
vdd-buck-supply:
description: A reference to the 1.8V buck supply
diff --git a/Documentation/devicetree/bindings/sound/realtek,rt5682s.yaml b/Documentation/devicetree/bindings/sound/realtek,rt5682s.yaml
index d65c0ed5060c..ca5b8987b749 100644
--- a/Documentation/devicetree/bindings/sound/realtek,rt5682s.yaml
+++ b/Documentation/devicetree/bindings/sound/realtek,rt5682s.yaml
@@ -21,6 +21,7 @@ properties:
description: I2C address of the device.
interrupts:
+ maxItems: 1
description: The CODEC's interrupt output.
realtek,dmic1-data-pin:
@@ -94,7 +95,7 @@ required:
examples:
- |
- #include <dt-bindings/gpio/tegra-gpio.h>
+ #include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/interrupt-controller/irq.h>
i2c {
@@ -104,10 +105,9 @@ examples:
codec@1a {
compatible = "realtek,rt5682s";
reg = <0x1a>;
- interrupt-parent = <&gpio>;
- interrupts = <TEGRA_GPIO(U, 6) IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <6 IRQ_TYPE_LEVEL_HIGH>;
realtek,ldo1-en-gpios =
- <&gpio TEGRA_GPIO(R, 2) GPIO_ACTIVE_HIGH>;
+ <&gpio 2 GPIO_ACTIVE_HIGH>;
realtek,dmic1-data-pin = <1>;
realtek,dmic1-clk-pin = <1>;
realtek,jd-src = <1>;
diff --git a/Documentation/devicetree/bindings/sound/renesas,rsnd.yaml b/Documentation/devicetree/bindings/sound/renesas,rsnd.yaml
index c2930d65728e..e17c0245f77a 100644
--- a/Documentation/devicetree/bindings/sound/renesas,rsnd.yaml
+++ b/Documentation/devicetree/bindings/sound/renesas,rsnd.yaml
@@ -123,9 +123,7 @@ properties:
$ref: audio-graph-port.yaml#
unevaluatedProperties: false
-# use patternProperties to avoid naming "xxx,yyy" issue
-patternProperties:
- "^rcar_sound,dvc$":
+ rcar_sound,dvc:
description: DVC subnode.
type: object
patternProperties:
@@ -141,7 +139,7 @@ patternProperties:
- dma-names
additionalProperties: false
- "^rcar_sound,mix$":
+ rcar_sound,mix:
description: MIX subnode.
type: object
patternProperties:
@@ -150,7 +148,7 @@ patternProperties:
# no properties
additionalProperties: false
- "^rcar_sound,ctu$":
+ rcar_sound,ctu:
description: CTU subnode.
type: object
patternProperties:
@@ -159,7 +157,7 @@ patternProperties:
# no properties
additionalProperties: false
- "^rcar_sound,src$":
+ rcar_sound,src:
description: SRC subnode.
type: object
patternProperties:
@@ -182,7 +180,7 @@ patternProperties:
- dma-names
additionalProperties: false
- "^rcar_sound,ssiu$":
+ rcar_sound,ssiu:
description: SSIU subnode.
type: object
patternProperties:
@@ -202,7 +200,7 @@ patternProperties:
- dma-names
additionalProperties: false
- "^rcar_sound,ssi$":
+ rcar_sound,ssi:
description: SSI subnode.
type: object
patternProperties:
@@ -239,7 +237,7 @@ patternProperties:
additionalProperties: false
# For DAI base
- "^rcar_sound,dai$":
+ rcar_sound,dai:
description: DAI subnode.
type: object
patternProperties:
diff --git a/Documentation/devicetree/bindings/sound/renesas,rz-ssi.yaml b/Documentation/devicetree/bindings/sound/renesas,rz-ssi.yaml
index 414ff8035a4e..7e8d252f7bca 100644
--- a/Documentation/devicetree/bindings/sound/renesas,rz-ssi.yaml
+++ b/Documentation/devicetree/bindings/sound/renesas,rz-ssi.yaml
@@ -4,7 +4,7 @@
$id: http://devicetree.org/schemas/sound/renesas,rz-ssi.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
-title: Renesas RZ/G2L ASoC Sound Serial Interface (SSIF-2)
+title: Renesas RZ/{G2L,V2L} ASoC Sound Serial Interface (SSIF-2)
maintainers:
- Biju Das <biju.das.jz@bp.renesas.com>
@@ -14,6 +14,7 @@ properties:
items:
- enum:
- renesas,r9a07g044-ssi # RZ/G2{L,LC}
+ - renesas,r9a07g054-ssi # RZ/V2L
- const: renesas,rz-ssi
reg:
diff --git a/Documentation/devicetree/bindings/sound/samsung,aries-wm8994.yaml b/Documentation/devicetree/bindings/sound/samsung,aries-wm8994.yaml
index 5fff586dc802..afdacffc9a7a 100644
--- a/Documentation/devicetree/bindings/sound/samsung,aries-wm8994.yaml
+++ b/Documentation/devicetree/bindings/sound/samsung,aries-wm8994.yaml
@@ -31,6 +31,8 @@ properties:
description: |
phandles to the I2S controller and bluetooth codec,
in that order
+ required:
+ - sound-dai
codec:
type: object
@@ -38,6 +40,8 @@ properties:
sound-dai:
$ref: /schemas/types.yaml#/definitions/phandle-array
description: phandle to the WM8994 CODEC
+ required:
+ - sound-dai
samsung,audio-routing:
$ref: /schemas/types.yaml#/definitions/non-unique-string-array
diff --git a/Documentation/devicetree/bindings/sound/samsung,arndale.yaml b/Documentation/devicetree/bindings/sound/samsung,arndale.yaml
new file mode 100644
index 000000000000..cea2bf3544f0
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/samsung,arndale.yaml
@@ -0,0 +1,45 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/sound/samsung,arndale.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Insignal Arndale boards audio complex
+
+maintainers:
+ - Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>
+ - Sylwester Nawrocki <s.nawrocki@samsung.com>
+
+properties:
+ compatible:
+ enum:
+ - samsung,arndale-alc5631
+ - samsung,arndale-rt5631
+ - samsung,arndale-wm1811
+
+ samsung,audio-codec:
+ description: Phandle to the audio codec.
+ $ref: /schemas/types.yaml#/definitions/phandle
+
+ samsung,audio-cpu:
+ description: Phandle to the Samsung I2S controller.
+ $ref: /schemas/types.yaml#/definitions/phandle
+
+ samsung,model:
+ description: The user-visible name of this sound complex.
+ $ref: /schemas/types.yaml#/definitions/string
+
+required:
+ - compatible
+ - samsung,audio-codec
+ - samsung,audio-cpu
+
+additionalProperties: false
+
+examples:
+ - |
+ sound {
+ compatible = "samsung,arndale-rt5631";
+ samsung,audio-cpu = <&i2s0>;
+ samsung,audio-codec = <&rt5631>;
+ };
diff --git a/Documentation/devicetree/bindings/sound/samsung,smdk-wm8994.txt b/Documentation/devicetree/bindings/sound/samsung,smdk-wm8994.txt
deleted file mode 100644
index 4686646fb122..000000000000
--- a/Documentation/devicetree/bindings/sound/samsung,smdk-wm8994.txt
+++ /dev/null
@@ -1,14 +0,0 @@
-Samsung SMDK audio complex
-
-Required properties:
-- compatible : "samsung,smdk-wm8994"
-- samsung,i2s-controller: The phandle of the Samsung I2S0 controller
-- samsung,audio-codec: The phandle of the WM8994 audio codec
-Example:
-
-sound {
- compatible = "samsung,smdk-wm8994";
-
- samsung,i2s-controller = <&i2s0>;
- samsung,audio-codec = <&wm8994>;
-};
diff --git a/Documentation/devicetree/bindings/sound/samsung,smdk5250.yaml b/Documentation/devicetree/bindings/sound/samsung,smdk5250.yaml
new file mode 100644
index 000000000000..cb51af90435e
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/samsung,smdk5250.yaml
@@ -0,0 +1,38 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/sound/samsung,smdk5250.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Samsung SMDK5250 audio complex with WM8994 codec
+
+maintainers:
+ - Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>
+ - Sylwester Nawrocki <s.nawrocki@samsung.com>
+
+properties:
+ compatible:
+ const: samsung,smdk-wm8994
+
+ samsung,audio-codec:
+ description: Phandle to the audio codec.
+ $ref: /schemas/types.yaml#/definitions/phandle
+
+ samsung,i2s-controller:
+ description: Phandle to the Samsung I2S controller.
+ $ref: /schemas/types.yaml#/definitions/phandle
+
+required:
+ - compatible
+ - samsung,audio-codec
+ - samsung,i2s-controller
+
+additionalProperties: false
+
+examples:
+ - |
+ sound {
+ compatible = "samsung,smdk-wm8994";
+ samsung,i2s-controller = <&i2s0>;
+ samsung,audio-codec = <&wm8994>;
+ };
diff --git a/Documentation/devicetree/bindings/sound/samsung,snow.yaml b/Documentation/devicetree/bindings/sound/samsung,snow.yaml
new file mode 100644
index 000000000000..0c3b3302b842
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/samsung,snow.yaml
@@ -0,0 +1,74 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/sound/samsung,snow.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Google Snow audio complex with MAX9809x codec
+
+maintainers:
+ - Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>
+ - Sylwester Nawrocki <s.nawrocki@samsung.com>
+
+properties:
+ compatible:
+ enum:
+ - google,snow-audio-max98090
+ - google,snow-audio-max98091
+ - google,snow-audio-max98095
+
+ codec:
+ type: object
+ properties:
+ sound-dai:
+ description: List of phandles to the CODEC and HDMI IP nodes.
+ items:
+ - description: Phandle to the MAX98090, MAX98091 or MAX98095 CODEC.
+ - description: Phandle to the HDMI IP block node.
+ required:
+ - sound-dai
+
+ cpu:
+ type: object
+ properties:
+ sound-dai:
+ description: Phandle to the Samsung I2S controller.
+ maxItems: 1
+ required:
+ - sound-dai
+
+ samsung,audio-codec:
+ description: Phandle to the audio codec.
+ $ref: /schemas/types.yaml#/definitions/phandle
+ deprecated: true
+
+ samsung,i2s-controller:
+ description: Phandle to the Samsung I2S controller.
+ $ref: /schemas/types.yaml#/definitions/phandle
+ deprecated: true
+
+ samsung,model:
+ description: The user-visible name of this sound complex.
+ $ref: /schemas/types.yaml#/definitions/string
+
+required:
+ - compatible
+ - codec
+ - cpu
+
+additionalProperties: false
+
+examples:
+ - |
+ sound {
+ compatible = "google,snow-audio-max98095";
+ samsung,model = "Snow-I2S-MAX98095";
+
+ cpu {
+ sound-dai = <&i2s0 0>;
+ };
+
+ codec {
+ sound-dai = <&max98095 0>, <&hdmi>;
+ };
+ };
diff --git a/Documentation/devicetree/bindings/sound/samsung,tm2-audio.txt b/Documentation/devicetree/bindings/sound/samsung,tm2-audio.txt
deleted file mode 100644
index f5ccc12ddc00..000000000000
--- a/Documentation/devicetree/bindings/sound/samsung,tm2-audio.txt
+++ /dev/null
@@ -1,42 +0,0 @@
-Samsung Exynos5433 TM2(E) audio complex with WM5110 codec
-
-Required properties:
-
- - compatible : "samsung,tm2-audio"
- - model : the user-visible name of this sound complex
- - audio-codec : the first entry should be phandle of the wm5110 audio
- codec node, as described in ../mfd/arizona.txt;
- the second entry should be phandle of the HDMI
- transmitter node
- - i2s-controller : the list of phandle and argument tuples pointing to
- I2S controllers, the first entry should be I2S0 and
- the second one I2S1
- - audio-amplifier : the phandle of the MAX98504 amplifier
- - samsung,audio-routing : a list of the connections between audio components;
- each entry is a pair of strings, the first being the
- connection's sink, the second being the connection's
- source; valid names for sources and sinks are the
- WM5110's and MAX98504's pins and the jacks on the
- board: HP, SPK, Main Mic, Sub Mic, Third Mic,
- Headset Mic
- - mic-bias-gpios : GPIO pin that enables the Main Mic bias regulator
-
-
-Example:
-
-sound {
- compatible = "samsung,tm2-audio";
- audio-codec = <&wm5110>, <&hdmi>;
- i2s-controller = <&i2s0 0>, <&i2s1 0>;
- audio-amplifier = <&max98504>;
- mic-bias-gpios = <&gpr3 2 0>;
- model = "wm5110";
- samsung,audio-routing =
- "HP", "HPOUT1L",
- "HP", "HPOUT1R",
- "SPK", "SPKOUT",
- "SPKOUT", "HPOUT2L",
- "SPKOUT", "HPOUT2R",
- "Main Mic", "MICBIAS2",
- "IN1R", "Main Mic";
-};
diff --git a/Documentation/devicetree/bindings/sound/samsung,tm2.yaml b/Documentation/devicetree/bindings/sound/samsung,tm2.yaml
new file mode 100644
index 000000000000..74712d6f3ef4
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/samsung,tm2.yaml
@@ -0,0 +1,80 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/sound/samsung,tm2.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Samsung Exynos5433 TM2(E) audio complex with WM5110 codec
+
+maintainers:
+ - Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>
+ - Sylwester Nawrocki <s.nawrocki@samsung.com>
+
+properties:
+ compatible:
+ const: samsung,tm2-audio
+
+ audio-amplifier:
+ description: Phandle to the MAX98504 amplifier.
+ $ref: /schemas/types.yaml#/definitions/phandle
+
+ audio-codec:
+ description: Phandles to the codecs.
+ $ref: /schemas/types.yaml#/definitions/phandle-array
+ items:
+ - description: Phandle to the WM5110 audio codec.
+ - description: Phandle to the HDMI transmitter node.
+
+ samsung,audio-routing:
+ description: |
+ List of the connections between audio components; each entry is
+ a pair of strings, the first being the connection's sink, the second
+ being the connection's source; valid names for sources and sinks are the
+ WM5110's and MAX98504's pins and the jacks on the board: HP, SPK, Main
+ Mic, Sub Mic, Third Mic, Headset Mic.
+ $ref: /schemas/types.yaml#/definitions/non-unique-string-array
+
+ i2s-controller:
+ description: Phandles to the I2S controllers.
+ $ref: /schemas/types.yaml#/definitions/phandle-array
+ items:
+ - description: Phandle to I2S0.
+ - description: Phandle to I2S1.
+
+ mic-bias-gpios:
+ description: GPIO pin that enables the Main Mic bias regulator.
+
+ model:
+ description: The user-visible name of this sound complex.
+ $ref: /schemas/types.yaml#/definitions/string
+
+required:
+ - compatible
+ - audio-amplifier
+ - audio-codec
+ - samsung,audio-routing
+ - i2s-controller
+ - mic-bias-gpios
+ - model
+
+additionalProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/gpio/gpio.h>
+
+ sound {
+ compatible = "samsung,tm2-audio";
+ audio-codec = <&wm5110>, <&hdmi>;
+ i2s-controller = <&i2s0 0>, <&i2s1 0>;
+ audio-amplifier = <&max98504>;
+ mic-bias-gpios = <&gpr3 2 GPIO_ACTIVE_HIGH>;
+ model = "wm5110";
+ samsung,audio-routing = "HP", "HPOUT1L",
+ "HP", "HPOUT1R",
+ "SPK", "SPKOUT",
+ "SPKOUT", "HPOUT2L",
+ "SPKOUT", "HPOUT2R",
+ "RCV", "HPOUT3L",
+ "RCV", "HPOUT3R";
+ };
diff --git a/Documentation/devicetree/bindings/sound/simple-card.yaml b/Documentation/devicetree/bindings/sound/simple-card.yaml
index 45fd9fd9eb54..b261d49b9ddb 100644
--- a/Documentation/devicetree/bindings/sound/simple-card.yaml
+++ b/Documentation/devicetree/bindings/sound/simple-card.yaml
@@ -48,6 +48,15 @@ definitions:
It is useful for some aCPUs with fixed clocks.
$ref: /schemas/types.yaml#/definitions/flag
+ system-clock-fixed:
+ description: |
+ Specifies that the clock frequency should not be modified.
+ Implied when system-clock-frequency is specified, but can be used when
+ a clock is mapped to the device whose frequency cannot or should not be
+ changed. When mclk-fs is also specified, this restricts the device to a
+ single fixed sampling rate.
+ $ref: /schemas/types.yaml#/definitions/flag
+
mclk-fs:
description: |
Multiplication factor between stream rate and codec mclk.
@@ -134,6 +143,8 @@ definitions:
$ref: "#/definitions/system-clock-frequency"
system-clock-direction-out:
$ref: "#/definitions/system-clock-direction-out"
+ system-clock-fixed:
+ $ref: "#/definitions/system-clock-fixed"
required:
- sound-dai
@@ -156,45 +167,45 @@ properties:
description: User specified audio sound card name.
$ref: /schemas/types.yaml#/definitions/string
-# use patternProperties to avoid naming "xxx,yyy" issue
-patternProperties:
- "^simple-audio-card,widgets$":
+ simple-audio-card,widgets:
$ref: "#/definitions/widgets"
- "^simple-audio-card,routing$":
+ simple-audio-card,routing:
$ref: "#/definitions/routing"
- "^simple-audio-card,cpu(@[0-9a-f]+)?":
- $ref: "#/definitions/dai"
- "^simple-audio-card,codec(@[0-9a-f]+)?":
- $ref: "#/definitions/dai"
# common properties
- "^simple-audio-card,frame-master$":
+ simple-audio-card,frame-master:
$ref: "#/definitions/frame-master"
- "^simple-audio-card,bitclock-master$":
+ simple-audio-card,bitclock-master:
$ref: "#/definitions/bitclock-master"
- "^simple-audio-card,frame-inversion$":
+ simple-audio-card,frame-inversion:
$ref: "#/definitions/frame-inversion"
- "^simple-audio-card,bitclock-inversion$":
+ simple-audio-card,bitclock-inversion:
$ref: "#/definitions/bitclock-inversion"
- "^simple-audio-card,format$":
+ simple-audio-card,format:
$ref: "#/definitions/format"
- "^simple-audio-card,mclk-fs$":
+ simple-audio-card,mclk-fs:
$ref: "#/definitions/mclk-fs"
- "^simple-audio-card,aux-devs$":
+ simple-audio-card,aux-devs:
$ref: "#/definitions/aux-devs"
- "^simple-audio-card,convert-rate$":
+ simple-audio-card,convert-rate:
$ref: "#/definitions/convert-rate"
- "^simple-audio-card,convert-channels$":
+ simple-audio-card,convert-channels:
$ref: "#/definitions/convert-channels"
- "^simple-audio-card,prefix$":
+ simple-audio-card,prefix:
$ref: "#/definitions/prefix"
- "^simple-audio-card,pin-switches$":
+ simple-audio-card,pin-switches:
$ref: "#/definitions/pin-switches"
- "^simple-audio-card,hp-det-gpio$":
+ simple-audio-card,hp-det-gpio:
maxItems: 1
- "^simple-audio-card,mic-det-gpio$":
+ simple-audio-card,mic-det-gpio:
maxItems: 1
+patternProperties:
+ "^simple-audio-card,cpu(@[0-9a-f]+)?$":
+ $ref: "#/definitions/dai"
+ "^simple-audio-card,codec(@[0-9a-f]+)?$":
+ $ref: "#/definitions/dai"
+
"^simple-audio-card,dai-link(@[0-9a-f]+)?$":
description: |
Container for dai-link level properties and the CPU and CODEC sub-nodes.
diff --git a/Documentation/devicetree/bindings/sound/snow.txt b/Documentation/devicetree/bindings/sound/snow.txt
deleted file mode 100644
index 80fd9a87bb3f..000000000000
--- a/Documentation/devicetree/bindings/sound/snow.txt
+++ /dev/null
@@ -1,31 +0,0 @@
-Audio Binding for Snow boards
-
-Required properties:
-- compatible : Can be one of the following,
- "google,snow-audio-max98090" or
- "google,snow-audio-max98091" or
- "google,snow-audio-max98095"
-- samsung,i2s-controller (deprecated): The phandle of the Samsung I2S controller
-- samsung,audio-codec (deprecated): The phandle of the audio codec
-
-Required sub-nodes:
-
- - 'cpu' subnode with a 'sound-dai' property containing the phandle of the I2S
- controller
- - 'codec' subnode with a 'sound-dai' property containing list of phandles
- to the CODEC nodes, first entry must be the phandle of the MAX98090,
- MAX98091 or MAX98095 CODEC (exact device type is indicated by the compatible
- string) and the second entry must be the phandle of the HDMI IP block node
-
-Optional:
-- samsung,model: The name of the sound-card
-
-Example:
-
-sound {
- compatible = "google,snow-audio-max98095";
-
- samsung,model = "Snow-I2S-MAX98095";
- samsung,i2s-controller = <&i2s0>;
- samsung,audio-codec = <&max98095>;
-};
diff --git a/Documentation/devicetree/bindings/sound/tas5805m.yaml b/Documentation/devicetree/bindings/sound/tas5805m.yaml
new file mode 100644
index 000000000000..3aade02d8a96
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/tas5805m.yaml
@@ -0,0 +1,56 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/sound/tas5805m.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: TAS5805M audio amplifier
+
+maintainers:
+ - Daniel Beer <daniel.beer@igorinstitute.com>
+
+description: |
+ The TAS5805M is a class D audio amplifier with a built-in DSP.
+
+properties:
+ compatible:
+ enum:
+ - ti,tas5805m
+
+ reg:
+ maxItems: 1
+ description: |
+ I2C address of the amplifier. See the datasheet for possible values.
+
+ pvdd-supply:
+ description: |
+ Regulator for audio power supply (PVDD in the datasheet).
+
+ pdn-gpios:
+ description: |
+ Power-down control GPIO (PDN pin in the datasheet).
+
+ ti,dsp-config-name:
+ description: |
+ The name of the DSP configuration that should be loaded for this
+ instance. Configuration blobs are sequences of register writes
+ generated from TI's PPC3 tool.
+ $ref: /schemas/types.yaml#/definitions/string
+
+examples:
+ - |
+ i2c0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ tas5805m: tas5805m@2c {
+ reg = <0x2c>;
+ compatible = "ti,tas5805m";
+
+ pvdd-supply = <&audiopwr>;
+ pdn-gpios = <&tlmm 160 0>;
+
+ ti,dsp-config-name = "mono_pbtl_48khz";
+ };
+ };
+
+additionalProperties: true
diff --git a/Documentation/devicetree/bindings/sound/tlv320aic31xx.txt b/Documentation/devicetree/bindings/sound/tlv320aic31xx.txt
index e372303697dc..bbad98d5b986 100644
--- a/Documentation/devicetree/bindings/sound/tlv320aic31xx.txt
+++ b/Documentation/devicetree/bindings/sound/tlv320aic31xx.txt
@@ -58,7 +58,7 @@ The pins can be used in referring sound node's audio-routing property.
Example:
#include <dt-bindings/gpio/gpio.h>
-#include <dt-bindings/sound/tlv320aic31xx-micbias.h>
+#include <dt-bindings/sound/tlv320aic31xx.h>
tlv320aic31xx: tlv320aic31xx@18 {
compatible = "ti,tlv320aic311x";
diff --git a/Documentation/devicetree/bindings/spi/mediatek,spi-mt65xx.yaml b/Documentation/devicetree/bindings/spi/mediatek,spi-mt65xx.yaml
new file mode 100644
index 000000000000..818130b11bb9
--- /dev/null
+++ b/Documentation/devicetree/bindings/spi/mediatek,spi-mt65xx.yaml
@@ -0,0 +1,107 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/spi/mediatek,spi-mt65xx.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: SPI Bus controller for MediaTek ARM SoCs
+
+maintainers:
+ - Leilk Liu <leilk.liu@mediatek.com>
+
+allOf:
+ - $ref: "/schemas/spi/spi-controller.yaml#"
+
+properties:
+ compatible:
+ oneOf:
+ - items:
+ - enum:
+ - mediatek,mt7629-spi
+ - const: mediatek,mt7622-spi
+ - items:
+ - enum:
+ - mediatek,mt8516-spi
+ - const: mediatek,mt2712-spi
+ - items:
+ - enum:
+ - mediatek,mt6779-spi
+ - mediatek,mt8186-spi
+ - mediatek,mt8192-spi
+ - mediatek,mt8195-spi
+ - const: mediatek,mt6765-spi
+ - items:
+ - enum:
+ - mediatek,mt7986-spi-ipm
+ - const: mediatek,spi-ipm
+ - items:
+ - enum:
+ - mediatek,mt2701-spi
+ - mediatek,mt2712-spi
+ - mediatek,mt6589-spi
+ - mediatek,mt6765-spi
+ - mediatek,mt6893-spi
+ - mediatek,mt7622-spi
+ - mediatek,mt8135-spi
+ - mediatek,mt8173-spi
+ - mediatek,mt8183-spi
+
+ reg:
+ maxItems: 1
+
+ interrupts:
+ maxItems: 1
+
+ clocks:
+ items:
+ - description: clock used for the parent clock
+ - description: clock used for the muxes clock
+ - description: clock used for the clock gate
+
+ clock-names:
+ items:
+ - const: parent-clk
+ - const: sel-clk
+ - const: spi-clk
+
+ mediatek,pad-select:
+ $ref: /schemas/types.yaml#/definitions/uint32-array
+ minItems: 1
+ maxItems: 4
+ items:
+ enum: [0, 1, 2, 3]
+ description:
+ specify which pins group(ck/mi/mo/cs) spi controller used.
+ This is an array.
+
+required:
+ - compatible
+ - reg
+ - interrupts
+ - clocks
+ - clock-names
+ - '#address-cells'
+ - '#size-cells'
+
+unevaluatedProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/clock/mt8173-clk.h>
+ #include <dt-bindings/gpio/gpio.h>
+ #include <dt-bindings/interrupt-controller/arm-gic.h>
+ #include <dt-bindings/interrupt-controller/irq.h>
+
+ spi@1100a000 {
+ compatible = "mediatek,mt8173-spi";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x1100a000 0x1000>;
+ interrupts = <GIC_SPI 110 IRQ_TYPE_LEVEL_LOW>;
+ clocks = <&topckgen CLK_TOP_SYSPLL3_D2>,
+ <&topckgen CLK_TOP_SPI_SEL>,
+ <&pericfg CLK_PERI_SPI0>;
+ clock-names = "parent-clk", "sel-clk", "spi-clk";
+ cs-gpios = <&pio 105 GPIO_ACTIVE_LOW>, <&pio 72 GPIO_ACTIVE_LOW>;
+ mediatek,pad-select = <1>, <0>;
+ };
diff --git a/Documentation/devicetree/bindings/spi/mediatek,spi-mtk-nor.yaml b/Documentation/devicetree/bindings/spi/mediatek,spi-mtk-nor.yaml
index 4e4694e3d539..be3cc7faed53 100644
--- a/Documentation/devicetree/bindings/spi/mediatek,spi-mtk-nor.yaml
+++ b/Documentation/devicetree/bindings/spi/mediatek,spi-mtk-nor.yaml
@@ -30,6 +30,7 @@ properties:
- mediatek,mt7622-nor
- mediatek,mt7623-nor
- mediatek,mt7629-nor
+ - mediatek,mt8186-nor
- mediatek,mt8192-nor
- mediatek,mt8195-nor
- enum:
@@ -49,6 +50,8 @@ properties:
- description: clock used for controller
- description: clock used for nor dma bus. this depends on hardware
design, so this is optional.
+ - description: clock used for controller axi slave bus.
+ this depends on hardware design, so it is optional.
clock-names:
minItems: 2
@@ -56,6 +59,7 @@ properties:
- const: spi
- const: sf
- const: axi
+ - const: axi_s
required:
- compatible
diff --git a/Documentation/devicetree/bindings/spi/mediatek,spi-slave-mt27xx.yaml b/Documentation/devicetree/bindings/spi/mediatek,spi-slave-mt27xx.yaml
new file mode 100644
index 000000000000..7977799a8ee1
--- /dev/null
+++ b/Documentation/devicetree/bindings/spi/mediatek,spi-slave-mt27xx.yaml
@@ -0,0 +1,58 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/spi/mediatek,spi-slave-mt27xx.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: SPI Slave controller for MediaTek ARM SoCs
+
+maintainers:
+ - Leilk Liu <leilk.liu@mediatek.com>
+
+allOf:
+ - $ref: "/schemas/spi/spi-controller.yaml#"
+
+properties:
+ compatible:
+ enum:
+ - mediatek,mt2712-spi-slave
+ - mediatek,mt8195-spi-slave
+
+ reg:
+ maxItems: 1
+
+ interrupts:
+ maxItems: 1
+
+ clocks:
+ maxItems: 1
+
+ clock-names:
+ items:
+ - const: spi
+
+required:
+ - compatible
+ - reg
+ - interrupts
+ - clocks
+ - clock-names
+
+unevaluatedProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/clock/mt2712-clk.h>
+ #include <dt-bindings/gpio/gpio.h>
+ #include <dt-bindings/interrupt-controller/arm-gic.h>
+ #include <dt-bindings/interrupt-controller/irq.h>
+
+ spi@10013000 {
+ compatible = "mediatek,mt2712-spi-slave";
+ reg = <0x10013000 0x100>;
+ interrupts = <GIC_SPI 283 IRQ_TYPE_LEVEL_LOW>;
+ clocks = <&infracfg CLK_INFRA_AO_SPI1>;
+ clock-names = "spi";
+ assigned-clocks = <&topckgen CLK_TOP_SPISLV_SEL>;
+ assigned-clock-parents = <&topckgen CLK_TOP_UNIVPLL1_D2>;
+ };
diff --git a/Documentation/devicetree/bindings/spi/microchip,mpfs-spi.yaml b/Documentation/devicetree/bindings/spi/microchip,mpfs-spi.yaml
new file mode 100644
index 000000000000..ece261b8e963
--- /dev/null
+++ b/Documentation/devicetree/bindings/spi/microchip,mpfs-spi.yaml
@@ -0,0 +1,52 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/spi/microchip,mpfs-spi.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Microchip MPFS {Q,}SPI Controller Device Tree Bindings
+
+maintainers:
+ - Conor Dooley <conor.dooley@microchip.com>
+
+allOf:
+ - $ref: spi-controller.yaml#
+
+properties:
+ compatible:
+ enum:
+ - microchip,mpfs-spi
+ - microchip,mpfs-qspi
+
+ reg:
+ maxItems: 1
+
+ interrupts:
+ maxItems: 1
+
+ clock-names:
+ maxItems: 1
+
+ clocks:
+ maxItems: 1
+
+required:
+ - compatible
+ - reg
+ - interrupts
+ - clocks
+
+unevaluatedProperties: false
+
+examples:
+ - |
+ #include "dt-bindings/clock/microchip,mpfs-clock.h"
+ spi@20108000 {
+ compatible = "microchip,mpfs-spi";
+ reg = <0x20108000 0x1000>;
+ clocks = <&clkcfg CLK_SPI0>;
+ interrupt-parent = <&plic>;
+ interrupts = <54>;
+ spi-max-frequency = <25000000>;
+ };
+...
diff --git a/Documentation/devicetree/bindings/spi/nvidia,tegra210-quad.yaml b/Documentation/devicetree/bindings/spi/nvidia,tegra210-quad.yaml
index 35a8045b2c70..0296edd1de22 100644
--- a/Documentation/devicetree/bindings/spi/nvidia,tegra210-quad.yaml
+++ b/Documentation/devicetree/bindings/spi/nvidia,tegra210-quad.yaml
@@ -19,6 +19,7 @@ properties:
- nvidia,tegra210-qspi
- nvidia,tegra186-qspi
- nvidia,tegra194-qspi
+ - nvidia,tegra234-qspi
reg:
maxItems: 1
@@ -106,7 +107,7 @@ examples:
dma-names = "rx", "tx";
flash@0 {
- compatible = "spi-nor";
+ compatible = "jedec,spi-nor";
reg = <0>;
spi-max-frequency = <104000000>;
spi-tx-bus-width = <2>;
diff --git a/Documentation/devicetree/bindings/spi/renesas,rspi.yaml b/Documentation/devicetree/bindings/spi/renesas,rspi.yaml
index 76e6d9e52fc7..2c3c6bd6ec45 100644
--- a/Documentation/devicetree/bindings/spi/renesas,rspi.yaml
+++ b/Documentation/devicetree/bindings/spi/renesas,rspi.yaml
@@ -22,7 +22,8 @@ properties:
- renesas,rspi-r7s72100 # RZ/A1H
- renesas,rspi-r7s9210 # RZ/A2
- renesas,r9a07g044-rspi # RZ/G2{L,LC}
- - const: renesas,rspi-rz # RZ/A and RZ/G2{L,LC}
+ - renesas,r9a07g054-rspi # RZ/V2L
+ - const: renesas,rspi-rz
- items:
- enum:
@@ -124,6 +125,7 @@ allOf:
enum:
- renesas,qspi
- renesas,r9a07g044-rspi
+ - renesas,r9a07g054-rspi
then:
required:
- resets
diff --git a/Documentation/devicetree/bindings/spi/samsung,spi-peripheral-props.yaml b/Documentation/devicetree/bindings/spi/samsung,spi-peripheral-props.yaml
new file mode 100644
index 000000000000..f0db3fb3d688
--- /dev/null
+++ b/Documentation/devicetree/bindings/spi/samsung,spi-peripheral-props.yaml
@@ -0,0 +1,33 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/spi/samsung,spi-peripheral-props.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Peripheral-specific properties for Samsung S3C/S5P/Exynos SoC SPI controller
+
+maintainers:
+ - Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>
+
+description:
+ See spi-peripheral-props.yaml for more info.
+
+properties:
+ controller-data:
+ type: object
+ additionalProperties: false
+
+ properties:
+ samsung,spi-feedback-delay:
+ description: |
+ The sampling phase shift to be applied on the miso line (to account
+ for any lag in the miso line). Valid values:
+ - 0: No phase shift.
+ - 1: 90 degree phase shift sampling.
+ - 2: 180 degree phase shift sampling.
+ - 3: 270 degree phase shift sampling.
+ $ref: /schemas/types.yaml#/definitions/uint32
+ enum: [0, 1, 2, 3]
+ default: 0
+
+additionalProperties: true
diff --git a/Documentation/devicetree/bindings/spi/samsung,spi.yaml b/Documentation/devicetree/bindings/spi/samsung,spi.yaml
new file mode 100644
index 000000000000..bf9a76d931d2
--- /dev/null
+++ b/Documentation/devicetree/bindings/spi/samsung,spi.yaml
@@ -0,0 +1,188 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/spi/samsung,spi.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Samsung S3C/S5P/Exynos SoC SPI controller
+
+maintainers:
+ - Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>
+
+description:
+ All the SPI controller nodes should be represented in the aliases node using
+ the following format 'spi{n}' where n is a unique number for the alias.
+
+properties:
+ compatible:
+ oneOf:
+ - enum:
+ - samsung,s3c2443-spi # for S3C2443, S3C2416 and S3C2450
+ - samsung,s3c6410-spi
+ - samsung,s5pv210-spi # for S5PV210 and S5PC110
+ - samsung,exynos5433-spi
+ - tesla,fsd-spi
+ - const: samsung,exynos7-spi
+ deprecated: true
+
+ clocks:
+ minItems: 2
+ maxItems: 3
+
+ clock-names:
+ minItems: 2
+ maxItems: 3
+
+ cs-gpios: true
+
+ dmas:
+ minItems: 2
+ maxItems: 2
+
+ dma-names:
+ items:
+ - const: tx
+ - const: rx
+
+ interrupts:
+ maxItems: 1
+
+ no-cs-readback:
+ description:
+ The CS line is disconnected, therefore the device should not operate
+ based on CS signalling.
+ type: boolean
+
+ num-cs:
+ minimum: 1
+ maximum: 4
+ default: 1
+
+ samsung,spi-src-clk:
+ description:
+ If the spi controller includes a internal clock mux to select the clock
+ source for the spi bus clock, this property can be used to indicate the
+ clock to be used for driving the spi bus clock. If not specified, the
+ clock number 0 is used as default.
+ $ref: /schemas/types.yaml#/definitions/uint32
+ default: 0
+
+ reg:
+ maxItems: 1
+
+required:
+ - compatible
+ - clocks
+ - clock-names
+ - dmas
+ - dma-names
+ - interrupts
+ - reg
+
+allOf:
+ - $ref: spi-controller.yaml#
+ - if:
+ properties:
+ compatible:
+ contains:
+ const: samsung,exynos5433-spi
+ then:
+ properties:
+ clocks:
+ minItems: 3
+ maxItems: 3
+ clock-names:
+ items:
+ - const: spi
+ - enum:
+ - spi_busclk0
+ - spi_busclk1
+ - spi_busclk2
+ - spi_busclk3
+ - const: spi_ioclk
+ else:
+ properties:
+ clocks:
+ minItems: 2
+ maxItems: 2
+ clock-names:
+ items:
+ - const: spi
+ - enum:
+ - spi_busclk0
+ - spi_busclk1
+ - spi_busclk2
+ - spi_busclk3
+
+unevaluatedProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/clock/exynos5433.h>
+ #include <dt-bindings/clock/samsung,s2mps11.h>
+ #include <dt-bindings/interrupt-controller/arm-gic.h>
+ #include <dt-bindings/gpio/gpio.h>
+
+ spi@14d30000 {
+ compatible = "samsung,exynos5433-spi";
+ reg = <0x14d30000 0x100>;
+ interrupts = <GIC_SPI 433 IRQ_TYPE_LEVEL_HIGH>;
+ dmas = <&pdma0 11>, <&pdma0 10>;
+ dma-names = "tx", "rx";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&cmu_peric CLK_PCLK_SPI1>,
+ <&cmu_peric CLK_SCLK_SPI1>,
+ <&cmu_peric CLK_SCLK_IOCLK_SPI1>;
+ clock-names = "spi",
+ "spi_busclk0",
+ "spi_ioclk";
+ samsung,spi-src-clk = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi1_bus>;
+ num-cs = <1>;
+
+ cs-gpios = <&gpd6 3 GPIO_ACTIVE_HIGH>;
+
+ audio-codec@0 {
+ compatible = "wlf,wm5110";
+ reg = <0x0>;
+ spi-max-frequency = <20000000>;
+ interrupt-parent = <&gpa0>;
+ interrupts = <4 IRQ_TYPE_NONE>;
+ clocks = <&pmu_system_controller 0>,
+ <&s2mps13_osc S2MPS11_CLK_BT>;
+ clock-names = "mclk1", "mclk2";
+
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+
+ wlf,micd-detect-debounce = <300>;
+ wlf,micd-bias-start-time = <0x1>;
+ wlf,micd-rate = <0x7>;
+ wlf,micd-dbtime = <0x2>;
+ wlf,micd-force-micbias;
+ wlf,micd-configs = <0x0 1 0>;
+ wlf,hpdet-channel = <1>;
+ wlf,gpsw = <0x1>;
+ wlf,inmode = <2 0 2 0>;
+
+ wlf,reset = <&gpc0 7 GPIO_ACTIVE_HIGH>;
+ wlf,ldoena = <&gpf0 0 GPIO_ACTIVE_HIGH>;
+
+ /* core supplies */
+ AVDD-supply = <&ldo18_reg>;
+ DBVDD1-supply = <&ldo18_reg>;
+ CPVDD-supply = <&ldo18_reg>;
+ DBVDD2-supply = <&ldo18_reg>;
+ DBVDD3-supply = <&ldo18_reg>;
+ SPKVDDL-supply = <&ldo18_reg>;
+ SPKVDDR-supply = <&ldo18_reg>;
+
+ controller-data {
+ samsung,spi-feedback-delay = <0>;
+ };
+ };
+ };
diff --git a/Documentation/devicetree/bindings/spi/spi-controller.yaml b/Documentation/devicetree/bindings/spi/spi-controller.yaml
index 36b72518f565..0f4d40218400 100644
--- a/Documentation/devicetree/bindings/spi/spi-controller.yaml
+++ b/Documentation/devicetree/bindings/spi/spi-controller.yaml
@@ -139,4 +139,11 @@ examples:
spi-max-frequency = <100000>;
reg = <1>;
};
+
+ flash@2 {
+ compatible = "jedec,spi-nor";
+ spi-max-frequency = <50000000>;
+ reg = <2>, <3>;
+ stacked-memories = /bits/ 64 <0x10000000 0x10000000>;
+ };
};
diff --git a/Documentation/devicetree/bindings/spi/spi-mt65xx.txt b/Documentation/devicetree/bindings/spi/spi-mt65xx.txt
deleted file mode 100644
index 2a24969159cc..000000000000
--- a/Documentation/devicetree/bindings/spi/spi-mt65xx.txt
+++ /dev/null
@@ -1,68 +0,0 @@
-Binding for MTK SPI controller
-
-Required properties:
-- compatible: should be one of the following.
- - mediatek,mt2701-spi: for mt2701 platforms
- - mediatek,mt2712-spi: for mt2712 platforms
- - mediatek,mt6589-spi: for mt6589 platforms
- - mediatek,mt6765-spi: for mt6765 platforms
- - mediatek,mt7622-spi: for mt7622 platforms
- - "mediatek,mt7629-spi", "mediatek,mt7622-spi": for mt7629 platforms
- - mediatek,mt8135-spi: for mt8135 platforms
- - mediatek,mt8173-spi: for mt8173 platforms
- - mediatek,mt8183-spi: for mt8183 platforms
- - mediatek,mt6893-spi: for mt6893 platforms
- - "mediatek,mt8192-spi", "mediatek,mt6765-spi": for mt8192 platforms
- - "mediatek,mt8195-spi", "mediatek,mt6765-spi": for mt8195 platforms
- - "mediatek,mt8516-spi", "mediatek,mt2712-spi": for mt8516 platforms
- - "mediatek,mt6779-spi", "mediatek,mt6765-spi": for mt6779 platforms
-
-- #address-cells: should be 1.
-
-- #size-cells: should be 0.
-
-- reg: Address and length of the register set for the device
-
-- interrupts: Should contain spi interrupt
-
-- clocks: phandles to input clocks.
- The first should be one of the following. It's PLL.
- - <&clk26m>: specify parent clock 26MHZ.
- - <&topckgen CLK_TOP_SYSPLL3_D2>: specify parent clock 109MHZ.
- It's the default one.
- - <&topckgen CLK_TOP_SYSPLL4_D2>: specify parent clock 78MHZ.
- - <&topckgen CLK_TOP_UNIVPLL2_D4>: specify parent clock 104MHZ.
- - <&topckgen CLK_TOP_UNIVPLL1_D8>: specify parent clock 78MHZ.
- The second should be <&topckgen CLK_TOP_SPI_SEL>. It's clock mux.
- The third is <&pericfg CLK_PERI_SPI0>. It's clock gate.
-
-- clock-names: shall be "parent-clk" for the parent clock, "sel-clk" for the
- muxes clock, and "spi-clk" for the clock gate.
-
-Optional properties:
--cs-gpios: see spi-bus.txt.
-
-- mediatek,pad-select: specify which pins group(ck/mi/mo/cs) spi
- controller used. This is an array, the element value should be 0~3,
- only required for MT8173.
- 0: specify GPIO69,70,71,72 for spi pins.
- 1: specify GPIO102,103,104,105 for spi pins.
- 2: specify GPIO128,129,130,131 for spi pins.
- 3: specify GPIO5,6,7,8 for spi pins.
-
-Example:
-
-- SoC Specific Portion:
-spi: spi@1100a000 {
- compatible = "mediatek,mt8173-spi";
- #address-cells = <1>;
- #size-cells = <0>;
- reg = <0 0x1100a000 0 0x1000>;
- interrupts = <GIC_SPI 110 IRQ_TYPE_LEVEL_LOW>;
- clocks = <&topckgen CLK_TOP_SYSPLL3_D2>,
- <&topckgen CLK_TOP_SPI_SEL>,
- <&pericfg CLK_PERI_SPI0>;
- clock-names = "parent-clk", "sel-clk", "spi-clk";
- cs-gpios = <&pio 105 GPIO_ACTIVE_LOW>, <&pio 72 GPIO_ACTIVE_LOW>;
- mediatek,pad-select = <1>, <0>;
-};
diff --git a/Documentation/devicetree/bindings/spi/spi-nxp-fspi.yaml b/Documentation/devicetree/bindings/spi/spi-nxp-fspi.yaml
index 283815d59e85..1b552c298277 100644
--- a/Documentation/devicetree/bindings/spi/spi-nxp-fspi.yaml
+++ b/Documentation/devicetree/bindings/spi/spi-nxp-fspi.yaml
@@ -7,7 +7,8 @@ $schema: http://devicetree.org/meta-schemas/core.yaml#
title: NXP Flex Serial Peripheral Interface (FSPI)
maintainers:
- - Kuldeep Singh <kuldeep.singh@nxp.com>
+ - Han Xu <han.xu@nxp.com>
+ - Kuldeep Singh <singh.kuldeep87k@gmail.com>
allOf:
- $ref: "spi-controller.yaml#"
diff --git a/Documentation/devicetree/bindings/spi/spi-peripheral-props.yaml b/Documentation/devicetree/bindings/spi/spi-peripheral-props.yaml
index 5dd209206e88..5e32928c4fc3 100644
--- a/Documentation/devicetree/bindings/spi/spi-peripheral-props.yaml
+++ b/Documentation/devicetree/bindings/spi/spi-peripheral-props.yaml
@@ -23,8 +23,9 @@ properties:
minItems: 1
maxItems: 256
items:
- minimum: 0
- maximum: 256
+ items:
+ - minimum: 0
+ maximum: 256
description:
Chip select used by the device.
@@ -82,8 +83,34 @@ properties:
description:
Delay, in microseconds, after a write transfer.
+ stacked-memories:
+ description: Several SPI memories can be wired in stacked mode.
+ This basically means that either a device features several chip
+ selects, or that different devices must be seen as a single
+ bigger chip. This basically doubles (or more) the total address
+ space with only a single additional wire, while still needing
+ to repeat the commands when crossing a chip boundary. The size of
+ each chip should be provided as members of the array.
+ $ref: /schemas/types.yaml#/definitions/uint64-array
+ minItems: 2
+ maxItems: 4
+
+ parallel-memories:
+ description: Several SPI memories can be wired in parallel mode.
+ The devices are physically on a different buses but will always
+ act synchronously as each data word is spread across the
+ different memories (eg. even bits are stored in one memory, odd
+ bits in the other). This basically doubles the address space and
+ the throughput while greatly complexifying the wiring because as
+ many busses as devices must be wired. The size of each chip should
+ be provided as members of the array.
+ $ref: /schemas/types.yaml#/definitions/uint64-array
+ minItems: 2
+ maxItems: 4
+
# The controller specific properties go here.
allOf:
- $ref: cdns,qspi-nor-peripheral-props.yaml#
+ - $ref: samsung,spi-peripheral-props.yaml#
additionalProperties: true
diff --git a/Documentation/devicetree/bindings/spi/spi-pl022.yaml b/Documentation/devicetree/bindings/spi/spi-pl022.yaml
index 6d633728fc2b..bda45ff3d294 100644
--- a/Documentation/devicetree/bindings/spi/spi-pl022.yaml
+++ b/Documentation/devicetree/bindings/spi/spi-pl022.yaml
@@ -38,9 +38,7 @@ properties:
clock-names:
items:
- - enum:
- - SSPCLK
- - sspclk
+ - const: sspclk
- const: apb_pclk
pl022,autosuspend-delay:
diff --git a/Documentation/devicetree/bindings/spi/spi-samsung.txt b/Documentation/devicetree/bindings/spi/spi-samsung.txt
deleted file mode 100644
index 49028a4f5df1..000000000000
--- a/Documentation/devicetree/bindings/spi/spi-samsung.txt
+++ /dev/null
@@ -1,122 +0,0 @@
-* Samsung SPI Controller
-
-The Samsung SPI controller is used to interface with various devices such as flash
-and display controllers using the SPI communication interface.
-
-Required SoC Specific Properties:
-
-- compatible: should be one of the following.
- - samsung,s3c2443-spi: for s3c2443, s3c2416 and s3c2450 platforms
- - samsung,s3c6410-spi: for s3c6410 platforms
- - samsung,s5pv210-spi: for s5pv210 and s5pc110 platforms
- - samsung,exynos5433-spi: for exynos5433 compatible controllers
- - samsung,exynos7-spi: for exynos7 platforms <DEPRECATED>
-
-- reg: physical base address of the controller and length of memory mapped
- region.
-
-- interrupts: The interrupt number to the cpu. The interrupt specifier format
- depends on the interrupt controller.
-
-- dmas : Two or more DMA channel specifiers following the convention outlined
- in bindings/dma/dma.txt
-
-- dma-names: Names for the dma channels. There must be at least one channel
- named "tx" for transmit and named "rx" for receive.
-
-- clocks: specifies the clock IDs provided to the SPI controller; they are
- required for interacting with the controller itself, for synchronizing the bus
- and as I/O clock (the latter is required by exynos5433 and exynos7).
-
-- clock-names: string names of the clocks in the 'clocks' property; for all the
- the devices the names must be "spi", "spi_busclkN" (where N is determined by
- "samsung,spi-src-clk"), while Exynos5433 should specify a third clock
- "spi_ioclk" for the I/O clock.
-
-Required Board Specific Properties:
-
-- #address-cells: should be 1.
-- #size-cells: should be 0.
-
-Optional Board Specific Properties:
-
-- samsung,spi-src-clk: If the spi controller includes a internal clock mux to
- select the clock source for the spi bus clock, this property can be used to
- indicate the clock to be used for driving the spi bus clock. If not specified,
- the clock number 0 is used as default.
-
-- num-cs: Specifies the number of chip select lines supported. If
- not specified, the default number of chip select lines is set to 1.
-
-- cs-gpios: should specify GPIOs used for chipselects (see spi-bus.txt)
-
-- no-cs-readback: the CS line is disconnected, therefore the device should not
- operate based on CS signalling.
-
-SPI Controller specific data in SPI slave nodes:
-
-- The spi slave nodes should provide the following information which is required
- by the spi controller.
-
- - samsung,spi-feedback-delay: The sampling phase shift to be applied on the
- miso line (to account for any lag in the miso line). The following are the
- valid values.
-
- - 0: No phase shift.
- - 1: 90 degree phase shift sampling.
- - 2: 180 degree phase shift sampling.
- - 3: 270 degree phase shift sampling.
-
-Aliases:
-
-- All the SPI controller nodes should be represented in the aliases node using
- the following format 'spi{n}' where n is a unique number for the alias.
-
-
-Example:
-
-- SoC Specific Portion:
-
- spi_0: spi@12d20000 {
- compatible = "samsung,exynos4210-spi";
- reg = <0x12d20000 0x100>;
- interrupts = <0 66 0>;
- dmas = <&pdma0 5
- &pdma0 4>;
- dma-names = "tx", "rx";
- #address-cells = <1>;
- #size-cells = <0>;
- };
-
-- Board Specific Portion:
-
- spi_0: spi@12d20000 {
- #address-cells = <1>;
- #size-cells = <0>;
- pinctrl-names = "default";
- pinctrl-0 = <&spi0_bus>;
- cs-gpios = <&gpa2 5 0>;
-
- w25q80bw@0 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "w25x80";
- reg = <0>;
- spi-max-frequency = <10000>;
-
- controller-data {
- samsung,spi-feedback-delay = <0>;
- };
-
- partition@0 {
- label = "U-Boot";
- reg = <0x0 0x40000>;
- read-only;
- };
-
- partition@40000 {
- label = "Kernel";
- reg = <0x40000 0xc0000>;
- };
- };
- };
diff --git a/Documentation/devicetree/bindings/spi/spi-slave-mt27xx.txt b/Documentation/devicetree/bindings/spi/spi-slave-mt27xx.txt
deleted file mode 100644
index 9192724540fd..000000000000
--- a/Documentation/devicetree/bindings/spi/spi-slave-mt27xx.txt
+++ /dev/null
@@ -1,33 +0,0 @@
-Binding for MTK SPI Slave controller
-
-Required properties:
-- compatible: should be one of the following.
- - mediatek,mt2712-spi-slave: for mt2712 platforms
- - mediatek,mt8195-spi-slave: for mt8195 platforms
-- reg: Address and length of the register set for the device.
-- interrupts: Should contain spi interrupt.
-- clocks: phandles to input clocks.
- It's clock gate, and should be <&infracfg CLK_INFRA_AO_SPI1>.
-- clock-names: should be "spi" for the clock gate.
-
-Optional properties:
-- assigned-clocks: it's mux clock, should be <&topckgen CLK_TOP_SPISLV_SEL>.
-- assigned-clock-parents: parent of mux clock.
- It's PLL, and should be one of the following.
- - <&topckgen CLK_TOP_UNIVPLL1_D2>: specify parent clock 312MHZ.
- It's the default one.
- - <&topckgen CLK_TOP_UNIVPLL1_D4>: specify parent clock 156MHZ.
- - <&topckgen CLK_TOP_UNIVPLL2_D4>: specify parent clock 104MHZ.
- - <&topckgen CLK_TOP_UNIVPLL1_D8>: specify parent clock 78MHZ.
-
-Example:
-- SoC Specific Portion:
-spis1: spi@10013000 {
- compatible = "mediatek,mt2712-spi-slave";
- reg = <0 0x10013000 0 0x100>;
- interrupts = <GIC_SPI 283 IRQ_TYPE_LEVEL_LOW>;
- clocks = <&infracfg CLK_INFRA_AO_SPI1>;
- clock-names = "spi";
- assigned-clocks = <&topckgen CLK_TOP_SPISLV_SEL>;
- assigned-clock-parents = <&topckgen CLK_TOP_UNIVPLL1_D2>;
-};
diff --git a/Documentation/devicetree/bindings/spi/spi-sunplus-sp7021.yaml b/Documentation/devicetree/bindings/spi/spi-sunplus-sp7021.yaml
new file mode 100644
index 000000000000..3a58cf0f1ec8
--- /dev/null
+++ b/Documentation/devicetree/bindings/spi/spi-sunplus-sp7021.yaml
@@ -0,0 +1,78 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+# Copyright (C) Sunplus Co., Ltd. 2021
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/spi/spi-sunplus-sp7021.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Sunplus sp7021 SPI controller
+
+allOf:
+ - $ref: "spi-controller.yaml"
+
+maintainers:
+ - Li-hao Kuo <lhjeff911@gmail.com>
+
+properties:
+ compatible:
+ enum:
+ - sunplus,sp7021-spi
+
+ reg:
+ items:
+ - description: the SPI master registers
+ - description: the SPI slave registers
+
+ reg-names:
+ items:
+ - const: master
+ - const: slave
+
+ interrupt-names:
+ items:
+ - const: dma_w
+ - const: master_risc
+ - const: slave_risc
+
+ interrupts:
+ minItems: 3
+
+ clocks:
+ maxItems: 1
+
+ resets:
+ maxItems: 1
+
+required:
+ - compatible
+ - reg
+ - reg-names
+ - interrupts
+ - interrupt-names
+ - clocks
+ - resets
+ - pinctrl-names
+ - pinctrl-0
+
+unevaluatedProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/interrupt-controller/irq.h>
+ spi@9C002D80 {
+ compatible = "sunplus,sp7021-spi";
+ reg = <0x9C002D80 0x80>, <0x9C002E00 0x80>;
+ reg-names = "master", "slave";
+ interrupt-parent = <&intc>;
+ interrupt-names = "dma_w",
+ "master_risc",
+ "slave_risc";
+ interrupts = <144 IRQ_TYPE_LEVEL_HIGH>,
+ <146 IRQ_TYPE_LEVEL_HIGH>,
+ <145 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clkc 0x32>;
+ resets = <&rstc 0x22>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pins_spi0>;
+ };
+...
diff --git a/Documentation/devicetree/bindings/thermal/exynos-thermal.txt b/Documentation/devicetree/bindings/thermal/exynos-thermal.txt
deleted file mode 100644
index 33004ce7e5df..000000000000
--- a/Documentation/devicetree/bindings/thermal/exynos-thermal.txt
+++ /dev/null
@@ -1,106 +0,0 @@
-* Exynos Thermal Management Unit (TMU)
-
-** Required properties:
-
-- compatible : One of the following:
- "samsung,exynos3250-tmu"
- "samsung,exynos4412-tmu"
- "samsung,exynos4210-tmu"
- "samsung,exynos5250-tmu"
- "samsung,exynos5260-tmu"
- "samsung,exynos5420-tmu" for TMU channel 0, 1 on Exynos5420
- "samsung,exynos5420-tmu-ext-triminfo" for TMU channels 2, 3 and 4
- Exynos5420 (Must pass triminfo base and triminfo clock)
- "samsung,exynos5433-tmu"
- "samsung,exynos7-tmu"
-- reg : Address range of the thermal registers. For soc's which has multiple
- instances of TMU and some registers are shared across all TMU's like
- interrupt related then 2 set of register has to supplied. First set
- belongs to register set of TMU instance and second set belongs to
- registers shared with the TMU instance.
-
- NOTE: On Exynos5420, the TRIMINFO register is misplaced for TMU
- channels 2, 3 and 4
- Use "samsung,exynos5420-tmu-ext-triminfo" in cases, there is a misplaced
- register, also provide clock to access that base.
-
- TRIMINFO at 0x1006c000 contains data for TMU channel 3
- TRIMINFO at 0x100a0000 contains data for TMU channel 4
- TRIMINFO at 0x10068000 contains data for TMU channel 2
-
-- interrupts : Should contain interrupt for thermal system
-- clocks : The main clocks for TMU device
- -- 1. operational clock for TMU channel
- -- 2. optional clock to access the shared registers of TMU channel
- -- 3. optional special clock for functional operation
-- clock-names : Thermal system clock name
- -- "tmu_apbif" operational clock for current TMU channel
- -- "tmu_triminfo_apbif" clock to access the shared triminfo register
- for current TMU channel
- -- "tmu_sclk" clock for functional operation of the current TMU
- channel
-
-The Exynos TMU supports generating interrupts when reaching given
-temperature thresholds. Number of supported thermal trip points depends
-on the SoC (only first trip points defined in DT will be configured):
- - most of SoC: 4
- - samsung,exynos5433-tmu: 8
- - samsung,exynos7-tmu: 8
-
-** Optional properties:
-
-- vtmu-supply: This entry is optional and provides the regulator node supplying
- voltage to TMU. If needed this entry can be placed inside
- board/platform specific dts file.
-
-Example 1):
-
- tmu@100c0000 {
- compatible = "samsung,exynos4412-tmu";
- interrupt-parent = <&combiner>;
- reg = <0x100C0000 0x100>;
- interrupts = <2 4>;
- clocks = <&clock 383>;
- clock-names = "tmu_apbif";
- vtmu-supply = <&tmu_regulator_node>;
- #thermal-sensor-cells = <0>;
- };
-
-Example 2): (In case of Exynos5420 "with misplaced TRIMINFO register")
- tmu_cpu2: tmu@10068000 {
- compatible = "samsung,exynos5420-tmu-ext-triminfo";
- reg = <0x10068000 0x100>, <0x1006c000 0x4>;
- interrupts = <0 184 0>;
- clocks = <&clock 318>, <&clock 318>;
- clock-names = "tmu_apbif", "tmu_triminfo_apbif";
- #thermal-sensor-cells = <0>;
- };
-
- tmu_cpu3: tmu@1006c000 {
- compatible = "samsung,exynos5420-tmu-ext-triminfo";
- reg = <0x1006c000 0x100>, <0x100a0000 0x4>;
- interrupts = <0 185 0>;
- clocks = <&clock 318>, <&clock 319>;
- clock-names = "tmu_apbif", "tmu_triminfo_apbif";
- #thermal-sensor-cells = <0>;
- };
-
- tmu_gpu: tmu@100a0000 {
- compatible = "samsung,exynos5420-tmu-ext-triminfo";
- reg = <0x100a0000 0x100>, <0x10068000 0x4>;
- interrupts = <0 215 0>;
- clocks = <&clock 319>, <&clock 318>;
- clock-names = "tmu_apbif", "tmu_triminfo_apbif";
- #thermal-sensor-cells = <0>;
- };
-
-Note: For multi-instance tmu each instance should have an alias correctly
-numbered in "aliases" node.
-
-Example:
-
-aliases {
- tmuctrl0 = &tmuctrl_0;
- tmuctrl1 = &tmuctrl_1;
- tmuctrl2 = &tmuctrl_2;
-};
diff --git a/Documentation/devicetree/bindings/thermal/qcom-lmh.yaml b/Documentation/devicetree/bindings/thermal/qcom-lmh.yaml
index 289e9a845600..a9b7388ca9ac 100644
--- a/Documentation/devicetree/bindings/thermal/qcom-lmh.yaml
+++ b/Documentation/devicetree/bindings/thermal/qcom-lmh.yaml
@@ -19,6 +19,7 @@ properties:
compatible:
enum:
- qcom,sdm845-lmh
+ - qcom,sm8150-lmh
reg:
items:
diff --git a/Documentation/devicetree/bindings/thermal/qcom-tsens.yaml b/Documentation/devicetree/bindings/thermal/qcom-tsens.yaml
index d3b9e9b600a2..b6406bcc683f 100644
--- a/Documentation/devicetree/bindings/thermal/qcom-tsens.yaml
+++ b/Documentation/devicetree/bindings/thermal/qcom-tsens.yaml
@@ -43,6 +43,7 @@ properties:
- description: v2 of TSENS
items:
- enum:
+ - qcom,msm8953-tsens
- qcom,msm8996-tsens
- qcom,msm8998-tsens
- qcom,sc7180-tsens
diff --git a/Documentation/devicetree/bindings/thermal/samsung,exynos-thermal.yaml b/Documentation/devicetree/bindings/thermal/samsung,exynos-thermal.yaml
new file mode 100644
index 000000000000..17129f75d962
--- /dev/null
+++ b/Documentation/devicetree/bindings/thermal/samsung,exynos-thermal.yaml
@@ -0,0 +1,184 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/thermal/samsung,exynos-thermal.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Samsung Exynos SoC Thermal Management Unit (TMU)
+
+maintainers:
+ - Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>
+
+description: |
+ For multi-instance tmu each instance should have an alias correctly numbered
+ in "aliases" node.
+
+properties:
+ compatible:
+ enum:
+ - samsung,exynos3250-tmu
+ - samsung,exynos4412-tmu
+ - samsung,exynos4210-tmu
+ - samsung,exynos5250-tmu
+ - samsung,exynos5260-tmu
+ # For TMU channel 0, 1 on Exynos5420:
+ - samsung,exynos5420-tmu
+ # For TMU channels 2, 3 and 4 of Exynos5420:
+ - samsung,exynos5420-tmu-ext-triminfo
+ - samsung,exynos5433-tmu
+ - samsung,exynos7-tmu
+
+ clocks:
+ minItems: 1
+ maxItems: 3
+
+ clock-names:
+ minItems: 1
+ maxItems: 3
+
+ interrupts:
+ description: |
+ The Exynos TMU supports generating interrupts when reaching given
+ temperature thresholds. Number of supported thermal trip points depends
+ on the SoC (only first trip points defined in DT will be configured)::
+ - most of SoC: 4
+ - samsung,exynos5433-tmu: 8
+ - samsung,exynos7-tmu: 8
+ maxItems: 1
+
+ reg:
+ items:
+ - description: TMU instance registers.
+ - description: |
+ Shared TMU registers.
+
+ Note:: On Exynos5420, the TRIMINFO register is misplaced for TMU
+ channels 2, 3 and 4 Use "samsung,exynos5420-tmu-ext-triminfo" in
+ cases, there is a misplaced register, also provide clock to access
+ that base.
+ TRIMINFO at 0x1006c000 contains data for TMU channel 3
+ TRIMINFO at 0x100a0000 contains data for TMU channel 4
+ TRIMINFO at 0x10068000 contains data for TMU channel 2
+ minItems: 1
+
+ '#thermal-sensor-cells': true
+
+ vtmu-supply:
+ description: The regulator node supplying voltage to TMU.
+
+required:
+ - compatible
+ - clocks
+ - clock-names
+ - interrupts
+ - reg
+
+allOf:
+ - $ref: /schemas/thermal/thermal-sensor.yaml
+ - if:
+ properties:
+ compatible:
+ contains:
+ const: samsung,exynos5420-tmu-ext-triminfo
+ then:
+ properties:
+ clocks:
+ items:
+ - description:
+ Operational clock for TMU channel.
+ - description:
+ Optional clock to access the shared registers (e.g. TRIMINFO) of TMU
+ channel.
+ clock-names:
+ items:
+ - const: tmu_apbif
+ - const: tmu_triminfo_apbif
+ reg:
+ minItems: 2
+ maxItems: 2
+ - if:
+ properties:
+ compatible:
+ contains:
+ enum:
+ - samsung,exynos5433-tmu
+ - samsung,exynos7-tmu
+ then:
+ properties:
+ clocks:
+ items:
+ - description:
+ Operational clock for TMU channel.
+ - description:
+ Optional special clock for functional operation of TMU channel.
+ clock-names:
+ items:
+ - const: tmu_apbif
+ - const: tmu_sclk
+ reg:
+ minItems: 1
+ maxItems: 1
+
+ - if:
+ properties:
+ compatible:
+ contains:
+ enum:
+ - samsung,exynos3250-tmu
+ - samsung,exynos4412-tmu
+ - samsung,exynos4210-tmu
+ - samsung,exynos5250-tmu
+ - samsung,exynos5260-tmu
+ - samsung,exynos5420-tmu
+ then:
+ properties:
+ clocks:
+ minItems: 1
+ maxItems: 1
+ reg:
+ minItems: 1
+ maxItems: 1
+
+additionalProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/clock/exynos4.h>
+
+ tmu@100c0000 {
+ compatible = "samsung,exynos4412-tmu";
+ reg = <0x100C0000 0x100>;
+ interrupt-parent = <&combiner>;
+ interrupts = <2 4>;
+ #thermal-sensor-cells = <0>;
+ clocks = <&clock CLK_TMU_APBIF>;
+ clock-names = "tmu_apbif";
+ vtmu-supply = <&ldo10_reg>;
+ };
+
+ - |
+ #include <dt-bindings/interrupt-controller/arm-gic.h>
+
+ tmu@10068000 {
+ compatible = "samsung,exynos5420-tmu-ext-triminfo";
+ reg = <0x10068000 0x100>, <0x1006c000 0x4>;
+ interrupts = <GIC_SPI 184 IRQ_TYPE_LEVEL_HIGH>;
+ #thermal-sensor-cells = <0>;
+ clocks = <&clock 318>, <&clock 318>; /* CLK_TMU */
+ clock-names = "tmu_apbif", "tmu_triminfo_apbif";
+ vtmu-supply = <&ldo7_reg>;
+ };
+
+ - |
+ #include <dt-bindings/interrupt-controller/arm-gic.h>
+
+ tmu@10060000 {
+ compatible = "samsung,exynos5433-tmu";
+ reg = <0x10060000 0x200>;
+ interrupts = <GIC_SPI 95 IRQ_TYPE_LEVEL_HIGH>;
+ #thermal-sensor-cells = <0>;
+ clocks = <&cmu_peris 3>, /* CLK_PCLK_TMU0_APBIF */
+ <&cmu_peris 35>; /* CLK_SCLK_TMU0 */
+ clock-names = "tmu_apbif", "tmu_sclk";
+ vtmu-supply = <&ldo3_reg>;
+ };
diff --git a/Documentation/devicetree/bindings/timer/andestech,atcpit100-timer.txt b/Documentation/devicetree/bindings/timer/andestech,atcpit100-timer.txt
deleted file mode 100644
index 4c9ea5989e35..000000000000
--- a/Documentation/devicetree/bindings/timer/andestech,atcpit100-timer.txt
+++ /dev/null
@@ -1,33 +0,0 @@
-Andestech ATCPIT100 timer
-------------------------------------------------------------------
-ATCPIT100 is a generic IP block from Andes Technology, embedded in
-Andestech AE3XX platforms and other designs.
-
-This timer is a set of compact multi-function timers, which can be
-used as pulse width modulators (PWM) as well as simple timers.
-
-It supports up to 4 PIT channels. Each PIT channel is a
-multi-function timer and provide the following usage scenarios:
-One 32-bit timer
-Two 16-bit timers
-Four 8-bit timers
-One 16-bit PWM
-One 16-bit timer and one 8-bit PWM
-Two 8-bit timer and one 8-bit PWM
-
-Required properties:
-- compatible : Should be "andestech,atcpit100"
-- reg : Address and length of the register set
-- interrupts : Reference to the timer interrupt
-- clocks : a clock to provide the tick rate for "andestech,atcpit100"
-- clock-names : should be "PCLK" for the peripheral clock source.
-
-Examples:
-
-timer0: timer@f0400000 {
- compatible = "andestech,atcpit100";
- reg = <0xf0400000 0x1000>;
- interrupts = <2>;
- clocks = <&apb>;
- clock-names = "PCLK";
-};
diff --git a/Documentation/devicetree/bindings/timer/mediatek,mtk-timer.txt b/Documentation/devicetree/bindings/timer/mediatek,mtk-timer.txt
index e5c57d6e0186..fbd76a8e023b 100644
--- a/Documentation/devicetree/bindings/timer/mediatek,mtk-timer.txt
+++ b/Documentation/devicetree/bindings/timer/mediatek,mtk-timer.txt
@@ -12,6 +12,7 @@ Required properties:
For those SoCs that use GPT
* "mediatek,mt2701-timer" for MT2701 compatible timers (GPT)
* "mediatek,mt6580-timer" for MT6580 compatible timers (GPT)
+ * "mediatek,mt6582-timer" for MT6582 compatible timers (GPT)
* "mediatek,mt6589-timer" for MT6589 compatible timers (GPT)
* "mediatek,mt7623-timer" for MT7623 compatible timers (GPT)
* "mediatek,mt8127-timer" for MT8127 compatible timers (GPT)
diff --git a/Documentation/devicetree/bindings/timer/nvidia,tegra-timer.yaml b/Documentation/devicetree/bindings/timer/nvidia,tegra-timer.yaml
new file mode 100644
index 000000000000..b78209cd0f28
--- /dev/null
+++ b/Documentation/devicetree/bindings/timer/nvidia,tegra-timer.yaml
@@ -0,0 +1,150 @@
+# SPDX-License-Identifier: GPL-2.0-only
+%YAML 1.2
+---
+$id: "http://devicetree.org/schemas/timer/nvidia,tegra-timer.yaml#"
+$schema: "http://devicetree.org/meta-schemas/core.yaml#"
+
+title: NVIDIA Tegra timer
+
+maintainers:
+ - Stephen Warren <swarren@nvidia.com>
+
+allOf:
+ - if:
+ properties:
+ compatible:
+ contains:
+ const: nvidia,tegra210-timer
+ then:
+ properties:
+ interrupts:
+ # Either a single combined interrupt or up to 14 individual interrupts
+ minItems: 1
+ maxItems: 14
+ description: >
+ A list of 14 interrupts; one per each timer channels 0 through 13
+
+ - if:
+ properties:
+ compatible:
+ oneOf:
+ - items:
+ - enum:
+ - nvidia,tegra114-timer
+ - nvidia,tegra124-timer
+ - nvidia,tegra132-timer
+ - const: nvidia,tegra30-timer
+ - items:
+ - const: nvidia,tegra30-timer
+ - const: nvidia,tegra20-timer
+ then:
+ properties:
+ interrupts:
+ # Either a single combined interrupt or up to 6 individual interrupts
+ minItems: 1
+ maxItems: 6
+ description: >
+ A list of 6 interrupts; one per each of timer channels 1 through 5,
+ and one for the shared interrupt for the remaining channels.
+
+ - if:
+ properties:
+ compatible:
+ const: nvidia,tegra20-timer
+ then:
+ properties:
+ interrupts:
+ # Either a single combined interrupt or up to 4 individual interrupts
+ minItems: 1
+ maxItems: 4
+ description: |
+ A list of 4 interrupts; one per timer channel.
+
+properties:
+ compatible:
+ oneOf:
+ - const: nvidia,tegra210-timer
+ description: >
+ The Tegra210 timer provides fourteen 29-bit timer counters and one 32-bit
+ timestamp counter. The TMRs run at either a fixed 1 MHz clock rate derived
+ from the oscillator clock (TMR0-TMR9) or directly at the oscillator clock
+ (TMR10-TMR13). Each TMR can be programmed to generate one-shot, periodic,
+ or watchdog interrupts.
+ - items:
+ - enum:
+ - nvidia,tegra114-timer
+ - nvidia,tegra124-timer
+ - nvidia,tegra132-timer
+ - const: nvidia,tegra30-timer
+ - items:
+ - const: nvidia,tegra30-timer
+ - const: nvidia,tegra20-timer
+ description: >
+ The Tegra30 timer provides ten 29-bit timer channels, a single 32-bit free
+ running counter, and 5 watchdog modules. The first two channels may also
+ trigger a legacy watchdog reset.
+ - const: nvidia,tegra20-timer
+ description: >
+ The Tegra20 timer provides four 29-bit timer channels and a single 32-bit free
+ running counter. The first two channels may also trigger a watchdog reset.
+
+ reg:
+ maxItems: 1
+
+ interrupts: true
+
+ clocks:
+ maxItems: 1
+
+ clock-names:
+ items:
+ - const: timer
+
+
+required:
+ - compatible
+ - reg
+ - interrupts
+ - clocks
+
+additionalProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/interrupt-controller/irq.h>
+ timer@60005000 {
+ compatible = "nvidia,tegra30-timer", "nvidia,tegra20-timer";
+ reg = <0x60005000 0x400>;
+ interrupts = <0 0 IRQ_TYPE_LEVEL_HIGH>,
+ <0 1 IRQ_TYPE_LEVEL_HIGH>,
+ <0 41 IRQ_TYPE_LEVEL_HIGH>,
+ <0 42 IRQ_TYPE_LEVEL_HIGH>,
+ <0 121 IRQ_TYPE_LEVEL_HIGH>,
+ <0 122 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&tegra_car 214>;
+ };
+ - |
+ #include <dt-bindings/clock/tegra210-car.h>
+ #include <dt-bindings/interrupt-controller/arm-gic.h>
+ #include <dt-bindings/interrupt-controller/irq.h>
+
+ timer@60005000 {
+ compatible = "nvidia,tegra210-timer";
+ reg = <0x60005000 0x400>;
+ interrupts = <GIC_SPI 156 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 152 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 153 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 154 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 155 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 176 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 177 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 178 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 179 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&tegra_car TEGRA210_CLK_TIMER>;
+ clock-names = "timer";
+ };
diff --git a/Documentation/devicetree/bindings/timer/nvidia,tegra20-timer.txt b/Documentation/devicetree/bindings/timer/nvidia,tegra20-timer.txt
deleted file mode 100644
index 4a864bd10d3d..000000000000
--- a/Documentation/devicetree/bindings/timer/nvidia,tegra20-timer.txt
+++ /dev/null
@@ -1,24 +0,0 @@
-NVIDIA Tegra20 timer
-
-The Tegra20 timer provides four 29-bit timer channels and a single 32-bit free
-running counter. The first two channels may also trigger a watchdog reset.
-
-Required properties:
-
-- compatible : should be "nvidia,tegra20-timer".
-- reg : Specifies base physical address and size of the registers.
-- interrupts : A list of 4 interrupts; one per timer channel.
-- clocks : Must contain one entry, for the module clock.
- See ../clocks/clock-bindings.txt for details.
-
-Example:
-
-timer {
- compatible = "nvidia,tegra20-timer";
- reg = <0x60005000 0x60>;
- interrupts = <0 0 0x04
- 0 1 0x04
- 0 41 0x04
- 0 42 0x04>;
- clocks = <&tegra_car 132>;
-};
diff --git a/Documentation/devicetree/bindings/timer/nvidia,tegra210-timer.txt b/Documentation/devicetree/bindings/timer/nvidia,tegra210-timer.txt
deleted file mode 100644
index 032cda96fe0d..000000000000
--- a/Documentation/devicetree/bindings/timer/nvidia,tegra210-timer.txt
+++ /dev/null
@@ -1,36 +0,0 @@
-NVIDIA Tegra210 timer
-
-The Tegra210 timer provides fourteen 29-bit timer counters and one 32-bit
-timestamp counter. The TMRs run at either a fixed 1 MHz clock rate derived
-from the oscillator clock (TMR0-TMR9) or directly at the oscillator clock
-(TMR10-TMR13). Each TMR can be programmed to generate one-shot, periodic,
-or watchdog interrupts.
-
-Required properties:
-- compatible : "nvidia,tegra210-timer".
-- reg : Specifies base physical address and size of the registers.
-- interrupts : A list of 14 interrupts; one per each timer channels 0 through
- 13.
-- clocks : Must contain one entry, for the module clock.
- See ../clocks/clock-bindings.txt for details.
-
-timer@60005000 {
- compatible = "nvidia,tegra210-timer";
- reg = <0x0 0x60005000 0x0 0x400>;
- interrupts = <GIC_SPI 156 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 152 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 153 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 154 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 155 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 176 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 177 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 178 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 179 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&tegra_car TEGRA210_CLK_TIMER>;
- clock-names = "timer";
-};
diff --git a/Documentation/devicetree/bindings/timer/nvidia,tegra30-timer.txt b/Documentation/devicetree/bindings/timer/nvidia,tegra30-timer.txt
deleted file mode 100644
index 1761f53ee36f..000000000000
--- a/Documentation/devicetree/bindings/timer/nvidia,tegra30-timer.txt
+++ /dev/null
@@ -1,28 +0,0 @@
-NVIDIA Tegra30 timer
-
-The Tegra30 timer provides ten 29-bit timer channels, a single 32-bit free
-running counter, and 5 watchdog modules. The first two channels may also
-trigger a legacy watchdog reset.
-
-Required properties:
-
-- compatible : For Tegra30, must contain "nvidia,tegra30-timer". Otherwise,
- must contain '"nvidia,<chip>-timer", "nvidia,tegra30-timer"' where
- <chip> is tegra124 or tegra132.
-- reg : Specifies base physical address and size of the registers.
-- interrupts : A list of 6 interrupts; one per each of timer channels 1
- through 5, and one for the shared interrupt for the remaining channels.
-- clocks : Must contain one entry, for the module clock.
- See ../clocks/clock-bindings.txt for details.
-
-timer {
- compatible = "nvidia,tegra30-timer", "nvidia,tegra20-timer";
- reg = <0x60005000 0x400>;
- interrupts = <0 0 0x04
- 0 1 0x04
- 0 41 0x04
- 0 42 0x04
- 0 121 0x04
- 0 122 0x04>;
- clocks = <&tegra_car 214>;
-};
diff --git a/Documentation/devicetree/bindings/trivial-devices.yaml b/Documentation/devicetree/bindings/trivial-devices.yaml
index 091792ba993e..da929cb08463 100644
--- a/Documentation/devicetree/bindings/trivial-devices.yaml
+++ b/Documentation/devicetree/bindings/trivial-devices.yaml
@@ -137,6 +137,8 @@ properties:
- infineon,slb9645tt
# Infineon TLV493D-A1B6 I2C 3D Magnetic Sensor
- infineon,tlv493d-a1b6
+ # Infineon Multi-phase Digital VR Controller xdpe11280
+ - infineon,xdpe11280
# Infineon Multi-phase Digital VR Controller xdpe12254
- infineon,xdpe12254
# Infineon Multi-phase Digital VR Controller xdpe12284
@@ -337,6 +339,7 @@ properties:
# Thermometer with SPI interface
- ti,tmp121
- ti,tmp122
+ - ti,tmp125
# Digital Temperature Sensor
- ti,tmp275
# TI DC-DC converter on PMBus
@@ -354,6 +357,8 @@ properties:
- ti,tps544c25
# Winbond/Nuvoton H/W Monitor
- winbond,w83793
+ # Vicor Corporation Digital Supervisor
+ - vicor,pli1209bc
# i2c trusted platform module (TPM)
- winbond,wpct301
diff --git a/Documentation/devicetree/bindings/usb/dwc2.yaml b/Documentation/devicetree/bindings/usb/dwc2.yaml
index f00867ebc147..4cebce682d16 100644
--- a/Documentation/devicetree/bindings/usb/dwc2.yaml
+++ b/Documentation/devicetree/bindings/usb/dwc2.yaml
@@ -41,6 +41,7 @@ properties:
- amlogic,meson8b-usb
- amlogic,meson-gxbb-usb
- amlogic,meson-g12a-usb
+ - intel,socfpga-agilex-hsotg
- const: snps,dwc2
- const: amcc,dwc-otg
- const: apm,apm82181-dwc-otg
@@ -53,6 +54,7 @@ properties:
- const: st,stm32mp15-hsotg
- const: snps,dwc2
- const: samsung,s3c6400-hsotg
+ - const: intel,socfpga-agilex-hsotg
reg:
maxItems: 1
@@ -67,6 +69,13 @@ properties:
items:
- const: otg
+ disable-over-current:
+ type: boolean
+ description: whether to disable detection of over-current condition.
+
+ iommus:
+ maxItems: 1
+
resets:
items:
- description: common reset
diff --git a/Documentation/devicetree/bindings/usb/ti,j721e-usb.yaml b/Documentation/devicetree/bindings/usb/ti,j721e-usb.yaml
index a634774c537c..eedde385d299 100644
--- a/Documentation/devicetree/bindings/usb/ti,j721e-usb.yaml
+++ b/Documentation/devicetree/bindings/usb/ti,j721e-usb.yaml
@@ -7,7 +7,7 @@ $schema: "http://devicetree.org/meta-schemas/core.yaml#"
title: Bindings for the TI wrapper module for the Cadence USBSS-DRD controller
maintainers:
- - Roger Quadros <rogerq@ti.com>
+ - Roger Quadros <rogerq@kernel.org>
properties:
compatible:
diff --git a/Documentation/devicetree/bindings/usb/ti,keystone-dwc3.yaml b/Documentation/devicetree/bindings/usb/ti,keystone-dwc3.yaml
index f6e91a5fd8fe..4f7a212fddd3 100644
--- a/Documentation/devicetree/bindings/usb/ti,keystone-dwc3.yaml
+++ b/Documentation/devicetree/bindings/usb/ti,keystone-dwc3.yaml
@@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml#
title: TI Keystone Soc USB Controller
maintainers:
- - Roger Quadros <rogerq@ti.com>
+ - Roger Quadros <rogerq@kernel.org>
properties:
compatible:
diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml
index 294093d45a23..baed2b007d0e 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.yaml
+++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml
@@ -23,6 +23,8 @@ patternProperties:
"^(simple-audio-card|st-plgpio|st-spics|ts),.*": true
# Keep list in alphabetical order.
+ "^100ask,.*":
+ description: Baiwen.com (100ask).
"^70mai,.*":
description: 70mai Co., Ltd.
"^8dev,.*":
@@ -61,6 +63,8 @@ patternProperties:
description: Aeroflex Gaisler AB
"^aesop,.*":
description: AESOP Embedded Forum
+ "^airoha,.*":
+ description: Airoha
"^al,.*":
description: Annapurna Labs
"^alcatel,.*":
@@ -277,12 +281,16 @@ patternProperties:
description: Hangzhou C-SKY Microsystems Co., Ltd
"^csq,.*":
description: Shenzen Chuangsiqi Technology Co.,Ltd.
+ "^ctera,.*":
+ description: CTERA Networks Intl.
"^cubietech,.*":
description: Cubietech, Ltd.
"^cui,.*":
description: CUI Devices
"^cypress,.*":
description: Cypress Semiconductor Corporation
+ "^cyx,.*":
+ description: Shenzhen CYX Industrial Co., Ltd
"^cznic,.*":
description: CZ.NIC, z.s.p.o.
"^dallas,.*":
@@ -489,6 +497,8 @@ patternProperties:
deprecated: true
"^hannstar,.*":
description: HannStar Display Corporation
+ "^haochuangyi,.*":
+ description: Shenzhen Haochuangyi Technology Co.,Ltd
"^haoyu,.*":
description: Haoyu Microelectronic Co. Ltd.
"^hardkernel,.*":
@@ -769,6 +779,8 @@ patternProperties:
description: MiraMEMS Sensing Technology Co., Ltd.
"^mitsubishi,.*":
description: Mitsubishi Electric Corporation
+ "^miyoo,.*":
+ description: Miyoo
"^mntre,.*":
description: MNT Research GmbH
"^modtronix,.*":
@@ -892,6 +904,8 @@ patternProperties:
description: Ortus Technology Co., Ltd.
"^osddisplays,.*":
description: OSD Displays
+ "^osmc,.*":
+ description: Sam Nazarko Trading Ltd. (Open Source Media Centre)
"^ouya,.*":
description: Ouya Inc.
"^overkiz,.*":
@@ -1205,6 +1219,8 @@ patternProperties:
description: Shenzhen Techstar Electronics Co., Ltd.
"^terasic,.*":
description: Terasic Inc.
+ "^tesla,.*":
+ description: Tesla, Inc.
"^tfc,.*":
description: Three Five Corp
"^thead,.*":
@@ -1298,6 +1314,8 @@ patternProperties:
description: Vertexcom Technologies, Inc.
"^via,.*":
description: VIA Technologies, Inc.
+ "^vicor,.*":
+ description: Vicor Corporation
"^videostrong,.*":
description: Videostrong Technology Co., Ltd.
"^virtio,.*":
@@ -1348,6 +1366,8 @@ patternProperties:
description: WinLink Co., Ltd
"^winstar,.*":
description: Winstar Display Corp.
+ "^wirelesstag,.*":
+ description: Wireless Tag (qiming yunduan)
"^wits,.*":
description: Shenzhen Merrii Technology Co., Ltd. (WITS)
"^wlf,.*":
diff --git a/Documentation/devicetree/bindings/watchdog/mtk-wdt.txt b/Documentation/devicetree/bindings/watchdog/mtk-wdt.txt
index 0114871f887a..a97418c74f6b 100644
--- a/Documentation/devicetree/bindings/watchdog/mtk-wdt.txt
+++ b/Documentation/devicetree/bindings/watchdog/mtk-wdt.txt
@@ -8,6 +8,7 @@ Required properties:
- compatible should contain:
"mediatek,mt2701-wdt", "mediatek,mt6589-wdt": for MT2701
"mediatek,mt2712-wdt": for MT2712
+ "mediatek,mt6582-wdt", "mediatek,mt6589-wdt": for MT6582
"mediatek,mt6589-wdt": for MT6589
"mediatek,mt6797-wdt", "mediatek,mt6589-wdt": for MT6797
"mediatek,mt7622-wdt", "mediatek,mt6589-wdt": for MT7622
diff --git a/Documentation/driver-api/cxl/memory-devices.rst b/Documentation/driver-api/cxl/memory-devices.rst
index 3b8f41395f6b..db476bb170b6 100644
--- a/Documentation/driver-api/cxl/memory-devices.rst
+++ b/Documentation/driver-api/cxl/memory-devices.rst
@@ -14,6 +14,303 @@ that optionally define a device's contribution to an interleaved address
range across multiple devices underneath a host-bridge or interleaved
across host-bridges.
+CXL Bus: Theory of Operation
+============================
+Similar to how a RAID driver takes disk objects and assembles them into a new
+logical device, the CXL subsystem is tasked to take PCIe and ACPI objects and
+assemble them into a CXL.mem decode topology. The need for runtime configuration
+of the CXL.mem topology is also similar to RAID in that different environments
+with the same hardware configuration may decide to assemble the topology in
+contrasting ways. One may choose performance (RAID0) striping memory across
+multiple Host Bridges and endpoints while another may opt for fault tolerance
+and disable any striping in the CXL.mem topology.
+
+Platform firmware enumerates a menu of interleave options at the "CXL root port"
+(Linux term for the top of the CXL decode topology). From there, PCIe topology
+dictates which endpoints can participate in which Host Bridge decode regimes.
+Each PCIe Switch in the path between the root and an endpoint introduces a point
+at which the interleave can be split. For example platform firmware may say at a
+given range only decodes to 1 one Host Bridge, but that Host Bridge may in turn
+interleave cycles across multiple Root Ports. An intervening Switch between a
+port and an endpoint may interleave cycles across multiple Downstream Switch
+Ports, etc.
+
+Here is a sample listing of a CXL topology defined by 'cxl_test'. The 'cxl_test'
+module generates an emulated CXL topology of 2 Host Bridges each with 2 Root
+Ports. Each of those Root Ports are connected to 2-way switches with endpoints
+connected to those downstream ports for a total of 8 endpoints::
+
+ # cxl list -BEMPu -b cxl_test
+ {
+ "bus":"root3",
+ "provider":"cxl_test",
+ "ports:root3":[
+ {
+ "port":"port5",
+ "host":"cxl_host_bridge.1",
+ "ports:port5":[
+ {
+ "port":"port8",
+ "host":"cxl_switch_uport.1",
+ "endpoints:port8":[
+ {
+ "endpoint":"endpoint9",
+ "host":"mem2",
+ "memdev":{
+ "memdev":"mem2",
+ "pmem_size":"256.00 MiB (268.44 MB)",
+ "ram_size":"256.00 MiB (268.44 MB)",
+ "serial":"0x1",
+ "numa_node":1,
+ "host":"cxl_mem.1"
+ }
+ },
+ {
+ "endpoint":"endpoint15",
+ "host":"mem6",
+ "memdev":{
+ "memdev":"mem6",
+ "pmem_size":"256.00 MiB (268.44 MB)",
+ "ram_size":"256.00 MiB (268.44 MB)",
+ "serial":"0x5",
+ "numa_node":1,
+ "host":"cxl_mem.5"
+ }
+ }
+ ]
+ },
+ {
+ "port":"port12",
+ "host":"cxl_switch_uport.3",
+ "endpoints:port12":[
+ {
+ "endpoint":"endpoint17",
+ "host":"mem8",
+ "memdev":{
+ "memdev":"mem8",
+ "pmem_size":"256.00 MiB (268.44 MB)",
+ "ram_size":"256.00 MiB (268.44 MB)",
+ "serial":"0x7",
+ "numa_node":1,
+ "host":"cxl_mem.7"
+ }
+ },
+ {
+ "endpoint":"endpoint13",
+ "host":"mem4",
+ "memdev":{
+ "memdev":"mem4",
+ "pmem_size":"256.00 MiB (268.44 MB)",
+ "ram_size":"256.00 MiB (268.44 MB)",
+ "serial":"0x3",
+ "numa_node":1,
+ "host":"cxl_mem.3"
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "port":"port4",
+ "host":"cxl_host_bridge.0",
+ "ports:port4":[
+ {
+ "port":"port6",
+ "host":"cxl_switch_uport.0",
+ "endpoints:port6":[
+ {
+ "endpoint":"endpoint7",
+ "host":"mem1",
+ "memdev":{
+ "memdev":"mem1",
+ "pmem_size":"256.00 MiB (268.44 MB)",
+ "ram_size":"256.00 MiB (268.44 MB)",
+ "serial":"0",
+ "numa_node":0,
+ "host":"cxl_mem.0"
+ }
+ },
+ {
+ "endpoint":"endpoint14",
+ "host":"mem5",
+ "memdev":{
+ "memdev":"mem5",
+ "pmem_size":"256.00 MiB (268.44 MB)",
+ "ram_size":"256.00 MiB (268.44 MB)",
+ "serial":"0x4",
+ "numa_node":0,
+ "host":"cxl_mem.4"
+ }
+ }
+ ]
+ },
+ {
+ "port":"port10",
+ "host":"cxl_switch_uport.2",
+ "endpoints:port10":[
+ {
+ "endpoint":"endpoint16",
+ "host":"mem7",
+ "memdev":{
+ "memdev":"mem7",
+ "pmem_size":"256.00 MiB (268.44 MB)",
+ "ram_size":"256.00 MiB (268.44 MB)",
+ "serial":"0x6",
+ "numa_node":0,
+ "host":"cxl_mem.6"
+ }
+ },
+ {
+ "endpoint":"endpoint11",
+ "host":"mem3",
+ "memdev":{
+ "memdev":"mem3",
+ "pmem_size":"256.00 MiB (268.44 MB)",
+ "ram_size":"256.00 MiB (268.44 MB)",
+ "serial":"0x2",
+ "numa_node":0,
+ "host":"cxl_mem.2"
+ }
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+
+In that listing each "root", "port", and "endpoint" object correspond a kernel
+'struct cxl_port' object. A 'cxl_port' is a device that can decode CXL.mem to
+its descendants. So "root" claims non-PCIe enumerable platform decode ranges and
+decodes them to "ports", "ports" decode to "endpoints", and "endpoints"
+represent the decode from SPA (System Physical Address) to DPA (Device Physical
+Address).
+
+Continuing the RAID analogy, disks have both topology metadata and on device
+metadata that determine RAID set assembly. CXL Port topology and CXL Port link
+status is metadata for CXL.mem set assembly. The CXL Port topology is enumerated
+by the arrival of a CXL.mem device. I.e. unless and until the PCIe core attaches
+the cxl_pci driver to a CXL Memory Expander there is no role for CXL Port
+objects. Conversely for hot-unplug / removal scenarios, there is no need for
+the Linux PCI core to tear down switch-level CXL resources because the endpoint
+->remove() event cleans up the port data that was established to support that
+Memory Expander.
+
+The port metadata and potential decode schemes that a give memory device may
+participate can be determined via a command like::
+
+ # cxl list -BDMu -d root -m mem3
+ {
+ "bus":"root3",
+ "provider":"cxl_test",
+ "decoders:root3":[
+ {
+ "decoder":"decoder3.1",
+ "resource":"0x8030000000",
+ "size":"512.00 MiB (536.87 MB)",
+ "volatile_capable":true,
+ "nr_targets":2
+ },
+ {
+ "decoder":"decoder3.3",
+ "resource":"0x8060000000",
+ "size":"512.00 MiB (536.87 MB)",
+ "pmem_capable":true,
+ "nr_targets":2
+ },
+ {
+ "decoder":"decoder3.0",
+ "resource":"0x8020000000",
+ "size":"256.00 MiB (268.44 MB)",
+ "volatile_capable":true,
+ "nr_targets":1
+ },
+ {
+ "decoder":"decoder3.2",
+ "resource":"0x8050000000",
+ "size":"256.00 MiB (268.44 MB)",
+ "pmem_capable":true,
+ "nr_targets":1
+ }
+ ],
+ "memdevs:root3":[
+ {
+ "memdev":"mem3",
+ "pmem_size":"256.00 MiB (268.44 MB)",
+ "ram_size":"256.00 MiB (268.44 MB)",
+ "serial":"0x2",
+ "numa_node":0,
+ "host":"cxl_mem.2"
+ }
+ ]
+ }
+
+...which queries the CXL topology to ask "given CXL Memory Expander with a kernel
+device name of 'mem3' which platform level decode ranges may this device
+participate". A given expander can participate in multiple CXL.mem interleave
+sets simultaneously depending on how many decoder resource it has. In this
+example mem3 can participate in one or more of a PMEM interleave that spans to
+Host Bridges, a PMEM interleave that targets a single Host Bridge, a Volatile
+memory interleave that spans 2 Host Bridges, and a Volatile memory interleave
+that only targets a single Host Bridge.
+
+Conversely the memory devices that can participate in a given platform level
+decode scheme can be determined via a command like the following::
+
+ # cxl list -MDu -d 3.2
+ [
+ {
+ "memdevs":[
+ {
+ "memdev":"mem1",
+ "pmem_size":"256.00 MiB (268.44 MB)",
+ "ram_size":"256.00 MiB (268.44 MB)",
+ "serial":"0",
+ "numa_node":0,
+ "host":"cxl_mem.0"
+ },
+ {
+ "memdev":"mem5",
+ "pmem_size":"256.00 MiB (268.44 MB)",
+ "ram_size":"256.00 MiB (268.44 MB)",
+ "serial":"0x4",
+ "numa_node":0,
+ "host":"cxl_mem.4"
+ },
+ {
+ "memdev":"mem7",
+ "pmem_size":"256.00 MiB (268.44 MB)",
+ "ram_size":"256.00 MiB (268.44 MB)",
+ "serial":"0x6",
+ "numa_node":0,
+ "host":"cxl_mem.6"
+ },
+ {
+ "memdev":"mem3",
+ "pmem_size":"256.00 MiB (268.44 MB)",
+ "ram_size":"256.00 MiB (268.44 MB)",
+ "serial":"0x2",
+ "numa_node":0,
+ "host":"cxl_mem.2"
+ }
+ ]
+ },
+ {
+ "root decoders":[
+ {
+ "decoder":"decoder3.2",
+ "resource":"0x8050000000",
+ "size":"256.00 MiB (268.44 MB)",
+ "pmem_capable":true,
+ "nr_targets":1
+ }
+ ]
+ }
+ ]
+
+...where the naming scheme for decoders is "decoder<port_id>.<instance_id>".
+
Driver Infrastructure
=====================
@@ -28,6 +325,14 @@ CXL Memory Device
.. kernel-doc:: drivers/cxl/pci.c
:internal:
+.. kernel-doc:: drivers/cxl/mem.c
+ :doc: cxl mem
+
+CXL Port
+--------
+.. kernel-doc:: drivers/cxl/port.c
+ :doc: cxl port
+
CXL Core
--------
.. kernel-doc:: drivers/cxl/cxl.h
@@ -36,10 +341,16 @@ CXL Core
.. kernel-doc:: drivers/cxl/cxl.h
:internal:
-.. kernel-doc:: drivers/cxl/core/bus.c
+.. kernel-doc:: drivers/cxl/core/port.c
:doc: cxl core
-.. kernel-doc:: drivers/cxl/core/bus.c
+.. kernel-doc:: drivers/cxl/core/port.c
+ :identifiers:
+
+.. kernel-doc:: drivers/cxl/core/pci.c
+ :doc: cxl core pci
+
+.. kernel-doc:: drivers/cxl/core/pci.c
:identifiers:
.. kernel-doc:: drivers/cxl/core/pmem.c
diff --git a/Documentation/driver-api/device-io.rst b/Documentation/driver-api/device-io.rst
index e9f04b1815d1..4d2baac0311c 100644
--- a/Documentation/driver-api/device-io.rst
+++ b/Documentation/driver-api/device-io.rst
@@ -502,6 +502,15 @@ pcim_iomap()
Not using these wrappers may make drivers unusable on certain platforms with
stricter rules for mapping I/O memory.
+Generalizing Access to System and I/O Memory
+============================================
+
+.. kernel-doc:: include/linux/iosys-map.h
+ :doc: overview
+
+.. kernel-doc:: include/linux/iosys-map.h
+ :internal:
+
Public Functions Provided
=========================
diff --git a/Documentation/driver-api/dma-buf.rst b/Documentation/driver-api/dma-buf.rst
index 2cd7db82d9fe..55006678394a 100644
--- a/Documentation/driver-api/dma-buf.rst
+++ b/Documentation/driver-api/dma-buf.rst
@@ -128,15 +128,6 @@ Kernel Functions and Structures Reference
.. kernel-doc:: include/linux/dma-buf.h
:internal:
-Buffer Mapping Helpers
-~~~~~~~~~~~~~~~~~~~~~~
-
-.. kernel-doc:: include/linux/dma-buf-map.h
- :doc: overview
-
-.. kernel-doc:: include/linux/dma-buf-map.h
- :internal:
-
Reservation Objects
-------------------
diff --git a/Documentation/driver-api/gpio/board.rst b/Documentation/driver-api/gpio/board.rst
index 191fa867826a..4e3adf31c8d1 100644
--- a/Documentation/driver-api/gpio/board.rst
+++ b/Documentation/driver-api/gpio/board.rst
@@ -71,14 +71,14 @@ with the help of _DSD (Device Specific Data), introduced in ACPI 5.1::
Device (FOO) {
Name (_CRS, ResourceTemplate () {
- GpioIo (Exclusive, ..., IoRestrictionOutputOnly,
- "\\_SB.GPI0") {15} // red
- GpioIo (Exclusive, ..., IoRestrictionOutputOnly,
- "\\_SB.GPI0") {16} // green
- GpioIo (Exclusive, ..., IoRestrictionOutputOnly,
- "\\_SB.GPI0") {17} // blue
- GpioIo (Exclusive, ..., IoRestrictionOutputOnly,
- "\\_SB.GPI0") {1} // power
+ GpioIo (Exclusive, PullUp, 0, 0, IoRestrictionOutputOnly,
+ "\\_SB.GPI0", 0, ResourceConsumer) { 15 } // red
+ GpioIo (Exclusive, PullUp, 0, 0, IoRestrictionOutputOnly,
+ "\\_SB.GPI0", 0, ResourceConsumer) { 16 } // green
+ GpioIo (Exclusive, PullUp, 0, 0, IoRestrictionOutputOnly,
+ "\\_SB.GPI0", 0, ResourceConsumer) { 17 } // blue
+ GpioIo (Exclusive, PullNone, 0, 0, IoRestrictionOutputOnly,
+ "\\_SB.GPI0", 0, ResourceConsumer) { 1 } // power
})
Name (_DSD, Package () {
@@ -92,10 +92,7 @@ with the help of _DSD (Device Specific Data), introduced in ACPI 5.1::
^FOO, 2, 0, 1,
}
},
- Package () {
- "power-gpios",
- Package () {^FOO, 3, 0, 0},
- },
+ Package () { "power-gpios", Package () { ^FOO, 3, 0, 0 } },
}
})
}
diff --git a/Documentation/driver-api/index.rst b/Documentation/driver-api/index.rst
index c57c609ad2eb..a7b0223e2886 100644
--- a/Documentation/driver-api/index.rst
+++ b/Documentation/driver-api/index.rst
@@ -103,6 +103,7 @@ available subsections can be seen below.
sync_file
vfio-mediated-device
vfio
+ vfio-pci-device-specific-driver-acceptance
xilinx/index
xillybus
zorro
diff --git a/Documentation/driver-api/media/drivers/davinci-vpbe-devel.rst b/Documentation/driver-api/media/drivers/davinci-vpbe-devel.rst
index f0961672e6a3..4e87bdbc7ae4 100644
--- a/Documentation/driver-api/media/drivers/davinci-vpbe-devel.rst
+++ b/Documentation/driver-api/media/drivers/davinci-vpbe-devel.rst
@@ -7,22 +7,22 @@ File partitioning
-----------------
V4L2 display device driver
- drivers/media/platform/davinci/vpbe_display.c
- drivers/media/platform/davinci/vpbe_display.h
+ drivers/media/platform/ti/davinci/vpbe_display.c
+ drivers/media/platform/ti/davinci/vpbe_display.h
VPBE display controller
- drivers/media/platform/davinci/vpbe.c
- drivers/media/platform/davinci/vpbe.h
+ drivers/media/platform/ti/davinci/vpbe.c
+ drivers/media/platform/ti/davinci/vpbe.h
VPBE venc sub device driver
- drivers/media/platform/davinci/vpbe_venc.c
- drivers/media/platform/davinci/vpbe_venc.h
- drivers/media/platform/davinci/vpbe_venc_regs.h
+ drivers/media/platform/ti/davinci/vpbe_venc.c
+ drivers/media/platform/ti/davinci/vpbe_venc.h
+ drivers/media/platform/ti/davinci/vpbe_venc_regs.h
VPBE osd driver
- drivers/media/platform/davinci/vpbe_osd.c
- drivers/media/platform/davinci/vpbe_osd.h
- drivers/media/platform/davinci/vpbe_osd_regs.h
+ drivers/media/platform/ti/davinci/vpbe_osd.c
+ drivers/media/platform/ti/davinci/vpbe_osd.h
+ drivers/media/platform/ti/davinci/vpbe_osd_regs.h
To be done
----------
diff --git a/Documentation/driver-api/media/drivers/fimc-devel.rst b/Documentation/driver-api/media/drivers/fimc-devel.rst
index 956e3a9901f8..4c6b7c8be19f 100644
--- a/Documentation/driver-api/media/drivers/fimc-devel.rst
+++ b/Documentation/driver-api/media/drivers/fimc-devel.rst
@@ -12,22 +12,22 @@ Files partitioning
- media device driver
- drivers/media/platform/exynos4-is/media-dev.[ch]
+ drivers/media/platform/samsung/exynos4-is/media-dev.[ch]
- camera capture video device driver
- drivers/media/platform/exynos4-is/fimc-capture.c
+ drivers/media/platform/samsung/exynos4-is/fimc-capture.c
- MIPI-CSI2 receiver subdev
- drivers/media/platform/exynos4-is/mipi-csis.[ch]
+ drivers/media/platform/samsung/exynos4-is/mipi-csis.[ch]
- video post-processor (mem-to-mem)
- drivers/media/platform/exynos4-is/fimc-core.c
+ drivers/media/platform/samsung/exynos4-is/fimc-core.c
- common files
- drivers/media/platform/exynos4-is/fimc-core.h
- drivers/media/platform/exynos4-is/fimc-reg.h
- drivers/media/platform/exynos4-is/regs-fimc.h
+ drivers/media/platform/samsung/exynos4-is/fimc-core.h
+ drivers/media/platform/samsung/exynos4-is/fimc-reg.h
+ drivers/media/platform/samsung/exynos4-is/regs-fimc.h
diff --git a/Documentation/driver-api/media/v4l2-event.rst b/Documentation/driver-api/media/v4l2-event.rst
index 5b8254eba7da..52d4fbc5d819 100644
--- a/Documentation/driver-api/media/v4l2-event.rst
+++ b/Documentation/driver-api/media/v4l2-event.rst
@@ -167,7 +167,7 @@ The first event type in the class is reserved for future use, so the first
available event type is 'class base + 1'.
An example on how the V4L2 events may be used can be found in the OMAP
-3 ISP driver (``drivers/media/platform/omap3isp``).
+3 ISP driver (``drivers/media/platform/ti/omap3isp``).
A subdev can directly send an event to the :c:type:`v4l2_device` notify
function with ``V4L2_DEVICE_NOTIFY_EVENT``. This allows the bridge to map
diff --git a/Documentation/driver-api/mtd/index.rst b/Documentation/driver-api/mtd/index.rst
index 436ba5a851d7..6a4278f409d7 100644
--- a/Documentation/driver-api/mtd/index.rst
+++ b/Documentation/driver-api/mtd/index.rst
@@ -7,6 +7,6 @@ Memory Technology Device (MTD)
.. toctree::
:maxdepth: 1
- intel-spi
+ spi-intel
nand_ecc
spi-nor
diff --git a/Documentation/driver-api/mtd/intel-spi.rst b/Documentation/driver-api/mtd/spi-intel.rst
index 0465f6879262..df854f20ead1 100644
--- a/Documentation/driver-api/mtd/intel-spi.rst
+++ b/Documentation/driver-api/mtd/spi-intel.rst
@@ -1,5 +1,5 @@
==============================
-Upgrading BIOS using intel-spi
+Upgrading BIOS using spi-intel
==============================
Many Intel CPUs like Baytrail and Braswell include SPI serial flash host
@@ -11,12 +11,12 @@ avoid accidental (or on purpose) overwrite of the content.
Not all manufacturers protect the SPI serial flash, mainly because it
allows upgrading the BIOS image directly from an OS.
-The intel-spi driver makes it possible to read and write the SPI serial
+The spi-intel driver makes it possible to read and write the SPI serial
flash, if certain protection bits are not set and locked. If it finds
any of them set, the whole MTD device is made read-only to prevent
partial overwrites. By default the driver exposes SPI serial flash
contents as read-only but it can be changed from kernel command line,
-passing "intel-spi.writeable=1".
+passing "spi_intel.writeable=1".
Please keep in mind that overwriting the BIOS image on SPI serial flash
might render the machine unbootable and requires special equipment like
@@ -32,7 +32,7 @@ Linux.
serial flash. Distros like Debian and Fedora have this prepackaged with
name "mtd-utils".
- 3) Add "intel-spi.writeable=1" to the kernel command line and reboot
+ 3) Add "spi_intel.writeable=1" to the kernel command line and reboot
the board (you can also reload the driver passing "writeable=1" as
module parameter to modprobe).
diff --git a/Documentation/driver-api/serial/driver.rst b/Documentation/driver-api/serial/driver.rst
index 31bd4e16fb1f..06ec04ba086f 100644
--- a/Documentation/driver-api/serial/driver.rst
+++ b/Documentation/driver-api/serial/driver.rst
@@ -311,7 +311,7 @@ hardware.
This call must not sleep
set_ldisc(port,termios)
- Notifier for discipline change. See Documentation/driver-api/serial/tty.rst.
+ Notifier for discipline change. See Documentation/tty/tty_ldisc.rst.
Locking: caller holds tty_port->mutex
diff --git a/Documentation/driver-api/thermal/index.rst b/Documentation/driver-api/thermal/index.rst
index 4cb0b9b6bfb8..030306ffa408 100644
--- a/Documentation/driver-api/thermal/index.rst
+++ b/Documentation/driver-api/thermal/index.rst
@@ -17,3 +17,4 @@ Thermal
intel_powerclamp
nouveau_thermal
x86_pkg_temperature_thermal
+ intel_dptf
diff --git a/Documentation/driver-api/thermal/intel_dptf.rst b/Documentation/driver-api/thermal/intel_dptf.rst
new file mode 100644
index 000000000000..96668dca753a
--- /dev/null
+++ b/Documentation/driver-api/thermal/intel_dptf.rst
@@ -0,0 +1,272 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+===============================================================
+Intel(R) Dynamic Platform and Thermal Framework Sysfs Interface
+===============================================================
+
+:Copyright: |copy| 2022 Intel Corporation
+
+:Author: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
+
+Introduction
+------------
+
+Intel(R) Dynamic Platform and Thermal Framework (DPTF) is a platform
+level hardware/software solution for power and thermal management.
+
+As a container for multiple power/thermal technologies, DPTF provides
+a coordinated approach for different policies to effect the hardware
+state of a system.
+
+Since it is a platform level framework, this has several components.
+Some parts of the technology is implemented in the firmware and uses
+ACPI and PCI devices to expose various features for monitoring and
+control. Linux has a set of kernel drivers exposing hardware interface
+to user space. This allows user space thermal solutions like
+"Linux Thermal Daemon" to read platform specific thermal and power
+tables to deliver adequate performance while keeping the system under
+thermal limits.
+
+DPTF ACPI Drivers interface
+----------------------------
+
+:file:`/sys/bus/platform/devices/<N>/uuids`, where <N>
+=INT3400|INTC1040|INTC1041|INTC10A0
+
+``available_uuids`` (RO)
+ A set of UUIDs strings presenting available policies
+ which should be notified to the firmware when the
+ user space can support those policies.
+
+ UUID strings:
+
+ "42A441D6-AE6A-462b-A84B-4A8CE79027D3" : Passive 1
+
+ "3A95C389-E4B8-4629-A526-C52C88626BAE" : Active
+
+ "97C68AE7-15FA-499c-B8C9-5DA81D606E0A" : Critical
+
+ "63BE270F-1C11-48FD-A6F7-3AF253FF3E2D" : Adaptive performance
+
+ "5349962F-71E6-431D-9AE8-0A635B710AEE" : Emergency call
+
+ "9E04115A-AE87-4D1C-9500-0F3E340BFE75" : Passive 2
+
+ "F5A35014-C209-46A4-993A-EB56DE7530A1" : Power Boss
+
+ "6ED722A7-9240-48A5-B479-31EEF723D7CF" : Virtual Sensor
+
+ "16CAF1B7-DD38-40ED-B1C1-1B8A1913D531" : Cooling mode
+
+ "BE84BABF-C4D4-403D-B495-3128FD44dAC1" : HDC
+
+``current_uuid`` (RW)
+ User space can write strings from available UUIDs, one at a
+ time.
+
+:file:`/sys/bus/platform/devices/<N>/`, where <N>
+=INT3400|INTC1040|INTC1041|INTC10A0
+
+``imok`` (WO)
+ User space daemon write 1 to respond to firmware event
+ for sending keep alive notification. User space receives
+ THERMAL_EVENT_KEEP_ALIVE kobject uevent notification when
+ firmware calls for user space to respond with imok ACPI
+ method.
+
+``odvp*`` (RO)
+ Firmware thermal status variable values. Thermal tables
+ calls for different processing based on these variable
+ values.
+
+``data_vault`` (RO)
+ Binary thermal table. Refer to
+ https:/github.com/intel/thermal_daemon for decoding
+ thermal table.
+
+
+ACPI Thermal Relationship table interface
+------------------------------------------
+
+:file:`/dev/acpi_thermal_rel`
+
+ This device provides IOCTL interface to read standard ACPI
+ thermal relationship tables via ACPI methods _TRT and _ART.
+ These IOCTLs are defined in
+ drivers/thermal/intel/int340x_thermal/acpi_thermal_rel.h
+
+ IOCTLs:
+
+ ACPI_THERMAL_GET_TRT_LEN: Get length of TRT table
+
+ ACPI_THERMAL_GET_ART_LEN: Get length of ART table
+
+ ACPI_THERMAL_GET_TRT_COUNT: Number of records in TRT table
+
+ ACPI_THERMAL_GET_ART_COUNT: Number of records in ART table
+
+ ACPI_THERMAL_GET_TRT: Read binary TRT table, length to read is
+ provided via argument to ioctl().
+
+ ACPI_THERMAL_GET_ART: Read binary ART table, length to read is
+ provided via argument to ioctl().
+
+DPTF ACPI Sensor drivers
+-------------------------
+
+DPTF Sensor drivers are presented as standard thermal sysfs thermal_zone.
+
+
+DPTF ACPI Cooling drivers
+--------------------------
+
+DPTF cooling drivers are presented as standard thermal sysfs cooling_device.
+
+
+DPTF Processor thermal PCI Driver interface
+--------------------------------------------
+
+:file:`/sys/bus/pci/devices/0000\:00\:04.0/power_limits/`
+
+Refer to Documentation/power/powercap/powercap.rst for powercap
+ABI.
+
+``power_limit_0_max_uw`` (RO)
+ Maximum powercap sysfs constraint_0_power_limit_uw for Intel RAPL
+
+``power_limit_0_step_uw`` (RO)
+ Power limit increment/decrements for Intel RAPL constraint 0 power limit
+
+``power_limit_0_min_uw`` (RO)
+ Minimum powercap sysfs constraint_0_power_limit_uw for Intel RAPL
+
+``power_limit_0_tmin_us`` (RO)
+ Minimum powercap sysfs constraint_0_time_window_us for Intel RAPL
+
+``power_limit_0_tmax_us`` (RO)
+ Maximum powercap sysfs constraint_0_time_window_us for Intel RAPL
+
+``power_limit_1_max_uw`` (RO)
+ Maximum powercap sysfs constraint_1_power_limit_uw for Intel RAPL
+
+``power_limit_1_step_uw`` (RO)
+ Power limit increment/decrements for Intel RAPL constraint 1 power limit
+
+``power_limit_1_min_uw`` (RO)
+ Minimum powercap sysfs constraint_1_power_limit_uw for Intel RAPL
+
+``power_limit_1_tmin_us`` (RO)
+ Minimum powercap sysfs constraint_1_time_window_us for Intel RAPL
+
+``power_limit_1_tmax_us`` (RO)
+ Maximum powercap sysfs constraint_1_time_window_us for Intel RAPL
+
+:file:`/sys/bus/pci/devices/0000\:00\:04.0/`
+
+``tcc_offset_degree_celsius`` (RW)
+ TCC offset from the critical temperature where hardware will throttle
+ CPU.
+
+:file:`/sys/bus/pci/devices/0000\:00\:04.0/workload_request`
+
+``workload_available_types`` (RO)
+ Available workload types. User space can specify one of the workload type
+ it is currently executing via workload_type. For example: idle, bursty,
+ sustained etc.
+
+``workload_type`` (RW)
+ User space can specify any one of the available workload type using
+ this interface.
+
+DPTF Processor thermal RFIM interface
+--------------------------------------------
+
+RFIM interface allows adjustment of FIVR (Fully Integrated Voltage Regulator)
+and DDR (Double Data Rate)frequencies to avoid RF interference with WiFi and 5G.
+
+Switching voltage regulators (VR) generate radiated EMI or RFI at the
+fundamental frequency and its harmonics. Some harmonics may interfere
+with very sensitive wireless receivers such as Wi-Fi and cellular that
+are integrated into host systems like notebook PCs. One of mitigation
+methods is requesting SOC integrated VR (IVR) switching frequency to a
+small % and shift away the switching noise harmonic interference from
+radio channels. OEM or ODMs can use the driver to control SOC IVR
+operation within the range where it does not impact IVR performance.
+
+DRAM devices of DDR IO interface and their power plane can generate EMI
+at the data rates. Similar to IVR control mechanism, Intel offers a
+mechanism by which DDR data rates can be changed if several conditions
+are met: there is strong RFI interference because of DDR; CPU power
+management has no other restriction in changing DDR data rates;
+PC ODMs enable this feature (real time DDR RFI Mitigation referred to as
+DDR-RFIM) for Wi-Fi from BIOS.
+
+
+FIVR attributes
+
+:file:`/sys/bus/pci/devices/0000\:00\:04.0/fivr/`
+
+``vco_ref_code_lo`` (RW)
+ The VCO reference code is an 11-bit field and controls the FIVR
+ switching frequency. This is the 3-bit LSB field.
+
+``vco_ref_code_hi`` (RW)
+ The VCO reference code is an 11-bit field and controls the FIVR
+ switching frequency. This is the 8-bit MSB field.
+
+``spread_spectrum_pct`` (RW)
+ Set the FIVR spread spectrum clocking percentage
+
+``spread_spectrum_clk_enable`` (RW)
+ Enable/disable of the FIVR spread spectrum clocking feature
+
+``rfi_vco_ref_code`` (RW)
+ This field is a read only status register which reflects the
+ current FIVR switching frequency
+
+``fivr_fffc_rev`` (RW)
+ This field indicated the revision of the FIVR HW.
+
+
+DVFS attributes
+
+:file:`/sys/bus/pci/devices/0000\:00\:04.0/dvfs/`
+
+``rfi_restriction_run_busy`` (RW)
+ Request the restriction of specific DDR data rate and set this
+ value 1. Self reset to 0 after operation.
+
+``rfi_restriction_err_code`` (RW)
+ 0 :Request is accepted, 1:Feature disabled,
+ 2: the request restricts more points than it is allowed
+
+``rfi_restriction_data_rate_Delta`` (RW)
+ Restricted DDR data rate for RFI protection: Lower Limit
+
+``rfi_restriction_data_rate_Base`` (RW)
+ Restricted DDR data rate for RFI protection: Upper Limit
+
+``ddr_data_rate_point_0`` (RO)
+ DDR data rate selection 1st point
+
+``ddr_data_rate_point_1`` (RO)
+ DDR data rate selection 2nd point
+
+``ddr_data_rate_point_2`` (RO)
+ DDR data rate selection 3rd point
+
+``ddr_data_rate_point_3`` (RO)
+ DDR data rate selection 4th point
+
+``rfi_disable (RW)``
+ Disable DDR rate change feature
+
+DPTF Power supply and Battery Interface
+----------------------------------------
+
+Refer to Documentation/ABI/testing/sysfs-platform-dptf
+
+DPTF Fan Control
+----------------------------------------
+
+Refer to Documentation/admin-guide/acpi/fan_performance_states.rst
diff --git a/Documentation/driver-api/vfio-pci-device-specific-driver-acceptance.rst b/Documentation/driver-api/vfio-pci-device-specific-driver-acceptance.rst
new file mode 100644
index 000000000000..b7b99b876b50
--- /dev/null
+++ b/Documentation/driver-api/vfio-pci-device-specific-driver-acceptance.rst
@@ -0,0 +1,35 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+Acceptance criteria for vfio-pci device specific driver variants
+================================================================
+
+Overview
+--------
+The vfio-pci driver exists as a device agnostic driver using the
+system IOMMU and relying on the robustness of platform fault
+handling to provide isolated device access to userspace. While the
+vfio-pci driver does include some device specific support, further
+extensions for yet more advanced device specific features are not
+sustainable. The vfio-pci driver has therefore split out
+vfio-pci-core as a library that may be reused to implement features
+requiring device specific knowledge, ex. saving and loading device
+state for the purposes of supporting migration.
+
+In support of such features, it's expected that some device specific
+variants may interact with parent devices (ex. SR-IOV PF in support of
+a user assigned VF) or other extensions that may not be otherwise
+accessible via the vfio-pci base driver. Authors of such drivers
+should be diligent not to create exploitable interfaces via these
+interactions or allow unchecked userspace data to have an effect
+beyond the scope of the assigned device.
+
+New driver submissions are therefore requested to have approval via
+sign-off/ack/review/etc for any interactions with parent drivers.
+Additionally, drivers should make an attempt to provide sufficient
+documentation for reviewers to understand the device specific
+extensions, for example in the case of migration data, how is the
+device state composed and consumed, which portions are not otherwise
+available to the user via vfio-pci, what safeguards exist to validate
+the data, etc. To that extent, authors should additionally expect to
+require reviews from at least one of the listed reviewers, in addition
+to the overall vfio maintainer.
diff --git a/Documentation/features/core/cBPF-JIT/arch-support.txt b/Documentation/features/core/cBPF-JIT/arch-support.txt
index e59b5215402d..77bd6974dd6d 100644
--- a/Documentation/features/core/cBPF-JIT/arch-support.txt
+++ b/Documentation/features/core/cBPF-JIT/arch-support.txt
@@ -17,7 +17,6 @@
| m68k: | TODO |
| microblaze: | TODO |
| mips: | ok |
- | nds32: | TODO |
| nios2: | TODO |
| openrisc: | TODO |
| parisc: | TODO |
diff --git a/Documentation/features/core/eBPF-JIT/arch-support.txt b/Documentation/features/core/eBPF-JIT/arch-support.txt
index dcbd8679f514..d5ab547b2be6 100644
--- a/Documentation/features/core/eBPF-JIT/arch-support.txt
+++ b/Documentation/features/core/eBPF-JIT/arch-support.txt
@@ -17,7 +17,6 @@
| m68k: | TODO |
| microblaze: | TODO |
| mips: | ok |
- | nds32: | TODO |
| nios2: | TODO |
| openrisc: | TODO |
| parisc: | TODO |
diff --git a/Documentation/features/core/generic-idle-thread/arch-support.txt b/Documentation/features/core/generic-idle-thread/arch-support.txt
index 4efcba7b5239..ddb3762ca7f5 100644
--- a/Documentation/features/core/generic-idle-thread/arch-support.txt
+++ b/Documentation/features/core/generic-idle-thread/arch-support.txt
@@ -17,7 +17,6 @@
| m68k: | TODO |
| microblaze: | TODO |
| mips: | ok |
- | nds32: | TODO |
| nios2: | TODO |
| openrisc: | ok |
| parisc: | ok |
diff --git a/Documentation/features/core/jump-labels/arch-support.txt b/Documentation/features/core/jump-labels/arch-support.txt
index 0c801d1bd2da..d5380ef68713 100644
--- a/Documentation/features/core/jump-labels/arch-support.txt
+++ b/Documentation/features/core/jump-labels/arch-support.txt
@@ -17,7 +17,6 @@
| m68k: | TODO |
| microblaze: | TODO |
| mips: | ok |
- | nds32: | TODO |
| nios2: | TODO |
| openrisc: | TODO |
| parisc: | ok |
diff --git a/Documentation/features/core/thread-info-in-task/arch-support.txt b/Documentation/features/core/thread-info-in-task/arch-support.txt
index bc74d8beea72..0654ba3a42ff 100644
--- a/Documentation/features/core/thread-info-in-task/arch-support.txt
+++ b/Documentation/features/core/thread-info-in-task/arch-support.txt
@@ -17,7 +17,6 @@
| m68k: | TODO |
| microblaze: | TODO |
| mips: | TODO |
- | nds32: | ok |
| nios2: | TODO |
| openrisc: | TODO |
| parisc: | ok |
diff --git a/Documentation/features/core/tracehook/arch-support.txt b/Documentation/features/core/tracehook/arch-support.txt
index af34308fce7f..8e95dc0c7b90 100644
--- a/Documentation/features/core/tracehook/arch-support.txt
+++ b/Documentation/features/core/tracehook/arch-support.txt
@@ -17,7 +17,6 @@
| m68k: | TODO |
| microblaze: | TODO |
| mips: | ok |
- | nds32: | ok |
| nios2: | ok |
| openrisc: | ok |
| parisc: | ok |
diff --git a/Documentation/features/debug/KASAN/arch-support.txt b/Documentation/features/debug/KASAN/arch-support.txt
index c244ac7eee26..407ca1d91242 100644
--- a/Documentation/features/debug/KASAN/arch-support.txt
+++ b/Documentation/features/debug/KASAN/arch-support.txt
@@ -17,7 +17,6 @@
| m68k: | TODO |
| microblaze: | TODO |
| mips: | TODO |
- | nds32: | TODO |
| nios2: | TODO |
| openrisc: | TODO |
| parisc: | TODO |
diff --git a/Documentation/features/debug/debug-vm-pgtable/arch-support.txt b/Documentation/features/debug/debug-vm-pgtable/arch-support.txt
index fa83403b4aec..83eafe1a7f68 100644
--- a/Documentation/features/debug/debug-vm-pgtable/arch-support.txt
+++ b/Documentation/features/debug/debug-vm-pgtable/arch-support.txt
@@ -17,7 +17,6 @@
| m68k: | TODO |
| microblaze: | TODO |
| mips: | TODO |
- | nds32: | TODO |
| nios2: | TODO |
| openrisc: | TODO |
| parisc: | TODO |
diff --git a/Documentation/features/debug/gcov-profile-all/arch-support.txt b/Documentation/features/debug/gcov-profile-all/arch-support.txt
index b39c1a5de3f3..49e0dda11227 100644
--- a/Documentation/features/debug/gcov-profile-all/arch-support.txt
+++ b/Documentation/features/debug/gcov-profile-all/arch-support.txt
@@ -17,7 +17,6 @@
| m68k: | TODO |
| microblaze: | ok |
| mips: | ok |
- | nds32: | TODO |
| nios2: | TODO |
| openrisc: | TODO |
| parisc: | TODO |
diff --git a/Documentation/features/debug/kcov/arch-support.txt b/Documentation/features/debug/kcov/arch-support.txt
index 7e44013cc320..3d34b724ddae 100644
--- a/Documentation/features/debug/kcov/arch-support.txt
+++ b/Documentation/features/debug/kcov/arch-support.txt
@@ -17,7 +17,6 @@
| m68k: | TODO |
| microblaze: | TODO |
| mips: | ok |
- | nds32: | TODO |
| nios2: | TODO |
| openrisc: | TODO |
| parisc: | TODO |
diff --git a/Documentation/features/debug/kgdb/arch-support.txt b/Documentation/features/debug/kgdb/arch-support.txt
index 2cb0576f9180..7aa073d908c5 100644
--- a/Documentation/features/debug/kgdb/arch-support.txt
+++ b/Documentation/features/debug/kgdb/arch-support.txt
@@ -17,7 +17,6 @@
| m68k: | TODO |
| microblaze: | ok |
| mips: | ok |
- | nds32: | TODO |
| nios2: | ok |
| openrisc: | TODO |
| parisc: | ok |
diff --git a/Documentation/features/debug/kmemleak/arch-support.txt b/Documentation/features/debug/kmemleak/arch-support.txt
index e9ac415f8aec..5c784ff9768a 100644
--- a/Documentation/features/debug/kmemleak/arch-support.txt
+++ b/Documentation/features/debug/kmemleak/arch-support.txt
@@ -17,7 +17,6 @@
| m68k: | TODO |
| microblaze: | ok |
| mips: | ok |
- | nds32: | ok |
| nios2: | TODO |
| openrisc: | TODO |
| parisc: | TODO |
diff --git a/Documentation/features/debug/kprobes-on-ftrace/arch-support.txt b/Documentation/features/debug/kprobes-on-ftrace/arch-support.txt
index 96156e8802a7..a1f6e98c6b1f 100644
--- a/Documentation/features/debug/kprobes-on-ftrace/arch-support.txt
+++ b/Documentation/features/debug/kprobes-on-ftrace/arch-support.txt
@@ -17,7 +17,6 @@
| m68k: | TODO |
| microblaze: | TODO |
| mips: | TODO |
- | nds32: | TODO |
| nios2: | TODO |
| openrisc: | TODO |
| parisc: | ok |
diff --git a/Documentation/features/debug/kprobes/arch-support.txt b/Documentation/features/debug/kprobes/arch-support.txt
index ee95ed61909a..e7e7015175e7 100644
--- a/Documentation/features/debug/kprobes/arch-support.txt
+++ b/Documentation/features/debug/kprobes/arch-support.txt
@@ -17,7 +17,6 @@
| m68k: | TODO |
| microblaze: | TODO |
| mips: | ok |
- | nds32: | TODO |
| nios2: | TODO |
| openrisc: | TODO |
| parisc: | ok |
diff --git a/Documentation/features/debug/kretprobes/arch-support.txt b/Documentation/features/debug/kretprobes/arch-support.txt
index 612cb97d47b8..838eb53a6fa5 100644
--- a/Documentation/features/debug/kretprobes/arch-support.txt
+++ b/Documentation/features/debug/kretprobes/arch-support.txt
@@ -17,7 +17,6 @@
| m68k: | TODO |
| microblaze: | TODO |
| mips: | ok |
- | nds32: | TODO |
| nios2: | TODO |
| openrisc: | TODO |
| parisc: | ok |
diff --git a/Documentation/features/debug/optprobes/arch-support.txt b/Documentation/features/debug/optprobes/arch-support.txt
index d6ff141a6122..6358b00b1723 100644
--- a/Documentation/features/debug/optprobes/arch-support.txt
+++ b/Documentation/features/debug/optprobes/arch-support.txt
@@ -17,7 +17,6 @@
| m68k: | TODO |
| microblaze: | TODO |
| mips: | TODO |
- | nds32: | TODO |
| nios2: | TODO |
| openrisc: | TODO |
| parisc: | TODO |
diff --git a/Documentation/features/debug/stackprotector/arch-support.txt b/Documentation/features/debug/stackprotector/arch-support.txt
index ad4de22a71ab..f6cdf781305f 100644
--- a/Documentation/features/debug/stackprotector/arch-support.txt
+++ b/Documentation/features/debug/stackprotector/arch-support.txt
@@ -17,7 +17,6 @@
| m68k: | TODO |
| microblaze: | TODO |
| mips: | ok |
- | nds32: | TODO |
| nios2: | TODO |
| openrisc: | TODO |
| parisc: | TODO |
diff --git a/Documentation/features/debug/uprobes/arch-support.txt b/Documentation/features/debug/uprobes/arch-support.txt
index 8bd5548a4485..0b871e797d24 100644
--- a/Documentation/features/debug/uprobes/arch-support.txt
+++ b/Documentation/features/debug/uprobes/arch-support.txt
@@ -17,7 +17,6 @@
| m68k: | TODO |
| microblaze: | TODO |
| mips: | ok |
- | nds32: | TODO |
| nios2: | TODO |
| openrisc: | TODO |
| parisc: | TODO |
diff --git a/Documentation/features/debug/user-ret-profiler/arch-support.txt b/Documentation/features/debug/user-ret-profiler/arch-support.txt
index 2a3fe812a5fa..a2feda7adff1 100644
--- a/Documentation/features/debug/user-ret-profiler/arch-support.txt
+++ b/Documentation/features/debug/user-ret-profiler/arch-support.txt
@@ -17,7 +17,6 @@
| m68k: | TODO |
| microblaze: | TODO |
| mips: | TODO |
- | nds32: | TODO |
| nios2: | TODO |
| openrisc: | TODO |
| parisc: | TODO |
diff --git a/Documentation/features/io/dma-contiguous/arch-support.txt b/Documentation/features/io/dma-contiguous/arch-support.txt
index bece89586efa..9b407f26d45e 100644
--- a/Documentation/features/io/dma-contiguous/arch-support.txt
+++ b/Documentation/features/io/dma-contiguous/arch-support.txt
@@ -17,7 +17,6 @@
| m68k: | TODO |
| microblaze: | ok |
| mips: | ok |
- | nds32: | TODO |
| nios2: | TODO |
| openrisc: | TODO |
| parisc: | TODO |
diff --git a/Documentation/features/locking/cmpxchg-local/arch-support.txt b/Documentation/features/locking/cmpxchg-local/arch-support.txt
index 52bdda004f5c..090520b0e02d 100644
--- a/Documentation/features/locking/cmpxchg-local/arch-support.txt
+++ b/Documentation/features/locking/cmpxchg-local/arch-support.txt
@@ -17,7 +17,6 @@
| m68k: | TODO |
| microblaze: | TODO |
| mips: | TODO |
- | nds32: | TODO |
| nios2: | TODO |
| openrisc: | TODO |
| parisc: | TODO |
diff --git a/Documentation/features/locking/lockdep/arch-support.txt b/Documentation/features/locking/lockdep/arch-support.txt
index a8cd163c8b7e..6d840b103537 100644
--- a/Documentation/features/locking/lockdep/arch-support.txt
+++ b/Documentation/features/locking/lockdep/arch-support.txt
@@ -17,7 +17,6 @@
| m68k: | TODO |
| microblaze: | ok |
| mips: | ok |
- | nds32: | ok |
| nios2: | TODO |
| openrisc: | ok |
| parisc: | TODO |
diff --git a/Documentation/features/locking/queued-rwlocks/arch-support.txt b/Documentation/features/locking/queued-rwlocks/arch-support.txt
index 8c85949752b3..de586be05d64 100644
--- a/Documentation/features/locking/queued-rwlocks/arch-support.txt
+++ b/Documentation/features/locking/queued-rwlocks/arch-support.txt
@@ -17,7 +17,6 @@
| m68k: | TODO |
| microblaze: | TODO |
| mips: | ok |
- | nds32: | TODO |
| nios2: | TODO |
| openrisc: | ok |
| parisc: | TODO |
diff --git a/Documentation/features/locking/queued-spinlocks/arch-support.txt b/Documentation/features/locking/queued-spinlocks/arch-support.txt
index 5f4e1b3841af..29d0c8b7b1c5 100644
--- a/Documentation/features/locking/queued-spinlocks/arch-support.txt
+++ b/Documentation/features/locking/queued-spinlocks/arch-support.txt
@@ -17,7 +17,6 @@
| m68k: | TODO |
| microblaze: | TODO |
| mips: | ok |
- | nds32: | TODO |
| nios2: | TODO |
| openrisc: | ok |
| parisc: | TODO |
diff --git a/Documentation/features/perf/kprobes-event/arch-support.txt b/Documentation/features/perf/kprobes-event/arch-support.txt
index 78f3fe080f0e..881a8a50e41e 100644
--- a/Documentation/features/perf/kprobes-event/arch-support.txt
+++ b/Documentation/features/perf/kprobes-event/arch-support.txt
@@ -17,7 +17,6 @@
| m68k: | TODO |
| microblaze: | TODO |
| mips: | ok |
- | nds32: | ok |
| nios2: | TODO |
| openrisc: | TODO |
| parisc: | ok |
diff --git a/Documentation/features/perf/perf-regs/arch-support.txt b/Documentation/features/perf/perf-regs/arch-support.txt
index 5bf3b1854a1f..7639a796a8e1 100644
--- a/Documentation/features/perf/perf-regs/arch-support.txt
+++ b/Documentation/features/perf/perf-regs/arch-support.txt
@@ -17,7 +17,6 @@
| m68k: | TODO |
| microblaze: | TODO |
| mips: | ok |
- | nds32: | TODO |
| nios2: | TODO |
| openrisc: | TODO |
| parisc: | TODO |
diff --git a/Documentation/features/perf/perf-stackdump/arch-support.txt b/Documentation/features/perf/perf-stackdump/arch-support.txt
index d88659bb4fc1..df1a4c679a45 100644
--- a/Documentation/features/perf/perf-stackdump/arch-support.txt
+++ b/Documentation/features/perf/perf-stackdump/arch-support.txt
@@ -17,7 +17,6 @@
| m68k: | TODO |
| microblaze: | TODO |
| mips: | ok |
- | nds32: | TODO |
| nios2: | TODO |
| openrisc: | TODO |
| parisc: | TODO |
diff --git a/Documentation/features/sched/membarrier-sync-core/arch-support.txt b/Documentation/features/sched/membarrier-sync-core/arch-support.txt
index 883d33b265d6..51b7afc937f1 100644
--- a/Documentation/features/sched/membarrier-sync-core/arch-support.txt
+++ b/Documentation/features/sched/membarrier-sync-core/arch-support.txt
@@ -40,7 +40,6 @@
| m68k: | TODO |
| microblaze: | TODO |
| mips: | TODO |
- | nds32: | TODO |
| nios2: | TODO |
| openrisc: | TODO |
| parisc: | TODO |
diff --git a/Documentation/features/sched/numa-balancing/arch-support.txt b/Documentation/features/sched/numa-balancing/arch-support.txt
index 9affb7c2c500..d0e308135434 100644
--- a/Documentation/features/sched/numa-balancing/arch-support.txt
+++ b/Documentation/features/sched/numa-balancing/arch-support.txt
@@ -17,7 +17,6 @@
| m68k: | .. |
| microblaze: | .. |
| mips: | TODO |
- | nds32: | TODO |
| nios2: | .. |
| openrisc: | .. |
| parisc: | .. |
diff --git a/Documentation/features/seccomp/seccomp-filter/arch-support.txt b/Documentation/features/seccomp/seccomp-filter/arch-support.txt
index 26eec58ab819..05613c5ff560 100644
--- a/Documentation/features/seccomp/seccomp-filter/arch-support.txt
+++ b/Documentation/features/seccomp/seccomp-filter/arch-support.txt
@@ -17,7 +17,6 @@
| m68k: | TODO |
| microblaze: | TODO |
| mips: | ok |
- | nds32: | TODO |
| nios2: | TODO |
| openrisc: | TODO |
| parisc: | ok |
diff --git a/Documentation/features/time/arch-tick-broadcast/arch-support.txt b/Documentation/features/time/arch-tick-broadcast/arch-support.txt
index 8dcaab070c7b..b4c96ebab7e3 100644
--- a/Documentation/features/time/arch-tick-broadcast/arch-support.txt
+++ b/Documentation/features/time/arch-tick-broadcast/arch-support.txt
@@ -17,7 +17,6 @@
| m68k: | TODO |
| microblaze: | TODO |
| mips: | ok |
- | nds32: | TODO |
| nios2: | TODO |
| openrisc: | TODO |
| parisc: | TODO |
diff --git a/Documentation/features/time/clockevents/arch-support.txt b/Documentation/features/time/clockevents/arch-support.txt
index 9a81cb03b1fd..3f6976052e2a 100644
--- a/Documentation/features/time/clockevents/arch-support.txt
+++ b/Documentation/features/time/clockevents/arch-support.txt
@@ -17,7 +17,6 @@
| m68k: | TODO |
| microblaze: | ok |
| mips: | ok |
- | nds32: | ok |
| nios2: | ok |
| openrisc: | ok |
| parisc: | TODO |
diff --git a/Documentation/features/time/context-tracking/arch-support.txt b/Documentation/features/time/context-tracking/arch-support.txt
index 4ed116c2ec39..bb1c1801553e 100644
--- a/Documentation/features/time/context-tracking/arch-support.txt
+++ b/Documentation/features/time/context-tracking/arch-support.txt
@@ -17,7 +17,6 @@
| m68k: | TODO |
| microblaze: | TODO |
| mips: | ok |
- | nds32: | TODO |
| nios2: | TODO |
| openrisc: | TODO |
| parisc: | TODO |
diff --git a/Documentation/features/time/irq-time-acct/arch-support.txt b/Documentation/features/time/irq-time-acct/arch-support.txt
index bc30c15557c7..3cea25b80c8c 100644
--- a/Documentation/features/time/irq-time-acct/arch-support.txt
+++ b/Documentation/features/time/irq-time-acct/arch-support.txt
@@ -17,7 +17,6 @@
| m68k: | TODO |
| microblaze: | TODO |
| mips: | ok |
- | nds32: | TODO |
| nios2: | TODO |
| openrisc: | TODO |
| parisc: | .. |
diff --git a/Documentation/features/time/virt-cpuacct/arch-support.txt b/Documentation/features/time/virt-cpuacct/arch-support.txt
index 050de43bbbb9..5163a60a1c1e 100644
--- a/Documentation/features/time/virt-cpuacct/arch-support.txt
+++ b/Documentation/features/time/virt-cpuacct/arch-support.txt
@@ -17,7 +17,6 @@
| m68k: | TODO |
| microblaze: | TODO |
| mips: | ok |
- | nds32: | TODO |
| nios2: | TODO |
| openrisc: | TODO |
| parisc: | ok |
diff --git a/Documentation/features/vm/ELF-ASLR/arch-support.txt b/Documentation/features/vm/ELF-ASLR/arch-support.txt
index 2949c99fbb2f..73ec761f1e27 100644
--- a/Documentation/features/vm/ELF-ASLR/arch-support.txt
+++ b/Documentation/features/vm/ELF-ASLR/arch-support.txt
@@ -17,7 +17,6 @@
| m68k: | TODO |
| microblaze: | TODO |
| mips: | ok |
- | nds32: | TODO |
| nios2: | TODO |
| openrisc: | TODO |
| parisc: | ok |
diff --git a/Documentation/features/vm/PG_uncached/arch-support.txt b/Documentation/features/vm/PG_uncached/arch-support.txt
index 6cde38458596..9066a90b38d9 100644
--- a/Documentation/features/vm/PG_uncached/arch-support.txt
+++ b/Documentation/features/vm/PG_uncached/arch-support.txt
@@ -17,7 +17,6 @@
| m68k: | TODO |
| microblaze: | TODO |
| mips: | TODO |
- | nds32: | TODO |
| nios2: | TODO |
| openrisc: | TODO |
| parisc: | TODO |
diff --git a/Documentation/features/vm/THP/arch-support.txt b/Documentation/features/vm/THP/arch-support.txt
index 7dbd6967b37e..f717ab792e5a 100644
--- a/Documentation/features/vm/THP/arch-support.txt
+++ b/Documentation/features/vm/THP/arch-support.txt
@@ -17,7 +17,6 @@
| m68k: | .. |
| microblaze: | .. |
| mips: | ok |
- | nds32: | TODO |
| nios2: | .. |
| openrisc: | .. |
| parisc: | TODO |
diff --git a/Documentation/features/vm/TLB/arch-support.txt b/Documentation/features/vm/TLB/arch-support.txt
index e1c3a4c4d107..6fa76a37f299 100644
--- a/Documentation/features/vm/TLB/arch-support.txt
+++ b/Documentation/features/vm/TLB/arch-support.txt
@@ -17,7 +17,6 @@
| m68k: | .. |
| microblaze: | .. |
| mips: | TODO |
- | nds32: | TODO |
| nios2: | .. |
| openrisc: | .. |
| parisc: | TODO |
diff --git a/Documentation/features/vm/huge-vmap/arch-support.txt b/Documentation/features/vm/huge-vmap/arch-support.txt
index bc53905a0306..6e1792ee37fe 100644
--- a/Documentation/features/vm/huge-vmap/arch-support.txt
+++ b/Documentation/features/vm/huge-vmap/arch-support.txt
@@ -17,7 +17,6 @@
| m68k: | TODO |
| microblaze: | TODO |
| mips: | TODO |
- | nds32: | TODO |
| nios2: | TODO |
| openrisc: | TODO |
| parisc: | TODO |
diff --git a/Documentation/features/vm/ioremap_prot/arch-support.txt b/Documentation/features/vm/ioremap_prot/arch-support.txt
index 9a0c8783b84d..a6dcbe5f47b6 100644
--- a/Documentation/features/vm/ioremap_prot/arch-support.txt
+++ b/Documentation/features/vm/ioremap_prot/arch-support.txt
@@ -17,7 +17,6 @@
| m68k: | TODO |
| microblaze: | TODO |
| mips: | ok |
- | nds32: | TODO |
| nios2: | TODO |
| openrisc: | TODO |
| parisc: | TODO |
diff --git a/Documentation/features/vm/pte_special/arch-support.txt b/Documentation/features/vm/pte_special/arch-support.txt
index 40b969f3a6bb..376477749c42 100644
--- a/Documentation/features/vm/pte_special/arch-support.txt
+++ b/Documentation/features/vm/pte_special/arch-support.txt
@@ -17,7 +17,6 @@
| m68k: | TODO |
| microblaze: | TODO |
| mips: | ok |
- | nds32: | TODO |
| nios2: | TODO |
| openrisc: | TODO |
| parisc: | TODO |
diff --git a/Documentation/filesystems/caching/netfs-api.rst b/Documentation/filesystems/caching/netfs-api.rst
index f84e9ffdf0b4..5066113acad5 100644
--- a/Documentation/filesystems/caching/netfs-api.rst
+++ b/Documentation/filesystems/caching/netfs-api.rst
@@ -345,8 +345,9 @@ The following facilities are provided to manage this:
To support this, the following functions are provided::
- int fscache_set_page_dirty(struct page *page,
- struct fscache_cookie *cookie);
+ bool fscache_dirty_folio(struct address_space *mapping,
+ struct folio *folio,
+ struct fscache_cookie *cookie);
void fscache_unpin_writeback(struct writeback_control *wbc,
struct fscache_cookie *cookie);
void fscache_clear_inode_writeback(struct fscache_cookie *cookie,
@@ -354,7 +355,7 @@ To support this, the following functions are provided::
const void *aux);
The *set* function is intended to be called from the filesystem's
-``set_page_dirty`` address space operation. If ``I_PINNING_FSCACHE_WB`` is not
+``dirty_folio`` address space operation. If ``I_PINNING_FSCACHE_WB`` is not
set, it sets that flag and increments the use count on the cookie (the caller
must already have called ``fscache_use_cookie()``).
diff --git a/Documentation/filesystems/dax.rst b/Documentation/filesystems/dax.rst
index e3b30429d703..c04609d8ee24 100644
--- a/Documentation/filesystems/dax.rst
+++ b/Documentation/filesystems/dax.rst
@@ -23,11 +23,11 @@ on it as usual. The `DAX` code currently only supports files with a block
size equal to your kernel's `PAGE_SIZE`, so you may need to specify a block
size when creating the filesystem.
-Currently 4 filesystems support `DAX`: ext2, ext4, xfs and virtiofs.
+Currently 5 filesystems support `DAX`: ext2, ext4, xfs, virtiofs and erofs.
Enabling `DAX` on them is different.
-Enabling DAX on ext2
---------------------
+Enabling DAX on ext2 and erofs
+------------------------------
When mounting the filesystem, use the ``-o dax`` option on the command line or
add 'dax' to the options in ``/etc/fstab``. This works to enable `DAX` on all files
diff --git a/Documentation/filesystems/erofs.rst b/Documentation/filesystems/erofs.rst
index 7119aa213be7..bef6d3040ce4 100644
--- a/Documentation/filesystems/erofs.rst
+++ b/Documentation/filesystems/erofs.rst
@@ -40,7 +40,7 @@ Here is the main features of EROFS:
Inode metadata size 32 bytes 64 bytes
Max file size 4 GB 16 EB (also limited by max. vol size)
Max uids/gids 65536 4294967296
- File change time no yes (64 + 32-bit timestamp)
+ Per-inode timestamp no yes (64 + 32-bit timestamp)
Max hardlinks 65536 4294967296
Metadata reserved 4 bytes 14 bytes
===================== ============ =====================================
diff --git a/Documentation/filesystems/ext4/blocks.rst b/Documentation/filesystems/ext4/blocks.rst
index bd722ecd92d6..b0f80ea87c90 100644
--- a/Documentation/filesystems/ext4/blocks.rst
+++ b/Documentation/filesystems/ext4/blocks.rst
@@ -39,7 +39,7 @@ For 32-bit filesystems, limits are as follows:
- 4TiB
- 8TiB
- 16TiB
- - 256PiB
+ - 256TiB
* - Blocks Per Block Group
- 8,192
- 16,384
diff --git a/Documentation/filesystems/fscrypt.rst b/Documentation/filesystems/fscrypt.rst
index 4d5d50dca65c..6ccd5efb25b7 100644
--- a/Documentation/filesystems/fscrypt.rst
+++ b/Documentation/filesystems/fscrypt.rst
@@ -1047,8 +1047,8 @@ astute users may notice some differences in behavior:
may be used to overwrite the source files but isn't guaranteed to be
effective on all filesystems and storage devices.
-- Direct I/O is not supported on encrypted files. Attempts to use
- direct I/O on such files will fall back to buffered I/O.
+- Direct I/O is supported on encrypted files only under some
+ circumstances. For details, see `Direct I/O support`_.
- The fallocate operations FALLOC_FL_COLLAPSE_RANGE and
FALLOC_FL_INSERT_RANGE are not supported on encrypted files and will
@@ -1179,6 +1179,27 @@ Inline encryption doesn't affect the ciphertext or other aspects of
the on-disk format, so users may freely switch back and forth between
using "inlinecrypt" and not using "inlinecrypt".
+Direct I/O support
+==================
+
+For direct I/O on an encrypted file to work, the following conditions
+must be met (in addition to the conditions for direct I/O on an
+unencrypted file):
+
+* The file must be using inline encryption. Usually this means that
+ the filesystem must be mounted with ``-o inlinecrypt`` and inline
+ encryption hardware must be present. However, a software fallback
+ is also available. For details, see `Inline encryption support`_.
+
+* The I/O request must be fully aligned to the filesystem block size.
+ This means that the file position the I/O is targeting, the lengths
+ of all I/O segments, and the memory addresses of all I/O buffers
+ must be multiples of this value. Note that the filesystem block
+ size may be greater than the logical block size of the block device.
+
+If either of the above conditions is not met, then direct I/O on the
+encrypted file will fall back to buffered I/O.
+
Implementation details
======================
diff --git a/Documentation/filesystems/locking.rst b/Documentation/filesystems/locking.rst
index 3f9b1497ebb8..2998cec9af4b 100644
--- a/Documentation/filesystems/locking.rst
+++ b/Documentation/filesystems/locking.rst
@@ -239,7 +239,7 @@ prototypes::
int (*writepage)(struct page *page, struct writeback_control *wbc);
int (*readpage)(struct file *, struct page *);
int (*writepages)(struct address_space *, struct writeback_control *);
- int (*set_page_dirty)(struct page *page);
+ bool (*dirty_folio)(struct address_space *, struct folio *folio);
void (*readahead)(struct readahead_control *);
int (*readpages)(struct file *filp, struct address_space *mapping,
struct list_head *pages, unsigned nr_pages);
@@ -250,21 +250,21 @@ prototypes::
loff_t pos, unsigned len, unsigned copied,
struct page *page, void *fsdata);
sector_t (*bmap)(struct address_space *, sector_t);
- void (*invalidatepage) (struct page *, unsigned int, unsigned int);
+ void (*invalidate_folio) (struct folio *, size_t start, size_t len);
int (*releasepage) (struct page *, int);
void (*freepage)(struct page *);
int (*direct_IO)(struct kiocb *, struct iov_iter *iter);
bool (*isolate_page) (struct page *, isolate_mode_t);
int (*migratepage)(struct address_space *, struct page *, struct page *);
void (*putback_page) (struct page *);
- int (*launder_page)(struct page *);
- int (*is_partially_uptodate)(struct page *, unsigned long, unsigned long);
+ int (*launder_folio)(struct folio *);
+ bool (*is_partially_uptodate)(struct folio *, size_t from, size_t count);
int (*error_remove_page)(struct address_space *, struct page *);
int (*swap_activate)(struct file *);
int (*swap_deactivate)(struct file *);
locking rules:
- All except set_page_dirty and freepage may block
+ All except dirty_folio and freepage may block
====================== ======================== ========= ===============
ops PageLocked(page) i_rwsem invalidate_lock
@@ -272,20 +272,20 @@ ops PageLocked(page) i_rwsem invalidate_lock
writepage: yes, unlocks (see below)
readpage: yes, unlocks shared
writepages:
-set_page_dirty no
+dirty_folio maybe
readahead: yes, unlocks shared
readpages: no shared
write_begin: locks the page exclusive
write_end: yes, unlocks exclusive
bmap:
-invalidatepage: yes exclusive
+invalidate_folio: yes exclusive
releasepage: yes
freepage: yes
direct_IO:
isolate_page: yes
migratepage: yes (both)
putback_page: yes
-launder_page: yes
+launder_folio: yes
is_partially_uptodate: yes
error_remove_page: yes
swap_activate: no
@@ -361,22 +361,22 @@ If nr_to_write is NULL, all dirty pages must be written.
writepages should _only_ write pages which are present on
mapping->io_pages.
-->set_page_dirty() is called from various places in the kernel
-when the target page is marked as needing writeback. It may be called
-under spinlock (it cannot block) and is sometimes called with the page
-not locked.
+->dirty_folio() is called from various places in the kernel when
+the target folio is marked as needing writeback. The folio cannot be
+truncated because either the caller holds the folio lock, or the caller
+has found the folio while holding the page table lock which will block
+truncation.
->bmap() is currently used by legacy ioctl() (FIBMAP) provided by some
filesystems and by the swapper. The latter will eventually go away. Please,
keep it that way and don't breed new callers.
-->invalidatepage() is called when the filesystem must attempt to drop
+->invalidate_folio() is called when the filesystem must attempt to drop
some or all of the buffers from the page when it is being truncated. It
-returns zero on success. If ->invalidatepage is zero, the kernel uses
-block_invalidatepage() instead. The filesystem must exclusively acquire
-invalidate_lock before invalidating page cache in truncate / hole punch path
-(and thus calling into ->invalidatepage) to block races between page cache
-invalidation and page cache filling functions (fault, read, ...).
+returns zero on success. The filesystem must exclusively acquire
+invalidate_lock before invalidating page cache in truncate / hole punch
+path (and thus calling into ->invalidate_folio) to block races between page
+cache invalidation and page cache filling functions (fault, read, ...).
->releasepage() is called when the kernel is about to try to drop the
buffers from the page in preparation for freeing it. It returns zero to
@@ -386,9 +386,9 @@ the kernel assumes that the fs has no private interest in the buffers.
->freepage() is called when the kernel is done dropping the page
from the page cache.
-->launder_page() may be called prior to releasing a page if
-it is still found to be dirty. It returns zero if the page was successfully
-cleaned, or an error value if not. Note that in order to prevent the page
+->launder_folio() may be called prior to releasing a folio if
+it is still found to be dirty. It returns zero if the folio was successfully
+cleaned, or an error value if not. Note that in order to prevent the folio
getting mapped back in and redirtied, it needs to be kept locked
across the entire operation.
@@ -438,13 +438,13 @@ prototypes::
locking rules:
====================== ============= ================= =========
-ops inode->i_lock blocked_lock_lock may block
+ops flc_lock blocked_lock_lock may block
====================== ============= ================= =========
-lm_notify: yes yes no
+lm_notify: no yes no
lm_grant: no no no
lm_break: yes no no
lm_change yes no no
-lm_breaker_owns_lease: no no no
+lm_breaker_owns_lease: yes no no
====================== ============= ================= =========
buffer_head
diff --git a/Documentation/filesystems/netfs_library.rst b/Documentation/filesystems/netfs_library.rst
index 136f8da3d0e2..4f373a8ec47b 100644
--- a/Documentation/filesystems/netfs_library.rst
+++ b/Documentation/filesystems/netfs_library.rst
@@ -462,6 +462,10 @@ operation table looks like the following::
struct iov_iter *iter,
netfs_io_terminated_t term_func,
void *term_func_priv);
+
+ int (*query_occupancy)(struct netfs_cache_resources *cres,
+ loff_t start, size_t len, size_t granularity,
+ loff_t *_data_start, size_t *_data_len);
};
With a termination handler function pointer::
@@ -536,6 +540,18 @@ The methods defined in the table are:
indicating whether the termination is definitely happening in the caller's
context.
+ * ``query_occupancy()``
+
+ [Required] Called to find out where the next piece of data is within a
+ particular region of the cache. The start and length of the region to be
+ queried are passed in, along with the granularity to which the answer needs
+ to be aligned. The function passes back the start and length of the data,
+ if any, available within that region. Note that there may be a hole at the
+ front.
+
+ It returns 0 if some data was found, -ENODATA if there was no usable data
+ within the region or -ENOBUFS if there is no caching on this file.
+
Note that these methods are passed a pointer to the cache resource structure,
not the read request structure as they could be used in other situations where
there isn't a read request structure as well, such as writing dirty data to the
diff --git a/Documentation/filesystems/porting.rst b/Documentation/filesystems/porting.rst
index bf19fd6b86e7..7c1583dbeb59 100644
--- a/Documentation/filesystems/porting.rst
+++ b/Documentation/filesystems/porting.rst
@@ -45,6 +45,12 @@ typically between calling iget_locked() and unlocking the inode.
At some point that will become mandatory.
+**mandatory**
+
+The foo_inode_info should always be allocated through alloc_inode_sb() rather
+than kmem_cache_alloc() or kmalloc() related to set up the inode reclaim context
+correctly.
+
---
**mandatory**
diff --git a/Documentation/filesystems/vfs.rst b/Documentation/filesystems/vfs.rst
index bf5c48066fac..4f14edf93941 100644
--- a/Documentation/filesystems/vfs.rst
+++ b/Documentation/filesystems/vfs.rst
@@ -658,7 +658,7 @@ pages, however the address_space has finer control of write sizes.
The read process essentially only requires 'readpage'. The write
process is more complicated and uses write_begin/write_end or
-set_page_dirty to write data into the address_space, and writepage and
+dirty_folio to write data into the address_space, and writepage and
writepages to writeback data to storage.
Adding and removing pages to/from an address_space is protected by the
@@ -724,7 +724,7 @@ cache in your filesystem. The following members are defined:
int (*writepage)(struct page *page, struct writeback_control *wbc);
int (*readpage)(struct file *, struct page *);
int (*writepages)(struct address_space *, struct writeback_control *);
- int (*set_page_dirty)(struct page *page);
+ bool (*dirty_folio)(struct address_space *, struct folio *);
void (*readahead)(struct readahead_control *);
int (*readpages)(struct file *filp, struct address_space *mapping,
struct list_head *pages, unsigned nr_pages);
@@ -735,7 +735,7 @@ cache in your filesystem. The following members are defined:
loff_t pos, unsigned len, unsigned copied,
struct page *page, void *fsdata);
sector_t (*bmap)(struct address_space *, sector_t);
- void (*invalidatepage) (struct page *, unsigned int, unsigned int);
+ void (*invalidate_folio) (struct folio *, size_t start, size_t len);
int (*releasepage) (struct page *, int);
void (*freepage)(struct page *);
ssize_t (*direct_IO)(struct kiocb *, struct iov_iter *iter);
@@ -745,10 +745,10 @@ cache in your filesystem. The following members are defined:
int (*migratepage) (struct page *, struct page *);
/* put migration-failed page back to right list */
void (*putback_page) (struct page *);
- int (*launder_page) (struct page *);
+ int (*launder_folio) (struct folio *);
- int (*is_partially_uptodate) (struct page *, unsigned long,
- unsigned long);
+ bool (*is_partially_uptodate) (struct folio *, size_t from,
+ size_t count);
void (*is_dirty_writeback) (struct page *, bool *, bool *);
int (*error_remove_page) (struct mapping *mapping, struct page *page);
int (*swap_activate)(struct file *);
@@ -793,25 +793,29 @@ cache in your filesystem. The following members are defined:
This will choose pages from the address space that are tagged as
DIRTY and will pass them to ->writepage.
-``set_page_dirty``
- called by the VM to set a page dirty. This is particularly
- needed if an address space attaches private data to a page, and
- that data needs to be updated when a page is dirtied. This is
+``dirty_folio``
+ called by the VM to mark a folio as dirty. This is particularly
+ needed if an address space attaches private data to a folio, and
+ that data needs to be updated when a folio is dirtied. This is
called, for example, when a memory mapped page gets modified.
- If defined, it should set the PageDirty flag, and the
- PAGECACHE_TAG_DIRTY tag in the radix tree.
+ If defined, it should set the folio dirty flag, and the
+ PAGECACHE_TAG_DIRTY search mark in i_pages.
``readahead``
Called by the VM to read pages associated with the address_space
object. The pages are consecutive in the page cache and are
locked. The implementation should decrement the page refcount
after starting I/O on each page. Usually the page will be
- unlocked by the I/O completion handler. If the filesystem decides
- to stop attempting I/O before reaching the end of the readahead
- window, it can simply return. The caller will decrement the page
- refcount and unlock the remaining pages for you. Set PageUptodate
- if the I/O completes successfully. Setting PageError on any page
- will be ignored; simply unlock the page if an I/O error occurs.
+ unlocked by the I/O completion handler. The set of pages are
+ divided into some sync pages followed by some async pages,
+ rac->ra->async_size gives the number of async pages. The
+ filesystem should attempt to read all sync pages but may decide
+ to stop once it reaches the async pages. If it does decide to
+ stop attempting I/O, it can simply return. The caller will
+ remove the remaining pages from the address space, unlock them
+ and decrement the page refcount. Set PageUptodate if the I/O
+ completes successfully. Setting PageError on any page will be
+ ignored; simply unlock the page if an I/O error occurs.
``readpages``
called by the VM to read pages associated with the address_space
@@ -868,15 +872,15 @@ cache in your filesystem. The following members are defined:
to find out where the blocks in the file are and uses those
addresses directly.
-``invalidatepage``
- If a page has PagePrivate set, then invalidatepage will be
- called when part or all of the page is to be removed from the
+``invalidate_folio``
+ If a folio has private data, then invalidate_folio will be
+ called when part or all of the folio is to be removed from the
address space. This generally corresponds to either a
truncation, punch hole or a complete invalidation of the address
space (in the latter case 'offset' will always be 0 and 'length'
- will be PAGE_SIZE). Any private data associated with the page
+ will be folio_size()). Any private data associated with the page
should be updated to reflect this truncation. If offset is 0
- and length is PAGE_SIZE, then the private data should be
+ and length is folio_size(), then the private data should be
released, because the page must be able to be completely
discarded. This may be done by calling the ->releasepage
function, but in this case the release MUST succeed.
@@ -930,16 +934,16 @@ cache in your filesystem. The following members are defined:
``putback_page``
Called by the VM when isolated page's migration fails.
-``launder_page``
- Called before freeing a page - it writes back the dirty page.
- To prevent redirtying the page, it is kept locked during the
+``launder_folio``
+ Called before freeing a folio - it writes back the dirty folio.
+ To prevent redirtying the folio, it is kept locked during the
whole operation.
``is_partially_uptodate``
Called by the VM when reading a file through the pagecache when
- the underlying blocksize != pagesize. If the required block is
- up to date then the read can complete without needing the IO to
- bring the whole page up to date.
+ the underlying blocksize is smaller than the size of the folio.
+ If the required block is up to date then the read can complete
+ without needing I/O to bring the whole page up to date.
``is_dirty_writeback``
Called by the VM when attempting to reclaim a page. The VM uses
diff --git a/Documentation/firmware-guide/acpi/enumeration.rst b/Documentation/firmware-guide/acpi/enumeration.rst
index 74b830b2fd59..c414646a1bb4 100644
--- a/Documentation/firmware-guide/acpi/enumeration.rst
+++ b/Documentation/firmware-guide/acpi/enumeration.rst
@@ -19,16 +19,17 @@ possible we decided to do following:
platform devices.
- Devices behind real busses where there is a connector resource
- are represented as struct spi_device or struct i2c_device
- (standard UARTs are not busses so there is no struct uart_device).
+ are represented as struct spi_device or struct i2c_device. Note
+ that standard UARTs are not busses so there is no struct uart_device,
+ although some of them may be represented by sturct serdev_device.
As both ACPI and Device Tree represent a tree of devices (and their
resources) this implementation follows the Device Tree way as much as
possible.
-The ACPI implementation enumerates devices behind busses (platform, SPI and
-I2C), creates the physical devices and binds them to their ACPI handle in
-the ACPI namespace.
+The ACPI implementation enumerates devices behind busses (platform, SPI,
+I2C, and in some cases UART), creates the physical devices and binds them
+to their ACPI handle in the ACPI namespace.
This means that when ACPI_HANDLE(dev) returns non-NULL the device was
enumerated from ACPI namespace. This handle can be used to extract other
@@ -46,18 +47,16 @@ some minor changes.
Adding ACPI support for an existing driver should be pretty
straightforward. Here is the simplest example::
- #ifdef CONFIG_ACPI
static const struct acpi_device_id mydrv_acpi_match[] = {
/* ACPI IDs here */
{ }
};
MODULE_DEVICE_TABLE(acpi, mydrv_acpi_match);
- #endif
static struct platform_driver my_driver = {
...
.driver = {
- .acpi_match_table = ACPI_PTR(mydrv_acpi_match),
+ .acpi_match_table = mydrv_acpi_match,
},
};
@@ -155,7 +154,7 @@ Here is what the ACPI namespace for a SPI slave might look like::
Device (EEP0)
{
Name (_ADR, 1)
- Name (_CID, Package() {
+ Name (_CID, Package () {
"ATML0025",
"AT25",
})
@@ -172,59 +171,51 @@ The SPI device drivers only need to add ACPI IDs in a similar way than with
the platform device drivers. Below is an example where we add ACPI support
to at25 SPI eeprom driver (this is meant for the above ACPI snippet)::
- #ifdef CONFIG_ACPI
static const struct acpi_device_id at25_acpi_match[] = {
{ "AT25", 0 },
- { },
+ { }
};
MODULE_DEVICE_TABLE(acpi, at25_acpi_match);
- #endif
static struct spi_driver at25_driver = {
.driver = {
...
- .acpi_match_table = ACPI_PTR(at25_acpi_match),
+ .acpi_match_table = at25_acpi_match,
},
};
Note that this driver actually needs more information like page size of the
-eeprom etc. but at the time writing this there is no standard way of
-passing those. One idea is to return this in _DSM method like::
+eeprom, etc. This information can be passed via _DSD method like::
Device (EEP0)
{
...
- Method (_DSM, 4, NotSerialized)
+ Name (_DSD, Package ()
{
- Store (Package (6)
+ ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+ Package ()
{
- "byte-len", 1024,
- "addr-mode", 2,
- "page-size, 32
- }, Local0)
-
- // Check UUIDs etc.
-
- Return (Local0)
- }
-
-Then the at25 SPI driver can get this configuration by calling _DSM on its
-ACPI handle like::
-
- struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
- struct acpi_object_list input;
- acpi_status status;
+ Package () { "size", 1024 },
+ Package () { "pagesize", 32 },
+ Package () { "address-width", 16 },
+ }
+ })
+ }
- /* Fill in the input buffer */
+Then the at25 SPI driver can get this configuration by calling device property
+APIs during ->probe() phase like::
- status = acpi_evaluate_object(ACPI_HANDLE(&spi->dev), "_DSM",
- &input, &output);
- if (ACPI_FAILURE(status))
- /* Handle the error */
+ err = device_property_read_u32(dev, "size", &size);
+ if (err)
+ ...error handling...
- /* Extract the data here */
+ err = device_property_read_u32(dev, "pagesize", &page_size);
+ if (err)
+ ...error handling...
- kfree(output.pointer);
+ err = device_property_read_u32(dev, "address-width", &addr_width);
+ if (err)
+ ...error handling...
I2C serial bus support
======================
@@ -237,26 +228,24 @@ registered.
Below is an example of how to add ACPI support to the existing mpu3050
input driver::
- #ifdef CONFIG_ACPI
static const struct acpi_device_id mpu3050_acpi_match[] = {
{ "MPU3050", 0 },
- { },
+ { }
};
MODULE_DEVICE_TABLE(acpi, mpu3050_acpi_match);
- #endif
static struct i2c_driver mpu3050_i2c_driver = {
.driver = {
.name = "mpu3050",
- .owner = THIS_MODULE,
.pm = &mpu3050_pm,
.of_match_table = mpu3050_of_match,
- .acpi_match_table = ACPI_PTR(mpu3050_acpi_match),
+ .acpi_match_table = mpu3050_acpi_match,
},
.probe = mpu3050_probe,
.remove = mpu3050_remove,
.id_table = mpu3050_ids,
};
+ module_i2c_driver(mpu3050_i2c_driver);
Reference to PWM device
=======================
@@ -282,9 +271,9 @@ introduced, i.e.::
}
}
}
-
})
...
+ }
In the above example the PWM-based LED driver references to the PWM channel 0
of \_SB.PCI0.PWM device with initial period setting equal to 600 ms (note that
@@ -306,26 +295,13 @@ For example::
{
Name (SBUF, ResourceTemplate()
{
- ...
// Used to power on/off the device
- GpioIo (Exclusive, PullDefault, 0x0000, 0x0000,
- IoRestrictionOutputOnly, "\\_SB.PCI0.GPI0",
- 0x00, ResourceConsumer,,)
- {
- // Pin List
- 0x0055
- }
+ GpioIo (Exclusive, PullNone, 0, 0, IoRestrictionOutputOnly,
+ "\\_SB.PCI0.GPI0", 0, ResourceConsumer) { 85 }
// Interrupt for the device
- GpioInt (Edge, ActiveHigh, ExclusiveAndWake, PullNone,
- 0x0000, "\\_SB.PCI0.GPI0", 0x00, ResourceConsumer,,)
- {
- // Pin list
- 0x0058
- }
-
- ...
-
+ GpioInt (Edge, ActiveHigh, ExclusiveAndWake, PullNone, 0,
+ "\\_SB.PCI0.GPI0", 0, ResourceConsumer) { 88 }
}
Return (SBUF)
@@ -337,11 +313,12 @@ For example::
ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
Package ()
{
- Package () {"power-gpios", Package() {^DEV, 0, 0, 0 }},
- Package () {"irq-gpios", Package() {^DEV, 1, 0, 0 }},
+ Package () { "power-gpios", Package () { ^DEV, 0, 0, 0 } },
+ Package () { "irq-gpios", Package () { ^DEV, 1, 0, 0 } },
}
})
...
+ }
These GPIO numbers are controller relative and path "\\_SB.PCI0.GPI0"
specifies the path to the controller. In order to use these GPIOs in Linux
@@ -460,10 +437,10 @@ namespace link::
Device (TMP0)
{
Name (_HID, "PRP0001")
- Name (_DSD, Package() {
+ Name (_DSD, Package () {
ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
Package () {
- Package (2) { "compatible", "ti,tmp75" },
+ Package () { "compatible", "ti,tmp75" },
}
})
Method (_CRS, 0, Serialized)
diff --git a/Documentation/firmware-guide/acpi/gpio-properties.rst b/Documentation/firmware-guide/acpi/gpio-properties.rst
index df4b711053ee..eaec732cc77c 100644
--- a/Documentation/firmware-guide/acpi/gpio-properties.rst
+++ b/Documentation/firmware-guide/acpi/gpio-properties.rst
@@ -21,18 +21,18 @@ index, like the ASL example below shows::
Name (_CRS, ResourceTemplate ()
{
GpioIo (Exclusive, PullUp, 0, 0, IoRestrictionOutputOnly,
- "\\_SB.GPO0", 0, ResourceConsumer) {15}
+ "\\_SB.GPO0", 0, ResourceConsumer) { 15 }
GpioIo (Exclusive, PullUp, 0, 0, IoRestrictionOutputOnly,
- "\\_SB.GPO0", 0, ResourceConsumer) {27, 31}
+ "\\_SB.GPO0", 0, ResourceConsumer) { 27, 31 }
})
Name (_DSD, Package ()
{
ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
Package ()
- {
- Package () {"reset-gpios", Package() {^BTH, 1, 1, 0 }},
- Package () {"shutdown-gpios", Package() {^BTH, 0, 0, 0 }},
+ {
+ Package () { "reset-gpios", Package () { ^BTH, 1, 1, 0 } },
+ Package () { "shutdown-gpios", Package () { ^BTH, 0, 0, 0 } },
}
})
}
@@ -123,17 +123,17 @@ Example::
// _DSD Hierarchical Properties Extension UUID
ToUUID("dbb8e3e6-5886-4ba6-8795-1319f52a966b"),
Package () {
- Package () {"hog-gpio8", "G8PU"}
+ Package () { "hog-gpio8", "G8PU" }
}
})
Name (G8PU, Package () {
ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
Package () {
- Package () {"gpio-hog", 1},
- Package () {"gpios", Package () {8, 0}},
- Package () {"output-high", 1},
- Package () {"line-name", "gpio8-pullup"},
+ Package () { "gpio-hog", 1 },
+ Package () { "gpios", Package () { 8, 0 } },
+ Package () { "output-high", 1 },
+ Package () { "line-name", "gpio8-pullup" },
}
})
@@ -266,15 +266,17 @@ have a device like below::
Name (_CRS, ResourceTemplate () {
GpioIo (Exclusive, PullNone, 0, 0, IoRestrictionNone,
- "\\_SB.GPO0", 0, ResourceConsumer) {15}
+ "\\_SB.GPO0", 0, ResourceConsumer) { 15 }
GpioIo (Exclusive, PullNone, 0, 0, IoRestrictionNone,
- "\\_SB.GPO0", 0, ResourceConsumer) {27}
+ "\\_SB.GPO0", 0, ResourceConsumer) { 27 }
})
}
The driver might expect to get the right GPIO when it does::
desc = gpiod_get(dev, "reset", GPIOD_OUT_LOW);
+ if (IS_ERR(desc))
+ ...error handling...
but since there is no way to know the mapping between "reset" and
the GpioIo() in _CRS desc will hold ERR_PTR(-ENOENT).
diff --git a/Documentation/gpu/drm-internals.rst b/Documentation/gpu/drm-internals.rst
index 607f78f0f189..38afed24a75c 100644
--- a/Documentation/gpu/drm-internals.rst
+++ b/Documentation/gpu/drm-internals.rst
@@ -75,6 +75,12 @@ update it, its value is mostly useless. The DRM core prints it to the
kernel log at initialization time and passes it to userspace through the
DRM_IOCTL_VERSION ioctl.
+Module Initialization
+---------------------
+
+.. kernel-doc:: include/drm/drm_module.h
+ :doc: overview
+
Managing Ownership of the Framebuffer Aperture
----------------------------------------------
diff --git a/Documentation/gpu/drm-kms-helpers.rst b/Documentation/gpu/drm-kms-helpers.rst
index 5bb55ec1b9b5..c3ce91eecbc1 100644
--- a/Documentation/gpu/drm-kms-helpers.rst
+++ b/Documentation/gpu/drm-kms-helpers.rst
@@ -232,34 +232,34 @@ HDCP Helper Functions Reference
Display Port Helper Functions Reference
=======================================
-.. kernel-doc:: drivers/gpu/drm/drm_dp_helper.c
+.. kernel-doc:: drivers/gpu/drm/dp/drm_dp.c
:doc: dp helpers
-.. kernel-doc:: include/drm/drm_dp_helper.h
+.. kernel-doc:: include/drm/dp/drm_dp_helper.h
:internal:
-.. kernel-doc:: drivers/gpu/drm/drm_dp_helper.c
+.. kernel-doc:: drivers/gpu/drm/dp/drm_dp.c
:export:
Display Port CEC Helper Functions Reference
===========================================
-.. kernel-doc:: drivers/gpu/drm/drm_dp_cec.c
+.. kernel-doc:: drivers/gpu/drm/dp/drm_dp_cec.c
:doc: dp cec helpers
-.. kernel-doc:: drivers/gpu/drm/drm_dp_cec.c
+.. kernel-doc:: drivers/gpu/drm/dp/drm_dp_cec.c
:export:
Display Port Dual Mode Adaptor Helper Functions Reference
=========================================================
-.. kernel-doc:: drivers/gpu/drm/drm_dp_dual_mode_helper.c
+.. kernel-doc:: drivers/gpu/drm/dp/drm_dp_dual_mode_helper.c
:doc: dp dual mode helpers
-.. kernel-doc:: include/drm/drm_dp_dual_mode_helper.h
+.. kernel-doc:: include/drm/dp/drm_dp_dual_mode_helper.h
:internal:
-.. kernel-doc:: drivers/gpu/drm/drm_dp_dual_mode_helper.c
+.. kernel-doc:: drivers/gpu/drm/dp/drm_dp_dual_mode_helper.c
:export:
Display Port MST Helpers
@@ -268,19 +268,19 @@ Display Port MST Helpers
Overview
--------
-.. kernel-doc:: drivers/gpu/drm/drm_dp_mst_topology.c
+.. kernel-doc:: drivers/gpu/drm/dp/drm_dp_mst_topology.c
:doc: dp mst helper
-.. kernel-doc:: drivers/gpu/drm/drm_dp_mst_topology.c
+.. kernel-doc:: drivers/gpu/drm/dp/drm_dp_mst_topology.c
:doc: Branch device and port refcounting
Functions Reference
-------------------
-.. kernel-doc:: include/drm/drm_dp_mst_helper.h
+.. kernel-doc:: include/drm/dp/drm_dp_mst_helper.h
:internal:
-.. kernel-doc:: drivers/gpu/drm/drm_dp_mst_topology.c
+.. kernel-doc:: drivers/gpu/drm/dp/drm_dp_mst_topology.c
:export:
Topology Lifetime Internals
@@ -289,7 +289,7 @@ Topology Lifetime Internals
These functions aren't exported to drivers, but are documented here to help make
the MST topology helpers easier to understand
-.. kernel-doc:: drivers/gpu/drm/drm_dp_mst_topology.c
+.. kernel-doc:: drivers/gpu/drm/dp/drm_dp_mst_topology.c
:functions: drm_dp_mst_topology_try_get_mstb drm_dp_mst_topology_get_mstb
drm_dp_mst_topology_put_mstb
drm_dp_mst_topology_try_get_port drm_dp_mst_topology_get_port
diff --git a/Documentation/gpu/drm-kms.rst b/Documentation/gpu/drm-kms.rst
index d14bf1c35d7e..6f9c064fd323 100644
--- a/Documentation/gpu/drm-kms.rst
+++ b/Documentation/gpu/drm-kms.rst
@@ -423,12 +423,12 @@ Connector Functions Reference
Writeback Connectors
--------------------
-.. kernel-doc:: include/drm/drm_writeback.h
- :internal:
-
.. kernel-doc:: drivers/gpu/drm/drm_writeback.c
:doc: overview
+.. kernel-doc:: include/drm/drm_writeback.h
+ :internal:
+
.. kernel-doc:: drivers/gpu/drm/drm_writeback.c
:export:
diff --git a/Documentation/gpu/drm-mm.rst b/Documentation/gpu/drm-mm.rst
index e0538083a2c0..198bcc1affa1 100644
--- a/Documentation/gpu/drm-mm.rst
+++ b/Documentation/gpu/drm-mm.rst
@@ -8,7 +8,7 @@ the very dynamic nature of many of that data, managing graphics memory
efficiently is thus crucial for the graphics stack and plays a central
role in the DRM infrastructure.
-The DRM core includes two memory managers, namely Translation Table Maps
+The DRM core includes two memory managers, namely Translation Table Manager
(TTM) and Graphics Execution Manager (GEM). TTM was the first DRM memory
manager to be developed and tried to be a one-size-fits-them all
solution. It provides a single userspace API to accommodate the need of
diff --git a/Documentation/gpu/i915.rst b/Documentation/gpu/i915.rst
index b7d801993bfa..bcaefc952764 100644
--- a/Documentation/gpu/i915.rst
+++ b/Documentation/gpu/i915.rst
@@ -539,6 +539,7 @@ GuC ABI
.. kernel-doc:: drivers/gpu/drm/i915/gt/uc/abi/guc_communication_mmio_abi.h
.. kernel-doc:: drivers/gpu/drm/i915/gt/uc/abi/guc_communication_ctb_abi.h
.. kernel-doc:: drivers/gpu/drm/i915/gt/uc/abi/guc_actions_abi.h
+.. kernel-doc:: drivers/gpu/drm/i915/gt/uc/abi/guc_klvs_abi.h
HuC
---
diff --git a/Documentation/gpu/todo.rst b/Documentation/gpu/todo.rst
index da138dd39883..127e76ee0b2d 100644
--- a/Documentation/gpu/todo.rst
+++ b/Documentation/gpu/todo.rst
@@ -222,7 +222,7 @@ Convert drivers to use drm_fbdev_generic_setup()
Most drivers can use drm_fbdev_generic_setup(). Driver have to implement
atomic modesetting and GEM vmap support. Historically, generic fbdev emulation
expected the framebuffer in system memory or system-like memory. By employing
-struct dma_buf_map, drivers with frambuffers in I/O memory can be supported
+struct iosys_map, drivers with frambuffers in I/O memory can be supported
as well.
Contact: Maintainer of the driver you plan to convert
@@ -234,13 +234,35 @@ Reimplement functions in drm_fbdev_fb_ops without fbdev
A number of callback functions in drm_fbdev_fb_ops could benefit from
being rewritten without dependencies on the fbdev module. Some of the
-helpers could further benefit from using struct dma_buf_map instead of
+helpers could further benefit from using struct iosys_map instead of
raw pointers.
Contact: Thomas Zimmermann <tzimmermann@suse.de>, Daniel Vetter
Level: Advanced
+Benchmark and optimize blitting and format-conversion function
+--------------------------------------------------------------
+
+Drawing to dispay memory quickly is crucial for many applications'
+performance.
+
+On at least x86-64, sys_imageblit() is significantly slower than
+cfb_imageblit(), even though both use the same blitting algorithm and
+the latter is written for I/O memory. It turns out that cfb_imageblit()
+uses movl instructions, while sys_imageblit apparently does not. This
+seems to be a problem with gcc's optimizer. DRM's format-conversion
+helpers might be subject to similar issues.
+
+Benchmark and optimize fbdev's sys_() helpers and DRM's format-conversion
+helpers. In cases that can be further optimized, maybe implement a different
+algorithm. For micro-optimizations, use movl/movq instructions explicitly.
+That might possibly require architecture-specific helpers (e.g., storel()
+storeq()).
+
+Contact: Thomas Zimmermann <tzimmermann@suse.de>
+
+Level: Intermediate
drm_framebuffer_funcs and drm_mode_config_funcs.fb_create cleanup
-----------------------------------------------------------------
@@ -300,30 +322,6 @@ Contact: Daniel Vetter, Noralf Tronnes
Level: Advanced
-Garbage collect fbdev scrolling acceleration
---------------------------------------------
-
-Scroll acceleration has been disabled in fbcon. Now it works as the old
-SCROLL_REDRAW mode. A ton of code was removed in fbcon.c and the hook bmove was
-removed from fbcon_ops.
-Remaining tasks:
-
-- a bunch of the hooks in fbcon_ops could be removed or simplified by calling
- directly instead of the function table (with a switch on p->rotate)
-
-- fb_copyarea is unused after this, and can be deleted from all drivers
-
-- after that, fb_copyarea can be deleted from fb_ops in include/linux/fb.h as
- well as cfb_copyarea
-
-Note that not all acceleration code can be deleted, since clearing and cursor
-support is still accelerated, which might be good candidates for further
-deletion projects.
-
-Contact: Daniel Vetter
-
-Level: Intermediate
-
idr_init_base()
---------------
@@ -434,19 +432,19 @@ Contact: Emil Velikov, respective driver maintainers
Level: Intermediate
-Use struct dma_buf_map throughout codebase
-------------------------------------------
+Use struct iosys_map throughout codebase
+----------------------------------------
-Pointers to shared device memory are stored in struct dma_buf_map. Each
+Pointers to shared device memory are stored in struct iosys_map. Each
instance knows whether it refers to system or I/O memory. Most of the DRM-wide
-interface have been converted to use struct dma_buf_map, but implementations
+interface have been converted to use struct iosys_map, but implementations
often still use raw pointers.
-The task is to use struct dma_buf_map where it makes sense.
+The task is to use struct iosys_map where it makes sense.
-* Memory managers should use struct dma_buf_map for dma-buf-imported buffers.
-* TTM might benefit from using struct dma_buf_map internally.
-* Framebuffer copying and blitting helpers should operate on struct dma_buf_map.
+* Memory managers should use struct iosys_map for dma-buf-imported buffers.
+* TTM might benefit from using struct iosys_map internally.
+* Framebuffer copying and blitting helpers should operate on struct iosys_map.
Contact: Thomas Zimmermann <tzimmermann@suse.de>, Christian König, Daniel Vetter
@@ -467,6 +465,21 @@ Contact: Thomas Zimmermann <tzimmermann@suse.de>
Level: Intermediate
+Request memory regions in all drivers
+-------------------------------------
+
+Go through all drivers and add code to request the memory regions that the
+driver uses. This requires adding calls to request_mem_region(),
+pci_request_region() or similar functions. Use helpers for managed cleanup
+where possible.
+
+Drivers are pretty bad at doing this and there used to be conflicts among
+DRM and fbdev drivers. Still, it's the correct thing to do.
+
+Contact: Thomas Zimmermann <tzimmermann@suse.de>
+
+Level: Starter
+
Core refactorings
=================
@@ -484,8 +497,12 @@ This is a really varied tasks with lots of little bits and pieces:
achieved by using an IPI to the local processor.
* There's a massive confusion of different panic handlers. DRM fbdev emulation
- helpers have one, but on top of that the fbcon code itself also has one. We
- need to make sure that they stop fighting over each another.
+ helpers had their own (long removed), but on top of that the fbcon code itself
+ also has one. We need to make sure that they stop fighting over each other.
+ This is worked around by checking ``oops_in_progress`` at various entry points
+ into the DRM fbdev emulation helpers. A much cleaner approach here would be to
+ switch fbcon to the `threaded printk support
+ <https://lwn.net/Articles/800946/>`_.
* ``drm_can_sleep()`` is a mess. It hides real bugs in normal operations and
isn't a full solution for panic paths. We need to make sure that it only
@@ -497,16 +514,15 @@ This is a really varied tasks with lots of little bits and pieces:
even spinlocks (because NMI and hardirq can panic too). We need to either
make sure to not call such paths, or trylock everything. Really tricky.
-* For the above locking troubles reasons it's pretty much impossible to
- attempt a synchronous modeset from panic handlers. The only thing we could
- try to achive is an atomic ``set_base`` of the primary plane, and hope that
- it shows up. Everything else probably needs to be delayed to some worker or
- something else which happens later on. Otherwise it just kills the box
- harder, prevent the panic from going out on e.g. netconsole.
+* A clean solution would be an entirely separate panic output support in KMS,
+ bypassing the current fbcon support. See `[PATCH v2 0/3] drm: Add panic handling
+ <https://lore.kernel.org/dri-devel/20190311174218.51899-1-noralf@tronnes.org/>`_.
-* There's also proposal for a simplied DRM console instead of the full-blown
- fbcon and DRM fbdev emulation. Any kind of panic handling tricks should
- obviously work for both console, in case we ever get kmslog merged.
+* Encoding the actual oops and preceding dmesg in a QR might help with the
+ dread "important stuff scrolled away" problem. See `[RFC][PATCH] Oops messages
+ transfer using QR codes
+ <https://lore.kernel.org/lkml/1446217392-11981-1-git-send-email-alexandru.murtaza@intel.com/>`_
+ for some example code that could be reused.
Contact: Daniel Vetter
diff --git a/Documentation/gpu/vkms.rst b/Documentation/gpu/vkms.rst
index 941f0e7e5eef..9c873c3912cc 100644
--- a/Documentation/gpu/vkms.rst
+++ b/Documentation/gpu/vkms.rst
@@ -124,8 +124,6 @@ Add Plane Features
There's lots of plane features we could add support for:
-- Multiple overlay planes. [Good to get started]
-
- Clearing primary plane: clear primary plane before plane composition (at the
start) for correctness of pixel blend ops. It also guarantees alpha channel
is cleared in the target buffer for stable crc. [Good to get started]
diff --git a/Documentation/hwmon/aquacomputer_d5next.rst b/Documentation/hwmon/aquacomputer_d5next.rst
index 1f4bb4ba2e4b..3373e27b707d 100644
--- a/Documentation/hwmon/aquacomputer_d5next.rst
+++ b/Documentation/hwmon/aquacomputer_d5next.rst
@@ -6,22 +6,21 @@ Kernel driver aquacomputer-d5next
Supported devices:
* Aquacomputer D5 Next watercooling pump
+* Aquacomputer Farbwerk 360 RGB controller
Author: Aleksa Savic
Description
-----------
-This driver exposes hardware sensors of the Aquacomputer D5 Next watercooling
-pump, which communicates through a proprietary USB HID protocol.
+This driver exposes hardware sensors of listed Aquacomputer devices, which
+communicate through proprietary USB HID protocols.
-Available sensors are pump and fan speed, power, voltage and current, as
-well as coolant temperature. Also available through debugfs are the serial
-number, firmware version and power-on count.
-
-Attaching a fan is optional and allows it to be controlled using temperature
-curves directly from the pump. If it's not connected, the fan-related sensors
-will report zeroes.
+For the D5 Next pump, available sensors are pump and fan speed, power, voltage
+and current, as well as coolant temperature. Also available through debugfs are
+the serial number, firmware version and power-on count. Attaching a fan to it is
+optional and allows it to be controlled using temperature curves directly from the
+pump. If it's not connected, the fan-related sensors will report zeroes.
The pump can be configured either through software or via its physical
interface. Configuring the pump through this driver is not implemented, as it
@@ -29,33 +28,31 @@ seems to require sending it a complete configuration. That includes addressable
RGB LEDs, for which there is no standard sysfs interface. Thus, that task is
better suited for userspace tools.
+The Farbwerk 360 exposes four temperature sensors. Depending on the device,
+not all sysfs and debugfs entries will be available.
+
Usage notes
-----------
-The pump communicates via HID reports. The driver is loaded automatically by
+The devices communicate via HID reports. The driver is loaded automatically by
the kernel and supports hotswapping.
Sysfs entries
-------------
-============ =============================================
-temp1_input Coolant temperature (in millidegrees Celsius)
-fan1_input Pump speed (in RPM)
-fan2_input Fan speed (in RPM)
-power1_input Pump power (in micro Watts)
-power2_input Fan power (in micro Watts)
-in0_input Pump voltage (in milli Volts)
-in1_input Fan voltage (in milli Volts)
-in2_input +5V rail voltage (in milli Volts)
-curr1_input Pump current (in milli Amperes)
-curr2_input Fan current (in milli Amperes)
-============ =============================================
+================ =============================================
+temp[1-4]_input Temperature sensors (in millidegrees Celsius)
+fan[1-2]_input Pump/fan speed (in RPM)
+power[1-2]_input Pump/fan power (in micro Watts)
+in[0-2]_input Pump/fan voltage (in milli Volts)
+curr[1-2]_input Pump/fan current (in milli Amperes)
+================ =============================================
Debugfs entries
---------------
-================ ===============================================
-serial_number Serial number of the pump
+================ =================================================
+serial_number Serial number of the device
firmware_version Version of installed firmware
-power_cycles Count of how many times the pump was powered on
-================ ===============================================
+power_cycles Count of how many times the device was powered on
+================ =================================================
diff --git a/Documentation/hwmon/asus_ec_sensors.rst b/Documentation/hwmon/asus_ec_sensors.rst
new file mode 100644
index 000000000000..e7e8f1640f45
--- /dev/null
+++ b/Documentation/hwmon/asus_ec_sensors.rst
@@ -0,0 +1,54 @@
+.. SPDX-License-Identifier: GPL-2.0-or-later
+
+Kernel driver asus_ec_sensors
+=================================
+
+Supported boards:
+ * PRIME X570-PRO,
+ * Pro WS X570-ACE,
+ * ROG CROSSHAIR VIII DARK HERO,
+ * ROG CROSSHAIR VIII HERO (WI-FI)
+ * ROG CROSSHAIR VIII FORMULA,
+ * ROG CROSSHAIR VIII HERO,
+ * ROG CROSSHAIR VIII IMPACT,
+ * ROG STRIX B550-E GAMING,
+ * ROG STRIX B550-I GAMING,
+ * ROG STRIX X570-E GAMING,
+ * ROG STRIX X570-F GAMING,
+ * ROG STRIX X570-I GAMING
+
+Authors:
+ - Eugene Shalygin <eugene.shalygin@gmail.com>
+
+Description:
+------------
+ASUS mainboards publish hardware monitoring information via Super I/O
+chip and the ACPI embedded controller (EC) registers. Some of the sensors
+are only available via the EC.
+
+The driver is aware of and reads the following sensors:
+
+1. Chipset (PCH) temperature
+2. CPU package temperature
+3. Motherboard temperature
+4. Readings from the T_Sensor header
+5. VRM temperature
+6. CPU_Opt fan RPM
+7. VRM heatsink fan RPM
+8. Chipset fan RPM
+9. Readings from the "Water flow meter" header (RPM)
+10. Readings from the "Water In" and "Water Out" temperature headers
+11. CPU current
+12. CPU core voltage
+
+Sensor values are read from EC registers, and to avoid race with the board
+firmware the driver acquires ACPI mutex, the one used by the WMI when its
+methods access the EC.
+
+Module Parameters
+-----------------
+ * mutex_path: string
+ The driver holds path to the ACPI mutex for each board (actually,
+ the path is mostly identical for them). If ASUS changes this path
+ in a future BIOS update, this parameter can be used to override
+ the stored in the driver value until it gets updated.
diff --git a/Documentation/hwmon/dell-smm-hwmon.rst b/Documentation/hwmon/dell-smm-hwmon.rst
index beec88491171..d3323a96665d 100644
--- a/Documentation/hwmon/dell-smm-hwmon.rst
+++ b/Documentation/hwmon/dell-smm-hwmon.rst
@@ -165,3 +165,183 @@ obtain the same information and to control the fan status. The ioctl
interface can be accessed from C programs or from shell using the
i8kctl utility. See the source file of ``i8kutils`` for more
information on how to use the ioctl interface.
+
+SMM Interface
+-------------
+
+.. warning:: The SMM interface was reverse-engineered by trial-and-error
+ since Dell did not provide any Documentation,
+ please keep that in mind.
+
+The driver uses the SMM interface to send commands to the system BIOS.
+This interface is normally used by Dell's 32-bit diagnostic program or
+on newer notebook models by the buildin BIOS diagnostics.
+The SMM is triggered by writing to the special ioports ``0xb2`` and ``0x84``,
+and may cause short hangs when the BIOS code is taking too long to
+execute.
+
+The SMM handler inside the system BIOS looks at the contents of the
+``eax``, ``ebx``, ``ecx``, ``edx``, ``esi`` and ``edi`` registers.
+Each register has a special purpose:
+
+=============== ==================================
+Register Purpose
+=============== ==================================
+eax Holds the command code before SMM,
+ holds the first result after SMM.
+ebx Holds the arguments.
+ecx Unknown, set to 0.
+edx Holds the second result after SMM.
+esi Unknown, set to 0.
+edi Unknown, set to 0.
+=============== ==================================
+
+The SMM handler can signal a failure by either:
+
+- setting the lower sixteen bits of ``eax`` to ``0xffff``
+- not modifying ``eax`` at all
+- setting the carry flag
+
+SMM command codes
+-----------------
+
+=============== ======================= ================================================
+Command Code Command Name Description
+=============== ======================= ================================================
+``0x0025`` Get Fn key status Returns the Fn key pressed after SMM:
+
+ - 9th bit in ``eax`` indicates Volume up
+ - 10th bit in ``eax`` indicates Volume down
+ - both bits indicate Volume mute
+
+``0xa069`` Get power status Returns current power status after SMM:
+
+ - 1st bit in ``eax`` indicates Battery connected
+ - 3th bit in ``eax`` indicates AC connected
+
+``0x00a3`` Get fan state Returns current fan state after SMM:
+
+ - 1st byte in ``eax`` holds the current
+ fan state (0 - 2 or 3)
+
+``0x01a3`` Set fan state Sets the fan speed:
+
+ - 1st byte in ``ebx`` holds the fan number
+ - 2nd byte in ``ebx`` holds the desired
+ fan state (0 - 2 or 3)
+
+``0x02a3`` Get fan speed Returns the current fan speed in RPM:
+
+ - 1st byte in ``ebx`` holds the fan number
+ - 1st word in ``eax`` holds the current
+ fan speed in RPM (after SMM)
+
+``0x03a3`` Get fan type Returns the fan type:
+
+ - 1st byte in ``ebx`` holds the fan number
+ - 1st byte in ``eax`` holds the
+ fan type (after SMM):
+
+ - 5th bit indicates docking fan
+ - 1 indicates Processor fan
+ - 2 indicates Motherboard fan
+ - 3 indicates Video fan
+ - 4 indicates Power supply fan
+ - 5 indicates Chipset fan
+ - 6 indicates other fan type
+
+``0x04a3`` Get nominal fan speed Returns the nominal RPM in each fan state:
+
+ - 1st byte in ``ebx`` holds the fan number
+ - 2nd byte in ``ebx`` holds the fan state
+ in question (0 - 2 or 3)
+ - 1st word in ``eax`` holds the nominal
+ fan speed in RPM (after SMM)
+
+``0x05a3`` Get fan speed tolerance Returns the speed tolerance for each fan state:
+
+ - 1st byte in ``ebx`` holds the fan number
+ - 2nd byte in ``ebx`` holds the fan state
+ in question (0 - 2 or 3)
+ - 1st byte in ``eax`` returns the speed
+ tolerance
+
+``0x10a3`` Get sensor temperature Returns the measured temperature:
+
+ - 1st byte in ``ebx`` holds the sensor number
+ - 1st byte in ``eax`` holds the measured
+ temperature (after SMM)
+
+``0x11a3`` Get sensor type Returns the sensor type:
+
+ - 1st byte in ``ebx`` holds the sensor number
+ - 1st byte in ``eax`` holds the
+ temperature type (after SMM):
+
+ - 1 indicates CPU sensor
+ - 2 indicates GPU sensor
+ - 3 indicates SODIMM sensor
+ - 4 indicates other sensor type
+ - 5 indicates Ambient sensor
+ - 6 indicates other sensor type
+
+``0xfea3`` Get SMM signature Returns Dell signature if interface
+ is supported (after SMM):
+
+ - ``eax`` holds 1145651527
+ (0x44494147 or "DIAG")
+ - ``edx`` holds 1145392204
+ (0x44454c4c or "DELL")
+
+``0xffa3`` Get SMM signature Same as ``0xfea3``, check both.
+=============== ======================= ================================================
+
+There are additional commands for enabling (``0x31a3`` or ``0x35a3``) and
+disabling (``0x30a3`` or ``0x34a3``) automatic fan speed control.
+The commands are however causing severe sideeffects on many machines, so
+they are not used by default.
+
+On several machines (Inspiron 3505, Precision 490, Vostro 1720, ...), the
+fans supports a 4th "magic" state, which signals the BIOS that automatic
+fan control should be enabled for a specific fan.
+However there are also some machines who do support a 4th regular fan state too,
+but in case of the "magic" state, the nominal RPM reported for this state is a
+placeholder value, which however is not always detectable.
+
+Firmware Bugs
+-------------
+
+The SMM calls can behave erratic on some machines:
+
+======================================================= =================
+Firmware Bug Affected Machines
+======================================================= =================
+Reading of fan states return spurious errors. Precision 490
+
+Reading of fan types causes erratic fan behaviour. Studio XPS 8000
+
+ Studio XPS 8100
+
+ Inspiron 580
+
+Fan-related SMM calls take too long (about 500ms). Inspiron 7720
+
+ Vostro 3360
+
+ XPS 13 9333
+
+ XPS 15 L502X
+======================================================= =================
+
+In case you experience similar issues on your Dell machine, please
+submit a bugreport on bugzilla to we can apply workarounds.
+
+Limitations
+-----------
+
+The SMM calls can take too long to execute on some machines, causing
+short hangs and/or audio glitches.
+Also the fan state needs to be restored after suspend, as well as
+the automatic mode settings.
+When reading a temperature sensor, values above 127 degrees indicate
+a BIOS read error or a deactivated sensor.
diff --git a/Documentation/hwmon/index.rst b/Documentation/hwmon/index.rst
index df20022c741f..9d2787a12a69 100644
--- a/Documentation/hwmon/index.rst
+++ b/Documentation/hwmon/index.rst
@@ -43,6 +43,7 @@ Hardware Monitoring Kernel Drivers
asb100
asc7621
aspeed-pwm-tacho
+ asus_ec_sensors
asus_wmi_ec_sensors
asus_wmi_sensors
bcm54140
@@ -160,6 +161,7 @@ Hardware Monitoring Kernel Drivers
pc87427
pcf8591
pim4328
+ pli1209bc
pm6764tr
pmbus
powr1220
@@ -193,6 +195,7 @@ Hardware Monitoring Kernel Drivers
tmp108
tmp401
tmp421
+ tmp464
tmp513
tps23861
tps40422
diff --git a/Documentation/hwmon/lm70.rst b/Documentation/hwmon/lm70.rst
index 6ddc5b67ccb5..11303a7e16a8 100644
--- a/Documentation/hwmon/lm70.rst
+++ b/Documentation/hwmon/lm70.rst
@@ -15,6 +15,10 @@ Supported chips:
Information: https://www.ti.com/product/tmp122
+ * Texas Instruments TMP125
+
+ Information: https://www.ti.com/product/tmp125
+
* National Semiconductor LM71
Datasheet: https://www.ti.com/product/LM71
@@ -53,6 +57,9 @@ The LM74 and TMP121/TMP122/TMP123/TMP124 are very similar; main difference is
The TMP122/TMP124 also feature configurable temperature thresholds.
+The TMP125 is less accurate and provides 10-bit temperature data
+with 0.25 degrees Celsius resolution.
+
The LM71 is also very similar; main difference is 14-bit temperature
data (0.03125 degrees celsius resolution).
diff --git a/Documentation/hwmon/max6639.rst b/Documentation/hwmon/max6639.rst
index 3da54225f83c..c85d285a3489 100644
--- a/Documentation/hwmon/max6639.rst
+++ b/Documentation/hwmon/max6639.rst
@@ -9,7 +9,7 @@ Supported chips:
Addresses scanned: I2C 0x2c, 0x2e, 0x2f
- Datasheet: http://pdfserv.maxim-ic.com/en/ds/MAX6639.pdf
+ Datasheet: https://datasheets.maximintegrated.com/en/ds/MAX6639-MAX6639F.pdf
Authors:
- He Changqing <hechangqing@semptian.com>
diff --git a/Documentation/hwmon/pli1209bc.rst b/Documentation/hwmon/pli1209bc.rst
new file mode 100644
index 000000000000..ea5b3f68a515
--- /dev/null
+++ b/Documentation/hwmon/pli1209bc.rst
@@ -0,0 +1,75 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+Kernel driver pli1209bc
+=======================
+
+Supported chips:
+
+ * Digital Supervisor PLI1209BC
+
+ Prefix: 'pli1209bc'
+
+ Addresses scanned: 0x50 - 0x5F
+
+ Datasheet: https://www.vicorpower.com/documents/datasheets/ds-PLI1209BCxyzz-VICOR.pdf
+
+Authors:
+ - Marcello Sylvester Bauer <sylv@sylv.io>
+
+Description
+-----------
+
+The Vicor PLI1209BC is an isolated digital power system supervisor that provides
+a communication interface between a host processor and one Bus Converter Module
+(BCM). The PLI communicates with a system controller via a PMBus compatible
+interface over an isolated UART interface. Through the PLI, the host processor
+can configure, set protection limits, and monitor the BCM.
+
+Sysfs entries
+-------------
+
+======================= ========================================================
+in1_label "vin2"
+in1_input Input voltage.
+in1_rated_min Minimum rated input voltage.
+in1_rated_max Maximum rated input voltage.
+in1_max Maximum input voltage.
+in1_max_alarm Input voltage high alarm.
+in1_crit Critical input voltage.
+in1_crit_alarm Input voltage critical alarm.
+
+in2_label "vout2"
+in2_input Output voltage.
+in2_rated_min Minimum rated output voltage.
+in2_rated_max Maximum rated output voltage.
+in2_alarm Output voltage alarm
+
+curr1_label "iin2"
+curr1_input Input current.
+curr1_max Maximum input current.
+curr1_max_alarm Maximum input current high alarm.
+curr1_crit Critical input current.
+curr1_crit_alarm Input current critical alarm.
+
+curr2_label "iout2"
+curr2_input Output current.
+curr2_crit Critical output current.
+curr2_crit_alarm Output current critical alarm.
+curr2_max Maximum output current.
+curr2_max_alarm Output current high alarm.
+
+power1_label "pin2"
+power1_input Input power.
+power1_alarm Input power alarm.
+
+power2_label "pout2"
+power2_input Output power.
+power2_rated_max Maximum rated output power.
+
+temp1_input Die temperature.
+temp1_alarm Die temperature alarm.
+temp1_max Maximum die temperature.
+temp1_max_alarm Die temperature high alarm.
+temp1_crit Critical die temperature.
+temp1_crit_alarm Die temperature critical alarm.
+======================= ========================================================
diff --git a/Documentation/hwmon/sch5627.rst b/Documentation/hwmon/sch5627.rst
index 187682e99114..ecb4fc84d045 100644
--- a/Documentation/hwmon/sch5627.rst
+++ b/Documentation/hwmon/sch5627.rst
@@ -20,6 +20,10 @@ Description
SMSC SCH5627 Super I/O chips include complete hardware monitoring
capabilities. They can monitor up to 5 voltages, 4 fans and 8 temperatures.
+In addition, the SCH5627 exports data describing which temperature sensors
+affect the speed of each fan. Setting pwmX_auto_channels_temp to 0 forces
+the corresponding fan to full speed until another value is written.
+
The SMSC SCH5627 hardware monitoring part also contains an integrated
watchdog. In order for this watchdog to function some motherboard specific
initialization most be done by the BIOS, so if the watchdog is not enabled
diff --git a/Documentation/hwmon/sysfs-interface.rst b/Documentation/hwmon/sysfs-interface.rst
index 85652a6aaa3e..209626fb2405 100644
--- a/Documentation/hwmon/sysfs-interface.rst
+++ b/Documentation/hwmon/sysfs-interface.rst
@@ -99,6 +99,10 @@ Global attributes
`name`
The chip name.
+`label`
+ A descriptive label that allows to uniquely identify a device
+ within the system.
+
`update_interval`
The interval at which the chip will update readings.
diff --git a/Documentation/hwmon/tmp464.rst b/Documentation/hwmon/tmp464.rst
new file mode 100644
index 000000000000..7596e7623d06
--- /dev/null
+++ b/Documentation/hwmon/tmp464.rst
@@ -0,0 +1,73 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+Kernel driver tmp464
+====================
+
+Supported chips:
+
+ * Texas Instruments TMP464
+
+ Prefix: 'tmp464'
+
+ Addresses scanned: I2C 0x48, 0x49, 0x4a and 0x4b
+
+ Datasheet: http://focus.ti.com/docs/prod/folders/print/tmp464.html
+
+ * Texas Instruments TMP468
+
+ Prefix: 'tmp468'
+
+ Addresses scanned: I2C 0x48, 0x49, 0x4a and 0x4b
+
+ Datasheet: http://focus.ti.com/docs/prod/folders/print/tmp468.html
+
+Authors:
+
+ Agathe Porte <agathe.porte@nokia.com>
+ Guenter Roeck <linux@roeck-us.net>
+
+Description
+-----------
+
+This driver implements support for Texas Instruments TMP464 and TMP468
+temperature sensor chips. TMP464 provides one local and four remote
+sensors. TMP468 provides one local and eight remote sensors.
+Temperature is measured in degrees Celsius. The chips are wired over
+I2C/SMBus and specified over a temperature range of -40 to +125 degrees
+Celsius. Resolution for both the local and remote channels is 0.0625
+degree C.
+
+The chips support only temperature measurements. The driver exports
+temperature values, limits, and alarms via the following sysfs files:
+
+**temp[1-9]_input**
+
+**temp[1-9]_max**
+
+**temp[1-9]_max_hyst**
+
+**temp[1-9]_max_alarm**
+
+**temp[1-9]_crit**
+
+**temp[1-9]_crit_alarm**
+
+**temp[1-9]_crit_hyst**
+
+**temp[2-9]_offset**
+
+**temp[2-9]_fault**
+
+Each sensor can be individually disabled via Devicetree or from sysfs
+via:
+
+**temp[1-9]_enable**
+
+If labels were specified in Devicetree, additional sysfs files will
+be present:
+
+**temp[1-9]_label**
+
+The update interval is configurable with the following sysfs attribute.
+
+**update_interval**
diff --git a/Documentation/hwmon/xdpe12284.rst b/Documentation/hwmon/xdpe12284.rst
index 67d1f87808e5..a224dc74ad35 100644
--- a/Documentation/hwmon/xdpe12284.rst
+++ b/Documentation/hwmon/xdpe12284.rst
@@ -5,6 +5,10 @@ Kernel driver xdpe122
Supported chips:
+ * Infineon XDPE11280
+
+ Prefix: 'xdpe11280'
+
* Infineon XDPE12254
Prefix: 'xdpe12254'
@@ -20,10 +24,10 @@ Authors:
Description
-----------
-This driver implements support for Infineon Multi-phase XDPE122 family
-dual loop voltage regulators.
-The family includes XDPE12284 and XDPE12254 devices.
-The devices from this family complaint with:
+This driver implements support for Infineon Multi-phase XDPE112 and XDPE122
+family dual loop voltage regulators.
+These families include XDPE11280, XDPE12284 and XDPE12254 devices.
+The devices from this family compliant with:
- Intel VR13 and VR13HC rev 1.3, IMVP8 rev 1.2 and IMPVP9 rev 1.3 DC-DC
converter specification.
diff --git a/Documentation/index.rst b/Documentation/index.rst
index 2b4de3926858..b58692d687f6 100644
--- a/Documentation/index.rst
+++ b/Documentation/index.rst
@@ -166,6 +166,7 @@ to ReStructured Text format, or are simply too old.
.. toctree::
:maxdepth: 2
+ tools/index
staging/index
watch_queue
diff --git a/Documentation/kernel-hacking/locking.rst b/Documentation/kernel-hacking/locking.rst
index e6cd40663ea5..4cbd50edf277 100644
--- a/Documentation/kernel-hacking/locking.rst
+++ b/Documentation/kernel-hacking/locking.rst
@@ -295,7 +295,7 @@ Pete Zaitcev gives the following summary:
- If you are in a process context (any syscall) and want to lock other
process out, use a mutex. You can take a mutex and sleep
- (``copy_from_user*(`` or ``kmalloc(x,GFP_KERNEL)``).
+ (``copy_from_user()`` or ``kmalloc(x,GFP_KERNEL)``).
- Otherwise (== data can be touched in an interrupt), use
spin_lock_irqsave() and
diff --git a/Documentation/locking/locktypes.rst b/Documentation/locking/locktypes.rst
index 4fd7b70fcde1..bfa75ea1b66a 100644
--- a/Documentation/locking/locktypes.rst
+++ b/Documentation/locking/locktypes.rst
@@ -247,7 +247,7 @@ based on rt_mutex which changes the semantics:
Non-PREEMPT_RT kernels disable preemption to get this effect.
PREEMPT_RT kernels use a per-CPU lock for serialization which keeps
- preemption disabled. The lock disables softirq handlers and also
+ preemption enabled. The lock disables softirq handlers and also
prevents reentrancy due to task preemption.
PREEMPT_RT kernels preserve all other spinlock_t semantics:
diff --git a/Documentation/maintainer/maintainer-entry-profile.rst b/Documentation/maintainer/maintainer-entry-profile.rst
index 5d5cc3acdf85..93b2ae6c34a9 100644
--- a/Documentation/maintainer/maintainer-entry-profile.rst
+++ b/Documentation/maintainer/maintainer-entry-profile.rst
@@ -103,3 +103,4 @@ to do something different in the near future.
../nvdimm/maintainer-entry-profile
../riscv/patch-acceptance
../driver-api/media/maintainer-entry-profile
+ ../driver-api/vfio-pci-device-specific-driver-acceptance
diff --git a/Documentation/networking/bonding.rst b/Documentation/networking/bonding.rst
index ab98373535ea..525e6842dd33 100644
--- a/Documentation/networking/bonding.rst
+++ b/Documentation/networking/bonding.rst
@@ -313,6 +313,17 @@ arp_ip_target
maximum number of targets that can be specified is 16. The
default value is no IP addresses.
+ns_ip6_target
+
+ Specifies the IPv6 addresses to use as IPv6 monitoring peers when
+ arp_interval is > 0. These are the targets of the NS request
+ sent to determine the health of the link to the targets.
+ Specify these values in ffff:ffff::ffff:ffff format. Multiple IPv6
+ addresses must be separated by a comma. At least one IPv6
+ address must be given for NS/NA monitoring to function. The
+ maximum number of targets that can be specified is 16. The
+ default value is no IPv6 addresses.
+
arp_validate
Specifies whether or not ARP probes and replies should be
diff --git a/Documentation/networking/devlink/index.rst b/Documentation/networking/devlink/index.rst
index 443123772f44..c17cdb079611 100644
--- a/Documentation/networking/devlink/index.rst
+++ b/Documentation/networking/devlink/index.rst
@@ -4,6 +4,22 @@ Linux Devlink Documentation
devlink is an API to expose device information and resources not directly
related to any device class, such as chip-wide/switch-ASIC-wide configuration.
+Locking
+-------
+
+Driver facing APIs are currently transitioning to allow more explicit
+locking. Drivers can use the existing ``devlink_*`` set of APIs, or
+new APIs prefixed by ``devl_*``. The older APIs handle all the locking
+in devlink core, but don't allow registration of most sub-objects once
+the main devlink object is itself registered. The newer ``devl_*`` APIs assume
+the devlink instance lock is already held. Drivers can take the instance
+lock by calling ``devl_lock()``. It is also held in most of the callbacks.
+Eventually all callbacks will be invoked under the devlink instance lock,
+refer to the use of the ``DEVLINK_NL_FLAG_NO_LOCK`` flag in devlink core
+to find out which callbacks are not converted, yet.
+
+Drivers are encouraged to use the devlink instance lock for their own needs.
+
Interface documentation
-----------------------
diff --git a/Documentation/networking/dsa/sja1105.rst b/Documentation/networking/dsa/sja1105.rst
index 29b1bae0cf00..e0219c1452ab 100644
--- a/Documentation/networking/dsa/sja1105.rst
+++ b/Documentation/networking/dsa/sja1105.rst
@@ -293,6 +293,33 @@ of dropped frames, which is a sum of frames dropped due to timing violations,
lack of destination ports and MTU enforcement checks). Byte-level counters are
not available.
+Limitations
+===========
+
+The SJA1105 switch family always performs VLAN processing. When configured as
+VLAN-unaware, frames carry a different VLAN tag internally, depending on
+whether the port is standalone or under a VLAN-unaware bridge.
+
+The virtual link keys are always fixed at {MAC DA, VLAN ID, VLAN PCP}, but the
+driver asks for the VLAN ID and VLAN PCP when the port is under a VLAN-aware
+bridge. Otherwise, it fills in the VLAN ID and PCP automatically, based on
+whether the port is standalone or in a VLAN-unaware bridge, and accepts only
+"VLAN-unaware" tc-flower keys (MAC DA).
+
+The existing tc-flower keys that are offloaded using virtual links are no
+longer operational after one of the following happens:
+
+- port was standalone and joins a bridge (VLAN-aware or VLAN-unaware)
+- port is part of a bridge whose VLAN awareness state changes
+- port was part of a bridge and becomes standalone
+- port was standalone, but another port joins a VLAN-aware bridge and this
+ changes the global VLAN awareness state of the bridge
+
+The driver cannot veto all these operations, and it cannot update/remove the
+existing tc-flower filters either. So for proper operation, the tc-flower
+filters should be installed only after the forwarding configuration of the port
+has been made, and removed by user space before making any changes to it.
+
Device Tree bindings and board design
=====================================
diff --git a/Documentation/networking/ethtool-netlink.rst b/Documentation/networking/ethtool-netlink.rst
index 9d98e0511249..24d9be69065d 100644
--- a/Documentation/networking/ethtool-netlink.rst
+++ b/Documentation/networking/ethtool-netlink.rst
@@ -860,8 +860,17 @@ Kernel response contents:
``ETHTOOL_A_RINGS_RX_JUMBO`` u32 size of RX jumbo ring
``ETHTOOL_A_RINGS_TX`` u32 size of TX ring
``ETHTOOL_A_RINGS_RX_BUF_LEN`` u32 size of buffers on the ring
+ ``ETHTOOL_A_RINGS_TCP_DATA_SPLIT`` u8 TCP header / data split
+ ``ETHTOOL_A_RINGS_CQE_SIZE`` u32 Size of TX/RX CQE
==================================== ====== ===========================
+``ETHTOOL_A_RINGS_TCP_DATA_SPLIT`` indicates whether the device is usable with
+page-flipping TCP zero-copy receive (``getsockopt(TCP_ZEROCOPY_RECEIVE)``).
+If enabled the device is configured to place frame headers and data into
+separate buffers. The device configuration must make it possible to receive
+full memory pages of data, for example because MTU is high enough or through
+HW-GRO.
+
RINGS_SET
=========
@@ -877,6 +886,7 @@ Request contents:
``ETHTOOL_A_RINGS_RX_JUMBO`` u32 size of RX jumbo ring
``ETHTOOL_A_RINGS_TX`` u32 size of TX ring
``ETHTOOL_A_RINGS_RX_BUF_LEN`` u32 size of buffers on the ring
+ ``ETHTOOL_A_RINGS_CQE_SIZE`` u32 Size of TX/RX CQE
==================================== ====== ===========================
Kernel checks that requested ring sizes do not exceed limits reported by
@@ -884,6 +894,15 @@ driver. Driver may impose additional constraints and may not suspport all
attributes.
+``ETHTOOL_A_RINGS_CQE_SIZE`` specifies the completion queue event size.
+Completion queue events(CQE) are the events posted by NIC to indicate the
+completion status of a packet when the packet is sent(like send success or
+error) or received(like pointers to packet fragments). The CQE size parameter
+enables to modify the CQE size other than default size if NIC supports it.
+A bigger CQE can have more receive buffer pointers inturn NIC can transfer
+a bigger frame from wire. Based on the NIC hardware, the overall completion
+queue size can be adjusted in the driver if CQE size is modified.
+
CHANNELS_GET
============
diff --git a/Documentation/networking/index.rst b/Documentation/networking/index.rst
index 58bc8cd367c6..ce017136ab05 100644
--- a/Documentation/networking/index.rst
+++ b/Documentation/networking/index.rst
@@ -96,6 +96,7 @@ Contents:
sctp
secid
seg6-sysctl
+ smc-sysctl
statistics
strparser
switchdev
diff --git a/Documentation/networking/ip-sysctl.rst b/Documentation/networking/ip-sysctl.rst
index 2572eecc3e86..b0024aa7b051 100644
--- a/Documentation/networking/ip-sysctl.rst
+++ b/Documentation/networking/ip-sysctl.rst
@@ -878,6 +878,29 @@ tcp_min_tso_segs - INTEGER
Default: 2
+tcp_tso_rtt_log - INTEGER
+ Adjustment of TSO packet sizes based on min_rtt
+
+ Starting from linux-5.18, TCP autosizing can be tweaked
+ for flows having small RTT.
+
+ Old autosizing was splitting the pacing budget to send 1024 TSO
+ per second.
+
+ tso_packet_size = sk->sk_pacing_rate / 1024;
+
+ With the new mechanism, we increase this TSO sizing using:
+
+ distance = min_rtt_usec / (2^tcp_tso_rtt_log)
+ tso_packet_size += gso_max_size >> distance;
+
+ This means that flows between very close hosts can use bigger
+ TSO packets, reducing their cpu costs.
+
+ If you want to use the old autosizing, set this sysctl to 0.
+
+ Default: 9 (2^9 = 512 usec)
+
tcp_pacing_ss_ratio - INTEGER
sk->sk_pacing_rate is set by TCP stack using a ratio applied
to current rate. (current_rate = cwnd * mss / srtt)
diff --git a/Documentation/networking/mctp.rst b/Documentation/networking/mctp.rst
index 46f74bffce0f..c628cb5406d2 100644
--- a/Documentation/networking/mctp.rst
+++ b/Documentation/networking/mctp.rst
@@ -212,6 +212,54 @@ remote address is already known, or the message does not require a reply.
Like the send calls, sockets will only receive responses to requests they have
sent (TO=1) and may only respond (TO=0) to requests they have received.
+``ioctl(SIOCMCTPALLOCTAG)`` and ``ioctl(SIOCMCTPDROPTAG)``
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+These tags give applications more control over MCTP message tags, by allocating
+(and dropping) tag values explicitly, rather than the kernel automatically
+allocating a per-message tag at ``sendmsg()`` time.
+
+In general, you will only need to use these ioctls if your MCTP protocol does
+not fit the usual request/response model. For example, if you need to persist
+tags across multiple requests, or a request may generate more than one response.
+In these cases, the ioctls allow you to decouple the tag allocation (and
+release) from individual message send and receive operations.
+
+Both ioctls are passed a pointer to a ``struct mctp_ioc_tag_ctl``:
+
+.. code-block:: C
+
+ struct mctp_ioc_tag_ctl {
+ mctp_eid_t peer_addr;
+ __u8 tag;
+ __u16 flags;
+ };
+
+``SIOCMCTPALLOCTAG`` allocates a tag for a specific peer, which an application
+can use in future ``sendmsg()`` calls. The application populates the
+``peer_addr`` member with the remote EID. Other fields must be zero.
+
+On return, the ``tag`` member will be populated with the allocated tag value.
+The allocated tag will have the following tag bits set:
+
+ - ``MCTP_TAG_OWNER``: it only makes sense to allocate tags if you're the tag
+ owner
+
+ - ``MCTP_TAG_PREALLOC``: to indicate to ``sendmsg()`` that this is a
+ preallocated tag.
+
+ - ... and the actual tag value, within the least-significant three bits
+ (``MCTP_TAG_MASK``). Note that zero is a valid tag value.
+
+The tag value should be used as-is for the ``smctp_tag`` member of ``struct
+sockaddr_mctp``.
+
+``SIOCMCTPDROPTAG`` releases a tag that has been previously allocated by a
+``SIOCMCTPALLOCTAG`` ioctl. The ``peer_addr`` must be the same as used for the
+allocation, and the ``tag`` value must match exactly the tag returned from the
+allocation (including the ``MCTP_TAG_OWNER`` and ``MCTP_TAG_PREALLOC`` bits).
+The ``flags`` field must be zero.
+
Kernel internals
================
diff --git a/Documentation/networking/page_pool.rst b/Documentation/networking/page_pool.rst
index a147591ce203..5db8c263b0c6 100644
--- a/Documentation/networking/page_pool.rst
+++ b/Documentation/networking/page_pool.rst
@@ -105,6 +105,47 @@ a page will cause no race conditions is enough.
Please note the caller must not use data area after running
page_pool_put_page_bulk(), as this function overwrites it.
+* page_pool_get_stats(): Retrieve statistics about the page_pool. This API
+ is only available if the kernel has been configured with
+ ``CONFIG_PAGE_POOL_STATS=y``. A pointer to a caller allocated ``struct
+ page_pool_stats`` structure is passed to this API which is filled in. The
+ caller can then report those stats to the user (perhaps via ethtool,
+ debugfs, etc.). See below for an example usage of this API.
+
+Stats API and structures
+------------------------
+If the kernel is configured with ``CONFIG_PAGE_POOL_STATS=y``, the API
+``page_pool_get_stats()`` and structures described below are available. It
+takes a pointer to a ``struct page_pool`` and a pointer to a ``struct
+page_pool_stats`` allocated by the caller.
+
+The API will fill in the provided ``struct page_pool_stats`` with
+statistics about the page_pool.
+
+The stats structure has the following fields::
+
+ struct page_pool_stats {
+ struct page_pool_alloc_stats alloc_stats;
+ struct page_pool_recycle_stats recycle_stats;
+ };
+
+
+The ``struct page_pool_alloc_stats`` has the following fields:
+ * ``fast``: successful fast path allocations
+ * ``slow``: slow path order-0 allocations
+ * ``slow_high_order``: slow path high order allocations
+ * ``empty``: ptr ring is empty, so a slow path allocation was forced.
+ * ``refill``: an allocation which triggered a refill of the cache
+ * ``waive``: pages obtained from the ptr ring that cannot be added to
+ the cache due to a NUMA mismatch.
+
+The ``struct page_pool_recycle_stats`` has the following fields:
+ * ``cached``: recycling placed page in the page pool cache
+ * ``cache_full``: page pool cache was full
+ * ``ring``: page placed into the ptr ring
+ * ``ring_full``: page released from page pool because the ptr ring was full
+ * ``released_refcnt``: page released (and not recycled) because refcnt > 1
+
Coding examples
===============
@@ -157,6 +198,21 @@ NAPI poller
}
}
+Stats
+-----
+
+.. code-block:: c
+
+ #ifdef CONFIG_PAGE_POOL_STATS
+ /* retrieve stats */
+ struct page_pool_stats stats = { 0 };
+ if (page_pool_get_stats(page_pool, &stats)) {
+ /* perhaps the driver reports statistics with ethool */
+ ethtool_print_allocation_stats(&stats.alloc_stats);
+ ethtool_print_recycle_stats(&stats.recycle_stats);
+ }
+ #endif
+
Driver unload
-------------
diff --git a/Documentation/networking/smc-sysctl.rst b/Documentation/networking/smc-sysctl.rst
new file mode 100644
index 000000000000..0987fd1bc220
--- /dev/null
+++ b/Documentation/networking/smc-sysctl.rst
@@ -0,0 +1,23 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+==========
+SMC Sysctl
+==========
+
+/proc/sys/net/smc/* Variables
+=============================
+
+autocorking_size - INTEGER
+ Setting SMC auto corking size:
+ SMC auto corking is like TCP auto corking from the application's
+ perspective of view. When applications do consecutive small
+ write()/sendmsg() system calls, we try to coalesce these small writes
+ as much as possible, to lower total amount of CDC and RDMA Write been
+ sent.
+ autocorking_size limits the maximum corked bytes that can be sent to
+ the under device in 1 single sending. If set to 0, the SMC auto corking
+ is disabled.
+ Applications can still use TCP_CORK for optimal behavior when they
+ know how/when to uncork their sockets.
+
+ Default: 64K
diff --git a/Documentation/networking/timestamping.rst b/Documentation/networking/timestamping.rst
index f5809206eb93..be4eb1242057 100644
--- a/Documentation/networking/timestamping.rst
+++ b/Documentation/networking/timestamping.rst
@@ -668,7 +668,7 @@ timestamping:
(through another RX timestamping FIFO). Deferral on RX is typically
necessary when retrieving the timestamp needs a sleepable context. In
that case, it is the responsibility of the DSA driver to call
- ``netif_rx_ni()`` on the freshly timestamped skb.
+ ``netif_rx()`` on the freshly timestamped skb.
3.2.2 Ethernet PHYs
^^^^^^^^^^^^^^^^^^^
diff --git a/Documentation/process/applying-patches.rst b/Documentation/process/applying-patches.rst
index c2121c1e55d7..c269f5e1a0a3 100644
--- a/Documentation/process/applying-patches.rst
+++ b/Documentation/process/applying-patches.rst
@@ -249,6 +249,10 @@ The 5.x.y (-stable) and 5.x patches live at
https://www.kernel.org/pub/linux/kernel/v5.x/
+The 5.x.y incremental patches live at
+
+ https://www.kernel.org/pub/linux/kernel/v5.x/incr/
+
The -rc patches are not stored on the webserver but are generated on
demand from git tags such as
@@ -308,12 +312,11 @@ versions.
If no 5.x.y kernel is available, then the highest numbered 5.x kernel is
the current stable kernel.
-.. note::
+The -stable team provides normal as well as incremental patches. Below is
+how to apply these patches.
- The -stable team usually do make incremental patches available as well
- as patches against the latest mainline release, but I only cover the
- non-incremental ones below. The incremental ones can be found at
- https://www.kernel.org/pub/linux/kernel/v5.x/incr/
+Normal patches
+~~~~~~~~~~~~~~
These patches are not incremental, meaning that for example the 5.7.3
patch does not apply on top of the 5.7.2 kernel source, but rather on top
@@ -331,6 +334,21 @@ Here's a small example::
$ cd ..
$ mv linux-5.7.2 linux-5.7.3 # rename the kernel source dir
+Incremental patches
+~~~~~~~~~~~~~~~~~~~
+
+Incremental patches are different: instead of being applied on top
+of base 5.x kernel, they are applied on top of previous stable kernel
+(5.x.y-1).
+
+Here's the example to apply these::
+
+ $ cd ~/linux-5.7.2 # change to the kernel source dir
+ $ patch -p1 < ../patch-5.7.2-3 # apply the new 5.7.3 patch
+ $ cd ..
+ $ mv linux-5.7.2 linux-5.7.3 # rename the kernel source dir
+
+
The -rc kernels
===============
diff --git a/Documentation/process/deprecated.rst b/Documentation/process/deprecated.rst
index 388cb19f5dbb..a6e36d9c3d14 100644
--- a/Documentation/process/deprecated.rst
+++ b/Documentation/process/deprecated.rst
@@ -71,6 +71,9 @@ Instead, the 2-factor form of the allocator should be used::
foo = kmalloc_array(count, size, GFP_KERNEL);
+Specifically, kmalloc() can be replaced with kmalloc_array(), and
+kzalloc() can be replaced with kcalloc().
+
If no 2-factor form is available, the saturate-on-overflow helpers should
be used::
@@ -91,9 +94,20 @@ Instead, use the helper::
array usage and switch to a `flexible array member
<#zero-length-and-one-element-arrays>`_ instead.
-See array_size(), array3_size(), and struct_size(),
-for more details as well as the related check_add_overflow() and
-check_mul_overflow() family of functions.
+For other calculations, please compose the use of the size_mul(),
+size_add(), and size_sub() helpers. For example, in the case of::
+
+ foo = krealloc(current_size + chunk_size * (count - 3), GFP_KERNEL);
+
+Instead, use the helpers::
+
+ foo = krealloc(size_add(current_size,
+ size_mul(chunk_size,
+ size_sub(count, 3))), GFP_KERNEL);
+
+For more details, also see array3_size() and flex_array_size(),
+as well as the related check_mul_overflow(), check_add_overflow(),
+check_sub_overflow(), and check_shl_overflow() family of functions.
simple_strtol(), simple_strtoll(), simple_strtoul(), simple_strtoull()
----------------------------------------------------------------------
diff --git a/Documentation/process/handling-regressions.rst b/Documentation/process/handling-regressions.rst
new file mode 100644
index 000000000000..abb741b1aeee
--- /dev/null
+++ b/Documentation/process/handling-regressions.rst
@@ -0,0 +1,746 @@
+.. SPDX-License-Identifier: (GPL-2.0+ OR CC-BY-4.0)
+.. See the bottom of this file for additional redistribution information.
+
+Handling regressions
+++++++++++++++++++++
+
+*We don't cause regressions* -- this document describes what this "first rule of
+Linux kernel development" means in practice for developers. It complements
+Documentation/admin-guide/reporting-regressions.rst, which covers the topic from a
+user's point of view; if you never read that text, go and at least skim over it
+before continuing here.
+
+The important bits (aka "The TL;DR")
+====================================
+
+#. Ensure subscribers of the `regression mailing list <https://lore.kernel.org/regressions/>`_
+ (regressions@lists.linux.dev) quickly become aware of any new regression
+ report:
+
+ * When receiving a mailed report that did not CC the list, bring it into the
+ loop by immediately sending at least a brief "Reply-all" with the list
+ CCed.
+
+ * Forward or bounce any reports submitted in bug trackers to the list.
+
+#. Make the Linux kernel regression tracking bot "regzbot" track the issue (this
+ is optional, but recommended):
+
+ * For mailed reports, check if the reporter included a line like ``#regzbot
+ introduced v5.13..v5.14-rc1``. If not, send a reply (with the regressions
+ list in CC) containing a paragraph like the following, which tells regzbot
+ when the issue started to happen::
+
+ #regzbot ^introduced 1f2e3d4c5b6a
+
+ * When forwarding reports from a bug tracker to the regressions list (see
+ above), include a paragraph like the following::
+
+ #regzbot introduced: v5.13..v5.14-rc1
+ #regzbot from: Some N. Ice Human <some.human@example.com>
+ #regzbot monitor: http://some.bugtracker.example.com/ticket?id=123456789
+
+#. When submitting fixes for regressions, add "Link:" tags to the patch
+ description pointing to all places where the issue was reported, as
+ mandated by Documentation/process/submitting-patches.rst and
+ :ref:`Documentation/process/5.Posting.rst <development_posting>`.
+
+#. Try to fix regressions quickly once the culprit has been identified; fixes
+ for most regressions should be merged within two weeks, but some need to be
+ resolved within two or three days.
+
+
+All the details on Linux kernel regressions relevant for developers
+===================================================================
+
+
+The important basics in more detail
+-----------------------------------
+
+
+What to do when receiving regression reports
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Ensure the Linux kernel's regression tracker and others subscribers of the
+`regression mailing list <https://lore.kernel.org/regressions/>`_
+(regressions@lists.linux.dev) become aware of any newly reported regression:
+
+ * When you receive a report by mail that did not CC the list, immediately bring
+ it into the loop by sending at least a brief "Reply-all" with the list CCed;
+ try to ensure it gets CCed again in case you reply to a reply that omitted
+ the list.
+
+ * If a report submitted in a bug tracker hits your Inbox, forward or bounce it
+ to the list. Consider checking the list archives beforehand, if the reporter
+ already forwarded the report as instructed by
+ Documentation/admin-guide/reporting-issues.rst.
+
+When doing either, consider making the Linux kernel regression tracking bot
+"regzbot" immediately start tracking the issue:
+
+ * For mailed reports, check if the reporter included a "regzbot command" like
+ ``#regzbot introduced 1f2e3d4c5b6a``. If not, send a reply (with the
+ regressions list in CC) with a paragraph like the following:::
+
+ #regzbot ^introduced: v5.13..v5.14-rc1
+
+ This tells regzbot the version range in which the issue started to happen;
+ you can specify a range using commit-ids as well or state a single commit-id
+ in case the reporter bisected the culprit.
+
+ Note the caret (^) before the "introduced": it tells regzbot to treat the
+ parent mail (the one you reply to) as the initial report for the regression
+ you want to see tracked; that's important, as regzbot will later look out
+ for patches with "Link:" tags pointing to the report in the archives on
+ lore.kernel.org.
+
+ * When forwarding a regressions reported to a bug tracker, include a paragraph
+ with these regzbot commands::
+
+ #regzbot introduced: 1f2e3d4c5b6a
+ #regzbot from: Some N. Ice Human <some.human@example.com>
+ #regzbot monitor: http://some.bugtracker.example.com/ticket?id=123456789
+
+ Regzbot will then automatically associate patches with the report that
+ contain "Link:" tags pointing to your mail or the mentioned ticket.
+
+What's important when fixing regressions
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You don't need to do anything special when submitting fixes for regression, just
+remember to do what Documentation/process/submitting-patches.rst,
+:ref:`Documentation/process/5.Posting.rst <development_posting>`, and
+Documentation/process/stable-kernel-rules.rst already explain in more detail:
+
+ * Point to all places where the issue was reported using "Link:" tags::
+
+ Link: https://lore.kernel.org/r/30th.anniversary.repost@klaava.Helsinki.FI/
+ Link: https://bugzilla.kernel.org/show_bug.cgi?id=1234567890
+
+ * Add a "Fixes:" tag to specify the commit causing the regression.
+
+ * If the culprit was merged in an earlier development cycle, explicitly mark
+ the fix for backporting using the ``Cc: stable@vger.kernel.org`` tag.
+
+All this is expected from you and important when it comes to regression, as
+these tags are of great value for everyone (you included) that might be looking
+into the issue weeks, months, or years later. These tags are also crucial for
+tools and scripts used by other kernel developers or Linux distributions; one of
+these tools is regzbot, which heavily relies on the "Link:" tags to associate
+reports for regression with changes resolving them.
+
+Prioritize work on fixing regressions
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You should fix any reported regression as quickly as possible, to provide
+affected users with a solution in a timely manner and prevent more users from
+running into the issue; nevertheless developers need to take enough time and
+care to ensure regression fixes do not cause additional damage.
+
+In the end though, developers should give their best to prevent users from
+running into situations where a regression leaves them only three options: "run
+a kernel with a regression that seriously impacts usage", "continue running an
+outdated and thus potentially insecure kernel version for more than two weeks
+after a regression's culprit was identified", and "downgrade to a still
+supported kernel series that lack required features".
+
+How to realize this depends a lot on the situation. Here are a few rules of
+thumb for you, in order or importance:
+
+ * Prioritize work on handling regression reports and fixing regression over all
+ other Linux kernel work, unless the latter concerns acute security issues or
+ bugs causing data loss or damage.
+
+ * Always consider reverting the culprit commits and reapplying them later
+ together with necessary fixes, as this might be the least dangerous and
+ quickest way to fix a regression.
+
+ * Developers should handle regressions in all supported kernel series, but are
+ free to delegate the work to the stable team, if the issue probably at no
+ point in time occurred with mainline.
+
+ * Try to resolve any regressions introduced in the current development before
+ its end. If you fear a fix might be too risky to apply only days before a new
+ mainline release, let Linus decide: submit the fix separately to him as soon
+ as possible with the explanation of the situation. He then can make a call
+ and postpone the release if necessary, for example if multiple such changes
+ show up in his inbox.
+
+ * Address regressions in stable, longterm, or proper mainline releases with
+ more urgency than regressions in mainline pre-releases. That changes after
+ the release of the fifth pre-release, aka "-rc5": mainline then becomes as
+ important, to ensure all the improvements and fixes are ideally tested
+ together for at least one week before Linus releases a new mainline version.
+
+ * Fix regressions within two or three days, if they are critical for some
+ reason -- for example, if the issue is likely to affect many users of the
+ kernel series in question on all or certain architectures. Note, this
+ includes mainline, as issues like compile errors otherwise might prevent many
+ testers or continuous integration systems from testing the series.
+
+ * Aim to fix regressions within one week after the culprit was identified, if
+ the issue was introduced in either:
+
+ * a recent stable/longterm release
+
+ * the development cycle of the latest proper mainline release
+
+ In the latter case (say Linux v5.14), try to address regressions even
+ quicker, if the stable series for the predecessor (v5.13) will be abandoned
+ soon or already was stamped "End-of-Life" (EOL) -- this usually happens about
+ three to four weeks after a new mainline release.
+
+ * Try to fix all other regressions within two weeks after the culprit was
+ found. Two or three additional weeks are acceptable for performance
+ regressions and other issues which are annoying, but don't prevent anyone
+ from running Linux (unless it's an issue in the current development cycle,
+ as those should ideally be addressed before the release). A few weeks in
+ total are acceptable if a regression can only be fixed with a risky change
+ and at the same time is affecting only a few users; as much time is
+ also okay if the regression is already present in the second newest longterm
+ kernel series.
+
+Note: The aforementioned time frames for resolving regressions are meant to
+include getting the fix tested, reviewed, and merged into mainline, ideally with
+the fix being in linux-next at least briefly. This leads to delays you need to
+account for.
+
+Subsystem maintainers are expected to assist in reaching those periods by doing
+timely reviews and quick handling of accepted patches. They thus might have to
+send git-pull requests earlier or more often than usual; depending on the fix,
+it might even be acceptable to skip testing in linux-next. Especially fixes for
+regressions in stable and longterm kernels need to be handled quickly, as fixes
+need to be merged in mainline before they can be backported to older series.
+
+
+More aspects regarding regressions developers should be aware of
+----------------------------------------------------------------
+
+
+How to deal with changes where a risk of regression is known
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Evaluate how big the risk of regressions is, for example by performing a code
+search in Linux distributions and Git forges. Also consider asking other
+developers or projects likely to be affected to evaluate or even test the
+proposed change; if problems surface, maybe some solution acceptable for all
+can be found.
+
+If the risk of regressions in the end seems to be relatively small, go ahead
+with the change, but let all involved parties know about the risk. Hence, make
+sure your patch description makes this aspect obvious. Once the change is
+merged, tell the Linux kernel's regression tracker and the regressions mailing
+list about the risk, so everyone has the change on the radar in case reports
+trickle in. Depending on the risk, you also might want to ask the subsystem
+maintainer to mention the issue in his mainline pull request.
+
+What else is there to known about regressions?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Check out Documentation/admin-guide/reporting-regressions.rst, it covers a lot
+of other aspects you want might want to be aware of:
+
+ * the purpose of the "no regressions rule"
+
+ * what issues actually qualify as regression
+
+ * who's in charge for finding the root cause of a regression
+
+ * how to handle tricky situations, e.g. when a regression is caused by a
+ security fix or when fixing a regression might cause another one
+
+Whom to ask for advice when it comes to regressions
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Send a mail to the regressions mailing list (regressions@lists.linux.dev) while
+CCing the Linux kernel's regression tracker (regressions@leemhuis.info); if the
+issue might better be dealt with in private, feel free to omit the list.
+
+
+More about regression tracking and regzbot
+------------------------------------------
+
+
+Why the Linux kernel has a regression tracker, and why is regzbot used?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Rules like "no regressions" need someone to ensure they are followed, otherwise
+they are broken either accidentally or on purpose. History has shown this to be
+true for the Linux kernel as well. That's why Thorsten Leemhuis volunteered to
+keep an eye on things as the Linux kernel's regression tracker, who's
+occasionally helped by other people. Neither of them are paid to do this,
+that's why regression tracking is done on a best effort basis.
+
+Earlier attempts to manually track regressions have shown it's an exhausting and
+frustrating work, which is why they were abandoned after a while. To prevent
+this from happening again, Thorsten developed regzbot to facilitate the work,
+with the long term goal to automate regression tracking as much as possible for
+everyone involved.
+
+How does regression tracking work with regzbot?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The bot watches for replies to reports of tracked regressions. Additionally,
+it's looking out for posted or committed patches referencing such reports
+with "Link:" tags; replies to such patch postings are tracked as well.
+Combined this data provides good insights into the current state of the fixing
+process.
+
+Regzbot tries to do its job with as little overhead as possible for both
+reporters and developers. In fact, only reporters are burdened with an extra
+duty: they need to tell regzbot about the regression report using the ``#regzbot
+introduced`` command outlined above; if they don't do that, someone else can
+take care of that using ``#regzbot ^introduced``.
+
+For developers there normally is no extra work involved, they just need to make
+sure to do something that was expected long before regzbot came to light: add
+"Link:" tags to the patch description pointing to all reports about the issue
+fixed.
+
+Do I have to use regzbot?
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+It's in the interest of everyone if you do, as kernel maintainers like Linus
+Torvalds partly rely on regzbot's tracking in their work -- for example when
+deciding to release a new version or extend the development phase. For this they
+need to be aware of all unfixed regression; to do that, Linus is known to look
+into the weekly reports sent by regzbot.
+
+Do I have to tell regzbot about every regression I stumble upon?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Ideally yes: we are all humans and easily forget problems when something more
+important unexpectedly comes up -- for example a bigger problem in the Linux
+kernel or something in real life that's keeping us away from keyboards for a
+while. Hence, it's best to tell regzbot about every regression, except when you
+immediately write a fix and commit it to a tree regularly merged to the affected
+kernel series.
+
+How to see which regressions regzbot tracks currently?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Check `regzbot's web-interface <https://linux-regtracking.leemhuis.info/regzbot/>`_
+for the latest info; alternatively, `search for the latest regression report
+<https://lore.kernel.org/lkml/?q=%22Linux+regressions+report%22+f%3Aregzbot>`_,
+which regzbot normally sends out once a week on Sunday evening (UTC), which is a
+few hours before Linus usually publishes new (pre-)releases.
+
+What places is regzbot monitoring?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Regzbot is watching the most important Linux mailing lists as well as the git
+repositories of linux-next, mainline, and stable/longterm.
+
+What kind of issues are supposed to be tracked by regzbot?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The bot is meant to track regressions, hence please don't involve regzbot for
+regular issues. But it's okay for the Linux kernel's regression tracker if you
+use regzbot to track severe issues, like reports about hangs, corrupted data,
+or internal errors (Panic, Oops, BUG(), warning, ...).
+
+Can I add regressions found by CI systems to regzbot's tracking?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Feel free to do so, if the particular regression likely has impact on practical
+use cases and thus might be noticed by users; hence, please don't involve
+regzbot for theoretical regressions unlikely to show themselves in real world
+usage.
+
+How to interact with regzbot?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+By using a 'regzbot command' in a direct or indirect reply to the mail with the
+regression report. These commands need to be in their own paragraph (IOW: they
+need to be separated from the rest of the mail using blank lines).
+
+One such command is ``#regzbot introduced <version or commit>``, which makes
+regzbot consider your mail as a regressions report added to the tracking, as
+already described above; ``#regzbot ^introduced <version or commit>`` is another
+such command, which makes regzbot consider the parent mail as a report for a
+regression which it starts to track.
+
+Once one of those two commands has been utilized, other regzbot commands can be
+used in direct or indirect replies to the report. You can write them below one
+of the `introduced` commands or in replies to the mail that used one of them
+or itself is a reply to that mail:
+
+ * Set or update the title::
+
+ #regzbot title: foo
+
+ * Monitor a discussion or bugzilla.kernel.org ticket where additions aspects of
+ the issue or a fix are discussed -- for example the posting of a patch fixing
+ the regression::
+
+ #regzbot monitor: https://lore.kernel.org/all/30th.anniversary.repost@klaava.Helsinki.FI/
+
+ Monitoring only works for lore.kernel.org and bugzilla.kernel.org; regzbot
+ will consider all messages in that thread or ticket as related to the fixing
+ process.
+
+ * Point to a place with further details of interest, like a mailing list post
+ or a ticket in a bug tracker that are slightly related, but about a different
+ topic::
+
+ #regzbot link: https://bugzilla.kernel.org/show_bug.cgi?id=123456789
+
+ * Mark a regression as fixed by a commit that is heading upstream or already
+ landed::
+
+ #regzbot fixed-by: 1f2e3d4c5d
+
+ * Mark a regression as a duplicate of another one already tracked by regzbot::
+
+ #regzbot dup-of: https://lore.kernel.org/all/30th.anniversary.repost@klaava.Helsinki.FI/
+
+ * Mark a regression as invalid::
+
+ #regzbot invalid: wasn't a regression, problem has always existed
+
+Is there more to tell about regzbot and its commands?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+More detailed and up-to-date information about the Linux
+kernel's regression tracking bot can be found on its
+`project page <https://gitlab.com/knurd42/regzbot>`_, which among others
+contains a `getting started guide <https://gitlab.com/knurd42/regzbot/-/blob/main/docs/getting_started.md>`_
+and `reference documentation <https://gitlab.com/knurd42/regzbot/-/blob/main/docs/reference.md>`_
+which both cover more details than the above section.
+
+Quotes from Linus about regression
+----------------------------------
+
+Find below a few real life examples of how Linus Torvalds expects regressions to
+be handled:
+
+ * From `2017-10-26 (1/2)
+ <https://lore.kernel.org/lkml/CA+55aFwiiQYJ+YoLKCXjN_beDVfu38mg=Ggg5LFOcqHE8Qi7Zw@mail.gmail.com/>`_::
+
+ If you break existing user space setups THAT IS A REGRESSION.
+
+ It's not ok to say "but we'll fix the user space setup".
+
+ Really. NOT OK.
+
+ [...]
+
+ The first rule is:
+
+ - we don't cause regressions
+
+ and the corollary is that when regressions *do* occur, we admit to
+ them and fix them, instead of blaming user space.
+
+ The fact that you have apparently been denying the regression now for
+ three weeks means that I will revert, and I will stop pulling apparmor
+ requests until the people involved understand how kernel development
+ is done.
+
+ * From `2017-10-26 (2/2)
+ <https://lore.kernel.org/lkml/CA+55aFxW7NMAMvYhkvz1UPbUTUJewRt6Yb51QAx5RtrWOwjebg@mail.gmail.com/>`_::
+
+ People should basically always feel like they can update their kernel
+ and simply not have to worry about it.
+
+ I refuse to introduce "you can only update the kernel if you also
+ update that other program" kind of limitations. If the kernel used to
+ work for you, the rule is that it continues to work for you.
+
+ There have been exceptions, but they are few and far between, and they
+ generally have some major and fundamental reasons for having happened,
+ that were basically entirely unavoidable, and people _tried_hard_ to
+ avoid them. Maybe we can't practically support the hardware any more
+ after it is decades old and nobody uses it with modern kernels any
+ more. Maybe there's a serious security issue with how we did things,
+ and people actually depended on that fundamentally broken model. Maybe
+ there was some fundamental other breakage that just _had_ to have a
+ flag day for very core and fundamental reasons.
+
+ And notice that this is very much about *breaking* peoples environments.
+
+ Behavioral changes happen, and maybe we don't even support some
+ feature any more. There's a number of fields in /proc/<pid>/stat that
+ are printed out as zeroes, simply because they don't even *exist* in
+ the kernel any more, or because showing them was a mistake (typically
+ an information leak). But the numbers got replaced by zeroes, so that
+ the code that used to parse the fields still works. The user might not
+ see everything they used to see, and so behavior is clearly different,
+ but things still _work_, even if they might no longer show sensitive
+ (or no longer relevant) information.
+
+ But if something actually breaks, then the change must get fixed or
+ reverted. And it gets fixed in the *kernel*. Not by saying "well, fix
+ your user space then". It was a kernel change that exposed the
+ problem, it needs to be the kernel that corrects for it, because we
+ have a "upgrade in place" model. We don't have a "upgrade with new
+ user space".
+
+ And I seriously will refuse to take code from people who do not
+ understand and honor this very simple rule.
+
+ This rule is also not going to change.
+
+ And yes, I realize that the kernel is "special" in this respect. I'm
+ proud of it.
+
+ I have seen, and can point to, lots of projects that go "We need to
+ break that use case in order to make progress" or "you relied on
+ undocumented behavior, it sucks to be you" or "there's a better way to
+ do what you want to do, and you have to change to that new better
+ way", and I simply don't think that's acceptable outside of very early
+ alpha releases that have experimental users that know what they signed
+ up for. The kernel hasn't been in that situation for the last two
+ decades.
+
+ We do API breakage _inside_ the kernel all the time. We will fix
+ internal problems by saying "you now need to do XYZ", but then it's
+ about internal kernel API's, and the people who do that then also
+ obviously have to fix up all the in-kernel users of that API. Nobody
+ can say "I now broke the API you used, and now _you_ need to fix it
+ up". Whoever broke something gets to fix it too.
+
+ And we simply do not break user space.
+
+ * From `2020-05-21
+ <https://lore.kernel.org/all/CAHk-=wiVi7mSrsMP=fLXQrXK_UimybW=ziLOwSzFTtoXUacWVQ@mail.gmail.com/>`_::
+
+ The rules about regressions have never been about any kind of
+ documented behavior, or where the code lives.
+
+ The rules about regressions are always about "breaks user workflow".
+
+ Users are literally the _only_ thing that matters.
+
+ No amount of "you shouldn't have used this" or "that behavior was
+ undefined, it's your own fault your app broke" or "that used to work
+ simply because of a kernel bug" is at all relevant.
+
+ Now, reality is never entirely black-and-white. So we've had things
+ like "serious security issue" etc that just forces us to make changes
+ that may break user space. But even then the rule is that we don't
+ really have other options that would allow things to continue.
+
+ And obviously, if users take years to even notice that something
+ broke, or if we have sane ways to work around the breakage that
+ doesn't make for too much trouble for users (ie "ok, there are a
+ handful of users, and they can use a kernel command line to work
+ around it" kind of things) we've also been a bit less strict.
+
+ But no, "that was documented to be broken" (whether it's because the
+ code was in staging or because the man-page said something else) is
+ irrelevant. If staging code is so useful that people end up using it,
+ that means that it's basically regular kernel code with a flag saying
+ "please clean this up".
+
+ The other side of the coin is that people who talk about "API
+ stability" are entirely wrong. API's don't matter either. You can make
+ any changes to an API you like - as long as nobody notices.
+
+ Again, the regression rule is not about documentation, not about
+ API's, and not about the phase of the moon.
+
+ It's entirely about "we caused problems for user space that used to work".
+
+ * From `2017-11-05
+ <https://lore.kernel.org/all/CA+55aFzUvbGjD8nQ-+3oiMBx14c_6zOj2n7KLN3UsJ-qsd4Dcw@mail.gmail.com/>`_::
+
+ And our regression rule has never been "behavior doesn't change".
+ That would mean that we could never make any changes at all.
+
+ For example, we do things like add new error handling etc all the
+ time, which we then sometimes even add tests for in our kselftest
+ directory.
+
+ So clearly behavior changes all the time and we don't consider that a
+ regression per se.
+
+ The rule for a regression for the kernel is that some real user
+ workflow breaks. Not some test. Not a "look, I used to be able to do
+ X, now I can't".
+
+ * From `2018-08-03
+ <https://lore.kernel.org/all/CA+55aFwWZX=CXmWDTkDGb36kf12XmTehmQjbiMPCqCRG2hi9kw@mail.gmail.com/>`_::
+
+ YOU ARE MISSING THE #1 KERNEL RULE.
+
+ We do not regress, and we do not regress exactly because your are 100% wrong.
+
+ And the reason you state for your opinion is in fact exactly *WHY* you
+ are wrong.
+
+ Your "good reasons" are pure and utter garbage.
+
+ The whole point of "we do not regress" is so that people can upgrade
+ the kernel and never have to worry about it.
+
+ > Kernel had a bug which has been fixed
+
+ That is *ENTIRELY* immaterial.
+
+ Guys, whether something was buggy or not DOES NOT MATTER.
+
+ Why?
+
+ Bugs happen. That's a fact of life. Arguing that "we had to break
+ something because we were fixing a bug" is completely insane. We fix
+ tens of bugs every single day, thinking that "fixing a bug" means that
+ we can break something is simply NOT TRUE.
+
+ So bugs simply aren't even relevant to the discussion. They happen,
+ they get found, they get fixed, and it has nothing to do with "we
+ break users".
+
+ Because the only thing that matters IS THE USER.
+
+ How hard is that to understand?
+
+ Anybody who uses "but it was buggy" as an argument is entirely missing
+ the point. As far as the USER was concerned, it wasn't buggy - it
+ worked for him/her.
+
+ Maybe it worked *because* the user had taken the bug into account,
+ maybe it worked because the user didn't notice - again, it doesn't
+ matter. It worked for the user.
+
+ Breaking a user workflow for a "bug" is absolutely the WORST reason
+ for breakage you can imagine.
+
+ It's basically saying "I took something that worked, and I broke it,
+ but now it's better". Do you not see how f*cking insane that statement
+ is?
+
+ And without users, your program is not a program, it's a pointless
+ piece of code that you might as well throw away.
+
+ Seriously. This is *why* the #1 rule for kernel development is "we
+ don't break users". Because "I fixed a bug" is absolutely NOT AN
+ ARGUMENT if that bug fix broke a user setup. You actually introduced a
+ MUCH BIGGER bug by "fixing" something that the user clearly didn't
+ even care about.
+
+ And dammit, we upgrade the kernel ALL THE TIME without upgrading any
+ other programs at all. It is absolutely required, because flag-days
+ and dependencies are horribly bad.
+
+ And it is also required simply because I as a kernel developer do not
+ upgrade random other tools that I don't even care about as I develop
+ the kernel, and I want any of my users to feel safe doing the same
+ time.
+
+ So no. Your rule is COMPLETELY wrong. If you cannot upgrade a kernel
+ without upgrading some other random binary, then we have a problem.
+
+ * From `2021-06-05
+ <https://lore.kernel.org/all/CAHk-=wiUVqHN76YUwhkjZzwTdjMMJf_zN4+u7vEJjmEGh3recw@mail.gmail.com/>`_::
+
+ THERE ARE NO VALID ARGUMENTS FOR REGRESSIONS.
+
+ Honestly, security people need to understand that "not working" is not
+ a success case of security. It's a failure case.
+
+ Yes, "not working" may be secure. But security in that case is *pointless*.
+
+ * From `2011-05-06 (1/3)
+ <https://lore.kernel.org/all/BANLkTim9YvResB+PwRp7QTK-a5VNg2PvmQ@mail.gmail.com/>`_::
+
+ Binary compatibility is more important.
+
+ And if binaries don't use the interface to parse the format (or just
+ parse it wrongly - see the fairly recent example of adding uuid's to
+ /proc/self/mountinfo), then it's a regression.
+
+ And regressions get reverted, unless there are security issues or
+ similar that makes us go "Oh Gods, we really have to break things".
+
+ I don't understand why this simple logic is so hard for some kernel
+ developers to understand. Reality matters. Your personal wishes matter
+ NOT AT ALL.
+
+ If you made an interface that can be used without parsing the
+ interface description, then we're stuck with the interface. Theory
+ simply doesn't matter.
+
+ You could help fix the tools, and try to avoid the compatibility
+ issues that way. There aren't that many of them.
+
+ From `2011-05-06 (2/3)
+ <https://lore.kernel.org/all/BANLkTi=KVXjKR82sqsz4gwjr+E0vtqCmvA@mail.gmail.com/>`_::
+
+ it's clearly NOT an internal tracepoint. By definition. It's being
+ used by powertop.
+
+ From `2011-05-06 (3/3)
+ <https://lore.kernel.org/all/BANLkTinazaXRdGovYL7rRVp+j6HbJ7pzhg@mail.gmail.com/>`_::
+
+ We have programs that use that ABI and thus it's a regression if they break.
+
+ * From `2012-07-06 <https://lore.kernel.org/all/CA+55aFwnLJ+0sjx92EGREGTWOx84wwKaraSzpTNJwPVV8edw8g@mail.gmail.com/>`_::
+
+ > Now this got me wondering if Debian _unstable_ actually qualifies as a
+ > standard distro userspace.
+
+ Oh, if the kernel breaks some standard user space, that counts. Tons
+ of people run Debian unstable
+
+ * From `2019-09-15
+ <https://lore.kernel.org/lkml/CAHk-=wiP4K8DRJWsCo=20hn_6054xBamGKF2kPgUzpB5aMaofA@mail.gmail.com/>`_::
+
+ One _particularly_ last-minute revert is the top-most commit (ignoring
+ the version change itself) done just before the release, and while
+ it's very annoying, it's perhaps also instructive.
+
+ What's instructive about it is that I reverted a commit that wasn't
+ actually buggy. In fact, it was doing exactly what it set out to do,
+ and did it very well. In fact it did it _so_ well that the much
+ improved IO patterns it caused then ended up revealing a user-visible
+ regression due to a real bug in a completely unrelated area.
+
+ The actual details of that regression are not the reason I point that
+ revert out as instructive, though. It's more that it's an instructive
+ example of what counts as a regression, and what the whole "no
+ regressions" kernel rule means. The reverted commit didn't change any
+ API's, and it didn't introduce any new bugs. But it ended up exposing
+ another problem, and as such caused a kernel upgrade to fail for a
+ user. So it got reverted.
+
+ The point here being that we revert based on user-reported _behavior_,
+ not based on some "it changes the ABI" or "it caused a bug" concept.
+ The problem was really pre-existing, and it just didn't happen to
+ trigger before. The better IO patterns introduced by the change just
+ happened to expose an old bug, and people had grown to depend on the
+ previously benign behavior of that old issue.
+
+ And never fear, we'll re-introduce the fix that improved on the IO
+ patterns once we've decided just how to handle the fact that we had a
+ bad interaction with an interface that people had then just happened
+ to rely on incidental behavior for before. It's just that we'll have
+ to hash through how to do that (there are no less than three different
+ patches by three different developers being discussed, and there might
+ be more coming...). In the meantime, I reverted the thing that exposed
+ the problem to users for this release, even if I hope it will be
+ re-introduced (perhaps even backported as a stable patch) once we have
+ consensus about the issue it exposed.
+
+ Take-away from the whole thing: it's not about whether you change the
+ kernel-userspace ABI, or fix a bug, or about whether the old code
+ "should never have worked in the first place". It's about whether
+ something breaks existing users' workflow.
+
+ Anyway, that was my little aside on the whole regression thing. Since
+ it's that "first rule of kernel programming", I felt it is perhaps
+ worth just bringing it up every once in a while
+
+..
+ end-of-content
+..
+ This text is available under GPL-2.0+ or CC-BY-4.0, as stated at the top
+ of the file. If you want to distribute this text under CC-BY-4.0 only,
+ please use "The Linux kernel developers" for author attribution and link
+ this as source:
+ https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/plain/Documentation/process/handling-regressions.rst
+..
+ Note: Only the content of this RST file as found in the Linux kernel sources
+ is available under CC-BY-4.0, as versions of this text that were processed
+ (for example by the kernel's build system) might contain content taken from
+ files which use a more restrictive license.
diff --git a/Documentation/process/index.rst b/Documentation/process/index.rst
index 9f1b88492bb3..3587dae4d0ef 100644
--- a/Documentation/process/index.rst
+++ b/Documentation/process/index.rst
@@ -25,6 +25,7 @@ Below are the essential guides that every developer should read.
code-of-conduct-interpretation
development-process
submitting-patches
+ handling-regressions
programming-language
coding-style
maintainer-handbooks
@@ -48,6 +49,7 @@ Other guides to the community that are of interest to most developers are:
deprecated
embargoed-hardware-issues
maintainers
+ researcher-guidelines
These are some overall technical guides that have been put here for now for
lack of a better place.
diff --git a/Documentation/process/researcher-guidelines.rst b/Documentation/process/researcher-guidelines.rst
new file mode 100644
index 000000000000..afc944e0e898
--- /dev/null
+++ b/Documentation/process/researcher-guidelines.rst
@@ -0,0 +1,143 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+.. _researcher_guidelines:
+
+Researcher Guidelines
++++++++++++++++++++++
+
+The Linux kernel community welcomes transparent research on the Linux
+kernel, the activities involved in producing it, and any other byproducts
+of its development. Linux benefits greatly from this kind of research, and
+most aspects of Linux are driven by research in one form or another.
+
+The community greatly appreciates if researchers can share preliminary
+findings before making their results public, especially if such research
+involves security. Getting involved early helps both improve the quality
+of research and ability for Linux to improve from it. In any case,
+sharing open access copies of the published research with the community
+is recommended.
+
+This document seeks to clarify what the Linux kernel community considers
+acceptable and non-acceptable practices when conducting such research. At
+the very least, such research and related activities should follow
+standard research ethics rules. For more background on research ethics
+generally, ethics in technology, and research of developer communities
+in particular, see:
+
+* `History of Research Ethics <https://www.unlv.edu/research/ORI-HSR/history-ethics>`_
+* `IEEE Ethics <https://www.ieee.org/about/ethics/index.html>`_
+* `Developer and Researcher Views on the Ethics of Experiments on Open-Source Projects <https://arxiv.org/pdf/2112.13217.pdf>`_
+
+The Linux kernel community expects that everyone interacting with the
+project is participating in good faith to make Linux better. Research on
+any publicly-available artifact (including, but not limited to source
+code) produced by the Linux kernel community is welcome, though research
+on developers must be distinctly opt-in.
+
+Passive research that is based entirely on publicly available sources,
+including posts to public mailing lists and commits to public
+repositories, is clearly permissible. Though, as with any research,
+standard ethics must still be followed.
+
+Active research on developer behavior, however, must be done with the
+explicit agreement of, and full disclosure to, the individual developers
+involved. Developers cannot be interacted with/experimented on without
+consent; this, too, is standard research ethics.
+
+To help clarify: sending patches to developers *is* interacting
+with them, but they have already consented to receiving *good faith
+contributions*. Sending intentionally flawed/vulnerable patches or
+contributing misleading information to discussions is not consented
+to. Such communication can be damaging to the developer (e.g. draining
+time, effort, and morale) and damaging to the project by eroding
+the entire developer community's trust in the contributor (and the
+contributor's organization as a whole), undermining efforts to provide
+constructive feedback to contributors, and putting end users at risk of
+software flaws.
+
+Participation in the development of Linux itself by researchers, as
+with anyone, is welcomed and encouraged. Research into Linux code is
+a common practice, especially when it comes to developing or running
+analysis tools that produce actionable results.
+
+When engaging with the developer community, sending a patch has
+traditionally been the best way to make an impact. Linux already has
+plenty of known bugs -- what's much more helpful is having vetted fixes.
+Before contributing, carefully read the appropriate documentation:
+
+* Documentation/process/development-process.rst
+* Documentation/process/submitting-patches.rst
+* Documentation/admin-guide/reporting-issues.rst
+* Documentation/admin-guide/security-bugs.rst
+
+Then send a patch (including a commit log with all the details listed
+below) and follow up on any feedback from other developers.
+
+When sending patches produced from research, the commit logs should
+contain at least the following details, so that developers have
+appropriate context for understanding the contribution. Answer:
+
+* What is the specific problem that has been found?
+* How could the problem be reached on a running system?
+* What effect would encountering the problem have on the system?
+* How was the problem found? Specifically include details about any
+ testing, static or dynamic analysis programs, and any other tools or
+ methods used to perform the work.
+* Which version of Linux was the problem found on? Using the most recent
+ release or a recent linux-next branch is strongly preferred (see
+ Documentation/process/howto.rst).
+* What was changed to fix the problem, and why it is believed to be correct?
+* How was the change build tested and run-time tested?
+* What prior commit does this change fix? This should go in a "Fixes:"
+ tag as the documentation describes.
+* Who else has reviewed this patch? This should go in appropriate
+ "Reviewed-by:" tags; see below.
+
+For example::
+
+ From: Author <author@email>
+ Subject: [PATCH] drivers/foo_bar: Add missing kfree()
+
+ The error path in foo_bar driver does not correctly free the allocated
+ struct foo_bar_info. This can happen if the attached foo_bar device
+ rejects the initialization packets sent during foo_bar_probe(). This
+ would result in a 64 byte slab memory leak once per device attach,
+ wasting memory resources over time.
+
+ This flaw was found using an experimental static analysis tool we are
+ developing, LeakMagic[1], which reported the following warning when
+ analyzing the v5.15 kernel release:
+
+ path/to/foo_bar.c:187: missing kfree() call?
+
+ Add the missing kfree() to the error path. No other references to
+ this memory exist outside the probe function, so this is the only
+ place it can be freed.
+
+ x86_64 and arm64 defconfig builds with CONFIG_FOO_BAR=y using GCC
+ 11.2 show no new warnings, and LeakMagic no longer warns about this
+ code path. As we don't have a FooBar device to test with, no runtime
+ testing was able to be performed.
+
+ [1] https://url/to/leakmagic/details
+
+ Reported-by: Researcher <researcher@email>
+ Fixes: aaaabbbbccccdddd ("Introduce support for FooBar")
+ Signed-off-by: Author <author@email>
+ Reviewed-by: Reviewer <reviewer@email>
+
+If you are a first time contributor it is recommended that the patch
+itself be vetted by others privately before being posted to public lists.
+(This is required if you have been explicitly told your patches need
+more careful internal review.) These people are expected to have their
+"Reviewed-by" tag included in the resulting patch. Finding another
+developer familiar with Linux contribution, especially within your own
+organization, and having them help with reviews before sending them to
+the public mailing lists tends to significantly improve the quality of the
+resulting patches, and there by reduces the burden on other developers.
+
+If no one can be found to internally review patches and you need
+help finding such a person, or if you have any other questions
+related to this document and the developer community's expectations,
+please reach out to the private Technical Advisory Board mailing list:
+<tech-board@lists.linux-foundation.org>.
diff --git a/Documentation/process/submitting-patches.rst b/Documentation/process/submitting-patches.rst
index 31ea120ce531..fb496b2ebfd3 100644
--- a/Documentation/process/submitting-patches.rst
+++ b/Documentation/process/submitting-patches.rst
@@ -495,7 +495,8 @@ Using Reported-by:, Tested-by:, Reviewed-by:, Suggested-by: and Fixes:
The Reported-by tag gives credit to people who find bugs and report them and it
hopefully inspires them to help us again in the future. Please note that if
the bug was reported in private, then ask for permission first before using the
-Reported-by tag.
+Reported-by tag. The tag is intended for bugs; please do not use it to credit
+feature requests.
A Tested-by: tag indicates that the patch has been successfully tested (in
some environment) by the person named. This tag informs maintainers that
diff --git a/Documentation/scheduler/index.rst b/Documentation/scheduler/index.rst
index 88900aabdbf7..b430d856056a 100644
--- a/Documentation/scheduler/index.rst
+++ b/Documentation/scheduler/index.rst
@@ -14,9 +14,11 @@ Linux Scheduler
sched-domains
sched-capacity
sched-energy
+ schedutil
sched-nice-design
sched-rt-group
sched-stats
+ sched-debug
text_files
diff --git a/Documentation/scheduler/sched-debug.rst b/Documentation/scheduler/sched-debug.rst
new file mode 100644
index 000000000000..4d3d24f2a439
--- /dev/null
+++ b/Documentation/scheduler/sched-debug.rst
@@ -0,0 +1,54 @@
+=================
+Scheduler debugfs
+=================
+
+Booting a kernel with CONFIG_SCHED_DEBUG=y will give access to
+scheduler specific debug files under /sys/kernel/debug/sched. Some of
+those files are described below.
+
+numa_balancing
+==============
+
+`numa_balancing` directory is used to hold files to control NUMA
+balancing feature. If the system overhead from the feature is too
+high then the rate the kernel samples for NUMA hinting faults may be
+controlled by the `scan_period_min_ms, scan_delay_ms,
+scan_period_max_ms, scan_size_mb` files.
+
+
+scan_period_min_ms, scan_delay_ms, scan_period_max_ms, scan_size_mb
+-------------------------------------------------------------------
+
+Automatic NUMA balancing scans tasks address space and unmaps pages to
+detect if pages are properly placed or if the data should be migrated to a
+memory node local to where the task is running. Every "scan delay" the task
+scans the next "scan size" number of pages in its address space. When the
+end of the address space is reached the scanner restarts from the beginning.
+
+In combination, the "scan delay" and "scan size" determine the scan rate.
+When "scan delay" decreases, the scan rate increases. The scan delay and
+hence the scan rate of every task is adaptive and depends on historical
+behaviour. If pages are properly placed then the scan delay increases,
+otherwise the scan delay decreases. The "scan size" is not adaptive but
+the higher the "scan size", the higher the scan rate.
+
+Higher scan rates incur higher system overhead as page faults must be
+trapped and potentially data must be migrated. However, the higher the scan
+rate, the more quickly a tasks memory is migrated to a local node if the
+workload pattern changes and minimises performance impact due to remote
+memory accesses. These files control the thresholds for scan delays and
+the number of pages scanned.
+
+``scan_period_min_ms`` is the minimum time in milliseconds to scan a
+tasks virtual memory. It effectively controls the maximum scanning
+rate for each task.
+
+``scan_delay_ms`` is the starting "scan delay" used for a task when it
+initially forks.
+
+``scan_period_max_ms`` is the maximum time in milliseconds to scan a
+tasks virtual memory. It effectively controls the minimum scanning
+rate for each task.
+
+``scan_size_mb`` is how many megabytes worth of pages are scanned for
+a given scan.
diff --git a/Documentation/scheduler/sched-domains.rst b/Documentation/scheduler/sched-domains.rst
index 84dcdcd2911c..e57ad28301bd 100644
--- a/Documentation/scheduler/sched-domains.rst
+++ b/Documentation/scheduler/sched-domains.rst
@@ -37,10 +37,10 @@ rebalancing event for the current runqueue has arrived. The actual load
balancing workhorse, run_rebalance_domains()->rebalance_domains(), is then run
in softirq context (SCHED_SOFTIRQ).
-The latter function takes two arguments: the current CPU and whether it was idle
-at the time the scheduler_tick() happened and iterates over all sched domains
-our CPU is on, starting from its base domain and going up the ->parent chain.
-While doing that, it checks to see if the current domain has exhausted its
+The latter function takes two arguments: the runqueue of current CPU and whether
+the CPU was idle at the time the scheduler_tick() happened and iterates over all
+sched domains our CPU is on, starting from its base domain and going up the ->parent
+chain. While doing that, it checks to see if the current domain has exhausted its
rebalance interval. If so, it runs load_balance() on that domain. It then checks
the parent sched_domain (if it exists), and the parent of the parent and so
forth.
diff --git a/Documentation/scheduler/schedutil.txt b/Documentation/scheduler/schedutil.rst
index 78f6b91e2291..32c7d69fc86c 100644
--- a/Documentation/scheduler/schedutil.txt
+++ b/Documentation/scheduler/schedutil.rst
@@ -1,11 +1,15 @@
+=========
+Schedutil
+=========
+.. note::
-NOTE; all this assumes a linear relation between frequency and work capacity,
-we know this is flawed, but it is the best workable approximation.
+ All this assumes a linear relation between frequency and work capacity,
+ we know this is flawed, but it is the best workable approximation.
PELT (Per Entity Load Tracking)
--------------------------------
+===============================
With PELT we track some metrics across the various scheduler entities, from
individual tasks to task-group slices to CPU runqueues. As the basis for this
@@ -38,8 +42,8 @@ while 'runnable' will increase to reflect the amount of contention.
For more detail see: kernel/sched/pelt.c
-Frequency- / CPU Invariance
----------------------------
+Frequency / CPU Invariance
+==========================
Because consuming the CPU for 50% at 1GHz is not the same as consuming the CPU
for 50% at 2GHz, nor is running 50% on a LITTLE CPU the same as running 50% on
@@ -47,7 +51,7 @@ a big CPU, we allow architectures to scale the time delta with two ratios, one
Dynamic Voltage and Frequency Scaling (DVFS) ratio and one microarch ratio.
For simple DVFS architectures (where software is in full control) we trivially
-compute the ratio as:
+compute the ratio as::
f_cur
r_dvfs := -----
@@ -55,7 +59,7 @@ compute the ratio as:
For more dynamic systems where the hardware is in control of DVFS we use
hardware counters (Intel APERF/MPERF, ARMv8.4-AMU) to provide us this ratio.
-For Intel specifically, we use:
+For Intel specifically, we use::
APERF
f_cur := ----- * P0
@@ -87,7 +91,7 @@ For more detail see:
UTIL_EST / UTIL_EST_FASTUP
---------------------------
+==========================
Because periodic tasks have their averages decayed while they sleep, even
though when running their expected utilization will be the same, they suffer a
@@ -106,7 +110,7 @@ For more detail see: kernel/sched/fair.c:util_est_dequeue()
UCLAMP
-------
+======
It is possible to set effective u_min and u_max clamps on each CFS or RT task;
the runqueue keeps an max aggregate of these clamps for all running tasks.
@@ -115,7 +119,7 @@ For more detail see: include/uapi/linux/sched/types.h
Schedutil / DVFS
-----------------
+================
Every time the scheduler load tracking is updated (task wakeup, task
migration, time progression) we call out to schedutil to update the hardware
@@ -123,7 +127,7 @@ DVFS state.
The basis is the CPU runqueue's 'running' metric, which per the above it is
the frequency invariant utilization estimate of the CPU. From this we compute
-a desired frequency like:
+a desired frequency like::
max( running, util_est ); if UTIL_EST
u_cfs := { running; otherwise
@@ -135,7 +139,7 @@ a desired frequency like:
f_des := min( f_max, 1.25 u * f_max )
-XXX IO-wait; when the update is due to a task wakeup from IO-completion we
+XXX IO-wait: when the update is due to a task wakeup from IO-completion we
boost 'u' above.
This frequency is then used to select a P-state/OPP or directly munged into a
@@ -153,7 +157,7 @@ For more information see: kernel/sched/cpufreq_schedutil.c
NOTES
------
+=====
- On low-load scenarios, where DVFS is most relevant, the 'running' numbers
will closely reflect utilization.
diff --git a/Documentation/security/SCTP.rst b/Documentation/security/SCTP.rst
index d5fd6ccc3dcb..b73eb764a001 100644
--- a/Documentation/security/SCTP.rst
+++ b/Documentation/security/SCTP.rst
@@ -15,10 +15,7 @@ For security module support, three SCTP specific hooks have been implemented::
security_sctp_assoc_request()
security_sctp_bind_connect()
security_sctp_sk_clone()
-
-Also the following security hook has been utilised::
-
- security_inet_conn_established()
+ security_sctp_assoc_established()
The usage of these hooks are described below with the SELinux implementation
described in the `SCTP SELinux Support`_ chapter.
@@ -122,11 +119,12 @@ calls **sctp_peeloff**\(3).
@newsk - pointer to new sock structure.
-security_inet_conn_established()
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-Called when a COOKIE ACK is received::
+security_sctp_assoc_established()
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Called when a COOKIE ACK is received, and the peer secid will be
+saved into ``@asoc->peer_secid`` for client::
- @sk - pointer to sock structure.
+ @asoc - pointer to sctp association structure.
@skb - pointer to skbuff of the COOKIE ACK packet.
@@ -134,7 +132,7 @@ Security Hooks used for Association Establishment
-------------------------------------------------
The following diagram shows the use of ``security_sctp_bind_connect()``,
-``security_sctp_assoc_request()``, ``security_inet_conn_established()`` when
+``security_sctp_assoc_request()``, ``security_sctp_assoc_established()`` when
establishing an association.
::
@@ -172,7 +170,7 @@ establishing an association.
<------------------------------------------- COOKIE ACK
| |
sctp_sf_do_5_1E_ca |
- Call security_inet_conn_established() |
+ Call security_sctp_assoc_established() |
to set the peer label. |
| |
| If SCTP_SOCKET_TCP or peeled off
@@ -198,7 +196,7 @@ hooks with the SELinux specifics expanded below::
security_sctp_assoc_request()
security_sctp_bind_connect()
security_sctp_sk_clone()
- security_inet_conn_established()
+ security_sctp_assoc_established()
security_sctp_assoc_request()
@@ -271,12 +269,12 @@ sockets sid and peer sid to that contained in the ``@asoc sid`` and
@newsk - pointer to new sock structure.
-security_inet_conn_established()
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+security_sctp_assoc_established()
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Called when a COOKIE ACK is received where it sets the connection's peer sid
to that in ``@skb``::
- @sk - pointer to sock structure.
+ @asoc - pointer to sctp association structure.
@skb - pointer to skbuff of the COOKIE ACK packet.
diff --git a/Documentation/security/keys/trusted-encrypted.rst b/Documentation/security/keys/trusted-encrypted.rst
index 80d5a5af62a1..f614dad7de12 100644
--- a/Documentation/security/keys/trusted-encrypted.rst
+++ b/Documentation/security/keys/trusted-encrypted.rst
@@ -107,12 +107,13 @@ Encrypted Keys
--------------
Encrypted keys do not depend on a trust source, and are faster, as they use AES
-for encryption/decryption. New keys are created from kernel-generated random
-numbers, and are encrypted/decrypted using a specified ‘master’ key. The
-‘master’ key can either be a trusted-key or user-key type. The main disadvantage
-of encrypted keys is that if they are not rooted in a trusted key, they are only
-as secure as the user key encrypting them. The master user key should therefore
-be loaded in as secure a way as possible, preferably early in boot.
+for encryption/decryption. New keys are created either from kernel-generated
+random numbers or user-provided decrypted data, and are encrypted/decrypted
+using a specified ‘master’ key. The ‘master’ key can either be a trusted-key or
+user-key type. The main disadvantage of encrypted keys is that if they are not
+rooted in a trusted key, they are only as secure as the user key encrypting
+them. The master user key should therefore be loaded in as secure a way as
+possible, preferably early in boot.
Usage
@@ -199,6 +200,8 @@ Usage::
keyctl add encrypted name "new [format] key-type:master-key-name keylen"
ring
+ keyctl add encrypted name "new [format] key-type:master-key-name keylen
+ decrypted-data" ring
keyctl add encrypted name "load hex_blob" ring
keyctl update keyid "update key-type:master-key-name"
@@ -303,6 +306,16 @@ Load an encrypted key "evm" from saved blob::
82dbbc55be2a44616e4959430436dc4f2a7a9659aa60bb4652aeb2120f149ed197c564e0
24717c64 5972dcb82ab2dde83376d82b2e3c09ffc
+Instantiate an encrypted key "evm" using user-provided decrypted data::
+
+ $ keyctl add encrypted evm "new default user:kmk 32 `cat evm_decrypted_data.blob`" @u
+ 794890253
+
+ $ keyctl print 794890253
+ default user:kmk 32 2375725ad57798846a9bbd240de8906f006e66c03af53b1b382d
+ bbc55be2a44616e4959430436dc4f2a7a9659aa60bb4652aeb2120f149ed197c564e0247
+ 17c64 5972dcb82ab2dde83376d82b2e3c09ffc
+
Other uses for trusted and encrypted keys, such as for disk and file encryption
are anticipated. In particular the new format 'ecryptfs' has been defined
in order to use encrypted keys to mount an eCryptfs filesystem. More details
diff --git a/Documentation/sound/designs/control-names.rst b/Documentation/sound/designs/control-names.rst
index 7fedd0f33cd9..765ff9b5b7d9 100644
--- a/Documentation/sound/designs/control-names.rst
+++ b/Documentation/sound/designs/control-names.rst
@@ -34,7 +34,7 @@ CHANNEL
Front front left/right channels
Surround rear left/right in 4.0/5.1 surround
CLFE C/LFE channels
-Center center cannel
+Center center channel
LFE LFE channel
Side side left/right for 7.1 surround
============ ==================================================
diff --git a/Documentation/sound/hd-audio/models.rst b/Documentation/sound/hd-audio/models.rst
index d25335993e55..9b52f50a6854 100644
--- a/Documentation/sound/hd-audio/models.rst
+++ b/Documentation/sound/hd-audio/models.rst
@@ -261,6 +261,10 @@ alc-sense-combo
huawei-mbx-stereo
Enable initialization verbs for Huawei MBX stereo speakers;
might be risky, try this at your own risk
+alc298-samsung-headphone
+ Samsung laptops with ALC298
+alc256-samsung-headphone
+ Samsung laptops with ALC256
ALC66x/67x/892
==============
diff --git a/Documentation/sphinx/kerneldoc-preamble.sty b/Documentation/sphinx/kerneldoc-preamble.sty
new file mode 100644
index 000000000000..9d0204dc38be
--- /dev/null
+++ b/Documentation/sphinx/kerneldoc-preamble.sty
@@ -0,0 +1,226 @@
+% -*- coding: utf-8 -*-
+% SPDX-License-Identifier: GPL-2.0
+%
+% LaTeX preamble for "make latexdocs" or "make pdfdocs" including:
+% - TOC width settings
+% - Setting of tabulary (\tymin)
+% - Headheight setting for fancyhdr
+% - Fontfamily settings for CJK (Chinese, Japanese, and Korean) translations
+%
+% Note on the suffix of .sty:
+% This is not implemented as a LaTeX style file, but as a file containing
+% plain LaTeX code to be included into preamble.
+% ".sty" is chosen because ".tex" would cause the build scripts to confuse
+% this file with a LaTeX main file.
+%
+% Copyright (C) 2022 Akira Yokosawa
+
+% Custom width parameters for TOC
+% - Redefine low-level commands defined in report.cls.
+% - Indent of 2 chars is preserved for ease of comparison.
+% Summary of changes from default params:
+% Width of page number (\@pnumwidth): 1.55em -> 2.7em
+% Width of chapter number: 1.5em -> 1.8em
+% Indent of section number: 1.5em -> 1.8em
+% Width of section number: 2.6em -> 3.2em
+% Indent of sebsection number: 4.1em -> 5em
+% Width of subsection number: 3.5em -> 4.3em
+%
+% These params can have 4 digit page counts, 2 digit chapter counts,
+% section counts of 4 digits + 1 period (e.g., 18.10), and subsection counts
+% of 5 digits + 2 periods (e.g., 18.7.13).
+\makeatletter
+%% Redefine \@pnumwidth (page number width)
+\renewcommand*\@pnumwidth{2.7em}
+%% Redefine \l@chapter (chapter list entry)
+\renewcommand*\l@chapter[2]{%
+ \ifnum \c@tocdepth >\m@ne
+ \addpenalty{-\@highpenalty}%
+ \vskip 1.0em \@plus\p@
+ \setlength\@tempdima{1.8em}%
+ \begingroup
+ \parindent \z@ \rightskip \@pnumwidth
+ \parfillskip -\@pnumwidth
+ \leavevmode \bfseries
+ \advance\leftskip\@tempdima
+ \hskip -\leftskip
+ #1\nobreak\hfil
+ \nobreak\hb@xt@\@pnumwidth{\hss #2%
+ \kern-\p@\kern\p@}\par
+ \penalty\@highpenalty
+ \endgroup
+ \fi}
+%% Redefine \l@section and \l@subsection
+\renewcommand*\l@section{\@dottedtocline{1}{1.8em}{3.2em}}
+\renewcommand*\l@subsection{\@dottedtocline{2}{5em}{4.3em}}
+\makeatother
+%% Sphinx < 1.8 doesn't have \sphinxtableofcontentshook
+\providecommand{\sphinxtableofcontentshook}{}
+%% Undefine it for compatibility with Sphinx 1.7.9
+\renewcommand{\sphinxtableofcontentshook}{} % Empty the hook
+
+% Prevent column squeezing of tabulary. \tymin is set by Sphinx as:
+% \setlength{\tymin}{3\fontcharwd\font`0 }
+% , which is too short.
+\setlength{\tymin}{20em}
+
+% Adjust \headheight for fancyhdr
+\addtolength{\headheight}{1.6pt}
+\addtolength{\topmargin}{-1.6pt}
+
+% Translations have Asian (CJK) characters which are only displayed if
+% xeCJK is used
+\IfFontExistsTF{Noto Sans CJK SC}{
+ % Load xeCJK when CJK font is available
+ \usepackage{xeCJK}
+ % Noto CJK fonts don't provide slant shape. [AutoFakeSlant] permits
+ % its emulation.
+ % Select KR variant at the beginning of each document so that quotation
+ % and apostorph symbols of half-width is used in TOC of Latin documents.
+ \IfFontExistsTF{Noto Serif CJK KR}{
+ \setCJKmainfont{Noto Serif CJK KR}[AutoFakeSlant]
+ }{
+ \setCJKmainfont{Noto Sans CJK KR}[AutoFakeSlant]
+ }
+ \setCJKsansfont{Noto Sans CJK KR}[AutoFakeSlant]
+ \setCJKmonofont{Noto Sans Mono CJK KR}[AutoFakeSlant]
+ % Teach xeCJK of half-width symbols
+ \xeCJKDeclareCharClass{HalfLeft}{`“,`‘}
+ \xeCJKDeclareCharClass{HalfRight}{`â€,`’}
+ % CJK Language-specific font choices
+ %% for Simplified Chinese
+ \IfFontExistsTF{Noto Serif CJK SC}{
+ \newCJKfontfamily[SCmain]\scmain{Noto Serif CJK SC}[AutoFakeSlant]
+ \newCJKfontfamily[SCserif]\scserif{Noto Serif CJK SC}[AutoFakeSlant]
+ }{
+ \newCJKfontfamily[SCmain]\scmain{Noto Sans CJK SC}[AutoFakeSlant]
+ \newCJKfontfamily[SCserif]\scserif{Noto Sans CJK SC}[AutoFakeSlant]
+ }
+ \newCJKfontfamily[SCsans]\scsans{Noto Sans CJK SC}[AutoFakeSlant]
+ \newCJKfontfamily[SCmono]\scmono{Noto Sans Mono CJK SC}[AutoFakeSlant]
+ %% for Traditional Chinese
+ \IfFontExistsTF{Noto Serif CJK TC}{
+ \newCJKfontfamily[TCmain]\tcmain{Noto Serif CJK TC}[AutoFakeSlant]
+ \newCJKfontfamily[TCserif]\tcserif{Noto Serif CJK TC}[AutoFakeSlant]
+ }{
+ \newCJKfontfamily[TCmain]\tcmain{Noto Sans CJK TC}[AutoFakeSlant]
+ \newCJKfontfamily[TCserif]\tcserif{Noto Sans CJK TC}[AutoFakeSlant]
+ }
+ \newCJKfontfamily[TCsans]\tcsans{Noto Sans CJK TC}[AutoFakeSlant]
+ \newCJKfontfamily[TCmono]\tcmono{Noto Sans Mono CJK TC}[AutoFakeSlant]
+ %% for Korean
+ \IfFontExistsTF{Noto Serif CJK KR}{
+ \newCJKfontfamily[KRmain]\krmain{Noto Serif CJK KR}[AutoFakeSlant]
+ \newCJKfontfamily[KRserif]\krserif{Noto Serif CJK KR}[AutoFakeSlant]
+ }{
+ \newCJKfontfamily[KRmain]\krmain{Noto Sans CJK KR}[AutoFakeSlant]
+ \newCJKfontfamily[KRserif]\krserif{Noto Sans CJK KR}[AutoFakeSlant]
+ }
+ \newCJKfontfamily[KRsans]\krsans{Noto Sans CJK KR}[AutoFakeSlant]
+ \newCJKfontfamily[KRmono]\krmono{Noto Sans Mono CJK KR}[AutoFakeSlant]
+ %% for Japanese
+ \IfFontExistsTF{Noto Serif CJK JP}{
+ \newCJKfontfamily[JPmain]\jpmain{Noto Serif CJK JP}[AutoFakeSlant]
+ \newCJKfontfamily[JPserif]\jpserif{Noto Serif CJK JP}[AutoFakeSlant]
+ }{
+ \newCJKfontfamily[JPmain]\jpmain{Noto Sans CJK JP}[AutoFakeSlant]
+ \newCJKfontfamily[JPserif]\jpserif{Noto Sans CJK JP}[AutoFakeSlant]
+ }
+ \newCJKfontfamily[JPsans]\jpsans{Noto Sans CJK JP}[AutoFakeSlant]
+ \newCJKfontfamily[JPmono]\jpmono{Noto Sans Mono CJK JP}[AutoFakeSlant]
+ % Dummy commands for Sphinx < 2.3 (no 'extrapackages' support)
+ \providecommand{\onehalfspacing}{}
+ \providecommand{\singlespacing}{}
+ % Define custom macros to on/off CJK
+ %% One and half spacing for CJK contents
+ \newcommand{\kerneldocCJKon}{\makexeCJKactive\onehalfspacing}
+ \newcommand{\kerneldocCJKoff}{\makexeCJKinactive\singlespacing}
+ % Define custom macros for switching CJK font setting
+ %% for Simplified Chinese
+ \newcommand{\kerneldocBeginSC}{%
+ \begingroup%
+ \scmain%
+ \xeCJKDeclareCharClass{FullLeft}{`“,`‘}% Full-width in SC
+ \xeCJKDeclareCharClass{FullRight}{`â€,`’}% Full-width in SC
+ \renewcommand{\CJKrmdefault}{SCserif}%
+ \renewcommand{\CJKsfdefault}{SCsans}%
+ \renewcommand{\CJKttdefault}{SCmono}%
+ \xeCJKsetup{CJKspace = false}% gobble white spaces by ' '
+ % For CJK ascii-art alignment
+ \setmonofont{Noto Sans Mono CJK SC}[AutoFakeSlant]%
+ }
+ \newcommand{\kerneldocEndSC}{\endgroup}
+ %% for Traditional Chinese
+ \newcommand{\kerneldocBeginTC}{%
+ \begingroup%
+ \tcmain%
+ \xeCJKDeclareCharClass{FullLeft}{`“,`‘}% Full-width in TC
+ \xeCJKDeclareCharClass{FullRight}{`â€,`’}% Full-width in TC
+ \renewcommand{\CJKrmdefault}{TCserif}%
+ \renewcommand{\CJKsfdefault}{TCsans}%
+ \renewcommand{\CJKttdefault}{TCmono}%
+ \xeCJKsetup{CJKspace = false}% gobble white spaces by ' '
+ % For CJK ascii-art alignment
+ \setmonofont{Noto Sans Mono CJK TC}[AutoFakeSlant]%
+ }
+ \newcommand{\kerneldocEndTC}{\endgroup}
+ %% for Korean
+ \newcommand{\kerneldocBeginKR}{%
+ \begingroup%
+ \krmain%
+ \renewcommand{\CJKrmdefault}{KRserif}%
+ \renewcommand{\CJKsfdefault}{KRsans}%
+ \renewcommand{\CJKttdefault}{KRmono}%
+ % \xeCJKsetup{CJKspace = true} % true by default
+ % For CJK ascii-art alignment (still misaligned for Hangul)
+ \setmonofont{Noto Sans Mono CJK KR}[AutoFakeSlant]%
+ }
+ \newcommand{\kerneldocEndKR}{\endgroup}
+ %% for Japanese
+ \newcommand{\kerneldocBeginJP}{%
+ \begingroup%
+ \jpmain%
+ \renewcommand{\CJKrmdefault}{JPserif}%
+ \renewcommand{\CJKsfdefault}{JPsans}%
+ \renewcommand{\CJKttdefault}{JPmono}%
+ \xeCJKsetup{CJKspace = false}% gobble white space by ' '
+ % For CJK ascii-art alignment
+ \setmonofont{Noto Sans Mono CJK JP}[AutoFakeSlant]%
+ }
+ \newcommand{\kerneldocEndJP}{\endgroup}
+
+ % Single spacing in literal blocks
+ \fvset{baselinestretch=1}
+ % To customize \sphinxtableofcontents
+ \usepackage{etoolbox}
+ % Inactivate CJK after tableofcontents
+ \apptocmd{\sphinxtableofcontents}{\kerneldocCJKoff}{}{}
+ \xeCJKsetup{CJKspace = true}% For inter-phrase space of Korean TOC
+}{ % No CJK font found
+ % Custom macros to on/off CJK and switch CJK fonts (Dummy)
+ \newcommand{\kerneldocCJKon}{}
+ \newcommand{\kerneldocCJKoff}{}
+ %% By defining \kerneldocBegin(SC|TC|KR|JP) as commands with an argument
+ %% and ignore the argument (#1) in their definitions, whole contents of
+ %% CJK chapters can be ignored.
+ \newcommand{\kerneldocBeginSC}[1]{%
+ %% Put a note on missing CJK fonts in place of zh_CN translation.
+ \begin{sphinxadmonition}{note}{Note on missing fonts:}
+ Translations of Simplified Chinese (zh\_CN), Traditional Chinese
+ (zh\_TW), Korean (ko\_KR), and Japanese (ja\_JP) were skipped
+ due to the lack of suitable font families.
+
+ If you want them, please install ``Noto Sans CJK'' font families
+ by following instructions from
+ \sphinxcode{./scripts/sphinx-pre-install}.
+ Having optional ``Noto Serif CJK'' font families will improve
+ the looks of those translations.
+ \end{sphinxadmonition}}
+ \newcommand{\kerneldocEndSC}{}
+ \newcommand{\kerneldocBeginTC}[1]{}
+ \newcommand{\kerneldocEndTC}{}
+ \newcommand{\kerneldocBeginKR}[1]{}
+ \newcommand{\kerneldocEndKR}{}
+ \newcommand{\kerneldocBeginJP}[1]{}
+ \newcommand{\kerneldocEndJP}{}
+}
diff --git a/Documentation/sphinx/kfigure.py b/Documentation/sphinx/kfigure.py
index 3c78828330be..24d2b2addcce 100644
--- a/Documentation/sphinx/kfigure.py
+++ b/Documentation/sphinx/kfigure.py
@@ -31,10 +31,13 @@ u"""
* ``dot(1)``: Graphviz (https://www.graphviz.org). If Graphviz is not
available, the DOT language is inserted as literal-block.
+ For conversion to PDF, ``rsvg-convert(1)`` of librsvg
+ (https://gitlab.gnome.org/GNOME/librsvg) is used when available.
* SVG to PDF: To generate PDF, you need at least one of this tools:
- ``convert(1)``: ImageMagick (https://www.imagemagick.org)
+ - ``inkscape(1)``: Inkscape (https://inkscape.org/)
List of customizations:
@@ -49,6 +52,7 @@ import os
from os import path
import subprocess
from hashlib import sha1
+import re
from docutils import nodes
from docutils.statemachine import ViewList
from docutils.parsers.rst import directives
@@ -109,10 +113,20 @@ def pass_handle(self, node): # pylint: disable=W0613
# Graphviz's dot(1) support
dot_cmd = None
+# dot(1) -Tpdf should be used
+dot_Tpdf = False
# ImageMagick' convert(1) support
convert_cmd = None
+# librsvg's rsvg-convert(1) support
+rsvg_convert_cmd = None
+
+# Inkscape's inkscape(1) support
+inkscape_cmd = None
+# Inkscape prior to 1.0 uses different command options
+inkscape_ver_one = False
+
def setup(app):
# check toolchain first
@@ -160,23 +174,62 @@ def setupTools(app):
This function is called once, when the builder is initiated.
"""
- global dot_cmd, convert_cmd # pylint: disable=W0603
+ global dot_cmd, dot_Tpdf, convert_cmd, rsvg_convert_cmd # pylint: disable=W0603
+ global inkscape_cmd, inkscape_ver_one # pylint: disable=W0603
kernellog.verbose(app, "kfigure: check installed tools ...")
dot_cmd = which('dot')
convert_cmd = which('convert')
+ rsvg_convert_cmd = which('rsvg-convert')
+ inkscape_cmd = which('inkscape')
if dot_cmd:
kernellog.verbose(app, "use dot(1) from: " + dot_cmd)
+
+ try:
+ dot_Thelp_list = subprocess.check_output([dot_cmd, '-Thelp'],
+ stderr=subprocess.STDOUT)
+ except subprocess.CalledProcessError as err:
+ dot_Thelp_list = err.output
+ pass
+
+ dot_Tpdf_ptn = b'pdf'
+ dot_Tpdf = re.search(dot_Tpdf_ptn, dot_Thelp_list)
else:
kernellog.warn(app, "dot(1) not found, for better output quality install "
"graphviz from https://www.graphviz.org")
- if convert_cmd:
- kernellog.verbose(app, "use convert(1) from: " + convert_cmd)
+ if inkscape_cmd:
+ kernellog.verbose(app, "use inkscape(1) from: " + inkscape_cmd)
+ inkscape_ver = subprocess.check_output([inkscape_cmd, '--version'],
+ stderr=subprocess.DEVNULL)
+ ver_one_ptn = b'Inkscape 1'
+ inkscape_ver_one = re.search(ver_one_ptn, inkscape_ver)
+ convert_cmd = None
+ rsvg_convert_cmd = None
+ dot_Tpdf = False
+
else:
- kernellog.warn(app,
- "convert(1) not found, for SVG to PDF conversion install "
- "ImageMagick (https://www.imagemagick.org)")
+ if convert_cmd:
+ kernellog.verbose(app, "use convert(1) from: " + convert_cmd)
+ else:
+ kernellog.warn(app,
+ "Neither inkscape(1) nor convert(1) found.\n"
+ "For SVG to PDF conversion, "
+ "install either Inkscape (https://inkscape.org/) (preferred) or\n"
+ "ImageMagick (https://www.imagemagick.org)")
+
+ if rsvg_convert_cmd:
+ kernellog.verbose(app, "use rsvg-convert(1) from: " + rsvg_convert_cmd)
+ kernellog.verbose(app, "use 'dot -Tsvg' and rsvg-convert(1) for DOT -> PDF conversion")
+ dot_Tpdf = False
+ else:
+ kernellog.verbose(app,
+ "rsvg-convert(1) not found.\n"
+ " SVG rendering of convert(1) is done by ImageMagick-native renderer.")
+ if dot_Tpdf:
+ kernellog.verbose(app, "use 'dot -Tpdf' for DOT -> PDF conversion")
+ else:
+ kernellog.verbose(app, "use 'dot -Tsvg' and convert(1) for DOT -> PDF conversion")
# integrate conversion tools
@@ -242,7 +295,7 @@ def convert_image(img_node, translator, src_fname=None):
elif in_ext == '.svg':
if translator.builder.format == 'latex':
- if convert_cmd is None:
+ if not inkscape_cmd and convert_cmd is None:
kernellog.verbose(app,
"no SVG to PDF conversion available / include SVG raw.")
img_node.replace_self(file2literal(src_fname))
@@ -266,7 +319,14 @@ def convert_image(img_node, translator, src_fname=None):
if in_ext == '.dot':
kernellog.verbose(app, 'convert DOT to: {out}/' + _name)
- ok = dot2format(app, src_fname, dst_fname)
+ if translator.builder.format == 'latex' and not dot_Tpdf:
+ svg_fname = path.join(translator.builder.outdir, fname + '.svg')
+ ok1 = dot2format(app, src_fname, svg_fname)
+ ok2 = svg2pdf_by_rsvg(app, svg_fname, dst_fname)
+ ok = ok1 and ok2
+
+ else:
+ ok = dot2format(app, src_fname, dst_fname)
elif in_ext == '.svg':
kernellog.verbose(app, 'convert SVG to: {out}/' + _name)
@@ -303,22 +363,70 @@ def dot2format(app, dot_fname, out_fname):
return bool(exit_code == 0)
def svg2pdf(app, svg_fname, pdf_fname):
- """Converts SVG to PDF with ``convert(1)`` command.
+ """Converts SVG to PDF with ``inkscape(1)`` or ``convert(1)`` command.
- Uses ``convert(1)`` from ImageMagick (https://www.imagemagick.org) for
- conversion. Returns ``True`` on success and ``False`` if an error occurred.
+ Uses ``inkscape(1)`` from Inkscape (https://inkscape.org/) or ``convert(1)``
+ from ImageMagick (https://www.imagemagick.org) for conversion.
+ Returns ``True`` on success and ``False`` if an error occurred.
* ``svg_fname`` pathname of the input SVG file with extension (``.svg``)
* ``pdf_name`` pathname of the output PDF file with extension (``.pdf``)
"""
cmd = [convert_cmd, svg_fname, pdf_fname]
- # use stdout and stderr from parent
- exit_code = subprocess.call(cmd)
+ cmd_name = 'convert(1)'
+
+ if inkscape_cmd:
+ cmd_name = 'inkscape(1)'
+ if inkscape_ver_one:
+ cmd = [inkscape_cmd, '-o', pdf_fname, svg_fname]
+ else:
+ cmd = [inkscape_cmd, '-z', '--export-pdf=%s' % pdf_fname, svg_fname]
+
+ try:
+ warning_msg = subprocess.check_output(cmd, stderr=subprocess.STDOUT)
+ exit_code = 0
+ except subprocess.CalledProcessError as err:
+ warning_msg = err.output
+ exit_code = err.returncode
+ pass
+
if exit_code != 0:
kernellog.warn(app, "Error #%d when calling: %s" % (exit_code, " ".join(cmd)))
+ if warning_msg:
+ kernellog.warn(app, "Warning msg from %s: %s"
+ % (cmd_name, str(warning_msg, 'utf-8')))
+ elif warning_msg:
+ kernellog.verbose(app, "Warning msg from %s (likely harmless):\n%s"
+ % (cmd_name, str(warning_msg, 'utf-8')))
+
return bool(exit_code == 0)
+def svg2pdf_by_rsvg(app, svg_fname, pdf_fname):
+ """Convert SVG to PDF with ``rsvg-convert(1)`` command.
+
+ * ``svg_fname`` pathname of input SVG file, including extension ``.svg``
+ * ``pdf_fname`` pathname of output PDF file, including extension ``.pdf``
+
+ Input SVG file should be the one generated by ``dot2format()``.
+ SVG -> PDF conversion is done by ``rsvg-convert(1)``.
+
+ If ``rsvg-convert(1)`` is unavailable, fall back to ``svg2pdf()``.
+
+ """
+
+ if rsvg_convert_cmd is None:
+ ok = svg2pdf(app, svg_fname, pdf_fname)
+ else:
+ cmd = [rsvg_convert_cmd, '--format=pdf', '-o', pdf_fname, svg_fname]
+ # use stdout and stderr from parent
+ exit_code = subprocess.call(cmd)
+ if exit_code != 0:
+ kernellog.warn(app, "Error #%d when calling: %s" % (exit_code, " ".join(cmd)))
+ ok = bool(exit_code == 0)
+
+ return ok
+
# image handling
# ---------------------
diff --git a/Documentation/spi/pxa2xx.rst b/Documentation/spi/pxa2xx.rst
index 6347580826be..716f65d87d04 100644
--- a/Documentation/spi/pxa2xx.rst
+++ b/Documentation/spi/pxa2xx.rst
@@ -101,7 +101,6 @@ device. All fields are optional.
u8 rx_threshold;
u8 dma_burst_size;
u32 timeout;
- int gpio_cs;
};
The "pxa2xx_spi_chip.tx_threshold" and "pxa2xx_spi_chip.rx_threshold" fields are
@@ -146,7 +145,6 @@ field. Below is a sample configuration using the PXA255 NSSP.
.rx_threshold = 8, /* SSP hardward FIFO threshold */
.dma_burst_size = 8, /* Byte wide transfers used so 8 byte bursts */
.timeout = 235, /* See Intel documentation */
- .gpio_cs = 2, /* Use external chip select */
};
static struct pxa2xx_spi_chip cs8405a_chip_info = {
@@ -154,7 +152,6 @@ field. Below is a sample configuration using the PXA255 NSSP.
.rx_threshold = 8, /* SSP hardward FIFO threshold */
.dma_burst_size = 8, /* Byte wide transfers used so 8 byte bursts */
.timeout = 235, /* See Intel documentation */
- .gpio_cs = 3, /* Use external chip select */
};
static struct spi_board_info streetracer_spi_board_info[] __initdata = {
diff --git a/Documentation/tools/index.rst b/Documentation/tools/index.rst
new file mode 100644
index 000000000000..0bb1e61bdcc0
--- /dev/null
+++ b/Documentation/tools/index.rst
@@ -0,0 +1,20 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+============
+Kernel tools
+============
+
+This book covers user-space tools that are shipped with the kernel source;
+more additions are needed here:
+
+.. toctree::
+ :maxdepth: 1
+
+ rtla/index
+
+.. only:: subproject and html
+
+ Indices
+ =======
+
+ * :ref:`genindex`
diff --git a/Documentation/tools/rtla/common_hist_options.rst b/Documentation/tools/rtla/common_hist_options.rst
index 0266cd08a6c9..df53ff835bfb 100644
--- a/Documentation/tools/rtla/common_hist_options.rst
+++ b/Documentation/tools/rtla/common_hist_options.rst
@@ -2,7 +2,7 @@
Set the histogram bucket size (default *1*).
-**-e**, **--entries** *N*
+**-E**, **--entries** *N*
Set the number of entries of the histogram (default 256).
diff --git a/Documentation/tools/rtla/common_options.rst b/Documentation/tools/rtla/common_options.rst
index 721790ad984e..af76df6205d4 100644
--- a/Documentation/tools/rtla/common_options.rst
+++ b/Documentation/tools/rtla/common_options.rst
@@ -14,6 +14,25 @@
Save the stopped trace to [*file|osnoise_trace.txt*].
+**-e**, **--event** *sys:event*
+
+ Enable an event in the trace (**-t**) session. The argument can be a specific event, e.g., **-e** *sched:sched_switch*, or all events of a system group, e.g., **-e** *sched*. Multiple **-e** are allowed. It is only active when **-t** or **-a** are set.
+
+**--filter** *<filter>*
+
+ Filter the previous **-e** *sys:event* event with *<filter>*. For further information about event filtering see https://www.kernel.org/doc/html/latest/trace/events.html#event-filtering.
+
+**--trigger** *<trigger>*
+ Enable a trace event trigger to the previous **-e** *sys:event*.
+ If the *hist:* trigger is activated, the output histogram will be automatically saved to a file named *system_event_hist.txt*.
+ For example, the command:
+
+ rtla <command> <mode> -t -e osnoise:irq_noise --trigger="hist:key=desc,duration/1000:sort=desc,duration/1000:vals=hitcount"
+
+ Will automatically save the content of the histogram associated to *osnoise:irq_noise* event in *osnoise_irq_noise_hist.txt*.
+
+ For further information about event trigger see https://www.kernel.org/doc/html/latest/trace/events.html#event-triggers.
+
**-P**, **--priority** *o:prio|r:prio|f:prio|d:runtime:period*
Set scheduling parameters to the osnoise tracer threads, the format to set the priority are:
diff --git a/Documentation/tools/rtla/common_osnoise_description.rst b/Documentation/tools/rtla/common_osnoise_description.rst
index 8973c5df888f..d5d61615b967 100644
--- a/Documentation/tools/rtla/common_osnoise_description.rst
+++ b/Documentation/tools/rtla/common_osnoise_description.rst
@@ -1,7 +1,7 @@
The **rtla osnoise** tool is an interface for the *osnoise* tracer. The
*osnoise* tracer dispatches a kernel thread per-cpu. These threads read the
time in a loop while with preemption, softirq and IRQs enabled, thus
-allowing all the sources of operating systme noise during its execution.
+allowing all the sources of operating system noise during its execution.
The *osnoise*'s tracer threads take note of the delta between each time
read, along with an interference counter of all sources of interference.
At the end of each period, the *osnoise* tracer displays a summary of
diff --git a/Documentation/tools/rtla/common_osnoise_options.rst b/Documentation/tools/rtla/common_osnoise_options.rst
index d556883e4e26..f792ca58c211 100644
--- a/Documentation/tools/rtla/common_osnoise_options.rst
+++ b/Documentation/tools/rtla/common_osnoise_options.rst
@@ -1,3 +1,8 @@
+**-a**, **--auto** *us*
+
+ Set the automatic trace mode. This mode sets some commonly used options
+ while debugging the system. It is equivalent to use **-s** *us* **-T 1 -t**.
+
**-p**, **--period** *us*
Set the *osnoise* tracer period in microseconds.
@@ -15,3 +20,8 @@
Stop the trace if the total sample is higher than the argument in microseconds.
If **-T** is set, it will also save the trace to the output.
+
+**-T**, **--threshold** *us*
+
+ Specify the minimum delta between two time reads to be considered noise.
+ The default threshold is *5 us*.
diff --git a/Documentation/tools/rtla/common_timerlat_options.rst b/Documentation/tools/rtla/common_timerlat_options.rst
index e9c1bfd55d48..bacdea6de7a3 100644
--- a/Documentation/tools/rtla/common_timerlat_options.rst
+++ b/Documentation/tools/rtla/common_timerlat_options.rst
@@ -1,3 +1,10 @@
+**-a**, **--auto** *us*
+
+ Set the automatic trace mode. This mode sets some commonly used options
+ while debugging the system. It is equivalent to use **-T** *us* **-s** *us*
+ **-t**. By default, *timerlat* tracer uses FIFO:95 for *timerlat* threads,
+ thus equilavent to **-P** *f:95*.
+
**-p**, **--period** *us*
Set the *timerlat* tracer period in microseconds.
@@ -14,3 +21,8 @@
Save the stack trace at the *IRQ* if a *Thread* latency is higher than the
argument in us.
+
+**--dma-latency** *us*
+ Set the /dev/cpu_dma_latency to *us*, aiming to bound exit from idle latencies.
+ *cyclictest* sets this value to *0* by default, use **--dma-latency** *0* to have
+ similar results.
diff --git a/Documentation/tools/rtla/index.rst b/Documentation/tools/rtla/index.rst
new file mode 100644
index 000000000000..840f0bf3e803
--- /dev/null
+++ b/Documentation/tools/rtla/index.rst
@@ -0,0 +1,26 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+================================
+The realtime Linux analysis tool
+================================
+
+RTLA provides a set of tools for the analysis of the kernel's realtime
+behavior on specific hardware.
+
+.. toctree::
+ :maxdepth: 1
+
+ rtla
+ rtla-osnoise
+ rtla-osnoise-hist
+ rtla-osnoise-top
+ rtla-timerlat
+ rtla-timerlat-hist
+ rtla-timerlat-top
+
+.. only:: subproject and html
+
+ Indices
+ =======
+
+ * :ref:`genindex`
diff --git a/Documentation/tools/rtla/rtla-osnoise-hist.rst b/Documentation/tools/rtla/rtla-osnoise-hist.rst
index 52298ddd8701..f2e79d22c4c4 100644
--- a/Documentation/tools/rtla/rtla-osnoise-hist.rst
+++ b/Documentation/tools/rtla/rtla-osnoise-hist.rst
@@ -36,7 +36,7 @@ default). The reason for reducing the runtime is to avoid starving the
**rtla** tool. The tool is also set to run for *one minute*. The output
histogram is set to group outputs in buckets of *10us* and *25* entries::
- [root@f34 ~/]# rtla osnoise hist -P F:1 -c 0-11 -r 900000 -d 1M -b 10 -e 25
+ [root@f34 ~/]# rtla osnoise hist -P F:1 -c 0-11 -r 900000 -d 1M -b 10 -E 25
# RTLA osnoise histogram
# Time unit is microseconds (us)
# Duration: 0 00:01:00
diff --git a/Documentation/trace/fprobe.rst b/Documentation/trace/fprobe.rst
new file mode 100644
index 000000000000..b64bec1ce144
--- /dev/null
+++ b/Documentation/trace/fprobe.rst
@@ -0,0 +1,174 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+==================================
+Fprobe - Function entry/exit probe
+==================================
+
+.. Author: Masami Hiramatsu <mhiramat@kernel.org>
+
+Introduction
+============
+
+Fprobe is a function entry/exit probe mechanism based on ftrace.
+Instead of using ftrace full feature, if you only want to attach callbacks
+on function entry and exit, similar to the kprobes and kretprobes, you can
+use fprobe. Compared with kprobes and kretprobes, fprobe gives faster
+instrumentation for multiple functions with single handler. This document
+describes how to use fprobe.
+
+The usage of fprobe
+===================
+
+The fprobe is a wrapper of ftrace (+ kretprobe-like return callback) to
+attach callbacks to multiple function entry and exit. User needs to set up
+the `struct fprobe` and pass it to `register_fprobe()`.
+
+Typically, `fprobe` data structure is initialized with the `entry_handler`
+and/or `exit_handler` as below.
+
+.. code-block:: c
+
+ struct fprobe fp = {
+ .entry_handler = my_entry_callback,
+ .exit_handler = my_exit_callback,
+ };
+
+To enable the fprobe, call one of register_fprobe(), register_fprobe_ips(), and
+register_fprobe_syms(). These functions register the fprobe with different types
+of parameters.
+
+The register_fprobe() enables a fprobe by function-name filters.
+E.g. this enables @fp on "func*()" function except "func2()".::
+
+ register_fprobe(&fp, "func*", "func2");
+
+The register_fprobe_ips() enables a fprobe by ftrace-location addresses.
+E.g.
+
+.. code-block:: c
+
+ unsigned long ips[] = { 0x.... };
+
+ register_fprobe_ips(&fp, ips, ARRAY_SIZE(ips));
+
+And the register_fprobe_syms() enables a fprobe by symbol names.
+E.g.
+
+.. code-block:: c
+
+ char syms[] = {"func1", "func2", "func3"};
+
+ register_fprobe_syms(&fp, syms, ARRAY_SIZE(syms));
+
+To disable (remove from functions) this fprobe, call::
+
+ unregister_fprobe(&fp);
+
+You can temporally (soft) disable the fprobe by::
+
+ disable_fprobe(&fp);
+
+and resume by::
+
+ enable_fprobe(&fp);
+
+The above is defined by including the header::
+
+ #include <linux/fprobe.h>
+
+Same as ftrace, the registered callbacks will start being called some time
+after the register_fprobe() is called and before it returns. See
+:file:`Documentation/trace/ftrace.rst`.
+
+Also, the unregister_fprobe() will guarantee that the both enter and exit
+handlers are no longer being called by functions after unregister_fprobe()
+returns as same as unregister_ftrace_function().
+
+The fprobe entry/exit handler
+=============================
+
+The prototype of the entry/exit callback function is as follows:
+
+.. code-block:: c
+
+ void callback_func(struct fprobe *fp, unsigned long entry_ip, struct pt_regs *regs);
+
+Note that both entry and exit callbacks have same ptototype. The @entry_ip is
+saved at function entry and passed to exit handler.
+
+@fp
+ This is the address of `fprobe` data structure related to this handler.
+ You can embed the `fprobe` to your data structure and get it by
+ container_of() macro from @fp. The @fp must not be NULL.
+
+@entry_ip
+ This is the ftrace address of the traced function (both entry and exit).
+ Note that this may not be the actual entry address of the function but
+ the address where the ftrace is instrumented.
+
+@regs
+ This is the `pt_regs` data structure at the entry and exit. Note that
+ the instruction pointer of @regs may be different from the @entry_ip
+ in the entry_handler. If you need traced instruction pointer, you need
+ to use @entry_ip. On the other hand, in the exit_handler, the instruction
+ pointer of @regs is set to the currect return address.
+
+Share the callbacks with kprobes
+================================
+
+Since the recursion safeness of the fprobe (and ftrace) is a bit different
+from the kprobes, this may cause an issue if user wants to run the same
+code from the fprobe and the kprobes.
+
+Kprobes has per-cpu 'current_kprobe' variable which protects the kprobe
+handler from recursion in all cases. On the other hand, fprobe uses
+only ftrace_test_recursion_trylock(). This allows interrupt context to
+call another (or same) fprobe while the fprobe user handler is running.
+
+This is not a matter if the common callback code has its own recursion
+detection, or it can handle the recursion in the different contexts
+(normal/interrupt/NMI.)
+But if it relies on the 'current_kprobe' recursion lock, it has to check
+kprobe_running() and use kprobe_busy_*() APIs.
+
+Fprobe has FPROBE_FL_KPROBE_SHARED flag to do this. If your common callback
+code will be shared with kprobes, please set FPROBE_FL_KPROBE_SHARED
+*before* registering the fprobe, like:
+
+.. code-block:: c
+
+ fprobe.flags = FPROBE_FL_KPROBE_SHARED;
+
+ register_fprobe(&fprobe, "func*", NULL);
+
+This will protect your common callback from the nested call.
+
+The missed counter
+==================
+
+The `fprobe` data structure has `fprobe::nmissed` counter field as same as
+kprobes.
+This counter counts up when;
+
+ - fprobe fails to take ftrace_recursion lock. This usually means that a function
+ which is traced by other ftrace users is called from the entry_handler.
+
+ - fprobe fails to setup the function exit because of the shortage of rethook
+ (the shadow stack for hooking the function return.)
+
+The `fprobe::nmissed` field counts up in both cases. Therefore, the former
+skips both of entry and exit callback and the latter skips the exit
+callback, but in both case the counter will increase by 1.
+
+Note that if you set the FTRACE_OPS_FL_RECURSION and/or FTRACE_OPS_FL_RCU to
+`fprobe::ops::flags` (ftrace_ops::flags) when registering the fprobe, this
+counter may not work correctly, because ftrace skips the fprobe function which
+increase the counter.
+
+
+Functions and structures
+========================
+
+.. kernel-doc:: include/linux/fprobe.h
+.. kernel-doc:: kernel/trace/fprobe.c
+
diff --git a/Documentation/trace/index.rst b/Documentation/trace/index.rst
index 3769b9b7aed8..f9b7bcb5a630 100644
--- a/Documentation/trace/index.rst
+++ b/Documentation/trace/index.rst
@@ -9,6 +9,7 @@ Linux Tracing Technologies
tracepoint-analysis
ftrace
ftrace-uses
+ fprobe
kprobes
kprobetrace
uprobetracer
@@ -30,3 +31,4 @@ Linux Tracing Technologies
stm
sys-t
coresight/index
+ user_events
diff --git a/Documentation/trace/osnoise-tracer.rst b/Documentation/trace/osnoise-tracer.rst
index b648cb9bf1f0..963def9f97c6 100644
--- a/Documentation/trace/osnoise-tracer.rst
+++ b/Documentation/trace/osnoise-tracer.rst
@@ -51,7 +51,7 @@ For example::
[root@f32 ~]# cd /sys/kernel/tracing/
[root@f32 tracing]# echo osnoise > current_tracer
-It is possible to follow the trace by reading the trace trace file::
+It is possible to follow the trace by reading the trace file::
[root@f32 tracing]# cat trace
# tracer: osnoise
@@ -108,7 +108,7 @@ The tracer has a set of options inside the osnoise directory, they are:
option.
- tracing_threshold: the minimum delta between two time() reads to be
considered as noise, in us. When set to 0, the default value will
- will be used, which is currently 5 us.
+ be used, which is currently 5 us.
Additional Tracing
------------------
diff --git a/Documentation/trace/user_events.rst b/Documentation/trace/user_events.rst
new file mode 100644
index 000000000000..bddedabaca80
--- /dev/null
+++ b/Documentation/trace/user_events.rst
@@ -0,0 +1,216 @@
+=========================================
+user_events: User-based Event Tracing
+=========================================
+
+:Author: Beau Belgrave
+
+Overview
+--------
+User based trace events allow user processes to create events and trace data
+that can be viewed via existing tools, such as ftrace, perf and eBPF.
+To enable this feature, build your kernel with CONFIG_USER_EVENTS=y.
+
+Programs can view status of the events via
+/sys/kernel/debug/tracing/user_events_status and can both register and write
+data out via /sys/kernel/debug/tracing/user_events_data.
+
+Programs can also use /sys/kernel/debug/tracing/dynamic_events to register and
+delete user based events via the u: prefix. The format of the command to
+dynamic_events is the same as the ioctl with the u: prefix applied.
+
+Typically programs will register a set of events that they wish to expose to
+tools that can read trace_events (such as ftrace and perf). The registration
+process gives back two ints to the program for each event. The first int is the
+status index. This index describes which byte in the
+/sys/kernel/debug/tracing/user_events_status file represents this event. The
+second int is the write index. This index describes the data when a write() or
+writev() is called on the /sys/kernel/debug/tracing/user_events_data file.
+
+The structures referenced in this document are contained with the
+/include/uap/linux/user_events.h file in the source tree.
+
+**NOTE:** *Both user_events_status and user_events_data are under the tracefs
+filesystem and may be mounted at different paths than above.*
+
+Registering
+-----------
+Registering within a user process is done via ioctl() out to the
+/sys/kernel/debug/tracing/user_events_data file. The command to issue is
+DIAG_IOCSREG.
+
+This command takes a struct user_reg as an argument::
+
+ struct user_reg {
+ u32 size;
+ u64 name_args;
+ u32 status_index;
+ u32 write_index;
+ };
+
+The struct user_reg requires two inputs, the first is the size of the structure
+to ensure forward and backward compatibility. The second is the command string
+to issue for registering. Upon success two outputs are set, the status index
+and the write index.
+
+User based events show up under tracefs like any other event under the
+subsystem named "user_events". This means tools that wish to attach to the
+events need to use /sys/kernel/debug/tracing/events/user_events/[name]/enable
+or perf record -e user_events:[name] when attaching/recording.
+
+**NOTE:** *The write_index returned is only valid for the FD that was used*
+
+Command Format
+^^^^^^^^^^^^^^
+The command string format is as follows::
+
+ name[:FLAG1[,FLAG2...]] [Field1[;Field2...]]
+
+Supported Flags
+^^^^^^^^^^^^^^^
+**BPF_ITER** - EBPF programs attached to this event will get the raw iovec
+struct instead of any data copies for max performance.
+
+Field Format
+^^^^^^^^^^^^
+::
+
+ type name [size]
+
+Basic types are supported (__data_loc, u32, u64, int, char, char[20], etc).
+User programs are encouraged to use clearly sized types like u32.
+
+**NOTE:** *Long is not supported since size can vary between user and kernel.*
+
+The size is only valid for types that start with a struct prefix.
+This allows user programs to describe custom structs out to tools, if required.
+
+For example, a struct in C that looks like this::
+
+ struct mytype {
+ char data[20];
+ };
+
+Would be represented by the following field::
+
+ struct mytype myname 20
+
+Deleting
+-----------
+Deleting an event from within a user process is done via ioctl() out to the
+/sys/kernel/debug/tracing/user_events_data file. The command to issue is
+DIAG_IOCSDEL.
+
+This command only requires a single string specifying the event to delete by
+its name. Delete will only succeed if there are no references left to the
+event (in both user and kernel space). User programs should use a separate file
+to request deletes than the one used for registration due to this.
+
+Status
+------
+When tools attach/record user based events the status of the event is updated
+in realtime. This allows user programs to only incur the cost of the write() or
+writev() calls when something is actively attached to the event.
+
+User programs call mmap() on /sys/kernel/debug/tracing/user_events_status to
+check the status for each event that is registered. The byte to check in the
+file is given back after the register ioctl() via user_reg.status_index.
+Currently the size of user_events_status is a single page, however, custom
+kernel configurations can change this size to allow more user based events. In
+all cases the size of the file is a multiple of a page size.
+
+For example, if the register ioctl() gives back a status_index of 3 you would
+check byte 3 of the returned mmap data to see if anything is attached to that
+event.
+
+Administrators can easily check the status of all registered events by reading
+the user_events_status file directly via a terminal. The output is as follows::
+
+ Byte:Name [# Comments]
+ ...
+
+ Active: ActiveCount
+ Busy: BusyCount
+ Max: MaxCount
+
+For example, on a system that has a single event the output looks like this::
+
+ 1:test
+
+ Active: 1
+ Busy: 0
+ Max: 4096
+
+If a user enables the user event via ftrace, the output would change to this::
+
+ 1:test # Used by ftrace
+
+ Active: 1
+ Busy: 1
+ Max: 4096
+
+**NOTE:** *A status index of 0 will never be returned. This allows user
+programs to have an index that can be used on error cases.*
+
+Status Bits
+^^^^^^^^^^^
+The byte being checked will be non-zero if anything is attached. Programs can
+check specific bits in the byte to see what mechanism has been attached.
+
+The following values are defined to aid in checking what has been attached:
+
+**EVENT_STATUS_FTRACE** - Bit set if ftrace has been attached (Bit 0).
+
+**EVENT_STATUS_PERF** - Bit set if perf/eBPF has been attached (Bit 1).
+
+Writing Data
+------------
+After registering an event the same fd that was used to register can be used
+to write an entry for that event. The write_index returned must be at the start
+of the data, then the remaining data is treated as the payload of the event.
+
+For example, if write_index returned was 1 and I wanted to write out an int
+payload of the event. Then the data would have to be 8 bytes (2 ints) in size,
+with the first 4 bytes being equal to 1 and the last 4 bytes being equal to the
+value I want as the payload.
+
+In memory this would look like this::
+
+ int index;
+ int payload;
+
+User programs might have well known structs that they wish to use to emit out
+as payloads. In those cases writev() can be used, with the first vector being
+the index and the following vector(s) being the actual event payload.
+
+For example, if I have a struct like this::
+
+ struct payload {
+ int src;
+ int dst;
+ int flags;
+ };
+
+It's advised for user programs to do the following::
+
+ struct iovec io[2];
+ struct payload e;
+
+ io[0].iov_base = &write_index;
+ io[0].iov_len = sizeof(write_index);
+ io[1].iov_base = &e;
+ io[1].iov_len = sizeof(e);
+
+ writev(fd, (const struct iovec*)io, 2);
+
+**NOTE:** *The write_index is not emitted out into the trace being recorded.*
+
+EBPF
+----
+EBPF programs that attach to a user-based event tracepoint are given a pointer
+to a struct user_bpf_context. The bpf context contains the data type (which can
+be a user or kernel buffer, or can be a pointer to the iovec) and the data
+length that was emitted (minus the write_index).
+
+Example Code
+------------
+See sample code in samples/user_events.
diff --git a/Documentation/translations/conf.py b/Documentation/translations/conf.py
deleted file mode 100644
index 92cdbba74229..000000000000
--- a/Documentation/translations/conf.py
+++ /dev/null
@@ -1,12 +0,0 @@
-# -*- coding: utf-8 -*-
-# SPDX-License-Identifier: GPL-2.0
-
-# -- Additinal options for LaTeX output ----------------------------------
-# font config for ascii-art alignment
-
-latex_elements['preamble'] += '''
- \\IfFontExistsTF{Noto Sans CJK SC}{
- % For CJK ascii-art alignment
- \\setmonofont{Noto Sans Mono CJK SC}[AutoFakeSlant]
- }{}
-'''
diff --git a/Documentation/translations/ja_JP/index.rst b/Documentation/translations/ja_JP/index.rst
index 88d4d98eed15..20738c931d02 100644
--- a/Documentation/translations/ja_JP/index.rst
+++ b/Documentation/translations/ja_JP/index.rst
@@ -3,7 +3,7 @@
\renewcommand\thesection*
\renewcommand\thesubsection*
\kerneldocCJKon
- \kerneldocBeginJP
+ \kerneldocBeginJP{
Japanese translations
=====================
@@ -15,4 +15,4 @@ Japanese translations
.. raw:: latex
- \kerneldocEndJP
+ }\kerneldocEndJP
diff --git a/Documentation/translations/ko_KR/index.rst b/Documentation/translations/ko_KR/index.rst
index f636b482fb4c..4add6b2fe1f2 100644
--- a/Documentation/translations/ko_KR/index.rst
+++ b/Documentation/translations/ko_KR/index.rst
@@ -3,7 +3,7 @@
\renewcommand\thesection*
\renewcommand\thesubsection*
\kerneldocCJKon
- \kerneldocBeginKR
+ \kerneldocBeginKR{
한국어 번역
===========
@@ -26,5 +26,4 @@
.. raw:: latex
- \normalsize
- \kerneldocEndKR
+ }\kerneldocEndKR
diff --git a/Documentation/translations/zh_CN/accounting/delay-accounting.rst b/Documentation/translations/zh_CN/accounting/delay-accounting.rst
index 67d5606e5401..f1849411018e 100644
--- a/Documentation/translations/zh_CN/accounting/delay-accounting.rst
+++ b/Documentation/translations/zh_CN/accounting/delay-accounting.rst
@@ -17,6 +17,8 @@ a) 等待一个CPU(任务为å¯è¿è¡Œï¼‰
b) 完æˆç”±è¯¥ä»»åŠ¡å‘èµ·çš„å—I/OåŒæ­¥è¯·æ±‚
c) 页é¢äº¤æ¢
d) 内存回收
+e) 页缓存抖动
+f) 直接规整
并将这些统计信æ¯é€šè¿‡taskstatsæŽ¥å£æä¾›ç»™ç”¨æˆ·ç©ºé—´ã€‚
@@ -37,10 +39,10 @@ d) 内存回收
å‘用户æ€è¿”回一个通用数æ®ç»“构,对应æ¯pid或æ¯tgid的统计信æ¯ã€‚延时计数功能填写
该数æ®ç»“构的特定字段。è§
- include/linux/taskstats.h
+ include/uapi/linux/taskstats.h
å…¶æè¿°äº†å»¶æ—¶è®¡æ•°ç›¸å…³å­—段。系统通常以计数器形å¼è¿”回 CPUã€åŒæ­¥å— I/Oã€äº¤æ¢ã€å†…å­˜
-回收等的累积延时。
+回收ã€é¡µç¼“存抖动ã€ç›´æŽ¥è§„整等的累积延时。
å–任务æŸè®¡æ•°å™¨ä¸¤ä¸ªè¿žç»­è¯»æ•°çš„差值,将得到任务在该时间间隔内等待对应资æºçš„æ€»å»¶æ—¶ã€‚
@@ -72,40 +74,36 @@ kernel.task_delayacct进行开关。注æ„ï¼Œåªæœ‰åœ¨å¯ç”¨å»¶æ—¶è®¡æ•°åŽå¯åŠ
getdelays命令的一般格å¼::
- getdelays [-t tgid] [-p pid] [-c cmd...]
+ getdelays [-dilv] [-t tgid] [-p pid]
获å–pid为10的任务从系统å¯åЍåŽçš„å»¶æ—¶ä¿¡æ¯::
- # ./getdelays -p 10
+ # ./getdelays -d -p 10
(输出信æ¯å’Œä¸‹ä¾‹ç›¸ä¼¼ï¼‰
èŽ·å–æ‰€æœ‰tgid为5的任务从系统å¯åЍåŽçš„æ€»å»¶æ—¶ä¿¡æ¯::
- # ./getdelays -t 5
-
-
- CPU count real total virtual total delay total
- 7876 92005750 100000000 24001500
- IO count delay total
- 0 0
- SWAP count delay total
- 0 0
- RECLAIM count delay total
- 0 0
-
-èŽ·å–æŒ‡å®šç®€å•命令è¿è¡Œæ—¶çš„å»¶æ—¶ä¿¡æ¯::
-
- # ./getdelays -c ls /
-
- bin data1 data3 data5 dev home media opt root srv sys usr
- boot data2 data4 data6 etc lib mnt proc sbin subdomain tmp var
-
-
- CPU count real total virtual total delay total
- 6 4000250 4000000 0
- IO count delay total
- 0 0
- SWAP count delay total
- 0 0
- RECLAIM count delay total
- 0 0
+ # ./getdelays -d -t 5
+ print delayacct stats ON
+ TGID 5
+
+
+ CPU count real total virtual total delay total delay average
+ 8 7000000 6872122 3382277 0.423ms
+ IO count delay total delay average
+ 0 0 0ms
+ SWAP count delay total delay average
+ 0 0 0ms
+ RECLAIM count delay total delay average
+ 0 0 0ms
+ THRASHING count delay total delay average
+ 0 0 0ms
+ COMPACT count delay total delay average
+ 0 0 0ms
+
+获å–pid为1çš„IO计数,它åªå’Œ-p一起使用::
+ # ./getdelays -i -p 1
+ printing IO accounting
+ linuxrc: read=65536, write=0, cancelled_write=0
+
+上é¢çš„命令与-v一起使用,å¯ä»¥èŽ·å–æ›´å¤šè°ƒè¯•ä¿¡æ¯ã€‚
diff --git a/Documentation/translations/zh_CN/admin-guide/index.rst b/Documentation/translations/zh_CN/admin-guide/index.rst
index 548e57f4b3f1..be535ffaf4b0 100644
--- a/Documentation/translations/zh_CN/admin-guide/index.rst
+++ b/Documentation/translations/zh_CN/admin-guide/index.rst
@@ -20,15 +20,15 @@ Linux 内核用户和管ç†å‘˜æŒ‡å—
Todolist:
- kernel-parameters
- devices
- sysctl/index
+* kernel-parameters
+* devices
+* sysctl/index
本节介ç»CPUæ¼æ´žåŠå…¶ç¼“解措施。
Todolist:
- hw-vuln/index
+* hw-vuln/index
下é¢çš„一组文档,针对的是试图跟踪问题和bug的用户。
@@ -44,18 +44,18 @@ Todolist:
Todolist:
- reporting-bugs
- ramoops
- dynamic-debug-howto
- kdump/index
- perf/index
+* reporting-bugs
+* ramoops
+* dynamic-debug-howto
+* kdump/index
+* perf/index
这是应用程åºå¼€å‘人员感兴趣的章节的开始。å¯ä»¥åœ¨è¿™é‡Œæ‰¾åˆ°æ¶µç›–内核ABIå„个
æ–¹é¢çš„æ–‡æ¡£ã€‚
Todolist:
- sysfs-rules
+* sysfs-rules
本手册的其余部分包括å„ç§æŒ‡å—,介ç»å¦‚ä½•æ ¹æ®æ‚¨çš„喜好é…置内核的特定行为。
@@ -69,61 +69,61 @@ Todolist:
lockup-watchdogs
unicode
sysrq
+ mm/index
Todolist:
- acpi/index
- aoe/index
- auxdisplay/index
- bcache
- binderfs
- binfmt-misc
- blockdev/index
- bootconfig
- braille-console
- btmrvl
- cgroup-v1/index
- cgroup-v2
- cifs/index
- dell_rbu
- device-mapper/index
- edid
- efi-stub
- ext4
- nfs/index
- gpio/index
- highuid
- hw_random
- initrd
- iostats
- java
- jfs
- kernel-per-CPU-kthreads
- laptops/index
- lcd-panel-cgram
- ldm
- LSM/index
- md
- media/index
- mm/index
- module-signing
- mono
- namespaces/index
- numastat
- parport
- perf-security
- pm/index
- pnp
- rapidio
- ras
- rtc
- serial-console
- svga
- thunderbolt
- ufs
- vga-softcursor
- video-output
- xfs
+* acpi/index
+* aoe/index
+* auxdisplay/index
+* bcache
+* binderfs
+* binfmt-misc
+* blockdev/index
+* bootconfig
+* braille-console
+* btmrvl
+* cgroup-v1/index
+* cgroup-v2
+* cifs/index
+* dell_rbu
+* device-mapper/index
+* edid
+* efi-stub
+* ext4
+* nfs/index
+* gpio/index
+* highuid
+* hw_random
+* initrd
+* iostats
+* java
+* jfs
+* kernel-per-CPU-kthreads
+* laptops/index
+* lcd-panel-cgram
+* ldm
+* LSM/index
+* md
+* media/index
+* module-signing
+* mono
+* namespaces/index
+* numastat
+* parport
+* perf-security
+* pm/index
+* pnp
+* rapidio
+* ras
+* rtc
+* serial-console
+* svga
+* thunderbolt
+* ufs
+* vga-softcursor
+* video-output
+* xfs
.. only:: subproject and html
diff --git a/Documentation/translations/zh_CN/admin-guide/mm/damon/index.rst b/Documentation/translations/zh_CN/admin-guide/mm/damon/index.rst
new file mode 100644
index 000000000000..0c8276109fc0
--- /dev/null
+++ b/Documentation/translations/zh_CN/admin-guide/mm/damon/index.rst
@@ -0,0 +1,28 @@
+.. SPDX-License-Identifier: GPL-2.0
+.. include:: ../../../disclaimer-zh_CN.rst
+
+:Original: Documentation/admin-guide/mm/damon/index.rst
+
+:翻译:
+
+ å¸å»¶è…¾ Yanteng Si <siyanteng@loongson.cn>
+
+:校译:
+
+============
+监测数æ®è®¿é—®
+============
+
+:doc:`DAMON </vm/damon/index>` å…许轻é‡çº§çš„æ•°æ®è®¿é—®ç›‘测。使用DAMON,
+用户å¯ä»¥åˆ†æžä»–们系统的内存访问模å¼ï¼Œå¹¶ä¼˜åŒ–它们。
+
+.. toctree::
+ :maxdepth: 2
+
+ start
+ usage
+ reclaim
+
+
+
+
diff --git a/Documentation/translations/zh_CN/admin-guide/mm/damon/reclaim.rst b/Documentation/translations/zh_CN/admin-guide/mm/damon/reclaim.rst
new file mode 100644
index 000000000000..9e541578f38d
--- /dev/null
+++ b/Documentation/translations/zh_CN/admin-guide/mm/damon/reclaim.rst
@@ -0,0 +1,232 @@
+.. SPDX-License-Identifier: GPL-2.0
+.. include:: ../../../disclaimer-zh_CN.rst
+
+:Original: Documentation/admin-guide/mm/damon/reclaim.rst
+
+:翻译:
+
+ å¸å»¶è…¾ Yanteng Si <siyanteng@loongson.cn>
+
+:校译:
+
+===============
+基于DAMON的回收
+===============
+
+基于DAMON的回收(DAMON_RECLAIMï¼‰æ˜¯ä¸€ä¸ªé™æ€çš„内核模å—,旨在用于轻度内存压力下的主动和轻
+é‡çº§çš„å›žæ”¶ã€‚å®ƒçš„ç›®çš„ä¸æ˜¯å–代基于LRU列表的页é¢å›žæ”¶ï¼Œè€Œæ˜¯æœ‰é€‰æ‹©åœ°ç”¨äºŽä¸åŒç¨‹åº¦çš„内存压力和è¦
+求。
+
+哪些地方需è¦ä¸»åŠ¨å›žæ”¶ï¼Ÿ
+======================
+
+在一般的内存超é‡ä½¿ç”¨ï¼ˆover-committed systems,虚拟化相关术语)的系统上,主动回收冷页
+有助于节çœå†…存和å‡å°‘延迟高峰,这些延迟是由直接回收进程或kswapdçš„CPUæ¶ˆè€—å¼•èµ·çš„ï¼ŒåŒæ—¶åªäº§
+生最å°çš„æ€§èƒ½ä¸‹é™ [1]_ [2]_ 。
+
+基于空闲页报告 [3]_ 的内存过度承诺的虚拟化系统就是很好的例å­ã€‚在这样的系统中,客户机
+å‘ä¸»æœºæŠ¥å‘Šä»–ä»¬çš„ç©ºé—²å†…å­˜ï¼Œè€Œä¸»æœºåˆ™å°†æŠ¥å‘Šçš„å†…å­˜é‡æ–°åˆ†é…给其他客户。因此,系统的内存得到了充
+分的利用。然而,客户å¯èƒ½ä¸é‚£ä¹ˆèŠ‚çœå†…å­˜ï¼Œä¸»è¦æ˜¯å› ä¸ºä¸€äº›å†…æ ¸å­ç³»ç»Ÿå’Œç”¨æˆ·ç©ºé—´åº”用程åºè¢«è®¾è®¡ä¸º
+使用尽å¯èƒ½å¤šçš„内存。然åŽï¼Œå®¢æˆ·æœºå¯èƒ½åªå‘主机报告少é‡çš„内存是空闲的,导致系统的内存利用率下é™ã€‚
+在客户中è¿è¡Œä¸»åŠ¨å›žæ”¶å¯ä»¥ç¼“解这个问题。
+
+它是如何工作的?
+================
+
+DAMON_RECLAIM找到在特定时间内没有被访问的内存区域并分页。为了é¿å…它在分页æ“作中消耗过多
+çš„CPU,å¯ä»¥é…置一个速度é™åˆ¶ã€‚在这个速度é™åˆ¶ä¸‹ï¼Œå®ƒé¦–先分页出那些没有被访问过的内存区域。系
+统管ç†å‘˜è¿˜å¯ä»¥é…置在什么情况下这个方案应该自动激活和åœç”¨ä¸‰ä¸ªå†…存压力水ä½ã€‚
+
+接å£: 模å—傿•°
+==============
+
+è¦ä½¿ç”¨è¿™ä¸ªåŠŸèƒ½ï¼Œä½ é¦–å…ˆè¦ç¡®ä¿ä½ çš„系统è¿è¡Œåœ¨ä¸€ä¸ªä»¥ ``CONFIG_DAMON_RECLAIM=y`` 构建的内
+核上。
+
+为了让系统管ç†å‘˜å¯ç”¨æˆ–ç¦ç”¨å®ƒï¼Œå¹¶ä¸ºç»™å®šçš„系统进行调整,DAMON_RECLAIM利用了模å—傿•°ã€‚也就
+是说,你å¯ä»¥æŠŠ ``damon_reclaim.<parameter>=<value>`` 放在内核å¯åŠ¨å‘½ä»¤è¡Œä¸Šï¼Œæˆ–è€…æŠŠ
+适当的值写入 ``/sys/modules/damon_reclaim/parameters/<parameter>`` 文件。
+
+注æ„,除 ``å¯ç”¨`` å¤–çš„å‚æ•°å€¼åªåœ¨DAMON_RECLAIMå¯åŠ¨æ—¶åº”ç”¨ã€‚å› æ­¤ï¼Œå¦‚æžœä½ æƒ³åœ¨è¿è¡Œæ—¶åº”用新
+çš„å‚æ•°å€¼ï¼Œè€ŒDAMON_RECLAIMå·²ç»è¢«å¯ç”¨ï¼Œä½ åº”该通过 ``å¯ç”¨`` çš„å‚æ•°æ–‡ä»¶ç¦ç”¨å’Œé‡æ–°å¯ç”¨å®ƒã€‚
+åœ¨é‡æ–°å¯ç”¨ä¹‹å‰ï¼Œåº”å°†æ–°çš„å‚æ•°å€¼å†™å…¥é€‚å½“çš„å‚æ•°å€¼ä¸­ã€‚
+
+䏋颿˜¯æ¯ä¸ªå‚æ•°çš„æè¿°ã€‚
+
+enable
+------
+
+å¯ç”¨æˆ–ç¦ç”¨DAMON_RECLAIM。
+
+ä½ å¯ä»¥é€šè¿‡æŠŠè¿™ä¸ªå‚数的值设置为 ``Y`` æ¥å¯ç”¨DAMON_RCLAIM,把它设置为 ``N`` å¯ä»¥ç¦ç”¨
+DAMON_RECLAIM。注æ„,由于基于水ä½çš„æ¿€æ´»æ¡ä»¶ï¼ŒDAMON_RECLAIMä¸èƒ½è¿›è¡ŒçœŸæ­£çš„监测和回收。
+这一点请å‚考下é¢å…³äºŽæ°´ä½å‚æ•°çš„æè¿°ã€‚
+
+min_age
+-------
+
+识别冷内存区域的时间阈值,å•使˜¯å¾®ç§’。
+
+如果一个内存区域在这个时间或更长的时间内没有被访问,DAMON_RECLAIM会将该区域识别为冷的,
+并回收它。
+
+默认为120秒。
+
+quota_ms
+--------
+
+回收的时间é™åˆ¶ï¼Œä»¥æ¯«ç§’为å•ä½ã€‚
+
+DAMON_RECLAIM 试图在一个时间窗å£ï¼ˆquota_reset_interval_ms)内åªä½¿ç”¨åˆ°è¿™ä¸ªæ—¶é—´ï¼Œä»¥
+å°è¯•回收冷页。这å¯ä»¥ç”¨æ¥é™åˆ¶DAMON_RECLAIMçš„CPU消耗。如果该值为零,则该é™åˆ¶è¢«ç¦ç”¨ã€‚
+
+默认为10ms。
+
+quota_sz
+--------
+
+回收的内存大å°é™åˆ¶ï¼Œå•ä½ä¸ºå­—节。
+
+DAMON_RECLAIM æ”¶å–在一个时间窗å£ï¼ˆquota_reset_interval_ms)内试图回收的内存é‡ï¼Œå¹¶
+使其ä¸è¶…过这个é™åˆ¶ã€‚è¿™å¯ä»¥ç”¨æ¥é™åˆ¶CPUå’ŒIO的消耗。如果该值为零,则é™åˆ¶è¢«ç¦ç”¨ã€‚
+
+默认情况下是128 MiB。
+
+quota_reset_interval_ms
+-----------------------
+
+æ—¶é—´/大å°é…颿”¶å–é‡ç½®é—´éš”,å•ä½ä¸ºæ¯«ç§’。
+
+时间(quota_ms)和大å°ï¼ˆquota_sz)的é…é¢çš„目标é‡ç½®é—´éš”。也就是说,DAMON_RECLAIM在
+å°è¯•回收‘ä¸â€™è¶…过quota_ms毫秒或quota_sz字节的内存。
+
+默认为1秒。
+
+wmarks_interval
+---------------
+
+当DAMON_RECLAIM被å¯ç”¨ä½†ç”±äºŽå…¶æ°´ä½è§„åˆ™è€Œä¸æ´»è·ƒæ—¶ï¼Œåœ¨æ£€æŸ¥æ°´ä½ä¹‹å‰çš„æœ€å°ç­‰å¾…时间。
+
+wmarks_high
+-----------
+
+高水ä½çš„å¯ç”¨å†…存率(æ¯åƒå­—节)。
+
+如果系统的å¯ç”¨å†…存(以æ¯åƒå­—节为å•ä½ï¼‰é«˜äºŽè¿™ä¸ªæ•°å€¼ï¼ŒDAMON_RECLAIM就会å˜å¾—䏿´»è·ƒï¼Œæ‰€ä»¥
+它什么也ä¸åšï¼Œåªæ˜¯å®šæœŸæ£€æŸ¥æ°´ä½ã€‚
+
+wmarks_mid
+----------
+
+中间水ä½çš„å¯ç”¨å†…存率(æ¯åƒå­—节)。
+
+如果系统的空闲内存(以æ¯åƒå­—节为å•ä½ï¼‰åœ¨è¿™ä¸ªå’Œä½Žæ°´ä½çº¿ä¹‹é—´ï¼ŒDAMON_RECLAIM就会被激活,
+因此开始监测和回收。
+
+wmarks_low
+----------
+
+低水ä½çš„å¯ç”¨å†…存率(æ¯åƒå­—节)。
+
+如果系统的空闲内存(以æ¯åƒå­—节为å•ä½ï¼‰ä½ŽäºŽè¿™ä¸ªæ•°å€¼ï¼ŒDAMON_RECLAIM就会å˜å¾—䏿´»è·ƒï¼Œæ‰€ä»¥
+它除了定期检查水ä½å¤–什么都ä¸åšã€‚åœ¨è¿™ç§æƒ…况下,系统会退回到基于LRU列表的页é¢ç²’度回收逻辑。
+
+sample_interval
+---------------
+
+监测的采样间隔,å•使˜¯å¾®ç§’。
+
+DAMON用于监测冷内存的采样间隔。更多细节请å‚考DAMON文档 (:doc:`usage`) 。
+
+aggr_interval
+-------------
+
+监测的èšé›†é—´éš”,å•使˜¯å¾®ç§’。
+
+DAMON对冷内存监测的èšé›†é—´éš”。更多细节请å‚考DAMON文档 (:doc:`usage`)。
+
+min_nr_regions
+--------------
+
+ç›‘æµ‹åŒºåŸŸçš„æœ€å°æ•°é‡ã€‚
+
+DAMON用于冷内存监测的最å°ç›‘测区域数。这å¯ä»¥ç”¨æ¥è®¾ç½®ç›‘测质é‡çš„下é™ã€‚但是,设
+置的太高å¯èƒ½ä¼šå¯¼è‡´ç›‘测开销的增加。更多细节请å‚考DAMON文档 (:doc:`usage`) 。
+
+max_nr_regions
+--------------
+
+监测区域的最大数é‡ã€‚
+
+DAMON用于冷内存监测的最大监测区域数。这å¯ä»¥ç”¨æ¥è®¾ç½®ç›‘测开销的上é™å€¼ã€‚但是,
+设置得太低å¯èƒ½ä¼šå¯¼è‡´ç›‘测质é‡ä¸å¥½ã€‚更多细节请å‚考DAMON文档 (:doc:`usage`) 。
+
+monitor_region_start
+--------------------
+
+目标内存区域的物ç†åœ°å€èµ·ç‚¹ã€‚
+
+DAMON_RECLAIM将对其进行工作的内存区域的起始物ç†åœ°å€ã€‚也就是说,DAMON_RECLAIM
+将在这个区域中找到冷的内存区域并进行回收。默认情况下,该区域使用最大系统内存区。
+
+monitor_region_end
+------------------
+
+目标内存区域的结æŸç‰©ç†åœ°å€ã€‚
+
+DAMON_RECLAIM将对其进行工作的内存区域的末端物ç†åœ°å€ã€‚也就是说,DAMON_RECLAIMå°†
+在这个区域内找到冷的内存区域并进行回收。默认情况下,该区域使用最大系统内存区。
+
+kdamond_pid
+-----------
+
+DAMON线程的PID。
+
+如果DAMON_RECLAIM被å¯ç”¨ï¼Œè¿™å°†æˆä¸ºå·¥ä½œçº¿ç¨‹çš„PID。å¦åˆ™ï¼Œä¸º-1。
+
+nr_reclaim_tried_regions
+------------------------
+
+试图通过DAMON_RECLAIM回收的内存区域的数é‡ã€‚
+
+bytes_reclaim_tried_regions
+---------------------------
+
+试图通过DAMON_RECLAIM回收的内存区域的总字节数。
+
+nr_reclaimed_regions
+--------------------
+
+通过DAMON_RECLAIMæˆåŠŸå›žæ”¶çš„å†…å­˜åŒºåŸŸçš„æ•°é‡ã€‚
+
+bytes_reclaimed_regions
+-----------------------
+
+通过DAMON_RECLAIMæˆåŠŸå›žæ”¶çš„å†…å­˜åŒºåŸŸçš„æ€»å­—èŠ‚æ•°ã€‚
+
+nr_quota_exceeds
+----------------
+
+超过时间/空间é…é¢é™åˆ¶çš„æ¬¡æ•°ã€‚
+
+例å­
+====
+
+下é¢çš„è¿è¡Œç¤ºä¾‹å‘½ä»¤ä½¿DAMON_RECLAIM找到30秒或更长时间没有访问的内存区域并“回收â€ï¼Ÿ
+为了é¿å…DAMON_RECLAIM在分页æ“作中消耗过多的CPU时间,回收被é™åˆ¶åœ¨æ¯ç§’1GiB以内。
+å®ƒè¿˜è¦æ±‚DAMON_RECLAIM在系统的å¯ç”¨å†…存率超过50%æ—¶ä¸åšä»»ä½•事情,但如果它低于40%æ—¶
+就开始真正的工作。如果DAMON_RECLAIM没有å–得进展,因此空闲内存率低于20%ï¼Œå®ƒä¼šè¦æ±‚
+DAMON_RECLAIM冿¬¡ä»€ä¹ˆéƒ½ä¸åšï¼Œè¿™æ ·æˆ‘们就å¯ä»¥é€€å›žåˆ°åŸºäºŽLRU列表的页é¢ç²’度回收了::
+
+ # cd /sys/modules/damon_reclaim/parameters
+ # echo 30000000 > min_age
+ # echo $((1 * 1024 * 1024 * 1024)) > quota_sz
+ # echo 1000 > quota_reset_interval_ms
+ # echo 500 > wmarks_high
+ # echo 400 > wmarks_mid
+ # echo 200 > wmarks_low
+ # echo Y > enabled
+
+.. [1] https://research.google/pubs/pub48551/
+.. [2] https://lwn.net/Articles/787611/
+.. [3] https://www.kernel.org/doc/html/latest/vm/free_page_reporting.html
diff --git a/Documentation/translations/zh_CN/admin-guide/mm/damon/start.rst b/Documentation/translations/zh_CN/admin-guide/mm/damon/start.rst
new file mode 100644
index 000000000000..67d1b49481dc
--- /dev/null
+++ b/Documentation/translations/zh_CN/admin-guide/mm/damon/start.rst
@@ -0,0 +1,132 @@
+.. SPDX-License-Identifier: GPL-2.0
+.. include:: ../../../disclaimer-zh_CN.rst
+
+:Original: Documentation/admin-guide/mm/damon/start.rst
+
+:翻译:
+
+ å¸å»¶è…¾ Yanteng Si <siyanteng@loongson.cn>
+
+:校译:
+
+========
+入门指å—
+========
+
+本文通过演示DAMON的默认用户空间工具,简è¦åœ°ä»‹ç»äº†å¦‚何使用DAMON。请注æ„,为了简æ´
+èµ·è§ï¼Œæœ¬æ–‡æ¡£åªæè¿°äº†å®ƒçš„部分功能。更多细节请å‚考该工具的使用文档。
+`doc <https://github.com/awslabs/damo/blob/next/USAGE.md>`_ .
+
+
+剿æ¡ä»¶
+========
+
+内核
+----
+
+首先,你è¦ç¡®ä¿ä½ å½“å‰ç³»ç»Ÿä¸­è·‘的内核构建时选定了这个功能选项 ``CONFIG_DAMON_*=y``.
+
+
+用户空间工具
+------------
+
+在演示中,我们将使用DAMON的默认用户空间工具,称为DAMON Operator(DAMO)。它å¯ä»¥åœ¨
+https://github.com/awslabs/damo找到。下é¢çš„例å­å‡è®¾DAMO在你的$PATH上。当然,但
+è¿™å¹¶ä¸æ˜¯å¼ºåˆ¶æ€§çš„。
+
+因为DAMO使用的是DAMONçš„debugfs接å£(详情请å‚考 :doc:`usage` 中的使用方法) 你应该
+ç¡®ä¿debugfs被挂载。手动挂载它,如下所示::
+
+ # mount -t debugfs none /sys/kernel/debug/
+
+或者在你的 ``/etc/fstab`` 文件中添加以下一行,这样你的系统就å¯ä»¥åœ¨å¯åŠ¨æ—¶è‡ªåŠ¨æŒ‚è½½
+debugfs了::
+
+ debugfs /sys/kernel/debug debugfs defaults 0 0
+
+
+记录数æ®è®¿é—®æ¨¡å¼
+================
+
+下é¢çš„命令记录了一个程åºçš„内存访问模å¼ï¼Œå¹¶å°†ç›‘测结果ä¿å­˜åˆ°æ–‡ä»¶ä¸­ã€‚ ::
+
+ $ git clone https://github.com/sjp38/masim
+ $ cd masim; make; ./masim ./configs/zigzag.cfg &
+ $ sudo damo record -o damon.data $(pidof masim)
+
+命令的å‰ä¸¤è¡Œä¸‹è½½äº†ä¸€ä¸ªäººå·¥å†…存访问生æˆå™¨ç¨‹åºå¹¶åœ¨åŽå°è¿è¡Œã€‚生æˆå™¨å°†é‡å¤åœ°é€ä¸€è®¿é—®ä¸¤ä¸ª
+100 MiB大å°çš„内存区域。你å¯ä»¥ç”¨ä½ çš„真实工作负载æ¥ä»£æ›¿å®ƒã€‚最åŽä¸€è¡Œè¦æ±‚ ``damo`` å°†
+访问模å¼è®°å½•在 ``damon.data`` 文件中。
+
+
+将记录的模å¼å¯è§†åŒ–
+==================
+
+ä½ å¯ä»¥åœ¨heatmapä¸­ç›´è§‚åœ°çœ‹åˆ°è¿™ç§æ¨¡å¼ï¼Œæ˜¾ç¤ºå“ªä¸ªå†…存区域(X轴)何时被访问(Y轴)以åŠè®¿
+问的频率(数字)。::
+
+ $ sudo damo report heats --heatmap stdout
+ 22222222222222222222222222222222222222211111111111111111111111111111111111111100
+ 44444444444444444444444444444444444444434444444444444444444444444444444444443200
+ 44444444444444444444444444444444444444433444444444444444444444444444444444444200
+ 33333333333333333333333333333333333333344555555555555555555555555555555555555200
+ 33333333333333333333333333333333333344444444444444444444444444444444444444444200
+ 22222222222222222222222222222222222223355555555555555555555555555555555555555200
+ 00000000000000000000000000000000000000288888888888888888888888888888888888888400
+ 00000000000000000000000000000000000000288888888888888888888888888888888888888400
+ 33333333333333333333333333333333333333355555555555555555555555555555555555555200
+ 88888888888888888888888888888888888888600000000000000000000000000000000000000000
+ 88888888888888888888888888888888888888600000000000000000000000000000000000000000
+ 33333333333333333333333333333333333333444444444444444444444444444444444444443200
+ 00000000000000000000000000000000000000288888888888888888888888888888888888888400
+ [...]
+ # access_frequency: 0 1 2 3 4 5 6 7 8 9
+ # x-axis: space (139728247021568-139728453431248: 196.848 MiB)
+ # y-axis: time (15256597248362-15326899978162: 1 m 10.303 s)
+ # resolution: 80x40 (2.461 MiB and 1.758 s for each character)
+
+你也å¯ä»¥ç›´è§‚地看到工作集的大å°åˆ†å¸ƒï¼ŒæŒ‰å¤§å°æŽ’åºã€‚::
+
+ $ sudo damo report wss --range 0 101 10
+ # <percentile> <wss>
+ # target_id 18446632103789443072
+ # avr: 107.708 MiB
+ 0 0 B | |
+ 10 95.328 MiB |**************************** |
+ 20 95.332 MiB |**************************** |
+ 30 95.340 MiB |**************************** |
+ 40 95.387 MiB |**************************** |
+ 50 95.387 MiB |**************************** |
+ 60 95.398 MiB |**************************** |
+ 70 95.398 MiB |**************************** |
+ 80 95.504 MiB |**************************** |
+ 90 190.703 MiB |********************************************************* |
+ 100 196.875 MiB |***********************************************************|
+
+在上述命令中使用 ``--sortby`` 选项,å¯ä»¥æ˜¾ç¤ºå·¥ä½œé›†çš„大尿˜¯å¦‚何按时间顺åºå˜åŒ–的。::
+
+ $ sudo damo report wss --range 0 101 10 --sortby time
+ # <percentile> <wss>
+ # target_id 18446632103789443072
+ # avr: 107.708 MiB
+ 0 3.051 MiB | |
+ 10 190.703 MiB |***********************************************************|
+ 20 95.336 MiB |***************************** |
+ 30 95.328 MiB |***************************** |
+ 40 95.387 MiB |***************************** |
+ 50 95.332 MiB |***************************** |
+ 60 95.320 MiB |***************************** |
+ 70 95.398 MiB |***************************** |
+ 80 95.398 MiB |***************************** |
+ 90 95.340 MiB |***************************** |
+ 100 95.398 MiB |***************************** |
+
+
+æ•°æ®è®¿é—®æ¨¡å¼æ„ŸçŸ¥çš„内存管ç†
+==========================
+
+以下三个命令使æ¯ä¸€ä¸ªå¤§å°>=4K的内存区域在你的工作负载中没有被访问>=60ç§’ï¼Œå°±ä¼šè¢«æ¢æŽ‰ã€‚ ::
+
+ $ echo "#min-size max-size min-acc max-acc min-age max-age action" > test_scheme
+ $ echo "4K max 0 0 60s max pageout" >> test_scheme
+ $ damo schemes -c test_scheme <pid of your workload>
diff --git a/Documentation/translations/zh_CN/admin-guide/mm/damon/usage.rst b/Documentation/translations/zh_CN/admin-guide/mm/damon/usage.rst
new file mode 100644
index 000000000000..5d7533347216
--- /dev/null
+++ b/Documentation/translations/zh_CN/admin-guide/mm/damon/usage.rst
@@ -0,0 +1,286 @@
+.. SPDX-License-Identifier: GPL-2.0
+.. include:: ../../../disclaimer-zh_CN.rst
+
+:Original: Documentation/admin-guide/mm/damon/usage.rst
+
+:翻译:
+
+ å¸å»¶è…¾ Yanteng Si <siyanteng@loongson.cn>
+
+:校译:
+
+========
+详细用法
+========
+
+DAMON 为ä¸åŒçš„用户æä¾›äº†ä¸‹é¢ä¸‰ç§æŽ¥å£ã€‚
+
+- *DAMON用户空间工具。*
+ `è¿™ <https://github.com/awslabs/damo>`_ 为有这特æƒçš„人, 如系统管ç†å‘˜ï¼Œå¸Œæœ›æœ‰ä¸€ä¸ªåˆšå¥½
+ å¯ä»¥å·¥ä½œçš„人性化界é¢ã€‚
+ 使用它,用户å¯ä»¥ä»¥äººæ€§åŒ–的方å¼ä½¿ç”¨DAMON的主è¦åŠŸèƒ½ã€‚ä¸è¿‡ï¼Œå®ƒå¯èƒ½ä¸ä¼šä¸ºç‰¹æ®Šæƒ…况进行高度调整。
+ å®ƒåŒæ—¶æ”¯æŒè™šæ‹Ÿå’Œç‰©ç†åœ°å€ç©ºé—´çš„监测。更多细节,请å‚考它的 `使用文档
+ <https://github.com/awslabs/damo/blob/next/USAGE.md>`_。
+- *debugfs接å£ã€‚*
+ :ref:`è¿™ <debugfs_interface>` 是为那些希望更高级的使用DAMON的特æƒç”¨æˆ·ç©ºé—´ç¨‹åºå‘˜å‡†å¤‡çš„。
+ 使用它,用户å¯ä»¥é€šè¿‡è¯»å–和写入特殊的debugfs文件æ¥ä½¿ç”¨DAMON的主è¦åŠŸèƒ½ã€‚å› æ­¤ï¼Œä½ å¯ä»¥ç¼–写和使
+ 用你个性化的DAMON debugfs包装程åºï¼Œä»£æ›¿ä½ è¯»/写debugfs文件。 `DAMON用户空间工具
+ <https://github.com/awslabs/damo>`_ 就是这ç§ç¨‹åºçš„ä¸€ä¸ªä¾‹å­ å®ƒåŒæ—¶æ”¯æŒè™šæ‹Ÿå’Œç‰©ç†åœ°å€
+ 空间的监测。注æ„,这个界é¢åªæä¾›ç®€å•的监测结果 :ref:`统计 <damos_stats>`。对于详细的监测
+ 结果,DAMONæä¾›äº†ä¸€ä¸ª:ref:`跟踪点 <tracepoint>`。
+
+- *内核空间编程接å£ã€‚*
+ :doc:`This </vm/damon/api>` 这是为内核空间程åºå‘˜å‡†å¤‡çš„。使用它,用户å¯ä»¥é€šè¿‡ä¸ºä½ ç¼–写内
+ 核空间的DAMON应用程åºï¼Œæœ€çµæ´»æœ‰æ•ˆåœ°åˆ©ç”¨DAMONçš„æ¯ä¸€ä¸ªåŠŸèƒ½ã€‚ä½ ç”šè‡³å¯ä»¥ä¸ºå„ç§åœ°å€ç©ºé—´æ‰©å±•DAMON。
+ 详细情况请å‚è€ƒæŽ¥å£ :doc:`文件 </vm/damon/api>`。
+
+
+debugfs接å£
+===========
+
+DAMON导出了八个文件, ``attrs``, ``target_ids``, ``init_regions``,
+``schemes``, ``monitor_on``, ``kdamond_pid``, ``mk_contexts`` 和
+``rm_contexts`` under its debugfs directory, ``<debugfs>/damon/``.
+
+
+属性
+----
+
+用户å¯ä»¥é€šè¿‡è¯»å–和写入 ``attrs`` 文件获得和设置 ``采样间隔`` 〠``èšé›†é—´éš”`` 〠``区域更新间隔``
+以åŠç›‘测目标区域的最å°/最大数é‡ã€‚è¦è¯¦ç»†äº†è§£ç›‘测属性,请å‚考 `:doc:/vm/damon/design` 。例如,
+下é¢çš„命令将这些值设置为5msã€100msã€1000msã€10å’Œ1000,然åŽå†æ¬¡æ£€æŸ¥::
+
+ # cd <debugfs>/damon
+ # echo 5000 100000 1000000 10 1000 > attrs
+ # cat attrs
+ 5000 100000 1000000 10 1000
+
+
+目标ID
+------
+
+一些类型的地å€ç©ºé—´æ”¯æŒå¤šä¸ªç›‘测目标。例如,虚拟内存地å€ç©ºé—´çš„监测å¯ä»¥æœ‰å¤šä¸ªè¿›ç¨‹ä½œä¸ºç›‘测目标。用户
+å¯ä»¥é€šè¿‡å†™å…¥ç›®æ ‡çš„相关id值æ¥è®¾ç½®ç›®æ ‡ï¼Œå¹¶é€šè¿‡è¯»å– ``target_ids`` 文件æ¥è޷得当å‰ç›®æ ‡çš„id。在监
+测虚拟地å€ç©ºé—´çš„æƒ…况下,这些值应该是监测目标进程的pid。例如,下é¢çš„命令将pid为42å’Œ4242的进程设
+ä¸ºç›‘æµ‹ç›®æ ‡ï¼Œå¹¶å†æ¬¡æ£€æŸ¥::
+
+ # cd <debugfs>/damon
+ # echo 42 4242 > target_ids
+ # cat target_ids
+ 42 4242
+
+用户还å¯ä»¥é€šè¿‡åœ¨æ–‡ä»¶ä¸­å†™å…¥ä¸€ä¸ªç‰¹æ®Šçš„关键字 "paddr\n" æ¥ç›‘测系统的物ç†å†…存地å€ç©ºé—´ã€‚因为物ç†åœ°
+å€ç©ºé—´ç›‘æµ‹ä¸æ”¯æŒå¤šä¸ªç›®æ ‡ï¼Œè¯»å–文件会显示一个å‡å€¼ï¼Œå³ ``42`` ,如下图所示::
+
+ # cd <debugfs>/damon
+ # echo paddr > target_ids
+ # cat target_ids
+ 42
+
+请注æ„,设置目标IDå¹¶ä¸å¯åŠ¨ç›‘æµ‹ã€‚
+
+
+åˆå§‹ç›‘测目标区域
+----------------
+
+在虚拟地å€ç©ºé—´ç›‘测的情况下,DAMON自动设置和更新监测的目标区域,这样就å¯ä»¥è¦†ç›–目标进程的整个
+内存映射。然而,用户å¯èƒ½å¸Œæœ›å°†ç›‘测区域é™åˆ¶åœ¨ç‰¹å®šçš„地å€èŒƒå›´å†…ï¼Œå¦‚å †ã€æ ˆæˆ–特定的文件映射区域。
+或者,一些用户å¯ä»¥çŸ¥é“他们工作负载的åˆå§‹è®¿é—®æ¨¡å¼ï¼Œå› æ­¤å¸Œæœ›ä¸ºâ€œè‡ªé€‚应区域调整â€è®¾ç½®æœ€ä½³åˆå§‹åŒºåŸŸã€‚
+
+相比之下,DAMON在物ç†å†…存监测的情况下ä¸ä¼šè‡ªåŠ¨è®¾ç½®å’Œæ›´æ–°ç›‘æµ‹ç›®æ ‡åŒºåŸŸã€‚å› æ­¤ï¼Œç”¨æˆ·åº”è¯¥è‡ªå·±è®¾ç½®
+监测目标区域。
+
+åœ¨è¿™ç§æƒ…况下,用户å¯ä»¥é€šè¿‡åœ¨ ``init_regions`` 文件中写入适当的值,明确地设置他们想è¦çš„åˆ
+始监测目标区域。输入的æ¯ä¸€è¡Œåº”代表一个区域,形å¼å¦‚下::
+
+ <target idx> <start address> <end address>
+
+目标idx应该是 ``target_ids`` 文件中目标的索引,从 ``0`` 开始,区域应该按照地å€é¡ºåºä¼ é€’。
+例如,下é¢çš„命令将设置几个地å€èŒƒå›´ï¼Œ ``1-100`` å’Œ ``100-200`` 作为pid 42çš„åˆå§‹ç›‘测目标
+区域,这是 ``target_ids`` 中的第一个(索引 ``0`` ),å¦å¤–几个地å€èŒƒå›´ï¼Œ ``20-40`` å’Œ
+``50-100`` 作为pid 4242的地å€ï¼Œè¿™æ˜¯ ``target_ids`` 中的第二个(索引 ``1`` )::
+
+ # cd <debugfs>/damon
+ # cat target_ids
+ 42 4242
+ # echo "0 1 100
+ 0 100 200
+ 1 20 40
+ 1 50 100" > init_regions
+
+请注æ„ï¼Œè¿™åªæ˜¯è®¾ç½®äº†åˆå§‹çš„监测目标区域。在虚拟内存监测的情况下,DAMON会在一个 ``区域更新间隔``
+åŽè‡ªåŠ¨æ›´æ–°åŒºåŸŸçš„è¾¹ç•Œã€‚å› æ­¤ï¼Œåœ¨è¿™ç§æƒ…况下,如果用户ä¸å¸Œæœ›æ›´æ–°çš„è¯ï¼Œåº”该把 ``区域的更新间隔`` 设
+置得足够大。
+
+
+方案
+----
+
+对于通常的基于DAMON的数æ®è®¿é—®æ„ŸçŸ¥çš„内存管ç†ä¼˜åŒ–ï¼Œç”¨æˆ·åªæ˜¯å¸Œæœ›ç³»ç»Ÿå¯¹ç‰¹å®šè®¿é—®æ¨¡å¼çš„内存区域应用内
+å­˜ç®¡ç†æ“作。DAMON从用户那里接收这ç§å½¢å¼åŒ–çš„æ“作方案,并将这些方案应用到目标进程中。
+
+用户å¯ä»¥é€šè¿‡è¯»å–和写入 ``scheme`` debugfs文件æ¥èŽ·å¾—å’Œè®¾ç½®è¿™äº›æ–¹æ¡ˆã€‚è¯»å–该文件还å¯ä»¥æ˜¾ç¤ºæ¯ä¸ª
+方案的统计数æ®ã€‚在文件中,æ¯ä¸€ä¸ªæ–¹æ¡ˆéƒ½åº”该在æ¯ä¸€è¡Œä¸­ä»¥ä¸‹åˆ—å½¢å¼è¡¨ç¤ºå‡ºæ¥::
+
+ <target access pattern> <action> <quota> <watermarks>
+
+ä½ å¯ä»¥é€šè¿‡ç®€å•地在文件中写入一个空字符串æ¥ç¦ç”¨æ–¹æ¡ˆã€‚
+
+目标访问模å¼
+~~~~~~~~~~~~
+
+``<目标访问模å¼>`` 是由三个范围构æˆçš„,形å¼å¦‚下::
+
+ min-size max-size min-acc max-acc min-age max-age
+
+具体æ¥è¯´ï¼ŒåŒºåŸŸå¤§å°çš„字节数( `min-size` å’Œ `max-size` ),访问频率的æ¯èšåˆåŒºé—´çš„监测访问次
+数( `min-acc` å’Œ `max-acc` ),区域年龄的èšåˆåŒºé—´æ•°ï¼ˆ `min-age` å’Œ `max-age` )都被指定。
+请注æ„,这些范围是å°é—­åŒºé—´ã€‚
+
+动作
+~~~~
+
+``<action>`` 是一个预定义的内存管ç†åŠ¨ä½œçš„æ•´æ•°ï¼ŒDAMON将应用于具有目标访问模å¼çš„区域。支æŒ
+的数字和它们的å«ä¹‰å¦‚下::
+
+ - 0: Call ``madvise()`` for the region with ``MADV_WILLNEED``
+ - 1: Call ``madvise()`` for the region with ``MADV_COLD``
+ - 2: Call ``madvise()`` for the region with ``MADV_PAGEOUT``
+ - 3: Call ``madvise()`` for the region with ``MADV_HUGEPAGE``
+ - 4: Call ``madvise()`` for the region with ``MADV_NOHUGEPAGE``
+ - 5: Do nothing but count the statistics
+
+é…é¢
+~~~~
+
+æ¯ä¸ª ``动作`` 的最佳 ``目标访问模å¼`` å–决于工作负载,所以ä¸å®¹æ˜“找到。更糟糕的是,将æŸä¸ª
+动作的方案设置得过于激进会导致严é‡çš„开销。为了é¿å…è¿™ç§å¼€é”€ï¼Œç”¨æˆ·å¯ä»¥é€šè¿‡ä¸‹é¢è¡¨æ ¼ä¸­çš„ ``<quota>``
+æ¥é™åˆ¶æ–¹æ¡ˆçš„æ—¶é—´å’Œå¤§å°é…é¢::
+
+ <ms> <sz> <reset interval> <priority weights>
+
+这使得DAMON在 ``<reset interval>`` 毫秒内,尽é‡åªç”¨ ``<ms>`` 毫秒的时间对 ``目标访
+问模å¼`` 的内存区域应用动作,并在 ``<reset interval>`` 内åªå¯¹æœ€å¤š<sz>字节的内存区域应
+用动作。将 ``<ms>`` å’Œ ``<sz>`` 都设置为零,å¯ä»¥ç¦ç”¨é…é¢é™åˆ¶ã€‚
+
+当预计超过é…é¢é™åˆ¶æ—¶ï¼ŒDAMONä¼šæ ¹æ® ``目标访问模å¼`` 的大å°ã€è®¿é—®é¢‘率和年龄,对å‘现的内存
+区域进行优先排åºã€‚为了实现个性化的优先级,用户å¯ä»¥åœ¨ ``<优先级æƒé‡>`` 中设置这三个属性的
+æƒé‡ï¼Œå…·ä½“å½¢å¼å¦‚下::
+
+ <size weight> <access frequency weight> <age weight>
+
+æ°´ä½
+~~~~
+
+æœ‰äº›æ–¹æ¡ˆéœ€è¦æ ¹æ®ç³»ç»Ÿç‰¹å®šæŒ‡æ ‡çš„当å‰å€¼æ¥è¿è¡Œï¼Œå¦‚è‡ªç”±å†…å­˜æ¯”çŽ‡ã€‚å¯¹äºŽè¿™ç§æƒ…况,用户å¯ä»¥ä¸ºè¯¥æ¡
+件指定水ä½ã€‚::
+
+ <metric> <check interval> <high mark> <middle mark> <low mark>
+
+``<metric>`` æ˜¯ä¸€ä¸ªé¢„å®šä¹‰çš„æ•´æ•°ï¼Œç”¨äºŽè¦æ£€æŸ¥çš„度é‡ã€‚支æŒçš„æ•°å­—和它们的å«ä¹‰å¦‚下。
+
+ - 0: 忽视水ä½
+ - 1: 系统空闲内存率 (åƒåˆ†æ¯”)
+
+æ¯éš” ``<检查间隔>`` 微秒检查一次公制的值。
+
+如果该值高于 ``<高标>`` 或低于 ``<低标>`` ,该方案被åœç”¨ã€‚如果该值低于 ``<中标>`` ,
+该方案将被激活。
+
+统计数æ®
+~~~~~~~~
+
+它还统计æ¯ä¸ªæ–¹æ¡ˆè¢«å°è¯•应用的区域的总数é‡å’Œå­—节数,æ¯ä¸ªæ–¹æ¡ˆè¢«æˆåŠŸåº”ç”¨çš„åŒºåŸŸçš„ä¸¤ä¸ªæ•°é‡ï¼Œä»¥
+åŠè¶…过é…é¢é™åˆ¶çš„æ€»æ•°é‡ã€‚这些统计数æ®å¯ç”¨äºŽåœ¨çº¿åˆ†æžæˆ–调整方案。
+
+统计数æ®å¯ä»¥é€šè¿‡è¯»å–æ–¹æ¡ˆæ–‡ä»¶æ¥æ˜¾ç¤ºã€‚读å–该文件将显示你在æ¯ä¸€è¡Œä¸­è¾“入的æ¯ä¸ª ``方案`` ,
+统计的五个数字将被加在æ¯ä¸€è¡Œçš„æœ«å°¾ã€‚
+
+例å­
+~~~~
+
+下é¢çš„命令应用了一个方案:â€å¦‚果一个大å°ä¸º[4KiB, 8KiB]的内存区域在[10, 20]çš„èšåˆæ—¶é—´
+间隔内显示出æ¯ä¸€ä¸ªèšåˆæ—¶é—´é—´éš”[0, 5]的访问é‡ï¼Œè¯·åˆ†é¡µå‡ºè¯¥åŒºåŸŸã€‚对于分页,æ¯ç§’最多åªèƒ½ä½¿
+用10ms,而且æ¯ç§’分页ä¸èƒ½è¶…过1GiB。在这一é™åˆ¶ä¸‹ï¼Œé¦–先分页出具有较长年龄的内存区域。å¦å¤–,
+æ¯5秒钟检查一次系统的å¯ç”¨å†…存率,当å¯ç”¨å†…存率低于50%时开始监测和分页,但如果å¯ç”¨å†…存率
+大于60%,或低于30%ï¼Œåˆ™åœæ­¢ç›‘测“::
+
+ # cd <debugfs>/damon
+ # scheme="4096 8192 0 5 10 20 2" # target access pattern and action
+ # scheme+=" 10 $((1024*1024*1024)) 1000" # quotas
+ # scheme+=" 0 0 100" # prioritization weights
+ # scheme+=" 1 5000000 600 500 300" # watermarks
+ # echo "$scheme" > schemes
+
+
+开关
+----
+
+除éžä½ æ˜Žç¡®åœ°å¯åŠ¨ç›‘æµ‹ï¼Œå¦åˆ™å¦‚上所述的文件设置ä¸ä¼šäº§ç”Ÿæ•ˆæžœã€‚ä½ å¯ä»¥é€šè¿‡å†™å…¥å’Œè¯»å– ``monitor_on``
+文件æ¥å¯åЍã€åœæ­¢å’Œæ£€æŸ¥ç›‘测的当å‰çжæ€ã€‚写入 ``on`` 该文件å¯ä»¥å¯åŠ¨å¯¹æœ‰å±žæ€§çš„ç›®æ ‡çš„ç›‘æµ‹ã€‚å†™å…¥
+``off`` è¯¥æ–‡ä»¶åˆ™åœæ­¢è¿™äº›ç›®æ ‡ã€‚如果æ¯ä¸ªç›®æ ‡è¿›ç¨‹è¢«ç»ˆæ­¢ï¼ŒDAMONä¹Ÿä¼šåœæ­¢ã€‚下é¢çš„示例命令开å¯ã€å…³
+闭和检查DAMON的状æ€::
+
+ # cd <debugfs>/damon
+ # echo on > monitor_on
+ # echo off > monitor_on
+ # cat monitor_on
+ off
+
+请注æ„ï¼Œå½“ç›‘æµ‹å¼€å¯æ—¶ï¼Œä½ ä¸èƒ½å†™åˆ°ä¸Šè¿°çš„debugfs文件。如果你在DAMONè¿è¡Œæ—¶å†™åˆ°è¿™äº›æ–‡ä»¶ï¼Œå°†ä¼šè¿”
+回一个错误代ç ï¼Œå¦‚ ``-EBUSY`` 。
+
+
+监测线程PID
+-----------
+
+DAMON通过一个å«åškdamond的内核线程æ¥è¿›è¡Œè¯·æ±‚监测。你å¯ä»¥é€šè¿‡è¯»å– ``kdamond_pid`` 文件获
+得该线程的 ``pid`` 。当监测被 ``关闭`` 时,读å–该文件ä¸ä¼šè¿”回任何信æ¯::
+
+ # cd <debugfs>/damon
+ # cat monitor_on
+ off
+ # cat kdamond_pid
+ none
+ # echo on > monitor_on
+ # cat kdamond_pid
+ 18594
+
+
+使用多个监测线程
+----------------
+
+æ¯ä¸ªç›‘测上下文都会创建一个 ``kdamond`` 线程。你å¯ä»¥ä½¿ç”¨ ``mk_contexts`` å’Œ ``rm_contexts``
+文件为多个 ``kdamond`` 需è¦çš„用例创建和删除监测上下文。
+
+将新上下文的å称写入 ``mk_contexts`` 文件,在 ``DAMON debugfs`` 目录上创建一个该å称的目录。
+该目录将有该上下文的 ``DAMON debugfs`` 文件::
+
+ # cd <debugfs>/damon
+ # ls foo
+ # ls: cannot access 'foo': No such file or directory
+ # echo foo > mk_contexts
+ # ls foo
+ # attrs init_regions kdamond_pid schemes target_ids
+
+如果ä¸å†éœ€è¦ä¸Šä¸‹æ–‡ï¼Œä½ å¯ä»¥é€šè¿‡æŠŠä¸Šä¸‹æ–‡çš„å字放到 ``rm_contexts`` 文件中æ¥åˆ é™¤å®ƒå’Œç›¸åº”的目录::
+
+ # echo foo > rm_contexts
+ # ls foo
+ # ls: cannot access 'foo': No such file or directory
+
+注æ„, ``mk_contexts`` 〠``rm_contexts`` å’Œ ``monitor_on`` 文件åªåœ¨æ ¹ç›®å½•下。
+
+
+监测结果的监测点
+================
+
+DAMON通过一个tracepoint ``damon:damon_aggregated`` æä¾›ç›‘测结果. å½“ç›‘æµ‹å¼€å¯æ—¶ï¼Œä½ å¯
+以记录追踪点事件,并使用追踪点支æŒå·¥å…·å¦‚perf显示结果。比如说::
+
+ # echo on > monitor_on
+ # perf record -e damon:damon_aggregated &
+ # sleep 5
+ # kill 9 $(pidof perf)
+ # echo off > monitor_on
+ # perf script
diff --git a/Documentation/translations/zh_CN/admin-guide/mm/index.rst b/Documentation/translations/zh_CN/admin-guide/mm/index.rst
new file mode 100644
index 000000000000..702271c5b683
--- /dev/null
+++ b/Documentation/translations/zh_CN/admin-guide/mm/index.rst
@@ -0,0 +1,49 @@
+.. include:: ../../disclaimer-zh_CN.rst
+
+:Original: Documentation/admin-guide/mm/index.rst
+
+:翻译:
+
+ å¾é‘« xu xin <xu.xin16@zte.com.cn>
+
+
+========
+内存管ç†
+========
+
+Linux内存管ç†å­ç³»ç»Ÿï¼Œé¡¾åæ€ä¹‰ï¼Œæ˜¯è´Ÿè´£ç³»ç»Ÿä¸­çš„内存管ç†ã€‚它包括了虚拟内存与请求
+分页的实现,内核内部结构和用户空间程åºçš„内存分é…ã€å°†æ–‡ä»¶æ˜ å°„到进程地å€ç©ºé—´ä»¥
+åŠè®¸å¤šå…¶ä»–很酷的事情。
+
+Linuxå†…å­˜ç®¡ç†æ˜¯ä¸€ä¸ªå…·æœ‰è®¸å¤šå¯é…ç½®è®¾ç½®çš„å¤æ‚系统, 且这些设置中的大多数都å¯ä»¥é€š
+过 ``/proc`` 文件系统获得,并且å¯ä»¥ä½¿ç”¨ ``sysctl`` 进行查询和调整。这些API接
+å£è¢«æè¿°åœ¨Documentation/admin-guide/sysctl/vm.rst文件和 `man 5 proc`_ 中。
+
+.. _man 5 proc: http://man7.org/linux/man-pages/man5/proc.5.html
+
+Linuxå†…å­˜ç®¡ç†æœ‰å®ƒè‡ªå·±çš„æœ¯è¯­ï¼Œå¦‚果你还ä¸ç†Ÿæ‚‰å®ƒï¼Œè¯·è€ƒè™‘阅读下é¢å‚考:
+:ref:`Documentation/admin-guide/mm/concepts.rst <mm_concepts>`.
+
+在此目录下,我们详细æè¿°äº†å¦‚何与Linux内存管ç†ä¸­çš„å„ç§æœºåˆ¶äº¤äº’。
+
+.. toctree::
+ :maxdepth: 1
+
+ damon/index
+ ksm
+
+Todolist:
+* concepts
+* cma_debugfs
+* hugetlbpage
+* idle_page_tracking
+* memory-hotplug
+* nommu-mmap
+* numa_memory_policy
+* numaperf
+* pagemap
+* soft-dirty
+* swap_numa
+* transhuge
+* userfaultfd
+* zswap
diff --git a/Documentation/translations/zh_CN/admin-guide/mm/ksm.rst b/Documentation/translations/zh_CN/admin-guide/mm/ksm.rst
new file mode 100644
index 000000000000..4829156ef1ae
--- /dev/null
+++ b/Documentation/translations/zh_CN/admin-guide/mm/ksm.rst
@@ -0,0 +1,148 @@
+.. include:: ../../disclaimer-zh_CN.rst
+
+:Original: Documentation/admin-guide/mm/ksm.rst
+
+:翻译:
+
+ å¾é‘« xu xin <xu.xin16@zte.com.cn>
+
+
+============
+内核åŒé¡µåˆå¹¶
+============
+
+
+概述
+====
+
+KSM是一ç§èƒ½èŠ‚çœå†…存的数æ®åŽ»é‡åŠŸèƒ½ï¼Œç”±CONFIG_KSM=yå¯ç”¨ï¼Œå¹¶åœ¨2.6.32版本时被添
+加到Linuxå†…æ ¸ã€‚è¯¦è§ ``mm/ksm.c`` 的实现,以åŠhttp://lwn.net/Articles/306704
+å’Œhttps://lwn.net/Articles/330589
+
+KSM最åˆç›®çš„æ˜¯ä¸ºäº†ä¸ŽKVM(å³è‘—å的内核共享内存)一起使用而开å‘的,通过共享虚拟机
+之间的公共数æ®ï¼Œå°†æ›´å¤šè™šæ‹Ÿæœºæ”¾å…¥ç‰©ç†å†…存。但它对于任何会生æˆå¤šä¸ªç›¸åŒæ•°æ®å®žä¾‹çš„
+应用程åºéƒ½æ˜¯å¾ˆæœ‰ç”¨çš„。
+
+KSM的守护进程ksmd会定期扫æé‚£äº›å·²æ³¨å†Œçš„用户内存区域,查找内容相åŒçš„页é¢ï¼Œè¿™äº›
+页é¢å¯ä»¥è¢«å•ä¸ªå†™ä¿æŠ¤é¡µé¢æ›¿æ¢ï¼ˆå¦‚æžœè¿›ç¨‹ä»¥åŽæƒ³è¦æ›´æ–°å…¶å†…容,将自动å¤åˆ¶ï¼‰ã€‚使用:
+引用:`sysfs intraface <ksm_sysfs>` æŽ¥å£æ¥é…ç½®KSM守护程åºåœ¨å•个过程中所扫æçš„页
+数以åŠä¸¤ä¸ªè¿‡ç¨‹ä¹‹é—´çš„间隔时间。
+
+KSMåªåˆå¹¶åŒ¿åï¼ˆç§æœ‰ï¼‰é¡µé¢ï¼Œä»Žä¸åˆå¹¶é¡µç¼“存(文件)页é¢ã€‚KSMçš„åˆå¹¶é¡µé¢æœ€åˆåªèƒ½è¢«
+é”定在内核内存中,但现在å¯ä»¥å°±åƒå…¶ä»–用户页é¢ä¸€æ ·è¢«æ¢å‡ºï¼ˆä½†å½“它们被交æ¢å›žæ¥æ—¶å…±
+享会被破å: ksmdå¿…é¡»é‡æ–°å‘çŽ°å®ƒä»¬çš„èº«ä»½å¹¶å†æ¬¡åˆå¹¶ï¼‰ã€‚
+
+以madvise控制KSM
+================
+
+KSM仅在特定的地å€ç©ºé—´åŒºåŸŸæ—¶è¿è¡Œï¼Œå³åº”用程åºé€šè¿‡ä½¿ç”¨å¦‚下所示的madvise(2)系统调
+用æ¥è¯·æ±‚æŸå—åœ°å€æˆä¸ºå¯èƒ½çš„åˆå¹¶å€™é€‰è€…的地å€ç©ºé—´::
+
+ int madvise(addr, length, MADV_MERGEABLE)
+
+应用程åºå½“然也å¯ä»¥é€šè¿‡è°ƒç”¨::
+
+ int madvise(addr, length, MADV_UNMERGEABLE)
+
+æ¥å–消该请求,并æ¢å¤ä¸ºéžå…±äº«é¡µé¢ï¼šæ­¤æ—¶KSM将去除åˆå¹¶åœ¨è¯¥èŒƒå›´å†…的任何åˆå¹¶é¡µã€‚注æ„:
+这个去除åˆå¹¶çš„调用å¯èƒ½çªç„¶éœ€è¦çš„内存é‡è¶…过实际å¯ç”¨çš„内存é‡-那么å¯èƒ½ä¼šå‡ºçްEAGAIN
+失败,但更å¯èƒ½ä¼šå”¤é†’OOM killer。
+
+如果KSM未被é…置到正在è¿è¡Œçš„内核中,则madvise MADV_MERGEABLE å’Œ MADV_UNMERGEABLE
+的调用åªä¼šä»¥EINVAL 失败。如果正在è¿è¡Œçš„内核是用CONFIG_KSM=yæ–¹å¼æž„建的,那么这些
+调用通常会æˆåŠŸï¼šå³ä½¿KSM守护程åºå½“剿²¡æœ‰è¿è¡Œï¼ŒMADV_MERGEABLE ä»ç„¶ä¼šåœ¨KSM守护程åº
+å¯åŠ¨æ—¶æ³¨å†ŒèŒƒå›´ï¼Œå³ä½¿è¯¥èŒƒå›´ä¸èƒ½åŒ…å«KSM实际å¯ä»¥åˆå¹¶çš„任何页é¢ï¼Œå³ä½¿MADV_UNMERGEABLE
+应用于从未标记为MADV_MERGEABLE的范围。
+
+如果一å—内存区域必须被拆分为至少一个新的MADV_MERGEABLE区域或MADV_UNMERGEABLE区域,
+当该进程将超过 ``vm.max_map_count`` 的设定,则madviseå¯èƒ½è¿”回ENOMEM。(请å‚阅文档
+Documentation/admin-guide/sysctl/vm.rst)。
+
+与其他madvise调用一样,它们在用户地å€ç©ºé—´çš„æ˜ å°„åŒºåŸŸä¸Šä½¿ç”¨ï¼šå¦‚æžœæŒ‡å®šçš„èŒƒå›´åŒ…å«æœª
+映射的间隙(尽管在中间的映射区域工作),它们将报告ENOMEM,如果没有足够的内存用于
+内部结构,则å¯èƒ½ä¼šå› EAGAIN而失败。
+
+KSM守护进程sysfs接å£
+====================
+
+KSM守护进程å¯ä»¥ç”±``/sys/kernel/mm/ksm/`` 中的sysfs文件控制,所有人都å¯ä»¥è¯»å–,但
+åªèƒ½ç”±rootç”¨æˆ·å†™å…¥ã€‚å„æŽ¥å£è§£é‡Šå¦‚下:
+
+
+pages_to_scan
+ ksmd进程进入ç¡çœ å‰è¦æ‰«æçš„页数。
+ 例如, ``echo 100 > /sys/kernel/mm/ksm/pages_to_scan``
+
+ 默认值:100(该值被选择用于演示目的)
+
+sleep_millisecs
+ ksmd在下次扫æå‰åº”休眠多少毫秒
+ 例如, ``echo 20 > /sys/kernel/mm/ksm/sleep_millisecs``
+
+ 默认值:20(该值被选择用于演示目的)
+
+merge_across_nodes
+ 指定是å¦å¯ä»¥åˆå¹¶æ¥è‡ªä¸åŒNUMA节点的页é¢ã€‚当设置为0时,ksmä»…åˆå¹¶åœ¨ç‰©ç†ä¸Šä½
+ 于åŒä¸€NUMA节点的内存区域中的页é¢ã€‚è¿™é™ä½Žäº†è®¿é—®å…±äº«é¡µé¢çš„延迟。在有明显的
+ NUMAè·ç¦»ä¸Šï¼Œå…·æœ‰æ›´å¤šèŠ‚ç‚¹çš„ç³»ç»Ÿå¯èƒ½å—益于设置该值为0时的更低延迟。而对于
+ 需è¦å¯¹å†…å­˜ä½¿ç”¨é‡æœ€å°åŒ–的较å°ç³»ç»Ÿæ¥è¯´ï¼Œè®¾ç½®è¯¥å€¼ä¸º1(默认设置)则å¯èƒ½ä¼šå—
+ 益于更大共享页é¢ã€‚在决定使用哪ç§è®¾ç½®ä¹‹å‰ï¼Œæ‚¨å¯èƒ½å¸Œæœ›æ¯”较系统在æ¯ç§è®¾ç½®ä¸‹
+ 的性能。 ``merge_across_nodes`` 仅当系统中没有ksmå…±äº«é¡µé¢æ—¶ï¼Œæ‰èƒ½è¢«æ›´æ”¹è®¾
+ 置:首先将接å£`run` 设置为2从而对页进行去åˆå¹¶ï¼Œç„¶åŽåœ¨ä¿®æ”¹
+ ``merge_across_nodes`` åŽå†å°†â€˜run’åˆè®¾ç½®ä¸º1ï¼Œä»¥æ ¹æ®æ–°è®¾ç½®æ¥é‡æ–°åˆå¹¶ã€‚
+
+ 默认值:1(如早期的å‘布版本一样åˆå¹¶è·¨ç«™ç‚¹ï¼‰
+
+run
+ * 设置为0å¯åœæ­¢ksmdè¿è¡Œï¼Œä½†ä¿ç•™åˆå¹¶é¡µé¢ï¼Œ
+ * 设置为1å¯è¿è¡Œksmd,例如, ``echo 1 > /sys/kernel/mm/ksm/run`` ,
+ * 设置为2å¯åœæ­¢ksmdè¿è¡Œï¼Œå¹¶ä¸”对所有目å‰å·²åˆå¹¶çš„页进行去åˆå¹¶ï¼Œä½†ä¿ç•™å¯åˆå¹¶
+ 区域以供下次è¿è¡Œã€‚
+
+ 默认值:0(必须设置为1æ‰èƒ½æ¿€æ´»KSM,除éžç¦ç”¨äº†CONFIG_SYSFS)
+
+use_zero_pages
+ 指定是å¦åº”当特殊处ç†ç©ºé¡µï¼ˆå³é‚£äº›ä»…å«zero的已分é…页)。当该值设置为1时,
+ 空页与内核零页åˆå¹¶ï¼Œè€Œä¸æ˜¯åƒé€šå¸¸æƒ…况下那样空页自身彼此åˆå¹¶ã€‚è¿™å¯ä»¥æ ¹æ®
+ 工作负载的ä¸åŒï¼Œåœ¨å…·æœ‰ç€è‰²é›¶é¡µçš„æž¶æž„上å¯ä»¥æé«˜æ€§èƒ½ã€‚å¯ç”¨æ­¤è®¾ç½®æ—¶åº”å°å¿ƒï¼Œ
+ 因为它å¯èƒ½ä¼šé™ä½ŽæŸäº›å·¥ä½œè´Ÿè½½çš„KSM性能,比如,当待åˆå¹¶çš„候选页é¢çš„æ ¡éªŒå’Œ
+ 与空页é¢çš„æ ¡éªŒå’Œæ°å¥½åŒ¹é…的时候。此设置å¯éšæ—¶æ›´æ”¹ï¼Œä»…å¯¹é‚£äº›æ›´æ”¹åŽå†åˆå¹¶
+ çš„é¡µé¢æœ‰æ•ˆã€‚
+
+ 默认值:0ï¼ˆå¦‚åŒæ—©æœŸç‰ˆæœ¬çš„KSM正常表现)
+
+max_page_sharing
+ å•个KSM页é¢å…许的最大共享站点数。这将强制执行é‡å¤æ•°æ®æ¶ˆé™¤é™åˆ¶ï¼Œä»¥é¿å…涉
+ åŠé历共享KSM页é¢çš„虚拟映射的虚拟内存æ“作的高延迟。最å°å€¼ä¸º2,因为新创
+ 建的KSM页é¢å°†è‡³å°‘有两个共享者。该值越高,KSMåˆå¹¶å†…存的速度越快,去é‡
+ å› å­ä¹Ÿè¶Šé«˜ï¼Œä½†æ˜¯å¯¹äºŽä»»ä½•给定的KSM页é¢ï¼Œè™šæ‹Ÿæ˜ å°„çš„æœ€åæƒ…况é历的速度也会
+ è¶Šæ…¢ã€‚å‡æ…¢äº†è¿™ç§é历速度就æ„味ç€åœ¨äº¤æ¢ã€åŽ‹ç¼©ã€NUMA平衡和页é¢è¿ç§»æœŸé—´ï¼Œ
+ æŸäº›è™šæ‹Ÿå†…å­˜æ“作将有更高的延迟,从而é™ä½Žè¿™äº›è™šæ‹Ÿå†…å­˜æ“作调用者的å“应能力。
+ å…¶ä»–ä»»åŠ¡å¦‚æžœä¸æ¶‰åŠæ‰§è¡Œè™šæ‹Ÿæ˜ å°„é历的VMæ“作,其任务调度延迟ä¸å—æ­¤å‚æ•°çš„å½±
+ å“,因为这些é历本身是调度å‹å¥½çš„。
+
+stable_node_chains_prune_millisecs
+ 指定KSM检查特定页é¢çš„元数æ®çš„频率(å³é‚£äº›è¾¾åˆ°è¿‡æ—¶ä¿¡æ¯æ•°æ®åŽ»é‡é™åˆ¶æ ‡å‡†çš„
+ 页é¢ï¼‰å•使˜¯æ¯«ç§’。较å°çš„æ¯«ç§’值将以更低的延迟æ¥é‡Šæ”¾KSM元数æ®ï¼Œä½†å®ƒä»¬å°†ä½¿
+ ksmdåœ¨æ‰«ææœŸé—´ä½¿ç”¨æ›´å¤šCPU。如果还没有一个KSM页é¢è¾¾åˆ° ``max_page_sharing``
+ 标准,那就没有什么用。
+
+KSM与MADV_MERGEABLE的工作有效性体现于 ``/sys/kernel/mm/ksm/`` 路径下的接å£ï¼š
+
+pages_shared
+ 表示多少共享页正在被使用
+pages_sharing
+ 表示还有多少站点正在共享这些共享页,å³èŠ‚çœäº†å¤šå°‘
+pages_unshared
+ 表示有多少页是唯一的,但被å夿£€æŸ¥ä»¥è¿›è¡Œåˆå¹¶
+pages_volatile
+ 表示有多少页因å˜åŒ–太快而无法放在tree中
+full_scans
+ 表示所有å¯åˆå¹¶åŒºåŸŸå·²æ‰«æå¤šå°‘次
+stable_node_chains
+ 达到 ``max_page_sharing`` é™åˆ¶çš„KSM页数
+stable_node_dups
+ é‡å¤çš„KSM页数
+
+比值 ``pages_sharing/pages_shared`` 的最大值å—é™åˆ¶äºŽ ``max_page_sharing``
+çš„è®¾å®šã€‚è¦æƒ³å¢žåŠ è¯¥æ¯”å€¼ï¼Œåˆ™ç›¸åº”åœ°è¦å¢žåŠ  ``max_page_sharing`` 的值。
diff --git a/Documentation/translations/zh_CN/core-api/index.rst b/Documentation/translations/zh_CN/core-api/index.rst
index d10191c45cf1..26d9913fc8b6 100644
--- a/Documentation/translations/zh_CN/core-api/index.rst
+++ b/Documentation/translations/zh_CN/core-api/index.rst
@@ -42,6 +42,7 @@
kref
assoc_array
xarray
+ rbtree
Todolist:
@@ -49,7 +50,6 @@ Todolist:
idr
circular-buffers
- rbtree
generic-radix-tree
packing
bus-virt-phys-mapping
diff --git a/Documentation/translations/zh_CN/core-api/rbtree.rst b/Documentation/translations/zh_CN/core-api/rbtree.rst
new file mode 100644
index 000000000000..a3e1555cb974
--- /dev/null
+++ b/Documentation/translations/zh_CN/core-api/rbtree.rst
@@ -0,0 +1,391 @@
+.. SPDX-License-Identifier: GPL-2.0
+.. include:: ../disclaimer-zh_CN.rst
+
+:Original: Documentation/core-api/rbtree.rst
+
+:翻译:
+
+ å”艺舟 Tang Yizhou <tangyeechou@gmail.com>
+
+=========================
+Linux中的红黑树(rbtree)
+=========================
+
+
+:日期: 2007年1月18日
+:作者: Rob Landley <rob@landley.net>
+
+何为红黑树,它们有什么用?
+--------------------------
+
+红黑树是一ç§è‡ªå¹³è¡¡äºŒå‰æœç´¢æ ‘,被用æ¥å­˜å‚¨å¯æŽ’åºçš„é”®/值数æ®å¯¹ã€‚这与基数树(被用æ¥é«˜æ•ˆ
+å­˜å‚¨ç¨€ç–æ•°ç»„ï¼Œå› æ­¤ä½¿ç”¨é•¿æ•´åž‹ä¸‹æ ‡æ¥æ’å…¥/访问/åˆ é™¤ç»“ç‚¹ï¼‰å’Œå“ˆå¸Œè¡¨ï¼ˆæ²¡æœ‰ä¿æŒæŽ’åºå› è€Œæ— æ³•
+容易地按åºéåŽ†ï¼ŒåŒæ—¶å¿…须调节其大å°å’Œå“ˆå¸Œå‡½æ•°ï¼Œç„¶è€Œçº¢é»‘æ ‘å¯ä»¥ä¼˜é›…地伸缩以便存储任æ„
+æ•°é‡çš„键)ä¸åŒã€‚
+
+红黑树和AVL树类似,但在æ’入和删除时æä¾›äº†æ›´å¿«çš„å®žæ—¶æœ‰ç•Œçš„æœ€åæƒ…况性能(分别最多两次
+旋转和三次旋转,æ¥å¹³è¡¡æ ‘ï¼‰ï¼ŒæŸ¥è¯¢æ—¶é—´è½»å¾®å˜æ…¢ï¼ˆä½†æ—¶é—´å¤æ‚度ä»ç„¶æ˜¯O(log n))。
+
+引用Linuxæ¯å‘¨æ–°é—»ï¼ˆLinux Weekly News):
+
+ å†…æ ¸ä¸­æœ‰å¤šå¤„çº¢é»‘æ ‘çš„ä½¿ç”¨æ¡ˆä¾‹ã€‚æœ€åŽæœŸé™è°ƒåº¦å™¨å’Œå®Œå…¨å…¬å¹³æŽ’队(CFQ)I/O调度器利用
+ 红黑树跟踪请求;数æ®åŒ…CD/DVD驱动程åºä¹Ÿæ˜¯å¦‚此。高精度时钟代ç ä½¿ç”¨ä¸€é¢—红黑树组织
+ 未完æˆçš„定时器请求。ext3文件系统用红黑树跟踪目录项。虚拟内存区域(VMAs)ã€epoll
+ 文件æè¿°ç¬¦ã€å¯†ç å­¦å¯†é’¥å’Œåœ¨â€œåˆ†å±‚令牌桶â€è°ƒåº¦å™¨ä¸­çš„网络数æ®åŒ…都由红黑树跟踪。
+
+本文档涵盖了对Linux红黑树实现的使用方法。更多关于红黑树的性质和实现的信æ¯ï¼Œå‚è§ï¼š
+
+ Linuxæ¯å‘¨æ–°é—»å…³äºŽçº¢é»‘树的文章
+ https://lwn.net/Articles/184495/
+
+ ç»´åŸºç™¾ç§‘çº¢é»‘æ ‘è¯æ¡
+ https://en.wikipedia.org/wiki/Red-black_tree
+
+红黑树的Linux实现
+-----------------
+
+Linux的红黑树实现在文件“lib/rbtree.câ€ä¸­ã€‚è¦ä½¿ç”¨å®ƒï¼Œéœ€è¦â€œ#include <linux/rbtree.h>â€ã€‚
+
+Linux的红黑树实现对速度进行了优化,因此比传统的实现少一个间接层(有更好的缓存局部性)。
+æ¯ä¸ªrb_node结构体的实例嵌入在它管ç†çš„æ•°æ®ç»“构中,因此ä¸éœ€è¦é æŒ‡é’ˆæ¥åˆ†ç¦»rb_node和它
+管ç†çš„æ•°æ®ç»“构。用户应该编写他们自己的树æœç´¢å’Œæ’入函数,æ¥è°ƒç”¨å·²æä¾›çš„红黑树函数,
+è€Œä¸æ˜¯ä½¿ç”¨ä¸€ä¸ªæ¯”较回调函数指针。加é”代ç ä¹Ÿç•™ç»™çº¢é»‘树的用户编写。
+
+创建一颗红黑树
+--------------
+
+红黑树中的数æ®ç»“点是包å«rb_node结构体æˆå‘˜çš„结构体::
+
+ struct mytype {
+ struct rb_node node;
+ char *keystring;
+ };
+
+当处ç†ä¸€ä¸ªæŒ‡å‘内嵌rb_node结构体的指针时,包ä½rb_node的结构体å¯ç”¨æ ‡å‡†çš„container_of()
+å®è®¿é—®ã€‚此外,个体æˆå‘˜å¯ç›´æŽ¥ç”¨rb_entry(node, type, member)访问。
+
+æ¯é¢—红黑树的根是一个rb_rootæ•°æ®ç»“构,它由以下方å¼åˆå§‹åŒ–为空:
+
+ struct rb_root mytree = RB_ROOT;
+
+在一颗红黑树中æœç´¢å€¼
+--------------------
+
+为你的树写一个æœç´¢å‡½æ•°æ˜¯ç›¸å½“简å•的:从树根开始,比较æ¯ä¸ªå€¼ï¼Œç„¶åŽæ ¹æ®éœ€è¦ç»§ç»­å‰å¾€å·¦è¾¹æˆ–
+å³è¾¹çš„分支。
+
+示例::
+
+ struct mytype *my_search(struct rb_root *root, char *string)
+ {
+ struct rb_node *node = root->rb_node;
+
+ while (node) {
+ struct mytype *data = container_of(node, struct mytype, node);
+ int result;
+
+ result = strcmp(string, data->keystring);
+
+ if (result < 0)
+ node = node->rb_left;
+ else if (result > 0)
+ node = node->rb_right;
+ else
+ return data;
+ }
+ return NULL;
+ }
+
+在一颗红黑树中æ’入数æ®
+----------------------
+
+在树中æ’入数æ®çš„æ­¥éª¤åŒ…括:首先æœç´¢æ’入新结点的ä½ç½®ï¼Œç„¶åŽæ’入结点并对树å†å¹³è¡¡
+("recoloring")。
+
+æ’入的æœç´¢å’Œä¸Šæ–‡çš„æœç´¢ä¸åŒï¼Œå®ƒè¦æ‰¾åˆ°å«æŽ¥æ–°ç»“点的ä½ç½®ã€‚新结点也需è¦ä¸€ä¸ªæŒ‡å‘它的父节点
+的链接,以达到å†å¹³è¡¡çš„目的。
+
+示例::
+
+ int my_insert(struct rb_root *root, struct mytype *data)
+ {
+ struct rb_node **new = &(root->rb_node), *parent = NULL;
+
+ /* Figure out where to put new node */
+ while (*new) {
+ struct mytype *this = container_of(*new, struct mytype, node);
+ int result = strcmp(data->keystring, this->keystring);
+
+ parent = *new;
+ if (result < 0)
+ new = &((*new)->rb_left);
+ else if (result > 0)
+ new = &((*new)->rb_right);
+ else
+ return FALSE;
+ }
+
+ /* Add new node and rebalance tree. */
+ rb_link_node(&data->node, parent, new);
+ rb_insert_color(&data->node, root);
+
+ return TRUE;
+ }
+
+在一颗红黑树中删除或替æ¢å·²ç»å­˜åœ¨çš„æ•°æ®
+--------------------------------------
+
+è‹¥è¦ä»Žæ ‘中删除一个已ç»å­˜åœ¨çš„结点,调用::
+
+ void rb_erase(struct rb_node *victim, struct rb_root *tree);
+
+示例::
+
+ struct mytype *data = mysearch(&mytree, "walrus");
+
+ if (data) {
+ rb_erase(&data->node, &mytree);
+ myfree(data);
+ }
+
+è‹¥è¦ç”¨ä¸€ä¸ªæ–°ç»“ç‚¹æ›¿æ¢æ ‘中一个已ç»å­˜åœ¨çš„键值相åŒçš„结点,调用::
+
+ void rb_replace_node(struct rb_node *old, struct rb_node *new,
+ struct rb_root *tree);
+
+é€šè¿‡è¿™ç§æ–¹å¼æ›¿æ¢ç»“点ä¸ä¼šå¯¹æ ‘åšé‡æŽ’åºï¼šå¦‚果新结点的键值和旧结点ä¸åŒï¼Œçº¢é»‘æ ‘å¯èƒ½è¢«
+ç ´å。
+
+(按排åºçš„顺åºï¼‰é历存储在红黑树中的元素
+----------------------------------------
+
+我们æä¾›äº†å››ä¸ªå‡½æ•°ï¼Œç”¨äºŽä»¥æŽ’åºçš„æ–¹å¼é历一颗红黑树的内容。这些函数å¯ä»¥åœ¨ä»»æ„红黑树
+上工作,并且ä¸éœ€è¦è¢«ä¿®æ”¹æˆ–包装(除éžåŠ é”的目的)::
+
+ struct rb_node *rb_first(struct rb_root *tree);
+ struct rb_node *rb_last(struct rb_root *tree);
+ struct rb_node *rb_next(struct rb_node *node);
+ struct rb_node *rb_prev(struct rb_node *node);
+
+è¦å¼€å§‹è¿­ä»£ï¼Œéœ€è¦ä½¿ç”¨ä¸€ä¸ªæŒ‡å‘树根的指针调用rb_first()或rb_last(),它将返回一个指å‘
+树中第一个或最åŽä¸€ä¸ªå…ƒç´ æ‰€åŒ…å«çš„节点结构的指针。è¦ç»§ç»­çš„è¯ï¼Œå¯ä»¥åœ¨å½“å‰ç»“点上调用
+rb_next()或rb_prev()æ¥èŽ·å–下一个或上一个结点。当没有剩余的结点时,将返回NULL。
+
+迭代器函数返回一个指å‘被嵌入的rb_node结构体的指针,由此,包ä½rb_node的结构体å¯ç”¨
+标准的container_of()å®è®¿é—®ã€‚此外,个体æˆå‘˜å¯ç›´æŽ¥ç”¨rb_entry(node, type, member)
+访问。
+
+示例::
+
+ struct rb_node *node;
+ for (node = rb_first(&mytree); node; node = rb_next(node))
+ printk("key=%s\n", rb_entry(node, struct mytype, node)->keystring);
+
+带缓存的红黑树
+--------------
+
+计算最左边(最å°çš„ï¼‰ç»“ç‚¹æ˜¯äºŒå‰æœç´¢æ ‘的一个相当常è§çš„任务,例如用于é历,或用户根æ®
+他们自己的逻辑ä¾èµ–一个特定的顺åºã€‚为此,用户å¯ä»¥ä½¿ç”¨'struct rb_root_cached'æ¥ä¼˜åŒ–
+æ—¶é—´å¤æ‚度为O(logN)çš„rb_first()的调用,以简å•åœ°èŽ·å–æŒ‡é’ˆï¼Œé¿å…了潜在的昂贵的树迭代。
+维护æ“作的é¢å¤–è¿è¡Œæ—¶é—´å¼€é”€å¯å¿½ç•¥ï¼Œä¸è¿‡å†…å­˜å ç”¨è¾ƒå¤§ã€‚
+
+å’Œrb_root结构体类似,带缓存的红黑树由以下方å¼åˆå§‹åŒ–为空::
+
+ struct rb_root_cached mytree = RB_ROOT_CACHED;
+
+å¸¦ç¼“å­˜çš„çº¢é»‘æ ‘åªæ˜¯ä¸€ä¸ªå¸¸è§„çš„rb_root,加上一个é¢å¤–的指针æ¥ç¼“存最左边的节点。这使得
+rb_root_cachedå¯ä»¥å­˜åœ¨äºŽrb_root存在的任何地方,并且åªéœ€å¢žåŠ å‡ ä¸ªæŽ¥å£æ¥æ”¯æŒå¸¦ç¼“存的
+æ ‘::
+
+ struct rb_node *rb_first_cached(struct rb_root_cached *tree);
+ void rb_insert_color_cached(struct rb_node *, struct rb_root_cached *, bool);
+ void rb_erase_cached(struct rb_node *node, struct rb_root_cached *);
+
+æ“作和删除也有对应的带缓存的树的调用::
+
+ void rb_insert_augmented_cached(struct rb_node *node, struct rb_root_cached *,
+ bool, struct rb_augment_callbacks *);
+ void rb_erase_augmented_cached(struct rb_node *, struct rb_root_cached *,
+ struct rb_augment_callbacks *);
+
+
+对增强型红黑树的支æŒ
+--------------------
+
+增强型红黑树是一ç§åœ¨æ¯ä¸ªç»“点里存储了“一些â€é™„加数æ®çš„红黑树,其中结点N的附加数æ®
+必须是以Nä¸ºæ ¹çš„å­æ ‘中所有结点的内容的函数。它是建立在红黑树基础设施之上的å¯é€‰ç‰¹æ€§ã€‚
+想è¦ä½¿ç”¨è¿™ä¸ªç‰¹æ€§çš„红黑树用户,æ’入和删除结点时必须调用增强型接å£å¹¶æä¾›å¢žå¼ºåž‹å›žè°ƒå‡½æ•°ã€‚
+
+实现增强型红黑树æ“作的C文件必须包å«<linux/rbtree_augmented.h>è€Œä¸æ˜¯<linux/rbtree.h>。
+注æ„,linux/rbtree_augmented.h暴露了一些红黑树实现的细节而你ä¸åº”ä¾èµ–å®ƒä»¬ï¼Œè¯·åšæŒ
+使用文档记录的API,并且ä¸è¦åœ¨å¤´æ–‡ä»¶ä¸­åŒ…å«<linux/rbtree_augmented.h>,以最å°åŒ–ä½ çš„
+用户æ„外地ä¾èµ–这些实现细节的å¯èƒ½ã€‚
+
+æ’入时,用户必须更新通往被æ’入节点的路径上的增强信æ¯ï¼Œç„¶åŽåƒå¾€å¸¸ä¸€æ ·è°ƒç”¨rb_link_node(),
+ç„¶åŽæ˜¯rb_augment_inserted()è€Œä¸æ˜¯å¹³æ—¶çš„rb_insert_color()调用。如果
+rb_augment_inserted()å†å¹³è¡¡äº†çº¢é»‘树,它将回调至一个用户æä¾›çš„å‡½æ•°æ¥æ›´æ–°å—å½±å“çš„
+å­æ ‘上的增强信æ¯ã€‚
+
+删除一个结点时,用户必须调用rb_erase_augmented()è€Œä¸æ˜¯rb_erase()。
+rb_erase_augmented()回调至一个用户æä¾›çš„å‡½æ•°æ¥æ›´æ–°å—å½±å“çš„å­æ ‘上的增强信æ¯ã€‚
+
+åœ¨ä¸¤ç§æƒ…况下,回调都是通过rb_augment_callbacks结构体æä¾›çš„。必须定义3个回调:
+
+- 一个传播回调,它更新一个给定结点和它的祖先们的增强数æ®ï¼Œç›´åˆ°ä¸€ä¸ªç»™å®šçš„åœæ­¢ç‚¹
+ (如果是NULL,将更新一路更新到树根)。
+
+- 一个å¤åˆ¶å›žè°ƒï¼Œå®ƒå°†ä¸€é¢—ç»™å®šå­æ ‘的增强数æ®å¤åˆ¶åˆ°ä¸€ä¸ªæ–°æŒ‡å®šçš„å­æ ‘树根。
+
+- ä¸€ä¸ªæ ‘æ—‹è½¬å›žè°ƒï¼Œå®ƒå°†ä¸€é¢—ç»™å®šçš„å­æ ‘的增强值å¤åˆ¶åˆ°æ–°æŒ‡å®šçš„å­æ ‘æ ‘æ ¹ä¸Šï¼Œå¹¶é‡æ–°è®¡ç®—
+ å…ˆå‰çš„å­æ ‘树根的增强值。
+
+rb_erase_augmented()编译åŽçš„代ç å¯èƒ½ä¼šå†…è”ä¼ æ’­ã€å¤åˆ¶å›žè°ƒï¼Œè¿™å°†å¯¼è‡´å‡½æ•°ä½“积更大,
+å› æ­¤æ¯ä¸ªå¢žå¼ºåž‹çº¢é»‘æ ‘çš„ç”¨æˆ·åº”è¯¥åªæœ‰ä¸€ä¸ªrb_erase_augmented()的调用点,以é™åˆ¶ç¼–译åŽ
+的代ç å¤§å°ã€‚
+
+
+使用示例
+^^^^^^^^
+
+区间树是增强型红黑树的一个例å­ã€‚å‚考Cormen,Leiserson,Rivestå’ŒStein写的
+《算法导论》。区间树的更多细节:
+
+ç»å…¸çš„çº¢é»‘æ ‘åªæœ‰ä¸€ä¸ªé”®ï¼Œå®ƒä¸èƒ½ç›´æŽ¥ç”¨æ¥å­˜å‚¨åƒ[lo:hi]这样的区间范围,也ä¸èƒ½å¿«é€ŸæŸ¥æ‰¾
+与新的lo:hié‡å çš„éƒ¨åˆ†ï¼Œæˆ–è€…æŸ¥æ‰¾æ˜¯å¦æœ‰ä¸Žæ–°çš„lo:hi完全匹é…的部分。
+
+然而,红黑树å¯ä»¥è¢«å¢žå¼ºï¼Œä»¥ä¸€ç§ç»“æž„åŒ–çš„æ–¹å¼æ¥å­˜å‚¨è¿™ç§åŒºé—´èŒƒå›´ï¼Œä»Žè€Œä½¿é«˜æ•ˆçš„æŸ¥æ‰¾å’Œ
+ç²¾ç¡®åŒ¹é…æˆä¸ºå¯èƒ½ã€‚
+
+这个存储在æ¯ä¸ªèŠ‚ç‚¹ä¸­çš„â€œé¢å¤–ä¿¡æ¯â€æ˜¯å…¶æ‰€æœ‰åŽä»£ç»“点中的最大hi(max_hi)值。这个信æ¯
+å¯ä»¥ä¿æŒåœ¨æ¯ä¸ªç»“点上,åªéœ€æŸ¥çœ‹ä¸€ä¸‹è¯¥ç»“点和它的直系å­ç»“ç‚¹ä»¬ã€‚è¿™å°†è¢«ç”¨äºŽæ—¶é—´å¤æ‚度
+为O(log n)çš„æœ€ä½ŽåŒ¹é…æŸ¥æ‰¾ï¼ˆæ‰€æœ‰å¯èƒ½çš„匹é…中最低的起始地å€ï¼‰ï¼Œå°±åƒè¿™æ ·::
+
+ struct interval_tree_node *
+ interval_tree_first_match(struct rb_root *root,
+ unsigned long start, unsigned long last)
+ {
+ struct interval_tree_node *node;
+
+ if (!root->rb_node)
+ return NULL;
+ node = rb_entry(root->rb_node, struct interval_tree_node, rb);
+
+ while (true) {
+ if (node->rb.rb_left) {
+ struct interval_tree_node *left =
+ rb_entry(node->rb.rb_left,
+ struct interval_tree_node, rb);
+ if (left->__subtree_last >= start) {
+ /*
+ * Some nodes in left subtree satisfy Cond2.
+ * Iterate to find the leftmost such node N.
+ * If it also satisfies Cond1, that's the match
+ * we are looking for. Otherwise, there is no
+ * matching interval as nodes to the right of N
+ * can't satisfy Cond1 either.
+ */
+ node = left;
+ continue;
+ }
+ }
+ if (node->start <= last) { /* Cond1 */
+ if (node->last >= start) /* Cond2 */
+ return node; /* node is leftmost match */
+ if (node->rb.rb_right) {
+ node = rb_entry(node->rb.rb_right,
+ struct interval_tree_node, rb);
+ if (node->__subtree_last >= start)
+ continue;
+ }
+ }
+ return NULL; /* No match */
+ }
+ }
+
+æ’å…¥/删除是通过以下增强型回调æ¥å®šä¹‰çš„::
+
+ static inline unsigned long
+ compute_subtree_last(struct interval_tree_node *node)
+ {
+ unsigned long max = node->last, subtree_last;
+ if (node->rb.rb_left) {
+ subtree_last = rb_entry(node->rb.rb_left,
+ struct interval_tree_node, rb)->__subtree_last;
+ if (max < subtree_last)
+ max = subtree_last;
+ }
+ if (node->rb.rb_right) {
+ subtree_last = rb_entry(node->rb.rb_right,
+ struct interval_tree_node, rb)->__subtree_last;
+ if (max < subtree_last)
+ max = subtree_last;
+ }
+ return max;
+ }
+
+ static void augment_propagate(struct rb_node *rb, struct rb_node *stop)
+ {
+ while (rb != stop) {
+ struct interval_tree_node *node =
+ rb_entry(rb, struct interval_tree_node, rb);
+ unsigned long subtree_last = compute_subtree_last(node);
+ if (node->__subtree_last == subtree_last)
+ break;
+ node->__subtree_last = subtree_last;
+ rb = rb_parent(&node->rb);
+ }
+ }
+
+ static void augment_copy(struct rb_node *rb_old, struct rb_node *rb_new)
+ {
+ struct interval_tree_node *old =
+ rb_entry(rb_old, struct interval_tree_node, rb);
+ struct interval_tree_node *new =
+ rb_entry(rb_new, struct interval_tree_node, rb);
+
+ new->__subtree_last = old->__subtree_last;
+ }
+
+ static void augment_rotate(struct rb_node *rb_old, struct rb_node *rb_new)
+ {
+ struct interval_tree_node *old =
+ rb_entry(rb_old, struct interval_tree_node, rb);
+ struct interval_tree_node *new =
+ rb_entry(rb_new, struct interval_tree_node, rb);
+
+ new->__subtree_last = old->__subtree_last;
+ old->__subtree_last = compute_subtree_last(old);
+ }
+
+ static const struct rb_augment_callbacks augment_callbacks = {
+ augment_propagate, augment_copy, augment_rotate
+ };
+
+ void interval_tree_insert(struct interval_tree_node *node,
+ struct rb_root *root)
+ {
+ struct rb_node **link = &root->rb_node, *rb_parent = NULL;
+ unsigned long start = node->start, last = node->last;
+ struct interval_tree_node *parent;
+
+ while (*link) {
+ rb_parent = *link;
+ parent = rb_entry(rb_parent, struct interval_tree_node, rb);
+ if (parent->__subtree_last < last)
+ parent->__subtree_last = last;
+ if (start < parent->start)
+ link = &parent->rb.rb_left;
+ else
+ link = &parent->rb.rb_right;
+ }
+
+ node->__subtree_last = last;
+ rb_link_node(&node->rb, rb_parent, link);
+ rb_insert_augmented(&node->rb, root, &augment_callbacks);
+ }
+
+ void interval_tree_remove(struct interval_tree_node *node,
+ struct rb_root *root)
+ {
+ rb_erase_augmented(&node->rb, root, &augment_callbacks);
+ }
diff --git a/Documentation/translations/zh_CN/cpu-freq/cpu-drivers.rst b/Documentation/translations/zh_CN/cpu-freq/cpu-drivers.rst
index 87a36044f828..2ca92042767b 100644
--- a/Documentation/translations/zh_CN/cpu-freq/cpu-drivers.rst
+++ b/Documentation/translations/zh_CN/cpu-freq/cpu-drivers.rst
@@ -84,6 +84,8 @@ CPUfreq核心层注册一个cpufreq_driver结构体。
.resume - 一个指å‘per-policyæ¢å¤å‡½æ•°çš„æŒ‡é’ˆï¼Œè¯¥å‡½æ•°åœ¨å…³ä¸­æ–­ä¸”在调节器å†ä¸€æ¬¡å¯åЍå‰è¢«
调用。
+ .ready - 一个指å‘per-policy准备函数的指针,该函数在策略完全åˆå§‹åŒ–之åŽè¢«è°ƒç”¨ã€‚
+
.attr - 一个指å‘NULL结尾的"struct freq_attr"列表的指针,该列表å…许导出值到
sysfs。
diff --git a/Documentation/translations/zh_CN/devicetree/index.rst b/Documentation/translations/zh_CN/devicetree/index.rst
new file mode 100644
index 000000000000..23d0b6fccd58
--- /dev/null
+++ b/Documentation/translations/zh_CN/devicetree/index.rst
@@ -0,0 +1,50 @@
+.. SPDX-License-Identifier: GPL-2.0
+.. include:: ../disclaimer-zh_CN.rst
+
+:Original: Documentation/Devicetree/index.rst
+
+:翻译:
+
+ å¸å»¶è…¾ Yanteng Si <siyanteng@loongson.cn>
+
+:校译:
+
+
+=============================
+Open Firmware 和 Devicetree
+=============================
+
+该文档是整个设备树文档的总目录,标题中多是业内默认的术语,åˆè§å°±ç¿»è¯‘æˆä¸­æ–‡ï¼Œ
+晦涩难懂,因此尽é‡ä¿ç•™ï¼ŒåŽé¢ç¿»è¯‘å…¶å­æ–‡æ¡£æ—¶ï¼Œå¯èƒ½ä¼šæ ¹æ®è¯­å¢ƒï¼Œçµæ´»åœ°ç¿»è¯‘为中文。
+
+内核Devicetree的使用
+=======================
+.. toctree::
+ :maxdepth: 1
+
+ usage-model
+ of_unittest
+
+Todolist:
+
+* kernel-api
+
+Devicetree Overlays
+===================
+.. toctree::
+ :maxdepth: 1
+
+Todolist:
+
+* changesets
+* dynamic-resolution-notes
+* overlay-notes
+
+Devicetree Bindings
+===================
+.. toctree::
+ :maxdepth: 1
+
+Todolist:
+
+* bindings/index
diff --git a/Documentation/translations/zh_CN/devicetree/of_unittest.rst b/Documentation/translations/zh_CN/devicetree/of_unittest.rst
new file mode 100644
index 000000000000..abd94e771ef8
--- /dev/null
+++ b/Documentation/translations/zh_CN/devicetree/of_unittest.rst
@@ -0,0 +1,189 @@
+.. SPDX-License-Identifier: GPL-2.0
+.. include:: ../disclaimer-zh_CN.rst
+
+:Original: Documentation/Devicetree/of_unittest.rst
+
+:翻译:
+
+ å¸å»¶è…¾ Yanteng Si <siyanteng@loongson.cn>
+
+:校译:
+
+=================================
+Open Firmware Devicetree å•元测试
+=================================
+
+作者: Gaurav Minocha <gaurav.minocha.os@gmail.com>
+
+1. 概述
+=======
+
+本文档解释了执行 OF å•å…ƒæµ‹è¯•æ‰€éœ€çš„æµ‹è¯•æ•°æ®æ˜¯å¦‚何动æ€åœ°é™„加到实时树上的,与机器的架构无关。
+
+建议在继续读下去之å‰ï¼Œå…ˆé˜…读以下文件。
+
+(1) Documentation/devicetree/usage-model.rst
+(2) http://www.devicetree.org/Device_Tree_Usage
+
+OF Selftestè¢«è®¾è®¡ç”¨æ¥æµ‹è¯•æä¾›ç»™è®¾å¤‡é©±åЍ开å‘者的接å£ï¼ˆinclude/linux/of.h),以从未æ‰å¹³
+化的设备树数æ®ç»“构中获å–设备信æ¯ç­‰ã€‚这个接å£è¢«å¤§å¤šæ•°è®¾å¤‡é©±åŠ¨åœ¨å„ç§ä½¿ç”¨æƒ…况下使用。
+
+
+2. 测试数æ®
+===========
+
+è®¾å¤‡æ ‘æºæ–‡ä»¶ï¼ˆdrivers/of/unittest-data/testcases.dtsï¼‰åŒ…å«æ‰§è¡Œdrivers/of/unittest.c
+中自动化å•元测试所需的测试数æ®ã€‚ç›®å‰ï¼Œä»¥ä¸‹è®¾å¤‡æ ‘æºåŒ…嫿–‡ä»¶ï¼ˆ.dtsi)被包å«åœ¨testcases.dt中::
+
+ drivers/of/unittest-data/tests-interrupts.dtsi
+ drivers/of/unittest-data/tests-platform.dtsi
+ drivers/of/unittest-data/tests-phandle.dtsi
+ drivers/of/unittest-data/tests-match.dtsi
+
+当内核在å¯ç”¨OF_SELFTEST的情况下被构建时,那么下é¢çš„make规则::
+
+ $(obj)/%.dtb: $(src)/%.dts FORCE
+ $(call if_changed_dep, dtc)
+
+用于将DTæºæ–‡ä»¶ï¼ˆtestcases.dts)编译æˆäºŒè¿›åˆ¶blob(testcases.dtb),也被称为æ‰å¹³åŒ–çš„DT。
+
+之åŽï¼Œä½¿ç”¨ä»¥ä¸‹è§„则将上述二进制blob包装æˆä¸€ä¸ªæ±‡ç¼–文件(testcases.dtb.S)::
+
+ $(obj)/%.dtb.S: $(obj)/%.dtb
+ $(call cmd, dt_S_dtb)
+
+汇编文件被编译æˆä¸€ä¸ªå¯¹è±¡æ–‡ä»¶ï¼ˆtestcases.dtb.o),并被链接到内核镜åƒä¸­ã€‚
+
+
+2.1. 添加测试数æ®
+-----------------
+
+未æ‰å¹³åŒ–的设备树结构体:
+
+未æ‰å¹³åŒ–的设备树由连接的设备节点组æˆï¼Œå…¶æ ‘状结构形å¼å¦‚下所述::
+
+ // following struct members are used to construct the tree
+ struct device_node {
+ ...
+ struct device_node *parent;
+ struct device_node *child;
+ struct device_node *sibling;
+ ...
+ };
+
+图1æè¿°äº†ä¸€ä¸ªæœºå™¨çš„æœªæ‰å¹³åŒ–设备树的通用结构,åªè€ƒè™‘了å­èŠ‚ç‚¹å’ŒåŒçº§æŒ‡é’ˆã€‚存在å¦ä¸€ä¸ªæŒ‡é’ˆï¼Œ
+``*parent`` ,用于åå‘é历该树。因此,在一个特定的层次上,å­èŠ‚ç‚¹å’Œæ‰€æœ‰çš„å…„å¼Ÿå§å¦¹èŠ‚ç‚¹å°†
+有一个指å‘å…±åŒèŠ‚ç‚¹çš„çˆ¶æŒ‡é’ˆï¼ˆä¾‹å¦‚ï¼Œchild1ã€sibling2ã€sibling3ã€sibling4的父指针指å‘
+根节点)::
+
+ root ('/')
+ |
+ child1 -> sibling2 -> sibling3 -> sibling4 -> null
+ | | | |
+ | | | null
+ | | |
+ | | child31 -> sibling32 -> null
+ | | | |
+ | | null null
+ | |
+ | child21 -> sibling22 -> sibling23 -> null
+ | | | |
+ | null null null
+ |
+ child11 -> sibling12 -> sibling13 -> sibling14 -> null
+ | | | |
+ | | | null
+ | | |
+ null null child131 -> null
+ |
+ null
+
+Figure 1: 未æ‰å¹³åŒ–的设备树的通用结构
+
+
+在执行OFå•元测试之å‰ï¼Œéœ€è¦å°†æµ‹è¯•æ•°æ®é™„加到机器的设备树上(如果存在)。因此,当调用
+selftest_data_add()时,首先会读å–通过以下内核符å·é“¾æŽ¥åˆ°å†…核镜åƒä¸­çš„æ‰å¹³åŒ–è®¾å¤‡æ ‘
+æ•°æ®::
+
+ __dtb_testcases_begin - address marking the start of test data blob
+ __dtb_testcases_end - address marking the end of test data blob
+
+其次,它调用of_fdt_unflatten_tree()æ¥è§£é™¤æ‰å¹³åŒ–çš„blob。最åŽï¼Œå¦‚果机器的设备树
+(å³å®žæ—¶æ ‘)是存在的,那么它将未æ‰å¹³åŒ–çš„æµ‹è¯•æ•°æ®æ ‘附加到实时树上,å¦åˆ™å®ƒå°†è‡ªå·±ä½œä¸º
+实时设备树附加。
+
+attach_node_and_children()使用of_attach_node()将节点附加到实时树上,如下所
+述。为了解释这一点,图2中æè¿°çš„æµ‹è¯•æ•°æ®æ ‘被附加到图1中æè¿°çš„实时树上::
+
+ root ('/')
+ |
+ testcase-data
+ |
+ test-child0 -> test-sibling1 -> test-sibling2 -> test-sibling3 -> null
+ | | | |
+ test-child01 null null null
+
+
+Figure 2: å°†æµ‹è¯•æ•°æ®æ ‘附在实时树上的例å­ã€‚
+
+æ ¹æ®ä¸Šé¢çš„æ–¹æ¡ˆï¼Œå®žæ—¶æ ‘å·²ç»å­˜åœ¨ï¼Œæ‰€ä»¥ä¸éœ€è¦é™„加根('/')节点。所有其他节点都是通过在
+æ¯ä¸ªèŠ‚ç‚¹ä¸Šè°ƒç”¨of_attach_node()æ¥é™„加的。
+
+在函数of_attach_node()中,新的节点被附在实时树中给定的父节点的å­èŠ‚ç‚¹ä¸Šã€‚ä½†æ˜¯ï¼Œå¦‚
+æžœçˆ¶èŠ‚ç‚¹å·²ç»æœ‰äº†ä¸€ä¸ªå­©å­ï¼Œé‚£ä¹ˆæ–°èŠ‚ç‚¹å°±ä¼šå–代当å‰çš„å­©å­ï¼Œå¹¶å°†å…¶å˜æˆå…¶å…„弟å§å¦¹ã€‚因此,
+当测试案例的数æ®èŠ‚ç‚¹è¢«è¿žæŽ¥åˆ°ä¸Šé¢çš„实时树(图1)时,最终的结构如图3所示::
+
+ root ('/')
+ |
+ testcase-data -> child1 -> sibling2 -> sibling3 -> sibling4 -> null
+ | | | | |
+ (...) | | | null
+ | | child31 -> sibling32 -> null
+ | | | |
+ | | null null
+ | |
+ | child21 -> sibling22 -> sibling23 -> null
+ | | | |
+ | null null null
+ |
+ child11 -> sibling12 -> sibling13 -> sibling14 -> null
+ | | | |
+ null null | null
+ |
+ child131 -> null
+ |
+ null
+ -----------------------------------------------------------------------
+
+ root ('/')
+ |
+ testcase-data -> child1 -> sibling2 -> sibling3 -> sibling4 -> null
+ | | | | |
+ | (...) (...) (...) null
+ |
+ test-sibling3 -> test-sibling2 -> test-sibling1 -> test-child0 -> null
+ | | | |
+ null null null test-child01
+
+
+Figure 3: 附加测试案例数æ®åŽçš„实时设备树结构。
+
+
+èªæ˜Žçš„读者会注æ„到,与先å‰çš„结构相比,test-child0节点æˆä¸ºæœ€åŽä¸€ä¸ªå…„弟å§å¦¹ï¼ˆå›¾2)。
+在连接了第一个test-child0节点之åŽï¼Œåˆè¿žæŽ¥äº†test-sibling1节点,该节点推动å­èŠ‚ç‚¹
+(å³test-child0)æˆä¸ºå…„弟å§å¦¹ï¼Œå¹¶ä½¿è‡ªå·±æˆä¸ºå­èŠ‚ç‚¹ï¼Œå¦‚ä¸Šæ‰€è¿°ã€‚
+
+如果å‘现一个é‡å¤çš„节点(å³å¦‚果一个具有相åŒfull_name属性的节点已ç»å­˜åœ¨äºŽå®žæ—¶æ ‘中),
+那么该节点ä¸ä¼šè¢«é™„加,而是通过调用函数update_node_properties()将其属性更新到活
+树的节点中。
+
+
+2.2. 删除测试数æ®
+-----------------
+
+一旦测试用例执行完,selftest_data_remove被调用,以移除最åˆè¿žæŽ¥çš„设备节点(首先是
+å¶å­èŠ‚ç‚¹è¢«åˆ†ç¦»ï¼Œç„¶åŽå‘ä¸Šç§»åŠ¨çˆ¶èŠ‚ç‚¹è¢«ç§»é™¤ï¼Œæœ€åŽæ˜¯æ•´ä¸ªæ ‘)。selftest_data_remove()
+调用detach_node_and_children(),使用of_detach_node()将节点从实时设备树上分离。
+
+为了分离一个节点,of_detach_node()è¦ä¹ˆå°†ç»™å®šèŠ‚ç‚¹çš„çˆ¶èŠ‚ç‚¹çš„å­èŠ‚ç‚¹æŒ‡é’ˆæ›´æ–°ä¸ºå…¶åŒçº§èŠ‚
+点,è¦ä¹ˆæ ¹æ®æƒ…况将å‰ä¸€ä¸ªåŒçº§èŠ‚ç‚¹é™„åœ¨ç»™å®šèŠ‚ç‚¹çš„åŒçº§èŠ‚ç‚¹ä¸Šã€‚å°±è¿™æ ·å§ã€‚ :)
diff --git a/Documentation/translations/zh_CN/devicetree/usage-model.rst b/Documentation/translations/zh_CN/devicetree/usage-model.rst
new file mode 100644
index 000000000000..318a3c6a0114
--- /dev/null
+++ b/Documentation/translations/zh_CN/devicetree/usage-model.rst
@@ -0,0 +1,330 @@
+.. SPDX-License-Identifier: GPL-2.0
+.. include:: ../disclaimer-zh_CN.rst
+
+:Original: Documentation/Devicetree/usage-model.rst
+
+:翻译:
+
+ å¸å»¶è…¾ Yanteng Si <siyanteng@loongson.cn>
+
+:校译:
+
+
+===================
+Linux 和 Devicetree
+===================
+
+Linux对设备树数æ®çš„使用模型
+
+:作者: Grant Likely <grant.likely@secretlab.ca>
+
+这篇文章æè¿°äº†Linuxå¦‚ä½•ä½¿ç”¨è®¾å¤‡æ ‘ã€‚å…³äºŽè®¾å¤‡æ ‘æ•°æ®æ ¼å¼çš„æ¦‚è¿°å¯ä»¥åœ¨
+devicetree.org\ [1]_ 的设备树使用页é¢ä¸Šæ‰¾åˆ°ã€‚
+
+.. [1] https://www.devicetree.org/specifications/
+
+"Open Firmware Device Tree",或简称为Devicetree(DT),是一ç§ç”¨äºŽæè¿°ç¡¬
+件的数æ®ç»“æž„å’Œè¯­è¨€ã€‚æ›´ç¡®åˆ‡åœ°è¯´ï¼Œå®ƒæ˜¯ä¸€ç§æ“作系统å¯è¯»çš„硬件æè¿°ï¼Œè¿™æ ·æ“作系统就ä¸
+需è¦å¯¹æœºå™¨çš„细节进行硬编ç ã€‚
+
+从结构上看,DT是一棵树,或者说是带有命å节点的无环图,节点å¯ä»¥æœ‰ä»»æ„æ•°é‡çš„命å
+属性æ¥å°è£…ä»»æ„的数æ®ã€‚è¿˜å­˜åœ¨ä¸€ç§æœºåˆ¶ï¼Œå¯ä»¥åœ¨è‡ªç„¶çš„æ ‘状结构之外创建从一个节点到
+å¦ä¸€ä¸ªèŠ‚ç‚¹çš„ä»»æ„链接。
+
+从概念上讲,一套通用的使用惯例,称为 "bindings"ï¼ˆåŽæ–‡è¯‘为绑定),被定义为数æ®
+应该如何出现在树中,以æè¿°å…¸åž‹çš„ç¡¬ä»¶ç‰¹æ€§ï¼ŒåŒ…æ‹¬æ•°æ®æ€»çº¿ã€ä¸­æ–­çº¿ã€GPIO连接和外围
+设备。
+
+å°½å¯èƒ½ä½¿ç”¨çŽ°æœ‰çš„ç»‘å®šæ¥æè¿°ç¡¬ä»¶ï¼Œä»¥æœ€å¤§é™åº¦åœ°åˆ©ç”¨çŽ°æœ‰çš„æ”¯æŒä»£ç ï¼Œä½†ç”±äºŽå±žæ€§å’ŒèŠ‚
+点å称是简å•çš„æ–‡æœ¬å­—ç¬¦ä¸²ï¼Œé€šè¿‡å®šä¹‰æ–°çš„èŠ‚ç‚¹å’Œå±žæ€§æ¥æ‰©å±•现有的绑定或创建新的绑定
+很容易。然而,è¦è­¦æƒ•的是,在创建一个新的绑定之å‰ï¼Œæœ€å¥½å…ˆå¯¹å·²ç»å­˜åœ¨çš„东西åšä¸€äº›
+åŠŸè¯¾ã€‚ç›®å‰æœ‰ä¸¤ç§ä¸åŒçš„ã€ä¸å…¼å®¹çš„i2c总线的绑定,这是因为在创建新的绑定时没有事先
+调查i2c设备在现有系统中是如何被枚举的。
+
+1. 历å²
+-------
+DTæœ€åˆæ˜¯ç”±Open Firmware创建的,作为将数æ®ä»ŽOpen Firmware传递给客户程åº
+(如传递给æ“作系统)的通信方法的一部分。æ“作系统使用设备树在è¿è¡Œæ—¶æŽ¢æµ‹ç¡¬ä»¶çš„æ‹“
+扑结构,从而在没有硬编ç ä¿¡æ¯çš„æƒ…况下支æŒå¤§å¤šæ•°å¯ç”¨çš„硬件(å‡è®¾æ‰€æœ‰è®¾å¤‡çš„驱动程
+åºéƒ½å¯ç”¨ï¼‰ã€‚
+
+由于Open Firmware通常在PowerPCå’ŒSPARCå¹³å°ä¸Šä½¿ç”¨ï¼Œé•¿æœŸä»¥æ¥ï¼Œå¯¹è¿™äº›æž¶æž„çš„
+Linux支æŒä¸€ç›´ä½¿ç”¨è®¾å¤‡æ ‘。
+
+2005年,当PowerPC Linux开始大规模清ç†å¹¶åˆå¹¶32ä½å’Œ64使”¯æŒæ—¶ï¼Œå†³å®šåœ¨æ‰€æœ‰
+Powerpcå¹³å°ä¸Šè¦æ±‚DT支æŒï¼Œæ— è®ºå®ƒä»¬æ˜¯å¦ä½¿ç”¨Open Firmware。为了åšåˆ°è¿™ä¸€ç‚¹ï¼Œ
+我们创建了一个å«åšæ‰å¹³åŒ–设备树(FDT)的DT表示法,它å¯ä»¥ä½œä¸ºä¸€ä¸ªäºŒè¿›åˆ¶çš„blob
+传递给内核,而ä¸éœ€è¦çœŸæ­£çš„Open Firmware实现。U-Bootã€kexec和其他引导程åº
+被修改,以支æŒä¼ é€’设备树二进制(dtb)和在引导时修改dtb。DT也被添加到PowerPC
+引导包装器(arch/powerpc/boot/\*)中,这样dtbå°±å¯ä»¥è¢«åŒ…裹在内核镜åƒä¸­ï¼Œä»¥
+支æŒå¼•导现有的éžDT察觉的固件。
+
+一段时间åŽï¼ŒFDT基础架构被普åŠåˆ°äº†æ‰€æœ‰çš„æž¶æž„中。在写这篇文章的时候,6个主线架
+构(armã€microblazeã€mipsã€powerpcã€sparcå’Œx86)和1个éžä¸»çº¿æž¶æž„(ios)
+有æŸç§ç¨‹åº¦çš„DT支æŒã€‚
+
+1. æ•°æ®æ¨¡åž‹
+-----------
+如果你还没有读过设备树用法\ [1]_页,那么现在就去读å§ã€‚没关系,我等ç€....
+
+2.1 高层次视角
+--------------
+最é‡è¦çš„æ˜¯è¦æ˜Žç™½ï¼ŒDTåªæ˜¯ä¸€ä¸ªæè¿°ç¡¬ä»¶çš„æ•°æ®ç»“构。它没有什么神奇之处,也ä¸ä¼šç¥ž
+奇地让所有的硬件é…置问题消失。它所åšçš„æ˜¯æä¾›ä¸€ç§è¯­è¨€ï¼Œå°†ç¡¬ä»¶é…置与Linux内核
+(或任何其他æ“作系统)中的æ¿å¡å’Œè®¾å¤‡é©±åŠ¨æ”¯æŒè§£è€¦ã€‚使用它å¯ä»¥ä½¿æ¿å¡å’Œè®¾å¤‡æ”¯æŒ
+å˜æˆæ•°æ®é©±åŠ¨ï¼›æ ¹æ®ä¼ é€’到内核的数æ®åšå‡ºè®¾ç½®å†³å®šï¼Œè€Œä¸æ˜¯æ ¹æ®æ¯å°æœºå™¨çš„硬编ç é€‰
+择。
+
+ç†æƒ³æƒ…况下,数æ®é©±åŠ¨çš„å¹³å°è®¾ç½®åº”该导致更少的代ç é‡å¤ï¼Œå¹¶ä½¿å…¶æ›´å®¹æ˜“用一个内核
+é•œåƒæ”¯æŒå„ç§ç¡¬ä»¶ã€‚
+
+Linux使用DTæ•°æ®æœ‰ä¸‰ä¸ªä¸»è¦ç›®çš„:
+
+1) å¹³å°è¯†åˆ«ã€‚
+2) è¿è¡Œæ—¶é…置,以åŠ
+3) 设备数é‡ã€‚
+
+2.2 å¹³å°è¯†åˆ«
+------------
+首先,内核将使用DTä¸­çš„æ•°æ®æ¥è¯†åˆ«ç‰¹å®šçš„æœºå™¨ã€‚åœ¨ä¸€ä¸ªç†æƒ³çš„世界里,具体的平å°å¯¹
+内核æ¥è¯´å¹¶ä¸é‡è¦ï¼Œå› ä¸ºæ‰€æœ‰çš„å¹³å°ç»†èŠ‚éƒ½ä¼šè¢«è®¾å¤‡æ ‘ä»¥ä¸€è‡´å’Œå¯é çš„æ–¹å¼å®Œç¾Žæè¿°ã€‚
+但是,硬件并ä¸å®Œç¾Žï¼Œæ‰€ä»¥å†…核必须在早期å¯åŠ¨æ—¶è¯†åˆ«æœºå™¨ï¼Œä»¥ä¾¿æœ‰æœºä¼šè¿è¡Œç‰¹å®šäºŽæœº
+器的修å¤ç¨‹åºã€‚
+
+在大多数情况下,机器的身份是ä¸ç›¸å…³çš„ï¼Œè€Œå†…æ ¸å°†æ ¹æ®æœºå™¨çš„æ ¸å¿ƒCPU或SoCæ¥é€‰æ‹©
+设置代ç ã€‚例如,在ARM上,arch/arm/kernel/setup.c中的setup_arch()将调
+用arch/arm/kernel/devtree.c中的setup_machine_fdt(),它通过
+machine_desc表æœç´¢å¹¶é€‰æ‹©ä¸Žè®¾å¤‡æ ‘æ•°æ®æœ€åŒ¹é…çš„machine_desc。它通过查看根
+设备树节点中的'compatible'属性,并将其与struct machine_desc中的
+dt_compat列表(如果你好奇,该列表定义在arch/arm/include/asm/mach/arch.h
+中)进行比较,从而确定最佳匹é…。
+
+“compatible†属性包å«ä¸€ä¸ªæŽ’åºçš„字符串列表,以机器的确切å称开始,åŽé¢æ˜¯
+一个å¯é€‰çš„与之兼容的æ¿å­åˆ—表,从最兼容到最ä¸å…¼å®¹æŽ’åºã€‚例如,TI BeagleBoard
+和它的åŽç»§è€…BeagleBoard xMæ¿çš„æ ¹å…¼å®¹å±žæ€§å¯èƒ½çœ‹èµ·æ¥åˆ†åˆ«ä¸º::
+
+ compatible = "ti,omap3-beagleboard", "ti,omap3450", "ti,omap3";
+ compatible = "ti,omap3-beagleboard-xm", "ti,omap3450", "ti,omap3";
+
+其中 "ti,map3-beagleboard-xm "指定了确切的型å·ï¼Œå®ƒè¿˜å£°ç§°å®ƒä¸ŽOMAP 3450 SoC
+以åŠä¸€èˆ¬çš„OMP3系列SoC兼容。你会注æ„到,该列表从最具体的(确切的æ¿å­ï¼‰åˆ°æœ€
+ä¸å…·ä½“的(SoC系列)进行排åºã€‚
+
+èªæ˜Žçš„读者å¯èƒ½ä¼šæŒ‡å‡ºï¼ŒBeagle xM也å¯ä»¥å£°ç§°ä¸ŽåŽŸBeagleæ¿å…¼å®¹ã€‚然而,我们应
+该当心在æ¿çº§ä¸Šè¿™æ ·åšï¼Œå› ä¸ºé€šå¸¸æƒ…况下,å³ä½¿åœ¨åŒä¸€äº§å“系列中,æ¯å—æ¿éƒ½æœ‰å¾ˆé«˜
+çš„å˜åŒ–ï¼Œè€Œä¸”å½“ä¸€å—æ¿å£°ç§°ä¸Žå¦ä¸€å—æ¿å…¼å®¹æ—¶ï¼Œå¾ˆéš¾ç¡®å®šåˆ°åº•æ˜¯ä»€ä¹ˆæ„æ€ã€‚对于高层
+æ¥è¯´ï¼Œæœ€å¥½æ˜¯è°¨æ…Žè¡Œäº‹ï¼Œä¸è¦å£°ç§°ä¸€å—æ¿å­ä¸Žå¦ä¸€å—æ¿å­å…¼å®¹ã€‚值得注æ„的例外是,
+当䏀嗿¿å­æ˜¯å¦ä¸€å—æ¿å­çš„载体时,例如CPU模å—连接到一个载体æ¿ä¸Šã€‚
+
+关于兼容值还有一个注æ„事项。在兼容属性中使用的任何字符串都必须有文件说明它
+表示什么。在Documentation/devicetree/bindings中添加兼容字符串的文档。
+
+åŒæ ·åœ¨ARM上,对于æ¯ä¸ªmachine_descï¼Œå†…æ ¸ä¼šæŸ¥çœ‹æ˜¯å¦æœ‰ä»»ä½•dt_compat列表æ¡
+目出现在兼容属性中。如果有,那么该机器_desc就是驱动该机器的候选者。在æœç´¢
+了整个machine_descs表之åŽï¼Œsetup_machine_fdt()æ ¹æ®æ¯ä¸ªmachine_desc
+在兼容属性中匹é…çš„æ¡ç›®ï¼Œè¿”回 “最兼容†的machine_desc。如果没有找到匹é…
+的machine_desc,那么它将返回NULL。
+
+这个方案背åŽçš„原因是观察到,在大多数情况下,如果它们都使用相åŒçš„SoC或相åŒ
+系列的SoC,一个机器_descå¯ä»¥æ”¯æŒå¤§é‡çš„电路æ¿ã€‚然而,ä¸å¯é¿å…地会有一些例
+外情况,å³ç‰¹å®šçš„æ¿å­éœ€è¦ç‰¹æ®Šçš„设置代ç ï¼Œè¿™åœ¨ä¸€èˆ¬æƒ…况下是没有用的。特殊情况
+å¯ä»¥é€šè¿‡åœ¨é€šç”¨è®¾ç½®ä»£ç ä¸­æ˜Žç¡®æ£€æŸ¥æœ‰é—®é¢˜çš„æ¿å­æ¥å¤„ç†ï¼Œä½†å¦‚果超过几个情况下,
+这样åšå¾ˆå¿«å°±ä¼šå˜å¾—很难看和/或无法维护。
+
+相å,兼容列表å…许通用机器_desc通过在dt_compat列表中指定“ä¸å¤ªå…¼å®¹â€çš„值
+æ¥æä¾›å¯¹å¹¿æ³›çš„é€šç”¨æ¿çš„æ”¯æŒã€‚在上é¢çš„例å­ä¸­ï¼Œé€šç”¨æ¿æ”¯æŒå¯ä»¥å£°ç§°ä¸Žâ€œti,ompa3â€
+或“ti,ompa3450â€å…¼å®¹ã€‚如果在最åˆçš„beagleboard上å‘现了一个bug,需è¦åœ¨
+早期å¯åŠ¨æ—¶ä½¿ç”¨ç‰¹æ®Šçš„å˜é€šä»£ç ï¼Œé‚£ä¹ˆå¯ä»¥æ·»åŠ ä¸€ä¸ªæ–°çš„machine_desc,实现å˜é€šï¼Œ
+并且åªåœ¨â€œti,omap3-beagleboardâ€ä¸ŠåŒ¹é…。
+
+PowerPC使用了一个ç¨å¾®ä¸åŒçš„æ–¹æ¡ˆï¼Œå®ƒä»Žæ¯ä¸ªæœºå™¨_desc中调用.probe()é’©å­ï¼Œ
+并使用第一个返回TRUE的钩å­ã€‚ç„¶è€Œï¼Œè¿™ç§æ–¹æ³•没有考虑到兼容列表的优先级,对于
+新的架构支æŒå¯èƒ½åº”该é¿å…。
+
+2.3 è¿è¡Œæ—¶é…ç½®
+--------------
+在大多数情况下,DT是将数æ®ä»Žå›ºä»¶ä¼ é€’给内核的唯一方法,所以也被用æ¥ä¼ é€’è¿è¡Œ
+æ—¶å’Œé…置数æ®ï¼Œå¦‚å†…æ ¸å‚æ•°å­—符串和initrd镜åƒçš„ä½ç½®ã€‚
+
+这些数æ®å¤§éƒ¨åˆ†éƒ½åŒ…å«åœ¨/chosen节点中,当å¯åЍLinux时,它看起æ¥å°±åƒè¿™æ ·::
+
+ chosen {
+ bootargs = "console=ttyS0,115200 loglevel=8";
+ initrd-start = <0xc8000000>;
+ initrd-end = <0xc8200000>;
+ };
+
+bootargs属性包å«å†…æ ¸å‚æ•°ï¼Œinitrd-\*属性定义initrd blob的地å€å’Œå¤§å°ã€‚注
+æ„initrd-end是initrd映åƒåŽçš„第一个地å€ï¼Œæ‰€ä»¥è¿™ä¸Žç»“构体资æºçš„通常语义ä¸ä¸€
+致。选择的节点也å¯ä»¥é€‰æ‹©åŒ…å«ä»»æ„æ•°é‡çš„é¢å¤–属性,用于平å°ç‰¹å®šçš„é…置数æ®ã€‚
+
+在早期å¯åŠ¨è¿‡ç¨‹ä¸­ï¼Œæž¶æž„è®¾ç½®ä»£ç é€šè¿‡ä¸åŒçš„辅助回调函数多次调用
+of_scan_flat_dt()æ¥è§£æžè®¾å¤‡æ ‘æ•°æ®ï¼Œç„¶åŽè¿›è¡Œåˆ†é¡µè®¾ç½®ã€‚of_scan_flat_dt()
+ä»£ç æ‰«æè®¾å¤‡æ ‘ï¼Œå¹¶ä½¿ç”¨è¾…åŠ©å‡½æ•°æ¥æå–æ—©æœŸå¯åŠ¨æœŸé—´æ‰€éœ€çš„ä¿¡æ¯ã€‚通常情况下,
+early_init_dt_scan_chosen()è¾…åŠ©å‡½æ•°ç”¨äºŽè§£æžæ‰€é€‰èŠ‚ç‚¹ï¼ŒåŒ…æ‹¬å†…æ ¸å‚æ•°ï¼Œ
+early_init_dt_scan_root()用于åˆå§‹åŒ–DT地å€ç©ºé—´æ¨¡åž‹ï¼Œearly_init_dt_scan_memory()
+用于确定å¯ç”¨RAM的大å°å’Œä½ç½®ã€‚
+
+在ARM上,函数setup_machine_fdt()è´Ÿè´£åœ¨é€‰æ‹©æ”¯æŒæ¿å­çš„æ­£ç¡®machine_desc
+åŽï¼Œå¯¹è®¾å¤‡æ ‘进行早期扫æã€‚
+
+2.4 设备数é‡
+------------
+在电路æ¿è¢«è¯†åˆ«åŽï¼Œåœ¨æ—©æœŸé…置数æ®è¢«è§£æžåŽï¼Œå†…æ ¸åˆå§‹åŒ–å¯ä»¥ä»¥æ­£å¸¸æ–¹å¼è¿›è¡Œã€‚在
+这个过程中的æŸä¸ªæ—¶åˆ»ï¼Œunflatten_device_tree()被调用以将数æ®è½¬æ¢æˆæ›´æœ‰
+效的è¿è¡Œæ—¶è¡¨ç¤ºã€‚这也是调用机器特定设置钩å­çš„æ—¶å€™ï¼Œæ¯”如ARM上的machine_desc
+.init_early()ã€.init_irq()å’Œ.init_machine()é’©å­ã€‚本节的其余部分使用
+了ARM实现的例å­ï¼Œä½†æ‰€æœ‰æž¶æž„在使用DT时都会åšå‡ ä¹Žç›¸åŒçš„事情。
+
+从å称上å¯ä»¥çŒœåˆ°ï¼Œ.init_early()用于在å¯åŠ¨è¿‡ç¨‹æ—©æœŸéœ€è¦æ‰§è¡Œçš„任何机器特定设
+置,而.init_irq()则用于设置中断处ç†ã€‚使用DTå¹¶ä¸ä¼šå®žè´¨æ€§åœ°æ”¹å˜è¿™ä¸¤ä¸ªå‡½æ•°çš„
+行为。如果æä¾›äº†DT,那么.init_early()å’Œ.init_irq()都能调用任何一个DT查
+询函数(of_* in include/linux/of*.h),以获得关于平å°çš„é¢å¤–æ•°æ®ã€‚
+
+DTä¸Šä¸‹æ–‡ä¸­æœ€æœ‰è¶£çš„é’©å­æ˜¯.init_machine(),它主è¦è´Ÿè´£å°†å¹³å°çš„æ•°æ®å¡«å……到
+Linux设备模型中。历å²ä¸Šï¼Œè¿™åœ¨åµŒå…¥å¼å¹³å°ä¸Šæ˜¯é€šè¿‡åœ¨æ¿å¡support .c文件中定
+ä¹‰ä¸€ç»„é™æ€æ—¶é’Ÿç»“æž„ã€platform_devices和其他数æ®ï¼Œå¹¶åœ¨.init_machine()中
+大釿³¨å†Œæ¥å®žçŽ°çš„ã€‚å½“ä½¿ç”¨DT时,就ä¸ç”¨ä¸ºæ¯ä¸ªå¹³å°çš„陿€è®¾å¤‡è¿›è¡Œç¡¬ç¼–ç ï¼Œå¯ä»¥é€šè¿‡
+è§£æžDT获得设备列表,并动æ€åˆ†é…设备结构体。
+
+最简å•的情况是,.init_machine()åªè´Ÿè´£æ³¨å†Œä¸€ä¸ªplatform_devices。
+platform_device是Linux使用的一个概念,用于ä¸èƒ½è¢«ç¡¬ä»¶æ£€æµ‹åˆ°çš„内存或I/O映
+射的设备,以åŠâ€œå¤åˆâ€æˆ– “虚拟â€è®¾å¤‡ï¼ˆåŽé¢ä¼šè¯¦ç»†ä»‹ç»ï¼‰ã€‚虽然DT没有“平å°è®¾å¤‡â€çš„
+术语,但平å°è®¾å¤‡å¤§è‡´å¯¹åº”于树根的设备节点和简å•内存映射总线节点的å­èŠ‚ç‚¹ã€‚
+
+çŽ°åœ¨æ˜¯ä¸¾ä¾‹è¯´æ˜Žçš„å¥½æ—¶æœºã€‚ä¸‹é¢æ˜¯NVIDIA Tegraæ¿çš„设备树的一部分::
+
+ /{
+ compatible = "nvidia,harmony", "nvidia,tegra20";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ interrupt-parent = <&intc>;
+
+ chosen { };
+ aliases { };
+
+ memory {
+ device_type = "memory";
+ reg = <0x00000000 0x40000000>;
+ };
+
+ soc {
+ compatible = "nvidia,tegra20-soc", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ intc: interrupt-controller@50041000 {
+ compatible = "nvidia,tegra20-gic";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ reg = <0x50041000 0x1000>, < 0x50040100 0x0100 >;
+ };
+
+ serial@70006300 {
+ compatible = "nvidia,tegra20-uart";
+ reg = <0x70006300 0x100>;
+ interrupts = <122>;
+ };
+
+ i2s1: i2s@70002800 {
+ compatible = "nvidia,tegra20-i2s";
+ reg = <0x70002800 0x100>;
+ interrupts = <77>;
+ codec = <&wm8903>;
+ };
+
+ i2c@7000c000 {
+ compatible = "nvidia,tegra20-i2c";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x7000c000 0x100>;
+ interrupts = <70>;
+
+ wm8903: codec@1a {
+ compatible = "wlf,wm8903";
+ reg = <0x1a>;
+ interrupts = <347>;
+ };
+ };
+ };
+
+ sound {
+ compatible = "nvidia,harmony-sound";
+ i2s-controller = <&i2s1>;
+ i2s-codec = <&wm8903>;
+ };
+ };
+
+在.init_machine()时,Tegraæ¿æ”¯æŒä»£ç å°†éœ€è¦æŸ¥çœ‹è¿™ä¸ªDT,并决定为哪些节点
+创建platform_devices。然而,看一下这个树,并ä¸èƒ½ç«‹å³çœ‹å‡ºæ¯ä¸ªèŠ‚ç‚¹ä»£è¡¨ä»€ä¹ˆ
+类型的设备,甚至ä¸èƒ½çœ‹å‡ºä¸€ä¸ªèŠ‚ç‚¹æ˜¯å¦ä»£è¡¨ä¸€ä¸ªè®¾å¤‡ã€‚/chosenã€/aliaseså’Œ
+/memory节点是信æ¯èŠ‚ç‚¹ï¼Œå¹¶ä¸æè¿°è®¾å¤‡ï¼ˆå°½ç®¡å¯ä»¥è¯´å†…å­˜å¯ä»¥è¢«è®¤ä¸ºæ˜¯ä¸€ä¸ªè®¾å¤‡ï¼‰ã€‚
+/soc节点的å­èŠ‚ç‚¹æ˜¯å†…å­˜æ˜ å°„çš„è®¾å¤‡ï¼Œä½†æ˜¯codec@1a是一个i2c设备,而sound节
+ç‚¹ä»£è¡¨çš„ä¸æ˜¯ä¸€ä¸ªè®¾å¤‡ï¼Œè€Œæ˜¯å…¶ä»–设备是如何连接在一起以创建音频å­ç³»ç»Ÿçš„。我知
+铿¯ä¸ªè®¾å¤‡æ˜¯ä»€ä¹ˆï¼Œå› ä¸ºæˆ‘熟悉电路æ¿çš„è®¾è®¡ï¼Œä½†æ˜¯å†…æ ¸æ€Žä¹ˆçŸ¥é“æ¯ä¸ªèŠ‚ç‚¹è¯¥æ€Žä¹ˆåšï¼Ÿ
+
+诀çªåœ¨äºŽï¼Œå†…核从树的根部开始,寻找具有“兼容â€å±žæ€§çš„节点。首先,一般认为任何
+具有“兼容â€å±žæ€§çš„节点都代表æŸç§è®¾å¤‡ï¼›å…¶æ¬¡ï¼Œå¯ä»¥è®¤ä¸ºæ ‘根的任何节点è¦ä¹ˆç›´æŽ¥è¿ž
+接到处ç†å™¨æ€»çº¿ä¸Šï¼Œè¦ä¹ˆæ˜¯æ— æ³•ç”¨å…¶ä»–æ–¹å¼æè¿°çš„æ‚项系统设备。对于这些节点中的
+æ¯ä¸€ä¸ªï¼ŒLinux都会分é…和注册一个platform_device,它åˆå¯èƒ½è¢«ç»‘定到一个
+platform_driver。
+
+为什么为这些节点使用platform_device是一个安全的å‡è®¾ï¼Ÿå—¯ï¼Œå°±Linux对设备
+的建模方å¼è€Œè¨€ï¼Œå‡ ä¹Žæ‰€æœ‰çš„æ€»çº¿ç±»åž‹éƒ½å‡å®šå…¶è®¾å¤‡æ˜¯æ€»çº¿æŽ§åˆ¶å™¨çš„å­©å­ã€‚例如,æ¯
+个i2c_client是i2c_master的一个å­èŠ‚ç‚¹ã€‚æ¯ä¸ªspi_device都是SPI总线的一
+个å­èŠ‚ç‚¹ã€‚ç±»ä¼¼çš„è¿˜æœ‰USBã€PCIã€MDIOç­‰ã€‚åŒæ ·çš„层次结构也出现在DT中,I2C设
+备节点åªä½œä¸ºI2C总线节点的å­èŠ‚ç‚¹å‡ºçŽ°ã€‚åŒç†ï¼ŒSPIã€MDIOã€USB等等。唯一ä¸éœ€
+è¦ç‰¹å®šç±»åž‹çš„父设备的设备是platform_devices(和amba_devices,但åŽé¢ä¼š
+详细介ç»ï¼‰ï¼Œå®ƒä»¬å°†æ„‰å¿«åœ°è¿è¡Œåœ¨Linux/sys/devices树的底部。因此,如果一个
+DT节点ä½äºŽæ ‘的根部,那么它真的å¯èƒ½æœ€å¥½æ³¨å†Œä¸ºplatform_device。
+
+Linuxæ¿æ”¯æŒä»£ç è°ƒç”¨of_platform_populate(NULL, NULL, NULL, NULL)æ¥
+å¯åŠ¨æ ‘æ ¹çš„è®¾å¤‡å‘çŽ°ã€‚å‚æ•°éƒ½æ˜¯NULL,因为当从树的根部开始时,ä¸éœ€è¦æä¾›ä¸€ä¸ªèµ·
+始节点(第一个NULL),一个父结构设备(最åŽä¸€ä¸ªNULL),而且我们没有使用匹é…
+表(尚未)。对于åªéœ€è¦æ³¨å†Œè®¾å¤‡çš„æ¿å­ï¼Œé™¤äº†of_platform_populate()的调用,
+.init_machine()å¯ä»¥å®Œå…¨ä¸ºç©ºã€‚
+
+在Tegra的例å­ä¸­ï¼Œè¿™è¯´æ˜Žäº†/socå’Œ/sound节点,但是SoC节点的å­èŠ‚ç‚¹å‘¢ï¼Ÿå®ƒä»¬
+ä¸åº”该也被注册为平å°è®¾å¤‡å—?对于Linux DT支æŒï¼Œä¸€èˆ¬çš„行为是å­è®¾å¤‡åœ¨é©±åЍ
+.probe()时被父设备驱动注册。因此,一个i2c总线设备驱动程åºå°†ä¸ºæ¯ä¸ªå­èŠ‚ç‚¹
+注册一个i2c_client,一个SPI总线驱动程åºå°†æ³¨å†Œå…¶spi_deviceå­èŠ‚ç‚¹ï¼Œå…¶ä»–
+总线类型也是如此。根æ®è¯¥æ¨¡åž‹ï¼Œå¯ä»¥ç¼–写一个与SoC节点绑定的驱动程åºï¼Œå¹¶ç®€å•
+地为其æ¯ä¸ªå­èŠ‚ç‚¹æ³¨å†Œplatform_device。æ¿å¡æ”¯æŒä»£ç å°†åˆ†é…和注册一个SoC设
+备,一个(ç†è®ºä¸Šçš„)SoC设备驱动程åºå¯ä»¥ç»‘定到SoC设备,并在其.probe()é’©
+中为/soc/interruptcontrollerã€/soc/serialã€/soc/i2så’Œ/soc/i2c注
+册platform_devices。很简å•,对å—?
+
+å®žé™…ä¸Šï¼Œäº‹å®žè¯æ˜Žï¼Œå°†ä¸€äº›platform_deviceçš„å­è®¾å¤‡æ³¨å†Œä¸ºæ›´å¤šçš„platform_device
+是一ç§å¸¸è§çš„æ¨¡å¼ï¼Œè®¾å¤‡æ ‘支æŒä»£ç åæ˜ äº†è¿™ä¸€ç‚¹ï¼Œå¹¶ä½¿ä¸Šè¿°ä¾‹å­æ›´ç®€å•。
+of_platform_populate()çš„ç¬¬äºŒä¸ªå‚æ•°æ˜¯ä¸€ä¸ªof_device_id表,任何与该表
+中的æ¡ç›®ç›¸åŒ¹é…的节点也将获得其å­èŠ‚ç‚¹çš„æ³¨å†Œã€‚åœ¨Tegra的例å­ä¸­ï¼Œä»£ç å¯ä»¥æ˜¯
+这样的::
+
+ static void __init harmony_init_machine(void)
+ {
+ /* ... */
+ of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
+ }
+
+“simple-busâ€åœ¨Devicetree规范中被定义为一个属性,æ„味ç€ä¸€ä¸ªç®€å•的内存映射
+的总线,所以of_platform_populate()代ç å¯ä»¥è¢«å†™æˆåªæ˜¯å‡è®¾ç®€å•总线兼容的节
+点将总是被éåŽ†ã€‚ç„¶è€Œï¼Œæˆ‘ä»¬æŠŠå®ƒä½œä¸ºä¸€ä¸ªå‚æ•°ä¼ å…¥ï¼Œä»¥ä¾¿ç”µè·¯æ¿æ”¯æŒä»£ç å¯ä»¥éšæ—¶è¦†
+盖默认行为。
+
+[éœ€è¦æ·»åŠ å…³äºŽæ·»åŠ i2c/spi/etcå­è®¾å¤‡çš„讨论] 。
+
+附录A:AMBA设备
+---------------
+
+ARM Primecell是连接到ARM AMBA总线的æŸç§è®¾å¤‡ï¼Œå®ƒåŒ…括对硬件检测和电æºç®¡ç†
+的一些支æŒã€‚在Linux中,amba_deviceå’Œamba_bus_type结构体被用æ¥è¡¨ç¤º
+Primecell设备。然而,棘手的一点是,AMBA总线上的所有设备并éžéƒ½æ˜¯Primecell,
+而且对于Linuxæ¥è¯´ï¼Œå…¸åž‹çš„æƒ…况是amba_deviceå’Œplatform_device实例都是åŒ
+一总线段的åŒä¹‰è¯ã€‚
+
+当使用DT时,这给of_platform_populate()带æ¥äº†é—®é¢˜ï¼Œå› ä¸ºå®ƒå¿…须决定是å¦å°†
+æ¯ä¸ªèŠ‚ç‚¹æ³¨å†Œä¸ºplatform_device或amba_device。ä¸å¹¸çš„æ˜¯ï¼Œè¿™ä½¿è®¾å¤‡åˆ›å»ºæ¨¡åž‹
+å˜å¾—æœ‰ç‚¹å¤æ‚,但解决方案原æ¥å¹¶ä¸æ˜¯å¤ªå…·æœ‰ä¾µç•¥æ€§ã€‚如果一个节点与“arm,amba-primecellâ€
+兼容,那么of_platform_populate()将把它注册为amba_deviceè€Œä¸æ˜¯
+platform_device。
diff --git a/Documentation/translations/zh_CN/index.rst b/Documentation/translations/zh_CN/index.rst
index 46e14ec9963d..88d8df957a78 100644
--- a/Documentation/translations/zh_CN/index.rst
+++ b/Documentation/translations/zh_CN/index.rst
@@ -5,7 +5,7 @@
\renewcommand\thesection*
\renewcommand\thesubsection*
\kerneldocCJKon
- \kerneldocBeginSC
+ \kerneldocBeginSC{
.. _linux_doc_zh:
@@ -56,10 +56,14 @@ TODOList:
下列文档æè¿°äº†å†…核需è¦çš„å¹³å°å›ºä»¶ç›¸å…³ä¿¡æ¯ã€‚
+.. toctree::
+ :maxdepth: 2
+
+ devicetree/index
+
TODOList:
* firmware-guide/index
-* devicetree/index
应用程åºå¼€å‘人员文档
--------------------
@@ -104,14 +108,17 @@ TODOList:
:maxdepth: 2
core-api/index
+ accounting/index
cpu-freq/index
iio/index
+ infiniband/index
+ power/index
+ virt/index
sound/index
filesystems/index
- virt/index
- infiniband/index
- accounting/index
scheduler/index
+ vm/index
+ peci/index
TODOList:
@@ -129,7 +136,6 @@ TODOList:
* netlabel/index
* networking/index
* pcmcia/index
-* power/index
* target/index
* timers/index
* spi/index
@@ -140,7 +146,6 @@ TODOList:
* gpu/index
* security/index
* crypto/index
-* vm/index
* bpf/index
* usb/index
* PCI/index
@@ -198,4 +203,4 @@ TODOList:
.. raw:: latex
- \kerneldocEndSC
+ }\kerneldocEndSC
diff --git a/Documentation/translations/zh_CN/peci/index.rst b/Documentation/translations/zh_CN/peci/index.rst
new file mode 100644
index 000000000000..4f6694c828fa
--- /dev/null
+++ b/Documentation/translations/zh_CN/peci/index.rst
@@ -0,0 +1,26 @@
+.. SPDX-License-Identifier: GPL-2.0-only
+.. include:: ../disclaimer-zh_CN.rst
+
+:Original: Documentation/peci/index.rst
+
+:翻译:
+
+ å¸å»¶è…¾ Yanteng Si <siyanteng@loongson.cn>
+
+:校译:
+
+=================
+Linux PECI å­ç³»ç»Ÿ
+=================
+
+.. toctree::
+
+
+ peci
+
+.. only:: subproject and html
+
+ Indices
+ =======
+
+ * :ref:`genindex`
diff --git a/Documentation/translations/zh_CN/peci/peci.rst b/Documentation/translations/zh_CN/peci/peci.rst
new file mode 100644
index 000000000000..a3b4f99b994c
--- /dev/null
+++ b/Documentation/translations/zh_CN/peci/peci.rst
@@ -0,0 +1,54 @@
+.. SPDX-License-Identifier: GPL-2.0-only
+.. include:: ../disclaimer-zh_CN.rst
+
+:Original: Documentation/peci/peci.rst
+
+:翻译:
+
+ å¸å»¶è…¾ Yanteng Si <siyanteng@loongson.cn>
+
+:校译:
+
+====
+概述
+====
+
+å¹³å°çŽ¯å¢ƒæŽ§åˆ¶æŽ¥å£ï¼ˆPECI)是英特尔处ç†å™¨å’Œç®¡ç†æŽ§åˆ¶å™¨ï¼ˆå¦‚底æ¿ç®¡ç†æŽ§åˆ¶å™¨ï¼ŒBMC)
+之间的一个通信接å£ã€‚PECIæä¾›çš„æœåŠ¡å…è®¸ç®¡ç†æŽ§åˆ¶å™¨é€šè¿‡è®¿é—®å„ç§å¯„存器æ¥é…ç½®ã€ç›‘
+控和调试平å°ã€‚它定义了一个专门的命令åè®®ï¼Œç®¡ç†æŽ§åˆ¶å™¨ä½œä¸ºPECIçš„å‘起者,处ç†å™¨
+作为PECIçš„å“应者。PECIå¯ä»¥ç”¨äºŽåŸºäºŽå•处ç†å™¨å’Œå¤šå¤„ç†å™¨çš„系统中。
+
+注æ„:英特尔PECI规范没有作为专门的文件å‘布,而是作为英特尔CPU的外部设计规范
+(EDS)的一部分。外部设计规范通常是ä¸å…¬å¼€çš„。
+
+PECI 线
+---------
+
+PECI线接å£ä½¿ç”¨å•线进行自é”和数æ®ä¼ è¾“。它ä¸éœ€è¦ä»»ä½•é¢å¤–的控制线--物ç†å±‚是一个
+自é”çš„å•线总线信å·ï¼Œæ¯ä¸€ä¸ªæ¯”特都从接近零ä¼çš„空闲状æ€å¼€å§‹é©±åЍã€ä¸Šå‡è¾¹ç¼˜ã€‚驱动高
+电平信å·çš„æŒç»­æ—¶é—´å¯ä»¥ç¡®å®šä½å€¼æ˜¯é€»è¾‘ “0†还是逻辑 “1â€ã€‚PECI线还包括与æ¯ä¸ªä¿¡
+æ¯å»ºç«‹çš„å¯å˜æ•°æ®é€ŸçŽ‡ã€‚
+
+对于PECI线,æ¯ä¸ªå¤„ç†å™¨åŒ…将在一个定义的范围内利用唯一的ã€å›ºå®šçš„地å€ï¼Œè¯¥åœ°å€åº”
+该与处ç†å™¨æ’座ID有固定的关系--如果其中一个处ç†å™¨è¢«ç§»é™¤ï¼Œå®ƒä¸ä¼šå½±å“其余处ç†å™¨
+的地å€ã€‚
+
+PECIå­ç³»ç»Ÿä»£ç å†…嵌文档
+------------------------
+
+该API在以下内核代ç ä¸­:
+
+include/linux/peci.h
+
+drivers/peci/internal.h
+
+drivers/peci/core.c
+
+drivers/peci/request.c
+
+PECI CPU 驱动 API
+-------------------
+
+该API在以下内核代ç ä¸­:
+
+drivers/peci/cpu.c
diff --git a/Documentation/translations/zh_CN/power/energy-model.rst b/Documentation/translations/zh_CN/power/energy-model.rst
new file mode 100644
index 000000000000..c7da1b6aefee
--- /dev/null
+++ b/Documentation/translations/zh_CN/power/energy-model.rst
@@ -0,0 +1,190 @@
+.. SPDX-License-Identifier: GPL-2.0
+.. include:: ../disclaimer-zh_CN.rst
+
+:Original: Documentation/power/energy-model.rst
+
+:翻译:
+
+ å”艺舟 Tang Yizhou <tangyeechou@gmail.com>
+
+============
+è®¾å¤‡èƒ½é‡æ¨¡åž‹
+============
+
+1. 概述
+-------
+
+èƒ½é‡æ¨¡åž‹ï¼ˆEM)框架是一ç§é©±åŠ¨ç¨‹åºä¸Žå†…æ ¸å­ç³»ç»Ÿä¹‹é—´çš„æŽ¥å£ã€‚其中驱动程åºäº†è§£ä¸åŒ
+性能层级的设备所消耗的功率,而内核å­ç³»ç»Ÿæ„¿æ„使用该信æ¯åšå‡ºèƒ½é‡æ„ŸçŸ¥å†³ç­–。
+
+è®¾å¤‡æ‰€æ¶ˆè€—çš„åŠŸçŽ‡çš„ä¿¡æ¯æ¥æºåœ¨ä¸åŒçš„å¹³å°ä¸Šå¯èƒ½æœ‰å¾ˆå¤§çš„ä¸åŒã€‚è¿™äº›åŠŸçŽ‡æˆæœ¬åœ¨æŸäº›
+情况下å¯ä»¥ä½¿ç”¨è®¾å¤‡æ ‘æ•°æ®æ¥ä¼°ç®—。在其它情况下,固件会更清楚。或者,用户空间å¯èƒ½
+是最清楚的。以此类推。为了é¿å…æ¯ä¸€ä¸ªå®¢æˆ·ç«¯å­ç³»ç»Ÿå¯¹æ¯ä¸€ç§å¯èƒ½çš„ä¿¡æ¯æºè‡ªå·±é‡æ–°
+实现支æŒï¼ŒEMæ¡†æž¶ä½œä¸ºä¸€ä¸ªæŠ½è±¡å±‚ä»‹å…¥ï¼Œå®ƒåœ¨å†…æ ¸ä¸­å¯¹åŠŸçŽ‡æˆæœ¬è¡¨çš„æ ¼å¼è¿›è¡Œæ ‡å‡†åŒ–,
+因此能够é¿å…多余的工作。
+
+功率值å¯ä»¥ç”¨æ¯«ç“¦æˆ–“抽象刻度â€è¡¨ç¤ºã€‚多个å­ç³»ç»Ÿå¯èƒ½ä½¿ç”¨EM,由系统集æˆå•†æ¥æ£€æŸ¥
+åŠŸçŽ‡å€¼åˆ»åº¦ç±»åž‹çš„è¦æ±‚æ˜¯å¦æ»¡è¶³ã€‚å¯ä»¥åœ¨èƒ½é‡æ„ŸçŸ¥è°ƒåº¦å™¨çš„æ–‡æ¡£ä¸­æ‰¾åˆ°ä¸€ä¸ªä¾‹å­
+Documentation/scheduler/sched-energy.rst。对于一些å­ç³»ç»Ÿï¼Œæ¯”如热能或
+powercapï¼Œç”¨â€œæŠ½è±¡åˆ»åº¦â€æè¿°åŠŸçŽ‡å€¼å¯èƒ½ä¼šå¯¼è‡´é—®é¢˜ã€‚这些å­ç³»ç»Ÿå¯¹è¿‡åŽ»ä½¿ç”¨çš„åŠŸçŽ‡çš„
+估算值更感兴趣,因此å¯èƒ½éœ€è¦çœŸå®žçš„æ¯«ç“¦ã€‚è¿™äº›è¦æ±‚的一个例å­å¯ä»¥åœ¨æ™ºèƒ½åŠŸçŽ‡åˆ†é…
+Documentation/driver-api/thermal/power_allocator.rst文档中找到。
+
+内核å­ç³»ç»Ÿå¯èƒ½ï¼ˆåŸºäºŽEM内部标志ä½ï¼‰å®žçŽ°äº†å¯¹EM注册设备是å¦å…·æœ‰ä¸ä¸€è‡´åˆ»åº¦çš„自动
+检查。è¦è®°ä½çš„é‡è¦äº‹æƒ…是,当功率值以“抽象刻度â€è¡¨ç¤ºæ—¶ï¼Œä»Žä¸­æŽ¨å¯¼ä»¥æ¯«ç„¦è€³ä¸ºå•ä½
+çš„çœŸå®žèƒ½é‡æ¶ˆè€—是ä¸å¯èƒ½çš„。
+
+下图æè¿°äº†ä¸€ä¸ªé©±åŠ¨çš„ä¾‹å­ï¼ˆè¿™é‡Œæ˜¯é’ˆå¯¹Arm的,但该方法适用于任何体系结构),它
+å‘EM框架æä¾›äº†åŠŸçŽ‡æˆæœ¬ï¼Œæ„Ÿå…´è¶£çš„客户端å¯ä»Žä¸­è¯»å–æ•°æ®::
+
+ +---------------+ +-----------------+ +---------------+
+ | Thermal (IPA) | | Scheduler (EAS) | | Other |
+ +---------------+ +-----------------+ +---------------+
+ | | em_cpu_energy() |
+ | | em_cpu_get() |
+ +---------+ | +---------+
+ | | |
+ v v v
+ +---------------------+
+ | Energy Model |
+ | Framework |
+ +---------------------+
+ ^ ^ ^
+ | | | em_dev_register_perf_domain()
+ +----------+ | +---------+
+ | | |
+ +---------------+ +---------------+ +--------------+
+ | cpufreq-dt | | arm_scmi | | Other |
+ +---------------+ +---------------+ +--------------+
+ ^ ^ ^
+ | | |
+ +--------------+ +---------------+ +--------------+
+ | Device Tree | | Firmware | | ? |
+ +--------------+ +---------------+ +--------------+
+
+对于CPU设备,EM框架管ç†ç€ç³»ç»Ÿä¸­æ¯ä¸ªâ€œæ€§èƒ½åŸŸâ€çš„åŠŸçŽ‡æˆæœ¬è¡¨ã€‚一个性能域是一组
+性能一起伸缩的CPU。性能域通常与CPUFreq策略具有1对1映射。一个性能域中的
+所有CPUè¦æ±‚具有相åŒçš„微架构。ä¸åŒæ€§èƒ½åŸŸä¸­çš„CPUå¯ä»¥æœ‰ä¸åŒçš„微架构。
+
+
+2. 核心API
+----------
+
+2.1 é…置选项
+^^^^^^^^^^^^
+
+必须使能CONFIG_ENERGY_MODELæ‰èƒ½ä½¿ç”¨EM框架。
+
+
+2.2 性能域的注册
+^^^^^^^^^^^^^^^^
+
+“高级â€EM的注册
+~~~~~~~~~~~~~~~~
+
+“高级â€EM因它å…许驱动æä¾›æ›´ç²¾ç¡®çš„功率模型而得å。它并ä¸å—é™äºŽæ¡†æž¶ä¸­çš„一些已
+实现的数学公å¼ï¼ˆå°±åƒâ€œç®€å•â€EM那样)。它å¯ä»¥æ›´å¥½åœ°å映æ¯ä¸ªæ€§èƒ½çжæ€çš„实际功率
+测é‡ã€‚因此,在EM陿€åŠŸçŽ‡ï¼ˆæ¼ç”µæµåŠŸçŽ‡ï¼‰æ˜¯é‡è¦çš„æƒ…å†µä¸‹ï¼Œåº”è¯¥é¦–é€‰è¿™ç§æ³¨å†Œæ–¹å¼ã€‚
+
+驱动程åºåº”通过以下API将性能域注册到EM框架中::
+
+ int em_dev_register_perf_domain(struct device *dev, unsigned int nr_states,
+ struct em_data_callback *cb, cpumask_t *cpus, bool milliwatts);
+
+驱动程åºå¿…é¡»æä¾›ä¸€ä¸ªå›žè°ƒå‡½æ•°ï¼Œä¸ºæ¯ä¸ªæ€§èƒ½çжæ€è¿”回<频率,功率>元组。驱动程åº
+æä¾›çš„回调函数å¯ä»¥è‡ªç”±åœ°ä»Žä»»ä½•相关ä½ç½®ï¼ˆDTã€å›ºä»¶......)以åŠä»¥ä»»ä½•被认为是
+å¿…è¦çš„æ–¹å¼èŽ·å–æ•°æ®ã€‚åªæœ‰å¯¹äºŽCPU设备,驱动程åºå¿…须使用cpumask指定性能域的CPU。
+对于CPU以外的其他设备,最åŽä¸€ä¸ªå‚数必须被设置为NULL。
+
+最åŽä¸€ä¸ªå‚数“milliwattsâ€ï¼ˆæ¯«ç“¦ï¼‰è®¾ç½®æˆæ­£ç¡®çš„值是很é‡è¦çš„,使用EM的内核
+å­ç³»ç»Ÿå¯èƒ½ä¼šä¾èµ–è¿™ä¸ªæ ‡å¿—æ¥æ£€æŸ¥æ‰€æœ‰çš„EM设备是å¦ä½¿ç”¨ç›¸åŒçš„刻度。如果有ä¸åŒçš„
+刻度,这些å­ç³»ç»Ÿå¯èƒ½å†³å®šï¼šè¿”回警告/é”™è¯¯ï¼Œåœæ­¢å·¥ä½œæˆ–崩溃(panic)。
+
+关于实现这个回调函数的驱动程åºçš„例å­ï¼Œå‚è§ç¬¬3节。或者在第2.4节阅读这个API
+的更多文档。
+
+
+“简å•â€EM的注册
+~~~~~~~~~~~~~~~~
+
+“简å•â€EM是用框架的辅助函数cpufreq_register_em_with_opp()注册的。它实现了
+一个和以下数学公å¼ç´§å¯†ç›¸å…³çš„功率模型::
+
+ Power = C * V^2 * f
+
+ä½¿ç”¨è¿™ç§æ–¹æ³•注册的EMå¯èƒ½æ— æ³•æ­£ç¡®åæ˜ çœŸå®žè®¾å¤‡çš„物ç†ç‰¹æ€§ï¼Œä¾‹å¦‚当陿€åŠŸçŽ‡
+(æ¼ç”µæµåŠŸçŽ‡ï¼‰å¾ˆé‡è¦æ—¶ã€‚
+
+
+2.3 访问性能域
+^^^^^^^^^^^^^^
+
+有两个API函数æä¾›å¯¹èƒ½é‡æ¨¡åž‹çš„访问。em_cpu_get()以CPU idä¸ºå‚æ•°ï¼Œem_pd_get()
+ä»¥è®¾å¤‡æŒ‡é’ˆä¸ºå‚æ•°ã€‚使用哪个接å£å–决于å­ç³»ç»Ÿï¼Œä½†å¯¹äºŽCPU设备æ¥è¯´ï¼Œè¿™ä¸¤ä¸ªå‡½æ•°éƒ½è¿”
+回相åŒçš„æ€§èƒ½åŸŸã€‚
+
+对CPUçš„èƒ½é‡æ¨¡åž‹æ„Ÿå…´è¶£çš„å­ç³»ç»Ÿå¯ä»¥é€šè¿‡em_cpu_get() API检索它。在创建性能域时
+分é…ä¸€æ¬¡èƒ½é‡æ¨¡åž‹è¡¨ï¼Œå®ƒä¿å­˜åœ¨å†…存中ä¸è¢«ä¿®æ”¹ã€‚
+
+一个性能域所消耗的能é‡å¯ä»¥ä½¿ç”¨em_cpu_energy() APIæ¥ä¼°ç®—。该估算å‡å®šCPU设备
+使用的CPUfreq监管器是schedutil。当å‰è¯¥è®¡ç®—ä¸èƒ½æä¾›ç»™å…¶å®ƒç±»åž‹çš„设备。
+
+关于上述API的更多细节å¯ä»¥åœ¨ ``<linux/energy_model.h>`` 或第2.4节中找到。
+
+
+2.4 API的细节æè¿°
+^^^^^^^^^^^^^^^^^
+å‚è§ include/linux/energy_model.h å’Œ kernel/power/energy_model.c çš„kernel doc。
+
+3. 驱动示例
+-----------
+
+CPUFreq框架支æŒä¸“用的回调函数,用于为指定的CPU(们)注册EM:
+cpufreq_driver::register_em()。这个回调必须为æ¯ä¸ªç‰¹å®šçš„é©±åŠ¨ç¨‹åºæ­£ç¡®å®žçŽ°ï¼Œ
+因为框架会在设置过程中适时地调用它。本节æä¾›äº†ä¸€ä¸ªç®€å•的例å­ï¼Œå±•示CPUFreq驱动
+åœ¨èƒ½é‡æ¨¡åž‹æ¡†æž¶ä¸­ä½¿ç”¨ï¼ˆå‡çš„)“fooâ€å议注册性能域。该驱动实现了一个est_power()
+函数æä¾›ç»™EM框架::
+
+ -> drivers/cpufreq/foo_cpufreq.c
+
+ 01 static int est_power(unsigned long *mW, unsigned long *KHz,
+ 02 struct device *dev)
+ 03 {
+ 04 long freq, power;
+ 05
+ 06 /* 使用“fooâ€åè®®è®¾ç½®é¢‘çŽ‡ä¸Šé™ */
+ 07 freq = foo_get_freq_ceil(dev, *KHz);
+ 08 if (freq < 0);
+ 09 return freq;
+ 10
+ 11 /* ä¼°ç®—ç›¸å…³é¢‘çŽ‡ä¸‹è®¾å¤‡çš„åŠŸçŽ‡æˆæœ¬ */
+ 12 power = foo_estimate_power(dev, freq);
+ 13 if (power < 0);
+ 14 return power;
+ 15
+ 16 /* 将这些值返回给EM框架 */
+ 17 *mW = power;
+ 18 *KHz = freq;
+ 19
+ 20 return 0;
+ 21 }
+ 22
+ 23 static void foo_cpufreq_register_em(struct cpufreq_policy *policy)
+ 24 {
+ 25 struct em_data_callback em_cb = EM_DATA_CB(est_power);
+ 26 struct device *cpu_dev;
+ 27 int nr_opp;
+ 28
+ 29 cpu_dev = get_cpu_device(cpumask_first(policy->cpus));
+ 30
+ 31 /* 查找该策略支æŒçš„OPPæ•°é‡ */
+ 32 nr_opp = foo_get_nr_opp(policy);
+ 33
+ 34 /* 并注册新的性能域 */
+ 35 em_dev_register_perf_domain(cpu_dev, nr_opp, &em_cb, policy->cpus,
+ 36 true);
+ 37 }
+ 38
+ 39 static struct cpufreq_driver foo_cpufreq_driver = {
+ 40 .register_em = foo_cpufreq_register_em,
+ 41 };
diff --git a/Documentation/translations/zh_CN/power/index.rst b/Documentation/translations/zh_CN/power/index.rst
new file mode 100644
index 000000000000..bc54983ba515
--- /dev/null
+++ b/Documentation/translations/zh_CN/power/index.rst
@@ -0,0 +1,56 @@
+.. SPDX-License-Identifier: GPL-2.0
+.. include:: ../disclaimer-zh_CN.rst
+
+:Original: Documentation/power/index.rst
+
+:翻译:
+
+ å”艺舟 Tang Yizhou <tangyeechou@gmail.com>
+
+========
+电æºç®¡ç†
+========
+
+.. toctree::
+ :maxdepth: 1
+
+ energy-model
+ opp
+
+TODOList:
+
+ * apm-acpi
+ * basic-pm-debugging
+ * charger-manager
+ * drivers-testing
+ * freezing-of-tasks
+ * pci
+ * pm_qos_interface
+ * power_supply_class
+ * runtime_pm
+ * s2ram
+ * suspend-and-cpuhotplug
+ * suspend-and-interrupts
+ * swsusp-and-swap-files
+ * swsusp-dmcrypt
+ * swsusp
+ * video
+ * tricks
+
+ * userland-swsusp
+
+ * powercap/powercap
+ * powercap/dtpm
+
+ * regulator/consumer
+ * regulator/design
+ * regulator/machine
+ * regulator/overview
+ * regulator/regulator
+
+.. only:: subproject and html
+
+ Indices
+ =======
+
+ * :ref:`genindex`
diff --git a/Documentation/translations/zh_CN/power/opp.rst b/Documentation/translations/zh_CN/power/opp.rst
new file mode 100644
index 000000000000..8d6e3f6f6202
--- /dev/null
+++ b/Documentation/translations/zh_CN/power/opp.rst
@@ -0,0 +1,341 @@
+.. SPDX-License-Identifier: GPL-2.0
+.. include:: ../disclaimer-zh_CN.rst
+
+:Original: Documentation/power/opp.rst
+
+:翻译:
+
+ å”艺舟 Tang Yizhou <tangyeechou@gmail.com>
+
+======================
+æ“作性能值(OPP)库
+======================
+
+(C) 2009-2010 Nishanth Menon <nm@ti.com>, 德州仪器公å¸
+
+.. 目录
+
+ 1. 简介
+ 2. OPP链表åˆå§‹æ³¨å†Œ
+ 3. OPPæœç´¢å‡½æ•°
+ 4. OPPå¯ç”¨æ€§æŽ§åˆ¶å‡½æ•°
+ 5. OPPæ•°æ®æ£€ç´¢å‡½æ•°
+ 6. æ•°æ®ç»“æž„
+
+1. 简介
+=======
+
+1.1 何为æ“作性能值(OPP)?
+------------------------------
+
+å½“ä»Šå¤æ‚çš„å•片系统(SoCï¼‰ç”±å¤šä¸ªå­æ¨¡å—组æˆï¼Œè¿™äº›å­æ¨¡å—会è”åˆå·¥ä½œã€‚在一个执行ä¸åŒç”¨ä¾‹
+çš„æ“ä½œç³»ç»Ÿä¸­ï¼Œå¹¶ä¸æ˜¯SoC中的所有模å—都需è¦ä¸€ç›´ä»¥æœ€é«˜é¢‘率工作。为了促æˆè¿™ä¸€ç‚¹ï¼ŒSoC中
+çš„å­æ¨¡å—被分组为ä¸åŒåŸŸï¼Œå…许一些域以较低的电压和频率è¿è¡Œï¼Œè€Œå…¶å®ƒåŸŸåˆ™ä»¥è¾ƒé«˜çš„“电压/
+频率对â€è¿è¡Œã€‚
+
+设备按域支æŒçš„由频率电压对组æˆçš„离散的元组的集åˆï¼Œè¢«ç§°ä¸ºæ“作性能值(组),或OPPs。
+
+举例æ¥è¯´ï¼š
+
+让我们考虑一个支æŒä¸‹è¿°é¢‘率ã€ç”µåŽ‹å€¼çš„å†…å­˜ä¿æŠ¤å•元(MPU)设备:
+{300MHz,最低电压为1V}, {800MHz,最低电压为1.2V}, {1GHz,最低电压为1.3V}
+
+我们能将它们表示为3个OPP,如下述{Hz, uV}元组(译注:频率的å•使˜¯èµ«å…¹ï¼Œç”µåŽ‹çš„å•使˜¯
+å¾®ä¼ï¼‰ã€‚
+
+- {300000000, 1000000}
+- {800000000, 1200000}
+- {1000000000, 1300000}
+
+1.2 æ“作性能值库
+----------------
+
+OPP库æä¾›äº†ä¸€ç»„辅助函数æ¥ç»„织和查询OPPä¿¡æ¯ã€‚该库ä½äºŽdrivers/opp/目录下,其头文件
+ä½äºŽinclude/linux/pm_opp.h中。OPP库å¯ä»¥é€šè¿‡å¼€å¯CONFIG_PM_OPPæ¥å¯ç”¨ã€‚æŸäº›SoC,
+如德州仪器的OMAP框架å…许在ä¸éœ€è¦cpufreq的情况下å¯é€‰åœ°åœ¨æŸä¸€OPP下å¯åŠ¨ã€‚
+
+OPP库的典型用法如下::
+
+ (用户) -> 注册一个默认的OPPé›†åˆ -> (库)
+ (SoC框架) -> 在必è¦çš„æƒ…况下,对æŸäº›OPP进行修改 -> OPP layer
+ -> æœç´¢/检索信æ¯çš„æŸ¥è¯¢ ->
+
+OPP层期望æ¯ä¸ªåŸŸç”±ä¸€ä¸ªå”¯ä¸€çš„设备指针æ¥è¡¨ç¤ºã€‚SoC框架在OPP层为æ¯ä¸ªè®¾å¤‡æ³¨å†Œäº†ä¸€ç»„åˆå§‹
+OPPã€‚è¿™ä¸ªé“¾è¡¨çš„é•¿åº¦è¢«æœŸæœ›æ˜¯ä¸€ä¸ªæœ€ä¼˜åŒ–çš„å°æ•°å­—,通常æ¯ä¸ªè®¾å¤‡å¤§çº¦5个。åˆå§‹é“¾è¡¨åŒ…å«äº†
+一个OPP集åˆï¼Œè¿™ä¸ªé›†åˆè¢«æœŸæœ›èƒ½åœ¨ç³»ç»Ÿä¸­å®‰å…¨ä½¿èƒ½ã€‚
+
+关于OPPå¯ç”¨æ€§çš„说明
+^^^^^^^^^^^^^^^^^^^
+
+éšç€ç³»ç»Ÿçš„è¿è¡Œï¼ŒSoC框架å¯èƒ½ä¼šåŸºäºŽå„ç§å¤–部因素选择让æŸäº›OPP在æ¯ä¸ªè®¾å¤‡ä¸Šå¯ç”¨æˆ–ä¸å¯ç”¨ï¼Œ
+ç¤ºä¾‹ï¼šæ¸©åº¦ç®¡ç†æˆ–其它异常场景中,SoC框架å¯èƒ½ä¼šé€‰æ‹©ç¦ç”¨ä¸€ä¸ªè¾ƒé«˜é¢‘率的OPP以安全地继续
+è¿è¡Œï¼Œç›´åˆ°è¯¥OPPè¢«é‡æ–°å¯ç”¨ï¼ˆå¦‚æžœå¯èƒ½ï¼‰ã€‚
+
+OPP库在它的实现中达æˆäº†è¿™ä¸ªæ¦‚念。以下æ“作函数åªèƒ½å¯¹å¯ç”¨çš„OPP使用:
+dev_pm_opp_find_freq_{ceil, floor}, dev_pm_opp_get_voltage,
+dev_pm_opp_get_freq, dev_pm_opp_get_opp_count。
+
+dev_pm_opp_find_freq_exactæ˜¯ç”¨æ¥æŸ¥æ‰¾OPP指针的,该指针å¯è¢«ç”¨åœ¨dev_pm_opp_enable/
+disable函数,使一个OPPåœ¨è¢«éœ€è¦æ—¶å˜ä¸ºå¯ç”¨ã€‚
+
+警告:如果对一个设备调用dev_pm_opp_enable/disable函数,OPP库的用户应该使用
+dev_pm_opp_get_opp_countæ¥åˆ·æ–°OPPçš„å¯ç”¨æ€§è®¡æ•°ã€‚触å‘这些的具体机制,或者对有ä¾èµ–çš„
+å­ç³»ç»Ÿï¼ˆæ¯”如cpufreq)的通知机制,都是由使用OPP库的SoC特定框架酌情处ç†çš„。在这些æ“作
+ä¸­ï¼ŒåŒæ ·éœ€è¦æ³¨æ„刷新cpufreq表。
+
+2. OPP链表åˆå§‹æ³¨å†Œ
+==================
+SoC的实现会迭代调用dev_pm_opp_add函数æ¥å¢žåŠ æ¯ä¸ªè®¾å¤‡çš„OPP。预期SoC框架将以最优的
+æ–¹å¼æ³¨å†ŒOPPæ¡ç›® - 典型的数字范围å°äºŽ5。通过注册OPP生æˆçš„OPP链表,在整个设备è¿è¡Œè¿‡ç¨‹
+中由OPP库维护。SoC框架éšåŽå¯ä»¥ä½¿ç”¨dev_pm_opp_enable / disable函数动æ€åœ°
+控制OPPçš„å¯ç”¨æ€§ã€‚
+
+dev_pm_opp_add
+ 为设备指针所指å‘的特定域添加一个新的OPP。OPP是用频率和电压定义的。一旦完æˆ
+ 添加,OPP被认为是å¯ç”¨çš„,å¯ä»¥ç”¨dev_pm_opp_enable/disableå‡½æ•°æ¥æŽ§åˆ¶å…¶å¯ç”¨æ€§ã€‚
+ OPP库内部用dev_pm_opp结构体存储并管ç†è¿™äº›ä¿¡æ¯ã€‚这个函数å¯ä»¥è¢«SoC框架根æ®SoC
+ 的使用环境的需求æ¥å®šä¹‰ä¸€ä¸ªæœ€ä¼˜é“¾è¡¨ã€‚
+
+ 警告:
+ ä¸è¦åœ¨ä¸­æ–­ä¸Šä¸‹æ–‡ä½¿ç”¨è¿™ä¸ªå‡½æ•°ã€‚
+
+ 示例::
+
+ soc_pm_init()
+ {
+ /* åšä¸€äº›äº‹æƒ… */
+ r = dev_pm_opp_add(mpu_dev, 1000000, 900000);
+ if (!r) {
+ pr_err("%s: unable to register mpu opp(%d)\n", r);
+ goto no_cpufreq;
+ }
+ /* åšä¸€äº›å’Œcpufreq相关的事情 */
+ no_cpufreq:
+ /* åšå‰©ä½™çš„事情 */
+ }
+
+3. OPPæœç´¢å‡½æ•°
+==============
+cpufreq等高层框架对频率进行æ“作,为了将频率映射到相应的OPP,OPP库æä¾›äº†ä¾¿åˆ©çš„函数
+æ¥æœç´¢OPP库内部管ç†çš„OPP链表。这些æœç´¢å‡½æ•°å¦‚果找到匹é…çš„OPP,将返回指å‘该OPP的指针,
+å¦åˆ™è¿”回错误。这些错误预计由标准的错误检查,如IS_ERR()æ¥å¤„ç†ï¼Œå¹¶ç”±è°ƒç”¨è€…采å–适当的
+行动。
+
+这些函数的调用者应在使用完OPPåŽè°ƒç”¨dev_pm_opp_put()。å¦åˆ™ï¼ŒOPP的内存将永远ä¸ä¼š
+被释放,并导致内存泄露。
+
+dev_pm_opp_find_freq_exact
+ æ ¹æ® *精确的* 频率和å¯ç”¨æ€§æ¥æœç´¢OPP。这个函数对默认ä¸å¯ç”¨çš„OPP特别有用。
+ 例å­ï¼šåœ¨SoC框架检测到更高频率å¯ç”¨çš„æƒ…况下,它å¯ä»¥ä½¿ç”¨è¿™ä¸ªå‡½æ•°åœ¨è°ƒç”¨
+ dev_pm_opp_enable之剿‰¾åˆ°OPP::
+
+ opp = dev_pm_opp_find_freq_exact(dev, 1000000000, false);
+ dev_pm_opp_put(opp);
+ /* ä¸è¦æ“作指针.. åªæ˜¯åšæœ‰æ•ˆæ€§æ£€æŸ¥.. */
+ if (IS_ERR(opp)) {
+ pr_err("frequency not disabled!\n");
+ /* 触å‘åˆé€‚çš„æ“作.. */
+ } else {
+ dev_pm_opp_enable(dev,1000000000);
+ }
+
+ 注æ„:
+ 这是唯一一个å¯ä»¥æœç´¢ä¸å¯ç”¨OPP的函数。
+
+dev_pm_opp_find_freq_floor
+ æœç´¢ä¸€ä¸ª *最多* æä¾›æŒ‡å®šé¢‘率的å¯ç”¨OPP。这个函数在æœç´¢è¾ƒå°çš„åŒ¹é…æˆ–按频率
+ 递å‡çš„é¡ºåºæ“作OPPä¿¡æ¯æ—¶å¾ˆæœ‰ç”¨ã€‚
+ 例å­ï¼šè¦æ‰¾çš„一个设备的最高OPP::
+
+ freq = ULONG_MAX;
+ opp = dev_pm_opp_find_freq_floor(dev, &freq);
+ dev_pm_opp_put(opp);
+
+dev_pm_opp_find_freq_ceil
+ æœç´¢ä¸€ä¸ª *最少* æä¾›æŒ‡å®šé¢‘率的å¯ç”¨OPP。这个函数在æœç´¢è¾ƒå¤§çš„åŒ¹é…æˆ–按频率
+ é€’å¢žçš„é¡ºåºæ“作OPPä¿¡æ¯æ—¶å¾ˆæœ‰ç”¨ã€‚
+ 例1:找到一个设备最å°çš„OPP::
+
+ freq = 0;
+ opp = dev_pm_opp_find_freq_ceil(dev, &freq);
+ dev_pm_opp_put(opp);
+
+ 例: 一个SoC的cpufreq_driver->target的简易实现::
+
+ soc_cpufreq_target(..)
+ {
+ /* åšç­–略检查等æ“作 */
+ /* 找到和请求最接近的频率 */
+ opp = dev_pm_opp_find_freq_ceil(dev, &freq);
+ dev_pm_opp_put(opp);
+ if (!IS_ERR(opp))
+ soc_switch_to_freq_voltage(freq);
+ else
+ /* 当ä¸èƒ½æ»¡è¶³è¯·æ±‚时,è¦åšçš„事 */
+ /* åšå…¶å®ƒäº‹ */
+ }
+
+4. OPPå¯ç”¨æ€§æŽ§åˆ¶å‡½æ•°
+====================
+在OPP库中注册的默认OPP链表也许无法满足所有å¯èƒ½çš„场景。OPP库æä¾›äº†ä¸€å¥—函数æ¥ä¿®æ”¹
+OPP链表中的æŸä¸ªOPPçš„å¯ç”¨æ€§ã€‚这使得SoCæ¡†æž¶èƒ½å¤Ÿç²¾ç»†åœ°åŠ¨æ€æŽ§åˆ¶å“ªä¸€ç»„OPP是å¯ç”¨äºŽæ“作
+的。设计这些函数的目的是在诸如考虑温度时 *暂时地* 删除æŸä¸ªOPP(例如,在温度下é™
+之å‰ä¸è¦ä½¿ç”¨æŸOPP)。
+
+警告:
+ ä¸è¦åœ¨ä¸­æ–­ä¸Šä¸‹æ–‡ä½¿ç”¨è¿™äº›å‡½æ•°ã€‚
+
+dev_pm_opp_enable
+ 使一个OPPå¯ç”¨äºŽæ“作。
+ 例å­ï¼šå‡è®¾1GHzçš„OPPåªæœ‰åœ¨SoC温度低于æŸä¸ªé˜ˆå€¼æ—¶æ‰å¯ç”¨ã€‚SoC框架的实现å¯èƒ½
+ 会选择åšä»¥ä¸‹äº‹æƒ…::
+
+ if (cur_temp < temp_low_thresh) {
+ /* 若1GHz未使能,则使能 */
+ opp = dev_pm_opp_find_freq_exact(dev, 1000000000, false);
+ dev_pm_opp_put(opp);
+ /* 仅仅是错误检查 */
+ if (!IS_ERR(opp))
+ ret = dev_pm_opp_enable(dev, 1000000000);
+ else
+ goto try_something_else;
+ }
+
+dev_pm_opp_disable
+ 使一个OPPä¸å¯ç”¨äºŽæ“作。
+ 例å­ï¼šå‡è®¾1GHzçš„OPPåªæœ‰åœ¨SoC温度高于æŸä¸ªé˜ˆå€¼æ—¶æ‰å¯ç”¨ã€‚SoC框架的实现å¯èƒ½
+ 会选择åšä»¥ä¸‹äº‹æƒ…::
+
+ if (cur_temp > temp_high_thresh) {
+ /* 若1GHz已使能,则关闭 */
+ opp = dev_pm_opp_find_freq_exact(dev, 1000000000, true);
+ dev_pm_opp_put(opp);
+ /* 仅仅是错误检查 */
+ if (!IS_ERR(opp))
+ ret = dev_pm_opp_disable(dev, 1000000000);
+ else
+ goto try_something_else;
+ }
+
+5. OPPæ•°æ®æ£€ç´¢å‡½æ•°
+==================
+由于OPP库对OPPä¿¡æ¯è¿›è¡Œäº†æŠ½è±¡åŒ–处ç†ï¼Œå› æ­¤éœ€è¦ä¸€ç»„函数æ¥ä»Ždev_pm_opp结构体中æå–
+ä¿¡æ¯ã€‚一旦使用æœç´¢å‡½æ•°æ£€ç´¢åˆ°ä¸€ä¸ªOPP指针,以下函数就å¯ä»¥è¢«SoCæ¡†æž¶ç”¨æ¥æ£€ç´¢OPP层
+内部æè¿°çš„ä¿¡æ¯ã€‚
+
+dev_pm_opp_get_voltage
+ 检索OPP指针æè¿°çš„电压。
+ 例å­: 当cpufreq切æ¢åˆ°åˆ°ä¸åŒé¢‘率时,SoC框架需è¦ç”¨ç¨³åŽ‹å™¨æ¡†æž¶å°†OPPæè¿°
+ 的电压设置到æä¾›ç”µåŽ‹çš„ç”µæºç®¡ç†èŠ¯ç‰‡ä¸­::
+
+ soc_switch_to_freq_voltage(freq)
+ {
+ /* åšä¸€äº›äº‹æƒ… */
+ opp = dev_pm_opp_find_freq_ceil(dev, &freq);
+ v = dev_pm_opp_get_voltage(opp);
+ dev_pm_opp_put(opp);
+ if (v)
+ regulator_set_voltage(.., v);
+ /* åšå…¶å®ƒäº‹ */
+ }
+
+dev_pm_opp_get_freq
+ 检索OPP指针æè¿°çš„频率。
+ 例å­ï¼šæ¯”方说,SoC框架使用了几个辅助函数,通过这些函数,我们å¯ä»¥å°†OPP
+ æŒ‡é’ˆä¼ å…¥ï¼Œè€Œä¸æ˜¯ä¼ å…¥é¢å¤–çš„å‚æ•°ï¼Œç”¨æ¥å¤„ç†ä¸€ç³»åˆ—æ•°æ®å‚æ•°::
+
+ soc_cpufreq_target(..)
+ {
+ /* åšä¸€äº›äº‹æƒ….. */
+ max_freq = ULONG_MAX;
+ max_opp = dev_pm_opp_find_freq_floor(dev,&max_freq);
+ requested_opp = dev_pm_opp_find_freq_ceil(dev,&freq);
+ if (!IS_ERR(max_opp) && !IS_ERR(requested_opp))
+ r = soc_test_validity(max_opp, requested_opp);
+ dev_pm_opp_put(max_opp);
+ dev_pm_opp_put(requested_opp);
+ /* åšå…¶å®ƒäº‹ */
+ }
+ soc_test_validity(..)
+ {
+ if(dev_pm_opp_get_voltage(max_opp) < dev_pm_opp_get_voltage(requested_opp))
+ return -EINVAL;
+ if(dev_pm_opp_get_freq(max_opp) < dev_pm_opp_get_freq(requested_opp))
+ return -EINVAL;
+ /* åšä¸€äº›äº‹æƒ….. */
+ }
+
+dev_pm_opp_get_opp_count
+ 检索æŸä¸ªè®¾å¤‡å¯ç”¨çš„OPPæ•°é‡ã€‚
+ 例å­ï¼šå‡è®¾SoC中的一个å处ç†å™¨éœ€è¦çŸ¥é“æŸä¸ªè¡¨ä¸­çš„å¯ç”¨é¢‘率,主处ç†å™¨å¯ä»¥
+ 按如下方å¼å‘出通知::
+
+ soc_notify_coproc_available_frequencies()
+ {
+ /* åšä¸€äº›äº‹æƒ… */
+ num_available = dev_pm_opp_get_opp_count(dev);
+ speeds = kzalloc(sizeof(u32) * num_available, GFP_KERNEL);
+ /* 按å‡åºå¡«å……表 */
+ freq = 0;
+ while (!IS_ERR(opp = dev_pm_opp_find_freq_ceil(dev, &freq))) {
+ speeds[i] = freq;
+ freq++;
+ i++;
+ dev_pm_opp_put(opp);
+ }
+
+ soc_notify_coproc(AVAILABLE_FREQs, speeds, num_available);
+ /* åšå…¶å®ƒäº‹ */
+ }
+
+6. æ•°æ®ç»“æž„
+===========
+通常,一个SoC包å«å¤šä¸ªå¯å˜ç”µåŽ‹åŸŸã€‚æ¯ä¸ªåŸŸç”±ä¸€ä¸ªè®¾å¤‡æŒ‡é’ˆæè¿°ã€‚å’ŒOPP之间的关系å¯ä»¥
+æŒ‰ä»¥ä¸‹æ–¹å¼æè¿°::
+
+ SoC
+ |- device 1
+ | |- opp 1 (availability, freq, voltage)
+ | |- opp 2 ..
+ ... ...
+ | `- opp n ..
+ |- device 2
+ ...
+ `- device m
+
+OPP库维护ç€ä¸€ä¸ªå†…部链表,SoC框架使用上文æè¿°çš„å„个函数æ¥å¡«å……和访问。然而,æè¿°
+真实OPP和域的结构体是OPP库自身的内部组æˆï¼Œä»¥å…许åˆé€‚的抽象在ä¸åŒç³»ç»Ÿä¸­å¾—到å¤ç”¨ã€‚
+
+struct dev_pm_opp
+ OPP库的内部数æ®ç»“构,用于表示一个OPP。除了频率ã€ç”µåŽ‹ã€å¯ç”¨æ€§ä¿¡æ¯å¤–,
+ 它还包å«OPP库è¿è¡Œæ‰€éœ€çš„内部统计信æ¯ã€‚指å‘这个结构体的指针被æä¾›ç»™
+ 用户(比如SoC框架)使用,在与OPP层的交互中作为OPP的标识符。
+
+ 警告:
+ 结构体dev_pm_opp的指针ä¸åº”è¯¥ç”±ç”¨æˆ·è§£æžæˆ–修改。一个实例的默认值由
+ dev_pm_opp_add填充,但OPPçš„å¯ç”¨æ€§ç”±dev_pm_opp_enable/disable函数
+ 修改。
+
+struct device
+ 这用于å‘OPP层标识一个域。设备的性质和它的实现是由OPP库的用户决定的,
+ 如SoC框架。
+
+总体æ¥è¯´ï¼Œä»¥ä¸€ä¸ªç®€åŒ–的视角看,对数æ®ç»“构的æ“作å¯ä»¥æè¿°ä¸ºä¸‹é¢å„图::
+
+ åˆå§‹åŒ– / 修改:
+ +-----+ /- dev_pm_opp_enable
+ dev_pm_opp_add --> | opp | <-------
+ | +-----+ \- dev_pm_opp_disable
+ \-------> domain_info(device)
+
+ æœç´¢å‡½æ•°:
+ /-- dev_pm_opp_find_freq_ceil ---\ +-----+
+ domain_info<---- dev_pm_opp_find_freq_exact -----> | opp |
+ \-- dev_pm_opp_find_freq_floor ---/ +-----+
+
+ 检索函数:
+ +-----+ /- dev_pm_opp_get_voltage
+ | opp | <---
+ +-----+ \- dev_pm_opp_get_freq
+
+ domain_info <- dev_pm_opp_get_opp_count
diff --git a/Documentation/translations/zh_CN/riscv/index.rst b/Documentation/translations/zh_CN/riscv/index.rst
index bbf5d7b3777a..614cde0c0997 100644
--- a/Documentation/translations/zh_CN/riscv/index.rst
+++ b/Documentation/translations/zh_CN/riscv/index.rst
@@ -18,6 +18,7 @@ RISC-V 体系结构
:maxdepth: 1
boot-image-header
+ vm-layout
pmu
patch-acceptance
diff --git a/Documentation/translations/zh_CN/riscv/vm-layout.rst b/Documentation/translations/zh_CN/riscv/vm-layout.rst
new file mode 100644
index 000000000000..585cb89317a3
--- /dev/null
+++ b/Documentation/translations/zh_CN/riscv/vm-layout.rst
@@ -0,0 +1,67 @@
+.. SPDX-License-Identifier: GPL-2.0
+.. include:: ../disclaimer-zh_CN.rst
+
+:Original: Documentation/riscv/vm-layout.rst
+
+:翻译:
+
+ å¸å»¶è…¾ Yanteng Si <siyanteng@loongson.cn>
+
+============================
+RISC-V Linux上的虚拟内存布局
+============================
+
+:作者: Alexandre Ghiti <alex@ghiti.fr>
+:日期: 12 February 2021
+
+这份文件æè¿°äº†RISC-V Linux内核使用的虚拟内存布局。
+
+32ä½ RISC-V Linux 内核
+======================
+
+RISC-V Linux Kernel SV32
+------------------------
+
+TODO
+
+64ä½ RISC-V Linux 内核
+======================
+
+RISC-Vç‰¹æƒæž¶æž„文档指出,64ä½åœ°å€ "必须使第63-48ä½å€¼éƒ½ç­‰äºŽç¬¬47ä½ï¼Œå¦åˆ™å°†å‘生缺页异常。":这将虚
+拟地å€ç©ºé—´åˆ†æˆä¸¤åŠï¼Œä¸­é—´æœ‰ä¸€ä¸ªéžå¸¸å¤§çš„æ´žï¼Œä¸‹åŠéƒ¨åˆ†æ˜¯ç”¨æˆ·ç©ºé—´æ‰€åœ¨çš„地方,上åŠéƒ¨åˆ†æ˜¯RISC-V Linux
+内核所在的地方。
+
+RISC-V Linux Kernel SV39
+------------------------
+
+::
+
+ ========================================================================================================================
+ å¼€å§‹åœ°å€ | åç§» | 结æŸåœ°å€ | å¤§å° | 虚拟内存区域æè¿°
+ ========================================================================================================================
+ | | | |
+ 0000000000000000 | 0 | 0000003fffffffff | 256 GB | 用户空间虚拟内存,æ¯ä¸ªå†…存管ç†å™¨ä¸åŒ
+ __________________|____________|__________________|_________|___________________________________________________________
+ | | | |
+ 0000004000000000 | +256 GB | ffffffbfffffffff | ~16M TB | ... 巨大的ã€å‡ ä¹Ž64ä½å®½çš„直到内核映射的-256GB地方
+ | | | | 开始å移的éžç»å…¸è™šæ‹Ÿå†…存地å€ç©ºæ´žã€‚
+ | | | |
+ __________________|____________|__________________|_________|___________________________________________________________
+ |
+ | 内核空间的虚拟内存,在所有进程之间共享:
+ ____________________________________________________________|___________________________________________________________
+ | | | |
+ ffffffc6fee00000 | -228 GB | ffffffc6feffffff | 2 MB | fixmap
+ ffffffc6ff000000 | -228 GB | ffffffc6ffffffff | 16 MB | PCI io
+ ffffffc700000000 | -228 GB | ffffffc7ffffffff | 4 GB | vmemmap
+ ffffffc800000000 | -224 GB | ffffffd7ffffffff | 64 GB | vmalloc/ioremap space
+ ffffffd800000000 | -160 GB | fffffff6ffffffff | 124 GB | 直接映射所有物ç†å†…å­˜
+ fffffff700000000 | -36 GB | fffffffeffffffff | 32 GB | kasan
+ __________________|____________|__________________|_________|____________________________________________________________
+ |
+ |
+ ____________________________________________________________|____________________________________________________________
+ | | | |
+ ffffffff00000000 | -4 GB | ffffffff7fffffff | 2 GB | modules, BPF
+ ffffffff80000000 | -2 GB | ffffffffffffffff | 2 GB | kernel
+ __________________|____________|__________________|_________|____________________________________________________________
diff --git a/Documentation/translations/zh_CN/scheduler/index.rst b/Documentation/translations/zh_CN/scheduler/index.rst
index f8f8f35d53c7..12bf3bd02ccf 100644
--- a/Documentation/translations/zh_CN/scheduler/index.rst
+++ b/Documentation/translations/zh_CN/scheduler/index.rst
@@ -5,6 +5,7 @@
:翻译:
å¸å»¶è…¾ Yanteng Si <siyanteng@loongson.cn>
+ å”艺舟 Tang Yizhou <tangyeechou@gmail.com>
:校译:
@@ -23,16 +24,14 @@ Linux调度器
sched-design-CFS
sched-domains
sched-capacity
-
+ sched-energy
+ sched-nice-design
+ sched-stats
TODOList:
- sched-bwc
sched-deadline
- sched-energy
- sched-nice-design
sched-rt-group
- sched-stats
text_files
diff --git a/Documentation/translations/zh_CN/scheduler/sched-energy.rst b/Documentation/translations/zh_CN/scheduler/sched-energy.rst
new file mode 100644
index 000000000000..fdbf6cfeea93
--- /dev/null
+++ b/Documentation/translations/zh_CN/scheduler/sched-energy.rst
@@ -0,0 +1,351 @@
+.. SPDX-License-Identifier: GPL-2.0
+.. include:: ../disclaimer-zh_CN.rst
+
+:Original: Documentation/scheduler/sched-energy.rst
+
+:翻译:
+
+ å”艺舟 Tang Yizhou <tangyeechou@gmail.com>
+
+============
+èƒ½é‡æ„ŸçŸ¥è°ƒåº¦
+============
+
+1. 简介
+-------
+
+èƒ½é‡æ„ŸçŸ¥è°ƒåº¦ï¼ˆEAS)使调度器有能力预测其决策对CPU所消耗的能é‡çš„å½±å“。EASä¾é 
+ä¸€ä¸ªèƒ½é‡æ¨¡åž‹ï¼ˆEM)æ¥ä¸ºæ¯ä¸ªä»»åŠ¡é€‰æ‹©ä¸€ä¸ªèŠ‚èƒ½çš„CPUï¼ŒåŒæ—¶æœ€å°åŒ–对åžå率的影å“。
+本文档致力于介ç»ä»‹ç»EAS是如何工作的,它背åŽçš„主è¦è®¾è®¡å†³ç­–是什么,以åŠä½¿å…¶è¿è¡Œ
+所需的æ¡ä»¶ç»†èŠ‚ã€‚
+
+在进一步阅读之å‰ï¼Œè¯·æ³¨æ„,在撰写本文时::
+
+ /!\ EAS䏿”¯æŒå¯¹ç§°CPUæ‹“æ‰‘çš„å¹³å° /!\
+
+EASåªåœ¨å¼‚æž„CPU拓扑结构(如Arm大尿 ¸ï¼Œbig.LITTLE)上è¿è¡Œã€‚å› ä¸ºåœ¨è¿™ç§æƒ…况下,
+通过调度æ¥èŠ‚çº¦èƒ½é‡çš„æ½œåŠ›æ˜¯æœ€å¤§çš„ã€‚
+
+EAS实际使用的EM䏿˜¯ç”±è°ƒåº¦å™¨ç»´æŠ¤çš„,而是一个专门的框架。关于这个框架的细节和
+它æä¾›çš„内容,请å‚考其文档(è§Documentation/power/energy-model.rst)。
+
+
+2. 背景和术语
+-------------
+
+从一开始就说清楚定义:
+ - èƒ½é‡ = [焦耳] (比如供电设备上的电池æä¾›çš„资æºï¼‰
+ - 功率 = 能é‡/æ—¶é—´ = [焦耳/ç§’] = [瓦特]
+
+ EAS的目标是最å°åŒ–èƒ½é‡æ¶ˆè€—ï¼ŒåŒæ—¶ä»èƒ½å°†å·¥ä½œå®Œæˆã€‚ä¹Ÿå°±æ˜¯è¯´ï¼Œæˆ‘ä»¬è¦æœ€å¤§åŒ–::
+
+ 性能 [指令数/秒]
+ ----------------
+ 功率 [瓦特]
+
+它等效于最å°åŒ–::
+
+ èƒ½é‡ [焦耳]
+ -----------
+ 指令数
+
+åŒæ—¶ä»ç„¶èŽ·å¾—â€œè‰¯å¥½â€çš„æ€§èƒ½ã€‚当å‰è°ƒåº¦å™¨åªè€ƒè™‘性能目标,因此该å¼å­æœ¬è´¨ä¸Šæ˜¯ä¸€ä¸ª
+å¯é€‰çš„ä¼˜åŒ–ç›®æ ‡ï¼Œå®ƒåŒæ—¶è€ƒè™‘äº†ä¸¤ä¸ªç›®æ ‡ï¼šèƒ½é‡æ•ˆçŽ‡å’Œæ€§èƒ½ã€‚
+
+引入EM的想法是为了让调度器评估其决策的影å“ï¼Œè€Œä¸æ˜¯ç›²ç›®åœ°åº”用å¯èƒ½ä»…在部分
+平尿œ‰æ­£é¢æ•ˆæžœçš„èŠ‚èƒ½æŠ€æœ¯ã€‚åŒæ—¶ï¼ŒEM必须尽å¯èƒ½çš„简å•,以最å°åŒ–调度器的时延
+å½±å“。
+
+简而言之,EAS改å˜äº†CFS任务分é…ç»™CPU的方å¼ã€‚当调度器决定一个任务应该在哪里
+è¿è¡Œæ—¶ï¼ˆåœ¨å”¤é†’期间),EM被用æ¥åœ¨ä¸æŸå®³ç³»ç»Ÿåžå率的情况下,从几个较好的候选
+CPU中挑选一个ç»é¢„æµ‹èƒ½é‡æ¶ˆè€—最优的CPU。EAS的预测ä¾èµ–äºŽå¯¹å¹³å°æ‹“扑结构特定元素
+的了解,包括CPU的“算力â€ï¼Œä»¥åŠå®ƒä»¬å„è‡ªçš„èƒ½é‡æˆæœ¬ã€‚
+
+
+3. 拓扑信æ¯
+-----------
+
+EAS(以åŠè°ƒåº¦å™¨çš„剩余部分)使用“算力â€çš„æ¦‚念æ¥åŒºåˆ†ä¸åŒè®¡ç®—åžå率的CPU。一个
+CPU的“算力â€ä»£è¡¨äº†å®ƒåœ¨æœ€é«˜é¢‘率下è¿è¡Œæ—¶èƒ½å®Œæˆçš„工作é‡ï¼Œä¸”这个值是相对系统中
+算力最大的CPU而言的。算力值被归一化为1024以内,并且å¯ä¸Žç”±å®žä½“负载跟踪
+(PELT)机制算出的利用率信å·åšå¯¹æ¯”。由于有算力值和利用率值,EAS能够估计一个
+任务/CPU有多大/æœ‰å¤šå¿™ï¼Œå¹¶åœ¨è¯„ä¼°æ€§èƒ½ä¸Žèƒ½é‡æ—¶å°†å…¶è€ƒè™‘在内。CPU算力由特定体系
+结构实现的arch_scale_cpu_capacity()回调函数æä¾›ã€‚
+
+EAS使用的其余平å°ä¿¡æ¯æ˜¯ç›´æŽ¥ä»Žèƒ½é‡æ¨¡åž‹ï¼ˆEM)框架中读å–的。一个平å°çš„EM是一张
+表,表中æ¯é¡¹ä»£è¡¨ç³»ç»Ÿä¸­ä¸€ä¸ªâ€œæ€§èƒ½åŸŸâ€çš„åŠŸçŽ‡æˆæœ¬ã€‚(若è¦äº†è§£æ›´å¤šå…³äºŽæ€§èƒ½åŸŸçš„细节,
+è§Documentation/power/energy-model.rst)
+
+å½“è°ƒåº¦åŸŸè¢«å»ºç«‹æˆ–é‡æ–°å»ºç«‹æ—¶ï¼Œè°ƒåº¦å™¨ç®¡ç†å¯¹æ‹“扑代ç ä¸­EM对象的引用。对于æ¯ä¸ªæ ¹åŸŸ
+(rd),调度器维护一个与当å‰rd->span相交的所有性能域的å•å‘链表。链表中的æ¯ä¸ª
+节点都包å«ä¸€ä¸ªæŒ‡å‘EM框架所æä¾›çš„结构体em_perf_domain的指针。
+
+链表被附加在根域上,以应对独å çš„cpusetçš„é…置。由于独å çš„cpuset的边界ä¸ä¸€å®šä¸Ž
+性能域的边界一致,ä¸åŒæ ¹åŸŸçš„链表å¯èƒ½åŒ…å«é‡å¤çš„元素。
+
+示例1
+ 让我们考虑一个有12个CPU的平å°ï¼Œåˆ†æˆ3个性能域,(pd0,pd4å’Œpd8),按以下
+ æ–¹å¼ç»„织::
+
+ CPUs: 0 1 2 3 4 5 6 7 8 9 10 11
+ PDs: |--pd0--|--pd4--|---pd8---|
+ RDs: |----rd1----|-----rd2-----|
+
+ 现在,考虑用户空间决定将系统分æˆä¸¤ä¸ªç‹¬å çš„cpusets,因此创建了两个独立的根域,
+ æ¯ä¸ªæ ¹åŸŸåŒ…å«6个CPU。这两个根域在上图中被表示为rd1å’Œrd2。由于pd4与rd1å’Œrd2
+ éƒ½æœ‰äº¤é›†ï¼Œå®ƒå°†åŒæ—¶å‡ºçŽ°äºŽé™„åŠ åœ¨è¿™ä¸¤ä¸ªæ ¹åŸŸçš„â€œ->pdâ€é“¾è¡¨ä¸­:
+
+ * rd1->pd: pd0 -> pd4
+ * rd2->pd: pd4 -> pd8
+
+ 请注æ„,调度器将为pd4创建两个é‡å¤çš„链表节点(æ¯ä¸ªé“¾è¡¨ä¸­å„一个)。然而这
+ ä¸¤ä¸ªèŠ‚ç‚¹æŒæœ‰æŒ‡å‘åŒä¸€ä¸ªEM框架的共享数æ®ç»“构的指针。
+
+由于对这些链表的访问å¯èƒ½ä¸Žçƒ­æ’æ‹”åŠå…¶å®ƒäº‹ä»¶å¹¶å‘å‘生,因此它们å—RCUé”ä¿æŠ¤ï¼Œå°±åƒ
+è¢«è°ƒåº¦å™¨æ“æŽ§çš„æ‹“æ‰‘ç»“æž„ä½“ä¸­å‰©ä¸‹å­—æ®µä¸€æ ·ã€‚
+
+EASåŒæ ·ç»´æŠ¤äº†ä¸€ä¸ªé™æ€é”®ï¼ˆsched_energy_present),当至少有一个根域满足EAS
+å¯åŠ¨çš„æ‰€æœ‰æ¡ä»¶æ—¶ï¼Œè¿™ä¸ªé”®å°±ä¼šè¢«å¯åŠ¨ã€‚åœ¨ç¬¬6节中总结了这些æ¡ä»¶ã€‚
+
+
+4. èƒ½é‡æ„ŸçŸ¥ä»»åŠ¡æ”¾ç½®
+-------------------
+
+EAS覆盖了CFS的任务唤醒平衡代ç ã€‚在唤醒平衡时,它使用平å°çš„EMå’ŒPELTä¿¡å·æ¥é€‰æ‹©èŠ‚èƒ½
+的目标CPU。当EAS被å¯ç”¨æ—¶ï¼Œselect_task_rq_fair()调用find_energy_efficient_cpu()
+æ¥åšä»»åŠ¡æ”¾ç½®å†³å®šã€‚è¿™ä¸ªå‡½æ•°å¯»æ‰¾åœ¨æ¯ä¸ªæ€§èƒ½åŸŸä¸­å¯»æ‰¾å…·æœ‰æœ€é«˜å‰©ä½™ç®—力(CPU算力 - CPU
+利用率)的CPUï¼Œå› ä¸ºå®ƒèƒ½è®©æˆ‘ä»¬ä¿æŒæœ€ä½Žçš„频率。然åŽï¼Œè¯¥å‡½æ•°æ£€æŸ¥å°†ä»»åŠ¡æ”¾åœ¨æ–°CPU相较
+ä¾ç„¶æ”¾åœ¨ä¹‹å‰æ´»åŠ¨çš„prev_cpu是å¦å¯ä»¥èŠ‚çœèƒ½é‡ã€‚
+
+如果唤醒的任务被è¿ç§»ï¼Œfind_energy_efficient_cpu()使用compute_energy()æ¥ä¼°ç®—
+系统将消耗多少能é‡ã€‚compute_energy()检查å„CPU当å‰çš„利用率情况,并å°è¯•调整æ¥
+“模拟â€ä»»åŠ¡è¿ç§»ã€‚EM框架æä¾›äº†API em_pd_energy()计算æ¯ä¸ªæ€§èƒ½åŸŸåœ¨ç»™å®šçš„利用率æ¡ä»¶
+ä¸‹çš„é¢„æœŸèƒ½é‡æ¶ˆè€—。
+
+下é¢è¯¦ç»†ä»‹ç»ä¸€ä¸ªä¼˜åŒ–èƒ½é‡æ¶ˆè€—的任务放置决策的例å­ã€‚
+
+示例2
+ 让我们考虑一个有两个独立性能域的(伪)平å°ï¼Œæ¯ä¸ªæ€§èƒ½åŸŸå«æœ‰2个CPU。CPU0å’ŒCPU1
+ æ˜¯å°æ ¸ï¼ŒCPU2å’ŒCPU3是大核。
+
+ 调度器必须决定将任务P放在哪个CPU上,这个任务的util_avg = 200(平å‡åˆ©ç”¨çŽ‡ï¼‰ï¼Œ
+ prev_cpu = 0(上一次è¿è¡Œåœ¨CPU0)。
+
+ ç›®å‰CPU的利用率情况如下图所示。CPU 0-3çš„util_avg分别为400ã€100ã€600å’Œ500。
+ æ¯ä¸ªæ€§èƒ½åŸŸæœ‰ä¸‰ä¸ªæ“作性能值(OPP)。与æ¯ä¸ªOPP相关的CPUç®—åŠ›å’ŒåŠŸçŽ‡æˆæœ¬åˆ—在能é‡
+ 模型表中。P的util_avg在图中显示为"PP"::
+
+ CPU util.
+ 1024 - - - - - - - Energy Model
+ +-----------+-------------+
+ | Little | Big |
+ 768 ============= +-----+-----+------+------+
+ | Cap | Pwr | Cap | Pwr |
+ +-----+-----+------+------+
+ 512 =========== - ##- - - - - | 170 | 50 | 512 | 400 |
+ ## ## | 341 | 150 | 768 | 800 |
+ 341 -PP - - - - ## ## | 512 | 300 | 1024 | 1700 |
+ PP ## ## +-----+-----+------+------+
+ 170 -## - - - - ## ##
+ ## ## ## ##
+ ------------ -------------
+ CPU0 CPU1 CPU2 CPU3
+
+ Current OPP: ===== Other OPP: - - - util_avg (100 each): ##
+
+
+ find_energy_efficient_cpu()将首先在两个性能域中寻找具有最大剩余算力的CPU。
+ 在这个例å­ä¸­æ˜¯CPU1å’ŒCPU3。然åŽï¼Œå®ƒå°†ä¼°ç®—,当P被放在它们中的任æ„一个时,系统的
+ èƒ½è€—ï¼Œå¹¶æ£€æŸ¥è¿™æ ·åšæ˜¯å¦ä¼šæ¯”把P放在CPU0上节çœä¸€äº›èƒ½é‡ã€‚EASå‡å®šOPPséµå¾ªåˆ©ç”¨çއ
+ (这与CPUFreq监管器schedutil的行为一致。关于这个问题的更多细节,è§ç¬¬6节)。
+
+ **情况1. P被è¿ç§»åˆ°CPU1**::
+
+ 1024 - - - - - - -
+
+ Energy calculation:
+ 768 ============= * CPU0: 200 / 341 * 150 = 88
+ * CPU1: 300 / 341 * 150 = 131
+ * CPU2: 600 / 768 * 800 = 625
+ 512 - - - - - - - ##- - - - - * CPU3: 500 / 768 * 800 = 520
+ ## ## => total_energy = 1364
+ 341 =========== ## ##
+ PP ## ##
+ 170 -## - - PP- ## ##
+ ## ## ## ##
+ ------------ -------------
+ CPU0 CPU1 CPU2 CPU3
+
+
+ **情况2. P被è¿ç§»åˆ°CPU3**::
+
+ 1024 - - - - - - -
+
+ Energy calculation:
+ 768 ============= * CPU0: 200 / 341 * 150 = 88
+ * CPU1: 100 / 341 * 150 = 43
+ PP * CPU2: 600 / 768 * 800 = 625
+ 512 - - - - - - - ##- - -PP - * CPU3: 700 / 768 * 800 = 729
+ ## ## => total_energy = 1485
+ 341 =========== ## ##
+ ## ##
+ 170 -## - - - - ## ##
+ ## ## ## ##
+ ------------ -------------
+ CPU0 CPU1 CPU2 CPU3
+
+ **情况3. P便—§ç•™åœ¨prev_cpu/CPU0**::
+
+ 1024 - - - - - - -
+
+ Energy calculation:
+ 768 ============= * CPU0: 400 / 512 * 300 = 234
+ * CPU1: 100 / 512 * 300 = 58
+ * CPU2: 600 / 768 * 800 = 625
+ 512 =========== - ##- - - - - * CPU3: 500 / 768 * 800 = 520
+ ## ## => total_energy = 1437
+ 341 -PP - - - - ## ##
+ PP ## ##
+ 170 -## - - - - ## ##
+ ## ## ## ##
+ ------------ -------------
+ CPU0 CPU1 CPU2 CPU3
+
+ 从这些计算结果æ¥çœ‹ï¼Œæƒ…况1çš„æ€»èƒ½é‡æœ€ä½Žã€‚所以从节约能é‡çš„角度看,CPU1是最佳候选
+ 者。
+
+å¤§æ ¸é€šå¸¸æ¯”å°æ ¸æ›´è€—电,因此主è¦åœ¨ä»»åŠ¡ä¸é€‚åˆåœ¨å°æ ¸è¿è¡Œæ—¶ä½¿ç”¨ã€‚ç„¶è€Œï¼Œå°æ ¸å¹¶ä¸æ€»æ˜¯æ¯”
+大核节能。举例æ¥è¯´ï¼Œå¯¹äºŽæŸäº›ç³»ç»Ÿï¼Œå°æ ¸çš„高OPPå¯èƒ½æ¯”大核的低OPPèƒ½é‡æ¶ˆè€—更高。因此,
+å¦‚æžœå°æ ¸åœ¨æŸä¸€ç‰¹å®šæ—¶é—´ç‚¹åˆšå¥½æœ‰è¶³å¤Ÿçš„利用率,在此刻被唤醒的å°ä»»åŠ¡æ”¾åœ¨å¤§æ ¸æ‰§è¡Œå¯èƒ½
+ä¼šæ›´èŠ‚èƒ½ï¼Œå°½ç®¡å®ƒåœ¨å°æ ¸ä¸Šè¿è¡Œä¹Ÿæ˜¯åˆé€‚的。
+
+å³ä½¿åœ¨å¤§æ ¸æ‰€æœ‰OPP都ä¸å¦‚å°æ ¸OPP节能的情况下,在æŸäº›ç‰¹å®šæ¡ä»¶ä¸‹ï¼Œä»¤å°ä»»åŠ¡è¿è¡Œåœ¨å¤§æ ¸
+上ä¾ç„¶å¯èƒ½èŠ‚èƒ½ã€‚äº‹å®žä¸Šï¼Œå°†ä¸€ä¸ªä»»åŠ¡æ”¾åœ¨ä¸€ä¸ªå°æ ¸ä¸Šå¯èƒ½å¯¼è‡´æ•´ä¸ªæ€§èƒ½åŸŸçš„OPPæé«˜ï¼Œè¿™å°†
+增加已ç»åœ¨è¯¥æ€§èƒ½åŸŸè¿è¡Œçš„ä»»åŠ¡çš„èƒ½é‡æˆæœ¬ã€‚如果唤醒的任务被放在一个大核上,它的执行
+æˆæœ¬å¯èƒ½æ¯”æ”¾åœ¨å°æ ¸ä¸Šæ›´é«˜ï¼Œä½†è¿™ä¸ä¼šå½±å“å°æ ¸ä¸Šçš„其它任务,这些任务将继续以较低的OPP
+è¿è¡Œã€‚因此,当考虑CPUæ¶ˆè€—çš„æ€»èƒ½é‡æ—¶ï¼Œåœ¨å¤§æ ¸ä¸Šè¿è¡Œä¸€ä¸ªä»»åŠ¡çš„é¢å¤–æˆæœ¬å¯èƒ½å°äºŽä¸ºæ‰€æœ‰
+其它è¿è¡Œåœ¨å°æ ¸çš„任务æé«˜OPPçš„æˆæœ¬ã€‚
+
+上é¢çš„例å­å‡ ä¹Žä¸å¯èƒ½ä»¥ä¸€ç§é€šç”¨çš„æ–¹å¼å¾—åˆ°æ­£ç¡®çš„ç»“æžœï¼›åŒæ—¶ï¼Œå¯¹äºŽæ‰€æœ‰å¹³å°ï¼Œåœ¨ä¸çŸ¥é“
+系统所有CPUæ¯ä¸ªä¸åŒOPPçš„è¿è¡Œæˆæœ¬æ—¶ï¼Œä¹Ÿæ— æ³•得到正确的结果。得益于基于EM的设计,
+EAS应该能够正确处ç†è¿™äº›é—®é¢˜è€Œä¸ä¼šå¼•å‘太多麻烦。然而,为了确ä¿å¯¹é«˜åˆ©ç”¨çŽ‡åœºæ™¯çš„
+åžå率造æˆçš„影哿œ€å°åŒ–,EASåŒæ ·å®žçŽ°äº†å¦å¤–一ç§å«â€œè¿‡åº¦åˆ©ç”¨çއâ€çš„æœºåˆ¶ã€‚
+
+
+5. 过度利用率
+-------------
+
+从一般的角度æ¥çœ‹ï¼ŒEAS能æä¾›æœ€å¤§å¸®åŠ©çš„æ˜¯é‚£äº›æ¶‰åŠä½Žã€ä¸­CPU利用率的使用场景。æ¯å½“CPU
+密集型的长任务è¿è¡Œï¼Œå®ƒä»¬å°†éœ€è¦æ‰€æœ‰çš„å¯ç”¨CPU算力,调度器将没有什么办法æ¥èŠ‚çœèƒ½é‡åŒæ—¶
+åˆä¸æŸå®³åžå率。为了é¿å…EASæŸå®³æ€§èƒ½ï¼Œä¸€æ—¦CPU被使用的算力超过80%,它将被标记为“过度
+利用â€ã€‚åªè¦æ ¹åŸŸä¸­æ²¡æœ‰CPU是过度利用状æ€ï¼Œè´Ÿè½½å‡è¡¡è¢«ç¦ç”¨ï¼Œè€ŒEAS将覆盖唤醒平衡代ç ã€‚
+EAS很å¯èƒ½å°†è´Ÿè½½æ”¾ç½®åœ¨ç³»ç»Ÿä¸­èƒ½é‡æ•ˆçŽ‡æœ€é«˜çš„CPUè€Œä¸æ˜¯å…¶å®ƒCPU上,åªè¦ä¸æŸå®³åžå率。
+因此,负载å‡è¡¡å™¨è¢«ç¦ç”¨ä»¥é˜²æ­¢å®ƒæ‰“ç ´EASå‘çŽ°çš„èŠ‚èƒ½ä»»åŠ¡æ”¾ç½®ã€‚å½“ç³»ç»Ÿæœªå¤„äºŽè¿‡åº¦åˆ©ç”¨çŠ¶æ€æ—¶ï¼Œ
+è¿™æ ·åšæ˜¯å®‰å…¨çš„,因为低于80%的临界点æ„味ç€ï¼š
+
+ a. 所有的CPU都有一些空闲时间,所以EAS使用的利用率信å·å¾ˆå¯èƒ½å‡†ç¡®åœ°ä»£è¡¨å„ç§ä»»åŠ¡
+ 的“大å°â€ã€‚
+ b. 所有任务,ä¸ç®¡å®ƒä»¬çš„nice值是多大,都应该被æä¾›äº†è¶³å¤Ÿå¤šçš„CPU算力。
+ c. 既然有多余的算力,那么所有的任务都必须定期阻塞/休眠,在唤醒时进行平衡就足够
+ 了。
+
+åªè¦ä¸€ä¸ªCPU利用率超过80%的临界点,上述三个å‡è®¾ä¸­è‡³å°‘æœ‰ä¸€ä¸ªæ˜¯ä¸æ­£ç¡®çš„ã€‚åœ¨è¿™ç§æƒ…况下,
+æ•´ä¸ªæ ¹åŸŸçš„â€œè¿‡åº¦åˆ©ç”¨â€æ ‡å¿—被设置,EAS被ç¦ç”¨ï¼Œè´Ÿè½½å‡è¡¡å™¨è¢«é‡æ–°å¯ç”¨ã€‚通过这样åšï¼Œè°ƒåº¦å™¨
+åˆå›žåˆ°äº†åœ¨CPU密集的æ¡ä»¶ä¸‹åŸºäºŽè´Ÿè½½çš„算法åšè´Ÿè½½å‡è¡¡ã€‚这更好地尊é‡äº†ä»»åŠ¡çš„nice值。
+
+由于过度利用率的概念在很大程度上ä¾èµ–äºŽæ£€æµ‹ç³»ç»Ÿä¸­æ˜¯å¦æœ‰ä¸€äº›ç©ºé—²æ—¶é—´ï¼Œæ‰€ä»¥å¿…须考虑
+(比CFS)更高优先级的调度类(以åŠä¸­æ–­ï¼‰â€œçªƒå–â€çš„CPU算力。åƒè¿™æ ·ï¼Œå¯¹è¿‡åº¦ä½¿ç”¨çŽ‡çš„æ£€æµ‹
+ä¸ä»…è¦è€ƒè™‘CFS任务使用的算力,还需è¦è€ƒè™‘其它调度类和中断。
+
+
+6. EASçš„ä¾èµ–å’Œè¦æ±‚
+------------------
+
+èƒ½é‡æ„ŸçŸ¥è°ƒåº¦ä¾èµ–系统的CPU具有特定的硬件属性,以åŠå†…核中的其它特性被å¯ç”¨ã€‚本节列出
+了这些ä¾èµ–,并对如何满足这些ä¾èµ–æä¾›äº†æç¤ºã€‚
+
+
+6.1 - éžå¯¹ç§°CPU拓扑
+^^^^^^^^^^^^^^^^^^^
+
+
+如简介所æï¼Œç›®å‰åªæœ‰éžå¯¹ç§°CPUæ‹“æ‰‘ç»“æž„çš„å¹³å°æ”¯æŒEAS。通过在è¿è¡Œæ—¶æŸ¥è¯¢
+SD_ASYM_CPUCAPACITY_FULLæ ‡å¿—ä½æ˜¯å¦åœ¨åˆ›å»ºè°ƒåº¦åŸŸæ—¶å·²è®¾ç½®æ¥æ£€æŸ¥è¿™ä¸€è¦æ±‚æ˜¯å¦æ»¡è¶³ã€‚
+
+å‚阅Documentation/scheduler/sched-capacity.rst以了解在sched_domain层次结构
+ä¸­è®¾ç½®æ­¤æ ‡å¿—ä½æ‰€éœ€æ»¡è¶³çš„è¦æ±‚。
+
+请注æ„,EASå¹¶éžä»Žæ ¹æœ¬ä¸Šä¸ŽSMPä¸å…¼å®¹ï¼Œä½†åœ¨SMPå¹³å°ä¸Šè¿˜æ²¡æœ‰è§‚察到明显的节能。这一
+é™åˆ¶å¯ä»¥åœ¨å°†æ¥è¿›è¡Œä¿®æ”¹ï¼Œå¦‚æžœè¢«è¯æ˜Žä¸æ˜¯è¿™æ ·çš„è¯ã€‚
+
+
+6.2 - 当å‰çš„èƒ½é‡æ¨¡åž‹
+^^^^^^^^^^^^^^^^^^^^
+
+EAS使用一个平å°çš„EMæ¥ä¼°ç®—调度决策对能é‡çš„å½±å“。因此,你的平å°å¿…é¡»å‘EM框架æä¾›
+èƒ½é‡æˆæœ¬è¡¨ï¼Œä»¥å¯åЍEAS。è¦åšåˆ°è¿™ä¸€ç‚¹ï¼Œè¯·å‚阅文档
+Documentation/power/energy-model.rst中的独立EM框架部分。
+
+å¦è¯·æ³¨æ„,调度域需è¦åœ¨EM注册åŽé‡å»ºï¼Œä»¥ä¾¿å¯åЍEAS。
+
+EAS使用EM对能é‡ä½¿ç”¨çŽ‡è¿›è¡Œé¢„æµ‹å†³ç­–ï¼Œå› æ­¤å®ƒåœ¨æ£€æŸ¥ä»»åŠ¡æ”¾ç½®çš„å¯èƒ½é€‰é¡¹æ—¶æ›´åŠ æ³¨é‡
+差异。对于EASæ¥è¯´ï¼ŒEM的功率值是以毫瓦还是以“抽象刻度â€ä¸ºå•ä½è¡¨ç¤ºå¹¶ä¸é‡è¦ã€‚
+
+
+
+6.3 - èƒ½é‡æ¨¡åž‹å¤æ‚度
+^^^^^^^^^^^^^^^^^^^^
+
+ä»»åŠ¡å”¤é†’è·¯å¾„æ˜¯æ—¶å»¶æ•æ„Ÿçš„。当一个平å°çš„EMå¤ªå¤æ‚(太多CPU,太多性能域,太多状æ€
+ç­‰ï¼‰ï¼Œåœ¨å”¤é†’è·¯å¾„ä¸­ä½¿ç”¨å®ƒçš„æˆæœ¬å°±ä¼šå‡é«˜åˆ°ä¸å¯æŽ¥å—ã€‚èƒ½é‡æ„ŸçŸ¥å”¤é†’ç®—æ³•çš„å¤æ‚度为:
+
+ C = Nd * (Nc + Ns)
+
+其中:Nd是性能域的数é‡ï¼›Nc是CPU的数é‡ï¼›Ns是OPP的总数(例如:对于两个性能域,
+æ¯ä¸ªåŸŸæœ‰4个OPP,则Ns = 8)。
+
+å½“è°ƒåº¦åŸŸå»ºç«‹æ—¶ï¼Œå¤æ‚æ€§æ£€æŸ¥æ˜¯åœ¨æ ¹åŸŸä¸Šè¿›è¡Œçš„ã€‚å¦‚æžœä¸€ä¸ªæ ¹åŸŸçš„å¤æ‚度Cæ°å¥½é«˜äºŽå®Œå…¨
+主观设定的EM_MAX_COMPLEXITY阈值(在本文写作时,是2048),则EASä¸ä¼šåœ¨æ­¤æ ¹åŸŸ
+å¯åŠ¨ã€‚
+
+如果你的平å°çš„èƒ½é‡æ¨¡åž‹çš„夿‚度太高,EAS无法在这个根域上使用,但你真的想用,
+那么你就åªå‰©ä¸‹ä¸¤ä¸ªå¯èƒ½çš„选择:
+
+ 1. 将你的系统拆分æˆåˆ†ç¦»çš„ã€è¾ƒå°çš„ã€ä½¿ç”¨ç‹¬å cpuset的根域,并在æ¯ä¸ªæ ¹åŸŸå±€éƒ¨
+ å¯ç”¨EAS。这个方案的好处是开箱å³ç”¨ï¼Œä½†ç¼ºç‚¹æ˜¯æ— æ³•在根域之间实现负载å‡è¡¡ï¼Œ
+ è¿™å¯èƒ½ä¼šå¯¼è‡´æ€»ä½“系统负载ä¸å‡è¡¡ã€‚
+ 2. æäº¤è¡¥ä¸ä»¥é™ä½ŽEASå”¤é†’ç®—æ³•çš„å¤æ‚度,从而使其能够在åˆç†çš„æ—¶é—´å†…å¤„ç†æ›´å¤§
+ 的EM。
+
+
+6.4 - Schedutil监管器
+^^^^^^^^^^^^^^^^^^^^^
+
+EAS试图预测CPU在ä¸ä¹…的将æ¥ä¼šåœ¨å“ªä¸ªOPP下è¿è¡Œï¼Œä»¥ä¼°ç®—å®ƒä»¬çš„èƒ½é‡æ¶ˆè€—。为了åšåˆ°
+这一点,它å‡å®šCPUçš„OPPè·ŸéšCPU利用率å˜åŒ–而å˜åŒ–。
+
+尽管在实践中很难对这一å‡è®¾çš„准确性æä¾›ç¡¬æ€§ä¿è¯ï¼ˆå› ä¸ºï¼Œä¸¾ä¾‹æ¥è¯´ç¡¬ä»¶å¯èƒ½ä¸ä¼šåš
+å®ƒè¢«è¦æ±‚åšçš„事情),相对于其他CPUFreq监管器,schedutil至少_请求_使用利用率
+ä¿¡å·è®¡ç®—的频率。因此,与EAS一起使用的唯一åˆç†çš„监管器是schedutil,因为它是
+唯一一个在频率请求和能é‡é¢„测之间æä¾›æŸç§ç¨‹åº¦çš„一致性的监管器。
+
+䏿”¯æŒå°†EAS与schedutil之外的任何其它监管器一起使用。
+
+
+6.5 刻度ä¸å˜æ€§ä½¿ç”¨çŽ‡ä¿¡å·
+^^^^^^^^^^^^^^^^^^^^^^^^
+
+为了对ä¸åŒçš„CPU和所有的性能状æ€åšå‡ºå‡†ç¡®çš„预测,EAS需è¦é¢‘率ä¸å˜çš„å’ŒCPUä¸å˜çš„
+PELTä¿¡å·ã€‚这些信å·å¯ä»¥é€šè¿‡æ¯ä¸ªä½“系结构定义的arch_scale{cpu,freq}_capacity()
+回调函数获å–。
+
+䏿”¯æŒåœ¨æ²¡æœ‰å®žçŽ°è¿™ä¸¤ä¸ªå›žè°ƒå‡½æ•°çš„å¹³å°ä¸Šä½¿ç”¨EAS。
+
+
+6.6 多线程(SMT)
+^^^^^^^^^^^^^^^^^
+
+当å‰å®žçŽ°çš„EASæ˜¯ä¸æ„ŸçŸ¥SMT的,因此无法利用多线程硬件节约能é‡ã€‚EAS认为线程是独立的
+CPUï¼Œè¿™å®žé™…ä¸Šå¯¹æ€§èƒ½å’Œèƒ½é‡æ¶ˆè€—都是ä¸åˆ©çš„。
+
+䏿”¯æŒåœ¨SMT上使用EAS。
diff --git a/Documentation/translations/zh_CN/scheduler/sched-nice-design.rst b/Documentation/translations/zh_CN/scheduler/sched-nice-design.rst
new file mode 100644
index 000000000000..9107f0c0b979
--- /dev/null
+++ b/Documentation/translations/zh_CN/scheduler/sched-nice-design.rst
@@ -0,0 +1,99 @@
+.. SPDX-License-Identifier: GPL-2.0
+.. include:: ../disclaimer-zh_CN.rst
+
+:Original: Documentation/scheduler/sched-nice-design.rst
+
+:翻译:
+
+ å”艺舟 Tang Yizhou <tangyeechou@gmail.com>
+
+=====================
+调度器nice值设计
+=====================
+
+本文档解释了新的Linux调度器中修改和精简åŽçš„nice级别的实现æ€è·¯ã€‚
+
+Linuxçš„nice级别总是éžå¸¸è„†å¼±ï¼Œäººä»¬æŒç»­ä¸æ–­åœ°ç¼ ç€æˆ‘们,让nice +19的任务å ç”¨
+更少的CPU时间。
+
+ä¸å¹¸çš„æ˜¯ï¼Œåœ¨æ—§çš„è°ƒåº¦å™¨ä¸­ï¼Œè¿™ä¸æ˜¯é‚£ä¹ˆå®¹æ˜“实现的(å¦åˆ™æˆ‘们早就åšåˆ°äº†ï¼‰ï¼Œå› ä¸ºå¯¹
+nice级别的支æŒåœ¨åކå²ä¸Šæ˜¯ä¸Žæ—¶é—´ç‰‡é•¿åº¦è€¦åˆçš„,而时间片å•使˜¯ç”±HZ滴答驱动的,
+所以最å°çš„æ—¶é—´ç‰‡æ˜¯1/HZ。
+
+在O(1)调度器中(2003年),我们改å˜äº†è´Ÿçš„nice级别,使它们比2.4内核更强
+(人们对这一å˜åŒ–很满æ„ï¼‰ï¼Œè€Œä¸”æˆ‘ä»¬è¿˜æ•…æ„æ ¡æ­£äº†çº¿æ€§æ—¶é—´ç‰‡å‡†åˆ™ï¼Œä½¿å¾—nice +19
+的级别 _正好_ 是1 jiffy。为了让大家更好地ç†è§£å®ƒï¼Œæ—¶é—´ç‰‡çš„图会是这样的(质é‡
+ä¸ä½³çš„ASCII艺术æé†’ï¼ï¼‰::
+
+
+ A
+ \ | [timeslice length]
+ \ |
+ \ |
+ \ |
+ \ |
+ \|___100msecs
+ |^ . _
+ | ^ . _
+ | ^ . _
+ -*----------------------------------*-----> [nice level]
+ -20 | +19
+ |
+ |
+
+因此,如果有人真的想renice任务,相较线性规则,+19会给出更大的效果(改å˜
+ABIæ¥æ‰©å±•优先级的解决方案在早期就被放弃了)。
+
+è¿™ç§æ–¹æ³•åœ¨ä¸€å®šç¨‹åº¦ä¸Šå¥æ•ˆäº†ä¸€æ®µæ—¶é—´ï¼Œä½†åŽæ¥HZ=1000时,它导致1 jiffy为
+1ms,这æ„味ç€0.1%çš„CPU使用率,我们认为这有点过度。过度 _䏿˜¯_ 因为它表示
+çš„CPU使用率过å°ï¼Œè€Œæ˜¯å› ä¸ºå®ƒå¼•å‘了过于频ç¹ï¼ˆæ¯æ¯«ç§’1æ¬¡ï¼‰çš„é‡æ–°è°ƒåº¦ï¼ˆå› æ­¤ä¼š
+ç ´å缓存,等等。请记ä½ï¼Œç¡¬ä»¶æ›´å¼±ã€cacheæ›´å°æ˜¯å¾ˆä¹…以å‰çš„事了,当时人们在
+nice +19级别è¿è¡Œæ•°é‡é¢‡å¤šçš„应用程åºï¼‰ã€‚
+
+因此,对于HZ=1000,我们将nice +19改为5æ¯«ç§’ï¼Œå› ä¸ºè¿™æ„Ÿè§‰åƒæ˜¯æ­£ç¡®çš„æœ€å°
+粒度——这相当于5%çš„CPU利用率。但nice +19的根本的HZæ•æ„Ÿå±žæ€§ä¾ç„¶ä¿æŒä¸å˜ï¼Œ
+我们没有收到过关于nice +19在CPU利用率方é¢å¤ª _å¼±_ çš„ä»»ä½•æŠ±æ€¨ï¼Œæˆ‘ä»¬åªæ”¶åˆ°
+过它(ä¾ç„¶ï¼‰å¤ª _强_ 的抱怨 :-)。
+
+总结一下:我们一直想让niceå„级别一致性更强,但在HZå’Œjiffiesçš„é™åˆ¶ä¸‹ï¼Œä»¥åŠ
+nice级别与时间片ã€è°ƒåº¦ç²’åº¦è€¦åˆæ˜¯ä»¤äººè®¨åŽŒçš„è®¾è®¡ï¼Œè¿™ä¸€ç›®æ ‡å¹¶ä¸çœŸæ­£å¯è¡Œã€‚
+
+第二个关于Linux nice级别支æŒçš„æŠ±æ€¨æ˜¯ï¼ˆä¸é‚£ä¹ˆé¢‘ç¹ï¼Œä½†ä»ç„¶å®šæœŸå‘生),它
+在原点周围的ä¸å¯¹ç§°æ€§ï¼ˆä½ å¯ä»¥åœ¨ä¸Šé¢çš„图片中看到),或者更准确地说:事实上
+nice级别的行为å–决于 _ç»å¯¹çš„_ nice级别,而niceåº”ç”¨ç¨‹åºæŽ¥å£æœ¬èº«ä»Žæ ¹æœ¬ä¸Š
+说是“相对â€çš„:
+
+ int nice(int inc);
+
+ asmlinkage long sys_nice(int increment)
+
+(第一个是glibcçš„åº”ç”¨ç¨‹åºæŽ¥å£ï¼Œç¬¬äºŒä¸ªæ˜¯syscallçš„åº”ç”¨ç¨‹åºæŽ¥å£ï¼‰
+注æ„,“incâ€æ˜¯ç›¸å¯¹å½“å‰nice级别而言的,类似bash的“niceâ€å‘½ä»¤ç­‰å·¥å…·æ˜¯è¿™ä¸ª
+ç›¸å¯¹æ€§åº”ç”¨ç¨‹åºæŽ¥å£çš„镜åƒã€‚
+
+在旧的调度器中,举例æ¥è¯´ï¼Œå¦‚果你以nice +1å¯åŠ¨ä¸€ä¸ªä»»åŠ¡ï¼Œå¹¶ä»¥nice +2å¯åЍ
+å¦ä¸€ä¸ªä»»åŠ¡ï¼Œè¿™ä¸¤ä¸ªä»»åŠ¡çš„CPU分é…å°†å–决于父外壳程åºçš„nice级别——如果它是
+nice -10,那么CPU的分é…ä¸åŒäºŽ+5或+10。
+
+第三个关于Linux nice级别支æŒçš„æŠ±æ€¨æ˜¯ï¼Œè´Ÿæ•°nice级别“ä¸å¤Ÿæœ‰åŠ›â€ï¼Œä»¥å¾ˆå¤šäºº
+ä¸å¾—ä¸è¯‰è¯¸äºŽå®žæ—¶è°ƒåº¦ä¼˜å…ˆçº§æ¥è¿è¡ŒéŸ³é¢‘(和其它多媒体)应用程åºï¼Œæ¯”如
+SCHED_FIFO。但这也造æˆäº†å…¶å®ƒé—®é¢˜ï¼šSCHED_FIFOæœªè¢«è¯æ˜Žæ˜¯å…于饥饿的,一个
+有问题的SCHED_FIFO应用程åºä¹Ÿä¼šé”ä½è¿è¡Œè‰¯å¥½çš„系统。
+
+v2.6.23版内核的新调度器解决了这三ç§ç±»åž‹çš„æŠ±æ€¨ï¼š
+
+为了解决第一个抱怨(nice级别ä¸å¤Ÿâ€œæœ‰åŠ›â€ï¼‰ï¼Œè°ƒåº¦å™¨ä¸Žâ€œæ—¶é—´ç‰‡â€ã€HZ的概念
+è§£è€¦ï¼ˆè°ƒåº¦ç²’åº¦è¢«å¤„ç†æˆä¸€ä¸ªå’Œnice级别独立的概念),因此有å¯èƒ½å®žçŽ°æ›´å¥½ã€
+更一致的nice +19支æŒï¼šåœ¨æ–°çš„调度器中,nice +19的任务得到一个HZ无关的
+1.5%CPUä½¿ç”¨çŽ‡ï¼Œè€Œä¸æ˜¯æ—§ç‰ˆè°ƒåº¦å™¨ä¸­3%-5%-9%çš„å¯å˜èŒƒå›´ã€‚
+
+为了解决第二个抱怨(niceå„级别ä¸ä¸€è‡´ï¼‰ï¼Œæ–°è°ƒåº¦å™¨ä»¤è°ƒç”¨nice(1)对å„任务的
+CPU利用率有相åŒçš„å½±å“,无论其ç»å¯¹nice级别如何。所以在新调度器上,è¿è¡Œä¸€ä¸ª
+nice +10和一个nice +11的任务会与è¿è¡Œä¸€ä¸ªnice -5和一个nice -4的任务的
+CPU利用率分割是相åŒçš„(一个会得到55%çš„CPU,å¦ä¸€ä¸ªä¼šå¾—到45%)。这是为什么
+nice级别被改为“乘法â€ï¼ˆæˆ–指数)——这样的è¯ï¼Œä¸ç®¡ä½ ä»Žå“ªä¸ªçº§åˆ«å¼€å§‹ï¼Œâ€œç›¸å¯¹â€
+结果将总是一样的。
+
+第三个抱怨(负数nice级别ä¸å¤Ÿâ€œæœ‰åŠ›â€ï¼Œå¹¶è¿«ä½¿éŸ³é¢‘应用程åºåœ¨æ›´å±é™©çš„
+SCHED_FIFO调度策略下è¿è¡Œï¼‰å‡ ä¹Žè¢«æ–°çš„调度器自动解决了:更强的负数级别
+å…·æœ‰é‡æ–°æ ¡æ­£nice级别动æ€èŒƒå›´çš„自动化副作用。
diff --git a/Documentation/translations/zh_CN/scheduler/sched-stats.rst b/Documentation/translations/zh_CN/scheduler/sched-stats.rst
new file mode 100644
index 000000000000..1c68c3d1c283
--- /dev/null
+++ b/Documentation/translations/zh_CN/scheduler/sched-stats.rst
@@ -0,0 +1,156 @@
+.. SPDX-License-Identifier: GPL-2.0
+.. include:: ../disclaimer-zh_CN.rst
+
+:Original: Documentation/scheduler/sched-stats.rst
+
+:翻译:
+
+ å”艺舟 Tang Yizhou <tangyeechou@gmail.com>
+
+==============
+调度器统计数æ®
+==============
+
+第15版schedstats去掉了sched_yield的一些计数器:yld_exp_empty,yld_act_empty
+å’Œyld_both_empty。在其它方é¢å’Œç¬¬14版完全相åŒã€‚
+
+第14版schedstats包括对sched_domains(译注:调度域)的支æŒï¼Œè¯¥ç‰¹æ€§è¿›å…¥å†…æ ¸
+主线2.6.20,ä¸è¿‡è¿™ä¸€ç‰ˆschedstats与2.6.13-2.6.19内核的版本12çš„ç»Ÿè®¡æ•°æ®æ˜¯å®Œå…¨
+相åŒçš„(内核未å‘布第13版)。有些计数器按æ¯ä¸ªè¿è¡Œé˜Ÿåˆ—统计是更有æ„义的,其它则
+按æ¯ä¸ªè°ƒåº¦åŸŸç»Ÿè®¡æ˜¯æ›´æœ‰æ„义的。注æ„,调度域(以åŠå®ƒä»¬çš„附属信æ¯ï¼‰ä»…在开å¯
+CONFIG_SMP的机器上是相关的和å¯ç”¨çš„。
+
+在第14版schedstat中,æ¯ä¸ªè¢«åˆ—出的CPU至少会有一级域统计数æ®ï¼Œä¸”很å¯èƒ½æœ‰ä¸€ä¸ª
+以上的域。在这个实现中,域没有特别的åå­—ï¼Œä½†æ˜¯ç¼–å·æœ€é«˜çš„域通常在机器上所有的
+CPU上仲è£å¹³è¡¡ï¼Œè€Œdomain0是最紧密èšç„¦çš„域,有时仅在一对CPU之间进行平衡。此时,
+没有任何体系结构需è¦3层以上的域。域统计数æ®ä¸­çš„第一个字段是一个ä½å›¾ï¼Œè¡¨æ˜Žå“ªäº›
+CPUå—该域的影å“。
+
+这些字段是计数器,而且åªèƒ½é€’增。使用这些字段的程åºå°†éœ€è¦ä»ŽåŸºçº¿è§‚测开始,然åŽåœ¨
+åŽç»­æ¯ä¸€ä¸ªè§‚测中计算出计数器的å˜åŒ–ã€‚ä¸€ä¸ªèƒ½ä»¥è¿™ç§æ–¹å¼å¤„ç†å…¶ä¸­å¾ˆå¤šå­—段的perl脚本
+å¯è§
+
+ http://eaglet.pdxhosts.com/rick/linux/schedstat/
+
+请注æ„,任何这样的脚本都必须是特定于版本的,改å˜ç‰ˆæœ¬çš„主è¦åŽŸå› æ˜¯è¾“å‡ºæ ¼å¼çš„å˜åŒ–。
+对于那些希望编写自己的脚本的人,å¯ä»¥å‚考这里æè¿°çš„å„个字段。
+
+CPU统计数æ®
+-----------
+cpu<N> 1 2 3 4 5 6 7 8 9
+
+第一个字段是sched_yield()的统计数æ®ï¼š
+
+ 1) sched_yield()被调用了#次
+
+接下æ¥çš„三个是schedule()的统计数æ®ï¼š
+
+ 2) 这个字段是一个过时的数组过期计数,在O(1)调度器中使用。为了ABI兼容性,
+ 我们ä¿ç•™äº†å®ƒï¼Œä½†å®ƒæ€»æ˜¯è¢«è®¾ç½®ä¸º0。
+ 3) schedule()被调用了#次
+ 4) 调用schedule()导致处ç†å™¨å˜ä¸ºç©ºé—²äº†#次
+
+接下æ¥çš„两个是try_to_wake_up()的统计数æ®ï¼š
+
+ 5) try_to_wake_up()被调用了#次
+ 6) 调用try_to_wake_up()导致本地CPU被唤醒了#次
+
+接下æ¥çš„ä¸‰ä¸ªç»Ÿè®¡æ•°æ®æè¿°äº†è°ƒåº¦å»¶è¿Ÿï¼š
+
+ 7) 本处ç†å™¨è¿è¡Œä»»åŠ¡çš„æ€»æ—¶é—´ï¼Œå•使˜¯jiffies
+ 8) 本处ç†å™¨ä»»åŠ¡ç­‰å¾…è¿è¡Œçš„æ—¶é—´ï¼Œå•使˜¯jiffies
+ 9) 本CPUè¿è¡Œäº†#个时间片
+
+域统计数æ®
+----------
+
+对于æ¯ä¸ªè¢«æè¿°çš„CPU,和它相关的æ¯ä¸€ä¸ªè°ƒåº¦åŸŸå‡ä¼šäº§ç”Ÿä¸‹é¢ä¸€è¡Œæ•°æ®ï¼ˆæ³¨æ„,如果
+CONFIG_SMP没有被定义,那么*没有*调度域被使用,这些行ä¸ä¼šå‡ºçŽ°åœ¨è¾“å‡ºä¸­ï¼‰ã€‚
+
+domain<N> <cpumask> 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
+
+ç¬¬ä¸€ä¸ªå­—æ®µæ˜¯ä¸€ä¸ªä½æŽ©ç ï¼Œè¡¨æ˜Žè¯¥åŸŸåœ¨æ“作哪些CPU。
+
+接下æ¥çš„24个字段是load_balance()函数的å„个统计数æ®ï¼ŒæŒ‰ç©ºé—²ç±»åž‹åˆ†ç»„(空闲,
+ç¹å¿™ï¼Œæ–°ç©ºé—²ï¼‰ï¼š
+
+
+ 1) 当CPU空闲时,load_balance()在这个调度域中被调用了#次
+ 2) 当CPU空闲时,load_balance()在这个调度域中被调用,但是å‘现负载无需
+ å‡è¡¡#次
+ 3) 当CPU空闲时,load_balance()在这个调度域中被调用,试图è¿ç§»1个或更多
+ 任务且失败了#次
+ 4) 当CPU空闲时,load_balance()在这个调度域中被调用,å‘现ä¸å‡è¡¡ï¼ˆå¦‚果有)
+ #次
+ 5) 当CPU空闲时,pull_task()在这个调度域中被调用#次
+ 6) 当CPU空闲时,尽管目标任务是热缓存状æ€ï¼Œpull_task()ä¾ç„¶è¢«è°ƒç”¨#次
+ 7) 当CPU空闲时,load_balance()在这个调度域中被调用,未能找到更ç¹å¿™çš„
+ 队列#次
+ 8) 当CPU空闲时,在调度域中找到了更ç¹å¿™çš„队列,但未找到更ç¹å¿™çš„调度组
+ #次
+ 9) 当CPUç¹å¿™æ—¶ï¼Œload_balance()在这个调度域中被调用了#次
+ 10) 当CPUç¹å¿™æ—¶ï¼Œload_balance()在这个调度域中被调用,但是å‘现负载无需
+ å‡è¡¡#次
+ 11) 当CPUç¹å¿™æ—¶ï¼Œload_balance()在这个调度域中被调用,试图è¿ç§»1个或更多
+ 任务且失败了#次
+ 12) 当CPUç¹å¿™æ—¶ï¼Œload_balance()在这个调度域中被调用,å‘现ä¸å‡è¡¡ï¼ˆå¦‚果有)
+ #次
+ 13) 当CPUç¹å¿™æ—¶ï¼Œpull_task()在这个调度域中被调用#次
+ 14) 当CPUç¹å¿™æ—¶ï¼Œå°½ç®¡ç›®æ ‡ä»»åŠ¡æ˜¯çƒ­ç¼“å­˜çŠ¶æ€ï¼Œpull_task()ä¾ç„¶è¢«è°ƒç”¨#次
+ 15) 当CPUç¹å¿™æ—¶ï¼Œload_balance()在这个调度域中被调用,未能找到更ç¹å¿™çš„
+ 队列#次
+ 16) 当CPUç¹å¿™æ—¶ï¼Œåœ¨è°ƒåº¦åŸŸä¸­æ‰¾åˆ°äº†æ›´ç¹å¿™çš„队列,但未找到更ç¹å¿™çš„调度组
+ #次
+ 17) 当CPU新空闲时,load_balance()在这个调度域中被调用了#次
+ 18) 当CPU新空闲时,load_balance()在这个调度域中被调用,但是å‘现负载无需
+ å‡è¡¡#次
+ 19) 当CPU新空闲时,load_balance()在这个调度域中被调用,试图è¿ç§»1个或更多
+ 任务且失败了#次
+ 20) 当CPU新空闲时,load_balance()在这个调度域中被调用,å‘现ä¸å‡è¡¡ï¼ˆå¦‚果有)
+ #次
+ 21) 当CPU新空闲时,pull_task()在这个调度域中被调用#次
+ 22) 当CPU新空闲时,尽管目标任务是热缓存状æ€ï¼Œpull_task()ä¾ç„¶è¢«è°ƒç”¨#次
+ 23) 当CPU新空闲时,load_balance()在这个调度域中被调用,未能找到更ç¹å¿™çš„
+ 队列#次
+ 24) 当CPU新空闲时,在调度域中找到了更ç¹å¿™çš„队列,但未找到更ç¹å¿™çš„调度组
+ #次
+
+接下æ¥çš„3个字段是active_load_balance()函数的å„个统计数æ®ï¼š
+
+ 25) active_load_balance()被调用了#次
+ 26) active_load_balance()被调用,试图è¿ç§»1个或更多任务且失败了#次
+ 27) active_load_balance()被调用,æˆåŠŸè¿ç§»äº†#次任务
+
+接下æ¥çš„3个字段是sched_balance_exec()函数的å„个统计数æ®ï¼š
+
+ 28) sbe_cntä¸å†è¢«ä½¿ç”¨
+ 29) sbe_balancedä¸å†è¢«ä½¿ç”¨
+ 30) sbe_pushedä¸å†è¢«ä½¿ç”¨
+
+接下æ¥çš„3个字段是sched_balance_fork()函数的å„个统计数æ®ï¼š
+
+ 31) sbf_cntä¸å†è¢«ä½¿ç”¨
+ 32) sbf_balancedä¸å†è¢«ä½¿ç”¨
+ 33) sbf_pushedä¸å†è¢«ä½¿ç”¨
+
+接下æ¥çš„3个字段是try_to_wake_up()函数的å„个统计数æ®ï¼š
+
+ 34) 在这个调度域中调用try_to_wake_up()唤醒任务时,任务在调度域中一个
+ 和上次è¿è¡Œä¸åŒçš„æ–°CPU上è¿è¡Œäº†#次
+ 35) 在这个调度域中调用try_to_wake_up()唤醒任务时,任务被è¿ç§»åˆ°å‘生唤醒
+ çš„CPU次数为#,因为该任务在原CPU是冷缓存状æ€
+ 36) 在这个调度域中调用try_to_wake_up()唤醒任务时,引å‘被动负载å‡è¡¡#次
+
+/proc/<pid>/schedstat
+---------------------
+schedstats还添加了一个新的/proc/<pid>/schedstatæ–‡ä»¶ï¼Œæ¥æä¾›ä¸€äº›è¿›ç¨‹çº§çš„
+相åŒä¿¡æ¯ã€‚这个文件中,有三个字段与该进程相关:
+
+ 1) 在CPU上è¿è¡ŒèŠ±è´¹çš„æ—¶é—´
+ 2) 在è¿è¡Œé˜Ÿåˆ—上等待的时间
+ 3) 在CPU上è¿è¡Œäº†#个时间片
+
+å¯ä»¥å¾ˆå®¹æ˜“地编写一个程åºï¼Œåˆ©ç”¨è¿™äº›é¢å¤–çš„å­—æ®µæ¥æŠ¥å‘Šä¸€ä¸ªç‰¹å®šçš„è¿›ç¨‹æˆ–ä¸€ç»„è¿›ç¨‹åœ¨
+调度器策略下的表现如何。这样的程åºçš„一个简å•版本å¯åœ¨ä¸‹é¢çš„链接找到
+
+ http://eaglet.pdxhosts.com/rick/linux/schedstat/v12/latency.c
diff --git a/Documentation/translations/zh_CN/vm/active_mm.rst b/Documentation/translations/zh_CN/vm/active_mm.rst
new file mode 100644
index 000000000000..366609ea4f37
--- /dev/null
+++ b/Documentation/translations/zh_CN/vm/active_mm.rst
@@ -0,0 +1,85 @@
+.. include:: ../disclaimer-zh_CN.rst
+
+:Original: Documentation/vm/active_mm.rst
+
+:翻译:
+
+ å¸å»¶è…¾ Yanteng Si <siyanteng@loongson.cn>
+
+:校译:
+
+
+=========
+Active MM
+=========
+
+这是一å°linux之父回å¤å¼€å‘者的一å°é‚®ä»¶ï¼Œæ‰€ä»¥ç¿»è¯‘时我尽é‡ä¿æŒé‚®ä»¶æ ¼å¼çš„完整。
+
+::
+
+ List: linux-kernel
+ Subject: Re: active_mm
+ From: Linus Torvalds <torvalds () transmeta ! com>
+ Date: 1999-07-30 21:36:24
+
+ 因为我并ä¸ç»å¸¸å†™è§£é‡Šï¼Œæ‰€ä»¥å·²ç»æŠ„é€åˆ°linux-kernel邮件列表,而当我åšè¿™äº›ï¼Œ
+ 且更多的人在阅读它们时,我觉得棒æžäº†ã€‚
+
+ 1999å¹´7月30æ—¥ 星期五, David Mosberger 写é“:
+ >
+ > æ˜¯å¦æœ‰ä¸€ä¸ªç®€çŸ­çš„æè¿°ï¼Œè¯´æ˜Žtask_struct中的
+ > "mm" 和 "active_mm"应该如何使用? (如果
+ > 这个问题在邮件列表中讨论过,我表示歉æ„--我刚
+ > 刚度å‡å›žæ¥ï¼Œæœ‰ä¸€æ®µæ—¶é—´æ²¡èƒ½å…³æ³¨linux-kernel了)。
+
+ 基本上,新的设定是:
+
+ - 我们有“真实地å€ç©ºé—´â€å’Œâ€œåŒ¿å地å€ç©ºé—´â€ã€‚区别在于,匿å地å€ç©ºé—´æ ¹æœ¬ä¸å…³å¿ƒç”¨
+ 户级页表,所以当我们åšä¸Šä¸‹æ–‡åˆ‡æ¢åˆ°åŒ¿å地å€ç©ºé—´æ—¶ï¼Œæˆ‘ä»¬åªæ˜¯è®©ä»¥å‰çš„地å€ç©ºé—´
+ 处于活动状æ€ã€‚
+
+ 一个“匿å地å€ç©ºé—´â€çš„æ˜Žæ˜¾ç”¨é€”是任何ä¸éœ€è¦ä»»ä½•用户映射的线程--所有的内核线
+ 程基本上都属于这一类,但å³ä½¿æ˜¯â€œçœŸæ­£çš„â€çº¿ç¨‹ä¹Ÿå¯ä»¥æš‚时说在一定时间内它们ä¸
+ 会对用户空间感兴趣,调度器ä¸å¦¨è¯•ç€é¿å…在切æ¢VM状æ€ä¸Šæµªè´¹æ—¶é—´ã€‚ç›®å‰åªæœ‰è€
+ å¼çš„bdflush sync能åšåˆ°è¿™ä¸€ç‚¹ã€‚
+
+ - “tsk->mmâ€ æŒ‡å‘ â€œçœŸå®žåœ°å€ç©ºé—´â€ã€‚对于一个匿å进程æ¥è¯´ï¼Œtsk->mm将是NULL,
+ 其逻辑原因是匿å进程实际上根本就 “没有†真正的地å€ç©ºé—´ã€‚
+
+ - 然而,我们显然需è¦è·Ÿè¸ªæˆ‘们为这样的匿å用户“å·ç”¨â€äº†å“ªä¸ªåœ°å€ç©ºé—´ã€‚为此,我们
+ 有 “tsk->active_mmâ€ï¼Œå®ƒæ˜¾ç¤ºäº†å½“剿´»åŠ¨çš„åœ°å€ç©ºé—´æ˜¯ä»€ä¹ˆã€‚
+
+ 规则是,对于一个有真实地å€ç©ºé—´çš„进程(å³tsk->mm是 non-NULL),active_mm
+ 显然必须与真实的mm相åŒã€‚
+
+ 对于一个匿å进程,tsk->mm == NULL,而tsk->active_mm是匿å进程è¿è¡Œæ—¶
+ “借用â€çš„mm。当匿å进程被调度走时,借用的地å€ç©ºé—´è¢«è¿”回并清除。
+
+ ä¸ºäº†æ”¯æŒæ‰€æœ‰è¿™äº›ï¼Œâ€œstruct mm_structâ€çŽ°åœ¨æœ‰ä¸¤ä¸ªè®¡æ•°å™¨ï¼šä¸€ä¸ªæ˜¯ “mm_usersâ€
+ è®¡æ•°å™¨ï¼Œå³æœ‰å¤šå°‘ “真正的地å€ç©ºé—´ç”¨æˆ·â€ï¼Œå¦ä¸€ä¸ªæ˜¯ “mm_countâ€è®¡æ•°å™¨ï¼Œå³ “lazyâ€
+ 用户(å³åŒ¿å用户)的数é‡ï¼Œå¦‚果有任何真正的用户,则加1。
+
+ 通常情况下,至少有一个真正的用户,但也å¯èƒ½æ˜¯çœŸæ­£çš„用户在å¦ä¸€ä¸ªCPU上退出,而
+ 一个lazy的用户ä»åœ¨æ´»åŠ¨ï¼Œæ‰€ä»¥ä½ å®žé™…ä¸Šå¾—åˆ°çš„æƒ…å†µæ˜¯ï¼Œä½ æœ‰ä¸€ä¸ªåœ°å€ç©ºé—´ **åª**
+ 被lazy的用户使用。这通常是一个短暂的生命周期状æ€ï¼Œå› ä¸ºä¸€æ—¦è¿™ä¸ªçº¿ç¨‹è¢«å®‰æŽ’给一
+ 个真正的线程,这个 “僵尸†mm就会被释放,因为 “mm_countâ€å˜æˆäº†é›¶ã€‚
+
+ å¦å¤–,一个新的规则是,**没有人** å†æŠŠ “init_mm†作为一个真正的MM了。
+ “init_mmâ€åº”è¯¥è¢«è®¤ä¸ºåªæ˜¯ä¸€ä¸ª “没有其他上下文时的lazy上下文â€ï¼Œäº‹å®žä¸Šï¼Œå®ƒä¸»
+ è¦æ˜¯åœ¨å¯åŠ¨æ—¶ä½¿ç”¨ï¼Œå½“æ—¶è¿˜æ²¡æœ‰çœŸæ­£çš„VMè¢«åˆ›å»ºã€‚å› æ­¤ï¼Œç”¨æ¥æ£€æŸ¥çš„代ç 
+
+ if (current->mm == &init_mm)
+
+ 一般æ¥è¯´ï¼Œåº”该用
+
+ if (!current->mm)
+
+ å–代上é¢çš„写法(这更有æ„义--测试基本上是 â€œæˆ‘ä»¬æ˜¯å¦æœ‰ä¸€ä¸ªç”¨æˆ·çŽ¯å¢ƒâ€ï¼Œå¹¶ä¸”通常
+ 由缺页异常处ç†ç¨‹åºå’Œç±»ä¼¼çš„东西æ¥å®Œæˆï¼‰ã€‚
+
+ 总之,我刚æ‰åœ¨ftp.kernel.org上放了一个pre-patch-2.3.13-1,因为它ç¨å¾®æ”¹
+ å˜äº†æŽ¥å£ä»¥é€‚é…alpha(è°ä¼šæƒ³åˆ°å‘¢ï¼Œä½†alpha体系结构上下文切æ¢ä»£ç å®žé™…上最终是
+ 最丑陋的之一--ä¸åƒå…¶ä»–架构的MMå’Œå¯„å­˜å™¨çŠ¶æ€æ˜¯åˆ†å¼€çš„,alphaçš„PALcode将两者
+ 连接起æ¥ï¼Œä½ éœ€è¦åŒæ—¶åˆ‡æ¢ä¸¤è€…)。
+
+ (æ–‡æ¡£æ¥æº http://marc.info/?l=linux-kernel&m=93337278602211&w=2)
diff --git a/Documentation/translations/zh_CN/vm/balance.rst b/Documentation/translations/zh_CN/vm/balance.rst
new file mode 100644
index 000000000000..e98a47ef24a8
--- /dev/null
+++ b/Documentation/translations/zh_CN/vm/balance.rst
@@ -0,0 +1,81 @@
+.. include:: ../disclaimer-zh_CN.rst
+
+:Original: Documentation/vm/balance.rst
+
+:翻译:
+
+ å¸å»¶è…¾ Yanteng Si <siyanteng@loongson.cn>
+
+:校译:
+
+
+========
+内存平衡
+========
+
+2000年1月开始,作者:Kanoj Sarcar <kanoj@sgi.com>
+
+对于 !__GFP_HIGH å’Œ !__GFP_KSWAPD_RECLAIM 以åŠéž __GFP_IO 的分é…,需è¦è¿›è¡Œ
+内存平衡。
+
+调用者é¿å…å›žæ”¶çš„ç¬¬ä¸€ä¸ªåŽŸå› æ˜¯è°ƒç”¨è€…ç”±äºŽæŒæœ‰è‡ªæ—‹é”或处于中断环境中而无法ç¡çœ ã€‚第二个
+原因å¯èƒ½æ˜¯ï¼Œè°ƒç”¨è€…æ„¿æ„在ä¸äº§ç”Ÿé¡µé¢å›žæ”¶å¼€é”€çš„æƒ…况下分é…失败。这å¯èƒ½å‘生在有0阶回退
+选项的机会主义高阶分é…è¯·æ±‚ä¸­ã€‚åœ¨è¿™ç§æƒ…况下,调用者å¯èƒ½ä¹Ÿå¸Œæœ›é¿å…唤醒kswapd。
+
+__GFP_IO分é…请求是为了防止文件系统死é”。
+
+在没有éžç¡çœ åˆ†é…请求的情况下,åšå¹³è¡¡ä¼¼ä¹Žæ˜¯æœ‰å®³çš„。页é¢å›žæ”¶å¯ä»¥è¢«æ‡’散地å¯åŠ¨ï¼Œä¹Ÿå°±æ˜¯
+è¯´ï¼Œåªæœ‰åœ¨éœ€è¦çš„æ—¶å€™ï¼ˆä¹Ÿå°±æ˜¯åŒºåŸŸçš„空闲内存为0ï¼‰ï¼Œè€Œä¸æ˜¯è®©å®ƒæˆä¸ºä¸€ä¸ªä¸»åŠ¨çš„è¿‡ç¨‹ã€‚
+
+也就是说,内核应该å°è¯•ä»Žç›´æŽ¥æ˜ å°„æ± ä¸­æ»¡è¶³å¯¹ç›´æŽ¥æ˜ å°„é¡µçš„è¯·æ±‚ï¼Œè€Œä¸æ˜¯å›žé€€åˆ°dma池中,
+这样就å¯ä»¥ä¿æŒdma池为dma请求(ä¸ç®¡æ˜¯ä¸æ˜¯åŽŸå­çš„)所填充。类似的争论也适用于高内存
+和直接映射的页é¢ã€‚相å,如果有很多空闲的dma页,最好是通过从dma池中分é…ä¸€ä¸ªæ¥æ»¡è¶³
+å¸¸è§„çš„å†…å­˜è¯·æ±‚ï¼Œè€Œä¸æ˜¯äº§ç”Ÿå¸¸è§„区域平衡的开销。
+
+在2.2ä¸­ï¼Œåªæœ‰å½“空闲页总数低于总内存的1/64时,æ‰ä¼šå¯åŠ¨å†…å­˜å¹³è¡¡/页é¢å›žæ”¶ã€‚如果dma
+和常规内存的比例åˆé€‚,å³ä½¿dma区完全空了,也很å¯èƒ½ä¸ä¼šè¿›è¡Œå¹³è¡¡ã€‚2.2å·²ç»åœ¨ä¸åŒå†…å­˜
+大å°çš„生产机器上è¿è¡Œï¼Œå³ä½¿æœ‰è¿™ä¸ªé—®é¢˜å­˜åœ¨ï¼Œä¼¼ä¹Žä¹Ÿåšå¾—ä¸é”™ã€‚在2.3中,由于HIGHMEMçš„
+存在,这个问题å˜å¾—更加严é‡ã€‚
+
+在2.3中,区域平衡å¯ä»¥ç”¨ä¸¤ç§æ–¹å¼ä¹‹ä¸€æ¥å®Œæˆï¼šæ ¹æ®åŒºåŸŸçš„大å°ï¼ˆå¯èƒ½æ˜¯ä½Žçº§åŒºåŸŸçš„大å°ï¼‰ï¼Œ
+我们å¯ä»¥åœ¨åˆå§‹åŒ–阶段决定在平衡任何区域时应该争å–å¤šå°‘ç©ºé—²é¡µã€‚å¥½çš„æ–¹é¢æ˜¯ï¼Œåœ¨å¹³è¡¡çš„æ—¶
+候,我们ä¸éœ€è¦çœ‹ä½Žçº§åŒºçš„大å°ï¼Œåçš„æ–¹é¢æ˜¯ï¼Œæˆ‘们å¯èƒ½ä¼šå› ä¸ºå¿½ç•¥ä½Žçº§åŒºå¯èƒ½è¾ƒä½Žçš„使用率
+而åšè¿‡äºŽé¢‘ç¹çš„平衡。å¦å¤–,åªè¦å¯¹åˆ†é…程åºç¨ä½œä¿®æ”¹ï¼Œå°±æœ‰å¯èƒ½å°†memclass()å®ç®€åŒ–为一
+个简å•的等å¼ã€‚
+
+å¦ä¸€ä¸ªå¯èƒ½çš„解决方案是,我们åªåœ¨ä¸€ä¸ªåŒº **å’Œ** 其所有低级区的空闲内存低于该区åŠå…¶
+低级区总内存的1/64时进行平衡。这就解决了2.2的平衡问题,并尽å¯èƒ½åœ°ä¿æŒäº†ä¸Ž2.2行为
+的接近。å¦å¤–,平衡算法在å„ç§æž¶æž„上的工作方å¼ä¹Ÿæ˜¯ä¸€æ ·çš„,这些架构有ä¸åŒæ•°é‡å’Œç±»åž‹çš„
+内存区。如果我们想å˜å¾—更花哨一点,我们å¯ä»¥åœ¨æœªæ¥ä¸ºä¸åŒåŒºåŸŸçš„自由页é¢åˆ†é…ä¸åŒçš„æƒé‡ã€‚
+
+请注æ„,如果普通区的大å°ä¸Ždma区相比是巨大的,那么在决定是å¦å¹³è¡¡æ™®é€šåŒºçš„æ—¶å€™ï¼Œè€ƒè™‘
+空闲的dma页就å˜å¾—ä¸é‚£ä¹ˆé‡è¦äº†ã€‚那么第一个解决方案就å˜å¾—更有å¸å¼•力。
+
+所附的补ä¸å®žçŽ°äº†ç¬¬äºŒä¸ªè§£å†³æ–¹æ¡ˆã€‚å®ƒè¿˜ “修å¤â€äº†ä¸¤ä¸ªé—®é¢˜ï¼šé¦–先,在低内存æ¡ä»¶ä¸‹ï¼Œkswapd
+被唤醒,就åƒ2.2中的éžç¡çœ åˆ†é…。第二,HIGHMEM区也被平衡了,以便给replace_with_highmem()
+一个争å–获得HIGHMEMé¡µçš„æœºä¼šï¼ŒåŒæ—¶ç¡®ä¿HIGHMEM分é…ä¸ä¼šè½å›žæ™®é€šåŒºã€‚这也确ä¿äº†HIGHMEM
+页ä¸ä¼šè¢«æ³„露(例如,在一个HIGHMEM页在交æ¢ç¼“存中但没有被任何人使用的情况下)。
+
+kswapd还需è¦çŸ¥é“它应该平衡哪些区。kswapdä¸»è¦æ˜¯åœ¨æ— æ³•进行平衡的情况下需è¦çš„,å¯èƒ½
+是因为所有的分é…请求都æ¥è‡ªä¸­æ–­ä¸Šä¸‹æ–‡ï¼Œè€Œæ‰€æœ‰çš„进程上下文都在ç¡çœ ã€‚对于2.3,
+kswapdå¹¶ä¸çœŸæ­£éœ€è¦å¹³è¡¡é«˜å†…存区,因为中断上下文并ä¸è¯·æ±‚高内存页。kswapd看zone
+结构体中的zone_wake_kswapd字段æ¥å†³å®šä¸€ä¸ªåŒºæ˜¯å¦éœ€è¦å¹³è¡¡ã€‚
+
+如果从进程内存和shm中å·å–页é¢å¯ä»¥å‡è½»è¯¥é¡µé¢èŠ‚ç‚¹ä¸­ä»»ä½•åŒºçš„å†…å­˜åŽ‹åŠ›ï¼Œè€Œè¯¥åŒºçš„å†…å­˜åŽ‹åŠ›
+å·²ç»ä½ŽäºŽå…¶æ°´ä½ï¼Œåˆ™ä¼šè¿›è¡Œå·å–。
+
+watemark[WMARK_MIN/WMARK_LOW/WMARK_HIGH]/low_on_memory/zone_wake_kswapd:
+这些是æ¯ä¸ªåŒºçš„字段,用于确定一个区何时需è¦å¹³è¡¡ã€‚当页颿•°ä½ŽäºŽæ°´ä½[WMARK_MIN]时,
+hysteric 的字段low_on_memoryè¢«è®¾ç½®ã€‚è¿™ä¸ªå­—æ®µä¼šä¸€ç›´è¢«è®¾ç½®ï¼Œç›´åˆ°ç©ºé—²é¡µæ•°å˜æˆæ°´ä½
+[WMARK_HIGH]。当low_on_memory被设置时,页é¢åˆ†é…请求将å°è¯•释放该区域的一些页é¢ï¼ˆå¦‚æžœ
+请求中设置了GFP_WAIT)。与此相å的是,决定唤醒kswapdä»¥é‡Šæ”¾ä¸€äº›åŒºçš„é¡µã€‚è¿™ä¸ªå†³å®šä¸æ˜¯åŸºäºŽ
+hysteresis 的,而是当空闲页的数é‡ä½ŽäºŽwatermark[WMARK_LOW]æ—¶å°±ä¼šè¿›è¡Œï¼›åœ¨è¿™ç§æƒ…况下,
+zone_wake_kswapd也被设置。
+
+
+我所å¬åˆ°çš„(超棒的)想法:
+
+1. 动æ€ç»åŽ†åº”è¯¥å½±å“平衡:å¯ä»¥è·Ÿè¸ªä¸€ä¸ªåŒºçš„失败请求的数é‡ï¼Œå¹¶å馈到平衡方案中(jalvo@mbay.net)。
+
+2. 实现一个类似于replace_with_highmem()çš„replace_with_regular(),以ä¿ç•™dma页é¢ã€‚
+ (lkd@tantalophile.demon.co.uk)
diff --git a/Documentation/translations/zh_CN/vm/damon/api.rst b/Documentation/translations/zh_CN/vm/damon/api.rst
new file mode 100644
index 000000000000..21143eea4ebe
--- /dev/null
+++ b/Documentation/translations/zh_CN/vm/damon/api.rst
@@ -0,0 +1,32 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+:Original: Documentation/vm/damon/api.rst
+
+:翻译:
+
+ å¸å»¶è…¾ Yanteng Si <siyanteng@loongson.cn>
+
+:校译:
+
+
+=======
+APIå‚考
+=======
+
+内核空间的程åºå¯ä»¥ä½¿ç”¨ä¸‹é¢çš„APIæ¥ä½¿ç”¨DAMONçš„æ¯ä¸ªåŠŸèƒ½ã€‚ä½ æ‰€éœ€è¦åšçš„就是引用 ``damon.h`` ,
+它ä½äºŽæºä»£ç æ ‘çš„include/linux/。
+
+结构体
+======
+
+该API在以下内核代ç ä¸­:
+
+include/linux/damon.h
+
+
+函数
+====
+
+该API在以下内核代ç ä¸­:
+
+mm/damon/core.c
diff --git a/Documentation/translations/zh_CN/vm/damon/design.rst b/Documentation/translations/zh_CN/vm/damon/design.rst
new file mode 100644
index 000000000000..05f66c02740a
--- /dev/null
+++ b/Documentation/translations/zh_CN/vm/damon/design.rst
@@ -0,0 +1,139 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+:Original: Documentation/vm/damon/design.rst
+
+:翻译:
+
+ å¸å»¶è…¾ Yanteng Si <siyanteng@loongson.cn>
+
+:校译:
+
+
+====
+设计
+====
+
+å¯é…置的层
+==========
+
+DAMONæä¾›äº†æ•°æ®è®¿é—®ç›‘æŽ§åŠŸèƒ½ï¼ŒåŒæ—¶ä½¿å…¶å‡†ç¡®æ€§å’Œå¼€é”€å¯æŽ§ã€‚基本的访问监控需è¦ä¾èµ–于目标地å€ç©ºé—´
+并为之优化的基元。å¦ä¸€æ–¹é¢ï¼Œä½œä¸ºDAMON的核心,准确性和开销的æƒè¡¡æœºåˆ¶æ˜¯åœ¨çº¯é€»è¾‘空间中。DAMON
+将这两部分分离在ä¸åŒçš„层中,并定义了它的接å£ï¼Œä»¥å…许å„ç§ä½Žå±‚次的基元实现与核心逻辑的é…置。
+
+由于这ç§åˆ†ç¦»çš„设计和å¯é…置的接å£ï¼Œç”¨æˆ·å¯ä»¥é€šè¿‡é…ç½®æ ¸å¿ƒé€»è¾‘å’Œé€‚å½“çš„ä½Žçº§åŸºå…ƒå®žçŽ°æ¥æ‰©å±•DAMONçš„
+任何地å€ç©ºé—´ã€‚如果没有æä¾›åˆé€‚的,用户å¯ä»¥è‡ªå·±å®žçŽ°åŸºå…ƒã€‚
+
+例如,物ç†å†…å­˜ã€è™šæ‹Ÿå†…å­˜ã€äº¤æ¢ç©ºé—´ã€é‚£äº›ç‰¹å®šçš„进程ã€NUMAèŠ‚ç‚¹ã€æ–‡ä»¶å’Œæ”¯æŒçš„内存设备将被支æŒã€‚
+å¦å¤–,如果æŸäº›æž¶æž„或设备支æŒç‰¹æ®Šçš„优化访问检查基元,这些基元将很容易被é…置。
+
+
+特定地å€ç©ºé—´åŸºå…ƒçš„å‚考实现
+==========================
+
+基本访问监测的低级基元被定义为两部分。:
+
+1. 确定地å€ç©ºé—´çš„监测目标地å€èŒƒå›´
+2. 目标空间中特定地å€èŒƒå›´çš„访问检查。
+
+DAMONç›®å‰ä¸ºç‰©ç†å’Œè™šæ‹Ÿåœ°å€ç©ºé—´æä¾›äº†åŸºå…ƒçš„实现。下é¢ä¸¤ä¸ªå°èŠ‚æè¿°äº†è¿™äº›å·¥ä½œçš„æ–¹å¼ã€‚
+
+
+基于VMA的目标地å€èŒƒå›´æž„造
+-------------------------
+
+这仅仅是针对虚拟地å€ç©ºé—´åŸºå…ƒçš„实现。对于物ç†åœ°å€ç©ºé—´ï¼Œåªæ˜¯è¦æ±‚用户手动设置监控目标地å€èŒƒå›´ã€‚
+
+在进程的超级巨大的虚拟地å€ç©ºé—´ä¸­ï¼Œåªæœ‰å°éƒ¨åˆ†è¢«æ˜ å°„到物ç†å†…存并被访问。因此,跟踪未映射的地
+å€åŒºåŸŸåªæ˜¯ä¸€ç§æµªè´¹ã€‚然而,由于DAMONå¯ä»¥ä½¿ç”¨è‡ªé€‚应区域调整机制æ¥å¤„ç†ä¸€å®šç¨‹åº¦çš„噪声,所以严
+æ ¼æ¥è¯´ï¼Œè·Ÿè¸ªæ¯ä¸€ä¸ªæ˜ å°„并䏿˜¯å¿…须的,但在æŸäº›æƒ…况下甚至会产生很高的开销。也就是说,监测目标
+内部过于巨大的未映射区域应该被移除,以ä¸å ç”¨è‡ªé€‚应机制的时间。
+
+å‡ºäºŽè¿™ä¸ªåŽŸå› ï¼Œè¿™ä¸ªå®žçŽ°å°†å¤æ‚的映射转æ¢ä¸ºä¸‰ä¸ªä¸åŒçš„区域,覆盖地å€ç©ºé—´çš„æ¯ä¸ªæ˜ å°„åŒºåŸŸã€‚è¿™ä¸‰ä¸ª
+区域之间的两个空隙是给定地å€ç©ºé—´ä¸­ä¸¤ä¸ªæœ€å¤§çš„æœªæ˜ å°„区域。这两个最大的未映射区域是堆和最上é¢
+çš„mmap()区域之间的间隙,以åŠåœ¨å¤§å¤šæ•°æƒ…况下最下é¢çš„mmap()区域和堆之间的间隙。因为这些间隙
+在通常的地å€ç©ºé—´ä¸­æ˜¯å¼‚常巨大的,排除这些间隙就足以åšå‡ºåˆç†çš„æƒè¡¡ã€‚ä¸‹é¢è¯¦ç»†è¯´æ˜Žäº†è¿™ä¸€ç‚¹::
+
+ <heap>
+ <BIG UNMAPPED REGION 1>
+ <uppermost mmap()-ed region>
+ (small mmap()-ed regions and munmap()-ed regions)
+ <lowermost mmap()-ed region>
+ <BIG UNMAPPED REGION 2>
+ <stack>
+
+
+基于PTE访问ä½çš„访问检查
+-----------------------
+
+物ç†å’Œè™šæ‹Ÿåœ°å€ç©ºé—´çš„实现都使用PTE Accessed-bit进行基本访问检查。唯一的区别在于从地å€ä¸­
+找到相关的PTE访问ä½çš„æ–¹å¼ã€‚虚拟地å€çš„实现是为该地å€çš„目标任务查找页表,而物ç†åœ°å€çš„实现则
+æ˜¯æŸ¥æ‰¾ä¸Žè¯¥åœ°å€æœ‰æ˜ å°„关系的æ¯ä¸€ä¸ªé¡µè¡¨ã€‚é€šè¿‡è¿™ç§æ–¹å¼ï¼Œå®žçŽ°è€…æ‰¾åˆ°å¹¶æ¸…é™¤ä¸‹ä¸€ä¸ªé‡‡æ ·ç›®æ ‡åœ°å€çš„ä½ï¼Œ
+å¹¶æ£€æŸ¥è¯¥ä½æ˜¯å¦åœ¨ä¸€ä¸ªé‡‡æ ·å‘¨æœŸåŽå†æ¬¡è®¾ç½®ã€‚è¿™å¯èƒ½ä¼šå¹²æ‰°å…¶ä»–使用访问ä½çš„内核å­ç³»ç»Ÿï¼Œå³ç©ºé—²é¡µè·Ÿ
+踪和回收逻辑。为了é¿å…è¿™ç§å¹²æ‰°ï¼ŒDAMON使其与空闲页é¢è·Ÿè¸ªç›¸äº’排斥,并使用 ``PG_idle`` å’Œ
+``PG_young`` 页颿 ‡å¿—æ¥è§£å†³ä¸Žå›žæ”¶é€»è¾‘的冲çªï¼Œå°±åƒç©ºé—²é¡µé¢è·Ÿè¸ªé‚£æ ·ã€‚
+
+
+独立于地å€ç©ºé—´çš„æ ¸å¿ƒæœºåˆ¶
+========================
+
+下é¢å››ä¸ªéƒ¨åˆ†åˆ†åˆ«æè¿°äº†DAMONçš„æ ¸å¿ƒæœºåˆ¶å’Œäº”ä¸ªç›‘æµ‹å±žæ€§ï¼Œå³ ``采样间隔`` 〠``èšé›†é—´éš”`` ã€
+``区域更新间隔`` 〠``最å°åŒºåŸŸæ•°`` å’Œ ``最大区域数`` 。
+
+
+访问频率监测
+------------
+
+DAMON的输出显示了在给定的时间内哪些页é¢çš„访问频率是多少。访问频率的分辨率是通过设置
+``采样间隔`` å’Œ ``èšé›†é—´éš”`` æ¥æŽ§åˆ¶çš„ã€‚è¯¦ç»†åœ°è¯´ï¼ŒDAMON检查æ¯ä¸ª ``采样间隔`` 对æ¯
+个页é¢çš„访问,并将结果汇总。æ¢å¥è¯è¯´ï¼Œè®¡ç®—æ¯ä¸ªé¡µé¢çš„访问次数。在æ¯ä¸ª ``èšåˆé—´éš”`` 过
+去åŽï¼ŒDAMON调用先å‰ç”±ç”¨æˆ·æ³¨å†Œçš„回调函数,以便用户å¯ä»¥é˜…读èšåˆçš„结果,然åŽå†æ¸…除这些结
+果。这å¯ä»¥ç”¨ä»¥ä¸‹ç®€å•çš„ä¼ªä»£ç æ¥æè¿°::
+
+ while monitoring_on:
+ for page in monitoring_target:
+ if accessed(page):
+ nr_accesses[page] += 1
+ if time() % aggregation_interval == 0:
+ for callback in user_registered_callbacks:
+ callback(monitoring_target, nr_accesses)
+ for page in monitoring_target:
+ nr_accesses[page] = 0
+ sleep(sampling interval)
+
+è¿™ç§æœºåˆ¶çš„监测开销将éšç€ç›®æ ‡å·¥ä½œè´Ÿè½½è§„模的增长而任æ„增加。
+
+
+基于区域的抽样调查
+------------------
+
+为了é¿å…开销的无é™åˆ¶å¢žåŠ ï¼ŒDAMONå°†å‡å®šå…·æœ‰ç›¸åŒè®¿é—®é¢‘率的相邻页é¢å½’入一个区域。åªè¦ä¿æŒ
+这个å‡è®¾ï¼ˆä¸€ä¸ªåŒºåŸŸå†…的页é¢å…·æœ‰ç›¸åŒçš„访问频率),该区域内就åªéœ€è¦æ£€æŸ¥ä¸€ä¸ªé¡µé¢ã€‚因此,对
+于æ¯ä¸ª ``采样间隔`` ,DAMON在æ¯ä¸ªåŒºåŸŸä¸­éšæœºæŒ‘é€‰ä¸€ä¸ªé¡µé¢ï¼Œç­‰å¾…一个 ``采样间隔`` ,检
+æŸ¥è¯¥é¡µé¢æ˜¯å¦åŒæ—¶è¢«è®¿é—®ï¼Œå¦‚果被访问则增加该区域的访问频率。因此,监测开销是å¯ä»¥é€šè¿‡è®¾ç½®
+åŒºåŸŸçš„æ•°é‡æ¥æŽ§åˆ¶çš„。DAMONå…许用户设置最å°å’Œæœ€å¤§çš„åŒºåŸŸæ•°é‡æ¥è¿›è¡Œæƒè¡¡ã€‚
+
+然而,如果å‡è®¾æ²¡æœ‰å¾—到ä¿è¯ï¼Œè¿™ä¸ªæ–¹æ¡ˆå°±ä¸èƒ½ä¿æŒè¾“出的质é‡ã€‚
+
+
+适应性区域调整
+--------------
+
+å³ä½¿æœ€åˆçš„监测目标区域被很好地构建以满足å‡è®¾ï¼ˆåŒä¸€åŒºåŸŸå†…的页é¢å…·æœ‰ç›¸ä¼¼çš„访问频率),数
+æ®è®¿é—®æ¨¡å¼ä¹Ÿä¼šè¢«åЍæ€åœ°æ”¹å˜ã€‚这将导致监测质é‡ä¸‹é™ã€‚为了尽å¯èƒ½åœ°ä¿æŒå‡è®¾ï¼ŒDAMONæ ¹æ®æ¯ä¸ª
+区域的访问频率自适应地进行åˆå¹¶å’Œæ‹†åˆ†ã€‚
+
+对于æ¯ä¸ª ``èšé›†åŒºé—´`` ,它比较相邻区域的访问频率,如果频率差异较å°ï¼Œå°±åˆå¹¶è¿™äº›åŒºåŸŸã€‚
+ç„¶åŽï¼Œåœ¨å®ƒæŠ¥å‘Šå¹¶æ¸…除æ¯ä¸ªåŒºåŸŸçš„èšåˆæŽ¥å…¥é¢‘率åŽï¼Œå¦‚果区域总数ä¸è¶…过用户指定的最大区域数,
+它将æ¯ä¸ªåŒºåŸŸæ‹†åˆ†ä¸ºä¸¤ä¸ªæˆ–三个区域。
+
+é€šè¿‡è¿™ç§æ–¹å¼ï¼ŒDAMONæä¾›äº†å…¶æœ€ä½³çš„è´¨é‡å’Œæœ€å°çš„å¼€é”€ï¼ŒåŒæ—¶ä¿æŒäº†ç”¨æˆ·ä¸ºå…¶æƒè¡¡è®¾å®šçš„界é™ã€‚
+
+
+动æ€ç›®æ ‡ç©ºé—´æ›´æ–°å¤„ç†
+--------------------
+
+监测目标地å€èŒƒå›´å¯ä»¥åŠ¨æ€æ”¹å˜ã€‚例如,虚拟内存å¯ä»¥åЍæ€åœ°è¢«æ˜ å°„和解映射。物ç†å†…å­˜å¯ä»¥è¢«
+çƒ­æ’æ‹”。
+
+由于在æŸäº›æƒ…况下å˜åŒ–å¯èƒ½ç›¸å½“频ç¹ï¼ŒDAMON检查动æ€å†…存映射的å˜åŒ–,并仅在用户指定的时间
+间隔( ``区域更新间隔`` )内将其应用于抽象的目标区域。
diff --git a/Documentation/translations/zh_CN/vm/damon/faq.rst b/Documentation/translations/zh_CN/vm/damon/faq.rst
new file mode 100644
index 000000000000..07b4ac19407d
--- /dev/null
+++ b/Documentation/translations/zh_CN/vm/damon/faq.rst
@@ -0,0 +1,48 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+:Original: Documentation/vm/damon/faq.rst
+
+:翻译:
+
+ å¸å»¶è…¾ Yanteng Si <siyanteng@loongson.cn>
+
+:校译:
+
+
+========
+常è§é—®é¢˜
+========
+
+为什么是一个新的å­ç³»ç»Ÿï¼Œè€Œä¸æ˜¯æ‰©å±•perf或其他用户空间工具?
+==========================================================
+
+首先,因为它需è¦å°½å¯èƒ½çš„è½»é‡çº§ï¼Œä»¥ä¾¿å¯ä»¥åœ¨çº¿ä½¿ç”¨ï¼Œæ‰€ä»¥åº”该é¿å…任何ä¸å¿…è¦çš„开销,如内核-用户
+ç©ºé—´çš„ä¸Šä¸‹æ–‡åˆ‡æ¢æˆæœ¬ã€‚第二,DAMONçš„ç›®æ ‡æ˜¯è¢«åŒ…æ‹¬å†…æ ¸åœ¨å†…çš„å…¶ä»–ç¨‹åºæ‰€ä½¿ç”¨ã€‚因此,对特定工具
+(如perf)的ä¾èµ–性是ä¸å¯å–的。这就是DAMON在内核空间实现的两个最大的原因。
+
+
+“闲置页é¢è·Ÿè¸ªâ€ 或 “perf mem†å¯ä»¥æ›¿ä»£DAMONå—?
+==============================================
+
+闲置页跟踪是物ç†åœ°å€ç©ºé—´è®¿é—®æ£€æŸ¥çš„一个低层次的原始方法。“perf memâ€ä¹Ÿæ˜¯ç±»ä¼¼çš„,尽管它å¯ä»¥
+使用采样æ¥å‡å°‘开销。å¦ä¸€æ–¹é¢ï¼ŒDAMON是一个更高层次的框架,用于监控å„ç§åœ°å€ç©ºé—´ã€‚它专注于内
+存管ç†ä¼˜åŒ–,并æä¾›å¤æ‚的精度/å¼€é”€å¤„ç†æœºåˆ¶ã€‚因此,“空闲页é¢è·Ÿè¸ªâ€ å’Œ “perf mem†å¯ä»¥æä¾›
+DAMON输出的一个å­é›†ï¼Œä½†ä¸èƒ½æ›¿ä»£DAMON。
+
+
+DAMON是å¦åªæ”¯æŒè™šæ‹Ÿå†…存?
+=========================
+
+ä¸ï¼ŒDAMON的核心是独立于地å€ç©ºé—´çš„。用户å¯ä»¥åœ¨DAMON核心上实现和é…置特定地å€ç©ºé—´çš„低级原始
+éƒ¨åˆ†ï¼ŒåŒ…æ‹¬ç›‘æµ‹ç›®æ ‡åŒºåŸŸçš„æž„é€ å’Œå®žé™…çš„è®¿é—®æ£€æŸ¥ã€‚é€šè¿‡è¿™ç§æ–¹å¼ï¼ŒDAMON用户å¯ä»¥ç”¨ä»»ä½•访问检查技
+术æ¥ç›‘测任何地å€ç©ºé—´ã€‚
+
+尽管如此,DAMON默认为虚拟内存和物ç†å†…å­˜æä¾›äº†åŸºäºŽvma/rmap跟踪和PTEè®¿é—®ä½æ£€æŸ¥çš„地å€ç©ºé—´
+相关功能的实现,以供å‚考和方便使用。
+
+
+我å¯ä»¥ç®€å•地监测页é¢çš„粒度å—?
+==============================
+
+是的,你å¯ä»¥é€šè¿‡è®¾ç½® ``min_nr_regions`` 属性高于工作集大å°é™¤ä»¥é¡µé¢å¤§å°çš„值æ¥å®žçŽ°ã€‚
+因为监视目标区域的大å°è¢«å¼ºåˆ¶ä¸º ``>=page size`` ,所以区域分割ä¸ä¼šäº§ç”Ÿä»»ä½•å½±å“。
diff --git a/Documentation/translations/zh_CN/vm/damon/index.rst b/Documentation/translations/zh_CN/vm/damon/index.rst
new file mode 100644
index 000000000000..84d36d90c9b0
--- /dev/null
+++ b/Documentation/translations/zh_CN/vm/damon/index.rst
@@ -0,0 +1,33 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+:Original: Documentation/vm/damon/index.rst
+
+:翻译:
+
+ å¸å»¶è…¾ Yanteng Si <siyanteng@loongson.cn>
+
+:校译:
+
+
+==========================
+DAMON:æ•°æ®è®¿é—®ç›‘视器
+==========================
+
+DAMON是Linux内核的一个数æ®è®¿é—®ç›‘控框架å­ç³»ç»Ÿã€‚DAMON的核心机制使其æˆä¸º
+(该核心机制详è§(Documentation/translations/zh_CN/vm/damon/design.rst))
+
+ - *准确度* (监测输出对DRAM级别的内存管ç†è¶³å¤Ÿæœ‰ç”¨ï¼›ä½†å¯èƒ½ä¸é€‚åˆCPU Cache级别),
+ - *è½»é‡çº§* (监控开销低到å¯ä»¥åœ¨çº¿åº”用),以åŠ
+ - *坿‰©å±•* (无论目标工作负载的大å°ï¼Œå¼€é”€çš„上é™å€¼éƒ½åœ¨æ’定范围内)。
+
+å› æ­¤ï¼Œåˆ©ç”¨è¿™ä¸ªæ¡†æž¶ï¼Œå†…æ ¸çš„å†…å­˜ç®¡ç†æœºåˆ¶å¯ä»¥åšå‡ºé«˜çº§å†³ç­–。会导致高数æ®è®¿é—®ç›‘控开销的实
+验性内存管ç†ä¼˜åŒ–工作å¯ä»¥å†æ¬¡è¿›è¡Œã€‚åŒæ—¶ï¼Œåœ¨ç”¨æˆ·ç©ºé—´ï¼Œæœ‰ä¸€äº›ç‰¹æ®Šå·¥ä½œè´Ÿè½½çš„用户å¯ä»¥ç¼–写
+个性化的应用程åºï¼Œä»¥ä¾¿æ›´å¥½åœ°äº†è§£å’Œä¼˜åŒ–他们的工作负载和系统。
+
+.. toctree::
+ :maxdepth: 2
+
+ faq
+ design
+ api
+
diff --git a/Documentation/translations/zh_CN/vm/free_page_reporting.rst b/Documentation/translations/zh_CN/vm/free_page_reporting.rst
new file mode 100644
index 000000000000..31d6c34b956b
--- /dev/null
+++ b/Documentation/translations/zh_CN/vm/free_page_reporting.rst
@@ -0,0 +1,38 @@
+.. include:: ../disclaimer-zh_CN.rst
+
+:Original: Documentation/vm/_free_page_reporting.rst
+
+:翻译:
+
+ å¸å»¶è…¾ Yanteng Si <siyanteng@loongson.cn>
+
+:校译:
+
+==========
+空闲页报告
+==========
+
+空闲页报告是一个API,设备å¯ä»¥é€šè¿‡å®ƒæ¥æ³¨å†ŒæŽ¥æ”¶ç³»ç»Ÿå½“剿œªä½¿ç”¨çš„页é¢åˆ—表。这在虚拟
+åŒ–çš„æƒ…å†µä¸‹æ˜¯å¾ˆæœ‰ç”¨çš„ï¼Œå®¢æˆ·æœºèƒ½å¤Ÿä½¿ç”¨è¿™äº›æ•°æ®æ¥é€šçŸ¥ç®¡ç†å™¨å®ƒä¸å†ä½¿ç”¨å†…存中的æŸäº›é¡µ
+é¢ã€‚
+
+对于驱动,通常是气çƒé©±åЍè¦ä½¿ç”¨è¿™ä¸ªåŠŸèƒ½ï¼Œå®ƒå°†åˆ†é…å’Œåˆå§‹åŒ–一个page_reporting_dev_info
+结构体。它è¦å¡«å……çš„ç»“æž„ä½“ä¸­çš„å­—æ®µæ˜¯ç”¨äºŽå¤„ç†æ•£ç‚¹åˆ—表的 "report" 函数指针。它还必
+é¡»ä¿è¯æ¯æ¬¡è°ƒç”¨è¯¥å‡½æ•°æ—¶èƒ½å¤„ç†è‡³å°‘相当于PAGE_REPORTING_CAPACITY的散点列表æ¡ç›®ã€‚
+å‡è®¾æ²¡æœ‰å…¶ä»–é¡µé¢æŠ¥å‘Šè®¾å¤‡å·²ç»æ³¨å†Œï¼Œ 对page_reporting_registerçš„è°ƒç”¨å°†å‘æŠ¥å‘Šæ¡†
+æž¶æ³¨å†Œé¡µé¢æŠ¥å‘ŠæŽ¥å£ã€‚
+
+ä¸€æ—¦æ³¨å†Œï¼Œé¡µé¢æŠ¥å‘ŠAPI将开始å‘é©±åŠ¨æŠ¥å‘Šæˆæ‰¹çš„页é¢ã€‚API将在接å£è¢«æ³¨å†ŒåŽ2秒开始报告
+页é¢ï¼Œå¹¶åœ¨ä»»ä½•足够高的页é¢è¢«é‡Šæ”¾ä¹‹åŽ2秒继续报告。
+
+报告的页é¢å°†è¢«å­˜å‚¨åœ¨ä¼ é€’给报告函数的散列表中,最åŽä¸€ä¸ªæ¡ç›®çš„结æŸä½è¢«è®¾ç½®åœ¨æ¡ç›®
+nent-1中。 当页é¢è¢«æŠ¥å‘Šå‡½æ•°å¤„ç†æ—¶ï¼Œåˆ†é…器将无法访问它们。一旦报告函数完æˆï¼Œè¿™äº›
+页将被返回到它们所获得的自由区域。
+
+在移除使用空闲页报告的驱动之å‰ï¼Œæœ‰å¿…è¦è°ƒç”¨page_reporting_unregister,以移除
+ç›®å‰è¢«ç©ºé—²é¡µæŠ¥å‘Šä½¿ç”¨çš„page_reporting_dev_info结构体。这样åšå°†é˜»æ­¢è¿›ä¸€æ­¥çš„æŠ¥
+告通过该接å£å‘出。如果å¦ä¸€ä¸ªé©±åŠ¨æˆ–åŒä¸€é©±åŠ¨è¢«æ³¨å†Œï¼Œå®ƒå°±æœ‰å¯èƒ½æ¢å¤å‰ä¸€ä¸ªé©±åŠ¨åœ¨æŠ¥å‘Š
+空闲页方é¢çš„工作。
+
+
+Alexander Duyck, 2019年12月04日
diff --git a/Documentation/translations/zh_CN/vm/highmem.rst b/Documentation/translations/zh_CN/vm/highmem.rst
new file mode 100644
index 000000000000..018838e58c3e
--- /dev/null
+++ b/Documentation/translations/zh_CN/vm/highmem.rst
@@ -0,0 +1,128 @@
+.. include:: ../disclaimer-zh_CN.rst
+
+:Original: Documentation/vm/highmem.rst
+
+:翻译:
+
+ å¸å»¶è…¾ Yanteng Si <siyanteng@loongson.cn>
+
+:校译:
+
+==========
+高内存处ç†
+==========
+
+作者: Peter Zijlstra <a.p.zijlstra@chello.nl>
+
+.. contents:: :local:
+
+高内存是什么?
+==============
+
+当物ç†å†…å­˜çš„å¤§å°æŽ¥è¿‘æˆ–è¶…è¿‡è™šæ‹Ÿå†…å­˜çš„æœ€å¤§å¤§å°æ—¶ï¼Œå°±ä¼šä½¿ç”¨é«˜å†…存(highmem)。在这一点上,内
+æ ¸ä¸å¯èƒ½åœ¨ä»»ä½•æ—¶å€™éƒ½ä¿æŒæ‰€æœ‰å¯ç”¨çš„物ç†å†…存的映射。这æ„味ç€å†…核需è¦å¼€å§‹ä½¿ç”¨å®ƒæƒ³è®¿é—®çš„物ç†å†…
+存的临时映射。
+
+没有被永久映射覆盖的那部分(物ç†ï¼‰å†…存就是我们所说的 "高内存"。对于这个边界的确切ä½ç½®ï¼Œæœ‰
+å„ç§æž¶æž„上的é™åˆ¶ã€‚
+
+例如,在i386架构中,我们选择将内核映射到æ¯ä¸ªè¿›ç¨‹çš„虚拟空间,这样我们就ä¸å¿…为内核的进入/退
+出付出全部的TLB作废代价。这æ„味ç€å¯ç”¨çš„虚拟内存空间(i386上为4GiB)必须在用户和内核空间之
+间进行划分。
+
+ä½¿ç”¨è¿™ç§æ–¹æ³•çš„æž¶æž„çš„ä¼ ç»Ÿåˆ†é…æ–¹å¼æ˜¯3:1,3GiB用于用户空间,顶部的1GiB用于内核空间。::
+
+ +--------+ 0xffffffff
+ | Kernel |
+ +--------+ 0xc0000000
+ | |
+ | User |
+ | |
+ +--------+ 0x00000000
+
+è¿™æ„味ç€å†…核在任何时候最多å¯ä»¥æ˜ å°„1GiB的物ç†å†…存,但是由于我们需è¦è™šæ‹Ÿåœ°å€ç©ºé—´æ¥åšå…¶ä»–事
+情--包括访问其余物ç†å†…存的临时映射--实际的直接映射通常会更少(通常在~896MiBå·¦å³ï¼‰ã€‚
+
+其他有mm上下文标签的TLB的架构å¯ä»¥æœ‰ç‹¬ç«‹çš„内核和用户映射。然而,一些硬件(如一些ARM)在使
+用mm上下文标签时,其虚拟空间有é™ã€‚
+
+
+临时虚拟映射
+============
+
+内核包å«å‡ ç§åˆ›å»ºä¸´æ—¶æ˜ å°„的方法。:
+
+* vmap(). è¿™å¯ä»¥ç”¨æ¥å°†å¤šä¸ªç‰©ç†é¡µé•¿æœŸæ˜ å°„到一个连续的虚拟空间。它需è¦synchronization
+ æ¥è§£é™¤æ˜ å°„。
+
+* kmap(). è¿™å…许对å•个页é¢è¿›è¡ŒçŸ­æœŸæ˜ å°„。它需è¦synchronization,但在一定程度上被摊销。
+ 当以嵌套方å¼ä½¿ç”¨æ—¶ï¼Œå®ƒä¹Ÿå¾ˆå®¹æ˜“出现死é”,因此ä¸å»ºè®®åœ¨æ–°ä»£ç ä¸­ä½¿ç”¨å®ƒã€‚
+
+* kmap_atomic(). è¿™å…许对å•个页é¢è¿›è¡Œéžå¸¸çŸ­çš„æ—¶é—´æ˜ å°„。由于映射被é™åˆ¶åœ¨å‘布它的CPU上,
+ 它表现得很好,但å‘å¸ƒä»»åŠ¡å› æ­¤è¢«è¦æ±‚留在该CPU上直到它完æˆï¼Œä»¥å…其他任务å–代它的映射。
+
+ kmap_atomic() 也å¯ä»¥ç”±ä¸­æ–­ä¸Šä¸‹æ–‡ä½¿ç”¨ï¼Œå› ä¸ºå®ƒä¸ç¡çœ ï¼Œè€Œä¸”调用者å¯èƒ½åœ¨è°ƒç”¨kunmap_atomic()
+ ä¹‹åŽæ‰ç¡çœ ã€‚
+
+ å¯ä»¥å‡è®¾k[un]map_atomic()ä¸ä¼šå¤±è´¥ã€‚
+
+
+使用kmap_atomic
+===============
+
+何时何地使用 kmap_atomic() æ˜¯å¾ˆç›´æŽ¥çš„ã€‚å½“ä»£ç æƒ³è¦è®¿é—®ä¸€ä¸ªå¯èƒ½ä»Žé«˜å†…存(è§__GFP_HIGHMEM)
+分é…的页é¢çš„内容时,例如在页缓存中的页é¢ï¼Œå°±ä¼šä½¿ç”¨å®ƒã€‚该API有两个函数,它们的使用方å¼ä¸Ž
+下é¢ç±»ä¼¼::
+
+ /* 找到感兴趣的页é¢ã€‚ */
+ struct page *page = find_get_page(mapping, offset);
+
+ /* 获得对该页内容的访问æƒã€‚ */
+ void *vaddr = kmap_atomic(page);
+
+ /* 对该页的内容åšä¸€äº›å¤„ç†ã€‚ */
+ memset(vaddr, 0, PAGE_SIZE);
+
+ /* 解除该页é¢çš„æ˜ å°„。 */
+ kunmap_atomic(vaddr);
+
+注æ„,kunmap_atomic()调用的是kmap_atomic()è°ƒç”¨çš„ç»“æžœè€Œä¸æ˜¯å‚数。
+
+å¦‚æžœä½ éœ€è¦æ˜ å°„两个页é¢ï¼Œå› ä¸ºä½ æƒ³ä»Žä¸€ä¸ªé¡µé¢å¤åˆ¶åˆ°å¦ä¸€ä¸ªé¡µé¢ï¼Œä½ éœ€è¦ä¿æŒkmap_atomic调用严
+格嵌套,如::
+
+ vaddr1 = kmap_atomic(page1);
+ vaddr2 = kmap_atomic(page2);
+
+ memcpy(vaddr1, vaddr2, PAGE_SIZE);
+
+ kunmap_atomic(vaddr2);
+ kunmap_atomic(vaddr1);
+
+
+ä¸´æ—¶æ˜ å°„çš„æˆæœ¬
+==============
+
+创建临时映射的代价å¯èƒ½ç›¸å½“高。体系架构必须æ“ä½œå†…æ ¸çš„é¡µè¡¨ã€æ•°æ®TLBå’Œ/或MMU的寄存器。
+
+如果CONFIG_HIGHMEM没有被设置,那么内核会å°è¯•用一点计算æ¥åˆ›å»ºæ˜ å°„,将页é¢ç»“构地å€è½¬æ¢æˆ
+指å‘页é¢å†…å®¹çš„æŒ‡é’ˆï¼Œè€Œä¸æ˜¯åŽ»æ£é¼“æ˜ å°„ã€‚åœ¨è¿™ç§æƒ…况下,解映射æ“作å¯èƒ½æ˜¯ä¸€ä¸ªç©ºæ“作。
+
+如果CONFIG_MMU没有被设置,那么就ä¸å¯èƒ½æœ‰ä¸´æ—¶æ˜ å°„å’Œé«˜å†…å­˜ã€‚åœ¨è¿™ç§æƒ…况下,也将使用计算方法。
+
+
+i386 PAE
+========
+
+在æŸäº›æƒ…况下,i386 架构将å…许你在 32 使œºå™¨ä¸Šå®‰è£…多达 64GiB çš„å†…å­˜ã€‚ä½†è¿™æœ‰ä¸€äº›åŽæžœ:
+
+* Linux需è¦ä¸ºç³»ç»Ÿä¸­çš„æ¯ä¸ªé¡µé¢å»ºç«‹ä¸€ä¸ªé¡µå¸§ç»“构,而且页帧需è¦é©»åœ¨æ°¸ä¹…映射中,这æ„味ç€ï¼š
+
+* 你最多å¯ä»¥æœ‰896M/sizeof(struct page)页帧;由于页结构体是32字节的,所以最终会有
+ 112G的页;然而,内核需è¦åœ¨å†…存中存储更多的页帧......
+
+* PAE使你的页表å˜å¤§--è¿™ä½¿ç³»ç»Ÿå˜æ…¢ï¼Œå› ä¸ºæ›´å¤šçš„æ•°æ®éœ€è¦åœ¨TLB填充等方é¢è¢«è®¿é—®ã€‚一个好处
+ 是,PAE有更多的PTEä½ï¼Œå¯ä»¥æä¾›åƒNXå’ŒPAT这样的高级功能。
+
+一般的建议是,你ä¸è¦åœ¨32使œºå™¨ä¸Šä½¿ç”¨è¶…过8GiB的空间--尽管更多的空间å¯èƒ½å¯¹ä½ å’Œä½ çš„工作
+釿œ‰ç”¨ï¼Œä½†ä½ å‡ ä¹Žæ˜¯é ä½ è‡ªå·±--ä¸è¦æŒ‡æœ›å†…核开å‘者真的会很关心事情的进展情况。
diff --git a/Documentation/translations/zh_CN/vm/index.rst b/Documentation/translations/zh_CN/vm/index.rst
new file mode 100644
index 000000000000..a1d2f0356cc1
--- /dev/null
+++ b/Documentation/translations/zh_CN/vm/index.rst
@@ -0,0 +1,53 @@
+.. include:: ../disclaimer-zh_CN.rst
+
+:Original: Documentation/vm/index.rst
+
+:翻译:
+
+ å¸å»¶è…¾ Yanteng Si <siyanteng@loongson.cn>
+
+:校译:
+
+=================
+Linuxå†…å­˜ç®¡ç†æ–‡æ¡£
+=================
+
+这是一个关于Linux内存管ç†ï¼ˆmm)å­ç³»ç»Ÿå†…部的文档集,其中有ä¸åŒå±‚次的细节,包括注释
+和邮件列表的回å¤ï¼Œç”¨äºŽé˜è¿°æ•°æ®ç»“构和算法的基本情况。如果你正在寻找关于简å•分é…内存的建
+议,请å‚阅(Documentation/translations/zh_CN/core-api/memory-allocation.rst)。
+对于控制和调整指å—,请å‚阅(Documentation/admin-guide/mm/index)。
+TODO:待引用文档集被翻译完毕åŽè¯·åŠæ—¶ä¿®æ”¹æ­¤å¤„)
+
+.. toctree::
+ :maxdepth: 1
+
+ active_mm
+ balance
+ damon/index
+ free_page_reporting
+ highmem
+ ksm
+
+TODOLIST:
+* arch_pgtable_helpers
+* free_page_reporting
+* frontswap
+* hmm
+* hwpoison
+* hugetlbfs_reserv
+* memory-model
+* mmu_notifier
+* numa
+* overcommit-accounting
+* page_migration
+* page_frags
+* page_owner
+* page_table_check
+* remap_file_pages
+* slub
+* split_page_table_lock
+* transhuge
+* unevictable-lru
+* vmalloced-kernel-stacks
+* z3fold
+* zsmalloc
diff --git a/Documentation/translations/zh_CN/vm/ksm.rst b/Documentation/translations/zh_CN/vm/ksm.rst
new file mode 100644
index 000000000000..83b0c73984da
--- /dev/null
+++ b/Documentation/translations/zh_CN/vm/ksm.rst
@@ -0,0 +1,70 @@
+.. include:: ../disclaimer-zh_CN.rst
+
+:Original: Documentation/vm/ksm.rst
+
+:翻译:
+
+ å¾é‘« xu xin <xu.xin16@zte.com.cn>
+
+============
+内核åŒé¡µåˆå¹¶
+============
+
+KSM 是一ç§èŠ‚çœå†…存的数æ®åŽ»é‡åŠŸèƒ½ï¼Œç”±CONFIG_KSM=yå¯ç”¨ï¼Œå¹¶åœ¨2.6.32版本时被添加
+到Linuxå†…æ ¸ã€‚è¯¦è§ ``mm/ksm.c`` 的实现,以åŠhttp://lwn.net/Articles/306704å’Œ
+https://lwn.net/Articles/330589
+
+KSM的用户空间的接å£åœ¨Documentation/translations/zh_CN/admin-guide/mm/ksm.rst
+文档中有æè¿°ã€‚
+
+设计
+====
+
+概述
+----
+
+概述内容请è§mm/ksm.c文档中的“DOC: Overviewâ€
+
+逆映射
+------
+KSM维护ç€ç¨³å®šæ ‘中的KSM页的逆映射信æ¯ã€‚
+
+当KSM页é¢çš„共享数å°äºŽ ``max_page_sharing`` 的虚拟内存区域(VMAs)时,则代表了
+KSM页的稳定树其中的节点指å‘了一个rmap_itemç»“æž„ä½“ç±»åž‹çš„åˆ—è¡¨ã€‚åŒæ—¶ï¼Œè¿™ä¸ªKSM页
+çš„ ``page->mapping`` 指å‘了该稳定树节点。
+
+如果共享数超过了阈值,KSMå°†ç»™ç¨³å®šæ ‘æ·»åŠ ç¬¬äºŒä¸ªç»´åº¦ã€‚ç¨³å®šæ ‘å°±å˜æˆé“¾æŽ¥ä¸€ä¸ªæˆ–多
+个稳定树"副本"çš„"链"。æ¯ä¸ªå‰¯æœ¬éƒ½ä¿ç•™KSM页的逆映射信æ¯ï¼Œå…¶ä¸­ ``page->mapping``
+指å‘该"副本"。
+
+æ¯ä¸ªé“¾ä»¥åŠé“¾æŽ¥åˆ°è¯¥é“¾ä¸­çš„æ‰€æœ‰"副本"强制ä¸å˜çš„æ˜¯ï¼Œå®ƒä»¬ä»£è¡¨äº†ç›¸åŒçš„å†™ä¿æŠ¤å†…å­˜
+内容,尽管任中一个"副本"是由åŒä¸€ç‰‡å†…存区的ä¸åŒçš„KSMå¤åˆ¶é¡µæ‰€æŒ‡å‘的。
+
+这样一æ¥ï¼Œç›¸æ¯”与无é™çš„é€†æ˜ å°„é“¾è¡¨ï¼Œç¨³å®šæ ‘çš„æŸ¥æ‰¾è®¡ç®—å¤æ‚性ä¸å—å½±å“。但在稳定树
+本身中ä¸èƒ½æœ‰é‡å¤çš„KSM页é¢å†…容ä»ç„¶æ˜¯å¼ºåˆ¶è¦æ±‚。
+
+ç”± ``max_page_sharing`` 强制决定的数æ®åŽ»é‡é™åˆ¶æ˜¯å¿…è¦çš„,以此æ¥é¿å…虚拟内存
+rmap链表å˜å¾—过大。rmapçš„é历具有O(N)çš„å¤æ‚度,其中N是共享页é¢çš„rmap_项(å³
+虚拟映射)的数é‡ï¼Œè€Œè¿™ä¸ªå…±äº«é¡µé¢çš„节点数é‡åˆè¢« ``max_page_sharing`` 所é™åˆ¶ã€‚
+因此,这有效地将线性O(N)è®¡ç®—å¤æ‚度从rmapé历中分散到ä¸åŒçš„KSM页é¢ä¸Šã€‚ksmdè¿›
+程在稳定节点"链"上的é历也是O(N),但这个N是稳定树"副本"的数é‡ï¼Œè€Œä¸æ˜¯rmap项
+的数é‡ï¼Œå› æ­¤å®ƒå¯¹ksmd性能没有显著影å“。实际上,最佳稳定树"副本"的候选节点将
+ä¿ç•™åœ¨"副本"列表的开头。
+
+``max_page_sharing`` 的值设置得高了会促使更快的内存åˆå¹¶ï¼ˆå› ä¸ºå°†æœ‰æ›´å°‘的稳定
+树副本排队进入稳定节点chain->hlist)和更高的数æ®åŽ»é‡ç³»æ•°ï¼Œä½†ä»£ä»·æ˜¯åœ¨äº¤æ¢ã€åŽ‹
+缩ã€NUMA平衡和页é¢è¿ç§»è¿‡ç¨‹ä¸­å¯èƒ½å¯¼è‡´KSM页的最大rmapé历速度较慢。
+
+``stable_node_dups/stable_node_chains`` çš„æ¯”å€¼è¿˜å— ``max_page_sharing`` 调控
+的影å“,高比值å¯èƒ½æ„味ç€ç¨³å®šèŠ‚ç‚¹dup中存在碎片,这å¯ä»¥é€šè¿‡åœ¨ksmd中引入碎片算
+法æ¥è§£å†³ï¼Œè¯¥ç®—法将rmap项从一个稳定节点dupé‡å®šä½åˆ°å¦ä¸€ä¸ªç¨³å®šèŠ‚ç‚¹dup,以便释放
+é‚£äº›ä»…åŒ…å«æžå°‘rmap项的稳定节点"dup",但这å¯èƒ½ä¼šå¢žåŠ ksmd进程的CPU使用率,并å¯
+èƒ½ä¼šå‡æ…¢åº”用程åºåœ¨KSM页é¢ä¸Šçš„åªè¯»è®¡ç®—。
+
+KSM会定期扫æç¨³å®šèŠ‚ç‚¹"链"中链接的所有稳定树"副本",以便删å‡è¿‡æ—¶äº†çš„稳定节点。
+è¿™ç§æ‰«æçš„频率由 ``stable_node_chains_prune_millisecs`` 这个sysfs 接å£å®šä¹‰ã€‚
+
+å‚考
+====
+内核代ç è¯·è§mm/ksm.c。
+涉åŠçš„函数(mm_slot ksm_scan stable_node rmap_item)。
diff --git a/Documentation/translations/zh_TW/index.rst b/Documentation/translations/zh_TW/index.rst
index f56f78ba7860..e1ce9d8c06f8 100644
--- a/Documentation/translations/zh_TW/index.rst
+++ b/Documentation/translations/zh_TW/index.rst
@@ -5,7 +5,7 @@
\renewcommand\thesection*
\renewcommand\thesubsection*
\kerneldocCJKon
- \kerneldocBeginTC
+ \kerneldocBeginTC{
.. _linux_doc_zh_tw:
@@ -174,4 +174,4 @@ TODOList:
.. raw:: latex
- \kerneldocEndTC
+ }\kerneldocEndTC
diff --git a/Documentation/userspace-api/ioctl/ioctl-number.rst b/Documentation/userspace-api/ioctl/ioctl-number.rst
index 687efcf245c1..dfbc27d17ff7 100644
--- a/Documentation/userspace-api/ioctl/ioctl-number.rst
+++ b/Documentation/userspace-api/ioctl/ioctl-number.rst
@@ -115,6 +115,7 @@ Code Seq# Include File Comments
'B' 00-1F linux/cciss_ioctl.h conflict!
'B' 00-0F include/linux/pmu.h conflict!
'B' C0-FF advanced bbus <mailto:maassen@uni-freiburg.de>
+'B' 00-0F xen/xenbus_dev.h conflict!
'C' all linux/soundcard.h conflict!
'C' 01-2F linux/capi.h conflict!
'C' F0-FF drivers/net/wan/cosa.h conflict!
@@ -134,6 +135,7 @@ Code Seq# Include File Comments
'F' 80-8F linux/arcfb.h conflict!
'F' DD video/sstfb.h conflict!
'G' 00-3F drivers/misc/sgi-gru/grulib.h conflict!
+'G' 00-0F xen/gntalloc.h, xen/gntdev.h conflict!
'H' 00-7F linux/hiddev.h conflict!
'H' 00-0F linux/hidraw.h conflict!
'H' 01 linux/mei.h conflict!
@@ -176,6 +178,7 @@ Code Seq# Include File Comments
'P' 60-6F sound/sscape_ioctl.h conflict!
'P' 00-0F drivers/usb/class/usblp.c conflict!
'P' 01-09 drivers/misc/pci_endpoint_test.c conflict!
+'P' 00-0F xen/privcmd.h conflict!
'Q' all linux/soundcard.h
'R' 00-1F linux/random.h conflict!
'R' 01 linux/rfkill.h conflict!
@@ -253,7 +256,7 @@ Code Seq# Include File Comments
'l' 00-3F linux/tcfs_fs.h transparent cryptographic file system
<http://web.archive.org/web/%2A/http://mikonos.dia.unisa.it/tcfs>
'l' 40-7F linux/udf_fs_i.h in development:
- <http://sourceforge.net/projects/linux-udf/>
+ <https://github.com/pali/udftools>
'm' 00-09 linux/mmtimer.h conflict!
'm' all linux/mtio.h conflict!
'm' all linux/soundcard.h conflict!
diff --git a/Documentation/userspace-api/media/lirc.h.rst.exceptions b/Documentation/userspace-api/media/lirc.h.rst.exceptions
index ec86e82d026d..913d17b49831 100644
--- a/Documentation/userspace-api/media/lirc.h.rst.exceptions
+++ b/Documentation/userspace-api/media/lirc.h.rst.exceptions
@@ -11,12 +11,14 @@ ignore define LIRC_SPACE
ignore define LIRC_PULSE
ignore define LIRC_FREQUENCY
ignore define LIRC_TIMEOUT
+ignore define LIRC_OVERFLOW
ignore define LIRC_VALUE
ignore define LIRC_MODE2
ignore define LIRC_IS_SPACE
ignore define LIRC_IS_PULSE
ignore define LIRC_IS_FREQUENCY
ignore define LIRC_IS_TIMEOUT
+ignore define LIRC_IS_OVERFLOW
ignore define LIRC_MODE2SEND
ignore define LIRC_SEND2MODE
@@ -28,7 +30,6 @@ ignore define LIRC_CAN_REC
ignore define LIRC_CAN_SEND_MASK
ignore define LIRC_CAN_REC_MASK
-ignore define LIRC_CAN_SET_REC_DUTY_CYCLE
# Obsolete ioctls
@@ -75,6 +76,7 @@ ignore define PULSE_MASK
ignore define LIRC_MODE2_SPACE
ignore define LIRC_MODE2_PULSE
ignore define LIRC_MODE2_TIMEOUT
+ignore define LIRC_MODE2_OVERFLOW
ignore define LIRC_VALUE_MASK
ignore define LIRC_MODE2_MASK
diff --git a/Documentation/userspace-api/media/rc/lirc-dev-intro.rst b/Documentation/userspace-api/media/rc/lirc-dev-intro.rst
index 9a5e5f0aae11..d899331b943f 100644
--- a/Documentation/userspace-api/media/rc/lirc-dev-intro.rst
+++ b/Documentation/userspace-api/media/rc/lirc-dev-intro.rst
@@ -103,11 +103,11 @@ on the following table.
``LIRC_MODE2_PULSE``
- Signifies the presence of IR in microseconds.
+ Signifies the presence of IR in microseconds, also known as *flash*.
``LIRC_MODE2_SPACE``
- Signifies absence of IR in microseconds.
+ Signifies absence of IR in microseconds, also known as *gap*.
``LIRC_MODE2_FREQUENCY``
@@ -121,6 +121,13 @@ on the following table.
to no IR being detected, this packet will be sent, with the number
of microseconds with no IR.
+ ``LIRC_MODE2_OVERFLOW``
+
+ Signifies that the IR receiver encounter an overflow, and some IR
+ is missing. The IR data after this should be correct again. The
+ actual value is not important, but this is set to 0xffffff by the
+ kernel for compatibility with lircd.
+
.. _lirc-mode-pulse:
``LIRC_MODE_PULSE``
diff --git a/Documentation/userspace-api/media/rc/lirc-get-features.rst b/Documentation/userspace-api/media/rc/lirc-get-features.rst
index 4bf25860f932..545137620ead 100644
--- a/Documentation/userspace-api/media/rc/lirc-get-features.rst
+++ b/Documentation/userspace-api/media/rc/lirc-get-features.rst
@@ -102,12 +102,6 @@ LIRC features
The driver supports setting the receive carrier frequency using
:ref:`ioctl LIRC_SET_REC_CARRIER <LIRC_SET_REC_CARRIER>`.
-.. _LIRC-CAN-SET-REC-DUTY-CYCLE-RANGE:
-
-``LIRC_CAN_SET_REC_DUTY_CYCLE_RANGE``
-
- Unused. Kept just to avoid breaking uAPI.
-
.. _LIRC-CAN-SET-REC-CARRIER-RANGE:
``LIRC_CAN_SET_REC_CARRIER_RANGE``
@@ -129,12 +123,6 @@ LIRC features
The driver supports
:ref:`ioctl LIRC_SET_REC_TIMEOUT <LIRC_SET_REC_TIMEOUT>`.
-.. _LIRC-CAN-SET-REC-FILTER:
-
-``LIRC_CAN_SET_REC_FILTER``
-
- Unused. Kept just to avoid breaking uAPI.
-
.. _LIRC-CAN-MEASURE-CARRIER:
``LIRC_CAN_MEASURE_CARRIER``
@@ -149,12 +137,6 @@ LIRC features
The driver supports learning mode using
:ref:`ioctl LIRC_SET_WIDEBAND_RECEIVER <LIRC_SET_WIDEBAND_RECEIVER>`.
-.. _LIRC-CAN-NOTIFY-DECODE:
-
-``LIRC_CAN_NOTIFY_DECODE``
-
- Unused. Kept just to avoid breaking uAPI.
-
.. _LIRC-CAN-SEND-RAW:
``LIRC_CAN_SEND_RAW``
diff --git a/Documentation/userspace-api/media/v4l/ext-ctrls-codec-stateless.rst b/Documentation/userspace-api/media/v4l/ext-ctrls-codec-stateless.rst
index cc080c4257d0..6541e4c32b26 100644
--- a/Documentation/userspace-api/media/v4l/ext-ctrls-codec-stateless.rst
+++ b/Documentation/userspace-api/media/v4l/ext-ctrls-codec-stateless.rst
@@ -616,6 +616,12 @@ Stateless Codec Control ID
* - ``V4L2_H264_DECODE_PARAM_FLAG_BOTTOM_FIELD``
- 0x00000004
-
+ * - ``V4L2_H264_DECODE_PARAM_FLAG_PFRAME``
+ - 0x00000008
+ -
+ * - ``V4L2_H264_DECODE_PARAM_FLAG_BFRAME``
+ - 0x00000010
+ -
.. raw:: latex
@@ -1692,7 +1698,12 @@ See section '7.3.1 Tx mode semantics' of the :ref:`vp9` specification for more d
* - __u8
- ``reference_mode``
- Specifies the type of inter prediction to be used. See
- :ref:`Reference Mode<vp9_reference_mode>` for more details.
+ :ref:`Reference Mode<vp9_reference_mode>` for more details. Note that
+ this is derived as part of the compressed header parsing process and
+ for this reason should have been part of
+ :c:type: `v4l2_ctrl_vp9_compressed_hdr` optional control. It is safe to
+ set this value to zero if the driver does not require compressed
+ headers.
* - __u8
- ``reserved[7]``
- Applications and drivers must set this to zero.
diff --git a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst
index e141f0e4eec9..4cd7c541fc30 100644
--- a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst
+++ b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst
@@ -3166,11 +3166,11 @@ enum v4l2_mpeg_video_hevc_size_of_length_field -
:c:func:`v4l2_timeval_to_ns()` function to convert the struct
:c:type:`timeval` in struct :c:type:`v4l2_buffer` to a __u64.
* - __u8
- - ``rps``
- - The reference set for the reference frame
- (V4L2_HEVC_DPB_ENTRY_RPS_ST_CURR_BEFORE,
- V4L2_HEVC_DPB_ENTRY_RPS_ST_CURR_AFTER or
- V4L2_HEVC_DPB_ENTRY_RPS_LT_CURR)
+ - ``flags``
+ - Long term flag for the reference frame
+ (V4L2_HEVC_DPB_ENTRY_LONG_TERM_REFERENCE). The flag is set as
+ described in the ITU HEVC specification chapter "8.3.2 Decoding
+ process for reference picture set".
* - __u8
- ``field_pic``
- Whether the reference is a field picture or a frame.
@@ -3383,15 +3383,15 @@ enum v4l2_mpeg_video_hevc_size_of_length_field -
* - __u8
- ``poc_st_curr_before[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]``
- PocStCurrBefore as described in section 8.3.2 "Decoding process for reference
- picture set.
+ picture set": provides the index of the short term before references in DPB array.
* - __u8
- ``poc_st_curr_after[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]``
- PocStCurrAfter as described in section 8.3.2 "Decoding process for reference
- picture set.
+ picture set": provides the index of the short term after references in DPB array.
* - __u8
- ``poc_lt_curr[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]``
- PocLtCurr as described in section 8.3.2 "Decoding process for reference
- picture set.
+ picture set": provides the index of the long term references in DPB array.
* - __u64
- ``flags``
- See :ref:`Decode Parameters Flags <hevc_decode_params_flags>`
diff --git a/Documentation/userspace-api/media/v4l/pixfmt-reserved.rst b/Documentation/userspace-api/media/v4l/pixfmt-reserved.rst
index 2f2133b4cd9c..cabfa34b7db5 100644
--- a/Documentation/userspace-api/media/v4l/pixfmt-reserved.rst
+++ b/Documentation/userspace-api/media/v4l/pixfmt-reserved.rst
@@ -233,19 +233,12 @@ please make a proposal on the linux-media mailing list.
- ``V4L2_PIX_FMT_MT21C``
- 'MT21'
- - Compressed two-planar YVU420 format used by Mediatek MT8173.
- The compression is lossless.
- It is an opaque intermediate format and the MDP hardware must be
+ - Compressed two-planar YVU420 format used by Mediatek MT8173, MT8192,
+ MT8195 and more. The compression is lossless. This format have
+ similitude with ``V4L2_PIX_FMT_MM21`` in term of alignment and tiling.
+ It remains an opaque intermediate format and the MDP hardware must be
used to convert ``V4L2_PIX_FMT_MT21C`` to ``V4L2_PIX_FMT_NV12M``,
``V4L2_PIX_FMT_YUV420M`` or ``V4L2_PIX_FMT_YVU420``.
- * .. _V4L2-PIX-FMT-MM21:
-
- - ``V4L2_PIX_FMT_MM21``
- - 'MM21'
- - Non-compressed, tiled two-planar format used by Mediatek MT8183.
- This is an opaque intermediate format and the MDP3 hardware can be
- used to convert it to other formats.
-
.. raw:: latex
\normalsize
diff --git a/Documentation/userspace-api/media/v4l/pixfmt-rgb.rst b/Documentation/userspace-api/media/v4l/pixfmt-rgb.rst
index 48b0f787274c..30f51cd33f99 100644
--- a/Documentation/userspace-api/media/v4l/pixfmt-rgb.rst
+++ b/Documentation/userspace-api/media/v4l/pixfmt-rgb.rst
@@ -672,8 +672,8 @@ nomenclature that instead use the order of components as seen in a 24- or
- ``V4L2_PIX_FMT_BGR24``
- 'BGR3'
- - G\ :sub:`7-0`
- B\ :sub:`7-0`
+ - G\ :sub:`7-0`
- R\ :sub:`7-0`
-
* .. _V4L2-PIX-FMT-RGB24:
diff --git a/Documentation/userspace-api/media/v4l/pixfmt-yuv-luma.rst b/Documentation/userspace-api/media/v4l/pixfmt-yuv-luma.rst
index 91942c4f0967..8ebd58c3588f 100644
--- a/Documentation/userspace-api/media/v4l/pixfmt-yuv-luma.rst
+++ b/Documentation/userspace-api/media/v4l/pixfmt-yuv-luma.rst
@@ -75,8 +75,8 @@ are often referred to as greyscale formats.
- ``V4L2_PIX_FMT_Y10P``
- 'Y10P'
- - Y'\ :sub:`0`\ [7:0]
- - Y'\ :sub:`1`\ [9:8]
+ - Y'\ :sub:`0`\ [9:2]
+ - Y'\ :sub:`1`\ [9:2]
- Y'\ :sub:`2`\ [9:2]
- Y'\ :sub:`3`\ [9:2]
- Y'\ :sub:`3`\ [1:0] Y'\ :sub:`2`\ [1:0] Y'\ :sub:`1`\ [1:0] Y'\ :sub:`0`\ [1:0]
diff --git a/Documentation/userspace-api/media/v4l/pixfmt-yuv-planar.rst b/Documentation/userspace-api/media/v4l/pixfmt-yuv-planar.rst
index 3a09d93d405b..8dff5906639b 100644
--- a/Documentation/userspace-api/media/v4l/pixfmt-yuv-planar.rst
+++ b/Documentation/userspace-api/media/v4l/pixfmt-yuv-planar.rst
@@ -76,7 +76,7 @@ All components are stored with the same number of bits per component.
- 'NV21'
- 8
- 4:2:0
- - Cr, Cr
+ - Cr, Cb
- Yes
- Linear
* - V4L2_PIX_FMT_NV12M
@@ -90,7 +90,7 @@ All components are stored with the same number of bits per component.
- 'NM21'
- 8
- 4:2:0
- - Cr, Cr
+ - Cr, Cb
- No
- Linear
* - V4L2_PIX_FMT_NV12MT
@@ -120,7 +120,7 @@ All components are stored with the same number of bits per component.
- 'NV61'
- 8
- 4:2:2
- - Cr, Cr
+ - Cr, Cb
- Yes
- Linear
* - V4L2_PIX_FMT_NV16M
@@ -134,7 +134,7 @@ All components are stored with the same number of bits per component.
- 'NM61'
- 8
- 4:2:2
- - Cr, Cr
+ - Cr, Cb
- No
- Linear
* - V4L2_PIX_FMT_NV24
@@ -148,7 +148,7 @@ All components are stored with the same number of bits per component.
- 'NV42'
- 8
- 4:4:4
- - Cr, Cr
+ - Cr, Cb
- Yes
- Linear
@@ -257,6 +257,9 @@ of the luma plane.
.. _V4L2-PIX-FMT-NV12-4L4:
.. _V4L2-PIX-FMT-NV12-16L16:
.. _V4L2-PIX-FMT-NV12-32L32:
+.. _V4L2-PIX-FMT-NV12M-8L128:
+.. _V4L2-PIX-FMT-NV12M-10BE-8L128:
+.. _V4L2-PIX-FMT-MM21:
Tiled NV12
----------
@@ -281,21 +284,47 @@ If the vertical resolution is an odd number of tiles, the last row of
tiles is stored in linear order. The layouts of the luma and chroma
planes are identical.
-``V4L2_PIX_FMT_NV12_4L4`` stores pixel in 4x4 tiles, and stores
+``V4L2_PIX_FMT_NV12_4L4`` stores pixels in 4x4 tiles, and stores
tiles linearly in memory. The line stride and image height must be
aligned to a multiple of 4. The layouts of the luma and chroma planes are
identical.
-``V4L2_PIX_FMT_NV12_16L16`` stores pixel in 16x16 tiles, and stores
+``V4L2_PIX_FMT_NV12_16L16`` stores pixels in 16x16 tiles, and stores
tiles linearly in memory. The line stride and image height must be
aligned to a multiple of 16. The layouts of the luma and chroma planes are
identical.
-``V4L2_PIX_FMT_NV12_32L32`` stores pixel in 32x32 tiles, and stores
+``V4L2_PIX_FMT_NV12_32L32`` stores pixels in 32x32 tiles, and stores
tiles linearly in memory. The line stride and image height must be
aligned to a multiple of 32. The layouts of the luma and chroma planes are
identical.
+``V4L2_PIX_FMT_NV12M_8L128`` is similar to ``V4L2_PIX_FMT_NV12M`` but stores
+pixels in 2D 8x128 tiles, and stores tiles linearly in memory.
+The image height must be aligned to a multiple of 128.
+The layouts of the luma and chroma planes are identical.
+
+``V4L2_PIX_FMT_NV12M_10BE_8L128`` is similar to ``V4L2_PIX_FMT_NV12M`` but stores
+10 bits pixels in 2D 8x128 tiles, and stores tiles linearly in memory.
+the data is arranged in big endian order.
+The image height must be aligned to a multiple of 128.
+The layouts of the luma and chroma planes are identical.
+Note the tile size is 8bytes multiplied by 128 bytes,
+it means that the low bits and high bits of one pixel may be in different tiles.
+The 10 bit pixels are packed, so 5 bytes contain 4 10-bit pixels layout like
+this (for luma):
+byte 0: Y0(bits 9-2)
+byte 1: Y0(bits 1-0) Y1(bits 9-4)
+byte 2: Y1(bits 3-0) Y2(bits 9-6)
+byte 3: Y2(bits 5-0) Y3(bits 9-8)
+byte 4: Y3(bits 7-0)
+
+``V4L2_PIX_FMT_MM21`` store luma pixel in 16x32 tiles, and chroma pixels
+in 16x16 tiles. The line stride must be aligned to a multiple of 16 and the
+image height must be aligned to a multiple of 32. The number of luma and chroma
+tiles are identical, even though the tile size differ. The image is formed of
+two non-contiguous planes.
+
.. _nv12mt:
.. kernel-figure:: nv12mt.svg
diff --git a/Documentation/userspace-api/media/v4l/v4l2grab.c.rst b/Documentation/userspace-api/media/v4l/v4l2grab.c.rst
index b38f661da733..1a55e3617ea8 100644
--- a/Documentation/userspace-api/media/v4l/v4l2grab.c.rst
+++ b/Documentation/userspace-api/media/v4l/v4l2grab.c.rst
@@ -134,7 +134,7 @@ file: media/v4l/v4l2grab.c
tv.tv_usec = 0;
r = select(fd + 1, &fds, NULL, NULL, &tv);
- } while ((r == -1 && (errno = EINTR)));
+ } while ((r == -1 && (errno == EINTR)));
if (r == -1) {
perror("select");
return errno;
diff --git a/Documentation/userspace-api/media/v4l/vidioc-qbuf.rst b/Documentation/userspace-api/media/v4l/vidioc-qbuf.rst
index 77e0747a6d28..e4b3d9beb9ab 100644
--- a/Documentation/userspace-api/media/v4l/vidioc-qbuf.rst
+++ b/Documentation/userspace-api/media/v4l/vidioc-qbuf.rst
@@ -125,7 +125,7 @@ Applications call the ``VIDIOC_DQBUF`` ioctl to dequeue a filled
queue. They just set the ``type``, ``memory`` and ``reserved`` fields of
a struct :c:type:`v4l2_buffer` as above, when
``VIDIOC_DQBUF`` is called with a pointer to this structure the driver
-fills the remaining fields or returns an error code. The driver may also
+fills all remaining fields or returns an error code. The driver may also
set ``V4L2_BUF_FLAG_ERROR`` in the ``flags`` field. It indicates a
non-critical (recoverable) streaming error. In such case the application
may continue as normal, but should be aware that data in the dequeued
diff --git a/Documentation/virt/kvm/api.rst b/Documentation/virt/kvm/api.rst
index bb8cfddbb22d..07a45474abe9 100644
--- a/Documentation/virt/kvm/api.rst
+++ b/Documentation/virt/kvm/api.rst
@@ -417,7 +417,7 @@ kvm_run' (see below).
-----------------
:Capability: basic
-:Architectures: all except ARM, arm64
+:Architectures: all except arm64
:Type: vcpu ioctl
:Parameters: struct kvm_regs (out)
:Returns: 0 on success, -1 on error
@@ -450,7 +450,7 @@ Reads the general purpose registers from the vcpu.
-----------------
:Capability: basic
-:Architectures: all except ARM, arm64
+:Architectures: all except arm64
:Type: vcpu ioctl
:Parameters: struct kvm_regs (in)
:Returns: 0 on success, -1 on error
@@ -824,7 +824,7 @@ Writes the floating point state to the vcpu.
-----------------------
:Capability: KVM_CAP_IRQCHIP, KVM_CAP_S390_IRQCHIP (s390)
-:Architectures: x86, ARM, arm64, s390
+:Architectures: x86, arm64, s390
:Type: vm ioctl
:Parameters: none
:Returns: 0 on success, -1 on error
@@ -833,7 +833,7 @@ Creates an interrupt controller model in the kernel.
On x86, creates a virtual ioapic, a virtual PIC (two PICs, nested), and sets up
future vcpus to have a local APIC. IRQ routing for GSIs 0-15 is set to both
PIC and IOAPIC; GSI 16-23 only go to the IOAPIC.
-On ARM/arm64, a GICv2 is created. Any other GIC versions require the usage of
+On arm64, a GICv2 is created. Any other GIC versions require the usage of
KVM_CREATE_DEVICE, which also supports creating a GICv2. Using
KVM_CREATE_DEVICE is preferred over KVM_CREATE_IRQCHIP for GICv2.
On s390, a dummy irq routing table is created.
@@ -846,7 +846,7 @@ before KVM_CREATE_IRQCHIP can be used.
-----------------
:Capability: KVM_CAP_IRQCHIP
-:Architectures: x86, arm, arm64
+:Architectures: x86, arm64
:Type: vm ioctl
:Parameters: struct kvm_irq_level
:Returns: 0 on success, -1 on error
@@ -870,7 +870,7 @@ capability is present (or unless it is not using the in-kernel irqchip,
of course).
-ARM/arm64 can signal an interrupt either at the CPU level, or at the
+arm64 can signal an interrupt either at the CPU level, or at the
in-kernel irqchip (GIC), and for in-kernel irqchip can tell the GIC to
use PPIs designated for specific cpus. The irq field is interpreted
like this::
@@ -896,7 +896,7 @@ When KVM_CAP_ARM_IRQ_LINE_LAYOUT_2 is supported, the target vcpu is
identified as (256 * vcpu2_index + vcpu_index). Otherwise, vcpu2_index
must be zero.
-Note that on arm/arm64, the KVM_CAP_IRQCHIP capability only conditions
+Note that on arm64, the KVM_CAP_IRQCHIP capability only conditions
injection of interrupts for the in-kernel irqchip. KVM_IRQ_LINE can always
be used for a userspace interrupt controller.
@@ -1087,7 +1087,7 @@ Other flags returned by ``KVM_GET_CLOCK`` are accepted but ignored.
:Capability: KVM_CAP_VCPU_EVENTS
:Extended by: KVM_CAP_INTR_SHADOW
-:Architectures: x86, arm, arm64
+:Architectures: x86, arm64
:Type: vcpu ioctl
:Parameters: struct kvm_vcpu_event (out)
:Returns: 0 on success, -1 on error
@@ -1146,8 +1146,8 @@ The following bits are defined in the flags field:
fields contain a valid state. This bit will be set whenever
KVM_CAP_EXCEPTION_PAYLOAD is enabled.
-ARM/ARM64:
-^^^^^^^^^^
+ARM64:
+^^^^^^
If the guest accesses a device that is being emulated by the host kernel in
such a way that a real device would generate a physical SError, KVM may make
@@ -1206,7 +1206,7 @@ directly to the virtual CPU).
:Capability: KVM_CAP_VCPU_EVENTS
:Extended by: KVM_CAP_INTR_SHADOW
-:Architectures: x86, arm, arm64
+:Architectures: x86, arm64
:Type: vcpu ioctl
:Parameters: struct kvm_vcpu_event (in)
:Returns: 0 on success, -1 on error
@@ -1241,8 +1241,8 @@ can be set in the flags field to signal that the
exception_has_payload, exception_payload, and exception.pending fields
contain a valid state and shall be written into the VCPU.
-ARM/ARM64:
-^^^^^^^^^^
+ARM64:
+^^^^^^
User space may need to inject several types of events to the guest.
@@ -1394,7 +1394,7 @@ documentation when it pops into existence).
-------------------
:Capability: KVM_CAP_ENABLE_CAP
-:Architectures: mips, ppc, s390
+:Architectures: mips, ppc, s390, x86
:Type: vcpu ioctl
:Parameters: struct kvm_enable_cap (in)
:Returns: 0 on success; -1 on error
@@ -1449,7 +1449,7 @@ for vm-wide capabilities.
---------------------
:Capability: KVM_CAP_MP_STATE
-:Architectures: x86, s390, arm, arm64, riscv
+:Architectures: x86, s390, arm64, riscv
:Type: vcpu ioctl
:Parameters: struct kvm_mp_state (out)
:Returns: 0 on success; -1 on error
@@ -1467,7 +1467,7 @@ Possible values are:
========================== ===============================================
KVM_MP_STATE_RUNNABLE the vcpu is currently running
- [x86,arm/arm64,riscv]
+ [x86,arm64,riscv]
KVM_MP_STATE_UNINITIALIZED the vcpu is an application processor (AP)
which has not yet received an INIT signal [x86]
KVM_MP_STATE_INIT_RECEIVED the vcpu has received an INIT signal, and is
@@ -1476,7 +1476,7 @@ Possible values are:
is waiting for an interrupt [x86]
KVM_MP_STATE_SIPI_RECEIVED the vcpu has just received a SIPI (vector
accessible via KVM_GET_VCPU_EVENTS) [x86]
- KVM_MP_STATE_STOPPED the vcpu is stopped [s390,arm/arm64,riscv]
+ KVM_MP_STATE_STOPPED the vcpu is stopped [s390,arm64,riscv]
KVM_MP_STATE_CHECK_STOP the vcpu is in a special error state [s390]
KVM_MP_STATE_OPERATING the vcpu is operating (running or halted)
[s390]
@@ -1488,8 +1488,8 @@ On x86, this ioctl is only useful after KVM_CREATE_IRQCHIP. Without an
in-kernel irqchip, the multiprocessing state must be maintained by userspace on
these architectures.
-For arm/arm64/riscv:
-^^^^^^^^^^^^^^^^^^^^
+For arm64/riscv:
+^^^^^^^^^^^^^^^^
The only states that are valid are KVM_MP_STATE_STOPPED and
KVM_MP_STATE_RUNNABLE which reflect if the vcpu is paused or not.
@@ -1498,7 +1498,7 @@ KVM_MP_STATE_RUNNABLE which reflect if the vcpu is paused or not.
---------------------
:Capability: KVM_CAP_MP_STATE
-:Architectures: x86, s390, arm, arm64, riscv
+:Architectures: x86, s390, arm64, riscv
:Type: vcpu ioctl
:Parameters: struct kvm_mp_state (in)
:Returns: 0 on success; -1 on error
@@ -1510,8 +1510,8 @@ On x86, this ioctl is only useful after KVM_CREATE_IRQCHIP. Without an
in-kernel irqchip, the multiprocessing state must be maintained by userspace on
these architectures.
-For arm/arm64/riscv:
-^^^^^^^^^^^^^^^^^^^^
+For arm64/riscv:
+^^^^^^^^^^^^^^^^
The only states that are valid are KVM_MP_STATE_STOPPED and
KVM_MP_STATE_RUNNABLE which reflect if the vcpu should be paused or not.
@@ -1780,14 +1780,14 @@ The flags bitmap is defined as::
------------------------
:Capability: KVM_CAP_IRQ_ROUTING
-:Architectures: x86 s390 arm arm64
+:Architectures: x86 s390 arm64
:Type: vm ioctl
:Parameters: struct kvm_irq_routing (in)
:Returns: 0 on success, -1 on error
Sets the GSI routing table entries, overwriting any previously set entries.
-On arm/arm64, GSI routing has the following limitation:
+On arm64, GSI routing has the following limitation:
- GSI routing does not apply to KVM_IRQ_LINE but only to KVM_IRQFD.
@@ -2855,7 +2855,7 @@ after pausing the vcpu, but before it is resumed.
-------------------
:Capability: KVM_CAP_SIGNAL_MSI
-:Architectures: x86 arm arm64
+:Architectures: x86 arm64
:Type: vm ioctl
:Parameters: struct kvm_msi (in)
:Returns: >0 on delivery, 0 if guest blocked the MSI, and -1 on error
@@ -3043,7 +3043,7 @@ into the hash PTE second double word).
--------------
:Capability: KVM_CAP_IRQFD
-:Architectures: x86 s390 arm arm64
+:Architectures: x86 s390 arm64
:Type: vm ioctl
:Parameters: struct kvm_irqfd (in)
:Returns: 0 on success, -1 on error
@@ -3069,7 +3069,7 @@ Note that closing the resamplefd is not sufficient to disable the
irqfd. The KVM_IRQFD_FLAG_RESAMPLE is only necessary on assignment
and need not be specified with KVM_IRQFD_FLAG_DEASSIGN.
-On arm/arm64, gsi routing being supported, the following can happen:
+On arm64, gsi routing being supported, the following can happen:
- in case no routing entry is associated to this gsi, injection fails
- in case the gsi is associated to an irqchip routing entry,
@@ -3268,6 +3268,7 @@ number.
:Capability: KVM_CAP_DEVICE_CTRL, KVM_CAP_VM_ATTRIBUTES for vm device,
KVM_CAP_VCPU_ATTRIBUTES for vcpu device
+ KVM_CAP_SYS_ATTRIBUTES for system (/dev/kvm) device (no set)
:Type: device ioctl, vm ioctl, vcpu ioctl
:Parameters: struct kvm_device_attr
:Returns: 0 on success, -1 on error
@@ -3302,7 +3303,8 @@ transferred is defined by the particular attribute.
------------------------
:Capability: KVM_CAP_DEVICE_CTRL, KVM_CAP_VM_ATTRIBUTES for vm device,
- KVM_CAP_VCPU_ATTRIBUTES for vcpu device
+ KVM_CAP_VCPU_ATTRIBUTES for vcpu device
+ KVM_CAP_SYS_ATTRIBUTES for system (/dev/kvm) device
:Type: device ioctl, vm ioctl, vcpu ioctl
:Parameters: struct kvm_device_attr
:Returns: 0 on success, -1 on error
@@ -3323,7 +3325,7 @@ current state. "addr" is ignored.
----------------------
:Capability: basic
-:Architectures: arm, arm64
+:Architectures: arm64
:Type: vcpu ioctl
:Parameters: struct kvm_vcpu_init (in)
:Returns: 0 on success; -1 on error
@@ -3421,7 +3423,7 @@ Possible features:
-----------------------------
:Capability: basic
-:Architectures: arm, arm64
+:Architectures: arm64
:Type: vm ioctl
:Parameters: struct kvm_vcpu_init (out)
:Returns: 0 on success; -1 on error
@@ -3450,7 +3452,7 @@ VCPU matching underlying host.
---------------------
:Capability: basic
-:Architectures: arm, arm64, mips
+:Architectures: arm64, mips
:Type: vcpu ioctl
:Parameters: struct kvm_reg_list (in/out)
:Returns: 0 on success; -1 on error
@@ -3477,7 +3479,7 @@ KVM_GET_ONE_REG/KVM_SET_ONE_REG calls.
-----------------------------------------
:Capability: KVM_CAP_ARM_SET_DEVICE_ADDR
-:Architectures: arm, arm64
+:Architectures: arm64
:Type: vm ioctl
:Parameters: struct kvm_arm_device_address (in)
:Returns: 0 on success, -1 on error
@@ -3504,13 +3506,13 @@ can access emulated or directly exposed devices, which the host kernel needs
to know about. The id field is an architecture specific identifier for a
specific device.
-ARM/arm64 divides the id field into two parts, a device id and an
+arm64 divides the id field into two parts, a device id and an
address type id specific to the individual device::
bits: | 63 ... 32 | 31 ... 16 | 15 ... 0 |
field: | 0x00000000 | device id | addr type id |
-ARM/arm64 currently only require this when using the in-kernel GIC
+arm64 currently only require this when using the in-kernel GIC
support for the hardware VGIC features, using KVM_ARM_DEVICE_VGIC_V2
as the device id. When setting the base address for the guest's
mapping of the VGIC virtual CPU and distributor interface, the ioctl
@@ -3681,15 +3683,17 @@ The fields in each entry are defined as follows:
4.89 KVM_S390_MEM_OP
--------------------
-:Capability: KVM_CAP_S390_MEM_OP
+:Capability: KVM_CAP_S390_MEM_OP, KVM_CAP_S390_PROTECTED, KVM_CAP_S390_MEM_OP_EXTENSION
:Architectures: s390
-:Type: vcpu ioctl
+:Type: vm ioctl, vcpu ioctl
:Parameters: struct kvm_s390_mem_op (in)
:Returns: = 0 on success,
< 0 on generic error (e.g. -EFAULT or -ENOMEM),
> 0 if an exception occurred while walking the page tables
-Read or write data from/to the logical (virtual) memory of a VCPU.
+Read or write data from/to the VM's memory.
+The KVM_CAP_S390_MEM_OP_EXTENSION capability specifies what functionality is
+supported.
Parameters are specified via the following structure::
@@ -3699,33 +3703,99 @@ Parameters are specified via the following structure::
__u32 size; /* amount of bytes */
__u32 op; /* type of operation */
__u64 buf; /* buffer in userspace */
- __u8 ar; /* the access register number */
- __u8 reserved[31]; /* should be set to 0 */
+ union {
+ struct {
+ __u8 ar; /* the access register number */
+ __u8 key; /* access key, ignored if flag unset */
+ };
+ __u32 sida_offset; /* offset into the sida */
+ __u8 reserved[32]; /* ignored */
+ };
};
-The type of operation is specified in the "op" field. It is either
-KVM_S390_MEMOP_LOGICAL_READ for reading from logical memory space or
-KVM_S390_MEMOP_LOGICAL_WRITE for writing to logical memory space. The
-KVM_S390_MEMOP_F_CHECK_ONLY flag can be set in the "flags" field to check
-whether the corresponding memory access would create an access exception
-(without touching the data in the memory at the destination). In case an
-access exception occurred while walking the MMU tables of the guest, the
-ioctl returns a positive error number to indicate the type of exception.
-This exception is also raised directly at the corresponding VCPU if the
-flag KVM_S390_MEMOP_F_INJECT_EXCEPTION is set in the "flags" field.
-
The start address of the memory region has to be specified in the "gaddr"
field, and the length of the region in the "size" field (which must not
be 0). The maximum value for "size" can be obtained by checking the
KVM_CAP_S390_MEM_OP capability. "buf" is the buffer supplied by the
userspace application where the read data should be written to for
-KVM_S390_MEMOP_LOGICAL_READ, or where the data that should be written is
-stored for a KVM_S390_MEMOP_LOGICAL_WRITE. When KVM_S390_MEMOP_F_CHECK_ONLY
-is specified, "buf" is unused and can be NULL. "ar" designates the access
-register number to be used; the valid range is 0..15.
+a read access, or where the data that should be written is stored for
+a write access. The "reserved" field is meant for future extensions.
+Reserved and unused values are ignored. Future extension that add members must
+introduce new flags.
+
+The type of operation is specified in the "op" field. Flags modifying
+their behavior can be set in the "flags" field. Undefined flag bits must
+be set to 0.
+
+Possible operations are:
+ * ``KVM_S390_MEMOP_LOGICAL_READ``
+ * ``KVM_S390_MEMOP_LOGICAL_WRITE``
+ * ``KVM_S390_MEMOP_ABSOLUTE_READ``
+ * ``KVM_S390_MEMOP_ABSOLUTE_WRITE``
+ * ``KVM_S390_MEMOP_SIDA_READ``
+ * ``KVM_S390_MEMOP_SIDA_WRITE``
+
+Logical read/write:
+^^^^^^^^^^^^^^^^^^^
+
+Access logical memory, i.e. translate the given guest address to an absolute
+address given the state of the VCPU and use the absolute address as target of
+the access. "ar" designates the access register number to be used; the valid
+range is 0..15.
+Logical accesses are permitted for the VCPU ioctl only.
+Logical accesses are permitted for non-protected guests only.
+
+Supported flags:
+ * ``KVM_S390_MEMOP_F_CHECK_ONLY``
+ * ``KVM_S390_MEMOP_F_INJECT_EXCEPTION``
+ * ``KVM_S390_MEMOP_F_SKEY_PROTECTION``
+
+The KVM_S390_MEMOP_F_CHECK_ONLY flag can be set to check whether the
+corresponding memory access would cause an access exception; however,
+no actual access to the data in memory at the destination is performed.
+In this case, "buf" is unused and can be NULL.
+
+In case an access exception occurred during the access (or would occur
+in case of KVM_S390_MEMOP_F_CHECK_ONLY), the ioctl returns a positive
+error number indicating the type of exception. This exception is also
+raised directly at the corresponding VCPU if the flag
+KVM_S390_MEMOP_F_INJECT_EXCEPTION is set.
+
+If the KVM_S390_MEMOP_F_SKEY_PROTECTION flag is set, storage key
+protection is also in effect and may cause exceptions if accesses are
+prohibited given the access key designated by "key"; the valid range is 0..15.
+KVM_S390_MEMOP_F_SKEY_PROTECTION is available if KVM_CAP_S390_MEM_OP_EXTENSION
+is > 0.
+
+Absolute read/write:
+^^^^^^^^^^^^^^^^^^^^
-The "reserved" field is meant for future extensions. It is not used by
-KVM with the currently defined set of flags.
+Access absolute memory. This operation is intended to be used with the
+KVM_S390_MEMOP_F_SKEY_PROTECTION flag, to allow accessing memory and performing
+the checks required for storage key protection as one operation (as opposed to
+user space getting the storage keys, performing the checks, and accessing
+memory thereafter, which could lead to a delay between check and access).
+Absolute accesses are permitted for the VM ioctl if KVM_CAP_S390_MEM_OP_EXTENSION
+is > 0.
+Currently absolute accesses are not permitted for VCPU ioctls.
+Absolute accesses are permitted for non-protected guests only.
+
+Supported flags:
+ * ``KVM_S390_MEMOP_F_CHECK_ONLY``
+ * ``KVM_S390_MEMOP_F_SKEY_PROTECTION``
+
+The semantics of the flags are as for logical accesses.
+
+SIDA read/write:
+^^^^^^^^^^^^^^^^
+
+Access the secure instruction data area which contains memory operands necessary
+for instruction emulation for protected guests.
+SIDA accesses are available if the KVM_CAP_S390_PROTECTED capability is available.
+SIDA accesses are permitted for the VCPU ioctl only.
+SIDA accesses are permitted for protected guests only.
+
+No flags are supported.
4.90 KVM_S390_GET_SKEYS
-----------------------
@@ -4724,7 +4794,7 @@ to I/O ports.
------------------------------------
:Capability: KVM_CAP_MANUAL_DIRTY_LOG_PROTECT2
-:Architectures: x86, arm, arm64, mips
+:Architectures: x86, arm64, mips
:Type: vm ioctl
:Parameters: struct kvm_clear_dirty_log (in)
:Returns: 0 on success, -1 on error
@@ -4836,7 +4906,7 @@ version has the following quirks:
4.119 KVM_ARM_VCPU_FINALIZE
---------------------------
-:Architectures: arm, arm64
+:Architectures: arm64
:Type: vcpu ioctl
:Parameters: int feature (in)
:Returns: 0 on success, -1 on error
@@ -5918,7 +5988,7 @@ should put the acknowledged interrupt vector into the 'epr' field.
If exit_reason is KVM_EXIT_SYSTEM_EVENT then the vcpu has triggered
a system-level event using some architecture specific mechanism (hypercall
-or some special instruction). In case of ARM/ARM64, this is triggered using
+or some special instruction). In case of ARM64, this is triggered using
HVC instruction based PSCI call from the vcpu. The 'type' field describes
the system-level event type. The 'flags' field describes architecture
specific flags for the system-level event.
@@ -5937,6 +6007,11 @@ Valid values for 'type' are:
to ignore the request, or to gather VM memory core dump and/or
reset/shutdown of the VM.
+Valid flags are:
+
+ - KVM_SYSTEM_EVENT_RESET_FLAG_PSCI_RESET2 (arm64 only) -- the guest issued
+ a SYSTEM_RESET2 call according to v1.1 of the PSCI specification.
+
::
/* KVM_EXIT_IOAPIC_EOI */
@@ -6011,7 +6086,7 @@ in send_page or recv a buffer to recv_page).
__u64 fault_ipa;
} arm_nisv;
-Used on arm and arm64 systems. If a guest accesses memory not in a memslot,
+Used on arm64 systems. If a guest accesses memory not in a memslot,
KVM will typically return to userspace and ask it to do MMIO emulation on its
behalf. However, for certain classes of instructions, no instruction decode
(direction, length of memory access) is provided, and fetching and decoding
@@ -6028,11 +6103,10 @@ did not fall within an I/O window.
Userspace implementations can query for KVM_CAP_ARM_NISV_TO_USER, and enable
this capability at VM creation. Once this is done, these types of errors will
instead return to userspace with KVM_EXIT_ARM_NISV, with the valid bits from
-the HSR (arm) and ESR_EL2 (arm64) in the esr_iss field, and the faulting IPA
-in the fault_ipa field. Userspace can either fix up the access if it's
-actually an I/O access by decoding the instruction from guest memory (if it's
-very brave) and continue executing the guest, or it can decide to suspend,
-dump, or restart the guest.
+the ESR_EL2 in the esr_iss field, and the faulting IPA in the fault_ipa field.
+Userspace can either fix up the access if it's actually an I/O access by
+decoding the instruction from guest memory (if it's very brave) and continue
+executing the guest, or it can decide to suspend, dump, or restart the guest.
Note that KVM does not skip the faulting instruction as it does for
KVM_EXIT_MMIO, but userspace has to emulate any change to the processing state
@@ -6739,7 +6813,7 @@ and injected exceptions.
7.18 KVM_CAP_MANUAL_DIRTY_LOG_PROTECT2
-:Architectures: x86, arm, arm64, mips
+:Architectures: x86, arm64, mips
:Parameters: args[0] whether feature should be enabled or not
Valid flags are::
@@ -6995,6 +7069,70 @@ indicated by the fd to the VM this is called on.
This is intended to support intra-host migration of VMs between userspace VMMs,
upgrading the VMM process without interrupting the guest.
+7.30 KVM_CAP_PPC_AIL_MODE_3
+-------------------------------
+
+:Capability: KVM_CAP_PPC_AIL_MODE_3
+:Architectures: ppc
+:Type: vm
+
+This capability indicates that the kernel supports the mode 3 setting for the
+"Address Translation Mode on Interrupt" aka "Alternate Interrupt Location"
+resource that is controlled with the H_SET_MODE hypercall.
+
+This capability allows a guest kernel to use a better-performance mode for
+handling interrupts and system calls.
+
+7.31 KVM_CAP_DISABLE_QUIRKS2
+----------------------------
+
+:Capability: KVM_CAP_DISABLE_QUIRKS2
+:Parameters: args[0] - set of KVM quirks to disable
+:Architectures: x86
+:Type: vm
+
+This capability, if enabled, will cause KVM to disable some behavior
+quirks.
+
+Calling KVM_CHECK_EXTENSION for this capability returns a bitmask of
+quirks that can be disabled in KVM.
+
+The argument to KVM_ENABLE_CAP for this capability is a bitmask of
+quirks to disable, and must be a subset of the bitmask returned by
+KVM_CHECK_EXTENSION.
+
+The valid bits in cap.args[0] are:
+
+=================================== ============================================
+ KVM_X86_QUIRK_LINT0_REENABLED By default, the reset value for the LVT
+ LINT0 register is 0x700 (APIC_MODE_EXTINT).
+ When this quirk is disabled, the reset value
+ is 0x10000 (APIC_LVT_MASKED).
+
+ KVM_X86_QUIRK_CD_NW_CLEARED By default, KVM clears CR0.CD and CR0.NW.
+ When this quirk is disabled, KVM does not
+ change the value of CR0.CD and CR0.NW.
+
+ KVM_X86_QUIRK_LAPIC_MMIO_HOLE By default, the MMIO LAPIC interface is
+ available even when configured for x2APIC
+ mode. When this quirk is disabled, KVM
+ disables the MMIO LAPIC interface if the
+ LAPIC is in x2APIC mode.
+
+ KVM_X86_QUIRK_OUT_7E_INC_RIP By default, KVM pre-increments %rip before
+ exiting to userspace for an OUT instruction
+ to port 0x7e. When this quirk is disabled,
+ KVM does not pre-increment %rip before
+ exiting to userspace.
+
+ KVM_X86_QUIRK_MISC_ENABLE_NO_MWAIT When this quirk is disabled, KVM sets
+ CPUID.01H:ECX[bit 3] (MONITOR/MWAIT) if
+ IA32_MISC_ENABLE[bit 18] (MWAIT) is set.
+ Additionally, when this quirk is disabled,
+ KVM clears CPUID.01H:ECX[bit 3] if
+ IA32_MISC_ENABLE[bit 18] is cleared.
+=================================== ============================================
+
8. Other capabilities.
======================
@@ -7122,7 +7260,7 @@ reserved.
8.9 KVM_CAP_ARM_USER_IRQ
------------------------
-:Architectures: arm, arm64
+:Architectures: arm64
This capability, if KVM_CHECK_EXTENSION indicates that it is available, means
that if userspace creates a VM without an in-kernel interrupt controller, it
@@ -7249,7 +7387,7 @@ HvFlushVirtualAddressList, HvFlushVirtualAddressListEx.
8.19 KVM_CAP_ARM_INJECT_SERROR_ESR
----------------------------------
-:Architectures: arm, arm64
+:Architectures: arm64
This capability indicates that userspace can specify (via the
KVM_SET_VCPU_EVENTS ioctl) the syndrome value reported to the guest when it
@@ -7559,3 +7697,25 @@ The argument to KVM_ENABLE_CAP is also a bitmask, and must be a subset
of the result of KVM_CHECK_EXTENSION. KVM will forward to userspace
the hypercalls whose corresponding bit is in the argument, and return
ENOSYS for the others.
+
+8.35 KVM_CAP_PMU_CAPABILITY
+---------------------------
+
+:Capability KVM_CAP_PMU_CAPABILITY
+:Architectures: x86
+:Type: vm
+:Parameters: arg[0] is bitmask of PMU virtualization capabilities.
+:Returns 0 on success, -EINVAL when arg[0] contains invalid bits
+
+This capability alters PMU virtualization in KVM.
+
+Calling KVM_CHECK_EXTENSION for this capability returns a bitmask of
+PMU virtualization capabilities that can be adjusted on a VM.
+
+The argument to KVM_ENABLE_CAP is also a bitmask and selects specific
+PMU virtualization capabilities to be applied to the VM. This can
+only be invoked on a VM prior to the creation of VCPUs.
+
+At this time, KVM_PMU_CAP_DISABLE is the only capability. Setting
+this capability will disable PMU virtualization for that VM. Usermode
+should adjust CPUID leaf 0xA to reflect that the PMU is disabled.
diff --git a/Documentation/virt/kvm/devices/vcpu.rst b/Documentation/virt/kvm/devices/vcpu.rst
index 60a29972d3f1..716aa3edae14 100644
--- a/Documentation/virt/kvm/devices/vcpu.rst
+++ b/Documentation/virt/kvm/devices/vcpu.rst
@@ -70,7 +70,7 @@ irqchip.
-ENODEV PMUv3 not supported or GIC not initialized
-ENXIO PMUv3 not properly configured or in-kernel irqchip not
configured as required prior to calling this attribute
- -EBUSY PMUv3 already initialized
+ -EBUSY PMUv3 already initialized or a VCPU has already run
-EINVAL Invalid filter range
======= ======================================================
@@ -104,11 +104,43 @@ hardware event. Filtering event 0x1E (CHAIN) has no effect either, as it
isn't strictly speaking an event. Filtering the cycle counter is possible
using event 0x11 (CPU_CYCLES).
+1.4 ATTRIBUTE: KVM_ARM_VCPU_PMU_V3_SET_PMU
+------------------------------------------
+
+:Parameters: in kvm_device_attr.addr the address to an int representing the PMU
+ identifier.
+
+:Returns:
+
+ ======= ====================================================
+ -EBUSY PMUv3 already initialized, a VCPU has already run or
+ an event filter has already been set
+ -EFAULT Error accessing the PMU identifier
+ -ENXIO PMU not found
+ -ENODEV PMUv3 not supported or GIC not initialized
+ -ENOMEM Could not allocate memory
+ ======= ====================================================
+
+Request that the VCPU uses the specified hardware PMU when creating guest events
+for the purpose of PMU emulation. The PMU identifier can be read from the "type"
+file for the desired PMU instance under /sys/devices (or, equivalent,
+/sys/bus/even_source). This attribute is particularly useful on heterogeneous
+systems where there are at least two CPU PMUs on the system. The PMU that is set
+for one VCPU will be used by all the other VCPUs. It isn't possible to set a PMU
+if a PMU event filter is already present.
+
+Note that KVM will not make any attempts to run the VCPU on the physical CPUs
+associated with the PMU specified by this attribute. This is entirely left to
+userspace. However, attempting to run the VCPU on a physical CPU not supported
+by the PMU will fail and KVM_RUN will return with
+exit_reason = KVM_EXIT_FAIL_ENTRY and populate the fail_entry struct by setting
+hardare_entry_failure_reason field to KVM_EXIT_FAIL_ENTRY_CPU_UNSUPPORTED and
+the cpu field to the processor id.
2. GROUP: KVM_ARM_VCPU_TIMER_CTRL
=================================
-:Architectures: ARM, ARM64
+:Architectures: ARM64
2.1. ATTRIBUTES: KVM_ARM_VCPU_TIMER_IRQ_VTIMER, KVM_ARM_VCPU_TIMER_IRQ_PTIMER
-----------------------------------------------------------------------------
diff --git a/Documentation/virt/kvm/vcpu-requests.rst b/Documentation/virt/kvm/vcpu-requests.rst
index ad2915ef7020..b61d48aec36c 100644
--- a/Documentation/virt/kvm/vcpu-requests.rst
+++ b/Documentation/virt/kvm/vcpu-requests.rst
@@ -112,11 +112,10 @@ KVM_REQ_TLB_FLUSH
choose to use the common kvm_flush_remote_tlbs() implementation will
need to handle this VCPU request.
-KVM_REQ_MMU_RELOAD
+KVM_REQ_VM_DEAD
- When shadow page tables are used and memory slots are removed it's
- necessary to inform each VCPU to completely refresh the tables. This
- request is used for that.
+ This request informs all VCPUs that the VM is dead and unusable, e.g. due to
+ fatal error or because the VM's state has been intentionally destroyed.
KVM_REQ_UNBLOCK
diff --git a/Documentation/virt/uml/user_mode_linux_howto_v2.rst b/Documentation/virt/uml/user_mode_linux_howto_v2.rst
index 2cafd3c3c6cb..d5ad96c795f6 100644
--- a/Documentation/virt/uml/user_mode_linux_howto_v2.rst
+++ b/Documentation/virt/uml/user_mode_linux_howto_v2.rst
@@ -664,7 +664,11 @@ one is input, the second one output.
* The fd channel - use file descriptor numbers for input/output. Example:
``con1=fd:0,fd:1.``
-* The port channel - listen on TCP port number. Example: ``con1=port:4321``
+* The port channel - start a telnet server on TCP port number. Example:
+ ``con1=port:4321``. The host must have /usr/sbin/in.telnetd (usually part of
+ a telnetd package) and the port-helper from the UML utilities (see the
+ information for the xterm channel below). UML will not boot until a client
+ connects.
* The pty and pts channels - use system pty/pts.
diff --git a/Documentation/vm/damon/design.rst b/Documentation/vm/damon/design.rst
index 210f0f50efd8..0cff6fac6b7e 100644
--- a/Documentation/vm/damon/design.rst
+++ b/Documentation/vm/damon/design.rst
@@ -13,12 +13,13 @@ primitives that dependent on and optimized for the target address space. On
the other hand, the accuracy and overhead tradeoff mechanism, which is the core
of DAMON, is in the pure logic space. DAMON separates the two parts in
different layers and defines its interface to allow various low level
-primitives implementations configurable with the core logic.
+primitives implementations configurable with the core logic. We call the low
+level primitives implementations monitoring operations.
Due to this separated design and the configurable interface, users can extend
-DAMON for any address space by configuring the core logics with appropriate low
-level primitive implementations. If appropriate one is not provided, users can
-implement the primitives on their own.
+DAMON for any address space by configuring the core logics with appropriate
+monitoring operations. If appropriate one is not provided, users can implement
+the operations on their own.
For example, physical memory, virtual memory, swap space, those for specific
processes, NUMA nodes, files, and backing memory devices would be supportable.
@@ -26,25 +27,24 @@ Also, if some architectures or devices support special optimized access check
primitives, those will be easily configurable.
-Reference Implementations of Address Space Specific Primitives
-==============================================================
+Reference Implementations of Address Space Specific Monitoring Operations
+=========================================================================
-The low level primitives for the fundamental access monitoring are defined in
-two parts:
+The monitoring operations are defined in two parts:
1. Identification of the monitoring target address range for the address space.
2. Access check of specific address range in the target space.
-DAMON currently provides the implementations of the primitives for the physical
+DAMON currently provides the implementations of the operations for the physical
and virtual address spaces. Below two subsections describe how those work.
VMA-based Target Address Range Construction
-------------------------------------------
-This is only for the virtual address space primitives implementation. That for
-the physical address space simply asks users to manually set the monitoring
-target address ranges.
+This is only for the virtual address space monitoring operations
+implementation. That for the physical address space simply asks users to
+manually set the monitoring target address ranges.
Only small parts in the super-huge virtual address space of the processes are
mapped to the physical memory and accessed. Thus, tracking the unmapped
@@ -84,9 +84,10 @@ table having a mapping to the address. In this way, the implementations find
and clear the bit(s) for next sampling target address and checks whether the
bit(s) set again after one sampling period. This could disturb other kernel
subsystems using the Accessed bits, namely Idle page tracking and the reclaim
-logic. To avoid such disturbances, DAMON makes it mutually exclusive with Idle
-page tracking and uses ``PG_idle`` and ``PG_young`` page flags to solve the
-conflict with the reclaim logic, as Idle page tracking does.
+logic. DAMON does nothing to avoid disturbing Idle page tracking, so handling
+the interference is the responsibility of sysadmins. However, it solves the
+conflict with the reclaim logic using ``PG_idle`` and ``PG_young`` page flags,
+as Idle page tracking does.
Address Space Independent Core Mechanisms
@@ -94,8 +95,8 @@ Address Space Independent Core Mechanisms
Below four sections describe each of the DAMON core mechanisms and the five
monitoring attributes, ``sampling interval``, ``aggregation interval``,
-``regions update interval``, ``minimum number of regions``, and ``maximum
-number of regions``.
+``update interval``, ``minimum number of regions``, and ``maximum number of
+regions``.
Access Frequency Monitoring
@@ -168,6 +169,8 @@ The monitoring target address range could dynamically changed. For example,
virtual memory could be dynamically mapped and unmapped. Physical memory could
be hot-plugged.
-As the changes could be quite frequent in some cases, DAMON checks the dynamic
-memory mapping changes and applies it to the abstracted target area only for
-each of a user-specified time interval (``regions update interval``).
+As the changes could be quite frequent in some cases, DAMON allows the
+monitoring operations to check dynamic changes including memory mapping changes
+and applies it to monitoring operations-related data structures such as the
+abstracted monitoring target memory area only for each of a user-specified time
+interval (``update interval``).
diff --git a/Documentation/vm/damon/faq.rst b/Documentation/vm/damon/faq.rst
index 11aea40eb328..dde7e2414ee6 100644
--- a/Documentation/vm/damon/faq.rst
+++ b/Documentation/vm/damon/faq.rst
@@ -31,7 +31,7 @@ Does DAMON support virtual memory only?
=======================================
No. The core of the DAMON is address space independent. The address space
-specific low level primitive parts including monitoring target regions
+specific monitoring operations including monitoring target regions
constructions and actual access checks can be implemented and configured on the
DAMON core by the users. In this way, DAMON users can monitor any address
space with any access check technique.
diff --git a/Documentation/vm/page_owner.rst b/Documentation/vm/page_owner.rst
index 9837fc8147dd..905555e3e483 100644
--- a/Documentation/vm/page_owner.rst
+++ b/Documentation/vm/page_owner.rst
@@ -26,9 +26,9 @@ fragmentation statistics can be obtained through gfp flag information of
each page. It is already implemented and activated if page owner is
enabled. Other usages are more than welcome.
-page owner is disabled in default. So, if you'd like to use it, you need
-to add "page_owner=on" into your boot cmdline. If the kernel is built
-with page owner and page owner is disabled in runtime due to no enabling
+page owner is disabled by default. So, if you'd like to use it, you need
+to add "page_owner=on" to your boot cmdline. If the kernel is built
+with page owner and page owner is disabled in runtime due to not enabling
boot option, runtime overhead is marginal. If disabled in runtime, it
doesn't require memory to store owner information, so there is no runtime
memory overhead. And, page owner inserts just two unlikely branches into
@@ -85,7 +85,7 @@ Usage
cat /sys/kernel/debug/page_owner > page_owner_full.txt
./page_owner_sort page_owner_full.txt sorted_page_owner.txt
- The general output of ``page_owner_full.txt`` is as follows:
+ The general output of ``page_owner_full.txt`` is as follows::
Page allocated via order XXX, ...
PFN XXX ...
@@ -100,7 +100,7 @@ Usage
and pages of buf, and finally sorts them according to the times.
See the result about who allocated each page
- in the ``sorted_page_owner.txt``. General output:
+ in the ``sorted_page_owner.txt``. General output::
XXX times, XXX pages:
Page allocated via order XXX, ...
diff --git a/Documentation/vm/page_table_check.rst b/Documentation/vm/page_table_check.rst
index 81f521ff7ea7..1a09472f10a3 100644
--- a/Documentation/vm/page_table_check.rst
+++ b/Documentation/vm/page_table_check.rst
@@ -9,7 +9,7 @@ Page Table Check
Introduction
============
-Page table check allows to hardern the kernel by ensuring that some types of
+Page table check allows to harden the kernel by ensuring that some types of
the memory corruptions are prevented.
Page table check performs extra verifications at the time when new pages become
diff --git a/Documentation/x86/index.rst b/Documentation/x86/index.rst
index f498f1d36cd3..982c8af853b9 100644
--- a/Documentation/x86/index.rst
+++ b/Documentation/x86/index.rst
@@ -21,6 +21,7 @@ x86-specific Documentation
tlb
mtrr
pat
+ intel-hfi
intel-iommu
intel_txt
amd-memory-encryption
diff --git a/Documentation/x86/intel-hfi.rst b/Documentation/x86/intel-hfi.rst
new file mode 100644
index 000000000000..49dea58ea4fb
--- /dev/null
+++ b/Documentation/x86/intel-hfi.rst
@@ -0,0 +1,72 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+============================================================
+Hardware-Feedback Interface for scheduling on Intel Hardware
+============================================================
+
+Overview
+--------
+
+Intel has described the Hardware Feedback Interface (HFI) in the Intel 64 and
+IA-32 Architectures Software Developer's Manual (Intel SDM) Volume 3 Section
+14.6 [1]_.
+
+The HFI gives the operating system a performance and energy efficiency
+capability data for each CPU in the system. Linux can use the information from
+the HFI to influence task placement decisions.
+
+The Hardware Feedback Interface
+-------------------------------
+
+The Hardware Feedback Interface provides to the operating system information
+about the performance and energy efficiency of each CPU in the system. Each
+capability is given as a unit-less quantity in the range [0-255]. Higher values
+indicate higher capability. Energy efficiency and performance are reported in
+separate capabilities. Even though on some systems these two metrics may be
+related, they are specified as independent capabilities in the Intel SDM.
+
+These capabilities may change at runtime as a result of changes in the
+operating conditions of the system or the action of external factors. The rate
+at which these capabilities are updated is specific to each processor model. On
+some models, capabilities are set at boot time and never change. On others,
+capabilities may change every tens of milliseconds. For instance, a remote
+mechanism may be used to lower Thermal Design Power. Such change can be
+reflected in the HFI. Likewise, if the system needs to be throttled due to
+excessive heat, the HFI may reflect reduced performance on specific CPUs.
+
+The kernel or a userspace policy daemon can use these capabilities to modify
+task placement decisions. For instance, if either the performance or energy
+capabilities of a given logical processor becomes zero, it is an indication that
+the hardware recommends to the operating system to not schedule any tasks on
+that processor for performance or energy efficiency reasons, respectively.
+
+Implementation details for Linux
+--------------------------------
+
+The infrastructure to handle thermal event interrupts has two parts. In the
+Local Vector Table of a CPU's local APIC, there exists a register for the
+Thermal Monitor Register. This register controls how interrupts are delivered
+to a CPU when the thermal monitor generates and interrupt. Further details
+can be found in the Intel SDM Vol. 3 Section 10.5 [1]_.
+
+The thermal monitor may generate interrupts per CPU or per package. The HFI
+generates package-level interrupts. This monitor is configured and initialized
+via a set of machine-specific registers. Specifically, the HFI interrupt and
+status are controlled via designated bits in the IA32_PACKAGE_THERM_INTERRUPT
+and IA32_PACKAGE_THERM_STATUS registers, respectively. There exists one HFI
+table per package. Further details can be found in the Intel SDM Vol. 3
+Section 14.9 [1]_.
+
+The hardware issues an HFI interrupt after updating the HFI table and is ready
+for the operating system to consume it. CPUs receive such interrupt via the
+thermal entry in the Local APIC's Local Vector Table.
+
+When servicing such interrupt, the HFI driver parses the updated table and
+relays the update to userspace using the thermal notification framework. Given
+that there may be many HFI updates every second, the updates relayed to
+userspace are throttled at a rate of CONFIG_HZ jiffies.
+
+References
+----------
+
+.. [1] https://www.intel.com/sdm
diff --git a/Documentation/x86/sva.rst b/Documentation/x86/sva.rst
index 076efd51ef1f..2e9b8b0f9a0f 100644
--- a/Documentation/x86/sva.rst
+++ b/Documentation/x86/sva.rst
@@ -104,18 +104,47 @@ The MSR must be configured on each logical CPU before any application
thread can interact with a device. Threads that belong to the same
process share the same page tables, thus the same MSR value.
-PASID is cleared when a process is created. The PASID allocation and MSR
-programming may occur long after a process and its threads have been created.
-One thread must call iommu_sva_bind_device() to allocate the PASID for the
-process. If a thread uses ENQCMD without the MSR first being populated, a #GP
-will be raised. The kernel will update the PASID MSR with the PASID for all
-threads in the process. A single process PASID can be used simultaneously
-with multiple devices since they all share the same address space.
-
-One thread can call iommu_sva_unbind_device() to free the allocated PASID.
-The kernel will clear the PASID MSR for all threads belonging to the process.
-
-New threads inherit the MSR value from the parent.
+PASID Life Cycle Management
+===========================
+
+PASID is initialized as INVALID_IOASID (-1) when a process is created.
+
+Only processes that access SVA-capable devices need to have a PASID
+allocated. This allocation happens when a process opens/binds an SVA-capable
+device but finds no PASID for this process. Subsequent binds of the same, or
+other devices will share the same PASID.
+
+Although the PASID is allocated to the process by opening a device,
+it is not active in any of the threads of that process. It's loaded to the
+IA32_PASID MSR lazily when a thread tries to submit a work descriptor
+to a device using the ENQCMD.
+
+That first access will trigger a #GP fault because the IA32_PASID MSR
+has not been initialized with the PASID value assigned to the process
+when the device was opened. The Linux #GP handler notes that a PASID has
+been allocated for the process, and so initializes the IA32_PASID MSR
+and returns so that the ENQCMD instruction is re-executed.
+
+On fork(2) or exec(2) the PASID is removed from the process as it no
+longer has the same address space that it had when the device was opened.
+
+On clone(2) the new task shares the same address space, so will be
+able to use the PASID allocated to the process. The IA32_PASID is not
+preemptively initialized as the PASID value might not be allocated yet or
+the kernel does not know whether this thread is going to access the device
+and the cleared IA32_PASID MSR reduces context switch overhead by xstate
+init optimization. Since #GP faults have to be handled on any threads that
+were created before the PASID was assigned to the mm of the process, newly
+created threads might as well be treated in a consistent way.
+
+Due to complexity of freeing the PASID and clearing all IA32_PASID MSRs in
+all threads in unbind, free the PASID lazily only on mm exit.
+
+If a process does a close(2) of the device file descriptor and munmap(2)
+of the device MMIO portal, then the driver will unbind the device. The
+PASID is still marked VALID in the PASID_MSR for any threads in the
+process that accessed the device. But this is harmless as without the
+MMIO portal they cannot submit new work to the device.
Relationships
=============
diff --git a/MAINTAINERS b/MAINTAINERS
index ea3e6c914384..d2bf8f0cdca3 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -190,8 +190,9 @@ M: Johannes Berg <johannes@sipsolutions.net>
L: linux-wireless@vger.kernel.org
S: Maintained
W: https://wireless.wiki.kernel.org/
-T: git git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211.git
-T: git git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next.git
+Q: https://patchwork.kernel.org/project/linux-wireless/list/
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/wireless/wireless.git
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/wireless/wireless-next.git
F: Documentation/driver-api/80211/cfg80211.rst
F: Documentation/networking/regulatory.rst
F: include/linux/ieee80211.h
@@ -388,11 +389,11 @@ L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
S: Maintained
F: drivers/acpi/arm64
-ACPI I2C MULTI INSTANTIATE DRIVER
+ACPI SERIAL MULTI INSTANTIATE DRIVER
M: Hans de Goede <hdegoede@redhat.com>
L: platform-driver-x86@vger.kernel.org
S: Maintained
-F: drivers/platform/x86/i2c-multi-instantiate.c
+F: drivers/platform/x86/serial-multi-instantiate.c
ACPI PCC(Platform Communication Channel) MAILBOX DRIVER
M: Sudeep Holla <sudeep.holla@arm.com>
@@ -1001,6 +1002,7 @@ L: linux-pm@vger.kernel.org
S: Supported
F: Documentation/admin-guide/pm/amd-pstate.rst
F: drivers/cpufreq/amd-pstate*
+F: tools/power/x86/amd_pstate_tracer/amd_pstate_trace.py
AMD PTDMA DRIVER
M: Sanjay R Mehta <sanju.mehta@amd.com>
@@ -1030,6 +1032,15 @@ S: Maintained
F: Documentation/hid/amd-sfh*
F: drivers/hid/amd-sfh-hid/
+AMPHION VPU CODEC V4L2 DRIVER
+M: Ming Qian <ming.qian@nxp.com>
+M: Shijie Qin <shijie.qin@nxp.com>
+M: Zhou Peng <eagle.zhou@nxp.com>
+L: linux-media@vger.kernel.org
+S: Maintained
+F: Documentation/devicetree/bindings/media/amphion,vpu.yaml
+F: drivers/media/platform/amphion/
+
AMS AS73211 DRIVER
M: Christian Eggers <ceggers@arri.de>
L: linux-iio@vger.kernel.org
@@ -1228,18 +1239,6 @@ S: Supported
F: drivers/clk/analogbits/*
F: include/linux/clk/analogbits*
-ANDES ARCHITECTURE
-M: Nick Hu <nickhu@andestech.com>
-M: Greentime Hu <green.hu@gmail.com>
-M: Vincent Chen <deanbo422@gmail.com>
-S: Supported
-T: git https://git.kernel.org/pub/scm/linux/kernel/git/greentime/linux.git
-F: Documentation/devicetree/bindings/interrupt-controller/andestech,ativic32.txt
-F: Documentation/devicetree/bindings/nds32/
-F: arch/nds32/
-N: nds32
-K: nds32
-
ANDROID CONFIG FRAGMENTS
M: Rob Herring <robh@kernel.org>
S: Supported
@@ -1619,6 +1618,7 @@ M: Olof Johansson <olof@lixom.net>
M: soc@kernel.org
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
S: Maintained
+C: irc://irc.libera.chat/armlinux
T: git git://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git
F: arch/arm/boot/dts/Makefile
F: arch/arm64/boot/dts/Makefile
@@ -1626,6 +1626,7 @@ F: arch/arm64/boot/dts/Makefile
ARM SUB-ARCHITECTURES
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
S: Maintained
+C: irc://irc.libera.chat/armlinux
T: git git://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git
F: arch/arm/mach-*/
F: arch/arm/plat-*/
@@ -1684,9 +1685,9 @@ S: Maintained
F: drivers/clk/sunxi/
ARM/Allwinner sunXi SoC support
-M: Maxime Ripard <mripard@kernel.org>
M: Chen-Yu Tsai <wens@csie.org>
-R: Jernej Skrabec <jernej.skrabec@gmail.com>
+M: Jernej Skrabec <jernej.skrabec@gmail.com>
+M: Samuel Holland <samuel@sholland.org>
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
S: Maintained
T: git git://git.kernel.org/pub/scm/linux/kernel/git/sunxi/linux.git
@@ -1766,7 +1767,7 @@ T: git https://github.com/AsahiLinux/linux.git
F: Documentation/devicetree/bindings/arm/apple.yaml
F: Documentation/devicetree/bindings/arm/apple/*
F: Documentation/devicetree/bindings/i2c/apple,i2c.yaml
-F: Documentation/devicetree/bindings/interrupt-controller/apple,aic.yaml
+F: Documentation/devicetree/bindings/interrupt-controller/apple,*
F: Documentation/devicetree/bindings/mailbox/apple,mailbox.yaml
F: Documentation/devicetree/bindings/pci/apple,pcie.yaml
F: Documentation/devicetree/bindings/pinctrl/apple,pinctrl.yaml
@@ -1779,6 +1780,7 @@ F: drivers/irqchip/irq-apple-aic.c
F: drivers/mailbox/apple-mailbox.c
F: drivers/pinctrl/pinctrl-apple-gpio.c
F: drivers/soc/apple/*
+F: drivers/watchdog/apple_wdt.c
F: include/dt-bindings/interrupt-controller/apple-aic.h
F: include/dt-bindings/pinctrl/apple.h
F: include/linux/apple-mailbox.h
@@ -2115,13 +2117,6 @@ F: Documentation/devicetree/bindings/arm/intel,keembay.yaml
F: arch/arm64/boot/dts/intel/keembay-evm.dts
F: arch/arm64/boot/dts/intel/keembay-soc.dtsi
-ARM/INTEL RESEARCH IMOTE/STARGATE 2 MACHINE SUPPORT
-M: Jonathan Cameron <jic23@cam.ac.uk>
-L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
-S: Maintained
-F: arch/arm/mach-pxa/stargate2.c
-F: drivers/pcmcia/pxa2xx_stargate2.c
-
ARM/INTEL XSC3 (MANZANO) ARM CORE
M: Lennert Buytenhek <kernel@wantstofly.org>
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
@@ -2250,7 +2245,7 @@ F: drivers/phy/mediatek/
ARM/Microchip (AT91) SoC support
M: Nicolas Ferre <nicolas.ferre@microchip.com>
M: Alexandre Belloni <alexandre.belloni@bootlin.com>
-M: Ludovic Desroches <ludovic.desroches@microchip.com>
+M: Claudiu Beznea <claudiu.beznea@microchip.com>
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
S: Supported
W: http://www.linux4sam.org
@@ -2363,6 +2358,7 @@ L: openbmc@lists.ozlabs.org (moderated for non-subscribers)
S: Supported
F: Documentation/devicetree/bindings/*/*/*npcm*
F: Documentation/devicetree/bindings/*/*npcm*
+F: Documentation/devicetree/bindings/arm/npcm/*
F: arch/arm/boot/dts/nuvoton-npcm*
F: arch/arm/mach-npcm/
F: drivers/*/*npcm*
@@ -2373,6 +2369,7 @@ ARM/NUVOTON WPCM450 ARCHITECTURE
M: Jonathan Neuschäfer <j.neuschaefer@gmx.net>
L: openbmc@lists.ozlabs.org (moderated for non-subscribers)
S: Maintained
+W: https://github.com/neuschaefer/wpcm450/wiki
F: Documentation/devicetree/bindings/*/*wpcm*
F: arch/arm/boot/dts/nuvoton-wpcm450*
F: arch/arm/mach-npcm/wpcm450.c
@@ -2527,6 +2524,7 @@ M: Magnus Damm <magnus.damm@gmail.com>
L: linux-renesas-soc@vger.kernel.org
S: Supported
Q: http://patchwork.kernel.org/project/linux-renesas-soc/list/
+C: irc://irc.libera.chat/renesas-soc
T: git git://git.kernel.org/pub/scm/linux/kernel/git/geert/renesas-devel.git next
F: Documentation/devicetree/bindings/arm/renesas.yaml
F: arch/arm64/boot/dts/renesas/
@@ -2568,11 +2566,14 @@ F: sound/soc/rockchip/
N: rockchip
ARM/SAMSUNG S3C, S5P AND EXYNOS ARM ARCHITECTURES
-M: Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>
+M: Krzysztof Kozlowski <krzk@kernel.org>
+R: Alim Akhtar <alim.akhtar@samsung.com>
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
L: linux-samsung-soc@vger.kernel.org
S: Maintained
+C: irc://irc.libera.chat/linux-exynos
Q: https://patchwork.kernel.org/project/linux-samsung-soc/list/
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/krzk/linux.git
F: Documentation/arm/samsung/
F: Documentation/devicetree/bindings/arm/samsung/
F: Documentation/devicetree/bindings/power/pd-samsung.yaml
@@ -2607,7 +2608,7 @@ M: Åukasz Stelmach <l.stelmach@samsung.com>
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
L: linux-media@vger.kernel.org
S: Maintained
-F: drivers/media/platform/s5p-g2d/
+F: drivers/media/platform/samsung/s5p-g2d/
ARM/SAMSUNG S5P SERIES HDMI CEC SUBSYSTEM SUPPORT
M: Marek Szyprowski <m.szyprowski@samsung.com>
@@ -2624,7 +2625,7 @@ M: Sylwester Nawrocki <s.nawrocki@samsung.com>
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
L: linux-media@vger.kernel.org
S: Maintained
-F: drivers/media/platform/s5p-jpeg/
+F: drivers/media/platform/samsung/s5p-jpeg/
ARM/SAMSUNG S5P SERIES Multi Format Codec (MFC) SUPPORT
M: Marek Szyprowski <m.szyprowski@samsung.com>
@@ -2632,7 +2633,7 @@ M: Andrzej Hajda <andrzej.hajda@intel.com>
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
L: linux-media@vger.kernel.org
S: Maintained
-F: drivers/media/platform/s5p-mfc/
+F: drivers/media/platform/samsung/s5p-mfc/
ARM/SHMOBILE ARM ARCHITECTURE
M: Geert Uytterhoeven <geert+renesas@glider.be>
@@ -2640,6 +2641,7 @@ M: Magnus Damm <magnus.damm@gmail.com>
L: linux-renesas-soc@vger.kernel.org
S: Supported
Q: http://patchwork.kernel.org/project/linux-renesas-soc/list/
+C: irc://irc.libera.chat/renesas-soc
T: git git://git.kernel.org/pub/scm/linux/kernel/git/geert/renesas-devel.git next
F: Documentation/devicetree/bindings/arm/renesas.yaml
F: arch/arm/boot/dts/emev2*
@@ -2701,7 +2703,7 @@ F: drivers/clocksource/clksrc_st_lpc.c
F: drivers/cpufreq/sti-cpufreq.c
F: drivers/dma/st_fdma*
F: drivers/i2c/busses/i2c-st.c
-F: drivers/media/platform/sti/c8sectpfe/
+F: drivers/media/platform/st/sti/c8sectpfe/
F: drivers/media/rc/st_rc.c
F: drivers/mmc/host/sdhci-st.c
F: drivers/phy/st/phy-miphy28lp.c
@@ -2732,7 +2734,7 @@ N: stm32
N: stm
ARM/Synaptics SoC support
-M: Jisheng Zhang <Jisheng.Zhang@synaptics.com>
+M: Jisheng Zhang <jszhang@kernel.org>
M: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
S: Maintained
@@ -2753,6 +2755,14 @@ S: Maintained
F: Documentation/devicetree/bindings/media/tegra-cec.txt
F: drivers/media/cec/platform/tegra/
+ARM/TESLA FSD SoC SUPPORT
+M: Alim Akhtar <alim.akhtar@samsung.com>
+M: linux-fsd@tesla.com
+L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
+L: linux-samsung-soc@vger.kernel.org
+S: Maintained
+F: arch/arm64/boot/dts/tesla*
+
ARM/TETON BGA MACHINE SUPPORT
M: "Mark F. Brown" <mark.brown314@gmail.com>
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
@@ -3017,7 +3027,7 @@ L: linux-media@vger.kernel.org
L: openbmc@lists.ozlabs.org (moderated for non-subscribers)
S: Maintained
F: Documentation/devicetree/bindings/media/aspeed-video.txt
-F: drivers/media/platform/aspeed-video.c
+F: drivers/media/platform/aspeed/
ASUS NOTEBOOKS AND EEEPC ACPI/WMI EXTRAS DRIVERS
M: Corentin Chary <corentin.chary@gmail.com>
@@ -3049,6 +3059,12 @@ L: linux-hwmon@vger.kernel.org
S: Maintained
F: drivers/hwmon/asus_wmi_ec_sensors.c
+ASUS EC HARDWARE MONITOR DRIVER
+M: Eugene Shalygin <eugene.shalygin@gmail.com>
+L: linux-hwmon@vger.kernel.org
+S: Maintained
+F: drivers/hwmon/asus-ec-sensors.c
+
ASUS WIRELESS RADIO CONTROL DRIVER
M: João Paulo Rechi Vita <jprvita@gmail.com>
L: platform-driver-x86@vger.kernel.org
@@ -3132,11 +3148,9 @@ W: https://wireless.wiki.kernel.org/en/users/Drivers/ath5k
F: drivers/net/wireless/ath/ath5k/
ATHEROS ATH6KL WIRELESS DRIVER
-M: Kalle Valo <kvalo@kernel.org>
L: linux-wireless@vger.kernel.org
-S: Supported
+S: Orphan
W: https://wireless.wiki.kernel.org/en/users/Drivers/ath6kl
-T: git git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/ath.git
F: drivers/net/wireless/ath/ath6kl/
ATI_REMOTE2 DRIVER
@@ -3193,6 +3207,7 @@ ATOMIC INFRASTRUCTURE
M: Will Deacon <will@kernel.org>
M: Peter Zijlstra <peterz@infradead.org>
R: Boqun Feng <boqun.feng@gmail.com>
+R: Mark Rutland <mark.rutland@arm.com>
L: linux-kernel@vger.kernel.org
S: Maintained
F: arch/*/include/asm/atomic*.h
@@ -3374,7 +3389,7 @@ L: linux-media@vger.kernel.org
S: Supported
W: https://linuxtv.org
T: git git://linuxtv.org/media_tree.git
-F: drivers/media/platform/sti/bdisp
+F: drivers/media/platform/st/sti/bdisp
BECKHOFF CX5020 ETHERCAT MASTER DRIVER
M: Dariusz Marcinkiewicz <reksio@newterm.pl>
@@ -3435,6 +3450,7 @@ F: Documentation/ABI/stable/sysfs-block
F: Documentation/block/
F: block/
F: drivers/block/
+F: include/linux/bio.h
F: include/linux/blk*
F: kernel/trace/blktrace.c
F: lib/sbitmap.c
@@ -3522,6 +3538,8 @@ F: net/sched/act_bpf.c
F: net/sched/cls_bpf.c
F: samples/bpf/
F: scripts/bpf_doc.py
+F: scripts/pahole-flags.sh
+F: scripts/pahole-version.sh
F: tools/bpf/
F: tools/lib/bpf/
F: tools/testing/selftests/bpf/
@@ -3814,9 +3832,6 @@ BROADCOM BRCM80211 IEEE802.11n WIRELESS DRIVER
M: Arend van Spriel <aspriel@gmail.com>
M: Franky Lin <franky.lin@broadcom.com>
M: Hante Meuleman <hante.meuleman@broadcom.com>
-M: Chi-hsien Lin <chi-hsien.lin@infineon.com>
-M: Wright Feng <wright.feng@infineon.com>
-M: Chung-hsien Hsu <chung-hsien.hsu@infineon.com>
L: linux-wireless@vger.kernel.org
L: brcm80211-dev-list.pdl@broadcom.com
L: SHA-cyfmac-dev-list@infineon.com
@@ -3900,7 +3915,7 @@ M: Scott Branden <sbranden@broadcom.com>
M: bcm-kernel-feedback-list@broadcom.com
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
S: Maintained
-T: git git://github.com/broadcom/cygnus-linux.git
+T: git git://github.com/broadcom/stblinux.git
F: arch/arm64/boot/dts/broadcom/northstar2/*
F: arch/arm64/boot/dts/broadcom/stingray/*
F: drivers/clk/bcm/clk-ns*
@@ -4156,9 +4171,8 @@ N: csky
K: csky
CA8210 IEEE-802.15.4 RADIO DRIVER
-M: Harry Morris <h.morris@cascoda.com>
L: linux-wpan@vger.kernel.org
-S: Maintained
+S: Orphan
W: https://github.com/Cascoda/ca8210-linux.git
F: Documentation/devicetree/bindings/net/ieee802154/ca8210.txt
F: drivers/net/ieee802154/ca8210.c
@@ -4239,7 +4253,7 @@ L: linux-media@vger.kernel.org
S: Orphan
T: git git://linuxtv.org/media_tree.git
F: Documentation/admin-guide/media/cafe_ccic*
-F: drivers/media/platform/marvell-ccic/
+F: drivers/media/platform/marvell/
CAIF NETWORK LAYER
L: netdev@vger.kernel.org
@@ -4442,6 +4456,7 @@ F: drivers/power/supply/cw2015_battery.c
CEPH COMMON CODE (LIBCEPH)
M: Ilya Dryomov <idryomov@gmail.com>
M: Jeff Layton <jlayton@kernel.org>
+M: Xiubo Li <xiubli@redhat.com>
L: ceph-devel@vger.kernel.org
S: Supported
W: http://ceph.com/
@@ -4452,6 +4467,7 @@ F: net/ceph/
CEPH DISTRIBUTED FILE SYSTEM CLIENT (CEPH)
M: Jeff Layton <jlayton@kernel.org>
+M: Xiubo Li <xiubli@redhat.com>
M: Ilya Dryomov <idryomov@gmail.com>
L: ceph-devel@vger.kernel.org
S: Supported
@@ -4543,6 +4559,7 @@ F: drivers/platform/chrome/
CHROMEOS EC CODEC DRIVER
M: Cheng-Yi Chiang <cychiang@chromium.org>
+M: Tzung-Bi Shih <tzungbi@google.com>
R: Guenter Roeck <groeck@chromium.org>
S: Maintained
F: Documentation/devicetree/bindings/sound/google,cros-ec-codec.yaml
@@ -4762,7 +4779,7 @@ M: Philipp Zabel <p.zabel@pengutronix.de>
L: linux-media@vger.kernel.org
S: Maintained
F: Documentation/devicetree/bindings/media/coda.yaml
-F: drivers/media/platform/coda/
+F: drivers/media/platform/chips-media/
CODE OF CONDUCT
M: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
@@ -4908,7 +4925,8 @@ F: kernel/cgroup/cpuset.c
CONTROL GROUP - MEMORY RESOURCE CONTROLLER (MEMCG)
M: Johannes Weiner <hannes@cmpxchg.org>
M: Michal Hocko <mhocko@kernel.org>
-M: Vladimir Davydov <vdavydov.dev@gmail.com>
+M: Roman Gushchin <roman.gushchin@linux.dev>
+M: Shakeel Butt <shakeelb@google.com>
L: cgroups@vger.kernel.org
L: linux-mm@kvack.org
S: Maintained
@@ -5311,6 +5329,7 @@ DATA ACCESS MONITOR
M: SeongJae Park <sj@kernel.org>
L: linux-mm@kvack.org
S: Maintained
+F: Documentation/ABI/testing/sysfs-kernel-mm-damon
F: Documentation/admin-guide/mm/damon/
F: Documentation/vm/damon/
F: include/linux/damon.h
@@ -5404,6 +5423,7 @@ F: drivers/platform/x86/dell/dell-rbtn.*
DELL LAPTOP SMM DRIVER
M: Pali Rohár <pali@kernel.org>
S: Maintained
+F: Documentation/ABI/obsolete/procfs-i8k
F: drivers/hwmon/dell-smm-hwmon.c
F: include/uapi/linux/i8k.h
@@ -5473,7 +5493,7 @@ L: linux-media@vger.kernel.org
S: Supported
W: https://linuxtv.org
T: git git://linuxtv.org/media_tree.git
-F: drivers/media/platform/sti/delta
+F: drivers/media/platform/st/sti/delta
DELTA AHE-50DC FAN CONTROL MODULE DRIVER
M: Zev Weiss <zev@bewilderbeest.net>
@@ -5585,7 +5605,7 @@ F: include/linux/devm-helpers.h
DEVICE-MAPPER (LVM)
M: Alasdair Kergon <agk@redhat.com>
-M: Mike Snitzer <snitzer@redhat.com>
+M: Mike Snitzer <snitzer@kernel.org>
M: dm-devel@redhat.com
L: dm-devel@redhat.com
S: Maintained
@@ -5733,7 +5753,7 @@ T: git git://anongit.freedesktop.org/drm/drm-misc
F: Documentation/driver-api/dma-buf.rst
F: drivers/dma-buf/
F: include/linux/*fence.h
-F: include/linux/dma-buf*
+F: include/linux/dma-buf.h
F: include/linux/dma-resv.h
K: \bdma_(?:buf|fence|resv)\b
@@ -5772,7 +5792,7 @@ F: tools/testing/selftests/dma/
DMA-BUF HEAPS FRAMEWORK
M: Sumit Semwal <sumit.semwal@linaro.org>
-R: Benjamin Gaignard <benjamin.gaignard@linaro.org>
+R: Benjamin Gaignard <benjamin.gaignard@collabora.com>
R: Liam Mark <lmark@codeaurora.org>
R: Laura Abbott <labbott@redhat.com>
R: Brian Starkey <Brian.Starkey@arm.com>
@@ -6076,7 +6096,8 @@ L: dri-devel@lists.freedesktop.org
T: git git://anongit.freedesktop.org/drm/drm-misc
S: Maintained
F: drivers/gpu/drm/panel/panel-lvds.c
-F: Documentation/devicetree/bindings/display/panel/lvds.yaml
+F: Documentation/devicetree/bindings/display/lvds.yaml
+F: Documentation/devicetree/bindings/display/panel/panel-lvds.yaml
DRM DRIVER FOR MANTIX MLAF057WE51 PANELS
M: Guido Günther <agx@sigxcpu.org>
@@ -6105,6 +6126,14 @@ T: git git://anongit.freedesktop.org/drm/drm-misc
F: Documentation/devicetree/bindings/display/multi-inno,mi0283qt.txt
F: drivers/gpu/drm/tiny/mi0283qt.c
+DRM DRIVER FOR MIPI DBI compatible panels
+M: Noralf Trønnes <noralf@tronnes.org>
+S: Maintained
+W: https://github.com/notro/panel-mipi-dbi/wiki
+T: git git://anongit.freedesktop.org/drm/drm-misc
+F: Documentation/devicetree/bindings/display/panel/panel-mipi-dbi-spi.yaml
+F: drivers/gpu/drm/tiny/panel-mipi-dbi.c
+
DRM DRIVER FOR MSM ADRENO GPU
M: Rob Clark <robdclark@gmail.com>
M: Sean Paul <sean@poorly.run>
@@ -6125,6 +6154,13 @@ T: git git://anongit.freedesktop.org/drm/drm-misc
F: Documentation/devicetree/bindings/display/panel/novatek,nt35510.yaml
F: drivers/gpu/drm/panel/panel-novatek-nt35510.c
+DRM DRIVER FOR NOVATEK NT35560 PANELS
+M: Linus Walleij <linus.walleij@linaro.org>
+S: Maintained
+T: git git://anongit.freedesktop.org/drm/drm-misc
+F: Documentation/devicetree/bindings/display/panel/sony,acx424akp.yaml
+F: drivers/gpu/drm/panel/panel-novatek-nt35560.c
+
DRM DRIVER FOR NOVATEK NT36672A PANELS
M: Sumit Semwal <sumit.semwal@linaro.org>
S: Maintained
@@ -6161,6 +6197,13 @@ T: git git://anongit.freedesktop.org/drm/drm-misc
F: Documentation/devicetree/bindings/display/repaper.txt
F: drivers/gpu/drm/tiny/repaper.c
+DRM DRIVER FOR SOLOMON SSD130X OLED DISPLAYS
+M: Javier Martinez Canillas <javierm@redhat.com>
+S: Maintained
+T: git git://anongit.freedesktop.org/drm/drm-misc
+F: Documentation/devicetree/bindings/display/solomon,ssd1307fb.yaml
+F: drivers/gpu/drm/solomon/ssd130x*
+
DRM DRIVER FOR QEMU'S CIRRUS DEVICE
M: Dave Airlie <airlied@redhat.com>
M: Gerd Hoffmann <kraxel@redhat.com>
@@ -6249,12 +6292,6 @@ T: git git://anongit.freedesktop.org/drm/drm-misc
F: Documentation/devicetree/bindings/display/sitronix,st7735r.yaml
F: drivers/gpu/drm/tiny/st7735r.c
-DRM DRIVER FOR SONY ACX424AKP PANELS
-M: Linus Walleij <linus.walleij@linaro.org>
-S: Maintained
-T: git git://anongit.freedesktop.org/drm/drm-misc
-F: drivers/gpu/drm/panel/panel-sony-acx424akp.c
-
DRM DRIVER FOR ST-ERICSSON MCDE
M: Linus Walleij <linus.walleij@linaro.org>
S: Maintained
@@ -6301,8 +6338,8 @@ T: git git://anongit.freedesktop.org/drm/drm-misc
F: drivers/gpu/drm/vboxvideo/
DRM DRIVER FOR VMWARE VIRTUAL GPU
-M: "VMware Graphics" <linux-graphics-maintainer@vmware.com>
M: Zack Rusin <zackr@vmware.com>
+R: VMware Graphics Reviewers <linux-graphics-maintainer@vmware.com>
L: dri-devel@lists.freedesktop.org
S: Supported
T: git git://anongit.freedesktop.org/drm/drm-misc
@@ -6502,7 +6539,7 @@ F: Documentation/devicetree/bindings/display/rockchip/
F: drivers/gpu/drm/rockchip/
DRM DRIVERS FOR STI
-M: Benjamin Gaignard <benjamin.gaignard@linaro.org>
+M: Alain Volmat <alain.volmat@foss.st.com>
L: dri-devel@lists.freedesktop.org
S: Maintained
T: git git://anongit.freedesktop.org/drm/drm-misc
@@ -6511,8 +6548,8 @@ F: drivers/gpu/drm/sti
DRM DRIVERS FOR STM
M: Yannick Fertre <yannick.fertre@foss.st.com>
+M: Raphael Gallais-Pou <raphael.gallais-pou@foss.st.com>
M: Philippe Cornu <philippe.cornu@foss.st.com>
-M: Benjamin Gaignard <benjamin.gaignard@linaro.org>
L: dri-devel@lists.freedesktop.org
S: Maintained
T: git git://anongit.freedesktop.org/drm/drm-misc
@@ -7006,12 +7043,6 @@ L: linux-edac@vger.kernel.org
S: Maintained
F: drivers/edac/sb_edac.c
-EDAC-SIFIVE
-M: Yash Shah <yash.shah@sifive.com>
-L: linux-edac@vger.kernel.org
-S: Supported
-F: drivers/edac/sifive_edac.c
-
EDAC-SKYLAKE
M: Tony Luck <tony.luck@intel.com>
L: linux-edac@vger.kernel.org
@@ -7182,7 +7213,7 @@ F: drivers/net/can/usb/etas_es58x/
ETHERNET BRIDGE
M: Roopa Prabhu <roopa@nvidia.com>
-M: Nikolay Aleksandrov <nikolay@nvidia.com>
+M: Nikolay Aleksandrov <razor@blackwall.org>
L: bridge@lists.linux-foundation.org (moderated for non-subscribers)
L: netdev@vger.kernel.org
S: Maintained
@@ -7208,8 +7239,10 @@ F: drivers/net/mdio/of_mdio.c
F: drivers/net/pcs/
F: drivers/net/phy/
F: include/dt-bindings/net/qca-ar803x.h
+F: include/linux/linkmode.h
F: include/linux/*mdio*.h
F: include/linux/mdio/*.h
+F: include/linux/mii.h
F: include/linux/of_net.h
F: include/linux/phy.h
F: include/linux/phy_fixed.h
@@ -7223,6 +7256,9 @@ F: net/core/of_net.c
EXEC & BINFMT API
R: Eric Biederman <ebiederm@xmission.com>
R: Kees Cook <keescook@chromium.org>
+L: linux-mm@kvack.org
+S: Supported
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux.git for-next/execve
F: arch/alpha/kernel/binfmt_loader.c
F: arch/x86/ia32/ia32_aout.c
F: fs/*binfmt_*.c
@@ -7230,6 +7266,7 @@ F: fs/exec.c
F: include/linux/binfmts.h
F: include/linux/elf.h
F: include/uapi/linux/binfmts.h
+F: include/uapi/linux/elf.h
F: tools/testing/selftests/exec/
N: asm/elf.h
N: binfmt
@@ -7265,7 +7302,9 @@ Extended Verification Module (EVM)
M: Mimi Zohar <zohar@linux.ibm.com>
L: linux-integrity@vger.kernel.org
S: Supported
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/zohar/linux-integrity.git
F: security/integrity/evm/
+F: security/integrity/
EXTENSIBLE FIRMWARE INTERFACE (EFI)
M: Ard Biesheuvel <ardb@kernel.org>
@@ -7573,6 +7612,12 @@ S: Maintained
W: http://floatingpoint.sourceforge.net/emulator/index.html
F: arch/x86/math-emu/
+FRAMEBUFFER CORE
+M: Daniel Vetter <daniel@ffwll.ch>
+F: drivers/video/fbdev/core/
+S: Odd Fixes
+T: git git://anongit.freedesktop.org/drm/drm-misc
+
FRAMEBUFFER LAYER
M: Helge Deller <deller@gmx.de>
L: linux-fbdev@vger.kernel.org
@@ -7736,8 +7781,7 @@ M: Qiang Zhao <qiang.zhao@nxp.com>
L: linuxppc-dev@lists.ozlabs.org
S: Maintained
F: drivers/soc/fsl/qe/
-F: include/soc/fsl/*qe*.h
-F: include/soc/fsl/*ucc*.h
+F: include/soc/fsl/qe/
FREESCALE QUICC ENGINE UCC ETHERNET DRIVER
M: Li Yang <leoyang.li@nxp.com>
@@ -7768,6 +7812,7 @@ F: Documentation/devicetree/bindings/misc/fsl,dpaa2-console.yaml
F: Documentation/devicetree/bindings/soc/fsl/
F: drivers/soc/fsl/
F: include/linux/fsl/
+F: include/soc/fsl/
FREESCALE SOC FS_ENET DRIVER
M: Pantelis Antoniou <pantelis.antoniou@gmail.com>
@@ -7778,10 +7823,10 @@ F: drivers/net/ethernet/freescale/fs_enet/
F: include/linux/fs_enet_pd.h
FREESCALE SOC SOUND DRIVERS
-M: Nicolin Chen <nicoleotsuka@gmail.com>
+M: Shengjiu Wang <shengjiu.wang@gmail.com>
M: Xiubo Li <Xiubo.Lee@gmail.com>
R: Fabio Estevam <festevam@gmail.com>
-R: Shengjiu Wang <shengjiu.wang@gmail.com>
+R: Nicolin Chen <nicoleotsuka@gmail.com>
L: alsa-devel@alsa-project.org (moderated for non-subscribers)
L: linuxppc-dev@lists.ozlabs.org
S: Maintained
@@ -7922,6 +7967,12 @@ L: platform-driver-x86@vger.kernel.org
S: Maintained
F: drivers/platform/x86/fujitsu-tablet.c
+FUNGIBLE ETHERNET DRIVERS
+M: Dimitris Michailidis <dmichail@fungible.com>
+L: netdev@vger.kernel.org
+S: Supported
+F: drivers/net/ethernet/fungible/
+
FUSE: FILESYSTEM IN USERSPACE
M: Miklos Szeredi <miklos@szeredi.hu>
L: linux-fsdevel@vger.kernel.org
@@ -8635,7 +8686,7 @@ S: Maintained
F: drivers/gpio/gpio-hisi.c
HISILICON HIGH PERFORMANCE RSA ENGINE DRIVER (HPRE)
-M: Zaibo Xu <xuzaibo@huawei.com>
+M: Longfang Liu <liulongfang@huawei.com>
L: linux-crypto@vger.kernel.org
S: Maintained
F: Documentation/ABI/testing/debugfs-hisi-hpre
@@ -8695,9 +8746,9 @@ L: linux-crypto@vger.kernel.org
S: Maintained
F: Documentation/ABI/testing/debugfs-hisi-zip
F: drivers/crypto/hisilicon/qm.c
-F: drivers/crypto/hisilicon/qm.h
F: drivers/crypto/hisilicon/sgl.c
F: drivers/crypto/hisilicon/zip/
+F: include/linux/hisi_acc_qm.h
HISILICON ROCE DRIVER
M: Wenpeng Liang <liangwenpeng@huawei.com>
@@ -8715,8 +8766,8 @@ F: Documentation/devicetree/bindings/scsi/hisilicon-sas.txt
F: drivers/scsi/hisi_sas/
HISILICON SECURITY ENGINE V2 DRIVER (SEC2)
-M: Zaibo Xu <xuzaibo@huawei.com>
M: Kai Ye <yekai13@huawei.com>
+M: Longfang Liu <liulongfang@huawei.com>
L: linux-crypto@vger.kernel.org
S: Maintained
F: Documentation/ABI/testing/debugfs-hisi-sec
@@ -8747,7 +8798,7 @@ F: Documentation/devicetree/bindings/mfd/hisilicon,hi6421-spmi-pmic.yaml
F: drivers/mfd/hi6421-spmi-pmic.c
HISILICON TRUE RANDOM NUMBER GENERATOR V2 SUPPORT
-M: Zaibo Xu <xuzaibo@huawei.com>
+M: Weili Qian <qianweili@huawei.com>
S: Maintained
F: drivers/crypto/hisilicon/trng/trng.c
@@ -8861,7 +8912,7 @@ L: linux-media@vger.kernel.org
S: Supported
W: https://linuxtv.org
T: git git://linuxtv.org/media_tree.git
-F: drivers/media/platform/sti/hva
+F: drivers/media/platform/st/sti/hva
HWPOISON MEMORY FAILURE HANDLING
M: Naoya Horiguchi <naoya.horiguchi@nec.com>
@@ -8896,6 +8947,12 @@ L: linux-media@vger.kernel.org
S: Maintained
F: drivers/media/i2c/hi846.c
+HYNIX HI847 SENSOR DRIVER
+M: Shawn Tu <shawnx.tu@intel.com>
+L: linux-media@vger.kernel.org
+S: Maintained
+F: drivers/media/i2c/hi847.c
+
Hyper-V/Azure CORE AND DRIVERS
M: "K. Y. Srinivasan" <kys@microsoft.com>
M: Haiyang Zhang <haiyangz@microsoft.com>
@@ -9250,6 +9307,15 @@ S: Maintained
W: https://github.com/o2genum/ideapad-slidebar
F: drivers/input/misc/ideapad_slidebar.c
+IDMAPPED MOUNTS
+M: Christian Brauner <brauner@kernel.org>
+L: linux-fsdevel@vger.kernel.org
+S: Maintained
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/brauner/linux.git
+F: Documentation/filesystems/idmappings.rst
+F: tools/testing/selftests/mount_setattr/
+F: include/linux/mnt_idmapping.h
+
IDT VersaClock 5 CLOCK DRIVER
M: Luca Ceresoli <luca@lucaceresoli.net>
S: Maintained
@@ -9507,6 +9573,7 @@ L: linux-integrity@vger.kernel.org
S: Supported
T: git git://git.kernel.org/pub/scm/linux/kernel/git/zohar/linux-integrity.git
F: security/integrity/ima/
+F: security/integrity/
INTEL 810/815 FRAMEBUFFER DRIVER
M: Antonino Daplas <adaplas@gmail.com>
@@ -10000,6 +10067,14 @@ L: linux-iio@vger.kernel.org
F: Documentation/devicetree/bindings/counter/interrupt-counter.yaml
F: drivers/counter/interrupt-cnt.c
+INTERSIL ISL7998X VIDEO DECODER DRIVER
+M: Michael Tretter <m.tretter@pengutronix.de>
+R: Pengutronix Kernel Team <kernel@pengutronix.de>
+L: linux-media@vger.kernel.org
+S: Maintained
+F: Documentation/devicetree/bindings/media/i2c/isil,isl79987.yaml
+F: drivers/media/i2c/isl7998x.c
+
INVENSENSE ICM-426xx IMU DRIVER
M: Jean-Baptiste Maneyrol <jmaneyrol@invensense.com>
L: linux-iio@vger.kernel.org
@@ -10047,6 +10122,13 @@ F: include/linux/iova.h
F: include/linux/of_iommu.h
F: include/uapi/linux/iommu.h
+IOSYS-MAP HELPERS
+M: Thomas Zimmermann <tzimmermann@suse.de>
+L: dri-devel@lists.freedesktop.org
+S: Maintained
+T: git git://anongit.freedesktop.org/drm/drm-misc
+F: include/linux/iosys-map.h
+
IO_URING
M: Jens Axboe <axboe@kernel.dk>
R: Pavel Begunkov <asml.silence@gmail.com>
@@ -10299,7 +10381,7 @@ M: Mikhail Ulyanov <mikhail.ulyanov@cogentembedded.com>
L: linux-media@vger.kernel.org
L: linux-renesas-soc@vger.kernel.org
S: Maintained
-F: drivers/media/platform/rcar_jpu.c
+F: drivers/media/platform/renesas/rcar_jpu.c
JSM Neo PCI based serial card
L: linux-serial@vger.kernel.org
@@ -10438,6 +10520,8 @@ KERNEL REGRESSIONS
M: Thorsten Leemhuis <linux@leemhuis.info>
L: regressions@lists.linux.dev
S: Supported
+F: Documentation/admin-guide/reporting-regressions.rst
+F: Documentation/process/handling-regressions.rst
KERNEL SELFTEST FRAMEWORK
M: Shuah Khan <shuah@kernel.org>
@@ -10545,8 +10629,8 @@ F: arch/riscv/kvm/
KERNEL VIRTUAL MACHINE for s390 (KVM/s390)
M: Christian Borntraeger <borntraeger@linux.ibm.com>
M: Janosch Frank <frankja@linux.ibm.com>
+M: Claudio Imbrenda <imbrenda@linux.ibm.com>
R: David Hildenbrand <david@redhat.com>
-R: Claudio Imbrenda <imbrenda@linux.ibm.com>
L: kvm@vger.kernel.org
S: Supported
W: http://www.ibm.com/developerworks/linux/linux390/
@@ -10643,6 +10727,14 @@ F: include/linux/keyctl.h
F: include/uapi/linux/keyctl.h
F: security/keys/
+KEYS/KEYRINGS_INTEGRITY
+M: Jarkko Sakkinen <jarkko@kernel.org>
+M: Mimi Zohar <zohar@linux.ibm.com>
+L: linux-integrity@vger.kernel.org
+L: keyrings@vger.kernel.org
+S: Supported
+F: security/integrity/platform_certs
+
KFENCE
M: Alexander Potapenko <glider@google.com>
M: Marco Elver <elver@google.com>
@@ -10748,7 +10840,6 @@ L7 BPF FRAMEWORK
M: John Fastabend <john.fastabend@gmail.com>
M: Daniel Borkmann <daniel@iogearbox.net>
M: Jakub Sitnicki <jakub@cloudflare.com>
-M: Lorenz Bauer <lmb@cloudflare.com>
L: netdev@vger.kernel.org
L: bpf@vger.kernel.org
S: Maintained
@@ -10877,6 +10968,12 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/axboe/linux-block.git
F: drivers/ata/pata_arasan_cf.c
F: include/linux/pata_arasan_cf_data.h
+LIBATA PATA DRIVERS
+R: Sergey Shtylyov <s.shtylyov@omp.ru>
+L: linux-ide@vger.kernel.org
+F: drivers/ata/ata_*.c
+F: drivers/ata/pata_*.c
+
LIBATA PATA FARADAY FTIDE010 AND GEMINI SATA BRIDGE DRIVERS
M: Linus Walleij <linus.walleij@linaro.org>
L: linux-ide@vger.kernel.org
@@ -11107,12 +11204,17 @@ F: lib/list-test.c
LITEX PLATFORM
M: Karol Gugala <kgugala@antmicro.com>
M: Mateusz Holenko <mholenko@antmicro.com>
+M: Gabriel Somlo <gsomlo@gmail.com>
+M: Joel Stanley <joel@jms.id.au>
S: Maintained
F: Documentation/devicetree/bindings/*/litex,*.yaml
F: arch/openrisc/boot/dts/or1klitex.dts
-F: drivers/soc/litex/litex_soc_ctrl.c
-F: drivers/tty/serial/liteuart.c
F: include/linux/litex.h
+F: drivers/tty/serial/liteuart.c
+F: drivers/soc/litex/*
+F: drivers/net/ethernet/litex/*
+F: drivers/mmc/host/litex_mmc.c
+N: litex
LIVE PATCHING
M: Josh Poimboeuf <jpoimboe@redhat.com>
@@ -11305,6 +11407,13 @@ S: Maintained
W: http://linux-test-project.github.io/
T: git git://github.com/linux-test-project/ltp.git
+LYNX 28G SERDES PHY DRIVER
+M: Ioana Ciornei <ioana.ciornei@nxp.com>
+L: netdev@vger.kernel.org
+S: Supported
+F: Documentation/devicetree/bindings/phy/fsl,lynx-28g.yaml
+F: drivers/phy/freescale/phy-fsl-lynx-28g.c
+
LYNX PCS MODULE
M: Ioana Ciornei <ioana.ciornei@nxp.com>
L: netdev@vger.kernel.org
@@ -11366,8 +11475,9 @@ M: Johannes Berg <johannes@sipsolutions.net>
L: linux-wireless@vger.kernel.org
S: Maintained
W: https://wireless.wiki.kernel.org/
-T: git git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211.git
-T: git git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next.git
+Q: https://patchwork.kernel.org/project/linux-wireless/list/
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/wireless/wireless.git
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/wireless/wireless-next.git
F: Documentation/networking/mac80211-injection.rst
F: Documentation/networking/mac80211_hwsim/mac80211_hwsim.rst
F: drivers/net/wireless/mac80211_hwsim.[ch]
@@ -11651,7 +11761,7 @@ F: drivers/iio/proximity/mb1232.c
MAXIM MAX17040 FAMILY FUEL GAUGE DRIVERS
R: Iskren Chernev <iskren.chernev@gmail.com>
-R: Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>
+R: Krzysztof Kozlowski <krzk@kernel.org>
R: Marek Szyprowski <m.szyprowski@samsung.com>
R: Matheus Castello <matheus@castello.eng.br>
L: linux-pm@vger.kernel.org
@@ -11661,7 +11771,7 @@ F: drivers/power/supply/max17040_battery.c
MAXIM MAX17042 FAMILY FUEL GAUGE DRIVERS
R: Hans de Goede <hdegoede@redhat.com>
-R: Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>
+R: Krzysztof Kozlowski <krzk@kernel.org>
R: Marek Szyprowski <m.szyprowski@samsung.com>
R: Sebastian Krzyszkowiak <sebastian.krzyszkowiak@puri.sm>
R: Purism Kernel Team <kernel@puri.sm>
@@ -11695,7 +11805,7 @@ MAXIM MAX77802 PMIC REGULATOR DEVICE DRIVER
M: Javier Martinez Canillas <javier@dowhile0.org>
L: linux-kernel@vger.kernel.org
S: Supported
-F: Documentation/devicetree/bindings/*/*max77802.txt
+F: Documentation/devicetree/bindings/*/*max77802.yaml
F: drivers/regulator/max77802-regulator.c
F: include/dt-bindings/*/*max77802.h
@@ -11706,23 +11816,26 @@ F: Documentation/devicetree/bindings/power/supply/maxim,max77976.yaml
F: drivers/power/supply/max77976_charger.c
MAXIM MUIC CHARGER DRIVERS FOR EXYNOS BASED BOARDS
-M: Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>
+M: Krzysztof Kozlowski <krzk@kernel.org>
M: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
L: linux-pm@vger.kernel.org
S: Supported
+F: Documentation/devicetree/bindings/power/supply/maxim,max14577.yaml
F: drivers/power/supply/max14577_charger.c
F: drivers/power/supply/max77693_charger.c
MAXIM PMIC AND MUIC DRIVERS FOR EXYNOS BASED BOARDS
M: Chanwoo Choi <cw00.choi@samsung.com>
-M: Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>
+M: Krzysztof Kozlowski <krzk@kernel.org>
M: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
L: linux-kernel@vger.kernel.org
S: Supported
+F: Documentation/devicetree/bindings/*/maxim,max14577.yaml
F: Documentation/devicetree/bindings/*/maxim,max77686.yaml
+F: Documentation/devicetree/bindings/*/maxim,max77843.yaml
F: Documentation/devicetree/bindings/clock/maxim,max77686.txt
-F: Documentation/devicetree/bindings/mfd/max14577.txt
F: Documentation/devicetree/bindings/mfd/max77693.txt
+F: drivers/*/*max77843.c
F: drivers/*/max14577*.c
F: drivers/*/max77686*.c
F: drivers/*/max77693*.c
@@ -11818,7 +11931,7 @@ M: Philipp Zabel <p.zabel@pengutronix.de>
L: linux-media@vger.kernel.org
S: Maintained
T: git git://linuxtv.org/media_tree.git
-F: drivers/media/platform/imx-pxp.[ch]
+F: drivers/media/platform/nxp/imx-pxp.[ch]
MEDIA DRIVERS FOR ASCOT2E
M: Sergey Kozlov <serjk@netup.ru>
@@ -11883,10 +11996,10 @@ L: linux-media@vger.kernel.org
S: Maintained
T: git git://linuxtv.org/media_tree.git
F: Documentation/admin-guide/media/imx7.rst
+F: Documentation/devicetree/bindings/media/nxp,imx-mipi-csi2.yaml
F: Documentation/devicetree/bindings/media/nxp,imx7-csi.yaml
-F: Documentation/devicetree/bindings/media/nxp,imx7-mipi-csi2.yaml
+F: drivers/media/platform/imx/imx-mipi-csis.c
F: drivers/staging/media/imx/imx7-media-csi.c
-F: drivers/staging/media/imx/imx7-mipi-csis.c
MEDIA DRIVERS FOR HELENE
M: Abylay Ospan <aospan@netup.ru>
@@ -11941,7 +12054,7 @@ L: linux-tegra@vger.kernel.org
S: Maintained
T: git git://linuxtv.org/media_tree.git
F: Documentation/devicetree/bindings/media/nvidia,tegra-vde.txt
-F: drivers/staging/media/tegra-vde/
+F: drivers/media/platform/nvidia/tegra-vde/
MEDIA DRIVERS FOR RENESAS - CEU
M: Jacopo Mondi <jacopo@jmondi.org>
@@ -11950,7 +12063,7 @@ L: linux-renesas-soc@vger.kernel.org
S: Supported
T: git git://linuxtv.org/media_tree.git
F: Documentation/devicetree/bindings/media/renesas,ceu.yaml
-F: drivers/media/platform/renesas-ceu.c
+F: drivers/media/platform/renesas/renesas-ceu.c
F: include/media/drv-intf/renesas-ceu.h
MEDIA DRIVERS FOR RENESAS - DRIF
@@ -11960,7 +12073,7 @@ L: linux-renesas-soc@vger.kernel.org
S: Supported
T: git git://linuxtv.org/media_tree.git
F: Documentation/devicetree/bindings/media/renesas,drif.yaml
-F: drivers/media/platform/rcar_drif.c
+F: drivers/media/platform/renesas/rcar_drif.c
MEDIA DRIVERS FOR RENESAS - FCP
M: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
@@ -11969,7 +12082,7 @@ L: linux-renesas-soc@vger.kernel.org
S: Supported
T: git git://linuxtv.org/media_tree.git
F: Documentation/devicetree/bindings/media/renesas,fcp.yaml
-F: drivers/media/platform/rcar-fcp.c
+F: drivers/media/platform/renesas/rcar-fcp.c
F: include/media/rcar-fcp.h
MEDIA DRIVERS FOR RENESAS - FDP1
@@ -11979,7 +12092,7 @@ L: linux-renesas-soc@vger.kernel.org
S: Supported
T: git git://linuxtv.org/media_tree.git
F: Documentation/devicetree/bindings/media/renesas,fdp1.yaml
-F: drivers/media/platform/rcar_fdp1.c
+F: drivers/media/platform/renesas/rcar_fdp1.c
MEDIA DRIVERS FOR RENESAS - VIN
M: Niklas Söderlund <niklas.soderlund@ragnatech.se>
@@ -11990,8 +12103,8 @@ T: git git://linuxtv.org/media_tree.git
F: Documentation/devicetree/bindings/media/renesas,csi2.yaml
F: Documentation/devicetree/bindings/media/renesas,isp.yaml
F: Documentation/devicetree/bindings/media/renesas,vin.yaml
-F: drivers/media/platform/rcar-isp.c
-F: drivers/media/platform/rcar-vin/
+F: drivers/media/platform/renesas/rcar-isp.c
+F: drivers/media/platform/renesas/rcar-vin/
MEDIA DRIVERS FOR RENESAS - VSP1
M: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
@@ -12001,7 +12114,7 @@ L: linux-renesas-soc@vger.kernel.org
S: Supported
T: git git://linuxtv.org/media_tree.git
F: Documentation/devicetree/bindings/media/renesas,vsp1.yaml
-F: drivers/media/platform/vsp1/
+F: drivers/media/platform/renesas/vsp1/
MEDIA DRIVERS FOR ST STV0910 DEMODULATOR ICs
L: linux-media@vger.kernel.org
@@ -12023,7 +12136,7 @@ L: linux-media@vger.kernel.org
S: Supported
T: git git://linuxtv.org/media_tree.git
F: Documentation/devicetree/bindings/media/st,stm32-dcmi.yaml
-F: drivers/media/platform/stm32/stm32-dcmi.c
+F: drivers/media/platform/st/stm32/stm32-dcmi.c
MEDIA INPUT INFRASTRUCTURE (V4L/DVB)
M: Mauro Carvalho Chehab <mchehab@kernel.org>
@@ -12107,7 +12220,7 @@ M: Rick Chang <rick.chang@mediatek.com>
M: Bin Liu <bin.liu@mediatek.com>
S: Supported
F: Documentation/devicetree/bindings/media/mediatek-jpeg-decoder.txt
-F: drivers/media/platform/mtk-jpeg/
+F: drivers/media/platform/mediatek/jpeg/
MEDIATEK MDP DRIVER
M: Minghsiu Tsai <minghsiu.tsai@mediatek.com>
@@ -12115,8 +12228,8 @@ M: Houlong Wei <houlong.wei@mediatek.com>
M: Andrew-CT Chen <andrew-ct.chen@mediatek.com>
S: Supported
F: Documentation/devicetree/bindings/media/mediatek-mdp.txt
-F: drivers/media/platform/mtk-mdp/
-F: drivers/media/platform/mtk-vpu/
+F: drivers/media/platform/mediatek/mdp/
+F: drivers/media/platform/mediatek/vpu/
MEDIATEK MEDIA DRIVER
M: Tiffany Lin <tiffany.lin@mediatek.com>
@@ -12124,8 +12237,8 @@ M: Andrew-CT Chen <andrew-ct.chen@mediatek.com>
S: Supported
F: Documentation/devicetree/bindings/media/mediatek-vcodec.txt
F: Documentation/devicetree/bindings/media/mediatek-vpu.txt
-F: drivers/media/platform/mtk-vcodec/
-F: drivers/media/platform/mtk-vpu/
+F: drivers/media/platform/mediatek/vcodec/
+F: drivers/media/platform/mediatek/vpu/
MEDIATEK MMC/SD/SDIO DRIVER
M: Chaotian Jing <chaotian.jing@mediatek.com>
@@ -12141,6 +12254,7 @@ R: Shayne Chen <shayne.chen@mediatek.com>
R: Sean Wang <sean.wang@mediatek.com>
L: linux-wireless@vger.kernel.org
S: Maintained
+F: Documentation/devicetree/bindings/net/wireless/mediatek,mt76.yaml
F: drivers/net/wireless/mediatek/mt76/
MEDIATEK MT7601U WIRELESS LAN DRIVER
@@ -12396,7 +12510,7 @@ F: include/uapi/linux/membarrier.h
F: kernel/sched/membarrier.c
MEMBLOCK
-M: Mike Rapoport <rppt@linux.ibm.com>
+M: Mike Rapoport <rppt@kernel.org>
L: linux-mm@kvack.org
S: Maintained
F: Documentation/core-api/boot-time-mm.rst
@@ -12404,7 +12518,7 @@ F: include/linux/memblock.h
F: mm/memblock.c
MEMORY CONTROLLER DRIVERS
-M: Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>
+M: Krzysztof Kozlowski <krzk@kernel.org>
L: linux-kernel@vger.kernel.org
S: Maintained
T: git git://git.kernel.org/pub/scm/linux/kernel/git/krzk/linux-mem-ctrl.git
@@ -12500,7 +12614,7 @@ L: linux-amlogic@lists.infradead.org
S: Supported
T: git git://linuxtv.org/media_tree.git
F: Documentation/devicetree/bindings/media/amlogic,axg-ge2d.yaml
-F: drivers/media/platform/meson/ge2d/
+F: drivers/media/platform/amlogic/meson-ge2d/
MESON NAND CONTROLLER DRIVER FOR AMLOGIC SOCS
M: Liang Yang <liang.yang@amlogic.com>
@@ -12582,6 +12696,13 @@ L: alsa-devel@alsa-project.org (moderated for non-subscribers)
S: Supported
F: sound/soc/atmel
+MICROCHIP CSI2DC DRIVER
+M: Eugen Hristev <eugen.hristev@microchip.com>
+L: linux-media@vger.kernel.org
+S: Supported
+F: Documentation/devicetree/bindings/media/microchip,csi2dc.yaml
+F: drivers/media/platform/atmel/microchip-csi2dc.c
+
MICROCHIP ECC DRIVER
M: Tudor Ambarus <tudor.ambarus@microchip.com>
L: linux-crypto@vger.kernel.org
@@ -12607,11 +12728,8 @@ L: linux-media@vger.kernel.org
S: Supported
F: Documentation/devicetree/bindings/media/atmel,isc.yaml
F: Documentation/devicetree/bindings/media/microchip,xisc.yaml
-F: drivers/media/platform/atmel/atmel-isc-base.c
-F: drivers/media/platform/atmel/atmel-isc-regs.h
-F: drivers/media/platform/atmel/atmel-isc.h
-F: drivers/media/platform/atmel/atmel-sama5d2-isc.c
-F: drivers/media/platform/atmel/atmel-sama7g5-isc.c
+F: drivers/media/platform/atmel/atmel-isc*
+F: drivers/media/platform/atmel/atmel-sama*-isc*
F: include/linux/atmel-isc-media.h
MICROCHIP ISI DRIVER
@@ -13294,8 +13412,8 @@ W: http://www.iptables.org/
W: http://www.nftables.org/
Q: http://patchwork.ozlabs.org/project/netfilter-devel/list/
C: irc://irc.libera.chat/netfilter
-T: git git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf.git
-T: git git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf-next.git
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/netfilter/nf.git
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/netfilter/nf-next.git
F: include/linux/netfilter*
F: include/linux/netfilter/
F: include/net/netfilter/
@@ -13352,6 +13470,7 @@ F: net/core/drop_monitor.c
NETWORKING DRIVERS
M: "David S. Miller" <davem@davemloft.net>
M: Jakub Kicinski <kuba@kernel.org>
+M: Paolo Abeni <pabeni@redhat.com>
L: netdev@vger.kernel.org
S: Maintained
Q: https://patchwork.kernel.org/project/netdevbpf/list/
@@ -13374,9 +13493,10 @@ NETWORKING DRIVERS (WIRELESS)
M: Kalle Valo <kvalo@kernel.org>
L: linux-wireless@vger.kernel.org
S: Maintained
-Q: http://patchwork.kernel.org/project/linux-wireless/list/
-T: git git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/wireless-drivers.git
-T: git git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/wireless-drivers-next.git
+W: https://wireless.wiki.kernel.org/
+Q: https://patchwork.kernel.org/project/linux-wireless/list/
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/wireless/wireless.git
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/wireless/wireless-next.git
F: Documentation/devicetree/bindings/net/wireless/
F: drivers/net/wireless/
@@ -13397,6 +13517,7 @@ F: tools/testing/selftests/drivers/net/dsa/
NETWORKING [GENERAL]
M: "David S. Miller" <davem@davemloft.net>
M: Jakub Kicinski <kuba@kernel.org>
+M: Paolo Abeni <pabeni@redhat.com>
L: netdev@vger.kernel.org
S: Maintained
Q: https://patchwork.kernel.org/project/netdevbpf/list/
@@ -13449,7 +13570,11 @@ L: netdev@vger.kernel.org
S: Maintained
T: git git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net.git
F: arch/x86/net/*
+F: include/linux/ip.h
+F: include/linux/ipv6*
+F: include/net/fib*
F: include/net/ip*
+F: include/net/route.h
F: net/ipv4/
F: net/ipv6/
@@ -13510,10 +13635,6 @@ F: include/net/tls.h
F: include/uapi/linux/tls.h
F: net/tls/*
-NETWORKING [WIRELESS]
-L: linux-wireless@vger.kernel.org
-Q: http://patchwork.kernel.org/project/linux-wireless/list/
-
NETXEN (1/10) GbE SUPPORT
M: Manish Chopra <manishc@marvell.com>
M: Rahul Verma <rahulv@marvell.com>
@@ -13540,7 +13661,7 @@ F: include/uapi/linux/nexthop.h
F: net/ipv4/nexthop.c
NFC SUBSYSTEM
-M: Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>
+M: Krzysztof Kozlowski <krzk@kernel.org>
L: linux-nfc@lists.01.org (subscribers-only)
L: netdev@vger.kernel.org
S: Maintained
@@ -13561,7 +13682,7 @@ F: tools/testing/selftests/nci/
NFS, SUNRPC, AND LOCKD CLIENTS
M: Trond Myklebust <trond.myklebust@hammerspace.com>
-M: Anna Schumaker <anna.schumaker@netapp.com>
+M: Anna Schumaker <anna@kernel.org>
L: linux-nfs@vger.kernel.org
S: Maintained
W: http://client.linux-nfs.org
@@ -13674,7 +13795,7 @@ F: scripts/nsdeps
NTB AMD DRIVER
M: Sanjay R Mehta <sanju.mehta@amd.com>
M: Shyam Sundar S K <Shyam-sundar.S-k@amd.com>
-L: linux-ntb@googlegroups.com
+L: ntb@lists.linux.dev
S: Supported
F: drivers/ntb/hw/amd/
@@ -13682,7 +13803,7 @@ NTB DRIVER CORE
M: Jon Mason <jdmason@kudzu.us>
M: Dave Jiang <dave.jiang@intel.com>
M: Allen Hubbe <allenbh@gmail.com>
-L: linux-ntb@googlegroups.com
+L: ntb@lists.linux.dev
S: Supported
W: https://github.com/jonmason/ntb/wiki
T: git git://github.com/jonmason/ntb.git
@@ -13694,13 +13815,13 @@ F: tools/testing/selftests/ntb/
NTB IDT DRIVER
M: Serge Semin <fancer.lancer@gmail.com>
-L: linux-ntb@googlegroups.com
+L: ntb@lists.linux.dev
S: Supported
F: drivers/ntb/hw/idt/
NTB INTEL DRIVER
M: Dave Jiang <dave.jiang@intel.com>
-L: linux-ntb@googlegroups.com
+L: ntb@lists.linux.dev
S: Supported
W: https://github.com/davejiang/linux/wiki
T: git https://github.com/davejiang/linux.git
@@ -13854,7 +13975,7 @@ F: Documentation/devicetree/bindings/regulator/nxp,pf8x00-regulator.yaml
F: drivers/regulator/pf8x00-regulator.c
NXP PTN5150A CC LOGIC AND EXTCON DRIVER
-M: Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>
+M: Krzysztof Kozlowski <krzk@kernel.org>
L: linux-kernel@vger.kernel.org
S: Maintained
F: Documentation/devicetree/bindings/extcon/extcon-ptn5150.yaml
@@ -14067,7 +14188,7 @@ M: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
L: linux-media@vger.kernel.org
S: Maintained
F: Documentation/devicetree/bindings/media/ti,omap3isp.txt
-F: drivers/media/platform/omap3isp/
+F: drivers/media/platform/ti/omap3isp/
F: drivers/staging/media/omap4iss/
OMAP MMC SUPPORT
@@ -14175,6 +14296,12 @@ M: Harald Welte <laforge@gnumonks.org>
S: Maintained
F: drivers/char/pcmcia/cm4040_cs.*
+OMNIVISION OG01A1B SENSOR DRIVER
+M: Shawn Tu <shawnx.tu@intel.com>
+L: linux-media@vger.kernel.org
+S: Maintained
+F: drivers/media/i2c/og01a1b.c
+
OMNIVISION OV02A10 SENSOR DRIVER
M: Dongchun Zhu <dongchun.zhu@mediatek.com>
L: linux-media@vger.kernel.org
@@ -14183,6 +14310,13 @@ T: git git://linuxtv.org/media_tree.git
F: Documentation/devicetree/bindings/media/i2c/ovti,ov02a10.yaml
F: drivers/media/i2c/ov02a10.c
+OMNIVISION OV08D10 SENSOR DRIVER
+M: Jimmy Su <jimmy.su@intel.com>
+L: linux-media@vger.kernel.org
+S: Maintained
+T: git git://linuxtv.org/media_tree.git
+F: drivers/media/i2c/ov08d10.c
+
OMNIVISION OV13858 SENSOR DRIVER
M: Sakari Ailus <sakari.ailus@linux.intel.com>
L: linux-media@vger.kernel.org
@@ -14379,6 +14513,7 @@ M: Rob Herring <robh+dt@kernel.org>
M: Frank Rowand <frowand.list@gmail.com>
L: devicetree@vger.kernel.org
S: Maintained
+C: irc://irc.libera.chat/devicetree
W: http://www.devicetree.org/
T: git git://git.kernel.org/pub/scm/linux/kernel/git/robh/linux.git
F: Documentation/ABI/testing/sysfs-firmware-ofw
@@ -14390,6 +14525,7 @@ OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS
M: Rob Herring <robh+dt@kernel.org>
L: devicetree@vger.kernel.org
S: Maintained
+C: irc://irc.libera.chat/devicetree
Q: http://patchwork.ozlabs.org/project/devicetree-bindings/list/
T: git git://git.kernel.org/pub/scm/linux/kernel/git/robh/linux.git
F: Documentation/devicetree/
@@ -14576,8 +14712,9 @@ F: include/uapi/linux/ppdev.h
PARAVIRT_OPS INTERFACE
M: Juergen Gross <jgross@suse.com>
-M: Deep Shah <sdeep@vmware.com>
-M: "VMware, Inc." <pv-drivers@vmware.com>
+M: Srivatsa S. Bhat (VMware) <srivatsa@csail.mit.edu>
+R: Alexey Makhalov <amakhalov@vmware.com>
+R: VMware PV-Drivers Reviewers <pv-drivers@vmware.com>
L: virtualization@lists.linux-foundation.org
L: x86@kernel.org
S: Supported
@@ -15123,7 +15260,7 @@ M: Ingo Molnar <mingo@redhat.com>
M: Arnaldo Carvalho de Melo <acme@kernel.org>
R: Mark Rutland <mark.rutland@arm.com>
R: Alexander Shishkin <alexander.shishkin@linux.intel.com>
-R: Jiri Olsa <jolsa@redhat.com>
+R: Jiri Olsa <jolsa@kernel.org>
R: Namhyung Kim <namhyung@kernel.org>
L: linux-perf-users@vger.kernel.org
L: linux-kernel@vger.kernel.org
@@ -15278,14 +15415,16 @@ F: drivers/pinctrl/renesas/
PIN CONTROLLER - SAMSUNG
M: Tomasz Figa <tomasz.figa@gmail.com>
-M: Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>
+M: Krzysztof Kozlowski <krzk@kernel.org>
M: Sylwester Nawrocki <s.nawrocki@samsung.com>
+R: Alim Akhtar <alim.akhtar@samsung.com>
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
L: linux-samsung-soc@vger.kernel.org
S: Maintained
+C: irc://irc.libera.chat/linux-exynos
Q: https://patchwork.kernel.org/project/linux-samsung-soc/list/
T: git git://git.kernel.org/pub/scm/linux/kernel/git/pinctrl/samsung.git
-F: Documentation/devicetree/bindings/pinctrl/samsung-pinctrl.txt
+F: Documentation/devicetree/bindings/pinctrl/samsung,pinctrl*yaml
F: drivers/pinctrl/samsung/
F: include/dt-bindings/pinctrl/samsung.h
@@ -15504,6 +15643,7 @@ F: drivers/net/ppp/pptp.c
PRESSURE STALL INFORMATION (PSI)
M: Johannes Weiner <hannes@cmpxchg.org>
+M: Suren Baghdasaryan <surenb@google.com>
S: Maintained
F: include/linux/psi*
F: kernel/sched/psi.c
@@ -15539,6 +15679,7 @@ M: Iurii Zaikin <yzaikin@google.com>
L: linux-kernel@vger.kernel.org
L: linux-fsdevel@vger.kernel.org
S: Maintained
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/mcgrof/linux.git sysctl-next
F: fs/proc/proc_sysctl.c
F: include/linux/sysctl.h
F: kernel/sysctl-test.c
@@ -15886,18 +16027,20 @@ S: Supported
W: https://wireless.wiki.kernel.org/en/users/Drivers/ath10k
T: git git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/ath.git
F: drivers/net/wireless/ath/ath10k/
+F: Documentation/devicetree/bindings/net/wireless/qcom,ath10k.txt
QUALCOMM ATHEROS ATH11K WIRELESS DRIVER
M: Kalle Valo <kvalo@kernel.org>
L: ath11k@lists.infradead.org
S: Supported
T: git git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/ath.git
+F: Documentation/devicetree/bindings/net/wireless/qcom,ath11k.yaml
F: drivers/net/wireless/ath/ath11k/
QUALCOMM ATHEROS ATH9K WIRELESS DRIVER
-M: ath9k-devel@qca.qualcomm.com
+M: Toke Høiland-Jørgensen <toke@toke.dk>
L: linux-wireless@vger.kernel.org
-S: Supported
+S: Maintained
W: https://wireless.wiki.kernel.org/en/users/Drivers/ath9k
F: Documentation/devicetree/bindings/net/wireless/qca,ath9k.yaml
F: drivers/net/wireless/ath/ath9k/
@@ -15972,14 +16115,6 @@ F: Documentation/devicetree/bindings/misc/qcom,fastrpc.txt
F: drivers/misc/fastrpc.c
F: include/uapi/misc/fastrpc.h
-QUALCOMM GENERIC INTERFACE I2C DRIVER
-M: Akash Asthana <akashast@codeaurora.org>
-M: Mukesh Savaliya <msavaliy@codeaurora.org>
-L: linux-i2c@vger.kernel.org
-L: linux-arm-msm@vger.kernel.org
-S: Supported
-F: drivers/i2c/busses/i2c-qcom-geni.c
-
QUALCOMM HEXAGON ARCHITECTURE
M: Brian Cain <bcain@codeaurora.org>
L: linux-hexagon@vger.kernel.org
@@ -16051,8 +16186,8 @@ F: Documentation/devicetree/bindings/mtd/qcom,nandc.yaml
F: drivers/mtd/nand/raw/qcom_nandc.c
QUALCOMM RMNET DRIVER
-M: Subash Abhinov Kasiviswanathan <subashab@codeaurora.org>
-M: Sean Tranchetti <stranche@codeaurora.org>
+M: Subash Abhinov Kasiviswanathan <quic_subashab@quicinc.com>
+M: Sean Tranchetti <quic_stranche@quicinc.com>
L: netdev@vger.kernel.org
S: Maintained
F: Documentation/networking/device_drivers/cellular/qualcomm/rmnet.rst
@@ -16078,11 +16213,10 @@ F: Documentation/devicetree/bindings/media/*venus*
F: drivers/media/platform/qcom/venus/
QUALCOMM WCN36XX WIRELESS DRIVER
-M: Kalle Valo <kvalo@kernel.org>
+M: Loic Poulain <loic.poulain@linaro.org>
L: wcn36xx@lists.infradead.org
S: Supported
W: https://wireless.wiki.kernel.org/en/users/Drivers/wcn36xx
-T: git git://github.com/KrasnikovEugene/wcn36xx.git
F: drivers/net/wireless/ath/wcn36xx/
QUANTENNA QTNFMAC WIRELESS DRIVER
@@ -16184,6 +16318,7 @@ M: Jason A. Donenfeld <Jason@zx2c4.com>
T: git https://git.kernel.org/pub/scm/linux/kernel/git/crng/random.git
S: Maintained
F: drivers/char/random.c
+F: drivers/virt/vmgenid.c
RAPIDIO SUBSYSTEM
M: Matt Porter <mporter@kernel.crashing.org>
@@ -16298,6 +16433,8 @@ F: tools/testing/selftests/resctrl/
READ-COPY UPDATE (RCU)
M: "Paul E. McKenney" <paulmck@kernel.org>
+M: Frederic Weisbecker <frederic@kernel.org> (kernel/rcu/tree_nocb.h)
+M: Neeraj Upadhyay <quic_neeraju@quicinc.com> (kernel/rcu/tasks.h)
M: Josh Triplett <josh@joshtriplett.org>
R: Steven Rostedt <rostedt@goodmis.org>
R: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
@@ -16345,10 +16482,10 @@ F: drivers/watchdog/realtek_otto_wdt.c
REALTEK RTL83xx SMI DSA ROUTER CHIPS
M: Linus Walleij <linus.walleij@linaro.org>
+M: Alvin Å ipraga <alsi@bang-olufsen.dk>
S: Maintained
-F: Documentation/devicetree/bindings/net/dsa/realtek-smi.txt
-F: drivers/net/dsa/realtek-smi*
-F: drivers/net/dsa/rtl83*
+F: Documentation/devicetree/bindings/net/dsa/realtek.yaml
+F: drivers/net/dsa/realtek/*
REALTEK WIRELESS DRIVER (rtlwifi family)
M: Ping-Ke Shih <pkshih@realtek.com>
@@ -16464,6 +16601,14 @@ F: Documentation/devicetree/bindings/i2c/renesas,rmobile-iic.yaml
F: drivers/i2c/busses/i2c-rcar.c
F: drivers/i2c/busses/i2c-sh_mobile.c
+RENESAS R-CAR SATA DRIVER
+R: Sergey Shtylyov <s.shtylyov@omp.ru>
+S: Supported
+L: linux-ide@vger.kernel.org
+L: linux-renesas-soc@vger.kernel.org
+F: Documentation/devicetree/bindings/ata/renesas,rcar-sata.yaml
+F: drivers/ata/sata_rcar.c
+
RENESAS R-CAR THERMAL DRIVERS
M: Niklas Söderlund <niklas.soderlund@ragnatech.se>
L: linux-renesas-soc@vger.kernel.org
@@ -16532,8 +16677,9 @@ M: Johannes Berg <johannes@sipsolutions.net>
L: linux-wireless@vger.kernel.org
S: Maintained
W: https://wireless.wiki.kernel.org/
-T: git git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211.git
-T: git git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next.git
+Q: https://patchwork.kernel.org/project/linux-wireless/list/
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/wireless/wireless.git
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/wireless/wireless-next.git
F: Documentation/ABI/stable/sysfs-class-rfkill
F: Documentation/driver-api/rfkill.rst
F: include/linux/rfkill.h
@@ -16604,8 +16750,7 @@ F: Documentation/devicetree/bindings/sound/rockchip,i2s-tdm.yaml
F: sound/soc/rockchip/rockchip_i2s_tdm.*
ROCKCHIP ISP V1 DRIVER
-M: Helen Koike <helen.koike@collabora.com>
-M: Dafna Hirschfeld <dafna.hirschfeld@collabora.com>
+M: Dafna Hirschfeld <dafna@fastmail.com>
L: linux-media@vger.kernel.org
L: linux-rockchip@lists.infradead.org
S: Maintained
@@ -16798,8 +16943,8 @@ F: drivers/video/fbdev/savage/
S390
M: Heiko Carstens <hca@linux.ibm.com>
M: Vasily Gorbik <gor@linux.ibm.com>
-M: Christian Borntraeger <borntraeger@linux.ibm.com>
-R: Alexander Gordeev <agordeev@linux.ibm.com>
+M: Alexander Gordeev <agordeev@linux.ibm.com>
+R: Christian Borntraeger <borntraeger@linux.ibm.com>
R: Sven Schnelle <svens@linux.ibm.com>
L: linux-s390@vger.kernel.org
S: Supported
@@ -16914,7 +17059,7 @@ W: http://www.ibm.com/developerworks/linux/linux390/
F: drivers/s390/scsi/zfcp_*
S3C ADC BATTERY DRIVER
-M: Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>
+M: Krzysztof Kozlowski <krzk@kernel.org>
L: linux-samsung-soc@vger.kernel.org
S: Odd Fixes
F: drivers/power/supply/s3c_adc_battery.c
@@ -16959,7 +17104,7 @@ F: Documentation/admin-guide/LSM/SafeSetID.rst
F: security/safesetid/
SAMSUNG AUDIO (ASoC) DRIVERS
-M: Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>
+M: Krzysztof Kozlowski <krzk@kernel.org>
M: Sylwester Nawrocki <s.nawrocki@samsung.com>
L: alsa-devel@alsa-project.org (moderated for non-subscribers)
S: Supported
@@ -16967,7 +17112,7 @@ F: Documentation/devicetree/bindings/sound/samsung*
F: sound/soc/samsung/
SAMSUNG EXYNOS PSEUDO RANDOM NUMBER GENERATOR (RNG) DRIVER
-M: Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>
+M: Krzysztof Kozlowski <krzk@kernel.org>
L: linux-crypto@vger.kernel.org
L: linux-samsung-soc@vger.kernel.org
S: Maintained
@@ -17002,7 +17147,7 @@ S: Maintained
F: drivers/platform/x86/samsung-laptop.c
SAMSUNG MULTIFUNCTION PMIC DEVICE DRIVERS
-M: Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>
+M: Krzysztof Kozlowski <krzk@kernel.org>
M: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
L: linux-kernel@vger.kernel.org
L: linux-samsung-soc@vger.kernel.org
@@ -17024,11 +17169,11 @@ M: Sylwester Nawrocki <sylvester.nawrocki@gmail.com>
L: linux-media@vger.kernel.org
L: linux-samsung-soc@vger.kernel.org
S: Maintained
-F: drivers/media/platform/s3c-camif/
+F: drivers/media/platform/samsung/s3c-camif/
F: include/media/drv-intf/s3c_camif.h
SAMSUNG S3FWRN5 NFC DRIVER
-M: Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>
+M: Krzysztof Kozlowski <krzk@kernel.org>
M: Krzysztof Opasiak <k.opasiak@samsung.com>
L: linux-nfc@lists.01.org (subscribers-only)
S: Maintained
@@ -17050,7 +17195,7 @@ S: Supported
F: drivers/media/i2c/s5k5baf.c
SAMSUNG S5P Security SubSystem (SSS) DRIVER
-M: Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>
+M: Krzysztof Kozlowski <krzk@kernel.org>
M: Vladimir Zapolskiy <vz@mleia.com>
L: linux-crypto@vger.kernel.org
L: linux-samsung-soc@vger.kernel.org
@@ -17064,12 +17209,13 @@ M: Sylwester Nawrocki <s.nawrocki@samsung.com>
L: linux-media@vger.kernel.org
S: Supported
Q: https://patchwork.linuxtv.org/project/linux-media/list/
-F: drivers/media/platform/exynos4-is/
+F: drivers/media/platform/samsung/exynos4-is/
SAMSUNG SOC CLOCK DRIVERS
M: Sylwester Nawrocki <s.nawrocki@samsung.com>
M: Tomasz Figa <tomasz.figa@gmail.com>
M: Chanwoo Choi <cw00.choi@samsung.com>
+R: Alim Akhtar <alim.akhtar@samsung.com>
L: linux-samsung-soc@vger.kernel.org
S: Supported
T: git git://git.kernel.org/pub/scm/linux/kernel/git/snawrocki/clk.git
@@ -17084,12 +17230,12 @@ F: include/linux/clk/samsung.h
F: include/linux/platform_data/clk-s3c2410.h
SAMSUNG SPI DRIVERS
-M: Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>
+M: Krzysztof Kozlowski <krzk@kernel.org>
M: Andi Shyti <andi@etezian.org>
L: linux-spi@vger.kernel.org
L: linux-samsung-soc@vger.kernel.org
S: Maintained
-F: Documentation/devicetree/bindings/spi/spi-samsung.txt
+F: Documentation/devicetree/bindings/spi/samsung,spi*.yaml
F: drivers/spi/spi-s3c*
F: include/linux/platform_data/spi-s3c64xx.h
F: include/linux/spi/s3c24xx-fiq.h
@@ -17101,11 +17247,12 @@ S: Supported
F: drivers/net/ethernet/samsung/sxgbe/
SAMSUNG THERMAL DRIVER
-M: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
+M: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
+M: Krzysztof Kozlowski <krzk@kernel.org>
L: linux-pm@vger.kernel.org
L: linux-samsung-soc@vger.kernel.org
-S: Supported
-T: git https://github.com/lmajewski/linux-samsung-thermal.git
+S: Maintained
+F: Documentation/devicetree/bindings/thermal/samsung,exynos-thermal.yaml
F: drivers/thermal/samsung/
SAMSUNG USB2 PHY DRIVER
@@ -17497,7 +17644,7 @@ F: include/media/i2c/rj54n1cb0c.h
SH_VOU V4L2 OUTPUT DRIVER
L: linux-media@vger.kernel.org
S: Orphan
-F: drivers/media/platform/sh_vou.c
+F: drivers/media/platform/renesas/sh_vou.c
F: include/media/drv-intf/sh_vou.h
SI2157 MEDIA DRIVER
@@ -17706,6 +17853,21 @@ S: Maintained
W: http://www.winischhofer.at/linuxsisusbvga.shtml
F: drivers/usb/misc/sisusbvga/
+SL28 CPLD MFD DRIVER
+M: Michael Walle <michael@walle.cc>
+S: Maintained
+F: Documentation/devicetree/bindings/gpio/kontron,sl28cpld-gpio.yaml
+F: Documentation/devicetree/bindings/hwmon/kontron,sl28cpld-hwmon.yaml
+F: Documentation/devicetree/bindings/interrupt-controller/kontron,sl28cpld-intc.yaml
+F: Documentation/devicetree/bindings/mfd/kontron,sl28cpld.yaml
+F: Documentation/devicetree/bindings/pwm/kontron,sl28cpld-pwm.yaml
+F: Documentation/devicetree/bindings/watchdog/kontron,sl28cpld-wdt.yaml
+F: drivers/gpio/gpio-sl28cpld.c
+F: drivers/hwmon/sl28cpld-hwmon.c
+F: drivers/irqchip/irq-sl28cpld.c
+F: drivers/pwm/pwm-sl28cpld.c
+F: drivers/watchdog/sl28cpld_wdt.c
+
SLAB ALLOCATOR
M: Christoph Lameter <cl@linux.com>
M: Pekka Enberg <penberg@kernel.org>
@@ -17713,8 +17875,10 @@ M: David Rientjes <rientjes@google.com>
M: Joonsoo Kim <iamjoonsoo.kim@lge.com>
M: Andrew Morton <akpm@linux-foundation.org>
M: Vlastimil Babka <vbabka@suse.cz>
+R: Roman Gushchin <roman.gushchin@linux.dev>
L: linux-mm@kvack.org
S: Maintained
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/vbabka/slab.git
F: include/linux/sl?b*.h
F: mm/sl?b*
@@ -18252,7 +18416,8 @@ F: Documentation/devicetree/bindings/iio/imu/st,lsm6dsx.yaml
F: drivers/iio/imu/st_lsm6dsx/
ST MIPID02 CSI-2 TO PARALLEL BRIDGE DRIVER
-M: Mickael Guene <mickael.guene@st.com>
+M: Benjamin Mugnier <benjamin.mugnier@foss.st.com>
+M: Sylvain Petinot <sylvain.petinot@foss.st.com>
L: linux-media@vger.kernel.org
S: Maintained
T: git git://linuxtv.org/media_tree.git
@@ -18422,7 +18587,7 @@ F: Documentation/devicetree/bindings/sound/st,sti-asoc-card.txt
F: sound/soc/sti/
STI CEC DRIVER
-M: Benjamin Gaignard <benjamin.gaignard@linaro.org>
+M: Alain Volmat <alain.volmat@foss.st.com>
S: Maintained
F: Documentation/devicetree/bindings/media/stih-cec.txt
F: drivers/media/cec/platform/sti/
@@ -18491,6 +18656,13 @@ S: Maintained
F: Documentation/devicetree/bindings/rtc/sunplus,sp7021-rtc.yaml
F: drivers/rtc/rtc-sunplus.c
+SUNPLUS SPI CONTROLLER INTERFACE DRIVER
+M: Li-hao Kuo <lhjeff911@gmail.com>
+L: linux-spi@vger.kernel.org
+S: Maintained
+F: Documentation/devicetree/bindings/spi/spi-sunplus-sp7021.yaml
+F: drivers/spi/spi-sunplus-sp7021.c
+
SUPERH
M: Yoshinori Sato <ysato@users.sourceforge.jp>
M: Rich Felker <dalias@libc.org>
@@ -19042,6 +19214,7 @@ TEXAS INSTRUMENTS ASoC DRIVERS
M: Peter Ujfalusi <peter.ujfalusi@gmail.com>
L: alsa-devel@alsa-project.org (moderated for non-subscribers)
S: Maintained
+F: Documentation/devicetree/bindings/sound/davinci-mcasp-audio.yaml
F: sound/soc/ti/
TEXAS INSTRUMENTS' DAC7612 DAC DRIVER
@@ -19222,7 +19395,7 @@ S: Maintained
W: https://linuxtv.org
Q: http://patchwork.linuxtv.org/project/linux-media/list/
T: git git://linuxtv.org/mhadli/v4l-dvb-davinci_devices.git
-F: drivers/media/platform/am437x/
+F: drivers/media/platform/ti/am437x/
TI BANDGAP AND THERMAL DRIVER
M: Eduardo Valentin <edubezval@gmail.com>
@@ -19281,7 +19454,7 @@ S: Maintained
W: https://linuxtv.org
Q: http://patchwork.linuxtv.org/project/linux-media/list/
T: git git://linuxtv.org/mhadli/v4l-dvb-davinci_devices.git
-F: drivers/media/platform/davinci/
+F: drivers/media/platform/ti/davinci/
F: include/media/davinci/
TI ENHANCED QUADRATURE ENCODER PULSE (eQEP) DRIVER
@@ -19367,7 +19540,8 @@ W: http://linuxtv.org/
Q: http://patchwork.linuxtv.org/project/linux-media/list/
F: Documentation/devicetree/bindings/media/ti,cal.yaml
F: Documentation/devicetree/bindings/media/ti,vpe.yaml
-F: drivers/media/platform/ti-vpe/
+F: drivers/media/platform/ti/cal/
+F: drivers/media/platform/ti/vpe/
TI WILINK WIRELESS DRIVERS
L: linux-wireless@vger.kernel.org
@@ -19438,6 +19612,15 @@ S: Maintained
F: Documentation/hwmon/tmp401.rst
F: drivers/hwmon/tmp401.c
+TMP464 HARDWARE MONITOR DRIVER
+M: Agathe Porte <agathe.porte@nokia.com>
+M: Guenter Roeck <linux@roeck-us.net>
+L: linux-hwmon@vger.kernel.org
+S: Maintained
+F: Documentation/devicetree/bindings/hwmon/ti,tmp464.yaml
+F: Documentation/hwmon/tmp464.rst
+F: drivers/hwmon/tmp464.c
+
TMP513 HARDWARE MONITOR DRIVER
M: Eric Tremblay <etremblay@distech-controls.com>
L: linux-hwmon@vger.kernel.org
@@ -19576,6 +19759,14 @@ F: Documentation/trace/timerlat-tracer.rst
F: Documentation/trace/hwlat_detector.rst
F: arch/*/kernel/trace.c
+Real-time Linux Analysis (RTLA) tools
+M: Daniel Bristot de Oliveira <bristot@kernel.org>
+M: Steven Rostedt <rostedt@goodmis.org>
+L: linux-trace-devel@vger.kernel.org
+S: Maintained
+F: Documentation/tools/rtla/
+F: tools/tracing/rtla/
+
TRADITIONAL CHINESE DOCUMENTATION
M: Hu Haowen <src.res@email.cn>
L: linux-doc-tw-discuss@lists.sourceforge.net
@@ -20245,6 +20436,13 @@ L: kvm@vger.kernel.org
S: Maintained
F: drivers/vfio/fsl-mc/
+VFIO HISILICON PCI DRIVER
+M: Longfang Liu <liulongfang@huawei.com>
+M: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>
+L: kvm@vger.kernel.org
+S: Maintained
+F: drivers/vfio/pci/hisilicon/
+
VFIO MEDIATED DEVICE DRIVERS
M: Kirti Wankhede <kwankhede@nvidia.com>
L: kvm@vger.kernel.org
@@ -20254,12 +20452,28 @@ F: drivers/vfio/mdev/
F: include/linux/mdev.h
F: samples/vfio-mdev/
+VFIO PCI DEVICE SPECIFIC DRIVERS
+R: Jason Gunthorpe <jgg@nvidia.com>
+R: Yishai Hadas <yishaih@nvidia.com>
+R: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>
+R: Kevin Tian <kevin.tian@intel.com>
+L: kvm@vger.kernel.org
+S: Maintained
+P: Documentation/driver-api/vfio-pci-device-specific-driver-acceptance.rst
+F: drivers/vfio/pci/*/
+
VFIO PLATFORM DRIVER
M: Eric Auger <eric.auger@redhat.com>
L: kvm@vger.kernel.org
S: Maintained
F: drivers/vfio/platform/
+VFIO MLX5 PCI DRIVER
+M: Yishai Hadas <yishaih@nvidia.com>
+L: kvm@vger.kernel.org
+S: Maintained
+F: drivers/vfio/pci/mlx5/
+
VGA_SWITCHEROO
R: Lukas Wunner <lukas@wunner.de>
S: Maintained
@@ -20323,8 +20537,8 @@ F: drivers/media/common/videobuf2/*
F: include/media/videobuf2-*
VIMC VIRTUAL MEDIA CONTROLLER DRIVER
-M: Helen Koike <helen.koike@collabora.com>
-R: Shuah Khan <skhan@linuxfoundation.org>
+M: Shuah Khan <skhan@linuxfoundation.org>
+R: Kieran Bingham <kieran.bingham@ideasonboard.com>
L: linux-media@vger.kernel.org
S: Maintained
W: https://linuxtv.org
@@ -20579,30 +20793,33 @@ F: tools/testing/vsock/
VMWARE BALLOON DRIVER
M: Nadav Amit <namit@vmware.com>
-M: "VMware, Inc." <pv-drivers@vmware.com>
+R: VMware PV-Drivers Reviewers <pv-drivers@vmware.com>
L: linux-kernel@vger.kernel.org
S: Maintained
F: drivers/misc/vmw_balloon.c
VMWARE HYPERVISOR INTERFACE
-M: Deep Shah <sdeep@vmware.com>
-M: "VMware, Inc." <pv-drivers@vmware.com>
+M: Srivatsa S. Bhat (VMware) <srivatsa@csail.mit.edu>
+M: Alexey Makhalov <amakhalov@vmware.com>
+R: VMware PV-Drivers Reviewers <pv-drivers@vmware.com>
L: virtualization@lists.linux-foundation.org
+L: x86@kernel.org
S: Supported
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git x86/vmware
F: arch/x86/include/asm/vmware.h
F: arch/x86/kernel/cpu/vmware.c
VMWARE PVRDMA DRIVER
M: Bryan Tan <bryantan@vmware.com>
M: Vishnu Dasa <vdasa@vmware.com>
-M: VMware PV-Drivers <pv-drivers@vmware.com>
+R: VMware PV-Drivers Reviewers <pv-drivers@vmware.com>
L: linux-rdma@vger.kernel.org
S: Maintained
F: drivers/infiniband/hw/vmw_pvrdma/
VMware PVSCSI driver
M: Vishal Bhakta <vbhakta@vmware.com>
-M: VMware PV-Drivers <pv-drivers@vmware.com>
+R: VMware PV-Drivers Reviewers <pv-drivers@vmware.com>
L: linux-scsi@vger.kernel.org
S: Maintained
F: drivers/scsi/vmw_pvscsi.c
@@ -20610,7 +20827,7 @@ F: drivers/scsi/vmw_pvscsi.h
VMWARE VIRTUAL PTP CLOCK DRIVER
M: Vivek Thampi <vithampi@vmware.com>
-M: "VMware, Inc." <pv-drivers@vmware.com>
+R: VMware PV-Drivers Reviewers <pv-drivers@vmware.com>
L: netdev@vger.kernel.org
S: Supported
F: drivers/ptp/ptp_vmw.c
@@ -20618,14 +20835,15 @@ F: drivers/ptp/ptp_vmw.c
VMWARE VMCI DRIVER
M: Jorgen Hansen <jhansen@vmware.com>
M: Vishnu Dasa <vdasa@vmware.com>
+R: VMware PV-Drivers Reviewers <pv-drivers@vmware.com>
L: linux-kernel@vger.kernel.org
-L: pv-drivers@vmware.com (private)
S: Maintained
F: drivers/misc/vmw_vmci/
VMWARE VMMOUSE SUBDRIVER
-M: "VMware Graphics" <linux-graphics-maintainer@vmware.com>
-M: "VMware, Inc." <pv-drivers@vmware.com>
+M: Zack Rusin <zackr@vmware.com>
+R: VMware Graphics Reviewers <linux-graphics-maintainer@vmware.com>
+R: VMware PV-Drivers Reviewers <pv-drivers@vmware.com>
L: linux-input@vger.kernel.org
S: Maintained
F: drivers/input/mouse/vmmouse.c
@@ -20633,7 +20851,7 @@ F: drivers/input/mouse/vmmouse.h
VMWARE VMXNET3 ETHERNET DRIVER
M: Ronak Doshi <doshir@vmware.com>
-M: pv-drivers@vmware.com
+R: VMware PV-Drivers Reviewers <pv-drivers@vmware.com>
L: netdev@vger.kernel.org
S: Maintained
F: drivers/net/vmxnet3/
@@ -21009,7 +21227,7 @@ L: linux-media@vger.kernel.org
S: Maintained
W: https://linuxtv.org
T: git git://linuxtv.org/media_tree.git
-F: drivers/media/tuners/tuner-xc2028.*
+F: drivers/media/tuners/xc2028.*
XDP (eXpress Data Path)
M: Alexei Starovoitov <ast@kernel.org>
@@ -21229,6 +21447,11 @@ T: git https://github.com/Xilinx/linux-xlnx.git
F: Documentation/devicetree/bindings/phy/xlnx,zynqmp-psgtr.yaml
F: drivers/phy/xilinx/phy-zynqmp.c
+XILINX ZYNQMP SHA3 DRIVER
+M: Harsha <harsha.harsha@xilinx.com>
+S: Maintained
+F: drivers/crypto/xilinx/zynqmp-sha.c
+
XILINX EVENT MANAGEMENT DRIVER
M: Abhyuday Godhasara <abhyuday.godhasara@xilinx.com>
S: Maintained
@@ -21409,7 +21632,6 @@ THE REST
M: Linus Torvalds <torvalds@linux-foundation.org>
L: linux-kernel@vger.kernel.org
S: Buried alive in reporters
-Q: http://patchwork.kernel.org/project/LKML/list/
T: git git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
F: *
F: */
diff --git a/Makefile b/Makefile
index 0fb4f94a6885..7214f075e1f0 100644
--- a/Makefile
+++ b/Makefile
@@ -2,8 +2,8 @@
VERSION = 5
PATCHLEVEL = 17
SUBLEVEL = 0
-EXTRAVERSION = -rc1
-NAME = Gobble Gobble
+EXTRAVERSION =
+NAME = Superb Owl
# *DOCUMENTATION*
# To see a list of typical targets execute "make help"
diff --git a/arch/Kconfig b/arch/Kconfig
index 678a80713b21..9af3a597cc67 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -24,9 +24,6 @@ config KEXEC_ELF
config HAVE_IMA_KEXEC
bool
-config SET_FS
- bool
-
config HOTPLUG_SMT
bool
@@ -599,21 +596,22 @@ config STACKPROTECTOR_STRONG
config ARCH_SUPPORTS_SHADOW_CALL_STACK
bool
help
- An architecture should select this if it supports Clang's Shadow
- Call Stack and implements runtime support for shadow stack
+ An architecture should select this if it supports the compiler's
+ Shadow Call Stack and implements runtime support for shadow stack
switching.
config SHADOW_CALL_STACK
- bool "Clang Shadow Call Stack"
- depends on CC_IS_CLANG && ARCH_SUPPORTS_SHADOW_CALL_STACK
+ bool "Shadow Call Stack"
+ depends on ARCH_SUPPORTS_SHADOW_CALL_STACK
depends on DYNAMIC_FTRACE_WITH_REGS || !FUNCTION_GRAPH_TRACER
help
- This option enables Clang's Shadow Call Stack, which uses a
- shadow stack to protect function return addresses from being
- overwritten by an attacker. More information can be found in
- Clang's documentation:
+ This option enables the compiler's Shadow Call Stack, which
+ uses a shadow stack to protect function return addresses from
+ being overwritten by an attacker. More information can be found
+ in the compiler's documentation:
- https://clang.llvm.org/docs/ShadowCallStack.html
+ - Clang: https://clang.llvm.org/docs/ShadowCallStack.html
+ - GCC: https://gcc.gnu.org/onlinedocs/gcc/Instrumentation-Options.html#Instrumentation-Options
Note that security guarantees in the kernel differ from the
ones documented for user space. The kernel must store addresses
@@ -898,6 +896,13 @@ config HAVE_SOFTIRQ_ON_OWN_STACK
Architecture provides a function to run __do_softirq() on a
separate stack.
+config ALTERNATE_USER_ADDRESS_SPACE
+ bool
+ help
+ Architectures set this when the CPU uses separate address
+ spaces for kernel and user space pointers. In this case, the
+ access_ok() check on a __user pointer is skipped.
+
config PGTABLE_LEVELS
int
default 2
@@ -1159,16 +1164,30 @@ config HAVE_ARCH_RANDOMIZE_KSTACK_OFFSET
to the compiler, so it will attempt to add canary checks regardless
of the static branch state.
-config RANDOMIZE_KSTACK_OFFSET_DEFAULT
- bool "Randomize kernel stack offset on syscall entry"
+config RANDOMIZE_KSTACK_OFFSET
+ bool "Support for randomizing kernel stack offset on syscall entry" if EXPERT
+ default y
depends on HAVE_ARCH_RANDOMIZE_KSTACK_OFFSET
+ depends on INIT_STACK_NONE || !CC_IS_CLANG || CLANG_VERSION >= 140000
help
The kernel stack offset can be randomized (after pt_regs) by
roughly 5 bits of entropy, frustrating memory corruption
attacks that depend on stack address determinism or
- cross-syscall address exposures. This feature is controlled
- by kernel boot param "randomize_kstack_offset=on/off", and this
- config chooses the default boot state.
+ cross-syscall address exposures.
+
+ The feature is controlled via the "randomize_kstack_offset=on/off"
+ kernel boot param, and if turned off has zero overhead due to its use
+ of static branches (see JUMP_LABEL).
+
+ If unsure, say Y.
+
+config RANDOMIZE_KSTACK_OFFSET_DEFAULT
+ bool "Default state of kernel stack offset randomization"
+ depends on RANDOMIZE_KSTACK_OFFSET
+ help
+ Kernel stack offset randomization is controlled by kernel boot param
+ "randomize_kstack_offset=on/off", and this config chooses the default
+ boot state.
config ARCH_OPTIONAL_KERNEL_RWX
def_bool n
@@ -1278,12 +1297,41 @@ config HAVE_STATIC_CALL_INLINE
config HAVE_PREEMPT_DYNAMIC
bool
+
+config HAVE_PREEMPT_DYNAMIC_CALL
+ bool
depends on HAVE_STATIC_CALL
- depends on GENERIC_ENTRY
+ select HAVE_PREEMPT_DYNAMIC
help
- Select this if the architecture support boot time preempt setting
- on top of static calls. It is strongly advised to support inline
- static call to avoid any overhead.
+ An architecture should select this if it can handle the preemption
+ model being selected at boot time using static calls.
+
+ Where an architecture selects HAVE_STATIC_CALL_INLINE, any call to a
+ preemption function will be patched directly.
+
+ Where an architecture does not select HAVE_STATIC_CALL_INLINE, any
+ call to a preemption function will go through a trampoline, and the
+ trampoline will be patched.
+
+ It is strongly advised to support inline static call to avoid any
+ overhead.
+
+config HAVE_PREEMPT_DYNAMIC_KEY
+ bool
+ depends on HAVE_ARCH_JUMP_LABEL && CC_HAS_ASM_GOTO
+ select HAVE_PREEMPT_DYNAMIC
+ help
+ An architecture should select this if it can handle the preemption
+ model being selected at boot time using static keys.
+
+ Each preemption function will be given an early return based on a
+ static key. This should have slightly lower overhead than non-inline
+ static calls, as this effectively inlines each trampoline into the
+ start of its callee. This may avoid redundant work, and may
+ integrate better with CFI schemes.
+
+ This will have greater overhead than using inline static calls as
+ the call to the preemption function cannot be entirely elided.
config ARCH_WANT_LD_ORPHAN_WARN
bool
diff --git a/arch/alpha/Kconfig b/arch/alpha/Kconfig
index 4e87783c90ad..7d0d26b5b3f5 100644
--- a/arch/alpha/Kconfig
+++ b/arch/alpha/Kconfig
@@ -12,7 +12,6 @@ config ALPHA
select FORCE_PCI if !ALPHA_JENSEN
select PCI_DOMAINS if PCI
select PCI_SYSCALL if PCI
- select HAVE_AOUT
select HAVE_ASM_MODVERSIONS
select HAVE_PCSPKR_PLATFORM
select HAVE_PERF_EVENTS
@@ -35,7 +34,6 @@ config ALPHA
select OLD_SIGSUSPEND
select CPU_NO_EFFICIENT_FFS if !ALPHA_EV67
select MMU_GATHER_NO_RANGE
- select SET_FS
select SPARSEMEM_EXTREME if SPARSEMEM
select ZONE_DMA
help
diff --git a/arch/alpha/configs/defconfig b/arch/alpha/configs/defconfig
index 7f1ca30b115b..7e9336930880 100644
--- a/arch/alpha/configs/defconfig
+++ b/arch/alpha/configs/defconfig
@@ -62,7 +62,6 @@ CONFIG_TMPFS=y
CONFIG_NFS_FS=m
CONFIG_NFS_V3=y
CONFIG_NFSD=m
-CONFIG_NFSD_V3=y
CONFIG_NLS_CODEPAGE_437=y
CONFIG_MAGIC_SYSRQ=y
CONFIG_DEBUG_KERNEL=y
diff --git a/arch/alpha/include/asm/hwrpb.h b/arch/alpha/include/asm/hwrpb.h
index d8180e527a1e..fc76f36265ad 100644
--- a/arch/alpha/include/asm/hwrpb.h
+++ b/arch/alpha/include/asm/hwrpb.h
@@ -152,7 +152,7 @@ struct memdesc_struct {
unsigned long chksum;
unsigned long optional_pa;
unsigned long numclusters;
- struct memclust_struct cluster[0];
+ struct memclust_struct cluster[];
};
struct dsr_struct {
diff --git a/arch/alpha/include/asm/pgtable.h b/arch/alpha/include/asm/pgtable.h
index 02f0429f1068..170451fde043 100644
--- a/arch/alpha/include/asm/pgtable.h
+++ b/arch/alpha/include/asm/pgtable.h
@@ -233,6 +233,7 @@ pmd_page_vaddr(pmd_t pmd)
return ((pmd_val(pmd) & _PFN_MASK) >> (32-PAGE_SHIFT)) + PAGE_OFFSET;
}
+#define pmd_pfn(pmd) (pmd_val(pmd) >> 32)
#define pmd_page(pmd) (pfn_to_page(pmd_val(pmd) >> 32))
#define pud_page(pud) (pfn_to_page(pud_val(pud) >> 32))
diff --git a/arch/alpha/include/asm/processor.h b/arch/alpha/include/asm/processor.h
index 090499c99c1c..43e234c518b1 100644
--- a/arch/alpha/include/asm/processor.h
+++ b/arch/alpha/include/asm/processor.h
@@ -26,10 +26,6 @@
#define TASK_UNMAPPED_BASE \
((current->personality & ADDR_LIMIT_32BIT) ? 0x40000000 : TASK_SIZE / 2)
-typedef struct {
- unsigned long seg;
-} mm_segment_t;
-
/* This is dead. Everything has been moved to thread_info. */
struct thread_struct { };
#define INIT_THREAD { }
diff --git a/arch/alpha/include/asm/thread_info.h b/arch/alpha/include/asm/thread_info.h
index 2592356e3215..fdc485d7787a 100644
--- a/arch/alpha/include/asm/thread_info.h
+++ b/arch/alpha/include/asm/thread_info.h
@@ -19,7 +19,6 @@ struct thread_info {
unsigned int flags; /* low level flags */
unsigned int ieee_state; /* see fpu.h */
- mm_segment_t addr_limit; /* thread address space */
unsigned cpu; /* current CPU */
int preempt_count; /* 0 => preemptable, <0 => BUG */
unsigned int status; /* thread-synchronous flags */
@@ -35,7 +34,6 @@ struct thread_info {
#define INIT_THREAD_INFO(tsk) \
{ \
.task = &tsk, \
- .addr_limit = KERNEL_DS, \
.preempt_count = INIT_PREEMPT_COUNT, \
}
diff --git a/arch/alpha/include/asm/uaccess.h b/arch/alpha/include/asm/uaccess.h
index 1b6f25efa247..c32c2584c0b7 100644
--- a/arch/alpha/include/asm/uaccess.h
+++ b/arch/alpha/include/asm/uaccess.h
@@ -2,47 +2,7 @@
#ifndef __ALPHA_UACCESS_H
#define __ALPHA_UACCESS_H
-/*
- * The fs value determines whether argument validity checking should be
- * performed or not. If get_fs() == USER_DS, checking is performed, with
- * get_fs() == KERNEL_DS, checking is bypassed.
- *
- * Or at least it did once upon a time. Nowadays it is a mask that
- * defines which bits of the address space are off limits. This is a
- * wee bit faster than the above.
- *
- * For historical reasons, these macros are grossly misnamed.
- */
-
-#define KERNEL_DS ((mm_segment_t) { 0UL })
-#define USER_DS ((mm_segment_t) { -0x40000000000UL })
-
-#define get_fs() (current_thread_info()->addr_limit)
-#define set_fs(x) (current_thread_info()->addr_limit = (x))
-
-#define uaccess_kernel() (get_fs().seg == KERNEL_DS.seg)
-
-/*
- * Is a address valid? This does a straightforward calculation rather
- * than tests.
- *
- * Address valid if:
- * - "addr" doesn't have any high-bits set
- * - AND "size" doesn't have any high-bits set
- * - AND "addr+size-(size != 0)" doesn't have any high-bits set
- * - OR we are in kernel mode.
- */
-#define __access_ok(addr, size) ({ \
- unsigned long __ao_a = (addr), __ao_b = (size); \
- unsigned long __ao_end = __ao_a + __ao_b - !!__ao_b; \
- (get_fs().seg & (__ao_a | __ao_b | __ao_end)) == 0; })
-
-#define access_ok(addr, size) \
-({ \
- __chk_user_ptr(addr); \
- __access_ok(((unsigned long)(addr)), (size)); \
-})
-
+#include <asm-generic/access_ok.h>
/*
* These are the main single-value transfer routines. They automatically
* use the right size if we just have the right pointer type.
@@ -105,7 +65,7 @@ extern void __get_user_unknown(void);
long __gu_err = -EFAULT; \
unsigned long __gu_val = 0; \
const __typeof__(*(ptr)) __user *__gu_addr = (ptr); \
- if (__access_ok((unsigned long)__gu_addr, size)) { \
+ if (__access_ok(__gu_addr, size)) { \
__gu_err = 0; \
switch (size) { \
case 1: __get_user_8(__gu_addr); break; \
@@ -200,7 +160,7 @@ extern void __put_user_unknown(void);
({ \
long __pu_err = -EFAULT; \
__typeof__(*(ptr)) __user *__pu_addr = (ptr); \
- if (__access_ok((unsigned long)__pu_addr, size)) { \
+ if (__access_ok(__pu_addr, size)) { \
__pu_err = 0; \
switch (size) { \
case 1: __put_user_8(x, __pu_addr); break; \
@@ -316,17 +276,14 @@ raw_copy_to_user(void __user *to, const void *from, unsigned long len)
extern long __clear_user(void __user *to, long len);
-extern inline long
+static inline long
clear_user(void __user *to, long len)
{
- if (__access_ok((unsigned long)to, len))
+ if (__access_ok(to, len))
len = __clear_user(to, len);
return len;
}
-#define user_addr_max() \
- (uaccess_kernel() ? ~0UL : TASK_SIZE)
-
extern long strncpy_from_user(char *dest, const char __user *src, long count);
extern __must_check long strnlen_user(const char __user *str, long n);
diff --git a/arch/alpha/include/asm/xor.h b/arch/alpha/include/asm/xor.h
index 5aeb4fb3cb7c..e0de0c233ab9 100644
--- a/arch/alpha/include/asm/xor.h
+++ b/arch/alpha/include/asm/xor.h
@@ -5,24 +5,43 @@
* Optimized RAID-5 checksumming functions for alpha EV5 and EV6
*/
-extern void xor_alpha_2(unsigned long, unsigned long *, unsigned long *);
-extern void xor_alpha_3(unsigned long, unsigned long *, unsigned long *,
- unsigned long *);
-extern void xor_alpha_4(unsigned long, unsigned long *, unsigned long *,
- unsigned long *, unsigned long *);
-extern void xor_alpha_5(unsigned long, unsigned long *, unsigned long *,
- unsigned long *, unsigned long *, unsigned long *);
+extern void
+xor_alpha_2(unsigned long bytes, unsigned long * __restrict p1,
+ const unsigned long * __restrict p2);
+extern void
+xor_alpha_3(unsigned long bytes, unsigned long * __restrict p1,
+ const unsigned long * __restrict p2,
+ const unsigned long * __restrict p3);
+extern void
+xor_alpha_4(unsigned long bytes, unsigned long * __restrict p1,
+ const unsigned long * __restrict p2,
+ const unsigned long * __restrict p3,
+ const unsigned long * __restrict p4);
+extern void
+xor_alpha_5(unsigned long bytes, unsigned long * __restrict p1,
+ const unsigned long * __restrict p2,
+ const unsigned long * __restrict p3,
+ const unsigned long * __restrict p4,
+ const unsigned long * __restrict p5);
-extern void xor_alpha_prefetch_2(unsigned long, unsigned long *,
- unsigned long *);
-extern void xor_alpha_prefetch_3(unsigned long, unsigned long *,
- unsigned long *, unsigned long *);
-extern void xor_alpha_prefetch_4(unsigned long, unsigned long *,
- unsigned long *, unsigned long *,
- unsigned long *);
-extern void xor_alpha_prefetch_5(unsigned long, unsigned long *,
- unsigned long *, unsigned long *,
- unsigned long *, unsigned long *);
+extern void
+xor_alpha_prefetch_2(unsigned long bytes, unsigned long * __restrict p1,
+ const unsigned long * __restrict p2);
+extern void
+xor_alpha_prefetch_3(unsigned long bytes, unsigned long * __restrict p1,
+ const unsigned long * __restrict p2,
+ const unsigned long * __restrict p3);
+extern void
+xor_alpha_prefetch_4(unsigned long bytes, unsigned long * __restrict p1,
+ const unsigned long * __restrict p2,
+ const unsigned long * __restrict p3,
+ const unsigned long * __restrict p4);
+extern void
+xor_alpha_prefetch_5(unsigned long bytes, unsigned long * __restrict p1,
+ const unsigned long * __restrict p2,
+ const unsigned long * __restrict p3,
+ const unsigned long * __restrict p4,
+ const unsigned long * __restrict p5);
asm(" \n\
.text \n\
diff --git a/arch/alpha/include/uapi/asm/signal.h b/arch/alpha/include/uapi/asm/signal.h
index a69dd8d080a8..1413075f7616 100644
--- a/arch/alpha/include/uapi/asm/signal.h
+++ b/arch/alpha/include/uapi/asm/signal.h
@@ -100,7 +100,7 @@ struct sigaction {
typedef struct sigaltstack {
void __user *ss_sp;
int ss_flags;
- size_t ss_size;
+ __kernel_size_t ss_size;
} stack_t;
/* sigstack(2) is deprecated, and will be withdrawn in a future version
diff --git a/arch/alpha/include/uapi/asm/socket.h b/arch/alpha/include/uapi/asm/socket.h
index 284d28755b8d..7d81535893af 100644
--- a/arch/alpha/include/uapi/asm/socket.h
+++ b/arch/alpha/include/uapi/asm/socket.h
@@ -133,6 +133,8 @@
#define SO_RESERVE_MEM 73
+#define SO_TXREHASH 74
+
#if !defined(__KERNEL__)
#if __BITS_PER_LONG == 64
diff --git a/arch/alpha/mm/init.c b/arch/alpha/mm/init.c
index f6114d03357c..7511723b7669 100644
--- a/arch/alpha/mm/init.c
+++ b/arch/alpha/mm/init.c
@@ -76,14 +76,14 @@ pgd_alloc(struct mm_struct *mm)
pmd_t *
__bad_pagetable(void)
{
- memset((void *) EMPTY_PGT, 0, PAGE_SIZE);
+ memset(absolute_pointer(EMPTY_PGT), 0, PAGE_SIZE);
return (pmd_t *) EMPTY_PGT;
}
pte_t
__bad_page(void)
{
- memset((void *) EMPTY_PGE, 0, PAGE_SIZE);
+ memset(absolute_pointer(EMPTY_PGE), 0, PAGE_SIZE);
return pte_mkdirty(mk_pte(virt_to_page(EMPTY_PGE), PAGE_SHARED));
}
@@ -253,7 +253,7 @@ void __init paging_init(void)
free_area_init(max_zone_pfn);
/* Initialize the kernel's ZERO_PGE. */
- memset((void *)ZERO_PGE, 0, PAGE_SIZE);
+ memset(absolute_pointer(ZERO_PGE), 0, PAGE_SIZE);
}
#if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_SRM)
diff --git a/arch/arc/Kconfig b/arch/arc/Kconfig
index 3c2a4753d09b..e0a60a27e14d 100644
--- a/arch/arc/Kconfig
+++ b/arch/arc/Kconfig
@@ -45,7 +45,6 @@ config ARC
select PCI_SYSCALL if PCI
select PERF_USE_VMALLOC if ARC_CACHE_VIPT_ALIASING
select HAVE_ARCH_JUMP_LABEL if ISA_ARCV2 && !CPU_ENDIAN_BE32
- select SET_FS
select TRACE_IRQFLAGS_SUPPORT
config LOCKDEP_SUPPORT
diff --git a/arch/arc/include/asm/hugepage.h b/arch/arc/include/asm/hugepage.h
index 11b0ff26b97b..5001b796fb8d 100644
--- a/arch/arc/include/asm/hugepage.h
+++ b/arch/arc/include/asm/hugepage.h
@@ -31,7 +31,6 @@ static inline pmd_t pte_pmd(pte_t pte)
#define pmd_write(pmd) pte_write(pmd_pte(pmd))
#define pmd_young(pmd) pte_young(pmd_pte(pmd))
-#define pmd_pfn(pmd) pte_pfn(pmd_pte(pmd))
#define pmd_dirty(pmd) pte_dirty(pmd_pte(pmd))
#define mk_pmd(page, prot) pte_pmd(mk_pte(page, prot))
diff --git a/arch/arc/include/asm/pgtable-levels.h b/arch/arc/include/asm/pgtable-levels.h
index 8084ef2f6491..7848348719b2 100644
--- a/arch/arc/include/asm/pgtable-levels.h
+++ b/arch/arc/include/asm/pgtable-levels.h
@@ -161,6 +161,7 @@
#define pmd_present(x) (pmd_val(x))
#define pmd_clear(xp) do { pmd_val(*(xp)) = 0; } while (0)
#define pmd_page_vaddr(pmd) (pmd_val(pmd) & PAGE_MASK)
+#define pmd_pfn(pmd) ((pmd_val(pmd) & PAGE_MASK) >> PAGE_SHIFT)
#define pmd_page(pmd) virt_to_page(pmd_page_vaddr(pmd))
#define set_pmd(pmdp, pmd) (*(pmdp) = pmd)
#define pmd_pgtable(pmd) ((pgtable_t) pmd_page_vaddr(pmd))
diff --git a/arch/arc/include/asm/segment.h b/arch/arc/include/asm/segment.h
deleted file mode 100644
index 871f8ab11bfd..000000000000
--- a/arch/arc/include/asm/segment.h
+++ /dev/null
@@ -1,20 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com)
- */
-
-#ifndef __ASMARC_SEGMENT_H
-#define __ASMARC_SEGMENT_H
-
-#ifndef __ASSEMBLY__
-
-typedef unsigned long mm_segment_t;
-
-#define MAKE_MM_SEG(s) ((mm_segment_t) { (s) })
-
-#define KERNEL_DS MAKE_MM_SEG(0)
-#define USER_DS MAKE_MM_SEG(TASK_SIZE)
-#define uaccess_kernel() (get_fs() == KERNEL_DS)
-
-#endif /* __ASSEMBLY__ */
-#endif /* __ASMARC_SEGMENT_H */
diff --git a/arch/arc/include/asm/thread_info.h b/arch/arc/include/asm/thread_info.h
index d36863e34bfc..1e0b2e3914d5 100644
--- a/arch/arc/include/asm/thread_info.h
+++ b/arch/arc/include/asm/thread_info.h
@@ -27,7 +27,6 @@
#ifndef __ASSEMBLY__
#include <linux/thread_info.h>
-#include <asm/segment.h>
/*
* low level task data that entry.S needs immediate access to
@@ -40,7 +39,6 @@ struct thread_info {
unsigned long flags; /* low level flags */
int preempt_count; /* 0 => preemptable, <0 => BUG */
struct task_struct *task; /* main task structure */
- mm_segment_t addr_limit; /* thread address space */
__u32 cpu; /* current CPU */
unsigned long thr_ptr; /* TLS ptr */
};
@@ -56,7 +54,6 @@ struct thread_info {
.flags = 0, \
.cpu = 0, \
.preempt_count = INIT_PREEMPT_COUNT, \
- .addr_limit = KERNEL_DS, \
}
static inline __attribute_const__ struct thread_info *current_thread_info(void)
diff --git a/arch/arc/include/asm/uaccess.h b/arch/arc/include/asm/uaccess.h
index 783bfdb3bfa3..99712471c96a 100644
--- a/arch/arc/include/asm/uaccess.h
+++ b/arch/arc/include/asm/uaccess.h
@@ -23,35 +23,6 @@
#include <linux/string.h> /* for generic string functions */
-
-#define __kernel_ok (uaccess_kernel())
-
-/*
- * Algorithmically, for __user_ok() we want do:
- * (start < TASK_SIZE) && (start+len < TASK_SIZE)
- * where TASK_SIZE could either be retrieved from thread_info->addr_limit or
- * emitted directly in code.
- *
- * This can however be rewritten as follows:
- * (len <= TASK_SIZE) && (start+len < TASK_SIZE)
- *
- * Because it essentially checks if buffer end is within limit and @len is
- * non-ngeative, which implies that buffer start will be within limit too.
- *
- * The reason for rewriting being, for majority of cases, @len is generally
- * compile time constant, causing first sub-expression to be compile time
- * subsumed.
- *
- * The second part would generate weird large LIMMs e.g. (0x6000_0000 - 0x10),
- * so we check for TASK_SIZE using get_fs() since the addr_limit load from mem
- * would already have been done at this call site for __kernel_ok()
- *
- */
-#define __user_ok(addr, sz) (((sz) <= TASK_SIZE) && \
- ((addr) <= (get_fs() - (sz))))
-#define __access_ok(addr, sz) (unlikely(__kernel_ok) || \
- likely(__user_ok((addr), (sz))))
-
/*********** Single byte/hword/word copies ******************/
#define __get_user_fn(sz, u, k) \
@@ -667,7 +638,6 @@ extern unsigned long arc_clear_user_noinline(void __user *to,
#define __clear_user(d, n) arc_clear_user_noinline(d, n)
#endif
-#include <asm/segment.h>
#include <asm-generic/uaccess.h>
#endif
diff --git a/arch/arc/kernel/process.c b/arch/arc/kernel/process.c
index 8e90052f6f05..5f7f5aab361f 100644
--- a/arch/arc/kernel/process.c
+++ b/arch/arc/kernel/process.c
@@ -43,7 +43,7 @@ SYSCALL_DEFINE0(arc_gettls)
return task_thread_info(current)->thr_ptr;
}
-SYSCALL_DEFINE3(arc_usr_cmpxchg, int *, uaddr, int, expected, int, new)
+SYSCALL_DEFINE3(arc_usr_cmpxchg, int __user *, uaddr, int, expected, int, new)
{
struct pt_regs *regs = current_pt_regs();
u32 uval;
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index fabe39169b12..c1251856ef77 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_CURRENT_STACK_POINTER
select ARCH_HAS_DEBUG_VIRTUAL if MMU
select ARCH_HAS_DMA_WRITE_COMBINE if !ARM_DMA_MEM_BUFFERABLE
select ARCH_HAS_ELF_RANDOMIZE
@@ -37,6 +38,7 @@ config ARM
select ARCH_USE_CMPXCHG_LOCKREF
select ARCH_USE_MEMTEST
select ARCH_WANT_DEFAULT_TOPDOWN_MMAP_LAYOUT if MMU
+ select ARCH_WANT_GENERAL_HUGETLB
select ARCH_WANT_IPC_PARSE_VERSION
select ARCH_WANT_LD_ORPHAN_WARN
select BINFMT_FLAT_ARGVP_ENVP_ON_STACK
@@ -58,6 +60,7 @@ config ARM
select GENERIC_CPU_AUTOPROBE
select GENERIC_EARLY_IOREMAP
select GENERIC_IDLE_POLL_SETUP
+ select GENERIC_IRQ_MULTI_HANDLER
select GENERIC_IRQ_PROBE
select GENERIC_IRQ_SHOW
select GENERIC_IRQ_SHOW_LEVEL
@@ -83,6 +86,7 @@ config ARM
select HAVE_EBPF_JIT if !CPU_ENDIAN_BE32
select HAVE_CONTEXT_TRACKING
select HAVE_C_RECORDMCOUNT
+ select HAVE_BUILDTIME_MCOUNT_SORT
select HAVE_DEBUG_KMEMLEAK if !XIP_KERNEL
select HAVE_DMA_CONTIGUOUS if MMU
select HAVE_DYNAMIC_FTRACE if !XIP_KERNEL && !CPU_ENDIAN_BE32 && MMU
@@ -91,8 +95,8 @@ config ARM
select HAVE_EXIT_THREAD
select HAVE_FAST_GUP if ARM_LPAE
select HAVE_FTRACE_MCOUNT_RECORD if !XIP_KERNEL
- select HAVE_FUNCTION_GRAPH_TRACER if !THUMB2_KERNEL && !CC_IS_CLANG
- select HAVE_FUNCTION_TRACER if !XIP_KERNEL && !(THUMB2_KERNEL && CC_IS_CLANG)
+ select HAVE_FUNCTION_GRAPH_TRACER
+ select HAVE_FUNCTION_TRACER if !XIP_KERNEL
select HAVE_GCC_PLUGINS
select HAVE_HW_BREAKPOINT if PERF_EVENTS && (CPU_V6 || CPU_V6K || CPU_V7)
select HAVE_IRQ_TIME_ACCOUNTING
@@ -126,7 +130,8 @@ config ARM
select PERF_USE_VMALLOC
select RTC_LIB
select SYS_SUPPORTS_APM_EMULATION
- select THREAD_INFO_IN_TASK if CURRENT_POINTER_IN_TPIDRURO
+ select THREAD_INFO_IN_TASK
+ select HAVE_ARCH_VMAP_STACK if MMU && ARM_HAS_GROUP_RELOCS
select TRACE_IRQFLAGS_SUPPORT if !CPU_V7M
# Above selects are sorted alphabetically; please add new ones
# according to that. Thanks.
@@ -138,6 +143,17 @@ config ARM
Europe. There is an ARM Linux project with a web page at
<http://www.arm.linux.org.uk/>.
+config ARM_HAS_GROUP_RELOCS
+ def_bool y
+ depends on !LD_IS_LLD || LLD_VERSION >= 140000
+ depends on !COMPILE_TEST
+ help
+ Whether or not to use R_ARM_ALU_PC_Gn or R_ARM_LDR_PC_Gn group
+ relocations, which have been around for a long time, but were not
+ supported in LLD until version 14. The combined range is -/+ 256 MiB,
+ which is usually sufficient, but not for allyesconfig, so we disable
+ this feature when doing compile testing.
+
config ARM_HAS_SG_CHAIN
bool
@@ -217,18 +233,12 @@ config ARCH_MAY_HAVE_PC_FDC
config ARCH_SUPPORTS_UPROBES
def_bool y
-config ARCH_HAS_DMA_SET_COHERENT_MASK
- bool
-
config GENERIC_ISA_DMA
bool
config FIQ
bool
-config NEED_RET_TO_USER
- bool
-
config ARCH_MTD_XIP
bool
@@ -266,7 +276,7 @@ config PHYS_OFFSET
hex "Physical address of main memory" if MMU
depends on !ARM_PATCH_PHYS_VIRT
default DRAM_BASE if !MMU
- default 0x00000000 if ARCH_FOOTBRIDGE || ARCH_IXP4XX
+ default 0x00000000 if ARCH_FOOTBRIDGE
default 0x10000000 if ARCH_OMAP1 || ARCH_RPC
default 0x30000000 if ARCH_S3C24XX
default 0xa0000000 if ARCH_IOP32X || ARCH_PXA
@@ -294,6 +304,17 @@ config MMU
Select if you want MMU-based virtualised addressing space
support by paged memory management. If unsure, say 'Y'.
+config ARM_SINGLE_ARMV7M
+ def_bool !MMU
+ select ARM_NVIC
+ select AUTO_ZRELADDR
+ select TIMER_OF
+ select COMMON_CLK
+ select CPU_V7M
+ select NO_IOPORT_MAP
+ select SPARSE_IRQ
+ select USE_OF
+
config ARCH_MMAP_RND_BITS_MIN
default 8
@@ -308,12 +329,11 @@ config ARCH_MMAP_RND_BITS_MAX
#
choice
prompt "ARM system type"
- default ARM_SINGLE_ARMV7M if !MMU
- default ARCH_MULTIPLATFORM if MMU
+ depends on MMU
+ default ARCH_MULTIPLATFORM
config ARCH_MULTIPLATFORM
bool "Allow multiple platforms to be selected"
- depends on MMU
select ARCH_FLATMEM_ENABLE
select ARCH_SPARSEMEM_ENABLE
select ARCH_SELECT_MEMORY_MODEL
@@ -322,31 +342,17 @@ config ARCH_MULTIPLATFORM
select AUTO_ZRELADDR
select TIMER_OF
select COMMON_CLK
- select GENERIC_IRQ_MULTI_HANDLER
select HAVE_PCI
select PCI_DOMAINS_GENERIC if PCI
select SPARSE_IRQ
select USE_OF
-config ARM_SINGLE_ARMV7M
- bool "ARMv7-M based platforms (Cortex-M0/M3/M4)"
- depends on !MMU
- select ARM_NVIC
- select AUTO_ZRELADDR
- select TIMER_OF
- select COMMON_CLK
- select CPU_V7M
- select NO_IOPORT_MAP
- select SPARSE_IRQ
- select USE_OF
-
config ARCH_EP93XX
bool "EP93xx-based"
select ARCH_SPARSEMEM_ENABLE
select ARM_AMBA
imply ARM_PATCH_PHYS_VIRT
select ARM_VIC
- select GENERIC_IRQ_MULTI_HANDLER
select AUTO_ZRELADDR
select CLKSRC_MMIO
select CPU_ARM920T
@@ -359,7 +365,6 @@ config ARCH_FOOTBRIDGE
bool "FootBridge"
select CPU_SA110
select FOOTBRIDGE
- select NEED_MACH_IO_H if !MMU
select NEED_MACH_MEMORY_H
help
Support for systems based on the DC21285 companion chip
@@ -367,11 +372,9 @@ config ARCH_FOOTBRIDGE
config ARCH_IOP32X
bool "IOP32x-based"
- depends on MMU
select CPU_XSCALE
select GPIO_IOP
select GPIOLIB
- select NEED_RET_TO_USER
select FORCE_PCI
select PLAT_IOP
help
@@ -380,19 +383,15 @@ config ARCH_IOP32X
config ARCH_IXP4XX
bool "IXP4xx-based"
- depends on MMU
- select ARCH_HAS_DMA_SET_COHERENT_MASK
select ARCH_SUPPORTS_BIG_ENDIAN
+ select ARM_PATCH_PHYS_VIRT
select CPU_XSCALE
- select DMABOUNCE if PCI
- select GENERIC_IRQ_MULTI_HANDLER
select GPIO_IXP4XX
select GPIOLIB
select HAVE_PCI
select IXP4XX_IRQ
select IXP4XX_TIMER
- # With the new PCI driver this is not needed
- select NEED_MACH_IO_H if IXP4XX_PCI_LEGACY
+ select SPARSE_IRQ
select USB_EHCI_BIG_ENDIAN_DESC
select USB_EHCI_BIG_ENDIAN_MMIO
help
@@ -401,7 +400,6 @@ config ARCH_IXP4XX
config ARCH_DOVE
bool "Marvell Dove"
select CPU_PJ4
- select GENERIC_IRQ_MULTI_HANDLER
select GPIOLIB
select HAVE_PCI
select MVEBU_MBUS
@@ -415,7 +413,6 @@ config ARCH_DOVE
config ARCH_PXA
bool "PXA2xx/PXA3xx-based"
- depends on MMU
select ARCH_MTD_XIP
select ARM_CPU_SUSPEND if PM
select AUTO_ZRELADDR
@@ -424,7 +421,6 @@ config ARCH_PXA
select CLKSRC_MMIO
select TIMER_OF
select CPU_XSCALE if !CPU_XSC3
- select GENERIC_IRQ_MULTI_HANDLER
select GPIO_PXA
select GPIOLIB
select IRQ_DOMAIN
@@ -435,7 +431,6 @@ config ARCH_PXA
config ARCH_RPC
bool "RiscPC"
- depends on MMU
depends on !CC_IS_CLANG && GCC_VERSION < 90100 && GCC_VERSION >= 60000
select ARCH_ACORN
select ARCH_MAY_HAVE_PC_FDC
@@ -463,7 +458,6 @@ config ARCH_SA1100
select COMMON_CLK
select CPU_FREQ
select CPU_SA1100
- select GENERIC_IRQ_MULTI_HANDLER
select GPIOLIB
select IRQ_DOMAIN
select ISA
@@ -478,7 +472,6 @@ config ARCH_S3C24XX
select CLKSRC_SAMSUNG_PWM
select GPIO_SAMSUNG
select GPIOLIB
- select GENERIC_IRQ_MULTI_HANDLER
select NEED_MACH_IO_H
select S3C2410_WATCHDOG
select SAMSUNG_ATAGS
@@ -492,11 +485,9 @@ config ARCH_S3C24XX
config ARCH_OMAP1
bool "TI OMAP1"
- depends on MMU
select ARCH_OMAP
select CLKSRC_MMIO
select GENERIC_IRQ_CHIP
- select GENERIC_IRQ_MULTI_HANDLER
select GPIOLIB
select HAVE_LEGACY_CLK
select IRQ_DOMAIN
@@ -572,6 +563,18 @@ config ARCH_VIRT
select HAVE_ARM_ARCH_TIMER
select ARCH_SUPPORTS_BIG_ENDIAN
+config ARCH_AIROHA
+ bool "Airoha SoC Support"
+ depends on ARCH_MULTI_V7
+ select ARM_AMBA
+ select ARM_GIC
+ select ARM_GIC_V3
+ select ARM_PSCI
+ select HAVE_ARM_ARCH_TIMER
+ select COMMON_CLK
+ help
+ Support for Airoha EN7523 SoCs
+
#
# This is sorted alphabetically by mach-* pathname. However, plat-*
# Kconfigs may be included either alphabetically (according to the
@@ -1163,7 +1166,12 @@ config SMP_ON_UP
config CURRENT_POINTER_IN_TPIDRURO
def_bool y
- depends on SMP && CPU_32v6K && !CPU_V6
+ depends on CPU_32v6K && !CPU_V6
+
+config IRQSTACKS
+ def_bool y
+ select HAVE_IRQ_EXIT_ON_IRQ_STACK
+ select HAVE_SOFTIRQ_ON_OWN_STACK
config ARM_CPU_TOPOLOGY
bool "Support cpu topology definition"
@@ -1507,9 +1515,6 @@ config HW_PERF_EVENTS
def_bool y
depends on ARM_PMU
-config ARCH_WANT_GENERAL_HUGETLB
- def_bool y
-
config ARM_MODULE_PLTS
bool "Use PLTs to allow module memory to spill over into vmalloc area"
depends on MODULES
@@ -1607,10 +1612,14 @@ config XEN
help
Say Y if you want to run Linux in a Virtual Machine on Xen on ARM.
+config CC_HAVE_STACKPROTECTOR_TLS
+ def_bool $(cc-option,-mtp=cp15 -mstack-protector-guard=tls -mstack-protector-guard-offset=0)
+
config STACKPROTECTOR_PER_TASK
bool "Use a unique stack canary value for each task"
- depends on GCC_PLUGINS && STACKPROTECTOR && THREAD_INFO_IN_TASK && !XIP_DEFLATED_DATA
- select GCC_PLUGIN_ARM_SSP_PER_TASK
+ depends on STACKPROTECTOR && CURRENT_POINTER_IN_TPIDRURO && !XIP_DEFLATED_DATA
+ depends on GCC_PLUGINS || CC_HAVE_STACKPROTECTOR_TLS
+ select GCC_PLUGIN_ARM_SSP_PER_TASK if !CC_HAVE_STACKPROTECTOR_TLS
default y
help
Due to the fact that GCC uses an ordinary symbol reference from
diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug
index 976315dea958..0c9497d549e3 100644
--- a/arch/arm/Kconfig.debug
+++ b/arch/arm/Kconfig.debug
@@ -65,7 +65,7 @@ config UNWINDER_FRAME_POINTER
config UNWINDER_ARM
bool "ARM EABI stack unwinder"
- depends on AEABI && !FUNCTION_GRAPH_TRACER
+ depends on AEABI
select ARM_UNWIND
help
This option enables stack unwinding support in the kernel
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 77172d555c7e..a2391b8de5a5 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -160,6 +160,7 @@ textofs-$(CONFIG_ARCH_AXXIA) := 0x00308000
# Machine directory name. This list is sorted alphanumerically
# by CONFIG_* macro name.
machine-$(CONFIG_ARCH_ACTIONS) += actions
+machine-$(CONFIG_ARCH_AIROHA) += airoha
machine-$(CONFIG_ARCH_ALPINE) += alpine
machine-$(CONFIG_ARCH_ARTPEC) += artpec
machine-$(CONFIG_ARCH_ASPEED) += aspeed
@@ -275,6 +276,14 @@ endif
ifeq ($(CONFIG_STACKPROTECTOR_PER_TASK),y)
prepare: stack_protector_prepare
+ifeq ($(CONFIG_CC_HAVE_STACKPROTECTOR_TLS),y)
+stack_protector_prepare: prepare0
+ $(eval KBUILD_CFLAGS += \
+ -mstack-protector-guard=tls \
+ -mstack-protector-guard-offset=$(shell \
+ awk '{if ($$2 == "TSK_STACK_CANARY") print $$3;}'\
+ include/generated/asm-offsets.h))
+else
stack_protector_prepare: prepare0
$(eval SSP_PLUGIN_CFLAGS := \
-fplugin-arg-arm_ssp_per_task_plugin-offset=$(shell \
@@ -283,6 +292,7 @@ stack_protector_prepare: prepare0
$(eval KBUILD_CFLAGS += $(SSP_PLUGIN_CFLAGS))
$(eval GCC_PLUGINS_CFLAGS += $(SSP_PLUGIN_CFLAGS))
endif
+endif
all: $(notdir $(KBUILD_IMAGE))
diff --git a/arch/arm/boot/compressed/Makefile b/arch/arm/boot/compressed/Makefile
index 954eee8a785a..187a187706cb 100644
--- a/arch/arm/boot/compressed/Makefile
+++ b/arch/arm/boot/compressed/Makefile
@@ -92,17 +92,13 @@ ifeq ($(CONFIG_USE_OF),y)
OBJS += $(libfdt_objs) fdt_check_mem_start.o
endif
-# -fstack-protector-strong triggers protection checks in this code,
-# but it is being used too early to link to meaningful stack_chk logic.
-$(foreach o, $(libfdt_objs) atags_to_fdt.o fdt_check_mem_start.o, \
- $(eval CFLAGS_$(o) := -I $(srctree)/scripts/dtc/libfdt -fno-stack-protector))
-
targets := vmlinux vmlinux.lds piggy_data piggy.o \
head.o $(OBJS)
KBUILD_CFLAGS += -DDISABLE_BRANCH_PROFILING
ccflags-y := -fpic $(call cc-option,-mno-single-pic-base,) -fno-builtin \
+ -I$(srctree)/scripts/dtc/libfdt -fno-stack-protector \
-I$(obj) $(DISABLE_ARM_SSP_PER_TASK_PLUGIN)
ccflags-remove-$(CONFIG_FUNCTION_TRACER) += -pg
asflags-y := -DZIMAGE
diff --git a/arch/arm/boot/compressed/misc.c b/arch/arm/boot/compressed/misc.c
index e1e9a5dde853..c3c66ff2d696 100644
--- a/arch/arm/boot/compressed/misc.c
+++ b/arch/arm/boot/compressed/misc.c
@@ -128,13 +128,6 @@ asmlinkage void __div0(void)
error("Attempting division by 0!");
}
-const unsigned long __stack_chk_guard = 0x000a0dff;
-
-void __stack_chk_fail(void)
-{
- error("stack-protector: Kernel stack is corrupted\n");
-}
-
extern int do_decompress(u8 *input, int len, u8 *output, void (*error)(char *x));
diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index 235ad559acb2..7c16f8a2b738 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -93,6 +93,7 @@ dtb-$(CONFIG_ARCH_BCM2835) += \
bcm2837-rpi-3-b.dtb \
bcm2837-rpi-3-b-plus.dtb \
bcm2837-rpi-cm3-io3.dtb \
+ bcm2837-rpi-zero-2-w.dtb \
bcm2711-rpi-400.dtb \
bcm2711-rpi-4-b.dtb \
bcm2711-rpi-cm4-io.dtb \
@@ -187,6 +188,8 @@ dtb-$(CONFIG_ARCH_DAVINCI) += \
da850-lego-ev3.dtb
dtb-$(CONFIG_ARCH_DIGICOLOR) += \
cx92755_equinox.dtb
+dtb-$(CONFIG_ARCH_AIROHA) += \
+ en7523-evb.dtb
dtb-$(CONFIG_ARCH_EXYNOS3) += \
exynos3250-artik5-eval.dtb \
exynos3250-monk.dtb \
@@ -221,6 +224,8 @@ dtb-$(CONFIG_ARCH_EXYNOS5) += \
exynos5420-arndale-octa.dtb \
exynos5420-peach-pit.dtb \
exynos5420-smdk5420.dtb \
+ exynos5420-chagall-wifi.dtb \
+ exynos5420-klimt-wifi.dtb \
exynos5422-odroidhc1.dtb \
exynos5422-odroidxu3.dtb \
exynos5422-odroidxu3-lite.dtb \
@@ -269,7 +274,7 @@ dtb-$(CONFIG_ARCH_IXP4XX) += \
intel-ixp42x-dlink-dsm-g600.dtb \
intel-ixp42x-gateworks-gw2348.dtb \
intel-ixp43x-gateworks-gw2358.dtb \
- intel-ixp42x-netgear-wg302v2.dtb \
+ intel-ixp42x-netgear-wg302v1.dtb \
intel-ixp42x-arcom-vulcan.dtb \
intel-ixp42x-gateway-7001.dtb
dtb-$(CONFIG_ARCH_KEYSTONE) += \
@@ -281,6 +286,7 @@ dtb-$(CONFIG_ARCH_KEYSTONE) += \
dtb-$(CONFIG_MACH_KIRKWOOD) += \
kirkwood-b3.dtb \
kirkwood-blackarmor-nas220.dtb \
+ kirkwood-c200-v1.dtb \
kirkwood-cloudbox.dtb \
kirkwood-d2net.dtb \
kirkwood-db-88f6281.dtb \
@@ -735,6 +741,8 @@ dtb-$(CONFIG_SOC_IMX7D) += \
dtb-$(CONFIG_SOC_IMX7ULP) += \
imx7ulp-com.dtb \
imx7ulp-evk.dtb
+dtb-$(CONFIG_SOC_LAN966) += \
+ lan966x-pcb8291.dtb
dtb-$(CONFIG_SOC_LS1021A) += \
ls1021a-moxa-uc-8410a.dtb \
ls1021a-qds.dtb \
@@ -806,6 +814,7 @@ dtb-$(CONFIG_ARCH_OMAP3) += \
logicpd-som-lv-37xx-devkit.dtb \
omap3430-sdp.dtb \
omap3-beagle.dtb \
+ omap3-beagle-ab4.dtb \
omap3-beagle-xm.dtb \
omap3-beagle-xm-ab.dtb \
omap3-cm-t3517.dtb \
@@ -894,6 +903,7 @@ dtb-$(CONFIG_SOC_AM33XX) += \
am335x-regor-rdk.dtb \
am335x-sancloud-bbe.dtb \
am335x-sancloud-bbe-lite.dtb \
+ am335x-sancloud-bbe-extended-wifi.dtb \
am335x-shc.dtb \
am335x-sbc-t335.dtb \
am335x-sl50.dtb \
@@ -1161,6 +1171,7 @@ dtb-$(CONFIG_ARCH_STM32) += \
stm32mp157c-dhcom-picoitx.dtb \
stm32mp157c-dk2.dtb \
stm32mp157c-ed1.dtb \
+ stm32mp157c-emsbc-argon.dtb \
stm32mp157c-ev1.dtb \
stm32mp157c-lxa-mc1.dtb \
stm32mp157c-odyssey.dtb
@@ -1228,6 +1239,7 @@ dtb-$(CONFIG_MACH_SUN7I) += \
sun7i-a20-bananapro.dtb \
sun7i-a20-cubieboard2.dtb \
sun7i-a20-cubietruck.dtb \
+ sun7i-a20-haoyu-marsboard.dtb \
sun7i-a20-hummingbird.dtb \
sun7i-a20-itead-ibox.dtb \
sun7i-a20-i12-tvbox.dtb \
@@ -1415,6 +1427,7 @@ dtb-$(CONFIG_ARCH_ZYNQ) += \
zynq-zybo.dtb \
zynq-zybo-z7.dtb
dtb-$(CONFIG_MACH_ARMADA_370) += \
+ armada-370-c200-v2.dtb \
armada-370-db.dtb \
armada-370-dlink-dns327l.dtb \
armada-370-mirabox.dtb \
@@ -1492,6 +1505,9 @@ dtb-$(CONFIG_ARCH_MEDIATEK) += \
dtb-$(CONFIG_ARCH_MILBEAUT) += milbeaut-m10v-evb.dtb
dtb-$(CONFIG_ARCH_MSTARV7) += \
mstar-infinity-msc313-breadbee_crust.dtb \
+ mstar-infinity2m-ssd202d-100ask-dongshanpione.dtb \
+ mstar-infinity2m-ssd202d-miyoo-mini.dtb \
+ mstar-infinity2m-ssd202d-wirelesstag-ido-sbc2d06-v1b-22w.dtb \
mstar-infinity2m-ssd202d-ssd201htv2.dtb \
mstar-infinity2m-ssd202d-unitv2.dtb \
mstar-infinity3-msc313e-breadbee.dtb \
@@ -1505,6 +1521,7 @@ dtb-$(CONFIG_ARCH_ASPEED) += \
aspeed-bmc-arm-centriq2400-rep.dtb \
aspeed-bmc-arm-stardragon4800-rep2.dtb \
aspeed-bmc-asrock-e3c246d4i.dtb \
+ aspeed-bmc-asrock-romed8hm3.dtb \
aspeed-bmc-bytedance-g220a.dtb \
aspeed-bmc-facebook-bletchley.dtb \
aspeed-bmc-facebook-cloudripper.dtb \
@@ -1542,6 +1559,7 @@ dtb-$(CONFIG_ARCH_ASPEED) += \
aspeed-bmc-opp-zaius.dtb \
aspeed-bmc-portwell-neptune.dtb \
aspeed-bmc-quanta-q71l.dtb \
+ aspeed-bmc-quanta-s6q.dtb \
aspeed-bmc-supermicro-x11spi.dtb \
aspeed-bmc-inventec-transformers.dtb \
aspeed-bmc-tyan-s7106.dtb \
diff --git a/arch/arm/boot/dts/am335x-pdu001.dts b/arch/arm/boot/dts/am335x-pdu001.dts
index b793beeab245..ce6cc2b96654 100644
--- a/arch/arm/boot/dts/am335x-pdu001.dts
+++ b/arch/arm/boot/dts/am335x-pdu001.dts
@@ -353,7 +353,7 @@
};
};
- mcp79400: mcp79400@6f {
+ mcp79400: rtc@6f {
compatible = "microchip,mcp7940x";
reg = <0x6f>;
};
diff --git a/arch/arm/boot/dts/am335x-sancloud-bbe-extended-wifi.dts b/arch/arm/boot/dts/am335x-sancloud-bbe-extended-wifi.dts
new file mode 100644
index 000000000000..246a1a9b3e44
--- /dev/null
+++ b/arch/arm/boot/dts/am335x-sancloud-bbe-extended-wifi.dts
@@ -0,0 +1,113 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2021 Sancloud Ltd
+ * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/
+ */
+/dts-v1/;
+
+#include "am33xx.dtsi"
+#include "am335x-bone-common.dtsi"
+#include "am335x-boneblack-common.dtsi"
+#include "am335x-sancloud-bbe-common.dtsi"
+#include <dt-bindings/interrupt-controller/irq.h>
+
+/ {
+ model = "SanCloud BeagleBone Enhanced Extended WiFi";
+ compatible = "sancloud,am335x-boneenhanced",
+ "ti,am335x-bone-black",
+ "ti,am335x-bone",
+ "ti,am33xx";
+
+ wlan_en_reg: fixedregulator@2 {
+ compatible = "regulator-fixed";
+ regulator-name = "wlan-en-regulator";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ startup-delay-us= <100000>;
+ };
+};
+
+&am33xx_pinmux {
+ mmc3_pins: pinmux_mmc3_pins {
+ pinctrl-single,pins = <
+ /* gpmc_a9.gpio1_25: RADIO_EN */
+ AM33XX_PADCONF(AM335X_PIN_GPMC_A9, PIN_OUTPUT_PULLUP, MUX_MODE7)
+
+ /* gpmc_ad12.mmc2_dat0 */
+ AM33XX_PADCONF(AM335X_PIN_GPMC_AD12, PIN_INPUT_PULLUP, MUX_MODE3)
+
+ /* gpmc_ad13.mmc2_dat1 */
+ AM33XX_PADCONF(AM335X_PIN_GPMC_AD13, PIN_INPUT_PULLUP, MUX_MODE3)
+
+ /* gpmc_ad14.mmc2_dat2 */
+ AM33XX_PADCONF(AM335X_PIN_GPMC_AD14, PIN_INPUT_PULLUP, MUX_MODE3)
+
+ /* gpmc_ad15.mmc2_dat3 */
+ AM33XX_PADCONF(AM335X_PIN_GPMC_AD15, PIN_INPUT_PULLUP, MUX_MODE3)
+
+ /* gpmc_csn3.mmc2_cmd */
+ AM33XX_PADCONF(AM335X_PIN_GPMC_CSN3, PIN_INPUT_PULLUP, MUX_MODE3)
+
+ /* gpmc_clk.mmc2_clk */
+ AM33XX_PADCONF(AM335X_PIN_GPMC_CLK, PIN_INPUT_PULLUP, MUX_MODE3)
+ >;
+ };
+
+ bluetooth_pins: pinmux_bluetooth_pins {
+ pinctrl-single,pins = <
+ /* event_intr0.gpio0_19 */
+ AM33XX_PADCONF(AM335X_PIN_XDMA_EVENT_INTR0, PIN_INPUT_PULLUP, MUX_MODE7)
+ >;
+ };
+
+ uart1_pins: pinmux_uart1_pins {
+ pinctrl-single,pins = <
+ /* uart1_rxd */
+ AM33XX_PADCONF(AM335X_PIN_UART1_RXD, PIN_INPUT, MUX_MODE0)
+
+ /* uart1_txd */
+ AM33XX_PADCONF(AM335X_PIN_UART1_TXD, PIN_INPUT, MUX_MODE0)
+
+ /* uart1_ctsn */
+ AM33XX_PADCONF(AM335X_PIN_UART1_CTSN, PIN_INPUT_PULLDOWN, MUX_MODE0)
+
+ /* uart1_rtsn */
+ AM33XX_PADCONF(AM335X_PIN_UART1_RTSN, PIN_OUTPUT_PULLDOWN, MUX_MODE0)
+ >;
+ };
+};
+
+&i2c2 {
+ status = "disabled";
+};
+
+&mmc3 {
+ status = "okay";
+ vmmc-supply = <&wlan_en_reg>;
+ bus-width = <4>;
+ non-removable;
+ cap-power-off-card;
+ ti,needs-special-hs-handling;
+ keep-power-in-suspend;
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc3_pins>;
+ dmas = <&edma_xbar 12 0 1
+ &edma_xbar 13 0 2>;
+ dma-names = "tx", "rx";
+ clock-frequency = <50000000>;
+ max-frequency = <50000000>;
+};
+
+&uart1 {
+ status = "okay";
+
+ bluetooth {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart1_pins &bluetooth_pins>;
+ compatible = "qcom,qca6174-bt";
+ enable-gpios = <&gpio1 25 GPIO_ACTIVE_HIGH>;
+ clocks = <&l4ls_clkctrl AM3_L4LS_UART2_CLKCTRL 0>;
+ interrupt-parent = <&gpio0>;
+ interrupts = <19 IRQ_TYPE_EDGE_RISING>;
+ };
+};
diff --git a/arch/arm/boot/dts/am335x-wega.dtsi b/arch/arm/boot/dts/am335x-wega.dtsi
index 673159d93a6a..f957fea8208e 100644
--- a/arch/arm/boot/dts/am335x-wega.dtsi
+++ b/arch/arm/boot/dts/am335x-wega.dtsi
@@ -55,7 +55,7 @@
2 1 0 0 /* # 0: INACTIVE, 1: TX, 2: RX */
>;
tx-num-evt = <16>;
- rt-num-evt = <16>;
+ rx-num-evt = <16>;
status = "okay";
};
diff --git a/arch/arm/boot/dts/am43x-epos-evm.dts b/arch/arm/boot/dts/am43x-epos-evm.dts
index 2f4d2e4e9b3e..4f9a7251a107 100644
--- a/arch/arm/boot/dts/am43x-epos-evm.dts
+++ b/arch/arm/boot/dts/am43x-epos-evm.dts
@@ -11,7 +11,7 @@
#include <dt-bindings/pinctrl/am43xx.h>
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/pwm/pwm.h>
-#include <dt-bindings/sound/tlv320aic31xx-micbias.h>
+#include <dt-bindings/sound/tlv320aic31xx.h>
/ {
model = "TI AM43x EPOS EVM";
diff --git a/arch/arm/boot/dts/armada-370-c200-v2.dts b/arch/arm/boot/dts/armada-370-c200-v2.dts
new file mode 100644
index 000000000000..1a4a09bdde63
--- /dev/null
+++ b/arch/arm/boot/dts/armada-370-c200-v2.dts
@@ -0,0 +1,388 @@
+// SPDX-License-Identifier: (GPL-2.0-or-later OR MIT)
+/*
+ * Device Tree file for Ctera C200-V2
+ *
+ * Copyright (C) 2022 Pawel Dembicki <paweldembicki@gmail.com>
+ */
+
+/dts-v1/;
+
+#include "armada-370.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/thermal/thermal.h>
+#include <dt-bindings/leds/common.h>
+
+/ {
+ model = "Ctera C200 V2";
+ compatible = "ctera,c200-v2", "marvell,armada370", "marvell,armada-370-xp";
+
+ chosen {
+ bootargs = "console=ttyS0,115200";
+ stdout-path = "serial0:115200n8";
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0x00000000 0x40000000>; /* 1024 MB */
+ };
+
+ soc {
+ ranges = <MBUS_ID(0xf0, 0x01) 0 0xd0000000 0x100000
+ MBUS_ID(0x01, 0xe0) 0 0xfff00000 0x100000
+ MBUS_ID(0x09, 0x01) 0 0xf1100000 0x10000>;
+ };
+
+ thermal-zones {
+ ethphy-thermal {
+ polling-delay = <20000>;
+ polling-delay-passive = <2000>;
+
+ thermal-sensors = <&ethphy0>;
+
+ trips {
+ ethphy_alert1: trip1 {
+ temperature = <65000>;
+ hysteresis = <4000>;
+ type = "passive";
+ };
+
+ ethphy_crit: trip2 {
+ temperature = <100000>;
+ hysteresis = <2000>;
+ type = "critical";
+ };
+ };
+ };
+ };
+
+ beeper {
+ compatible = "pwm-beeper";
+ pinctrl-0 = <&pmx_beeper>;
+ pinctrl-names = "default";
+ pwms = <&gpio1 31 4000>;
+ };
+
+ gpio-poweroff {
+ compatible = "gpio-poweroff";
+ pinctrl-0 = <&pmx_poweroff>;
+ pinctrl-names = "default";
+ gpios = <&gpio0 7 GPIO_ACTIVE_HIGH>;
+ };
+
+ keys {
+ compatible = "gpio-keys";
+ pinctrl-0 = <&pmx_buttons>;
+ pinctrl-names = "default";
+
+ power {
+ label = "Power Button";
+ linux,code = <KEY_POWER>;
+ gpios = <&gpio0 10 GPIO_ACTIVE_HIGH>;
+ };
+
+ reset {
+ label = "Reset Button";
+ linux,code = <KEY_RESTART>;
+ gpios = <&gpio0 6 GPIO_ACTIVE_LOW>;
+ };
+
+ usb1 {
+ label = "USB1 Button";
+ linux,code = <BTN_0>;
+ gpios = <&gpio1 0 GPIO_ACTIVE_LOW>;
+ };
+
+ usb2 {
+ label = "USB2 Button";
+ linux,code = <BTN_1>;
+ gpios = <&gpio0 14 GPIO_ACTIVE_LOW>;
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ pinctrl-0 = <&pmx_leds1 &pmx_leds2>;
+ pinctrl-names = "default";
+
+ led-0 {
+ function = LED_FUNCTION_USB;
+ function-enumerator = <2>;
+ color = <LED_COLOR_ID_RED>;
+ gpios = <&gpio0 12 GPIO_ACTIVE_LOW>;
+ };
+
+ led-1 {
+ function = LED_FUNCTION_USB;
+ function-enumerator = <2>;
+ color = <LED_COLOR_ID_GREEN>;
+ gpios = <&gpio0 13 GPIO_ACTIVE_LOW>;
+ };
+
+ led-2 {
+ function = LED_FUNCTION_USB;
+ function-enumerator = <1>;
+ color = <LED_COLOR_ID_RED>;
+ gpios = <&gpio0 15 GPIO_ACTIVE_LOW>;
+ };
+
+ led-3 {
+ function = LED_FUNCTION_USB;
+ function-enumerator = <1>;
+ color = <LED_COLOR_ID_GREEN>;
+ gpios = <&gpio0 16 GPIO_ACTIVE_LOW>;
+ };
+
+ led-4 {
+ function = LED_FUNCTION_DISK;
+ function-enumerator = <2>;
+ color = <LED_COLOR_ID_GREEN>;
+ gpios = <&gpio1 15 GPIO_ACTIVE_LOW>;
+ };
+
+ led-5 {
+ function = LED_FUNCTION_DISK;
+ function-enumerator = <1>;
+ color = <LED_COLOR_ID_RED>;
+ gpios = <&gpio1 18 GPIO_ACTIVE_LOW>;
+ };
+
+ led-6 {
+ function = LED_FUNCTION_DISK;
+ function-enumerator = <2>;
+ color = <LED_COLOR_ID_RED>;
+ gpios = <&gpio1 19 GPIO_ACTIVE_LOW>;
+ };
+
+ led-7 {
+ function = LED_FUNCTION_INDICATOR;
+ color = <LED_COLOR_ID_BLUE>;
+ gpios = <&gpio1 20 GPIO_ACTIVE_HIGH>;
+ };
+
+ led-8 {
+ function = LED_FUNCTION_DISK_ERR;
+ color = <LED_COLOR_ID_RED>;
+ gpios = <&gpio1 21 GPIO_ACTIVE_LOW>;
+ };
+
+ led-9 {
+ function = LED_FUNCTION_DISK_ERR;
+ color = <LED_COLOR_ID_GREEN>;
+ gpios = <&gpio1 23 GPIO_ACTIVE_LOW>;
+ };
+
+ led-10 {
+ function = LED_FUNCTION_STATUS;
+ color = <LED_COLOR_ID_RED>;
+ gpios = <&gpio1 24 GPIO_ACTIVE_LOW>;
+ };
+
+ led-11 {
+ function = LED_FUNCTION_DISK;
+ function-enumerator = <1>;
+ color = <LED_COLOR_ID_GREEN>;
+ gpios = <&gpio1 25 GPIO_ACTIVE_LOW>;
+ };
+
+ led-12 {
+ function = LED_FUNCTION_STATUS;
+ color = <LED_COLOR_ID_GREEN>;
+ gpios = <&gpio1 26 GPIO_ACTIVE_LOW>;
+ };
+ };
+};
+
+&coherencyfab {
+ broken-idle;
+};
+
+&eth1 {
+ pinctrl-0 = <&ge1_rgmii_pins>;
+ pinctrl-names = "default";
+ status = "okay";
+ phy-handle = <&ethphy0>;
+ phy-connection-type = "rgmii-id";
+};
+
+&i2c0 {
+ pinctrl-0 = <&i2c0_pins>;
+ pinctrl-names = "default";
+ clock-frequency = <100000>;
+ status = "okay";
+
+ hwmon@2a {
+ compatible = "nuvoton,nct7802";
+ reg = <0x2a>;
+ };
+
+ rtc@30 {
+ compatible = "sii,s35390a";
+ reg = <0x30>;
+ };
+};
+
+&mdio {
+ pinctrl-0 = <&mdio_pins>;
+ pinctrl-names = "default";
+
+ ethphy0: ethernet-phy@0 { /* Marvell 88E1318 */
+ reg = <0>;
+ #thermal-sensor-cells = <0>;
+ };
+};
+
+&nand_controller {
+ status = "okay";
+
+ nand@0 {
+ reg = <0>;
+ label = "pxa3xx_nand-0";
+ nand-rb = <0>;
+ marvell,nand-keep-config;
+ nand-on-flash-bbt;
+ nand-ecc-strength = <4>;
+ nand-ecc-step-size = <512>;
+
+ partitions {
+ compatible = "fixed-partitions";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ partition@0 {
+ label = "uboot";
+ reg = <0x0000000 0x200000>;
+ read-only;
+ };
+
+ partition@200000 {
+ label = "certificate";
+ reg = <0x0200000 0x100000>;
+ read-only;
+ };
+
+ partition@300000 {
+ label = "preset_cfg";
+ reg = <0x0300000 0x100000>;
+ read-only;
+ };
+
+ partition@400000 {
+ label = "dev_params";
+ reg = <0x0400000 0x100000>;
+ read-only;
+ };
+ partition@500000 {
+ label = "active_bank";
+ reg = <0x0500000 0x0100000>;
+ };
+
+ partition@600000 {
+ label = "magic";
+ reg = <0x0600000 0x0100000>;
+ read-only;
+ };
+
+ partition@700000 {
+ label = "bank1";
+ reg = <0x0700000 0x2800000>;
+ };
+
+ partition@2f00000 {
+ label = "bank2";
+ reg = <0x2f00000 0x2800000>;
+ };
+
+ /* 0x5700000-0x5a00000 undefined in vendor firmware */
+
+ partition@5a00000 {
+ label = "reserved";
+ reg = <0x5a00000 0x2000000>;
+ };
+
+ partition@7a00000 {
+ label = "rootfs";
+ reg = <0x7a00000 0x8600000>;
+ };
+ };
+ };
+};
+
+&pciec {
+ status = "okay";
+
+ pcie@1,0 { /* Renesas uPD720202 USB 3.0 controller */
+ pinctrl-0 = <&pmx_pcie>;
+ pinctrl-names = "default";
+ status = "okay";
+ reset-gpios = <&gpio1 27 GPIO_ACTIVE_LOW>;
+ };
+};
+
+&pinctrl {
+ pmx_poweroff: pmx-poweroff {
+ marvell,pins = "mpp7";
+ marvell,function = "gpo";
+ };
+
+ pmx_power_cpu: pmx-power-cpu {
+ marvell,pins = "mpp4";
+ marvell,function = "vdd";
+ };
+
+ pmx_buttons: pmx-buttons {
+ marvell,pins = "mpp6", "mpp10", "mpp14", "mpp32";
+ marvell,function = "gpio";
+ };
+
+ pmx_leds1: pmx-leds1 {
+ marvell,pins = "mpp47";
+ marvell,function = "gpo";
+ };
+
+ pmx_leds2: pmx-leds2 {
+ marvell,pins = "mpp12", "mpp13", "mpp15", "mpp16", "mpp50", "mpp51",
+ "mpp52", "mpp53", "mpp55", "mpp56", "mpp57", "mpp58";
+ marvell,function = "gpio";
+ };
+
+ pmx_pcie: pmx-pcie {
+ marvell,pins = "mpp59";
+ marvell,function = "gpio";
+ };
+
+ pmx_beeper: pmx-beeper {
+ marvell,pins = "mpp63";
+ marvell,function = "gpio";
+ };
+};
+
+&pmsu {
+ pinctrl-0 = <&pmx_power_cpu>;
+ pinctrl-names = "default";
+};
+
+&rtc {
+ status = "disabled";
+};
+
+&sata {
+ nr-ports = <2>;
+ status = "okay";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ hdd0_temp: sata-port@0 {
+ reg = <0>;
+ #thermal-sensor-cells = <0>;
+ };
+
+ hdd1_temp: sata-port@1 {
+ reg = <1>;
+ #thermal-sensor-cells = <0>;
+ };
+};
+
+&uart0 {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/armada-385-turris-omnia.dts b/arch/arm/boot/dts/armada-385-turris-omnia.dts
index 5bd6a66d2c2b..f240018148f6 100644
--- a/arch/arm/boot/dts/armada-385-turris-omnia.dts
+++ b/arch/arm/boot/dts/armada-385-turris-omnia.dts
@@ -71,16 +71,19 @@
pcie@1,0 {
/* Port 0, Lane 0 */
status = "okay";
+ slot-power-limit-milliwatt = <10000>;
};
pcie@2,0 {
/* Port 1, Lane 0 */
status = "okay";
+ slot-power-limit-milliwatt = <10000>;
};
pcie@3,0 {
/* Port 2, Lane 0 */
status = "okay";
+ slot-power-limit-milliwatt = <10000>;
};
};
};
diff --git a/arch/arm/boot/dts/armada-385.dtsi b/arch/arm/boot/dts/armada-385.dtsi
index f0022d10c715..83392b92dae2 100644
--- a/arch/arm/boot/dts/armada-385.dtsi
+++ b/arch/arm/boot/dts/armada-385.dtsi
@@ -69,16 +69,25 @@
reg = <0x0800 0 0 0 0>;
#address-cells = <3>;
#size-cells = <2>;
+ interrupt-names = "intx";
+ interrupts-extended = <&gic GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>;
#interrupt-cells = <1>;
ranges = <0x82000000 0 0 0x82000000 0x1 0 1 0
0x81000000 0 0 0x81000000 0x1 0 1 0>;
bus-range = <0x00 0xff>;
- interrupt-map-mask = <0 0 0 0>;
- interrupt-map = <0 0 0 0 &gic GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-map-mask = <0 0 0 7>;
+ interrupt-map = <0 0 0 1 &pcie1_intc 0>,
+ <0 0 0 2 &pcie1_intc 1>,
+ <0 0 0 3 &pcie1_intc 2>,
+ <0 0 0 4 &pcie1_intc 3>;
marvell,pcie-port = <0>;
marvell,pcie-lane = <0>;
clocks = <&gateclk 8>;
status = "disabled";
+ pcie1_intc: interrupt-controller {
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ };
};
/* x1 port */
@@ -88,16 +97,25 @@
reg = <0x1000 0 0 0 0>;
#address-cells = <3>;
#size-cells = <2>;
+ interrupt-names = "intx";
+ interrupts-extended = <&gic GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>;
#interrupt-cells = <1>;
ranges = <0x82000000 0 0 0x82000000 0x2 0 1 0
0x81000000 0 0 0x81000000 0x2 0 1 0>;
bus-range = <0x00 0xff>;
- interrupt-map-mask = <0 0 0 0>;
- interrupt-map = <0 0 0 0 &gic GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-map-mask = <0 0 0 7>;
+ interrupt-map = <0 0 0 1 &pcie2_intc 0>,
+ <0 0 0 2 &pcie2_intc 1>,
+ <0 0 0 3 &pcie2_intc 2>,
+ <0 0 0 4 &pcie2_intc 3>;
marvell,pcie-port = <1>;
marvell,pcie-lane = <0>;
clocks = <&gateclk 5>;
status = "disabled";
+ pcie2_intc: interrupt-controller {
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ };
};
/* x1 port */
@@ -107,16 +125,25 @@
reg = <0x1800 0 0 0 0>;
#address-cells = <3>;
#size-cells = <2>;
+ interrupt-names = "intx";
+ interrupts-extended = <&gic GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>;
#interrupt-cells = <1>;
ranges = <0x82000000 0 0 0x82000000 0x3 0 1 0
0x81000000 0 0 0x81000000 0x3 0 1 0>;
bus-range = <0x00 0xff>;
- interrupt-map-mask = <0 0 0 0>;
- interrupt-map = <0 0 0 0 &gic GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-map-mask = <0 0 0 7>;
+ interrupt-map = <0 0 0 1 &pcie3_intc 0>,
+ <0 0 0 2 &pcie3_intc 1>,
+ <0 0 0 3 &pcie3_intc 2>,
+ <0 0 0 4 &pcie3_intc 3>;
marvell,pcie-port = <2>;
marvell,pcie-lane = <0>;
clocks = <&gateclk 6>;
status = "disabled";
+ pcie3_intc: interrupt-controller {
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ };
};
/*
@@ -129,16 +156,25 @@
reg = <0x2000 0 0 0 0>;
#address-cells = <3>;
#size-cells = <2>;
+ interrupt-names = "intx";
+ interrupts-extended = <&gic GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>;
#interrupt-cells = <1>;
ranges = <0x82000000 0 0 0x82000000 0x4 0 1 0
0x81000000 0 0 0x81000000 0x4 0 1 0>;
bus-range = <0x00 0xff>;
- interrupt-map-mask = <0 0 0 0>;
- interrupt-map = <0 0 0 0 &gic GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-map-mask = <0 0 0 7>;
+ interrupt-map = <0 0 0 1 &pcie4_intc 0>,
+ <0 0 0 2 &pcie4_intc 1>,
+ <0 0 0 3 &pcie4_intc 2>,
+ <0 0 0 4 &pcie4_intc 3>;
marvell,pcie-port = <3>;
marvell,pcie-lane = <0>;
clocks = <&gateclk 7>;
status = "disabled";
+ pcie4_intc: interrupt-controller {
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ };
};
};
};
diff --git a/arch/arm/boot/dts/aspeed-bmc-ampere-mtjade.dts b/arch/arm/boot/dts/aspeed-bmc-ampere-mtjade.dts
index 4c3c3f1a12ea..1b2e7ad37566 100644
--- a/arch/arm/boot/dts/aspeed-bmc-ampere-mtjade.dts
+++ b/arch/arm/boot/dts/aspeed-bmc-ampere-mtjade.dts
@@ -339,17 +339,8 @@
<&adc10mux 0>, <&adc10mux 1>,
<&adc11mux 0>, <&adc11mux 1>,
<&adc12mux 0>, <&adc12mux 1>,
- <&adc13mux 0>, <&adc13mux 1>;
- };
-
- iio-hwmon-adc14 {
- compatible = "iio-hwmon";
- io-channels = <&adc 14>;
- };
-
- iio-hwmon-battery {
- compatible = "iio-hwmon";
- io-channels = <&adc 15>;
+ <&adc13mux 0>, <&adc13mux 1>,
+ <&adc 14>, <&adc 15>;
};
};
@@ -362,6 +353,13 @@
/* spi-max-frequency = <50000000>; */
#include "openbmc-flash-layout-64.dtsi"
};
+
+ flash@1 {
+ status = "okay";
+ m25p,fast-read;
+ label = "alt-bmc";
+#include "openbmc-flash-layout-64-alt.dtsi"
+ };
};
&spi1 {
@@ -853,7 +851,7 @@
/*E0-E7*/ "","","","","","","","",
/*F0-F7*/ "","","BMC_SYS_PSON_L","S0_DDR_SAVE","PGOOD",
"S1_DDR_SAVE","","",
- /*G0-G7*/ "S0_FW_BOOT_OK","SHD_REQ_L","","S0_OVERTEMP_L","","",
+ /*G0-G7*/ "host0-ready","SHD_REQ_L","","S0_OVERTEMP_L","","",
"","",
/*H0-H7*/ "","","","","PSU1_VIN_GOOD","PSU2_VIN_GOOD","","",
/*I0-I7*/ "PSU1_PRESENT","PSU2_PRESENT","S1_BMC_SPECIAL_BOOT",
@@ -869,7 +867,7 @@
/*Q0-Q7*/ "","","","","","UID_BUTTON","","",
/*R0-R7*/ "","","BMC_EXT_HIGHTEMP_L","OCP_AUX_PWREN",
"OCP_MAIN_PWREN","RESET_BUTTON","","",
- /*S0-S7*/ "","","","","RTC_BAT_SEN_EN","","","",
+ /*S0-S7*/ "","","","","rtc-battery-voltage-read-enable","","","",
/*T0-T7*/ "","","","","","","","",
/*U0-U7*/ "","","","","","","","",
/*V0-V7*/ "","","","","","","","",
@@ -884,7 +882,7 @@
/*AC0-AC7*/ "SYS_PWR_GD","","","","","BMC_READY","SLAVE_PRESENT_L",
"BMC_OCP_PG";
- i2c4_o_en {
+ i2c4-o-en-hog {
gpio-hog;
gpios = <ASPEED_GPIO(Y, 2) GPIO_ACTIVE_HIGH>;
output-high;
diff --git a/arch/arm/boot/dts/aspeed-bmc-asrock-romed8hm3.dts b/arch/arm/boot/dts/aspeed-bmc-asrock-romed8hm3.dts
new file mode 100644
index 000000000000..e71ccfd1df63
--- /dev/null
+++ b/arch/arm/boot/dts/aspeed-bmc-asrock-romed8hm3.dts
@@ -0,0 +1,259 @@
+// SPDX-License-Identifier: GPL-2.0+
+/dts-v1/;
+
+#include "aspeed-g5.dtsi"
+#include <dt-bindings/gpio/aspeed-gpio.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+
+/{
+ model = "ASRock ROMED8HM3 BMC v1.00";
+ compatible = "asrock,romed8hm3-bmc", "aspeed,ast2500";
+
+ aliases {
+ serial4 = &uart5;
+ };
+
+ chosen {
+ stdout-path = &uart5;
+ bootargs = "console=tty0 console=ttyS4,115200 earlycon";
+ };
+
+ memory@80000000 {
+ reg = <0x80000000 0x20000000>;
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ heartbeat {
+ gpios = <&gpio ASPEED_GPIO(H, 6) GPIO_ACTIVE_LOW>;
+ linux,default-trigger = "timer";
+ };
+
+ system-fault {
+ gpios = <&gpio ASPEED_GPIO(Z, 2) GPIO_ACTIVE_LOW>;
+ panic-indicator;
+ };
+ };
+
+ iio-hwmon {
+ compatible = "iio-hwmon";
+ io-channels = <&adc 0>, <&adc 1>, <&adc 2>, <&adc 3>,
+ <&adc 4>, <&adc 5>, <&adc 6>, <&adc 7>,
+ <&adc 8>, <&adc 9>, <&adc 10>, <&adc 11>,
+ <&adc 12>, <&adc 13>, <&adc 14>, <&adc 15>;
+ };
+};
+
+&fmc {
+ status = "okay";
+ flash@0 {
+ status = "okay";
+ m25p,fast-read;
+ label = "bmc";
+ spi-max-frequency = <100000000>; /* 100 MHz */
+#include "openbmc-flash-layout-64.dtsi"
+ };
+};
+
+&uart5 {
+ status = "okay";
+};
+
+&vuart {
+ status = "okay";
+ aspeed,lpc-io-reg = <0x2f8>;
+ aspeed,lpc-interrupts = <3 IRQ_TYPE_LEVEL_HIGH>;
+};
+
+&mac0 {
+ status = "okay";
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_rgmii1_default &pinctrl_mdio1_default>;
+};
+
+&i2c0 {
+ status = "okay";
+
+ /* inlet temp sensor */
+ w83773g@4c {
+ compatible = "nuvoton,w83773g";
+ reg = <0x4c>;
+ };
+};
+
+&i2c1 {
+ status = "okay";
+};
+
+&i2c2 {
+ status = "okay";
+
+ /* IPB temp sensor */
+ w83773g@4c {
+ compatible = "nuvoton,w83773g";
+ reg = <0x4c>;
+ };
+
+ /* IPB PMIC */
+ lm25066@40 {
+ compatible = "lm25066";
+ reg = <0x40>;
+ };
+
+ /* 12VSB PMIC */
+ lm25066@41 {
+ compatible = "lm25066";
+ reg = <0x41>;
+ };
+};
+
+&i2c4 {
+ status = "okay";
+};
+
+&i2c5 {
+ status = "okay";
+};
+
+&i2c6 {
+ status = "okay";
+};
+
+&i2c7 {
+ status = "okay";
+
+ /* Baseboard FRU eeprom */
+ eeprom@50 {
+ compatible = "st,24c128", "atmel,24c128";
+ reg = <0x50>;
+ pagesize = <16>;
+ };
+};
+
+&i2c8 {
+ status = "okay";
+};
+
+&i2c9 {
+ status = "okay";
+};
+
+&video {
+ status = "okay";
+};
+
+&vhub {
+ status = "okay";
+};
+
+&lpc_ctrl {
+ status = "okay";
+};
+
+&lpc_snoop {
+ status = "okay";
+ snoop-ports = <0x80>;
+};
+
+&kcs3 {
+ status = "okay";
+ aspeed,lpc-io-reg = <0xca2>;
+};
+
+&pwm_tacho {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pwm3_default
+ &pinctrl_pwm4_default
+ &pinctrl_pwm5_default
+ &pinctrl_pwm6_default>;
+
+ fan@3 {
+ reg = <0x03>;
+ aspeed,fan-tach-ch = /bits/ 8 <0x03 0x0b>;
+ };
+
+ fan@4 {
+ reg = <0x04>;
+ aspeed,fan-tach-ch = /bits/ 8 <0x04 0x0c>;
+ };
+
+ fan@5 {
+ reg = <0x05>;
+ aspeed,fan-tach-ch = /bits/ 8 <0x05 0x0d>;
+ };
+
+ fan@6 {
+ reg = <0x06>;
+ aspeed,fan-tach-ch = /bits/ 8 <0x06 0x0e>;
+ };
+};
+
+&gpio {
+ status = "okay";
+ gpio-line-names =
+ /* A */ "LOCATORLED_STATUS_N", "BMC_MAC2_INTB", "NMI_BTN_N", "BMC_NMI",
+ "", "", "", "",
+ /* B */ "DDR_MEM_TEMP", "", "", "", "", "", "", "",
+ /* C */ "", "", "", "", "PCIE_HP_SEL_N", "PCIE_SATA_SEL_N", "LOCATORBTN", "",
+ /* D */ "BMC_PSIN", "BMC_PSOUT", "BMC_RESETCON", "RESETCON",
+ "", "", "", "PSU_FAN_FAIL_N",
+ /* E */ "", "", "", "", "", "", "", "",
+ /* F */ "NIC_PWR_GOOD", "PRSNTB0", "PRSNTB1", "PRSNTB2",
+ "PRSNTB3", "", "3VSB_PCIE1_PG", "12V_PCIE1_PG",
+ /* G */ "HWM_BAT_EN", "CHASSIS_ID0", "CHASSIS_ID1", "CHASSIS_ID2",
+ "BMC_ALERT1_N_R", "BMC_ALERT2_N_R", "BMC_ALERT3_N", "BMC_ALERT4_N",
+ /* H */ "X24_C1_PRSNT", "X24_C2_PRSNT", "X24_C3_PRSNT", "FM_MEM_THERM_EVENT_BMC_R_N",
+ "FACMODE", "BMC_RTCRST", "BMC_HB_LED_N", "BMC_CASEOPEN",
+ /* I */ "", "", "", "", "", "", "", "",
+ /* J */ "BMC_READY", "BMC_PCH_BIOS_CS_N", "", "P0_MA_DDR_QS_CS_N",
+ "", "", "", "",
+ /* K */ "", "", "", "", "", "", "", "",
+ /* L */ "", "", "", "", "", "", "", "",
+ /* M */ "", "", "MEZZ_PWRBRK_N", "OCP_HP_RST_EN",
+ "MAIN_PWR_EN_G", "BMC_MAIN_EN", "AUX_PWR_EN_G", "BMC_AUX_EN",
+ /* N */ "", "", "", "", "", "", "", "",
+ /* O */ "", "", "", "", "", "", "", "",
+ /* P */ "", "", "", "", "", "", "", "",
+ /* Q */ "", "", "", "",
+ "BMC_SMB_PRESENT_1_N", "BMC_SMB_PRESENT_2_N",
+ "BMC_SMB_PRESENT_3_N", "BMC_PCIE_WAKE_N",
+ /* R */ "", "", "THERMALTRIP_CLEAR_N", "", "", "", "", "",
+ /* S */ "", "", "", "", "", "", "", "",
+ /* T */ "", "", "", "", "", "", "", "",
+ /* U */ "", "", "", "", "", "", "", "",
+ /* V */ "", "", "", "", "", "", "", "",
+ /* W */ "", "", "", "", "", "", "", "",
+ /* X */ "", "", "", "", "", "", "", "",
+ /* Y */ "SLP_S3", "SLP_S4_S5", "NODE_ID_1", "NODE_ID_2", "", "", "", "",
+ /* Z */ "", "", "SYSTEM_FAULT_LED_N", "FAST_THROTTLE_N",
+ "", "", "", "",
+ /* AA */ "FM_CPU0_IBMC_THERMTRIP_N", "", "PROCHOT_L_G", "",
+ "", "", "", "",
+ /* AB */ "BMC_FORCE_SELFREFRESH", "PWRGD_OUT", "", "IRQ_BMC_PCH_SMI_LPC_N",
+ "", "", "", "",
+ /* AC */ "", "", "", "", "", "", "", "";
+};
+
+&adc {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_adc0_default
+ &pinctrl_adc1_default
+ &pinctrl_adc2_default
+ &pinctrl_adc3_default
+ &pinctrl_adc4_default
+ &pinctrl_adc5_default
+ &pinctrl_adc6_default
+ &pinctrl_adc7_default
+ &pinctrl_adc8_default
+ &pinctrl_adc9_default
+ &pinctrl_adc10_default
+ &pinctrl_adc11_default
+ &pinctrl_adc12_default
+ &pinctrl_adc13_default
+ &pinctrl_adc14_default
+ &pinctrl_adc15_default>;
+};
diff --git a/arch/arm/boot/dts/aspeed-bmc-facebook-bletchley.dts b/arch/arm/boot/dts/aspeed-bmc-facebook-bletchley.dts
index f973ea883b97..eaf1bc261ee3 100644
--- a/arch/arm/boot/dts/aspeed-bmc-facebook-bletchley.dts
+++ b/arch/arm/boot/dts/aspeed-bmc-facebook-bletchley.dts
@@ -5,6 +5,8 @@
#include "aspeed-g6.dtsi"
#include <dt-bindings/gpio/aspeed-gpio.h>
#include <dt-bindings/usb/pd.h>
+#include <dt-bindings/leds/leds-pca955x.h>
+#include <dt-bindings/interrupt-controller/irq.h>
/ {
model = "Facebook Bletchley BMC";
@@ -31,7 +33,7 @@
<&adc1 4>, <&adc1 5>, <&adc1 6>, <&adc1 7>;
};
- spi_gpio: spi-gpio {
+ spi1_gpio: spi1-gpio {
compatible = "spi-gpio";
#address-cells = <1>;
#size-cells = <0>;
@@ -49,119 +51,165 @@
};
};
+ spi2_gpio: spi2-gpio {
+ compatible = "spi-gpio";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ gpio-sck = <&gpio0 ASPEED_GPIO(X, 3) GPIO_ACTIVE_HIGH>;
+ gpio-mosi = <&gpio0 ASPEED_GPIO(X, 4) GPIO_ACTIVE_HIGH>;
+ gpio-miso = <&gpio0 ASPEED_GPIO(X, 5) GPIO_ACTIVE_HIGH>;
+ num-chipselects = <1>;
+ cs-gpios = <&gpio0 ASPEED_GPIO(X, 0) GPIO_ACTIVE_LOW>;
+
+ flash@0 {
+ reg = <0>;
+ compatible = "jedec,spi-nor";
+ m25p,fast-read;
+ label = "pnor";
+ spi-max-frequency = <100000000>;
+ };
+ };
+
switchphy: ethernet-phy@0 {
// Fixed link
};
- leds {
+ front_gpio_leds {
compatible = "gpio-leds";
-
sys_log_id {
- retain-state-shutdown;
- default-state = "keep";
+ default-state = "off";
gpios = <&front_leds 0 GPIO_ACTIVE_HIGH>;
};
+ };
+
+ fan_gpio_leds {
+ compatible = "gpio-leds";
fan0_blue {
retain-state-shutdown;
default-state = "on";
- gpios = <&fan_ioexp 8 GPIO_ACTIVE_HIGH>;
+ gpios = <&fan_leds 8 GPIO_ACTIVE_HIGH>;
};
fan1_blue {
retain-state-shutdown;
default-state = "on";
- gpios = <&fan_ioexp 9 GPIO_ACTIVE_HIGH>;
+ gpios = <&fan_leds 9 GPIO_ACTIVE_HIGH>;
};
fan2_blue {
retain-state-shutdown;
default-state = "on";
- gpios = <&fan_ioexp 10 GPIO_ACTIVE_HIGH>;
+ gpios = <&fan_leds 10 GPIO_ACTIVE_HIGH>;
};
fan3_blue {
retain-state-shutdown;
default-state = "on";
- gpios = <&fan_ioexp 11 GPIO_ACTIVE_HIGH>;
+ gpios = <&fan_leds 11 GPIO_ACTIVE_HIGH>;
};
fan0_amber {
retain-state-shutdown;
default-state = "off";
- gpios = <&fan_ioexp 12 GPIO_ACTIVE_HIGH>;
+ gpios = <&fan_leds 12 GPIO_ACTIVE_HIGH>;
};
fan1_amber {
retain-state-shutdown;
default-state = "off";
- gpios = <&fan_ioexp 13 GPIO_ACTIVE_HIGH>;
+ gpios = <&fan_leds 13 GPIO_ACTIVE_HIGH>;
};
fan2_amber {
retain-state-shutdown;
default-state = "off";
- gpios = <&fan_ioexp 14 GPIO_ACTIVE_HIGH>;
+ gpios = <&fan_leds 14 GPIO_ACTIVE_HIGH>;
};
fan3_amber {
retain-state-shutdown;
default-state = "off";
- gpios = <&fan_ioexp 15 GPIO_ACTIVE_HIGH>;
- };
- sled0_amber {
- retain-state-shutdown;
- default-state = "off";
- gpios = <&sled0_leds 0 GPIO_ACTIVE_LOW>;
- };
- sled0_blue {
- retain-state-shutdown;
- default-state = "off";
- gpios = <&sled0_leds 1 GPIO_ACTIVE_LOW>;
+ gpios = <&fan_leds 15 GPIO_ACTIVE_HIGH>;
};
+ };
+
+ sled1_gpio_leds {
+ compatible = "gpio-leds";
sled1_amber {
retain-state-shutdown;
- default-state = "off";
+ default-state = "keep";
gpios = <&sled1_leds 0 GPIO_ACTIVE_LOW>;
};
sled1_blue {
retain-state-shutdown;
- default-state = "off";
+ default-state = "keep";
gpios = <&sled1_leds 1 GPIO_ACTIVE_LOW>;
};
+ };
+
+ sled2_gpio_leds {
+ compatible = "gpio-leds";
sled2_amber {
retain-state-shutdown;
- default-state = "off";
+ default-state = "keep";
gpios = <&sled2_leds 0 GPIO_ACTIVE_LOW>;
};
sled2_blue {
retain-state-shutdown;
- default-state = "off";
+ default-state = "keep";
gpios = <&sled2_leds 1 GPIO_ACTIVE_LOW>;
};
+ };
+
+ sled3_gpio_leds {
+ compatible = "gpio-leds";
sled3_amber {
retain-state-shutdown;
- default-state = "off";
+ default-state = "keep";
gpios = <&sled3_leds 0 GPIO_ACTIVE_LOW>;
};
sled3_blue {
retain-state-shutdown;
- default-state = "off";
+ default-state = "keep";
gpios = <&sled3_leds 1 GPIO_ACTIVE_LOW>;
};
+ };
+
+ sled4_gpio_leds {
+ compatible = "gpio-leds";
sled4_amber {
retain-state-shutdown;
- default-state = "off";
+ default-state = "keep";
gpios = <&sled4_leds 0 GPIO_ACTIVE_LOW>;
};
sled4_blue {
retain-state-shutdown;
- default-state = "off";
+ default-state = "keep";
gpios = <&sled4_leds 1 GPIO_ACTIVE_LOW>;
};
+ };
+
+ sled5_gpio_leds {
+ compatible = "gpio-leds";
sled5_amber {
retain-state-shutdown;
- default-state = "off";
+ default-state = "keep";
gpios = <&sled5_leds 0 GPIO_ACTIVE_LOW>;
};
sled5_blue {
retain-state-shutdown;
- default-state = "off";
+ default-state = "keep";
gpios = <&sled5_leds 1 GPIO_ACTIVE_LOW>;
};
};
+
+ sled6_gpio_leds {
+ compatible = "gpio-leds";
+ sled6_amber {
+ retain-state-shutdown;
+ default-state = "keep";
+ gpios = <&sled6_leds 0 GPIO_ACTIVE_LOW>;
+ };
+ sled6_blue {
+ retain-state-shutdown;
+ default-state = "keep";
+ gpios = <&sled6_leds 1 GPIO_ACTIVE_LOW>;
+ };
+ };
};
&mac2 {
@@ -177,10 +225,6 @@
};
};
-&rtc {
- status = "okay";
-};
-
&fmc {
status = "okay";
flash@0 {
@@ -190,24 +234,21 @@
spi-max-frequency = <50000000>;
#include "openbmc-flash-layout-128.dtsi"
};
-};
-
-&spi2 {
- status = "okay";
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_spi2_default>;
-
- flash@0 {
+ flash@1 {
status = "okay";
m25p,fast-read;
- label = "pnor";
- spi-max-frequency = <100000000>;
+ label = "flash1";
+ spi-max-frequency = <50000000>;
};
};
&i2c0 {
status = "okay";
- /* TODO: Add ADC INA230 */
+ ina230@45 {
+ compatible = "ti,ina230";
+ reg = <0x45>;
+ shunt-resistor = <2000>;
+ };
mp5023@40 {
compatible = "mps,mp5023";
@@ -219,7 +260,7 @@
reg = <0x4f>;
};
- sled0_ioexp: pca9539@76 {
+ sled1_ioexp: pca9539@76 {
compatible = "nxp,pca9539";
reg = <0x76>;
#address-cells = <1>;
@@ -227,14 +268,17 @@
gpio-controller;
#gpio-cells = <2>;
+ interrupt-parent = <&gpio0>;
+ interrupts = <ASPEED_GPIO(M, 0) IRQ_TYPE_LEVEL_LOW>;
+
gpio-line-names =
- "SLED0_MS_DETECT1","SLED0_VBUS_BMC_EN","SLED0_INA230_ALERT","SLED0_P12V_STBY_ALERT",
- "SLED0_SSD_ALERT","SLED0_MS_DETECT0","SLED0_RST_CCG5","SLED0_FUSB302_INT",
- "SLED0_MD_STBY_RESET","SLED0_MD_IOEXP_EN_FAULT","SLED0_MD_DIR","SLED0_MD_DECAY",
- "SLED0_MD_MODE1","SLED0_MD_MODE2","SLED0_MD_MODE3","power-host0";
+ "SLED1_MS_DETECT1","SLED1_VBUS_BMC_EN","SLED1_INA230_ALERT","SLED1_P12V_STBY_ALERT",
+ "SLED1_SSD_ALERT","SLED1_MS_DETECT0","SLED1_RST_CCG5","SLED1_FUSB302_INT",
+ "SLED1_MD_STBY_RESET","SLED1_MD_IOEXP_EN_FAULT","SLED1_MD_DIR","SLED1_MD_DECAY",
+ "SLED1_MD_MODE1","SLED1_MD_MODE2","SLED1_MD_MODE3","power-host1";
};
- sled0_leds: pca9552@67 {
+ sled1_leds: pca9552@67 {
compatible = "nxp,pca9552";
reg = <0x67>;
#address-cells = <1>;
@@ -243,13 +287,13 @@
#gpio-cells = <2>;
gpio-line-names =
- "led-sled0-amber","led-sled0-blue","SLED0_RST_IOEXP","",
+ "led-sled1-amber","led-sled1-blue","SLED1_RST_IOEXP","SLED1_MD_REF_PWM",
"","","","",
"","","","",
"","","","";
};
- sled0_fusb302: typec-portc@22 {
+ sled1_fusb302: typec-portc@22 {
compatible = "fcs,fusb302";
reg = <0x22>;
@@ -270,7 +314,11 @@
&i2c1 {
status = "okay";
- /* TODO: Add ADC INA230 */
+ ina230@45 {
+ compatible = "ti,ina230";
+ reg = <0x45>;
+ shunt-resistor = <2000>;
+ };
mp5023@40 {
compatible = "mps,mp5023";
@@ -282,7 +330,7 @@
reg = <0x4f>;
};
- sled1_ioexp: pca9539@76 {
+ sled2_ioexp: pca9539@76 {
compatible = "nxp,pca9539";
reg = <0x76>;
#address-cells = <1>;
@@ -290,14 +338,17 @@
gpio-controller;
#gpio-cells = <2>;
+ interrupt-parent = <&gpio0>;
+ interrupts = <ASPEED_GPIO(M, 1) IRQ_TYPE_LEVEL_LOW>;
+
gpio-line-names =
- "SLED1_MS_DETECT1","SLED1_VBUS_BMC_EN","SLED1_INA230_ALERT","SLED1_P12V_STBY_ALERT",
- "SLED1_SSD_ALERT","SLED1_MS_DETECT0","SLED1_RST_CCG5","SLED1_FUSB302_INT",
- "SLED1_MD_STBY_RESET","SLED1_MD_IOEXP_EN_FAULT","SLED1_MD_DIR","SLED1_MD_DECAY",
- "SLED1_MD_MODE1","SLED1_MD_MODE2","SLED1_MD_MODE3","power-host1";
+ "SLED2_MS_DETECT1","SLED2_VBUS_BMC_EN","SLED2_INA230_ALERT","SLED2_P12V_STBY_ALERT",
+ "SLED2_SSD_ALERT","SLED2_MS_DETECT0","SLED2_RST_CCG5","SLED2_FUSB302_INT",
+ "SLED2_MD_STBY_RESET","SLED2_MD_IOEXP_EN_FAULT","SLED2_MD_DIR","SLED2_MD_DECAY",
+ "SLED2_MD_MODE1","SLED2_MD_MODE2","SLED2_MD_MODE3","power-host2";
};
- sled1_leds: pca9552@67 {
+ sled2_leds: pca9552@67 {
compatible = "nxp,pca9552";
reg = <0x67>;
#address-cells = <1>;
@@ -306,13 +357,13 @@
#gpio-cells = <2>;
gpio-line-names =
- "led-sled1-amber","led-sled1-blue","SLED1_RST_IOEXP","",
+ "led-sled2-amber","led-sled2-blue","SLED2_RST_IOEXP","SLED2_MD_REF_PWM",
"","","","",
"","","","",
"","","","";
};
- sled1_fusb302: typec-portc@22 {
+ sled2_fusb302: typec-portc@22 {
compatible = "fcs,fusb302";
reg = <0x22>;
@@ -331,13 +382,13 @@
};
};
-&i2c1 {
- status = "okay";
-};
-
&i2c2 {
status = "okay";
- /* TODO: Add ADC INA230 */
+ ina230@45 {
+ compatible = "ti,ina230";
+ reg = <0x45>;
+ shunt-resistor = <2000>;
+ };
mp5023@40 {
compatible = "mps,mp5023";
@@ -349,7 +400,7 @@
reg = <0x4f>;
};
- sled2_ioexp: pca9539@76 {
+ sled3_ioexp: pca9539@76 {
compatible = "nxp,pca9539";
reg = <0x76>;
#address-cells = <1>;
@@ -357,14 +408,17 @@
gpio-controller;
#gpio-cells = <2>;
+ interrupt-parent = <&gpio0>;
+ interrupts = <ASPEED_GPIO(M, 2) IRQ_TYPE_LEVEL_LOW>;
+
gpio-line-names =
- "SLED2_MS_DETECT1","SLED2_VBUS_BMC_EN","SLED2_INA230_ALERT","SLED2_P12V_STBY_ALERT",
- "SLED2_SSD_ALERT","SLED2_MS_DETECT0","SLED2_RST_CCG5","SLED2_FUSB302_INT",
- "SLED2_MD_STBY_RESET","SLED2_MD_IOEXP_EN_FAULT","SLED2_MD_DIR","SLED2_MD_DECAY",
- "SLED2_MD_MODE1","SLED2_MD_MODE2","SLED2_MD_MODE3","power-host2";
+ "SLED3_MS_DETECT1","SLED3_VBUS_BMC_EN","SLED3_INA230_ALERT","SLED3_P12V_STBY_ALERT",
+ "SLED3_SSD_ALERT","SLED3_MS_DETECT0","SLED3_RST_CCG5","SLED3_FUSB302_INT",
+ "SLED3_MD_STBY_RESET","SLED3_MD_IOEXP_EN_FAULT","SLED3_MD_DIR","SLED3_MD_DECAY",
+ "SLED3_MD_MODE1","SLED3_MD_MODE2","SLED3_MD_MODE3","power-host3";
};
- sled2_leds: pca9552@67 {
+ sled3_leds: pca9552@67 {
compatible = "nxp,pca9552";
reg = <0x67>;
#address-cells = <1>;
@@ -373,13 +427,13 @@
#gpio-cells = <2>;
gpio-line-names =
- "led-sled2-amber","led-sled2-blue","SLED2_RST_IOEXP","",
+ "led-sled3-amber","led-sled3-blue","SLED3_RST_IOEXP","SLED3_MD_REF_PWM",
"","","","",
"","","","",
"","","","";
};
- sled2_fusb302: typec-portc@22 {
+ sled3_fusb302: typec-portc@22 {
compatible = "fcs,fusb302";
reg = <0x22>;
@@ -400,7 +454,11 @@
&i2c3 {
status = "okay";
- /* TODO: Add ADC INA230 */
+ ina230@45 {
+ compatible = "ti,ina230";
+ reg = <0x45>;
+ shunt-resistor = <2000>;
+ };
mp5023@40 {
compatible = "mps,mp5023";
@@ -412,7 +470,7 @@
reg = <0x4f>;
};
- sled3_ioexp: pca9539@76 {
+ sled4_ioexp: pca9539@76 {
compatible = "nxp,pca9539";
reg = <0x76>;
#address-cells = <1>;
@@ -420,14 +478,17 @@
gpio-controller;
#gpio-cells = <2>;
+ interrupt-parent = <&gpio0>;
+ interrupts = <ASPEED_GPIO(M, 3) IRQ_TYPE_LEVEL_LOW>;
+
gpio-line-names =
- "SLED3_MS_DETECT1","SLED3_VBUS_BMC_EN","SLED3_INA230_ALERT","SLED3_P12V_STBY_ALERT",
- "SLED3_SSD_ALERT","SLED3_MS_DETECT0","SLED3_RST_CCG5","SLED3_FUSB302_INT",
- "SLED3_MD_STBY_RESET","SLED3_MD_IOEXP_EN_FAULT","SLED3_MD_DIR","SLED3_MD_DECAY",
- "SLED3_MD_MODE1","SLED3_MD_MODE2","SLED3_MD_MODE3","power-host3";
+ "SLED4_MS_DETECT1","SLED4_VBUS_BMC_EN","SLED4_INA230_ALERT","SLED4_P12V_STBY_ALERT",
+ "SLED4_SSD_ALERT","SLED4_MS_DETECT0","SLED4_RST_CCG5","SLED4_FUSB302_INT",
+ "SLED4_MD_STBY_RESET","SLED4_MD_IOEXP_EN_FAULT","SLED4_MD_DIR","SLED4_MD_DECAY",
+ "SLED4_MD_MODE1","SLED4_MD_MODE2","SLED4_MD_MODE3","power-host4";
};
- sled3_leds: pca9552@67 {
+ sled4_leds: pca9552@67 {
compatible = "nxp,pca9552";
reg = <0x67>;
#address-cells = <1>;
@@ -436,13 +497,13 @@
#gpio-cells = <2>;
gpio-line-names =
- "led-sled3-amber","led-sled3-blue","SLED3_RST_IOEXP","",
+ "led-sled4-amber","led-sled4-blue","SLED4_RST_IOEXP","SLED4_MD_REF_PWM",
"","","","",
"","","","",
"","","","";
};
- sled3_fusb302: typec-portc@22 {
+ sled4_fusb302: typec-portc@22 {
compatible = "fcs,fusb302";
reg = <0x22>;
@@ -463,7 +524,11 @@
&i2c4 {
status = "okay";
- /* TODO: Add ADC INA230 */
+ ina230@45 {
+ compatible = "ti,ina230";
+ reg = <0x45>;
+ shunt-resistor = <2000>;
+ };
mp5023@40 {
compatible = "mps,mp5023";
@@ -475,7 +540,7 @@
reg = <0x4f>;
};
- sled4_ioexp: pca9539@76 {
+ sled5_ioexp: pca9539@76 {
compatible = "nxp,pca9539";
reg = <0x76>;
#address-cells = <1>;
@@ -483,14 +548,17 @@
gpio-controller;
#gpio-cells = <2>;
+ interrupt-parent = <&gpio0>;
+ interrupts = <ASPEED_GPIO(M, 4) IRQ_TYPE_LEVEL_LOW>;
+
gpio-line-names =
- "SLED4_MS_DETECT1","SLED4_VBUS_BMC_EN","SLED4_INA230_ALERT","SLED4_P12V_STBY_ALERT",
- "SLED4_SSD_ALERT","SLED4_MS_DETECT0","SLED4_RST_CCG5","SLED4_FUSB302_INT",
- "SLED4_MD_STBY_RESET","SLED4_MD_IOEXP_EN_FAULT","SLED4_MD_DIR","SLED4_MD_DECAY",
- "SLED4_MD_MODE1","SLED4_MD_MODE2","SLED4_MD_MODE3","power-host4";
+ "SLED5_MS_DETECT1","SLED5_VBUS_BMC_EN","SLED5_INA230_ALERT","SLED5_P12V_STBY_ALERT",
+ "SLED5_SSD_ALERT","SLED5_MS_DETECT0","SLED5_RST_CCG5","SLED5_FUSB302_INT",
+ "SLED5_MD_STBY_RESET","SLED5_MD_IOEXP_EN_FAULT","SLED5_MD_DIR","SLED5_MD_DECAY",
+ "SLED5_MD_MODE1","SLED5_MD_MODE2","SLED5_MD_MODE3","power-host5";
};
- sled4_leds: pca9552@67 {
+ sled5_leds: pca9552@67 {
compatible = "nxp,pca9552";
reg = <0x67>;
#address-cells = <1>;
@@ -499,13 +567,13 @@
#gpio-cells = <2>;
gpio-line-names =
- "led-sled4-amber","led-sled4-blue","SLED4_RST_IOEXP","",
+ "led-sled5-amber","led-sled5-blue","SLED5_RST_IOEXP","SLED5_MD_REF_PWM",
"","","","",
"","","","",
"","","","";
};
- sled4_fusb302: typec-portc@22 {
+ sled5_fusb302: typec-portc@22 {
compatible = "fcs,fusb302";
reg = <0x22>;
@@ -526,7 +594,11 @@
&i2c5 {
status = "okay";
- /* TODO: Add ADC INA230 */
+ ina230@45 {
+ compatible = "ti,ina230";
+ reg = <0x45>;
+ shunt-resistor = <2000>;
+ };
mp5023@40 {
compatible = "mps,mp5023";
@@ -538,7 +610,7 @@
reg = <0x4f>;
};
- sled5_ioexp: pca9539@76 {
+ sled6_ioexp: pca9539@76 {
compatible = "nxp,pca9539";
reg = <0x76>;
#address-cells = <1>;
@@ -546,14 +618,17 @@
gpio-controller;
#gpio-cells = <2>;
+ interrupt-parent = <&gpio0>;
+ interrupts = <ASPEED_GPIO(M, 5) IRQ_TYPE_LEVEL_LOW>;
+
gpio-line-names =
- "SLED5_MS_DETECT1","SLED5_VBUS_BMC_EN","SLED5_INA230_ALERT","SLED5_P12V_STBY_ALERT",
- "SLED5_SSD_ALERT","SLED5_MS_DETECT0","SLED5_RST_CCG5","SLED5_FUSB302_INT",
- "SLED5_MD_STBY_RESET","SLED5_MD_IOEXP_EN_FAULT","SLED5_MD_DIR","SLED5_MD_DECAY",
- "SLED5_MD_MODE1","SLED5_MD_MODE2","SLED5_MD_MODE3","power-host5";
+ "SLED6_MS_DETECT1","SLED6_VBUS_BMC_EN","SLED6_INA230_ALERT","SLED6_P12V_STBY_ALERT",
+ "SLED6_SSD_ALERT","SLED6_MS_DETECT0","SLED6_RST_CCG5","SLED6_FUSB302_INT",
+ "SLED6_MD_STBY_RESET","SLED6_MD_IOEXP_EN_FAULT","SLED6_MD_DIR","SLED6_MD_DECAY",
+ "SLED6_MD_MODE1","SLED6_MD_MODE2","SLED6_MD_MODE3","power-host6";
};
- sled5_leds: pca9552@67 {
+ sled6_leds: pca9552@67 {
compatible = "nxp,pca9552";
reg = <0x67>;
#address-cells = <1>;
@@ -562,13 +637,13 @@
#gpio-cells = <2>;
gpio-line-names =
- "led-sled5-amber","led-sled5-blue","SLED5_RST_IOEXP","",
+ "led-sled6-amber","led-sled6-blue","SLED6_RST_IOEXP","SLED6_MD_REF_PWM",
"","","","",
"","","","",
"","","","";
};
- sled5_fusb302: typec-portc@22 {
+ sled6_fusb302: typec-portc@22 {
compatible = "fcs,fusb302";
reg = <0x22>;
@@ -596,6 +671,7 @@
};
rtc@51 {
+ /* in-chip rtc disabled, use external rtc (battery-backed) */
compatible = "nxp,pcf85263";
reg = <0x51>;
};
@@ -655,6 +731,7 @@
adm1278@11 {
compatible = "adi,adm1278";
reg = <0x11>;
+ shunt-resistor-micro-ohms = <300>;
};
tmp421@4c {
@@ -667,7 +744,7 @@
reg = <0x4d>;
};
- fan_ioexp: pca9552@67 {
+ fan_leds: pca9552@67 {
compatible = "nxp,pca9552";
reg = <0x67>;
#address-cells = <1>;
@@ -700,36 +777,38 @@
/*D0-D7*/ "","","","","","","","",
/*E0-E7*/ "","","","","","","","",
/*F0-F7*/ "","","","","","","","",
- /*G0-G7*/ "","SWITCH_FRU_MUX","","","","","","",
+ /*G0-G7*/ "BSM_FRU_WP","SWITCH_FRU_MUX","","",
+ "PWRGD_P1V05_VDDCORE","PWRGD_P1V5_VDD","","",
/*H0-H7*/ "presence-riser1","presence-riser2",
- "presence-sled0","presence-sled1",
- "presence-sled2","presence-sled3",
- "presence-sled4","presence-sled5",
+ "presence-sled1","presence-sled2",
+ "presence-sled3","presence-sled4",
+ "presence-sled5","presence-sled6",
/*I0-I7*/ "REV_ID0","","REV_ID1","REV_ID2",
- "","","","",
+ "","BSM_FLASH_WP_STATUS","BMC_TPM_PRES","",
/*J0-J7*/ "","","","","","","","",
/*K0-K7*/ "","","","","","","","",
- /*L0-L7*/ "","","","","","","","",
- /*M0-M7*/ "ALERT_SLED0","ALERT_SLED1",
- "ALERT_SLED2","ALERT_SLED3",
- "ALERT_SLED4","ALERT_SLED5",
+ /*L0-L7*/ "","","","","","BMC_RTC_INT","","",
+ /*M0-M7*/ "ALERT_SLED1","ALERT_SLED2",
+ "ALERT_SLED3","ALERT_SLED4",
+ "ALERT_SLED5","ALERT_SLED6",
"P12V_AUX_ALERT1","",
/*N0-N7*/ "","","","","","","","",
/*O0-O7*/ "","","","",
"","BOARD_ID0","BOARD_ID1","BOARD_ID2",
- /*P0-P7*/ "","","","","","","","",
+ /*P0-P7*/ "","","","","","","","BMC_HEARTBEAT",
/*Q0-Q7*/ "","","","","","","","",
/*R0-R7*/ "","","","","","","","",
/*S0-S7*/ "","","","BAT_DETECT",
"BMC_BT_WP0","BMC_BT_WP1","","",
/*T0-T7*/ "","","","","","","","",
/*U0-U7*/ "","","","","","","","",
- /*V0-V7*/ "","RST_BMC_MVL","","",
+ /*V0-V7*/ "PWRGD_CNS_PSU","RST_BMC_MVL","","PSU_PRSNT",
"USB2_SEL0_A","USB2_SEL1_A",
"USB2_SEL0_B","USB2_SEL1_B",
/*W0-W7*/ "RST_FRONT_IOEXP","","","","","","","",
/*X0-X7*/ "","","","","","","","",
- /*Y0-Y7*/ "","","BSM_FLASH_LATCH","","","","","",
+ /*Y0-Y7*/ "BMC_SELF_HW_RST","BSM_PRSNT","BSM_FLASH_LATCH","",
+ "","","","",
/*Z0-Z7*/ "","","","","","","","";
};
@@ -754,3 +833,8 @@
&pinctrl_adc12_default &pinctrl_adc13_default
&pinctrl_adc14_default &pinctrl_adc15_default>;
};
+
+&mdio3 {
+ status = "okay";
+ /* TODO: Add Marvell 88X3310 */
+};
diff --git a/arch/arm/boot/dts/aspeed-bmc-ibm-everest.dts b/arch/arm/boot/dts/aspeed-bmc-ibm-everest.dts
index 22c06ff7a7ed..578f9e2fc7ed 100644
--- a/arch/arm/boot/dts/aspeed-bmc-ibm-everest.dts
+++ b/arch/arm/boot/dts/aspeed-bmc-ibm-everest.dts
@@ -171,9 +171,10 @@
/* 48MB region from the end of flash to start of vga memory */
ramoops@bc000000 {
compatible = "ramoops";
- reg = <0xbc000000 0x180000>; /* 16 * (3 * 0x8000) */
+ reg = <0xbc000000 0x200000>; /* 16 * (4 * 0x8000) */
record-size = <0x8000>;
console-size = <0x8000>;
+ ftrace-size = <0x8000>;
pmsg-size = <0x8000>;
max-reason = <3>; /* KMSG_DUMP_EMERG */
};
@@ -269,9 +270,7 @@
/*C0-C7*/ "","","","","","","","",
/*D0-D7*/ "","","","","","","","",
/*E0-E7*/ "","","","","","","","",
- /*F0-F7*/ "PIN_HOLE_RESET_IN_N","","",
- "PIN_HOLE_RESET_OUT_N","","",
- "factory-reset-toggle","",
+ /*F0-F7*/ "","","rtc-battery-voltage-read-enable","reset-cause-pinhole","","","factory-reset-toggle","",
/*G0-G7*/ "","","","","","","","",
/*H0-H7*/ "led-rtc-battery","led-bmc","led-rear-enc-id0","led-rear-enc-fault0","","","","",
/*I0-I7*/ "","","","","","","bmc-secure-boot","",
@@ -2394,6 +2393,10 @@
status = "okay";
};
+&uhci {
+ status = "okay";
+};
+
&emmc_controller {
status = "okay";
};
diff --git a/arch/arm/boot/dts/aspeed-bmc-ibm-rainier.dts b/arch/arm/boot/dts/aspeed-bmc-ibm-rainier.dts
index c47974219832..528b49e2c0f8 100644
--- a/arch/arm/boot/dts/aspeed-bmc-ibm-rainier.dts
+++ b/arch/arm/boot/dts/aspeed-bmc-ibm-rainier.dts
@@ -102,9 +102,10 @@
ramoops@bc000000 {
compatible = "ramoops";
- reg = <0xbc000000 0x180000>; /* 16 * (3 * 0x8000) */
+ reg = <0xbc000000 0x200000>; /* 16 * (4 * 0x8000) */
record-size = <0x8000>;
console-size = <0x8000>;
+ ftrace-size = <0x8000>;
pmsg-size = <0x8000>;
max-reason = <3>; /* KMSG_DUMP_EMERG */
};
@@ -239,6 +240,10 @@
status = "okay";
};
+&uhci {
+ status = "okay";
+};
+
&gpio0 {
gpio-line-names =
/*A0-A7*/ "","","","","","","","",
@@ -246,7 +251,7 @@
/*C0-C7*/ "","","","","","","","",
/*D0-D7*/ "","","","","","","","",
/*E0-E7*/ "","","","","","","","",
- /*F0-F7*/ "","","","","","","factory-reset-toggle","",
+ /*F0-F7*/ "","","rtc-battery-voltage-read-enable","reset-cause-pinhole","","","factory-reset-toggle","",
/*G0-G7*/ "","","","","","","","",
/*H0-H7*/ "","bmc-ingraham0","rear-enc-id0","rear-enc-fault0","","","","",
/*I0-I7*/ "","","","","","","bmc-secure-boot","",
@@ -2360,30 +2365,6 @@
use-ncsi;
};
-&fmc {
- status = "okay";
- flash@0 {
- status = "okay";
- m25p,fast-read;
- label = "bmc";
- spi-max-frequency = <50000000>;
-#include "openbmc-flash-layout-128.dtsi"
- };
-};
-
-&spi1 {
- status = "okay";
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_spi1_default>;
-
- flash@0 {
- status = "okay";
- m25p,fast-read;
- label = "pnor";
- spi-max-frequency = <100000000>;
- };
-};
-
&wdt1 {
aspeed,reset-type = "none";
aspeed,external-signal;
diff --git a/arch/arm/boot/dts/aspeed-bmc-opp-tacoma.dts b/arch/arm/boot/dts/aspeed-bmc-opp-tacoma.dts
index e39f310d55eb..72b7a6639ed9 100644
--- a/arch/arm/boot/dts/aspeed-bmc-opp-tacoma.dts
+++ b/arch/arm/boot/dts/aspeed-bmc-opp-tacoma.dts
@@ -197,7 +197,6 @@
fsi-routing-gpios = <&gpio0 ASPEED_GPIO(Q, 7) GPIO_ACTIVE_HIGH>;
fsi-mux-gpios = <&gpio0 ASPEED_GPIO(B, 0) GPIO_ACTIVE_HIGH>;
- cfam-reset-gpios = <&gpio0 ASPEED_GPIO(Q, 0) GPIO_ACTIVE_LOW>;
cfam@0,0 {
reg = <0 0>;
@@ -877,3 +876,14 @@
status = "okay";
memory-region = <&vga_memory>;
};
+
+&kcs2 {
+ status = "okay";
+ aspeed,lpc-io-reg = <0xca8 0xcac>;
+};
+
+&kcs3 {
+ status = "okay";
+ aspeed,lpc-io-reg = <0xca2>;
+ aspeed,lpc-interrupts = <11 IRQ_TYPE_LEVEL_LOW>;
+};
diff --git a/arch/arm/boot/dts/aspeed-bmc-quanta-s6q.dts b/arch/arm/boot/dts/aspeed-bmc-quanta-s6q.dts
new file mode 100644
index 000000000000..69e1bd256271
--- /dev/null
+++ b/arch/arm/boot/dts/aspeed-bmc-quanta-s6q.dts
@@ -0,0 +1,610 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+// Copyright 2022 Quanta Corp.
+/dts-v1/;
+
+#include "aspeed-g6.dtsi"
+#include <dt-bindings/gpio/aspeed-gpio.h>
+#include <dt-bindings/i2c/i2c.h>
+
+/ {
+ model = "Quanta S6Q BMC";
+ compatible = "quanta,s6q-bmc", "aspeed,ast2600";
+
+ aliases {
+ // bus 0
+ i2c20 = &SMB_HOST_DB2000_3V3AUX_SCL;
+ i2c21 = &U12_PCA9546_CH1;
+ i2c22 = &SMB_HOST_DB800_B_SCL;
+ i2c23 = &SMB_HOST_DB800_C_SCL;
+
+ // bus 1
+ i2c24 = &SMB_M2_P0_1V8AUX_SCL;
+ i2c25 = &SMB_M2_P1_1V8AUX_SCL;
+ i2c26 = &SMB_CPU_PIROM_3V3AUX_SCL;
+ i2c27 = &SMB_TEMP_3V3AUX_SCL;
+ i2c28 = &SMB_IPMB_3V3AUX_SSDSB_SCL;
+ i2c29 = &SMB_IPMB_3V3AUX_SCL;
+ i2c31 = &SMB_FB_SCL;
+
+ // bus 1 - Fan board
+ i2c32 = &SMB_IOEXP_SCL;
+ i2c33 = &SMB_PROGRAM_SCL;
+ i2c34 = &SMB_FB_SCL_CH2;
+ i2c35 = &SMB_FAN_SENSE_SCL;
+
+ // bus 6
+ i2c36 = &U197_PCA9546_CH0;
+ i2c37 = &U197_PCA9546_CH1;
+ i2c38 = &U197_PCA9546_CH2;
+ i2c39 = &U197_PCA9546_CH3;
+
+ //bus 7
+ i2c40 = &SMB_OCP_SFF_3V3AUX_SCL; //OCP1
+ i2c41 = &SMB_OCP_LFF_3V3AUX_SCL; //OCP2
+ };
+
+ chosen {
+ stdout-path = &uart5;
+ bootargs = "console=ttyS4,115200n8 earlycon";
+ };
+
+ memory@80000000 {
+ device_type = "memory";
+ reg = <0x80000000 0x40000000>;
+ };
+
+ iio-hwmon {
+ compatible = "iio-hwmon";
+ io-channels = <&adc0 0>, <&adc0 1>, <&adc0 2>, <&adc0 3>,
+ <&adc0 4>, <&adc0 5>, <&adc0 6>, <&adc0 7>,
+ <&adc1 0>, <&adc1 1>, <&adc1 2>, <&adc1 3>,
+ <&adc1 4>, <&adc1 5>, <&adc1 6>, <&adc1 7>;
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ BMC_HEARTBEAT_N {
+ label="BMC_HEARTBEAT_N";
+ gpios = <&gpio0 ASPEED_GPIO(P, 7) GPIO_ACTIVE_LOW>;
+ linux,default-trigger = "heartbeat";
+ };
+
+ BMC_LED_STATUS_AMBER_N {
+ label="BMC_LED_STATUS_AMBER_N";
+ gpios = <&gpio0 ASPEED_GPIO(S, 6) GPIO_ACTIVE_LOW>;
+ default-state = "off";
+ };
+
+ FM_ID_LED_N {
+ label="FM_ID_LED_N";
+ gpios = <&gpio0 ASPEED_GPIO(B, 5) GPIO_ACTIVE_LOW>;
+ default-state = "off";
+ };
+ };
+};
+
+&gpio0 {
+ gpio-line-names =
+ /*A0 - A7*/ "", "", "", "", "", "", "", "",
+ /*B0 - B7*/ "", "", "", "", "", "", "", "",
+ /*C0 - C7*/ "", "", "", "", "", "", "", "",
+ /*D0 - D7*/ "", "", "", "", "", "", "", "",
+ /*E0 - E7*/ "", "", "", "", "", "", "", "",
+ /*F0 - F7*/ "PLTRST_N", "", "PWR_DEBUG_N", "", "", "", "", "",
+ /*G0 - G7*/ "", "", "", "", "", "", "", "",
+ /*H0 - H7*/ "", "", "", "", "", "", "", "",
+ /*I0 - I7*/ "", "", "", "", "", "", "", "",
+ /*J0 - J7*/ "", "", "", "", "", "", "", "",
+ /*K0 - K7*/ "", "", "", "", "", "", "", "",
+ /*L0 - L7*/ "", "", "", "", "PREQ_N", "TCK_MUX_SEL", "", "",
+ /*M0 - M7*/ "", "", "", "PWRGD_SYS_PWROK", "", "PRDY_N", "", "",
+ /*N0 - N7*/ "", "", "", "", "", "", "", "",
+ /*O0 - O7*/ "", "", "", "", "", "", "", "",
+ /*P0 - P7*/ "SYS_BMC_PWRBTN_R_N", "SYS_PWRBTN_N", "FM_MB_RST_BTN", "RST_BMC_RSTBTN_OUT_N", "", "", "", "",
+ /*Q0 - Q7*/ "", "", "", "", "", "", "", "",
+ /*R0 - R7*/ "", "", "", "", "", "", "", "",
+ /*S0 - S7*/ "", "", "", "FP_ID_BTN_SCM_N", "", "", "", "",
+ /*T0 - T7*/ "", "", "", "", "", "", "", "",
+ /*U0 - U7*/ "", "", "", "", "", "", "", "",
+ /*V0 - V7*/ "", "", "", "", "", "SMI", "", "",
+ /*W0 - W7*/ "", "", "", "", "", "", "", "",
+ /*X0 - X7*/ "", "", "", "", "", "", "", "",
+ /*Y0 - Y7*/ "", "", "", "", "", "", "", "",
+ /*Z0 - Z7*/ "FM_BMC_READY_N", "", "", "", "", "", "", "",
+ /*AA0 - AA7*/ "", "", "", "", "", "", "", "",
+ /*AB0 - AB7*/ "", "", "", "", "", "", "", "",
+ /*AC0 - AC7*/ "", "", "", "", "", "", "", "";
+};
+
+&sgpiom0 {
+ status = "okay";
+ ngpios = <128>;
+ bus-frequency = <48000>;
+ gpio-line-names =
+ /* SGPIO input lines */
+ /*IOA0-IOA7*/ "","", "SIO_POWER_GOOD","OA1", "XDP_PRST_N","", "","", "FM_SLPS3_PLD_N","", "FM_SLPS4_PLD_N","", "FM_BIOS_POST_CMPLT_BMC_N","", "FM_ADR_TRIGGER_N","OA7",
+ /*IOB0-IOB7*/ "FM_ADR_COMPLETE","", "FM_PMBUS_ALERT_B_EN","", "PSU0_PRESENT_N","", "PSU1_PRESENT_N","", "PSU0_VIN_BUF_GOOD","", "PSU01_VIN_BUF_GOOD","", "PWRGD_PS0_PWROK_R","", "PWRGD_PS1_PWROK_R","",
+ /*IOC0-IOC7*/ "PWRGD_PS_PWROK_PLD_R","", "CHASSIS_INTRUSION","", "BMC_MFG_MODE","", "FM_BMC_EN_DET_R","", "FM_ME_BT_DONE","", "CPU1_PRESENCE","", "CPU2_PRESENCE","", "IRQ_PSYS_CRIT_N","",
+ /*IOD0-IOD7*/ "","", "CPU1_THERMTRIP","", "CPU2_THERMTRIP","", "CPU1_MEM_THERM_EVENT","", "CPU2_MEM_THERM_EVENT","", "CPU1_VRHOT","", "CPU2_VRHOT","", "","",
+ /*IOE0-IOE7*/ "","", "CPU1_MEM_VRHOT","", "CPU2_MEM_VRHOT","", "","", "PCH_BMC_THERMTRIP","", "","", "","", "","",
+ /*IOF0-IOF7*/ "CPU_ERR0","", "CPU_ERR1","", "CPU_ERR2","", "","", "","", "CPU_CATERR","", "","", "","",
+ /*IOG0-IOG7*/ "","", "","", "","", "","", "","", "","", "","", "","",
+ /*IOH0-IOH7*/ "","", "FP_ID_BTN_R1_N","", "FP_RST_BTN_N","", "","", "","", "FP_PWR_BTN_PLD_N_R","", "","", "","",
+ /*IOI0-IOI7*/ "","", "","", "","", "","", "","", "","", "","", "","",
+ /*IOJ0-IOJ7*/ "","", "","", "","", "","", "","", "","", "","", "","",
+ /*IOK0-IOK7*/ "","", "","", "","", "","", "","", "","", "","", "","",
+ /*IOL0-IOL7*/ "","", "","", "","", "","", "","", "","", "","", "","",
+ /*IOM0-IOM7*/ "","", "","", "","", "","", "","", "","", "","", "","",
+ /*ION0-ION7*/ "","BMC_SW_HEARTBEAT_N_R", "","FP_LED_FAULT_N", "","FP_ID_LED_N", "","FM_BMC_RSTBTN_OUT_N", "","FM_THERMTRIP_DLY_LVC1_R_N", "","", "","RST_PCA9548_SENSOR_PLD_N", "","USB_OC1_REAR_N",
+ /*IOO0-IOO7*/ "","IRQ_TPM_SPI_N", "","", "","IRQ_PCH_SCI_WHEA_R_N", "","IRQ_BMC_PCH_NMI_R", "","H_CPU_NMI_LVC1_R_N", "","", "","", "","FM_JTAG_BMC_PLD_MUX_SEL",
+ /*IOP0-IOP7*/ "IP0","OP0", "","", "","", "","", "","", "","", "","", "IP7","OP7";
+};
+
+&adc0 {
+ vref = <2500>;
+ status = "okay";
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_adc0_default &pinctrl_adc1_default
+ &pinctrl_adc2_default &pinctrl_adc3_default
+ &pinctrl_adc4_default &pinctrl_adc5_default
+ &pinctrl_adc6_default &pinctrl_adc7_default>;
+};
+
+&adc1 {
+ vref = <2500>;
+ status = "okay";
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_adc8_default &pinctrl_adc9_default
+ &pinctrl_adc10_default &pinctrl_adc11_default
+ &pinctrl_adc12_default &pinctrl_adc13_default
+ &pinctrl_adc14_default &pinctrl_adc15_default>;
+};
+
+&mdio2 {
+ status = "okay";
+
+ ethphy2: ethernet-phy@0 {
+ compatible = "ethernet-phy-ieee802.3-c22";
+ reg = <0>;
+ };
+};
+
+&mac2 {
+ status = "okay";
+
+ phy-mode = "rgmii";
+ phy-handle = <&ethphy2>;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_rgmii3_default>;
+};
+
+&mac3 {
+ status = "okay";
+
+ phy-mode = "rmii";
+ use-ncsi;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_rmii4_default>;
+};
+
+&fmc {
+ status = "okay";
+
+ flash@0 {
+ status = "okay";
+ m25p,fast-read;
+ label = "bmc";
+ spi-max-frequency = <50000000>;
+#include "openbmc-flash-layout-64.dtsi"
+ };
+};
+
+&spi2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_spi2_default &pinctrl_spi2cs1_default
+ &pinctrl_spi2cs2_default>;
+ status = "okay";
+
+ flash@0 {
+ status = "okay";
+ m25p,fast-read;
+ label = "spi2:0";
+ spi-max-frequency = <50000000>;
+ };
+};
+
+&kcs1 {
+ status = "okay";
+ aspeed,lpc-io-reg = <0xCA0>;
+};
+
+&kcs2 {
+ status = "okay";
+ aspeed,lpc-io-reg = <0xCA8>;
+};
+
+&kcs3 {
+ status = "okay";
+ aspeed,lpc-io-reg = <0xCA2>;
+};
+
+&emmc_controller {
+ status = "okay";
+};
+
+&emmc {
+ non-removable;
+ bus-width = <4>;
+ max-frequency = <100000000>;
+};
+
+&vhub {
+ status = "okay";
+};
+
+&lpc_snoop {
+ status = "okay";
+ snoop-ports = <0x80>;
+};
+
+&uart1 {
+ status = "okay";
+};
+
+&uart2 {
+ status = "okay";
+};
+
+&uart4 {
+ status = "okay";
+};
+
+&uart5 {
+ status = "okay";
+};
+
+&uart_routing {
+ status = "okay";
+};
+
+&i2c0 {
+ status = "okay";
+
+ U34_PWR_ADC@48 {
+ compatible = "ti,ads7830";
+ reg = <0x48>;
+ };
+
+ U35_PWR_ADC@4b {
+ compatible = "ti,ads7830";
+ reg = <0x4b>;
+ };
+
+ i2c-switch@70 {
+ compatible = "nxp,pca9546";
+ reg = <0x70>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ i2c-mux-idle-disconnect;
+
+ SMB_HOST_DB2000_3V3AUX_SCL: i2c@0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0>;
+ };
+
+ U12_PCA9546_CH1: i2c@1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <1>;
+ };
+
+ SMB_HOST_DB800_B_SCL: i2c@2 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <2>;
+ };
+
+ SMB_HOST_DB800_C_SCL: i2c@3 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <3>;
+ };
+ };
+};
+
+&i2c1 {
+ status = "okay";
+
+ i2c-switch@59 {
+ compatible = "nxp,pca9848";
+ reg = <0x59>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ i2c-mux-idle-disconnect;
+
+ SMB_M2_P0_1V8AUX_SCL: i2c@0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0>;
+ };
+
+ SMB_M2_P1_1V8AUX_SCL: i2c@1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <1>;
+ };
+
+ SMB_CPU_PIROM_3V3AUX_SCL: i2c@2 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <2>;
+ };
+
+ SMB_TEMP_3V3AUX_SCL: i2c@3 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <3>;
+
+ U163_tmp75@48 {
+ compatible = "ti,tmp75";
+ reg = <0x48>;
+ };
+ U114_tmp75@49 {
+ compatible = "ti,tmp75";
+ reg = <0x49>;
+ };
+ };
+
+ SMB_IPMB_3V3AUX_SSDSB_SCL: i2c@4 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <4>;
+
+ U4_tmp75@4c {
+ compatible = "ti,tmp75";
+ reg = <0x4c>;
+ };
+ U73_tmp75@4d {
+ compatible = "ti,tmp75";
+ reg = <0x4d>;
+ };
+ };
+
+ SMB_IPMB_3V3AUX_SCL: i2c@5 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <5>;
+
+ U190_fru@51 {
+ compatible = "atmel,24c128";
+ reg = <0x51>;
+ pagesize = <32>;
+ };
+ };
+
+ SMB_FB_SCL: i2c@7 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <7>;
+
+ i2c-switch@77 {
+ compatible = "nxp,pca9546";
+ reg = <0x77>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ i2c-mux-idle-disconnect;
+
+ SMB_IOEXP_SCL: i2c@0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0>;
+ };
+
+ SMB_PROGRAM_SCL: i2c@1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <1>;
+ };
+
+ SMB_FB_SCL_CH2: i2c@2 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <2>;
+ };
+
+ SMB_FAN_SENSE_SCL: i2c@3 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <3>;
+
+ Current_Meter_U2@45 {
+ compatible = "ti,ina219";
+ reg = <0x45>;
+ shunt-resistor = <1000>; /* = 1 mOhm */
+ };
+
+ Current_Meter_U3@44 {
+ compatible = "ti,ina219";
+ reg = <0x44>;
+ shunt-resistor = <1000>; /* = 1 mOhm */
+ };
+
+ TEMP_sensor_U2@4b {
+ compatible = "ti,tmp75";
+ reg = <0x4b>;
+ };
+ };
+ };
+ };
+ };
+};
+
+&i2c2 {
+ status = "okay";
+ bus-frequency = <400000>;
+
+ ipmb@10 {
+ compatible = "ipmb-dev";
+ reg = <(0x10 | I2C_OWN_SLAVE_ADDRESS)>;
+ i2c-protocol;
+ };
+};
+
+&i2c3 {
+ status = "okay";
+
+ /* MB FRU (U173) @ 0xA2 */
+ mb_fru: mb_fru@51 {
+ compatible = "atmel,24c128";
+ reg = <0x51>;
+ pagesize = <32>;
+ };
+
+ /* FP_U1 Inlet */
+ FP_U1_tmp75@4a {
+ compatible = "ti,tmp75";
+ reg = <0x4a>;
+ };
+
+ FP_U4_fru@52 {
+ compatible = "atmel,24c02";
+ reg = <0x52>;
+ pagesize = <16>;
+ };
+};
+
+&i2c4 {
+ status = "okay";
+};
+
+&i2c5 {
+ status = "okay";
+};
+
+&i2c6 {
+ status = "okay";
+
+ i2c-switch@77 {
+ compatible = "nxp,pca9548";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x77>;
+ i2c-mux-idle-disconnect;
+
+ U197_PCA9546_CH0: i2c@0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0>;
+ };
+
+ U197_PCA9546_CH1: i2c@1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <1>;
+
+ cpu0_pvccin@60 {
+ compatible = "isil,raa229004";
+ reg = <0x60>;
+ };
+
+ cpu0_pvccinfaon@61 {
+ compatible = "isil,isl69260";
+ reg = <0x61>;
+ };
+
+ cpu0_pvccd_hv@63 {
+ compatible = "isil,isl69260";
+ reg = <0x63>;
+ };
+ };
+
+ U197_PCA9546_CH2: i2c@2 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <2>;
+
+ cpu1_pvccin@72 {
+ compatible = "isil,raa229004";
+ reg = <0x72>;
+ };
+
+ cpu1_pvccinfaon@74 {
+ compatible = "isil,isl69260";
+ reg = <0x74>;
+ };
+
+ cpu1_pvccd_hv@76 {
+ compatible = "isil,isl69260";
+ reg = <0x76>;
+ };
+ };
+
+ U197_PCA9546_CH3: i2c@3 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <3>;
+ };
+ };
+};
+
+&i2c7 {
+ status = "okay";
+
+ i2c-switch@75 {
+ compatible = "nxp,pca9546";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x75>;
+ i2c-mux-idle-disconnect;
+
+ SMB_OCP_SFF_3V3AUX_SCL: i2c@0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0>;
+ };
+
+ SMB_OCP_LFF_3V3AUX_SCL: i2c@1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <1>;
+ };
+ };
+};
+
+&i2c8 {
+ status = "okay";
+};
+
+&i2c9 {
+ status = "okay";
+};
+
+&i2c11 {
+ status = "okay";
+};
+
+&i2c14 {
+ status = "okay";
+
+ /* SCM FRU (U19) @ 0xA2 */
+ scm_fru: scm_fru@51 {
+ compatible = "atmel,24c128";
+ reg = <0x51>;
+ pagesize = <32>;
+ };
+
+ scm_tmp75_u4@4a {
+ compatible = "ti,tmp75";
+ reg = <0x4a>;
+ };
+};
+
+&i2c15 {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/aspeed-g6-pinctrl.dtsi b/arch/arm/boot/dts/aspeed-g6-pinctrl.dtsi
index 6dde51c2aed3..e4775bbceecc 100644
--- a/arch/arm/boot/dts/aspeed-g6-pinctrl.dtsi
+++ b/arch/arm/boot/dts/aspeed-g6-pinctrl.dtsi
@@ -118,7 +118,7 @@
};
pinctrl_fwqspid_default: fwqspid_default {
- function = "FWQSPID";
+ function = "FWSPID";
groups = "FWQSPID";
};
diff --git a/arch/arm/boot/dts/at91-sam9x60ek.dts b/arch/arm/boot/dts/at91-sam9x60ek.dts
index b1068cca4228..7719ea3d4933 100644
--- a/arch/arm/boot/dts/at91-sam9x60ek.dts
+++ b/arch/arm/boot/dts/at91-sam9x60ek.dts
@@ -48,11 +48,11 @@
status = "okay";
};
- vdd_1v5: fixed-regulator-vdd_1v5@1 {
+ vdd_1v15: fixed-regulator-vdd_1v15@1 {
compatible = "regulator-fixed";
- regulator-name = "VDD_1V5";
- regulator-min-microvolt = <1500000>;
- regulator-max-microvolt = <1500000>;
+ regulator-name = "VDD_1V15";
+ regulator-min-microvolt = <1150000>;
+ regulator-max-microvolt = <1150000>;
regulator-always-on;
status = "okay";
};
diff --git a/arch/arm/boot/dts/at91-sama7g5ek.dts b/arch/arm/boot/dts/at91-sama7g5ek.dts
index ccf9e224da78..08685a10eda1 100644
--- a/arch/arm/boot/dts/at91-sama7g5ek.dts
+++ b/arch/arm/boot/dts/at91-sama7g5ek.dts
@@ -131,6 +131,18 @@
status = "okay";
};
+&can0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_can0_default>;
+ status = "okay";
+};
+
+&can1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_can1_default>;
+ status = "okay";
+};
+
&cpu0 {
cpu-supply = <&vddcpu>;
};
@@ -239,6 +251,7 @@
regulator-state-standby {
regulator-on-in-suspend;
+ regulator-suspend-microvolt = <3300000>;
regulator-mode = <4>;
};
@@ -279,6 +292,7 @@
regulator-state-standby {
regulator-on-in-suspend;
+ regulator-suspend-voltage = <1150000>;
regulator-mode = <4>;
};
@@ -290,7 +304,7 @@
vddcpu: VDD_OTHER {
regulator-name = "VDD_OTHER";
- regulator-min-microvolt = <1125000>;
+ regulator-min-microvolt = <1050000>;
regulator-max-microvolt = <1850000>;
regulator-initial-mode = <2>;
regulator-allowed-modes = <2>, <4>;
@@ -299,6 +313,7 @@
regulator-state-standby {
regulator-on-in-suspend;
+ regulator-suspend-voltage = <1050000>;
regulator-mode = <4>;
};
@@ -315,6 +330,7 @@
regulator-always-on;
regulator-state-standby {
+ regulator-suspend-voltage = <1800000>;
regulator-on-in-suspend;
};
@@ -329,6 +345,7 @@
regulator-max-microvolt = <3700000>;
regulator-state-standby {
+ regulator-suspend-voltage = <1800000>;
regulator-on-in-suspend;
};
@@ -454,6 +471,19 @@
};
&pioA {
+
+ pinctrl_can0_default: can0_default {
+ pinmux = <PIN_PD12__CANTX0>,
+ <PIN_PD13__CANRX0 >;
+ bias-disable;
+ };
+
+ pinctrl_can1_default: can1_default {
+ pinmux = <PIN_PD14__CANTX1>,
+ <PIN_PD15__CANRX1 >;
+ bias-disable;
+ };
+
pinctrl_flx0_default: flx0_default {
pinmux = <PIN_PE3__FLEXCOM0_IO0>,
<PIN_PE4__FLEXCOM0_IO1>,
diff --git a/arch/arm/boot/dts/bcm2711.dtsi b/arch/arm/boot/dts/bcm2711.dtsi
index dff18fc9a906..89af57482bc8 100644
--- a/arch/arm/boot/dts/bcm2711.dtsi
+++ b/arch/arm/boot/dts/bcm2711.dtsi
@@ -290,6 +290,7 @@
hvs: hvs@7e400000 {
compatible = "brcm,bcm2711-hvs";
+ reg = <0x7e400000 0x8000>;
interrupts = <GIC_SPI 97 IRQ_TYPE_LEVEL_HIGH>;
};
@@ -458,12 +459,26 @@
#size-cells = <0>;
enable-method = "brcm,bcm2836-smp"; // for ARM 32-bit
+ /* Source for d/i-cache-line-size and d/i-cache-sets
+ * https://developer.arm.com/documentation/100095/0003
+ * /Level-1-Memory-System/About-the-L1-memory-system?lang=en
+ * Source for d/i-cache-size
+ * https://www.raspberrypi.com/documentation/computers
+ * /processors.html#bcm2711
+ */
cpu0: cpu@0 {
device_type = "cpu";
compatible = "arm,cortex-a72";
reg = <0>;
enable-method = "spin-table";
cpu-release-addr = <0x0 0x000000d8>;
+ d-cache-size = <0x8000>;
+ d-cache-line-size = <64>;
+ d-cache-sets = <256>; // 32KiB(size)/64(line-size)=512ways/2-way set
+ i-cache-size = <0xc000>;
+ i-cache-line-size = <64>;
+ i-cache-sets = <256>; // 48KiB(size)/64(line-size)=768ways/3-way set
+ next-level-cache = <&l2>;
};
cpu1: cpu@1 {
@@ -472,6 +487,13 @@
reg = <1>;
enable-method = "spin-table";
cpu-release-addr = <0x0 0x000000e0>;
+ d-cache-size = <0x8000>;
+ d-cache-line-size = <64>;
+ d-cache-sets = <256>; // 32KiB(size)/64(line-size)=512ways/2-way set
+ i-cache-size = <0xc000>;
+ i-cache-line-size = <64>;
+ i-cache-sets = <256>; // 48KiB(size)/64(line-size)=768ways/3-way set
+ next-level-cache = <&l2>;
};
cpu2: cpu@2 {
@@ -480,6 +502,13 @@
reg = <2>;
enable-method = "spin-table";
cpu-release-addr = <0x0 0x000000e8>;
+ d-cache-size = <0x8000>;
+ d-cache-line-size = <64>;
+ d-cache-sets = <256>; // 32KiB(size)/64(line-size)=512ways/2-way set
+ i-cache-size = <0xc000>;
+ i-cache-line-size = <64>;
+ i-cache-sets = <256>; // 48KiB(size)/64(line-size)=768ways/3-way set
+ next-level-cache = <&l2>;
};
cpu3: cpu@3 {
@@ -488,6 +517,28 @@
reg = <3>;
enable-method = "spin-table";
cpu-release-addr = <0x0 0x000000f0>;
+ d-cache-size = <0x8000>;
+ d-cache-line-size = <64>;
+ d-cache-sets = <256>; // 32KiB(size)/64(line-size)=512ways/2-way set
+ i-cache-size = <0xc000>;
+ i-cache-line-size = <64>;
+ i-cache-sets = <256>; // 48KiB(size)/64(line-size)=768ways/3-way set
+ next-level-cache = <&l2>;
+ };
+
+ /* Source for d/i-cache-line-size and d/i-cache-sets
+ * https://developer.arm.com/documentation/100095/0003
+ * /Level-2-Memory-System/About-the-L2-memory-system?lang=en
+ * Source for d/i-cache-size
+ * https://www.raspberrypi.com/documentation/computers
+ * /processors.html#bcm2711
+ */
+ l2: l2-cache0 {
+ compatible = "cache";
+ cache-size = <0x100000>;
+ cache-line-size = <64>;
+ cache-sets = <1024>; // 1MiB(size)/64(line-size)=16384ways/16-way set
+ cache-level = <2>;
};
};
diff --git a/arch/arm/boot/dts/bcm2835.dtsi b/arch/arm/boot/dts/bcm2835.dtsi
index 0549686134ea..1c90e5a44283 100644
--- a/arch/arm/boot/dts/bcm2835.dtsi
+++ b/arch/arm/boot/dts/bcm2835.dtsi
@@ -14,6 +14,23 @@
device_type = "cpu";
compatible = "arm,arm1176jzf-s";
reg = <0x0>;
+ /* Source for d/i-cache-line-size and d/i-cache-sets
+ * https://developer.arm.com/documentation/ddi0301
+ * /h/level-one-memory-system/cache-organization?lang=en
+ *
+ * Source for d/i-cache-size
+ * https://forums.raspberrypi.com/viewtopic.php?t=98428
+ *
+ * NOTE: The BCM2835 has a L2 cache but it is dedicated to the GPU
+ * It can be shared with the CPU through fw settings,
+ * but this is not recommended.
+ */
+ d-cache-size = <0x4000>;
+ d-cache-line-size = <16>;
+ d-cache-sets = <256>; // 16KiB(size)/16(line-size)=1024ways/4-way set
+ i-cache-size = <0x4000>;
+ i-cache-line-size = <16>;
+ i-cache-sets = <256>; // 16KiB(size)/16(line-size)=1024ways/4-way set
};
};
diff --git a/arch/arm/boot/dts/bcm2836.dtsi b/arch/arm/boot/dts/bcm2836.dtsi
index b390006aef79..534dacfc4dd5 100644
--- a/arch/arm/boot/dts/bcm2836.dtsi
+++ b/arch/arm/boot/dts/bcm2836.dtsi
@@ -41,11 +41,26 @@
#size-cells = <0>;
enable-method = "brcm,bcm2836-smp";
+ /* Source for d/i-cache-line-size and d/i-cache-sets
+ * https://developer.arm.com/documentation/ddi0464/f/L1-Memory-System
+ * /About-the-L1-memory-system?lang=en
+ *
+ * Source for d/i-cache-size
+ * https://forums.raspberrypi.com/viewtopic.php?t=98428
+ */
+
v7_cpu0: cpu@0 {
device_type = "cpu";
compatible = "arm,cortex-a7";
reg = <0xf00>;
clock-frequency = <800000000>;
+ d-cache-size = <0x8000>;
+ d-cache-line-size = <64>;
+ d-cache-sets = <128>; // 32KiB(size)/64(line-size)=512ways/4-way set
+ i-cache-size = <0x8000>;
+ i-cache-line-size = <32>;
+ i-cache-sets = <512>; // 32KiB(size)/32(line-size)=1024ways/2-way set
+ next-level-cache = <&l2>;
};
v7_cpu1: cpu@1 {
@@ -53,6 +68,13 @@
compatible = "arm,cortex-a7";
reg = <0xf01>;
clock-frequency = <800000000>;
+ d-cache-size = <0x8000>;
+ d-cache-line-size = <64>;
+ d-cache-sets = <128>; // 32KiB(size)/64(line-size)=512ways/4-way set
+ i-cache-size = <0x8000>;
+ i-cache-line-size = <32>;
+ i-cache-sets = <512>; // 32KiB(size)/32(line-size)=1024ways/2-way set
+ next-level-cache = <&l2>;
};
v7_cpu2: cpu@2 {
@@ -60,6 +82,13 @@
compatible = "arm,cortex-a7";
reg = <0xf02>;
clock-frequency = <800000000>;
+ d-cache-size = <0x8000>;
+ d-cache-line-size = <64>;
+ d-cache-sets = <128>; // 32KiB(size)/64(line-size)=512ways/4-way set
+ i-cache-size = <0x8000>;
+ i-cache-line-size = <32>;
+ i-cache-sets = <512>; // 32KiB(size)/32(line-size)=1024ways/2-way set
+ next-level-cache = <&l2>;
};
v7_cpu3: cpu@3 {
@@ -67,6 +96,27 @@
compatible = "arm,cortex-a7";
reg = <0xf03>;
clock-frequency = <800000000>;
+ d-cache-size = <0x8000>;
+ d-cache-line-size = <64>;
+ d-cache-sets = <128>; // 32KiB(size)/64(line-size)=512ways/4-way set
+ i-cache-size = <0x8000>;
+ i-cache-line-size = <32>;
+ i-cache-sets = <512>; // 32KiB(size)/32(line-size)=1024ways/2-way set
+ next-level-cache = <&l2>;
+ };
+
+ /* Source for cache-line-size + cache-sets
+ * https://developer.arm.com/documentation/ddi0464/f/L2-Memory-System
+ * /About-the-L2-Memory-system?lang=en
+ * Source for cache-size
+ * https://forums.raspberrypi.com/viewtopic.php?t=98428
+ */
+ l2: l2-cache0 {
+ compatible = "cache";
+ cache-size = <0x80000>;
+ cache-line-size = <64>;
+ cache-sets = <1024>; // 512KiB(size)/64(line-size)=8192ways/8-way set
+ cache-level = <2>;
};
};
};
diff --git a/arch/arm/boot/dts/bcm2837-rpi-zero-2-w.dts b/arch/arm/boot/dts/bcm2837-rpi-zero-2-w.dts
new file mode 100644
index 000000000000..4a768562985e
--- /dev/null
+++ b/arch/arm/boot/dts/bcm2837-rpi-zero-2-w.dts
@@ -0,0 +1,136 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2022 Stefan Wahren <stefan.wahren@i2se.com>
+ */
+
+/dts-v1/;
+#include "bcm2837.dtsi"
+#include "bcm2836-rpi.dtsi"
+#include "bcm283x-rpi-usb-otg.dtsi"
+#include "bcm283x-rpi-wifi-bt.dtsi"
+
+/ {
+ compatible = "raspberrypi,model-zero-2-w", "brcm,bcm2837";
+ model = "Raspberry Pi Zero 2 W";
+
+ memory@0 {
+ device_type = "memory";
+ reg = <0 0x20000000>;
+ };
+
+ chosen {
+ /* 8250 auxiliary UART instead of pl011 */
+ stdout-path = "serial1:115200n8";
+ };
+
+ leds {
+ led-act {
+ gpios = <&gpio 29 GPIO_ACTIVE_LOW>;
+ };
+ };
+};
+
+&bt {
+ shutdown-gpios = <&gpio 42 GPIO_ACTIVE_HIGH>;
+};
+
+&gpio {
+ /*
+ * This is based on the official GPU firmware DT blob.
+ *
+ * Legend:
+ * "NC" = not connected (no rail from the SoC)
+ * "FOO" = GPIO line named "FOO" on the schematic
+ * "FOO_N" = GPIO line named "FOO" on schematic, active low
+ */
+ gpio-line-names = "ID_SDA",
+ "ID_SCL",
+ "SDA1",
+ "SCL1",
+ "GPIO_GCLK",
+ "GPIO5",
+ "GPIO6",
+ "SPI_CE1_N",
+ "SPI_CE0_N",
+ "SPI_MISO",
+ "SPI_MOSI",
+ "SPI_SCLK",
+ "GPIO12",
+ "GPIO13",
+ /* Serial port */
+ "TXD0",
+ "RXD0",
+ "GPIO16",
+ "GPIO17",
+ "GPIO18",
+ "GPIO19",
+ "GPIO20",
+ "GPIO21",
+ "GPIO22",
+ "GPIO23",
+ "GPIO24",
+ "GPIO25",
+ "GPIO26",
+ "GPIO27",
+ "HDMI_HPD_N",
+ "STATUS_LED_N",
+ "NC", /* GPIO30 */
+ "NC", /* GPIO31 */
+ "NC", /* GPIO32 */
+ "NC", /* GPIO33 */
+ "NC", /* GPIO34 */
+ "NC", /* GPIO35 */
+ "NC", /* GPIO36 */
+ "NC", /* GPIO37 */
+ "NC", /* GPIO38 */
+ "NC", /* GPIO39 */
+ "CAM_GPIO0", /* GPIO40 */
+ "WL_ON", /* GPIO41 */
+ "BT_ON", /* GPIO42 */
+ "WIFI_CLK", /* GPIO43 */
+ "SDA0", /* GPIO44 */
+ "SCL0", /* GPIO45 */
+ "SMPS_SCL",
+ "SMPS_SDA",
+ /* Used by SD Card */
+ "SD_CLK_R",
+ "SD_CMD_R",
+ "SD_DATA0_R",
+ "SD_DATA1_R",
+ "SD_DATA2_R",
+ "SD_DATA3_R";
+
+ pinctrl-0 = <&gpioout &alt0>;
+};
+
+&hdmi {
+ hpd-gpios = <&gpio 28 GPIO_ACTIVE_LOW>;
+ power-domains = <&power RPI_POWER_DOMAIN_HDMI>;
+ status = "okay";
+};
+
+&sdhci {
+ pinctrl-0 = <&emmc_gpio34 &gpclk2_gpio43>;
+};
+
+&sdhost {
+ pinctrl-names = "default";
+ pinctrl-0 = <&sdhost_gpio48>;
+ bus-width = <4>;
+ status = "okay";
+};
+
+&uart0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0_gpio32 &uart0_ctsrts_gpio30>;
+};
+
+&uart1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart1_gpio14>;
+ status = "okay";
+};
+
+&wifi_pwrseq {
+ reset-gpios = <&gpio 41 GPIO_ACTIVE_LOW>;
+};
diff --git a/arch/arm/boot/dts/bcm2837.dtsi b/arch/arm/boot/dts/bcm2837.dtsi
index 0199ec98cd61..5dbdebc46259 100644
--- a/arch/arm/boot/dts/bcm2837.dtsi
+++ b/arch/arm/boot/dts/bcm2837.dtsi
@@ -40,12 +40,26 @@
#size-cells = <0>;
enable-method = "brcm,bcm2836-smp"; // for ARM 32-bit
+ /* Source for d/i-cache-line-size and d/i-cache-sets
+ * https://developer.arm.com/documentation/ddi0500/e/level-1-memory-system
+ * /about-the-l1-memory-system?lang=en
+ *
+ * Source for d/i-cache-size
+ * https://magpi.raspberrypi.com/articles/raspberry-pi-3-specs-benchmarks
+ */
cpu0: cpu@0 {
device_type = "cpu";
compatible = "arm,cortex-a53";
reg = <0>;
enable-method = "spin-table";
cpu-release-addr = <0x0 0x000000d8>;
+ d-cache-size = <0x8000>;
+ d-cache-line-size = <64>;
+ d-cache-sets = <128>; // 32KiB(size)/64(line-size)=512ways/4-way set
+ i-cache-size = <0x8000>;
+ i-cache-line-size = <64>;
+ i-cache-sets = <256>; // 32KiB(size)/64(line-size)=512ways/2-way set
+ next-level-cache = <&l2>;
};
cpu1: cpu@1 {
@@ -54,6 +68,13 @@
reg = <1>;
enable-method = "spin-table";
cpu-release-addr = <0x0 0x000000e0>;
+ d-cache-size = <0x8000>;
+ d-cache-line-size = <64>;
+ d-cache-sets = <128>; // 32KiB(size)/64(line-size)=512ways/4-way set
+ i-cache-size = <0x8000>;
+ i-cache-line-size = <64>;
+ i-cache-sets = <256>; // 32KiB(size)/64(line-size)=512ways/2-way set
+ next-level-cache = <&l2>;
};
cpu2: cpu@2 {
@@ -62,6 +83,13 @@
reg = <2>;
enable-method = "spin-table";
cpu-release-addr = <0x0 0x000000e8>;
+ d-cache-size = <0x8000>;
+ d-cache-line-size = <64>;
+ d-cache-sets = <128>; // 32KiB(size)/64(line-size)=512ways/4-way set
+ i-cache-size = <0x8000>;
+ i-cache-line-size = <64>;
+ i-cache-sets = <256>; // 32KiB(size)/64(line-size)=512ways/2-way set
+ next-level-cache = <&l2>;
};
cpu3: cpu@3 {
@@ -70,6 +98,27 @@
reg = <3>;
enable-method = "spin-table";
cpu-release-addr = <0x0 0x000000f0>;
+ d-cache-size = <0x8000>;
+ d-cache-line-size = <64>;
+ d-cache-sets = <128>; // 32KiB(size)/64(line-size)=512ways/4-way set
+ i-cache-size = <0x8000>;
+ i-cache-line-size = <64>;
+ i-cache-sets = <256>; // 32KiB(size)/64(line-size)=512ways/2-way set
+ next-level-cache = <&l2>;
+ };
+
+ /* Source for cache-line-size + cache-sets
+ * https://developer.arm.com/documentation/ddi0500
+ * /e/level-2-memory-system/about-the-l2-memory-system?lang=en
+ * Source for cache-size
+ * https://datasheets.raspberrypi.com/cm/cm1-and-cm3-datasheet.pdf
+ */
+ l2: l2-cache0 {
+ compatible = "cache";
+ cache-size = <0x80000>;
+ cache-line-size = <64>;
+ cache-sets = <512>; // 512KiB(size)/64(line-size)=8192ways/16-way set
+ cache-level = <2>;
};
};
};
diff --git a/arch/arm/boot/dts/bcm47094-asus-rt-ac88u.dts b/arch/arm/boot/dts/bcm47094-asus-rt-ac88u.dts
index 249476fdad7a..82f9629f0abb 100644
--- a/arch/arm/boot/dts/bcm47094-asus-rt-ac88u.dts
+++ b/arch/arm/boot/dts/bcm47094-asus-rt-ac88u.dts
@@ -93,6 +93,82 @@
gpios = <&chipcommon 4 GPIO_ACTIVE_LOW>;
};
};
+
+ switch {
+ compatible = "realtek,rtl8365mb";
+ /* 7 = MDIO (has input reads), 6 = MDC (clock, output only) */
+ mdc-gpios = <&chipcommon 6 GPIO_ACTIVE_HIGH>;
+ mdio-gpios = <&chipcommon 7 GPIO_ACTIVE_HIGH>;
+ reset-gpios = <&chipcommon 10 GPIO_ACTIVE_LOW>;
+ realtek,disable-leds;
+ dsa,member = <1 0>;
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+ label = "lan5";
+ phy-handle = <&ethphy0>;
+ };
+
+ port@1 {
+ reg = <1>;
+ label = "lan6";
+ phy-handle = <&ethphy1>;
+ };
+
+ port@2 {
+ reg = <2>;
+ label = "lan7";
+ phy-handle = <&ethphy2>;
+ };
+
+ port@3 {
+ reg = <3>;
+ label = "lan8";
+ phy-handle = <&ethphy3>;
+ };
+
+ port@6 {
+ reg = <6>;
+ label = "cpu";
+ ethernet = <&sw0_p5>;
+ phy-mode = "rgmii";
+ tx-internal-delay-ps = <2000>;
+ rx-internal-delay-ps = <2100>;
+
+ fixed-link {
+ speed = <1000>;
+ full-duplex;
+ pause;
+ };
+ };
+ };
+
+ mdio {
+ compatible = "realtek,smi-mdio";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ ethphy0: ethernet-phy@0 {
+ reg = <0>;
+ };
+
+ ethphy1: ethernet-phy@1 {
+ reg = <1>;
+ };
+
+ ethphy2: ethernet-phy@2 {
+ reg = <2>;
+ };
+
+ ethphy3: ethernet-phy@3 {
+ reg = <3>;
+ };
+ };
+ };
};
&srab {
diff --git a/arch/arm/boot/dts/bcm47094-luxul-xwr-3150-v1.dts b/arch/arm/boot/dts/bcm47094-luxul-xwr-3150-v1.dts
index 24ae3c8a3e09..9efcb2424228 100644
--- a/arch/arm/boot/dts/bcm47094-luxul-xwr-3150-v1.dts
+++ b/arch/arm/boot/dts/bcm47094-luxul-xwr-3150-v1.dts
@@ -25,6 +25,9 @@
nvram@1eff0000 {
compatible = "brcm,nvram";
reg = <0x1eff0000 0x10000>;
+
+ et0macaddr: et0macaddr {
+ };
};
leds {
@@ -72,6 +75,11 @@
};
};
+&gmac0 {
+ nvmem-cells = <&et0macaddr>;
+ nvmem-cell-names = "mac-address";
+};
+
&usb3 {
vcc-gpio = <&chipcommon 18 GPIO_ACTIVE_HIGH>;
};
diff --git a/arch/arm/boot/dts/bcm958625-meraki-alamo.dtsi b/arch/arm/boot/dts/bcm958625-meraki-alamo.dtsi
index ba01054a76cf..58b7d9fc7574 100644
--- a/arch/arm/boot/dts/bcm958625-meraki-alamo.dtsi
+++ b/arch/arm/boot/dts/bcm958625-meraki-alamo.dtsi
@@ -57,10 +57,9 @@
led-4 {
/* amber:power */
- function = LED_FUNCTION_POWER;
+ function = LED_FUNCTION_FAULT;
color = <LED_COLOR_ID_AMBER>;
gpios = <&gpioa 3 GPIO_ACTIVE_HIGH>;
- default-state = "on";
};
led-5 {
diff --git a/arch/arm/boot/dts/bcm958625-meraki-kingpin.dtsi b/arch/arm/boot/dts/bcm958625-meraki-kingpin.dtsi
index 7c487c74fd10..576cfc52567b 100644
--- a/arch/arm/boot/dts/bcm958625-meraki-kingpin.dtsi
+++ b/arch/arm/boot/dts/bcm958625-meraki-kingpin.dtsi
@@ -106,10 +106,9 @@
led-a {
/* amber:power */
- function = LED_FUNCTION_POWER;
+ function = LED_FUNCTION_FAULT;
color = <LED_COLOR_ID_AMBER>;
gpios = <&gpioa 0 GPIO_ACTIVE_LOW>;
- default-state = "on";
};
led-b {
diff --git a/arch/arm/boot/dts/bcm958625-meraki-mx6x-common.dtsi b/arch/arm/boot/dts/bcm958625-meraki-mx6x-common.dtsi
index 6519b7c61af1..b0854d881ac6 100644
--- a/arch/arm/boot/dts/bcm958625-meraki-mx6x-common.dtsi
+++ b/arch/arm/boot/dts/bcm958625-meraki-mx6x-common.dtsi
@@ -22,7 +22,7 @@
};
led-2 {
- function = LED_FUNCTION_INDICATOR;
+ function = LED_FUNCTION_POWER;
color = <LED_COLOR_ID_GREEN>;
pwms = <&pwm 2 50000>;
max-brightness = <255>;
@@ -39,6 +39,8 @@
&amac2 {
status = "okay";
+ nvmem-cells = <&mac_address>;
+ nvmem-cell-names = "mac-address";
};
&ehci0 {
@@ -53,6 +55,12 @@
reg = <0x50>;
pagesize = <32>;
read-only;
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ mac_address: mac-address@66 {
+ reg = <0x66 0x6>;
+ };
};
};
diff --git a/arch/arm/boot/dts/dra7-l4.dtsi b/arch/arm/boot/dts/dra7-l4.dtsi
index 956a26d52a4c..0a11bacffc1f 100644
--- a/arch/arm/boot/dts/dra7-l4.dtsi
+++ b/arch/arm/boot/dts/dra7-l4.dtsi
@@ -3482,8 +3482,7 @@
ti,timer-pwm;
};
};
-
- target-module@2c000 { /* 0x4882c000, ap 17 02.0 */
+ timer15_target: target-module@2c000 { /* 0x4882c000, ap 17 02.0 */
compatible = "ti,sysc-omap4-timer", "ti,sysc";
reg = <0x2c000 0x4>,
<0x2c010 0x4>;
@@ -3511,7 +3510,7 @@
};
};
- target-module@2e000 { /* 0x4882e000, ap 19 14.0 */
+ timer16_target: target-module@2e000 { /* 0x4882e000, ap 19 14.0 */
compatible = "ti,sysc-omap4-timer", "ti,sysc";
reg = <0x2e000 0x4>,
<0x2e010 0x4>;
diff --git a/arch/arm/boot/dts/dra7.dtsi b/arch/arm/boot/dts/dra7.dtsi
index 6b485cbed8d5..97ce0c4f1df7 100644
--- a/arch/arm/boot/dts/dra7.dtsi
+++ b/arch/arm/boot/dts/dra7.dtsi
@@ -160,7 +160,7 @@
target-module@48210000 {
compatible = "ti,sysc-omap4-simple", "ti,sysc";
power-domains = <&prm_mpu>;
- clocks = <&mpu_clkctrl DRA7_MPU_CLKCTRL 0>;
+ clocks = <&mpu_clkctrl DRA7_MPU_MPU_CLKCTRL 0>;
clock-names = "fck";
#address-cells = <1>;
#size-cells = <1>;
@@ -875,10 +875,10 @@
<0x58000014 4>;
reg-names = "rev", "syss";
ti,syss-mask = <1>;
- clocks = <&dss_clkctrl DRA7_DSS_CORE_CLKCTRL 0>,
- <&dss_clkctrl DRA7_DSS_CORE_CLKCTRL 9>,
- <&dss_clkctrl DRA7_DSS_CORE_CLKCTRL 10>,
- <&dss_clkctrl DRA7_DSS_CORE_CLKCTRL 11>;
+ clocks = <&dss_clkctrl DRA7_DSS_DSS_CORE_CLKCTRL 0>,
+ <&dss_clkctrl DRA7_DSS_DSS_CORE_CLKCTRL 9>,
+ <&dss_clkctrl DRA7_DSS_DSS_CORE_CLKCTRL 10>,
+ <&dss_clkctrl DRA7_DSS_DSS_CORE_CLKCTRL 11>;
clock-names = "fck", "hdmi_clk", "sys_clk", "tv_clk";
#address-cells = <1>;
#size-cells = <1>;
@@ -912,7 +912,7 @@
SYSC_OMAP2_SOFTRESET |
SYSC_OMAP2_AUTOIDLE)>;
ti,syss-mask = <1>;
- clocks = <&dss_clkctrl DRA7_DSS_CORE_CLKCTRL 8>;
+ clocks = <&dss_clkctrl DRA7_DSS_DSS_CORE_CLKCTRL 8>;
clock-names = "fck";
#address-cells = <1>;
#size-cells = <1>;
@@ -939,8 +939,8 @@
<SYSC_IDLE_SMART>,
<SYSC_IDLE_SMART_WKUP>;
ti,sysc-mask = <(SYSC_OMAP4_SOFTRESET)>;
- clocks = <&dss_clkctrl DRA7_DSS_CORE_CLKCTRL 9>,
- <&dss_clkctrl DRA7_DSS_CORE_CLKCTRL 8>;
+ clocks = <&dss_clkctrl DRA7_DSS_DSS_CORE_CLKCTRL 9>,
+ <&dss_clkctrl DRA7_DSS_DSS_CORE_CLKCTRL 8>;
clock-names = "fck", "dss_clk";
#address-cells = <1>;
#size-cells = <1>;
@@ -979,7 +979,7 @@
compatible = "vivante,gc";
reg = <0x0 0x700>;
interrupts = <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&dss_clkctrl DRA7_BB2D_CLKCTRL 0>;
+ clocks = <&dss_clkctrl DRA7_DSS_BB2D_CLKCTRL 0>;
clock-names = "core";
};
};
@@ -1333,26 +1333,26 @@
ti,no-reset-on-init;
ti,no-idle;
timer@0 {
- assigned-clocks = <&wkupaon_clkctrl DRA7_TIMER1_CLKCTRL 24>;
+ assigned-clocks = <&wkupaon_clkctrl DRA7_WKUPAON_TIMER1_CLKCTRL 24>;
assigned-clock-parents = <&sys_32k_ck>;
};
};
/* Local timers, see ARM architected timer wrap erratum i940 */
-&timer3_target {
+&timer15_target {
ti,no-reset-on-init;
ti,no-idle;
timer@0 {
- assigned-clocks = <&l4per_clkctrl DRA7_L4PER_TIMER3_CLKCTRL 24>;
+ assigned-clocks = <&l4per3_clkctrl DRA7_L4PER3_TIMER15_CLKCTRL 24>;
assigned-clock-parents = <&timer_sys_clk_div>;
};
};
-&timer4_target {
+&timer16_target {
ti,no-reset-on-init;
ti,no-idle;
timer@0 {
- assigned-clocks = <&l4per_clkctrl DRA7_L4PER_TIMER4_CLKCTRL 24>;
+ assigned-clocks = <&l4per3_clkctrl DRA7_L4PER3_TIMER16_CLKCTRL 24>;
assigned-clock-parents = <&timer_sys_clk_div>;
};
};
diff --git a/arch/arm/boot/dts/en7523-evb.dts b/arch/arm/boot/dts/en7523-evb.dts
new file mode 100644
index 000000000000..a8d8bb0419a0
--- /dev/null
+++ b/arch/arm/boot/dts/en7523-evb.dts
@@ -0,0 +1,35 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+/dts-v1/;
+
+/* Bootloader installs ATF here */
+/memreserve/ 0x80000000 0x200000;
+
+#include "en7523.dtsi"
+
+/ {
+ model = "Airoha EN7523 Evaluation Board";
+ compatible = "airoha,en7523-evb", "airoha,en7523";
+
+ aliases {
+ serial0 = &uart1;
+ };
+
+ chosen {
+ bootargs = "console=ttyS0,115200 earlycon";
+ stdout-path = "serial0:115200n8";
+ linux,usable-memory-range = <0x80200000 0x1fe00000>;
+ };
+
+ memory@80000000 {
+ device_type = "memory";
+ reg = <0x80000000 0x20000000>;
+ };
+};
+
+&gpio0 {
+ status = "okay";
+};
+
+&gpio1 {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/en7523.dtsi b/arch/arm/boot/dts/en7523.dtsi
new file mode 100644
index 000000000000..36597f587f46
--- /dev/null
+++ b/arch/arm/boot/dts/en7523.dtsi
@@ -0,0 +1,138 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+ interrupt-parent = <&gic>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ reserved-memory {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ npu_binary@84000000 {
+ no-map;
+ reg = <0x84000000 0xA00000>;
+ };
+
+ npu_flag@84B0000 {
+ no-map;
+ reg = <0x84B00000 0x100000>;
+ };
+
+ npu_pkt@85000000 {
+ no-map;
+ reg = <0x85000000 0x1A00000>;
+ };
+
+ npu_phyaddr@86B00000 {
+ no-map;
+ reg = <0x86B00000 0x100000>;
+ };
+
+ npu_rxdesc@86D00000 {
+ no-map;
+ reg = <0x86D00000 0x100000>;
+ };
+ };
+
+ psci {
+ compatible = "arm,psci-0.2";
+ method = "smc";
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu-map {
+ cluster0 {
+ core0 {
+ cpu = <&cpu0>;
+ };
+ core1 {
+ cpu = <&cpu1>;
+ };
+ };
+ };
+
+ cpu0: cpu@0 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a53";
+ reg = <0x0>;
+ enable-method = "psci";
+ clock-frequency = <80000000>;
+ next-level-cache = <&L2_0>;
+ };
+
+ cpu1: cpu@1 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a53";
+ reg = <0x1>;
+ enable-method = "psci";
+ clock-frequency = <80000000>;
+ next-level-cache = <&L2_0>;
+ };
+
+ L2_0: l2-cache0 {
+ compatible = "cache";
+ };
+ };
+
+ gic: interrupt-controller@9000000 {
+ compatible = "arm,gic-v3";
+ interrupt-controller;
+ #interrupt-cells = <3>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x09000000 0x20000>,
+ <0x09080000 0x80000>,
+ <0x09400000 0x2000>,
+ <0x09500000 0x2000>,
+ <0x09600000 0x20000>;
+ interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_LOW>;
+ };
+
+ 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>;
+ };
+
+ uart1: serial@1fbf0000 {
+ compatible = "ns16550";
+ reg = <0x1fbf0000 0x30>;
+ reg-io-width = <4>;
+ reg-shift = <2>;
+ interrupts = <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>;
+ clock-frequency = <1843200>;
+ status = "okay";
+ };
+
+ gpio0: gpio@1fbf0200 {
+ compatible = "airoha,en7523-gpio";
+ reg = <0x1fbf0204 0x4>,
+ <0x1fbf0200 0x4>,
+ <0x1fbf0220 0x4>,
+ <0x1fbf0214 0x4>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ gpio1: gpio@1fbf0270 {
+ compatible = "airoha,en7523-gpio";
+ reg = <0x1fbf0270 0x4>,
+ <0x1fbf0260 0x4>,
+ <0x1fbf0264 0x4>,
+ <0x1fbf0278 0x4>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+};
diff --git a/arch/arm/boot/dts/exynos3250-artik5.dtsi b/arch/arm/boot/dts/exynos3250-artik5.dtsi
index 829c05b2c405..7b429622a288 100644
--- a/arch/arm/boot/dts/exynos3250-artik5.dtsi
+++ b/arch/arm/boot/dts/exynos3250-artik5.dtsi
@@ -356,7 +356,7 @@
};
&pinctrl_1 {
- bten: bten {
+ bten: bten-pins {
samsung,pins ="gpx1-7";
samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
@@ -364,7 +364,7 @@
samsung,pin-pud-pdn = <EXYNOS_PIN_PULL_DOWN>;
};
- wlanen: wlanen {
+ wlanen: wlanen-pins {
samsung,pins = "gpx2-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
@@ -372,12 +372,12 @@
samsung,pin-val = <1>;
};
- s2mps14_irq: s2mps14-irq {
+ s2mps14_irq: s2mps14-irq-pins {
samsung,pins = "gpx3-5";
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
};
- bthostwake: bthostwake {
+ bthostwake: bthostwake-pins {
samsung,pins = "gpx3-6";
samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
@@ -385,7 +385,7 @@
samsung,pin-pud-pdn = <EXYNOS_PIN_PULL_NONE>;
};
- btwake: btwake {
+ btwake: btwake-pins {
samsung,pins = "gpx3-7";
samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
diff --git a/arch/arm/boot/dts/exynos3250-monk.dts b/arch/arm/boot/dts/exynos3250-monk.dts
index 8b41a9d5e2db..02a9dc479d34 100644
--- a/arch/arm/boot/dts/exynos3250-monk.dts
+++ b/arch/arm/boot/dts/exynos3250-monk.dts
@@ -69,7 +69,7 @@
reg = <0x25>;
wakeup-source;
- muic: max77836-muic {
+ extcon {
compatible = "maxim,max77836-muic";
};
diff --git a/arch/arm/boot/dts/exynos3250-pinctrl.dtsi b/arch/arm/boot/dts/exynos3250-pinctrl.dtsi
index dff3c6e3aa1f..cc30d154ec94 100644
--- a/arch/arm/boot/dts/exynos3250-pinctrl.dtsi
+++ b/arch/arm/boot/dts/exynos3250-pinctrl.dtsi
@@ -12,47 +12,22 @@
#include <dt-bindings/pinctrl/samsung.h>
#define PIN_IN(_pin, _pull, _drv) \
- _pin { \
+ pin- ## _pin { \
samsung,pins = #_pin; \
samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>; \
samsung,pin-pud = <EXYNOS_PIN_PULL_ ##_pull>; \
samsung,pin-drv = <EXYNOS4_PIN_DRV_ ##_drv>; \
}
-#define PIN_OUT(_pin, _drv) \
- _pin { \
- samsung,pins = #_pin; \
- samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>; \
- samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>; \
- samsung,pin-drv = <EXYNOS4_PIN_DRV_ ##_drv>; \
- }
-
-#define PIN_OUT_SET(_pin, _val, _drv) \
- _pin { \
- samsung,pins = #_pin; \
- samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>; \
- samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>; \
- samsung,pin-drv = <EXYNOS4_PIN_DRV_ ##_drv>; \
- samsung,pin-val = <_val>; \
- }
-
-#define PIN_CFG(_pin, _sel, _pull, _drv) \
- _pin { \
- samsung,pins = #_pin; \
- samsung,pin-function = <_sel>; \
- samsung,pin-pud = <EXYNOS_PIN_PULL_ ##_pull>; \
- samsung,pin-drv = <EXYNOS4_PIN_DRV_ ##_drv>; \
- }
-
#define PIN_SLP(_pin, _mode, _pull) \
- _pin { \
+ pin- ## _pin { \
samsung,pins = #_pin; \
samsung,pin-con-pdn = <EXYNOS_PIN_PDN_ ##_mode>; \
samsung,pin-pud-pdn = <EXYNOS_PIN_PULL_ ##_pull>; \
}
&pinctrl_0 {
- gpa0: gpa0 {
+ gpa0: gpa0-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -60,7 +35,7 @@
#interrupt-cells = <2>;
};
- gpa1: gpa1 {
+ gpa1: gpa1-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -68,7 +43,7 @@
#interrupt-cells = <2>;
};
- gpb: gpb {
+ gpb: gpb-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -76,7 +51,7 @@
#interrupt-cells = <2>;
};
- gpc0: gpc0 {
+ gpc0: gpc0-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -84,7 +59,7 @@
#interrupt-cells = <2>;
};
- gpc1: gpc1 {
+ gpc1: gpc1-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -92,7 +67,7 @@
#interrupt-cells = <2>;
};
- gpd0: gpd0 {
+ gpd0: gpd0-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -100,7 +75,7 @@
#interrupt-cells = <2>;
};
- gpd1: gpd1 {
+ gpd1: gpd1-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -108,84 +83,84 @@
#interrupt-cells = <2>;
};
- uart0_data: uart0-data {
+ uart0_data: uart0-data-pins {
samsung,pins = "gpa0-0", "gpa0-1";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- uart0_fctl: uart0-fctl {
+ uart0_fctl: uart0-fctl-pins {
samsung,pins = "gpa0-2", "gpa0-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- uart1_data: uart1-data {
+ uart1_data: uart1-data-pins {
samsung,pins = "gpa0-4", "gpa0-5";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- uart1_fctl: uart1-fctl {
+ uart1_fctl: uart1-fctl-pins {
samsung,pins = "gpa0-6", "gpa0-7";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- i2c2_bus: i2c2-bus {
+ i2c2_bus: i2c2-bus-pins {
samsung,pins = "gpa0-6", "gpa0-7";
samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- uart2_data: uart2-data {
+ uart2_data: uart2-data-pins {
samsung,pins = "gpa1-0", "gpa1-1";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- i2c3_bus: i2c3-bus {
+ i2c3_bus: i2c3-bus-pins {
samsung,pins = "gpa1-2", "gpa1-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- spi0_bus: spi0-bus {
+ spi0_bus: spi0-bus-pins {
samsung,pins = "gpb-0", "gpb-2", "gpb-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- i2c4_bus: i2c4-bus {
+ i2c4_bus: i2c4-bus-pins {
samsung,pins = "gpb-0", "gpb-1";
samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- spi1_bus: spi1-bus {
+ spi1_bus: spi1-bus-pins {
samsung,pins = "gpb-4", "gpb-6", "gpb-7";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- i2c5_bus: i2c5-bus {
+ i2c5_bus: i2c5-bus-pins {
samsung,pins = "gpb-2", "gpb-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- i2s2_bus: i2s2-bus {
+ i2s2_bus: i2s2-bus-pins {
samsung,pins = "gpc1-0", "gpc1-1", "gpc1-2", "gpc1-3",
"gpc1-4";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
@@ -193,7 +168,7 @@
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- pcm2_bus: pcm2-bus {
+ pcm2_bus: pcm2-bus-pins {
samsung,pins = "gpc1-0", "gpc1-1", "gpc1-2", "gpc1-3",
"gpc1-4";
samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
@@ -201,63 +176,63 @@
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- i2c6_bus: i2c6-bus {
+ i2c6_bus: i2c6-bus-pins {
samsung,pins = "gpc1-3", "gpc1-4";
samsung,pin-function = <EXYNOS_PIN_FUNC_4>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- pwm0_out: pwm0-out {
+ pwm0_out: pwm0-out-pins {
samsung,pins = "gpd0-0";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- pwm1_out: pwm1-out {
+ pwm1_out: pwm1-out-pins {
samsung,pins = "gpd0-1";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- i2c7_bus: i2c7-bus {
+ i2c7_bus: i2c7-bus-pins {
samsung,pins = "gpd0-2", "gpd0-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- pwm2_out: pwm2-out {
+ pwm2_out: pwm2-out-pins {
samsung,pins = "gpd0-2";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- pwm3_out: pwm3-out {
+ pwm3_out: pwm3-out-pins {
samsung,pins = "gpd0-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- i2c0_bus: i2c0-bus {
+ i2c0_bus: i2c0-bus-pins {
samsung,pins = "gpd1-0", "gpd1-1";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- mipi0_clk: mipi0-clk {
+ mipi0_clk: mipi0-clk-pins {
samsung,pins = "gpd1-0", "gpd1-1";
samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- i2c1_bus: i2c1-bus {
+ i2c1_bus: i2c1-bus-pins {
samsung,pins = "gpd1-2", "gpd1-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
@@ -266,22 +241,22 @@
};
&pinctrl_1 {
- gpe0: gpe0 {
+ gpe0: gpe0-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
};
- gpe1: gpe1 {
+ gpe1: gpe1-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
};
- gpe2: gpe2 {
+ gpe2: gpe2-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
};
- gpk0: gpk0 {
+ gpk0: gpk0-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -289,7 +264,7 @@
#interrupt-cells = <2>;
};
- gpk1: gpk1 {
+ gpk1: gpk1-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -297,7 +272,7 @@
#interrupt-cells = <2>;
};
- gpk2: gpk2 {
+ gpk2: gpk2-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -305,7 +280,7 @@
#interrupt-cells = <2>;
};
- gpl0: gpl0 {
+ gpl0: gpl0-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -313,7 +288,7 @@
#interrupt-cells = <2>;
};
- gpm0: gpm0 {
+ gpm0: gpm0-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -321,7 +296,7 @@
#interrupt-cells = <2>;
};
- gpm1: gpm1 {
+ gpm1: gpm1-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -329,7 +304,7 @@
#interrupt-cells = <2>;
};
- gpm2: gpm2 {
+ gpm2: gpm2-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -337,7 +312,7 @@
#interrupt-cells = <2>;
};
- gpm3: gpm3 {
+ gpm3: gpm3-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -345,7 +320,7 @@
#interrupt-cells = <2>;
};
- gpm4: gpm4 {
+ gpm4: gpm4-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -353,7 +328,7 @@
#interrupt-cells = <2>;
};
- gpx0: gpx0 {
+ gpx0: gpx0-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -370,7 +345,7 @@
#interrupt-cells = <2>;
};
- gpx1: gpx1 {
+ gpx1: gpx1-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -387,7 +362,7 @@
#interrupt-cells = <2>;
};
- gpx2: gpx2 {
+ gpx2: gpx2-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -395,7 +370,7 @@
#interrupt-cells = <2>;
};
- gpx3: gpx3 {
+ gpx3: gpx3-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -403,126 +378,126 @@
#interrupt-cells = <2>;
};
- sd0_clk: sd0-clk {
+ sd0_clk: sd0-clk-pins {
samsung,pins = "gpk0-0";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
};
- sd0_cmd: sd0-cmd {
+ sd0_cmd: sd0-cmd-pins {
samsung,pins = "gpk0-1";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
};
- sd0_cd: sd0-cd {
+ sd0_cd: sd0-cd-pins {
samsung,pins = "gpk0-2";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
};
- sd0_rdqs: sd0-rdqs {
+ sd0_rdqs: sd0-rdqs-pins {
samsung,pins = "gpk0-7";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
};
- sd0_bus1: sd0-bus-width1 {
+ sd0_bus1: sd0-bus-width1-pins {
samsung,pins = "gpk0-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
};
- sd0_bus4: sd0-bus-width4 {
+ sd0_bus4: sd0-bus-width4-pins {
samsung,pins = "gpk0-4", "gpk0-5", "gpk0-6";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
};
- sd0_bus8: sd0-bus-width8 {
+ sd0_bus8: sd0-bus-width8-pins {
samsung,pins = "gpl0-0", "gpl0-1", "gpl0-2", "gpl0-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
};
- sd1_clk: sd1-clk {
+ sd1_clk: sd1-clk-pins {
samsung,pins = "gpk1-0";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
};
- sd1_cmd: sd1-cmd {
+ sd1_cmd: sd1-cmd-pins {
samsung,pins = "gpk1-1";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
};
- sd1_cd: sd1-cd {
+ sd1_cd: sd1-cd-pins {
samsung,pins = "gpk1-2";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
};
- sd1_bus1: sd1-bus-width1 {
+ sd1_bus1: sd1-bus-width1-pins {
samsung,pins = "gpk1-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
};
- sd1_bus4: sd1-bus-width4 {
+ sd1_bus4: sd1-bus-width4-pins {
samsung,pins = "gpk1-4", "gpk1-5", "gpk1-6";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
};
- sd2_clk: sd2-clk {
+ sd2_clk: sd2-clk-pins {
samsung,pins = "gpk2-0";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
};
- sd2_cmd: sd2-cmd {
+ sd2_cmd: sd2-cmd-pins {
samsung,pins = "gpk2-1";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
};
- sd2_cd: sd2-cd {
+ sd2_cd: sd2-cd-pins {
samsung,pins = "gpk2-2";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
};
- sd2_bus1: sd2-bus-width1 {
+ sd2_bus1: sd2-bus-width1-pins {
samsung,pins = "gpk2-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
};
- sd2_bus4: sd2-bus-width4 {
+ sd2_bus4: sd2-bus-width4-pins {
samsung,pins = "gpk2-4", "gpk2-5", "gpk2-6";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
};
- cam_port_b_io: cam-port-b-io {
+ cam_port_b_io: cam-port-b-io-pins {
samsung,pins = "gpm0-0", "gpm0-1", "gpm0-2", "gpm0-3",
"gpm0-4", "gpm0-5", "gpm0-6", "gpm0-7",
"gpm1-0", "gpm1-1", "gpm2-0", "gpm2-1";
@@ -531,35 +506,35 @@
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- cam_port_b_clk_active: cam-port-b-clk-active {
+ cam_port_b_clk_active: cam-port-b-clk-active-pins {
samsung,pins = "gpm2-2";
samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
};
- cam_port_b_clk_idle: cam-port-b-clk-idle {
+ cam_port_b_clk_idle: cam-port-b-clk-idle-pins {
samsung,pins = "gpm2-2";
samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- fimc_is_i2c0: fimc-is-i2c0 {
+ fimc_is_i2c0: fimc-is-i2c0-pins {
samsung,pins = "gpm4-0", "gpm4-1";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- fimc_is_i2c1: fimc-is-i2c1 {
+ fimc_is_i2c1: fimc-is-i2c1-pins {
samsung,pins = "gpm4-2", "gpm4-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- fimc_is_uart: fimc-is-uart {
+ fimc_is_uart: fimc-is-uart-pins {
samsung,pins = "gpm3-5", "gpm3-7";
samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
diff --git a/arch/arm/boot/dts/exynos3250-rinato.dts b/arch/arm/boot/dts/exynos3250-rinato.dts
index 5f7f8fedfb92..6d2c7bb19184 100644
--- a/arch/arm/boot/dts/exynos3250-rinato.dts
+++ b/arch/arm/boot/dts/exynos3250-rinato.dts
@@ -70,7 +70,7 @@
reg = <0x25>;
wakeup-source;
- muic: max77836-muic {
+ extcon {
compatible = "maxim,max77836-muic";
};
diff --git a/arch/arm/boot/dts/exynos3250.dtsi b/arch/arm/boot/dts/exynos3250.dtsi
index a10b789d8acf..ae644315855d 100644
--- a/arch/arm/boot/dts/exynos3250.dtsi
+++ b/arch/arm/boot/dts/exynos3250.dtsi
@@ -421,7 +421,7 @@
status = "disabled";
};
- pdma0: pdma@12680000 {
+ pdma0: dma-controller@12680000 {
compatible = "arm,pl330", "arm,primecell";
reg = <0x12680000 0x1000>;
interrupts = <GIC_SPI 138 IRQ_TYPE_LEVEL_HIGH>;
@@ -432,7 +432,7 @@
#dma-requests = <32>;
};
- pdma1: pdma@12690000 {
+ pdma1: dma-controller@12690000 {
compatible = "arm,pl330", "arm,primecell";
reg = <0x12690000 0x1000>;
interrupts = <GIC_SPI 139 IRQ_TYPE_LEVEL_HIGH>;
diff --git a/arch/arm/boot/dts/exynos4.dtsi b/arch/arm/boot/dts/exynos4.dtsi
index eab77a66ae8f..e81b3ee4e0f7 100644
--- a/arch/arm/boot/dts/exynos4.dtsi
+++ b/arch/arm/boot/dts/exynos4.dtsi
@@ -669,7 +669,7 @@
status = "disabled";
};
- pdma0: pdma@12680000 {
+ pdma0: dma-controller@12680000 {
compatible = "arm,pl330", "arm,primecell";
reg = <0x12680000 0x1000>;
interrupts = <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>;
@@ -680,7 +680,7 @@
#dma-requests = <32>;
};
- pdma1: pdma@12690000 {
+ pdma1: dma-controller@12690000 {
compatible = "arm,pl330", "arm,primecell";
reg = <0x12690000 0x1000>;
interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
@@ -691,7 +691,7 @@
#dma-requests = <32>;
};
- mdma1: mdma@12850000 {
+ mdma1: dma-controller@12850000 {
compatible = "arm,pl330", "arm,primecell";
reg = <0x12850000 0x1000>;
interrupts = <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>;
diff --git a/arch/arm/boot/dts/exynos4210-i9100.dts b/arch/arm/boot/dts/exynos4210-i9100.dts
index 33894054b8b0..3c0a18b30837 100644
--- a/arch/arm/boot/dts/exynos4210-i9100.dts
+++ b/arch/arm/boot/dts/exynos4210-i9100.dts
@@ -672,26 +672,26 @@
pinctrl-names = "default";
pinctrl-0 = <&sleep0>;
- sleep0: sleep-states {
- gpa0-0 {
+ sleep0: sleep-state {
+ gpa0-0-pin {
samsung,pins = "gpa0-0";
samsung,pin-con-pdn = <EXYNOS_PIN_PDN_INPUT>;
samsung,pin-pud-pdn = <EXYNOS_PIN_PULL_NONE>;
};
- gpa0-1 {
+ gpa0-1-pin {
samsung,pins = "gpa0-1";
samsung,pin-con-pdn = <EXYNOS_PIN_PDN_OUT0>;
samsung,pin-pud-pdn = <EXYNOS_PIN_PULL_NONE>;
};
- gpa0-2 {
+ gpa0-2-pin {
samsung,pins = "gpa0-2";
samsung,pin-con-pdn = <EXYNOS_PIN_PDN_INPUT>;
samsung,pin-pud-pdn = <EXYNOS_PIN_PULL_NONE>;
};
- gpa0-3 {
+ gpa0-3-pin {
samsung,pins = "gpa0-3";
samsung,pin-con-pdn = <EXYNOS_PIN_PDN_OUT1>;
samsung,pin-pud-pdn = <EXYNOS_PIN_PULL_NONE>;
@@ -700,19 +700,19 @@
};
&pinctrl_1 {
- mhl_int: mhl-int {
+ mhl_int: mhl-int-pins {
samsung,pins = "gpf3-5";
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
};
- i2c_mhl_bus: i2c-mhl-bus {
+ i2c_mhl_bus: i2c-mhl-bus-pins {
samsung,pins = "gpf0-4", "gpf0-6";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- usb_sel: usb-sel {
+ usb_sel: usb-sel-pins {
samsung,pins = "gpl0-6";
samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
@@ -720,7 +720,7 @@
samsung,pin-val = <0>;
};
- bt_en: bt-en {
+ bt_en: bt-en-pins {
samsung,pins = "gpl0-4";
samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
@@ -728,7 +728,7 @@
samsung,pin-val = <0>;
};
- bt_res: bt-res {
+ bt_res: bt-res-pins {
samsung,pins = "gpl1-0";
samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
@@ -736,7 +736,7 @@
samsung,pin-val = <0>;
};
- otg_gp: otg-gp {
+ otg_gp: otg-gp-pins {
samsung,pins = "gpx3-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
@@ -744,23 +744,23 @@
samsung,pin-val = <0>;
};
- mag_mhl_gpio: mag-mhl {
+ mag_mhl_gpio: mag-mhl-pins {
samsung,pins = "gpd0-2";
samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
};
- max8997_irq: max8997-irq {
+ max8997_irq: max8997-irq-pins {
samsung,pins = "gpx0-7";
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
};
- max17042_fuel_irq: max17042-fuel-irq {
+ max17042_fuel_irq: max17042-fuel-irq-pins {
samsung,pins = "gpx2-3";
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
};
- tsp224_irq: tsp224-irq {
+ tsp224_irq: tsp224-irq-pins {
samsung,pins = "gpx0-4";
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
};
diff --git a/arch/arm/boot/dts/exynos4210-origen.dts b/arch/arm/boot/dts/exynos4210-origen.dts
index 435fda60e86d..a08ce2f37ea2 100644
--- a/arch/arm/boot/dts/exynos4210-origen.dts
+++ b/arch/arm/boot/dts/exynos4210-origen.dts
@@ -316,7 +316,7 @@
};
&pinctrl_1 {
- max8997_irq: max8997-irq {
+ max8997_irq: max8997-irq-pins {
samsung,pins = "gpx0-3", "gpx0-4";
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
};
diff --git a/arch/arm/boot/dts/exynos4210-pinctrl.dtsi b/arch/arm/boot/dts/exynos4210-pinctrl.dtsi
index 520c5934a8d4..6373009bb727 100644
--- a/arch/arm/boot/dts/exynos4210-pinctrl.dtsi
+++ b/arch/arm/boot/dts/exynos4210-pinctrl.dtsi
@@ -14,7 +14,7 @@
#include <dt-bindings/pinctrl/samsung.h>
&pinctrl_0 {
- gpa0: gpa0 {
+ gpa0: gpa0-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -22,7 +22,7 @@
#interrupt-cells = <2>;
};
- gpa1: gpa1 {
+ gpa1: gpa1-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -30,7 +30,7 @@
#interrupt-cells = <2>;
};
- gpb: gpb {
+ gpb: gpb-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -38,7 +38,7 @@
#interrupt-cells = <2>;
};
- gpc0: gpc0 {
+ gpc0: gpc0-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -46,7 +46,7 @@
#interrupt-cells = <2>;
};
- gpc1: gpc1 {
+ gpc1: gpc1-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -54,7 +54,7 @@
#interrupt-cells = <2>;
};
- gpd0: gpd0 {
+ gpd0: gpd0-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -62,7 +62,7 @@
#interrupt-cells = <2>;
};
- gpd1: gpd1 {
+ gpd1: gpd1-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -70,7 +70,7 @@
#interrupt-cells = <2>;
};
- gpe0: gpe0 {
+ gpe0: gpe0-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -78,7 +78,7 @@
#interrupt-cells = <2>;
};
- gpe1: gpe1 {
+ gpe1: gpe1-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -86,7 +86,7 @@
#interrupt-cells = <2>;
};
- gpe2: gpe2 {
+ gpe2: gpe2-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -94,7 +94,7 @@
#interrupt-cells = <2>;
};
- gpe3: gpe3 {
+ gpe3: gpe3-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -102,7 +102,7 @@
#interrupt-cells = <2>;
};
- gpe4: gpe4 {
+ gpe4: gpe4-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -110,7 +110,7 @@
#interrupt-cells = <2>;
};
- gpf0: gpf0 {
+ gpf0: gpf0-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -118,7 +118,7 @@
#interrupt-cells = <2>;
};
- gpf1: gpf1 {
+ gpf1: gpf1-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -126,7 +126,7 @@
#interrupt-cells = <2>;
};
- gpf2: gpf2 {
+ gpf2: gpf2-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -134,7 +134,7 @@
#interrupt-cells = <2>;
};
- gpf3: gpf3 {
+ gpf3: gpf3-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -142,112 +142,112 @@
#interrupt-cells = <2>;
};
- uart0_data: uart0-data {
+ uart0_data: uart0-data-pins {
samsung,pins = "gpa0-0", "gpa0-1";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- uart0_fctl: uart0-fctl {
+ uart0_fctl: uart0-fctl-pins {
samsung,pins = "gpa0-2", "gpa0-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- uart1_data: uart1-data {
+ uart1_data: uart1-data-pins {
samsung,pins = "gpa0-4", "gpa0-5";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- uart1_fctl: uart1-fctl {
+ uart1_fctl: uart1-fctl-pins {
samsung,pins = "gpa0-6", "gpa0-7";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- i2c2_bus: i2c2-bus {
+ i2c2_bus: i2c2-bus-pins {
samsung,pins = "gpa0-6", "gpa0-7";
samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- uart2_data: uart2-data {
+ uart2_data: uart2-data-pins {
samsung,pins = "gpa1-0", "gpa1-1";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- uart2_fctl: uart2-fctl {
+ uart2_fctl: uart2-fctl-pins {
samsung,pins = "gpa1-2", "gpa1-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- uart_audio_a: uart-audio-a {
+ uart_audio_a: uart-audio-a-pins {
samsung,pins = "gpa1-0", "gpa1-1";
samsung,pin-function = <EXYNOS_PIN_FUNC_4>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- i2c3_bus: i2c3-bus {
+ i2c3_bus: i2c3-bus-pins {
samsung,pins = "gpa1-2", "gpa1-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- uart3_data: uart3-data {
+ uart3_data: uart3-data-pins {
samsung,pins = "gpa1-4", "gpa1-5";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- uart_audio_b: uart-audio-b {
+ uart_audio_b: uart-audio-b-pins {
samsung,pins = "gpa1-4", "gpa1-5";
samsung,pin-function = <EXYNOS_PIN_FUNC_4>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- spi0_bus: spi0-bus {
+ spi0_bus: spi0-bus-pins {
samsung,pins = "gpb-0", "gpb-2", "gpb-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- i2c4_bus: i2c4-bus {
+ i2c4_bus: i2c4-bus-pins {
samsung,pins = "gpb-2", "gpb-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- spi1_bus: spi1-bus {
+ spi1_bus: spi1-bus-pins {
samsung,pins = "gpb-4", "gpb-6", "gpb-7";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- i2c5_bus: i2c5-bus {
+ i2c5_bus: i2c5-bus-pins {
samsung,pins = "gpb-6", "gpb-7";
samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- i2s1_bus: i2s1-bus {
+ i2s1_bus: i2s1-bus-pins {
samsung,pins = "gpc0-0", "gpc0-1", "gpc0-2", "gpc0-3",
"gpc0-4";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
@@ -255,7 +255,7 @@
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- pcm1_bus: pcm1-bus {
+ pcm1_bus: pcm1-bus-pins {
samsung,pins = "gpc0-0", "gpc0-1", "gpc0-2", "gpc0-3",
"gpc0-4";
samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
@@ -263,7 +263,7 @@
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- ac97_bus: ac97-bus {
+ ac97_bus: ac97-bus-pins {
samsung,pins = "gpc0-0", "gpc0-1", "gpc0-2", "gpc0-3",
"gpc0-4";
samsung,pin-function = <EXYNOS_PIN_FUNC_4>;
@@ -271,7 +271,7 @@
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- i2s2_bus: i2s2-bus {
+ i2s2_bus: i2s2-bus-pins {
samsung,pins = "gpc1-0", "gpc1-1", "gpc1-2", "gpc1-3",
"gpc1-4";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
@@ -279,7 +279,7 @@
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- pcm2_bus: pcm2-bus {
+ pcm2_bus: pcm2-bus-pins {
samsung,pins = "gpc1-0", "gpc1-1", "gpc1-2", "gpc1-3",
"gpc1-4";
samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
@@ -287,105 +287,105 @@
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- spdif_bus: spdif-bus {
+ spdif_bus: spdif-bus-pins {
samsung,pins = "gpc1-0", "gpc1-1";
samsung,pin-function = <EXYNOS_PIN_FUNC_4>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- i2c6_bus: i2c6-bus {
+ i2c6_bus: i2c6-bus-pins {
samsung,pins = "gpc1-3", "gpc1-4";
samsung,pin-function = <EXYNOS_PIN_FUNC_4>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- spi2_bus: spi2-bus {
+ spi2_bus: spi2-bus-pins {
samsung,pins = "gpc1-1", "gpc1-2", "gpc1-3", "gpc1-4";
samsung,pin-function = <EXYNOS_PIN_FUNC_5>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- i2c7_bus: i2c7-bus {
+ i2c7_bus: i2c7-bus-pins {
samsung,pins = "gpd0-2", "gpd0-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- i2c0_bus: i2c0-bus {
+ i2c0_bus: i2c0-bus-pins {
samsung,pins = "gpd1-0", "gpd1-1";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- i2c1_bus: i2c1-bus {
+ i2c1_bus: i2c1-bus-pins {
samsung,pins = "gpd1-2", "gpd1-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- pwm0_out: pwm0-out {
+ pwm0_out: pwm0-out-pins {
samsung,pins = "gpd0-0";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- pwm1_out: pwm1-out {
+ pwm1_out: pwm1-out-pins {
samsung,pins = "gpd0-1";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- pwm2_out: pwm2-out {
+ pwm2_out: pwm2-out-pins {
samsung,pins = "gpd0-2";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- pwm3_out: pwm3-out {
+ pwm3_out: pwm3-out-pins {
samsung,pins = "gpd0-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- lcd_ctrl: lcd-ctrl {
+ lcd_ctrl: lcd-ctrl-pins {
samsung,pins = "gpd0-0", "gpd0-1";
samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- lcd_sync: lcd-sync {
+ lcd_sync: lcd-sync-pins {
samsung,pins = "gpf0-0", "gpf0-1";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- lcd_en: lcd-en {
+ lcd_en: lcd-en-pins {
samsung,pins = "gpe3-4";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- lcd_clk: lcd-clk {
+ lcd_clk: lcd-clk-pins {
samsung,pins = "gpf0-0", "gpf0-1", "gpf0-2", "gpf0-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- lcd_data16: lcd-data-width16 {
+ lcd_data16: lcd-data-width16-pins {
samsung,pins = "gpf0-7", "gpf1-0", "gpf1-1", "gpf1-2",
"gpf1-3", "gpf1-6", "gpf1-7", "gpf2-0",
"gpf2-1", "gpf2-2", "gpf2-3", "gpf2-7",
@@ -395,7 +395,7 @@
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- lcd_data18: lcd-data-width18 {
+ lcd_data18: lcd-data-width18-pins {
samsung,pins = "gpf0-6", "gpf0-7", "gpf1-0", "gpf1-1",
"gpf1-2", "gpf1-3", "gpf1-6", "gpf1-7",
"gpf2-0", "gpf2-1", "gpf2-2", "gpf2-3",
@@ -406,7 +406,7 @@
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- lcd_data24: lcd-data-width24 {
+ lcd_data24: lcd-data-width24-pins {
samsung,pins = "gpf0-4", "gpf0-5", "gpf0-6", "gpf0-7",
"gpf1-0", "gpf1-1", "gpf1-2", "gpf1-3",
"gpf1-4", "gpf1-5", "gpf1-6", "gpf1-7",
@@ -420,7 +420,7 @@
};
&pinctrl_1 {
- gpj0: gpj0 {
+ gpj0: gpj0-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -428,7 +428,7 @@
#interrupt-cells = <2>;
};
- gpj1: gpj1 {
+ gpj1: gpj1-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -436,7 +436,7 @@
#interrupt-cells = <2>;
};
- gpk0: gpk0 {
+ gpk0: gpk0-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -444,7 +444,7 @@
#interrupt-cells = <2>;
};
- gpk1: gpk1 {
+ gpk1: gpk1-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -452,7 +452,7 @@
#interrupt-cells = <2>;
};
- gpk2: gpk2 {
+ gpk2: gpk2-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -460,7 +460,7 @@
#interrupt-cells = <2>;
};
- gpk3: gpk3 {
+ gpk3: gpk3-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -468,7 +468,7 @@
#interrupt-cells = <2>;
};
- gpl0: gpl0 {
+ gpl0: gpl0-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -476,7 +476,7 @@
#interrupt-cells = <2>;
};
- gpl1: gpl1 {
+ gpl1: gpl1-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -484,7 +484,7 @@
#interrupt-cells = <2>;
};
- gpl2: gpl2 {
+ gpl2: gpl2-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -492,42 +492,42 @@
#interrupt-cells = <2>;
};
- gpy0: gpy0 {
+ gpy0: gpy0-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
};
- gpy1: gpy1 {
+ gpy1: gpy1-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
};
- gpy2: gpy2 {
+ gpy2: gpy2-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
};
- gpy3: gpy3 {
+ gpy3: gpy3-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
};
- gpy4: gpy4 {
+ gpy4: gpy4-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
};
- gpy5: gpy5 {
+ gpy5: gpy5-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
};
- gpy6: gpy6 {
+ gpy6: gpy6-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
};
- gpx0: gpx0 {
+ gpx0: gpx0-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -544,7 +544,7 @@
#interrupt-cells = <2>;
};
- gpx1: gpx1 {
+ gpx1: gpx1-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -561,7 +561,7 @@
#interrupt-cells = <2>;
};
- gpx2: gpx2 {
+ gpx2: gpx2-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -569,7 +569,7 @@
#interrupt-cells = <2>;
};
- gpx3: gpx3 {
+ gpx3: gpx3-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -577,238 +577,238 @@
#interrupt-cells = <2>;
};
- sd0_clk: sd0-clk {
+ sd0_clk: sd0-clk-pins {
samsung,pins = "gpk0-0";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
};
- sd0_cmd: sd0-cmd {
+ sd0_cmd: sd0-cmd-pins {
samsung,pins = "gpk0-1";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
};
- sd0_cd: sd0-cd {
+ sd0_cd: sd0-cd-pins {
samsung,pins = "gpk0-2";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
};
- sd0_bus1: sd0-bus-width1 {
+ sd0_bus1: sd0-bus-width1-pins {
samsung,pins = "gpk0-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
};
- sd0_bus4: sd0-bus-width4 {
+ sd0_bus4: sd0-bus-width4-pins {
samsung,pins = "gpk0-3", "gpk0-4", "gpk0-5", "gpk0-6";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
};
- sd0_bus8: sd0-bus-width8 {
+ sd0_bus8: sd0-bus-width8-pins {
samsung,pins = "gpk1-3", "gpk1-4", "gpk1-5", "gpk1-6";
samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
};
- sd4_clk: sd4-clk {
+ sd4_clk: sd4-clk-pins {
samsung,pins = "gpk0-0";
samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
};
- sd4_cmd: sd4-cmd {
+ sd4_cmd: sd4-cmd-pins {
samsung,pins = "gpk0-1";
samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
};
- sd4_cd: sd4-cd {
+ sd4_cd: sd4-cd-pins {
samsung,pins = "gpk0-2";
samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
};
- sd4_bus1: sd4-bus-width1 {
+ sd4_bus1: sd4-bus-width1-pins {
samsung,pins = "gpk0-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
};
- sd4_bus4: sd4-bus-width4 {
+ sd4_bus4: sd4-bus-width4-pins {
samsung,pins = "gpk0-3", "gpk0-4", "gpk0-5", "gpk0-6";
samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
};
- sd4_bus8: sd4-bus-width8 {
+ sd4_bus8: sd4-bus-width8-pins {
samsung,pins = "gpk1-3", "gpk1-4", "gpk1-5", "gpk1-6";
samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
};
- sd1_clk: sd1-clk {
+ sd1_clk: sd1-clk-pins {
samsung,pins = "gpk1-0";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
};
- sd1_cmd: sd1-cmd {
+ sd1_cmd: sd1-cmd-pins {
samsung,pins = "gpk1-1";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
};
- sd1_cd: sd1-cd {
+ sd1_cd: sd1-cd-pins {
samsung,pins = "gpk1-2";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
};
- sd1_bus1: sd1-bus-width1 {
+ sd1_bus1: sd1-bus-width1-pins {
samsung,pins = "gpk1-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
};
- sd1_bus4: sd1-bus-width4 {
+ sd1_bus4: sd1-bus-width4-pins {
samsung,pins = "gpk1-3", "gpk1-4", "gpk1-5", "gpk1-6";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
};
- sd2_clk: sd2-clk {
+ sd2_clk: sd2-clk-pins {
samsung,pins = "gpk2-0";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
};
- sd2_cmd: sd2-cmd {
+ sd2_cmd: sd2-cmd-pins {
samsung,pins = "gpk2-1";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
};
- sd2_cd: sd2-cd {
+ sd2_cd: sd2-cd-pins {
samsung,pins = "gpk2-2";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
};
- sd2_bus1: sd2-bus-width1 {
+ sd2_bus1: sd2-bus-width1-pins {
samsung,pins = "gpk2-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
};
- sd2_bus4: sd2-bus-width4 {
+ sd2_bus4: sd2-bus-width4-pins {
samsung,pins = "gpk2-3", "gpk2-4", "gpk2-5", "gpk2-6";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
};
- sd2_bus8: sd2-bus-width8 {
+ sd2_bus8: sd2-bus-width8-pins {
samsung,pins = "gpk3-3", "gpk3-4", "gpk3-5", "gpk3-6";
samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
};
- sd3_clk: sd3-clk {
+ sd3_clk: sd3-clk-pins {
samsung,pins = "gpk3-0";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
};
- sd3_cmd: sd3-cmd {
+ sd3_cmd: sd3-cmd-pins {
samsung,pins = "gpk3-1";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
};
- sd3_cd: sd3-cd {
+ sd3_cd: sd3-cd-pins {
samsung,pins = "gpk3-2";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
};
- sd3_bus1: sd3-bus-width1 {
+ sd3_bus1: sd3-bus-width1-pins {
samsung,pins = "gpk3-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
};
- sd3_bus4: sd3-bus-width4 {
+ sd3_bus4: sd3-bus-width4-pins {
samsung,pins = "gpk3-3", "gpk3-4", "gpk3-5", "gpk3-6";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
};
- eint0: ext-int0 {
+ eint0: ext-int0-pins {
samsung,pins = "gpx0-0";
samsung,pin-function = <EXYNOS_PIN_FUNC_F>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- eint8: ext-int8 {
+ eint8: ext-int8-pins {
samsung,pins = "gpx1-0";
samsung,pin-function = <EXYNOS_PIN_FUNC_F>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- eint15: ext-int15 {
+ eint15: ext-int15-pins {
samsung,pins = "gpx1-7";
samsung,pin-function = <EXYNOS_PIN_FUNC_F>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- eint16: ext-int16 {
+ eint16: ext-int16-pins {
samsung,pins = "gpx2-0";
samsung,pin-function = <EXYNOS_PIN_FUNC_F>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- eint31: ext-int31 {
+ eint31: ext-int31-pins {
samsung,pins = "gpx3-7";
samsung,pin-function = <EXYNOS_PIN_FUNC_F>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- cam_port_a_io: cam-port-a-io {
+ cam_port_a_io: cam-port-a-io-pins {
samsung,pins = "gpj0-0", "gpj0-1", "gpj0-2", "gpj0-3",
"gpj0-4", "gpj0-5", "gpj0-6", "gpj0-7",
"gpj1-0", "gpj1-1", "gpj1-2", "gpj1-4";
@@ -817,21 +817,21 @@
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- cam_port_a_clk_active: cam-port-a-clk-active {
+ cam_port_a_clk_active: cam-port-a-clk-active-pins {
samsung,pins = "gpj1-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
};
- cam_port_a_clk_idle: cam-port-a-clk-idle {
+ cam_port_a_clk_idle: cam-port-a-clk-idle-pins {
samsung,pins = "gpj1-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- hdmi_cec: hdmi-cec {
+ hdmi_cec: hdmi-cec-pins {
samsung,pins = "gpx3-6";
samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
@@ -840,12 +840,12 @@
};
&pinctrl_2 {
- gpz: gpz {
+ gpz: gpz-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
};
- i2s0_bus: i2s0-bus {
+ i2s0_bus: i2s0-bus-pins {
samsung,pins = "gpz-0", "gpz-1", "gpz-2", "gpz-3",
"gpz-4", "gpz-5", "gpz-6";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
@@ -853,7 +853,7 @@
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- pcm0_bus: pcm0-bus {
+ pcm0_bus: pcm0-bus-pins {
samsung,pins = "gpz-0", "gpz-1", "gpz-2", "gpz-3",
"gpz-4";
samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
diff --git a/arch/arm/boot/dts/exynos4210-smdkv310.dts b/arch/arm/boot/dts/exynos4210-smdkv310.dts
index d5797a67bf48..a5dfd7fd49b3 100644
--- a/arch/arm/boot/dts/exynos4210-smdkv310.dts
+++ b/arch/arm/boot/dts/exynos4210-smdkv310.dts
@@ -152,14 +152,14 @@
};
&pinctrl_1 {
- keypad_rows: keypad-rows {
+ keypad_rows: keypad-rows-pins {
samsung,pins = "gpx2-0", "gpx2-1";
samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- keypad_cols: keypad-cols {
+ keypad_cols: keypad-cols-pins {
samsung,pins = "gpx1-0", "gpx1-1", "gpx1-2", "gpx1-3",
"gpx1-4", "gpx1-5", "gpx1-6", "gpx1-7";
samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
diff --git a/arch/arm/boot/dts/exynos4210-trats.dts b/arch/arm/boot/dts/exynos4210-trats.dts
index 9c4ff7521348..01f44d95f671 100644
--- a/arch/arm/boot/dts/exynos4210-trats.dts
+++ b/arch/arm/boot/dts/exynos4210-trats.dts
@@ -464,19 +464,19 @@
};
&pinctrl_1 {
- bt_shutdown: bt-shutdown {
+ bt_shutdown: bt-shutdown-pins {
samsung,pins = "gpl1-0";
samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
};
- bt_host_wakeup: bt-host-wakeup {
+ bt_host_wakeup: bt-host-wakeup-pins {
samsung,pins = "gpx2-6";
samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
};
- bt_device_wakeup: bt-device-wakeup {
+ bt_device_wakeup: bt-device-wakeup-pins {
samsung,pins = "gpx3-1";
samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
diff --git a/arch/arm/boot/dts/exynos4210-universal_c210.dts b/arch/arm/boot/dts/exynos4210-universal_c210.dts
index 9f93e7464aed..138d606d58a5 100644
--- a/arch/arm/boot/dts/exynos4210-universal_c210.dts
+++ b/arch/arm/boot/dts/exynos4210-universal_c210.dts
@@ -533,37 +533,37 @@
};
&pinctrl_1 {
- bt_shutdown: bt-shutdown {
+ bt_shutdown: bt-shutdown-pins {
samsung,pins = "gpe1-4";
samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
};
- bt_host_wakeup: bt-host-wakeup {
+ bt_host_wakeup: bt-host-wakeup-pins {
samsung,pins = "gpx2-6";
samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
};
- bt_device_wakeup: bt-device-wakeup {
+ bt_device_wakeup: bt-device-wakeup-pins {
samsung,pins = "gpx3-1";
samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
};
- lp3974_irq: lp3974-irq {
+ lp3974_irq: lp3974-irq-pins {
samsung,pins = "gpx0-7", "gpx2-7";
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
};
- hdmi_hpd: hdmi-hpd {
+ hdmi_hpd: hdmi-hpd-pins {
samsung,pins = "gpx3-7";
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
};
};
&pinctrl_0 {
- i2c_ddc_bus: i2c-ddc-bus {
+ i2c_ddc_bus: i2c-ddc-bus-pins {
samsung,pins = "gpe4-2", "gpe4-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
@@ -659,7 +659,7 @@
};
&soc {
- mdma0: mdma@12840000 {
+ mdma0: dma-controller@12840000 {
compatible = "arm,pl330", "arm,primecell";
reg = <0x12840000 0x1000>;
interrupts = <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>;
diff --git a/arch/arm/boot/dts/exynos4210.dtsi b/arch/arm/boot/dts/exynos4210.dtsi
index 7e7d65ce6585..2c25cc37934e 100644
--- a/arch/arm/boot/dts/exynos4210.dtsi
+++ b/arch/arm/boot/dts/exynos4210.dtsi
@@ -527,8 +527,6 @@
compatible = "samsung,exynos4210-tmu";
clocks = <&clock CLK_TMU_APBIF>;
clock-names = "tmu_apbif";
- samsung,tmu_gain = <15>;
- samsung,tmu_reference_voltage = <7>;
};
#include "exynos4210-pinctrl.dtsi"
diff --git a/arch/arm/boot/dts/exynos4412-galaxy-s3.dtsi b/arch/arm/boot/dts/exynos4412-galaxy-s3.dtsi
index c14e37dc3a9b..03dffc690b79 100644
--- a/arch/arm/boot/dts/exynos4412-galaxy-s3.dtsi
+++ b/arch/arm/boot/dts/exynos4412-galaxy-s3.dtsi
@@ -151,13 +151,13 @@
};
&pinctrl_0 {
- camera_flash_host: camera-flash-host {
+ camera_flash_host: camera-flash-host-pins {
samsung,pins = "gpj1-0";
samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
samsung,pin-val = <0>;
};
- camera_flash_isp: camera-flash-isp {
+ camera_flash_isp: camera-flash-isp-pins {
samsung,pins = "gpj1-0";
samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
samsung,pin-val = <1>;
diff --git a/arch/arm/boot/dts/exynos4412-itop-elite.dts b/arch/arm/boot/dts/exynos4412-itop-elite.dts
index 47431307cb3c..a9406280b979 100644
--- a/arch/arm/boot/dts/exynos4412-itop-elite.dts
+++ b/arch/arm/boot/dts/exynos4412-itop-elite.dts
@@ -192,7 +192,7 @@
};
&pinctrl_1 {
- ether-reset {
+ ether-reset-pins {
samsung,pins = "gpc0-1";
samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
diff --git a/arch/arm/boot/dts/exynos4412-itop-scp-core.dtsi b/arch/arm/boot/dts/exynos4412-itop-scp-core.dtsi
index b3726d4d7d93..a67cb61e3cbb 100644
--- a/arch/arm/boot/dts/exynos4412-itop-scp-core.dtsi
+++ b/arch/arm/boot/dts/exynos4412-itop-scp-core.dtsi
@@ -484,7 +484,7 @@
};
&pinctrl_1 {
- hsic_reset: hsic-reset {
+ hsic_reset: hsic-reset-pins {
samsung,pins = "gpm2-4";
samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
diff --git a/arch/arm/boot/dts/exynos4412-midas.dtsi b/arch/arm/boot/dts/exynos4412-midas.dtsi
index 968c7943653e..23f50c9be527 100644
--- a/arch/arm/boot/dts/exynos4412-midas.dtsi
+++ b/arch/arm/boot/dts/exynos4412-midas.dtsi
@@ -987,19 +987,19 @@
pinctrl-names = "default";
pinctrl-0 = <&sleep0>;
- mhl_int: mhl-int {
+ mhl_int: mhl-int-pins {
samsung,pins = "gpf3-5";
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
};
- i2c_mhl_bus: i2c-mhl-bus {
+ i2c_mhl_bus: i2c-mhl-bus-pins {
samsung,pins = "gpf0-4", "gpf0-6";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- sleep0: sleep-states {
+ sleep0: sleep-state {
PIN_SLP(gpa0-0, INPUT, NONE);
PIN_SLP(gpa0-1, OUT0, NONE);
PIN_SLP(gpa0-2, INPUT, NONE);
@@ -1102,52 +1102,52 @@
pinctrl-names = "default";
pinctrl-0 = <&sleep1>;
- gpio_keys: gpio-keys {
+ gpio_keys: gpio-keys-pins {
samsung,pins = "gpx0-1", "gpx2-2", "gpx2-7", "gpx3-3";
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
};
- bt_shutdown: bt-shutdown {
+ bt_shutdown: bt-shutdown-pins {
samsung,pins = "gpl0-6";
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
};
- bt_host_wakeup: bt-host-wakeup {
+ bt_host_wakeup: bt-host-wakeup-pins {
samsung,pins = "gpx2-6";
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
};
- bt_device_wakeup: bt-device-wakeup {
+ bt_device_wakeup: bt-device-wakeup-pins {
samsung,pins = "gpx3-1";
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
};
- max77686_irq: max77686-irq {
+ max77686_irq: max77686-irq-pins {
samsung,pins = "gpx0-7";
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
};
- max77693_irq: max77693-irq {
+ max77693_irq: max77693-irq-pins {
samsung,pins = "gpx1-5";
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
};
- max77693_fuel_irq: max77693-fuel-irq {
+ max77693_fuel_irq: max77693-fuel-irq-pins {
samsung,pins = "gpx2-3";
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
};
- sdhci2_cd: sdhci2-cd-irq {
+ sdhci2_cd: sdhci2-cd-irq-pins {
samsung,pins = "gpx3-4";
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
};
- hdmi_hpd: hdmi-hpd {
+ hdmi_hpd: hdmi-hpd-pins {
samsung,pins = "gpx3-7";
samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
};
- sleep1: sleep-states {
+ sleep1: sleep-state {
PIN_SLP(gpk0-0, PREV, NONE);
PIN_SLP(gpk0-1, PREV, NONE);
PIN_SLP(gpk0-2, OUT0, NONE);
@@ -1300,7 +1300,7 @@
pinctrl-names = "default";
pinctrl-0 = <&sleep2>;
- sleep2: sleep-states {
+ sleep2: sleep-state {
PIN_SLP(gpz-0, INPUT, DOWN);
PIN_SLP(gpz-1, INPUT, DOWN);
PIN_SLP(gpz-2, INPUT, DOWN);
@@ -1315,7 +1315,7 @@
pinctrl-names = "default";
pinctrl-0 = <&sleep3>;
- sleep3: sleep-states {
+ sleep3: sleep-state {
PIN_SLP(gpv0-0, INPUT, DOWN);
PIN_SLP(gpv0-1, INPUT, DOWN);
PIN_SLP(gpv0-2, INPUT, DOWN);
diff --git a/arch/arm/boot/dts/exynos4412-odroid-common.dtsi b/arch/arm/boot/dts/exynos4412-odroid-common.dtsi
index 5b1d4591b35c..e7669b9e9edb 100644
--- a/arch/arm/boot/dts/exynos4412-odroid-common.dtsi
+++ b/arch/arm/boot/dts/exynos4412-odroid-common.dtsi
@@ -172,24 +172,24 @@
};
&pinctrl_1 {
- gpio_power_key: power-key {
+ gpio_power_key: power-key-pins {
samsung,pins = "gpx1-3";
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
};
- max77686_irq: max77686-irq {
+ max77686_irq: max77686-irq-pins {
samsung,pins = "gpx3-2";
samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- hdmi_hpd: hdmi-hpd {
+ hdmi_hpd: hdmi-hpd-pins {
samsung,pins = "gpx3-7";
samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
};
- emmc_rstn: emmc-rstn {
+ emmc_rstn: emmc-rstn-pins {
samsung,pins = "gpk1-2";
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
};
diff --git a/arch/arm/boot/dts/exynos4412-odroidx.dts b/arch/arm/boot/dts/exynos4412-odroidx.dts
index 440135d0ff2a..a9fada51eb50 100644
--- a/arch/arm/boot/dts/exynos4412-odroidx.dts
+++ b/arch/arm/boot/dts/exynos4412-odroidx.dts
@@ -112,7 +112,7 @@
};
&pinctrl_1 {
- gpio_home_key: home-key {
+ gpio_home_key: home-key-pins {
samsung,pins = "gpx2-2";
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
};
diff --git a/arch/arm/boot/dts/exynos4412-origen.dts b/arch/arm/boot/dts/exynos4412-origen.dts
index e6aec5facabf..6db09dba07ff 100644
--- a/arch/arm/boot/dts/exynos4412-origen.dts
+++ b/arch/arm/boot/dts/exynos4412-origen.dts
@@ -506,14 +506,14 @@
};
&pinctrl_1 {
- keypad_rows: keypad-rows {
+ keypad_rows: keypad-rows-pins {
samsung,pins = "gpx2-0", "gpx2-1", "gpx2-2";
samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- keypad_cols: keypad-cols {
+ keypad_cols: keypad-cols-pins {
samsung,pins = "gpx1-0", "gpx1-1";
samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
diff --git a/arch/arm/boot/dts/exynos4412-p4note.dtsi b/arch/arm/boot/dts/exynos4412-p4note.dtsi
index 22c3086e0076..97f131b1014b 100644
--- a/arch/arm/boot/dts/exynos4412-p4note.dtsi
+++ b/arch/arm/boot/dts/exynos4412-p4note.dtsi
@@ -16,6 +16,7 @@
#include <dt-bindings/input/linux-event-codes.h>
#include <dt-bindings/interrupt-controller/irq.h>
#include <dt-bindings/pinctrl/samsung.h>
+#include <dt-bindings/power/summit,smb347-charger.h>
/ {
compatible = "samsung,p4note", "samsung,exynos4412", "samsung,exynos4";
@@ -114,6 +115,17 @@
clock-names = "ext_clock";
};
+ battery_cell: battery-cell {
+ compatible = "simple-battery";
+ device-chemistry = "lithium-ion";
+ constant-charge-current-max-microamp = <2200000>;
+ precharge-current-microamp = <250000>;
+ charge-term-current-microamp = <250000>;
+ constant-charge-voltage-max-microvolt = <4200000>;
+
+ power-supplies = <&power_supply>;
+ };
+
i2c-gpio-1 {
compatible = "i2c-gpio";
sda-gpios = <&gpy2 4 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
@@ -182,6 +194,28 @@
};
};
};
+
+ i2c-gpio-4 {
+ compatible = "i2c-gpio";
+ sda-gpios = <&gpm2 0 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+ scl-gpios = <&gpm2 1 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+
+ i2c-gpio,delay-us = <2>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ power_supply: charger@6 {
+ compatible = "summit,smb347";
+ reg = <0x6>;
+ summit,enable-usb-charging;
+ summit,enable-charge-control = <SMB3XX_CHG_ENABLE_SW>;
+ summit,fast-voltage-threshold-microvolt = <2600000>;
+ summit,chip-temperature-threshold-celsius = <130>;
+ summit,usb-current-limit-microamp = <1800000>;
+
+ monitored-battery = <&battery_cell>;
+ };
+ };
};
&adc {
@@ -641,19 +675,19 @@
pinctrl-names = "default";
pinctrl-0 = <&sleep0>;
- tsp_reg_gpio_2: tsp-reg-gpio-2 {
+ tsp_reg_gpio_2: tsp-reg-gpio-2-pins {
samsung,pins = "gpb-5";
samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
};
- tsp_reg_gpio_3: tsp-reg-gpio-3 {
+ tsp_reg_gpio_3: tsp-reg-gpio-3-pins {
samsung,pins = "gpb-7";
samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
};
- sleep0: sleep-states {
+ sleep0: sleep-state {
PIN_SLP(gpa0-0, INPUT, NONE);
PIN_SLP(gpa0-1, OUT0, NONE);
PIN_SLP(gpa0-2, INPUT, NONE);
@@ -755,19 +789,19 @@
pinctrl-names = "default";
pinctrl-0 = <&sleep1>;
- sd3_wifi: sd3-wifi {
+ sd3_wifi: sd3-wifi-pins {
samsung,pins = "gpk3-3", "gpk3-4", "gpk3-5", "gpk3-6";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
};
- bt_shutdown: bt-shutdown {
+ bt_shutdown: bt-shutdown-pins {
samsung,pins = "gpl0-6";
samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
};
- uart_sel: uart-sel {
+ uart_sel: uart-sel-pins {
samsung,pins = "gpl2-7";
samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
@@ -775,82 +809,82 @@
/* 0 = CP, 1 = AP (serial output) */
};
- tsp_rst: tsp-rst {
+ tsp_rst: tsp-rst-pins {
samsung,pins = "gpm0-4";
samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
};
- tsp_irq: tsp-irq {
+ tsp_irq: tsp-irq-pins {
samsung,pins = "gpm2-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_F>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
};
- wifi_reset: wifi-reset {
+ wifi_reset: wifi-reset-pins {
samsung,pins = "gpm3-5";
samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
};
- tsp_reg_gpio_1: tsp-reg-gpio-1 {
+ tsp_reg_gpio_1: tsp-reg-gpio-1-pins {
samsung,pins = "gpm4-5";
samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
};
- ak8975_irq: ak8975-irq {
+ ak8975_irq: ak8975-irq-pins {
samsung,pins = "gpm4-7";
samsung,pin-function = <EXYNOS_PIN_FUNC_F>;
samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
};
- stmpe_adc_irq: stmpe-adc-irq {
+ 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>;
};
- max77686_irq: max77686-irq {
+ max77686_irq: max77686-irq-pins {
samsung,pins = "gpx0-7";
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
};
- gpio_keys: gpio-keys {
+ gpio_keys: gpio-keys-pins {
samsung,pins = "gpx2-2", "gpx2-7", "gpx3-3";
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
};
- fuel_alert_irq: fuel-alert-irq {
+ fuel_alert_irq: fuel-alert-irq-pins {
samsung,pins = "gpx2-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
};
- wifi_host_wake: wifi-host-wake {
+ wifi_host_wake: wifi-host-wake-pins {
samsung,pins = "gpx2-5";
samsung,pin-function = <EXYNOS_PIN_FUNC_F>;
samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
};
- bt_host_wakeup: bt-host-wakeup {
+ bt_host_wakeup: bt-host-wakeup-pins {
samsung,pins = "gpx2-6";
samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
};
- bt_device_wakeup: bt-device-wakeup {
+ bt_device_wakeup: bt-device-wakeup-pins {
samsung,pins = "gpx3-1";
samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
};
- sdhci2_cd: sdhci2-cd {
+ sdhci2_cd: sdhci2-cd-pins {
samsung,pins = "gpx3-4";
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
};
- sleep1: sleep-states {
+ sleep1: sleep-state {
PIN_SLP(gpk0-0, PREV, NONE);
PIN_SLP(gpk0-1, PREV, NONE);
PIN_SLP(gpk0-2, PREV, NONE);
@@ -1004,7 +1038,7 @@
pinctrl-names = "default";
pinctrl-0 = <&sleep2>;
- sleep2: sleep-states {
+ sleep2: sleep-state {
PIN_SLP(gpz-0, INPUT, DOWN);
PIN_SLP(gpz-1, INPUT, DOWN);
PIN_SLP(gpz-2, INPUT, DOWN);
@@ -1019,7 +1053,7 @@
pinctrl-names = "default";
pinctrl-0 = <&sleep3>;
- sleep3: sleep-states {
+ sleep3: sleep-state {
PIN_SLP(gpv0-0, INPUT, DOWN);
PIN_SLP(gpv0-1, INPUT, DOWN);
PIN_SLP(gpv0-2, INPUT, DOWN);
diff --git a/arch/arm/boot/dts/exynos4412-pinctrl.dtsi b/arch/arm/boot/dts/exynos4412-pinctrl.dtsi
index d7d5fdc230d8..88b8afd55664 100644
--- a/arch/arm/boot/dts/exynos4412-pinctrl.dtsi
+++ b/arch/arm/boot/dts/exynos4412-pinctrl.dtsi
@@ -19,7 +19,7 @@
}
&pinctrl_0 {
- gpa0: gpa0 {
+ gpa0: gpa0-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -27,7 +27,7 @@
#interrupt-cells = <2>;
};
- gpa1: gpa1 {
+ gpa1: gpa1-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -35,7 +35,7 @@
#interrupt-cells = <2>;
};
- gpb: gpb {
+ gpb: gpb-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -43,7 +43,7 @@
#interrupt-cells = <2>;
};
- gpc0: gpc0 {
+ gpc0: gpc0-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -51,7 +51,7 @@
#interrupt-cells = <2>;
};
- gpc1: gpc1 {
+ gpc1: gpc1-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -59,7 +59,7 @@
#interrupt-cells = <2>;
};
- gpd0: gpd0 {
+ gpd0: gpd0-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -67,7 +67,7 @@
#interrupt-cells = <2>;
};
- gpd1: gpd1 {
+ gpd1: gpd1-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -75,7 +75,7 @@
#interrupt-cells = <2>;
};
- gpf0: gpf0 {
+ gpf0: gpf0-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -83,7 +83,7 @@
#interrupt-cells = <2>;
};
- gpf1: gpf1 {
+ gpf1: gpf1-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -91,7 +91,7 @@
#interrupt-cells = <2>;
};
- gpf2: gpf2 {
+ gpf2: gpf2-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -99,7 +99,7 @@
#interrupt-cells = <2>;
};
- gpf3: gpf3 {
+ gpf3: gpf3-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -107,7 +107,7 @@
#interrupt-cells = <2>;
};
- gpj0: gpj0 {
+ gpj0: gpj0-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -115,7 +115,7 @@
#interrupt-cells = <2>;
};
- gpj1: gpj1 {
+ gpj1: gpj1-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -123,112 +123,112 @@
#interrupt-cells = <2>;
};
- uart0_data: uart0-data {
+ uart0_data: uart0-data-pins {
samsung,pins = "gpa0-0", "gpa0-1";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- uart0_fctl: uart0-fctl {
+ uart0_fctl: uart0-fctl-pins {
samsung,pins = "gpa0-2", "gpa0-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- uart1_data: uart1-data {
+ uart1_data: uart1-data-pins {
samsung,pins = "gpa0-4", "gpa0-5";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- uart1_fctl: uart1-fctl {
+ uart1_fctl: uart1-fctl-pins {
samsung,pins = "gpa0-6", "gpa0-7";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- i2c2_bus: i2c2-bus {
+ i2c2_bus: i2c2-bus-pins {
samsung,pins = "gpa0-6", "gpa0-7";
samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- uart2_data: uart2-data {
+ uart2_data: uart2-data-pins {
samsung,pins = "gpa1-0", "gpa1-1";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- uart2_fctl: uart2-fctl {
+ uart2_fctl: uart2-fctl-pins {
samsung,pins = "gpa1-2", "gpa1-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- uart_audio_a: uart-audio-a {
+ uart_audio_a: uart-audio-a-pins {
samsung,pins = "gpa1-0", "gpa1-1";
samsung,pin-function = <EXYNOS_PIN_FUNC_4>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- i2c3_bus: i2c3-bus {
+ i2c3_bus: i2c3-bus-pins {
samsung,pins = "gpa1-2", "gpa1-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- uart3_data: uart3-data {
+ uart3_data: uart3-data-pins {
samsung,pins = "gpa1-4", "gpa1-5";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- uart_audio_b: uart-audio-b {
+ uart_audio_b: uart-audio-b-pins {
samsung,pins = "gpa1-4", "gpa1-5";
samsung,pin-function = <EXYNOS_PIN_FUNC_4>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- spi0_bus: spi0-bus {
+ spi0_bus: spi0-bus-pins {
samsung,pins = "gpb-0", "gpb-2", "gpb-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- i2c4_bus: i2c4-bus {
+ i2c4_bus: i2c4-bus-pins {
samsung,pins = "gpb-0", "gpb-1";
samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- spi1_bus: spi1-bus {
+ spi1_bus: spi1-bus-pins {
samsung,pins = "gpb-4", "gpb-6", "gpb-7";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- i2c5_bus: i2c5-bus {
+ i2c5_bus: i2c5-bus-pins {
samsung,pins = "gpb-2", "gpb-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- i2s1_bus: i2s1-bus {
+ i2s1_bus: i2s1-bus-pins {
samsung,pins = "gpc0-0", "gpc0-1", "gpc0-2", "gpc0-3",
"gpc0-4";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
@@ -236,7 +236,7 @@
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- pcm1_bus: pcm1-bus {
+ pcm1_bus: pcm1-bus-pins {
samsung,pins = "gpc0-0", "gpc0-1", "gpc0-2", "gpc0-3",
"gpc0-4";
samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
@@ -244,7 +244,7 @@
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- ac97_bus: ac97-bus {
+ ac97_bus: ac97-bus-pins {
samsung,pins = "gpc0-0", "gpc0-1", "gpc0-2", "gpc0-3",
"gpc0-4";
samsung,pin-function = <EXYNOS_PIN_FUNC_4>;
@@ -252,7 +252,7 @@
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- i2s2_bus: i2s2-bus {
+ i2s2_bus: i2s2-bus-pins {
samsung,pins = "gpc1-0", "gpc1-1", "gpc1-2", "gpc1-3",
"gpc1-4";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
@@ -260,7 +260,7 @@
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- pcm2_bus: pcm2-bus {
+ pcm2_bus: pcm2-bus-pins {
samsung,pins = "gpc1-0", "gpc1-1", "gpc1-2", "gpc1-3",
"gpc1-4";
samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
@@ -268,105 +268,105 @@
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- spdif_bus: spdif-bus {
+ spdif_bus: spdif-bus-pins {
samsung,pins = "gpc1-0", "gpc1-1";
samsung,pin-function = <EXYNOS_PIN_FUNC_4>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- i2c6_bus: i2c6-bus {
+ i2c6_bus: i2c6-bus-pins {
samsung,pins = "gpc1-3", "gpc1-4";
samsung,pin-function = <EXYNOS_PIN_FUNC_4>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- spi2_bus: spi2-bus {
+ spi2_bus: spi2-bus-pins {
samsung,pins = "gpc1-1", "gpc1-3", "gpc1-4";
samsung,pin-function = <EXYNOS_PIN_FUNC_5>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- pwm0_out: pwm0-out {
+ pwm0_out: pwm0-out-pins {
samsung,pins = "gpd0-0";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- pwm1_out: pwm1-out {
+ pwm1_out: pwm1-out-pins {
samsung,pins = "gpd0-1";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- lcd_ctrl: lcd-ctrl {
+ lcd_ctrl: lcd-ctrl-pins {
samsung,pins = "gpd0-0", "gpd0-1";
samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- i2c7_bus: i2c7-bus {
+ i2c7_bus: i2c7-bus-pins {
samsung,pins = "gpd0-2", "gpd0-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- pwm2_out: pwm2-out {
+ pwm2_out: pwm2-out-pins {
samsung,pins = "gpd0-2";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- pwm3_out: pwm3-out {
+ pwm3_out: pwm3-out-pins {
samsung,pins = "gpd0-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- i2c0_bus: i2c0-bus {
+ i2c0_bus: i2c0-bus-pins {
samsung,pins = "gpd1-0", "gpd1-1";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- mipi0_clk: mipi0-clk {
+ mipi0_clk: mipi0-clk-pins {
samsung,pins = "gpd1-0", "gpd1-1";
samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- i2c1_bus: i2c1-bus {
+ i2c1_bus: i2c1-bus-pins {
samsung,pins = "gpd1-2", "gpd1-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- mipi1_clk: mipi1-clk {
+ mipi1_clk: mipi1-clk-pins {
samsung,pins = "gpd1-2", "gpd1-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- lcd_clk: lcd-clk {
+ lcd_clk: lcd-clk-pins {
samsung,pins = "gpf0-0", "gpf0-1", "gpf0-2", "gpf0-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- lcd_data16: lcd-data-width16 {
+ lcd_data16: lcd-data-width16-pins {
samsung,pins = "gpf0-7", "gpf1-0", "gpf1-1", "gpf1-2",
"gpf1-3", "gpf1-6", "gpf1-7", "gpf2-0",
"gpf2-1", "gpf2-2", "gpf2-3", "gpf2-7",
@@ -376,7 +376,7 @@
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- lcd_data18: lcd-data-width18 {
+ lcd_data18: lcd-data-width18-pins {
samsung,pins = "gpf0-6", "gpf0-7", "gpf1-0", "gpf1-1",
"gpf1-2", "gpf1-3", "gpf1-6", "gpf1-7",
"gpf2-0", "gpf2-1", "gpf2-2", "gpf2-3",
@@ -387,7 +387,7 @@
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- lcd_data24: lcd-data-width24 {
+ lcd_data24: lcd-data-width24-pins {
samsung,pins = "gpf0-4", "gpf0-5", "gpf0-6", "gpf0-7",
"gpf1-0", "gpf1-1", "gpf1-2", "gpf1-3",
"gpf1-4", "gpf1-5", "gpf1-6", "gpf1-7",
@@ -399,14 +399,14 @@
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- lcd_ldi: lcd-ldi {
+ lcd_ldi: lcd-ldi-pins {
samsung,pins = "gpf3-4";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- cam_port_a_io: cam-port-a-io {
+ cam_port_a_io: cam-port-a-io-pins {
samsung,pins = "gpj0-0", "gpj0-1", "gpj0-2", "gpj0-3",
"gpj0-4", "gpj0-5", "gpj0-6", "gpj0-7",
"gpj1-0", "gpj1-1", "gpj1-2", "gpj1-4";
@@ -415,14 +415,14 @@
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- cam_port_a_clk_active: cam-port-a-clk-active {
+ cam_port_a_clk_active: cam-port-a-clk-active-pins {
samsung,pins = "gpj1-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
};
- cam_port_a_clk_idle: cam-port-a-clk-idle {
+ cam_port_a_clk_idle: cam-port-a-clk-idle-pins {
samsung,pins = "gpj1-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
@@ -431,7 +431,7 @@
};
&pinctrl_1 {
- gpk0: gpk0 {
+ gpk0: gpk0-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -439,7 +439,7 @@
#interrupt-cells = <2>;
};
- gpk1: gpk1 {
+ gpk1: gpk1-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -447,7 +447,7 @@
#interrupt-cells = <2>;
};
- gpk2: gpk2 {
+ gpk2: gpk2-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -455,7 +455,7 @@
#interrupt-cells = <2>;
};
- gpk3: gpk3 {
+ gpk3: gpk3-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -463,7 +463,7 @@
#interrupt-cells = <2>;
};
- gpl0: gpl0 {
+ gpl0: gpl0-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -471,7 +471,7 @@
#interrupt-cells = <2>;
};
- gpl1: gpl1 {
+ gpl1: gpl1-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -479,7 +479,7 @@
#interrupt-cells = <2>;
};
- gpl2: gpl2 {
+ gpl2: gpl2-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -487,7 +487,7 @@
#interrupt-cells = <2>;
};
- gpm0: gpm0 {
+ gpm0: gpm0-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -495,7 +495,7 @@
#interrupt-cells = <2>;
};
- gpm1: gpm1 {
+ gpm1: gpm1-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -503,7 +503,7 @@
#interrupt-cells = <2>;
};
- gpm2: gpm2 {
+ gpm2: gpm2-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -511,7 +511,7 @@
#interrupt-cells = <2>;
};
- gpm3: gpm3 {
+ gpm3: gpm3-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -519,7 +519,7 @@
#interrupt-cells = <2>;
};
- gpm4: gpm4 {
+ gpm4: gpm4-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -527,42 +527,42 @@
#interrupt-cells = <2>;
};
- gpy0: gpy0 {
+ gpy0: gpy0-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
};
- gpy1: gpy1 {
+ gpy1: gpy1-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
};
- gpy2: gpy2 {
+ gpy2: gpy2-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
};
- gpy3: gpy3 {
+ gpy3: gpy3-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
};
- gpy4: gpy4 {
+ gpy4: gpy4-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
};
- gpy5: gpy5 {
+ gpy5: gpy5-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
};
- gpy6: gpy6 {
+ gpy6: gpy6-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
};
- gpx0: gpx0 {
+ gpx0: gpx0-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -579,7 +579,7 @@
#interrupt-cells = <2>;
};
- gpx1: gpx1 {
+ gpx1: gpx1-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -596,7 +596,7 @@
#interrupt-cells = <2>;
};
- gpx2: gpx2 {
+ gpx2: gpx2-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -604,7 +604,7 @@
#interrupt-cells = <2>;
};
- gpx3: gpx3 {
+ gpx3: gpx3-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -612,203 +612,203 @@
#interrupt-cells = <2>;
};
- sd0_clk: sd0-clk {
+ sd0_clk: sd0-clk-pins {
samsung,pins = "gpk0-0";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
};
- sd0_cmd: sd0-cmd {
+ sd0_cmd: sd0-cmd-pins {
samsung,pins = "gpk0-1";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
};
- sd0_cd: sd0-cd {
+ sd0_cd: sd0-cd-pins {
samsung,pins = "gpk0-2";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
};
- sd0_bus1: sd0-bus-width1 {
+ sd0_bus1: sd0-bus-width1-pins {
samsung,pins = "gpk0-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
};
- sd0_bus4: sd0-bus-width4 {
+ sd0_bus4: sd0-bus-width4-pins {
samsung,pins = "gpk0-3", "gpk0-4", "gpk0-5", "gpk0-6";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
};
- sd0_bus8: sd0-bus-width8 {
+ sd0_bus8: sd0-bus-width8-pins {
samsung,pins = "gpk1-3", "gpk1-4", "gpk1-5", "gpk1-6";
samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
};
- sd4_clk: sd4-clk {
+ sd4_clk: sd4-clk-pins {
samsung,pins = "gpk0-0";
samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
};
- sd4_cmd: sd4-cmd {
+ sd4_cmd: sd4-cmd-pins {
samsung,pins = "gpk0-1";
samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
};
- sd4_cd: sd4-cd {
+ sd4_cd: sd4-cd-pins {
samsung,pins = "gpk0-2";
samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
};
- sd4_bus1: sd4-bus-width1 {
+ sd4_bus1: sd4-bus-width1-pins {
samsung,pins = "gpk0-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
};
- sd4_bus4: sd4-bus-width4 {
+ sd4_bus4: sd4-bus-width4-pins {
samsung,pins = "gpk0-3", "gpk0-4", "gpk0-5", "gpk0-6";
samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
};
- sd4_bus8: sd4-bus-width8 {
+ sd4_bus8: sd4-bus-width8-pins {
samsung,pins = "gpk1-3", "gpk1-4", "gpk1-5", "gpk1-6";
samsung,pin-function = <EXYNOS_PIN_FUNC_4>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
};
- sd1_clk: sd1-clk {
+ sd1_clk: sd1-clk-pins {
samsung,pins = "gpk1-0";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
};
- sd1_cmd: sd1-cmd {
+ sd1_cmd: sd1-cmd-pins {
samsung,pins = "gpk1-1";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
};
- sd1_cd: sd1-cd {
+ sd1_cd: sd1-cd-pins {
samsung,pins = "gpk1-2";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
};
- sd1_bus1: sd1-bus-width1 {
+ sd1_bus1: sd1-bus-width1-pins {
samsung,pins = "gpk1-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
};
- sd1_bus4: sd1-bus-width4 {
+ sd1_bus4: sd1-bus-width4-pins {
samsung,pins = "gpk1-3", "gpk1-4", "gpk1-5", "gpk1-6";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
};
- sd2_clk: sd2-clk {
+ sd2_clk: sd2-clk-pins {
samsung,pins = "gpk2-0";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
};
- sd2_cmd: sd2-cmd {
+ sd2_cmd: sd2-cmd-pins {
samsung,pins = "gpk2-1";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
};
- sd2_cd: sd2-cd {
+ sd2_cd: sd2-cd-pins {
samsung,pins = "gpk2-2";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
};
- sd2_bus1: sd2-bus-width1 {
+ sd2_bus1: sd2-bus-width1-pins {
samsung,pins = "gpk2-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
};
- sd2_bus4: sd2-bus-width4 {
+ sd2_bus4: sd2-bus-width4-pins {
samsung,pins = "gpk2-3", "gpk2-4", "gpk2-5", "gpk2-6";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
};
- sd2_bus8: sd2-bus-width8 {
+ sd2_bus8: sd2-bus-width8-pins {
samsung,pins = "gpk3-3", "gpk3-4", "gpk3-5", "gpk3-6";
samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
};
- sd3_clk: sd3-clk {
+ sd3_clk: sd3-clk-pins {
samsung,pins = "gpk3-0";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
};
- sd3_cmd: sd3-cmd {
+ sd3_cmd: sd3-cmd-pins {
samsung,pins = "gpk3-1";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
};
- sd3_cd: sd3-cd {
+ sd3_cd: sd3-cd-pins {
samsung,pins = "gpk3-2";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
};
- sd3_bus1: sd3-bus-width1 {
+ sd3_bus1: sd3-bus-width1-pins {
samsung,pins = "gpk3-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
};
- sd3_bus4: sd3-bus-width4 {
+ sd3_bus4: sd3-bus-width4-pins {
samsung,pins = "gpk3-3", "gpk3-4", "gpk3-5", "gpk3-6";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
};
- cam_port_b_io: cam-port-b-io {
+ cam_port_b_io: cam-port-b-io-pins {
samsung,pins = "gpm0-0", "gpm0-1", "gpm0-2", "gpm0-3",
"gpm0-4", "gpm0-5", "gpm0-6", "gpm0-7",
"gpm1-0", "gpm1-1", "gpm2-0", "gpm2-1";
@@ -817,77 +817,77 @@
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- cam_port_b_clk_active: cam-port-b-clk-active {
+ cam_port_b_clk_active: cam-port-b-clk-active-pins {
samsung,pins = "gpm2-2";
samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
};
- cam_port_b_clk_idle: cam-port-b-clk-idle {
+ cam_port_b_clk_idle: cam-port-b-clk-idle-pins {
samsung,pins = "gpm2-2";
samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- eint0: ext-int0 {
+ eint0: ext-int0-pins {
samsung,pins = "gpx0-0";
samsung,pin-function = <EXYNOS_PIN_FUNC_F>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- eint8: ext-int8 {
+ eint8: ext-int8-pins {
samsung,pins = "gpx1-0";
samsung,pin-function = <EXYNOS_PIN_FUNC_F>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- eint15: ext-int15 {
+ eint15: ext-int15-pins {
samsung,pins = "gpx1-7";
samsung,pin-function = <EXYNOS_PIN_FUNC_F>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- eint16: ext-int16 {
+ eint16: ext-int16-pins {
samsung,pins = "gpx2-0";
samsung,pin-function = <EXYNOS_PIN_FUNC_F>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- eint31: ext-int31 {
+ eint31: ext-int31-pins {
samsung,pins = "gpx3-7";
samsung,pin-function = <EXYNOS_PIN_FUNC_F>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- fimc_is_i2c0: fimc-is-i2c0 {
+ fimc_is_i2c0: fimc-is-i2c0-pins {
samsung,pins = "gpm4-0", "gpm4-1";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- fimc_is_i2c1: fimc-is-i2c1 {
+ fimc_is_i2c1: fimc-is-i2c1-pins {
samsung,pins = "gpm4-2", "gpm4-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- fimc_is_uart: fimc-is-uart {
+ fimc_is_uart: fimc-is-uart-pins {
samsung,pins = "gpm3-5", "gpm3-7";
samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- hdmi_cec: hdmi-cec {
+ hdmi_cec: hdmi-cec-pins {
samsung,pins = "gpx3-6";
samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
@@ -896,7 +896,7 @@
};
&pinctrl_2 {
- gpz: gpz {
+ gpz: gpz-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -904,7 +904,7 @@
#interrupt-cells = <2>;
};
- i2s0_bus: i2s0-bus {
+ i2s0_bus: i2s0-bus-pins {
samsung,pins = "gpz-0", "gpz-1", "gpz-2", "gpz-3",
"gpz-4", "gpz-5", "gpz-6";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
@@ -912,7 +912,7 @@
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- pcm0_bus: pcm0-bus {
+ pcm0_bus: pcm0-bus-pins {
samsung,pins = "gpz-0", "gpz-1", "gpz-2", "gpz-3",
"gpz-4";
samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
@@ -922,7 +922,7 @@
};
&pinctrl_3 {
- gpv0: gpv0 {
+ gpv0: gpv0-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -930,7 +930,7 @@
#interrupt-cells = <2>;
};
- gpv1: gpv1 {
+ gpv1: gpv1-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -938,7 +938,7 @@
#interrupt-cells = <2>;
};
- gpv2: gpv2 {
+ gpv2: gpv2-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -946,7 +946,7 @@
#interrupt-cells = <2>;
};
- gpv3: gpv3 {
+ gpv3: gpv3-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -954,7 +954,7 @@
#interrupt-cells = <2>;
};
- gpv4: gpv4 {
+ gpv4: gpv4-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -962,7 +962,7 @@
#interrupt-cells = <2>;
};
- c2c_bus: c2c-bus {
+ c2c_bus: c2c-bus-pins {
samsung,pins = "gpv0-0", "gpv0-1", "gpv0-2", "gpv0-3",
"gpv0-4", "gpv0-5", "gpv0-6", "gpv0-7",
"gpv1-0", "gpv1-1", "gpv1-2", "gpv1-3",
diff --git a/arch/arm/boot/dts/exynos4412-smdk4412.dts b/arch/arm/boot/dts/exynos4412-smdk4412.dts
index cc99b955af0c..a40ff394977c 100644
--- a/arch/arm/boot/dts/exynos4412-smdk4412.dts
+++ b/arch/arm/boot/dts/exynos4412-smdk4412.dts
@@ -133,14 +133,14 @@
};
&pinctrl_1 {
- keypad_rows: keypad-rows {
+ keypad_rows: keypad-rows-pins {
samsung,pins = "gpx2-0", "gpx2-1", "gpx2-2";
samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- keypad_cols: keypad-cols {
+ keypad_cols: keypad-cols-pins {
samsung,pins = "gpx1-0", "gpx1-1", "gpx1-2", "gpx1-3",
"gpx1-4", "gpx1-5", "gpx1-6", "gpx1-7";
samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
diff --git a/arch/arm/boot/dts/exynos4412.dtsi b/arch/arm/boot/dts/exynos4412.dtsi
index d3802046c8b8..aa0b61b59970 100644
--- a/arch/arm/boot/dts/exynos4412.dtsi
+++ b/arch/arm/boot/dts/exynos4412.dtsi
@@ -813,7 +813,7 @@
interrupt-parent = <&combiner>;
interrupts = <2 4>;
reg = <0x100C0000 0x100>;
- clocks = <&clock 383>;
+ clocks = <&clock CLK_TMU_APBIF>;
clock-names = "tmu_apbif";
status = "disabled";
};
diff --git a/arch/arm/boot/dts/exynos5250-arndale.dts b/arch/arm/boot/dts/exynos5250-arndale.dts
index 3583095fbb2a..f7795f2d0f0e 100644
--- a/arch/arm/boot/dts/exynos5250-arndale.dts
+++ b/arch/arm/boot/dts/exynos5250-arndale.dts
@@ -590,7 +590,7 @@
};
&pinctrl_0 {
- s5m8767_irq: s5m8767-irq {
+ s5m8767_irq: s5m8767-irq-pins {
samsung,pins = "gpx3-2";
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
};
@@ -632,3 +632,8 @@
#size-cells = <0>;
};
};
+
+&usbdrd {
+ vdd10-supply = <&ldo15_reg>;
+ vdd33-supply = <&ldo12_reg>;
+};
diff --git a/arch/arm/boot/dts/exynos5250-pinctrl.dtsi b/arch/arm/boot/dts/exynos5250-pinctrl.dtsi
index d31a68672bfa..918947a3897e 100644
--- a/arch/arm/boot/dts/exynos5250-pinctrl.dtsi
+++ b/arch/arm/boot/dts/exynos5250-pinctrl.dtsi
@@ -12,7 +12,7 @@
#include <dt-bindings/pinctrl/samsung.h>
&pinctrl_0 {
- gpa0: gpa0 {
+ gpa0: gpa0-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -20,7 +20,7 @@
#interrupt-cells = <2>;
};
- gpa1: gpa1 {
+ gpa1: gpa1-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -28,7 +28,7 @@
#interrupt-cells = <2>;
};
- gpa2: gpa2 {
+ gpa2: gpa2-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -36,7 +36,7 @@
#interrupt-cells = <2>;
};
- gpb0: gpb0 {
+ gpb0: gpb0-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -44,7 +44,7 @@
#interrupt-cells = <2>;
};
- gpb1: gpb1 {
+ gpb1: gpb1-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -52,7 +52,7 @@
#interrupt-cells = <2>;
};
- gpb2: gpb2 {
+ gpb2: gpb2-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -60,7 +60,7 @@
#interrupt-cells = <2>;
};
- gpb3: gpb3 {
+ gpb3: gpb3-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -68,7 +68,7 @@
#interrupt-cells = <2>;
};
- gpc0: gpc0 {
+ gpc0: gpc0-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -76,7 +76,7 @@
#interrupt-cells = <2>;
};
- gpc1: gpc1 {
+ gpc1: gpc1-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -84,7 +84,7 @@
#interrupt-cells = <2>;
};
- gpc2: gpc2 {
+ gpc2: gpc2-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -92,7 +92,7 @@
#interrupt-cells = <2>;
};
- gpc3: gpc3 {
+ gpc3: gpc3-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -100,7 +100,7 @@
#interrupt-cells = <2>;
};
- gpd0: gpd0 {
+ gpd0: gpd0-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -108,7 +108,7 @@
#interrupt-cells = <2>;
};
- gpd1: gpd1 {
+ gpd1: gpd1-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -116,42 +116,42 @@
#interrupt-cells = <2>;
};
- gpy0: gpy0 {
+ gpy0: gpy0-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
};
- gpy1: gpy1 {
+ gpy1: gpy1-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
};
- gpy2: gpy2 {
+ gpy2: gpy2-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
};
- gpy3: gpy3 {
+ gpy3: gpy3-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
};
- gpy4: gpy4 {
+ gpy4: gpy4-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
};
- gpy5: gpy5 {
+ gpy5: gpy5-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
};
- gpy6: gpy6 {
+ gpy6: gpy6-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
};
- gpc4: gpc4 {
+ gpc4: gpc4-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -159,7 +159,7 @@
#interrupt-cells = <2>;
};
- gpx0: gpx0 {
+ gpx0: gpx0-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -170,7 +170,7 @@
<26 0>, <26 1>, <27 0>, <27 1>;
};
- gpx1: gpx1 {
+ gpx1: gpx1-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -181,7 +181,7 @@
<30 0>, <30 1>, <31 0>, <31 1>;
};
- gpx2: gpx2 {
+ gpx2: gpx2-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -189,7 +189,7 @@
#interrupt-cells = <2>;
};
- gpx3: gpx3 {
+ gpx3: gpx3-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -197,104 +197,104 @@
#interrupt-cells = <2>;
};
- uart0_data: uart0-data {
+ uart0_data: uart0-data-pins {
samsung,pins = "gpa0-0", "gpa0-1";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- uart0_fctl: uart0-fctl {
+ uart0_fctl: uart0-fctl-pins {
samsung,pins = "gpa0-2", "gpa0-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- i2c2_bus: i2c2-bus {
+ i2c2_bus: i2c2-bus-pins {
samsung,pins = "gpa0-6", "gpa0-7";
samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- i2c2_hs_bus: i2c2-hs-bus {
+ i2c2_hs_bus: i2c2-hs-bus-pins {
samsung,pins = "gpa0-6", "gpa0-7";
samsung,pin-function = <EXYNOS_PIN_FUNC_4>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- i2c2_gpio_bus: i2c2-gpio-bus {
+ i2c2_gpio_bus: i2c2-gpio-bus-pins {
samsung,pins = "gpa0-6", "gpa0-7";
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- uart2_data: uart2-data {
+ uart2_data: uart2-data-pins {
samsung,pins = "gpa1-0", "gpa1-1";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- uart2_fctl: uart2-fctl {
+ uart2_fctl: uart2-fctl-pins {
samsung,pins = "gpa1-2", "gpa1-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- i2c3_bus: i2c3-bus {
+ i2c3_bus: i2c3-bus-pins {
samsung,pins = "gpa1-2", "gpa1-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- i2c3_hs_bus: i2c3-hs-bus {
+ i2c3_hs_bus: i2c3-hs-bus-pins {
samsung,pins = "gpa1-2", "gpa1-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_4>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- uart3_data: uart3-data {
- samsung,pins = "gpa1-4", "gpa1-4";
+ uart3_data: uart3-data-pins {
+ samsung,pins = "gpa1-4", "gpa1-5";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- spi0_bus: spi0-bus {
+ spi0_bus: spi0-bus-pins {
samsung,pins = "gpa2-0", "gpa2-2", "gpa2-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- i2c4_bus: i2c4-bus {
+ i2c4_bus: i2c4-bus-pins {
samsung,pins = "gpa2-0", "gpa2-1";
samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- i2c5_bus: i2c5-bus {
+ i2c5_bus: i2c5-bus-pins {
samsung,pins = "gpa2-2", "gpa2-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- spi1_bus: spi1-bus {
+ spi1_bus: spi1-bus-pins {
samsung,pins = "gpa2-4", "gpa2-6", "gpa2-7";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- i2s1_bus: i2s1-bus {
+ i2s1_bus: i2s1-bus-pins {
samsung,pins = "gpb0-0", "gpb0-1", "gpb0-2", "gpb0-3",
"gpb0-4";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
@@ -302,7 +302,7 @@
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- pcm1_bus: pcm1-bus {
+ pcm1_bus: pcm1-bus-pins {
samsung,pins = "gpb0-0", "gpb0-1", "gpb0-2", "gpb0-3",
"gpb0-4";
samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
@@ -310,7 +310,7 @@
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- ac97_bus: ac97-bus {
+ ac97_bus: ac97-bus-pins {
samsung,pins = "gpb0-0", "gpb0-1", "gpb0-2", "gpb0-3",
"gpb0-4";
samsung,pin-function = <EXYNOS_PIN_FUNC_4>;
@@ -318,7 +318,7 @@
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- i2s2_bus: i2s2-bus {
+ i2s2_bus: i2s2-bus-pins {
samsung,pins = "gpb1-0", "gpb1-1", "gpb1-2", "gpb1-3",
"gpb1-4";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
@@ -326,7 +326,7 @@
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- pcm2_bus: pcm2-bus {
+ pcm2_bus: pcm2-bus-pins {
samsung,pins = "gpb1-0", "gpb1-1", "gpb1-2", "gpb1-3",
"gpb1-4";
samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
@@ -334,280 +334,280 @@
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- spdif_bus: spdif-bus {
+ spdif_bus: spdif-bus-pins {
samsung,pins = "gpb1-0", "gpb1-1";
samsung,pin-function = <EXYNOS_PIN_FUNC_4>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- spi2_bus: spi2-bus {
+ spi2_bus: spi2-bus-pins {
samsung,pins = "gpb1-1", "gpb1-3", "gpb1-4";
samsung,pin-function = <EXYNOS_PIN_FUNC_5>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- i2c6_bus: i2c6-bus {
+ i2c6_bus: i2c6-bus-pins {
samsung,pins = "gpb1-3", "gpb1-4";
samsung,pin-function = <EXYNOS_PIN_FUNC_4>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- pwm0_out: pwm0-out {
+ pwm0_out: pwm0-out-pins {
samsung,pins = "gpb2-0";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- pwm1_out: pwm1-out {
+ pwm1_out: pwm1-out-pins {
samsung,pins = "gpb2-1";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- pwm2_out: pwm2-out {
+ pwm2_out: pwm2-out-pins {
samsung,pins = "gpb2-2";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- pwm3_out: pwm3-out {
+ pwm3_out: pwm3-out-pins {
samsung,pins = "gpb2-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- i2c7_bus: i2c7-bus {
+ i2c7_bus: i2c7-bus-pins {
samsung,pins = "gpb2-2", "gpb2-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- i2c0_bus: i2c0-bus {
+ i2c0_bus: i2c0-bus-pins {
samsung,pins = "gpb3-0", "gpb3-1";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- i2c1_bus: i2c1-bus {
+ i2c1_bus: i2c1-bus-pins {
samsung,pins = "gpb3-2", "gpb3-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- i2c0_hs_bus: i2c0-hs-bus {
+ i2c0_hs_bus: i2c0-hs-bus-pins {
samsung,pins = "gpb3-0", "gpb3-1";
samsung,pin-function = <EXYNOS_PIN_FUNC_4>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- i2c1_hs_bus: i2c1-hs-bus {
+ i2c1_hs_bus: i2c1-hs-bus-pins {
samsung,pins = "gpb3-2", "gpb3-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_4>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- sd0_clk: sd0-clk {
+ sd0_clk: sd0-clk-pins {
samsung,pins = "gpc0-0";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
};
- sd0_cmd: sd0-cmd {
+ sd0_cmd: sd0-cmd-pins {
samsung,pins = "gpc0-1";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
};
- sd0_cd: sd0-cd {
+ sd0_cd: sd0-cd-pins {
samsung,pins = "gpc0-2";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
};
- sd0_bus1: sd0-bus-width1 {
+ sd0_bus1: sd0-bus-width1-pins {
samsung,pins = "gpc0-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
};
- sd0_bus4: sd0-bus-width4 {
+ sd0_bus4: sd0-bus-width4-pins {
samsung,pins = "gpc0-3", "gpc0-4", "gpc0-5", "gpc0-6";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
};
- sd0_bus8: sd0-bus-width8 {
+ sd0_bus8: sd0-bus-width8-pins {
samsung,pins = "gpc1-0", "gpc1-1", "gpc1-2", "gpc1-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
};
- sd1_clk: sd1-clk {
+ sd1_clk: sd1-clk-pins {
samsung,pins = "gpc2-0";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
};
- sd1_cmd: sd1-cmd {
+ sd1_cmd: sd1-cmd-pins {
samsung,pins = "gpc2-1";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
};
- sd1_cd: sd1-cd {
+ sd1_cd: sd1-cd-pins {
samsung,pins = "gpc2-2";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
};
- sd1_bus1: sd1-bus-width1 {
+ sd1_bus1: sd1-bus-width1-pins {
samsung,pins = "gpc2-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
};
- sd1_bus4: sd1-bus-width4 {
+ sd1_bus4: sd1-bus-width4-pins {
samsung,pins = "gpc2-3", "gpc2-4", "gpc2-5", "gpc2-6";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
};
- sd2_clk: sd2-clk {
+ sd2_clk: sd2-clk-pins {
samsung,pins = "gpc3-0";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
};
- sd2_cmd: sd2-cmd {
+ sd2_cmd: sd2-cmd-pins {
samsung,pins = "gpc3-1";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
};
- sd2_cd: sd2-cd {
+ sd2_cd: sd2-cd-pins {
samsung,pins = "gpc3-2";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
};
- sd2_bus1: sd2-bus-width1 {
+ sd2_bus1: sd2-bus-width1-pins {
samsung,pins = "gpc3-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
};
- sd2_bus4: sd2-bus-width4 {
+ sd2_bus4: sd2-bus-width4-pins {
samsung,pins = "gpc3-3", "gpc3-4", "gpc3-5", "gpc3-6";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
};
- sd2_bus8: sd2-bus-width8 {
+ sd2_bus8: sd2-bus-width8-pins {
samsung,pins = "gpc4-3", "gpc4-4", "gpc4-5", "gpc4-6";
samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
};
- sd3_clk: sd3-clk {
+ sd3_clk: sd3-clk-pins {
samsung,pins = "gpc4-0";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
};
- sd3_cmd: sd3-cmd {
+ sd3_cmd: sd3-cmd-pins {
samsung,pins = "gpc4-1";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
};
- sd3_cd: sd3-cd {
+ sd3_cd: sd3-cd-pins {
samsung,pins = "gpc4-2";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
};
- sd3_bus1: sd3-bus-width1 {
+ sd3_bus1: sd3-bus-width1-pins {
samsung,pins = "gpc4-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
};
- sd3_bus4: sd3-bus-width4 {
+ sd3_bus4: sd3-bus-width4-pins {
samsung,pins = "gpc4-3", "gpc4-4", "gpc4-5", "gpc4-6";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
};
- uart1_data: uart1-data {
+ uart1_data: uart1-data-pins {
samsung,pins = "gpd0-0", "gpd0-1";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- uart1_fctl: uart1-fctl {
+ uart1_fctl: uart1-fctl-pins {
samsung,pins = "gpd0-2", "gpd0-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- dp_hpd: dp_hpd {
+ dp_hpd: dp-hpd-pins {
samsung,pins = "gpx0-7";
samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- hdmi_cec: hdmi-cec {
+ hdmi_cec: hdmi-cec-pins {
samsung,pins = "gpx3-6";
samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- hdmi_hpd: hdmi-hpd {
+ hdmi_hpd: hdmi-hpd-pins {
samsung,pins = "gpx3-7";
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
};
};
&pinctrl_1 {
- gpe0: gpe0 {
+ gpe0: gpe0-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -615,7 +615,7 @@
#interrupt-cells = <2>;
};
- gpe1: gpe1 {
+ gpe1: gpe1-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -623,7 +623,7 @@
#interrupt-cells = <2>;
};
- gpf0: gpf0 {
+ gpf0: gpf0-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -631,7 +631,7 @@
#interrupt-cells = <2>;
};
- gpf1: gpf1 {
+ gpf1: gpf1-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -639,7 +639,7 @@
#interrupt-cells = <2>;
};
- gpg0: gpg0 {
+ gpg0: gpg0-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -647,7 +647,7 @@
#interrupt-cells = <2>;
};
- gpg1: gpg1 {
+ gpg1: gpg1-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -655,7 +655,7 @@
#interrupt-cells = <2>;
};
- gpg2: gpg2 {
+ gpg2: gpg2-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -663,7 +663,7 @@
#interrupt-cells = <2>;
};
- gph0: gph0 {
+ gph0: gph0-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -671,7 +671,7 @@
#interrupt-cells = <2>;
};
- gph1: gph1 {
+ gph1: gph1-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -679,7 +679,7 @@
#interrupt-cells = <2>;
};
- cam_gpio_a: cam-gpio-a {
+ cam_gpio_a: cam-gpio-a-pins {
samsung,pins = "gpe0-0", "gpe0-1", "gpe0-2", "gpe0-3",
"gpe0-4", "gpe0-5", "gpe0-6", "gpe0-7",
"gpe1-0", "gpe1-1";
@@ -688,7 +688,7 @@
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- cam_gpio_b: cam-gpio-b {
+ cam_gpio_b: cam-gpio-b-pins {
samsung,pins = "gpf0-0", "gpf0-1", "gpf0-2", "gpf0-3",
"gpf1-0", "gpf1-1", "gpf1-2", "gpf1-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
@@ -696,42 +696,42 @@
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- cam_i2c2_bus: cam-i2c2-bus {
+ cam_i2c2_bus: cam-i2c2-bus-pins {
samsung,pins = "gpe0-6", "gpe1-0";
samsung,pin-function = <EXYNOS_PIN_FUNC_4>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- cam_spi1_bus: cam-spi1-bus {
+ cam_spi1_bus: cam-spi1-bus-pins {
samsung,pins = "gpe0-4", "gpe0-5", "gpf0-2", "gpf0-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_4>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- cam_i2c1_bus: cam-i2c1-bus {
+ cam_i2c1_bus: cam-i2c1-bus-pins {
samsung,pins = "gpf0-2", "gpf0-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- cam_i2c0_bus: cam-i2c0-bus {
+ cam_i2c0_bus: cam-i2c0-bus-pins {
samsung,pins = "gpf0-0", "gpf0-1";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- cam_spi0_bus: cam-spi0-bus {
+ cam_spi0_bus: cam-spi0-bus-pins {
samsung,pins = "gpf1-0", "gpf1-1", "gpf1-2", "gpf1-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- cam_bayrgb_bus: cam-bayrgb-bus {
+ cam_bayrgb_bus: cam-bayrgb-bus-pins {
samsung,pins = "gpg0-0", "gpg0-1", "gpg0-2", "gpg0-3",
"gpg0-4", "gpg0-5", "gpg0-6", "gpg0-7",
"gpg1-0", "gpg1-1", "gpg1-2", "gpg1-3",
@@ -742,7 +742,7 @@
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- cam_port_a: cam-port-a {
+ cam_port_a: cam-port-a-pins {
samsung,pins = "gph0-0", "gph0-1", "gph0-2", "gph0-3",
"gph1-0", "gph1-1", "gph1-2", "gph1-3",
"gph1-4", "gph1-5", "gph1-6", "gph1-7";
@@ -753,7 +753,7 @@
};
&pinctrl_2 {
- gpv0: gpv0 {
+ gpv0: gpv0-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -761,7 +761,7 @@
#interrupt-cells = <2>;
};
- gpv1: gpv1 {
+ gpv1: gpv1-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -769,7 +769,7 @@
#interrupt-cells = <2>;
};
- gpv2: gpv2 {
+ gpv2: gpv2-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -777,7 +777,7 @@
#interrupt-cells = <2>;
};
- gpv3: gpv3 {
+ gpv3: gpv3-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -785,7 +785,7 @@
#interrupt-cells = <2>;
};
- gpv4: gpv4 {
+ gpv4: gpv4-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -793,7 +793,7 @@
#interrupt-cells = <2>;
};
- c2c_rxd: c2c-rxd {
+ c2c_rxd: c2c-rxd-pins {
samsung,pins = "gpv0-0", "gpv0-1", "gpv0-2", "gpv0-3",
"gpv0-4", "gpv0-5", "gpv0-6", "gpv0-7",
"gpv1-0", "gpv1-1", "gpv1-2", "gpv1-3",
@@ -803,7 +803,7 @@
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- c2c_txd: c2c-txd {
+ c2c_txd: c2c-txd-pins {
samsung,pins = "gpv2-0", "gpv2-1", "gpv2-2", "gpv2-3",
"gpv2-4", "gpv2-5", "gpv2-6", "gpv2-7",
"gpv3-0", "gpv3-1", "gpv3-2", "gpv3-3",
@@ -815,7 +815,7 @@
};
&pinctrl_3 {
- gpz: gpz {
+ gpz: gpz-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -823,7 +823,7 @@
#interrupt-cells = <2>;
};
- i2s0_bus: i2s0-bus {
+ i2s0_bus: i2s0-bus-pins {
samsung,pins = "gpz-0", "gpz-1", "gpz-2", "gpz-3",
"gpz-4", "gpz-5", "gpz-6";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
diff --git a/arch/arm/boot/dts/exynos5250-smdk5250.dts b/arch/arm/boot/dts/exynos5250-smdk5250.dts
index 39bbe18145cf..21fbbf3d8684 100644
--- a/arch/arm/boot/dts/exynos5250-smdk5250.dts
+++ b/arch/arm/boot/dts/exynos5250-smdk5250.dts
@@ -118,6 +118,9 @@
status = "okay";
ddc = <&i2c_2>;
hpd-gpios = <&gpx3 7 GPIO_ACTIVE_HIGH>;
+ vdd-supply = <&ldo8_reg>;
+ vdd_osc-supply = <&ldo10_reg>;
+ vdd_pll-supply = <&ldo8_reg>;
};
&i2c_0 {
@@ -410,10 +413,15 @@
};
&pinctrl_0 {
- max77686_irq: max77686-irq {
+ max77686_irq: max77686-irq-pins {
samsung,pins = "gpx3-2";
samsung,pin-function = <EXYNOS_PIN_FUNC_F>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
};
+
+&usbdrd {
+ vdd10-supply = <&ldo15_reg>;
+ vdd33-supply = <&ldo12_reg>;
+};
diff --git a/arch/arm/boot/dts/exynos5250-snow-common.dtsi b/arch/arm/boot/dts/exynos5250-snow-common.dtsi
index 2335c4687349..c15ecfc4077d 100644
--- a/arch/arm/boot/dts/exynos5250-snow-common.dtsi
+++ b/arch/arm/boot/dts/exynos5250-snow-common.dtsi
@@ -587,63 +587,63 @@
};
&pinctrl_0 {
- wifi_en: wifi-en {
+ wifi_en: wifi-en-pins {
samsung,pins = "gpx0-1";
samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- wifi_rst: wifi-rst {
+ wifi_rst: wifi-rst-pins {
samsung,pins = "gpx0-2";
samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- power_key_irq: power-key-irq {
+ power_key_irq: power-key-irq-pins {
samsung,pins = "gpx1-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_F>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- ec_irq: ec-irq {
+ ec_irq: ec-irq-pins {
samsung,pins = "gpx1-6";
samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- tps65090_irq: tps65090-irq {
+ tps65090_irq: tps65090-irq-pins {
samsung,pins = "gpx2-6";
samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- usb3_vbus_en: usb3-vbus-en {
+ usb3_vbus_en: usb3-vbus-en-pins {
samsung,pins = "gpx2-7";
samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- max77686_irq: max77686-irq {
+ max77686_irq: max77686-irq-pins {
samsung,pins = "gpx3-2";
samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- lid_irq: lid-irq {
+ lid_irq: lid-irq-pins {
samsung,pins = "gpx3-5";
samsung,pin-function = <EXYNOS_PIN_FUNC_F>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- hdmi_hpd_irq: hdmi-hpd-irq {
+ hdmi_hpd_irq: hdmi-hpd-irq-pins {
samsung,pins = "gpx3-7";
samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
@@ -652,14 +652,14 @@
};
&pinctrl_1 {
- arb_their_claim: arb-their-claim {
+ arb_their_claim: arb-their-claim-pins {
samsung,pins = "gpe0-4";
samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- arb_our_claim: arb-our-claim {
+ arb_our_claim: arb-our-claim-pins {
samsung,pins = "gpf0-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
@@ -698,6 +698,11 @@
cs-gpios = <&gpa2 5 GPIO_ACTIVE_HIGH>;
};
+&usbdrd {
+ vdd10-supply = <&ldo15_reg>;
+ vdd33-supply = <&ldo12_reg>;
+};
+
&usbdrd_dwc3 {
dr_mode = "host";
};
diff --git a/arch/arm/boot/dts/exynos5250-snow-rev5.dts b/arch/arm/boot/dts/exynos5250-snow-rev5.dts
index f8ca61df6981..0a47597d6f0d 100644
--- a/arch/arm/boot/dts/exynos5250-snow-rev5.dts
+++ b/arch/arm/boot/dts/exynos5250-snow-rev5.dts
@@ -47,7 +47,7 @@
};
&pinctrl_0 {
- max98090_irq: max98090-irq {
+ max98090_irq: max98090-irq-pins {
samsung,pins = "gpx0-4";
samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
diff --git a/arch/arm/boot/dts/exynos5250-snow.dts b/arch/arm/boot/dts/exynos5250-snow.dts
index a630bc654a49..906aa7aae710 100644
--- a/arch/arm/boot/dts/exynos5250-snow.dts
+++ b/arch/arm/boot/dts/exynos5250-snow.dts
@@ -43,7 +43,7 @@
};
&pinctrl_0 {
- max98095_en: max98095-en {
+ max98095_en: max98095-en-pins {
samsung,pins = "gpx1-7";
samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
diff --git a/arch/arm/boot/dts/exynos5250-spring.dts b/arch/arm/boot/dts/exynos5250-spring.dts
index e0feedcf54bb..24609bb20158 100644
--- a/arch/arm/boot/dts/exynos5250-spring.dts
+++ b/arch/arm/boot/dts/exynos5250-spring.dts
@@ -451,63 +451,63 @@
};
&pinctrl_0 {
- s5m8767_dvs: s5m8767-dvs {
+ s5m8767_dvs: s5m8767-dvs-pins {
samsung,pins = "gpd1-0", "gpd1-1", "gpd1-2";
samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- dp_hpd_gpio: dp-hpd {
+ dp_hpd_gpio: dp-hpd-pins {
samsung,pins = "gpc3-0";
samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- trackpad_irq: trackpad-irq {
+ trackpad_irq: trackpad-irq-pins {
samsung,pins = "gpx1-2";
samsung,pin-function = <EXYNOS_PIN_FUNC_F>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- power_key_irq: power-key-irq {
+ power_key_irq: power-key-irq-pins {
samsung,pins = "gpx1-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_F>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- ec_irq: ec-irq {
+ ec_irq: ec-irq-pins {
samsung,pins = "gpx1-6";
samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- s5m8767_ds: s5m8767-ds {
+ s5m8767_ds: s5m8767-ds-pins {
samsung,pins = "gpx2-3", "gpx2-4", "gpx2-5";
samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- s5m8767_irq: s5m8767-irq {
+ s5m8767_irq: s5m8767-irq-pins {
samsung,pins = "gpx3-2";
samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- lid_irq: lid-irq {
+ lid_irq: lid-irq-pins {
samsung,pins = "gpx3-5";
samsung,pin-function = <EXYNOS_PIN_FUNC_F>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- hdmi_hpd_irq: hdmi-hpd-irq {
+ hdmi_hpd_irq: hdmi-hpd-irq-pins {
samsung,pins = "gpx3-7";
samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
@@ -516,7 +516,7 @@
};
&pinctrl_1 {
- hsic_reset: hsic-reset {
+ hsic_reset: hsic-reset-pins {
samsung,pins = "gpe1-0";
samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
@@ -553,4 +553,9 @@
num-cs = <1>;
};
+&usbdrd {
+ vdd10-supply = <&ldo15_reg>;
+ vdd33-supply = <&ldo12_reg>;
+};
+
#include "cros-ec-keyboard.dtsi"
diff --git a/arch/arm/boot/dts/exynos5250.dtsi b/arch/arm/boot/dts/exynos5250.dtsi
index 139778928b93..5baaa7eb71a4 100644
--- a/arch/arm/boot/dts/exynos5250.dtsi
+++ b/arch/arm/boot/dts/exynos5250.dtsi
@@ -496,8 +496,7 @@
status = "disabled";
reg = <0x12d20000 0x100>;
interrupts = <GIC_SPI 66 IRQ_TYPE_LEVEL_HIGH>;
- dmas = <&pdma0 5
- &pdma0 4>;
+ dmas = <&pdma0 5>, <&pdma0 4>;
dma-names = "tx", "rx";
#address-cells = <1>;
#size-cells = <0>;
@@ -512,8 +511,7 @@
status = "disabled";
reg = <0x12d30000 0x100>;
interrupts = <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>;
- dmas = <&pdma1 5
- &pdma1 4>;
+ dmas = <&pdma1 5>, <&pdma1 4>;
dma-names = "tx", "rx";
#address-cells = <1>;
#size-cells = <0>;
@@ -528,8 +526,7 @@
status = "disabled";
reg = <0x12d40000 0x100>;
interrupts = <GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>;
- dmas = <&pdma0 7
- &pdma0 6>;
+ dmas = <&pdma0 7>, <&pdma0 6>;
dma-names = "tx", "rx";
#address-cells = <1>;
#size-cells = <0>;
@@ -637,7 +634,7 @@
#sound-dai-cells = <1>;
};
- usb_dwc3 {
+ usbdrd: usb3 {
compatible = "samsung,exynos5250-dwusb3";
clocks = <&clock CLK_USB3>;
clock-names = "usbdrd30";
@@ -695,7 +692,7 @@
samsung,pmureg-phandle = <&pmu_system_controller>;
};
- pdma0: pdma@121a0000 {
+ pdma0: dma-controller@121a0000 {
compatible = "arm,pl330", "arm,primecell";
reg = <0x121A0000 0x1000>;
interrupts = <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>;
@@ -706,7 +703,7 @@
#dma-requests = <32>;
};
- pdma1: pdma@121b0000 {
+ pdma1: dma-controller@121b0000 {
compatible = "arm,pl330", "arm,primecell";
reg = <0x121B0000 0x1000>;
interrupts = <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>;
@@ -717,7 +714,7 @@
#dma-requests = <32>;
};
- mdma0: mdma@10800000 {
+ mdma0: dma-controller@10800000 {
compatible = "arm,pl330", "arm,primecell";
reg = <0x10800000 0x1000>;
interrupts = <GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>;
@@ -728,7 +725,7 @@
#dma-requests = <1>;
};
- mdma1: mdma@11c10000 {
+ mdma1: dma-controller@11c10000 {
compatible = "arm,pl330", "arm,primecell";
reg = <0x11C10000 0x1000>;
interrupts = <GIC_SPI 124 IRQ_TYPE_LEVEL_HIGH>;
diff --git a/arch/arm/boot/dts/exynos5260-pinctrl.dtsi b/arch/arm/boot/dts/exynos5260-pinctrl.dtsi
index 17e2f3e0d71e..150607f8103d 100644
--- a/arch/arm/boot/dts/exynos5260-pinctrl.dtsi
+++ b/arch/arm/boot/dts/exynos5260-pinctrl.dtsi
@@ -12,7 +12,7 @@
#include <dt-bindings/pinctrl/samsung.h>
&pinctrl_0 {
- gpa0: gpa0 {
+ gpa0: gpa0-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -20,7 +20,7 @@
#interrupt-cells = <2>;
};
- gpa1: gpa1 {
+ gpa1: gpa1-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -28,7 +28,7 @@
#interrupt-cells = <2>;
};
- gpa2: gpa2 {
+ gpa2: gpa2-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -36,7 +36,7 @@
#interrupt-cells = <2>;
};
- gpb0: gpb0 {
+ gpb0: gpb0-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -44,7 +44,7 @@
#interrupt-cells = <2>;
};
- gpb1: gpb1 {
+ gpb1: gpb1-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -52,7 +52,7 @@
#interrupt-cells = <2>;
};
- gpb2: gpb2 {
+ gpb2: gpb2-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -60,7 +60,7 @@
#interrupt-cells = <2>;
};
- gpb3: gpb3 {
+ gpb3: gpb3-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -68,7 +68,7 @@
#interrupt-cells = <2>;
};
- gpb4: gpb4 {
+ gpb4: gpb4-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -76,7 +76,7 @@
#interrupt-cells = <2>;
};
- gpb5: gpb5 {
+ gpb5: gpb5-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -84,7 +84,7 @@
#interrupt-cells = <2>;
};
- gpd0: gpd0 {
+ gpd0: gpd0-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -92,7 +92,7 @@
#interrupt-cells = <2>;
};
- gpd1: gpd1 {
+ gpd1: gpd1-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -100,7 +100,7 @@
#interrupt-cells = <2>;
};
- gpd2: gpd2 {
+ gpd2: gpd2-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -108,7 +108,7 @@
#interrupt-cells = <2>;
};
- gpe0: gpe0 {
+ gpe0: gpe0-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -116,7 +116,7 @@
#interrupt-cells = <2>;
};
- gpe1: gpe1 {
+ gpe1: gpe1-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -124,7 +124,7 @@
#interrupt-cells = <2>;
};
- gpf0: gpf0 {
+ gpf0: gpf0-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -132,7 +132,7 @@
#interrupt-cells = <2>;
};
- gpf1: gpf1 {
+ gpf1: gpf1-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -140,7 +140,7 @@
#interrupt-cells = <2>;
};
- gpk0: gpk0 {
+ gpk0: gpk0-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -148,7 +148,7 @@
#interrupt-cells = <2>;
};
- gpx0: gpx0 {
+ gpx0: gpx0-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -164,7 +164,7 @@
#interrupt-cells = <2>;
};
- gpx1: gpx1 {
+ gpx1: gpx1-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -180,7 +180,7 @@
#interrupt-cells = <2>;
};
- gpx2: gpx2 {
+ gpx2: gpx2-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -188,7 +188,7 @@
#interrupt-cells = <2>;
};
- gpx3: gpx3 {
+ gpx3: gpx3-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -196,63 +196,63 @@
#interrupt-cells = <2>;
};
- uart0_data: uart0-data {
+ uart0_data: uart0-data-pins {
samsung,pins = "gpa0-0", "gpa0-1";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS5260_PIN_DRV_LV1>;
};
- uart0_fctl: uart0-fctl {
+ uart0_fctl: uart0-fctl-pins {
samsung,pins = "gpa0-2", "gpa0-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS5260_PIN_DRV_LV1>;
};
- uart1_data: uart1-data {
+ uart1_data: uart1-data-pins {
samsung,pins = "gpa1-0", "gpa1-1";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS5260_PIN_DRV_LV1>;
};
- uart1_fctl: uart1-fctl {
+ uart1_fctl: uart1-fctl-pins {
samsung,pins = "gpa1-2", "gpa1-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS5260_PIN_DRV_LV1>;
};
- uart2_data: uart2-data {
+ uart2_data: uart2-data-pins {
samsung,pins = "gpa1-4", "gpa1-5";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS5260_PIN_DRV_LV1>;
};
- spi0_bus: spi0-bus {
+ spi0_bus: spi0-bus-pins {
samsung,pins = "gpa2-0", "gpa2-2", "gpa2-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS5260_PIN_DRV_LV1>;
};
- spi1_bus: spi1-bus {
+ spi1_bus: spi1-bus-pins {
samsung,pins = "gpa2-4", "gpa2-6", "gpa2-7";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS5260_PIN_DRV_LV1>;
};
- usb3_vbus0_en: usb3-vbus0-en {
+ usb3_vbus0_en: usb3-vbus0-en-pins {
samsung,pins = "gpa2-4";
samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS5260_PIN_DRV_LV1>;
};
- i2s1_bus: i2s1-bus {
+ i2s1_bus: i2s1-bus-pins {
samsung,pins = "gpb0-0", "gpb0-1", "gpb0-2", "gpb0-3",
"gpb0-4";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
@@ -260,7 +260,7 @@
samsung,pin-drv = <EXYNOS5260_PIN_DRV_LV1>;
};
- pcm1_bus: pcm1-bus {
+ pcm1_bus: pcm1-bus-pins {
samsung,pins = "gpb0-0", "gpb0-1", "gpb0-2", "gpb0-3",
"gpb0-4";
samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
@@ -268,105 +268,105 @@
samsung,pin-drv = <EXYNOS5260_PIN_DRV_LV1>;
};
- spdif1_bus: spdif1-bus {
+ spdif1_bus: spdif1-bus-pins {
samsung,pins = "gpb0-0", "gpb0-1", "gpb0-2";
samsung,pin-function = <EXYNOS_PIN_FUNC_4>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS5260_PIN_DRV_LV1>;
};
- spi2_bus: spi2-bus {
+ spi2_bus: spi2-bus-pins {
samsung,pins = "gpb1-0", "gpb1-2", "gpb1-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS5260_PIN_DRV_LV1>;
};
- i2c0_hs_bus: i2c0-hs-bus {
+ i2c0_hs_bus: i2c0-hs-bus-pins {
samsung,pins = "gpb3-0", "gpb3-1";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS5260_PIN_DRV_LV1>;
};
- i2c1_hs_bus: i2c1-hs-bus {
+ i2c1_hs_bus: i2c1-hs-bus-pins {
samsung,pins = "gpb3-2", "gpb3-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS5260_PIN_DRV_LV1>;
};
- i2c2_hs_bus: i2c2-hs-bus {
+ i2c2_hs_bus: i2c2-hs-bus-pins {
samsung,pins = "gpb3-4", "gpb3-5";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS5260_PIN_DRV_LV1>;
};
- i2c3_hs_bus: i2c3-hs-bus {
+ i2c3_hs_bus: i2c3-hs-bus-pins {
samsung,pins = "gpb3-6", "gpb3-7";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS5260_PIN_DRV_LV1>;
};
- i2c4_bus: i2c4-bus {
+ i2c4_bus: i2c4-bus-pins {
samsung,pins = "gpb4-0", "gpb4-1";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS5260_PIN_DRV_LV1>;
};
- i2c5_bus: i2c5-bus {
+ i2c5_bus: i2c5-bus-pins {
samsung,pins = "gpb4-2", "gpb4-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS5260_PIN_DRV_LV1>;
};
- i2c6_bus: i2c6-bus {
+ i2c6_bus: i2c6-bus-pins {
samsung,pins = "gpb4-4", "gpb4-5";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS5260_PIN_DRV_LV1>;
};
- i2c7_bus: i2c7-bus {
+ i2c7_bus: i2c7-bus-pins {
samsung,pins = "gpb4-6", "gpb4-7";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS5260_PIN_DRV_LV1>;
};
- i2c8_bus: i2c8-bus {
+ i2c8_bus: i2c8-bus-pins {
samsung,pins = "gpb5-0", "gpb5-1";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS5260_PIN_DRV_LV1>;
};
- i2c9_bus: i2c9-bus {
+ i2c9_bus: i2c9-bus-pins {
samsung,pins = "gpb5-2", "gpb5-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS5260_PIN_DRV_LV1>;
};
- i2c10_bus: i2c10-bus {
+ i2c10_bus: i2c10-bus-pins {
samsung,pins = "gpb5-4", "gpb5-5";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS5260_PIN_DRV_LV1>;
};
- i2c11_bus: i2c11-bus {
+ i2c11_bus: i2c11-bus-pins {
samsung,pins = "gpb5-6", "gpb5-7";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS5260_PIN_DRV_LV1>;
};
- cam_gpio_a: cam-gpio-a {
+ cam_gpio_a: cam-gpio-a-pins {
samsung,pins = "gpe0-0", "gpe0-1", "gpe0-2", "gpe0-3",
"gpe0-4", "gpe0-5", "gpe0-6", "gpe0-7",
"gpe1-0", "gpe1-1";
@@ -375,7 +375,7 @@
samsung,pin-drv = <EXYNOS5260_PIN_DRV_LV1>;
};
- cam_gpio_b: cam-gpio-b {
+ cam_gpio_b: cam-gpio-b-pins {
samsung,pins = "gpf0-0", "gpf0-1", "gpf0-2", "gpf0-3",
"gpf1-0", "gpf1-1", "gpf1-2", "gpf1-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
@@ -383,28 +383,28 @@
samsung,pin-drv = <EXYNOS5260_PIN_DRV_LV1>;
};
- cam_i2c1_bus: cam-i2c1-bus {
+ cam_i2c1_bus: cam-i2c1-bus-pins {
samsung,pins = "gpf0-2", "gpf0-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS5260_PIN_DRV_LV1>;
};
- cam_i2c0_bus: cam-i2c0-bus {
+ cam_i2c0_bus: cam-i2c0-bus-pins {
samsung,pins = "gpf0-0", "gpf0-1";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS5260_PIN_DRV_LV1>;
};
- cam_spi0_bus: cam-spi0-bus {
+ cam_spi0_bus: cam-spi0-bus-pins {
samsung,pins = "gpf1-0", "gpf1-1", "gpf1-2", "gpf1-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS5260_PIN_DRV_LV1>;
};
- cam_spi1_bus: cam-spi1-bus {
+ cam_spi1_bus: cam-spi1-bus-pins {
samsung,pins = "gpf1-4", "gpf1-5", "gpf1-6", "gpf1-7";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
@@ -413,7 +413,7 @@
};
&pinctrl_1 {
- gpc0: gpc0 {
+ gpc0: gpc0-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -421,7 +421,7 @@
#interrupt-cells = <2>;
};
- gpc1: gpc1 {
+ gpc1: gpc1-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -429,7 +429,7 @@
#interrupt-cells = <2>;
};
- gpc2: gpc2 {
+ gpc2: gpc2-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -437,7 +437,7 @@
#interrupt-cells = <2>;
};
- gpc3: gpc3 {
+ gpc3: gpc3-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -445,7 +445,7 @@
#interrupt-cells = <2>;
};
- gpc4: gpc4 {
+ gpc4: gpc4-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -453,112 +453,112 @@
#interrupt-cells = <2>;
};
- sd0_clk: sd0-clk {
+ sd0_clk: sd0-clk-pins {
samsung,pins = "gpc0-0";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS5260_PIN_DRV_LV6>;
};
- sd0_cmd: sd0-cmd {
+ sd0_cmd: sd0-cmd-pins {
samsung,pins = "gpc0-1";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS5260_PIN_DRV_LV6>;
};
- sd0_bus1: sd0-bus-width1 {
+ sd0_bus1: sd0-bus-width1-pins {
samsung,pins = "gpc0-2";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS5260_PIN_DRV_LV6>;
};
- sd0_bus4: sd0-bus-width4 {
+ sd0_bus4: sd0-bus-width4-pins {
samsung,pins = "gpc0-3", "gpc0-4", "gpc0-5";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS5260_PIN_DRV_LV6>;
};
- sd0_bus8: sd0-bus-width8 {
+ sd0_bus8: sd0-bus-width8-pins {
samsung,pins = "gpc3-0", "gpc3-1", "gpc3-2", "gpc3-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS5260_PIN_DRV_LV6>;
};
- sd0_rdqs: sd0-rdqs {
+ sd0_rdqs: sd0-rdqs-pins {
samsung,pins = "gpc0-6";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS5260_PIN_DRV_LV6>;
};
- sd1_clk: sd1-clk {
+ sd1_clk: sd1-clk-pins {
samsung,pins = "gpc1-0";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS5260_PIN_DRV_LV6>;
};
- sd1_cmd: sd1-cmd {
+ sd1_cmd: sd1-cmd-pins {
samsung,pins = "gpc1-1";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS5260_PIN_DRV_LV6>;
};
- sd1_bus1: sd1-bus-width1 {
+ sd1_bus1: sd1-bus-width1-pins {
samsung,pins = "gpc1-2";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS5260_PIN_DRV_LV6>;
};
- sd1_bus4: sd1-bus-width4 {
+ sd1_bus4: sd1-bus-width4-pins {
samsung,pins = "gpc1-3", "gpc1-4", "gpc1-5";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS5260_PIN_DRV_LV6>;
};
- sd1_bus8: sd1-bus-width8 {
+ sd1_bus8: sd1-bus-width8-pins {
samsung,pins = "gpc4-0", "gpc4-1", "gpc4-2", "gpc4-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS5260_PIN_DRV_LV6>;
};
- sd2_clk: sd2-clk {
+ sd2_clk: sd2-clk-pins {
samsung,pins = "gpc2-0";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS5260_PIN_DRV_LV6>;
};
- sd2_cmd: sd2-cmd {
+ sd2_cmd: sd2-cmd-pins {
samsung,pins = "gpc2-1";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS5260_PIN_DRV_LV6>;
};
- sd2_cd: sd2-cd {
+ sd2_cd: sd2-cd-pins {
samsung,pins = "gpc2-2";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS5260_PIN_DRV_LV6>;
};
- sd2_bus1: sd2-bus-width1 {
+ sd2_bus1: sd2-bus-width1-pins {
samsung,pins = "gpc2-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS5260_PIN_DRV_LV6>;
};
- sd2_bus4: sd2-bus-width4 {
+ sd2_bus4: sd2-bus-width4-pins {
samsung,pins = "gpc2-4", "gpc2-5", "gpc2-6";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
@@ -567,7 +567,7 @@
};
&pinctrl_2 {
- gpz0: gpz0 {
+ gpz0: gpz0-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -575,7 +575,7 @@
#interrupt-cells = <2>;
};
- gpz1: gpz1 {
+ gpz1: gpz1-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
diff --git a/arch/arm/boot/dts/exynos5260-xyref5260.dts b/arch/arm/boot/dts/exynos5260-xyref5260.dts
index 0dc2ec16aa0a..3c3b751d4360 100644
--- a/arch/arm/boot/dts/exynos5260-xyref5260.dts
+++ b/arch/arm/boot/dts/exynos5260-xyref5260.dts
@@ -29,6 +29,27 @@
#clock-cells = <0>;
};
+ ioclk_pcm: clock-pcm-ext {
+ compatible = "fixed-clock";
+ clock-frequency = <2048000>;
+ clock-output-names = "ioclk_pcm_extclk";
+ #clock-cells = <0>;
+ };
+
+ ioclk_i2s: clock-i2s-cd {
+ compatible = "fixed-clock";
+ clock-frequency = <147456000>;
+ clock-output-names = "ioclk_i2s_cdclk";
+ #clock-cells = <0>;
+ };
+
+ ioclk_spdif: clock-spdif-ext {
+ compatible = "fixed-clock";
+ clock-frequency = <49152000>;
+ clock-output-names = "ioclk_spdif_extclk";
+ #clock-cells = <0>;
+ };
+
xrtcxti: xrtcxti {
compatible = "fixed-clock";
clock-frequency = <32768>;
@@ -38,7 +59,7 @@
};
&pinctrl_0 {
- hdmi_hpd_irq: hdmi-hpd-irq {
+ hdmi_hpd_irq: hdmi-hpd-irq-pins {
samsung,pins = "gpx3-7";
samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
diff --git a/arch/arm/boot/dts/exynos5260.dtsi b/arch/arm/boot/dts/exynos5260.dtsi
index 524d244050e0..56271e7c4587 100644
--- a/arch/arm/boot/dts/exynos5260.dtsi
+++ b/arch/arm/boot/dts/exynos5260.dtsi
@@ -113,78 +113,206 @@
compatible = "samsung,exynos5260-clock-top";
reg = <0x10010000 0x10000>;
#clock-cells = <1>;
+ clocks = <&fin_pll>,
+ <&clock_mif MIF_DOUT_MEM_PLL>,
+ <&clock_mif MIF_DOUT_BUS_PLL>,
+ <&clock_mif MIF_DOUT_MEDIA_PLL>;
+ clock-names = "fin_pll",
+ "dout_mem_pll",
+ "dout_bus_pll",
+ "dout_media_pll";
};
clock_peri: clock-controller@10200000 {
compatible = "samsung,exynos5260-clock-peri";
reg = <0x10200000 0x10000>;
#clock-cells = <1>;
+ clocks = <&fin_pll>,
+ <&ioclk_pcm>,
+ <&ioclk_i2s>,
+ <&ioclk_spdif>,
+ <&fin_pll>,
+ <&clock_top TOP_DOUT_ACLK_PERI_66>,
+ <&clock_top TOP_DOUT_SCLK_PERI_UART0>,
+ <&clock_top TOP_DOUT_SCLK_PERI_UART1>,
+ <&clock_top TOP_DOUT_SCLK_PERI_UART2>,
+ <&clock_top TOP_DOUT_SCLK_PERI_SPI0_B>,
+ <&clock_top TOP_DOUT_SCLK_PERI_SPI1_B>,
+ <&clock_top TOP_DOUT_SCLK_PERI_SPI2_B>,
+ <&clock_top TOP_DOUT_ACLK_PERI_AUD>;
+ clock-names = "fin_pll",
+ "ioclk_pcm_extclk",
+ "ioclk_i2s_cdclk",
+ "ioclk_spdif_extclk",
+ "phyclk_hdmi_phy_ref_cko",
+ "dout_aclk_peri_66",
+ "dout_sclk_peri_uart0",
+ "dout_sclk_peri_uart1",
+ "dout_sclk_peri_uart2",
+ "dout_sclk_peri_spi0_b",
+ "dout_sclk_peri_spi1_b",
+ "dout_sclk_peri_spi2_b",
+ "dout_aclk_peri_aud";
};
clock_egl: clock-controller@10600000 {
compatible = "samsung,exynos5260-clock-egl";
reg = <0x10600000 0x10000>;
#clock-cells = <1>;
+ clocks = <&fin_pll>,
+ <&clock_mif MIF_DOUT_BUS_PLL>;
+ clock-names = "fin_pll",
+ "dout_bus_pll";
};
clock_kfc: clock-controller@10700000 {
compatible = "samsung,exynos5260-clock-kfc";
reg = <0x10700000 0x10000>;
#clock-cells = <1>;
+ clocks = <&fin_pll>,
+ <&clock_mif MIF_DOUT_MEDIA_PLL>;
+ clock-names = "fin_pll",
+ "dout_media_pll";
};
clock_g2d: clock-controller@10a00000 {
compatible = "samsung,exynos5260-clock-g2d";
reg = <0x10A00000 0x10000>;
#clock-cells = <1>;
+ clocks = <&fin_pll>,
+ <&clock_top TOP_DOUT_ACLK_G2D_333>;
+ clock-names = "fin_pll",
+ "dout_aclk_g2d_333";
};
clock_mif: clock-controller@10ce0000 {
compatible = "samsung,exynos5260-clock-mif";
reg = <0x10CE0000 0x10000>;
#clock-cells = <1>;
+ clocks = <&fin_pll>;
+ clock-names = "fin_pll";
};
clock_mfc: clock-controller@11090000 {
compatible = "samsung,exynos5260-clock-mfc";
reg = <0x11090000 0x10000>;
#clock-cells = <1>;
+ clocks = <&fin_pll>,
+ <&clock_top TOP_DOUT_ACLK_MFC_333>;
+ clock-names = "fin_pll",
+ "dout_aclk_mfc_333";
};
clock_g3d: clock-controller@11830000 {
compatible = "samsung,exynos5260-clock-g3d";
reg = <0x11830000 0x10000>;
#clock-cells = <1>;
+ clocks = <&fin_pll>;
+ clock-names = "fin_pll";
};
clock_fsys: clock-controller@122e0000 {
compatible = "samsung,exynos5260-clock-fsys";
reg = <0x122E0000 0x10000>;
#clock-cells = <1>;
+ clocks = <&fin_pll>,
+ <&fin_pll>,
+ <&fin_pll>,
+ <&fin_pll>,
+ <&fin_pll>,
+ <&fin_pll>,
+ <&clock_top TOP_DOUT_ACLK_FSYS_200>;
+ clock-names = "fin_pll",
+ "phyclk_usbhost20_phy_phyclock",
+ "phyclk_usbhost20_phy_freeclk",
+ "phyclk_usbhost20_phy_clk48mohci",
+ "phyclk_usbdrd30_udrd30_pipe_pclk",
+ "phyclk_usbdrd30_udrd30_phyclock",
+ "dout_aclk_fsys_200";
};
clock_aud: clock-controller@128c0000 {
compatible = "samsung,exynos5260-clock-aud";
reg = <0x128C0000 0x10000>;
#clock-cells = <1>;
+ clocks = <&fin_pll>,
+ <&clock_top TOP_FOUT_AUD_PLL>,
+ <&ioclk_i2s>,
+ <&ioclk_pcm>;
+ clock-names = "fin_pll",
+ "fout_aud_pll",
+ "ioclk_i2s_cdclk",
+ "ioclk_pcm_extclk";
};
clock_isp: clock-controller@133c0000 {
compatible = "samsung,exynos5260-clock-isp";
reg = <0x133C0000 0x10000>;
#clock-cells = <1>;
+ clocks = <&fin_pll>,
+ <&clock_top TOP_DOUT_ACLK_ISP1_266>,
+ <&clock_top TOP_DOUT_ACLK_ISP1_400>,
+ <&clock_top TOP_MOUT_ACLK_ISP1_266>;
+ clock-names = "fin_pll",
+ "dout_aclk_isp1_266",
+ "dout_aclk_isp1_400",
+ "mout_aclk_isp1_266";
};
clock_gscl: clock-controller@13f00000 {
compatible = "samsung,exynos5260-clock-gscl";
reg = <0x13F00000 0x10000>;
#clock-cells = <1>;
+ clocks = <&fin_pll>,
+ <&clock_top TOP_DOUT_ACLK_GSCL_400>,
+ <&clock_top TOP_DOUT_ACLK_GSCL_333>;
+ clock-names = "fin_pll",
+ "dout_aclk_gscl_400",
+ "dout_aclk_gscl_333";
};
clock_disp: clock-controller@14550000 {
compatible = "samsung,exynos5260-clock-disp";
reg = <0x14550000 0x10000>;
#clock-cells = <1>;
+ clocks = <&fin_pll>,
+ <&fin_pll>,
+ <&fin_pll>,
+ <&fin_pll>,
+ <&fin_pll>,
+ <&fin_pll>,
+ <&fin_pll>,
+ <&fin_pll>,
+ <&fin_pll>,
+ <&fin_pll>,
+ <&fin_pll>,
+ <&fin_pll>,
+ <&fin_pll>,
+ <&fin_pll>,
+ <&ioclk_spdif>,
+ <&clock_top TOP_DOUT_ACLK_PERI_AUD>,
+ <&clock_top TOP_DOUT_ACLK_DISP_222>,
+ <&clock_top TOP_DOUT_SCLK_DISP_PIXEL>,
+ <&clock_top TOP_DOUT_ACLK_DISP_333>;
+ clock-names = "fin_pll",
+ "phyclk_dptx_phy_ch3_txd_clk",
+ "phyclk_dptx_phy_ch2_txd_clk",
+ "phyclk_dptx_phy_ch1_txd_clk",
+ "phyclk_dptx_phy_ch0_txd_clk",
+ "phyclk_hdmi_phy_tmds_clko",
+ "phyclk_hdmi_phy_ref_clko",
+ "phyclk_hdmi_phy_pixel_clko",
+ "phyclk_hdmi_link_o_tmds_clkhi",
+ "phyclk_mipi_dphy_4l_m_txbyte_clkhs",
+ "phyclk_dptx_phy_o_ref_clk_24m",
+ "phyclk_dptx_phy_clk_div2",
+ "phyclk_mipi_dphy_4l_m_rxclkesc0",
+ "phyclk_hdmi_phy_ref_cko",
+ "ioclk_spdif_extclk",
+ "dout_aclk_peri_aud",
+ "dout_aclk_disp_222",
+ "dout_sclk_disp_pixel",
+ "dout_aclk_disp_333";
};
gic: interrupt-controller@10481000 {
diff --git a/arch/arm/boot/dts/exynos5410-odroidxu.dts b/arch/arm/boot/dts/exynos5410-odroidxu.dts
index 884fef55836c..e54a3391854d 100644
--- a/arch/arm/boot/dts/exynos5410-odroidxu.dts
+++ b/arch/arm/boot/dts/exynos5410-odroidxu.dts
@@ -188,8 +188,7 @@
interrupt-parent = <&gpx0>;
interrupts = <4 IRQ_TYPE_NONE>;
pinctrl-names = "default";
- pinctrl-0 = <&max77802_irq>, <&pmic_dvs_1>, <&pmic_dvs_2>,
- <&pmic_dvs_3>;
+ pinctrl-0 = <&max77802_irq>, <&pmic_dvs_1>, <&pmic_dvs_2>;
wakeup-source;
#clock-cells = <1>;
@@ -394,10 +393,6 @@
regulator-always-on;
};
- ldo16_reg: LDO16 {
- regulator-name = "ldo16";
- };
-
ldo17_reg: LDO17 {
regulator-name = "cam_sensor_core";
regulator-min-microvolt = <1200000>;
@@ -427,10 +422,6 @@
regulator-max-microvolt = <2850000>;
};
- ldo22_reg: LDO22 {
- regulator-name = "ldo22";
- };
-
ldo23_reg: LDO23 {
regulator-name = "dp_p3v3";
regulator-min-microvolt = <3300000>;
@@ -477,10 +468,6 @@
regulator-always-on;
};
- ldo31_reg: LDO31 {
- regulator-name = "ldo31";
- };
-
/* On revisions with ti,ina231 this is sensor VS */
ldo32_reg: LDO32 {
regulator-name = "vs_power_meter";
@@ -548,14 +535,14 @@
};
&pinctrl_0 {
- emmc_nrst_pin: emmc-nrst {
+ emmc_nrst_pin: emmc-nrst-pins {
samsung,pins = "gpd1-0";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
};
- sd2_wp: sd2-wp {
+ sd2_wp: sd2-wp-pins {
samsung,pins = "gpm5-0";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
/* Pin is floating so be sure to disable write-protect */
@@ -563,21 +550,14 @@
samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV4>;
};
- pmic_dvs_3: pmic-dvs-3 {
- samsung,pins = "gpx0-0";
- samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
- samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
- samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
- };
-
- pmic_dvs_2: pmic-dvs-2 {
- samsung,pins = "gpx0-1";
+ pmic_dvs_2: pmic-dvs-2-pins {
+ samsung,pins = "gpx0-0", "gpx0-1";
samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
};
- pmic_dvs_1: pmic-dvs-1 {
+ pmic_dvs_1: pmic-dvs-1-pins {
samsung,pins = "gpx0-2";
samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
@@ -585,7 +565,7 @@
samsung,pin-val = <1>;
};
- max77802_irq: max77802-irq {
+ max77802_irq: max77802-irq-pins {
samsung,pins = "gpx0-4";
samsung,pin-function = <EXYNOS_PIN_FUNC_F>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
diff --git a/arch/arm/boot/dts/exynos5410-pinctrl.dtsi b/arch/arm/boot/dts/exynos5410-pinctrl.dtsi
index 9599ba8ba798..6c7814b4372e 100644
--- a/arch/arm/boot/dts/exynos5410-pinctrl.dtsi
+++ b/arch/arm/boot/dts/exynos5410-pinctrl.dtsi
@@ -9,7 +9,7 @@
#include <dt-bindings/pinctrl/samsung.h>
&pinctrl_0 {
- gpa0: gpa0 {
+ gpa0: gpa0-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -17,7 +17,7 @@
#interrupt-cells = <2>;
};
- gpa1: gpa1 {
+ gpa1: gpa1-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -25,7 +25,7 @@
#interrupt-cells = <2>;
};
- gpa2: gpa2 {
+ gpa2: gpa2-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -33,7 +33,7 @@
#interrupt-cells = <2>;
};
- gpb0: gpb0 {
+ gpb0: gpb0-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -41,7 +41,7 @@
#interrupt-cells = <2>;
};
- gpb1: gpb1 {
+ gpb1: gpb1-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -49,7 +49,7 @@
#interrupt-cells = <2>;
};
- gpb2: gpb2 {
+ gpb2: gpb2-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -57,7 +57,7 @@
#interrupt-cells = <2>;
};
- gpb3: gpb3 {
+ gpb3: gpb3-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -65,7 +65,7 @@
#interrupt-cells = <2>;
};
- gpc0: gpc0 {
+ gpc0: gpc0-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -73,7 +73,7 @@
#interrupt-cells = <2>;
};
- gpc3: gpc3 {
+ gpc3: gpc3-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -81,7 +81,7 @@
#interrupt-cells = <2>;
};
- gpc1: gpc1 {
+ gpc1: gpc1-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -89,7 +89,7 @@
#interrupt-cells = <2>;
};
- gpc2: gpc2 {
+ gpc2: gpc2-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -97,12 +97,12 @@
#interrupt-cells = <2>;
};
- gpm5: gpm5 {
+ gpm5: gpm5-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
};
- gpd1: gpd1 {
+ gpd1: gpd1-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -110,7 +110,7 @@
#interrupt-cells = <2>;
};
- gpe0: gpe0 {
+ gpe0: gpe0-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -118,7 +118,7 @@
#interrupt-cells = <2>;
};
- gpe1: gpe1 {
+ gpe1: gpe1-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -126,7 +126,7 @@
#interrupt-cells = <2>;
};
- gpf0: gpf0 {
+ gpf0: gpf0-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -134,7 +134,7 @@
#interrupt-cells = <2>;
};
- gpf1: gpf1 {
+ gpf1: gpf1-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -142,7 +142,7 @@
#interrupt-cells = <2>;
};
- gpg0: gpg0 {
+ gpg0: gpg0-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -150,7 +150,7 @@
#interrupt-cells = <2>;
};
- gpg1: gpg1 {
+ gpg1: gpg1-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -158,7 +158,7 @@
#interrupt-cells = <2>;
};
- gpg2: gpg2 {
+ gpg2: gpg2-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -166,7 +166,7 @@
#interrupt-cells = <2>;
};
- gph0: gph0 {
+ gph0: gph0-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -174,7 +174,7 @@
#interrupt-cells = <2>;
};
- gph1: gph1 {
+ gph1: gph1-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -182,52 +182,52 @@
#interrupt-cells = <2>;
};
- gpm7: gpm7 {
+ gpm7: gpm7-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
};
- gpy0: gpy0 {
+ gpy0: gpy0-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
};
- gpy1: gpy1 {
+ gpy1: gpy1-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
};
- gpy2: gpy2 {
+ gpy2: gpy2-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
};
- gpy3: gpy3 {
+ gpy3: gpy3-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
};
- gpy4: gpy4 {
+ gpy4: gpy4-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
};
- gpy5: gpy5 {
+ gpy5: gpy5-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
};
- gpy6: gpy6 {
+ gpy6: gpy6-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
};
- gpy7: gpy7 {
+ gpy7: gpy7-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
};
- gpx0: gpx0 {
+ gpx0: gpx0-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -244,7 +244,7 @@
<27 1>;
};
- gpx1: gpx1 {
+ gpx1: gpx1-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -261,7 +261,7 @@
<31 1>;
};
- gpx2: gpx2 {
+ gpx2: gpx2-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -269,7 +269,7 @@
#interrupt-cells = <2>;
};
- gpx3: gpx3 {
+ gpx3: gpx3-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -277,210 +277,210 @@
#interrupt-cells = <2>;
};
- uart0_data: uart0-data {
+ uart0_data: uart0-data-pins {
samsung,pins = "gpa0-0", "gpa0-1";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
};
- uart0_fctl: uart0-fctl {
+ uart0_fctl: uart0-fctl-pins {
samsung,pins = "gpa0-2", "gpa0-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
};
- uart1_data: uart1-data {
+ uart1_data: uart1-data-pins {
samsung,pins = "gpa0-4", "gpa0-5";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
};
- uart1_fctl: uart1-fctl {
+ uart1_fctl: uart1-fctl-pins {
samsung,pins = "gpa0-6", "gpa0-7";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
};
- i2c2_bus: i2c2-bus {
+ i2c2_bus: i2c2-bus-pins {
samsung,pins = "gpa0-6", "gpa0-7";
samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
};
- uart2_data: uart2-data {
+ uart2_data: uart2-data-pins {
samsung,pins = "gpa1-0", "gpa1-1";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
};
- uart2_fctl: uart2-fctl {
+ uart2_fctl: uart2-fctl-pins {
samsung,pins = "gpa1-2", "gpa1-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
};
- i2c3_bus: i2c3-bus {
+ i2c3_bus: i2c3-bus-pins {
samsung,pins = "gpa1-2", "gpa1-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
};
- uart3_data: uart3-data {
+ uart3_data: uart3-data-pins {
samsung,pins = "gpa1-4", "gpa1-5";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
};
- i2c4_hs_bus: i2c4-hs-bus {
+ i2c4_hs_bus: i2c4-hs-bus-pins {
samsung,pins = "gpa2-0", "gpa2-1";
samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
};
- i2c5_hs_bus: i2c5-hs-bus {
+ i2c5_hs_bus: i2c5-hs-bus-pins {
samsung,pins = "gpa2-2", "gpa2-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
};
- i2c6_hs_bus: i2c6-hs-bus {
+ i2c6_hs_bus: i2c6-hs-bus-pins {
samsung,pins = "gpb1-3", "gpb1-4";
samsung,pin-function = <EXYNOS_PIN_FUNC_4>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
};
- pwm0_out: pwm0-out {
+ pwm0_out: pwm0-out-pins {
samsung,pins = "gpb2-0";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
};
- pwm1_out: pwm1-out {
+ pwm1_out: pwm1-out-pins {
samsung,pins = "gpb2-1";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
};
- pwm2_out: pwm2-out {
+ pwm2_out: pwm2-out-pins {
samsung,pins = "gpb2-2";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
};
- pwm3_out: pwm3-out {
+ pwm3_out: pwm3-out-pins {
samsung,pins = "gpb2-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
};
- i2c7_hs_bus: i2c7-hs-bus {
+ i2c7_hs_bus: i2c7-hs-bus-pins {
samsung,pins = "gpb2-2", "gpb2-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
};
- i2c0_bus: i2c0-bus {
+ i2c0_bus: i2c0-bus-pins {
samsung,pins = "gpb3-0", "gpb3-1";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
};
- i2c1_bus: i2c1-bus {
+ i2c1_bus: i2c1-bus-pins {
samsung,pins = "gpb3-2", "gpb3-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
};
- sd0_clk: sd0-clk {
+ sd0_clk: sd0-clk-pins {
samsung,pins = "gpc0-0";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV4>;
};
- sd0_cmd: sd0-cmd {
+ sd0_cmd: sd0-cmd-pins {
samsung,pins = "gpc0-1";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV4>;
};
- sd0_cd: sd0-cd {
+ sd0_cd: sd0-cd-pins {
samsung,pins = "gpc0-2";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV4>;
};
- sd0_bus1: sd0-bus-width1 {
+ sd0_bus1: sd0-bus-width1-pins {
samsung,pins = "gpc0-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV4>;
};
- sd0_bus4: sd0-bus-width4 {
+ sd0_bus4: sd0-bus-width4-pins {
samsung,pins = "gpc0-4", "gpc0-5", "gpc0-6";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV4>;
};
- sd2_clk: sd2-clk {
+ sd2_clk: sd2-clk-pins {
samsung,pins = "gpc2-0";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV4>;
};
- sd2_cmd: sd2-cmd {
+ sd2_cmd: sd2-cmd-pins {
samsung,pins = "gpc2-1";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV4>;
};
- sd2_cd: sd2-cd {
+ sd2_cd: sd2-cd-pins {
samsung,pins = "gpc2-2";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV4>;
};
- sd2_bus1: sd2-bus-width1 {
+ sd2_bus1: sd2-bus-width1-pins {
samsung,pins = "gpc2-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV4>;
};
- sd2_bus4: sd2-bus-width4 {
+ sd2_bus4: sd2-bus-width4-pins {
samsung,pins = "gpc2-4", "gpc2-5", "gpc2-6";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV4>;
};
- sd0_bus8: sd0-bus-width8 {
+ sd0_bus8: sd0-bus-width8-pins {
samsung,pins = "gpc3-0", "gpc3-1", "gpc3-2", "gpc3-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
@@ -489,7 +489,7 @@
};
&pinctrl_1 {
- gpj0: gpj0 {
+ gpj0: gpj0-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -497,7 +497,7 @@
#interrupt-cells = <2>;
};
- gpj1: gpj1 {
+ gpj1: gpj1-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -505,7 +505,7 @@
#interrupt-cells = <2>;
};
- gpj2: gpj2 {
+ gpj2: gpj2-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -513,7 +513,7 @@
#interrupt-cells = <2>;
};
- gpj3: gpj3 {
+ gpj3: gpj3-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -521,7 +521,7 @@
#interrupt-cells = <2>;
};
- gpj4: gpj4 {
+ gpj4: gpj4-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -529,7 +529,7 @@
#interrupt-cells = <2>;
};
- gpk0: gpk0 {
+ gpk0: gpk0-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -537,7 +537,7 @@
#interrupt-cells = <2>;
};
- gpk1: gpk1 {
+ gpk1: gpk1-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -545,7 +545,7 @@
#interrupt-cells = <2>;
};
- gpk2: gpk2 {
+ gpk2: gpk2-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -553,7 +553,7 @@
#interrupt-cells = <2>;
};
- gpk3: gpk3 {
+ gpk3: gpk3-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -561,28 +561,28 @@
#interrupt-cells = <2>;
};
- usb3_1_oc: usb3-1-oc {
+ usb3_1_oc: usb3-1-oc-pins {
samsung,pins = "gpk2-4", "gpk2-5";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
};
- usb3_1_vbusctrl: usb3-1-vbusctrl {
+ usb3_1_vbusctrl: usb3-1-vbusctrl-pins {
samsung,pins = "gpk2-6", "gpk2-7";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
};
- usb3_0_oc: usb3-0-oc {
+ usb3_0_oc: usb3-0-oc-pins {
samsung,pins = "gpk3-0", "gpk3-1";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
};
- usb3_0_vbusctrl: usb3-0-vbusctrl {
+ usb3_0_vbusctrl: usb3-0-vbusctrl-pins {
samsung,pins = "gpk3-2", "gpk3-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
@@ -591,7 +591,7 @@
};
&pinctrl_2 {
- gpv0: gpv0 {
+ gpv0: gpv0-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -599,7 +599,7 @@
#interrupt-cells = <2>;
};
- gpv1: gpv1 {
+ gpv1: gpv1-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -607,7 +607,7 @@
#interrupt-cells = <2>;
};
- gpv2: gpv2 {
+ gpv2: gpv2-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -615,7 +615,7 @@
#interrupt-cells = <2>;
};
- gpv3: gpv3 {
+ gpv3: gpv3-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -623,7 +623,7 @@
#interrupt-cells = <2>;
};
- gpv4: gpv4 {
+ gpv4: gpv4-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -633,7 +633,7 @@
};
&pinctrl_3 {
- gpz: gpz {
+ gpz: gpz-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -641,7 +641,7 @@
#interrupt-cells = <2>;
};
- audi2s0_bus: audi2s0-bus {
+ audi2s0_bus: audi2s0-bus-pins {
samsung,pins = "gpz-0", "gpz-1", "gpz-2", "gpz-3",
"gpz-4";
samsung,pin-function = <2>;
diff --git a/arch/arm/boot/dts/exynos5410-smdk5410.dts b/arch/arm/boot/dts/exynos5410-smdk5410.dts
index 2a3ade77a2de..b8f953c41c73 100644
--- a/arch/arm/boot/dts/exynos5410-smdk5410.dts
+++ b/arch/arm/boot/dts/exynos5410-smdk5410.dts
@@ -41,6 +41,19 @@
reg = <0x02037000 0x1000>;
};
+ vdd10_usb3: voltage-regulator-0 {
+ compatible = "regulator-fixed";
+ regulator-name = "VDD10_USB3";
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1000000>;
+ };
+
+ vdd33_usb3: voltage-regulator-0 {
+ compatible = "regulator-fixed";
+ regulator-name = "VDD33_USB3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
};
&mmc_0 {
@@ -66,14 +79,14 @@
};
&pinctrl_0 {
- srom_ctl: srom-ctl {
+ srom_ctl: srom-ctl-pins {
samsung,pins = "gpy0-3", "gpy0-4", "gpy0-5",
"gpy1-0", "gpy1-1", "gpy1-2", "gpy1-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
};
- srom_ebi: srom-ebi {
+ srom_ebi: srom-ebi-pins {
samsung,pins = "gpy3-0", "gpy3-1", "gpy3-2", "gpy3-3",
"gpy3-4", "gpy3-5", "gpy3-6", "gpy3-7",
"gpy5-0", "gpy5-1", "gpy5-2", "gpy5-3",
@@ -121,3 +134,13 @@
&serial_2 {
status = "okay";
};
+
+&usbdrd3_0 {
+ vdd10-supply = <&vdd10_usb3>;
+ vdd33-supply = <&vdd33_usb3>;
+};
+
+&usbdrd3_1 {
+ vdd10-supply = <&vdd10_usb3>;
+ vdd33-supply = <&vdd33_usb3>;
+};
diff --git a/arch/arm/boot/dts/exynos5410.dtsi b/arch/arm/boot/dts/exynos5410.dtsi
index 584ce62361b1..4d797a9abba4 100644
--- a/arch/arm/boot/dts/exynos5410.dtsi
+++ b/arch/arm/boot/dts/exynos5410.dtsi
@@ -189,7 +189,7 @@
interrupts = <GIC_SPI 47 IRQ_TYPE_LEVEL_HIGH>;
};
- pdma0: pdma@121a0000 {
+ pdma0: dma-controller@121a0000 {
compatible = "arm,pl330", "arm,primecell";
reg = <0x121a0000 0x1000>;
interrupts = <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>;
@@ -200,7 +200,7 @@
#dma-requests = <32>;
};
- pdma1: pdma@121b0000 {
+ pdma1: dma-controller@121b0000 {
compatible = "arm,pl330", "arm,primecell";
reg = <0x121b0000 0x1000>;
interrupts = <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>;
diff --git a/arch/arm/boot/dts/exynos5420-arndale-octa.dts b/arch/arm/boot/dts/exynos5420-arndale-octa.dts
index dfc7f14f5772..946b791faf85 100644
--- a/arch/arm/boot/dts/exynos5420-arndale-octa.dts
+++ b/arch/arm/boot/dts/exynos5420-arndale-octa.dts
@@ -808,7 +808,7 @@
};
&pinctrl_0 {
- s2mps11_irq: s2mps11-irq {
+ s2mps11_irq: s2mps11-irq-pins {
samsung,pins = "gpx3-2";
samsung,pin-function = <EXYNOS_PIN_FUNC_F>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
@@ -825,3 +825,13 @@
&usbdrd_dwc3_1 {
dr_mode = "host";
};
+
+&usbdrd3_0 {
+ vdd10-supply = <&ldo11_reg>;
+ vdd33-supply = <&ldo9_reg>;
+};
+
+&usbdrd3_1 {
+ vdd10-supply = <&ldo11_reg>;
+ vdd33-supply = <&ldo9_reg>;
+};
diff --git a/arch/arm/boot/dts/exynos5420-chagall-wifi.dts b/arch/arm/boot/dts/exynos5420-chagall-wifi.dts
new file mode 100644
index 000000000000..1319344a2c74
--- /dev/null
+++ b/arch/arm/boot/dts/exynos5420-chagall-wifi.dts
@@ -0,0 +1,75 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Samsung's Exynos5420 Chagall WiFi board device tree source
+ *
+ * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ * Copyright (c) 2022 Henrik Grimler
+ */
+
+/dts-v1/;
+#include "exynos5420-galaxy-tab-common.dtsi"
+
+/ {
+ model = "Samsung Chagall WiFi based on Exynos5420";
+ compatible = "samsung,chagall-wifi", "samsung,exynos5420", \
+ "samsung,exynos5";
+};
+
+&ldo15_reg {
+ /* Unused */
+ regulator-name = "VDD_LDO15";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+};
+
+&ldo17_reg {
+ regulator-name = "VDD_IRLED_3V3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3350000>;
+ regulator-always-on;
+ regulator-boot-on;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+};
+
+&ldo28_reg {
+ /* Unused */
+ regulator-name = "VDD_LDO28";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+};
+
+&ldo29_reg {
+ regulator-name = "VDD_TCON_1V8";
+ regulator-min-microvolt = <1900000>;
+ regulator-max-microvolt = <1900000>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+};
+
+&ldo31_reg {
+ regulator-name = "VDD_GRIP_1V8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ regulator-boot-on;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+};
+
+&ldo32_reg {
+ regulator-name = "VDD_TSP_1V8";
+ regulator-min-microvolt = <1900000>;
+ regulator-max-microvolt = <1900000>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+};
diff --git a/arch/arm/boot/dts/exynos5420-galaxy-tab-common.dtsi b/arch/arm/boot/dts/exynos5420-galaxy-tab-common.dtsi
new file mode 100644
index 000000000000..d19bc3d266fa
--- /dev/null
+++ b/arch/arm/boot/dts/exynos5420-galaxy-tab-common.dtsi
@@ -0,0 +1,691 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Base DT for Samsung's family of tablets based on Exynos5420.
+ *
+ * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ * Copyright (c) 2022 Henrik Grimler
+ */
+
+/dts-v1/;
+#include "exynos5420.dtsi"
+#include "exynos5420-cpus.dtsi"
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/clock/samsung,s2mps11.h>
+
+/ {
+ chassis-type = "tablet";
+
+ /*
+ * To successfully boot the mainline kernel with the stock
+ * bootloader (SBOOT), the tlb needs to be flushed after the
+ * page table pointer has been updated in __common_mmu_cache_on.
+ * The same hack is also needed to boot exynos4412-i9300 with
+ * stock bootloader, and probably other Samsung devices of
+ * similar age. See
+ * https://lore.kernel.org/all/1355276466-18295-1-git-send-email-arve@android.com
+ * for more details.
+ */
+
+ chosen {
+ stdout-path = "serial2:115200n8";
+ };
+
+ memory@20000000 {
+ device_type = "memory";
+ reg = <0x20000000 0xc0000000>;
+ };
+
+ firmware@2073000 {
+ compatible = "samsung,secure-firmware";
+ reg = <0x02073000 0x1000>;
+ };
+
+ fixed-rate-clocks {
+ oscclk {
+ compatible = "samsung,exynos5420-oscclk";
+ clock-frequency = <24000000>;
+ };
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+ pinctrl-names = "default";
+
+ key-power {
+ debounce-interval = <10>;
+ gpios = <&gpx2 2 GPIO_ACTIVE_LOW>;
+ label = "Power";
+ linux,code = <KEY_POWER>;
+ wakeup-source;
+ };
+
+ key-home {
+ debounce-interval = <10>;
+ gpios = <&gpx0 5 GPIO_ACTIVE_LOW>;
+ label = "Home";
+ linux,code = <KEY_HOME>;
+ wakeup-source;
+ };
+
+ key-volume-up {
+ debounce-interval = <10>;
+ gpios = <&gpx0 2 GPIO_ACTIVE_LOW>;
+ label = "Volume Up";
+ linux,code = <KEY_VOLUMEUP>;
+ };
+
+ key-volume-down {
+ debounce-interval = <10>;
+ gpios = <&gpx0 3 GPIO_ACTIVE_LOW>;
+ label = "Volume Down";
+ linux,code = <KEY_VOLUMEDOWN>;
+ };
+ };
+};
+
+&cci {
+ /* CCI is disabled in hardware */
+ status = "disabled";
+};
+
+&cpu0 {
+ cpu-supply = <&buck2_reg>;
+};
+
+&cpu4 {
+ cpu-supply = <&buck6_reg>;
+};
+
+&gpu {
+ status = "okay";
+ mali-supply = <&buck4_reg>;
+};
+
+&hsi2c_7 {
+ status = "okay";
+
+ pmic@66 {
+ compatible = "samsung,s2mps11-pmic";
+ reg = <0x66>;
+
+ interrupt-parent = <&gpx3>;
+ interrupts = <2 IRQ_TYPE_LEVEL_LOW>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&s2mps11_irq>;
+
+ s2mps11_osc: clocks {
+ compatible = "samsung,s2mps11-clk";
+ #clock-cells = <1>;
+ clock-output-names = "s2mps11_ap", "s2mps11_cp",
+ "s2mps11_bt";
+ };
+
+ regulators {
+ buck1_reg: BUCK1 {
+ regulator-name = "VDD_MIF_1V1";
+ regulator-min-microvolt = <700000>;
+ regulator-max-microvolt = <1300000>;
+ regulator-always-on;
+ regulator-boot-on;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ buck2_reg: BUCK2 {
+ regulator-name = "VDD_ARM_1V0";
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1500000>;
+ regulator-always-on;
+ regulator-boot-on;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ buck3_reg: BUCK3 {
+ regulator-name = "VDD_INT_1V0";
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1400000>;
+ regulator-always-on;
+ regulator-boot-on;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ buck4_reg: BUCK4 {
+ regulator-name = "VDD_G3D_1V0";
+ regulator-min-microvolt = <700000>;
+ regulator-max-microvolt = <1400000>;
+ regulator-always-on;
+ regulator-boot-on;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ buck5_reg: BUCK5 {
+ regulator-name = "VDD_MEM_1V2";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-always-on;
+ regulator-boot-on;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+
+ };
+
+ buck6_reg: BUCK6 {
+ regulator-name = "VDD_KFC_1V0";
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1500000>;
+ regulator-always-on;
+ regulator-boot-on;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ buck7_reg: BUCK7 {
+ regulator-name = "VIN_LLDO_1V4";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1500000>;
+ regulator-always-on;
+ };
+
+ buck8_reg: BUCK8 {
+ regulator-name = "VIN_MLDO_2V0";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <2100000>;
+ regulator-always-on;
+ };
+
+ buck9_reg: BUCK9 {
+ regulator-name = "VIN_HLDO_3V5";
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3500000>;
+ regulator-always-on;
+ };
+
+ buck10_reg: BUCK10 {
+ regulator-name = "VDD_CAM_ISP_1V0";
+ regulator-min-microvolt = <750000>;
+ regulator-max-microvolt = <3550000>;
+ };
+
+ ldo1_reg: LDO1 {
+ regulator-name = "VDD_ALIVE_1.0V";
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1000000>;
+ regulator-always-on;
+ };
+
+ ldo2_reg: LDO2 {
+ regulator-name = "VDD_APIO_1V8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ regulator-boot-on;
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ };
+ };
+
+ ldo3_reg: LDO3 {
+ regulator-name = "VDD_APIO_MMC01_1V8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ ldo4_reg: LDO4 {
+ regulator-name = "VDD_ADC_1V8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ regulator-boot-on;
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ };
+ };
+
+ ldo5_reg: LDO5 {
+ /* Unused */
+ regulator-name = "VDD_LDO5";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ ldo6_reg: LDO6 {
+ regulator-name = "VDD_MIPI_1V0";
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1000000>;
+ regulator-always-on;
+ regulator-boot-on;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ ldo7_reg: LDO7 {
+ regulator-name = "VDD_MIPI_PLL_ABB1_18V";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ regulator-boot-on;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ ldo8_reg: LDO8 {
+ /* Unused */
+ regulator-name = "VDD_LDO8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ ldo9_reg: LDO9 {
+ regulator-name = "VDD_UOTG_3V0";
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3000000>;
+ regulator-always-on;
+ regulator-boot-on;
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ };
+ };
+
+ ldo10_reg: LDO10 {
+ regulator-name = "VDDQ_PRE_1V8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ regulator-boot-on;
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ };
+ };
+
+ ldo11_reg: LDO11 {
+ regulator-name = "VDD_HSIC_1V0";
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1000000>;
+ regulator-always-on;
+ regulator-boot-on;
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ };
+ };
+
+ ldo12_reg: LDO12 {
+ regulator-name = "VDD_HSIC_1V8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ regulator-boot-on;
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ };
+ };
+
+ ldo13_reg: LDO13 {
+ regulator-name = "VDD_APIO_MMC2_2V8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <2800000>;
+ regulator-boot-on;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ ldo14_reg: LDO14 {
+ regulator-name = "VDD_MOTOR_3V0";
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3000000>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ ldo15_reg: LDO15 {
+ regulator-name = "VDD_LDO15";
+ /*
+ * LDO15 varies between devices and is
+ * specified in the device dts
+ */
+ };
+
+ ldo16_reg: LDO16 {
+ regulator-name = "VDD_AP_2V8";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ regulator-always-on;
+ regulator-boot-on;
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ };
+ };
+
+ ldo17_reg: LDO17 {
+ regulator-name = "VDD_LDO17";
+ /*
+ * LDO17 varies between devices and is
+ * specified in the device dts
+ */
+ };
+
+ ldo18_reg: LDO18 {
+ /* Unused */
+ regulator-name = "VDD_LDO18";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ ldo19_reg: LDO19 {
+ regulator-name = "VDD_VTF_2V8";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ ldo20_reg: LDO20 {
+ regulator-name = "VDD_CAM1_CAM_1V8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ ldo21_reg: LDO21 {
+ regulator-name = "VDD_CAM_IO_1V8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ ldo22_reg: LDO22 {
+ regulator-name = "VDD_CAM0_S_CORE_1V1";
+ regulator-min-microvolt = <1050000>;
+ regulator-max-microvolt = <1200000>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ ldo23_reg: LDO23 {
+ regulator-name = "VDD_MIFS_1V1";
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1100000>;
+ regulator-always-on;
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ };
+ };
+
+ ldo24_reg: LDO24 {
+ regulator-name = "VDD_TSP_3V3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ ldo25_reg: LDO25 {
+ /* Unused */
+ regulator-name = "VDD_LDO25";
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <3950000>;
+ };
+
+ ldo26_reg: LDO26 {
+ regulator-name = "VDD_CAM0_AF_2V8";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ ldo27_reg: LDO27 {
+ regulator-name = "VDD_G3DS_1V0";
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1000000>;
+ regulator-always-on;
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ };
+ };
+
+ ldo28_reg: LDO28 {
+ regulator-name = "VDD_LDO28";
+ /*
+ * LDO28 varies between devices and is
+ * specified in the device dts
+ */
+ };
+
+ ldo29_reg: LDO29 {
+ regulator-name = "VDD_LDO29";
+ /*
+ * LDO29 varies between devices and is
+ * specified in the device dts
+ */
+ };
+
+ ldo30_reg: LDO30 {
+ regulator-name = "VDD_TOUCH_1V8";
+ regulator-min-microvolt = <1900000>;
+ regulator-max-microvolt = <1900000>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ ldo31_reg: LDO31 {
+ regulator-name = "VDD_LDO31";
+ /*
+ * LDO31 varies between devices and is
+ * specified in the device dts
+ */
+ };
+
+ ldo32_reg: LDO32 {
+ regulator-name = "VDD_LDO32";
+ /*
+ * LDO32 varies between devices and is
+ * specified in the device dts
+ */
+ };
+
+ ldo33_reg: LDO33 {
+ regulator-name = "VDD_MHL_1V8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ ldo34_reg: LDO34 {
+ regulator-name = "VDD_MHL_3V3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ ldo35_reg: LDO35 {
+ regulator-name = "VDD_SIL_1V2";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ ldo36_reg: LDO36 {
+ /* Unused */
+ regulator-name = "VDD_LDO36";
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <3950000>;
+ };
+
+ ldo37_reg: LDO37 {
+ /* Unused */
+ regulator-name = "VDD_LDO37";
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <3950000>;
+ };
+
+ ldo38_reg: LDO38 {
+ regulator-name = "VDD_KEY_LED_3V3";
+ regulator-min-microvolt = <2500000>;
+ regulator-max-microvolt = <3300000>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+ };
+ };
+};
+
+&mixer {
+ status = "okay";
+};
+
+/* Internal storage */
+&mmc_0 {
+ status = "okay";
+ bus-width = <8>;
+ cap-mmc-highspeed;
+ card-detect-delay = <200>;
+ mmc-hs200-1_8v;
+ non-removable;
+ pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus1 &sd0_bus4 &sd0_bus8>;
+ pinctrl-names = "default";
+ samsung,dw-mshc-ciu-div = <3>;
+ samsung,dw-mshc-ddr-timing = <0 2>;
+ samsung,dw-mshc-sdr-timing = <0 4>;
+ vqmmc-supply = <&ldo3_reg>;
+};
+
+/* External sdcard */
+&mmc_2 {
+ status = "okay";
+ bus-width = <4>;
+ cap-sd-highspeed;
+ card-detect-delay = <200>;
+ cd-gpios = <&gpx2 4 GPIO_ACTIVE_LOW>;
+ pinctrl-0 = <&sd2_clk &sd2_cmd &mmc2_cd &sd2_bus1 &sd2_bus4>;
+ pinctrl-names = "default";
+ samsung,dw-mshc-ciu-div = <3>;
+ samsung,dw-mshc-ddr-timing = <0 2>;
+ samsung,dw-mshc-sdr-timing = <0 4>;
+ sd-uhs-sdr50;
+ vmmc-supply = <&ldo19_reg>;
+ vqmmc-supply = <&ldo13_reg>;
+};
+
+&pinctrl_0 {
+ mmc2_cd: mmc2-cd-pins {
+ samsung,pins = "gpx2-4";
+ samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+ };
+
+ s2mps11_irq: s2mps11-irq-pins {
+ samsung,pins = "gpx3-0";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_F>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+ samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
+ };
+};
+
+&rtc {
+ status = "okay";
+ clocks = <&clock CLK_RTC>, <&s2mps11_osc S2MPS11_CLK_AP>;
+ clock-names = "rtc", "rtc_src";
+};
+
+&tmu_cpu0 {
+ vtmu-supply = <&ldo10_reg>;
+};
+
+&tmu_cpu1 {
+ vtmu-supply = <&ldo10_reg>;
+};
+
+&tmu_cpu2 {
+ vtmu-supply = <&ldo10_reg>;
+};
+
+&tmu_cpu3 {
+ vtmu-supply = <&ldo10_reg>;
+};
+
+&tmu_gpu {
+ vtmu-supply = <&ldo10_reg>;
+};
+
+&usbdrd_dwc3_0 {
+ dr_mode = "peripheral";
+};
+
+&usbdrd_dwc3_1 {
+ dr_mode = "peripheral";
+};
+
+&usbdrd3_0 {
+ vdd33-supply = <&ldo9_reg>;
+ vdd10-supply = <&ldo11_reg>;
+};
+
+&usbdrd3_1 {
+ vdd33-supply = <&ldo9_reg>;
+ vdd10-supply = <&ldo11_reg>;
+};
diff --git a/arch/arm/boot/dts/exynos5420-klimt-wifi.dts b/arch/arm/boot/dts/exynos5420-klimt-wifi.dts
new file mode 100644
index 000000000000..011787b1bbf0
--- /dev/null
+++ b/arch/arm/boot/dts/exynos5420-klimt-wifi.dts
@@ -0,0 +1,75 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Samsung's Exynos5420 Klimt WiFi board device tree source
+ *
+ * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ * Copyright (c) 2022 Henrik Grimler
+ */
+
+/dts-v1/;
+#include "exynos5420-galaxy-tab-common.dtsi"
+
+/ {
+ model = "Samsung Klimt WiFi based on Exynos5420";
+ compatible = "samsung,klimt-wifi", "samsung,exynos5420", \
+ "samsung,exynos5";
+};
+
+&ldo15_reg {
+ /* Unused */
+ regulator-name = "VDD_LDO15";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+};
+
+&ldo17_reg {
+ regulator-name = "VDD_VCI_3V0";
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3000000>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+};
+
+&ldo28_reg {
+ regulator-name = "VDD3_1V8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+};
+
+&ldo29_reg {
+ regulator-name = "VDDR_1V6";
+ regulator-min-microvolt = <1600000>;
+ regulator-max-microvolt = <1600000>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+};
+
+&ldo31_reg {
+ /* Unused */
+ regulator-name = "VDD_LDO31";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+};
+
+&ldo32_reg {
+ regulator-name = "VDD_TSP_1V8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+};
+
+&mmc_2 {
+ sd-uhs-sdr104;
+};
diff --git a/arch/arm/boot/dts/exynos5420-peach-pit.dts b/arch/arm/boot/dts/exynos5420-peach-pit.dts
index e76fb104db19..d6434ec86022 100644
--- a/arch/arm/boot/dts/exynos5420-peach-pit.dts
+++ b/arch/arm/boot/dts/exynos5420-peach-pit.dts
@@ -212,7 +212,7 @@
interrupts = <1 IRQ_TYPE_NONE>;
pinctrl-names = "default";
pinctrl-0 = <&max77802_irq>, <&pmic_selb>,
- <&pmic_dvs_1>, <&pmic_dvs_2>, <&pmic_dvs_3>;
+ <&pmic_dvs_1>, <&pmic_dvs_2>;
wakeup-source;
reg = <0x9>;
#clock-cells = <1>;
@@ -774,14 +774,14 @@
pinctrl-names = "default";
pinctrl-0 = <&mask_tpm_reset>;
- wifi_en: wifi-en {
+ wifi_en: wifi-en-pins {
samsung,pins = "gpx0-0";
samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
};
- max98090_irq: max98090-irq {
+ max98090_irq: max98090-irq-pins {
samsung,pins = "gpx0-2";
samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
@@ -789,7 +789,7 @@
};
/* We need GPX0_6 to be low at sleep time; just keep it low always */
- mask_tpm_reset: mask-tpm-reset {
+ mask_tpm_reset: mask-tpm-reset-pins {
samsung,pins = "gpx0-6";
samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
@@ -797,70 +797,70 @@
samsung,pin-val = <0>;
};
- tpm_irq: tpm-irq {
+ tpm_irq: tpm-irq-pins {
samsung,pins = "gpx1-0";
samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
};
- trackpad_irq: trackpad-irq {
+ trackpad_irq: trackpad-irq-pins {
samsung,pins = "gpx1-1";
samsung,pin-function = <EXYNOS_PIN_FUNC_F>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
};
- power_key_irq: power-key-irq {
+ power_key_irq: power-key-irq-pins {
samsung,pins = "gpx1-2";
samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
};
- ec_irq: ec-irq {
+ ec_irq: ec-irq-pins {
samsung,pins = "gpx1-5";
samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
};
- tps65090_irq: tps65090-irq {
+ tps65090_irq: tps65090-irq-pins {
samsung,pins = "gpx2-5";
samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
};
- dp_hpd_gpio: dp_hpd_gpio {
+ dp_hpd_gpio: dp-hpd-gpio-pins {
samsung,pins = "gpx2-6";
samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
};
- max77802_irq: max77802-irq {
+ max77802_irq: max77802-irq-pins {
samsung,pins = "gpx3-1";
samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
};
- lid_irq: lid-irq {
+ lid_irq: lid-irq-pins {
samsung,pins = "gpx3-4";
samsung,pin-function = <EXYNOS_PIN_FUNC_F>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
};
- hdmi_hpd_irq: hdmi-hpd-irq {
+ hdmi_hpd_irq: hdmi-hpd-irq-pins {
samsung,pins = "gpx3-7";
samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
};
- pmic_dvs_1: pmic-dvs-1 {
+ pmic_dvs_1: pmic-dvs-1-pins {
samsung,pins = "gpy7-6";
samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
@@ -868,74 +868,67 @@
};
};
-&pinctrl_1 {
- /* Adjust WiFi drive strengths lower for EMI */
- sd1_clk: sd1-clk {
- samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV3>;
- };
+/* pinctrl_1 */
+/* Adjust WiFi drive strengths lower for EMI */
+&sd1_bus1 {
+ samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV3>;
+};
- sd1_cmd: sd1-cmd {
- samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV3>;
- };
+&sd1_bus4 {
+ samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV3>;
+};
- sd1_bus1: sd1-bus-width1 {
- samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV3>;
- };
+&sd1_bus8 {
+ samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV3>;
+};
- sd1_bus4: sd1-bus-width4 {
- samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV3>;
- };
+&sd1_clk {
+ samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV3>;
+};
- sd1_bus8: sd1-bus-width8 {
- samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV3>;
- };
+&sd1_cmd {
+ samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV3>;
};
&pinctrl_2 {
- pmic_dvs_2: pmic-dvs-2 {
- samsung,pins = "gpj4-2";
+ pmic_dvs_2: pmic-dvs-2-pins {
+ samsung,pins = "gpj4-2", "gpj4-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
};
+};
- pmic_dvs_3: pmic-dvs-3 {
- samsung,pins = "gpj4-3";
- samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
- samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
- samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
- };
+/* pinctrl_3*/
+/* Drive SPI lines at x2 for better integrity */
+&spi2_bus {
+ samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV3>;
};
&pinctrl_3 {
- /* Drive SPI lines at x2 for better integrity */
- spi2-bus {
- samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV3>;
- };
-
/* Drive SPI chip select at x2 for better integrity */
- ec_spi_cs: ec-spi-cs {
+ ec_spi_cs: ec-spi-cs-pins {
samsung,pins = "gpb1-2";
samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV3>;
};
- usb300_vbus_en: usb300-vbus-en {
+ usb300_vbus_en: usb300-vbus-en-pins {
samsung,pins = "gph0-0";
samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
};
- usb301_vbus_en: usb301-vbus-en {
+ usb301_vbus_en: usb301-vbus-en-pins {
samsung,pins = "gph0-1";
samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
};
- pmic_selb: pmic-selb {
+ pmic_selb: pmic-selb-pins {
samsung,pins = "gph0-2", "gph0-3", "gph0-4", "gph0-5",
"gph0-6";
samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
@@ -1090,6 +1083,16 @@
vtmu-supply = <&ldo10_reg>;
};
+&usbdrd3_0 {
+ vdd10-supply = <&ldo15_reg>;
+ vdd33-supply = <&ldo12_reg>;
+};
+
+&usbdrd3_1 {
+ vdd10-supply = <&ldo15_reg>;
+ vdd33-supply = <&ldo12_reg>;
+};
+
&usbdrd_dwc3_0 {
dr_mode = "host";
};
diff --git a/arch/arm/boot/dts/exynos5420-pinctrl.dtsi b/arch/arm/boot/dts/exynos5420-pinctrl.dtsi
index b82af7c89654..546ba274f4e5 100644
--- a/arch/arm/boot/dts/exynos5420-pinctrl.dtsi
+++ b/arch/arm/boot/dts/exynos5420-pinctrl.dtsi
@@ -12,7 +12,7 @@
#include <dt-bindings/pinctrl/samsung.h>
&pinctrl_0 {
- gpy7: gpy7 {
+ gpy7: gpy7-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -20,7 +20,7 @@
#interrupt-cells = <2>;
};
- gpx0: gpx0 {
+ gpx0: gpx0-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -31,7 +31,7 @@
<26 0>, <26 1>, <27 0>, <27 1>;
};
- gpx1: gpx1 {
+ gpx1: gpx1-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -42,7 +42,7 @@
<30 0>, <30 1>, <31 0>, <31 1>;
};
- gpx2: gpx2 {
+ gpx2: gpx2-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -50,7 +50,7 @@
#interrupt-cells = <2>;
};
- gpx3: gpx3 {
+ gpx3: gpx3-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -58,14 +58,14 @@
#interrupt-cells = <2>;
};
- dp_hpd: dp_hpd {
+ dp_hpd: dp-hpd-pins {
samsung,pins = "gpx0-7";
samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
};
- hdmi_cec: hdmi-cec {
+ hdmi_cec: hdmi-cec-pins {
samsung,pins = "gpx3-6";
samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
@@ -74,7 +74,7 @@
};
&pinctrl_1 {
- gpc0: gpc0 {
+ gpc0: gpc0-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -82,7 +82,7 @@
#interrupt-cells = <2>;
};
- gpc1: gpc1 {
+ gpc1: gpc1-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -90,7 +90,7 @@
#interrupt-cells = <2>;
};
- gpc2: gpc2 {
+ gpc2: gpc2-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -98,7 +98,7 @@
#interrupt-cells = <2>;
};
- gpc3: gpc3 {
+ gpc3: gpc3-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -106,7 +106,7 @@
#interrupt-cells = <2>;
};
- gpc4: gpc4 {
+ gpc4: gpc4-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -114,7 +114,7 @@
#interrupt-cells = <2>;
};
- gpd1: gpd1 {
+ gpd1: gpd1-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -122,175 +122,175 @@
#interrupt-cells = <2>;
};
- gpy0: gpy0 {
+ gpy0: gpy0-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
};
- gpy1: gpy1 {
+ gpy1: gpy1-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
};
- gpy2: gpy2 {
+ gpy2: gpy2-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
};
- gpy3: gpy3 {
+ gpy3: gpy3-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
};
- gpy4: gpy4 {
+ gpy4: gpy4-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
};
- gpy5: gpy5 {
+ gpy5: gpy5-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
};
- gpy6: gpy6 {
+ gpy6: gpy6-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
};
- sd0_clk: sd0-clk {
+ sd0_clk: sd0-clk-pins {
samsung,pins = "gpc0-0";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV4>;
};
- sd0_cmd: sd0-cmd {
+ sd0_cmd: sd0-cmd-pins {
samsung,pins = "gpc0-1";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV4>;
};
- sd0_cd: sd0-cd {
+ sd0_cd: sd0-cd-pins {
samsung,pins = "gpc0-2";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV4>;
};
- sd0_bus1: sd0-bus-width1 {
+ sd0_bus1: sd0-bus-width1-pins {
samsung,pins = "gpc0-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV4>;
};
- sd0_bus4: sd0-bus-width4 {
+ sd0_bus4: sd0-bus-width4-pins {
samsung,pins = "gpc0-4", "gpc0-5", "gpc0-6";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV4>;
};
- sd0_bus8: sd0-bus-width8 {
+ sd0_bus8: sd0-bus-width8-pins {
samsung,pins = "gpc3-0", "gpc3-1", "gpc3-2", "gpc3-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV4>;
};
- sd0_rclk: sd0-rclk {
+ sd0_rclk: sd0-rclk-pins {
samsung,pins = "gpc0-7";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV4>;
};
- sd1_clk: sd1-clk {
+ sd1_clk: sd1-clk-pins {
samsung,pins = "gpc1-0";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV4>;
};
- sd1_cmd: sd1-cmd {
+ sd1_cmd: sd1-cmd-pins {
samsung,pins = "gpc1-1";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV4>;
};
- sd1_cd: sd1-cd {
+ sd1_cd: sd1-cd-pins {
samsung,pins = "gpc1-2";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV4>;
};
- sd1_int: sd1-int {
+ sd1_int: sd1-int-pins {
samsung,pins = "gpd1-1";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
};
- sd1_bus1: sd1-bus-width1 {
+ sd1_bus1: sd1-bus-width1-pins {
samsung,pins = "gpc1-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV4>;
};
- sd1_bus4: sd1-bus-width4 {
+ sd1_bus4: sd1-bus-width4-pins {
samsung,pins = "gpc1-4", "gpc1-5", "gpc1-6";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV4>;
};
- sd1_bus8: sd1-bus-width8 {
+ sd1_bus8: sd1-bus-width8-pins {
samsung,pins = "gpd1-4", "gpd1-5", "gpd1-6", "gpd1-7";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV4>;
};
- sd2_clk: sd2-clk {
+ sd2_clk: sd2-clk-pins {
samsung,pins = "gpc2-0";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV4>;
};
- sd2_cmd: sd2-cmd {
+ sd2_cmd: sd2-cmd-pins {
samsung,pins = "gpc2-1";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV4>;
};
- sd2_cd: sd2-cd {
+ sd2_cd: sd2-cd-pins {
samsung,pins = "gpc2-2";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV4>;
};
- sd2_bus1: sd2-bus-width1 {
+ sd2_bus1: sd2-bus-width1-pins {
samsung,pins = "gpc2-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV4>;
};
- sd2_bus4: sd2-bus-width4 {
+ sd2_bus4: sd2-bus-width4-pins {
samsung,pins = "gpc2-4", "gpc2-5", "gpc2-6";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV4>;
};
- sd2_wp: sd2-wp {
+ sd2_wp: sd2-wp-pins {
samsung,pins = "gpc4-0";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
@@ -299,7 +299,7 @@
};
&pinctrl_2 {
- gpe0: gpe0 {
+ gpe0: gpe0-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -307,7 +307,7 @@
#interrupt-cells = <2>;
};
- gpe1: gpe1 {
+ gpe1: gpe1-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -315,7 +315,7 @@
#interrupt-cells = <2>;
};
- gpf0: gpf0 {
+ gpf0: gpf0-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -323,7 +323,7 @@
#interrupt-cells = <2>;
};
- gpf1: gpf1 {
+ gpf1: gpf1-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -331,7 +331,7 @@
#interrupt-cells = <2>;
};
- gpg0: gpg0 {
+ gpg0: gpg0-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -339,7 +339,7 @@
#interrupt-cells = <2>;
};
- gpg1: gpg1 {
+ gpg1: gpg1-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -347,7 +347,7 @@
#interrupt-cells = <2>;
};
- gpg2: gpg2 {
+ gpg2: gpg2-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -355,7 +355,7 @@
#interrupt-cells = <2>;
};
- gpj4: gpj4 {
+ gpj4: gpj4-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -363,7 +363,7 @@
#interrupt-cells = <2>;
};
- cam_gpio_a: cam-gpio-a {
+ cam_gpio_a: cam-gpio-a-pins {
samsung,pins = "gpe0-0", "gpe0-1", "gpe0-2", "gpe0-3",
"gpe0-4", "gpe0-5", "gpe0-6", "gpe0-7",
"gpe1-0", "gpe1-1";
@@ -372,7 +372,7 @@
samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
};
- cam_gpio_b: cam-gpio-b {
+ cam_gpio_b: cam-gpio-b-pins {
samsung,pins = "gpf0-0", "gpf0-1", "gpf0-2", "gpf0-3",
"gpf1-0", "gpf1-1", "gpf1-2", "gpf1-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
@@ -380,42 +380,42 @@
samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
};
- cam_i2c2_bus: cam-i2c2-bus {
+ cam_i2c2_bus: cam-i2c2-bus-pins {
samsung,pins = "gpf0-4", "gpf0-5";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
};
- cam_spi1_bus: cam-spi1-bus {
+ cam_spi1_bus: cam-spi1-bus-pins {
samsung,pins = "gpe0-4", "gpe0-5", "gpf0-2", "gpf0-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_4>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
};
- cam_i2c1_bus: cam-i2c1-bus {
+ cam_i2c1_bus: cam-i2c1-bus-pins {
samsung,pins = "gpf0-2", "gpf0-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
};
- cam_i2c0_bus: cam-i2c0-bus {
+ cam_i2c0_bus: cam-i2c0-bus-pins {
samsung,pins = "gpf0-0", "gpf0-1";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
};
- cam_spi0_bus: cam-spi0-bus {
+ cam_spi0_bus: cam-spi0-bus-pins {
samsung,pins = "gpf1-0", "gpf1-1", "gpf1-2", "gpf1-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
};
- cam_bayrgb_bus: cam-bayrgb-bus {
+ cam_bayrgb_bus: cam-bayrgb-bus-pins {
samsung,pins = "gpg0-0", "gpg0-1", "gpg0-2", "gpg0-3",
"gpg0-4", "gpg0-5", "gpg0-6", "gpg0-7",
"gpg1-0", "gpg1-1", "gpg1-2", "gpg1-3",
@@ -428,7 +428,7 @@
};
&pinctrl_3 {
- gpa0: gpa0 {
+ gpa0: gpa0-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -436,7 +436,7 @@
#interrupt-cells = <2>;
};
- gpa1: gpa1 {
+ gpa1: gpa1-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -444,7 +444,7 @@
#interrupt-cells = <2>;
};
- gpa2: gpa2 {
+ gpa2: gpa2-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -452,7 +452,7 @@
#interrupt-cells = <2>;
};
- gpb0: gpb0 {
+ gpb0: gpb0-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -460,7 +460,7 @@
#interrupt-cells = <2>;
};
- gpb1: gpb1 {
+ gpb1: gpb1-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -468,7 +468,7 @@
#interrupt-cells = <2>;
};
- gpb2: gpb2 {
+ gpb2: gpb2-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -476,7 +476,7 @@
#interrupt-cells = <2>;
};
- gpb3: gpb3 {
+ gpb3: gpb3-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -484,7 +484,7 @@
#interrupt-cells = <2>;
};
- gpb4: gpb4 {
+ gpb4: gpb4-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -492,7 +492,7 @@
#interrupt-cells = <2>;
};
- gph0: gph0 {
+ gph0: gph0-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -500,98 +500,98 @@
#interrupt-cells = <2>;
};
- uart0_data: uart0-data {
+ uart0_data: uart0-data-pins {
samsung,pins = "gpa0-0", "gpa0-1";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
};
- uart0_fctl: uart0-fctl {
+ uart0_fctl: uart0-fctl-pins {
samsung,pins = "gpa0-2", "gpa0-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
};
- uart1_data: uart1-data {
+ uart1_data: uart1-data-pins {
samsung,pins = "gpa0-4", "gpa0-5";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
};
- uart1_fctl: uart1-fctl {
+ uart1_fctl: uart1-fctl-pins {
samsung,pins = "gpa0-6", "gpa0-7";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
};
- i2c2_bus: i2c2-bus {
+ i2c2_bus: i2c2-bus-pins {
samsung,pins = "gpa0-6", "gpa0-7";
samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
};
- uart2_data: uart2-data {
+ uart2_data: uart2-data-pins {
samsung,pins = "gpa1-0", "gpa1-1";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
};
- uart2_fctl: uart2-fctl {
+ uart2_fctl: uart2-fctl-pins {
samsung,pins = "gpa1-2", "gpa1-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
};
- i2c3_bus: i2c3-bus {
+ i2c3_bus: i2c3-bus-pins {
samsung,pins = "gpa1-2", "gpa1-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
};
- uart3_data: uart3-data {
+ uart3_data: uart3-data-pins {
samsung,pins = "gpa1-4", "gpa1-5";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
};
- spi0_bus: spi0-bus {
+ spi0_bus: spi0-bus-pins {
samsung,pins = "gpa2-0", "gpa2-1", "gpa2-2", "gpa2-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
};
- spi1_bus: spi1-bus {
+ spi1_bus: spi1-bus-pins {
samsung,pins = "gpa2-4", "gpa2-6", "gpa2-7";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
};
- i2c4_hs_bus: i2c4-hs-bus {
+ i2c4_hs_bus: i2c4-hs-bus-pins {
samsung,pins = "gpa2-0", "gpa2-1";
samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
};
- i2c5_hs_bus: i2c5-hs-bus {
+ i2c5_hs_bus: i2c5-hs-bus-pins {
samsung,pins = "gpa2-2", "gpa2-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
};
- i2s1_bus: i2s1-bus {
+ i2s1_bus: i2s1-bus-pins {
samsung,pins = "gpb0-0", "gpb0-1", "gpb0-2", "gpb0-3",
"gpb0-4";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
@@ -599,7 +599,7 @@
samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
};
- pcm1_bus: pcm1-bus {
+ pcm1_bus: pcm1-bus-pins {
samsung,pins = "gpb0-0", "gpb0-1", "gpb0-2", "gpb0-3",
"gpb0-4";
samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
@@ -607,7 +607,7 @@
samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
};
- i2s2_bus: i2s2-bus {
+ i2s2_bus: i2s2-bus-pins {
samsung,pins = "gpb1-0", "gpb1-1", "gpb1-2", "gpb1-3",
"gpb1-4";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
@@ -615,7 +615,7 @@
samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
};
- pcm2_bus: pcm2-bus {
+ pcm2_bus: pcm2-bus-pins {
samsung,pins = "gpb1-0", "gpb1-1", "gpb1-2", "gpb1-3",
"gpb1-4";
samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
@@ -623,91 +623,91 @@
samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
};
- spdif_bus: spdif-bus {
+ spdif_bus: spdif-bus-pins {
samsung,pins = "gpb1-0", "gpb1-1";
samsung,pin-function = <EXYNOS_PIN_FUNC_4>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
};
- spi2_bus: spi2-bus {
+ spi2_bus: spi2-bus-pins {
samsung,pins = "gpb1-1", "gpb1-3", "gpb1-4";
samsung,pin-function = <EXYNOS_PIN_FUNC_5>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
};
- i2c6_hs_bus: i2c6-hs-bus {
+ i2c6_hs_bus: i2c6-hs-bus-pins {
samsung,pins = "gpb1-3", "gpb1-4";
samsung,pin-function = <EXYNOS_PIN_FUNC_4>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
};
- pwm0_out: pwm0-out {
+ pwm0_out: pwm0-out-pins {
samsung,pins = "gpb2-0";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
};
- pwm1_out: pwm1-out {
+ pwm1_out: pwm1-out-pins {
samsung,pins = "gpb2-1";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
};
- pwm2_out: pwm2-out {
+ pwm2_out: pwm2-out-pins {
samsung,pins = "gpb2-2";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
};
- pwm3_out: pwm3-out {
+ pwm3_out: pwm3-out-pins {
samsung,pins = "gpb2-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
};
- i2c7_hs_bus: i2c7-hs-bus {
+ i2c7_hs_bus: i2c7-hs-bus-pins {
samsung,pins = "gpb2-2", "gpb2-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
};
- i2c0_bus: i2c0-bus {
+ i2c0_bus: i2c0-bus-pins {
samsung,pins = "gpb3-0", "gpb3-1";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
};
- i2c1_bus: i2c1-bus {
+ i2c1_bus: i2c1-bus-pins {
samsung,pins = "gpb3-2", "gpb3-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
};
- i2c8_hs_bus: i2c8-hs-bus {
+ i2c8_hs_bus: i2c8-hs-bus-pins {
samsung,pins = "gpb3-4", "gpb3-5";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
};
- i2c9_hs_bus: i2c9-hs-bus {
+ i2c9_hs_bus: i2c9-hs-bus-pins {
samsung,pins = "gpb3-6", "gpb3-7";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
};
- i2c10_hs_bus: i2c10-hs-bus {
+ i2c10_hs_bus: i2c10-hs-bus-pins {
samsung,pins = "gpb4-0", "gpb4-1";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
@@ -716,7 +716,7 @@
};
&pinctrl_4 {
- gpz: gpz {
+ gpz: gpz-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -724,7 +724,7 @@
#interrupt-cells = <2>;
};
- i2s0_bus: i2s0-bus {
+ i2s0_bus: i2s0-bus-pins {
samsung,pins = "gpz-0", "gpz-1", "gpz-2", "gpz-3",
"gpz-4", "gpz-5", "gpz-6";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
diff --git a/arch/arm/boot/dts/exynos5420-smdk5420.dts b/arch/arm/boot/dts/exynos5420-smdk5420.dts
index a4f0e3ffedbd..4d7b6d9008a7 100644
--- a/arch/arm/boot/dts/exynos5420-smdk5420.dts
+++ b/arch/arm/boot/dts/exynos5420-smdk5420.dts
@@ -124,6 +124,9 @@
hpd-gpios = <&gpx3 7 GPIO_ACTIVE_HIGH>;
pinctrl-names = "default";
pinctrl-0 = <&hdmi_hpd_irq>;
+ vdd-supply = <&ldo6_reg>;
+ vdd_osc-supply = <&ldo7_reg>;
+ vdd_pll-supply = <&ldo6_reg>;
};
&hsi2c_4 {
@@ -377,7 +380,7 @@
};
&pinctrl_0 {
- hdmi_hpd_irq: hdmi-hpd-irq {
+ hdmi_hpd_irq: hdmi-hpd-irq-pins {
samsung,pins = "gpx3-7";
samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
@@ -386,14 +389,14 @@
};
&pinctrl_2 {
- usb300_vbus_en: usb300-vbus-en {
+ usb300_vbus_en: usb300-vbus-en-pins {
samsung,pins = "gpg0-5";
samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
};
- usb301_vbus_en: usb301-vbus-en {
+ usb301_vbus_en: usb301-vbus-en-pins {
samsung,pins = "gpg1-4";
samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
@@ -407,6 +410,16 @@
clock-names = "rtc", "rtc_src";
};
+&usbdrd3_0 {
+ vdd10-supply = <&ldo11_reg>;
+ vdd33-supply = <&ldo9_reg>;
+};
+
+&usbdrd3_1 {
+ vdd10-supply = <&ldo11_reg>;
+ vdd33-supply = <&ldo9_reg>;
+};
+
&usbdrd_phy0 {
vbus-supply = <&usb300_vbus_reg>;
};
diff --git a/arch/arm/boot/dts/exynos5420.dtsi b/arch/arm/boot/dts/exynos5420.dtsi
index e23e8ffb093f..21b608705049 100644
--- a/arch/arm/boot/dts/exynos5420.dtsi
+++ b/arch/arm/boot/dts/exynos5420.dtsi
@@ -302,8 +302,8 @@
clocks = <&clock CLK_PCLK_PPMU_DREX0_0>;
clock-names = "ppmu";
events {
- ppmu_event3_dmc0_0: ppmu-event3-dmc0_0 {
- event-name = "ppmu-event3-dmc0_0";
+ ppmu_event3_dmc0_0: ppmu-event3-dmc0-0 {
+ event-name = "ppmu-event3-dmc0-0";
};
};
};
@@ -314,8 +314,8 @@
clocks = <&clock CLK_PCLK_PPMU_DREX0_1>;
clock-names = "ppmu";
events {
- ppmu_event3_dmc0_1: ppmu-event3-dmc0_1 {
- event-name = "ppmu-event3-dmc0_1";
+ ppmu_event3_dmc0_1: ppmu-event3-dmc0-1 {
+ event-name = "ppmu-event3-dmc0-1";
};
};
};
@@ -326,8 +326,8 @@
clocks = <&clock CLK_PCLK_PPMU_DREX1_0>;
clock-names = "ppmu";
events {
- ppmu_event3_dmc1_0: ppmu-event3-dmc1_0 {
- event-name = "ppmu-event3-dmc1_0";
+ ppmu_event3_dmc1_0: ppmu-event3-dmc1-0 {
+ event-name = "ppmu-event3-dmc1-0";
};
};
};
@@ -338,8 +338,8 @@
clocks = <&clock CLK_PCLK_PPMU_DREX1_1>;
clock-names = "ppmu";
events {
- ppmu_event3_dmc1_1: ppmu-event3-dmc1_1 {
- event-name = "ppmu-event3-dmc1_1";
+ ppmu_event3_dmc1_1: ppmu-event3-dmc1-1 {
+ event-name = "ppmu-event3-dmc1-1";
};
};
};
@@ -430,7 +430,7 @@
power-domains = <&mau_pd>;
};
- adma: adma@3880000 {
+ adma: dma-controller@3880000 {
compatible = "arm,pl330", "arm,primecell";
reg = <0x03880000 0x1000>;
interrupts = <GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>;
@@ -442,7 +442,7 @@
power-domains = <&mau_pd>;
};
- pdma0: pdma@121a0000 {
+ pdma0: dma-controller@121a0000 {
compatible = "arm,pl330", "arm,primecell";
reg = <0x121A0000 0x1000>;
interrupts = <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>;
@@ -453,7 +453,7 @@
#dma-requests = <32>;
};
- pdma1: pdma@121b0000 {
+ pdma1: dma-controller@121b0000 {
compatible = "arm,pl330", "arm,primecell";
reg = <0x121B0000 0x1000>;
interrupts = <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>;
@@ -464,7 +464,7 @@
#dma-requests = <32>;
};
- mdma0: mdma@10800000 {
+ mdma0: dma-controller@10800000 {
compatible = "arm,pl330", "arm,primecell";
reg = <0x10800000 0x1000>;
interrupts = <GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>;
@@ -475,7 +475,7 @@
#dma-requests = <1>;
};
- mdma1: mdma@11c10000 {
+ mdma1: dma-controller@11c10000 {
compatible = "arm,pl330", "arm,primecell";
reg = <0x11C10000 0x1000>;
interrupts = <GIC_SPI 124 IRQ_TYPE_LEVEL_HIGH>;
diff --git a/arch/arm/boot/dts/exynos5422-odroid-core.dtsi b/arch/arm/boot/dts/exynos5422-odroid-core.dtsi
index e7958dbecfd2..2f65dcf6ba73 100644
--- a/arch/arm/boot/dts/exynos5422-odroid-core.dtsi
+++ b/arch/arm/boot/dts/exynos5422-odroid-core.dtsi
@@ -358,7 +358,7 @@
tCKESR-min-tck = <2>;
tMRD-min-tck = <5>;
- timings_samsung_K3QF2F20DB_800mhz: lpddr3-timings@800000000 {
+ timings_samsung_K3QF2F20DB_800mhz: timings@800000000 {
compatible = "jedec,lpddr3-timings";
/* workaround: 'reg' shows max-freq */
reg = <800000000>;
@@ -999,7 +999,7 @@
};
&pinctrl_0 {
- s2mps11_irq: s2mps11-irq {
+ s2mps11_irq: s2mps11-irq-pins {
samsung,pins = "gpx0-4";
samsung,pin-function = <EXYNOS_PIN_FUNC_F>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
diff --git a/arch/arm/boot/dts/exynos5422-odroidxu3-common.dtsi b/arch/arm/boot/dts/exynos5422-odroidxu3-common.dtsi
index e35af40a55cb..a6961ff24030 100644
--- a/arch/arm/boot/dts/exynos5422-odroidxu3-common.dtsi
+++ b/arch/arm/boot/dts/exynos5422-odroidxu3-common.dtsi
@@ -480,14 +480,14 @@
};
&pinctrl_0 {
- power_key: power-key {
+ power_key: power-key-pins {
samsung,pins = "gpx0-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
};
- hdmi_hpd_irq: hdmi-hpd-irq {
+ hdmi_hpd_irq: hdmi-hpd-irq-pins {
samsung,pins = "gpx3-7";
samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
@@ -496,7 +496,7 @@
};
&pinctrl_1 {
- emmc_nrst_pin: emmc-nrst {
+ emmc_nrst_pin: emmc-nrst-pins {
samsung,pins = "gpd1-0";
samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
diff --git a/arch/arm/boot/dts/exynos5800-peach-pi.dts b/arch/arm/boot/dts/exynos5800-peach-pi.dts
index 77013ee586f8..4ee76281979c 100644
--- a/arch/arm/boot/dts/exynos5800-peach-pi.dts
+++ b/arch/arm/boot/dts/exynos5800-peach-pi.dts
@@ -221,7 +221,7 @@
interrupts = <1 IRQ_TYPE_NONE>;
pinctrl-names = "default";
pinctrl-0 = <&max77802_irq>, <&pmic_selb>,
- <&pmic_dvs_1>, <&pmic_dvs_2>, <&pmic_dvs_3>;
+ <&pmic_dvs_1>, <&pmic_dvs_2>;
wakeup-source;
reg = <0x9>;
#clock-cells = <1>;
@@ -756,14 +756,14 @@
pinctrl-names = "default";
pinctrl-0 = <&mask_tpm_reset>;
- wifi_en: wifi-en {
+ wifi_en: wifi-en-pins {
samsung,pins = "gpx0-0";
samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
};
- max98091_irq: max98091-irq {
+ max98091_irq: max98091-irq-pins {
samsung,pins = "gpx0-2";
samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
@@ -771,7 +771,7 @@
};
/* We need GPX0_6 to be low at sleep time; just keep it low always */
- mask_tpm_reset: mask-tpm-reset {
+ mask_tpm_reset: mask-tpm-reset-pins {
samsung,pins = "gpx0-6";
samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
@@ -779,70 +779,70 @@
samsung,pin-val = <0>;
};
- tpm_irq: tpm-irq {
+ tpm_irq: tpm-irq-pins {
samsung,pins = "gpx1-0";
samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
};
- trackpad_irq: trackpad-irq {
+ trackpad_irq: trackpad-irq-pins {
samsung,pins = "gpx1-1";
samsung,pin-function = <EXYNOS_PIN_FUNC_F>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
};
- power_key_irq: power-key-irq {
+ power_key_irq: power-key-irq-pins {
samsung,pins = "gpx1-2";
samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
};
- ec_irq: ec-irq {
+ ec_irq: ec-irq-pins {
samsung,pins = "gpx1-5";
samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
};
- tps65090_irq: tps65090-irq {
+ tps65090_irq: tps65090-irq-pins {
samsung,pins = "gpx2-5";
samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
};
- dp_hpd_gpio: dp_hpd_gpio {
+ dp_hpd_gpio: dp-hpd-gpio-pins {
samsung,pins = "gpx2-6";
samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
};
- max77802_irq: max77802-irq {
+ max77802_irq: max77802-irq-pins {
samsung,pins = "gpx3-1";
samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
};
- lid_irq: lid-irq {
+ lid_irq: lid-irq-pins {
samsung,pins = "gpx3-4";
samsung,pin-function = <EXYNOS_PIN_FUNC_F>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
};
- hdmi_hpd_irq: hdmi-hpd-irq {
+ hdmi_hpd_irq: hdmi-hpd-irq-pins {
samsung,pins = "gpx3-7";
samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
};
- pmic_dvs_1: pmic-dvs-1 {
+ pmic_dvs_1: pmic-dvs-1-pins {
samsung,pins = "gpy7-6";
samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
@@ -850,74 +850,67 @@
};
};
-&pinctrl_1 {
- /* Adjust WiFi drive strengths lower for EMI */
- sd1_clk: sd1-clk {
- samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV3>;
- };
+/* pinctrl_1 */
+/* Adjust WiFi drive strengths lower for EMI */
+&sd1_bus1 {
+ samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV3>;
+};
- sd1_cmd: sd1-cmd {
- samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV3>;
- };
+&sd1_bus4 {
+ samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV3>;
+};
- sd1_bus1: sd1-bus-width1 {
- samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV3>;
- };
+&sd1_bus8 {
+ samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV3>;
+};
- sd1_bus4: sd1-bus-width4 {
- samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV3>;
- };
+&sd1_clk {
+ samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV3>;
+};
- sd1_bus8: sd1-bus-width8 {
- samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV3>;
- };
+&sd1_cmd {
+ samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV3>;
};
&pinctrl_2 {
- pmic_dvs_2: pmic-dvs-2 {
- samsung,pins = "gpj4-2";
+ pmic_dvs_2: pmic-dvs-2-pins {
+ samsung,pins = "gpj4-2", "gpj4-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
};
+};
- pmic_dvs_3: pmic-dvs-3 {
- samsung,pins = "gpj4-3";
- samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
- samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
- samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
- };
+/* pinctrl_3*/
+/* Drive SPI lines at x2 for better integrity */
+&spi2_bus {
+ samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV3>;
};
&pinctrl_3 {
- /* Drive SPI lines at x2 for better integrity */
- spi2-bus {
- samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV3>;
- };
-
/* Drive SPI chip select at x2 for better integrity */
- ec_spi_cs: ec-spi-cs {
+ ec_spi_cs: ec-spi-cs-pins {
samsung,pins = "gpb1-2";
samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV3>;
};
- usb300_vbus_en: usb300-vbus-en {
+ usb300_vbus_en: usb300-vbus-en-pins {
samsung,pins = "gph0-0";
samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
};
- usb301_vbus_en: usb301-vbus-en {
+ usb301_vbus_en: usb301-vbus-en-pins {
samsung,pins = "gph0-1";
samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
};
- pmic_selb: pmic-selb {
+ pmic_selb: pmic-selb-pins {
samsung,pins = "gph0-2", "gph0-3", "gph0-4", "gph0-5",
"gph0-6";
samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
@@ -1072,6 +1065,16 @@
vtmu-supply = <&ldo10_reg>;
};
+&usbdrd3_0 {
+ vdd10-supply = <&ldo15_reg>;
+ vdd33-supply = <&ldo12_reg>;
+};
+
+&usbdrd3_1 {
+ vdd10-supply = <&ldo15_reg>;
+ vdd33-supply = <&ldo12_reg>;
+};
+
&usbdrd_dwc3_0 {
dr_mode = "host";
};
diff --git a/arch/arm/boot/dts/imx23-evk.dts b/arch/arm/boot/dts/imx23-evk.dts
index 8cbaf1c81174..3b609d987d88 100644
--- a/arch/arm/boot/dts/imx23-evk.dts
+++ b/arch/arm/boot/dts/imx23-evk.dts
@@ -79,7 +79,6 @@
MX23_PAD_LCD_RESET__GPIO_1_18
MX23_PAD_PWM3__GPIO_1_29
MX23_PAD_PWM4__GPIO_1_30
- MX23_PAD_SSP1_DETECT__SSP1_DETECT
>;
fsl,drive-strength = <MXS_DRIVE_4mA>;
fsl,voltage = <MXS_VOLTAGE_HIGH>;
diff --git a/arch/arm/boot/dts/imx28-tx28.dts b/arch/arm/boot/dts/imx28-tx28.dts
index 9e5651c7ea6b..6d7b044fec5b 100644
--- a/arch/arm/boot/dts/imx28-tx28.dts
+++ b/arch/arm/boot/dts/imx28-tx28.dts
@@ -338,7 +338,7 @@
};
ds1339: rtc@68 {
- compatible = "mxim,ds1339";
+ compatible = "dallas,ds1339";
reg = <0x68>;
trickle-resistor-ohms = <250>;
trickle-diode-disable;
diff --git a/arch/arm/boot/dts/imx28.dtsi b/arch/arm/boot/dts/imx28.dtsi
index 84d0176d5193..130b4145af82 100644
--- a/arch/arm/boot/dts/imx28.dtsi
+++ b/arch/arm/boot/dts/imx28.dtsi
@@ -110,6 +110,8 @@
interrupt-names = "bch";
clocks = <&clks 50>;
clock-names = "gpmi_io";
+ assigned-clocks = <&clks 13>;
+ assigned-clock-parents = <&clks 10>;
dmas = <&dma_apbh 4>;
dma-names = "rx-tx";
status = "disabled";
diff --git a/arch/arm/boot/dts/imx51-ts4800.dts b/arch/arm/boot/dts/imx51-ts4800.dts
index 6ecb83e7f336..85654d6baf28 100644
--- a/arch/arm/boot/dts/imx51-ts4800.dts
+++ b/arch/arm/boot/dts/imx51-ts4800.dts
@@ -102,7 +102,7 @@
pinctrl-0 = <&pinctrl_i2c2>;
status = "okay";
- rtc: m41t00@68 {
+ rtc: rtc@68 {
compatible = "st,m41t00";
reg = <0x68>;
};
diff --git a/arch/arm/boot/dts/imx53-m53menlo.dts b/arch/arm/boot/dts/imx53-m53menlo.dts
index 4f88e96d81dd..d5c68d1ea707 100644
--- a/arch/arm/boot/dts/imx53-m53menlo.dts
+++ b/arch/arm/boot/dts/imx53-m53menlo.dts
@@ -53,6 +53,31 @@
};
};
+ lvds-decoder {
+ compatible = "ti,ds90cf364a", "lvds-decoder";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ lvds_decoder_in: endpoint {
+ remote-endpoint = <&lvds0_out>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+
+ lvds_decoder_out: endpoint {
+ remote-endpoint = <&panel_in>;
+ };
+ };
+ };
+ };
+
panel {
compatible = "edt,etm0700g0dh6";
pinctrl-0 = <&pinctrl_display_gpio>;
@@ -61,7 +86,7 @@
port {
panel_in: endpoint {
- remote-endpoint = <&lvds0_out>;
+ remote-endpoint = <&lvds_decoder_out>;
};
};
};
@@ -450,7 +475,7 @@
reg = <2>;
lvds0_out: endpoint {
- remote-endpoint = <&panel_in>;
+ remote-endpoint = <&lvds_decoder_in>;
};
};
};
diff --git a/arch/arm/boot/dts/imx53-tx53.dtsi b/arch/arm/boot/dts/imx53-tx53.dtsi
index 81c2726a328a..8712e9851465 100644
--- a/arch/arm/boot/dts/imx53-tx53.dtsi
+++ b/arch/arm/boot/dts/imx53-tx53.dtsi
@@ -241,7 +241,7 @@
clock-frequency = <400000>;
status = "okay";
- rtc1: ds1339@68 {
+ rtc1: rtc@68 {
compatible = "dallas,ds1339";
reg = <0x68>;
pinctrl-names = "default";
diff --git a/arch/arm/boot/dts/imx6dl-plym2m.dts b/arch/arm/boot/dts/imx6dl-plym2m.dts
index 60fe5f14666e..c4ce23d8ac9f 100644
--- a/arch/arm/boot/dts/imx6dl-plym2m.dts
+++ b/arch/arm/boot/dts/imx6dl-plym2m.dts
@@ -50,6 +50,11 @@
};
};
+ iio-hwmon {
+ compatible = "iio-hwmon";
+ io-channels = <&vdiv_vaccu>;
+ };
+
leds {
compatible = "gpio-leds";
pinctrl-names = "default";
@@ -101,6 +106,64 @@
regulator-min-microvolt = <12000000>;
regulator-max-microvolt = <12000000>;
};
+
+ thermal-zones {
+ chassis-thermal {
+ polling-delay = <20000>;
+ polling-delay-passive = <0>;
+ thermal-sensors = <&tsens0>;
+ };
+
+ touch-thermal0 {
+ polling-delay = <20000>;
+ polling-delay-passive = <0>;
+ thermal-sensors = <&touch_temp0>;
+ };
+
+ touch-thermal1 {
+ polling-delay = <20000>;
+ polling-delay-passive = <0>;
+ thermal-sensors = <&touch_temp1>;
+ };
+ };
+
+ touchscreen {
+ compatible = "resistive-adc-touch";
+ io-channels = <&adc_ts 1>, <&adc_ts 3>, <&adc_ts 4>,
+ <&adc_ts 5>;
+ io-channel-names = "y", "z1", "z2", "x";
+ touchscreen-min-pressure = <64687>;
+ touchscreen-inverted-x;
+ touchscreen-inverted-y;
+ touchscreen-x-plate-ohms = <300>;
+ touchscreen-y-plate-ohms = <800>;
+ };
+
+ touch_temp0: touch-temperature-sensor0 {
+ compatible = "generic-adc-thermal";
+ #thermal-sensor-cells = <0>;
+ io-channels = <&adc_ts 0>;
+ io-channel-names = "sensor-channel";
+ temperature-lookup-table = < (-40000) 736
+ 85000 474>;
+ };
+
+ touch_temp1: touch-temperature-sensor1 {
+ compatible = "generic-adc-thermal";
+ #thermal-sensor-cells = <0>;
+ io-channels = <&adc_ts 7>;
+ io-channel-names = "sensor-channel";
+ temperature-lookup-table = < (-40000) 826
+ 85000 609>;
+ };
+
+ vdiv_vaccu: voltage-divider-vaccu {
+ compatible = "voltage-divider";
+ io-channels = <&adc_ts 2>;
+ output-ohms = <2500>;
+ full-ohms = <64000>;
+ #io-channel-cells = <0>;
+ };
};
&can1 {
@@ -129,26 +192,61 @@
pinctrl-0 = <&pinctrl_ecspi2>;
status = "okay";
- touchscreen@0 {
- compatible = "ti,tsc2046";
+ adc_ts: adc@0 {
+ compatible = "ti,tsc2046e-adc";
reg = <0>;
pinctrl-0 = <&pinctrl_tsc2046>;
pinctrl-names ="default";
- spi-max-frequency = <100000>;
- interrupts-extended = <&gpio3 20 IRQ_TYPE_EDGE_FALLING>;
- pendown-gpio = <&gpio3 20 GPIO_ACTIVE_LOW>;
+ spi-max-frequency = <1000000>;
+ interrupts-extended = <&gpio3 20 IRQ_TYPE_LEVEL_LOW>;
+ #io-channel-cells = <1>;
- touchscreen-inverted-x;
- touchscreen-inverted-y;
- touchscreen-max-pressure = <4095>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ channel@0 {
+ reg = <0>;
+ settling-time-us = <300>;
+ oversampling-ratio = <5>;
+ };
- ti,vref-delay-usecs = /bits/ 16 <100>;
- ti,x-plate-ohms = /bits/ 16 <800>;
- ti,y-plate-ohms = /bits/ 16 <300>;
- ti,debounce-max = /bits/ 16 <3>;
- ti,debounce-tol = /bits/ 16 <70>;
- ti,debounce-rep = /bits/ 16 <3>;
- wakeup-source;
+ channel@1 {
+ reg = <1>;
+ settling-time-us = <700>;
+ oversampling-ratio = <5>;
+ };
+
+ channel@2 {
+ reg = <2>;
+ settling-time-us = <300>;
+ oversampling-ratio = <5>;
+ };
+
+ channel@3 {
+ reg = <3>;
+ settling-time-us = <700>;
+ oversampling-ratio = <5>;
+ };
+
+ channel@4 {
+ reg = <4>;
+ settling-time-us = <700>;
+ oversampling-ratio = <5>;
+ };
+
+ channel@5 {
+ reg = <5>;
+ settling-time-us = <700>;
+ oversampling-ratio = <5>;
+ };
+
+ /* channel 6 is not connected */
+
+ channel@7 {
+ reg = <7>;
+ settling-time-us = <300>;
+ oversampling-ratio = <5>;
+ };
};
};
@@ -233,9 +331,10 @@
pinctrl-0 = <&pinctrl_i2c3>;
status = "okay";
- temperature-sensor@70 {
+ tsens0: temperature-sensor@70 {
compatible = "ti,tmp103";
reg = <0x70>;
+ #thermal-sensor-cells = <0>;
};
};
diff --git a/arch/arm/boot/dts/imx6dl-prtvt7.dts b/arch/arm/boot/dts/imx6dl-prtvt7.dts
index 190d26642bc8..b86deebef7b7 100644
--- a/arch/arm/boot/dts/imx6dl-prtvt7.dts
+++ b/arch/arm/boot/dts/imx6dl-prtvt7.dts
@@ -6,6 +6,7 @@
/dts-v1/;
#include "imx6dl.dtsi"
#include "imx6qdl-prti6q.dtsi"
+#include <dt-bindings/display/sdtv-standards.h>
#include <dt-bindings/input/input.h>
#include <dt-bindings/leds/common.h>
#include <dt-bindings/sound/fsl-imx-audmux.h>
@@ -28,6 +29,35 @@
power-supply = <&reg_bl_12v0>;
};
+ display {
+ compatible = "fsl,imx-parallel-display";
+ pinctrl-0 = <&pinctrl_ipu1_disp>;
+ pinctrl-names = "default";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ display_in: endpoint {
+ remote-endpoint = <&ipu1_di0_disp0>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+
+ display_out: endpoint {
+ remote-endpoint = <&panel_in>;
+ };
+ };
+ };
+
+ iio-hwmon {
+ compatible = "iio-hwmon";
+ io-channels = <&vdiv_vaccu>;
+ };
+
keys {
compatible = "gpio-keys";
autorepeat;
@@ -135,6 +165,30 @@
};
};
+ panel {
+ compatible = "innolux,g070y2-t02";
+ backlight = <&backlight_lcd>;
+ power-supply = <&reg_3v3>;
+
+ port {
+ panel_in: endpoint {
+ remote-endpoint = <&display_out>;
+ };
+ };
+ };
+
+ connector {
+ compatible = "composite-video-connector";
+ label = "Composite0";
+ sdtv-standards = <SDTV_STD_PAL_B>;
+
+ port {
+ comp0_out: endpoint {
+ remote-endpoint = <&tvp5150_comp0_in>;
+ };
+ };
+ };
+
reg_bl_12v0: regulator-bl-12v0 {
compatible = "regulator-fixed";
pinctrl-names = "default";
@@ -146,6 +200,13 @@
enable-active-high;
};
+ reg_3v3: regulator-3v3 {
+ compatible = "regulator-fixed";
+ regulator-name = "3v3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
reg_1v8: regulator-1v8 {
compatible = "regulator-fixed";
regulator-name = "1v8";
@@ -179,6 +240,64 @@
frame-master;
};
};
+
+ thermal-zones {
+ chassis-thermal {
+ polling-delay = <20000>;
+ polling-delay-passive = <0>;
+ thermal-sensors = <&tsens0>;
+ };
+
+ touch-thermal0 {
+ polling-delay = <20000>;
+ polling-delay-passive = <0>;
+ thermal-sensors = <&touch_temp0>;
+ };
+
+ touch-thermal1 {
+ polling-delay = <20000>;
+ polling-delay-passive = <0>;
+ thermal-sensors = <&touch_temp1>;
+ };
+ };
+
+ touchscreen {
+ compatible = "resistive-adc-touch";
+ io-channels = <&adc_ts 1>, <&adc_ts 3>, <&adc_ts 4>,
+ <&adc_ts 5>;
+ io-channel-names = "y", "z1", "z2", "x";
+ touchscreen-min-pressure = <64687>;
+ touchscreen-inverted-x;
+ touchscreen-inverted-y;
+ touchscreen-x-plate-ohms = <300>;
+ touchscreen-y-plate-ohms = <800>;
+ };
+
+ touch_temp0: touch-temperature-sensor0 {
+ compatible = "generic-adc-thermal";
+ #thermal-sensor-cells = <0>;
+ io-channels = <&adc_ts 0>;
+ io-channel-names = "sensor-channel";
+ temperature-lookup-table = < (-40000) 736
+ 85000 474>;
+ };
+
+ touch_temp1: touch-temperature-sensor1 {
+ compatible = "generic-adc-thermal";
+ #thermal-sensor-cells = <0>;
+ io-channels = <&adc_ts 7>;
+ io-channel-names = "sensor-channel";
+ temperature-lookup-table = < (-40000) 826
+ 85000 609>;
+ };
+
+ vdiv_vaccu: voltage-divider-vaccu {
+ compatible = "voltage-divider";
+ io-channels = <&adc_ts 2>;
+ output-ohms = <2500>;
+ full-ohms = <64000>;
+ #io-channel-cells = <0>;
+ };
};
&audmux {
@@ -221,22 +340,41 @@
pinctrl-0 = <&pinctrl_ecspi2>;
status = "okay";
- touchscreen@0 {
- compatible = "ti,tsc2046";
+ adc_ts: adc@0 {
+ compatible = "ti,tsc2046e-adc";
reg = <0>;
pinctrl-0 = <&pinctrl_tsc>;
pinctrl-names ="default";
- spi-max-frequency = <100000>;
- interrupts-extended = <&gpio3 20 IRQ_TYPE_EDGE_FALLING>;
- pendown-gpio = <&gpio3 20 GPIO_ACTIVE_LOW>;
- touchscreen-max-pressure = <4095>;
- ti,vref-delay-usecs = /bits/ 16 <100>;
- ti,x-plate-ohms = /bits/ 16 <800>;
- ti,y-plate-ohms = /bits/ 16 <300>;
- ti,debounce-max = /bits/ 16 <3>;
- ti,debounce-tol = /bits/ 16 <70>;
- ti,debounce-rep = /bits/ 16 <3>;
- wakeup-source;
+ spi-max-frequency = <1000000>;
+ interrupts-extended = <&gpio3 20 IRQ_TYPE_LEVEL_LOW>;
+ #io-channel-cells = <1>;
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ channel@1 {
+ reg = <1>;
+ settling-time-us = <700>;
+ oversampling-ratio = <5>;
+ };
+
+ channel@3 {
+ reg = <3>;
+ settling-time-us = <700>;
+ oversampling-ratio = <5>;
+ };
+
+ channel@4 {
+ reg = <4>;
+ settling-time-us = <700>;
+ oversampling-ratio = <5>;
+ };
+
+ channel@5 {
+ reg = <5>;
+ settling-time-us = <700>;
+ oversampling-ratio = <5>;
+ };
};
};
@@ -252,6 +390,31 @@
VDDIO-supply = <&reg_3v3>;
VDDD-supply = <&reg_1v8>;
};
+
+ video@5c {
+ compatible = "ti,tvp5150";
+ reg = <0x5c>;
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ tvp5150_comp0_in: endpoint {
+ remote-endpoint = <&comp0_out>;
+ };
+ };
+
+ /* Output port 2 is video output pad */
+ port@2 {
+ reg = <2>;
+
+ tvp5151_to_ipu1_csi0_mux: endpoint {
+ remote-endpoint = <&ipu1_csi0_mux_from_parallel_sensor>;
+ };
+ };
+ };
};
&i2c3 {
@@ -260,6 +423,12 @@
reg = <0x51>;
};
+ tsens0: temperature-sensor@70 {
+ compatible = "ti,tmp103";
+ reg = <0x70>;
+ #thermal-sensor-cells = <0>;
+ };
+
gpio_pca: gpio@74 {
compatible = "nxp,pca9539";
reg = <0x74>;
@@ -275,6 +444,14 @@
status = "okay";
};
+&ipu1_di0_disp0 {
+ remote-endpoint = <&display_in>;
+};
+
+&ipu1_csi0_mux_from_parallel_sensor {
+ remote-endpoint = <&tvp5151_to_ipu1_csi0_mux>;
+};
+
&pwm1 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_pwm1>;
diff --git a/arch/arm/boot/dts/imx6dl-victgo.dts b/arch/arm/boot/dts/imx6dl-victgo.dts
index d37ba4ed847d..227c952543d4 100644
--- a/arch/arm/boot/dts/imx6dl-victgo.dts
+++ b/arch/arm/boot/dts/imx6dl-victgo.dts
@@ -66,6 +66,11 @@
};
};
+ iio-hwmon {
+ compatible = "iio-hwmon";
+ io-channels = <&vdiv_vaccu>, <&vdiv_hitch_pos>;
+ };
+
leds {
compatible = "gpio-leds";
pinctrl-names = "default";
@@ -181,6 +186,72 @@
frame-master;
};
};
+
+ thermal-zones {
+ chassis-thermal {
+ polling-delay = <20000>;
+ polling-delay-passive = <0>;
+ thermal-sensors = <&tsens0>;
+ };
+
+ touch-thermal0 {
+ polling-delay = <20000>;
+ polling-delay-passive = <0>;
+ thermal-sensors = <&touch_temp0>;
+ };
+
+ touch-thermal1 {
+ polling-delay = <20000>;
+ polling-delay-passive = <0>;
+ thermal-sensors = <&touch_temp1>;
+ };
+ };
+
+ touchscreen {
+ compatible = "resistive-adc-touch";
+ io-channels = <&adc_ts 1>, <&adc_ts 3>, <&adc_ts 4>,
+ <&adc_ts 5>;
+ io-channel-names = "y", "z1", "z2", "x";
+ touchscreen-min-pressure = <64687>;
+ touchscreen-inverted-x;
+ touchscreen-inverted-y;
+ touchscreen-x-plate-ohms = <300>;
+ touchscreen-y-plate-ohms = <800>;
+ };
+
+ touch_temp0: touch-temperature-sensor0 {
+ compatible = "generic-adc-thermal";
+ #thermal-sensor-cells = <0>;
+ io-channels = <&adc_ts 0>;
+ io-channel-names = "sensor-channel";
+ temperature-lookup-table = < (-40000) 736
+ 85000 474>;
+ };
+
+ touch_temp1: touch-temperature-sensor1 {
+ compatible = "generic-adc-thermal";
+ #thermal-sensor-cells = <0>;
+ io-channels = <&adc_ts 7>;
+ io-channel-names = "sensor-channel";
+ temperature-lookup-table = < (-40000) 826
+ 85000 609>;
+ };
+
+ vdiv_vaccu: voltage-divider-vaccu {
+ compatible = "voltage-divider";
+ io-channels = <&adc_ts 2>;
+ output-ohms = <2500>;
+ full-ohms = <64000>;
+ #io-channel-cells = <0>;
+ };
+
+ vdiv_hitch_pos: voltage-divider-hitch-pos {
+ compatible = "voltage-divider";
+ io-channels = <&adc_ts 6>;
+ output-ohms = <3300>;
+ full-ohms = <13300>;
+ #io-channel-cells = <0>;
+ };
};
&audmux {
@@ -244,22 +315,41 @@
pinctrl-0 = <&pinctrl_ecspi2>;
status = "okay";
- touchscreen@0 {
- compatible = "ti,tsc2046";
+ adc_ts: adc@0 {
+ compatible = "ti,tsc2046e-adc";
reg = <0>;
- pinctrl-names = "default";
pinctrl-0 = <&pinctrl_touchscreen>;
- spi-max-frequency = <200000>;
- interrupts-extended = <&gpio5 8 IRQ_TYPE_EDGE_FALLING>;
- pendown-gpio = <&gpio5 8 GPIO_ACTIVE_LOW>;
- touchscreen-size-x = <800>;
- touchscreen-size-y = <480>;
- touchscreen-inverted-y;
- touchscreen-max-pressure = <4095>;
- ti,vref-delay-usecs = /bits/ 16 <100>;
- ti,x-plate-ohms = /bits/ 16 <800>;
- ti,y-plate-ohms = /bits/ 16 <300>;
- wakeup-source;
+ pinctrl-names ="default";
+ spi-max-frequency = <1000000>;
+ interrupts-extended = <&gpio5 8 IRQ_TYPE_LEVEL_LOW>;
+ #io-channel-cells = <1>;
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ channel@1 {
+ reg = <1>;
+ settling-time-us = <700>;
+ oversampling-ratio = <5>;
+ };
+
+ channel@3 {
+ reg = <3>;
+ settling-time-us = <700>;
+ oversampling-ratio = <5>;
+ };
+
+ channel@4 {
+ reg = <4>;
+ settling-time-us = <700>;
+ oversampling-ratio = <5>;
+ };
+
+ channel@5 {
+ reg = <5>;
+ settling-time-us = <700>;
+ oversampling-ratio = <5>;
+ };
};
};
@@ -446,9 +536,10 @@
reg = <0x51>;
};
- temperature-sensor@70 {
+ tsens0: temperature-sensor@70 {
compatible = "ti,tmp103";
reg = <0x70>;
+ #thermal-sensor-cells = <0>;
};
};
diff --git a/arch/arm/boot/dts/imx6q-tbs2910.dts b/arch/arm/boot/dts/imx6q-tbs2910.dts
index 343364d3e4f7..8daef65d5bb3 100644
--- a/arch/arm/boot/dts/imx6q-tbs2910.dts
+++ b/arch/arm/boot/dts/imx6q-tbs2910.dts
@@ -159,7 +159,7 @@
pinctrl-0 = <&pinctrl_i2c3>;
status = "okay";
- rtc: ds1307@68 {
+ rtc: rtc@68 {
compatible = "dallas,ds1307";
reg = <0x68>;
};
diff --git a/arch/arm/boot/dts/imx6qdl-dhcom-pdk2.dtsi b/arch/arm/boot/dts/imx6qdl-dhcom-pdk2.dtsi
index dc89b554e694..fe72650295a5 100644
--- a/arch/arm/boot/dts/imx6qdl-dhcom-pdk2.dtsi
+++ b/arch/arm/boot/dts/imx6qdl-dhcom-pdk2.dtsi
@@ -4,7 +4,10 @@
* Copyright (C) 2018 Marek Vasut <marex@denx.de>
*/
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
#include <dt-bindings/leds/common.h>
+#include <dt-bindings/pwm/pwm.h>
/ {
chosen {
diff --git a/arch/arm/boot/dts/imx6qdl-mba6.dtsi b/arch/arm/boot/dts/imx6qdl-mba6.dtsi
index daf76345b179..f4dca20669d6 100644
--- a/arch/arm/boot/dts/imx6qdl-mba6.dtsi
+++ b/arch/arm/boot/dts/imx6qdl-mba6.dtsi
@@ -17,6 +17,7 @@
mmc1 = &usdhc2;
/delete-property/ mmc2;
/delete-property/ mmc3;
+ rtc0 = &rtc0;
};
chosen {
@@ -39,18 +40,21 @@
label = "s6";
linux,code = <KEY_F6>;
gpios = <&gpio7 13 GPIO_ACTIVE_LOW>;
+ wakeup-source;
};
button2 {
label = "s7";
linux,code = <KEY_F7>;
gpios = <&gpio7 12 GPIO_ACTIVE_LOW>;
+ wakeup-source;
};
button3 {
label = "s8";
linux,code = <KEY_F8>;
gpios = <&gpio1 8 GPIO_ACTIVE_LOW>;
+ wakeup-source;
};
};
@@ -82,6 +86,8 @@
reg_pcie: regulator-pcie {
compatible = "regulator-fixed";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_regpcie>;
regulator-name = "supply-pcie";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
@@ -392,7 +398,6 @@
pinctrl_hog: hoggrp {
fsl,pins = <
- /* LCD.CONTRAST -> Rev 0100 only, not used on Rev.0200*/
MX6QDL_PAD_DI0_PIN4__GPIO4_IO20 0x0001b099
MX6QDL_PAD_ENET_RXD1__GPIO1_IO26 0x0001b099
@@ -433,8 +438,6 @@
MX6QDL_PAD_SD4_DAT3__GPIO2_IO11 0x001b0f0 /* #PCIE.WAKE */
MX6QDL_PAD_NANDF_CLE__GPIO6_IO07 0x001b0f0 /* #PCIE.RST */
MX6QDL_PAD_NANDF_CS0__GPIO6_IO11 0x001b0f0 /* #PCIE.DIS */
- /* HYS = 1, DSE = 110, PUE+PKE, SPEED = HIGH (11)*/
- MX6QDL_PAD_NANDF_D0__GPIO2_IO00 0x00130f0 /* PCIE.PWR_EN */
>;
};
@@ -459,6 +462,13 @@
>;
};
+ pinctrl_regpcie: regpciegrp {
+ fsl,pins = <
+ /* HYS = 1, DSE = 110, PUE+PKE, SPEED = HIGH (11)*/
+ MX6QDL_PAD_NANDF_D0__GPIO2_IO00 0x00130f0 /* PCIE.PWR_EN */
+ >;
+ };
+
pinctrl_uart2: uart2grp {
fsl,pins = <
MX6QDL_PAD_SD4_DAT4__UART2_RX_DATA 0x1b099
diff --git a/arch/arm/boot/dts/imx6qdl-mba6a.dtsi b/arch/arm/boot/dts/imx6qdl-mba6a.dtsi
index a61f2705a340..df8fa169e9f6 100644
--- a/arch/arm/boot/dts/imx6qdl-mba6a.dtsi
+++ b/arch/arm/boot/dts/imx6qdl-mba6a.dtsi
@@ -6,12 +6,6 @@
* Author: Markus Niebel <Markus.Niebel@tq-group.com>
*/
-/ {
- aliases {
- rtc0 = &rtc0;
- };
-};
-
&fec {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_enet>, <&pinctrl_enet_fix>;
diff --git a/arch/arm/boot/dts/imx6qdl-mba6b.dtsi b/arch/arm/boot/dts/imx6qdl-mba6b.dtsi
index 9f9f7037c9e4..7d1cd7454c7f 100644
--- a/arch/arm/boot/dts/imx6qdl-mba6b.dtsi
+++ b/arch/arm/boot/dts/imx6qdl-mba6b.dtsi
@@ -6,12 +6,6 @@
* Author: Markus Niebel <Markus.Niebel@tq-group.com>
*/
-/ {
- aliases {
- rtc0 = &rtc0;
- };
-};
-
&fec {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_enet>;
@@ -19,8 +13,11 @@
&i2c1 {
clock-frequency = <100000>;
- pinctrl-names = "default";
+ pinctrl-names = "default", "gpio";
pinctrl-0 = <&pinctrl_i2c1>;
+ pinctrl-1 = <&pinctrl_i2c1_recovery>;
+ scl-gpios = <&gpio5 27 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+ sda-gpios = <&gpio5 26 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
status = "okay";
};
diff --git a/arch/arm/boot/dts/imx6qdl-phytec-pfla02.dtsi b/arch/arm/boot/dts/imx6qdl-phytec-pfla02.dtsi
index f3236204cb5a..1f2ba6f6254e 100644
--- a/arch/arm/boot/dts/imx6qdl-phytec-pfla02.dtsi
+++ b/arch/arm/boot/dts/imx6qdl-phytec-pfla02.dtsi
@@ -205,6 +205,19 @@
regulator-always-on;
};
};
+
+ da9063_rtc: rtc {
+ compatible = "dlg,da9063-rtc";
+ };
+
+ da9063_wdog: watchdog {
+ compatible = "dlg,da9063-watchdog";
+ };
+
+ onkey {
+ compatible = "dlg,da9063-onkey";
+ status = "disabled";
+ };
};
};
diff --git a/arch/arm/boot/dts/imx6qdl-phytec-phycore-som.dtsi b/arch/arm/boot/dts/imx6qdl-phytec-phycore-som.dtsi
index 94b254bfd054..28a805384668 100644
--- a/arch/arm/boot/dts/imx6qdl-phytec-phycore-som.dtsi
+++ b/arch/arm/boot/dts/imx6qdl-phytec-phycore-som.dtsi
@@ -116,6 +116,16 @@
dlg,use-sw-pm;
};
+ thermal {
+ compatible = "dlg,da9062-thermal";
+ status = "disabled";
+ };
+
+ gpio {
+ compatible = "dlg,da9062-gpio";
+ status = "disabled";
+ };
+
regulators {
vdd_arm: buck1 {
regulator-name = "vdd_arm";
diff --git a/arch/arm/boot/dts/imx6qdl-tqma6.dtsi b/arch/arm/boot/dts/imx6qdl-tqma6.dtsi
index 51a3a5392c95..344ea935c7da 100644
--- a/arch/arm/boot/dts/imx6qdl-tqma6.dtsi
+++ b/arch/arm/boot/dts/imx6qdl-tqma6.dtsi
@@ -52,6 +52,13 @@
>;
};
+ pinctrl_i2c1_recovery: i2c1recoverygrp {
+ fsl,pins = <
+ MX6QDL_PAD_CSI0_DAT8__GPIO5_IO26 0x4001b899
+ MX6QDL_PAD_CSI0_DAT9__GPIO5_IO27 0x4001b899
+ >;
+ };
+
pinctrl_i2c3: i2c3grp {
fsl,pins = <
MX6QDL_PAD_GPIO_5__I2C3_SCL 0x4001b899
@@ -59,6 +66,13 @@
>;
};
+ pinctrl_i2c3_recovery: i2c3recoverygrp {
+ fsl,pins = <
+ MX6QDL_PAD_GPIO_5__GPIO1_IO05 0x4001b899
+ MX6QDL_PAD_GPIO_6__GPIO1_IO06 0x4001b899
+ >;
+ };
+
pinctrl_pmic: pmicgrp {
fsl,pins = <
MX6QDL_PAD_NANDF_RB0__GPIO6_IO10 0x1b099 /* PMIC irq */
diff --git a/arch/arm/boot/dts/imx6qdl-tqma6a.dtsi b/arch/arm/boot/dts/imx6qdl-tqma6a.dtsi
index bfb67da64b96..7dc3f0005b0f 100644
--- a/arch/arm/boot/dts/imx6qdl-tqma6a.dtsi
+++ b/arch/arm/boot/dts/imx6qdl-tqma6a.dtsi
@@ -4,6 +4,8 @@
* Copyright 2013-2017 Markus Niebel <Markus.Niebel@tq-group.com>
*/
+#include <dt-bindings/gpio/gpio.h>
+
&fec {
interrupts-extended = <&gpio1 6 IRQ_TYPE_LEVEL_HIGH>,
<&intc 0 119 IRQ_TYPE_LEVEL_HIGH>;
@@ -11,8 +13,11 @@
};
&i2c1 {
- pinctrl-names = "default";
+ pinctrl-names = "default", "gpio";
pinctrl-0 = <&pinctrl_i2c1>;
+ pinctrl-1 = <&pinctrl_i2c1_recovery>;
+ scl-gpios = <&gpio5 27 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+ sda-gpios = <&gpio5 26 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
clock-frequency = <100000>;
status = "okay";
diff --git a/arch/arm/boot/dts/imx6qdl-tqma6b.dtsi b/arch/arm/boot/dts/imx6qdl-tqma6b.dtsi
index 49c472285c06..dd0925766440 100644
--- a/arch/arm/boot/dts/imx6qdl-tqma6b.dtsi
+++ b/arch/arm/boot/dts/imx6qdl-tqma6b.dtsi
@@ -4,9 +4,14 @@
* Copyright 2013-2017 Markus Niebel <Markus.Niebel@tq-group.com>
*/
+#include <dt-bindings/gpio/gpio.h>
+
&i2c3 {
- pinctrl-names = "default";
+ pinctrl-names = "default", "gpio";
pinctrl-0 = <&pinctrl_i2c3>;
+ pinctrl-1 = <&pinctrl_i2c3_recovery>;
+ scl-gpios = <&gpio1 5 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+ sda-gpios = <&gpio1 6 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
clock-frequency = <100000>;
status = "okay";
diff --git a/arch/arm/boot/dts/imx6qdl-tx6-mb7.dtsi b/arch/arm/boot/dts/imx6qdl-tx6-mb7.dtsi
index 410972e1dca9..99ec7a838f8d 100644
--- a/arch/arm/boot/dts/imx6qdl-tx6-mb7.dtsi
+++ b/arch/arm/boot/dts/imx6qdl-tx6-mb7.dtsi
@@ -85,7 +85,7 @@
};
&i2c3 {
- rtc: mcp7940x@6f {
+ rtc: rtc@6f {
compatible = "microchip,mcp7940x";
reg = <0x6f>;
};
diff --git a/arch/arm/boot/dts/imx6qdl-udoo.dtsi b/arch/arm/boot/dts/imx6qdl-udoo.dtsi
index d07d8f83456d..ccfa8e320be6 100644
--- a/arch/arm/boot/dts/imx6qdl-udoo.dtsi
+++ b/arch/arm/boot/dts/imx6qdl-udoo.dtsi
@@ -5,6 +5,8 @@
* Author: Fabio Estevam <fabio.estevam@freescale.com>
*/
+#include <dt-bindings/gpio/gpio.h>
+
/ {
aliases {
backlight = &backlight;
@@ -226,6 +228,7 @@
MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x17059
MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x17059
MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x17059
+ MX6QDL_PAD_SD3_DAT5__GPIO7_IO00 0x1b0b0
>;
};
@@ -304,7 +307,7 @@
&usdhc3 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_usdhc3>;
- non-removable;
+ cd-gpios = <&gpio7 0 GPIO_ACTIVE_LOW>;
status = "okay";
};
diff --git a/arch/arm/boot/dts/imx6qdl-vicut1.dtsi b/arch/arm/boot/dts/imx6qdl-vicut1.dtsi
index b9e305774fed..1ac7e13249d2 100644
--- a/arch/arm/boot/dts/imx6qdl-vicut1.dtsi
+++ b/arch/arm/boot/dts/imx6qdl-vicut1.dtsi
@@ -126,15 +126,6 @@
regulator-max-microvolt = <3300000>;
};
- reg_h1_vbus: regulator-h1-vbus {
- compatible = "regulator-fixed";
- regulator-name = "h1-vbus";
- regulator-min-microvolt = <5000000>;
- regulator-max-microvolt = <5000000>;
- gpio = <&gpio1 0 GPIO_ACTIVE_HIGH>;
- enable-active-high;
- };
-
reg_otg_vbus: regulator-otg-vbus {
compatible = "regulator-fixed";
regulator-name = "otg-vbus";
@@ -212,6 +203,8 @@
&can1 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_can1>;
+ termination-gpios = <&gpio1 0 GPIO_ACTIVE_LOW>;
+ termination-ohms = <150>;
status = "okay";
};
@@ -492,7 +485,6 @@
};
&usbh1 {
- vbus-supply = <&reg_h1_vbus>;
pinctrl-names = "default";
phy_type = "utmi";
dr_mode = "host";
diff --git a/arch/arm/boot/dts/imx6qp-sabresd.dts b/arch/arm/boot/dts/imx6qp-sabresd.dts
index 480e73183f6b..f69eec18d865 100644
--- a/arch/arm/boot/dts/imx6qp-sabresd.dts
+++ b/arch/arm/boot/dts/imx6qp-sabresd.dts
@@ -50,8 +50,12 @@
};
};
+&vgen3_reg {
+ regulator-always-on;
+};
+
&pcie {
- status = "disabled";
+ status = "okay";
};
&sata {
diff --git a/arch/arm/boot/dts/imx6sx-udoo-neo.dtsi b/arch/arm/boot/dts/imx6sx-udoo-neo.dtsi
index ee645655090d..35861bbea94e 100644
--- a/arch/arm/boot/dts/imx6sx-udoo-neo.dtsi
+++ b/arch/arm/boot/dts/imx6sx-udoo-neo.dtsi
@@ -183,6 +183,27 @@
status = "okay";
};
+&i2c3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c3>;
+ clock-frequency = <100000>;
+ status = "okay";
+
+ hdmi-transmitter@70 {
+ compatible = "nxp,tda998x";
+ reg = <0x70>;
+ interrupts-extended = <&gpio3 27 IRQ_TYPE_LEVEL_LOW>;
+
+ ports {
+ port {
+ hdmi: endpoint {
+ remote-endpoint = <&lcdc>;
+ };
+ };
+ };
+ };
+};
+
&i2c4 { /* Onboard Motion sensors */
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_i2c4>;
@@ -190,6 +211,18 @@
status = "disabled";
};
+&lcdif1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_lcd>;
+ status = "okay";
+
+ port {
+ lcdc: endpoint {
+ remote-endpoint = <&hdmi>;
+ };
+ };
+};
+
&iomuxc {
pinctrl_bt_reg: btreggrp {
fsl,pins =
@@ -227,12 +260,53 @@
<MX6SX_PAD_GPIO1_IO02__I2C2_SCL 0x4001b8b1>;
};
+ pinctrl_i2c3: i2c3grp {
+ fsl,pins =
+ <MX6SX_PAD_KEY_ROW4__I2C3_SDA 0x4001b8b1>,
+ <MX6SX_PAD_KEY_COL4__I2C3_SCL 0x4001b8b1>;
+ };
+
pinctrl_i2c4: i2c4grp {
fsl,pins =
<MX6SX_PAD_USB_H_DATA__I2C4_SDA 0x4001b8b1>,
<MX6SX_PAD_USB_H_STROBE__I2C4_SCL 0x4001b8b1>;
};
+ pinctrl_lcd: lcdgrp {
+ fsl,pins = <
+ MX6SX_PAD_LCD1_DATA00__LCDIF1_DATA_0 0x4001b0b0
+ MX6SX_PAD_LCD1_DATA01__LCDIF1_DATA_1 0x4001b0b0
+ MX6SX_PAD_LCD1_DATA02__LCDIF1_DATA_2 0x4001b0b0
+ MX6SX_PAD_LCD1_DATA03__LCDIF1_DATA_3 0x4001b0b0
+ MX6SX_PAD_LCD1_DATA04__LCDIF1_DATA_4 0x4001b0b0
+ MX6SX_PAD_LCD1_DATA05__LCDIF1_DATA_5 0x4001b0b0
+ MX6SX_PAD_LCD1_DATA06__LCDIF1_DATA_6 0x4001b0b0
+ MX6SX_PAD_LCD1_DATA07__LCDIF1_DATA_7 0x4001b0b0
+ MX6SX_PAD_LCD1_DATA08__LCDIF1_DATA_8 0x4001b0b0
+ MX6SX_PAD_LCD1_DATA09__LCDIF1_DATA_9 0x4001b0b0
+ MX6SX_PAD_LCD1_DATA10__LCDIF1_DATA_10 0x4001b0b0
+ MX6SX_PAD_LCD1_DATA11__LCDIF1_DATA_11 0x4001b0b0
+ MX6SX_PAD_LCD1_DATA12__LCDIF1_DATA_12 0x4001b0b0
+ MX6SX_PAD_LCD1_DATA13__LCDIF1_DATA_13 0x4001b0b0
+ MX6SX_PAD_LCD1_DATA14__LCDIF1_DATA_14 0x4001b0b0
+ MX6SX_PAD_LCD1_DATA15__LCDIF1_DATA_15 0x4001b0b0
+ MX6SX_PAD_LCD1_DATA16__LCDIF1_DATA_16 0x4001b0b0
+ MX6SX_PAD_LCD1_DATA17__LCDIF1_DATA_17 0x4001b0b0
+ MX6SX_PAD_LCD1_DATA18__LCDIF1_DATA_18 0x4001b0b0
+ MX6SX_PAD_LCD1_DATA19__LCDIF1_DATA_19 0x4001b0b0
+ MX6SX_PAD_LCD1_DATA20__LCDIF1_DATA_20 0x4001b0b0
+ MX6SX_PAD_LCD1_DATA21__LCDIF1_DATA_21 0x4001b0b0
+ MX6SX_PAD_LCD1_DATA22__LCDIF1_DATA_22 0x4001b0b0
+ MX6SX_PAD_LCD1_DATA23__LCDIF1_DATA_23 0x4001b0b0
+ MX6SX_PAD_LCD1_CLK__LCDIF1_CLK 0x4001b0b0
+ MX6SX_PAD_LCD1_ENABLE__LCDIF1_ENABLE 0x4001b0b0
+ MX6SX_PAD_LCD1_VSYNC__LCDIF1_VSYNC 0x4001b0b0
+ MX6SX_PAD_LCD1_HSYNC__LCDIF1_HSYNC 0x4001b0b0
+ MX6SX_PAD_LCD1_RESET__GPIO3_IO_27 0x4001b0b0
+ >;
+ };
+
+
pinctrl_uart1: uart1grp {
fsl,pins =
<MX6SX_PAD_GPIO1_IO04__UART1_DCE_TX 0x1b0b1>,
diff --git a/arch/arm/boot/dts/imx6ul-tx6ul-mainboard.dts b/arch/arm/boot/dts/imx6ul-tx6ul-mainboard.dts
index 97686097a86e..92ac0edcb608 100644
--- a/arch/arm/boot/dts/imx6ul-tx6ul-mainboard.dts
+++ b/arch/arm/boot/dts/imx6ul-tx6ul-mainboard.dts
@@ -119,7 +119,7 @@
/delete-node/ codec@a;
/delete-node/ touchscreen@48;
- rtc: mcp7940x@6f {
+ rtc: rtc@6f {
compatible = "microchip,mcp7940x";
reg = <0x6f>;
};
diff --git a/arch/arm/boot/dts/imx7-colibri-aster.dtsi b/arch/arm/boot/dts/imx7-colibri-aster.dtsi
index 139188eb9f40..b770fc937970 100644
--- a/arch/arm/boot/dts/imx7-colibri-aster.dtsi
+++ b/arch/arm/boot/dts/imx7-colibri-aster.dtsi
@@ -103,7 +103,7 @@
};
/* M41T0M6 real time clock on carrier board */
- rtc: m41t0m6@68 {
+ rtc: rtc@68 {
compatible = "st,m41t0";
reg = <0x68>;
};
diff --git a/arch/arm/boot/dts/imx7-colibri-eval-v3.dtsi b/arch/arm/boot/dts/imx7-colibri-eval-v3.dtsi
index 3caf450735d7..3b9df8c82ae3 100644
--- a/arch/arm/boot/dts/imx7-colibri-eval-v3.dtsi
+++ b/arch/arm/boot/dts/imx7-colibri-eval-v3.dtsi
@@ -129,7 +129,7 @@
};
/* M41T0M6 real time clock on carrier board */
- rtc: m41t0m6@68 {
+ rtc: rtc@68 {
compatible = "st,m41t0";
reg = <0x68>;
};
diff --git a/arch/arm/boot/dts/imx7-colibri.dtsi b/arch/arm/boot/dts/imx7-colibri.dtsi
index 62b771c1d5a9..f1c60b0cb143 100644
--- a/arch/arm/boot/dts/imx7-colibri.dtsi
+++ b/arch/arm/boot/dts/imx7-colibri.dtsi
@@ -40,7 +40,7 @@
dailink_master: simple-audio-card,codec {
sound-dai = <&codec>;
- clocks = <&clks IMX7D_AUDIO_MCLK_ROOT_CLK>;
+ clocks = <&clks IMX7D_AUDIO_MCLK_ROOT_DIV>;
};
};
};
@@ -293,7 +293,7 @@
compatible = "fsl,sgtl5000";
#sound-dai-cells = <0>;
reg = <0x0a>;
- clocks = <&clks IMX7D_AUDIO_MCLK_ROOT_CLK>;
+ clocks = <&clks IMX7D_AUDIO_MCLK_ROOT_DIV>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_sai1_mclk>;
VDDA-supply = <&reg_module_3v3_avdd>;
diff --git a/arch/arm/boot/dts/imx7-mba7.dtsi b/arch/arm/boot/dts/imx7-mba7.dtsi
index 49086c6b6a0a..3df6dff7734a 100644
--- a/arch/arm/boot/dts/imx7-mba7.dtsi
+++ b/arch/arm/boot/dts/imx7-mba7.dtsi
@@ -302,7 +302,7 @@
tlv320aic32x4: audio-codec@18 {
compatible = "ti,tlv320aic32x4";
reg = <0x18>;
- clocks = <&clks IMX7D_AUDIO_MCLK_ROOT_CLK>;
+ clocks = <&clks IMX7D_AUDIO_MCLK_ROOT_DIV>;
clock-names = "mclk";
ldoin-supply = <&reg_audio_3v3>;
iov-supply = <&reg_audio_3v3>;
diff --git a/arch/arm/boot/dts/imx7d-nitrogen7.dts b/arch/arm/boot/dts/imx7d-nitrogen7.dts
index e0751e6ba3c0..a31de900139d 100644
--- a/arch/arm/boot/dts/imx7d-nitrogen7.dts
+++ b/arch/arm/boot/dts/imx7d-nitrogen7.dts
@@ -288,7 +288,7 @@
codec: wm8960@1a {
compatible = "wlf,wm8960";
reg = <0x1a>;
- clocks = <&clks IMX7D_AUDIO_MCLK_ROOT_CLK>;
+ clocks = <&clks IMX7D_AUDIO_MCLK_ROOT_DIV>;
clock-names = "mclk";
wlf,shared-lrclk;
};
diff --git a/arch/arm/boot/dts/imx7d-pico-hobbit.dts b/arch/arm/boot/dts/imx7d-pico-hobbit.dts
index 7b2198a9372c..d917dc4f2f22 100644
--- a/arch/arm/boot/dts/imx7d-pico-hobbit.dts
+++ b/arch/arm/boot/dts/imx7d-pico-hobbit.dts
@@ -31,7 +31,7 @@
dailink_master: simple-audio-card,codec {
sound-dai = <&sgtl5000>;
- clocks = <&clks IMX7D_AUDIO_MCLK_ROOT_CLK>;
+ clocks = <&clks IMX7D_AUDIO_MCLK_ROOT_DIV>;
};
};
};
@@ -41,7 +41,7 @@
#sound-dai-cells = <0>;
reg = <0x0a>;
compatible = "fsl,sgtl5000";
- clocks = <&clks IMX7D_AUDIO_MCLK_ROOT_CLK>;
+ clocks = <&clks IMX7D_AUDIO_MCLK_ROOT_DIV>;
VDDA-supply = <&reg_2p5v>;
VDDIO-supply = <&reg_vref_1v8>;
};
diff --git a/arch/arm/boot/dts/imx7d-pico-pi.dts b/arch/arm/boot/dts/imx7d-pico-pi.dts
index 70bea95c06d8..f263e391e24c 100644
--- a/arch/arm/boot/dts/imx7d-pico-pi.dts
+++ b/arch/arm/boot/dts/imx7d-pico-pi.dts
@@ -31,7 +31,7 @@
dailink_master: simple-audio-card,codec {
sound-dai = <&sgtl5000>;
- clocks = <&clks IMX7D_AUDIO_MCLK_ROOT_CLK>;
+ clocks = <&clks IMX7D_AUDIO_MCLK_ROOT_DIV>;
};
};
};
@@ -41,7 +41,7 @@
#sound-dai-cells = <0>;
reg = <0x0a>;
compatible = "fsl,sgtl5000";
- clocks = <&clks IMX7D_AUDIO_MCLK_ROOT_CLK>;
+ clocks = <&clks IMX7D_AUDIO_MCLK_ROOT_DIV>;
VDDA-supply = <&reg_2p5v>;
VDDIO-supply = <&reg_vref_1v8>;
};
diff --git a/arch/arm/boot/dts/imx7d-sdb.dts b/arch/arm/boot/dts/imx7d-sdb.dts
index 7813ef960f6e..f053f5122741 100644
--- a/arch/arm/boot/dts/imx7d-sdb.dts
+++ b/arch/arm/boot/dts/imx7d-sdb.dts
@@ -385,14 +385,14 @@
codec: wm8960@1a {
compatible = "wlf,wm8960";
reg = <0x1a>;
- clocks = <&clks IMX7D_AUDIO_MCLK_ROOT_CLK>;
+ clocks = <&clks IMX7D_AUDIO_MCLK_ROOT_DIV>;
clock-names = "mclk";
wlf,shared-lrclk;
wlf,hp-cfg = <2 2 3>;
wlf,gpio-cfg = <1 3>;
assigned-clocks = <&clks IMX7D_AUDIO_MCLK_ROOT_SRC>,
<&clks IMX7D_PLL_AUDIO_POST_DIV>,
- <&clks IMX7D_AUDIO_MCLK_ROOT_CLK>;
+ <&clks IMX7D_AUDIO_MCLK_ROOT_DIV>;
assigned-clock-parents = <&clks IMX7D_PLL_AUDIO_POST_DIV>;
assigned-clock-rates = <0>, <884736000>, <12288000>;
};
diff --git a/arch/arm/boot/dts/imx7d.dtsi b/arch/arm/boot/dts/imx7d.dtsi
index b7735979b7e4..f8cba47536a0 100644
--- a/arch/arm/boot/dts/imx7d.dtsi
+++ b/arch/arm/boot/dts/imx7d.dtsi
@@ -113,6 +113,49 @@
<0x31004000 0x2000>,
<0x31006000 0x2000>;
};
+
+ pcie: pcie@33800000 {
+ compatible = "fsl,imx7d-pcie";
+ reg = <0x33800000 0x4000>,
+ <0x4ff00000 0x80000>;
+ reg-names = "dbi", "config";
+ #address-cells = <3>;
+ #size-cells = <2>;
+ device_type = "pci";
+ bus-range = <0x00 0xff>;
+ ranges = <0x81000000 0 0 0x4ff80000 0 0x00010000>, /* downstream I/O */
+ <0x82000000 0 0x40000000 0x40000000 0 0x0ff00000>; /* non-prefetchable memory */
+ num-lanes = <1>;
+ interrupts = <GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "msi";
+ #interrupt-cells = <1>;
+ interrupt-map-mask = <0 0 0 0x7>;
+ /*
+ * Reference manual lists pci irqs incorrectly
+ * Real hardware ordering is same as imx6: D+MSI, C, B, A
+ */
+ interrupt-map = <0 0 0 1 &intc GIC_SPI 125 IRQ_TYPE_LEVEL_HIGH>,
+ <0 0 0 2 &intc GIC_SPI 124 IRQ_TYPE_LEVEL_HIGH>,
+ <0 0 0 3 &intc GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>,
+ <0 0 0 4 &intc GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX7D_PCIE_CTRL_ROOT_CLK>,
+ <&clks IMX7D_PLL_ENET_MAIN_100M_CLK>,
+ <&clks IMX7D_PCIE_PHY_ROOT_CLK>;
+ clock-names = "pcie", "pcie_bus", "pcie_phy";
+ assigned-clocks = <&clks IMX7D_PCIE_CTRL_ROOT_SRC>,
+ <&clks IMX7D_PCIE_PHY_ROOT_SRC>;
+ assigned-clock-parents = <&clks IMX7D_PLL_ENET_MAIN_250M_CLK>,
+ <&clks IMX7D_PLL_ENET_MAIN_100M_CLK>;
+
+ fsl,max-link-speed = <2>;
+ power-domains = <&pgc_pcie_phy>;
+ resets = <&src IMX7_RESET_PCIEPHY>,
+ <&src IMX7_RESET_PCIE_CTRL_APPS_EN>,
+ <&src IMX7_RESET_PCIE_CTRL_APPS_TURNOFF>;
+ reset-names = "pciephy", "apps", "turnoff";
+ fsl,imx7d-pcie-phy = <&pcie_phy>;
+ status = "disabled";
+ };
};
};
@@ -162,49 +205,6 @@
fsl,stop-mode = <&gpr 0x10 4>;
status = "disabled";
};
-
- pcie: pcie@33800000 {
- compatible = "fsl,imx7d-pcie";
- reg = <0x33800000 0x4000>,
- <0x4ff00000 0x80000>;
- reg-names = "dbi", "config";
- #address-cells = <3>;
- #size-cells = <2>;
- device_type = "pci";
- bus-range = <0x00 0xff>;
- ranges = <0x81000000 0 0 0x4ff80000 0 0x00010000>, /* downstream I/O */
- <0x82000000 0 0x40000000 0x40000000 0 0x0ff00000>; /* non-prefetchable memory */
- num-lanes = <1>;
- interrupts = <GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>;
- interrupt-names = "msi";
- #interrupt-cells = <1>;
- interrupt-map-mask = <0 0 0 0x7>;
- /*
- * Reference manual lists pci irqs incorrectly
- * Real hardware ordering is same as imx6: D+MSI, C, B, A
- */
- interrupt-map = <0 0 0 1 &intc GIC_SPI 125 IRQ_TYPE_LEVEL_HIGH>,
- <0 0 0 2 &intc GIC_SPI 124 IRQ_TYPE_LEVEL_HIGH>,
- <0 0 0 3 &intc GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>,
- <0 0 0 4 &intc GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&clks IMX7D_PCIE_CTRL_ROOT_CLK>,
- <&clks IMX7D_PLL_ENET_MAIN_100M_CLK>,
- <&clks IMX7D_PCIE_PHY_ROOT_CLK>;
- clock-names = "pcie", "pcie_bus", "pcie_phy";
- assigned-clocks = <&clks IMX7D_PCIE_CTRL_ROOT_SRC>,
- <&clks IMX7D_PCIE_PHY_ROOT_SRC>;
- assigned-clock-parents = <&clks IMX7D_PLL_ENET_MAIN_250M_CLK>,
- <&clks IMX7D_PLL_ENET_MAIN_100M_CLK>;
-
- fsl,max-link-speed = <2>;
- power-domains = <&pgc_pcie_phy>;
- resets = <&src IMX7_RESET_PCIEPHY>,
- <&src IMX7_RESET_PCIE_CTRL_APPS_EN>,
- <&src IMX7_RESET_PCIE_CTRL_APPS_TURNOFF>;
- reset-names = "pciephy", "apps", "turnoff";
- fsl,imx7d-pcie-phy = <&pcie_phy>;
- status = "disabled";
- };
};
&ca_funnel_in_ports {
diff --git a/arch/arm/boot/dts/imx7s-warp.dts b/arch/arm/boot/dts/imx7s-warp.dts
index 4f1edef06c92..e8734d218b9d 100644
--- a/arch/arm/boot/dts/imx7s-warp.dts
+++ b/arch/arm/boot/dts/imx7s-warp.dts
@@ -75,7 +75,7 @@
dailink_master: simple-audio-card,codec {
sound-dai = <&codec>;
- clocks = <&clks IMX7D_AUDIO_MCLK_ROOT_CLK>;
+ clocks = <&clks IMX7D_AUDIO_MCLK_ROOT_DIV>;
};
};
};
@@ -232,7 +232,7 @@
#sound-dai-cells = <0>;
reg = <0x0a>;
compatible = "fsl,sgtl5000";
- clocks = <&clks IMX7D_AUDIO_MCLK_ROOT_CLK>;
+ clocks = <&clks IMX7D_AUDIO_MCLK_ROOT_DIV>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_sai1_mclk>;
VDDA-supply = <&vgen4_reg>;
diff --git a/arch/arm/boot/dts/imx7ulp.dtsi b/arch/arm/boot/dts/imx7ulp.dtsi
index b7ea37ad4e55..bcec98b96411 100644
--- a/arch/arm/boot/dts/imx7ulp.dtsi
+++ b/arch/arm/boot/dts/imx7ulp.dtsi
@@ -259,7 +259,7 @@
interrupts = <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&pcc2 IMX7ULP_CLK_WDG1>;
assigned-clocks = <&pcc2 IMX7ULP_CLK_WDG1>;
- assigned-clocks-parents = <&scg1 IMX7ULP_CLK_FIRC_BUS_CLK>;
+ assigned-clock-parents = <&scg1 IMX7ULP_CLK_FIRC_BUS_CLK>;
timeout-sec = <40>;
};
diff --git a/arch/arm/boot/dts/imxrt1050-pinfunc.h b/arch/arm/boot/dts/imxrt1050-pinfunc.h
new file mode 100644
index 000000000000..22c14a3262ad
--- /dev/null
+++ b/arch/arm/boot/dts/imxrt1050-pinfunc.h
@@ -0,0 +1,993 @@
+/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */
+/*
+ * Copyright (C) 2019
+ * Author(s): Giulio Benetti <giulio.benetti@benettiengineering.com>
+ */
+
+#ifndef _DT_BINDINGS_PINCTRL_IMXRT1050_PINFUNC_H
+#define _DT_BINDINGS_PINCTRL_IMXRT1050_PINFUNC_H
+
+#define IMX_PAD_SION 0x40000000
+
+/*
+ * The pin function ID is a tuple of
+ * <mux_reg conf_reg input_reg mux_mode input_val>
+ */
+
+#define MXRT1050_IOMUXC_GPIO_EMC_00_SEMC_DA00 0x014 0x204 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_00_FLEXPWM4_PWM0_A 0x014 0x204 0x494 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_00_LPSPI2_SCK 0x014 0x204 0x500 0x2 0x1
+#define MXRT1050_IOMUXC_GPIO_EMC_00_XBAR_INOUT2 0x014 0x204 0x60C 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_00_FLEXIO1_D00 0x014 0x204 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_00_GPIO4_IO00 0x014 0x204 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_EMC_01_SEMC_DA01 0x018 0x208 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_01_FLEXPWM4_PWM0_B 0x018 0x208 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_01_LPSPI2_PCS0 0x018 0x208 0x4FC 0x2 0x1
+#define MXRT1050_IOMUXC_GPIO_EMC_01_XBAR_INOUT3 0x018 0x208 0x610 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_01_FLEXIO1_D01 0x018 0x208 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_01_GPIO4_IO01 0x018 0x208 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_EMC_02_SEMC_DA02 0x01C 0x20C 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_02_FLEXPWM4_PWM1_A 0x01C 0x20C 0x498 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_02_LPSPI2_SDO 0x01C 0x20C 0x508 0x2 0x1
+#define MXRT1050_IOMUXC_GPIO_EMC_02_XBAR_INOUT4 0x01C 0x20C 0x614 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_02_FLEXIO1_D02 0x01C 0x20C 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_02_GPIO4_IO02 0x01C 0x20C 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_EMC_03_SEMC_DA03 0x020 0x210 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_03_FLEXPWM4_PWM1_B 0x020 0x210 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_03_LPSPI2_SDI 0x020 0x210 0x504 0x2 0x1
+#define MXRT1050_IOMUXC_GPIO_EMC_03_XBAR_INOUT5 0x020 0x210 0x618 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_03_FLEXIO1_D03 0x020 0x210 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_03_GPIO4_IO03 0x020 0x210 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_EMC_04_SEMC_DA04 0x024 0x214 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_04_FLEXPWM4_PWM2_A 0x024 0x214 0x49C 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_04_SAI2_TX_DATA 0x024 0x214 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_04_XBAR_INOUT6 0x024 0x214 0x61C 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_04_FLEXIO1_D04 0x024 0x214 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_04_GPIO4_IO04 0x024 0x214 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_EMC_05_SEMC_DA05 0x028 0x218 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_05_FLEXPWM4_PWM2_B 0x028 0x218 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_05_SAI2_TX_SYNC 0x028 0x218 0x5C4 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_05_XBAR_INOUT7 0x028 0x218 0x620 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_05_FLEXIO1_D05 0x028 0x218 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_05_GPIO4_IO05 0x028 0x218 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_EMC_06_SEMC_DA06 0x02C 0x21C 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_06_FLEXPWM2_PWM0_A 0x02C 0x21C 0x478 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_06_SAI2_TX_BCLK 0x02C 0x21C 0x5C0 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_06_XBAR_INOUT8 0x02C 0x21C 0x624 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_06_FLEXIO1_D06 0x02C 0x21C 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_06_GPIO4_IO06 0x02C 0x21C 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_EMC_07_SEMC_DA07 0x030 0x220 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_07_FLEXPWM2_PWM0_B 0x030 0x220 0x488 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_07_SAI2_MCLK 0x030 0x220 0x5B0 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_07_XBAR_INOUT9 0x030 0x220 0x628 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_07_FLEXIO1_D07 0x030 0x220 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_07_GPIO4_IO07 0x030 0x220 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_EMC_08_SEMC_DM00 0x034 0x224 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_08_FLEXPWM2_PWM1_A 0x034 0x224 0x47C 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_08_SAI2_RX_DATA 0x034 0x224 0x5B8 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_08_XBAR_INOUT17 0x034 0x224 0x62C 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_08_FLEXIO1_D08 0x034 0x224 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_08_GPIO4_IO08 0x034 0x224 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_EMC_09_SEMC_ADDR00 0x038 0x228 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_09_FLEXPWM2_PWM1_B 0x038 0x228 0x48C 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_09_SAI2_RX_SYNC 0x038 0x228 0x5BC 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_09_FLEXCAN2_TX 0x038 0x228 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_09_FLEXIO1_D09 0x038 0x228 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_09_GPIO4_IO09 0x038 0x228 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_EMC_10_SEMC_ADDR01 0x03C 0x22C 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_10_FLEXPWM2_PWM2_A 0x03C 0x22C 0x480 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_10_SAI2_RX_BCLK 0x03C 0x22C 0x5B4 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_10_FLEXCAN2_RX 0x03C 0x22C 0x450 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_10_FLEXIO1_D10 0x03C 0x22C 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_10_GPIO4_IO10 0x03C 0x22C 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_EMC_11_SEMC_ADDR02 0x040 0x230 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_11_FLEXPWM2_PWM2_B 0x040 0x230 0x490 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_11_LPI2C4_SDA 0x040 0x230 0x4E8 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_11_USDHC2_RESET_B 0x040 0x230 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_11_FLEXIO1_D11 0x040 0x230 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_11_GPIO4_IO11 0x040 0x230 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_EMC_12_SEMC_ADDR03 0x044 0x234 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_12_XBAR_INOUT24 0x044 0x234 0x640 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_12_LPI2C4_SCL 0x044 0x234 0x4E4 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_12_USDHC2_WP 0x044 0x234 0x5D8 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_12_FLEXPWM1_PWM3_A 0x044 0x234 0x454 0x4 0x1
+#define MXRT1050_IOMUXC_GPIO_EMC_12_GPIO4_IO12 0x044 0x234 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_EMC_13_SEMC_ADDR04 0x048 0x238 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_13_XBAR_INOUT25 0x048 0x238 0x650 0x1 0x1
+#define MXRT1050_IOMUXC_GPIO_EMC_13_LPUART3_TXD 0x048 0x238 0x53C 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_13_MQS_RIGHT 0x048 0x238 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_13_FLEXPWM1_PWM3_B 0x048 0x238 0x464 0x4 0x1
+#define MXRT1050_IOMUXC_GPIO_EMC_13_GPIO4_IO13 0x048 0x238 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_EMC_14_SEMC_ADDR05 0x04C 0x23C 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_14_XBAR_INOUT19 0x04C 0x23C 0x654 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_14_LPUART3_RXD 0x04C 0x23C 0x538 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_14_MQS_LEFT 0x04C 0x23C 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_14_LPSPI2_PCS1 0x04C 0x23C 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_14_GPIO4_IO14 0x04C 0x23C 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_EMC_15_SEMC_ADDR06 0x050 0x240 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_15_XBAR_INOUT20 0x050 0x240 0x634 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_15_LPUART3_CTS_B 0x050 0x240 0x534 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_15_SPDIF_OUT 0x050 0x240 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_15_TMR3_TIMER0 0x050 0x240 0x57C 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_15_GPIO4_IO15 0x050 0x240 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_EMC_16_SEMC_ADDR07 0x054 0x244 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_16_XBAR_INOUT21 0x054 0x244 0x658 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_16_LPUART3_RTS_B 0x054 0x244 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_16_SPDIF_IN 0x054 0x244 0x5C8 0x3 0x1
+#define MXRT1050_IOMUXC_GPIO_EMC_16_TMR3_TIMER1 0x054 0x244 0x580 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_16_GPIO4_IO16 0x054 0x244 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_EMC_17_SEMC_ADDR08 0x058 0x248 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_17_FLEXPWM4_PWM3_A 0x058 0x248 0x4A0 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_17_LPUART4_CTS_B 0x058 0x248 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_17_FLEXCAN1_TX 0x058 0x248 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_17_TMR3_TIMER2 0x058 0x248 0x584 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_17_GPIO4_IO17 0x058 0x248 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_EMC_18_SEMC_ADDR09 0x05C 0x24C 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_18_FLEXPWM4_PWM3_B 0x05C 0x24C 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_18_LPUART4_RTS_B 0x05C 0x24C 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_18_FLEXCAN1_RX 0x05C 0x24C 0x44C 0x3 0x1
+#define MXRT1050_IOMUXC_GPIO_EMC_18_TMR3_TIMER3 0x05C 0x24C 0x588 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_18_GPIO4_IO18 0x05C 0x24C 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_18_SNVS_VIO_5_CTL 0x05C 0x24C 0x000 0x6 0x0
+
+#define MXRT1050_IOMUXC_GPIO_EMC_19_SEMC_ADDR11 0x060 0x250 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_19_FLEXPWM2_PWM3_A 0x060 0x250 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_19_LPUART4_TXD 0x060 0x250 0x544 0x2 0x1
+#define MXRT1050_IOMUXC_GPIO_EMC_19_ENET_RX_DATA01 0x060 0x250 0x438 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_19_TMR2_TIMER0 0x060 0x250 0x56C 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_19_GPIO4_IO19 0x060 0x250 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_19_SNVS_VIO_5 0x060 0x250 0x000 0x6 0x0
+
+#define MXRT1050_IOMUXC_GPIO_EMC_20_SEMC_ADDR12 0x064 0x254 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_20_FLEXPWM2_PWM3_B 0x064 0x254 0x484 0x1 0x1
+#define MXRT1050_IOMUXC_GPIO_EMC_20_LPUART4_RXD 0x064 0x254 0x540 0x2 0x1
+#define MXRT1050_IOMUXC_GPIO_EMC_20_ENET_RX_DATA00 0x064 0x254 0x434 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_20_TMR2_TIMER0 0x064 0x254 0x570 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_20_GPIO4_IO20 0x064 0x254 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_EMC_21_SEMC_BA0 0x068 0x258 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_21_FLEXPWM3_PWM3_A 0x068 0x258 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_21_LPI2C3_SDA 0x068 0x258 0x4E0 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_21_ENET_TX_DATA01 0x068 0x258 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_21_TMR2_TIMER2 0x068 0x258 0x574 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_21_GPIO4_IO21 0x068 0x258 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_EMC_22_SEMC_BA1 0x06C 0x25C 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_22_FLEXPWM3_PWM3_B 0x06C 0x25C 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_22_LPI2C3_SCL 0x06C 0x25C 0x4DC 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_22_ENET_TX_DATA00 0x06C 0x25C 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_22_TMR2_TIMER3 0x06C 0x25C 0x578 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_22_GPIO4_IO22 0x06C 0x25C 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_EMC_23_SEMC_ADDR10 0x070 0x260 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_23_FLEXPWM1_PWM0_A 0x070 0x260 0x458 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_23_LPUART5_TXD 0x070 0x260 0x54C 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_23_ENET_RX_EN 0x070 0x260 0x43C 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_23_GPT1_CAPTURE2 0x070 0x260 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_23_GPIO4_IO23 0x070 0x260 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_EMC_24_SEMC_CAS 0x074 0x264 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_24_FLEXPWM1_PWM0_B 0x074 0x264 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_24_LPUART5_RXD 0x074 0x264 0x548 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_24_ENET_TX_EN 0x074 0x264 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_24_GPT1_CAPTURE1 0x074 0x264 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_24_GPIO4_IO24 0x074 0x264 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_EMC_25_SEMC_RAS 0x078 0x268 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_25_FLEXPWM1_PWM1_A 0x078 0x268 0x45C 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_25_LPUART6_TXD 0x078 0x268 0x554 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_25_ENET_TX_CLK 0x078 0x268 0x448 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_25_ENET_REF_CLK 0x078 0x268 0x42C 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_25_GPIO4_IO25 0x078 0x268 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_EMC_26_SEMC_CLK 0x07C 0x26C 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_26_FLEXPWM1_PWM1_B 0x07C 0x26C 0x46C 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_26_LPUART6_RXD 0x07C 0x26C 0x550 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_26_ENET_RX_ER 0x07C 0x26C 0x440 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_26_FLEXIO1_D12 0x07C 0x26C 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_26_GPIO4_IO26 0x07C 0x26C 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_EMC_27_SEMC_CKE 0x080 0x270 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_27_FLEXPWM1_PWM2_A 0x080 0x270 0x460 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_27_LPUART5_RTS_B 0x080 0x270 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_27_LPSPI1_SCK 0x080 0x270 0x4F0 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_27_FLEXIO1_D13 0x080 0x270 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_27_GPIO4_IO27 0x080 0x270 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_EMC_28_SEMC_WE 0x084 0x274 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_28_FLEXPWM1_PWM2_B 0x084 0x274 0x470 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_28_LPUART5_CTS_B 0x084 0x274 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_28_LPSPI1_SDO 0x084 0x274 0x4F8 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_28_FLEXIO1_D14 0x084 0x274 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_28_GPIO4_IO28 0x084 0x274 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_EMC_29_SEMC_CS0 0x088 0x278 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_29_FLEXPWM3_PWM0_A 0x088 0x278 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_29_LPUART6_RTS_B 0x088 0x278 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_29_LPSPI1_SDI 0x088 0x278 0x4F4 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_29_FLEXIO1_D15 0x088 0x278 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_29_GPIO4_IO29 0x088 0x278 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_EMC_30_SEMC_DA08 0x08C 0x27C 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_30_FLEXPWM3_PWM0_B 0x08C 0x27C 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_30_LPUART6_CTS_B 0x08C 0x27C 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_30_LPSPI1_PCS0 0x08C 0x27C 0x4EC 0x3 0x1
+#define MXRT1050_IOMUXC_GPIO_EMC_30_CSI_DATA23 0x08C 0x27C 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_30_GPIO4_IO30 0x08C 0x27C 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_EMC_31_SEMC_DA09 0x090 0x280 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_31_FLEXPWM3_PWM1_A 0x090 0x280 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_31_LPUART7_TXD 0x090 0x280 0x55C 0x2 0x1
+#define MXRT1050_IOMUXC_GPIO_EMC_31_LPSPI1_PCS1 0x090 0x280 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_31_CSI_DATA22 0x090 0x280 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_31_GPIO4_IO31 0x090 0x280 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_EMC_32_SEMC_DA10 0x094 0x284 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_32_FLEXPWM3_PWM1_B 0x094 0x284 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_32_LPUART7_RXD 0x094 0x284 0x558 0x2 0x1
+#define MXRT1050_IOMUXC_GPIO_EMC_32_CCM_PMIC_READY 0x094 0x284 0x3FC 0x3 0x4
+#define MXRT1050_IOMUXC_GPIO_EMC_32_CSI_DATA21 0x094 0x284 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_32_GPIO3_IO18 0x094 0x284 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_EMC_33_SEMC_DA11 0x098 0x288 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_33_FLEXPWM3_PWM2_A 0x098 0x288 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_33_USDHC1_RESET_B 0x098 0x288 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_33_SAI3_RX_DATA 0x098 0x288 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_33_CSI_DATA20 0x098 0x288 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_33_GPIO3_IO19 0x098 0x288 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_EMC_34_SEMC_DA12 0x09C 0x28C 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_34_FLEXPWM3_PWM2_B 0x09C 0x28C 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_34_USDHC1_VSELECT 0x09C 0x28C 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_34_SAI3_RX_SYNC 0x09C 0x28C 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_34_CSI_DATA19 0x09C 0x28C 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_34_GPIO3_IO20 0x09C 0x28C 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_EMC_35_SEMC_DA13 0x0A0 0x290 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_35_XBAR_INOUT18 0x0A0 0x290 0x630 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_35_GPT1_COMPARE1 0x0A0 0x290 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_35_SAI3_RX_BCLK 0x0A0 0x290 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_35_CSI_DATA18 0x0A0 0x290 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_35_GPIO3_IO21 0x0A0 0x290 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_35_USDHC1_CD_B 0x0A0 0x290 0x5D4 0x6 0x0
+
+#define MXRT1050_IOMUXC_GPIO_EMC_36_SEMC_DA14 0x0A4 0x294 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_36_XBAR_INOUT22 0x0A4 0x294 0x638 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_36_GPT1_COMPARE2 0x0A4 0x294 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_36_SAI3_TX_DATA 0x0A4 0x294 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_36_CSI_DATA17 0x0A4 0x294 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_36_GPIO3_IO22 0x0A4 0x294 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_36_USDHC1_WP 0x0A4 0x294 0x5D8 0x6 0x1
+
+#define MXRT1050_IOMUXC_GPIO_EMC_37_SEMC_DA15 0x0A8 0x298 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_37_XBAR_INOUT23 0x0A8 0x298 0x63C 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_37_GPT1_COMPARE3 0x0A8 0x298 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_37_SAI3_MCLK 0x0A8 0x298 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_37_CSI_DATA16 0x0A8 0x298 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_37_GPIO3_IO23 0x0A8 0x298 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_37_USDHC2_WP 0x0A8 0x298 0x608 0x6 0x0
+
+#define MXRT1050_IOMUXC_GPIO_EMC_38_SEMC_DM01 0x0AC 0x29C 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_38_FLEXPWM1_PWM3_A 0x0AC 0x29C 0x454 0x1 0x2
+#define MXRT1050_IOMUXC_GPIO_EMC_38_LPUART8_TXD 0x0AC 0x29C 0x564 0x2 0x2
+#define MXRT1050_IOMUXC_GPIO_EMC_38_SAI3_TX_BCLK 0x0AC 0x29C 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_38_CSI_FIELD 0x0AC 0x29C 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_38_GPIO3_IO24 0x0AC 0x29C 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_38_USDHC2_VSELECT 0x0AC 0x29C 0x000 0x6 0x0
+
+#define MXRT1050_IOMUXC_GPIO_EMC_39_SEMC_DQS 0x0B0 0x2A0 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_39_FLEXPWM1_PWM3_B 0x0B0 0x2A0 0x464 0x1 0x2
+#define MXRT1050_IOMUXC_GPIO_EMC_39_LPUART8_RXD 0x0B0 0x2A0 0x560 0x2 0x2
+#define MXRT1050_IOMUXC_GPIO_EMC_39_SAI3_TX_SYNC 0x0B0 0x2A0 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_39_WDOG1_B 0x0B0 0x2A0 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_39_GPIO3_IO25 0x0B0 0x2A0 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_39_USDHC2_CD_B 0x0B0 0x2A0 0x5E0 0x6 0x1
+
+#define MXRT1050_IOMUXC_GPIO_EMC_40_SEMC_RDY 0x0B4 0x2A4 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_40_GPT2_CAPTURE2 0x0B4 0x2A4 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_40_LPSPI1_PCS2 0x0B4 0x2A4 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_40_USB_OTG2_OC 0x0B4 0x2A4 0x5CC 0x3 0x1
+#define MXRT1050_IOMUXC_GPIO_EMC_40_ENET_MDC 0x0B4 0x2A4 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_40_GPIO3_IO26 0x0B4 0x2A4 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_40_USDHC2_RESET_B 0x0B4 0x2A4 0x000 0x6 0x0
+
+#define MXRT1050_IOMUXC_GPIO_EMC_41_SEMC_CSX0 0x0B8 0x2A8 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_41_GPT2_CAPTURE1 0x0B8 0x2A8 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_41_LPSPI1_PCS3 0x0B8 0x2A8 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_41_USB_OTG2_PWR 0x0B8 0x2A8 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_41_ENET_MDIO 0x0B8 0x2A8 0x430 0x4 0x1
+#define MXRT1050_IOMUXC_GPIO_EMC_41_GPIO3_IO27 0x0B8 0x2A8 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_41_USDHC2_VSELECT 0x0B8 0x2A8 0x000 0x6 0x0
+
+#define MXRT1050_IOMUXC_GPIO_AD_B0_00_FLEXPWM2_PWM3_A 0x0BC 0x2AC 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_00_XBAR_INOUT14 0x0BC 0x2AC 0x644 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_00_REF_CLK_32K 0x0BC 0x2AC 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_00_USB_OTG2_ID 0x0BC 0x2AC 0x3F8 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_00_LPI2C1_SCLS 0x0BC 0x2AC 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_00_GPIO1_IO00 0x0BC 0x2AC 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_00_USDHC1_RESET_B 0x0BC 0x2AC 0x000 0x6 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_00_LPSPI3_SCK 0x0BC 0x2AC 0x510 0x7 0x0
+
+#define MXRT1050_IOMUXC_GPIO_AD_B0_01_FLEXPWM2_PWM3_B 0x0C0 0x2B0 0x484 0x0 0x2
+#define MXRT1050_IOMUXC_GPIO_AD_B0_01_XBAR_INOUT15 0x0C0 0x2B0 0x648 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_01_REF_CLK_24M 0x0C0 0x2B0 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_01_USB_OTG1_ID 0x0C0 0x2B0 0x3F4 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_01_LPI2C1_SDAS 0x0C0 0x2B0 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_01_GPIO1_IO01 0x0C0 0x2B0 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_01_EWM_OUT_B 0x0C0 0x2B0 0x000 0x6 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_01_LPSPI3_SDO 0x0C0 0x2B0 0x518 0x7 0x1
+
+#define MXRT1050_IOMUXC_GPIO_AD_B0_02_FLEXCAN2_TX 0x0C4 0x2B4 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_02_XBAR_INOUT16 0x0C4 0x2B4 0x64C 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_02_LPUART6_TXD 0x0C4 0x2B4 0x554 0x2 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B0_02_USB_OTG1_PWR 0x0C4 0x2B4 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_02_FLEXPWM1_PWM0_X 0x0C4 0x2B4 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_02_GPIO1_IO02 0x0C4 0x2B4 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_02_LPI2C1_HREQ 0x0C4 0x2B4 0x000 0x6 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_02_LPSPI3_SDI 0x0C4 0x2B4 0x514 0x7 0x1
+
+#define MXRT1050_IOMUXC_GPIO_AD_B0_03_FLEXCAN2_RX 0x0C8 0x2B8 0x450 0x0 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B0_03_XBAR_INOUT17 0x0C8 0x2B8 0x62C 0x1 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B0_03_LPUART6_RXD 0x0C8 0x2B8 0x550 0x2 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B0_03_USB_OTG1_OC 0x0C8 0x2B8 0x5D0 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_03_FLEXPWM1_PWM1_X 0x0C8 0x2B8 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_03_GPIO1_IO03 0x0C8 0x2B8 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_03_REF_CLK_24M 0x0C8 0x2B8 0x000 0x6 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_03_LPSPI3_PCS0 0x0C8 0x2B8 0x50C 0x7 0x0
+
+#define MXRT1050_IOMUXC_GPIO_AD_B0_04_SRC_BOOT_MODE00 0x0CC 0x2BC 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_04_MQS_RIGHT 0x0CC 0x2BC 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_04_ENET_TX_DATA03 0x0CC 0x2BC 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_04_SAI2_TX_SYNC 0x0CC 0x2BC 0x5C4 0x3 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B0_04_CSI_DATA09 0x0CC 0x2BC 0x41C 0x4 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B0_04_GPIO1_IO04 0x0CC 0x2BC 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_04_PIT_TRIGGER00 0x0CC 0x2BC 0x000 0x6 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_04_LPSPI3_PCS1 0x0CC 0x2BC 0x000 0x7 0x0
+
+#define MXRT1050_IOMUXC_GPIO_AD_B0_05_SRC_BOOT_MODE01 0x0D0 0x2C0 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_05_MQS_LEFT 0x0D0 0x2C0 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_05_ENET_TX_DATA02 0x0D0 0x2C0 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_05_SAI2_TX_BCLK 0x0D0 0x2C0 0x5C0 0x3 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B0_05_CSI_DATA08 0x0D0 0x2C0 0x418 0x4 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B0_05_GPIO1_IO05 0x0D0 0x2C0 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_05_XBAR_INOUT17 0x0D0 0x2C0 0x62C 0x6 0x2
+#define MXRT1050_IOMUXC_GPIO_AD_B0_05_LPSPI3_PCS2 0x0D0 0x2C0 0x000 0x7 0x0
+
+#define MXRT1050_IOMUXC_GPIO_AD_B0_06_JTAG_TMS 0x0D4 0x2C4 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_06_GPT2_COMPARE1 0x0D4 0x2C4 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_06_ENET_RX_CLK 0x0D4 0x2C4 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_06_SAI2_RX_BCLK 0x0D4 0x2C4 0x5B4 0x3 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B0_06_CSI_DATA07 0x0D4 0x2C4 0x414 0x4 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B0_06_GPIO1_IO06 0x0D4 0x2C4 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_06_XBAR_INOUT18 0x0D4 0x2C4 0x630 0x6 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B0_06_LPSPI3_PCS3 0x0D4 0x2C4 0x000 0x7 0x0
+
+#define MXRT1050_IOMUXC_GPIO_AD_B0_07_JTAG_TCK 0x0D8 0x2C8 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_07_GPT2_COMPARE2 0x0D8 0x2C8 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_07_ENET_TX_ER 0x0D8 0x2C8 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_07_SAI2_RX_SYNC 0x0D8 0x2C8 0x5BC 0x3 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B0_07_CSI_DATA06 0x0D8 0x2C8 0x410 0x4 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B0_07_GPIO1_IO07 0x0D8 0x2C8 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_07_XBAR_INOUT19 0x0D8 0x2C8 0x654 0x6 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B0_07_ENET_1588_EVENT3_OUT 0x0D8 0x2C8 0x000 0x7 0x0
+
+#define MXRT1050_IOMUXC_GPIO_AD_B0_08_JTAG_MOD 0x0DC 0x2CC 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_08_GPT2_COMPARE3 0x0DC 0x2CC 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_08_ENET_RX_DATA03 0x0DC 0x2CC 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_08_SAI2_RX_DATA 0x0DC 0x2CC 0x5B8 0x3 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B0_08_CSI_DATA05 0x0DC 0x2CC 0x40C 0x4 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B0_08_GPIO1_IO08 0x0DC 0x2CC 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_08_XBAR_INOUT20 0x0DC 0x2CC 0x634 0x6 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B0_08_ENET_1588_EVENT3_IN 0x0DC 0x2CC 0x000 0x7 0x0
+
+#define MXRT1050_IOMUXC_GPIO_AD_B0_09_JTAG_TDI 0x0E0 0x2D0 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_09_FLEXPWM2_PWM3_A 0x0E0 0x2D0 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_09_ENET_RX_DATA02 0x0E0 0x2D0 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_09_SAI2_TX_DATA 0x0E0 0x2D0 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_09_CSI_DATA04 0x0E0 0x2D0 0x408 0x4 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B0_09_GPIO1_IO09 0x0E0 0x2D0 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_09_XBAR_INOUT21 0x0E0 0x2D0 0x658 0x6 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B0_09_GPT2_CLK 0x0E0 0x2D0 0x000 0x7 0x0
+
+#define MXRT1050_IOMUXC_GPIO_AD_B0_10_JTAG_TDO 0x0E4 0x2D4 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_10_FLEXPWM1_PWM3_A 0x0E4 0x2D4 0x454 0x1 0x3
+#define MXRT1050_IOMUXC_GPIO_AD_B0_10_ENET_CRS 0x0E4 0x2D4 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_10_SAI2_MCLK 0x0E4 0x2D4 0x5B0 0x3 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B0_10_CSI_DATA03 0x0E4 0x2D4 0x404 0x4 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B0_10_GPIO1_IO10 0x0E4 0x2D4 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_10_XBAR_INOUT22 0x0E4 0x2D4 0x638 0x6 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B0_10_ENET_1588_EVENT0_OUT 0x0E4 0x2D4 0x000 0x7 0x0
+
+#define MXRT1050_IOMUXC_GPIO_AD_B0_11_JTAG_TRSTB 0x0E8 0x2D8 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_11_FLEXPWM1_PWM3_B 0x0E8 0x2D8 0x464 0x1 0x3
+#define MXRT1050_IOMUXC_GPIO_AD_B0_11_ENET_COL 0x0E8 0x2D8 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_11_WDOG1_B 0x0E8 0x2D8 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_11_CSI_DATA02 0x0E8 0x2D8 0x400 0x4 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B0_11_GPIO1_IO11 0x0E8 0x2D8 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_11_XBAR_INOUT23 0x0E8 0x2D8 0x63C 0x6 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B0_11_ENET_1588_EVENT0_IN 0x0E8 0x2D8 0x444 0x7 0x1
+
+#define MXRT1050_IOMUXC_GPIO_AD_B0_12_LPI2C4_SCL 0x0EC 0x2DC 0x4E4 0x0 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B0_12_CCM_PMIC_READY 0x0EC 0x2DC 0x3FC 0x1 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B0_12_LPUART1_TXD 0x0EC 0x2DC 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_12_WDOG2_B 0x0EC 0x2DC 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_12_FLEXPWM1_PWM2_X 0x0EC 0x2DC 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_12_GPIO1_IO12 0x0EC 0x2DC 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_12_ENET_1588_EVENT1_OUT 0x0EC 0x2DC 0x000 0x6 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_12_NMI 0x0EC 0x2DC 0x568 0x7 0x0
+
+#define MXRT1050_IOMUXC_GPIO_AD_B0_13_LPI2C4_SDA 0x0F0 0x2E0 0x4E8 0x0 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B0_13_GPT1_CLK 0x0F0 0x2E0 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_13_LPUART1_RXD 0x0F0 0x2E0 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_13_EWM_OUT_B 0x0F0 0x2E0 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_13_FLEXPWM1_PWM3_X 0x0F0 0x2E0 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_13_GPIO1_IO13 0x0F0 0x2E0 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_13_ENET_1588_EVENT1_IN 0x0F0 0x2E0 0x000 0x6 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_13_REF_CLK_24M 0x0F0 0x2E0 0x000 0x7 0x0
+
+#define MXRT1050_IOMUXC_GPIO_AD_B0_14_USB_OTG2_OC 0x0F4 0x2E4 0x5CC 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_14_XBAR_INOUT24 0x0F4 0x2E4 0x640 0x1 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B0_14_LPUART1_CTS_B 0x0F4 0x2E4 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_14_ENET_1588_EVENT0_OUT 0x0F4 0x2E4 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_14_CSI_VSYNC 0x0F4 0x2E4 0x428 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_14_GPIO1_IO14 0x0F4 0x2E4 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_14_FLEXCAN2_TX 0x0F4 0x2E4 0x000 0x6 0x0
+
+#define MXRT1050_IOMUXC_GPIO_AD_B0_15_USB_OTG2_PWR 0x0F8 0x2E8 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_15_XBAR_INOUT25 0x0F8 0x2E8 0x650 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_15_LPUART1_RTS_B 0x0F8 0x2E8 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_15_ENET_1588_EVENT0_IN 0x0F8 0x2E8 0x444 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_15_CSI_HSYNC 0x0F8 0x2E8 0x420 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_15_GPIO1_IO15 0x0F8 0x2E8 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_15_FLEXCAN2_RX 0x0F8 0x2E8 0x450 0x6 0x2
+#define MXRT1050_IOMUXC_GPIO_AD_B0_15_WDOG1_WDOG_RST_B_DEB 0x0F8 0x2E8 0x000 0x7 0x0
+
+#define MXRT1050_IOMUXC_GPIO_AD_B1_00_USB_OTG2_ID 0x0FC 0x2EC 0x3F8 0x0 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_00_TMR3_TIMER0 0x0FC 0x2EC 0x57C 0x1 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_00_LPUART2_CTS_B 0x0FC 0x2EC 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_00_LPI2C1_SCL 0x0FC 0x2EC 0x4CC 0x3 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_00_WDOG1_B 0x0FC 0x2EC 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_00_GPIO1_IO16 0x0FC 0x2EC 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_00_USDHC1_WP 0x0FC 0x2EC 0x5D8 0x6 0x2
+#define MXRT1050_IOMUXC_GPIO_AD_B1_00_KPP_ROW07 0x0FC 0x2EC 0x000 0x7 0x0
+
+#define MXRT1050_IOMUXC_GPIO_AD_B1_01_USB_OTG1_PWR 0x100 0x2F0 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_01_TMR3_TIMER1 0x100 0x2F0 0x580 0x1 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_01_LPUART2_RTS_B 0x100 0x2F0 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_01_LPI2C1_SDA 0x100 0x2F0 0x4D0 0x3 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_01_CCM_PMIC_READY 0x100 0x2F0 0x3FC 0x4 0x2
+#define MXRT1050_IOMUXC_GPIO_AD_B1_01_GPIO1_IO17 0x100 0x2F0 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_01_USDHC1_VSELECT 0x100 0x2F0 0x000 0x6 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_01_KPP_COL07 0x100 0x2F0 0x000 0x7 0x0
+
+#define MXRT1050_IOMUXC_GPIO_AD_B1_02_USB_OTG1_ID 0x104 0x2F4 0x3F4 0x0 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_02_TMR3_TIMER2 0x104 0x2F4 0x584 0x1 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_02_LPUART2_TXD 0x104 0x2F4 0x530 0x2 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_02_SPDIF_OUT 0x104 0x2F4 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_02_ENET_1588_EVENT2_OUT 0x104 0x2F4 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_02_GPIO1_IO18 0x104 0x2F4 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_02_USDHC1_CD_B 0x104 0x2F4 0x5D4 0x6 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_02_KPP_ROW06 0x104 0x2F4 0x000 0x7 0x0
+
+#define MXRT1050_IOMUXC_GPIO_AD_B1_03_USB_OTG1_OC 0x108 0x2F8 0x5D0 0x0 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_03_TMR3_TIMER3 0x108 0x2F8 0x588 0x1 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_03_LPUART2_RXD 0x108 0x2F8 0x52C 0x2 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_03_SPDIF_IN 0x108 0x2F8 0x5C8 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_03_ENET_1588_EVENT2_IN 0x108 0x2F8 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_03_GPIO1_IO19 0x108 0x2F8 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_03_USDHC2_CD_B 0x108 0x2F8 0x5E0 0x6 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_03_KPP_COL06 0x108 0x2F8 0x000 0x7 0x0
+
+#define MXRT1050_IOMUXC_GPIO_AD_B1_04_FLEXSPI_B_DATA3 0x10C 0x2FC 0x4C4 0x0 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_04_ENET_MDC 0x10C 0x2FC 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_04_LPUART3_CTS_B 0x10C 0x2FC 0x534 0x2 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_04_SPDIF_SR_CLK 0x10C 0x2FC 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_04_CSI_PIXCLK 0x10C 0x2FC 0x424 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_04_GPIO1_IO20 0x10C 0x2FC 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_04_USDHC2_DATA0 0x10C 0x2FC 0x5E8 0x6 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_04_KPP_ROW05 0x10C 0x2FC 0x000 0x7 0x0
+
+#define MXRT1050_IOMUXC_GPIO_AD_B1_05_FLEXSPI_B_DATA2 0x110 0x300 0x4C0 0x0 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_05_ENET_MDIO 0x110 0x300 0x430 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_05_LPUART3_RTS_B 0x110 0x300 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_05_SPDIF_OUT 0x110 0x300 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_05_CSI_MCLK 0x110 0x300 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_05_GPIO1_IO21 0x110 0x300 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_05_USDHC2_DATA1 0x110 0x300 0x5EC 0x6 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_05_KPP_COL05 0x110 0x300 0x000 0x7 0x0
+
+#define MXRT1050_IOMUXC_GPIO_AD_B1_06_FLEXSPI_B_DATA1 0x114 0x304 0x4BC 0x0 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_06_LPI2C3_SDA 0x114 0x304 0x4E0 0x1 0x2
+#define MXRT1050_IOMUXC_GPIO_AD_B1_06_LPUART3_TXD 0x114 0x304 0x53C 0x2 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_06_SPDIF_LOCK 0x114 0x304 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_06_CSI_VSYNC 0x114 0x304 0x428 0x4 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_06_GPIO1_IO22 0x114 0x304 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_06_USDHC2_DATA2 0x114 0x304 0x5F0 0x6 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_06_KPP_ROW04 0x114 0x304 0x000 0x7 0x0
+
+#define MXRT1050_IOMUXC_GPIO_AD_B1_07_FLEXSPI_B_DATA0 0x118 0x308 0x4B8 0x0 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_07_LPI2C3_SCL 0x118 0x308 0x4DC 0x1 0x2
+#define MXRT1050_IOMUXC_GPIO_AD_B1_07_LPUART3_RXD 0x118 0x308 0x538 0x2 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_07_SPDIF_EXT_CLK 0x118 0x308 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_07_CSI_HSYNC 0x118 0x308 0x420 0x4 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_07_GPIO1_IO23 0x118 0x308 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_07_USDHC2_DATA3 0x118 0x308 0x5F4 0x6 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_07_KPP_COL04 0x118 0x308 0x000 0x7 0x0
+
+#define MXRT1050_IOMUXC_GPIO_AD_B1_08_FLEXSPI_A_SS1_B 0x11C 0x30C 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_08_FLEXPWM4_PWM0_A 0x11C 0x30C 0x494 0x1 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_08_FLEXCAN1_TX 0x11C 0x30C 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_08_CCM_PMIC_READY 0x11C 0x30C 0x3FC 0x3 0x3
+#define MXRT1050_IOMUXC_GPIO_AD_B1_08_CSI_DATA09 0x11C 0x30C 0x41C 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_08_GPIO1_IO24 0x11C 0x30C 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_08_USDHC2_CMD 0x11C 0x30C 0x5E4 0x6 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_08_KPP_ROW03 0x11C 0x30C 0x000 0x7 0x0
+
+#define MXRT1050_IOMUXC_GPIO_AD_B1_09_FLEXSPI_A_DQS 0x120 0x310 0x4A4 0x0 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_09_FLEXPWM4_PWM1_A 0x120 0x310 0x498 0x1 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_09_FLEXCAN1_RX 0x120 0x310 0x44C 0x2 0x2
+#define MXRT1050_IOMUXC_GPIO_AD_B1_09_SAI1_MCLK 0x120 0x310 0x58C 0x3 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_09_CSI_DATA08 0x120 0x310 0x418 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_09_GPIO1_IO25 0x120 0x310 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_09_USDHC2_CLK 0x120 0x310 0x5DC 0x6 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_09_KPP_COL03 0x120 0x310 0x000 0x7 0x0
+
+#define MXRT1050_IOMUXC_GPIO_AD_B1_10_FLEXSPI_A_DATA3 0x124 0x314 0x4B4 0x0 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_10_WDOG1_B 0x124 0x314 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_10_LPUART8_TXD 0x124 0x314 0x564 0x2 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_10_SAI1_RX_SYNC 0x124 0x314 0x5A4 0x3 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_10_CSI_DATA07 0x124 0x314 0x414 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_10_GPIO1_IO26 0x124 0x314 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_10_USDHC2_WP 0x124 0x314 0x608 0x6 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_10_KPP_ROW02 0x124 0x314 0x000 0x7 0x0
+
+#define MXRT1050_IOMUXC_GPIO_AD_B1_11_FLEXSPI_A_DATA2 0x128 0x318 0x4B0 0x0 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_11_EWM_OUT_B 0x128 0x318 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_11_LPUART8_RXD 0x128 0x318 0x560 0x2 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_11_SAI1_RX_BCLK 0x128 0x318 0x590 0x3 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_11_CSI_DATA06 0x128 0x318 0x410 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_11_GPIO1_IO27 0x128 0x318 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_11_USDHC2_RESET_B 0x128 0x318 0x000 0x6 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_11_KPP_COL02 0x128 0x318 0x000 0x7 0x0
+
+#define MXRT1050_IOMUXC_GPIO_AD_B1_12_FLEXSPI_A_DATA1 0x12C 0x31C 0x4AC 0x0 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_12_ACMP1_OUT 0x12C 0x31C 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_12_LPSPI3_PCS0 0x12C 0x31C 0x50C 0x2 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_12_SAI1_RX_DATA00 0x12C 0x31C 0x594 0x3 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_12_CSI_DATA05 0x12C 0x31C 0x40C 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_12_GPIO1_IO28 0x12C 0x31C 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_12_USDHC2_DATA4 0x12C 0x31C 0x5F8 0x6 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_12_KPP_ROW01 0x12C 0x31C 0x000 0x7 0x0
+
+#define MXRT1050_IOMUXC_GPIO_AD_B1_13_FLEXSPI_A_DATA0 0x130 0x320 0x4A8 0x0 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_13_ACMP2_OUT 0x130 0x320 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_13_LPSPI3_SDI 0x130 0x320 0x514 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_13_SAI1_TX_DATA00 0x130 0x320 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_13_CSI_DATA04 0x130 0x320 0x408 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_13_GPIO1_IO29 0x130 0x320 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_13_USDHC2_DATA5 0x130 0x320 0x5FC 0x6 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_13_KPP_COL01 0x130 0x320 0x000 0x7 0x0
+
+#define MXRT1050_IOMUXC_GPIO_AD_B1_14_FLEXSPI_A_SCLK 0x134 0x324 0x4C8 0x0 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_14_ACMP3_OUT 0x134 0x324 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_14_LPSPI3_SDO 0x134 0x324 0x518 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_14_SAI1_TX_BCLK 0x134 0x324 0x5A8 0x3 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_14_CSI_DATA03 0x134 0x324 0x404 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_14_GPIO1_IO30 0x134 0x324 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_14_USDHC2_DATA6 0x134 0x324 0x600 0x6 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_14_KPP_ROW00 0x134 0x324 0x000 0x7 0x0
+
+#define MXRT1050_IOMUXC_GPIO_AD_B1_15_FLEXSPI_A_SS0_B 0x138 0x328 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_15_ACMP4_OUT 0x138 0x328 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_15_LPSPI3_SCK 0x138 0x328 0x510 0x2 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_15_SAI1_TX_SYNC 0x138 0x328 0x5AC 0x3 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_15_CSI_DATA02 0x138 0x328 0x400 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_15_GPIO1_IO31 0x138 0x328 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_15_USDHC2_DATA7 0x138 0x328 0x604 0x6 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_15_KPP_COL00 0x138 0x328 0x000 0x7 0x0
+
+#define MXRT1050_IOMUXC_GPIO_B0_00_LCD_CLK 0x13C 0x32C 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_00_TMR1_TIMER0 0x13C 0x32C 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_00_MQS_RIGHT 0x13C 0x32C 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_00_LPSPI4_PCS0 0x13C 0x32C 0x51C 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_00_FLEXIO2_D00 0x13C 0x32C 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_00_GPIO2_IO00 0x13C 0x32C 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_00_SEMC_CSX1 0x13C 0x32C 0x000 0x6 0x0
+
+#define MXRT1050_IOMUXC_GPIO_B0_01_LCD_ENABLE 0x140 0x330 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_01_TMR1_TIMER1 0x140 0x330 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_01_MQS_LEFT 0x140 0x330 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_01_LPSPI4_SDI 0x140 0x330 0x524 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_01_FLEXIO2_D01 0x140 0x330 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_01_GPIO2_IO01 0x140 0x330 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_01_SEMC_CSX2 0x140 0x330 0x000 0x6 0x0
+
+#define MXRT1050_IOMUXC_GPIO_B0_02_LCD_HSYNC 0x144 0x334 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_02_TMR1_TIMER2 0x144 0x334 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_02_FLEXCAN1_TX 0x144 0x334 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_02_LPSPI4_SDO 0x144 0x334 0x528 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_02_FLEXIO2_D02 0x144 0x334 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_02_GPIO2_IO02 0x144 0x334 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_02_SEMC_CSX3 0x144 0x334 0x000 0x6 0x0
+
+#define MXRT1050_IOMUXC_GPIO_B0_03_LCD_VSYNC 0x148 0x338 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_03_TMR2_TIMER0 0x148 0x338 0x56C 0x1 0x1
+#define MXRT1050_IOMUXC_GPIO_B0_03_FLEXCAN1_RX 0x148 0x338 0x44C 0x2 0x3
+#define MXRT1050_IOMUXC_GPIO_B0_03_LPSPI4_SCK 0x148 0x338 0x520 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_03_FLEXIO2_D03 0x148 0x338 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_03_GPIO2_IO03 0x148 0x338 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_03_WDOG2_RESET_B_DEB 0x148 0x338 0x000 0x6 0x0
+
+#define MXRT1050_IOMUXC_GPIO_B0_04_LCD_DATA00 0x14C 0x33C 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_04_TMR2_TIMER1 0x14C 0x33C 0x570 0x1 0x1
+#define MXRT1050_IOMUXC_GPIO_B0_04_LPI2C2_SCL 0x14C 0x33C 0x4D4 0x2 0x1
+#define MXRT1050_IOMUXC_GPIO_B0_04_ARM_TRACE00 0x14C 0x33C 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_04_FLEXIO2_D04 0x14C 0x33C 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_04_GPIO2_IO04 0x14C 0x33C 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_04_SRC_BT_CFG00 0x14C 0x33C 0x000 0x6 0x0
+
+#define MXRT1050_IOMUXC_GPIO_B0_05_LCD_DATA01 0x150 0x340 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_05_TMR2_TIMER2 0x150 0x340 0x574 0x1 0x1
+#define MXRT1050_IOMUXC_GPIO_B0_05_LPI2C2_SDA 0x150 0x340 0x4D8 0x2 0x1
+#define MXRT1050_IOMUXC_GPIO_B0_05_ARM_TRACE01 0x150 0x340 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_05_FLEXIO2_D05 0x150 0x340 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_05_GPIO2_IO05 0x150 0x340 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_05_SRC_BT_CFG01 0x150 0x340 0x000 0x6 0x0
+
+#define MXRT1050_IOMUXC_GPIO_B0_06_LCD_DATA02 0x154 0x344 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_06_TMR3_TIMER0 0x154 0x344 0x57C 0x1 0x2
+#define MXRT1050_IOMUXC_GPIO_B0_06_FLEXPWM2_PWM0_A 0x154 0x344 0x478 0x2 0x1
+#define MXRT1050_IOMUXC_GPIO_B0_06_ARM_TRACE02 0x154 0x344 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_06_FLEXIO2_D06 0x154 0x344 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_06_GPIO2_IO06 0x154 0x344 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_06_SRC_BT_CFG02 0x154 0x344 0x000 0x6 0x0
+
+#define MXRT1050_IOMUXC_GPIO_B0_07_LCD_DATA03 0x158 0x348 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_07_TMR3_TIMER1 0x158 0x348 0x580 0x1 0x2
+#define MXRT1050_IOMUXC_GPIO_B0_07_FLEXPWM2_PWM0_B 0x158 0x348 0x488 0x2 0x1
+#define MXRT1050_IOMUXC_GPIO_B0_07_ARM_TRACE03 0x158 0x348 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_07_FLEXIO2_D07 0x158 0x348 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_07_GPIO2_IO07 0x158 0x348 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_07_SRC_BT_CFG03 0x158 0x348 0x000 0x6 0x0
+
+#define MXRT1050_IOMUXC_GPIO_B0_08_LCD_DATA04 0x15C 0x34C 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_08_TMR3_TIMER2 0x15C 0x34C 0x584 0x1 0x2
+#define MXRT1050_IOMUXC_GPIO_B0_08_FLEXPWM2_PWM1_A 0x15C 0x34C 0x47C 0x2 0x1
+#define MXRT1050_IOMUXC_GPIO_B0_08_LPUART3_TXD 0x15C 0x34C 0x53C 0x3 0x2
+#define MXRT1050_IOMUXC_GPIO_B0_08_FLEXIO2_D08 0x15C 0x34C 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_08_GPIO2_IO08 0x15C 0x34C 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_08_SRC_BT_CFG04 0x15C 0x34C 0x000 0x6 0x0
+
+#define MXRT1050_IOMUXC_GPIO_B0_09_LCD_DATA05 0x160 0x350 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_09_TMR4_TIMER0 0x160 0x350 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_09_FLEXPWM2_PWM1_B 0x160 0x350 0x48C 0x2 0x1
+#define MXRT1050_IOMUXC_GPIO_B0_09_LPUART3_RXD 0x160 0x350 0x538 0x3 0x2
+#define MXRT1050_IOMUXC_GPIO_B0_09_FLEXIO2_D09 0x160 0x350 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_09_GPIO2_IO09 0x160 0x350 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_09_SRC_BT_CFG05 0x160 0x350 0x000 0x6 0x0
+
+#define MXRT1050_IOMUXC_GPIO_B0_10_LCD_DATA06 0x164 0x354 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_10_TMR4_TIMER1 0x164 0x354 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_10_FLEXPWM2_PWM2_A 0x164 0x354 0x480 0x2 0x1
+#define MXRT1050_IOMUXC_GPIO_B0_10_SAI1_TX_DATA03 0x164 0x354 0x598 0x3 0x1
+#define MXRT1050_IOMUXC_GPIO_B0_10_FLEXIO2_D10 0x164 0x354 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_10_GPIO2_IO10 0x164 0x354 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_10_SRC_BT_CFG06 0x164 0x354 0x000 0x6 0x0
+
+#define MXRT1050_IOMUXC_GPIO_B0_11_LCD_DATA07 0x168 0x358 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_11_TMR4_TIMER2 0x168 0x358 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_11_FLEXPWM2_PWM2_B 0x168 0x358 0x490 0x2 0x1
+#define MXRT1050_IOMUXC_GPIO_B0_11_SAI1_TX_DATA02 0x168 0x358 0x59C 0x3 0x1
+#define MXRT1050_IOMUXC_GPIO_B0_11_FLEXIO2_D11 0x168 0x358 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_11_GPIO2_IO11 0x168 0x358 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_11_SRC_BT_CFG07 0x168 0x358 0x000 0x6 0x0
+
+#define MXRT1050_IOMUXC_GPIO_B0_12_LCD_DATA08 0x16C 0x35C 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_12_XBAR_INOUT10 0x16C 0x35C 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_12_ARM_TRACE_CLK 0x16C 0x35C 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_12_SAI1_TX_DATA01 0x16C 0x35C 0x5A0 0x3 0x1
+#define MXRT1050_IOMUXC_GPIO_B0_12_FLEXIO2_D12 0x16C 0x35C 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_12_GPIO2_IO12 0x16C 0x35C 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_12_SRC_BT_CFG08 0x16C 0x35C 0x000 0x6 0x0
+
+#define MXRT1050_IOMUXC_GPIO_B0_13_LCD_DATA09 0x170 0x360 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_13_XBAR_INOUT11 0x170 0x360 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_13_ARM_TRACE_SWO 0x170 0x360 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_13_SAI1_MCLK 0x170 0x360 0x58C 0x3 0x2
+#define MXRT1050_IOMUXC_GPIO_B0_13_FLEXIO2_D13 0x170 0x360 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_13_GPIO2_IO13 0x170 0x360 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_13_SRC_BT_CFG09 0x170 0x360 0x000 0x6 0x0
+
+#define MXRT1050_IOMUXC_GPIO_B0_14_LCD_DATA10 0x174 0x364 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_14_XBAR_INOUT12 0x174 0x364 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_14_ARM_CM7_TXEV 0x174 0x364 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_14_SAI1_RX_SYNC 0x174 0x364 0x5A4 0x3 0x2
+#define MXRT1050_IOMUXC_GPIO_B0_14_FLEXIO2_D14 0x174 0x364 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_14_GPIO2_IO14 0x174 0x364 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_14_SRC_BT_CFG10 0x174 0x364 0x000 0x6 0x0
+
+#define MXRT1050_IOMUXC_GPIO_B0_15_LCD_DATA11 0x178 0x368 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_15_XBAR_INOUT13 0x178 0x368 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_15_ARM_CM7_RXEV 0x178 0x368 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_15_SAI1_RX_BCLK 0x178 0x368 0x590 0x3 0x2
+#define MXRT1050_IOMUXC_GPIO_B0_15_FLEXIO2_D15 0x178 0x368 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_15_GPIO2_IO15 0x178 0x368 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_15_SRC_BT_CFG11 0x178 0x368 0x000 0x6 0x0
+
+#define MXRT1050_IOMUXC_GPIO_B1_00_LCD_DATA12 0x17C 0x36C 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_00_XBAR_INOUT14 0x17C 0x36C 0x644 0x1 0x1
+#define MXRT1050_IOMUXC_GPIO_B1_00_LPUART4_TXD 0x17C 0x36C 0x544 0x2 0x2
+#define MXRT1050_IOMUXC_GPIO_B1_00_SAI1_RX_DATA00 0x17C 0x36C 0x594 0x3 0x2
+#define MXRT1050_IOMUXC_GPIO_B1_00_FLEXIO2_D16 0x17C 0x36C 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_00_GPIO2_IO16 0x17C 0x36C 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_00_FLEXPWM1_PWM3_A 0x17C 0x36C 0x454 0x6 0x4
+
+#define MXRT1050_IOMUXC_GPIO_B1_01_LCD_DATA13 0x180 0x370 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_01_XBAR_INOUT15 0x180 0x370 0x648 0x1 0x1
+#define MXRT1050_IOMUXC_GPIO_B1_01_LPUART4_RXD 0x180 0x370 0x540 0x2 0x2
+#define MXRT1050_IOMUXC_GPIO_B1_01_SAI1_TX_DATA00 0x180 0x370 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_01_FLEXIO2_D17 0x180 0x370 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_01_GPIO2_IO17 0x180 0x370 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_01_FLEXPWM1_PWM3_B 0x180 0x370 0x464 0x6 0x4
+
+#define MXRT1050_IOMUXC_GPIO_B1_02_LCD_DATA14 0x184 0x374 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_02_XBAR_INOUT16 0x184 0x374 0x64C 0x1 0x1
+#define MXRT1050_IOMUXC_GPIO_B1_02_LPSPI4_PCS2 0x184 0x374 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_02_SAI1_TX_BCLK 0x184 0x374 0x5A8 0x3 0x2
+#define MXRT1050_IOMUXC_GPIO_B1_02_FLEXIO2_D18 0x184 0x374 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_02_GPIO2_IO18 0x184 0x374 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_02_FLEXPWM2_PWM3_A 0x184 0x374 0x000 0x6 0x0
+
+#define MXRT1050_IOMUXC_GPIO_B1_03_LCD_DATA15 0x188 0x378 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_03_XBAR_INOUT17 0x188 0x378 0x62C 0x1 0x3
+#define MXRT1050_IOMUXC_GPIO_B1_03_LPSPI4_PCS1 0x188 0x378 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_03_SAI1_TX_SYNC 0x188 0x378 0x5AC 0x3 0x2
+#define MXRT1050_IOMUXC_GPIO_B1_03_FLEXIO2_D19 0x188 0x378 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_03_GPIO2_IO19 0x188 0x378 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_03_FLEXPWM2_PWM3_B 0x188 0x378 0x484 0x6 0x3
+
+#define MXRT1050_IOMUXC_GPIO_B1_04_LCD_DATA16 0x18C 0x37C 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_04_LPSPI4_PCS0 0x18C 0x37C 0x51C 0x1 0x1
+#define MXRT1050_IOMUXC_GPIO_B1_04_CSI_DATA15 0x18C 0x37C 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_04_ENET_RX_DATA00 0x18C 0x37C 0x434 0x3 0x1
+#define MXRT1050_IOMUXC_GPIO_B1_04_FLEXIO2_D20 0x18C 0x37C 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_04_GPIO2_IO20 0x18C 0x37C 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_B1_05_LCD_DATA17 0x190 0x380 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_05_LPSPI4_SDI 0x190 0x380 0x524 0x1 0x1
+#define MXRT1050_IOMUXC_GPIO_B1_05_CSI_DATA14 0x190 0x380 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_05_ENET_RX_DATA01 0x190 0x380 0x438 0x3 0x1
+#define MXRT1050_IOMUXC_GPIO_B1_05_FLEXIO2_D21 0x190 0x380 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_05_GPIO2_IO21 0x190 0x380 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_B1_06_LCD_DATA18 0x194 0x384 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_06_LPSPI4_SDO 0x194 0x384 0x528 0x1 0x1
+#define MXRT1050_IOMUXC_GPIO_B1_06_CSI_DATA13 0x194 0x384 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_06_ENET_RX_EN 0x194 0x384 0x43C 0x3 0x1
+#define MXRT1050_IOMUXC_GPIO_B1_06_FLEXIO2_D22 0x194 0x384 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_06_GPIO2_IO22 0x194 0x384 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_B1_07_LCD_DATA19 0x198 0x388 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_07_LPSPI4_SCK 0x198 0x388 0x520 0x1 0x1
+#define MXRT1050_IOMUXC_GPIO_B1_07_CSI_DATA12 0x198 0x388 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_07_ENET_TX_DATA00 0x198 0x388 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_07_FLEXIO2_D23 0x198 0x388 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_07_GPIO2_IO23 0x198 0x388 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_B1_08_LCD_DATA20 0x19C 0x38C 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_08_TMR1_TIMER3 0x19C 0x38C 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_08_CSI_DATA11 0x19C 0x38C 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_08_ENET_TX_DATA01 0x19C 0x38C 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_08_FLEXIO2_D24 0x19C 0x38C 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_08_GPIO2_IO24 0x19C 0x38C 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_08_FLEXCAN2_TX 0x19C 0x38C 0x000 0x6 0x0
+
+#define MXRT1050_IOMUXC_GPIO_B1_09_LCD_DATA21 0x1A0 0x390 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_09_TMR2_TIMER3 0x1A0 0x390 0x578 0x1 0x1
+#define MXRT1050_IOMUXC_GPIO_B1_09_CSI_DATA10 0x1A0 0x390 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_09_ENET_TX_EN 0x1A0 0x390 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_09_FLEXIO2_D25 0x1A0 0x390 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_09_GPIO2_IO25 0x1A0 0x390 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_09_FLEXCAN2_RX 0x1A0 0x390 0x450 0x6 0x3
+
+#define MXRT1050_IOMUXC_GPIO_B1_10_LCD_DATA22 0x1A4 0x394 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_10_TMR3_TIMER3 0x1A4 0x394 0x588 0x1 0x2
+#define MXRT1050_IOMUXC_GPIO_B1_10_CSI_DATA00 0x1A4 0x394 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_10_ENET_TX_CLK 0x1A4 0x394 0x448 0x3 0x1
+#define MXRT1050_IOMUXC_GPIO_B1_10_FLEXIO2_D26 0x1A4 0x394 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_10_GPIO2_IO26 0x1A4 0x394 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_10_ENET_REF_CLK 0x1A4 0x394 0x42C 0x6 0x1
+
+#define MXRT1050_IOMUXC_GPIO_B1_11_LCD_DATA23 0x1A8 0x398 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_11_TMR4_TIMER3 0x1A8 0x398 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_11_CSI_DATA01 0x1A8 0x398 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_11_ENET_RX_ER 0x1A8 0x398 0x440 0x3 0x1
+#define MXRT1050_IOMUXC_GPIO_B1_11_FLEXIO2_D27 0x1A8 0x398 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_11_GPIO2_IO27 0x1A8 0x398 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_11_LPSPI4_PCS3 0x1A8 0x398 0x000 0x6 0x0
+
+#define MXRT1050_IOMUXC_GPIO_B1_12_LPUART5_TXD 0x1AC 0x39C 0x54C 0x1 0x1
+#define MXRT1050_IOMUXC_GPIO_B1_12_CSI_PIXCLK 0x1AC 0x39C 0x424 0x2 0x1
+#define MXRT1050_IOMUXC_GPIO_B1_12_ENET_1588_EVENT0_IN 0x1AC 0x39C 0x444 0x3 0x2
+#define MXRT1050_IOMUXC_GPIO_B1_12_FLEXIO2_D28 0x1AC 0x39C 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_12_GPIO2_IO28 0x1AC 0x39C 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_12_USDHC1_CD_B 0x1AC 0x39C 0x5D4 0x6 0x2
+
+#define MXRT1050_IOMUXC_GPIO_B1_13_WDOG1_B 0x1B0 0x3A0 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_13_LPUART5_RXD 0x1B0 0x3A0 0x548 0x1 0x1
+#define MXRT1050_IOMUXC_GPIO_B1_13_CSI_VSYNC 0x1B0 0x3A0 0x428 0x2 0x2
+#define MXRT1050_IOMUXC_GPIO_B1_13_ENET_1588_EVENT0_OUT 0x1B0 0x3A0 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_13_FLEXIO2_D29 0x1B0 0x3A0 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_13_GPIO2_IO29 0x1B0 0x3A0 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_13_USDHC1_WP 0x1B0 0x3A0 0x5D8 0x6 0x3
+
+#define MXRT1050_IOMUXC_GPIO_B1_14_ENET_MDC 0x1B4 0x3A4 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_14_FLEXPWM4_PWM2_A 0x1B4 0x3A4 0x49C 0x1 0x1
+#define MXRT1050_IOMUXC_GPIO_B1_14_CSI_HSYNC 0x1B4 0x3A4 0x420 0x2 0x2
+#define MXRT1050_IOMUXC_GPIO_B1_14_XBAR_INOUT02 0x1B4 0x3A4 0x60C 0x3 0x1
+#define MXRT1050_IOMUXC_GPIO_B1_14_FLEXIO2_D30 0x1B4 0x3A4 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_14_GPIO2_IO30 0x1B4 0x3A4 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_14_USDHC1_VSELECT 0x1B4 0x3A4 0x000 0x6 0x0
+
+#define MXRT1050_IOMUXC_GPIO_B1_15_ENET_MDIO 0x1B8 0x3A8 0x430 0x0 0x2
+#define MXRT1050_IOMUXC_GPIO_B1_15_FLEXPWM4_PWM3_A 0x1B8 0x3A8 0x4A0 0x1 0x1
+#define MXRT1050_IOMUXC_GPIO_B1_15_CSI_MCLK 0x1B8 0x3A8 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_15_XBAR_INOUT03 0x1B8 0x3A8 0x610 0x3 0x1
+#define MXRT1050_IOMUXC_GPIO_B1_15_FLEXIO2_D31 0x1B8 0x3A8 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_15_GPIO2_IO31 0x1B8 0x3A8 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_15_USDHC1_RESET_B 0x1B8 0x3A8 0x000 0x6 0x0
+
+#define MXRT1050_IOMUXC_GPIO_SD_B0_00_USDHC1_CMD 0x1BC 0x3AC 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B0_00_FLEXPWM1_PWM0_A 0x1BC 0x3AC 0x458 0x1 0x1
+#define MXRT1050_IOMUXC_GPIO_SD_B0_00_LPI2C3_SCL 0x1BC 0x3AC 0x4DC 0x2 0x1
+#define MXRT1050_IOMUXC_GPIO_SD_B0_00_XBAR_INOUT04 0x1BC 0x3AC 0x614 0x3 0x1
+#define MXRT1050_IOMUXC_GPIO_SD_B0_00_LPSPI1_SCK 0x1BC 0x3AC 0x4F0 0x4 0x1
+#define MXRT1050_IOMUXC_GPIO_SD_B0_00_GPIO3_IO12 0x1BC 0x3AC 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B0_00_FLEXSPI_A_SS1_B 0x1BC 0x3AC 0x000 0x6 0x0
+
+#define MXRT1050_IOMUXC_GPIO_SD_B0_01_USDHC1_CLK 0x1C0 0x3B0 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B0_01_FLEXPWM1_PWM0_B 0x1C0 0x3B0 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B0_01_LPI2C3_SDA 0x1C0 0x3B0 0x4E0 0x2 0x1
+#define MXRT1050_IOMUXC_GPIO_SD_B0_01_XBAR_INOUT05 0x1C0 0x3B0 0x618 0x3 0x1
+#define MXRT1050_IOMUXC_GPIO_SD_B0_01_LPSPI1_PCS0 0x1C0 0x3B0 0x4EC 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B0_01_GPIO3_IO13 0x1C0 0x3B0 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B0_01_FLEXSPI_B_SS1_B 0x1C0 0x3B0 0x000 0x6 0x0
+
+#define MXRT1050_IOMUXC_GPIO_SD_B0_02_USDHC1_DATA0 0x1C4 0x3B4 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B0_02_FLEXPWM1_PWM1_A 0x1C4 0x3B4 0x45C 0x1 0x1
+#define MXRT1050_IOMUXC_GPIO_SD_B0_02_LPUART8_CTS_B 0x1C4 0x3B4 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B0_02_XBAR_INOUT06 0x1C4 0x3B4 0x61C 0x3 0x1
+#define MXRT1050_IOMUXC_GPIO_SD_B0_02_LPSPI1_SDO 0x1C4 0x3B4 0x4F8 0x4 0x1
+#define MXRT1050_IOMUXC_GPIO_SD_B0_02_GPIO3_IO14 0x1C4 0x3B4 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_SD_B0_03_USDHC1_DATA1 0x1C8 0x3B8 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B0_03_FLEXPWM1_PWM1_B 0x1C8 0x3B8 0x46C 0x1 0x1
+#define MXRT1050_IOMUXC_GPIO_SD_B0_03_LPUART8_RTS_B 0x1C8 0x3B8 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B0_03_XBAR_INOUT07 0x1C8 0x3B8 0x620 0x3 0x1
+#define MXRT1050_IOMUXC_GPIO_SD_B0_03_LPSPI1_SDI 0x1C8 0x3B8 0x4F4 0x4 0x1
+#define MXRT1050_IOMUXC_GPIO_SD_B0_03_GPIO3_IO15 0x1C8 0x3B8 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_SD_B0_04_USDHC1_DATA2 0x1CC 0x3BC 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B0_04_FLEXPWM1_PWM2_A 0x1CC 0x3BC 0x460 0x1 0x1
+#define MXRT1050_IOMUXC_GPIO_SD_B0_04_LPUART8_TXD 0x1CC 0x3BC 0x564 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B0_04_XBAR_INOUT08 0x1CC 0x3BC 0x624 0x3 0x1
+#define MXRT1050_IOMUXC_GPIO_SD_B0_04_FLEXSPI_B_SS0_B 0x1CC 0x3BC 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B0_04_GPIO3_IO16 0x1CC 0x3BC 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B0_04_CCM_CLKO1 0x1CC 0x3BC 0x000 0x6 0x0
+
+#define MXRT1050_IOMUXC_GPIO_SD_B0_05_USDHC1_DATA3 0x1D0 0x3C0 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B0_05_FLEXPWM1_PWM2_B 0x1D0 0x3C0 0x470 0x1 0x1
+#define MXRT1050_IOMUXC_GPIO_SD_B0_05_LPUART8_RXD 0x1D0 0x3C0 0x560 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B0_05_XBAR_INOUT09 0x1D0 0x3C0 0x628 0x3 0x1
+#define MXRT1050_IOMUXC_GPIO_SD_B0_05_FLEXSPI_B_DQS 0x1D0 0x3C0 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B0_05_GPIO3_IO17 0x1D0 0x3C0 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B0_05_CCM_CLKO2 0x1D0 0x3C0 0x000 0x6 0x0
+
+#define MXRT1050_IOMUXC_GPIO_SD_B1_00_USDHC2_DATA3 0x1D4 0x3C4 0x5F4 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_00_FLEXSPI_B_DATA3 0x1D4 0x3C4 0x4C4 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_00_FLEXPWM1_PWM3_A 0x1D4 0x3C4 0x454 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_00_SAI1_TX_DATA03 0x1D4 0x3C4 0x598 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_00_LPUART4_TXD 0x1D4 0x3C4 0x544 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_00_GPIO3_IO00 0x1D4 0x3C4 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_SD_B1_01_USDHC2_DATA2 0x1D8 0x3C8 0x5F0 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_01_FLEXSPI_B_DATA2 0x1D8 0x3C8 0x4C0 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_01_FLEXPWM1_PWM3_B 0x1D8 0x3C8 0x464 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_01_SAI1_TX_DATA02 0x1D8 0x3C8 0x59C 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_01_LPUART4_RXD 0x1D8 0x3C8 0x540 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_01_GPIO3_IO01 0x1D8 0x3C8 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_SD_B1_02_USDHC2_DATA1 0x1DC 0x3CC 0x5EC 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_02_FLEXSPI_B_DATA1 0x1DC 0x3CC 0x4BC 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_02_FLEXPWM2_PWM3_A 0x1DC 0x3CC 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_02_SAI1_TX_DATA01 0x1DC 0x3CC 0x5A0 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_02_FLEXCAN1_TX 0x1DC 0x3CC 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_02_GPIO3_IO02 0x1DC 0x3CC 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_02_CCM_WAIT 0x1DC 0x3CC 0x000 0x6 0x0
+
+#define MXRT1050_IOMUXC_GPIO_SD_B1_03_USDHC2_DATA0 0x1E0 0x3D0 0x5E8 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_03_FLEXSPI_B_DATA0 0x1E0 0x3D0 0x4B8 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_03_FLEXPWM2_PWM3_B 0x1E0 0x3D0 0x484 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_03_SAI1_MCLK 0x1E0 0x3D0 0x58C 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_03_FLEXCAN1_RX 0x1E0 0x3D0 0x44C 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_03_GPIO3_IO03 0x1E0 0x3D0 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_03_CCM_PMIC_READY 0x1E0 0x3D0 0x3FC 0x6 0x0
+
+#define MXRT1050_IOMUXC_GPIO_SD_B1_04_USDHC2_CLK 0x1E4 0x3D4 0x5DC 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_04_FLEXSPI_B_SCLK 0x1E4 0x3D4 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_04_LPI2C1_SCL 0x1E4 0x3D4 0x4CC 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_04_SAI1_RX_SYNC 0x1E4 0x3D4 0x5A4 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_04_FLEXCAN1_A_SS1_B 0x1E4 0x3D4 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_04_GPIO3_IO04 0x1E4 0x3D4 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_04_CCM_STOP 0x1E4 0x3D4 0x000 0x6 0x0
+
+#define MXRT1050_IOMUXC_GPIO_SD_B1_05_USDHC2_CMD 0x1E8 0x3D8 0x5E4 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_05_FLEXSPI_A_DQS 0x1E8 0x3D8 0x4A4 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_05_LPI2C1_SDA 0x1E8 0x3D8 0x4D0 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_05_SAI1_RX_BCLK 0x1E8 0x3D8 0x590 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_05_FLEXCAN1_B_SS0_B 0x1E8 0x3D8 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_05_GPIO3_IO05 0x1E8 0x3D8 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_SD_B1_06_USDHC2_RESET_B 0x1EC 0x3DC 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_06_FLEXSPI_A_SS0_B 0x1EC 0x3DC 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_06_LPUART7_CTS_B 0x1EC 0x3DC 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_06_SAI1_RX_DATA00 0x1EC 0x3DC 0x594 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_06_LPSPI2_PCS0 0x1EC 0x3DC 0x4FC 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_06_GPIO3_IO06 0x1EC 0x3DC 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_SD_B1_07_SEMC_CSX1 0x1F0 0x3E0 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_07_FLEXSPI_A_SCLK 0x1F0 0x3E0 0x4C8 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_07_LPUART7_RTS_B 0x1F0 0x3E0 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_07_SAI1_TX_DATA00 0x1F0 0x3E0 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_07_LPSPI2_SCK 0x1F0 0x3E0 0x500 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_07_GPIO3_IO07 0x1F0 0x3E0 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_07_CCM_REF_EN_B 0x1F0 0x3E0 0x000 0x6 0x0
+
+#define MXRT1050_IOMUXC_GPIO_SD_B1_08_USDHC2_DATA4 0x1F4 0x3E4 0x5F8 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_08_FLEXSPI_A_DATA0 0x1F4 0x3E4 0x4A8 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_08_LPUART7_TXD 0x1F4 0x3E4 0x55C 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_08_SAI1_TX_BLCK 0x1F4 0x3E4 0x5A8 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_08_LPSPI2_SDO 0x1F4 0x3E4 0x508 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_08_GPIO3_IO08 0x1F4 0x3E4 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_08_SEMC_CSX2 0x1F4 0x3E4 0x000 0x6 0x0
+
+#define MXRT1050_IOMUXC_GPIO_SD_B1_09_USDHC2_DATA5 0x1F8 0x3E8 0x5FC 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_09_FLEXSPI_A_DATA1 0x1F8 0x3E8 0x4AC 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_09_LPUART7_RXD 0x1F8 0x3E8 0x558 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_09_SAI1_TX_SYNC 0x1F8 0x3E8 0x5AC 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_09_LPSPI2_SDI 0x1F8 0x3E8 0x504 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_09_GPIO3_IO09 0x1F8 0x3E8 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_SD_B1_10_USDHC2_DATA6 0x1FC 0x3EC 0x600 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_10_FLEXSPI_A_DATA2 0x1FC 0x3EC 0x4B0 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_10_LPUART2_RXD 0x1FC 0x3EC 0x52C 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_10_LPI2C2_SDA 0x1FC 0x3EC 0x4D8 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_10_LPSPI2_PCS2 0x1FC 0x3EC 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_10_GPIO3_IO10 0x1FC 0x3EC 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_SD_B1_11_USDHC2_DATA7 0x200 0x3F0 0x604 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_11_FLEXSPI_A_DATA3 0x200 0x3F0 0x4B4 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_11_LPUART2_TXD 0x200 0x3F0 0x530 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_11_LPI2C2_SCL 0x200 0x3F0 0x4D4 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_11_LPSPI2_PCS3 0x200 0x3F0 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_11_GPIO3_IO11 0x200 0x3F0 0x000 0x5 0x0
+
+#endif /* _DT_BINDINGS_PINCTRL_IMXRT1050_PINFUNC_H */
diff --git a/arch/arm/boot/dts/intel-ixp42x-gateway-7001.dts b/arch/arm/boot/dts/intel-ixp42x-gateway-7001.dts
index a1c03c965f17..b7cbc90e1c18 100644
--- a/arch/arm/boot/dts/intel-ixp42x-gateway-7001.dts
+++ b/arch/arm/boot/dts/intel-ixp42x-gateway-7001.dts
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: ISC
/*
- * Device Tree file for Gateway 7001 AP
+ * Device Tree file for Gateway 7001 AP based on IXP422
* Derived from boardfiles written by Imre Kaloz
*/
@@ -29,7 +29,6 @@
aliases {
/* second UART is the primary console */
serial0 = &uart1;
- serial1 = &uart0;
};
soc {
diff --git a/arch/arm/boot/dts/intel-ixp42x-netgear-wg302v2.dts b/arch/arm/boot/dts/intel-ixp42x-netgear-wg302v1.dts
index a57009436ed8..df2ca6d95ee5 100644
--- a/arch/arm/boot/dts/intel-ixp42x-netgear-wg302v2.dts
+++ b/arch/arm/boot/dts/intel-ixp42x-netgear-wg302v1.dts
@@ -10,26 +10,26 @@
#include <dt-bindings/input/input.h>
/ {
- model = "Netgear WG302 v2";
- compatible = "netgear,wg302v2", "intel,ixp42x";
+ model = "Netgear WG302 v1";
+ compatible = "netgear,wg302v1", "intel,ixp42x";
#address-cells = <1>;
#size-cells = <1>;
memory@0 {
- /* 16 MB SDRAM according to OpenWrt database */
+ /* 32 MB SDRAM according to boot arguments */
device_type = "memory";
- reg = <0x00000000 0x01000000>;
+ reg = <0x00000000 0x02000000>;
};
chosen {
- bootargs = "console=ttyS0,115200n8 root=/dev/sda1 rw rootwait";
- stdout-path = "uart1:115200n8";
+ /* The RedBoot comes up in 9600 baud so let's keep this */
+ bootargs = "console=ttyS0,9600n8";
+ stdout-path = "uart1:9600n8";
};
aliases {
/* These are switched around */
serial0 = &uart1;
- serial1 = &uart0;
};
soc {
@@ -38,18 +38,17 @@
compatible = "intel,ixp4xx-flash", "cfi-flash";
bank-width = <2>;
/*
- * 32 MB of Flash in 128 0x20000 sized blocks
- * mapped in at CS0 and CS1
+ * 8 MB of Flash in 64 0x20000 sized blocks
+ * mapped in at CS0.
*/
- reg = <0 0x00000000 0x2000000>;
+ reg = <0 0x00000000 0x800000>;
/* Configure expansion bus to allow writes */
intel,ixp4xx-eb-write-enable = <1>;
partitions {
compatible = "redboot-fis";
- /* CHECKME: guess this is Redboot FIS */
- fis-index-block = <0xff>;
+ fis-index-block = <0x3f>;
};
};
};
@@ -82,14 +81,14 @@
queue-rx = <&qmgr 3>;
queue-txready = <&qmgr 20>;
phy-mode = "rgmii";
- phy-handle = <&phy8>;
+ phy-handle = <&phy30>;
mdio {
#address-cells = <1>;
#size-cells = <0>;
- phy8: ethernet-phy@8 {
- reg = <8>;
+ phy30: ethernet-phy@30 {
+ reg = <30>;
};
};
};
diff --git a/arch/arm/boot/dts/intel-ixp42x.dtsi b/arch/arm/boot/dts/intel-ixp42x.dtsi
index d0e0f8afb7c9..84cee8ec3ab8 100644
--- a/arch/arm/boot/dts/intel-ixp42x.dtsi
+++ b/arch/arm/boot/dts/intel-ixp42x.dtsi
@@ -9,7 +9,7 @@
soc {
bus@c4000000 {
compatible = "intel,ixp42x-expansion-bus-controller", "syscon";
- reg = <0xc4000000 0x28>;
+ reg = <0xc4000000 0x30>;
};
pci@c0000000 {
diff --git a/arch/arm/boot/dts/iwg20d-q7-common.dtsi b/arch/arm/boot/dts/iwg20d-q7-common.dtsi
index 849034a49a3f..03caea6fc6ff 100644
--- a/arch/arm/boot/dts/iwg20d-q7-common.dtsi
+++ b/arch/arm/boot/dts/iwg20d-q7-common.dtsi
@@ -181,7 +181,7 @@
};
&gpio2 {
- touch-interrupt {
+ touch-interrupt-hog {
gpio-hog;
gpios = <12 GPIO_ACTIVE_LOW>;
input;
diff --git a/arch/arm/boot/dts/kirkwood-c200-v1.dts b/arch/arm/boot/dts/kirkwood-c200-v1.dts
new file mode 100644
index 000000000000..f59ff7578dfc
--- /dev/null
+++ b/arch/arm/boot/dts/kirkwood-c200-v1.dts
@@ -0,0 +1,310 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Ctera C200 V1 Board Description
+ * Copyright 2021-2022 Pawel Dembicki <paweldembicki@gmail.com>
+ */
+
+/dts-v1/;
+
+#include "kirkwood.dtsi"
+#include "kirkwood-6281.dtsi"
+#include <dt-bindings/leds/common.h>
+
+/ {
+ model = "Ctera C200 V1";
+ compatible = "ctera,c200-v1", "marvell,kirkwood-88f6281", "marvell,kirkwood";
+
+ chosen {
+ bootargs = "console=ttyS0,115200";
+ stdout-path = &uart0;
+ };
+
+ memory@0 {
+ device_type = "memory";
+ reg = <0x00000000 0x20000000>;
+ };
+
+ keys {
+ compatible = "gpio-keys";
+ pinctrl-0 = <&pmx_buttons>;
+ pinctrl-names = "default";
+
+ power {
+ label = "Power Button";
+ linux,code = <KEY_POWER>;
+ gpios = <&gpio1 16 GPIO_ACTIVE_HIGH>;
+ };
+
+ reset {
+ label = "Reset Button";
+ linux,code = <KEY_RESTART>;
+ gpios = <&gpio1 17 GPIO_ACTIVE_LOW>;
+ };
+
+ usb1 {
+ label = "USB1 Button";
+ linux,code = <BTN_0>;
+ gpios = <&gpio0 28 GPIO_ACTIVE_LOW>;
+ };
+
+ usb2 {
+ label = "USB2 Button";
+ linux,code = <BTN_1>;
+ gpios = <&gpio0 29 GPIO_ACTIVE_LOW>;
+ };
+ };
+
+ gpio-poweroff {
+ compatible = "gpio-poweroff";
+ pinctrl-0 = <&pmx_poweroff>;
+ pinctrl-names = "default";
+ gpios = <&gpio1 2 GPIO_ACTIVE_HIGH>;
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ pinctrl-0 = <&pmx_leds>;
+ pinctrl-names = "default";
+
+ led-0 {
+ function = LED_FUNCTION_DISK;
+ function-enumerator = <2>;
+ color = <LED_COLOR_ID_RED>;
+ gpios = <&gpio0 14 GPIO_ACTIVE_LOW>;
+ };
+
+ led-1 {
+ function = LED_FUNCTION_DISK;
+ function-enumerator = <1>;
+ color = <LED_COLOR_ID_GREEN>;
+ gpios = <&gpio0 15 GPIO_ACTIVE_LOW>;
+ };
+
+ led-2 {
+ function = LED_FUNCTION_DISK;
+ function-enumerator = <2>;
+ color = <LED_COLOR_ID_GREEN>;
+ gpios = <&gpio0 16 GPIO_ACTIVE_LOW>;
+ };
+
+ led-3 {
+ function = LED_FUNCTION_DISK;
+ function-enumerator = <1>;
+ color = <LED_COLOR_ID_RED>;
+ gpios = <&gpio0 17 GPIO_ACTIVE_LOW>;
+ };
+
+ led-4 {
+ function = LED_FUNCTION_STATUS;
+ color = <LED_COLOR_ID_RED>;
+ gpios = <&gpio1 6 GPIO_ACTIVE_LOW>;
+ };
+
+ led-5 {
+ function = LED_FUNCTION_STATUS;
+ color = <LED_COLOR_ID_GREEN>;
+ gpios = <&gpio1 7 GPIO_ACTIVE_LOW>;
+ };
+
+ led-6 {
+ function = LED_FUNCTION_INDICATOR;
+ color = <LED_COLOR_ID_BLUE>;
+ gpios = <&gpio1 8 GPIO_ACTIVE_LOW>;
+ };
+
+ led-7 {
+ function = LED_FUNCTION_DISK_ERR;
+ color = <LED_COLOR_ID_RED>;
+ gpios = <&gpio1 10 GPIO_ACTIVE_LOW>;
+ };
+
+ led-8 {
+ function = LED_FUNCTION_DISK_ERR;
+ color = <LED_COLOR_ID_GREEN>;
+ gpios = <&gpio1 11 GPIO_ACTIVE_LOW>;
+ };
+
+ led-9 {
+ function = LED_FUNCTION_USB;
+ function-enumerator = <1>;
+ color = <LED_COLOR_ID_RED>;
+ gpios = <&gpio1 12 GPIO_ACTIVE_LOW>;
+ };
+
+ led-10 {
+ function = LED_FUNCTION_USB;
+ function-enumerator = <1>;
+ color = <LED_COLOR_ID_GREEN>;
+ gpios = <&gpio1 13 GPIO_ACTIVE_LOW>;
+ linux,default-trigger = "usbport";
+ trigger-sources = <&hub_port2>;
+ };
+
+ led-11 {
+ function = LED_FUNCTION_USB;
+ function-enumerator = <2>;
+ color = <LED_COLOR_ID_RED>;
+ gpios = <&gpio1 14 GPIO_ACTIVE_LOW>;
+ };
+
+ led-12 {
+ function = LED_FUNCTION_USB;
+ function-enumerator = <2>;
+ color = <LED_COLOR_ID_GREEN>;
+ gpios = <&gpio1 15 GPIO_ACTIVE_LOW>;
+ linux,default-trigger = "usbport";
+ trigger-sources = <&hub_port1>;
+ };
+ };
+};
+
+&eth0 {
+ status = "okay";
+};
+
+&eth0port {
+ phy-handle = <&ethphy9>;
+};
+
+&i2c0 {
+ status = "okay";
+
+ rtc@30 {
+ compatible = "s35390a";
+ reg = <0x30>;
+ };
+
+ lm63@4c {
+ compatible = "national,lm63";
+ reg = <0x4c>;
+ };
+};
+
+&mdio {
+ status = "okay";
+
+ ethphy9: ethernet-phy@9 {
+ reg = <9>;
+ };
+};
+
+&nand {
+ status = "okay";
+ chip-delay = <40>;
+
+ partition@0 {
+ label = "uboot";
+ reg = <0x0000000 0x200000>;
+ };
+
+ partition@200000 {
+ label = "certificate";
+ reg = <0x0200000 0x100000>;
+ };
+
+ partition@300000 {
+ label = "preset_cfg";
+ reg = <0x0300000 0x100000>;
+ };
+
+ partition@400000 {
+ label = "dev_params";
+ reg = <0x0400000 0x100000>;
+ };
+
+ partition@500000 {
+ label = "active_bank";
+ reg = <0x0500000 0x0100000>;
+ };
+
+ partition@600000 {
+ label = "magic";
+ reg = <0x0600000 0x0100000>;
+ };
+
+ partition@700000 {
+ label = "bank1";
+ reg = <0x0700000 0x2800000>;
+ };
+
+ partition@2f00000 {
+ label = "bank2";
+ reg = <0x2f00000 0x2800000>;
+ };
+
+ /* 0x5700000-0x5a00000 undefined in vendor firmware */
+
+ partition@5a00000 {
+ label = "reserved";
+ reg = <0x5a00000 0x2000000>;
+ };
+
+ partition@7a00000 {
+ label = "rootfs";
+ reg = <0x7a00000 0x8600000>;
+ };
+};
+
+&pinctrl {
+ /* Buzzer gpios are connected to two pins of buzzer.
+ * This buzzer require a modulated signal from gpio.
+ * Leave it as is due lack of proper driver.
+ */
+ pmx_buzzer: pmx-buzzer {
+ marvell,pins = "mpp12", "mpp13";
+ marvell,function = "gpio";
+ };
+
+ pmx_leds: pmx-leds {
+ marvell,pins = "mpp14", "mpp15", "mpp16", "mpp17", "mpp38",
+ "mpp39", "mpp40", "mpp42", "mpp43", "mpp44",
+ "mpp45", "mpp46", "mpp47";
+ marvell,function = "gpio";
+ };
+
+ pmx_buttons: pmx-buttons {
+ marvell,pins = "mpp28", "mpp29", "mpp48", "mpp49";
+ marvell,function = "gpio";
+ };
+
+ pmx_poweroff: pmx-poweroff {
+ marvell,pins = "mpp34";
+ marvell,function = "gpio";
+ };
+};
+
+&rtc {
+ status = "disabled";
+};
+
+&sata {
+ status = "okay";
+ nr-ports = <2>;
+};
+
+&uart0 {
+ status = "okay";
+};
+
+&usb0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "okay";
+
+ port@1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <1>;
+ #trigger-source-cells = <0>;
+
+ hub_port1: port@1 {
+ reg = <1>;
+ #trigger-source-cells = <0>;
+ };
+
+ hub_port2: port@2 {
+ reg = <2>;
+ #trigger-source-cells = <0>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/lan966x-pcb8291.dts b/arch/arm/boot/dts/lan966x-pcb8291.dts
new file mode 100644
index 000000000000..3281af90ac6d
--- /dev/null
+++ b/arch/arm/boot/dts/lan966x-pcb8291.dts
@@ -0,0 +1,64 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * lan966x_pcb8291.dts - Device Tree file for PCB8291
+ */
+/dts-v1/;
+#include "lan966x.dtsi"
+
+/ {
+ model = "Microchip EVB - LAN9662";
+ compatible = "microchip,lan9662-pcb8291", "microchip,lan9662", "microchip,lan966";
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+
+ aliases {
+ serial0 = &usart3;
+ };
+};
+
+&gpio {
+ fc_shrd7_pins: fc_shrd7-pins {
+ pins = "GPIO_49";
+ function = "fc_shrd7";
+ };
+
+ fc_shrd8_pins: fc_shrd8-pins {
+ pins = "GPIO_54";
+ function = "fc_shrd8";
+ };
+
+ fc3_b_pins: fcb3-spi-pins {
+ /* SCK, RXD, TXD */
+ pins = "GPIO_51", "GPIO_52", "GPIO_53";
+ function = "fc3_b";
+ };
+
+ can0_b_pins: can0_b_pins {
+ /* RX, TX */
+ pins = "GPIO_35", "GPIO_36";
+ function = "can0_b";
+ };
+};
+
+&can0 {
+ pinctrl-0 = <&can0_b_pins>;
+ pinctrl-names = "default";
+ status = "okay";
+};
+
+&flx3 {
+ atmel,flexcom-mode = <ATMEL_FLEXCOM_MODE_USART>;
+ status = "okay";
+
+ usart3: serial@200 {
+ pinctrl-0 = <&fc3_b_pins>, <&fc_shrd7_pins>, <&fc_shrd8_pins>;
+ pinctrl-names = "default";
+ status = "okay";
+ };
+};
+
+&watchdog {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/lan966x.dtsi b/arch/arm/boot/dts/lan966x.dtsi
new file mode 100644
index 000000000000..7d2869648050
--- /dev/null
+++ b/arch/arm/boot/dts/lan966x.dtsi
@@ -0,0 +1,237 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * lan966x.dtsi - Device Tree Include file for Microchip LAN966 family SoC
+ *
+ * Copyright (C) 2021 Microchip Technology, Inc. and its subsidiaries
+ *
+ * Author: Kavyasree Kotagiri <kavyasree.kotagiri@microchip.com>
+ *
+ */
+
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/mfd/atmel-flexcom.h>
+#include <dt-bindings/dma/at91.h>
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/clock/microchip,lan966x.h>
+
+/ {
+ model = "Microchip LAN966 family SoC";
+ compatible = "microchip,lan966";
+ interrupt-parent = <&gic>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu@0 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a7";
+ clock-frequency = <600000000>;
+ reg = <0x0>;
+ };
+ };
+
+ clocks {
+ sys_clk: sys_clk {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <162500000>;
+ };
+
+ cpu_clk: cpu_clk {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <600000000>;
+ };
+
+ ddr_clk: ddr_clk {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <300000000>;
+ };
+
+ nic_clk: nic_clk {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <200000000>;
+ };
+ };
+
+ clks: clock-controller@e00c00a8 {
+ compatible = "microchip,lan966x-gck";
+ #clock-cells = <1>;
+ clocks = <&cpu_clk>, <&ddr_clk>, <&sys_clk>;
+ clock-names = "cpu", "ddr", "sys";
+ reg = <0xe00c00a8 0x38>;
+ };
+
+ timer {
+ compatible = "arm,armv7-timer";
+ interrupt-parent = <&gic>;
+ interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(1) | IRQ_TYPE_LEVEL_LOW)>,
+ <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(1) | IRQ_TYPE_LEVEL_LOW)>,
+ <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(1) | IRQ_TYPE_LEVEL_LOW)>,
+ <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(1) | IRQ_TYPE_LEVEL_LOW)>;
+ clock-frequency = <37500000>;
+ };
+
+ soc {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ flx0: flexcom@e0040000 {
+ compatible = "atmel,sama5d2-flexcom";
+ reg = <0xe0040000 0x100>;
+ clocks = <&clks GCK_ID_FLEXCOM0>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0x0 0xe0040000 0x800>;
+ status = "disabled";
+ };
+
+ flx1: flexcom@e0044000 {
+ compatible = "atmel,sama5d2-flexcom";
+ reg = <0xe0044000 0x100>;
+ clocks = <&clks GCK_ID_FLEXCOM1>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0x0 0xe0044000 0x800>;
+ status = "disabled";
+ };
+
+ trng: rng@e0048000 {
+ compatible = "atmel,at91sam9g45-trng";
+ reg = <0xe0048000 0x100>;
+ clocks = <&nic_clk>;
+ };
+
+ aes: crypto@e004c000 {
+ compatible = "atmel,at91sam9g46-aes";
+ reg = <0xe004c000 0x100>;
+ interrupts = <GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH>;
+ dmas = <&dma0 AT91_XDMAC_DT_PERID(13)>,
+ <&dma0 AT91_XDMAC_DT_PERID(12)>;
+ dma-names = "rx", "tx";
+ clocks = <&nic_clk>;
+ clock-names = "aes_clk";
+ };
+
+ flx2: flexcom@e0060000 {
+ compatible = "atmel,sama5d2-flexcom";
+ reg = <0xe0060000 0x100>;
+ clocks = <&clks GCK_ID_FLEXCOM2>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0x0 0xe0060000 0x800>;
+ status = "disabled";
+ };
+
+ flx3: flexcom@e0064000 {
+ compatible = "atmel,sama5d2-flexcom";
+ reg = <0xe0064000 0x100>;
+ clocks = <&clks GCK_ID_FLEXCOM3>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0x0 0xe0064000 0x800>;
+ status = "disabled";
+
+ usart3: serial@200 {
+ compatible = "atmel,at91sam9260-usart";
+ reg = <0x200 0x200>;
+ interrupts = <GIC_SPI 51 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&nic_clk>;
+ clock-names = "usart";
+ atmel,fifo-size = <32>;
+ status = "disabled";
+ };
+ };
+
+ dma0: dma-controller@e0068000 {
+ compatible = "microchip,sama7g5-dma";
+ reg = <0xe0068000 0x1000>;
+ interrupts = <GIC_SPI 47 IRQ_TYPE_LEVEL_HIGH>;
+ #dma-cells = <1>;
+ clocks = <&nic_clk>;
+ clock-names = "dma_clk";
+ };
+
+ sha: crypto@e006c000 {
+ compatible = "atmel,at91sam9g46-sha";
+ reg = <0xe006c000 0xec>;
+ interrupts = <GIC_SPI 57 IRQ_TYPE_LEVEL_HIGH>;
+ dmas = <&dma0 AT91_XDMAC_DT_PERID(14)>;
+ dma-names = "tx";
+ clocks = <&nic_clk>;
+ clock-names = "sha_clk";
+ };
+
+ flx4: flexcom@e0070000 {
+ compatible = "atmel,sama5d2-flexcom";
+ reg = <0xe0070000 0x100>;
+ clocks = <&clks GCK_ID_FLEXCOM4>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0x0 0xe0070000 0x800>;
+ status = "disabled";
+ };
+
+ timer0: timer@e008c000 {
+ compatible = "snps,dw-apb-timer";
+ reg = <0xe008c000 0x400>;
+ clocks = <&nic_clk>;
+ clock-names = "timer";
+ interrupts = <GIC_SPI 39 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ watchdog: watchdog@e0090000 {
+ compatible = "snps,dw-wdt";
+ reg = <0xe0090000 0x1000>;
+ interrupts = <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&nic_clk>;
+ status = "disabled";
+ };
+
+ can0: can@e081c000 {
+ compatible = "bosch,m_can";
+ reg = <0xe081c000 0xfc>, <0x00100000 0x4000>;
+ reg-names = "m_can", "message_ram";
+ interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "int0", "int1";
+ clocks = <&clks GCK_ID_MCAN0>, <&clks GCK_ID_MCAN0>;
+ clock-names = "hclk", "cclk";
+ assigned-clocks = <&clks GCK_ID_MCAN0>;
+ assigned-clock-rates = <40000000>;
+ bosch,mram-cfg = <0x0 0 0 64 0 0 32 32>;
+ status = "disabled";
+ };
+
+ gpio: pinctrl@e2004064 {
+ compatible = "microchip,lan966x-pinctrl";
+ reg = <0xe2004064 0xb4>,
+ <0xe2010024 0x138>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ gpio-ranges = <&gpio 0 0 78>;
+ interrupt-controller;
+ interrupts = <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>;
+ #interrupt-cells = <2>;
+ };
+
+ gic: interrupt-controller@e8c11000 {
+ compatible = "arm,gic-400", "arm,cortex-a7-gic";
+ #interrupt-cells = <3>;
+ interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-controller;
+ reg = <0xe8c11000 0x1000>,
+ <0xe8c12000 0x2000>,
+ <0xe8c14000 0x2000>,
+ <0xe8c16000 0x2000>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/logicpd-torpedo-35xx-devkit.dts b/arch/arm/boot/dts/logicpd-torpedo-35xx-devkit.dts
index 57bae2aa910e..cb08aa62d967 100644
--- a/arch/arm/boot/dts/logicpd-torpedo-35xx-devkit.dts
+++ b/arch/arm/boot/dts/logicpd-torpedo-35xx-devkit.dts
@@ -11,3 +11,11 @@
model = "LogicPD Zoom OMAP35xx Torpedo Development Kit";
compatible = "logicpd,dm3730-torpedo-devkit", "ti,omap3430", "ti,omap3";
};
+
+&omap3_pmx_core {
+ isp1763_pins: pinmux_isp1763_pins {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x2154, PIN_INPUT_PULLUP | MUX_MODE4) /* sdmmc1_dat6.gpio_128 */
+ >;
+ };
+};
diff --git a/arch/arm/boot/dts/logicpd-torpedo-37xx-devkit.dts b/arch/arm/boot/dts/logicpd-torpedo-37xx-devkit.dts
index 5532db04046c..07ea822fe405 100644
--- a/arch/arm/boot/dts/logicpd-torpedo-37xx-devkit.dts
+++ b/arch/arm/boot/dts/logicpd-torpedo-37xx-devkit.dts
@@ -85,3 +85,12 @@
>;
};
};
+
+/* The gpio muxing between omap3530 and dm3730 is different for GPIO_128 */
+&omap3_pmx_wkup {
+ isp1763_pins: pinmux_isp1763_pins {
+ pinctrl-single,pins = <
+ OMAP3_WKUP_IOPAD(0x2a58, PIN_INPUT_PULLUP | MUX_MODE4) /* reserved.gpio_128 */
+ >;
+ };
+};
diff --git a/arch/arm/boot/dts/logicpd-torpedo-baseboard.dtsi b/arch/arm/boot/dts/logicpd-torpedo-baseboard.dtsi
index 533a47bc4a53..b4664ab00256 100644
--- a/arch/arm/boot/dts/logicpd-torpedo-baseboard.dtsi
+++ b/arch/arm/boot/dts/logicpd-torpedo-baseboard.dtsi
@@ -93,7 +93,8 @@
&gpmc {
ranges = <0 0 0x30000000 0x1000000 /* CS0: 16MB for NAND */
- 1 0 0x2c000000 0x1000000>; /* CS1: 16MB for LAN9221 */
+ 1 0 0x2c000000 0x1000000 /* CS1: 16MB for LAN9221 */
+ 6 0 0x28000000 0x1000000>; /* CS6: 16MB for ISP1763 */
ethernet@gpmc {
pinctrl-names = "default";
@@ -102,6 +103,44 @@
interrupts = <1 IRQ_TYPE_LEVEL_LOW>; /* gpio129 */
reg = <1 0 0xff>;
};
+
+ usb@6,0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&isp1763_pins>;
+ compatible = "nxp,usb-isp1763";
+ reg = <0x6 0x0 0xff>;
+ interrupt-parent = <&gpio5>;
+ interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
+ interrupt-names = "host";
+ bus-width = <16>;
+ dr_mode = "host";
+ gpmc,mux-add-data = <0>;
+ gpmc,device-width = <2>;
+ gpmc,wait-pin = <0>;
+ gpmc,burst-length = <4>;
+ gpmc,cycle2cycle-samecsen = <1>;
+ gpmc,cycle2cycle-diffcsen = <1>;
+ gpmc,cs-on-ns = <0>;
+ gpmc,cs-rd-off-ns = <45>;
+ gpmc,cs-wr-off-ns = <45>;
+ gpmc,adv-on-ns = <0>;
+ gpmc,adv-rd-off-ns = <0>;
+ gpmc,adv-wr-off-ns = <0>;
+ gpmc,oe-on-ns = <0>;
+ gpmc,oe-off-ns = <45>;
+ gpmc,we-on-ns = <0>;
+ gpmc,we-off-ns = <25>;
+ gpmc,rd-cycle-ns = <60>;
+ gpmc,wr-cycle-ns = <45>;
+ gpmc,access-ns = <35>;
+ gpmc,page-burst-access-ns = <0>;
+ gpmc,bus-turnaround-ns = <0>;
+ gpmc,cycle2cycle-delay-ns = <60>;
+ gpmc,wait-monitoring-ns = <0>;
+ gpmc,clk-activation-ns = <0>;
+ gpmc,wr-data-mux-bus-ns = <5>;
+ gpmc,wr-access-ns = <20>;
+ };
};
&hdqw1w {
diff --git a/arch/arm/boot/dts/meson.dtsi b/arch/arm/boot/dts/meson.dtsi
index 3be7cba603d5..26eaba3fa96f 100644
--- a/arch/arm/boot/dts/meson.dtsi
+++ b/arch/arm/boot/dts/meson.dtsi
@@ -59,7 +59,7 @@
};
uart_A: serial@84c0 {
- compatible = "amlogic,meson6-uart", "amlogic,meson-uart";
+ compatible = "amlogic,meson6-uart";
reg = <0x84c0 0x18>;
interrupts = <GIC_SPI 26 IRQ_TYPE_EDGE_RISING>;
fifo-size = <128>;
@@ -67,7 +67,7 @@
};
uart_B: serial@84dc {
- compatible = "amlogic,meson6-uart", "amlogic,meson-uart";
+ compatible = "amlogic,meson6-uart";
reg = <0x84dc 0x18>;
interrupts = <GIC_SPI 75 IRQ_TYPE_EDGE_RISING>;
status = "disabled";
@@ -105,7 +105,7 @@
};
uart_C: serial@8700 {
- compatible = "amlogic,meson6-uart", "amlogic,meson-uart";
+ compatible = "amlogic,meson6-uart";
reg = <0x8700 0x18>;
interrupts = <GIC_SPI 93 IRQ_TYPE_EDGE_RISING>;
status = "disabled";
@@ -228,7 +228,7 @@
};
uart_AO: serial@4c0 {
- compatible = "amlogic,meson6-uart", "amlogic,meson-ao-uart", "amlogic,meson-uart";
+ compatible = "amlogic,meson6-uart", "amlogic,meson-ao-uart";
reg = <0x4c0 0x18>;
interrupts = <GIC_SPI 90 IRQ_TYPE_EDGE_RISING>;
status = "disabled";
diff --git a/arch/arm/boot/dts/meson8.dtsi b/arch/arm/boot/dts/meson8.dtsi
index f80ddc98d3a2..9997a5d0333a 100644
--- a/arch/arm/boot/dts/meson8.dtsi
+++ b/arch/arm/boot/dts/meson8.dtsi
@@ -736,27 +736,27 @@
};
&uart_AO {
- compatible = "amlogic,meson8-uart", "amlogic,meson-uart";
- clocks = <&clkc CLKID_CLK81>, <&xtal>, <&clkc CLKID_CLK81>;
- clock-names = "baud", "xtal", "pclk";
+ compatible = "amlogic,meson8-uart", "amlogic,meson-ao-uart";
+ clocks = <&xtal>, <&clkc CLKID_CLK81>, <&clkc CLKID_CLK81>;
+ clock-names = "xtal", "pclk", "baud";
};
&uart_A {
- compatible = "amlogic,meson8-uart", "amlogic,meson-uart";
- clocks = <&clkc CLKID_CLK81>, <&xtal>, <&clkc CLKID_UART0>;
- clock-names = "baud", "xtal", "pclk";
+ compatible = "amlogic,meson8-uart";
+ clocks = <&xtal>, <&clkc CLKID_UART0>, <&clkc CLKID_CLK81>;
+ clock-names = "xtal", "pclk", "baud";
};
&uart_B {
- compatible = "amlogic,meson8-uart", "amlogic,meson-uart";
- clocks = <&clkc CLKID_CLK81>, <&xtal>, <&clkc CLKID_UART1>;
- clock-names = "baud", "xtal", "pclk";
+ compatible = "amlogic,meson8-uart";
+ clocks = <&xtal>, <&clkc CLKID_UART0>, <&clkc CLKID_CLK81>;
+ clock-names = "xtal", "pclk", "baud";
};
&uart_C {
- compatible = "amlogic,meson8-uart", "amlogic,meson-uart";
- clocks = <&clkc CLKID_CLK81>, <&xtal>, <&clkc CLKID_UART2>;
- clock-names = "baud", "xtal", "pclk";
+ compatible = "amlogic,meson8-uart";
+ clocks = <&xtal>, <&clkc CLKID_UART0>, <&clkc CLKID_CLK81>;
+ clock-names = "xtal", "pclk", "baud";
};
&usb0 {
diff --git a/arch/arm/boot/dts/meson8b.dtsi b/arch/arm/boot/dts/meson8b.dtsi
index b49b7cbaed4e..94f1c03decce 100644
--- a/arch/arm/boot/dts/meson8b.dtsi
+++ b/arch/arm/boot/dts/meson8b.dtsi
@@ -724,27 +724,27 @@
};
&uart_AO {
- compatible = "amlogic,meson8b-uart", "amlogic,meson-uart";
- clocks = <&clkc CLKID_CLK81>, <&xtal>, <&clkc CLKID_CLK81>;
- clock-names = "baud", "xtal", "pclk";
+ compatible = "amlogic,meson8b-uart", "amlogic,meson-ao-uart";
+ clocks = <&xtal>, <&clkc CLKID_CLK81>, <&clkc CLKID_CLK81>;
+ clock-names = "xtal", "pclk", "baud";
};
&uart_A {
- compatible = "amlogic,meson8b-uart", "amlogic,meson-uart";
- clocks = <&clkc CLKID_CLK81>, <&xtal>, <&clkc CLKID_UART0>;
- clock-names = "baud", "xtal", "pclk";
+ compatible = "amlogic,meson8b-uart";
+ clocks = <&xtal>, <&clkc CLKID_UART0>, <&clkc CLKID_CLK81>;
+ clock-names = "xtal", "pclk", "baud";
};
&uart_B {
- compatible = "amlogic,meson8b-uart", "amlogic,meson-uart";
- clocks = <&clkc CLKID_CLK81>, <&xtal>, <&clkc CLKID_UART1>;
- clock-names = "baud", "xtal", "pclk";
+ compatible = "amlogic,meson8b-uart";
+ clocks = <&xtal>, <&clkc CLKID_UART0>, <&clkc CLKID_CLK81>;
+ clock-names = "xtal", "pclk", "baud";
};
&uart_C {
- compatible = "amlogic,meson8b-uart", "amlogic,meson-uart";
- clocks = <&clkc CLKID_CLK81>, <&xtal>, <&clkc CLKID_UART2>;
- clock-names = "baud", "xtal", "pclk";
+ compatible = "amlogic,meson8b-uart";
+ clocks = <&xtal>, <&clkc CLKID_UART0>, <&clkc CLKID_CLK81>;
+ clock-names = "xtal", "pclk", "baud";
};
&usb0 {
diff --git a/arch/arm/boot/dts/mstar-infinity.dtsi b/arch/arm/boot/dts/mstar-infinity.dtsi
index 0bee517797f4..441a917b88ba 100644
--- a/arch/arm/boot/dts/mstar-infinity.dtsi
+++ b/arch/arm/boot/dts/mstar-infinity.dtsi
@@ -8,6 +8,40 @@
#include <dt-bindings/gpio/msc313-gpio.h>
+/ {
+ cpu0_opp_table: opp_table0 {
+ compatible = "operating-points-v2";
+ opp-shared;
+
+ opp-240000000 {
+ opp-hz = /bits/ 64 <240000000>;
+ opp-microvolt = <1000000>;
+ clock-latency-ns = <300000>;
+ };
+
+ opp-400000000 {
+ opp-hz = /bits/ 64 <400000000>;
+ opp-microvolt = <1000000>;
+ clock-latency-ns = <300000>;
+ };
+ opp-600000000 {
+ opp-hz = /bits/ 64 <600000000>;
+ opp-microvolt = <1000000>;
+ clock-latency-ns = <300000>;
+ };
+
+ opp-800000000 {
+ opp-hz = /bits/ 64 <800000000>;
+ opp-microvolt = <1000000>;
+ clock-latency-ns = <300000>;
+ };
+ };
+};
+
+&cpu0 {
+ operating-points-v2 = <&cpu0_opp_table>;
+};
+
&imi {
reg = <0xa0000000 0x16000>;
};
diff --git a/arch/arm/boot/dts/mstar-infinity2m-ssd201-som2d01.dtsi b/arch/arm/boot/dts/mstar-infinity2m-ssd201-som2d01.dtsi
new file mode 100644
index 000000000000..34df472fed71
--- /dev/null
+++ b/arch/arm/boot/dts/mstar-infinity2m-ssd201-som2d01.dtsi
@@ -0,0 +1,20 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+/*
+ * Copyright (c) 2021 thingy.jp.
+ * Author: Daniel Palmer <daniel@thingy.jp>
+ * Author: Romain Perier <romain.perier@gmail.com>
+ */
+
+/ {
+ reg_vcc_dram: regulator-vcc-dram {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc_dram";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-boot-on;
+ };
+};
+
+&pm_uart {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/mstar-infinity2m-ssd202d-100ask-dongshanpione.dts b/arch/arm/boot/dts/mstar-infinity2m-ssd202d-100ask-dongshanpione.dts
new file mode 100644
index 000000000000..f25a04c98ccb
--- /dev/null
+++ b/arch/arm/boot/dts/mstar-infinity2m-ssd202d-100ask-dongshanpione.dts
@@ -0,0 +1,25 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2021 thingy.jp.
+ * Author: Daniel Palmer <daniel@thingy.jp>
+ */
+
+/dts-v1/;
+#include "mstar-infinity2m-ssd202d.dtsi"
+
+/ {
+ model = "DongShanPi One";
+ compatible = "100ask,dongshanpione", "mstar,infinity2m";
+
+ aliases {
+ serial0 = &pm_uart;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+};
+
+&pm_uart {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/mstar-infinity2m-ssd202d-miyoo-mini.dts b/arch/arm/boot/dts/mstar-infinity2m-ssd202d-miyoo-mini.dts
new file mode 100644
index 000000000000..1bbbf47132dc
--- /dev/null
+++ b/arch/arm/boot/dts/mstar-infinity2m-ssd202d-miyoo-mini.dts
@@ -0,0 +1,25 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2021 thingy.jp.
+ * Author: Daniel Palmer <daniel@thingy.jp>
+ */
+
+/dts-v1/;
+#include "mstar-infinity2m-ssd202d.dtsi"
+
+/ {
+ model = "Miyoo Mini";
+ compatible = "miyoo,miyoo-mini", "mstar,infinity2m";
+
+ aliases {
+ serial0 = &pm_uart;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+};
+
+&pm_uart {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/mstar-infinity2m-ssd202d-wirelesstag-ido-sbc2d06-v1b-22w.dts b/arch/arm/boot/dts/mstar-infinity2m-ssd202d-wirelesstag-ido-sbc2d06-v1b-22w.dts
new file mode 100644
index 000000000000..b15c40762bc0
--- /dev/null
+++ b/arch/arm/boot/dts/mstar-infinity2m-ssd202d-wirelesstag-ido-sbc2d06-v1b-22w.dts
@@ -0,0 +1,23 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+/*
+ * Copyright (c) 2021 thingy.jp.
+ * Author: Daniel Palmer <daniel@thingy.jp>
+ * Author: Romain Perier <romain.perier@gmail.com>
+ */
+
+/dts-v1/;
+#include "mstar-infinity2m-ssd202d-wirelesstag-ido-som2d01.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+ model = "Wireless Tag IDO-SBC2D06-1VB-22W";
+ compatible = "wirelesstag,ido-sbc2d06-v1b-22w", "mstar,infinity2m";
+
+ leds {
+ compatible = "gpio-leds";
+ sys_led {
+ gpios = <&gpio SSD20XD_GPIO_GPIO85 GPIO_ACTIVE_LOW>;
+ linux,default-trigger = "heartbeat";
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/mstar-infinity2m-ssd202d-wirelesstag-ido-som2d01.dtsi b/arch/arm/boot/dts/mstar-infinity2m-ssd202d-wirelesstag-ido-som2d01.dtsi
new file mode 100644
index 000000000000..d877aff85033
--- /dev/null
+++ b/arch/arm/boot/dts/mstar-infinity2m-ssd202d-wirelesstag-ido-som2d01.dtsi
@@ -0,0 +1,28 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+/*
+ * Copyright (c) 2021 thingy.jp.
+ * Author: Daniel Palmer <daniel@thingy.jp>
+ * Author: Romain Perier <romain.perier@gmail.com>
+ */
+
+/dts-v1/;
+#include "mstar-infinity2m-ssd202d.dtsi"
+#include "mstar-infinity2m-ssd201-som2d01.dtsi"
+
+/ {
+ model = "Wireless Tag IDO-SOM2D01 (SSD202D)";
+ compatible = "wirelesstag,ido-som2d01", "mstar,infinity2m";
+
+ aliases {
+ serial0 = &pm_uart;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+};
+
+&reg_vcc_dram {
+ regulator-min-microvolt = <1500000>;
+ regulator-max-microvolt = <1500000>;
+};
diff --git a/arch/arm/boot/dts/mstar-infinity2m-ssd20xd.dtsi b/arch/arm/boot/dts/mstar-infinity2m-ssd20xd.dtsi
index 7a5e28b33f96..6f067da61ba3 100644
--- a/arch/arm/boot/dts/mstar-infinity2m-ssd20xd.dtsi
+++ b/arch/arm/boot/dts/mstar-infinity2m-ssd20xd.dtsi
@@ -6,6 +6,11 @@
#include "mstar-infinity2m.dtsi"
+&gpio {
+ compatible = "sstar,ssd20xd-gpio";
+ status = "okay";
+};
+
&smpctrl {
compatible = "sstar,ssd201-smpctrl", "mstar,smpctrl";
status = "okay";
diff --git a/arch/arm/boot/dts/mstar-infinity2m.dtsi b/arch/arm/boot/dts/mstar-infinity2m.dtsi
index 6d4d1d224e96..1b485efd7156 100644
--- a/arch/arm/boot/dts/mstar-infinity2m.dtsi
+++ b/arch/arm/boot/dts/mstar-infinity2m.dtsi
@@ -6,11 +6,28 @@
#include "mstar-infinity.dtsi"
+&cpu0_opp_table {
+ opp-1000000000 {
+ opp-hz = /bits/ 64 <1000000000>;
+ opp-microvolt = <1000000>;
+ clock-latency-ns = <300000>;
+ };
+
+ opp-1200000000 {
+ opp-hz = /bits/ 64 <1200000000>;
+ opp-microvolt = <1000000>;
+ clock-latency-ns = <300000>;
+ };
+};
+
&cpus {
cpu1: cpu@1 {
device_type = "cpu";
compatible = "arm,cortex-a7";
+ operating-points-v2 = <&cpu0_opp_table>;
reg = <0x1>;
+ clocks = <&cpupll>;
+ clock-names = "cpuclk";
};
};
diff --git a/arch/arm/boot/dts/mstar-infinity3.dtsi b/arch/arm/boot/dts/mstar-infinity3.dtsi
index 9857e2a9934d..a56cf29e5d82 100644
--- a/arch/arm/boot/dts/mstar-infinity3.dtsi
+++ b/arch/arm/boot/dts/mstar-infinity3.dtsi
@@ -6,6 +6,64 @@
#include "mstar-infinity.dtsi"
+&cpu0_opp_table {
+ opp-1008000000 {
+ opp-hz = /bits/ 64 <1008000000>;
+ opp-microvolt = <1000000>;
+ clock-latency-ns = <300000>;
+ };
+
+ // overclock frequencies below, shown to work fine up to 1.3 GHz
+ opp-108000000 {
+ opp-hz = /bits/ 64 <1080000000>;
+ opp-microvolt = <1000000>;
+ clock-latency-ns = <300000>;
+ turbo-mode;
+ };
+
+ opp-1188000000 {
+ opp-hz = /bits/ 64 <1188000000>;
+ opp-microvolt = <1000000>;
+ clock-latency-ns = <300000>;
+ turbo-mode;
+ };
+
+ opp-1296000000 {
+ opp-hz = /bits/ 64 <1296000000>;
+ opp-microvolt = <1000000>;
+ clock-latency-ns = <300000>;
+ turbo-mode;
+ };
+
+ opp-1350000000 {
+ opp-hz = /bits/ 64 <1350000000>;
+ opp-microvolt = <1000000>;
+ clock-latency-ns = <300000>;
+ turbo-mode;
+ };
+
+ opp-1404000000 {
+ opp-hz = /bits/ 64 <1404000000>;
+ opp-microvolt = <1000000>;
+ clock-latency-ns = <300000>;
+ turbo-mode;
+ };
+
+ opp-1458000000 {
+ opp-hz = /bits/ 64 <1458000000>;
+ opp-microvolt = <1000000>;
+ clock-latency-ns = <300000>;
+ turbo-mode;
+ };
+
+ opp-1512000000 {
+ opp-hz = /bits/ 64 <1512000000>;
+ opp-microvolt = <1000000>;
+ clock-latency-ns = <300000>;
+ turbo-mode;
+ };
+};
+
&imi {
reg = <0xa0000000 0x20000>;
};
diff --git a/arch/arm/boot/dts/mstar-v7.dtsi b/arch/arm/boot/dts/mstar-v7.dtsi
index 89ebfe4f29da..c26ba9b7b6dd 100644
--- a/arch/arm/boot/dts/mstar-v7.dtsi
+++ b/arch/arm/boot/dts/mstar-v7.dtsi
@@ -21,6 +21,8 @@
device_type = "cpu";
compatible = "arm,cortex-a7";
reg = <0x0>;
+ clocks = <&cpupll>;
+ clock-names = "cpuclk";
};
};
@@ -155,6 +157,13 @@
clocks = <&xtal>;
};
+ cpupll: cpupll@206400 {
+ compatible = "mstar,msc313-cpupll";
+ reg = <0x206400 0x200>;
+ #clock-cells = <0>;
+ clocks = <&mpll MSTAR_MSC313_MPLL_DIV2>;
+ };
+
gpio: gpio@207800 {
#gpio-cells = <2>;
reg = <0x207800 0x200>;
diff --git a/arch/arm/boot/dts/mt6582-prestigio-pmt5008-3g.dts b/arch/arm/boot/dts/mt6582-prestigio-pmt5008-3g.dts
new file mode 100644
index 000000000000..b057e037f940
--- /dev/null
+++ b/arch/arm/boot/dts/mt6582-prestigio-pmt5008-3g.dts
@@ -0,0 +1,43 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2021 Maxim Kutnij <gtk3@inbox.ru>
+ */
+
+/dts-v1/;
+#include "mt6582.dtsi"
+
+/ {
+ model = "Prestigio PMT5008 3G";
+ compatible = "prestigio,pmt5008-3g", "mediatek,mt6582";
+
+ aliases {
+ bootargs = "console=ttyS0,921600n8 earlyprintk";
+ serial0 = &uart0;
+ serial3 = &uart3;
+ };
+
+ chosen {
+ stdout-path = "serial0:921600n8";
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0x80000000 0x40000000>;
+ };
+};
+
+&uart0 {
+ status = "okay";
+};
+
+&uart1 {
+ status = "okay";
+};
+
+&uart2 {
+ status = "okay";
+};
+
+&uart3 {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/mt6582.dtsi b/arch/arm/boot/dts/mt6582.dtsi
new file mode 100644
index 000000000000..4263371784cd
--- /dev/null
+++ b/arch/arm/boot/dts/mt6582.dtsi
@@ -0,0 +1,128 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2021 Maxim Kutnij <gtk3@inbox.ru>
+ */
+
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "mediatek,mt6582";
+ interrupt-parent = <&sysirq>;
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu@0 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a7";
+ reg = <0x0>;
+ };
+ cpu@1 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a7";
+ reg = <0x1>;
+ };
+ cpu@2 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a7";
+ reg = <0x2>;
+ };
+ cpu@3 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a7";
+ reg = <0x3>;
+ };
+ };
+
+ system_clk: dummy13m {
+ compatible = "fixed-clock";
+ clock-frequency = <13000000>;
+ #clock-cells = <0>;
+ };
+
+ rtc_clk: dummy32k {
+ compatible = "fixed-clock";
+ clock-frequency = <32000>;
+ #clock-cells = <0>;
+ };
+
+ uart_clk: dummy26m {
+ compatible = "fixed-clock";
+ clock-frequency = <26000000>;
+ #clock-cells = <0>;
+ };
+
+ timer: timer@11008000 {
+ compatible = "mediatek,mt6577-timer";
+ reg = <0x10008000 0x80>;
+ interrupts = <GIC_SPI 112 IRQ_TYPE_LEVEL_LOW>;
+ clocks = <&system_clk>, <&rtc_clk>;
+ clock-names = "system-clk", "rtc-clk";
+ };
+
+ sysirq: interrupt-controller@10200100 {
+ compatible = "mediatek,mt6582-sysirq",
+ "mediatek,mt6577-sysirq";
+ interrupt-controller;
+ #interrupt-cells = <3>;
+ interrupt-parent = <&gic>;
+ reg = <0x10200100 0x1c>;
+ };
+
+ gic: interrupt-controller@10211000 {
+ compatible = "arm,cortex-a7-gic";
+ interrupt-controller;
+ #interrupt-cells = <3>;
+ interrupt-parent = <&gic>;
+ reg = <0x10211000 0x1000>,
+ <0x10212000 0x2000>,
+ <0x10214000 0x2000>,
+ <0x10216000 0x2000>;
+ };
+
+ uart0: serial@11002000 {
+ compatible = "mediatek,mt6582-uart",
+ "mediatek,mt6577-uart";
+ reg = <0x11002000 0x400>;
+ interrupts = <GIC_SPI 51 IRQ_TYPE_LEVEL_LOW>;
+ clocks = <&uart_clk>;
+ status = "disabled";
+ };
+
+ uart1: serial@11003000 {
+ compatible = "mediatek,mt6582-uart",
+ "mediatek,mt6577-uart";
+ reg = <0x11003000 0x400>;
+ interrupts = <GIC_SPI 52 IRQ_TYPE_LEVEL_LOW>;
+ clocks = <&uart_clk>;
+ status = "disabled";
+ };
+
+ uart2: serial@11004000 {
+ compatible = "mediatek,mt6582-uart",
+ "mediatek,mt6577-uart";
+ reg = <0x11004000 0x400>;
+ interrupts = <GIC_SPI 53 IRQ_TYPE_LEVEL_LOW>;
+ clocks = <&uart_clk>;
+ status = "disabled";
+ };
+
+ uart3: serial@11005000 {
+ compatible = "mediatek,mt6582-uart",
+ "mediatek,mt6577-uart";
+ reg = <0x11005000 0x400>;
+ interrupts = <GIC_SPI 54 IRQ_TYPE_LEVEL_LOW>;
+ clocks = <&uart_clk>;
+ status = "disabled";
+ };
+
+ watchdog: watchdog@10007000 {
+ compatible = "mediatek,mt6582-wdt",
+ "mediatek,mt6589-wdt";
+ reg = <0x10007000 0x100>;
+ };
+};
diff --git a/arch/arm/boot/dts/nuvoton-wpcm450-supermicro-x9sci-ln4f.dts b/arch/arm/boot/dts/nuvoton-wpcm450-supermicro-x9sci-ln4f.dts
index 83f27fbf4e93..3ee61251a16d 100644
--- a/arch/arm/boot/dts/nuvoton-wpcm450-supermicro-x9sci-ln4f.dts
+++ b/arch/arm/boot/dts/nuvoton-wpcm450-supermicro-x9sci-ln4f.dts
@@ -8,6 +8,9 @@
#include "nuvoton-wpcm450.dtsi"
+#include <dt-bindings/input/linux-event-codes.h>
+#include <dt-bindings/gpio/gpio.h>
+
/ {
model = "Supermicro X9SCi-LN4F BMC";
compatible = "supermicro,x9sci-ln4f-bmc", "nuvoton,wpcm450";
@@ -20,6 +23,46 @@
device_type = "memory";
reg = <0 0x08000000>; /* 128 MiB */
};
+
+ gpio-keys {
+ compatible = "gpio-keys";
+ pinctrl-names = "default";
+ pinctrl-0 = <&key_pins>;
+
+ uid {
+ label = "UID button";
+ linux,code = <KEY_HOME>;
+ gpios = <&gpio0 14 GPIO_ACTIVE_HIGH>;
+ };
+ };
+
+ gpio-leds {
+ compatible = "gpio-leds";
+ pinctrl-names = "default";
+ pinctrl-0 = <&led_pins>;
+
+ uid {
+ label = "UID";
+ gpios = <&gpio1 7 GPIO_ACTIVE_HIGH>;
+ };
+
+ heartbeat {
+ label = "heartbeat";
+ gpios = <&gpio1 4 GPIO_ACTIVE_LOW>;
+ };
+ };
+};
+
+&pinctrl {
+ key_pins: mux-keys {
+ groups = "gspi", "sspi";
+ function = "gpio";
+ };
+
+ led_pins: mux-leds {
+ groups = "hg3", "hg0", "pwm4";
+ function = "gpio";
+ };
};
&serial0 {
diff --git a/arch/arm/boot/dts/nuvoton-wpcm450.dtsi b/arch/arm/boot/dts/nuvoton-wpcm450.dtsi
index d7cbeb187484..93595850a4c3 100644
--- a/arch/arm/boot/dts/nuvoton-wpcm450.dtsi
+++ b/arch/arm/boot/dts/nuvoton-wpcm450.dtsi
@@ -8,6 +8,17 @@
#address-cells = <1>;
#size-cells = <1>;
+ aliases {
+ gpio0 = &gpio0;
+ gpio1 = &gpio1;
+ gpio2 = &gpio2;
+ gpio3 = &gpio3;
+ gpio4 = &gpio4;
+ gpio5 = &gpio5;
+ gpio6 = &gpio6;
+ gpio7 = &gpio7;
+ };
+
cpus {
#address-cells = <1>;
#size-cells = <0>;
@@ -33,12 +44,19 @@
interrupt-parent = <&aic>;
ranges;
+ gcr: syscon@b0000000 {
+ compatible = "nuvoton,wpcm450-gcr", "syscon", "simple-mfd";
+ reg = <0xb0000000 0x200>;
+ };
+
serial0: serial@b8000000 {
compatible = "nuvoton,wpcm450-uart";
reg = <0xb8000000 0x20>;
reg-shift = <2>;
interrupts = <7 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clk24m>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&bsp_pins>;
status = "disabled";
};
@@ -72,5 +90,371 @@
interrupt-controller;
#interrupt-cells = <2>;
};
+
+ pinctrl: pinctrl@b8003000 {
+ compatible = "nuvoton,wpcm450-pinctrl";
+ reg = <0xb8003000 0x1000>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ gpio0: gpio@0 {
+ reg = <0>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupts = <2 IRQ_TYPE_LEVEL_HIGH>,
+ <3 IRQ_TYPE_LEVEL_HIGH>,
+ <4 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-controller;
+ };
+
+ gpio1: gpio@1 {
+ reg = <1>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupts = <5 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-controller;
+ };
+
+ gpio2: gpio@2 {
+ reg = <2>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ gpio3: gpio@3 {
+ reg = <3>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ gpio4: gpio@4 {
+ reg = <4>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ gpio5: gpio@5 {
+ reg = <5>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ gpio6: gpio@6 {
+ reg = <6>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ gpio7: gpio@7 {
+ reg = <7>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ smb3_pins: mux-smb3 {
+ groups = "smb3";
+ function = "smb3";
+ };
+
+ smb4_pins: mux-smb4 {
+ groups = "smb4";
+ function = "smb4";
+ };
+
+ smb5_pins: mux-smb5 {
+ groups = "smb5";
+ function = "smb5";
+ };
+
+ scs1_pins: mux-scs1 {
+ groups = "scs1";
+ function = "scs1";
+ };
+
+ scs2_pins: mux-scs2 {
+ groups = "scs2";
+ function = "scs2";
+ };
+
+ scs3_pins: mux-scs3 {
+ groups = "scs3";
+ function = "scs3";
+ };
+
+ smb0_pins: mux-smb0 {
+ groups = "smb0";
+ function = "smb0";
+ };
+
+ smb1_pins: mux-smb1 {
+ groups = "smb1";
+ function = "smb1";
+ };
+
+ smb2_pins: mux-smb2 {
+ groups = "smb2";
+ function = "smb2";
+ };
+
+ bsp_pins: mux-bsp {
+ groups = "bsp";
+ function = "bsp";
+ };
+
+ hsp1_pins: mux-hsp1 {
+ groups = "hsp1";
+ function = "hsp1";
+ };
+
+ hsp2_pins: mux-hsp2 {
+ groups = "hsp2";
+ function = "hsp2";
+ };
+
+ r1err_pins: mux-r1err {
+ groups = "r1err";
+ function = "r1err";
+ };
+
+ r1md_pins: mux-r1md {
+ groups = "r1md";
+ function = "r1md";
+ };
+
+ rmii2_pins: mux-rmii2 {
+ groups = "rmii2";
+ function = "rmii2";
+ };
+
+ r2err_pins: mux-r2err {
+ groups = "r2err";
+ function = "r2err";
+ };
+
+ r2md_pins: mux-r2md {
+ groups = "r2md";
+ function = "r2md";
+ };
+
+ kbcc_pins: mux-kbcc {
+ groups = "kbcc";
+ function = "kbcc";
+ };
+
+ dvo0_pins: mux-dvo0 {
+ groups = "dvo";
+ function = "dvo0";
+ };
+
+ dvo3_pins: mux-dvo3 {
+ groups = "dvo";
+ function = "dvo3";
+ };
+
+ clko_pins: mux-clko {
+ groups = "clko";
+ function = "clko";
+ };
+
+ smi_pins: mux-smi {
+ groups = "smi";
+ function = "smi";
+ };
+
+ uinc_pins: mux-uinc {
+ groups = "uinc";
+ function = "uinc";
+ };
+
+ gspi_pins: mux-gspi {
+ groups = "gspi";
+ function = "gspi";
+ };
+
+ mben_pins: mux-mben {
+ groups = "mben";
+ function = "mben";
+ };
+
+ xcs2_pins: mux-xcs2 {
+ groups = "xcs2";
+ function = "xcs2";
+ };
+
+ xcs1_pins: mux-xcs1 {
+ groups = "xcs1";
+ function = "xcs1";
+ };
+
+ sdio_pins: mux-sdio {
+ groups = "sdio";
+ function = "sdio";
+ };
+
+ sspi_pins: mux-sspi {
+ groups = "sspi";
+ function = "sspi";
+ };
+
+ fi0_pins: mux-fi0 {
+ groups = "fi0";
+ function = "fi0";
+ };
+
+ fi1_pins: mux-fi1 {
+ groups = "fi1";
+ function = "fi1";
+ };
+
+ fi2_pins: mux-fi2 {
+ groups = "fi2";
+ function = "fi2";
+ };
+
+ fi3_pins: mux-fi3 {
+ groups = "fi3";
+ function = "fi3";
+ };
+
+ fi4_pins: mux-fi4 {
+ groups = "fi4";
+ function = "fi4";
+ };
+
+ fi5_pins: mux-fi5 {
+ groups = "fi5";
+ function = "fi5";
+ };
+
+ fi6_pins: mux-fi6 {
+ groups = "fi6";
+ function = "fi6";
+ };
+
+ fi7_pins: mux-fi7 {
+ groups = "fi7";
+ function = "fi7";
+ };
+
+ fi8_pins: mux-fi8 {
+ groups = "fi8";
+ function = "fi8";
+ };
+
+ fi9_pins: mux-fi9 {
+ groups = "fi9";
+ function = "fi9";
+ };
+
+ fi10_pins: mux-fi10 {
+ groups = "fi10";
+ function = "fi10";
+ };
+
+ fi11_pins: mux-fi11 {
+ groups = "fi11";
+ function = "fi11";
+ };
+
+ fi12_pins: mux-fi12 {
+ groups = "fi12";
+ function = "fi12";
+ };
+
+ fi13_pins: mux-fi13 {
+ groups = "fi13";
+ function = "fi13";
+ };
+
+ fi14_pins: mux-fi14 {
+ groups = "fi14";
+ function = "fi14";
+ };
+
+ fi15_pins: mux-fi15 {
+ groups = "fi15";
+ function = "fi15";
+ };
+
+ pwm0_pins: mux-pwm0 {
+ groups = "pwm0";
+ function = "pwm0";
+ };
+
+ pwm1_pins: mux-pwm1 {
+ groups = "pwm1";
+ function = "pwm1";
+ };
+
+ pwm2_pins: mux-pwm2 {
+ groups = "pwm2";
+ function = "pwm2";
+ };
+
+ pwm3_pins: mux-pwm3 {
+ groups = "pwm3";
+ function = "pwm3";
+ };
+
+ pwm4_pins: mux-pwm4 {
+ groups = "pwm4";
+ function = "pwm4";
+ };
+
+ pwm5_pins: mux-pwm5 {
+ groups = "pwm5";
+ function = "pwm5";
+ };
+
+ pwm6_pins: mux-pwm6 {
+ groups = "pwm6";
+ function = "pwm6";
+ };
+
+ pwm7_pins: mux-pwm7 {
+ groups = "pwm7";
+ function = "pwm7";
+ };
+
+ hg0_pins: mux-hg0 {
+ groups = "hg0";
+ function = "hg0";
+ };
+
+ hg1_pins: mux-hg1 {
+ groups = "hg1";
+ function = "hg1";
+ };
+
+ hg2_pins: mux-hg2 {
+ groups = "hg2";
+ function = "hg2";
+ };
+
+ hg3_pins: mux-hg3 {
+ groups = "hg3";
+ function = "hg3";
+ };
+
+ hg4_pins: mux-hg4 {
+ groups = "hg4";
+ function = "hg4";
+ };
+
+ hg5_pins: mux-hg5 {
+ groups = "hg5";
+ function = "hg5";
+ };
+
+ hg6_pins: mux-hg6 {
+ groups = "hg6";
+ function = "hg6";
+ };
+
+ hg7_pins: mux-hg7 {
+ groups = "hg7";
+ function = "hg7";
+ };
+ };
};
};
diff --git a/arch/arm/boot/dts/omap3-beagle-ab4.dts b/arch/arm/boot/dts/omap3-beagle-ab4.dts
new file mode 100644
index 000000000000..990ff2d84686
--- /dev/null
+++ b/arch/arm/boot/dts/omap3-beagle-ab4.dts
@@ -0,0 +1,47 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/dts-v1/;
+
+#include "omap3-beagle.dts"
+
+/ {
+ model = "TI OMAP3 BeagleBoard A to B4";
+ compatible = "ti,omap3-beagle-ab4", "ti,omap3-beagle", "ti,omap3430", "ti,omap3";
+};
+
+/*
+ * Workaround for capacitor C70 issue, see "Boards revision A and < B5"
+ * section at https://elinux.org/BeagleBoard_Community
+ */
+
+/* Unusable as clocksource because of unreliable oscillator */
+&counter32k {
+ status = "disabled";
+};
+
+/* Unusable as clockevent because of unreliable oscillator, allow to idle */
+&timer1_target {
+ /delete-property/ti,no-reset-on-init;
+ /delete-property/ti,no-idle;
+ timer@0 {
+ /delete-property/ti,timer-alwon;
+ };
+};
+
+/* Preferred always-on timer for clocksource */
+&timer12_target {
+ ti,no-reset-on-init;
+ ti,no-idle;
+ timer@0 {
+ /* Always clocked by secure_32k_fck */
+ };
+};
+
+/* Preferred timer for clockevent */
+&timer2_target {
+ ti,no-reset-on-init;
+ ti,no-idle;
+ timer@0 {
+ assigned-clocks = <&gpt2_fck>;
+ assigned-clock-parents = <&sys_ck>;
+ };
+};
diff --git a/arch/arm/boot/dts/omap3-beagle.dts b/arch/arm/boot/dts/omap3-beagle.dts
index f9f34b8458e9..0548b391334f 100644
--- a/arch/arm/boot/dts/omap3-beagle.dts
+++ b/arch/arm/boot/dts/omap3-beagle.dts
@@ -304,39 +304,6 @@
phys = <0 &hsusb2_phy>;
};
-/* Unusable as clocksource because of unreliable oscillator */
-&counter32k {
- status = "disabled";
-};
-
-/* Unusable as clockevent because if unreliable oscillator, allow to idle */
-&timer1_target {
- /delete-property/ti,no-reset-on-init;
- /delete-property/ti,no-idle;
- timer@0 {
- /delete-property/ti,timer-alwon;
- };
-};
-
-/* Preferred always-on timer for clocksource */
-&timer12_target {
- ti,no-reset-on-init;
- ti,no-idle;
- timer@0 {
- /* Always clocked by secure_32k_fck */
- };
-};
-
-/* Preferred timer for clockevent */
-&timer2_target {
- ti,no-reset-on-init;
- ti,no-idle;
- timer@0 {
- assigned-clocks = <&gpt2_fck>;
- assigned-clock-parents = <&sys_ck>;
- };
-};
-
&twl_gpio {
ti,use-leds;
/* pullups: BIT(1) */
diff --git a/arch/arm/boot/dts/omap3-devkit8000-common.dtsi b/arch/arm/boot/dts/omap3-devkit8000-common.dtsi
index 5e55198e4576..54cd37336be7 100644
--- a/arch/arm/boot/dts/omap3-devkit8000-common.dtsi
+++ b/arch/arm/boot/dts/omap3-devkit8000-common.dtsi
@@ -158,6 +158,24 @@
status = "disabled";
};
+/* Unusable as clockevent because if unreliable oscillator, allow to idle */
+&timer1_target {
+ /delete-property/ti,no-reset-on-init;
+ /delete-property/ti,no-idle;
+ timer@0 {
+ /delete-property/ti,timer-alwon;
+ };
+};
+
+/* Preferred timer for clockevent */
+&timer12_target {
+ ti,no-reset-on-init;
+ ti,no-idle;
+ timer@0 {
+ /* Always clocked by secure_32k_fck */
+ };
+};
+
&twl_gpio {
ti,use-leds;
/*
diff --git a/arch/arm/boot/dts/omap3-devkit8000.dts b/arch/arm/boot/dts/omap3-devkit8000.dts
index c2995a280729..162d0726b008 100644
--- a/arch/arm/boot/dts/omap3-devkit8000.dts
+++ b/arch/arm/boot/dts/omap3-devkit8000.dts
@@ -14,36 +14,3 @@
display2 = &tv0;
};
};
-
-/* Unusable as clocksource because of unreliable oscillator */
-&counter32k {
- status = "disabled";
-};
-
-/* Unusable as clockevent because if unreliable oscillator, allow to idle */
-&timer1_target {
- /delete-property/ti,no-reset-on-init;
- /delete-property/ti,no-idle;
- timer@0 {
- /delete-property/ti,timer-alwon;
- };
-};
-
-/* Preferred always-on timer for clocksource */
-&timer12_target {
- ti,no-reset-on-init;
- ti,no-idle;
- timer@0 {
- /* Always clocked by secure_32k_fck */
- };
-};
-
-/* Preferred timer for clockevent */
-&timer2_target {
- ti,no-reset-on-init;
- ti,no-idle;
- timer@0 {
- assigned-clocks = <&gpt2_fck>;
- assigned-clock-parents = <&sys_ck>;
- };
-};
diff --git a/arch/arm/boot/dts/openbmc-flash-layout-64.dtsi b/arch/arm/boot/dts/openbmc-flash-layout-64.dtsi
index 31f59de5190b..7af41361c480 100644
--- a/arch/arm/boot/dts/openbmc-flash-layout-64.dtsi
+++ b/arch/arm/boot/dts/openbmc-flash-layout-64.dtsi
@@ -28,7 +28,7 @@ partitions {
label = "rofs";
};
- rwfs@6000000 {
+ rwfs@2a00000 {
reg = <0x2a00000 0x1600000>; // 22MB
label = "rwfs";
};
diff --git a/arch/arm/boot/dts/openbmc-flash-layout.dtsi b/arch/arm/boot/dts/openbmc-flash-layout.dtsi
index 6c26524e93e1..b47e14063c38 100644
--- a/arch/arm/boot/dts/openbmc-flash-layout.dtsi
+++ b/arch/arm/boot/dts/openbmc-flash-layout.dtsi
@@ -20,7 +20,7 @@ partitions {
label = "kernel";
};
- rofs@c0000 {
+ rofs@4c0000 {
reg = <0x4c0000 0x1740000>;
label = "rofs";
};
diff --git a/arch/arm/boot/dts/ox810se-wd-mbwe.dts b/arch/arm/boot/dts/ox810se-wd-mbwe.dts
index 7e2fcb220aea..c59e06ff2423 100644
--- a/arch/arm/boot/dts/ox810se-wd-mbwe.dts
+++ b/arch/arm/boot/dts/ox810se-wd-mbwe.dts
@@ -103,6 +103,10 @@
};
};
+&etha {
+ status = "okay";
+};
+
&uart1 {
status = "okay";
diff --git a/arch/arm/boot/dts/ox810se.dtsi b/arch/arm/boot/dts/ox810se.dtsi
index 0755e5864c4a..96c0745f7b70 100644
--- a/arch/arm/boot/dts/ox810se.dtsi
+++ b/arch/arm/boot/dts/ox810se.dtsi
@@ -81,6 +81,24 @@
ranges;
interrupt-parent = <&intc>;
+ etha: ethernet@40400000 {
+ compatible = "oxsemi,ox810se-dwmac", "snps,dwmac";
+ reg = <0x40400000 0x2000>;
+ interrupts = <8>;
+ interrupt-names = "macirq";
+ mac-address = [000000000000]; /* Filled in by U-Boot */
+ phy-mode = "rgmii";
+
+ clocks = <&stdclk 6>, <&gmacclk>;
+ clock-names = "gmac", "stmmaceth";
+ resets = <&reset 6>;
+
+ /* Regmap for sys registers */
+ oxsemi,sys-ctrl = <&sys>;
+
+ status = "disabled";
+ };
+
apb-bridge@44000000 {
#address-cells = <1>;
#size-cells = <1>;
diff --git a/arch/arm/boot/dts/qcom-apq8026-lg-lenok.dts b/arch/arm/boot/dts/qcom-apq8026-lg-lenok.dts
index f350c4e8c194..2b7e52fda6a7 100644
--- a/arch/arm/boot/dts/qcom-apq8026-lg-lenok.dts
+++ b/arch/arm/boot/dts/qcom-apq8026-lg-lenok.dts
@@ -16,11 +16,35 @@
aliases {
serial0 = &blsp1_uart3;
+ serial1 = &blsp1_uart4;
};
chosen {
stdout-path = "serial0:115200n8";
};
+
+ vreg_wlan: wlan-regulator {
+ compatible = "regulator-fixed";
+
+ regulator-name = "wl-reg";
+ regulator-min-microvolt = <2950000>;
+ regulator-max-microvolt = <2950000>;
+
+ gpio = <&tlmm 46 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&wlan_regulator_default_state>;
+ };
+};
+
+&blsp1_i2c1 {
+ status = "okay";
+
+ fuel-gauge@55 {
+ compatible = "ti,bq27421";
+ reg = <0x55>;
+ };
};
&blsp1_i2c5 {
@@ -57,14 +81,30 @@
status = "okay";
};
+&blsp1_uart4 {
+ status = "okay";
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&blsp1_uart4_default_state>;
+
+ bluetooth {
+ compatible = "brcm,bcm43430a0-bt";
+
+ max-speed = <3000000>;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&bluetooth_default_state>;
+
+ host-wakeup-gpios = <&tlmm 48 GPIO_ACTIVE_HIGH>;
+ device-wakeup-gpios = <&tlmm 47 GPIO_ACTIVE_HIGH>;
+ shutdown-gpios = <&tlmm 45 GPIO_ACTIVE_HIGH>;
+ };
+};
+
&rpm_requests {
pm8226-regulators {
compatible = "qcom,rpm-pm8226-regulators";
- pm8226_s1: s1 {
- regulator-min-microvolt = <500000>;
- regulator-max-microvolt = <1275000>;
- };
pm8226_s3: s3 {
regulator-min-microvolt = <1200000>;
regulator-max-microvolt = <1350000>;
@@ -195,24 +235,55 @@
bus-width = <8>;
non-removable;
+};
- pinctrl-names = "default";
- pinctrl-0 = <&sdhc1_pin_a>;
+&sdhc_3 {
+ status = "okay";
+
+ max-frequency = <100000000>;
+ non-removable;
+
+ vmmc-supply = <&vreg_wlan>;
+ vqmmc-supply = <&pm8226_l6>;
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ wifi@1 {
+ compatible = "brcm,bcm43430a0-fmac", "brcm,bcm4329-fmac";
+ reg = <1>;
+
+ interrupts-extended = <&tlmm 37 IRQ_TYPE_EDGE_FALLING>;
+ interrupt-names = "host-wake";
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&wlan_hostwake_default_state>;
+ };
+};
+
+&smbb {
+ qcom,fast-charge-safe-current = <450000>;
+ qcom,fast-charge-current-limit = <400000>;
+ qcom,fast-charge-safe-voltage = <4350000>;
+ qcom,fast-charge-high-threshold-voltage = <4350000>;
+ qcom,auto-recharge-threshold-voltage = <4240000>;
+ qcom,minimum-input-voltage = <4450000>;
};
&tlmm {
- sdhc1_pin_a: sdhc1-pin-active {
- clk {
- pins = "sdc1_clk";
- drive-strength = <10>;
- bias-disable;
- };
+ blsp1_uart4_default_state: blsp1-uart4-default-state {
+ pins = "gpio12", "gpio13", "gpio14", "gpio15";
+ function = "blsp_uart4";
+ drive-strength = <8>;
+ bias-disable;
+ };
- cmd-data {
- pins = "sdc1_cmd", "sdc1_data";
- drive-strength = <10>;
- bias-pull-up;
- };
+ bluetooth_default_state: bluetooth-default-state {
+ pins = "gpio47", "gpio48";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-disable;
+ input-enable;
};
touch_pins: touch {
@@ -234,4 +305,31 @@
output-high;
};
};
+
+ wlan_hostwake_default_state: wlan-hostwake-default-state {
+ pins = "gpio37";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-disable;
+ input-enable;
+ };
+
+ wlan_regulator_default_state: wlan-regulator-default-state {
+ pins = "gpio46";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-pull-up;
+ };
+};
+
+&usb {
+ status = "okay";
+ extcon = <&smbb>;
+ dr_mode = "peripheral";
+};
+
+&usb_hs_phy {
+ extcon = <&smbb>;
+ v1p8-supply = <&pm8226_l10>;
+ v3p3-supply = <&pm8226_l20>;
};
diff --git a/arch/arm/boot/dts/qcom-apq8060-dragonboard.dts b/arch/arm/boot/dts/qcom-apq8060-dragonboard.dts
index d664ccd454c5..138d6478ac84 100644
--- a/arch/arm/boot/dts/qcom-apq8060-dragonboard.dts
+++ b/arch/arm/boot/dts/qcom-apq8060-dragonboard.dts
@@ -83,7 +83,7 @@
soc {
pinctrl@800000 {
- /* eMMMC pins, all 8 data lines connected */
+ /* eMMC pins, all 8 data lines connected */
dragon_sdcc1_pins: sdcc1 {
mux {
pins = "gpio159", "gpio160", "gpio161",
@@ -674,14 +674,14 @@
bias-pull-down;
};
- /* LVS0 thru 3 and mvs0 are just switches */
+ /* LVS0 thru 3 and mvs are just switches */
lvs0 {
regulator-always-on;
};
lvs1 { };
lvs2 { };
lvs3 { };
- mvs0 {};
+ mvs { };
};
diff --git a/arch/arm/boot/dts/qcom-apq8064-asus-nexus7-flo.dts b/arch/arm/boot/dts/qcom-apq8064-asus-nexus7-flo.dts
index 9a835335bf78..ca9f73528196 100644
--- a/arch/arm/boot/dts/qcom-apq8064-asus-nexus7-flo.dts
+++ b/arch/arm/boot/dts/qcom-apq8064-asus-nexus7-flo.dts
@@ -212,13 +212,12 @@
};
};
- dsi0: mdss_dsi@4700000 {
+ dsi0: dsi@4700000 {
status = "okay";
vdda-supply = <&pm8921_l2>;/*VDD_MIPI1 to 4*/
vdd-supply = <&pm8921_l8>;
vddio-supply = <&pm8921_lvs7>;
avdd-supply = <&pm8921_l11>;
- vcss-supply = <&ext_3p3v>;
panel@0 {
reg = <0>;
diff --git a/arch/arm/boot/dts/qcom-apq8064.dtsi b/arch/arm/boot/dts/qcom-apq8064.dtsi
index 4d562c94c31c..a1c8ae516d21 100644
--- a/arch/arm/boot/dts/qcom-apq8064.dtsi
+++ b/arch/arm/boot/dts/qcom-apq8064.dtsi
@@ -815,6 +815,7 @@
nvmem-cells = <&tsens_calib>, <&tsens_backup>;
nvmem-cell-names = "calib", "calib_backup";
#clock-cells = <1>;
+ #power-domain-cells = <1>;
#reset-cells = <1>;
#thermal-sensor-cells = <1>;
};
@@ -830,11 +831,12 @@
compatible = "qcom,mmcc-apq8064";
reg = <0x4000000 0x1000>;
#clock-cells = <1>;
+ #power-domain-cells = <1>;
#reset-cells = <1>;
};
l2cc: clock-controller@2011000 {
- compatible = "syscon";
+ compatible = "qcom,kpss-gcc", "syscon";
reg = <0x2011000 0x1000>;
};
@@ -1238,7 +1240,7 @@
reg = <0x5700000 0x70>;
};
- dsi0: mdss_dsi@4700000 {
+ dsi0: dsi@4700000 {
compatible = "qcom,mdss-dsi-ctrl";
label = "MDSS DSI CTRL->0";
#address-cells = <1>;
@@ -1268,6 +1270,7 @@
<&dsi0_phy 1>;
syscon-sfpb = <&mmss_sfpb>;
phys = <&dsi0_phy>;
+ phy-names = "dsi";
ports {
#address-cells = <1>;
#size-cells = <0>;
@@ -1368,10 +1371,10 @@
pcie: pci@1b500000 {
compatible = "qcom,pcie-apq8064", "snps,dw-pcie";
- reg = <0x1b500000 0x1000
- 0x1b502000 0x80
- 0x1b600000 0x100
- 0x0ff00000 0x100000>;
+ reg = <0x1b500000 0x1000>,
+ <0x1b502000 0x80>,
+ <0x1b600000 0x100>,
+ <0x0ff00000 0x100000>;
reg-names = "dbi", "elbi", "parf", "config";
device_type = "pci";
linux,pci-domain = <0>;
@@ -1379,8 +1382,8 @@
num-lanes = <1>;
#address-cells = <3>;
#size-cells = <2>;
- ranges = <0x81000000 0 0 0x0fe00000 0 0x00100000 /* I/O */
- 0x82000000 0 0x08000000 0x08000000 0 0x07e00000>; /* memory */
+ ranges = <0x81000000 0 0 0x0fe00000 0 0x00100000>, /* I/O */
+ <0x82000000 0 0x08000000 0x08000000 0 0x07e00000>; /* mem */
interrupts = <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "msi";
#interrupt-cells = <1>;
diff --git a/arch/arm/boot/dts/qcom-ipq4019.dtsi b/arch/arm/boot/dts/qcom-ipq4019.dtsi
index 7dec0553636e..a9d0566a3190 100644
--- a/arch/arm/boot/dts/qcom-ipq4019.dtsi
+++ b/arch/arm/boot/dts/qcom-ipq4019.dtsi
@@ -142,7 +142,8 @@
clocks {
sleep_clk: sleep_clk {
compatible = "fixed-clock";
- clock-frequency = <32768>;
+ clock-frequency = <32000>;
+ clock-output-names = "gcc_sleep_clk_src";
#clock-cells = <0>;
};
@@ -186,6 +187,7 @@
gcc: clock-controller@1800000 {
compatible = "qcom,gcc-ipq4019";
#clock-cells = <1>;
+ #power-domain-cells = <1>;
#reset-cells = <1>;
reg = <0x1800000 0x60000>;
};
diff --git a/arch/arm/boot/dts/qcom-mdm9615.dtsi b/arch/arm/boot/dts/qcom-mdm9615.dtsi
index c32415f0e66d..4d4f37cebf21 100644
--- a/arch/arm/boot/dts/qcom-mdm9615.dtsi
+++ b/arch/arm/boot/dts/qcom-mdm9615.dtsi
@@ -139,6 +139,7 @@
gcc: clock-controller@900000 {
compatible = "qcom,gcc-mdm9615";
#clock-cells = <1>;
+ #power-domain-cells = <1>;
#reset-cells = <1>;
reg = <0x900000 0x4000>;
};
@@ -151,7 +152,7 @@
};
l2cc: clock-controller@2011000 {
- compatible = "syscon";
+ compatible = "qcom,kpss-gcc", "syscon";
reg = <0x02011000 0x1000>;
};
diff --git a/arch/arm/boot/dts/qcom-msm8226.dtsi b/arch/arm/boot/dts/qcom-msm8226.dtsi
index 7d48599502b3..85e56992d2d0 100644
--- a/arch/arm/boot/dts/qcom-msm8226.dtsi
+++ b/arch/arm/boot/dts/qcom-msm8226.dtsi
@@ -8,6 +8,7 @@
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/clock/qcom,gcc-msm8974.h>
#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/reset/qcom,gcc-msm8974.h>
/ {
#address-cells = <1>;
@@ -72,6 +73,35 @@
rpm_requests: rpm-requests {
compatible = "qcom,rpm-msm8226";
qcom,smd-channels = "rpm_requests";
+
+ rpmpd: power-controller {
+ compatible = "qcom,msm8226-rpmpd";
+ #power-domain-cells = <1>;
+ operating-points-v2 = <&rpmpd_opp_table>;
+
+ rpmpd_opp_table: opp-table {
+ compatible = "operating-points-v2";
+
+ rpmpd_opp_ret: opp1 {
+ opp-level = <1>;
+ };
+ rpmpd_opp_svs_krait: opp2 {
+ opp-level = <2>;
+ };
+ rpmpd_opp_svs_soc: opp3 {
+ opp-level = <3>;
+ };
+ rpmpd_opp_nom: opp4 {
+ opp-level = <4>;
+ };
+ rpmpd_opp_turbo: opp5 {
+ opp-level = <5>;
+ };
+ rpmpd_opp_super_turbo: opp6 {
+ opp-level = <6>;
+ };
+ };
+ };
};
};
};
@@ -115,6 +145,8 @@
<&gcc GCC_SDCC1_AHB_CLK>,
<&xo_board>;
clock-names = "core", "iface", "xo";
+ pinctrl-names = "default";
+ pinctrl-0 = <&sdhc1_default_state>;
status = "disabled";
};
@@ -129,6 +161,8 @@
<&gcc GCC_SDCC2_AHB_CLK>,
<&xo_board>;
clock-names = "core", "iface", "xo";
+ pinctrl-names = "default";
+ pinctrl-0 = <&sdhc2_default_state>;
status = "disabled";
};
@@ -143,6 +177,8 @@
<&gcc GCC_SDCC3_AHB_CLK>,
<&xo_board>;
clock-names = "core", "iface", "xo";
+ pinctrl-names = "default";
+ pinctrl-0 = <&sdhc3_default_state>;
status = "disabled";
};
@@ -229,6 +265,44 @@
#size-cells = <0>;
};
+ usb: usb@f9a55000 {
+ compatible = "qcom,ci-hdrc";
+ reg = <0xf9a55000 0x200>,
+ <0xf9a55200 0x200>;
+ interrupts = <GIC_SPI 134 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&gcc GCC_USB_HS_AHB_CLK>,
+ <&gcc GCC_USB_HS_SYSTEM_CLK>;
+ clock-names = "iface", "core";
+ assigned-clocks = <&gcc GCC_USB_HS_SYSTEM_CLK>;
+ assigned-clock-rates = <75000000>;
+ resets = <&gcc GCC_USB_HS_BCR>;
+ reset-names = "core";
+ phy_type = "ulpi";
+ dr_mode = "otg";
+ hnp-disable;
+ srp-disable;
+ adp-disable;
+ ahb-burst-config = <0>;
+ phy-names = "usb-phy";
+ phys = <&usb_hs_phy>;
+ status = "disabled";
+ #reset-cells = <1>;
+
+ ulpi {
+ usb_hs_phy: phy {
+ compatible = "qcom,usb-hs-phy-msm8226",
+ "qcom,usb-hs-phy";
+ #phy-cells = <0>;
+ clocks = <&xo_board>, <&gcc GCC_USB2A_PHY_SLEEP_CLK>;
+ clock-names = "ref", "sleep";
+ resets = <&gcc GCC_USB2A_PHY_BCR>, <&usb 0>;
+ reset-names = "phy", "por";
+ qcom,init-seq = /bits/ 8 <0x0 0x44
+ 0x1 0x68 0x2 0x24 0x3 0x13>;
+ };
+ };
+ };
+
gcc: clock-controller@fc400000 {
compatible = "qcom,gcc-msm8226";
reg = <0xfc400000 0x4000>;
@@ -281,6 +355,57 @@
drive-strength = <2>;
bias-disable;
};
+
+ sdhc1_default_state: sdhc1-default-state {
+ clk {
+ pins = "sdc1_clk";
+ drive-strength = <10>;
+ bias-disable;
+ };
+
+ cmd-data {
+ pins = "sdc1_cmd", "sdc1_data";
+ drive-strength = <10>;
+ bias-pull-up;
+ };
+ };
+
+ sdhc2_default_state: sdhc2-default-state {
+ clk {
+ pins = "sdc2_clk";
+ drive-strength = <10>;
+ bias-disable;
+ };
+
+ cmd-data {
+ pins = "sdc2_cmd", "sdc2_data";
+ drive-strength = <10>;
+ bias-pull-up;
+ };
+ };
+
+ sdhc3_default_state: sdhc3-default-state {
+ clk {
+ pins = "gpio44";
+ function = "sdc3";
+ drive-strength = <8>;
+ bias-disable;
+ };
+
+ cmd {
+ pins = "gpio43";
+ function = "sdc3";
+ drive-strength = <8>;
+ bias-pull-up;
+ };
+
+ data {
+ pins = "gpio39", "gpio40", "gpio41", "gpio42";
+ function = "sdc3";
+ drive-strength = <8>;
+ bias-pull-up;
+ };
+ };
};
restart@fc4ab000 {
diff --git a/arch/arm/boot/dts/qcom-msm8660.dtsi b/arch/arm/boot/dts/qcom-msm8660.dtsi
index 1e8aab357f9c..a258abb23a64 100644
--- a/arch/arm/boot/dts/qcom-msm8660.dtsi
+++ b/arch/arm/boot/dts/qcom-msm8660.dtsi
@@ -126,6 +126,7 @@
gcc: clock-controller@900000 {
compatible = "qcom,gcc-msm8660";
#clock-cells = <1>;
+ #power-domain-cells = <1>;
#reset-cells = <1>;
reg = <0x900000 0x4000>;
};
@@ -390,7 +391,7 @@
};
l2cc: clock-controller@2082000 {
- compatible = "syscon";
+ compatible = "qcom,kpss-gcc", "syscon";
reg = <0x02082000 0x1000>;
};
diff --git a/arch/arm/boot/dts/qcom-msm8960-cdp.dts b/arch/arm/boot/dts/qcom-msm8960-cdp.dts
index 4af01039c3b2..d1fd0fe12ffe 100644
--- a/arch/arm/boot/dts/qcom-msm8960-cdp.dts
+++ b/arch/arm/boot/dts/qcom-msm8960-cdp.dts
@@ -279,7 +279,7 @@
pinctrl-0 = <&spi1_default>;
spi@16080000 {
status = "okay";
- eth@0 {
+ ethernet@0 {
compatible = "micrel,ks8851";
reg = <0>;
interrupt-parent = <&msmgpio>;
diff --git a/arch/arm/boot/dts/qcom-msm8960.dtsi b/arch/arm/boot/dts/qcom-msm8960.dtsi
index 2a0ec97a264f..4a2d74cf01d2 100644
--- a/arch/arm/boot/dts/qcom-msm8960.dtsi
+++ b/arch/arm/boot/dts/qcom-msm8960.dtsi
@@ -78,6 +78,15 @@
};
};
+ /* Temporary fixed regulator */
+ vsdcc_fixed: vsdcc-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "SDCC Power";
+ regulator-min-microvolt = <2700000>;
+ regulator-max-microvolt = <2700000>;
+ regulator-always-on;
+ };
+
soc: soc {
#address-cells = <1>;
#size-cells = <1>;
@@ -118,6 +127,7 @@
gcc: clock-controller@900000 {
compatible = "qcom,gcc-msm8960";
#clock-cells = <1>;
+ #power-domain-cells = <1>;
#reset-cells = <1>;
reg = <0x900000 0x4000>;
};
@@ -133,11 +143,12 @@
compatible = "qcom,mmcc-msm8960";
reg = <0x4000000 0x1000>;
#clock-cells = <1>;
+ #power-domain-cells = <1>;
#reset-cells = <1>;
};
l2cc: clock-controller@2011000 {
- compatible = "syscon";
+ compatible = "qcom,kpss-gcc", "syscon";
reg = <0x2011000 0x1000>;
};
@@ -146,7 +157,9 @@
reg = <0x108000 0x1000>;
qcom,ipc = <&l2cc 0x8 2>;
- interrupts = <0 19 0>, <0 21 0>, <0 22 0>;
+ interrupts = <GIC_SPI 19 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 21 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 22 IRQ_TYPE_EDGE_RISING>;
interrupt-names = "ack", "err", "wakeup";
regulators {
@@ -192,7 +205,7 @@
compatible = "qcom,msm-uartdm-v1.3", "qcom,msm-uartdm";
reg = <0x16440000 0x1000>,
<0x16400000 0x1000>;
- interrupts = <0 154 0x0>;
+ interrupts = <GIC_SPI 154 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&gcc GSBI5_UART_CLK>, <&gcc GSBI5_H_CLK>;
clock-names = "core", "iface";
status = "disabled";
@@ -249,15 +262,6 @@
clock-names = "core";
};
- /* Temporary fixed regulator */
- vsdcc_fixed: vsdcc-regulator {
- compatible = "regulator-fixed";
- regulator-name = "SDCC Power";
- regulator-min-microvolt = <2700000>;
- regulator-max-microvolt = <2700000>;
- regulator-always-on;
- };
-
amba {
compatible = "simple-bus";
#address-cells = <1>;
@@ -318,7 +322,7 @@
#address-cells = <1>;
#size-cells = <0>;
reg = <0x16080000 0x1000>;
- interrupts = <0 147 0>;
+ interrupts = <GIC_SPI 147 IRQ_TYPE_LEVEL_HIGH>;
spi-max-frequency = <24000000>;
cs-gpios = <&msmgpio 8 0>;
diff --git a/arch/arm/boot/dts/qcom-pm8226.dtsi b/arch/arm/boot/dts/qcom-pm8226.dtsi
index dddb5150dfd7..b3d0f7b5874d 100644
--- a/arch/arm/boot/dts/qcom-pm8226.dtsi
+++ b/arch/arm/boot/dts/qcom-pm8226.dtsi
@@ -16,6 +16,39 @@
debounce = <15625>;
bias-pull-up;
};
+
+ smbb: charger@1000 {
+ compatible = "qcom,pm8226-charger";
+ reg = <0x1000>;
+ interrupts = <0x0 0x10 7 IRQ_TYPE_EDGE_BOTH>,
+ <0x0 0x10 5 IRQ_TYPE_EDGE_BOTH>,
+ <0x0 0x10 4 IRQ_TYPE_EDGE_BOTH>,
+ <0x0 0x12 1 IRQ_TYPE_EDGE_BOTH>,
+ <0x0 0x12 0 IRQ_TYPE_EDGE_BOTH>,
+ <0x0 0x13 2 IRQ_TYPE_EDGE_BOTH>,
+ <0x0 0x13 1 IRQ_TYPE_EDGE_BOTH>,
+ <0x0 0x14 1 IRQ_TYPE_EDGE_BOTH>;
+ interrupt-names = "chg-done",
+ "chg-fast",
+ "chg-trkl",
+ "bat-temp-ok",
+ "bat-present",
+ "chg-gone",
+ "usb-valid",
+ "dc-valid";
+
+ chg_otg: otg-vbus { };
+ };
+
+ pm8226_mpps: mpps@a000 {
+ compatible = "qcom,pm8226-mpp", "qcom,spmi-mpp";
+ reg = <0xa000>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ gpio-ranges = <&pm8226_mpps 0 0 8>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
};
pm8226_1: pm8226@1 {
@@ -23,5 +56,15 @@
reg = <0x1 SPMI_USID>;
#address-cells = <1>;
#size-cells = <0>;
+
+ pm8226_spmi_regulators: pm8226-regulators {
+ compatible = "qcom,pm8226-regulators";
+ };
+
+ pm8226_vib: vibrator@c000 {
+ compatible = "qcom,pm8916-vib";
+ reg = <0xc000>;
+ status = "disabled";
+ };
};
};
diff --git a/arch/arm/boot/dts/qcom-sdx55.dtsi b/arch/arm/boot/dts/qcom-sdx55.dtsi
index 8ac0492c7659..d455795da44c 100644
--- a/arch/arm/boot/dts/qcom-sdx55.dtsi
+++ b/arch/arm/boot/dts/qcom-sdx55.dtsi
@@ -413,7 +413,7 @@
<0x40000000 0xf1d>,
<0x40000f20 0xc8>,
<0x40001000 0x1000>,
- <0x40002000 0x10000>,
+ <0x40200000 0x100000>,
<0x01c03000 0x3000>;
reg-names = "parf", "dbi", "elbi", "atu", "addr_space",
"mmio";
@@ -536,7 +536,7 @@
reg = <0x0c264000 0x1000>;
};
- spmi_bus: qcom,spmi@c440000 {
+ spmi_bus: spmi@c440000 {
compatible = "qcom,spmi-pmic-arb";
reg = <0x0c440000 0x0000d00>,
<0x0c600000 0x2000000>,
diff --git a/arch/arm/boot/dts/r8a7740-armadillo800eva.dts b/arch/arm/boot/dts/r8a7740-armadillo800eva.dts
index a01f3def1c69..0af63ddc4473 100644
--- a/arch/arm/boot/dts/r8a7740-armadillo800eva.dts
+++ b/arch/arm/boot/dts/r8a7740-armadillo800eva.dts
@@ -266,7 +266,7 @@
function = "lcd0";
};
- lcd0_mux {
+ lcd0-mux-hog {
/* DBGMD/LCDC0/FSIA MUX */
gpio-hog;
gpios = <176 0>;
diff --git a/arch/arm/boot/dts/r8a7742-iwg21d-q7-dbcm-ca.dts b/arch/arm/boot/dts/r8a7742-iwg21d-q7-dbcm-ca.dts
index 3c8a7c8b1fdd..4e58c54cde17 100644
--- a/arch/arm/boot/dts/r8a7742-iwg21d-q7-dbcm-ca.dts
+++ b/arch/arm/boot/dts/r8a7742-iwg21d-q7-dbcm-ca.dts
@@ -91,10 +91,10 @@
&gpio0 {
/* Disable hogging GP0_18 to output LOW */
- /delete-node/ qspi_en;
+ /delete-node/ qspi-en-hog;
/* Hog GP0_18 to output HIGH to enable VIN2 */
- vin2_en {
+ vin2-en-hog {
gpio-hog;
gpios = <18 GPIO_ACTIVE_HIGH>;
output-high;
diff --git a/arch/arm/boot/dts/r8a7742-iwg21d-q7.dts b/arch/arm/boot/dts/r8a7742-iwg21d-q7.dts
index a5a79cdbcd0e..64102b664055 100644
--- a/arch/arm/boot/dts/r8a7742-iwg21d-q7.dts
+++ b/arch/arm/boot/dts/r8a7742-iwg21d-q7.dts
@@ -226,7 +226,7 @@
};
&gpio0 {
- touch-interrupt {
+ touch-interrupt-hog {
gpio-hog;
gpios = <24 GPIO_ACTIVE_LOW>;
input;
@@ -234,7 +234,7 @@
};
&gpio1 {
- can-trx-en-gpio{
+ can-trx-en-hog {
gpio-hog;
gpios = <28 GPIO_ACTIVE_HIGH>;
output-low;
diff --git a/arch/arm/boot/dts/r8a7742-iwg21m.dtsi b/arch/arm/boot/dts/r8a7742-iwg21m.dtsi
index 5621c9ed698f..b281a4d164b0 100644
--- a/arch/arm/boot/dts/r8a7742-iwg21m.dtsi
+++ b/arch/arm/boot/dts/r8a7742-iwg21m.dtsi
@@ -37,7 +37,7 @@
&gpio0 {
/* GP0_18 set low to select QSPI. Doing so will disable VIN2 */
- qspi_en {
+ qspi-en-hog {
gpio-hog;
gpios = <18 GPIO_ACTIVE_HIGH>;
output-low;
diff --git a/arch/arm/boot/dts/r8a77470-iwg23s-sbc.dts b/arch/arm/boot/dts/r8a77470-iwg23s-sbc.dts
index b024621c9981..644802285249 100644
--- a/arch/arm/boot/dts/r8a77470-iwg23s-sbc.dts
+++ b/arch/arm/boot/dts/r8a77470-iwg23s-sbc.dts
@@ -116,7 +116,7 @@
};
&gpio2 {
- interrupt-fixup {
+ interrupt-fixup-hog {
gpio-hog;
gpios = <29 GPIO_ACTIVE_HIGH>;
line-name = "hdmi-hpd-int";
diff --git a/arch/arm/boot/dts/r9a06g032-rzn1d400-db.dts b/arch/arm/boot/dts/r9a06g032-rzn1d400-db.dts
index 4e57ae2688fc..3f8f3ce87e12 100644
--- a/arch/arm/boot/dts/r9a06g032-rzn1d400-db.dts
+++ b/arch/arm/boot/dts/r9a06g032-rzn1d400-db.dts
@@ -26,3 +26,8 @@
&uart0 {
status = "okay";
};
+
+&wdt0 {
+ timeout-sec = <60>;
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/r9a06g032.dtsi b/arch/arm/boot/dts/r9a06g032.dtsi
index c47896e4ab58..636a6ab31c58 100644
--- a/arch/arm/boot/dts/r9a06g032.dtsi
+++ b/arch/arm/boot/dts/r9a06g032.dtsi
@@ -66,6 +66,22 @@
interrupt-parent = <&gic>;
ranges;
+ wdt0: watchdog@40008000 {
+ compatible = "renesas,r9a06g032-wdt", "renesas,rzn1-wdt";
+ reg = <0x40008000 0x1000>;
+ interrupts = <GIC_SPI 73 IRQ_TYPE_EDGE_RISING>;
+ clocks = <&sysctrl R9A06G032_CLK_WATCHDOG>;
+ status = "disabled";
+ };
+
+ wdt1: watchdog@40009000 {
+ compatible = "renesas,r9a06g032-wdt", "renesas,rzn1-wdt";
+ reg = <0x40009000 0x1000>;
+ interrupts = <GIC_SPI 74 IRQ_TYPE_EDGE_RISING>;
+ clocks = <&sysctrl R9A06G032_CLK_WATCHDOG>;
+ status = "disabled";
+ };
+
sysctrl: system-controller@4000c000 {
compatible = "renesas,r9a06g032-sysctrl";
reg = <0x4000c000 0x1000>;
@@ -173,6 +189,17 @@
status = "okay";
};
+ nand_controller: nand-controller@40102000 {
+ compatible = "renesas,r9a06g032-nandc", "renesas,rzn1-nandc";
+ reg = <0x40102000 0x2000>;
+ interrupts = <GIC_SPI 58 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&sysctrl R9A06G032_HCLK_NAND>, <&sysctrl R9A06G032_CLK_NAND>;
+ clock-names = "hclk", "eclk";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
gic: interrupt-controller@44101000 {
compatible = "arm,gic-400", "arm,cortex-a7-gic";
interrupt-controller;
diff --git a/arch/arm/boot/dts/rk3188-px3-evb.dts b/arch/arm/boot/dts/rk3188-px3-evb.dts
index 39c60426c9c9..fc478ac4e781 100644
--- a/arch/arm/boot/dts/rk3188-px3-evb.dts
+++ b/arch/arm/boot/dts/rk3188-px3-evb.dts
@@ -212,7 +212,7 @@
regulator-name = "wl_18";
};
- lcd_33: SWITCH_REG1 {
+ lcd_33: SWITCH_REG {
regulator-name = "lcd_33";
};
};
diff --git a/arch/arm/boot/dts/rk322x.dtsi b/arch/arm/boot/dts/rk322x.dtsi
index 8eed9e3a92e9..5868eb512f69 100644
--- a/arch/arm/boot/dts/rk322x.dtsi
+++ b/arch/arm/boot/dts/rk322x.dtsi
@@ -718,8 +718,8 @@
interrupts = <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>;
assigned-clocks = <&cru SCLK_HDMI_PHY>;
assigned-clock-parents = <&hdmi_phy>;
- clocks = <&cru SCLK_HDMI_HDCP>, <&cru PCLK_HDMI_CTRL>, <&cru SCLK_HDMI_CEC>;
- clock-names = "isfr", "iahb", "cec";
+ clocks = <&cru PCLK_HDMI_CTRL>, <&cru SCLK_HDMI_HDCP>, <&cru SCLK_HDMI_CEC>;
+ clock-names = "iahb", "isfr", "cec";
pinctrl-names = "default";
pinctrl-0 = <&hdmii2c_xfer &hdmi_hpd &hdmi_cec>;
resets = <&cru SRST_HDMI_P>;
diff --git a/arch/arm/boot/dts/rk3288.dtsi b/arch/arm/boot/dts/rk3288.dtsi
index aaaa61875701..26b9bbe310af 100644
--- a/arch/arm/boot/dts/rk3288.dtsi
+++ b/arch/arm/boot/dts/rk3288.dtsi
@@ -971,7 +971,7 @@
status = "disabled";
};
- crypto: cypto-controller@ff8a0000 {
+ crypto: crypto@ff8a0000 {
compatible = "rockchip,rk3288-crypto";
reg = <0x0 0xff8a0000 0x0 0x4000>;
interrupts = <GIC_SPI 48 IRQ_TYPE_LEVEL_HIGH>;
@@ -980,7 +980,6 @@
clock-names = "aclk", "hclk", "sclk", "apb_pclk";
resets = <&cru SRST_CRYPTO>;
reset-names = "crypto-rst";
- status = "okay";
};
iep_mmu: iommu@ff900800 {
diff --git a/arch/arm/boot/dts/rv1108-elgin-r1.dts b/arch/arm/boot/dts/rv1108-elgin-r1.dts
index f62c9f7af79d..0c99a5934ebf 100644
--- a/arch/arm/boot/dts/rv1108-elgin-r1.dts
+++ b/arch/arm/boot/dts/rv1108-elgin-r1.dts
@@ -72,6 +72,7 @@
interrupt-parent = <&gpio0>;
interrupts = <RK_PB4 IRQ_TYPE_LEVEL_LOW>;
rockchip,system-power-controller;
+ #clock-cells = <0>;
vcc1-supply = <&vcc_sys>;
vcc2-supply = <&vcc_sys>;
diff --git a/arch/arm/boot/dts/rv1108-evb.dts b/arch/arm/boot/dts/rv1108-evb.dts
index fe5fc9bf75c9..46cad7cb94bf 100644
--- a/arch/arm/boot/dts/rv1108-evb.dts
+++ b/arch/arm/boot/dts/rv1108-evb.dts
@@ -85,6 +85,7 @@
interrupt-parent = <&gpio0>;
interrupts = <RK_PB4 IRQ_TYPE_LEVEL_LOW>;
rockchip,system-power-controller;
+ #clock-cells = <0>;
vcc1-supply = <&vcc_sys>;
vcc2-supply = <&vcc_sys>;
diff --git a/arch/arm/boot/dts/s3c2416-pinctrl.dtsi b/arch/arm/boot/dts/s3c2416-pinctrl.dtsi
index 92439ee5d7de..20a7d72827c2 100644
--- a/arch/arm/boot/dts/s3c2416-pinctrl.dtsi
+++ b/arch/arm/boot/dts/s3c2416-pinctrl.dtsi
@@ -12,66 +12,66 @@
* Pin banks
*/
- gpa: gpa {
+ gpa: gpa-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
};
- gpb: gpb {
+ gpb: gpb-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
};
- gpc: gpc {
+ gpc: gpc-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
};
- gpd: gpd {
+ gpd: gpd-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
};
- gpe: gpe {
+ gpe: gpe-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
};
- gpf: gpf {
+ gpf: gpf-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
interrupt-controller;
#interrupt-cells = <2>;
};
- gpg: gpg {
+ gpg: gpg-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
interrupt-controller;
#interrupt-cells = <2>;
};
- gph: gph {
+ gph: gph-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
};
- gpj: gpj {
+ gpj: gpj-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
};
- gpk: gpk {
+ gpk: gpk-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
};
- gpl: gpl {
+ gpl: gpl-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
};
- gpm: gpm {
+ gpm: gpm-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
};
@@ -80,92 +80,92 @@
* Pin groups
*/
- uart0_data: uart0-data {
+ uart0_data: uart0-data-pins {
samsung,pins = "gph-0", "gph-1";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
};
- uart0_fctl: uart0-fctl {
+ uart0_fctl: uart0-fctl-pins {
samsung,pins = "gph-8", "gph-9";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
};
- uart1_data: uart1-data {
+ uart1_data: uart1-data-pins {
samsung,pins = "gph-2", "gph-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
};
- uart1_fctl: uart1-fctl {
+ uart1_fctl: uart1-fctl-pins {
samsung,pins = "gph-10", "gph-11";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
};
- uart2_data: uart2-data {
+ uart2_data: uart2-data-pins {
samsung,pins = "gph-4", "gph-5";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
};
- uart2_fctl: uart2-fctl {
+ uart2_fctl: uart2-fctl-pins {
samsung,pins = "gph-6", "gph-7";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
};
- uart3_data: uart3-data {
+ uart3_data: uart3-data-pins {
samsung,pins = "gph-6", "gph-7";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
};
- extuart_clk: extuart-clk {
+ extuart_clk: extuart-clk-pins {
samsung,pins = "gph-12";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
};
- i2c0_bus: i2c0-bus {
+ i2c0_bus: i2c0-bus-pins {
samsung,pins = "gpe-14", "gpe-15";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
};
- spi0_bus: spi0-bus {
+ spi0_bus: spi0-bus-pins {
samsung,pins = "gpe-11", "gpe-12", "gpe-13";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
};
- sd0_clk: sd0-clk {
+ sd0_clk: sd0-clk-pins {
samsung,pins = "gpe-5";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
};
- sd0_cmd: sd0-cmd {
+ sd0_cmd: sd0-cmd-pins {
samsung,pins = "gpe-6";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
};
- sd0_bus1: sd0-bus1 {
+ sd0_bus1: sd0-bus1-pins {
samsung,pins = "gpe-7";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
};
- sd0_bus4: sd0-bus4 {
+ sd0_bus4: sd0-bus4-pins {
samsung,pins = "gpe-8", "gpe-9", "gpe-10";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
};
- sd1_cmd: sd1-cmd {
+ sd1_cmd: sd1-cmd-pins {
samsung,pins = "gpl-8";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
};
- sd1_clk: sd1-clk {
+ sd1_clk: sd1-clk-pins {
samsung,pins = "gpl-9";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
};
- sd1_bus1: sd1-bus1 {
+ sd1_bus1: sd1-bus1-pins {
samsung,pins = "gpl-0";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
};
- sd1_bus4: sd1-bus4 {
+ sd1_bus4: sd1-bus4-pins {
samsung,pins = "gpl-1", "gpl-2", "gpl-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
};
diff --git a/arch/arm/boot/dts/s3c6410-mini6410.dts b/arch/arm/boot/dts/s3c6410-mini6410.dts
index 285555b9ed94..17097da36f5e 100644
--- a/arch/arm/boot/dts/s3c6410-mini6410.dts
+++ b/arch/arm/boot/dts/s3c6410-mini6410.dts
@@ -193,12 +193,12 @@
};
&pinctrl0 {
- gpio_leds: gpio-leds {
+ gpio_leds: gpio-leds-pins {
samsung,pins = "gpk-4", "gpk-5", "gpk-6", "gpk-7";
samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
};
- gpio_keys: gpio-keys {
+ gpio_keys: gpio-keys-pins {
samsung,pins = "gpn-0", "gpn-1", "gpn-2", "gpn-3",
"gpn-4", "gpn-5", "gpl-11", "gpl-12";
samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
diff --git a/arch/arm/boot/dts/s3c64xx-pinctrl.dtsi b/arch/arm/boot/dts/s3c64xx-pinctrl.dtsi
index 8e9594d64b57..0a3186d57cb5 100644
--- a/arch/arm/boot/dts/s3c64xx-pinctrl.dtsi
+++ b/arch/arm/boot/dts/s3c64xx-pinctrl.dtsi
@@ -16,111 +16,111 @@
* Pin banks
*/
- gpa: gpa {
+ gpa: gpa-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
interrupt-controller;
#interrupt-cells = <2>;
};
- gpb: gpb {
+ gpb: gpb-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
interrupt-controller;
#interrupt-cells = <2>;
};
- gpc: gpc {
+ gpc: gpc-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
interrupt-controller;
#interrupt-cells = <2>;
};
- gpd: gpd {
+ gpd: gpd-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
interrupt-controller;
#interrupt-cells = <2>;
};
- gpe: gpe {
+ gpe: gpe-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
};
- gpf: gpf {
+ gpf: gpf-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
interrupt-controller;
#interrupt-cells = <2>;
};
- gpg: gpg {
+ gpg: gpg-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
interrupt-controller;
#interrupt-cells = <2>;
};
- gph: gph {
+ gph: gph-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
interrupt-controller;
#interrupt-cells = <2>;
};
- gpi: gpi {
+ gpi: gpi-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
};
- gpj: gpj {
+ gpj: gpj-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
};
- gpk: gpk {
+ gpk: gpk-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
};
- gpl: gpl {
+ gpl: gpl-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
interrupt-controller;
#interrupt-cells = <2>;
};
- gpm: gpm {
+ gpm: gpm-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
interrupt-controller;
#interrupt-cells = <2>;
};
- gpn: gpn {
+ gpn: gpn-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
interrupt-controller;
#interrupt-cells = <2>;
};
- gpo: gpo {
+ gpo: gpo-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
interrupt-controller;
#interrupt-cells = <2>;
};
- gpp: gpp {
+ gpp: gpp-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
interrupt-controller;
#interrupt-cells = <2>;
};
- gpq: gpq {
+ gpq: gpq-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
interrupt-controller;
@@ -131,225 +131,225 @@
* Pin groups
*/
- uart0_data: uart0-data {
+ uart0_data: uart0-data-pins {
samsung,pins = "gpa-0", "gpa-1";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
};
- uart0_fctl: uart0-fctl {
+ uart0_fctl: uart0-fctl-pins {
samsung,pins = "gpa-2", "gpa-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
};
- uart1_data: uart1-data {
+ uart1_data: uart1-data-pins {
samsung,pins = "gpa-4", "gpa-5";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
};
- uart1_fctl: uart1-fctl {
+ uart1_fctl: uart1-fctl-pins {
samsung,pins = "gpa-6", "gpa-7";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
};
- uart2_data: uart2-data {
+ uart2_data: uart2-data-pins {
samsung,pins = "gpb-0", "gpb-1";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
};
- uart3_data: uart3-data {
+ uart3_data: uart3-data-pins {
samsung,pins = "gpb-2", "gpb-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
};
- ext_dma_0: ext-dma-0 {
+ ext_dma_0: ext-dma-0-pins {
samsung,pins = "gpb-0", "gpb-1";
samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
};
- ext_dma_1: ext-dma-1 {
+ ext_dma_1: ext-dma-1-pins {
samsung,pins = "gpb-2", "gpb-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_4>;
samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
};
- irda_data_0: irda-data-0 {
+ irda_data_0: irda-data-0-pins {
samsung,pins = "gpb-0", "gpb-1";
samsung,pin-function = <EXYNOS_PIN_FUNC_4>;
samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
};
- irda_data_1: irda-data-1 {
+ irda_data_1: irda-data-1-pins {
samsung,pins = "gpb-2", "gpb-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
};
- irda_sdbw: irda-sdbw {
+ irda_sdbw: irda-sdbw-pins {
samsung,pins = "gpb-4";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
};
- i2c0_bus: i2c0-bus {
+ i2c0_bus: i2c0-bus-pins {
samsung,pins = "gpb-5", "gpb-6";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <S3C64XX_PIN_PULL_UP>;
};
- i2c1_bus: i2c1-bus {
+ i2c1_bus: i2c1-bus-pins {
/* S3C6410-only */
samsung,pins = "gpb-2", "gpb-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_6>;
samsung,pin-pud = <S3C64XX_PIN_PULL_UP>;
};
- spi0_bus: spi0-bus {
+ spi0_bus: spi0-bus-pins {
samsung,pins = "gpc-0", "gpc-1", "gpc-2";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <S3C64XX_PIN_PULL_UP>;
};
- spi0_cs: spi0-cs {
+ spi0_cs: spi0-cs-pins {
samsung,pins = "gpc-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
};
- spi1_bus: spi1-bus {
+ spi1_bus: spi1-bus-pins {
samsung,pins = "gpc-4", "gpc-5", "gpc-6";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <S3C64XX_PIN_PULL_UP>;
};
- spi1_cs: spi1-cs {
+ spi1_cs: spi1-cs-pins {
samsung,pins = "gpc-7";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
};
- sd0_cmd: sd0-cmd {
+ sd0_cmd: sd0-cmd-pins {
samsung,pins = "gpg-1";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
};
- sd0_clk: sd0-clk {
+ sd0_clk: sd0-clk-pins {
samsung,pins = "gpg-0";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
};
- sd0_bus1: sd0-bus1 {
+ sd0_bus1: sd0-bus1-pins {
samsung,pins = "gpg-2";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
};
- sd0_bus4: sd0-bus4 {
+ sd0_bus4: sd0-bus4-pins {
samsung,pins = "gpg-2", "gpg-3", "gpg-4", "gpg-5";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
};
- sd0_cd: sd0-cd {
+ sd0_cd: sd0-cd-pins {
samsung,pins = "gpg-6";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <S3C64XX_PIN_PULL_UP>;
};
- sd1_cmd: sd1-cmd {
+ sd1_cmd: sd1-cmd-pins {
samsung,pins = "gph-1";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
};
- sd1_clk: sd1-clk {
+ sd1_clk: sd1-clk-pins {
samsung,pins = "gph-0";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
};
- sd1_bus1: sd1-bus1 {
+ sd1_bus1: sd1-bus1-pins {
samsung,pins = "gph-2";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
};
- sd1_bus4: sd1-bus4 {
+ sd1_bus4: sd1-bus4-pins {
samsung,pins = "gph-2", "gph-3", "gph-4", "gph-5";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
};
- sd1_bus8: sd1-bus8 {
+ sd1_bus8: sd1-bus8-pins {
samsung,pins = "gph-2", "gph-3", "gph-4", "gph-5",
"gph-6", "gph-7", "gph-8", "gph-9";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
};
- sd1_cd: sd1-cd {
+ sd1_cd: sd1-cd-pins {
samsung,pins = "gpg-6";
samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
samsung,pin-pud = <S3C64XX_PIN_PULL_UP>;
};
- sd2_cmd: sd2-cmd {
+ sd2_cmd: sd2-cmd-pins {
samsung,pins = "gpc-4";
samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
};
- sd2_clk: sd2-clk {
+ sd2_clk: sd2-clk-pins {
samsung,pins = "gpc-5";
samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
};
- sd2_bus1: sd2-bus1 {
+ sd2_bus1: sd2-bus1-pins {
samsung,pins = "gph-6";
samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
};
- sd2_bus4: sd2-bus4 {
+ sd2_bus4: sd2-bus4-pins {
samsung,pins = "gph-6", "gph-7", "gph-8", "gph-9";
samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
};
- i2s0_bus: i2s0-bus {
+ i2s0_bus: i2s0-bus-pins {
samsung,pins = "gpd-0", "gpd-2", "gpd-3", "gpd-4";
samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
};
- i2s0_cdclk: i2s0-cdclk {
+ i2s0_cdclk: i2s0-cdclk-pins {
samsung,pins = "gpd-1";
samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
};
- i2s1_bus: i2s1-bus {
+ i2s1_bus: i2s1-bus-pins {
samsung,pins = "gpe-0", "gpe-2", "gpe-3", "gpe-4";
samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
};
- i2s1_cdclk: i2s1-cdclk {
+ i2s1_cdclk: i2s1-cdclk-pins {
samsung,pins = "gpe-1";
samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
};
- i2s2_bus: i2s2-bus {
+ i2s2_bus: i2s2-bus-pins {
/* S3C6410-only */
samsung,pins = "gpc-4", "gpc-5", "gpc-6", "gph-6",
"gph-8", "gph-9";
@@ -357,50 +357,50 @@
samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
};
- i2s2_cdclk: i2s2-cdclk {
+ i2s2_cdclk: i2s2-cdclk-pins {
/* S3C6410-only */
samsung,pins = "gph-7";
samsung,pin-function = <EXYNOS_PIN_FUNC_5>;
samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
};
- pcm0_bus: pcm0-bus {
+ pcm0_bus: pcm0-bus-pins {
samsung,pins = "gpd-0", "gpd-2", "gpd-3", "gpd-4";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
};
- pcm0_extclk: pcm0-extclk {
+ pcm0_extclk: pcm0-extclk-pins {
samsung,pins = "gpd-1";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
};
- pcm1_bus: pcm1-bus {
+ pcm1_bus: pcm1-bus-pins {
samsung,pins = "gpe-0", "gpe-2", "gpe-3", "gpe-4";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
};
- pcm1_extclk: pcm1-extclk {
+ pcm1_extclk: pcm1-extclk-pins {
samsung,pins = "gpe-1";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
};
- ac97_bus_0: ac97-bus-0 {
+ ac97_bus_0: ac97-bus-0-pins {
samsung,pins = "gpd-0", "gpd-1", "gpd-2", "gpd-3", "gpd-4";
samsung,pin-function = <EXYNOS_PIN_FUNC_4>;
samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
};
- ac97_bus_1: ac97-bus-1 {
+ ac97_bus_1: ac97-bus-1-pins {
samsung,pins = "gpe-0", "gpe-1", "gpe-2", "gpe-3", "gpe-4";
samsung,pin-function = <EXYNOS_PIN_FUNC_4>;
samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
};
- cam_port: cam-port {
+ cam_port: cam-port-pins {
samsung,pins = "gpf-0", "gpf-1", "gpf-2", "gpf-4",
"gpf-5", "gpf-6", "gpf-7", "gpf-8",
"gpf-9", "gpf-10", "gpf-11", "gpf-12";
@@ -408,242 +408,242 @@
samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
};
- cam_rst: cam-rst {
+ cam_rst: cam-rst-pins {
samsung,pins = "gpf-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
};
- cam_field: cam-field {
+ cam_field: cam-field-pins {
/* S3C6410-only */
samsung,pins = "gpb-4";
samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
};
- pwm_extclk: pwm-extclk {
+ pwm_extclk: pwm-extclk-pins {
samsung,pins = "gpf-13";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
};
- pwm0_out: pwm0-out {
+ pwm0_out: pwm0-out-pins {
samsung,pins = "gpf-14";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
};
- pwm1_out: pwm1-out {
+ pwm1_out: pwm1-out-pins {
samsung,pins = "gpf-15";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
};
- clkout0: clkout-0 {
+ clkout0: clkout-0-pins {
samsung,pins = "gpf-14";
samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
};
- keypad_col0_0: keypad-col0-0 {
+ keypad_col0_0: keypad-col0-0-pins {
samsung,pins = "gph-0";
samsung,pin-function = <EXYNOS_PIN_FUNC_4>;
samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
};
- keypad_col1_0: keypad-col1-0 {
+ keypad_col1_0: keypad-col1-0-pins {
samsung,pins = "gph-1";
samsung,pin-function = <EXYNOS_PIN_FUNC_4>;
samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
};
- keypad_col2_0: keypad-col2-0 {
+ keypad_col2_0: keypad-col2-0-pins {
samsung,pins = "gph-2";
samsung,pin-function = <EXYNOS_PIN_FUNC_4>;
samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
};
- keypad_col3_0: keypad-col3-0 {
+ keypad_col3_0: keypad-col3-0-pins {
samsung,pins = "gph-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_4>;
samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
};
- keypad_col4_0: keypad-col4-0 {
+ keypad_col4_0: keypad-col4-0-pins {
samsung,pins = "gph-4";
samsung,pin-function = <EXYNOS_PIN_FUNC_4>;
samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
};
- keypad_col5_0: keypad-col5-0 {
+ keypad_col5_0: keypad-col5-0-pins {
samsung,pins = "gph-5";
samsung,pin-function = <EXYNOS_PIN_FUNC_4>;
samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
};
- keypad_col6_0: keypad-col6-0 {
+ keypad_col6_0: keypad-col6-0-pins {
samsung,pins = "gph-6";
samsung,pin-function = <EXYNOS_PIN_FUNC_4>;
samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
};
- keypad_col7_0: keypad-col7-0 {
+ keypad_col7_0: keypad-col7-0-pins {
samsung,pins = "gph-7";
samsung,pin-function = <EXYNOS_PIN_FUNC_4>;
samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
};
- keypad_col0_1: keypad-col0-1 {
+ keypad_col0_1: keypad-col0-1-pins {
samsung,pins = "gpl-0";
samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
};
- keypad_col1_1: keypad-col1-1 {
+ keypad_col1_1: keypad-col1-1-pins {
samsung,pins = "gpl-1";
samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
};
- keypad_col2_1: keypad-col2-1 {
+ keypad_col2_1: keypad-col2-1-pins {
samsung,pins = "gpl-2";
samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
};
- keypad_col3_1: keypad-col3-1 {
+ keypad_col3_1: keypad-col3-1-pins {
samsung,pins = "gpl-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
};
- keypad_col4_1: keypad-col4-1 {
+ keypad_col4_1: keypad-col4-1-pins {
samsung,pins = "gpl-4";
samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
};
- keypad_col5_1: keypad-col5-1 {
+ keypad_col5_1: keypad-col5-1-pins {
samsung,pins = "gpl-5";
samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
};
- keypad_col6_1: keypad-col6-1 {
+ keypad_col6_1: keypad-col6-1-pins {
samsung,pins = "gpl-6";
samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
};
- keypad_col7_1: keypad-col7-1 {
+ keypad_col7_1: keypad-col7-1-pins {
samsung,pins = "gpl-7";
samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
};
- keypad_row0_0: keypad-row0-0 {
+ keypad_row0_0: keypad-row0-0-pins {
samsung,pins = "gpk-8";
samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
};
- keypad_row1_0: keypad-row1-0 {
+ keypad_row1_0: keypad-row1-0-pins {
samsung,pins = "gpk-9";
samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
};
- keypad_row2_0: keypad-row2-0 {
+ keypad_row2_0: keypad-row2-0-pins {
samsung,pins = "gpk-10";
samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
};
- keypad_row3_0: keypad-row3-0 {
+ keypad_row3_0: keypad-row3-0-pins {
samsung,pins = "gpk-11";
samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
};
- keypad_row4_0: keypad-row4-0 {
+ keypad_row4_0: keypad-row4-0-pins {
samsung,pins = "gpk-12";
samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
};
- keypad_row5_0: keypad-row5-0 {
+ keypad_row5_0: keypad-row5-0-pins {
samsung,pins = "gpk-13";
samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
};
- keypad_row6_0: keypad-row6-0 {
+ keypad_row6_0: keypad-row6-0-pins {
samsung,pins = "gpk-14";
samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
};
- keypad_row7_0: keypad-row7-0 {
+ keypad_row7_0: keypad-row7-0-pins {
samsung,pins = "gpk-15";
samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
};
- keypad_row0_1: keypad-row0-1 {
+ keypad_row0_1: keypad-row0-1-pins {
samsung,pins = "gpn-0";
samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
};
- keypad_row1_1: keypad-row1-1 {
+ keypad_row1_1: keypad-row1-1-pins {
samsung,pins = "gpn-1";
samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
};
- keypad_row2_1: keypad-row2-1 {
+ keypad_row2_1: keypad-row2-1-pins {
samsung,pins = "gpn-2";
samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
};
- keypad_row3_1: keypad-row3-1 {
+ keypad_row3_1: keypad-row3-1-pins {
samsung,pins = "gpn-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
};
- keypad_row4_1: keypad-row4-1 {
+ keypad_row4_1: keypad-row4-1-pins {
samsung,pins = "gpn-4";
samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
};
- keypad_row5_1: keypad-row5-1 {
+ keypad_row5_1: keypad-row5-1-pins {
samsung,pins = "gpn-5";
samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
};
- keypad_row6_1: keypad-row6-1 {
+ keypad_row6_1: keypad-row6-1-pins {
samsung,pins = "gpn-6";
samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
};
- keypad_row7_1: keypad-row7-1 {
+ keypad_row7_1: keypad-row7-1-pins {
samsung,pins = "gpn-7";
samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
};
- lcd_ctrl: lcd-ctrl {
+ lcd_ctrl: lcd-ctrl-pins {
samsung,pins = "gpj-8", "gpj-9", "gpj-10", "gpj-11";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
};
- lcd_data16: lcd-data-width16 {
+ lcd_data16: lcd-data-width16-pins {
samsung,pins = "gpi-3", "gpi-4", "gpi-5", "gpi-6",
"gpi-7", "gpi-10", "gpi-11", "gpi-12",
"gpi-13", "gpi-14", "gpi-15", "gpj-3",
@@ -652,7 +652,7 @@
samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
};
- lcd_data18: lcd-data-width18 {
+ lcd_data18: lcd-data-width18-pins {
samsung,pins = "gpi-2", "gpi-3", "gpi-4", "gpi-5",
"gpi-6", "gpi-7", "gpi-10", "gpi-11",
"gpi-12", "gpi-13", "gpi-14", "gpi-15",
@@ -662,7 +662,7 @@
samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
};
- lcd_data24: lcd-data-width24 {
+ lcd_data24: lcd-data-width24-pins {
samsung,pins = "gpi-0", "gpi-1", "gpi-2", "gpi-3",
"gpi-4", "gpi-5", "gpi-6", "gpi-7",
"gpi-8", "gpi-9", "gpi-10", "gpi-11",
@@ -673,7 +673,7 @@
samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
};
- hsi_bus: hsi-bus {
+ hsi_bus: hsi-bus-pins {
samsung,pins = "gpk-0", "gpk-1", "gpk-2", "gpk-3",
"gpk-4", "gpk-5", "gpk-6", "gpk-7";
samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
diff --git a/arch/arm/boot/dts/s3c64xx.dtsi b/arch/arm/boot/dts/s3c64xx.dtsi
index cb11a87dbc42..67a7a66e11d5 100644
--- a/arch/arm/boot/dts/s3c64xx.dtsi
+++ b/arch/arm/boot/dts/s3c64xx.dtsi
@@ -178,20 +178,12 @@
interrupt-parent = <&vic1>;
interrupts = <21>;
- pctrl_int_map: pinctrl-interrupt-map {
- interrupt-map = <0 &vic0 0>,
- <1 &vic0 1>,
- <2 &vic1 0>,
- <3 &vic1 1>;
- #address-cells = <0>;
- #size-cells = <0>;
- #interrupt-cells = <1>;
- };
-
wakeup-interrupt-controller {
compatible = "samsung,s3c64xx-wakeup-eint";
- interrupts = <0>, <1>, <2>, <3>;
- interrupt-parent = <&pctrl_int_map>;
+ interrupts-extended = <&vic0 0>,
+ <&vic0 1>,
+ <&vic1 0>,
+ <&vic1 1>;
};
};
};
diff --git a/arch/arm/boot/dts/s5pv210-aquila.dts b/arch/arm/boot/dts/s5pv210-aquila.dts
index 6423348034b6..54de3bc77c30 100644
--- a/arch/arm/boot/dts/s5pv210-aquila.dts
+++ b/arch/arm/boot/dts/s5pv210-aquila.dts
@@ -391,7 +391,7 @@
};
&pinctrl0 {
- t_flash_detect: t-flash-detect {
+ t_flash_detect: t-flash-detect-pins {
samsung,pins = "gph3-4";
samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
diff --git a/arch/arm/boot/dts/s5pv210-aries.dtsi b/arch/arm/boot/dts/s5pv210-aries.dtsi
index 160f8cd9a68d..c8f1c324a6c2 100644
--- a/arch/arm/boot/dts/s5pv210-aries.dtsi
+++ b/arch/arm/boot/dts/s5pv210-aries.dtsi
@@ -645,21 +645,21 @@
};
&pinctrl0 {
- bt_reset: bt-reset {
+ bt_reset: bt-reset-pins {
samsung,pins = "gpb-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- wlan_bt_en: wlan-bt-en {
+ wlan_bt_en: wlan-bt-en-pins {
samsung,pins = "gpb-5";
samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
samsung,pin-val = <1>;
};
- codec_ldo: codec-ldo {
+ codec_ldo: codec-ldo-pins {
samsung,pins = "gpf3-4";
samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
@@ -671,19 +671,19 @@
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- wlan_gpio_rst: wlan-gpio-rst {
+ wlan_gpio_rst: wlan-gpio-rst-pins {
samsung,pins = "gpg1-2";
samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
};
- bt_wake: bt-wake {
+ bt_wake: bt-wake-pins {
samsung,pins = "gpg3-4";
samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
};
- gp2a_irq: gp2a-irq {
+ gp2a_irq: gp2a-irq-pins {
samsung,pins = "gph0-2";
samsung,pin-function = <EXYNOS_PIN_FUNC_F>;
samsung,pin-pud = <S3C64XX_PIN_PULL_DOWN>;
@@ -698,67 +698,67 @@
samsung,pin-val = <0>;
};
- pmic_irq: pmic-irq {
+ pmic_irq: pmic-irq-pins {
samsung,pins = "gph0-7";
samsung,pin-function = <EXYNOS_PIN_FUNC_F>;
samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- wifi_host_wake: wifi-host-wake {
+ wifi_host_wake: wifi-host-wake-pins {
samsung,pins = "gph2-4";
samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
samsung,pin-pud = <S3C64XX_PIN_PULL_DOWN>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- bt_host_wake: bt-host-wake {
+ bt_host_wake: bt-host-wake-pins {
samsung,pins = "gph2-5";
samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
samsung,pin-pud = <S3C64XX_PIN_PULL_DOWN>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- musb_irq: musq-irq {
+ musb_irq: musq-irq-pins {
samsung,pins = "gph2-7";
samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- tf_detect: tf-detect {
+ tf_detect: tf-detect-pins {
samsung,pins = "gph3-4";
samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
samsung,pin-pud = <S3C64XX_PIN_PULL_DOWN>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- wifi_wake: wifi-wake {
+ wifi_wake: wifi-wake-pins {
samsung,pins = "gph3-5";
samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
};
- magnetometer_i2c_pins: yas529-i2c-pins {
+ magnetometer_i2c_pins: yas529-i2c-pins-pins {
samsung,pins = "gpj0-0", "gpj0-1";
samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- ts_irq: ts-irq {
+ ts_irq: ts-irq-pins {
samsung,pins = "gpj0-5";
samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- vibrator_ena: vibrator-ena {
+ vibrator_ena: vibrator-ena-pins {
samsung,pins = "gpj1-1";
samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- gp2a_power: gp2a-power {
+ gp2a_power: gp2a-power-pins {
samsung,pins = "gpj1-4";
samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
@@ -771,7 +771,7 @@
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- touchkey_vdd_ena: touchkey-vdd-ena {
+ touchkey_vdd_ena: touchkey-vdd-ena-pins {
samsung,pins = "gpj3-2";
samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
@@ -789,13 +789,13 @@
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- pmic_i2c_pins: pmic-i2c-pins {
+ pmic_i2c_pins: pmic-i2c-pins-pins {
samsung,pins = "gpj4-0", "gpj4-3";
samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- touchkey_irq: touchkey-irq {
+ touchkey_irq: touchkey-irq-pins {
samsung,pins = "gpj4-1";
samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
samsung,pin-pud = <S3C64XX_PIN_PULL_UP>;
@@ -820,7 +820,7 @@
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- panel_rst: panel-rst {
+ panel_rst: panel-rst-pins {
samsung,pins = "mp05-5";
samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
diff --git a/arch/arm/boot/dts/s5pv210-fascinate4g.dts b/arch/arm/boot/dts/s5pv210-fascinate4g.dts
index 7427c84f1126..dfb2ee65e4a8 100644
--- a/arch/arm/boot/dts/s5pv210-fascinate4g.dts
+++ b/arch/arm/boot/dts/s5pv210-fascinate4g.dts
@@ -126,39 +126,39 @@
pinctrl-names = "default";
pinctrl-0 = <&sleep_cfg>;
- headset_det: headset-det {
+ headset_det: headset-det-pins {
samsung,pins = "gph0-6", "gph3-6";
samsung,pin-function = <EXYNOS_PIN_FUNC_F>;
samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
};
- fg_irq: fg-irq {
+ fg_irq: fg-irq-pins {
samsung,pins = "gph3-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_F>;
samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- headset_micbias_ena: headset-micbias-ena {
+ headset_micbias_ena: headset-micbias-ena-pins {
samsung,pins = "gpj2-5";
samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- earpath_sel: earpath-sel {
+ earpath_sel: earpath-sel-pins {
samsung,pins = "gpj2-6";
samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- main_micbias_ena: main-micbias-ena {
+ main_micbias_ena: main-micbias-ena-pins {
samsung,pins = "gpj4-2";
samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
/* Based on vendor kernel v2.6.35.7 */
- sleep_cfg: sleep-cfg {
+ sleep_cfg: sleep-state {
PIN_SLP(gpa0-0, PREV, NONE);
PIN_SLP(gpa0-1, PREV, NONE);
PIN_SLP(gpa0-2, PREV, NONE);
diff --git a/arch/arm/boot/dts/s5pv210-galaxys.dts b/arch/arm/boot/dts/s5pv210-galaxys.dts
index eeec2bdece11..a78caaa1f3c5 100644
--- a/arch/arm/boot/dts/s5pv210-galaxys.dts
+++ b/arch/arm/boot/dts/s5pv210-galaxys.dts
@@ -150,53 +150,53 @@
pinctrl-names = "default";
pinctrl-0 = <&sleep_cfg>;
- fm_i2c_pins: fm-i2c-pins {
+ fm_i2c_pins: fm-i2c-pins-pins {
samsung,pins = "gpd1-2", "gpd1-3";
samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- headset_det: headset-det {
+ headset_det: headset-det-pins {
samsung,pins = "gph0-6", "gph3-6";
samsung,pin-function = <EXYNOS_PIN_FUNC_F>;
samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
};
- fm_irq: fm-irq {
+ fm_irq: fm-irq-pins {
samsung,pins = "gpj2-4";
samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
samsung,pin-pud = <S3C64XX_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- fm_rst: fm-rst {
+ fm_rst: fm-rst-pins {
samsung,pins = "gpj2-5";
samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- earpath_sel: earpath-sel {
+ earpath_sel: earpath-sel-pins {
samsung,pins = "gpj2-6";
samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- massmemory_en: massmemory-en {
+ massmemory_en: massmemory-en-pins {
samsung,pins = "gpj2-7";
samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- micbias_reg_ena: micbias-reg-ena {
+ micbias_reg_ena: micbias-reg-ena-pins {
samsung,pins = "gpj4-2";
samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
/* Based on CyanogenMod 3.0.101 kernel */
- sleep_cfg: sleep-cfg {
+ sleep_cfg: sleep-state {
PIN_SLP(gpa0-0, PREV, NONE);
PIN_SLP(gpa0-1, PREV, NONE);
PIN_SLP(gpa0-2, PREV, NONE);
diff --git a/arch/arm/boot/dts/s5pv210-pinctrl.dtsi b/arch/arm/boot/dts/s5pv210-pinctrl.dtsi
index b8c5172c31dd..ae34e7e57892 100644
--- a/arch/arm/boot/dts/s5pv210-pinctrl.dtsi
+++ b/arch/arm/boot/dts/s5pv210-pinctrl.dtsi
@@ -26,7 +26,7 @@
}
&pinctrl0 {
- gpa0: gpa0 {
+ gpa0: gpa0-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -34,7 +34,7 @@
#interrupt-cells = <2>;
};
- gpa1: gpa1 {
+ gpa1: gpa1-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -42,7 +42,7 @@
#interrupt-cells = <2>;
};
- gpb: gpb {
+ gpb: gpb-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -50,7 +50,7 @@
#interrupt-cells = <2>;
};
- gpc0: gpc0 {
+ gpc0: gpc0-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -58,7 +58,7 @@
#interrupt-cells = <2>;
};
- gpc1: gpc1 {
+ gpc1: gpc1-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -66,7 +66,7 @@
#interrupt-cells = <2>;
};
- gpd0: gpd0 {
+ gpd0: gpd0-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -74,7 +74,7 @@
#interrupt-cells = <2>;
};
- gpd1: gpd1 {
+ gpd1: gpd1-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -82,7 +82,7 @@
#interrupt-cells = <2>;
};
- gpe0: gpe0 {
+ gpe0: gpe0-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -90,7 +90,7 @@
#interrupt-cells = <2>;
};
- gpe1: gpe1 {
+ gpe1: gpe1-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -98,7 +98,7 @@
#interrupt-cells = <2>;
};
- gpf0: gpf0 {
+ gpf0: gpf0-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -106,7 +106,7 @@
#interrupt-cells = <2>;
};
- gpf1: gpf1 {
+ gpf1: gpf1-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -114,7 +114,7 @@
#interrupt-cells = <2>;
};
- gpf2: gpf2 {
+ gpf2: gpf2-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -122,7 +122,7 @@
#interrupt-cells = <2>;
};
- gpf3: gpf3 {
+ gpf3: gpf3-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -130,7 +130,7 @@
#interrupt-cells = <2>;
};
- gpg0: gpg0 {
+ gpg0: gpg0-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -138,7 +138,7 @@
#interrupt-cells = <2>;
};
- gpg1: gpg1 {
+ gpg1: gpg1-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -146,7 +146,7 @@
#interrupt-cells = <2>;
};
- gpg2: gpg2 {
+ gpg2: gpg2-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -154,7 +154,7 @@
#interrupt-cells = <2>;
};
- gpg3: gpg3 {
+ gpg3: gpg3-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -162,7 +162,7 @@
#interrupt-cells = <2>;
};
- gpj0: gpj0 {
+ gpj0: gpj0-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -170,7 +170,7 @@
#interrupt-cells = <2>;
};
- gpj1: gpj1 {
+ gpj1: gpj1-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -178,7 +178,7 @@
#interrupt-cells = <2>;
};
- gpj2: gpj2 {
+ gpj2: gpj2-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -186,7 +186,7 @@
#interrupt-cells = <2>;
};
- gpj3: gpj3 {
+ gpj3: gpj3-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -194,7 +194,7 @@
#interrupt-cells = <2>;
};
- gpj4: gpj4 {
+ gpj4: gpj4-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -202,47 +202,47 @@
#interrupt-cells = <2>;
};
- gpi: gpi {
+ gpi: gpi-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
};
- mp01: mp01 {
+ mp01: mp01-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
};
- mp02: mp02 {
+ mp02: mp02-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
};
- mp03: mp03 {
+ mp03: mp03-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
};
- mp04: mp04 {
+ mp04: mp04-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
};
- mp05: mp05 {
+ mp05: mp05-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
};
- mp06: mp06 {
+ mp06: mp06-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
};
- mp07: mp07 {
+ mp07: mp07-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
};
- gph0: gph0 {
+ gph0: gph0-gpio-bank {
gpio-controller;
interrupt-controller;
interrupt-parent = <&vic0>;
@@ -252,7 +252,7 @@
#interrupt-cells = <2>;
};
- gph1: gph1 {
+ gph1: gph1-gpio-bank {
gpio-controller;
interrupt-controller;
interrupt-parent = <&vic0>;
@@ -262,7 +262,7 @@
#interrupt-cells = <2>;
};
- gph2: gph2 {
+ gph2: gph2-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -270,7 +270,7 @@
#interrupt-cells = <2>;
};
- gph3: gph3 {
+ gph3: gph3-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -278,77 +278,77 @@
#interrupt-cells = <2>;
};
- uart0_data: uart0-data {
+ uart0_data: uart0-data-pins {
samsung,pins = "gpa0-0", "gpa0-1";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- uart0_fctl: uart0-fctl {
+ uart0_fctl: uart0-fctl-pins {
samsung,pins = "gpa0-2", "gpa0-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- uart1_data: uart1-data {
+ uart1_data: uart1-data-pins {
samsung,pins = "gpa0-4", "gpa0-5";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- uart1_fctl: uart1-fctl {
+ uart1_fctl: uart1-fctl-pins {
samsung,pins = "gpa0-6", "gpa0-7";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- uart2_data: uart2-data {
+ uart2_data: uart2-data-pins {
samsung,pins = "gpa1-0", "gpa1-1";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- uart2_fctl: uart2-fctl {
+ uart2_fctl: uart2-fctl-pins {
samsung,pins = "gpa1-2", "gpa1-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- uart3_data: uart3-data {
+ uart3_data: uart3-data-pins {
samsung,pins = "gpa1-2", "gpa1-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- uart_audio: uart-audio {
+ uart_audio: uart-audio-pins {
samsung,pins = "gpa1-2", "gpa1-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_4>;
samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- spi0_bus: spi0-bus {
+ spi0_bus: spi0-bus-pins {
samsung,pins = "gpb-0", "gpb-2", "gpb-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <S3C64XX_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- spi1_bus: spi1-bus {
+ spi1_bus: spi1-bus-pins {
samsung,pins = "gpb-4", "gpb-6", "gpb-7";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <S3C64XX_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- i2s0_bus: i2s0-bus {
+ i2s0_bus: i2s0-bus-pins {
samsung,pins = "gpi-0", "gpi-1", "gpi-2", "gpi-3",
"gpi-4", "gpi-5", "gpi-6";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
@@ -356,7 +356,7 @@
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- i2s1_bus: i2s1-bus {
+ i2s1_bus: i2s1-bus-pins {
samsung,pins = "gpc0-0", "gpc0-1", "gpc0-2", "gpc0-3",
"gpc0-4";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
@@ -364,7 +364,7 @@
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- i2s2_bus: i2s2-bus {
+ i2s2_bus: i2s2-bus-pins {
samsung,pins = "gpc1-0", "gpc1-1", "gpc1-2", "gpc1-3",
"gpc1-4";
samsung,pin-function = <EXYNOS_PIN_FUNC_4>;
@@ -372,7 +372,7 @@
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- pcm1_bus: pcm1-bus {
+ pcm1_bus: pcm1-bus-pins {
samsung,pins = "gpc0-0", "gpc0-1", "gpc0-2", "gpc0-3",
"gpc0-4";
samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
@@ -380,7 +380,7 @@
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- ac97_bus: ac97-bus {
+ ac97_bus: ac97-bus-pins {
samsung,pins = "gpc0-0", "gpc0-1", "gpc0-2", "gpc0-3",
"gpc0-4";
samsung,pin-function = <EXYNOS_PIN_FUNC_4>;
@@ -388,7 +388,7 @@
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- i2s2_bus: i2s2-bus {
+ i2s2_bus: i2s2-bus-pins {
samsung,pins = "gpc1-0", "gpc1-1", "gpc1-2", "gpc1-3",
"gpc1-4";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
@@ -396,7 +396,7 @@
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- pcm2_bus: pcm2-bus {
+ pcm2_bus: pcm2-bus-pins {
samsung,pins = "gpc1-0", "gpc1-1", "gpc1-2", "gpc1-3",
"gpc1-4";
samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
@@ -404,371 +404,371 @@
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- spdif_bus: spdif-bus {
+ spdif_bus: spdif-bus-pins {
samsung,pins = "gpc1-0", "gpc1-1";
samsung,pin-function = <EXYNOS_PIN_FUNC_4>;
samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- spi2_bus: spi2-bus {
+ spi2_bus: spi2-bus-pins {
samsung,pins = "gpc1-1", "gpc1-2", "gpc1-3", "gpc1-4";
samsung,pin-function = <EXYNOS_PIN_FUNC_5>;
samsung,pin-pud = <S3C64XX_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- i2c0_bus: i2c0-bus {
+ i2c0_bus: i2c0-bus-pins {
samsung,pins = "gpd1-0", "gpd1-1";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <S3C64XX_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- i2c1_bus: i2c1-bus {
+ i2c1_bus: i2c1-bus-pins {
samsung,pins = "gpd1-2", "gpd1-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <S3C64XX_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- i2c2_bus: i2c2-bus {
+ i2c2_bus: i2c2-bus-pins {
samsung,pins = "gpd1-4", "gpd1-5";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <S3C64XX_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- pwm0_out: pwm0-out {
+ pwm0_out: pwm0-out-pins {
samsung,pins = "gpd0-0";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- pwm1_out: pwm1-out {
+ pwm1_out: pwm1-out-pins {
samsung,pins = "gpd0-1";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- pwm2_out: pwm2-out {
+ pwm2_out: pwm2-out-pins {
samsung,pins = "gpd0-2";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- pwm3_out: pwm3-out {
+ pwm3_out: pwm3-out-pins {
samsung,pins = "gpd0-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- keypad_row0: keypad-row-0 {
+ keypad_row0: keypad-row-0-pins {
samsung,pins = "gph3-0";
samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- keypad_row1: keypad-row-1 {
+ keypad_row1: keypad-row-1-pins {
samsung,pins = "gph3-1";
samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- keypad_row2: keypad-row-2 {
+ keypad_row2: keypad-row-2-pins {
samsung,pins = "gph3-2";
samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- keypad_row3: keypad-row-3 {
+ keypad_row3: keypad-row-3-pins {
samsung,pins = "gph3-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- keypad_row4: keypad-row-4 {
+ keypad_row4: keypad-row-4-pins {
samsung,pins = "gph3-4";
samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- keypad_row5: keypad-row-5 {
+ keypad_row5: keypad-row-5-pins {
samsung,pins = "gph3-5";
samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- keypad_row6: keypad-row-6 {
+ keypad_row6: keypad-row-6-pins {
samsung,pins = "gph3-6";
samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- keypad_row7: keypad-row-7 {
+ keypad_row7: keypad-row-7-pins {
samsung,pins = "gph3-7";
samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- keypad_col0: keypad-col-0 {
+ keypad_col0: keypad-col-0-pins {
samsung,pins = "gph2-0";
samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- keypad_col1: keypad-col-1 {
+ keypad_col1: keypad-col-1-pins {
samsung,pins = "gph2-1";
samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- keypad_col2: keypad-col-2 {
+ keypad_col2: keypad-col-2-pins {
samsung,pins = "gph2-2";
samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- keypad_col3: keypad-col-3 {
+ keypad_col3: keypad-col-3-pins {
samsung,pins = "gph2-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- keypad_col4: keypad-col-4 {
+ keypad_col4: keypad-col-4-pins {
samsung,pins = "gph2-4";
samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- keypad_col5: keypad-col-5 {
+ keypad_col5: keypad-col-5-pins {
samsung,pins = "gph2-5";
samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- keypad_col6: keypad-col-6 {
+ keypad_col6: keypad-col-6-pins {
samsung,pins = "gph2-6";
samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- keypad_col7: keypad-col-7 {
+ keypad_col7: keypad-col-7-pins {
samsung,pins = "gph2-7";
samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- sd0_clk: sd0-clk {
+ sd0_clk: sd0-clk-pins {
samsung,pins = "gpg0-0";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
};
- sd0_cmd: sd0-cmd {
+ sd0_cmd: sd0-cmd-pins {
samsung,pins = "gpg0-1";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
};
- sd0_cd: sd0-cd {
+ sd0_cd: sd0-cd-pins {
samsung,pins = "gpg0-2";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <S3C64XX_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
};
- sd0_bus1: sd0-bus-width1 {
+ sd0_bus1: sd0-bus-width1-pins {
samsung,pins = "gpg0-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <S3C64XX_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
};
- sd0_bus4: sd0-bus-width4 {
+ sd0_bus4: sd0-bus-width4-pins {
samsung,pins = "gpg0-3", "gpg0-4", "gpg0-5", "gpg0-6";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <S3C64XX_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
};
- sd0_bus8: sd0-bus-width8 {
+ sd0_bus8: sd0-bus-width8-pins {
samsung,pins = "gpg1-3", "gpg1-4", "gpg1-5", "gpg1-6";
samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
samsung,pin-pud = <S3C64XX_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
};
- sd1_clk: sd1-clk {
+ sd1_clk: sd1-clk-pins {
samsung,pins = "gpg1-0";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
};
- sd1_cmd: sd1-cmd {
+ sd1_cmd: sd1-cmd-pins {
samsung,pins = "gpg1-1";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
};
- sd1_cd: sd1-cd {
+ sd1_cd: sd1-cd-pins {
samsung,pins = "gpg1-2";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <S3C64XX_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
};
- sd1_bus1: sd1-bus-width1 {
+ sd1_bus1: sd1-bus-width1-pins {
samsung,pins = "gpg1-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <S3C64XX_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
};
- sd1_bus4: sd1-bus-width4 {
+ sd1_bus4: sd1-bus-width4-pins {
samsung,pins = "gpg1-3", "gpg1-4", "gpg1-5", "gpg1-6";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <S3C64XX_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
};
- sd2_clk: sd2-clk {
+ sd2_clk: sd2-clk-pins {
samsung,pins = "gpg2-0";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
};
- sd2_cmd: sd2-cmd {
+ sd2_cmd: sd2-cmd-pins {
samsung,pins = "gpg2-1";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
};
- sd2_cd: sd2-cd {
+ sd2_cd: sd2-cd-pins {
samsung,pins = "gpg2-2";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <S3C64XX_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
};
- sd2_bus1: sd2-bus-width1 {
+ sd2_bus1: sd2-bus-width1-pins {
samsung,pins = "gpg2-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <S3C64XX_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
};
- sd2_bus4: sd2-bus-width4 {
+ sd2_bus4: sd2-bus-width4-pins {
samsung,pins = "gpg2-3", "gpg2-4", "gpg2-5", "gpg2-6";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <S3C64XX_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
};
- sd2_bus8: sd2-bus-width8 {
+ sd2_bus8: sd2-bus-width8-pins {
samsung,pins = "gpg3-3", "gpg3-4", "gpg3-5", "gpg3-6";
samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
samsung,pin-pud = <S3C64XX_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
};
- sd3_clk: sd3-clk {
+ sd3_clk: sd3-clk-pins {
samsung,pins = "gpg3-0";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
};
- sd3_cmd: sd3-cmd {
+ sd3_cmd: sd3-cmd-pins {
samsung,pins = "gpg3-1";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
};
- sd3_cd: sd3-cd {
+ sd3_cd: sd3-cd-pins {
samsung,pins = "gpg3-2";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <S3C64XX_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
};
- sd3_bus1: sd3-bus-width1 {
+ sd3_bus1: sd3-bus-width1-pins {
samsung,pins = "gpg3-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <S3C64XX_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
};
- sd3_bus4: sd3-bus-width4 {
+ sd3_bus4: sd3-bus-width4-pins {
samsung,pins = "gpg3-3", "gpg3-4", "gpg3-5", "gpg3-6";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <S3C64XX_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
};
- eint0: ext-int0 {
+ eint0: ext-int0-pins {
samsung,pins = "gph0-0";
samsung,pin-function = <EXYNOS_PIN_FUNC_F>;
samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- eint8: ext-int8 {
+ eint8: ext-int8-pins {
samsung,pins = "gph1-0";
samsung,pin-function = <EXYNOS_PIN_FUNC_F>;
samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- eint15: ext-int15 {
+ eint15: ext-int15-pins {
samsung,pins = "gph1-7";
samsung,pin-function = <EXYNOS_PIN_FUNC_F>;
samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- eint16: ext-int16 {
+ eint16: ext-int16-pins {
samsung,pins = "gph2-0";
samsung,pin-function = <EXYNOS_PIN_FUNC_F>;
samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- eint31: ext-int31 {
+ eint31: ext-int31-pins {
samsung,pins = "gph3-7";
samsung,pin-function = <EXYNOS_PIN_FUNC_F>;
samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- cam_port_a_io: cam-port-a-io {
+ cam_port_a_io: cam-port-a-io-pins {
samsung,pins = "gpe0-0", "gpe0-1", "gpe0-2", "gpe0-3",
"gpe0-4", "gpe0-5", "gpe0-6", "gpe0-7",
"gpe1-0", "gpe1-1", "gpe1-2", "gpe1-4";
@@ -777,21 +777,21 @@
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- cam_port_a_clk_active: cam-port-a-clk-active {
+ cam_port_a_clk_active: cam-port-a-clk-active-pins {
samsung,pins = "gpe1-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
};
- cam_port_a_clk_idle: cam-port-a-clk-idle {
+ cam_port_a_clk_idle: cam-port-a-clk-idle-pins {
samsung,pins = "gpe1-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
samsung,pin-pud = <S3C64XX_PIN_PULL_DOWN>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- cam_port_b_io: cam-port-b-io {
+ cam_port_b_io: cam-port-b-io-pins {
samsung,pins = "gpj0-0", "gpj0-1", "gpj0-2", "gpj0-3",
"gpj0-4", "gpj0-5", "gpj0-6", "gpj0-7",
"gpj1-0", "gpj1-1", "gpj1-2", "gpj1-4";
@@ -800,42 +800,42 @@
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- cam_port_b_clk_active: cam-port-b-clk-active {
+ cam_port_b_clk_active: cam-port-b-clk-active-pins {
samsung,pins = "gpj1-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
};
- cam_port_b_clk_idle: cam-port-b-clk-idle {
+ cam_port_b_clk_idle: cam-port-b-clk-idle-pins {
samsung,pins = "gpj1-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
samsung,pin-pud = <S3C64XX_PIN_PULL_DOWN>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- lcd_ctrl: lcd-ctrl {
+ lcd_ctrl: lcd-ctrl-pins {
samsung,pins = "gpd0-0", "gpd0-1";
samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- lcd_sync: lcd-sync {
+ lcd_sync: lcd-sync-pins {
samsung,pins = "gpf0-0", "gpf0-1";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- lcd_clk: lcd-clk {
+ lcd_clk: lcd-clk-pins {
samsung,pins = "gpf0-0", "gpf0-1", "gpf0-2", "gpf0-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- lcd_data24: lcd-data-width24 {
+ lcd_data24: lcd-data-width24-pins {
samsung,pins = "gpf0-4", "gpf0-5", "gpf0-6", "gpf0-7",
"gpf1-0", "gpf1-1", "gpf1-2", "gpf1-3",
"gpf1-4", "gpf1-5", "gpf1-6", "gpf1-7",
diff --git a/arch/arm/boot/dts/sam9x60.dtsi b/arch/arm/boot/dts/sam9x60.dtsi
index ec45ced3cde6..998629a3c34f 100644
--- a/arch/arm/boot/dts/sam9x60.dtsi
+++ b/arch/arm/boot/dts/sam9x60.dtsi
@@ -270,7 +270,7 @@
clock-names = "pclk", "gclk";
};
- sha: sha@f002c000 {
+ sha: crypto@f002c000 {
compatible = "atmel,at91sam9g46-sha";
reg = <0xf002c000 0x100>;
interrupts = <41 IRQ_TYPE_LEVEL_HIGH 0>;
@@ -280,7 +280,6 @@
dma-names = "tx";
clocks = <&pmc PMC_TYPE_PERIPHERAL 41>;
clock-names = "sha_clk";
- status = "okay";
};
trng: trng@f0030000 {
@@ -288,10 +287,9 @@
reg = <0xf0030000 0x100>;
interrupts = <38 IRQ_TYPE_LEVEL_HIGH 0>;
clocks = <&pmc PMC_TYPE_PERIPHERAL 38>;
- status = "okay";
};
- aes: aes@f0034000 {
+ aes: crypto@f0034000 {
compatible = "atmel,at91sam9g46-aes";
reg = <0xf0034000 0x100>;
interrupts = <39 IRQ_TYPE_LEVEL_HIGH 0>;
@@ -304,10 +302,9 @@
dma-names = "tx", "rx";
clocks = <&pmc PMC_TYPE_PERIPHERAL 39>;
clock-names = "aes_clk";
- status = "okay";
};
- tdes: tdes@f0038000 {
+ tdes: crypto@f0038000 {
compatible = "atmel,at91sam9g46-tdes";
reg = <0xf0038000 0x100>;
interrupts = <40 IRQ_TYPE_LEVEL_HIGH 0>;
@@ -320,7 +317,6 @@
dma-names = "tx", "rx";
clocks = <&pmc PMC_TYPE_PERIPHERAL 40>;
clock-names = "tdes_clk";
- status = "okay";
};
classd: classd@f003c000 {
diff --git a/arch/arm/boot/dts/sama5d2.dtsi b/arch/arm/boot/dts/sama5d2.dtsi
index 09c741e8ecb8..89c71d419f82 100644
--- a/arch/arm/boot/dts/sama5d2.dtsi
+++ b/arch/arm/boot/dts/sama5d2.dtsi
@@ -306,7 +306,7 @@
status = "disabled";
};
- sha@f0028000 {
+ sha: crypto@f0028000 {
compatible = "atmel,at91sam9g46-sha";
reg = <0xf0028000 0x100>;
interrupts = <12 IRQ_TYPE_LEVEL_HIGH 0>;
@@ -316,10 +316,9 @@
dma-names = "tx";
clocks = <&pmc PMC_TYPE_PERIPHERAL 12>;
clock-names = "sha_clk";
- status = "okay";
};
- aes@f002c000 {
+ aes: crypto@f002c000 {
compatible = "atmel,at91sam9g46-aes";
reg = <0xf002c000 0x100>;
interrupts = <9 IRQ_TYPE_LEVEL_HIGH 0>;
@@ -332,7 +331,6 @@
dma-names = "tx", "rx";
clocks = <&pmc PMC_TYPE_PERIPHERAL 9>;
clock-names = "aes_clk";
- status = "okay";
};
spi0: spi@f8000000 {
@@ -415,7 +413,7 @@
pmecc: ecc-engine@f8014070 {
compatible = "atmel,sama5d2-pmecc";
reg = <0xf8014070 0x490>,
- <0xf8014500 0x100>;
+ <0xf8014500 0x200>;
};
};
@@ -1084,7 +1082,7 @@
#gpio-cells = <2>;
};
- tdes@fc044000 {
+ tdes: crypto@fc044000 {
compatible = "atmel,at91sam9g46-tdes";
reg = <0xfc044000 0x100>;
interrupts = <11 IRQ_TYPE_LEVEL_HIGH 0>;
@@ -1097,7 +1095,6 @@
dma-names = "tx", "rx";
clocks = <&pmc PMC_TYPE_PERIPHERAL 11>;
clock-names = "tdes_clk";
- status = "okay";
};
classd: classd@fc048000 {
diff --git a/arch/arm/boot/dts/sama5d3.dtsi b/arch/arm/boot/dts/sama5d3.dtsi
index d1841bffe3c5..8fa423c52592 100644
--- a/arch/arm/boot/dts/sama5d3.dtsi
+++ b/arch/arm/boot/dts/sama5d3.dtsi
@@ -381,7 +381,7 @@
status = "disabled";
};
- sha@f8034000 {
+ sha: crypto@f8034000 {
compatible = "atmel,at91sam9g46-sha";
reg = <0xf8034000 0x100>;
interrupts = <42 IRQ_TYPE_LEVEL_HIGH 0>;
@@ -391,7 +391,7 @@
clock-names = "sha_clk";
};
- aes@f8038000 {
+ aes: crypto@f8038000 {
compatible = "atmel,at91sam9g46-aes";
reg = <0xf8038000 0x100>;
interrupts = <43 IRQ_TYPE_LEVEL_HIGH 0>;
@@ -402,7 +402,7 @@
clock-names = "aes_clk";
};
- tdes@f803c000 {
+ tdes: crypto@f803c000 {
compatible = "atmel,at91sam9g46-tdes";
reg = <0xf803c000 0x100>;
interrupts = <44 IRQ_TYPE_LEVEL_HIGH 0>;
diff --git a/arch/arm/boot/dts/sama5d4.dtsi b/arch/arm/boot/dts/sama5d4.dtsi
index f6e3e6f57252..7b9242664875 100644
--- a/arch/arm/boot/dts/sama5d4.dtsi
+++ b/arch/arm/boot/dts/sama5d4.dtsi
@@ -673,7 +673,7 @@
status = "disabled";
};
- aes@fc044000 {
+ aes: crypto@fc044000 {
compatible = "atmel,at91sam9g46-aes";
reg = <0xfc044000 0x100>;
interrupts = <12 IRQ_TYPE_LEVEL_HIGH 0>;
@@ -684,10 +684,9 @@
dma-names = "tx", "rx";
clocks = <&pmc PMC_TYPE_PERIPHERAL 12>;
clock-names = "aes_clk";
- status = "okay";
};
- tdes@fc04c000 {
+ tdes: crpyto@fc04c000 {
compatible = "atmel,at91sam9g46-tdes";
reg = <0xfc04c000 0x100>;
interrupts = <14 IRQ_TYPE_LEVEL_HIGH 0>;
@@ -698,10 +697,9 @@
dma-names = "tx", "rx";
clocks = <&pmc PMC_TYPE_PERIPHERAL 14>;
clock-names = "tdes_clk";
- status = "okay";
};
- sha@fc050000 {
+ sha: crypto@fc050000 {
compatible = "atmel,at91sam9g46-sha";
reg = <0xfc050000 0x100>;
interrupts = <15 IRQ_TYPE_LEVEL_HIGH 0>;
@@ -710,7 +708,6 @@
dma-names = "tx";
clocks = <&pmc PMC_TYPE_PERIPHERAL 15>;
clock-names = "sha_clk";
- status = "okay";
};
hsmc: smc@fc05c000 {
diff --git a/arch/arm/boot/dts/sama7g5.dtsi b/arch/arm/boot/dts/sama7g5.dtsi
index eddcfbf4d223..4decd3a91a76 100644
--- a/arch/arm/boot/dts/sama7g5.dtsi
+++ b/arch/arm/boot/dts/sama7g5.dtsi
@@ -30,6 +30,44 @@
device_type = "cpu";
compatible = "arm,cortex-a7";
reg = <0x0>;
+ clocks = <&pmc PMC_TYPE_CORE PMC_CPUPLL>;
+ clock-names = "cpu";
+ operating-points-v2 = <&cpu_opp_table>;
+ };
+ };
+
+ cpu_opp_table: opp-table {
+ compatible = "operating-points-v2";
+
+ opp-90000000 {
+ opp-hz = /bits/ 64 <90000000>;
+ opp-microvolt = <1050000 1050000 1225000>;
+ clock-latency-ns = <320000>;
+ };
+
+ opp-250000000 {
+ opp-hz = /bits/ 64 <250000000>;
+ opp-microvolt = <1050000 1050000 1225000>;
+ clock-latency-ns = <320000>;
+ };
+
+ opp-600000000 {
+ opp-hz = /bits/ 64 <600000000>;
+ opp-microvolt = <1050000 1050000 1225000>;
+ clock-latency-ns = <320000>;
+ opp-suspend;
+ };
+
+ opp-800000000 {
+ opp-hz = /bits/ 64 <800000000>;
+ opp-microvolt = <1150000 1125000 1225000>;
+ clock-latency-ns = <320000>;
+ };
+
+ opp-1000000002 {
+ opp-hz = /bits/ 64 <1000000002>;
+ opp-microvolt = <1250000 1225000 1300000>;
+ clock-latency-ns = <320000>;
};
};
@@ -75,6 +113,45 @@
#size-cells = <1>;
ranges;
+ nfc_sram: sram@600000 {
+ compatible = "mmio-sram";
+ no-memory-wc;
+ reg = <0x00600000 0x2400>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0 0x00600000 0x2400>;
+ };
+
+ nfc_io: nfc-io@10000000 {
+ compatible = "atmel,sama5d3-nfc-io", "syscon";
+ reg = <0x10000000 0x8000000>;
+ };
+
+ ebi: ebi@40000000 {
+ compatible = "atmel,sama5d3-ebi";
+ #address-cells = <2>;
+ #size-cells = <1>;
+ atmel,smc = <&hsmc>;
+ reg = <0x40000000 0x20000000>;
+ ranges = <0x0 0x0 0x40000000 0x8000000
+ 0x1 0x0 0x48000000 0x8000000
+ 0x2 0x0 0x50000000 0x8000000
+ 0x3 0x0 0x58000000 0x8000000>;
+ clocks = <&pmc PMC_TYPE_CORE PMC_MCK1>;
+ status = "disabled";
+
+ nand_controller: nand-controller {
+ compatible = "atmel,sama5d3-nand-controller";
+ atmel,nfc-sram = <&nfc_sram>;
+ atmel,nfc-io = <&nfc_io>;
+ ecc-engine = <&pmecc>;
+ #address-cells = <2>;
+ #size-cells = <1>;
+ ranges;
+ status = "disabled";
+ };
+ };
+
securam: securam@e0000000 {
compatible = "microchip,sama7g5-securam", "atmel,sama5d2-securam", "mmio-sram";
reg = <0xe0000000 0x4000>;
@@ -83,7 +160,6 @@
#size-cells = <1>;
ranges = <0 0xe0000000 0x4000>;
no-memory-wc;
- status = "okay";
};
secumod: secumod@e0004000 {
@@ -181,6 +257,22 @@
clock-names = "t0_clk", "t1_clk", "t2_clk", "slow_clk";
};
+ hsmc: hsmc@e0808000 {
+ compatible = "atmel,sama5d2-smc", "syscon", "simple-mfd";
+ reg = <0xe0808000 0x1000>;
+ interrupts = <GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&pmc PMC_TYPE_PERIPHERAL 21>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ pmecc: ecc-engine@e0808070 {
+ compatible = "atmel,sama5d2-pmecc";
+ reg = <0xe0808070 0x490>,
+ <0xe0808500 0x200>;
+ };
+ };
+
qspi0: spi@e080c000 {
compatible = "microchip,sama7g5-ospi";
reg = <0xe080c000 0x400>, <0x20000000 0x10000000>;
@@ -211,6 +303,102 @@
status = "disabled";
};
+ can0: can@e0828000 {
+ compatible = "bosch,m_can";
+ reg = <0xe0828000 0x100>, <0x100000 0x7800>;
+ reg-names = "m_can", "message_ram";
+ interrupts = <GIC_SPI 61 IRQ_TYPE_LEVEL_HIGH
+ GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "int0", "int1";
+ clocks = <&pmc PMC_TYPE_PERIPHERAL 61>, <&pmc PMC_TYPE_GCK 61>;
+ clock-names = "hclk", "cclk";
+ assigned-clocks = <&pmc PMC_TYPE_GCK 61>;
+ assigned-clock-parents = <&pmc PMC_TYPE_CORE PMC_SYSPLL>;
+ assigned-clock-rates = <40000000>;
+ bosch,mram-cfg = <0x3400 0 0 64 0 0 32 32>;
+ status = "disabled";
+ };
+
+ can1: can@e082c000 {
+ compatible = "bosch,m_can";
+ reg = <0xe082c000 0x100>, <0x100000 0xbc00>;
+ reg-names = "m_can", "message_ram";
+ interrupts = <GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH
+ GIC_SPI 124 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "int0", "int1";
+ clocks = <&pmc PMC_TYPE_PERIPHERAL 62>, <&pmc PMC_TYPE_GCK 62>;
+ clock-names = "hclk", "cclk";
+ assigned-clocks = <&pmc PMC_TYPE_GCK 62>;
+ assigned-clock-parents = <&pmc PMC_TYPE_CORE PMC_SYSPLL>;
+ assigned-clock-rates = <40000000>;
+ bosch,mram-cfg = <0x7800 0 0 64 0 0 32 32>;
+ status = "disabled";
+ };
+
+ can2: can@e0830000 {
+ compatible = "bosch,m_can";
+ reg = <0xe0830000 0x100>, <0x100000 0x10000>;
+ reg-names = "m_can", "message_ram";
+ interrupts = <GIC_SPI 63 IRQ_TYPE_LEVEL_HIGH
+ GIC_SPI 125 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "int0", "int1";
+ clocks = <&pmc PMC_TYPE_PERIPHERAL 63>, <&pmc PMC_TYPE_GCK 63>;
+ clock-names = "hclk", "cclk";
+ assigned-clocks = <&pmc PMC_TYPE_GCK 63>;
+ assigned-clock-parents = <&pmc PMC_TYPE_CORE PMC_SYSPLL>;
+ assigned-clock-rates = <40000000>;
+ bosch,mram-cfg = <0xbc00 0 0 64 0 0 32 32>;
+ status = "disabled";
+ };
+
+ can3: can@e0834000 {
+ compatible = "bosch,m_can";
+ reg = <0xe0834000 0x100>, <0x110000 0x4400>;
+ reg-names = "m_can", "message_ram";
+ interrupts = <GIC_SPI 64 IRQ_TYPE_LEVEL_HIGH
+ GIC_SPI 126 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "int0", "int1";
+ clocks = <&pmc PMC_TYPE_PERIPHERAL 64>, <&pmc PMC_TYPE_GCK 64>;
+ clock-names = "hclk", "cclk";
+ assigned-clocks = <&pmc PMC_TYPE_GCK 64>;
+ assigned-clock-parents = <&pmc PMC_TYPE_CORE PMC_SYSPLL>;
+ assigned-clock-rates = <40000000>;
+ bosch,mram-cfg = <0x0 0 0 64 0 0 32 32>;
+ status = "disabled";
+ };
+
+ can4: can@e0838000 {
+ compatible = "bosch,m_can";
+ reg = <0xe0838000 0x100>, <0x110000 0x8800>;
+ reg-names = "m_can", "message_ram";
+ interrupts = <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH
+ GIC_SPI 127 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "int0", "int1";
+ clocks = <&pmc PMC_TYPE_PERIPHERAL 65>, <&pmc PMC_TYPE_GCK 65>;
+ clock-names = "hclk", "cclk";
+ assigned-clocks = <&pmc PMC_TYPE_GCK 65>;
+ assigned-clock-parents = <&pmc PMC_TYPE_CORE PMC_SYSPLL>;
+ assigned-clock-rates = <40000000>;
+ bosch,mram-cfg = <0x4400 0 0 64 0 0 32 32>;
+ status = "disabled";
+ };
+
+ can5: can@e083c000 {
+ compatible = "bosch,m_can";
+ reg = <0xe083c000 0x100>, <0x110000 0xcc00>;
+ reg-names = "m_can", "message_ram";
+ interrupts = <GIC_SPI 66 IRQ_TYPE_LEVEL_HIGH
+ GIC_SPI 128 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "int0", "int1";
+ clocks = <&pmc PMC_TYPE_PERIPHERAL 66>, <&pmc PMC_TYPE_GCK 66>;
+ clock-names = "hclk", "cclk";
+ assigned-clocks = <&pmc PMC_TYPE_GCK 66>;
+ assigned-clock-parents = <&pmc PMC_TYPE_CORE PMC_SYSPLL>;
+ assigned-clock-rates = <40000000>;
+ bosch,mram-cfg = <0x8800 0 0 64 0 0 32 32>;
+ status = "disabled";
+ };
+
adc: adc@e1000000 {
compatible = "microchip,sama7g5-adc";
reg = <0xe1000000 0x200>;
@@ -322,6 +510,19 @@
status = "disabled";
};
+ eic: interrupt-controller@e1628000 {
+ compatible = "microchip,sama7g5-eic";
+ reg = <0xe1628000 0xec>;
+ interrupt-parent = <&gic>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ interrupts = <GIC_SPI 153 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 154 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&pmc PMC_TYPE_PERIPHERAL 37>;
+ clock-names = "pclk";
+ status = "disabled";
+ };
+
pit64b0: timer@e1800000 {
compatible = "microchip,sama7g5-pit64b", "microchip,sam9x60-pit64b";
reg = <0xe1800000 0x4000>;
@@ -338,6 +539,27 @@
clock-names = "pclk", "gclk";
};
+ aes: crypto@e1810000 {
+ compatible = "atmel,at91sam9g46-aes";
+ reg = <0xe1810000 0x100>;
+ interrupts = <GIC_SPI 27 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&pmc PMC_TYPE_PERIPHERAL 27>;
+ clock-names = "aes_clk";
+ dmas = <&dma0 AT91_XDMAC_DT_PERID(1)>,
+ <&dma0 AT91_XDMAC_DT_PERID(2)>;
+ dma-names = "tx", "rx";
+ };
+
+ sha: crypto@e1814000 {
+ compatible = "atmel,at91sam9g46-sha";
+ reg = <0xe1814000 0x100>;
+ interrupts = <GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&pmc PMC_TYPE_PERIPHERAL 83>;
+ clock-names = "sha_clk";
+ dmas = <&dma0 AT91_XDMAC_DT_PERID(48)>;
+ dma-names = "tx";
+ };
+
flx0: flexcom@e1818000 {
compatible = "atmel,sama5d2-flexcom";
reg = <0xe1818000 0x200>;
@@ -382,8 +604,6 @@
dmas = <&dma0 AT91_XDMAC_DT_PERID(7)>,
<&dma0 AT91_XDMAC_DT_PERID(8)>;
dma-names = "rx", "tx";
- atmel,use-dma-rx;
- atmel,use-dma-tx;
status = "disabled";
};
};
@@ -420,6 +640,17 @@
status = "disabled";
};
+ tdes: crypto@e2014000 {
+ compatible = "atmel,at91sam9g46-tdes";
+ reg = <0xe2014000 0x100>;
+ interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&pmc PMC_TYPE_PERIPHERAL 96>;
+ clock-names = "tdes_clk";
+ dmas = <&dma0 AT91_XDMAC_DT_PERID(54)>,
+ <&dma0 AT91_XDMAC_DT_PERID(53)>;
+ dma-names = "tx", "rx";
+ };
+
flx4: flexcom@e2018000 {
compatible = "atmel,sama5d2-flexcom";
reg = <0xe2018000 0x200>;
@@ -558,8 +789,6 @@
dmas = <&dma0 AT91_XDMAC_DT_PERID(21)>,
<&dma0 AT91_XDMAC_DT_PERID(22)>;
dma-names = "rx", "tx";
- atmel,use-dma-rx;
- atmel,use-dma-tx;
status = "disabled";
};
};
@@ -584,8 +813,6 @@
dmas = <&dma0 AT91_XDMAC_DT_PERID(23)>,
<&dma0 AT91_XDMAC_DT_PERID(24)>;
dma-names = "rx", "tx";
- atmel,use-dma-rx;
- atmel,use-dma-tx;
status = "disabled";
};
};
@@ -618,13 +845,11 @@
uddrc: uddrc@e3800000 {
compatible = "microchip,sama7g5-uddrc";
reg = <0xe3800000 0x4000>;
- status = "okay";
};
ddr3phy: ddr3phy@e3804000 {
compatible = "microchip,sama7g5-ddr3phy";
reg = <0xe3804000 0x1000>;
- status = "okay";
};
gic: interrupt-controller@e8c11000 {
diff --git a/arch/arm/boot/dts/socfpga_arria10_mercury_aa1.dts b/arch/arm/boot/dts/socfpga_arria10_mercury_aa1.dts
index 2a3364b26361..a75c059b6727 100644
--- a/arch/arm/boot/dts/socfpga_arria10_mercury_aa1.dts
+++ b/arch/arm/boot/dts/socfpga_arria10_mercury_aa1.dts
@@ -6,7 +6,7 @@
/ {
model = "Enclustra Mercury AA1";
- compatible = "altr,socfpga-arria10", "altr,socfpga";
+ compatible = "enclustra,mercury-aa1", "altr,socfpga-arria10", "altr,socfpga";
aliases {
ethernet0 = &gmac0;
diff --git a/arch/arm/boot/dts/socfpga_arria10_socdk.dtsi b/arch/arm/boot/dts/socfpga_arria10_socdk.dtsi
index 7edebe20e859..ec7365444a3b 100644
--- a/arch/arm/boot/dts/socfpga_arria10_socdk.dtsi
+++ b/arch/arm/boot/dts/socfpga_arria10_socdk.dtsi
@@ -6,7 +6,7 @@
/ {
model = "Altera SOCFPGA Arria 10";
- compatible = "altr,socfpga-arria10", "altr,socfpga";
+ compatible = "altr,socfpga-arria10-socdk", "altr,socfpga-arria10", "altr,socfpga";
aliases {
ethernet0 = &gmac0;
diff --git a/arch/arm/boot/dts/socfpga_arria5_socdk.dts b/arch/arm/boot/dts/socfpga_arria5_socdk.dts
index 1b02d46496a8..7f5458d8fccc 100644
--- a/arch/arm/boot/dts/socfpga_arria5_socdk.dts
+++ b/arch/arm/boot/dts/socfpga_arria5_socdk.dts
@@ -7,7 +7,7 @@
/ {
model = "Altera SOCFPGA Arria V SoC Development Kit";
- compatible = "altr,socfpga-arria5", "altr,socfpga";
+ compatible = "altr,socfpga-arria5-socdk", "altr,socfpga-arria5", "altr,socfpga";
chosen {
bootargs = "earlyprintk";
@@ -50,7 +50,7 @@
};
};
- regulator_3_3v: 3-3-v-regulator {
+ regulator_3_3v: regulator {
compatible = "regulator-fixed";
regulator-name = "3.3V";
regulator-min-microvolt = <3300000>;
diff --git a/arch/arm/boot/dts/socfpga_cyclone5_chameleon96.dts b/arch/arm/boot/dts/socfpga_cyclone5_chameleon96.dts
index f6561766d83f..76262f1e5e03 100644
--- a/arch/arm/boot/dts/socfpga_cyclone5_chameleon96.dts
+++ b/arch/arm/boot/dts/socfpga_cyclone5_chameleon96.dts
@@ -24,7 +24,7 @@
reg = <0x0 0x20000000>; /* 512MB */
};
- regulator_3_3v: 3-3-v-regulator {
+ regulator_3_3v: regulator {
compatible = "regulator-fixed";
regulator-name = "3.3V";
regulator-min-microvolt = <3300000>;
diff --git a/arch/arm/boot/dts/socfpga_cyclone5_de0_nano_soc.dts b/arch/arm/boot/dts/socfpga_cyclone5_de0_nano_soc.dts
index 67076e1b1c7f..c8f051fb2bf6 100644
--- a/arch/arm/boot/dts/socfpga_cyclone5_de0_nano_soc.dts
+++ b/arch/arm/boot/dts/socfpga_cyclone5_de0_nano_soc.dts
@@ -24,7 +24,7 @@
ethernet0 = &gmac1;
};
- regulator_3_3v: 3-3-v-regulator {
+ regulator_3_3v: regulator {
compatible = "regulator-fixed";
regulator-name = "3.3V";
regulator-min-microvolt = <3300000>;
diff --git a/arch/arm/boot/dts/socfpga_cyclone5_socdk.dts b/arch/arm/boot/dts/socfpga_cyclone5_socdk.dts
index 51bb436784e2..253ef139181d 100644
--- a/arch/arm/boot/dts/socfpga_cyclone5_socdk.dts
+++ b/arch/arm/boot/dts/socfpga_cyclone5_socdk.dts
@@ -50,7 +50,7 @@
};
};
- regulator_3_3v: 3-3-v-regulator {
+ regulator_3_3v: regulator {
compatible = "regulator-fixed";
regulator-name = "3.3V";
regulator-min-microvolt = <3300000>;
diff --git a/arch/arm/boot/dts/socfpga_cyclone5_sockit.dts b/arch/arm/boot/dts/socfpga_cyclone5_sockit.dts
index cae9ddd5ed38..3dd99c7c95e0 100644
--- a/arch/arm/boot/dts/socfpga_cyclone5_sockit.dts
+++ b/arch/arm/boot/dts/socfpga_cyclone5_sockit.dts
@@ -111,7 +111,7 @@
};
};
- regulator_3_3v: vcc3p3-regulator {
+ regulator_3_3v: regulator {
compatible = "regulator-fixed";
regulator-name = "VCC3P3";
regulator-min-microvolt = <3300000>;
diff --git a/arch/arm/boot/dts/socfpga_cyclone5_sodia.dts b/arch/arm/boot/dts/socfpga_cyclone5_sodia.dts
index 3f7aa7bf0863..b0003f350e65 100644
--- a/arch/arm/boot/dts/socfpga_cyclone5_sodia.dts
+++ b/arch/arm/boot/dts/socfpga_cyclone5_sodia.dts
@@ -26,7 +26,7 @@
ethernet0 = &gmac1;
};
- regulator_3_3v: 3-3-v-regulator {
+ regulator_3_3v: regulator {
compatible = "regulator-fixed";
regulator-name = "3.3V";
regulator-min-microvolt = <3300000>;
diff --git a/arch/arm/boot/dts/spear320-hmi.dts b/arch/arm/boot/dts/spear320-hmi.dts
index 367ba48aac3e..b587e4ec11e5 100644
--- a/arch/arm/boot/dts/spear320-hmi.dts
+++ b/arch/arm/boot/dts/spear320-hmi.dts
@@ -235,7 +235,6 @@
#address-cells = <1>;
#size-cells = <0>;
reg = <0x41>;
- irq-over-gpio;
irq-gpios = <&gpiopinctrl 29 0x4>;
id = <0>;
blocks = <0x5>;
diff --git a/arch/arm/boot/dts/ste-ab8500.dtsi b/arch/arm/boot/dts/ste-ab8500.dtsi
index 2cf19386a525..35137c6e52ee 100644
--- a/arch/arm/boot/dts/ste-ab8500.dtsi
+++ b/arch/arm/boot/dts/ste-ab8500.dtsi
@@ -28,26 +28,28 @@
interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>;
interrupt-controller;
#interrupt-cells = <2>;
+ #address-cells = <1>;
+ #size-cells = <0>;
ab8500_clock: clock-controller {
compatible = "stericsson,ab8500-clk";
#clock-cells = <1>;
};
- ab8500_gpio: ab8500-gpiocontroller {
+ ab8500_gpio: gpio {
compatible = "stericsson,ab8500-gpio";
gpio-controller;
#gpio-cells = <2>;
};
- ab8500-rtc {
+ rtc {
compatible = "stericsson,ab8500-rtc";
interrupts = <17 IRQ_TYPE_LEVEL_HIGH>,
<18 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "60S", "ALARM";
};
- gpadc: ab8500-gpadc {
+ gpadc: adc {
compatible = "stericsson,ab8500-gpadc";
interrupts = <32 IRQ_TYPE_LEVEL_HIGH>,
<39 IRQ_TYPE_LEVEL_HIGH>;
@@ -120,13 +122,10 @@
};
};
- ab8500_temp {
+ thermal {
compatible = "stericsson,abx500-temp";
interrupts = <3 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "ABX500_TEMP_WARM";
- io-channels = <&gpadc 0x06>,
- <&gpadc 0x07>;
- io-channel-names = "aux1", "aux2";
};
ab8500_fg {
@@ -212,7 +211,7 @@
monitored-battery = <&battery>;
};
- ab8500_usb: ab8500_usb {
+ ab8500_usb: phy {
compatible = "stericsson,ab8500-usb";
interrupts = <90 IRQ_TYPE_LEVEL_HIGH>,
<96 IRQ_TYPE_LEVEL_HIGH>,
@@ -236,7 +235,7 @@
#phy-cells = <0>;
};
- ab8500-ponkey {
+ key {
compatible = "stericsson,ab8500-poweron-key";
interrupts = <6 IRQ_TYPE_LEVEL_HIGH>,
<7 IRQ_TYPE_LEVEL_HIGH>;
@@ -247,29 +246,31 @@
compatible = "stericsson,ab8500-sysctrl";
};
- ab8500-pwm-1 {
+ pwm@1 {
compatible = "stericsson,ab8500-pwm";
+ reg = <1>;
clocks = <&ab8500_clock AB8500_SYSCLK_INT>;
clock-names = "intclk";
+ #pwm-cells = <1>;
};
- ab8500-pwm-2 {
+ pwm@2 {
compatible = "stericsson,ab8500-pwm";
+ reg = <2>;
clocks = <&ab8500_clock AB8500_SYSCLK_INT>;
clock-names = "intclk";
+ #pwm-cells = <1>;
};
- ab8500-pwm-3 {
+ pwm@3 {
compatible = "stericsson,ab8500-pwm";
+ reg = <3>;
clocks = <&ab8500_clock AB8500_SYSCLK_INT>;
clock-names = "intclk";
+ #pwm-cells = <1>;
};
- ab8500-debugfs {
- compatible = "stericsson,ab8500-debug";
- };
-
- codec: ab8500-codec {
+ codec: codec {
compatible = "stericsson,ab8500-codec";
V-AUD-supply = <&ab8500_ldo_audio_reg>;
@@ -283,7 +284,7 @@
stericsson,earpeice-cmv = <950>; /* Units in mV. */
};
- ext_regulators: ab8500-ext-regulators {
+ ext_regulators: regulator-external {
compatible = "stericsson,ab8500-ext-regulator";
ab8500_ext1_reg: ab8500_ext1 {
@@ -307,7 +308,7 @@
};
};
- ab8500-regulators {
+ regulator {
compatible = "stericsson,ab8500-regulator";
vin-supply = <&ab8500_ext3_reg>;
diff --git a/arch/arm/boot/dts/ste-ab8505.dtsi b/arch/arm/boot/dts/ste-ab8505.dtsi
index e98335e9d1cb..131c82508e82 100644
--- a/arch/arm/boot/dts/ste-ab8505.dtsi
+++ b/arch/arm/boot/dts/ste-ab8505.dtsi
@@ -25,26 +25,28 @@
interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>;
interrupt-controller;
#interrupt-cells = <2>;
+ #address-cells = <1>;
+ #size-cells = <0>;
ab8500_clock: clock-controller {
compatible = "stericsson,ab8500-clk";
#clock-cells = <1>;
};
- ab8505_gpio: ab8505-gpiocontroller {
+ ab8505_gpio: gpio {
compatible = "stericsson,ab8505-gpio";
gpio-controller;
#gpio-cells = <2>;
};
- ab8500-rtc {
+ rtc {
compatible = "stericsson,ab8500-rtc";
interrupts = <17 IRQ_TYPE_LEVEL_HIGH>,
<18 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "60S", "ALARM";
};
- gpadc: ab8500-gpadc {
+ gpadc: adc {
compatible = "stericsson,ab8500-gpadc";
interrupts = <39 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "SW_CONV_END";
@@ -92,8 +94,13 @@
};
};
+ thermal {
+ compatible = "stericsson,abx500-temp";
+ interrupts = <3 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "ABX500_TEMP_WARM";
+ };
+
ab8500_fg {
- status = "disabled";
compatible = "stericsson,ab8500-fg";
interrupts = <24 IRQ_TYPE_LEVEL_HIGH>,
<8 IRQ_TYPE_LEVEL_HIGH>,
@@ -111,7 +118,6 @@
};
ab8500_btemp {
- status = "disabled";
compatible = "stericsson,ab8500-btemp";
interrupts = <20 IRQ_TYPE_LEVEL_HIGH>,
<80 IRQ_TYPE_LEVEL_HIGH>,
@@ -131,7 +137,6 @@
};
ab8500_charger {
- status = "disabled";
compatible = "stericsson,ab8500-charger";
interrupts = <10 IRQ_TYPE_LEVEL_HIGH>,
<11 IRQ_TYPE_LEVEL_HIGH>,
@@ -170,12 +175,11 @@
};
ab8500_chargalg {
- status = "disabled";
compatible = "stericsson,ab8500-chargalg";
monitored-battery = <&battery>;
};
- ab8500_usb: ab8500_usb {
+ ab8500_usb: phy {
compatible = "stericsson,ab8500-usb";
interrupts = <90 IRQ_TYPE_LEVEL_HIGH>,
<96 IRQ_TYPE_LEVEL_HIGH>,
@@ -199,7 +203,7 @@
#phy-cells = <0>;
};
- ab8500-ponkey {
+ key {
compatible = "stericsson,ab8500-poweron-key";
interrupts = <6 IRQ_TYPE_LEVEL_HIGH>,
<7 IRQ_TYPE_LEVEL_HIGH>;
@@ -210,17 +214,15 @@
compatible = "stericsson,ab8500-sysctrl";
};
- ab8500-pwm {
+ pwm@1 {
compatible = "stericsson,ab8500-pwm";
+ reg = <1>;
clocks = <&ab8500_clock AB8500_SYSCLK_INT>;
clock-names = "intclk";
+ #pwm-cells = <1>;
};
- ab8500-debugfs {
- compatible = "stericsson,ab8500-debug";
- };
-
- codec: ab8500-codec {
+ codec: codec {
compatible = "stericsson,ab8500-codec";
V-AUD-supply = <&ab8500_ldo_audio_reg>;
@@ -233,7 +235,7 @@
stericsson,earpeice-cmv = <950>; /* Units in mV. */
};
- ab8505-regulators {
+ regulator {
compatible = "stericsson,ab8505-regulator";
ab8500_ldo_aux1_reg: ab8500_ldo_aux1 {
diff --git a/arch/arm/boot/dts/ste-href-ab8500.dtsi b/arch/arm/boot/dts/ste-href-ab8500.dtsi
index 3ccb7b5c7162..9fa024900d53 100644
--- a/arch/arm/boot/dts/ste-href-ab8500.dtsi
+++ b/arch/arm/boot/dts/ste-href-ab8500.dtsi
@@ -9,7 +9,7 @@
soc {
prcmu@80157000 {
ab8500 {
- ab8500-gpiocontroller {
+ gpio {
/* Hog a few default settings */
pinctrl-names = "default";
pinctrl-0 = <&gpio2_default_mode>,
diff --git a/arch/arm/boot/dts/ste-href.dtsi b/arch/arm/boot/dts/ste-href.dtsi
index 718752a0248e..fbaa0ce46427 100644
--- a/arch/arm/boot/dts/ste-href.dtsi
+++ b/arch/arm/boot/dts/ste-href.dtsi
@@ -16,7 +16,24 @@
battery: battery {
compatible = "simple-battery";
battery-type = "lithium-ion-polymer";
- thermistor-on-batctrl;
+ };
+
+ thermal-zones {
+ battery-thermal {
+ /* This zone will be polled by the battery temperature code */
+ polling-delay = <0>;
+ polling-delay-passive = <0>;
+ thermal-sensors = <&bat_therm>;
+ };
+ };
+
+ bat_therm: thermistor {
+ compatible = "murata,ncp18wb473";
+ io-channels = <&gpadc 0x02>; /* BatTemp */
+ pullup-uv = <1800000>;
+ pullup-ohm = <230000>;
+ pulldown-ohm = <0>;
+ #thermal-sensor-cells = <0>;
};
soc {
@@ -219,16 +236,16 @@
prcmu@80157000 {
ab8500 {
- ab8500-gpiocontroller {
+ gpio {
};
- ab8500_usb {
+ phy {
pinctrl-names = "default", "sleep";
pinctrl-0 = <&usb_a_1_default>;
pinctrl-1 = <&usb_a_1_sleep>;
};
- ab8500-regulators {
+ regulator {
ab8500_ldo_aux1_reg: ab8500_ldo_aux1 {
regulator-name = "V-DISPLAY";
};
diff --git a/arch/arm/boot/dts/ste-snowball.dts b/arch/arm/boot/dts/ste-snowball.dts
index fb719c8a8eb2..1c9094f24893 100644
--- a/arch/arm/boot/dts/ste-snowball.dts
+++ b/arch/arm/boot/dts/ste-snowball.dts
@@ -20,7 +20,24 @@
battery: battery {
compatible = "simple-battery";
battery-type = "lithium-ion-polymer";
- thermistor-on-batctrl;
+ };
+
+ thermal-zones {
+ battery-thermal {
+ /* This zone will be polled by the battery temperature code */
+ polling-delay = <0>;
+ polling-delay-passive = <0>;
+ thermal-sensors = <&bat_therm>;
+ };
+ };
+
+ bat_therm: thermistor {
+ compatible = "murata,ncp18wb473";
+ io-channels = <&gpadc 0x02>; /* BatTemp */
+ pullup-uv = <1800000>;
+ pullup-ohm = <230000>;
+ pulldown-ohm = <0>;
+ #thermal-sensor-cells = <0>;
};
en_3v3_reg: en_3v3 {
@@ -384,7 +401,7 @@
prcmu@80157000 {
ab8500 {
- ab8500-gpiocontroller {
+ gpio {
/*
* AB8500 GPIOs are numbered starting from 1, so the first
* index 0 is what in the datasheet is called "GPIO1", and
@@ -406,13 +423,13 @@
"PM_GPIO42"; /* AB8500 GPIO42 */
};
- ab8500_usb {
+ phy {
pinctrl-names = "default", "sleep";
pinctrl-0 = <&usb_a_1_default>;
pinctrl-1 = <&usb_a_1_sleep>;
};
- ext_regulators: ab8500-ext-regulators {
+ ext_regulators: regulator-external {
ab8500_ext1_reg: ab8500_ext1 {
regulator-name = "ab8500-ext-supply1";
};
@@ -426,7 +443,7 @@
};
};
- ab8500-regulators {
+ regulator {
ab8500_ldo_aux1_reg: ab8500_ldo_aux1 {
regulator-name = "V-DISPLAY";
};
diff --git a/arch/arm/boot/dts/ste-ux500-samsung-codina.dts b/arch/arm/boot/dts/ste-ux500-samsung-codina.dts
index fbd60065542d..1c1725d31c7c 100644
--- a/arch/arm/boot/dts/ste-ux500-samsung-codina.dts
+++ b/arch/arm/boot/dts/ste-ux500-samsung-codina.dts
@@ -47,6 +47,24 @@
compatible = "samsung,eb425161lu";
};
+ thermal-zones {
+ battery-thermal {
+ /* This zone will be polled by the battery temperature code */
+ polling-delay = <0>;
+ polling-delay-passive = <0>;
+ thermal-sensors = <&bat_therm>;
+ };
+ };
+
+ bat_therm: thermistor {
+ compatible = "samsung,1404-001221";
+ io-channels = <&gpadc 0x02>; /* BatTemp */
+ pullup-uv = <1800000>;
+ pullup-ohm = <230000>;
+ pulldown-ohm = <0>;
+ #thermal-sensor-cells = <0>;
+ };
+
/* TI TXS0206 level translator for 2.9 V */
sd_level_translator: regulator-gpio {
compatible = "regulator-fixed";
@@ -459,13 +477,13 @@
prcmu@80157000 {
ab8500 {
- ab8500_usb {
+ phy {
pinctrl-names = "default", "sleep";
pinctrl-0 = <&usb_a_1_default>;
pinctrl-1 = <&usb_a_1_sleep>;
};
- ab8500-regulators {
+ regulator {
ab8500_ldo_aux1 {
/* Used for VDD for sensors */
regulator-name = "V-SENSORS-VDD";
diff --git a/arch/arm/boot/dts/ste-ux500-samsung-gavini.dts b/arch/arm/boot/dts/ste-ux500-samsung-gavini.dts
index 1c0e5cfeddac..fd170974765f 100644
--- a/arch/arm/boot/dts/ste-ux500-samsung-gavini.dts
+++ b/arch/arm/boot/dts/ste-ux500-samsung-gavini.dts
@@ -24,6 +24,24 @@
compatible = "samsung,eb585157lu";
};
+ thermal-zones {
+ battery-thermal {
+ /* This zone will be polled by the battery temperature code */
+ polling-delay = <0>;
+ polling-delay-passive = <0>;
+ thermal-sensors = <&bat_therm>;
+ };
+ };
+
+ bat_therm: thermistor {
+ compatible = "samsung,1404-001221";
+ io-channels = <&gpadc 0x02>; /* BatTemp */
+ pullup-uv = <1800000>;
+ pullup-ohm = <230000>;
+ pulldown-ohm = <0>;
+ #thermal-sensor-cells = <0>;
+ };
+
/* TI TXS0206 level translator for 2.9 V */
sd_level_translator: regulator-gpio {
compatible = "regulator-fixed";
@@ -432,13 +450,13 @@
prcmu@80157000 {
ab8500 {
- ab8500_usb {
+ phy {
pinctrl-names = "default", "sleep";
pinctrl-0 = <&usb_a_1_default>;
pinctrl-1 = <&usb_a_1_sleep>;
};
- ab8500-regulators {
+ regulator {
ab8500_ldo_aux1 {
/* Used for VDD for sensors */
regulator-name = "V-SENSORS-VDD";
diff --git a/arch/arm/boot/dts/ste-ux500-samsung-golden.dts b/arch/arm/boot/dts/ste-ux500-samsung-golden.dts
index fc4c5166d85b..290ab59e863d 100644
--- a/arch/arm/boot/dts/ste-ux500-samsung-golden.dts
+++ b/arch/arm/boot/dts/ste-ux500-samsung-golden.dts
@@ -29,6 +29,24 @@
compatible = "samsung,eb-l1m7flu";
};
+ thermal-zones {
+ battery-thermal {
+ /* This zone will be polled by the battery temperature code */
+ polling-delay = <0>;
+ polling-delay-passive = <0>;
+ thermal-sensors = <&bat_therm>;
+ };
+ };
+
+ bat_therm: thermistor {
+ compatible = "samsung,1404-001221";
+ io-channels = <&gpadc 0x02>; /* BatTemp */
+ pullup-uv = <1800000>;
+ pullup-ohm = <230000>;
+ pulldown-ohm = <0>;
+ #thermal-sensor-cells = <0>;
+ };
+
i2c-gpio-0 {
compatible = "i2c-gpio";
sda-gpios = <&gpio2 14 (GPIO_ACTIVE_HIGH|GPIO_OPEN_DRAIN)>;
@@ -280,13 +298,13 @@
prcmu@80157000 {
ab8505 {
- ab8500_usb {
+ phy {
pinctrl-names = "default", "sleep";
pinctrl-0 = <&usb_a_1_default>;
pinctrl-1 = <&usb_a_1_sleep>;
};
- ab8505-regulators {
+ regulator {
ab8500_ldo_aux1 {
regulator-name = "sensor_3v";
regulator-min-microvolt = <3000000>;
diff --git a/arch/arm/boot/dts/ste-ux500-samsung-janice.dts b/arch/arm/boot/dts/ste-ux500-samsung-janice.dts
index 5ddcbc1a855d..42762bfcd878 100644
--- a/arch/arm/boot/dts/ste-ux500-samsung-janice.dts
+++ b/arch/arm/boot/dts/ste-ux500-samsung-janice.dts
@@ -24,6 +24,24 @@
compatible = "samsung,eb535151vu";
};
+ thermal-zones {
+ battery-thermal {
+ /* This zone will be polled by the battery temperature code */
+ polling-delay = <0>;
+ polling-delay-passive = <0>;
+ thermal-sensors = <&bat_therm>;
+ };
+ };
+
+ bat_therm: thermistor {
+ compatible = "samsung,1404-001221";
+ io-channels = <&gpadc 0x02>; /* BatTemp */
+ pullup-uv = <1800000>;
+ pullup-ohm = <230000>;
+ pulldown-ohm = <0>;
+ #thermal-sensor-cells = <0>;
+ };
+
/* External LDO for eMMC LDO VMEM_3V3 controlled by GPIO6 */
ldo_3v3_reg: regulator-gpio-ldo-3v3 {
compatible = "regulator-fixed";
@@ -480,13 +498,13 @@
prcmu@80157000 {
ab8500 {
- ab8500_usb {
+ phy {
pinctrl-names = "default", "sleep";
pinctrl-0 = <&usb_a_1_default>;
pinctrl-1 = <&usb_a_1_sleep>;
};
- ab8500-regulators {
+ regulator {
ab8500_ldo_aux1 {
/* Used for VDD for sensors */
regulator-name = "V-SENSORS-VDD";
@@ -594,7 +612,7 @@
reg = <0x08>;
mount-matrix = "0", "1", "0",
"-1", "0", "0",
- "0", "0", "-1";
+ "0", "0", "1";
vddio-supply = <&ab8500_ldo_aux2_reg>; // 1.8V
vdd-supply = <&ab8500_ldo_aux1_reg>; // 3V
};
diff --git a/arch/arm/boot/dts/ste-ux500-samsung-kyle.dts b/arch/arm/boot/dts/ste-ux500-samsung-kyle.dts
index 9ec3f85b1a18..2a5bf54137ce 100644
--- a/arch/arm/boot/dts/ste-ux500-samsung-kyle.dts
+++ b/arch/arm/boot/dts/ste-ux500-samsung-kyle.dts
@@ -28,6 +28,24 @@
compatible = "samsung,eb425161la";
};
+ thermal-zones {
+ battery-thermal {
+ /* This zone will be polled by the battery temperature code */
+ polling-delay = <0>;
+ polling-delay-passive = <0>;
+ thermal-sensors = <&bat_therm>;
+ };
+ };
+
+ bat_therm: thermistor {
+ compatible = "samsung,1404-001221";
+ io-channels = <&gpadc 0x02>; /* BatTemp */
+ pullup-uv = <1800000>;
+ pullup-ohm = <230000>;
+ pulldown-ohm = <0>;
+ #thermal-sensor-cells = <0>;
+ };
+
/* TI TXS0206 level translator for 2.9 V */
sd_level_translator: regulator-gpio {
compatible = "regulator-fixed";
@@ -301,13 +319,13 @@
prcmu@80157000 {
ab8505 {
- ab8500_usb {
+ phy {
pinctrl-names = "default", "sleep";
pinctrl-0 = <&usb_a_1_default>;
pinctrl-1 = <&usb_a_1_sleep>;
};
- ab8505-regulators {
+ regulator {
ab8500_ldo_aux1 {
/* Used for VDD for sensors */
regulator-name = "AUX1";
diff --git a/arch/arm/boot/dts/ste-ux500-samsung-skomer.dts b/arch/arm/boot/dts/ste-ux500-samsung-skomer.dts
index 580ca497f312..dcb03ce7cbd4 100644
--- a/arch/arm/boot/dts/ste-ux500-samsung-skomer.dts
+++ b/arch/arm/boot/dts/ste-ux500-samsung-skomer.dts
@@ -24,6 +24,24 @@
compatible = "samsung,eb485159lu";
};
+ thermal-zones {
+ battery-thermal {
+ /* This zone will be polled by the battery temperature code */
+ polling-delay = <0>;
+ polling-delay-passive = <0>;
+ thermal-sensors = <&bat_therm>;
+ };
+ };
+
+ bat_therm: thermistor {
+ compatible = "samsung,1404-001221";
+ io-channels = <&gpadc 0x02>; /* BatTemp */
+ pullup-uv = <1800000>;
+ pullup-ohm = <230000>;
+ pulldown-ohm = <0>;
+ #thermal-sensor-cells = <0>;
+ };
+
/* TI TXS0206 level translator for 2.9 V */
sd_level_translator: regulator-gpio {
compatible = "regulator-fixed";
@@ -185,10 +203,6 @@
cap-sd-highspeed;
cap-mmc-highspeed;
/* All direction control is used */
- st,sig-dir-cmd;
- st,sig-dir-dat0;
- st,sig-dir-dat2;
- st,sig-dir-dat31;
st,sig-pin-fbclk;
full-pwr-cycle;
vmmc-supply = <&ab8500_ldo_aux3_reg>;
@@ -285,13 +299,13 @@
prcmu@80157000 {
ab8505 {
- ab8500_usb {
+ phy {
pinctrl-names = "default", "sleep";
pinctrl-0 = <&usb_a_1_default>;
pinctrl-1 = <&usb_a_1_sleep>;
};
- ab8505-regulators {
+ regulator {
ab8500_ldo_aux1 {
/* Used for VDD for sensors */
regulator-name = "AUX1";
diff --git a/arch/arm/boot/dts/stih407-clock.dtsi b/arch/arm/boot/dts/stih407-clock.dtsi
index 9cce9541e26b..350bcfcf498b 100644
--- a/arch/arm/boot/dts/stih407-clock.dtsi
+++ b/arch/arm/boot/dts/stih407-clock.dtsi
@@ -29,7 +29,7 @@
*/
clockgen-a9@92b0000 {
compatible = "st,clkgen-c32";
- reg = <0x92b0000 0xffff>;
+ reg = <0x92b0000 0x10000>;
clockgen_a9_pll: clockgen-a9-pll {
#clock-cells = <1>;
@@ -37,32 +37,27 @@
clocks = <&clk_sysin>;
};
- };
- /*
- * ARM CPU related clocks.
- */
- clk_m_a9: clk-m-a9@92b0000 {
- #clock-cells = <0>;
- compatible = "st,stih407-clkgen-a9-mux";
- reg = <0x92b0000 0x10000>;
-
- clocks = <&clockgen_a9_pll 0>,
- <&clockgen_a9_pll 0>,
- <&clk_s_c0_flexgen 13>,
- <&clk_m_a9_ext2f_div2>;
+ clk_m_a9: clk-m-a9 {
+ #clock-cells = <0>;
+ compatible = "st,stih407-clkgen-a9-mux";
+ clocks = <&clockgen_a9_pll 0>,
+ <&clockgen_a9_pll 0>,
+ <&clk_s_c0_flexgen 13>,
+ <&clk_m_a9_ext2f_div2>;
- /*
- * ARM Peripheral clock for timers
- */
- arm_periph_clk: clk-m-a9-periphs {
- #clock-cells = <0>;
- compatible = "fixed-factor-clock";
+ /*
+ * ARM Peripheral clock for timers
+ */
+ arm_periph_clk: clk-m-a9-periphs {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
- clocks = <&clk_m_a9>;
- clock-div = <2>;
- clock-mult = <1>;
+ clocks = <&clk_m_a9>;
+ clock-div = <2>;
+ clock-mult = <1>;
+ };
};
};
@@ -87,14 +82,6 @@
};
};
- clk_s_c0_quadfs: clk-s-c0-quadfs@9103000 {
- #clock-cells = <1>;
- compatible = "st,quadfs-pll";
- reg = <0x9103000 0x1000>;
-
- clocks = <&clk_sysin>;
- };
-
clk_s_c0: clockgen-c@9103000 {
compatible = "st,clkgen-c32";
reg = <0x9103000 0x1000>;
@@ -113,6 +100,13 @@
clocks = <&clk_sysin>;
};
+ clk_s_c0_quadfs: clk-s-c0-quadfs {
+ #clock-cells = <1>;
+ compatible = "st,quadfs-pll";
+
+ clocks = <&clk_sysin>;
+ };
+
clk_s_c0_flexgen: clk-s-c0-flexgen {
#clock-cells = <1>;
compatible = "st,flexgen", "st,flexgen-stih407-c0";
@@ -142,18 +136,17 @@
};
};
- clk_s_d0_quadfs: clk-s-d0-quadfs@9104000 {
- #clock-cells = <1>;
- compatible = "st,quadfs-d0";
- reg = <0x9104000 0x1000>;
-
- clocks = <&clk_sysin>;
- };
-
clockgen-d0@9104000 {
compatible = "st,clkgen-c32";
reg = <0x9104000 0x1000>;
+ clk_s_d0_quadfs: clk-s-d0-quadfs {
+ #clock-cells = <1>;
+ compatible = "st,quadfs-d0";
+
+ clocks = <&clk_sysin>;
+ };
+
clk_s_d0_flexgen: clk-s-d0-flexgen {
#clock-cells = <1>;
compatible = "st,flexgen", "st,flexgen-stih407-d0";
@@ -166,18 +159,17 @@
};
};
- clk_s_d2_quadfs: clk-s-d2-quadfs@9106000 {
- #clock-cells = <1>;
- compatible = "st,quadfs-d2";
- reg = <0x9106000 0x1000>;
-
- clocks = <&clk_sysin>;
- };
-
clockgen-d2@9106000 {
compatible = "st,clkgen-c32";
reg = <0x9106000 0x1000>;
+ clk_s_d2_quadfs: clk-s-d2-quadfs {
+ #clock-cells = <1>;
+ compatible = "st,quadfs-d2";
+
+ clocks = <&clk_sysin>;
+ };
+
clk_s_d2_flexgen: clk-s-d2-flexgen {
#clock-cells = <1>;
compatible = "st,flexgen", "st,flexgen-stih407-d2";
@@ -192,18 +184,17 @@
};
};
- clk_s_d3_quadfs: clk-s-d3-quadfs@9107000 {
- #clock-cells = <1>;
- compatible = "st,quadfs-d3";
- reg = <0x9107000 0x1000>;
-
- clocks = <&clk_sysin>;
- };
-
clockgen-d3@9107000 {
compatible = "st,clkgen-c32";
reg = <0x9107000 0x1000>;
+ clk_s_d3_quadfs: clk-s-d3-quadfs {
+ #clock-cells = <1>;
+ compatible = "st,quadfs-d3";
+
+ clocks = <&clk_sysin>;
+ };
+
clk_s_d3_flexgen: clk-s-d3-flexgen {
#clock-cells = <1>;
compatible = "st,flexgen", "st,flexgen-stih407-d3";
diff --git a/arch/arm/boot/dts/stih407-family.dtsi b/arch/arm/boot/dts/stih407-family.dtsi
index 21f3347a91d6..1713f7878117 100644
--- a/arch/arm/boot/dts/stih407-family.dtsi
+++ b/arch/arm/boot/dts/stih407-family.dtsi
@@ -115,37 +115,140 @@
status = "okay";
};
- soc {
- #address-cells = <1>;
- #size-cells = <1>;
- interrupt-parent = <&intc>;
+ restart: restart-controller {
+ compatible = "st,stih407-restart";
+ st,syscfg = <&syscfg_sbc_reg>;
+ status = "okay";
+ };
+
+ powerdown: powerdown-controller {
+ compatible = "st,stih407-powerdown";
+ #reset-cells = <1>;
+ };
+
+ softreset: softreset-controller {
+ compatible = "st,stih407-softreset";
+ #reset-cells = <1>;
+ };
+
+ picophyreset: picophyreset-controller {
+ compatible = "st,stih407-picophyreset";
+ #reset-cells = <1>;
+ };
+
+ irq-syscfg {
+ compatible = "st,stih407-irq-syscfg";
+ st,syscfg = <&syscfg_core>;
+ st,irq-device = <ST_IRQ_SYSCFG_PMU_0>,
+ <ST_IRQ_SYSCFG_PMU_1>;
+ st,fiq-device = <ST_IRQ_SYSCFG_DISABLED>,
+ <ST_IRQ_SYSCFG_DISABLED>;
+ };
+
+ usb2_picophy0: phy1 {
+ compatible = "st,stih407-usb2-phy";
+ #phy-cells = <0>;
+ st,syscfg = <&syscfg_core 0x100 0xf4>;
+ resets = <&softreset STIH407_PICOPHY_SOFTRESET>,
+ <&picophyreset STIH407_PICOPHY2_RESET>;
+ reset-names = "global", "port";
+ };
+
+ miphy28lp_phy: miphy28lp {
+ compatible = "st,miphy28lp-phy";
+ st,syscfg = <&syscfg_core>;
+ #address-cells = <1>;
+ #size-cells = <1>;
ranges;
- compatible = "simple-bus";
- restart: restart-controller@0 {
- compatible = "st,stih407-restart";
- reg = <0 0>;
- st,syscfg = <&syscfg_sbc_reg>;
- status = "okay";
- };
+ phy_port0: port@9b22000 {
+ reg = <0x9b22000 0xff>,
+ <0x9b09000 0xff>,
+ <0x9b04000 0xff>;
+ reg-names = "sata-up",
+ "pcie-up",
+ "pipew";
+
+ st,syscfg = <0x114 0x818 0xe0 0xec>;
+ #phy-cells = <1>;
- powerdown: powerdown-controller@0 {
- compatible = "st,stih407-powerdown";
- reg = <0 0>;
- #reset-cells = <1>;
+ reset-names = "miphy-sw-rst";
+ resets = <&softreset STIH407_MIPHY0_SOFTRESET>;
};
- softreset: softreset-controller@0 {
- compatible = "st,stih407-softreset";
- reg = <0 0>;
- #reset-cells = <1>;
+ phy_port1: port@9b2a000 {
+ reg = <0x9b2a000 0xff>,
+ <0x9b19000 0xff>,
+ <0x9b14000 0xff>;
+ reg-names = "sata-up",
+ "pcie-up",
+ "pipew";
+
+ st,syscfg = <0x118 0x81c 0xe4 0xf0>;
+
+ #phy-cells = <1>;
+
+ reset-names = "miphy-sw-rst";
+ resets = <&softreset STIH407_MIPHY1_SOFTRESET>;
};
- picophyreset: picophyreset-controller@0 {
- compatible = "st,stih407-picophyreset";
- reg = <0 0>;
- #reset-cells = <1>;
+ phy_port2: port@8f95000 {
+ reg = <0x8f95000 0xff>,
+ <0x8f90000 0xff>;
+ reg-names = "pipew",
+ "usb3-up";
+
+ st,syscfg = <0x11c 0x820>;
+
+ #phy-cells = <1>;
+
+ reset-names = "miphy-sw-rst";
+ resets = <&softreset STIH407_MIPHY2_SOFTRESET>;
};
+ };
+
+ st231_gp0: st231-gp0 {
+ compatible = "st,st231-rproc";
+ memory-region = <&gp0_reserved>;
+ resets = <&softreset STIH407_ST231_GP0_SOFTRESET>;
+ reset-names = "sw_reset";
+ clocks = <&clk_s_c0_flexgen CLK_ST231_GP_0>;
+ clock-frequency = <600000000>;
+ st,syscfg = <&syscfg_core 0x22c>;
+ #mbox-cells = <1>;
+ mbox-names = "vq0_rx", "vq0_tx", "vq1_rx", "vq1_tx";
+ mboxes = <&mailbox0 0 2>, <&mailbox2 0 1>, <&mailbox0 0 3>, <&mailbox2 0 0>;
+ };
+
+ st231_delta: st231-delta {
+ compatible = "st,st231-rproc";
+ memory-region = <&delta_reserved>;
+ resets = <&softreset STIH407_ST231_DMU_SOFTRESET>;
+ reset-names = "sw_reset";
+ clocks = <&clk_s_c0_flexgen CLK_ST231_DMU>;
+ clock-frequency = <600000000>;
+ st,syscfg = <&syscfg_core 0x224>;
+ #mbox-cells = <1>;
+ mbox-names = "vq0_rx", "vq0_tx", "vq1_rx", "vq1_tx";
+ mboxes = <&mailbox0 0 0>, <&mailbox3 0 1>, <&mailbox0 0 1>, <&mailbox3 0 0>;
+ };
+
+ delta0 {
+ compatible = "st,st-delta";
+ clock-names = "delta",
+ "delta-st231",
+ "delta-flash-promip";
+ clocks = <&clk_s_c0_flexgen CLK_VID_DMU>,
+ <&clk_s_c0_flexgen CLK_ST231_DMU>,
+ <&clk_s_c0_flexgen CLK_FLASH_PROMIP>;
+ };
+
+ soc {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ interrupt-parent = <&intc>;
+ ranges;
+ compatible = "simple-bus";
syscfg_sbc: sbc-syscfg@9620000 {
compatible = "st,stih407-sbc-syscfg", "syscon";
@@ -189,16 +292,6 @@
reg = <0x94b5100 0x1000>;
};
- irq-syscfg@0 {
- compatible = "st,stih407-irq-syscfg";
- reg = <0 0>;
- st,syscfg = <&syscfg_core>;
- st,irq-device = <ST_IRQ_SYSCFG_PMU_0>,
- <ST_IRQ_SYSCFG_PMU_1>;
- st,fiq-device = <ST_IRQ_SYSCFG_DISABLED>,
- <ST_IRQ_SYSCFG_DISABLED>;
- };
-
/* Display */
vtg_main: sti-vtg-main@8d02800 {
compatible = "st,vtg";
@@ -389,70 +482,6 @@
status = "disabled";
};
- usb2_picophy0: phy1@0 {
- compatible = "st,stih407-usb2-phy";
- reg = <0 0>;
- #phy-cells = <0>;
- st,syscfg = <&syscfg_core 0x100 0xf4>;
- resets = <&softreset STIH407_PICOPHY_SOFTRESET>,
- <&picophyreset STIH407_PICOPHY2_RESET>;
- reset-names = "global", "port";
- };
-
- miphy28lp_phy: miphy28lp@0 {
- compatible = "st,miphy28lp-phy";
- st,syscfg = <&syscfg_core>;
- #address-cells = <1>;
- #size-cells = <1>;
- ranges;
- reg = <0 0>;
-
- phy_port0: port@9b22000 {
- reg = <0x9b22000 0xff>,
- <0x9b09000 0xff>,
- <0x9b04000 0xff>;
- reg-names = "sata-up",
- "pcie-up",
- "pipew";
-
- st,syscfg = <0x114 0x818 0xe0 0xec>;
- #phy-cells = <1>;
-
- reset-names = "miphy-sw-rst";
- resets = <&softreset STIH407_MIPHY0_SOFTRESET>;
- };
-
- phy_port1: port@9b2a000 {
- reg = <0x9b2a000 0xff>,
- <0x9b19000 0xff>,
- <0x9b14000 0xff>;
- reg-names = "sata-up",
- "pcie-up",
- "pipew";
-
- st,syscfg = <0x118 0x81c 0xe4 0xf0>;
-
- #phy-cells = <1>;
-
- reset-names = "miphy-sw-rst";
- resets = <&softreset STIH407_MIPHY1_SOFTRESET>;
- };
-
- phy_port2: port@8f95000 {
- reg = <0x8f95000 0xff>,
- <0x8f90000 0xff>;
- reg-names = "pipew",
- "usb3-up";
-
- st,syscfg = <0x11c 0x820>;
-
- #phy-cells = <1>;
-
- reset-names = "miphy-sw-rst";
- resets = <&softreset STIH407_MIPHY2_SOFTRESET>;
- };
- };
-
spi@9840000 {
compatible = "st,comms-ssc4-spi";
reg = <0x9840000 0x110>;
@@ -815,34 +844,6 @@
status = "okay";
};
- st231_gp0: st231-gp0@0 {
- compatible = "st,st231-rproc";
- reg = <0 0>;
- memory-region = <&gp0_reserved>;
- resets = <&softreset STIH407_ST231_GP0_SOFTRESET>;
- reset-names = "sw_reset";
- clocks = <&clk_s_c0_flexgen CLK_ST231_GP_0>;
- clock-frequency = <600000000>;
- st,syscfg = <&syscfg_core 0x22c>;
- #mbox-cells = <1>;
- mbox-names = "vq0_rx", "vq0_tx", "vq1_rx", "vq1_tx";
- mboxes = <&mailbox0 0 2>, <&mailbox2 0 1>, <&mailbox0 0 3>, <&mailbox2 0 0>;
- };
-
- st231_delta: st231-delta@0 {
- compatible = "st,st231-rproc";
- reg = <0 0>;
- memory-region = <&delta_reserved>;
- resets = <&softreset STIH407_ST231_DMU_SOFTRESET>;
- reset-names = "sw_reset";
- clocks = <&clk_s_c0_flexgen CLK_ST231_DMU>;
- clock-frequency = <600000000>;
- st,syscfg = <&syscfg_core 0x224>;
- #mbox-cells = <1>;
- mbox-names = "vq0_rx", "vq0_tx", "vq1_rx", "vq1_tx";
- mboxes = <&mailbox0 0 0>, <&mailbox3 0 1>, <&mailbox0 0 1>, <&mailbox3 0 0>;
- };
-
/* fdma audio */
fdma0: dma-controller@8e20000 {
compatible = "st,stih407-fdma-mpe31-11", "st,slim-rproc";
@@ -986,16 +987,5 @@
status = "disabled";
};
-
- delta0@0 {
- compatible = "st,st-delta";
- reg = <0 0>;
- clock-names = "delta",
- "delta-st231",
- "delta-flash-promip";
- clocks = <&clk_s_c0_flexgen CLK_VID_DMU>,
- <&clk_s_c0_flexgen CLK_ST231_DMU>,
- <&clk_s_c0_flexgen CLK_FLASH_PROMIP>;
- };
};
};
diff --git a/arch/arm/boot/dts/stih410-b2120.dts b/arch/arm/boot/dts/stih410-b2120.dts
index 9d3b118f5f0f..538ff98ca1b1 100644
--- a/arch/arm/boot/dts/stih410-b2120.dts
+++ b/arch/arm/boot/dts/stih410-b2120.dts
@@ -24,6 +24,14 @@
ethernet0 = &ethernet0;
};
+ usb2_picophy1: phy2 {
+ status = "okay";
+ };
+
+ usb2_picophy2: phy3 {
+ status = "okay";
+ };
+
soc {
mmc0: sdhci@9060000 {
@@ -33,14 +41,6 @@
sd-uhs-ddr50;
};
- usb2_picophy1: phy2@0 {
- status = "okay";
- };
-
- usb2_picophy2: phy3@0 {
- status = "okay";
- };
-
ohci0: usb@9a03c00 {
status = "okay";
};
diff --git a/arch/arm/boot/dts/stih410-b2260.dts b/arch/arm/boot/dts/stih410-b2260.dts
index 9d579c16c295..26d93f26f6d0 100644
--- a/arch/arm/boot/dts/stih410-b2260.dts
+++ b/arch/arm/boot/dts/stih410-b2260.dts
@@ -75,6 +75,21 @@
};
};
+ miphy28lp_phy: miphy28lp {
+
+ phy_port1: port@9b2a000 {
+ st,osc-force-ext;
+ };
+ };
+
+ usb2_picophy1: phy2 {
+ status = "okay";
+ };
+
+ usb2_picophy2: phy3 {
+ status = "okay";
+ };
+
soc {
/* Low speed expansion connector */
uart0: serial@9830000 {
@@ -145,14 +160,6 @@
status = "okay";
};
- usb2_picophy1: phy2@0 {
- status = "okay";
- };
-
- usb2_picophy2: phy3@0 {
- status = "okay";
- };
-
ohci0: usb@9a03c00 {
status = "okay";
};
@@ -196,13 +203,6 @@
status = "okay";
};
- miphy28lp_phy: miphy28lp@0 {
-
- phy_port1: port@9b2a000 {
- st,osc-force-ext;
- };
- };
-
sata1: sata@9b28000 {
status = "okay";
};
diff --git a/arch/arm/boot/dts/stih410-clock.dtsi b/arch/arm/boot/dts/stih410-clock.dtsi
index 6b0e6d4477a3..abac98a1810b 100644
--- a/arch/arm/boot/dts/stih410-clock.dtsi
+++ b/arch/arm/boot/dts/stih410-clock.dtsi
@@ -32,7 +32,7 @@
*/
clockgen-a9@92b0000 {
compatible = "st,clkgen-c32";
- reg = <0x92b0000 0xffff>;
+ reg = <0x92b0000 0x10000>;
clockgen_a9_pll: clockgen-a9-pll {
#clock-cells = <1>;
@@ -40,29 +40,29 @@
clocks = <&clk_sysin>;
};
- };
- /*
- * ARM CPU related clocks.
- */
- clk_m_a9: clk-m-a9@92b0000 {
- #clock-cells = <0>;
- compatible = "st,stih407-clkgen-a9-mux", "st,clkgen-mux";
- reg = <0x92b0000 0x10000>;
-
- clocks = <&clockgen_a9_pll 0>,
- <&clockgen_a9_pll 0>,
- <&clk_s_c0_flexgen 13>,
- <&clk_m_a9_ext2f_div2>;
/*
- * ARM Peripheral clock for timers
+ * ARM CPU related clocks.
*/
- arm_periph_clk: clk-m-a9-periphs {
+ clk_m_a9: clk-m-a9 {
#clock-cells = <0>;
- compatible = "fixed-factor-clock";
- clocks = <&clk_m_a9>;
- clock-div = <2>;
- clock-mult = <1>;
+ compatible = "st,stih407-clkgen-a9-mux", "st,clkgen-mux";
+
+ clocks = <&clockgen_a9_pll 0>,
+ <&clockgen_a9_pll 0>,
+ <&clk_s_c0_flexgen 13>,
+ <&clk_m_a9_ext2f_div2>;
+
+ /*
+ * ARM Peripheral clock for timers
+ */
+ arm_periph_clk: clk-m-a9-periphs {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&clk_m_a9>;
+ clock-div = <2>;
+ clock-mult = <1>;
+ };
};
};
@@ -87,14 +87,6 @@
};
};
- clk_s_c0_quadfs: clk-s-c0-quadfs@9103000 {
- #clock-cells = <1>;
- compatible = "st,quadfs-pll";
- reg = <0x9103000 0x1000>;
-
- clocks = <&clk_sysin>;
- };
-
clk_s_c0: clockgen-c@9103000 {
compatible = "st,clkgen-c32";
reg = <0x9103000 0x1000>;
@@ -113,6 +105,13 @@
clocks = <&clk_sysin>;
};
+ clk_s_c0_quadfs: clk-s-c0-quadfs {
+ #clock-cells = <1>;
+ compatible = "st,quadfs-pll";
+
+ clocks = <&clk_sysin>;
+ };
+
clk_s_c0_flexgen: clk-s-c0-flexgen {
#clock-cells = <1>;
compatible = "st,flexgen", "st,flexgen-stih410-c0";
@@ -142,18 +141,17 @@
};
};
- clk_s_d0_quadfs: clk-s-d0-quadfs@9104000 {
- #clock-cells = <1>;
- compatible = "st,quadfs-d0";
- reg = <0x9104000 0x1000>;
-
- clocks = <&clk_sysin>;
- };
-
clockgen-d0@9104000 {
compatible = "st,clkgen-c32";
reg = <0x9104000 0x1000>;
+ clk_s_d0_quadfs: clk-s-d0-quadfs {
+ #clock-cells = <1>;
+ compatible = "st,quadfs-d0";
+
+ clocks = <&clk_sysin>;
+ };
+
clk_s_d0_flexgen: clk-s-d0-flexgen {
#clock-cells = <1>;
compatible = "st,flexgen", "st,flexgen-stih410-d0";
@@ -166,18 +164,17 @@
};
};
- clk_s_d2_quadfs: clk-s-d2-quadfs@9106000 {
- #clock-cells = <1>;
- compatible = "st,quadfs-d2";
- reg = <0x9106000 0x1000>;
-
- clocks = <&clk_sysin>;
- };
-
clockgen-d2@9106000 {
compatible = "st,clkgen-c32";
reg = <0x9106000 0x1000>;
+ clk_s_d2_quadfs: clk-s-d2-quadfs {
+ #clock-cells = <1>;
+ compatible = "st,quadfs-d2";
+
+ clocks = <&clk_sysin>;
+ };
+
clk_s_d2_flexgen: clk-s-d2-flexgen {
#clock-cells = <1>;
compatible = "st,flexgen", "st,flexgen-stih407-d2";
@@ -192,18 +189,17 @@
};
};
- clk_s_d3_quadfs: clk-s-d3-quadfs@9107000 {
- #clock-cells = <1>;
- compatible = "st,quadfs-d3";
- reg = <0x9107000 0x1000>;
-
- clocks = <&clk_sysin>;
- };
-
clockgen-d3@9107000 {
compatible = "st,clkgen-c32";
reg = <0x9107000 0x1000>;
+ clk_s_d3_quadfs: clk-s-d3-quadfs {
+ #clock-cells = <1>;
+ compatible = "st,quadfs-d3";
+
+ clocks = <&clk_sysin>;
+ };
+
clk_s_d3_flexgen: clk-s-d3-flexgen {
#clock-cells = <1>;
compatible = "st,flexgen", "st,flexgen-stih407-d3";
diff --git a/arch/arm/boot/dts/stih410.dtsi b/arch/arm/boot/dts/stih410.dtsi
index 6d847019c554..ce2f62cf129b 100644
--- a/arch/arm/boot/dts/stih410.dtsi
+++ b/arch/arm/boot/dts/stih410.dtsi
@@ -12,31 +12,29 @@
bdisp0 = &bdisp0;
};
- soc {
- usb2_picophy1: phy2@0 {
- compatible = "st,stih407-usb2-phy";
- reg = <0 0>;
- #phy-cells = <0>;
- st,syscfg = <&syscfg_core 0xf8 0xf4>;
- resets = <&softreset STIH407_PICOPHY_SOFTRESET>,
- <&picophyreset STIH407_PICOPHY0_RESET>;
- reset-names = "global", "port";
-
- status = "disabled";
- };
+ usb2_picophy1: phy2 {
+ compatible = "st,stih407-usb2-phy";
+ #phy-cells = <0>;
+ st,syscfg = <&syscfg_core 0xf8 0xf4>;
+ resets = <&softreset STIH407_PICOPHY_SOFTRESET>,
+ <&picophyreset STIH407_PICOPHY0_RESET>;
+ reset-names = "global", "port";
+
+ status = "disabled";
+ };
- usb2_picophy2: phy3@0 {
- compatible = "st,stih407-usb2-phy";
- reg = <0 0>;
- #phy-cells = <0>;
- st,syscfg = <&syscfg_core 0xfc 0xf4>;
- resets = <&softreset STIH407_PICOPHY_SOFTRESET>,
- <&picophyreset STIH407_PICOPHY1_RESET>;
- reset-names = "global", "port";
+ usb2_picophy2: phy3 {
+ compatible = "st,stih407-usb2-phy";
+ #phy-cells = <0>;
+ st,syscfg = <&syscfg_core 0xfc 0xf4>;
+ resets = <&softreset STIH407_PICOPHY_SOFTRESET>,
+ <&picophyreset STIH407_PICOPHY1_RESET>;
+ reset-names = "global", "port";
- status = "disabled";
- };
+ status = "disabled";
+ };
+ soc {
ohci0: usb@9a03c00 {
compatible = "st,st-ohci-300x";
reg = <0x9a03c00 0x100>;
@@ -274,16 +272,6 @@
interrupts = <GIC_SPI 205 IRQ_TYPE_EDGE_RISING>;
};
- delta0@0 {
- compatible = "st,st-delta";
- clock-names = "delta",
- "delta-st231",
- "delta-flash-promip";
- clocks = <&clk_s_c0_flexgen CLK_VID_DMU>,
- <&clk_s_c0_flexgen CLK_ST231_DMU>,
- <&clk_s_c0_flexgen CLK_FLASH_PROMIP>;
- };
-
sti-cec@94a087c {
compatible = "st,stih-cec";
reg = <0x94a087c 0x64>;
diff --git a/arch/arm/boot/dts/stih418-b2199.dts b/arch/arm/boot/dts/stih418-b2199.dts
index b66e2b29edea..d21bcc7c1271 100644
--- a/arch/arm/boot/dts/stih418-b2199.dts
+++ b/arch/arm/boot/dts/stih418-b2199.dts
@@ -37,6 +37,17 @@
};
};
+ miphy28lp_phy: miphy28lp {
+
+ phy_port0: port@9b22000 {
+ st,osc-rdy;
+ };
+
+ phy_port1: port@9b2a000 {
+ st,osc-force-ext;
+ };
+ };
+
soc {
sbc_serial0: serial@9530000 {
status = "okay";
@@ -84,17 +95,6 @@
non-removable;
};
- miphy28lp_phy: miphy28lp@0 {
-
- phy_port0: port@9b22000 {
- st,osc-rdy;
- };
-
- phy_port1: port@9b2a000 {
- st,osc-force-ext;
- };
- };
-
st_dwc3: dwc3@8f94000 {
status = "okay";
};
diff --git a/arch/arm/boot/dts/stih418-clock.dtsi b/arch/arm/boot/dts/stih418-clock.dtsi
index e84c476b83ed..e1749e92a2e7 100644
--- a/arch/arm/boot/dts/stih418-clock.dtsi
+++ b/arch/arm/boot/dts/stih418-clock.dtsi
@@ -32,7 +32,7 @@
*/
clockgen-a9@92b0000 {
compatible = "st,clkgen-c32";
- reg = <0x92b0000 0xffff>;
+ reg = <0x92b0000 0x10000>;
clockgen_a9_pll: clockgen-a9-pll {
#clock-cells = <1>;
@@ -40,30 +40,29 @@
clocks = <&clk_sysin>;
};
- };
-
- /*
- * ARM CPU related clocks.
- */
- clk_m_a9: clk-m-a9@92b0000 {
- #clock-cells = <0>;
- compatible = "st,stih407-clkgen-a9-mux", "st,clkgen-mux";
- reg = <0x92b0000 0x10000>;
-
- clocks = <&clockgen_a9_pll 0>,
- <&clockgen_a9_pll 0>,
- <&clk_s_c0_flexgen 13>,
- <&clk_m_a9_ext2f_div2>;
/*
- * ARM Peripheral clock for timers
+ * ARM CPU related clocks.
*/
- arm_periph_clk: clk-m-a9-periphs {
+ clk_m_a9: clk-m-a9 {
#clock-cells = <0>;
- compatible = "fixed-factor-clock";
- clocks = <&clk_m_a9>;
- clock-div = <2>;
- clock-mult = <1>;
+ compatible = "st,stih407-clkgen-a9-mux", "st,clkgen-mux";
+
+ clocks = <&clockgen_a9_pll 0>,
+ <&clockgen_a9_pll 0>,
+ <&clk_s_c0_flexgen 13>,
+ <&clk_m_a9_ext2f_div2>;
+
+ /*
+ * ARM Peripheral clock for timers
+ */
+ arm_periph_clk: clk-m-a9-periphs {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&clk_m_a9>;
+ clock-div = <2>;
+ clock-mult = <1>;
+ };
};
};
@@ -88,14 +87,6 @@
};
};
- clk_s_c0_quadfs: clk-s-c0-quadfs@9103000 {
- #clock-cells = <1>;
- compatible = "st,quadfs-pll";
- reg = <0x9103000 0x1000>;
-
- clocks = <&clk_sysin>;
- };
-
clk_s_c0: clockgen-c@9103000 {
compatible = "st,clkgen-c32";
reg = <0x9103000 0x1000>;
@@ -114,6 +105,13 @@
clocks = <&clk_sysin>;
};
+ clk_s_c0_quadfs: clk-s-c0-quadfs {
+ #clock-cells = <1>;
+ compatible = "st,quadfs-pll";
+
+ clocks = <&clk_sysin>;
+ };
+
clk_s_c0_flexgen: clk-s-c0-flexgen {
#clock-cells = <1>;
compatible = "st,flexgen", "st,flexgen-stih418-c0";
@@ -143,18 +141,17 @@
};
};
- clk_s_d0_quadfs: clk-s-d0-quadfs@9104000 {
- #clock-cells = <1>;
- compatible = "st,quadfs-d0";
- reg = <0x9104000 0x1000>;
-
- clocks = <&clk_sysin>;
- };
-
clockgen-d0@9104000 {
compatible = "st,clkgen-c32";
reg = <0x9104000 0x1000>;
+ clk_s_d0_quadfs: clk-s-d0-quadfs {
+ #clock-cells = <1>;
+ compatible = "st,quadfs-d0";
+
+ clocks = <&clk_sysin>;
+ };
+
clk_s_d0_flexgen: clk-s-d0-flexgen {
#clock-cells = <1>;
compatible = "st,flexgen", "st,flexgen-stih410-d0";
@@ -167,18 +164,17 @@
};
};
- clk_s_d2_quadfs: clk-s-d2-quadfs@9106000 {
- #clock-cells = <1>;
- compatible = "st,quadfs-d2";
- reg = <0x9106000 0x1000>;
-
- clocks = <&clk_sysin>;
- };
-
clockgen-d2@9106000 {
compatible = "st,clkgen-c32";
reg = <0x9106000 0x1000>;
+ clk_s_d2_quadfs: clk-s-d2-quadfs {
+ #clock-cells = <1>;
+ compatible = "st,quadfs-d2";
+
+ clocks = <&clk_sysin>;
+ };
+
clk_s_d2_flexgen: clk-s-d2-flexgen {
#clock-cells = <1>;
compatible = "st,flexgen", "st,flexgen-stih418-d2";
@@ -193,18 +189,17 @@
};
};
- clk_s_d3_quadfs: clk-s-d3-quadfs@9107000 {
- #clock-cells = <1>;
- compatible = "st,quadfs-d3";
- reg = <0x9107000 0x1000>;
-
- clocks = <&clk_sysin>;
- };
-
clockgen-d3@9107000 {
compatible = "st,clkgen-c32";
reg = <0x9107000 0x1000>;
+ clk_s_d3_quadfs: clk-s-d3-quadfs {
+ #clock-cells = <1>;
+ compatible = "st,quadfs-d3";
+
+ clocks = <&clk_sysin>;
+ };
+
clk_s_d3_flexgen: clk-s-d3-flexgen {
#clock-cells = <1>;
compatible = "st,flexgen", "st,flexgen-stih407-d3";
diff --git a/arch/arm/boot/dts/stih418.dtsi b/arch/arm/boot/dts/stih418.dtsi
index 97eda4392fbe..b35b9b7a7ccc 100644
--- a/arch/arm/boot/dts/stih418.dtsi
+++ b/arch/arm/boot/dts/stih418.dtsi
@@ -26,31 +26,29 @@
};
};
+ usb2_picophy1: phy2 {
+ compatible = "st,stih407-usb2-phy";
+ #phy-cells = <0>;
+ st,syscfg = <&syscfg_core 0xf8 0xf4>;
+ resets = <&softreset STIH407_PICOPHY_SOFTRESET>,
+ <&picophyreset STIH407_PICOPHY0_RESET>;
+ reset-names = "global", "port";
+ };
+
+ usb2_picophy2: phy3 {
+ compatible = "st,stih407-usb2-phy";
+ #phy-cells = <0>;
+ st,syscfg = <&syscfg_core 0xfc 0xf4>;
+ resets = <&softreset STIH407_PICOPHY_SOFTRESET>,
+ <&picophyreset STIH407_PICOPHY1_RESET>;
+ reset-names = "global", "port";
+ };
+
soc {
rng11: rng@8a8a000 {
status = "disabled";
};
- usb2_picophy1: phy2@0 {
- compatible = "st,stih407-usb2-phy";
- reg = <0 0>;
- #phy-cells = <0>;
- st,syscfg = <&syscfg_core 0xf8 0xf4>;
- resets = <&softreset STIH407_PICOPHY_SOFTRESET>,
- <&picophyreset STIH407_PICOPHY0_RESET>;
- reset-names = "global", "port";
- };
-
- usb2_picophy2: phy3@0 {
- compatible = "st,stih407-usb2-phy";
- reg = <0 0>;
- #phy-cells = <0>;
- st,syscfg = <&syscfg_core 0xfc 0xf4>;
- resets = <&softreset STIH407_PICOPHY_SOFTRESET>,
- <&picophyreset STIH407_PICOPHY1_RESET>;
- reset-names = "global", "port";
- };
-
ohci0: usb@9a03c00 {
compatible = "st,st-ohci-300x";
reg = <0x9a03c00 0x100>;
diff --git a/arch/arm/boot/dts/stihxxx-b2120.dtsi b/arch/arm/boot/dts/stihxxx-b2120.dtsi
index d051f080e52e..4c72dedcd1be 100644
--- a/arch/arm/boot/dts/stihxxx-b2120.dtsi
+++ b/arch/arm/boot/dts/stihxxx-b2120.dtsi
@@ -71,6 +71,17 @@
};
};
+ miphy28lp_phy: miphy28lp {
+
+ phy_port0: port@9b22000 {
+ st,osc-rdy;
+ };
+
+ phy_port1: port@9b2a000 {
+ st,osc-force-ext;
+ };
+ };
+
soc {
sbc_serial0: serial@9530000 {
status = "okay";
@@ -128,17 +139,6 @@
st,i2c-min-sda-pulse-width-us = <5>;
};
- miphy28lp_phy: miphy28lp@0 {
-
- phy_port0: port@9b22000 {
- st,osc-rdy;
- };
-
- phy_port1: port@9b2a000 {
- st,osc-force-ext;
- };
- };
-
st_dwc3: dwc3@8f94000 {
status = "okay";
};
diff --git a/arch/arm/boot/dts/stm32429i-eval.dts b/arch/arm/boot/dts/stm32429i-eval.dts
index cb46326a8c75..0d98aca01736 100644
--- a/arch/arm/boot/dts/stm32429i-eval.dts
+++ b/arch/arm/boot/dts/stm32429i-eval.dts
@@ -308,6 +308,18 @@
};
};
+&timers5 {
+ /* Override timer5 to act as clockevent */
+ compatible = "st,stm32-timer";
+ interrupts = <50>;
+ status = "okay";
+ /delete-property/#address-cells;
+ /delete-property/#size-cells;
+ /delete-property/clock-names;
+ /delete-node/pwm;
+ /delete-node/timer@4;
+};
+
&usart1 {
pinctrl-0 = <&usart1_pins_a>;
pinctrl-names = "default";
diff --git a/arch/arm/boot/dts/stm32746g-eval.dts b/arch/arm/boot/dts/stm32746g-eval.dts
index 327613fd9666..a293e65141c6 100644
--- a/arch/arm/boot/dts/stm32746g-eval.dts
+++ b/arch/arm/boot/dts/stm32746g-eval.dts
@@ -194,6 +194,18 @@
bus-width = <4>;
};
+&timers5 {
+ /* Override timer5 to act as clockevent */
+ compatible = "st,stm32-timer";
+ interrupts = <50>;
+ status = "okay";
+ /delete-property/#address-cells;
+ /delete-property/#size-cells;
+ /delete-property/clock-names;
+ /delete-node/pwm;
+ /delete-node/timer@4;
+};
+
&usart1 {
pinctrl-0 = <&usart1_pins_a>;
pinctrl-names = "default";
diff --git a/arch/arm/boot/dts/stm32f429-disco.dts b/arch/arm/boot/dts/stm32f429-disco.dts
index 6435e099c632..3b81228d46a2 100644
--- a/arch/arm/boot/dts/stm32f429-disco.dts
+++ b/arch/arm/boot/dts/stm32f429-disco.dts
@@ -205,6 +205,18 @@
};
};
+&timers5 {
+ /* Override timer5 to act as clockevent */
+ compatible = "st,stm32-timer";
+ interrupts = <50>;
+ status = "okay";
+ /delete-property/#address-cells;
+ /delete-property/#size-cells;
+ /delete-property/clock-names;
+ /delete-node/pwm;
+ /delete-node/timer@4;
+};
+
&usart1 {
pinctrl-0 = <&usart1_pins_a>;
pinctrl-names = "default";
diff --git a/arch/arm/boot/dts/stm32f429.dtsi b/arch/arm/boot/dts/stm32f429.dtsi
index 8748d5850298..c31ceb821231 100644
--- a/arch/arm/boot/dts/stm32f429.dtsi
+++ b/arch/arm/boot/dts/stm32f429.dtsi
@@ -93,14 +93,6 @@
};
};
- timer2: timer@40000000 {
- compatible = "st,stm32-timer";
- reg = <0x40000000 0x400>;
- interrupts = <28>;
- clocks = <&rcc 0 STM32F4_APB1_CLOCK(TIM2)>;
- status = "disabled";
- };
-
timers2: timers@40000000 {
#address-cells = <1>;
#size-cells = <0>;
@@ -123,14 +115,6 @@
};
};
- timer3: timer@40000400 {
- compatible = "st,stm32-timer";
- reg = <0x40000400 0x400>;
- interrupts = <29>;
- clocks = <&rcc 0 STM32F4_APB1_CLOCK(TIM3)>;
- status = "disabled";
- };
-
timers3: timers@40000400 {
#address-cells = <1>;
#size-cells = <0>;
@@ -153,14 +137,6 @@
};
};
- timer4: timer@40000800 {
- compatible = "st,stm32-timer";
- reg = <0x40000800 0x400>;
- interrupts = <30>;
- clocks = <&rcc 0 STM32F4_APB1_CLOCK(TIM4)>;
- status = "disabled";
- };
-
timers4: timers@40000800 {
#address-cells = <1>;
#size-cells = <0>;
@@ -183,13 +159,6 @@
};
};
- timer5: timer@40000c00 {
- compatible = "st,stm32-timer";
- reg = <0x40000c00 0x400>;
- interrupts = <50>;
- clocks = <&rcc 0 STM32F4_APB1_CLOCK(TIM5)>;
- };
-
timers5: timers@40000c00 {
#address-cells = <1>;
#size-cells = <0>;
@@ -212,14 +181,6 @@
};
};
- timer6: timer@40001000 {
- compatible = "st,stm32-timer";
- reg = <0x40001000 0x400>;
- interrupts = <54>;
- clocks = <&rcc 0 STM32F4_APB1_CLOCK(TIM6)>;
- status = "disabled";
- };
-
timers6: timers@40001000 {
#address-cells = <1>;
#size-cells = <0>;
@@ -236,14 +197,6 @@
};
};
- timer7: timer@40001400 {
- compatible = "st,stm32-timer";
- reg = <0x40001400 0x400>;
- interrupts = <55>;
- clocks = <&rcc 0 STM32F4_APB1_CLOCK(TIM7)>;
- status = "disabled";
- };
-
timers7: timers@40001400 {
#address-cells = <1>;
#size-cells = <0>;
@@ -759,6 +712,16 @@
status = "disabled";
};
+ dma2d: dma2d@4002b000 {
+ compatible = "st,stm32-dma2d";
+ reg = <0x4002b000 0xc00>;
+ interrupts = <90>;
+ resets = <&rcc STM32F4_AHB1_RESET(DMA2D)>;
+ clocks = <&rcc 0 STM32F4_AHB1_CLOCK(DMA2D)>;
+ clock-names = "dma2d";
+ status = "disabled";
+ };
+
usbotg_hs: usb@40040000 {
compatible = "snps,dwc2";
reg = <0x40040000 0x40000>;
diff --git a/arch/arm/boot/dts/stm32f469-disco.dts b/arch/arm/boot/dts/stm32f469-disco.dts
index 30905ce672a0..5a0daf8e8b11 100644
--- a/arch/arm/boot/dts/stm32f469-disco.dts
+++ b/arch/arm/boot/dts/stm32f469-disco.dts
@@ -132,6 +132,10 @@
clock-frequency = <8000000>;
};
+&dma2d {
+ status = "okay";
+};
+
&dsi {
#address-cells = <1>;
#size-cells = <0>;
@@ -224,6 +228,18 @@
bus-width = <4>;
};
+&timers5 {
+ /* Override timer5 to act as clockevent */
+ compatible = "st,stm32-timer";
+ interrupts = <50>;
+ status = "okay";
+ /delete-property/#address-cells;
+ /delete-property/#size-cells;
+ /delete-property/clock-names;
+ /delete-node/pwm;
+ /delete-node/timer@4;
+};
+
&usart3 {
pinctrl-0 = <&usart3_pins_a>;
pinctrl-names = "default";
diff --git a/arch/arm/boot/dts/stm32f746-disco.dts b/arch/arm/boot/dts/stm32f746-disco.dts
index 569d23cc61e5..c11616ed5fc6 100644
--- a/arch/arm/boot/dts/stm32f746-disco.dts
+++ b/arch/arm/boot/dts/stm32f746-disco.dts
@@ -109,6 +109,18 @@
bus-width = <4>;
};
+&timers5 {
+ /* Override timer5 to act as clockevent */
+ compatible = "st,stm32-timer";
+ interrupts = <50>;
+ status = "okay";
+ /delete-property/#address-cells;
+ /delete-property/#size-cells;
+ /delete-property/clock-names;
+ /delete-node/pwm;
+ /delete-node/timer@4;
+};
+
&usart1 {
pinctrl-0 = <&usart1_pins_b>;
pinctrl-names = "default";
diff --git a/arch/arm/boot/dts/stm32f746.dtsi b/arch/arm/boot/dts/stm32f746.dtsi
index 014b416f57e6..dc868e6da40e 100644
--- a/arch/arm/boot/dts/stm32f746.dtsi
+++ b/arch/arm/boot/dts/stm32f746.dtsi
@@ -75,14 +75,6 @@
};
soc {
- timer2: timer@40000000 {
- compatible = "st,stm32-timer";
- reg = <0x40000000 0x400>;
- interrupts = <28>;
- clocks = <&rcc 0 STM32F7_APB1_CLOCK(TIM2)>;
- status = "disabled";
- };
-
timers2: timers@40000000 {
#address-cells = <1>;
#size-cells = <0>;
@@ -105,14 +97,6 @@
};
};
- timer3: timer@40000400 {
- compatible = "st,stm32-timer";
- reg = <0x40000400 0x400>;
- interrupts = <29>;
- clocks = <&rcc 0 STM32F7_APB1_CLOCK(TIM3)>;
- status = "disabled";
- };
-
timers3: timers@40000400 {
#address-cells = <1>;
#size-cells = <0>;
@@ -135,14 +119,6 @@
};
};
- timer4: timer@40000800 {
- compatible = "st,stm32-timer";
- reg = <0x40000800 0x400>;
- interrupts = <30>;
- clocks = <&rcc 0 STM32F7_APB1_CLOCK(TIM4)>;
- status = "disabled";
- };
-
timers4: timers@40000800 {
#address-cells = <1>;
#size-cells = <0>;
@@ -165,13 +141,6 @@
};
};
- timer5: timer@40000c00 {
- compatible = "st,stm32-timer";
- reg = <0x40000c00 0x400>;
- interrupts = <50>;
- clocks = <&rcc 0 STM32F7_APB1_CLOCK(TIM5)>;
- };
-
timers5: timers@40000c00 {
#address-cells = <1>;
#size-cells = <0>;
@@ -194,14 +163,6 @@
};
};
- timer6: timer@40001000 {
- compatible = "st,stm32-timer";
- reg = <0x40001000 0x400>;
- interrupts = <54>;
- clocks = <&rcc 0 STM32F7_APB1_CLOCK(TIM6)>;
- status = "disabled";
- };
-
timers6: timers@40001000 {
#address-cells = <1>;
#size-cells = <0>;
@@ -218,14 +179,6 @@
};
};
- timer7: timer@40001400 {
- compatible = "st,stm32-timer";
- reg = <0x40001400 0x400>;
- interrupts = <55>;
- clocks = <&rcc 0 STM32F7_APB1_CLOCK(TIM7)>;
- status = "disabled";
- };
-
timers7: timers@40001400 {
#address-cells = <1>;
#size-cells = <0>;
diff --git a/arch/arm/boot/dts/stm32f769-disco.dts b/arch/arm/boot/dts/stm32f769-disco.dts
index be943b701980..b038d0ed39e8 100644
--- a/arch/arm/boot/dts/stm32f769-disco.dts
+++ b/arch/arm/boot/dts/stm32f769-disco.dts
@@ -137,6 +137,18 @@
bus-width = <4>;
};
+&timers5 {
+ /* Override timer5 to act as clockevent */
+ compatible = "st,stm32-timer";
+ interrupts = <50>;
+ status = "okay";
+ /delete-property/#address-cells;
+ /delete-property/#size-cells;
+ /delete-property/clock-names;
+ /delete-node/pwm;
+ /delete-node/timer@4;
+};
+
&usart1 {
pinctrl-0 = <&usart1_pins_a>;
pinctrl-names = "default";
diff --git a/arch/arm/boot/dts/stm32mp13-pinctrl.dtsi b/arch/arm/boot/dts/stm32mp13-pinctrl.dtsi
index 069f95f2b628..d2472cd8f1d0 100644
--- a/arch/arm/boot/dts/stm32mp13-pinctrl.dtsi
+++ b/arch/arm/boot/dts/stm32mp13-pinctrl.dtsi
@@ -7,7 +7,7 @@
&pinctrl {
sdmmc1_b4_pins_a: sdmmc1-b4-0 {
- pins1 {
+ pins {
pinmux = <STM32_PINMUX('C', 8, AF12)>, /* SDMMC1_D0 */
<STM32_PINMUX('C', 9, AF12)>, /* SDMMC1_D1 */
<STM32_PINMUX('C', 10, AF12)>, /* SDMMC1_D2 */
@@ -17,12 +17,6 @@
drive-push-pull;
bias-disable;
};
- pins2 {
- pinmux = <STM32_PINMUX('C', 12, AF12)>; /* SDMMC1_CK */
- slew-rate = <2>;
- drive-push-pull;
- bias-disable;
- };
};
sdmmc1_b4_od_pins_a: sdmmc1-b4-od-0 {
@@ -36,16 +30,81 @@
bias-disable;
};
pins2 {
+ pinmux = <STM32_PINMUX('D', 2, AF12)>; /* SDMMC1_CMD */
+ slew-rate = <1>;
+ drive-open-drain;
+ bias-disable;
+ };
+ };
+
+ sdmmc1_b4_sleep_pins_a: sdmmc1-b4-sleep-0 {
+ pins {
+ pinmux = <STM32_PINMUX('C', 8, ANALOG)>, /* SDMMC1_D0 */
+ <STM32_PINMUX('C', 9, ANALOG)>, /* SDMMC1_D1 */
+ <STM32_PINMUX('C', 10, ANALOG)>, /* SDMMC1_D2 */
+ <STM32_PINMUX('C', 11, ANALOG)>, /* SDMMC1_D3 */
+ <STM32_PINMUX('C', 12, ANALOG)>, /* SDMMC1_CK */
+ <STM32_PINMUX('D', 2, ANALOG)>; /* SDMMC1_CMD */
+ };
+ };
+
+ sdmmc1_clk_pins_a: sdmmc1-clk-0 {
+ pins {
pinmux = <STM32_PINMUX('C', 12, AF12)>; /* SDMMC1_CK */
- slew-rate = <2>;
+ slew-rate = <1>;
drive-push-pull;
bias-disable;
};
- pins3 {
- pinmux = <STM32_PINMUX('D', 2, AF12)>; /* SDMMC1_CMD */
+ };
+
+ sdmmc2_b4_pins_a: sdmmc2-b4-0 {
+ pins {
+ pinmux = <STM32_PINMUX('B', 14, AF10)>, /* SDMMC2_D0 */
+ <STM32_PINMUX('B', 15, AF10)>, /* SDMMC2_D1 */
+ <STM32_PINMUX('B', 3, AF10)>, /* SDMMC2_D2 */
+ <STM32_PINMUX('B', 4, AF10)>, /* SDMMC2_D3 */
+ <STM32_PINMUX('G', 6, AF10)>; /* SDMMC2_CMD */
+ slew-rate = <1>;
+ drive-push-pull;
+ bias-pull-up;
+ };
+ };
+
+ sdmmc2_b4_od_pins_a: sdmmc2-b4-od-0 {
+ pins1 {
+ pinmux = <STM32_PINMUX('B', 14, AF10)>, /* SDMMC2_D0 */
+ <STM32_PINMUX('B', 15, AF10)>, /* SDMMC2_D1 */
+ <STM32_PINMUX('B', 3, AF10)>, /* SDMMC2_D2 */
+ <STM32_PINMUX('B', 4, AF10)>; /* SDMMC2_D3 */
+ slew-rate = <1>;
+ drive-push-pull;
+ bias-pull-up;
+ };
+ pins2 {
+ pinmux = <STM32_PINMUX('G', 6, AF10)>; /* SDMMC2_CMD */
slew-rate = <1>;
drive-open-drain;
- bias-disable;
+ bias-pull-up;
+ };
+ };
+
+ sdmmc2_b4_sleep_pins_a: sdmmc2-b4-sleep-0 {
+ pins {
+ pinmux = <STM32_PINMUX('B', 14, ANALOG)>, /* SDMMC2_D0 */
+ <STM32_PINMUX('B', 15, ANALOG)>, /* SDMMC2_D1 */
+ <STM32_PINMUX('B', 3, ANALOG)>, /* SDMMC2_D2 */
+ <STM32_PINMUX('B', 4, ANALOG)>, /* SDMMC2_D3 */
+ <STM32_PINMUX('E', 3, ANALOG)>, /* SDMMC2_CK */
+ <STM32_PINMUX('G', 6, ANALOG)>; /* SDMMC2_CMD */
+ };
+ };
+
+ sdmmc2_clk_pins_a: sdmmc2-clk-0 {
+ pins {
+ pinmux = <STM32_PINMUX('E', 3, AF10)>; /* SDMMC2_CK */
+ slew-rate = <1>;
+ drive-push-pull;
+ bias-pull-up;
};
};
diff --git a/arch/arm/boot/dts/stm32mp131.dtsi b/arch/arm/boot/dts/stm32mp131.dtsi
index 86126dc0d898..1708c79b5254 100644
--- a/arch/arm/boot/dts/stm32mp131.dtsi
+++ b/arch/arm/boot/dts/stm32mp131.dtsi
@@ -92,10 +92,10 @@
timer {
compatible = "arm,armv7-timer";
- interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
- <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
- <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
- <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>;
+ interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(1) | IRQ_TYPE_LEVEL_LOW)>,
+ <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(1) | IRQ_TYPE_LEVEL_LOW)>,
+ <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(1) | IRQ_TYPE_LEVEL_LOW)>,
+ <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(1) | IRQ_TYPE_LEVEL_LOW)>;
interrupt-parent = <&intc>;
always-on;
};
@@ -115,15 +115,76 @@
status = "disabled";
};
+ dma1: dma-controller@48000000 {
+ compatible = "st,stm32-dma";
+ reg = <0x48000000 0x400>;
+ interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 48 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk_pclk4>;
+ #dma-cells = <4>;
+ st,mem2mem;
+ dma-requests = <8>;
+ };
+
+ dma2: dma-controller@48001000 {
+ compatible = "st,stm32-dma";
+ reg = <0x48001000 0x400>;
+ interrupts = <GIC_SPI 57 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 58 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 59 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 60 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 61 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk_pclk4>;
+ #dma-cells = <4>;
+ st,mem2mem;
+ dma-requests = <8>;
+ };
+
+ dmamux1: dma-router@48002000 {
+ compatible = "st,stm32h7-dmamux";
+ reg = <0x48002000 0x40>;
+ clocks = <&clk_pclk4>;
+ #dma-cells = <3>;
+ dma-masters = <&dma1 &dma2>;
+ dma-requests = <128>;
+ dma-channels = <16>;
+ };
+
+ exti: interrupt-controller@5000d000 {
+ compatible = "st,stm32mp13-exti", "syscon";
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ reg = <0x5000d000 0x400>;
+ };
+
syscfg: syscon@50020000 {
compatible = "st,stm32mp157-syscfg", "syscon";
reg = <0x50020000 0x400>;
clocks = <&clk_pclk3>;
};
+ mdma: dma-controller@58000000 {
+ compatible = "st,stm32h7-mdma";
+ reg = <0x58000000 0x1000>;
+ interrupts = <GIC_SPI 107 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk_pclk4>;
+ #dma-cells = <5>;
+ dma-channels = <32>;
+ dma-requests = <48>;
+ };
+
sdmmc1: mmc@58005000 {
- compatible = "arm,pl18x", "arm,primecell";
- arm,primecell-periphid = <0x00253180>;
+ compatible = "st,stm32-sdmmc2", "arm,pl18x", "arm,primecell";
+ arm,primecell-periphid = <0x20253180>;
reg = <0x58005000 0x1000>, <0x58006000 0x1000>;
interrupts = <GIC_SPI 50 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "cmd_irq";
@@ -131,7 +192,21 @@
clock-names = "apb_pclk";
cap-sd-highspeed;
cap-mmc-highspeed;
- max-frequency = <120000000>;
+ max-frequency = <130000000>;
+ status = "disabled";
+ };
+
+ sdmmc2: mmc@58007000 {
+ compatible = "st,stm32-sdmmc2", "arm,pl18x", "arm,primecell";
+ arm,primecell-periphid = <0x20253180>;
+ reg = <0x58007000 0x1000>, <0x58008000 0x1000>;
+ interrupts = <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "cmd_irq";
+ clocks = <&clk_pll4_p>;
+ clock-names = "apb_pclk";
+ cap-sd-highspeed;
+ cap-mmc-highspeed;
+ max-frequency = <130000000>;
status = "disabled";
};
diff --git a/arch/arm/boot/dts/stm32mp135f-dk.dts b/arch/arm/boot/dts/stm32mp135f-dk.dts
index 7e96d9e36217..ee100d108ea2 100644
--- a/arch/arm/boot/dts/stm32mp135f-dk.dts
+++ b/arch/arm/boot/dts/stm32mp135f-dk.dts
@@ -38,9 +38,10 @@
};
&sdmmc1 {
- pinctrl-names = "default", "opendrain";
- pinctrl-0 = <&sdmmc1_b4_pins_a>;
- pinctrl-1 = <&sdmmc1_b4_od_pins_a>;
+ pinctrl-names = "default", "opendrain", "sleep";
+ pinctrl-0 = <&sdmmc1_b4_pins_a &sdmmc1_clk_pins_a>;
+ pinctrl-1 = <&sdmmc1_b4_od_pins_a &sdmmc1_clk_pins_a>;
+ pinctrl-2 = <&sdmmc1_b4_sleep_pins_a>;
broken-cd;
disable-wp;
st,neg-edge;
diff --git a/arch/arm/boot/dts/stm32mp15-pinctrl.dtsi b/arch/arm/boot/dts/stm32mp15-pinctrl.dtsi
index 3b65130affec..f0d66d8c6e3b 100644
--- a/arch/arm/boot/dts/stm32mp15-pinctrl.dtsi
+++ b/arch/arm/boot/dts/stm32mp15-pinctrl.dtsi
@@ -338,6 +338,47 @@
};
};
+ ethernet0_rmii_pins_b: rmii-1 {
+ pins1 {
+ pinmux = <STM32_PINMUX('B', 5, AF0)>, /* ETH1_CLK */
+ <STM32_PINMUX('C', 1, AF11)>, /* ETH1_MDC */
+ <STM32_PINMUX('G', 13, AF11)>, /* ETH1_TXD0 */
+ <STM32_PINMUX('G', 14, AF11)>; /* ETH1_TXD1 */
+ bias-disable;
+ drive-push-pull;
+ slew-rate = <1>;
+ };
+ pins2 {
+ pinmux = <STM32_PINMUX('A', 2, AF11)>; /* ETH1_MDIO */
+ bias-disable;
+ drive-push-pull;
+ slew-rate = <0>;
+ };
+ pins3 {
+ pinmux = <STM32_PINMUX('A', 7, AF11)>, /* ETH1_CRS_DV */
+ <STM32_PINMUX('C', 4, AF11)>, /* ETH1_RXD0 */
+ <STM32_PINMUX('C', 5, AF11)>; /* ETH1_RXD1 */
+ bias-disable;
+ };
+ pins4 {
+ pinmux = <STM32_PINMUX('B', 11, AF11)>; /* ETH1_TX_EN */
+ };
+ };
+
+ ethernet0_rmii_sleep_pins_b: rmii-sleep-1 {
+ pins1 {
+ pinmux = <STM32_PINMUX('A', 2, ANALOG)>, /* ETH1_MDIO */
+ <STM32_PINMUX('A', 7, ANALOG)>, /* ETH1_CRS_DV */
+ <STM32_PINMUX('B', 5, ANALOG)>, /* ETH1_CLK */
+ <STM32_PINMUX('B', 11, ANALOG)>, /* ETH1_TX_EN */
+ <STM32_PINMUX('C', 1, ANALOG)>, /* ETH1_MDC */
+ <STM32_PINMUX('C', 4, ANALOG)>, /* ETH1_RXD0 */
+ <STM32_PINMUX('C', 5, ANALOG)>, /* ETH1_RXD1 */
+ <STM32_PINMUX('G', 13, ANALOG)>, /* ETH1_TXD0 */
+ <STM32_PINMUX('G', 14, ANALOG)>; /* ETH1_TXD1 */
+ };
+ };
+
fmc_pins_a: fmc-0 {
pins1 {
pinmux = <STM32_PINMUX('D', 4, AF12)>, /* FMC_NOE */
@@ -927,6 +968,21 @@
};
};
+ pwm1_pins_b: pwm1-1 {
+ pins {
+ pinmux = <STM32_PINMUX('E', 9, AF1)>; /* TIM1_CH1 */
+ bias-pull-down;
+ drive-push-pull;
+ slew-rate = <0>;
+ };
+ };
+
+ pwm1_sleep_pins_b: pwm1-sleep-1 {
+ pins {
+ pinmux = <STM32_PINMUX('E', 9, ANALOG)>; /* TIM1_CH1 */
+ };
+ };
+
pwm2_pins_a: pwm2-0 {
pins {
pinmux = <STM32_PINMUX('A', 3, AF1)>; /* TIM2_CH4 */
@@ -1190,7 +1246,7 @@
};
};
- sai2a_sleep_pins_c: sai2a-2 {
+ sai2a_sleep_pins_c: sai2a-sleep-2 {
pins {
pinmux = <STM32_PINMUX('D', 13, ANALOG)>, /* SAI2_SCK_A */
<STM32_PINMUX('D', 11, ANALOG)>, /* SAI2_SD_A */
@@ -2042,6 +2098,42 @@
};
};
+ usart3_pins_d: usart3-3 {
+ pins1 {
+ pinmux = <STM32_PINMUX('B', 10, AF7)>, /* USART3_TX */
+ <STM32_PINMUX('G', 8, AF8)>; /* USART3_RTS */
+ bias-disable;
+ drive-push-pull;
+ slew-rate = <0>;
+ };
+ pins2 {
+ pinmux = <STM32_PINMUX('D', 9, AF7)>, /* USART3_RX */
+ <STM32_PINMUX('D', 11, AF7)>; /* USART3_CTS_NSS */
+ bias-disable;
+ };
+ };
+
+ usart3_idle_pins_d: usart3-idle-3 {
+ pins1 {
+ pinmux = <STM32_PINMUX('B', 10, ANALOG)>, /* USART3_TX */
+ <STM32_PINMUX('G', 8, ANALOG)>, /* USART3_RTS */
+ <STM32_PINMUX('D', 11, ANALOG)>; /* USART3_CTS_NSS */
+ };
+ pins2 {
+ pinmux = <STM32_PINMUX('D', 9, AF7)>; /* USART3_RX */
+ bias-disable;
+ };
+ };
+
+ usart3_sleep_pins_d: usart3-sleep-3 {
+ pins {
+ pinmux = <STM32_PINMUX('B', 10, ANALOG)>, /* USART3_TX */
+ <STM32_PINMUX('G', 8, ANALOG)>, /* USART3_RTS */
+ <STM32_PINMUX('D', 11, ANALOG)>, /* USART3_CTS_NSS */
+ <STM32_PINMUX('D', 9, ANALOG)>; /* USART3_RX */
+ };
+ };
+
usbotg_hs_pins_a: usbotg-hs-0 {
pins {
pinmux = <STM32_PINMUX('A', 10, ANALOG)>; /* OTG_ID */
diff --git a/arch/arm/boot/dts/stm32mp151.dtsi b/arch/arm/boot/dts/stm32mp151.dtsi
index 1cfc2f011e70..f9aa9af31efd 100644
--- a/arch/arm/boot/dts/stm32mp151.dtsi
+++ b/arch/arm/boot/dts/stm32mp151.dtsi
@@ -45,10 +45,10 @@
timer {
compatible = "arm,armv7-timer";
- interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
- <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
- <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
- <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>;
+ interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(1) | IRQ_TYPE_LEVEL_LOW)>,
+ <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(1) | IRQ_TYPE_LEVEL_LOW)>,
+ <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(1) | IRQ_TYPE_LEVEL_LOW)>,
+ <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(1) | IRQ_TYPE_LEVEL_LOW)>;
interrupt-parent = <&intc>;
};
@@ -455,6 +455,9 @@
interrupts-extended = <&exti 27 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&rcc USART2_K>;
wakeup-source;
+ dmas = <&dmamux1 43 0x400 0x15>,
+ <&dmamux1 44 0x400 0x11>;
+ dma-names = "rx", "tx";
status = "disabled";
};
@@ -464,6 +467,9 @@
interrupts-extended = <&exti 28 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&rcc USART3_K>;
wakeup-source;
+ dmas = <&dmamux1 45 0x400 0x15>,
+ <&dmamux1 46 0x400 0x11>;
+ dma-names = "rx", "tx";
status = "disabled";
};
@@ -473,6 +479,9 @@
interrupts-extended = <&exti 30 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&rcc UART4_K>;
wakeup-source;
+ dmas = <&dmamux1 63 0x400 0x15>,
+ <&dmamux1 64 0x400 0x11>;
+ dma-names = "rx", "tx";
status = "disabled";
};
@@ -482,6 +491,9 @@
interrupts-extended = <&exti 31 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&rcc UART5_K>;
wakeup-source;
+ dmas = <&dmamux1 65 0x400 0x15>,
+ <&dmamux1 66 0x400 0x11>;
+ dma-names = "rx", "tx";
status = "disabled";
};
@@ -588,6 +600,9 @@
interrupts-extended = <&exti 32 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&rcc UART7_K>;
wakeup-source;
+ dmas = <&dmamux1 79 0x400 0x15>,
+ <&dmamux1 80 0x400 0x11>;
+ dma-names = "rx", "tx";
status = "disabled";
};
@@ -597,6 +612,9 @@
interrupts-extended = <&exti 33 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&rcc UART8_K>;
wakeup-source;
+ dmas = <&dmamux1 81 0x400 0x15>,
+ <&dmamux1 82 0x400 0x11>;
+ dma-names = "rx", "tx";
status = "disabled";
};
@@ -678,6 +696,9 @@
interrupts-extended = <&exti 29 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&rcc USART6_K>;
wakeup-source;
+ dmas = <&dmamux1 71 0x400 0x15>,
+ <&dmamux1 72 0x400 0x11>;
+ dma-names = "rx", "tx";
status = "disabled";
};
@@ -1059,7 +1080,7 @@
};
sdmmc3: mmc@48004000 {
- compatible = "arm,pl18x", "arm,primecell";
+ compatible = "st,stm32-sdmmc2", "arm,pl18x", "arm,primecell";
arm,primecell-periphid = <0x00253180>;
reg = <0x48004000 0x400>;
interrupts = <GIC_SPI 137 IRQ_TYPE_LEVEL_HIGH>;
@@ -1381,7 +1402,7 @@
};
sdmmc1: mmc@58005000 {
- compatible = "arm,pl18x", "arm,primecell";
+ compatible = "st,stm32-sdmmc2", "arm,pl18x", "arm,primecell";
arm,primecell-periphid = <0x00253180>;
reg = <0x58005000 0x1000>;
interrupts = <GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH>;
@@ -1396,7 +1417,7 @@
};
sdmmc2: mmc@58007000 {
- compatible = "arm,pl18x", "arm,primecell";
+ compatible = "st,stm32-sdmmc2", "arm,pl18x", "arm,primecell";
arm,primecell-periphid = <0x00253180>;
reg = <0x58007000 0x1000>;
interrupts = <GIC_SPI 124 IRQ_TYPE_LEVEL_HIGH>;
@@ -1560,7 +1581,7 @@
reg = <0x5c004000 0x400>;
clocks = <&rcc RTCAPB>, <&rcc RTC>;
clock-names = "pclk", "rtc_ck";
- interrupts = <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts-extended = <&exti 19 IRQ_TYPE_LEVEL_HIGH>;
status = "disabled";
};
diff --git a/arch/arm/boot/dts/stm32mp153.dtsi b/arch/arm/boot/dts/stm32mp153.dtsi
index 1c1889b194cf..486084e0b80b 100644
--- a/arch/arm/boot/dts/stm32mp153.dtsi
+++ b/arch/arm/boot/dts/stm32mp153.dtsi
@@ -22,6 +22,13 @@
interrupt-affinity = <&cpu0>, <&cpu1>;
};
+ timer {
+ interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
+ <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
+ <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
+ <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>;
+ };
+
soc {
m_can1: can@4400e000 {
compatible = "bosch,m_can";
diff --git a/arch/arm/boot/dts/stm32mp157a-icore-stm32mp1-ctouch2.dts b/arch/arm/boot/dts/stm32mp157a-icore-stm32mp1-ctouch2.dts
index d3058a036c74..1f75f1d45181 100644
--- a/arch/arm/boot/dts/stm32mp157a-icore-stm32mp1-ctouch2.dts
+++ b/arch/arm/boot/dts/stm32mp157a-icore-stm32mp1-ctouch2.dts
@@ -43,5 +43,7 @@
pinctrl-0 = <&uart4_pins_a>;
pinctrl-1 = <&uart4_sleep_pins_a>;
pinctrl-2 = <&uart4_idle_pins_a>;
+ /delete-property/dmas;
+ /delete-property/dma-names;
status = "okay";
};
diff --git a/arch/arm/boot/dts/stm32mp157a-icore-stm32mp1-edimm2.2.dts b/arch/arm/boot/dts/stm32mp157a-icore-stm32mp1-edimm2.2.dts
index a797eaa917b7..ba92d7d8ed00 100644
--- a/arch/arm/boot/dts/stm32mp157a-icore-stm32mp1-edimm2.2.dts
+++ b/arch/arm/boot/dts/stm32mp157a-icore-stm32mp1-edimm2.2.dts
@@ -128,5 +128,7 @@
pinctrl-0 = <&uart4_pins_a>;
pinctrl-1 = <&uart4_sleep_pins_a>;
pinctrl-2 = <&uart4_idle_pins_a>;
+ /delete-property/dmas;
+ /delete-property/dma-names;
status = "okay";
};
diff --git a/arch/arm/boot/dts/stm32mp157a-iot-box.dts b/arch/arm/boot/dts/stm32mp157a-iot-box.dts
index 70f394b4d3c0..6a5a4af25bd9 100644
--- a/arch/arm/boot/dts/stm32mp157a-iot-box.dts
+++ b/arch/arm/boot/dts/stm32mp157a-iot-box.dts
@@ -58,6 +58,8 @@
/delete-property/st,hw-flow-ctrl;
cts-gpios = <&gpioa 15 GPIO_ACTIVE_LOW>;
rts-gpios = <&gpiob 0 GPIO_ACTIVE_LOW>;
+ /delete-property/dmas;
+ /delete-property/dma-names;
status = "okay";
bluetooth {
diff --git a/arch/arm/boot/dts/stm32mp157a-microgea-stm32mp1-microdev2.0-of7.dts b/arch/arm/boot/dts/stm32mp157a-microgea-stm32mp1-microdev2.0-of7.dts
index 5670b23812a2..fae656edd820 100644
--- a/arch/arm/boot/dts/stm32mp157a-microgea-stm32mp1-microdev2.0-of7.dts
+++ b/arch/arm/boot/dts/stm32mp157a-microgea-stm32mp1-microdev2.0-of7.dts
@@ -143,6 +143,8 @@
pinctrl-0 = <&uart4_pins_a>;
pinctrl-1 = <&uart4_sleep_pins_a>;
pinctrl-2 = <&uart4_idle_pins_a>;
+ /delete-property/dmas;
+ /delete-property/dma-names;
status = "okay";
};
@@ -150,5 +152,7 @@
&uart8 {
pinctrl-names = "default";
pinctrl-0 = <&uart8_pins_a>;
+ /delete-property/dmas;
+ /delete-property/dma-names;
status = "okay";
};
diff --git a/arch/arm/boot/dts/stm32mp157a-microgea-stm32mp1-microdev2.0.dts b/arch/arm/boot/dts/stm32mp157a-microgea-stm32mp1-microdev2.0.dts
index 7a75868164dc..b9d0d3d6ad15 100644
--- a/arch/arm/boot/dts/stm32mp157a-microgea-stm32mp1-microdev2.0.dts
+++ b/arch/arm/boot/dts/stm32mp157a-microgea-stm32mp1-microdev2.0.dts
@@ -44,6 +44,8 @@
pinctrl-0 = <&uart4_pins_a>;
pinctrl-1 = <&uart4_sleep_pins_a>;
pinctrl-2 = <&uart4_idle_pins_a>;
+ /delete-property/dmas;
+ /delete-property/dma-names;
status = "okay";
};
@@ -51,5 +53,7 @@
&uart8 {
pinctrl-names = "default";
pinctrl-0 = <&uart8_pins_a>;
+ /delete-property/dmas;
+ /delete-property/dma-names;
status = "okay";
};
diff --git a/arch/arm/boot/dts/stm32mp157a-stinger96.dtsi b/arch/arm/boot/dts/stm32mp157a-stinger96.dtsi
index a4b14ef3caee..3a36f7fe0a2c 100644
--- a/arch/arm/boot/dts/stm32mp157a-stinger96.dtsi
+++ b/arch/arm/boot/dts/stm32mp157a-stinger96.dtsi
@@ -288,6 +288,8 @@
pinctrl-0 = <&usart2_pins_b>;
pinctrl-1 = <&usart2_sleep_pins_b>;
st,hw-flow-ctrl;
+ /delete-property/dmas;
+ /delete-property/dma-names;
status = "okay";
};
@@ -296,6 +298,8 @@
pinctrl-names = "default";
pinctrl-0 = <&uart4_pins_c>;
st,hw-flow-ctrl;
+ /delete-property/dmas;
+ /delete-property/dma-names;
status = "okay";
};
@@ -303,6 +307,8 @@
&uart7 {
pinctrl-names = "default";
pinctrl-0 = <&uart7_pins_b>;
+ /delete-property/dmas;
+ /delete-property/dma-names;
status = "okay";
};
diff --git a/arch/arm/boot/dts/stm32mp157c-ed1.dts b/arch/arm/boot/dts/stm32mp157c-ed1.dts
index 46b471d09c50..b1eb688a278a 100644
--- a/arch/arm/boot/dts/stm32mp157c-ed1.dts
+++ b/arch/arm/boot/dts/stm32mp157c-ed1.dts
@@ -384,6 +384,8 @@
pinctrl-0 = <&uart4_pins_a>;
pinctrl-1 = <&uart4_sleep_pins_a>;
pinctrl-2 = <&uart4_idle_pins_a>;
+ /delete-property/dmas;
+ /delete-property/dma-names;
status = "okay";
};
diff --git a/arch/arm/boot/dts/stm32mp157c-emsbc-argon.dts b/arch/arm/boot/dts/stm32mp157c-emsbc-argon.dts
new file mode 100644
index 000000000000..33b3f11d24bb
--- /dev/null
+++ b/arch/arm/boot/dts/stm32mp157c-emsbc-argon.dts
@@ -0,0 +1,53 @@
+// SPDX-License-Identifier: (GPL-2.0 or MIT)
+//
+// Copyright (c) 2021 emtrion GmbH
+// Author: Reinhold Müller <reinhold.mueller@emtrion.de>.
+//
+
+/dts-v1/;
+
+#include "stm32mp157c-emstamp-argon.dtsi"
+
+/ {
+ model = "emtrion STM32MP157C emSBC-Argon Developer Board";
+ compatible = "emtrion,stm32mp157c-emsbc-argon", "emtrion,stm32mp157c-emstamp-argon",
+ "st,stm32mp157";
+
+ led: gpio_leds {
+ compatible = "gpio-leds";
+ led-2 {
+ label = "red";
+ gpios = <&gpiof 12 GPIO_ACTIVE_LOW>;
+ linux,default-trigger = "none";
+ default-state = "off";
+ };
+ led-3 {
+ label = "green";
+ gpios = <&gpioe 7 GPIO_ACTIVE_LOW>;
+ linux,default-trigger = "none";
+ default-state = "off";
+ };
+ };
+};
+
+&dac {
+ status = "okay";
+};
+
+&sdmmc1 {
+ pinctrl-names = "default", "opendrain", "sleep";
+ pinctrl-0 = <&sdmmc1_b4_pins_a>;
+ pinctrl-1 = <&sdmmc1_b4_od_pins_a>;
+ pinctrl-2 = <&sdmmc1_b4_sleep_pins_a>;
+ cd-gpios = <&gpiob 7 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>;
+ disable-wp;
+ st,neg-edge;
+ bus-width = <4>;
+ vmmc-supply = <&vdd_sd>;
+ status = "okay";
+};
+
+&spi1 {
+ status = "okay";
+};
+
diff --git a/arch/arm/boot/dts/stm32mp157c-emstamp-argon.dtsi b/arch/arm/boot/dts/stm32mp157c-emstamp-argon.dtsi
new file mode 100644
index 000000000000..33ae5e0590df
--- /dev/null
+++ b/arch/arm/boot/dts/stm32mp157c-emstamp-argon.dtsi
@@ -0,0 +1,552 @@
+// SPDX-License-Identifier: (GPL-2.0 or MIT)
+//
+// Copyright (c) 2021 emtrion GmbH
+// Author: Reinhold Müller <reinhold.mueller@emtrion.de>.
+//
+
+#include "stm32mp157.dtsi"
+#include "stm32mp15xc.dtsi"
+#include "stm32mp15-pinctrl.dtsi"
+#include "stm32mp15xxac-pinctrl.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/mfd/st,stpmic1.h>
+
+/ {
+ aliases {
+ ethernet0 = &ethernet0;
+ serial0 = &uart4;
+ serial1 = &usart2;
+ serial2 = &usart3;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+
+ memory@c0000000 {
+ device_type = "memory";
+ reg = <0xc0000000 0x20000000>;
+ };
+
+ reserved-memory {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ mcuram2: mcuram2@10000000 {
+ compatible = "shared-dma-pool";
+ reg = <0x10000000 0x40000>;
+ no-map;
+ };
+
+ vdev0vring0: vdev0vring0@10040000 {
+ compatible = "shared-dma-pool";
+ reg = <0x10040000 0x2000>;
+ no-map;
+ };
+
+ vdev0vring1: vdev0vring1@10042000 {
+ compatible = "shared-dma-pool";
+ reg = <0x10042000 0x2000>;
+ no-map;
+ };
+
+ vdev0buffer: vdev0buffer@10044000 {
+ compatible = "shared-dma-pool";
+ reg = <0x10044000 0x4000>;
+ no-map;
+ };
+
+ mcuram: mcuram@30000000 {
+ compatible = "shared-dma-pool";
+ reg = <0x30000000 0x40000>;
+ no-map;
+ };
+
+ retram: retram@38000000 {
+ compatible = "shared-dma-pool";
+ reg = <0x38000000 0x10000>;
+ no-map;
+ };
+
+ gpu_reserved: gpu@dc000000 {
+ reg = <0xdc000000 0x4000000>;
+ no-map;
+ };
+ };
+
+ led: gpio_leds {
+ compatible = "gpio-leds";
+ led-0 {
+ label = "panic";
+ gpios = <&gpioa 13 GPIO_ACTIVE_LOW>;
+ linux,default-trigger = "none";
+ default-state = "off";
+ panic-indicator;
+ };
+ led-1 {
+ label = "heartbeat";
+ gpios = <&gpioa 14 GPIO_ACTIVE_LOW>;
+ linux,default-trigger = "heartbeat";
+ default-state = "on";
+ };
+ };
+};
+
+&adc {
+ vdd-supply = <&vdd>;
+ vdda-supply = <&vdd>;
+ vref-supply = <&vrefbuf>;
+ status = "okay";
+
+ adc1: adc@0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&adc1_in6_pins_a>;
+ st,min-sample-time-nsecs = <5000>;
+ st,adc-channels = <6>;
+ status = "disabled";
+ };
+
+ adc2: adc@100 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "okay";
+ channel@12 {
+ reg = <12>;
+ label = "sense_temp";
+ st,min-sample-time-ns = <9000>;
+ };
+ channel@15 {
+ reg = <15>;
+ label = "vbat";
+ st,min-sample-time-ns = <9000>;
+ };
+ channel@16 {
+ reg = <16>;
+ label = "dac_out1";
+ st,min-sample-time-ns = <9000>;
+ };
+ channel@17 {
+ reg = <17>;
+ label = "dac_out1";
+ st,min-sample-time-ns = <9000>;
+ };
+ };
+};
+
+&crc1 {
+ status = "okay";
+};
+
+&cryp1 {
+ status = "okay";
+};
+
+&dac {
+ pinctrl-names = "default";
+ pinctrl-0 = <&dac_ch1_pins_a &dac_ch2_pins_a>;
+ vref-supply = <&vdda>;
+ status = "disabled";
+
+ dac1: dac@1 {
+ status = "okay";
+ };
+ dac2: dac@2 {
+ status = "okay";
+ };
+};
+
+&dts {
+ status = "okay";
+};
+
+&ethernet0 {
+ status = "okay";
+ snps,reset-gpio = <&gpioa 1 GPIO_ACTIVE_LOW>;
+ snps,reset-active-low;
+ snps,reset-delays-us = <0 30000 50000>;
+ pinctrl-0 = <&ethernet0_rmii_pins_b>;
+ pinctrl-1 = <&ethernet0_rmii_sleep_pins_b>;
+ pinctrl-names = "default", "sleep";
+ phy-mode = "rmii";
+ max-speed = <100>;
+ phy-handle = <&phy0>;
+ st,eth-ref-clk-sel;
+
+ mdio0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "snps,dwmac-mdio";
+ phy0: ethernet-phy@0 {
+ reg = <0>;
+ };
+ };
+};
+
+&gpu {
+ contiguous-area = <&gpu_reserved>;
+};
+
+&hash1 {
+ status = "okay";
+};
+
+&i2c1 {
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&i2c1_pins_a>;
+ pinctrl-1 = <&i2c1_sleep_pins_a>;
+ i2c-scl-rising-time-ns = <100>;
+ i2c-scl-falling-time-ns = <7>;
+ status = "disabled";
+ /delete-property/dmas;
+ /delete-property/dma-names;
+};
+
+&i2c4 {
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&i2c4_pins_a>;
+ pinctrl-1 = <&i2c4_sleep_pins_a>;
+ i2c-scl-rising-time-ns = <185>;
+ i2c-scl-falling-time-ns = <20>;
+ status = "okay";
+ /delete-property/dmas;
+ /delete-property/dma-names;
+
+ pmic: stpmic@33 {
+ compatible = "st,stpmic1";
+ reg = <0x33>;
+ interrupts-extended = <&gpioa 0 IRQ_TYPE_EDGE_FALLING>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ status = "okay";
+
+ regulators {
+ compatible = "st,stpmic1-regulators";
+
+ ldo1-supply = <&v3v3>;
+ ldo3-supply = <&vdd_ddr>;
+ ldo6-supply = <&v3v3>;
+ pwr_sw1-supply = <&bst_out>;
+ pwr_sw2-supply = <&bst_out>;
+
+ vddcore: buck1 {
+ regulator-name = "vddcore";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1350000>;
+ regulator-always-on;
+ regulator-initial-mode = <0>;
+ regulator-over-current-protection;
+ };
+
+ vdd_ddr: buck2 {
+ regulator-name = "vdd_ddr";
+ regulator-min-microvolt = <1350000>;
+ regulator-max-microvolt = <1350000>;
+ regulator-always-on;
+ regulator-initial-mode = <0>;
+ regulator-over-current-protection;
+ };
+
+ vdd: buck3 {
+ regulator-name = "vdd";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ st,mask-reset;
+ regulator-initial-mode = <0>;
+ regulator-over-current-protection;
+ };
+
+ v3v3: buck4 {
+ regulator-name = "v3v3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ regulator-over-current-protection;
+ regulator-initial-mode = <0>;
+ };
+
+ v1v8_audio: ldo1 {
+ regulator-name = "v1v8_audio";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ interrupts = <IT_CURLIM_LDO1 0>;
+ };
+
+ v3v3_hdmi: ldo2 {
+ regulator-name = "v3v3_hdmi";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ interrupts = <IT_CURLIM_LDO2 0>;
+ };
+
+ vtt_ddr: ldo3 {
+ regulator-name = "vtt_ddr";
+ regulator-min-microvolt = <500000>;
+ regulator-max-microvolt = <750000>;
+ regulator-always-on;
+ regulator-over-current-protection;
+ };
+
+ vdd_usb: ldo4 {
+ regulator-name = "vdd_usb";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ interrupts = <IT_CURLIM_LDO4 0>;
+ };
+
+ vdd_sd: ldo5 {
+ regulator-name = "vdd_sd";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ interrupts = <IT_CURLIM_LDO5 0>;
+ regulator-always-on;
+ };
+
+ vdda: ldo6 {
+ regulator-name = "vdda";
+ regulator-min-microvolt = <2900000>;
+ regulator-max-microvolt = <2900000>;
+ regulator-always-on;
+ interrupts = <IT_CURLIM_LDO6 0>;
+ regulator-boot-on;
+ };
+
+ vref_ddr: vref_ddr {
+ regulator-name = "vref_ddr";
+ regulator-always-on;
+ regulator-over-current-protection;
+ };
+
+ bst_out: boost {
+ regulator-name = "bst_out";
+ interrupts = <IT_OCP_BOOST 0>;
+ };
+
+ vbus_otg: pwr_sw1 {
+ regulator-name = "vbus_otg";
+ interrupts = <IT_OCP_OTG 0>;
+ regulator-active-discharge;
+ };
+
+ vbus_usbh: pwr_sw2 {
+ regulator-name = "usbh_vbus";
+ interrupts = <IT_OCP_SWOUT 0>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+ };
+
+ onkey {
+ compatible = "st,stpmic1-onkey";
+ interrupts = <IT_PONKEY_F 0>, <IT_PONKEY_R 1>;
+ interrupt-names = "onkey-falling", "onkey-rising";
+ status = "okay";
+ };
+
+ watchdog {
+ compatible = "st,stpmic1-wdt";
+ status = "disabled";
+ };
+ };
+};
+
+&i2c5 {
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&i2c5_pins_a>;
+ pinctrl-1 = <&i2c5_sleep_pins_a>;
+ i2c-scl-rising-time-ns = <185>;
+ i2c-scl-falling-time-ns = <20>;
+ /delete-property/dmas;
+ /delete-property/dma-names;
+};
+
+&ipcc {
+ status = "okay";
+};
+
+&iwdg2 {
+ timeout-sec = <32>;
+ status = "okay";
+};
+
+&m4_rproc {
+ memory-region = <&retram>, <&mcuram>, <&mcuram2>, <&vdev0vring0>,
+ <&vdev0vring1>, <&vdev0buffer>;
+ mboxes = <&ipcc 0>, <&ipcc 1>, <&ipcc 2>;
+ mbox-names = "vq0", "vq1", "shutdown";
+ interrupt-parent = <&exti>;
+ interrupts = <68 1>;
+ interrupt-names = "wdg";
+ recovery;
+ status = "okay";
+};
+
+&pwr_regulators {
+ vdd-supply = <&vdd>;
+ vdd_3v3_usbfs-supply = <&vdd_usb>;
+};
+
+&qspi {
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&qspi_clk_pins_a &qspi_bk1_pins_a>;
+ pinctrl-1 = <&qspi_clk_sleep_pins_a &qspi_bk1_sleep_pins_a>;
+ reg = <0x58003000 0x1000>, <0x70000000 0x4000000>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "okay";
+
+ flash0: is25lp016d@0 {
+ compatible = "jedec,spi-nor";
+ reg = <0>;
+ spi-max-frequency = <133000000>;
+ spi-rx-bus-width = <1>;
+ spi-tx-bus-width = <1>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ };
+};
+
+&rng1 {
+ status = "okay";
+};
+
+&rtc {
+ status = "okay";
+};
+
+&sdmmc2 {
+ arm,primecell-periphid = <0x10153180>;
+ pinctrl-names = "default", "opendrain", "sleep";
+ pinctrl-0 = <&sdmmc2_b4_pins_b>;
+ pinctrl-1 = <&sdmmc2_b4_od_pins_b>;
+ pinctrl-2 = <&sdmmc2_b4_sleep_pins_a>;
+ non-removable;
+ st,neg-edge;
+ bus-width = <4>;
+ vmmc-supply = <&v3v3>;
+ status = "okay";
+};
+
+&spi1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi1_pins_a>;
+ cs-gpios = <&gpioz 3 0>;
+ status = "disabled";
+
+ spidev@0 {
+ compatible = "spidev";
+ reg = <0>;
+ spi-max-frequency = <100000>;
+ };
+};
+
+&timers1 {
+ /* spare dmas for other usage */
+ /delete-property/dmas;
+ /delete-property/dma-names;
+ pwm {
+ pinctrl-0 = <&pwm1_pins_b>;
+ pinctrl-1 = <&pwm1_sleep_pins_b>;
+ pinctrl-names = "default", "sleep";
+ status = "okay";
+ };
+ timer@0 {
+ status = "okay";
+ };
+};
+
+&timers4 {
+ /delete-property/dmas;
+ /delete-property/dma-names;
+ pwm {
+ pinctrl-0 = <&pwm4_pins_b>;
+ pinctrl-1 = <&pwm4_sleep_pins_b>;
+ pinctrl-names = "default", "sleep";
+ status = "okay";
+ };
+ timer@3 {
+ status = "okay";
+ };
+};
+
+&timers5 {
+ /delete-property/dmas;
+ /delete-property/dma-names;
+ pwm {
+ pinctrl-0 = <&pwm5_pins_a>;
+ pinctrl-1 = <&pwm5_sleep_pins_a>;
+ pinctrl-names = "default", "sleep";
+ status = "okay";
+ };
+ timer@4 {
+ status = "okay";
+ };
+};
+
+&uart4 {
+ pinctrl-names = "default", "sleep", "idle";
+ pinctrl-0 = <&uart4_pins_a>;
+ pinctrl-1 = <&uart4_sleep_pins_a>;
+ pinctrl-2 = <&uart4_idle_pins_a>;
+ status = "okay";
+};
+
+&usart2 {
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&usart2_pins_a>;
+ pinctrl-1 = <&usart2_sleep_pins_a>;
+ status = "okay";
+};
+
+&usart3 {
+ pinctrl-names = "default", "sleep", "idle";
+ pinctrl-0 = <&usart3_pins_d>;
+ pinctrl-1 = <&usart3_sleep_pins_d>;
+ pinctrl-2 = <&usart3_idle_pins_d>;
+ status = "okay";
+};
+
+&usbh_ehci {
+ phys = <&usbphyc_port0>;
+ phy-names = "usb";
+ status = "okay";
+};
+
+&usbh_ohci {
+ phys = <&usbphyc_port0>;
+ phy-names = "usb";
+ status = "okay";
+};
+
+&usbotg_hs {
+ dr_mode = "peripheral";
+ pinctrl-names = "default";
+ pinctrl-0 = <&usbotg_hs_pins_a>;
+ phy-names = "usb2-phy";
+ phys = <&usbphyc_port1 0>;
+ vbus-supply = <&vbus_otg>;
+ status = "okay";
+};
+
+&usbphyc {
+ status = "okay";
+};
+
+&usbphyc_port0 {
+ phy-supply = <&vdd_usb>;
+};
+
+&usbphyc_port1 {
+ phy-supply = <&vdd_usb>;
+};
+
+&vrefbuf {
+ regulator-min-microvolt = <2500000>;
+ regulator-max-microvolt = <2500000>;
+ vdda-supply = <&vdd>;
+ status = "okay";
+};
+
diff --git a/arch/arm/boot/dts/stm32mp157c-lxa-mc1.dts b/arch/arm/boot/dts/stm32mp157c-lxa-mc1.dts
index 1e9bf7eea0f1..e8d2ec41d537 100644
--- a/arch/arm/boot/dts/stm32mp157c-lxa-mc1.dts
+++ b/arch/arm/boot/dts/stm32mp157c-lxa-mc1.dts
@@ -248,5 +248,7 @@
&uart4 {
pinctrl-names = "default";
pinctrl-0 = <&uart4_pins_a>;
+ /delete-property/dmas;
+ /delete-property/dma-names;
status = "okay";
};
diff --git a/arch/arm/boot/dts/stm32mp157c-odyssey.dts b/arch/arm/boot/dts/stm32mp157c-odyssey.dts
index 554f5d3bcdc3..ed66d25b8bf3 100644
--- a/arch/arm/boot/dts/stm32mp157c-odyssey.dts
+++ b/arch/arm/boot/dts/stm32mp157c-odyssey.dts
@@ -81,6 +81,8 @@
&uart4 {
pinctrl-names = "default";
pinctrl-0 = <&uart4_pins_a>;
+ /delete-property/dmas;
+ /delete-property/dma-names;
status = "okay";
};
diff --git a/arch/arm/boot/dts/stm32mp15xx-dhcom-drc02.dtsi b/arch/arm/boot/dts/stm32mp15xx-dhcom-drc02.dtsi
index 4b10b013ffd5..35b1034aa3cf 100644
--- a/arch/arm/boot/dts/stm32mp15xx-dhcom-drc02.dtsi
+++ b/arch/arm/boot/dts/stm32mp15xx-dhcom-drc02.dtsi
@@ -131,6 +131,8 @@
&usart3 {
pinctrl-names = "default";
pinctrl-0 = <&usart3_pins_a>;
+ /delete-property/dmas;
+ /delete-property/dma-names;
status = "okay";
};
@@ -144,6 +146,8 @@
pinctrl-names = "default";
pinctrl-0 = <&uart8_pins_a>;
rts-gpios = <&gpioe 6 GPIO_ACTIVE_HIGH>;
+ /delete-property/dmas;
+ /delete-property/dma-names;
status = "okay";
};
diff --git a/arch/arm/boot/dts/stm32mp15xx-dhcom-pdk2.dtsi b/arch/arm/boot/dts/stm32mp15xx-dhcom-pdk2.dtsi
index fbf3826933e4..5f586f024060 100644
--- a/arch/arm/boot/dts/stm32mp15xx-dhcom-pdk2.dtsi
+++ b/arch/arm/boot/dts/stm32mp15xx-dhcom-pdk2.dtsi
@@ -287,6 +287,8 @@
&usart3 {
pinctrl-names = "default";
pinctrl-0 = <&usart3_pins_a>;
+ /delete-property/dmas;
+ /delete-property/dma-names;
status = "okay";
};
@@ -294,6 +296,8 @@
pinctrl-names = "default";
pinctrl-0 = <&uart8_pins_a &uart8_rtscts_pins_a>;
uart-has-rtscts;
+ /delete-property/dmas;
+ /delete-property/dma-names;
status = "okay";
};
diff --git a/arch/arm/boot/dts/stm32mp15xx-dhcom-picoitx.dtsi b/arch/arm/boot/dts/stm32mp15xx-dhcom-picoitx.dtsi
index ba816ef8b9b2..abc595350e71 100644
--- a/arch/arm/boot/dts/stm32mp15xx-dhcom-picoitx.dtsi
+++ b/arch/arm/boot/dts/stm32mp15xx-dhcom-picoitx.dtsi
@@ -105,12 +105,16 @@
&usart3 {
pinctrl-names = "default";
pinctrl-0 = <&usart3_pins_a>;
+ /delete-property/dmas;
+ /delete-property/dma-names;
status = "okay";
};
&uart8 {
pinctrl-names = "default";
pinctrl-0 = <&uart8_pins_a &uart8_rtscts_pins_a>;
+ /delete-property/dmas;
+ /delete-property/dma-names;
status = "okay";
};
diff --git a/arch/arm/boot/dts/stm32mp15xx-dhcom-som.dtsi b/arch/arm/boot/dts/stm32mp15xx-dhcom-som.dtsi
index 8c41f819f776..83e2c87713f8 100644
--- a/arch/arm/boot/dts/stm32mp15xx-dhcom-som.dtsi
+++ b/arch/arm/boot/dts/stm32mp15xx-dhcom-som.dtsi
@@ -196,7 +196,6 @@
"", "", "DHCOM-E", "",
"", "", "", "",
"", "", "", "";
- status = "okay";
};
&gpiod {
@@ -521,5 +520,7 @@
&uart4 {
pinctrl-names = "default";
pinctrl-0 = <&uart4_pins_a>;
+ /delete-property/dmas;
+ /delete-property/dma-names;
status = "okay";
};
diff --git a/arch/arm/boot/dts/stm32mp15xx-dhcor-avenger96.dtsi b/arch/arm/boot/dts/stm32mp15xx-dhcor-avenger96.dtsi
index 6885948f3024..61e17f44ce81 100644
--- a/arch/arm/boot/dts/stm32mp15xx-dhcor-avenger96.dtsi
+++ b/arch/arm/boot/dts/stm32mp15xx-dhcor-avenger96.dtsi
@@ -376,6 +376,8 @@
label = "LS-UART1";
pinctrl-names = "default";
pinctrl-0 = <&uart4_pins_b>;
+ /delete-property/dmas;
+ /delete-property/dma-names;
status = "okay";
};
@@ -385,6 +387,8 @@
pinctrl-names = "default";
pinctrl-0 = <&uart7_pins_a>;
uart-has-rtscts;
+ /delete-property/dmas;
+ /delete-property/dma-names;
status = "okay";
};
@@ -394,6 +398,8 @@
pinctrl-0 = <&usart2_pins_a>;
pinctrl-1 = <&usart2_sleep_pins_a>;
st,hw-flow-ctrl;
+ /delete-property/dmas;
+ /delete-property/dma-names;
status = "okay";
bluetooth {
diff --git a/arch/arm/boot/dts/stm32mp15xx-dhcor-som.dtsi b/arch/arm/boot/dts/stm32mp15xx-dhcor-som.dtsi
index 44ecc4708587..6336c3ca0f0e 100644
--- a/arch/arm/boot/dts/stm32mp15xx-dhcor-som.dtsi
+++ b/arch/arm/boot/dts/stm32mp15xx-dhcor-som.dtsi
@@ -19,6 +19,48 @@
device_type = "memory";
reg = <0xc0000000 0x40000000>;
};
+
+ reserved-memory {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ mcuram2: mcuram2@10000000 {
+ compatible = "shared-dma-pool";
+ reg = <0x10000000 0x40000>;
+ no-map;
+ };
+
+ vdev0vring0: vdev0vring0@10040000 {
+ compatible = "shared-dma-pool";
+ reg = <0x10040000 0x1000>;
+ no-map;
+ };
+
+ vdev0vring1: vdev0vring1@10041000 {
+ compatible = "shared-dma-pool";
+ reg = <0x10041000 0x1000>;
+ no-map;
+ };
+
+ vdev0buffer: vdev0buffer@10042000 {
+ compatible = "shared-dma-pool";
+ reg = <0x10042000 0x4000>;
+ no-map;
+ };
+
+ mcuram: mcuram@30000000 {
+ compatible = "shared-dma-pool";
+ reg = <0x30000000 0x40000>;
+ no-map;
+ };
+
+ retram: retram@38000000 {
+ compatible = "shared-dma-pool";
+ reg = <0x38000000 0x10000>;
+ no-map;
+ };
+ };
};
&crc1 {
@@ -179,11 +221,25 @@
};
};
+&ipcc {
+ status = "okay";
+};
+
&iwdg2 {
timeout-sec = <32>;
status = "okay";
};
+&m4_rproc {
+ memory-region = <&retram>, <&mcuram>, <&mcuram2>, <&vdev0vring0>,
+ <&vdev0vring1>, <&vdev0buffer>;
+ mboxes = <&ipcc 0>, <&ipcc 1>, <&ipcc 2>;
+ mbox-names = "vq0", "vq1", "shutdown";
+ interrupt-parent = <&exti>;
+ interrupts = <68 1>;
+ status = "okay";
+};
+
&pwr_regulators {
vdd-supply = <&vdd>;
vdd_3v3_usbfs-supply = <&vdd_usb>;
diff --git a/arch/arm/boot/dts/stm32mp15xx-dkx.dtsi b/arch/arm/boot/dts/stm32mp15xx-dkx.dtsi
index 6caeb448c190..333c2af97130 100644
--- a/arch/arm/boot/dts/stm32mp15xx-dkx.dtsi
+++ b/arch/arm/boot/dts/stm32mp15xx-dkx.dtsi
@@ -650,6 +650,8 @@
pinctrl-0 = <&uart4_pins_a>;
pinctrl-1 = <&uart4_sleep_pins_a>;
pinctrl-2 = <&uart4_idle_pins_a>;
+ /delete-property/dmas;
+ /delete-property/dma-names;
status = "okay";
};
@@ -658,6 +660,8 @@
pinctrl-0 = <&uart7_pins_c>;
pinctrl-1 = <&uart7_sleep_pins_c>;
pinctrl-2 = <&uart7_idle_pins_c>;
+ /delete-property/dmas;
+ /delete-property/dma-names;
status = "disabled";
};
diff --git a/arch/arm/boot/dts/sun7i-a20-haoyu-marsboard.dts b/arch/arm/boot/dts/sun7i-a20-haoyu-marsboard.dts
new file mode 100644
index 000000000000..097e479c2772
--- /dev/null
+++ b/arch/arm/boot/dts/sun7i-a20-haoyu-marsboard.dts
@@ -0,0 +1,182 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright 2021 Conley Lee
+ * Conley Lee <conleylee@foxmail.com>
+ */
+
+/dts-v1/;
+#include "sun7i-a20.dtsi"
+#include "sunxi-common-regulators.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+
+/ {
+ model = "HAOYU Electronics Marsboard A20";
+ compatible = "haoyu,a20-marsboard", "allwinner,sun7i-a20";
+
+ aliases {
+ serial0 = &uart0;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+
+ hdmi-connector {
+ compatible = "hdmi-connector";
+ type = "a";
+
+ port {
+ hdmi_con_in: endpoint {
+ remote-endpoint = <&hdmi_out_con>;
+ };
+ };
+ };
+};
+
+&ahci {
+ target-supply = <&reg_ahci_5v>;
+ status = "okay";
+};
+
+&codec {
+ status = "okay";
+};
+
+&cpu0 {
+ cpu-supply = <&reg_dcdc2>;
+};
+
+&de {
+ status = "okay";
+};
+
+&ehci0 {
+ status = "okay";
+};
+
+&ehci1 {
+ status = "okay";
+};
+
+&gmac {
+ pinctrl-names = "default";
+ pinctrl-0 = <&gmac_mii_pins>, <&gmac_txerr>;
+ phy-handle = <&phy0>;
+ phy-mode = "mii";
+ status = "okay";
+};
+
+&hdmi {
+ status = "okay";
+};
+
+&hdmi_out {
+ hdmi_out_con: endpoint {
+ remote-endpoint = <&hdmi_con_in>;
+ };
+};
+
+&i2c0 {
+ status = "okay";
+
+ axp209: pmic@34 {
+ reg = <0x34>;
+ interrupt-parent = <&nmi_intc>;
+ interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
+ };
+};
+
+&mmc0 {
+ vmmc-supply = <&reg_vcc3v3>;
+ bus-width = <4>;
+ cd-gpios = <&pio 7 10 GPIO_ACTIVE_LOW>; /* PH10 */
+ status = "okay";
+};
+
+&gmac_mdio {
+ phy0: ethernet-phy@0 {
+ reg = <0>;
+ };
+};
+
+&ohci0 {
+ status = "okay";
+};
+
+&ohci1 {
+ status = "okay";
+};
+
+&otg_sram {
+ status = "okay";
+};
+
+&pio {
+ gmac_txerr: gmac-txerr-pin {
+ pins = "PA17";
+ function = "gmac";
+ };
+};
+
+&reg_ahci_5v {
+ status = "okay";
+};
+
+#include "axp209.dtsi"
+
+&ac_power_supply {
+ status = "okay";
+};
+
+&reg_dcdc2 {
+ regulator-always-on;
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1450000>;
+ regulator-name = "vdd-cpu";
+};
+
+&reg_dcdc3 {
+ regulator-always-on;
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1400000>;
+ regulator-name = "vdd-int-dll";
+};
+
+&reg_ldo1 {
+ regulator-name = "vdd-rtc";
+};
+
+&reg_ldo2 {
+ regulator-always-on;
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3000000>;
+ regulator-name = "avcc";
+};
+
+&reg_usb1_vbus {
+ status = "okay";
+};
+
+&reg_usb2_vbus {
+ status = "okay";
+};
+
+&uart0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0_pb_pins>;
+ status = "okay";
+};
+
+&usb_otg {
+ dr_mode = "otg";
+ status = "okay";
+};
+
+&usbphy {
+ usb0_id_det-gpios = <&pio 7 4 (GPIO_ACTIVE_HIGH | GPIO_PULL_UP)>; /* PH4 */
+ usb1_vbus-supply = <&reg_usb1_vbus>;
+ usb2_vbus-supply = <&reg_usb2_vbus>;
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/sun8i-h3-nanopi-neo-air.dts b/arch/arm/boot/dts/sun8i-h3-nanopi-neo-air.dts
index be49eabbff94..cd3df12b6573 100644
--- a/arch/arm/boot/dts/sun8i-h3-nanopi-neo-air.dts
+++ b/arch/arm/boot/dts/sun8i-h3-nanopi-neo-air.dts
@@ -103,12 +103,40 @@
};
};
+&mmc2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc2_8bit_pins>;
+ vmmc-supply = <&reg_vcc3v3>;
+ vqmmc-supply = <&reg_vcc3v3>;
+ bus-width = <8>;
+ non-removable;
+ status = "okay";
+};
+
&uart0 {
pinctrl-names = "default";
pinctrl-0 = <&uart0_pa_pins>;
status = "okay";
};
+&uart3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart3_pins>, <&uart3_rts_cts_pins>;
+ uart-has-rtscts;
+ status = "okay";
+
+ bluetooth {
+ compatible = "brcm,bcm43438-bt";
+ clocks = <&rtc 1>;
+ clock-names = "lpo";
+ vbat-supply = <&reg_vcc3v3>;
+ vddio-supply = <&reg_vcc3v3>;
+ device-wakeup-gpios = <&pio 0 8 GPIO_ACTIVE_HIGH>; /* PA8 */
+ host-wakeup-gpios = <&pio 0 7 GPIO_ACTIVE_HIGH>; /* PA7 */
+ shutdown-gpios = <&pio 6 13 GPIO_ACTIVE_HIGH>; /* PG13 */
+ };
+};
+
&usbphy {
/* USB VBUS is always on */
status = "okay";
diff --git a/arch/arm/boot/dts/sun8i-h3-nanopi-neo.dts b/arch/arm/boot/dts/sun8i-h3-nanopi-neo.dts
index 9f33f6fae595..df71fab3cf4e 100644
--- a/arch/arm/boot/dts/sun8i-h3-nanopi-neo.dts
+++ b/arch/arm/boot/dts/sun8i-h3-nanopi-neo.dts
@@ -45,6 +45,10 @@
/ {
model = "FriendlyARM NanoPi NEO";
compatible = "friendlyarm,nanopi-neo", "allwinner,sun8i-h3";
+
+ aliases {
+ ethernet0 = &emac;
+ };
};
&ehci0 {
diff --git a/arch/arm/boot/dts/sun8i-h3.dtsi b/arch/arm/boot/dts/sun8i-h3.dtsi
index 845f25235407..eac2349a2380 100644
--- a/arch/arm/boot/dts/sun8i-h3.dtsi
+++ b/arch/arm/boot/dts/sun8i-h3.dtsi
@@ -245,7 +245,7 @@
cpu_thermal: cpu-thermal {
polling-delay-passive = <0>;
polling-delay = <0>;
- thermal-sensors = <&ths 0>;
+ thermal-sensors = <&ths>;
trips {
cpu_hot_trip: cpu-hot {
diff --git a/arch/arm/boot/dts/sun8i-v3s.dtsi b/arch/arm/boot/dts/sun8i-v3s.dtsi
index b30bc1a25ebb..084323d5c61c 100644
--- a/arch/arm/boot/dts/sun8i-v3s.dtsi
+++ b/arch/arm/boot/dts/sun8i-v3s.dtsi
@@ -593,6 +593,17 @@
#size-cells = <0>;
};
+ gic: interrupt-controller@1c81000 {
+ compatible = "arm,gic-400";
+ reg = <0x01c81000 0x1000>,
+ <0x01c82000 0x2000>,
+ <0x01c84000 0x2000>,
+ <0x01c86000 0x2000>;
+ interrupt-controller;
+ #interrupt-cells = <3>;
+ interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
+ };
+
csi1: camera@1cb4000 {
compatible = "allwinner,sun8i-v3s-csi";
reg = <0x01cb4000 0x3000>;
@@ -604,16 +615,5 @@
resets = <&ccu RST_BUS_CSI>;
status = "disabled";
};
-
- gic: interrupt-controller@1c81000 {
- compatible = "arm,gic-400";
- reg = <0x01c81000 0x1000>,
- <0x01c82000 0x2000>,
- <0x01c84000 0x2000>,
- <0x01c86000 0x2000>;
- interrupt-controller;
- #interrupt-cells = <3>;
- interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
- };
};
};
diff --git a/arch/arm/boot/dts/sunxi-h3-h5.dtsi b/arch/arm/boot/dts/sunxi-h3-h5.dtsi
index 4aeca9e7e30d..d7e9f977f986 100644
--- a/arch/arm/boot/dts/sunxi-h3-h5.dtsi
+++ b/arch/arm/boot/dts/sunxi-h3-h5.dtsi
@@ -913,6 +913,19 @@
#size-cells = <0>;
};
+ r_uart: serial@1f02800 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0x01f02800 0x400>;
+ interrupts = <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ clocks = <&r_ccu CLK_APB0_UART>;
+ resets = <&r_ccu RST_APB0_UART>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&r_uart_pins>;
+ status = "disabled";
+ };
+
r_pio: pinctrl@1f02c00 {
compatible = "allwinner,sun8i-h3-r-pinctrl";
reg = <0x01f02c00 0x400>;
@@ -939,6 +952,11 @@
pins = "PL10";
function = "s_pwm";
};
+
+ r_uart_pins: r-uart-pins {
+ pins = "PL2", "PL3";
+ function = "s_uart";
+ };
};
r_pwm: pwm@1f03800 {
diff --git a/arch/arm/boot/dts/tegra124-nyan-big-fhd.dts b/arch/arm/boot/dts/tegra124-nyan-big-fhd.dts
index d35fb79d2f51..4db43324dafa 100644
--- a/arch/arm/boot/dts/tegra124-nyan-big-fhd.dts
+++ b/arch/arm/boot/dts/tegra124-nyan-big-fhd.dts
@@ -5,7 +5,13 @@
/ {
/* Version of Nyan Big with 1080p panel */
- panel {
- compatible = "auo,b133htn01";
+ host1x@50000000 {
+ dpaux@545c0000 {
+ aux-bus {
+ panel: panel {
+ compatible = "auo,b133htn01";
+ };
+ };
+ };
};
};
diff --git a/arch/arm/boot/dts/tegra124-nyan-big.dts b/arch/arm/boot/dts/tegra124-nyan-big.dts
index 1d2aac2cb6d0..fdc1d64dfff9 100644
--- a/arch/arm/boot/dts/tegra124-nyan-big.dts
+++ b/arch/arm/boot/dts/tegra124-nyan-big.dts
@@ -13,12 +13,15 @@
"google,nyan-big-rev1", "google,nyan-big-rev0",
"google,nyan-big", "google,nyan", "nvidia,tegra124";
- panel: panel {
- compatible = "auo,b133xtn01";
-
- power-supply = <&vdd_3v3_panel>;
- backlight = <&backlight>;
- ddc-i2c-bus = <&dpaux>;
+ host1x@50000000 {
+ dpaux@545c0000 {
+ aux-bus {
+ panel: panel {
+ compatible = "auo,b133xtn01";
+ backlight = <&backlight>;
+ };
+ };
+ };
};
mmc@700b0400 { /* SD Card on this bus */
diff --git a/arch/arm/boot/dts/tegra124-nyan-blaze.dts b/arch/arm/boot/dts/tegra124-nyan-blaze.dts
index 677babde6460..abdf4456826f 100644
--- a/arch/arm/boot/dts/tegra124-nyan-blaze.dts
+++ b/arch/arm/boot/dts/tegra124-nyan-blaze.dts
@@ -15,12 +15,15 @@
"google,nyan-blaze-rev0", "google,nyan-blaze",
"google,nyan", "nvidia,tegra124";
- panel: panel {
- compatible = "samsung,ltn140at29-301";
-
- power-supply = <&vdd_3v3_panel>;
- backlight = <&backlight>;
- ddc-i2c-bus = <&dpaux>;
+ host1x@50000000 {
+ dpaux@545c0000 {
+ aux-bus {
+ panel: panel {
+ compatible = "samsung,ltn140at29-301";
+ backlight = <&backlight>;
+ };
+ };
+ };
};
sound {
diff --git a/arch/arm/boot/dts/tegra124-venice2.dts b/arch/arm/boot/dts/tegra124-venice2.dts
index 232c90604df9..6a9592ceb5f2 100644
--- a/arch/arm/boot/dts/tegra124-venice2.dts
+++ b/arch/arm/boot/dts/tegra124-venice2.dts
@@ -48,6 +48,13 @@
dpaux@545c0000 {
vdd-supply = <&vdd_3v3_panel>;
status = "okay";
+
+ aux-bus {
+ panel: panel {
+ compatible = "lg,lp129qe";
+ backlight = <&backlight>;
+ };
+ };
};
};
@@ -1080,13 +1087,6 @@
};
};
- panel: panel {
- compatible = "lg,lp129qe";
- power-supply = <&vdd_3v3_panel>;
- backlight = <&backlight>;
- ddc-i2c-bus = <&dpaux>;
- };
-
vdd_mux: regulator-mux {
compatible = "regulator-fixed";
regulator-name = "+VDD_MUX";
diff --git a/arch/arm/boot/dts/tegra20-asus-tf101.dts b/arch/arm/boot/dts/tegra20-asus-tf101.dts
index 020172ee7340..a054d39db466 100644
--- a/arch/arm/boot/dts/tegra20-asus-tf101.dts
+++ b/arch/arm/boot/dts/tegra20-asus-tf101.dts
@@ -436,17 +436,27 @@
};
};
+ spdif@70002400 {
+ status = "okay";
+
+ nvidia,fixed-parent-rate;
+ };
+
i2s@70002800 {
status = "okay";
+
+ nvidia,fixed-parent-rate;
};
serial@70006040 {
compatible = "nvidia,tegra20-hsuart";
+ /delete-property/ reg-shift;
/* GPS BCM4751 */
};
serial@70006200 {
compatible = "nvidia,tegra20-hsuart";
+ /delete-property/ reg-shift;
status = "okay";
/* Azurewave AW-NH615 BCM4329B1 */
@@ -756,7 +766,7 @@
lpddr2 {
compatible = "elpida,B8132B2PB-6D-F", "jedec,lpddr2-s4";
- revision-id1 = <1>;
+ revision-id = <1 0>;
density = <2048>;
io-width = <16>;
};
diff --git a/arch/arm/boot/dts/tegra20-colibri.dtsi b/arch/arm/boot/dts/tegra20-colibri.dtsi
index 1eefb9ee4ac8..8ebd8afc857d 100644
--- a/arch/arm/boot/dts/tegra20-colibri.dtsi
+++ b/arch/arm/boot/dts/tegra20-colibri.dtsi
@@ -691,7 +691,7 @@
#address-cells = <1>;
#size-cells = <0>;
- asix@1 {
+ ethernet@1 {
compatible = "usbb95,772b";
reg = <1>;
local-mac-address = [00 00 00 00 00 00];
diff --git a/arch/arm/boot/dts/tegra20-paz00.dts b/arch/arm/boot/dts/tegra20-paz00.dts
index d53a175dc17a..0fb4b1f5bc1c 100644
--- a/arch/arm/boot/dts/tegra20-paz00.dts
+++ b/arch/arm/boot/dts/tegra20-paz00.dts
@@ -13,6 +13,8 @@
compatible = "compal,paz00", "nvidia,tegra20";
aliases {
+ mmc0 = &sdmmc4; /* eMMC */
+ mmc1 = &sdmmc1; /* MicroSD */
rtc0 = "/i2c@7000d000/tps6586x@34";
rtc1 = "/rtc@7000e000";
serial0 = &uarta;
@@ -558,7 +560,7 @@
status = "okay";
};
- mmc@c8000000 {
+ sdmmc1: mmc@c8000000 {
status = "okay";
cd-gpios = <&gpio TEGRA_GPIO(V, 5) GPIO_ACTIVE_LOW>;
wp-gpios = <&gpio TEGRA_GPIO(H, 1) GPIO_ACTIVE_HIGH>;
@@ -566,7 +568,7 @@
bus-width = <4>;
};
- mmc@c8000600 {
+ sdmmc4: mmc@c8000600 {
status = "okay";
bus-width = <8>;
non-removable;
diff --git a/arch/arm/boot/dts/tegra20-tamonten.dtsi b/arch/arm/boot/dts/tegra20-tamonten.dtsi
index de39c5465c0a..0e19bd0a847c 100644
--- a/arch/arm/boot/dts/tegra20-tamonten.dtsi
+++ b/arch/arm/boot/dts/tegra20-tamonten.dtsi
@@ -183,8 +183,8 @@
};
conf_ata {
nvidia,pins = "ata", "atb", "atc", "atd", "ate",
- "cdev1", "cdev2", "dap1", "dtb", "gma",
- "gmb", "gmc", "gmd", "gme", "gpu7",
+ "cdev1", "cdev2", "dap1", "dtb", "dtf",
+ "gma", "gmb", "gmc", "gmd", "gme", "gpu7",
"gpv", "i2cp", "irrx", "irtx", "pta",
"rm", "slxa", "slxk", "spia", "spib",
"uac";
@@ -203,7 +203,7 @@
};
conf_crtp {
nvidia,pins = "crtp", "dap2", "dap3", "dap4",
- "dtc", "dte", "dtf", "gpu", "sdio1",
+ "dtc", "dte", "gpu", "sdio1",
"slxc", "slxd", "spdi", "spdo", "spig",
"uda";
nvidia,pull = <TEGRA_PIN_PULL_NONE>;
diff --git a/arch/arm/boot/dts/tegra30-asus-tf700t.dts b/arch/arm/boot/dts/tegra30-asus-tf700t.dts
index 18a9bfa5e97b..1a331dec3cfe 100644
--- a/arch/arm/boot/dts/tegra30-asus-tf700t.dts
+++ b/arch/arm/boot/dts/tegra30-asus-tf700t.dts
@@ -742,7 +742,7 @@
#address-cells = <1>;
#size-cells = <0>;
- dsi-bridge@7 {
+ dsi@7 {
compatible = "toshiba,tc358768";
reg = <0x7>;
diff --git a/arch/arm/boot/dts/tegra30-asus-transformer-common.dtsi b/arch/arm/boot/dts/tegra30-asus-transformer-common.dtsi
index 85b43a86a26d..c662ab261ed5 100644
--- a/arch/arm/boot/dts/tegra30-asus-transformer-common.dtsi
+++ b/arch/arm/boot/dts/tegra30-asus-transformer-common.dtsi
@@ -1080,6 +1080,7 @@
serial@70006040 {
compatible = "nvidia,tegra30-hsuart";
+ /delete-property/ reg-shift;
status = "okay";
/* Broadcom GPS BCM47511 */
@@ -1087,6 +1088,7 @@
serial@70006200 {
compatible = "nvidia,tegra30-hsuart";
+ /delete-property/ reg-shift;
status = "okay";
nvidia,adjust-baud-rates = <0 9600 100>,
diff --git a/arch/arm/boot/dts/tegra30-colibri.dtsi b/arch/arm/boot/dts/tegra30-colibri.dtsi
index be691a1c33a1..22231d450b1b 100644
--- a/arch/arm/boot/dts/tegra30-colibri.dtsi
+++ b/arch/arm/boot/dts/tegra30-colibri.dtsi
@@ -960,7 +960,7 @@
#address-cells = <1>;
#size-cells = <0>;
- asix@1 {
+ ethernet@1 {
compatible = "usbb95,772b";
reg = <1>;
local-mac-address = [00 00 00 00 00 00];
diff --git a/arch/arm/boot/dts/tegra30-ouya.dts b/arch/arm/boot/dts/tegra30-ouya.dts
index a5cfbab5f565..e58dda4f9d2c 100644
--- a/arch/arm/boot/dts/tegra30-ouya.dts
+++ b/arch/arm/boot/dts/tegra30-ouya.dts
@@ -4553,7 +4553,7 @@
#address-cells = <1>;
#size-cells = <0>;
- smsc@2 { /* SMSC 10/100T Ethernet Controller */
+ ethernet@2 { /* SMSC 10/100T Ethernet Controller */
compatible = "usb424,9e00";
reg = <2>;
local-mac-address = [00 11 22 33 44 55];
diff --git a/arch/arm/boot/dts/tegra30-pegatron-chagall.dts b/arch/arm/boot/dts/tegra30-pegatron-chagall.dts
index f4b2d4218849..8ce61035290b 100644
--- a/arch/arm/boot/dts/tegra30-pegatron-chagall.dts
+++ b/arch/arm/boot/dts/tegra30-pegatron-chagall.dts
@@ -1103,6 +1103,7 @@
uartb: serial@70006040 {
compatible = "nvidia,tegra30-hsuart";
+ /delete-property/ reg-shift;
status = "okay";
/* Broadcom GPS BCM47511 */
@@ -1110,6 +1111,7 @@
uartc: serial@70006200 {
compatible = "nvidia,tegra30-hsuart";
+ /delete-property/ reg-shift;
status = "okay";
nvidia,adjust-baud-rates = <0 9600 100>,
diff --git a/arch/arm/boot/dts/vf-colibri-eval-v3.dtsi b/arch/arm/boot/dts/vf-colibri-eval-v3.dtsi
index c12a1b8bc086..14c411f146f5 100644
--- a/arch/arm/boot/dts/vf-colibri-eval-v3.dtsi
+++ b/arch/arm/boot/dts/vf-colibri-eval-v3.dtsi
@@ -103,7 +103,7 @@
status = "okay";
/* M41T0M6 real time clock on carrier board */
- rtc: m41t0m6@68 {
+ rtc: rtc@68 {
compatible = "st,m41t0";
reg = <0x68>;
};
diff --git a/arch/arm/configs/davinci_all_defconfig b/arch/arm/configs/davinci_all_defconfig
index e849367c0566..b58d45a03607 100644
--- a/arch/arm/configs/davinci_all_defconfig
+++ b/arch/arm/configs/davinci_all_defconfig
@@ -258,7 +258,6 @@ CONFIG_MINIX_FS=m
CONFIG_NFS_FS=y
CONFIG_ROOT_NFS=y
CONFIG_NFSD=m
-CONFIG_NFSD_V3=y
CONFIG_NLS_CODEPAGE_437=y
CONFIG_NLS_ASCII=m
CONFIG_NLS_ISO8859_1=y
diff --git a/arch/arm/configs/exynos_defconfig b/arch/arm/configs/exynos_defconfig
index cae09010a799..aa061074db78 100644
--- a/arch/arm/configs/exynos_defconfig
+++ b/arch/arm/configs/exynos_defconfig
@@ -158,6 +158,7 @@ CONFIG_CHARGER_MAX14577=y
CONFIG_CHARGER_MAX77693=y
CONFIG_CHARGER_MAX8997=y
CONFIG_CHARGER_MAX8998=y
+CONFIG_CHARGER_SMB347=y
CONFIG_CHARGER_TPS65090=y
CONFIG_SENSORS_LM90=y
CONFIG_SENSORS_NTC_THERMISTOR=y
diff --git a/arch/arm/configs/ezx_defconfig b/arch/arm/configs/ezx_defconfig
index ec84d80096b1..0788a892e160 100644
--- a/arch/arm/configs/ezx_defconfig
+++ b/arch/arm/configs/ezx_defconfig
@@ -309,7 +309,6 @@ CONFIG_NFS_FS=y
CONFIG_NFS_V3=y
CONFIG_NFS_V3_ACL=y
CONFIG_NFSD=m
-CONFIG_NFSD_V3=y
CONFIG_NFSD_V3_ACL=y
CONFIG_SMB_FS=m
CONFIG_CIFS=m
diff --git a/arch/arm/configs/imote2_defconfig b/arch/arm/configs/imote2_defconfig
index 6db871d4e077..015b7ef237de 100644
--- a/arch/arm/configs/imote2_defconfig
+++ b/arch/arm/configs/imote2_defconfig
@@ -283,7 +283,6 @@ CONFIG_NFS_FS=y
CONFIG_NFS_V3=y
CONFIG_NFS_V3_ACL=y
CONFIG_NFSD=m
-CONFIG_NFSD_V3=y
CONFIG_NFSD_V3_ACL=y
CONFIG_SMB_FS=m
CONFIG_CIFS=m
diff --git a/arch/arm/configs/imxrt_defconfig b/arch/arm/configs/imxrt_defconfig
new file mode 100644
index 000000000000..52dba3762996
--- /dev/null
+++ b/arch/arm/configs/imxrt_defconfig
@@ -0,0 +1,35 @@
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_BPF_SYSCALL=y
+CONFIG_SCHED_AUTOGROUP=y
+# CONFIG_MMU is not set
+CONFIG_ARCH_MXC=y
+CONFIG_SOC_IMXRT=y
+CONFIG_SET_MEM_PARAM=y
+CONFIG_DRAM_BASE=0x80000000
+CONFIG_DRAM_SIZE=0x02000000
+CONFIG_BINFMT_FLAT=y
+CONFIG_UEVENT_HELPER=y
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+CONFIG_IMX_WEIM=y
+CONFIG_LEGACY_PTY_COUNT=2
+CONFIG_SERIAL_FSL_LPUART=y
+CONFIG_SERIAL_FSL_LPUART_CONSOLE=y
+CONFIG_SERIAL_DEV_BUS=y
+CONFIG_PINCTRL_IMXRT1050=y
+CONFIG_GPIO_MXC=y
+CONFIG_MMC=y
+CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SDHCI_PLTFM=y
+CONFIG_MMC_SDHCI_ESDHC_IMX=y
+CONFIG_DMADEVICES=y
+CONFIG_FSL_EDMA=y
+CONFIG_CLK_IMXRT1050=y
+CONFIG_EXT4_FS=y
+CONFIG_EXT4_FS_POSIX_ACL=y
+CONFIG_EXT4_FS_SECURITY=y
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_UTF8=y
+CONFIG_EXFAT_FS=y
+CONFIG_NLS_ASCII=y
+CONFIG_NLS_UTF8=y
diff --git a/arch/arm/configs/integrator_defconfig b/arch/arm/configs/integrator_defconfig
index 4dfe321a79f6..5b485722ccf9 100644
--- a/arch/arm/configs/integrator_defconfig
+++ b/arch/arm/configs/integrator_defconfig
@@ -79,7 +79,6 @@ CONFIG_CRAMFS=y
CONFIG_NFS_FS=y
CONFIG_ROOT_NFS=y
CONFIG_NFSD=y
-CONFIG_NFSD_V3=y
CONFIG_NLS_CODEPAGE_437=y
CONFIG_NLS_ISO8859_1=y
CONFIG_MAGIC_SYSRQ=y
diff --git a/arch/arm/configs/iop32x_defconfig b/arch/arm/configs/iop32x_defconfig
index 18a21faa834c..de2cc6759cae 100644
--- a/arch/arm/configs/iop32x_defconfig
+++ b/arch/arm/configs/iop32x_defconfig
@@ -94,7 +94,6 @@ CONFIG_NFS_FS=y
CONFIG_NFS_V3=y
CONFIG_ROOT_NFS=y
CONFIG_NFSD=y
-CONFIG_NFSD_V3=y
CONFIG_PARTITION_ADVANCED=y
CONFIG_MAGIC_SYSRQ=y
CONFIG_DEBUG_KERNEL=y
diff --git a/arch/arm/configs/keystone_defconfig b/arch/arm/configs/keystone_defconfig
index 33c917df7b32..b1bcb858216b 100644
--- a/arch/arm/configs/keystone_defconfig
+++ b/arch/arm/configs/keystone_defconfig
@@ -213,7 +213,6 @@ CONFIG_NFS_FS=y
CONFIG_NFS_V3_ACL=y
CONFIG_ROOT_NFS=y
CONFIG_NFSD=y
-CONFIG_NFSD_V3=y
CONFIG_NFSD_V3_ACL=y
CONFIG_NLS_CODEPAGE_437=y
CONFIG_NLS_ISO8859_1=y
diff --git a/arch/arm/configs/lart_defconfig b/arch/arm/configs/lart_defconfig
index b6ddb9884326..2dfa33d7dca3 100644
--- a/arch/arm/configs/lart_defconfig
+++ b/arch/arm/configs/lart_defconfig
@@ -59,7 +59,6 @@ CONFIG_CRAMFS=m
CONFIG_NFS_FS=m
CONFIG_NFS_V3=y
CONFIG_NFSD=m
-CONFIG_NFSD_V3=y
CONFIG_NLS=y
CONFIG_NLS_CODEPAGE_437=m
CONFIG_NLS_CODEPAGE_850=m
diff --git a/arch/arm/configs/multi_v5_defconfig b/arch/arm/configs/multi_v5_defconfig
index fe8d760256a4..70241ad2b550 100644
--- a/arch/arm/configs/multi_v5_defconfig
+++ b/arch/arm/configs/multi_v5_defconfig
@@ -24,11 +24,6 @@ CONFIG_MACH_DM355_LEOPARD=y
CONFIG_MACH_MITYOMAPL138=y
CONFIG_MACH_OMAPL138_HAWKBOARD=y
CONFIG_ARCH_MXC=y
-CONFIG_MACH_MX21ADS=y
-CONFIG_MACH_MX27ADS=y
-CONFIG_MACH_MX27_3DS=y
-CONFIG_MACH_IMX27_VISSTRIM_M10=y
-CONFIG_MACH_PCA100=y
CONFIG_SOC_IMX25=y
CONFIG_SOC_IMX27=y
CONFIG_ARCH_MVEBU=y
@@ -57,11 +52,9 @@ CONFIG_MACH_WNR854T=y
CONFIG_MACH_RD88F5181L_GE=y
CONFIG_MACH_RD88F5181L_FXO=y
CONFIG_MACH_RD88F6183AP_GE=y
-CONFIG_ARCH_U300=y
+CONFIG_ARCH_SUNXI=y
CONFIG_AEABI=y
CONFIG_HIGHMEM=y
-CONFIG_ZBOOT_ROM_TEXT=0x0
-CONFIG_ZBOOT_ROM_BSS=0x0
CONFIG_ARM_APPENDED_DTB=y
CONFIG_ARM_ATAG_DTB_COMPAT=y
CONFIG_CPU_FREQ=y
@@ -85,6 +78,8 @@ CONFIG_NET_PKTGEN=m
CONFIG_CFG80211=y
CONFIG_MAC80211=y
CONFIG_PCI_MVEBU=y
+CONFIG_ARCH_VERSATILE=y
+CONFIG_PCI_VERSATILE=y
CONFIG_DEVTMPFS=y
CONFIG_DEVTMPFS_MOUNT=y
CONFIG_IMX_WEIM=y
@@ -111,6 +106,9 @@ CONFIG_EEPROM_AT24=y
# CONFIG_SCSI_PROC_FS is not set
CONFIG_BLK_DEV_SD=y
CONFIG_BLK_DEV_SR=m
+CONFIG_VIRTIO_PCI=y
+CONFIG_VIRTIO_MMIO=y
+CONFIG_VIRTIO_BLK=y
CONFIG_CHR_DEV_SG=m
CONFIG_ATA=y
CONFIG_SATA_AHCI=y
@@ -143,7 +141,10 @@ CONFIG_SERIAL_8250_RUNTIME_UARTS=6
CONFIG_SERIAL_8250_EXTENDED=y
CONFIG_SERIAL_8250_MANY_PORTS=y
CONFIG_SERIAL_8250_ASPEED_VUART=m
+CONFIG_SERIAL_8250_DW=y
CONFIG_SERIAL_OF_PLATFORM=y
+CONFIG_SERIAL_AMBA_PL011=y
+CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
CONFIG_SERIAL_ATMEL=y
CONFIG_SERIAL_ATMEL_CONSOLE=y
CONFIG_SERIAL_ATMEL_TTYAT=y
@@ -159,11 +160,11 @@ CONFIG_I2C_ASPEED=m
CONFIG_I2C_AT91=y
CONFIG_I2C_IMX=y
CONFIG_I2C_MV64XXX=y
-CONFIG_I2C_NOMADIK=y
CONFIG_SPI=y
CONFIG_SPI_ATMEL=y
CONFIG_SPI_IMX=y
CONFIG_SPI_ORION=y
+CONFIG_SPI_SUN6I=y
CONFIG_GPIO_ASPEED=m
CONFIG_GPIO_ASPEED_SGPIO=y
CONFIG_GPIO_MXC=y
@@ -180,14 +181,15 @@ CONFIG_THERMAL=y
CONFIG_KIRKWOOD_THERMAL=y
CONFIG_AT91SAM9X_WATCHDOG=y
CONFIG_ORION_WATCHDOG=y
+CONFIG_SUNXI_WATCHDOG=y
CONFIG_NPCM7XX_WATCHDOG=y
CONFIG_IMX2_WDT=y
CONFIG_MFD_ATMEL_HLCDC=y
-# CONFIG_ABX500_CORE is not set
CONFIG_REGULATOR=y
CONFIG_REGULATOR_FIXED_VOLTAGE=y
CONFIG_MEDIA_SUPPORT=y
CONFIG_MEDIA_CAMERA_SUPPORT=y
+CONFIG_MEDIA_PLATFORM_SUPPORT=y
CONFIG_V4L_PLATFORM_DRIVERS=y
CONFIG_VIDEO_ASPEED=m
CONFIG_VIDEO_ATMEL_ISI=m
@@ -196,6 +198,7 @@ CONFIG_DRM_ATMEL_HLCDC=m
CONFIG_DRM_PANEL_SIMPLE=y
CONFIG_DRM_PANEL_EDP=y
CONFIG_DRM_ASPEED_GFX=m
+CONFIG_FB=y
CONFIG_FB_IMX=y
CONFIG_FB_ATMEL=y
CONFIG_BACKLIGHT_ATMEL_LCDC=y
@@ -249,6 +252,7 @@ CONFIG_MMC_SDHCI_PLTFM=m
CONFIG_MMC_SDHCI_OF_ASPEED=m
CONFIG_MMC_ATMELMCI=y
CONFIG_MMC_MVSDIO=y
+CONFIG_MMC_SUNXI=y
CONFIG_NEW_LEDS=y
CONFIG_LEDS_CLASS=y
CONFIG_LEDS_GPIO=y
@@ -303,8 +307,8 @@ CONFIG_CRYPTO_DEV_MARVELL_CESA=y
CONFIG_CRC_CCITT=y
CONFIG_LIBCRC32C=y
CONFIG_DEBUG_INFO=y
-CONFIG_DEBUG_FS=y
CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_FS=y
CONFIG_DEBUG_KERNEL=y
# CONFIG_SCHED_DEBUG is not set
# CONFIG_DEBUG_PREEMPT is not set
diff --git a/arch/arm/configs/multi_v7_defconfig b/arch/arm/configs/multi_v7_defconfig
index 8863fa969ede..6e0c8c19b35c 100644
--- a/arch/arm/configs/multi_v7_defconfig
+++ b/arch/arm/configs/multi_v7_defconfig
@@ -24,7 +24,9 @@ CONFIG_ARCH_BCM_NSP=y
CONFIG_ARCH_BCM_5301X=y
CONFIG_ARCH_BCM_281XX=y
CONFIG_ARCH_BCM_21664=y
+CONFIG_ARCH_BCM_23550=y
CONFIG_ARCH_BCM2835=y
+CONFIG_ARCH_BCM_53573=y
CONFIG_ARCH_BCM_63XX=y
CONFIG_ARCH_BRCMSTB=y
CONFIG_ARCH_BERLIN=y
@@ -32,6 +34,7 @@ CONFIG_MACH_BERLIN_BG2=y
CONFIG_MACH_BERLIN_BG2CD=y
CONFIG_MACH_BERLIN_BG2Q=y
CONFIG_ARCH_DIGICOLOR=y
+CONFIG_ARCH_AIROHA=y
CONFIG_ARCH_EXYNOS=y
CONFIG_ARCH_HIGHBANK=y
CONFIG_ARCH_HISI=y
@@ -75,6 +78,7 @@ CONFIG_SOC_AM43XX=y
CONFIG_SOC_DRA7XX=y
CONFIG_ARCH_QCOM=y
CONFIG_ARCH_MSM8X60=y
+CONFIG_ARCH_MSM8916=y
CONFIG_ARCH_MSM8960=y
CONFIG_ARCH_MSM8974=y
CONFIG_ARCH_ROCKCHIP=y
@@ -109,11 +113,13 @@ CONFIG_CPU_FREQ_GOV_CONSERVATIVE=m
CONFIG_CPU_FREQ_GOV_SCHEDUTIL=y
CONFIG_CPUFREQ_DT=y
CONFIG_ARM_IMX6Q_CPUFREQ=y
+CONFIG_ARM_QCOM_CPUFREQ_NVMEM=y
CONFIG_ARM_RASPBERRYPI_CPUFREQ=y
CONFIG_ARM_SCMI_CPUFREQ=y
CONFIG_QORIQ_CPUFREQ=y
CONFIG_CPU_IDLE=y
CONFIG_ARM_CPUIDLE=y
+CONFIG_ARM_PSCI_CPUIDLE=y
CONFIG_ARM_ZYNQ_CPUIDLE=y
CONFIG_ARM_EXYNOS_CPUIDLE=y
CONFIG_ARM_TEGRA_CPUIDLE=y
@@ -157,6 +163,8 @@ CONFIG_IPV6_MIP6=m
CONFIG_IPV6_TUNNEL=m
CONFIG_IPV6_MULTIPLE_TABLES=y
CONFIG_NET_DSA=m
+CONFIG_QRTR=m
+CONFIG_QRTR_SMD=m
CONFIG_CAN=y
CONFIG_CAN_AT91=m
CONFIG_CAN_FLEXCAN=m
@@ -169,6 +177,7 @@ CONFIG_BT_HCIUART=m
CONFIG_BT_HCIUART_BCM=y
CONFIG_BT_MRVL=m
CONFIG_BT_MRVL_SDIO=m
+CONFIG_BT_QCOMSMD=m
CONFIG_CFG80211=m
CONFIG_MAC80211=m
CONFIG_RFKILL=y
@@ -225,6 +234,7 @@ CONFIG_AD525X_DPOT_I2C=y
CONFIG_ICS932S401=y
CONFIG_ATMEL_SSC=m
CONFIG_QCOM_COINCELL=m
+CONFIG_QCOM_FASTRPC=m
CONFIG_APDS9802ALS=y
CONFIG_ISL29003=y
CONFIG_PCI_ENDPOINT_TEST=m
@@ -282,12 +292,14 @@ CONFIG_MARVELL_PHY=y
CONFIG_AT803X_PHY=y
CONFIG_ROCKCHIP_PHY=y
CONFIG_DP83867_PHY=y
+CONFIG_USB_BRCMSTB=m
CONFIG_USB_PEGASUS=y
CONFIG_USB_RTL8152=m
CONFIG_USB_LAN78XX=m
CONFIG_USB_USBNET=y
CONFIG_USB_NET_SMSC75XX=y
CONFIG_USB_NET_SMSC95XX=y
+CONFIG_WCN36XX=m
CONFIG_BRCMFMAC=m
CONFIG_MWIFIEX=m
CONFIG_MWIFIEX_SDIO=m
@@ -316,6 +328,7 @@ CONFIG_TOUCHSCREEN_ST1232=m
CONFIG_TOUCHSCREEN_STMPE=y
CONFIG_TOUCHSCREEN_SUN4I=y
CONFIG_INPUT_MISC=y
+CONFIG_INPUT_PM8941_PWRKEY=y
CONFIG_INPUT_MAX77693_HAPTIC=m
CONFIG_INPUT_MAX8997_HAPTIC=m
CONFIG_INPUT_CPCAP_PWRBUTTON=m
@@ -398,6 +411,8 @@ CONFIG_I2C_IMX=y
CONFIG_I2C_MESON=y
CONFIG_I2C_MV64XXX=y
CONFIG_I2C_OWL=y
+CONFIG_I2C_QCOM_CCI=m
+CONFIG_I2C_QUP=y
CONFIG_I2C_RIIC=y
CONFIG_I2C_RK3X=y
CONFIG_I2C_S3C2410=y
@@ -426,6 +441,7 @@ CONFIG_SPI_ORION=y
CONFIG_SPI_PL022=y
CONFIG_SPI_ROCKCHIP=m
CONFIG_SPI_RSPI=y
+CONFIG_SPI_QUP=m
CONFIG_SPI_S3C64XX=m
CONFIG_SPI_SH_MSIOF=m
CONFIG_SPI_SH_HSPI=y
@@ -476,6 +492,8 @@ CONFIG_GPIO_TWL4030=y
CONFIG_POWER_RESET_AS3722=y
CONFIG_POWER_RESET_GPIO=y
CONFIG_POWER_RESET_GPIO_RESTART=y
+CONFIG_POWER_RESET_MSM=y
+CONFIG_POWER_RESET_QCOM_PON=y
CONFIG_POWER_RESET_ST=y
CONFIG_POWER_RESET_KEYSTONE=y
CONFIG_POWER_RESET_RMOBILE=y
@@ -493,6 +511,7 @@ CONFIG_CHARGER_MAX14577=m
CONFIG_CHARGER_MAX77693=m
CONFIG_CHARGER_MAX8997=m
CONFIG_CHARGER_MAX8998=m
+CONFIG_CHARGER_SMB347=m
CONFIG_CHARGER_TPS65090=y
CONFIG_SENSORS_ARM_SCMI=y
CONFIG_SENSORS_ASPEED=m
@@ -516,6 +535,7 @@ CONFIG_ST_THERMAL_MEMMAP=y
CONFIG_TEGRA_SOCTHERM=m
CONFIG_TEGRA30_TSENSOR=m
CONFIG_GENERIC_ADC_THERMAL=m
+CONFIG_QCOM_TSENS=y
CONFIG_UNIPHIER_THERMAL=y
CONFIG_DA9063_WATCHDOG=m
CONFIG_XILINX_WATCHDOG=y
@@ -531,11 +551,13 @@ CONFIG_SUNXI_WATCHDOG=y
CONFIG_IMX2_WDT=y
CONFIG_ST_LPC_WATCHDOG=y
CONFIG_TEGRA_WATCHDOG=m
+CONFIG_QCOM_WDT=m
CONFIG_MESON_WATCHDOG=y
CONFIG_DIGICOLOR_WATCHDOG=y
CONFIG_RENESAS_WDT=m
CONFIG_RENESAS_RZAWDT=m
CONFIG_STPMIC1_WATCHDOG=y
+CONFIG_PM8916_WATCHDOG=m
CONFIG_BCM47XX_WDT=y
CONFIG_BCM2835_WDT=y
CONFIG_BCM_KONA_WDT=y
@@ -602,7 +624,8 @@ CONFIG_REGULATOR_PALMAS=y
CONFIG_REGULATOR_PBIAS=y
CONFIG_REGULATOR_PWM=y
CONFIG_REGULATOR_QCOM_RPM=y
-CONFIG_REGULATOR_QCOM_SMD_RPM=m
+CONFIG_REGULATOR_QCOM_SMD_RPM=y
+CONFIG_REGULATOR_QCOM_SPMI=y
CONFIG_REGULATOR_RK808=y
CONFIG_REGULATOR_RN5T618=y
CONFIG_REGULATOR_S2MPA01=m
@@ -691,6 +714,7 @@ CONFIG_DRM_PANEL_RAYDIUM_RM68200=m
CONFIG_DRM_PANEL_SAMSUNG_S6E63J0X03=m
CONFIG_DRM_PANEL_SAMSUNG_S6E8AA0=m
CONFIG_DRM_LVDS_CODEC=m
+CONFIG_DRM_DISPLAY_CONNECTOR=m
CONFIG_DRM_NXP_PTN3460=m
CONFIG_DRM_PARADE_PS8622=m
CONFIG_DRM_SII902X=m
@@ -741,6 +765,8 @@ CONFIG_SND_SOC_FSL_SAI=m
CONFIG_SND_PXA_SOC_SSP=m
CONFIG_SND_MMP_SOC_SSPA=m
CONFIG_SND_PXA910_SOC=m
+CONFIG_SND_SOC_QCOM=m
+CONFIG_SND_SOC_APQ8016_SBC=m
CONFIG_SND_SOC_ROCKCHIP=m
CONFIG_SND_SOC_ROCKCHIP_SPDIF=m
CONFIG_SND_SOC_ROCKCHIP_MAX98090=m
@@ -774,6 +800,8 @@ CONFIG_SND_SOC_TEGRA_MAX98090=m
CONFIG_SND_SOC_AK4642=m
CONFIG_SND_SOC_CPCAP=m
CONFIG_SND_SOC_CS42L51_I2C=m
+CONFIG_SND_SOC_MSM8916_WCD_ANALOG=m
+CONFIG_SND_SOC_MSM8916_WCD_DIGITAL=m
CONFIG_SND_SOC_SGTL5000=m
CONFIG_SND_SOC_STI_SAS=m
CONFIG_SND_SOC_WM8978=m
@@ -936,6 +964,7 @@ CONFIG_RTC_DRV_AT91SAM9=m
CONFIG_RTC_DRV_VT8500=y
CONFIG_RTC_DRV_SUNXI=y
CONFIG_RTC_DRV_MV=y
+CONFIG_RTC_DRV_PM8XXX=m
CONFIG_RTC_DRV_TEGRA=y
CONFIG_RTC_DRV_ST_LPC=y
CONFIG_RTC_DRV_STM32=y
@@ -984,26 +1013,47 @@ CONFIG_COMMON_CLK_SCMI=y
CONFIG_COMMON_CLK_S2MPS11=m
CONFIG_CLK_RASPBERRYPI=y
CONFIG_COMMON_CLK_QCOM=y
+CONFIG_QCOM_A53PLL=y
+CONFIG_QCOM_CLK_APCS_MSM8916=y
CONFIG_QCOM_CLK_RPM=y
+CONFIG_QCOM_CLK_SMD_RPM=y
CONFIG_APQ_MMCC_8084=y
CONFIG_MSM_GCC_8660=y
+CONFIG_MSM_GCC_8916=y
CONFIG_MSM_MMCC_8960=y
CONFIG_MSM_MMCC_8974=y
+CONFIG_HWSPINLOCK=y
+CONFIG_HWSPINLOCK_QCOM=y
CONFIG_MICROCHIP_PIT64B=y
CONFIG_BCM2835_MBOX=y
+CONFIG_QCOM_APCS_IPC=y
+CONFIG_QCOM_IPCC=y
CONFIG_ROCKCHIP_IOMMU=y
CONFIG_TEGRA_IOMMU_GART=y
CONFIG_TEGRA_IOMMU_SMMU=y
CONFIG_EXYNOS_IOMMU=y
+CONFIG_QCOM_IOMMU=y
CONFIG_REMOTEPROC=y
+CONFIG_QCOM_Q6V5_MSS=m
+CONFIG_QCOM_SYSMON=m
+CONFIG_QCOM_WCNSS_PIL=m
CONFIG_ST_REMOTEPROC=m
+CONFIG_RPMSG_QCOM_SMD=y
CONFIG_RPMSG_VIRTIO=m
CONFIG_ASPEED_LPC_CTRL=m
CONFIG_ASPEED_LPC_SNOOP=m
CONFIG_ASPEED_P2A_CTRL=m
CONFIG_RASPBERRYPI_POWER=y
+CONFIG_QCOM_CPR=y
CONFIG_QCOM_GSBI=y
-CONFIG_QCOM_SMD_RPM=m
+CONFIG_QCOM_RMTFS_MEM=m
+CONFIG_QCOM_RPMPD=y
+CONFIG_QCOM_SMEM=y
+CONFIG_QCOM_SMD_RPM=y
+CONFIG_QCOM_SMP2P=y
+CONFIG_QCOM_SMSM=y
+CONFIG_QCOM_SOCINFO=m
+CONFIG_QCOM_STATS=m
CONFIG_QCOM_WCNSS_CTRL=m
CONFIG_ARCH_EMEV2=y
CONFIG_ARCH_R8A7794=y
@@ -1036,6 +1086,7 @@ CONFIG_DEVFREQ_EVENT_EXYNOS_NOCP=m
CONFIG_EXTCON_MAX14577=m
CONFIG_EXTCON_MAX77693=m
CONFIG_EXTCON_MAX8997=m
+CONFIG_EXTCON_USB_GPIO=y
CONFIG_TI_AEMIF=y
CONFIG_STM32_FMC2_EBI=y
CONFIG_EXYNOS5422_DMC=m
@@ -1048,6 +1099,7 @@ CONFIG_BERLIN2_ADC=m
CONFIG_CPCAP_ADC=m
CONFIG_EXYNOS_ADC=m
CONFIG_MESON_SARADC=m
+CONFIG_QCOM_SPMI_VADC=m
CONFIG_ROCKCHIP_SARADC=m
CONFIG_STM32_ADC_CORE=m
CONFIG_STM32_ADC=m
@@ -1090,9 +1142,11 @@ CONFIG_PHY_SUN9I_USB=y
CONFIG_PHY_HIX5HD2_SATA=y
CONFIG_PHY_BERLIN_SATA=y
CONFIG_PHY_BERLIN_USB=y
+CONFIG_PHY_BRCM_USB=m
CONFIG_PHY_MMP3_USB=m
CONFIG_PHY_CPCAP_USB=m
CONFIG_PHY_QCOM_APQ8064_SATA=m
+CONFIG_PHY_QCOM_USB_HS=y
CONFIG_PHY_RCAR_GEN2=m
CONFIG_PHY_ROCKCHIP_DP=m
CONFIG_PHY_ROCKCHIP_USB=y
@@ -1110,6 +1164,7 @@ CONFIG_TI_PIPE3=y
CONFIG_TWL4030_USB=m
CONFIG_RAS=y
CONFIG_NVMEM_IMX_OCOTP=y
+CONFIG_QCOM_QFPROM=y
CONFIG_ROCKCHIP_EFUSE=m
CONFIG_NVMEM_SUNXI_SID=y
CONFIG_NVMEM_VF610_OCOTP=y
@@ -1122,6 +1177,8 @@ CONFIG_FSI_MASTER_ASPEED=m
CONFIG_FSI_SCOM=m
CONFIG_FSI_SBEFIFO=m
CONFIG_FSI_OCC=m
+CONFIG_INTERCONNECT_QCOM=y
+CONFIG_INTERCONNECT_QCOM_MSM8916=y
CONFIG_COUNTER=m
CONFIG_STM32_TIMER_CNT=m
CONFIG_STM32_LPTIMER_CNT=m
@@ -1161,6 +1218,8 @@ CONFIG_CRYPTO_DEV_ATMEL_AES=m
CONFIG_CRYPTO_DEV_ATMEL_TDES=m
CONFIG_CRYPTO_DEV_ATMEL_SHA=m
CONFIG_CRYPTO_DEV_MARVELL_CESA=m
+CONFIG_CRYPTO_DEV_QCE=m
+CONFIG_CRYPTO_DEV_QCOM_RNG=m
CONFIG_CRYPTO_DEV_ROCKCHIP=m
CONFIG_CRYPTO_DEV_STM32_CRC=m
CONFIG_CRYPTO_DEV_STM32_HASH=m
diff --git a/arch/arm/configs/netwinder_defconfig b/arch/arm/configs/netwinder_defconfig
index 2e3b20ef0db1..c3c171cec91b 100644
--- a/arch/arm/configs/netwinder_defconfig
+++ b/arch/arm/configs/netwinder_defconfig
@@ -71,7 +71,6 @@ CONFIG_NFS_V3=y
CONFIG_NFS_V4=y
CONFIG_ROOT_NFS=y
CONFIG_NFSD=y
-CONFIG_NFSD_V3=y
CONFIG_SMB_FS=y
CONFIG_PARTITION_ADVANCED=y
CONFIG_NLS_CODEPAGE_437=y
diff --git a/arch/arm/configs/pxa_defconfig b/arch/arm/configs/pxa_defconfig
index dedaaae3d0d8..29b1f192afbb 100644
--- a/arch/arm/configs/pxa_defconfig
+++ b/arch/arm/configs/pxa_defconfig
@@ -41,8 +41,6 @@ CONFIG_MACH_EXEDA=y
CONFIG_MACH_CM_X300=y
CONFIG_MACH_CAPC7117=y
CONFIG_ARCH_GUMSTIX=y
-CONFIG_MACH_INTELMOTE2=y
-CONFIG_MACH_STARGATE2=y
CONFIG_MACH_XCEP=y
CONFIG_TRIZEPS_PXA=y
CONFIG_MACH_TRIZEPS4WL=y
@@ -487,7 +485,6 @@ CONFIG_SND_SOC_ZYLONITE=m
CONFIG_SND_PXA2XX_SOC_HX4700=m
CONFIG_SND_PXA2XX_SOC_MAGICIAN=m
CONFIG_SND_PXA2XX_SOC_MIOA701=m
-CONFIG_SND_PXA2XX_SOC_IMOTE2=m
CONFIG_SND_SOC_AK4642=m
CONFIG_SND_SOC_WM8978=m
CONFIG_SND_SIMPLE_CARD=m
diff --git a/arch/arm/configs/sama7_defconfig b/arch/arm/configs/sama7_defconfig
index 0368068e04d9..07b0494ef743 100644
--- a/arch/arm/configs/sama7_defconfig
+++ b/arch/arm/configs/sama7_defconfig
@@ -26,6 +26,13 @@ CONFIG_FORCE_MAX_ZONEORDER=15
CONFIG_UACCESS_WITH_MEMCPY=y
# CONFIG_ATAGS is not set
CONFIG_CMDLINE="console=ttyS0,115200 earlyprintk ignore_loglevel"
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE=y
+CONFIG_CPU_FREQ_GOV_POWERSAVE=y
+CONFIG_CPU_FREQ_GOV_USERSPACE=y
+CONFIG_CPU_FREQ_GOV_ONDEMAND=y
+CONFIG_CPUFREQ_DT=y
+CONFIG_CPU_IDLE=y
CONFIG_VFP=y
CONFIG_NEON=y
CONFIG_KERNEL_MODE_NEON=y
@@ -82,7 +89,11 @@ CONFIG_DEVTMPFS_MOUNT=y
CONFIG_MTD=y
CONFIG_MTD_TESTS=m
CONFIG_MTD_CMDLINE_PARTS=y
+CONFIG_MTD_RAW_NAND=y
+CONFIG_MTD_NAND_ATMEL=y
+# CONFIG_MTD_NAND_ECC_SW_HAMMING is not set
CONFIG_MTD_SPI_NOR=y
+CONFIG_MTD_UBI=y
CONFIG_BLK_DEV_LOOP=y
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_COUNT=1
@@ -170,21 +181,21 @@ CONFIG_RTC_DRV_AT91RM9200=y
CONFIG_RTC_DRV_AT91SAM9=y
CONFIG_DMADEVICES=y
CONFIG_AT_XDMAC=y
-CONFIG_DMATEST=y
CONFIG_STAGING=y
CONFIG_MICROCHIP_PIT64B=y
# CONFIG_IOMMU_SUPPORT is not set
-# CONFIG_ATMEL_EBI is not set
CONFIG_IIO=y
CONFIG_IIO_SW_TRIGGER=y
CONFIG_AT91_SAMA5D2_ADC=y
CONFIG_PWM=y
CONFIG_PWM_ATMEL=y
+CONFIG_MCHP_EIC=y
CONFIG_EXT2_FS=y
CONFIG_EXT3_FS=y
CONFIG_FANOTIFY=y
CONFIG_VFAT_FS=y
CONFIG_TMPFS=y
+CONFIG_UBIFS_FS=y
CONFIG_NFS_FS=y
CONFIG_ROOT_NFS=y
CONFIG_NLS_CODEPAGE_437=y
@@ -192,9 +203,19 @@ CONFIG_NLS_CODEPAGE_850=y
CONFIG_NLS_ISO8859_1=y
CONFIG_NLS_UTF8=y
CONFIG_LSM="N"
-CONFIG_CRYPTO_DEFLATE=y
-CONFIG_CRYPTO_LZO=y
-# CONFIG_CRYPTO_HW is not set
+CONFIG_CRYPTO_AUTHENC=y
+CONFIG_CRYPTO_GCM=y
+CONFIG_CRYPTO_CBC=y
+CONFIG_CRYPTO_CFB=y
+CONFIG_CRYPTO_OFB=y
+CONFIG_CRYPTO_XTS=y
+CONFIG_CRYPTO_SHA1=y
+CONFIG_CRYPTO_DES=y
+CONFIG_CRYPTO_USER_API_HASH=m
+CONFIG_CRYPTO_USER_API_SKCIPHER=m
+CONFIG_CRYPTO_DEV_ATMEL_AES=y
+CONFIG_CRYPTO_DEV_ATMEL_TDES=y
+CONFIG_CRYPTO_DEV_ATMEL_SHA=y
CONFIG_CRC_CCITT=y
CONFIG_CRC_ITU_T=y
CONFIG_DMA_CMA=y
diff --git a/arch/arm/configs/shmobile_defconfig b/arch/arm/configs/shmobile_defconfig
index 2c2702ec6d02..db8df8a3a7b1 100644
--- a/arch/arm/configs/shmobile_defconfig
+++ b/arch/arm/configs/shmobile_defconfig
@@ -69,9 +69,13 @@ CONFIG_INPUT_DA9063_ONKEY=y
CONFIG_INPUT_ADXL34X=y
# CONFIG_LEGACY_PTYS is not set
CONFIG_SERIAL_8250=y
+# CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set
+# CONFIG_SERIAL_8250_16550A_VARIANTS is not set
CONFIG_SERIAL_8250_CONSOLE=y
+# CONFIG_SERIAL_8250_PCI is not set
CONFIG_SERIAL_8250_DW=y
CONFIG_SERIAL_8250_EM=y
+# CONFIG_SERIAL_8250_PERICOM is not set
CONFIG_SERIAL_SH_SCI=y
CONFIG_I2C_CHARDEV=y
CONFIG_I2C_DEMUX_PINCTRL=y
diff --git a/arch/arm/configs/versatile_defconfig b/arch/arm/configs/versatile_defconfig
index d06aa64e05a1..c2d79a67f81f 100644
--- a/arch/arm/configs/versatile_defconfig
+++ b/arch/arm/configs/versatile_defconfig
@@ -86,7 +86,6 @@ CONFIG_ROMFS_FS=y
CONFIG_NFS_FS=y
CONFIG_ROOT_NFS=y
CONFIG_NFSD=y
-CONFIG_NFSD_V3=y
CONFIG_NLS_CODEPAGE_850=m
CONFIG_NLS_ISO8859_1=m
CONFIG_MAGIC_SYSRQ=y
diff --git a/arch/arm/configs/viper_defconfig b/arch/arm/configs/viper_defconfig
index 989599ce5300..c28539bfd128 100644
--- a/arch/arm/configs/viper_defconfig
+++ b/arch/arm/configs/viper_defconfig
@@ -145,7 +145,6 @@ CONFIG_NFS_FS=y
CONFIG_NFS_V3=y
CONFIG_ROOT_NFS=y
CONFIG_NFSD=m
-CONFIG_NFSD_V3=y
CONFIG_PARTITION_ADVANCED=y
CONFIG_NLS_CODEPAGE_437=m
CONFIG_NLS_CODEPAGE_850=m
diff --git a/arch/arm/configs/zeus_defconfig b/arch/arm/configs/zeus_defconfig
index d3b98c4d225b..25bb6995f105 100644
--- a/arch/arm/configs/zeus_defconfig
+++ b/arch/arm/configs/zeus_defconfig
@@ -160,7 +160,6 @@ CONFIG_NFS_FS=y
CONFIG_NFS_V3=y
CONFIG_ROOT_NFS=y
CONFIG_NFSD=m
-CONFIG_NFSD_V3=y
CONFIG_PARTITION_ADVANCED=y
CONFIG_NLS_CODEPAGE_437=m
CONFIG_NLS_CODEPAGE_850=m
diff --git a/arch/arm/crypto/aes-neonbs-core.S b/arch/arm/crypto/aes-neonbs-core.S
index 7d0cc7f226a5..7b61032f29fa 100644
--- a/arch/arm/crypto/aes-neonbs-core.S
+++ b/arch/arm/crypto/aes-neonbs-core.S
@@ -758,29 +758,24 @@ ENTRY(aesbs_cbc_decrypt)
ENDPROC(aesbs_cbc_decrypt)
.macro next_ctr, q
- vmov.32 \q\()h[1], r10
+ vmov \q\()h, r9, r10
adds r10, r10, #1
- vmov.32 \q\()h[0], r9
adcs r9, r9, #0
- vmov.32 \q\()l[1], r8
+ vmov \q\()l, r7, r8
adcs r8, r8, #0
- vmov.32 \q\()l[0], r7
adc r7, r7, #0
vrev32.8 \q, \q
.endm
/*
* aesbs_ctr_encrypt(u8 out[], u8 const in[], u8 const rk[],
- * int rounds, int blocks, u8 ctr[], u8 final[])
+ * int rounds, int bytes, u8 ctr[])
*/
ENTRY(aesbs_ctr_encrypt)
mov ip, sp
push {r4-r10, lr}
- ldm ip, {r5-r7} // load args 4-6
- teq r7, #0
- addne r5, r5, #1 // one extra block if final != 0
-
+ ldm ip, {r5, r6} // load args 4-5
vld1.8 {q0}, [r6] // load counter
vrev32.8 q1, q0
vmov r9, r10, d3
@@ -792,20 +787,19 @@ ENTRY(aesbs_ctr_encrypt)
adc r7, r7, #0
99: vmov q1, q0
+ sub lr, r5, #1
vmov q2, q0
+ adr ip, 0f
vmov q3, q0
+ and lr, lr, #112
vmov q4, q0
+ cmp r5, #112
vmov q5, q0
+ sub ip, ip, lr, lsl #1
vmov q6, q0
+ add ip, ip, lr, lsr #2
vmov q7, q0
-
- adr ip, 0f
- sub lr, r5, #1
- and lr, lr, #7
- cmp r5, #8
- sub ip, ip, lr, lsl #5
- sub ip, ip, lr, lsl #2
- movlt pc, ip // computed goto if blocks < 8
+ movle pc, ip // computed goto if bytes < 112
next_ctr q1
next_ctr q2
@@ -820,12 +814,14 @@ ENTRY(aesbs_ctr_encrypt)
bl aesbs_encrypt8
adr ip, 1f
- and lr, r5, #7
- cmp r5, #8
- movgt r4, #0
- ldrle r4, [sp, #40] // load final in the last round
- sub ip, ip, lr, lsl #2
- movlt pc, ip // computed goto if blocks < 8
+ sub lr, r5, #1
+ cmp r5, #128
+ bic lr, lr, #15
+ ands r4, r5, #15 // preserves C flag
+ teqcs r5, r5 // set Z flag if not last iteration
+ sub ip, ip, lr, lsr #2
+ rsb r4, r4, #16
+ movcc pc, ip // computed goto if bytes < 128
vld1.8 {q8}, [r1]!
vld1.8 {q9}, [r1]!
@@ -834,46 +830,70 @@ ENTRY(aesbs_ctr_encrypt)
vld1.8 {q12}, [r1]!
vld1.8 {q13}, [r1]!
vld1.8 {q14}, [r1]!
- teq r4, #0 // skip last block if 'final'
-1: bne 2f
+1: subne r1, r1, r4
vld1.8 {q15}, [r1]!
-2: adr ip, 3f
- cmp r5, #8
- sub ip, ip, lr, lsl #3
- movlt pc, ip // computed goto if blocks < 8
+ add ip, ip, #2f - 1b
veor q0, q0, q8
- vst1.8 {q0}, [r0]!
veor q1, q1, q9
- vst1.8 {q1}, [r0]!
veor q4, q4, q10
- vst1.8 {q4}, [r0]!
veor q6, q6, q11
- vst1.8 {q6}, [r0]!
veor q3, q3, q12
- vst1.8 {q3}, [r0]!
veor q7, q7, q13
- vst1.8 {q7}, [r0]!
veor q2, q2, q14
+ bne 3f
+ veor q5, q5, q15
+
+ movcc pc, ip // computed goto if bytes < 128
+
+ vst1.8 {q0}, [r0]!
+ vst1.8 {q1}, [r0]!
+ vst1.8 {q4}, [r0]!
+ vst1.8 {q6}, [r0]!
+ vst1.8 {q3}, [r0]!
+ vst1.8 {q7}, [r0]!
vst1.8 {q2}, [r0]!
- teq r4, #0 // skip last block if 'final'
- W(bne) 5f
-3: veor q5, q5, q15
+2: subne r0, r0, r4
vst1.8 {q5}, [r0]!
-4: next_ctr q0
+ next_ctr q0
- subs r5, r5, #8
+ subs r5, r5, #128
bgt 99b
vst1.8 {q0}, [r6]
pop {r4-r10, pc}
-5: vst1.8 {q5}, [r4]
- b 4b
+3: adr lr, .Lpermute_table + 16
+ cmp r5, #16 // Z flag remains cleared
+ sub lr, lr, r4
+ vld1.8 {q8-q9}, [lr]
+ vtbl.8 d16, {q5}, d16
+ vtbl.8 d17, {q5}, d17
+ veor q5, q8, q15
+ bcc 4f // have to reload prev if R5 < 16
+ vtbx.8 d10, {q2}, d18
+ vtbx.8 d11, {q2}, d19
+ mov pc, ip // branch back to VST sequence
+
+4: sub r0, r0, r4
+ vshr.s8 q9, q9, #7 // create mask for VBIF
+ vld1.8 {q8}, [r0] // reload
+ vbif q5, q8, q9
+ vst1.8 {q5}, [r0]
+ pop {r4-r10, pc}
ENDPROC(aesbs_ctr_encrypt)
+ .align 6
+.Lpermute_table:
+ .byte 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
+ .byte 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
+ .byte 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07
+ .byte 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f
+ .byte 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
+ .byte 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
+
.macro next_tweak, out, in, const, tmp
vshr.s64 \tmp, \in, #63
vand \tmp, \tmp, \const
@@ -888,6 +908,7 @@ ENDPROC(aesbs_ctr_encrypt)
* aesbs_xts_decrypt(u8 out[], u8 const in[], u8 const rk[], int rounds,
* int blocks, u8 iv[], int reorder_last_tweak)
*/
+ .align 6
__xts_prepare8:
vld1.8 {q14}, [r7] // load iv
vmov.i32 d30, #0x87 // compose tweak mask vector
diff --git a/arch/arm/crypto/aes-neonbs-glue.c b/arch/arm/crypto/aes-neonbs-glue.c
index 5c6cd3c63cbc..f00f042ef357 100644
--- a/arch/arm/crypto/aes-neonbs-glue.c
+++ b/arch/arm/crypto/aes-neonbs-glue.c
@@ -37,7 +37,7 @@ asmlinkage void aesbs_cbc_decrypt(u8 out[], u8 const in[], u8 const rk[],
int rounds, int blocks, u8 iv[]);
asmlinkage void aesbs_ctr_encrypt(u8 out[], u8 const in[], u8 const rk[],
- int rounds, int blocks, u8 ctr[], u8 final[]);
+ int rounds, int blocks, u8 ctr[]);
asmlinkage void aesbs_xts_encrypt(u8 out[], u8 const in[], u8 const rk[],
int rounds, int blocks, u8 iv[], int);
@@ -243,32 +243,25 @@ static int ctr_encrypt(struct skcipher_request *req)
err = skcipher_walk_virt(&walk, req, false);
while (walk.nbytes > 0) {
- unsigned int blocks = walk.nbytes / AES_BLOCK_SIZE;
- u8 *final = (walk.total % AES_BLOCK_SIZE) ? buf : NULL;
+ const u8 *src = walk.src.virt.addr;
+ u8 *dst = walk.dst.virt.addr;
+ int bytes = walk.nbytes;
- if (walk.nbytes < walk.total) {
- blocks = round_down(blocks,
- walk.stride / AES_BLOCK_SIZE);
- final = NULL;
- }
+ if (unlikely(bytes < AES_BLOCK_SIZE))
+ src = dst = memcpy(buf + sizeof(buf) - bytes,
+ src, bytes);
+ else if (walk.nbytes < walk.total)
+ bytes &= ~(8 * AES_BLOCK_SIZE - 1);
kernel_neon_begin();
- aesbs_ctr_encrypt(walk.dst.virt.addr, walk.src.virt.addr,
- ctx->rk, ctx->rounds, blocks, walk.iv, final);
+ aesbs_ctr_encrypt(dst, src, ctx->rk, ctx->rounds, bytes, walk.iv);
kernel_neon_end();
- if (final) {
- u8 *dst = walk.dst.virt.addr + blocks * AES_BLOCK_SIZE;
- u8 *src = walk.src.virt.addr + blocks * AES_BLOCK_SIZE;
+ if (unlikely(bytes < AES_BLOCK_SIZE))
+ memcpy(walk.dst.virt.addr,
+ buf + sizeof(buf) - bytes, bytes);
- crypto_xor_cpy(dst, src, final,
- walk.total % AES_BLOCK_SIZE);
-
- err = skcipher_walk_done(&walk, 0);
- break;
- }
- err = skcipher_walk_done(&walk,
- walk.nbytes - blocks * AES_BLOCK_SIZE);
+ err = skcipher_walk_done(&walk, walk.nbytes - bytes);
}
return err;
diff --git a/arch/arm/crypto/blake2s-shash.c b/arch/arm/crypto/blake2s-shash.c
index 17c1c3bfe2f5..763c73beea2d 100644
--- a/arch/arm/crypto/blake2s-shash.c
+++ b/arch/arm/crypto/blake2s-shash.c
@@ -13,12 +13,12 @@
static int crypto_blake2s_update_arm(struct shash_desc *desc,
const u8 *in, unsigned int inlen)
{
- return crypto_blake2s_update(desc, in, inlen, blake2s_compress);
+ return crypto_blake2s_update(desc, in, inlen, false);
}
static int crypto_blake2s_final_arm(struct shash_desc *desc, u8 *out)
{
- return crypto_blake2s_final(desc, out, blake2s_compress);
+ return crypto_blake2s_final(desc, out, false);
}
#define BLAKE2S_ALG(name, driver_name, digest_size) \
diff --git a/arch/arm/include/asm/assembler.h b/arch/arm/include/asm/assembler.h
index 7d23d4bb2168..34fe8d2dd5d1 100644
--- a/arch/arm/include/asm/assembler.h
+++ b/arch/arm/include/asm/assembler.h
@@ -86,6 +86,10 @@
#define IMM12_MASK 0xfff
+/* the frame pointer used for stack unwinding */
+ARM( fpreg .req r11 )
+THUMB( fpreg .req r7 )
+
/*
* Enable and disable interrupts
*/
@@ -107,6 +111,16 @@
.endm
#endif
+#if __LINUX_ARM_ARCH__ < 7
+ .macro dsb, args
+ mcr p15, 0, r0, c7, c10, 4
+ .endm
+
+ .macro isb, args
+ mcr p15, 0, r0, c7, c5, 4
+ .endm
+#endif
+
.macro asm_trace_hardirqs_off, save=1
#if defined(CONFIG_TRACE_IRQFLAGS)
.if \save
@@ -199,43 +213,12 @@
.endm
.endr
- .macro get_current, rd
-#ifdef CONFIG_CURRENT_POINTER_IN_TPIDRURO
- mrc p15, 0, \rd, c13, c0, 3 @ get TPIDRURO register
-#else
- get_thread_info \rd
- ldr \rd, [\rd, #TI_TASK]
-#endif
- .endm
-
- .macro set_current, rn
-#ifdef CONFIG_CURRENT_POINTER_IN_TPIDRURO
- mcr p15, 0, \rn, c13, c0, 3 @ set TPIDRURO register
-#endif
- .endm
-
- .macro reload_current, t1:req, t2:req
-#ifdef CONFIG_CURRENT_POINTER_IN_TPIDRURO
- adr_l \t1, __entry_task @ get __entry_task base address
- mrc p15, 0, \t2, c13, c0, 4 @ get per-CPU offset
- ldr \t1, [\t1, \t2] @ load variable
- mcr p15, 0, \t1, c13, c0, 3 @ store in TPIDRURO
-#endif
- .endm
-
/*
* Get current thread_info.
*/
.macro get_thread_info, rd
-#ifdef CONFIG_THREAD_INFO_IN_TASK
/* thread_info is the first member of struct task_struct */
get_current \rd
-#else
- ARM( mov \rd, sp, lsr #THREAD_SIZE_ORDER + PAGE_SHIFT )
- THUMB( mov \rd, sp )
- THUMB( lsr \rd, \rd, #THREAD_SIZE_ORDER + PAGE_SHIFT )
- mov \rd, \rd, lsl #THREAD_SIZE_ORDER + PAGE_SHIFT
-#endif
.endm
/*
@@ -288,6 +271,7 @@
*/
#define ALT_UP(instr...) \
.pushsection ".alt.smp.init", "a" ;\
+ .align 2 ;\
.long 9998b - . ;\
9997: instr ;\
.if . - 9997b == 2 ;\
@@ -299,6 +283,7 @@
.popsection
#define ALT_UP_B(label) \
.pushsection ".alt.smp.init", "a" ;\
+ .align 2 ;\
.long 9998b - . ;\
W(b) . + (label - 9998b) ;\
.popsection
@@ -308,6 +293,80 @@
#define ALT_UP_B(label) b label
#endif
+ /*
+ * this_cpu_offset - load the per-CPU offset of this CPU into
+ * register 'rd'
+ */
+ .macro this_cpu_offset, rd:req
+#ifdef CONFIG_SMP
+ALT_SMP(mrc p15, 0, \rd, c13, c0, 4)
+#ifdef CONFIG_CPU_V6
+ALT_UP_B(.L1_\@)
+.L0_\@:
+ .subsection 1
+.L1_\@: ldr_va \rd, __per_cpu_offset
+ b .L0_\@
+ .previous
+#endif
+#else
+ mov \rd, #0
+#endif
+ .endm
+
+ /*
+ * set_current - store the task pointer of this CPU's current task
+ */
+ .macro set_current, rn:req, tmp:req
+#if defined(CONFIG_CURRENT_POINTER_IN_TPIDRURO) || defined(CONFIG_SMP)
+9998: mcr p15, 0, \rn, c13, c0, 3 @ set TPIDRURO register
+#ifdef CONFIG_CPU_V6
+ALT_UP_B(.L0_\@)
+ .subsection 1
+.L0_\@: str_va \rn, __current, \tmp
+ b .L1_\@
+ .previous
+.L1_\@:
+#endif
+#else
+ str_va \rn, __current, \tmp
+#endif
+ .endm
+
+ /*
+ * get_current - load the task pointer of this CPU's current task
+ */
+ .macro get_current, rd:req
+#if defined(CONFIG_CURRENT_POINTER_IN_TPIDRURO) || defined(CONFIG_SMP)
+9998: mrc p15, 0, \rd, c13, c0, 3 @ get TPIDRURO register
+#ifdef CONFIG_CPU_V6
+ALT_UP_B(.L0_\@)
+ .subsection 1
+.L0_\@: ldr_va \rd, __current
+ b .L1_\@
+ .previous
+.L1_\@:
+#endif
+#else
+ ldr_va \rd, __current
+#endif
+ .endm
+
+ /*
+ * reload_current - reload the task pointer of this CPU's current task
+ * into the TLS register
+ */
+ .macro reload_current, t1:req, t2:req
+#if defined(CONFIG_CURRENT_POINTER_IN_TPIDRURO) || defined(CONFIG_SMP)
+#ifdef CONFIG_CPU_V6
+ALT_SMP(nop)
+ALT_UP_B(.L0_\@)
+#endif
+ ldr_this_cpu \t1, __entry_task, \t1, \t2
+ mcr p15, 0, \t1, c13, c0, 3 @ store in TPIDRURO
+.L0_\@:
+#endif
+ .endm
+
/*
* Instruction barrier
*/
@@ -564,12 +623,12 @@ THUMB( orr \reg , \reg , #PSR_T_BIT )
/*
* mov_l - move a constant value or [relocated] address into a register
*/
- .macro mov_l, dst:req, imm:req
+ .macro mov_l, dst:req, imm:req, cond
.if __LINUX_ARM_ARCH__ < 7
- ldr \dst, =\imm
+ ldr\cond \dst, =\imm
.else
- movw \dst, #:lower16:\imm
- movt \dst, #:upper16:\imm
+ movw\cond \dst, #:lower16:\imm
+ movt\cond \dst, #:upper16:\imm
.endif
.endm
@@ -607,6 +666,78 @@ THUMB( orr \reg , \reg , #PSR_T_BIT )
__adldst_l str, \src, \sym, \tmp, \cond
.endm
+ .macro __ldst_va, op, reg, tmp, sym, cond
+#if __LINUX_ARM_ARCH__ >= 7 || \
+ !defined(CONFIG_ARM_HAS_GROUP_RELOCS) || \
+ (defined(MODULE) && defined(CONFIG_ARM_MODULE_PLTS))
+ mov_l \tmp, \sym, \cond
+ \op\cond \reg, [\tmp]
+#else
+ /*
+ * Avoid a literal load, by emitting a sequence of ADD/LDR instructions
+ * with the appropriate relocations. The combined sequence has a range
+ * of -/+ 256 MiB, which should be sufficient for the core kernel and
+ * for modules loaded into the module region.
+ */
+ .globl \sym
+ .reloc .L0_\@, R_ARM_ALU_PC_G0_NC, \sym
+ .reloc .L1_\@, R_ARM_ALU_PC_G1_NC, \sym
+ .reloc .L2_\@, R_ARM_LDR_PC_G2, \sym
+.L0_\@: sub\cond \tmp, pc, #8
+.L1_\@: sub\cond \tmp, \tmp, #4
+.L2_\@: \op\cond \reg, [\tmp, #0]
+#endif
+ .endm
+
+ /*
+ * ldr_va - load a 32-bit word from the virtual address of \sym
+ */
+ .macro ldr_va, rd:req, sym:req, cond
+ __ldst_va ldr, \rd, \rd, \sym, \cond
+ .endm
+
+ /*
+ * str_va - store a 32-bit word to the virtual address of \sym
+ */
+ .macro str_va, rn:req, sym:req, tmp:req, cond
+ __ldst_va str, \rn, \tmp, \sym, \cond
+ .endm
+
+ /*
+ * ldr_this_cpu_armv6 - Load a 32-bit word from the per-CPU variable 'sym',
+ * without using a temp register. Supported in ARM mode
+ * only.
+ */
+ .macro ldr_this_cpu_armv6, rd:req, sym:req
+ this_cpu_offset \rd
+ .globl \sym
+ .reloc .L0_\@, R_ARM_ALU_PC_G0_NC, \sym
+ .reloc .L1_\@, R_ARM_ALU_PC_G1_NC, \sym
+ .reloc .L2_\@, R_ARM_LDR_PC_G2, \sym
+ add \rd, \rd, pc
+.L0_\@: sub \rd, \rd, #4
+.L1_\@: sub \rd, \rd, #0
+.L2_\@: ldr \rd, [\rd, #4]
+ .endm
+
+ /*
+ * ldr_this_cpu - Load a 32-bit word from the per-CPU variable 'sym'
+ * into register 'rd', which may be the stack pointer,
+ * using 't1' and 't2' as general temp registers. These
+ * are permitted to overlap with 'rd' if != sp
+ */
+ .macro ldr_this_cpu, rd:req, sym:req, t1:req, t2:req
+#if __LINUX_ARM_ARCH__ >= 7 || \
+ !defined(CONFIG_ARM_HAS_GROUP_RELOCS) || \
+ (defined(MODULE) && defined(CONFIG_ARM_MODULE_PLTS))
+ this_cpu_offset \t1
+ mov_l \t2, \sym
+ ldr \rd, [\t1, \t2]
+#else
+ ldr_this_cpu_armv6 \rd, \sym
+#endif
+ .endm
+
/*
* rev_l - byte-swap a 32-bit value
*
@@ -624,4 +755,19 @@ THUMB( orr \reg , \reg , #PSR_T_BIT )
.endif
.endm
+ /*
+ * bl_r - branch and link to register
+ *
+ * @dst: target to branch to
+ * @c: conditional opcode suffix
+ */
+ .macro bl_r, dst:req, c
+ .if __LINUX_ARM_ARCH__ < 6
+ mov\c lr, pc
+ mov\c pc, \dst
+ .else
+ blx\c \dst
+ .endif
+ .endm
+
#endif /* __ASM_ASSEMBLER_H__ */
diff --git a/arch/arm/include/asm/cacheflush.h b/arch/arm/include/asm/cacheflush.h
index 5e56288e343b..a094f964c869 100644
--- a/arch/arm/include/asm/cacheflush.h
+++ b/arch/arm/include/asm/cacheflush.h
@@ -445,15 +445,10 @@ static inline void __sync_cache_range_r(volatile void *p, size_t size)
* however some exceptions may exist. Caveat emptor.
*
* - The clobber list is dictated by the call to v7_flush_dcache_*.
- * fp is preserved to the stack explicitly prior disabling the cache
- * since adding it to the clobber list is incompatible with having
- * CONFIG_FRAME_POINTER=y. ip is saved as well if ever r12-clobbering
- * trampoline are inserted by the linker and to keep sp 64-bit aligned.
*/
#define v7_exit_coherency_flush(level) \
asm volatile( \
".arch armv7-a \n\t" \
- "stmfd sp!, {fp, ip} \n\t" \
"mrc p15, 0, r0, c1, c0, 0 @ get SCTLR \n\t" \
"bic r0, r0, #"__stringify(CR_C)" \n\t" \
"mcr p15, 0, r0, c1, c0, 0 @ set SCTLR \n\t" \
@@ -463,10 +458,9 @@ static inline void __sync_cache_range_r(volatile void *p, size_t size)
"bic r0, r0, #(1 << 6) @ disable local coherency \n\t" \
"mcr p15, 0, r0, c1, c0, 1 @ set ACTLR \n\t" \
"isb \n\t" \
- "dsb \n\t" \
- "ldmfd sp!, {fp, ip}" \
- : : : "r0","r1","r2","r3","r4","r5","r6","r7", \
- "r9","r10","lr","memory" )
+ "dsb" \
+ : : : "r0","r1","r2","r3","r4","r5","r6", \
+ "r9","r10","ip","lr","memory" )
void flush_uprobe_xol_access(struct page *page, unsigned long uaddr,
void *kaddr, unsigned long len);
diff --git a/arch/arm/include/asm/current.h b/arch/arm/include/asm/current.h
index 6bf0aad672c3..1e1178bf176d 100644
--- a/arch/arm/include/asm/current.h
+++ b/arch/arm/include/asm/current.h
@@ -8,25 +8,18 @@
#define _ASM_ARM_CURRENT_H
#ifndef __ASSEMBLY__
+#include <asm/insn.h>
struct task_struct;
-static inline void set_current(struct task_struct *cur)
-{
- if (!IS_ENABLED(CONFIG_CURRENT_POINTER_IN_TPIDRURO))
- return;
-
- /* Set TPIDRURO */
- asm("mcr p15, 0, %0, c13, c0, 3" :: "r"(cur) : "memory");
-}
-
-#ifdef CONFIG_CURRENT_POINTER_IN_TPIDRURO
+extern struct task_struct *__current;
-static inline struct task_struct *get_current(void)
+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)
/*
@@ -39,16 +32,39 @@ static inline struct task_struct *get_current(void)
* https://github.com/ClangBuiltLinux/linux/issues/1485
*/
cur = __builtin_thread_pointer();
+#elif defined(CONFIG_CURRENT_POINTER_IN_TPIDRURO) || defined(CONFIG_SMP)
+ asm("0: mrc p15, 0, %0, c13, c0, 3 \n\t"
+#ifdef CONFIG_CPU_V6
+ "1: \n\t"
+ " .subsection 1 \n\t"
+#if defined(CONFIG_ARM_HAS_GROUP_RELOCS) && \
+ !(defined(MODULE) && defined(CONFIG_ARM_MODULE_PLTS))
+ "2: " LOAD_SYM_ARMV6(%0, __current) " \n\t"
+ " b 1b \n\t"
#else
- asm("mrc p15, 0, %0, c13, c0, 3" : "=r"(cur));
+ "2: ldr %0, 3f \n\t"
+ " ldr %0, [%0] \n\t"
+ " b 1b \n\t"
+ "3: .long __current \n\t"
+#endif
+ " .previous \n\t"
+ " .pushsection \".alt.smp.init\", \"a\" \n\t"
+ " .long 0b - . \n\t"
+ " b . + (2b - 0b) \n\t"
+ " .popsection \n\t"
+#endif
+ : "=r"(cur));
+#elif __LINUX_ARM_ARCH__>= 7 || \
+ !defined(CONFIG_ARM_HAS_GROUP_RELOCS) || \
+ (defined(MODULE) && defined(CONFIG_ARM_MODULE_PLTS))
+ cur = __current;
+#else
+ asm(LOAD_SYM_ARMV6(%0, __current) : "=r"(cur));
#endif
return cur;
}
#define current get_current()
-#else
-#include <asm-generic/current.h>
-#endif /* CONFIG_CURRENT_POINTER_IN_TPIDRURO */
#endif /* __ASSEMBLY__ */
diff --git a/arch/arm/include/asm/elf.h b/arch/arm/include/asm/elf.h
index b8102a6ddf16..d68101655b74 100644
--- a/arch/arm/include/asm/elf.h
+++ b/arch/arm/include/asm/elf.h
@@ -61,6 +61,9 @@ typedef struct user_fp elf_fpregset_t;
#define R_ARM_MOVT_ABS 44
#define R_ARM_MOVW_PREL_NC 45
#define R_ARM_MOVT_PREL 46
+#define R_ARM_ALU_PC_G0_NC 57
+#define R_ARM_ALU_PC_G1_NC 59
+#define R_ARM_LDR_PC_G2 63
#define R_ARM_THM_CALL 10
#define R_ARM_THM_JUMP24 30
diff --git a/arch/arm/include/asm/entry-macro-multi.S b/arch/arm/include/asm/entry-macro-multi.S
deleted file mode 100644
index dfc6bfa43012..000000000000
--- a/arch/arm/include/asm/entry-macro-multi.S
+++ /dev/null
@@ -1,40 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#include <asm/assembler.h>
-
-/*
- * Interrupt handling. Preserves r7, r8, r9
- */
- .macro arch_irq_handler_default
- get_irqnr_preamble r6, lr
-1: get_irqnr_and_base r0, r2, r6, lr
- movne r1, sp
- @
- @ routine called with r0 = irq number, r1 = struct pt_regs *
- @
- badrne lr, 1b
- bne asm_do_IRQ
-
-#ifdef CONFIG_SMP
- /*
- * XXX
- *
- * this macro assumes that irqstat (r2) and base (r6) are
- * preserved from get_irqnr_and_base above
- */
- ALT_SMP(test_for_ipi r0, r2, r6, lr)
- ALT_UP_B(9997f)
- movne r1, sp
- badrne lr, 1b
- bne do_IPI
-#endif
-9997:
- .endm
-
- .macro arch_irq_handler, symbol_name
- .align 5
- .global \symbol_name
-\symbol_name:
- mov r8, lr
- arch_irq_handler_default
- ret r8
- .endm
diff --git a/arch/arm/include/asm/ftrace.h b/arch/arm/include/asm/ftrace.h
index a4dbac07e4ef..7e9251ca29fe 100644
--- a/arch/arm/include/asm/ftrace.h
+++ b/arch/arm/include/asm/ftrace.h
@@ -2,6 +2,8 @@
#ifndef _ASM_ARM_FTRACE
#define _ASM_ARM_FTRACE
+#define HAVE_FUNCTION_GRAPH_FP_TEST
+
#ifdef CONFIG_DYNAMIC_FTRACE_WITH_REGS
#define ARCH_SUPPORTS_FTRACE_OPS 1
#endif
@@ -48,7 +50,7 @@ void *return_address(unsigned int);
static inline void *return_address(unsigned int level)
{
- return NULL;
+ return NULL;
}
#endif
diff --git a/arch/arm/include/asm/hardware/entry-macro-iomd.S b/arch/arm/include/asm/hardware/entry-macro-iomd.S
deleted file mode 100644
index f7692731e514..000000000000
--- a/arch/arm/include/asm/hardware/entry-macro-iomd.S
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- * arch/arm/include/asm/hardware/entry-macro-iomd.S
- *
- * Low-level IRQ helper macros for IOC/IOMD based platforms
- *
- * This file is licensed under the terms of the GNU General Public
- * License version 2. This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
- */
-
-/* IOC / IOMD based hardware */
-#include <asm/hardware/iomd.h>
-
- .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
- ldrb \irqstat, [\base, #IOMD_IRQREQB] @ get high priority first
- ldr \tmp, =irq_prio_h
- teq \irqstat, #0
-#ifdef IOMD_BASE
- ldrbeq \irqstat, [\base, #IOMD_DMAREQ] @ get dma
- addeq \tmp, \tmp, #256 @ irq_prio_h table size
- teqeq \irqstat, #0
- bne 2406f
-#endif
- ldrbeq \irqstat, [\base, #IOMD_IRQREQA] @ get low priority
- addeq \tmp, \tmp, #256 @ irq_prio_d table size
- teqeq \irqstat, #0
-#ifdef IOMD_IRQREQC
- ldrbeq \irqstat, [\base, #IOMD_IRQREQC]
- addeq \tmp, \tmp, #256 @ irq_prio_l table size
- teqeq \irqstat, #0
-#endif
-#ifdef IOMD_IRQREQD
- ldrbeq \irqstat, [\base, #IOMD_IRQREQD]
- addeq \tmp, \tmp, #256 @ irq_prio_lc table size
- teqeq \irqstat, #0
-#endif
-2406: ldrbne \irqnr, [\tmp, \irqstat] @ get IRQ number
- .endm
-
-/*
- * Interrupt table (incorporates priority). Please note that we
- * rely on the order of these tables (see above code).
- */
- .align 5
-irq_prio_h: .byte 0, 8, 9, 8,10,10,10,10,11,11,11,11,10,10,10,10
- .byte 12, 8, 9, 8,10,10,10,10,11,11,11,11,10,10,10,10
- .byte 13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10
- .byte 13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10
- .byte 14,14,14,14,10,10,10,10,11,11,11,11,10,10,10,10
- .byte 14,14,14,14,10,10,10,10,11,11,11,11,10,10,10,10
- .byte 13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10
- .byte 13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10
- .byte 15,15,15,15,10,10,10,10,11,11,11,11,10,10,10,10
- .byte 15,15,15,15,10,10,10,10,11,11,11,11,10,10,10,10
- .byte 13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10
- .byte 13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10
- .byte 15,15,15,15,10,10,10,10,11,11,11,11,10,10,10,10
- .byte 15,15,15,15,10,10,10,10,11,11,11,11,10,10,10,10
- .byte 13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10
- .byte 13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10
-#ifdef IOMD_BASE
-irq_prio_d: .byte 0,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
- .byte 20,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
- .byte 21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
- .byte 21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
- .byte 22,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
- .byte 22,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
- .byte 21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
- .byte 21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
- .byte 23,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
- .byte 23,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
- .byte 21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
- .byte 21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
- .byte 22,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
- .byte 22,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
- .byte 21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
- .byte 21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
-#endif
-irq_prio_l: .byte 0, 0, 1, 0, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3
- .byte 4, 0, 1, 0, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3
- .byte 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5
- .byte 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5
- .byte 6, 6, 6, 6, 6, 6, 6, 6, 3, 3, 3, 3, 3, 3, 3, 3
- .byte 6, 6, 6, 6, 6, 6, 6, 6, 3, 3, 3, 3, 3, 3, 3, 3
- .byte 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5
- .byte 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5
- .byte 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
- .byte 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
- .byte 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
- .byte 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
- .byte 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
- .byte 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
- .byte 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
- .byte 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
-#ifdef IOMD_IRQREQC
-irq_prio_lc: .byte 24,24,25,24,26,26,26,26,27,27,27,27,27,27,27,27
- .byte 28,24,25,24,26,26,26,26,27,27,27,27,27,27,27,27
- .byte 29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29
- .byte 29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29
- .byte 30,30,30,30,30,30,30,30,27,27,27,27,27,27,27,27
- .byte 30,30,30,30,30,30,30,30,27,27,27,27,27,27,27,27
- .byte 29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29
- .byte 29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29
- .byte 31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31
- .byte 31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31
- .byte 31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31
- .byte 31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31
- .byte 31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31
- .byte 31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31
- .byte 31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31
- .byte 31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31
-#endif
-#ifdef IOMD_IRQREQD
-irq_prio_ld: .byte 40,40,41,40,42,42,42,42,43,43,43,43,43,43,43,43
- .byte 44,40,41,40,42,42,42,42,43,43,43,43,43,43,43,43
- .byte 45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45
- .byte 45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45
- .byte 46,46,46,46,46,46,46,46,43,43,43,43,43,43,43,43
- .byte 46,46,46,46,46,46,46,46,43,43,43,43,43,43,43,43
- .byte 45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45
- .byte 45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45
- .byte 47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47
- .byte 47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47
- .byte 47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47
- .byte 47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47
- .byte 47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47
- .byte 47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47
- .byte 47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47
- .byte 47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47
-#endif
-
diff --git a/arch/arm/include/asm/insn.h b/arch/arm/include/asm/insn.h
index 5475cbf9fb6b..faf3d1c28368 100644
--- a/arch/arm/include/asm/insn.h
+++ b/arch/arm/include/asm/insn.h
@@ -2,6 +2,23 @@
#ifndef __ASM_ARM_INSN_H
#define __ASM_ARM_INSN_H
+#include <linux/types.h>
+
+/*
+ * Avoid a literal load by emitting a sequence of ADD/LDR instructions with the
+ * appropriate relocations. The combined sequence has a range of -/+ 256 MiB,
+ * which should be sufficient for the core kernel as well as modules loaded
+ * into the module region. (Not supported by LLD before release 14)
+ */
+#define LOAD_SYM_ARMV6(reg, sym) \
+ " .globl " #sym " \n\t" \
+ " .reloc 10f, R_ARM_ALU_PC_G0_NC, " #sym " \n\t" \
+ " .reloc 11f, R_ARM_ALU_PC_G1_NC, " #sym " \n\t" \
+ " .reloc 12f, R_ARM_LDR_PC_G2, " #sym " \n\t" \
+ "10: sub " #reg ", pc, #8 \n\t" \
+ "11: sub " #reg ", " #reg ", #4 \n\t" \
+ "12: ldr " #reg ", [" #reg ", #0] \n\t"
+
static inline unsigned long
arm_gen_nop(void)
{
diff --git a/arch/arm/include/asm/irq.h b/arch/arm/include/asm/irq.h
index 1cbcc462b07e..a7c2337b0c7d 100644
--- a/arch/arm/include/asm/irq.h
+++ b/arch/arm/include/asm/irq.h
@@ -26,7 +26,6 @@
struct irqaction;
struct pt_regs;
-extern void asm_do_IRQ(unsigned int, struct pt_regs *);
void handle_IRQ(unsigned int, struct pt_regs *);
void init_IRQ(void);
diff --git a/arch/arm/include/asm/mach/arch.h b/arch/arm/include/asm/mach/arch.h
index eec0c0bda766..9349e7a82c9c 100644
--- a/arch/arm/include/asm/mach/arch.h
+++ b/arch/arm/include/asm/mach/arch.h
@@ -56,9 +56,7 @@ struct machine_desc {
void (*init_time)(void);
void (*init_machine)(void);
void (*init_late)(void);
-#ifdef CONFIG_GENERIC_IRQ_MULTI_HANDLER
void (*handle_irq)(struct pt_regs *);
-#endif
void (*restart)(enum reboot_mode, const char *);
};
diff --git a/arch/arm/include/asm/mmu.h b/arch/arm/include/asm/mmu.h
index 1592a4264488..e049723840d3 100644
--- a/arch/arm/include/asm/mmu.h
+++ b/arch/arm/include/asm/mmu.h
@@ -10,7 +10,7 @@ typedef struct {
#else
int switch_pending;
#endif
- unsigned int vmalloc_seq;
+ atomic_t vmalloc_seq;
unsigned long sigpage;
#ifdef CONFIG_VDSO
unsigned long vdso;
diff --git a/arch/arm/include/asm/mmu_context.h b/arch/arm/include/asm/mmu_context.h
index 84e58956fcab..db2cb06aa8cf 100644
--- a/arch/arm/include/asm/mmu_context.h
+++ b/arch/arm/include/asm/mmu_context.h
@@ -23,6 +23,16 @@
void __check_vmalloc_seq(struct mm_struct *mm);
+#ifdef CONFIG_MMU
+static inline void check_vmalloc_seq(struct mm_struct *mm)
+{
+ if (!IS_ENABLED(CONFIG_ARM_LPAE) &&
+ unlikely(atomic_read(&mm->context.vmalloc_seq) !=
+ atomic_read(&init_mm.context.vmalloc_seq)))
+ __check_vmalloc_seq(mm);
+}
+#endif
+
#ifdef CONFIG_CPU_HAS_ASID
void check_and_switch_context(struct mm_struct *mm, struct task_struct *tsk);
@@ -52,8 +62,7 @@ static inline void a15_erratum_get_cpumask(int this_cpu, struct mm_struct *mm,
static inline void check_and_switch_context(struct mm_struct *mm,
struct task_struct *tsk)
{
- if (unlikely(mm->context.vmalloc_seq != init_mm.context.vmalloc_seq))
- __check_vmalloc_seq(mm);
+ check_vmalloc_seq(mm);
if (irqs_disabled())
/*
@@ -129,6 +138,15 @@ switch_mm(struct mm_struct *prev, struct mm_struct *next,
#endif
}
+#ifdef CONFIG_VMAP_STACK
+static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk)
+{
+ if (mm != &init_mm)
+ check_vmalloc_seq(mm);
+}
+#define enter_lazy_tlb enter_lazy_tlb
+#endif
+
#include <asm-generic/mmu_context.h>
#endif
diff --git a/arch/arm/include/asm/page.h b/arch/arm/include/asm/page.h
index 11b058a72a5b..5fcc8a600e36 100644
--- a/arch/arm/include/asm/page.h
+++ b/arch/arm/include/asm/page.h
@@ -147,6 +147,9 @@ extern void copy_page(void *to, const void *from);
#include <asm/pgtable-3level-types.h>
#else
#include <asm/pgtable-2level-types.h>
+#ifdef CONFIG_VMAP_STACK
+#define ARCH_PAGE_TABLE_SYNC_MASK PGTBL_PMD_MODIFIED
+#endif
#endif
#endif /* CONFIG_MMU */
diff --git a/arch/arm/include/asm/paravirt_api_clock.h b/arch/arm/include/asm/paravirt_api_clock.h
new file mode 100644
index 000000000000..65ac7cee0dad
--- /dev/null
+++ b/arch/arm/include/asm/paravirt_api_clock.h
@@ -0,0 +1 @@
+#include <asm/paravirt.h>
diff --git a/arch/arm/include/asm/percpu.h b/arch/arm/include/asm/percpu.h
index e2fcb3cfd3de..7545c87c251f 100644
--- a/arch/arm/include/asm/percpu.h
+++ b/arch/arm/include/asm/percpu.h
@@ -5,20 +5,27 @@
#ifndef _ASM_ARM_PERCPU_H_
#define _ASM_ARM_PERCPU_H_
+#include <asm/insn.h>
+
register unsigned long current_stack_pointer asm ("sp");
/*
* Same as asm-generic/percpu.h, except that we store the per cpu offset
* in the TPIDRPRW. TPIDRPRW only exists on V6K and V7
*/
-#if defined(CONFIG_SMP) && !defined(CONFIG_CPU_V6)
+#ifdef CONFIG_SMP
static inline void set_my_cpu_offset(unsigned long off)
{
+ extern unsigned int smp_on_up;
+
+ if (IS_ENABLED(CONFIG_CPU_V6) && !smp_on_up)
+ return;
+
/* Set TPIDRPRW */
asm volatile("mcr p15, 0, %0, c13, c0, 4" : : "r" (off) : "memory");
}
-static inline unsigned long __my_cpu_offset(void)
+static __always_inline unsigned long __my_cpu_offset(void)
{
unsigned long off;
@@ -27,8 +34,28 @@ static inline unsigned long __my_cpu_offset(void)
* We want to allow caching the value, so avoid using volatile and
* instead use a fake stack read to hazard against barrier().
*/
- asm("mrc p15, 0, %0, c13, c0, 4" : "=r" (off)
- : "Q" (*(const unsigned long *)current_stack_pointer));
+ asm("0: mrc p15, 0, %0, c13, c0, 4 \n\t"
+#ifdef CONFIG_CPU_V6
+ "1: \n\t"
+ " .subsection 1 \n\t"
+#if defined(CONFIG_ARM_HAS_GROUP_RELOCS) && \
+ !(defined(MODULE) && defined(CONFIG_ARM_MODULE_PLTS))
+ "2: " LOAD_SYM_ARMV6(%0, __per_cpu_offset) " \n\t"
+ " b 1b \n\t"
+#else
+ "2: ldr %0, 3f \n\t"
+ " ldr %0, [%0] \n\t"
+ " b 1b \n\t"
+ "3: .long __per_cpu_offset \n\t"
+#endif
+ " .previous \n\t"
+ " .pushsection \".alt.smp.init\", \"a\" \n\t"
+ " .long 0b - . \n\t"
+ " b . + (2b - 0b) \n\t"
+ " .popsection \n\t"
+#endif
+ : "=r" (off)
+ : "Q" (*(const unsigned long *)current_stack_pointer));
return off;
}
diff --git a/arch/arm/include/asm/pgtable-2level.h b/arch/arm/include/asm/pgtable-2level.h
index 70fe69bdcce2..92abd4cd8ca2 100644
--- a/arch/arm/include/asm/pgtable-2level.h
+++ b/arch/arm/include/asm/pgtable-2level.h
@@ -208,6 +208,8 @@ static inline pmd_t *pmd_offset(pud_t *pud, unsigned long addr)
}
#define pmd_offset pmd_offset
+#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)
diff --git a/arch/arm/include/asm/processor.h b/arch/arm/include/asm/processor.h
index 6af68edfa53a..bdc35c0e8dfb 100644
--- a/arch/arm/include/asm/processor.h
+++ b/arch/arm/include/asm/processor.h
@@ -96,6 +96,7 @@ unsigned long __get_wchan(struct task_struct *p);
#define __ALT_SMP_ASM(smp, up) \
"9998: " smp "\n" \
" .pushsection \".alt.smp.init\", \"a\"\n" \
+ " .align 2\n" \
" .long 9998b - .\n" \
" " up "\n" \
" .popsection\n"
diff --git a/arch/arm/include/asm/smp.h b/arch/arm/include/asm/smp.h
index f16cbbd5cda4..7c1c90d9f582 100644
--- a/arch/arm/include/asm/smp.h
+++ b/arch/arm/include/asm/smp.h
@@ -25,11 +25,6 @@ struct seq_file;
extern void show_ipi_list(struct seq_file *, int);
/*
- * Called from assembly code, this handles an IPI.
- */
-asmlinkage void do_IPI(int ipinr, struct pt_regs *regs);
-
-/*
* Called from C code, this handles an IPI.
*/
void handle_IPI(int ipinr, struct pt_regs *regs);
diff --git a/arch/arm/include/asm/spectre.h b/arch/arm/include/asm/spectre.h
new file mode 100644
index 000000000000..85f9e538fb32
--- /dev/null
+++ b/arch/arm/include/asm/spectre.h
@@ -0,0 +1,38 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#ifndef __ASM_SPECTRE_H
+#define __ASM_SPECTRE_H
+
+enum {
+ SPECTRE_UNAFFECTED,
+ SPECTRE_MITIGATED,
+ SPECTRE_VULNERABLE,
+};
+
+enum {
+ __SPECTRE_V2_METHOD_BPIALL,
+ __SPECTRE_V2_METHOD_ICIALLU,
+ __SPECTRE_V2_METHOD_SMC,
+ __SPECTRE_V2_METHOD_HVC,
+ __SPECTRE_V2_METHOD_LOOP8,
+};
+
+enum {
+ SPECTRE_V2_METHOD_BPIALL = BIT(__SPECTRE_V2_METHOD_BPIALL),
+ SPECTRE_V2_METHOD_ICIALLU = BIT(__SPECTRE_V2_METHOD_ICIALLU),
+ SPECTRE_V2_METHOD_SMC = BIT(__SPECTRE_V2_METHOD_SMC),
+ SPECTRE_V2_METHOD_HVC = BIT(__SPECTRE_V2_METHOD_HVC),
+ SPECTRE_V2_METHOD_LOOP8 = BIT(__SPECTRE_V2_METHOD_LOOP8),
+};
+
+#ifdef CONFIG_GENERIC_CPU_VULNERABILITIES
+void spectre_v2_update_state(unsigned int state, unsigned int methods);
+#else
+static inline void spectre_v2_update_state(unsigned int state,
+ unsigned int methods)
+{}
+#endif
+
+int spectre_bhb_update_vectors(unsigned int method);
+
+#endif
diff --git a/arch/arm/include/asm/stacktrace.h b/arch/arm/include/asm/stacktrace.h
index 8f54f9ad8a9b..3e78f921b8b2 100644
--- a/arch/arm/include/asm/stacktrace.h
+++ b/arch/arm/include/asm/stacktrace.h
@@ -14,6 +14,9 @@ struct stackframe {
unsigned long sp;
unsigned long lr;
unsigned long pc;
+
+ /* address of the LR value on the stack */
+ unsigned long *lr_addr;
#ifdef CONFIG_KRETPROBES
struct llist_node *kr_cur;
struct task_struct *tsk;
@@ -36,5 +39,7 @@ void arm_get_current_stackframe(struct pt_regs *regs, struct stackframe *frame)
extern int unwind_frame(struct stackframe *frame);
extern void walk_stackframe(struct stackframe *frame,
int (*fn)(struct stackframe *, void *), void *data);
+extern void dump_mem(const char *lvl, const char *str, unsigned long bottom,
+ unsigned long top);
#endif /* __ASM_STACKTRACE_H */
diff --git a/arch/arm/include/asm/switch_to.h b/arch/arm/include/asm/switch_to.h
index 61e4a3c4ca6e..9372348516ce 100644
--- a/arch/arm/include/asm/switch_to.h
+++ b/arch/arm/include/asm/switch_to.h
@@ -3,6 +3,7 @@
#define __ASM_ARM_SWITCH_TO_H
#include <linux/thread_info.h>
+#include <asm/smp_plat.h>
/*
* For v7 SMP cores running a preemptible kernel we may be pre-empted
@@ -26,7 +27,7 @@ extern struct task_struct *__switch_to(struct task_struct *, struct thread_info
#define switch_to(prev,next,last) \
do { \
__complete_pending_tlbi(); \
- if (IS_ENABLED(CONFIG_CURRENT_POINTER_IN_TPIDRURO)) \
+ if (IS_ENABLED(CONFIG_CURRENT_POINTER_IN_TPIDRURO) || is_smp()) \
__this_cpu_write(__entry_task, next); \
last = __switch_to(prev,task_thread_info(prev), task_thread_info(next)); \
} while (0)
diff --git a/arch/arm/include/asm/thread_info.h b/arch/arm/include/asm/thread_info.h
index 164e15f26485..aecc403b2880 100644
--- a/arch/arm/include/asm/thread_info.h
+++ b/arch/arm/include/asm/thread_info.h
@@ -25,6 +25,14 @@
#define THREAD_SIZE (PAGE_SIZE << THREAD_SIZE_ORDER)
#define THREAD_START_SP (THREAD_SIZE - 8)
+#ifdef CONFIG_VMAP_STACK
+#define THREAD_ALIGN (2 * THREAD_SIZE)
+#else
+#define THREAD_ALIGN THREAD_SIZE
+#endif
+
+#define OVERFLOW_STACK_SIZE SZ_4K
+
#ifndef __ASSEMBLY__
struct task_struct;
@@ -54,9 +62,6 @@ struct cpu_context_save {
struct thread_info {
unsigned long flags; /* low level flags */
int preempt_count; /* 0 => preemptable, <0 => bug */
-#ifndef CONFIG_THREAD_INFO_IN_TASK
- struct task_struct *task; /* main task structure */
-#endif
__u32 cpu; /* cpu */
__u32 cpu_domain; /* cpu domain */
struct cpu_context_save cpu_context; /* cpu context */
@@ -72,39 +77,15 @@ struct thread_info {
#define INIT_THREAD_INFO(tsk) \
{ \
- INIT_THREAD_INFO_TASK(tsk) \
.flags = 0, \
.preempt_count = INIT_PREEMPT_COUNT, \
}
-#ifdef CONFIG_THREAD_INFO_IN_TASK
-#define INIT_THREAD_INFO_TASK(tsk)
-
static inline struct task_struct *thread_task(struct thread_info* ti)
{
return (struct task_struct *)ti;
}
-#else
-#define INIT_THREAD_INFO_TASK(tsk) .task = &(tsk),
-
-static inline struct task_struct *thread_task(struct thread_info* ti)
-{
- return ti->task;
-}
-
-/*
- * how to get the thread information struct from C
- */
-static inline struct thread_info *current_thread_info(void) __attribute_const__;
-
-static inline struct thread_info *current_thread_info(void)
-{
- return (struct thread_info *)
- (current_stack_pointer & ~(THREAD_SIZE - 1));
-}
-#endif
-
#define thread_saved_pc(tsk) \
((unsigned long)(task_thread_info(tsk)->cpu_context.pc))
#define thread_saved_sp(tsk) \
diff --git a/arch/arm/include/asm/tls.h b/arch/arm/include/asm/tls.h
index c3296499176c..3dcd0f71a0da 100644
--- a/arch/arm/include/asm/tls.h
+++ b/arch/arm/include/asm/tls.h
@@ -18,21 +18,32 @@
.endm
.macro switch_tls_v6, base, tp, tpuser, tmp1, tmp2
- ldr \tmp1, =elf_hwcap
- ldr \tmp1, [\tmp1, #0]
+#ifdef CONFIG_SMP
+ALT_SMP(nop)
+ALT_UP_B(.L0_\@)
+ .subsection 1
+#endif
+.L0_\@:
+ ldr_va \tmp1, elf_hwcap
mov \tmp2, #0xffff0fff
tst \tmp1, #HWCAP_TLS @ hardware TLS available?
streq \tp, [\tmp2, #-15] @ set TLS value at 0xffff0ff0
- mrcne p15, 0, \tmp2, c13, c0, 2 @ get the user r/w register
- mcrne p15, 0, \tp, c13, c0, 3 @ yes, set TLS register
- mcrne p15, 0, \tpuser, c13, c0, 2 @ set user r/w register
- strne \tmp2, [\base, #TI_TP_VALUE + 4] @ save it
+ beq .L2_\@
+ mcr p15, 0, \tp, c13, c0, 3 @ yes, set TLS register
+#ifdef CONFIG_SMP
+ b .L1_\@
+ .previous
+#endif
+.L1_\@: switch_tls_v6k \base, \tp, \tpuser, \tmp1, \tmp2
+.L2_\@:
.endm
.macro switch_tls_software, base, tp, tpuser, tmp1, tmp2
mov \tmp1, #0xffff0fff
str \tp, [\tmp1, #-15] @ set TLS value at 0xffff0ff0
.endm
+#else
+#include <asm/smp_plat.h>
#endif
#ifdef CONFIG_TLS_REG_EMUL
@@ -43,7 +54,7 @@
#elif defined(CONFIG_CPU_V6)
#define tls_emu 0
#define has_tls_reg (elf_hwcap & HWCAP_TLS)
-#define defer_tls_reg_update 0
+#define defer_tls_reg_update is_smp()
#define switch_tls switch_tls_v6
#elif defined(CONFIG_CPU_32v6K)
#define tls_emu 0
@@ -81,11 +92,11 @@ static inline void set_tls(unsigned long val)
*/
barrier();
- if (!tls_emu && !defer_tls_reg_update) {
- if (has_tls_reg) {
+ if (!tls_emu) {
+ if (has_tls_reg && !defer_tls_reg_update) {
asm("mcr p15, 0, %0, c13, c0, 3"
: : "r" (val));
- } else {
+ } else if (!has_tls_reg) {
#ifdef CONFIG_KUSER_HELPERS
/*
* User space must never try to access this
diff --git a/arch/arm/include/asm/uaccess.h b/arch/arm/include/asm/uaccess.h
index 36fbc3329252..2fcbec9c306c 100644
--- a/arch/arm/include/asm/uaccess.h
+++ b/arch/arm/include/asm/uaccess.h
@@ -11,6 +11,7 @@
#include <linux/string.h>
#include <asm/memory.h>
#include <asm/domain.h>
+#include <asm/unaligned.h>
#include <asm/unified.h>
#include <asm/compiler.h>
@@ -55,21 +56,6 @@ extern int __put_user_bad(void);
#ifdef CONFIG_MMU
/*
- * We use 33-bit arithmetic here. Success returns zero, failure returns
- * addr_limit. We take advantage that addr_limit will be zero for KERNEL_DS,
- * so this will always return success in that case.
- */
-#define __range_ok(addr, size) ({ \
- unsigned long flag, roksum; \
- __chk_user_ptr(addr); \
- __asm__(".syntax unified\n" \
- "adds %1, %2, %3; sbcscc %1, %1, %0; movcc %0, #0" \
- : "=&r" (flag), "=&r" (roksum) \
- : "r" (addr), "Ir" (size), "0" (TASK_SIZE) \
- : "cc"); \
- flag; })
-
-/*
* This is a type: either unsigned long, if the argument fits into
* that type, or otherwise unsigned long long.
*/
@@ -240,15 +226,12 @@ extern int __put_user_8(void *, unsigned long long);
#else /* CONFIG_MMU */
-#define __addr_ok(addr) ((void)(addr), 1)
-#define __range_ok(addr, size) ((void)(addr), 0)
-
#define get_user(x, p) __get_user(x, p)
#define __put_user_check __put_user_nocheck
#endif /* CONFIG_MMU */
-#define access_ok(addr, size) (__range_ok(addr, size) == 0)
+#include <asm-generic/access_ok.h>
#ifdef CONFIG_CPU_SPECTRE
/*
@@ -475,8 +458,6 @@ do { \
: "r" (x), "i" (-EFAULT) \
: "cc")
-#define HAVE_GET_KERNEL_NOFAULT
-
#define __get_kernel_nofault(dst, src, type, err_label) \
do { \
const type *__pk_ptr = (src); \
@@ -497,7 +478,10 @@ do { \
} \
default: __err = __get_user_bad(); break; \
} \
- *(type *)(dst) = __val; \
+ if (IS_ENABLED(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS)) \
+ put_unaligned(__val, (type *)(dst)); \
+ else \
+ *(type *)(dst) = __val; /* aligned by caller */ \
if (__err) \
goto err_label; \
} while (0)
@@ -507,7 +491,9 @@ do { \
const type *__pk_ptr = (dst); \
unsigned long __dst = (unsigned long)__pk_ptr; \
int __err = 0; \
- type __val = *(type *)src; \
+ type __val = IS_ENABLED(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) \
+ ? get_unaligned((type *)(src)) \
+ : *(type *)(src); /* aligned by caller */ \
switch (sizeof(type)) { \
case 1: __put_user_asm_byte(__val, __dst, __err, ""); break; \
case 2: __put_user_asm_half(__val, __dst, __err, ""); break; \
diff --git a/arch/arm/include/asm/v7m.h b/arch/arm/include/asm/v7m.h
index 2cb00d15831b..4512f7e1918f 100644
--- a/arch/arm/include/asm/v7m.h
+++ b/arch/arm/include/asm/v7m.h
@@ -13,6 +13,7 @@
#define V7M_SCB_ICSR_PENDSVSET (1 << 28)
#define V7M_SCB_ICSR_PENDSVCLR (1 << 27)
#define V7M_SCB_ICSR_RETTOBASE (1 << 11)
+#define V7M_SCB_ICSR_VECTACTIVE 0x000001ff
#define V7M_SCB_VTOR 0x08
@@ -38,7 +39,7 @@
#define V7M_SCB_SHCSR_MEMFAULTENA (1 << 16)
#define V7M_xPSR_FRAMEPTRALIGN 0x00000200
-#define V7M_xPSR_EXCEPTIONNO 0x000001ff
+#define V7M_xPSR_EXCEPTIONNO V7M_SCB_ICSR_VECTACTIVE
/*
* When branching to an address that has bits [31:28] == 0xf an exception return
diff --git a/arch/arm/include/asm/vmlinux.lds.h b/arch/arm/include/asm/vmlinux.lds.h
index 4a91428c324d..fad45c884e98 100644
--- a/arch/arm/include/asm/vmlinux.lds.h
+++ b/arch/arm/include/asm/vmlinux.lds.h
@@ -26,6 +26,19 @@
#define ARM_MMU_DISCARD(x) x
#endif
+/*
+ * ld.lld does not support NOCROSSREFS:
+ * https://github.com/ClangBuiltLinux/linux/issues/1609
+ */
+#ifdef CONFIG_LD_IS_LLD
+#define NOCROSSREFS
+#endif
+
+/* Set start/end symbol names to the LMA for the section */
+#define ARM_LMA(sym, section) \
+ sym##_start = LOADADDR(section); \
+ sym##_end = LOADADDR(section) + SIZEOF(section)
+
#define PROC_INFO \
. = ALIGN(4); \
__proc_info_begin = .; \
@@ -110,19 +123,31 @@
* only thing that matters is their relative offsets
*/
#define ARM_VECTORS \
- __vectors_start = .; \
- .vectors 0xffff0000 : AT(__vectors_start) { \
- *(.vectors) \
+ __vectors_lma = .; \
+ OVERLAY 0xffff0000 : NOCROSSREFS AT(__vectors_lma) { \
+ .vectors { \
+ *(.vectors) \
+ } \
+ .vectors.bhb.loop8 { \
+ *(.vectors.bhb.loop8) \
+ } \
+ .vectors.bhb.bpiall { \
+ *(.vectors.bhb.bpiall) \
+ } \
} \
- . = __vectors_start + SIZEOF(.vectors); \
- __vectors_end = .; \
+ ARM_LMA(__vectors, .vectors); \
+ ARM_LMA(__vectors_bhb_loop8, .vectors.bhb.loop8); \
+ ARM_LMA(__vectors_bhb_bpiall, .vectors.bhb.bpiall); \
+ . = __vectors_lma + SIZEOF(.vectors) + \
+ SIZEOF(.vectors.bhb.loop8) + \
+ SIZEOF(.vectors.bhb.bpiall); \
\
- __stubs_start = .; \
- .stubs ADDR(.vectors) + 0x1000 : AT(__stubs_start) { \
+ __stubs_lma = .; \
+ .stubs ADDR(.vectors) + 0x1000 : AT(__stubs_lma) { \
*(.stubs) \
} \
- . = __stubs_start + SIZEOF(.stubs); \
- __stubs_end = .; \
+ ARM_LMA(__stubs, .stubs); \
+ . = __stubs_lma + SIZEOF(.stubs); \
\
PROVIDE(vector_fiq_offset = vector_fiq - ADDR(.vectors));
diff --git a/arch/arm/include/asm/xor.h b/arch/arm/include/asm/xor.h
index aefddec79286..669cad5194d3 100644
--- a/arch/arm/include/asm/xor.h
+++ b/arch/arm/include/asm/xor.h
@@ -44,7 +44,8 @@
: "0" (dst), "r" (a1), "r" (a2), "r" (a3), "r" (a4))
static void
-xor_arm4regs_2(unsigned long bytes, unsigned long *p1, unsigned long *p2)
+xor_arm4regs_2(unsigned long bytes, unsigned long * __restrict p1,
+ const unsigned long * __restrict p2)
{
unsigned int lines = bytes / sizeof(unsigned long) / 4;
register unsigned int a1 __asm__("r4");
@@ -64,8 +65,9 @@ xor_arm4regs_2(unsigned long bytes, unsigned long *p1, unsigned long *p2)
}
static void
-xor_arm4regs_3(unsigned long bytes, unsigned long *p1, unsigned long *p2,
- unsigned long *p3)
+xor_arm4regs_3(unsigned long bytes, unsigned long * __restrict p1,
+ const unsigned long * __restrict p2,
+ const unsigned long * __restrict p3)
{
unsigned int lines = bytes / sizeof(unsigned long) / 4;
register unsigned int a1 __asm__("r4");
@@ -86,8 +88,10 @@ xor_arm4regs_3(unsigned long bytes, unsigned long *p1, unsigned long *p2,
}
static void
-xor_arm4regs_4(unsigned long bytes, unsigned long *p1, unsigned long *p2,
- unsigned long *p3, unsigned long *p4)
+xor_arm4regs_4(unsigned long bytes, unsigned long * __restrict p1,
+ const unsigned long * __restrict p2,
+ const unsigned long * __restrict p3,
+ const unsigned long * __restrict p4)
{
unsigned int lines = bytes / sizeof(unsigned long) / 2;
register unsigned int a1 __asm__("r8");
@@ -105,8 +109,11 @@ xor_arm4regs_4(unsigned long bytes, unsigned long *p1, unsigned long *p2,
}
static void
-xor_arm4regs_5(unsigned long bytes, unsigned long *p1, unsigned long *p2,
- unsigned long *p3, unsigned long *p4, unsigned long *p5)
+xor_arm4regs_5(unsigned long bytes, unsigned long * __restrict p1,
+ const unsigned long * __restrict p2,
+ const unsigned long * __restrict p3,
+ const unsigned long * __restrict p4,
+ const unsigned long * __restrict p5)
{
unsigned int lines = bytes / sizeof(unsigned long) / 2;
register unsigned int a1 __asm__("r8");
@@ -146,7 +153,8 @@ static struct xor_block_template xor_block_arm4regs = {
extern struct xor_block_template const xor_block_neon_inner;
static void
-xor_neon_2(unsigned long bytes, unsigned long *p1, unsigned long *p2)
+xor_neon_2(unsigned long bytes, unsigned long * __restrict p1,
+ const unsigned long * __restrict p2)
{
if (in_interrupt()) {
xor_arm4regs_2(bytes, p1, p2);
@@ -158,8 +166,9 @@ xor_neon_2(unsigned long bytes, unsigned long *p1, unsigned long *p2)
}
static void
-xor_neon_3(unsigned long bytes, unsigned long *p1, unsigned long *p2,
- unsigned long *p3)
+xor_neon_3(unsigned long bytes, unsigned long * __restrict p1,
+ const unsigned long * __restrict p2,
+ const unsigned long * __restrict p3)
{
if (in_interrupt()) {
xor_arm4regs_3(bytes, p1, p2, p3);
@@ -171,8 +180,10 @@ xor_neon_3(unsigned long bytes, unsigned long *p1, unsigned long *p2,
}
static void
-xor_neon_4(unsigned long bytes, unsigned long *p1, unsigned long *p2,
- unsigned long *p3, unsigned long *p4)
+xor_neon_4(unsigned long bytes, unsigned long * __restrict p1,
+ const unsigned long * __restrict p2,
+ const unsigned long * __restrict p3,
+ const unsigned long * __restrict p4)
{
if (in_interrupt()) {
xor_arm4regs_4(bytes, p1, p2, p3, p4);
@@ -184,8 +195,11 @@ xor_neon_4(unsigned long bytes, unsigned long *p1, unsigned long *p2,
}
static void
-xor_neon_5(unsigned long bytes, unsigned long *p1, unsigned long *p2,
- unsigned long *p3, unsigned long *p4, unsigned long *p5)
+xor_neon_5(unsigned long bytes, unsigned long * __restrict p1,
+ const unsigned long * __restrict p2,
+ const unsigned long * __restrict p3,
+ const unsigned long * __restrict p4,
+ const unsigned long * __restrict p5)
{
if (in_interrupt()) {
xor_arm4regs_5(bytes, p1, p2, p3, p4, p5);
diff --git a/arch/arm/include/uapi/asm/signal.h b/arch/arm/include/uapi/asm/signal.h
index c9a3ea1d8d41..9e2178420db2 100644
--- a/arch/arm/include/uapi/asm/signal.h
+++ b/arch/arm/include/uapi/asm/signal.h
@@ -93,7 +93,7 @@ struct sigaction {
typedef struct sigaltstack {
void __user *ss_sp;
int ss_flags;
- size_t ss_size;
+ __kernel_size_t ss_size;
} stack_t;
diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile
index ae295a3bcfef..553866751e1a 100644
--- a/arch/arm/kernel/Makefile
+++ b/arch/arm/kernel/Makefile
@@ -10,6 +10,7 @@ ifdef CONFIG_FUNCTION_TRACER
CFLAGS_REMOVE_ftrace.o = -pg
CFLAGS_REMOVE_insn.o = -pg
CFLAGS_REMOVE_patch.o = -pg
+CFLAGS_REMOVE_unwind.o = -pg
endif
CFLAGS_REMOVE_return_address.o = -pg
@@ -106,4 +107,6 @@ endif
obj-$(CONFIG_HAVE_ARM_SMCCC) += smccc-call.o
+obj-$(CONFIG_GENERIC_CPU_VULNERABILITIES) += spectre.o
+
extra-y := $(head-y) vmlinux.lds
diff --git a/arch/arm/kernel/asm-offsets.c b/arch/arm/kernel/asm-offsets.c
index 645845e4982a..2c8d76fd7c66 100644
--- a/arch/arm/kernel/asm-offsets.c
+++ b/arch/arm/kernel/asm-offsets.c
@@ -43,9 +43,6 @@ int main(void)
BLANK();
DEFINE(TI_FLAGS, offsetof(struct thread_info, flags));
DEFINE(TI_PREEMPT, offsetof(struct thread_info, preempt_count));
-#ifndef CONFIG_THREAD_INFO_IN_TASK
- DEFINE(TI_TASK, offsetof(struct thread_info, task));
-#endif
DEFINE(TI_CPU, offsetof(struct thread_info, cpu));
DEFINE(TI_CPU_DOMAIN, offsetof(struct thread_info, cpu_domain));
DEFINE(TI_CPU_SAVE, offsetof(struct thread_info, cpu_context));
diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S
index 5cd057859fe9..06508698abb8 100644
--- a/arch/arm/kernel/entry-armv.S
+++ b/arch/arm/kernel/entry-armv.S
@@ -19,9 +19,6 @@
#include <asm/glue-df.h>
#include <asm/glue-pf.h>
#include <asm/vfpmacros.h>
-#ifndef CONFIG_GENERIC_IRQ_MULTI_HANDLER
-#include <mach/entry-macro.S>
-#endif
#include <asm/thread_notify.h>
#include <asm/unwind.h>
#include <asm/unistd.h>
@@ -30,19 +27,35 @@
#include <asm/uaccess-asm.h>
#include "entry-header.S"
-#include <asm/entry-macro-multi.S>
#include <asm/probes.h>
/*
* Interrupt handling.
*/
- .macro irq_handler
-#ifdef CONFIG_GENERIC_IRQ_MULTI_HANDLER
- mov r0, sp
- bl generic_handle_arch_irq
-#else
- arch_irq_handler_default
+ .macro irq_handler, from_user:req
+ mov r1, sp
+ ldr_this_cpu r2, irq_stack_ptr, r2, r3
+ .if \from_user == 0
+ @
+ @ If we took the interrupt while running in the kernel, we may already
+ @ be using the IRQ stack, so revert to the original value in that case.
+ @
+ subs r3, r2, r1 @ SP above bottom of IRQ stack?
+ rsbscs r3, r3, #THREAD_SIZE @ ... and below the top?
+#ifdef CONFIG_VMAP_STACK
+ ldr_va r3, high_memory, cc @ End of the linear region
+ cmpcc r3, r1 @ Stack pointer was below it?
#endif
+ bcc 0f @ If not, switch to the IRQ stack
+ mov r0, r1
+ bl generic_handle_arch_irq
+ b 1f
+0:
+ .endif
+
+ mov_l r0, generic_handle_arch_irq
+ bl call_with_stack
+1:
.endm
.macro pabt_helper
@@ -140,27 +153,35 @@ ENDPROC(__und_invalid)
#define SPFIX(code...)
#endif
- .macro svc_entry, stack_hole=0, trace=1, uaccess=1
+ .macro svc_entry, stack_hole=0, trace=1, uaccess=1, overflow_check=1
UNWIND(.fnstart )
- UNWIND(.save {r0 - pc} )
- sub sp, sp, #(SVC_REGS_SIZE + \stack_hole - 4)
+ sub sp, sp, #(SVC_REGS_SIZE + \stack_hole)
+ THUMB( add sp, r1 ) @ get SP in a GPR without
+ THUMB( sub r1, sp, r1 ) @ using a temp register
+
+ .if \overflow_check
+ UNWIND(.save {r0 - pc} )
+ do_overflow_check (SVC_REGS_SIZE + \stack_hole)
+ .endif
+
#ifdef CONFIG_THUMB2_KERNEL
- SPFIX( str r0, [sp] ) @ temporarily saved
- SPFIX( mov r0, sp )
- SPFIX( tst r0, #4 ) @ test original stack alignment
- SPFIX( ldr r0, [sp] ) @ restored
+ tst r1, #4 @ test stack pointer alignment
+ sub r1, sp, r1 @ restore original R1
+ sub sp, r1 @ restore original SP
#else
SPFIX( tst sp, #4 )
#endif
- SPFIX( subeq sp, sp, #4 )
- stmia sp, {r1 - r12}
+ SPFIX( subne sp, sp, #4 )
+
+ ARM( stmib sp, {r1 - r12} )
+ THUMB( stmia sp, {r0 - r12} ) @ No STMIB in Thumb-2
ldmia r0, {r3 - r5}
- add r7, sp, #S_SP - 4 @ here for interlock avoidance
+ add r7, sp, #S_SP @ here for interlock avoidance
mov r6, #-1 @ "" "" "" ""
- add r2, sp, #(SVC_REGS_SIZE + \stack_hole - 4)
- SPFIX( addeq r2, r2, #4 )
- str r3, [sp, #-4]! @ save the "real" r0 copied
+ add r2, sp, #(SVC_REGS_SIZE + \stack_hole)
+ SPFIX( addne r2, r2, #4 )
+ str r3, [sp] @ save the "real" r0 copied
@ from the exception stack
mov r3, lr
@@ -199,7 +220,7 @@ ENDPROC(__dabt_svc)
.align 5
__irq_svc:
svc_entry
- irq_handler
+ irq_handler from_user=0
#ifdef CONFIG_PREEMPTION
ldr r8, [tsk, #TI_PREEMPT] @ get preempt count
@@ -426,7 +447,7 @@ ENDPROC(__dabt_usr)
__irq_usr:
usr_entry
kuser_cmpxchg_check
- irq_handler
+ irq_handler from_user=1
get_thread_info tsk
mov why, #0
b ret_to_user_from_irq
@@ -752,16 +773,17 @@ ENTRY(__switch_to)
ldr r6, [r2, #TI_CPU_DOMAIN]
#endif
switch_tls r1, r4, r5, r3, r7
-#if defined(CONFIG_STACKPROTECTOR) && !defined(CONFIG_SMP)
- ldr r7, [r2, #TI_TASK]
+#if defined(CONFIG_STACKPROTECTOR) && !defined(CONFIG_SMP) && \
+ !defined(CONFIG_STACKPROTECTOR_PER_TASK)
ldr r8, =__stack_chk_guard
.if (TSK_STACK_CANARY > IMM12_MASK)
- add r7, r7, #TSK_STACK_CANARY & ~IMM12_MASK
+ add r9, r2, #TSK_STACK_CANARY & ~IMM12_MASK
+ ldr r9, [r9, #TSK_STACK_CANARY & IMM12_MASK]
+ .else
+ ldr r9, [r2, #TSK_STACK_CANARY & IMM12_MASK]
.endif
- ldr r7, [r7, #TSK_STACK_CANARY & IMM12_MASK]
-#elif defined(CONFIG_CURRENT_POINTER_IN_TPIDRURO)
- mov r7, r2 @ Preserve 'next'
#endif
+ mov r7, r2 @ Preserve 'next'
#ifdef CONFIG_CPU_USE_DOMAINS
mcr p15, 0, r6, c3, c0, 0 @ Set domain register
#endif
@@ -770,19 +792,102 @@ ENTRY(__switch_to)
ldr r0, =thread_notify_head
mov r1, #THREAD_NOTIFY_SWITCH
bl atomic_notifier_call_chain
-#if defined(CONFIG_STACKPROTECTOR) && !defined(CONFIG_SMP)
- str r7, [r8]
+#if defined(CONFIG_STACKPROTECTOR) && !defined(CONFIG_SMP) && \
+ !defined(CONFIG_STACKPROTECTOR_PER_TASK)
+ str r9, [r8]
#endif
- THUMB( mov ip, r4 )
mov r0, r5
- set_current r7
- ARM( ldmia r4, {r4 - sl, fp, sp, pc} ) @ Load all regs saved previously
- THUMB( ldmia ip!, {r4 - sl, fp} ) @ Load all regs saved previously
- THUMB( ldr sp, [ip], #4 )
- THUMB( ldr pc, [ip] )
+#if !defined(CONFIG_THUMB2_KERNEL) && !defined(CONFIG_VMAP_STACK)
+ set_current r7, r8
+ ldmia r4, {r4 - sl, fp, sp, pc} @ Load all regs saved previously
+#else
+ mov r1, r7
+ ldmia r4, {r4 - sl, fp, ip, lr} @ Load all regs saved previously
+#ifdef CONFIG_VMAP_STACK
+ @
+ @ Do a dummy read from the new stack while running from the old one so
+ @ that we can rely on do_translation_fault() to fix up any stale PMD
+ @ entries covering the vmalloc region.
+ @
+ ldr r2, [ip]
+#endif
+
+ @ When CONFIG_THREAD_INFO_IN_TASK=n, the update of SP itself is what
+ @ effectuates the task switch, as that is what causes the observable
+ @ values of current and current_thread_info to change. When
+ @ CONFIG_THREAD_INFO_IN_TASK=y, setting current (and therefore
+ @ current_thread_info) is done explicitly, and the update of SP just
+ @ switches us to another stack, with few other side effects. In order
+ @ to prevent this distinction from causing any inconsistencies, let's
+ @ keep the 'set_current' call as close as we can to the update of SP.
+ set_current r1, r2
+ mov sp, ip
+ ret lr
+#endif
UNWIND(.fnend )
ENDPROC(__switch_to)
+#ifdef CONFIG_VMAP_STACK
+ .text
+ .align 2
+__bad_stack:
+ @
+ @ We've just detected an overflow. We need to load the address of this
+ @ CPU's overflow stack into the stack pointer register. We have only one
+ @ scratch register so let's use a sequence of ADDs including one
+ @ involving the PC, and decorate them with PC-relative group
+ @ relocations. As these are ARM only, switch to ARM mode first.
+ @
+ @ We enter here with IP clobbered and its value stashed on the mode
+ @ stack.
+ @
+THUMB( bx pc )
+THUMB( nop )
+THUMB( .arm )
+ ldr_this_cpu_armv6 ip, overflow_stack_ptr
+
+ str sp, [ip, #-4]! @ Preserve original SP value
+ mov sp, ip @ Switch to overflow stack
+ pop {ip} @ Original SP in IP
+
+#if defined(CONFIG_UNWINDER_FRAME_POINTER) && defined(CONFIG_CC_IS_GCC)
+ mov ip, ip @ mov expected by unwinder
+ push {fp, ip, lr, pc} @ GCC flavor frame record
+#else
+ str ip, [sp, #-8]! @ store original SP
+ push {fpreg, lr} @ Clang flavor frame record
+#endif
+UNWIND( ldr ip, [r0, #4] ) @ load exception LR
+UNWIND( str ip, [sp, #12] ) @ store in the frame record
+ ldr ip, [r0, #12] @ reload IP
+
+ @ Store the original GPRs to the new stack.
+ svc_entry uaccess=0, overflow_check=0
+
+UNWIND( .save {sp, pc} )
+UNWIND( .save {fpreg, lr} )
+UNWIND( .setfp fpreg, sp )
+
+ ldr fpreg, [sp, #S_SP] @ Add our frame record
+ @ to the linked list
+#if defined(CONFIG_UNWINDER_FRAME_POINTER) && defined(CONFIG_CC_IS_GCC)
+ ldr r1, [fp, #4] @ reload SP at entry
+ add fp, fp, #12
+#else
+ ldr r1, [fpreg, #8]
+#endif
+ str r1, [sp, #S_SP] @ store in pt_regs
+
+ @ Stash the regs for handle_bad_stack
+ mov r0, sp
+
+ @ Time to die
+ bl handle_bad_stack
+ nop
+UNWIND( .fnend )
+ENDPROC(__bad_stack)
+#endif
+
__INIT
/*
@@ -1002,12 +1107,11 @@ vector_\name:
sub lr, lr, #\correction
.endif
- @
- @ Save r0, lr_<exception> (parent PC) and spsr_<exception>
- @ (parent CPSR)
- @
+ @ Save r0, lr_<exception> (parent PC)
stmia sp, {r0, lr} @ save r0, lr
- mrs lr, spsr
+
+ @ Save spsr_<exception> (parent CPSR)
+2: mrs lr, spsr
str lr, [sp, #8] @ save spsr
@
@@ -1028,6 +1132,44 @@ vector_\name:
movs pc, lr @ branch to handler in SVC mode
ENDPROC(vector_\name)
+#ifdef CONFIG_HARDEN_BRANCH_HISTORY
+ .subsection 1
+ .align 5
+vector_bhb_loop8_\name:
+ .if \correction
+ sub lr, lr, #\correction
+ .endif
+
+ @ Save r0, lr_<exception> (parent PC)
+ stmia sp, {r0, lr}
+
+ @ bhb workaround
+ mov r0, #8
+3: b . + 4
+ subs r0, r0, #1
+ bne 3b
+ dsb
+ isb
+ b 2b
+ENDPROC(vector_bhb_loop8_\name)
+
+vector_bhb_bpiall_\name:
+ .if \correction
+ sub lr, lr, #\correction
+ .endif
+
+ @ Save r0, lr_<exception> (parent PC)
+ stmia sp, {r0, lr}
+
+ @ bhb workaround
+ mcr p15, 0, r0, c7, c5, 6 @ BPIALL
+ @ isb not needed due to "movs pc, lr" in the vector stub
+ @ which gives a "context synchronisation".
+ b 2b
+ENDPROC(vector_bhb_bpiall_\name)
+ .previous
+#endif
+
.align 2
@ handler addresses follow this label
1:
@@ -1036,6 +1178,10 @@ ENDPROC(vector_\name)
.section .stubs, "ax", %progbits
@ This must be the first word
.word vector_swi
+#ifdef CONFIG_HARDEN_BRANCH_HISTORY
+ .word vector_bhb_loop8_swi
+ .word vector_bhb_bpiall_swi
+#endif
vector_rst:
ARM( swi SYS_ERROR0 )
@@ -1150,8 +1296,10 @@ vector_addrexcptn:
* FIQ "NMI" handler
*-----------------------------------------------------------------------------
* Handle a FIQ using the SVC stack allowing FIQ act like NMI on x86
- * systems.
+ * systems. This must be the last vector stub, so lets place it in its own
+ * subsection.
*/
+ .subsection 2
vector_stub fiq, FIQ_MODE, 4
.long __fiq_usr @ 0 (USR_26 / USR_32)
@@ -1184,6 +1332,30 @@ vector_addrexcptn:
W(b) vector_irq
W(b) vector_fiq
+#ifdef CONFIG_HARDEN_BRANCH_HISTORY
+ .section .vectors.bhb.loop8, "ax", %progbits
+.L__vectors_bhb_loop8_start:
+ W(b) vector_rst
+ W(b) vector_bhb_loop8_und
+ W(ldr) pc, .L__vectors_bhb_loop8_start + 0x1004
+ W(b) vector_bhb_loop8_pabt
+ W(b) vector_bhb_loop8_dabt
+ W(b) vector_addrexcptn
+ W(b) vector_bhb_loop8_irq
+ W(b) vector_bhb_loop8_fiq
+
+ .section .vectors.bhb.bpiall, "ax", %progbits
+.L__vectors_bhb_bpiall_start:
+ W(b) vector_rst
+ W(b) vector_bhb_bpiall_und
+ W(ldr) pc, .L__vectors_bhb_bpiall_start + 0x1008
+ W(b) vector_bhb_bpiall_pabt
+ W(b) vector_bhb_bpiall_dabt
+ W(b) vector_addrexcptn
+ W(b) vector_bhb_bpiall_irq
+ W(b) vector_bhb_bpiall_fiq
+#endif
+
.data
.align 2
diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S
index ac86c34682bb..90d40f4d56cf 100644
--- a/arch/arm/kernel/entry-common.S
+++ b/arch/arm/kernel/entry-common.S
@@ -16,12 +16,14 @@
.equ NR_syscalls, __NR_syscalls
-#ifdef CONFIG_NEED_RET_TO_USER
-#include <mach/entry-macro.S>
-#else
- .macro arch_ret_to_user, tmp1, tmp2
- .endm
+ .macro arch_ret_to_user, tmp
+#ifdef CONFIG_ARCH_IOP32X
+ mrc p15, 0, \tmp, c15, c1, 0
+ tst \tmp, #(1 << 6)
+ bicne \tmp, \tmp, #(1 << 6)
+ mcrne p15, 0, \tmp, c15, c1, 0 @ Disable cp6 access
#endif
+ .endm
#include "entry-header.S"
@@ -55,7 +57,7 @@ __ret_fast_syscall:
/* perform architecture specific actions before user return */
- arch_ret_to_user r1, lr
+ arch_ret_to_user r1
restore_user_regs fast = 1, offset = S_OFF
UNWIND(.fnend )
@@ -128,7 +130,7 @@ no_work_pending:
asm_trace_hardirqs_on save = 0
/* perform architecture specific actions before user return */
- arch_ret_to_user r1, lr
+ arch_ret_to_user r1
ct_user_enter save = 0
restore_user_regs fast = 0, offset = 0
@@ -154,12 +156,36 @@ ENDPROC(ret_from_fork)
*/
.align 5
+#ifdef CONFIG_HARDEN_BRANCH_HISTORY
+ENTRY(vector_bhb_loop8_swi)
+ sub sp, sp, #PT_REGS_SIZE
+ stmia sp, {r0 - r12}
+ mov r8, #8
+1: b 2f
+2: subs r8, r8, #1
+ bne 1b
+ dsb
+ isb
+ b 3f
+ENDPROC(vector_bhb_loop8_swi)
+
+ .align 5
+ENTRY(vector_bhb_bpiall_swi)
+ sub sp, sp, #PT_REGS_SIZE
+ stmia sp, {r0 - r12}
+ mcr p15, 0, r8, c7, c5, 6 @ BPIALL
+ isb
+ b 3f
+ENDPROC(vector_bhb_bpiall_swi)
+#endif
+ .align 5
ENTRY(vector_swi)
#ifdef CONFIG_CPU_V7M
v7m_exception_entry
#else
sub sp, sp, #PT_REGS_SIZE
stmia sp, {r0 - r12} @ Calling r0 - r12
+3:
ARM( add r8, sp, #S_PC )
ARM( stmdb r8, {sp, lr}^ ) @ Calling sp, lr
THUMB( mov r8, sp )
diff --git a/arch/arm/kernel/entry-ftrace.S b/arch/arm/kernel/entry-ftrace.S
index a74289ebc803..3e7bcaca5e07 100644
--- a/arch/arm/kernel/entry-ftrace.S
+++ b/arch/arm/kernel/entry-ftrace.S
@@ -22,12 +22,9 @@
* mcount can be thought of as a function called in the middle of a subroutine
* call. As such, it needs to be transparent for both the caller and the
* callee: the original lr needs to be restored when leaving mcount, and no
- * registers should be clobbered. (In the __gnu_mcount_nc implementation, we
- * clobber the ip register. This is OK because the ARM calling convention
- * allows it to be clobbered in subroutines and doesn't use it to hold
- * parameters.)
+ * registers should be clobbered.
*
- * When using dynamic ftrace, we patch out the mcount call by a "pop {lr}"
+ * When using dynamic ftrace, we patch out the mcount call by a "add sp, #4"
* instead of the __gnu_mcount_nc call (see arch/arm/kernel/ftrace.c).
*/
@@ -38,23 +35,20 @@
.macro __mcount suffix
mcount_enter
- ldr r0, =ftrace_trace_function
- ldr r2, [r0]
- adr r0, .Lftrace_stub
+ ldr_va r2, ftrace_trace_function
+ badr r0, .Lftrace_stub
cmp r0, r2
bne 1f
#ifdef CONFIG_FUNCTION_GRAPH_TRACER
- ldr r1, =ftrace_graph_return
- ldr r2, [r1]
- cmp r0, r2
- bne ftrace_graph_caller\suffix
-
- ldr r1, =ftrace_graph_entry
- ldr r2, [r1]
- ldr r0, =ftrace_graph_entry_stub
- cmp r0, r2
- bne ftrace_graph_caller\suffix
+ ldr_va r2, ftrace_graph_return
+ cmp r0, r2
+ bne ftrace_graph_caller\suffix
+
+ ldr_va r2, ftrace_graph_entry
+ mov_l r0, ftrace_graph_entry_stub
+ cmp r0, r2
+ bne ftrace_graph_caller\suffix
#endif
mcount_exit
@@ -70,29 +64,27 @@
.macro __ftrace_regs_caller
- sub sp, sp, #8 @ space for PC and CPSR OLD_R0,
+ str lr, [sp, #-8]! @ store LR as PC and make space for CPSR/OLD_R0,
@ OLD_R0 will overwrite previous LR
- add ip, sp, #12 @ move in IP the value of SP as it was
- @ before the push {lr} of the mcount mechanism
+ ldr lr, [sp, #8] @ get previous LR
- str lr, [sp, #0] @ store LR instead of PC
+ str r0, [sp, #8] @ write r0 as OLD_R0 over previous LR
- ldr lr, [sp, #8] @ get previous LR
+ str lr, [sp, #-4]! @ store previous LR as LR
- str r0, [sp, #8] @ write r0 as OLD_R0 over previous LR
+ add lr, sp, #16 @ move in LR the value of SP as it was
+ @ before the push {lr} of the mcount mechanism
- stmdb sp!, {ip, lr}
- stmdb sp!, {r0-r11, lr}
+ push {r0-r11, ip, lr}
@ stack content at this point:
@ 0 4 48 52 56 60 64 68 72
- @ R0 | R1 | ... | LR | SP + 4 | previous LR | LR | PSR | OLD_R0 |
+ @ R0 | R1 | ... | IP | SP + 4 | previous LR | LR | PSR | OLD_R0 |
- mov r3, sp @ struct pt_regs*
+ mov r3, sp @ struct pt_regs*
- ldr r2, =function_trace_op
- ldr r2, [r2] @ pointer to the current
+ ldr_va r2, function_trace_op @ pointer to the current
@ function tracing op
ldr r1, [sp, #S_LR] @ lr of instrumented func
@@ -108,35 +100,37 @@ ftrace_regs_call:
#ifdef CONFIG_FUNCTION_GRAPH_TRACER
.globl ftrace_graph_regs_call
ftrace_graph_regs_call:
- mov r0, r0
+ARM( mov r0, r0 )
+THUMB( nop.w )
#endif
@ pop saved regs
- ldmia sp!, {r0-r12} @ restore r0 through r12
- ldr ip, [sp, #8] @ restore PC
- ldr lr, [sp, #4] @ restore LR
- ldr sp, [sp, #0] @ restore SP
- mov pc, ip @ return
+ pop {r0-r11, ip, lr} @ restore r0 through r12
+ ldr lr, [sp], #4 @ restore LR
+ ldr pc, [sp], #12
.endm
#ifdef CONFIG_FUNCTION_GRAPH_TRACER
.macro __ftrace_graph_regs_caller
- sub r0, fp, #4 @ lr of instrumented routine (parent)
+#ifdef CONFIG_UNWINDER_FRAME_POINTER
+ sub r0, fp, #4 @ lr of instrumented routine (parent)
+#else
+ add r0, sp, #S_LR
+#endif
@ called from __ftrace_regs_caller
- ldr r1, [sp, #S_PC] @ instrumented routine (func)
+ ldr r1, [sp, #S_PC] @ instrumented routine (func)
mcount_adjust_addr r1, r1
- mov r2, fp @ frame pointer
+ mov r2, fpreg @ frame pointer
+ add r3, sp, #PT_REGS_SIZE
bl prepare_ftrace_return
@ pop registers saved in ftrace_regs_caller
- ldmia sp!, {r0-r12} @ restore r0 through r12
- ldr ip, [sp, #8] @ restore PC
- ldr lr, [sp, #4] @ restore LR
- ldr sp, [sp, #0] @ restore SP
- mov pc, ip @ return
+ pop {r0-r11, ip, lr} @ restore r0 through r12
+ ldr lr, [sp], #4 @ restore LR
+ ldr pc, [sp], #12
.endm
#endif
@@ -149,8 +143,7 @@ ftrace_graph_regs_call:
mcount_adjust_addr r0, lr @ instrumented function
#ifdef CONFIG_DYNAMIC_FTRACE_WITH_REGS
- ldr r2, =function_trace_op
- ldr r2, [r2] @ pointer to the current
+ ldr_va r2, function_trace_op @ pointer to the current
@ function tracing op
mov r3, #0 @ regs is NULL
#endif
@@ -162,14 +155,19 @@ ftrace_call\suffix:
#ifdef CONFIG_FUNCTION_GRAPH_TRACER
.globl ftrace_graph_call\suffix
ftrace_graph_call\suffix:
- mov r0, r0
+ARM( mov r0, r0 )
+THUMB( nop.w )
#endif
mcount_exit
.endm
.macro __ftrace_graph_caller
+#ifdef CONFIG_UNWINDER_FRAME_POINTER
sub r0, fp, #4 @ &lr of instrumented routine (&parent)
+#else
+ add r0, sp, #20
+#endif
#ifdef CONFIG_DYNAMIC_FTRACE
@ called from __ftrace_caller, saved in mcount_enter
ldr r1, [sp, #16] @ instrumented routine (func)
@@ -178,7 +176,8 @@ ftrace_graph_call\suffix:
@ called from __mcount, untouched in lr
mcount_adjust_addr r1, lr @ instrumented routine (func)
#endif
- mov r2, fp @ frame pointer
+ mov r2, fpreg @ frame pointer
+ add r3, sp, #24
bl prepare_ftrace_return
mcount_exit
.endm
@@ -202,16 +201,17 @@ ftrace_graph_call\suffix:
.endm
.macro mcount_exit
- ldmia sp!, {r0-r3, ip, lr}
- ret ip
+ ldmia sp!, {r0-r3}
+ ldr lr, [sp, #4]
+ ldr pc, [sp], #8
.endm
ENTRY(__gnu_mcount_nc)
UNWIND(.fnstart)
#ifdef CONFIG_DYNAMIC_FTRACE
- mov ip, lr
- ldmia sp!, {lr}
- ret ip
+ push {lr}
+ ldr lr, [sp, #4]
+ ldr pc, [sp], #8
#else
__mcount
#endif
@@ -256,17 +256,33 @@ ENDPROC(ftrace_graph_regs_caller)
.purgem mcount_exit
#ifdef CONFIG_FUNCTION_GRAPH_TRACER
- .globl return_to_handler
-return_to_handler:
+ENTRY(return_to_handler)
stmdb sp!, {r0-r3}
- mov r0, fp @ frame pointer
+ add r0, sp, #16 @ sp at exit of instrumented routine
bl ftrace_return_to_handler
mov lr, r0 @ r0 has real ret addr
ldmia sp!, {r0-r3}
ret lr
+ENDPROC(return_to_handler)
#endif
ENTRY(ftrace_stub)
.Lftrace_stub:
ret lr
ENDPROC(ftrace_stub)
+
+#ifdef CONFIG_DYNAMIC_FTRACE
+
+ __INIT
+
+ .macro init_tramp, dst:req
+ENTRY(\dst\()_from_init)
+ ldr pc, =\dst
+ENDPROC(\dst\()_from_init)
+ .endm
+
+ init_tramp ftrace_caller
+#ifdef CONFIG_DYNAMIC_FTRACE_WITH_REGS
+ init_tramp ftrace_regs_caller
+#endif
+#endif
diff --git a/arch/arm/kernel/entry-header.S b/arch/arm/kernel/entry-header.S
index ae24dd54e9ef..9a1dc142f782 100644
--- a/arch/arm/kernel/entry-header.S
+++ b/arch/arm/kernel/entry-header.S
@@ -292,12 +292,18 @@
.macro restore_user_regs, fast = 0, offset = 0
-#if defined(CONFIG_CPU_32v6K) && !defined(CONFIG_CPU_V6)
+#if defined(CONFIG_CPU_32v6K) && \
+ (!defined(CONFIG_CPU_V6) || defined(CONFIG_SMP))
+#ifdef CONFIG_CPU_V6
+ALT_SMP(nop)
+ALT_UP_B(.L1_\@)
+#endif
@ The TLS register update is deferred until return to user space so we
@ can use it for other things while running in the kernel
- get_thread_info r1
+ mrc p15, 0, r1, c13, c0, 3 @ get current_thread_info pointer
ldr r1, [r1, #TI_TP_VALUE]
mcr p15, 0, r1, c13, c0, 3 @ set TLS register
+.L1_\@:
#endif
uaccess_enable r1, isb=0
@@ -423,3 +429,40 @@ scno .req r7 @ syscall number
tbl .req r8 @ syscall table pointer
why .req r8 @ Linux syscall (!= 0)
tsk .req r9 @ current thread_info
+
+ .macro do_overflow_check, frame_size:req
+#ifdef CONFIG_VMAP_STACK
+ @
+ @ Test whether the SP has overflowed. Task and IRQ stacks are aligned
+ @ so that SP & BIT(THREAD_SIZE_ORDER + PAGE_SHIFT) should always be
+ @ zero.
+ @
+ARM( tst sp, #1 << (THREAD_SIZE_ORDER + PAGE_SHIFT) )
+THUMB( tst r1, #1 << (THREAD_SIZE_ORDER + PAGE_SHIFT) )
+THUMB( it ne )
+ bne .Lstack_overflow_check\@
+
+ .pushsection .text
+.Lstack_overflow_check\@:
+ @
+ @ The stack pointer is not pointing to a valid vmap'ed stack, but it
+ @ may be pointing into the linear map instead, which may happen if we
+ @ are already running from the overflow stack. We cannot detect overflow
+ @ in such cases so just carry on.
+ @
+ str ip, [r0, #12] @ Stash IP on the mode stack
+ ldr_va ip, high_memory @ Start of VMALLOC space
+ARM( cmp sp, ip ) @ SP in vmalloc space?
+THUMB( cmp r1, ip )
+THUMB( itt lo )
+ ldrlo ip, [r0, #12] @ Restore IP
+ blo .Lout\@ @ Carry on
+
+THUMB( sub r1, sp, r1 ) @ Restore original R1
+THUMB( sub sp, r1 ) @ Restore original SP
+ add sp, sp, #\frame_size @ Undo svc_entry's SP change
+ b __bad_stack @ Handle VMAP stack overflow
+ .popsection
+.Lout\@:
+#endif
+ .endm
diff --git a/arch/arm/kernel/entry-v7m.S b/arch/arm/kernel/entry-v7m.S
index 7bde93c10962..de8a60363c85 100644
--- a/arch/arm/kernel/entry-v7m.S
+++ b/arch/arm/kernel/entry-v7m.S
@@ -39,16 +39,25 @@ __irq_entry:
@
@ Invoke the IRQ handler
@
- mrs r0, ipsr
- ldr r1, =V7M_xPSR_EXCEPTIONNO
- and r0, r1
- sub r0, #16
- mov r1, sp
- stmdb sp!, {lr}
- @ routine called with r0 = irq number, r1 = struct pt_regs *
- bl nvic_handle_irq
-
- pop {lr}
+ mov r0, sp
+ ldr_this_cpu sp, irq_stack_ptr, r1, r2
+
+ @
+ @ If we took the interrupt while running in the kernel, we may already
+ @ be using the IRQ stack, so revert to the original value in that case.
+ @
+ subs r2, sp, r0 @ SP above bottom of IRQ stack?
+ rsbscs r2, r2, #THREAD_SIZE @ ... and below the top?
+ movcs sp, r0
+
+ push {r0, lr} @ preserve LR and original SP
+
+ @ routine called with r0 = struct pt_regs *
+ bl generic_handle_arch_irq
+
+ pop {r0, lr}
+ mov sp, r0
+
@
@ Check for any pending work if returning to user
@
@@ -101,15 +110,17 @@ ENTRY(__switch_to)
str sp, [ip], #4
str lr, [ip], #4
mov r5, r0
+ mov r6, r2 @ Preserve 'next'
add r4, r2, #TI_CPU_SAVE
ldr r0, =thread_notify_head
mov r1, #THREAD_NOTIFY_SWITCH
bl atomic_notifier_call_chain
- mov ip, r4
mov r0, r5
- ldmia ip!, {r4 - r11} @ Load all regs saved previously
- ldr sp, [ip]
- ldr pc, [ip, #4]!
+ mov r1, r6
+ ldmia r4, {r4 - r12, lr} @ Load all regs saved previously
+ set_current r1, r2
+ mov sp, ip
+ bx lr
.fnend
ENDPROC(__switch_to)
diff --git a/arch/arm/kernel/ftrace.c b/arch/arm/kernel/ftrace.c
index a006585e1c09..83cc068586bc 100644
--- a/arch/arm/kernel/ftrace.c
+++ b/arch/arm/kernel/ftrace.c
@@ -22,12 +22,24 @@
#include <asm/ftrace.h>
#include <asm/insn.h>
#include <asm/set_memory.h>
+#include <asm/stacktrace.h>
#include <asm/patch.h>
+/*
+ * The compiler emitted profiling hook consists of
+ *
+ * PUSH {LR}
+ * BL __gnu_mcount_nc
+ *
+ * To turn this combined sequence into a NOP, we need to restore the value of
+ * SP before the PUSH. Let's use an ADD rather than a POP into LR, as LR is not
+ * modified anyway, and reloading LR from memory is highly likely to be less
+ * efficient.
+ */
#ifdef CONFIG_THUMB2_KERNEL
-#define NOP 0xf85deb04 /* pop.w {lr} */
+#define NOP 0xf10d0d04 /* add.w sp, sp, #4 */
#else
-#define NOP 0xe8bd4000 /* pop {lr} */
+#define NOP 0xe28dd004 /* add sp, sp, #4 */
#endif
#ifdef CONFIG_DYNAMIC_FTRACE
@@ -51,9 +63,20 @@ static unsigned long ftrace_nop_replace(struct dyn_ftrace *rec)
return NOP;
}
-static unsigned long adjust_address(struct dyn_ftrace *rec, unsigned long addr)
+void ftrace_caller_from_init(void);
+void ftrace_regs_caller_from_init(void);
+
+static unsigned long __ref adjust_address(struct dyn_ftrace *rec,
+ unsigned long addr)
{
- return addr;
+ if (!IS_ENABLED(CONFIG_DYNAMIC_FTRACE) ||
+ system_state >= SYSTEM_FREEING_INITMEM ||
+ likely(!is_kernel_inittext(rec->ip)))
+ return addr;
+ if (!IS_ENABLED(CONFIG_DYNAMIC_FTRACE_WITH_REGS) ||
+ addr == (unsigned long)&ftrace_caller)
+ return (unsigned long)&ftrace_caller_from_init;
+ return (unsigned long)&ftrace_regs_caller_from_init;
}
int ftrace_arch_code_modify_prepare(void)
@@ -189,15 +212,23 @@ int ftrace_make_nop(struct module *mod,
#endif
new = ftrace_nop_replace(rec);
- ret = ftrace_modify_code(ip, old, new, true);
+ /*
+ * Locations in .init.text may call __gnu_mcount_mc via a linker
+ * emitted veneer if they are too far away from its implementation, and
+ * so validation may fail spuriously in such cases. Let's work around
+ * this by omitting those from validation.
+ */
+ ret = ftrace_modify_code(ip, old, new, !is_kernel_inittext(ip));
return ret;
}
#endif /* CONFIG_DYNAMIC_FTRACE */
#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+asmlinkage
void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr,
- unsigned long frame_pointer)
+ unsigned long frame_pointer,
+ unsigned long stack_pointer)
{
unsigned long return_hooker = (unsigned long) &return_to_handler;
unsigned long old;
@@ -205,6 +236,23 @@ void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr,
if (unlikely(atomic_read(&current->tracing_graph_pause)))
return;
+ if (IS_ENABLED(CONFIG_UNWINDER_FRAME_POINTER)) {
+ /* FP points one word below parent's top of stack */
+ frame_pointer += 4;
+ } else {
+ struct stackframe frame = {
+ .fp = frame_pointer,
+ .sp = stack_pointer,
+ .lr = self_addr,
+ .pc = self_addr,
+ };
+ if (unwind_frame(&frame) < 0)
+ return;
+ if (frame.lr != self_addr)
+ parent = frame.lr_addr;
+ frame_pointer = frame.sp;
+ }
+
old = *parent;
*parent = return_hooker;
@@ -225,7 +273,7 @@ static int __ftrace_modify_caller(unsigned long *callsite,
unsigned long caller_fn = (unsigned long) func;
unsigned long pc = (unsigned long) callsite;
unsigned long branch = arm_gen_branch(pc, caller_fn);
- unsigned long nop = 0xe1a00000; /* mov r0, r0 */
+ unsigned long nop = arm_gen_nop();
unsigned long old = enable ? nop : branch;
unsigned long new = enable ? branch : nop;
diff --git a/arch/arm/kernel/head-common.S b/arch/arm/kernel/head-common.S
index da18e0a17dc2..42cae73fcc19 100644
--- a/arch/arm/kernel/head-common.S
+++ b/arch/arm/kernel/head-common.S
@@ -105,10 +105,8 @@ __mmap_switched:
mov r1, #0
bl __memset @ clear .bss
-#ifdef CONFIG_CURRENT_POINTER_IN_TPIDRURO
adr_l r0, init_task @ get swapper task_struct
- set_current r0
-#endif
+ set_current r0, r1
ldmia r4, {r0, r1, r2, r3}
str r9, [r0] @ Save processor ID
diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S
index c04dd94630c7..500612d3da2e 100644
--- a/arch/arm/kernel/head.S
+++ b/arch/arm/kernel/head.S
@@ -424,6 +424,13 @@ ENDPROC(secondary_startup)
ENDPROC(secondary_startup_arm)
ENTRY(__secondary_switched)
+#if defined(CONFIG_VMAP_STACK) && !defined(CONFIG_ARM_LPAE)
+ @ Before using the vmap'ed stack, we have to switch to swapper_pg_dir
+ @ as the ID map does not cover the vmalloc region.
+ mrc p15, 0, ip, c2, c0, 1 @ read TTBR1
+ mcr p15, 0, ip, c2, c0, 0 @ set TTBR0
+ instr_sync
+#endif
adr_l r7, secondary_data + 12 @ get secondary_data.stack
ldr sp, [r7]
ldr r0, [r7, #4] @ get secondary_data.task
diff --git a/arch/arm/kernel/irq.c b/arch/arm/kernel/irq.c
index b79975bd988c..5c6f8d11a3ce 100644
--- a/arch/arm/kernel/irq.c
+++ b/arch/arm/kernel/irq.c
@@ -36,13 +36,53 @@
#include <asm/hardware/cache-l2x0.h>
#include <asm/hardware/cache-uniphier.h>
#include <asm/outercache.h>
+#include <asm/softirq_stack.h>
#include <asm/exception.h>
#include <asm/mach/arch.h>
#include <asm/mach/irq.h>
#include <asm/mach/time.h>
+#include "reboot.h"
+
unsigned long irq_err_count;
+#ifdef CONFIG_IRQSTACKS
+
+asmlinkage DEFINE_PER_CPU_READ_MOSTLY(u8 *, irq_stack_ptr);
+
+static void __init init_irq_stacks(void)
+{
+ u8 *stack;
+ int cpu;
+
+ for_each_possible_cpu(cpu) {
+ if (!IS_ENABLED(CONFIG_VMAP_STACK))
+ stack = (u8 *)__get_free_pages(GFP_KERNEL,
+ THREAD_SIZE_ORDER);
+ else
+ stack = __vmalloc_node(THREAD_SIZE, THREAD_ALIGN,
+ THREADINFO_GFP, NUMA_NO_NODE,
+ __builtin_return_address(0));
+
+ if (WARN_ON(!stack))
+ break;
+ per_cpu(irq_stack_ptr, cpu) = &stack[THREAD_SIZE];
+ }
+}
+
+static void ____do_softirq(void *arg)
+{
+ __do_softirq();
+}
+
+void do_softirq_own_stack(void)
+{
+ call_with_stack(____do_softirq, NULL,
+ __this_cpu_read(irq_stack_ptr));
+}
+
+#endif
+
int arch_show_interrupts(struct seq_file *p, int prec)
{
#ifdef CONFIG_FIQ
@@ -80,27 +120,14 @@ void handle_IRQ(unsigned int irq, struct pt_regs *regs)
ack_bad_irq(irq);
}
-/*
- * asm_do_IRQ is the interface to be used from assembly code.
- */
-asmlinkage void __exception_irq_entry
-asm_do_IRQ(unsigned int irq, struct pt_regs *regs)
-{
- struct pt_regs *old_regs;
-
- irq_enter();
- old_regs = set_irq_regs(regs);
-
- handle_IRQ(irq, regs);
-
- set_irq_regs(old_regs);
- irq_exit();
-}
-
void __init init_IRQ(void)
{
int ret;
+#ifdef CONFIG_IRQSTACKS
+ init_irq_stacks();
+#endif
+
if (IS_ENABLED(CONFIG_OF) && !machine_desc->init_irq)
irqchip_init();
else
diff --git a/arch/arm/kernel/kgdb.c b/arch/arm/kernel/kgdb.c
index 7bd30c0a4280..22f937e6f3ff 100644
--- a/arch/arm/kernel/kgdb.c
+++ b/arch/arm/kernel/kgdb.c
@@ -154,22 +154,38 @@ static int kgdb_compiled_brk_fn(struct pt_regs *regs, unsigned int instr)
return 0;
}
-static struct undef_hook kgdb_brkpt_hook = {
+static struct undef_hook kgdb_brkpt_arm_hook = {
.instr_mask = 0xffffffff,
.instr_val = KGDB_BREAKINST,
- .cpsr_mask = MODE_MASK,
+ .cpsr_mask = PSR_T_BIT | MODE_MASK,
.cpsr_val = SVC_MODE,
.fn = kgdb_brk_fn
};
-static struct undef_hook kgdb_compiled_brkpt_hook = {
+static struct undef_hook kgdb_brkpt_thumb_hook = {
+ .instr_mask = 0xffff,
+ .instr_val = KGDB_BREAKINST & 0xffff,
+ .cpsr_mask = PSR_T_BIT | MODE_MASK,
+ .cpsr_val = PSR_T_BIT | SVC_MODE,
+ .fn = kgdb_brk_fn
+};
+
+static struct undef_hook kgdb_compiled_brkpt_arm_hook = {
.instr_mask = 0xffffffff,
.instr_val = KGDB_COMPILED_BREAK,
- .cpsr_mask = MODE_MASK,
+ .cpsr_mask = PSR_T_BIT | MODE_MASK,
.cpsr_val = SVC_MODE,
.fn = kgdb_compiled_brk_fn
};
+static struct undef_hook kgdb_compiled_brkpt_thumb_hook = {
+ .instr_mask = 0xffff,
+ .instr_val = KGDB_COMPILED_BREAK & 0xffff,
+ .cpsr_mask = PSR_T_BIT | MODE_MASK,
+ .cpsr_val = PSR_T_BIT | SVC_MODE,
+ .fn = kgdb_compiled_brk_fn
+};
+
static int __kgdb_notify(struct die_args *args, unsigned long cmd)
{
struct pt_regs *regs = args->regs;
@@ -210,8 +226,10 @@ int kgdb_arch_init(void)
if (ret != 0)
return ret;
- register_undef_hook(&kgdb_brkpt_hook);
- register_undef_hook(&kgdb_compiled_brkpt_hook);
+ register_undef_hook(&kgdb_brkpt_arm_hook);
+ register_undef_hook(&kgdb_brkpt_thumb_hook);
+ register_undef_hook(&kgdb_compiled_brkpt_arm_hook);
+ register_undef_hook(&kgdb_compiled_brkpt_thumb_hook);
return 0;
}
@@ -224,8 +242,10 @@ int kgdb_arch_init(void)
*/
void kgdb_arch_exit(void)
{
- unregister_undef_hook(&kgdb_brkpt_hook);
- unregister_undef_hook(&kgdb_compiled_brkpt_hook);
+ unregister_undef_hook(&kgdb_brkpt_arm_hook);
+ unregister_undef_hook(&kgdb_brkpt_thumb_hook);
+ unregister_undef_hook(&kgdb_compiled_brkpt_arm_hook);
+ unregister_undef_hook(&kgdb_compiled_brkpt_thumb_hook);
unregister_die_notifier(&kgdb_notifier);
}
diff --git a/arch/arm/kernel/module.c b/arch/arm/kernel/module.c
index beac45e89ba6..549abcedf795 100644
--- a/arch/arm/kernel/module.c
+++ b/arch/arm/kernel/module.c
@@ -68,6 +68,44 @@ bool module_exit_section(const char *name)
strstarts(name, ".ARM.exidx.exit");
}
+#ifdef CONFIG_ARM_HAS_GROUP_RELOCS
+/*
+ * This implements the partitioning algorithm for group relocations as
+ * documented in the ARM AArch32 ELF psABI (IHI 0044).
+ *
+ * A single PC-relative symbol reference is divided in up to 3 add or subtract
+ * operations, where the final one could be incorporated into a load/store
+ * instruction with immediate offset. E.g.,
+ *
+ * ADD Rd, PC, #... or ADD Rd, PC, #...
+ * ADD Rd, Rd, #... ADD Rd, Rd, #...
+ * LDR Rd, [Rd, #...] ADD Rd, Rd, #...
+ *
+ * The latter has a guaranteed range of only 16 MiB (3x8 == 24 bits), so it is
+ * of limited use in the kernel. However, the ADD/ADD/LDR combo has a range of
+ * -/+ 256 MiB, (2x8 + 12 == 28 bits), which means it has sufficient range for
+ * any in-kernel symbol reference (unless module PLTs are being used).
+ *
+ * The main advantage of this approach over the typical pattern using a literal
+ * load is that literal loads may miss in the D-cache, and generally lead to
+ * lower cache efficiency for variables that are referenced often from many
+ * different places in the code.
+ */
+static u32 get_group_rem(u32 group, u32 *offset)
+{
+ u32 val = *offset;
+ u32 shift;
+ do {
+ shift = val ? (31 - __fls(val)) & ~1 : 32;
+ *offset = val;
+ if (!val)
+ break;
+ val &= 0xffffff >> shift;
+ } while (group--);
+ return shift;
+}
+#endif
+
int
apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex,
unsigned int relindex, struct module *module)
@@ -82,6 +120,9 @@ apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex,
unsigned long loc;
Elf32_Sym *sym;
const char *symname;
+#ifdef CONFIG_ARM_HAS_GROUP_RELOCS
+ u32 shift, group = 1;
+#endif
s32 offset;
u32 tmp;
#ifdef CONFIG_THUMB2_KERNEL
@@ -212,6 +253,55 @@ apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex,
*(u32 *)loc = __opcode_to_mem_arm(tmp);
break;
+#ifdef CONFIG_ARM_HAS_GROUP_RELOCS
+ case R_ARM_ALU_PC_G0_NC:
+ group = 0;
+ fallthrough;
+ case R_ARM_ALU_PC_G1_NC:
+ tmp = __mem_to_opcode_arm(*(u32 *)loc);
+ offset = ror32(tmp & 0xff, (tmp & 0xf00) >> 7);
+ if (tmp & BIT(22))
+ offset = -offset;
+ offset += sym->st_value - loc;
+ if (offset < 0) {
+ offset = -offset;
+ tmp = (tmp & ~BIT(23)) | BIT(22); // SUB opcode
+ } else {
+ tmp = (tmp & ~BIT(22)) | BIT(23); // ADD opcode
+ }
+
+ shift = get_group_rem(group, &offset);
+ if (shift < 24) {
+ offset >>= 24 - shift;
+ offset |= (shift + 8) << 7;
+ }
+ *(u32 *)loc = __opcode_to_mem_arm((tmp & ~0xfff) | offset);
+ break;
+
+ case R_ARM_LDR_PC_G2:
+ tmp = __mem_to_opcode_arm(*(u32 *)loc);
+ offset = tmp & 0xfff;
+ if (~tmp & BIT(23)) // U bit cleared?
+ offset = -offset;
+ offset += sym->st_value - loc;
+ if (offset < 0) {
+ offset = -offset;
+ tmp &= ~BIT(23); // clear U bit
+ } else {
+ tmp |= BIT(23); // set U bit
+ }
+ get_group_rem(2, &offset);
+
+ if (offset > 0xfff) {
+ pr_err("%s: section %u reloc %u sym '%s': relocation %u out of range (%#lx -> %#x)\n",
+ module->name, relindex, i, symname,
+ ELF32_R_TYPE(rel->r_info), loc,
+ sym->st_value);
+ return -ENOEXEC;
+ }
+ *(u32 *)loc = __opcode_to_mem_arm((tmp & ~0xfff) | offset);
+ break;
+#endif
#ifdef CONFIG_THUMB2_KERNEL
case R_ARM_THM_CALL:
case R_ARM_THM_JUMP24:
diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c
index d47159f3791c..0617af11377f 100644
--- a/arch/arm/kernel/process.c
+++ b/arch/arm/kernel/process.c
@@ -36,7 +36,7 @@
#include "signal.h"
-#ifdef CONFIG_CURRENT_POINTER_IN_TPIDRURO
+#if defined(CONFIG_CURRENT_POINTER_IN_TPIDRURO) || defined(CONFIG_SMP)
DEFINE_PER_CPU(struct task_struct *, __entry_task);
#endif
@@ -46,6 +46,11 @@ unsigned long __stack_chk_guard __read_mostly;
EXPORT_SYMBOL(__stack_chk_guard);
#endif
+#ifndef CONFIG_CURRENT_POINTER_IN_TPIDRURO
+asmlinkage struct task_struct *__current;
+EXPORT_SYMBOL(__current);
+#endif
+
static const char *processor_modes[] __maybe_unused = {
"USER_26", "FIQ_26" , "IRQ_26" , "SVC_26" , "UK4_26" , "UK5_26" , "UK6_26" , "UK7_26" ,
"UK8_26" , "UK9_26" , "UK10_26", "UK11_26", "UK12_26", "UK13_26", "UK14_26", "UK15_26",
diff --git a/arch/arm/kernel/return_address.c b/arch/arm/kernel/return_address.c
index 00c11579406c..8aac1e10b117 100644
--- a/arch/arm/kernel/return_address.c
+++ b/arch/arm/kernel/return_address.c
@@ -41,7 +41,8 @@ void *return_address(unsigned int level)
frame.fp = (unsigned long)__builtin_frame_address(0);
frame.sp = current_stack_pointer;
frame.lr = (unsigned long)__builtin_return_address(0);
- frame.pc = (unsigned long)return_address;
+here:
+ frame.pc = (unsigned long)&&here;
#ifdef CONFIG_KRETPROBES
frame.kr_cur = NULL;
frame.tsk = current;
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index 284a80c0b6e1..039feb7cd590 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -141,10 +141,10 @@ EXPORT_SYMBOL(outer_cache);
int __cpu_architecture __read_mostly = CPU_ARCH_UNKNOWN;
struct stack {
- u32 irq[3];
- u32 abt[3];
- u32 und[3];
- u32 fiq[3];
+ u32 irq[4];
+ u32 abt[4];
+ u32 und[4];
+ u32 fiq[4];
} ____cacheline_aligned;
#ifndef CONFIG_CPU_V7M
diff --git a/arch/arm/kernel/sleep.S b/arch/arm/kernel/sleep.S
index 43077e11dafd..a86a1d4f3461 100644
--- a/arch/arm/kernel/sleep.S
+++ b/arch/arm/kernel/sleep.S
@@ -67,6 +67,12 @@ ENTRY(__cpu_suspend)
ldr r4, =cpu_suspend_size
#endif
mov r5, sp @ current virtual SP
+#ifdef CONFIG_VMAP_STACK
+ @ Run the suspend code from the overflow stack so we don't have to rely
+ @ on vmalloc-to-phys conversions anywhere in the arch suspend code.
+ @ The original SP value captured in R5 will be restored on the way out.
+ ldr_this_cpu sp, overflow_stack_ptr, r6, r7
+#endif
add r4, r4, #12 @ Space for pgd, virt sp, phys resume fn
sub sp, sp, r4 @ allocate CPU state on stack
ldr r3, =sleep_save_sp
@@ -113,6 +119,13 @@ ENTRY(cpu_resume_mmu)
ENDPROC(cpu_resume_mmu)
.popsection
cpu_resume_after_mmu:
+#if defined(CONFIG_VMAP_STACK) && !defined(CONFIG_ARM_LPAE)
+ @ Before using the vmap'ed stack, we have to switch to swapper_pg_dir
+ @ as the ID map does not cover the vmalloc region.
+ mrc p15, 0, ip, c2, c0, 1 @ read TTBR1
+ mcr p15, 0, ip, c2, c0, 0 @ set TTBR0
+ instr_sync
+#endif
bl cpu_init @ restore the und/abt/irq banked regs
mov r0, #0 @ return zero on success
ldmfd sp!, {r4 - r11, pc}
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
index 97ee6b1567e9..73fc645fc4c7 100644
--- a/arch/arm/kernel/smp.c
+++ b/arch/arm/kernel/smp.c
@@ -400,6 +400,12 @@ static void smp_store_cpu_info(unsigned int cpuid)
check_cpu_icache_size(cpuid);
}
+static void set_current(struct task_struct *cur)
+{
+ /* Set TPIDRURO */
+ asm("mcr p15, 0, %0, c13, c0, 3" :: "r"(cur) : "memory");
+}
+
/*
* This is the secondary CPU boot entry. We're using this CPUs
* idle thread stack, but a set of temporary page tables.
@@ -628,11 +634,6 @@ static void ipi_complete(unsigned int cpu)
/*
* Main handler for inter-processor interrupts
*/
-asmlinkage void __exception_irq_entry do_IPI(int ipinr, struct pt_regs *regs)
-{
- handle_IPI(ipinr, regs);
-}
-
static void do_handle_IPI(int ipinr)
{
unsigned int cpu = smp_processor_id();
diff --git a/arch/arm/kernel/spectre.c b/arch/arm/kernel/spectre.c
new file mode 100644
index 000000000000..0dcefc36fb7a
--- /dev/null
+++ b/arch/arm/kernel/spectre.c
@@ -0,0 +1,71 @@
+// SPDX-License-Identifier: GPL-2.0-only
+#include <linux/bpf.h>
+#include <linux/cpu.h>
+#include <linux/device.h>
+
+#include <asm/spectre.h>
+
+static bool _unprivileged_ebpf_enabled(void)
+{
+#ifdef CONFIG_BPF_SYSCALL
+ return !sysctl_unprivileged_bpf_disabled;
+#else
+ return false;
+#endif
+}
+
+ssize_t cpu_show_spectre_v1(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ return sprintf(buf, "Mitigation: __user pointer sanitization\n");
+}
+
+static unsigned int spectre_v2_state;
+static unsigned int spectre_v2_methods;
+
+void spectre_v2_update_state(unsigned int state, unsigned int method)
+{
+ if (state > spectre_v2_state)
+ spectre_v2_state = state;
+ spectre_v2_methods |= method;
+}
+
+ssize_t cpu_show_spectre_v2(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ const char *method;
+
+ if (spectre_v2_state == SPECTRE_UNAFFECTED)
+ return sprintf(buf, "%s\n", "Not affected");
+
+ if (spectre_v2_state != SPECTRE_MITIGATED)
+ return sprintf(buf, "%s\n", "Vulnerable");
+
+ if (_unprivileged_ebpf_enabled())
+ return sprintf(buf, "Vulnerable: Unprivileged eBPF enabled\n");
+
+ switch (spectre_v2_methods) {
+ case SPECTRE_V2_METHOD_BPIALL:
+ method = "Branch predictor hardening";
+ break;
+
+ case SPECTRE_V2_METHOD_ICIALLU:
+ method = "I-cache invalidation";
+ break;
+
+ case SPECTRE_V2_METHOD_SMC:
+ case SPECTRE_V2_METHOD_HVC:
+ method = "Firmware call";
+ break;
+
+ case SPECTRE_V2_METHOD_LOOP8:
+ method = "History overwrite";
+ break;
+
+ default:
+ method = "Multiple mitigations";
+ break;
+ }
+
+ return sprintf(buf, "Mitigation: %s\n", method);
+}
diff --git a/arch/arm/kernel/stacktrace.c b/arch/arm/kernel/stacktrace.c
index 75e905508f27..b5efecb3d730 100644
--- a/arch/arm/kernel/stacktrace.c
+++ b/arch/arm/kernel/stacktrace.c
@@ -160,7 +160,8 @@ static noinline void __save_stack_trace(struct task_struct *tsk,
frame.fp = (unsigned long)__builtin_frame_address(0);
frame.sp = current_stack_pointer;
frame.lr = (unsigned long)__builtin_return_address(0);
- frame.pc = (unsigned long)__save_stack_trace;
+here:
+ frame.pc = (unsigned long)&&here;
}
#ifdef CONFIG_KRETPROBES
frame.kr_cur = NULL;
diff --git a/arch/arm/kernel/swp_emulate.c b/arch/arm/kernel/swp_emulate.c
index 6166ba38bf99..b74bfcf94fb1 100644
--- a/arch/arm/kernel/swp_emulate.c
+++ b/arch/arm/kernel/swp_emulate.c
@@ -195,7 +195,7 @@ static int swp_handler(struct pt_regs *regs, unsigned int instr)
destreg, EXTRACT_REG_NUM(instr, RT2_OFFSET), data);
/* Check access in reasonable access range for both SWP and SWPB */
- if (!access_ok((address & ~3), 4)) {
+ if (!access_ok((void __user *)(address & ~3), 4)) {
pr_debug("SWP{B} emulation: access to %p not allowed!\n",
(void *)address);
res = -EFAULT;
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c
index da04ed85855a..9283dc65be31 100644
--- a/arch/arm/kernel/traps.c
+++ b/arch/arm/kernel/traps.c
@@ -30,11 +30,13 @@
#include <linux/atomic.h>
#include <asm/cacheflush.h>
#include <asm/exception.h>
+#include <asm/spectre.h>
#include <asm/unistd.h>
#include <asm/traps.h>
#include <asm/ptrace.h>
#include <asm/unwind.h>
#include <asm/tls.h>
+#include <asm/stacktrace.h>
#include <asm/system_misc.h>
#include <asm/opcodes.h>
@@ -60,13 +62,24 @@ static int __init user_debug_setup(char *str)
__setup("user_debug=", user_debug_setup);
#endif
-static void dump_mem(const char *, const char *, unsigned long, unsigned long);
-
void dump_backtrace_entry(unsigned long where, unsigned long from,
unsigned long frame, const char *loglvl)
{
unsigned long end = frame + 4 + sizeof(struct pt_regs);
+ if (IS_ENABLED(CONFIG_UNWINDER_FRAME_POINTER) &&
+ IS_ENABLED(CONFIG_CC_IS_GCC) &&
+ end > ALIGN(frame, THREAD_SIZE)) {
+ /*
+ * If we are walking past the end of the stack, it may be due
+ * to the fact that we are on an IRQ or overflow stack. In this
+ * case, we can load the address of the other stack from the
+ * frame record.
+ */
+ frame = ((unsigned long *)frame)[-2] - 4;
+ end = frame + 4 + sizeof(struct pt_regs);
+ }
+
#ifndef CONFIG_KALLSYMS
printk("%sFunction entered at [<%08lx>] from [<%08lx>]\n",
loglvl, where, from);
@@ -110,7 +123,8 @@ void dump_backtrace_stm(u32 *stack, u32 instruction, const char *loglvl)
static int verify_stack(unsigned long sp)
{
if (sp < PAGE_OFFSET ||
- (sp > (unsigned long)high_memory && high_memory != NULL))
+ (!IS_ENABLED(CONFIG_VMAP_STACK) &&
+ sp > (unsigned long)high_memory && high_memory != NULL))
return -EFAULT;
return 0;
@@ -120,8 +134,8 @@ static int verify_stack(unsigned long sp)
/*
* Dump out the contents of some memory nicely...
*/
-static void dump_mem(const char *lvl, const char *str, unsigned long bottom,
- unsigned long top)
+void dump_mem(const char *lvl, const char *str, unsigned long bottom,
+ unsigned long top)
{
unsigned long first;
int i;
@@ -280,7 +294,8 @@ static int __die(const char *str, int err, struct pt_regs *regs)
if (!user_mode(regs) || in_interrupt()) {
dump_mem(KERN_EMERG, "Stack: ", regs->ARM_sp,
- THREAD_SIZE + (unsigned long)task_stack_page(tsk));
+ ALIGN(regs->ARM_sp - THREAD_SIZE, THREAD_ALIGN)
+ + THREAD_SIZE);
dump_backtrace(regs, tsk, KERN_EMERG);
dump_instr(KERN_EMERG, regs);
}
@@ -576,7 +591,7 @@ do_cache_op(unsigned long start, unsigned long end, int flags)
if (end < start || flags)
return -EINVAL;
- if (!access_ok(start, end - start))
+ if (!access_ok((void __user *)start, end - start))
return -EFAULT;
return __do_cache_op(start, end);
@@ -789,10 +804,59 @@ static inline void __init kuser_init(void *vectors)
}
#endif
+#ifndef CONFIG_CPU_V7M
+static void copy_from_lma(void *vma, void *lma_start, void *lma_end)
+{
+ memcpy(vma, lma_start, lma_end - lma_start);
+}
+
+static void flush_vectors(void *vma, size_t offset, size_t size)
+{
+ unsigned long start = (unsigned long)vma + offset;
+ unsigned long end = start + size;
+
+ flush_icache_range(start, end);
+}
+
+#ifdef CONFIG_HARDEN_BRANCH_HISTORY
+int spectre_bhb_update_vectors(unsigned int method)
+{
+ extern char __vectors_bhb_bpiall_start[], __vectors_bhb_bpiall_end[];
+ extern char __vectors_bhb_loop8_start[], __vectors_bhb_loop8_end[];
+ void *vec_start, *vec_end;
+
+ if (system_state >= SYSTEM_FREEING_INITMEM) {
+ pr_err("CPU%u: Spectre BHB workaround too late - system vulnerable\n",
+ smp_processor_id());
+ return SPECTRE_VULNERABLE;
+ }
+
+ switch (method) {
+ case SPECTRE_V2_METHOD_LOOP8:
+ vec_start = __vectors_bhb_loop8_start;
+ vec_end = __vectors_bhb_loop8_end;
+ break;
+
+ case SPECTRE_V2_METHOD_BPIALL:
+ vec_start = __vectors_bhb_bpiall_start;
+ vec_end = __vectors_bhb_bpiall_end;
+ break;
+
+ default:
+ pr_err("CPU%u: unknown Spectre BHB state %d\n",
+ smp_processor_id(), method);
+ return SPECTRE_VULNERABLE;
+ }
+
+ copy_from_lma(vectors_page, vec_start, vec_end);
+ flush_vectors(vectors_page, 0, vec_end - vec_start);
+
+ return SPECTRE_MITIGATED;
+}
+#endif
+
void __init early_trap_init(void *vectors_base)
{
-#ifndef CONFIG_CPU_V7M
- unsigned long vectors = (unsigned long)vectors_base;
extern char __stubs_start[], __stubs_end[];
extern char __vectors_start[], __vectors_end[];
unsigned i;
@@ -813,17 +877,87 @@ void __init early_trap_init(void *vectors_base)
* into the vector page, mapped at 0xffff0000, and ensure these
* are visible to the instruction stream.
*/
- memcpy((void *)vectors, __vectors_start, __vectors_end - __vectors_start);
- memcpy((void *)vectors + 0x1000, __stubs_start, __stubs_end - __stubs_start);
+ copy_from_lma(vectors_base, __vectors_start, __vectors_end);
+ copy_from_lma(vectors_base + 0x1000, __stubs_start, __stubs_end);
kuser_init(vectors_base);
- flush_icache_range(vectors, vectors + PAGE_SIZE * 2);
+ flush_vectors(vectors_base, 0, PAGE_SIZE * 2);
+}
#else /* ifndef CONFIG_CPU_V7M */
+void __init early_trap_init(void *vectors_base)
+{
/*
* on V7-M there is no need to copy the vector table to a dedicated
* memory area. The address is configurable and so a table in the kernel
* image can be used.
*/
+}
+#endif
+
+#ifdef CONFIG_VMAP_STACK
+
+DECLARE_PER_CPU(u8 *, irq_stack_ptr);
+
+asmlinkage DEFINE_PER_CPU(u8 *, overflow_stack_ptr);
+
+static int __init allocate_overflow_stacks(void)
+{
+ u8 *stack;
+ int cpu;
+
+ for_each_possible_cpu(cpu) {
+ stack = (u8 *)__get_free_page(GFP_KERNEL);
+ if (WARN_ON(!stack))
+ return -ENOMEM;
+ per_cpu(overflow_stack_ptr, cpu) = &stack[OVERFLOW_STACK_SIZE];
+ }
+ return 0;
+}
+early_initcall(allocate_overflow_stacks);
+
+asmlinkage void handle_bad_stack(struct pt_regs *regs)
+{
+ unsigned long tsk_stk = (unsigned long)current->stack;
+#ifdef CONFIG_IRQSTACKS
+ unsigned long irq_stk = (unsigned long)this_cpu_read(irq_stack_ptr);
#endif
+ unsigned long ovf_stk = (unsigned long)this_cpu_read(overflow_stack_ptr);
+
+ console_verbose();
+ pr_emerg("Insufficient stack space to handle exception!");
+
+ pr_emerg("Task stack: [0x%08lx..0x%08lx]\n",
+ tsk_stk, tsk_stk + THREAD_SIZE);
+#ifdef CONFIG_IRQSTACKS
+ pr_emerg("IRQ stack: [0x%08lx..0x%08lx]\n",
+ irq_stk - THREAD_SIZE, irq_stk);
+#endif
+ pr_emerg("Overflow stack: [0x%08lx..0x%08lx]\n",
+ ovf_stk - OVERFLOW_STACK_SIZE, ovf_stk);
+
+ die("kernel stack overflow", regs, 0);
+}
+
+#ifndef CONFIG_ARM_LPAE
+/*
+ * Normally, we rely on the logic in do_translation_fault() to update stale PMD
+ * entries covering the vmalloc space in a task's page tables when it first
+ * accesses the region in question. Unfortunately, this is not sufficient when
+ * the task stack resides in the vmalloc region, as do_translation_fault() is a
+ * C function that needs a stack to run.
+ *
+ * So we need to ensure that these PMD entries are up to date *before* the MM
+ * switch. As we already have some logic in the MM switch path that takes care
+ * of this, let's trigger it by bumping the counter every time the core vmalloc
+ * code modifies a PMD entry in the vmalloc region. Use release semantics on
+ * the store so that other CPUs observing the counter's new value are
+ * guaranteed to see the updated page table entries as well.
+ */
+void arch_sync_kernel_mappings(unsigned long start, unsigned long end)
+{
+ if (start < VMALLOC_END && end > VMALLOC_START)
+ atomic_inc_return_release(&init_mm.context.vmalloc_seq);
}
+#endif
+#endif
diff --git a/arch/arm/kernel/unwind.c b/arch/arm/kernel/unwind.c
index 59fdf257bf8b..a37ea6c772cd 100644
--- a/arch/arm/kernel/unwind.c
+++ b/arch/arm/kernel/unwind.c
@@ -33,6 +33,8 @@
#include <asm/traps.h>
#include <asm/unwind.h>
+#include "reboot.h"
+
/* Dummy functions to avoid linker complaints */
void __aeabi_unwind_cpp_pr0(void)
{
@@ -53,6 +55,7 @@ struct unwind_ctrl_block {
unsigned long vrs[16]; /* virtual register set */
const unsigned long *insn; /* pointer to the current instructions word */
unsigned long sp_high; /* highest value of sp allowed */
+ unsigned long *lr_addr; /* address of LR value on the stack */
/*
* 1 : check for stack overflow for each register pop.
* 0 : save overhead if there is plenty of stack remaining.
@@ -237,6 +240,8 @@ static int unwind_pop_register(struct unwind_ctrl_block *ctrl,
* from being tracked by KASAN.
*/
ctrl->vrs[reg] = READ_ONCE_NOCHECK(*(*vsp));
+ if (reg == 14)
+ ctrl->lr_addr = *vsp;
(*vsp)++;
return URC_OK;
}
@@ -256,8 +261,9 @@ static int unwind_exec_pop_subset_r4_to_r13(struct unwind_ctrl_block *ctrl,
mask >>= 1;
reg++;
}
- if (!load_sp)
+ if (!load_sp) {
ctrl->vrs[SP] = (unsigned long)vsp;
+ }
return URC_OK;
}
@@ -313,9 +319,9 @@ static int unwind_exec_insn(struct unwind_ctrl_block *ctrl)
if ((insn & 0xc0) == 0x00)
ctrl->vrs[SP] += ((insn & 0x3f) << 2) + 4;
- else if ((insn & 0xc0) == 0x40)
+ else if ((insn & 0xc0) == 0x40) {
ctrl->vrs[SP] -= ((insn & 0x3f) << 2) + 4;
- else if ((insn & 0xf0) == 0x80) {
+ } else if ((insn & 0xf0) == 0x80) {
unsigned long mask;
insn = (insn << 8) | unwind_get_byte(ctrl);
@@ -330,9 +336,9 @@ static int unwind_exec_insn(struct unwind_ctrl_block *ctrl)
if (ret)
goto error;
} else if ((insn & 0xf0) == 0x90 &&
- (insn & 0x0d) != 0x0d)
+ (insn & 0x0d) != 0x0d) {
ctrl->vrs[SP] = ctrl->vrs[insn & 0x0f];
- else if ((insn & 0xf0) == 0xa0) {
+ } else if ((insn & 0xf0) == 0xa0) {
ret = unwind_exec_pop_r4_to_rN(ctrl, insn);
if (ret)
goto error;
@@ -375,23 +381,22 @@ error:
*/
int unwind_frame(struct stackframe *frame)
{
- unsigned long low;
const struct unwind_idx *idx;
struct unwind_ctrl_block ctrl;
+ unsigned long sp_low;
/* store the highest address on the stack to avoid crossing it*/
- low = frame->sp;
- ctrl.sp_high = ALIGN(low, THREAD_SIZE);
+ sp_low = frame->sp;
+ ctrl.sp_high = ALIGN(sp_low - THREAD_SIZE, THREAD_ALIGN)
+ + THREAD_SIZE;
pr_debug("%s(pc = %08lx lr = %08lx sp = %08lx)\n", __func__,
frame->pc, frame->lr, frame->sp);
- if (!kernel_text_address(frame->pc))
- return -URC_FAILURE;
-
idx = unwind_find_idx(frame->pc);
if (!idx) {
- pr_warn("unwind: Index not found %08lx\n", frame->pc);
+ if (frame->pc && kernel_text_address(frame->pc))
+ pr_warn("unwind: Index not found %08lx\n", frame->pc);
return -URC_FAILURE;
}
@@ -403,7 +408,20 @@ int unwind_frame(struct stackframe *frame)
if (idx->insn == 1)
/* can't unwind */
return -URC_FAILURE;
- else if ((idx->insn & 0x80000000) == 0)
+ else if (frame->pc == prel31_to_addr(&idx->addr_offset)) {
+ /*
+ * Unwinding is tricky when we're halfway through the prologue,
+ * since the stack frame that the unwinder expects may not be
+ * fully set up yet. However, one thing we do know for sure is
+ * that if we are unwinding from the very first instruction of
+ * a function, we are still effectively in the stack frame of
+ * the caller, and the unwind info has no relevance yet.
+ */
+ if (frame->pc == frame->lr)
+ return -URC_FAILURE;
+ frame->pc = frame->lr;
+ return URC_OK;
+ } else if ((idx->insn & 0x80000000) == 0)
/* prel31 to the unwind table */
ctrl.insn = (unsigned long *)prel31_to_addr(&idx->insn);
else if ((idx->insn & 0xff000000) == 0x80000000)
@@ -430,6 +448,16 @@ int unwind_frame(struct stackframe *frame)
ctrl.check_each_pop = 0;
+ if (prel31_to_addr(&idx->addr_offset) == (u32)&call_with_stack) {
+ /*
+ * call_with_stack() is the only place where we permit SP to
+ * jump from one stack to another, and since we know it is
+ * guaranteed to happen, set up the SP bounds accordingly.
+ */
+ sp_low = frame->fp;
+ ctrl.sp_high = ALIGN(frame->fp, THREAD_SIZE);
+ }
+
while (ctrl.entries > 0) {
int urc;
if ((ctrl.sp_high - ctrl.vrs[SP]) < sizeof(ctrl.vrs))
@@ -437,7 +465,7 @@ int unwind_frame(struct stackframe *frame)
urc = unwind_exec_insn(&ctrl);
if (urc < 0)
return urc;
- if (ctrl.vrs[SP] < low || ctrl.vrs[SP] >= ctrl.sp_high)
+ if (ctrl.vrs[SP] < sp_low || ctrl.vrs[SP] > ctrl.sp_high)
return -URC_FAILURE;
}
@@ -452,6 +480,7 @@ int unwind_frame(struct stackframe *frame)
frame->sp = ctrl.vrs[SP];
frame->lr = ctrl.vrs[LR];
frame->pc = ctrl.vrs[PC];
+ frame->lr_addr = ctrl.lr_addr;
return URC_OK;
}
@@ -475,7 +504,12 @@ void unwind_backtrace(struct pt_regs *regs, struct task_struct *tsk,
frame.fp = (unsigned long)__builtin_frame_address(0);
frame.sp = current_stack_pointer;
frame.lr = (unsigned long)__builtin_return_address(0);
- frame.pc = (unsigned long)unwind_backtrace;
+ /* We are saving the stack and execution state at this
+ * point, so we should ensure that frame.pc is within
+ * this block of code.
+ */
+here:
+ frame.pc = (unsigned long)&&here;
} else {
/* task blocked in __switch_to */
frame.fp = thread_saved_fp(tsk);
diff --git a/arch/arm/kernel/vmlinux.lds.S b/arch/arm/kernel/vmlinux.lds.S
index f02d617e3359..aa12b65a7fd6 100644
--- a/arch/arm/kernel/vmlinux.lds.S
+++ b/arch/arm/kernel/vmlinux.lds.S
@@ -138,12 +138,12 @@ SECTIONS
#ifdef CONFIG_STRICT_KERNEL_RWX
. = ALIGN(1<<SECTION_SHIFT);
#else
- . = ALIGN(THREAD_SIZE);
+ . = ALIGN(THREAD_ALIGN);
#endif
__init_end = .;
_sdata = .;
- RW_DATA(L1_CACHE_BYTES, PAGE_SIZE, THREAD_SIZE)
+ RW_DATA(L1_CACHE_BYTES, PAGE_SIZE, THREAD_ALIGN)
_edata = .;
BSS_SECTION(0, 0, 0)
diff --git a/arch/arm/lib/backtrace-clang.S b/arch/arm/lib/backtrace-clang.S
index 5b2cdb1003e3..290c52a60fc6 100644
--- a/arch/arm/lib/backtrace-clang.S
+++ b/arch/arm/lib/backtrace-clang.S
@@ -144,7 +144,7 @@ for_each_frame: tst frame, mask @ Check for address exceptions
*/
1003: ldr sv_lr, [sv_fp, #4] @ get saved lr from next frame
- ldr r0, [sv_lr, #-4] @ get call instruction
+1004: ldr r0, [sv_lr, #-4] @ get call instruction
ldr r3, .Lopcode+4
and r2, r3, r0 @ is this a bl call
teq r2, r3
@@ -164,7 +164,7 @@ finished_setup:
/*
* Print the function (sv_pc) and where it was called from (sv_lr).
*/
-1004: mov r0, sv_pc
+ mov r0, sv_pc
mov r1, sv_lr
mov r2, frame
@@ -197,6 +197,14 @@ finished_setup:
cmp sv_fp, frame @ next frame must be
mov frame, sv_fp @ above the current frame
+#ifdef CONFIG_IRQSTACKS
+ @
+ @ Kernel stacks may be discontiguous in memory. If the next
+ @ frame is below the previous frame, accept it as long as it
+ @ lives in kernel memory.
+ @
+ cmpls sv_fp, #PAGE_OFFSET
+#endif
bhi for_each_frame
1006: adr r0, .Lbad
@@ -210,7 +218,7 @@ ENDPROC(c_backtrace)
.long 1001b, 1006b
.long 1002b, 1006b
.long 1003b, 1006b
- .long 1004b, 1006b
+ .long 1004b, finished_setup
.long 1005b, 1006b
.popsection
diff --git a/arch/arm/lib/backtrace.S b/arch/arm/lib/backtrace.S
index e8408f22d4dc..293a2716bd20 100644
--- a/arch/arm/lib/backtrace.S
+++ b/arch/arm/lib/backtrace.S
@@ -98,6 +98,14 @@ for_each_frame: tst frame, mask @ Check for address exceptions
cmp sv_fp, frame @ next frame must be
mov frame, sv_fp @ above the current frame
+#ifdef CONFIG_IRQSTACKS
+ @
+ @ Kernel stacks may be discontiguous in memory. If the next
+ @ frame is below the previous frame, accept it as long as it
+ @ lives in kernel memory.
+ @
+ cmpls sv_fp, #PAGE_OFFSET
+#endif
bhi for_each_frame
1006: adr r0, .Lbad
diff --git a/arch/arm/lib/call_with_stack.S b/arch/arm/lib/call_with_stack.S
index 28b0341ae786..0a268a6c513c 100644
--- a/arch/arm/lib/call_with_stack.S
+++ b/arch/arm/lib/call_with_stack.S
@@ -8,25 +8,42 @@
#include <linux/linkage.h>
#include <asm/assembler.h>
+#include <asm/unwind.h>
/*
* void call_with_stack(void (*fn)(void *), void *arg, void *sp)
*
* Change the stack to that pointed at by sp, then invoke fn(arg) with
* the new stack.
+ *
+ * The sequence below follows the APCS frame convention for frame pointer
+ * unwinding, and implements the unwinder annotations needed by the EABI
+ * unwinder.
*/
-ENTRY(call_with_stack)
- str sp, [r2, #-4]!
- str lr, [r2, #-4]!
+ENTRY(call_with_stack)
+#if defined(CONFIG_UNWINDER_FRAME_POINTER) && defined(CONFIG_CC_IS_GCC)
+ mov ip, sp
+ push {fp, ip, lr, pc}
+ sub fp, ip, #4
+#else
+UNWIND( .fnstart )
+UNWIND( .save {fpreg, lr} )
+ push {fpreg, lr}
+UNWIND( .setfp fpreg, sp )
+ mov fpreg, sp
+#endif
mov sp, r2
mov r2, r0
mov r0, r1
- badr lr, 1f
- ret r2
+ bl_r r2
-1: ldr lr, [sp]
- ldr sp, [sp, #4]
- ret lr
+#if defined(CONFIG_UNWINDER_FRAME_POINTER) && defined(CONFIG_CC_IS_GCC)
+ ldmdb fp, {fp, sp, pc}
+#else
+ mov sp, fpreg
+ pop {fpreg, pc}
+UNWIND( .fnend )
+#endif
ENDPROC(call_with_stack)
diff --git a/arch/arm/lib/copy_from_user.S b/arch/arm/lib/copy_from_user.S
index 480a20766137..270de7debd0f 100644
--- a/arch/arm/lib/copy_from_user.S
+++ b/arch/arm/lib/copy_from_user.S
@@ -91,18 +91,15 @@
strb\cond \reg, [\ptr], #1
.endm
- .macro enter reg1 reg2
+ .macro enter regs:vararg
mov r3, #0
- stmdb sp!, {r0, r2, r3, \reg1, \reg2}
+UNWIND( .save {r0, r2, r3, \regs} )
+ stmdb sp!, {r0, r2, r3, \regs}
.endm
- .macro usave reg1 reg2
- UNWIND( .save {r0, r2, r3, \reg1, \reg2} )
- .endm
-
- .macro exit reg1 reg2
+ .macro exit regs:vararg
add sp, sp, #8
- ldmfd sp!, {r0, \reg1, \reg2}
+ ldmfd sp!, {r0, \regs}
.endm
.text
diff --git a/arch/arm/lib/copy_template.S b/arch/arm/lib/copy_template.S
index 810a805d36dc..8fbafb074fe9 100644
--- a/arch/arm/lib/copy_template.S
+++ b/arch/arm/lib/copy_template.S
@@ -69,13 +69,10 @@
* than one 32bit instruction in Thumb-2)
*/
-
- UNWIND( .fnstart )
- enter r4, lr
- UNWIND( .fnend )
-
UNWIND( .fnstart )
- usave r4, lr @ in first stmdb block
+ enter r4, UNWIND(fpreg,) lr
+ UNWIND( .setfp fpreg, sp )
+ UNWIND( mov fpreg, sp )
subs r2, r2, #4
blt 8f
@@ -86,12 +83,7 @@
bne 10f
1: subs r2, r2, #(28)
- stmfd sp!, {r5 - r8}
- UNWIND( .fnend )
-
- UNWIND( .fnstart )
- usave r4, lr
- UNWIND( .save {r5 - r8} ) @ in second stmfd block
+ stmfd sp!, {r5, r6, r8, r9}
blt 5f
CALGN( ands ip, r0, #31 )
@@ -110,9 +102,9 @@
PLD( pld [r1, #92] )
3: PLD( pld [r1, #124] )
-4: ldr8w r1, r3, r4, r5, r6, r7, r8, ip, lr, abort=20f
+4: ldr8w r1, r3, r4, r5, r6, r8, r9, ip, lr, abort=20f
subs r2, r2, #32
- str8w r0, r3, r4, r5, r6, r7, r8, ip, lr, abort=20f
+ str8w r0, r3, r4, r5, r6, r8, r9, ip, lr, abort=20f
bge 3b
PLD( cmn r2, #96 )
PLD( bge 4b )
@@ -132,8 +124,8 @@
ldr1w r1, r4, abort=20f
ldr1w r1, r5, abort=20f
ldr1w r1, r6, abort=20f
- ldr1w r1, r7, abort=20f
ldr1w r1, r8, abort=20f
+ ldr1w r1, r9, abort=20f
ldr1w r1, lr, abort=20f
#if LDR1W_SHIFT < STR1W_SHIFT
@@ -150,17 +142,14 @@
str1w r0, r4, abort=20f
str1w r0, r5, abort=20f
str1w r0, r6, abort=20f
- str1w r0, r7, abort=20f
str1w r0, r8, abort=20f
+ str1w r0, r9, abort=20f
str1w r0, lr, abort=20f
CALGN( bcs 2b )
-7: ldmfd sp!, {r5 - r8}
- UNWIND( .fnend ) @ end of second stmfd block
+7: ldmfd sp!, {r5, r6, r8, r9}
- UNWIND( .fnstart )
- usave r4, lr @ still in first stmdb block
8: movs r2, r2, lsl #31
ldr1b r1, r3, ne, abort=21f
ldr1b r1, r4, cs, abort=21f
@@ -169,7 +158,7 @@
str1b r0, r4, cs, abort=21f
str1b r0, ip, cs, abort=21f
- exit r4, pc
+ exit r4, UNWIND(fpreg,) pc
9: rsb ip, ip, #4
cmp ip, #2
@@ -189,13 +178,10 @@
ldr1w r1, lr, abort=21f
beq 17f
bgt 18f
- UNWIND( .fnend )
.macro forward_copy_shift pull push
- UNWIND( .fnstart )
- usave r4, lr @ still in first stmdb block
subs r2, r2, #28
blt 14f
@@ -205,12 +191,8 @@
CALGN( subcc r2, r2, ip )
CALGN( bcc 15f )
-11: stmfd sp!, {r5 - r9}
- UNWIND( .fnend )
+11: stmfd sp!, {r5, r6, r8 - r10}
- UNWIND( .fnstart )
- usave r4, lr
- UNWIND( .save {r5 - r9} ) @ in new second stmfd block
PLD( pld [r1, #0] )
PLD( subs r2, r2, #96 )
PLD( pld [r1, #28] )
@@ -219,35 +201,32 @@
PLD( pld [r1, #92] )
12: PLD( pld [r1, #124] )
-13: ldr4w r1, r4, r5, r6, r7, abort=19f
+13: ldr4w r1, r4, r5, r6, r8, abort=19f
mov r3, lr, lspull #\pull
subs r2, r2, #32
- ldr4w r1, r8, r9, ip, lr, abort=19f
+ ldr4w r1, r9, r10, ip, lr, abort=19f
orr r3, r3, r4, lspush #\push
mov r4, r4, lspull #\pull
orr r4, r4, r5, lspush #\push
mov r5, r5, lspull #\pull
orr r5, r5, r6, lspush #\push
mov r6, r6, lspull #\pull
- orr r6, r6, r7, lspush #\push
- mov r7, r7, lspull #\pull
- orr r7, r7, r8, lspush #\push
+ orr r6, r6, r8, lspush #\push
mov r8, r8, lspull #\pull
orr r8, r8, r9, lspush #\push
mov r9, r9, lspull #\pull
- orr r9, r9, ip, lspush #\push
+ orr r9, r9, r10, lspush #\push
+ mov r10, r10, lspull #\pull
+ orr r10, r10, ip, lspush #\push
mov ip, ip, lspull #\pull
orr ip, ip, lr, lspush #\push
- str8w r0, r3, r4, r5, r6, r7, r8, r9, ip, abort=19f
+ str8w r0, r3, r4, r5, r6, r8, r9, r10, ip, abort=19f
bge 12b
PLD( cmn r2, #96 )
PLD( bge 13b )
- ldmfd sp!, {r5 - r9}
- UNWIND( .fnend ) @ end of the second stmfd block
+ ldmfd sp!, {r5, r6, r8 - r10}
- UNWIND( .fnstart )
- usave r4, lr @ still in first stmdb block
14: ands ip, r2, #28
beq 16f
@@ -262,7 +241,6 @@
16: sub r1, r1, #(\push / 8)
b 8b
- UNWIND( .fnend )
.endm
@@ -273,6 +251,7 @@
18: forward_copy_shift pull=24 push=8
+ UNWIND( .fnend )
/*
* Abort preamble and completion macros.
@@ -282,13 +261,13 @@
*/
.macro copy_abort_preamble
-19: ldmfd sp!, {r5 - r9}
+19: ldmfd sp!, {r5, r6, r8 - r10}
b 21f
-20: ldmfd sp!, {r5 - r8}
+20: ldmfd sp!, {r5, r6, r8, r9}
21:
.endm
.macro copy_abort_end
- ldmfd sp!, {r4, pc}
+ ldmfd sp!, {r4, UNWIND(fpreg,) pc}
.endm
diff --git a/arch/arm/lib/copy_to_user.S b/arch/arm/lib/copy_to_user.S
index 842ea5ede485..fac49e57cc0b 100644
--- a/arch/arm/lib/copy_to_user.S
+++ b/arch/arm/lib/copy_to_user.S
@@ -90,18 +90,15 @@
strusr \reg, \ptr, 1, \cond, abort=\abort
.endm
- .macro enter reg1 reg2
+ .macro enter regs:vararg
mov r3, #0
- stmdb sp!, {r0, r2, r3, \reg1, \reg2}
+UNWIND( .save {r0, r2, r3, \regs} )
+ stmdb sp!, {r0, r2, r3, \regs}
.endm
- .macro usave reg1 reg2
- UNWIND( .save {r0, r2, r3, \reg1, \reg2} )
- .endm
-
- .macro exit reg1 reg2
+ .macro exit regs:vararg
add sp, sp, #8
- ldmfd sp!, {r0, \reg1, \reg2}
+ ldmfd sp!, {r0, \regs}
.endm
.text
diff --git a/arch/arm/lib/memcpy.S b/arch/arm/lib/memcpy.S
index e4caf48c089f..90f2b645aa0d 100644
--- a/arch/arm/lib/memcpy.S
+++ b/arch/arm/lib/memcpy.S
@@ -42,16 +42,13 @@
strb\cond \reg, [\ptr], #1
.endm
- .macro enter reg1 reg2
- stmdb sp!, {r0, \reg1, \reg2}
+ .macro enter regs:vararg
+UNWIND( .save {r0, \regs} )
+ stmdb sp!, {r0, \regs}
.endm
- .macro usave reg1 reg2
- UNWIND( .save {r0, \reg1, \reg2} )
- .endm
-
- .macro exit reg1 reg2
- ldmfd sp!, {r0, \reg1, \reg2}
+ .macro exit regs:vararg
+ ldmfd sp!, {r0, \regs}
.endm
.text
diff --git a/arch/arm/lib/memmove.S b/arch/arm/lib/memmove.S
index 6fecc12a1f51..6410554039fd 100644
--- a/arch/arm/lib/memmove.S
+++ b/arch/arm/lib/memmove.S
@@ -31,12 +31,13 @@ WEAK(memmove)
subs ip, r0, r1
cmphi r2, ip
bls __memcpy
-
- stmfd sp!, {r0, r4, lr}
UNWIND( .fnend )
UNWIND( .fnstart )
- UNWIND( .save {r0, r4, lr} ) @ in first stmfd block
+ UNWIND( .save {r0, r4, fpreg, lr} )
+ stmfd sp!, {r0, r4, UNWIND(fpreg,) lr}
+ UNWIND( .setfp fpreg, sp )
+ UNWIND( mov fpreg, sp )
add r1, r1, r2
add r0, r0, r2
subs r2, r2, #4
@@ -48,12 +49,7 @@ WEAK(memmove)
bne 10f
1: subs r2, r2, #(28)
- stmfd sp!, {r5 - r8}
- UNWIND( .fnend )
-
- UNWIND( .fnstart )
- UNWIND( .save {r0, r4, lr} )
- UNWIND( .save {r5 - r8} ) @ in second stmfd block
+ stmfd sp!, {r5, r6, r8, r9}
blt 5f
CALGN( ands ip, r0, #31 )
@@ -72,9 +68,9 @@ WEAK(memmove)
PLD( pld [r1, #-96] )
3: PLD( pld [r1, #-128] )
-4: ldmdb r1!, {r3, r4, r5, r6, r7, r8, ip, lr}
+4: ldmdb r1!, {r3, r4, r5, r6, r8, r9, ip, lr}
subs r2, r2, #32
- stmdb r0!, {r3, r4, r5, r6, r7, r8, ip, lr}
+ stmdb r0!, {r3, r4, r5, r6, r8, r9, ip, lr}
bge 3b
PLD( cmn r2, #96 )
PLD( bge 4b )
@@ -88,8 +84,8 @@ WEAK(memmove)
W(ldr) r4, [r1, #-4]!
W(ldr) r5, [r1, #-4]!
W(ldr) r6, [r1, #-4]!
- W(ldr) r7, [r1, #-4]!
W(ldr) r8, [r1, #-4]!
+ W(ldr) r9, [r1, #-4]!
W(ldr) lr, [r1, #-4]!
add pc, pc, ip
@@ -99,17 +95,13 @@ WEAK(memmove)
W(str) r4, [r0, #-4]!
W(str) r5, [r0, #-4]!
W(str) r6, [r0, #-4]!
- W(str) r7, [r0, #-4]!
W(str) r8, [r0, #-4]!
+ W(str) r9, [r0, #-4]!
W(str) lr, [r0, #-4]!
CALGN( bcs 2b )
-7: ldmfd sp!, {r5 - r8}
- UNWIND( .fnend ) @ end of second stmfd block
-
- UNWIND( .fnstart )
- UNWIND( .save {r0, r4, lr} ) @ still in first stmfd block
+7: ldmfd sp!, {r5, r6, r8, r9}
8: movs r2, r2, lsl #31
ldrbne r3, [r1, #-1]!
@@ -118,7 +110,7 @@ WEAK(memmove)
strbne r3, [r0, #-1]!
strbcs r4, [r0, #-1]!
strbcs ip, [r0, #-1]
- ldmfd sp!, {r0, r4, pc}
+ ldmfd sp!, {r0, r4, UNWIND(fpreg,) pc}
9: cmp ip, #2
ldrbgt r3, [r1, #-1]!
@@ -137,13 +129,10 @@ WEAK(memmove)
ldr r3, [r1, #0]
beq 17f
blt 18f
- UNWIND( .fnend )
.macro backward_copy_shift push pull
- UNWIND( .fnstart )
- UNWIND( .save {r0, r4, lr} ) @ still in first stmfd block
subs r2, r2, #28
blt 14f
@@ -152,12 +141,7 @@ WEAK(memmove)
CALGN( subcc r2, r2, ip )
CALGN( bcc 15f )
-11: stmfd sp!, {r5 - r9}
- UNWIND( .fnend )
-
- UNWIND( .fnstart )
- UNWIND( .save {r0, r4, lr} )
- UNWIND( .save {r5 - r9} ) @ in new second stmfd block
+11: stmfd sp!, {r5, r6, r8 - r10}
PLD( pld [r1, #-4] )
PLD( subs r2, r2, #96 )
@@ -167,35 +151,31 @@ WEAK(memmove)
PLD( pld [r1, #-96] )
12: PLD( pld [r1, #-128] )
-13: ldmdb r1!, {r7, r8, r9, ip}
+13: ldmdb r1!, {r8, r9, r10, ip}
mov lr, r3, lspush #\push
subs r2, r2, #32
ldmdb r1!, {r3, r4, r5, r6}
orr lr, lr, ip, lspull #\pull
mov ip, ip, lspush #\push
- orr ip, ip, r9, lspull #\pull
+ orr ip, ip, r10, lspull #\pull
+ mov r10, r10, lspush #\push
+ orr r10, r10, r9, lspull #\pull
mov r9, r9, lspush #\push
orr r9, r9, r8, lspull #\pull
mov r8, r8, lspush #\push
- orr r8, r8, r7, lspull #\pull
- mov r7, r7, lspush #\push
- orr r7, r7, r6, lspull #\pull
+ orr r8, r8, r6, lspull #\pull
mov r6, r6, lspush #\push
orr r6, r6, r5, lspull #\pull
mov r5, r5, lspush #\push
orr r5, r5, r4, lspull #\pull
mov r4, r4, lspush #\push
orr r4, r4, r3, lspull #\pull
- stmdb r0!, {r4 - r9, ip, lr}
+ stmdb r0!, {r4 - r6, r8 - r10, ip, lr}
bge 12b
PLD( cmn r2, #96 )
PLD( bge 13b )
- ldmfd sp!, {r5 - r9}
- UNWIND( .fnend ) @ end of the second stmfd block
-
- UNWIND( .fnstart )
- UNWIND( .save {r0, r4, lr} ) @ still in first stmfd block
+ ldmfd sp!, {r5, r6, r8 - r10}
14: ands ip, r2, #28
beq 16f
@@ -211,7 +191,6 @@ WEAK(memmove)
16: add r1, r1, #(\pull / 8)
b 8b
- UNWIND( .fnend )
.endm
@@ -222,5 +201,6 @@ WEAK(memmove)
18: backward_copy_shift push=24 pull=8
+ UNWIND( .fnend )
ENDPROC(memmove)
ENDPROC(__memmove)
diff --git a/arch/arm/lib/memset.S b/arch/arm/lib/memset.S
index 9817cb258c1a..d71ab61430b2 100644
--- a/arch/arm/lib/memset.S
+++ b/arch/arm/lib/memset.S
@@ -28,16 +28,16 @@ UNWIND( .fnstart )
mov r3, r1
7: cmp r2, #16
blt 4f
+UNWIND( .fnend )
#if ! CALGN(1)+0
/*
* We need 2 extra registers for this loop - use r8 and the LR
*/
- stmfd sp!, {r8, lr}
-UNWIND( .fnend )
UNWIND( .fnstart )
UNWIND( .save {r8, lr} )
+ stmfd sp!, {r8, lr}
mov r8, r1
mov lr, r3
@@ -66,10 +66,9 @@ UNWIND( .fnend )
* whole cache lines at once.
*/
- stmfd sp!, {r4-r8, lr}
-UNWIND( .fnend )
UNWIND( .fnstart )
UNWIND( .save {r4-r8, lr} )
+ stmfd sp!, {r4-r8, lr}
mov r4, r1
mov r5, r3
mov r6, r1
diff --git a/arch/arm/lib/uaccess_with_memcpy.c b/arch/arm/lib/uaccess_with_memcpy.c
index 106f83a5ea6d..c30b689bec2e 100644
--- a/arch/arm/lib/uaccess_with_memcpy.c
+++ b/arch/arm/lib/uaccess_with_memcpy.c
@@ -92,11 +92,6 @@ __copy_to_user_memcpy(void __user *to, const void *from, unsigned long n)
unsigned long ua_flags;
int atomic;
- if (uaccess_kernel()) {
- memcpy((void *)to, from, n);
- return 0;
- }
-
/* the mmap semaphore is taken only if not in an atomic context */
atomic = faulthandler_disabled();
@@ -165,11 +160,6 @@ __clear_user_memset(void __user *addr, unsigned long n)
{
unsigned long ua_flags;
- if (uaccess_kernel()) {
- memset((void *)addr, 0, n);
- return 0;
- }
-
mmap_read_lock(current->mm);
while (n) {
pte_t *pte;
diff --git a/arch/arm/lib/xor-neon.c b/arch/arm/lib/xor-neon.c
index b99dd8e1c93f..522510baed49 100644
--- a/arch/arm/lib/xor-neon.c
+++ b/arch/arm/lib/xor-neon.c
@@ -17,17 +17,11 @@ MODULE_LICENSE("GPL");
/*
* Pull in the reference implementations while instructing GCC (through
* -ftree-vectorize) to attempt to exploit implicit parallelism and emit
- * NEON instructions.
+ * NEON instructions. Clang does this by default at O2 so no pragma is
+ * needed.
*/
-#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
+#ifdef CONFIG_CC_IS_GCC
#pragma GCC optimize "tree-vectorize"
-#else
-/*
- * While older versions of GCC do not generate incorrect code, they fail to
- * recognize the parallel nature of these functions, and emit plain ARM code,
- * which is known to be slower than the optimized ARM code in asm-arm/xor.h.
- */
-#warning This code requires at least version 4.6 of GCC
#endif
#pragma GCC diagnostic ignored "-Wunused-variable"
diff --git a/arch/nds32/kernel/vdso/.gitignore b/arch/arm/mach-airoha/Makefile
index 652e31d82582..a5857d0d02eb 100644
--- a/arch/nds32/kernel/vdso/.gitignore
+++ b/arch/arm/mach-airoha/Makefile
@@ -1,2 +1,2 @@
# SPDX-License-Identifier: GPL-2.0-only
-vdso.lds
+obj-y += airoha.o
diff --git a/arch/arm/mach-airoha/airoha.c b/arch/arm/mach-airoha/airoha.c
new file mode 100644
index 000000000000..ea23b5abb478
--- /dev/null
+++ b/arch/arm/mach-airoha/airoha.c
@@ -0,0 +1,16 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Device Tree support for Airoha SoCs
+ *
+ * Copyright (c) 2022 Felix Fietkau <nbd@nbd.name>
+ */
+#include <asm/mach/arch.h>
+
+static const char * const airoha_board_dt_compat[] = {
+ "airoha,en7523",
+ NULL,
+};
+
+DT_MACHINE_START(MEDIATEK_DT, "Airoha Cortex-A53 (Device Tree)")
+ .dt_compat = airoha_board_dt_compat,
+MACHINE_END
diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig
index 02f6b108fd5d..279810381256 100644
--- a/arch/arm/mach-at91/Kconfig
+++ b/arch/arm/mach-at91/Kconfig
@@ -63,6 +63,7 @@ config SOC_SAMA7G5
select HAVE_AT91_GENERATED_CLK
select HAVE_AT91_SAM9X60_PLL
select HAVE_AT91_UTMI
+ select PM_OPP
select SOC_SAMA7
help
Select this if you are using one of Microchip's SAMA7G5 family SoC.
diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c
index dd6f4ce3f766..0fd609e26615 100644
--- a/arch/arm/mach-at91/pm.c
+++ b/arch/arm/mach-at91/pm.c
@@ -605,6 +605,30 @@ static void at91sam9_sdram_standby(void)
at91_ramc_write(1, AT91_SDRAMC_LPR, saved_lpr1);
}
+static void sama7g5_standby(void)
+{
+ int pwrtmg, ratio;
+
+ pwrtmg = readl(soc_pm.data.ramc[0] + UDDRC_PWRCTL);
+ ratio = readl(soc_pm.data.pmc + AT91_PMC_RATIO);
+
+ /*
+ * Place RAM into self-refresh after a maximum idle clocks. The maximum
+ * idle clocks is configured by bootloader in
+ * UDDRC_PWRMGT.SELFREF_TO_X32.
+ */
+ writel(pwrtmg | UDDRC_PWRCTL_SELFREF_EN,
+ soc_pm.data.ramc[0] + UDDRC_PWRCTL);
+ /* Divide CPU clock by 16. */
+ writel(ratio & ~AT91_PMC_RATIO_RATIO, soc_pm.data.pmc + AT91_PMC_RATIO);
+
+ cpu_do_idle();
+
+ /* Restore previous configuration. */
+ writel(ratio, soc_pm.data.pmc + AT91_PMC_RATIO);
+ writel(pwrtmg, soc_pm.data.ramc[0] + UDDRC_PWRCTL);
+}
+
struct ramc_info {
void (*idle)(void);
unsigned int memctrl;
@@ -615,6 +639,7 @@ static const struct ramc_info ramc_infos[] __initconst = {
{ .idle = at91sam9_sdram_standby, .memctrl = AT91_MEMCTRL_SDRAMC},
{ .idle = at91_ddr_standby, .memctrl = AT91_MEMCTRL_DDRSDR},
{ .idle = sama5d3_ddr_standby, .memctrl = AT91_MEMCTRL_DDRSDR},
+ { .idle = sama7g5_standby, },
};
static const struct of_device_id ramc_ids[] __initconst = {
@@ -622,7 +647,7 @@ static const struct of_device_id ramc_ids[] __initconst = {
{ .compatible = "atmel,at91sam9260-sdramc", .data = &ramc_infos[1] },
{ .compatible = "atmel,at91sam9g45-ddramc", .data = &ramc_infos[2] },
{ .compatible = "atmel,sama5d3-ddramc", .data = &ramc_infos[3] },
- { .compatible = "microchip,sama7g5-uddrc", },
+ { .compatible = "microchip,sama7g5-uddrc", .data = &ramc_infos[4], },
{ /*sentinel*/ }
};
diff --git a/arch/arm/mach-at91/pm_suspend.S b/arch/arm/mach-at91/pm_suspend.S
index fdb4f63ecde4..abe4ced33eda 100644
--- a/arch/arm/mach-at91/pm_suspend.S
+++ b/arch/arm/mach-at91/pm_suspend.S
@@ -159,7 +159,7 @@ sr_ena_1:
/* Switch to self-refresh. */
ldr tmp1, [r2, #UDDRC_PWRCTL]
- orr tmp1, tmp1, #UDDRC_PWRCTRL_SELFREF_SW
+ orr tmp1, tmp1, #UDDRC_PWRCTL_SELFREF_SW
str tmp1, [r2, #UDDRC_PWRCTL]
sr_ena_2:
@@ -276,7 +276,7 @@ sr_dis_5:
/* Trigger self-refresh exit. */
ldr tmp1, [r2, #UDDRC_PWRCTL]
- bic tmp1, tmp1, #UDDRC_PWRCTRL_SELFREF_SW
+ bic tmp1, tmp1, #UDDRC_PWRCTL_SELFREF_SW
str tmp1, [r2, #UDDRC_PWRCTL]
sr_dis_6:
diff --git a/arch/arm/mach-bcm/Kconfig b/arch/arm/mach-bcm/Kconfig
index bd3f82788ebc..8db655c3e321 100644
--- a/arch/arm/mach-bcm/Kconfig
+++ b/arch/arm/mach-bcm/Kconfig
@@ -185,7 +185,6 @@ config ARCH_BCM_53573
config ARCH_BCM_63XX
bool "Broadcom BCM63xx DSL SoC"
depends on ARCH_MULTI_V7
- depends on MMU
select ARCH_HAS_RESET_CONTROLLER
select ARM_ERRATA_754322
select ARM_ERRATA_764369 if SMP
diff --git a/arch/arm/mach-bcm/Makefile b/arch/arm/mach-bcm/Makefile
index 7baa8c9427d5..b2394ddb0558 100644
--- a/arch/arm/mach-bcm/Makefile
+++ b/arch/arm/mach-bcm/Makefile
@@ -40,6 +40,7 @@ obj-$(CONFIG_ARCH_BCM_MOBILE_L2_CACHE) += kona_l2_cache.o
# Support for secure monitor traps
obj-$(CONFIG_ARCH_BCM_MOBILE_SMC) += bcm_kona_smc.o
+CFLAGS_REMOVE_bcm_kona_smc.o += $(CC_FLAGS_FTRACE)
# BCM2835
ifeq ($(CONFIG_ARCH_BCM2835),y)
diff --git a/arch/arm/mach-dove/irq.c b/arch/arm/mach-dove/irq.c
index 31ccbcee2627..d36f6b8269c2 100644
--- a/arch/arm/mach-dove/irq.c
+++ b/arch/arm/mach-dove/irq.c
@@ -73,12 +73,12 @@ void __init dove_init_irq(void)
/*
* Initialize gpiolib for GPIOs 0-71.
*/
- orion_gpio_init(NULL, 0, 32, DOVE_GPIO_LO_VIRT_BASE, 0,
+ orion_gpio_init(0, 32, DOVE_GPIO_LO_VIRT_BASE, 0,
IRQ_DOVE_GPIO_START, gpio0_irqs);
- orion_gpio_init(NULL, 32, 32, DOVE_GPIO_HI_VIRT_BASE, 0,
+ orion_gpio_init(32, 32, DOVE_GPIO_HI_VIRT_BASE, 0,
IRQ_DOVE_GPIO_START + 32, gpio1_irqs);
- orion_gpio_init(NULL, 64, 8, DOVE_GPIO2_VIRT_BASE, 0,
+ orion_gpio_init(64, 8, DOVE_GPIO2_VIRT_BASE, 0,
IRQ_DOVE_GPIO_START + 64, gpio2_irqs);
}
diff --git a/arch/arm/mach-exynos/firmware.c b/arch/arm/mach-exynos/firmware.c
index 2eaf2dbb8e81..2da5b60b59e2 100644
--- a/arch/arm/mach-exynos/firmware.c
+++ b/arch/arm/mach-exynos/firmware.c
@@ -60,8 +60,10 @@ static int exynos_cpu_boot(int cpu)
/*
* Exynos3250 doesn't need to send smc command for secondary CPU boot
* because Exynos3250 removes WFE in secure mode.
+ *
+ * On Exynos5 devices the call is ignored by trustzone firmware.
*/
- if (soc_is_exynos3250())
+ if (!soc_is_exynos4210() && !soc_is_exynos4412())
return 0;
/*
diff --git a/arch/arm/mach-exynos/mcpm-exynos.c b/arch/arm/mach-exynos/mcpm-exynos.c
index cd861c57d5ad..fd0dbeb93357 100644
--- a/arch/arm/mach-exynos/mcpm-exynos.c
+++ b/arch/arm/mach-exynos/mcpm-exynos.c
@@ -35,7 +35,6 @@ static bool secure_firmware __ro_after_init;
*/
#define exynos_v7_exit_coherency_flush(level) \
asm volatile( \
- "stmfd sp!, {fp, ip}\n\t"\
"mrc p15, 0, r0, c1, c0, 0 @ get SCTLR\n\t" \
"bic r0, r0, #"__stringify(CR_C)"\n\t" \
"mcr p15, 0, r0, c1, c0, 0 @ set SCTLR\n\t" \
@@ -50,11 +49,10 @@ static bool secure_firmware __ro_after_init;
"mcr p15, 0, r0, c1, c0, 1 @ set ACTLR\n\t" \
"isb\n\t" \
"dsb\n\t" \
- "ldmfd sp!, {fp, ip}" \
: \
: "Ir" (pmu_base_addr + S5P_INFORM0) \
- : "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", \
- "r9", "r10", "lr", "memory")
+ : "r0", "r1", "r2", "r3", "r4", "r5", "r6", \
+ "r9", "r10", "ip", "lr", "memory")
static int exynos_cpu_powerup(unsigned int cpu, unsigned int cluster)
{
diff --git a/arch/arm/mach-footbridge/common.c b/arch/arm/mach-footbridge/common.c
index eee095f0e2f6..322495df271d 100644
--- a/arch/arm/mach-footbridge/common.c
+++ b/arch/arm/mach-footbridge/common.c
@@ -27,6 +27,91 @@
#include "common.h"
+#include <mach/hardware.h>
+#include <mach/irqs.h>
+#include <asm/hardware/dec21285.h>
+
+static int dc21285_get_irq(void)
+{
+ void __iomem *irqstatus = (void __iomem *)CSR_IRQ_STATUS;
+ u32 mask = readl(irqstatus);
+
+ if (mask & IRQ_MASK_SDRAMPARITY)
+ return IRQ_SDRAMPARITY;
+
+ if (mask & IRQ_MASK_UART_RX)
+ return IRQ_CONRX;
+
+ if (mask & IRQ_MASK_DMA1)
+ return IRQ_DMA1;
+
+ if (mask & IRQ_MASK_DMA2)
+ return IRQ_DMA2;
+
+ if (mask & IRQ_MASK_IN0)
+ return IRQ_IN0;
+
+ if (mask & IRQ_MASK_IN1)
+ return IRQ_IN1;
+
+ if (mask & IRQ_MASK_IN2)
+ return IRQ_IN2;
+
+ if (mask & IRQ_MASK_IN3)
+ return IRQ_IN3;
+
+ if (mask & IRQ_MASK_PCI)
+ return IRQ_PCI;
+
+ if (mask & IRQ_MASK_DOORBELLHOST)
+ return IRQ_DOORBELLHOST;
+
+ if (mask & IRQ_MASK_I2OINPOST)
+ return IRQ_I2OINPOST;
+
+ if (mask & IRQ_MASK_TIMER1)
+ return IRQ_TIMER1;
+
+ if (mask & IRQ_MASK_TIMER2)
+ return IRQ_TIMER2;
+
+ if (mask & IRQ_MASK_TIMER3)
+ return IRQ_TIMER3;
+
+ if (mask & IRQ_MASK_UART_TX)
+ return IRQ_CONTX;
+
+ if (mask & IRQ_MASK_PCI_ABORT)
+ return IRQ_PCI_ABORT;
+
+ if (mask & IRQ_MASK_PCI_SERR)
+ return IRQ_PCI_SERR;
+
+ if (mask & IRQ_MASK_DISCARD_TIMER)
+ return IRQ_DISCARD_TIMER;
+
+ if (mask & IRQ_MASK_PCI_DPERR)
+ return IRQ_PCI_DPERR;
+
+ if (mask & IRQ_MASK_PCI_PERR)
+ return IRQ_PCI_PERR;
+
+ return 0;
+}
+
+static void dc21285_handle_irq(struct pt_regs *regs)
+{
+ int irq;
+ do {
+ irq = dc21285_get_irq();
+ if (!irq)
+ break;
+
+ generic_handle_irq(irq);
+ } while (1);
+}
+
+
unsigned int mem_fclk_21285 = 50000000;
EXPORT_SYMBOL(mem_fclk_21285);
@@ -108,6 +193,8 @@ static void __init __fb_init_irq(void)
void __init footbridge_init_irq(void)
{
+ set_handle_irq(dc21285_handle_irq);
+
__fb_init_irq();
if (!footbridge_cfn_mode())
diff --git a/arch/arm/mach-footbridge/include/mach/entry-macro.S b/arch/arm/mach-footbridge/include/mach/entry-macro.S
deleted file mode 100644
index dabbd5c54a78..000000000000
--- a/arch/arm/mach-footbridge/include/mach/entry-macro.S
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * arch/arm/mach-footbridge/include/mach/entry-macro.S
- *
- * Low-level IRQ helper macros for footbridge-based platforms
- *
- * This file is licensed under the terms of the GNU General Public
- * License version 2. This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
- */
-#include <mach/hardware.h>
-#include <mach/irqs.h>
-#include <asm/hardware/dec21285.h>
-
- .equ dc21285_high, ARMCSR_BASE & 0xff000000
- .equ dc21285_low, ARMCSR_BASE & 0x00ffffff
-
- .macro get_irqnr_preamble, base, tmp
- mov \base, #dc21285_high
- .if dc21285_low
- orr \base, \base, #dc21285_low
- .endif
- .endm
-
- .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
- ldr \irqstat, [\base, #0x180] @ get interrupts
-
- mov \irqnr, #IRQ_SDRAMPARITY
- tst \irqstat, #IRQ_MASK_SDRAMPARITY
- bne 1001f
-
- tst \irqstat, #IRQ_MASK_UART_RX
- movne \irqnr, #IRQ_CONRX
- bne 1001f
-
- tst \irqstat, #IRQ_MASK_DMA1
- movne \irqnr, #IRQ_DMA1
- bne 1001f
-
- tst \irqstat, #IRQ_MASK_DMA2
- movne \irqnr, #IRQ_DMA2
- bne 1001f
-
- tst \irqstat, #IRQ_MASK_IN0
- movne \irqnr, #IRQ_IN0
- bne 1001f
-
- tst \irqstat, #IRQ_MASK_IN1
- movne \irqnr, #IRQ_IN1
- bne 1001f
-
- tst \irqstat, #IRQ_MASK_IN2
- movne \irqnr, #IRQ_IN2
- bne 1001f
-
- tst \irqstat, #IRQ_MASK_IN3
- movne \irqnr, #IRQ_IN3
- bne 1001f
-
- tst \irqstat, #IRQ_MASK_PCI
- movne \irqnr, #IRQ_PCI
- bne 1001f
-
- tst \irqstat, #IRQ_MASK_DOORBELLHOST
- movne \irqnr, #IRQ_DOORBELLHOST
- bne 1001f
-
- tst \irqstat, #IRQ_MASK_I2OINPOST
- movne \irqnr, #IRQ_I2OINPOST
- bne 1001f
-
- tst \irqstat, #IRQ_MASK_TIMER1
- movne \irqnr, #IRQ_TIMER1
- bne 1001f
-
- tst \irqstat, #IRQ_MASK_TIMER2
- movne \irqnr, #IRQ_TIMER2
- bne 1001f
-
- tst \irqstat, #IRQ_MASK_TIMER3
- movne \irqnr, #IRQ_TIMER3
- bne 1001f
-
- tst \irqstat, #IRQ_MASK_UART_TX
- movne \irqnr, #IRQ_CONTX
- bne 1001f
-
- tst \irqstat, #IRQ_MASK_PCI_ABORT
- movne \irqnr, #IRQ_PCI_ABORT
- bne 1001f
-
- tst \irqstat, #IRQ_MASK_PCI_SERR
- movne \irqnr, #IRQ_PCI_SERR
- bne 1001f
-
- tst \irqstat, #IRQ_MASK_DISCARD_TIMER
- movne \irqnr, #IRQ_DISCARD_TIMER
- bne 1001f
-
- tst \irqstat, #IRQ_MASK_PCI_DPERR
- movne \irqnr, #IRQ_PCI_DPERR
- bne 1001f
-
- tst \irqstat, #IRQ_MASK_PCI_PERR
- movne \irqnr, #IRQ_PCI_PERR
-1001:
- .endm
-
diff --git a/arch/arm/mach-footbridge/include/mach/hardware.h b/arch/arm/mach-footbridge/include/mach/hardware.h
index ecaf6e7388d9..985ad3a95671 100644
--- a/arch/arm/mach-footbridge/include/mach/hardware.h
+++ b/arch/arm/mach-footbridge/include/mach/hardware.h
@@ -21,32 +21,26 @@
* 0xf0000000 0x80000000 16MB ISA memory
*/
-#ifdef CONFIG_MMU
-#define MMU_IO(a, b) (a)
-#else
-#define MMU_IO(a, b) (b)
-#endif
-
#define XBUS_SIZE 0x00100000
-#define XBUS_BASE MMU_IO(0xff800000, 0x40000000)
+#define XBUS_BASE 0xff800000
#define ARMCSR_SIZE 0x00100000
-#define ARMCSR_BASE MMU_IO(0xfe000000, 0x42000000)
+#define ARMCSR_BASE 0xfe000000
#define WFLUSH_SIZE 0x00100000
-#define WFLUSH_BASE MMU_IO(0xfd000000, 0x78000000)
+#define WFLUSH_BASE 0xfd000000
#define PCIIACK_SIZE 0x00100000
-#define PCIIACK_BASE MMU_IO(0xfc000000, 0x79000000)
+#define PCIIACK_BASE 0xfc000000
#define PCICFG1_SIZE 0x01000000
-#define PCICFG1_BASE MMU_IO(0xfb000000, 0x7a000000)
+#define PCICFG1_BASE 0xfb000000
#define PCICFG0_SIZE 0x01000000
-#define PCICFG0_BASE MMU_IO(0xfa000000, 0x7b000000)
+#define PCICFG0_BASE 0xfa000000
#define PCIMEM_SIZE 0x01000000
-#define PCIMEM_BASE MMU_IO(0xf0000000, 0x80000000)
+#define PCIMEM_BASE 0xf0000000
#define XBUS_CS2 0x40012000
diff --git a/arch/arm/mach-footbridge/include/mach/io.h b/arch/arm/mach-footbridge/include/mach/io.h
deleted file mode 100644
index 4e18b921373f..000000000000
--- a/arch/arm/mach-footbridge/include/mach/io.h
+++ /dev/null
@@ -1,20 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * arch/arm/mach-footbridge/include/mach/io.h
- *
- * Copyright (C) 1997-1999 Russell King
- *
- * Modifications:
- * 06-12-1997 RMK Created.
- * 07-04-1999 RMK Major cleanup
- */
-#ifndef __ASM_ARM_ARCH_IO_H
-#define __ASM_ARM_ARCH_IO_H
-
-/*
- * Translation of various i/o addresses to host addresses for !CONFIG_MMU
- */
-#define PCIO_BASE 0x7c000000
-#define __io(a) ((void __iomem *)(PCIO_BASE + (a)))
-
-#endif
diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
index f296bac467c8..c5a59158722b 100644
--- a/arch/arm/mach-imx/Kconfig
+++ b/arch/arm/mach-imx/Kconfig
@@ -227,6 +227,13 @@ config SOC_IMX7ULP
help
This enables support for Freescale i.MX7 Ultra Low Power processor.
+config SOC_IMXRT
+ bool "i.MXRT support"
+ depends on ARM_SINGLE_ARMV7M
+ select ARMV7M_SYSTICK if ARM_SINGLE_ARMV7M
+ help
+ This enables support for Freescale i.MXRT Crossover processor.
+
config SOC_VF610
bool "Vybrid Family VF610 support"
select ARM_GIC if ARCH_MULTI_V7
diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile
index d5291ed9186a..6fb3965b9ae6 100644
--- a/arch/arm/mach-imx/Makefile
+++ b/arch/arm/mach-imx/Makefile
@@ -63,6 +63,8 @@ obj-$(CONFIG_SOC_IMX50) += mach-imx50.o
obj-$(CONFIG_SOC_IMX51) += mach-imx51.o
obj-$(CONFIG_SOC_IMX53) += mach-imx53.o
+obj-$(CONFIG_SOC_IMXRT) += mach-imxrt.o
+
obj-$(CONFIG_SOC_VF610) += mach-vf610.o
obj-$(CONFIG_SOC_LS1021A) += mach-ls1021a.o
diff --git a/arch/arm/mach-imx/mach-imxrt.c b/arch/arm/mach-imx/mach-imxrt.c
new file mode 100644
index 000000000000..2063a3059c84
--- /dev/null
+++ b/arch/arm/mach-imx/mach-imxrt.c
@@ -0,0 +1,19 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2019
+ * Author(s): Giulio Benetti <giulio.benetti@benettiengineering.com>
+ */
+
+#include <linux/kernel.h>
+#include <asm/mach/arch.h>
+#include <asm/v7m.h>
+
+static const char *const imxrt_compat[] __initconst = {
+ "fsl,imxrt1050",
+ NULL
+};
+
+DT_MACHINE_START(IMXRTDT, "IMXRT (Device Tree Support)")
+ .dt_compat = imxrt_compat,
+ .restart = armv7m_restart,
+MACHINE_END
diff --git a/arch/arm/mach-integrator/Kconfig b/arch/arm/mach-integrator/Kconfig
index 63a0ca82659a..d61ea616cf8e 100644
--- a/arch/arm/mach-integrator/Kconfig
+++ b/arch/arm/mach-integrator/Kconfig
@@ -42,24 +42,12 @@ config INTEGRATOR_IMPD1
allows ARM(R) Ltd PrimeCells to be developed and evaluated.
The IM-PD1 can be found on the Integrator/PP2 platform.
-config INTEGRATOR_CM7TDMI
- bool "Integrator/CM7TDMI core module"
- depends on ARCH_INTEGRATOR_AP
- depends on ARCH_MULTI_V4 && !MMU
- select CPU_ARM7TDMI
-
config INTEGRATOR_CM720T
bool "Integrator/CM720T core module"
depends on ARCH_INTEGRATOR_AP
depends on ARCH_MULTI_V4T
select CPU_ARM720T
-config INTEGRATOR_CM740T
- bool "Integrator/CM740T core module"
- depends on ARCH_INTEGRATOR_AP
- depends on ARCH_MULTI_V4T && !MMU
- select CPU_ARM740T
-
config INTEGRATOR_CM920T
bool "Integrator/CM920T core module"
depends on ARCH_INTEGRATOR_AP
@@ -78,23 +66,6 @@ config INTEGRATOR_CM926EJS
depends on ARCH_MULTI_V5
select CPU_ARM926T
-config INTEGRATOR_CM940T
- bool "Integrator/CM940T core module"
- depends on ARCH_INTEGRATOR_AP
- depends on ARCH_MULTI_V4T && !MMU
- select CPU_ARM940T
-
-config INTEGRATOR_CM946ES
- bool "Integrator/CM946E-S core module"
- depends on ARCH_INTEGRATOR_AP
- depends on ARCH_MULTI_V5 && !MMU
- select CPU_ARM946E
-
-config INTEGRATOR_CM966ES
- bool "Integrator/CM966E-S core module"
- depends on ARCH_INTEGRATOR_AP
- depends on BROKEN # no kernel support
-
config INTEGRATOR_CM10200E_REV0
bool "Integrator/CM10200E rev.0 core module"
depends on ARCH_INTEGRATOR_AP && n
@@ -127,7 +98,7 @@ config INTEGRATOR_CM1136JFS
config ARCH_INTEGRATOR_CP
bool "Support Integrator/CP platform"
- depends on (!MMU || ARCH_MULTI_V5 || ARCH_MULTI_V6)
+ depends on ARCH_MULTI_V5 || ARCH_MULTI_V6
select ARM_TIMER_SP804
select SERIAL_AMBA_PL011 if TTY
select SERIAL_AMBA_PL011_CONSOLE if TTY
@@ -135,12 +106,6 @@ config ARCH_INTEGRATOR_CP
help
Include support for the ARM(R) Integrator CP platform.
-config INTEGRATOR_CT7T
- bool "Integrator/CT7TD (ARM7TDMI) core tile"
- depends on ARCH_INTEGRATOR_CP
- depends on ARCH_MULTI_V4T && !MMU
- select CPU_ARM7TDMI
-
config INTEGRATOR_CT926
bool "Integrator/CT926 (ARM926EJ-S) core tile"
depends on ARCH_INTEGRATOR_CP
diff --git a/arch/arm/mach-integrator/hardware.h b/arch/arm/mach-integrator/hardware.h
index 4d6ade3dd4ee..81ce09e3ad45 100644
--- a/arch/arm/mach-integrator/hardware.h
+++ b/arch/arm/mach-integrator/hardware.h
@@ -16,12 +16,7 @@
#define IO_START INTEGRATOR_HDR_BASE // PA of IO
/* macro to get at IO space when running virtually */
-#ifdef CONFIG_MMU
#define IO_ADDRESS(x) (((x) & 0x000fffff) | (((x) >> 4) & 0x0ff00000) | IO_BASE)
-#else
-#define IO_ADDRESS(x) (x)
-#endif
-
#define __io_address(n) ((void __iomem *)IO_ADDRESS(n))
/*
diff --git a/arch/arm/mach-iop32x/cp6.c b/arch/arm/mach-iop32x/cp6.c
index ec74b07fb7e3..2882674a1c39 100644
--- a/arch/arm/mach-iop32x/cp6.c
+++ b/arch/arm/mach-iop32x/cp6.c
@@ -7,7 +7,7 @@
#include <asm/traps.h>
#include <asm/ptrace.h>
-static int cp6_trap(struct pt_regs *regs, unsigned int instr)
+void iop_enable_cp6(void)
{
u32 temp;
@@ -16,7 +16,15 @@ static int cp6_trap(struct pt_regs *regs, unsigned int instr)
"mrc p15, 0, %0, c15, c1, 0\n\t"
"orr %0, %0, #(1 << 6)\n\t"
"mcr p15, 0, %0, c15, c1, 0\n\t"
+ "mrc p15, 0, %0, c15, c1, 0\n\t"
+ "mov %0, %0\n\t"
+ "sub pc, pc, #4 @ cp_wait\n\t"
: "=r"(temp));
+}
+
+static int cp6_trap(struct pt_regs *regs, unsigned int instr)
+{
+ iop_enable_cp6();
return 0;
}
diff --git a/arch/arm/mach-iop32x/include/mach/entry-macro.S b/arch/arm/mach-iop32x/include/mach/entry-macro.S
deleted file mode 100644
index 8e6766d4621e..000000000000
--- a/arch/arm/mach-iop32x/include/mach/entry-macro.S
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * arch/arm/mach-iop32x/include/mach/entry-macro.S
- *
- * Low-level IRQ helper macros for IOP32x-based platforms
- *
- * This file is licensed under the terms of the GNU General Public
- * License version 2. This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
- */
- .macro get_irqnr_preamble, base, tmp
- mrc p15, 0, \tmp, c15, c1, 0
- orr \tmp, \tmp, #(1 << 6)
- mcr p15, 0, \tmp, c15, c1, 0 @ Enable cp6 access
- mrc p15, 0, \tmp, c15, c1, 0
- mov \tmp, \tmp
- sub pc, pc, #4 @ cp_wait
- .endm
-
- .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
- mrc p6, 0, \irqstat, c8, c0, 0 @ Read IINTSRC
- cmp \irqstat, #0
- clzne \irqnr, \irqstat
- rsbne \irqnr, \irqnr, #31
- .endm
-
- .macro arch_ret_to_user, tmp1, tmp2
- mrc p15, 0, \tmp1, c15, c1, 0
- ands \tmp2, \tmp1, #(1 << 6)
- bicne \tmp1, \tmp1, #(1 << 6)
- mcrne p15, 0, \tmp1, c15, c1, 0 @ Disable cp6 access
- .endm
diff --git a/arch/arm/mach-iop32x/include/mach/irqs.h b/arch/arm/mach-iop32x/include/mach/irqs.h
index c4e78df428e8..e09ae5f48aec 100644
--- a/arch/arm/mach-iop32x/include/mach/irqs.h
+++ b/arch/arm/mach-iop32x/include/mach/irqs.h
@@ -9,6 +9,6 @@
#ifndef __IRQS_H
#define __IRQS_H
-#define NR_IRQS 32
+#define NR_IRQS 33
#endif
diff --git a/arch/arm/mach-iop32x/iop3xx.h b/arch/arm/mach-iop32x/iop3xx.h
index 46b4b34a4ad2..a6ec7ebadb35 100644
--- a/arch/arm/mach-iop32x/iop3xx.h
+++ b/arch/arm/mach-iop32x/iop3xx.h
@@ -225,6 +225,7 @@ extern int iop3xx_get_init_atu(void);
#include <linux/reboot.h>
void iop3xx_map_io(void);
+void iop_enable_cp6(void);
void iop_init_cp6_handler(void);
void iop_init_time(unsigned long tickrate);
void iop3xx_restart(enum reboot_mode, const char *);
diff --git a/arch/arm/mach-iop32x/irq.c b/arch/arm/mach-iop32x/irq.c
index 2d48bf1398c1..6dca7e97d81f 100644
--- a/arch/arm/mach-iop32x/irq.c
+++ b/arch/arm/mach-iop32x/irq.c
@@ -29,17 +29,26 @@ static void intstr_write(u32 val)
asm volatile("mcr p6, 0, %0, c4, c0, 0" : : "r" (val));
}
+static u32 iintsrc_read(void)
+{
+ int irq;
+
+ asm volatile("mrc p6, 0, %0, c8, c0, 0" : "=r" (irq));
+
+ return irq;
+}
+
static void
iop32x_irq_mask(struct irq_data *d)
{
- iop32x_mask &= ~(1 << d->irq);
+ iop32x_mask &= ~(1 << (d->irq - 1));
intctl_write(iop32x_mask);
}
static void
iop32x_irq_unmask(struct irq_data *d)
{
- iop32x_mask |= 1 << d->irq;
+ iop32x_mask |= 1 << (d->irq - 1);
intctl_write(iop32x_mask);
}
@@ -50,11 +59,25 @@ struct irq_chip ext_chip = {
.irq_unmask = iop32x_irq_unmask,
};
+static void iop_handle_irq(struct pt_regs *regs)
+{
+ u32 mask;
+
+ iop_enable_cp6();
+
+ do {
+ mask = iintsrc_read();
+ if (mask)
+ generic_handle_irq(fls(mask));
+ } while (mask);
+}
+
void __init iop32x_init_irq(void)
{
int i;
iop_init_cp6_handler();
+ set_handle_irq(iop_handle_irq);
intctl_write(0);
intstr_write(0);
@@ -65,7 +88,7 @@ void __init iop32x_init_irq(void)
machine_is_em7210())
*IOP3XX_PCIIRSR = 0x0f;
- for (i = 0; i < NR_IRQS; i++) {
+ for (i = 1; i < NR_IRQS; i++) {
irq_set_chip_and_handler(i, &ext_chip, handle_level_irq);
irq_clear_status_flags(i, IRQ_NOREQUEST | IRQ_NOPROBE);
}
diff --git a/arch/arm/mach-iop32x/irqs.h b/arch/arm/mach-iop32x/irqs.h
index 69858e4e905d..e1dfc8b4e7d7 100644
--- a/arch/arm/mach-iop32x/irqs.h
+++ b/arch/arm/mach-iop32x/irqs.h
@@ -7,36 +7,40 @@
#ifndef __IOP32X_IRQS_H
#define __IOP32X_IRQS_H
+/* Interrupts in Linux start at 1, hardware starts at 0 */
+
+#define IOP_IRQ(x) ((x) + 1)
+
/*
* IOP80321 chipset interrupts
*/
-#define IRQ_IOP32X_DMA0_EOT 0
-#define IRQ_IOP32X_DMA0_EOC 1
-#define IRQ_IOP32X_DMA1_EOT 2
-#define IRQ_IOP32X_DMA1_EOC 3
-#define IRQ_IOP32X_AA_EOT 6
-#define IRQ_IOP32X_AA_EOC 7
-#define IRQ_IOP32X_CORE_PMON 8
-#define IRQ_IOP32X_TIMER0 9
-#define IRQ_IOP32X_TIMER1 10
-#define IRQ_IOP32X_I2C_0 11
-#define IRQ_IOP32X_I2C_1 12
-#define IRQ_IOP32X_MESSAGING 13
-#define IRQ_IOP32X_ATU_BIST 14
-#define IRQ_IOP32X_PERFMON 15
-#define IRQ_IOP32X_CORE_PMU 16
-#define IRQ_IOP32X_BIU_ERR 17
-#define IRQ_IOP32X_ATU_ERR 18
-#define IRQ_IOP32X_MCU_ERR 19
-#define IRQ_IOP32X_DMA0_ERR 20
-#define IRQ_IOP32X_DMA1_ERR 21
-#define IRQ_IOP32X_AA_ERR 23
-#define IRQ_IOP32X_MSG_ERR 24
-#define IRQ_IOP32X_SSP 25
-#define IRQ_IOP32X_XINT0 27
-#define IRQ_IOP32X_XINT1 28
-#define IRQ_IOP32X_XINT2 29
-#define IRQ_IOP32X_XINT3 30
-#define IRQ_IOP32X_HPI 31
+#define IRQ_IOP32X_DMA0_EOT IOP_IRQ(0)
+#define IRQ_IOP32X_DMA0_EOC IOP_IRQ(1)
+#define IRQ_IOP32X_DMA1_EOT IOP_IRQ(2)
+#define IRQ_IOP32X_DMA1_EOC IOP_IRQ(3)
+#define IRQ_IOP32X_AA_EOT IOP_IRQ(6)
+#define IRQ_IOP32X_AA_EOC IOP_IRQ(7)
+#define IRQ_IOP32X_CORE_PMON IOP_IRQ(8)
+#define IRQ_IOP32X_TIMER0 IOP_IRQ(9)
+#define IRQ_IOP32X_TIMER1 IOP_IRQ(10)
+#define IRQ_IOP32X_I2C_0 IOP_IRQ(11)
+#define IRQ_IOP32X_I2C_1 IOP_IRQ(12)
+#define IRQ_IOP32X_MESSAGING IOP_IRQ(13)
+#define IRQ_IOP32X_ATU_BIST IOP_IRQ(14)
+#define IRQ_IOP32X_PERFMON IOP_IRQ(15)
+#define IRQ_IOP32X_CORE_PMU IOP_IRQ(16)
+#define IRQ_IOP32X_BIU_ERR IOP_IRQ(17)
+#define IRQ_IOP32X_ATU_ERR IOP_IRQ(18)
+#define IRQ_IOP32X_MCU_ERR IOP_IRQ(19)
+#define IRQ_IOP32X_DMA0_ERR IOP_IRQ(20)
+#define IRQ_IOP32X_DMA1_ERR IOP_IRQ(21)
+#define IRQ_IOP32X_AA_ERR IOP_IRQ(23)
+#define IRQ_IOP32X_MSG_ERR IOP_IRQ(24)
+#define IRQ_IOP32X_SSP IOP_IRQ(25)
+#define IRQ_IOP32X_XINT0 IOP_IRQ(27)
+#define IRQ_IOP32X_XINT1 IOP_IRQ(28)
+#define IRQ_IOP32X_XINT2 IOP_IRQ(29)
+#define IRQ_IOP32X_XINT3 IOP_IRQ(30)
+#define IRQ_IOP32X_HPI IOP_IRQ(31)
#endif
diff --git a/arch/arm/mach-ixp4xx/Kconfig b/arch/arm/mach-ixp4xx/Kconfig
index 4c787b4be62b..f41ba3f42fc8 100644
--- a/arch/arm/mach-ixp4xx/Kconfig
+++ b/arch/arm/mach-ixp4xx/Kconfig
@@ -17,63 +17,6 @@ config MACH_IXP4XX_OF
help
Say 'Y' here to support Device Tree-based IXP4xx platforms.
-config MACH_GATEWAY7001
- bool "Gateway 7001"
- depends on IXP4XX_PCI_LEGACY
- help
- Say 'Y' here if you want your kernel to support Gateway's
- 7001 Access Point. For more information on this platform,
- see http://openwrt.org
-
-config MACH_GORAMO_MLR
- bool "GORAMO Multi Link Router"
- depends on IXP4XX_PCI_LEGACY
- help
- Say 'Y' here if you want your kernel to support GORAMO
- MultiLink router.
-
-config ARCH_PRPMC1100
- bool "PrPMC1100"
- help
- Say 'Y' here if you want your kernel to support the Motorola
- PrPCM1100 Processor Mezanine Module. For more information on
- this platform, see <file:Documentation/arm/ixp4xx.rst>.
-
-comment "IXP4xx Options"
-
-config IXP4XX_PCI_LEGACY
- bool "IXP4xx legacy PCI driver support"
- depends on PCI
- help
- Selects legacy PCI driver.
- Not recommended for new development.
-
-config IXP4XX_INDIRECT_PCI
- bool "Use indirect PCI memory access"
- depends on IXP4XX_PCI_LEGACY
- help
- IXP4xx provides two methods of accessing PCI memory space:
-
- 1) A direct mapped window from 0x48000000 to 0x4BFFFFFF (64MB).
- To access PCI via this space, we simply ioremap() the BAR
- into the kernel and we can use the standard read[bwl]/write[bwl]
- macros. This is the preferred method due to speed but it
- limits the system to just 64MB of PCI memory. This can be
- problematic if using video cards and other memory-heavy devices.
-
- 2) If > 64MB of memory space is required, the IXP4xx can be
- configured to use indirect registers to access the whole PCI
- memory space. This currently allows for up to 1 GB (0x10000000
- to 0x4FFFFFFF) of memory on the bus. The disadvantage of this
- is that every PCI access requires three local register accesses
- plus a spinlock, but in some cases the performance hit is
- acceptable. In addition, you cannot mmap() PCI devices in this
- case due to the indirect nature of the PCI window.
-
- By default, the direct method is used. Choose this option if you
- need to use the indirect method instead. If you don't know
- what you need, leave this option unselected.
-
endmenu
endif
diff --git a/arch/arm/mach-ixp4xx/Makefile b/arch/arm/mach-ixp4xx/Makefile
index b241094c9649..3d1c9d854c7f 100644
--- a/arch/arm/mach-ixp4xx/Makefile
+++ b/arch/arm/mach-ixp4xx/Makefile
@@ -1,19 +1,2 @@
# SPDX-License-Identifier: GPL-2.0
-#
-# Makefile for the linux kernel.
-#
-
-obj-pci-y :=
-obj-pci-n :=
-
-# Device tree platform
-obj-pci-$(CONFIG_MACH_IXP4XX_OF) += ixp4xx-of.o
-
-obj-pci-$(CONFIG_MACH_GATEWAY7001) += gateway7001-pci.o
-
-obj-y += common.o
-
-obj-$(CONFIG_MACH_GATEWAY7001) += gateway7001-setup.o
-obj-$(CONFIG_MACH_GORAMO_MLR) += goramo_mlr.o
-
-obj-$(CONFIG_PCI) += $(obj-pci-$(CONFIG_PCI)) common-pci.o
+obj-y += ixp4xx-of.o
diff --git a/arch/arm/mach-ixp4xx/common-pci.c b/arch/arm/mach-ixp4xx/common-pci.c
deleted file mode 100644
index 893c19c254e3..000000000000
--- a/arch/arm/mach-ixp4xx/common-pci.c
+++ /dev/null
@@ -1,451 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * arch/arm/mach-ixp4xx/common-pci.c
- *
- * IXP4XX PCI routines for all platforms
- *
- * Maintainer: Deepak Saxena <dsaxena@plexity.net>
- *
- * Copyright (C) 2002 Intel Corporation.
- * Copyright (C) 2003 Greg Ungerer <gerg@snapgear.com>
- * Copyright (C) 2003-2004 MontaVista Software, Inc.
- */
-
-#include <linux/sched.h>
-#include <linux/kernel.h>
-#include <linux/pci.h>
-#include <linux/interrupt.h>
-#include <linux/mm.h>
-#include <linux/init.h>
-#include <linux/ioport.h>
-#include <linux/slab.h>
-#include <linux/delay.h>
-#include <linux/device.h>
-#include <linux/io.h>
-#include <linux/export.h>
-#include <asm/dma-mapping.h>
-
-#include <asm/cputype.h>
-#include <asm/irq.h>
-#include <linux/sizes.h>
-#include <asm/mach/pci.h>
-#include <mach/hardware.h>
-
-
-/*
- * IXP4xx PCI read function is dependent on whether we are
- * running A0 or B0 (AppleGate) silicon.
- */
-int (*ixp4xx_pci_read)(u32 addr, u32 cmd, u32* data);
-
-/*
- * Base address for PCI register region
- */
-unsigned long ixp4xx_pci_reg_base = 0;
-
-/*
- * PCI cfg an I/O routines are done by programming a
- * command/byte enable register, and then read/writing
- * the data from a data register. We need to ensure
- * these transactions are atomic or we will end up
- * with corrupt data on the bus or in a driver.
- */
-static DEFINE_RAW_SPINLOCK(ixp4xx_pci_lock);
-
-/*
- * Read from PCI config space
- */
-static void crp_read(u32 ad_cbe, u32 *data)
-{
- unsigned long flags;
- raw_spin_lock_irqsave(&ixp4xx_pci_lock, flags);
- *PCI_CRP_AD_CBE = ad_cbe;
- *data = *PCI_CRP_RDATA;
- raw_spin_unlock_irqrestore(&ixp4xx_pci_lock, flags);
-}
-
-/*
- * Write to PCI config space
- */
-static void crp_write(u32 ad_cbe, u32 data)
-{
- unsigned long flags;
- raw_spin_lock_irqsave(&ixp4xx_pci_lock, flags);
- *PCI_CRP_AD_CBE = CRP_AD_CBE_WRITE | ad_cbe;
- *PCI_CRP_WDATA = data;
- raw_spin_unlock_irqrestore(&ixp4xx_pci_lock, flags);
-}
-
-static inline int check_master_abort(void)
-{
- /* check Master Abort bit after access */
- unsigned long isr = *PCI_ISR;
-
- if (isr & PCI_ISR_PFE) {
- /* make sure the Master Abort bit is reset */
- *PCI_ISR = PCI_ISR_PFE;
- pr_debug("%s failed\n", __func__);
- return 1;
- }
-
- return 0;
-}
-
-int ixp4xx_pci_read_errata(u32 addr, u32 cmd, u32* data)
-{
- unsigned long flags;
- int retval = 0;
- int i;
-
- raw_spin_lock_irqsave(&ixp4xx_pci_lock, flags);
-
- *PCI_NP_AD = addr;
-
- /*
- * PCI workaround - only works if NP PCI space reads have
- * no side effects!!! Read 8 times. last one will be good.
- */
- for (i = 0; i < 8; i++) {
- *PCI_NP_CBE = cmd;
- *data = *PCI_NP_RDATA;
- *data = *PCI_NP_RDATA;
- }
-
- if(check_master_abort())
- retval = 1;
-
- raw_spin_unlock_irqrestore(&ixp4xx_pci_lock, flags);
- return retval;
-}
-
-int ixp4xx_pci_read_no_errata(u32 addr, u32 cmd, u32* data)
-{
- unsigned long flags;
- int retval = 0;
-
- raw_spin_lock_irqsave(&ixp4xx_pci_lock, flags);
-
- *PCI_NP_AD = addr;
-
- /* set up and execute the read */
- *PCI_NP_CBE = cmd;
-
- /* the result of the read is now in NP_RDATA */
- *data = *PCI_NP_RDATA;
-
- if(check_master_abort())
- retval = 1;
-
- raw_spin_unlock_irqrestore(&ixp4xx_pci_lock, flags);
- return retval;
-}
-
-int ixp4xx_pci_write(u32 addr, u32 cmd, u32 data)
-{
- unsigned long flags;
- int retval = 0;
-
- raw_spin_lock_irqsave(&ixp4xx_pci_lock, flags);
-
- *PCI_NP_AD = addr;
-
- /* set up the write */
- *PCI_NP_CBE = cmd;
-
- /* execute the write by writing to NP_WDATA */
- *PCI_NP_WDATA = data;
-
- if(check_master_abort())
- retval = 1;
-
- raw_spin_unlock_irqrestore(&ixp4xx_pci_lock, flags);
- return retval;
-}
-
-static u32 ixp4xx_config_addr(u8 bus_num, u16 devfn, int where)
-{
- u32 addr;
- if (!bus_num) {
- /* type 0 */
- addr = BIT(32-PCI_SLOT(devfn)) | ((PCI_FUNC(devfn)) << 8) |
- (where & ~3);
- } else {
- /* type 1 */
- addr = (bus_num << 16) | ((PCI_SLOT(devfn)) << 11) |
- ((PCI_FUNC(devfn)) << 8) | (where & ~3) | 1;
- }
- return addr;
-}
-
-/*
- * Mask table, bits to mask for quantity of size 1, 2 or 4 bytes.
- * 0 and 3 are not valid indexes...
- */
-static u32 bytemask[] = {
- /*0*/ 0,
- /*1*/ 0xff,
- /*2*/ 0xffff,
- /*3*/ 0,
- /*4*/ 0xffffffff,
-};
-
-static u32 local_byte_lane_enable_bits(u32 n, int size)
-{
- if (size == 1)
- return (0xf & ~BIT(n)) << CRP_AD_CBE_BESL;
- if (size == 2)
- return (0xf & ~(BIT(n) | BIT(n+1))) << CRP_AD_CBE_BESL;
- if (size == 4)
- return 0;
- return 0xffffffff;
-}
-
-static int local_read_config(int where, int size, u32 *value)
-{
- u32 n, data;
- pr_debug("local_read_config from %d size %d\n", where, size);
- n = where % 4;
- crp_read(where & ~3, &data);
- *value = (data >> (8*n)) & bytemask[size];
- pr_debug("local_read_config read %#x\n", *value);
- return PCIBIOS_SUCCESSFUL;
-}
-
-static int local_write_config(int where, int size, u32 value)
-{
- u32 n, byte_enables, data;
- pr_debug("local_write_config %#x to %d size %d\n", value, where, size);
- n = where % 4;
- byte_enables = local_byte_lane_enable_bits(n, size);
- if (byte_enables == 0xffffffff)
- return PCIBIOS_BAD_REGISTER_NUMBER;
- data = value << (8*n);
- crp_write((where & ~3) | byte_enables, data);
- return PCIBIOS_SUCCESSFUL;
-}
-
-static u32 byte_lane_enable_bits(u32 n, int size)
-{
- if (size == 1)
- return (0xf & ~BIT(n)) << 4;
- if (size == 2)
- return (0xf & ~(BIT(n) | BIT(n+1))) << 4;
- if (size == 4)
- return 0;
- return 0xffffffff;
-}
-
-static int ixp4xx_pci_read_config(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *value)
-{
- u32 n, byte_enables, addr, data;
- u8 bus_num = bus->number;
-
- pr_debug("read_config from %d size %d dev %d:%d:%d\n", where, size,
- bus_num, PCI_SLOT(devfn), PCI_FUNC(devfn));
-
- *value = 0xffffffff;
- n = where % 4;
- byte_enables = byte_lane_enable_bits(n, size);
- if (byte_enables == 0xffffffff)
- return PCIBIOS_BAD_REGISTER_NUMBER;
-
- addr = ixp4xx_config_addr(bus_num, devfn, where);
- if (ixp4xx_pci_read(addr, byte_enables | NP_CMD_CONFIGREAD, &data))
- return PCIBIOS_DEVICE_NOT_FOUND;
-
- *value = (data >> (8*n)) & bytemask[size];
- pr_debug("read_config_byte read %#x\n", *value);
- return PCIBIOS_SUCCESSFUL;
-}
-
-static int ixp4xx_pci_write_config(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 value)
-{
- u32 n, byte_enables, addr, data;
- u8 bus_num = bus->number;
-
- pr_debug("write_config_byte %#x to %d size %d dev %d:%d:%d\n", value, where,
- size, bus_num, PCI_SLOT(devfn), PCI_FUNC(devfn));
-
- n = where % 4;
- byte_enables = byte_lane_enable_bits(n, size);
- if (byte_enables == 0xffffffff)
- return PCIBIOS_BAD_REGISTER_NUMBER;
-
- addr = ixp4xx_config_addr(bus_num, devfn, where);
- data = value << (8*n);
- if (ixp4xx_pci_write(addr, byte_enables | NP_CMD_CONFIGWRITE, data))
- return PCIBIOS_DEVICE_NOT_FOUND;
-
- return PCIBIOS_SUCCESSFUL;
-}
-
-struct pci_ops ixp4xx_ops = {
- .read = ixp4xx_pci_read_config,
- .write = ixp4xx_pci_write_config,
-};
-
-/*
- * PCI abort handler
- */
-static int abort_handler(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
-{
- u32 isr, status;
-
- isr = *PCI_ISR;
- local_read_config(PCI_STATUS, 2, &status);
- pr_debug("PCI: abort_handler addr = %#lx, isr = %#x, "
- "status = %#x\n", addr, isr, status);
-
- /* make sure the Master Abort bit is reset */
- *PCI_ISR = PCI_ISR_PFE;
- status |= PCI_STATUS_REC_MASTER_ABORT;
- local_write_config(PCI_STATUS, 2, status);
-
- /*
- * If it was an imprecise abort, then we need to correct the
- * return address to be _after_ the instruction.
- */
- if (fsr & (1 << 10))
- regs->ARM_pc += 4;
-
- return 0;
-}
-
-void __init ixp4xx_pci_preinit(void)
-{
- unsigned long cpuid = read_cpuid_id();
-
-#ifdef CONFIG_IXP4XX_INDIRECT_PCI
- pcibios_min_mem = 0x10000000; /* 1 GB of indirect PCI MMIO space */
-#else
- pcibios_min_mem = 0x48000000; /* 64 MB of PCI MMIO space */
-#endif
- /*
- * Determine which PCI read method to use.
- * Rev 0 IXP425 requires workaround.
- */
- if (!(cpuid & 0xf) && cpu_is_ixp42x()) {
- printk("PCI: IXP42x A0 silicon detected - "
- "PCI Non-Prefetch Workaround Enabled\n");
- ixp4xx_pci_read = ixp4xx_pci_read_errata;
- } else
- ixp4xx_pci_read = ixp4xx_pci_read_no_errata;
-
-
- /* hook in our fault handler for PCI errors */
- hook_fault_code(16+6, abort_handler, SIGBUS, 0,
- "imprecise external abort");
-
- pr_debug("setup PCI-AHB(inbound) and AHB-PCI(outbound) address mappings\n");
-
- /*
- * We use identity AHB->PCI address translation
- * in the 0x48000000 to 0x4bffffff address space
- */
- *PCI_PCIMEMBASE = 0x48494A4B;
-
- /*
- * We also use identity PCI->AHB address translation
- * in 4 16MB BARs that begin at the physical memory start
- */
- *PCI_AHBMEMBASE = (PHYS_OFFSET & 0xFF000000) +
- ((PHYS_OFFSET & 0xFF000000) >> 8) +
- ((PHYS_OFFSET & 0xFF000000) >> 16) +
- ((PHYS_OFFSET & 0xFF000000) >> 24) +
- 0x00010203;
-
- if (*PCI_CSR & PCI_CSR_HOST) {
- printk("PCI: IXP4xx is host\n");
-
- pr_debug("setup BARs in controller\n");
-
- /*
- * We configure the PCI inbound memory windows to be
- * 1:1 mapped to SDRAM
- */
- local_write_config(PCI_BASE_ADDRESS_0, 4, PHYS_OFFSET);
- local_write_config(PCI_BASE_ADDRESS_1, 4, PHYS_OFFSET + SZ_16M);
- local_write_config(PCI_BASE_ADDRESS_2, 4, PHYS_OFFSET + SZ_32M);
- local_write_config(PCI_BASE_ADDRESS_3, 4,
- PHYS_OFFSET + SZ_32M + SZ_16M);
-
- /*
- * Enable CSR window at 64 MiB to allow PCI masters
- * to continue prefetching past 64 MiB boundary.
- */
- local_write_config(PCI_BASE_ADDRESS_4, 4, PHYS_OFFSET + SZ_64M);
-
- /*
- * Enable the IO window to be way up high, at 0xfffffc00
- */
- local_write_config(PCI_BASE_ADDRESS_5, 4, 0xfffffc01);
- local_write_config(0x40, 4, 0x000080FF); /* No TRDY time limit */
- } else {
- printk("PCI: IXP4xx is target - No bus scan performed\n");
- }
-
- printk("PCI: IXP4xx Using %s access for memory space\n",
-#ifndef CONFIG_IXP4XX_INDIRECT_PCI
- "direct"
-#else
- "indirect"
-#endif
- );
-
- pr_debug("clear error bits in ISR\n");
- *PCI_ISR = PCI_ISR_PSE | PCI_ISR_PFE | PCI_ISR_PPE | PCI_ISR_AHBE;
-
- /*
- * Set Initialize Complete in PCI Control Register: allow IXP4XX to
- * respond to PCI configuration cycles. Specify that the AHB bus is
- * operating in big endian mode. Set up byte lane swapping between
- * little-endian PCI and the big-endian AHB bus
- */
-#ifdef __ARMEB__
- *PCI_CSR = PCI_CSR_IC | PCI_CSR_ABE | PCI_CSR_PDS | PCI_CSR_ADS;
-#else
- *PCI_CSR = PCI_CSR_IC | PCI_CSR_ABE;
-#endif
-
- pr_debug("DONE\n");
-}
-
-int ixp4xx_setup(int nr, struct pci_sys_data *sys)
-{
- struct resource *res;
-
- if (nr >= 1)
- return 0;
-
- res = kcalloc(2, sizeof(*res), GFP_KERNEL);
- if (res == NULL) {
- /*
- * If we're out of memory this early, something is wrong,
- * so we might as well catch it here.
- */
- panic("PCI: unable to allocate resources?\n");
- }
-
- local_write_config(PCI_COMMAND, 2, PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY);
-
- res[0].name = "PCI I/O Space";
- res[0].start = 0x00000000;
- res[0].end = 0x0000ffff;
- res[0].flags = IORESOURCE_IO;
-
- res[1].name = "PCI Memory Space";
- res[1].start = PCIBIOS_MIN_MEM;
- res[1].end = PCIBIOS_MAX_MEM;
- res[1].flags = IORESOURCE_MEM;
-
- request_resource(&ioport_resource, &res[0]);
- request_resource(&iomem_resource, &res[1]);
-
- pci_add_resource_offset(&sys->resources, &res[0], sys->io_offset);
- pci_add_resource_offset(&sys->resources, &res[1], sys->mem_offset);
-
- return 1;
-}
-
-EXPORT_SYMBOL(ixp4xx_pci_read);
-EXPORT_SYMBOL(ixp4xx_pci_write);
diff --git a/arch/arm/mach-ixp4xx/common.c b/arch/arm/mach-ixp4xx/common.c
deleted file mode 100644
index cdc720f54daa..000000000000
--- a/arch/arm/mach-ixp4xx/common.c
+++ /dev/null
@@ -1,448 +0,0 @@
-/*
- * arch/arm/mach-ixp4xx/common.c
- *
- * Generic code shared across all IXP4XX platforms
- *
- * Maintainer: Deepak Saxena <dsaxena@plexity.net>
- *
- * Copyright 2002 (c) Intel Corporation
- * Copyright 2003-2004 (c) MontaVista, Software, Inc.
- *
- * This file is licensed under the terms of the GNU General Public
- * License version 2. This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
- */
-
-#include <linux/kernel.h>
-#include <linux/mm.h>
-#include <linux/init.h>
-#include <linux/serial.h>
-#include <linux/tty.h>
-#include <linux/platform_device.h>
-#include <linux/serial_core.h>
-#include <linux/interrupt.h>
-#include <linux/bitops.h>
-#include <linux/io.h>
-#include <linux/export.h>
-#include <linux/cpu.h>
-#include <linux/pci.h>
-#include <linux/sched_clock.h>
-#include <linux/soc/ixp4xx/cpu.h>
-#include <linux/irqchip/irq-ixp4xx.h>
-#include <linux/platform_data/timer-ixp4xx.h>
-#include <linux/dma-map-ops.h>
-#include <mach/udc.h>
-#include <mach/hardware.h>
-#include <linux/uaccess.h>
-#include <asm/page.h>
-#include <asm/exception.h>
-#include <asm/irq.h>
-#include <asm/system_misc.h>
-#include <asm/mach/map.h>
-#include <asm/mach/irq.h>
-#include <asm/mach/time.h>
-
-#include "irqs.h"
-
-u32 ixp4xx_read_feature_bits(void)
-{
- u32 val = ~__raw_readl(IXP4XX_EXP_CFG2);
-
- if (cpu_is_ixp42x_rev_a0())
- return IXP42X_FEATURE_MASK & ~(IXP4XX_FEATURE_RCOMP |
- IXP4XX_FEATURE_AES);
- if (cpu_is_ixp42x())
- return val & IXP42X_FEATURE_MASK;
- if (cpu_is_ixp43x())
- return val & IXP43X_FEATURE_MASK;
- return val & IXP46X_FEATURE_MASK;
-}
-EXPORT_SYMBOL(ixp4xx_read_feature_bits);
-
-void ixp4xx_write_feature_bits(u32 value)
-{
- __raw_writel(~value, IXP4XX_EXP_CFG2);
-}
-EXPORT_SYMBOL(ixp4xx_write_feature_bits);
-
-#define IXP4XX_TIMER_FREQ 66666000
-
-/*************************************************************************
- * IXP4xx chipset I/O mapping
- *************************************************************************/
-static struct map_desc ixp4xx_io_desc[] __initdata = {
- { /* UART, Interrupt ctrl, GPIO, timers, NPEs, MACs, USB .... */
- .virtual = (unsigned long)IXP4XX_PERIPHERAL_BASE_VIRT,
- .pfn = __phys_to_pfn(IXP4XX_PERIPHERAL_BASE_PHYS),
- .length = IXP4XX_PERIPHERAL_REGION_SIZE,
- .type = MT_DEVICE
- }, { /* Expansion Bus Config Registers */
- .virtual = (unsigned long)IXP4XX_EXP_CFG_BASE_VIRT,
- .pfn = __phys_to_pfn(IXP4XX_EXP_CFG_BASE_PHYS),
- .length = IXP4XX_EXP_CFG_REGION_SIZE,
- .type = MT_DEVICE
- }, { /* PCI Registers */
- .virtual = (unsigned long)IXP4XX_PCI_CFG_BASE_VIRT,
- .pfn = __phys_to_pfn(IXP4XX_PCI_CFG_BASE_PHYS),
- .length = IXP4XX_PCI_CFG_REGION_SIZE,
- .type = MT_DEVICE
- },
-};
-
-void __init ixp4xx_map_io(void)
-{
- iotable_init(ixp4xx_io_desc, ARRAY_SIZE(ixp4xx_io_desc));
-}
-
-void __init ixp4xx_init_irq(void)
-{
- /*
- * ixp4xx does not implement the XScale PWRMODE register
- * so it must not call cpu_do_idle().
- */
- cpu_idle_poll_ctrl(true);
-
- ixp4xx_irq_init(IXP4XX_INTC_BASE_PHYS,
- (cpu_is_ixp46x() || cpu_is_ixp43x()));
-}
-
-void __init ixp4xx_timer_init(void)
-{
- return ixp4xx_timer_setup(IXP4XX_TIMER_BASE_PHYS,
- IRQ_IXP4XX_TIMER1,
- IXP4XX_TIMER_FREQ);
-}
-
-static struct pxa2xx_udc_mach_info ixp4xx_udc_info;
-
-void __init ixp4xx_set_udc_info(struct pxa2xx_udc_mach_info *info)
-{
- memcpy(&ixp4xx_udc_info, info, sizeof *info);
-}
-
-static struct resource ixp4xx_udc_resources[] = {
- [0] = {
- .start = 0xc800b000,
- .end = 0xc800bfff,
- .flags = IORESOURCE_MEM,
- },
- [1] = {
- .start = IRQ_IXP4XX_USB,
- .end = IRQ_IXP4XX_USB,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-static struct resource ixp4xx_gpio_resource[] = {
- {
- .start = IXP4XX_GPIO_BASE_PHYS,
- .end = IXP4XX_GPIO_BASE_PHYS + 0xfff,
- .flags = IORESOURCE_MEM,
- },
-};
-
-static struct platform_device ixp4xx_gpio_device = {
- .name = "ixp4xx-gpio",
- .id = -1,
- .dev = {
- .coherent_dma_mask = DMA_BIT_MASK(32),
- },
- .resource = ixp4xx_gpio_resource,
- .num_resources = ARRAY_SIZE(ixp4xx_gpio_resource),
-};
-
-/*
- * USB device controller. The IXP4xx uses the same controller as PXA25X,
- * so we just use the same device.
- */
-static struct platform_device ixp4xx_udc_device = {
- .name = "pxa25x-udc",
- .id = -1,
- .num_resources = 2,
- .resource = ixp4xx_udc_resources,
- .dev = {
- .platform_data = &ixp4xx_udc_info,
- },
-};
-
-static struct resource ixp4xx_npe_resources[] = {
- {
- .start = IXP4XX_NPEA_BASE_PHYS,
- .end = IXP4XX_NPEA_BASE_PHYS + 0xfff,
- .flags = IORESOURCE_MEM,
- },
- {
- .start = IXP4XX_NPEB_BASE_PHYS,
- .end = IXP4XX_NPEB_BASE_PHYS + 0xfff,
- .flags = IORESOURCE_MEM,
- },
- {
- .start = IXP4XX_NPEC_BASE_PHYS,
- .end = IXP4XX_NPEC_BASE_PHYS + 0xfff,
- .flags = IORESOURCE_MEM,
- },
-
-};
-
-static struct platform_device ixp4xx_npe_device = {
- .name = "ixp4xx-npe",
- .id = -1,
- .num_resources = ARRAY_SIZE(ixp4xx_npe_resources),
- .resource = ixp4xx_npe_resources,
-};
-
-static struct resource ixp4xx_qmgr_resources[] = {
- {
- .start = IXP4XX_QMGR_BASE_PHYS,
- .end = IXP4XX_QMGR_BASE_PHYS + 0x3fff,
- .flags = IORESOURCE_MEM,
- },
- {
- .start = IRQ_IXP4XX_QM1,
- .end = IRQ_IXP4XX_QM1,
- .flags = IORESOURCE_IRQ,
- },
- {
- .start = IRQ_IXP4XX_QM2,
- .end = IRQ_IXP4XX_QM2,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-static struct platform_device ixp4xx_qmgr_device = {
- .name = "ixp4xx-qmgr",
- .id = -1,
- .num_resources = ARRAY_SIZE(ixp4xx_qmgr_resources),
- .resource = ixp4xx_qmgr_resources,
-};
-
-static struct platform_device *ixp4xx_devices[] __initdata = {
- &ixp4xx_npe_device,
- &ixp4xx_qmgr_device,
- &ixp4xx_gpio_device,
- &ixp4xx_udc_device,
-};
-
-static struct resource ixp46x_i2c_resources[] = {
- [0] = {
- .start = 0xc8011000,
- .end = 0xc801101c,
- .flags = IORESOURCE_MEM,
- },
- [1] = {
- .start = IRQ_IXP4XX_I2C,
- .end = IRQ_IXP4XX_I2C,
- .flags = IORESOURCE_IRQ
- }
-};
-
-/* A single 32-bit register on IXP46x */
-#define IXP4XX_HWRANDOM_BASE_PHYS 0x70002100
-
-static struct resource ixp46x_hwrandom_resource[] = {
- {
- .start = IXP4XX_HWRANDOM_BASE_PHYS,
- .end = IXP4XX_HWRANDOM_BASE_PHYS + 0x3,
- .flags = IORESOURCE_MEM,
- },
-};
-
-static struct platform_device ixp46x_hwrandom_device = {
- .name = "ixp4xx-hwrandom",
- .id = -1,
- .dev = {
- .coherent_dma_mask = DMA_BIT_MASK(32),
- },
- .resource = ixp46x_hwrandom_resource,
- .num_resources = ARRAY_SIZE(ixp46x_hwrandom_resource),
-};
-
-/*
- * I2C controller. The IXP46x uses the same block as the IOP3xx, so
- * we just use the same device name.
- */
-static struct platform_device ixp46x_i2c_controller = {
- .name = "IOP3xx-I2C",
- .id = 0,
- .num_resources = 2,
- .resource = ixp46x_i2c_resources
-};
-
-static struct resource ixp46x_ptp_resources[] = {
- DEFINE_RES_MEM(IXP4XX_TIMESYNC_BASE_PHYS, SZ_4K),
- DEFINE_RES_IRQ_NAMED(IRQ_IXP4XX_GPIO8, "master"),
- DEFINE_RES_IRQ_NAMED(IRQ_IXP4XX_GPIO7, "slave"),
-};
-
-static struct platform_device ixp46x_ptp = {
- .name = "ptp-ixp46x",
- .id = -1,
- .resource = ixp46x_ptp_resources,
- .num_resources = ARRAY_SIZE(ixp46x_ptp_resources),
-};
-
-static struct platform_device *ixp46x_devices[] __initdata = {
- &ixp46x_hwrandom_device,
- &ixp46x_i2c_controller,
- &ixp46x_ptp,
-};
-
-unsigned long ixp4xx_exp_bus_size;
-EXPORT_SYMBOL(ixp4xx_exp_bus_size);
-
-static struct platform_device_info ixp_dev_info __initdata = {
- .name = "ixp4xx_crypto",
- .id = 0,
- .dma_mask = DMA_BIT_MASK(32),
-};
-
-static int __init ixp_crypto_register(void)
-{
- struct platform_device *pdev;
-
- if (!(~(*IXP4XX_EXP_CFG2) & (IXP4XX_FEATURE_HASH |
- IXP4XX_FEATURE_AES | IXP4XX_FEATURE_DES))) {
- printk(KERN_ERR "ixp_crypto: No HW crypto available\n");
- return -ENODEV;
- }
-
- pdev = platform_device_register_full(&ixp_dev_info);
- if (IS_ERR(pdev))
- return PTR_ERR(pdev);
-
- return 0;
-}
-
-void __init ixp4xx_sys_init(void)
-{
- ixp4xx_exp_bus_size = SZ_16M;
-
- platform_add_devices(ixp4xx_devices, ARRAY_SIZE(ixp4xx_devices));
-
- if (IS_ENABLED(CONFIG_CRYPTO_DEV_IXP4XX))
- ixp_crypto_register();
-
- if (cpu_is_ixp46x()) {
- int region;
-
- platform_add_devices(ixp46x_devices,
- ARRAY_SIZE(ixp46x_devices));
-
- for (region = 0; region < 7; region++) {
- if((*(IXP4XX_EXP_REG(0x4 * region)) & 0x200)) {
- ixp4xx_exp_bus_size = SZ_32M;
- break;
- }
- }
- }
-
- printk("IXP4xx: Using %luMiB expansion bus window size\n",
- ixp4xx_exp_bus_size >> 20);
-}
-
-unsigned long ixp4xx_timer_freq = IXP4XX_TIMER_FREQ;
-EXPORT_SYMBOL(ixp4xx_timer_freq);
-
-void ixp4xx_restart(enum reboot_mode mode, const char *cmd)
-{
- if (mode == REBOOT_SOFT) {
- /* Jump into ROM at address 0 */
- soft_restart(0);
- } else {
- /* Use on-chip reset capability */
-
- /* set the "key" register to enable access to
- * "timer" and "enable" registers
- */
- *IXP4XX_OSWK = IXP4XX_WDT_KEY;
-
- /* write 0 to the timer register for an immediate reset */
- *IXP4XX_OSWT = 0;
-
- *IXP4XX_OSWE = IXP4XX_WDT_RESET_ENABLE | IXP4XX_WDT_COUNT_ENABLE;
- }
-}
-
-#ifdef CONFIG_PCI
-static int ixp4xx_needs_bounce(struct device *dev, dma_addr_t dma_addr, size_t size)
-{
- return (dma_addr + size) > SZ_64M;
-}
-
-static int ixp4xx_platform_notify_remove(struct device *dev)
-{
- if (dev_is_pci(dev))
- dmabounce_unregister_dev(dev);
-
- return 0;
-}
-#endif
-
-/*
- * Setup DMA mask to 64MB on PCI devices and 4 GB on all other things.
- */
-static int ixp4xx_platform_notify(struct device *dev)
-{
- dev->dma_mask = &dev->coherent_dma_mask;
-
-#ifdef CONFIG_PCI
- if (dev_is_pci(dev)) {
- dev->coherent_dma_mask = DMA_BIT_MASK(28); /* 64 MB */
- dmabounce_register_dev(dev, 2048, 4096, ixp4xx_needs_bounce);
- return 0;
- }
-#endif
-
- dev->coherent_dma_mask = DMA_BIT_MASK(32);
- return 0;
-}
-
-int dma_set_coherent_mask(struct device *dev, u64 mask)
-{
- if (dev_is_pci(dev))
- mask &= DMA_BIT_MASK(28); /* 64 MB */
-
- if ((mask & DMA_BIT_MASK(28)) == DMA_BIT_MASK(28)) {
- dev->coherent_dma_mask = mask;
- return 0;
- }
-
- return -EIO; /* device wanted sub-64MB mask */
-}
-EXPORT_SYMBOL(dma_set_coherent_mask);
-
-#ifdef CONFIG_IXP4XX_INDIRECT_PCI
-/*
- * In the case of using indirect PCI, we simply return the actual PCI
- * address and our read/write implementation use that to drive the
- * access registers. If something outside of PCI is ioremap'd, we
- * fallback to the default.
- */
-
-static void __iomem *ixp4xx_ioremap_caller(phys_addr_t addr, size_t size,
- unsigned int mtype, void *caller)
-{
- if (!is_pci_memory(addr))
- return __arm_ioremap_caller(addr, size, mtype, caller);
-
- return (void __iomem *)addr;
-}
-
-static void ixp4xx_iounmap(volatile void __iomem *addr)
-{
- if (!is_pci_memory((__force u32)addr))
- __iounmap(addr);
-}
-#endif
-
-void __init ixp4xx_init_early(void)
-{
- platform_notify = ixp4xx_platform_notify;
-#ifdef CONFIG_PCI
- platform_notify_remove = ixp4xx_platform_notify_remove;
-#endif
-#ifdef CONFIG_IXP4XX_INDIRECT_PCI
- arch_ioremap_caller = ixp4xx_ioremap_caller;
- arch_iounmap = ixp4xx_iounmap;
-#endif
-}
diff --git a/arch/arm/mach-ixp4xx/gateway7001-pci.c b/arch/arm/mach-ixp4xx/gateway7001-pci.c
deleted file mode 100644
index 3c3ee9dad6d8..000000000000
--- a/arch/arm/mach-ixp4xx/gateway7001-pci.c
+++ /dev/null
@@ -1,61 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * arch/arch/mach-ixp4xx/gateway7001-pci.c
- *
- * PCI setup routines for Gateway 7001
- *
- * Copyright (C) 2007 Imre Kaloz <kaloz@openwrt.org>
- *
- * based on coyote-pci.c:
- * Copyright (C) 2002 Jungo Software Technologies.
- * Copyright (C) 2003 MontaVista Softwrae, Inc.
- *
- * Maintainer: Imre Kaloz <kaloz@openwrt.org>
- */
-
-#include <linux/kernel.h>
-#include <linux/pci.h>
-#include <linux/init.h>
-#include <linux/irq.h>
-
-#include <asm/mach-types.h>
-#include <mach/hardware.h>
-
-#include <asm/mach/pci.h>
-
-#include "irqs.h"
-
-void __init gateway7001_pci_preinit(void)
-{
- irq_set_irq_type(IRQ_IXP4XX_GPIO10, IRQ_TYPE_LEVEL_LOW);
- irq_set_irq_type(IRQ_IXP4XX_GPIO11, IRQ_TYPE_LEVEL_LOW);
-
- ixp4xx_pci_preinit();
-}
-
-static int __init gateway7001_map_irq(const struct pci_dev *dev, u8 slot,
- u8 pin)
-{
- if (slot == 1)
- return IRQ_IXP4XX_GPIO11;
- else if (slot == 2)
- return IRQ_IXP4XX_GPIO10;
- else return -1;
-}
-
-struct hw_pci gateway7001_pci __initdata = {
- .nr_controllers = 1,
- .ops = &ixp4xx_ops,
- .preinit = gateway7001_pci_preinit,
- .setup = ixp4xx_setup,
- .map_irq = gateway7001_map_irq,
-};
-
-int __init gateway7001_pci_init(void)
-{
- if (machine_is_gateway7001())
- pci_common_init(&gateway7001_pci);
- return 0;
-}
-
-subsys_initcall(gateway7001_pci_init);
diff --git a/arch/arm/mach-ixp4xx/gateway7001-setup.c b/arch/arm/mach-ixp4xx/gateway7001-setup.c
deleted file mode 100644
index 678e7dfff0e5..000000000000
--- a/arch/arm/mach-ixp4xx/gateway7001-setup.c
+++ /dev/null
@@ -1,113 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * arch/arm/mach-ixp4xx/gateway7001-setup.c
- *
- * Board setup for the Gateway 7001 board
- *
- * Copyright (C) 2007 Imre Kaloz <kaloz@openwrt.org>
- *
- * based on coyote-setup.c:
- * Copyright (C) 2003-2005 MontaVista Software, Inc.
- *
- * Author: Imre Kaloz <Kaloz@openwrt.org>
- */
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/device.h>
-#include <linux/serial.h>
-#include <linux/tty.h>
-#include <linux/serial_8250.h>
-
-#include <asm/types.h>
-#include <asm/setup.h>
-#include <asm/memory.h>
-#include <mach/hardware.h>
-#include <asm/irq.h>
-#include <asm/mach-types.h>
-#include <asm/mach/arch.h>
-#include <asm/mach/flash.h>
-
-#include "irqs.h"
-
-static struct flash_platform_data gateway7001_flash_data = {
- .map_name = "cfi_probe",
- .width = 2,
-};
-
-static struct resource gateway7001_flash_resource = {
- .flags = IORESOURCE_MEM,
-};
-
-static struct platform_device gateway7001_flash = {
- .name = "IXP4XX-Flash",
- .id = 0,
- .dev = {
- .platform_data = &gateway7001_flash_data,
- },
- .num_resources = 1,
- .resource = &gateway7001_flash_resource,
-};
-
-static struct resource gateway7001_uart_resource = {
- .start = IXP4XX_UART2_BASE_PHYS,
- .end = IXP4XX_UART2_BASE_PHYS + 0x0fff,
- .flags = IORESOURCE_MEM,
-};
-
-static struct plat_serial8250_port gateway7001_uart_data[] = {
- {
- .mapbase = IXP4XX_UART2_BASE_PHYS,
- .membase = (char *)IXP4XX_UART2_BASE_VIRT + REG_OFFSET,
- .irq = IRQ_IXP4XX_UART2,
- .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
- .iotype = UPIO_MEM,
- .regshift = 2,
- .uartclk = IXP4XX_UART_XTAL,
- },
- { },
-};
-
-static struct platform_device gateway7001_uart = {
- .name = "serial8250",
- .id = PLAT8250_DEV_PLATFORM,
- .dev = {
- .platform_data = gateway7001_uart_data,
- },
- .num_resources = 1,
- .resource = &gateway7001_uart_resource,
-};
-
-static struct platform_device *gateway7001_devices[] __initdata = {
- &gateway7001_flash,
- &gateway7001_uart
-};
-
-static void __init gateway7001_init(void)
-{
- ixp4xx_sys_init();
-
- gateway7001_flash_resource.start = IXP4XX_EXP_BUS_BASE(0);
- gateway7001_flash_resource.end = IXP4XX_EXP_BUS_BASE(0) + SZ_32M - 1;
-
- *IXP4XX_EXP_CS0 |= IXP4XX_FLASH_WRITABLE;
- *IXP4XX_EXP_CS1 = *IXP4XX_EXP_CS0;
-
- platform_add_devices(gateway7001_devices, ARRAY_SIZE(gateway7001_devices));
-}
-
-#ifdef CONFIG_MACH_GATEWAY7001
-MACHINE_START(GATEWAY7001, "Gateway 7001 AP")
- /* Maintainer: Imre Kaloz <kaloz@openwrt.org> */
- .map_io = ixp4xx_map_io,
- .init_early = ixp4xx_init_early,
- .init_irq = ixp4xx_init_irq,
- .init_time = ixp4xx_timer_init,
- .atag_offset = 0x100,
- .init_machine = gateway7001_init,
-#if defined(CONFIG_PCI)
- .dma_zone_size = SZ_64M,
-#endif
- .restart = ixp4xx_restart,
-MACHINE_END
-#endif
diff --git a/arch/arm/mach-ixp4xx/goramo_mlr.c b/arch/arm/mach-ixp4xx/goramo_mlr.c
deleted file mode 100644
index 07b50dfcc489..000000000000
--- a/arch/arm/mach-ixp4xx/goramo_mlr.c
+++ /dev/null
@@ -1,532 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Goramo MultiLink router platform code
- * Copyright (C) 2006-2009 Krzysztof Halasa <khc@pm.waw.pl>
- */
-
-#include <linux/delay.h>
-#include <linux/gpio.h>
-#include <linux/hdlc.h>
-#include <linux/io.h>
-#include <linux/irq.h>
-#include <linux/kernel.h>
-#include <linux/pci.h>
-#include <linux/platform_data/wan_ixp4xx_hss.h>
-#include <linux/serial_8250.h>
-#include <asm/mach-types.h>
-#include <asm/mach/arch.h>
-#include <asm/mach/flash.h>
-#include <asm/mach/pci.h>
-#include <asm/system_info.h>
-
-#include "irqs.h"
-
-#define SLOT_ETHA 0x0B /* IDSEL = AD21 */
-#define SLOT_ETHB 0x0C /* IDSEL = AD20 */
-#define SLOT_MPCI 0x0D /* IDSEL = AD19 */
-#define SLOT_NEC 0x0E /* IDSEL = AD18 */
-
-/* GPIO lines */
-#define GPIO_SCL 0
-#define GPIO_SDA 1
-#define GPIO_STR 2
-#define GPIO_IRQ_NEC 3
-#define GPIO_IRQ_ETHA 4
-#define GPIO_IRQ_ETHB 5
-#define GPIO_HSS0_DCD_N 6
-#define GPIO_HSS1_DCD_N 7
-#define GPIO_UART0_DCD 8
-#define GPIO_UART1_DCD 9
-#define GPIO_HSS0_CTS_N 10
-#define GPIO_HSS1_CTS_N 11
-#define GPIO_IRQ_MPCI 12
-#define GPIO_HSS1_RTS_N 13
-#define GPIO_HSS0_RTS_N 14
-/* GPIO15 is not connected */
-
-/* Control outputs from 74HC4094 */
-#define CONTROL_HSS0_CLK_INT 0
-#define CONTROL_HSS1_CLK_INT 1
-#define CONTROL_HSS0_DTR_N 2
-#define CONTROL_HSS1_DTR_N 3
-#define CONTROL_EXT 4
-#define CONTROL_AUTO_RESET 5
-#define CONTROL_PCI_RESET_N 6
-#define CONTROL_EEPROM_WC_N 7
-
-/* offsets from start of flash ROM = 0x50000000 */
-#define CFG_ETH0_ADDRESS 0x40 /* 6 bytes */
-#define CFG_ETH1_ADDRESS 0x46 /* 6 bytes */
-#define CFG_REV 0x4C /* u32 */
-#define CFG_SDRAM_SIZE 0x50 /* u32 */
-#define CFG_SDRAM_CONF 0x54 /* u32 */
-#define CFG_SDRAM_MODE 0x58 /* u32 */
-#define CFG_SDRAM_REFRESH 0x5C /* u32 */
-
-#define CFG_HW_BITS 0x60 /* u32 */
-#define CFG_HW_USB_PORTS 0x00000007 /* 0 = no NEC chip, 1-5 = ports # */
-#define CFG_HW_HAS_PCI_SLOT 0x00000008
-#define CFG_HW_HAS_ETH0 0x00000010
-#define CFG_HW_HAS_ETH1 0x00000020
-#define CFG_HW_HAS_HSS0 0x00000040
-#define CFG_HW_HAS_HSS1 0x00000080
-#define CFG_HW_HAS_UART0 0x00000100
-#define CFG_HW_HAS_UART1 0x00000200
-#define CFG_HW_HAS_EEPROM 0x00000400
-
-#define FLASH_CMD_READ_ARRAY 0xFF
-#define FLASH_CMD_READ_ID 0x90
-#define FLASH_SER_OFF 0x102 /* 0x81 in 16-bit mode */
-
-static u32 hw_bits = 0xFFFFFFFD; /* assume all hardware present */;
-static u8 control_value;
-
-/*
- * FIXME: this is reimplementing I2C bit-bangining. Move this
- * over to using driver/i2c/busses/i2c-gpio.c like all other boards
- * and register proper I2C device(s) on the bus for this. (See
- * other IXP4xx boards for examples.)
- */
-static void set_scl(u8 value)
-{
- gpio_set_value(GPIO_SCL, !!value);
- udelay(3);
-}
-
-static void set_sda(u8 value)
-{
- gpio_set_value(GPIO_SDA, !!value);
- udelay(3);
-}
-
-static void set_str(u8 value)
-{
- gpio_set_value(GPIO_STR, !!value);
- udelay(3);
-}
-
-static inline void set_control(int line, int value)
-{
- if (value)
- control_value |= (1 << line);
- else
- control_value &= ~(1 << line);
-}
-
-
-static void output_control(void)
-{
- int i;
-
- gpio_direction_output(GPIO_SCL, 1);
- gpio_direction_output(GPIO_SDA, 1);
-
- for (i = 0; i < 8; i++) {
- set_scl(0);
- set_sda(control_value & (0x80 >> i)); /* MSB first */
- set_scl(1); /* active edge */
- }
-
- set_str(1);
- set_str(0);
-
- set_scl(0);
- set_sda(1); /* Be ready for START */
- set_scl(1);
-}
-
-
-static void (*set_carrier_cb_tab[2])(void *pdev, int carrier);
-
-static int hss_set_clock(int port, unsigned int clock_type)
-{
- int ctrl_int = port ? CONTROL_HSS1_CLK_INT : CONTROL_HSS0_CLK_INT;
-
- switch (clock_type) {
- case CLOCK_DEFAULT:
- case CLOCK_EXT:
- set_control(ctrl_int, 0);
- output_control();
- return CLOCK_EXT;
-
- case CLOCK_INT:
- set_control(ctrl_int, 1);
- output_control();
- return CLOCK_INT;
-
- default:
- return -EINVAL;
- }
-}
-
-static irqreturn_t hss_dcd_irq(int irq, void *pdev)
-{
- int port = (irq == IXP4XX_GPIO_IRQ(GPIO_HSS1_DCD_N));
- int i = gpio_get_value(port ? GPIO_HSS1_DCD_N : GPIO_HSS0_DCD_N);
- set_carrier_cb_tab[port](pdev, !i);
- return IRQ_HANDLED;
-}
-
-
-static int hss_open(int port, void *pdev,
- void (*set_carrier_cb)(void *pdev, int carrier))
-{
- int i, irq;
-
- if (!port)
- irq = IXP4XX_GPIO_IRQ(GPIO_HSS0_DCD_N);
- else
- irq = IXP4XX_GPIO_IRQ(GPIO_HSS1_DCD_N);
-
- i = gpio_get_value(port ? GPIO_HSS1_DCD_N : GPIO_HSS0_DCD_N);
- set_carrier_cb(pdev, !i);
-
- set_carrier_cb_tab[!!port] = set_carrier_cb;
-
- if ((i = request_irq(irq, hss_dcd_irq, 0, "IXP4xx HSS", pdev)) != 0) {
- printk(KERN_ERR "ixp4xx_hss: failed to request IRQ%i (%i)\n",
- irq, i);
- return i;
- }
-
- set_control(port ? CONTROL_HSS1_DTR_N : CONTROL_HSS0_DTR_N, 0);
- output_control();
- gpio_set_value(port ? GPIO_HSS1_RTS_N : GPIO_HSS0_RTS_N, 0);
- return 0;
-}
-
-static void hss_close(int port, void *pdev)
-{
- free_irq(port ? IXP4XX_GPIO_IRQ(GPIO_HSS1_DCD_N) :
- IXP4XX_GPIO_IRQ(GPIO_HSS0_DCD_N), pdev);
- set_carrier_cb_tab[!!port] = NULL; /* catch bugs */
-
- set_control(port ? CONTROL_HSS1_DTR_N : CONTROL_HSS0_DTR_N, 1);
- output_control();
- gpio_set_value(port ? GPIO_HSS1_RTS_N : GPIO_HSS0_RTS_N, 1);
-}
-
-
-/* Flash memory */
-static struct flash_platform_data flash_data = {
- .map_name = "cfi_probe",
- .width = 2,
-};
-
-static struct resource flash_resource = {
- .flags = IORESOURCE_MEM,
-};
-
-static struct platform_device device_flash = {
- .name = "IXP4XX-Flash",
- .id = 0,
- .dev = { .platform_data = &flash_data },
- .num_resources = 1,
- .resource = &flash_resource,
-};
-
-/* IXP425 2 UART ports */
-static struct resource uart_resources[] = {
- {
- .start = IXP4XX_UART1_BASE_PHYS,
- .end = IXP4XX_UART1_BASE_PHYS + 0x0fff,
- .flags = IORESOURCE_MEM,
- },
- {
- .start = IXP4XX_UART2_BASE_PHYS,
- .end = IXP4XX_UART2_BASE_PHYS + 0x0fff,
- .flags = IORESOURCE_MEM,
- }
-};
-
-static struct plat_serial8250_port uart_data[] = {
- {
- .mapbase = IXP4XX_UART1_BASE_PHYS,
- .membase = (char __iomem *)IXP4XX_UART1_BASE_VIRT +
- REG_OFFSET,
- .irq = IRQ_IXP4XX_UART1,
- .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
- .iotype = UPIO_MEM,
- .regshift = 2,
- .uartclk = IXP4XX_UART_XTAL,
- },
- {
- .mapbase = IXP4XX_UART2_BASE_PHYS,
- .membase = (char __iomem *)IXP4XX_UART2_BASE_VIRT +
- REG_OFFSET,
- .irq = IRQ_IXP4XX_UART2,
- .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
- .iotype = UPIO_MEM,
- .regshift = 2,
- .uartclk = IXP4XX_UART_XTAL,
- },
- { },
-};
-
-static struct platform_device device_uarts = {
- .name = "serial8250",
- .id = PLAT8250_DEV_PLATFORM,
- .dev.platform_data = uart_data,
- .num_resources = 2,
- .resource = uart_resources,
-};
-
-
-/* Built-in 10/100 Ethernet MAC interfaces */
-static struct resource eth_npeb_resources[] = {
- {
- .start = IXP4XX_EthB_BASE_PHYS,
- .end = IXP4XX_EthB_BASE_PHYS + 0x0fff,
- .flags = IORESOURCE_MEM,
- },
-};
-
-static struct resource eth_npec_resources[] = {
- {
- .start = IXP4XX_EthC_BASE_PHYS,
- .end = IXP4XX_EthC_BASE_PHYS + 0x0fff,
- .flags = IORESOURCE_MEM,
- },
-};
-
-static struct eth_plat_info eth_plat[] = {
- {
- .phy = 0,
- .rxq = 3,
- .txreadyq = 32,
- }, {
- .phy = 1,
- .rxq = 4,
- .txreadyq = 33,
- }
-};
-
-static struct platform_device device_eth_tab[] = {
- {
- .name = "ixp4xx_eth",
- .id = IXP4XX_ETH_NPEB,
- .dev.platform_data = eth_plat,
- .num_resources = ARRAY_SIZE(eth_npeb_resources),
- .resource = eth_npeb_resources,
- }, {
- .name = "ixp4xx_eth",
- .id = IXP4XX_ETH_NPEC,
- .dev.platform_data = eth_plat + 1,
- .num_resources = ARRAY_SIZE(eth_npec_resources),
- .resource = eth_npec_resources,
- }
-};
-
-
-/* IXP425 2 synchronous serial ports */
-static struct hss_plat_info hss_plat[] = {
- {
- .set_clock = hss_set_clock,
- .open = hss_open,
- .close = hss_close,
- .txreadyq = 34,
- }, {
- .set_clock = hss_set_clock,
- .open = hss_open,
- .close = hss_close,
- .txreadyq = 35,
- }
-};
-
-static struct platform_device device_hss_tab[] = {
- {
- .name = "ixp4xx_hss",
- .id = 0,
- .dev.platform_data = hss_plat,
- }, {
- .name = "ixp4xx_hss",
- .id = 1,
- .dev.platform_data = hss_plat + 1,
- }
-};
-
-
-static struct platform_device *device_tab[7] __initdata = {
- &device_flash, /* index 0 */
-};
-
-static inline u8 __init flash_readb(u8 __iomem *flash, u32 addr)
-{
-#ifdef __ARMEB__
- return __raw_readb(flash + addr);
-#else
- return __raw_readb(flash + (addr ^ 3));
-#endif
-}
-
-static inline u16 __init flash_readw(u8 __iomem *flash, u32 addr)
-{
-#ifdef __ARMEB__
- return __raw_readw(flash + addr);
-#else
- return __raw_readw(flash + (addr ^ 2));
-#endif
-}
-
-static void __init gmlr_init(void)
-{
- u8 __iomem *flash;
- int i, devices = 1; /* flash */
-
- ixp4xx_sys_init();
-
- if ((flash = ioremap(IXP4XX_EXP_BUS_BASE_PHYS, 0x80)) == NULL)
- printk(KERN_ERR "goramo-mlr: unable to access system"
- " configuration data\n");
- else {
- system_rev = __raw_readl(flash + CFG_REV);
- hw_bits = __raw_readl(flash + CFG_HW_BITS);
-
- for (i = 0; i < ETH_ALEN; i++) {
- eth_plat[0].hwaddr[i] =
- flash_readb(flash, CFG_ETH0_ADDRESS + i);
- eth_plat[1].hwaddr[i] =
- flash_readb(flash, CFG_ETH1_ADDRESS + i);
- }
-
- __raw_writew(FLASH_CMD_READ_ID, flash);
- system_serial_high = flash_readw(flash, FLASH_SER_OFF);
- system_serial_high <<= 16;
- system_serial_high |= flash_readw(flash, FLASH_SER_OFF + 2);
- system_serial_low = flash_readw(flash, FLASH_SER_OFF + 4);
- system_serial_low <<= 16;
- system_serial_low |= flash_readw(flash, FLASH_SER_OFF + 6);
- __raw_writew(FLASH_CMD_READ_ARRAY, flash);
-
- iounmap(flash);
- }
-
- switch (hw_bits & (CFG_HW_HAS_UART0 | CFG_HW_HAS_UART1)) {
- case CFG_HW_HAS_UART0:
- memset(&uart_data[1], 0, sizeof(uart_data[1]));
- device_uarts.num_resources = 1;
- break;
-
- case CFG_HW_HAS_UART1:
- device_uarts.dev.platform_data = &uart_data[1];
- device_uarts.resource = &uart_resources[1];
- device_uarts.num_resources = 1;
- break;
- }
- if (hw_bits & (CFG_HW_HAS_UART0 | CFG_HW_HAS_UART1))
- device_tab[devices++] = &device_uarts; /* max index 1 */
-
- if (hw_bits & CFG_HW_HAS_ETH0)
- device_tab[devices++] = &device_eth_tab[0]; /* max index 2 */
- if (hw_bits & CFG_HW_HAS_ETH1)
- device_tab[devices++] = &device_eth_tab[1]; /* max index 3 */
-
- if (hw_bits & CFG_HW_HAS_HSS0)
- device_tab[devices++] = &device_hss_tab[0]; /* max index 4 */
- if (hw_bits & CFG_HW_HAS_HSS1)
- device_tab[devices++] = &device_hss_tab[1]; /* max index 5 */
-
- hss_plat[0].timer_freq = ixp4xx_timer_freq;
- hss_plat[1].timer_freq = ixp4xx_timer_freq;
-
- gpio_request(GPIO_SCL, "SCL/clock");
- gpio_request(GPIO_SDA, "SDA/data");
- gpio_request(GPIO_STR, "strobe");
- gpio_request(GPIO_HSS0_RTS_N, "HSS0 RTS");
- gpio_request(GPIO_HSS1_RTS_N, "HSS1 RTS");
- gpio_request(GPIO_HSS0_DCD_N, "HSS0 DCD");
- gpio_request(GPIO_HSS1_DCD_N, "HSS1 DCD");
-
- gpio_direction_output(GPIO_SCL, 1);
- gpio_direction_output(GPIO_SDA, 1);
- gpio_direction_output(GPIO_STR, 0);
- gpio_direction_output(GPIO_HSS0_RTS_N, 1);
- gpio_direction_output(GPIO_HSS1_RTS_N, 1);
- gpio_direction_input(GPIO_HSS0_DCD_N);
- gpio_direction_input(GPIO_HSS1_DCD_N);
- irq_set_irq_type(IXP4XX_GPIO_IRQ(GPIO_HSS0_DCD_N), IRQ_TYPE_EDGE_BOTH);
- irq_set_irq_type(IXP4XX_GPIO_IRQ(GPIO_HSS1_DCD_N), IRQ_TYPE_EDGE_BOTH);
-
- set_control(CONTROL_HSS0_DTR_N, 1);
- set_control(CONTROL_HSS1_DTR_N, 1);
- set_control(CONTROL_EEPROM_WC_N, 1);
- set_control(CONTROL_PCI_RESET_N, 1);
- output_control();
-
- msleep(1); /* Wait for PCI devices to initialize */
-
- flash_resource.start = IXP4XX_EXP_BUS_BASE(0);
- flash_resource.end = IXP4XX_EXP_BUS_BASE(0) + ixp4xx_exp_bus_size - 1;
-
- platform_add_devices(device_tab, devices);
-}
-
-
-#ifdef CONFIG_PCI
-static void __init gmlr_pci_preinit(void)
-{
- irq_set_irq_type(IXP4XX_GPIO_IRQ(GPIO_IRQ_ETHA), IRQ_TYPE_LEVEL_LOW);
- irq_set_irq_type(IXP4XX_GPIO_IRQ(GPIO_IRQ_ETHB), IRQ_TYPE_LEVEL_LOW);
- irq_set_irq_type(IXP4XX_GPIO_IRQ(GPIO_IRQ_NEC), IRQ_TYPE_LEVEL_LOW);
- irq_set_irq_type(IXP4XX_GPIO_IRQ(GPIO_IRQ_MPCI), IRQ_TYPE_LEVEL_LOW);
- ixp4xx_pci_preinit();
-}
-
-static void __init gmlr_pci_postinit(void)
-{
- if ((hw_bits & CFG_HW_USB_PORTS) >= 2 &&
- (hw_bits & CFG_HW_USB_PORTS) < 5) {
- /* need to adjust number of USB ports on NEC chip */
- u32 value, addr = BIT(32 - SLOT_NEC) | 0xE0;
- if (!ixp4xx_pci_read(addr, NP_CMD_CONFIGREAD, &value)) {
- value &= ~7;
- value |= (hw_bits & CFG_HW_USB_PORTS);
- ixp4xx_pci_write(addr, NP_CMD_CONFIGWRITE, value);
- }
- }
-}
-
-static int __init gmlr_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
-{
- switch(slot) {
- case SLOT_ETHA: return IXP4XX_GPIO_IRQ(GPIO_IRQ_ETHA);
- case SLOT_ETHB: return IXP4XX_GPIO_IRQ(GPIO_IRQ_ETHB);
- case SLOT_NEC: return IXP4XX_GPIO_IRQ(GPIO_IRQ_NEC);
- default: return IXP4XX_GPIO_IRQ(GPIO_IRQ_MPCI);
- }
-}
-
-static struct hw_pci gmlr_hw_pci __initdata = {
- .nr_controllers = 1,
- .ops = &ixp4xx_ops,
- .preinit = gmlr_pci_preinit,
- .postinit = gmlr_pci_postinit,
- .setup = ixp4xx_setup,
- .map_irq = gmlr_map_irq,
-};
-
-static int __init gmlr_pci_init(void)
-{
- if (machine_is_goramo_mlr() &&
- (hw_bits & (CFG_HW_USB_PORTS | CFG_HW_HAS_PCI_SLOT)))
- pci_common_init(&gmlr_hw_pci);
- return 0;
-}
-
-subsys_initcall(gmlr_pci_init);
-#endif /* CONFIG_PCI */
-
-
-MACHINE_START(GORAMO_MLR, "MultiLink")
- /* Maintainer: Krzysztof Halasa */
- .map_io = ixp4xx_map_io,
- .init_early = ixp4xx_init_early,
- .init_irq = ixp4xx_init_irq,
- .init_time = ixp4xx_timer_init,
- .atag_offset = 0x100,
- .init_machine = gmlr_init,
-#if defined(CONFIG_PCI)
- .dma_zone_size = SZ_64M,
-#endif
- .restart = ixp4xx_restart,
-MACHINE_END
diff --git a/arch/arm/mach-ixp4xx/include/mach/hardware.h b/arch/arm/mach-ixp4xx/include/mach/hardware.h
deleted file mode 100644
index b2b7301ce503..000000000000
--- a/arch/arm/mach-ixp4xx/include/mach/hardware.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * arch/arm/mach-ixp4xx/include/mach/hardware.h
- *
- * Copyright (C) 2002 Intel Corporation.
- * Copyright (C) 2003-2004 MontaVista Software, Inc.
- */
-
-/*
- * Hardware definitions for IXP4xx based systems
- */
-
-#ifndef __ASM_ARCH_HARDWARE_H__
-#define __ASM_ARCH_HARDWARE_H__
-
-#ifdef CONFIG_IXP4XX_INDIRECT_PCI
-#define PCIBIOS_MAX_MEM 0x4FFFFFFF
-#else
-#define PCIBIOS_MAX_MEM 0x4BFFFFFF
-#endif
-
-/* Register locations and bits */
-#include "ixp4xx-regs.h"
-
-#ifndef __ASSEMBLER__
-#include <linux/soc/ixp4xx/cpu.h>
-#endif
-
-/* Platform helper functions and definitions */
-#include "platform.h"
-
-#endif /* _ASM_ARCH_HARDWARE_H */
diff --git a/arch/arm/mach-ixp4xx/include/mach/io.h b/arch/arm/mach-ixp4xx/include/mach/io.h
deleted file mode 100644
index 014cf6dcaf8b..000000000000
--- a/arch/arm/mach-ixp4xx/include/mach/io.h
+++ /dev/null
@@ -1,545 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * arch/arm/mach-ixp4xx/include/mach/io.h
- *
- * Author: Deepak Saxena <dsaxena@plexity.net>
- *
- * Copyright (C) 2002-2005 MontaVista Software, Inc.
- */
-
-#ifndef __ASM_ARM_ARCH_IO_H
-#define __ASM_ARM_ARCH_IO_H
-
-#include <linux/bitops.h>
-
-#include <mach/hardware.h>
-
-extern int (*ixp4xx_pci_read)(u32 addr, u32 cmd, u32* data);
-extern int ixp4xx_pci_write(u32 addr, u32 cmd, u32 data);
-
-
-/*
- * IXP4xx provides two methods of accessing PCI memory space:
- *
- * 1) A direct mapped window from 0x48000000 to 0x4BFFFFFF (64MB).
- * To access PCI via this space, we simply ioremap() the BAR
- * into the kernel and we can use the standard read[bwl]/write[bwl]
- * macros. This is the preffered method due to speed but it
- * limits the system to just 64MB of PCI memory. This can be
- * problematic if using video cards and other memory-heavy targets.
- *
- * 2) If > 64MB of memory space is required, the IXP4xx can use indirect
- * registers to access the whole 4 GB of PCI memory space (as we do below
- * for I/O transactions). This allows currently for up to 1 GB (0x10000000
- * to 0x4FFFFFFF) of memory on the bus. The disadvantage of this is that
- * every PCI access requires three local register accesses plus a spinlock,
- * but in some cases the performance hit is acceptable. In addition, you
- * cannot mmap() PCI devices in this case.
- */
-#ifdef CONFIG_IXP4XX_INDIRECT_PCI
-
-/*
- * In the case of using indirect PCI, we simply return the actual PCI
- * address and our read/write implementation use that to drive the
- * access registers. If something outside of PCI is ioremap'd, we
- * fallback to the default.
- */
-
-extern unsigned long pcibios_min_mem;
-static inline int is_pci_memory(u32 addr)
-{
- return (addr >= pcibios_min_mem) && (addr <= 0x4FFFFFFF);
-}
-
-#define writeb(v, p) __indirect_writeb(v, p)
-#define writew(v, p) __indirect_writew(v, p)
-#define writel(v, p) __indirect_writel(v, p)
-
-#define writeb_relaxed(v, p) __indirect_writeb(v, p)
-#define writew_relaxed(v, p) __indirect_writew(v, p)
-#define writel_relaxed(v, p) __indirect_writel(v, p)
-
-#define writesb(p, v, l) __indirect_writesb(p, v, l)
-#define writesw(p, v, l) __indirect_writesw(p, v, l)
-#define writesl(p, v, l) __indirect_writesl(p, v, l)
-
-#define readb(p) __indirect_readb(p)
-#define readw(p) __indirect_readw(p)
-#define readl(p) __indirect_readl(p)
-
-#define readb_relaxed(p) __indirect_readb(p)
-#define readw_relaxed(p) __indirect_readw(p)
-#define readl_relaxed(p) __indirect_readl(p)
-
-#define readsb(p, v, l) __indirect_readsb(p, v, l)
-#define readsw(p, v, l) __indirect_readsw(p, v, l)
-#define readsl(p, v, l) __indirect_readsl(p, v, l)
-
-static inline void __indirect_writeb(u8 value, volatile void __iomem *p)
-{
- u32 addr = (u32)p;
- u32 n, byte_enables, data;
-
- if (!is_pci_memory(addr)) {
- __raw_writeb(value, p);
- return;
- }
-
- n = addr % 4;
- byte_enables = (0xf & ~BIT(n)) << IXP4XX_PCI_NP_CBE_BESL;
- data = value << (8*n);
- ixp4xx_pci_write(addr, byte_enables | NP_CMD_MEMWRITE, data);
-}
-
-static inline void __indirect_writesb(volatile void __iomem *bus_addr,
- const void *p, int count)
-{
- const u8 *vaddr = p;
-
- while (count--)
- writeb(*vaddr++, bus_addr);
-}
-
-static inline void __indirect_writew(u16 value, volatile void __iomem *p)
-{
- u32 addr = (u32)p;
- u32 n, byte_enables, data;
-
- if (!is_pci_memory(addr)) {
- __raw_writew(value, p);
- return;
- }
-
- n = addr % 4;
- byte_enables = (0xf & ~(BIT(n) | BIT(n+1))) << IXP4XX_PCI_NP_CBE_BESL;
- data = value << (8*n);
- ixp4xx_pci_write(addr, byte_enables | NP_CMD_MEMWRITE, data);
-}
-
-static inline void __indirect_writesw(volatile void __iomem *bus_addr,
- const void *p, int count)
-{
- const u16 *vaddr = p;
-
- while (count--)
- writew(*vaddr++, bus_addr);
-}
-
-static inline void __indirect_writel(u32 value, volatile void __iomem *p)
-{
- u32 addr = (__force u32)p;
-
- if (!is_pci_memory(addr)) {
- __raw_writel(value, p);
- return;
- }
-
- ixp4xx_pci_write(addr, NP_CMD_MEMWRITE, value);
-}
-
-static inline void __indirect_writesl(volatile void __iomem *bus_addr,
- const void *p, int count)
-{
- const u32 *vaddr = p;
- while (count--)
- writel(*vaddr++, bus_addr);
-}
-
-static inline u8 __indirect_readb(const volatile void __iomem *p)
-{
- u32 addr = (u32)p;
- u32 n, byte_enables, data;
-
- if (!is_pci_memory(addr))
- return __raw_readb(p);
-
- n = addr % 4;
- byte_enables = (0xf & ~BIT(n)) << IXP4XX_PCI_NP_CBE_BESL;
- if (ixp4xx_pci_read(addr, byte_enables | NP_CMD_MEMREAD, &data))
- return 0xff;
-
- return data >> (8*n);
-}
-
-static inline void __indirect_readsb(const volatile void __iomem *bus_addr,
- void *p, u32 count)
-{
- u8 *vaddr = p;
-
- while (count--)
- *vaddr++ = readb(bus_addr);
-}
-
-static inline u16 __indirect_readw(const volatile void __iomem *p)
-{
- u32 addr = (u32)p;
- u32 n, byte_enables, data;
-
- if (!is_pci_memory(addr))
- return __raw_readw(p);
-
- n = addr % 4;
- byte_enables = (0xf & ~(BIT(n) | BIT(n+1))) << IXP4XX_PCI_NP_CBE_BESL;
- if (ixp4xx_pci_read(addr, byte_enables | NP_CMD_MEMREAD, &data))
- return 0xffff;
-
- return data>>(8*n);
-}
-
-static inline void __indirect_readsw(const volatile void __iomem *bus_addr,
- void *p, u32 count)
-{
- u16 *vaddr = p;
-
- while (count--)
- *vaddr++ = readw(bus_addr);
-}
-
-static inline u32 __indirect_readl(const volatile void __iomem *p)
-{
- u32 addr = (__force u32)p;
- u32 data;
-
- if (!is_pci_memory(addr))
- return __raw_readl(p);
-
- if (ixp4xx_pci_read(addr, NP_CMD_MEMREAD, &data))
- return 0xffffffff;
-
- return data;
-}
-
-static inline void __indirect_readsl(const volatile void __iomem *bus_addr,
- void *p, u32 count)
-{
- u32 *vaddr = p;
-
- while (count--)
- *vaddr++ = readl(bus_addr);
-}
-
-
-/*
- * We can use the built-in functions b/c they end up calling writeb/readb
- */
-#define memset_io(c,v,l) _memset_io((c),(v),(l))
-#define memcpy_fromio(a,c,l) _memcpy_fromio((a),(c),(l))
-#define memcpy_toio(c,a,l) _memcpy_toio((c),(a),(l))
-
-#endif /* CONFIG_IXP4XX_INDIRECT_PCI */
-
-#ifndef CONFIG_PCI
-
-#define __io(v) __typesafe_io(v)
-
-#else
-
-/*
- * IXP4xx does not have a transparent cpu -> PCI I/O translation
- * window. Instead, it has a set of registers that must be tweaked
- * with the proper byte lanes, command types, and address for the
- * transaction. This means that we need to override the default
- * I/O functions.
- */
-
-#define outb outb
-static inline void outb(u8 value, u32 addr)
-{
- u32 n, byte_enables, data;
- n = addr % 4;
- byte_enables = (0xf & ~BIT(n)) << IXP4XX_PCI_NP_CBE_BESL;
- data = value << (8*n);
- ixp4xx_pci_write(addr, byte_enables | NP_CMD_IOWRITE, data);
-}
-
-#define outsb outsb
-static inline void outsb(u32 io_addr, const void *p, u32 count)
-{
- const u8 *vaddr = p;
-
- while (count--)
- outb(*vaddr++, io_addr);
-}
-
-#define outw outw
-static inline void outw(u16 value, u32 addr)
-{
- u32 n, byte_enables, data;
- n = addr % 4;
- byte_enables = (0xf & ~(BIT(n) | BIT(n+1))) << IXP4XX_PCI_NP_CBE_BESL;
- data = value << (8*n);
- ixp4xx_pci_write(addr, byte_enables | NP_CMD_IOWRITE, data);
-}
-
-#define outsw outsw
-static inline void outsw(u32 io_addr, const void *p, u32 count)
-{
- const u16 *vaddr = p;
- while (count--)
- outw(cpu_to_le16(*vaddr++), io_addr);
-}
-
-#define outl outl
-static inline void outl(u32 value, u32 addr)
-{
- ixp4xx_pci_write(addr, NP_CMD_IOWRITE, value);
-}
-
-#define outsl outsl
-static inline void outsl(u32 io_addr, const void *p, u32 count)
-{
- const u32 *vaddr = p;
- while (count--)
- outl(cpu_to_le32(*vaddr++), io_addr);
-}
-
-#define inb inb
-static inline u8 inb(u32 addr)
-{
- u32 n, byte_enables, data;
- n = addr % 4;
- byte_enables = (0xf & ~BIT(n)) << IXP4XX_PCI_NP_CBE_BESL;
- if (ixp4xx_pci_read(addr, byte_enables | NP_CMD_IOREAD, &data))
- return 0xff;
-
- return data >> (8*n);
-}
-
-#define insb insb
-static inline void insb(u32 io_addr, void *p, u32 count)
-{
- u8 *vaddr = p;
- while (count--)
- *vaddr++ = inb(io_addr);
-}
-
-#define inw inw
-static inline u16 inw(u32 addr)
-{
- u32 n, byte_enables, data;
- n = addr % 4;
- byte_enables = (0xf & ~(BIT(n) | BIT(n+1))) << IXP4XX_PCI_NP_CBE_BESL;
- if (ixp4xx_pci_read(addr, byte_enables | NP_CMD_IOREAD, &data))
- return 0xffff;
-
- return data>>(8*n);
-}
-
-#define insw insw
-static inline void insw(u32 io_addr, void *p, u32 count)
-{
- u16 *vaddr = p;
- while (count--)
- *vaddr++ = le16_to_cpu(inw(io_addr));
-}
-
-#define inl inl
-static inline u32 inl(u32 addr)
-{
- u32 data;
- if (ixp4xx_pci_read(addr, NP_CMD_IOREAD, &data))
- return 0xffffffff;
-
- return data;
-}
-
-#define insl insl
-static inline void insl(u32 io_addr, void *p, u32 count)
-{
- u32 *vaddr = p;
- while (count--)
- *vaddr++ = le32_to_cpu(inl(io_addr));
-}
-
-#define PIO_OFFSET 0x10000UL
-#define PIO_MASK 0x0ffffUL
-
-#define __is_io_address(p) (((unsigned long)p >= PIO_OFFSET) && \
- ((unsigned long)p <= (PIO_MASK + PIO_OFFSET)))
-
-#define ioread8(p) ioread8(p)
-static inline u8 ioread8(const void __iomem *addr)
-{
- unsigned long port = (unsigned long __force)addr;
- if (__is_io_address(port))
- return (unsigned int)inb(port & PIO_MASK);
- else
-#ifndef CONFIG_IXP4XX_INDIRECT_PCI
- return (unsigned int)__raw_readb(addr);
-#else
- return (unsigned int)__indirect_readb(addr);
-#endif
-}
-
-#define ioread8_rep(p, v, c) ioread8_rep(p, v, c)
-static inline void ioread8_rep(const void __iomem *addr, void *vaddr, u32 count)
-{
- unsigned long port = (unsigned long __force)addr;
- if (__is_io_address(port))
- insb(port & PIO_MASK, vaddr, count);
- else
-#ifndef CONFIG_IXP4XX_INDIRECT_PCI
- __raw_readsb(addr, vaddr, count);
-#else
- __indirect_readsb(addr, vaddr, count);
-#endif
-}
-
-#define ioread16(p) ioread16(p)
-static inline u16 ioread16(const void __iomem *addr)
-{
- unsigned long port = (unsigned long __force)addr;
- if (__is_io_address(port))
- return (unsigned int)inw(port & PIO_MASK);
- else
-#ifndef CONFIG_IXP4XX_INDIRECT_PCI
- return le16_to_cpu((__force __le16)__raw_readw(addr));
-#else
- return (unsigned int)__indirect_readw(addr);
-#endif
-}
-
-#define ioread16_rep(p, v, c) ioread16_rep(p, v, c)
-static inline void ioread16_rep(const void __iomem *addr, void *vaddr,
- u32 count)
-{
- unsigned long port = (unsigned long __force)addr;
- if (__is_io_address(port))
- insw(port & PIO_MASK, vaddr, count);
- else
-#ifndef CONFIG_IXP4XX_INDIRECT_PCI
- __raw_readsw(addr, vaddr, count);
-#else
- __indirect_readsw(addr, vaddr, count);
-#endif
-}
-
-#define ioread32(p) ioread32(p)
-static inline u32 ioread32(const void __iomem *addr)
-{
- unsigned long port = (unsigned long __force)addr;
- if (__is_io_address(port))
- return (unsigned int)inl(port & PIO_MASK);
- else {
-#ifndef CONFIG_IXP4XX_INDIRECT_PCI
- return le32_to_cpu((__force __le32)__raw_readl(addr));
-#else
- return (unsigned int)__indirect_readl(addr);
-#endif
- }
-}
-
-#define ioread32_rep(p, v, c) ioread32_rep(p, v, c)
-static inline void ioread32_rep(const void __iomem *addr, void *vaddr,
- u32 count)
-{
- unsigned long port = (unsigned long __force)addr;
- if (__is_io_address(port))
- insl(port & PIO_MASK, vaddr, count);
- else
-#ifndef CONFIG_IXP4XX_INDIRECT_PCI
- __raw_readsl(addr, vaddr, count);
-#else
- __indirect_readsl(addr, vaddr, count);
-#endif
-}
-
-#define iowrite8(v, p) iowrite8(v, p)
-static inline void iowrite8(u8 value, void __iomem *addr)
-{
- unsigned long port = (unsigned long __force)addr;
- if (__is_io_address(port))
- outb(value, port & PIO_MASK);
- else
-#ifndef CONFIG_IXP4XX_INDIRECT_PCI
- __raw_writeb(value, addr);
-#else
- __indirect_writeb(value, addr);
-#endif
-}
-
-#define iowrite8_rep(p, v, c) iowrite8_rep(p, v, c)
-static inline void iowrite8_rep(void __iomem *addr, const void *vaddr,
- u32 count)
-{
- unsigned long port = (unsigned long __force)addr;
- if (__is_io_address(port))
- outsb(port & PIO_MASK, vaddr, count);
- else
-#ifndef CONFIG_IXP4XX_INDIRECT_PCI
- __raw_writesb(addr, vaddr, count);
-#else
- __indirect_writesb(addr, vaddr, count);
-#endif
-}
-
-#define iowrite16(v, p) iowrite16(v, p)
-static inline void iowrite16(u16 value, void __iomem *addr)
-{
- unsigned long port = (unsigned long __force)addr;
- if (__is_io_address(port))
- outw(value, port & PIO_MASK);
- else
-#ifndef CONFIG_IXP4XX_INDIRECT_PCI
- __raw_writew(cpu_to_le16(value), addr);
-#else
- __indirect_writew(value, addr);
-#endif
-}
-
-#define iowrite16_rep(p, v, c) iowrite16_rep(p, v, c)
-static inline void iowrite16_rep(void __iomem *addr, const void *vaddr,
- u32 count)
-{
- unsigned long port = (unsigned long __force)addr;
- if (__is_io_address(port))
- outsw(port & PIO_MASK, vaddr, count);
- else
-#ifndef CONFIG_IXP4XX_INDIRECT_PCI
- __raw_writesw(addr, vaddr, count);
-#else
- __indirect_writesw(addr, vaddr, count);
-#endif
-}
-
-#define iowrite32(v, p) iowrite32(v, p)
-static inline void iowrite32(u32 value, void __iomem *addr)
-{
- unsigned long port = (unsigned long __force)addr;
- if (__is_io_address(port))
- outl(value, port & PIO_MASK);
- else
-#ifndef CONFIG_IXP4XX_INDIRECT_PCI
- __raw_writel((u32 __force)cpu_to_le32(value), addr);
-#else
- __indirect_writel(value, addr);
-#endif
-}
-
-#define iowrite32_rep(p, v, c) iowrite32_rep(p, v, c)
-static inline void iowrite32_rep(void __iomem *addr, const void *vaddr,
- u32 count)
-{
- unsigned long port = (unsigned long __force)addr;
- if (__is_io_address(port))
- outsl(port & PIO_MASK, vaddr, count);
- else
-#ifndef CONFIG_IXP4XX_INDIRECT_PCI
- __raw_writesl(addr, vaddr, count);
-#else
- __indirect_writesl(addr, vaddr, count);
-#endif
-}
-
-#define ioport_map(port, nr) ioport_map(port, nr)
-static inline void __iomem *ioport_map(unsigned long port, unsigned int nr)
-{
- return ((void __iomem*)((port) + PIO_OFFSET));
-}
-#define ioport_unmap(addr) ioport_unmap(addr)
-static inline void ioport_unmap(void __iomem *addr)
-{
-}
-#endif /* CONFIG_PCI */
-
-#endif /* __ASM_ARM_ARCH_IO_H */
diff --git a/arch/arm/mach-ixp4xx/include/mach/ixp4xx-regs.h b/arch/arm/mach-ixp4xx/include/mach/ixp4xx-regs.h
deleted file mode 100644
index 74e63d4531aa..000000000000
--- a/arch/arm/mach-ixp4xx/include/mach/ixp4xx-regs.h
+++ /dev/null
@@ -1,303 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * arch/arm/mach-ixp4xx/include/mach/ixp4xx-regs.h
- *
- * Register definitions for IXP4xx chipset. This file contains
- * register location and bit definitions only. Platform specific
- * definitions and helper function declarations are in platform.h
- * and machine-name.h.
- *
- * Copyright (C) 2002 Intel Corporation.
- * Copyright (C) 2003-2004 MontaVista Software, Inc.
- */
-
-#ifndef _ASM_ARM_IXP4XX_H_
-#define _ASM_ARM_IXP4XX_H_
-
-/*
- * IXP4xx Linux Memory Map:
- *
- * Phy Size Virt Description
- * =========================================================================
- *
- * 0x00000000 0x10000000(max) PAGE_OFFSET System RAM
- *
- * 0x48000000 0x04000000 ioremap'd PCI Memory Space
- *
- * 0x50000000 0x10000000 ioremap'd EXP BUS
- *
- * 0xC8000000 0x00013000 0xFEF00000 On-Chip Peripherals
- *
- * 0xC0000000 0x00001000 0xFEF13000 PCI CFG
- *
- * 0xC4000000 0x00001000 0xFEF14000 EXP CFG
- *
- * 0x60000000 0x00004000 0xFEF15000 QMgr
- */
-
-/*
- * Queue Manager
- */
-#define IXP4XX_QMGR_BASE_PHYS 0x60000000
-
-/*
- * Peripheral space, including debug UART. Must be section-aligned so that
- * it can be used with the low-level debug code.
- */
-#define IXP4XX_PERIPHERAL_BASE_PHYS 0xC8000000
-#define IXP4XX_PERIPHERAL_BASE_VIRT IOMEM(0xFEC00000)
-#define IXP4XX_PERIPHERAL_REGION_SIZE 0x00013000
-
-/*
- * PCI Config registers
- */
-#define IXP4XX_PCI_CFG_BASE_PHYS 0xC0000000
-#define IXP4XX_PCI_CFG_BASE_VIRT IOMEM(0xFEC13000)
-#define IXP4XX_PCI_CFG_REGION_SIZE 0x00001000
-
-/*
- * Expansion BUS Configuration registers
- */
-#define IXP4XX_EXP_CFG_BASE_PHYS 0xC4000000
-#define IXP4XX_EXP_CFG_BASE_VIRT 0xFEC14000
-#define IXP4XX_EXP_CFG_REGION_SIZE 0x00001000
-
-#define IXP4XX_EXP_CS0_OFFSET 0x00
-#define IXP4XX_EXP_CS1_OFFSET 0x04
-#define IXP4XX_EXP_CS2_OFFSET 0x08
-#define IXP4XX_EXP_CS3_OFFSET 0x0C
-#define IXP4XX_EXP_CS4_OFFSET 0x10
-#define IXP4XX_EXP_CS5_OFFSET 0x14
-#define IXP4XX_EXP_CS6_OFFSET 0x18
-#define IXP4XX_EXP_CS7_OFFSET 0x1C
-#define IXP4XX_EXP_CFG0_OFFSET 0x20
-#define IXP4XX_EXP_CFG1_OFFSET 0x24
-#define IXP4XX_EXP_CFG2_OFFSET 0x28
-#define IXP4XX_EXP_CFG3_OFFSET 0x2C
-
-/*
- * Expansion Bus Controller registers.
- */
-#define IXP4XX_EXP_REG(x) ((volatile u32 __iomem *)(IXP4XX_EXP_CFG_BASE_VIRT+(x)))
-
-#define IXP4XX_EXP_CS0 IXP4XX_EXP_REG(IXP4XX_EXP_CS0_OFFSET)
-#define IXP4XX_EXP_CS1 IXP4XX_EXP_REG(IXP4XX_EXP_CS1_OFFSET)
-#define IXP4XX_EXP_CS2 IXP4XX_EXP_REG(IXP4XX_EXP_CS2_OFFSET)
-#define IXP4XX_EXP_CS3 IXP4XX_EXP_REG(IXP4XX_EXP_CS3_OFFSET)
-#define IXP4XX_EXP_CS4 IXP4XX_EXP_REG(IXP4XX_EXP_CS4_OFFSET)
-#define IXP4XX_EXP_CS5 IXP4XX_EXP_REG(IXP4XX_EXP_CS5_OFFSET)
-#define IXP4XX_EXP_CS6 IXP4XX_EXP_REG(IXP4XX_EXP_CS6_OFFSET)
-#define IXP4XX_EXP_CS7 IXP4XX_EXP_REG(IXP4XX_EXP_CS7_OFFSET)
-
-#define IXP4XX_EXP_CFG0 IXP4XX_EXP_REG(IXP4XX_EXP_CFG0_OFFSET)
-#define IXP4XX_EXP_CFG1 IXP4XX_EXP_REG(IXP4XX_EXP_CFG1_OFFSET)
-#define IXP4XX_EXP_CFG2 IXP4XX_EXP_REG(IXP4XX_EXP_CFG2_OFFSET)
-#define IXP4XX_EXP_CFG3 IXP4XX_EXP_REG(IXP4XX_EXP_CFG3_OFFSET)
-
-
-/*
- * Peripheral Space Register Region Base Addresses
- */
-#define IXP4XX_UART1_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0x0000)
-#define IXP4XX_UART2_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0x1000)
-#define IXP4XX_PMU_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0x2000)
-#define IXP4XX_INTC_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0x3000)
-#define IXP4XX_GPIO_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0x4000)
-#define IXP4XX_TIMER_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0x5000)
-#define IXP4XX_NPEA_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0x6000)
-#define IXP4XX_NPEB_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0x7000)
-#define IXP4XX_NPEC_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0x8000)
-#define IXP4XX_EthB_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0x9000)
-#define IXP4XX_EthC_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0xA000)
-#define IXP4XX_USB_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0xB000)
-/* ixp46X only */
-#define IXP4XX_EthA_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0xC000)
-#define IXP4XX_EthB1_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0xD000)
-#define IXP4XX_EthB2_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0xE000)
-#define IXP4XX_EthB3_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0xF000)
-#define IXP4XX_TIMESYNC_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0x10000)
-#define IXP4XX_I2C_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0x11000)
-#define IXP4XX_SSP_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0x12000)
-
-
-/* The UART is explicitly put in the beginning of fixmap */
-#define IXP4XX_UART1_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0x0000)
-#define IXP4XX_UART2_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0x1000)
-#define IXP4XX_PMU_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0x2000)
-#define IXP4XX_INTC_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0x3000)
-#define IXP4XX_GPIO_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0x4000)
-#define IXP4XX_TIMER_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0x5000)
-#define IXP4XX_EthB_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0x9000)
-#define IXP4XX_EthC_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0xA000)
-#define IXP4XX_USB_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0xB000)
-/* ixp46X only */
-#define IXP4XX_EthA_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0xC000)
-#define IXP4XX_EthB1_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0xD000)
-#define IXP4XX_EthB2_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0xE000)
-#define IXP4XX_EthB3_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0xF000)
-#define IXP4XX_TIMESYNC_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0x10000)
-#define IXP4XX_I2C_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0x11000)
-#define IXP4XX_SSP_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0x12000)
-
-/*
- * Constants to make it easy to access Timer Control/Status registers
- */
-#define IXP4XX_OSTS_OFFSET 0x00 /* Continious TimeStamp */
-#define IXP4XX_OST1_OFFSET 0x04 /* Timer 1 Timestamp */
-#define IXP4XX_OSRT1_OFFSET 0x08 /* Timer 1 Reload */
-#define IXP4XX_OST2_OFFSET 0x0C /* Timer 2 Timestamp */
-#define IXP4XX_OSRT2_OFFSET 0x10 /* Timer 2 Reload */
-#define IXP4XX_OSWT_OFFSET 0x14 /* Watchdog Timer */
-#define IXP4XX_OSWE_OFFSET 0x18 /* Watchdog Enable */
-#define IXP4XX_OSWK_OFFSET 0x1C /* Watchdog Key */
-#define IXP4XX_OSST_OFFSET 0x20 /* Timer Status */
-
-/*
- * Operating System Timer Register Definitions.
- */
-
-#define IXP4XX_TIMER_REG(x) ((volatile u32 *)(IXP4XX_TIMER_BASE_VIRT+(x)))
-
-#define IXP4XX_OSTS IXP4XX_TIMER_REG(IXP4XX_OSTS_OFFSET)
-#define IXP4XX_OST1 IXP4XX_TIMER_REG(IXP4XX_OST1_OFFSET)
-#define IXP4XX_OSRT1 IXP4XX_TIMER_REG(IXP4XX_OSRT1_OFFSET)
-#define IXP4XX_OST2 IXP4XX_TIMER_REG(IXP4XX_OST2_OFFSET)
-#define IXP4XX_OSRT2 IXP4XX_TIMER_REG(IXP4XX_OSRT2_OFFSET)
-#define IXP4XX_OSWT IXP4XX_TIMER_REG(IXP4XX_OSWT_OFFSET)
-#define IXP4XX_OSWE IXP4XX_TIMER_REG(IXP4XX_OSWE_OFFSET)
-#define IXP4XX_OSWK IXP4XX_TIMER_REG(IXP4XX_OSWK_OFFSET)
-#define IXP4XX_OSST IXP4XX_TIMER_REG(IXP4XX_OSST_OFFSET)
-
-/*
- * Timer register values and bit definitions
- */
-#define IXP4XX_OST_ENABLE 0x00000001
-#define IXP4XX_OST_ONE_SHOT 0x00000002
-/* Low order bits of reload value ignored */
-#define IXP4XX_OST_RELOAD_MASK 0x00000003
-#define IXP4XX_OST_DISABLED 0x00000000
-#define IXP4XX_OSST_TIMER_1_PEND 0x00000001
-#define IXP4XX_OSST_TIMER_2_PEND 0x00000002
-#define IXP4XX_OSST_TIMER_TS_PEND 0x00000004
-#define IXP4XX_OSST_TIMER_WDOG_PEND 0x00000008
-#define IXP4XX_OSST_TIMER_WARM_RESET 0x00000010
-
-#define IXP4XX_WDT_KEY 0x0000482E
-
-#define IXP4XX_WDT_RESET_ENABLE 0x00000001
-#define IXP4XX_WDT_IRQ_ENABLE 0x00000002
-#define IXP4XX_WDT_COUNT_ENABLE 0x00000004
-
-
-/*
- * Constants to make it easy to access PCI Control/Status registers
- */
-#define PCI_NP_AD_OFFSET 0x00
-#define PCI_NP_CBE_OFFSET 0x04
-#define PCI_NP_WDATA_OFFSET 0x08
-#define PCI_NP_RDATA_OFFSET 0x0c
-#define PCI_CRP_AD_CBE_OFFSET 0x10
-#define PCI_CRP_WDATA_OFFSET 0x14
-#define PCI_CRP_RDATA_OFFSET 0x18
-#define PCI_CSR_OFFSET 0x1c
-#define PCI_ISR_OFFSET 0x20
-#define PCI_INTEN_OFFSET 0x24
-#define PCI_DMACTRL_OFFSET 0x28
-#define PCI_AHBMEMBASE_OFFSET 0x2c
-#define PCI_AHBIOBASE_OFFSET 0x30
-#define PCI_PCIMEMBASE_OFFSET 0x34
-#define PCI_AHBDOORBELL_OFFSET 0x38
-#define PCI_PCIDOORBELL_OFFSET 0x3C
-#define PCI_ATPDMA0_AHBADDR_OFFSET 0x40
-#define PCI_ATPDMA0_PCIADDR_OFFSET 0x44
-#define PCI_ATPDMA0_LENADDR_OFFSET 0x48
-#define PCI_ATPDMA1_AHBADDR_OFFSET 0x4C
-#define PCI_ATPDMA1_PCIADDR_OFFSET 0x50
-#define PCI_ATPDMA1_LENADDR_OFFSET 0x54
-
-/*
- * PCI Control/Status Registers
- */
-#define _IXP4XX_PCI_CSR(x) ((volatile u32 *)(IXP4XX_PCI_CFG_BASE_VIRT+(x)))
-
-#define PCI_NP_AD _IXP4XX_PCI_CSR(PCI_NP_AD_OFFSET)
-#define PCI_NP_CBE _IXP4XX_PCI_CSR(PCI_NP_CBE_OFFSET)
-#define PCI_NP_WDATA _IXP4XX_PCI_CSR(PCI_NP_WDATA_OFFSET)
-#define PCI_NP_RDATA _IXP4XX_PCI_CSR(PCI_NP_RDATA_OFFSET)
-#define PCI_CRP_AD_CBE _IXP4XX_PCI_CSR(PCI_CRP_AD_CBE_OFFSET)
-#define PCI_CRP_WDATA _IXP4XX_PCI_CSR(PCI_CRP_WDATA_OFFSET)
-#define PCI_CRP_RDATA _IXP4XX_PCI_CSR(PCI_CRP_RDATA_OFFSET)
-#define PCI_CSR _IXP4XX_PCI_CSR(PCI_CSR_OFFSET)
-#define PCI_ISR _IXP4XX_PCI_CSR(PCI_ISR_OFFSET)
-#define PCI_INTEN _IXP4XX_PCI_CSR(PCI_INTEN_OFFSET)
-#define PCI_DMACTRL _IXP4XX_PCI_CSR(PCI_DMACTRL_OFFSET)
-#define PCI_AHBMEMBASE _IXP4XX_PCI_CSR(PCI_AHBMEMBASE_OFFSET)
-#define PCI_AHBIOBASE _IXP4XX_PCI_CSR(PCI_AHBIOBASE_OFFSET)
-#define PCI_PCIMEMBASE _IXP4XX_PCI_CSR(PCI_PCIMEMBASE_OFFSET)
-#define PCI_AHBDOORBELL _IXP4XX_PCI_CSR(PCI_AHBDOORBELL_OFFSET)
-#define PCI_PCIDOORBELL _IXP4XX_PCI_CSR(PCI_PCIDOORBELL_OFFSET)
-#define PCI_ATPDMA0_AHBADDR _IXP4XX_PCI_CSR(PCI_ATPDMA0_AHBADDR_OFFSET)
-#define PCI_ATPDMA0_PCIADDR _IXP4XX_PCI_CSR(PCI_ATPDMA0_PCIADDR_OFFSET)
-#define PCI_ATPDMA0_LENADDR _IXP4XX_PCI_CSR(PCI_ATPDMA0_LENADDR_OFFSET)
-#define PCI_ATPDMA1_AHBADDR _IXP4XX_PCI_CSR(PCI_ATPDMA1_AHBADDR_OFFSET)
-#define PCI_ATPDMA1_PCIADDR _IXP4XX_PCI_CSR(PCI_ATPDMA1_PCIADDR_OFFSET)
-#define PCI_ATPDMA1_LENADDR _IXP4XX_PCI_CSR(PCI_ATPDMA1_LENADDR_OFFSET)
-
-/*
- * PCI register values and bit definitions
- */
-
-/* CSR bit definitions */
-#define PCI_CSR_HOST 0x00000001
-#define PCI_CSR_ARBEN 0x00000002
-#define PCI_CSR_ADS 0x00000004
-#define PCI_CSR_PDS 0x00000008
-#define PCI_CSR_ABE 0x00000010
-#define PCI_CSR_DBT 0x00000020
-#define PCI_CSR_ASE 0x00000100
-#define PCI_CSR_IC 0x00008000
-
-/* ISR (Interrupt status) Register bit definitions */
-#define PCI_ISR_PSE 0x00000001
-#define PCI_ISR_PFE 0x00000002
-#define PCI_ISR_PPE 0x00000004
-#define PCI_ISR_AHBE 0x00000008
-#define PCI_ISR_APDC 0x00000010
-#define PCI_ISR_PADC 0x00000020
-#define PCI_ISR_ADB 0x00000040
-#define PCI_ISR_PDB 0x00000080
-
-/* INTEN (Interrupt Enable) Register bit definitions */
-#define PCI_INTEN_PSE 0x00000001
-#define PCI_INTEN_PFE 0x00000002
-#define PCI_INTEN_PPE 0x00000004
-#define PCI_INTEN_AHBE 0x00000008
-#define PCI_INTEN_APDC 0x00000010
-#define PCI_INTEN_PADC 0x00000020
-#define PCI_INTEN_ADB 0x00000040
-#define PCI_INTEN_PDB 0x00000080
-
-/*
- * Shift value for byte enable on NP cmd/byte enable register
- */
-#define IXP4XX_PCI_NP_CBE_BESL 4
-
-/*
- * PCI commands supported by NP access unit
- */
-#define NP_CMD_IOREAD 0x2
-#define NP_CMD_IOWRITE 0x3
-#define NP_CMD_CONFIGREAD 0xa
-#define NP_CMD_CONFIGWRITE 0xb
-#define NP_CMD_MEMREAD 0x6
-#define NP_CMD_MEMWRITE 0x7
-
-/*
- * Constants for CRP access into local config space
- */
-#define CRP_AD_CBE_BESL 20
-#define CRP_AD_CBE_WRITE 0x00010000
-
-#define DCMD_LENGTH 0x01fff /* length mask (max = 8K - 1) */
-
-#endif
diff --git a/arch/arm/mach-ixp4xx/include/mach/platform.h b/arch/arm/mach-ixp4xx/include/mach/platform.h
deleted file mode 100644
index d8b4df96db08..000000000000
--- a/arch/arm/mach-ixp4xx/include/mach/platform.h
+++ /dev/null
@@ -1,102 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * arch/arm/mach-ixp4xx/include/mach/platform.h
- *
- * Constants and functions that are useful to IXP4xx platform-specific code
- * and device drivers.
- *
- * Copyright (C) 2004 MontaVista Software, Inc.
- */
-
-#ifndef __ASM_ARCH_HARDWARE_H__
-#error "Do not include this directly, instead #include <mach/hardware.h>"
-#endif
-
-#ifndef __ASSEMBLY__
-
-#include <linux/reboot.h>
-#include <linux/platform_data/eth_ixp4xx.h>
-
-#include <asm/types.h>
-
-#ifndef __ARMEB__
-#define REG_OFFSET 0
-#else
-#define REG_OFFSET 3
-#endif
-
-/*
- * Expansion bus memory regions
- */
-#define IXP4XX_EXP_BUS_BASE_PHYS (0x50000000)
-
-/*
- * The expansion bus on the IXP4xx can be configured for either 16 or
- * 32MB windows and the CS offset for each region changes based on the
- * current configuration. This means that we cannot simply hardcode
- * each offset. ixp4xx_sys_init() looks at the expansion bus configuration
- * as setup by the bootloader to determine our window size.
- */
-extern unsigned long ixp4xx_exp_bus_size;
-
-#define IXP4XX_EXP_BUS_BASE(region)\
- (IXP4XX_EXP_BUS_BASE_PHYS + ((region) * ixp4xx_exp_bus_size))
-
-#define IXP4XX_EXP_BUS_END(region)\
- (IXP4XX_EXP_BUS_BASE(region) + ixp4xx_exp_bus_size - 1)
-
-/* Those macros can be used to adjust timing and configure
- * other features for each region.
- */
-
-#define IXP4XX_EXP_BUS_RECOVERY_T(x) (((x) & 0x0f) << 16)
-#define IXP4XX_EXP_BUS_HOLD_T(x) (((x) & 0x03) << 20)
-#define IXP4XX_EXP_BUS_STROBE_T(x) (((x) & 0x0f) << 22)
-#define IXP4XX_EXP_BUS_SETUP_T(x) (((x) & 0x03) << 26)
-#define IXP4XX_EXP_BUS_ADDR_T(x) (((x) & 0x03) << 28)
-#define IXP4XX_EXP_BUS_SIZE(x) (((x) & 0x0f) << 10)
-#define IXP4XX_EXP_BUS_CYCLES(x) (((x) & 0x03) << 14)
-
-#define IXP4XX_EXP_BUS_CS_EN (1L << 31)
-#define IXP4XX_EXP_BUS_BYTE_RD16 (1L << 6)
-#define IXP4XX_EXP_BUS_HRDY_POL (1L << 5)
-#define IXP4XX_EXP_BUS_MUX_EN (1L << 4)
-#define IXP4XX_EXP_BUS_SPLT_EN (1L << 3)
-#define IXP4XX_EXP_BUS_WR_EN (1L << 1)
-#define IXP4XX_EXP_BUS_BYTE_EN (1L << 0)
-
-#define IXP4XX_EXP_BUS_CYCLES_INTEL 0x00
-#define IXP4XX_EXP_BUS_CYCLES_MOTOROLA 0x01
-#define IXP4XX_EXP_BUS_CYCLES_HPI 0x02
-
-#define IXP4XX_FLASH_WRITABLE (0x2)
-#define IXP4XX_FLASH_DEFAULT (0xbcd23c40)
-#define IXP4XX_FLASH_WRITE (0xbcd23c42)
-
-/*
- * Clock Speed Definitions.
- */
-#define IXP4XX_PERIPHERAL_BUS_CLOCK (66) /* 66MHzi APB BUS */
-#define IXP4XX_UART_XTAL 14745600
-
-/*
- * Frequency of clock used for primary clocksource
- */
-extern unsigned long ixp4xx_timer_freq;
-
-/*
- * Functions used by platform-level setup code
- */
-extern void ixp4xx_map_io(void);
-extern void ixp4xx_init_early(void);
-extern void ixp4xx_init_irq(void);
-extern void ixp4xx_sys_init(void);
-extern void ixp4xx_timer_init(void);
-extern void ixp4xx_restart(enum reboot_mode, const char *);
-extern void ixp4xx_pci_preinit(void);
-struct pci_sys_data;
-extern int ixp4xx_setup(int nr, struct pci_sys_data *sys);
-extern struct pci_ops ixp4xx_ops;
-
-#endif // __ASSEMBLY__
-
diff --git a/arch/arm/mach-ixp4xx/include/mach/udc.h b/arch/arm/mach-ixp4xx/include/mach/udc.h
deleted file mode 100644
index 7bd8b96c8843..000000000000
--- a/arch/arm/mach-ixp4xx/include/mach/udc.h
+++ /dev/null
@@ -1,8 +0,0 @@
-/*
- * arch/arm/mach-ixp4xx/include/mach/udc.h
- *
- */
-#include <linux/platform_data/pxa2xx_udc.h>
-
-extern void ixp4xx_set_udc_info(struct pxa2xx_udc_mach_info *info);
-
diff --git a/arch/arm/mach-ixp4xx/include/mach/uncompress.h b/arch/arm/mach-ixp4xx/include/mach/uncompress.h
index 9e08b270cfc7..09e7663e6a55 100644
--- a/arch/arm/mach-ixp4xx/include/mach/uncompress.h
+++ b/arch/arm/mach-ixp4xx/include/mach/uncompress.h
@@ -9,10 +9,12 @@
#ifndef _ARCH_UNCOMPRESS_H_
#define _ARCH_UNCOMPRESS_H_
-#include "ixp4xx-regs.h"
#include <asm/mach-types.h>
#include <linux/serial_reg.h>
+#define IXP4XX_UART1_BASE_PHYS 0xc8000000
+#define IXP4XX_UART2_BASE_PHYS 0xc8001000
+
#define TX_DONE (UART_LSR_TEMT|UART_LSR_THRE)
volatile u32* uart_base;
diff --git a/arch/arm/mach-ixp4xx/irqs.h b/arch/arm/mach-ixp4xx/irqs.h
deleted file mode 100644
index a3e8d6408c56..000000000000
--- a/arch/arm/mach-ixp4xx/irqs.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * arch/arm/mach-ixp4xx/include/mach/irqs.h
- *
- * IRQ definitions for IXP4XX based systems
- *
- * Copyright (C) 2002 Intel Corporation.
- * Copyright (C) 2003 MontaVista Software, Inc.
- */
-
-#ifndef _ARCH_IXP4XX_IRQS_H_
-#define _ARCH_IXP4XX_IRQS_H_
-
-#define IRQ_IXP4XX_BASE 16
-
-#define IRQ_IXP4XX_NPEA (IRQ_IXP4XX_BASE + 0)
-#define IRQ_IXP4XX_NPEB (IRQ_IXP4XX_BASE + 1)
-#define IRQ_IXP4XX_NPEC (IRQ_IXP4XX_BASE + 2)
-#define IRQ_IXP4XX_QM1 (IRQ_IXP4XX_BASE + 3)
-#define IRQ_IXP4XX_QM2 (IRQ_IXP4XX_BASE + 4)
-#define IRQ_IXP4XX_TIMER1 (IRQ_IXP4XX_BASE + 5)
-#define IRQ_IXP4XX_GPIO0 (IRQ_IXP4XX_BASE + 6)
-#define IRQ_IXP4XX_GPIO1 (IRQ_IXP4XX_BASE + 7)
-#define IRQ_IXP4XX_PCI_INT (IRQ_IXP4XX_BASE + 8)
-#define IRQ_IXP4XX_PCI_DMA1 (IRQ_IXP4XX_BASE + 9)
-#define IRQ_IXP4XX_PCI_DMA2 (IRQ_IXP4XX_BASE + 10)
-#define IRQ_IXP4XX_TIMER2 (IRQ_IXP4XX_BASE + 11)
-#define IRQ_IXP4XX_USB (IRQ_IXP4XX_BASE + 12)
-#define IRQ_IXP4XX_UART2 (IRQ_IXP4XX_BASE + 13)
-#define IRQ_IXP4XX_TIMESTAMP (IRQ_IXP4XX_BASE + 14)
-#define IRQ_IXP4XX_UART1 (IRQ_IXP4XX_BASE + 15)
-#define IRQ_IXP4XX_WDOG (IRQ_IXP4XX_BASE + 16)
-#define IRQ_IXP4XX_AHB_PMU (IRQ_IXP4XX_BASE + 17)
-#define IRQ_IXP4XX_XSCALE_PMU (IRQ_IXP4XX_BASE + 18)
-#define IRQ_IXP4XX_GPIO2 (IRQ_IXP4XX_BASE + 19)
-#define IRQ_IXP4XX_GPIO3 (IRQ_IXP4XX_BASE + 20)
-#define IRQ_IXP4XX_GPIO4 (IRQ_IXP4XX_BASE + 21)
-#define IRQ_IXP4XX_GPIO5 (IRQ_IXP4XX_BASE + 22)
-#define IRQ_IXP4XX_GPIO6 (IRQ_IXP4XX_BASE + 23)
-#define IRQ_IXP4XX_GPIO7 (IRQ_IXP4XX_BASE + 24)
-#define IRQ_IXP4XX_GPIO8 (IRQ_IXP4XX_BASE + 25)
-#define IRQ_IXP4XX_GPIO9 (IRQ_IXP4XX_BASE + 26)
-#define IRQ_IXP4XX_GPIO10 (IRQ_IXP4XX_BASE + 27)
-#define IRQ_IXP4XX_GPIO11 (IRQ_IXP4XX_BASE + 28)
-#define IRQ_IXP4XX_GPIO12 (IRQ_IXP4XX_BASE + 29)
-#define IRQ_IXP4XX_SW_INT1 (IRQ_IXP4XX_BASE + 30)
-#define IRQ_IXP4XX_SW_INT2 (IRQ_IXP4XX_BASE + 31)
-#define IRQ_IXP4XX_USB_HOST (IRQ_IXP4XX_BASE + 32)
-#define IRQ_IXP4XX_I2C (IRQ_IXP4XX_BASE + 33)
-#define IRQ_IXP4XX_SSP (IRQ_IXP4XX_BASE + 34)
-#define IRQ_IXP4XX_TSYNC (IRQ_IXP4XX_BASE + 35)
-#define IRQ_IXP4XX_EAU_DONE (IRQ_IXP4XX_BASE + 36)
-#define IRQ_IXP4XX_SHA_DONE (IRQ_IXP4XX_BASE + 37)
-#define IRQ_IXP4XX_SWCP_PE (IRQ_IXP4XX_BASE + 58)
-#define IRQ_IXP4XX_QM_PE (IRQ_IXP4XX_BASE + 60)
-#define IRQ_IXP4XX_MCU_ECC (IRQ_IXP4XX_BASE + 61)
-#define IRQ_IXP4XX_EXP_PE (IRQ_IXP4XX_BASE + 62)
-
-#define _IXP4XX_GPIO_IRQ(n) (IRQ_IXP4XX_GPIO ## n)
-#define IXP4XX_GPIO_IRQ(n) _IXP4XX_GPIO_IRQ(n)
-
-#define XSCALE_PMU_IRQ (IRQ_IXP4XX_XSCALE_PMU)
-
-#endif
diff --git a/arch/arm/mach-mmp/sram.c b/arch/arm/mach-mmp/sram.c
index 6794e2db1ad5..ecc46c31004f 100644
--- a/arch/arm/mach-mmp/sram.c
+++ b/arch/arm/mach-mmp/sram.c
@@ -72,6 +72,8 @@ static int sram_probe(struct platform_device *pdev)
if (!info)
return -ENOMEM;
+ platform_set_drvdata(pdev, info);
+
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (res == NULL) {
dev_err(&pdev->dev, "no memory resource defined\n");
@@ -107,8 +109,6 @@ static int sram_probe(struct platform_device *pdev)
list_add(&info->node, &sram_bank_list);
mutex_unlock(&sram_lock);
- platform_set_drvdata(pdev, info);
-
dev_info(&pdev->dev, "initialized\n");
return 0;
@@ -127,17 +127,19 @@ static int sram_remove(struct platform_device *pdev)
struct sram_bank_info *info;
info = platform_get_drvdata(pdev);
- if (info == NULL)
- return -ENODEV;
- mutex_lock(&sram_lock);
- list_del(&info->node);
- mutex_unlock(&sram_lock);
+ if (info->sram_size) {
+ mutex_lock(&sram_lock);
+ list_del(&info->node);
+ mutex_unlock(&sram_lock);
+
+ gen_pool_destroy(info->gpool);
+ iounmap(info->sram_virt);
+ kfree(info->pool_name);
+ }
- gen_pool_destroy(info->gpool);
- iounmap(info->sram_virt);
- kfree(info->pool_name);
kfree(info);
+
return 0;
}
diff --git a/arch/arm/mach-mstar/Kconfig b/arch/arm/mach-mstar/Kconfig
index cd300eeedc20..5dbea7b485af 100644
--- a/arch/arm/mach-mstar/Kconfig
+++ b/arch/arm/mach-mstar/Kconfig
@@ -1,8 +1,10 @@
menuconfig ARCH_MSTARV7
bool "MStar/Sigmastar Armv7 SoC Support"
depends on ARCH_MULTI_V7
+ select ARM_ERRATA_814220
select ARM_GIC
select ARM_HEAVY_MB
+ select HAVE_ARM_ARCH_TIMER
select MST_IRQ
select MSTAR_MSC313_MPLL
help
diff --git a/arch/arm/mach-mv78xx0/irq.c b/arch/arm/mach-mv78xx0/irq.c
index 788569e960e1..0b5f055ca1c3 100644
--- a/arch/arm/mach-mv78xx0/irq.c
+++ b/arch/arm/mach-mv78xx0/irq.c
@@ -67,7 +67,6 @@ void __init mv78xx0_init_irq(void)
* registers for core #1 are at an offset of 0x18 from those of
* core #0.)
*/
- orion_gpio_init(NULL, 0, 32, GPIO_VIRT_BASE,
- mv78xx0_core_index() ? 0x18 : 0,
+ orion_gpio_init(0, 32, GPIO_VIRT_BASE, mv78xx0_core_index() ? 0x18 : 0,
IRQ_MV78XX0_GPIO_START, gpio0_irqs);
}
diff --git a/arch/arm/mach-nspire/Kconfig b/arch/arm/mach-nspire/Kconfig
index b3d161e8e2fb..6ef1b167619b 100644
--- a/arch/arm/mach-nspire/Kconfig
+++ b/arch/arm/mach-nspire/Kconfig
@@ -2,7 +2,6 @@
config ARCH_NSPIRE
bool "TI-NSPIRE based"
depends on ARCH_MULTI_V4_V5
- depends on MMU
select CPU_ARM926T
select GENERIC_IRQ_CHIP
select ARM_AMBA
diff --git a/arch/arm/mach-omap2/display.c b/arch/arm/mach-omap2/display.c
index 6daaa645ae5d..21413a9b7b6c 100644
--- a/arch/arm/mach-omap2/display.c
+++ b/arch/arm/mach-omap2/display.c
@@ -263,9 +263,9 @@ static int __init omapdss_init_of(void)
}
r = of_platform_populate(node, NULL, NULL, &pdev->dev);
+ put_device(&pdev->dev);
if (r) {
pr_err("Unable to populate DSS submodule devices\n");
- put_device(&pdev->dev);
return r;
}
diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c
index ccb0e3732c0d..31d1a21f6041 100644
--- a/arch/arm/mach-omap2/omap_hwmod.c
+++ b/arch/arm/mach-omap2/omap_hwmod.c
@@ -752,8 +752,10 @@ static int __init _init_clkctrl_providers(void)
for_each_matching_node(np, ti_clkctrl_match_table) {
ret = _setup_clkctrl_provider(np);
- if (ret)
+ if (ret) {
+ of_node_put(np);
break;
+ }
}
return ret;
diff --git a/arch/arm/mach-orion5x/Kconfig b/arch/arm/mach-orion5x/Kconfig
index e94a61901ffd..c77f3b4e287b 100644
--- a/arch/arm/mach-orion5x/Kconfig
+++ b/arch/arm/mach-orion5x/Kconfig
@@ -1,7 +1,7 @@
# SPDX-License-Identifier: GPL-2.0-only
menuconfig ARCH_ORION5X
bool "Marvell Orion"
- depends on MMU && ARCH_MULTI_V5
+ depends on ARCH_MULTI_V5
select CPU_FEROCEON
select GPIOLIB
select MVEBU_MBUS
diff --git a/arch/arm/mach-orion5x/irq.c b/arch/arm/mach-orion5x/irq.c
index ac4af2283bef..1ae775d02d90 100644
--- a/arch/arm/mach-orion5x/irq.c
+++ b/arch/arm/mach-orion5x/irq.c
@@ -49,6 +49,6 @@ void __init orion5x_init_irq(void)
/*
* Initialize gpiolib for GPIOs 0-31.
*/
- orion_gpio_init(NULL, 0, 32, GPIO_VIRT_BASE, 0,
+ orion_gpio_init(0, 32, GPIO_VIRT_BASE, 0,
IRQ_ORION5X_GPIO_START, gpio0_irqs);
}
diff --git a/arch/arm/mach-pxa/Kconfig b/arch/arm/mach-pxa/Kconfig
index f7520a6cc7d4..57f0be4065c1 100644
--- a/arch/arm/mach-pxa/Kconfig
+++ b/arch/arm/mach-pxa/Kconfig
@@ -153,16 +153,6 @@ config GUMSTIX_AM300EPD
endchoice
-config MACH_INTELMOTE2
- bool "Intel Mote 2 Platform"
- select IWMMXT
- select PXA27x
-
-config MACH_STARGATE2
- bool "Intel Stargate 2 Platform"
- select IWMMXT
- select PXA27x
-
config MACH_XCEP
bool "Iskratel Electronics XCEP"
select MTD
diff --git a/arch/arm/mach-pxa/Makefile b/arch/arm/mach-pxa/Makefile
index 177abe584dd5..68730ceb8b7c 100644
--- a/arch/arm/mach-pxa/Makefile
+++ b/arch/arm/mach-pxa/Makefile
@@ -45,8 +45,6 @@ obj-$(CONFIG_MACH_CAPC7117) += capc7117.o mxm8x10.o
obj-$(CONFIG_ARCH_GUMSTIX) += gumstix.o
obj-$(CONFIG_GUMSTIX_AM200EPD) += am200epd.o
obj-$(CONFIG_GUMSTIX_AM300EPD) += am300epd.o
-obj-$(CONFIG_MACH_INTELMOTE2) += stargate2.o
-obj-$(CONFIG_MACH_STARGATE2) += stargate2.o
obj-$(CONFIG_MACH_XCEP) += xcep.o
obj-$(CONFIG_MACH_TRIZEPS4) += trizeps4.o
obj-$(CONFIG_MACH_LOGICPD_PXA270) += lpd270.o
diff --git a/arch/arm/mach-pxa/corgi.c b/arch/arm/mach-pxa/corgi.c
index 593c7f793da5..44659fbc37ba 100644
--- a/arch/arm/mach-pxa/corgi.c
+++ b/arch/arm/mach-pxa/corgi.c
@@ -530,6 +530,16 @@ static struct pxa2xx_spi_controller corgi_spi_info = {
.num_chipselect = 3,
};
+static struct gpiod_lookup_table corgi_spi_gpio_table = {
+ .dev_id = "pxa2xx-spi.1",
+ .table = {
+ GPIO_LOOKUP_IDX("gpio-pxa", CORGI_GPIO_ADS7846_CS, "cs", 0, GPIO_ACTIVE_LOW),
+ GPIO_LOOKUP_IDX("gpio-pxa", CORGI_GPIO_LCDCON_CS, "cs", 1, GPIO_ACTIVE_LOW),
+ GPIO_LOOKUP_IDX("gpio-pxa", CORGI_GPIO_MAX1111_CS, "cs", 2, GPIO_ACTIVE_LOW),
+ { },
+ },
+};
+
static void corgi_wait_for_hsync(void)
{
while (gpio_get_value(CORGI_GPIO_HSYNC))
@@ -548,10 +558,6 @@ static struct ads7846_platform_data corgi_ads7846_info = {
.wait_for_sync = corgi_wait_for_hsync,
};
-static struct pxa2xx_spi_chip corgi_ads7846_chip = {
- .gpio_cs = CORGI_GPIO_ADS7846_CS,
-};
-
static void corgi_bl_kick_battery(void)
{
void (*kick_batt)(void);
@@ -580,14 +586,6 @@ static struct corgi_lcd_platform_data corgi_lcdcon_info = {
.kick_battery = corgi_bl_kick_battery,
};
-static struct pxa2xx_spi_chip corgi_lcdcon_chip = {
- .gpio_cs = CORGI_GPIO_LCDCON_CS,
-};
-
-static struct pxa2xx_spi_chip corgi_max1111_chip = {
- .gpio_cs = CORGI_GPIO_MAX1111_CS,
-};
-
static struct spi_board_info corgi_spi_devices[] = {
{
.modalias = "ads7846",
@@ -595,7 +593,6 @@ static struct spi_board_info corgi_spi_devices[] = {
.bus_num = 1,
.chip_select = 0,
.platform_data = &corgi_ads7846_info,
- .controller_data= &corgi_ads7846_chip,
.irq = PXA_GPIO_TO_IRQ(CORGI_GPIO_TP_INT),
}, {
.modalias = "corgi-lcd",
@@ -603,18 +600,17 @@ static struct spi_board_info corgi_spi_devices[] = {
.bus_num = 1,
.chip_select = 1,
.platform_data = &corgi_lcdcon_info,
- .controller_data= &corgi_lcdcon_chip,
}, {
.modalias = "max1111",
.max_speed_hz = 450000,
.bus_num = 1,
.chip_select = 2,
- .controller_data= &corgi_max1111_chip,
},
};
static void __init corgi_init_spi(void)
{
+ gpiod_add_lookup_table(&corgi_spi_gpio_table);
pxa2xx_set_spi_info(1, &corgi_spi_info);
gpiod_add_lookup_table(&corgi_lcdcon_gpio_table);
spi_register_board_info(ARRAY_AND_SIZE(corgi_spi_devices));
diff --git a/arch/arm/mach-pxa/hx4700.c b/arch/arm/mach-pxa/hx4700.c
index 1d4c5db54be2..e1870fbb19e7 100644
--- a/arch/arm/mach-pxa/hx4700.c
+++ b/arch/arm/mach-pxa/hx4700.c
@@ -616,7 +616,6 @@ static struct pxa2xx_spi_chip tsc2046_chip = {
.tx_threshold = 1,
.rx_threshold = 2,
.timeout = 64,
- .gpio_cs = GPIO88_HX4700_TSC2046_CS,
};
static struct spi_board_info tsc2046_board_info[] __initdata = {
@@ -635,6 +634,14 @@ static struct pxa2xx_spi_controller pxa_ssp2_master_info = {
.enable_dma = 1,
};
+static struct gpiod_lookup_table pxa_ssp2_gpio_table = {
+ .dev_id = "pxa2xx-spi.2",
+ .table = {
+ GPIO_LOOKUP_IDX("gpio-pxa", GPIO88_HX4700_TSC2046_CS, "cs", 0, GPIO_ACTIVE_LOW),
+ { },
+ },
+};
+
/*
* External power
*/
@@ -896,6 +903,7 @@ static void __init hx4700_init(void)
pxa_set_i2c_info(NULL);
i2c_register_board_info(0, ARRAY_AND_SIZE(i2c_board_info));
i2c_register_board_info(1, ARRAY_AND_SIZE(pi2c_board_info));
+ gpiod_add_lookup_table(&pxa_ssp2_gpio_table);
pxa2xx_set_spi_info(2, &pxa_ssp2_master_info);
spi_register_board_info(ARRAY_AND_SIZE(tsc2046_board_info));
diff --git a/arch/arm/mach-pxa/icontrol.c b/arch/arm/mach-pxa/icontrol.c
index 04a12523cdee..753fe166ab68 100644
--- a/arch/arm/mach-pxa/icontrol.c
+++ b/arch/arm/mach-pxa/icontrol.c
@@ -13,7 +13,7 @@
#include <linux/irq.h>
#include <linux/platform_device.h>
#include <linux/property.h>
-#include <linux/gpio.h>
+#include <linux/gpio/machine.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
@@ -42,7 +42,6 @@ static struct pxa2xx_spi_chip mcp251x_chip_info1 = {
.rx_threshold = 128,
.dma_burst_size = 8,
.timeout = 235,
- .gpio_cs = ICONTROL_MCP251x_nCS1
};
static struct pxa2xx_spi_chip mcp251x_chip_info2 = {
@@ -50,7 +49,6 @@ static struct pxa2xx_spi_chip mcp251x_chip_info2 = {
.rx_threshold = 128,
.dma_burst_size = 8,
.timeout = 235,
- .gpio_cs = ICONTROL_MCP251x_nCS2
};
static struct pxa2xx_spi_chip mcp251x_chip_info3 = {
@@ -58,7 +56,6 @@ static struct pxa2xx_spi_chip mcp251x_chip_info3 = {
.rx_threshold = 128,
.dma_burst_size = 8,
.timeout = 235,
- .gpio_cs = ICONTROL_MCP251x_nCS3
};
static struct pxa2xx_spi_chip mcp251x_chip_info4 = {
@@ -66,7 +63,6 @@ static struct pxa2xx_spi_chip mcp251x_chip_info4 = {
.rx_threshold = 128,
.dma_burst_size = 8,
.timeout = 235,
- .gpio_cs = ICONTROL_MCP251x_nCS4
};
static const struct property_entry mcp251x_properties[] = {
@@ -143,6 +139,24 @@ struct platform_device pxa_spi_ssp4 = {
}
};
+static struct gpiod_lookup_table pxa_ssp3_gpio_table = {
+ .dev_id = "pxa2xx-spi.3",
+ .table = {
+ GPIO_LOOKUP_IDX("gpio-pxa", ICONTROL_MCP251x_nCS1, "cs", 0, GPIO_ACTIVE_LOW),
+ GPIO_LOOKUP_IDX("gpio-pxa", ICONTROL_MCP251x_nCS2, "cs", 1, GPIO_ACTIVE_LOW),
+ { },
+ },
+};
+
+static struct gpiod_lookup_table pxa_ssp4_gpio_table = {
+ .dev_id = "pxa2xx-spi.4",
+ .table = {
+ GPIO_LOOKUP_IDX("gpio-pxa", ICONTROL_MCP251x_nCS3, "cs", 0, GPIO_ACTIVE_LOW),
+ GPIO_LOOKUP_IDX("gpio-pxa", ICONTROL_MCP251x_nCS4, "cs", 1, GPIO_ACTIVE_LOW),
+ { },
+ },
+};
+
static struct platform_device *icontrol_spi_devices[] __initdata = {
&pxa_spi_ssp3,
&pxa_spi_ssp4,
@@ -175,6 +189,8 @@ static mfp_cfg_t mfp_can_cfg[] __initdata = {
static void __init icontrol_can_init(void)
{
pxa3xx_mfp_config(ARRAY_AND_SIZE(mfp_can_cfg));
+ gpiod_add_lookup_table(&pxa_ssp3_gpio_table);
+ gpiod_add_lookup_table(&pxa_ssp4_gpio_table);
platform_add_devices(ARRAY_AND_SIZE(icontrol_spi_devices));
spi_register_board_info(ARRAY_AND_SIZE(mcp251x_board_info));
}
diff --git a/arch/arm/mach-pxa/include/mach/uncompress.h b/arch/arm/mach-pxa/include/mach/uncompress.h
index c36306064eee..1ed629e38ce6 100644
--- a/arch/arm/mach-pxa/include/mach/uncompress.h
+++ b/arch/arm/mach-pxa/include/mach/uncompress.h
@@ -58,9 +58,8 @@ static inline void arch_decomp_setup(void)
uart_shift = 2;
uart_is_pxa = 1;
- if (machine_is_littleton() || machine_is_intelmote2()
- || machine_is_csb726() || machine_is_stargate2()
- || machine_is_cm_x300() || machine_is_balloon3())
+ if (machine_is_littleton() || machine_is_csb726() ||
+ machine_is_cm_x300() || machine_is_balloon3())
uart_base = STUART_BASE;
if (machine_is_arcom_zeus()) {
diff --git a/arch/arm/mach-pxa/littleton.c b/arch/arm/mach-pxa/littleton.c
index 793f61375ee8..73f5953b3bb6 100644
--- a/arch/arm/mach-pxa/littleton.c
+++ b/arch/arm/mach-pxa/littleton.c
@@ -195,7 +195,6 @@ static struct pxa2xx_spi_controller littleton_spi_info = {
static struct pxa2xx_spi_chip littleton_tdo24m_chip = {
.rx_threshold = 1,
.tx_threshold = 1,
- .gpio_cs = LITTLETON_GPIO_LCD_CS,
};
static struct spi_board_info littleton_spi_devices[] __initdata = {
@@ -208,8 +207,17 @@ static struct spi_board_info littleton_spi_devices[] __initdata = {
},
};
+static struct gpiod_lookup_table littleton_spi_gpio_table = {
+ .dev_id = "pxa2xx-spi.2",
+ .table = {
+ GPIO_LOOKUP_IDX("gpio-pxa", LITTLETON_GPIO_LCD_CS, "cs", 0, GPIO_ACTIVE_LOW),
+ { },
+ },
+};
+
static void __init littleton_init_spi(void)
{
+ gpiod_add_lookup_table(&littleton_spi_gpio_table);
pxa2xx_set_spi_info(2, &littleton_spi_info);
spi_register_board_info(ARRAY_AND_SIZE(littleton_spi_devices));
}
diff --git a/arch/arm/mach-pxa/magician.c b/arch/arm/mach-pxa/magician.c
index cd9fa465b9b2..200fd35168e0 100644
--- a/arch/arm/mach-pxa/magician.c
+++ b/arch/arm/mach-pxa/magician.c
@@ -938,8 +938,6 @@ struct pxa2xx_spi_chip tsc2046_chip_info = {
.tx_threshold = 1,
.rx_threshold = 2,
.timeout = 64,
- /* NOTICE must be GPIO, incompatibility with hw PXA SPI framing */
- .gpio_cs = GPIO14_MAGICIAN_TSC2046_CS,
};
static struct pxa2xx_spi_controller magician_spi_info = {
@@ -947,6 +945,15 @@ static struct pxa2xx_spi_controller magician_spi_info = {
.enable_dma = 1,
};
+static struct gpiod_lookup_table magician_spi_gpio_table = {
+ .dev_id = "pxa2xx-spi.2",
+ .table = {
+ /* NOTICE must be GPIO, incompatibility with hw PXA SPI framing */
+ GPIO_LOOKUP_IDX("gpio-pxa", GPIO14_MAGICIAN_TSC2046_CS, "cs", 0, GPIO_ACTIVE_LOW),
+ { },
+ },
+};
+
static struct spi_board_info ads7846_spi_board_info[] __initdata = {
{
.modalias = "ads7846",
@@ -1031,6 +1038,7 @@ static void __init magician_init(void)
} else
pr_err("LCD detection: CPLD mapping failed\n");
+ gpiod_add_lookup_table(&magician_spi_gpio_table);
pxa2xx_set_spi_info(2, &magician_spi_info);
spi_register_board_info(ARRAY_AND_SIZE(ads7846_spi_board_info));
diff --git a/arch/arm/mach-pxa/poodle.c b/arch/arm/mach-pxa/poodle.c
index 3a4ecc3c8f8b..58cfa434afde 100644
--- a/arch/arm/mach-pxa/poodle.c
+++ b/arch/arm/mach-pxa/poodle.c
@@ -197,6 +197,14 @@ static struct pxa2xx_spi_controller poodle_spi_info = {
.num_chipselect = 1,
};
+static struct gpiod_lookup_table poodle_spi_gpio_table = {
+ .dev_id = "pxa2xx-spi.1",
+ .table = {
+ GPIO_LOOKUP_IDX("gpio-pxa", POODLE_GPIO_TP_CS, "cs", 0, GPIO_ACTIVE_LOW),
+ { },
+ },
+};
+
static struct ads7846_platform_data poodle_ads7846_info = {
.model = 7846,
.vref_delay_usecs = 100,
@@ -205,23 +213,19 @@ static struct ads7846_platform_data poodle_ads7846_info = {
.gpio_pendown = POODLE_GPIO_TP_INT,
};
-static struct pxa2xx_spi_chip poodle_ads7846_chip = {
- .gpio_cs = POODLE_GPIO_TP_CS,
-};
-
static struct spi_board_info poodle_spi_devices[] = {
{
.modalias = "ads7846",
.max_speed_hz = 10000,
.bus_num = 1,
.platform_data = &poodle_ads7846_info,
- .controller_data= &poodle_ads7846_chip,
.irq = PXA_GPIO_TO_IRQ(POODLE_GPIO_TP_INT),
},
};
static void __init poodle_init_spi(void)
{
+ gpiod_add_lookup_table(&poodle_spi_gpio_table);
pxa2xx_set_spi_info(1, &poodle_spi_info);
spi_register_board_info(ARRAY_AND_SIZE(poodle_spi_devices));
}
diff --git a/arch/arm/mach-pxa/spitz.c b/arch/arm/mach-pxa/spitz.c
index 371008e9bb02..a648e7094e84 100644
--- a/arch/arm/mach-pxa/spitz.c
+++ b/arch/arm/mach-pxa/spitz.c
@@ -510,10 +510,6 @@ static struct ads7846_platform_data spitz_ads7846_info = {
.wait_for_sync = spitz_ads7846_wait_for_hsync,
};
-static struct pxa2xx_spi_chip spitz_ads7846_chip = {
- .gpio_cs = SPITZ_GPIO_ADS7846_CS,
-};
-
static void spitz_bl_kick_battery(void)
{
void (*kick_batt)(void);
@@ -555,14 +551,6 @@ static struct corgi_lcd_platform_data spitz_lcdcon_info = {
.kick_battery = spitz_bl_kick_battery,
};
-static struct pxa2xx_spi_chip spitz_lcdcon_chip = {
- .gpio_cs = SPITZ_GPIO_LCDCON_CS,
-};
-
-static struct pxa2xx_spi_chip spitz_max1111_chip = {
- .gpio_cs = SPITZ_GPIO_MAX1111_CS,
-};
-
static struct spi_board_info spitz_spi_devices[] = {
{
.modalias = "ads7846",
@@ -570,7 +558,6 @@ static struct spi_board_info spitz_spi_devices[] = {
.bus_num = 2,
.chip_select = 0,
.platform_data = &spitz_ads7846_info,
- .controller_data = &spitz_ads7846_chip,
.irq = PXA_GPIO_TO_IRQ(SPITZ_GPIO_TP_INT),
}, {
.modalias = "corgi-lcd",
@@ -578,13 +565,11 @@ static struct spi_board_info spitz_spi_devices[] = {
.bus_num = 2,
.chip_select = 1,
.platform_data = &spitz_lcdcon_info,
- .controller_data = &spitz_lcdcon_chip,
}, {
.modalias = "max1111",
.max_speed_hz = 450000,
.bus_num = 2,
.chip_select = 2,
- .controller_data = &spitz_max1111_chip,
},
};
@@ -592,6 +577,16 @@ static struct pxa2xx_spi_controller spitz_spi_info = {
.num_chipselect = 3,
};
+static struct gpiod_lookup_table spitz_spi_gpio_table = {
+ .dev_id = "pxa2xx-spi.2",
+ .table = {
+ GPIO_LOOKUP_IDX("gpio-pxa", SPITZ_GPIO_ADS7846_CS, "cs", 0, GPIO_ACTIVE_LOW),
+ GPIO_LOOKUP_IDX("gpio-pxa", SPITZ_GPIO_LCDCON_CS, "cs", 1, GPIO_ACTIVE_LOW),
+ GPIO_LOOKUP_IDX("gpio-pxa", SPITZ_GPIO_MAX1111_CS, "cs", 2, GPIO_ACTIVE_LOW),
+ { },
+ },
+};
+
static void __init spitz_spi_init(void)
{
if (machine_is_akita())
@@ -599,6 +594,7 @@ static void __init spitz_spi_init(void)
else
gpiod_add_lookup_table(&spitz_lcdcon_gpio_table);
+ gpiod_add_lookup_table(&spitz_spi_gpio_table);
pxa2xx_set_spi_info(2, &spitz_spi_info);
spi_register_board_info(ARRAY_AND_SIZE(spitz_spi_devices));
}
diff --git a/arch/arm/mach-pxa/stargate2.c b/arch/arm/mach-pxa/stargate2.c
deleted file mode 100644
index 8ca02ec1d44c..000000000000
--- a/arch/arm/mach-pxa/stargate2.c
+++ /dev/null
@@ -1,1030 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * linux/arch/arm/mach-pxa/stargate2.c
- *
- * Author: Ed C. Epp
- * Created: Nov 05, 2002
- * Copyright: Intel Corp.
- *
- * Modified 2009: Jonathan Cameron <jic23@cam.ac.uk>
- */
-
-#include <linux/init.h>
-#include <linux/device.h>
-#include <linux/interrupt.h>
-#include <linux/sched.h>
-#include <linux/bitops.h>
-#include <linux/fb.h>
-#include <linux/delay.h>
-#include <linux/platform_device.h>
-#include <linux/regulator/machine.h>
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/plat-ram.h>
-#include <linux/mtd/partitions.h>
-
-#include <linux/platform_data/i2c-pxa.h>
-#include <linux/platform_data/pcf857x.h>
-#include <linux/smc91x.h>
-#include <linux/gpio/machine.h>
-#include <linux/gpio.h>
-#include <linux/leds.h>
-#include <linux/property.h>
-
-#include <asm/types.h>
-#include <asm/setup.h>
-#include <asm/memory.h>
-#include <asm/mach-types.h>
-#include <asm/irq.h>
-
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-#include <asm/mach/irq.h>
-#include <asm/mach/flash.h>
-
-#include "pxa27x.h"
-#include <linux/platform_data/mmc-pxamci.h>
-#include "udc.h"
-#include "pxa27x-udc.h"
-#include <mach/smemc.h>
-
-#include <linux/spi/spi.h>
-#include <linux/spi/pxa2xx_spi.h>
-#include <linux/mfd/da903x.h>
-
-#include "devices.h"
-#include "generic.h"
-
-#define STARGATE_NR_IRQS (IRQ_BOARD_START + 8)
-
-/* Bluetooth */
-#define SG2_BT_RESET 81
-
-/* SD */
-#define SG2_GPIO_nSD_DETECT 90
-#define SG2_SD_POWER_ENABLE 89
-
-static unsigned long sg2_im2_unified_pin_config[] __initdata = {
- /* Device Identification for wakeup*/
- GPIO102_GPIO,
- /* DA9030 */
- GPIO1_GPIO,
-
- /* MMC */
- GPIO32_MMC_CLK,
- GPIO112_MMC_CMD,
- GPIO92_MMC_DAT_0,
- GPIO109_MMC_DAT_1,
- GPIO110_MMC_DAT_2,
- GPIO111_MMC_DAT_3,
-
- /* 802.15.4 radio - driver out of mainline */
- GPIO22_GPIO, /* CC_RSTN */
- GPIO114_GPIO, /* CC_FIFO */
- GPIO116_GPIO, /* CC_CCA */
- GPIO0_GPIO, /* CC_FIFOP */
- GPIO16_GPIO, /* CCSFD */
- GPIO115_GPIO, /* Power enable */
-
- /* I2C */
- GPIO117_I2C_SCL,
- GPIO118_I2C_SDA,
-
- /* SSP 3 - 802.15.4 radio */
- GPIO39_GPIO, /* Chip Select */
- GPIO34_SSP3_SCLK,
- GPIO35_SSP3_TXD,
- GPIO41_SSP3_RXD,
-
- /* SSP 2 to daughter boards */
- GPIO11_SSP2_RXD,
- GPIO38_SSP2_TXD,
- GPIO36_SSP2_SCLK,
- GPIO37_GPIO, /* chip select */
-
- /* SSP 1 - to daughter boards */
- GPIO24_GPIO, /* Chip Select */
- GPIO23_SSP1_SCLK,
- GPIO25_SSP1_TXD,
- GPIO26_SSP1_RXD,
-
- /* BTUART Basic Connector*/
- GPIO42_BTUART_RXD,
- GPIO43_BTUART_TXD,
- GPIO44_BTUART_CTS,
- GPIO45_BTUART_RTS,
-
- /* STUART - IM2 via debug board not sure on SG2*/
- GPIO46_STUART_RXD,
- GPIO47_STUART_TXD,
-
- /* Basic sensor board */
- GPIO96_GPIO, /* accelerometer interrupt */
- GPIO99_GPIO, /* ADC interrupt */
-
- /* SHT15 */
- GPIO100_GPIO,
- GPIO98_GPIO,
-
- /* Basic sensor board */
- GPIO96_GPIO, /* accelerometer interrupt */
- GPIO99_GPIO, /* ADC interrupt */
-
- /* Connector pins specified as gpios */
- GPIO94_GPIO, /* large basic connector pin 14 */
- GPIO10_GPIO, /* large basic connector pin 23 */
-};
-
-static struct gpiod_lookup_table sht15_gpiod_table = {
- .dev_id = "sht15",
- .table = {
- /* FIXME: should this have |GPIO_OPEN_DRAIN set? */
- GPIO_LOOKUP("gpio-pxa", 100, "data", GPIO_ACTIVE_HIGH),
- GPIO_LOOKUP("gpio-pxa", 98, "clk", GPIO_ACTIVE_HIGH),
- },
-};
-
-static struct platform_device sht15 = {
- .name = "sht15",
- .id = -1,
-};
-
-static struct regulator_consumer_supply stargate2_sensor_3_con[] = {
- REGULATOR_SUPPLY("vcc", "sht15"),
-};
-
-enum stargate2_ldos{
- vcc_vref,
- vcc_cc2420,
- /* a mote connector? */
- vcc_mica,
- /* the CSR bluecore chip */
- vcc_bt,
- /* The two voltages available to sensor boards */
- vcc_sensor_1_8,
- vcc_sensor_3,
- /* directly connected to the pxa27x */
- vcc_sram_ext,
- vcc_pxa_pll,
- vcc_pxa_usim, /* Reference voltage for certain gpios */
- vcc_pxa_mem,
- vcc_pxa_flash,
- vcc_pxa_core, /*Dc-Dc buck not yet supported */
- vcc_lcd,
- vcc_bb,
- vcc_bbio, /*not sure!*/
- vcc_io, /* cc2420 802.15.4 radio and pxa vcc_io ?*/
-};
-
-/* The values of the various regulator constraints are obviously dependent
- * on exactly what is wired to each ldo. Unfortunately this information is
- * not generally available. More information has been requested from Xbow.
- */
-static struct regulator_init_data stargate2_ldo_init_data[] = {
- [vcc_bbio] = {
- .constraints = { /* board default 1.8V */
- .name = "vcc_bbio",
- .min_uV = 1800000,
- .max_uV = 1800000,
- },
- },
- [vcc_bb] = {
- .constraints = { /* board default 2.8V */
- .name = "vcc_bb",
- .min_uV = 2700000,
- .max_uV = 3000000,
- },
- },
- [vcc_pxa_flash] = {
- .constraints = {/* default is 1.8V */
- .name = "vcc_pxa_flash",
- .min_uV = 1800000,
- .max_uV = 1800000,
- },
- },
- [vcc_cc2420] = { /* also vcc_io */
- .constraints = {
- /* board default is 2.8V */
- .name = "vcc_cc2420",
- .min_uV = 2700000,
- .max_uV = 3300000,
- },
- },
- [vcc_vref] = { /* Reference for what? */
- .constraints = { /* default 1.8V */
- .name = "vcc_vref",
- .min_uV = 1800000,
- .max_uV = 1800000,
- },
- },
- [vcc_sram_ext] = {
- .constraints = { /* default 2.8V */
- .name = "vcc_sram_ext",
- .min_uV = 2800000,
- .max_uV = 2800000,
- },
- },
- [vcc_mica] = {
- .constraints = { /* default 2.8V */
- .name = "vcc_mica",
- .min_uV = 2800000,
- .max_uV = 2800000,
- },
- },
- [vcc_bt] = {
- .constraints = { /* default 2.8V */
- .name = "vcc_bt",
- .min_uV = 2800000,
- .max_uV = 2800000,
- },
- },
- [vcc_lcd] = {
- .constraints = { /* default 2.8V */
- .name = "vcc_lcd",
- .min_uV = 2700000,
- .max_uV = 3300000,
- },
- },
- [vcc_io] = { /* Same or higher than everything
- * bar vccbat and vccusb */
- .constraints = { /* default 2.8V */
- .name = "vcc_io",
- .min_uV = 2692000,
- .max_uV = 3300000,
- },
- },
- [vcc_sensor_1_8] = {
- .constraints = { /* default 1.8V */
- .name = "vcc_sensor_1_8",
- .min_uV = 1800000,
- .max_uV = 1800000,
- },
- },
- [vcc_sensor_3] = { /* curiously default 2.8V */
- .constraints = {
- .name = "vcc_sensor_3",
- .min_uV = 2800000,
- .max_uV = 3000000,
- },
- .num_consumer_supplies = ARRAY_SIZE(stargate2_sensor_3_con),
- .consumer_supplies = stargate2_sensor_3_con,
- },
- [vcc_pxa_pll] = { /* 1.17V - 1.43V, default 1.3V*/
- .constraints = {
- .name = "vcc_pxa_pll",
- .min_uV = 1170000,
- .max_uV = 1430000,
- },
- },
- [vcc_pxa_usim] = {
- .constraints = { /* default 1.8V */
- .name = "vcc_pxa_usim",
- .min_uV = 1710000,
- .max_uV = 2160000,
- },
- },
- [vcc_pxa_mem] = {
- .constraints = { /* default 1.8V */
- .name = "vcc_pxa_mem",
- .min_uV = 1800000,
- .max_uV = 1800000,
- },
- },
-};
-
-static struct mtd_partition stargate2flash_partitions[] = {
- {
- .name = "Bootloader",
- .size = 0x00040000,
- .offset = 0,
- .mask_flags = 0,
- }, {
- .name = "Kernel",
- .size = 0x00200000,
- .offset = 0x00040000,
- .mask_flags = 0
- }, {
- .name = "Filesystem",
- .size = 0x01DC0000,
- .offset = 0x00240000,
- .mask_flags = 0
- },
-};
-
-static struct resource flash_resources = {
- .start = PXA_CS0_PHYS,
- .end = PXA_CS0_PHYS + SZ_32M - 1,
- .flags = IORESOURCE_MEM,
-};
-
-static struct flash_platform_data stargate2_flash_data = {
- .map_name = "cfi_probe",
- .parts = stargate2flash_partitions,
- .nr_parts = ARRAY_SIZE(stargate2flash_partitions),
- .name = "PXA27xOnChipROM",
- .width = 2,
-};
-
-static struct platform_device stargate2_flash_device = {
- .name = "pxa2xx-flash",
- .id = 0,
- .dev = {
- .platform_data = &stargate2_flash_data,
- },
- .resource = &flash_resources,
- .num_resources = 1,
-};
-
-static struct pxa2xx_spi_controller pxa_ssp_master_0_info = {
- .num_chipselect = 1,
-};
-
-static struct pxa2xx_spi_controller pxa_ssp_master_1_info = {
- .num_chipselect = 1,
-};
-
-static struct pxa2xx_spi_controller pxa_ssp_master_2_info = {
- .num_chipselect = 1,
-};
-
-/* An upcoming kernel change will scrap SFRM usage so these
- * drivers have been moved to use GPIOs */
-static struct pxa2xx_spi_chip staccel_chip_info = {
- .tx_threshold = 8,
- .rx_threshold = 8,
- .dma_burst_size = 8,
- .timeout = 235,
- .gpio_cs = 24,
-};
-
-static struct pxa2xx_spi_chip cc2420_info = {
- .tx_threshold = 8,
- .rx_threshold = 8,
- .dma_burst_size = 8,
- .timeout = 235,
- .gpio_cs = 39,
-};
-
-static struct spi_board_info spi_board_info[] __initdata = {
- {
- .modalias = "lis3l02dq",
- .max_speed_hz = 8000000,/* 8MHz max spi frequency at 3V */
- .bus_num = 1,
- .chip_select = 0,
- .controller_data = &staccel_chip_info,
- .irq = PXA_GPIO_TO_IRQ(96),
- }, {
- .modalias = "cc2420",
- .max_speed_hz = 6500000,
- .bus_num = 3,
- .chip_select = 0,
- .controller_data = &cc2420_info,
- },
-};
-
-static void sg2_udc_command(int cmd)
-{
- switch (cmd) {
- case PXA2XX_UDC_CMD_CONNECT:
- UP2OCR |= UP2OCR_HXOE | UP2OCR_DPPUE | UP2OCR_DPPUBE;
- break;
- case PXA2XX_UDC_CMD_DISCONNECT:
- UP2OCR &= ~(UP2OCR_HXOE | UP2OCR_DPPUE | UP2OCR_DPPUBE);
- break;
- }
-}
-
-static struct i2c_pxa_platform_data i2c_pwr_pdata = {
- .fast_mode = 1,
-};
-
-static struct i2c_pxa_platform_data i2c_pdata = {
- .fast_mode = 1,
-};
-
-static void __init imote2_stargate2_init(void)
-{
-
- pxa2xx_mfp_config(ARRAY_AND_SIZE(sg2_im2_unified_pin_config));
-
- pxa_set_ffuart_info(NULL);
- pxa_set_btuart_info(NULL);
- pxa_set_stuart_info(NULL);
-
- pxa2xx_set_spi_info(1, &pxa_ssp_master_0_info);
- pxa2xx_set_spi_info(2, &pxa_ssp_master_1_info);
- pxa2xx_set_spi_info(3, &pxa_ssp_master_2_info);
- spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info));
-
-
- pxa27x_set_i2c_power_info(&i2c_pwr_pdata);
- pxa_set_i2c_info(&i2c_pdata);
-}
-
-#ifdef CONFIG_MACH_INTELMOTE2
-/* As the the imote2 doesn't currently have a conventional SD slot
- * there is no option to hotplug cards, making all this rather simple
- */
-static int imote2_mci_get_ro(struct device *dev)
-{
- return 0;
-}
-
-/* Rather simple case as hotplugging not possible */
-static struct pxamci_platform_data imote2_mci_platform_data = {
- .ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34, /* default anyway */
- .get_ro = imote2_mci_get_ro,
-};
-
-static struct gpio_led imote2_led_pins[] = {
- {
- .name = "imote2:red",
- .gpio = 103,
- .active_low = 1,
- }, {
- .name = "imote2:green",
- .gpio = 104,
- .active_low = 1,
- }, {
- .name = "imote2:blue",
- .gpio = 105,
- .active_low = 1,
- },
-};
-
-static struct gpio_led_platform_data imote2_led_data = {
- .num_leds = ARRAY_SIZE(imote2_led_pins),
- .leds = imote2_led_pins,
-};
-
-static struct platform_device imote2_leds = {
- .name = "leds-gpio",
- .id = -1,
- .dev = {
- .platform_data = &imote2_led_data,
- },
-};
-
-static struct da903x_subdev_info imote2_da9030_subdevs[] = {
- {
- .name = "da903x-regulator",
- .id = DA9030_ID_LDO2,
- .platform_data = &stargate2_ldo_init_data[vcc_bbio],
- }, {
- .name = "da903x-regulator",
- .id = DA9030_ID_LDO3,
- .platform_data = &stargate2_ldo_init_data[vcc_bb],
- }, {
- .name = "da903x-regulator",
- .id = DA9030_ID_LDO4,
- .platform_data = &stargate2_ldo_init_data[vcc_pxa_flash],
- }, {
- .name = "da903x-regulator",
- .id = DA9030_ID_LDO5,
- .platform_data = &stargate2_ldo_init_data[vcc_cc2420],
- }, {
- .name = "da903x-regulator",
- .id = DA9030_ID_LDO6,
- .platform_data = &stargate2_ldo_init_data[vcc_vref],
- }, {
- .name = "da903x-regulator",
- .id = DA9030_ID_LDO7,
- .platform_data = &stargate2_ldo_init_data[vcc_sram_ext],
- }, {
- .name = "da903x-regulator",
- .id = DA9030_ID_LDO8,
- .platform_data = &stargate2_ldo_init_data[vcc_mica],
- }, {
- .name = "da903x-regulator",
- .id = DA9030_ID_LDO9,
- .platform_data = &stargate2_ldo_init_data[vcc_bt],
- }, {
- .name = "da903x-regulator",
- .id = DA9030_ID_LDO10,
- .platform_data = &stargate2_ldo_init_data[vcc_sensor_1_8],
- }, {
- .name = "da903x-regulator",
- .id = DA9030_ID_LDO11,
- .platform_data = &stargate2_ldo_init_data[vcc_sensor_3],
- }, {
- .name = "da903x-regulator",
- .id = DA9030_ID_LDO12,
- .platform_data = &stargate2_ldo_init_data[vcc_lcd],
- }, {
- .name = "da903x-regulator",
- .id = DA9030_ID_LDO15,
- .platform_data = &stargate2_ldo_init_data[vcc_pxa_pll],
- }, {
- .name = "da903x-regulator",
- .id = DA9030_ID_LDO17,
- .platform_data = &stargate2_ldo_init_data[vcc_pxa_usim],
- }, {
- .name = "da903x-regulator", /*pxa vcc i/o and cc2420 vcc i/o */
- .id = DA9030_ID_LDO18,
- .platform_data = &stargate2_ldo_init_data[vcc_io],
- }, {
- .name = "da903x-regulator",
- .id = DA9030_ID_LDO19,
- .platform_data = &stargate2_ldo_init_data[vcc_pxa_mem],
- },
-};
-
-static struct da903x_platform_data imote2_da9030_pdata = {
- .num_subdevs = ARRAY_SIZE(imote2_da9030_subdevs),
- .subdevs = imote2_da9030_subdevs,
-};
-
-static struct i2c_board_info __initdata imote2_pwr_i2c_board_info[] = {
- {
- .type = "da9030",
- .addr = 0x49,
- .platform_data = &imote2_da9030_pdata,
- .irq = PXA_GPIO_TO_IRQ(1),
- },
-};
-
-static struct i2c_board_info __initdata imote2_i2c_board_info[] = {
- { /* UCAM sensor board */
- .type = "max1239",
- .addr = 0x35,
- }, { /* ITS400 Sensor board only */
- .type = "max1363",
- .addr = 0x34,
- /* Through a nand gate - Also beware, on V2 sensor board the
- * pull up resistors are missing.
- */
- .irq = PXA_GPIO_TO_IRQ(99),
- }, { /* ITS400 Sensor board only */
- .type = "tsl2561",
- .addr = 0x49,
- /* Through a nand gate - Also beware, on V2 sensor board the
- * pull up resistors are missing.
- */
- .irq = PXA_GPIO_TO_IRQ(99),
- }, { /* ITS400 Sensor board only */
- .type = "tmp175",
- .addr = 0x4A,
- .irq = PXA_GPIO_TO_IRQ(96),
- }, { /* IMB400 Multimedia board */
- .type = "wm8940",
- .addr = 0x1A,
- },
-};
-
-static unsigned long imote2_pin_config[] __initdata = {
-
- /* Button */
- GPIO91_GPIO,
-
- /* LEDS */
- GPIO103_GPIO, /* red led */
- GPIO104_GPIO, /* green led */
- GPIO105_GPIO, /* blue led */
-};
-
-static struct pxa2xx_udc_mach_info imote2_udc_info __initdata = {
- .udc_command = sg2_udc_command,
-};
-
-static struct platform_device imote2_audio_device = {
- .name = "imote2-audio",
- .id = -1,
-};
-
-static struct platform_device *imote2_devices[] = {
- &stargate2_flash_device,
- &imote2_leds,
- &sht15,
- &imote2_audio_device,
-};
-
-static void __init imote2_init(void)
-{
- pxa2xx_mfp_config(ARRAY_AND_SIZE(imote2_pin_config));
-
- imote2_stargate2_init();
-
- gpiod_add_lookup_table(&sht15_gpiod_table);
- platform_add_devices(imote2_devices, ARRAY_SIZE(imote2_devices));
-
- i2c_register_board_info(0, imote2_i2c_board_info,
- ARRAY_SIZE(imote2_i2c_board_info));
- i2c_register_board_info(1, imote2_pwr_i2c_board_info,
- ARRAY_SIZE(imote2_pwr_i2c_board_info));
-
- pxa_set_mci_info(&imote2_mci_platform_data);
- pxa_set_udc_info(&imote2_udc_info);
-}
-#endif
-
-#ifdef CONFIG_MACH_STARGATE2
-
-static unsigned long stargate2_pin_config[] __initdata = {
-
- GPIO15_nCS_1, /* SRAM */
- /* SMC91x */
- GPIO80_nCS_4,
- GPIO40_GPIO, /*cable detect?*/
-
- /* Button */
- GPIO91_GPIO | WAKEUP_ON_LEVEL_HIGH,
-
- /* Compact Flash */
- GPIO79_PSKTSEL,
- GPIO48_nPOE,
- GPIO49_nPWE,
- GPIO50_nPIOR,
- GPIO51_nPIOW,
- GPIO85_nPCE_1,
- GPIO54_nPCE_2,
- GPIO55_nPREG,
- GPIO56_nPWAIT,
- GPIO57_nIOIS16,
- GPIO120_GPIO, /* Buff ctrl */
- GPIO108_GPIO, /* Power ctrl */
- GPIO82_GPIO, /* Reset */
- GPIO53_GPIO, /* SG2_S0_GPIO_DETECT */
-
- /* MMC not shared with imote2 */
- GPIO90_GPIO, /* nSD detect */
- GPIO89_GPIO, /* SD_POWER_ENABLE */
-
- /* Bluetooth */
- GPIO81_GPIO, /* reset */
-};
-
-static struct resource smc91x_resources[] = {
- [0] = {
- .name = "smc91x-regs",
- .start = (PXA_CS4_PHYS + 0x300),
- .end = (PXA_CS4_PHYS + 0xfffff),
- .flags = IORESOURCE_MEM,
- },
- [1] = {
- .start = PXA_GPIO_TO_IRQ(40),
- .end = PXA_GPIO_TO_IRQ(40),
- .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
- }
-};
-
-static struct smc91x_platdata stargate2_smc91x_info = {
- .flags = SMC91X_USE_8BIT | SMC91X_USE_16BIT | SMC91X_USE_32BIT
- | SMC91X_NOWAIT | SMC91X_USE_DMA,
- .pxa_u16_align4 = true,
-};
-
-static struct platform_device smc91x_device = {
- .name = "smc91x",
- .id = -1,
- .num_resources = ARRAY_SIZE(smc91x_resources),
- .resource = smc91x_resources,
- .dev = {
- .platform_data = &stargate2_smc91x_info,
- },
-};
-
-
-/*
- * The card detect interrupt isn't debounced so we delay it by 250ms
- * to give the card a chance to fully insert / eject.
- */
-static int stargate2_mci_init(struct device *dev,
- irq_handler_t stargate2_detect_int,
- void *data)
-{
- int err;
-
- err = gpio_request(SG2_SD_POWER_ENABLE, "SG2_sd_power_enable");
- if (err) {
- printk(KERN_ERR "Can't get the gpio for SD power control");
- goto return_err;
- }
- gpio_direction_output(SG2_SD_POWER_ENABLE, 0);
-
- err = gpio_request(SG2_GPIO_nSD_DETECT, "SG2_sd_detect");
- if (err) {
- printk(KERN_ERR "Can't get the sd detect gpio");
- goto free_power_en;
- }
- gpio_direction_input(SG2_GPIO_nSD_DETECT);
-
- err = request_irq(PXA_GPIO_TO_IRQ(SG2_GPIO_nSD_DETECT),
- stargate2_detect_int,
- IRQ_TYPE_EDGE_BOTH,
- "MMC card detect",
- data);
- if (err) {
- printk(KERN_ERR "can't request MMC card detect IRQ\n");
- goto free_nsd_detect;
- }
- return 0;
-
- free_nsd_detect:
- gpio_free(SG2_GPIO_nSD_DETECT);
- free_power_en:
- gpio_free(SG2_SD_POWER_ENABLE);
- return_err:
- return err;
-}
-
-/**
- * stargate2_mci_setpower() - set state of mmc power supply
- *
- * Very simple control. Either it is on or off and is controlled by
- * a gpio pin */
-static int stargate2_mci_setpower(struct device *dev, unsigned int vdd)
-{
- gpio_set_value(SG2_SD_POWER_ENABLE, !!vdd);
- return 0;
-}
-
-static void stargate2_mci_exit(struct device *dev, void *data)
-{
- free_irq(PXA_GPIO_TO_IRQ(SG2_GPIO_nSD_DETECT), data);
- gpio_free(SG2_SD_POWER_ENABLE);
- gpio_free(SG2_GPIO_nSD_DETECT);
-}
-
-static struct pxamci_platform_data stargate2_mci_platform_data = {
- .detect_delay_ms = 250,
- .ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34,
- .init = stargate2_mci_init,
- .setpower = stargate2_mci_setpower,
- .exit = stargate2_mci_exit,
-};
-
-
-/*
- * SRAM - The Stargate 2 has 32MB of SRAM.
- *
- * Here it is made available as an MTD. This will then
- * typically have a cifs filesystem created on it to provide
- * fast temporary storage.
- */
-static struct resource sram_resources = {
- .start = PXA_CS1_PHYS,
- .end = PXA_CS1_PHYS + SZ_32M-1,
- .flags = IORESOURCE_MEM,
-};
-
-static struct platdata_mtd_ram stargate2_sram_pdata = {
- .mapname = "Stargate2 SRAM",
- .bankwidth = 2,
-};
-
-static struct platform_device stargate2_sram = {
- .name = "mtd-ram",
- .id = 0,
- .resource = &sram_resources,
- .num_resources = 1,
- .dev = {
- .platform_data = &stargate2_sram_pdata,
- },
-};
-
-static struct pcf857x_platform_data platform_data_pcf857x = {
- .gpio_base = 128,
- .n_latch = 0,
- .setup = NULL,
- .teardown = NULL,
- .context = NULL,
-};
-
-static const struct property_entry pca9500_eeprom_properties[] = {
- PROPERTY_ENTRY_U32("pagesize", 4),
- { }
-};
-
-static const struct software_node pca9500_eeprom_node = {
- .properties = pca9500_eeprom_properties,
-};
-
-/**
- * stargate2_reset_bluetooth() reset the bluecore to ensure consistent state
- **/
-static int stargate2_reset_bluetooth(void)
-{
- int err;
- err = gpio_request(SG2_BT_RESET, "SG2_BT_RESET");
- if (err) {
- printk(KERN_ERR "Could not get gpio for bluetooth reset\n");
- return err;
- }
- gpio_direction_output(SG2_BT_RESET, 1);
- mdelay(5);
- /* now reset it - 5 msec minimum */
- gpio_set_value(SG2_BT_RESET, 0);
- mdelay(10);
- gpio_set_value(SG2_BT_RESET, 1);
- gpio_free(SG2_BT_RESET);
- return 0;
-}
-
-static struct led_info stargate2_leds[] = {
- {
- .name = "sg2:red",
- .flags = DA9030_LED_RATE_ON,
- }, {
- .name = "sg2:blue",
- .flags = DA9030_LED_RATE_ON,
- }, {
- .name = "sg2:green",
- .flags = DA9030_LED_RATE_ON,
- },
-};
-
-static struct da903x_subdev_info stargate2_da9030_subdevs[] = {
- {
- .name = "da903x-led",
- .id = DA9030_ID_LED_2,
- .platform_data = &stargate2_leds[0],
- }, {
- .name = "da903x-led",
- .id = DA9030_ID_LED_3,
- .platform_data = &stargate2_leds[2],
- }, {
- .name = "da903x-led",
- .id = DA9030_ID_LED_4,
- .platform_data = &stargate2_leds[1],
- }, {
- .name = "da903x-regulator",
- .id = DA9030_ID_LDO2,
- .platform_data = &stargate2_ldo_init_data[vcc_bbio],
- }, {
- .name = "da903x-regulator",
- .id = DA9030_ID_LDO3,
- .platform_data = &stargate2_ldo_init_data[vcc_bb],
- }, {
- .name = "da903x-regulator",
- .id = DA9030_ID_LDO4,
- .platform_data = &stargate2_ldo_init_data[vcc_pxa_flash],
- }, {
- .name = "da903x-regulator",
- .id = DA9030_ID_LDO5,
- .platform_data = &stargate2_ldo_init_data[vcc_cc2420],
- }, {
- .name = "da903x-regulator",
- .id = DA9030_ID_LDO6,
- .platform_data = &stargate2_ldo_init_data[vcc_vref],
- }, {
- .name = "da903x-regulator",
- .id = DA9030_ID_LDO7,
- .platform_data = &stargate2_ldo_init_data[vcc_sram_ext],
- }, {
- .name = "da903x-regulator",
- .id = DA9030_ID_LDO8,
- .platform_data = &stargate2_ldo_init_data[vcc_mica],
- }, {
- .name = "da903x-regulator",
- .id = DA9030_ID_LDO9,
- .platform_data = &stargate2_ldo_init_data[vcc_bt],
- }, {
- .name = "da903x-regulator",
- .id = DA9030_ID_LDO10,
- .platform_data = &stargate2_ldo_init_data[vcc_sensor_1_8],
- }, {
- .name = "da903x-regulator",
- .id = DA9030_ID_LDO11,
- .platform_data = &stargate2_ldo_init_data[vcc_sensor_3],
- }, {
- .name = "da903x-regulator",
- .id = DA9030_ID_LDO12,
- .platform_data = &stargate2_ldo_init_data[vcc_lcd],
- }, {
- .name = "da903x-regulator",
- .id = DA9030_ID_LDO15,
- .platform_data = &stargate2_ldo_init_data[vcc_pxa_pll],
- }, {
- .name = "da903x-regulator",
- .id = DA9030_ID_LDO17,
- .platform_data = &stargate2_ldo_init_data[vcc_pxa_usim],
- }, {
- .name = "da903x-regulator", /*pxa vcc i/o and cc2420 vcc i/o */
- .id = DA9030_ID_LDO18,
- .platform_data = &stargate2_ldo_init_data[vcc_io],
- }, {
- .name = "da903x-regulator",
- .id = DA9030_ID_LDO19,
- .platform_data = &stargate2_ldo_init_data[vcc_pxa_mem],
- },
-};
-
-static struct da903x_platform_data stargate2_da9030_pdata = {
- .num_subdevs = ARRAY_SIZE(stargate2_da9030_subdevs),
- .subdevs = stargate2_da9030_subdevs,
-};
-
-static struct i2c_board_info __initdata stargate2_pwr_i2c_board_info[] = {
- {
- .type = "da9030",
- .addr = 0x49,
- .platform_data = &stargate2_da9030_pdata,
- .irq = PXA_GPIO_TO_IRQ(1),
- },
-};
-
-static struct i2c_board_info __initdata stargate2_i2c_board_info[] = {
- /* Techically this a pca9500 - but it's compatible with the 8574
- * for gpio expansion and the 24c02 for eeprom access.
- */
- {
- .type = "pcf8574",
- .addr = 0x27,
- .platform_data = &platform_data_pcf857x,
- }, {
- .type = "24c02",
- .addr = 0x57,
- .swnode = &pca9500_eeprom_node,
- }, {
- .type = "max1238",
- .addr = 0x35,
- }, { /* ITS400 Sensor board only */
- .type = "max1363",
- .addr = 0x34,
- /* Through a nand gate - Also beware, on V2 sensor board the
- * pull up resistors are missing.
- */
- .irq = PXA_GPIO_TO_IRQ(99),
- }, { /* ITS400 Sensor board only */
- .type = "tsl2561",
- .addr = 0x49,
- /* Through a nand gate - Also beware, on V2 sensor board the
- * pull up resistors are missing.
- */
- .irq = PXA_GPIO_TO_IRQ(99),
- }, { /* ITS400 Sensor board only */
- .type = "tmp175",
- .addr = 0x4A,
- .irq = PXA_GPIO_TO_IRQ(96),
- },
-};
-
-/* Board doesn't support cable detection - so always lie and say
- * something is there.
- */
-static int sg2_udc_detect(void)
-{
- return 1;
-}
-
-static struct pxa2xx_udc_mach_info stargate2_udc_info __initdata = {
- .udc_is_connected = sg2_udc_detect,
- .udc_command = sg2_udc_command,
-};
-
-static struct platform_device *stargate2_devices[] = {
- &stargate2_flash_device,
- &stargate2_sram,
- &smc91x_device,
- &sht15,
-};
-
-static void __init stargate2_init(void)
-{
- /* This is probably a board specific hack as this must be set
- prior to connecting the MFP stuff up. */
- __raw_writel(__raw_readl(MECR) & ~MECR_NOS, MECR);
-
- pxa2xx_mfp_config(ARRAY_AND_SIZE(stargate2_pin_config));
-
- imote2_stargate2_init();
-
- gpiod_add_lookup_table(&sht15_gpiod_table);
- platform_add_devices(ARRAY_AND_SIZE(stargate2_devices));
-
- i2c_register_board_info(0, ARRAY_AND_SIZE(stargate2_i2c_board_info));
- i2c_register_board_info(1, stargate2_pwr_i2c_board_info,
- ARRAY_SIZE(stargate2_pwr_i2c_board_info));
-
- pxa_set_mci_info(&stargate2_mci_platform_data);
-
- pxa_set_udc_info(&stargate2_udc_info);
-
- stargate2_reset_bluetooth();
-}
-#endif
-
-#ifdef CONFIG_MACH_INTELMOTE2
-MACHINE_START(INTELMOTE2, "IMOTE 2")
- .map_io = pxa27x_map_io,
- .nr_irqs = PXA_NR_IRQS,
- .init_irq = pxa27x_init_irq,
- .handle_irq = pxa27x_handle_irq,
- .init_time = pxa_timer_init,
- .init_machine = imote2_init,
- .atag_offset = 0x100,
- .restart = pxa_restart,
-MACHINE_END
-#endif
-
-#ifdef CONFIG_MACH_STARGATE2
-MACHINE_START(STARGATE2, "Stargate 2")
- .map_io = pxa27x_map_io,
- .nr_irqs = STARGATE_NR_IRQS,
- .init_irq = pxa27x_init_irq,
- .handle_irq = pxa27x_handle_irq,
- .init_time = pxa_timer_init,
- .init_machine = stargate2_init,
- .atag_offset = 0x100,
- .restart = pxa_restart,
-MACHINE_END
-#endif
diff --git a/arch/arm/mach-pxa/z2.c b/arch/arm/mach-pxa/z2.c
index 8e74fbb0a96e..7eaeda269927 100644
--- a/arch/arm/mach-pxa/z2.c
+++ b/arch/arm/mach-pxa/z2.c
@@ -570,7 +570,6 @@ static struct pxa2xx_spi_chip z2_lbs_chip_info = {
.rx_threshold = 8,
.tx_threshold = 8,
.timeout = 1000,
- .gpio_cs = GPIO24_ZIPITZ2_WIFI_CS,
};
static struct libertas_spi_platform_data z2_lbs_pdata = {
@@ -584,7 +583,6 @@ static struct pxa2xx_spi_chip lms283_chip_info = {
.rx_threshold = 1,
.tx_threshold = 1,
.timeout = 64,
- .gpio_cs = GPIO88_ZIPITZ2_LCD_CS,
};
static struct gpiod_lookup_table lms283_gpio_table = {
@@ -624,8 +622,26 @@ static struct pxa2xx_spi_controller pxa_ssp2_master_info = {
.num_chipselect = 1,
};
+static struct gpiod_lookup_table pxa_ssp1_gpio_table = {
+ .dev_id = "pxa2xx-spi.1",
+ .table = {
+ GPIO_LOOKUP_IDX("gpio-pxa", GPIO24_ZIPITZ2_WIFI_CS, "cs", 0, GPIO_ACTIVE_LOW),
+ { },
+ },
+};
+
+static struct gpiod_lookup_table pxa_ssp2_gpio_table = {
+ .dev_id = "pxa2xx-spi.2",
+ .table = {
+ GPIO_LOOKUP_IDX("gpio-pxa", GPIO88_ZIPITZ2_LCD_CS, "cs", 0, GPIO_ACTIVE_LOW),
+ { },
+ },
+};
+
static void __init z2_spi_init(void)
{
+ gpiod_add_lookup_table(&pxa_ssp1_gpio_table);
+ gpiod_add_lookup_table(&pxa_ssp2_gpio_table);
pxa2xx_set_spi_info(1, &pxa_ssp1_master_info);
pxa2xx_set_spi_info(2, &pxa_ssp2_master_info);
gpiod_add_lookup_table(&lms283_gpio_table);
diff --git a/arch/arm/mach-qcom/platsmp.c b/arch/arm/mach-qcom/platsmp.c
index 58a4228455ce..65a0d5ce2bb3 100644
--- a/arch/arm/mach-qcom/platsmp.c
+++ b/arch/arm/mach-qcom/platsmp.c
@@ -357,8 +357,7 @@ static void __init qcom_smp_prepare_cpus(unsigned int max_cpus)
{
int cpu;
- if (qcom_scm_set_cold_boot_addr(secondary_startup_arm,
- cpu_present_mask)) {
+ if (qcom_scm_set_cold_boot_addr(secondary_startup_arm)) {
for_each_present_cpu(cpu) {
if (cpu == smp_processor_id())
continue;
diff --git a/arch/arm/mach-rpc/fiq.S b/arch/arm/mach-rpc/fiq.S
index 0de83e9b0b39..087bdf4bc093 100644
--- a/arch/arm/mach-rpc/fiq.S
+++ b/arch/arm/mach-rpc/fiq.S
@@ -2,10 +2,11 @@
#include <linux/linkage.h>
#include <asm/assembler.h>
#include <mach/hardware.h>
-#include <mach/entry-macro.S>
- .text
+ .equ ioc_base_high, IOC_BASE & 0xff000000
+ .equ ioc_base_low, IOC_BASE & 0x00ff0000
+ .text
.global rpc_default_fiq_end
ENTRY(rpc_default_fiq_start)
mov r12, #ioc_base_high
diff --git a/arch/arm/mach-rpc/include/mach/entry-macro.S b/arch/arm/mach-rpc/include/mach/entry-macro.S
deleted file mode 100644
index a6d1a9f4bb79..000000000000
--- a/arch/arm/mach-rpc/include/mach/entry-macro.S
+++ /dev/null
@@ -1,13 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#include <mach/hardware.h>
-#include <asm/hardware/entry-macro-iomd.S>
-
- .equ ioc_base_high, IOC_BASE & 0xff000000
- .equ ioc_base_low, IOC_BASE & 0x00ff0000
-
- .macro get_irqnr_preamble, base, tmp
- mov \base, #ioc_base_high @ point at IOC
- .if ioc_base_low
- orr \base, \base, #ioc_base_low
- .endif
- .endm
diff --git a/arch/arm/mach-rpc/irq.c b/arch/arm/mach-rpc/irq.c
index 803aeb126f0e..dc29384b6ef8 100644
--- a/arch/arm/mach-rpc/irq.c
+++ b/arch/arm/mach-rpc/irq.c
@@ -14,6 +14,99 @@
#define CLR 0x04
#define MASK 0x08
+static const u8 irq_prio_h[256] = {
+ 0, 8, 9, 8,10,10,10,10,11,11,11,11,10,10,10,10,
+ 12, 8, 9, 8,10,10,10,10,11,11,11,11,10,10,10,10,
+ 13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10,
+ 13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10,
+ 14,14,14,14,10,10,10,10,11,11,11,11,10,10,10,10,
+ 14,14,14,14,10,10,10,10,11,11,11,11,10,10,10,10,
+ 13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10,
+ 13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10,
+ 15,15,15,15,10,10,10,10,11,11,11,11,10,10,10,10,
+ 15,15,15,15,10,10,10,10,11,11,11,11,10,10,10,10,
+ 13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10,
+ 13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10,
+ 15,15,15,15,10,10,10,10,11,11,11,11,10,10,10,10,
+ 15,15,15,15,10,10,10,10,11,11,11,11,10,10,10,10,
+ 13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10,
+ 13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10,
+};
+
+static const u8 irq_prio_d[256] = {
+ 0,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16,
+ 20,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16,
+ 21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16,
+ 21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16,
+ 22,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16,
+ 22,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16,
+ 21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16,
+ 21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16,
+ 23,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16,
+ 23,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16,
+ 21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16,
+ 21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16,
+ 22,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16,
+ 22,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16,
+ 21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16,
+ 21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16,
+};
+
+static const u8 irq_prio_l[256] = {
+ 0, 0, 1, 0, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
+ 4, 0, 1, 0, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 6, 6, 6, 6, 6, 6, 6, 6, 3, 3, 3, 3, 3, 3, 3, 3,
+ 6, 6, 6, 6, 6, 6, 6, 6, 3, 3, 3, 3, 3, 3, 3, 3,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+};
+
+static int iomd_get_irq_nr(void)
+{
+ int irq;
+ u8 reg;
+
+ /* get highest priority first */
+ reg = readb(IOC_BASE + IOMD_IRQREQB);
+ irq = irq_prio_h[reg];
+ if (irq)
+ return irq;
+
+ /* get DMA */
+ reg = readb(IOC_BASE + IOMD_DMAREQ);
+ irq = irq_prio_d[reg];
+ if (irq)
+ return irq;
+
+ /* get low priority */
+ reg = readb(IOC_BASE + IOMD_IRQREQA);
+ irq = irq_prio_l[reg];
+ if (irq)
+ return irq;
+ return 0;
+}
+
+static void iomd_handle_irq(struct pt_regs *regs)
+{
+ int irq;
+
+ do {
+ irq = iomd_get_irq_nr();
+ if (irq)
+ generic_handle_irq(irq);
+ } while (irq);
+}
+
static void __iomem *iomd_get_base(struct irq_data *d)
{
void *cd = irq_data_get_irq_chip_data(d);
@@ -82,6 +175,8 @@ void __init rpc_init_irq(void)
set_fiq_handler(&rpc_default_fiq_start,
&rpc_default_fiq_end - &rpc_default_fiq_start);
+ set_handle_irq(iomd_handle_irq);
+
for (irq = 0; irq < NR_IRQS; irq++) {
clr = IRQ_NOREQUEST;
set = 0;
diff --git a/arch/arm/mach-s3c/Kconfig b/arch/arm/mach-s3c/Kconfig
index 25606e668cf9..1899fc3f44fd 100644
--- a/arch/arm/mach-s3c/Kconfig
+++ b/arch/arm/mach-s3c/Kconfig
@@ -191,18 +191,6 @@ config S3C64XX_DEV_SPI0
Compile in platform device definitions for S3C64XX's type
SPI controller 0
-config S3C64XX_DEV_SPI1
- bool
- help
- Compile in platform device definitions for S3C64XX's type
- SPI controller 1
-
-config S3C64XX_DEV_SPI2
- bool
- help
- Compile in platform device definitions for S3C64XX's type
- SPI controller 2
-
config SAMSUNG_DEV_TS
bool
help
diff --git a/arch/arm/mach-s3c/devs.c b/arch/arm/mach-s3c/devs.c
index 06dec64848f9..1e266fc24f9b 100644
--- a/arch/arm/mach-s3c/devs.c
+++ b/arch/arm/mach-s3c/devs.c
@@ -1107,8 +1107,7 @@ struct platform_device s3c64xx_device_spi0 = {
},
};
-void __init s3c64xx_spi0_set_platdata(int (*cfg_gpio)(void), int src_clk_nr,
- int num_cs)
+void __init s3c64xx_spi0_set_platdata(int src_clk_nr, int num_cs)
{
struct s3c64xx_spi_info pd;
@@ -1120,80 +1119,8 @@ void __init s3c64xx_spi0_set_platdata(int (*cfg_gpio)(void), int src_clk_nr,
pd.num_cs = num_cs;
pd.src_clk_nr = src_clk_nr;
- pd.cfg_gpio = (cfg_gpio) ? cfg_gpio : s3c64xx_spi0_cfg_gpio;
+ pd.cfg_gpio = s3c64xx_spi0_cfg_gpio;
s3c_set_platdata(&pd, sizeof(pd), &s3c64xx_device_spi0);
}
#endif /* CONFIG_S3C64XX_DEV_SPI0 */
-
-#ifdef CONFIG_S3C64XX_DEV_SPI1
-static struct resource s3c64xx_spi1_resource[] = {
- [0] = DEFINE_RES_MEM(S3C_PA_SPI1, SZ_256),
- [1] = DEFINE_RES_IRQ(IRQ_SPI1),
-};
-
-struct platform_device s3c64xx_device_spi1 = {
- .name = "s3c6410-spi",
- .id = 1,
- .num_resources = ARRAY_SIZE(s3c64xx_spi1_resource),
- .resource = s3c64xx_spi1_resource,
- .dev = {
- .dma_mask = &samsung_device_dma_mask,
- .coherent_dma_mask = DMA_BIT_MASK(32),
- },
-};
-
-void __init s3c64xx_spi1_set_platdata(int (*cfg_gpio)(void), int src_clk_nr,
- int num_cs)
-{
- struct s3c64xx_spi_info pd;
-
- /* Reject invalid configuration */
- if (!num_cs || src_clk_nr < 0) {
- pr_err("%s: Invalid SPI configuration\n", __func__);
- return;
- }
-
- pd.num_cs = num_cs;
- pd.src_clk_nr = src_clk_nr;
- pd.cfg_gpio = (cfg_gpio) ? cfg_gpio : s3c64xx_spi1_cfg_gpio;
-
- s3c_set_platdata(&pd, sizeof(pd), &s3c64xx_device_spi1);
-}
-#endif /* CONFIG_S3C64XX_DEV_SPI1 */
-
-#ifdef CONFIG_S3C64XX_DEV_SPI2
-static struct resource s3c64xx_spi2_resource[] = {
- [0] = DEFINE_RES_MEM(S3C_PA_SPI2, SZ_256),
- [1] = DEFINE_RES_IRQ(IRQ_SPI2),
-};
-
-struct platform_device s3c64xx_device_spi2 = {
- .name = "s3c6410-spi",
- .id = 2,
- .num_resources = ARRAY_SIZE(s3c64xx_spi2_resource),
- .resource = s3c64xx_spi2_resource,
- .dev = {
- .dma_mask = &samsung_device_dma_mask,
- .coherent_dma_mask = DMA_BIT_MASK(32),
- },
-};
-
-void __init s3c64xx_spi2_set_platdata(int (*cfg_gpio)(void), int src_clk_nr,
- int num_cs)
-{
- struct s3c64xx_spi_info pd;
-
- /* Reject invalid configuration */
- if (!num_cs || src_clk_nr < 0) {
- pr_err("%s: Invalid SPI configuration\n", __func__);
- return;
- }
-
- pd.num_cs = num_cs;
- pd.src_clk_nr = src_clk_nr;
- pd.cfg_gpio = (cfg_gpio) ? cfg_gpio : s3c64xx_spi2_cfg_gpio;
-
- s3c_set_platdata(&pd, sizeof(pd), &s3c64xx_device_spi2);
-}
-#endif /* CONFIG_S3C64XX_DEV_SPI2 */
diff --git a/arch/arm/mach-s3c/mach-crag6410-module.c b/arch/arm/mach-s3c/mach-crag6410-module.c
index 407ad493493e..5d1d4b67a4b7 100644
--- a/arch/arm/mach-s3c/mach-crag6410-module.c
+++ b/arch/arm/mach-s3c/mach-crag6410-module.c
@@ -32,10 +32,6 @@
#include "crag6410.h"
-static struct s3c64xx_spi_csinfo wm0010_spi_csinfo = {
- .line = S3C64XX_GPC(3),
-};
-
static struct wm0010_pdata wm0010_pdata = {
.gpio_reset = S3C64XX_GPN(6),
.reset_active_high = 1, /* Active high for Glenfarclas Rev 2 */
@@ -49,7 +45,6 @@ static struct spi_board_info wm1253_devs[] = {
.chip_select = 0,
.mode = SPI_MODE_0,
.irq = S3C_EINT(4),
- .controller_data = &wm0010_spi_csinfo,
.platform_data = &wm0010_pdata,
},
};
@@ -62,7 +57,6 @@ static struct spi_board_info balblair_devs[] = {
.chip_select = 0,
.mode = SPI_MODE_0,
.irq = S3C_EINT(4),
- .controller_data = &wm0010_spi_csinfo,
.platform_data = &wm0010_pdata,
},
};
@@ -229,10 +223,6 @@ static struct arizona_pdata wm5102_reva_pdata = {
},
};
-static struct s3c64xx_spi_csinfo codec_spi_csinfo = {
- .line = S3C64XX_GPN(5),
-};
-
static struct spi_board_info wm5102_reva_spi_devs[] = {
[0] = {
.modalias = "wm5102",
@@ -242,7 +232,6 @@ static struct spi_board_info wm5102_reva_spi_devs[] = {
.mode = SPI_MODE_0,
.irq = GLENFARCLAS_PMIC_IRQ_BASE +
WM831X_IRQ_GPIO_2,
- .controller_data = &codec_spi_csinfo,
.platform_data = &wm5102_reva_pdata,
},
};
@@ -275,7 +264,6 @@ static struct spi_board_info wm5102_spi_devs[] = {
.mode = SPI_MODE_0,
.irq = GLENFARCLAS_PMIC_IRQ_BASE +
WM831X_IRQ_GPIO_2,
- .controller_data = &codec_spi_csinfo,
.platform_data = &wm5102_pdata,
},
};
@@ -298,7 +286,6 @@ static struct spi_board_info wm5110_spi_devs[] = {
.mode = SPI_MODE_0,
.irq = GLENFARCLAS_PMIC_IRQ_BASE +
WM831X_IRQ_GPIO_2,
- .controller_data = &codec_spi_csinfo,
.platform_data = &wm5102_reva_pdata,
},
};
diff --git a/arch/arm/mach-s3c/mach-crag6410.c b/arch/arm/mach-s3c/mach-crag6410.c
index 4a12c75d407f..e3e0fe897bcc 100644
--- a/arch/arm/mach-s3c/mach-crag6410.c
+++ b/arch/arm/mach-s3c/mach-crag6410.c
@@ -825,6 +825,15 @@ static const struct gpio_led_platform_data gpio_leds_pdata = {
static struct dwc2_hsotg_plat crag6410_hsotg_pdata;
+static struct gpiod_lookup_table crag_spi0_gpiod_table = {
+ .dev_id = "s3c6410-spi.0",
+ .table = {
+ GPIO_LOOKUP_IDX("GPIOC", 3, "cs", 0, GPIO_ACTIVE_LOW),
+ GPIO_LOOKUP_IDX("GPION", 5, "cs", 1, GPIO_ACTIVE_LOW),
+ { },
+ },
+};
+
static void __init crag6410_machine_init(void)
{
/* Open drain IRQs need pullups */
@@ -856,7 +865,9 @@ static void __init crag6410_machine_init(void)
i2c_register_board_info(1, i2c_devs1, ARRAY_SIZE(i2c_devs1));
samsung_keypad_set_platdata(&crag6410_keypad_data);
- s3c64xx_spi0_set_platdata(NULL, 0, 2);
+
+ gpiod_add_lookup_table(&crag_spi0_gpiod_table);
+ s3c64xx_spi0_set_platdata(0, 2);
pwm_add_table(crag6410_pwm_lookup, ARRAY_SIZE(crag6410_pwm_lookup));
platform_add_devices(crag6410_devices, ARRAY_SIZE(crag6410_devices));
diff --git a/arch/arm/mach-s3c/setup-spi-s3c64xx.c b/arch/arm/mach-s3c/setup-spi-s3c64xx.c
index efcf78d41585..497aff71c29c 100644
--- a/arch/arm/mach-s3c/setup-spi-s3c64xx.c
+++ b/arch/arm/mach-s3c/setup-spi-s3c64xx.c
@@ -16,12 +16,3 @@ int s3c64xx_spi0_cfg_gpio(void)
return 0;
}
#endif
-
-#ifdef CONFIG_S3C64XX_DEV_SPI1
-int s3c64xx_spi1_cfg_gpio(void)
-{
- s3c_gpio_cfgall_range(S3C64XX_GPC(4), 3,
- S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
- return 0;
-}
-#endif
diff --git a/arch/arm/mach-s3c/spi-core-s3c24xx.h b/arch/arm/mach-s3c/spi-core-s3c24xx.h
index 057667469cc3..919c5fd0c9af 100644
--- a/arch/arm/mach-s3c/spi-core-s3c24xx.h
+++ b/arch/arm/mach-s3c/spi-core-s3c24xx.h
@@ -16,12 +16,6 @@ static inline void s3c24xx_spi_setname(char *name)
#ifdef CONFIG_S3C64XX_DEV_SPI0
s3c64xx_device_spi0.name = name;
#endif
-#ifdef CONFIG_S3C64XX_DEV_SPI1
- s3c64xx_device_spi1.name = name;
-#endif
-#ifdef CONFIG_S3C64XX_DEV_SPI2
- s3c64xx_device_spi2.name = name;
-#endif
}
#endif /* __PLAT_S3C_SPI_CORE_S3C24XX_H */
diff --git a/arch/arm/mach-shmobile/Kconfig b/arch/arm/mach-shmobile/Kconfig
index 3683d6f10973..50909c4b95b2 100644
--- a/arch/arm/mach-shmobile/Kconfig
+++ b/arch/arm/mach-shmobile/Kconfig
@@ -1,7 +1,7 @@
# SPDX-License-Identifier: GPL-2.0
menuconfig ARCH_RENESAS
bool "Renesas ARM SoCs"
- depends on ARCH_MULTI_V7 && MMU
+ depends on ARCH_MULTI_V7
select ARM_GIC
select GPIOLIB
select NO_IOPORT_MAP
diff --git a/arch/arm/mach-socfpga/Kconfig b/arch/arm/mach-socfpga/Kconfig
index 43ddec677c0b..594edf9bbea4 100644
--- a/arch/arm/mach-socfpga/Kconfig
+++ b/arch/arm/mach-socfpga/Kconfig
@@ -2,6 +2,7 @@
menuconfig ARCH_INTEL_SOCFPGA
bool "Altera SOCFPGA family"
depends on ARCH_MULTI_V7
+ select ARCH_HAS_RESET_CONTROLLER
select ARCH_SUPPORTS_BIG_ENDIAN
select ARM_AMBA
select ARM_GIC
@@ -18,6 +19,7 @@ menuconfig ARCH_INTEL_SOCFPGA
select PL310_ERRATA_727915
select PL310_ERRATA_753970 if PL310
select PL310_ERRATA_769419
+ select RESET_CONTROLLER
if ARCH_INTEL_SOCFPGA
config SOCFPGA_SUSPEND
diff --git a/arch/arm/mach-spear/spear13xx.c b/arch/arm/mach-spear/spear13xx.c
index 74d1ca2a529a..b38391e9d8bf 100644
--- a/arch/arm/mach-spear/spear13xx.c
+++ b/arch/arm/mach-spear/spear13xx.c
@@ -29,7 +29,7 @@ void __init spear13xx_l2x0_init(void)
/*
* 512KB (64KB/way), 8-way associativity, parity supported
*
- * FIXME: 9th bit, of Auxillary Controller register must be set
+ * FIXME: 9th bit, of Auxiliary Controller register must be set
* for some spear13xx devices for stable L2 operation.
*
* Enable Early BRESP, L2 prefetch for Instruction and Data,
diff --git a/arch/arm/mach-ux500/Kconfig b/arch/arm/mach-ux500/Kconfig
index 24ed7f4a87a4..c18def269137 100644
--- a/arch/arm/mach-ux500/Kconfig
+++ b/arch/arm/mach-ux500/Kconfig
@@ -1,7 +1,7 @@
# SPDX-License-Identifier: GPL-2.0
menuconfig ARCH_U8500
bool "ST-Ericsson U8500 Series"
- depends on ARCH_MULTI_V7 && MMU
+ depends on ARCH_MULTI_V7
select AB8500_CORE
select ABX500_CORE
select ARM_AMBA
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig
index 58afba346729..d30ee26ccc87 100644
--- a/arch/arm/mm/Kconfig
+++ b/arch/arm/mm/Kconfig
@@ -386,6 +386,7 @@ config CPU_V6
select CPU_PABRT_V6
select CPU_THUMB_CAPABLE
select CPU_TLB_V6 if MMU
+ select SMP_ON_UP if SMP
# ARMv6k
config CPU_V6K
@@ -830,6 +831,7 @@ config CPU_BPREDICT_DISABLE
config CPU_SPECTRE
bool
+ select GENERIC_CPU_VULNERABILITIES
config HARDEN_BRANCH_PREDICTOR
bool "Harden the branch predictor against aliasing attacks" if EXPERT
@@ -850,6 +852,16 @@ config HARDEN_BRANCH_PREDICTOR
If unsure, say Y.
+config HARDEN_BRANCH_HISTORY
+ bool "Harden Spectre style attacks against branch history" if EXPERT
+ depends on CPU_SPECTRE
+ default y
+ help
+ Speculation attacks against some high-performance processors can
+ make use of branch history to influence future speculation. When
+ taking an exception, a sequence of branches overwrites the branch
+ history, or branch history is invalidated.
+
config TLS_REG_EMUL
bool
select NEED_KUSER_HELPERS
diff --git a/arch/arm/mm/cache-v7.S b/arch/arm/mm/cache-v7.S
index 830bbfb26ca5..7c9499b728c4 100644
--- a/arch/arm/mm/cache-v7.S
+++ b/arch/arm/mm/cache-v7.S
@@ -90,7 +90,7 @@ ENDPROC(v7_flush_icache_all)
*
* Flush the D-cache up to the Level of Unification Inner Shareable
*
- * Corrupted registers: r0-r7, r9-r11 (r6 only in Thumb mode)
+ * Corrupted registers: r0-r6, r9-r10
*/
ENTRY(v7_flush_dcache_louis)
@@ -117,7 +117,7 @@ ENDPROC(v7_flush_dcache_louis)
*
* Flush the whole D-cache.
*
- * Corrupted registers: r0-r7, r9-r11 (r6 only in Thumb mode)
+ * Corrupted registers: r0-r6, r9-r10
*
* - mm - mm_struct describing address space
*/
@@ -149,22 +149,22 @@ flush_levels:
movw r4, #0x3ff
ands r4, r4, r1, lsr #3 @ find maximum number on the way size
clz r5, r4 @ find bit position of way size increment
- movw r7, #0x7fff
- ands r7, r7, r1, lsr #13 @ extract max number of the index size
+ movw r6, #0x7fff
+ and r1, r6, r1, lsr #13 @ extract max number of the index size
+ mov r6, #1
+ movne r4, r4, lsl r5 @ # of ways shifted into bits [31:...]
+ movne r6, r6, lsl r5 @ 1 shifted left by same amount
loop1:
- mov r9, r7 @ create working copy of max index
+ mov r9, r1 @ create working copy of max index
loop2:
- ARM( orr r11, r10, r4, lsl r5 ) @ factor way and cache number into r11
- THUMB( lsl r6, r4, r5 )
- THUMB( orr r11, r10, r6 ) @ factor way and cache number into r11
- ARM( orr r11, r11, r9, lsl r2 ) @ factor index number into r11
- THUMB( lsl r6, r9, r2 )
- THUMB( orr r11, r11, r6 ) @ factor index number into r11
- mcr p15, 0, r11, c7, c14, 2 @ clean & invalidate by set/way
+ mov r5, r9, lsl r2 @ factor set number into r5
+ orr r5, r5, r4 @ factor way number into r5
+ orr r5, r5, r10 @ factor cache level into r5
+ mcr p15, 0, r5, c7, c14, 2 @ clean & invalidate by set/way
subs r9, r9, #1 @ decrement the index
bge loop2
- subs r4, r4, #1 @ decrement the way
- bge loop1
+ subs r4, r4, r6 @ decrement the way
+ bcs loop1
skip:
add r10, r10, #2 @ increment cache number
cmp r3, r10
@@ -192,14 +192,12 @@ ENDPROC(v7_flush_dcache_all)
*
*/
ENTRY(v7_flush_kern_cache_all)
- ARM( stmfd sp!, {r4-r5, r7, r9-r11, lr} )
- THUMB( stmfd sp!, {r4-r7, r9-r11, lr} )
+ stmfd sp!, {r4-r6, r9-r10, lr}
bl v7_flush_dcache_all
mov r0, #0
ALT_SMP(mcr p15, 0, r0, c7, c1, 0) @ invalidate I-cache inner shareable
ALT_UP(mcr p15, 0, r0, c7, c5, 0) @ I+BTB cache invalidate
- ARM( ldmfd sp!, {r4-r5, r7, r9-r11, lr} )
- THUMB( ldmfd sp!, {r4-r7, r9-r11, lr} )
+ ldmfd sp!, {r4-r6, r9-r10, lr}
ret lr
ENDPROC(v7_flush_kern_cache_all)
@@ -210,14 +208,12 @@ ENDPROC(v7_flush_kern_cache_all)
* Invalidate the I-cache to the point of unification.
*/
ENTRY(v7_flush_kern_cache_louis)
- ARM( stmfd sp!, {r4-r5, r7, r9-r11, lr} )
- THUMB( stmfd sp!, {r4-r7, r9-r11, lr} )
+ stmfd sp!, {r4-r6, r9-r10, lr}
bl v7_flush_dcache_louis
mov r0, #0
ALT_SMP(mcr p15, 0, r0, c7, c1, 0) @ invalidate I-cache inner shareable
ALT_UP(mcr p15, 0, r0, c7, c5, 0) @ I+BTB cache invalidate
- ARM( ldmfd sp!, {r4-r5, r7, r9-r11, lr} )
- THUMB( ldmfd sp!, {r4-r7, r9-r11, lr} )
+ ldmfd sp!, {r4-r6, r9-r10, lr}
ret lr
ENDPROC(v7_flush_kern_cache_louis)
diff --git a/arch/arm/mm/context.c b/arch/arm/mm/context.c
index 48091870db89..4204ffa2d104 100644
--- a/arch/arm/mm/context.c
+++ b/arch/arm/mm/context.c
@@ -240,8 +240,7 @@ void check_and_switch_context(struct mm_struct *mm, struct task_struct *tsk)
unsigned int cpu = smp_processor_id();
u64 asid;
- if (unlikely(mm->context.vmalloc_seq != init_mm.context.vmalloc_seq))
- __check_vmalloc_seq(mm);
+ check_vmalloc_seq(mm);
/*
* We cannot update the pgd and the ASID atomicly with classic
diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c
index 6d0cb0f7bc54..fe249ea91908 100644
--- a/arch/arm/mm/init.c
+++ b/arch/arm/mm/init.c
@@ -164,47 +164,6 @@ phys_addr_t __init arm_memblock_steal(phys_addr_t size, phys_addr_t align)
return phys;
}
-static void __init arm_initrd_init(void)
-{
-#ifdef CONFIG_BLK_DEV_INITRD
- phys_addr_t start;
- unsigned long size;
-
- initrd_start = initrd_end = 0;
-
- if (!phys_initrd_size)
- return;
-
- /*
- * Round the memory region to page boundaries as per free_initrd_mem()
- * This allows us to detect whether the pages overlapping the initrd
- * are in use, but more importantly, reserves the entire set of pages
- * as we don't want these pages allocated for other purposes.
- */
- start = round_down(phys_initrd_start, PAGE_SIZE);
- size = phys_initrd_size + (phys_initrd_start - start);
- size = round_up(size, PAGE_SIZE);
-
- if (!memblock_is_region_memory(start, size)) {
- pr_err("INITRD: 0x%08llx+0x%08lx is not a memory region - disabling initrd\n",
- (u64)start, size);
- return;
- }
-
- if (memblock_is_region_reserved(start, size)) {
- pr_err("INITRD: 0x%08llx+0x%08lx overlaps in-use memory region - disabling initrd\n",
- (u64)start, size);
- return;
- }
-
- memblock_reserve(start, size);
-
- /* Now convert initrd to virtual addresses */
- initrd_start = __phys_to_virt(phys_initrd_start);
- initrd_end = initrd_start + phys_initrd_size;
-#endif
-}
-
#ifdef CONFIG_CPU_ICACHE_MISMATCH_WORKAROUND
void check_cpu_icache_size(int cpuid)
{
@@ -226,7 +185,7 @@ void __init arm_memblock_init(const struct machine_desc *mdesc)
/* Register the kernel text, kernel data and initrd with memblock. */
memblock_reserve(__pa(KERNEL_START), KERNEL_END - KERNEL_START);
- arm_initrd_init();
+ reserve_initrd_mem();
arm_mm_memblock_reserve();
diff --git a/arch/arm/mm/ioremap.c b/arch/arm/mm/ioremap.c
index 197f8eb3a775..aa08bcb72db9 100644
--- a/arch/arm/mm/ioremap.c
+++ b/arch/arm/mm/ioremap.c
@@ -117,16 +117,21 @@ EXPORT_SYMBOL(ioremap_page);
void __check_vmalloc_seq(struct mm_struct *mm)
{
- unsigned int seq;
+ int seq;
do {
- seq = init_mm.context.vmalloc_seq;
+ seq = atomic_read(&init_mm.context.vmalloc_seq);
memcpy(pgd_offset(mm, VMALLOC_START),
pgd_offset_k(VMALLOC_START),
sizeof(pgd_t) * (pgd_index(VMALLOC_END) -
pgd_index(VMALLOC_START)));
- mm->context.vmalloc_seq = seq;
- } while (seq != init_mm.context.vmalloc_seq);
+ /*
+ * Use a store-release so that other CPUs that observe the
+ * counter's new value are guaranteed to see the results of the
+ * memcpy as well.
+ */
+ atomic_set_release(&mm->context.vmalloc_seq, seq);
+ } while (seq != atomic_read(&init_mm.context.vmalloc_seq));
}
#if !defined(CONFIG_SMP) && !defined(CONFIG_ARM_LPAE)
@@ -157,7 +162,7 @@ static void unmap_area_sections(unsigned long virt, unsigned long size)
* Note: this is still racy on SMP machines.
*/
pmd_clear(pmdp);
- init_mm.context.vmalloc_seq++;
+ atomic_inc_return_release(&init_mm.context.vmalloc_seq);
/*
* Free the page table, if there was one.
@@ -174,8 +179,7 @@ static void unmap_area_sections(unsigned long virt, unsigned long size)
* Ensure that the active_mm is up to date - we want to
* catch any use-after-iounmap cases.
*/
- if (current->active_mm->context.vmalloc_seq != init_mm.context.vmalloc_seq)
- __check_vmalloc_seq(current->active_mm);
+ check_vmalloc_seq(current->active_mm);
flush_tlb_kernel_range(virt, end);
}
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
index 274e4f73fd33..5e2be37a198e 100644
--- a/arch/arm/mm/mmu.c
+++ b/arch/arm/mm/mmu.c
@@ -212,12 +212,14 @@ early_param("ecc", early_ecc);
static int __init early_cachepolicy(char *p)
{
pr_warn("cachepolicy kernel parameter not supported without cp15\n");
+ return 0;
}
early_param("cachepolicy", early_cachepolicy);
static int __init noalign_setup(char *__unused)
{
pr_warn("noalign kernel parameter not supported without cp15\n");
+ return 1;
}
__setup("noalign", noalign_setup);
diff --git a/arch/arm/mm/proc-v7-bugs.c b/arch/arm/mm/proc-v7-bugs.c
index 114c05ab4dd9..06dbfb968182 100644
--- a/arch/arm/mm/proc-v7-bugs.c
+++ b/arch/arm/mm/proc-v7-bugs.c
@@ -6,8 +6,35 @@
#include <asm/cp15.h>
#include <asm/cputype.h>
#include <asm/proc-fns.h>
+#include <asm/spectre.h>
#include <asm/system_misc.h>
+#ifdef CONFIG_ARM_PSCI
+static int __maybe_unused spectre_v2_get_cpu_fw_mitigation_state(void)
+{
+ struct arm_smccc_res res;
+
+ arm_smccc_1_1_invoke(ARM_SMCCC_ARCH_FEATURES_FUNC_ID,
+ ARM_SMCCC_ARCH_WORKAROUND_1, &res);
+
+ switch ((int)res.a0) {
+ case SMCCC_RET_SUCCESS:
+ return SPECTRE_MITIGATED;
+
+ case SMCCC_ARCH_WORKAROUND_RET_UNAFFECTED:
+ return SPECTRE_UNAFFECTED;
+
+ default:
+ return SPECTRE_VULNERABLE;
+ }
+}
+#else
+static int __maybe_unused spectre_v2_get_cpu_fw_mitigation_state(void)
+{
+ return SPECTRE_VULNERABLE;
+}
+#endif
+
#ifdef CONFIG_HARDEN_BRANCH_PREDICTOR
DEFINE_PER_CPU(harden_branch_predictor_fn_t, harden_branch_predictor_fn);
@@ -36,13 +63,61 @@ static void __maybe_unused call_hvc_arch_workaround_1(void)
arm_smccc_1_1_hvc(ARM_SMCCC_ARCH_WORKAROUND_1, NULL);
}
-static void cpu_v7_spectre_init(void)
+static unsigned int spectre_v2_install_workaround(unsigned int method)
{
const char *spectre_v2_method = NULL;
int cpu = smp_processor_id();
if (per_cpu(harden_branch_predictor_fn, cpu))
- return;
+ return SPECTRE_MITIGATED;
+
+ switch (method) {
+ case SPECTRE_V2_METHOD_BPIALL:
+ per_cpu(harden_branch_predictor_fn, cpu) =
+ harden_branch_predictor_bpiall;
+ spectre_v2_method = "BPIALL";
+ break;
+
+ case SPECTRE_V2_METHOD_ICIALLU:
+ per_cpu(harden_branch_predictor_fn, cpu) =
+ harden_branch_predictor_iciallu;
+ spectre_v2_method = "ICIALLU";
+ break;
+
+ case SPECTRE_V2_METHOD_HVC:
+ per_cpu(harden_branch_predictor_fn, cpu) =
+ call_hvc_arch_workaround_1;
+ cpu_do_switch_mm = cpu_v7_hvc_switch_mm;
+ spectre_v2_method = "hypervisor";
+ break;
+
+ case SPECTRE_V2_METHOD_SMC:
+ per_cpu(harden_branch_predictor_fn, cpu) =
+ call_smc_arch_workaround_1;
+ cpu_do_switch_mm = cpu_v7_smc_switch_mm;
+ spectre_v2_method = "firmware";
+ break;
+ }
+
+ if (spectre_v2_method)
+ pr_info("CPU%u: Spectre v2: using %s workaround\n",
+ smp_processor_id(), spectre_v2_method);
+
+ return SPECTRE_MITIGATED;
+}
+#else
+static unsigned int spectre_v2_install_workaround(unsigned int method)
+{
+ pr_info("CPU%u: Spectre V2: workarounds disabled by configuration\n",
+ smp_processor_id());
+
+ return SPECTRE_VULNERABLE;
+}
+#endif
+
+static void cpu_v7_spectre_v2_init(void)
+{
+ unsigned int state, method = 0;
switch (read_cpuid_part()) {
case ARM_CPU_PART_CORTEX_A8:
@@ -51,69 +126,133 @@ static void cpu_v7_spectre_init(void)
case ARM_CPU_PART_CORTEX_A17:
case ARM_CPU_PART_CORTEX_A73:
case ARM_CPU_PART_CORTEX_A75:
- per_cpu(harden_branch_predictor_fn, cpu) =
- harden_branch_predictor_bpiall;
- spectre_v2_method = "BPIALL";
+ state = SPECTRE_MITIGATED;
+ method = SPECTRE_V2_METHOD_BPIALL;
break;
case ARM_CPU_PART_CORTEX_A15:
case ARM_CPU_PART_BRAHMA_B15:
- per_cpu(harden_branch_predictor_fn, cpu) =
- harden_branch_predictor_iciallu;
- spectre_v2_method = "ICIALLU";
+ state = SPECTRE_MITIGATED;
+ method = SPECTRE_V2_METHOD_ICIALLU;
break;
-#ifdef CONFIG_ARM_PSCI
case ARM_CPU_PART_BRAHMA_B53:
/* Requires no workaround */
+ state = SPECTRE_UNAFFECTED;
break;
+
default:
/* Other ARM CPUs require no workaround */
- if (read_cpuid_implementor() == ARM_CPU_IMP_ARM)
+ if (read_cpuid_implementor() == ARM_CPU_IMP_ARM) {
+ state = SPECTRE_UNAFFECTED;
break;
+ }
+
fallthrough;
- /* Cortex A57/A72 require firmware workaround */
- case ARM_CPU_PART_CORTEX_A57:
- case ARM_CPU_PART_CORTEX_A72: {
- struct arm_smccc_res res;
- arm_smccc_1_1_invoke(ARM_SMCCC_ARCH_FEATURES_FUNC_ID,
- ARM_SMCCC_ARCH_WORKAROUND_1, &res);
- if ((int)res.a0 != 0)
- return;
+ /* Cortex A57/A72 require firmware workaround */
+ case ARM_CPU_PART_CORTEX_A57:
+ case ARM_CPU_PART_CORTEX_A72:
+ state = spectre_v2_get_cpu_fw_mitigation_state();
+ if (state != SPECTRE_MITIGATED)
+ break;
switch (arm_smccc_1_1_get_conduit()) {
case SMCCC_CONDUIT_HVC:
- per_cpu(harden_branch_predictor_fn, cpu) =
- call_hvc_arch_workaround_1;
- cpu_do_switch_mm = cpu_v7_hvc_switch_mm;
- spectre_v2_method = "hypervisor";
+ method = SPECTRE_V2_METHOD_HVC;
break;
case SMCCC_CONDUIT_SMC:
- per_cpu(harden_branch_predictor_fn, cpu) =
- call_smc_arch_workaround_1;
- cpu_do_switch_mm = cpu_v7_smc_switch_mm;
- spectre_v2_method = "firmware";
+ method = SPECTRE_V2_METHOD_SMC;
break;
default:
+ state = SPECTRE_VULNERABLE;
break;
}
}
-#endif
+
+ if (state == SPECTRE_MITIGATED)
+ state = spectre_v2_install_workaround(method);
+
+ spectre_v2_update_state(state, method);
+}
+
+#ifdef CONFIG_HARDEN_BRANCH_HISTORY
+static int spectre_bhb_method;
+
+static const char *spectre_bhb_method_name(int method)
+{
+ switch (method) {
+ case SPECTRE_V2_METHOD_LOOP8:
+ return "loop";
+
+ case SPECTRE_V2_METHOD_BPIALL:
+ return "BPIALL";
+
+ default:
+ return "unknown";
}
+}
- if (spectre_v2_method)
- pr_info("CPU%u: Spectre v2: using %s workaround\n",
- smp_processor_id(), spectre_v2_method);
+static int spectre_bhb_install_workaround(int method)
+{
+ if (spectre_bhb_method != method) {
+ if (spectre_bhb_method) {
+ pr_err("CPU%u: Spectre BHB: method disagreement, system vulnerable\n",
+ smp_processor_id());
+
+ return SPECTRE_VULNERABLE;
+ }
+
+ if (spectre_bhb_update_vectors(method) == SPECTRE_VULNERABLE)
+ return SPECTRE_VULNERABLE;
+
+ spectre_bhb_method = method;
+ }
+
+ pr_info("CPU%u: Spectre BHB: using %s workaround\n",
+ smp_processor_id(), spectre_bhb_method_name(method));
+
+ return SPECTRE_MITIGATED;
}
#else
-static void cpu_v7_spectre_init(void)
+static int spectre_bhb_install_workaround(int method)
{
+ return SPECTRE_VULNERABLE;
}
#endif
+static void cpu_v7_spectre_bhb_init(void)
+{
+ unsigned int state, method = 0;
+
+ switch (read_cpuid_part()) {
+ case ARM_CPU_PART_CORTEX_A15:
+ case ARM_CPU_PART_BRAHMA_B15:
+ case ARM_CPU_PART_CORTEX_A57:
+ case ARM_CPU_PART_CORTEX_A72:
+ state = SPECTRE_MITIGATED;
+ method = SPECTRE_V2_METHOD_LOOP8;
+ break;
+
+ case ARM_CPU_PART_CORTEX_A73:
+ case ARM_CPU_PART_CORTEX_A75:
+ state = SPECTRE_MITIGATED;
+ method = SPECTRE_V2_METHOD_BPIALL;
+ break;
+
+ default:
+ state = SPECTRE_UNAFFECTED;
+ break;
+ }
+
+ if (state == SPECTRE_MITIGATED)
+ state = spectre_bhb_install_workaround(method);
+
+ spectre_v2_update_state(state, method);
+}
+
static __maybe_unused bool cpu_v7_check_auxcr_set(bool *warned,
u32 mask, const char *msg)
{
@@ -142,16 +281,17 @@ static bool check_spectre_auxcr(bool *warned, u32 bit)
void cpu_v7_ca8_ibe(void)
{
if (check_spectre_auxcr(this_cpu_ptr(&spectre_warned), BIT(6)))
- cpu_v7_spectre_init();
+ cpu_v7_spectre_v2_init();
}
void cpu_v7_ca15_ibe(void)
{
if (check_spectre_auxcr(this_cpu_ptr(&spectre_warned), BIT(0)))
- cpu_v7_spectre_init();
+ cpu_v7_spectre_v2_init();
}
void cpu_v7_bugs_init(void)
{
- cpu_v7_spectre_init();
+ cpu_v7_spectre_v2_init();
+ cpu_v7_spectre_bhb_init();
}
diff --git a/arch/arm/net/bpf_jit_32.c b/arch/arm/net/bpf_jit_32.c
index 10ceebb7530b..9e457156ad4d 100644
--- a/arch/arm/net/bpf_jit_32.c
+++ b/arch/arm/net/bpf_jit_32.c
@@ -1864,7 +1864,7 @@ static int build_body(struct jit_ctx *ctx)
if (ctx->target == NULL)
ctx->offsets[i] = ctx->idx;
- /* If unsuccesfull, return with error code */
+ /* If unsuccesful, return with error code */
if (ret)
return ret;
}
@@ -1973,7 +1973,7 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog)
* for jit, although it can decrease the size of the image.
*
* As each arm instruction is of length 32bit, we are translating
- * number of JITed intructions into the size required to store these
+ * number of JITed instructions into the size required to store these
* JITed code.
*/
image_size = sizeof(u32) * ctx.idx;
diff --git a/arch/arm/plat-orion/gpio.c b/arch/arm/plat-orion/gpio.c
index 734f0be4f14a..3ef9ecdd6343 100644
--- a/arch/arm/plat-orion/gpio.c
+++ b/arch/arm/plat-orion/gpio.c
@@ -516,8 +516,7 @@ static void orion_gpio_mask_irq(struct irq_data *d)
irq_gc_unlock(gc);
}
-void __init orion_gpio_init(struct device_node *np,
- int gpio_base, int ngpio,
+void __init orion_gpio_init(int gpio_base, int ngpio,
void __iomem *base, int mask_offset,
int secondary_irq_base,
int irqs[4])
@@ -545,9 +544,6 @@ void __init orion_gpio_init(struct device_node *np,
ochip->chip.base = gpio_base;
ochip->chip.ngpio = ngpio;
ochip->chip.can_sleep = 0;
-#ifdef CONFIG_OF
- ochip->chip.of_node = np;
-#endif
ochip->chip.dbg_show = orion_gpio_dbg_show;
spin_lock_init(&ochip->lock);
@@ -605,7 +601,7 @@ void __init orion_gpio_init(struct device_node *np,
IRQ_NOREQUEST, IRQ_LEVEL | IRQ_NOPROBE);
/* Setup irq domain on top of the generic chip. */
- ochip->domain = irq_domain_add_legacy(np,
+ ochip->domain = irq_domain_add_legacy(NULL,
ochip->chip.ngpio,
ochip->secondary_irq_base,
ochip->secondary_irq_base,
diff --git a/arch/arm/plat-orion/include/plat/orion-gpio.h b/arch/arm/plat-orion/include/plat/orion-gpio.h
index e856b073a9c8..25a2963e0e0f 100644
--- a/arch/arm/plat-orion/include/plat/orion-gpio.h
+++ b/arch/arm/plat-orion/include/plat/orion-gpio.h
@@ -30,8 +30,7 @@ int orion_gpio_led_blink_set(struct gpio_desc *desc, int state,
void orion_gpio_set_valid(unsigned pin, int mode);
/* Initialize gpiolib. */
-void __init orion_gpio_init(struct device_node *np,
- int gpio_base, int ngpio,
+void __init orion_gpio_init(int gpio_base, int ngpio,
void __iomem *base, int mask_offset,
int secondary_irq_base,
int irq[4]);
diff --git a/arch/arm/probes/kprobes/Makefile b/arch/arm/probes/kprobes/Makefile
index 14db56f49f0a..6159010dac4a 100644
--- a/arch/arm/probes/kprobes/Makefile
+++ b/arch/arm/probes/kprobes/Makefile
@@ -1,4 +1,7 @@
# SPDX-License-Identifier: GPL-2.0
+KASAN_SANITIZE_actions-common.o := n
+KASAN_SANITIZE_actions-arm.o := n
+KASAN_SANITIZE_actions-thumb.o := n
obj-$(CONFIG_KPROBES) += core.o actions-common.o checkers-common.o
obj-$(CONFIG_ARM_KPROBES_TEST) += test-kprobes.o
test-kprobes-objs := test-core.o
diff --git a/arch/arm/probes/kprobes/actions-common.c b/arch/arm/probes/kprobes/actions-common.c
index 836aebe596cd..79171344dbeb 100644
--- a/arch/arm/probes/kprobes/actions-common.c
+++ b/arch/arm/probes/kprobes/actions-common.c
@@ -84,7 +84,8 @@ emulate_generic_r0_12_noflags(probes_opcode_t insn,
register void *rfn asm("lr") = asi->insn_fn;
__asm__ __volatile__ (
- "stmdb sp!, {%[regs], r11} \n\t"
+ARM( "stmdb sp!, {%[regs], r11} \n\t" )
+THUMB( "stmdb sp!, {%[regs], r7} \n\t" )
"ldmia %[regs], {r0-r12} \n\t"
#if __LINUX_ARM_ARCH__ >= 6
"blx %[fn] \n\t"
@@ -96,10 +97,11 @@ emulate_generic_r0_12_noflags(probes_opcode_t insn,
#endif
"ldr lr, [sp], #4 \n\t" /* lr = regs */
"stmia lr, {r0-r12} \n\t"
- "ldr r11, [sp], #4 \n\t"
+ARM( "ldr r11, [sp], #4 \n\t" )
+THUMB( "ldr r7, [sp], #4 \n\t" )
: [regs] "=r" (rregs), [fn] "=r" (rfn)
: "0" (rregs), "1" (rfn)
- : "r0", "r2", "r3", "r4", "r5", "r6", "r7",
+ : "r0", "r2", "r3", "r4", "r5", "r6", ARM("r7") THUMB("r11"),
"r8", "r9", "r10", "r12", "memory", "cc"
);
}
diff --git a/arch/arm/probes/kprobes/actions-thumb.c b/arch/arm/probes/kprobes/actions-thumb.c
index 7884fcb81c26..51624fc263fc 100644
--- a/arch/arm/probes/kprobes/actions-thumb.c
+++ b/arch/arm/probes/kprobes/actions-thumb.c
@@ -447,14 +447,16 @@ t16_emulate_loregs(probes_opcode_t insn,
__asm__ __volatile__ (
"msr cpsr_fs, %[oldcpsr] \n\t"
+ "mov r11, r7 \n\t"
"ldmia %[regs], {r0-r7} \n\t"
"blx %[fn] \n\t"
"stmia %[regs], {r0-r7} \n\t"
+ "mov r7, r11 \n\t"
"mrs %[newcpsr], cpsr \n\t"
: [newcpsr] "=r" (newcpsr)
: [oldcpsr] "r" (oldcpsr), [regs] "r" (regs),
[fn] "r" (asi->insn_fn)
- : "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
+ : "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r11",
"lr", "memory", "cc"
);
@@ -524,14 +526,16 @@ t16_emulate_push(probes_opcode_t insn,
struct arch_probes_insn *asi, struct pt_regs *regs)
{
__asm__ __volatile__ (
+ "mov r11, r7 \n\t"
"ldr r9, [%[regs], #13*4] \n\t"
"ldr r8, [%[regs], #14*4] \n\t"
"ldmia %[regs], {r0-r7} \n\t"
"blx %[fn] \n\t"
"str r9, [%[regs], #13*4] \n\t"
+ "mov r7, r11 \n\t"
:
: [regs] "r" (regs), [fn] "r" (asi->insn_fn)
- : "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9",
+ : "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r8", "r9", "r11",
"lr", "memory", "cc"
);
}
@@ -558,14 +562,16 @@ t16_emulate_pop_nopc(probes_opcode_t insn,
struct arch_probes_insn *asi, struct pt_regs *regs)
{
__asm__ __volatile__ (
+ "mov r11, r7 \n\t"
"ldr r9, [%[regs], #13*4] \n\t"
"ldmia %[regs], {r0-r7} \n\t"
"blx %[fn] \n\t"
"stmia %[regs], {r0-r7} \n\t"
"str r9, [%[regs], #13*4] \n\t"
+ "mov r7, r11 \n\t"
:
: [regs] "r" (regs), [fn] "r" (asi->insn_fn)
- : "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r9",
+ : "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r9", "r11",
"lr", "memory", "cc"
);
}
@@ -577,14 +583,16 @@ t16_emulate_pop_pc(probes_opcode_t insn,
register unsigned long pc asm("r8");
__asm__ __volatile__ (
+ "mov r11, r7 \n\t"
"ldr r9, [%[regs], #13*4] \n\t"
"ldmia %[regs], {r0-r7} \n\t"
"blx %[fn] \n\t"
"stmia %[regs], {r0-r7} \n\t"
"str r9, [%[regs], #13*4] \n\t"
+ "mov r7, r11 \n\t"
: "=r" (pc)
: [regs] "r" (regs), [fn] "r" (asi->insn_fn)
- : "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r9",
+ : "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r9", "r11",
"lr", "memory", "cc"
);
diff --git a/arch/arm/vdso/Makefile b/arch/arm/vdso/Makefile
index 7c9e395b77f7..ec52b776f926 100644
--- a/arch/arm/vdso/Makefile
+++ b/arch/arm/vdso/Makefile
@@ -18,7 +18,7 @@ ccflags-y += -DDISABLE_BRANCH_PROFILING -DBUILD_VDSO32
ldflags-$(CONFIG_CPU_ENDIAN_BE8) := --be8
ldflags-y := -Bsymbolic --no-undefined -soname=linux-vdso.so.1 \
- -z max-page-size=4096 -nostdlib -shared $(ldflags-y) \
+ -z max-page-size=4096 -shared $(ldflags-y) \
--hash-style=sysv --build-id=sha1 \
-T
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 6978140edfa4..f8680892401b 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -10,6 +10,7 @@ config ARM64
select ACPI_SPCR_TABLE if ACPI
select ACPI_PPTT if ACPI
select ARCH_HAS_DEBUG_WX
+ select ARCH_BINFMT_ELF_EXTRA_PHDRS
select ARCH_BINFMT_ELF_STATE
select ARCH_CORRECT_STACKTRACE_ON_KRETPROBE
select ARCH_ENABLE_HUGEPAGE_MIGRATION if HUGETLB_PAGE && MIGRATION
@@ -18,6 +19,7 @@ config ARM64
select ARCH_ENABLE_SPLIT_PMD_PTLOCK if PGTABLE_LEVELS > 2
select ARCH_ENABLE_THP_MIGRATION if TRANSPARENT_HUGEPAGE
select ARCH_HAS_CACHE_LINE_SIZE
+ select ARCH_HAS_CURRENT_STACK_POINTER
select ARCH_HAS_DEBUG_VIRTUAL
select ARCH_HAS_DEBUG_VM_PGTABLE
select ARCH_HAS_DMA_PREP_COHERENT
@@ -192,6 +194,7 @@ config ARM64
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_POSIX_CPU_TIMERS_TASK_WORK
select HAVE_FUNCTION_ARG_ACCESS_API
@@ -670,15 +673,43 @@ config ARM64_ERRATUM_1508412
config ARM64_WORKAROUND_TRBE_OVERWRITE_FILL_MODE
bool
+config ARM64_ERRATUM_2051678
+ bool "Cortex-A510: 2051678: disable Hardware Update of the page table dirty bit"
+ default y
+ help
+ This options adds the workaround for ARM Cortex-A510 erratum ARM64_ERRATUM_2051678.
+ Affected Coretex-A510 might not respect the ordering rules for
+ hardware update of the page table's dirty bit. The workaround
+ is to not enable the feature on affected CPUs.
+
+ If unsure, say Y.
+
+config ARM64_ERRATUM_2077057
+ bool "Cortex-A510: 2077057: workaround software-step corrupting SPSR_EL2"
+ default y
+ help
+ This option adds the workaround for ARM Cortex-A510 erratum 2077057.
+ Affected Cortex-A510 may corrupt SPSR_EL2 when the a step exception is
+ expected, but a Pointer Authentication trap is taken instead. The
+ erratum causes SPSR_EL1 to be copied to SPSR_EL2, which could allow
+ EL1 to cause a return to EL2 with a guest controlled ELR_EL2.
+
+ This can only happen when EL2 is stepping EL1.
+
+ When these conditions occur, the SPSR_EL2 value is unchanged from the
+ previous guest entry, and can be restored from the in-memory copy.
+
+ If unsure, say Y.
+
config ARM64_ERRATUM_2119858
- bool "Cortex-A710: 2119858: workaround TRBE overwriting trace data in FILL mode"
+ bool "Cortex-A710/X2: 2119858: workaround TRBE overwriting trace data in FILL mode"
default y
depends on CORESIGHT_TRBE
select ARM64_WORKAROUND_TRBE_OVERWRITE_FILL_MODE
help
- This option adds the workaround for ARM Cortex-A710 erratum 2119858.
+ This option adds the workaround for ARM Cortex-A710/X2 erratum 2119858.
- Affected Cortex-A710 cores could overwrite up to 3 cache lines of trace
+ Affected Cortex-A710/X2 cores could overwrite up to 3 cache lines of trace
data at the base of the buffer (pointed to by TRBASER_EL1) in FILL mode in
the event of a WRAP event.
@@ -761,14 +792,14 @@ config ARM64_ERRATUM_2253138
If unsure, say Y.
config ARM64_ERRATUM_2224489
- bool "Cortex-A710: 2224489: workaround TRBE writing to address out-of-range"
+ bool "Cortex-A710/X2: 2224489: workaround TRBE writing to address out-of-range"
depends on CORESIGHT_TRBE
default y
select ARM64_WORKAROUND_TRBE_WRITE_OUT_OF_RANGE
help
- This option adds the workaround for ARM Cortex-A710 erratum 2224489.
+ This option adds the workaround for ARM Cortex-A710/X2 erratum 2224489.
- Affected Cortex-A710 cores might write to an out-of-range address, not reserved
+ Affected Cortex-A710/X2 cores might write to an out-of-range address, not reserved
for TRBE. Under some conditions, the TRBE might generate a write to the next
virtually addressed page following the last page of the TRBE address space
(i.e., the TRBLIMITR_EL1.LIMIT), instead of wrapping around to the base.
@@ -778,6 +809,65 @@ config ARM64_ERRATUM_2224489
If unsure, say Y.
+config ARM64_ERRATUM_2064142
+ bool "Cortex-A510: 2064142: workaround TRBE register writes while disabled"
+ depends on COMPILE_TEST # Until the CoreSight TRBE driver changes are in
+ default y
+ help
+ This option adds the workaround for ARM Cortex-A510 erratum 2064142.
+
+ Affected Cortex-A510 core might fail to write into system registers after the
+ TRBE has been disabled. Under some conditions after the TRBE has been disabled
+ writes into TRBE registers TRBLIMITR_EL1, TRBPTR_EL1, TRBBASER_EL1, TRBSR_EL1,
+ and TRBTRG_EL1 will be ignored and will not be effected.
+
+ Work around this in the driver by executing TSB CSYNC and DSB after collection
+ is stopped and before performing a system register write to one of the affected
+ registers.
+
+ If unsure, say Y.
+
+config ARM64_ERRATUM_2038923
+ bool "Cortex-A510: 2038923: workaround TRBE corruption with enable"
+ depends on COMPILE_TEST # Until the CoreSight TRBE driver changes are in
+ default y
+ help
+ This option adds the workaround for ARM Cortex-A510 erratum 2038923.
+
+ Affected Cortex-A510 core might cause an inconsistent view on whether trace is
+ prohibited within the CPU. As a result, the trace buffer or trace buffer state
+ might be corrupted. This happens after TRBE buffer has been enabled by setting
+ TRBLIMITR_EL1.E, followed by just a single context synchronization event before
+ execution changes from a context, in which trace is prohibited to one where it
+ isn't, or vice versa. In these mentioned conditions, the view of whether trace
+ is prohibited is inconsistent between parts of the CPU, and the trace buffer or
+ the trace buffer state might be corrupted.
+
+ Work around this in the driver by preventing an inconsistent view of whether the
+ trace is prohibited or not based on TRBLIMITR_EL1.E by immediately following a
+ change to TRBLIMITR_EL1.E with at least one ISB instruction before an ERET, or
+ two ISB instructions if no ERET is to take place.
+
+ If unsure, say Y.
+
+config ARM64_ERRATUM_1902691
+ bool "Cortex-A510: 1902691: workaround TRBE trace corruption"
+ depends on COMPILE_TEST # Until the CoreSight TRBE driver changes are in
+ default y
+ help
+ This option adds the workaround for ARM Cortex-A510 erratum 1902691.
+
+ Affected Cortex-A510 core might cause trace data corruption, when being written
+ into the memory. Effectively TRBE is broken and hence cannot be used to capture
+ trace data.
+
+ Work around this problem in the driver by just preventing TRBE initialization on
+ affected cpus. The firmware must have disabled the access to TRBE for the kernel
+ on such implementations. This will cover the kernel for any firmware that doesn't
+ do this already.
+
+ If unsure, say Y.
+
config CAVIUM_ERRATUM_22375
bool "Cavium erratum 22375, 24313"
default y
@@ -805,13 +895,17 @@ config CAVIUM_ERRATUM_23144
If unsure, say Y.
config CAVIUM_ERRATUM_23154
- bool "Cavium erratum 23154: Access to ICC_IAR1_EL1 is not sync'ed"
+ bool "Cavium errata 23154 and 38545: GICv3 lacks HW synchronisation"
default y
help
- The gicv3 of ThunderX requires a modified version for
+ The ThunderX GICv3 implementation requires a modified version for
reading the IAR status to ensure data synchronization
(access to icc_iar1_el1 is not sync'ed before and after).
+ It also suffers from erratum 38545 (also present on Marvell's
+ OcteonTX and OcteonTX2), resulting in deactivated interrupts being
+ spuriously presented to the CPU interface.
+
If unsure, say Y.
config CAVIUM_ERRATUM_27456
@@ -1166,10 +1260,7 @@ config HW_PERF_EVENTS
def_bool y
depends on ARM_PMU
-config ARCH_HAS_FILTER_PGPROT
- def_bool y
-
-# Supported by clang >= 7.0
+# Supported by clang >= 7.0 or GCC >= 12.0.0
config CC_HAVE_SHADOW_CALL_STACK
def_bool $(cc-option, -fsanitize=shadow-call-stack -ffixed-x18)
@@ -1297,6 +1388,15 @@ config UNMAP_KERNEL_AT_EL0
If unsure, say Y.
+config MITIGATE_SPECTRE_BRANCH_HISTORY
+ bool "Mitigate Spectre style attacks against branch history" if EXPERT
+ default y
+ help
+ Speculation attacks against some high-performance processors can
+ make use of branch history to influence future speculation.
+ When taking an exception from user-space, a sequence of branches
+ or a firmware call overwrites the branch history.
+
config RODATA_FULL_DEFAULT_ENABLED
bool "Apply r/o permissions of VM areas also to their linear aliases"
default y
diff --git a/arch/arm64/Kconfig.platforms b/arch/arm64/Kconfig.platforms
index 7d5d58800170..30b123cde02c 100644
--- a/arch/arm64/Kconfig.platforms
+++ b/arch/arm64/Kconfig.platforms
@@ -268,6 +268,12 @@ config ARCH_TEGRA
help
This enables support for the NVIDIA Tegra SoC family.
+config ARCH_TESLA_FSD
+ bool "ARMv8 based Tesla platform"
+ depends on ARCH_EXYNOS
+ help
+ Support for ARMv8 based Tesla platforms.
+
config ARCH_SPRD
bool "Spreadtrum SoC platform"
help
@@ -309,9 +315,6 @@ config ARCH_VISCONTI
help
This enables support for Toshiba Visconti SoCs Family.
-config ARCH_VULCAN
- def_bool n
-
config ARCH_XGENE
bool "AppliedMicro X-Gene SOC Family"
help
diff --git a/arch/arm64/boot/dts/Makefile b/arch/arm64/boot/dts/Makefile
index 639e01a4d855..1ba04e31a438 100644
--- a/arch/arm64/boot/dts/Makefile
+++ b/arch/arm64/boot/dts/Makefile
@@ -27,6 +27,7 @@ subdir-y += rockchip
subdir-y += socionext
subdir-y += sprd
subdir-y += synaptics
+subdir-y += tesla
subdir-y += ti
subdir-y += toshiba
subdir-y += xilinx
diff --git a/arch/arm64/boot/dts/altera/socfpga_stratix10.dtsi b/arch/arm64/boot/dts/altera/socfpga_stratix10.dtsi
index 3ec301bd08a9..884bda106399 100644
--- a/arch/arm64/boot/dts/altera/socfpga_stratix10.dtsi
+++ b/arch/arm64/boot/dts/altera/socfpga_stratix10.dtsi
@@ -77,6 +77,16 @@
method = "smc";
};
+ /* Local timer */
+ timer {
+ compatible = "arm,armv8-timer";
+ interrupts = <1 13 0xf08>,
+ <1 14 0xf08>,
+ <1 11 0xf08>,
+ <1 10 0xf08>;
+ interrupt-parent = <&intc>;
+ };
+
intc: interrupt-controller@fffc1000 {
compatible = "arm,gic-400", "arm,cortex-a15-gic";
#interrupt-cells = <3>;
@@ -286,7 +296,7 @@
status = "disabled";
};
- mmc: dwmmc0@ff808000 {
+ mmc: mmc@ff808000 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "altr,socfpga-dw-mshc";
@@ -323,7 +333,7 @@
reg = <0xffe00000 0x100000>;
};
- pdma: pdma@ffda0000 {
+ pdma: dma-controller@ffda0000 {
compatible = "arm,pl330", "arm,primecell";
reg = <0xffda0000 0x1000>;
interrupts = <0 81 4>,
@@ -406,15 +416,6 @@
reg = <0xffd12000 0x228>;
};
- /* Local timer */
- timer {
- compatible = "arm,armv8-timer";
- interrupts = <1 13 0xf08>,
- <1 14 0xf08>,
- <1 11 0xf08>,
- <1 10 0xf08>;
- };
-
timer0: timer0@ffc03000 {
compatible = "snps,dw-apb-timer";
interrupts = <0 113 4>;
@@ -484,6 +485,7 @@
resets = <&rst USB0_RESET>, <&rst USB0_OCP_RESET>;
reset-names = "dwc2", "dwc2-ecc";
clocks = <&clkmgr STRATIX10_USB_CLK>;
+ clock-names = "otg";
iommus = <&smmu 6>;
status = "disabled";
};
diff --git a/arch/arm64/boot/dts/altera/socfpga_stratix10_socdk.dts b/arch/arm64/boot/dts/altera/socfpga_stratix10_socdk.dts
index 46e558ab7729..5159cd5771dc 100644
--- a/arch/arm64/boot/dts/altera/socfpga_stratix10_socdk.dts
+++ b/arch/arm64/boot/dts/altera/socfpga_stratix10_socdk.dts
@@ -7,6 +7,7 @@
/ {
model = "SoCFPGA Stratix 10 SoCDK";
+ compatible = "altr,socfpga-stratix10-socdk", "altr,socfpga-stratix10";
aliases {
serial0 = &uart0;
@@ -43,7 +44,7 @@
reg = <0 0 0 0>;
};
- ref_033v: 033-v-ref {
+ ref_033v: regulator-v-ref {
compatible = "regulator-fixed";
regulator-name = "0.33V";
regulator-min-microvolt = <330000>;
diff --git a/arch/arm64/boot/dts/altera/socfpga_stratix10_socdk_nand.dts b/arch/arm64/boot/dts/altera/socfpga_stratix10_socdk_nand.dts
index bbc3db42d6e8..0ab676c639a1 100644
--- a/arch/arm64/boot/dts/altera/socfpga_stratix10_socdk_nand.dts
+++ b/arch/arm64/boot/dts/altera/socfpga_stratix10_socdk_nand.dts
@@ -7,6 +7,7 @@
/ {
model = "SoCFPGA Stratix 10 SoCDK";
+ compatible = "altr,socfpga-stratix10-socdk", "altr,socfpga-stratix10";
aliases {
serial0 = &uart0;
@@ -43,7 +44,7 @@
reg = <0 0 0 0>;
};
- ref_033v: 033-v-ref {
+ ref_033v: regulator-v-ref {
compatible = "regulator-fixed";
regulator-name = "0.33V";
regulator-min-microvolt = <330000>;
diff --git a/arch/arm64/boot/dts/amlogic/Makefile b/arch/arm64/boot/dts/amlogic/Makefile
index 5148cd9e5146..0eec18678311 100644
--- a/arch/arm64/boot/dts/amlogic/Makefile
+++ b/arch/arm64/boot/dts/amlogic/Makefile
@@ -36,6 +36,7 @@ dtb-$(CONFIG_ARCH_MESON) += meson-gxl-s905d-p230.dtb
dtb-$(CONFIG_ARCH_MESON) += meson-gxl-s905d-p231.dtb
dtb-$(CONFIG_ARCH_MESON) += meson-gxl-s905d-phicomm-n1.dtb
dtb-$(CONFIG_ARCH_MESON) += meson-gxl-s905d-sml5442tw.dtb
+dtb-$(CONFIG_ARCH_MESON) += meson-gxl-s905d-vero4k-plus.dtb
dtb-$(CONFIG_ARCH_MESON) += meson-gxl-s805x-p241.dtb
dtb-$(CONFIG_ARCH_MESON) += meson-gxl-s905w-p281.dtb
dtb-$(CONFIG_ARCH_MESON) += meson-gxl-s905w-tx3-mini.dtb
@@ -51,9 +52,15 @@ dtb-$(CONFIG_ARCH_MESON) += meson-gxm-rbox-pro.dtb
dtb-$(CONFIG_ARCH_MESON) += meson-gxm-s912-libretech-pc.dtb
dtb-$(CONFIG_ARCH_MESON) += meson-gxm-vega-s96.dtb
dtb-$(CONFIG_ARCH_MESON) += meson-gxm-wetek-core2.dtb
+dtb-$(CONFIG_ARCH_MESON) += meson-sm1-a95xf3-air.dtb
+dtb-$(CONFIG_ARCH_MESON) += meson-sm1-a95xf3-air-gbit.dtb
dtb-$(CONFIG_ARCH_MESON) += meson-sm1-bananapi-m5.dtb
+dtb-$(CONFIG_ARCH_MESON) += meson-sm1-h96-max.dtb
dtb-$(CONFIG_ARCH_MESON) += meson-sm1-khadas-vim3l.dtb
dtb-$(CONFIG_ARCH_MESON) += meson-sm1-odroid-c4.dtb
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.dtb
+dtb-$(CONFIG_ARCH_MESON) += meson-sm1-x96-air-gbit.dtb
dtb-$(CONFIG_ARCH_MESON) += meson-a1-ad401.dtb
+dtb-$(CONFIG_ARCH_MESON) += meson-s4-s805x2-aq222.dtb
diff --git a/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi b/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi
index 517519e6e87f..45947c1031c4 100644
--- a/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi
@@ -107,6 +107,12 @@
no-map;
};
+ /* 32 MiB reserved for ARM Trusted Firmware (BL32) */
+ secmon_reserved_bl32: secmon@5300000 {
+ reg = <0x0 0x05300000 0x0 0x2000000>;
+ no-map;
+ };
+
linux,cma {
compatible = "shared-dma-pool";
reusable;
@@ -839,6 +845,22 @@
};
};
+ pwm_f_z_pins: pwm-f-z {
+ mux {
+ groups = "pwm_f_z";
+ function = "pwm_f";
+ bias-disable;
+ };
+ };
+
+ pwm_f_a_pins: pwm-f-a {
+ mux {
+ groups = "pwm_f_a";
+ function = "pwm_f";
+ bias-disable;
+ };
+ };
+
pwm_f_x_pins: pwm-f-x {
mux {
groups = "pwm_f_x";
@@ -1881,6 +1903,33 @@
};
};
+ uart_ao_b_2_3_pins: uart-ao-b-2-3 {
+ mux {
+ groups = "uart_ao_b_tx_2",
+ "uart_ao_b_rx_3";
+ function = "uart_ao_b";
+ bias-disable;
+ };
+ };
+
+ uart_ao_b_8_9_pins: uart-ao-b-8-9 {
+ mux {
+ groups = "uart_ao_b_tx_8",
+ "uart_ao_b_rx_9";
+ function = "uart_ao_b";
+ bias-disable;
+ };
+ };
+
+ uart_ao_b_cts_rts_pins: uart-ao-b-cts-rts {
+ mux {
+ groups = "uart_ao_b_cts",
+ "uart_ao_b_rts";
+ function = "uart_ao_b";
+ bias-disable;
+ };
+ };
+
pwm_a_e_pins: pwm-a-e {
mux {
groups = "pwm_a_e";
diff --git a/arch/arm64/boot/dts/amlogic/meson-g12a-sei510.dts b/arch/arm64/boot/dts/amlogic/meson-g12a-sei510.dts
index d8838dde0f0f..4fb31c2ba31c 100644
--- a/arch/arm64/boot/dts/amlogic/meson-g12a-sei510.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-g12a-sei510.dts
@@ -157,14 +157,6 @@
regulator-always-on;
};
- reserved-memory {
- /* TEE Reserved Memory */
- bl32_reserved: bl32@5000000 {
- reg = <0x0 0x05300000 0x0 0x2000000>;
- no-map;
- };
- };
-
sdio_pwrseq: sdio-pwrseq {
compatible = "mmc-pwrseq-simple";
reset-gpios = <&gpio GPIOX_6 GPIO_ACTIVE_LOW>;
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 3e968b244191..fd3fa82e4c33 100644
--- a/arch/arm64/boot/dts/amlogic/meson-g12b-odroid-n2.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-g12b-odroid-n2.dtsi
@@ -17,7 +17,7 @@
rtc1 = &vrtc;
};
- dioo2133: audio-amplifier-0 {
+ dio2133: audio-amplifier-0 {
compatible = "simple-audio-amplifier";
enable-gpios = <&gpio_ao GPIOAO_2 GPIO_ACTIVE_HIGH>;
VCC-supply = <&vcc_5v>;
@@ -219,7 +219,7 @@
audio-widgets = "Line", "Lineout";
audio-aux-devs = <&tdmout_b>, <&tdmout_c>, <&tdmin_a>,
<&tdmin_b>, <&tdmin_c>, <&tdmin_lb>,
- <&dioo2133>;
+ <&dio2133>;
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",
diff --git a/arch/arm64/boot/dts/amlogic/meson-gx.dtsi b/arch/arm64/boot/dts/amlogic/meson-gx.dtsi
index 6b457b2c30a4..aa14ea017a61 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gx.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-gx.dtsi
@@ -49,6 +49,12 @@
no-map;
};
+ /* 32 MiB reserved for ARM Trusted Firmware (BL32) */
+ secmon_reserved_bl32: secmon@5300000 {
+ reg = <0x0 0x05300000 0x0 0x2000000>;
+ no-map;
+ };
+
linux,cma {
compatible = "shared-dma-pool";
reusable;
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905d-vero4k-plus.dts b/arch/arm64/boot/dts/amlogic/meson-gxl-s905d-vero4k-plus.dts
new file mode 100644
index 000000000000..4b0ff707e21b
--- /dev/null
+++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905d-vero4k-plus.dts
@@ -0,0 +1,117 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Author: Christian Hewitt <christianshewitt@gmail.com>
+ */
+
+/dts-v1/;
+
+#include "meson-gxl-s905d.dtsi"
+#include "meson-gx-p23x-q20x.dtsi"
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/leds/common.h>
+
+/ {
+ compatible = "osmc,vero4k-plus", "amlogic,s905d", "amlogic,meson-gxl";
+ model = "OSMC Vero 4K Plus";
+
+ gpio-keys-polled {
+ compatible = "gpio-keys-polled";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ poll-interval = <20>;
+
+ button@0 {
+ label = "power";
+ linux,code = <KEY_POWER>;
+ gpios = <&gpio_ao GPIOAO_2 GPIO_ACTIVE_HIGH>;
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ led-standby {
+ color = <LED_COLOR_ID_RED>;
+ function = LED_FUNCTION_POWER;
+ gpios = <&gpio_ao GPIOAO_9 GPIO_ACTIVE_LOW>;
+ default-state = "off";
+ panic-indicator;
+ };
+ };
+};
+
+&ethmac {
+ pinctrl-0 = <&eth_pins>;
+ pinctrl-names = "default";
+
+ phy-mode = "rgmii-txid";
+ phy-handle = <&external_phy>;
+
+ amlogic,tx-delay-ns = <0>;
+};
+
+&external_mdio {
+ external_phy: ethernet-phy@0 {
+ /* Realtek RTL8211F (0x001cc916) */
+ pinctrl-0 = <&eth_phy_irq_pin>;
+ pinctrl-names = "default";
+
+ reg = <0>;
+ max-speed = <1000>;
+
+ reset-assert-us = <10000>;
+ reset-deassert-us = <80000>;
+ reset-gpios = <&gpio GPIOZ_14 GPIO_ACTIVE_LOW>;
+
+ interrupt-parent = <&gpio_intc>;
+ interrupts = <25 IRQ_TYPE_LEVEL_LOW>;
+ };
+};
+
+&pinctrl_periphs {
+ /* Ensure the phy irq pin is properly configured as input */
+ eth_phy_irq_pin: eth-phy-irq {
+ mux {
+ groups = "GPIOZ_15";
+ function = "gpio_periphs";
+ bias-disable;
+ output-disable;
+ };
+ };
+};
+
+&sd_emmc_a {
+ brcmf: wifi@1 {
+ reg = <1>;
+ compatible = "brcm,bcm4329-fmac";
+ };
+};
+
+&uart_A {
+ status = "okay";
+ pinctrl-0 = <&uart_a_pins>, <&uart_a_cts_rts_pins>;
+ pinctrl-names = "default";
+ uart-has-rtscts;
+
+ bluetooth {
+ compatible = "brcm,bcm43438-bt";
+ shutdown-gpios = <&gpio GPIOX_17 GPIO_ACTIVE_HIGH>;
+ max-speed = <2000000>;
+ clocks = <&wifi32k>;
+ clock-names = "lpo";
+ };
+};
+
+&usb {
+ dr_mode = "host";
+};
+
+&usb2_phy0 {
+ /* HDMI_5V also supplies the USB VBUS */
+ phy-supply = <&hdmi_5v>;
+};
+
+&usb2_phy0 {
+ /* HDMI_5V also supplies the USB VBUS */
+ phy-supply = <&hdmi_5v>;
+};
diff --git a/arch/arm64/boot/dts/amlogic/meson-s4-s805x2-aq222.dts b/arch/arm64/boot/dts/amlogic/meson-s4-s805x2-aq222.dts
new file mode 100644
index 000000000000..8ffbcb2b1ac5
--- /dev/null
+++ b/arch/arm64/boot/dts/amlogic/meson-s4-s805x2-aq222.dts
@@ -0,0 +1,30 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2021 Amlogic, Inc. All rights reserved.
+ */
+
+/dts-v1/;
+
+#include "meson-s4.dtsi"
+
+/ {
+ model = "Amlogic Meson S4 AQ222 Development Board";
+ compatible = "amlogic,aq222", "amlogic,s4";
+ interrupt-parent = <&gic>;
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ aliases {
+ serial0 = &uart_B;
+ };
+
+ memory@0 {
+ device_type = "memory";
+ reg = <0x0 0x0 0x0 0x40000000>;
+ };
+
+};
+
+&uart_B {
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/amlogic/meson-s4.dtsi b/arch/arm64/boot/dts/amlogic/meson-s4.dtsi
new file mode 100644
index 000000000000..bf9ae1e1016b
--- /dev/null
+++ b/arch/arm64/boot/dts/amlogic/meson-s4.dtsi
@@ -0,0 +1,99 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2021 Amlogic, Inc. All rights reserved.
+ */
+
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+/ {
+ cpus {
+ #address-cells = <2>;
+ #size-cells = <0>;
+
+ cpu0: cpu@0 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a35","arm,armv8";
+ reg = <0x0 0x0>;
+ enable-method = "psci";
+ };
+
+ cpu1: cpu@1 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a35","arm,armv8";
+ reg = <0x0 0x1>;
+ enable-method = "psci";
+ };
+
+ cpu2: cpu@2 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a35","arm,armv8";
+ reg = <0x0 0x2>;
+ enable-method = "psci";
+ };
+
+ cpu3: cpu@3 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a35","arm,armv8";
+ reg = <0x0 0x3>;
+ enable-method = "psci";
+ };
+ };
+
+ timer {
+ compatible = "arm,armv8-timer";
+ interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+ <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+ <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+ <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>;
+ };
+
+ psci {
+ compatible = "arm,psci-1.0";
+ method = "smc";
+ };
+
+ xtal: xtal-clk {
+ compatible = "fixed-clock";
+ clock-frequency = <24000000>;
+ clock-output-names = "xtal";
+ #clock-cells = <0>;
+ };
+
+ soc {
+ compatible = "simple-bus";
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ gic: interrupt-controller@fff01000 {
+ compatible = "arm,gic-400";
+ #interrupt-cells = <3>;
+ #address-cells = <0>;
+ interrupt-controller;
+ reg = <0x0 0xfff01000 0 0x1000>,
+ <0x0 0xfff02000 0 0x2000>,
+ <0x0 0xfff04000 0 0x2000>,
+ <0x0 0xfff06000 0 0x2000>;
+ interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
+ };
+
+ apb4: apb4@fe000000 {
+ compatible = "simple-bus";
+ reg = <0x0 0xfe000000 0x0 0x480000>;
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges = <0x0 0x0 0x0 0xfe000000 0x0 0x480000>;
+
+ uart_B: serial@7a000 {
+ compatible = "amlogic,meson-s4-uart",
+ "amlogic,meson-ao-uart";
+ reg = <0x0 0x7a000 0x0 0x18>;
+ interrupts = <GIC_SPI 169 IRQ_TYPE_EDGE_RISING>;
+ status = "disabled";
+ clocks = <&xtal>, <&xtal>, <&xtal>;
+ clock-names = "xtal", "pclk", "baud";
+ };
+ };
+ };
+};
diff --git a/arch/arm64/boot/dts/amlogic/meson-sm1-a95xf3-air-gbit.dts b/arch/arm64/boot/dts/amlogic/meson-sm1-a95xf3-air-gbit.dts
new file mode 100644
index 000000000000..d1debccdc1c2
--- /dev/null
+++ b/arch/arm64/boot/dts/amlogic/meson-sm1-a95xf3-air-gbit.dts
@@ -0,0 +1,129 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2019 BayLibre SAS. All rights reserved.
+ * Copyright (c) 2020 Christian Hewitt <christianshewitt@gmail.com>
+ */
+
+/dts-v1/;
+
+#include "meson-sm1-ac2xx.dtsi"
+#include <dt-bindings/sound/meson-g12a-tohdmitx.h>
+
+/ {
+ compatible = "cyx,a95xf3-air-gbit", "amlogic,sm1";
+ model = "Shenzhen CYX Industrial Co., Ltd A95XF3-AIR";
+
+ sound {
+ compatible = "amlogic,axg-sound-card";
+ model = "A95XF3-AIR";
+ 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";
+
+ assigned-clocks = <&clkc CLKID_MPLL2>,
+ <&clkc CLKID_MPLL0>,
+ <&clkc CLKID_MPLL1>;
+ assigned-clock-parents = <0>, <0>, <0>;
+ assigned-clock-rates = <294912000>,
+ <270950400>,
+ <393216000>;
+ status = "okay";
+
+ dai-link-0 {
+ sound-dai = <&frddr_a>;
+ };
+
+ dai-link-1 {
+ sound-dai = <&frddr_b>;
+ };
+
+ dai-link-2 {
+ sound-dai = <&frddr_c>;
+ };
+
+ /* 8ch hdmi interface */
+ dai-link-3 {
+ sound-dai = <&tdmif_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>;
+ };
+ };
+
+ /* hdmi glue */
+ dai-link-4 {
+ sound-dai = <&tohdmitx TOHDMITX_I2S_OUT>;
+
+ codec {
+ sound-dai = <&hdmi_tx>;
+ };
+ };
+ };
+};
+
+&arb {
+ status = "okay";
+};
+
+&clkc_audio {
+ status = "okay";
+};
+
+&ethmac {
+ status = "okay";
+
+ pinctrl-0 = <&eth_pins>, <&eth_rgmii_pins>;
+ pinctrl-names = "default";
+ phy-mode = "rgmii-txid";
+ phy-handle = <&external_phy>;
+
+ rx-internal-delay-ps = <800>;
+};
+
+&ext_mdio {
+ external_phy: ethernet-phy@0 {
+ /* Realtek RTL8211F (0x001cc916) */
+ reg = <0>;
+ max-speed = <1000>;
+
+ reset-assert-us = <10000>;
+ reset-deassert-us = <80000>;
+ reset-gpios = <&gpio GPIOZ_15 (GPIO_ACTIVE_LOW | GPIO_OPEN_DRAIN)>;
+
+ interrupt-parent = <&gpio_intc>;
+ /* MAC_INTR on GPIOZ_14 */
+ interrupts = <26 IRQ_TYPE_LEVEL_LOW>;
+ };
+};
+
+&frddr_a {
+ status = "okay";
+};
+
+&frddr_b {
+ status = "okay";
+};
+
+&frddr_c {
+ status = "okay";
+};
+
+&tdmif_b {
+ status = "okay";
+};
+
+&tdmout_b {
+ status = "okay";
+};
+
+&tohdmitx {
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/amlogic/meson-sm1-a95xf3-air.dts b/arch/arm64/boot/dts/amlogic/meson-sm1-a95xf3-air.dts
new file mode 100644
index 000000000000..c94f2870b78b
--- /dev/null
+++ b/arch/arm64/boot/dts/amlogic/meson-sm1-a95xf3-air.dts
@@ -0,0 +1,108 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2019 BayLibre SAS. All rights reserved.
+ * Copyright (c) 2020 Christian Hewitt <christianshewitt@gmail.com>
+ */
+
+/dts-v1/;
+
+#include "meson-sm1-ac2xx.dtsi"
+#include <dt-bindings/sound/meson-g12a-tohdmitx.h>
+
+/ {
+ compatible = "cyx,a95xf3-air", "amlogic,sm1";
+ model = "Shenzhen CYX Industrial Co., Ltd A95XF3-AIR";
+
+ sound {
+ compatible = "amlogic,axg-sound-card";
+ model = "A95XF3-AIR";
+ 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";
+
+ assigned-clocks = <&clkc CLKID_MPLL2>,
+ <&clkc CLKID_MPLL0>,
+ <&clkc CLKID_MPLL1>;
+ assigned-clock-parents = <0>, <0>, <0>;
+ assigned-clock-rates = <294912000>,
+ <270950400>,
+ <393216000>;
+ status = "okay";
+
+ dai-link-0 {
+ sound-dai = <&frddr_a>;
+ };
+
+ dai-link-1 {
+ sound-dai = <&frddr_b>;
+ };
+
+ dai-link-2 {
+ sound-dai = <&frddr_c>;
+ };
+
+ /* 8ch hdmi interface */
+ dai-link-3 {
+ sound-dai = <&tdmif_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>;
+ };
+ };
+
+ /* hdmi glue */
+ dai-link-4 {
+ sound-dai = <&tohdmitx TOHDMITX_I2S_OUT>;
+
+ codec {
+ sound-dai = <&hdmi_tx>;
+ };
+ };
+ };
+};
+
+&arb {
+ status = "okay";
+};
+
+&clkc_audio {
+ status = "okay";
+};
+
+&ethmac {
+ status = "okay";
+ phy-handle = <&internal_ephy>;
+ phy-mode = "rmii";
+};
+
+&frddr_a {
+ status = "okay";
+};
+
+&frddr_b {
+ status = "okay";
+};
+
+&frddr_c {
+ status = "okay";
+};
+
+&tdmif_b {
+ status = "okay";
+};
+
+&tdmout_b {
+ status = "okay";
+};
+
+&tohdmitx {
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/amlogic/meson-sm1-ac2xx.dtsi b/arch/arm64/boot/dts/amlogic/meson-sm1-ac2xx.dtsi
new file mode 100644
index 000000000000..46a34731f7e2
--- /dev/null
+++ b/arch/arm64/boot/dts/amlogic/meson-sm1-ac2xx.dtsi
@@ -0,0 +1,300 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2019 BayLibre SAS. All rights reserved.
+ * Copyright (c) 2020 Christian Hewitt <christianshewitt@gmail.com>
+ *
+ * AC200/AC202 = S905D3
+ * AC213/AC214 = S905X3
+ *
+ */
+
+#include "meson-sm1.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/gpio/meson-g12a-gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+ 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>;
+ };
+
+ cvbs-connector {
+ compatible = "composite-video-connector";
+
+ port {
+ cvbs_connector_in: endpoint {
+ remote-endpoint = <&cvbs_vdac_out>;
+ };
+ };
+ };
+
+ hdmi-connector {
+ compatible = "hdmi-connector";
+ type = "a";
+
+ port {
+ hdmi_connector_in: endpoint {
+ remote-endpoint = <&hdmi_tx_tmds_out>;
+ };
+ };
+ };
+
+ memory@0 {
+ device_type = "memory";
+ reg = <0x0 0x0 0x0 0x40000000>;
+ };
+
+ ao_5v: regulator-ao_5v {
+ compatible = "regulator-fixed";
+ regulator-name = "AO_5V";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ vin-supply = <&dc_in>;
+ regulator-always-on;
+ };
+
+ dc_in: regulator-dc_in {
+ compatible = "regulator-fixed";
+ regulator-name = "DC_IN";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-always-on;
+ };
+
+ 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 = <&dc_in>;
+ regulator-always-on;
+ };
+
+ vddcpu: regulator-vddcpu {
+ compatible = "pwm-regulator";
+
+ regulator-name = "VDDCPU";
+ regulator-min-microvolt = <690000>;
+ regulator-max-microvolt = <1050000>;
+
+ vin-supply = <&dc_in>;
+
+ pwms = <&pwm_AO_cd 1 1500 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>;
+ 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 */
+ };
+};
+
+&cec_AO {
+ pinctrl-0 = <&cec_ao_a_h_pins>;
+ pinctrl-names = "default";
+ status = "disabled";
+ hdmi-phandle = <&hdmi_tx>;
+};
+
+&cecb_AO {
+ pinctrl-0 = <&cec_ao_b_h_pins>;
+ pinctrl-names = "default";
+ status = "okay";
+ hdmi-phandle = <&hdmi_tx>;
+};
+
+&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_CPU1_CLK>;
+ clock-latency = <50000>;
+};
+
+&cpu2 {
+ cpu-supply = <&vddcpu>;
+ operating-points-v2 = <&cpu_opp_table>;
+ clocks = <&clkc CLKID_CPU2_CLK>;
+ clock-latency = <50000>;
+};
+
+&cpu3 {
+ cpu-supply = <&vddcpu>;
+ operating-points-v2 = <&cpu_opp_table>;
+ clocks = <&clkc CLKID_CPU3_CLK>;
+ clock-latency = <50000>;
+};
+
+&cvbs_vdac_port {
+ cvbs_vdac_out: endpoint {
+ remote-endpoint = <&cvbs_connector_in>;
+ };
+};
+
+&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>;
+ };
+};
+
+&ir {
+ status = "okay";
+ pinctrl-0 = <&remote_input_ao_pins>;
+ pinctrl-names = "default";
+};
+
+&pwm_AO_ab {
+ status = "okay";
+ pinctrl-0 = <&pwm_ao_a_pins>;
+ pinctrl-names = "default";
+ clocks = <&xtal>;
+ clock-names = "clkin0";
+};
+
+&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";
+};
+
+&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-sdr104;
+ max-frequency = <200000000>;
+
+ 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;
+ /* CRC errors are observed at 50MHz */
+ max-frequency = <35000000>;
+ 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>;
+};
+
+&uart_AO {
+ status = "okay";
+ pinctrl-0 = <&uart_ao_a_pins>;
+ pinctrl-names = "default";
+};
+
+&usb {
+ status = "okay";
+ dr_mode = "otg";
+};
diff --git a/arch/arm64/boot/dts/amlogic/meson-sm1-bananapi-m5.dts b/arch/arm64/boot/dts/amlogic/meson-sm1-bananapi-m5.dts
index 212c6aa5a3b8..5751c48620ed 100644
--- a/arch/arm64/boot/dts/amlogic/meson-sm1-bananapi-m5.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-sm1-bananapi-m5.dts
@@ -123,7 +123,7 @@
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <3300000>;
- enable-gpio = <&gpio GPIOE_2 GPIO_ACTIVE_HIGH>;
+ enable-gpio = <&gpio_ao GPIOE_2 GPIO_ACTIVE_HIGH>;
enable-active-high;
regulator-always-on;
diff --git a/arch/arm64/boot/dts/amlogic/meson-sm1-h96-max.dts b/arch/arm64/boot/dts/amlogic/meson-sm1-h96-max.dts
new file mode 100644
index 000000000000..0f6660e68e72
--- /dev/null
+++ b/arch/arm64/boot/dts/amlogic/meson-sm1-h96-max.dts
@@ -0,0 +1,145 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2019 BayLibre SAS. All rights reserved.
+ * Copyright (c) 2020 Christian Hewitt <christianshewitt@gmail.com>
+ */
+
+/dts-v1/;
+
+#include "meson-sm1-ac2xx.dtsi"
+#include <dt-bindings/sound/meson-g12a-tohdmitx.h>
+
+/ {
+ compatible = "haochuangyi,h96-max", "amlogic,sm1";
+ model = "Shenzhen Haochuangyi Technology Co., Ltd H96 Max";
+
+ sound {
+ compatible = "amlogic,axg-sound-card";
+ model = "H96-MAX";
+ 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";
+
+ assigned-clocks = <&clkc CLKID_MPLL2>,
+ <&clkc CLKID_MPLL0>,
+ <&clkc CLKID_MPLL1>;
+ assigned-clock-parents = <0>, <0>, <0>;
+ assigned-clock-rates = <294912000>,
+ <270950400>,
+ <393216000>;
+ status = "okay";
+
+ dai-link-0 {
+ sound-dai = <&frddr_a>;
+ };
+
+ dai-link-1 {
+ sound-dai = <&frddr_b>;
+ };
+
+ dai-link-2 {
+ sound-dai = <&frddr_c>;
+ };
+
+ /* 8ch hdmi interface */
+ dai-link-3 {
+ sound-dai = <&tdmif_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>;
+ };
+ };
+
+ /* hdmi glue */
+ dai-link-4 {
+ sound-dai = <&tohdmitx TOHDMITX_I2S_OUT>;
+
+ codec {
+ sound-dai = <&hdmi_tx>;
+ };
+ };
+ };
+};
+
+&arb {
+ status = "okay";
+};
+
+&clkc_audio {
+ status = "okay";
+};
+
+&ethmac {
+ status = "okay";
+
+ pinctrl-0 = <&eth_pins>, <&eth_rgmii_pins>;
+ pinctrl-names = "default";
+ phy-mode = "rgmii-txid";
+ phy-handle = <&external_phy>;
+
+ rx-internal-delay-ps = <800>;
+};
+
+&ext_mdio {
+ external_phy: ethernet-phy@0 {
+ /* Realtek RTL8211F (0x001cc916) */
+ reg = <0>;
+ max-speed = <1000>;
+
+ reset-assert-us = <10000>;
+ reset-deassert-us = <80000>;
+ reset-gpios = <&gpio GPIOZ_15 (GPIO_ACTIVE_LOW | GPIO_OPEN_DRAIN)>;
+
+ interrupt-parent = <&gpio_intc>;
+ /* MAC_INTR on GPIOZ_14 */
+ interrupts = <26 IRQ_TYPE_LEVEL_LOW>;
+ };
+};
+
+&frddr_a {
+ status = "okay";
+};
+
+&frddr_b {
+ status = "okay";
+};
+
+&frddr_c {
+ status = "okay";
+};
+
+&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;
+
+ bluetooth {
+ compatible = "brcm,bcm43438-bt";
+ shutdown-gpios = <&gpio GPIOX_17 GPIO_ACTIVE_HIGH>;
+ max-speed = <2000000>;
+ clocks = <&wifi32k>;
+ clock-names = "lpo";
+ };
+};
diff --git a/arch/arm64/boot/dts/amlogic/meson-sm1-odroid.dtsi b/arch/arm64/boot/dts/amlogic/meson-sm1-odroid.dtsi
index 0bd1e98a0eef..ddb1b345397f 100644
--- a/arch/arm64/boot/dts/amlogic/meson-sm1-odroid.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-sm1-odroid.dtsi
@@ -48,7 +48,7 @@
regulator-max-microvolt = <3300000>;
vin-supply = <&vcc_5v>;
- enable-gpio = <&gpio GPIOE_2 GPIO_ACTIVE_HIGH>;
+ enable-gpio = <&gpio_ao GPIOE_2 GPIO_OPEN_DRAIN>;
enable-active-high;
regulator-always-on;
diff --git a/arch/arm64/boot/dts/amlogic/meson-sm1-sei610.dts b/arch/arm64/boot/dts/amlogic/meson-sm1-sei610.dts
index 427475846fc7..a5d79f2f7c19 100644
--- a/arch/arm64/boot/dts/amlogic/meson-sm1-sei610.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-sm1-sei610.dts
@@ -203,14 +203,6 @@
regulator-always-on;
};
- reserved-memory {
- /* TEE Reserved Memory */
- bl32_reserved: bl32@5000000 {
- reg = <0x0 0x05300000 0x0 0x2000000>;
- no-map;
- };
- };
-
sdio_pwrseq: sdio-pwrseq {
compatible = "mmc-pwrseq-simple";
reset-gpios = <&gpio GPIOX_6 GPIO_ACTIVE_LOW>;
diff --git a/arch/arm64/boot/dts/amlogic/meson-sm1-x96-air-gbit.dts b/arch/arm64/boot/dts/amlogic/meson-sm1-x96-air-gbit.dts
new file mode 100644
index 000000000000..7e1a74046ba5
--- /dev/null
+++ b/arch/arm64/boot/dts/amlogic/meson-sm1-x96-air-gbit.dts
@@ -0,0 +1,133 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2019 BayLibre SAS. All rights reserved.
+ * Copyright (c) 2020 Christian Hewitt <christianshewitt@gmail.com>
+ */
+
+/dts-v1/;
+
+#include "meson-sm1-ac2xx.dtsi"
+#include <dt-bindings/sound/meson-g12a-tohdmitx.h>
+
+/ {
+ compatible = "amediatech,x96-air-gbit", "amlogic,sm1";
+ model = "Shenzhen Amediatech Technology Co., Ltd X96 Air";
+
+ sound {
+ compatible = "amlogic,axg-sound-card";
+ model = "X96-AIR";
+ 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";
+
+ assigned-clocks = <&clkc CLKID_MPLL2>,
+ <&clkc CLKID_MPLL0>,
+ <&clkc CLKID_MPLL1>;
+ assigned-clock-parents = <0>, <0>, <0>;
+ assigned-clock-rates = <294912000>,
+ <270950400>,
+ <393216000>;
+ status = "okay";
+
+ dai-link-0 {
+ sound-dai = <&frddr_a>;
+ };
+
+ dai-link-1 {
+ sound-dai = <&frddr_b>;
+ };
+
+ dai-link-2 {
+ sound-dai = <&frddr_c>;
+ };
+
+ /* 8ch hdmi interface */
+ dai-link-3 {
+ sound-dai = <&tdmif_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>;
+ };
+ };
+
+ /* hdmi glue */
+ dai-link-4 {
+ sound-dai = <&tohdmitx TOHDMITX_I2S_OUT>;
+
+ codec {
+ sound-dai = <&hdmi_tx>;
+ };
+ };
+ };
+};
+
+&arb {
+ status = "okay";
+};
+
+&clkc_audio {
+ status = "okay";
+};
+
+&ethmac {
+ status = "okay";
+
+ pinctrl-0 = <&eth_pins>, <&eth_rgmii_pins>;
+ pinctrl-names = "default";
+ phy-mode = "rgmii-txid";
+ phy-handle = <&external_phy>;
+
+ rx-internal-delay-ps = <800>;
+};
+
+&ext_mdio {
+ external_phy: ethernet-phy@0 {
+ /* Realtek RTL8211F (0x001cc916) */
+ reg = <0>;
+ max-speed = <1000>;
+
+ reset-assert-us = <10000>;
+ reset-deassert-us = <80000>;
+ reset-gpios = <&gpio GPIOZ_15 (GPIO_ACTIVE_LOW | GPIO_OPEN_DRAIN)>;
+
+ interrupt-parent = <&gpio_intc>;
+ /* MAC_INTR on GPIOZ_14 */
+ interrupts = <26 IRQ_TYPE_LEVEL_LOW>;
+ };
+};
+
+&frddr_a {
+ status = "okay";
+};
+
+&frddr_b {
+ status = "okay";
+};
+
+&frddr_c {
+ status = "okay";
+};
+
+&ir {
+ linux,rc-map-name = "rc-x96max";
+};
+
+&tdmif_b {
+ status = "okay";
+};
+
+&tdmout_b {
+ status = "okay";
+};
+
+&tohdmitx {
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/amlogic/meson-sm1-x96-air.dts b/arch/arm64/boot/dts/amlogic/meson-sm1-x96-air.dts
new file mode 100644
index 000000000000..cd93d798f2a3
--- /dev/null
+++ b/arch/arm64/boot/dts/amlogic/meson-sm1-x96-air.dts
@@ -0,0 +1,112 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2019 BayLibre SAS. All rights reserved.
+ * Copyright (c) 2020 Christian Hewitt <christianshewitt@gmail.com>
+ */
+
+/dts-v1/;
+
+#include "meson-sm1-ac2xx.dtsi"
+#include <dt-bindings/sound/meson-g12a-tohdmitx.h>
+
+/ {
+ compatible = "amediatech,x96-air", "amlogic,sm1";
+ model = "Shenzhen Amediatech Technology Co., Ltd X96 Air";
+
+ sound {
+ compatible = "amlogic,axg-sound-card";
+ model = "X96-AIR";
+ 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";
+
+ assigned-clocks = <&clkc CLKID_MPLL2>,
+ <&clkc CLKID_MPLL0>,
+ <&clkc CLKID_MPLL1>;
+ assigned-clock-parents = <0>, <0>, <0>;
+ assigned-clock-rates = <294912000>,
+ <270950400>,
+ <393216000>;
+ status = "okay";
+
+ dai-link-0 {
+ sound-dai = <&frddr_a>;
+ };
+
+ dai-link-1 {
+ sound-dai = <&frddr_b>;
+ };
+
+ dai-link-2 {
+ sound-dai = <&frddr_c>;
+ };
+
+ /* 8ch hdmi interface */
+ dai-link-3 {
+ sound-dai = <&tdmif_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>;
+ };
+ };
+
+ /* hdmi glue */
+ dai-link-4 {
+ sound-dai = <&tohdmitx TOHDMITX_I2S_OUT>;
+
+ codec {
+ sound-dai = <&hdmi_tx>;
+ };
+ };
+ };
+};
+
+&arb {
+ status = "okay";
+};
+
+&clkc_audio {
+ status = "okay";
+};
+
+&ethmac {
+ status = "okay";
+ phy-handle = <&internal_ephy>;
+ phy-mode = "rmii";
+};
+
+&frddr_a {
+ status = "okay";
+};
+
+&frddr_b {
+ status = "okay";
+};
+
+&frddr_c {
+ status = "okay";
+};
+
+&ir {
+ linux,rc-map-name = "rc-beelink-gs1";
+};
+
+&tdmif_b {
+ status = "okay";
+};
+
+&tdmout_b {
+ status = "okay";
+};
+
+&tohdmitx {
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/amlogic/meson-sm1.dtsi b/arch/arm64/boot/dts/amlogic/meson-sm1.dtsi
index 3d8b1f4f2001..3c07a89bfd27 100644
--- a/arch/arm64/boot/dts/amlogic/meson-sm1.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-sm1.dtsi
@@ -356,6 +356,33 @@
status = "disabled";
};
+ spdifin: audio-controller@400 {
+ compatible = "amlogic,g12a-spdifin",
+ "amlogic,axg-spdifin";
+ reg = <0x0 0x400 0x0 0x30>;
+ #sound-dai-cells = <0>;
+ sound-name-prefix = "SPDIFIN";
+ interrupts = <GIC_SPI 151 IRQ_TYPE_EDGE_RISING>;
+ clocks = <&clkc_audio AUD_CLKID_SPDIFIN>,
+ <&clkc_audio AUD_CLKID_SPDIFIN_CLK>;
+ clock-names = "pclk", "refclk";
+ resets = <&clkc_audio AUD_RESET_SPDIFIN>;
+ status = "disabled";
+ };
+
+ spdifout_a: audio-controller@480 {
+ compatible = "amlogic,g12a-spdifout",
+ "amlogic,axg-spdifout";
+ reg = <0x0 0x480 0x0 0x50>;
+ #sound-dai-cells = <0>;
+ sound-name-prefix = "SPDIFOUT_A";
+ clocks = <&clkc_audio AUD_CLKID_SPDIFOUT>,
+ <&clkc_audio AUD_CLKID_SPDIFOUT_CLK>;
+ clock-names = "pclk", "mclk";
+ resets = <&clkc_audio AUD_RESET_SPDIFOUT>;
+ status = "disabled";
+ };
+
tdmout_a: audio-controller@500 {
compatible = "amlogic,sm1-tdmout";
reg = <0x0 0x500 0x0 0x40>;
diff --git a/arch/arm64/boot/dts/apple/t8103.dtsi b/arch/arm64/boot/dts/apple/t8103.dtsi
index 19afbc91020a..9f8f4145db88 100644
--- a/arch/arm64/boot/dts/apple/t8103.dtsi
+++ b/arch/arm64/boot/dts/apple/t8103.dtsi
@@ -97,6 +97,18 @@
<AIC_FIQ AIC_TMR_HV_VIRT IRQ_TYPE_LEVEL_HIGH>;
};
+ pmu-e {
+ compatible = "apple,icestorm-pmu";
+ interrupt-parent = <&aic>;
+ interrupts = <AIC_FIQ AIC_CPU_PMU_E IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ pmu-p {
+ compatible = "apple,firestorm-pmu";
+ interrupt-parent = <&aic>;
+ interrupts = <AIC_FIQ AIC_CPU_PMU_P IRQ_TYPE_LEVEL_HIGH>;
+ };
+
clkref: clock-ref {
compatible = "fixed-clock";
#clock-cells = <0>;
@@ -213,6 +225,18 @@
interrupt-controller;
reg = <0x2 0x3b100000 0x0 0x8000>;
power-domains = <&ps_aic>;
+
+ affinities {
+ e-core-pmu-affinity {
+ apple,fiq-index = <AIC_CPU_PMU_E>;
+ cpus = <&cpu0 &cpu1 &cpu2 &cpu3>;
+ };
+
+ p-core-pmu-affinity {
+ apple,fiq-index = <AIC_CPU_PMU_P>;
+ cpus = <&cpu4 &cpu5 &cpu6 &cpu7>;
+ };
+ };
};
pmgr: power-management@23b700000 {
diff --git a/arch/arm64/boot/dts/arm/Makefile b/arch/arm64/boot/dts/arm/Makefile
index 800da2e84f3f..4382b73baef5 100644
--- a/arch/arm64/boot/dts/arm/Makefile
+++ b/arch/arm64/boot/dts/arm/Makefile
@@ -2,7 +2,7 @@
dtb-$(CONFIG_ARCH_VEXPRESS) += \
foundation-v8.dtb foundation-v8-psci.dtb \
foundation-v8-gicv3.dtb foundation-v8-gicv3-psci.dtb
-dtb-$(CONFIG_ARCH_VEXPRESS) += juno.dtb juno-r1.dtb juno-r2.dtb
+dtb-$(CONFIG_ARCH_VEXPRESS) += juno.dtb juno-r1.dtb juno-r2.dtb juno-scmi.dtb juno-r1-scmi.dtb juno-r2-scmi.dtb
dtb-$(CONFIG_ARCH_VEXPRESS) += rtsm_ve-aemv8a.dtb
dtb-$(CONFIG_ARCH_VEXPRESS) += vexpress-v2f-1xv7-ca53x2.dtb
dtb-$(CONFIG_ARCH_VEXPRESS) += fvp-base-revc.dtb
diff --git a/arch/arm64/boot/dts/arm/juno-base.dtsi b/arch/arm64/boot/dts/arm/juno-base.dtsi
index 6288e104a089..446c8f476eec 100644
--- a/arch/arm64/boot/dts/arm/juno-base.dtsi
+++ b/arch/arm64/boot/dts/arm/juno-base.dtsi
@@ -543,8 +543,7 @@
<0x02000000 0x00 0x50000000 0x00 0x50000000 0x0 0x08000000>,
<0x42000000 0x40 0x00000000 0x40 0x00000000 0x1 0x00000000>;
/* Standard AXI Translation entries as programmed by EDK2 */
- dma-ranges = <0x02000000 0x0 0x2c1c0000 0x0 0x2c1c0000 0x0 0x00040000>,
- <0x02000000 0x0 0x80000000 0x0 0x80000000 0x0 0x80000000>,
+ dma-ranges = <0x02000000 0x0 0x80000000 0x0 0x80000000 0x0 0x80000000>,
<0x43000000 0x8 0x00000000 0x8 0x00000000 0x2 0x00000000>;
#interrupt-cells = <1>;
interrupt-map-mask = <0 0 0 7>;
@@ -672,7 +671,7 @@
dma-coherent;
};
- dma@7ff00000 {
+ dma-controller@7ff00000 {
compatible = "arm,pl330", "arm,primecell";
reg = <0x0 0x7ff00000 0 0x1000>;
#dma-cells = <1>;
diff --git a/arch/arm64/boot/dts/arm/juno-r1-scmi.dts b/arch/arm64/boot/dts/arm/juno-r1-scmi.dts
new file mode 100644
index 000000000000..190a0fba4ad6
--- /dev/null
+++ b/arch/arm64/boot/dts/arm/juno-r1-scmi.dts
@@ -0,0 +1,23 @@
+#include "juno-r1.dts"
+#include "juno-scmi.dtsi"
+
+/ {
+ funnel@20130000 {
+ power-domains = <&scmi_devpd 8>;
+ };
+
+ etf@20140000 {
+ power-domains = <&scmi_devpd 0>;
+ };
+
+ funnel@20150000 {
+ power-domains = <&scmi_devpd 0>;
+ };
+};
+
+&A57_0 {
+ clocks = <&scmi_dvfs 0>;
+};
+&A57_1 {
+ clocks = <&scmi_dvfs 0>;
+};
diff --git a/arch/arm64/boot/dts/arm/juno-r2-scmi.dts b/arch/arm64/boot/dts/arm/juno-r2-scmi.dts
new file mode 100644
index 000000000000..dbf13770084f
--- /dev/null
+++ b/arch/arm64/boot/dts/arm/juno-r2-scmi.dts
@@ -0,0 +1,23 @@
+#include "juno-r2.dts"
+#include "juno-scmi.dtsi"
+
+/ {
+ funnel@20130000 {
+ power-domains = <&scmi_devpd 8>;
+ };
+
+ etf@20140000 {
+ power-domains = <&scmi_devpd 0>;
+ };
+
+ funnel@20150000 {
+ power-domains = <&scmi_devpd 0>;
+ };
+};
+
+&A72_0 {
+ clocks = <&scmi_dvfs 0>;
+};
+&A72_1 {
+ clocks = <&scmi_dvfs 0>;
+};
diff --git a/arch/arm64/boot/dts/arm/juno-scmi.dts b/arch/arm64/boot/dts/arm/juno-scmi.dts
new file mode 100644
index 000000000000..41588fa46d31
--- /dev/null
+++ b/arch/arm64/boot/dts/arm/juno-scmi.dts
@@ -0,0 +1,9 @@
+#include "juno.dts"
+#include "juno-scmi.dtsi"
+
+&A57_0 {
+ clocks = <&scmi_dvfs 0>;
+};
+&A57_1 {
+ clocks = <&scmi_dvfs 0>;
+};
diff --git a/arch/arm64/boot/dts/arm/juno-scmi.dtsi b/arch/arm64/boot/dts/arm/juno-scmi.dtsi
new file mode 100644
index 000000000000..d72dcff9bf06
--- /dev/null
+++ b/arch/arm64/boot/dts/arm/juno-scmi.dtsi
@@ -0,0 +1,199 @@
+/ {
+ etf@20010000 {
+ power-domains = <&scmi_devpd 8>;
+ };
+
+ tpiu@20030000 {
+ power-domains = <&scmi_devpd 8>;
+ };
+
+ funnel@20040000 {
+ power-domains = <&scmi_devpd 8>;
+ };
+
+ etr@20070000 {
+ power-domains = <&scmi_devpd 8>;
+ };
+
+ stm@20100000 {
+ power-domains = <&scmi_devpd 8>;
+ };
+
+ replicator@20120000 {
+ power-domains = <&scmi_devpd 8>;
+ };
+
+ funnel@220c0000 {
+ power-domains = <&scmi_devpd 8>;
+ };
+
+ funnel@230c0000 {
+ power-domains = <&scmi_devpd 8>;
+ };
+
+ hdlcd@7ff50000 {
+ clocks = <&scmi_clk 3>;
+ };
+
+ hdlcd@7ff60000 {
+ clocks = <&scmi_clk 3>;
+ };
+
+ /delete-node/ scpi;
+
+ firmware {
+ scmi {
+ compatible = "arm,scmi";
+ mbox-names = "tx", "rx";
+ mboxes = <&mailbox 0 0 &mailbox 0 1>;
+ shmem = <&cpu_scp_lpri0 &cpu_scp_lpri1>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ scmi_devpd: protocol@11 {
+ reg = <0x11>;
+ #power-domain-cells = <1>;
+ };
+
+ scmi_dvfs: protocol@13 {
+ reg = <0x13>;
+ #clock-cells = <1>;
+ mbox-names = "tx", "rx";
+ mboxes = <&mailbox 1 0 &mailbox 1 1>;
+ shmem = <&cpu_scp_hpri0 &cpu_scp_hpri1>;
+ };
+
+ scmi_clk: protocol@14 {
+ reg = <0x14>;
+ #clock-cells = <1>;
+ };
+
+ scmi_sensors0: protocol@15 {
+ reg = <0x15>;
+ #thermal-sensor-cells = <1>;
+ };
+ };
+ };
+
+ thermal-zones {
+ pmic {
+ thermal-sensors = <&scmi_sensors0 0>;
+ };
+
+ soc {
+ thermal-sensors = <&scmi_sensors0 3>;
+ };
+
+ big-cluster {
+ thermal-sensors = <&scmi_sensors0 21>;
+ };
+
+ little-cluster {
+ thermal-sensors = <&scmi_sensors0 22>;
+ };
+
+ gpu0 {
+ thermal-sensors = <&scmi_sensors0 23>;
+ };
+
+ gpu1 {
+ thermal-sensors = <&scmi_sensors0 24>;
+ };
+ };
+
+};
+
+&A53_0 {
+ clocks = <&scmi_dvfs 1>;
+};
+&A53_1 {
+ clocks = <&scmi_dvfs 1>;
+};
+&A53_2 {
+ clocks = <&scmi_dvfs 1>;
+};
+&A53_3 {
+ clocks = <&scmi_dvfs 1>;
+};
+
+&cpu_debug0 {
+ power-domains = <&scmi_devpd 8>;
+};
+&cpu_debug1 {
+ power-domains = <&scmi_devpd 8>;
+};
+&cpu_debug2 {
+ power-domains = <&scmi_devpd 8>;
+};
+&cpu_debug3 {
+ power-domains = <&scmi_devpd 8>;
+};
+&cpu_debug4 {
+ power-domains = <&scmi_devpd 8>;
+};
+&cpu_debug5 {
+ power-domains = <&scmi_devpd 8>;
+};
+
+&etm0 {
+ power-domains = <&scmi_devpd 8>;
+};
+&etm1 {
+ power-domains = <&scmi_devpd 8>;
+};
+&etm2 {
+ power-domains = <&scmi_devpd 8>;
+};
+&etm3 {
+ power-domains = <&scmi_devpd 8>;
+};
+&etm4 {
+ power-domains = <&scmi_devpd 8>;
+};
+&etm5 {
+ power-domains = <&scmi_devpd 8>;
+};
+
+&gpu {
+ clocks = <&scmi_dvfs 2>;
+ power-domains = <&scmi_devpd 9>;
+};
+
+&mailbox {
+ compatible = "arm,mhu-doorbell", "arm,primecell";
+ #mbox-cells = <2>;
+ mbox-name = "ARM-MHU";
+};
+
+&smmu_etr {
+ power-domains = <&scmi_devpd 8>;
+};
+
+&smmu_gpu {
+ power-domains = <&scmi_devpd 9>;
+};
+
+&sram {
+ /delete-node/ scp-sram@0;
+ /delete-node/ scp-sram@200;
+
+ cpu_scp_lpri0: scp-sram@0 {
+ compatible = "arm,scmi-shmem";
+ reg = <0x0 0x80>;
+ };
+
+ cpu_scp_lpri1: scp-sram@80 {
+ compatible = "arm,scmi-shmem";
+ reg = <0x80 0x80>;
+ };
+
+ cpu_scp_hpri0: scp-sram@100 {
+ compatible = "arm,scmi-shmem";
+ reg = <0x100 0x80>;
+ };
+
+ cpu_scp_hpri1: scp-sram@180 {
+ compatible = "arm,scmi-shmem";
+ reg = <0x180 0x80>;
+ };
+};
diff --git a/arch/arm64/boot/dts/broadcom/Makefile b/arch/arm64/boot/dts/broadcom/Makefile
index c6882032a428..5082fcd1fea5 100644
--- a/arch/arm64/boot/dts/broadcom/Makefile
+++ b/arch/arm64/boot/dts/broadcom/Makefile
@@ -5,7 +5,8 @@ dtb-$(CONFIG_ARCH_BCM2835) += bcm2711-rpi-400.dtb \
bcm2837-rpi-3-a-plus.dtb \
bcm2837-rpi-3-b.dtb \
bcm2837-rpi-3-b-plus.dtb \
- bcm2837-rpi-cm3-io3.dtb
+ bcm2837-rpi-cm3-io3.dtb \
+ bcm2837-rpi-zero-2-w.dtb
subdir-y += bcm4908
subdir-y += northstar2
diff --git a/arch/arm64/boot/dts/broadcom/bcm2837-rpi-zero-2-w.dts b/arch/arm64/boot/dts/broadcom/bcm2837-rpi-zero-2-w.dts
new file mode 100644
index 000000000000..307ae693e4a0
--- /dev/null
+++ b/arch/arm64/boot/dts/broadcom/bcm2837-rpi-zero-2-w.dts
@@ -0,0 +1,2 @@
+// SPDX-License-Identifier: GPL-2.0
+#include "arm/bcm2837-rpi-zero-2-w.dts"
diff --git a/arch/arm64/boot/dts/broadcom/bcm4908/bcm4908.dtsi b/arch/arm64/boot/dts/broadcom/bcm4908/bcm4908.dtsi
index 984c737fa627..a4be040a00c0 100644
--- a/arch/arm64/boot/dts/broadcom/bcm4908/bcm4908.dtsi
+++ b/arch/arm64/boot/dts/broadcom/bcm4908/bcm4908.dtsi
@@ -273,9 +273,18 @@
#size-cells = <1>;
ranges = <0x00 0x00 0xff800000 0x3000>;
- timer: timer@400 {
- compatible = "brcm,bcm6328-timer", "syscon";
- reg = <0x400 0x3c>;
+ twd: timer-mfd@400 {
+ compatible = "brcm,bcm4908-twd", "simple-mfd", "syscon";
+ reg = <0x400 0x4c>;
+ ranges = <0x0 0x400 0x4c>;
+
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ watchdog@28 {
+ compatible = "brcm,bcm6345-wdt";
+ reg = <0x28 0x8>;
+ };
};
gpio0: gpio-controller@500 {
@@ -287,6 +296,141 @@
gpio-controller;
};
+ pinctrl@560 {
+ compatible = "brcm,bcm4908-pinctrl";
+ reg = <0x560 0x10>;
+
+ pins_led_0_a: led_0-a-pins {
+ function = "led_0";
+ groups = "led_0_grp_a";
+ };
+
+ pins_led_1_a: led_1-a-pins {
+ function = "led_1";
+ groups = "led_1_grp_a";
+ };
+
+ pins_led_2_a: led_2-a-pins {
+ function = "led_2";
+ groups = "led_2_grp_a";
+ };
+
+ pins_led_3_a: led_3-a-pins {
+ function = "led_3";
+ groups = "led_3_grp_a";
+ };
+
+ pins_led_4_a: led_4-a-pins {
+ function = "led_4";
+ groups = "led_4_grp_a";
+ };
+
+ pins_led_5_a: led_5-a-pins {
+ function = "led_5";
+ groups = "led_5_grp_a";
+ };
+
+ pins_led_6_a: led_6-a-pins {
+ function = "led_6";
+ groups = "led_6_grp_a";
+ };
+
+ pins_led_7_a: led_7-a-pins {
+ function = "led_7";
+ groups = "led_7_grp_a";
+ };
+
+ pins_led_8_a: led_8-a-pins {
+ function = "led_8";
+ groups = "led_8_grp_a";
+ };
+
+ pins_led_9_a: led_9-a-pins {
+ function = "led_9";
+ groups = "led_9_grp_a";
+ };
+
+ pins_led_21_a: led_21-a-pins {
+ function = "led_21";
+ groups = "led_21_grp_a";
+ };
+
+ pins_led_22_a: led_22-a-pins {
+ function = "led_22";
+ groups = "led_22_grp_a";
+ };
+
+ pins_led_26_a: led_26-a-pins {
+ function = "led_26";
+ groups = "led_26_grp_a";
+ };
+
+ pins_led_27_a: led_27-a-pins {
+ function = "led_27";
+ groups = "led_27_grp_a";
+ };
+
+ pins_led_28_a: led_28-a-pins {
+ function = "led_28";
+ groups = "led_28_grp_a";
+ };
+
+ pins_led_29_a: led_29-a-pins {
+ function = "led_29";
+ groups = "led_29_grp_a";
+ };
+
+ pins_led_30_a: led_30-a-pins {
+ function = "led_30";
+ groups = "led_30_grp_a";
+ };
+
+ pins_hs_uart: hs_uart-pins {
+ function = "hs_uart";
+ groups = "hs_uart_grp";
+ };
+
+ pins_i2c_a: i2c-a-pins {
+ function = "i2c";
+ groups = "i2c_grp_a";
+ };
+
+ pins_i2c_b: i2c-b-pins {
+ function = "i2c";
+ groups = "i2c_grp_b";
+ };
+
+ pins_i2s: i2s-pins {
+ function = "i2s";
+ groups = "i2s_grp";
+ };
+
+ pins_nand_ctrl: nand_ctrl-pins {
+ function = "nand_ctrl";
+ groups = "nand_ctrl_grp";
+ };
+
+ pins_nand_data: nand_data-pins {
+ function = "nand_data";
+ groups = "nand_data_grp";
+ };
+
+ pins_emmc_ctrl: emmc_ctrl-pins {
+ function = "emmc_ctrl";
+ groups = "emmc_ctrl_grp";
+ };
+
+ pins_usb0_pwr: usb0_pwr-pins {
+ function = "usb0_pwr";
+ groups = "usb0_pwr_grp";
+ };
+
+ pins_usb1_pwr: usb1_pwr-pins {
+ function = "usb1_pwr";
+ groups = "usb1_pwr_grp";
+ };
+ };
+
uart0: serial@640 {
compatible = "brcm,bcm6345-uart";
reg = <0x640 0x18>;
@@ -312,6 +456,15 @@
};
};
+ i2c@2100 {
+ compatible = "brcm,brcmper-i2c";
+ reg = <0x2100 0x58>;
+ clock-frequency = <97500>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pins_i2c_a>;
+ status = "disabled";
+ };
+
misc@2600 {
compatible = "brcm,misc", "simple-mfd";
reg = <0x2600 0xe4>;
@@ -330,7 +483,7 @@
reboot {
compatible = "syscon-reboot";
- regmap = <&timer>;
+ regmap = <&twd>;
offset = <0x34>;
mask = <1>;
};
diff --git a/arch/arm64/boot/dts/broadcom/northstar2/ns2-svk.dts b/arch/arm64/boot/dts/broadcom/northstar2/ns2-svk.dts
index ec19fbf928a1..12a4b1c03390 100644
--- a/arch/arm64/boot/dts/broadcom/northstar2/ns2-svk.dts
+++ b/arch/arm64/boot/dts/broadcom/northstar2/ns2-svk.dts
@@ -111,8 +111,8 @@
compatible = "silabs,si3226x";
reg = <0>;
spi-max-frequency = <5000000>;
- spi-cpha = <1>;
- spi-cpol = <1>;
+ spi-cpha;
+ spi-cpol;
pl022,hierarchy = <0>;
pl022,interface = <0>;
pl022,slave-tx-disable = <0>;
@@ -135,8 +135,8 @@
at25,byte-len = <0x8000>;
at25,addr-mode = <2>;
at25,page-size = <64>;
- spi-cpha = <1>;
- spi-cpol = <1>;
+ spi-cpha;
+ spi-cpol;
pl022,hierarchy = <0>;
pl022,interface = <0>;
pl022,slave-tx-disable = <0>;
diff --git a/arch/arm64/boot/dts/broadcom/northstar2/ns2.dtsi b/arch/arm64/boot/dts/broadcom/northstar2/ns2.dtsi
index 2cfeaf3b0a87..f59fa3979a04 100644
--- a/arch/arm64/boot/dts/broadcom/northstar2/ns2.dtsi
+++ b/arch/arm64/boot/dts/broadcom/northstar2/ns2.dtsi
@@ -276,7 +276,7 @@
mboxes = <&pdc3 0>;
};
- dma0: dma@61360000 {
+ dma0: dma-controller@61360000 {
compatible = "arm,pl330", "arm,primecell";
reg = <0x61360000 0x1000>;
interrupts = <GIC_SPI 208 IRQ_TYPE_LEVEL_HIGH>,
@@ -644,7 +644,7 @@
reg = <0x66180000 0x1000>;
interrupts = <GIC_SPI 404 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&iprocslow>, <&iprocslow>;
- clock-names = "spiclk", "apb_pclk";
+ clock-names = "sspclk", "apb_pclk";
#address-cells = <1>;
#size-cells = <0>;
status = "disabled";
@@ -655,7 +655,7 @@
reg = <0x66190000 0x1000>;
interrupts = <GIC_SPI 405 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&iprocslow>, <&iprocslow>;
- clock-names = "spiclk", "apb_pclk";
+ clock-names = "sspclk", "apb_pclk";
#address-cells = <1>;
#size-cells = <0>;
status = "disabled";
@@ -687,7 +687,7 @@
};
};
- sata: ahci@663f2000 {
+ sata: sata@663f2000 {
compatible = "brcm,iproc-ahci", "generic-ahci";
reg = <0x663f2000 0x1000>;
dma-coherent;
diff --git a/arch/arm64/boot/dts/broadcom/stingray/stingray.dtsi b/arch/arm64/boot/dts/broadcom/stingray/stingray.dtsi
index 7b04dfe67bef..7f1b8efd0883 100644
--- a/arch/arm64/boot/dts/broadcom/stingray/stingray.dtsi
+++ b/arch/arm64/boot/dts/broadcom/stingray/stingray.dtsi
@@ -519,7 +519,7 @@
reg = <0x00180000 0x1000>;
interrupts = <GIC_SPI 187 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&hsls_div2_clk>, <&hsls_div2_clk>;
- clock-names = "spiclk", "apb_pclk";
+ clock-names = "sspclk", "apb_pclk";
num-cs = <1>;
#address-cells = <1>;
#size-cells = <0>;
@@ -531,7 +531,7 @@
reg = <0x00190000 0x1000>;
interrupts = <GIC_SPI 188 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&hsls_div2_clk>, <&hsls_div2_clk>;
- clock-names = "spiclk", "apb_pclk";
+ clock-names = "sspclk", "apb_pclk";
num-cs = <1>;
#address-cells = <1>;
#size-cells = <0>;
@@ -543,7 +543,7 @@
reg = <0x00220000 0x28>;
};
- dma0: dma@310000 {
+ dma0: dma-controller@310000 {
compatible = "arm,pl330", "arm,primecell";
reg = <0x00310000 0x1000>;
interrupts = <GIC_SPI 193 IRQ_TYPE_LEVEL_HIGH>,
diff --git a/arch/arm64/boot/dts/exynos/Makefile b/arch/arm64/boot/dts/exynos/Makefile
index b41e86df0a84..6e4ba69268e5 100644
--- a/arch/arm64/boot/dts/exynos/Makefile
+++ b/arch/arm64/boot/dts/exynos/Makefile
@@ -1,6 +1,8 @@
# SPDX-License-Identifier: GPL-2.0
dtb-$(CONFIG_ARCH_EXYNOS) += \
- exynos5433-tm2.dtb \
- exynos5433-tm2e.dtb \
- exynos7-espresso.dtb \
+ exynos5433-tm2.dtb \
+ exynos5433-tm2e.dtb \
+ exynos7-espresso.dtb \
+ exynos7885-jackpotlte.dtb \
+ exynos850-e850-96.dtb \
exynosautov9-sadk.dtb
diff --git a/arch/arm64/boot/dts/exynos/exynos5433-pinctrl.dtsi b/arch/arm64/boot/dts/exynos/exynos5433-pinctrl.dtsi
index 32a6518517e5..4b46af3e164d 100644
--- a/arch/arm64/boot/dts/exynos/exynos5433-pinctrl.dtsi
+++ b/arch/arm64/boot/dts/exynos/exynos5433-pinctrl.dtsi
@@ -11,16 +11,25 @@
#include <dt-bindings/pinctrl/samsung.h>
-#define PIN(_func, _pin, _pull, _drv) \
- _pin { \
+#define PIN(_pin, _func, _pull, _drv) \
+ pin- ## _pin { \
samsung,pins = #_pin; \
samsung,pin-function = <EXYNOS_PIN_FUNC_ ##_func>; \
samsung,pin-pud = <EXYNOS_PIN_PULL_ ##_pull>; \
samsung,pin-drv = <EXYNOS5433_PIN_DRV_ ##_drv>; \
}
+#define PIN_IN(_pin, _pull, _drv) \
+ PIN(_pin, INPUT, _pull, _drv)
+
+#define PIN_OT(_pin, _pull, _drv) \
+ PIN(_pin, OUTPUT, _pull, _drv)
+
+#define PIN_F2(_pin, _pull, _drv) \
+ PIN(_pin, 2, _pull, _drv)
+
&pinctrl_alive {
- gpa0: gpa0 {
+ gpa0: gpa0-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -37,7 +46,7 @@
#interrupt-cells = <2>;
};
- gpa1: gpa1 {
+ gpa1: gpa1-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -54,7 +63,7 @@
#interrupt-cells = <2>;
};
- gpa2: gpa2 {
+ gpa2: gpa2-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -62,7 +71,7 @@
#interrupt-cells = <2>;
};
- gpa3: gpa3 {
+ gpa3: gpa3-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -70,7 +79,7 @@
#interrupt-cells = <2>;
};
- gpf1: gpf1 {
+ gpf1: gpf1-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -78,7 +87,7 @@
#interrupt-cells = <2>;
};
- gpf2: gpf2 {
+ gpf2: gpf2-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -86,7 +95,7 @@
#interrupt-cells = <2>;
};
- gpf3: gpf3 {
+ gpf3: gpf3-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -94,7 +103,7 @@
#interrupt-cells = <2>;
};
- gpf4: gpf4 {
+ gpf4: gpf4-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -102,7 +111,7 @@
#interrupt-cells = <2>;
};
- gpf5: gpf5 {
+ gpf5: gpf5-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -112,7 +121,7 @@
};
&pinctrl_aud {
- gpz0: gpz0 {
+ gpz0: gpz0-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -120,7 +129,7 @@
#interrupt-cells = <2>;
};
- gpz1: gpz1 {
+ gpz1: gpz1-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -128,7 +137,7 @@
#interrupt-cells = <2>;
};
- i2s0_bus: i2s0-bus {
+ i2s0_bus: i2s0-bus-pins {
samsung,pins = "gpz0-0", "gpz0-1", "gpz0-2", "gpz0-3",
"gpz0-4", "gpz0-5", "gpz0-6";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
@@ -136,14 +145,14 @@
samsung,pin-drv = <EXYNOS5433_PIN_DRV_FAST_SR1>;
};
- pcm0_bus: pcm0-bus {
+ pcm0_bus: pcm0-bus-pins {
samsung,pins = "gpz1-0", "gpz1-1", "gpz1-2", "gpz1-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS5433_PIN_DRV_FAST_SR1>;
};
- uart_aud_bus: uart-aud-bus {
+ uart_aud_bus: uart-aud-bus-pins {
samsung,pins = "gpz1-3", "gpz1-2", "gpz1-1", "gpz1-0";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
@@ -152,7 +161,7 @@
};
&pinctrl_cpif {
- gpv6: gpv6 {
+ gpv6: gpv6-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -162,7 +171,7 @@
};
&pinctrl_ese {
- gpj2: gpj2 {
+ gpj2: gpj2-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -172,7 +181,7 @@
};
&pinctrl_finger {
- gpd5: gpd5 {
+ gpd5: gpd5-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -180,14 +189,14 @@
#interrupt-cells = <2>;
};
- spi2_bus: spi2-bus {
+ spi2_bus: spi2-bus-pins {
samsung,pins = "gpd5-0", "gpd5-2", "gpd5-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS5433_PIN_DRV_FAST_SR1>;
};
- hs_i2c6_bus: hs-i2c6-bus {
+ hs_i2c6_bus: hs-i2c6-bus-pins {
samsung,pins = "gpd5-3", "gpd5-2";
samsung,pin-function = <EXYNOS_PIN_FUNC_4>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
@@ -196,7 +205,7 @@
};
&pinctrl_fsys {
- gph1: gph1 {
+ gph1: gph1-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -204,7 +213,7 @@
#interrupt-cells = <2>;
};
- gpr4: gpr4 {
+ gpr4: gpr4-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -212,7 +221,7 @@
#interrupt-cells = <2>;
};
- gpr0: gpr0 {
+ gpr0: gpr0-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -220,7 +229,7 @@
#interrupt-cells = <2>;
};
- gpr1: gpr1 {
+ gpr1: gpr1-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -228,7 +237,7 @@
#interrupt-cells = <2>;
};
- gpr2: gpr2 {
+ gpr2: gpr2-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -236,7 +245,7 @@
#interrupt-cells = <2>;
};
- gpr3: gpr3 {
+ gpr3: gpr3-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -244,139 +253,139 @@
#interrupt-cells = <2>;
};
- sd0_clk: sd0-clk {
+ sd0_clk: sd0-clk-pins {
samsung,pins = "gpr0-0";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS5433_PIN_DRV_FAST_SR4>;
};
- sd0_cmd: sd0-cmd {
+ sd0_cmd: sd0-cmd-pins {
samsung,pins = "gpr0-1";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS5433_PIN_DRV_FAST_SR4>;
};
- sd0_rdqs: sd0-rdqs {
+ sd0_rdqs: sd0-rdqs-pins {
samsung,pins = "gpr0-2";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
samsung,pin-drv = <EXYNOS5433_PIN_DRV_FAST_SR4>;
};
- sd0_qrdy: sd0-qrdy {
+ sd0_qrdy: sd0-qrdy-pins {
samsung,pins = "gpr0-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
samsung,pin-drv = <EXYNOS5433_PIN_DRV_FAST_SR4>;
};
- sd0_bus1: sd0-bus-width1 {
+ sd0_bus1: sd0-bus-width1-pins {
samsung,pins = "gpr1-0";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS5433_PIN_DRV_FAST_SR4>;
};
- sd0_bus4: sd0-bus-width4 {
+ sd0_bus4: sd0-bus-width4-pins {
samsung,pins = "gpr1-1", "gpr1-2", "gpr1-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS5433_PIN_DRV_FAST_SR4>;
};
- sd0_bus8: sd0-bus-width8 {
+ sd0_bus8: sd0-bus-width8-pins {
samsung,pins = "gpr1-4", "gpr1-5", "gpr1-6", "gpr1-7";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS5433_PIN_DRV_FAST_SR4>;
};
- sd1_clk: sd1-clk {
+ sd1_clk: sd1-clk-pins {
samsung,pins = "gpr2-0";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS5433_PIN_DRV_FAST_SR4>;
};
- sd1_cmd: sd1-cmd {
+ sd1_cmd: sd1-cmd-pins {
samsung,pins = "gpr2-1";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS5433_PIN_DRV_FAST_SR4>;
};
- sd1_bus1: sd1-bus-width1 {
+ sd1_bus1: sd1-bus-width1-pins {
samsung,pins = "gpr3-0";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS5433_PIN_DRV_FAST_SR4>;
};
- sd1_bus4: sd1-bus-width4 {
+ sd1_bus4: sd1-bus-width4-pins {
samsung,pins = "gpr3-1", "gpr3-2", "gpr3-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS5433_PIN_DRV_FAST_SR4>;
};
- sd1_bus8: sd1-bus-width8 {
+ sd1_bus8: sd1-bus-width8-pins {
samsung,pins = "gpr3-4", "gpr3-5", "gpr3-6", "gpr3-7";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS5433_PIN_DRV_FAST_SR4>;
};
- pcie_bus: pcie_bus {
+ pcie_bus: pcie-bus-pins {
samsung,pins = "gpr3-4", "gpr3-5", "gpr3-6";
samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
};
- sd2_clk: sd2-clk {
+ sd2_clk: sd2-clk-pins {
samsung,pins = "gpr4-0";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS5433_PIN_DRV_FAST_SR4>;
};
- sd2_cmd: sd2-cmd {
+ sd2_cmd: sd2-cmd-pins {
samsung,pins = "gpr4-1";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS5433_PIN_DRV_FAST_SR4>;
};
- sd2_cd: sd2-cd {
+ sd2_cd: sd2-cd-pins {
samsung,pins = "gpr4-2";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS5433_PIN_DRV_FAST_SR4>;
};
- sd2_bus1: sd2-bus-width1 {
+ sd2_bus1: sd2-bus-width1-pins {
samsung,pins = "gpr4-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS5433_PIN_DRV_FAST_SR4>;
};
- sd2_bus4: sd2-bus-width4 {
+ sd2_bus4: sd2-bus-width4-pins {
samsung,pins = "gpr4-4", "gpr4-5", "gpr4-6";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS5433_PIN_DRV_FAST_SR4>;
};
- sd2_clk_output: sd2-clk-output {
+ sd2_clk_output: sd2-clk-output-pins {
samsung,pins = "gpr4-0";
samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS5433_PIN_DRV_FAST_SR3>;
};
- sd2_cmd_output: sd2-cmd-output {
+ sd2_cmd_output: sd2-cmd-output-pins {
samsung,pins = "gpr4-1";
samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
@@ -385,7 +394,7 @@
};
&pinctrl_imem {
- gpf0: gpf0 {
+ gpf0: gpf0-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -395,7 +404,7 @@
};
&pinctrl_nfc {
- gpj0: gpj0 {
+ gpj0: gpj0-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -403,7 +412,7 @@
#interrupt-cells = <2>;
};
- hs_i2c4_bus: hs-i2c4-bus {
+ hs_i2c4_bus: hs-i2c4-bus-pins {
samsung,pins = "gpj0-1", "gpj0-0";
samsung,pin-function = <EXYNOS_PIN_FUNC_4>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
@@ -412,7 +421,7 @@
};
&pinctrl_peric {
- gpv7: gpv7 {
+ gpv7: gpv7-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -420,7 +429,7 @@
#interrupt-cells = <2>;
};
- gpb0: gpb0 {
+ gpb0: gpb0-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -428,7 +437,7 @@
#interrupt-cells = <2>;
};
- gpc0: gpc0 {
+ gpc0: gpc0-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -436,7 +445,7 @@
#interrupt-cells = <2>;
};
- gpc1: gpc1 {
+ gpc1: gpc1-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -444,7 +453,7 @@
#interrupt-cells = <2>;
};
- gpc2: gpc2 {
+ gpc2: gpc2-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -452,7 +461,7 @@
#interrupt-cells = <2>;
};
- gpc3: gpc3 {
+ gpc3: gpc3-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -460,7 +469,7 @@
#interrupt-cells = <2>;
};
- gpg0: gpg0 {
+ gpg0: gpg0-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -468,7 +477,7 @@
#interrupt-cells = <2>;
};
- gpd0: gpd0 {
+ gpd0: gpd0-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -476,7 +485,7 @@
#interrupt-cells = <2>;
};
- gpd1: gpd1 {
+ gpd1: gpd1-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -484,7 +493,7 @@
#interrupt-cells = <2>;
};
- gpd2: gpd2 {
+ gpd2: gpd2-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -492,7 +501,7 @@
#interrupt-cells = <2>;
};
- gpd4: gpd4 {
+ gpd4: gpd4-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -500,7 +509,7 @@
#interrupt-cells = <2>;
};
- gpd8: gpd8 {
+ gpd8: gpd8-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -508,7 +517,7 @@
#interrupt-cells = <2>;
};
- gpd6: gpd6 {
+ gpd6: gpd6-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -516,7 +525,7 @@
#interrupt-cells = <2>;
};
- gpd7: gpd7 {
+ gpd7: gpd7-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -524,7 +533,7 @@
#interrupt-cells = <2>;
};
- gpg1: gpg1 {
+ gpg1: gpg1-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -532,7 +541,7 @@
#interrupt-cells = <2>;
};
- gpg2: gpg2 {
+ gpg2: gpg2-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -540,7 +549,7 @@
#interrupt-cells = <2>;
};
- gpg3: gpg3 {
+ gpg3: gpg3-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -548,21 +557,21 @@
#interrupt-cells = <2>;
};
- hs_i2c8_bus: hs-i2c8-bus {
+ hs_i2c8_bus: hs-i2c8-bus-pins {
samsung,pins = "gpb0-1", "gpb0-0";
samsung,pin-function = <EXYNOS_PIN_FUNC_4>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS5433_PIN_DRV_FAST_SR1>;
};
- hs_i2c9_bus: hs-i2c9-bus {
+ hs_i2c9_bus: hs-i2c9-bus-pins {
samsung,pins = "gpb0-3", "gpb0-2";
samsung,pin-function = <EXYNOS_PIN_FUNC_4>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS5433_PIN_DRV_FAST_SR1>;
};
- i2s1_bus: i2s1-bus {
+ i2s1_bus: i2s1-bus-pins {
samsung,pins = "gpd4-0", "gpd4-1", "gpd4-2",
"gpd4-3", "gpd4-4";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
@@ -570,7 +579,7 @@
samsung,pin-drv = <EXYNOS5433_PIN_DRV_FAST_SR1>;
};
- pcm1_bus: pcm1-bus {
+ pcm1_bus: pcm1-bus-pins {
samsung,pins = "gpd4-0", "gpd4-1", "gpd4-2",
"gpd4-3", "gpd4-4";
samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
@@ -578,193 +587,193 @@
samsung,pin-drv = <EXYNOS5433_PIN_DRV_FAST_SR1>;
};
- spdif_bus: spdif-bus {
+ spdif_bus: spdif-bus-pins {
samsung,pins = "gpd4-3", "gpd4-4";
samsung,pin-function = <EXYNOS_PIN_FUNC_4>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS5433_PIN_DRV_FAST_SR1>;
};
- fimc_is_spi_pin0: fimc-is-spi-pin0 {
+ fimc_is_spi_pin0: fimc-is-spi-pin0-pins {
samsung,pins = "gpc3-3", "gpc3-2", "gpc3-1", "gpc3-0";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS5433_PIN_DRV_FAST_SR1>;
};
- fimc_is_spi_pin1: fimc-is-spi-pin1 {
+ fimc_is_spi_pin1: fimc-is-spi-pin1-pins {
samsung,pins = "gpc3-7", "gpc3-6", "gpc3-5", "gpc3-4";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS5433_PIN_DRV_FAST_SR1>;
};
- uart0_bus: uart0-bus {
+ uart0_bus: uart0-bus-pins {
samsung,pins = "gpd0-3", "gpd0-2", "gpd0-1", "gpd0-0";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
};
- hs_i2c2_bus: hs-i2c2-bus {
+ hs_i2c2_bus: hs-i2c2-bus-pins {
samsung,pins = "gpd0-3", "gpd0-2";
samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS5433_PIN_DRV_FAST_SR1>;
};
- uart2_bus: uart2-bus {
+ uart2_bus: uart2-bus-pins {
samsung,pins = "gpd1-5", "gpd1-4";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
};
- uart1_bus: uart1-bus {
+ uart1_bus: uart1-bus-pins {
samsung,pins = "gpd1-3", "gpd1-2", "gpd1-1", "gpd1-0";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
};
- hs_i2c3_bus: hs-i2c3-bus {
+ hs_i2c3_bus: hs-i2c3-bus-pins {
samsung,pins = "gpd1-3", "gpd1-2";
samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS5433_PIN_DRV_FAST_SR1>;
};
- hs_i2c0_bus: hs-i2c0-bus {
+ hs_i2c0_bus: hs-i2c0-bus-pins {
samsung,pins = "gpd2-1", "gpd2-0";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS5433_PIN_DRV_FAST_SR1>;
};
- hs_i2c1_bus: hs-i2c1-bus {
+ hs_i2c1_bus: hs-i2c1-bus-pins {
samsung,pins = "gpd2-3", "gpd2-2";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS5433_PIN_DRV_FAST_SR1>;
};
- pwm0_out: pwm0-out {
+ pwm0_out: pwm0-out-pins {
samsung,pins = "gpd2-4";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS5433_PIN_DRV_FAST_SR1>;
};
- pwm1_out: pwm1-out {
+ pwm1_out: pwm1-out-pins {
samsung,pins = "gpd2-5";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS5433_PIN_DRV_FAST_SR1>;
};
- pwm2_out: pwm2-out {
+ pwm2_out: pwm2-out-pins {
samsung,pins = "gpd2-6";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS5433_PIN_DRV_FAST_SR1>;
};
- pwm3_out: pwm3-out {
+ pwm3_out: pwm3-out-pins {
samsung,pins = "gpd2-7";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS5433_PIN_DRV_FAST_SR1>;
};
- spi1_bus: spi1-bus {
+ spi1_bus: spi1-bus-pins {
samsung,pins = "gpd6-2", "gpd6-4", "gpd6-5";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS5433_PIN_DRV_FAST_SR1>;
};
- hs_i2c7_bus: hs-i2c7-bus {
+ hs_i2c7_bus: hs-i2c7-bus-pins {
samsung,pins = "gpd2-7", "gpd2-6";
samsung,pin-function = <EXYNOS_PIN_FUNC_4>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS5433_PIN_DRV_FAST_SR1>;
};
- spi0_bus: spi0-bus {
+ spi0_bus: spi0-bus-pins {
samsung,pins = "gpd8-0", "gpd6-0", "gpd6-1";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS5433_PIN_DRV_FAST_SR1>;
};
- hs_i2c10_bus: hs-i2c10-bus {
+ hs_i2c10_bus: hs-i2c10-bus-pins {
samsung,pins = "gpg3-1", "gpg3-0";
samsung,pin-function = <EXYNOS_PIN_FUNC_4>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS5433_PIN_DRV_FAST_SR1>;
};
- hs_i2c11_bus: hs-i2c11-bus {
+ hs_i2c11_bus: hs-i2c11-bus-pins {
samsung,pins = "gpg3-3", "gpg3-2";
samsung,pin-function = <EXYNOS_PIN_FUNC_4>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS5433_PIN_DRV_FAST_SR1>;
};
- spi3_bus: spi3-bus {
+ spi3_bus: spi3-bus-pins {
samsung,pins = "gpg3-4", "gpg3-6", "gpg3-7";
samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS5433_PIN_DRV_FAST_SR1>;
};
- spi4_bus: spi4-bus {
+ spi4_bus: spi4-bus-pins {
samsung,pins = "gpv7-1", "gpv7-3", "gpv7-4";
samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS5433_PIN_DRV_FAST_SR1>;
};
- fimc_is_uart: fimc-is-uart {
+ fimc_is_uart: fimc-is-uart-pins {
samsung,pins = "gpc1-1", "gpc0-7";
samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS5433_PIN_DRV_FAST_SR1>;
};
- fimc_is_ch0_i2c: fimc-is-ch0_i2c {
+ fimc_is_ch0_i2c: fimc-is-ch0-i2c-pins {
samsung,pins = "gpc2-1", "gpc2-0";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS5433_PIN_DRV_FAST_SR1>;
};
- fimc_is_ch0_mclk: fimc-is-ch0_mclk {
+ fimc_is_ch0_mclk: fimc-is-ch0-mclk-pins {
samsung,pins = "gpd7-0";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS5433_PIN_DRV_FAST_SR1>;
};
- fimc_is_ch1_i2c: fimc-is-ch1-i2c {
+ fimc_is_ch1_i2c: fimc-is-ch1-i2c-pins {
samsung,pins = "gpc2-3", "gpc2-2";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS5433_PIN_DRV_FAST_SR1>;
};
- fimc_is_ch1_mclk: fimc-is-ch1-mclk {
+ fimc_is_ch1_mclk: fimc-is-ch1-mclk-pins {
samsung,pins = "gpd7-1";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS5433_PIN_DRV_FAST_SR1>;
};
- fimc_is_ch2_i2c: fimc-is-ch2-i2c {
+ fimc_is_ch2_i2c: fimc-is-ch2-i2c-pins {
samsung,pins = "gpc2-5", "gpc2-4";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS5433_PIN_DRV_FAST_SR1>;
};
- fimc_is_ch2_mclk: fimc-is-ch2-mclk {
+ fimc_is_ch2_mclk: fimc-is-ch2-mclk-pins {
samsung,pins = "gpd7-2";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
@@ -773,7 +782,7 @@
};
&pinctrl_touch {
- gpj1: gpj1 {
+ gpj1: gpj1-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -781,7 +790,7 @@
#interrupt-cells = <2>;
};
- hs_i2c5_bus: hs-i2c5-bus {
+ hs_i2c5_bus: hs-i2c5-bus-pins {
samsung,pins = "gpj1-1", "gpj1-0";
samsung,pin-function = <EXYNOS_PIN_FUNC_4>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
diff --git a/arch/arm64/boot/dts/exynos/exynos5433-tm2-common.dtsi b/arch/arm64/boot/dts/exynos/exynos5433-tm2-common.dtsi
index cbcc01a66aab..91c9bd1b47dd 100644
--- a/arch/arm64/boot/dts/exynos/exynos5433-tm2-common.dtsi
+++ b/arch/arm64/boot/dts/exynos/exynos5433-tm2-common.dtsi
@@ -858,10 +858,10 @@
interrupts = <5 IRQ_TYPE_EDGE_FALLING>;
reg = <0x66>;
- muic: max77843-muic {
+ muic: extcon {
compatible = "maxim,max77843-muic";
- musb_con: musb-connector {
+ musb_con: connector {
compatible = "samsung,usb-connector-11pin",
"usb-b-connector";
label = "micro-USB";
@@ -871,6 +871,17 @@
#address-cells = <1>;
#size-cells = <0>;
+ port@0 {
+ /*
+ * TODO: The DTS this is based on does not have
+ * port@0 which is a required property. The ports
+ * look incomplete and need fixing.
+ * Add a disabled port just to satisfy dtschema.
+ */
+ reg = <0>;
+ status = "disabled";
+ };
+
port@3 {
reg = <3>;
musb_con_to_mhl: endpoint {
@@ -910,7 +921,7 @@
};
};
- haptic: max77843-haptic {
+ haptic: motor-driver {
compatible = "maxim,max77843-haptic";
haptic-supply = <&ldo38_reg>;
pwms = <&pwm 0 33670 0>;
@@ -1011,80 +1022,80 @@
pinctrl-0 = <&initial_alive>;
initial_alive: initial-state {
- PIN(INPUT, gpa0-0, DOWN, FAST_SR1);
- PIN(INPUT, gpa0-1, NONE, FAST_SR1);
- PIN(INPUT, gpa0-2, DOWN, FAST_SR1);
- PIN(INPUT, gpa0-3, NONE, FAST_SR1);
- PIN(INPUT, gpa0-4, NONE, FAST_SR1);
- PIN(INPUT, gpa0-5, DOWN, FAST_SR1);
- PIN(INPUT, gpa0-6, NONE, FAST_SR1);
- PIN(INPUT, gpa0-7, NONE, FAST_SR1);
-
- PIN(INPUT, gpa1-0, UP, FAST_SR1);
- PIN(INPUT, gpa1-1, UP, FAST_SR1);
- PIN(INPUT, gpa1-2, NONE, FAST_SR1);
- PIN(INPUT, gpa1-3, DOWN, FAST_SR1);
- PIN(INPUT, gpa1-4, DOWN, FAST_SR1);
- PIN(INPUT, gpa1-5, NONE, FAST_SR1);
- PIN(INPUT, gpa1-6, NONE, FAST_SR1);
- PIN(INPUT, gpa1-7, NONE, FAST_SR1);
-
- PIN(INPUT, gpa2-0, NONE, FAST_SR1);
- PIN(INPUT, gpa2-1, NONE, FAST_SR1);
- PIN(INPUT, gpa2-2, NONE, FAST_SR1);
- PIN(INPUT, gpa2-3, DOWN, FAST_SR1);
- PIN(INPUT, gpa2-4, NONE, FAST_SR1);
- PIN(INPUT, gpa2-5, DOWN, FAST_SR1);
- PIN(INPUT, gpa2-6, DOWN, FAST_SR1);
- PIN(INPUT, gpa2-7, NONE, FAST_SR1);
-
- PIN(INPUT, gpa3-0, DOWN, FAST_SR1);
- PIN(INPUT, gpa3-1, DOWN, FAST_SR1);
- PIN(INPUT, gpa3-2, NONE, FAST_SR1);
- PIN(INPUT, gpa3-3, DOWN, FAST_SR1);
- PIN(INPUT, gpa3-4, NONE, FAST_SR1);
- PIN(INPUT, gpa3-5, DOWN, FAST_SR1);
- PIN(INPUT, gpa3-6, DOWN, FAST_SR1);
- PIN(INPUT, gpa3-7, DOWN, FAST_SR1);
-
- PIN(INPUT, gpf1-0, NONE, FAST_SR1);
- PIN(INPUT, gpf1-1, NONE, FAST_SR1);
- PIN(INPUT, gpf1-2, DOWN, FAST_SR1);
- PIN(INPUT, gpf1-4, UP, FAST_SR1);
- PIN(OUTPUT, gpf1-5, NONE, FAST_SR1);
- PIN(INPUT, gpf1-6, DOWN, FAST_SR1);
- PIN(INPUT, gpf1-7, DOWN, FAST_SR1);
-
- PIN(INPUT, gpf2-0, DOWN, FAST_SR1);
- PIN(INPUT, gpf2-1, DOWN, FAST_SR1);
- PIN(INPUT, gpf2-2, DOWN, FAST_SR1);
- PIN(INPUT, gpf2-3, DOWN, FAST_SR1);
-
- PIN(INPUT, gpf3-0, DOWN, FAST_SR1);
- PIN(INPUT, gpf3-1, DOWN, FAST_SR1);
- PIN(INPUT, gpf3-2, NONE, FAST_SR1);
- PIN(INPUT, gpf3-3, DOWN, FAST_SR1);
-
- PIN(INPUT, gpf4-0, DOWN, FAST_SR1);
- PIN(INPUT, gpf4-1, DOWN, FAST_SR1);
- PIN(INPUT, gpf4-2, DOWN, FAST_SR1);
- PIN(INPUT, gpf4-3, DOWN, FAST_SR1);
- PIN(INPUT, gpf4-4, DOWN, FAST_SR1);
- PIN(INPUT, gpf4-5, DOWN, FAST_SR1);
- PIN(INPUT, gpf4-6, DOWN, FAST_SR1);
- PIN(INPUT, gpf4-7, DOWN, FAST_SR1);
-
- PIN(INPUT, gpf5-0, DOWN, FAST_SR1);
- PIN(INPUT, gpf5-1, DOWN, FAST_SR1);
- PIN(INPUT, gpf5-2, DOWN, FAST_SR1);
- PIN(INPUT, gpf5-3, DOWN, FAST_SR1);
- PIN(OUTPUT, gpf5-4, NONE, FAST_SR1);
- PIN(INPUT, gpf5-5, DOWN, FAST_SR1);
- PIN(INPUT, gpf5-6, DOWN, FAST_SR1);
- PIN(INPUT, gpf5-7, DOWN, FAST_SR1);
+ PIN_IN(gpa0-0, DOWN, FAST_SR1);
+ PIN_IN(gpa0-1, NONE, FAST_SR1);
+ PIN_IN(gpa0-2, DOWN, FAST_SR1);
+ PIN_IN(gpa0-3, NONE, FAST_SR1);
+ PIN_IN(gpa0-4, NONE, FAST_SR1);
+ PIN_IN(gpa0-5, DOWN, FAST_SR1);
+ PIN_IN(gpa0-6, NONE, FAST_SR1);
+ PIN_IN(gpa0-7, NONE, FAST_SR1);
+
+ PIN_IN(gpa1-0, UP, FAST_SR1);
+ PIN_IN(gpa1-1, UP, FAST_SR1);
+ PIN_IN(gpa1-2, NONE, FAST_SR1);
+ PIN_IN(gpa1-3, DOWN, FAST_SR1);
+ PIN_IN(gpa1-4, DOWN, FAST_SR1);
+ PIN_IN(gpa1-5, NONE, FAST_SR1);
+ PIN_IN(gpa1-6, NONE, FAST_SR1);
+ PIN_IN(gpa1-7, NONE, FAST_SR1);
+
+ PIN_IN(gpa2-0, NONE, FAST_SR1);
+ PIN_IN(gpa2-1, NONE, FAST_SR1);
+ PIN_IN(gpa2-2, NONE, FAST_SR1);
+ PIN_IN(gpa2-3, DOWN, FAST_SR1);
+ PIN_IN(gpa2-4, NONE, FAST_SR1);
+ PIN_IN(gpa2-5, DOWN, FAST_SR1);
+ PIN_IN(gpa2-6, DOWN, FAST_SR1);
+ PIN_IN(gpa2-7, NONE, FAST_SR1);
+
+ PIN_IN(gpa3-0, DOWN, FAST_SR1);
+ PIN_IN(gpa3-1, DOWN, FAST_SR1);
+ PIN_IN(gpa3-2, NONE, FAST_SR1);
+ PIN_IN(gpa3-3, DOWN, FAST_SR1);
+ PIN_IN(gpa3-4, NONE, FAST_SR1);
+ PIN_IN(gpa3-5, DOWN, FAST_SR1);
+ PIN_IN(gpa3-6, DOWN, FAST_SR1);
+ PIN_IN(gpa3-7, DOWN, FAST_SR1);
+
+ PIN_IN(gpf1-0, NONE, FAST_SR1);
+ PIN_IN(gpf1-1, NONE, FAST_SR1);
+ PIN_IN(gpf1-2, DOWN, FAST_SR1);
+ PIN_IN(gpf1-4, UP, FAST_SR1);
+ PIN_OT(gpf1-5, NONE, FAST_SR1);
+ PIN_IN(gpf1-6, DOWN, FAST_SR1);
+ PIN_IN(gpf1-7, DOWN, FAST_SR1);
+
+ PIN_IN(gpf2-0, DOWN, FAST_SR1);
+ PIN_IN(gpf2-1, DOWN, FAST_SR1);
+ PIN_IN(gpf2-2, DOWN, FAST_SR1);
+ PIN_IN(gpf2-3, DOWN, FAST_SR1);
+
+ PIN_IN(gpf3-0, DOWN, FAST_SR1);
+ PIN_IN(gpf3-1, DOWN, FAST_SR1);
+ PIN_IN(gpf3-2, NONE, FAST_SR1);
+ PIN_IN(gpf3-3, DOWN, FAST_SR1);
+
+ PIN_IN(gpf4-0, DOWN, FAST_SR1);
+ PIN_IN(gpf4-1, DOWN, FAST_SR1);
+ PIN_IN(gpf4-2, DOWN, FAST_SR1);
+ PIN_IN(gpf4-3, DOWN, FAST_SR1);
+ PIN_IN(gpf4-4, DOWN, FAST_SR1);
+ PIN_IN(gpf4-5, DOWN, FAST_SR1);
+ PIN_IN(gpf4-6, DOWN, FAST_SR1);
+ PIN_IN(gpf4-7, DOWN, FAST_SR1);
+
+ PIN_IN(gpf5-0, DOWN, FAST_SR1);
+ PIN_IN(gpf5-1, DOWN, FAST_SR1);
+ PIN_IN(gpf5-2, DOWN, FAST_SR1);
+ PIN_IN(gpf5-3, DOWN, FAST_SR1);
+ PIN_OT(gpf5-4, NONE, FAST_SR1);
+ PIN_IN(gpf5-5, DOWN, FAST_SR1);
+ PIN_IN(gpf5-6, DOWN, FAST_SR1);
+ PIN_IN(gpf5-7, DOWN, FAST_SR1);
};
- te_irq: te-irq {
+ te_irq: te-irq-pins {
samsung,pins = "gpf1-3";
samsung,pin-function = <0xf>;
};
@@ -1095,8 +1106,8 @@
pinctrl-0 = <&initial_cpif>;
initial_cpif: initial-state {
- PIN(INPUT, gpv6-0, DOWN, FAST_SR1);
- PIN(INPUT, gpv6-1, DOWN, FAST_SR1);
+ PIN_IN(gpv6-0, DOWN, FAST_SR1);
+ PIN_IN(gpv6-1, DOWN, FAST_SR1);
};
};
@@ -1104,13 +1115,16 @@
pinctrl-names = "default";
pinctrl-0 = <&initial_ese>;
- pcie_wlanen: pcie-wlanen {
- PIN(INPUT, gpj2-0, UP, FAST_SR4);
+ pcie_wlanen: pcie-wlanen-pins {
+ samsung,pins = "gpj2-0";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+ samsung,pin-drv = <EXYNOS5433_PIN_DRV_FAST_SR4>;
};
initial_ese: initial-state {
- PIN(INPUT, gpj2-1, DOWN, FAST_SR1);
- PIN(INPUT, gpj2-2, DOWN, FAST_SR1);
+ PIN_IN(gpj2-1, DOWN, FAST_SR1);
+ PIN_IN(gpj2-2, DOWN, FAST_SR1);
};
};
@@ -1119,11 +1133,11 @@
pinctrl-0 = <&initial_fsys>;
initial_fsys: initial-state {
- PIN(INPUT, gpr3-0, NONE, FAST_SR1);
- PIN(INPUT, gpr3-1, DOWN, FAST_SR1);
- PIN(INPUT, gpr3-2, DOWN, FAST_SR1);
- PIN(INPUT, gpr3-3, DOWN, FAST_SR1);
- PIN(INPUT, gpr3-7, NONE, FAST_SR1);
+ PIN_IN(gpr3-0, NONE, FAST_SR1);
+ PIN_IN(gpr3-1, DOWN, FAST_SR1);
+ PIN_IN(gpr3-2, DOWN, FAST_SR1);
+ PIN_IN(gpr3-3, DOWN, FAST_SR1);
+ PIN_IN(gpr3-7, NONE, FAST_SR1);
};
};
@@ -1132,14 +1146,14 @@
pinctrl-0 = <&initial_imem>;
initial_imem: initial-state {
- PIN(INPUT, gpf0-0, UP, FAST_SR1);
- PIN(INPUT, gpf0-1, UP, FAST_SR1);
- PIN(INPUT, gpf0-2, DOWN, FAST_SR1);
- PIN(INPUT, gpf0-3, UP, FAST_SR1);
- PIN(INPUT, gpf0-4, DOWN, FAST_SR1);
- PIN(INPUT, gpf0-5, NONE, FAST_SR1);
- PIN(INPUT, gpf0-6, DOWN, FAST_SR1);
- PIN(INPUT, gpf0-7, UP, FAST_SR1);
+ PIN_IN(gpf0-0, UP, FAST_SR1);
+ PIN_IN(gpf0-1, UP, FAST_SR1);
+ PIN_IN(gpf0-2, DOWN, FAST_SR1);
+ PIN_IN(gpf0-3, UP, FAST_SR1);
+ PIN_IN(gpf0-4, DOWN, FAST_SR1);
+ PIN_IN(gpf0-5, NONE, FAST_SR1);
+ PIN_IN(gpf0-6, DOWN, FAST_SR1);
+ PIN_IN(gpf0-7, UP, FAST_SR1);
};
};
@@ -1148,7 +1162,7 @@
pinctrl-0 = <&initial_nfc>;
initial_nfc: initial-state {
- PIN(INPUT, gpj0-2, DOWN, FAST_SR1);
+ PIN_IN(gpj0-2, DOWN, FAST_SR1);
};
};
@@ -1157,53 +1171,53 @@
pinctrl-0 = <&initial_peric>;
initial_peric: initial-state {
- PIN(INPUT, gpv7-0, DOWN, FAST_SR1);
- PIN(INPUT, gpv7-1, DOWN, FAST_SR1);
- PIN(INPUT, gpv7-2, NONE, FAST_SR1);
- PIN(INPUT, gpv7-3, DOWN, FAST_SR1);
- PIN(INPUT, gpv7-4, DOWN, FAST_SR1);
- PIN(INPUT, gpv7-5, DOWN, FAST_SR1);
+ PIN_IN(gpv7-0, DOWN, FAST_SR1);
+ PIN_IN(gpv7-1, DOWN, FAST_SR1);
+ PIN_IN(gpv7-2, NONE, FAST_SR1);
+ PIN_IN(gpv7-3, DOWN, FAST_SR1);
+ PIN_IN(gpv7-4, DOWN, FAST_SR1);
+ PIN_IN(gpv7-5, DOWN, FAST_SR1);
- PIN(INPUT, gpb0-4, DOWN, FAST_SR1);
+ PIN_IN(gpb0-4, DOWN, FAST_SR1);
- PIN(INPUT, gpc0-2, DOWN, FAST_SR1);
- PIN(INPUT, gpc0-5, DOWN, FAST_SR1);
- PIN(INPUT, gpc0-7, DOWN, FAST_SR1);
+ PIN_IN(gpc0-2, DOWN, FAST_SR1);
+ PIN_IN(gpc0-5, DOWN, FAST_SR1);
+ PIN_IN(gpc0-7, DOWN, FAST_SR1);
- PIN(INPUT, gpc1-1, DOWN, FAST_SR1);
+ PIN_IN(gpc1-1, DOWN, FAST_SR1);
- PIN(INPUT, gpc3-4, NONE, FAST_SR1);
- PIN(INPUT, gpc3-5, NONE, FAST_SR1);
- PIN(INPUT, gpc3-6, NONE, FAST_SR1);
- PIN(INPUT, gpc3-7, NONE, FAST_SR1);
+ PIN_IN(gpc3-4, NONE, FAST_SR1);
+ PIN_IN(gpc3-5, NONE, FAST_SR1);
+ PIN_IN(gpc3-6, NONE, FAST_SR1);
+ PIN_IN(gpc3-7, NONE, FAST_SR1);
- PIN(OUTPUT, gpg0-0, NONE, FAST_SR1);
- PIN(2, gpg0-1, DOWN, FAST_SR1);
+ PIN_OT(gpg0-0, NONE, FAST_SR1);
+ PIN_F2(gpg0-1, DOWN, FAST_SR1);
- PIN(INPUT, gpd2-5, DOWN, FAST_SR1);
+ PIN_IN(gpd2-5, DOWN, FAST_SR1);
- PIN(INPUT, gpd4-0, NONE, FAST_SR1);
- PIN(INPUT, gpd4-1, DOWN, FAST_SR1);
- PIN(INPUT, gpd4-2, DOWN, FAST_SR1);
- PIN(INPUT, gpd4-3, DOWN, FAST_SR1);
- PIN(INPUT, gpd4-4, DOWN, FAST_SR1);
+ PIN_IN(gpd4-0, NONE, FAST_SR1);
+ PIN_IN(gpd4-1, DOWN, FAST_SR1);
+ PIN_IN(gpd4-2, DOWN, FAST_SR1);
+ PIN_IN(gpd4-3, DOWN, FAST_SR1);
+ PIN_IN(gpd4-4, DOWN, FAST_SR1);
- PIN(INPUT, gpd6-3, DOWN, FAST_SR1);
+ PIN_IN(gpd6-3, DOWN, FAST_SR1);
- PIN(INPUT, gpd8-1, UP, FAST_SR1);
+ PIN_IN(gpd8-1, UP, FAST_SR1);
- PIN(INPUT, gpg1-0, DOWN, FAST_SR1);
- PIN(INPUT, gpg1-1, DOWN, FAST_SR1);
- PIN(INPUT, gpg1-2, DOWN, FAST_SR1);
- PIN(INPUT, gpg1-3, DOWN, FAST_SR1);
- PIN(INPUT, gpg1-4, DOWN, FAST_SR1);
+ PIN_IN(gpg1-0, DOWN, FAST_SR1);
+ PIN_IN(gpg1-1, DOWN, FAST_SR1);
+ PIN_IN(gpg1-2, DOWN, FAST_SR1);
+ PIN_IN(gpg1-3, DOWN, FAST_SR1);
+ PIN_IN(gpg1-4, DOWN, FAST_SR1);
- PIN(INPUT, gpg2-0, DOWN, FAST_SR1);
- PIN(INPUT, gpg2-1, DOWN, FAST_SR1);
+ PIN_IN(gpg2-0, DOWN, FAST_SR1);
+ PIN_IN(gpg2-1, DOWN, FAST_SR1);
- PIN(INPUT, gpg3-0, DOWN, FAST_SR1);
- PIN(INPUT, gpg3-1, DOWN, FAST_SR1);
- PIN(INPUT, gpg3-5, DOWN, FAST_SR1);
+ PIN_IN(gpg3-0, DOWN, FAST_SR1);
+ PIN_IN(gpg3-1, DOWN, FAST_SR1);
+ PIN_IN(gpg3-5, DOWN, FAST_SR1);
};
};
@@ -1212,7 +1226,7 @@
pinctrl-0 = <&initial_touch>;
initial_touch: initial-state {
- PIN(INPUT, gpj1-2, DOWN, FAST_SR1);
+ PIN_IN(gpj1-2, DOWN, FAST_SR1);
};
};
diff --git a/arch/arm64/boot/dts/exynos/exynos5433.dtsi b/arch/arm64/boot/dts/exynos/exynos5433.dtsi
index bfe4ed8a23d6..661567d2dd7a 100644
--- a/arch/arm64/boot/dts/exynos/exynos5433.dtsi
+++ b/arch/arm64/boot/dts/exynos/exynos5433.dtsi
@@ -1858,7 +1858,7 @@
status = "disabled";
};
- pdma0: pdma@15610000 {
+ pdma0: dma-controller@15610000 {
compatible = "arm,pl330", "arm,primecell";
reg = <0x15610000 0x1000>;
interrupts = <GIC_SPI 228 IRQ_TYPE_LEVEL_HIGH>;
@@ -1869,7 +1869,7 @@
#dma-requests = <32>;
};
- pdma1: pdma@15600000 {
+ pdma1: dma-controller@15600000 {
compatible = "arm,pl330", "arm,primecell";
reg = <0x15600000 0x1000>;
interrupts = <GIC_SPI 246 IRQ_TYPE_LEVEL_HIGH>;
@@ -1885,13 +1885,12 @@
reg = <0x11400000 0x100>, <0x11500000 0x08>;
clocks = <&cmu_aud CLK_PCLK_SFR0_CTRL>;
clock-names = "sfr0_ctrl";
- samsung,pmu-syscon = <&pmu_system_controller>;
power-domains = <&pd_aud>;
#address-cells = <1>;
#size-cells = <1>;
ranges;
- adma: adma@11420000 {
+ adma: dma-controller@11420000 {
compatible = "arm,pl330", "arm,primecell";
reg = <0x11420000 0x1000>;
interrupts = <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>;
diff --git a/arch/arm64/boot/dts/exynos/exynos7-espresso.dts b/arch/arm64/boot/dts/exynos/exynos7-espresso.dts
index 125c03f351d9..0895e818d3c1 100644
--- a/arch/arm64/boot/dts/exynos/exynos7-espresso.dts
+++ b/arch/arm64/boot/dts/exynos/exynos7-espresso.dts
@@ -354,7 +354,7 @@
};
&pinctrl_alive {
- pmic_irq: pmic-irq {
+ pmic_irq: pmic-irq-pins {
samsung,pins = "gpa0-2";
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
@@ -393,14 +393,14 @@
};
&pinctrl_bus1 {
- usb30_vbus_en: usb30-vbus-en {
+ usb30_vbus_en: usb30-vbus-en-pins {
samsung,pins = "gph1-1";
samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- usb3drd_boost_en: usb3drd-boost-en {
+ usb3drd_boost_en: usb3drd-boost-en-pins {
samsung,pins = "gpf4-1";
samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
@@ -412,6 +412,11 @@
status = "okay";
};
+&usbdrd {
+ vdd10-supply = <&ldo4_reg>;
+ vdd33-supply = <&ldo6_reg>;
+};
+
&usbdrd_phy {
vbus-supply = <&usb30_vbus_reg>;
vbus-boost-supply = <&usb3drd_boost_5v>;
diff --git a/arch/arm64/boot/dts/exynos/exynos7-pinctrl.dtsi b/arch/arm64/boot/dts/exynos/exynos7-pinctrl.dtsi
index 472dd649aa7e..be9b971f3697 100644
--- a/arch/arm64/boot/dts/exynos/exynos7-pinctrl.dtsi
+++ b/arch/arm64/boot/dts/exynos/exynos7-pinctrl.dtsi
@@ -12,7 +12,7 @@
#include <dt-bindings/pinctrl/samsung.h>
&pinctrl_alive {
- gpa0: gpa0 {
+ gpa0: gpa0-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -29,7 +29,7 @@
<GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>;
};
- gpa1: gpa1 {
+ gpa1: gpa1-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -46,7 +46,7 @@
<GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>;
};
- gpa2: gpa2 {
+ gpa2: gpa2-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -54,7 +54,7 @@
#interrupt-cells = <2>;
};
- gpa3: gpa3 {
+ gpa3: gpa3-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -64,7 +64,7 @@
};
&pinctrl_bus0 {
- gpb0: gpb0 {
+ gpb0: gpb0-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -72,7 +72,7 @@
#interrupt-cells = <2>;
};
- gpc0: gpc0 {
+ gpc0: gpc0-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -80,7 +80,7 @@
#interrupt-cells = <2>;
};
- gpc1: gpc1 {
+ gpc1: gpc1-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -88,7 +88,7 @@
#interrupt-cells = <2>;
};
- gpc2: gpc2 {
+ gpc2: gpc2-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -96,7 +96,7 @@
#interrupt-cells = <2>;
};
- gpc3: gpc3 {
+ gpc3: gpc3-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -104,7 +104,7 @@
#interrupt-cells = <2>;
};
- gpd0: gpd0 {
+ gpd0: gpd0-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -112,7 +112,7 @@
#interrupt-cells = <2>;
};
- gpd1: gpd1 {
+ gpd1: gpd1-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -120,7 +120,7 @@
#interrupt-cells = <2>;
};
- gpd2: gpd2 {
+ gpd2: gpd2-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -128,7 +128,7 @@
#interrupt-cells = <2>;
};
- gpd4: gpd4 {
+ gpd4: gpd4-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -136,7 +136,7 @@
#interrupt-cells = <2>;
};
- gpd5: gpd5 {
+ gpd5: gpd5-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -144,7 +144,7 @@
#interrupt-cells = <2>;
};
- gpd6: gpd6 {
+ gpd6: gpd6-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -152,7 +152,7 @@
#interrupt-cells = <2>;
};
- gpd7: gpd7 {
+ gpd7: gpd7-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -160,7 +160,7 @@
#interrupt-cells = <2>;
};
- gpd8: gpd8 {
+ gpd8: gpd8-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -168,7 +168,7 @@
#interrupt-cells = <2>;
};
- gpg0: gpg0 {
+ gpg0: gpg0-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -176,7 +176,7 @@
#interrupt-cells = <2>;
};
- gpg3: gpg3 {
+ gpg3: gpg3-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -184,161 +184,161 @@
#interrupt-cells = <2>;
};
- hs_i2c10_bus: hs-i2c10-bus {
+ hs_i2c10_bus: hs-i2c10-bus-pins {
samsung,pins = "gpb0-1", "gpb0-0";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- hs_i2c11_bus: hs-i2c11-bus {
+ hs_i2c11_bus: hs-i2c11-bus-pins {
samsung,pins = "gpb0-3", "gpb0-2";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- hs_i2c2_bus: hs-i2c2-bus {
+ hs_i2c2_bus: hs-i2c2-bus-pins {
samsung,pins = "gpd0-3", "gpd0-2";
samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- uart0_data: uart0-data {
+ uart0_data: uart0-data-pins {
samsung,pins = "gpd0-0", "gpd0-1";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- uart0_fctl: uart0-fctl {
+ uart0_fctl: uart0-fctl-pins {
samsung,pins = "gpd0-2", "gpd0-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- uart2_data: uart2-data {
+ uart2_data: uart2-data-pins {
samsung,pins = "gpd1-4", "gpd1-5";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- hs_i2c3_bus: hs-i2c3-bus {
+ hs_i2c3_bus: hs-i2c3-bus-pins {
samsung,pins = "gpd1-3", "gpd1-2";
samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- uart1_data: uart1-data {
+ uart1_data: uart1-data-pins {
samsung,pins = "gpd1-0", "gpd1-1";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- uart1_fctl: uart1-fctl {
+ uart1_fctl: uart1-fctl-pins {
samsung,pins = "gpd1-2", "gpd1-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- hs_i2c0_bus: hs-i2c0-bus {
+ hs_i2c0_bus: hs-i2c0-bus-pins {
samsung,pins = "gpd2-1", "gpd2-0";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- hs_i2c1_bus: hs-i2c1-bus {
+ hs_i2c1_bus: hs-i2c1-bus-pins {
samsung,pins = "gpd2-3", "gpd2-2";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- hs_i2c9_bus: hs-i2c9-bus {
+ hs_i2c9_bus: hs-i2c9-bus-pins {
samsung,pins = "gpd2-7", "gpd2-6";
samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- pwm0_out: pwm0-out {
+ pwm0_out: pwm0-out-pins {
samsung,pins = "gpd2-4";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- pwm1_out: pwm1-out {
+ pwm1_out: pwm1-out-pins {
samsung,pins = "gpd2-5";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- pwm2_out: pwm2-out {
+ pwm2_out: pwm2-out-pins {
samsung,pins = "gpd2-6";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- pwm3_out: pwm3-out {
+ pwm3_out: pwm3-out-pins {
samsung,pins = "gpd2-7";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- hs_i2c8_bus: hs-i2c8-bus {
+ hs_i2c8_bus: hs-i2c8-bus-pins {
samsung,pins = "gpd5-3", "gpd5-2";
samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- uart3_data: uart3-data {
+ uart3_data: uart3-data-pins {
samsung,pins = "gpd5-0", "gpd5-1";
samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- spi2_bus: spi2-bus {
+ spi2_bus: spi2-bus-pins {
samsung,pins = "gpd5-0", "gpd5-1", "gpd5-2", "gpd5-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- spi1_bus: spi1-bus {
+ spi1_bus: spi1-bus-pins {
samsung,pins = "gpd6-2", "gpd6-3", "gpd6-4", "gpd6-5";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- spi0_bus: spi0-bus {
+ spi0_bus: spi0-bus-pins {
samsung,pins = "gpd8-0", "gpd8-1", "gpd6-0", "gpd6-1";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- hs_i2c4_bus: hs-i2c4-bus {
+ hs_i2c4_bus: hs-i2c4-bus-pins {
samsung,pins = "gpg3-1", "gpg3-0";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- hs_i2c5_bus: hs-i2c5-bus {
+ hs_i2c5_bus: hs-i2c5-bus-pins {
samsung,pins = "gpg3-3", "gpg3-2";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
@@ -347,7 +347,7 @@
};
&pinctrl_nfc {
- gpj0: gpj0 {
+ gpj0: gpj0-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -355,7 +355,7 @@
#interrupt-cells = <2>;
};
- hs_i2c6_bus: hs-i2c6-bus {
+ hs_i2c6_bus: hs-i2c6-bus-pins {
samsung,pins = "gpj0-1", "gpj0-0";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
@@ -364,7 +364,7 @@
};
&pinctrl_touch {
- gpj1: gpj1 {
+ gpj1: gpj1-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -372,7 +372,7 @@
#interrupt-cells = <2>;
};
- hs_i2c7_bus: hs-i2c7-bus {
+ hs_i2c7_bus: hs-i2c7-bus-pins {
samsung,pins = "gpj1-1", "gpj1-0";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
@@ -381,7 +381,7 @@
};
&pinctrl_ff {
- gpg4: gpg4 {
+ gpg4: gpg4-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -389,7 +389,7 @@
#interrupt-cells = <2>;
};
- spi3_bus: spi3-bus {
+ spi3_bus: spi3-bus-pins {
samsung,pins = "gpg4-0", "gpg4-1", "gpg4-2", "gpg4-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
@@ -398,7 +398,7 @@
};
&pinctrl_ese {
- gpv7: gpv7 {
+ gpv7: gpv7-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -406,7 +406,7 @@
#interrupt-cells = <2>;
};
- spi4_bus: spi4-bus {
+ spi4_bus: spi4-bus-pins {
samsung,pins = "gpv7-0", "gpv7-1", "gpv7-2", "gpv7-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
@@ -415,7 +415,7 @@
};
&pinctrl_fsys0 {
- gpr4: gpr4 {
+ gpr4: gpr4-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -423,35 +423,35 @@
#interrupt-cells = <2>;
};
- sd2_clk: sd2-clk {
+ sd2_clk: sd2-clk-pins {
samsung,pins = "gpr4-0";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
};
- sd2_cmd: sd2-cmd {
+ sd2_cmd: sd2-cmd-pins {
samsung,pins = "gpr4-1";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
};
- sd2_cd: sd2-cd {
+ sd2_cd: sd2-cd-pins {
samsung,pins = "gpr4-2";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
};
- sd2_bus1: sd2-bus-width1 {
+ sd2_bus1: sd2-bus-width1-pins {
samsung,pins = "gpr4-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
};
- sd2_bus4: sd2-bus-width4 {
+ sd2_bus4: sd2-bus-width4-pins {
samsung,pins = "gpr4-4", "gpr4-5", "gpr4-6";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
@@ -460,7 +460,7 @@
};
&pinctrl_fsys1 {
- gpr0: gpr0 {
+ gpr0: gpr0-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -468,7 +468,7 @@
#interrupt-cells = <2>;
};
- gpr1: gpr1 {
+ gpr1: gpr1-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -476,7 +476,7 @@
#interrupt-cells = <2>;
};
- gpr2: gpr2 {
+ gpr2: gpr2-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -484,7 +484,7 @@
#interrupt-cells = <2>;
};
- gpr3: gpr3 {
+ gpr3: gpr3-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -492,105 +492,105 @@
#interrupt-cells = <2>;
};
- sd0_clk: sd0-clk {
+ sd0_clk: sd0-clk-pins {
samsung,pins = "gpr0-0";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS7_FSYS1_PIN_DRV_LV2>;
};
- sd0_cmd: sd0-cmd {
+ sd0_cmd: sd0-cmd-pins {
samsung,pins = "gpr0-1";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS7_FSYS1_PIN_DRV_LV2>;
};
- sd0_ds: sd0-ds {
+ sd0_ds: sd0-ds-pins {
samsung,pins = "gpr0-2";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
samsung,pin-drv = <EXYNOS7_FSYS1_PIN_DRV_LV2>;
};
- sd0_qrdy: sd0-qrdy {
+ sd0_qrdy: sd0-qrdy-pins {
samsung,pins = "gpr0-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
samsung,pin-drv = <EXYNOS7_FSYS1_PIN_DRV_LV2>;
};
- sd0_bus1: sd0-bus-width1 {
+ sd0_bus1: sd0-bus-width1-pins {
samsung,pins = "gpr1-0";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS7_FSYS1_PIN_DRV_LV2>;
};
- sd0_bus4: sd0-bus-width4 {
+ sd0_bus4: sd0-bus-width4-pins {
samsung,pins = "gpr1-1", "gpr1-2", "gpr1-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS7_FSYS1_PIN_DRV_LV2>;
};
- sd0_bus8: sd0-bus-width8 {
+ sd0_bus8: sd0-bus-width8-pins {
samsung,pins = "gpr1-4", "gpr1-5", "gpr1-6", "gpr1-7";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS7_FSYS1_PIN_DRV_LV2>;
};
- sd1_clk: sd1-clk {
+ sd1_clk: sd1-clk-pins {
samsung,pins = "gpr2-0";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS7_FSYS1_PIN_DRV_LV3>;
};
- sd1_cmd: sd1-cmd {
+ sd1_cmd: sd1-cmd-pins {
samsung,pins = "gpr2-1";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS7_FSYS1_PIN_DRV_LV3>;
};
- sd1_ds: sd1-ds {
+ sd1_ds: sd1-ds-pins {
samsung,pins = "gpr2-2";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
samsung,pin-drv = <EXYNOS7_FSYS1_PIN_DRV_LV4>;
};
- sd1_qrdy: sd1-qrdy {
+ sd1_qrdy: sd1-qrdy-pins {
samsung,pins = "gpr2-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
samsung,pin-drv = <EXYNOS7_FSYS1_PIN_DRV_LV4>;
};
- sd1_int: sd1-int {
+ sd1_int: sd1-int-pins {
samsung,pins = "gpr2-4";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
samsung,pin-drv = <EXYNOS7_FSYS1_PIN_DRV_LV4>;
};
- sd1_bus1: sd1-bus-width1 {
+ sd1_bus1: sd1-bus-width1-pins {
samsung,pins = "gpr3-0";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS7_FSYS1_PIN_DRV_LV3>;
};
- sd1_bus4: sd1-bus-width4 {
+ sd1_bus4: sd1-bus-width4-pins {
samsung,pins = "gpr3-1", "gpr3-2", "gpr3-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS7_FSYS1_PIN_DRV_LV3>;
};
- sd1_bus8: sd1-bus-width8 {
+ sd1_bus8: sd1-bus-width8-pins {
samsung,pins = "gpr3-4", "gpr3-5", "gpr3-6", "gpr3-7";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
@@ -599,7 +599,7 @@
};
&pinctrl_bus1 {
- gpf0: gpf0 {
+ gpf0: gpf0-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -607,7 +607,7 @@
#interrupt-cells = <2>;
};
- gpf1: gpf1 {
+ gpf1: gpf1-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -615,7 +615,7 @@
#interrupt-cells = <2>;
};
- gpf2: gpf2 {
+ gpf2: gpf2-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -623,7 +623,7 @@
#interrupt-cells = <2>;
};
- gpf3: gpf3 {
+ gpf3: gpf3-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -631,7 +631,7 @@
#interrupt-cells = <2>;
};
- gpf4: gpf4 {
+ gpf4: gpf4-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -639,7 +639,7 @@
#interrupt-cells = <2>;
};
- gpf5: gpf5 {
+ gpf5: gpf5-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -647,7 +647,7 @@
#interrupt-cells = <2>;
};
- gpg1: gpg1 {
+ gpg1: gpg1-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -655,7 +655,7 @@
#interrupt-cells = <2>;
};
- gpg2: gpg2 {
+ gpg2: gpg2-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -663,7 +663,7 @@
#interrupt-cells = <2>;
};
- gph1: gph1 {
+ gph1: gph1-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -671,7 +671,7 @@
#interrupt-cells = <2>;
};
- gpv6: gpv6 {
+ gpv6: gpv6-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -679,21 +679,21 @@
#interrupt-cells = <2>;
};
- spi5_bus: spi5-bus {
+ spi5_bus: spi5-bus-pins {
samsung,pins = "gpf2-0", "gpf2-1", "gpf2-2", "gpf2-3";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
};
- ufs_refclk_out: ufs-refclk-out {
+ ufs_refclk_out: ufs-refclk-out-pins {
samsung,pins = "gpg2-4";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV2>;
};
- ufs_rst_n: ufs-rst-n {
+ ufs_rst_n: ufs-rst-n-pins {
samsung,pins = "gph1-5";
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
diff --git a/arch/arm64/boot/dts/exynos/exynos7.dtsi b/arch/arm64/boot/dts/exynos/exynos7.dtsi
index c3efbc8add38..e38bb02a2152 100644
--- a/arch/arm64/boot/dts/exynos/exynos7.dtsi
+++ b/arch/arm64/boot/dts/exynos/exynos7.dtsi
@@ -142,7 +142,7 @@
<0x11006000 0x2000>;
};
- pdma0: pdma@10e10000 {
+ pdma0: dma-controller@10e10000 {
compatible = "arm,pl330", "arm,primecell";
reg = <0x10E10000 0x1000>;
interrupts = <GIC_SPI 225 IRQ_TYPE_LEVEL_HIGH>;
@@ -153,7 +153,7 @@
#dma-requests = <32>;
};
- pdma1: pdma@10eb0000 {
+ pdma1: dma-controller@10eb0000 {
compatible = "arm,pl330", "arm,primecell";
reg = <0x10EB0000 0x1000>;
interrupts = <GIC_SPI 226 IRQ_TYPE_LEVEL_HIGH>;
@@ -177,10 +177,11 @@
clocks = <&fin_pll>, <&clock_topc DOUT_SCLK_BUS0_PLL>,
<&clock_topc DOUT_SCLK_BUS1_PLL>,
<&clock_topc DOUT_SCLK_CC_PLL>,
- <&clock_topc DOUT_SCLK_MFC_PLL>;
+ <&clock_topc DOUT_SCLK_MFC_PLL>,
+ <&clock_topc DOUT_SCLK_AUD_PLL>;
clock-names = "fin_pll", "dout_sclk_bus0_pll",
"dout_sclk_bus1_pll", "dout_sclk_cc_pll",
- "dout_sclk_mfc_pll";
+ "dout_sclk_mfc_pll", "dout_sclk_aud_pll";
};
clock_top1: clock-controller@105e0000 {
@@ -218,12 +219,32 @@
compatible = "samsung,exynos7-clock-peric1";
reg = <0x14c80000 0xd00>;
#clock-cells = <1>;
- clocks = <&fin_pll>, <&clock_top0 DOUT_ACLK_PERIC1>,
+ clocks = <&fin_pll>,
+ <&clock_top0 DOUT_ACLK_PERIC1>,
<&clock_top0 CLK_SCLK_UART1>,
<&clock_top0 CLK_SCLK_UART2>,
- <&clock_top0 CLK_SCLK_UART3>;
- clock-names = "fin_pll", "dout_aclk_peric1_66",
- "sclk_uart1", "sclk_uart2", "sclk_uart3";
+ <&clock_top0 CLK_SCLK_UART3>,
+ <&clock_top0 CLK_SCLK_SPI0>,
+ <&clock_top0 CLK_SCLK_SPI1>,
+ <&clock_top0 CLK_SCLK_SPI2>,
+ <&clock_top0 CLK_SCLK_SPI3>,
+ <&clock_top0 CLK_SCLK_SPI4>,
+ <&clock_top0 CLK_SCLK_I2S1>,
+ <&clock_top0 CLK_SCLK_PCM1>,
+ <&clock_top0 CLK_SCLK_SPDIF>;
+ clock-names = "fin_pll",
+ "dout_aclk_peric1_66",
+ "sclk_uart1",
+ "sclk_uart2",
+ "sclk_uart3",
+ "sclk_spi0",
+ "sclk_spi1",
+ "sclk_spi2",
+ "sclk_spi3",
+ "sclk_spi4",
+ "sclk_i2s1",
+ "sclk_pcm1",
+ "sclk_spdif";
};
clock_peris: clock-controller@10040000 {
@@ -663,16 +684,15 @@
reg = <0x15500000 0x100>;
clocks = <&clock_fsys0 ACLK_USBDRD300>,
<&clock_fsys0 OSCCLK_PHY_CLKOUT_USB30_PHY>,
- <&clock_fsys0 PHYCLK_USBDRD300_UDRD30_PIPE_PCLK_USER>,
<&clock_fsys0 PHYCLK_USBDRD300_UDRD30_PHYCLK_USER>,
+ <&clock_fsys0 PHYCLK_USBDRD300_UDRD30_PIPE_PCLK_USER>,
<&clock_fsys0 SCLK_USBDRD300_REFCLK>;
- clock-names = "phy", "ref", "phy_pipe",
- "phy_utmi", "itp";
+ clock-names = "phy", "ref", "phy_utmi", "phy_pipe", "itp";
samsung,pmu-syscon = <&pmu_system_controller>;
#phy-cells = <1>;
};
- usbdrd3 {
+ usbdrd: usb {
compatible = "samsung,exynos7-dwusb3";
clocks = <&clock_fsys0 ACLK_USBDRD300>,
<&clock_fsys0 SCLK_USBDRD300_SUSPENDCLK>,
diff --git a/arch/arm64/boot/dts/exynos/exynos7885-jackpotlte.dts b/arch/arm64/boot/dts/exynos/exynos7885-jackpotlte.dts
new file mode 100644
index 000000000000..4cf9aa25f618
--- /dev/null
+++ b/arch/arm64/boot/dts/exynos/exynos7885-jackpotlte.dts
@@ -0,0 +1,92 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Samsung Galaxy A8 2018 (jackpotlte/SM-A530F) device tree source
+ *
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2021 Dávid Virág
+ */
+
+/dts-v1/;
+#include "exynos7885.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+
+/ {
+ model = "Samsung Galaxy A8 (2018)";
+ compatible = "samsung,jackpotlte", "samsung,exynos7885";
+ chassis-type = "handset";
+
+ aliases {
+ serial0 = &serial_0;
+ serial1 = &serial_1;
+ serial2 = &serial_2;
+ };
+
+ chosen {
+ stdout-path = &serial_2;
+ };
+
+ memory@80000000 {
+ device_type = "memory";
+ reg = <0x0 0x80000000 0x3da00000>,
+ <0x0 0xc0000000 0x40000000>,
+ <0x8 0x80000000 0x40000000>;
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+ pinctrl-names = "default";
+ pinctrl-0 = <&key_volup &key_voldown &key_power>;
+
+ volup-key {
+ label = "Volume Up";
+ linux,code = <KEY_VOLUMEUP>;
+ gpios = <&gpa1 5 GPIO_ACTIVE_LOW>;
+ };
+
+ voldown-key {
+ label = "Volume Down";
+ linux,code = <KEY_VOLUMEDOWN>;
+ gpios = <&gpa1 6 GPIO_ACTIVE_LOW>;
+ };
+
+ power-key {
+ label = "Power";
+ linux,code = <KEY_POWER>;
+ gpios = <&gpa1 7 GPIO_ACTIVE_LOW>;
+ wakeup-source;
+ };
+ };
+};
+
+&oscclk {
+ clock-frequency = <26000000>;
+};
+
+&pinctrl_alive {
+ key_volup: key-volup-pins {
+ samsung,pins = "gpa1-5";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_F>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+ samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
+ };
+
+ key_voldown: key-voldown-pins {
+ samsung,pins = "gpa1-6";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_F>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+ samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
+ };
+
+ key_power: key-power-pins {
+ samsung,pins = "gpa1-7";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_F>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+ samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
+ };
+};
+
+&serial_2 {
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/exynos/exynos7885-pinctrl.dtsi b/arch/arm64/boot/dts/exynos/exynos7885-pinctrl.dtsi
new file mode 100644
index 000000000000..a50c1dbd5545
--- /dev/null
+++ b/arch/arm64/boot/dts/exynos/exynos7885-pinctrl.dtsi
@@ -0,0 +1,855 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Samsung Exynos7885 SoC pin-mux and pin-config device tree source
+ *
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2021 Dávid Virág
+ *
+ * Samsung's Exynos7885 SoC pin-mux and pin-config options are listed as
+ * device tree nodes in this file.
+ */
+
+#include <dt-bindings/pinctrl/samsung.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+&pinctrl_alive {
+ etc0: etc0-gpio-bank {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ etc1: etc1-gpio-bank {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpa0: gpa0-gpio-bank {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ interrupt-parent = <&gic>;
+ interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ gpa1: gpa1-gpio-bank {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ interrupt-parent = <&gic>;
+ interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ gpa2: gpa2-gpio-bank {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpq0: gpq0-gpio-bank {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ sim1_det_gpio: sim1-det-gpio-pins {
+ samsung,pins = "gpa2-5";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_F>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+ };
+
+ sim0_det_gpio: sim0-det-gpio-pins {
+ samsung,pins = "gpa2-6";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_F>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+ };
+
+ speedy_bus: speedy-bus-pins {
+ samsung,pins = "gpq0-2";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+ samsung,pin-con-pdn = <EXYNOS_PIN_PDN_PREV>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+ samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
+ };
+
+ /* UART_DEBUG */
+ uart2_bus: uart2-bus-pins {
+ samsung,pins = "gpq0-4", "gpq0-3";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+ };
+};
+
+&pinctrl_dispaud {
+ gpb0: gpb0-gpio-bank {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpb1: gpb1-gpio-bank {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpb2: gpb2-gpio-bank {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ aud_codec_mclk: aud-codec-mclk-pins {
+ samsung,pins = "gpb0-0";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
+ };
+
+ aud_codec_mclk_idle: aud-codec-mclk-idle-pins {
+ samsung,pins = "gpb0-0";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
+ };
+
+ aud_codec_bus: aud-codec-bus-pins {
+ samsung,pins = "gpb0-1", "gpb0-2", "gpb0-3", "gpb0-4";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
+ };
+
+ aud_codec_bus_idle: aud-codec-bus-idle-pins {
+ samsung,pins = "gpb0-1", "gpb0-2", "gpb0-3", "gpb0-4";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
+ };
+
+ aud_loopback_bus: aud-loopback-bus-pins {
+ samsung,pins = "gpb1-0";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
+ };
+
+ aud_loopback_bus_idle: aud-loopback-bus-idle-pins {
+ samsung,pins = "gpb1-0";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
+ };
+
+ aud_fm_bus: aud-fm-bus-pins {
+ samsung,pins = "gpb1-1", "gpb1-2", "gpb1-3";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
+ };
+
+ aud_fm_bus_idle: aud-fm-bus-idle-pins {
+ samsung,pins = "gpb1-1", "gpb1-2", "gpb1-3";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
+ };
+
+ aud_spk_bus: aud-spk-bus-pins {
+ samsung,pins = "gpb2-0", "gpb2-1", "gpb2-2", "gpb2-3";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
+ };
+
+ aud_spk_bus_idle: aud-spk-bus-idle-pins {
+ samsung,pins = "gpb2-0", "gpb2-1", "gpb2-2", "gpb2-3";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
+ };
+};
+
+&pinctrl_fsys {
+ gpf0: gpf0-gpio-bank {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpf2: gpf2-gpio-bank {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpf3: gpf3-gpio-bank {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpf4: gpf4-gpio-bank {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ sd0_clk: sd0-clk-pins {
+ samsung,pins = "gpf0-0";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+ samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV4>;
+ };
+
+ sd0_clk_fast_slew_rate_1x: sd0-clk-fast-slew-rate-1x-pins {
+ samsung,pins = "gpf0-0";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+ samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
+ };
+
+ sd0_clk_fast_slew_rate_2x: sd0-clk-fast-slew-rate-2x-pins {
+ samsung,pins = "gpf0-0";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+ samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV2>;
+ };
+
+ sd0_clk_fast_slew_rate_3x: sd0-clk-fast-slew-rate-3x-pins {
+ samsung,pins = "gpf0-0";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+ samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV3>;
+ };
+
+ sd0_clk_fast_slew_rate_4x: sd0-clk-fast-slew-rate-4x-pins {
+ samsung,pins = "gpf0-0";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+ samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV4>;
+ };
+
+ sd0_cmd: sd0-cmd-pins {
+ samsung,pins = "gpf0-1";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+ samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV4>;
+ };
+
+ sd0_rdqs: sd0-rdqs-pins {
+ samsung,pins = "gpf0-2";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
+ samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV4>;
+ };
+
+ sd0_bus1: sd0-bus-width1-pins {
+ samsung,pins = "gpf2-0";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+ samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV4>;
+ };
+
+ sd0_bus4: sd0-bus-width4-pins {
+ samsung,pins = "gpf2-1", "gpf2-2", "gpf2-3";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+ samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV4>;
+ };
+
+ sd0_bus8: sd0-bus-width8-pins {
+ samsung,pins = "gpf2-4", "gpf2-5", "gpf2-6", "gpf2-7";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+ samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV4>;
+ };
+
+ sd1_clk: sd1-clk-pins {
+ samsung,pins = "gpf3-0";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+ samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV3>;
+ };
+
+ sd1_clk_fast_slew_rate_1x: sd1-clk-fast-slew-rate-1x-pins {
+ samsung,pins = "gpf3-0";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+ samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
+ };
+
+ sd1_clk_fast_slew_rate_2x: sd1-clk-fast-slew-rate-2x-pins {
+ samsung,pins = "gpf3-0";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+ samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV2>;
+ };
+
+ sd1_clk_fast_slew_rate_3x: sd1-clk-fast-slew-rate-3x-pins {
+ samsung,pins = "gpf3-0";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+ samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV3>;
+ };
+
+ sd1_clk_fast_slew_rate_4x: sd1-clk-fast-slew-rate-4x-pins {
+ samsung,pins = "gpf3-0";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+ samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV4>;
+ };
+
+ sd1_cmd: sd1-cmd-pins {
+ samsung,pins = "gpf3-1";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+ samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV3>;
+ };
+
+ sd1_bus1: sd1-bus-width1-pins {
+ samsung,pins = "gpf3-2";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+ samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV3>;
+ };
+
+ sd1_bus4: sd1-bus-width4-pins {
+ samsung,pins = "gpf3-3", "gpf3-5";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+ samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV3>;
+ };
+
+ sd2_clk: sd2-clk-pins {
+ samsung,pins = "gpf4-0";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+ samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV3>;
+ };
+
+ sd2_clk_fast_slew_rate_1x: sd2-clk-fast-slew-rate-1x-pins {
+ samsung,pins = "gpf4-0";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+ samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
+ };
+
+ sd2_clk_fast_slew_rate_2x: sd2-clk-fast-slew-rate-2x-pins {
+ samsung,pins = "gpf4-0";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+ samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV2>;
+ };
+
+ sd2_clk_fast_slew_rate_3x: sd2-clk-fast-slew-rate-3x-pins {
+ samsung,pins = "gpf4-0";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+ samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV3>;
+ };
+
+ sd2_clk_fast_slew_rate_4x: sd2-clk-fast-slew-rate-4x-pins {
+ samsung,pins = "gpf4-0";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+ samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV4>;
+ };
+
+ sd2_cmd: sd2-cmd-pins {
+ samsung,pins = "gpf4-1";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+ samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV3>;
+ };
+
+ sd2_bus1: sd2-bus-width1-pins {
+ samsung,pins = "gpf4-2";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+ samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV3>;
+ };
+
+ sd2_bus4: sd2-bus-width4-pins {
+ samsung,pins = "gpf4-3", "gpf4-4", "gpf4-5";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+ samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV3>;
+ };
+};
+
+&pinctrl_top {
+ gpc0: gpc0-gpio-bank {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpc1: gpc1-gpio-bank {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpc2: gpc2-gpio-bank {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpg0: gpg0-gpio-bank {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpg1: gpg1-gpio-bank {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpg2: gpg2-gpio-bank {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpg3: gpg3-gpio-bank {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpg4: gpg4-gpio-bank {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpp0: gpp0-gpio-bank {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpp1: gpp1-gpio-bank {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpp2: gpp2-gpio-bank {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpp3: gpp3-gpio-bank {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpp4: gpp4-gpio-bank {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpp5: gpp5-gpio-bank {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpp6: gpp6-gpio-bank {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpp7: gpp7-gpio-bank {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpp8: gpp8-gpio-bank {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ hs_i2c0_bus: hs-i2c0-bus-pins {
+ samsung,pins = "gpc1-1", "gpc1-0";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+ samsung,pin-con-pdn = <EXYNOS_PIN_PDN_OUT1>;
+ samsung,pin-pud-pdn = <EXYNOS_PIN_PULL_UP>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+ samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
+ };
+
+ hs_i2c1_bus: hs-i2c1-bus-pins {
+ samsung,pins = "gpc1-3", "gpc1-2";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+ samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
+ samsung,pin-con-pdn = <EXYNOS_PIN_PDN_OUT1>;
+ samsung,pin-pud-pdn = <EXYNOS_PIN_PULL_UP>;
+ };
+
+ hs_i2c2_bus: hs-i2c2-bus-pins {
+ samsung,pins = "gpc1-5", "gpc1-4";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+ samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
+ samsung,pin-con-pdn = <EXYNOS_PIN_PDN_OUT1>;
+ samsung,pin-pud-pdn = <EXYNOS_PIN_PULL_UP>;
+ };
+
+ hs_i2c3_bus: hs-i2c3-bus-pins {
+ samsung,pins = "gpc1-7", "gpc1-6";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+ samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
+ samsung,pin-con-pdn = <EXYNOS_PIN_PDN_OUT1>;
+ samsung,pin-pud-pdn = <EXYNOS_PIN_PULL_UP>;
+ };
+
+ /* USI0 UART */
+ uart3_bus_single: uart3-bus-single-pins {
+ samsung,pins = "gpc2-3", "gpc2-2", "gpc2-1", "gpc2-0";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+ };
+
+ /* USI0 UART_HSI2C1 */
+ uart3_bus_dual: uart3-bus-dual-pins {
+ samsung,pins = "gpc2-1", "gpc2-0";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+ };
+
+ /* USI0 HSI2C0 */
+ hs_i2c4_bus: hs-i2c4-bus-pins {
+ samsung,pins = "gpc2-1", "gpc2-0";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+ samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
+ samsung,pin-con-pdn = <EXYNOS_PIN_PDN_OUT1>;
+ samsung,pin-pud-pdn = <EXYNOS_PIN_PULL_UP>;
+ };
+
+ /* USI0 HSI2C1 */
+ hs_i2c5_bus: hs-i2c5-bus-pins {
+ samsung,pins = "gpc2-3", "gpc2-2";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+ samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
+ samsung,pin-con-pdn = <EXYNOS_PIN_PDN_OUT1>;
+ samsung,pin-pud-pdn = <EXYNOS_PIN_PULL_UP>;
+ };
+
+ /* USI0 SPI */
+ spi2_bus: spi2-bus-pins {
+ samsung,pins = "gpc2-1", "gpc2-0", "gpc2-3";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+ samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
+ };
+
+ spi2_cs: spi2-cs-pins {
+ samsung,pins = "gpc2-2";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+ samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
+ };
+
+ /* USI1 UART */
+ uart4_bus_single: uart4-bus-single-pins {
+ samsung,pins = "gpc2-7", "gpc2-6", "gpc2-5", "gpc2-4";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+ };
+
+ /* USI1 UART_HSI2C1*/
+ uart4_bus_dual: uart4-bus-dual-pins {
+ samsung,pins = "gpc2-5", "gpc2-4";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+ };
+
+ /* USI1 HSI2C0 */
+ hs_i2c6_bus: hs-i2c6-bus-pins {
+ samsung,pins = "gpc2-5", "gpc2-4";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+ samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
+ samsung,pin-con-pdn = <EXYNOS_PIN_PDN_OUT1>;
+ samsung,pin-pud-pdn = <EXYNOS_PIN_PULL_UP>;
+ };
+
+ /* USI1 HSI2C1 */
+ hs_i2c7_bus: hs-i2c7-bus-pins {
+ samsung,pins = "gpc2-7", "gpc2-6";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+ samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
+ samsung,pin-con-pdn = <EXYNOS_PIN_PDN_OUT1>;
+ samsung,pin-pud-pdn = <EXYNOS_PIN_PULL_UP>;
+ };
+
+ /* USI1 SPI */
+ spi3_bus: spi3-bus-pins {
+ samsung,pins = "gpc2-5", "gpc2-4", "gpc2-7";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+ samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
+ };
+
+ spi3_cs: spi3-cs-pins {
+ samsung,pins = "gpc2-6";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+ samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
+ };
+
+ fm_lna_en: fm-lna-en-pins {
+ samsung,pins = "gpg0-2";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
+ samsung,pin-con-pdn = <EXYNOS_PIN_PDN_PREV>;
+ samsung,pin-pud-pdn = <EXYNOS_PIN_PULL_UP>;
+ samsung,pin-val = <1>;
+ };
+
+ uart1_bus: uart1-bus-pins {
+ samsung,pins = "gpg1-3", "gpg1-2", "gpg1-1", "gpg1-0";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+ };
+
+ i2c7_bus: i2c7-bus-pins {
+ samsung,pins = "gpg1-5", "gpg1-4";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+ samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
+ };
+
+ aud_dmic_on: aud-dmic-on-pins {
+ samsung,pins = "gpg2-1";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
+ samsung,pin-con-pdn = <EXYNOS_PIN_PDN_PREV>;
+ samsung,pin-val = <1>;
+ };
+
+ aud_dmic_off: aud-dmic-off-pins {
+ samsung,pins = "gpg2-1";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
+ samsung,pin-con-pdn = <EXYNOS_PIN_PDN_PREV>;
+ samsung,pin-val = <0>;
+ };
+
+ /* UART_HEALTH */
+ uart0_bus: uart0-bus-pins {
+ samsung,pins = "gpp0-3", "gpp0-2", "gpp0-1", "gpp0-0";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+ };
+
+ i2c0_bus: i2c0-bus-pins {
+ samsung,pins = "gpp1-1", "gpp1-0";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+ samsung,pin-con-pdn = <EXYNOS_PIN_PDN_PREV>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+ samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
+ };
+
+ i2c1_bus: i2c1-bus-pins {
+ samsung,pins = "gpp1-3", "gpp1-2";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+ samsung,pin-con-pdn = <EXYNOS_PIN_PDN_PREV>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+ samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
+ };
+
+ i2c2_bus: i2c2-bus-pins {
+ samsung,pins = "gpp2-1", "gpp2-0";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+ samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
+ };
+
+ i2c3_bus: i2c3-bus-pins {
+ samsung,pins = "gpp3-1", "gpp3-0";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+ samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
+ };
+
+ i2c4_bus: i2c4-bus-pins {
+ samsung,pins = "gpp4-1", "gpp4-0";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+ samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
+ };
+
+ i2c5_bus: i2c5-bus-pins {
+ samsung,pins = "gpp4-3", "gpp4-2";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+ samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
+ };
+
+ i2c6_bus: i2c6-bus-pins {
+ samsung,pins = "gpp4-5", "gpp4-4";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+ samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
+ };
+
+ /* SPI_ESE */
+ spi0_bus: spi0-bus-pins {
+ samsung,pins = "gpp5-3", "gpp5-2", "gpp5-0";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+ samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
+ };
+
+ spi0_cs: spi0-cs-pins {
+ samsung,pins = "gpp5-1";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+ samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
+ };
+
+ /* SPI_FP */
+ spi1_bus: spi1-bus-pins {
+ samsung,pins = "gpp6-3", "gpp6-2", "gpp6-0";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+ samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
+ };
+
+ spi1_cs: spi1-cs-pins {
+ samsung,pins = "gpp6-1";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+ samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
+ };
+
+ /* USI2 UART */
+ uart5_bus_single: uart5-bus-single-pins {
+ samsung,pins = "gpp8-1", "gpp8-0", "gpp7-1", "gpp7-0";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+ };
+
+ /* USI2 UART_HSI2C1 */
+ uart5_bus_dual: uart5-bus-dual-pins {
+ samsung,pins = "gpp7-1", "gpp7-0";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+ };
+
+ /* USI2 HSI2C0 */
+ hs_i2c8_bus: hs-i2c8-bus-pins {
+ samsung,pins = "gpp7-1", "gpp7-0";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+ samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
+ samsung,pin-con-pdn = <EXYNOS_PIN_PDN_OUT1>;
+ samsung,pin-pud-pdn = <EXYNOS_PIN_PULL_UP>;
+ };
+
+ /* USI2 HSI2C1 */
+ hs_i2c9_bus: hs-i2c9-bus-pins {
+ samsung,pins = "gpp8-1", "gpp8-0";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+ samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
+ samsung,pin-con-pdn = <EXYNOS_PIN_PDN_OUT1>;
+ samsung,pin-pud-pdn = <EXYNOS_PIN_PULL_UP>;
+ };
+
+ /* USI2 SPI */
+ spi4_bus: spi4-bus-pins {
+ samsung,pins = "gpp7-1", "gpp7-0", "gpp8-1";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+ samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
+ };
+
+ spi4_cs: spi4-cs-pins {
+ samsung,pins = "gpp8-0";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+ samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
+ };
+};
diff --git a/arch/arm64/boot/dts/exynos/exynos7885.dtsi b/arch/arm64/boot/dts/exynos/exynos7885.dtsi
new file mode 100644
index 000000000000..3170661f5b67
--- /dev/null
+++ b/arch/arm64/boot/dts/exynos/exynos7885.dtsi
@@ -0,0 +1,423 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Samsung Exynos7885 SoC device tree source
+ *
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2021 Dávid Virág
+ */
+
+#include <dt-bindings/clock/exynos7885.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+/ {
+ compatible = "samsung,exynos7885";
+ #address-cells = <2>;
+ #size-cells = <1>;
+
+ interrupt-parent = <&gic>;
+
+ aliases {
+ pinctrl0 = &pinctrl_alive;
+ pinctrl1 = &pinctrl_dispaud;
+ pinctrl2 = &pinctrl_fsys;
+ pinctrl3 = &pinctrl_top;
+ };
+
+ arm-a53-pmu {
+ compatible = "arm,cortex-a53-pmu";
+ interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 97 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 99 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 218 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 219 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-affinity = <&cpu0>,
+ <&cpu1>,
+ <&cpu2>,
+ <&cpu3>,
+ <&cpu4>,
+ <&cpu5>;
+ };
+
+ arm-a73-pmu {
+ compatible = "arm,cortex-a73-pmu";
+ interrupts = <GIC_SPI 82 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-affinity = <&cpu6>,
+ <&cpu7>;
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu-map {
+ cluster0 {
+ core0 {
+ cpu = <&cpu0>;
+ };
+ core1 {
+ cpu = <&cpu1>;
+ };
+ core2 {
+ cpu = <&cpu2>;
+ };
+ core3 {
+ cpu = <&cpu3>;
+ };
+ core4 {
+ cpu = <&cpu4>;
+ };
+ core5 {
+ cpu = <&cpu5>;
+ };
+ };
+
+ cluster1 {
+ core0 {
+ cpu = <&cpu6>;
+ };
+ core1 {
+ cpu = <&cpu7>;
+ };
+ };
+ };
+
+ cpu0: cpu@100 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a53";
+ reg = <0x100>;
+ enable-method = "psci";
+ };
+
+ cpu1: cpu@101 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a53";
+ reg = <0x101>;
+ enable-method = "psci";
+ };
+
+ cpu2: cpu@102 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a53";
+ reg = <0x102>;
+ enable-method = "psci";
+ };
+
+ cpu3: cpu@103 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a53";
+ reg = <0x103>;
+ enable-method = "psci";
+ };
+
+ cpu4: cpu@200 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a53";
+ reg = <0x200>;
+ enable-method = "psci";
+ };
+
+ cpu5: cpu@201 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a53";
+ reg = <0x201>;
+ enable-method = "psci";
+ };
+
+ cpu6: cpu@0 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a73";
+ reg = <0x0>;
+ enable-method = "psci";
+ };
+
+ cpu7: cpu@1 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a73";
+ reg = <0x1>;
+ enable-method = "psci";
+ };
+ };
+
+ psci {
+ compatible = "arm,psci";
+ method = "smc";
+ cpu_suspend = <0xc4000001>;
+ cpu_off = <0x84000002>;
+ cpu_on = <0xc4000003>;
+ };
+
+ timer {
+ compatible = "arm,armv8-timer";
+ /* Hypervisor Virtual Timer interrupt is not wired to GIC */
+ interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>,
+ <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>,
+ <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>,
+ <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>;
+ };
+
+ fixed-rate-clocks {
+ oscclk: osc-clock {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-output-names = "oscclk";
+ };
+ };
+
+ soc: soc@0 {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0x0 0x0 0x0 0x20000000>;
+
+ chipid@10000000 {
+ compatible = "samsung,exynos850-chipid";
+ reg = <0x10000000 0x24>;
+ };
+
+ gic: interrupt-controller@12301000 {
+ compatible = "arm,gic-400";
+ #interrupt-cells = <3>;
+ #address-cells = <0>;
+ interrupt-controller;
+ reg = <0x12301000 0x1000>,
+ <0x12302000 0x2000>,
+ <0x12304000 0x2000>,
+ <0x12306000 0x2000>;
+ interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(8) |
+ IRQ_TYPE_LEVEL_HIGH)>;
+ };
+
+ cmu_peri: clock-controller@10010000 {
+ compatible = "samsung,exynos7885-cmu-peri";
+ reg = <0x10010000 0x8000>;
+ #clock-cells = <1>;
+
+ clocks = <&oscclk>,
+ <&cmu_top CLK_DOUT_PERI_BUS>,
+ <&cmu_top CLK_DOUT_PERI_SPI0>,
+ <&cmu_top CLK_DOUT_PERI_SPI1>,
+ <&cmu_top CLK_DOUT_PERI_UART0>,
+ <&cmu_top CLK_DOUT_PERI_UART1>,
+ <&cmu_top CLK_DOUT_PERI_UART2>,
+ <&cmu_top CLK_DOUT_PERI_USI0>,
+ <&cmu_top CLK_DOUT_PERI_USI1>,
+ <&cmu_top CLK_DOUT_PERI_USI2>;
+ clock-names = "oscclk",
+ "dout_peri_bus",
+ "dout_peri_spi0",
+ "dout_peri_spi1",
+ "dout_peri_uart0",
+ "dout_peri_uart1",
+ "dout_peri_uart2",
+ "dout_peri_usi0",
+ "dout_peri_usi1",
+ "dout_peri_usi2";
+ };
+
+ cmu_core: clock-controller@12000000 {
+ compatible = "samsung,exynos7885-cmu-core";
+ reg = <0x12000000 0x8000>;
+ #clock-cells = <1>;
+
+ clocks = <&oscclk>,
+ <&cmu_top CLK_DOUT_CORE_BUS>,
+ <&cmu_top CLK_DOUT_CORE_CCI>,
+ <&cmu_top CLK_DOUT_CORE_G3D>;
+ clock-names = "oscclk",
+ "dout_core_bus",
+ "dout_core_cci",
+ "dout_core_g3d";
+ };
+
+ cmu_top: clock-controller@12060000 {
+ compatible = "samsung,exynos7885-cmu-top";
+ reg = <0x12060000 0x8000>;
+ #clock-cells = <1>;
+
+ clocks = <&oscclk>;
+ clock-names = "oscclk";
+ };
+
+ pinctrl_alive: pinctrl@11cb0000 {
+ compatible = "samsung,exynos7885-pinctrl";
+ reg = <0x11cb0000 0x1000>;
+
+ wakeup-interrupt-controller {
+ compatible = "samsung,exynos7-wakeup-eint";
+ interrupt-parent = <&gic>;
+ interrupts = <GIC_SPI 130 IRQ_TYPE_LEVEL_HIGH>;
+ };
+ };
+
+ pinctrl_fsys: pinctrl@13430000 {
+ compatible = "samsung,exynos7885-pinctrl";
+ reg = <0x13430000 0x1000>;
+ interrupts = <GIC_SPI 150 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ pinctrl_top: pinctrl@139b0000 {
+ compatible = "samsung,exynos7885-pinctrl";
+ reg = <0x139b0000 0x1000>;
+ interrupts = <GIC_SPI 266 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ pinctrl_dispaud: pinctrl@148f0000 {
+ compatible = "samsung,exynos7885-pinctrl";
+ reg = <0x148f0000 0x1000>;
+ interrupts = <GIC_SPI 130 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ pmu_system_controller: system-controller@11c80000 {
+ compatible = "samsung,exynos7-pmu", "syscon";
+ reg = <0x11c80000 0x10000>;
+ };
+
+ serial_0: serial@13800000 {
+ compatible = "samsung,exynos5433-uart";
+ reg = <0x13800000 0x100>;
+ interrupts = <GIC_SPI 246 IRQ_TYPE_LEVEL_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0_bus>;
+ clocks = <&cmu_peri CLK_GOUT_UART0_EXT_UCLK>,
+ <&cmu_peri CLK_GOUT_UART0_PCLK>;
+ clock-names = "uart", "clk_uart_baud0";
+ samsung,uart-fifosize = <64>;
+ status = "disabled";
+ };
+
+ serial_1: serial@13810000 {
+ compatible = "samsung,exynos5433-uart";
+ reg = <0x13810000 0x100>;
+ interrupts = <GIC_SPI 247 IRQ_TYPE_LEVEL_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart1_bus>;
+ clocks = <&cmu_peri CLK_GOUT_UART1_EXT_UCLK>,
+ <&cmu_peri CLK_GOUT_UART1_PCLK>;
+ clock-names = "uart", "clk_uart_baud0";
+ samsung,uart-fifosize = <256>;
+ status = "disabled";
+ };
+
+ serial_2: serial@13820000 {
+ compatible = "samsung,exynos5433-uart";
+ reg = <0x13820000 0x100>;
+ interrupts = <GIC_SPI 279 IRQ_TYPE_LEVEL_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart2_bus>;
+ clocks = <&cmu_peri CLK_GOUT_UART2_EXT_UCLK>,
+ <&cmu_peri CLK_GOUT_UART2_PCLK>;
+ clock-names = "uart", "clk_uart_baud0";
+ samsung,uart-fifosize = <256>;
+ status = "disabled";
+ };
+
+ i2c_0: i2c@13830000 {
+ compatible = "samsung,s3c2440-i2c";
+ reg = <0x13830000 0x100>;
+ interrupts = <GIC_SPI 248 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0_bus>;
+ clocks = <&cmu_peri CLK_GOUT_I2C0_PCLK>;
+ clock-names = "i2c";
+ status = "disabled";
+ };
+
+ i2c_1: i2c@13840000 {
+ compatible = "samsung,s3c2440-i2c";
+ reg = <0x13840000 0x100>;
+ interrupts = <GIC_SPI 249 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c1_bus>;
+ clocks = <&cmu_peri CLK_GOUT_I2C1_PCLK>;
+ clock-names = "i2c";
+ status = "disabled";
+ };
+
+ i2c_2: i2c@13850000 {
+ compatible = "samsung,s3c2440-i2c";
+ reg = <0x13850000 0x100>;
+ interrupts = <GIC_SPI 250 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c2_bus>;
+ clocks = <&cmu_peri CLK_GOUT_I2C2_PCLK>;
+ clock-names = "i2c";
+ status = "disabled";
+ };
+
+ i2c_3: i2c@13860000 {
+ compatible = "samsung,s3c2440-i2c";
+ reg = <0x13860000 0x100>;
+ interrupts = <GIC_SPI 251 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c3_bus>;
+ clocks = <&cmu_peri CLK_GOUT_I2C3_PCLK>;
+ clock-names = "i2c";
+ status = "disabled";
+ };
+
+ i2c_4: i2c@13870000 {
+ compatible = "samsung,s3c2440-i2c";
+ reg = <0x13870000 0x100>;
+ interrupts = <GIC_SPI 252 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c4_bus>;
+ clocks = <&cmu_peri CLK_GOUT_I2C4_PCLK>;
+ clock-names = "i2c";
+ status = "disabled";
+ };
+
+ i2c_5: i2c@13880000 {
+ compatible = "samsung,s3c2440-i2c";
+ reg = <0x13880000 0x100>;
+ interrupts = <GIC_SPI 253 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c5_bus>;
+ clocks = <&cmu_peri CLK_GOUT_I2C5_PCLK>;
+ clock-names = "i2c";
+ status = "disabled";
+ };
+
+ i2c_6: i2c@13890000 {
+ compatible = "samsung,s3c2440-i2c";
+ reg = <0x13890000 0x100>;
+ interrupts = <GIC_SPI 254 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c6_bus>;
+ clocks = <&cmu_peri CLK_GOUT_I2C6_PCLK>;
+ clock-names = "i2c";
+ status = "disabled";
+ };
+
+ i2c_7: i2c@11cd0000 {
+ compatible = "samsung,s3c2440-i2c";
+ reg = <0x11cd0000 0x100>;
+ interrupts = <GIC_SPI 255 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c7_bus>;
+ clocks = <&cmu_peri CLK_GOUT_I2C7_PCLK>;
+ clock-names = "i2c";
+ status = "disabled";
+ };
+ };
+};
+
+#include "exynos7885-pinctrl.dtsi"
+#include "arm/exynos-syscon-restart.dtsi"
diff --git a/arch/arm64/boot/dts/exynos/exynos850-e850-96.dts b/arch/arm64/boot/dts/exynos/exynos850-e850-96.dts
new file mode 100644
index 000000000000..7b5a61d22cc5
--- /dev/null
+++ b/arch/arm64/boot/dts/exynos/exynos850-e850-96.dts
@@ -0,0 +1,195 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * WinLink E850-96 board device tree source
+ *
+ * Copyright (C) 2018 Samsung Electronics Co., Ltd.
+ * Copyright (C) 2021 Linaro Ltd.
+ *
+ * Device tree source file for WinLink's E850-96 board which is based on
+ * Samsung Exynos850 SoC.
+ */
+
+/dts-v1/;
+
+#include "exynos850.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/leds/common.h>
+
+/ {
+ model = "WinLink E850-96 board";
+ compatible = "winlink,e850-96", "samsung,exynos850";
+
+ chosen {
+ stdout-path = &serial_0;
+ };
+
+ /*
+ * RAM: 4 GiB (eMCP):
+ * - 2 GiB at 0x80000000
+ * - 2 GiB at 0x880000000
+ *
+ * 0xbab00000..0xbfffffff: secure memory (85 MiB).
+ */
+ memory@80000000 {
+ device_type = "memory";
+ reg = <0x0 0x80000000 0x3ab00000>,
+ <0x0 0xc0000000 0x40000000>,
+ <0x8 0x80000000 0x80000000>;
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+ pinctrl-names = "default";
+ pinctrl-0 = <&key_voldown_pins &key_volup_pins>;
+
+ volume-down-key {
+ label = "Volume Down";
+ linux,code = <KEY_VOLUMEDOWN>;
+ gpios = <&gpa1 0 GPIO_ACTIVE_LOW>;
+ };
+
+ volume-up-key {
+ label = "Volume Up";
+ linux,code = <KEY_VOLUMEUP>;
+ gpios = <&gpa0 7 GPIO_ACTIVE_LOW>;
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ /* HEART_BEAT_LED */
+ user_led1: led-1 {
+ label = "yellow:user1";
+ gpios = <&gpg2 2 GPIO_ACTIVE_HIGH>;
+ color = <LED_COLOR_ID_YELLOW>;
+ function = LED_FUNCTION_HEARTBEAT;
+ linux,default-trigger = "heartbeat";
+ };
+
+ /* eMMC_LED */
+ user_led2: led-2 {
+ label = "yellow:user2";
+ gpios = <&gpg2 3 GPIO_ACTIVE_HIGH>;
+ color = <LED_COLOR_ID_YELLOW>;
+ linux,default-trigger = "mmc0";
+ };
+
+ /* SD_LED */
+ user_led3: led-3 {
+ label = "white:user3";
+ gpios = <&gpg2 4 GPIO_ACTIVE_HIGH>;
+ color = <LED_COLOR_ID_WHITE>;
+ function = LED_FUNCTION_SD;
+ linux,default-trigger = "mmc2";
+ };
+
+ /* WIFI_LED */
+ wlan_active_led: led-4 {
+ label = "yellow:wlan";
+ gpios = <&gpg2 6 GPIO_ACTIVE_HIGH>;
+ color = <LED_COLOR_ID_YELLOW>;
+ function = LED_FUNCTION_WLAN;
+ linux,default-trigger = "phy0tx";
+ default-state = "off";
+ };
+
+ /* BLUETOOTH_LED */
+ bt_active_led: led-5 {
+ label = "blue:bt";
+ gpios = <&gpg2 7 GPIO_ACTIVE_HIGH>;
+ color = <LED_COLOR_ID_BLUE>;
+ function = LED_FUNCTION_BLUETOOTH;
+ linux,default-trigger = "hci0rx";
+ default-state = "off";
+ };
+ };
+
+ /*
+ * RTC clock (XrtcXTI); external, must be 32.768 kHz.
+ *
+ * TODO: Remove this once RTC clock is implemented properly as part of
+ * PMIC driver.
+ */
+ rtcclk: clock-rtcclk {
+ compatible = "fixed-clock";
+ clock-output-names = "rtcclk";
+ #clock-cells = <0>;
+ clock-frequency = <32768>;
+ };
+};
+
+&cmu_hsi {
+ clocks = <&oscclk>, <&rtcclk>,
+ <&cmu_top CLK_DOUT_HSI_BUS>,
+ <&cmu_top CLK_DOUT_HSI_MMC_CARD>,
+ <&cmu_top CLK_DOUT_HSI_USB20DRD>;
+ clock-names = "oscclk", "rtcclk", "dout_hsi_bus",
+ "dout_hsi_mmc_card", "dout_hsi_usb20drd";
+};
+
+&mmc_0 {
+ status = "okay";
+ mmc-hs200-1_8v;
+ mmc-hs400-1_8v;
+ cap-mmc-highspeed;
+ non-removable;
+ mmc-hs400-enhanced-strobe;
+ card-detect-delay = <200>;
+ clock-frequency = <800000000>;
+ bus-width = <8>;
+ samsung,dw-mshc-ciu-div = <3>;
+ samsung,dw-mshc-sdr-timing = <0 4>;
+ samsung,dw-mshc-ddr-timing = <2 4>;
+ samsung,dw-mshc-hs400-timing = <0 2>;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&sd0_clk_pins &sd0_cmd_pins &sd0_rdqs_pins &sd0_nreset_pins
+ &sd0_bus1_pins &sd0_bus4_pins &sd0_bus8_pins>;
+};
+
+&oscclk {
+ clock-frequency = <26000000>;
+};
+
+&pinctrl_alive {
+ key_voldown_pins: key-voldown-pins {
+ samsung,pins = "gpa1-0";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_EINT>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+ samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
+ };
+
+ key_volup_pins: key-volup-pins {
+ samsung,pins = "gpa0-7";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_EINT>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+ samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
+ };
+};
+
+&rtc {
+ status = "okay";
+ clocks = <&cmu_apm CLK_GOUT_RTC_PCLK>, <&rtcclk>;
+ clock-names = "rtc", "rtc_src";
+};
+
+&serial_0 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart1_pins>;
+};
+
+&usi_uart {
+ samsung,clkreq-on; /* needed for UART mode */
+ status = "okay";
+};
+
+&watchdog_cl0 {
+ status = "okay";
+};
+
+&watchdog_cl1 {
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/exynos/exynos850-pinctrl.dtsi b/arch/arm64/boot/dts/exynos/exynos850-pinctrl.dtsi
new file mode 100644
index 000000000000..f43e4a206282
--- /dev/null
+++ b/arch/arm64/boot/dts/exynos/exynos850-pinctrl.dtsi
@@ -0,0 +1,663 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Samsung's Exynos850 SoC pin-mux and pin-config device tree source
+ *
+ * Copyright (C) 2017 Samsung Electronics Co., Ltd.
+ * Copyright (C) 2021 Linaro Ltd.
+ *
+ * Samsung's Exynos850 SoC pin-mux and pin-config options are listed as device
+ * tree nodes in this file.
+ */
+
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/pinctrl/samsung.h>
+
+&pinctrl_alive {
+ gpa0: gpa0-gpio-bank {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ interrupt-parent = <&gic>;
+ interrupts = <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ gpa1: gpa1-gpio-bank {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ interrupt-parent = <&gic>;
+ interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ gpa2: gpa2-gpio-bank {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ interrupt-parent = <&gic>;
+ interrupts = <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ gpa3: gpa3-gpio-bank {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ interrupt-parent = <&gic>;
+ interrupts = <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 27 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ gpa4: gpa4-gpio-bank {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ interrupt-parent = <&gic>;
+ interrupts = <GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ gpq0: gpq0-gpio-bank {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ /* I2C5 (also called CAM_PMIC_I2C in TRM) */
+ i2c5_pins: i2c5-pins {
+ samsung,pins = "gpa3-5", "gpa3-6";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+ samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
+ };
+
+ /* I2C6 (also called MOTOR_I2C in TRM) */
+ i2c6_pins: i2c6-pins {
+ samsung,pins = "gpa3-7", "gpa4-0";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+ samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
+ };
+
+ /* USI: UART_DEBUG_0 pins */
+ uart0_pins: uart0-pins {
+ samsung,pins = "gpq0-0", "gpq0-1";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+ };
+
+ /* USI: UART_DEBUG_1 pins */
+ uart1_pins: uart1-pins {
+ samsung,pins = "gpa3-7", "gpa4-0";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+ };
+};
+
+&pinctrl_cmgp {
+ gpm0: gpm0-gpio-bank {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ interrupt-parent = <&gic>;
+ interrupts = <GIC_SPI 39 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ gpm1: gpm1-gpio-bank {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ interrupt-parent = <&gic>;
+ interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ gpm2: gpm2-gpio-bank {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ interrupt-parent = <&gic>;
+ interrupts = <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ gpm3: gpm3-gpio-bank {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ interrupt-parent = <&gic>;
+ interrupts = <GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ gpm4: gpm4-gpio-bank {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ interrupt-parent = <&gic>;
+ interrupts = <GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ gpm5: gpm5-gpio-bank {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ interrupt-parent = <&gic>;
+ interrupts = <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ gpm6: gpm6-gpio-bank {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ interrupt-parent = <&gic>;
+ interrupts = <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ gpm7: gpm7-gpio-bank {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ interrupt-parent = <&gic>;
+ interrupts = <GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ /* USI_CMGP0: HSI2C function */
+ hsi2c3_pins: hsi2c3-pins {
+ samsung,pins = "gpm0-0", "gpm1-0";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+ samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
+ };
+
+ /* USI_CMGP0: UART function (4 pins, Auto Flow Control) */
+ uart1_single_pins: uart1-single-pins {
+ samsung,pins = "gpm0-0", "gpm1-0", "gpm2-0", "gpm3-0";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+ };
+
+ /* USI_CMGP0: UART function (2 pins, Non-Auto Flow Control) */
+ uart1_dual_pins: uart1-dual-pins {
+ samsung,pins = "gpm0-0", "gpm1-0";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+ };
+
+ /* USI_CMGP0: SPI function */
+ spi1_pins: spi1-pins {
+ samsung,pins = "gpm0-0", "gpm1-0", "gpm2-0", "gpm3-0";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+ samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
+ };
+
+ /* USI_CMGP1: HSI2C function */
+ hsi2c4_pins: hsi2c4-pins {
+ samsung,pins = "gpm4-0", "gpm5-0";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+ samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
+ };
+
+ /* USI_CMGP1: UART function (4 pins, Auto Flow Control) */
+ uart2_single_pins: uart2-single-pins {
+ samsung,pins = "gpm4-0", "gpm5-0", "gpm6-0", "gpm7-0";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+ };
+
+ /* USI_CMGP1: UART function (2 pins, Non-Auto Flow Control) */
+ uart2_dual_pins: uart2-dual-pins {
+ samsung,pins = "gpm4-0", "gpm5-0";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+ };
+
+ /* USI_CMGP1: SPI function */
+ spi2_pins: spi2-pins {
+ samsung,pins = "gpm4-0", "gpm5-0", "gpm6-0", "gpm7-0";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+ samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
+ };
+};
+
+&pinctrl_aud {
+ gpb0: gpb0-gpio-bank {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpb1: gpb1-gpio-bank {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ aud_codec_mclk_pins: aud-codec-mclk-pins {
+ samsung,pins = "gpb0-0";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
+ };
+
+ aud_codec_mclk_idle_pins: aud-codec-mclk-idle-pins {
+ samsung,pins = "gpb0-0";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
+ };
+
+ aud_i2s0_pins: aud-i2s0-pins {
+ samsung,pins = "gpb0-1", "gpb0-2", "gpb0-3", "gpb0-4";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
+ };
+
+ aud_i2s0_idle_pins: aud-i2s0-idle-pins {
+ samsung,pins = "gpb0-1", "gpb0-2", "gpb0-3", "gpb0-4";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
+ };
+
+ aud_i2s1_pins: aud-i2s1-pins {
+ samsung,pins = "gpb1-0", "gpb1-1", "gpb1-2", "gpb1-3";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
+ };
+
+ aud_i2s1_idle_pins: aud-i2s1-idle-pins {
+ samsung,pins = "gpb1-0", "gpb1-1", "gpb1-2", "gpb1-3";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
+ };
+
+ aud_fm_pins: aud-fm-pins {
+ samsung,pins = "gpb1-4";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
+ };
+
+ aud_fm_idle_pins: aud-fm-idle-pins {
+ samsung,pins = "gpb1-4";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
+ };
+};
+
+&pinctrl_hsi {
+ gpf2: gpf2-gpio-bank {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ sd2_clk_pins: sd2-clk-pins {
+ samsung,pins = "gpf2-0";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+ samsung,pin-drv = <EXYNOS850_HSI_PIN_DRV_LV2>;
+ };
+
+ sd2_cmd_pins: sd2-cmd-pins {
+ samsung,pins = "gpf2-1";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+ samsung,pin-drv = <EXYNOS850_HSI_PIN_DRV_LV2>;
+ };
+
+ sd2_bus1_pins: sd2-bus1-pins {
+ samsung,pins = "gpf2-2";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+ samsung,pin-drv = <EXYNOS850_HSI_PIN_DRV_LV2>;
+ };
+
+ sd2_bus4_pins: sd2-bus4-pins {
+ samsung,pins = "gpf2-3", "gpf2-4", "gpf2-5";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+ samsung,pin-drv = <EXYNOS850_HSI_PIN_DRV_LV2>;
+ };
+
+ sd2_pdn_pins: sd2-pdn-pins {
+ samsung,pins = "gpf2-0", "gpf2-1", "gpf2-2", "gpf2-3",
+ "gpf2-4", "gpf2-5";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
+ };
+};
+
+&pinctrl_core {
+ gpf0: gpf0-gpio-bank {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpf1: gpf1-gpio-bank {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ sd0_clk_pins: sd0-clk-pins {
+ samsung,pins = "gpf0-0";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+ samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV4>;
+ };
+
+ sd0_cmd_pins: sd0-cmd-pins {
+ samsung,pins = "gpf0-1";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+ samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV4>;
+ };
+
+ sd0_rdqs_pins: sd0-rdqs-pins {
+ samsung,pins = "gpf0-2";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
+ samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV4>;
+ };
+
+ sd0_nreset_pins: sd0-nreset-pins {
+ samsung,pins = "gpf0-3";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+ samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV4>;
+ };
+
+ sd0_bus1_pins: sd0-bus1-pins {
+ samsung,pins = "gpf1-0";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+ samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV4>;
+ };
+
+ sd0_bus4_pins: sd0-bus4-pins {
+ samsung,pins = "gpf1-1", "gpf1-2", "gpf1-3";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+ samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV4>;
+ };
+
+ sd0_bus8_pins: sd0-bus8-pins {
+ samsung,pins = "gpf1-4", "gpf1-5", "gpf1-6", "gpf1-7";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+ samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV4>;
+ };
+};
+
+&pinctrl_peri {
+ gpc0: gpc0-gpio-bank {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpc1: gpc1-gpio-bank {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpg0: gpg0-gpio-bank {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpg1: gpg1-gpio-bank {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpg2: gpg2-gpio-bank {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpg3: gpg3-gpio-bank {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpp0: gpp0-gpio-bank {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+ gpp1: gpp1-gpio-bank {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpp2: gpp2-gpio-bank {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ sensor_mclk0_in_pins: sensor-mclk0-in-pins {
+ samsung,pins = "gpc0-0";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+ samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV3>;
+ };
+
+ sensor_mclk0_out_pins: sensor-mclk0-out-pins {
+ samsung,pins = "gpc0-0";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
+ samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV3>;
+ };
+
+ sensor_mclk0_fn_pins: sensor-mclk0-fn-pins {
+ samsung,pins = "gpc0-0";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+ samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV3>;
+ };
+
+ sensor_mclk1_in_pins: sensor-mclk1-in-pins {
+ samsung,pins = "gpc0-1";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+ samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV3>;
+ };
+
+ sensor_mclk1_out_pins: sensor-mclk1-out-pins {
+ samsung,pins = "gpc0-1";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
+ samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV3>;
+ };
+
+ sensor_mclk1_fn_pins: sensor-mclk1-fn-pins {
+ samsung,pins = "gpc0-1";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+ samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV3>;
+ };
+
+ sensor_mclk2_in_pins: sensor-mclk2-in-pins {
+ samsung,pins = "gpc0-2";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+ samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV3>;
+ };
+
+ sensor_mclk2_out_pins: sensor-mclk2-out-pins {
+ samsung,pins = "gpc0-2";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
+ samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV3>;
+ };
+
+ sensor_mclk2_fn_pins: sensor-mclk2-fn-pins {
+ samsung,pins = "gpc0-2";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+ samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV3>;
+ };
+
+ /* USI: HSI2C0 */
+ hsi2c0_pins: hsi2c0-pins {
+ samsung,pins = "gpc1-0", "gpc1-1";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+ samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
+ };
+
+ /* USI: HSI2C1 */
+ hsi2c1_pins: hsi2c1-pins {
+ samsung,pins = "gpc1-2", "gpc1-3";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+ samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
+ };
+
+ /* USI: HSI2C2 */
+ hsi2c2_pins: hsi2c2-pins {
+ samsung,pins = "gpc1-4", "gpc1-5";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+ samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
+ };
+
+ /* USI: SPI */
+ spi0_pins: spi0-pins {
+ samsung,pins = "gpp2-0", "gpp2-1", "gpp2-2", "gpp2-3";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+ samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
+ };
+
+ i2c0_pins: i2c0-pins {
+ samsung,pins = "gpp0-0", "gpp0-1";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+ samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
+ };
+
+ i2c1_pins: i2c1-pins {
+ samsung,pins = "gpp0-2", "gpp0-3";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+ samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
+ };
+
+ i2c2_pins: i2c2-pins {
+ samsung,pins = "gpp0-4", "gpp0-5";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+ samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
+ };
+
+ i2c3_pins: i2c3-pins {
+ samsung,pins = "gpp1-0", "gpp1-1";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+ samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
+ };
+
+ i2c4_pins: i2c4-pins {
+ samsung,pins = "gpp1-2", "gpp1-3";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+ samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
+ };
+
+ xclkout_pins: xclkout-pins {
+ samsung,pins = "gpq0-2";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+ };
+};
diff --git a/arch/arm64/boot/dts/exynos/exynos850.dtsi b/arch/arm64/boot/dts/exynos/exynos850.dtsi
new file mode 100644
index 000000000000..d1700e96fee2
--- /dev/null
+++ b/arch/arm64/boot/dts/exynos/exynos850.dtsi
@@ -0,0 +1,701 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Samsung Exynos850 SoC device tree source
+ *
+ * Copyright (C) 2018 Samsung Electronics Co., Ltd.
+ * Copyright (C) 2021 Linaro Ltd.
+ *
+ * Samsung Exynos850 SoC device nodes are listed in this file.
+ * Exynos850 based board files can include this file and provide
+ * values for board specific bindings.
+ */
+
+#include <dt-bindings/clock/exynos850.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/soc/samsung,exynos-usi.h>
+
+/ {
+ /* Also known under engineering name Exynos3830 */
+ compatible = "samsung,exynos850";
+ #address-cells = <2>;
+ #size-cells = <1>;
+
+ interrupt-parent = <&gic>;
+
+ aliases {
+ pinctrl0 = &pinctrl_alive;
+ pinctrl1 = &pinctrl_cmgp;
+ pinctrl2 = &pinctrl_aud;
+ pinctrl3 = &pinctrl_hsi;
+ pinctrl4 = &pinctrl_core;
+ pinctrl5 = &pinctrl_peri;
+ mmc0 = &mmc_0;
+ serial0 = &serial_0;
+ serial1 = &serial_1;
+ serial2 = &serial_2;
+ i2c0 = &i2c_0;
+ i2c1 = &i2c_1;
+ i2c2 = &i2c_2;
+ i2c3 = &i2c_3;
+ i2c4 = &i2c_4;
+ i2c5 = &i2c_5;
+ i2c6 = &i2c_6;
+ i2c7 = &hsi2c_0;
+ i2c8 = &hsi2c_1;
+ i2c9 = &hsi2c_2;
+ i2c10 = &hsi2c_3;
+ i2c11 = &hsi2c_4;
+ };
+
+ arm-pmu {
+ compatible = "arm,cortex-a55-pmu";
+ interrupts = <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 108 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 111 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-affinity = <&cpu0>, <&cpu1>, <&cpu2>, <&cpu3>,
+ <&cpu4>, <&cpu5>, <&cpu6>, <&cpu7>;
+ };
+
+ /* Main system clock (XTCXO); external, must be 26 MHz */
+ oscclk: clock-oscclk {
+ compatible = "fixed-clock";
+ clock-output-names = "oscclk";
+ #clock-cells = <0>;
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu-map {
+ cluster0 {
+ core0 {
+ cpu = <&cpu0>;
+ };
+ core1 {
+ cpu = <&cpu1>;
+ };
+ core2 {
+ cpu = <&cpu2>;
+ };
+ core3 {
+ cpu = <&cpu3>;
+ };
+ };
+
+ cluster1 {
+ core0 {
+ cpu = <&cpu4>;
+ };
+ core1 {
+ cpu = <&cpu5>;
+ };
+ core2 {
+ cpu = <&cpu6>;
+ };
+ core3 {
+ cpu = <&cpu7>;
+ };
+ };
+ };
+
+ cpu0: cpu@0 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a55";
+ reg = <0x0>;
+ enable-method = "psci";
+ };
+ cpu1: cpu@1 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a55";
+ reg = <0x1>;
+ enable-method = "psci";
+ };
+ cpu2: cpu@2 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a55";
+ reg = <0x2>;
+ enable-method = "psci";
+ };
+ cpu3: cpu@3 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a55";
+ reg = <0x3>;
+ enable-method = "psci";
+ };
+ cpu4: cpu@100 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a55";
+ reg = <0x100>;
+ enable-method = "psci";
+ };
+ cpu5: cpu@101 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a55";
+ reg = <0x101>;
+ enable-method = "psci";
+ };
+ cpu6: cpu@102 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a55";
+ reg = <0x102>;
+ enable-method = "psci";
+ };
+ cpu7: cpu@103 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a55";
+ reg = <0x103>;
+ enable-method = "psci";
+ };
+ };
+
+ psci {
+ compatible = "arm,psci-1.0";
+ method = "smc";
+ };
+
+ timer {
+ compatible = "arm,armv8-timer";
+ /* Hypervisor Virtual Timer interrupt is not wired to GIC */
+ interrupts =
+ <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>,
+ <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>,
+ <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>,
+ <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>;
+ };
+
+ soc: soc@0 {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0x0 0x0 0x0 0x20000000>;
+
+ chipid@10000000 {
+ compatible = "samsung,exynos850-chipid";
+ reg = <0x10000000 0x100>;
+ };
+
+ timer@10040000 {
+ compatible = "samsung,exynos4210-mct";
+ reg = <0x10040000 0x800>;
+ interrupts = <GIC_SPI 203 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 204 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 205 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 206 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 207 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 208 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 209 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 210 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 211 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 212 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 213 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 214 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&oscclk>, <&cmu_peri CLK_GOUT_MCT_PCLK>;
+ clock-names = "fin_pll", "mct";
+ };
+
+ gic: interrupt-controller@12a01000 {
+ compatible = "arm,gic-400";
+ #interrupt-cells = <3>;
+ #address-cells = <0>;
+ reg = <0x12a01000 0x1000>,
+ <0x12a02000 0x2000>,
+ <0x12a04000 0x2000>,
+ <0x12a06000 0x2000>;
+ interrupt-controller;
+ interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(8) |
+ IRQ_TYPE_LEVEL_HIGH)>;
+ };
+
+ pmu_system_controller: system-controller@11860000 {
+ compatible = "samsung,exynos850-pmu", "syscon";
+ reg = <0x11860000 0x10000>;
+ clocks = <&cmu_apm CLK_GOUT_PMU_ALIVE_PCLK>;
+
+ reboot: syscon-reboot {
+ compatible = "syscon-reboot";
+ regmap = <&pmu_system_controller>;
+ offset = <0x3a00>; /* SYSTEM_CONFIGURATION */
+ mask = <0x2>; /* SWRESET_SYSTEM */
+ value = <0x2>; /* reset value */
+ };
+ };
+
+ watchdog_cl0: watchdog@10050000 {
+ compatible = "samsung,exynos850-wdt";
+ reg = <0x10050000 0x100>;
+ interrupts = <GIC_SPI 228 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cmu_peri CLK_GOUT_WDT0_PCLK>, <&oscclk>;
+ clock-names = "watchdog", "watchdog_src";
+ samsung,syscon-phandle = <&pmu_system_controller>;
+ samsung,cluster-index = <0>;
+ status = "disabled";
+ };
+
+ watchdog_cl1: watchdog@10060000 {
+ compatible = "samsung,exynos850-wdt";
+ reg = <0x10060000 0x100>;
+ interrupts = <GIC_SPI 229 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cmu_peri CLK_GOUT_WDT1_PCLK>, <&oscclk>;
+ clock-names = "watchdog", "watchdog_src";
+ samsung,syscon-phandle = <&pmu_system_controller>;
+ samsung,cluster-index = <1>;
+ status = "disabled";
+ };
+
+ cmu_peri: clock-controller@10030000 {
+ compatible = "samsung,exynos850-cmu-peri";
+ reg = <0x10030000 0x8000>;
+ #clock-cells = <1>;
+
+ clocks = <&oscclk>, <&cmu_top CLK_DOUT_PERI_BUS>,
+ <&cmu_top CLK_DOUT_PERI_UART>,
+ <&cmu_top CLK_DOUT_PERI_IP>;
+ clock-names = "oscclk", "dout_peri_bus",
+ "dout_peri_uart", "dout_peri_ip";
+ };
+
+ cmu_apm: clock-controller@11800000 {
+ compatible = "samsung,exynos850-cmu-apm";
+ reg = <0x11800000 0x8000>;
+ #clock-cells = <1>;
+
+ clocks = <&oscclk>, <&cmu_top CLK_DOUT_CLKCMU_APM_BUS>;
+ clock-names = "oscclk", "dout_clkcmu_apm_bus";
+ };
+
+ cmu_cmgp: clock-controller@11c00000 {
+ compatible = "samsung,exynos850-cmu-cmgp";
+ reg = <0x11c00000 0x8000>;
+ #clock-cells = <1>;
+
+ clocks = <&oscclk>, <&cmu_apm CLK_GOUT_CLKCMU_CMGP_BUS>;
+ clock-names = "oscclk", "gout_clkcmu_cmgp_bus";
+ };
+
+ cmu_core: clock-controller@12000000 {
+ compatible = "samsung,exynos850-cmu-core";
+ reg = <0x12000000 0x8000>;
+ #clock-cells = <1>;
+
+ clocks = <&oscclk>, <&cmu_top CLK_DOUT_CORE_BUS>,
+ <&cmu_top CLK_DOUT_CORE_CCI>,
+ <&cmu_top CLK_DOUT_CORE_MMC_EMBD>,
+ <&cmu_top CLK_DOUT_CORE_SSS>;
+ clock-names = "oscclk", "dout_core_bus",
+ "dout_core_cci", "dout_core_mmc_embd",
+ "dout_core_sss";
+ };
+
+ cmu_top: clock-controller@120e0000 {
+ compatible = "samsung,exynos850-cmu-top";
+ reg = <0x120e0000 0x8000>;
+ #clock-cells = <1>;
+
+ clocks = <&oscclk>;
+ clock-names = "oscclk";
+ };
+
+ cmu_dpu: clock-controller@13000000 {
+ compatible = "samsung,exynos850-cmu-dpu";
+ reg = <0x13000000 0x8000>;
+ #clock-cells = <1>;
+
+ clocks = <&oscclk>, <&cmu_top CLK_DOUT_DPU>;
+ clock-names = "oscclk", "dout_dpu";
+ };
+
+ cmu_hsi: clock-controller@13400000 {
+ compatible = "samsung,exynos850-cmu-hsi";
+ reg = <0x13400000 0x8000>;
+ #clock-cells = <1>;
+
+ clocks = <&oscclk>,
+ <&cmu_top CLK_DOUT_HSI_BUS>,
+ <&cmu_top CLK_DOUT_HSI_MMC_CARD>,
+ <&cmu_top CLK_DOUT_HSI_USB20DRD>;
+ clock-names = "oscclk", "dout_hsi_bus",
+ "dout_hsi_mmc_card", "dout_hsi_usb20drd";
+ };
+
+ pinctrl_alive: pinctrl@11850000 {
+ compatible = "samsung,exynos850-pinctrl";
+ reg = <0x11850000 0x1000>;
+
+ wakeup-interrupt-controller {
+ compatible = "samsung,exynos850-wakeup-eint";
+ };
+ };
+
+ pinctrl_cmgp: pinctrl@11c30000 {
+ compatible = "samsung,exynos850-pinctrl";
+ reg = <0x11c30000 0x1000>;
+
+ wakeup-interrupt-controller {
+ compatible = "samsung,exynos850-wakeup-eint";
+ };
+ };
+
+ pinctrl_core: pinctrl@12070000 {
+ compatible = "samsung,exynos850-pinctrl";
+ reg = <0x12070000 0x1000>;
+ interrupts = <GIC_SPI 451 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ pinctrl_hsi: pinctrl@13430000 {
+ compatible = "samsung,exynos850-pinctrl";
+ reg = <0x13430000 0x1000>;
+ interrupts = <GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ pinctrl_peri: pinctrl@139b0000 {
+ compatible = "samsung,exynos850-pinctrl";
+ reg = <0x139b0000 0x1000>;
+ interrupts = <GIC_SPI 192 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ pinctrl_aud: pinctrl@14a60000 {
+ compatible = "samsung,exynos850-pinctrl";
+ reg = <0x14a60000 0x1000>;
+ };
+
+ rtc: rtc@11a30000 {
+ compatible = "samsung,s3c6410-rtc";
+ reg = <0x11a30000 0x100>;
+ interrupts = <GIC_SPI 57 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 58 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cmu_apm CLK_GOUT_RTC_PCLK>;
+ clock-names = "rtc";
+ status = "disabled";
+ };
+
+ mmc_0: mmc@12100000 {
+ compatible = "samsung,exynos7-dw-mshc-smu";
+ reg = <0x12100000 0x2000>;
+ interrupts = <GIC_SPI 452 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&cmu_core CLK_GOUT_MMC_EMBD_ACLK>,
+ <&cmu_core CLK_GOUT_MMC_EMBD_SDCLKIN>;
+ clock-names = "biu", "ciu";
+ fifo-depth = <0x40>;
+ status = "disabled";
+ };
+
+ i2c_0: i2c@13830000 {
+ compatible = "samsung,s3c2440-i2c";
+ reg = <0x13830000 0x100>;
+ interrupts = <GIC_SPI 196 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0_pins>;
+ clocks = <&cmu_peri CLK_GOUT_I2C0_PCLK>;
+ clock-names = "i2c";
+ status = "disabled";
+ };
+
+ i2c_1: i2c@13840000 {
+ compatible = "samsung,s3c2440-i2c";
+ reg = <0x13840000 0x100>;
+ interrupts = <GIC_SPI 197 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c1_pins>;
+ clocks = <&cmu_peri CLK_GOUT_I2C1_PCLK>;
+ clock-names = "i2c";
+ status = "disabled";
+ };
+
+ i2c_2: i2c@13850000 {
+ compatible = "samsung,s3c2440-i2c";
+ reg = <0x13850000 0x100>;
+ interrupts = <GIC_SPI 198 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c2_pins>;
+ clocks = <&cmu_peri CLK_GOUT_I2C2_PCLK>;
+ clock-names = "i2c";
+ status = "disabled";
+ };
+
+ i2c_3: i2c@13860000 {
+ compatible = "samsung,s3c2440-i2c";
+ reg = <0x13860000 0x100>;
+ interrupts = <GIC_SPI 199 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c3_pins>;
+ clocks = <&cmu_peri CLK_GOUT_I2C3_PCLK>;
+ clock-names = "i2c";
+ status = "disabled";
+ };
+
+ i2c_4: i2c@13870000 {
+ compatible = "samsung,s3c2440-i2c";
+ reg = <0x13870000 0x100>;
+ interrupts = <GIC_SPI 200 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c4_pins>;
+ clocks = <&cmu_peri CLK_GOUT_I2C4_PCLK>;
+ clock-names = "i2c";
+ status = "disabled";
+ };
+
+ /* I2C_5 (also called CAM_PMIC_I2C in TRM) */
+ i2c_5: i2c@13880000 {
+ compatible = "samsung,s3c2440-i2c";
+ reg = <0x13880000 0x100>;
+ interrupts = <GIC_SPI 201 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c5_pins>;
+ clocks = <&cmu_peri CLK_GOUT_I2C5_PCLK>;
+ clock-names = "i2c";
+ status = "disabled";
+ };
+
+ /* I2C_6 (also called MOTOR_I2C in TRM) */
+ i2c_6: i2c@13890000 {
+ compatible = "samsung,s3c2440-i2c";
+ reg = <0x13890000 0x100>;
+ interrupts = <GIC_SPI 202 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c6_pins>;
+ clocks = <&cmu_peri CLK_GOUT_I2C6_PCLK>;
+ clock-names = "i2c";
+ status = "disabled";
+ };
+
+ sysreg_peri: syscon@10020000 {
+ compatible = "samsung,exynos850-sysreg", "syscon";
+ reg = <0x10020000 0x10000>;
+ clocks = <&cmu_peri CLK_GOUT_SYSREG_PERI_PCLK>;
+ };
+
+ sysreg_cmgp: syscon@11c20000 {
+ compatible = "samsung,exynos850-sysreg", "syscon";
+ reg = <0x11c20000 0x10000>;
+ clocks = <&cmu_cmgp CLK_GOUT_SYSREG_CMGP_PCLK>;
+ };
+
+ usi_uart: usi@138200c0 {
+ compatible = "samsung,exynos850-usi";
+ reg = <0x138200c0 0x20>;
+ samsung,sysreg = <&sysreg_peri 0x1010>;
+ samsung,mode = <USI_V2_UART>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+ clocks = <&cmu_peri CLK_GOUT_UART_PCLK>,
+ <&cmu_peri CLK_GOUT_UART_IPCLK>;
+ clock-names = "pclk", "ipclk";
+ status = "disabled";
+
+ serial_0: serial@13820000 {
+ compatible = "samsung,exynos850-uart";
+ reg = <0x13820000 0xc0>;
+ interrupts = <GIC_SPI 227 IRQ_TYPE_LEVEL_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0_pins>;
+ clocks = <&cmu_peri CLK_GOUT_UART_PCLK>,
+ <&cmu_peri CLK_GOUT_UART_IPCLK>;
+ clock-names = "uart", "clk_uart_baud0";
+ status = "disabled";
+ };
+ };
+
+ usi_hsi2c_0: usi@138a00c0 {
+ compatible = "samsung,exynos850-usi";
+ reg = <0x138a00c0 0x20>;
+ samsung,sysreg = <&sysreg_peri 0x1020>;
+ samsung,mode = <USI_V2_I2C>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+ clocks = <&cmu_peri CLK_GOUT_HSI2C0_PCLK>,
+ <&cmu_peri CLK_GOUT_HSI2C0_IPCLK>;
+ clock-names = "pclk", "ipclk";
+ status = "disabled";
+
+ hsi2c_0: i2c@138a0000 {
+ compatible = "samsung,exynosautov9-hsi2c";
+ reg = <0x138a0000 0xc0>;
+ interrupts = <GIC_SPI 193 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&hsi2c0_pins>;
+ clocks = <&cmu_peri CLK_GOUT_HSI2C0_IPCLK>,
+ <&cmu_peri CLK_GOUT_HSI2C0_PCLK>;
+ clock-names = "hsi2c", "hsi2c_pclk";
+ status = "disabled";
+ };
+ };
+
+ usi_hsi2c_1: usi@138b00c0 {
+ compatible = "samsung,exynos850-usi";
+ reg = <0x138b00c0 0x20>;
+ samsung,sysreg = <&sysreg_peri 0x1030>;
+ samsung,mode = <USI_V2_I2C>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+ clocks = <&cmu_peri CLK_GOUT_HSI2C1_PCLK>,
+ <&cmu_peri CLK_GOUT_HSI2C1_IPCLK>;
+ clock-names = "pclk", "ipclk";
+ status = "disabled";
+
+ hsi2c_1: i2c@138b0000 {
+ compatible = "samsung,exynosautov9-hsi2c";
+ reg = <0x138b0000 0xc0>;
+ interrupts = <GIC_SPI 194 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&hsi2c1_pins>;
+ clocks = <&cmu_peri CLK_GOUT_HSI2C1_IPCLK>,
+ <&cmu_peri CLK_GOUT_HSI2C1_PCLK>;
+ clock-names = "hsi2c", "hsi2c_pclk";
+ status = "disabled";
+ };
+ };
+
+ usi_hsi2c_2: usi@138c00c0 {
+ compatible = "samsung,exynos850-usi";
+ reg = <0x138c00c0 0x20>;
+ samsung,sysreg = <&sysreg_peri 0x1040>;
+ samsung,mode = <USI_V2_I2C>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+ clocks = <&cmu_peri CLK_GOUT_HSI2C2_PCLK>,
+ <&cmu_peri CLK_GOUT_HSI2C2_IPCLK>;
+ clock-names = "pclk", "ipclk";
+ status = "disabled";
+
+ hsi2c_2: i2c@138c0000 {
+ compatible = "samsung,exynosautov9-hsi2c";
+ reg = <0x138c0000 0xc0>;
+ interrupts = <GIC_SPI 195 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&hsi2c2_pins>;
+ clocks = <&cmu_peri CLK_GOUT_HSI2C2_IPCLK>,
+ <&cmu_peri CLK_GOUT_HSI2C2_PCLK>;
+ clock-names = "hsi2c", "hsi2c_pclk";
+ status = "disabled";
+ };
+ };
+
+ usi_spi_0: usi@139400c0 {
+ compatible = "samsung,exynos850-usi";
+ reg = <0x139400c0 0x20>;
+ samsung,sysreg = <&sysreg_peri 0x1050>;
+ samsung,mode = <USI_V2_SPI>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+ clocks = <&cmu_peri CLK_GOUT_SPI0_PCLK>,
+ <&cmu_peri CLK_GOUT_SPI0_IPCLK>;
+ clock-names = "pclk", "ipclk";
+ status = "disabled";
+ };
+
+ usi_cmgp0: usi@11d000c0 {
+ compatible = "samsung,exynos850-usi";
+ reg = <0x11d000c0 0x20>;
+ samsung,sysreg = <&sysreg_cmgp 0x2000>;
+ samsung,mode = <USI_V2_I2C>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+ clocks = <&cmu_cmgp CLK_GOUT_CMGP_USI0_PCLK>,
+ <&cmu_cmgp CLK_GOUT_CMGP_USI0_IPCLK>;
+ clock-names = "pclk", "ipclk";
+ status = "disabled";
+
+ hsi2c_3: i2c@11d00000 {
+ compatible = "samsung,exynosautov9-hsi2c";
+ reg = <0x11d00000 0xc0>;
+ interrupts = <GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&hsi2c3_pins>;
+ clocks = <&cmu_cmgp CLK_GOUT_CMGP_USI0_IPCLK>,
+ <&cmu_cmgp CLK_GOUT_CMGP_USI0_PCLK>;
+ clock-names = "hsi2c", "hsi2c_pclk";
+ status = "disabled";
+ };
+
+ serial_1: serial@11d00000 {
+ compatible = "samsung,exynos850-uart";
+ reg = <0x11d00000 0xc0>;
+ interrupts = <GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart1_single_pins>;
+ clocks = <&cmu_cmgp CLK_GOUT_CMGP_USI0_PCLK>,
+ <&cmu_cmgp CLK_GOUT_CMGP_USI0_IPCLK>;
+ clock-names = "uart", "clk_uart_baud0";
+ status = "disabled";
+ };
+ };
+
+ usi_cmgp1: usi@11d200c0 {
+ compatible = "samsung,exynos850-usi";
+ reg = <0x11d200c0 0x20>;
+ samsung,sysreg = <&sysreg_cmgp 0x2010>;
+ samsung,mode = <USI_V2_I2C>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+ clocks = <&cmu_cmgp CLK_GOUT_CMGP_USI1_PCLK>,
+ <&cmu_cmgp CLK_GOUT_CMGP_USI1_IPCLK>;
+ clock-names = "pclk", "ipclk";
+ status = "disabled";
+
+ hsi2c_4: i2c@11d20000 {
+ compatible = "samsung,exynosautov9-hsi2c";
+ reg = <0x11d20000 0xc0>;
+ interrupts = <GIC_SPI 63 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&hsi2c4_pins>;
+ clocks = <&cmu_cmgp CLK_GOUT_CMGP_USI1_IPCLK>,
+ <&cmu_cmgp CLK_GOUT_CMGP_USI1_PCLK>;
+ clock-names = "hsi2c", "hsi2c_pclk";
+ status = "disabled";
+ };
+
+ serial_2: serial@11d20000 {
+ compatible = "samsung,exynos850-uart";
+ reg = <0x11d20000 0xc0>;
+ interrupts = <GIC_SPI 63 IRQ_TYPE_LEVEL_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart2_single_pins>;
+ clocks = <&cmu_cmgp CLK_GOUT_CMGP_USI1_PCLK>,
+ <&cmu_cmgp CLK_GOUT_CMGP_USI1_IPCLK>;
+ clock-names = "uart", "clk_uart_baud0";
+ status = "disabled";
+ };
+ };
+ };
+};
+
+#include "exynos850-pinctrl.dtsi"
diff --git a/arch/arm64/boot/dts/exynos/exynosautov9-pinctrl.dtsi b/arch/arm64/boot/dts/exynos/exynosautov9-pinctrl.dtsi
index 2407b03b5404..ef0349d1c3d0 100644
--- a/arch/arm64/boot/dts/exynos/exynosautov9-pinctrl.dtsi
+++ b/arch/arm64/boot/dts/exynos/exynosautov9-pinctrl.dtsi
@@ -11,7 +11,7 @@
#include <dt-bindings/pinctrl/samsung.h>
&pinctrl_alive {
- gpa0: gpa0 {
+ gpa0: gpa0-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
interrupt-controller;
@@ -27,7 +27,7 @@
<GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>;
};
- gpa1: gpa1 {
+ gpa1: gpa1-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
interrupt-controller;
@@ -47,7 +47,7 @@
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
};
- gpq0: gpq0 {
+ gpq0: gpq0-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -69,7 +69,7 @@
};
&pinctrl_aud {
- gpb0: gpb0 {
+ gpb0: gpb0-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -77,7 +77,7 @@
#interrupt-cells = <2>;
};
- gpb1: gpb1 {
+ gpb1: gpb1-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -85,7 +85,7 @@
#interrupt-cells = <2>;
};
- gpb2: gpb2 {
+ gpb2: gpb2-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -93,7 +93,7 @@
#interrupt-cells = <2>;
};
- gpb3: gpb3 {
+ gpb3: gpb3-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -199,7 +199,7 @@
};
&pinctrl_fsys0 {
- gpf0: gpf0 {
+ gpf0: gpf0-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -207,7 +207,7 @@
#interrupt-cells = <2>;
};
- gpf1: gpf1 {
+ gpf1: gpf1-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -355,7 +355,7 @@
};
&pinctrl_fsys1 {
- gpf8: gpf8 {
+ gpf8: gpf8-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -393,7 +393,7 @@
};
&pinctrl_fsys2 {
- gpf2: gpf2 {
+ gpf2: gpf2-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -401,7 +401,7 @@
#interrupt-cells = <2>;
};
- gpf3: gpf3 {
+ gpf3: gpf3-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -409,7 +409,7 @@
#interrupt-cells = <2>;
};
- gpf4: gpf4 {
+ gpf4: gpf4-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -417,7 +417,7 @@
#interrupt-cells = <2>;
};
- gpf5: gpf5 {
+ gpf5: gpf5-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -425,7 +425,7 @@
#interrupt-cells = <2>;
};
- gpf6: gpf6 {
+ gpf6: gpf6-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -499,7 +499,7 @@
};
&pinctrl_peric0 {
- gpp0: gpp0 {
+ gpp0: gpp0-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -507,7 +507,7 @@
#interrupt-cells = <2>;
};
- gpp1: gpp1 {
+ gpp1: gpp1-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -515,7 +515,7 @@
#interrupt-cells = <2>;
};
- gpp2: gpp2 {
+ gpp2: gpp2-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -523,7 +523,7 @@
#interrupt-cells = <2>;
};
- gpg0: gpg0 {
+ gpg0: gpg0-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -833,7 +833,7 @@
};
&pinctrl_peric1 {
- gpp3: gpp3 {
+ gpp3: gpp3-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -841,7 +841,7 @@
#interrupt-cells = <2>;
};
- gpp4: gpp4 {
+ gpp4: gpp4-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -849,7 +849,7 @@
#interrupt-cells = <2>;
};
- gpp5: gpp5 {
+ gpp5: gpp5-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -857,7 +857,7 @@
#interrupt-cells = <2>;
};
- gpg1: gpg1 {
+ gpg1: gpg1-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -865,7 +865,7 @@
#interrupt-cells = <2>;
};
- gpg2: gpg2 {
+ gpg2: gpg2-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
@@ -873,7 +873,7 @@
#interrupt-cells = <2>;
};
- gpg3: gpg3 {
+ gpg3: gpg3-gpio-bank {
gpio-controller;
#gpio-cells = <2>;
diff --git a/arch/arm64/boot/dts/exynos/exynosautov9.dtsi b/arch/arm64/boot/dts/exynos/exynosautov9.dtsi
index de8fcb82eaec..807d500d6022 100644
--- a/arch/arm64/boot/dts/exynos/exynosautov9.dtsi
+++ b/arch/arm64/boot/dts/exynos/exynosautov9.dtsi
@@ -208,7 +208,7 @@
reg = <0x10450000 0x1000>;
wakeup-interrupt-controller {
- compatible = "samsung,exynos7-wakeup-eint";
+ compatible = "samsung,exynosautov9-wakeup-eint";
};
};
diff --git a/arch/arm64/boot/dts/freescale/Makefile b/arch/arm64/boot/dts/freescale/Makefile
index 6d8f0a532587..7f51b537df40 100644
--- a/arch/arm64/boot/dts/freescale/Makefile
+++ b/arch/arm64/boot/dts/freescale/Makefile
@@ -1,14 +1,5 @@
# SPDX-License-Identifier: GPL-2.0
-# required for overlay support
-DTC_FLAGS_fsl-ls1028a-qds := -@
-DTC_FLAGS_fsl-ls1028a-qds-13bb := -@
-DTC_FLAGS_fsl-ls1028a-qds-65bb := -@
-DTC_FLAGS_fsl-ls1028a-qds-7777 := -@
-DTC_FLAGS_fsl-ls1028a-qds-85bb := -@
-DTC_FLAGS_fsl-ls1028a-qds-899b := -@
-DTC_FLAGS_fsl-ls1028a-qds-9999 := -@
-
dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1012a-frdm.dtb
dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1012a-frwy.dtb
dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1012a-oxalis.dtb
@@ -21,12 +12,6 @@ dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1028a-kontron-sl28-var2.dtb
dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1028a-kontron-sl28-var3-ads2.dtb
dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1028a-kontron-sl28-var4.dtb
dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1028a-qds.dtb
-dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1028a-qds-13bb.dtb
-dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1028a-qds-65bb.dtb
-dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1028a-qds-7777.dtb
-dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1028a-qds-85bb.dtb
-dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1028a-qds-899b.dtb
-dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1028a-qds-9999.dtb
dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1028a-rdb.dtb
dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1043a-qds.dtb
dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1043a-rdb.dtb
@@ -49,9 +34,24 @@ dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-lx2160a-qds.dtb
dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-lx2160a-rdb.dtb
dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-lx2162a-qds.dtb
+fsl-ls1028a-qds-13bb-dtbs := fsl-ls1028a-qds.dtb fsl-ls1028a-qds-13bb.dtbo
+fsl-ls1028a-qds-65bb-dtbs := fsl-ls1028a-qds.dtb fsl-ls1028a-qds-65bb.dtbo
+fsl-ls1028a-qds-7777-dtbs := fsl-ls1028a-qds.dtb fsl-ls1028a-qds-7777.dtbo
+fsl-ls1028a-qds-85bb-dtbs := fsl-ls1028a-qds.dtb fsl-ls1028a-qds-85bb.dtbo
+fsl-ls1028a-qds-899b-dtbs := fsl-ls1028a-qds.dtb fsl-ls1028a-qds-899b.dtbo
+fsl-ls1028a-qds-9999-dtbs := fsl-ls1028a-qds.dtb fsl-ls1028a-qds-9999.dtbo
+
+dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1028a-qds-13bb.dtb
+dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1028a-qds-65bb.dtb
+dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1028a-qds-7777.dtb
+dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1028a-qds-85bb.dtb
+dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1028a-qds-899b.dtb
+dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1028a-qds-9999.dtb
+
dtb-$(CONFIG_ARCH_MXC) += imx8mm-beacon-kit.dtb
-dtb-$(CONFIG_ARCH_MXC) += imx8mm-evk.dtb
dtb-$(CONFIG_ARCH_MXC) += imx8mm-ddr4-evk.dtb
+dtb-$(CONFIG_ARCH_MXC) += imx8mm-emcon-avari.dtb
+dtb-$(CONFIG_ARCH_MXC) += imx8mm-evk.dtb
dtb-$(CONFIG_ARCH_MXC) += imx8mm-icore-mx8mm-ctouch2.dtb
dtb-$(CONFIG_ARCH_MXC) += imx8mm-icore-mx8mm-edimm2.2.dtb
dtb-$(CONFIG_ARCH_MXC) += imx8mm-kontron-n801x-s.dtb
@@ -63,6 +63,11 @@ dtb-$(CONFIG_ARCH_MXC) += imx8mm-venice-gw72xx-0x.dtb
dtb-$(CONFIG_ARCH_MXC) += imx8mm-venice-gw73xx-0x.dtb
dtb-$(CONFIG_ARCH_MXC) += imx8mm-venice-gw7901.dtb
dtb-$(CONFIG_ARCH_MXC) += imx8mm-venice-gw7902.dtb
+dtb-$(CONFIG_ARCH_MXC) += imx8mm-venice-gw7903.dtb
+dtb-$(CONFIG_ARCH_MXC) += imx8mm-verdin-nonwifi-dahlia.dtb
+dtb-$(CONFIG_ARCH_MXC) += imx8mm-verdin-nonwifi-dev.dtb
+dtb-$(CONFIG_ARCH_MXC) += imx8mm-verdin-wifi-dahlia.dtb
+dtb-$(CONFIG_ARCH_MXC) += imx8mm-verdin-wifi-dev.dtb
dtb-$(CONFIG_ARCH_MXC) += imx8mn-beacon-kit.dtb
dtb-$(CONFIG_ARCH_MXC) += imx8mn-bsh-smm-s2.dtb
dtb-$(CONFIG_ARCH_MXC) += imx8mn-bsh-smm-s2pro.dtb
@@ -94,6 +99,24 @@ dtb-$(CONFIG_ARCH_MXC) += imx8qxp-colibri-eval-v3.dtb
dtb-$(CONFIG_ARCH_MXC) += imx8qxp-mek.dtb
dtb-$(CONFIG_ARCH_MXC) += imx8ulp-evk.dtb
+imx8mm-venice-gw72xx-0x-imx219-dtbs := imx8mm-venice-gw73xx-0x.dtb imx8mm-venice-gw73xx-0x-imx219.dtbo
+imx8mm-venice-gw72xx-0x-rs232-rts-dtbs := imx8mm-venice-gw72xx-0x.dtb imx8mm-venice-gw72xx-0x-rs232-rts.dtbo
+imx8mm-venice-gw72xx-0x-rs422-dtbs := imx8mm-venice-gw72xx-0x.dtb imx8mm-venice-gw72xx-0x-rs422.dtbo
+imx8mm-venice-gw72xx-0x-rs485-dtbs := imx8mm-venice-gw72xx-0x.dtb imx8mm-venice-gw72xx-0x-rs485.dtbo
+imx8mm-venice-gw73xx-0x-imx219-dtbs := imx8mm-venice-gw73xx-0x.dtb imx8mm-venice-gw73xx-0x-imx219.dtbo
+imx8mm-venice-gw73xx-0x-rs232-rts-dtbs := imx8mm-venice-gw73xx-0x.dtb imx8mm-venice-gw73xx-0x-rs232-rts.dtbo
+imx8mm-venice-gw73xx-0x-rs422-dtbs := imx8mm-venice-gw73xx-0x.dtb imx8mm-venice-gw73xx-0x-rs422.dtbo
+imx8mm-venice-gw73xx-0x-rs485-dtbs := imx8mm-venice-gw73xx-0x.dtb imx8mm-venice-gw73xx-0x-rs485.dtbo
+
+dtb-$(CONFIG_ARCH_MXC) += imx8mm-venice-gw72xx-0x-imx219.dtb
+dtb-$(CONFIG_ARCH_MXC) += imx8mm-venice-gw72xx-0x-rs232-rts.dtb
+dtb-$(CONFIG_ARCH_MXC) += imx8mm-venice-gw72xx-0x-rs422.dtb
+dtb-$(CONFIG_ARCH_MXC) += imx8mm-venice-gw72xx-0x-rs485.dtb
+dtb-$(CONFIG_ARCH_MXC) += imx8mm-venice-gw73xx-0x-imx219.dtb
+dtb-$(CONFIG_ARCH_MXC) += imx8mm-venice-gw73xx-0x-rs232-rts.dtb
+dtb-$(CONFIG_ARCH_MXC) += imx8mm-venice-gw73xx-0x-rs422.dtb
+dtb-$(CONFIG_ARCH_MXC) += imx8mm-venice-gw73xx-0x-rs485.dtb
+
dtb-$(CONFIG_ARCH_S32) += s32g274a-evb.dtb
dtb-$(CONFIG_ARCH_S32) += s32g274a-rdb2.dtb
dtb-$(CONFIG_ARCH_S32) += s32v234-evb.dtb
diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1028a-kontron-sl28.dts b/arch/arm64/boot/dts/freescale/fsl-ls1028a-kontron-sl28.dts
index d74e738e4070..c03f4e183389 100644
--- a/arch/arm64/boot/dts/freescale/fsl-ls1028a-kontron-sl28.dts
+++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a-kontron-sl28.dts
@@ -157,6 +157,10 @@
};
};
+&ftm_alarm0 {
+ status = "okay";
+};
+
&gpio1 {
gpio-line-names =
"", "", "", "", "", "", "", "",
diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds-13bb.dts b/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds-13bb.dts
index f748a2c12a70..f826392c23fa 100644
--- a/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds-13bb.dts
+++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds-13bb.dts
@@ -12,102 +12,80 @@
/dts-v1/;
/plugin/;
-/ {
- fragment@0 {
- target = <&mdio_slot1>;
-
- __overlay__ {
- #address-cells = <1>;
- #size-cells = <0>;
-
- slot1_sgmii: ethernet-phy@2 {
- /* AQR112 */
- reg = <0x2>;
- compatible = "ethernet-phy-ieee802.3-c45";
- };
- };
- };
-
- fragment@1 {
- target = <&enetc_port0>;
-
- __overlay__ {
- phy-handle = <&slot1_sgmii>;
- phy-mode = "usxgmii";
- managed = "in-band-status";
- status = "okay";
- };
+&mdio_slot1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ slot1_sgmii: ethernet-phy@2 {
+ /* AQR112 */
+ reg = <0x2>;
+ compatible = "ethernet-phy-ieee802.3-c45";
};
+};
- fragment@2 {
- target = <&mdio_slot2>;
-
- __overlay__ {
- #address-cells = <1>;
- #size-cells = <0>;
-
- /* 4 ports on AQR412 */
- slot2_qxgmii0: ethernet-phy@0 {
- reg = <0x0>;
- compatible = "ethernet-phy-ieee802.3-c45";
- };
-
- slot2_qxgmii1: ethernet-phy@1 {
- reg = <0x1>;
- compatible = "ethernet-phy-ieee802.3-c45";
- };
+&enetc_port0 {
+ phy-handle = <&slot1_sgmii>;
+ phy-mode = "usxgmii";
+ managed = "in-band-status";
+ status = "okay";
+};
- slot2_qxgmii2: ethernet-phy@2 {
- reg = <0x2>;
- compatible = "ethernet-phy-ieee802.3-c45";
- };
+&mdio_slot2 {
+ #address-cells = <1>;
+ #size-cells = <0>;
- slot2_qxgmii3: ethernet-phy@3 {
- reg = <0x3>;
- compatible = "ethernet-phy-ieee802.3-c45";
- };
- };
+ /* 4 ports on AQR412 */
+ slot2_qxgmii0: ethernet-phy@0 {
+ reg = <0x0>;
+ compatible = "ethernet-phy-ieee802.3-c45";
};
- fragment@3 {
- target = <&mscc_felix_ports>;
+ slot2_qxgmii1: ethernet-phy@1 {
+ reg = <0x1>;
+ compatible = "ethernet-phy-ieee802.3-c45";
+ };
- __overlay__ {
- port@0 {
- status = "okay";
- phy-handle = <&slot2_qxgmii0>;
- phy-mode = "usxgmii";
- managed = "in-band-status";
- };
+ slot2_qxgmii2: ethernet-phy@2 {
+ reg = <0x2>;
+ compatible = "ethernet-phy-ieee802.3-c45";
+ };
- port@1 {
- status = "okay";
- phy-handle = <&slot2_qxgmii1>;
- phy-mode = "usxgmii";
- managed = "in-band-status";
- };
+ slot2_qxgmii3: ethernet-phy@3 {
+ reg = <0x3>;
+ compatible = "ethernet-phy-ieee802.3-c45";
+ };
+};
- port@2 {
- status = "okay";
- phy-handle = <&slot2_qxgmii2>;
- phy-mode = "usxgmii";
- managed = "in-band-status";
- };
+&mscc_felix_ports {
+ port@0 {
+ status = "okay";
+ phy-handle = <&slot2_qxgmii0>;
+ phy-mode = "usxgmii";
+ managed = "in-band-status";
+ };
- port@3 {
- status = "okay";
- phy-handle = <&slot2_qxgmii3>;
- phy-mode = "usxgmii";
- managed = "in-band-status";
- };
- };
+ port@1 {
+ status = "okay";
+ phy-handle = <&slot2_qxgmii1>;
+ phy-mode = "usxgmii";
+ managed = "in-band-status";
};
- fragment@4 {
- target = <&mscc_felix>;
+ port@2 {
+ status = "okay";
+ phy-handle = <&slot2_qxgmii2>;
+ phy-mode = "usxgmii";
+ managed = "in-band-status";
+ };
- __overlay__ {
- status = "okay";
- };
+ port@3 {
+ status = "okay";
+ phy-handle = <&slot2_qxgmii3>;
+ phy-mode = "usxgmii";
+ managed = "in-band-status";
};
};
+
+&mscc_felix {
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds-65bb.dts b/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds-65bb.dts
index 8ffb707a1576..40d34c8384a5 100644
--- a/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds-65bb.dts
+++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds-65bb.dts
@@ -11,98 +11,76 @@
/dts-v1/;
/plugin/;
-/ {
- fragment@0 {
- target = <&mdio_slot1>;
-
- __overlay__ {
- #address-cells = <1>;
- #size-cells = <0>;
-
- slot1_sgmii: ethernet-phy@2 {
- /* AQR112 */
- reg = <0x2>;
- compatible = "ethernet-phy-ieee802.3-c45";
- };
- };
- };
-
- fragment@1 {
- target = <&enetc_port0>;
-
- __overlay__ {
- phy-handle = <&slot1_sgmii>;
- phy-mode = "2500base-x";
- managed = "in-band-status";
- status = "okay";
- };
+&mdio_slot1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ slot1_sgmii: ethernet-phy@2 {
+ /* AQR112 */
+ reg = <0x2>;
+ compatible = "ethernet-phy-ieee802.3-c45";
};
+};
- fragment@2 {
- target = <&mdio_slot2>;
-
- __overlay__ {
- #address-cells = <1>;
- #size-cells = <0>;
-
- /* 4 ports on VSC8514 */
- slot2_qsgmii0: ethernet-phy@8 {
- reg = <0x8>;
- };
-
- slot2_qsgmii1: ethernet-phy@9 {
- reg = <0x9>;
- };
+&enetc_port0 {
+ phy-handle = <&slot1_sgmii>;
+ phy-mode = "2500base-x";
+ managed = "in-band-status";
+ status = "okay";
+};
- slot2_qsgmii2: ethernet-phy@a {
- reg = <0xa>;
- };
+&mdio_slot2 {
+ #address-cells = <1>;
+ #size-cells = <0>;
- slot2_qsgmii3: ethernet-phy@b {
- reg = <0xb>;
- };
- };
+ /* 4 ports on VSC8514 */
+ slot2_qsgmii0: ethernet-phy@8 {
+ reg = <0x8>;
};
- fragment@3 {
- target = <&mscc_felix_ports>;
+ slot2_qsgmii1: ethernet-phy@9 {
+ reg = <0x9>;
+ };
- __overlay__ {
- port@0 {
- status = "okay";
- phy-handle = <&slot2_qsgmii0>;
- phy-mode = "qsgmii";
- managed = "in-band-status";
- };
+ slot2_qsgmii2: ethernet-phy@a {
+ reg = <0xa>;
+ };
- port@1 {
- status = "okay";
- phy-handle = <&slot2_qsgmii1>;
- phy-mode = "qsgmii";
- managed = "in-band-status";
- };
+ slot2_qsgmii3: ethernet-phy@b {
+ reg = <0xb>;
+ };
+};
- port@2 {
- status = "okay";
- phy-handle = <&slot2_qsgmii2>;
- phy-mode = "qsgmii";
- managed = "in-band-status";
- };
+&mscc_felix_ports {
+ port@0 {
+ status = "okay";
+ phy-handle = <&slot2_qsgmii0>;
+ phy-mode = "qsgmii";
+ managed = "in-band-status";
+ };
- port@3 {
- status = "okay";
- phy-handle = <&slot2_qsgmii3>;
- phy-mode = "qsgmii";
- managed = "in-band-status";
- };
- };
+ port@1 {
+ status = "okay";
+ phy-handle = <&slot2_qsgmii1>;
+ phy-mode = "qsgmii";
+ managed = "in-band-status";
};
- fragment@4 {
- target = <&mscc_felix>;
+ port@2 {
+ status = "okay";
+ phy-handle = <&slot2_qsgmii2>;
+ phy-mode = "qsgmii";
+ managed = "in-band-status";
+ };
- __overlay__ {
- status = "okay";
- };
+ port@3 {
+ status = "okay";
+ phy-handle = <&slot2_qsgmii3>;
+ phy-mode = "qsgmii";
+ managed = "in-band-status";
};
};
+
+&mscc_felix {
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds-7777.dts b/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds-7777.dts
index eb6a1e674f10..1dff68d7484b 100644
--- a/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds-7777.dts
+++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds-7777.dts
@@ -12,71 +12,58 @@
/dts-v1/;
/plugin/;
-/ {
- fragment@0 {
- target = <&mdio_slot1>;
+&mdio_slot1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
- __overlay__ {
- #address-cells = <1>;
- #size-cells = <0>;
-
- /* 4 ports on AQR412 */
- slot1_sxgmii0: ethernet-phy@0 {
- reg = <0x0>;
- compatible = "ethernet-phy-ieee802.3-c45";
- };
-
- slot1_sxgmii1: ethernet-phy@1 {
- reg = <0x1>;
- compatible = "ethernet-phy-ieee802.3-c45";
- };
-
- slot1_sxgmii2: ethernet-phy@2 {
- reg = <0x2>;
- compatible = "ethernet-phy-ieee802.3-c45";
- };
+ /* 4 ports on AQR412 */
+ slot1_sxgmii0: ethernet-phy@0 {
+ reg = <0x0>;
+ compatible = "ethernet-phy-ieee802.3-c45";
+ };
- slot1_sxgmii3: ethernet-phy@3 {
- reg = <0x3>;
- compatible = "ethernet-phy-ieee802.3-c45";
- };
- };
+ slot1_sxgmii1: ethernet-phy@1 {
+ reg = <0x1>;
+ compatible = "ethernet-phy-ieee802.3-c45";
};
- fragment@1 {
- target = <&mscc_felix_ports>;
+ slot1_sxgmii2: ethernet-phy@2 {
+ reg = <0x2>;
+ compatible = "ethernet-phy-ieee802.3-c45";
+ };
- __overlay__ {
- port@0 {
- status = "okay";
- phy-handle = <&slot1_sxgmii0>;
- phy-mode = "2500base-x";
- };
+ slot1_sxgmii3: ethernet-phy@3 {
+ reg = <0x3>;
+ compatible = "ethernet-phy-ieee802.3-c45";
+ };
+};
- port@1 {
- status = "okay";
- phy-handle = <&slot1_sxgmii1>;
- phy-mode = "2500base-x";
- };
+&mscc_felix_ports {
+ port@0 {
+ status = "okay";
+ phy-handle = <&slot1_sxgmii0>;
+ phy-mode = "2500base-x";
+ };
- port@2 {
- status = "okay";
- phy-handle = <&slot1_sxgmii2>;
- phy-mode = "2500base-x";
- };
+ port@1 {
+ status = "okay";
+ phy-handle = <&slot1_sxgmii1>;
+ phy-mode = "2500base-x";
+ };
- port@3 {
- status = "okay";
- phy-handle = <&slot1_sxgmii3>;
- phy-mode = "2500base-x";
- };
- };
+ port@2 {
+ status = "okay";
+ phy-handle = <&slot1_sxgmii2>;
+ phy-mode = "2500base-x";
};
- fragment@2 {
- target = <&mscc_felix>;
- __overlay__ {
- status = "okay";
- };
+ port@3 {
+ status = "okay";
+ phy-handle = <&slot1_sxgmii3>;
+ phy-mode = "2500base-x";
};
};
+
+&mscc_felix {
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds-85bb.dts b/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds-85bb.dts
index 8e90c3088ba1..19424d349713 100644
--- a/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds-85bb.dts
+++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds-85bb.dts
@@ -11,97 +11,75 @@
/dts-v1/;
/plugin/;
-/ {
- fragment@0 {
- target = <&mdio_slot1>;
+&mdio_slot1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
- __overlay__ {
- #address-cells = <1>;
- #size-cells = <0>;
-
- slot1_sgmii: ethernet-phy@1c {
- /* 1st port on VSC8234 */
- reg = <0x1c>;
- };
- };
+ slot1_sgmii: ethernet-phy@1c {
+ /* 1st port on VSC8234 */
+ reg = <0x1c>;
};
+};
- fragment@1 {
- target = <&enetc_port0>;
-
- __overlay__ {
- phy-handle = <&slot1_sgmii>;
- phy-mode = "sgmii";
- managed = "in-band-status";
- status = "okay";
- };
- };
-
- fragment@2 {
- target = <&mdio_slot2>;
-
- __overlay__ {
- #address-cells = <1>;
- #size-cells = <0>;
-
- /* 4 ports on VSC8514 */
- slot2_qsgmii0: ethernet-phy@8 {
- reg = <0x8>;
- };
-
- slot2_qsgmii1: ethernet-phy@9 {
- reg = <0x9>;
- };
+&enetc_port0 {
+ phy-handle = <&slot1_sgmii>;
+ phy-mode = "sgmii";
+ managed = "in-band-status";
+ status = "okay";
+};
- slot2_qsgmii2: ethernet-phy@a {
- reg = <0xa>;
- };
+&mdio_slot2 {
+ #address-cells = <1>;
+ #size-cells = <0>;
- slot2_qsgmii3: ethernet-phy@b {
- reg = <0xb>;
- };
- };
+ /* 4 ports on VSC8514 */
+ slot2_qsgmii0: ethernet-phy@8 {
+ reg = <0x8>;
};
- fragment@3 {
- target = <&mscc_felix_ports>;
+ slot2_qsgmii1: ethernet-phy@9 {
+ reg = <0x9>;
+ };
- __overlay__ {
- port@0 {
- status = "okay";
- phy-handle = <&slot2_qsgmii0>;
- phy-mode = "qsgmii";
- managed = "in-band-status";
- };
+ slot2_qsgmii2: ethernet-phy@a {
+ reg = <0xa>;
+ };
- port@1 {
- status = "okay";
- phy-handle = <&slot2_qsgmii1>;
- phy-mode = "qsgmii";
- managed = "in-band-status";
- };
+ slot2_qsgmii3: ethernet-phy@b {
+ reg = <0xb>;
+ };
+};
- port@2 {
- status = "okay";
- phy-handle = <&slot2_qsgmii2>;
- phy-mode = "qsgmii";
- managed = "in-band-status";
- };
+&mscc_felix_ports {
+ port@0 {
+ status = "okay";
+ phy-handle = <&slot2_qsgmii0>;
+ phy-mode = "qsgmii";
+ managed = "in-band-status";
+ };
- port@3 {
- status = "okay";
- phy-handle = <&slot2_qsgmii3>;
- phy-mode = "qsgmii";
- managed = "in-band-status";
- };
- };
+ port@1 {
+ status = "okay";
+ phy-handle = <&slot2_qsgmii1>;
+ phy-mode = "qsgmii";
+ managed = "in-band-status";
};
- fragment@4 {
- target = <&mscc_felix>;
+ port@2 {
+ status = "okay";
+ phy-handle = <&slot2_qsgmii2>;
+ phy-mode = "qsgmii";
+ managed = "in-band-status";
+ };
- __overlay__ {
- status = "okay";
- };
+ port@3 {
+ status = "okay";
+ phy-handle = <&slot2_qsgmii3>;
+ phy-mode = "qsgmii";
+ managed = "in-band-status";
};
};
+
+&mscc_felix {
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds-899b.dts b/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds-899b.dts
index 5d0a094e6c44..fb85847f778f 100644
--- a/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds-899b.dts
+++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds-899b.dts
@@ -11,65 +11,51 @@
/dts-v1/;
/plugin/;
-/ {
- fragment@0 {
- target = <&mdio_slot1>;
- __overlay__ {
- #address-cells = <1>;
- #size-cells = <0>;
+&mdio_slot1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
- /* VSC8234 */
- slot1_sgmii0: ethernet-phy@1c {
- reg = <0x1c>;
- };
-
- slot1_sgmii1: ethernet-phy@1d {
- reg = <0x1d>;
- };
+ /* VSC8234 */
+ slot1_sgmii0: ethernet-phy@1c {
+ reg = <0x1c>;
+ };
- slot1_sgmii2: ethernet-phy@1e {
- reg = <0x1e>;
- };
+ slot1_sgmii1: ethernet-phy@1d {
+ reg = <0x1d>;
+ };
- slot1_sgmii3: ethernet-phy@1f {
- reg = <0x1f>;
- };
- };
+ slot1_sgmii2: ethernet-phy@1e {
+ reg = <0x1e>;
};
- fragment@1 {
- target = <&enetc_port0>;
- __overlay__ {
- phy-handle = <&slot1_sgmii0>;
- phy-mode = "sgmii";
- managed = "in-band-status";
- status = "okay";
- };
+ slot1_sgmii3: ethernet-phy@1f {
+ reg = <0x1f>;
};
+};
- fragment@2 {
- target = <&mscc_felix_ports>;
- __overlay__ {
- port@1 {
- status = "okay";
- phy-handle = <&slot1_sgmii1>;
- phy-mode = "sgmii";
- managed = "in-band-status";
- };
+&enetc_port0 {
+ phy-handle = <&slot1_sgmii0>;
+ phy-mode = "sgmii";
+ managed = "in-band-status";
+ status = "okay";
+};
- port@2 {
- status = "okay";
- phy-handle = <&slot1_sgmii2>;
- phy-mode = "sgmii";
- managed = "in-band-status";
- };
- };
+&mscc_felix_ports {
+ port@1 {
+ status = "okay";
+ phy-handle = <&slot1_sgmii1>;
+ phy-mode = "sgmii";
+ managed = "in-band-status";
};
- fragment@3 {
- target = <&mscc_felix>;
- __overlay__ {
- status = "okay";
- };
+ port@2 {
+ status = "okay";
+ phy-handle = <&slot1_sgmii2>;
+ phy-mode = "sgmii";
+ managed = "in-band-status";
};
};
+
+&mscc_felix {
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds-9999.dts b/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds-9999.dts
index 1ef743c48e84..63e46fad22bd 100644
--- a/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds-9999.dts
+++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds-9999.dts
@@ -11,69 +11,58 @@
/dts-v1/;
/plugin/;
-/ {
- fragment@0 {
- target = <&mdio_slot1>;
- __overlay__ {
- #address-cells = <1>;
- #size-cells = <0>;
+&mdio_slot1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
- /* VSC8234 */
- slot1_sgmii0: ethernet-phy@1c {
- reg = <0x1c>;
- };
-
- slot1_sgmii1: ethernet-phy@1d {
- reg = <0x1d>;
- };
+ /* VSC8234 */
+ slot1_sgmii0: ethernet-phy@1c {
+ reg = <0x1c>;
+ };
- slot1_sgmii2: ethernet-phy@1e {
- reg = <0x1e>;
- };
+ slot1_sgmii1: ethernet-phy@1d {
+ reg = <0x1d>;
+ };
- slot1_sgmii3: ethernet-phy@1f {
- reg = <0x1f>;
- };
- };
+ slot1_sgmii2: ethernet-phy@1e {
+ reg = <0x1e>;
};
- fragment@1 {
- target = <&mscc_felix_ports>;
- __overlay__ {
- port@0 {
- status = "okay";
- phy-handle = <&slot1_sgmii0>;
- phy-mode = "sgmii";
- managed = "in-band-status";
- };
+ slot1_sgmii3: ethernet-phy@1f {
+ reg = <0x1f>;
+ };
+};
- port@1 {
- status = "okay";
- phy-handle = <&slot1_sgmii1>;
- phy-mode = "sgmii";
- managed = "in-band-status";
- };
+&mscc_felix_ports {
+ port@0 {
+ status = "okay";
+ phy-handle = <&slot1_sgmii0>;
+ phy-mode = "sgmii";
+ managed = "in-band-status";
+ };
- port@2 {
- status = "okay";
- phy-handle = <&slot1_sgmii2>;
- phy-mode = "sgmii";
- managed = "in-band-status";
- };
+ port@1 {
+ status = "okay";
+ phy-handle = <&slot1_sgmii1>;
+ phy-mode = "sgmii";
+ managed = "in-band-status";
+ };
- port@3 {
- status = "okay";
- phy-handle = <&slot1_sgmii3>;
- phy-mode = "sgmii";
- managed = "in-band-status";
- };
- };
+ port@2 {
+ status = "okay";
+ phy-handle = <&slot1_sgmii2>;
+ phy-mode = "sgmii";
+ managed = "in-band-status";
};
- fragment@2 {
- target = <&mscc_felix>;
- __overlay__ {
- status = "okay";
- };
+ port@3 {
+ status = "okay";
+ phy-handle = <&slot1_sgmii3>;
+ phy-mode = "sgmii";
+ managed = "in-band-status";
};
};
+
+&mscc_felix {
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds.dts b/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds.dts
index 177bc1405f0f..19d3952dbffe 100644
--- a/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds.dts
+++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds.dts
@@ -107,6 +107,30 @@
reg = <5>;
};
};
+
+ mdio_slot1: mdio@4 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <4>;
+ };
+
+ mdio_slot2: mdio@5 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <5>;
+ };
+
+ mdio_slot3: mdio@6 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <6>;
+ };
+
+ mdio_slot4: mdio@7 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <7>;
+ };
};
};
diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi
index 5bb8c26e0825..088271d49139 100644
--- a/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi
+++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi
@@ -224,6 +224,17 @@
little-endian;
};
+ efuse@1e80000 {
+ compatible = "fsl,ls1028a-sfp";
+ reg = <0x0 0x1e80000 0x0 0x10000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ ls1028a_uid: unique-id@1c {
+ reg = <0x1c 0x8>;
+ };
+ };
+
scfg: syscon@1fc0000 {
compatible = "fsl,ls1028a-scfg", "syscon";
reg = <0x0 0x1fc0000 0x0 0x10000>;
diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi
index 3ed1f2c51cad..18e529118476 100644
--- a/arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi
+++ b/arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi
@@ -253,18 +253,18 @@
interrupt-controller;
reg = <0x14 4>;
interrupt-map =
- <0 0 &gic 0 0 GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>,
- <1 0 &gic 0 0 GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>,
- <2 0 &gic 0 0 GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>,
- <3 0 &gic 0 0 GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>,
- <4 0 &gic 0 0 GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>,
- <5 0 &gic 0 0 GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>,
- <6 0 &gic 0 0 GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>,
- <7 0 &gic 0 0 GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>,
- <8 0 &gic 0 0 GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>,
- <9 0 &gic 0 0 GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>,
- <10 0 &gic 0 0 GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>,
- <11 0 &gic 0 0 GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>;
+ <0 0 &gic GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>,
+ <1 0 &gic GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>,
+ <2 0 &gic GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>,
+ <3 0 &gic GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>,
+ <4 0 &gic GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>,
+ <5 0 &gic GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>,
+ <6 0 &gic GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>,
+ <7 0 &gic GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>,
+ <8 0 &gic GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>,
+ <9 0 &gic GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>,
+ <10 0 &gic GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>,
+ <11 0 &gic GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>;
interrupt-map-mask = <0xffffffff 0x0>;
};
};
diff --git a/arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi
index 3cb9c21d2775..1282b61da8a5 100644
--- a/arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi
+++ b/arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi
@@ -293,18 +293,18 @@
interrupt-controller;
reg = <0x14 4>;
interrupt-map =
- <0 0 &gic 0 0 GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>,
- <1 0 &gic 0 0 GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>,
- <2 0 &gic 0 0 GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>,
- <3 0 &gic 0 0 GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>,
- <4 0 &gic 0 0 GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>,
- <5 0 &gic 0 0 GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>,
- <6 0 &gic 0 0 GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>,
- <7 0 &gic 0 0 GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>,
- <8 0 &gic 0 0 GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>,
- <9 0 &gic 0 0 GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>,
- <10 0 &gic 0 0 GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>,
- <11 0 &gic 0 0 GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>;
+ <0 0 &gic GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>,
+ <1 0 &gic GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>,
+ <2 0 &gic GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>,
+ <3 0 &gic GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>,
+ <4 0 &gic GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>,
+ <5 0 &gic GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>,
+ <6 0 &gic GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>,
+ <7 0 &gic GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>,
+ <8 0 &gic GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>,
+ <9 0 &gic GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>,
+ <10 0 &gic GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>,
+ <11 0 &gic GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>;
interrupt-map-mask = <0xffffffff 0x0>;
};
};
diff --git a/arch/arm64/boot/dts/freescale/fsl-lx2160a-clearfog-itx.dtsi b/arch/arm64/boot/dts/freescale/fsl-lx2160a-clearfog-itx.dtsi
index 17f8e733972a..41702e7386e3 100644
--- a/arch/arm64/boot/dts/freescale/fsl-lx2160a-clearfog-itx.dtsi
+++ b/arch/arm64/boot/dts/freescale/fsl-lx2160a-clearfog-itx.dtsi
@@ -63,21 +63,25 @@
&dpmac7 {
sfp = <&sfp0>;
managed = "in-band-status";
+ phys = <&serdes_1 3>;
};
&dpmac8 {
sfp = <&sfp1>;
managed = "in-band-status";
+ phys = <&serdes_1 2>;
};
&dpmac9 {
sfp = <&sfp2>;
managed = "in-band-status";
+ phys = <&serdes_1 1>;
};
&dpmac10 {
sfp = <&sfp3>;
managed = "in-band-status";
+ phys = <&serdes_1 0>;
};
&emdio2 {
diff --git a/arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi b/arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi
index 7032505f5ef3..c5daa15b020d 100644
--- a/arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi
+++ b/arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi
@@ -612,6 +612,12 @@
ranges;
dma-ranges = <0x0 0x0 0x0 0x0 0x10000 0x00000000>;
+ serdes_1: phy@1ea0000 {
+ compatible = "fsl,lynx-28g";
+ reg = <0x0 0x1ea0000 0x0 0x1e30>;
+ #phy-cells = <1>;
+ };
+
crypto: crypto@8000000 {
compatible = "fsl,sec-v5.0", "fsl,sec-v4.0";
fsl,sec-era = <10>;
@@ -680,18 +686,18 @@
interrupt-controller;
reg = <0x14 4>;
interrupt-map =
- <0 0 &gic 0 0 GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>,
- <1 0 &gic 0 0 GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>,
- <2 0 &gic 0 0 GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>,
- <3 0 &gic 0 0 GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>,
- <4 0 &gic 0 0 GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>,
- <5 0 &gic 0 0 GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>,
- <6 0 &gic 0 0 GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>,
- <7 0 &gic 0 0 GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>,
- <8 0 &gic 0 0 GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>,
- <9 0 &gic 0 0 GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>,
- <10 0 &gic 0 0 GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>,
- <11 0 &gic 0 0 GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>;
+ <0 0 &gic GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>,
+ <1 0 &gic GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>,
+ <2 0 &gic GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>,
+ <3 0 &gic GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>,
+ <4 0 &gic GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>,
+ <5 0 &gic GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>,
+ <6 0 &gic GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>,
+ <7 0 &gic GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>,
+ <8 0 &gic GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>,
+ <9 0 &gic GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>,
+ <10 0 &gic GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>,
+ <11 0 &gic GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>;
interrupt-map-mask = <0xffffffff 0x0>;
};
};
diff --git a/arch/arm64/boot/dts/freescale/imx8-ss-lsio.dtsi b/arch/arm64/boot/dts/freescale/imx8-ss-lsio.dtsi
index ee4e585a9c39..6446e6df7a9a 100644
--- a/arch/arm64/boot/dts/freescale/imx8-ss-lsio.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8-ss-lsio.dtsi
@@ -141,6 +141,22 @@ lsio_subsys: bus@5d000000 {
status = "disabled";
};
+ lsio_mu5: mailbox@5d200000 {
+ reg = <0x5d200000 0x10000>;
+ interrupts = <GIC_SPI 184 IRQ_TYPE_LEVEL_HIGH>;
+ #mbox-cells = <2>;
+ power-domains = <&pd IMX_SC_R_MU_5A>;
+ status = "disabled";
+ };
+
+ lsio_mu6: mailbox@5d210000 {
+ reg = <0x5d210000 0x10000>;
+ interrupts = <GIC_SPI 185 IRQ_TYPE_LEVEL_HIGH>;
+ #mbox-cells = <2>;
+ power-domains = <&pd IMX_SC_R_MU_6A>;
+ status = "disabled";
+ };
+
lsio_mu13: mailbox@5d280000 {
reg = <0x5d280000 0x10000>;
interrupts = <GIC_SPI 192 IRQ_TYPE_LEVEL_HIGH>;
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-beacon-baseboard.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-beacon-baseboard.dtsi
index 0da311898e01..ec3f2c177035 100644
--- a/arch/arm64/boot/dts/freescale/imx8mm-beacon-baseboard.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mm-beacon-baseboard.dtsi
@@ -3,6 +3,8 @@
* Copyright 2020 Compass Electronics Group, LLC
*/
+#include <dt-bindings/phy/phy-imx8-pcie.h>
+
/ {
leds {
compatible = "gpio-leds";
@@ -34,6 +36,19 @@
};
};
+ pcie0_refclk: pcie0-refclk {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <100000000>;
+ };
+
+ pcie0_refclk_gated: pcie0-refclk-gated {
+ compatible = "gpio-gate-clock";
+ clocks = <&pcie0_refclk>;
+ #clock-cells = <0>;
+ enable-gpios = <&pca6416_1 2 GPIO_ACTIVE_LOW>;
+ };
+
reg_audio: regulator-audio {
compatible = "regulator-fixed";
regulator-name = "3v3_aud";
@@ -64,6 +79,16 @@
startup-delay-us = <100000>;
};
+ reg_pcie0: regulator-pcie {
+ compatible = "regulator-fixed";
+ regulator-name = "pci_pwr_en";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ enable-active-high;
+ gpio = <&pca6416_1 1 GPIO_ACTIVE_HIGH>;
+ startup-delay-us = <100000>;
+ };
+
reg_usdhc2_vmmc: regulator-usdhc2 {
compatible = "regulator-fixed";
regulator-name = "VSD_3V3";
@@ -202,6 +227,32 @@
};
};
+&pcie_phy {
+ fsl,refclk-pad-mode = <IMX8_PCIE_REFCLK_PAD_INPUT>;
+ fsl,tx-deemph-gen1 = <0x2d>;
+ fsl,tx-deemph-gen2 = <0xf>;
+ fsl,clkreq-unsupported;
+ clocks = <&pcie0_refclk_gated>;
+ clock-names = "ref";
+ status = "okay";
+};
+
+&pcie0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pcie0>;
+ reset-gpio = <&gpio4 21 GPIO_ACTIVE_LOW>;
+ clocks = <&clk IMX8MM_CLK_PCIE1_ROOT>, <&clk IMX8MM_CLK_PCIE1_AUX>,
+ <&pcie0_refclk_gated>;
+ clock-names = "pcie", "pcie_aux", "pcie_bus";
+ assigned-clocks = <&clk IMX8MM_CLK_PCIE1_AUX>,
+ <&clk IMX8MM_CLK_PCIE1_CTRL>;
+ assigned-clock-rates = <10000000>, <250000000>;
+ assigned-clock-parents = <&clk IMX8MM_SYS_PLL2_50M>,
+ <&clk IMX8MM_SYS_PLL2_250M>;
+ vpcie-supply = <&reg_pcie0>;
+ status = "okay";
+};
+
&sai3 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_sai3>;
@@ -308,6 +359,12 @@
>;
};
+ pinctrl_pcie0: pcie0grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_SAI2_RXFS_GPIO4_IO21 0x41
+ >;
+ };
+
pinctrl_sai3: sai3grp {
fsl,pins = <
MX8MM_IOMUXC_SAI3_TXFS_SAI3_TX_SYNC 0xd6
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-emcon-avari.dts b/arch/arm64/boot/dts/freescale/imx8mm-emcon-avari.dts
new file mode 100644
index 000000000000..b2e8967e9687
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8mm-emcon-avari.dts
@@ -0,0 +1,23 @@
+// SPDX-License-Identifier: (GPL-2.0 or MIT)
+//
+// Copyright (c) 2021 emtrion GmbH
+// Author: Frank Erdrich <frank.erdrich@emtrion.com>
+//
+
+/dts-v1/;
+
+#include "imx8mm-emcon.dtsi"
+#include "imx8mm-emcon-avari.dtsi"
+
+/ {
+ model = "emtrion SoM emCON-MX8M mini on Avari";
+ compatible = "emtrion,emcon-mx8mm-avari", "fsl,imx8mm";
+};
+
+&lvds_backlight {
+ status = "okay";
+};
+
+&pwm1 {
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-emcon-avari.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-emcon-avari.dtsi
new file mode 100644
index 000000000000..5028f232b6bd
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8mm-emcon-avari.dtsi
@@ -0,0 +1,139 @@
+// SPDX-License-Identifier: (GPL-2.0 or MIT)
+//
+// Copyright (C) 2021 emtrion GmbH
+// Author: Frank Erdrich <frank.erdrich@emtrion.com>
+//
+
+/ {
+ aliases {
+ boardid = &boardID;
+ mmc0 = &usdhc1;
+ mmc1 = &usdhc2;
+ };
+
+ chosen {
+ stdout-path = &uart1;
+ };
+
+ reg_wall_5p0: regulator-wall5p0 {
+ compatible = "regulator-fixed";
+ regulator-name = "Main-Supply";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ reg_base3p3: regulator-base3p3 {
+ compatible = "regulator-fixed";
+ vin-supply = <&reg_wall_5p0>;
+ regulator-name = "3V3-avari";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ reg_base1p5: regulator-base1p5 {
+ compatible = "regulator-fixed";
+ vin-supply = <&reg_base3p3>;
+ regulator-name = "1V5-avari";
+ regulator-min-microvolt = <1500000>;
+ regulator-max-microvolt = <1500000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ reg_usb_otg: regulator-otgvbus {
+ compatible = "regulator-fixed";
+ vin-supply = <&reg_wall_5p0>;
+ regulator-name = "OTG_VBUS";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ gpio = <&gpio1 8 GPIO_ACTIVE_LOW>;
+ regulator-always-on;
+ };
+
+ clk_codec: clock-codec {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <12000000>;
+ };
+
+ 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 = <&sai2>;
+ };
+
+ codec_dai: simple-audio-card,codec {
+ sound-dai = <&sgtl5000>;
+ };
+ };
+};
+
+&ecspi1 {
+ status = "okay";
+};
+
+&i2c2 {
+ status = "okay";
+};
+
+&i2c1 {
+ clock-frequency = <100000>;
+ status = "okay";
+
+ sgtl5000: audio-codec@a {
+ compatible = "fsl,sgtl5000";
+ reg = <0x0a>;
+ #sound-dai-cells = <0>;
+ clocks = <&clk_codec>;
+ VDDA-supply = <&reg_base3p3>;
+ VDDIO-supply = <&reg_base3p3>;
+ };
+
+ boardID: gpio@3a {
+ compatible = "nxp,pca8574";
+ reg = <0x3a>;
+ gpio-controller;
+ #gpio-cells = <1>;
+ };
+};
+
+&sai2 {
+ status = "okay";
+};
+
+&uart2 {
+ uart-has-rtscts;
+ status = "okay";
+};
+
+&uart3 {
+ status = "okay";
+};
+
+&uart4 {
+ status = "okay";
+};
+
+&usbotg1 {
+ status = "okay";
+};
+
+&usbotg2 {
+ dr_mode = "host";
+ status = "disabled";
+};
+
+&usdhc2 {
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-emcon.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-emcon.dtsi
new file mode 100644
index 000000000000..7c4af71baab9
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8mm-emcon.dtsi
@@ -0,0 +1,627 @@
+// SPDX-License-Identifier: (GPL-2.0 or MIT)
+//
+// Copyright 2018 NXP
+// Copyright (C) 2021 emtrion GmbH
+//
+
+/dts-v1/;
+
+#include "imx8mm.dtsi"
+
+/ {
+ chosen {
+ stdout-path = &uart1;
+ };
+
+ som_leds: leds {
+ compatible = "gpio-leds";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpio_led>;
+
+ green {
+ label = "som:green";
+ gpios = <&gpio3 4 GPIO_ACTIVE_HIGH>;
+ default-state = "on";
+ linux,default-trigger = "heartbeat";
+ };
+
+ red {
+ label = "som:red";
+ gpios = <&gpio5 10 GPIO_ACTIVE_HIGH>;
+ default-state = "off";
+ };
+ };
+
+ lvds_backlight: lvds-backlight {
+ compatible = "pwm-backlight";
+ enable-gpios = <&gpio3 23 GPIO_ACTIVE_HIGH>;
+ pwms = <&pwm1 0 50000 0>;
+ brightness-levels = <
+ 0 4 8 16 32 64 80 96 112
+ 128 144 160 176 250
+ >;
+ default-brightness-level = <9>;
+ status = "disabled";
+ };
+
+ reg_usdhc1_vmmc: regulator-emmc {
+ compatible = "regulator-fixed";
+ regulator-name = "eMMC";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ reg_usdhc2_vmmc: regulator-usdhc2 {
+ compatible = "regulator-fixed";
+ regulator-name = "sdcard_3V3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+};
+
+&A53_0 {
+ cpu-supply = <&buck2_reg>;
+};
+
+&ecspi1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_ecspi1 &pinctrl_ecspi1_cs>;
+ cs-gpios = <&gpio5 9 GPIO_ACTIVE_LOW>,
+ <&gpio5 13 GPIO_ACTIVE_LOW>;
+ status = "okay";
+};
+
+&fec1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_fec1>;
+ phy-mode = "rgmii-id";
+ phy-handle = <&ethphy0>;
+ fsl,magic-packet;
+ status = "okay";
+
+ mdio {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ ethphy0: ethernet-phy@0 {
+ compatible = "ethernet-phy-ieee802.3-c22";
+ reg = <0>;
+ reset-gpios = <&gpio1 9 GPIO_ACTIVE_LOW>;
+ reset-assert-us = <10000>;
+ };
+ };
+};
+
+&flexspi {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_flexspi0>;
+ pinctrl-1 = <&pinctrl_flexspi1>;
+ status = "okay";
+
+ flash0: spi-flash@0 {
+ reg = <0>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "jedec,spi-nor";
+ spi-max-frequency = <40000000>;
+ };
+};
+
+&iomuxc {
+ pinctrl-names = "default";
+
+ pinctrl_csi_pwn: csi-pwn-grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_GPIO1_IO07_GPIO1_IO7 0x19
+ >;
+ };
+
+ pinctrl_ecspi1: ecspi1-grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_ECSPI1_SCLK_ECSPI1_SCLK 0x82
+ MX8MM_IOMUXC_ECSPI1_MOSI_ECSPI1_MOSI 0x82
+ MX8MM_IOMUXC_ECSPI1_MISO_ECSPI1_MISO 0x82
+ >;
+ };
+
+ pinctrl_ecspi1_cs: ecspi1-cs {
+ fsl,pins = <
+ MX8MM_IOMUXC_ECSPI1_SS0_GPIO5_IO9 0x40000
+ MX8MM_IOMUXC_ECSPI2_SS0_GPIO5_IO13 0x40000
+ >;
+ };
+
+ pinctrl_fec1: fec1-grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_ENET_MDC_ENET1_MDC 0x3
+ MX8MM_IOMUXC_ENET_MDIO_ENET1_MDIO 0x3
+ MX8MM_IOMUXC_ENET_TD3_ENET1_RGMII_TD3 0x1f
+ MX8MM_IOMUXC_ENET_TD2_ENET1_RGMII_TD2 0x1f
+ MX8MM_IOMUXC_ENET_TD1_ENET1_RGMII_TD1 0x1f
+ MX8MM_IOMUXC_ENET_TD0_ENET1_RGMII_TD0 0x1f
+ MX8MM_IOMUXC_ENET_RD3_ENET1_RGMII_RD3 0x91
+ MX8MM_IOMUXC_ENET_RD2_ENET1_RGMII_RD2 0x91
+ MX8MM_IOMUXC_ENET_RD1_ENET1_RGMII_RD1 0x91
+ MX8MM_IOMUXC_ENET_RD0_ENET1_RGMII_RD0 0x91
+ MX8MM_IOMUXC_ENET_TXC_ENET1_RGMII_TXC 0x1f
+ MX8MM_IOMUXC_ENET_RXC_ENET1_RGMII_RXC 0x91
+ MX8MM_IOMUXC_ENET_RX_CTL_ENET1_RGMII_RX_CTL 0x91
+ MX8MM_IOMUXC_ENET_TX_CTL_ENET1_RGMII_TX_CTL 0x1f
+ MX8MM_IOMUXC_GPIO1_IO09_GPIO1_IO9 0x19
+ >;
+ };
+
+ pinctrl_flexspi0: flexspi0-grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_NAND_ALE_QSPI_A_SCLK 0x1c2
+ MX8MM_IOMUXC_NAND_CE0_B_QSPI_A_SS0_B 0x82
+ MX8MM_IOMUXC_NAND_DATA00_QSPI_A_DATA0 0x82
+ MX8MM_IOMUXC_NAND_DATA01_QSPI_A_DATA1 0x82
+ MX8MM_IOMUXC_NAND_DATA02_QSPI_A_DATA2 0x82
+ MX8MM_IOMUXC_NAND_DATA03_QSPI_A_DATA3 0x82
+ MX8MM_IOMUXC_NAND_DQS_QSPI_A_DQS 0x82
+ >;
+ };
+
+ pinctrl_flexspi1: flexspi1-grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_NAND_CLE_QSPI_B_SCLK 0x1c2
+ MX8MM_IOMUXC_NAND_CE2_B_QSPI_B_SS0_B 0x82
+ MX8MM_IOMUXC_NAND_DATA04_QSPI_B_DATA0 0x82
+ MX8MM_IOMUXC_NAND_DATA05_QSPI_B_DATA1 0x82
+ MX8MM_IOMUXC_NAND_DATA06_QSPI_B_DATA2 0x82
+ MX8MM_IOMUXC_NAND_DATA07_QSPI_B_DATA3 0x82
+ >;
+ };
+
+ pinctrl_gpio_led: gpio-led-grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_ECSPI2_SCLK_GPIO5_IO10 0x19
+ MX8MM_IOMUXC_NAND_CE3_B_GPIO3_IO4 0x19
+ >;
+ };
+
+ pinctrl_i2c1: i2c1-grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_I2C1_SCL_I2C1_SCL 0x400001c3
+ MX8MM_IOMUXC_I2C1_SDA_I2C1_SDA 0x400001c3
+ >;
+ };
+
+ pinctrl_i2c2: i2c2grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_I2C2_SCL_I2C2_SCL 0x400001c3
+ MX8MM_IOMUXC_I2C2_SDA_I2C2_SDA 0x400001c3
+ >;
+ };
+
+ pinctrl_i2c3: i2c3-grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_I2C3_SCL_I2C3_SCL 0x400001c3
+ MX8MM_IOMUXC_I2C3_SDA_I2C3_SDA 0x400001c3
+ >;
+ };
+
+ pinctrl_lvds: lvds-grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_SAI5_MCLK_GPIO3_IO25 0x06
+ >;
+ };
+
+ pinctrl_pcie0: pcie0-grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_SAI5_RXC_GPIO3_IO20 0x41
+ MX8MM_IOMUXC_SAI5_RXFS_GPIO3_IO19 0x41
+ >;
+ };
+
+ pinctrl_pmic: pmic-irq {
+ fsl,pins = <
+ MX8MM_IOMUXC_NAND_CE1_B_GPIO3_IO2 0x41
+ >;
+ };
+
+ pinctrl_pwm1: pwm1-grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_GPIO1_IO01_PWM1_OUT 0x06
+ >;
+ };
+
+ pinctrl_sai2: sai2-grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_SAI2_MCLK_SAI2_MCLK 0xd6
+ MX8MM_IOMUXC_SAI2_RXC_SAI2_RX_BCLK 0xd6
+ MX8MM_IOMUXC_SAI2_RXD0_SAI2_RX_DATA0 0xd6
+ MX8MM_IOMUXC_SAI2_RXFS_SAI2_RX_SYNC 0xd6
+ MX8MM_IOMUXC_SAI2_TXC_SAI2_TX_BCLK 0xd6
+ MX8MM_IOMUXC_SAI2_TXD0_SAI2_TX_DATA0 0xd6
+ MX8MM_IOMUXC_SAI2_TXFS_SAI2_TX_SYNC 0xd6
+ >;
+ };
+
+ pinctrl_spdif1: spdif1-grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_SPDIF_TX_SPDIF1_OUT 0xd6
+ MX8MM_IOMUXC_SPDIF_RX_SPDIF1_IN 0xd6
+ >;
+ };
+
+ pinctrl_uart1: uart1-grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_UART1_RXD_UART1_DCE_RX 0x140
+ MX8MM_IOMUXC_UART1_TXD_UART1_DCE_TX 0x140
+ >;
+ };
+
+ pinctrl_uart2: uart2-grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_UART2_RXD_UART2_DCE_RX 0x140
+ MX8MM_IOMUXC_UART2_TXD_UART2_DCE_TX 0x140
+
+ /* rts and cts */
+ MX8MM_IOMUXC_SAI3_RXC_UART2_DCE_CTS_B 0x140
+ MX8MM_IOMUXC_SAI3_RXD_UART2_DCE_RTS_B 0x140
+ >;
+ };
+
+ pinctrl_uart3: uart3-grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_UART3_RXD_UART3_DCE_RX 0x140
+ MX8MM_IOMUXC_UART3_TXD_UART3_DCE_TX 0x140
+ >;
+ };
+
+ pinctrl_uart4: uart4-grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_UART4_RXD_UART4_DCE_RX 0x140
+ MX8MM_IOMUXC_UART4_TXD_UART4_DCE_TX 0x140
+ >;
+ };
+
+ pinctrl_usdhc1: usdhc1-grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_SD1_CLK_USDHC1_CLK 0x190
+ MX8MM_IOMUXC_SD1_CMD_USDHC1_CMD 0x1d0
+ MX8MM_IOMUXC_SD1_DATA0_USDHC1_DATA0 0x1d0
+ MX8MM_IOMUXC_SD1_DATA1_USDHC1_DATA1 0x1d0
+ MX8MM_IOMUXC_SD1_DATA2_USDHC1_DATA2 0x1d0
+ MX8MM_IOMUXC_SD1_DATA3_USDHC1_DATA3 0x1d0
+ MX8MM_IOMUXC_SD1_DATA4_USDHC1_DATA4 0x1d0
+ MX8MM_IOMUXC_SD1_DATA5_USDHC1_DATA5 0x1d0
+ MX8MM_IOMUXC_SD1_DATA6_USDHC1_DATA6 0x1d0
+ MX8MM_IOMUXC_SD1_DATA7_USDHC1_DATA7 0x1d0
+ >;
+ };
+
+ pinctrl_usdhc1_100mhz: usdhc1-100mhz-grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_SD1_CLK_USDHC1_CLK 0x194
+ MX8MM_IOMUXC_SD1_CMD_USDHC1_CMD 0x1d4
+ MX8MM_IOMUXC_SD1_DATA0_USDHC1_DATA0 0x1d4
+ MX8MM_IOMUXC_SD1_DATA1_USDHC1_DATA1 0x1d4
+ MX8MM_IOMUXC_SD1_DATA2_USDHC1_DATA2 0x1d4
+ MX8MM_IOMUXC_SD1_DATA3_USDHC1_DATA3 0x1d4
+ MX8MM_IOMUXC_SD1_DATA4_USDHC1_DATA4 0x1d4
+ MX8MM_IOMUXC_SD1_DATA5_USDHC1_DATA5 0x1d4
+ MX8MM_IOMUXC_SD1_DATA6_USDHC1_DATA6 0x1d4
+ MX8MM_IOMUXC_SD1_DATA7_USDHC1_DATA7 0x1d4
+ >;
+ };
+
+ pinctrl_usdhc1_200mhz: usdhc1-200mhz-grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_SD1_CLK_USDHC1_CLK 0x196
+ MX8MM_IOMUXC_SD1_CMD_USDHC1_CMD 0x1d6
+ MX8MM_IOMUXC_SD1_DATA0_USDHC1_DATA0 0x1d6
+ MX8MM_IOMUXC_SD1_DATA1_USDHC1_DATA1 0x1d6
+ MX8MM_IOMUXC_SD1_DATA2_USDHC1_DATA2 0x1d6
+ MX8MM_IOMUXC_SD1_DATA3_USDHC1_DATA3 0x1d6
+ MX8MM_IOMUXC_SD1_DATA4_USDHC1_DATA4 0x1d6
+ MX8MM_IOMUXC_SD1_DATA5_USDHC1_DATA5 0x1d6
+ MX8MM_IOMUXC_SD1_DATA6_USDHC1_DATA6 0x1d6
+ MX8MM_IOMUXC_SD1_DATA7_USDHC1_DATA7 0x1d6
+ >;
+ };
+
+ pinctrl_usdhc1_gpio: usdhc1-gpio-grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_SD1_RESET_B_USDHC1_RESET_B 0x41
+ MX8MM_IOMUXC_GPIO1_IO03_GPIO1_IO3 0x1c4
+ >;
+ };
+
+ pinctrl_usdhc2: usdhc2-grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_SD2_CLK_USDHC2_CLK 0x190
+ MX8MM_IOMUXC_SD2_CMD_USDHC2_CMD 0x1d0
+ MX8MM_IOMUXC_SD2_DATA0_USDHC2_DATA0 0x1d0
+ MX8MM_IOMUXC_SD2_DATA1_USDHC2_DATA1 0x1d0
+ MX8MM_IOMUXC_SD2_DATA2_USDHC2_DATA2 0x1d0
+ MX8MM_IOMUXC_SD2_DATA3_USDHC2_DATA3 0x1d0
+ MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0x1d0
+ >;
+ };
+
+ pinctrl_usdhc2_100mhz: usdhc2-100mhz-grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_SD2_CLK_USDHC2_CLK 0x194
+ MX8MM_IOMUXC_SD2_CMD_USDHC2_CMD 0x1d4
+ MX8MM_IOMUXC_SD2_DATA0_USDHC2_DATA0 0x1d4
+ MX8MM_IOMUXC_SD2_DATA1_USDHC2_DATA1 0x1d4
+ MX8MM_IOMUXC_SD2_DATA2_USDHC2_DATA2 0x1d4
+ MX8MM_IOMUXC_SD2_DATA3_USDHC2_DATA3 0x1d4
+ MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0x1d0
+ >;
+ };
+
+ pinctrl_usdhc2_200mhz: usdhc2-200mhz-grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_SD2_CLK_USDHC2_CLK 0x196
+ MX8MM_IOMUXC_SD2_CMD_USDHC2_CMD 0x1d6
+ MX8MM_IOMUXC_SD2_DATA0_USDHC2_DATA0 0x1d6
+ MX8MM_IOMUXC_SD2_DATA1_USDHC2_DATA1 0x1d6
+ MX8MM_IOMUXC_SD2_DATA2_USDHC2_DATA2 0x1d6
+ MX8MM_IOMUXC_SD2_DATA3_USDHC2_DATA3 0x1d6
+ MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0x1d0
+ >;
+ };
+
+ /* no reset for sdhc2 interface */
+ pinctrl_usdhc2_gpio: usdhc2-gpio-grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_SD2_CD_B_GPIO2_IO12 0x1c4
+ MX8MM_IOMUXC_SD2_WP_USDHC2_WP 0x1c4
+ >;
+ };
+
+ pinctrl_wdog: wdog-grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_GPIO1_IO02_WDOG1_WDOG_B 0xc6
+ >;
+ };
+};
+
+&i2c1 {
+ clock-frequency = <400000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c1>;
+ status = "okay";
+};
+
+&i2c2 {
+ clock-frequency = <400000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c2>;
+ status = "okay";
+};
+
+&i2c3 {
+ clock-frequency = <400000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c3>;
+ status = "okay";
+
+ bd71847: pmic@4b {
+ compatible = "rohm,bd71847";
+ reg = <0x4b>;
+ pinctrl-0 = <&pinctrl_pmic>;
+ interrupt-parent = <&gpio3>;
+ interrupts = <2 IRQ_TYPE_LEVEL_LOW>;
+ rohm,reset-snvs-powered;
+
+ regulators {
+ buck1_reg: BUCK1 {
+ regulator-name = "BUCK1";
+ regulator-min-microvolt = <700000>;
+ regulator-max-microvolt = <1300000>;
+ regulator-boot-on;
+ regulator-always-on;
+ regulator-ramp-delay = <1250>;
+ };
+
+ buck2_reg: BUCK2 {
+ regulator-name = "BUCK2";
+ regulator-min-microvolt = <700000>;
+ regulator-max-microvolt = <1300000>;
+ regulator-boot-on;
+ regulator-always-on;
+ regulator-ramp-delay = <1250>;
+ rohm,dvs-run-voltage = <1000000>;
+ rohm,dvs-idle-voltage = <900000>;
+ };
+
+ buck3_reg: BUCK3 {
+ // BUCK5 in datasheet
+ regulator-name = "BUCK3";
+ regulator-min-microvolt = <700000>;
+ regulator-max-microvolt = <1350000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ buck4_reg: BUCK4 {
+ // BUCK6 in datasheet
+ regulator-name = "BUCK4";
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ buck5_reg: BUCK5 {
+ // BUCK7 in datasheet
+ regulator-name = "BUCK5";
+ regulator-min-microvolt = <1605000>;
+ regulator-max-microvolt = <1995000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ buck6_reg: BUCK6 {
+ // BUCK8 in datasheet
+ regulator-name = "BUCK6";
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1400000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ ldo1_reg: LDO1 {
+ regulator-name = "LDO1";
+ regulator-min-microvolt = <1600000>;
+ regulator-max-microvolt = <1900000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ ldo2_reg: LDO2 {
+ regulator-name = "LDO2";
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <900000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ ldo3_reg: LDO3 {
+ regulator-name = "LDO3";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ ldo4_reg: LDO4 {
+ regulator-name = "LDO4";
+ regulator-min-microvolt = <900000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ ldo6_reg: LDO6 {
+ regulator-name = "LDO6";
+ regulator-min-microvolt = <900000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+ };
+ };
+
+ rv1805: rtc@69 {
+ compatible = "abracon,ab1805";
+ reg = <0x69>;
+ };
+};
+
+&mu {
+ status = "okay";
+};
+
+&pwm1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pwm1>;
+};
+
+&sai2 {
+ #sound-dai-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_sai2>;
+ assigned-clocks = <&clk IMX8MM_CLK_SAI2>;
+ assigned-clock-parents = <&clk IMX8MM_AUDIO_PLL1_OUT>;
+ assigned-clock-rates = <12000000>;
+ status = "disabled";
+};
+
+&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 = "disabled";
+};
+
+&uart1 { /* console */
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart1>;
+ assigned-clocks = <&clk IMX8MM_CLK_UART1>;
+ assigned-clock-parents = <&clk IMX8MM_SYS_PLL1_80M>;
+ status = "okay";
+};
+
+&uart2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart2>;
+ assigned-clocks = <&clk IMX8MM_CLK_UART2>;
+ assigned-clock-parents = <&clk IMX8MM_SYS_PLL1_80M>;
+ status = "okay";
+};
+
+&uart3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart3>;
+ assigned-clocks = <&clk IMX8MM_CLK_UART3>;
+ assigned-clock-parents = <&clk IMX8MM_SYS_PLL1_80M>;
+ status = "okay";
+};
+
+&uart4 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart4>;
+ assigned-clocks = <&clk IMX8MM_CLK_UART4>;
+ assigned-clock-parents = <&clk IMX8MM_SYS_PLL1_80M>;
+ status = "okay";
+};
+
+&usbotg1 {
+ dr_mode = "otg";
+ over-current-active-low;
+ status = "okay";
+};
+
+&usbotg2 {
+ dr_mode = "host";
+ disable-over-current;
+ status = "disabled";
+};
+
+&usdhc1 {
+ pinctrl-names = "default", "state_100mhz", "state_200mhz";
+ pinctrl-0 = <&pinctrl_usdhc1>, <&pinctrl_usdhc1_gpio>;
+ pinctrl-1 = <&pinctrl_usdhc1_100mhz>, <&pinctrl_usdhc1_gpio>;
+ pinctrl-2 = <&pinctrl_usdhc1_200mhz>, <&pinctrl_usdhc1_gpio>;
+ bus-width = <8>;
+ vmmc-supply = <&reg_usdhc1_vmmc>;
+ keep-power-in-suspend;
+ non-removable;
+ status = "okay";
+};
+
+&usdhc2 {
+ pinctrl-names = "default", "state_100mhz", "state_200mhz";
+ pinctrl-0 = <&pinctrl_usdhc2>, <&pinctrl_usdhc2_gpio>;
+ pinctrl-1 = <&pinctrl_usdhc2_100mhz>, <&pinctrl_usdhc2_gpio>;
+ pinctrl-2 = <&pinctrl_usdhc2_200mhz>, <&pinctrl_usdhc2_gpio>;
+ cd-gpios = <&gpio2 12 GPIO_ACTIVE_LOW>;
+ wp-gpios = <&gpio2 20 GPIO_ACTIVE_HIGH>;
+ bus-width = <4>;
+ vmmc-supply = <&reg_usdhc2_vmmc>;
+ no-1-8-v;
+ status = "okay";
+};
+
+&wdog1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_wdog>;
+ fsl,ext-reset-output;
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-evk.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-evk.dtsi
index 3bac87b7e142..6d67df7692f1 100644
--- a/arch/arm64/boot/dts/freescale/imx8mm-evk.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mm-evk.dtsi
@@ -5,6 +5,7 @@
/dts-v1/;
+#include <dt-bindings/phy/phy-imx8-pcie.h>
#include <dt-bindings/usb/pd.h>
#include "imx8mm.dtsi"
@@ -30,6 +31,23 @@
};
};
+ pcie0_refclk: pcie0-refclk {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <100000000>;
+ };
+
+ reg_pcie0: regulator-pcie {
+ compatible = "regulator-fixed";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pcie0_reg>;
+ regulator-name = "MPCIE_3V3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&gpio1 5 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+
reg_usdhc2_vmmc: regulator-usdhc2 {
compatible = "regulator-fixed";
pinctrl-names = "default";
@@ -296,6 +314,30 @@
};
};
+&pcie_phy {
+ fsl,refclk-pad-mode = <IMX8_PCIE_REFCLK_PAD_INPUT>;
+ fsl,tx-deemph-gen1 = <0x2d>;
+ fsl,tx-deemph-gen2 = <0xf>;
+ clocks = <&pcie0_refclk>;
+ status = "okay";
+};
+
+&pcie0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pcie0>;
+ reset-gpio = <&gpio4 21 GPIO_ACTIVE_LOW>;
+ clocks = <&clk IMX8MM_CLK_PCIE1_ROOT>, <&clk IMX8MM_CLK_PCIE1_AUX>,
+ <&pcie0_refclk>;
+ clock-names = "pcie", "pcie_aux", "pcie_bus";
+ assigned-clocks = <&clk IMX8MM_CLK_PCIE1_AUX>,
+ <&clk IMX8MM_CLK_PCIE1_CTRL>;
+ assigned-clock-rates = <10000000>, <250000000>;
+ assigned-clock-parents = <&clk IMX8MM_SYS_PLL2_50M>,
+ <&clk IMX8MM_SYS_PLL2_250M>;
+ vpcie-supply = <&reg_pcie0>;
+ status = "okay";
+};
+
&sai3 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_sai3>;
@@ -413,6 +455,19 @@
>;
};
+ pinctrl_pcie0: pcie0grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_I2C4_SCL_PCIE1_CLKREQ_B 0x61
+ MX8MM_IOMUXC_SAI2_RXFS_GPIO4_IO21 0x41
+ >;
+ };
+
+ pinctrl_pcie0_reg: pcie0reggrp {
+ fsl,pins = <
+ MX8MM_IOMUXC_GPIO1_IO05_GPIO1_IO5 0x41
+ >;
+ };
+
pinctrl_pmic: pmicirqgrp {
fsl,pins = <
MX8MM_IOMUXC_GPIO1_IO03_GPIO1_IO3 0x141
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-pinfunc.h b/arch/arm64/boot/dts/freescale/imx8mm-pinfunc.h
index a003e6af3353..83c8f715cd90 100644
--- a/arch/arm64/boot/dts/freescale/imx8mm-pinfunc.h
+++ b/arch/arm64/boot/dts/freescale/imx8mm-pinfunc.h
@@ -248,6 +248,7 @@
#define MX8MM_IOMUXC_NAND_RE_B_GPIO3_IO15 0x130 0x398 0x000 0x5 0x0
#define MX8MM_IOMUXC_NAND_RE_B_SIM_M_HADDR11 0x130 0x398 0x000 0x7 0x0
#define MX8MM_IOMUXC_NAND_READY_B_RAWNAND_READY_B 0x134 0x39C 0x000 0x0 0x0
+#define MX8MM_IOMUXC_NAND_READY_B_SD3_RESET_B 0x134 0x39C 0x000 0x2 0x0
#define MX8MM_IOMUXC_NAND_READY_B_GPIO3_IO16 0x134 0x39C 0x000 0x5 0x0
#define MX8MM_IOMUXC_NAND_READY_B_SIM_M_HADDR12 0x134 0x39C 0x000 0x7 0x0
#define MX8MM_IOMUXC_NAND_WE_B_RAWNAND_WE_B 0x138 0x3A0 0x000 0x0 0x0
@@ -279,7 +280,7 @@
#define MX8MM_IOMUXC_SAI5_RXD2_SAI1_TX_DATA4 0x150 0x3B8 0x000 0x1 0x0
#define MX8MM_IOMUXC_SAI5_RXD2_SAI1_TX_SYNC 0x150 0x3B8 0x4CC 0x2 0x1
#define MX8MM_IOMUXC_SAI5_RXD2_SAI5_TX_BCLK 0x150 0x3B8 0x4E8 0x3 0x0
-#define MX8MM_IOMUXC_SAI5_RXD2_PDM_DATA2 0x150 0x3B8 0x53c 0x4 0x0
+#define MX8MM_IOMUXC_SAI5_RXD2_PDM_DATA2 0x150 0x3B8 0x53C 0x4 0x0
#define MX8MM_IOMUXC_SAI5_RXD2_GPIO3_IO23 0x150 0x3B8 0x000 0x5 0x0
#define MX8MM_IOMUXC_SAI5_RXD3_SAI5_RX_DATA3 0x154 0x3BC 0x4E0 0x0 0x0
#define MX8MM_IOMUXC_SAI5_RXD3_SAI1_TX_DATA5 0x154 0x3BC 0x000 0x1 0x0
@@ -486,7 +487,7 @@
#define MX8MM_IOMUXC_SAI3_TXFS_SAI3_TX_SYNC 0x1D8 0x440 0x000 0x0 0x0
#define MX8MM_IOMUXC_SAI3_TXFS_GPT1_CAPTURE2 0x1D8 0x440 0x000 0x1 0x0
#define MX8MM_IOMUXC_SAI3_TXFS_SAI5_RX_DATA1 0x1D8 0x440 0x4D8 0x2 0x2
-#define MX8MM_IOMUXC_SAI3_TXFS_UART2_DCE_RX 0x1D8 0x440 0x4Fc 0x4 0x2
+#define MX8MM_IOMUXC_SAI3_TXFS_UART2_DCE_RX 0x1D8 0x440 0x4FC 0x4 0x2
#define MX8MM_IOMUXC_SAI3_TXFS_UART2_DTE_TX 0x1D8 0x440 0x000 0x4 0x0
#define MX8MM_IOMUXC_SAI3_TXFS_GPIO4_IO31 0x1D8 0x440 0x000 0x5 0x0
#define MX8MM_IOMUXC_SAI3_TXFS_TPSMP_HDATA1 0x1D8 0x440 0x000 0x7 0x0
@@ -494,7 +495,7 @@
#define MX8MM_IOMUXC_SAI3_TXC_GPT1_COMPARE2 0x1DC 0x444 0x000 0x1 0x0
#define MX8MM_IOMUXC_SAI3_TXC_SAI5_RX_DATA2 0x1DC 0x444 0x4DC 0x2 0x2
#define MX8MM_IOMUXC_SAI3_TXC_UART2_DCE_TX 0x1DC 0x444 0x000 0x4 0x0
-#define MX8MM_IOMUXC_SAI3_TXC_UART2_DTE_RX 0x1DC 0x444 0x4Fc 0x4 0x3
+#define MX8MM_IOMUXC_SAI3_TXC_UART2_DTE_RX 0x1DC 0x444 0x4FC 0x4 0x3
#define MX8MM_IOMUXC_SAI3_TXC_GPIO5_IO0 0x1DC 0x444 0x000 0x5 0x0
#define MX8MM_IOMUXC_SAI3_TXC_TPSMP_HDATA2 0x1DC 0x444 0x000 0x7 0x0
#define MX8MM_IOMUXC_SAI3_TXD_SAI3_TX_DATA0 0x1E0 0x448 0x000 0x0 0x0
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-prt8mm.dts b/arch/arm64/boot/dts/freescale/imx8mm-prt8mm.dts
new file mode 100644
index 000000000000..9fbbbb556c0b
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8mm-prt8mm.dts
@@ -0,0 +1,304 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright 2020 Protonic Holland
+ * Copyright 2019 NXP
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/usb/pd.h>
+#include "imx8mm.dtsi"
+
+/ {
+ model = "Protonic PRT8MM";
+ compatible = "prt,prt8mm", "fsl,imx8mm";
+
+ chosen {
+ stdout-path = &uart4;
+ };
+
+ memory@40000000 {
+ device_type = "memory";
+ reg = <0x0 0x40000000 0 0x40000000>;
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpio_leds>;
+
+ debug-led0 {
+ label = "DEBUG_LED0";
+ gpios = <&gpio3 0 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "heartbeat";
+ };
+
+ debug-led1 {
+ label = "DEBUG_LED1";
+ gpios = <&gpio3 1 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "cpu";
+ };
+ };
+
+ sound-ssm2518 {
+ compatible = "simple-audio-card";
+ simple-audio-card,name = "ssm2518-audio";
+ simple-audio-card,format = "i2s";
+ simple-audio-card,frame-master = <&cpudai>;
+ simple-audio-card,bitclock-master = <&cpudai>;
+
+ cpudai: simple-audio-card,cpu {
+ sound-dai = <&sai3>;
+ };
+
+ simple-audio-card,codec {
+ sound-dai = <&ssm2518>;
+ clocks = <&clk IMX8MM_CLK_SAI3_ROOT>;
+ };
+ };
+};
+
+&i2c1 {
+ clock-frequency = <400000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c1>;
+ status = "okay";
+
+ ssm2518: audio-codec@34 {
+ compatible = "adi,ssm2518";
+ reg = <0x34>;
+ #sound-dai-cells = <0>;
+ };
+};
+
+&i2c2 {
+ clock-frequency = <400000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c2>;
+ status = "okay";
+
+ regulator@60 {
+ compatible = "fcs,fan53555";
+ reg = <0x60>;
+ regulator-name = "0V9_CORE";
+ regulator-min-microvolt = <900000>;
+ regulator-max-microvolt = <980000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+};
+
+&i2c3 {
+ clock-frequency = <400000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c3>;
+ status = "okay";
+
+ rtc@51 {
+ compatible = "nxp,pcf85363";
+ reg = <0x51>;
+ };
+
+ touchscreeen@5d {
+ compatible = "goodix,gt911";
+ reg = <0x5d>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_touchscreen>;
+ interrupt-parent = <&gpio1>;
+ interrupts = <8 IRQ_TYPE_NONE>;
+ irq-gpios = <&gpio1 8 GPIO_ACTIVE_HIGH>;
+ reset-gpios = <&gpio1 9 GPIO_ACTIVE_HIGH>;
+ };
+
+ temp-sense@70 {
+ compatible = "ti,tmp103";
+ reg = <0x70>;
+ };
+};
+
+&sai3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_sai3>;
+ assigned-clocks = <&clk IMX8MM_CLK_SAI3>;
+ assigned-clock-parents = <&clk IMX8MM_AUDIO_PLL1_OUT>;
+ assigned-clock-rates = <12288000>;
+ fsl,sai-mclk-direction-output;
+ fsl,sai-asynchronous;
+ status = "okay";
+};
+
+&snvs_pwrkey {
+ status = "okay";
+};
+
+&uart4 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart4>;
+ status = "okay";
+};
+
+&usbotg1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usbotg1>;
+ dr_mode = "host";
+ disable-over-current;
+ power-active-high;
+ status = "okay";
+};
+
+&usdhc2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usdhc2>;
+ assigned-clocks = <&clk IMX8MM_CLK_USDHC2>;
+ assigned-clock-rates = <100000000>;
+ cd-gpios = <&gpio2 12 GPIO_ACTIVE_LOW>;
+ bus-width = <4>;
+ status = "okay";
+};
+
+&usdhc3 {
+ pinctrl-names = "default", "state_100mhz", "state_200mhz";
+ pinctrl-0 = <&pinctrl_usdhc3>;
+ pinctrl-1 = <&pinctrl_usdhc3_100mhz>;
+ pinctrl-2 = <&pinctrl_usdhc3_200mhz>;
+ assigned-clocks = <&clk IMX8MM_CLK_USDHC3_ROOT>;
+ assigned-clock-rates = <400000000>;
+ bus-width = <8>;
+ non-removable;
+ no-sdio;
+ no-sd;
+ status = "okay";
+};
+
+&wdog1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_wdog>;
+ fsl,ext-reset-output;
+ status = "okay";
+};
+
+&iomuxc {
+ pinctrl_gpio_leds: ledsgrp {
+ fsl,pins = <
+ MX8MM_IOMUXC_NAND_ALE_GPIO3_IO0 0x00
+ MX8MM_IOMUXC_NAND_CE0_B_GPIO3_IO1 0x00
+ >;
+ };
+
+ pinctrl_i2c1: i2c1grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_I2C1_SCL_I2C1_SCL 0x400000c3
+ MX8MM_IOMUXC_I2C1_SDA_I2C1_SDA 0x400000c3
+ >;
+ };
+
+ pinctrl_i2c2: i2c2grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_I2C2_SCL_I2C2_SCL 0x400000c3
+ MX8MM_IOMUXC_I2C2_SDA_I2C2_SDA 0x400000c3
+ >;
+ };
+
+ pinctrl_i2c3: i2c3grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_I2C3_SCL_I2C3_SCL 0x400000c3
+ MX8MM_IOMUXC_I2C3_SDA_I2C3_SDA 0x400000c3
+ >;
+ };
+
+ pinctrl_sai3: sai3grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_SAI3_TXFS_SAI3_TX_SYNC 0xd6
+ MX8MM_IOMUXC_SAI3_TXC_SAI3_TX_BCLK 0xd6
+ MX8MM_IOMUXC_SAI3_MCLK_SAI3_MCLK 0xd6
+ MX8MM_IOMUXC_SAI3_TXD_SAI3_TX_DATA0 0xd6
+ >;
+ };
+
+ pinctrl_touchscreen: tsgrp {
+ fsl,pins = <
+ MX8MM_IOMUXC_GPIO1_IO08_GPIO1_IO8 0x80
+ MX8MM_IOMUXC_GPIO1_IO09_GPIO1_IO9 0x80
+ >;
+ };
+
+ pinctrl_uart4: uart4grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_UART4_RXD_UART4_DCE_RX 0x040
+ MX8MM_IOMUXC_UART4_TXD_UART4_DCE_TX 0x040
+ >;
+ };
+
+ pinctrl_usbotg1: usbotg1grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_GPIO1_IO12_USB1_OTG_PWR 0x000
+ MX8MM_IOMUXC_GPIO1_IO13_USB1_OTG_OC 0x000
+ >;
+ };
+
+ 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 0x0d4
+ >;
+ };
+
+ pinctrl_usdhc3: usdhc3grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_NAND_WE_B_USDHC3_CLK 0x190
+ MX8MM_IOMUXC_NAND_WP_B_USDHC3_CMD 0x1d0
+ MX8MM_IOMUXC_NAND_DATA04_USDHC3_DATA0 0x1d0
+ MX8MM_IOMUXC_NAND_DATA05_USDHC3_DATA1 0x1d0
+ MX8MM_IOMUXC_NAND_DATA06_USDHC3_DATA2 0x1d0
+ MX8MM_IOMUXC_NAND_DATA07_USDHC3_DATA3 0x1d0
+ MX8MM_IOMUXC_NAND_RE_B_USDHC3_DATA4 0x1d0
+ MX8MM_IOMUXC_NAND_CE2_B_USDHC3_DATA5 0x1d0
+ MX8MM_IOMUXC_NAND_CE3_B_USDHC3_DATA6 0x1d0
+ MX8MM_IOMUXC_NAND_CLE_USDHC3_DATA7 0x1d0
+ MX8MM_IOMUXC_NAND_CE1_B_USDHC3_STROBE 0x190
+ >;
+ };
+
+ pinctrl_usdhc3_100mhz: usdhc3grp100mhz {
+ fsl,pins = <
+ MX8MM_IOMUXC_NAND_WE_B_USDHC3_CLK 0x194
+ MX8MM_IOMUXC_NAND_WP_B_USDHC3_CMD 0x1d4
+ MX8MM_IOMUXC_NAND_DATA04_USDHC3_DATA0 0x1d4
+ MX8MM_IOMUXC_NAND_DATA05_USDHC3_DATA1 0x1d4
+ MX8MM_IOMUXC_NAND_DATA06_USDHC3_DATA2 0x1d4
+ MX8MM_IOMUXC_NAND_DATA07_USDHC3_DATA3 0x1d4
+ MX8MM_IOMUXC_NAND_RE_B_USDHC3_DATA4 0x1d4
+ MX8MM_IOMUXC_NAND_CE2_B_USDHC3_DATA5 0x1d4
+ MX8MM_IOMUXC_NAND_CE3_B_USDHC3_DATA6 0x1d4
+ MX8MM_IOMUXC_NAND_CLE_USDHC3_DATA7 0x1d4
+ MX8MM_IOMUXC_NAND_CE1_B_USDHC3_STROBE 0x194
+ >;
+ };
+
+ pinctrl_usdhc3_200mhz: usdhc3grp200mhz {
+ fsl,pins = <
+ MX8MM_IOMUXC_NAND_WE_B_USDHC3_CLK 0x196
+ MX8MM_IOMUXC_NAND_WP_B_USDHC3_CMD 0x1d6
+ MX8MM_IOMUXC_NAND_DATA04_USDHC3_DATA0 0x1d6
+ MX8MM_IOMUXC_NAND_DATA05_USDHC3_DATA1 0x1d6
+ MX8MM_IOMUXC_NAND_DATA06_USDHC3_DATA2 0x1d6
+ MX8MM_IOMUXC_NAND_DATA07_USDHC3_DATA3 0x1d6
+ MX8MM_IOMUXC_NAND_RE_B_USDHC3_DATA4 0x1d6
+ MX8MM_IOMUXC_NAND_CE2_B_USDHC3_DATA5 0x1d6
+ MX8MM_IOMUXC_NAND_CE3_B_USDHC3_DATA6 0x1d6
+ MX8MM_IOMUXC_NAND_CLE_USDHC3_DATA7 0x1d6
+ MX8MM_IOMUXC_NAND_CE1_B_USDHC3_STROBE 0x196
+ >;
+ };
+
+ pinctrl_wdog: wdoggrp {
+ fsl,pins = <
+ MX8MM_IOMUXC_GPIO1_IO02_WDOG1_WDOG_B 0xc6
+ >;
+ };
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-tqma8mqml-mba8mx.dts b/arch/arm64/boot/dts/freescale/imx8mm-tqma8mqml-mba8mx.dts
index 7844878788f4..286d2df01cfa 100644
--- a/arch/arm64/boot/dts/freescale/imx8mm-tqma8mqml-mba8mx.dts
+++ b/arch/arm64/boot/dts/freescale/imx8mm-tqma8mqml-mba8mx.dts
@@ -5,6 +5,7 @@
/dts-v1/;
+#include <dt-bindings/phy/phy-imx8-pcie.h>
#include "imx8mm-tqma8mqml.dtsi"
#include "mba8mx.dtsi"
@@ -58,6 +59,24 @@
};
};
+&pcie_phy {
+ clocks = <&pcie0_refclk>;
+ status = "okay";
+};
+
+&pcie0 {
+ reset-gpio = <&expander0 14 GPIO_ACTIVE_LOW>;
+ clocks = <&clk IMX8MM_CLK_PCIE1_ROOT>, <&clk IMX8MM_CLK_PCIE1_AUX>,
+ <&pcie0_refclk>;
+ clock-names = "pcie", "pcie_aux", "pcie_bus";
+ assigned-clocks = <&clk IMX8MM_CLK_PCIE1_AUX>,
+ <&clk IMX8MM_CLK_PCIE1_CTRL>;
+ assigned-clock-rates = <10000000>, <250000000>;
+ assigned-clock-parents = <&clk IMX8MM_SYS_PLL2_50M>,
+ <&clk IMX8MM_SYS_PLL2_250M>;
+ status = "okay";
+};
+
&sai3 {
assigned-clocks = <&clk IMX8MM_CLK_SAI3>;
assigned-clock-parents = <&clk IMX8MM_AUDIO_PLL1_OUT>;
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-tqma8mqml.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-tqma8mqml.dtsi
index 284e62acc0b4..16ee9b5179e6 100644
--- a/arch/arm64/boot/dts/freescale/imx8mm-tqma8mqml.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mm-tqma8mqml.dtsi
@@ -227,6 +227,11 @@
};
};
+&pcie_phy {
+ fsl,refclk-pad-mode = <IMX8_PCIE_REFCLK_PAD_INPUT>;
+ fsl,clkreq-unsupported;
+};
+
&usdhc3 {
pinctrl-names = "default", "state_100mhz", "state_200mhz";
pinctrl-0 = <&pinctrl_usdhc3>;
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-venice-gw71xx.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-venice-gw71xx.dtsi
index 28012279f6f6..73addc0b8e57 100644
--- a/arch/arm64/boot/dts/freescale/imx8mm-venice-gw71xx.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mm-venice-gw71xx.dtsi
@@ -5,6 +5,7 @@
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/leds/common.h>
+#include <dt-bindings/phy/phy-imx8-pcie.h>
/ {
aliases {
@@ -33,6 +34,12 @@
};
};
+ pcie0_refclk: pcie0-refclk {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <100000000>;
+ };
+
pps {
compatible = "pps-gpio";
pinctrl-names = "default";
@@ -61,6 +68,20 @@
status = "okay";
};
+&gpio1 {
+ gpio-line-names = "", "", "", "", "", "", "pci_usb_sel", "dio0",
+ "", "dio1", "", "", "", "", "", "",
+ "", "", "", "", "", "", "", "",
+ "", "", "", "", "", "", "", "";
+};
+
+&gpio4 {
+ gpio-line-names = "", "", "", "dio2", "dio3", "", "", "pci_wdis#",
+ "", "", "", "", "", "", "", "",
+ "", "", "", "", "", "", "", "",
+ "", "", "", "", "", "", "", "";
+};
+
&i2c2 {
clock-frequency = <400000>;
pinctrl-names = "default";
@@ -87,6 +108,28 @@
status = "okay";
};
+&pcie_phy {
+ fsl,refclk-pad-mode = <IMX8_PCIE_REFCLK_PAD_INPUT>;
+ fsl,clkreq-unsupported;
+ clocks = <&pcie0_refclk>;
+ status = "okay";
+};
+
+&pcie0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pcie0>;
+ reset-gpio = <&gpio4 6 GPIO_ACTIVE_LOW>;
+ clocks = <&clk IMX8MM_CLK_PCIE1_ROOT>, <&clk IMX8MM_CLK_PCIE1_AUX>,
+ <&pcie0_refclk>;
+ clock-names = "pcie", "pcie_aux", "pcie_bus";
+ assigned-clocks = <&clk IMX8MM_CLK_PCIE1_AUX>,
+ <&clk IMX8MM_CLK_PCIE1_CTRL>;
+ assigned-clock-rates = <10000000>, <250000000>;
+ assigned-clock-parents = <&clk IMX8MM_SYS_PLL2_50M>,
+ <&clk IMX8MM_SYS_PLL2_250M>;
+ status = "okay";
+};
+
/* GPS */
&uart1 {
pinctrl-names = "default";
@@ -148,6 +191,12 @@
>;
};
+ pinctrl_pcie0: pcie0grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_SAI1_RXD4_GPIO4_IO6 0x41
+ >;
+ };
+
pinctrl_pps: ppsgrp {
fsl,pins = <
MX8MM_IOMUXC_GPIO1_IO15_GPIO1_IO15 0x41
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-venice-gw72xx-0x-imx219.dts b/arch/arm64/boot/dts/freescale/imx8mm-venice-gw72xx-0x-imx219.dts
new file mode 100644
index 000000000000..4eaf8aabcbff
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8mm-venice-gw72xx-0x-imx219.dts
@@ -0,0 +1,93 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright 2022 Gateworks Corporation
+ */
+
+#include <dt-bindings/gpio/gpio.h>
+
+#include "imx8mm-pinfunc.h"
+
+/dts-v1/;
+/plugin/;
+
+&{/} {
+ compatible = "gw,imx8mm-gw72xx-0x", "fsl,imx8mm";
+
+ reg_cam: regulator-cam {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_reg_cam>;
+ compatible = "regulator-fixed";
+ regulator-name = "reg_cam";
+ gpio = <&gpio1 1 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ cam24m: cam24m {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <24000000>;
+ clock-output-names = "cam24m";
+ };
+};
+
+&csi {
+ status = "okay";
+};
+
+&i2c3 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ imx219: sensor@10 {
+ compatible = "sony,imx219";
+ reg = <0x10>;
+ clocks = <&cam24m>;
+ VDIG-supply = <&reg_cam>;
+
+ port {
+ /* MIPI CSI-2 bus endpoint */
+ imx219_to_mipi_csi2: endpoint {
+ remote-endpoint = <&imx8mm_mipi_csi_in>;
+ clock-lanes = <0>;
+ data-lanes = <1 2>;
+ link-frequencies = /bits/ 64 <456000000>;
+ };
+ };
+ };
+};
+
+&mipi_csi {
+ status = "okay";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ imx8mm_mipi_csi_in: endpoint {
+ remote-endpoint = <&imx219_to_mipi_csi2>;
+ data-lanes = <1 2>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+
+ imx8mm_mipi_csi_out: endpoint {
+ remote-endpoint = <&csi_in>;
+ };
+ };
+ };
+};
+
+&iomuxc {
+ pinctrl_reg_cam: regcamgrp {
+ fsl,pins = <
+ MX8MM_IOMUXC_GPIO1_IO01_GPIO1_IO1 0x41
+ >;
+ };
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-venice-gw72xx-0x-rs232-rts.dts b/arch/arm64/boot/dts/freescale/imx8mm-venice-gw72xx-0x-rs232-rts.dts
new file mode 100644
index 000000000000..3ea73a6886ff
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8mm-venice-gw72xx-0x-rs232-rts.dts
@@ -0,0 +1,53 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright 2022 Gateworks Corporation
+ *
+ * GW72xx RS232 with RTS/CTS hardware flow control:
+ * - GPIO4_0 rs485_en needs to be driven low (in-active)
+ * - UART4_TX becomes RTS
+ * - UART4_RX becomes CTS
+ */
+
+#include <dt-bindings/gpio/gpio.h>
+
+#include "imx8mm-pinfunc.h"
+
+/dts-v1/;
+/plugin/;
+
+&{/} {
+ compatible = "gw,imx8mm-gw72xx-0x";
+};
+
+&gpio4 {
+ rs485_en {
+ gpio-hog;
+ gpios = <0 GPIO_ACTIVE_HIGH>;
+ output-low;
+ line-name = "rs485_en";
+ };
+};
+
+&uart2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart2>;
+ rts-gpios = <&gpio5 29 GPIO_ACTIVE_LOW>;
+ cts-gpios = <&gpio5 28 GPIO_ACTIVE_LOW>;
+ uart-has-rtscts;
+ status = "okay";
+};
+
+&uart4 {
+ status = "disabled";
+};
+
+&iomuxc {
+ pinctrl_uart2: uart2grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_UART2_RXD_UART2_DCE_RX 0x140
+ MX8MM_IOMUXC_UART2_TXD_UART2_DCE_TX 0x140
+ MX8MM_IOMUXC_UART4_TXD_GPIO5_IO29 0x140
+ MX8MM_IOMUXC_UART4_RXD_GPIO5_IO28 0x140
+ >;
+ };
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-venice-gw72xx-0x-rs422.dts b/arch/arm64/boot/dts/freescale/imx8mm-venice-gw72xx-0x-rs422.dts
new file mode 100644
index 000000000000..c3cd9f2b0db3
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8mm-venice-gw72xx-0x-rs422.dts
@@ -0,0 +1,61 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright 2022 Gateworks Corporation
+ *
+ * GW72xx RS422 (RS485 full duplex):
+ * - GPIO1_0 rs485_term selects on-chip termination
+ * - GPIO4_0 rs485_en needs to be driven high (active)
+ * - GPIO4_2 rs485_hd needs to be driven low (in-active)
+ * - UART4_TX is DE for RS485 transmitter
+ * - RS485_EN needs to be pulled high
+ * - RS485_HALF needs to be low
+ */
+
+#include <dt-bindings/gpio/gpio.h>
+
+#include "imx8mm-pinfunc.h"
+
+/dts-v1/;
+/plugin/;
+
+&{/} {
+ compatible = "gw,imx8mm-gw72xx-0x";
+};
+
+&gpio4 {
+ rs485_en {
+ gpio-hog;
+ gpios = <0 GPIO_ACTIVE_HIGH>;
+ output-high;
+ line-name = "rs485_en";
+ };
+
+ rs485_hd {
+ gpio-hog;
+ gpios = <2 GPIO_ACTIVE_HIGH>;
+ output-low;
+ line-name = "rs485_hd";
+ };
+};
+
+&uart2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart2>;
+ rts-gpios = <&gpio5 29 GPIO_ACTIVE_HIGH>;
+ linux,rs485-enabled-at-boot-time;
+ status = "okay";
+};
+
+&uart4 {
+ status = "disabled";
+};
+
+&iomuxc {
+ pinctrl_uart2: uart2grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_UART2_RXD_UART2_DCE_RX 0x140
+ MX8MM_IOMUXC_UART2_TXD_UART2_DCE_TX 0x140
+ MX8MM_IOMUXC_UART4_TXD_GPIO5_IO29 0x140
+ >;
+ };
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-venice-gw72xx-0x-rs485.dts b/arch/arm64/boot/dts/freescale/imx8mm-venice-gw72xx-0x-rs485.dts
new file mode 100644
index 000000000000..cc0a287226ab
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8mm-venice-gw72xx-0x-rs485.dts
@@ -0,0 +1,61 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright 2022 Gateworks Corporation
+ *
+ * GW72xx RS485 HD:
+ * - GPIO1_0 rs485_term selects on-chip termination
+ * - GPIO4_0 rs485_en needs to be driven high (active)
+ * - GPIO4_2 rs485_hd needs to be driven high (active)
+ * - UART4_TX is DE for RS485 transmitter
+ * - RS485_EN needs to be pulled high
+ * - RS485_HALF needs to be pulled high
+ */
+
+#include <dt-bindings/gpio/gpio.h>
+
+#include "imx8mm-pinfunc.h"
+
+/dts-v1/;
+/plugin/;
+
+&{/} {
+ compatible = "gw,imx8mm-gw72xx-0x";
+};
+
+&gpio4 {
+ rs485_en {
+ gpio-hog;
+ gpios = <0 GPIO_ACTIVE_HIGH>;
+ output-high;
+ line-name = "rs485_en";
+ };
+
+ rs485_hd {
+ gpio-hog;
+ gpios = <2 GPIO_ACTIVE_HIGH>;
+ output-high;
+ line-name = "rs485_hd";
+ };
+};
+
+&uart2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart2>;
+ rts-gpios = <&gpio5 29 GPIO_ACTIVE_HIGH>;
+ linux,rs485-enabled-at-boot-time;
+ status = "okay";
+};
+
+&uart4 {
+ status = "disabled";
+};
+
+&iomuxc {
+ pinctrl_uart2: uart2grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_UART2_RXD_UART2_DCE_RX 0x140
+ MX8MM_IOMUXC_UART2_TXD_UART2_DCE_TX 0x140
+ MX8MM_IOMUXC_UART4_TXD_GPIO5_IO29 0x140
+ >;
+ };
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-venice-gw72xx.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-venice-gw72xx.dtsi
index 27afa46a253a..1e7badb2a82e 100644
--- a/arch/arm64/boot/dts/freescale/imx8mm-venice-gw72xx.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mm-venice-gw72xx.dtsi
@@ -5,9 +5,11 @@
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/leds/common.h>
+#include <dt-bindings/phy/phy-imx8-pcie.h>
/ {
aliases {
+ ethernet1 = &eth1;
usb0 = &usbotg1;
usb1 = &usbotg2;
};
@@ -33,6 +35,12 @@
};
};
+ pcie0_refclk: pcie0-refclk {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <100000000>;
+ };
+
pps {
compatible = "pps-gpio";
pinctrl-names = "default";
@@ -80,6 +88,22 @@
status = "okay";
};
+&gpio1 {
+ gpio-line-names = "rs485_term", "mipi_gpio4", "", "",
+ "", "", "pci_usb_sel", "dio0",
+ "", "dio1", "", "", "", "", "", "",
+ "", "", "", "", "", "", "", "",
+ "", "", "", "", "", "", "", "";
+};
+
+&gpio4 {
+ gpio-line-names = "rs485_en", "mipi_gpio3", "rs485_hd", "mipi_gpio2",
+ "mipi_gpio1", "", "", "pci_wdis#",
+ "", "", "", "", "", "", "", "",
+ "", "", "", "", "", "", "", "",
+ "", "", "", "", "", "", "", "";
+};
+
&i2c2 {
clock-frequency = <400000>;
pinctrl-names = "default";
@@ -106,6 +130,54 @@
status = "okay";
};
+&pcie_phy {
+ fsl,refclk-pad-mode = <IMX8_PCIE_REFCLK_PAD_INPUT>;
+ fsl,clkreq-unsupported;
+ clocks = <&pcie0_refclk>;
+ status = "okay";
+};
+
+&pcie0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pcie0>;
+ reset-gpio = <&gpio4 6 GPIO_ACTIVE_LOW>;
+ clocks = <&clk IMX8MM_CLK_PCIE1_ROOT>, <&clk IMX8MM_CLK_PCIE1_AUX>,
+ <&pcie0_refclk>;
+ clock-names = "pcie", "pcie_aux", "pcie_bus";
+ assigned-clocks = <&clk IMX8MM_CLK_PCIE1_AUX>,
+ <&clk IMX8MM_CLK_PCIE1_CTRL>;
+ assigned-clock-rates = <10000000>, <250000000>;
+ assigned-clock-parents = <&clk IMX8MM_SYS_PLL2_50M>,
+ <&clk IMX8MM_SYS_PLL2_250M>;
+ status = "okay";
+
+ pcie@0,0 {
+ reg = <0x0000 0 0 0 0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pcie@1,0 {
+ reg = <0x0000 0 0 0 0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pcie@2,3 {
+ reg = <0x1800 0 0 0 0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ eth1: pcie@5,0 {
+ reg = <0x0000 0 0 0 0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ local-mac-address = [00 00 00 00 00 00];
+ };
+ };
+ };
+ };
+};
+
/* off-board header */
&sai3 {
pinctrl-names = "default";
@@ -198,6 +270,12 @@
>;
};
+ pinctrl_pcie0: pcie0grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_SAI1_RXD4_GPIO4_IO6 0x41
+ >;
+ };
+
pinctrl_pps: ppsgrp {
fsl,pins = <
MX8MM_IOMUXC_GPIO1_IO15_GPIO1_IO15 0x41
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-venice-gw73xx-0x-imx219.dts b/arch/arm64/boot/dts/freescale/imx8mm-venice-gw73xx-0x-imx219.dts
new file mode 100644
index 000000000000..f3ece4b7fbbd
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8mm-venice-gw73xx-0x-imx219.dts
@@ -0,0 +1,93 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright 2022 Gateworks Corporation
+ */
+
+#include <dt-bindings/gpio/gpio.h>
+
+#include "imx8mm-pinfunc.h"
+
+/dts-v1/;
+/plugin/;
+
+&{/} {
+ compatible = "gw,imx8mm-gw73xx-0x", "fsl,imx8mm";
+
+ reg_cam: regulator-cam {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_reg_cam>;
+ compatible = "regulator-fixed";
+ regulator-name = "reg_cam";
+ gpio = <&gpio1 1 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ cam24m: cam24m {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <24000000>;
+ clock-output-names = "cam24m";
+ };
+};
+
+&csi {
+ status = "okay";
+};
+
+&i2c3 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ imx219: sensor@10 {
+ compatible = "sony,imx219";
+ reg = <0x10>;
+ clocks = <&cam24m>;
+ VDIG-supply = <&reg_cam>;
+
+ port {
+ /* MIPI CSI-2 bus endpoint */
+ imx219_to_mipi_csi2: endpoint {
+ remote-endpoint = <&imx8mm_mipi_csi_in>;
+ clock-lanes = <0>;
+ data-lanes = <1 2>;
+ link-frequencies = /bits/ 64 <456000000>;
+ };
+ };
+ };
+};
+
+&mipi_csi {
+ status = "okay";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ imx8mm_mipi_csi_in: endpoint {
+ remote-endpoint = <&imx219_to_mipi_csi2>;
+ data-lanes = <1 2>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+
+ imx8mm_mipi_csi_out: endpoint {
+ remote-endpoint = <&csi_in>;
+ };
+ };
+ };
+};
+
+&iomuxc {
+ pinctrl_reg_cam: regcamgrp {
+ fsl,pins = <
+ MX8MM_IOMUXC_GPIO1_IO01_GPIO1_IO1 0x41
+ >;
+ };
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-venice-gw73xx-0x-rs232-rts.dts b/arch/arm64/boot/dts/freescale/imx8mm-venice-gw73xx-0x-rs232-rts.dts
new file mode 100644
index 000000000000..2fa635e1c1a8
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8mm-venice-gw73xx-0x-rs232-rts.dts
@@ -0,0 +1,53 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright 2022 Gateworks Corporation
+ *
+ * GW73xx RS232 with RTS/CTS hardware flow control:
+ * - GPIO4_0 rs485_en needs to be driven low (in-active)
+ * - UART4_TX becomes RTS
+ * - UART4_RX becomes CTS
+ */
+
+#include <dt-bindings/gpio/gpio.h>
+
+#include "imx8mm-pinfunc.h"
+
+/dts-v1/;
+/plugin/;
+
+&{/} {
+ compatible = "gw,imx8mm-gw73xx-0x";
+};
+
+&gpio4 {
+ rs485_en {
+ gpio-hog;
+ gpios = <0 GPIO_ACTIVE_HIGH>;
+ output-low;
+ line-name = "rs485_en";
+ };
+};
+
+&uart2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart2>;
+ rts-gpios = <&gpio5 29 GPIO_ACTIVE_LOW>;
+ cts-gpios = <&gpio5 28 GPIO_ACTIVE_LOW>;
+ uart-has-rtscts;
+ status = "okay";
+};
+
+&uart4 {
+ status = "disabled";
+};
+
+&iomuxc {
+ pinctrl_uart2: uart2grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_UART2_RXD_UART2_DCE_RX 0x140
+ MX8MM_IOMUXC_UART2_TXD_UART2_DCE_TX 0x140
+ MX8MM_IOMUXC_UART4_TXD_GPIO5_IO29 0x140
+ MX8MM_IOMUXC_UART4_RXD_GPIO5_IO28 0x140
+ >;
+ };
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-venice-gw73xx-0x-rs422.dts b/arch/arm64/boot/dts/freescale/imx8mm-venice-gw73xx-0x-rs422.dts
new file mode 100644
index 000000000000..3e6404340d52
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8mm-venice-gw73xx-0x-rs422.dts
@@ -0,0 +1,61 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright 2021 Gateworks Corporation
+ *
+ * GW73xx RS422 (RS485 full duplex):
+ * - GPIO1_0 rs485_term selects on-chip termination
+ * - GPIO4_0 rs485_en needs to be driven high (active)
+ * - GPIO4_2 rs485_hd needs to be driven low (in-active)
+ * - UART4_TX is DE for RS485 transmitter
+ * - RS485_EN needs to be pulled high
+ * - RS485_HALF needs to be low
+ */
+
+#include <dt-bindings/gpio/gpio.h>
+
+#include "imx8mm-pinfunc.h"
+
+/dts-v1/;
+/plugin/;
+
+&{/} {
+ compatible = "gw,imx8mm-gw73xx-0x";
+};
+
+&gpio4 {
+ rs485_en {
+ gpio-hog;
+ gpios = <0 GPIO_ACTIVE_HIGH>;
+ output-high;
+ line-name = "rs485_en";
+ };
+
+ rs485_hd {
+ gpio-hog;
+ gpios = <2 GPIO_ACTIVE_HIGH>;
+ output-low;
+ line-name = "rs485_hd";
+ };
+};
+
+&uart2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart2>;
+ rts-gpios = <&gpio5 29 GPIO_ACTIVE_HIGH>;
+ linux,rs485-enabled-at-boot-time;
+ status = "okay";
+};
+
+&uart4 {
+ status = "disabled";
+};
+
+&iomuxc {
+ pinctrl_uart2: uart2grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_UART2_RXD_UART2_DCE_RX 0x140
+ MX8MM_IOMUXC_UART2_TXD_UART2_DCE_TX 0x140
+ MX8MM_IOMUXC_UART4_TXD_GPIO5_IO29 0x140
+ >;
+ };
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-venice-gw73xx-0x-rs485.dts b/arch/arm64/boot/dts/freescale/imx8mm-venice-gw73xx-0x-rs485.dts
new file mode 100644
index 000000000000..2c71ab9854cb
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8mm-venice-gw73xx-0x-rs485.dts
@@ -0,0 +1,61 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright 2021 Gateworks Corporation
+ *
+ * GW73xx RS485 HD:
+ * - GPIO1_0 rs485_term selects on-chip termination
+ * - GPIO4_0 rs485_en needs to be driven high (active)
+ * - GPIO4_2 rs485_hd needs to be driven high (active)
+ * - UART4_TX is DE for RS485 transmitter
+ * - RS485_EN needs to be pulled high
+ * - RS485_HALF needs to be pulled high
+ */
+
+#include <dt-bindings/gpio/gpio.h>
+
+#include "imx8mm-pinfunc.h"
+
+/dts-v1/;
+/plugin/;
+
+&{/} {
+ compatible = "gw,imx8mm-gw73xx-0x";
+};
+
+&gpio4 {
+ rs485_en {
+ gpio-hog;
+ gpios = <0 GPIO_ACTIVE_HIGH>;
+ output-high;
+ line-name = "rs485_en";
+ };
+
+ rs485_hd {
+ gpio-hog;
+ gpios = <2 GPIO_ACTIVE_HIGH>;
+ output-high;
+ line-name = "rs485_hd";
+ };
+};
+
+&uart2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart2>;
+ rts-gpios = <&gpio5 29 GPIO_ACTIVE_HIGH>;
+ linux,rs485-enabled-at-boot-time;
+ status = "okay";
+};
+
+&uart4 {
+ status = "disabled";
+};
+
+&iomuxc {
+ pinctrl_uart2: uart2grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_UART2_RXD_UART2_DCE_RX 0x140
+ MX8MM_IOMUXC_UART2_TXD_UART2_DCE_TX 0x140
+ MX8MM_IOMUXC_UART4_TXD_GPIO5_IO29 0x140
+ >;
+ };
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-venice-gw73xx.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-venice-gw73xx.dtsi
index a59e849c7be2..426483ec1f88 100644
--- a/arch/arm64/boot/dts/freescale/imx8mm-venice-gw73xx.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mm-venice-gw73xx.dtsi
@@ -5,9 +5,11 @@
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/leds/common.h>
+#include <dt-bindings/phy/phy-imx8-pcie.h>
/ {
aliases {
+ ethernet1 = &eth1;
usb0 = &usbotg1;
usb1 = &usbotg2;
};
@@ -33,6 +35,12 @@
};
};
+ pcie0_refclk: pcie0-refclk {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <100000000>;
+ };
+
pps {
compatible = "pps-gpio";
pinctrl-names = "default";
@@ -100,6 +108,22 @@
status = "okay";
};
+&gpio1 {
+ gpio-line-names = "rs485_term", "mipi_gpio4", "", "",
+ "", "", "pci_usb_sel", "dio0",
+ "", "dio1", "", "", "", "", "", "",
+ "", "", "", "", "", "", "", "",
+ "", "", "", "", "", "", "", "";
+};
+
+&gpio4 {
+ gpio-line-names = "rs485_en", "mipi_gpio3", "rs485_hd", "mipi_gpio2",
+ "mipi_gpio1", "", "", "pci_wdis#",
+ "", "", "", "", "", "", "", "",
+ "", "", "", "", "", "", "", "",
+ "", "", "", "", "", "", "", "";
+};
+
&i2c2 {
clock-frequency = <400000>;
pinctrl-names = "default";
@@ -126,6 +150,54 @@
status = "okay";
};
+&pcie_phy {
+ fsl,refclk-pad-mode = <IMX8_PCIE_REFCLK_PAD_INPUT>;
+ fsl,clkreq-unsupported;
+ clocks = <&pcie0_refclk>;
+ status = "okay";
+};
+
+&pcie0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pcie0>;
+ reset-gpio = <&gpio4 6 GPIO_ACTIVE_LOW>;
+ clocks = <&clk IMX8MM_CLK_PCIE1_ROOT>, <&clk IMX8MM_CLK_PCIE1_AUX>,
+ <&pcie0_refclk>;
+ clock-names = "pcie", "pcie_aux", "pcie_bus";
+ assigned-clocks = <&clk IMX8MM_CLK_PCIE1_AUX>,
+ <&clk IMX8MM_CLK_PCIE1_CTRL>;
+ assigned-clock-rates = <10000000>, <250000000>;
+ assigned-clock-parents = <&clk IMX8MM_SYS_PLL2_50M>,
+ <&clk IMX8MM_SYS_PLL2_250M>;
+ status = "okay";
+
+ pcie@0,0 {
+ reg = <0x0000 0 0 0 0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pcie@1,0 {
+ reg = <0x0000 0 0 0 0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pcie@2,4 {
+ reg = <0x2000 0 0 0 0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ eth1: pcie@6,0 {
+ reg = <0x0000 0 0 0 0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ local-mac-address = [00 00 00 00 00 00];
+ };
+ };
+ };
+ };
+};
+
/* off-board header */
&sai3 {
pinctrl-names = "default";
@@ -241,6 +313,12 @@
>;
};
+ pinctrl_pcie0: pcie0grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_SAI1_RXD4_GPIO4_IO6 0x41
+ >;
+ };
+
pinctrl_pps: ppsgrp {
fsl,pins = <
MX8MM_IOMUXC_GPIO1_IO15_GPIO1_IO15 0x41
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-venice-gw7901.dts b/arch/arm64/boot/dts/freescale/imx8mm-venice-gw7901.dts
index 21c546c4628d..7e7231046215 100644
--- a/arch/arm64/boot/dts/freescale/imx8mm-venice-gw7901.dts
+++ b/arch/arm64/boot/dts/freescale/imx8mm-venice-gw7901.dts
@@ -8,6 +8,7 @@
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/input/linux-event-codes.h>
#include <dt-bindings/leds/common.h>
+#include <dt-bindings/phy/phy-imx8-pcie.h>
#include "imx8mm.dtsi"
@@ -179,6 +180,12 @@
};
};
+ pcie0_refclk: pcie0-refclk {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <100000000>;
+ };
+
reg_3p3v: regulator-3p3v {
compatible = "regulator-fixed";
regulator-name = "3P3V";
@@ -286,6 +293,29 @@
};
};
+&gpio1 {
+ gpio-line-names = "uart1_rs422#", "", "", "uart1_rs485#",
+ "", "uart1_rs232#", "dig1_in", "dig1_out",
+ "", "", "", "", "", "", "", "",
+ "", "", "", "", "", "", "", "",
+ "", "", "", "", "", "", "", "";
+};
+
+&gpio4 {
+ gpio-line-names = "", "", "", "",
+ "", "", "uart3_rs232#", "uart3_rs422#",
+ "uart3_rs485#", "", "", "", "", "", "", "",
+ "", "", "", "", "", "", "", "",
+ "", "", "", "uart4_rs485#", "", "sim1det#", "sim2det#", "";
+};
+
+&gpio5 {
+ gpio-line-names = "", "", "", "dig2_out", "dig2_in", "sim2sel", "", "",
+ "", "", "uart4_rs232#", "", "", "uart4_rs422#", "", "",
+ "", "", "", "", "", "", "", "",
+ "", "", "", "", "", "", "", "";
+};
+
&gpu_2d {
status = "disabled";
};
@@ -644,6 +674,28 @@
status = "okay";
};
+&pcie_phy {
+ fsl,refclk-pad-mode = <IMX8_PCIE_REFCLK_PAD_INPUT>;
+ fsl,clkreq-unsupported;
+ clocks = <&pcie0_refclk>;
+ status = "okay";
+};
+
+&pcie0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pcie0>;
+ reset-gpio = <&gpio5 2 GPIO_ACTIVE_LOW>;
+ clocks = <&clk IMX8MM_CLK_PCIE1_ROOT>, <&clk IMX8MM_CLK_PCIE1_AUX>,
+ <&pcie0_refclk>;
+ clock-names = "pcie", "pcie_aux", "pcie_bus";
+ assigned-clocks = <&clk IMX8MM_CLK_PCIE1_AUX>,
+ <&clk IMX8MM_CLK_PCIE1_CTRL>;
+ assigned-clock-rates = <10000000>, <250000000>;
+ assigned-clock-parents = <&clk IMX8MM_SYS_PLL2_50M>,
+ <&clk IMX8MM_SYS_PLL2_250M>;
+ status = "okay";
+};
+
&pgc_gpu {
status = "disabled";
};
@@ -820,6 +872,13 @@
>;
};
+ pinctrl_pcie0: pciegrp {
+ fsl,pins = <
+ MX8MM_IOMUXC_SAI3_TXFS_GPIO4_IO31 0x40000041 /* WDIS# */
+ MX8MM_IOMUXC_SAI3_MCLK_GPIO5_IO2 0x41
+ >;
+ };
+
pinctrl_pmic: pmicgrp {
fsl,pins = <
MX8MM_IOMUXC_SAI5_RXC_GPIO3_IO20 0x41
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-venice-gw7902.dts b/arch/arm64/boot/dts/freescale/imx8mm-venice-gw7902.dts
index d52686f4c059..edf0c7aaaef0 100644
--- a/arch/arm64/boot/dts/freescale/imx8mm-venice-gw7902.dts
+++ b/arch/arm64/boot/dts/freescale/imx8mm-venice-gw7902.dts
@@ -9,6 +9,7 @@
#include <dt-bindings/input/linux-event-codes.h>
#include <dt-bindings/leds/common.h>
#include <dt-bindings/net/ti-dp83867.h>
+#include <dt-bindings/phy/phy-imx8-pcie.h>
#include "imx8mm.dtsi"
@@ -17,6 +18,7 @@
compatible = "gw,imx8mm-gw7902", "fsl,imx8mm";
aliases {
+ ethernet1 = &eth1;
usb0 = &usbotg1;
usb1 = &usbotg2;
};
@@ -128,6 +130,12 @@
};
};
+ pcie0_refclk: pcie0-refclk {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <100000000>;
+ };
+
pps {
compatible = "pps-gpio";
pinctrl-names = "default";
@@ -252,6 +260,43 @@
};
};
+&gpio1 {
+ gpio-line-names = "", "", "", "", "", "", "", "",
+ "", "", "", "", "", "m2_reset", "", "m2_wdis#",
+ "", "", "", "", "", "", "", "",
+ "", "", "", "", "", "", "", "";
+};
+
+&gpio2 {
+ gpio-line-names = "", "", "", "", "", "", "", "",
+ "uart2_en#", "", "", "", "", "", "", "",
+ "", "", "", "", "", "", "", "",
+ "", "", "", "", "", "", "", "";
+};
+
+&gpio3 {
+ gpio-line-names = "", "m2_gdis#", "", "", "", "", "", "m2_off#",
+ "", "", "", "", "", "", "", "",
+ "", "", "", "", "", "", "", "",
+ "", "", "", "", "", "", "", "";
+};
+
+&gpio4 {
+ gpio-line-names = "", "", "", "", "", "", "", "",
+ "", "", "", "amp_gpio3", "amp_gpio2", "", "amp_gpio1", "",
+ "", "", "", "", "amp_gpio4", "app_gpio1", "", "uart1_rs485",
+ "", "uart1_term", "uart1_half", "app_gpio2",
+ "mipi_gpio1", "", "", "";
+};
+
+&gpio5 {
+ gpio-line-names = "", "", "", "mipi_gpio4",
+ "mipi_gpio3", "mipi_gpio2", "", "",
+ "", "", "", "", "", "", "", "",
+ "", "", "", "", "", "", "", "",
+ "", "", "", "", "", "", "", "";
+};
+
&i2c1 {
clock-frequency = <100000>;
pinctrl-names = "default";
@@ -547,6 +592,42 @@
status = "okay";
};
+&pcie_phy {
+ fsl,refclk-pad-mode = <IMX8_PCIE_REFCLK_PAD_INPUT>;
+ fsl,clkreq-unsupported;
+ clocks = <&clk IMX8MM_CLK_DUMMY>;
+ status = "okay";
+};
+
+&pcie0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pcie0>;
+ reset-gpio = <&gpio4 5 GPIO_ACTIVE_LOW>;
+ clocks = <&clk IMX8MM_CLK_PCIE1_ROOT>, <&clk IMX8MM_CLK_PCIE1_AUX>,
+ <&clk IMX8MM_CLK_DUMMY>, <&pcie0_refclk>;
+ clock-names = "pcie", "pcie_aux", "pcie_phy", "pcie_bus";
+ assigned-clocks = <&clk IMX8MM_CLK_PCIE1_AUX>,
+ <&clk IMX8MM_CLK_PCIE1_CTRL>;
+ assigned-clock-rates = <10000000>, <250000000>;
+ assigned-clock-parents = <&clk IMX8MM_SYS_PLL2_50M>,
+ <&clk IMX8MM_SYS_PLL2_250M>;
+ status = "okay";
+
+ pcie@0,0 {
+ reg = <0x0000 0 0 0 0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ eth1: pcie@1,0 {
+ reg = <0x0000 0 0 0 0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ local-mac-address = [00 00 00 00 00 00];
+ };
+ };
+};
+
/* off-board header */
&sai3 {
pinctrl-names = "default";
@@ -647,7 +728,7 @@
pinctrl_hog: hoggrp {
fsl,pins = <
MX8MM_IOMUXC_NAND_CE0_B_GPIO3_IO1 0x40000159 /* M2_GDIS# */
- MX8MM_IOMUXC_GPIO1_IO13_GPIO1_IO13 0x40000041 /* M2_RST# */
+ MX8MM_IOMUXC_GPIO1_IO13_GPIO1_IO13 0x40000041 /* M2_RESET */
MX8MM_IOMUXC_NAND_DATA01_GPIO3_IO7 0x40000119 /* M2_OFF# */
MX8MM_IOMUXC_GPIO1_IO15_GPIO1_IO15 0x40000159 /* M2_WDIS# */
MX8MM_IOMUXC_SAI1_TXD2_GPIO4_IO14 0x40000041 /* AMP GPIO1 */
@@ -737,6 +818,12 @@
>;
};
+ pinctrl_pcie0: pciegrp {
+ fsl,pins = <
+ MX8MM_IOMUXC_SAI1_RXD3_GPIO4_IO5 0x41
+ >;
+ };
+
pinctrl_pmic: pmicgrp {
fsl,pins = <
MX8MM_IOMUXC_NAND_DATA02_GPIO3_IO8 0x41
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-venice-gw7903.dts b/arch/arm64/boot/dts/freescale/imx8mm-venice-gw7903.dts
new file mode 100644
index 000000000000..1deb2ea8fcc9
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8mm-venice-gw7903.dts
@@ -0,0 +1,836 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright 2022 Gateworks Corporation
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/linux-event-codes.h>
+#include <dt-bindings/leds/common.h>
+#include <dt-bindings/phy/phy-imx8-pcie.h>
+
+#include "imx8mm.dtsi"
+
+/ {
+ model = "Gateworks Venice GW7903 i.MX8MM board";
+ compatible = "gw,imx8mm-gw7903", "fsl,imx8mm";
+
+ aliases {
+ ethernet0 = &fec1;
+ usb0 = &usbotg1;
+ };
+
+ chosen {
+ stdout-path = &uart2;
+ };
+
+ memory@40000000 {
+ device_type = "memory";
+ reg = <0x0 0x40000000 0 0x80000000>;
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+
+ user-pb {
+ label = "user_pb";
+ gpios = <&gpio 2 GPIO_ACTIVE_LOW>;
+ linux,code = <BTN_0>;
+ };
+
+ user-pb1x {
+ label = "user_pb1x";
+ linux,code = <BTN_1>;
+ interrupt-parent = <&gsc>;
+ interrupts = <0>;
+ };
+
+ key-erased {
+ label = "key_erased";
+ linux,code = <BTN_2>;
+ interrupt-parent = <&gsc>;
+ interrupts = <1>;
+ };
+
+ eeprom-wp {
+ label = "eeprom_wp";
+ linux,code = <BTN_3>;
+ interrupt-parent = <&gsc>;
+ interrupts = <2>;
+ };
+
+ switch-hold {
+ label = "switch_hold";
+ linux,code = <BTN_5>;
+ interrupt-parent = <&gsc>;
+ interrupts = <7>;
+ };
+ };
+
+ led-controller {
+ compatible = "gpio-leds";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpio_leds>;
+
+ led-0 {
+ function = LED_FUNCTION_STATUS;
+ color = <LED_COLOR_ID_RED>;
+ label = "led01_red";
+ gpios = <&gpio5 5 GPIO_ACTIVE_HIGH>;
+ default-state = "off";
+ };
+
+ led-1 {
+ function = LED_FUNCTION_STATUS;
+ color = <LED_COLOR_ID_GREEN>;
+ label = "led01_grn";
+ gpios = <&gpio4 30 GPIO_ACTIVE_HIGH>;
+ default-state = "off";
+ };
+
+ led-2 {
+ function = LED_FUNCTION_STATUS;
+ color = <LED_COLOR_ID_RED>;
+ label = "led02_red";
+ gpios = <&gpio5 2 GPIO_ACTIVE_HIGH>;
+ default-state = "off";
+ };
+
+ led-3 {
+ function = LED_FUNCTION_STATUS;
+ color = <LED_COLOR_ID_GREEN>;
+ label = "led02_grn";
+ gpios = <&gpio1 14 GPIO_ACTIVE_HIGH>;
+ default-state = "off";
+ };
+
+ led-4 {
+ function = LED_FUNCTION_STATUS;
+ color = <LED_COLOR_ID_RED>;
+ label = "led03_red";
+ gpios = <&gpio1 9 GPIO_ACTIVE_HIGH>;
+ default-state = "off";
+ };
+
+ led-5 {
+ function = LED_FUNCTION_STATUS;
+ color = <LED_COLOR_ID_GREEN>;
+ label = "led03_grn";
+ gpios = <&gpio5 3 GPIO_ACTIVE_HIGH>;
+ default-state = "off";
+ };
+
+ led-6 {
+ function = LED_FUNCTION_STATUS;
+ color = <LED_COLOR_ID_RED>;
+ label = "led04_red";
+ gpios = <&gpio4 29 GPIO_ACTIVE_HIGH>;
+ default-state = "off";
+ };
+
+ led-7 {
+ function = LED_FUNCTION_STATUS;
+ color = <LED_COLOR_ID_GREEN>;
+ label = "led04_grn";
+ gpios = <&gpio4 28 GPIO_ACTIVE_HIGH>;
+ default-state = "off";
+ };
+
+ led-8 {
+ function = LED_FUNCTION_STATUS;
+ color = <LED_COLOR_ID_RED>;
+ label = "led05_red";
+ gpios = <&gpio1 13 GPIO_ACTIVE_HIGH>;
+ default-state = "off";
+ };
+
+ led-9 {
+ function = LED_FUNCTION_STATUS;
+ color = <LED_COLOR_ID_GREEN>;
+ label = "led05_grn";
+ gpios = <&gpio4 31 GPIO_ACTIVE_HIGH>;
+ default-state = "off";
+ };
+
+ led-a {
+ function = LED_FUNCTION_STATUS;
+ color = <LED_COLOR_ID_RED>;
+ label = "led06_red";
+ gpios = <&gpio5 4 GPIO_ACTIVE_HIGH>;
+ default-state = "off";
+ };
+
+ led-b {
+ function = LED_FUNCTION_STATUS;
+ color = <LED_COLOR_ID_GREEN>;
+ label = "led06_grn";
+ gpios = <&gpio1 8 GPIO_ACTIVE_HIGH>;
+ default-state = "off";
+ };
+ };
+
+ pcie0_refclk: pcie0-refclk {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <100000000>;
+ };
+
+ reg_3p3v: regulator-3p3v {
+ compatible = "regulator-fixed";
+ regulator-name = "3P3V";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+};
+
+&A53_0 {
+ cpu-supply = <&buck2>;
+};
+
+&A53_1 {
+ cpu-supply = <&buck2>;
+};
+
+&A53_2 {
+ cpu-supply = <&buck2>;
+};
+
+&A53_3 {
+ cpu-supply = <&buck2>;
+};
+
+&ddrc {
+ operating-points-v2 = <&ddrc_opp_table>;
+
+ ddrc_opp_table: opp-table {
+ compatible = "operating-points-v2";
+
+ opp-25M {
+ opp-hz = /bits/ 64 <25000000>;
+ };
+
+ opp-100M {
+ opp-hz = /bits/ 64 <100000000>;
+ };
+
+ opp-750M {
+ opp-hz = /bits/ 64 <750000000>;
+ };
+ };
+};
+
+&fec1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_fec1>;
+ phy-mode = "rgmii-id";
+ phy-handle = <&ethphy0>;
+ local-mac-address = [00 00 00 00 00 00];
+ status = "okay";
+
+ mdio {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ ethphy0: ethernet-phy@0 {
+ compatible = "ethernet-phy-ieee802.3-c22";
+ reg = <0>;
+ rx-internal-delay-ps = <2000>;
+ tx-internal-delay-ps = <2500>;
+ };
+ };
+};
+
+&gpio1 {
+ gpio-line-names = "", "", "", "", "", "", "", "",
+ "", "", "rs422_en#", "rs485_en#", "rs232_en#", "", "", "",
+ "", "", "", "", "", "", "", "",
+ "", "", "", "", "", "", "", "";
+};
+
+&gpio2 {
+ gpio-line-names = "dig2_in", "dig2_out#", "", "", "", "", "", "",
+ "dig1_out#", "dig1_in", "", "", "", "", "", "",
+ "", "", "", "", "", "", "", "",
+ "", "", "", "", "", "", "", "";
+};
+
+&gpio5 {
+ gpio-line-names = "", "", "", "", "", "", "", "sim1_det#",
+ "sim2_det#", "sim2_sel", "", "", "pci_wdis#", "", "", "",
+ "", "", "", "", "", "", "", "",
+ "", "", "", "", "", "", "", "";
+};
+
+&i2c1 {
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c1>;
+ status = "okay";
+
+ gsc: gsc@20 {
+ compatible = "gw,gsc";
+ reg = <0x20>;
+ pinctrl-0 = <&pinctrl_gsc>;
+ interrupt-parent = <&gpio4>;
+ interrupts = <26 IRQ_TYPE_EDGE_FALLING>;
+ interrupt-controller;
+ #interrupt-cells = <1>;
+
+ adc {
+ compatible = "gw,gsc-adc";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ channel@6 {
+ gw,mode = <0>;
+ reg = <0x06>;
+ label = "temp";
+ };
+
+ channel@8 {
+ gw,mode = <1>;
+ reg = <0x08>;
+ label = "vdd_bat";
+ };
+
+ channel@82 {
+ gw,mode = <2>;
+ reg = <0x82>;
+ label = "vin";
+ gw,voltage-divider-ohms = <22100 1000>;
+ gw,voltage-offset-microvolt = <700000>;
+ };
+
+ channel@84 {
+ gw,mode = <2>;
+ reg = <0x84>;
+ label = "vdd_5p0";
+ gw,voltage-divider-ohms = <10000 10000>;
+ };
+
+ channel@86 {
+ gw,mode = <2>;
+ reg = <0x86>;
+ label = "vdd_3p3";
+ gw,voltage-divider-ohms = <10000 10000>;
+ };
+
+ channel@88 {
+ gw,mode = <2>;
+ reg = <0x88>;
+ label = "vdd_0p9";
+ };
+
+ channel@8c {
+ gw,mode = <2>;
+ reg = <0x8c>;
+ label = "vdd_soc";
+ };
+
+ channel@8e {
+ gw,mode = <2>;
+ reg = <0x8e>;
+ label = "vdd_arm";
+ };
+
+ channel@90 {
+ gw,mode = <2>;
+ reg = <0x90>;
+ label = "vdd_1p8";
+ };
+
+ channel@92 {
+ gw,mode = <2>;
+ reg = <0x92>;
+ label = "vdd_dram";
+ };
+
+ channel@a2 {
+ gw,mode = <2>;
+ reg = <0xa2>;
+ label = "vdd_gsc";
+ gw,voltage-divider-ohms = <10000 10000>;
+ };
+ };
+ };
+
+ gpio: gpio@23 {
+ compatible = "nxp,pca9555";
+ reg = <0x23>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-parent = <&gsc>;
+ interrupts = <4>;
+ };
+
+ eeprom@50 {
+ compatible = "atmel,24c02";
+ reg = <0x50>;
+ pagesize = <16>;
+ };
+
+ eeprom@51 {
+ compatible = "atmel,24c02";
+ reg = <0x51>;
+ pagesize = <16>;
+ };
+
+ eeprom@52 {
+ compatible = "atmel,24c02";
+ reg = <0x52>;
+ pagesize = <16>;
+ };
+
+ eeprom@53 {
+ compatible = "atmel,24c02";
+ reg = <0x53>;
+ pagesize = <16>;
+ };
+
+ rtc@68 {
+ compatible = "dallas,ds1672";
+ reg = <0x68>;
+ };
+};
+
+&i2c2 {
+ clock-frequency = <400000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c2>;
+ status = "okay";
+
+ pmic@4b {
+ compatible = "rohm,bd71847";
+ reg = <0x4b>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pmic>;
+ interrupt-parent = <&gpio3>;
+ interrupts = <8 IRQ_TYPE_LEVEL_LOW>;
+ rohm,reset-snvs-powered;
+ #clock-cells = <0>;
+ clocks = <&osc_32k 0>;
+ clock-output-names = "clk-32k-out";
+
+ regulators {
+ /* vdd_soc: 0.805-0.900V (typ=0.8V) */
+ BUCK1 {
+ regulator-name = "buck1";
+ regulator-min-microvolt = <700000>;
+ regulator-max-microvolt = <1300000>;
+ regulator-boot-on;
+ regulator-always-on;
+ regulator-ramp-delay = <1250>;
+ };
+
+ /* vdd_arm: 0.805-1.0V (typ=0.9V) */
+ buck2: BUCK2 {
+ regulator-name = "buck2";
+ regulator-min-microvolt = <700000>;
+ regulator-max-microvolt = <1300000>;
+ regulator-boot-on;
+ regulator-always-on;
+ regulator-ramp-delay = <1250>;
+ rohm,dvs-run-voltage = <1000000>;
+ rohm,dvs-idle-voltage = <900000>;
+ };
+
+ /* vdd_0p9: 0.805-1.0V (typ=0.9V) */
+ BUCK3 {
+ regulator-name = "buck3";
+ regulator-min-microvolt = <700000>;
+ regulator-max-microvolt = <1350000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ /* vdd_3p3 */
+ BUCK4 {
+ regulator-name = "buck4";
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ /* vdd_1p8 */
+ BUCK5 {
+ regulator-name = "buck5";
+ regulator-min-microvolt = <1605000>;
+ regulator-max-microvolt = <1995000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ /* vdd_dram */
+ BUCK6 {
+ regulator-name = "buck6";
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1400000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ /* nvcc_snvs_1p8 */
+ LDO1 {
+ regulator-name = "ldo1";
+ regulator-min-microvolt = <1600000>;
+ regulator-max-microvolt = <1900000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ /* vdd_snvs_0p8 */
+ LDO2 {
+ regulator-name = "ldo2";
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <900000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ /* vdda_1p8 */
+ LDO3 {
+ regulator-name = "ldo3";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ LDO4 {
+ regulator-name = "ldo4";
+ regulator-min-microvolt = <900000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ LDO6 {
+ regulator-name = "ldo6";
+ regulator-min-microvolt = <900000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+ };
+ };
+};
+
+&i2c3 {
+ clock-frequency = <400000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c3>;
+ status = "okay";
+
+ accelerometer@19 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_accel>;
+ compatible = "st,lis2de12";
+ reg = <0x19>;
+ st,drdy-int-pin = <1>;
+ interrupt-parent = <&gpio1>;
+ interrupts = <15 IRQ_TYPE_LEVEL_LOW>;
+ interrupt-names = "INT1";
+ };
+};
+
+&pcie_phy {
+ fsl,refclk-pad-mode = <IMX8_PCIE_REFCLK_PAD_INPUT>;
+ fsl,clkreq-unsupported;
+ clocks = <&pcie0_refclk>;
+ status = "okay";
+};
+
+&pcie0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pcie0>;
+ reset-gpio = <&gpio5 11 GPIO_ACTIVE_LOW>;
+ clocks = <&clk IMX8MM_CLK_PCIE1_ROOT>, <&clk IMX8MM_CLK_PCIE1_AUX>,
+ <&pcie0_refclk>;
+ clock-names = "pcie", "pcie_aux", "pcie_bus";
+ assigned-clocks = <&clk IMX8MM_CLK_PCIE1_AUX>,
+ <&clk IMX8MM_CLK_PCIE1_CTRL>;
+ assigned-clock-rates = <10000000>, <250000000>;
+ assigned-clock-parents = <&clk IMX8MM_SYS_PLL2_50M>,
+ <&clk IMX8MM_SYS_PLL2_250M>;
+ status = "okay";
+};
+
+&pgc_mipi {
+ status = "disabled";
+};
+
+/* off-board RS232/RS485/RS422 */
+&uart1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart1>;
+ cts-gpios = <&gpio1 3 GPIO_ACTIVE_LOW>;
+ rts-gpios = <&gpio1 5 GPIO_ACTIVE_LOW>;
+ dtr-gpios = <&gpio1 0 GPIO_ACTIVE_LOW>;
+ dsr-gpios = <&gpio1 1 GPIO_ACTIVE_LOW>;
+ dcd-gpios = <&gpio3 24 GPIO_ACTIVE_LOW>;
+ uart-has-rtscts;
+ status = "okay";
+};
+
+/* console */
+&uart2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart2>;
+ status = "okay";
+};
+
+&usbotg1 {
+ dr_mode = "host";
+ disable-over-current;
+ status = "okay";
+};
+
+/* microSD */
+&usdhc2 {
+ pinctrl-names = "default", "state_100mhz", "state_200mhz";
+ pinctrl-0 = <&pinctrl_usdhc2>, <&pinctrl_usdhc2_gpio>;
+ pinctrl-1 = <&pinctrl_usdhc2_100mhz>, <&pinctrl_usdhc2_gpio>;
+ pinctrl-2 = <&pinctrl_usdhc2_200mhz>, <&pinctrl_usdhc2_gpio>;
+ cd-gpios = <&gpio2 12 GPIO_ACTIVE_LOW>;
+ bus-width = <4>;
+ vmmc-supply = <&reg_3p3v>;
+ status = "okay";
+};
+
+/* eMMC */
+&usdhc3 {
+ pinctrl-names = "default", "state_100mhz", "state_200mhz";
+ pinctrl-0 = <&pinctrl_usdhc3>;
+ pinctrl-1 = <&pinctrl_usdhc3_100mhz>;
+ pinctrl-2 = <&pinctrl_usdhc3_200mhz>;
+ bus-width = <8>;
+ non-removable;
+ 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 = <
+ MX8MM_IOMUXC_GPIO1_IO10_GPIO1_IO10 0x40000041 /* RS422# */
+ MX8MM_IOMUXC_GPIO1_IO11_GPIO1_IO11 0x40000041 /* RS485# */
+ MX8MM_IOMUXC_GPIO1_IO12_GPIO1_IO12 0x40000041 /* RS232# */
+ MX8MM_IOMUXC_SD1_DATA7_GPIO2_IO9 0x40000041 /* DIG1_IN */
+ MX8MM_IOMUXC_SD1_DATA6_GPIO2_IO8 0x40000041 /* DIG1_OUT */
+ MX8MM_IOMUXC_SD1_CLK_GPIO2_IO0 0x40000041 /* DIG2_IN */
+ MX8MM_IOMUXC_SD1_CMD_GPIO2_IO1 0x40000041 /* DIG2_OUT */
+ MX8MM_IOMUXC_ECSPI1_MOSI_GPIO5_IO7 0x40000041 /* SIM1DET# */
+ MX8MM_IOMUXC_ECSPI1_MISO_GPIO5_IO8 0x40000041 /* SIM2DET# */
+ MX8MM_IOMUXC_ECSPI1_SS0_GPIO5_IO9 0x40000041 /* SIM2SEL */
+ MX8MM_IOMUXC_ECSPI2_MISO_GPIO5_IO12 0x40000041 /* PCI_WDIS# */
+ >;
+ };
+
+ pinctrl_accel: accelgrp {
+ fsl,pins = <
+ MX8MM_IOMUXC_GPIO1_IO15_GPIO1_IO15 0x159
+ >;
+ };
+
+ pinctrl_fec1: fec1grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_ENET_MDC_ENET1_MDC 0x3
+ MX8MM_IOMUXC_ENET_MDIO_ENET1_MDIO 0x3
+ MX8MM_IOMUXC_ENET_TD3_ENET1_RGMII_TD3 0x1f
+ MX8MM_IOMUXC_ENET_TD2_ENET1_RGMII_TD2 0x1f
+ MX8MM_IOMUXC_ENET_TD1_ENET1_RGMII_TD1 0x1f
+ MX8MM_IOMUXC_ENET_TD0_ENET1_RGMII_TD0 0x1f
+ MX8MM_IOMUXC_ENET_RD3_ENET1_RGMII_RD3 0x91
+ MX8MM_IOMUXC_ENET_RD2_ENET1_RGMII_RD2 0x91
+ MX8MM_IOMUXC_ENET_RD1_ENET1_RGMII_RD1 0x91
+ MX8MM_IOMUXC_ENET_RD0_ENET1_RGMII_RD0 0x91
+ MX8MM_IOMUXC_ENET_TXC_ENET1_RGMII_TXC 0x1f
+ MX8MM_IOMUXC_ENET_RXC_ENET1_RGMII_RXC 0x91
+ MX8MM_IOMUXC_ENET_RX_CTL_ENET1_RGMII_RX_CTL 0x91
+ MX8MM_IOMUXC_ENET_TX_CTL_ENET1_RGMII_TX_CTL 0x1f
+ MX8MM_IOMUXC_SAI2_TXFS_GPIO4_IO24 0x19 /* IRQ# */
+ MX8MM_IOMUXC_SAI2_TXC_GPIO4_IO25 0x19 /* RST# */
+ >;
+ };
+
+ pinctrl_gsc: gscgrp {
+ fsl,pins = <
+ MX8MM_IOMUXC_SAI2_TXD0_GPIO4_IO26 0x159
+ >;
+ };
+
+ pinctrl_i2c1: i2c1grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_I2C1_SCL_I2C1_SCL 0x400001c3
+ MX8MM_IOMUXC_I2C1_SDA_I2C1_SDA 0x400001c3
+ >;
+ };
+
+ pinctrl_i2c2: i2c2grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_I2C2_SCL_I2C2_SCL 0x400001c3
+ MX8MM_IOMUXC_I2C2_SDA_I2C2_SDA 0x400001c3
+ >;
+ };
+
+ pinctrl_i2c3: i2c3grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_I2C3_SCL_I2C3_SCL 0x400001c3
+ MX8MM_IOMUXC_I2C3_SDA_I2C3_SDA 0x400001c3
+ >;
+ };
+
+ pinctrl_gpio_leds: gpioledgrp {
+ fsl,pins = <
+ MX8MM_IOMUXC_SPDIF_EXT_CLK_GPIO5_IO5 0x19
+ MX8MM_IOMUXC_SAI3_RXD_GPIO4_IO30 0x19
+ MX8MM_IOMUXC_SAI3_MCLK_GPIO5_IO2 0x19
+ MX8MM_IOMUXC_GPIO1_IO14_GPIO1_IO14 0x19
+ MX8MM_IOMUXC_GPIO1_IO09_GPIO1_IO9 0x19
+ MX8MM_IOMUXC_SPDIF_TX_GPIO5_IO3 0x19
+ MX8MM_IOMUXC_SAI3_RXC_GPIO4_IO29 0x19
+ MX8MM_IOMUXC_SAI3_RXFS_GPIO4_IO28 0x19
+ MX8MM_IOMUXC_GPIO1_IO13_GPIO1_IO13 0x19
+ MX8MM_IOMUXC_SAI3_TXFS_GPIO4_IO31 0x19
+ MX8MM_IOMUXC_SPDIF_RX_GPIO5_IO4 0x19
+ MX8MM_IOMUXC_GPIO1_IO08_GPIO1_IO8 0x19
+ >;
+ };
+
+ pinctrl_pcie0: pciegrp {
+ fsl,pins = <
+ MX8MM_IOMUXC_ECSPI2_MOSI_GPIO5_IO11 0x41
+ >;
+ };
+
+ pinctrl_pmic: pmicgrp {
+ fsl,pins = <
+ MX8MM_IOMUXC_NAND_DATA02_GPIO3_IO8 0x41
+ >;
+ };
+
+ pinctrl_uart1: uart1grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_UART1_RXD_UART1_DCE_RX 0x140
+ MX8MM_IOMUXC_UART1_TXD_UART1_DCE_TX 0x140
+ MX8MM_IOMUXC_GPIO1_IO00_GPIO1_IO0 0x140
+ MX8MM_IOMUXC_GPIO1_IO01_GPIO1_IO1 0x140
+ MX8MM_IOMUXC_GPIO1_IO03_GPIO1_IO3 0x140
+ MX8MM_IOMUXC_GPIO1_IO05_GPIO1_IO5 0x140
+ MX8MM_IOMUXC_SAI5_RXD3_GPIO3_IO24 0x140
+ >;
+ };
+
+ pinctrl_uart2: uart2grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_UART2_RXD_UART2_DCE_RX 0x140
+ MX8MM_IOMUXC_UART2_TXD_UART2_DCE_TX 0x140
+ >;
+ };
+
+ 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
+ >;
+ };
+
+ 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
+ >;
+ };
+
+ pinctrl_usdhc2_200mhz: usdhc2-200mhzgrp {
+ fsl,pins = <
+ MX8MM_IOMUXC_SD2_CLK_USDHC2_CLK 0x196
+ MX8MM_IOMUXC_SD2_CMD_USDHC2_CMD 0x1d6
+ MX8MM_IOMUXC_SD2_DATA0_USDHC2_DATA0 0x1d6
+ MX8MM_IOMUXC_SD2_DATA1_USDHC2_DATA1 0x1d6
+ MX8MM_IOMUXC_SD2_DATA2_USDHC2_DATA2 0x1d6
+ MX8MM_IOMUXC_SD2_DATA3_USDHC2_DATA3 0x1d6
+ >;
+ };
+
+ pinctrl_usdhc2_gpio: usdhc2-gpiogrp {
+ fsl,pins = <
+ MX8MM_IOMUXC_SD2_CD_B_GPIO2_IO12 0x1c4
+ MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0x1d0
+ >;
+ };
+
+ pinctrl_usdhc3: usdhc3grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_NAND_WE_B_USDHC3_CLK 0x190
+ MX8MM_IOMUXC_NAND_WP_B_USDHC3_CMD 0x1d0
+ MX8MM_IOMUXC_NAND_DATA04_USDHC3_DATA0 0x1d0
+ MX8MM_IOMUXC_NAND_DATA05_USDHC3_DATA1 0x1d0
+ MX8MM_IOMUXC_NAND_DATA06_USDHC3_DATA2 0x1d0
+ MX8MM_IOMUXC_NAND_DATA07_USDHC3_DATA3 0x1d0
+ MX8MM_IOMUXC_NAND_RE_B_USDHC3_DATA4 0x1d0
+ MX8MM_IOMUXC_NAND_CE2_B_USDHC3_DATA5 0x1d0
+ MX8MM_IOMUXC_NAND_CE3_B_USDHC3_DATA6 0x1d0
+ MX8MM_IOMUXC_NAND_CLE_USDHC3_DATA7 0x1d0
+ MX8MM_IOMUXC_NAND_CE1_B_USDHC3_STROBE 0x190
+ >;
+ };
+
+ pinctrl_usdhc3_100mhz: usdhc3-100mhzgrp {
+ fsl,pins = <
+ MX8MM_IOMUXC_NAND_WE_B_USDHC3_CLK 0x194
+ MX8MM_IOMUXC_NAND_WP_B_USDHC3_CMD 0x1d4
+ MX8MM_IOMUXC_NAND_DATA04_USDHC3_DATA0 0x1d4
+ MX8MM_IOMUXC_NAND_DATA05_USDHC3_DATA1 0x1d4
+ MX8MM_IOMUXC_NAND_DATA06_USDHC3_DATA2 0x1d4
+ MX8MM_IOMUXC_NAND_DATA07_USDHC3_DATA3 0x1d4
+ MX8MM_IOMUXC_NAND_RE_B_USDHC3_DATA4 0x1d4
+ MX8MM_IOMUXC_NAND_CE2_B_USDHC3_DATA5 0x1d4
+ MX8MM_IOMUXC_NAND_CE3_B_USDHC3_DATA6 0x1d4
+ MX8MM_IOMUXC_NAND_CLE_USDHC3_DATA7 0x1d4
+ MX8MM_IOMUXC_NAND_CE1_B_USDHC3_STROBE 0x194
+ >;
+ };
+
+ pinctrl_usdhc3_200mhz: usdhc3-200mhzgrp {
+ fsl,pins = <
+ MX8MM_IOMUXC_NAND_WE_B_USDHC3_CLK 0x196
+ MX8MM_IOMUXC_NAND_WP_B_USDHC3_CMD 0x1d6
+ MX8MM_IOMUXC_NAND_DATA04_USDHC3_DATA0 0x1d6
+ MX8MM_IOMUXC_NAND_DATA05_USDHC3_DATA1 0x1d6
+ MX8MM_IOMUXC_NAND_DATA06_USDHC3_DATA2 0x1d6
+ MX8MM_IOMUXC_NAND_DATA07_USDHC3_DATA3 0x1d6
+ MX8MM_IOMUXC_NAND_RE_B_USDHC3_DATA4 0x1d6
+ MX8MM_IOMUXC_NAND_CE2_B_USDHC3_DATA5 0x1d6
+ MX8MM_IOMUXC_NAND_CE3_B_USDHC3_DATA6 0x1d6
+ MX8MM_IOMUXC_NAND_CLE_USDHC3_DATA7 0x1d6
+ MX8MM_IOMUXC_NAND_CE1_B_USDHC3_STROBE 0x196
+ >;
+ };
+
+ pinctrl_wdog: wdoggrp {
+ fsl,pins = <
+ MX8MM_IOMUXC_GPIO1_IO02_WDOG1_WDOG_B 0xc6
+ >;
+ };
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-verdin-dahlia.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-verdin-dahlia.dtsi
new file mode 100644
index 000000000000..aca5ae0d307d
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8mm-verdin-dahlia.dtsi
@@ -0,0 +1,150 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+/*
+ * Copyright 2022 Toradex
+ */
+
+/ {
+ sound_card: sound-card {
+ compatible = "simple-audio-card";
+ simple-audio-card,bitclock-master = <&dailink_master>;
+ simple-audio-card,format = "i2s";
+ simple-audio-card,frame-master = <&dailink_master>;
+ simple-audio-card,name = "imx8mm-wm8904";
+ simple-audio-card,routing =
+ "Headphone Jack", "HPOUTL",
+ "Headphone Jack", "HPOUTR",
+ "IN2L", "Line In Jack",
+ "IN2R", "Line In Jack",
+ "Headphone Jack", "MICBIAS",
+ "IN1L", "Headphone Jack";
+ simple-audio-card,widgets =
+ "Microphone", "Headphone Jack",
+ "Headphone", "Headphone Jack",
+ "Line", "Line In Jack";
+
+ dailink_master: simple-audio-card,codec {
+ clocks = <&clk IMX8MM_CLK_SAI2_ROOT>;
+ sound-dai = <&wm8904_1a>;
+ };
+
+ simple-audio-card,cpu {
+ sound-dai = <&sai2>;
+ };
+ };
+};
+
+/* Verdin SPI_1 */
+&ecspi2 {
+ status = "okay";
+};
+
+/* EEPROM on display adapter boards */
+&eeprom_display_adapter {
+ status = "okay";
+};
+
+/* EEPROM on Verdin Development board */
+&eeprom_carrier_board {
+ status = "okay";
+};
+
+&fec1 {
+ status = "okay";
+};
+
+/* Verdin QSPI_1 */
+&flexspi {
+ status = "okay";
+};
+
+/* Current measurement into module VCC */
+&hwmon {
+ status = "okay";
+};
+
+&hwmon_temp {
+ vs-supply = <&reg_1p8v>;
+ status = "okay";
+};
+
+&i2c3 {
+ status = "okay";
+};
+
+/* Verdin I2C_1 */
+&i2c4 {
+ status = "okay";
+
+ /* Audio Codec */
+ wm8904_1a: audio-codec@1a {
+ compatible = "wlf,wm8904";
+ AVDD-supply = <&reg_3p3v>;
+ clocks = <&clk IMX8MM_CLK_SAI2_ROOT>;
+ clock-names = "mclk";
+ CPVDD-supply = <&reg_3p3v>;
+ DBVDD-supply = <&reg_3p3v>;
+ DCVDD-supply = <&reg_3p3v>;
+ MICVDD-supply = <&reg_3p3v>;
+ reg = <0x1a>;
+ #sound-dai-cells = <0>;
+ };
+};
+
+/* Verdin PCIE_1 */
+&pcie0 {
+ status = "okay";
+};
+
+&pcie_phy {
+ status = "okay";
+};
+
+/* Verdin PWM_3_DSI */
+&pwm1 {
+ status = "okay";
+};
+
+/* Verdin PWM_1 */
+&pwm2 {
+ status = "okay";
+};
+
+/* Verdin PWM_2 */
+&pwm3 {
+ status = "okay";
+};
+
+/* VERDIN I2S_1 */
+&sai2 {
+ status = "okay";
+};
+
+/* Verdin UART_3 */
+&uart1 {
+ status = "okay";
+};
+
+/* Verdin UART_1 */
+&uart2 {
+ status = "okay";
+};
+
+/* Verdin UART_2 */
+&uart3 {
+ status = "okay";
+};
+
+/* Verdin USB_1 */
+&usbotg1 {
+ status = "okay";
+};
+
+/* Verdin USB_2 */
+&usbotg2 {
+ status = "okay";
+};
+
+/* Verdin SD_1 */
+&usdhc2 {
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-verdin-dev.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-verdin-dev.dtsi
new file mode 100644
index 000000000000..73cc3fafa018
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8mm-verdin-dev.dtsi
@@ -0,0 +1,67 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+/*
+ * Copyright 2022 Toradex
+ */
+
+#include "imx8mm-verdin-dahlia.dtsi"
+
+/ {
+ sound_card: sound-card {
+ compatible = "simple-audio-card";
+ simple-audio-card,bitclock-master = <&dailink_master>;
+ simple-audio-card,format = "i2s";
+ simple-audio-card,frame-master = <&dailink_master>;
+ simple-audio-card,name = "imx8mm-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";
+
+ dailink_master: simple-audio-card,codec {
+ clocks = <&clk IMX8MM_CLK_SAI2_ROOT>;
+ sound-dai = <&nau8822_1a>;
+ };
+
+ simple-audio-card,cpu {
+ sound-dai = <&sai2>;
+ };
+ };
+};
+
+&gpio_expander_21 {
+ status = "okay";
+};
+
+/* Verdin I2C_1 */
+&i2c4 {
+ /* Audio Codec */
+ nau8822_1a: audio-codec@1a {
+ compatible = "nuvoton,nau8822";
+ reg = <0x1a>;
+ };
+};
+
+/* Verdin UART_1, connector X50 through RS485 transceiver */
+&uart2 {
+ linux,rs485-enabled-at-boot-time;
+ rs485-rts-active-low;
+ rs485-rx-during-tx;
+};
+
+/* Limit frequency on dev board due to long traces and bad signal integrity */
+&usdhc2 {
+ max-frequency = <100000000>;
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-verdin-nonwifi-dahlia.dts b/arch/arm64/boot/dts/freescale/imx8mm-verdin-nonwifi-dahlia.dts
new file mode 100644
index 000000000000..d64ff378a152
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8mm-verdin-nonwifi-dahlia.dts
@@ -0,0 +1,18 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+/*
+ * Copyright 2022 Toradex
+ */
+
+/dts-v1/;
+
+#include "imx8mm-verdin.dtsi"
+#include "imx8mm-verdin-nonwifi.dtsi"
+#include "imx8mm-verdin-dahlia.dtsi"
+
+/ {
+ model = "Toradex Verdin iMX8M Mini on Dahlia Board";
+ compatible = "toradex,verdin-imx8mm-nonwifi-dahlia",
+ "toradex,verdin-imx8mm-nonwifi",
+ "toradex,verdin-imx8mm",
+ "fsl,imx8mm";
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-verdin-nonwifi-dev.dts b/arch/arm64/boot/dts/freescale/imx8mm-verdin-nonwifi-dev.dts
new file mode 100644
index 000000000000..6ae71ecac8de
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8mm-verdin-nonwifi-dev.dts
@@ -0,0 +1,18 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+/*
+ * Copyright 2022 Toradex
+ */
+
+/dts-v1/;
+
+#include "imx8mm-verdin.dtsi"
+#include "imx8mm-verdin-nonwifi.dtsi"
+#include "imx8mm-verdin-dev.dtsi"
+
+/ {
+ model = "Toradex Verdin iMX8M Mini on Verdin Development Board";
+ compatible = "toradex,verdin-imx8mm-nonwifi-dev",
+ "toradex,verdin-imx8mm-nonwifi",
+ "toradex,verdin-imx8mm",
+ "fsl,imx8mm";
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-verdin-nonwifi.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-verdin-nonwifi.dtsi
new file mode 100644
index 000000000000..1e0f87c7a609
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8mm-verdin-nonwifi.dtsi
@@ -0,0 +1,75 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+/*
+ * Copyright 2022 Toradex
+ */
+
+&gpio3 {
+ gpio-line-names = "SODIMM_52",
+ "SODIMM_54",
+ "SODIMM_64",
+ "SODIMM_21",
+ "SODIMM_206",
+ "SODIMM_76",
+ "SODIMM_56",
+ "SODIMM_58",
+ "SODIMM_60",
+ "SODIMM_62",
+ "SODIMM_162",
+ "SODIMM_164",
+ "SODIMM_166",
+ "SODIMM_168",
+ "SODIMM_66",
+ "SODIMM_17",
+ "",
+ "SODIMM_156",
+ "SODIMM_160",
+ "SODIMM_244",
+ "",
+ "SODIMM_48",
+ "SODIMM_44",
+ "SODIMM_42",
+ "SODIMM_46";
+};
+
+&gpio4 {
+ gpio-line-names = "SODIMM_102",
+ "SODIMM_90",
+ "SODIMM_92",
+ "SODIMM_94",
+ "SODIMM_96",
+ "SODIMM_100",
+ "SODIMM_148",
+ "SODIMM_152",
+ "SODIMM_154",
+ "SODIMM_174",
+ "SODIMM_120",
+ "SODIMM_104",
+ "SODIMM_106",
+ "SODIMM_108",
+ "SODIMM_112",
+ "SODIMM_114",
+ "SODIMM_116",
+ "SODIMM_150",
+ "SODIMM_118",
+ "",
+ "SODIMM_88",
+ "SODIMM_149",
+ "SODIMM_147",
+ "SODIMM_36",
+ "SODIMM_32",
+ "SODIMM_30",
+ "SODIMM_34",
+ "SODIMM_38",
+ "SODIMM_252",
+ "SODIMM_133",
+ "SODIMM_135",
+ "SODIMM_129";
+};
+
+&usdhc3 {
+ bus-width = <4>;
+ pinctrl-names = "default", "state_100mhz", "state_200mhz";
+ pinctrl-0 = <&pinctrl_usdhc3>;
+ pinctrl-1 = <&pinctrl_usdhc3_100mhz>;
+ pinctrl-2 = <&pinctrl_usdhc3_200mhz>;
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-verdin-wifi-dahlia.dts b/arch/arm64/boot/dts/freescale/imx8mm-verdin-wifi-dahlia.dts
new file mode 100644
index 000000000000..d424c475cba1
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8mm-verdin-wifi-dahlia.dts
@@ -0,0 +1,18 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+/*
+ * Copyright 2022 Toradex
+ */
+
+/dts-v1/;
+
+#include "imx8mm-verdin.dtsi"
+#include "imx8mm-verdin-wifi.dtsi"
+#include "imx8mm-verdin-dahlia.dtsi"
+
+/ {
+ model = "Toradex Verdin iMX8M Mini WB on Dahlia Board";
+ compatible = "toradex,verdin-imx8mm-wifi-dahlia",
+ "toradex,verdin-imx8mm-wifi",
+ "toradex,verdin-imx8mm",
+ "fsl,imx8mm";
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-verdin-wifi-dev.dts b/arch/arm64/boot/dts/freescale/imx8mm-verdin-wifi-dev.dts
new file mode 100644
index 000000000000..ef952021832e
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8mm-verdin-wifi-dev.dts
@@ -0,0 +1,18 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+/*
+ * Copyright 2022 Toradex
+ */
+
+/dts-v1/;
+
+#include "imx8mm-verdin.dtsi"
+#include "imx8mm-verdin-wifi.dtsi"
+#include "imx8mm-verdin-dev.dtsi"
+
+/ {
+ model = "Toradex Verdin iMX8M Mini WB on Verdin Development Board";
+ compatible = "toradex,verdin-imx8mm-wifi-dev",
+ "toradex,verdin-imx8mm-wifi",
+ "toradex,verdin-imx8mm",
+ "fsl,imx8mm";
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-verdin-wifi.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-verdin-wifi.dtsi
new file mode 100644
index 000000000000..3e06a6ce3406
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8mm-verdin-wifi.dtsi
@@ -0,0 +1,94 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+/*
+ * Copyright 2022 Toradex
+ */
+
+/ {
+ reg_wifi_en: regulator-wifi-en {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ gpio = <&gpio3 25 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_wifi_pwr_en>;
+ regulator-max-microvolt = <3300000>;
+ regulator-min-microvolt = <3300000>;
+ regulator-name = "PDn_AW-CM276NF";
+ startup-delay-us = <2000>;
+ };
+};
+
+/* On-module Wi-Fi */
+&usdhc3 {
+ bus-width = <4>;
+ keep-power-in-suspend;
+ non-removable;
+ pinctrl-names = "default", "state_100mhz", "state_200mhz";
+ pinctrl-0 = <&pinctrl_usdhc3>, <&pinctrl_wifi_ctrl>;
+ pinctrl-1 = <&pinctrl_usdhc3_100mhz>, <&pinctrl_wifi_ctrl>;
+ pinctrl-2 = <&pinctrl_usdhc3_200mhz>, <&pinctrl_wifi_ctrl>;
+ vmmc-supply = <&reg_wifi_en>;
+ status = "okay";
+};
+
+&gpio3 {
+ gpio-line-names = "SODIMM_52",
+ "SODIMM_54",
+ "SODIMM_64",
+ "SODIMM_21",
+ "SODIMM_206",
+ "SODIMM_76",
+ "SODIMM_56",
+ "SODIMM_58",
+ "SODIMM_60",
+ "SODIMM_62",
+ "",
+ "",
+ "",
+ "",
+ "SODIMM_66",
+ "SODIMM_17",
+ "",
+ "",
+ "",
+ "SODIMM_244",
+ "",
+ "SODIMM_48",
+ "SODIMM_44",
+ "SODIMM_42",
+ "SODIMM_46";
+};
+
+&gpio4 {
+ gpio-line-names = "SODIMM_102",
+ "SODIMM_90",
+ "SODIMM_92",
+ "SODIMM_94",
+ "SODIMM_96",
+ "SODIMM_100",
+ "",
+ "",
+ "",
+ "",
+ "SODIMM_120",
+ "SODIMM_104",
+ "SODIMM_106",
+ "SODIMM_108",
+ "SODIMM_112",
+ "SODIMM_114",
+ "SODIMM_116",
+ "",
+ "SODIMM_118",
+ "",
+ "SODIMM_88",
+ "SODIMM_149",
+ "SODIMM_147",
+ "SODIMM_36",
+ "SODIMM_32",
+ "SODIMM_30",
+ "SODIMM_34",
+ "SODIMM_38",
+ "SODIMM_252",
+ "SODIMM_133",
+ "SODIMM_135",
+ "SODIMM_129";
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-verdin.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-verdin.dtsi
new file mode 100644
index 000000000000..0d84d29e70f1
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8mm-verdin.dtsi
@@ -0,0 +1,1264 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+/*
+ * Copyright 2022 Toradex
+ */
+
+#include "dt-bindings/phy/phy-imx8-pcie.h"
+#include "dt-bindings/pwm/pwm.h"
+#include "imx8mm.dtsi"
+
+/ {
+ chosen {
+ stdout-path = &uart1;
+ };
+
+ aliases {
+ rtc0 = &rtc_i2c;
+ rtc1 = &snvs_rtc;
+ };
+
+ backlight: backlight {
+ compatible = "pwm-backlight";
+ brightness-levels = <0 45 63 88 119 158 203 255>;
+ default-brightness-level = <4>;
+ /* Verdin I2S_2_D_OUT (DSI_1_BKL_EN/DSI_1_BKL_EN_LVDS, SODIMM 46) */
+ enable-gpios = <&gpio3 24 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2s_2_d_out_dsi_1_bkl_en>;
+ power-supply = <&reg_3p3v>;
+ /* Verdin PWM_3_DSI/PWM_3_DSI_LVDS (SODIMM 19) */
+ pwms = <&pwm1 0 6666667 PWM_POLARITY_INVERTED>;
+ status = "disabled";
+ };
+
+ /* Fixed clock dedicated to SPI CAN controller */
+ clk20m: oscillator {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <20000000>;
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpio_keys>;
+
+ wakeup {
+ debounce-interval = <10>;
+ /* Verdin CTRL_WAKE1_MICO# (SODIMM 252) */
+ gpios = <&gpio4 28 GPIO_ACTIVE_LOW>;
+ label = "Wake-Up";
+ linux,code = <KEY_WAKEUP>;
+ wakeup-source;
+ };
+ };
+
+ /* Carrier Board Supplies */
+ reg_1p8v: regulator-1p8v {
+ compatible = "regulator-fixed";
+ regulator-max-microvolt = <1800000>;
+ regulator-min-microvolt = <1800000>;
+ regulator-name = "+V1.8_SW";
+ };
+
+ reg_3p3v: regulator-3p3v {
+ compatible = "regulator-fixed";
+ regulator-max-microvolt = <3300000>;
+ regulator-min-microvolt = <3300000>;
+ regulator-name = "+V3.3_SW";
+ };
+
+ reg_5p0v: regulator-5p0v {
+ compatible = "regulator-fixed";
+ regulator-max-microvolt = <5000000>;
+ regulator-min-microvolt = <5000000>;
+ regulator-name = "+V5_SW";
+ };
+
+ /* Non PMIC On-module Supplies */
+ reg_ethphy: regulator-ethphy {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ gpio = <&gpio2 20 GPIO_ACTIVE_HIGH>; /* PMIC_EN_ETH */
+ off-on-delay = <500000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_reg_eth>;
+ regulator-boot-on;
+ regulator-max-microvolt = <3300000>;
+ regulator-min-microvolt = <3300000>;
+ regulator-name = "+V3.3_ETH";
+ startup-delay-us = <200000>;
+ };
+
+ reg_usb_otg1_vbus: regulator-usb-otg1 {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ /* Verdin USB_1_EN (SODIMM 155) */
+ gpio = <&gpio1 12 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_reg_usb1_en>;
+ regulator-max-microvolt = <5000000>;
+ regulator-min-microvolt = <5000000>;
+ regulator-name = "usb_otg1_vbus";
+ };
+
+ reg_usb_otg2_vbus: regulator-usb-otg2 {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ /* Verdin USB_2_EN (SODIMM 185) */
+ gpio = <&gpio1 14 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_reg_usb2_en>;
+ regulator-max-microvolt = <5000000>;
+ regulator-min-microvolt = <5000000>;
+ regulator-name = "usb_otg2_vbus";
+ };
+
+ reg_usdhc2_vmmc: regulator-usdhc2 {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ /* Verdin SD_1_PWR_EN (SODIMM 76) */
+ gpio = <&gpio3 5 GPIO_ACTIVE_HIGH>;
+ off-on-delay = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usdhc2_pwr_en>;
+ regulator-max-microvolt = <3300000>;
+ regulator-min-microvolt = <3300000>;
+ regulator-name = "+V3.3_SD";
+ startup-delay-us = <2000>;
+ };
+
+ reserved-memory {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ /* Use the kernel configuration settings instead */
+ /delete-node/ linux,cma;
+ };
+};
+
+&A53_0 {
+ cpu-supply = <&reg_vdd_arm>;
+};
+
+&A53_1 {
+ cpu-supply = <&reg_vdd_arm>;
+};
+
+&A53_2 {
+ cpu-supply = <&reg_vdd_arm>;
+};
+
+&A53_3 {
+ cpu-supply = <&reg_vdd_arm>;
+};
+
+&ddrc {
+ operating-points-v2 = <&ddrc_opp_table>;
+
+ ddrc_opp_table: opp-table {
+ compatible = "operating-points-v2";
+
+ opp-25M {
+ opp-hz = /bits/ 64 <25000000>;
+ };
+
+ opp-100M {
+ opp-hz = /bits/ 64 <100000000>;
+ };
+
+ opp-750M {
+ opp-hz = /bits/ 64 <750000000>;
+ };
+ };
+};
+
+/* Verdin SPI_1 */
+&ecspi2 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ cs-gpios = <&gpio5 13 GPIO_ACTIVE_LOW>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_ecspi2>;
+};
+
+/* Verdin CAN_1 (On-module) */
+&ecspi3 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ cs-gpios = <&gpio5 25 GPIO_ACTIVE_LOW>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_ecspi3>;
+ status = "okay";
+
+ can1: can@0 {
+ compatible = "microchip,mcp251xfd";
+ clocks = <&clk20m>;
+ interrupts-extended = <&gpio1 6 IRQ_TYPE_EDGE_FALLING>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_can1_int>;
+ reg = <0>;
+ spi-max-frequency = <8500000>;
+ };
+};
+
+/* Verdin ETH_1 (On-module PHY) */
+&fec1 {
+ fsl,magic-packet;
+ phy-handle = <&ethphy0>;
+ phy-mode = "rgmii-id";
+ phy-supply = <&reg_ethphy>;
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&pinctrl_fec1>;
+ pinctrl-1 = <&pinctrl_fec1_sleep>;
+
+ mdio {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ ethphy0: ethernet-phy@7 {
+ compatible = "ethernet-phy-ieee802.3-c22";
+ interrupt-parent = <&gpio1>;
+ interrupts = <10 IRQ_TYPE_LEVEL_LOW>;
+ micrel,led-mode = <0>;
+ reg = <7>;
+ };
+ };
+};
+
+/* Verdin QSPI_1 */
+&flexspi {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_flexspi0>;
+};
+
+&gpio1 {
+ gpio-line-names = "SODIMM_216",
+ "SODIMM_19",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "SODIMM_220",
+ "SODIMM_222",
+ "",
+ "SODIMM_218",
+ "SODIMM_155",
+ "SODIMM_157",
+ "SODIMM_185",
+ "SODIMM_187";
+};
+
+&gpio2 {
+ gpio-line-names = "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "SODIMM_84",
+ "SODIMM_78",
+ "SODIMM_74",
+ "SODIMM_80",
+ "SODIMM_82",
+ "SODIMM_70",
+ "SODIMM_72";
+};
+
+&gpio5 {
+ gpio-line-names = "SODIMM_131",
+ "",
+ "SODIMM_91",
+ "SODIMM_16",
+ "SODIMM_15",
+ "SODIMM_208",
+ "SODIMM_137",
+ "SODIMM_139",
+ "SODIMM_141",
+ "SODIMM_143",
+ "SODIMM_196",
+ "SODIMM_200",
+ "SODIMM_198",
+ "SODIMM_202",
+ "",
+ "",
+ "SODIMM_55",
+ "SODIMM_53",
+ "SODIMM_95",
+ "SODIMM_93",
+ "SODIMM_14",
+ "SODIMM_12",
+ "",
+ "",
+ "",
+ "",
+ "SODIMM_210",
+ "SODIMM_212",
+ "SODIMM_151",
+ "SODIMM_153";
+
+ ctrl_sleep_moci-hog {
+ gpio-hog;
+ /* Verdin CTRL_SLEEP_MOCI# (SODIMM 256) */
+ gpios = <1 GPIO_ACTIVE_HIGH>;
+ line-name = "CTRL_SLEEP_MOCI#";
+ output-high;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_ctrl_sleep_moci>;
+ };
+};
+
+/* On-module I2C */
+&i2c1 {
+ clock-frequency = <400000>;
+ pinctrl-names = "default", "gpio";
+ pinctrl-0 = <&pinctrl_i2c1>;
+ pinctrl-1 = <&pinctrl_i2c1_gpio>;
+ scl-gpios = <&gpio5 14 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+ sda-gpios = <&gpio5 15 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+ status = "okay";
+
+ pca9450: pmic@25 {
+ compatible = "nxp,pca9450a";
+ interrupt-parent = <&gpio1>;
+ /* PMIC PCA9450 PMIC_nINT GPIO1_IO3 */
+ interrupts = <3 IRQ_TYPE_LEVEL_LOW>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pmic>;
+ reg = <0x25>;
+ sd-vsel-gpios = <&gpio1 4 GPIO_ACTIVE_HIGH>;
+
+ regulators {
+ reg_vdd_soc: BUCK1 {
+ nxp,dvs-run-voltage = <850000>;
+ nxp,dvs-standby-voltage = <800000>;
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-max-microvolt = <850000>;
+ regulator-min-microvolt = <800000>;
+ regulator-name = "+VDD_SOC";
+ regulator-ramp-delay = <3125>;
+ };
+
+ reg_vdd_arm: BUCK2 {
+ nxp,dvs-run-voltage = <950000>;
+ nxp,dvs-standby-voltage = <850000>;
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-max-microvolt = <950000>;
+ regulator-min-microvolt = <850000>;
+ regulator-name = "+VDD_ARM";
+ regulator-ramp-delay = <3125>;
+ };
+
+ reg_vdd_dram: BUCK3 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-max-microvolt = <950000>;
+ regulator-min-microvolt = <850000>;
+ regulator-name = "+VDD_GPU_VPU_DDR";
+ };
+
+ reg_vdd_3v3: BUCK4 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-max-microvolt = <3300000>;
+ regulator-min-microvolt = <3300000>;
+ regulator-name = "+V3.3";
+ };
+
+ reg_vdd_1v8: BUCK5 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-max-microvolt = <1800000>;
+ regulator-min-microvolt = <1800000>;
+ regulator-name = "PWR_1V8_MOCI";
+ };
+
+ reg_nvcc_dram: BUCK6 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-max-microvolt = <1100000>;
+ regulator-min-microvolt = <1100000>;
+ regulator-name = "+VDD_DDR";
+ };
+
+ reg_nvcc_snvs: LDO1 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-max-microvolt = <1800000>;
+ regulator-min-microvolt = <1800000>;
+ regulator-name = "+V1.8_SNVS";
+ };
+
+ reg_vdd_snvs: LDO2 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-max-microvolt = <900000>;
+ regulator-min-microvolt = <800000>;
+ regulator-name = "+V0.8_SNVS";
+ };
+
+ reg_vdda: LDO3 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-max-microvolt = <1800000>;
+ regulator-min-microvolt = <1800000>;
+ regulator-name = "+V1.8A";
+ };
+
+ reg_vdd_phy: LDO4 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-max-microvolt = <900000>;
+ regulator-min-microvolt = <900000>;
+ regulator-name = "+V0.9_MIPI";
+ };
+
+ reg_nvcc_sd: LDO5 {
+ regulator-max-microvolt = <3300000>;
+ regulator-min-microvolt = <1800000>;
+ regulator-name = "+V3.3_1.8_SD";
+ };
+ };
+ };
+
+ rtc_i2c: rtc@32 {
+ compatible = "epson,rx8130";
+ reg = <0x32>;
+ };
+
+ adc@49 {
+ compatible = "ti,ads1015";
+ reg = <0x49>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ /* Verdin I2C_1 (ADC_4 - ADC_3) */
+ channel@0 {
+ reg = <0>;
+ ti,datarate = <4>;
+ ti,gain = <2>;
+ };
+
+ /* Verdin I2C_1 (ADC_4 - ADC_1) */
+ channel@1 {
+ reg = <1>;
+ ti,datarate = <4>;
+ ti,gain = <2>;
+ };
+
+ /* Verdin I2C_1 (ADC_3 - ADC_1) */
+ channel@2 {
+ reg = <2>;
+ ti,datarate = <4>;
+ ti,gain = <2>;
+ };
+
+ /* Verdin I2C_1 (ADC_2 - ADC_1) */
+ channel@3 {
+ reg = <3>;
+ ti,datarate = <4>;
+ ti,gain = <2>;
+ };
+
+ /* Verdin I2C_1 ADC_4 */
+ channel@4 {
+ reg = <4>;
+ ti,datarate = <4>;
+ ti,gain = <2>;
+ };
+
+ /* Verdin I2C_1 ADC_3 */
+ channel@5 {
+ reg = <5>;
+ ti,datarate = <4>;
+ ti,gain = <2>;
+ };
+
+ /* Verdin I2C_1 ADC_2 */
+ channel@6 {
+ reg = <6>;
+ ti,datarate = <4>;
+ ti,gain = <2>;
+ };
+
+ /* Verdin I2C_1 ADC_1 */
+ channel@7 {
+ reg = <7>;
+ ti,datarate = <4>;
+ ti,gain = <2>;
+ };
+ };
+
+ eeprom@50 {
+ compatible = "st,24c02";
+ pagesize = <16>;
+ reg = <0x50>;
+ };
+};
+
+/* Verdin I2C_2_DSI */
+&i2c2 {
+ clock-frequency = <10000>;
+ pinctrl-names = "default", "gpio";
+ pinctrl-0 = <&pinctrl_i2c2>;
+ pinctrl-1 = <&pinctrl_i2c2_gpio>;
+ scl-gpios = <&gpio5 16 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+ sda-gpios = <&gpio5 17 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+ status = "disabled";
+};
+
+/* Verdin I2C_3_HDMI N/A */
+
+/* Verdin I2C_4_CSI */
+&i2c3 {
+ clock-frequency = <400000>;
+ pinctrl-names = "default", "gpio";
+ pinctrl-0 = <&pinctrl_i2c3>;
+ pinctrl-1 = <&pinctrl_i2c3_gpio>;
+ scl-gpios = <&gpio5 18 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+ sda-gpios = <&gpio5 19 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+};
+
+/* Verdin I2C_1 */
+&i2c4 {
+ clock-frequency = <400000>;
+ pinctrl-names = "default", "gpio";
+ pinctrl-0 = <&pinctrl_i2c4>;
+ pinctrl-1 = <&pinctrl_i2c4_gpio>;
+ scl-gpios = <&gpio5 20 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+ sda-gpios = <&gpio5 21 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+
+ gpio_expander_21: gpio-expander@21 {
+ compatible = "nxp,pcal6416";
+ #gpio-cells = <2>;
+ gpio-controller;
+ reg = <0x21>;
+ vcc-supply = <&reg_3p3v>;
+ status = "disabled";
+ };
+
+ lvds_ti_sn65dsi83: bridge@2c {
+ compatible = "ti,sn65dsi83";
+ /* Verdin GPIO_9_DSI (SN65DSI84 IRQ, SODIMM 17, unused) */
+ /* Verdin GPIO_10_DSI (SODIMM 21) */
+ enable-gpios = <&gpio3 3 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpio_10_dsi>;
+ reg = <0x2c>;
+ status = "disabled";
+ };
+
+ /* Current measurement into module VCC */
+ hwmon: hwmon@40 {
+ compatible = "ti,ina219";
+ reg = <0x40>;
+ shunt-resistor = <10000>;
+ status = "disabled";
+ };
+
+ hdmi_lontium_lt8912: hdmi@48 {
+ compatible = "lontium,lt8912b";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpio_10_dsi>, <&pinctrl_pwm_3_dsi_hpd_gpio>;
+ reg = <0x48>;
+ /* Verdin GPIO_9_DSI (LT8912 INT, SODIMM 17, unused) */
+ /* Verdin GPIO_10_DSI (SODIMM 21) */
+ reset-gpios = <&gpio3 3 GPIO_ACTIVE_LOW>;
+ status = "disabled";
+ };
+
+ atmel_mxt_ts: touch@4a {
+ compatible = "atmel,maxtouch";
+ /* Verdin GPIO_9_DSI */
+ /* (TOUCH_INT#, SODIMM 17, also routed to SN65dsi83 IRQ albeit currently unused) */
+ interrupt-parent = <&gpio3>;
+ interrupts = <15 IRQ_TYPE_EDGE_FALLING>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpio_9_dsi>, <&pinctrl_i2s_2_bclk_touch_reset>;
+ reg = <0x4a>;
+ /* Verdin I2S_2_BCLK (TOUCH_RESET#, SODIMM 42) */
+ reset-gpios = <&gpio3 23 GPIO_ACTIVE_HIGH>;
+ status = "disabled";
+ };
+
+ /* Temperature sensor on carrier board */
+ hwmon_temp: sensor@4f {
+ compatible = "ti,tmp75c";
+ reg = <0x4f>;
+ status = "disabled";
+ };
+
+ /* EEPROM on display adapter (MIPI DSI Display Adapter) */
+ eeprom_display_adapter: eeprom@50 {
+ compatible = "st,24c02";
+ pagesize = <16>;
+ reg = <0x50>;
+ status = "disabled";
+ };
+
+ /* EEPROM on carrier board */
+ eeprom_carrier_board: eeprom@57 {
+ compatible = "st,24c02";
+ pagesize = <16>;
+ reg = <0x57>;
+ status = "disabled";
+ };
+};
+
+/* Verdin PCIE_1 */
+&pcie0 {
+ assigned-clocks = <&clk IMX8MM_CLK_PCIE1_AUX>,
+ <&clk IMX8MM_CLK_PCIE1_CTRL>;
+ assigned-clock-parents = <&clk IMX8MM_SYS_PLL2_50M>,
+ <&clk IMX8MM_SYS_PLL2_250M>;
+ assigned-clock-rates = <10000000>, <250000000>;
+ clocks = <&clk IMX8MM_CLK_PCIE1_ROOT>, <&clk IMX8MM_CLK_PCIE1_AUX>,
+ <&clk IMX8MM_CLK_PCIE1_PHY>;
+ clock-names = "pcie", "pcie_aux", "pcie_bus";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pcie0>;
+ /* PCIE_1_RESET# (SODIMM 244) */
+ reset-gpio = <&gpio3 19 GPIO_ACTIVE_LOW>;
+};
+
+&pcie_phy {
+ clocks = <&clk IMX8MM_CLK_PCIE1_PHY>;
+ fsl,clkreq-unsupported;
+ fsl,refclk-pad-mode = <IMX8_PCIE_REFCLK_PAD_OUTPUT>;
+ fsl,tx-deemph-gen1 = <0x2d>;
+ fsl,tx-deemph-gen2 = <0xf>;
+};
+
+/* Verdin PWM_3_DSI */
+&pwm1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pwm_1>;
+ #pwm-cells = <3>;
+};
+
+/* Verdin PWM_1 */
+&pwm2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pwm_2>;
+ #pwm-cells = <3>;
+};
+
+/* Verdin PWM_2 */
+&pwm3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pwm_3>;
+ #pwm-cells = <3>;
+};
+
+/* VERDIN I2S_1 */
+&sai2 {
+ #sound-dai-cells = <0>;
+ assigned-clock-parents = <&clk IMX8MM_AUDIO_PLL1_OUT>;
+ assigned-clock-rates = <24576000>;
+ assigned-clocks = <&clk IMX8MM_CLK_SAI2>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_sai2>;
+};
+
+&snvs_pwrkey {
+ status = "okay";
+};
+
+/* Verdin UART_3, used as the Linux console */
+&uart1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart1>;
+};
+
+/* Verdin UART_1 */
+&uart2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart2>;
+ uart-has-rtscts;
+};
+
+/* Verdin UART_2 */
+&uart3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart3>;
+ uart-has-rtscts;
+};
+
+/* Verdin UART_4 */
+/*
+ * Resource allocated to M4 by default, must not be accessed from Cortex-A35 or you get an OOPS
+ */
+&uart4 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart4>;
+};
+
+/* Verdin USB_1 */
+&usbotg1 {
+ adp-disable;
+ dr_mode = "otg";
+ hnp-disable;
+ over-current-active-low;
+ samsung,picophy-dc-vol-level-adjust = <7>;
+ samsung,picophy-pre-emp-curr-control = <3>;
+ srp-disable;
+ vbus-supply = <&reg_usb_otg1_vbus>;
+};
+
+/* Verdin USB_2 */
+&usbotg2 {
+ dr_mode = "host";
+ over-current-active-low;
+ samsung,picophy-dc-vol-level-adjust = <7>;
+ samsung,picophy-pre-emp-curr-control = <3>;
+ vbus-supply = <&reg_usb_otg2_vbus>;
+};
+
+&usbphynop1 {
+ vcc-supply = <&reg_vdd_3v3>;
+};
+
+&usbphynop2 {
+ vcc-supply = <&reg_vdd_3v3>;
+};
+
+/* On-module eMMC */
+&usdhc1 {
+ bus-width = <8>;
+ keep-power-in-suspend;
+ non-removable;
+ pinctrl-names = "default", "state_100mhz", "state_200mhz";
+ pinctrl-0 = <&pinctrl_usdhc1>;
+ pinctrl-1 = <&pinctrl_usdhc1_100mhz>;
+ pinctrl-2 = <&pinctrl_usdhc1_200mhz>;
+ status = "okay";
+};
+
+/* Verdin SD_1 */
+&usdhc2 {
+ bus-width = <4>;
+ cd-gpios = <&gpio2 12 GPIO_ACTIVE_LOW>;
+ disable-wp;
+ pinctrl-names = "default", "state_100mhz", "state_200mhz";
+ pinctrl-0 = <&pinctrl_usdhc2>, <&pinctrl_usdhc2_cd>;
+ pinctrl-1 = <&pinctrl_usdhc2_100mhz>, <&pinctrl_usdhc2_cd>;
+ pinctrl-2 = <&pinctrl_usdhc2_200mhz>, <&pinctrl_usdhc2_cd>;
+ vmmc-supply = <&reg_usdhc2_vmmc>;
+};
+
+&wdog1 {
+ fsl,ext-reset-output;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_wdog>;
+ status = "okay";
+};
+
+&iomuxc {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpio1>, <&pinctrl_gpio2>,
+ <&pinctrl_gpio3>, <&pinctrl_gpio4>,
+ <&pinctrl_gpio7>, <&pinctrl_gpio8>,
+ <&pinctrl_gpio_hog1>, <&pinctrl_gpio_hog2>, <&pinctrl_gpio_hog3>,
+ <&pinctrl_pmic_tpm_ena>;
+
+ pinctrl_can1_int: can1intgrp {
+ fsl,pins =
+ <MX8MM_IOMUXC_GPIO1_IO06_GPIO1_IO6 0x1c4>; /* CAN_1_SPI_INT#_1.8V */
+ };
+
+ pinctrl_can2_int: can2intgrp {
+ fsl,pins =
+ <MX8MM_IOMUXC_GPIO1_IO07_GPIO1_IO7 0x1c4>; /* CAN_2_SPI_INT#_1.8V */
+ };
+
+ pinctrl_ctrl_sleep_moci: ctrlsleepmocigrp {
+ fsl,pins =
+ <MX8MM_IOMUXC_SAI3_TXD_GPIO5_IO1 0x1c4>; /* SODIMM 256 */
+ };
+
+ pinctrl_ecspi2: ecspi2grp {
+ fsl,pins =
+ <MX8MM_IOMUXC_ECSPI2_SCLK_ECSPI2_SCLK 0x4>, /* SODIMM 196 */
+ <MX8MM_IOMUXC_ECSPI2_MOSI_ECSPI2_MOSI 0x4>, /* SODIMM 200 */
+ <MX8MM_IOMUXC_ECSPI2_MISO_ECSPI2_MISO 0x1c4>, /* SODIMM 198 */
+ <MX8MM_IOMUXC_ECSPI2_SS0_GPIO5_IO13 0x1c4>; /* SODIMM 202 */
+ };
+
+ pinctrl_ecspi3: ecspi3grp {
+ fsl,pins =
+ <MX8MM_IOMUXC_UART1_RXD_ECSPI3_SCLK 0x4>, /* CAN_SPI_SCK_1.8V */
+ <MX8MM_IOMUXC_UART1_TXD_ECSPI3_MOSI 0x4>, /* CAN_SPI_MOSI_1.8V */
+ <MX8MM_IOMUXC_UART2_RXD_ECSPI3_MISO 0x1c4>, /* CAN_SPI_MISO_1.8V */
+ <MX8MM_IOMUXC_UART2_TXD_GPIO5_IO25 0x1c4>, /* CAN_1_SPI_CS_1.8V# */
+ <MX8MM_IOMUXC_GPIO1_IO05_GPIO1_IO5 0x1c4>; /* CAN_2_SPI_CS#_1.8V */
+ };
+
+ pinctrl_fec1: fec1grp {
+ fsl,pins =
+ <MX8MM_IOMUXC_ENET_MDC_ENET1_MDC 0x3>,
+ <MX8MM_IOMUXC_ENET_MDIO_ENET1_MDIO 0x3>,
+ <MX8MM_IOMUXC_ENET_TD3_ENET1_RGMII_TD3 0x1f>,
+ <MX8MM_IOMUXC_ENET_TD2_ENET1_RGMII_TD2 0x1f>,
+ <MX8MM_IOMUXC_ENET_TD1_ENET1_RGMII_TD1 0x1f>,
+ <MX8MM_IOMUXC_ENET_TD0_ENET1_RGMII_TD0 0x1f>,
+ <MX8MM_IOMUXC_ENET_RD3_ENET1_RGMII_RD3 0x91>,
+ <MX8MM_IOMUXC_ENET_RD2_ENET1_RGMII_RD2 0x91>,
+ <MX8MM_IOMUXC_ENET_RD1_ENET1_RGMII_RD1 0x91>,
+ <MX8MM_IOMUXC_ENET_RD0_ENET1_RGMII_RD0 0x91>,
+ <MX8MM_IOMUXC_ENET_TXC_ENET1_RGMII_TXC 0x1f>,
+ <MX8MM_IOMUXC_ENET_RXC_ENET1_RGMII_RXC 0x91>,
+ <MX8MM_IOMUXC_ENET_RX_CTL_ENET1_RGMII_RX_CTL 0x91>,
+ <MX8MM_IOMUXC_ENET_TX_CTL_ENET1_RGMII_TX_CTL 0x1f>,
+ <MX8MM_IOMUXC_GPIO1_IO10_GPIO1_IO10 0x1c4>;
+ };
+
+ pinctrl_fec1_sleep: fec1-sleepgrp {
+ fsl,pins =
+ <MX8MM_IOMUXC_ENET_MDC_ENET1_MDC 0x3>,
+ <MX8MM_IOMUXC_ENET_MDIO_ENET1_MDIO 0x3>,
+ <MX8MM_IOMUXC_ENET_TD3_GPIO1_IO18 0x1f>,
+ <MX8MM_IOMUXC_ENET_TD2_GPIO1_IO19 0x1f>,
+ <MX8MM_IOMUXC_ENET_TD1_GPIO1_IO20 0x1f>,
+ <MX8MM_IOMUXC_ENET_TD0_GPIO1_IO21 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_GPIO1_IO23 0x1f>,
+ <MX8MM_IOMUXC_ENET_RXC_ENET1_RGMII_RXC 0x91>,
+ <MX8MM_IOMUXC_ENET_RX_CTL_ENET1_RGMII_RX_CTL 0x91>,
+ <MX8MM_IOMUXC_ENET_TX_CTL_GPIO1_IO22 0x1f>,
+ <MX8MM_IOMUXC_GPIO1_IO10_GPIO1_IO10 0x184>;
+ };
+
+ pinctrl_flexspi0: flexspi0grp {
+ fsl,pins =
+ <MX8MM_IOMUXC_NAND_ALE_QSPI_A_SCLK 0x1c2>, /* SODIMM 52 */
+ <MX8MM_IOMUXC_NAND_CE0_B_QSPI_A_SS0_B 0x82>, /* SODIMM 54 */
+ <MX8MM_IOMUXC_NAND_CE1_B_QSPI_A_SS1_B 0x82>, /* SODIMM 64 */
+ <MX8MM_IOMUXC_NAND_DQS_QSPI_A_DQS 0x82>, /* SODIMM 66 */
+ <MX8MM_IOMUXC_NAND_DATA00_QSPI_A_DATA0 0x82>, /* SODIMM 56 */
+ <MX8MM_IOMUXC_NAND_DATA01_QSPI_A_DATA1 0x82>, /* SODIMM 58 */
+ <MX8MM_IOMUXC_NAND_DATA02_QSPI_A_DATA2 0x82>, /* SODIMM 60 */
+ <MX8MM_IOMUXC_NAND_DATA03_QSPI_A_DATA3 0x82>; /* SODIMM 62 */
+ };
+
+ pinctrl_gpio1: gpio1grp {
+ fsl,pins =
+ <MX8MM_IOMUXC_NAND_CE3_B_GPIO3_IO4 0x184>; /* SODIMM 206 */
+ };
+
+ pinctrl_gpio2: gpio2grp {
+ fsl,pins =
+ <MX8MM_IOMUXC_SPDIF_EXT_CLK_GPIO5_IO5 0x1c4>; /* SODIMM 208 */
+ };
+
+ pinctrl_gpio3: gpio3grp {
+ fsl,pins =
+ <MX8MM_IOMUXC_UART3_RXD_GPIO5_IO26 0x184>; /* SODIMM 210 */
+ };
+
+ pinctrl_gpio4: gpio4grp {
+ fsl,pins =
+ <MX8MM_IOMUXC_UART3_TXD_GPIO5_IO27 0x184>; /* SODIMM 212 */
+ };
+
+ pinctrl_gpio5: gpio5grp {
+ fsl,pins =
+ <MX8MM_IOMUXC_GPIO1_IO00_GPIO1_IO0 0x184>; /* SODIMM 216 */
+ };
+
+ pinctrl_gpio6: gpio6grp {
+ fsl,pins =
+ <MX8MM_IOMUXC_GPIO1_IO11_GPIO1_IO11 0x184>; /* SODIMM 218 */
+ };
+
+ pinctrl_gpio7: gpio7grp {
+ fsl,pins =
+ <MX8MM_IOMUXC_GPIO1_IO08_GPIO1_IO8 0x184>; /* SODIMM 220 */
+ };
+
+ pinctrl_gpio8: gpio8grp {
+ fsl,pins =
+ <MX8MM_IOMUXC_GPIO1_IO09_GPIO1_IO9 0x184>; /* SODIMM 222 */
+ };
+
+ /* Verdin GPIO_9_DSI (pulled-up as active-low) */
+ pinctrl_gpio_9_dsi: gpio9dsigrp {
+ fsl,pins =
+ <MX8MM_IOMUXC_NAND_RE_B_GPIO3_IO15 0x1c4>; /* SODIMM 17 */
+ };
+
+ /* Verdin GPIO_10_DSI */
+ pinctrl_gpio_10_dsi: gpio10dsigrp {
+ fsl,pins =
+ <MX8MM_IOMUXC_NAND_CE2_B_GPIO3_IO3 0x1c4>; /* SODIMM 21 */
+ };
+
+ pinctrl_gpio_hog1: gpiohog1grp {
+ fsl,pins =
+ <MX8MM_IOMUXC_SAI1_MCLK_GPIO4_IO20 0x1c4>, /* SODIMM 88 */
+ <MX8MM_IOMUXC_SAI1_RXC_GPIO4_IO1 0x1c4>, /* SODIMM 90 */
+ <MX8MM_IOMUXC_SAI1_RXD0_GPIO4_IO2 0x1c4>, /* SODIMM 92 */
+ <MX8MM_IOMUXC_SAI1_RXD1_GPIO4_IO3 0x1c4>, /* SODIMM 94 */
+ <MX8MM_IOMUXC_SAI1_RXD2_GPIO4_IO4 0x1c4>, /* SODIMM 96 */
+ <MX8MM_IOMUXC_SAI1_RXD3_GPIO4_IO5 0x1c4>, /* SODIMM 100 */
+ <MX8MM_IOMUXC_SAI1_RXFS_GPIO4_IO0 0x1c4>, /* SODIMM 102 */
+ <MX8MM_IOMUXC_SAI1_TXC_GPIO4_IO11 0x1c4>, /* SODIMM 104 */
+ <MX8MM_IOMUXC_SAI1_TXD0_GPIO4_IO12 0x1c4>, /* SODIMM 106 */
+ <MX8MM_IOMUXC_SAI1_TXD1_GPIO4_IO13 0x1c4>, /* SODIMM 108 */
+ <MX8MM_IOMUXC_SAI1_TXD2_GPIO4_IO14 0x1c4>, /* SODIMM 112 */
+ <MX8MM_IOMUXC_SAI1_TXD3_GPIO4_IO15 0x1c4>, /* SODIMM 114 */
+ <MX8MM_IOMUXC_SAI1_TXD4_GPIO4_IO16 0x1c4>, /* SODIMM 116 */
+ <MX8MM_IOMUXC_SAI1_TXD6_GPIO4_IO18 0x1c4>, /* SODIMM 118 */
+ <MX8MM_IOMUXC_SAI1_TXFS_GPIO4_IO10 0x1c4>; /* SODIMM 120 */
+ };
+
+ pinctrl_gpio_hog2: gpiohog2grp {
+ fsl,pins =
+ <MX8MM_IOMUXC_SAI3_MCLK_GPIO5_IO2 0x1c4>; /* SODIMM 91 */
+ };
+
+ pinctrl_gpio_hog3: gpiohog3grp {
+ fsl,pins =
+ <MX8MM_IOMUXC_GPIO1_IO13_GPIO1_IO13 0x1c4>, /* SODIMM 157 */
+ <MX8MM_IOMUXC_GPIO1_IO15_GPIO1_IO15 0x1c4>; /* SODIMM 187 */
+ };
+
+ pinctrl_gpio_keys: gpiokeysgrp {
+ fsl,pins =
+ <MX8MM_IOMUXC_SAI3_RXFS_GPIO4_IO28 0x1c4>; /* SODIMM 252 */
+ };
+
+ /* On-module I2C */
+ pinctrl_i2c1: i2c1grp {
+ fsl,pins =
+ <MX8MM_IOMUXC_I2C1_SCL_I2C1_SCL 0x400001c6>, /* PMIC_I2C_SCL */
+ <MX8MM_IOMUXC_I2C1_SDA_I2C1_SDA 0x400001c6>; /* PMIC_I2C_SDA */
+ };
+
+ pinctrl_i2c1_gpio: i2c1gpiogrp {
+ fsl,pins =
+ <MX8MM_IOMUXC_I2C1_SCL_GPIO5_IO14 0x400001c6>, /* PMIC_I2C_SCL */
+ <MX8MM_IOMUXC_I2C1_SDA_GPIO5_IO15 0x400001c6>; /* PMIC_I2C_SDA */
+ };
+
+ /* Verdin I2C_4_CSI */
+ pinctrl_i2c2: i2c2grp {
+ fsl,pins =
+ <MX8MM_IOMUXC_I2C2_SCL_I2C2_SCL 0x400001c6>, /* SODIMM 55 */
+ <MX8MM_IOMUXC_I2C2_SDA_I2C2_SDA 0x400001c6>; /* SODIMM 53 */
+ };
+
+ pinctrl_i2c2_gpio: i2c2gpiogrp {
+ fsl,pins =
+ <MX8MM_IOMUXC_I2C2_SCL_GPIO5_IO16 0x400001c6>, /* SODIMM 55 */
+ <MX8MM_IOMUXC_I2C2_SDA_GPIO5_IO17 0x400001c6>; /* SODIMM 53 */
+ };
+
+ /* Verdin I2C_2_DSI */
+ pinctrl_i2c3: i2c3grp {
+ fsl,pins =
+ <MX8MM_IOMUXC_I2C3_SCL_I2C3_SCL 0x400001c6>, /* SODIMM 95 */
+ <MX8MM_IOMUXC_I2C3_SDA_I2C3_SDA 0x400001c6>; /* SODIMM 93 */
+ };
+
+ pinctrl_i2c3_gpio: i2c3gpiogrp {
+ fsl,pins =
+ <MX8MM_IOMUXC_I2C3_SCL_GPIO5_IO18 0x400001c6>, /* SODIMM 95 */
+ <MX8MM_IOMUXC_I2C3_SDA_GPIO5_IO19 0x400001c6>; /* SODIMM 93 */
+ };
+
+ /* Verdin I2C_1 */
+ pinctrl_i2c4: i2c4grp {
+ fsl,pins =
+ <MX8MM_IOMUXC_I2C4_SCL_I2C4_SCL 0x400001c6>, /* SODIMM 14 */
+ <MX8MM_IOMUXC_I2C4_SDA_I2C4_SDA 0x400001c6>; /* SODIMM 12 */
+ };
+
+ pinctrl_i2c4_gpio: i2c4gpiogrp {
+ fsl,pins =
+ <MX8MM_IOMUXC_I2C4_SCL_GPIO5_IO20 0x400001c6>, /* SODIMM 14 */
+ <MX8MM_IOMUXC_I2C4_SDA_GPIO5_IO21 0x400001c6>; /* SODIMM 12 */
+ };
+
+ /* Verdin I2S_2_BCLK (TOUCH_RESET#) */
+ pinctrl_i2s_2_bclk_touch_reset: i2s2bclktouchresetgrp {
+ fsl,pins =
+ <MX8MM_IOMUXC_SAI5_RXD2_GPIO3_IO23 0x184>; /* SODIMM 42 */
+ };
+
+ /* Verdin I2S_2_D_OUT shared with SAI5 */
+ pinctrl_i2s_2_d_out_dsi_1_bkl_en: i2s2doutdsi1bklengrp {
+ fsl,pins =
+ <MX8MM_IOMUXC_SAI5_RXD3_GPIO3_IO24 0x184>; /* SODIMM 46 */
+ };
+
+ pinctrl_pcie0: pcie0grp {
+ fsl,pins =
+ <MX8MM_IOMUXC_SAI5_RXFS_GPIO3_IO19 0x6>, /* SODIMM 244 */
+ /* PMIC_EN_PCIe_CLK, unused */
+ <MX8MM_IOMUXC_SD2_RESET_B_GPIO2_IO19 0x6>;
+ };
+
+ pinctrl_pmic: pmicirqgrp {
+ fsl,pins =
+ <MX8MM_IOMUXC_GPIO1_IO03_GPIO1_IO3 0x41>; /* PMIC_INT# */
+ };
+
+ /* Verdin PWM_3_DSI shared with GPIO1_IO1 */
+ pinctrl_pwm_1: pwm1grp {
+ fsl,pins =
+ <MX8MM_IOMUXC_GPIO1_IO01_PWM1_OUT 0x6>; /* SODIMM 19 */
+ };
+
+ pinctrl_pwm_2: pwm2grp {
+ fsl,pins =
+ <MX8MM_IOMUXC_SPDIF_RX_PWM2_OUT 0x6>; /* SODIMM 15 */
+ };
+
+ pinctrl_pwm_3: pwm3grp {
+ fsl,pins =
+ <MX8MM_IOMUXC_SPDIF_TX_PWM3_OUT 0x6>; /* SODIMM 16 */
+ };
+
+ /* Verdin PWM_3_DSI (pulled-down as active-high) shared with PWM1_OUT */
+ pinctrl_pwm_3_dsi_hpd_gpio: pwm3dsihpdgpiogrp {
+ fsl,pins =
+ <MX8MM_IOMUXC_GPIO1_IO01_GPIO1_IO1 0x184>; /* SODIMM 19 */
+ };
+
+ pinctrl_reg_eth: regethgrp {
+ fsl,pins =
+ <MX8MM_IOMUXC_SD2_WP_GPIO2_IO20 0x184>; /* PMIC_EN_ETH */
+ };
+
+ pinctrl_reg_usb1_en: regusb1engrp {
+ fsl,pins =
+ <MX8MM_IOMUXC_GPIO1_IO12_GPIO1_IO12 0x184>; /* SODIMM 155 */
+ };
+
+ pinctrl_reg_usb2_en: regusb2engrp {
+ fsl,pins =
+ <MX8MM_IOMUXC_GPIO1_IO14_GPIO1_IO14 0x184>; /* SODIMM 185 */
+ };
+
+ pinctrl_sai2: sai2grp {
+ fsl,pins =
+ <MX8MM_IOMUXC_SAI2_TXFS_SAI2_TX_SYNC 0xd6>, /* SODIMM 32 */
+ <MX8MM_IOMUXC_SAI2_TXC_SAI2_TX_BCLK 0xd6>, /* SODIMM 30 */
+ <MX8MM_IOMUXC_SAI2_MCLK_SAI2_MCLK 0xd6>, /* SODIMM 38 */
+ <MX8MM_IOMUXC_SAI2_RXD0_SAI2_RX_DATA0 0xd6>, /* SODIMM 36 */
+ <MX8MM_IOMUXC_SAI2_TXD0_SAI2_TX_DATA0 0xd6>; /* SODIMM 34 */
+ };
+
+ pinctrl_sai5: sai5grp {
+ fsl,pins =
+ <MX8MM_IOMUXC_SAI5_RXD0_SAI5_RX_DATA0 0xd6>, /* SODIMM 48 */
+ <MX8MM_IOMUXC_SAI5_RXD1_SAI5_TX_SYNC 0xd6>, /* SODIMM 44 */
+ <MX8MM_IOMUXC_SAI5_RXD2_SAI5_TX_BCLK 0xd6>, /* SODIMM 42 */
+ <MX8MM_IOMUXC_SAI5_RXD3_SAI5_TX_DATA0 0xd6>; /* SODIMM 46 */
+ };
+
+ /* control signal for optional ATTPM20P or SE050 */
+ pinctrl_pmic_tpm_ena: pmictpmenagrp {
+ fsl,pins =
+ <MX8MM_IOMUXC_SAI1_TXD7_GPIO4_IO19 0x1c4>; /* PMIC_TPM_ENA */
+ };
+
+ pinctrl_tsp: tspgrp {
+ fsl,pins =
+ <MX8MM_IOMUXC_SAI1_RXD4_GPIO4_IO6 0x140>, /* SODIMM 148 */
+ <MX8MM_IOMUXC_SAI1_RXD5_GPIO4_IO7 0x140>, /* SODIMM 152 */
+ <MX8MM_IOMUXC_SAI1_RXD6_GPIO4_IO8 0x140>, /* SODIMM 154 */
+ <MX8MM_IOMUXC_SAI1_RXD7_GPIO4_IO9 0x140>, /* SODIMM 174 */
+ <MX8MM_IOMUXC_SAI1_TXD5_GPIO4_IO17 0x140>; /* SODIMM 150 */
+ };
+
+ pinctrl_uart1: uart1grp {
+ fsl,pins =
+ <MX8MM_IOMUXC_SAI2_RXFS_UART1_DCE_TX 0x1c4>, /* SODIMM 149 */
+ <MX8MM_IOMUXC_SAI2_RXC_UART1_DCE_RX 0x1c4>; /* SODIMM 147 */
+ };
+
+ pinctrl_uart2: uart2grp {
+ fsl,pins =
+ <MX8MM_IOMUXC_SAI3_TXFS_UART2_DCE_RX 0x1c4>, /* SODIMM 129 */
+ <MX8MM_IOMUXC_SAI3_TXC_UART2_DCE_TX 0x1c4>, /* SODIMM 131 */
+ <MX8MM_IOMUXC_SAI3_RXC_UART2_DCE_CTS_B 0x1c4>, /* SODIMM 133 */
+ <MX8MM_IOMUXC_SAI3_RXD_UART2_DCE_RTS_B 0x1c4>; /* SODIMM 135 */
+ };
+
+ pinctrl_uart3: uart3grp {
+ fsl,pins =
+ <MX8MM_IOMUXC_ECSPI1_SCLK_UART3_DCE_RX 0x1c4>, /* SODIMM 137 */
+ <MX8MM_IOMUXC_ECSPI1_MOSI_UART3_DCE_TX 0x1c4>, /* SODIMM 139 */
+ <MX8MM_IOMUXC_ECSPI1_MISO_UART3_DCE_CTS_B 0x1c4>, /* SODIMM 141 */
+ <MX8MM_IOMUXC_ECSPI1_SS0_UART3_DCE_RTS_B 0x1c4>; /* SODIMM 143 */
+ };
+
+ pinctrl_uart4: uart4grp {
+ fsl,pins =
+ <MX8MM_IOMUXC_UART4_RXD_UART4_DCE_RX 0x1c4>, /* SODIMM 151 */
+ <MX8MM_IOMUXC_UART4_TXD_UART4_DCE_TX 0x1c4>; /* SODIMM 153 */
+ };
+
+ pinctrl_usdhc1: usdhc1grp {
+ fsl,pins =
+ <MX8MM_IOMUXC_SD1_CLK_USDHC1_CLK 0x190>,
+ <MX8MM_IOMUXC_SD1_CMD_USDHC1_CMD 0x1d0>,
+ <MX8MM_IOMUXC_SD1_DATA0_USDHC1_DATA0 0x1d0>,
+ <MX8MM_IOMUXC_SD1_DATA1_USDHC1_DATA1 0x1d0>,
+ <MX8MM_IOMUXC_SD1_DATA2_USDHC1_DATA2 0x1d0>,
+ <MX8MM_IOMUXC_SD1_DATA3_USDHC1_DATA3 0x1d0>,
+ <MX8MM_IOMUXC_SD1_DATA4_USDHC1_DATA4 0x1d0>,
+ <MX8MM_IOMUXC_SD1_DATA5_USDHC1_DATA5 0x1d0>,
+ <MX8MM_IOMUXC_SD1_DATA6_USDHC1_DATA6 0x1d0>,
+ <MX8MM_IOMUXC_SD1_DATA7_USDHC1_DATA7 0x1d0>,
+ <MX8MM_IOMUXC_SD1_RESET_B_USDHC1_RESET_B 0x1d1>,
+ <MX8MM_IOMUXC_SD1_STROBE_USDHC1_STROBE 0x190>;
+ };
+
+ pinctrl_usdhc1_100mhz: usdhc1-100mhzgrp {
+ fsl,pins =
+ <MX8MM_IOMUXC_SD1_CLK_USDHC1_CLK 0x194>,
+ <MX8MM_IOMUXC_SD1_CMD_USDHC1_CMD 0x1d4>,
+ <MX8MM_IOMUXC_SD1_DATA0_USDHC1_DATA0 0x1d4>,
+ <MX8MM_IOMUXC_SD1_DATA1_USDHC1_DATA1 0x1d4>,
+ <MX8MM_IOMUXC_SD1_DATA2_USDHC1_DATA2 0x1d4>,
+ <MX8MM_IOMUXC_SD1_DATA3_USDHC1_DATA3 0x1d4>,
+ <MX8MM_IOMUXC_SD1_DATA4_USDHC1_DATA4 0x1d4>,
+ <MX8MM_IOMUXC_SD1_DATA5_USDHC1_DATA5 0x1d4>,
+ <MX8MM_IOMUXC_SD1_DATA6_USDHC1_DATA6 0x1d4>,
+ <MX8MM_IOMUXC_SD1_DATA7_USDHC1_DATA7 0x1d4>,
+ <MX8MM_IOMUXC_SD1_RESET_B_USDHC1_RESET_B 0x1d1>,
+ <MX8MM_IOMUXC_SD1_STROBE_USDHC1_STROBE 0x194>;
+ };
+
+ pinctrl_usdhc1_200mhz: usdhc1-200mhzgrp {
+ fsl,pins =
+ <MX8MM_IOMUXC_SD1_CLK_USDHC1_CLK 0x196>,
+ <MX8MM_IOMUXC_SD1_CMD_USDHC1_CMD 0x1d6>,
+ <MX8MM_IOMUXC_SD1_DATA0_USDHC1_DATA0 0x1d6>,
+ <MX8MM_IOMUXC_SD1_DATA1_USDHC1_DATA1 0x1d6>,
+ <MX8MM_IOMUXC_SD1_DATA2_USDHC1_DATA2 0x1d6>,
+ <MX8MM_IOMUXC_SD1_DATA3_USDHC1_DATA3 0x1d6>,
+ <MX8MM_IOMUXC_SD1_DATA4_USDHC1_DATA4 0x1d6>,
+ <MX8MM_IOMUXC_SD1_DATA5_USDHC1_DATA5 0x1d6>,
+ <MX8MM_IOMUXC_SD1_DATA6_USDHC1_DATA6 0x1d6>,
+ <MX8MM_IOMUXC_SD1_DATA7_USDHC1_DATA7 0x1d6>,
+ <MX8MM_IOMUXC_SD1_RESET_B_USDHC1_RESET_B 0x1d1>,
+ <MX8MM_IOMUXC_SD1_STROBE_USDHC1_STROBE 0x196>;
+ };
+
+ pinctrl_usdhc2_cd: usdhc2cdgrp {
+ fsl,pins =
+ <MX8MM_IOMUXC_SD2_CD_B_GPIO2_IO12 0x1c4>; /* SODIMM 84 */
+ };
+
+ pinctrl_usdhc2_pwr_en: usdhc2pwrengrp {
+ fsl,pins =
+ <MX8MM_IOMUXC_NAND_CLE_GPIO3_IO5 0x184>; /* SODIMM 76 */
+ };
+
+ pinctrl_usdhc2: usdhc2grp {
+ fsl,pins =
+ <MX8MM_IOMUXC_SD2_CLK_USDHC2_CLK 0x190>, /* SODIMM 78 */
+ <MX8MM_IOMUXC_SD2_CMD_USDHC2_CMD 0x1d0>, /* SODIMM 74 */
+ <MX8MM_IOMUXC_SD2_DATA0_USDHC2_DATA0 0x1d0>, /* SODIMM 80 */
+ <MX8MM_IOMUXC_SD2_DATA1_USDHC2_DATA1 0x1d0>, /* SODIMM 82 */
+ <MX8MM_IOMUXC_SD2_DATA2_USDHC2_DATA2 0x1d0>, /* SODIMM 70 */
+ <MX8MM_IOMUXC_SD2_DATA3_USDHC2_DATA3 0x1d0>, /* SODIMM 72 */
+ <MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0x1d0>;
+ };
+
+ pinctrl_usdhc2_100mhz: usdhc2-100mhzgrp {
+ fsl,pins =
+ <MX8MM_IOMUXC_SD2_CLK_USDHC2_CLK 0x194>,
+ <MX8MM_IOMUXC_SD2_CMD_USDHC2_CMD 0x1d4>,
+ <MX8MM_IOMUXC_SD2_DATA0_USDHC2_DATA0 0x1d4>,
+ <MX8MM_IOMUXC_SD2_DATA1_USDHC2_DATA1 0x1d4>,
+ <MX8MM_IOMUXC_SD2_DATA2_USDHC2_DATA2 0x1d4>,
+ <MX8MM_IOMUXC_SD2_DATA3_USDHC2_DATA3 0x1d4>,
+ <MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0x1d0>;
+ };
+
+ pinctrl_usdhc2_200mhz: usdhc2-200mhzgrp {
+ fsl,pins =
+ <MX8MM_IOMUXC_SD2_CLK_USDHC2_CLK 0x196>,
+ <MX8MM_IOMUXC_SD2_CMD_USDHC2_CMD 0x1d6>,
+ <MX8MM_IOMUXC_SD2_DATA0_USDHC2_DATA0 0x1d6>,
+ <MX8MM_IOMUXC_SD2_DATA1_USDHC2_DATA1 0x1d6>,
+ <MX8MM_IOMUXC_SD2_DATA2_USDHC2_DATA2 0x1d6>,
+ <MX8MM_IOMUXC_SD2_DATA3_USDHC2_DATA3 0x1d6>,
+ <MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0x1d0>;
+ };
+
+ /* On-module Wi-Fi/BT or type specific SDHC interface */
+ /* (e.g. on X52 extension slot of Verdin Development Board) */
+ pinctrl_usdhc3: usdhc3grp {
+ fsl,pins =
+ <MX8MM_IOMUXC_NAND_WE_B_USDHC3_CLK 0x190>,
+ <MX8MM_IOMUXC_NAND_WP_B_USDHC3_CMD 0x1d0>,
+ <MX8MM_IOMUXC_NAND_DATA04_USDHC3_DATA0 0x1d0>,
+ <MX8MM_IOMUXC_NAND_DATA05_USDHC3_DATA1 0x1d0>,
+ <MX8MM_IOMUXC_NAND_DATA06_USDHC3_DATA2 0x1d0>,
+ <MX8MM_IOMUXC_NAND_DATA07_USDHC3_DATA3 0x1d0>;
+ };
+
+ pinctrl_usdhc3_100mhz: usdhc3-100mhzgrp {
+ fsl,pins =
+ <MX8MM_IOMUXC_NAND_WE_B_USDHC3_CLK 0x194>,
+ <MX8MM_IOMUXC_NAND_WP_B_USDHC3_CMD 0x1d4>,
+ <MX8MM_IOMUXC_NAND_DATA04_USDHC3_DATA0 0x1d4>,
+ <MX8MM_IOMUXC_NAND_DATA05_USDHC3_DATA1 0x1d4>,
+ <MX8MM_IOMUXC_NAND_DATA06_USDHC3_DATA2 0x1d4>,
+ <MX8MM_IOMUXC_NAND_DATA07_USDHC3_DATA3 0x1d4>;
+ };
+
+ pinctrl_usdhc3_200mhz: usdhc3-200mhzgrp {
+ fsl,pins =
+ <MX8MM_IOMUXC_NAND_WE_B_USDHC3_CLK 0x196>,
+ <MX8MM_IOMUXC_NAND_WP_B_USDHC3_CMD 0x1d6>,
+ <MX8MM_IOMUXC_NAND_DATA04_USDHC3_DATA0 0x1d6>,
+ <MX8MM_IOMUXC_NAND_DATA05_USDHC3_DATA1 0x1d6>,
+ <MX8MM_IOMUXC_NAND_DATA06_USDHC3_DATA2 0x1d6>,
+ <MX8MM_IOMUXC_NAND_DATA07_USDHC3_DATA3 0x1d6>;
+ };
+
+ pinctrl_wdog: wdoggrp {
+ fsl,pins =
+ <MX8MM_IOMUXC_GPIO1_IO02_WDOG1_WDOG_B 0xc6>; /* PMIC_WDI */
+ };
+
+ pinctrl_wifi_ctrl: wifictrlgrp {
+ fsl,pins =
+ <MX8MM_IOMUXC_NAND_READY_B_GPIO3_IO16 0x1c4>, /* WIFI_WKUP_BT */
+ <MX8MM_IOMUXC_SAI1_RXD7_GPIO4_IO9 0x1c4>, /* WIFI_W_WKUP_HOST */
+ <MX8MM_IOMUXC_SAI5_RXC_GPIO3_IO20 0x1c4>; /* WIFI_WKUP_WLAN */
+ };
+
+ pinctrl_wifi_i2s: bti2sgrp {
+ fsl,pins =
+ <MX8MM_IOMUXC_SAI1_RXD4_SAI6_TX_BCLK 0xd6>, /* WIFI_TX_BCLK */
+ <MX8MM_IOMUXC_SAI1_RXD5_SAI6_TX_DATA0 0xd6>, /* WIFI_TX_DATA0 */
+ <MX8MM_IOMUXC_SAI1_RXD6_SAI6_TX_SYNC 0xd6>, /* WIFI_TX_SYNC */
+ <MX8MM_IOMUXC_SAI1_TXD5_SAI6_RX_DATA0 0xd6>; /* WIFI_RX_DATA0 */
+ };
+
+ pinctrl_wifi_pwr_en: wifipwrengrp {
+ fsl,pins =
+ <MX8MM_IOMUXC_SAI5_MCLK_GPIO3_IO25 0x184>; /* PMIC_EN_WIFI */
+ };
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8mm.dtsi b/arch/arm64/boot/dts/freescale/imx8mm.dtsi
index f77f90ed416f..1ee05677c2dd 100644
--- a/arch/arm64/boot/dts/freescale/imx8mm.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mm.dtsi
@@ -548,7 +548,7 @@
};
gpr: iomuxc-gpr@30340000 {
- compatible = "fsl,imx8mm-iomuxc-gpr", "syscon";
+ compatible = "fsl,imx8mm-iomuxc-gpr", "fsl,imx6q-iomuxc-gpr", "syscon";
reg = <0x30340000 0x10000>;
};
@@ -707,7 +707,6 @@
clocks = <&clk IMX8MM_CLK_VPU_DEC_ROOT>;
assigned-clocks = <&clk IMX8MM_CLK_VPU_BUS>;
assigned-clock-parents = <&clk IMX8MM_SYS_PLL1_800M>;
- resets = <&src IMX8MQ_RESET_VPU_RESET>;
};
pgc_vpu_g1: power-domain@7 {
@@ -1211,6 +1210,19 @@
reg = <0x32e50200 0x200>;
};
+ pcie_phy: pcie-phy@32f00000 {
+ compatible = "fsl,imx8mm-pcie-phy";
+ reg = <0x32f00000 0x10000>;
+ clocks = <&clk IMX8MM_CLK_PCIE1_PHY>;
+ clock-names = "ref";
+ assigned-clocks = <&clk IMX8MM_CLK_PCIE1_PHY>;
+ assigned-clock-rates = <100000000>;
+ assigned-clock-parents = <&clk IMX8MM_SYS_PLL2_100M>;
+ resets = <&src IMX8MQ_RESET_PCIEPHY>;
+ reset-names = "pciephy";
+ #phy-cells = <0>;
+ status = "disabled";
+ };
};
dma_apbh: dma-controller@33000000 {
@@ -1242,6 +1254,37 @@
status = "disabled";
};
+ pcie0: pcie@33800000 {
+ compatible = "fsl,imx8mm-pcie";
+ reg = <0x33800000 0x400000>, <0x1ff00000 0x80000>;
+ reg-names = "dbi", "config";
+ #address-cells = <3>;
+ #size-cells = <2>;
+ device_type = "pci";
+ bus-range = <0x00 0xff>;
+ ranges = <0x81000000 0 0x00000000 0x1ff80000 0 0x00010000 /* downstream I/O 64KB */
+ 0x82000000 0 0x18000000 0x18000000 0 0x07f00000>; /* non-prefetchable memory */
+ num-lanes = <1>;
+ num-viewport = <4>;
+ interrupts = <GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "msi";
+ #interrupt-cells = <1>;
+ interrupt-map-mask = <0 0 0 0x7>;
+ interrupt-map = <0 0 0 1 &gic GIC_SPI 125 IRQ_TYPE_LEVEL_HIGH>,
+ <0 0 0 2 &gic GIC_SPI 124 IRQ_TYPE_LEVEL_HIGH>,
+ <0 0 0 3 &gic GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>,
+ <0 0 0 4 &gic GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>;
+ fsl,max-link-speed = <2>;
+ linux,pci-domain = <0>;
+ power-domains = <&pgc_pcie>;
+ resets = <&src IMX8MQ_RESET_PCIE_CTRL_APPS_EN>,
+ <&src IMX8MQ_RESET_PCIE_CTRL_APPS_TURNOFF>;
+ reset-names = "apps", "turnoff";
+ phys = <&pcie_phy>;
+ phy-names = "pcie-phy";
+ status = "disabled";
+ };
+
gpu_3d: gpu@38000000 {
compatible = "vivante,gc";
reg = <0x38000000 0x8000>;
@@ -1273,6 +1316,22 @@
power-domains = <&pgc_gpu>;
};
+ vpu_g1: video-codec@38300000 {
+ compatible = "nxp,imx8mm-vpu-g1";
+ reg = <0x38300000 0x10000>;
+ interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX8MM_CLK_VPU_G1_ROOT>;
+ power-domains = <&vpu_blk_ctrl IMX8MM_VPUBLK_PD_G1>;
+ };
+
+ vpu_g2: video-codec@38310000 {
+ compatible = "nxp,imx8mq-vpu-g2";
+ reg = <0x38310000 0x10000>;
+ interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX8MM_CLK_VPU_G2_ROOT>;
+ power-domains = <&vpu_blk_ctrl IMX8MM_VPUBLK_PD_G2>;
+ };
+
vpu_blk_ctrl: blk-ctrl@38330000 {
compatible = "fsl,imx8mm-vpu-blk-ctrl", "syscon";
reg = <0x38330000 0x100>;
@@ -1283,6 +1342,12 @@
<&clk IMX8MM_CLK_VPU_G2_ROOT>,
<&clk IMX8MM_CLK_VPU_H1_ROOT>;
clock-names = "g1", "g2", "h1";
+ assigned-clocks = <&clk IMX8MM_CLK_VPU_G1>,
+ <&clk IMX8MM_CLK_VPU_G2>;
+ assigned-clock-parents = <&clk IMX8MM_VPU_PLL_OUT>,
+ <&clk IMX8MM_VPU_PLL_OUT>;
+ assigned-clock-rates = <600000000>,
+ <600000000>;
#power-domain-cells = <1>;
};
diff --git a/arch/arm64/boot/dts/freescale/imx8mn-venice-gw7902.dts b/arch/arm64/boot/dts/freescale/imx8mn-venice-gw7902.dts
index 236f425e1570..3c0e63d2e82d 100644
--- a/arch/arm64/boot/dts/freescale/imx8mn-venice-gw7902.dts
+++ b/arch/arm64/boot/dts/freescale/imx8mn-venice-gw7902.dts
@@ -220,6 +220,10 @@
};
};
+&disp_blk_ctrl {
+ status = "disabled";
+};
+
/* off-board header */
&ecspi2 {
pinctrl-names = "default";
@@ -251,6 +255,47 @@
};
};
+&gpio1 {
+ gpio-line-names = "", "", "", "", "", "", "", "",
+ "", "", "", "", "", "m2_reset", "", "m2_wdis#",
+ "", "", "", "", "", "", "", "",
+ "", "", "", "", "", "", "", "";
+};
+
+&gpio2 {
+ gpio-line-names = "", "", "", "", "", "", "", "",
+ "uart2_en#", "", "", "", "", "", "", "",
+ "", "", "", "", "", "", "", "",
+ "", "", "", "", "", "", "", "";
+};
+
+&gpio3 {
+ gpio-line-names = "", "m2_gdis#", "", "", "", "", "", "m2_off#",
+ "", "", "", "", "", "", "", "",
+ "", "", "", "", "", "", "", "",
+ "", "", "", "", "", "", "", "";
+};
+
+&gpio4 {
+ gpio-line-names = "", "", "", "", "", "", "", "",
+ "", "", "", "", "", "", "", "",
+ "", "", "", "", "", "app_gpio1", "", "uart1_rs485",
+ "", "uart1_term", "uart1_half", "app_gpio2",
+ "mipi_gpio1", "", "", "";
+};
+
+&gpio5 {
+ gpio-line-names = "", "", "", "mipi_gpio4",
+ "mipi_gpio3", "mipi_gpio2", "", "",
+ "", "", "", "", "", "", "", "",
+ "", "", "", "", "", "", "", "",
+ "", "", "", "", "", "", "", "";
+};
+
+&gpu {
+ status = "disabled";
+};
+
&i2c1 {
clock-frequency = <100000>;
pinctrl-names = "default";
@@ -546,6 +591,10 @@
status = "okay";
};
+&pgc_gpumix {
+ status = "disabled";
+};
+
/* off-board header */
&sai3 {
pinctrl-names = "default";
@@ -633,7 +682,7 @@
pinctrl_hog: hoggrp {
fsl,pins = <
MX8MN_IOMUXC_NAND_CE0_B_GPIO3_IO1 0x40000159 /* M2_GDIS# */
- MX8MN_IOMUXC_GPIO1_IO13_GPIO1_IO13 0x40000041 /* M2_RST# */
+ MX8MN_IOMUXC_GPIO1_IO13_GPIO1_IO13 0x40000041 /* M2_RESET */
MX8MN_IOMUXC_NAND_DATA01_GPIO3_IO7 0x40000119 /* M2_OFF# */
MX8MN_IOMUXC_GPIO1_IO15_GPIO1_IO15 0x40000159 /* M2_WDIS# */
MX8MN_IOMUXC_SAI2_RXFS_GPIO4_IO21 0x40000041 /* APP GPIO1 */
diff --git a/arch/arm64/boot/dts/freescale/imx8mn.dtsi b/arch/arm64/boot/dts/freescale/imx8mn.dtsi
index b8d49d5f2668..99f0f5026674 100644
--- a/arch/arm64/boot/dts/freescale/imx8mn.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mn.dtsi
@@ -4,6 +4,8 @@
*/
#include <dt-bindings/clock/imx8mn-clock.h>
+#include <dt-bindings/power/imx8mn-power.h>
+#include <dt-bindings/reset/imx8mq-reset.h>
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/input/input.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
@@ -640,6 +642,53 @@
interrupts = <GIC_SPI 89 IRQ_TYPE_LEVEL_HIGH>;
#reset-cells = <1>;
};
+
+ gpc: gpc@303a0000 {
+ compatible = "fsl,imx8mn-gpc";
+ reg = <0x303a0000 0x10000>;
+ interrupt-parent = <&gic>;
+ interrupts = <GIC_SPI 87 IRQ_TYPE_LEVEL_HIGH>;
+
+ pgc {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pgc_hsiomix: power-domain@0 {
+ #power-domain-cells = <0>;
+ reg = <IMX8MN_POWER_DOMAIN_HSIOMIX>;
+ clocks = <&clk IMX8MN_CLK_USB_BUS>;
+ };
+
+ pgc_otg1: power-domain@1 {
+ #power-domain-cells = <0>;
+ reg = <IMX8MN_POWER_DOMAIN_OTG1>;
+ power-domains = <&pgc_hsiomix>;
+ };
+
+ pgc_gpumix: power-domain@2 {
+ #power-domain-cells = <0>;
+ reg = <IMX8MN_POWER_DOMAIN_GPUMIX>;
+ clocks = <&clk IMX8MN_CLK_GPU_CORE_ROOT>,
+ <&clk IMX8MN_CLK_GPU_SHADER>,
+ <&clk IMX8MN_CLK_GPU_BUS_ROOT>,
+ <&clk IMX8MN_CLK_GPU_AHB>;
+ resets = <&src IMX8MQ_RESET_GPU_RESET>;
+ };
+
+ pgc_dispmix: power-domain@3 {
+ #power-domain-cells = <0>;
+ reg = <IMX8MN_POWER_DOMAIN_DISPMIX>;
+ clocks = <&clk IMX8MN_CLK_DISP_AXI_ROOT>,
+ <&clk IMX8MN_CLK_DISP_APB_ROOT>;
+ };
+
+ pgc_mipi: power-domain@4 {
+ #power-domain-cells = <0>;
+ reg = <IMX8MN_POWER_DOMAIN_MIPI>;
+ power-domains = <&pgc_dispmix>;
+ };
+ };
+ };
};
aips2: bus@30400000 {
@@ -989,6 +1038,34 @@
#size-cells = <1>;
ranges;
+ disp_blk_ctrl: blk-ctrl@32e28000 {
+ compatible = "fsl,imx8mn-disp-blk-ctrl", "syscon";
+ reg = <0x32e28000 0x100>;
+ power-domains = <&pgc_dispmix>, <&pgc_dispmix>,
+ <&pgc_dispmix>, <&pgc_mipi>,
+ <&pgc_mipi>;
+ power-domain-names = "bus", "isi",
+ "lcdif", "mipi-dsi",
+ "mipi-csi";
+ clocks = <&clk IMX8MN_CLK_DISP_AXI>,
+ <&clk IMX8MN_CLK_DISP_APB>,
+ <&clk IMX8MN_CLK_DISP_AXI_ROOT>,
+ <&clk IMX8MN_CLK_DISP_APB_ROOT>,
+ <&clk IMX8MN_CLK_DISP_AXI_ROOT>,
+ <&clk IMX8MN_CLK_DISP_APB_ROOT>,
+ <&clk IMX8MN_CLK_DISP_PIXEL_ROOT>,
+ <&clk IMX8MN_CLK_DSI_CORE>,
+ <&clk IMX8MN_CLK_DSI_PHY_REF>,
+ <&clk IMX8MN_CLK_CSI1_PHY_REF>,
+ <&clk IMX8MN_CLK_CAMERA_PIXEL_ROOT>;
+ clock-names = "disp_axi", "disp_apb",
+ "disp_axi_root", "disp_apb_root",
+ "lcdif-axi", "lcdif-apb", "lcdif-pix",
+ "dsi-pclk", "dsi-ref",
+ "csi-aclk", "csi-pclk";
+ #power-domain-cells = <1>;
+ };
+
usbotg1: usb@32e40000 {
compatible = "fsl,imx8mn-usb", "fsl,imx7d-usb";
reg = <0x32e40000 0x200>;
@@ -999,6 +1076,7 @@
assigned-clock-parents = <&clk IMX8MN_SYS_PLL2_500M>;
phys = <&usbphynop1>;
fsl,usbmisc = <&usbmisc1 0>;
+ power-domains = <&pgc_otg1>;
status = "disabled";
};
@@ -1038,6 +1116,32 @@
status = "disabled";
};
+ gpu: gpu@38000000 {
+ compatible = "vivante,gc";
+ reg = <0x38000000 0x8000>;
+ interrupts = <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX8MN_CLK_GPU_AHB>,
+ <&clk IMX8MN_CLK_GPU_BUS_ROOT>,
+ <&clk IMX8MN_CLK_GPU_CORE_ROOT>,
+ <&clk IMX8MN_CLK_GPU_SHADER>;
+ clock-names = "reg", "bus", "core", "shader";
+ assigned-clocks = <&clk IMX8MN_CLK_GPU_CORE>,
+ <&clk IMX8MN_CLK_GPU_SHADER>,
+ <&clk IMX8MN_CLK_GPU_AXI>,
+ <&clk IMX8MN_CLK_GPU_AHB>,
+ <&clk IMX8MN_GPU_PLL>;
+ assigned-clock-parents = <&clk IMX8MN_GPU_PLL_OUT>,
+ <&clk IMX8MN_GPU_PLL_OUT>,
+ <&clk IMX8MN_SYS_PLL1_800M>,
+ <&clk IMX8MN_SYS_PLL1_800M>;
+ assigned-clock-rates = <400000000>,
+ <400000000>,
+ <800000000>,
+ <400000000>,
+ <1200000000>;
+ power-domains = <&pgc_gpumix>;
+ };
+
gic: interrupt-controller@38800000 {
compatible = "arm,gic-v3";
reg = <0x38800000 0x10000>,
diff --git a/arch/arm64/boot/dts/freescale/imx8mp-evk.dts b/arch/arm64/boot/dts/freescale/imx8mp-evk.dts
index 2eb943210678..4c3ac4214a2c 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp-evk.dts
+++ b/arch/arm64/boot/dts/freescale/imx8mp-evk.dts
@@ -294,9 +294,46 @@
reg = <0x20>;
gpio-controller;
#gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pca6416_int>;
+ interrupt-parent = <&gpio1>;
+ interrupts = <12 IRQ_TYPE_LEVEL_LOW>;
+ gpio-line-names = "EXT_PWREN1",
+ "EXT_PWREN2",
+ "CAN1/I2C5_SEL",
+ "PDM/CAN2_SEL",
+ "FAN_EN",
+ "PWR_MEAS_IO1",
+ "PWR_MEAS_IO2",
+ "EXP_P0_7",
+ "EXP_P1_0",
+ "EXP_P1_1",
+ "EXP_P1_2",
+ "EXP_P1_3",
+ "EXP_P1_4",
+ "EXP_P1_5",
+ "EXP_P1_6",
+ "EXP_P1_7";
};
};
+/* I2C on expansion connector J22. */
+&i2c5 {
+ clock-frequency = <100000>; /* Lower clock speed for external bus. */
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c5>;
+ status = "disabled"; /* can1 pins conflict with i2c5 */
+
+ /* GPIO 2 of PCA6416 is used to switch between CAN1 and I2C5 functions:
+ * LOW: CAN1 (default, pull-down)
+ * HIGH: I2C5
+ * You need to set it to high to enable I2C5 (for example, add gpio-hog
+ * in pca6416 node).
+ */
+};
+
&snvs_pwrkey {
status = "okay";
};
@@ -442,12 +479,25 @@
>;
};
+ pinctrl_i2c5: i2c5grp {
+ fsl,pins = <
+ MX8MP_IOMUXC_SPDIF_RX__I2C5_SDA 0x400001c3
+ MX8MP_IOMUXC_SPDIF_TX__I2C5_SCL 0x400001c3
+ >;
+ };
+
pinctrl_pmic: pmicgrp {
fsl,pins = <
MX8MP_IOMUXC_GPIO1_IO03__GPIO1_IO03 0x000001c0
>;
};
+ pinctrl_pca6416_int: pca6416_int_grp {
+ fsl,pins = <
+ MX8MP_IOMUXC_GPIO1_IO12__GPIO1_IO12 0x146 /* Input pull-up. */
+ >;
+ };
+
pinctrl_reg_usdhc2_vmmc: regusdhc2vmmcgrp {
fsl,pins = <
MX8MP_IOMUXC_SD2_RESET_B__GPIO2_IO19 0x41
diff --git a/arch/arm64/boot/dts/freescale/imx8mp-phycore-som.dtsi b/arch/arm64/boot/dts/freescale/imx8mp-phycore-som.dtsi
index fc178eebf8aa..79b290a002c1 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp-phycore-som.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mp-phycore-som.dtsi
@@ -60,6 +60,7 @@
ti,tx-internal-delay = <DP83867_RGMIIDCTL_2_00_NS>;
ti,fifo-depth = <DP83867_PHYCR_FIFO_DEPTH_4_B_NIB>;
ti,clk-output-sel = <DP83867_CLK_O_SEL_OFF>;
+ ti,min-output-impedance;
enet-phy-lane-no-swap;
};
};
@@ -113,6 +114,8 @@
regulator-boot-on;
regulator-always-on;
regulator-ramp-delay = <3125>;
+ nxp,dvs-run-voltage = <950000>;
+ nxp,dvs-standby-voltage = <850000>;
};
buck4: BUCK4 {
@@ -167,14 +170,14 @@
regulator-compatible = "LDO4";
regulator-min-microvolt = <800000>;
regulator-max-microvolt = <3300000>;
- regulator-boot-on;
- regulator-always-on;
};
ldo5: LDO5 {
regulator-compatible = "LDO5";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ regulator-always-on;
};
};
};
@@ -194,6 +197,8 @@
/* eMMC */
&usdhc3 {
+ assigned-clocks = <&clk IMX8MP_CLK_USDHC3_ROOT>;
+ assigned-clock-rates = <400000000>;
pinctrl-names = "default", "state_100mhz", "state_200mhz";
pinctrl-0 = <&pinctrl_usdhc3>;
pinctrl-1 = <&pinctrl_usdhc3_100mhz>;
@@ -221,12 +226,12 @@
MX8MP_IOMUXC_SAI1_RXD7__ENET1_RGMII_RD3 0x91
MX8MP_IOMUXC_SAI1_TXC__ENET1_RGMII_RXC 0x91
MX8MP_IOMUXC_SAI1_TXFS__ENET1_RGMII_RX_CTL 0x91
- MX8MP_IOMUXC_SAI1_TXD0__ENET1_RGMII_TD0 0x1f
- MX8MP_IOMUXC_SAI1_TXD1__ENET1_RGMII_TD1 0x1f
- MX8MP_IOMUXC_SAI1_TXD2__ENET1_RGMII_TD2 0x1f
- MX8MP_IOMUXC_SAI1_TXD3__ENET1_RGMII_TD3 0x1f
- MX8MP_IOMUXC_SAI1_TXD4__ENET1_RGMII_TX_CTL 0x1f
- MX8MP_IOMUXC_SAI1_TXD5__ENET1_RGMII_TXC 0x1f
+ MX8MP_IOMUXC_SAI1_TXD0__ENET1_RGMII_TD0 0x12
+ MX8MP_IOMUXC_SAI1_TXD1__ENET1_RGMII_TD1 0x12
+ MX8MP_IOMUXC_SAI1_TXD2__ENET1_RGMII_TD2 0x14
+ MX8MP_IOMUXC_SAI1_TXD3__ENET1_RGMII_TD3 0x14
+ MX8MP_IOMUXC_SAI1_TXD4__ENET1_RGMII_TX_CTL 0x14
+ MX8MP_IOMUXC_SAI1_TXD5__ENET1_RGMII_TXC 0x14
MX8MP_IOMUXC_GPIO1_IO15__GPIO1_IO15 0x11
>;
};
@@ -298,21 +303,21 @@
fsl,pins = <
MX8MP_IOMUXC_NAND_WE_B__USDHC3_CLK 0x196
MX8MP_IOMUXC_NAND_WP_B__USDHC3_CMD 0x1d6
- MX8MP_IOMUXC_NAND_DATA04__USDHC3_DATA0 0x1d6
- MX8MP_IOMUXC_NAND_DATA05__USDHC3_DATA1 0x1d6
- MX8MP_IOMUXC_NAND_DATA06__USDHC3_DATA2 0x1d6
- MX8MP_IOMUXC_NAND_DATA07__USDHC3_DATA3 0x1d6
- MX8MP_IOMUXC_NAND_RE_B__USDHC3_DATA4 0x1d6
- MX8MP_IOMUXC_NAND_CE2_B__USDHC3_DATA5 0x1d6
- MX8MP_IOMUXC_NAND_CE3_B__USDHC3_DATA6 0x1d6
- MX8MP_IOMUXC_NAND_CLE__USDHC3_DATA7 0x1d6
+ MX8MP_IOMUXC_NAND_DATA04__USDHC3_DATA0 0x1d2
+ MX8MP_IOMUXC_NAND_DATA05__USDHC3_DATA1 0x1d2
+ MX8MP_IOMUXC_NAND_DATA06__USDHC3_DATA2 0x1d2
+ MX8MP_IOMUXC_NAND_DATA07__USDHC3_DATA3 0x1d2
+ MX8MP_IOMUXC_NAND_RE_B__USDHC3_DATA4 0x1d2
+ MX8MP_IOMUXC_NAND_CE2_B__USDHC3_DATA5 0x1d2
+ MX8MP_IOMUXC_NAND_CE3_B__USDHC3_DATA6 0x1d2
+ MX8MP_IOMUXC_NAND_CLE__USDHC3_DATA7 0x1d2
MX8MP_IOMUXC_NAND_CE1_B__USDHC3_STROBE 0x196
>;
};
pinctrl_wdog: wdoggrp {
fsl,pins = <
- MX8MP_IOMUXC_GPIO1_IO02__WDOG1_WDOG_B 0xc6
+ MX8MP_IOMUXC_GPIO1_IO02__WDOG1_WDOG_B 0xe6
>;
};
};
diff --git a/arch/arm64/boot/dts/freescale/imx8mp.dtsi b/arch/arm64/boot/dts/freescale/imx8mp.dtsi
index 6b840c05dd77..3f8703f3ba5b 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mp.dtsi
@@ -958,6 +958,7 @@
assigned-clocks = <&clk IMX8MP_CLK_USB_PHY_REF>;
assigned-clock-parents = <&clk IMX8MP_CLK_24M>;
#phy-cells = <0>;
+ status = "disabled";
};
usb3_1: usb@32f10108 {
diff --git a/arch/arm64/boot/dts/freescale/imx8mq-evk.dts b/arch/arm64/boot/dts/freescale/imx8mq-evk.dts
index a1b7582f3ecf..99fed35168eb 100644
--- a/arch/arm64/boot/dts/freescale/imx8mq-evk.dts
+++ b/arch/arm64/boot/dts/freescale/imx8mq-evk.dts
@@ -27,6 +27,17 @@
clock-frequency = <100000000>;
};
+ reg_pcie1: regulator-pcie {
+ compatible = "regulator-fixed";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pcie1_reg>;
+ regulator-name = "MPCIE_3V3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&gpio5 10 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+
reg_usdhc2_vmmc: regulator-vsd-3v3 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_reg_usdhc2>;
@@ -123,6 +134,7 @@
&ddrc {
operating-points-v2 = <&ddrc_opp_table>;
+ status = "okay";
ddrc_opp_table: opp-table {
compatible = "operating-points-v2";
@@ -327,6 +339,20 @@
status = "okay";
};
+&pcie1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pcie1>;
+ reset-gpio = <&gpio5 12 GPIO_ACTIVE_LOW>;
+ clocks = <&clk IMX8MQ_CLK_PCIE2_ROOT>,
+ <&clk IMX8MQ_CLK_PCIE2_AUX>,
+ <&clk IMX8MQ_CLK_PCIE2_PHY>,
+ <&pcie0_refclk>;
+ clock-names = "pcie", "pcie_aux", "pcie_phy", "pcie_bus";
+ vpcie-supply = <&reg_pcie1>;
+ vph-supply = <&vgen5_reg>;
+ status = "okay";
+};
+
&pgc_gpu {
power-supply = <&sw1a_reg>;
};
@@ -482,6 +508,19 @@
>;
};
+ pinctrl_pcie1: pcie1grp {
+ fsl,pins = <
+ MX8MQ_IOMUXC_I2C4_SDA_PCIE2_CLKREQ_B 0x76
+ MX8MQ_IOMUXC_ECSPI2_MISO_GPIO5_IO12 0x16
+ >;
+ };
+
+ pinctrl_pcie1_reg: pcie1reggrp {
+ fsl,pins = <
+ MX8MQ_IOMUXC_ECSPI2_SCLK_GPIO5_IO10 0x16
+ >;
+ };
+
pinctrl_qspi: qspigrp {
fsl,pins = <
MX8MQ_IOMUXC_NAND_ALE_QSPI_A_SCLK 0x82
diff --git a/arch/arm64/boot/dts/freescale/imx8mq-librem5.dtsi b/arch/arm64/boot/dts/freescale/imx8mq-librem5.dtsi
index f3e3418f7edc..05c16376b4d8 100644
--- a/arch/arm64/boot/dts/freescale/imx8mq-librem5.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mq-librem5.dtsi
@@ -278,6 +278,7 @@
&ddrc {
operating-points-v2 = <&ddrc_opp_table>;
+ status = "okay";
ddrc_opp_table: opp-table {
compatible = "operating-points-v2";
@@ -1115,8 +1116,8 @@
status = "okay";
ports {
- port@1 {
- reg = <1>;
+ port@0 {
+ reg = <0>;
mipi1_sensor_ep: endpoint {
remote-endpoint = <&camera1_ep>;
diff --git a/arch/arm64/boot/dts/freescale/imx8mq-mnt-reform2.dts b/arch/arm64/boot/dts/freescale/imx8mq-mnt-reform2.dts
index fa721a13de20..94a13cb500e6 100644
--- a/arch/arm64/boot/dts/freescale/imx8mq-mnt-reform2.dts
+++ b/arch/arm64/boot/dts/freescale/imx8mq-mnt-reform2.dts
@@ -14,6 +14,30 @@
compatible = "mntre,reform2", "boundary,imx8mq-nitrogen8m-som", "fsl,imx8mq";
chassis-type = "laptop";
+ backlight: backlight {
+ compatible = "pwm-backlight";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_backlight>;
+ pwms = <&pwm2 0 10000>;
+ power-supply = <&reg_main_usb>;
+ enable-gpios = <&gpio1 10 GPIO_ACTIVE_HIGH>;
+ brightness-levels = <0 32 64 128 160 200 255>;
+ default-brightness-level = <6>;
+ };
+
+ panel {
+ compatible = "innolux,n125hce-gn1", "simple-panel";
+ power-supply = <&reg_main_3v3>;
+ backlight = <&backlight>;
+ no-hpd;
+
+ port {
+ panel_in: endpoint {
+ remote-endpoint = <&edp_bridge_out>;
+ };
+ };
+ };
+
pcie1_refclk: clock-pcie1-refclk {
compatible = "fixed-clock";
#clock-cells = <0>;
@@ -42,6 +66,22 @@
vin-supply = <&reg_main_5v>;
};
+ reg_main_1v8: regulator-main-1v8 {
+ compatible = "regulator-fixed";
+ regulator-name = "1V8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ vin-supply = <&reg_main_3v3>;
+ };
+
+ reg_main_1v2: regulator-main-1v2 {
+ compatible = "regulator-fixed";
+ regulator-name = "1V2";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ vin-supply = <&reg_main_5v>;
+ };
+
sound {
compatible = "fsl,imx-audio-wm8960";
audio-cpu = <&sai2>;
@@ -61,6 +101,13 @@
};
};
+&dphy {
+ assigned-clocks = <&clk IMX8MQ_CLK_DSI_PHY_REF>;
+ assigned-clock-parents = <&clk IMX8MQ_SYS1_PLL_800M>;
+ assigned-clock-rates = <25000000>;
+ status = "okay";
+};
+
&fec1 {
status = "okay";
};
@@ -84,6 +131,67 @@
};
};
+&i2c4 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c4>;
+ clock-frequency = <400000>;
+ status = "okay";
+
+ edp_bridge: bridge@2c {
+ compatible = "ti,sn65dsi86";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_edp_bridge>;
+ reg = <0x2c>;
+ enable-gpios = <&gpio3 20 GPIO_ACTIVE_HIGH>;
+ vccio-supply = <&reg_main_1v8>;
+ vpll-supply = <&reg_main_1v8>;
+ vcca-supply = <&reg_main_1v2>;
+ vcc-supply = <&reg_main_1v2>;
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ edp_bridge_in: endpoint {
+ remote-endpoint = <&mipi_dsi_out>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+
+ edp_bridge_out: endpoint {
+ remote-endpoint = <&panel_in>;
+ };
+ };
+ };
+ };
+};
+
+&lcdif {
+ assigned-clocks = <&clk IMX8MQ_CLK_LCDIF_PIXEL>;
+ assigned-clock-parents = <&clk IMX8MQ_SYS1_PLL_800M>;
+ /delete-property/assigned-clock-rates;
+ status = "okay";
+};
+
+&mipi_dsi {
+ status = "okay";
+
+ ports {
+ port@1 {
+ reg = <1>;
+
+ mipi_dsi_out: endpoint {
+ remote-endpoint = <&edp_bridge_in>;
+ };
+ };
+ };
+};
+
&pcie1 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_pcie1>;
@@ -96,6 +204,13 @@
status = "okay";
};
+&pwm2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pwm2>;
+ status = "okay";
+};
+
+
&reg_1p8v {
vin-supply = <&reg_main_5v>;
};
@@ -169,10 +284,29 @@
};
&iomuxc {
+ pinctrl_backlight: backlightgrp {
+ fsl,pins = <
+ MX8MQ_IOMUXC_GPIO1_IO10_GPIO1_IO10 0x3
+ >;
+ };
+
+ pinctrl_edp_bridge: edpbridgegrp {
+ fsl,pins = <
+ MX8MQ_IOMUXC_SAI5_RXC_GPIO3_IO20 0x1
+ >;
+ };
+
pinctrl_i2c3: i2c3grp {
fsl,pins = <
- MX8MQ_IOMUXC_I2C3_SCL_I2C3_SCL 0x4000007f
- MX8MQ_IOMUXC_I2C3_SDA_I2C3_SDA 0x4000007f
+ MX8MQ_IOMUXC_I2C3_SCL_I2C3_SCL 0x40000022
+ MX8MQ_IOMUXC_I2C3_SDA_I2C3_SDA 0x40000022
+ >;
+ };
+
+ pinctrl_i2c4: i2c4grp {
+ fsl,pins = <
+ MX8MQ_IOMUXC_I2C4_SCL_I2C4_SCL 0x40000022
+ MX8MQ_IOMUXC_I2C4_SDA_I2C4_SDA 0x40000022
>;
};
@@ -182,6 +316,12 @@
>;
};
+ pinctrl_pwm2: pwm2grp {
+ fsl,pins = <
+ MX8MQ_IOMUXC_SPDIF_RX_PWM2_OUT 0x3
+ >;
+ };
+
pinctrl_sai2: sai2grp {
fsl,pins = <
MX8MQ_IOMUXC_SAI2_RXD0_SAI2_RX_DATA0 0xd6
diff --git a/arch/arm64/boot/dts/freescale/imx8mq-tqma8mq.dtsi b/arch/arm64/boot/dts/freescale/imx8mq-tqma8mq.dtsi
index 8aedcddfeab8..38ffcd145b33 100644
--- a/arch/arm64/boot/dts/freescale/imx8mq-tqma8mq.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mq-tqma8mq.dtsi
@@ -272,10 +272,6 @@
status = "okay";
};
-&vpu {
- status = "okay";
-};
-
/* Attention: wdog reset forcing POR needs baseboard support */
&wdog1 {
status = "okay";
diff --git a/arch/arm64/boot/dts/freescale/imx8mq.dtsi b/arch/arm64/boot/dts/freescale/imx8mq.dtsi
index 2df2510d0118..5b3e849f554d 100644
--- a/arch/arm64/boot/dts/freescale/imx8mq.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mq.dtsi
@@ -554,7 +554,7 @@
assigned-clock-rates = <0>, <0>, <0>, <594000000>;
status = "disabled";
- port@0 {
+ port {
lcdif_mipi_dsi: endpoint {
remote-endpoint = <&mipi_dsi_lcdif_in>;
};
@@ -737,7 +737,21 @@
pgc_vpu: power-domain@6 {
#power-domain-cells = <0>;
reg = <IMX8M_POWER_DOMAIN_VPU>;
- clocks = <&clk IMX8MQ_CLK_VPU_DEC_ROOT>;
+ clocks = <&clk IMX8MQ_CLK_VPU_DEC_ROOT>,
+ <&clk IMX8MQ_CLK_VPU_G1_ROOT>,
+ <&clk IMX8MQ_CLK_VPU_G2_ROOT>;
+ assigned-clocks = <&clk IMX8MQ_CLK_VPU_G1>,
+ <&clk IMX8MQ_CLK_VPU_G2>,
+ <&clk IMX8MQ_CLK_VPU_BUS>,
+ <&clk IMX8MQ_VPU_PLL_BYPASS>;
+ assigned-clock-parents = <&clk IMX8MQ_VPU_PLL_OUT>,
+ <&clk IMX8MQ_VPU_PLL_OUT>,
+ <&clk IMX8MQ_SYS1_PLL_800M>,
+ <&clk IMX8MQ_VPU_PLL>;
+ assigned-clock-rates = <600000000>,
+ <600000000>,
+ <800000000>,
+ <0>;
};
pgc_disp: power-domain@7 {
@@ -1151,8 +1165,8 @@
#address-cells = <1>;
#size-cells = <0>;
- port@0 {
- reg = <0>;
+ port@1 {
+ reg = <1>;
csi1_mipi_ep: endpoint {
remote-endpoint = <&csi1_ep>;
@@ -1203,8 +1217,8 @@
#address-cells = <1>;
#size-cells = <0>;
- port@0 {
- reg = <0>;
+ port@1 {
+ reg = <1>;
csi2_mipi_ep: endpoint {
remote-endpoint = <&csi2_ep>;
@@ -1457,30 +1471,31 @@
status = "disabled";
};
- vpu: video-codec@38300000 {
- compatible = "nxp,imx8mq-vpu";
- reg = <0x38300000 0x10000>,
- <0x38310000 0x10000>,
- <0x38320000 0x10000>;
- reg-names = "g1", "g2", "ctrl";
- interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>;
- interrupt-names = "g1", "g2";
+ vpu_g1: video-codec@38300000 {
+ compatible = "nxp,imx8mq-vpu-g1";
+ reg = <0x38300000 0x10000>;
+ interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX8MQ_CLK_VPU_G1_ROOT>;
+ power-domains = <&vpu_blk_ctrl IMX8MQ_VPUBLK_PD_G1>;
+ };
+
+ vpu_g2: video-codec@38310000 {
+ compatible = "nxp,imx8mq-vpu-g2";
+ reg = <0x38310000 0x10000>;
+ interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX8MQ_CLK_VPU_G2_ROOT>;
+ power-domains = <&vpu_blk_ctrl IMX8MQ_VPUBLK_PD_G2>;
+ };
+
+ vpu_blk_ctrl: blk-ctrl@38320000 {
+ compatible = "fsl,imx8mq-vpu-blk-ctrl";
+ reg = <0x38320000 0x100>;
+ power-domains = <&pgc_vpu>, <&pgc_vpu>, <&pgc_vpu>;
+ power-domain-names = "bus", "g1", "g2";
clocks = <&clk IMX8MQ_CLK_VPU_G1_ROOT>,
- <&clk IMX8MQ_CLK_VPU_G2_ROOT>,
- <&clk IMX8MQ_CLK_VPU_DEC_ROOT>;
- clock-names = "g1", "g2", "bus";
- assigned-clocks = <&clk IMX8MQ_CLK_VPU_G1>,
- <&clk IMX8MQ_CLK_VPU_G2>,
- <&clk IMX8MQ_CLK_VPU_BUS>,
- <&clk IMX8MQ_VPU_PLL_BYPASS>;
- assigned-clock-parents = <&clk IMX8MQ_VPU_PLL_OUT>,
- <&clk IMX8MQ_VPU_PLL_OUT>,
- <&clk IMX8MQ_SYS1_PLL_800M>,
- <&clk IMX8MQ_VPU_PLL>;
- assigned-clock-rates = <600000000>, <600000000>,
- <800000000>, <0>;
- power-domains = <&pgc_vpu>;
+ <&clk IMX8MQ_CLK_VPU_G2_ROOT>;
+ clock-names = "g1", "g2";
+ #power-domain-cells = <1>;
};
pcie0: pcie@33800000 {
@@ -1579,6 +1594,7 @@
<&clk IMX8MQ_DRAM_PLL_OUT>,
<&clk IMX8MQ_CLK_DRAM_ALT>,
<&clk IMX8MQ_CLK_DRAM_APB>;
+ status = "disabled";
};
ddr-pmu@3d800000 {
diff --git a/arch/arm64/boot/dts/freescale/imx8qm-ss-conn.dtsi b/arch/arm64/boot/dts/freescale/imx8qm-ss-conn.dtsi
index 42637a45701c..ec1639174e2e 100644
--- a/arch/arm64/boot/dts/freescale/imx8qm-ss-conn.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8qm-ss-conn.dtsi
@@ -19,3 +19,7 @@
&usdhc2 {
compatible = "fsl,imx8qm-usdhc", "fsl,imx8qxp-usdhc", "fsl,imx7d-usdhc";
};
+
+&usdhc3 {
+ compatible = "fsl,imx8qm-usdhc", "fsl,imx8qxp-usdhc", "fsl,imx7d-usdhc";
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8qm-ss-lsio.dtsi b/arch/arm64/boot/dts/freescale/imx8qm-ss-lsio.dtsi
index 30896610c654..669aa14ce9f7 100644
--- a/arch/arm64/boot/dts/freescale/imx8qm-ss-lsio.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8qm-ss-lsio.dtsi
@@ -56,6 +56,14 @@
compatible = "fsl,imx8-mu-scu", "fsl,imx8qm-mu", "fsl,imx6sx-mu";
};
+&lsio_mu5 {
+ compatible = "fsl,imx8qm-mu", "fsl,imx6sx-mu";
+};
+
+&lsio_mu6 {
+ compatible = "fsl,imx8qm-mu", "fsl,imx6sx-mu";
+};
+
&lsio_mu13 {
compatible = "fsl,imx8qm-mu", "fsl,imx6sx-mu";
};
diff --git a/arch/arm64/boot/dts/freescale/imx8qm.dtsi b/arch/arm64/boot/dts/freescale/imx8qm.dtsi
index 4a7c017b5f31..be8c76a0554c 100644
--- a/arch/arm64/boot/dts/freescale/imx8qm.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8qm.dtsi
@@ -20,6 +20,9 @@
mmc1 = &usdhc2;
mmc2 = &usdhc3;
serial0 = &lpuart0;
+ serial1 = &lpuart1;
+ serial2 = &lpuart2;
+ serial3 = &lpuart3;
};
cpus {
@@ -54,7 +57,7 @@
A53_0: cpu@0 {
device_type = "cpu";
- compatible = "arm,cortex-a53", "arm,armv8";
+ compatible = "arm,cortex-a53";
reg = <0x0 0x0>;
enable-method = "psci";
i-cache-size = <0x8000>;
@@ -68,7 +71,7 @@
A53_1: cpu@1 {
device_type = "cpu";
- compatible = "arm,cortex-a53", "arm,armv8";
+ compatible = "arm,cortex-a53";
reg = <0x0 0x1>;
enable-method = "psci";
i-cache-size = <0x8000>;
@@ -82,7 +85,7 @@
A53_2: cpu@2 {
device_type = "cpu";
- compatible = "arm,cortex-a53", "arm,armv8";
+ compatible = "arm,cortex-a53";
reg = <0x0 0x2>;
enable-method = "psci";
i-cache-size = <0x8000>;
@@ -96,7 +99,7 @@
A53_3: cpu@3 {
device_type = "cpu";
- compatible = "arm,cortex-a53", "arm,armv8";
+ compatible = "arm,cortex-a53";
reg = <0x0 0x3>;
enable-method = "psci";
i-cache-size = <0x8000>;
@@ -110,7 +113,7 @@
A72_0: cpu@100 {
device_type = "cpu";
- compatible = "arm,cortex-a72", "arm,armv8";
+ compatible = "arm,cortex-a72";
reg = <0x0 0x100>;
enable-method = "psci";
i-cache-size = <0xC000>;
@@ -124,7 +127,7 @@
A72_1: cpu@101 {
device_type = "cpu";
- compatible = "arm,cortex-a72", "arm,armv8";
+ compatible = "arm,cortex-a72";
reg = <0x0 0x101>;
enable-method = "psci";
next-level-cache = <&A72_L2>;
@@ -201,6 +204,9 @@
compatible = "fsl,imx8qm-iomuxc";
};
+ rtc: rtc {
+ compatible = "fsl,imx8qxp-sc-rtc";
+ };
};
/* sorted in register address */
diff --git a/arch/arm64/boot/dts/freescale/imx8qxp-ss-adma.dtsi b/arch/arm64/boot/dts/freescale/imx8qxp-ss-adma.dtsi
index dc1daa8dc72f..7bae516004bf 100644
--- a/arch/arm64/boot/dts/freescale/imx8qxp-ss-adma.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8qxp-ss-adma.dtsi
@@ -5,19 +5,19 @@
*/
&lpuart0 {
- compatible = "fsl,imx8qxp-lpuart", "fsl,imx7ulp-lpuart";
+ compatible = "fsl,imx8qxp-lpuart";
};
&lpuart1 {
- compatible = "fsl,imx8qxp-lpuart", "fsl,imx7ulp-lpuart";
+ compatible = "fsl,imx8qxp-lpuart";
};
&lpuart2 {
- compatible = "fsl,imx8qxp-lpuart", "fsl,imx7ulp-lpuart";
+ compatible = "fsl,imx8qxp-lpuart";
};
&lpuart3 {
- compatible = "fsl,imx8qxp-lpuart", "fsl,imx7ulp-lpuart";
+ compatible = "fsl,imx8qxp-lpuart";
};
&i2c0 {
diff --git a/arch/arm64/boot/dts/freescale/imx8qxp-ss-lsio.dtsi b/arch/arm64/boot/dts/freescale/imx8qxp-ss-lsio.dtsi
index 11395479ffc0..8e2152c6eb88 100644
--- a/arch/arm64/boot/dts/freescale/imx8qxp-ss-lsio.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8qxp-ss-lsio.dtsi
@@ -56,6 +56,14 @@
compatible = "fsl,imx8-mu-scu", "fsl,imx8qxp-mu", "fsl,imx6sx-mu";
};
+&lsio_mu5 {
+ compatible = "fsl,imx8qxp-mu", "fsl,imx6sx-mu";
+};
+
+&lsio_mu6 {
+ compatible = "fsl,imx8qxp-mu", "fsl,imx6sx-mu";
+};
+
&lsio_mu13 {
compatible = "fsl,imx8qxp-mu", "fsl,imx6sx-mu";
};
diff --git a/arch/arm64/boot/dts/freescale/imx8ulp.dtsi b/arch/arm64/boot/dts/freescale/imx8ulp.dtsi
index a987ff7156bd..09f7364dd1d0 100644
--- a/arch/arm64/boot/dts/freescale/imx8ulp.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8ulp.dtsi
@@ -132,7 +132,7 @@
scmi_sensor: protocol@15 {
reg = <0x15>;
- #thermal-sensor-cells = <0>;
+ #thermal-sensor-cells = <1>;
};
};
};
diff --git a/arch/arm64/boot/dts/freescale/mba8mx.dtsi b/arch/arm64/boot/dts/freescale/mba8mx.dtsi
index f27e3c8de916..c2f0f1a1566c 100644
--- a/arch/arm64/boot/dts/freescale/mba8mx.dtsi
+++ b/arch/arm64/boot/dts/freescale/mba8mx.dtsi
@@ -66,6 +66,12 @@
};
};
+ pcie0_refclk: pcie0-refclk {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <100000000>;
+ };
+
reg_hub_vbus: regulator-hub-vbus {
compatible = "regulator-fixed";
regulator-name = "MBA8MX_HUB_VBUS";
@@ -91,7 +97,7 @@
sound {
compatible = "fsl,imx-audio-tlv320aic32x4";
- model = "tqm-tlv320aic32";
+ model = "imx-audio-tlv320aic32x4";
ssi-controller = <&sai3>;
audio-codec = <&tlv320aic3x04>;
};
diff --git a/arch/arm64/boot/dts/intel/socfpga_agilex.dtsi b/arch/arm64/boot/dts/intel/socfpga_agilex.dtsi
index 0dd2d2ee765a..c78371703e76 100644
--- a/arch/arm64/boot/dts/intel/socfpga_agilex.dtsi
+++ b/arch/arm64/boot/dts/intel/socfpga_agilex.dtsi
@@ -300,7 +300,7 @@
status = "disabled";
};
- mmc: dwmmc0@ff808000 {
+ mmc: mmc@ff808000 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "altr,socfpga-dw-mshc";
@@ -337,7 +337,7 @@
reg = <0xffe00000 0x40000>;
};
- pdma: pdma@ffda0000 {
+ pdma: dma-controller@ffda0000 {
compatible = "arm,pl330", "arm,primecell";
reg = <0xffda0000 0x1000>;
interrupts = <GIC_SPI 81 IRQ_TYPE_LEVEL_HIGH>,
@@ -502,7 +502,7 @@
};
usb0: usb@ffb00000 {
- compatible = "snps,dwc2";
+ compatible = "intel,socfpga-agilex-hsotg", "snps,dwc2";
reg = <0xffb00000 0x40000>;
interrupts = <GIC_SPI 93 IRQ_TYPE_LEVEL_HIGH>;
phys = <&usbphy0>;
@@ -510,12 +510,13 @@
resets = <&rst USB0_RESET>, <&rst USB0_OCP_RESET>;
reset-names = "dwc2", "dwc2-ecc";
clocks = <&clkmgr AGILEX_USB_CLK>;
+ clock-names = "otg";
iommus = <&smmu 6>;
status = "disabled";
};
usb1: usb@ffb40000 {
- compatible = "snps,dwc2";
+ compatible = "intel,socfpga-agilex-hsotg", "snps,dwc2";
reg = <0xffb40000 0x40000>;
interrupts = <GIC_SPI 94 IRQ_TYPE_LEVEL_HIGH>;
phys = <&usbphy0>;
diff --git a/arch/arm64/boot/dts/intel/socfpga_agilex_socdk.dts b/arch/arm64/boot/dts/intel/socfpga_agilex_socdk.dts
index 0f7a0ba344be..26cd3c121757 100644
--- a/arch/arm64/boot/dts/intel/socfpga_agilex_socdk.dts
+++ b/arch/arm64/boot/dts/intel/socfpga_agilex_socdk.dts
@@ -6,6 +6,7 @@
/ {
model = "SoCFPGA Agilex SoCDK";
+ compatible = "intel,socfpga-agilex-socdk", "intel,socfpga-agilex";
aliases {
serial0 = &uart0;
@@ -20,17 +21,17 @@
leds {
compatible = "gpio-leds";
- hps0 {
+ led0 {
label = "hps_led0";
gpios = <&portb 20 GPIO_ACTIVE_HIGH>;
};
- hps1 {
+ led1 {
label = "hps_led1";
gpios = <&portb 19 GPIO_ACTIVE_HIGH>;
};
- hps2 {
+ led2 {
label = "hps_led2";
gpios = <&portb 21 GPIO_ACTIVE_HIGH>;
};
diff --git a/arch/arm64/boot/dts/intel/socfpga_agilex_socdk_nand.dts b/arch/arm64/boot/dts/intel/socfpga_agilex_socdk_nand.dts
index 57f83481f551..51f83f96ec65 100644
--- a/arch/arm64/boot/dts/intel/socfpga_agilex_socdk_nand.dts
+++ b/arch/arm64/boot/dts/intel/socfpga_agilex_socdk_nand.dts
@@ -6,6 +6,7 @@
/ {
model = "SoCFPGA Agilex SoCDK";
+ compatible = "intel,socfpga-agilex-socdk", "intel,socfpga-agilex";
aliases {
serial0 = &uart0;
diff --git a/arch/arm64/boot/dts/intel/socfpga_n5x_socdk.dts b/arch/arm64/boot/dts/intel/socfpga_n5x_socdk.dts
index f3c1310dae0a..62c66e52b656 100644
--- a/arch/arm64/boot/dts/intel/socfpga_n5x_socdk.dts
+++ b/arch/arm64/boot/dts/intel/socfpga_n5x_socdk.dts
@@ -6,6 +6,7 @@
/ {
model = "eASIC N5X SoCDK";
+ compatible = "intel,n5x-socdk", "intel,socfpga-agilex";
aliases {
serial0 = &uart0;
@@ -23,6 +24,15 @@
/* We expect the bootloader to fill in the reg */
reg = <0 0 0 0>;
};
+
+ soc {
+ sdram_edac: memory-controller@f87f8000 {
+ compatible = "snps,ddrc-3.80a";
+ reg = <0xf87f8000 0x400>;
+ interrupts = <0 175 4>;
+ status = "okay";
+ };
+ };
};
&clkmgr {
diff --git a/arch/arm64/boot/dts/lg/lg1312.dtsi b/arch/arm64/boot/dts/lg/lg1312.dtsi
index 081fe7a9f605..bec97480a960 100644
--- a/arch/arm64/boot/dts/lg/lg1312.dtsi
+++ b/arch/arm64/boot/dts/lg/lg1312.dtsi
@@ -182,12 +182,13 @@
clocks = <&clk_bus>;
clock-names = "apb_pclk";
};
- dmac0: dma@c1128000 {
+ dmac0: dma-controller@c1128000 {
compatible = "arm,pl330", "arm,primecell";
reg = <0x0 0xc1128000 0x1000>;
interrupts = <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clk_bus>;
clock-names = "apb_pclk";
+ #dma-cells = <1>;
};
gpio0: gpio@fd400000 {
#gpio-cells = <2>;
diff --git a/arch/arm64/boot/dts/lg/lg1313.dtsi b/arch/arm64/boot/dts/lg/lg1313.dtsi
index 604bb6975337..ada3d4dc6305 100644
--- a/arch/arm64/boot/dts/lg/lg1313.dtsi
+++ b/arch/arm64/boot/dts/lg/lg1313.dtsi
@@ -182,12 +182,13 @@
clocks = <&clk_bus>;
clock-names = "apb_pclk";
};
- dmac0: dma@c1128000 {
+ dmac0: dma-controller@c1128000 {
compatible = "arm,pl330", "arm,primecell";
reg = <0x0 0xc1128000 0x1000>;
interrupts = <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clk_bus>;
clock-names = "apb_pclk";
+ #dma-cells = <1>;
};
gpio0: gpio@fd400000 {
#gpio-cells = <2>;
diff --git a/arch/arm64/boot/dts/marvell/armada-3720-turris-mox.dts b/arch/arm64/boot/dts/marvell/armada-3720-turris-mox.dts
index 04da07ae4420..1cee26479bfe 100644
--- a/arch/arm64/boot/dts/marvell/armada-3720-turris-mox.dts
+++ b/arch/arm64/boot/dts/marvell/armada-3720-turris-mox.dts
@@ -18,6 +18,7 @@
aliases {
spi0 = &spi0;
+ ethernet0 = &eth0;
ethernet1 = &eth1;
mmc0 = &sdhci0;
mmc1 = &sdhci1;
@@ -138,7 +139,9 @@
/*
* U-Boot port for Turris Mox has a bug which always expects that "ranges" DT property
* contains exactly 2 ranges with 3 (child) address cells, 2 (parent) address cells and
- * 2 size cells and also expects that the second range starts at 16 MB offset. If these
+ * 2 size cells and also expects that the second range starts at 16 MB offset. Also it
+ * expects that first range uses same address for PCI (child) and CPU (parent) cells (so
+ * no remapping) and that this address is the lowest from all specified ranges. If these
* conditions are not met then U-Boot crashes during loading kernel DTB file. PCIe address
* space is 128 MB long, so the best split between MEM and IO is to use fixed 16 MB window
* for IO and the rest 112 MB (64+32+16) for MEM, despite that maximal IO size is just 64 kB.
@@ -147,6 +150,9 @@
* https://source.denx.de/u-boot/u-boot/-/commit/cb2ddb291ee6fcbddd6d8f4ff49089dfe580f5d7
* https://source.denx.de/u-boot/u-boot/-/commit/c64ac3b3185aeb3846297ad7391fc6df8ecd73bf
* https://source.denx.de/u-boot/u-boot/-/commit/4a82fca8e330157081fc132a591ebd99ba02ee33
+ * Bug related to requirement of same child and parent addresses for first range is fixed
+ * in U-Boot version 2022.04 by following commit:
+ * https://source.denx.de/u-boot/u-boot/-/commit/1fd54253bca7d43d046bba4853fe5fafd034bc17
*/
#address-cells = <3>;
#size-cells = <2>;
diff --git a/arch/arm64/boot/dts/marvell/armada-37xx.dtsi b/arch/arm64/boot/dts/marvell/armada-37xx.dtsi
index 673f4906eef9..30233de58bb3 100644
--- a/arch/arm64/boot/dts/marvell/armada-37xx.dtsi
+++ b/arch/arm64/boot/dts/marvell/armada-37xx.dtsi
@@ -489,6 +489,7 @@
bus-range = <0x00 0xff>;
interrupts = <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>;
#interrupt-cells = <1>;
+ clocks = <&sb_periph_clk 13>;
msi-parent = <&pcie0>;
msi-controller;
/*
@@ -499,7 +500,7 @@
* (totaling 127 MiB) for MEM.
*/
ranges = <0x82000000 0 0xe8000000 0 0xe8000000 0 0x07f00000 /* Port 0 MEM */
- 0x81000000 0 0xefff0000 0 0xefff0000 0 0x00010000>; /* Port 0 IO */
+ 0x81000000 0 0x00000000 0 0xefff0000 0 0x00010000>; /* Port 0 IO */
interrupt-map-mask = <0 0 0 7>;
interrupt-map = <0 0 0 1 &pcie_intc 0>,
<0 0 0 2 &pcie_intc 1>,
diff --git a/arch/arm64/boot/dts/mediatek/mt2712-evb.dts b/arch/arm64/boot/dts/mediatek/mt2712-evb.dts
index 7d369fdd3117..11aa135aa0f3 100644
--- a/arch/arm64/boot/dts/mediatek/mt2712-evb.dts
+++ b/arch/arm64/boot/dts/mediatek/mt2712-evb.dts
@@ -110,6 +110,7 @@
phy-handle = <&ethernet_phy0>;
mediatek,tx-delay-ps = <1530>;
snps,reset-gpio = <&pio 87 GPIO_ACTIVE_LOW>;
+ snps,reset-delays-us = <0 10000 10000>;
pinctrl-names = "default", "sleep";
pinctrl-0 = <&eth_default>;
pinctrl-1 = <&eth_sleep>;
diff --git a/arch/arm64/boot/dts/mediatek/mt2712e.dtsi b/arch/arm64/boot/dts/mediatek/mt2712e.dtsi
index de16c0d80c30..a27b7628c5f7 100644
--- a/arch/arm64/boot/dts/mediatek/mt2712e.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt2712e.dtsi
@@ -726,7 +726,7 @@
};
eth: ethernet@1101c000 {
- compatible = "mediatek,mt2712-gmac";
+ compatible = "mediatek,mt2712-gmac", "snps,dwmac-4.20a";
reg = <0 0x1101c000 0 0x1300>;
interrupts = <GIC_SPI 237 IRQ_TYPE_LEVEL_LOW>;
interrupt-names = "macirq";
@@ -734,15 +734,19 @@
clock-names = "axi",
"apb",
"mac_main",
- "ptp_ref";
+ "ptp_ref",
+ "rmii_internal";
clocks = <&pericfg CLK_PERI_GMAC>,
<&pericfg CLK_PERI_GMAC_PCLK>,
<&topckgen CLK_TOP_ETHER_125M_SEL>,
- <&topckgen CLK_TOP_ETHER_50M_SEL>;
+ <&topckgen CLK_TOP_ETHER_50M_SEL>,
+ <&topckgen CLK_TOP_ETHER_50M_RMII_SEL>;
assigned-clocks = <&topckgen CLK_TOP_ETHER_125M_SEL>,
- <&topckgen CLK_TOP_ETHER_50M_SEL>;
+ <&topckgen CLK_TOP_ETHER_50M_SEL>,
+ <&topckgen CLK_TOP_ETHER_50M_RMII_SEL>;
assigned-clock-parents = <&topckgen CLK_TOP_ETHERPLL_125M>,
- <&topckgen CLK_TOP_APLL1_D3>;
+ <&topckgen CLK_TOP_APLL1_D3>,
+ <&topckgen CLK_TOP_ETHERPLL_50M>;
power-domains = <&scpsys MT2712_POWER_DOMAIN_AUDIO>;
mediatek,pericfg = <&pericfg>;
snps,axi-config = <&stmmac_axi_setup>;
diff --git a/arch/arm64/boot/dts/mediatek/mt6358.dtsi b/arch/arm64/boot/dts/mediatek/mt6358.dtsi
index 95145076b7e6..98f3b0e0c9f6 100644
--- a/arch/arm64/boot/dts/mediatek/mt6358.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt6358.dtsi
@@ -2,6 +2,7 @@
/*
* Copyright (c) 2020 MediaTek Inc.
*/
+#include <dt-bindings/input/input.h>
&pwrap {
pmic: mt6358 {
@@ -357,5 +358,16 @@
mt6358rtc: mt6358rtc {
compatible = "mediatek,mt6358-rtc";
};
+
+ mt6358keys: mt6358keys {
+ compatible = "mediatek,mt6358-keys";
+ power {
+ linux,keycodes = <KEY_POWER>;
+ wakeup-source;
+ };
+ home {
+ linux,keycodes = <KEY_HOME>;
+ };
+ };
};
};
diff --git a/arch/arm64/boot/dts/mediatek/mt7986a-rfb.dts b/arch/arm64/boot/dts/mediatek/mt7986a-rfb.dts
index 5cd760abff51..21e420829572 100644
--- a/arch/arm64/boot/dts/mediatek/mt7986a-rfb.dts
+++ b/arch/arm64/boot/dts/mediatek/mt7986a-rfb.dts
@@ -19,7 +19,8 @@
stdout-path = "serial0:115200n8";
};
- memory {
+ memory@40000000 {
+ device_type = "memory";
reg = <0 0x40000000 0 0x40000000>;
};
};
diff --git a/arch/arm64/boot/dts/mediatek/mt7986a.dtsi b/arch/arm64/boot/dts/mediatek/mt7986a.dtsi
index b8da76b6ba47..694acf8f5b70 100644
--- a/arch/arm64/boot/dts/mediatek/mt7986a.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt7986a.dtsi
@@ -6,16 +6,18 @@
#include <dt-bindings/interrupt-controller/irq.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/clock/mt7986-clk.h>
/ {
interrupt-parent = <&gic>;
#address-cells = <2>;
#size-cells = <2>;
- system_clk: dummy40m {
+ clk40m: oscillator@0 {
compatible = "fixed-clock";
clock-frequency = <40000000>;
#clock-cells = <0>;
+ clock-output-names = "clkxtal";
};
cpus {
@@ -98,6 +100,18 @@
interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>;
};
+ infracfg: infracfg@10001000 {
+ compatible = "mediatek,mt7986-infracfg", "syscon";
+ reg = <0 0x10001000 0 0x1000>;
+ #clock-cells = <1>;
+ };
+
+ topckgen: topckgen@1001b000 {
+ compatible = "mediatek,mt7986-topckgen", "syscon";
+ reg = <0 0x1001B000 0 0x1000>;
+ #clock-cells = <1>;
+ };
+
watchdog: watchdog@1001c000 {
compatible = "mediatek,mt7986-wdt",
"mediatek,mt6589-wdt";
@@ -107,6 +121,12 @@
status = "disabled";
};
+ apmixedsys: apmixedsys@1001e000 {
+ compatible = "mediatek,mt7986-apmixedsys";
+ reg = <0 0x1001E000 0 0x1000>;
+ #clock-cells = <1>;
+ };
+
pio: pinctrl@1001f000 {
compatible = "mediatek,mt7986a-pinctrl";
reg = <0 0x1001f000 0 0x1000>,
@@ -128,11 +148,25 @@
#interrupt-cells = <2>;
};
+ sgmiisys0: syscon@10060000 {
+ compatible = "mediatek,mt7986-sgmiisys_0",
+ "syscon";
+ reg = <0 0x10060000 0 0x1000>;
+ #clock-cells = <1>;
+ };
+
+ sgmiisys1: syscon@10070000 {
+ compatible = "mediatek,mt7986-sgmiisys_1",
+ "syscon";
+ reg = <0 0x10070000 0 0x1000>;
+ #clock-cells = <1>;
+ };
+
trng: trng@1020f000 {
compatible = "mediatek,mt7986-rng",
"mediatek,mt7623-rng";
reg = <0 0x1020f000 0 0x100>;
- clocks = <&system_clk>;
+ clocks = <&infracfg CLK_INFRA_TRNG_CK>;
clock-names = "rng";
status = "disabled";
};
@@ -142,7 +176,13 @@
"mediatek,mt6577-uart";
reg = <0 0x11002000 0 0x400>;
interrupts = <GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&system_clk>;
+ clocks = <&infracfg CLK_INFRA_UART0_SEL>,
+ <&infracfg CLK_INFRA_UART0_CK>;
+ clock-names = "baud", "bus";
+ assigned-clocks = <&topckgen CLK_TOP_UART_SEL>,
+ <&infracfg CLK_INFRA_UART0_SEL>;
+ assigned-clock-parents = <&topckgen CLK_TOP_XTAL>,
+ <&topckgen CLK_TOP_UART_SEL>;
status = "disabled";
};
@@ -151,7 +191,11 @@
"mediatek,mt6577-uart";
reg = <0 0x11003000 0 0x400>;
interrupts = <GIC_SPI 124 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&system_clk>;
+ clocks = <&infracfg CLK_INFRA_UART1_SEL>,
+ <&infracfg CLK_INFRA_UART1_CK>;
+ clock-names = "baud", "bus";
+ assigned-clocks = <&infracfg CLK_INFRA_UART1_SEL>;
+ assigned-clock-parents = <&topckgen CLK_TOP_F26M_SEL>;
status = "disabled";
};
@@ -160,10 +204,24 @@
"mediatek,mt6577-uart";
reg = <0 0x11004000 0 0x400>;
interrupts = <GIC_SPI 125 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&system_clk>;
+ clocks = <&infracfg CLK_INFRA_UART2_SEL>,
+ <&infracfg CLK_INFRA_UART2_CK>;
+ clock-names = "baud", "bus";
+ assigned-clocks = <&infracfg CLK_INFRA_UART2_SEL>;
+ assigned-clock-parents = <&topckgen CLK_TOP_F26M_SEL>;
status = "disabled";
};
+ ethsys: syscon@15000000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "mediatek,mt7986-ethsys",
+ "syscon";
+ reg = <0 0x15000000 0 0x1000>;
+ #clock-cells = <1>;
+ #reset-cells = <1>;
+ };
+
};
};
diff --git a/arch/arm64/boot/dts/mediatek/mt7986b-rfb.dts b/arch/arm64/boot/dts/mediatek/mt7986b-rfb.dts
index 5fb752edd754..d73467ea3641 100644
--- a/arch/arm64/boot/dts/mediatek/mt7986b-rfb.dts
+++ b/arch/arm64/boot/dts/mediatek/mt7986b-rfb.dts
@@ -19,7 +19,8 @@
stdout-path = "serial0:115200n8";
};
- memory {
+ memory@40000000 {
+ device_type = "memory";
reg = <0 0x40000000 0 0x40000000>;
};
};
diff --git a/arch/arm64/boot/dts/mediatek/mt8183.dtsi b/arch/arm64/boot/dts/mediatek/mt8183.dtsi
index 00f2ddd245e1..4b08691ed39e 100644
--- a/arch/arm64/boot/dts/mediatek/mt8183.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8183.dtsi
@@ -1594,6 +1594,18 @@
power-domains = <&spm MT8183_POWER_DOMAIN_VENC>;
};
+ venc_jpg: venc_jpg@17030000 {
+ compatible = "mediatek,mt8183-jpgenc", "mediatek,mtk-jpgenc";
+ reg = <0 0x17030000 0 0x1000>;
+ interrupts = <GIC_SPI 249 IRQ_TYPE_LEVEL_LOW>;
+ mediatek,larb = <&larb4>;
+ iommus = <&iommu M4U_PORT_JPGENC_RDMA>,
+ <&iommu M4U_PORT_JPGENC_BSDMA>;
+ power-domains = <&spm MT8183_POWER_DOMAIN_VENC>;
+ clocks = <&vencsys CLK_VENC_JPGENC>;
+ clock-names = "jpgenc";
+ };
+
ipu_conn: syscon@19000000 {
compatible = "mediatek,mt8183-ipu_conn", "syscon";
reg = <0 0x19000000 0 0x1000>;
diff --git a/arch/arm64/boot/dts/mediatek/mt8192.dtsi b/arch/arm64/boot/dts/mediatek/mt8192.dtsi
index 53d790c335f9..411feb294613 100644
--- a/arch/arm64/boot/dts/mediatek/mt8192.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8192.dtsi
@@ -9,6 +9,7 @@
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/interrupt-controller/irq.h>
#include <dt-bindings/pinctrl/mt8192-pinfunc.h>
+#include <dt-bindings/power/mt8192-power.h>
/ {
compatible = "mediatek,mt8192";
@@ -301,6 +302,212 @@
#interrupt-cells = <2>;
};
+ scpsys: syscon@10006000 {
+ compatible = "syscon", "simple-mfd";
+ reg = <0 0x10006000 0 0x1000>;
+ #power-domain-cells = <1>;
+
+ /* System Power Manager */
+ spm: power-controller {
+ compatible = "mediatek,mt8192-power-controller";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ #power-domain-cells = <1>;
+
+ /* power domain of the SoC */
+ power-domain@MT8192_POWER_DOMAIN_AUDIO {
+ reg = <MT8192_POWER_DOMAIN_AUDIO>;
+ clocks = <&topckgen CLK_TOP_AUD_INTBUS_SEL>,
+ <&infracfg CLK_INFRA_AUDIO_26M_B>,
+ <&infracfg CLK_INFRA_AUDIO>;
+ clock-names = "audio", "audio1", "audio2";
+ mediatek,infracfg = <&infracfg>;
+ #power-domain-cells = <0>;
+ };
+
+ power-domain@MT8192_POWER_DOMAIN_CONN {
+ reg = <MT8192_POWER_DOMAIN_CONN>;
+ clocks = <&infracfg CLK_INFRA_PMIC_CONN>;
+ clock-names = "conn";
+ mediatek,infracfg = <&infracfg>;
+ #power-domain-cells = <0>;
+ };
+
+ power-domain@MT8192_POWER_DOMAIN_MFG0 {
+ reg = <MT8192_POWER_DOMAIN_MFG0>;
+ clocks = <&topckgen CLK_TOP_MFG_PLL_SEL>;
+ clock-names = "mfg";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ #power-domain-cells = <1>;
+
+ power-domain@MT8192_POWER_DOMAIN_MFG1 {
+ reg = <MT8192_POWER_DOMAIN_MFG1>;
+ mediatek,infracfg = <&infracfg>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ #power-domain-cells = <1>;
+
+ power-domain@MT8192_POWER_DOMAIN_MFG2 {
+ reg = <MT8192_POWER_DOMAIN_MFG2>;
+ #power-domain-cells = <0>;
+ };
+
+ power-domain@MT8192_POWER_DOMAIN_MFG3 {
+ reg = <MT8192_POWER_DOMAIN_MFG3>;
+ #power-domain-cells = <0>;
+ };
+
+ power-domain@MT8192_POWER_DOMAIN_MFG4 {
+ reg = <MT8192_POWER_DOMAIN_MFG4>;
+ #power-domain-cells = <0>;
+ };
+
+ power-domain@MT8192_POWER_DOMAIN_MFG5 {
+ reg = <MT8192_POWER_DOMAIN_MFG5>;
+ #power-domain-cells = <0>;
+ };
+
+ power-domain@MT8192_POWER_DOMAIN_MFG6 {
+ reg = <MT8192_POWER_DOMAIN_MFG6>;
+ #power-domain-cells = <0>;
+ };
+ };
+ };
+
+ power-domain@MT8192_POWER_DOMAIN_DISP {
+ reg = <MT8192_POWER_DOMAIN_DISP>;
+ clocks = <&topckgen CLK_TOP_DISP_SEL>,
+ <&mmsys CLK_MM_SMI_INFRA>,
+ <&mmsys CLK_MM_SMI_COMMON>,
+ <&mmsys CLK_MM_SMI_GALS>,
+ <&mmsys CLK_MM_SMI_IOMMU>;
+ clock-names = "disp", "disp-0", "disp-1", "disp-2",
+ "disp-3";
+ mediatek,infracfg = <&infracfg>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ #power-domain-cells = <1>;
+
+ power-domain@MT8192_POWER_DOMAIN_IPE {
+ reg = <MT8192_POWER_DOMAIN_IPE>;
+ clocks = <&topckgen CLK_TOP_IPE_SEL>,
+ <&ipesys CLK_IPE_LARB19>,
+ <&ipesys CLK_IPE_LARB20>,
+ <&ipesys CLK_IPE_SMI_SUBCOM>,
+ <&ipesys CLK_IPE_GALS>;
+ clock-names = "ipe", "ipe-0", "ipe-1", "ipe-2",
+ "ipe-3";
+ mediatek,infracfg = <&infracfg>;
+ #power-domain-cells = <0>;
+ };
+
+ power-domain@MT8192_POWER_DOMAIN_ISP {
+ reg = <MT8192_POWER_DOMAIN_ISP>;
+ clocks = <&topckgen CLK_TOP_IMG1_SEL>,
+ <&imgsys CLK_IMG_LARB9>,
+ <&imgsys CLK_IMG_GALS>;
+ clock-names = "isp", "isp-0", "isp-1";
+ mediatek,infracfg = <&infracfg>;
+ #power-domain-cells = <0>;
+ };
+
+ power-domain@MT8192_POWER_DOMAIN_ISP2 {
+ reg = <MT8192_POWER_DOMAIN_ISP2>;
+ clocks = <&topckgen CLK_TOP_IMG2_SEL>,
+ <&imgsys2 CLK_IMG2_LARB11>,
+ <&imgsys2 CLK_IMG2_GALS>;
+ clock-names = "isp2", "isp2-0", "isp2-1";
+ mediatek,infracfg = <&infracfg>;
+ #power-domain-cells = <0>;
+ };
+
+ power-domain@MT8192_POWER_DOMAIN_MDP {
+ reg = <MT8192_POWER_DOMAIN_MDP>;
+ clocks = <&topckgen CLK_TOP_MDP_SEL>,
+ <&mdpsys CLK_MDP_SMI0>;
+ clock-names = "mdp", "mdp-0";
+ mediatek,infracfg = <&infracfg>;
+ #power-domain-cells = <0>;
+ };
+
+ power-domain@MT8192_POWER_DOMAIN_VENC {
+ reg = <MT8192_POWER_DOMAIN_VENC>;
+ clocks = <&topckgen CLK_TOP_VENC_SEL>,
+ <&vencsys CLK_VENC_SET1_VENC>;
+ clock-names = "venc", "venc-0";
+ mediatek,infracfg = <&infracfg>;
+ #power-domain-cells = <0>;
+ };
+
+ power-domain@MT8192_POWER_DOMAIN_VDEC {
+ reg = <MT8192_POWER_DOMAIN_VDEC>;
+ clocks = <&topckgen CLK_TOP_VDEC_SEL>,
+ <&vdecsys_soc CLK_VDEC_SOC_VDEC>,
+ <&vdecsys_soc CLK_VDEC_SOC_LAT>,
+ <&vdecsys_soc CLK_VDEC_SOC_LARB1>;
+ clock-names = "vdec", "vdec-0", "vdec-1", "vdec-2";
+ mediatek,infracfg = <&infracfg>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ #power-domain-cells = <1>;
+
+ power-domain@MT8192_POWER_DOMAIN_VDEC2 {
+ reg = <MT8192_POWER_DOMAIN_VDEC2>;
+ clocks = <&vdecsys CLK_VDEC_VDEC>,
+ <&vdecsys CLK_VDEC_LAT>,
+ <&vdecsys CLK_VDEC_LARB1>;
+ clock-names = "vdec2-0", "vdec2-1",
+ "vdec2-2";
+ #power-domain-cells = <0>;
+ };
+ };
+
+ power-domain@MT8192_POWER_DOMAIN_CAM {
+ reg = <MT8192_POWER_DOMAIN_CAM>;
+ clocks = <&topckgen CLK_TOP_CAM_SEL>,
+ <&camsys CLK_CAM_LARB13>,
+ <&camsys CLK_CAM_LARB14>,
+ <&camsys CLK_CAM_CCU_GALS>,
+ <&camsys CLK_CAM_CAM2MM_GALS>;
+ clock-names = "cam", "cam-0", "cam-1", "cam-2",
+ "cam-3";
+ mediatek,infracfg = <&infracfg>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ #power-domain-cells = <1>;
+
+ power-domain@MT8192_POWER_DOMAIN_CAM_RAWA {
+ reg = <MT8192_POWER_DOMAIN_CAM_RAWA>;
+ clocks = <&camsys_rawa CLK_CAM_RAWA_LARBX>;
+ clock-names = "cam_rawa-0";
+ #power-domain-cells = <0>;
+ };
+
+ power-domain@MT8192_POWER_DOMAIN_CAM_RAWB {
+ reg = <MT8192_POWER_DOMAIN_CAM_RAWB>;
+ clocks = <&camsys_rawb CLK_CAM_RAWB_LARBX>;
+ clock-names = "cam_rawb-0";
+ #power-domain-cells = <0>;
+ };
+
+ power-domain@MT8192_POWER_DOMAIN_CAM_RAWC {
+ reg = <MT8192_POWER_DOMAIN_CAM_RAWC>;
+ clocks = <&camsys_rawc CLK_CAM_RAWC_LARBX>;
+ clock-names = "cam_rawc-0";
+ #power-domain-cells = <0>;
+ };
+ };
+ };
+ };
+ };
+
+ watchdog: watchdog@10007000 {
+ compatible = "mediatek,mt8192-wdt";
+ reg = <0 0x10007000 0 0x100>;
+ #reset-cells = <1>;
+ };
+
apmixedsys: syscon@1000c000 {
compatible = "mediatek,mt8192-apmixedsys", "syscon";
reg = <0 0x1000c000 0 0x1000>;
@@ -312,7 +519,7 @@
"mediatek,mt6765-timer";
reg = <0 0x10017000 0 0x1000>;
interrupts = <GIC_SPI 233 IRQ_TYPE_LEVEL_HIGH 0>;
- clocks = <&clk26m>;
+ clocks = <&topckgen CLK_TOP_CSW_F26M_D2>;
clock-names = "clk13m";
};
@@ -327,7 +534,7 @@
"mediatek,mt6577-uart";
reg = <0 0x11002000 0 0x1000>;
interrupts = <GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH 0>;
- clocks = <&clk26m>, <&clk26m>;
+ clocks = <&clk26m>, <&infracfg CLK_INFRA_UART0>;
clock-names = "baud", "bus";
status = "disabled";
};
@@ -337,7 +544,7 @@
"mediatek,mt6577-uart";
reg = <0 0x11003000 0 0x1000>;
interrupts = <GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH 0>;
- clocks = <&clk26m>, <&clk26m>;
+ clocks = <&clk26m>, <&infracfg CLK_INFRA_UART1>;
clock-names = "baud", "bus";
status = "disabled";
};
@@ -355,9 +562,9 @@
#size-cells = <0>;
reg = <0 0x1100a000 0 0x1000>;
interrupts = <GIC_SPI 159 IRQ_TYPE_LEVEL_HIGH 0>;
- clocks = <&clk26m>,
- <&clk26m>,
- <&clk26m>;
+ clocks = <&topckgen CLK_TOP_MAINPLL_D5_D4>,
+ <&topckgen CLK_TOP_SPI_SEL>,
+ <&infracfg CLK_INFRA_SPI0>;
clock-names = "parent-clk", "sel-clk", "spi-clk";
status = "disabled";
};
@@ -369,9 +576,9 @@
#size-cells = <0>;
reg = <0 0x11010000 0 0x1000>;
interrupts = <GIC_SPI 160 IRQ_TYPE_LEVEL_HIGH 0>;
- clocks = <&clk26m>,
- <&clk26m>,
- <&clk26m>;
+ clocks = <&topckgen CLK_TOP_MAINPLL_D5_D4>,
+ <&topckgen CLK_TOP_SPI_SEL>,
+ <&infracfg CLK_INFRA_SPI1>;
clock-names = "parent-clk", "sel-clk", "spi-clk";
status = "disabled";
};
@@ -383,9 +590,9 @@
#size-cells = <0>;
reg = <0 0x11012000 0 0x1000>;
interrupts = <GIC_SPI 161 IRQ_TYPE_LEVEL_HIGH 0>;
- clocks = <&clk26m>,
- <&clk26m>,
- <&clk26m>;
+ clocks = <&topckgen CLK_TOP_MAINPLL_D5_D4>,
+ <&topckgen CLK_TOP_SPI_SEL>,
+ <&infracfg CLK_INFRA_SPI2>;
clock-names = "parent-clk", "sel-clk", "spi-clk";
status = "disabled";
};
@@ -397,9 +604,9 @@
#size-cells = <0>;
reg = <0 0x11013000 0 0x1000>;
interrupts = <GIC_SPI 162 IRQ_TYPE_LEVEL_HIGH 0>;
- clocks = <&clk26m>,
- <&clk26m>,
- <&clk26m>;
+ clocks = <&topckgen CLK_TOP_MAINPLL_D5_D4>,
+ <&topckgen CLK_TOP_SPI_SEL>,
+ <&infracfg CLK_INFRA_SPI3>;
clock-names = "parent-clk", "sel-clk", "spi-clk";
status = "disabled";
};
@@ -411,9 +618,9 @@
#size-cells = <0>;
reg = <0 0x11018000 0 0x1000>;
interrupts = <GIC_SPI 163 IRQ_TYPE_LEVEL_HIGH 0>;
- clocks = <&clk26m>,
- <&clk26m>,
- <&clk26m>;
+ clocks = <&topckgen CLK_TOP_MAINPLL_D5_D4>,
+ <&topckgen CLK_TOP_SPI_SEL>,
+ <&infracfg CLK_INFRA_SPI4>;
clock-names = "parent-clk", "sel-clk", "spi-clk";
status = "disabled";
};
@@ -425,9 +632,9 @@
#size-cells = <0>;
reg = <0 0x11019000 0 0x1000>;
interrupts = <GIC_SPI 164 IRQ_TYPE_LEVEL_HIGH 0>;
- clocks = <&clk26m>,
- <&clk26m>,
- <&clk26m>;
+ clocks = <&topckgen CLK_TOP_MAINPLL_D5_D4>,
+ <&topckgen CLK_TOP_SPI_SEL>,
+ <&infracfg CLK_INFRA_SPI5>;
clock-names = "parent-clk", "sel-clk", "spi-clk";
status = "disabled";
};
@@ -439,9 +646,9 @@
#size-cells = <0>;
reg = <0 0x1101d000 0 0x1000>;
interrupts = <GIC_SPI 165 IRQ_TYPE_LEVEL_HIGH 0>;
- clocks = <&clk26m>,
- <&clk26m>,
- <&clk26m>;
+ clocks = <&topckgen CLK_TOP_MAINPLL_D5_D4>,
+ <&topckgen CLK_TOP_SPI_SEL>,
+ <&infracfg CLK_INFRA_SPI6>;
clock-names = "parent-clk", "sel-clk", "spi-clk";
status = "disabled";
};
@@ -453,9 +660,9 @@
#size-cells = <0>;
reg = <0 0x1101e000 0 0x1000>;
interrupts = <GIC_SPI 166 IRQ_TYPE_LEVEL_HIGH 0>;
- clocks = <&clk26m>,
- <&clk26m>,
- <&clk26m>;
+ clocks = <&topckgen CLK_TOP_MAINPLL_D5_D4>,
+ <&topckgen CLK_TOP_SPI_SEL>,
+ <&infracfg CLK_INFRA_SPI7>;
clock-names = "parent-clk", "sel-clk", "spi-clk";
status = "disabled";
};
@@ -464,10 +671,12 @@
compatible = "mediatek,mt8192-nor";
reg = <0 0x11234000 0 0xe0>;
interrupts = <GIC_SPI 431 IRQ_TYPE_LEVEL_HIGH 0>;
- clocks = <&clk26m>,
- <&clk26m>,
- <&clk26m>;
+ clocks = <&topckgen CLK_TOP_SFLASH_SEL>,
+ <&infracfg CLK_INFRA_FLASHIF_SFLASH>,
+ <&infracfg CLK_INFRA_FLASHIF_TOP_H_133M>;
clock-names = "spi", "sf", "axi";
+ assigned-clocks = <&topckgen CLK_TOP_SFLASH_SEL>;
+ assigned-clock-parents = <&clk26m>;
#address-cells = <1>;
#size-cells = <0>;
status = "disable";
@@ -484,7 +693,8 @@
reg = <0 0x11cb0000 0 0x1000>,
<0 0x10217300 0 0x80>;
interrupts = <GIC_SPI 115 IRQ_TYPE_LEVEL_HIGH 0>;
- clocks = <&clk26m>, <&clk26m>;
+ clocks = <&imp_iic_wrap_e CLK_IMP_IIC_WRAP_E_I2C3>,
+ <&infracfg CLK_INFRA_AP_DMA>;
clock-names = "main", "dma";
clock-div = <1>;
#address-cells = <1>;
@@ -503,7 +713,8 @@
reg = <0 0x11d00000 0 0x1000>,
<0 0x10217600 0 0x180>;
interrupts = <GIC_SPI 119 IRQ_TYPE_LEVEL_HIGH 0>;
- clocks = <&clk26m>, <&clk26m>;
+ clocks = <&imp_iic_wrap_s CLK_IMP_IIC_WRAP_S_I2C7>,
+ <&infracfg CLK_INFRA_AP_DMA>;
clock-names = "main", "dma";
clock-div = <1>;
#address-cells = <1>;
@@ -516,7 +727,8 @@
reg = <0 0x11d01000 0 0x1000>,
<0 0x10217780 0 0x180>;
interrupts = <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH 0>;
- clocks = <&clk26m>, <&clk26m>;
+ clocks = <&imp_iic_wrap_s CLK_IMP_IIC_WRAP_S_I2C8>,
+ <&infracfg CLK_INFRA_AP_DMA>;
clock-names = "main", "dma";
clock-div = <1>;
#address-cells = <1>;
@@ -529,7 +741,8 @@
reg = <0 0x11d02000 0 0x1000>,
<0 0x10217900 0 0x180>;
interrupts = <GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH 0>;
- clocks = <&clk26m>, <&clk26m>;
+ clocks = <&imp_iic_wrap_s CLK_IMP_IIC_WRAP_S_I2C9>,
+ <&infracfg CLK_INFRA_AP_DMA>;
clock-names = "main", "dma";
clock-div = <1>;
#address-cells = <1>;
@@ -548,7 +761,8 @@
reg = <0 0x11d20000 0 0x1000>,
<0 0x10217100 0 0x80>;
interrupts = <GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH 0>;
- clocks = <&clk26m>, <&clk26m>;
+ clocks = <&imp_iic_wrap_ws CLK_IMP_IIC_WRAP_WS_I2C1>,
+ <&infracfg CLK_INFRA_AP_DMA>;
clock-names = "main", "dma";
clock-div = <1>;
#address-cells = <1>;
@@ -561,7 +775,8 @@
reg = <0 0x11d21000 0 0x1000>,
<0 0x10217180 0 0x180>;
interrupts = <GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH 0>;
- clocks = <&clk26m>, <&clk26m>;
+ clocks = <&imp_iic_wrap_ws CLK_IMP_IIC_WRAP_WS_I2C2>,
+ <&infracfg CLK_INFRA_AP_DMA>;
clock-names = "main", "dma";
clock-div = <1>;
#address-cells = <1>;
@@ -574,7 +789,8 @@
reg = <0 0x11d22000 0 0x1000>,
<0 0x10217380 0 0x180>;
interrupts = <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH 0>;
- clocks = <&clk26m>, <&clk26m>;
+ clocks = <&imp_iic_wrap_ws CLK_IMP_IIC_WRAP_WS_I2C4>,
+ <&infracfg CLK_INFRA_AP_DMA>;
clock-names = "main", "dma";
clock-div = <1>;
#address-cells = <1>;
@@ -593,7 +809,8 @@
reg = <0 0x11e00000 0 0x1000>,
<0 0x10217500 0 0x80>;
interrupts = <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH 0>;
- clocks = <&clk26m>, <&clk26m>;
+ clocks = <&imp_iic_wrap_w CLK_IMP_IIC_WRAP_W_I2C5>,
+ <&infracfg CLK_INFRA_AP_DMA>;
clock-names = "main", "dma";
clock-div = <1>;
#address-cells = <1>;
@@ -612,7 +829,8 @@
reg = <0 0x11f00000 0 0x1000>,
<0 0x10217080 0 0x80>;
interrupts = <GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH 0>;
- clocks = <&clk26m>, <&clk26m>;
+ clocks = <&imp_iic_wrap_n CLK_IMP_IIC_WRAP_N_I2C0>,
+ <&infracfg CLK_INFRA_AP_DMA>;
clock-names = "main", "dma";
clock-div = <1>;
#address-cells = <1>;
@@ -625,7 +843,8 @@
reg = <0 0x11f01000 0 0x1000>,
<0 0x10217580 0 0x80>;
interrupts = <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH 0>;
- clocks = <&clk26m>, <&clk26m>;
+ clocks = <&imp_iic_wrap_n CLK_IMP_IIC_WRAP_N_I2C6>,
+ <&infracfg CLK_INFRA_AP_DMA>;
clock-names = "main", "dma";
clock-div = <1>;
#address-cells = <1>;
diff --git a/arch/arm64/boot/dts/microchip/sparx5.dtsi b/arch/arm64/boot/dts/microchip/sparx5.dtsi
index 787ebcec121d..2dd5e38820b1 100644
--- a/arch/arm64/boot/dts/microchip/sparx5.dtsi
+++ b/arch/arm64/boot/dts/microchip/sparx5.dtsi
@@ -471,9 +471,10 @@
<0x6 0x10004000 0x7fc000>,
<0x6 0x11010000 0xaf0000>;
reg-names = "cpu", "dev", "gcb";
- interrupt-names = "xtr", "fdma";
+ interrupt-names = "xtr", "fdma", "ptp";
interrupts = <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>;
+ <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 27 IRQ_TYPE_LEVEL_HIGH>;
resets = <&reset 0>;
reset-names = "switch";
};
diff --git a/arch/arm64/boot/dts/nvidia/Makefile b/arch/arm64/boot/dts/nvidia/Makefile
index ea3f338fd013..bc34c9d8846a 100644
--- a/arch/arm64/boot/dts/nvidia/Makefile
+++ b/arch/arm64/boot/dts/nvidia/Makefile
@@ -1,4 +1,15 @@
# SPDX-License-Identifier: GPL-2.0
+
+# Enables support for device-tree overlays
+DTC_FLAGS_tegra210-p2371-2180 := -@
+DTC_FLAGS_tegra210-p3450-0000 := -@
+DTC_FLAGS_tegra186-p2771-0000 := -@
+DTC_FLAGS_tegra186-p3509-0000+p3636-0001 := -@
+DTC_FLAGS_tegra194-p2972-0000 := -@
+DTC_FLAGS_tegra194-p3509-0000+p3668-0000 := -@
+DTC_FLAGS_tegra194-p3509-0000+p3668-0001 := -@
+DTC_FLAGS_tegra234-p3737-0000+p3701-0000 := -@
+
dtb-$(CONFIG_ARCH_TEGRA_132_SOC) += tegra132-norrin.dtb
dtb-$(CONFIG_ARCH_TEGRA_210_SOC) += tegra210-p2371-0000.dtb
dtb-$(CONFIG_ARCH_TEGRA_210_SOC) += tegra210-p2371-2180.dtb
diff --git a/arch/arm64/boot/dts/nvidia/tegra186.dtsi b/arch/arm64/boot/dts/nvidia/tegra186.dtsi
index c91afff1b757..e9b40f5d79ec 100644
--- a/arch/arm64/boot/dts/nvidia/tegra186.dtsi
+++ b/arch/arm64/boot/dts/nvidia/tegra186.dtsi
@@ -73,6 +73,48 @@
snps,rxpbl = <8>;
};
+ gpcdma: dma-controller@2600000 {
+ compatible = "nvidia,tegra186-gpcdma";
+ reg = <0x0 0x2600000 0x0 0x210000>;
+ resets = <&bpmp TEGRA186_RESET_GPCDMA>;
+ reset-names = "gpcdma";
+ interrupts = <GIC_SPI 76 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 78 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 79 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 80 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 81 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>,
+ <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 99 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 102 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 104 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 105 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH>;
+ #dma-cells = <1>;
+ iommus = <&smmu TEGRA186_SID_GPCDMA_0>;
+ dma-coherent;
+ status = "okay";
+ };
+
aconnect@2900000 {
compatible = "nvidia,tegra186-aconnect",
"nvidia,tegra210-aconnect";
@@ -1938,14 +1980,14 @@
};
pmu_denver {
- compatible = "nvidia,denver-pmu", "arm,armv8-pmuv3";
+ compatible = "nvidia,denver-pmu";
interrupts = <GIC_SPI 320 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 321 IRQ_TYPE_LEVEL_HIGH>;
interrupt-affinity = <&denver_0 &denver_1>;
};
pmu_a57 {
- compatible = "arm,cortex-a57-pmu", "arm,armv8-pmuv3";
+ compatible = "arm,cortex-a57-pmu";
interrupts = <GIC_SPI 296 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 297 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 298 IRQ_TYPE_LEVEL_HIGH>,
diff --git a/arch/arm64/boot/dts/nvidia/tegra194-p3509-0000.dtsi b/arch/arm64/boot/dts/nvidia/tegra194-p3509-0000.dtsi
index 1323fa9b8301..32ce7904f44f 100644
--- a/arch/arm64/boot/dts/nvidia/tegra194-p3509-0000.dtsi
+++ b/arch/arm64/boot/dts/nvidia/tegra194-p3509-0000.dtsi
@@ -1826,6 +1826,10 @@
pads {
usb2 {
lanes {
+ usb2-0 {
+ status = "okay";
+ };
+
usb2-1 {
status = "okay";
};
@@ -1846,6 +1850,20 @@
};
ports {
+ usb2-0 {
+ mode = "otg";
+ status = "okay";
+ usb-role-switch;
+ connector {
+ compatible = "gpio-usb-b-connector",
+ "usb-b-connector";
+ label = "micro-USB";
+ type = "micro";
+ vbus-gpio = <&gpio TEGRA194_MAIN_GPIO(Z, 1)
+ GPIO_ACTIVE_LOW>;
+ };
+ };
+
usb2-1 {
mode = "host";
status = "okay";
@@ -1874,6 +1892,13 @@
phy-names = "usb2-1", "usb2-2", "usb3-2";
};
+ usb@3550000 {
+ status = "okay";
+
+ phys = <&{/bus@0/padctl@3520000/pads/usb2/lanes/usb2-0}>;
+ phy-names = "usb2-0";
+ };
+
spi@3270000 {
status = "okay";
diff --git a/arch/arm64/boot/dts/nvidia/tegra194.dtsi b/arch/arm64/boot/dts/nvidia/tegra194.dtsi
index 2d48c3715fc6..751ebe5e9506 100644
--- a/arch/arm64/boot/dts/nvidia/tegra194.dtsi
+++ b/arch/arm64/boot/dts/nvidia/tegra194.dtsi
@@ -115,6 +115,49 @@
snps,rxpbl = <8>;
};
+ gpcdma: dma-controller@2600000 {
+ compatible = "nvidia,tegra194-gpcdma",
+ "nvidia,tegra186-gpcdma";
+ reg = <0x2600000 0x210000>;
+ resets = <&bpmp TEGRA194_RESET_GPCDMA>;
+ reset-names = "gpcdma";
+ interrupts = <GIC_SPI 76 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 78 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 79 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 80 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 81 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>,
+ <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 99 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 102 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 104 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 105 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH>;
+ #dma-cells = <1>;
+ iommus = <&smmu TEGRA194_SID_GPCDMA_0>;
+ dma-coherent;
+ status = "okay";
+ };
+
aconnect@2900000 {
compatible = "nvidia,tegra194-aconnect",
"nvidia,tegra210-aconnect";
@@ -243,6 +286,10 @@
"rx19", "tx19",
"rx20", "tx20";
status = "disabled";
+ interconnects = <&mc TEGRA194_MEMORY_CLIENT_APEDMAR &emc>,
+ <&mc TEGRA194_MEMORY_CLIENT_APEDMAW &emc>;
+ interconnect-names = "dma-mem", "write";
+ iommus = <&smmu TEGRA194_SID_APE>;
};
tegra_i2s1: i2s@2901000 {
@@ -1584,7 +1631,7 @@
#iommu-cells = <1>;
nvidia,memory-controller = <&mc>;
- status = "okay";
+ status = "disabled";
};
smmu: iommu@12000000 {
@@ -2839,7 +2886,7 @@
};
pmu {
- compatible = "arm,armv8-pmuv3";
+ compatible = "nvidia,carmel-pmu";
interrupts = <GIC_SPI 384 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 385 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 386 IRQ_TYPE_LEVEL_HIGH>,
@@ -2876,11 +2923,6 @@
* for 8x and 11.025x sample rate streams.
*/
assigned-clock-rates = <258000000>;
-
- interconnects = <&mc TEGRA194_MEMORY_CLIENT_APEDMAR &emc>,
- <&mc TEGRA194_MEMORY_CLIENT_APEDMAW &emc>;
- interconnect-names = "dma-mem", "write";
- iommus = <&smmu TEGRA194_SID_APE>;
};
tcu: serial {
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 efbbb878ba5a..34d6a01ee1c6 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
@@ -1,6 +1,9 @@
// SPDX-License-Identifier: GPL-2.0
/dts-v1/;
+#include <dt-bindings/input/linux-event-codes.h>
+#include <dt-bindings/input/gpio-keys.h>
+
#include "tegra234-p3701-0000.dtsi"
#include "tegra234-p3737-0000.dtsi"
@@ -11,6 +14,1744 @@
aliases {
mmc3 = "/bus@0/mmc@3460000";
serial0 = &tcu;
+ serial1 = &uarta;
+ };
+
+ bus@0 {
+ aconnect@2900000 {
+ status = "okay";
+
+ ahub@2900800 {
+ status = "okay";
+
+ 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>;
+ };
+ };
+ };
+
+ 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 */
+ };
+ };
+ };
+ };
+
+ 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>;
+ };
+ };
+ };
+ };
+ };
+
+ dma-controller@2930000 {
+ status = "okay";
+ };
+
+ interrupt-controller@2a40000 {
+ status = "okay";
+ };
+ };
+
+ serial@3100000 {
+ compatible = "nvidia,tegra194-hsuart";
+ status = "okay";
+ };
+
+ hda@3510000 {
+ nvidia,model = "NVIDIA Jetson AGX Orin HDA";
+ };
};
chosen {
@@ -18,7 +1759,90 @@
stdout-path = "serial0:115200n8";
};
+ gpio-keys {
+ compatible = "gpio-keys";
+ status = "okay";
+
+ force-recovery {
+ label = "Force Recovery";
+ gpios = <&gpio TEGRA234_MAIN_GPIO(G, 0) GPIO_ACTIVE_LOW>;
+ linux,input-type = <EV_KEY>;
+ linux,code = <BTN_1>;
+ };
+
+ power-key {
+ label = "Power";
+ gpios = <&gpio_aon TEGRA234_AON_GPIO(EE, 4) GPIO_ACTIVE_LOW>;
+ linux,input-type = <EV_KEY>;
+ linux,code = <KEY_POWER>;
+ wakeup-event-action = <EV_ACT_ASSERTED>;
+ wakeup-source;
+ };
+
+ suspend {
+ label = "Suspend";
+ gpios = <&gpio TEGRA234_MAIN_GPIO(G, 2) GPIO_ACTIVE_LOW>;
+ linux,input-type = <EV_KEY>;
+ linux,code = <KEY_SLEEP>;
+ };
+ };
+
serial {
status = "okay";
};
+
+ sound {
+ status = "okay";
+
+ compatible = "nvidia,tegra186-audio-graph-card";
+
+ 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_i2s1_port>, <&xbar_i2s2_port>, <&xbar_i2s4_port>,
+ <&xbar_i2s6_port>, <&xbar_dmic3_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>,
+ /* 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>,
+ /* BE I/O Ports */
+ <&i2s1_port>, <&i2s2_port>, <&i2s4_port>, <&i2s6_port>,
+ <&dmic3_port>;
+
+ label = "NVIDIA Jetson AGX Orin APE";
+ };
};
diff --git a/arch/arm64/boot/dts/nvidia/tegra234.dtsi b/arch/arm64/boot/dts/nvidia/tegra234.dtsi
index 6b6f15804a1a..aaace605bdaa 100644
--- a/arch/arm64/boot/dts/nvidia/tegra234.dtsi
+++ b/arch/arm64/boot/dts/nvidia/tegra234.dtsi
@@ -1,9 +1,11 @@
// SPDX-License-Identifier: GPL-2.0
#include <dt-bindings/clock/tegra234-clock.h>
+#include <dt-bindings/gpio/tegra234-gpio.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/mailbox/tegra186-hsp.h>
#include <dt-bindings/memory/tegra234-mc.h>
+#include <dt-bindings/power/tegra234-powergate.h>
#include <dt-bindings/reset/tegra234-reset.h>
/ {
@@ -19,6 +21,424 @@
ranges = <0x0 0x0 0x0 0x40000000>;
+ aconnect@2900000 {
+ compatible = "nvidia,tegra234-aconnect",
+ "nvidia,tegra210-aconnect";
+ clocks = <&bpmp TEGRA234_CLK_APE>,
+ <&bpmp TEGRA234_CLK_APB2APE>;
+ clock-names = "ape", "apb2ape";
+ power-domains = <&bpmp TEGRA234_POWER_DOMAIN_AUD>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0x02900000 0x02900000 0x200000>;
+ status = "disabled";
+
+ tegra_ahub: ahub@2900800 {
+ compatible = "nvidia,tegra234-ahub";
+ reg = <0x02900800 0x800>;
+ clocks = <&bpmp TEGRA234_CLK_AHUB>;
+ clock-names = "ahub";
+ assigned-clocks = <&bpmp TEGRA234_CLK_AHUB>;
+ assigned-clock-parents = <&bpmp TEGRA234_CLK_PLLA_OUT0>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0x02900800 0x02900800 0x11800>;
+ status = "disabled";
+
+ tegra_i2s1: i2s@2901000 {
+ compatible = "nvidia,tegra234-i2s",
+ "nvidia,tegra210-i2s";
+ reg = <0x2901000 0x100>;
+ clocks = <&bpmp TEGRA234_CLK_I2S1>,
+ <&bpmp TEGRA234_CLK_I2S1_SYNC_INPUT>;
+ clock-names = "i2s", "sync_input";
+ assigned-clocks = <&bpmp TEGRA234_CLK_I2S1>;
+ assigned-clock-parents = <&bpmp TEGRA234_CLK_PLLA_OUT0>;
+ assigned-clock-rates = <1536000>;
+ sound-name-prefix = "I2S1";
+ status = "disabled";
+ };
+
+ tegra_i2s2: i2s@2901100 {
+ compatible = "nvidia,tegra234-i2s",
+ "nvidia,tegra210-i2s";
+ reg = <0x2901100 0x100>;
+ clocks = <&bpmp TEGRA234_CLK_I2S2>,
+ <&bpmp TEGRA234_CLK_I2S2_SYNC_INPUT>;
+ clock-names = "i2s", "sync_input";
+ assigned-clocks = <&bpmp TEGRA234_CLK_I2S2>;
+ assigned-clock-parents = <&bpmp TEGRA234_CLK_PLLA_OUT0>;
+ assigned-clock-rates = <1536000>;
+ sound-name-prefix = "I2S2";
+ status = "disabled";
+ };
+
+ tegra_i2s3: i2s@2901200 {
+ compatible = "nvidia,tegra234-i2s",
+ "nvidia,tegra210-i2s";
+ reg = <0x2901200 0x100>;
+ clocks = <&bpmp TEGRA234_CLK_I2S3>,
+ <&bpmp TEGRA234_CLK_I2S3_SYNC_INPUT>;
+ clock-names = "i2s", "sync_input";
+ assigned-clocks = <&bpmp TEGRA234_CLK_I2S3>;
+ assigned-clock-parents = <&bpmp TEGRA234_CLK_PLLA_OUT0>;
+ assigned-clock-rates = <1536000>;
+ sound-name-prefix = "I2S3";
+ status = "disabled";
+ };
+
+ tegra_i2s4: i2s@2901300 {
+ compatible = "nvidia,tegra234-i2s",
+ "nvidia,tegra210-i2s";
+ reg = <0x2901300 0x100>;
+ clocks = <&bpmp TEGRA234_CLK_I2S4>,
+ <&bpmp TEGRA234_CLK_I2S4_SYNC_INPUT>;
+ clock-names = "i2s", "sync_input";
+ assigned-clocks = <&bpmp TEGRA234_CLK_I2S4>;
+ assigned-clock-parents = <&bpmp TEGRA234_CLK_PLLA_OUT0>;
+ assigned-clock-rates = <1536000>;
+ sound-name-prefix = "I2S4";
+ status = "disabled";
+ };
+
+ tegra_i2s5: i2s@2901400 {
+ compatible = "nvidia,tegra234-i2s",
+ "nvidia,tegra210-i2s";
+ reg = <0x2901400 0x100>;
+ clocks = <&bpmp TEGRA234_CLK_I2S5>,
+ <&bpmp TEGRA234_CLK_I2S5_SYNC_INPUT>;
+ clock-names = "i2s", "sync_input";
+ assigned-clocks = <&bpmp TEGRA234_CLK_I2S5>;
+ assigned-clock-parents = <&bpmp TEGRA234_CLK_PLLA_OUT0>;
+ assigned-clock-rates = <1536000>;
+ sound-name-prefix = "I2S5";
+ status = "disabled";
+ };
+
+ tegra_i2s6: i2s@2901500 {
+ compatible = "nvidia,tegra234-i2s",
+ "nvidia,tegra210-i2s";
+ reg = <0x2901500 0x100>;
+ clocks = <&bpmp TEGRA234_CLK_I2S6>,
+ <&bpmp TEGRA234_CLK_I2S6_SYNC_INPUT>;
+ clock-names = "i2s", "sync_input";
+ assigned-clocks = <&bpmp TEGRA234_CLK_I2S6>;
+ assigned-clock-parents = <&bpmp TEGRA234_CLK_PLLA_OUT0>;
+ assigned-clock-rates = <1536000>;
+ sound-name-prefix = "I2S6";
+ status = "disabled";
+ };
+
+ tegra_sfc1: sfc@2902000 {
+ compatible = "nvidia,tegra234-sfc",
+ "nvidia,tegra210-sfc";
+ reg = <0x2902000 0x200>;
+ sound-name-prefix = "SFC1";
+ status = "disabled";
+ };
+
+ tegra_sfc2: sfc@2902200 {
+ compatible = "nvidia,tegra234-sfc",
+ "nvidia,tegra210-sfc";
+ reg = <0x2902200 0x200>;
+ sound-name-prefix = "SFC2";
+ status = "disabled";
+ };
+
+ tegra_sfc3: sfc@2902400 {
+ compatible = "nvidia,tegra234-sfc",
+ "nvidia,tegra210-sfc";
+ reg = <0x2902400 0x200>;
+ sound-name-prefix = "SFC3";
+ status = "disabled";
+ };
+
+ tegra_sfc4: sfc@2902600 {
+ compatible = "nvidia,tegra234-sfc",
+ "nvidia,tegra210-sfc";
+ reg = <0x2902600 0x200>;
+ sound-name-prefix = "SFC4";
+ status = "disabled";
+ };
+
+ tegra_amx1: amx@2903000 {
+ compatible = "nvidia,tegra234-amx",
+ "nvidia,tegra194-amx";
+ reg = <0x2903000 0x100>;
+ sound-name-prefix = "AMX1";
+ status = "disabled";
+ };
+
+ tegra_amx2: amx@2903100 {
+ compatible = "nvidia,tegra234-amx",
+ "nvidia,tegra194-amx";
+ reg = <0x2903100 0x100>;
+ sound-name-prefix = "AMX2";
+ status = "disabled";
+ };
+
+ tegra_amx3: amx@2903200 {
+ compatible = "nvidia,tegra234-amx",
+ "nvidia,tegra194-amx";
+ reg = <0x2903200 0x100>;
+ sound-name-prefix = "AMX3";
+ status = "disabled";
+ };
+
+ tegra_amx4: amx@2903300 {
+ compatible = "nvidia,tegra234-amx",
+ "nvidia,tegra194-amx";
+ reg = <0x2903300 0x100>;
+ sound-name-prefix = "AMX4";
+ status = "disabled";
+ };
+
+ tegra_adx1: adx@2903800 {
+ compatible = "nvidia,tegra234-adx",
+ "nvidia,tegra210-adx";
+ reg = <0x2903800 0x100>;
+ sound-name-prefix = "ADX1";
+ status = "disabled";
+ };
+
+ tegra_adx2: adx@2903900 {
+ compatible = "nvidia,tegra234-adx",
+ "nvidia,tegra210-adx";
+ reg = <0x2903900 0x100>;
+ sound-name-prefix = "ADX2";
+ status = "disabled";
+ };
+
+ tegra_adx3: adx@2903a00 {
+ compatible = "nvidia,tegra234-adx",
+ "nvidia,tegra210-adx";
+ reg = <0x2903a00 0x100>;
+ sound-name-prefix = "ADX3";
+ status = "disabled";
+ };
+
+ tegra_adx4: adx@2903b00 {
+ compatible = "nvidia,tegra234-adx",
+ "nvidia,tegra210-adx";
+ reg = <0x2903b00 0x100>;
+ sound-name-prefix = "ADX4";
+ status = "disabled";
+ };
+
+
+ tegra_dmic1: dmic@2904000 {
+ compatible = "nvidia,tegra234-dmic",
+ "nvidia,tegra210-dmic";
+ reg = <0x2904000 0x100>;
+ clocks = <&bpmp TEGRA234_CLK_DMIC1>;
+ clock-names = "dmic";
+ assigned-clocks = <&bpmp TEGRA234_CLK_DMIC1>;
+ assigned-clock-parents = <&bpmp TEGRA234_CLK_PLLA_OUT0>;
+ assigned-clock-rates = <3072000>;
+ sound-name-prefix = "DMIC1";
+ status = "disabled";
+ };
+
+ tegra_dmic2: dmic@2904100 {
+ compatible = "nvidia,tegra234-dmic",
+ "nvidia,tegra210-dmic";
+ reg = <0x2904100 0x100>;
+ clocks = <&bpmp TEGRA234_CLK_DMIC2>;
+ clock-names = "dmic";
+ assigned-clocks = <&bpmp TEGRA234_CLK_DMIC2>;
+ assigned-clock-parents = <&bpmp TEGRA234_CLK_PLLA_OUT0>;
+ assigned-clock-rates = <3072000>;
+ sound-name-prefix = "DMIC2";
+ status = "disabled";
+ };
+
+ tegra_dmic3: dmic@2904200 {
+ compatible = "nvidia,tegra234-dmic",
+ "nvidia,tegra210-dmic";
+ reg = <0x2904200 0x100>;
+ clocks = <&bpmp TEGRA234_CLK_DMIC3>;
+ clock-names = "dmic";
+ assigned-clocks = <&bpmp TEGRA234_CLK_DMIC3>;
+ assigned-clock-parents = <&bpmp TEGRA234_CLK_PLLA_OUT0>;
+ assigned-clock-rates = <3072000>;
+ sound-name-prefix = "DMIC3";
+ status = "disabled";
+ };
+
+ tegra_dmic4: dmic@2904300 {
+ compatible = "nvidia,tegra234-dmic",
+ "nvidia,tegra210-dmic";
+ reg = <0x2904300 0x100>;
+ clocks = <&bpmp TEGRA234_CLK_DMIC4>;
+ clock-names = "dmic";
+ assigned-clocks = <&bpmp TEGRA234_CLK_DMIC4>;
+ assigned-clock-parents = <&bpmp TEGRA234_CLK_PLLA_OUT0>;
+ assigned-clock-rates = <3072000>;
+ sound-name-prefix = "DMIC4";
+ status = "disabled";
+ };
+
+ tegra_dspk1: dspk@2905000 {
+ compatible = "nvidia,tegra234-dspk",
+ "nvidia,tegra186-dspk";
+ reg = <0x2905000 0x100>;
+ clocks = <&bpmp TEGRA234_CLK_DSPK1>;
+ clock-names = "dspk";
+ assigned-clocks = <&bpmp TEGRA234_CLK_DSPK1>;
+ assigned-clock-parents = <&bpmp TEGRA234_CLK_PLLA_OUT0>;
+ assigned-clock-rates = <12288000>;
+ sound-name-prefix = "DSPK1";
+ status = "disabled";
+ };
+
+ tegra_dspk2: dspk@2905100 {
+ compatible = "nvidia,tegra234-dspk",
+ "nvidia,tegra186-dspk";
+ reg = <0x2905100 0x100>;
+ clocks = <&bpmp TEGRA234_CLK_DSPK2>;
+ clock-names = "dspk";
+ assigned-clocks = <&bpmp TEGRA234_CLK_DSPK2>;
+ assigned-clock-parents = <&bpmp TEGRA234_CLK_PLLA_OUT0>;
+ assigned-clock-rates = <12288000>;
+ sound-name-prefix = "DSPK2";
+ status = "disabled";
+ };
+
+ tegra_mvc1: mvc@290a000 {
+ compatible = "nvidia,tegra234-mvc",
+ "nvidia,tegra210-mvc";
+ reg = <0x290a000 0x200>;
+ sound-name-prefix = "MVC1";
+ status = "disabled";
+ };
+
+ tegra_mvc2: mvc@290a200 {
+ compatible = "nvidia,tegra234-mvc",
+ "nvidia,tegra210-mvc";
+ reg = <0x290a200 0x200>;
+ sound-name-prefix = "MVC2";
+ status = "disabled";
+ };
+
+ tegra_amixer: amixer@290bb00 {
+ compatible = "nvidia,tegra234-amixer",
+ "nvidia,tegra210-amixer";
+ reg = <0x290bb00 0x800>;
+ sound-name-prefix = "MIXER1";
+ status = "disabled";
+ };
+
+ tegra_admaif: admaif@290f000 {
+ compatible = "nvidia,tegra234-admaif",
+ "nvidia,tegra186-admaif";
+ reg = <0x0290f000 0x1000>;
+ dmas = <&adma 1>, <&adma 1>,
+ <&adma 2>, <&adma 2>,
+ <&adma 3>, <&adma 3>,
+ <&adma 4>, <&adma 4>,
+ <&adma 5>, <&adma 5>,
+ <&adma 6>, <&adma 6>,
+ <&adma 7>, <&adma 7>,
+ <&adma 8>, <&adma 8>,
+ <&adma 9>, <&adma 9>,
+ <&adma 10>, <&adma 10>,
+ <&adma 11>, <&adma 11>,
+ <&adma 12>, <&adma 12>,
+ <&adma 13>, <&adma 13>,
+ <&adma 14>, <&adma 14>,
+ <&adma 15>, <&adma 15>,
+ <&adma 16>, <&adma 16>,
+ <&adma 17>, <&adma 17>,
+ <&adma 18>, <&adma 18>,
+ <&adma 19>, <&adma 19>,
+ <&adma 20>, <&adma 20>;
+ dma-names = "rx1", "tx1",
+ "rx2", "tx2",
+ "rx3", "tx3",
+ "rx4", "tx4",
+ "rx5", "tx5",
+ "rx6", "tx6",
+ "rx7", "tx7",
+ "rx8", "tx8",
+ "rx9", "tx9",
+ "rx10", "tx10",
+ "rx11", "tx11",
+ "rx12", "tx12",
+ "rx13", "tx13",
+ "rx14", "tx14",
+ "rx15", "tx15",
+ "rx16", "tx16",
+ "rx17", "tx17",
+ "rx18", "tx18",
+ "rx19", "tx19",
+ "rx20", "tx20";
+ interconnects = <&mc TEGRA234_MEMORY_CLIENT_APEDMAR &emc>,
+ <&mc TEGRA234_MEMORY_CLIENT_APEDMAW &emc>;
+ interconnect-names = "dma-mem", "write";
+ iommus = <&smmu_niso0 TEGRA234_SID_APE>;
+ status = "disabled";
+ };
+ };
+
+ adma: dma-controller@2930000 {
+ compatible = "nvidia,tegra234-adma",
+ "nvidia,tegra186-adma";
+ reg = <0x02930000 0x20000>;
+ interrupt-parent = <&agic>;
+ interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 27 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>;
+ #dma-cells = <1>;
+ clocks = <&bpmp TEGRA234_CLK_AHUB>;
+ clock-names = "d_audio";
+ status = "disabled";
+ };
+
+ agic: interrupt-controller@2a40000 {
+ compatible = "nvidia,tegra234-agic",
+ "nvidia,tegra210-agic";
+ #interrupt-cells = <3>;
+ interrupt-controller;
+ reg = <0x02a41000 0x1000>,
+ <0x02a42000 0x2000>;
+ interrupts = <GIC_SPI 145
+ (GIC_CPU_MASK_SIMPLE(4) |
+ IRQ_TYPE_LEVEL_HIGH)>;
+ clocks = <&bpmp TEGRA234_CLK_APE>;
+ clock-names = "clk";
+ status = "disabled";
+ };
+ };
+
misc@100000 {
compatible = "nvidia,tegra234-misc";
reg = <0x00100000 0xf000>,
@@ -144,6 +564,108 @@
status = "disabled";
};
+ gen1_i2c: i2c@3160000 {
+ compatible = "nvidia,tegra194-i2c";
+ reg = <0x3160000 0x100>;
+ status = "disabled";
+ interrupts = <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>;
+ clock-frequency = <400000>;
+ clocks = <&bpmp TEGRA234_CLK_I2C1
+ &bpmp TEGRA234_CLK_PLLP_OUT0>;
+ assigned-clocks = <&bpmp TEGRA234_CLK_I2C1>;
+ assigned-clock-parents = <&bpmp TEGRA234_CLK_PLLP_OUT0>;
+ clock-names = "div-clk", "parent";
+ resets = <&bpmp TEGRA234_RESET_I2C1>;
+ reset-names = "i2c";
+ };
+
+ cam_i2c: i2c@3180000 {
+ compatible = "nvidia,tegra194-i2c";
+ reg = <0x3180000 0x100>;
+ interrupts = <GIC_SPI 27 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+ clock-frequency = <400000>;
+ clocks = <&bpmp TEGRA234_CLK_I2C3
+ &bpmp TEGRA234_CLK_PLLP_OUT0>;
+ assigned-clocks = <&bpmp TEGRA234_CLK_I2C3>;
+ assigned-clock-parents = <&bpmp TEGRA234_CLK_PLLP_OUT0>;
+ clock-names = "div-clk", "parent";
+ resets = <&bpmp TEGRA234_RESET_I2C3>;
+ reset-names = "i2c";
+ };
+
+ dp_aux_ch1_i2c: i2c@3190000 {
+ compatible = "nvidia,tegra194-i2c";
+ reg = <0x3190000 0x100>;
+ interrupts = <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+ clock-frequency = <100000>;
+ clocks = <&bpmp TEGRA234_CLK_I2C4
+ &bpmp TEGRA234_CLK_PLLP_OUT0>;
+ assigned-clocks = <&bpmp TEGRA234_CLK_I2C4>;
+ assigned-clock-parents = <&bpmp TEGRA234_CLK_PLLP_OUT0>;
+ clock-names = "div-clk", "parent";
+ resets = <&bpmp TEGRA234_RESET_I2C4>;
+ reset-names = "i2c";
+ };
+
+ dp_aux_ch0_i2c: i2c@31b0000 {
+ compatible = "nvidia,tegra194-i2c";
+ reg = <0x31b0000 0x100>;
+ interrupts = <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+ clock-frequency = <100000>;
+ clocks = <&bpmp TEGRA234_CLK_I2C6
+ &bpmp TEGRA234_CLK_PLLP_OUT0>;
+ assigned-clocks = <&bpmp TEGRA234_CLK_I2C6>;
+ assigned-clock-parents = <&bpmp TEGRA234_CLK_PLLP_OUT0>;
+ clock-names = "div-clk", "parent";
+ resets = <&bpmp TEGRA234_RESET_I2C6>;
+ reset-names = "i2c";
+ };
+
+ dp_aux_ch2_i2c: i2c@31c0000 {
+ compatible = "nvidia,tegra194-i2c";
+ reg = <0x31c0000 0x100>;
+ interrupts = <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+ clock-frequency = <100000>;
+ clocks = <&bpmp TEGRA234_CLK_I2C7
+ &bpmp TEGRA234_CLK_PLLP_OUT0>;
+ assigned-clocks = <&bpmp TEGRA234_CLK_I2C7>;
+ assigned-clock-parents = <&bpmp TEGRA234_CLK_PLLP_OUT0>;
+ clock-names = "div-clk", "parent";
+ resets = <&bpmp TEGRA234_RESET_I2C7>;
+ reset-names = "i2c";
+ };
+
+ dp_aux_ch3_i2c: i2c@31e0000 {
+ compatible = "nvidia,tegra194-i2c";
+ reg = <0x31e0000 0x100>;
+ interrupts = <GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+ clock-frequency = <100000>;
+ clocks = <&bpmp TEGRA234_CLK_I2C9
+ &bpmp TEGRA234_CLK_PLLP_OUT0>;
+ assigned-clocks = <&bpmp TEGRA234_CLK_I2C9>;
+ assigned-clock-parents = <&bpmp TEGRA234_CLK_PLLP_OUT0>;
+ clock-names = "div-clk", "parent";
+ resets = <&bpmp TEGRA234_RESET_I2C9>;
+ reset-names = "i2c";
+ };
+
+ pwm1: pwm@3280000 {
+ compatible = "nvidia,tegra194-pwm",
+ "nvidia,tegra186-pwm";
+ reg = <0x3280000 0x10000>;
+ clocks = <&bpmp TEGRA234_CLK_PWM1>;
+ clock-names = "pwm";
+ resets = <&bpmp TEGRA234_RESET_PWM1>;
+ reset-names = "pwm";
+ status = "disabled";
+ #pwm-cells = <2>;
+ };
+
mmc@3460000 {
compatible = "nvidia,tegra234-sdhci", "nvidia,tegra186-sdhci";
reg = <0x03460000 0x20000>;
@@ -159,6 +681,7 @@
interconnects = <&mc TEGRA234_MEMORY_CLIENT_SDMMCRAB &emc>,
<&mc TEGRA234_MEMORY_CLIENT_SDMMCWAB &emc>;
interconnect-names = "dma-mem", "write";
+ iommus = <&smmu_niso1 TEGRA234_SID_SDMMC4>;
nvidia,pad-autocal-pull-up-offset-hs400 = <0x00>;
nvidia,pad-autocal-pull-down-offset-hs400 = <0x00>;
nvidia,pad-autocal-pull-up-offset-1v8-timeout = <0x0a>;
@@ -172,6 +695,23 @@
status = "disabled";
};
+ hda@3510000 {
+ compatible = "nvidia,tegra234-hda", "nvidia,tegra30-hda";
+ reg = <0x3510000 0x10000>;
+ interrupts = <GIC_SPI 60 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&bpmp TEGRA234_CLK_AZA_BIT>,
+ <&bpmp TEGRA234_CLK_AZA_2XBIT>;
+ clock-names = "hda", "hda2codec_2x";
+ resets = <&bpmp TEGRA234_RESET_HDA>,
+ <&bpmp TEGRA234_RESET_HDACODEC>;
+ reset-names = "hda", "hda2codec_2x";
+ power-domains = <&bpmp TEGRA234_POWER_DOMAIN_DISP>;
+ interconnects = <&mc TEGRA234_MEMORY_CLIENT_HDAR &emc>,
+ <&mc TEGRA234_MEMORY_CLIENT_HDAW &emc>;
+ interconnect-names = "dma-mem", "write";
+ status = "disabled";
+ };
+
fuse@3810000 {
compatible = "nvidia,tegra234-efuse";
reg = <0x03810000 0x10000>;
@@ -197,6 +737,148 @@
#mbox-cells = <2>;
};
+ smmu_niso1: iommu@8000000 {
+ compatible = "nvidia,tegra234-smmu", "nvidia,smmu-500";
+ reg = <0x8000000 0x1000000>,
+ <0x7000000 0x1000000>;
+ interrupts = <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 242 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 242 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>;
+ stream-match-mask = <0x7f80>;
+ #global-interrupts = <2>;
+ #iommu-cells = <1>;
+
+ nvidia,memory-controller = <&mc>;
+ status = "okay";
+ };
+
hsp_aon: hsp@c150000 {
compatible = "nvidia,tegra234-hsp", "nvidia,tegra194-hsp";
reg = <0x0c150000 0x90000>;
@@ -212,6 +894,37 @@
#mbox-cells = <2>;
};
+ gen2_i2c: i2c@c240000 {
+ compatible = "nvidia,tegra194-i2c";
+ reg = <0xc240000 0x100>;
+ interrupts = <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+ clock-frequency = <100000>;
+ clocks = <&bpmp TEGRA234_CLK_I2C2
+ &bpmp TEGRA234_CLK_PLLP_OUT0>;
+ clock-names = "div-clk", "parent";
+ assigned-clocks = <&bpmp TEGRA234_CLK_I2C2>;
+ assigned-clock-parents = <&bpmp TEGRA234_CLK_PLLP_OUT0>;
+ resets = <&bpmp TEGRA234_RESET_I2C2>;
+ reset-names = "i2c";
+ };
+
+ gen8_i2c: i2c@c250000 {
+ compatible = "nvidia,tegra194-i2c";
+ reg = <0xc250000 0x100>;
+ nvidia,hw-instance-id = <0x7>;
+ interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+ clock-frequency = <400000>;
+ clocks = <&bpmp TEGRA234_CLK_I2C8
+ &bpmp TEGRA234_CLK_PLLP_OUT0>;
+ clock-names = "div-clk", "parent";
+ assigned-clocks = <&bpmp TEGRA234_CLK_I2C8>;
+ assigned-clock-parents = <&bpmp TEGRA234_CLK_PLLP_OUT0>;
+ resets = <&bpmp TEGRA234_RESET_I2C8>;
+ reset-names = "i2c";
+ };
+
rtc@c2a0000 {
compatible = "nvidia,tegra234-rtc", "nvidia,tegra20-rtc";
reg = <0x0c2a0000 0x10000>;
@@ -261,6 +974,288 @@
#interrupt-cells = <3>;
interrupt-controller;
};
+
+ smmu_iso: iommu@10000000{
+ compatible = "nvidia,tegra234-smmu", "nvidia,smmu-500";
+ reg = <0x10000000 0x1000000>;
+ interrupts = <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>;
+ stream-match-mask = <0x7f80>;
+ #global-interrupts = <1>;
+ #iommu-cells = <1>;
+
+ nvidia,memory-controller = <&mc>;
+ status = "okay";
+ };
+
+ smmu_niso0: iommu@12000000 {
+ compatible = "nvidia,tegra234-smmu", "nvidia,smmu-500";
+ reg = <0x12000000 0x1000000>,
+ <0x11000000 0x1000000>;
+ interrupts = <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 232 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 232 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>;
+ stream-match-mask = <0x7f80>;
+ #global-interrupts = <2>;
+ #iommu-cells = <1>;
+
+ nvidia,memory-controller = <&mc>;
+ status = "okay";
+ };
};
sram@40000000 {
@@ -296,6 +1291,7 @@
<&mc TEGRA234_MEMORY_CLIENT_BPMPDMAR &emc>,
<&mc TEGRA234_MEMORY_CLIENT_BPMPDMAW &emc>;
interconnect-names = "read", "write", "dma-mem", "dma-write";
+ iommus = <&smmu_niso1 TEGRA234_SID_BPMP>;
bpmp_i2c: i2c {
compatible = "nvidia,tegra186-bpmp-i2c";
@@ -692,6 +1688,20 @@
status = "disabled";
};
+ sound {
+ status = "disabled";
+
+ clocks = <&bpmp TEGRA234_CLK_PLLA>,
+ <&bpmp TEGRA234_CLK_PLLA_OUT0>;
+ clock-names = "pll_a", "plla_out0";
+ assigned-clocks = <&bpmp TEGRA234_CLK_PLLA>,
+ <&bpmp TEGRA234_CLK_PLLA_OUT0>,
+ <&bpmp TEGRA234_CLK_AUD_MCLK>;
+ assigned-clock-parents = <0>,
+ <&bpmp TEGRA234_CLK_PLLA>,
+ <&bpmp TEGRA234_CLK_PLLA_OUT0>;
+ };
+
timer {
compatible = "arm,armv8-timer";
interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
diff --git a/arch/arm64/boot/dts/qcom/Makefile b/arch/arm64/boot/dts/qcom/Makefile
index f7232052d286..f9e6343acd03 100644
--- a/arch/arm64/boot/dts/qcom/Makefile
+++ b/arch/arm64/boot/dts/qcom/Makefile
@@ -18,10 +18,11 @@ dtb-$(CONFIG_ARCH_QCOM) += msm8916-samsung-a5u-eur.dtb
dtb-$(CONFIG_ARCH_QCOM) += msm8916-samsung-j5.dtb
dtb-$(CONFIG_ARCH_QCOM) += msm8916-samsung-serranove.dtb
dtb-$(CONFIG_ARCH_QCOM) += msm8916-wingtech-wt88047.dtb
-dtb-$(CONFIG_ARCH_QCOM) += msm8992-bullhead-rev-101.dtb
+dtb-$(CONFIG_ARCH_QCOM) += msm8992-lg-bullhead-rev-10.dtb
+dtb-$(CONFIG_ARCH_QCOM) += msm8992-lg-bullhead-rev-101.dtb
dtb-$(CONFIG_ARCH_QCOM) += msm8992-msft-lumia-octagon-talkman.dtb
dtb-$(CONFIG_ARCH_QCOM) += msm8992-xiaomi-libra.dtb
-dtb-$(CONFIG_ARCH_QCOM) += msm8994-angler-rev-101.dtb
+dtb-$(CONFIG_ARCH_QCOM) += msm8994-huawei-angler-rev-101.dtb
dtb-$(CONFIG_ARCH_QCOM) += msm8994-msft-lumia-octagon-cityman.dtb
dtb-$(CONFIG_ARCH_QCOM) += msm8994-sony-xperia-kitakami-ivy.dtb
dtb-$(CONFIG_ARCH_QCOM) += msm8994-sony-xperia-kitakami-karin.dtb
@@ -82,7 +83,8 @@ dtb-$(CONFIG_ARCH_QCOM) += sc7180-trogdor-pompom-r3.dtb
dtb-$(CONFIG_ARCH_QCOM) += sc7180-trogdor-pompom-r3-lte.dtb
dtb-$(CONFIG_ARCH_QCOM) += sc7180-trogdor-r1.dtb
dtb-$(CONFIG_ARCH_QCOM) += sc7180-trogdor-r1-lte.dtb
-dtb-$(CONFIG_ARCH_QCOM) += sc7280-herobrine.dtb
+dtb-$(CONFIG_ARCH_QCOM) += sc7280-herobrine-herobrine-r0.dtb
+dtb-$(CONFIG_ARCH_QCOM) += sc7280-herobrine-herobrine-r1.dtb
dtb-$(CONFIG_ARCH_QCOM) += sc7280-idp.dtb
dtb-$(CONFIG_ARCH_QCOM) += sc7280-idp2.dtb
dtb-$(CONFIG_ARCH_QCOM) += sc7280-crd.dtb
@@ -90,6 +92,7 @@ dtb-$(CONFIG_ARCH_QCOM) += sdm630-sony-xperia-ganges-kirin.dtb
dtb-$(CONFIG_ARCH_QCOM) += sdm630-sony-xperia-nile-discovery.dtb
dtb-$(CONFIG_ARCH_QCOM) += sdm630-sony-xperia-nile-pioneer.dtb
dtb-$(CONFIG_ARCH_QCOM) += sdm630-sony-xperia-nile-voyager.dtb
+dtb-$(CONFIG_ARCH_QCOM) += sdm632-fairphone-fp3.dtb
dtb-$(CONFIG_ARCH_QCOM) += sdm636-sony-xperia-ganges-mermaid.dtb
dtb-$(CONFIG_ARCH_QCOM) += sdm660-xiaomi-lavender.dtb
dtb-$(CONFIG_ARCH_QCOM) += sdm845-cheza-r1.dtb
@@ -103,7 +106,9 @@ dtb-$(CONFIG_ARCH_QCOM) += sdm845-sony-xperia-tama-akari.dtb
dtb-$(CONFIG_ARCH_QCOM) += sdm845-sony-xperia-tama-akatsuki.dtb
dtb-$(CONFIG_ARCH_QCOM) += sdm845-sony-xperia-tama-apollo.dtb
dtb-$(CONFIG_ARCH_QCOM) += sdm845-xiaomi-beryllium.dtb
+dtb-$(CONFIG_ARCH_QCOM) += sdm845-shift-axolotl.dtb
dtb-$(CONFIG_ARCH_QCOM) += sdm850-lenovo-yoga-c630.dtb
+dtb-$(CONFIG_ARCH_QCOM) += sdm850-samsung-w737.dtb
dtb-$(CONFIG_ARCH_QCOM) += sm6125-sony-xperia-seine-pdx201.dtb
dtb-$(CONFIG_ARCH_QCOM) += sm6350-sony-xperia-lena-pdx213.dtb
dtb-$(CONFIG_ARCH_QCOM) += sm7225-fairphone-fp4.dtb
@@ -121,4 +126,5 @@ dtb-$(CONFIG_ARCH_QCOM) += sm8350-microsoft-surface-duo2.dtb
dtb-$(CONFIG_ARCH_QCOM) += sm8350-mtp.dtb
dtb-$(CONFIG_ARCH_QCOM) += sm8350-sony-xperia-sagami-pdx214.dtb
dtb-$(CONFIG_ARCH_QCOM) += sm8350-sony-xperia-sagami-pdx215.dtb
+dtb-$(CONFIG_ARCH_QCOM) += sm8450-hdk.dtb
dtb-$(CONFIG_ARCH_QCOM) += sm8450-qrd.dtb
diff --git a/arch/arm64/boot/dts/qcom/apq8016-sbc.dts b/arch/arm64/boot/dts/qcom/apq8016-sbc.dts
index a5320d6d30e7..7c1eab605c15 100644
--- a/arch/arm64/boot/dts/qcom/apq8016-sbc.dts
+++ b/arch/arm64/boot/dts/qcom/apq8016-sbc.dts
@@ -253,7 +253,6 @@
port@0 {
reg = <0>;
csiphy0_ep: endpoint {
- clock-lanes = <1>;
data-lanes = <0 2>;
remote-endpoint = <&ov5640_ep>;
status = "okay";
@@ -289,7 +288,6 @@
port {
ov5640_ep: endpoint {
- clock-lanes = <1>;
data-lanes = <0 2>;
remote-endpoint = <&csiphy0_ep>;
};
@@ -351,12 +349,12 @@
pinctrl-0 = <&cdc_pdm_lines_act &ext_sec_tlmm_lines_act &ext_mclk_tlmm_lines_act>;
pinctrl-1 = <&cdc_pdm_lines_sus &ext_sec_tlmm_lines_sus &ext_mclk_tlmm_lines_sus>;
pinctrl-names = "default", "sleep";
- qcom,model = "DB410c";
- qcom,audio-routing =
+ model = "DB410c";
+ audio-routing =
"AMIC2", "MIC BIAS Internal2",
"AMIC3", "MIC BIAS External1";
- external-dai-link@0 {
+ quaternary-dai-link {
link-name = "ADV7533";
cpu {
sound-dai = <&lpass MI2S_QUATERNARY>;
@@ -366,7 +364,7 @@
};
};
- internal-codec-playback-dai-link@0 {
+ primary-dai-link {
link-name = "WCD";
cpu {
sound-dai = <&lpass MI2S_PRIMARY>;
@@ -376,7 +374,7 @@
};
};
- internal-codec-capture-dai-link@0 {
+ tertiary-dai-link {
link-name = "WCD-Capture";
cpu {
sound-dai = <&lpass MI2S_TERTIARY>;
diff --git a/arch/arm64/boot/dts/qcom/ipq6018.dtsi b/arch/arm64/boot/dts/qcom/ipq6018.dtsi
index 66ec5615651d..4e7efa97724b 100644
--- a/arch/arm64/boot/dts/qcom/ipq6018.dtsi
+++ b/arch/arm64/boot/dts/qcom/ipq6018.dtsi
@@ -373,6 +373,8 @@
intc: interrupt-controller@b000000 {
compatible = "qcom,msm-qgic2";
+ #address-cells = <2>;
+ #size-cells = <2>;
interrupt-controller;
#interrupt-cells = <0x3>;
reg = <0x0 0x0b000000 0x0 0x1000>, /*GICD*/
@@ -380,6 +382,13 @@
<0x0 0x0b001000 0x0 0x1000>, /*GICH*/
<0x0 0x0b004000 0x0 0x1000>; /*GICV*/
interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>;
+ ranges = <0 0 0 0xb00a000 0 0xffd>;
+
+ v2m@0 {
+ compatible = "arm,gic-v2m-frame";
+ msi-controller;
+ reg = <0x0 0x0 0x0 0xffd>;
+ };
};
pcie_phy: phy@84000 {
@@ -425,6 +434,7 @@
linux,pci-domain = <0>;
bus-range = <0x00 0xff>;
num-lanes = <1>;
+ max-link-speed = <3>;
#address-cells = <3>;
#size-cells = <2>;
@@ -520,7 +530,6 @@
ranges;
compatible = "arm,armv7-timer-mem";
reg = <0x0 0x0b120000 0x0 0x1000>;
- clock-frequency = <19200000>;
frame@b120000 {
frame-number = <0>;
@@ -748,7 +757,7 @@
snps,hird-threshold = /bits/ 8 <0x0>;
snps,dis_u2_susphy_quirk;
snps,dis_u3_susphy_quirk;
- snps,ref-clock-period-ns = <0x32>;
+ snps,ref-clock-period-ns = <0x29>;
dr_mode = "host";
};
};
diff --git a/arch/arm64/boot/dts/qcom/ipq8074.dtsi b/arch/arm64/boot/dts/qcom/ipq8074.dtsi
index e6cc261201ef..d80b1cefab10 100644
--- a/arch/arm64/boot/dts/qcom/ipq8074.dtsi
+++ b/arch/arm64/boot/dts/qcom/ipq8074.dtsi
@@ -76,6 +76,25 @@
method = "smc";
};
+ reserved-memory {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ smem@4ab00000 {
+ compatible = "qcom,smem";
+ reg = <0x0 0x4ab00000 0x0 0x00100000>;
+ no-map;
+
+ hwlocks = <&tcsr_mutex 0>;
+ };
+
+ memory@4ac00000 {
+ no-map;
+ reg = <0x0 0x4ac00000 0x0 0x00400000>;
+ };
+ };
+
firmware {
scm {
compatible = "qcom,scm-ipq8074", "qcom,scm";
@@ -331,6 +350,12 @@
#reset-cells = <0x1>;
};
+ tcsr_mutex: hwlock@1905000 {
+ compatible = "qcom,tcsr-mutex";
+ reg = <0x01905000 0x20000>;
+ #hwlock-cells = <1>;
+ };
+
spmi_bus: spmi@200f000 {
compatible = "qcom,spmi-pmic-arb";
reg = <0x0200f000 0x001000>,
@@ -609,9 +634,18 @@
intc: interrupt-controller@b000000 {
compatible = "qcom,msm-qgic2";
+ #address-cells = <1>;
+ #size-cells = <1>;
interrupt-controller;
#interrupt-cells = <0x3>;
reg = <0x0b000000 0x1000>, <0x0b002000 0x1000>;
+ ranges = <0 0xb00a000 0xffd>;
+
+ v2m@0 {
+ compatible = "arm,gic-v2m-frame";
+ msi-controller;
+ reg = <0x0 0xffd>;
+ };
};
timer {
@@ -636,7 +670,6 @@
ranges;
compatible = "arm,armv7-timer-mem";
reg = <0x0b120000 0x1000>;
- clock-frequency = <19200000>;
frame@b120000 {
frame-number = <0>;
diff --git a/arch/arm64/boot/dts/qcom/msm8916-longcheer-l8150.dts b/arch/arm64/boot/dts/qcom/msm8916-longcheer-l8150.dts
index 852de624f5af..b3836dde8a54 100644
--- a/arch/arm64/boot/dts/qcom/msm8916-longcheer-l8150.dts
+++ b/arch/arm64/boot/dts/qcom/msm8916-longcheer-l8150.dts
@@ -151,6 +151,21 @@
vddio-supply = <&pm8916_l6>;
};
+ light-sensor@23 {
+ compatible = "liteon,ltr559";
+ reg = <0x23>;
+ proximity-near-level = <75>;
+
+ interrupt-parent = <&msmgpio>;
+ interrupts = <115 IRQ_TYPE_EDGE_FALLING>;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&light_int_default>;
+
+ vdd-supply = <&pm8916_l17>;
+ vio-supply = <&pm8916_l6>;
+ };
+
gyroscope@68 {
compatible = "bosch,bmg160";
reg = <0x68>;
@@ -392,6 +407,14 @@
bias-disable;
};
+ light_int_default: light-int-default {
+ pins = "gpio115";
+ function = "gpio";
+
+ drive-strength = <2>;
+ bias-disable;
+ };
+
magn_int_default: magn-int-default {
pins = "gpio113";
function = "gpio";
diff --git a/arch/arm64/boot/dts/qcom/msm8916-samsung-j5.dts b/arch/arm64/boot/dts/qcom/msm8916-samsung-j5.dts
index 687bea438a57..6c408d61de75 100644
--- a/arch/arm64/boot/dts/qcom/msm8916-samsung-j5.dts
+++ b/arch/arm64/boot/dts/qcom/msm8916-samsung-j5.dts
@@ -41,7 +41,7 @@
};
home-key {
- lable = "Home Key";
+ label = "Home Key";
gpios = <&msmgpio 109 GPIO_ACTIVE_LOW>;
linux,code = <KEY_HOMEPAGE>;
};
diff --git a/arch/arm64/boot/dts/qcom/msm8916.dtsi b/arch/arm64/boot/dts/qcom/msm8916.dtsi
index 41897eb3736a..0a0be43529f6 100644
--- a/arch/arm64/boot/dts/qcom/msm8916.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8916.dtsi
@@ -1731,8 +1731,10 @@
clock-names = "ref", "sleep";
resets = <&gcc GCC_USB2A_PHY_BCR>, <&usb 0>;
reset-names = "phy", "por";
- qcom,init-seq = /bits/ 8 <0x0 0x44
- 0x1 0x6b 0x2 0x24 0x3 0x13>;
+ qcom,init-seq = /bits/ 8 <0x0 0x44>,
+ <0x1 0x6b>,
+ <0x2 0x24>,
+ <0x3 0x13>;
};
};
};
diff --git a/arch/arm64/boot/dts/qcom/msm8953.dtsi b/arch/arm64/boot/dts/qcom/msm8953.dtsi
new file mode 100644
index 000000000000..431228faacdd
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/msm8953.dtsi
@@ -0,0 +1,1326 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/* Copyright (c) 2022, The Linux Foundation. All rights reserved. */
+
+#include <dt-bindings/clock/qcom,gcc-msm8953.h>
+#include <dt-bindings/gpio/gpio.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>;
+
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ chosen { };
+
+ clocks {
+ sleep_clk: sleep-clk {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <32768>;
+ };
+
+ xo_board: xo-board {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <19200000>;
+ clock-output-names = "xo";
+ };
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ CPU0: cpu@0 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a53";
+ reg = <0x0>;
+ enable-method = "psci";
+ capacity-dmips-mhz = <1024>;
+ next-level-cache = <&L2_0>;
+ #cooling-cells = <2>;
+
+ l1-icache {
+ compatible = "cache";
+ };
+ l1-dcache {
+ compatible = "cache";
+ };
+ };
+
+ CPU1: cpu@1 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a53";
+ reg = <0x1>;
+ enable-method = "psci";
+ capacity-dmips-mhz = <1024>;
+ next-level-cache = <&L2_0>;
+ #cooling-cells = <2>;
+
+ l1-icache {
+ compatible = "cache";
+ };
+ l1-dcache {
+ compatible = "cache";
+ };
+ };
+
+ CPU2: cpu@2 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a53";
+ reg = <0x2>;
+ enable-method = "psci";
+ capacity-dmips-mhz = <1024>;
+ next-level-cache = <&L2_0>;
+ #cooling-cells = <2>;
+
+ l1-icache {
+ compatible = "cache";
+ };
+ l1-dcache {
+ compatible = "cache";
+ };
+ };
+
+ CPU3: cpu@3 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a53";
+ reg = <0x3>;
+ enable-method = "psci";
+ capacity-dmips-mhz = <1024>;
+ next-level-cache = <&L2_0>;
+ #cooling-cells = <2>;
+
+ l1-icache {
+ compatible = "cache";
+ };
+ l1-dcache {
+ compatible = "cache";
+ };
+ };
+
+ CPU4: cpu@100 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a53";
+ reg = <0x100>;
+ enable-method = "psci";
+ capacity-dmips-mhz = <1024>;
+ next-level-cache = <&L2_1>;
+ #cooling-cells = <2>;
+
+ l1-icache {
+ compatible = "cache";
+ };
+ l1-dcache {
+ compatible = "cache";
+ };
+ };
+
+ CPU5: cpu@101 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a53";
+ reg = <0x101>;
+ enable-method = "psci";
+ capacity-dmips-mhz = <1024>;
+ next-level-cache = <&L2_1>;
+ #cooling-cells = <2>;
+
+ l1-icache {
+ compatible = "cache";
+ };
+ l1-dcache {
+ compatible = "cache";
+ };
+ };
+
+ CPU6: cpu@102 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a53";
+ reg = <0x102>;
+ enable-method = "psci";
+ capacity-dmips-mhz = <1024>;
+ next-level-cache = <&L2_1>;
+ #cooling-cells = <2>;
+
+ l1-icache {
+ compatible = "cache";
+ };
+ l1-dcache {
+ compatible = "cache";
+ };
+ };
+
+ CPU7: cpu@103 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a53";
+ reg = <0x103>;
+ enable-method = "psci";
+ capacity-dmips-mhz = <1024>;
+ next-level-cache = <&L2_1>;
+ #cooling-cells = <2>;
+
+ l1-icache {
+ compatible = "cache";
+ };
+ l1-dcache {
+ compatible = "cache";
+ };
+ };
+
+ cpu-map {
+ cluster0 {
+ core0 {
+ cpu = <&CPU0>;
+ };
+ core1 {
+ cpu = <&CPU1>;
+ };
+ core2 {
+ cpu = <&CPU2>;
+ };
+ core3 {
+ cpu = <&CPU3>;
+ };
+ };
+
+ cluster1 {
+ core0 {
+ cpu = <&CPU4>;
+ };
+ core1 {
+ cpu = <&CPU5>;
+ };
+ core2 {
+ cpu = <&CPU6>;
+ };
+ core3 {
+ cpu = <&CPU7>;
+ };
+ };
+ };
+
+ L2_0: l2-cache_0 {
+ compatible = "cache";
+ cache-level = <2>;
+ };
+
+ L2_1: l2-cache_1 {
+ compatible = "cache";
+ cache-level = <2>;
+ };
+ };
+
+ firmware {
+ scm: scm {
+ compatible = "qcom,scm-msm8953";
+ clocks = <&gcc GCC_CRYPTO_CLK>,
+ <&gcc GCC_CRYPTO_AXI_CLK>,
+ <&gcc GCC_CRYPTO_AHB_CLK>;
+ clock-names = "core", "bus", "iface";
+ #reset-cells = <1>;
+ };
+ };
+
+ memory {
+ device_type = "memory";
+ /* We expect the bootloader to fill in the reg */
+ reg = <0 0 0 0>;
+ };
+
+ pmu {
+ compatible = "arm,cortex-a53-pmu";
+ interrupts = <GIC_PPI 7 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_HIGH)>;
+ };
+
+ psci {
+ compatible = "arm,psci-1.0";
+ method = "smc";
+ };
+
+ reserved-memory {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ zap_shader_region: memory@81800000 {
+ compatible = "shared-dma-pool";
+ reg = <0x0 0x81800000 0x0 0x2000>;
+ no-map;
+ };
+
+ memory@85b00000 {
+ reg = <0x0 0x85b00000 0x0 0x800000>;
+ no-map;
+ };
+
+ smem_mem: memory@86300000 {
+ compatible = "qcom,smem";
+ reg = <0x0 0x86300000 0x0 0x100000>;
+ qcom,rpm-msg-ram = <&rpm_msg_ram>;
+ hwlocks = <&tcsr_mutex 3>;
+ no-map;
+ };
+
+ memory@86400000 {
+ reg = <0x0 0x86400000 0x0 0x400000>;
+ no-map;
+ };
+
+ mpss_mem: memory@86c00000 {
+ reg = <0x0 0x86c00000 0x0 0x6a00000>;
+ no-map;
+ };
+
+ adsp_fw_mem: memory@8d600000 {
+ reg = <0x0 0x8d600000 0x0 0x1100000>;
+ no-map;
+ };
+
+ wcnss_fw_mem: memory@8e700000 {
+ reg = <0x0 0x8e700000 0x0 0x700000>;
+ no-map;
+ };
+
+ memory@90000000 {
+ reg = <0 0x90000000 0 0x1000>;
+ no-map;
+ };
+
+ memory@90001000 {
+ reg = <0x0 0x90001000 0x0 0x13ff000>;
+ no-map;
+ };
+
+ venus_mem: memory@91400000 {
+ reg = <0x0 0x91400000 0x0 0x700000>;
+ no-map;
+ };
+
+ mba_mem: memory@92000000 {
+ reg = <0x0 0x92000000 0x0 0x100000>;
+ no-map;
+ };
+
+ memory@f2d00000 {
+ compatible = "qcom,rmtfs-mem";
+ reg = <0x0 0xf2d00000 0x0 0x180000>;
+ no-map;
+
+ qcom,client-id = <1>;
+ };
+ };
+
+ smd {
+ compatible = "qcom,smd";
+
+ rpm {
+ interrupts = <GIC_SPI 168 IRQ_TYPE_EDGE_RISING>;
+ qcom,ipc = <&apcs 8 0>;
+ qcom,smd-edge = <15>;
+
+ rpm_requests: rpm_requests {
+ compatible = "qcom,rpm-msm8953";
+ qcom,smd-channels = "rpm_requests";
+
+ rpmcc: rpmcc {
+ compatible = "qcom,rpmcc-msm8953";
+ clocks = <&xo_board>;
+ clock-names = "xo";
+ #clock-cells = <1>;
+ };
+
+ rpmpd: power-controller {
+ compatible = "qcom,msm8953-rpmpd";
+ #power-domain-cells = <1>;
+ operating-points-v2 = <&rpmpd_opp_table>;
+
+ clocks = <&xo_board>;
+ clock-names = "ref";
+
+ rpmpd_opp_table: opp-table {
+ compatible = "operating-points-v2";
+
+ rpmpd_opp_ret: opp1 {
+ opp-level = <RPM_SMD_LEVEL_RETENTION>;
+ };
+
+ rpmpd_opp_ret_plus: opp2 {
+ opp-level = <RPM_SMD_LEVEL_RETENTION_PLUS>;
+ };
+
+ rpmpd_opp_min_svs: opp3 {
+ opp-level = <RPM_SMD_LEVEL_MIN_SVS>;
+ };
+
+ rpmpd_opp_low_svs: opp4 {
+ opp-level = <RPM_SMD_LEVEL_LOW_SVS>;
+ };
+
+ rpmpd_opp_svs: opp5 {
+ opp-level = <RPM_SMD_LEVEL_SVS>;
+ };
+
+ rpmpd_opp_svs_plus: opp6 {
+ opp-level = <RPM_SMD_LEVEL_SVS_PLUS>;
+ };
+
+ rpmpd_opp_nom: opp7 {
+ opp-level = <RPM_SMD_LEVEL_NOM>;
+ };
+
+ rpmpd_opp_nom_plus: opp8 {
+ opp-level = <RPM_SMD_LEVEL_NOM_PLUS>;
+ };
+
+ rpmpd_opp_turbo: opp9 {
+ opp-level = <RPM_SMD_LEVEL_TURBO>;
+ };
+ };
+ };
+ };
+ };
+ };
+
+ smsm {
+ compatible = "qcom,smsm";
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ qcom,ipc-1 = <&apcs 8 13>;
+ qcom,ipc-3 = <&apcs 8 19>;
+
+ apps_smsm: apps@0 {
+ reg = <0>;
+
+ #qcom,smem-state-cells = <1>;
+ };
+ };
+
+ soc: soc@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0 0 0 0xffffffff>;
+ compatible = "simple-bus";
+
+ rpm_msg_ram: sram@60000 {
+ compatible = "qcom,rpm-msg-ram";
+ reg = <0x60000 0x8000>;
+ };
+
+ hsusb_phy: phy@79000 {
+ compatible = "qcom,msm8953-qusb2-phy";
+ reg = <0x79000 0x180>;
+ #phy-cells = <0>;
+
+ clocks = <&gcc GCC_USB_PHY_CFG_AHB_CLK>,
+ <&gcc GCC_QUSB_REF_CLK>;
+ clock-names = "cfg_ahb", "ref";
+
+ qcom,tcsr-syscon = <&tcsr_phy_clk_scheme_sel>;
+
+ resets = <&gcc GCC_QUSB2_PHY_BCR>;
+
+ status = "disabled";
+ };
+
+ rng@e3000 {
+ compatible = "qcom,prng";
+ reg = <0x000e3000 0x1000>;
+ clocks = <&gcc GCC_PRNG_AHB_CLK>;
+ clock-names = "core";
+ };
+
+ tsens0: thermal-sensor@4a9000 {
+ compatible = "qcom,msm8953-tsens", "qcom,tsens-v2";
+ reg = <0x4a9000 0x1000>, /* TM */
+ <0x4a8000 0x1000>; /* SROT */
+ #qcom,sensors = <16>;
+ interrupts = <GIC_SPI 184 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 314 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "uplow", "critical";
+ #thermal-sensor-cells = <1>;
+ };
+
+ restart@4ab000 {
+ compatible = "qcom,pshold";
+ reg = <0x4ab000 0x4>;
+ };
+
+ tlmm: pinctrl@1000000 {
+ compatible = "qcom,msm8953-pinctrl";
+ reg = <0x1000000 0x300000>;
+ interrupts = <GIC_SPI 208 IRQ_TYPE_LEVEL_HIGH>;
+ gpio-controller;
+ gpio-ranges = <&tlmm 0 0 155>;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+
+ uart_console_active: uart-console-active-pins {
+ pins = "gpio4", "gpio5";
+ function = "blsp_uart2";
+ drive-strength = <2>;
+ bias-disable;
+ };
+
+ uart_console_sleep: uart-console-sleep-pins {
+ pins = "gpio4", "gpio5";
+ function = "blsp_uart2";
+ drive-strength = <2>;
+ bias-pull-down;
+ };
+
+ sdc1_clk_on: sdc1-clk-on-pins {
+ pins = "sdc1_clk";
+ bias-disable;
+ drive-strength = <16>;
+ };
+
+ sdc1_clk_off: sdc1-clk-off-pins {
+ pins = "sdc1_clk";
+ bias-disable;
+ drive-strength = <2>;
+ };
+
+ sdc1_cmd_on: sdc1-cmd-on-pins {
+ pins = "sdc1_cmd";
+ bias-disable;
+ drive-strength = <10>;
+ };
+
+ sdc1_cmd_off: sdc1-cmd-off-pins {
+ pins = "sdc1_cmd";
+ bias-disable;
+ drive-strength = <2>;
+ };
+
+ sdc1_data_on: sdc1-data-on-pins {
+ pins = "sdc1_data";
+ bias-pull-up;
+ drive-strength = <10>;
+ };
+
+ sdc1_data_off: sdc1-data-off-pins {
+ pins = "sdc1_data";
+ bias-pull-up;
+ drive-strength = <2>;
+ };
+
+ sdc1_rclk_on: sdc1-rclk-on-pins {
+ pins = "sdc1_rclk";
+ bias-pull-down;
+ };
+
+ sdc1_rclk_off: sdc1-rclk-off-pins {
+ pins = "sdc1_rclk";
+ bias-pull-down;
+ };
+
+ sdc2_clk_on: sdc2-clk-on-pins {
+ pins = "sdc2_clk";
+ drive-strength = <16>;
+ bias-disable;
+ };
+
+ sdc2_clk_off: sdc2-clk-off-pins {
+ pins = "sdc2_clk";
+ bias-disable;
+ drive-strength = <2>;
+ };
+
+ sdc2_cmd_on: sdc2-cmd-on-pins {
+ pins = "sdc2_cmd";
+ bias-pull-up;
+ drive-strength = <10>;
+ };
+
+ sdc2_cmd_off: sdc2-cmd-off-pins {
+ pins = "sdc2_cmd";
+ bias-pull-up;
+ drive-strength = <2>;
+ };
+
+ sdc2_data_on: sdc2-data-on-pins {
+ pins = "sdc2_data";
+ bias-pull-up;
+ drive-strength = <10>;
+ };
+
+ sdc2_data_off: sdc2-data-off-pins {
+ pins = "sdc2_data";
+ bias-pull-up;
+ drive-strength = <2>;
+ };
+
+ sdc2_cd_on: cd-on-pins {
+ pins = "gpio133";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-pull-up;
+ };
+
+ sdc2_cd_off: cd-off-pins {
+ pins = "gpio133";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-disable;
+ };
+
+ gpio_key_default: gpio-key-default-pins {
+ pins = "gpio85";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-pull-up;
+ };
+
+ i2c_1_default: i2c-1-default-pins {
+ pins = "gpio2", "gpio3";
+ function = "blsp_i2c1";
+ drive-strength = <2>;
+ bias-disable;
+ };
+
+ i2c_1_sleep: i2c-1-sleep-pins {
+ pins = "gpio2", "gpio3";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-disable;
+ };
+
+ i2c_2_default: i2c-2-default-pins {
+ pins = "gpio6", "gpio7";
+ function = "blsp_i2c2";
+ drive-strength = <2>;
+ bias-disable;
+ };
+
+ i2c_2_sleep: i2c-2-sleep-pins {
+ pins = "gpio6", "gpio7";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-disable;
+ };
+
+ i2c_3_default: i2c-3-default-pins {
+ pins = "gpio10", "gpio11";
+ function = "blsp_i2c3";
+ drive-strength = <2>;
+ bias-disable;
+ };
+
+ i2c_3_sleep: i2c-3-sleep-pins {
+ pins = "gpio10", "gpio11";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-disable;
+ };
+
+ i2c_4_default: i2c-4-default-pins {
+ pins = "gpio14", "gpio15";
+ function = "blsp_i2c4";
+ drive-strength = <2>;
+ bias-disable;
+ };
+
+ i2c_4_sleep: i2c-4-sleep-pins {
+ pins = "gpio14", "gpio15";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-disable;
+ };
+
+ i2c_5_default: i2c-5-default-pins {
+ pins = "gpio18", "gpio19";
+ function = "blsp_i2c5";
+ drive-strength = <2>;
+ bias-disable;
+ };
+
+ i2c_5_sleep: i2c-5-sleep-pins {
+ pins = "gpio18", "gpio19";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-disable;
+ };
+
+ i2c_6_default: i2c-6-default-pins {
+ pins = "gpio22", "gpio23";
+ function = "blsp_i2c6";
+ drive-strength = <2>;
+ bias-disable;
+ };
+
+ i2c_6_sleep: i2c-6-sleep-pins {
+ pins = "gpio22", "gpio23";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-disable;
+ };
+
+ i2c_7_default: i2c-7-default-pins {
+ pins = "gpio135", "gpio136";
+ function = "blsp_i2c7";
+ drive-strength = <2>;
+ bias-disable;
+ };
+
+ i2c_7_sleep: i2c-7-sleep-pins {
+ pins = "gpio135", "gpio136";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-disable;
+ };
+
+ i2c_8_default: i2c-8-default-pins {
+ pins = "gpio98", "gpio99";
+ function = "blsp_i2c8";
+ drive-strength = <2>;
+ bias-disable;
+ };
+
+ i2c_8_sleep: i2c-8-sleep-pins {
+ pins = "gpio98", "gpio99";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-disable;
+ };
+ };
+
+ gcc: clock-controller@1800000 {
+ compatible = "qcom,gcc-msm8953";
+ reg = <0x1800000 0x80000>;
+ #clock-cells = <1>;
+ #reset-cells = <1>;
+ #power-domain-cells = <1>;
+ clocks = <&xo_board>,
+ <&sleep_clk>,
+ <0>,
+ <0>,
+ <0>,
+ <0>;
+ clock-names = "xo",
+ "sleep",
+ "dsi0pll",
+ "dsi0pllbyte",
+ "dsi1pll",
+ "dsi1pllbyte";
+ };
+
+ tcsr_mutex: hwlock@1905000 {
+ compatible = "qcom,tcsr-mutex";
+ reg = <0x1905000 0x20000>;
+ #hwlock-cells = <1>;
+ };
+
+ tcsr: syscon@1937000 {
+ compatible = "qcom,tcsr-msm8953", "syscon";
+ reg = <0x1937000 0x30000>;
+ };
+
+ tcsr_phy_clk_scheme_sel: syscon@193f044 {
+ compatible = "syscon";
+ reg = <0x193f044 0x4>;
+ };
+
+ spmi_bus: spmi@200f000 {
+ compatible = "qcom,spmi-pmic-arb";
+ reg = <0x200f000 0x1000>,
+ <0x2400000 0x800000>,
+ <0x2c00000 0x800000>,
+ <0x3800000 0x200000>,
+ <0x200a000 0x2100>;
+ reg-names = "core", "chnls", "obsrvr", "intr", "cnfg";
+ interrupt-names = "periph_irq";
+ interrupts = <GIC_SPI 190 IRQ_TYPE_LEVEL_HIGH>;
+ qcom,ee = <0>;
+ qcom,channel = <0>;
+ interrupt-controller;
+
+ #interrupt-cells = <4>;
+ #address-cells = <2>;
+ #size-cells = <0>;
+ };
+
+ usb3: usb@70f8800 {
+ compatible = "qcom,msm8953-dwc3", "qcom,dwc3";
+ reg = <0x70f8800 0x400>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ interrupts = <GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 220 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "hs_phy_irq", "ss_phy_irq";
+
+ clocks = <&gcc GCC_USB_PHY_CFG_AHB_CLK>,
+ <&gcc GCC_USB30_MASTER_CLK>,
+ <&gcc GCC_PCNOC_USB3_AXI_CLK>,
+ <&gcc GCC_USB30_MOCK_UTMI_CLK>,
+ <&gcc GCC_USB30_SLEEP_CLK>;
+ clock-names = "cfg_noc", "core", "iface",
+ "mock_utmi", "sleep";
+
+ assigned-clocks = <&gcc GCC_USB30_MOCK_UTMI_CLK>,
+ <&gcc GCC_USB30_MASTER_CLK>;
+ assigned-clock-rates = <19200000>, <133330000>;
+
+ power-domains = <&gcc USB30_GDSC>;
+
+ qcom,select-utmi-as-pipe-clk;
+
+ status = "disabled";
+
+ usb3_dwc3: usb@7000000 {
+ compatible = "snps,dwc3";
+ reg = <0x07000000 0xcc00>;
+ interrupts = <GIC_SPI 140 IRQ_TYPE_LEVEL_HIGH>;
+ phys = <&hsusb_phy>;
+ phy-names = "usb2-phy";
+
+ snps,usb2-gadget-lpm-disable;
+ snps,dis-u1-entry-quirk;
+ snps,dis-u2-entry-quirk;
+ snps,is-utmi-l1-suspend;
+ snps,hird-threshold = /bits/ 8 <0x00>;
+
+ maximum-speed = "high-speed";
+ phy_mode = "utmi";
+ };
+ };
+
+ sdhc_1: sdhci@7824900 {
+ compatible = "qcom,msm8953-sdhci", "qcom,sdhci-msm-v4";
+
+ reg = <0x7824900 0x500>, <0x7824000 0x800>;
+ reg-names = "hc_mem", "core_mem";
+
+ interrupts = <GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 138 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "hc_irq", "pwr_irq";
+
+ clocks = <&gcc GCC_SDCC1_AHB_CLK>,
+ <&gcc GCC_SDCC1_APPS_CLK>,
+ <&xo_board>;
+ clock-names = "iface", "core", "xo";
+
+ power-domains = <&rpmpd MSM8953_VDDCX>;
+ operating-points-v2 = <&sdhc1_opp_table>;
+
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&sdc1_clk_on &sdc1_cmd_on &sdc1_data_on &sdc1_rclk_on>;
+ pinctrl-1 = <&sdc1_clk_off &sdc1_cmd_off &sdc1_data_off &sdc1_rclk_off>;
+
+ mmc-hs400-1_8v;
+ mmc-hs200-1_8v;
+ mmc-ddr-1_8v;
+ bus-width = <8>;
+ non-removable;
+
+ status = "disabled";
+
+ sdhc1_opp_table: opp-table-sdhc1 {
+ compatible = "operating-points-v2";
+
+ opp-25000000 {
+ opp-hz = /bits/ 64 <25000000>;
+ required-opps = <&rpmpd_opp_low_svs>;
+ };
+
+ opp-50000000 {
+ opp-hz = /bits/ 64 <50000000>;
+ required-opps = <&rpmpd_opp_svs>;
+ };
+
+ opp-100000000 {
+ opp-hz = /bits/ 64 <100000000>;
+ required-opps = <&rpmpd_opp_svs>;
+ };
+
+ opp-192000000 {
+ opp-hz = /bits/ 64 <192000000>;
+ required-opps = <&rpmpd_opp_nom>;
+ };
+
+ opp-384000000 {
+ opp-hz = /bits/ 64 <384000000>;
+ required-opps = <&rpmpd_opp_nom>;
+ };
+ };
+ };
+
+ sdhc_2: sdhci@7864900 {
+ compatible = "qcom,msm8953-sdhci", "qcom,sdhci-msm-v4";
+
+ reg = <0x7864900 0x500>, <0x7864000 0x800>;
+ reg-names = "hc_mem", "core_mem";
+
+ interrupts = <GIC_SPI 125 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 221 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "hc_irq", "pwr_irq";
+
+ clocks = <&gcc GCC_SDCC2_AHB_CLK>,
+ <&gcc GCC_SDCC2_APPS_CLK>,
+ <&xo_board>;
+ clock-names = "iface", "core", "xo";
+
+ power-domains = <&rpmpd MSM8953_VDDCX>;
+ operating-points-v2 = <&sdhc2_opp_table>;
+
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&sdc2_clk_on &sdc2_cmd_on &sdc2_data_on>;
+ pinctrl-1 = <&sdc2_clk_off &sdc2_cmd_off &sdc2_data_off>;
+
+ bus-width = <4>;
+
+ status = "disabled";
+
+ sdhc2_opp_table: opp-table-sdhc2 {
+ compatible = "operating-points-v2";
+
+ opp-25000000 {
+ opp-hz = /bits/ 64 <25000000>;
+ required-opps = <&rpmpd_opp_low_svs>;
+ };
+
+ opp-50000000 {
+ opp-hz = /bits/ 64 <50000000>;
+ required-opps = <&rpmpd_opp_svs>;
+ };
+
+ opp-100000000 {
+ opp-hz = /bits/ 64 <100000000>;
+ required-opps = <&rpmpd_opp_svs>;
+ };
+
+ opp-177770000 {
+ opp-hz = /bits/ 64 <177770000>;
+ required-opps = <&rpmpd_opp_nom>;
+ };
+
+ opp-200000000 {
+ opp-hz = /bits/ 64 <200000000>;
+ required-opps = <&rpmpd_opp_nom>;
+ };
+ };
+ };
+
+ uart_0: serial@78af000 {
+ compatible = "qcom,msm-uartdm-v1.4", "qcom,msm-uartdm";
+ reg = <0x78af000 0x200>;
+ interrupts = <GIC_SPI 107 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&gcc GCC_BLSP1_UART1_APPS_CLK>,
+ <&gcc GCC_BLSP1_AHB_CLK>;
+ clock-names = "core", "iface";
+
+ status = "disabled";
+ };
+
+ i2c_1: i2c@78b5000 {
+ compatible = "qcom,i2c-qup-v2.2.1";
+ reg = <0x78b5000 0x600>;
+ interrupts = <GIC_SPI 95 IRQ_TYPE_LEVEL_HIGH>;
+ clock-names = "iface", "core";
+ clocks = <&gcc GCC_BLSP1_AHB_CLK>,
+ <&gcc GCC_BLSP1_QUP1_I2C_APPS_CLK>;
+
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&i2c_1_default>;
+ pinctrl-1 = <&i2c_1_sleep>;
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ status = "disabled";
+ };
+
+ i2c_2: i2c@78b6000 {
+ compatible = "qcom,i2c-qup-v2.2.1";
+ reg = <0x78b6000 0x600>;
+ interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>;
+ clock-names = "iface", "core";
+ clocks = <&gcc GCC_BLSP1_AHB_CLK>,
+ <&gcc GCC_BLSP1_QUP2_I2C_APPS_CLK>;
+
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&i2c_2_default>;
+ pinctrl-1 = <&i2c_2_sleep>;
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ status = "disabled";
+ };
+
+ i2c_3: i2c@78b7000 {
+ compatible = "qcom,i2c-qup-v2.2.1";
+ reg = <0x78b7000 0x600>;
+ interrupts = <GIC_SPI 97 IRQ_TYPE_LEVEL_HIGH>;
+ clock-names = "iface", "core";
+ clocks = <&gcc GCC_BLSP1_AHB_CLK>,
+ <&gcc GCC_BLSP1_QUP3_I2C_APPS_CLK>;
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&i2c_3_default>;
+ pinctrl-1 = <&i2c_3_sleep>;
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ status = "disabled";
+ };
+
+ i2c_4: i2c@78b8000 {
+ compatible = "qcom,i2c-qup-v2.2.1";
+ reg = <0x78b8000 0x600>;
+ interrupts = <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>;
+ clock-names = "iface", "core";
+ clocks = <&gcc GCC_BLSP1_AHB_CLK>,
+ <&gcc GCC_BLSP1_QUP4_I2C_APPS_CLK>;
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&i2c_4_default>;
+ pinctrl-1 = <&i2c_4_sleep>;
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ status = "disabled";
+ };
+
+ i2c_5: i2c@7af5000 {
+ compatible = "qcom,i2c-qup-v2.2.1";
+ reg = <0x7af5000 0x600>;
+ interrupts = <GIC_SPI 299 IRQ_TYPE_LEVEL_HIGH>;
+ clock-names = "iface", "core";
+ clocks = <&gcc GCC_BLSP2_AHB_CLK>,
+ <&gcc GCC_BLSP2_QUP1_I2C_APPS_CLK>;
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&i2c_5_default>;
+ pinctrl-1 = <&i2c_5_sleep>;
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ status = "disabled";
+ };
+
+ i2c_6: i2c@7af6000 {
+ compatible = "qcom,i2c-qup-v2.2.1";
+ reg = <0x7af6000 0x600>;
+ interrupts = <GIC_SPI 300 IRQ_TYPE_LEVEL_HIGH>;
+ clock-names = "iface", "core";
+ clocks = <&gcc GCC_BLSP2_AHB_CLK>,
+ <&gcc GCC_BLSP2_QUP2_I2C_APPS_CLK>;
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&i2c_6_default>;
+ pinctrl-1 = <&i2c_6_sleep>;
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ status = "disabled";
+ };
+
+ i2c_7: i2c@7af7000 {
+ compatible = "qcom,i2c-qup-v2.2.1";
+ reg = <0x7af7000 0x600>;
+ interrupts = <GIC_SPI 301 IRQ_TYPE_LEVEL_HIGH>;
+ clock-names = "iface", "core";
+ clocks = <&gcc GCC_BLSP2_AHB_CLK>,
+ <&gcc GCC_BLSP2_QUP3_I2C_APPS_CLK>;
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&i2c_7_default>;
+ pinctrl-1 = <&i2c_7_sleep>;
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ status = "disabled";
+ };
+
+ i2c_8: i2c@7af8000 {
+ compatible = "qcom,i2c-qup-v2.2.1";
+ reg = <0x7af8000 0x600>;
+ interrupts = <GIC_SPI 302 IRQ_TYPE_LEVEL_HIGH>;
+ clock-names = "iface", "core";
+ clocks = <&gcc GCC_BLSP2_AHB_CLK>,
+ <&gcc GCC_BLSP2_QUP4_I2C_APPS_CLK>;
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&i2c_8_default>;
+ pinctrl-1 = <&i2c_8_sleep>;
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ status = "disabled";
+ };
+
+ intc: interrupt-controller@b000000 {
+ compatible = "qcom,msm-qgic2";
+ interrupt-controller;
+ #interrupt-cells = <3>;
+ reg = <0x0b000000 0x1000>, <0x0b002000 0x1000>;
+ };
+
+ apcs: mailbox@b011000 {
+ compatible = "qcom,msm8953-apcs-kpss-global", "syscon";
+ reg = <0xb011000 0x1000>;
+ #mbox-cells = <1>;
+ };
+
+ timer@b120000 {
+ compatible = "arm,armv7-timer-mem";
+ reg = <0xb120000 0x1000>;
+ #address-cells = <0x01>;
+ #size-cells = <0x01>;
+ ranges;
+
+ frame@b121000 {
+ frame-number = <0>;
+ interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>;
+ reg = <0xb121000 0x1000>,
+ <0xb122000 0x1000>;
+ };
+
+ frame@b123000 {
+ frame-number = <1>;
+ interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>;
+ reg = <0xb123000 0x1000>;
+ status = "disabled";
+ };
+
+ frame@b124000 {
+ frame-number = <2>;
+ interrupts = <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>;
+ reg = <0xb124000 0x1000>;
+ status = "disabled";
+ };
+
+ frame@b125000 {
+ frame-number = <3>;
+ interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>;
+ reg = <0xb125000 0x1000>;
+ status = "disabled";
+ };
+
+ frame@b126000 {
+ frame-number = <4>;
+ interrupts = <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>;
+ reg = <0xb126000 0x1000>;
+ status = "disabled";
+ };
+
+ frame@b127000 {
+ frame-number = <5>;
+ interrupts = <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>;
+ reg = <0xb127000 0x1000>;
+ status = "disabled";
+ };
+
+ frame@b128000 {
+ frame-number = <6>;
+ interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>;
+ reg = <0xb128000 0x1000>;
+ status = "disabled";
+ };
+ };
+ };
+
+ thermal-zones {
+ cpu0-thermal {
+ polling-delay-passive = <250>;
+ polling-delay = <1000>;
+ thermal-sensors = <&tsens0 9>;
+ trips {
+ cpu0_alert: trip-point0 {
+ temperature = <80000>;
+ hysteresis = <2000>;
+ type = "passive";
+ };
+ cpu0_crit: crit {
+ temperature = <100000>;
+ hysteresis = <2000>;
+ type = "critical";
+ };
+ };
+ cooling-maps {
+ map0 {
+ trip = <&cpu0_alert>;
+ cooling-device = <&CPU0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
+ };
+ cpu1-thermal {
+ polling-delay-passive = <250>;
+ polling-delay = <1000>;
+ thermal-sensors = <&tsens0 10>;
+ trips {
+ cpu1_alert: trip-point0 {
+ temperature = <80000>;
+ hysteresis = <2000>;
+ type = "passive";
+ };
+ cpu1_crit: crit {
+ temperature = <100000>;
+ hysteresis = <2000>;
+ type = "critical";
+ };
+ };
+ cooling-maps {
+ map0 {
+ trip = <&cpu1_alert>;
+ cooling-device = <&CPU1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
+ };
+ cpu2-thermal {
+ polling-delay-passive = <250>;
+ polling-delay = <1000>;
+ thermal-sensors = <&tsens0 11>;
+ trips {
+ cpu2_alert: trip-point0 {
+ temperature = <80000>;
+ hysteresis = <2000>;
+ type = "passive";
+ };
+ cpu2_crit: crit {
+ temperature = <100000>;
+ hysteresis = <2000>;
+ type = "critical";
+ };
+ };
+ cooling-maps {
+ map0 {
+ trip = <&cpu2_alert>;
+ cooling-device = <&CPU2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
+ };
+ cpu3-thermal {
+ polling-delay-passive = <250>;
+ polling-delay = <1000>;
+ thermal-sensors = <&tsens0 12>;
+ trips {
+ cpu3_alert: trip-point0 {
+ temperature = <80000>;
+ hysteresis = <2000>;
+ type = "passive";
+ };
+ cpu3_crit: crit {
+ temperature = <100000>;
+ hysteresis = <2000>;
+ type = "critical";
+ };
+ };
+ cooling-maps {
+ map0 {
+ trip = <&cpu3_alert>;
+ cooling-device = <&CPU3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
+ };
+ cpu4-thermal {
+ polling-delay-passive = <250>;
+ polling-delay = <1000>;
+ thermal-sensors = <&tsens0 4>;
+ trips {
+ cpu4_alert: trip-point0 {
+ temperature = <80000>;
+ hysteresis = <2000>;
+ type = "passive";
+ };
+ cpu4_crit: crit {
+ temperature = <100000>;
+ hysteresis = <2000>;
+ type = "critical";
+ };
+ };
+ cooling-maps {
+ map0 {
+ trip = <&cpu4_alert>;
+ cooling-device = <&CPU4 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
+ };
+ cpu5-thermal {
+ polling-delay-passive = <250>;
+ polling-delay = <1000>;
+ thermal-sensors = <&tsens0 5>;
+ trips {
+ cpu5_alert: trip-point0 {
+ temperature = <80000>;
+ hysteresis = <2000>;
+ type = "passive";
+ };
+ cpu5_crit: crit {
+ temperature = <100000>;
+ hysteresis = <2000>;
+ type = "critical";
+ };
+ };
+ cooling-maps {
+ map0 {
+ trip = <&cpu5_alert>;
+ cooling-device = <&CPU5 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
+ };
+ cpu6-thermal {
+ polling-delay-passive = <250>;
+ polling-delay = <1000>;
+ thermal-sensors = <&tsens0 6>;
+ trips {
+ cpu6_alert: trip-point0 {
+ temperature = <80000>;
+ hysteresis = <2000>;
+ type = "passive";
+ };
+ cpu6_crit: crit {
+ temperature = <100000>;
+ hysteresis = <2000>;
+ type = "critical";
+ };
+ };
+ cooling-maps {
+ map0 {
+ trip = <&cpu6_alert>;
+ cooling-device = <&CPU6 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
+ };
+ cpu7-thermal {
+ polling-delay-passive = <250>;
+ polling-delay = <1000>;
+ thermal-sensors = <&tsens0 7>;
+ trips {
+ cpu7_alert: trip-point0 {
+ temperature = <80000>;
+ hysteresis = <2000>;
+ type = "passive";
+ };
+ cpu7_crit: crit {
+ temperature = <100000>;
+ hysteresis = <2000>;
+ type = "critical";
+ };
+ };
+ cooling-maps {
+ map0 {
+ trip = <&cpu7_alert>;
+ cooling-device = <&CPU7 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
+ };
+ };
+
+ timer {
+ compatible = "arm,armv8-timer";
+ interrupts = <GIC_PPI 2 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>,
+ <GIC_PPI 3 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>,
+ <GIC_PPI 4 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>,
+ <GIC_PPI 1 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>;
+ };
+};
diff --git a/arch/arm64/boot/dts/qcom/msm8992-lg-bullhead-rev-10.dts b/arch/arm64/boot/dts/qcom/msm8992-lg-bullhead-rev-10.dts
new file mode 100644
index 000000000000..7e6bce4af441
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/msm8992-lg-bullhead-rev-10.dts
@@ -0,0 +1,14 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/* Copyright (c) Jean Thomas <virgule@jeanthomas.me>
+ */
+
+/dts-v1/;
+
+#include "msm8992-lg-bullhead.dtsi"
+
+/ {
+ model = "LG Nexus 5X rev 1.0";
+
+ /* required for bootloader to select correct board */
+ qcom,board-id = <0xa64 0>;
+};
diff --git a/arch/arm64/boot/dts/qcom/msm8992-lg-bullhead-rev-101.dts b/arch/arm64/boot/dts/qcom/msm8992-lg-bullhead-rev-101.dts
new file mode 100644
index 000000000000..e6a5ebd30e2f
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/msm8992-lg-bullhead-rev-101.dts
@@ -0,0 +1,14 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/* Copyright (c) Jean Thomas <virgule@jeanthomas.me>
+ */
+
+/dts-v1/;
+
+#include "msm8992-lg-bullhead.dtsi"
+
+/ {
+ model = "LG Nexus 5X rev 1.01";
+
+ /* required for bootloader to select correct board */
+ qcom,board-id = <0xb64 0>;
+};
diff --git a/arch/arm64/boot/dts/qcom/msm8992-bullhead-rev-101.dts b/arch/arm64/boot/dts/qcom/msm8992-lg-bullhead.dtsi
index 4da6c44bf532..3b0cc85d6674 100644
--- a/arch/arm64/boot/dts/qcom/msm8992-bullhead-rev-101.dts
+++ b/arch/arm64/boot/dts/qcom/msm8992-lg-bullhead.dtsi
@@ -18,9 +18,7 @@
compatible = "lg,bullhead", "qcom,msm8992";
chassis-type = "handset";
- /* required for bootloader to select correct board */
qcom,msm-id = <251 0>, <252 0>;
- qcom,board-id = <0xb64 0>;
qcom,pmic-id = <0x10009 0x1000A 0x0 0x0>;
/* Bullhead firmware doesn't support PSCI */
diff --git a/arch/arm64/boot/dts/qcom/msm8994-angler-rev-101.dts b/arch/arm64/boot/dts/qcom/msm8994-huawei-angler-rev-101.dts
index 0e3dd48f0dbf..0e3dd48f0dbf 100644
--- a/arch/arm64/boot/dts/qcom/msm8994-angler-rev-101.dts
+++ b/arch/arm64/boot/dts/qcom/msm8994-huawei-angler-rev-101.dts
diff --git a/arch/arm64/boot/dts/qcom/msm8994.dtsi b/arch/arm64/boot/dts/qcom/msm8994.dtsi
index 5a9a5ed0565f..8c1dc5155b71 100644
--- a/arch/arm64/boot/dts/qcom/msm8994.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8994.dtsi
@@ -444,7 +444,7 @@
};
sdhc1: sdhci@f9824900 {
- compatible = "qcom,sdhci-msm-v4";
+ compatible = "qcom,msm8994-sdhci", "qcom,sdhci-msm-v4";
reg = <0xf9824900 0x1a0>, <0xf9824000 0x800>;
reg-names = "hc_mem", "core_mem";
@@ -467,7 +467,7 @@
};
sdhc2: sdhci@f98a4900 {
- compatible = "qcom,sdhci-msm-v4";
+ compatible = "qcom,msm8994-sdhci", "qcom,sdhci-msm-v4";
reg = <0xf98a4900 0x11c>, <0xf98a4000 0x800>;
reg-names = "hc_mem", "core_mem";
@@ -713,6 +713,9 @@
#reset-cells = <1>;
#power-domain-cells = <1>;
reg = <0xfc400000 0x2000>;
+
+ clock-names = "xo", "sleep_clk";
+ clocks = <&xo_board>, <&sleep_clk>;
};
rpm_msg_ram: sram@fc428000 {
diff --git a/arch/arm64/boot/dts/qcom/msm8996-mtp.dts b/arch/arm64/boot/dts/qcom/msm8996-mtp.dts
index 7d9fc35bc7a0..6a1699a96c99 100644
--- a/arch/arm64/boot/dts/qcom/msm8996-mtp.dts
+++ b/arch/arm64/boot/dts/qcom/msm8996-mtp.dts
@@ -9,7 +9,7 @@
/ {
model = "Qualcomm Technologies, Inc. MSM 8996 MTP";
- compatible = "qcom,msm8996-mtp";
+ compatible = "qcom,msm8996-mtp", "qcom,msm8996";
aliases {
serial0 = &blsp2_uart2;
diff --git a/arch/arm64/boot/dts/qcom/msm8996.dtsi b/arch/arm64/boot/dts/qcom/msm8996.dtsi
index 91bc974aeb0a..f0f81c23c16f 100644
--- a/arch/arm64/boot/dts/qcom/msm8996.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8996.dtsi
@@ -134,7 +134,7 @@
};
};
- cluster0_opp: opp_table0 {
+ cluster0_opp: opp-table-cluster0 {
compatible = "operating-points-v2-kryo-cpu";
nvmem-cells = <&speedbin_efuse>;
opp-shared;
@@ -222,7 +222,7 @@
};
};
- cluster1_opp: opp_table1 {
+ cluster1_opp: opp-table-cluster1 {
compatible = "operating-points-v2-kryo-cpu";
nvmem-cells = <&speedbin_efuse>;
opp-shared;
@@ -679,8 +679,10 @@
#power-domain-cells = <1>;
reg = <0x00300000 0x90000>;
- clocks = <&rpmcc RPM_SMD_LN_BB_CLK>;
- clock-names = "cxo2";
+ clocks = <&rpmcc RPM_SMD_BB_CLK1>,
+ <&rpmcc RPM_SMD_LN_BB_CLK>,
+ <&sleep_clk>;
+ clock-names = "cxo", "cxo2", "sleep_clk";
};
tsens0: thermal-sensor@4a9000 {
@@ -713,7 +715,7 @@
clock-names = "bam_clk";
#dma-cells = <1>;
qcom,ee = <0>;
- qcom,controlled-remotely = <1>;
+ qcom,controlled-remotely;
};
crypto: crypto@67a000 {
@@ -887,7 +889,7 @@
#clock-cells = <1>;
#phy-cells = <0>;
- clocks = <&mmcc MDSS_AHB_CLK>, <&xo_board>;
+ clocks = <&mmcc MDSS_AHB_CLK>, <&rpmcc RPM_SMD_BB_CLK1>;
clock-names = "iface", "ref";
status = "disabled";
};
@@ -1546,7 +1548,7 @@
reg = <0x00290000 0x10000>;
};
- spmi_bus: qcom,spmi@400f000 {
+ spmi_bus: spmi@400f000 {
compatible = "qcom,spmi-pmic-arb";
reg = <0x0400f000 0x1000>,
<0x04400000 0x800000>,
@@ -2593,7 +2595,7 @@
reg = <0x06400000 0x90000>;
clock-names = "xo";
- clocks = <&xo_board>;
+ clocks = <&rpmcc RPM_SMD_BB_CLK1>;
#clock-cells = <1>;
};
@@ -2693,7 +2695,7 @@
};
sdhc1: sdhci@7464900 {
- compatible = "qcom,sdhci-msm-v4";
+ compatible = "qcom,msm8996-sdhci", "qcom,sdhci-msm-v4";
reg = <0x07464900 0x11c>, <0x07464000 0x800>;
reg-names = "hc_mem", "core_mem";
@@ -2704,7 +2706,7 @@
clock-names = "iface", "core", "xo";
clocks = <&gcc GCC_SDCC1_AHB_CLK>,
<&gcc GCC_SDCC1_APPS_CLK>,
- <&xo_board>;
+ <&rpmcc RPM_SMD_BB_CLK1>;
pinctrl-names = "default", "sleep";
pinctrl-0 = <&sdc1_state_on>;
@@ -2716,7 +2718,7 @@
};
sdhc2: sdhci@74a4900 {
- compatible = "qcom,sdhci-msm-v4";
+ compatible = "qcom,msm8996-sdhci", "qcom,sdhci-msm-v4";
reg = <0x074a4900 0x314>, <0x074a4000 0x800>;
reg-names = "hc_mem", "core_mem";
@@ -2727,7 +2729,7 @@
clock-names = "iface", "core", "xo";
clocks = <&gcc GCC_SDCC2_AHB_CLK>,
<&gcc GCC_SDCC2_APPS_CLK>,
- <&xo_board>;
+ <&rpmcc RPM_SMD_BB_CLK1>;
pinctrl-names = "default", "sleep";
pinctrl-0 = <&sdc2_state_on>;
@@ -3028,7 +3030,7 @@
interrupt-names = "wdog", "fatal", "ready",
"handover", "stop-ack";
- clocks = <&xo_board>;
+ clocks = <&rpmcc RPM_SMD_BB_CLK1>;
clock-names = "xo";
memory-region = <&adsp_region>;
@@ -3054,7 +3056,7 @@
power-domains = <&gcc HLOS1_VOTE_LPASS_ADSP_GDSC>;
compatible = "qcom,apr-v2";
qcom,smd-channels = "apr_audio_svc";
- qcom,apr-domain = <APR_DOMAIN_ADSP>;
+ qcom,domain = <APR_DOMAIN_ADSP>;
#address-cells = <1>;
#size-cells = <0>;
@@ -3273,7 +3275,7 @@
};
};
- gpu-thermal-top {
+ gpu-top-thermal {
polling-delay-passive = <250>;
polling-delay = <1000>;
@@ -3295,7 +3297,7 @@
};
};
- gpu-thermal-bottom {
+ gpu-bottom-thermal {
polling-delay-passive = <250>;
polling-delay = <1000>;
diff --git a/arch/arm64/boot/dts/qcom/msm8998.dtsi b/arch/arm64/boot/dts/qcom/msm8998.dtsi
index f273bc1ff629..2fda21e810c9 100644
--- a/arch/arm64/boot/dts/qcom/msm8998.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8998.dtsi
@@ -138,15 +138,9 @@
cpu-idle-states = <&LITTLE_CPU_SLEEP_0 &LITTLE_CPU_SLEEP_1>;
next-level-cache = <&L2_0>;
L2_0: l2-cache {
- compatible = "arm,arch-cache";
+ compatible = "cache";
cache-level = <2>;
};
- L1_I_0: l1-icache {
- compatible = "arm,arch-cache";
- };
- L1_D_0: l1-dcache {
- compatible = "arm,arch-cache";
- };
};
CPU1: cpu@1 {
@@ -157,12 +151,6 @@
capacity-dmips-mhz = <1024>;
cpu-idle-states = <&LITTLE_CPU_SLEEP_0 &LITTLE_CPU_SLEEP_1>;
next-level-cache = <&L2_0>;
- L1_I_1: l1-icache {
- compatible = "arm,arch-cache";
- };
- L1_D_1: l1-dcache {
- compatible = "arm,arch-cache";
- };
};
CPU2: cpu@2 {
@@ -173,12 +161,6 @@
capacity-dmips-mhz = <1024>;
cpu-idle-states = <&LITTLE_CPU_SLEEP_0 &LITTLE_CPU_SLEEP_1>;
next-level-cache = <&L2_0>;
- L1_I_2: l1-icache {
- compatible = "arm,arch-cache";
- };
- L1_D_2: l1-dcache {
- compatible = "arm,arch-cache";
- };
};
CPU3: cpu@3 {
@@ -189,12 +171,6 @@
capacity-dmips-mhz = <1024>;
cpu-idle-states = <&LITTLE_CPU_SLEEP_0 &LITTLE_CPU_SLEEP_1>;
next-level-cache = <&L2_0>;
- L1_I_3: l1-icache {
- compatible = "arm,arch-cache";
- };
- L1_D_3: l1-dcache {
- compatible = "arm,arch-cache";
- };
};
CPU4: cpu@100 {
@@ -206,15 +182,9 @@
cpu-idle-states = <&BIG_CPU_SLEEP_0 &BIG_CPU_SLEEP_1>;
next-level-cache = <&L2_1>;
L2_1: l2-cache {
- compatible = "arm,arch-cache";
+ compatible = "cache";
cache-level = <2>;
};
- L1_I_100: l1-icache {
- compatible = "arm,arch-cache";
- };
- L1_D_100: l1-dcache {
- compatible = "arm,arch-cache";
- };
};
CPU5: cpu@101 {
@@ -225,12 +195,6 @@
capacity-dmips-mhz = <1536>;
cpu-idle-states = <&BIG_CPU_SLEEP_0 &BIG_CPU_SLEEP_1>;
next-level-cache = <&L2_1>;
- L1_I_101: l1-icache {
- compatible = "arm,arch-cache";
- };
- L1_D_101: l1-dcache {
- compatible = "arm,arch-cache";
- };
};
CPU6: cpu@102 {
@@ -241,12 +205,6 @@
capacity-dmips-mhz = <1536>;
cpu-idle-states = <&BIG_CPU_SLEEP_0 &BIG_CPU_SLEEP_1>;
next-level-cache = <&L2_1>;
- L1_I_102: l1-icache {
- compatible = "arm,arch-cache";
- };
- L1_D_102: l1-dcache {
- compatible = "arm,arch-cache";
- };
};
CPU7: cpu@103 {
@@ -257,12 +215,6 @@
capacity-dmips-mhz = <1536>;
cpu-idle-states = <&BIG_CPU_SLEEP_0 &BIG_CPU_SLEEP_1>;
next-level-cache = <&L2_1>;
- L1_I_103: l1-icache {
- compatible = "arm,arch-cache";
- };
- L1_D_103: l1-dcache {
- compatible = "arm,arch-cache";
- };
};
cpu-map {
@@ -674,7 +626,7 @@
};
};
- gpu-thermal-bottom {
+ gpu-bottom-thermal {
polling-delay-passive = <250>;
polling-delay = <1000>;
@@ -689,7 +641,7 @@
};
};
- gpu-thermal-top {
+ gpu-top-thermal {
polling-delay-passive = <250>;
polling-delay = <1000>;
diff --git a/arch/arm64/boot/dts/qcom/pm6150l.dtsi b/arch/arm64/boot/dts/qcom/pm6150l.dtsi
index 3ca2860bb0cf..7aa2ef90cb6a 100644
--- a/arch/arm64/boot/dts/qcom/pm6150l.dtsi
+++ b/arch/arm64/boot/dts/qcom/pm6150l.dtsi
@@ -52,5 +52,15 @@
reg = <0x5 SPMI_USID>;
#address-cells = <1>;
#size-cells = <0>;
+
+ pm6150l_wled: leds@d800 {
+ compatible = "qcom,pm6150l-wled";
+ reg = <0xd800>, <0xd900>;
+ interrupts = <0x5 0xd8 0x1 IRQ_TYPE_EDGE_RISING>;
+ interrupt-names = "ovp";
+ label = "backlight";
+
+ status = "disabled";
+ };
};
};
diff --git a/arch/arm64/boot/dts/qcom/pm8953.dtsi b/arch/arm64/boot/dts/qcom/pm8953.dtsi
new file mode 100644
index 000000000000..741c538a9cee
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/pm8953.dtsi
@@ -0,0 +1,90 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/* Copyright (c) 2022, The Linux Foundation. All rights reserved. */
+
+#include <dt-bindings/iio/qcom,spmi-vadc.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/input/linux-event-codes.h>
+#include <dt-bindings/spmi/spmi.h>
+
+&spmi_bus {
+ pmic@0 {
+ compatible = "qcom,pm8953", "qcom,spmi-pmic";
+ reg = <0 SPMI_USID>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pm8953_pon: pon@800 {
+ compatible = "qcom,pm8916-pon";
+ reg = <0x800>;
+ mode-bootloader = <0x2>;
+ mode-recovery = <0x1>;
+
+ pwrkey {
+ compatible = "qcom,pm8941-pwrkey";
+ interrupts = <0x00 0x08 0 IRQ_TYPE_EDGE_BOTH>;
+ debounce = <15625>;
+ bias-pull-up;
+ linux,code = <KEY_POWER>;
+ };
+
+ pm8953_resin: resin {
+ compatible = "qcom,pm8941-resin";
+ interrupts = <0x00 0x08 1 IRQ_TYPE_EDGE_BOTH>;
+ debounce = <15625>;
+ bias-pull-up;
+ status = "disabled";
+ };
+ };
+
+ temp-alarm@2400 {
+ compatible = "qcom,spmi-temp-alarm";
+ reg = <0x2400>;
+ interrupts = <0x0 0x24 0x0 IRQ_TYPE_EDGE_RISING>;
+ io-channels = <&pm8953_vadc VADC_DIE_TEMP>;
+ io-channel-names = "thermal";
+ #thermal-sensor-cells = <0>;
+ };
+
+ pm8953_vadc: vadc@3100 {
+ compatible = "qcom,spmi-vadc";
+ reg = <0x3100>;
+ interrupts = <0x00 0x31 0x00 0x01>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ #io-channel-cells = <1>;
+
+ adc-chan@8 {
+ reg = <VADC_DIE_TEMP>;
+ };
+ adc-chan@9 {
+ reg = <VADC_REF_625MV>;
+ };
+ adc-chan@a {
+ reg = <VADC_REF_1250MV>;
+ };
+ adc-chan@c {
+ reg = <VADC_SPARE1>;
+ };
+ adc-chan@e {
+ reg = <VADC_GND_REF>;
+ };
+ adc-chan@f {
+ reg = <VADC_VDD_VADC>;
+ };
+ };
+
+ rtc@6000 {
+ compatible = "qcom,pm8941-rtc";
+ reg = <0x6000>, <0x6100>;
+ reg-names = "rtc", "alarm";
+ interrupts = <0x0 0x61 0x1 IRQ_TYPE_EDGE_RISING>;
+ };
+ };
+
+ pmic@1 {
+ compatible = "qcom,pm8953", "qcom,spmi-pmic";
+ reg = <1 SPMI_USID>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+};
diff --git a/arch/arm64/boot/dts/qcom/pms405.dtsi b/arch/arm64/boot/dts/qcom/pms405.dtsi
index 172be177fc8f..98d173a377d5 100644
--- a/arch/arm64/boot/dts/qcom/pms405.dtsi
+++ b/arch/arm64/boot/dts/qcom/pms405.dtsi
@@ -32,7 +32,7 @@
&spmi_bus {
pms405_0: pms405@0 {
- compatible = "qcom,spmi-pmic";
+ compatible = "qcom,pms405", "qcom,spmi-pmic";
reg = <0x0 SPMI_USID>;
#address-cells = <1>;
#size-cells = <0>;
@@ -139,7 +139,7 @@
};
pms405_1: pms405@1 {
- compatible = "qcom,spmi-pmic";
+ compatible = "qcom,pms405", "qcom,spmi-pmic";
reg = <0x1 SPMI_USID>;
pms405_spmi_regulators: regulators {
diff --git a/arch/arm64/boot/dts/qcom/qcs404.dtsi b/arch/arm64/boot/dts/qcom/qcs404.dtsi
index 6db753b49326..3f06f7cd3cf2 100644
--- a/arch/arm64/boot/dts/qcom/qcs404.dtsi
+++ b/arch/arm64/boot/dts/qcom/qcs404.dtsi
@@ -110,7 +110,7 @@
};
};
- cpu_opp_table: cpu-opp-table {
+ cpu_opp_table: opp-table-cpu {
compatible = "operating-points-v2-kryo-cpu";
opp-shared;
@@ -128,7 +128,7 @@
};
};
- cpr_opp_table: cpr-opp-table {
+ cpr_opp_table: opp-table-cpr {
compatible = "operating-points-v2-qcom-level";
cpr_opp1: opp1 {
diff --git a/arch/arm64/boot/dts/qcom/sc7180-trogdor-coachz.dtsi b/arch/arm64/boot/dts/qcom/sc7180-trogdor-coachz.dtsi
index 14ed09f30a73..c81805ef2250 100644
--- a/arch/arm64/boot/dts/qcom/sc7180-trogdor-coachz.dtsi
+++ b/arch/arm64/boot/dts/qcom/sc7180-trogdor-coachz.dtsi
@@ -142,6 +142,22 @@ ap_ts_pen_1v8: &i2c4 {
};
};
+&pp1800_uf_cam {
+ status = "okay";
+};
+
+&pp1800_wf_cam {
+ status = "okay";
+};
+
+&pp2800_uf_cam {
+ status = "okay";
+};
+
+&pp2800_wf_cam {
+ status = "okay";
+};
+
&pp3300_dx_edp {
gpio = <&tlmm 67 GPIO_ACTIVE_HIGH>;
};
diff --git a/arch/arm64/boot/dts/qcom/sc7180-trogdor-homestar.dtsi b/arch/arm64/boot/dts/qcom/sc7180-trogdor-homestar.dtsi
index f32369af1351..bff2b556cc75 100644
--- a/arch/arm64/boot/dts/qcom/sc7180-trogdor-homestar.dtsi
+++ b/arch/arm64/boot/dts/qcom/sc7180-trogdor-homestar.dtsi
@@ -146,6 +146,22 @@ ap_ts_pen_1v8: &i2c4 {
};
};
+&pp1800_uf_cam {
+ status = "okay";
+};
+
+&pp1800_wf_cam {
+ status = "okay";
+};
+
+&pp2800_uf_cam {
+ status = "okay";
+};
+
+&pp2800_wf_cam {
+ status = "okay";
+};
+
&pp3300_dx_edp {
gpio = <&tlmm 67 GPIO_ACTIVE_HIGH>;
};
diff --git a/arch/arm64/boot/dts/qcom/sc7180-trogdor.dtsi b/arch/arm64/boot/dts/qcom/sc7180-trogdor.dtsi
index bd5909ffb3dc..732e1181af48 100644
--- a/arch/arm64/boot/dts/qcom/sc7180-trogdor.dtsi
+++ b/arch/arm64/boot/dts/qcom/sc7180-trogdor.dtsi
@@ -144,6 +144,100 @@
vin-supply = <&ppvar_sys>;
};
+ pp1800_ec:
+ pp1800_sensors:
+ pp1800_ldo: pp1800-ldo-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "pp1800_ldo";
+
+ /* EC turns on with hibernate_l; always on for AP */
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+
+ /*
+ * Actually should be pp1800_h1 but we don't have any need to
+ * model that so we use the parent of pp1800_h1.
+ */
+ vin-supply = <&pp3300_a>;
+ };
+
+ pp1800_uf_cam: pp1800-uf-cam-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "pp1800_uf_cam";
+ status = "disabled";
+
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+
+ gpio = <&tlmm 6 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ pinctrl-names = "default";
+ pinctrl-0 = <&uf_cam_en>;
+
+ vin-supply = <&pp1800_ldo>;
+ regulator-enable-ramp-delay = <1000>;
+ };
+
+ pp1800_wf_cam: pp1800-wf-cam-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "pp1800_wf_cam";
+ status = "disabled";
+
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+
+ gpio = <&tlmm 7 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ pinctrl-names = "default";
+ pinctrl-0 = <&wf_cam_en>;
+
+ vin-supply = <&pp1800_ldo>;
+ regulator-enable-ramp-delay = <1000>;
+ };
+
+ pp2800_uf_cam: pp2800-uf-cam-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "pp2800_uf_cam";
+ status = "disabled";
+
+ regulator-min-microvolt = <2850000>;
+ regulator-max-microvolt = <2850000>;
+
+ gpio = <&tlmm 6 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ /*
+ * The pinconf can only be referenced once so we put it on the
+ * first regulator and comment it out here.
+ * pinctrl-names = "default";
+ * pinctrl-0 = <&uf_cam_en>;
+ */
+
+ vin-supply = <&pp3300_a>;
+ };
+
+ pp2800_vcm_wf_cam:
+ pp2800_wf_cam: pp2800-wf-cam-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "pp2800_wf_cam";
+ status = "disabled";
+
+ regulator-min-microvolt = <2850000>;
+ regulator-max-microvolt = <2850000>;
+
+ gpio = <&tlmm 7 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ /*
+ * The pinconf can only be referenced once so we put it on the
+ * first regulator and comment it out here.
+ * pinctrl-names = "default";
+ * pinctrl-0 = <&wf_cam_en>;
+ */
+
+ vin-supply = <&pp3300_a>;
+ };
+
pp3300_audio:
pp3300_codec: pp3300-codec-regulator {
compatible = "regulator-fixed";
@@ -190,7 +284,7 @@
vin-supply = <&pp3300_a>;
};
- pp3300_hub: pp3300-hub {
+ pp3300_hub: pp3300-hub-regulator {
compatible = "regulator-fixed";
regulator-name = "pp3300_hub";
@@ -543,7 +637,7 @@
pinctrl-0 = <&ap_ec_int_l>;
spi-max-frequency = <3000000>;
- cros_ec_pwm: ec-pwm {
+ cros_ec_pwm: pwm {
compatible = "google,cros-ec-pwm";
#pwm-cells = <1>;
};
@@ -1521,4 +1615,32 @@ ap_spi_fp: &spi10 {
drive-strength = <2>;
};
};
+
+ uf_cam_en: uf-cam-en {
+ pinmux {
+ pins = "gpio6";
+ function = "gpio";
+ };
+
+ pinconf {
+ pins = "gpio6";
+ drive-strength = <2>;
+ /* External pull down */
+ bias-disable;
+ };
+ };
+
+ wf_cam_en: wf-cam-en {
+ pinmux {
+ pins = "gpio7";
+ function = "gpio";
+ };
+
+ pinconf {
+ pins = "gpio7";
+ drive-strength = <2>;
+ /* External pull down */
+ bias-disable;
+ };
+ };
};
diff --git a/arch/arm64/boot/dts/qcom/sc7180.dtsi b/arch/arm64/boot/dts/qcom/sc7180.dtsi
index 2151cd8c8c7a..e1c46b80f14a 100644
--- a/arch/arm64/boot/dts/qcom/sc7180.dtsi
+++ b/arch/arm64/boot/dts/qcom/sc7180.dtsi
@@ -1459,6 +1459,8 @@
"imem",
"config";
+ qcom,qmp = <&aoss_qmp>;
+
qcom,smem-states = <&ipa_smp2p_out 0>,
<&ipa_smp2p_out 1>;
qcom,smem-state-names = "ipa-clock-enabled-valid",
diff --git a/arch/arm64/boot/dts/qcom/sc7280-chrome-common.dtsi b/arch/arm64/boot/dts/qcom/sc7280-chrome-common.dtsi
new file mode 100644
index 000000000000..9f4a9c263c35
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sc7280-chrome-common.dtsi
@@ -0,0 +1,97 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * sc7280 fragment for devices with Chrome bootloader
+ *
+ * This file mainly tries to abstract out the memory protections put into
+ * place by the Chrome bootloader which are different than what's put into
+ * place by Qualcomm's typical bootloader. It also has a smattering of other
+ * things that will hold true for any conceivable Chrome design
+ *
+ * Copyright 2022 Google LLC.
+ */
+
+/*
+ * Reserved memory changes
+ *
+ * Delete all unused memory nodes and define the peripheral memory regions
+ * required by the setup for Chrome boards.
+ */
+
+/delete-node/ &hyp_mem;
+/delete-node/ &xbl_mem;
+/delete-node/ &reserved_xbl_uefi_log;
+/delete-node/ &sec_apps_mem;
+
+/ {
+ reserved-memory {
+ adsp_mem: memory@86700000 {
+ reg = <0x0 0x86700000 0x0 0x2800000>;
+ no-map;
+ };
+
+ camera_mem: memory@8ad00000 {
+ reg = <0x0 0x8ad00000 0x0 0x500000>;
+ no-map;
+ };
+
+ venus_mem: memory@8b200000 {
+ reg = <0x0 0x8b200000 0x0 0x500000>;
+ no-map;
+ };
+
+ mpss_mem: memory@8b800000 {
+ reg = <0x0 0x8b800000 0x0 0xf600000>;
+ no-map;
+ };
+
+ wpss_mem: memory@9ae00000 {
+ reg = <0x0 0x9ae00000 0x0 0x1900000>;
+ no-map;
+ };
+
+ mba_mem: memory@9c700000 {
+ reg = <0x0 0x9c700000 0x0 0x200000>;
+ no-map;
+ };
+ };
+};
+
+/* The PMIC PON code isn't compatible w/ how Chrome EC/BIOS handle things. */
+&pmk8350_pon {
+ status = "disabled";
+};
+
+/*
+ * Chrome designs always boot from SPI flash hooked up to the qspi.
+ *
+ * It's expected that all boards will support "dual SPI" at 37.5 MHz.
+ * If some boards need a different speed or have a package that allows
+ * Quad SPI together with WP then those boards can easily override.
+ */
+&qspi {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&qspi_clk>, <&qspi_cs0>, <&qspi_data01>;
+
+ spi_flash: flash@0 {
+ compatible = "jedec,spi-nor";
+ reg = <0>;
+
+ spi-max-frequency = <37500000>;
+ spi-tx-bus-width = <2>;
+ spi-rx-bus-width = <2>;
+ };
+};
+
+/* Modem setup is different on Chrome setups than typical Qualcomm setup */
+&remoteproc_mpss {
+ status = "okay";
+ compatible = "qcom,sc7280-mss-pil";
+ iommus = <&apps_smmu 0x124 0x0>, <&apps_smmu 0x488 0x7>;
+ memory-region = <&mba_mem>, <&mpss_mem>;
+};
+
+/* Increase the size from 2.5MB to 8MB */
+&rmtfs_mem {
+ reg = <0x0 0x9c900000 0x0 0x800000>;
+};
diff --git a/arch/arm64/boot/dts/qcom/sc7280-crd.dts b/arch/arm64/boot/dts/qcom/sc7280-crd.dts
index cd2755ce530d..e2efbdde53a3 100644
--- a/arch/arm64/boot/dts/qcom/sc7280-crd.dts
+++ b/arch/arm64/boot/dts/qcom/sc7280-crd.dts
@@ -23,6 +23,18 @@
};
};
+&apps_rsc {
+ pmg1110-regulators {
+ compatible = "qcom,pmg1110-rpmh-regulators";
+ qcom,pmic-id = "k";
+
+ vreg_s1k_1p0: smps1 {
+ regulator-min-microvolt = <1010000>;
+ regulator-max-microvolt = <1170000>;
+ };
+ };
+};
+
ap_tp_i2c: &i2c0 {
status = "okay";
clock-frequency = <400000>;
diff --git a/arch/arm64/boot/dts/qcom/sc7280-herobrine-herobrine-r0.dts b/arch/arm64/boot/dts/qcom/sc7280-herobrine-herobrine-r0.dts
new file mode 100644
index 000000000000..1779d96c30f6
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sc7280-herobrine-herobrine-r0.dts
@@ -0,0 +1,1352 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Google Herobrine board device tree source
+ *
+ * Copyright 2021 Google LLC.
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/iio/qcom,spmi-adc7-pmk8350.h>
+#include <dt-bindings/iio/qcom,spmi-adc7-pmr735a.h>
+#include <dt-bindings/input/gpio-keys.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/pinctrl/qcom,pmic-gpio.h>
+#include <dt-bindings/regulator/qcom,rpmh-regulator.h>
+
+#include "sc7280.dtsi"
+
+/* PMICs depend on spmi_bus label and so must come after SoC */
+#include "pm7325.dtsi"
+#include "pm8350c.dtsi"
+#include "pmk8350.dtsi"
+
+#include "sc7280-chrome-common.dtsi"
+
+/ {
+ model = "Google Herobrine (rev0)";
+ compatible = "google,herobrine-rev0", "qcom,sc7280";
+};
+
+/ {
+ aliases {
+ serial0 = &uart5;
+ serial1 = &uart7;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+
+ /* FIXED REGULATORS - parents above children */
+
+ /* This is the top level supply and variable voltage */
+ ppvar_sys: ppvar-sys-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "ppvar_sys";
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ /* This divides ppvar_sys by 2, so voltage is variable */
+ src_vph_pwr: src-vph-pwr-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "src_vph_pwr";
+
+ /* EC turns on with switchcap_on; always on for AP */
+ regulator-always-on;
+ regulator-boot-on;
+
+ vin-supply = <&ppvar_sys>;
+ };
+
+ pp5000_s3: pp5000-s3-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "pp5000_s3";
+
+ /* EC turns on with en_pp5000_s3; always on for AP */
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+
+ vin-supply = <&ppvar_sys>;
+ };
+
+ pp3300_z1: pp3300-z1-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "pp3300_z1";
+
+ /* EC turns on with en_pp3300_z1; always on for AP */
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+
+ vin-supply = <&ppvar_sys>;
+ };
+
+ pp3300_audio:
+ pp3300_codec: pp3300-codec-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "pp3300_codec";
+
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+
+ gpio = <&tlmm 67 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ pinctrl-names = "default";
+ pinctrl-0 = <&en_pp3300_codec>;
+
+ vin-supply = <&pp3300_z1>;
+ };
+
+ pp3300_cam:
+ pp3300_edp:
+ pp3300_ts: pp3300-edp-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "pp3300_edp";
+
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+
+ gpio = <&tlmm 80 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ pinctrl-names = "default";
+ pinctrl-0 = <&en_pp3300_dx_edp>;
+
+ vin-supply = <&pp3300_z1>;
+ };
+
+ pp3300_fp:
+ pp3300_fp_ls:
+ pp3300_mcu: pp3300-fp-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "pp3300_fp";
+
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+
+ regulator-boot-on;
+ regulator-always-on;
+
+ /*
+ * WARNING: it is intentional that GPIO 42 isn't listed here.
+ * The userspace script for updating the fingerprint firmware
+ * needs to control the FP regulators during a FW update,
+ * hence the signal can't be owned by the kernel regulator.
+ */
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&en_fp_rails>;
+
+ vin-supply = <&pp3300_z1>;
+ };
+
+ pp3300_hub: pp3300-hub-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "pp3300_hub";
+
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+
+ regulator-boot-on;
+ regulator-always-on;
+
+ gpio = <&tlmm 24 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ pinctrl-names = "default";
+ pinctrl-0 = <&en_pp3300_hub>;
+
+ vin-supply = <&pp3300_z1>;
+ };
+
+ pp3300_tp: pp3300-tp-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "pp3300_tp";
+
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+
+ /* AP turns on with PP1800_L18B_S0; always on for AP */
+ regulator-always-on;
+ regulator-boot-on;
+
+ vin-supply = <&pp3300_z1>;
+ };
+
+ pp2850_uf_cam: pp2850-uf-cam-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "pp2850_uf_cam";
+
+ regulator-min-microvolt = <2850000>;
+ regulator-max-microvolt = <2850000>;
+
+ gpio = <&tlmm 6 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ pinctrl-names = "default";
+ pinctrl-0 = <&uf_cam_en>;
+
+ vin-supply = <&pp3300_cam>;
+ };
+
+ pp2850_vcm_wf_cam: pp2850-vcm-wf-cam-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "pp2850_vcm_wf_cam";
+
+ regulator-min-microvolt = <2850000>;
+ regulator-max-microvolt = <2850000>;
+
+ gpio = <&tlmm 7 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ pinctrl-names = "default";
+ pinctrl-0 = <&wf_cam_en>;
+
+ vin-supply = <&pp3300_cam>;
+ };
+
+ pp2850_wf_cam: pp2850-wf-cam-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "pp2850_wf_cam";
+
+ regulator-min-microvolt = <2850000>;
+ regulator-max-microvolt = <2850000>;
+
+ gpio = <&tlmm 7 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ /*
+ * The pinconf can only be referenced once so we put it on the
+ * first regulator and comment it out here.
+ *
+ * pinctrl-names = "default";
+ * pinctrl-0 = <&wf_cam_en>;
+ */
+
+ vin-supply = <&pp3300_cam>;
+ };
+
+ pp1800_fp: pp1800-fp-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "pp1800_fp";
+
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+
+ regulator-boot-on;
+ regulator-always-on;
+
+ /*
+ * WARNING: it is intentional that GPIO 42 isn't listed here.
+ * The userspace script for updating the fingerprint firmware
+ * needs to control the FP regulators during a FW update,
+ * hence the signal can't be owned by the kernel regulator.
+ */
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&en_fp_rails>;
+
+ vin-supply = <&pp1800_l18b_s0>;
+ status = "disabled";
+ };
+
+ pp1800_uf_cam: pp1800-uf-cam-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "pp1800_uf_cam";
+
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+
+ gpio = <&tlmm 6 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ /*
+ * The pinconf can only be referenced once so we put it on the
+ * first regulator and comment it out here.
+ *
+ * pinctrl-names = "default";
+ * pinctrl-0 = <&uf_cam_en>;
+ */
+
+ vin-supply = <&pp1800_l19b>;
+ };
+
+ pp1800_wf_cam: pp1800-wf-cam-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "pp1800_wf_cam";
+
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+
+ gpio = <&tlmm 7 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ /*
+ * The pinconf can only be referenced once so we put it on the
+ * first regulator and comment it out here.
+ *
+ * pinctrl-names = "default";
+ * pinctrl-0 = <&wf_cam_en>;
+ */
+
+ vin-supply = <&pp1800_l19b>;
+ };
+
+ pp1200_wf_cam: pp1200-wf-cam-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "pp1200_wf_cam";
+
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+
+ gpio = <&tlmm 7 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ /*
+ * The pinconf can only be referenced once so we put it on the
+ * first regulator and comment it out here.
+ *
+ * pinctrl-names = "default";
+ * pinctrl-0 = <&wf_cam_en>;
+ */
+
+ vin-supply = <&pp1200_l6b>;
+ };
+
+ /* BOARD-SPECIFIC TOP LEVEL NODES */
+
+ gpio_keys: gpio-keys {
+ compatible = "gpio-keys";
+ status = "disabled";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pen_pdct_l>;
+
+ pen_insert: pen-insert {
+ label = "Pen Insert";
+
+ /* Insert = low, eject = high */
+ gpios = <&tlmm 39 GPIO_ACTIVE_LOW>;
+ linux,code = <SW_PEN_INSERTED>;
+ linux,input-type = <EV_SW>;
+ wakeup-event-action = <EV_ACT_DEASSERTED>;
+ wakeup-source;
+ };
+ };
+
+ pwmleds {
+ compatible = "pwm-leds";
+ status = "disabled";
+ keyboard_backlight: keyboard-backlight {
+ status = "disabled";
+ label = "cros_ec::kbd_backlight";
+ pwms = <&cros_ec_pwm 0>;
+ max-brightness = <1023>;
+ };
+ };
+};
+
+&apps_rsc {
+ pm7325-regulators {
+ compatible = "qcom,pm7325-rpmh-regulators";
+ qcom,pmic-id = "b";
+
+ vdd19_pmu_pcie_i:
+ vdd19_pmu_rfa_i:
+ vreg_s1b_wlan:
+ vreg_s1b: smps1 {
+ regulator-min-microvolt = <1856000>;
+ regulator-max-microvolt = <2040000>;
+ };
+
+ vdd_pmu_aon_i:
+ vreg_s7b_wlan:
+ vreg_s7b: smps7 {
+ regulator-min-microvolt = <535000>;
+ regulator-max-microvolt = <1120000>;
+ };
+
+ vdd13_pmu_pcie_i:
+ vdd13_pmu_rfa_i:
+ vreg_s8b_wlan:
+ vreg_s8b: smps8 {
+ regulator-min-microvolt = <1256000>;
+ regulator-max-microvolt = <1500000>;
+ };
+
+ vdda_usb_ss_dp_core:
+ vreg_l1b: ldo1 {
+ regulator-min-microvolt = <825000>;
+ regulator-max-microvolt = <925000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vdda_usb_hs0_3p1:
+ vreg_l2b: ldo2 {
+ regulator-min-microvolt = <2700000>;
+ regulator-max-microvolt = <3544000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ pp1200_l6b:
+ vdd_ufs_1p2:
+ vdd_vref:
+ vdda_csi01_1p2:
+ vdda_csi23_1p2:
+ vdda_csi4_1p2:
+ vdda_dsi0_1p2:
+ vdda_pcie0_1p2:
+ vdda_pcie1_1p2:
+ vdda_usb_ss_dp_1p2:
+ vdda_qlink0_1p2_ck:
+ vdda_qlink1_1p2_ck:
+ vreg_l6b_1p2:
+ vreg_l6b: ldo6 {
+ regulator-min-microvolt = <1120000>;
+ regulator-max-microvolt = <1408000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ pp2950_l7b:
+ vreg_l7b: ldo7 {
+ regulator-min-microvolt = <2960000>;
+ regulator-max-microvolt = <2960000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ codec_vcc:
+ pp1800_l18b_s0:
+ pp1800_ts:
+ vdd1:
+ vddpx_0:
+ vddpx_3:
+ vddpx_7:
+ vreg_l18b: ldo18 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <2000000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ pp1800_l19b:
+ vddpx_ts:
+ vddpx_wl4otp:
+ vreg_l19b: ldo19 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+ };
+
+ pm8350c-regulators {
+ compatible = "qcom,pm8350c-rpmh-regulators";
+ qcom,pmic-id = "c";
+
+ vreg_s1c: smps1 {
+ regulator-min-microvolt = <2190000>;
+ regulator-max-microvolt = <2210000>;
+ };
+
+ vddpx_1:
+ vreg_s9c: smps9 {
+ regulator-min-microvolt = <1010000>;
+ regulator-max-microvolt = <1170000>;
+ };
+
+ pp1800_l1c:
+ pp1800_pen:
+ vdd_a_gfx_cs_1p1:
+ vdd_a_cxo_1p8:
+ vdd_qfprom:
+ vdda_apc_cs_1p8:
+ vdda_qrefs_1p8:
+ vdda_turing_q6_cs_1p8:
+ vdda_usb_hs0_1p8:
+ vreg_l1c: ldo1 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1980000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ dmic_vdd:
+ pp1800_alc5682:
+ pp1800_l2c:
+ pp1800_vreg_alc5682:
+ vreg_l2c: ldo2 {
+ regulator-min-microvolt = <1620000>;
+ regulator-max-microvolt = <1980000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ pp3300_sar:
+ pp3300_sensor:
+ vreg_l3c: ldo3 {
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <3540000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ ppvar_uim1:
+ vddpx_5:
+ vreg_l4c: ldo4 {
+ regulator-min-microvolt = <1620000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ pp2950_l5c:
+ uim_vcc:
+ vddpx_6:
+ vreg_l5c: ldo5 {
+ regulator-min-microvolt = <1620000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ ppvar_l6c:
+ vddpx_2:
+ vreg_l6c: ldo6 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <2950000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l7c: ldo7 {
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3544000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ pp1800_prox:
+ pp1800_sar:
+ vreg_l8c: ldo8 {
+ regulator-min-microvolt = <1620000>;
+ regulator-max-microvolt = <2000000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ pp2950_l9c:
+ vreg_l9c: ldo9 {
+ regulator-min-microvolt = <2960000>;
+ regulator-max-microvolt = <2960000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vdd_a_gnss_0p9:
+ vdd_ufs_core:
+ vdd_usb_hs0_core:
+ vdd_vref_0p9:
+ vdda_csi01_0p9:
+ vdda_csi23_0p9:
+ vdda_csi4_0p9:
+ vdda_dsi0_pll_0p9:
+ vdda_dsi0_0p9:
+ vdda_pcie0_core:
+ vdda_pcie1_core:
+ vdda_qlink0_0p9:
+ vdda_qlink1_0p9:
+ vdda_qlink0_0p9_ck:
+ vdda_qlink1_0p9_ck:
+ vdda_qrefs_0p875:
+ vreg_l10c_0p8:
+ vreg_l10c: ldo10 {
+ regulator-min-microvolt = <720000>;
+ regulator-max-microvolt = <1050000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ pp2800_l11c:
+ vreg_l11c: ldo11 {
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <3544000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ pp1800_l12c:
+ vreg_l12c: ldo12 {
+ regulator-min-microvolt = <1650000>;
+ regulator-max-microvolt = <2000000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ pp3300_l13c:
+ vreg_l13c: ldo13 {
+ regulator-min-microvolt = <2700000>;
+ regulator-max-microvolt = <3544000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_bob: bob {
+ regulator-min-microvolt = <3008000>;
+ regulator-max-microvolt = <3960000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_AUTO>;
+ };
+ };
+};
+
+ap_tp_i2c: &i2c1 {
+ status = "okay";
+ clock-frequency = <400000>;
+
+ trackpad: trackpad@15 {
+ compatible = "elan,ekth3000";
+ reg = <0x15>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&tp_int_odl>;
+
+ interrupt-parent = <&tlmm>;
+ interrupts = <102 IRQ_TYPE_EDGE_FALLING>;
+
+ vcc-supply = <&pp3300_z1>;
+
+ wakeup-source;
+ };
+};
+
+ap_h1_i2c: &i2c12 {
+ status = "okay";
+ clock-frequency = <400000>;
+
+ tpm@50 {
+ compatible = "google,cr50";
+ reg = <0x50>;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&h1_ap_int_odl>;
+
+ interrupt-parent = <&tlmm>;
+ interrupts = <54 IRQ_TYPE_EDGE_RISING>;
+ };
+};
+
+ap_ts_pen: &i2c13 {
+ status = "okay";
+ clock-frequency = <400000>;
+
+ ap_ts: touchscreen@10 {
+ compatible = "hid-over-i2c";
+ reg = <0x10>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&ts_int_l>, <&ts_reset_l>;
+
+ interrupt-parent = <&tlmm>;
+ interrupts = <81 IRQ_TYPE_LEVEL_LOW>;
+
+ post-power-on-delay-ms = <20>;
+ hid-descr-addr = <0x0001>;
+
+ vdd-supply = <&pp3300_ts>;
+ };
+};
+
+&pm7325_gpios {
+ status = "disabled"; /* No GPIOs are connected */
+};
+
+&pmk8350_gpios {
+ status = "disabled"; /* No GPIOs are connected */
+};
+
+&pmk8350_rtc {
+ status = "disabled";
+};
+
+&pmk8350_vadc {
+ pmk8350_die_temp {
+ reg = <PMK8350_ADC7_DIE_TEMP>;
+ label = "pmk8350_die_temp";
+ qcom,pre-scaling = <1 1>;
+ };
+
+ pmr735a_die_temp {
+ reg = <PMR735A_ADC7_DIE_TEMP>;
+ label = "pmr735a_die_temp";
+ qcom,pre-scaling = <1 1>;
+ };
+};
+
+&qfprom {
+ vcc-supply = <&vdd_qfprom>;
+};
+
+&qupv3_id_0 {
+ status = "okay";
+};
+
+&qupv3_id_1 {
+ status = "okay";
+};
+
+&sdhc_1 {
+ status = "okay";
+
+ vmmc-supply = <&pp2950_l7b>;
+ vqmmc-supply = <&pp1800_l19b>;
+};
+
+&sdhc_2 {
+ status = "okay";
+
+ pinctrl-0 = <&sdc2_clk>, <&sdc2_cmd>, <&sdc2_data>, <&sd_cd>;
+ pinctrl-1 = <&sdc2_clk_sleep>, <&sdc2_cmd_sleep>, <&sdc2_data_sleep>, <&sd_cd>;
+ vmmc-supply = <&pp2950_l9c>;
+ vqmmc-supply = <&ppvar_l6c>;
+
+ cd-gpios = <&tlmm 91 GPIO_ACTIVE_LOW>;
+};
+
+ap_ec_spi: &spi8 {
+ status = "okay";
+
+ pinctrl-0 = <&qup_spi8_data_clk>, <&qup_spi8_cs_gpio_init_high>, <&qup_spi8_cs_gpio>;
+ cs-gpios = <&tlmm 35 GPIO_ACTIVE_LOW>;
+
+ cros_ec: ec@0 {
+ compatible = "google,cros-ec-spi";
+ reg = <0>;
+ interrupt-parent = <&tlmm>;
+ interrupts = <142 IRQ_TYPE_LEVEL_LOW>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&ap_ec_int_l>;
+ spi-max-frequency = <3000000>;
+
+ cros_ec_pwm: pwm {
+ compatible = "google,cros-ec-pwm";
+ #pwm-cells = <1>;
+ };
+
+ i2c_tunnel: i2c-tunnel {
+ compatible = "google,cros-ec-i2c-tunnel";
+ google,remote-bus = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ 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";
+ };
+ };
+ };
+};
+
+#include <arm/cros-ec-keyboard.dtsi>
+#include <arm/cros-ec-sbs.dtsi>
+
+&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
+ >;
+};
+
+&uart5 {
+ compatible = "qcom,geni-debug-uart";
+ status = "okay";
+};
+
+&uart7 {
+ status = "okay";
+};
+
+&usb_1 {
+ status = "okay";
+};
+
+&usb_1_dwc3 {
+ dr_mode = "host";
+};
+
+&usb_1_hsphy {
+ status = "okay";
+
+ vdda-pll-supply = <&vdd_usb_hs0_core>;
+ vdda33-supply = <&vdda_usb_hs0_3p1>;
+ vdda18-supply = <&vdda_usb_hs0_1p8>;
+};
+
+&usb_1_qmpphy {
+ status = "okay";
+
+ vdda-phy-supply = <&vdda_usb_ss_dp_1p2>;
+ vdda-pll-supply = <&vdda_usb_ss_dp_core>;
+};
+
+&usb_2 {
+ status = "okay";
+};
+
+&usb_2_dwc3 {
+ dr_mode = "host";
+};
+
+&usb_2_hsphy {
+ status = "okay";
+
+ vdda-pll-supply = <&vdd_usb_hs0_core>;
+ vdda33-supply = <&vdda_usb_hs0_3p1>;
+ vdda18-supply = <&vdda_usb_hs0_1p8>;
+};
+
+/* PINCTRL - additions to nodes defined in sc7280.dtsi */
+
+&dp_hot_plug_det {
+ bias-disable;
+};
+
+&pcie1_clkreq_n {
+ bias-pull-up;
+ drive-strength = <2>;
+};
+
+&qspi_cs0 {
+ bias-disable;
+};
+
+&qspi_clk {
+ bias-disable;
+};
+
+&qspi_data01 {
+ /* High-Z when no transfers; nice to park the lines */
+ bias-pull-up;
+};
+
+&qup_uart5_rx {
+ drive-strength = <2>;
+ bias-pull-up;
+};
+
+&qup_uart5_tx {
+ drive-strength = <2>;
+ bias-disable;
+};
+
+&qup_uart7_cts {
+ /*
+ * Configure a pull-down on CTS to match the pull of
+ * the Bluetooth module.
+ */
+ bias-pull-down;
+};
+
+&qup_uart7_rts {
+ /* We'll drive RTS, so no pull */
+ drive-strength = <2>;
+ bias-disable;
+};
+
+&qup_uart7_tx {
+ /* We'll drive TX, so no pull */
+ drive-strength = <2>;
+ bias-disable;
+};
+
+&qup_uart7_rx {
+ /*
+ * Configure a pull-up on RX. This is needed to avoid
+ * garbage data when the TX pin of the Bluetooth module is
+ * in tri-state (module powered off or not driving the
+ * signal yet).
+ */
+ bias-pull-up;
+};
+
+&sdc1_clk {
+ bias-disable;
+ drive-strength = <16>;
+};
+
+&sdc1_cmd {
+ bias-pull-up;
+ drive-strength = <10>;
+};
+
+&sdc1_data {
+ bias-pull-up;
+ drive-strength = <10>;
+};
+
+&sdc1_rclk {
+ bias-pull-down;
+};
+
+&sdc2_clk {
+ bias-disable;
+ drive-strength = <16>;
+};
+
+&sdc2_cmd {
+ bias-pull-up;
+ drive-strength = <10>;
+};
+
+&sdc2_data {
+ bias-pull-up;
+ drive-strength = <10>;
+};
+
+/* PINCTRL - board-specific pinctrl */
+
+&pm8350c_gpios {
+ gpio-line-names = "AP_SUSPEND",
+ "",
+ "",
+ "AP_BL_EN",
+ "",
+ "SD_CD_ODL",
+ "",
+ "",
+ "AP_BL_PWM";
+
+ ap_bl_en: ap-bl-en {
+ pins = "gpio4";
+ function = "normal";
+ qcom,drive-strength = <PMIC_GPIO_STRENGTH_LOW>;
+ bias-disable;
+
+ /* Force backlight to be disabled to match state at boot. */
+ output-low;
+ };
+};
+
+&tlmm {
+ gpio-line-names = "HP_I2C_SDA", /* 0 */
+ "HP_I2C_SCL",
+ "SSD_RST_L",
+ "PE_WAKE_ODL",
+ "AP_TP_I2C_SDA",
+ "AP_TP_I2C_SCL",
+ "UF_CAM_EN",
+ "WF_CAM_EN",
+ "AP_SAR_SENSOR_SDA",
+ "AP_SAR_SENSOR_SCL",
+
+ "", /* 10 */
+ "",
+ "AP_SPI_MOSI",
+ "AP_SPI_MISO",
+ "AP_SPI_CLK",
+ "AP_SPI_CS0_L",
+ "",
+ "",
+ "EDP_HPD",
+ "",
+
+ "UF_CAM_RST_L", /* 20 */
+ "WF_CAM_RST_L",
+ "UART_AP_TX_DBG_RX",
+ "UART_DBG_TX_AP_RX",
+ "EN_PP3300_HUB",
+ "",
+ "HOST2WLAN_SOL",
+ "WLAN2HOST_SOL",
+ "BT_UART_CTS",
+ "BT_UART_RTS",
+
+ "BT_UART_TXD", /* 30 */
+ "BT_UART_RXD",
+ "AP_EC_SPI_MISO",
+ "AP_EC_SPI_MOSI",
+ "AP_EC_SPI_CLK",
+ "AP_EC_SPI_CS_L",
+ "",
+ "",
+ "",
+ "PEN_PDCT_L",
+
+ "IO_BRD_ID0", /* 40 */
+ "IO_BRD_ID1",
+ "EN_FP_RAILS",
+ "PEN_IRQ_L",
+ "AP_SPI_FP_MISO",
+ "AP_SPI_FP_MOSI",
+ "AP_SPI_FP_CLK",
+ "AP_SPI_FP_CS_L",
+ "AP_H1_SPI_MISO",
+ "AP_H1_SPI_MOSI",
+
+ "AP_H1_SPI_CLK", /* 50 */
+ "AP_H1_SPI_CS_L",
+ "AP_TS_PEN_I2C_SDA",
+ "AP_TS_PEN_I2C_SCL",
+ "H1_AP_INT_ODL",
+ "",
+ "LCM_RST_1V8_L",
+ "AMP_EN",
+ "",
+ "DP_HOT_PLUG_DET",
+
+ "HUB_RST_L", /* 60 */
+ "FP_TO_AP_IRQ_L",
+ "",
+ "",
+ "UF_CAM_MCLK",
+ "WF_CAM_MCLK",
+ "IO_BRD_ID2",
+ "EN_PP3300_CODEC",
+ "EC_IN_RW_ODL",
+ "UF_CAM_SDA",
+
+ "UF_CAM_SCL", /* 70 */
+ "WF_CAM_SDA",
+ "WF_CAM_SCL",
+ "AP_BRD_ID0",
+ "AP_BRD_ID1",
+ "AP_BRD_ID2",
+ "",
+ "FPMCU_BOOT0",
+ "FP_RST_L",
+ "PE_CLKREQ_ODL",
+
+ "EN_EDP_PP3300", /* 80 */
+ "TS_INT_L",
+ "FORCE_USB_BOOT",
+ "WCD_RST_L",
+ "WLAN_EN",
+ "BT_EN",
+ "WLAN_SW_CTRL",
+ "PCIE0_RESET_L",
+ "PCIE0_CLK_REQ_L",
+ "PCIE0_WAKE_L",
+
+ "AS_EN", /* 90 */
+ "SD_CD_ODL",
+ "",
+ /*
+ * AP_FLASH_WP_L is crossystem ABI. Schematics
+ * call it BIOS_FLASH_WP_L.
+ */
+ "AP_FLASH_WP_L",
+ "BT_WLAN_SB_CLK",
+ "BT_WLAN_SB_DATA",
+ "HP_MCLK",
+ "HP_BCLK",
+ "HP_DOUT",
+ "HP_DIN",
+
+ "HP_LRCLK", /* 100 */
+ "HP_IRQ",
+ "TP_INT_ODL",
+ "",
+ "IO_SKU_ID2",
+ "TS_RESET_L",
+ "AMP_BCLK",
+ "AMP_DIN",
+ "AMP_LRCLK",
+ "UIM2_DATA",
+
+ "UIM2_CLK", /* 110 */
+ "UIM2_RST",
+ "UIM2_PRESENT",
+ "UIM1_DATA",
+ "UIM1_CLK",
+ "UIM1_RST",
+ "",
+ "RFFE0_CLK",
+ "RFFE0_DATA/BOOT_CONFIG_0",
+ "RFFE1_CLK",
+
+ "RFFE1_DATA/BOOT_CONFIG_1", /* 120 */
+ "RFFE2_CLK",
+ "RFFE2_DATA/BOOT_CONFIG_2",
+ "RFFE3_CLK",
+ "RFFE3_DATA/BOOT_CONFIG_3",
+ "RFFE4_CLK",
+ "RFFE4_DATA",
+ "WCI2_LTE_COEX_RXD",
+ "WCI2_LTE_COEX_TXD",
+ "IO_SKU_ID0",
+
+ "IO_SKU_ID1", /* 130 */
+ "",
+ "",
+ "QLINK0_REQ",
+ "QLINK0_EN",
+ "QLINK0_WMSS_RESET_L",
+ "QLINK1_REQ",
+ "QLINK1_EN",
+ "QLINK1_WMSS_RESET_L",
+ "FORCED_USB_BOOT_POL",
+
+ "", /* 140 */
+ "P_SENSOR_INT_L",
+ "AP_EC_INT_L",
+ "",
+ "WCD_SWR_TX_CLK",
+ "WCD_SWR_TX_DATA_0",
+ "WCD_SWR_TX_DATA_1",
+ "WCD_SWR_RX_CLK",
+ "WCD_SWR_RX_DATA_0",
+ "WCD_SWR_RX_DATA_1",
+
+ "", /* 150 */
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "WCD_SWR_TX_DATA_2",
+ "",
+
+ "", /* 160 */
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+
+ "", /* 170 */
+ "SENS_UART_TXD",
+ "SENS_UART_RXD",
+ "",
+ "",
+ "";
+
+ /*
+ * pinctrl settings for pins that have no real owners.
+ */
+ pinctrl-names = "default";
+ pinctrl-0 = <&bios_flash_wp_l>;
+
+ amp_en: amp-en {
+ pins = "gpio57";
+ function = "gpio";
+ bias-pull-down;
+ };
+
+ ap_ec_int_l: ap-ec-int-l {
+ pins = "gpio142";
+ input-enable;
+ bias-pull-up;
+ };
+
+ bios_flash_wp_l: bios-flash-wp-l {
+ pins = "gpio93";
+ function = "gpio";
+ input-enable;
+ bias-disable;
+ };
+
+ bt_en: bt-en {
+ pins = "gpio85";
+ function = "gpio";
+ drive-strength = <2>;
+ output-low;
+ bias-pull-down;
+ };
+
+ en_fp_rails: en-fp-rails {
+ pins = "gpio42";
+ drive-strength = <2>;
+ output-high;
+ bias-disable;
+ };
+
+ en_pp3300_codec: en-pp3300-codec {
+ pins = "gpio67";
+ drive-strength = <2>;
+ bias-disable;
+ };
+
+ en_pp3300_dx_edp: en-pp3300-dx-edp {
+ pins = "gpio80";
+ function = "gpio";
+ drive-strength = <2>;
+ /* Has external pulldown */
+ bias-disable;
+ };
+
+ en_pp3300_hub: en-pp3300-hub {
+ pins = "gpio24";
+ function = "gpio";
+ drive-strength = <2>;
+ /* Has external pulldown */
+ bias-disable;
+ };
+
+ fp_to_ap_irq_l: fp-to-ap-irq-l {
+ pins = "gpio61";
+ function = "gpio";
+ input-enable;
+ /* Has external pullup */
+ bias-disable;
+ };
+
+ h1_ap_int_odl: h1-ap-int-odl {
+ pins = "gpio54";
+ function = "gpio";
+ input-enable;
+ bias-pull-up;
+ };
+
+ hp_irq: hp-irq {
+ pins = "gpio101";
+ function = "gpio";
+ bias-pull-up;
+ };
+
+ p_sensor_int_l: p-sensor-int-l {
+ pins = "gpio141";
+ function = "gpio";
+ input-enable;
+ bias-pull-up;
+ };
+
+ pen_irq_l: pen-irq-l {
+ pins = "gpio43";
+ function = "gpio";
+ /* Has external pullup */
+ bias-disable;
+ };
+
+ pen_pdct_l: pen-pdct-l {
+ pins = "gpio39";
+ function = "gpio";
+ /* Has external pullup */
+ bias-disable;
+ };
+
+ qup_spi8_cs_gpio_init_high: qup-spi8-cs-gpio-init-high {
+ pins = "gpio35";
+ output-high;
+ };
+
+ qup_spi11_cs_gpio_init_high: qup-spi11-cs-gpio-init-high {
+ pins = "gpio47";
+ output-high;
+ };
+
+ qup_spi12_cs_gpio_init_high: qup-spi12-cs-gpio-init-high {
+ pins = "gpio51";
+ output-high;
+ };
+
+ qup_uart7_sleep_cts: qup-uart7-sleep-cts {
+ pins = "gpio28";
+ function = "gpio";
+ /*
+ * Configure a pull-down on CTS to match the pull of
+ * the Bluetooth module.
+ */
+ bias-pull-down;
+ };
+
+ qup_uart7_sleep_rts: qup-uart7-sleep-rts {
+ pins = "gpio29";
+ function = "gpio";
+ /*
+ * Configure pull-down on RTS. As RTS is active low
+ * signal, pull it low to indicate the BT SoC that it
+ * can wakeup the system anytime from suspend state by
+ * pulling RX low (by sending wakeup bytes).
+ */
+ bias-pull-down;
+ };
+
+ qup_uart7_sleep_rx: qup-uart7-sleep-rx {
+ pins = "gpio31";
+ function = "gpio";
+ /*
+ * Configure a pull-up on RX. This is needed to avoid
+ * garbage data when the TX pin of the Bluetooth module
+ * is floating which may cause spurious wakeups.
+ */
+ bias-pull-up;
+ };
+
+ qup_uart7_sleep_tx: qup-uart7-sleep-tx {
+ pins = "gpio30";
+ function = "gpio";
+ /*
+ * Configure pull-up on TX when it isn't actively driven
+ * to prevent BT SoC from receiving garbage during sleep.
+ */
+ bias-pull-up;
+ };
+
+ sd_cd: sd-cd {
+ pins = "gpio91";
+ function = "gpio";
+ bias-pull-up;
+ };
+
+ tp_int_odl: tp-int-odl {
+ pins = "gpio102";
+ function = "gpio";
+ /* Has external pullup */
+ bias-disable;
+ };
+
+ ts_int_l: ts-int-l {
+ pins = "gpio81";
+ function = "gpio";
+ /* Has external pullup */
+ bias-pull-up;
+ };
+
+ ts_reset_l: ts-reset-l {
+ pins = "gpio105";
+ function = "gpio";
+ /* Has external pullup */
+ bias-disable;
+ drive-strength = <2>;
+ };
+
+ uf_cam_en: uf-cam-en {
+ pins = "gpio6";
+ function = "gpio";
+ drive-strength = <2>;
+ /* Has external pulldown */
+ bias-disable;
+ };
+
+ wf_cam_en: wf-cam-en {
+ pins = "gpio7";
+ function = "gpio";
+ drive-strength = <2>;
+ /* Has external pulldown */
+ bias-disable;
+ };
+};
diff --git a/arch/arm64/boot/dts/qcom/sc7280-herobrine-herobrine-r1.dts b/arch/arm64/boot/dts/qcom/sc7280-herobrine-herobrine-r1.dts
new file mode 100644
index 000000000000..f95273052da0
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sc7280-herobrine-herobrine-r1.dts
@@ -0,0 +1,313 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Google Herobrine board device tree source
+ *
+ * Copyright 2022 Google LLC.
+ */
+
+/dts-v1/;
+
+#include "sc7280-herobrine.dtsi"
+
+/ {
+ model = "Google Herobrine (rev1+)";
+ compatible = "google,herobrine", "qcom,sc7280";
+};
+
+/* ADDITIONS TO NODES DEFINED IN PARENT DEVICE TREE FILES */
+
+&ap_spi_fp {
+ status = "okay";
+};
+
+/*
+ * Although the trackpad is really part of the herobrine baseboard, we'll
+ * put the actual definition in the board device tree since different boards
+ * might hook up different trackpads (or no i2c trackpad at all in the case
+ * of tablets / detachables).
+ */
+ap_tp_i2c: &i2c0 {
+ status = "okay";
+ clock-frequency = <400000>;
+
+ trackpad: trackpad@15 {
+ compatible = "elan,ekth3000";
+ reg = <0x15>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&tp_int_odl>;
+
+ interrupt-parent = <&tlmm>;
+ interrupts = <7 IRQ_TYPE_EDGE_FALLING>;
+
+ vcc-supply = <&pp3300_z1>;
+
+ wakeup-source;
+ };
+};
+
+/*
+ * The touchscreen connector might come off the Qcard, at least in the case of
+ * eDP. Like the trackpad, we'll put it in the board device tree file since
+ * different boards have different touchscreens.
+ */
+ts_i2c: &i2c13 {
+ status = "okay";
+ clock-frequency = <400000>;
+
+ ap_ts: touchscreen@5c {
+ compatible = "hid-over-i2c";
+ reg = <0x5c>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&ts_int_conn>, <&ts_rst_conn>;
+
+ interrupt-parent = <&tlmm>;
+ interrupts = <55 IRQ_TYPE_LEVEL_LOW>;
+
+ post-power-on-delay-ms = <500>;
+ hid-descr-addr = <0x0000>;
+
+ vdd-supply = <&ts_avdd>;
+ };
+};
+
+/* For nvme */
+&pcie1 {
+ status = "okay";
+};
+
+/* For nvme */
+&pcie1_phy {
+ status = "okay";
+};
+
+/* For eMMC */
+&sdhc_1 {
+ status = "okay";
+};
+
+/* For SD Card */
+&sdhc_2 {
+ status = "okay";
+};
+
+/* PINCTRL - BOARD-SPECIFIC */
+
+/*
+ * Methodology for gpio-line-names:
+ * - If a pin goes to herobrine board and is named it gets that name.
+ * - If a pin goes to herobrine board and is not named, it gets no name.
+ * - If a pin is totally internal to Qcard then it gets Qcard name.
+ * - If a pin is not hooked up on Qcard, it gets no name.
+ */
+
+&pm8350c_gpios {
+ gpio-line-names = "FLASH_STROBE_1", /* 1 */
+ "AP_SUSPEND",
+ "PM8008_1_RST_N",
+ "",
+ "",
+ "",
+ "PMIC_EDP_BL_EN",
+ "PMIC_EDP_BL_PWM",
+ "";
+};
+
+&tlmm {
+ gpio-line-names = "AP_TP_I2C_SDA", /* 0 */
+ "AP_TP_I2C_SCL",
+ "SSD_RST_L",
+ "PE_WAKE_ODL",
+ "AP_SAR_SDA",
+ "AP_SAR_SCL",
+ "PRB_SC_GPIO_6",
+ "TP_INT_ODL",
+ "HP_I2C_SDA",
+ "HP_I2C_SCL",
+
+ "GNSS_L1_EN", /* 10 */
+ "GNSS_L5_EN",
+ "SPI_AP_MOSI",
+ "SPI_AP_MISO",
+ "SPI_AP_CLK",
+ "SPI_AP_CS0_L",
+ /*
+ * AP_FLASH_WP is crossystem ABI. Schematics
+ * call it BIOS_FLASH_WP_OD.
+ */
+ "AP_FLASH_WP",
+ "",
+ "AP_EC_INT_L",
+ "",
+
+ "UF_CAM_RST_L", /* 20 */
+ "WF_CAM_RST_L",
+ "UART_AP_TX_DBG_RX",
+ "UART_DBG_TX_AP_RX",
+ "",
+ "PM8008_IRQ_1",
+ "HOST2WLAN_SOL",
+ "WLAN2HOST_SOL",
+ "MOS_BT_UART_CTS",
+ "MOS_BT_UART_RFR",
+
+ "MOS_BT_UART_TX", /* 30 */
+ "MOS_BT_UART_RX",
+ "PRB_SC_GPIO_32",
+ "HUB_RST_L",
+ "",
+ "",
+ "AP_SPI_FP_MISO",
+ "AP_SPI_FP_MOSI",
+ "AP_SPI_FP_CLK",
+ "AP_SPI_FP_CS_L",
+
+ "AP_EC_SPI_MISO", /* 40 */
+ "AP_EC_SPI_MOSI",
+ "AP_EC_SPI_CLK",
+ "AP_EC_SPI_CS_L",
+ "LCM_RST_L",
+ "EARLY_EUD_N",
+ "",
+ "DP_HOT_PLUG_DET",
+ "IO_BRD_MLB_ID0",
+ "IO_BRD_MLB_ID1",
+
+ "IO_BRD_MLB_ID2", /* 50 */
+ "SSD_EN",
+ "TS_I2C_SDA_CONN",
+ "TS_I2C_CLK_CONN",
+ "TS_RST_CONN",
+ "TS_INT_CONN",
+ "AP_I2C_TPM_SDA",
+ "AP_I2C_TPM_SCL",
+ "PRB_SC_GPIO_58",
+ "PRB_SC_GPIO_59",
+
+ "EDP_HOT_PLUG_DET_N", /* 60 */
+ "FP_TO_AP_IRQ_L",
+ "",
+ "AMP_EN",
+ "CAM0_MCLK_GPIO_64",
+ "CAM1_MCLK_GPIO_65",
+ "WF_CAM_MCLK",
+ "PRB_SC_GPIO_67",
+ "FPMCU_BOOT0",
+ "UF_CAM_SDA",
+
+ "UF_CAM_SCL", /* 70 */
+ "",
+ "",
+ "WF_CAM_SDA",
+ "WF_CAM_SCL",
+ "",
+ "",
+ "EN_FP_RAILS",
+ "FP_RST_L",
+ "PCIE1_CLKREQ_ODL",
+
+ "EN_PP3300_DX_EDP", /* 80 */
+ "SC_GPIO_81",
+ "FORCED_USB_BOOT",
+ "WCD_RESET_N",
+ "MOS_WLAN_EN",
+ "MOS_BT_EN",
+ "MOS_SW_CTRL",
+ "MOS_PCIE0_RST",
+ "MOS_PCIE0_CLKREQ_N",
+ "MOS_PCIE0_WAKE_N",
+
+ "MOS_LAA_AS_EN", /* 90 */
+ "SD_CD_ODL",
+ "",
+ "",
+ "MOS_BT_WLAN_SLIMBUS_CLK",
+ "MOS_BT_WLAN_SLIMBUS_DAT0",
+ "HP_MCLK",
+ "HP_BCLK",
+ "HP_DOUT",
+ "HP_DIN",
+
+ "HP_LRCLK", /* 100 */
+ "HP_IRQ",
+ "",
+ "",
+ "GSC_AP_INT_ODL",
+ "EN_PP3300_CODEC",
+ "AMP_BCLK",
+ "AMP_DIN",
+ "AMP_LRCLK",
+ "UIM1_DATA_GPIO_109",
+
+ "UIM1_CLK_GPIO_110", /* 110 */
+ "UIM1_RESET_GPIO_111",
+ "PRB_SC_GPIO_112",
+ "UIM0_DATA",
+ "UIM0_CLK",
+ "UIM0_RST",
+ "UIM0_PRESENT_ODL",
+ "SDM_RFFE0_CLK",
+ "SDM_RFFE0_DATA",
+ "WF_CAM_EN",
+
+ "FASTBOOT_SEL_0", /* 120 */
+ "SC_GPIO_121",
+ "FASTBOOT_SEL_1",
+ "SC_GPIO_123",
+ "FASTBOOT_SEL_2",
+ "SM_RFFE4_CLK_GRFC_8",
+ "SM_RFFE4_DATA_GRFC_9",
+ "WLAN_COEX_UART1_RX",
+ "WLAN_COEX_UART1_TX",
+ "PRB_SC_GPIO_129",
+
+ "LCM_ID0", /* 130 */
+ "LCM_ID1",
+ "",
+ "SDR_QLINK_REQ",
+ "SDR_QLINK_EN",
+ "QLINK0_WMSS_RESET_N",
+ "SMR526_QLINK1_REQ",
+ "SMR526_QLINK1_EN",
+ "SMR526_QLINK1_WMSS_RESET_N",
+ "PRB_SC_GPIO_139",
+
+ "SAR1_IRQ_ODL", /* 140 */
+ "SAR0_IRQ_ODL",
+ "PRB_SC_GPIO_142",
+ "",
+ "WCD_SWR_TX_CLK",
+ "WCD_SWR_TX_DATA0",
+ "WCD_SWR_TX_DATA1",
+ "WCD_SWR_RX_CLK",
+ "WCD_SWR_RX_DATA0",
+ "WCD_SWR_RX_DATA1",
+
+ "DMIC01_CLK", /* 150 */
+ "DMIC01_DATA",
+ "DMIC23_CLK",
+ "DMIC23_DATA",
+ "",
+ "",
+ "EC_IN_RW_ODL",
+ "HUB_EN",
+ "WCD_SWR_TX_DATA2",
+ "",
+
+ "", /* 160 */
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+
+ "", /* 170 */
+ "MOS_BLE_UART_TX",
+ "MOS_BLE_UART_RX",
+ "",
+ "",
+ "";
+};
diff --git a/arch/arm64/boot/dts/qcom/sc7280-herobrine.dts b/arch/arm64/boot/dts/qcom/sc7280-herobrine.dts
deleted file mode 100644
index 7a92679a688b..000000000000
--- a/arch/arm64/boot/dts/qcom/sc7280-herobrine.dts
+++ /dev/null
@@ -1,14 +0,0 @@
-// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
-/*
- * Google Herobrine board device tree source
- *
- * Copyright 2021 Google LLC.
- */
-
-#include "sc7280-herobrine.dtsi"
-
-/ {
- model = "Google Herobrine";
- compatible = "google,herobrine",
- "qcom,sc7280";
-};
diff --git a/arch/arm64/boot/dts/qcom/sc7280-herobrine.dtsi b/arch/arm64/boot/dts/qcom/sc7280-herobrine.dtsi
index 4619fa9fcacd..dc17f2079695 100644
--- a/arch/arm64/boot/dts/qcom/sc7280-herobrine.dtsi
+++ b/arch/arm64/boot/dts/qcom/sc7280-herobrine.dtsi
@@ -1,87 +1,37 @@
// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
/*
- * Google Herobrine board device tree source
+ * Google Herobrine baseboard device tree source
*
- * Copyright 2021 Google LLC.
+ * The set of things in this file is a bit loosely defined. It's roughly
+ * defined as the set of things that the child boards happen to have in
+ * common. Since all of the child boards started from the same original
+ * design this is hopefully a large set of things but as more derivatives
+ * appear things may "bubble down" out of this file. For things that are
+ * part of the reference design but might not exist on child nodes we will
+ * follow the lead of the SoC dtsi files and leave their status as "disabled".
+ *
+ * Copyright 2022 Google LLC.
*/
-/dts-v1/;
-
-#include <dt-bindings/gpio/gpio.h>
-#include <dt-bindings/iio/qcom,spmi-adc7-pmk8350.h>
-#include <dt-bindings/iio/qcom,spmi-adc7-pmr735a.h>
#include <dt-bindings/input/gpio-keys.h>
#include <dt-bindings/input/input.h>
-#include <dt-bindings/pinctrl/qcom,pmic-gpio.h>
-#include <dt-bindings/regulator/qcom,rpmh-regulator.h>
-
-#include "sc7280.dtsi"
-
-/* PMICs depend on spmi_bus label and so must come after SoC */
-#include "pm7325.dtsi"
-#include "pm8350c.dtsi"
-#include "pmk8350.dtsi"
-
-/*
- * Reserved memory changes
- *
- * Delete all unused memory nodes and define the peripheral memory regions
- * required by the board dts.
- *
- */
-
-/delete-node/ &hyp_mem;
-/delete-node/ &xbl_mem;
-/delete-node/ &sec_apps_mem;
-/* Increase the size from 2MB to 8MB */
-&rmtfs_mem {
- reg = <0x0 0x83600000 0x0 0x800000>;
-};
+#include "sc7280-qcard.dtsi"
+#include "sc7280-chrome-common.dtsi"
/ {
- reserved-memory {
- adsp_mem: memory@86700000 {
- reg = <0x0 0x86700000 0x0 0x2800000>;
- no-map;
- };
-
- camera_mem: memory@8ad00000 {
- reg = <0x0 0x8ad00000 0x0 0x500000>;
- no-map;
- };
-
- venus_mem: memory@8b200000 {
- reg = <0x0 0x8b200000 0x0 0x500000>;
- no-map;
- };
-
- mpss_mem: memory@8b800000 {
- reg = <0x0 0x8b800000 0x0 0xf600000>;
- no-map;
- };
-
- wpss_mem: memory@9ae00000 {
- reg = <0x0 0x9ae00000 0x0 0x1900000>;
- no-map;
- };
-
- mba_mem: memory@9c700000 {
- reg = <0x0 0x9c700000 0x0 0x200000>;
- no-map;
- };
- };
-
- aliases {
- serial0 = &uart5;
- serial1 = &uart7;
- };
-
chosen {
stdout-path = "serial0:115200n8";
};
- /* FIXED REGULATORS - parents above children */
+ /*
+ * FIXED REGULATORS
+ *
+ * Sort order:
+ * 1. parents above children.
+ * 2. higher voltage above lower voltage.
+ * 3. alphabetically by node name.
+ */
/* This is the top level supply and variable voltage */
ppvar_sys: ppvar-sys-regulator {
@@ -103,11 +53,11 @@
vin-supply = <&ppvar_sys>;
};
- pp5000_s3: pp5000-s3-regulator {
+ pp5000_s5: pp5000-s5-regulator {
compatible = "regulator-fixed";
- regulator-name = "pp5000_s3";
+ regulator-name = "pp5000_s5";
- /* EC turns on with en_pp5000_s3; always on for AP */
+ /* EC turns on with en_pp5000_s5; always on for AP */
regulator-always-on;
regulator-boot-on;
regulator-min-microvolt = <5000000>;
@@ -129,7 +79,6 @@
vin-supply = <&ppvar_sys>;
};
- pp3300_audio:
pp3300_codec: pp3300-codec-regulator {
compatible = "regulator-fixed";
regulator-name = "pp3300_codec";
@@ -137,7 +86,7 @@
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
- gpio = <&tlmm 67 GPIO_ACTIVE_HIGH>;
+ gpio = <&tlmm 105 GPIO_ACTIVE_HIGH>;
enable-active-high;
pinctrl-names = "default";
pinctrl-0 = <&en_pp3300_codec>;
@@ -145,11 +94,9 @@
vin-supply = <&pp3300_z1>;
};
- pp3300_cam:
- pp3300_edp:
- pp3300_ts: pp3300-edp-regulator {
+ pp3300_left_in_mlb: pp3300-left-in-mlb-regulator {
compatible = "regulator-fixed";
- regulator-name = "pp3300_edp";
+ regulator-name = "pp3300_left_in_mlb";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
@@ -162,9 +109,9 @@
vin-supply = <&pp3300_z1>;
};
- pp3300_fp:
+ pp3300_mcu_fp:
pp3300_fp_ls:
- pp3300_mcu: pp3300-fp-regulator {
+ pp3300_fp_mcu: pp3300-fp-regulator {
compatible = "regulator-fixed";
regulator-name = "pp3300_fp";
@@ -175,7 +122,7 @@
regulator-always-on;
/*
- * WARNING: it is intentional that GPIO 42 isn't listed here.
+ * WARNING: it is intentional that GPIO 77 isn't listed here.
* The userspace script for updating the fingerprint firmware
* needs to control the FP regulators during a FW update,
* hence the signal can't be owned by the kernel regulator.
@@ -197,10 +144,10 @@
regulator-boot-on;
regulator-always-on;
- gpio = <&tlmm 24 GPIO_ACTIVE_HIGH>;
+ gpio = <&tlmm 157 GPIO_ACTIVE_HIGH>;
enable-active-high;
pinctrl-names = "default";
- pinctrl-0 = <&en_pp3300_hub>;
+ pinctrl-0 = <&hub_en>;
vin-supply = <&pp3300_z1>;
};
@@ -219,44 +166,44 @@
vin-supply = <&pp3300_z1>;
};
- pp2850_uf_cam: pp2850-uf-cam {
+ pp3300_ssd: pp3300-ssd-regulator {
compatible = "regulator-fixed";
- regulator-name = "pp2850_uf_cam";
+ regulator-name = "pp3300_ssd";
- regulator-min-microvolt = <2850000>;
- regulator-max-microvolt = <2850000>;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
- gpio = <&tlmm 6 GPIO_ACTIVE_HIGH>;
+ gpio = <&tlmm 51 GPIO_ACTIVE_HIGH>;
enable-active-high;
pinctrl-names = "default";
- pinctrl-0 = <&uf_cam_en>;
+ pinctrl-0 = <&ssd_en>;
- vin-supply = <&pp3300_cam>;
+ vin-supply = <&pp3300_z1>;
};
- pp2850_vcm_wf_cam: pp2850-vcm-wf-cam {
+ pp2850_vcm_wf_cam: pp2850-vcm-wf-cam-regulator {
compatible = "regulator-fixed";
regulator-name = "pp2850_vcm_wf_cam";
regulator-min-microvolt = <2850000>;
regulator-max-microvolt = <2850000>;
- gpio = <&tlmm 7 GPIO_ACTIVE_HIGH>;
+ gpio = <&tlmm 119 GPIO_ACTIVE_HIGH>;
enable-active-high;
pinctrl-names = "default";
pinctrl-0 = <&wf_cam_en>;
- vin-supply = <&pp3300_cam>;
+ vin-supply = <&pp3300_z1>;
};
- pp2850_wf_cam: pp2850-wf-cam {
+ pp2850_wf_cam: pp2850-wf-cam-regulator {
compatible = "regulator-fixed";
regulator-name = "pp2850_wf_cam";
regulator-min-microvolt = <2850000>;
regulator-max-microvolt = <2850000>;
- gpio = <&tlmm 7 GPIO_ACTIVE_HIGH>;
+ gpio = <&tlmm 119 GPIO_ACTIVE_HIGH>;
enable-active-high;
/*
* The pinconf can only be referenced once so we put it on the
@@ -266,7 +213,7 @@
* pinctrl-0 = <&wf_cam_en>;
*/
- vin-supply = <&pp3300_cam>;
+ vin-supply = <&pp3300_z1>;
};
pp1800_fp: pp1800-fp-regulator {
@@ -280,7 +227,7 @@
regulator-always-on;
/*
- * WARNING: it is intentional that GPIO 42 isn't listed here.
+ * WARNING: it is intentional that GPIO 77 isn't listed here.
* The userspace script for updating the fingerprint firmware
* needs to control the FP regulators during a FW update,
* hence the signal can't be owned by the kernel regulator.
@@ -293,34 +240,14 @@
status = "disabled";
};
- pp1800_uf_cam: pp1800-uf-cam {
- compatible = "regulator-fixed";
- regulator-name = "pp1800_uf_cam";
-
- regulator-min-microvolt = <1800000>;
- regulator-max-microvolt = <1800000>;
-
- gpio = <&tlmm 6 GPIO_ACTIVE_HIGH>;
- enable-active-high;
- /*
- * The pinconf can only be referenced once so we put it on the
- * first regulator and comment it out here.
- *
- * pinctrl-names = "default";
- * pinctrl-0 = <&uf_cam_en>;
- */
-
- vin-supply = <&pp1800_l19b>;
- };
-
- pp1800_wf_cam: pp1800-wf-cam {
+ pp1800_wf_cam: pp1800-wf-cam-regulator {
compatible = "regulator-fixed";
regulator-name = "pp1800_wf_cam";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
- gpio = <&tlmm 7 GPIO_ACTIVE_HIGH>;
+ gpio = <&tlmm 119 GPIO_ACTIVE_HIGH>;
enable-active-high;
/*
* The pinconf can only be referenced once so we put it on the
@@ -330,17 +257,17 @@
* pinctrl-0 = <&wf_cam_en>;
*/
- vin-supply = <&pp1800_l19b>;
+ vin-supply = <&vreg_l19b_s0>;
};
- pp1200_wf_cam: pp1200-wf-cam {
+ pp1200_wf_cam: pp1200-wf-cam-regulator {
compatible = "regulator-fixed";
regulator-name = "pp1200_wf_cam";
regulator-min-microvolt = <1200000>;
regulator-max-microvolt = <1200000>;
- gpio = <&tlmm 7 GPIO_ACTIVE_HIGH>;
+ gpio = <&tlmm 119 GPIO_ACTIVE_HIGH>;
enable-active-high;
/*
* The pinconf can only be referenced once so we put it on the
@@ -350,29 +277,11 @@
* pinctrl-0 = <&wf_cam_en>;
*/
- vin-supply = <&pp1200_l6b>;
+ vin-supply = <&pp3300_z1>;
};
/* BOARD-SPECIFIC TOP LEVEL NODES */
- gpio_keys: gpio-keys {
- compatible = "gpio-keys";
- status = "disabled";
- pinctrl-names = "default";
- pinctrl-0 = <&pen_pdct_l>;
-
- pen_insert: pen-insert {
- label = "Pen Insert";
-
- /* Insert = low, eject = high */
- gpios = <&tlmm 39 GPIO_ACTIVE_LOW>;
- linux,code = <SW_PEN_INSERTED>;
- linux,input-type = <EV_SW>;
- wakeup-event-action = <EV_ACT_DEASSERTED>;
- wakeup-source;
- };
- };
-
pwmleds {
compatible = "pwm-leds";
status = "disabled";
@@ -385,263 +294,54 @@
};
};
-&apps_rsc {
- pm7325-regulators {
- compatible = "qcom,pm7325-rpmh-regulators";
- qcom,pmic-id = "b";
-
- vdd19_pmu_pcie_i:
- vdd19_pmu_rfa_i:
- vreg_s1b_wlan:
- vreg_s1b: smps1 {
- regulator-min-microvolt = <1856000>;
- regulator-max-microvolt = <2040000>;
- };
-
- vdd_pmu_aon_i:
- vreg_s7b_wlan:
- vreg_s7b: smps7 {
- regulator-min-microvolt = <535000>;
- regulator-max-microvolt = <1120000>;
- };
-
- vdd13_pmu_pcie_i:
- vdd13_pmu_rfa_i:
- vreg_s8b_wlan:
- vreg_s8b: smps8 {
- regulator-min-microvolt = <1256000>;
- regulator-max-microvolt = <1500000>;
- };
-
- vdda_usb_ss_dp_core:
- vreg_l1b: ldo1 {
- regulator-min-microvolt = <825000>;
- regulator-max-microvolt = <925000>;
- regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
- };
-
- vdda_usb_hs0_3p1:
- vreg_l2b: ldo2 {
- regulator-min-microvolt = <2700000>;
- regulator-max-microvolt = <3544000>;
- regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
- };
-
- pp1200_l6b:
- vdd_ufs_1p2:
- vdd_vref:
- vdda_csi01_1p2:
- vdda_csi23_1p2:
- vdda_csi4_1p2:
- vdda_dsi0_1p2:
- vdda_pcie0_1p2:
- vdda_pcie1_1p2:
- vdda_usb_ss_dp_1p2:
- vdda_qlink0_1p2_ck:
- vdda_qlink1_1p2_ck:
- vreg_l6b_1p2:
- vreg_l6b: ldo6 {
- regulator-min-microvolt = <1120000>;
- regulator-max-microvolt = <1408000>;
- regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
- };
-
- pp2950_l7b:
- vreg_l7b: ldo7 {
- regulator-min-microvolt = <2960000>;
- regulator-max-microvolt = <2960000>;
- regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
- };
-
- codec_vcc:
- pp1800_l18b_s0:
- pp1800_ts:
- vdd1:
- vddpx_0:
- vddpx_3:
- vddpx_7:
- vreg_l18b: ldo18 {
- regulator-min-microvolt = <1800000>;
- regulator-max-microvolt = <2000000>;
- regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
- };
-
- pp1800_l19b:
- vddpx_ts:
- vddpx_wl4otp:
- vreg_l19b: ldo19 {
- regulator-min-microvolt = <1800000>;
- regulator-max-microvolt = <1800000>;
- regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
- };
- };
-
- pm8350c-regulators {
- compatible = "qcom,pm8350c-rpmh-regulators";
- qcom,pmic-id = "c";
-
- vreg_s1c: smps1 {
- regulator-min-microvolt = <2190000>;
- regulator-max-microvolt = <2210000>;
- };
+/*
+ * BOARD-LOCAL NAMES FOR REGULATORS THAT CONNECT TO QCARD
+ *
+ * Names are only listed here if regulators go somewhere other than a
+ * testpoint.
+ */
- vddpx_1:
- vreg_s9c: smps9 {
- regulator-min-microvolt = <1010000>;
- regulator-max-microvolt = <1170000>;
- };
+/* From Qcard to our board; ordered by PMIC-ID / rail number */
- pp1800_l1c:
- pp1800_pen:
- vdd_a_gfx_cs_1p1:
- vdd_a_cxo_1p8:
- vdd_qfprom:
- vdda_apc_cs_1p8:
- vdda_qrefs_1p8:
- vdda_turing_q6_cs_1p8:
- vdda_usb_hs0_1p8:
- vreg_l1c: ldo1 {
- regulator-min-microvolt = <1800000>;
- regulator-max-microvolt = <1980000>;
- regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
- };
+pp1256_s8b: &vreg_s8b_1p256 {};
- dmic_vdd:
- pp1800_alc5682:
- pp1800_l2c:
- pp1800_vreg_alc5682:
- vreg_l2c: ldo2 {
- regulator-min-microvolt = <1620000>;
- regulator-max-microvolt = <1980000>;
- regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
- };
+pp1800_l18b_s0: &vreg_l18b_1p8 {};
+pp1800_l18b: &vreg_l18b_1p8 {};
- pp3300_sar:
- pp3300_sensor:
- vreg_l3c: ldo3 {
- regulator-min-microvolt = <2800000>;
- regulator-max-microvolt = <3540000>;
- regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
- };
+vreg_l19b_s0: &vreg_l19b_1p8 {};
- ppvar_uim1:
- vddpx_5:
- vreg_l4c: ldo4 {
- regulator-min-microvolt = <1620000>;
- regulator-max-microvolt = <3300000>;
- regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
- };
+pp1800_alc5682: &vreg_l2c_1p8 {};
+pp1800_l2c: &vreg_l2c_1p8 {};
- pp2950_l5c:
- uim_vcc:
- vddpx_6:
- vreg_l5c: ldo5 {
- regulator-min-microvolt = <1620000>;
- regulator-max-microvolt = <3300000>;
- regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
- };
+vreg_l4c: &vreg_l4c_1p8_3p0 {};
- ppvar_l6c:
- vddpx_2:
- vreg_l6c: ldo6 {
- regulator-min-microvolt = <1800000>;
- regulator-max-microvolt = <2950000>;
- regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
- };
+ppvar_l6c: &vreg_l6c_2p96 {};
- vreg_l7c: ldo7 {
- regulator-min-microvolt = <3000000>;
- regulator-max-microvolt = <3544000>;
- regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
- };
+pp3000_l7c: &vreg_l7c_3p0 {};
- pp1800_prox:
- pp1800_sar:
- vreg_l8c: ldo8 {
- regulator-min-microvolt = <1620000>;
- regulator-max-microvolt = <2000000>;
- regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
- };
+pp1800_prox: &vreg_l8c_1p8 {};
+pp1800_l8c: &vreg_l8c_1p8 {};
- pp2950_l9c:
- vreg_l9c: ldo9 {
- regulator-min-microvolt = <2960000>;
- regulator-max-microvolt = <2960000>;
- regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
- };
+pp2950_l9c: &vreg_l9c_2p96 {};
- vdd_a_gnss_0p9:
- vdd_ufs_core:
- vdd_usb_hs0_core:
- vdd_vref_0p9:
- vdda_csi01_0p9:
- vdda_csi23_0p9:
- vdda_csi4_0p9:
- vdda_dsi0_pll_0p9:
- vdda_dsi0_0p9:
- vdda_pcie0_core:
- vdda_pcie1_core:
- vdda_qlink0_0p9:
- vdda_qlink1_0p9:
- vdda_qlink0_0p9_ck:
- vdda_qlink1_0p9_ck:
- vdda_qrefs_0p875:
- vreg_l10c_0p8:
- vreg_l10c: ldo10 {
- regulator-min-microvolt = <720000>;
- regulator-max-microvolt = <1050000>;
- regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
- };
+pp1800_lcm: &vreg_l12c_1p8 {};
+pp1800_mipi: &vreg_l12c_1p8 {};
+pp1800_l12c: &vreg_l12c_1p8 {};
- pp2800_l11c:
- vreg_l11c: ldo11 {
- regulator-min-microvolt = <2800000>;
- regulator-max-microvolt = <3544000>;
- regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
- };
+pp3300_lcm: &vreg_l13c_3p0 {};
+pp3300_mipi: &vreg_l13c_3p0 {};
+pp3300_l13c: &vreg_l13c_3p0 {};
- pp1800_l12c:
- vreg_l12c: ldo12 {
- regulator-min-microvolt = <1650000>;
- regulator-max-microvolt = <2000000>;
- regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
- };
+/* From our board to Qcard; ordered same as node definition above */
- pp3300_l13c:
- vreg_l13c: ldo13 {
- regulator-min-microvolt = <2700000>;
- regulator-max-microvolt = <3544000>;
- regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
- };
+vreg_edp_bl: &ppvar_sys {};
- vreg_bob: bob {
- regulator-min-microvolt = <3008000>;
- regulator-max-microvolt = <3960000>;
- regulator-initial-mode = <RPMH_REGULATOR_MODE_AUTO>;
- };
- };
-};
-
-ap_tp_i2c: &i2c1 {
- status = "okay";
- clock-frequency = <400000>;
-
- trackpad: trackpad@15 {
- compatible = "elan,ekth3000";
- reg = <0x15>;
- pinctrl-names = "default";
- pinctrl-0 = <&tp_int_odl>;
-
- interrupt-parent = <&tlmm>;
- interrupts = <102 IRQ_TYPE_EDGE_FALLING>;
+ts_avdd: &pp3300_left_in_mlb {};
+vreg_edp_3p3: &pp3300_left_in_mlb {};
- vcc-supply = <&pp3300_z1>;
+/* ADDITIONS TO NODES DEFINED IN PARENT DEVICE TREE FILES */
- wakeup-source;
- };
-};
-
-ap_h1_i2c: &i2c12 {
+ap_i2c_tpm: &i2c14 {
status = "okay";
clock-frequency = <400000>;
@@ -650,82 +350,26 @@ ap_h1_i2c: &i2c12 {
reg = <0x50>;
pinctrl-names = "default";
- pinctrl-0 = <&h1_ap_int_odl>;
-
- interrupt-parent = <&tlmm>;
- interrupts = <54 IRQ_TYPE_EDGE_RISING>;
- };
-};
-
-ap_ts_pen: &i2c13 {
- status = "okay";
- clock-frequency = <400000>;
-
- ap_ts: touchscreen@10 {
- compatible = "hid-over-i2c";
- reg = <0x10>;
- pinctrl-names = "default";
- pinctrl-0 = <&ts_int_l>, <&ts_reset_l>;
+ pinctrl-0 = <&gsc_ap_int_odl>;
interrupt-parent = <&tlmm>;
- interrupts = <81 IRQ_TYPE_LEVEL_LOW>;
-
- post-power-on-delay-ms = <20>;
- hid-descr-addr = <0x0001>;
-
- vdd-supply = <&pp3300_ts>;
+ interrupts = <104 IRQ_TYPE_EDGE_RISING>;
};
};
-&pm7325_gpios {
- status = "disabled"; /* No GPIOs are connected */
-};
-
-&pmk8350_gpios {
- status = "disabled"; /* No GPIOs are connected */
-};
+/* NVMe drive, enabled on a per-board basis */
+&pcie1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pcie1_clkreq_n>, <&ssd_rst_l>, <&pe_wake_odl>;
-&pmk8350_pon {
- status = "disabled";
+ perst-gpio = <&tlmm 2 GPIO_ACTIVE_LOW>;
+ vddpe-3v3-supply = <&pp3300_ssd>;
};
&pmk8350_rtc {
status = "disabled";
};
-&pmk8350_vadc {
- pmk8350_die_temp {
- reg = <PMK8350_ADC7_DIE_TEMP>;
- label = "pmk8350_die_temp";
- qcom,pre-scaling = <1 1>;
- };
-
- pmr735a_die_temp {
- reg = <PMR735A_ADC7_DIE_TEMP>;
- label = "pmr735a_die_temp";
- qcom,pre-scaling = <1 1>;
- };
-};
-
-&qfprom {
- vcc-supply = <&vdd_qfprom>;
-};
-
-&qspi {
- status = "okay";
- pinctrl-names = "default";
- pinctrl-0 = <&qspi_clk>, <&qspi_cs0>, <&qspi_data01>;
-
- flash@0 {
- compatible = "jedec,spi-nor";
- reg = <0>;
-
- spi-max-frequency = <37500000>;
- spi-tx-bus-width = <2>;
- spi-rx-bus-width = <2>;
- };
-};
-
&qupv3_id_0 {
status = "okay";
};
@@ -734,44 +378,50 @@ ap_ts_pen: &i2c13 {
status = "okay";
};
-&sdhc_1 {
- status = "okay";
-
- pinctrl-names = "default", "sleep";
- pinctrl-0 = <&sdc1_on>;
- pinctrl-1 = <&sdc1_off>;
- vmmc-supply = <&pp2950_l7b>;
- vqmmc-supply = <&pp1800_l19b>;
-};
-
+/* SD Card, enabled on a per-board basis */
&sdhc_2 {
- status = "okay";
+ pinctrl-0 = <&sdc2_clk>, <&sdc2_cmd>, <&sdc2_data>, <&sd_cd_odl>;
+ pinctrl-1 = <&sdc2_clk_sleep>, <&sdc2_cmd_sleep>, <&sdc2_data_sleep>, <&sd_cd_odl>;
- pinctrl-names = "default", "sleep";
- pinctrl-0 = <&sdc2_on>;
- pinctrl-1 = <&sdc2_off>;
vmmc-supply = <&pp2950_l9c>;
vqmmc-supply = <&ppvar_l6c>;
cd-gpios = <&tlmm 91 GPIO_ACTIVE_LOW>;
};
-ap_ec_spi: &spi8 {
+/* Fingerprint, enabled on a per-board basis */
+ap_spi_fp: &spi9 {
+ pinctrl-0 = <&qup_spi9_data_clk>, <&qup_spi9_cs_gpio_init_high>, <&qup_spi9_cs_gpio>;
+
+ cs-gpios = <&tlmm 39 GPIO_ACTIVE_LOW>;
+
+ cros_ec_fp: ec@0 {
+ compatible = "google,cros-ec-spi";
+ reg = <0>;
+ interrupt-parent = <&tlmm>;
+ interrupts = <61 IRQ_TYPE_LEVEL_LOW>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&fp_to_ap_irq_l>, <&fp_rst_l>, <&fpmcu_boot0>;
+ spi-max-frequency = <3000000>;
+ };
+};
+
+ap_ec_spi: &spi10 {
status = "okay";
+ pinctrl-0 = <&qup_spi10_data_clk>, <&qup_spi10_cs_gpio_init_high>, <&qup_spi10_cs_gpio>;
- pinctrl-0 = <&qup_spi8_data_clk>, <&qup_spi8_cs_gpio_init_high>, <&qup_spi8_cs_gpio>;
- cs-gpios = <&tlmm 35 GPIO_ACTIVE_LOW>;
+ cs-gpios = <&tlmm 43 GPIO_ACTIVE_LOW>;
cros_ec: ec@0 {
compatible = "google,cros-ec-spi";
reg = <0>;
interrupt-parent = <&tlmm>;
- interrupts = <142 IRQ_TYPE_LEVEL_LOW>;
+ interrupts = <18 IRQ_TYPE_LEVEL_LOW>;
pinctrl-names = "default";
pinctrl-0 = <&ap_ec_int_l>;
spi-max-frequency = <3000000>;
- cros_ec_pwm: ec-pwm {
+ cros_ec_pwm: pwm {
compatible = "google,cros-ec-pwm";
#pwm-cells = <1>;
};
@@ -841,15 +491,6 @@ ap_ec_spi: &spi8 {
>;
};
-&uart5 {
- compatible = "qcom,geni-debug-uart";
- status = "okay";
-};
-
-&uart7 {
- status = "okay";
-};
-
&usb_1 {
status = "okay";
};
@@ -860,17 +501,10 @@ ap_ec_spi: &spi8 {
&usb_1_hsphy {
status = "okay";
-
- vdda-pll-supply = <&vdd_usb_hs0_core>;
- vdda33-supply = <&vdda_usb_hs0_3p1>;
- vdda18-supply = <&vdda_usb_hs0_1p8>;
};
&usb_1_qmpphy {
status = "okay";
-
- vdda-phy-supply = <&vdda_usb_ss_dp_1p2>;
- vdda-pll-supply = <&vdda_usb_ss_dp_core>;
};
&usb_2 {
@@ -883,530 +517,269 @@ ap_ec_spi: &spi8 {
&usb_2_hsphy {
status = "okay";
+};
+
+/* PINCTRL - ADDITIONS TO NODES IN PARENT DEVICE TREE FILES */
- vdda-pll-supply = <&vdd_usb_hs0_core>;
- vdda33-supply = <&vdda_usb_hs0_3p1>;
- vdda18-supply = <&vdda_usb_hs0_1p8>;
+&dp_hot_plug_det {
+ bias-disable;
};
-/* PINCTRL - additions to nodes defined in sc7280.dtsi */
+&pcie1_clkreq_n {
+ bias-pull-up;
+ drive-strength = <2>;
+};
&qspi_cs0 {
bias-disable;
+ drive-strength = <8>;
};
&qspi_clk {
bias-disable;
+ drive-strength = <8>;
};
&qspi_data01 {
/* High-Z when no transfers; nice to park the lines */
bias-pull-up;
+ drive-strength = <8>;
};
-&qup_uart5_rx {
+/* For ap_tp_i2c */
+&qup_i2c0_data_clk {
+ /* Has external pull */
+ bias-disable;
drive-strength = <2>;
- bias-pull-up;
};
-&qup_uart5_tx {
- drive-strength = <2>;
+/* For ap_i2c_tpm */
+&qup_i2c14_data_clk {
+ /* Has external pull */
bias-disable;
+ drive-strength = <2>;
};
-&qup_uart7_cts {
- /*
- * Configure a pull-down on CTS to match the pull of
- * the Bluetooth module.
- */
- bias-pull-down;
+/* For ap_spi_fp */
+&qup_spi9_data_clk {
+ bias-disable;
+ drive-strength = <2>;
};
-&qup_uart7_rts {
- /* We'll drive RTS, so no pull */
- drive-strength = <2>;
+/* For ap_spi_fp */
+&qup_spi9_cs_gpio {
bias-disable;
+ drive-strength = <2>;
};
-&qup_uart7_tx {
- /* We'll drive TX, so no pull */
+/* For ap_ec_spi */
+&qup_spi10_data_clk {
+ bias-disable;
drive-strength = <2>;
+};
+
+/* For ap_ec_spi */
+&qup_spi10_cs_gpio {
bias-disable;
+ drive-strength = <2>;
};
-&qup_uart7_rx {
- /*
- * Configure a pull-up on RX. This is needed to avoid
- * garbage data when the TX pin of the Bluetooth module is
- * in tri-state (module powered off or not driving the
- * signal yet).
- */
+/* For uart_dbg */
+&qup_uart5_rx {
bias-pull-up;
};
-&sdc1_on {
- clk {
- bias-disable;
- drive-strength = <16>;
- };
-
- cmd {
- bias-pull-up;
- drive-strength = <10>;
- };
-
- data {
- bias-pull-up;
- drive-strength = <10>;
- };
-
- rclk {
- bias-pull-down;
- };
+/* For uart_dbg */
+&qup_uart5_tx {
+ bias-disable;
+ drive-strength = <2>;
};
-&sdc2_on {
- clk {
- bias-disable;
- drive-strength = <16>;
- };
-
- cmd {
- bias-pull-up;
- drive-strength = <10>;
- };
+&sdc2_clk {
+ bias-disable;
+ drive-strength = <16>;
+};
- data {
- bias-pull-up;
- drive-strength = <10>;
- };
+&sdc2_cmd {
+ bias-pull-up;
+ drive-strength = <10>;
+};
- sd-cd {
- pins = "gpio91";
- bias-pull-up;
- };
+&sdc2_data {
+ bias-pull-up;
+ drive-strength = <10>;
};
/* PINCTRL - board-specific pinctrl */
-&pm8350c_gpios {
- gpio-line-names = "AP_SUSPEND",
- "",
- "",
- "AP_BL_EN",
- "",
- "SD_CD_ODL",
- "",
- "",
- "AP_BL_PWM";
-
- ap_bl_en: ap-bl-en {
- pins = "gpio4";
- function = "normal";
- qcom,drive-strength = <PMIC_GPIO_STRENGTH_LOW>;
- bias-disable;
+&pm7325_gpios {
+ /*
+ * On a quick glance it might look like KYPD_VOL_UP_N is used, but
+ * that only passes through to a debug connector and not to the actual
+ * volume up key.
+ */
+ status = "disabled"; /* No GPIOs are connected */
+};
- /* Force backlight to be disabled to match state at boot. */
- output-low;
- };
+&pmk8350_gpios {
+ status = "disabled"; /* No GPIOs are connected */
};
&tlmm {
- gpio-line-names = "HP_I2C_SDA", /* 0 */
- "HP_I2C_SCL",
- "SSD_RST_L",
- "PE_WAKE_ODL",
- "AP_TP_I2C_SDA",
- "AP_TP_I2C_SCL",
- "UF_CAM_EN",
- "WF_CAM_EN",
- "AP_SAR_SENSOR_SDA",
- "AP_SAR_SENSOR_SCL",
-
- "", /* 10 */
- "",
- "AP_SPI_MOSI",
- "AP_SPI_MISO",
- "AP_SPI_CLK",
- "AP_SPI_CS0_L",
- "",
- "",
- "EDP_HPD",
- "",
-
- "UF_CAM_RST_L", /* 20 */
- "WF_CAM_RST_L",
- "UART_AP_TX_DBG_RX",
- "UART_DBG_TX_AP_RX",
- "EN_PP3300_HUB",
- "",
- "HOST2WLAN_SOL",
- "WLAN2HOST_SOL",
- "BT_UART_CTS",
- "BT_UART_RTS",
-
- "BT_UART_TXD", /* 30 */
- "BT_UART_RXD",
- "AP_EC_SPI_MISO",
- "AP_EC_SPI_MOSI",
- "AP_EC_SPI_CLK",
- "AP_EC_SPI_CS_L",
- "",
- "",
- "",
- "PEN_PDCT_L",
-
- "IO_BRD_ID0", /* 40 */
- "IO_BRD_ID1",
- "EN_FP_RAILS",
- "PEN_IRQ_L",
- "AP_SPI_FP_MISO",
- "AP_SPI_FP_MOSI",
- "AP_SPI_FP_CLK",
- "AP_SPI_FP_CS_L",
- "AP_H1_SPI_MISO",
- "AP_H1_SPI_MOSI",
-
- "AP_H1_SPI_CLK", /* 50 */
- "AP_H1_SPI_CS_L",
- "AP_TS_PEN_I2C_SDA",
- "AP_TS_PEN_I2C_SCL",
- "H1_AP_INT_ODL",
- "",
- "LCM_RST_1V8_L",
- "AMP_EN",
- "",
- "DP_HOT_PLUG_DET",
-
- "HUB_RST_L", /* 60 */
- "FP_TO_AP_IRQ_L",
- "",
- "",
- "UF_CAM_MCLK",
- "WF_CAM_MCLK",
- "IO_BRD_ID2",
- "EN_PP3300_CODEC",
- "EC_IN_RW_ODL",
- "UF_CAM_SDA",
-
- "UF_CAM_SCL", /* 70 */
- "WF_CAM_SDA",
- "WF_CAM_SCL",
- "AP_BRD_ID0",
- "AP_BRD_ID1",
- "AP_BRD_ID2",
- "",
- "FPMCU_BOOT0",
- "FP_RST_L",
- "PE_CLKREQ_ODL",
-
- "EN_EDP_PP3300", /* 80 */
- "TS_INT_L",
- "FORCE_USB_BOOT",
- "WCD_RST_L",
- "WLAN_EN",
- "BT_EN",
- "WLAN_SW_CTRL",
- "PCIE0_RESET_L",
- "PCIE0_CLK_REQ_L",
- "PCIE0_WAKE_L",
-
- "AS_EN", /* 90 */
- "SD_CD_ODL",
- "",
- /*
- * AP_FLASH_WP_L is crossystem ABI. Schematics
- * call it BIOS_FLASH_WP_L.
- */
- "AP_FLASH_WP_L",
- "BT_WLAN_SB_CLK",
- "BT_WLAN_SB_DATA",
- "HP_MCLK",
- "HP_BCLK",
- "HP_DOUT",
- "HP_DIN",
-
- "HP_LRCLK", /* 100 */
- "HP_IRQ",
- "TP_INT_ODL",
- "",
- "IO_SKU_ID2",
- "TS_RESET_L",
- "AMP_BCLK",
- "AMP_DIN",
- "AMP_LRCLK",
- "UIM2_DATA",
-
- "UIM2_CLK", /* 110 */
- "UIM2_RST",
- "UIM2_PRESENT",
- "UIM1_DATA",
- "UIM1_CLK",
- "UIM1_RST",
- "",
- "RFFE0_CLK",
- "RFFE0_DATA/BOOT_CONFIG_0",
- "RFFE1_CLK",
-
- "RFFE1_DATA/BOOT_CONFIG_1", /* 120 */
- "RFFE2_CLK",
- "RFFE2_DATA/BOOT_CONFIG_2",
- "RFFE3_CLK",
- "RFFE3_DATA/BOOT_CONFIG_3",
- "RFFE4_CLK",
- "RFFE4_DATA",
- "WCI2_LTE_COEX_RXD",
- "WCI2_LTE_COEX_TXD",
- "IO_SKU_ID0",
-
- "IO_SKU_ID1", /* 130 */
- "",
- "",
- "QLINK0_REQ",
- "QLINK0_EN",
- "QLINK0_WMSS_RESET_L",
- "QLINK1_REQ",
- "QLINK1_EN",
- "QLINK1_WMSS_RESET_L",
- "FORCED_USB_BOOT_POL",
-
- "", /* 140 */
- "P_SENSOR_INT_L",
- "AP_EC_INT_L",
- "",
- "WCD_SWR_TX_CLK",
- "WCD_SWR_TX_DATA_0",
- "WCD_SWR_TX_DATA_1",
- "WCD_SWR_RX_CLK",
- "WCD_SWR_RX_DATA_0",
- "WCD_SWR_RX_DATA_1",
-
- "", /* 150 */
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- "WCD_SWR_TX_DATA_2",
- "",
-
- "", /* 160 */
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- "",
-
- "", /* 170 */
- "SENS_UART_TXD",
- "SENS_UART_RXD",
- "",
- "",
- "";
-
- /*
- * pinctrl settings for pins that have no real owners.
- */
+ /* pinctrl settings for pins that have no real owners. */
pinctrl-names = "default";
- pinctrl-0 = <&bios_flash_wp_l>;
+ pinctrl-0 = <&bios_flash_wp_od>;
amp_en: amp-en {
- pins = "gpio57";
+ pins = "gpio63";
function = "gpio";
- bias-pull-down;
+ bias-disable;
+ drive-strength = <2>;
};
ap_ec_int_l: ap-ec-int-l {
- pins = "gpio142";
- input-enable;
+ pins = "gpio18";
+ function = "gpio";
bias-pull-up;
};
- bios_flash_wp_l: bios-flash-wp-l {
- pins = "gpio93";
+ bios_flash_wp_od: bios-flash-wp-od {
+ pins = "gpio16";
function = "gpio";
- input-enable;
+ /* Has external pull */
bias-disable;
};
- bt_en: bt-en {
- pins = "gpio85";
- function = "gpio";
- drive-strength = <2>;
- output-low;
- bias-pull-down;
- };
-
en_fp_rails: en-fp-rails {
- pins = "gpio42";
+ pins = "gpio77";
+ function = "gpio";
+ bias-disable;
drive-strength = <2>;
output-high;
- bias-disable;
};
en_pp3300_codec: en-pp3300-codec {
- pins = "gpio67";
- drive-strength = <2>;
+ pins = "gpio105";
+ function = "gpio";
bias-disable;
+ drive-strength = <2>;
};
en_pp3300_dx_edp: en-pp3300-dx-edp {
pins = "gpio80";
function = "gpio";
- drive-strength = <2>;
- /* Has external pulldown */
bias-disable;
+ drive-strength = <2>;
};
- en_pp3300_hub: en-pp3300-hub {
- pins = "gpio24";
+ fp_rst_l: fp-rst-l {
+ pins = "gpio78";
function = "gpio";
- drive-strength = <2>;
- /* Has external pulldown */
bias-disable;
+ drive-strength = <2>;
+ output-high;
};
fp_to_ap_irq_l: fp-to-ap-irq-l {
pins = "gpio61";
function = "gpio";
- input-enable;
/* Has external pullup */
bias-disable;
};
- h1_ap_int_odl: h1-ap-int-odl {
- pins = "gpio54";
+ fpmcu_boot0: fpmcu-boot0 {
+ pins = "gpio68";
function = "gpio";
- input-enable;
- bias-pull-up;
+ bias-disable;
+ output-low;
};
- hp_irq: hp-irq {
- pins = "gpio101";
+ gsc_ap_int_odl: gsc-ap-int-odl {
+ pins = "gpio104";
function = "gpio";
bias-pull-up;
};
- p_sensor_int_l: p-sensor-int-l {
- pins = "gpio141";
+ hp_irq: hp-irq {
+ pins = "gpio101";
function = "gpio";
- input-enable;
bias-pull-up;
};
- pen_irq_l: pen-irq-l {
- pins = "gpio43";
+ hub_en: hub-en {
+ pins = "gpio157";
function = "gpio";
- /* Has external pullup */
bias-disable;
+ drive-strength = <2>;
};
- pen_pdct_l: pen-pdct-l {
- pins = "gpio39";
+ pe_wake_odl: pe-wake-odl {
+ pins = "gpio3";
function = "gpio";
- /* Has external pullup */
+ /* Has external pull */
bias-disable;
+ drive-strength = <2>;
};
- qup_spi8_cs_gpio_init_high: qup-spi8-cs-gpio-init-high {
- pins = "gpio35";
- output-high;
- };
-
- qup_spi11_cs_gpio_init_high: qup-spi11-cs-gpio-init-high {
- pins = "gpio47";
- output-high;
- };
-
- qup_spi12_cs_gpio_init_high: qup-spi12-cs-gpio-init-high {
- pins = "gpio51";
+ /* For ap_spi_fp */
+ qup_spi9_cs_gpio_init_high: qup-spi9-cs-gpio-init-high {
+ pins = "gpio39";
+ function = "gpio";
output-high;
};
- qup_uart7_sleep_cts: qup-uart7-sleep-cts {
- pins = "gpio28";
+ /* For ap_ec_spi */
+ qup_spi10_cs_gpio_init_high: qup-spi10-cs-gpio-init-high {
+ pins = "gpio43";
function = "gpio";
- /*
- * Configure a pull-down on CTS to match the pull of
- * the Bluetooth module.
- */
- bias-pull-down;
+ output-high;
};
- qup_uart7_sleep_rts: qup-uart7-sleep-rts {
- pins = "gpio29";
+ sar0_irq_odl: sar0-irq-odl {
+ pins = "gpio141";
function = "gpio";
- /*
- * Configure pull-down on RTS. As RTS is active low
- * signal, pull it low to indicate the BT SoC that it
- * can wakeup the system anytime from suspend state by
- * pulling RX low (by sending wakeup bytes).
- */
- bias-pull-down;
+ bias-pull-up;
};
- qup_uart7_sleep_rx: qup-uart7-sleep-rx {
- pins = "gpio31";
+ sar1_irq_odl: sar0-irq-odl {
+ pins = "gpio140";
function = "gpio";
- /*
- * Configure a pull-up on RX. This is needed to avoid
- * garbage data when the TX pin of the Bluetooth module
- * is floating which may cause spurious wakeups.
- */
bias-pull-up;
};
- qup_uart7_sleep_tx: qup-uart7-sleep-tx {
- pins = "gpio30";
+ sd_cd_odl: sd-cd-odl {
+ pins = "gpio91";
function = "gpio";
- /*
- * Configure pull-up on TX when it isn't actively driven
- * to prevent BT SoC from receiving garbage during sleep.
- */
bias-pull-up;
};
- tp_int_odl: tp-int-odl {
- pins = "gpio102";
+ ssd_en: ssd-en {
+ pins = "gpio51";
function = "gpio";
- /* Has external pullup */
bias-disable;
+ drive-strength = <2>;
};
- ts_int_l: ts-int-l {
- pins = "gpio81";
- function = "gpio";
- /* Has external pullup */
- bias-pull-up;
- };
-
- ts_reset_l: ts-reset-l {
- pins = "gpio105";
+ ssd_rst_l: ssd-rst-l {
+ pins = "gpio2";
function = "gpio";
- /* Has external pullup */
bias-disable;
drive-strength = <2>;
+ output-low;
};
- uf_cam_en: uf-cam-en {
- pins = "gpio6";
+ tp_int_odl: tp-int-odl {
+ pins = "gpio7";
function = "gpio";
- drive-strength = <2>;
- /* Has external pulldown */
+ /* Has external pullup */
bias-disable;
};
wf_cam_en: wf-cam-en {
- pins = "gpio7";
+ pins = "gpio119";
function = "gpio";
- drive-strength = <2>;
/* Has external pulldown */
bias-disable;
+ drive-strength = <2>;
};
};
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 0896a6151817..a7c346aa3b02 100644
--- a/arch/arm64/boot/dts/qcom/sc7280-idp-ec-h1.dtsi
+++ b/arch/arm64/boot/dts/qcom/sc7280-idp-ec-h1.dtsi
@@ -20,7 +20,7 @@ ap_ec_spi: &spi10 {
pinctrl-0 = <&ap_ec_int_l>;
spi-max-frequency = <3000000>;
- cros_ec_pwm: ec-pwm {
+ cros_ec_pwm: pwm {
compatible = "google,cros-ec-pwm";
#pwm-cells = <1>;
};
diff --git a/arch/arm64/boot/dts/qcom/sc7280-idp.dts b/arch/arm64/boot/dts/qcom/sc7280-idp.dts
index 9b991ba5daaf..a7be133a782f 100644
--- a/arch/arm64/boot/dts/qcom/sc7280-idp.dts
+++ b/arch/arm64/boot/dts/qcom/sc7280-idp.dts
@@ -56,6 +56,10 @@
};
};
+&bluetooth {
+ vddio-supply = <&vreg_l19b_1p8>;
+};
+
&ipa {
status = "okay";
modem-init;
@@ -80,3 +84,19 @@
qcom,pre-scaling = <1 1>;
};
};
+
+&usb_2 {
+ status = "okay";
+};
+
+&usb_2_dwc3 {
+ dr_mode = "host";
+};
+
+&usb_2_hsphy {
+ status = "okay";
+
+ vdda-pll-supply = <&vreg_l10c_0p8>;
+ vdda33-supply = <&vreg_l2b_3p0>;
+ vdda18-supply = <&vreg_l1c_1p8>;
+};
diff --git a/arch/arm64/boot/dts/qcom/sc7280-idp.dtsi b/arch/arm64/boot/dts/qcom/sc7280-idp.dtsi
index d623d71d8bd4..ecbf2b89d896 100644
--- a/arch/arm64/boot/dts/qcom/sc7280-idp.dtsi
+++ b/arch/arm64/boot/dts/qcom/sc7280-idp.dtsi
@@ -5,7 +5,6 @@
* Copyright (c) 2021, The Linux Foundation. All rights reserved.
*/
-#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/iio/qcom,spmi-adc7-pmk8350.h>
#include <dt-bindings/input/linux-event-codes.h>
#include "sc7280.dtsi"
@@ -13,7 +12,14 @@
#include "pm8350c.dtsi"
#include "pmk8350.dtsi"
+#include "sc7280-chrome-common.dtsi"
+
/ {
+ aliases {
+ bluetooth0 = &bluetooth;
+ serial1 = &uart7;
+ };
+
gpio-keys {
compatible = "gpio-keys";
label = "gpio-keys";
@@ -45,58 +51,6 @@
};
};
-/*
- * Reserved memory changes
- *
- * Delete all unused memory nodes and define the peripheral memory regions
- * required by the board dts.
- *
- */
-
-/delete-node/ &hyp_mem;
-/delete-node/ &xbl_mem;
-/delete-node/ &reserved_xbl_uefi_log;
-/delete-node/ &sec_apps_mem;
-
-/* Increase the size from 2.5MB to 8MB */
-&rmtfs_mem {
- reg = <0x0 0x9c900000 0x0 0x800000>;
-};
-
-/ {
- reserved-memory {
- adsp_mem: memory@86700000 {
- reg = <0x0 0x86700000 0x0 0x2800000>;
- no-map;
- };
-
- camera_mem: memory@8ad00000 {
- reg = <0x0 0x8ad00000 0x0 0x500000>;
- no-map;
- };
-
- venus_mem: memory@8b200000 {
- reg = <0x0 0x8b200000 0x0 0x500000>;
- no-map;
- };
-
- mpss_mem: memory@8b800000 {
- reg = <0x0 0x8b800000 0x0 0xf600000>;
- no-map;
- };
-
- wpss_mem: memory@9ae00000 {
- reg = <0x0 0x9ae00000 0x0 0x1900000>;
- no-map;
- };
-
- mba_mem: memory@9c700000 {
- reg = <0x0 0x9c700000 0x0 0x200000>;
- no-map;
- };
- };
-};
-
&apps_rsc {
pm7325-regulators {
compatible = "qcom,pm7325-rpmh-regulators";
@@ -313,20 +267,6 @@
vcc-supply = <&vreg_l1c_1p8>;
};
-&qspi {
- status = "okay";
- pinctrl-names = "default";
- pinctrl-0 = <&qspi_clk>, <&qspi_cs0>, <&qspi_data01>;
-
- flash@0 {
- compatible = "jedec,spi-nor";
- reg = <0>;
- spi-max-frequency = <37500000>;
- spi-tx-bus-width = <2>;
- spi-rx-bus-width = <2>;
- };
-};
-
&qupv3_id_0 {
status = "okay";
};
@@ -335,20 +275,9 @@
status = "okay";
};
-&remoteproc_mpss {
- status = "okay";
- compatible = "qcom,sc7280-mss-pil";
- iommus = <&apps_smmu 0x124 0x0>, <&apps_smmu 0x488 0x7>;
- memory-region = <&mba_mem &mpss_mem>;
-};
-
&sdhc_1 {
status = "okay";
- pinctrl-names = "default", "sleep";
- pinctrl-0 = <&sdc1_on>;
- pinctrl-1 = <&sdc1_off>;
-
non-removable;
no-sd;
no-sdio;
@@ -360,9 +289,8 @@
&sdhc_2 {
status = "okay";
- pinctrl-names = "default", "sleep";
- pinctrl-0 = <&sdc2_on>;
- pinctrl-1 = <&sdc2_off>;
+ pinctrl-0 = <&sdc2_clk>, <&sdc2_cmd>, <&sdc2_data>, <&sd_cd>;
+ pinctrl-1 = <&sdc2_clk_sleep>, <&sdc2_cmd_sleep>, <&sdc2_data_sleep>, <&sd_cd>;
vmmc-supply = <&vreg_l9c_2p9>;
vqmmc-supply = <&vreg_l6c_2p9>;
@@ -398,22 +326,6 @@
vdda-pll-supply = <&vreg_l1b_0p8>;
};
-&usb_2 {
- status = "okay";
-};
-
-&usb_2_dwc3 {
- dr_mode = "peripheral";
-};
-
-&usb_2_hsphy {
- status = "okay";
-
- vdda-pll-supply = <&vreg_l10c_0p8>;
- vdda33-supply = <&vreg_l2b_3p0>;
- vdda18-supply = <&vreg_l1c_1p8>;
-};
-
&uart7 {
status = "okay";
@@ -422,10 +334,31 @@
<&tlmm 31 IRQ_TYPE_EDGE_FALLING>;
pinctrl-names = "default", "sleep";
pinctrl-1 = <&qup_uart7_sleep_cts>, <&qup_uart7_sleep_rts>, <&qup_uart7_sleep_tx>, <&qup_uart7_sleep_rx>;
+
+ bluetooth: bluetooth {
+ compatible = "qcom,wcn6750-bt";
+ pinctrl-names = "default";
+ pinctrl-0 = <&bt_en>, <&sw_ctrl>;
+ enable-gpios = <&tlmm 85 GPIO_ACTIVE_HIGH>;
+ swctrl-gpios = <&tlmm 86 GPIO_ACTIVE_HIGH>;
+ vddaon-supply = <&vreg_s7b_0p9>;
+ vddbtcxmx-supply = <&vreg_s7b_0p9>;
+ vddrfacmn-supply = <&vreg_s7b_0p9>;
+ vddrfa0p8-supply = <&vreg_s7b_0p9>;
+ vddrfa1p7-supply = <&vreg_s1b_1p8>;
+ vddrfa1p2-supply = <&vreg_s8b_1p2>;
+ vddrfa2p2-supply = <&vreg_s1c_2p2>;
+ vddasd-supply = <&vreg_l11c_2p8>;
+ max-speed = <3200000>;
+ };
};
/* PINCTRL - additions to nodes defined in sc7280.dtsi */
+&dp_hot_plug_det {
+ bias-disable;
+};
+
&pm7325_gpios {
key_vol_up_default: key-vol-up-default {
pins = "gpio6";
@@ -437,6 +370,11 @@
};
};
+&pcie1_clkreq_n {
+ bias-pull-up;
+ drive-strength = <2>;
+};
+
&qspi_cs0 {
bias-disable;
};
@@ -490,7 +428,48 @@
bias-pull-up;
};
+&sdc1_clk {
+ bias-disable;
+ drive-strength = <16>;
+};
+
+&sdc1_cmd {
+ bias-pull-up;
+ drive-strength = <10>;
+};
+
+&sdc1_data {
+ bias-pull-up;
+ drive-strength = <10>;
+};
+
+&sdc1_rclk {
+ bias-pull-down;
+};
+
+&sdc2_clk {
+ bias-disable;
+ drive-strength = <16>;
+};
+
+&sdc2_cmd {
+ bias-pull-up;
+ drive-strength = <10>;
+};
+
+&sdc2_data {
+ bias-pull-up;
+ drive-strength = <10>;
+};
+
&tlmm {
+ bt_en: bt-en {
+ pins = "gpio85";
+ function = "gpio";
+ output-low;
+ bias-disable;
+ };
+
nvme_pwren: nvme-pwren {
function = "gpio";
};
@@ -554,47 +533,17 @@
*/
bias-pull-up;
};
-};
-
-&sdc1_on {
- clk {
- bias-disable;
- drive-strength = <16>;
- };
-
- cmd {
- bias-pull-up;
- drive-strength = <10>;
- };
- data {
+ sd_cd: sd-cd {
+ pins = "gpio91";
+ function = "gpio";
bias-pull-up;
- drive-strength = <10>;
};
- rclk {
+ sw_ctrl: sw-ctrl {
+ pins = "gpio86";
+ function = "gpio";
bias-pull-down;
};
};
-&sdc2_on {
- clk {
- bias-disable;
- drive-strength = <16>;
- };
-
- cmd {
- bias-pull-up;
- drive-strength = <10>;
- };
-
- data {
- bias-pull-up;
- drive-strength = <10>;
- };
-
- sd-cd {
- pins = "gpio91";
- bias-pull-up;
- };
-};
diff --git a/arch/arm64/boot/dts/qcom/sc7280-idp2.dts b/arch/arm64/boot/dts/qcom/sc7280-idp2.dts
index 0382c770650a..73b9911dd802 100644
--- a/arch/arm64/boot/dts/qcom/sc7280-idp2.dts
+++ b/arch/arm64/boot/dts/qcom/sc7280-idp2.dts
@@ -23,6 +23,10 @@
};
};
+&bluetooth {
+ vddio-supply = <&vreg_l18b_1p8>;
+};
+
&nvme_pwren {
pins = "gpio51";
};
diff --git a/arch/arm64/boot/dts/qcom/sc7280-qcard.dtsi b/arch/arm64/boot/dts/qcom/sc7280-qcard.dtsi
new file mode 100644
index 000000000000..b833ba1e8f4a
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sc7280-qcard.dtsi
@@ -0,0 +1,547 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * sc7280 Qcard device tree source
+ *
+ * Qcard PCB has the processor, RAM, eMMC (if stuffed), and eDP connector (if
+ * stuffed) on it. This device tree tries to encapsulate all the things that
+ * all boards using Qcard will have in common. Given that there are stuffing
+ * options, some things may be left with status "disabled" and enabled in
+ * the actual board device tree files.
+ *
+ * Copyright 2022 Google LLC.
+ */
+
+#include <dt-bindings/iio/qcom,spmi-adc7-pmk8350.h>
+#include <dt-bindings/iio/qcom,spmi-adc7-pmr735a.h>
+#include <dt-bindings/pinctrl/qcom,pmic-gpio.h>
+#include <dt-bindings/regulator/qcom,rpmh-regulator.h>
+
+#include "sc7280.dtsi"
+
+/* PMICs depend on spmi_bus label and so must come after SoC */
+#include "pm7325.dtsi"
+#include "pm8350c.dtsi"
+#include "pmk8350.dtsi"
+
+/ {
+ aliases {
+ bluetooth0 = &bluetooth;
+ serial0 = &uart5;
+ serial1 = &uart7;
+ };
+};
+
+&apps_rsc {
+ /*
+ * Regulators are given labels corresponding to the various names
+ * they are referred to on schematics. They are also given labels
+ * corresponding to named voltage inputs on the SoC or components
+ * bundled with the SoC (like radio companion chips). We totally
+ * ignore it when one regulator is the input to another regulator.
+ * That's handled automatically by the initial config given to
+ * RPMH by the firmware.
+ *
+ * Regulators that the HLOS (High Level OS) doesn't touch at all
+ * are left out of here since they are managed elsewhere.
+ */
+
+ pm7325-regulators {
+ compatible = "qcom,pm7325-rpmh-regulators";
+ qcom,pmic-id = "b";
+
+ vdd19_pmu_pcie_i:
+ vdd19_pmu_rfa_i:
+ vreg_s1b_1p856: smps1 {
+ regulator-min-microvolt = <1856000>;
+ regulator-max-microvolt = <2040000>;
+ };
+
+ vdd_pmu_aon_i:
+ vdd09_pmu_rfa_i:
+ vdd095_mx_pmu:
+ vdd095_pmu:
+ vreg_s7b_0p952: smps7 {
+ regulator-min-microvolt = <535000>;
+ regulator-max-microvolt = <1120000>;
+ };
+
+ vdd13_pmu_rfa_i:
+ vdd13_pmu_pcie_i:
+ vreg_s8b_1p256: smps8 {
+ regulator-min-microvolt = <1256000>;
+ regulator-max-microvolt = <1500000>;
+ };
+
+ vdd_a_usbssdp_0_core:
+ vreg_l1b_0p912: ldo1 {
+ regulator-min-microvolt = <825000>;
+ regulator-max-microvolt = <925000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vdd_a_usbhs_3p1:
+ vreg_l2b_3p072: ldo2 {
+ regulator-min-microvolt = <2700000>;
+ regulator-max-microvolt = <3544000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vdd_a_csi_0_1_1p2:
+ vdd_a_csi_2_3_1p2:
+ vdd_a_csi_4_1p2:
+ vdd_a_dsi_0_1p2:
+ vdd_a_edp_0_1p2:
+ vdd_a_qlink_0_1p2:
+ vdd_a_qlink_1_1p2:
+ vdd_a_pcie_0_1p2:
+ vdd_a_pcie_1_1p2:
+ vdd_a_ufs_0_1p2:
+ vdd_a_usbssdp_0_1p2:
+ vreg_l6b_1p2: ldo6 {
+ regulator-min-microvolt = <1140000>;
+ regulator-max-microvolt = <1260000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ /*
+ * Despite the fact that this is named to be 2.5V on the
+ * schematic, it powers eMMC which doesn't accept 2.5V
+ */
+ vreg_l7b_2p5: ldo7 {
+ regulator-min-microvolt = <2960000>;
+ regulator-max-microvolt = <2960000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vdd_px_wcd9385:
+ vdd_txrx:
+ vddpx_0:
+ vddpx_3:
+ vddpx_7:
+ vreg_l18b_1p8: ldo18 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <2000000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vdd_1p8:
+ vdd_px_sdr735:
+ vdd_pxm:
+ vdd18_io:
+ vddio_px_1:
+ vddio_px_2:
+ vddio_px_3:
+ vddpx_ts:
+ vddpx_wl4otp:
+ vreg_l19b_1p8: ldo19 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+ };
+
+ pm8350c-regulators {
+ compatible = "qcom,pm8350c-rpmh-regulators";
+ qcom,pmic-id = "c";
+
+ vdd22_wlbtpa_ch0:
+ vdd22_wlbtpa_ch1:
+ vdd22_wlbtppa_ch0:
+ vdd22_wlbtppa_ch1:
+ vdd22_wlpa5g_ch0:
+ vdd22_wlpa5g_ch1:
+ vdd22_wlppa5g_ch0:
+ vdd22_wlppa5g_ch1:
+ vreg_s1c_2p2: smps1 {
+ regulator-min-microvolt = <2190000>;
+ regulator-max-microvolt = <2210000>;
+ };
+
+ lp4_vdd2_1p052:
+ vreg_s9c_0p676: smps9 {
+ regulator-min-microvolt = <1010000>;
+ regulator-max-microvolt = <1170000>;
+ };
+
+ vdda_apc_cs_1p8:
+ vdda_gfx_cs_1p8:
+ vdda_turing_q6_cs_1p8:
+ vdd_a_cxo_1p8:
+ vdd_a_qrefs_1p8:
+ vdd_a_usbhs_1p8:
+ vdd_qfprom:
+ vreg_l1c_1p8: ldo1 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1980000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l2c_1p8: ldo2 {
+ regulator-min-microvolt = <1620000>;
+ regulator-max-microvolt = <1980000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l3c_3p0: ldo3 {
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <3540000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vddpx_5:
+ vreg_l4c_1p8_3p0: ldo4 {
+ regulator-min-microvolt = <1620000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vddpx_6:
+ vreg_l5c_1p8_3p0: ldo5 {
+ regulator-min-microvolt = <1620000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vddpx_2:
+ vreg_l6c_2p96: ldo6 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <2950000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l7c_3p0: ldo7 {
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3544000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l8c_1p8: ldo8 {
+ regulator-min-microvolt = <1620000>;
+ regulator-max-microvolt = <2000000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l9c_2p96: ldo9 {
+ regulator-min-microvolt = <2960000>;
+ regulator-max-microvolt = <2960000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vdd_a_csi_0_1_0p9:
+ vdd_a_csi_2_3_0p9:
+ vdd_a_csi_4_0p9:
+ vdd_a_dsi_0_0p9:
+ vdd_a_dsi_0_pll_0p9:
+ vdd_a_edp_0_0p9:
+ vdd_a_gnss_0p9:
+ vdd_a_pcie_0_core:
+ vdd_a_pcie_1_core:
+ vdd_a_qlink_0_0p9:
+ vdd_a_qlink_0_0p9_ck:
+ vdd_a_qlink_1_0p9:
+ vdd_a_qlink_1_0p9_ck:
+ vdd_a_qrefs_0p875_0:
+ vdd_a_qrefs_0p875_1:
+ vdd_a_qrefs_0p875_2:
+ vdd_a_qrefs_0p875_3:
+ vdd_a_qrefs_0p875_4_5:
+ vdd_a_qrefs_0p875_6:
+ vdd_a_qrefs_0p875_7:
+ vdd_a_qrefs_0p875_8:
+ vdd_a_qrefs_0p875_9:
+ vdd_a_ufs_0_core:
+ vdd_a_usbhs_core:
+ vreg_l10c_0p88: ldo10 {
+ regulator-min-microvolt = <720000>;
+ regulator-max-microvolt = <1050000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l11c_2p8: ldo11 {
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <3544000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l12c_1p8: ldo12 {
+ regulator-min-microvolt = <1650000>;
+ regulator-max-microvolt = <2000000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l13c_3p0: ldo13 {
+ regulator-min-microvolt = <2700000>;
+ regulator-max-microvolt = <3544000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vdd_flash:
+ vdd_iris_rgb:
+ vdd_mic_bias:
+ vreg_bob: bob {
+ regulator-min-microvolt = <3008000>;
+ regulator-max-microvolt = <3960000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_AUTO>;
+ };
+ };
+};
+
+/* ADDITIONS TO NODES DEFINED IN PARENT DEVICE TREE FILES */
+
+&ipa {
+ status = "okay";
+ modem-init;
+};
+
+&pcie1_phy {
+ vdda-phy-supply = <&vreg_l10c_0p88>;
+ vdda-pll-supply = <&vreg_l6b_1p2>;
+};
+
+&pmk8350_vadc {
+ pmk8350-die-temp@3 {
+ reg = <PMK8350_ADC7_DIE_TEMP>;
+ label = "pmk8350_die_temp";
+ qcom,pre-scaling = <1 1>;
+ };
+
+ pmr735a-die-temp@403 {
+ reg = <PMR735A_ADC7_DIE_TEMP>;
+ label = "pmr735a_die_temp";
+ qcom,pre-scaling = <1 1>;
+ };
+};
+
+&qfprom {
+ vcc-supply = <&vdd_qfprom>;
+};
+
+/* For eMMC. NOTE: not all Qcards have eMMC stuffed */
+&sdhc_1 {
+ vmmc-supply = <&vreg_l7b_2p5>;
+ vqmmc-supply = <&vreg_l19b_1p8>;
+
+ non-removable;
+ no-sd;
+ no-sdio;
+};
+
+uart_dbg: &uart5 {
+ compatible = "qcom,geni-debug-uart";
+ status = "okay";
+};
+
+mos_bt_uart: &uart7 {
+ status = "okay";
+
+ /delete-property/ interrupts;
+ interrupts-extended = <&intc GIC_SPI 608 IRQ_TYPE_LEVEL_HIGH>,
+ <&tlmm 31 IRQ_TYPE_EDGE_FALLING>;
+ pinctrl-names = "default", "sleep";
+ pinctrl-1 = <&qup_uart7_sleep_cts>, <&qup_uart7_sleep_rts>, <&qup_uart7_sleep_tx>, <&qup_uart7_sleep_rx>;
+
+ bluetooth: bluetooth {
+ compatible = "qcom,wcn6750-bt";
+ pinctrl-names = "default";
+ pinctrl-0 = <&mos_bt_en>;
+ enable-gpios = <&tlmm 85 GPIO_ACTIVE_HIGH>;
+ swctrl-gpios = <&tlmm 86 GPIO_ACTIVE_HIGH>;
+ vddaon-supply = <&vreg_s7b_0p952>;
+ vddbtcxmx-supply = <&vreg_s7b_0p952>;
+ vddrfacmn-supply = <&vreg_s7b_0p952>;
+ vddrfa0p8-supply = <&vreg_s7b_0p952>;
+ vddrfa1p7-supply = <&vdd19_pmu_rfa_i>;
+ vddrfa1p2-supply = <&vdd13_pmu_rfa_i>;
+ vddrfa2p2-supply = <&vreg_s1c_2p2>;
+ vddasd-supply = <&vreg_l11c_2p8>;
+ vddio-supply = <&vreg_l18b_1p8>;
+ max-speed = <3200000>;
+ };
+};
+
+&usb_1_hsphy {
+ vdda-pll-supply = <&vdd_a_usbhs_core>;
+ vdda33-supply = <&vdd_a_usbhs_3p1>;
+ vdda18-supply = <&vdd_a_usbhs_1p8>;
+};
+
+&usb_1_qmpphy {
+ vdda-phy-supply = <&vdd_a_usbssdp_0_1p2>;
+ vdda-pll-supply = <&vdd_a_usbssdp_0_core>;
+};
+
+&usb_2_hsphy {
+ vdda-pll-supply = <&vdd_a_usbhs_core>;
+ vdda33-supply = <&vdd_a_usbhs_3p1>;
+ vdda18-supply = <&vdd_a_usbhs_1p8>;
+};
+
+/*
+ * PINCTRL - ADDITIONS TO NODES IN PARENT DEVICE TREE FILES
+ *
+ * NOTE: In general if pins leave the Qcard then the pinctrl goes in the
+ * baseboard or board device tree, not here.
+ */
+
+/*
+ * For ts_i2c
+ *
+ * Technically this i2c bus actually leaves the Qcard, but it leaves directly
+ * via the eDP connector (it doesn't hit the baseboard). The external pulls
+ * are on Qcard.
+ */
+&qup_i2c13_data_clk {
+ /* Has external pull */
+ bias-disable;
+ drive-strength = <2>;
+};
+
+/* For mos_bt_uart */
+&qup_uart7_cts {
+ /* Configure a pull-down on CTS to match the pull of the Bluetooth module. */
+ bias-pull-down;
+};
+
+/* For mos_bt_uart */
+&qup_uart7_rts {
+ /* We'll drive RTS, so no pull */
+ bias-disable;
+ drive-strength = <2>;
+};
+
+/* For mos_bt_uart */
+&qup_uart7_tx {
+ /* We'll drive TX, so no pull */
+ bias-disable;
+ drive-strength = <2>;
+};
+
+/* For mos_bt_uart */
+&qup_uart7_rx {
+ /*
+ * Configure a pull-up on RX. This is needed to avoid
+ * garbage data when the TX pin of the Bluetooth module is
+ * in tri-state (module powered off or not driving the
+ * signal yet).
+ */
+ bias-pull-up;
+};
+
+/* eMMC, if stuffed, is straight on the Qcard */
+&sdc1_clk {
+ bias-disable;
+ drive-strength = <16>;
+};
+
+&sdc1_cmd {
+ bias-pull-up;
+ drive-strength = <10>;
+};
+
+&sdc1_data {
+ bias-pull-up;
+ drive-strength = <10>;
+};
+
+&sdc1_rclk {
+ bias-pull-down;
+};
+
+/*
+ * PINCTRL - QCARD
+ *
+ * This has entries that are defined by Qcard even if they go to the main
+ * board. In cases where the pulls may be board dependent we defer those
+ * settings to the board device tree. Drive strengths tend to be assinged here
+ * but could conceivably be overwridden by board device trees.
+ */
+
+&pm8350c_gpios {
+ pmic_edp_bl_en: pmic-edp-bl-en {
+ pins = "gpio7";
+ function = "normal";
+ bias-disable;
+ qcom,drive-strength = <PMIC_GPIO_STRENGTH_LOW>;
+
+ /* Force backlight to be disabled to match state at boot. */
+ output-low;
+ };
+
+ pmic_edp_bl_pwm: pmic-edp-bl-pwm {
+ pins = "gpio8";
+ function = "func1";
+ bias-disable;
+ qcom,drive-strength = <PMIC_GPIO_STRENGTH_LOW>;
+ output-low;
+ power-source = <0>;
+ };
+};
+
+&tlmm {
+ mos_bt_en: mos-bt-en {
+ pins = "gpio85";
+ function = "gpio";
+ drive-strength = <2>;
+ output-low;
+ };
+
+ /* For mos_bt_uart */
+ qup_uart7_sleep_cts: qup-uart7-sleep-cts {
+ pins = "gpio28";
+ function = "gpio";
+ /*
+ * Configure a pull-down on CTS to match the pull of
+ * the Bluetooth module.
+ */
+ bias-pull-down;
+ };
+
+ /* For mos_bt_uart */
+ qup_uart7_sleep_rts: qup-uart7-sleep-rts {
+ pins = "gpio29";
+ function = "gpio";
+ /*
+ * Configure pull-down on RTS. As RTS is active low
+ * signal, pull it low to indicate the BT SoC that it
+ * can wakeup the system anytime from suspend state by
+ * pulling RX low (by sending wakeup bytes).
+ */
+ bias-pull-down;
+ };
+
+ /* For mos_bt_uart */
+ qup_uart7_sleep_rx: qup-uart7-sleep-rx {
+ pins = "gpio31";
+ function = "gpio";
+ /*
+ * Configure a pull-up on RX. This is needed to avoid
+ * garbage data when the TX pin of the Bluetooth module
+ * is floating which may cause spurious wakeups.
+ */
+ bias-pull-up;
+ };
+
+ /* For mos_bt_uart */
+ qup_uart7_sleep_tx: qup-uart7-sleep-tx {
+ pins = "gpio30";
+ function = "gpio";
+ /*
+ * Configure pull-up on TX when it isn't actively driven
+ * to prevent BT SoC from receiving garbage during sleep.
+ */
+ bias-pull-up;
+ };
+
+ ts_int_conn: ts-int-conn {
+ pins = "gpio55";
+ function = "gpio";
+ bias-pull-up;
+ };
+
+ ts_rst_conn: ts-rst-conn {
+ pins = "gpio54";
+ function = "gpio";
+ bias-pull-up;
+ drive-strength = <2>;
+ };
+};
diff --git a/arch/arm64/boot/dts/qcom/sc7280.dtsi b/arch/arm64/boot/dts/qcom/sc7280.dtsi
index 937c2e0e93eb..f0b64be63c21 100644
--- a/arch/arm64/boot/dts/qcom/sc7280.dtsi
+++ b/arch/arm64/boot/dts/qcom/sc7280.dtsi
@@ -4,12 +4,14 @@
*
* Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
*/
-
+#include <dt-bindings/clock/qcom,camcc-sc7280.h>
#include <dt-bindings/clock/qcom,dispcc-sc7280.h>
#include <dt-bindings/clock/qcom,gcc-sc7280.h>
#include <dt-bindings/clock/qcom,gpucc-sc7280.h>
#include <dt-bindings/clock/qcom,rpmh.h>
#include <dt-bindings/clock/qcom,videocc-sc7280.h>
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interconnect/qcom,osm-l3.h>
#include <dt-bindings/interconnect/qcom,sc7280.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/mailbox/qcom-ipcc.h>
@@ -162,6 +164,9 @@
&LITTLE_CPU_SLEEP_1
&CLUSTER_SLEEP_0>;
next-level-cache = <&L2_0>;
+ operating-points-v2 = <&cpu0_opp_table>;
+ 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>;
#cooling-cells = <2>;
L2_0: l2-cache {
@@ -182,6 +187,9 @@
&LITTLE_CPU_SLEEP_1
&CLUSTER_SLEEP_0>;
next-level-cache = <&L2_100>;
+ operating-points-v2 = <&cpu0_opp_table>;
+ 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>;
#cooling-cells = <2>;
L2_100: l2-cache {
@@ -199,6 +207,9 @@
&LITTLE_CPU_SLEEP_1
&CLUSTER_SLEEP_0>;
next-level-cache = <&L2_200>;
+ operating-points-v2 = <&cpu0_opp_table>;
+ 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>;
#cooling-cells = <2>;
L2_200: l2-cache {
@@ -216,6 +227,9 @@
&LITTLE_CPU_SLEEP_1
&CLUSTER_SLEEP_0>;
next-level-cache = <&L2_300>;
+ operating-points-v2 = <&cpu0_opp_table>;
+ 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>;
#cooling-cells = <2>;
L2_300: l2-cache {
@@ -233,6 +247,9 @@
&BIG_CPU_SLEEP_1
&CLUSTER_SLEEP_0>;
next-level-cache = <&L2_400>;
+ operating-points-v2 = <&cpu4_opp_table>;
+ 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>;
#cooling-cells = <2>;
L2_400: l2-cache {
@@ -250,6 +267,9 @@
&BIG_CPU_SLEEP_1
&CLUSTER_SLEEP_0>;
next-level-cache = <&L2_500>;
+ operating-points-v2 = <&cpu4_opp_table>;
+ 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>;
#cooling-cells = <2>;
L2_500: l2-cache {
@@ -267,6 +287,9 @@
&BIG_CPU_SLEEP_1
&CLUSTER_SLEEP_0>;
next-level-cache = <&L2_600>;
+ operating-points-v2 = <&cpu4_opp_table>;
+ 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>;
#cooling-cells = <2>;
L2_600: l2-cache {
@@ -284,6 +307,9 @@
&BIG_CPU_SLEEP_1
&CLUSTER_SLEEP_0>;
next-level-cache = <&L2_700>;
+ operating-points-v2 = <&cpu7_opp_table>;
+ 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>;
#cooling-cells = <2>;
L2_700: l2-cache {
@@ -383,6 +409,211 @@
};
};
+ cpu0_opp_table: cpu0-opp-table {
+ compatible = "operating-points-v2";
+ opp-shared;
+
+ cpu0_opp_300mhz: opp-300000000 {
+ opp-hz = /bits/ 64 <300000000>;
+ opp-peak-kBps = <800000 9600000>;
+ };
+
+ cpu0_opp_691mhz: opp-691200000 {
+ opp-hz = /bits/ 64 <691200000>;
+ opp-peak-kBps = <800000 17817600>;
+ };
+
+ cpu0_opp_806mhz: opp-806400000 {
+ opp-hz = /bits/ 64 <806400000>;
+ opp-peak-kBps = <800000 20889600>;
+ };
+
+ cpu0_opp_941mhz: opp-940800000 {
+ opp-hz = /bits/ 64 <940800000>;
+ opp-peak-kBps = <1804000 24576000>;
+ };
+
+ cpu0_opp_1152mhz: opp-1152000000 {
+ opp-hz = /bits/ 64 <1152000000>;
+ opp-peak-kBps = <2188000 27033600>;
+ };
+
+ cpu0_opp_1325mhz: opp-1324800000 {
+ opp-hz = /bits/ 64 <1324800000>;
+ opp-peak-kBps = <2188000 33792000>;
+ };
+
+ cpu0_opp_1517mhz: opp-1516800000 {
+ opp-hz = /bits/ 64 <1516800000>;
+ opp-peak-kBps = <3072000 38092800>;
+ };
+
+ cpu0_opp_1651mhz: opp-1651200000 {
+ opp-hz = /bits/ 64 <1651200000>;
+ opp-peak-kBps = <3072000 41779200>;
+ };
+
+ cpu0_opp_1805mhz: opp-1804800000 {
+ opp-hz = /bits/ 64 <1804800000>;
+ opp-peak-kBps = <4068000 48537600>;
+ };
+
+ cpu0_opp_1958mhz: opp-1958400000 {
+ opp-hz = /bits/ 64 <1958400000>;
+ opp-peak-kBps = <4068000 48537600>;
+ };
+
+ cpu0_opp_2016mhz: opp-2016000000 {
+ opp-hz = /bits/ 64 <2016000000>;
+ opp-peak-kBps = <6220000 48537600>;
+ };
+ };
+
+ cpu4_opp_table: cpu4-opp-table {
+ compatible = "operating-points-v2";
+ opp-shared;
+
+ cpu4_opp_691mhz: opp-691200000 {
+ opp-hz = /bits/ 64 <691200000>;
+ opp-peak-kBps = <1804000 9600000>;
+ };
+
+ cpu4_opp_941mhz: opp-940800000 {
+ opp-hz = /bits/ 64 <940800000>;
+ opp-peak-kBps = <2188000 17817600>;
+ };
+
+ cpu4_opp_1229mhz: opp-1228800000 {
+ opp-hz = /bits/ 64 <1228800000>;
+ opp-peak-kBps = <4068000 24576000>;
+ };
+
+ cpu4_opp_1344mhz: opp-1344000000 {
+ opp-hz = /bits/ 64 <1344000000>;
+ opp-peak-kBps = <4068000 24576000>;
+ };
+
+ cpu4_opp_1517mhz: opp-1516800000 {
+ opp-hz = /bits/ 64 <1516800000>;
+ opp-peak-kBps = <4068000 24576000>;
+ };
+
+ cpu4_opp_1651mhz: opp-1651200000 {
+ opp-hz = /bits/ 64 <1651200000>;
+ opp-peak-kBps = <6220000 38092800>;
+ };
+
+ cpu4_opp_1901mhz: opp-1900800000 {
+ opp-hz = /bits/ 64 <1900800000>;
+ opp-peak-kBps = <6220000 44851200>;
+ };
+
+ cpu4_opp_2054mhz: opp-2054400000 {
+ opp-hz = /bits/ 64 <2054400000>;
+ opp-peak-kBps = <6220000 44851200>;
+ };
+
+ cpu4_opp_2112mhz: opp-2112000000 {
+ opp-hz = /bits/ 64 <2112000000>;
+ opp-peak-kBps = <6220000 44851200>;
+ };
+
+ cpu4_opp_2131mhz: opp-2131200000 {
+ opp-hz = /bits/ 64 <2131200000>;
+ opp-peak-kBps = <6220000 44851200>;
+ };
+
+ cpu4_opp_2208mhz: opp-2208000000 {
+ opp-hz = /bits/ 64 <2208000000>;
+ opp-peak-kBps = <6220000 44851200>;
+ };
+
+ cpu4_opp_2400mhz: opp-2400000000 {
+ opp-hz = /bits/ 64 <2400000000>;
+ opp-peak-kBps = <8532000 48537600>;
+ };
+
+ cpu4_opp_2611mhz: opp-2611200000 {
+ opp-hz = /bits/ 64 <2611200000>;
+ opp-peak-kBps = <8532000 48537600>;
+ };
+ };
+
+ cpu7_opp_table: cpu7-opp-table {
+ compatible = "operating-points-v2";
+ opp-shared;
+
+ cpu7_opp_806mhz: opp-806400000 {
+ opp-hz = /bits/ 64 <806400000>;
+ opp-peak-kBps = <1804000 9600000>;
+ };
+
+ cpu7_opp_1056mhz: opp-1056000000 {
+ opp-hz = /bits/ 64 <1056000000>;
+ opp-peak-kBps = <2188000 17817600>;
+ };
+
+ cpu7_opp_1325mhz: opp-1324800000 {
+ opp-hz = /bits/ 64 <1324800000>;
+ opp-peak-kBps = <4068000 24576000>;
+ };
+
+ cpu7_opp_1517mhz: opp-1516800000 {
+ opp-hz = /bits/ 64 <1516800000>;
+ opp-peak-kBps = <4068000 24576000>;
+ };
+
+ cpu7_opp_1766mhz: opp-1766400000 {
+ opp-hz = /bits/ 64 <1766400000>;
+ opp-peak-kBps = <6220000 38092800>;
+ };
+
+ cpu7_opp_1862mhz: opp-1862400000 {
+ opp-hz = /bits/ 64 <1862400000>;
+ opp-peak-kBps = <6220000 38092800>;
+ };
+
+ cpu7_opp_2035mhz: opp-2035200000 {
+ opp-hz = /bits/ 64 <2035200000>;
+ opp-peak-kBps = <6220000 38092800>;
+ };
+
+ cpu7_opp_2112mhz: opp-2112000000 {
+ opp-hz = /bits/ 64 <2112000000>;
+ opp-peak-kBps = <6220000 44851200>;
+ };
+
+ cpu7_opp_2208mhz: opp-2208000000 {
+ opp-hz = /bits/ 64 <2208000000>;
+ opp-peak-kBps = <6220000 44851200>;
+ };
+
+ cpu7_opp_2381mhz: opp-2380800000 {
+ opp-hz = /bits/ 64 <2380800000>;
+ opp-peak-kBps = <6832000 44851200>;
+ };
+
+ cpu7_opp_2400mhz: opp-2400000000 {
+ opp-hz = /bits/ 64 <2400000000>;
+ opp-peak-kBps = <8532000 48537600>;
+ };
+
+ cpu7_opp_2515mhz: opp-2515200000 {
+ opp-hz = /bits/ 64 <2515200000>;
+ opp-peak-kBps = <8532000 48537600>;
+ };
+
+ cpu7_opp_2707mhz: opp-2707200000 {
+ opp-hz = /bits/ 64 <2707200000>;
+ opp-peak-kBps = <8532000 48537600>;
+ };
+
+ cpu7_opp_3014mhz: opp-3014400000 {
+ opp-hz = /bits/ 64 <3014400000>;
+ opp-peak-kBps = <8532000 48537600>;
+ };
+ };
+
memory@80000000 {
device_type = "memory";
/* We expect the bootloader to fill in the size */
@@ -615,6 +846,9 @@
sdhc_1: sdhci@7c4000 {
compatible = "qcom,sc7280-sdhci", "qcom,sdhci-msm-v5";
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&sdc1_clk>, <&sdc1_cmd>, <&sdc1_data>, <&sdc1_rclk>;
+ pinctrl-1 = <&sdc1_clk_sleep>, <&sdc1_cmd_sleep>, <&sdc1_data_sleep>, <&sdc1_rclk_sleep>;
status = "disabled";
reg = <0 0x007c4000 0 0x1000>,
@@ -1714,6 +1948,8 @@
interconnect-names = "memory",
"config";
+ qcom,qmp = <&aoss_qmp>;
+
qcom,smem-states = <&ipa_smp2p_out 0>,
<&ipa_smp2p_out 1>;
qcom,smem-state-names = "ipa-clock-enabled-valid",
@@ -1790,7 +2026,7 @@
};
};
- gmu: gmu@3d69000 {
+ gmu: gmu@3d6a000 {
compatible="qcom,adreno-gmu-635.0", "qcom,adreno-gmu";
reg = <0 0x03d6a000 0 0x34000>,
<0 0x3de0000 0 0x10000>,
@@ -2424,6 +2660,9 @@
sdhc_2: sdhci@8804000 {
compatible = "qcom,sc7280-sdhci", "qcom,sdhci-msm-v5";
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&sdc2_clk>, <&sdc2_cmd>, <&sdc2_data>;
+ pinctrl-1 = <&sdc2_clk_sleep>, <&sdc2_cmd_sleep>, <&sdc2_data_sleep>;
status = "disabled";
reg = <0 0x08804000 0 0x1000>;
@@ -2761,13 +3000,31 @@
#power-domain-cells = <1>;
};
+ camcc: clock-controller@ad00000 {
+ compatible = "qcom,sc7280-camcc";
+ reg = <0 0x0ad00000 0 0x10000>;
+ clocks = <&rpmhcc RPMH_CXO_CLK>,
+ <&rpmhcc RPMH_CXO_CLK_A>,
+ <&sleep_clk>;
+ clock-names = "bi_tcxo", "bi_tcxo_ao", "sleep_clk";
+ #clock-cells = <1>;
+ #reset-cells = <1>;
+ #power-domain-cells = <1>;
+ };
+
dispcc: clock-controller@af00000 {
compatible = "qcom,sc7280-dispcc";
reg = <0 0xaf00000 0 0x20000>;
clocks = <&rpmhcc RPMH_CXO_CLK>,
<&gcc GCC_DISP_GPLL0_CLK_SRC>,
- <0>, <0>, <0>, <0>, <0>, <0>;
- clock-names = "bi_tcxo", "gcc_disp_gpll0_clk",
+ <&mdss_dsi_phy 0>,
+ <&mdss_dsi_phy 1>,
+ <&dp_phy 0>,
+ <&dp_phy 1>,
+ <&mdss_edp_phy 0>,
+ <&mdss_edp_phy 1>;
+ clock-names = "bi_tcxo",
+ "gcc_disp_gpll0_clk",
"dsi0_phy_pll_out_byteclk",
"dsi0_phy_pll_out_dsiclk",
"dp_phy_pll_link_clk",
@@ -2779,6 +3036,389 @@
#power-domain-cells = <1>;
};
+ mdss: display-subsystem@ae00000 {
+ compatible = "qcom,sc7280-mdss";
+ reg = <0 0x0ae00000 0 0x1000>;
+ reg-names = "mdss";
+
+ power-domains = <&dispcc DISP_CC_MDSS_CORE_GDSC>;
+
+ clocks = <&gcc GCC_DISP_AHB_CLK>,
+ <&dispcc DISP_CC_MDSS_AHB_CLK>,
+ <&dispcc DISP_CC_MDSS_MDP_CLK>;
+ clock-names = "iface",
+ "ahb",
+ "core";
+
+ assigned-clocks = <&dispcc DISP_CC_MDSS_MDP_CLK>;
+ assigned-clock-rates = <300000000>;
+
+ interrupts = <GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-controller;
+ #interrupt-cells = <1>;
+
+ interconnects = <&mmss_noc MASTER_MDP0 0 &mc_virt SLAVE_EBI1 0>;
+ interconnect-names = "mdp0-mem";
+
+ iommus = <&apps_smmu 0x900 0x402>;
+
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ status = "disabled";
+
+ mdss_mdp: display-controller@ae01000 {
+ compatible = "qcom,sc7280-dpu";
+ reg = <0 0x0ae01000 0 0x8f030>,
+ <0 0x0aeb0000 0 0x2008>;
+ reg-names = "mdp", "vbif";
+
+ clocks = <&gcc GCC_DISP_HF_AXI_CLK>,
+ <&gcc GCC_DISP_SF_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 = "bus",
+ "nrt_bus",
+ "iface",
+ "lut",
+ "core",
+ "vsync";
+ assigned-clocks = <&dispcc DISP_CC_MDSS_MDP_CLK>,
+ <&dispcc DISP_CC_MDSS_VSYNC_CLK>,
+ <&dispcc DISP_CC_MDSS_AHB_CLK>;
+ assigned-clock-rates = <300000000>,
+ <19200000>,
+ <19200000>;
+ operating-points-v2 = <&mdp_opp_table>;
+ power-domains = <&rpmhpd SC7280_CX>;
+
+ interrupt-parent = <&mdss>;
+ interrupts = <0>;
+
+ status = "disabled";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+ dpu_intf1_out: endpoint {
+ remote-endpoint = <&dsi0_in>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+ dpu_intf5_out: endpoint {
+ remote-endpoint = <&edp_in>;
+ };
+ };
+
+ port@2 {
+ reg = <2>;
+ dpu_intf0_out: endpoint {
+ remote-endpoint = <&dp_in>;
+ };
+ };
+ };
+
+ mdp_opp_table: opp-table {
+ compatible = "operating-points-v2";
+
+ opp-200000000 {
+ opp-hz = /bits/ 64 <200000000>;
+ required-opps = <&rpmhpd_opp_low_svs>;
+ };
+
+ opp-300000000 {
+ opp-hz = /bits/ 64 <300000000>;
+ required-opps = <&rpmhpd_opp_svs>;
+ };
+
+ opp-380000000 {
+ opp-hz = /bits/ 64 <380000000>;
+ required-opps = <&rpmhpd_opp_svs_l1>;
+ };
+
+ opp-506666667 {
+ opp-hz = /bits/ 64 <506666667>;
+ required-opps = <&rpmhpd_opp_nom>;
+ };
+ };
+ };
+
+ mdss_dsi: dsi@ae94000 {
+ compatible = "qcom,mdss-dsi-ctrl";
+ reg = <0 0x0ae94000 0 0x400>;
+ reg-names = "dsi_ctrl";
+
+ interrupt-parent = <&mdss>;
+ interrupts = <4>;
+
+ clocks = <&dispcc DISP_CC_MDSS_BYTE0_CLK>,
+ <&dispcc DISP_CC_MDSS_BYTE0_INTF_CLK>,
+ <&dispcc DISP_CC_MDSS_PCLK0_CLK>,
+ <&dispcc DISP_CC_MDSS_ESC0_CLK>,
+ <&dispcc DISP_CC_MDSS_AHB_CLK>,
+ <&gcc GCC_DISP_HF_AXI_CLK>;
+ clock-names = "byte",
+ "byte_intf",
+ "pixel",
+ "core",
+ "iface",
+ "bus";
+
+ operating-points-v2 = <&dsi_opp_table>;
+ power-domains = <&rpmhpd SC7280_CX>;
+
+ phys = <&mdss_dsi_phy>;
+ phy-names = "dsi";
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ status = "disabled";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+ dsi0_in: endpoint {
+ remote-endpoint = <&dpu_intf1_out>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+ dsi0_out: endpoint {
+ };
+ };
+ };
+
+ dsi_opp_table: opp-table {
+ compatible = "operating-points-v2";
+
+ opp-187500000 {
+ opp-hz = /bits/ 64 <187500000>;
+ required-opps = <&rpmhpd_opp_low_svs>;
+ };
+
+ opp-300000000 {
+ opp-hz = /bits/ 64 <300000000>;
+ required-opps = <&rpmhpd_opp_svs>;
+ };
+
+ opp-358000000 {
+ opp-hz = /bits/ 64 <358000000>;
+ required-opps = <&rpmhpd_opp_svs_l1>;
+ };
+ };
+ };
+
+ mdss_dsi_phy: phy@ae94400 {
+ compatible = "qcom,sc7280-dsi-phy-7nm";
+ reg = <0 0x0ae94400 0 0x200>,
+ <0 0x0ae94600 0 0x280>,
+ <0 0x0ae94900 0 0x280>;
+ reg-names = "dsi_phy",
+ "dsi_phy_lane",
+ "dsi_pll";
+
+ #clock-cells = <1>;
+ #phy-cells = <0>;
+
+ clocks = <&dispcc DISP_CC_MDSS_AHB_CLK>,
+ <&rpmhcc RPMH_CXO_CLK>;
+ clock-names = "iface", "ref";
+
+ status = "disabled";
+ };
+
+ mdss_edp: edp@aea0000 {
+ compatible = "qcom,sc7280-edp";
+ pinctrl-names = "default";
+ pinctrl-0 = <&edp_hot_plug_det>;
+
+ reg = <0 0xaea0000 0 0x200>,
+ <0 0xaea0200 0 0x200>,
+ <0 0xaea0400 0 0xc00>,
+ <0 0xaea1000 0 0x400>;
+
+ interrupt-parent = <&mdss>;
+ interrupts = <14>;
+
+ clocks = <&rpmhcc RPMH_CXO_CLK>,
+ <&gcc GCC_EDP_CLKREF_EN>,
+ <&dispcc DISP_CC_MDSS_AHB_CLK>,
+ <&dispcc DISP_CC_MDSS_EDP_AUX_CLK>,
+ <&dispcc DISP_CC_MDSS_EDP_LINK_CLK>,
+ <&dispcc DISP_CC_MDSS_EDP_LINK_INTF_CLK>,
+ <&dispcc DISP_CC_MDSS_EDP_PIXEL_CLK>;
+ clock-names = "core_xo",
+ "core_ref",
+ "core_iface",
+ "core_aux",
+ "ctrl_link",
+ "ctrl_link_iface",
+ "stream_pixel";
+ #clock-cells = <1>;
+ assigned-clocks = <&dispcc DISP_CC_MDSS_EDP_LINK_CLK_SRC>,
+ <&dispcc DISP_CC_MDSS_EDP_PIXEL_CLK_SRC>;
+ assigned-clock-parents = <&mdss_edp_phy 0>, <&mdss_edp_phy 1>;
+
+ phys = <&mdss_edp_phy>;
+ phy-names = "dp";
+
+ operating-points-v2 = <&edp_opp_table>;
+ power-domains = <&rpmhpd SC7280_CX>;
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ status = "disabled";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+ edp_in: endpoint {
+ remote-endpoint = <&dpu_intf5_out>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+ edp_out: endpoint { };
+ };
+ };
+
+ edp_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_nom>;
+ };
+
+ opp-810000000 {
+ opp-hz = /bits/ 64 <810000000>;
+ required-opps = <&rpmhpd_opp_nom>;
+ };
+ };
+ };
+
+ mdss_edp_phy: phy@aec2a00 {
+ compatible = "qcom,sc7280-edp-phy";
+
+ reg = <0 0xaec2a00 0 0x19c>,
+ <0 0xaec2200 0 0xa0>,
+ <0 0xaec2600 0 0xa0>,
+ <0 0xaec2000 0 0x1c0>;
+
+ clocks = <&rpmhcc RPMH_CXO_CLK>,
+ <&gcc GCC_EDP_CLKREF_EN>;
+ clock-names = "aux",
+ "cfg_ahb";
+
+ #clock-cells = <1>;
+ #phy-cells = <0>;
+
+ status = "disabled";
+ };
+
+ mdss_dp: displayport-controller@ae90000 {
+ compatible = "qcom,sc7280-dp";
+
+ reg = <0 0x0ae90000 0 0x1400>;
+
+ interrupt-parent = <&mdss>;
+ interrupts = <12>;
+
+ clocks = <&dispcc DISP_CC_MDSS_AHB_CLK>,
+ <&dispcc DISP_CC_MDSS_DP_AUX_CLK>,
+ <&dispcc DISP_CC_MDSS_DP_LINK_CLK>,
+ <&dispcc DISP_CC_MDSS_DP_LINK_INTF_CLK>,
+ <&dispcc DISP_CC_MDSS_DP_PIXEL_CLK>;
+ clock-names = "core_iface",
+ "core_aux",
+ "ctrl_link",
+ "ctrl_link_iface",
+ "stream_pixel";
+ #clock-cells = <1>;
+ assigned-clocks = <&dispcc DISP_CC_MDSS_DP_LINK_CLK_SRC>,
+ <&dispcc DISP_CC_MDSS_DP_PIXEL_CLK_SRC>;
+ assigned-clock-parents = <&dp_phy 0>, <&dp_phy 1>;
+ phys = <&dp_phy>;
+ phy-names = "dp";
+
+ operating-points-v2 = <&dp_opp_table>;
+ power-domains = <&rpmhpd SC7280_CX>;
+
+ #sound-dai-cells = <0>;
+
+ status = "disabled";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+ dp_in: endpoint {
+ remote-endpoint = <&dpu_intf0_out>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+ dp_out: endpoint { };
+ };
+ };
+
+ dp_opp_table: opp-table {
+ compatible = "operating-points-v2";
+
+ opp-160000000 {
+ opp-hz = /bits/ 64 <160000000>;
+ required-opps = <&rpmhpd_opp_low_svs>;
+ };
+
+ opp-270000000 {
+ opp-hz = /bits/ 64 <270000000>;
+ required-opps = <&rpmhpd_opp_svs>;
+ };
+
+ opp-540000000 {
+ opp-hz = /bits/ 64 <540000000>;
+ required-opps = <&rpmhpd_opp_svs_l1>;
+ };
+
+ opp-810000000 {
+ opp-hz = /bits/ 64 <810000000>;
+ required-opps = <&rpmhpd_opp_nom>;
+ };
+ };
+ };
+ };
+
pdc: interrupt-controller@b220000 {
compatible = "qcom,sc7280-pdc", "qcom,pdc";
reg = <0 0x0b220000 0 0x30000>;
@@ -2872,11 +3512,19 @@
gpio-ranges = <&tlmm 0 0 175>;
wakeup-parent = <&pdc>;
+ dp_hot_plug_det: dp-hot-plug-det {
+ pins = "gpio47";
+ function = "dp_hot";
+ };
+
+ edp_hot_plug_det: edp-hot-plug-det {
+ pins = "gpio60";
+ function = "edp_hot";
+ };
+
pcie1_clkreq_n: pcie1-clkreq-n {
pins = "gpio79";
function = "pcie1_clkreqn";
- drive-strength = <2>;
- bias-pull-up;
};
qspi_clk: qspi-clk {
@@ -3384,83 +4032,6 @@
function = "qup07";
};
- sdc1_on: sdc1-on {
- clk {
- pins = "sdc1_clk";
- };
-
- cmd {
- pins = "sdc1_cmd";
- };
-
- data {
- pins = "sdc1_data";
- };
-
- rclk {
- pins = "sdc1_rclk";
- };
- };
-
- sdc1_off: sdc1-off {
- clk {
- pins = "sdc1_clk";
- drive-strength = <2>;
- bias-bus-hold;
- };
-
- cmd {
- pins = "sdc1_cmd";
- drive-strength = <2>;
- bias-bus-hold;
- };
-
- data {
- pins = "sdc1_data";
- drive-strength = <2>;
- bias-bus-hold;
- };
-
- rclk {
- pins = "sdc1_rclk";
- bias-bus-hold;
- };
- };
-
- sdc2_on: sdc2-on {
- clk {
- pins = "sdc2_clk";
- };
-
- cmd {
- pins = "sdc2_cmd";
- };
-
- data {
- pins = "sdc2_data";
- };
- };
-
- sdc2_off: sdc2-off {
- clk {
- pins = "sdc2_clk";
- drive-strength = <2>;
- bias-bus-hold;
- };
-
- cmd {
- pins ="sdc2_cmd";
- drive-strength = <2>;
- bias-bus-hold;
- };
-
- data {
- pins ="sdc2_data";
- drive-strength = <2>;
- bias-bus-hold;
- };
- };
-
qup_uart8_cts: qup-uart8-cts {
pins = "gpio32";
function = "qup10";
@@ -3620,6 +4191,76 @@
pins = "gpio63";
function = "qup17";
};
+
+ sdc1_clk: sdc1-clk {
+ pins = "sdc1_clk";
+ };
+
+ sdc1_cmd: sdc1-cmd {
+ pins = "sdc1_cmd";
+ };
+
+ sdc1_data: sdc1-data {
+ pins = "sdc1_data";
+ };
+
+ sdc1_rclk: sdc1-rclk {
+ pins = "sdc1_rclk";
+ };
+
+ sdc1_clk_sleep: sdc1-clk-sleep {
+ pins = "sdc1_clk";
+ drive-strength = <2>;
+ bias-bus-hold;
+ };
+
+ sdc1_cmd_sleep: sdc1-cmd-sleep {
+ pins = "sdc1_cmd";
+ drive-strength = <2>;
+ bias-bus-hold;
+ };
+
+ sdc1_data_sleep: sdc1-data-sleep {
+ pins = "sdc1_data";
+ drive-strength = <2>;
+ bias-bus-hold;
+ };
+
+ sdc1_rclk_sleep: sdc1-rclk-sleep {
+ pins = "sdc1_rclk";
+ drive-strength = <2>;
+ bias-bus-hold;
+ };
+
+ sdc2_clk: sdc2-clk {
+ pins = "sdc2_clk";
+ };
+
+ sdc2_cmd: sdc2-cmd {
+ pins = "sdc2_cmd";
+ };
+
+ sdc2_data: sdc2-data {
+ pins = "sdc2_data";
+ };
+
+ sdc2_clk_sleep: sdc2-clk-sleep {
+ pins = "sdc2_clk";
+ drive-strength = <2>;
+ bias-bus-hold;
+ };
+
+ sdc2_cmd_sleep: sdc2-cmd-sleep {
+ pins = "sdc2_cmd";
+ drive-strength = <2>;
+ bias-bus-hold;
+ };
+
+ sdc2_data_sleep: sdc2-data-sleep {
+ pins = "sdc2_data";
+ drive-strength = <2>;
+ bias-bus-hold;
+ };
};
imem@146a5000 {
@@ -3885,6 +4526,14 @@
};
};
+ epss_l3: interconnect@18590000 {
+ compatible = "qcom,sc7280-epss-l3";
+ reg = <0 0x18590000 0 0x1000>;
+ clocks = <&rpmhcc RPMH_CXO_CLK>, <&gcc GCC_GPLL0>;
+ clock-names = "xo", "alternate";
+ #interconnect-cells = <1>;
+ };
+
cpufreq_hw: cpufreq@18591000 {
compatible = "qcom,cpufreq-epss";
reg = <0 0x18591000 0 0x1000>,
diff --git a/arch/arm64/boot/dts/qcom/sdm630.dtsi b/arch/arm64/boot/dts/qcom/sdm630.dtsi
index 9217c3a51f79..240293592ef9 100644
--- a/arch/arm64/boot/dts/qcom/sdm630.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm630.dtsi
@@ -2160,7 +2160,7 @@
apr {
compatible = "qcom,apr-v2";
qcom,glink-channels = "apr_audio_svc";
- qcom,apr-domain = <APR_DOMAIN_ADSP>;
+ qcom,domain = <APR_DOMAIN_ADSP>;
#address-cells = <1>;
#size-cells = <0>;
diff --git a/arch/arm64/boot/dts/qcom/sdm632-fairphone-fp3.dts b/arch/arm64/boot/dts/qcom/sdm632-fairphone-fp3.dts
new file mode 100644
index 000000000000..8b815b2a60a7
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sdm632-fairphone-fp3.dts
@@ -0,0 +1,183 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2022, Luca Weiss <luca@z3ntu.xyz>
+ */
+/dts-v1/;
+
+#include "sdm632.dtsi"
+#include "pm8953.dtsi"
+
+/ {
+ model = "Fairphone 3";
+ compatible = "fairphone,fp3", "qcom,sdm632";
+ chassis-type = "handset";
+ qcom,msm-id = <349 0>;
+ qcom,board-id = <8 0x10000>;
+
+ aliases {
+ mmc0 = &sdhc_1;
+ mmc1 = &sdhc_2;
+ serial0 = &uart_0;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+
+ volume-up {
+ label = "volume_up";
+ linux,code = <KEY_VOLUMEUP>;
+ gpios = <&tlmm 85 GPIO_ACTIVE_LOW>;
+ };
+ };
+
+ vph_pwr: vph-pwr-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "vph_pwr";
+ regulator-always-on;
+ regulator-boot-on;
+ };
+};
+
+&hsusb_phy {
+ status = "okay";
+ vdd-supply = <&pm8953_l3>;
+ vdda-pll-supply = <&pm8953_l7>;
+ vdda-phy-dpdm-supply = <&pm8953_l13>;
+};
+
+&pm8953_resin {
+ status = "okay";
+ linux,code = <KEY_VOLUMEDOWN>;
+};
+
+&sdhc_1 {
+ status = "okay";
+ vmmc-supply = <&pm8953_l8>;
+ vqmmc-supply = <&pm8953_l5>;
+};
+
+&sdhc_2 {
+ status = "okay";
+ vmmc-supply = <&pm8953_l11>;
+ vqmmc-supply = <&pm8953_l12>;
+
+ cd-gpios = <&tlmm 133 GPIO_ACTIVE_LOW>;
+};
+
+&rpm_requests {
+ pm8953-regulators {
+ compatible = "qcom,rpm-pm8953-regulators";
+
+ vdd_l1-supply = <&pm8953_s3>;
+ vdd_l2_l3-supply = <&pm8953_s3>;
+ vdd_l4_l5_l6_l7_l16_l19-supply = <&pm8953_s4>;
+ vdd_l8_l11_l12_l13_l14_l15-supply = <&vph_pwr>;
+ vdd_l9_l10_l17_l18_l22-supply = <&vph_pwr>;
+
+ pm8953_s3: s3 {
+ regulator-min-microvolt = <984000>;
+ regulator-max-microvolt = <1240000>;
+ };
+ pm8953_s4: s4 {
+ regulator-min-microvolt = <1036000>;
+ regulator-max-microvolt = <2040000>;
+ };
+ pm8953_s5: s5 {
+ regulator-min-microvolt = <1036000>;
+ regulator-max-microvolt = <2040000>;
+ };
+
+ pm8953_l1: l1 {
+ regulator-min-microvolt = <975000>;
+ regulator-max-microvolt = <1050000>;
+ };
+ pm8953_l2: l2 {
+ regulator-min-microvolt = <975000>;
+ regulator-max-microvolt = <1175000>;
+ };
+ pm8953_l3: l3 {
+ regulator-min-microvolt = <925000>;
+ regulator-max-microvolt = <925000>;
+ };
+ pm8953_l5: l5 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+ pm8953_l6: l6 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+ pm8953_l7: l7 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1900000>;
+ };
+ pm8953_l8: l8 {
+ regulator-min-microvolt = <2900000>;
+ regulator-max-microvolt = <2900000>;
+ };
+ pm8953_l9: l9 {
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3300000>;
+ };
+ pm8953_l10: l10 {
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <3000000>;
+ };
+ pm8953_l11: l11 {
+ regulator-min-microvolt = <2950000>;
+ regulator-max-microvolt = <2950000>;
+ };
+ pm8953_l12: l12 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <2950000>;
+ };
+ pm8953_l13: l13 {
+ regulator-min-microvolt = <3125000>;
+ regulator-max-microvolt = <3125000>;
+ };
+ pm8953_l16: l16 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+ pm8953_l17: l17 {
+ regulator-min-microvolt = <2850000>;
+ regulator-max-microvolt = <2850000>;
+ };
+ pm8953_l19: l19 {
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1350000>;
+ };
+ pm8953_l22: l22 {
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ };
+ pm8953_l23: l23 {
+ regulator-min-microvolt = <975000>;
+ regulator-max-microvolt = <1225000>;
+ };
+ };
+};
+
+&tlmm {
+ /*
+ * 0-3: unused but protected by TZ
+ * 135-138: fingerprint reader (SPI)
+ */
+ gpio-reserved-ranges = <0 4>, <135 4>;
+};
+
+&uart_0 {
+ status = "okay";
+};
+
+&usb3 {
+ status = "okay";
+};
+
+&usb3_dwc3 {
+ dr_mode = "peripheral";
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm632.dtsi b/arch/arm64/boot/dts/qcom/sdm632.dtsi
new file mode 100644
index 000000000000..645b9f6a801f
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sdm632.dtsi
@@ -0,0 +1,81 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/* Copyright (c) 2022, The Linux Foundation. All rights reserved. */
+
+#include "msm8953.dtsi"
+
+/ {
+ thermal-zones {
+ /delete-node/cpu1-thermal;
+ /delete-node/cpu2-thermal;
+ /delete-node/cpu3-thermal;
+
+ cpu0-thermal {
+ thermal-sensors = <&tsens0 13>;
+
+ cooling-maps {
+ map0 {
+ cooling-device = <&CPU0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+ <&CPU1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+ <&CPU2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+ <&CPU3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
+ };
+
+ cpu4-thermal {
+ thermal-sensors = <&tsens0 5>;
+ };
+
+ cpu5-thermal {
+ thermal-sensors = <&tsens0 6>;
+ };
+
+ cpu6-thermal {
+ thermal-sensors = <&tsens0 7>;
+ };
+
+ cpu7-thermal {
+ thermal-sensors = <&tsens0 8>;
+ };
+ };
+};
+
+/*
+ * SDM632 uses Kryo 250 instead of Cortex A53
+ * CPU0-3 are efficiency cores, CPU4-7 are performance cores
+ */
+&CPU0 {
+ compatible = "qcom,kryo250";
+};
+
+&CPU1 {
+ compatible = "qcom,kryo250";
+};
+
+&CPU2 {
+ compatible = "qcom,kryo250";
+};
+
+&CPU3 {
+ compatible = "qcom,kryo250";
+};
+
+&CPU4 {
+ compatible = "qcom,kryo250";
+ capacity-dmips-mhz = <1980>;
+};
+
+&CPU5 {
+ compatible = "qcom,kryo250";
+ capacity-dmips-mhz = <1980>;
+};
+
+&CPU6 {
+ compatible = "qcom,kryo250";
+ capacity-dmips-mhz = <1980>;
+};
+
+&CPU7 {
+ compatible = "qcom,kryo250";
+ capacity-dmips-mhz = <1980>;
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm845-cheza.dtsi b/arch/arm64/boot/dts/qcom/sdm845-cheza.dtsi
index 4a6285a25f77..e7e4cc5936aa 100644
--- a/arch/arm64/boot/dts/qcom/sdm845-cheza.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm845-cheza.dtsi
@@ -708,7 +708,7 @@ ap_ts_i2c: &i2c14 {
pinctrl-0 = <&ec_ap_int_l>;
spi-max-frequency = <3000000>;
- cros_ec_pwm: ec-pwm {
+ cros_ec_pwm: pwm {
compatible = "google,cros-ec-pwm";
#pwm-cells = <1>;
};
diff --git a/arch/arm64/boot/dts/qcom/sdm845-db845c.dts b/arch/arm64/boot/dts/qcom/sdm845-db845c.dts
index 13f80a0b6faa..28fe45c5d516 100644
--- a/arch/arm64/boot/dts/qcom/sdm845-db845c.dts
+++ b/arch/arm64/boot/dts/qcom/sdm845-db845c.dts
@@ -425,6 +425,10 @@
status = "okay";
};
+&gpi_dma0 {
+ status = "okay";
+};
+
&gpu {
status = "okay";
zap-shader {
@@ -1125,7 +1129,6 @@
port@0 {
reg = <0>;
csiphy0_ep: endpoint {
- clock-lanes = <7>;
data-lanes = <0 1 2 3>;
remote-endpoint = <&ov8856_ep>;
};
@@ -1166,7 +1169,6 @@
port {
ov8856_ep: endpoint {
- clock-lanes = <1>;
link-frequencies = /bits/ 64
<360000000 180000000>;
data-lanes = <1 2 3 4>;
@@ -1211,7 +1213,6 @@
port {
ov7251_ep: endpoint {
- clock-lanes = <1>;
data-lanes = <0 1>;
// remote-endpoint = <&csiphy3_ep>;
};
diff --git a/arch/arm64/boot/dts/qcom/sdm845-oneplus-common.dtsi b/arch/arm64/boot/dts/qcom/sdm845-oneplus-common.dtsi
index 7f42e5315ecb..1084d5ce9ac7 100644
--- a/arch/arm64/boot/dts/qcom/sdm845-oneplus-common.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm845-oneplus-common.dtsi
@@ -54,7 +54,7 @@
* it is otherwise possible for an allocation adjacent to the
* rmtfs_mem region to trigger an XPU violation, causing a crash.
*/
- rmtfs_lower_guard: memory@f5b00000 {
+ rmtfs_lower_guard: rmtfs-lower-guard@f5b00000 {
no-map;
reg = <0 0xf5b00000 0 0x1000>;
};
@@ -63,7 +63,7 @@
* but given the same address every time. Hard code it as this address is
* where the modem firmware expects it to be.
*/
- rmtfs_mem: memory@f5b01000 {
+ rmtfs_mem: rmtfs-mem@f5b01000 {
compatible = "qcom,rmtfs-mem";
reg = <0 0xf5b01000 0 0x200000>;
no-map;
@@ -71,7 +71,7 @@
qcom,client-id = <1>;
qcom,vmid = <15>;
};
- rmtfs_upper_guard: memory@f5d01000 {
+ rmtfs_upper_guard: rmtfs-upper-guard@f5d01000 {
no-map;
reg = <0 0xf5d01000 0 0x1000>;
};
@@ -80,7 +80,7 @@
* It seems like reserving the old rmtfs_mem region is also needed to prevent
* random crashes which are most likely modem related, more testing needed.
*/
- removed_region: memory@88f00000 {
+ removed_region: removed-region@88f00000 {
no-map;
reg = <0 0x88f00000 0 0x1c00000>;
};
@@ -376,6 +376,17 @@
};
};
+&i2c10 {
+ status = "okay";
+ clock-frequency = <100000>;
+
+ bq27441_fg: bq27441-battery@55 {
+ compatible = "ti,bq27411";
+ status = "okay";
+ reg = <0x55>;
+ };
+};
+
&i2c12 {
status = "okay";
clock-frequency = <400000>;
diff --git a/arch/arm64/boot/dts/qcom/sdm845-oneplus-enchilada.dts b/arch/arm64/boot/dts/qcom/sdm845-oneplus-enchilada.dts
index 5936b47dee5f..bf2cf92e8976 100644
--- a/arch/arm64/boot/dts/qcom/sdm845-oneplus-enchilada.dts
+++ b/arch/arm64/boot/dts/qcom/sdm845-oneplus-enchilada.dts
@@ -13,6 +13,14 @@
chassis-type = "handset";
qcom,msm-id = <0x141 0x20001>;
qcom,board-id = <8 0 17819 22>;
+
+ battery: battery {
+ compatible = "simple-battery";
+
+ charge-full-design-microamp-hours = <3300000>;
+ voltage-min-design-microvolt = <3400000>;
+ voltage-max-design-microvolt = <4400000>;
+ };
};
&display_panel {
@@ -20,3 +28,7 @@
compatible = "samsung,sofef00";
};
+
+&bq27441_fg {
+ monitored-battery = <&battery>;
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm845-oneplus-fajita.dts b/arch/arm64/boot/dts/qcom/sdm845-oneplus-fajita.dts
index 78a0b99144e6..1b6b5bf368df 100644
--- a/arch/arm64/boot/dts/qcom/sdm845-oneplus-fajita.dts
+++ b/arch/arm64/boot/dts/qcom/sdm845-oneplus-fajita.dts
@@ -13,6 +13,14 @@
chassis-type = "handset";
qcom,msm-id = <0x141 0x20001>;
qcom,board-id = <8 0 18801 41>;
+
+ battery: battery {
+ compatible = "simple-battery";
+
+ charge-full-design-microamp-hours = <3700000>;
+ voltage-min-design-microvolt = <3400000>;
+ voltage-max-design-microvolt = <4400000>;
+ };
};
&display_panel {
@@ -21,6 +29,10 @@
compatible = "samsung,s6e3fc2x01";
};
+&bq27441_fg {
+ monitored-battery = <&battery>;
+};
+
&rmi4_f12 {
touchscreen-y-mm = <148>;
};
diff --git a/arch/arm64/boot/dts/qcom/sdm845-shift-axolotl.dts b/arch/arm64/boot/dts/qcom/sdm845-shift-axolotl.dts
new file mode 100644
index 000000000000..8553c8bf79bd
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sdm845-shift-axolotl.dts
@@ -0,0 +1,736 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2022, Alexander Martinz <amartinz@shiftphones.com>
+ * Copyright (c) 2022, Caleb Connolly <caleb@connolly.tech>
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/regulator/qcom,rpmh-regulator.h>
+#include "sdm845.dtsi"
+#include "pm8998.dtsi"
+#include "pmi8998.dtsi"
+
+/ {
+ model = "SHIFT SHIFT6mq";
+ compatible = "shift,axolotl", "qcom,sdm845";
+ qcom,msm-id = <321 0x20001>;
+ qcom,board-id = <11 0>;
+
+ aliases {
+ display0 = &framebuffer0;
+ serial0 = &uart9;
+ };
+
+ chosen {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ stdout-path = "serial0";
+
+ /* Use framebuffer setup by the bootloader. */
+ framebuffer0: framebuffer@9d400000 {
+ compatible = "simple-framebuffer";
+ reg = <0x0 0x9d400000 0x0 (1080 * 2160 * 4)>;
+ width = <1080>;
+ height = <2160>;
+ stride = <(1080 * 4)>;
+ format = "a8r8g8b8";
+ };
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+ autorepeat;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&volume_up_gpio>;
+
+ vol-up {
+ label = "volume_up";
+ linux,code = <KEY_VOLUMEUP>;
+ gpios = <&pm8998_gpio 6 GPIO_ACTIVE_LOW>;
+ debounce-interval = <15>;
+ };
+ };
+
+ reserved-memory {
+ framebuffer_region@9d400000 {
+ reg = <0x0 0x9d400000 0x0 (1080 * 2160 * 4)>;
+ no-map;
+ };
+
+ ramoops: ramoops@b0000000 {
+ compatible = "ramoops";
+ reg = <0 0xb0000000 0 0x00400000>;
+ record-size = <0x40000>;
+ console-size = <0x40000>;
+ ftrace-size = <0x40000>;
+ pmsg-size = <0x200000>;
+ ecc-size = <0x0>;
+ };
+ };
+
+ battery: battery {
+ compatible = "simple-battery";
+
+ charge-full-design-microamp-hours = <3850000>;
+ voltage-min-design-microvolt = <3600000>;
+ voltage-max-design-microvolt = <4400000>;
+ };
+
+ vph_pwr: vph-pwr-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "vph_pwr";
+ regulator-min-microvolt = <3700000>;
+ regulator-max-microvolt = <3700000>;
+ };
+
+ vreg_s4a_1p8: pm8998-smps4 {
+ compatible = "regulator-fixed";
+ regulator-name = "vreg_s4a_1p8";
+
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+
+ regulator-always-on;
+ regulator-boot-on;
+
+ vin-supply = <&vph_pwr>;
+ };
+};
+
+&adsp_pas {
+ status = "okay";
+ firmware-name = "qcom/sdm845/axolotl/adsp.mbn";
+};
+
+&apps_rsc {
+ pm8998-rpmh-regulators {
+ compatible = "qcom,pm8998-rpmh-regulators";
+ qcom,pmic-id = "a";
+
+ vdd-s1-supply = <&vph_pwr>;
+ vdd-s2-supply = <&vph_pwr>;
+ vdd-s3-supply = <&vph_pwr>;
+ vdd-s4-supply = <&vph_pwr>;
+ vdd-s5-supply = <&vph_pwr>;
+ vdd-s6-supply = <&vph_pwr>;
+ vdd-s7-supply = <&vph_pwr>;
+ vdd-s8-supply = <&vph_pwr>;
+ vdd-s9-supply = <&vph_pwr>;
+ vdd-s10-supply = <&vph_pwr>;
+ vdd-s11-supply = <&vph_pwr>;
+ vdd-s12-supply = <&vph_pwr>;
+ vdd-s13-supply = <&vph_pwr>;
+ vdd-l1-l27-supply = <&vreg_s7a_1p025>;
+ vdd-l2-l8-l17-supply = <&vreg_s3a_1p35>;
+ vdd-l3-l11-supply = <&vreg_s7a_1p025>;
+ vdd-l4-l5-supply = <&vreg_s7a_1p025>;
+ vdd-l6-supply = <&vph_pwr>;
+ vdd-l7-l12-l14-l15-supply = <&vreg_s5a_2p04>;
+ vdd-l9-supply = <&vreg_bob>;
+ vdd-l10-l23-l25-supply = <&vreg_bob>;
+ vdd-l13-l19-l21-supply = <&vreg_bob>;
+ vdd-l16-l28-supply = <&vreg_bob>;
+ vdd-l18-l22-supply = <&vreg_bob>;
+ vdd-l20-l24-supply = <&vreg_bob>;
+ vdd-l26-supply = <&vreg_s3a_1p35>;
+ vin-lvs-1-2-supply = <&vreg_s4a_1p8>;
+
+ vreg_s2a_1p125: smps2 {
+ regulator-min-microvolt = <1100000>;
+ regulator-max-microvolt = <1100000>;
+ };
+
+ vreg_s3a_1p35: smps3 {
+ regulator-min-microvolt = <1352000>;
+ regulator-max-microvolt = <1352000>;
+ };
+
+ vreg_s5a_2p04: smps5 {
+ regulator-min-microvolt = <1904000>;
+ regulator-max-microvolt = <2040000>;
+ };
+
+ vreg_s7a_1p025: smps7 {
+ regulator-min-microvolt = <900000>;
+ regulator-max-microvolt = <1028000>;
+ };
+
+ vdd_qusb_hs0:
+ vdda_hp_pcie_core:
+ vdda_mipi_csi0_0p9:
+ vdda_mipi_csi1_0p9:
+ vdda_mipi_csi2_0p9:
+ vdda_mipi_dsi0_pll:
+ vdda_mipi_dsi1_pll:
+ vdda_qlink_lv:
+ vdda_qlink_lv_ck:
+ vdda_qrefs_0p875:
+ vdda_pcie_core:
+ vdda_pll_cc_ebi01:
+ vdda_pll_cc_ebi23:
+ vdda_sp_sensor:
+ vdda_ufs1_core:
+ vdda_ufs2_core:
+ vdda_usb1_ss_core:
+ vdda_usb2_ss_core:
+ vreg_l1a_0p875: ldo1 {
+ regulator-min-microvolt = <880000>;
+ regulator-max-microvolt = <880000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vddpx_10:
+ vreg_l2a_1p2: ldo2 {
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ regulator-always-on;
+ };
+
+ vreg_l3a_1p0: ldo3 {
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1000000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vdd_wcss_cx:
+ vdd_wcss_mx:
+ vdda_wcss_pll:
+ vreg_l5a_0p8: ldo5 {
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <800000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vddpx_13:
+ vreg_l6a_1p8: ldo6 {
+ regulator-min-microvolt = <1856000>;
+ regulator-max-microvolt = <1856000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l7a_1p8: ldo7 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l8a_1p2: ldo8 {
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1248000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l9a_1p8: ldo9 {
+ regulator-min-microvolt = <1704000>;
+ regulator-max-microvolt = <2928000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l10a_1p8: ldo10 {
+ regulator-min-microvolt = <1704000>;
+ regulator-max-microvolt = <2928000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l11a_1p0: ldo11 {
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1048000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vdd_qfprom:
+ vdd_qfprom_sp:
+ vdda_apc1_cs_1p8:
+ vdda_gfx_cs_1p8:
+ vdda_qrefs_1p8:
+ vdda_qusb_hs0_1p8:
+ vddpx_11:
+ vreg_l12a_1p8: ldo12 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vddpx_2:
+ vreg_l13a_2p95: ldo13 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <2960000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l14a_1p88: ldo14 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l15a_1p8: ldo15 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l16a_2p7: ldo16 {
+ regulator-min-microvolt = <2704000>;
+ regulator-max-microvolt = <2704000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l17a_1p3: ldo17 {
+ regulator-min-microvolt = <1304000>;
+ regulator-max-microvolt = <1304000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l18a_2p7: ldo18 {
+ regulator-min-microvolt = <2704000>;
+ regulator-max-microvolt = <2960000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l19a_3p0: ldo19 {
+ regulator-min-microvolt = <2856000>;
+ regulator-max-microvolt = <3104000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l20a_2p95: ldo20 {
+ regulator-min-microvolt = <2704000>;
+ regulator-max-microvolt = <2960000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l21a_2p95: ldo21 {
+ regulator-min-microvolt = <2704000>;
+ regulator-max-microvolt = <2960000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l22a_2p85: ldo22 {
+ regulator-min-microvolt = <2864000>;
+ regulator-max-microvolt = <3312000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l23a_3p3: ldo23 {
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3312000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vdda_qusb_hs0_3p1:
+ vreg_l24a_3p075: ldo24 {
+ regulator-min-microvolt = <3088000>;
+ regulator-max-microvolt = <3088000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l25a_3p3: ldo25 {
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3312000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vdda_hp_pcie_1p2:
+ vdda_hv_ebi0:
+ vdda_hv_ebi1:
+ vdda_hv_ebi2:
+ vdda_hv_ebi3:
+ vdda_mipi_csi_1p25:
+ vdda_mipi_dsi0_1p2:
+ vdda_mipi_dsi1_1p2:
+ vdda_pcie_1p2:
+ vdda_ufs1_1p2:
+ vdda_ufs2_1p2:
+ vdda_usb1_ss_1p2:
+ vdda_usb2_ss_1p2:
+ vreg_l26a_1p2: ldo26 {
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l28a_3p0: ldo28 {
+ regulator-min-microvolt = <2856000>;
+ regulator-max-microvolt = <3008000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_lvs1a_1p8: lvs1 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ vreg_lvs2a_1p8: lvs2 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+ };
+
+ pmi8998-rpmh-regulators {
+ compatible = "qcom,pmi8998-rpmh-regulators";
+ qcom,pmic-id = "b";
+
+ vdd-bob-supply = <&vph_pwr>;
+
+ vreg_bob: bob {
+ regulator-min-microvolt = <3312000>;
+ regulator-max-microvolt = <3600000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_AUTO>;
+ regulator-allow-bypass;
+ };
+ };
+
+ pm8005-rpmh-regulators {
+ compatible = "qcom,pm8005-rpmh-regulators";
+ qcom,pmic-id = "c";
+
+ vdd-s1-supply = <&vph_pwr>;
+ vdd-s2-supply = <&vph_pwr>;
+ vdd-s3-supply = <&vph_pwr>;
+ vdd-s4-supply = <&vph_pwr>;
+
+ vreg_s3c_0p6: smps3 {
+ regulator-min-microvolt = <600000>;
+ regulator-max-microvolt = <600000>;
+ };
+ };
+};
+
+&cdsp_pas {
+ status = "okay";
+ firmware-name = "qcom/sdm845/axolotl/cdsp.mbn";
+};
+
+&dsi0 {
+ status = "okay";
+ vdda-supply = <&vdda_mipi_dsi0_1p2>;
+
+ panel@0 {
+ compatible = "visionox,rm69299-shift";
+ status = "okay";
+ reg = <0>;
+ vdda-supply = <&vreg_l14a_1p88>;
+ vdd3p3-supply = <&vreg_l28a_3p0>;
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ reset-gpios = <&tlmm 6 GPIO_ACTIVE_HIGH>;
+
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&sde_dsi_active &sde_te_active>;
+ pinctrl-1 = <&sde_dsi_suspend &sde_te_suspend>;
+
+ port {
+ panel_in_0: endpoint {
+ remote-endpoint = <&dsi0_out>;
+ };
+ };
+ };
+};
+
+&dsi0_out {
+ remote-endpoint = <&panel_in_0>;
+ data-lanes = <0 1 2 3>;
+};
+
+&dsi0_phy {
+ status = "okay";
+ vdds-supply = <&vdda_mipi_dsi0_pll>;
+};
+
+&gcc {
+ protected-clocks = <GCC_QSPI_CORE_CLK>,
+ <GCC_QSPI_CORE_CLK_SRC>,
+ <GCC_QSPI_CNOC_PERIPH_AHB_CLK>,
+ <GCC_LPASS_Q6_AXI_CLK>,
+ <GCC_LPASS_SWAY_CLK>;
+};
+
+&gmu {
+ status = "okay";
+};
+
+&gpu {
+ status = "okay";
+
+ zap-shader {
+ memory-region = <&gpu_mem>;
+ firmware-name = "qcom/sdm845/axolotl/a630_zap.mbn";
+ };
+};
+
+&i2c5 {
+ status="okay";
+
+ touchscreen@38 {
+ compatible = "focaltech,fts8719";
+ reg = <0x38>;
+ wakeup-source;
+ interrupt-parent = <&tlmm>;
+ interrupts = <125 0x2>;
+ vdd-supply = <&vreg_l28a_3p0>;
+ vcc-i2c-supply = <&vreg_l14a_1p88>;
+
+ pinctrl-names = "default", "suspend";
+ pinctrl-0 = <&ts_int_active &ts_reset_active>;
+ pinctrl-1 = <&ts_int_suspend &ts_reset_suspend>;
+
+ reset-gpio = <&tlmm 99 GPIO_ACTIVE_HIGH>;
+ irq-gpio = <&tlmm 125 GPIO_TRANSITORY>;
+ touchscreen-size-x = <1080>;
+ touchscreen-size-y = <2160>;
+ focaltech,max-touch-number = <5>;
+ };
+};
+
+&ipa {
+ status = "okay";
+
+ memory-region = <&ipa_fw_mem>;
+ firmware-name = "qcom/sdm845/axolotl/ipa_fws.mbn";
+};
+
+&mdss {
+ status = "okay";
+};
+
+&mss_pil {
+ status = "okay";
+ firmware-name = "qcom/sdm845/axolotl/mba.mbn", "qcom/sdm845/axolotl/modem.mbn";
+};
+
+&pm8998_gpio {
+ volume_up_gpio: pm8998_gpio6 {
+ pinconf {
+ pins = "gpio6";
+ function = "normal";
+ input-enable;
+ bias-pull-up;
+ qcom,drive-strength = <0>;
+ };
+ };
+};
+
+&pm8998_pon {
+ volume_down_resin: resin {
+ compatible = "qcom,pm8941-resin";
+ interrupts = <0x0 0x8 1 IRQ_TYPE_EDGE_BOTH>;
+ debounce = <15625>;
+ bias-pull-up;
+ linux,code = <KEY_VOLUMEDOWN>;
+ };
+};
+
+&qup_uart9_default {
+ pinconf-rx {
+ pins = "gpio5";
+ drive-strength = <2>;
+ bias-pull-up;
+ };
+
+ pinconf-tx {
+ pins = "gpio4";
+ drive-strength = <2>;
+ bias-disable;
+ };
+};
+
+&qupv3_id_0 {
+ status = "okay";
+};
+
+&qupv3_id_1 {
+ status = "okay";
+};
+
+&tlmm {
+ gpio-reserved-ranges = <0 4>, <81 4>;
+
+ sde_dsi_active: sde-dsi-active {
+ mux {
+ pins = "gpio6", "gpio11";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio6", "gpio11";
+ drive-strength = <8>;
+ bias-disable = <0>;
+ };
+ };
+
+ sde_dsi_suspend: sde-dsi-suspend {
+ mux {
+ pins = "gpio6", "gpio11";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio6", "gpio11";
+ drive-strength = <2>;
+ bias-pull-down;
+ };
+ };
+
+ sde_te_active: sde-te-active {
+ mux {
+ pins = "gpio10";
+ function = "mdp_vsync";
+ };
+
+ config {
+ pins = "gpio10";
+ drive-strength = <2>;
+ bias-pull-down;
+ };
+ };
+
+ sde_te_suspend: sde-te-suspend {
+ mux {
+ pins = "gpio10";
+ function = "mdp_vsync";
+ };
+
+ config {
+ pins = "gpio10";
+ drive-strength = <2>;
+ bias-pull-down;
+ };
+ };
+
+ ts_int_active: ts-int-active {
+ mux {
+ pins = "gpio125";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio125";
+ drive-strength = <8>;
+ bias-pull-up;
+ input-enable;
+ };
+ };
+
+ ts_int_suspend: ts-int-suspend {
+ mux {
+ pins = "gpio125";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio125";
+ drive-strength = <2>;
+ bias-pull-down;
+ input-enable;
+ };
+ };
+
+ ts_reset_active: ts-reset-active {
+ mux {
+ pins = "gpio99";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio99";
+ drive-strength = <8>;
+ bias-pull-up;
+ };
+ };
+
+ ts_reset_suspend: ts-reset-suspend {
+ mux {
+ pins = "gpio99";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio99";
+ drive-strength = <2>;
+ bias-pull-down;
+ };
+ };
+};
+
+&uart6 {
+ status = "okay";
+
+ bluetooth {
+ compatible = "qcom,wcn3990-bt";
+
+ vddio-supply = <&vreg_s4a_1p8>;
+ vddxo-supply = <&vreg_l7a_1p8>;
+ vddrf-supply = <&vreg_l17a_1p3>;
+ vddch0-supply = <&vreg_l25a_3p3>;
+ max-speed = <3200000>;
+ };
+};
+
+&uart9 {
+ status = "okay";
+};
+
+&ufs_mem_hc {
+ status = "okay";
+
+ reset-gpios = <&tlmm 150 GPIO_ACTIVE_LOW>;
+
+ vcc-supply = <&vreg_l20a_2p95>;
+ vcc-max-microamp = <600000>;
+};
+
+&ufs_mem_phy {
+ status = "okay";
+
+ vdda-phy-supply = <&vdda_ufs1_core>;
+ vdda-pll-supply = <&vdda_ufs1_1p2>;
+};
+
+&usb_1 {
+ status = "okay";
+};
+
+&usb_1_dwc3 {
+ dr_mode = "peripheral";
+};
+
+&usb_1_hsphy {
+ status = "okay";
+
+ vdd-supply = <&vreg_l1a_0p875>;
+ vdda-phy-dpdm-supply = <&vreg_l24a_3p075>;
+ vdda-pll-supply = <&vreg_l12a_1p8>;
+};
+
+&usb_1_qmpphy {
+ status = "okay";
+
+ vdda-phy-supply = <&vreg_l26a_1p2>;
+ vdda-pll-supply = <&vreg_l1a_0p875>;
+};
+
+&venus {
+ status = "okay";
+ firmware-name = "qcom/sdm845/axolotl/venus.mbn";
+};
+
+&wifi {
+ status = "okay";
+
+ vdd-0.8-cx-mx-supply = <&vreg_l5a_0p8>;
+ vdd-1.3-rfa-supply = <&vreg_l17a_1p3>;
+ vdd-1.8-xo-supply = <&vreg_l7a_1p8>;
+ vdd-3.3-ch0-supply = <&vreg_l25a_3p3>;
+ vdd-3.3-ch1-supply = <&vreg_l23a_3p3>;
+
+ qcom,snoc-host-cap-8bit-quirk;
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm845.dtsi b/arch/arm64/boot/dts/qcom/sdm845.dtsi
index cfdeaa81f1bb..41f4e46e1f85 100644
--- a/arch/arm64/boot/dts/qcom/sdm845.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm845.dtsi
@@ -12,6 +12,7 @@
#include <dt-bindings/clock/qcom,lpass-sdm845.h>
#include <dt-bindings/clock/qcom,rpmh.h>
#include <dt-bindings/clock/qcom,videocc-sdm845.h>
+#include <dt-bindings/dma/qcom-gpi.h>
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/interconnect/qcom,osm-l3.h>
#include <dt-bindings/interconnect/qcom,sdm845.h>
@@ -79,22 +80,22 @@
#size-cells = <2>;
ranges;
- hyp_mem: memory@85700000 {
+ hyp_mem: hyp-mem@85700000 {
reg = <0 0x85700000 0 0x600000>;
no-map;
};
- xbl_mem: memory@85e00000 {
+ xbl_mem: xbl-mem@85e00000 {
reg = <0 0x85e00000 0 0x100000>;
no-map;
};
- aop_mem: memory@85fc0000 {
+ aop_mem: aop-mem@85fc0000 {
reg = <0 0x85fc0000 0 0x20000>;
no-map;
};
- aop_cmd_db_mem: memory@85fe0000 {
+ aop_cmd_db_mem: aop-cmd-db-mem@85fe0000 {
compatible = "qcom,cmd-db";
reg = <0x0 0x85fe0000 0 0x20000>;
no-map;
@@ -107,12 +108,12 @@
hwlocks = <&tcsr_mutex 3>;
};
- tz_mem: memory@86200000 {
+ tz_mem: tz@86200000 {
reg = <0 0x86200000 0 0x2d00000>;
no-map;
};
- rmtfs_mem: memory@88f00000 {
+ rmtfs_mem: rmtfs@88f00000 {
compatible = "qcom,rmtfs-mem";
reg = <0 0x88f00000 0 0x200000>;
no-map;
@@ -121,67 +122,67 @@
qcom,vmid = <15>;
};
- qseecom_mem: memory@8ab00000 {
+ qseecom_mem: qseecom@8ab00000 {
reg = <0 0x8ab00000 0 0x1400000>;
no-map;
};
- camera_mem: memory@8bf00000 {
+ camera_mem: camera-mem@8bf00000 {
reg = <0 0x8bf00000 0 0x500000>;
no-map;
};
- ipa_fw_mem: memory@8c400000 {
+ ipa_fw_mem: ipa-fw@8c400000 {
reg = <0 0x8c400000 0 0x10000>;
no-map;
};
- ipa_gsi_mem: memory@8c410000 {
+ ipa_gsi_mem: ipa-gsi@8c410000 {
reg = <0 0x8c410000 0 0x5000>;
no-map;
};
- gpu_mem: memory@8c415000 {
+ gpu_mem: gpu@8c415000 {
reg = <0 0x8c415000 0 0x2000>;
no-map;
};
- adsp_mem: memory@8c500000 {
+ adsp_mem: adsp@8c500000 {
reg = <0 0x8c500000 0 0x1a00000>;
no-map;
};
- wlan_msa_mem: memory@8df00000 {
+ wlan_msa_mem: wlan-msa@8df00000 {
reg = <0 0x8df00000 0 0x100000>;
no-map;
};
- mpss_region: memory@8e000000 {
+ mpss_region: mpss@8e000000 {
reg = <0 0x8e000000 0 0x7800000>;
no-map;
};
- venus_mem: memory@95800000 {
+ venus_mem: venus@95800000 {
reg = <0 0x95800000 0 0x500000>;
no-map;
};
- cdsp_mem: memory@95d00000 {
+ cdsp_mem: cdsp@95d00000 {
reg = <0 0x95d00000 0 0x800000>;
no-map;
};
- mba_region: memory@96500000 {
+ mba_region: mba@96500000 {
reg = <0 0x96500000 0 0x200000>;
no-map;
};
- slpi_mem: memory@96700000 {
+ slpi_mem: slpi@96700000 {
reg = <0 0x96700000 0 0x1400000>;
no-map;
};
- spss_mem: memory@97b00000 {
+ spss_mem: spss@97b00000 {
reg = <0 0x97b00000 0 0x100000>;
no-map;
};
@@ -787,7 +788,7 @@
apr {
compatible = "qcom,apr-v2";
qcom,glink-channels = "apr_audio_svc";
- qcom,apr-domain = <APR_DOMAIN_ADSP>;
+ qcom,domain = <APR_DOMAIN_ADSP>;
#address-cells = <1>;
#size-cells = <0>;
qcom,intents = <512 20>;
@@ -1125,6 +1126,29 @@
};
};
+ gpi_dma0: dma-controller@800000 {
+ #dma-cells = <3>;
+ compatible = "qcom,sdm845-gpi-dma";
+ reg = <0 0x00800000 0 0x60000>;
+ interrupts = <GIC_SPI 244 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 245 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 246 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 247 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 248 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 249 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 250 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 251 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 252 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 253 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 254 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 255 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 256 IRQ_TYPE_LEVEL_HIGH>;
+ dma-channels = <13>;
+ dma-channel-mask = <0xfa>;
+ iommus = <&apps_smmu 0x0016 0x0>;
+ status = "disabled";
+ };
+
qupv3_id_0: geniqup@8c0000 {
compatible = "qcom,geni-se-qup";
reg = <0 0x008c0000 0 0x6000>;
@@ -1171,6 +1195,9 @@
interconnects = <&aggre1_noc MASTER_QUP_1 0 &config_noc SLAVE_BLSP_1 0>,
<&gladiator_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_BLSP_1 0>;
interconnect-names = "qup-core", "qup-config";
+ dmas = <&gpi_dma0 0 0 QCOM_GPI_SPI>,
+ <&gpi_dma0 1 0 QCOM_GPI_SPI>;
+ dma-names = "tx", "rx";
status = "disabled";
};
@@ -1544,6 +1571,29 @@
};
};
+ gpi_dma1: dma-controller@0xa00000 {
+ #dma-cells = <3>;
+ compatible = "qcom,sdm845-gpi-dma";
+ reg = <0 0x00a00000 0 0x60000>;
+ interrupts = <GIC_SPI 279 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 280 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 281 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 282 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 283 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 284 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 293 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 294 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 295 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 296 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 297 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 298 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 299 IRQ_TYPE_LEVEL_HIGH>;
+ dma-channels = <13>;
+ dma-channel-mask = <0xfa>;
+ iommus = <&apps_smmu 0x06d6 0x0>;
+ status = "disabled";
+ };
+
qupv3_id_1: geniqup@ac0000 {
compatible = "qcom,geni-se-qup";
reg = <0 0x00ac0000 0 0x6000>;
@@ -1967,7 +2017,7 @@
};
};
- system-cache-controller@1100000 {
+ llcc: system-cache-controller@1100000 {
compatible = "qcom,sdm845-llcc";
reg = <0 0x01100000 0 0x200000>, <0 0x01300000 0 0x50000>;
reg-names = "llcc_base", "llcc_broadcast_base";
@@ -2587,6 +2637,13 @@
"gpio2", "gpio3";
function = "qup0";
};
+
+ config {
+ pins = "gpio0", "gpio1",
+ "gpio2", "gpio3";
+ drive-strength = <6>;
+ bias-disable;
+ };
};
qup_spi1_default: qup-spi1-default {
@@ -3613,10 +3670,10 @@
#clock-cells = <0>;
clock-frequency = <9600000>;
clock-output-names = "mclk";
- qcom,micbias1-millivolt = <1800>;
- qcom,micbias2-millivolt = <1800>;
- qcom,micbias3-millivolt = <1800>;
- qcom,micbias4-millivolt = <1800>;
+ qcom,micbias1-microvolt = <1800000>;
+ qcom,micbias2-microvolt = <1800000>;
+ qcom,micbias3-microvolt = <1800000>;
+ qcom,micbias4-microvolt = <1800000>;
#address-cells = <1>;
#size-cells = <1>;
@@ -4139,6 +4196,8 @@
#clock-cells = <1>;
#reset-cells = <1>;
#power-domain-cells = <1>;
+ clocks = <&rpmhcc RPMH_CXO_CLK>;
+ clock-names = "bi_tcxo";
};
dsi_opp_table: dsi-opp-table {
@@ -4619,7 +4678,7 @@
};
aoss_qmp: power-controller@c300000 {
- compatible = "qcom,sdm845-aoss-qmp";
+ compatible = "qcom,sdm845-aoss-qmp", "qcom,aoss-qmp";
reg = <0 0x0c300000 0 0x100000>;
interrupts = <GIC_SPI 389 IRQ_TYPE_EDGE_RISING>;
mboxes = <&apss_shared 0>;
@@ -5258,7 +5317,7 @@
};
};
- gpu-thermal-top {
+ gpu-top-thermal {
polling-delay-passive = <250>;
polling-delay = <1000>;
@@ -5273,7 +5332,7 @@
};
};
- gpu-thermal-bottom {
+ gpu-bottom-thermal {
polling-delay-passive = <250>;
polling-delay = <1000>;
diff --git a/arch/arm64/boot/dts/qcom/sdm850-lenovo-yoga-c630.dts b/arch/arm64/boot/dts/qcom/sdm850-lenovo-yoga-c630.dts
index 58845a14805f..f1619b3f97ef 100644
--- a/arch/arm64/boot/dts/qcom/sdm850-lenovo-yoga-c630.dts
+++ b/arch/arm64/boot/dts/qcom/sdm850-lenovo-yoga-c630.dts
@@ -56,19 +56,6 @@
};
};
- panel {
- compatible = "boe,nv133fhm-n61";
- no-hpd;
-
- ports {
- port {
- panel_in_edp: endpoint {
- remote-endpoint = <&sn65dsi86_out>;
- };
- };
- };
- };
-
/* Reserved memory changes for IPA */
reserved-memory {
wlan_msa_mem: memory@8c400000 {
@@ -98,6 +85,12 @@
clock-frequency = <19200000>;
};
+
+ backlight: backlight {
+ compatible = "pwm-backlight";
+ pwms = <&sn65dsi86 1000000>;
+ enable-gpios = <&tlmm 11 GPIO_ACTIVE_HIGH>;
+ };
};
&adsp_pas {
@@ -419,6 +412,7 @@
clock-names = "refclk";
no-hpd;
+ #pwm-cells = <1>;
ports {
#address-cells = <1>;
@@ -438,6 +432,19 @@
};
};
};
+
+ aux-bus {
+ panel: panel {
+ compatible = "boe,nv133fhm-n61";
+ backlight = <&backlight>;
+
+ port {
+ panel_in_edp: endpoint {
+ remote-endpoint = <&sn65dsi86_out>;
+ };
+ };
+ };
+ };
};
};
@@ -807,3 +814,8 @@
qcom,snoc-host-cap-8bit-quirk;
};
+
+&crypto {
+ /* FIXME: qce_start triggers an SError */
+ status= "disable";
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm850-samsung-w737.dts b/arch/arm64/boot/dts/qcom/sdm850-samsung-w737.dts
new file mode 100644
index 000000000000..2a552d817b03
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sdm850-samsung-w737.dts
@@ -0,0 +1,748 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Samsung Galaxy Book2
+ *
+ * Copyright (c) 2022, Xilin Wu <strongtz@yeah.net>
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/pinctrl/qcom,pmic-gpio.h>
+#include <dt-bindings/input/gpio-keys.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/regulator/qcom,rpmh-regulator.h>
+#include <dt-bindings/sound/qcom,q6afe.h>
+#include <dt-bindings/sound/qcom,q6asm.h>
+#include "sdm850.dtsi"
+#include "pm8998.dtsi"
+
+/*
+ * Update following upstream (sdm845.dtsi) reserved
+ * memory mappings for firmware loading to succeed
+ */
+/delete-node/ &qseecom_mem;
+/delete-node/ &wlan_msa_mem;
+/delete-node/ &slpi_mem;
+/delete-node/ &ipa_fw_mem;
+/delete-node/ &ipa_gsi_mem;
+/delete-node/ &gpu_mem;
+/delete-node/ &mpss_region;
+/delete-node/ &adsp_mem;
+/delete-node/ &cdsp_mem;
+/delete-node/ &venus_mem;
+/delete-node/ &mba_region;
+/delete-node/ &spss_mem;
+
+/ {
+ model = "Samsung Galaxy Book2";
+ compatible = "samsung,w737", "qcom,sdm845";
+ chassis-type = "convertible";
+
+ chosen {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ // Firmware initialized the display at 1280p instead of 1440p
+ framebuffer0: framebuffer@80400000 {
+ compatible = "simple-framebuffer";
+ reg = <0 0x80400000 0 (1920 * 1280 * 4)>;
+ width = <1920>;
+ height = <1280>;
+ stride = <(1920 * 4)>;
+ format = "a8r8g8b8";
+ };
+ };
+
+ aliases {
+ hsuart0 = &uart6;
+ };
+
+ /* Reserved memory changes */
+ reserved-memory {
+ /* Bootloader display framebuffer region */
+ cont_splash_mem: memory@80400000 {
+ reg = <0x0 0x80400000 0x0 0x960000>;
+ no-map;
+ };
+
+ qseecom_mem: memory@8b500000 {
+ reg = <0 0x8b500000 0 0xa00000>;
+ no-map;
+ };
+
+ wlan_msa_mem: memory@8c400000 {
+ reg = <0 0x8c400000 0 0x100000>;
+ no-map;
+ };
+
+ slpi_mem: memory@8c500000 {
+ reg = <0 0x8c500000 0 0x1200000>;
+ no-map;
+ };
+
+ ipa_fw_mem: memory@8d700000 {
+ reg = <0 0x8d700000 0 0x100000>;
+ no-map;
+ };
+
+ gpu_mem: memory@8d800000 {
+ reg = <0 0x8d800000 0 0x5000>;
+ no-map;
+ };
+
+ mpss_region: memory@8e000000 {
+ reg = <0 0x8e000000 0 0x8000000>;
+ no-map;
+ };
+
+ adsp_mem: memory@96000000 {
+ reg = <0 0x96000000 0 0x2000000>;
+ no-map;
+ };
+
+ cdsp_mem: memory@98000000 {
+ reg = <0 0x98000000 0 0x800000>;
+ no-map;
+ };
+
+ venus_mem: memory@98800000 {
+ reg = <0 0x98800000 0 0x500000>;
+ no-map;
+ };
+
+ mba_region: memory@98d00000 {
+ reg = <0 0x98d00000 0 0x200000>;
+ no-map;
+ };
+
+ spss_mem: memory@98f00000 {
+ reg = <0 0x98f00000 0 0x100000>;
+ no-map;
+ };
+ };
+};
+
+&adsp_pas {
+ firmware-name = "qcom/samsung/w737/qcadsp850.mbn";
+ status = "okay";
+};
+
+&apps_rsc {
+ pm8998-rpmh-regulators {
+ compatible = "qcom,pm8998-rpmh-regulators";
+ qcom,pmic-id = "a";
+
+ vdd-l2-l8-l17-supply = <&vreg_s3a_1p35>;
+ vdd-l7-l12-l14-l15-supply = <&vreg_s5a_2p04>;
+
+ vreg_s2a_1p125: smps2 {
+ };
+
+ vreg_s3a_1p35: smps3 {
+ regulator-min-microvolt = <1352000>;
+ regulator-max-microvolt = <1352000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_s4a_1p8: smps4 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_s5a_2p04: smps5 {
+ regulator-min-microvolt = <2040000>;
+ regulator-max-microvolt = <2040000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_s7a_1p025: smps7 {
+ };
+
+ vdd_qusb_hs0:
+ vdda_hp_pcie_core:
+ vdda_mipi_csi0_0p9:
+ vdda_mipi_csi1_0p9:
+ vdda_mipi_csi2_0p9:
+ vdda_mipi_dsi0_pll:
+ vdda_mipi_dsi1_pll:
+ vdda_qlink_lv:
+ vdda_qlink_lv_ck:
+ vdda_qrefs_0p875:
+ vdda_pcie_core:
+ vdda_pll_cc_ebi01:
+ vdda_pll_cc_ebi23:
+ vdda_sp_sensor:
+ vdda_ufs1_core:
+ vdda_ufs2_core:
+ vdda_usb1_ss_core:
+ vdda_usb2_ss_core:
+ vreg_l1a_0p875: ldo1 {
+ regulator-min-microvolt = <880000>;
+ regulator-max-microvolt = <880000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vddpx_10:
+ vreg_l2a_1p2: ldo2 {
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ regulator-always-on;
+ };
+
+ vreg_l3a_1p0: ldo3 {
+ };
+
+ vdd_wcss_cx:
+ vdd_wcss_mx:
+ vdda_wcss_pll:
+ vreg_l5a_0p8: ldo5 {
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <800000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vddpx_13:
+ vreg_l6a_1p8: ldo6 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l7a_1p8: ldo7 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l8a_1p2: ldo8 {
+ };
+
+ vreg_l9a_1p8: ldo9 {
+ };
+
+ vreg_l10a_1p8: ldo10 {
+ };
+
+ vreg_l11a_1p0: ldo11 {
+ };
+
+ vdd_qfprom:
+ vdd_qfprom_sp:
+ vdda_apc1_cs_1p8:
+ vdda_gfx_cs_1p8:
+ vdda_qrefs_1p8:
+ vdda_qusb_hs0_1p8:
+ vddpx_11:
+ vreg_l12a_1p8: ldo12 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vddpx_2:
+ vreg_l13a_2p95: ldo13 {
+ };
+
+ vreg_l14a_1p88: ldo14 {
+ regulator-min-microvolt = <1880000>;
+ regulator-max-microvolt = <1880000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ regulator-always-on;
+ };
+
+ vreg_l15a_1p8: ldo15 {
+ };
+
+ vreg_l16a_2p7: ldo16 {
+ };
+
+ vreg_l17a_1p3: ldo17 {
+ regulator-min-microvolt = <1304000>;
+ regulator-max-microvolt = <1304000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l18a_1p8: ldo18 {
+ };
+
+ vreg_l19a_3p0: ldo19 {
+ regulator-min-microvolt = <3100000>;
+ regulator-max-microvolt = <3108000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l20a_2p95: ldo20 {
+ regulator-min-microvolt = <2960000>;
+ regulator-max-microvolt = <2960000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l21a_2p95: ldo21 {
+ };
+
+ vreg_l22a_2p85: ldo22 {
+ };
+
+ vreg_l23a_3p3: ldo23 {
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3312000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vdda_qusb_hs0_3p1:
+ vreg_l24a_3p075: ldo24 {
+ regulator-min-microvolt = <3075000>;
+ regulator-max-microvolt = <3083000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l25a_3p3: ldo25 {
+ regulator-min-microvolt = <3104000>;
+ regulator-max-microvolt = <3112000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vdda_hp_pcie_1p2:
+ vdda_hv_ebi0:
+ vdda_hv_ebi1:
+ vdda_hv_ebi2:
+ vdda_hv_ebi3:
+ vdda_mipi_csi_1p25:
+ vdda_mipi_dsi0_1p2:
+ vdda_mipi_dsi1_1p2:
+ vdda_pcie_1p2:
+ vdda_ufs1_1p2:
+ vdda_ufs2_1p2:
+ vdda_usb1_ss_1p2:
+ vdda_usb2_ss_1p2:
+ vreg_l26a_1p2: ldo26 {
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1208000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l28a_3p0: ldo28 {
+ };
+
+ vreg_lvs1a_1p8: lvs1 {
+ };
+
+ vreg_lvs2a_1p8: lvs2 {
+ };
+ };
+};
+
+&cdsp_pas {
+ firmware-name = "qcom/samsung/w737/qccdsp850.mbn";
+ status = "okay";
+};
+
+&gcc {
+ protected-clocks = <GCC_QSPI_CORE_CLK>,
+ <GCC_QSPI_CORE_CLK_SRC>,
+ <GCC_QSPI_CNOC_PERIPH_AHB_CLK>,
+ <GCC_LPASS_Q6_AXI_CLK>,
+ <GCC_LPASS_SWAY_CLK>;
+};
+
+&i2c10 {
+ status = "okay";
+ clock-frequency = <400000>;
+
+ /* SN65DSI86 @ 0x2c */
+ /* The panel requires dual DSI, which is not supported by the bridge driver */
+};
+
+&i2c11 {
+ status = "okay";
+ clock-frequency = <400000>;
+
+ /* HID-I2C Touchscreen @ 0x20 */
+};
+
+&i2c15 {
+ status = "okay";
+ clock-frequency = <400000>;
+
+ digitizer@9 {
+ compatible = "wacom,w9013", "hid-over-i2c";
+ reg = <0x9>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pen_irq_l>, <&pen_pdct_l>, <&pen_rst_l>;
+
+ post-power-on-delay-ms = <120>;
+
+ interrupt-parent = <&tlmm>;
+ interrupts = <119 IRQ_TYPE_LEVEL_LOW>;
+
+ hid-descr-addr = <0x1>;
+ };
+};
+
+&ipa {
+ status = "okay";
+ memory-region = <&ipa_fw_mem>;
+ firmware-name = "qcom/samsung/w737/ipa_fws.elf";
+};
+
+/* No idea why it causes an SError when enabled */
+&llcc {
+ status = "disabled";
+};
+
+&mss_pil {
+ status = "okay";
+ firmware-name = "qcom/samsung/w737/qcdsp1v2850.mbn", "qcom/samsung/w737/qcdsp2850.mbn";
+};
+
+&qup_i2c10_default {
+ pinconf {
+ pins = "gpio55", "gpio56";
+ drive-strength = <2>;
+ bias-disable;
+ };
+};
+
+&qup_i2c11_default {
+ pinconf {
+ pins = "gpio31", "gpio32";
+ drive-strength = <2>;
+ bias-disable;
+ };
+};
+
+&qup_i2c12_default {
+ drive-strength = <2>;
+ bias-disable;
+};
+
+&qup_uart6_default {
+ pinmux {
+ pins = "gpio45", "gpio46", "gpio47", "gpio48";
+ function = "qup6";
+ };
+
+ cts {
+ pins = "gpio45";
+ bias-pull-down;
+ };
+
+ rts-tx {
+ pins = "gpio46", "gpio47";
+ drive-strength = <2>;
+ bias-disable;
+ };
+
+ rx {
+ pins = "gpio48";
+ bias-pull-up;
+ };
+};
+
+&qupv3_id_0 {
+ status = "okay";
+};
+
+&qupv3_id_1 {
+ status = "okay";
+};
+
+&q6asmdai {
+ dai@0 {
+ reg = <0>;
+ };
+
+ dai@1 {
+ reg = <1>;
+ };
+
+ dai@2 {
+ reg = <2>;
+ };
+};
+
+&sound {
+ compatible = "qcom,sdm845-sndcard";
+ model = "Samsung-W737";
+
+ audio-routing =
+ "RX_BIAS", "MCLK",
+ "AMIC2", "MIC BIAS2",
+ "SpkrLeft IN", "SPK1 OUT",
+ "SpkrRight IN", "SPK2 OUT",
+ "MM_DL1", "MultiMedia1 Playback",
+ "MM_DL3", "MultiMedia3 Playback",
+ "MultiMedia2 Capture", "MM_UL2";
+
+ mm1-dai-link {
+ link-name = "MultiMedia1";
+ cpu {
+ sound-dai = <&q6asmdai MSM_FRONTEND_DAI_MULTIMEDIA1>;
+ };
+ };
+
+ mm2-dai-link {
+ link-name = "MultiMedia2";
+ cpu {
+ sound-dai = <&q6asmdai MSM_FRONTEND_DAI_MULTIMEDIA2>;
+ };
+ };
+
+ mm3-dai-link {
+ link-name = "MultiMedia3";
+ cpu {
+ sound-dai = <&q6asmdai MSM_FRONTEND_DAI_MULTIMEDIA3>;
+ };
+ };
+
+ slim-dai-link {
+ link-name = "SLIM Playback";
+ cpu {
+ sound-dai = <&q6afedai SLIMBUS_0_RX>;
+ };
+
+ platform {
+ sound-dai = <&q6routing>;
+ };
+
+ codec {
+ sound-dai = <&left_spkr>, <&right_spkr>, <&swm 0>, <&wcd9340 0>;
+ };
+ };
+
+ slimcap-dai-link {
+ link-name = "SLIM Capture";
+ cpu {
+ sound-dai = <&q6afedai SLIMBUS_0_TX>;
+ };
+
+ platform {
+ sound-dai = <&q6routing>;
+ };
+
+ codec {
+ sound-dai = <&wcd9340 1>;
+ };
+ };
+
+ slim-wcd-dai-link {
+ link-name = "SLIM WCD Playback";
+ cpu {
+ sound-dai = <&q6afedai SLIMBUS_1_RX>;
+ };
+
+ platform {
+ sound-dai = <&q6routing>;
+ };
+
+ codec {
+ sound-dai = <&wcd9340 2>;
+ };
+ };
+};
+
+&tlmm {
+ gpio-reserved-ranges = <0 6>, <85 4>;
+
+ pen_irq_l: pen-irq-l {
+ pinmux {
+ pins = "gpio119";
+ function = "gpio";
+ };
+
+ pinconf {
+ pins = "gpio119";
+ bias-disable;
+ };
+ };
+
+ pen_pdct_l: pen-pdct-l {
+ pinmux {
+ pins = "gpio124";
+ function = "gpio";
+ };
+
+ pinconf {
+ pins = "gpio124";
+ bias-disable;
+ drive-strength = <2>;
+ output-high;
+ };
+ };
+
+ pen_rst_l: pen-rst-l {
+ pinmux {
+ pins = "gpio21";
+ function = "gpio";
+ };
+
+ pinconf {
+ pins = "gpio21";
+ bias-disable;
+ drive-strength = <2>;
+
+ /*
+ * The pen driver doesn't currently support
+ * driving this reset line. By specifying
+ * output-high here we're relying on the fact
+ * that this pin has a default pulldown at boot
+ * (which makes sure the pen was in reset if it
+ * was powered) and then we set it high here to
+ * take it out of reset. Better would be if the
+ * pen driver could control this and we could
+ * remove "output-high" here.
+ */
+ output-high;
+ };
+ };
+
+ wcd_intr_default: wcd_intr_default {
+ pins = "gpio54";
+ function = "gpio";
+
+ input-enable;
+ bias-pull-down;
+ drive-strength = <2>;
+ };
+};
+
+&uart6 {
+ status = "okay";
+
+ bluetooth {
+ compatible = "qcom,wcn3990-bt";
+
+ vddio-supply = <&vreg_s4a_1p8>;
+ vddxo-supply = <&vreg_l7a_1p8>;
+ vddrf-supply = <&vreg_l17a_1p3>;
+ vddch0-supply = <&vreg_l25a_3p3>;
+ vddch1-supply = <&vreg_l23a_3p3>;
+ max-speed = <3200000>;
+ };
+};
+
+&ufs_mem_hc {
+ status = "okay";
+
+ reset-gpios = <&tlmm 150 GPIO_ACTIVE_LOW>;
+
+ vcc-supply = <&vreg_l20a_2p95>;
+ vcc-max-microamp = <600000>;
+};
+
+&ufs_mem_phy {
+ status = "okay";
+
+ vdda-phy-supply = <&vdda_ufs1_core>;
+ vdda-pll-supply = <&vdda_ufs1_1p2>;
+};
+
+&usb_1 {
+ status = "okay";
+};
+
+&usb_1_dwc3 {
+ dr_mode = "host";
+};
+
+&usb_1_hsphy {
+ status = "okay";
+
+ vdd-supply = <&vdda_usb1_ss_core>;
+ vdda-pll-supply = <&vdda_qusb_hs0_1p8>;
+ vdda-phy-dpdm-supply = <&vdda_qusb_hs0_3p1>;
+
+ qcom,imp-res-offset-value = <8>;
+ qcom,hstx-trim-value = <QUSB2_V2_HSTX_TRIM_21_6_MA>;
+ qcom,preemphasis-level = <QUSB2_V2_PREEMPHASIS_5_PERCENT>;
+ qcom,preemphasis-width = <QUSB2_V2_PREEMPHASIS_WIDTH_HALF_BIT>;
+};
+
+&usb_1_qmpphy {
+ status = "okay";
+
+ vdda-phy-supply = <&vdda_usb1_ss_1p2>;
+ vdda-pll-supply = <&vdda_usb1_ss_core>;
+};
+
+&usb_2 {
+ status = "okay";
+};
+
+&usb_2_dwc3 {
+ dr_mode = "host";
+};
+
+&usb_2_hsphy {
+ status = "okay";
+
+ vdd-supply = <&vdda_usb2_ss_core>;
+ vdda-pll-supply = <&vdda_qusb_hs0_1p8>;
+ vdda-phy-dpdm-supply = <&vdda_qusb_hs0_3p1>;
+
+ qcom,imp-res-offset-value = <8>;
+ qcom,hstx-trim-value = <QUSB2_V2_HSTX_TRIM_22_8_MA>;
+};
+
+&usb_2_qmpphy {
+ status = "okay";
+
+ vdda-phy-supply = <&vdda_usb2_ss_1p2>;
+ vdda-pll-supply = <&vdda_usb2_ss_core>;
+};
+
+&venus {
+ status = "okay";
+ firmware-name = "qcom/samsung/w737/qcvss850.mbn";
+};
+
+&wcd9340{
+ pinctrl-0 = <&wcd_intr_default>;
+ pinctrl-names = "default";
+ clock-names = "extclk";
+ clocks = <&rpmhcc RPMH_LN_BB_CLK2>;
+ reset-gpios = <&tlmm 64 0>;
+ vdd-buck-supply = <&vreg_s4a_1p8>;
+ vdd-buck-sido-supply = <&vreg_s4a_1p8>;
+ vdd-tx-supply = <&vreg_s4a_1p8>;
+ vdd-rx-supply = <&vreg_s4a_1p8>;
+ vdd-io-supply = <&vreg_s4a_1p8>;
+ 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>;
+
+ swm: swm@c85 {
+ left_spkr: wsa8810-left{
+ compatible = "sdw10217211000";
+ reg = <0 3>;
+ powerdown-gpios = <&wcdgpio 1 GPIO_ACTIVE_HIGH>;
+ #thermal-sensor-cells = <0>;
+ sound-name-prefix = "SpkrLeft";
+ #sound-dai-cells = <0>;
+ };
+
+ right_spkr: wsa8810-right{
+ compatible = "sdw10217211000";
+ powerdown-gpios = <&wcdgpio 2 GPIO_ACTIVE_HIGH>;
+ reg = <0 4>;
+ #thermal-sensor-cells = <0>;
+ sound-name-prefix = "SpkrRight";
+ #sound-dai-cells = <0>;
+ };
+ };
+};
+
+&wifi {
+ status = "okay";
+
+ vdd-0.8-cx-mx-supply = <&vreg_l5a_0p8>;
+ vdd-1.8-xo-supply = <&vreg_l7a_1p8>;
+ vdd-1.3-rfa-supply = <&vreg_l17a_1p3>;
+ vdd-3.3-ch0-supply = <&vreg_l25a_3p3>;
+ vdd-3.3-ch1-supply = <&vreg_l23a_3p3>;
+
+ qcom,snoc-host-cap-8bit-quirk;
+};
diff --git a/arch/arm64/boot/dts/qcom/sm6125.dtsi b/arch/arm64/boot/dts/qcom/sm6125.dtsi
index 49e6bca646c2..e81b2a7794fb 100644
--- a/arch/arm64/boot/dts/qcom/sm6125.dtsi
+++ b/arch/arm64/boot/dts/qcom/sm6125.dtsi
@@ -449,7 +449,7 @@
<&xo_board>;
clock-names = "iface", "core", "xo";
- power-domains = <&rpmpd 0>;
+ power-domains = <&rpmpd SM6125_VDDCX>;
bus-width = <8>;
non-removable;
@@ -474,7 +474,7 @@
pinctrl-1 = <&sdc2_state_off>;
pinctrl-names = "default", "sleep";
- power-domains = <&rpmpd 0>;
+ power-domains = <&rpmpd SM6125_VDDCX>;
bus-width = <4>;
status = "disabled";
diff --git a/arch/arm64/boot/dts/qcom/sm7225-fairphone-fp4.dts b/arch/arm64/boot/dts/qcom/sm7225-fairphone-fp4.dts
index d4af9e0dad87..adb6ca2be2a5 100644
--- a/arch/arm64/boot/dts/qcom/sm7225-fairphone-fp4.dts
+++ b/arch/arm64/boot/dts/qcom/sm7225-fairphone-fp4.dts
@@ -10,6 +10,7 @@
#include <dt-bindings/pinctrl/qcom,pmic-gpio.h>
#include <dt-bindings/regulator/qcom,rpmh-regulator.h>
#include "sm7225.dtsi"
+#include "pm6150l.dtsi"
#include "pm6350.dtsi"
/ {
@@ -300,6 +301,14 @@
firmware-name = "qcom/sm7225/fairphone4/modem.mdt";
};
+&pm6150l_wled {
+ status = "okay";
+
+ qcom,switching-freq = <800>;
+ qcom,current-limit-microamp = <20000>;
+ qcom,num-strings = <2>;
+};
+
&pm6350_gpios {
gpio_keys_pin: gpio-keys-pin {
pins = "gpio2";
diff --git a/arch/arm64/boot/dts/qcom/sm8150-microsoft-surface-duo.dts b/arch/arm64/boot/dts/qcom/sm8150-microsoft-surface-duo.dts
index 5901c28e6696..a73317e1a824 100644
--- a/arch/arm64/boot/dts/qcom/sm8150-microsoft-surface-duo.dts
+++ b/arch/arm64/boot/dts/qcom/sm8150-microsoft-surface-duo.dts
@@ -430,18 +430,8 @@
/* MAX34417 @ 0x1e */
};
-&pon {
- pwrkey {
- status = "okay";
- };
-
- resin {
- compatible = "qcom,pm8941-resin";
- interrupts = <0x0 0x8 0x1 IRQ_TYPE_EDGE_BOTH>;
- debounce = <15625>;
- bias-pull-up;
- linux,code = <KEY_VOLUMEDOWN>;
- };
+&pon_pwrkey {
+ status = "okay";
};
&qupv3_id_0 {
@@ -476,6 +466,12 @@
firmware-name = "qcom/sm8150/microsoft/slpi.mdt";
};
+&pon_resin {
+ status = "okay";
+
+ linux,code = <KEY_VOLUMEDOWN>;
+};
+
&tlmm {
gpio-reserved-ranges = <126 4>;
diff --git a/arch/arm64/boot/dts/qcom/sm8150.dtsi b/arch/arm64/boot/dts/qcom/sm8150.dtsi
index 6012322a5984..d15fee495238 100644
--- a/arch/arm64/boot/dts/qcom/sm8150.dtsi
+++ b/arch/arm64/boot/dts/qcom/sm8150.dtsi
@@ -932,6 +932,9 @@
reg = <0 0x00880000 0 0x4000>;
clock-names = "se";
clocks = <&gcc GCC_QUPV3_WRAP0_S0_CLK>;
+ dmas = <&gpi_dma0 0 0 QCOM_GPI_I2C>,
+ <&gpi_dma0 1 0 QCOM_GPI_I2C>;
+ dma-names = "tx", "rx";
pinctrl-names = "default";
pinctrl-0 = <&qup_i2c0_default>;
interrupts = <GIC_SPI 601 IRQ_TYPE_LEVEL_HIGH>;
@@ -946,6 +949,9 @@
reg-names = "se";
clock-names = "se";
clocks = <&gcc GCC_QUPV3_WRAP0_S0_CLK>;
+ dmas = <&gpi_dma0 0 0 QCOM_GPI_SPI>,
+ <&gpi_dma0 1 0 QCOM_GPI_SPI>;
+ dma-names = "tx", "rx";
pinctrl-names = "default";
pinctrl-0 = <&qup_spi0_default>;
interrupts = <GIC_SPI 601 IRQ_TYPE_LEVEL_HIGH>;
@@ -960,6 +966,9 @@
reg = <0 0x00884000 0 0x4000>;
clock-names = "se";
clocks = <&gcc GCC_QUPV3_WRAP0_S1_CLK>;
+ dmas = <&gpi_dma0 0 1 QCOM_GPI_I2C>,
+ <&gpi_dma0 1 1 QCOM_GPI_I2C>;
+ dma-names = "tx", "rx";
pinctrl-names = "default";
pinctrl-0 = <&qup_i2c1_default>;
interrupts = <GIC_SPI 602 IRQ_TYPE_LEVEL_HIGH>;
@@ -974,6 +983,9 @@
reg-names = "se";
clock-names = "se";
clocks = <&gcc GCC_QUPV3_WRAP0_S1_CLK>;
+ dmas = <&gpi_dma0 0 1 QCOM_GPI_SPI>,
+ <&gpi_dma0 1 1 QCOM_GPI_SPI>;
+ dma-names = "tx", "rx";
pinctrl-names = "default";
pinctrl-0 = <&qup_spi1_default>;
interrupts = <GIC_SPI 602 IRQ_TYPE_LEVEL_HIGH>;
@@ -988,6 +1000,9 @@
reg = <0 0x00888000 0 0x4000>;
clock-names = "se";
clocks = <&gcc GCC_QUPV3_WRAP0_S2_CLK>;
+ dmas = <&gpi_dma0 0 2 QCOM_GPI_I2C>,
+ <&gpi_dma0 1 2 QCOM_GPI_I2C>;
+ dma-names = "tx", "rx";
pinctrl-names = "default";
pinctrl-0 = <&qup_i2c2_default>;
interrupts = <GIC_SPI 603 IRQ_TYPE_LEVEL_HIGH>;
@@ -1002,6 +1017,9 @@
reg-names = "se";
clock-names = "se";
clocks = <&gcc GCC_QUPV3_WRAP0_S2_CLK>;
+ dmas = <&gpi_dma0 0 2 QCOM_GPI_SPI>,
+ <&gpi_dma0 1 2 QCOM_GPI_SPI>;
+ dma-names = "tx", "rx";
pinctrl-names = "default";
pinctrl-0 = <&qup_spi2_default>;
interrupts = <GIC_SPI 603 IRQ_TYPE_LEVEL_HIGH>;
@@ -1016,6 +1034,9 @@
reg = <0 0x0088c000 0 0x4000>;
clock-names = "se";
clocks = <&gcc GCC_QUPV3_WRAP0_S3_CLK>;
+ dmas = <&gpi_dma0 0 3 QCOM_GPI_I2C>,
+ <&gpi_dma0 1 3 QCOM_GPI_I2C>;
+ dma-names = "tx", "rx";
pinctrl-names = "default";
pinctrl-0 = <&qup_i2c3_default>;
interrupts = <GIC_SPI 604 IRQ_TYPE_LEVEL_HIGH>;
@@ -1030,6 +1051,9 @@
reg-names = "se";
clock-names = "se";
clocks = <&gcc GCC_QUPV3_WRAP0_S3_CLK>;
+ dmas = <&gpi_dma0 0 3 QCOM_GPI_SPI>,
+ <&gpi_dma0 1 3 QCOM_GPI_SPI>;
+ dma-names = "tx", "rx";
pinctrl-names = "default";
pinctrl-0 = <&qup_spi3_default>;
interrupts = <GIC_SPI 604 IRQ_TYPE_LEVEL_HIGH>;
@@ -1044,6 +1068,9 @@
reg = <0 0x00890000 0 0x4000>;
clock-names = "se";
clocks = <&gcc GCC_QUPV3_WRAP0_S4_CLK>;
+ dmas = <&gpi_dma0 0 4 QCOM_GPI_I2C>,
+ <&gpi_dma0 1 4 QCOM_GPI_I2C>;
+ dma-names = "tx", "rx";
pinctrl-names = "default";
pinctrl-0 = <&qup_i2c4_default>;
interrupts = <GIC_SPI 605 IRQ_TYPE_LEVEL_HIGH>;
@@ -1058,6 +1085,9 @@
reg-names = "se";
clock-names = "se";
clocks = <&gcc GCC_QUPV3_WRAP0_S4_CLK>;
+ dmas = <&gpi_dma0 0 4 QCOM_GPI_SPI>,
+ <&gpi_dma0 1 4 QCOM_GPI_SPI>;
+ dma-names = "tx", "rx";
pinctrl-names = "default";
pinctrl-0 = <&qup_spi4_default>;
interrupts = <GIC_SPI 605 IRQ_TYPE_LEVEL_HIGH>;
@@ -1072,6 +1102,9 @@
reg = <0 0x00894000 0 0x4000>;
clock-names = "se";
clocks = <&gcc GCC_QUPV3_WRAP0_S5_CLK>;
+ dmas = <&gpi_dma0 0 5 QCOM_GPI_I2C>,
+ <&gpi_dma0 1 5 QCOM_GPI_I2C>;
+ dma-names = "tx", "rx";
pinctrl-names = "default";
pinctrl-0 = <&qup_i2c5_default>;
interrupts = <GIC_SPI 606 IRQ_TYPE_LEVEL_HIGH>;
@@ -1086,6 +1119,9 @@
reg-names = "se";
clock-names = "se";
clocks = <&gcc GCC_QUPV3_WRAP0_S5_CLK>;
+ dmas = <&gpi_dma0 0 5 QCOM_GPI_SPI>,
+ <&gpi_dma0 1 5 QCOM_GPI_SPI>;
+ dma-names = "tx", "rx";
pinctrl-names = "default";
pinctrl-0 = <&qup_spi5_default>;
interrupts = <GIC_SPI 606 IRQ_TYPE_LEVEL_HIGH>;
@@ -1100,6 +1136,9 @@
reg = <0 0x00898000 0 0x4000>;
clock-names = "se";
clocks = <&gcc GCC_QUPV3_WRAP0_S6_CLK>;
+ dmas = <&gpi_dma0 0 6 QCOM_GPI_I2C>,
+ <&gpi_dma0 1 6 QCOM_GPI_I2C>;
+ dma-names = "tx", "rx";
pinctrl-names = "default";
pinctrl-0 = <&qup_i2c6_default>;
interrupts = <GIC_SPI 607 IRQ_TYPE_LEVEL_HIGH>;
@@ -1114,6 +1153,9 @@
reg-names = "se";
clock-names = "se";
clocks = <&gcc GCC_QUPV3_WRAP0_S6_CLK>;
+ dmas = <&gpi_dma0 0 6 QCOM_GPI_SPI>,
+ <&gpi_dma0 1 6 QCOM_GPI_SPI>;
+ dma-names = "tx", "rx";
pinctrl-names = "default";
pinctrl-0 = <&qup_spi6_default>;
interrupts = <GIC_SPI 607 IRQ_TYPE_LEVEL_HIGH>;
@@ -1128,6 +1170,9 @@
reg = <0 0x0089c000 0 0x4000>;
clock-names = "se";
clocks = <&gcc GCC_QUPV3_WRAP0_S7_CLK>;
+ dmas = <&gpi_dma0 0 7 QCOM_GPI_I2C>,
+ <&gpi_dma0 1 7 QCOM_GPI_I2C>;
+ dma-names = "tx", "rx";
pinctrl-names = "default";
pinctrl-0 = <&qup_i2c7_default>;
interrupts = <GIC_SPI 607 IRQ_TYPE_LEVEL_HIGH>;
@@ -1142,6 +1187,9 @@
reg-names = "se";
clock-names = "se";
clocks = <&gcc GCC_QUPV3_WRAP0_S7_CLK>;
+ dmas = <&gpi_dma0 0 7 QCOM_GPI_SPI>,
+ <&gpi_dma0 1 7 QCOM_GPI_SPI>;
+ dma-names = "tx", "rx";
pinctrl-names = "default";
pinctrl-0 = <&qup_spi7_default>;
interrupts = <GIC_SPI 608 IRQ_TYPE_LEVEL_HIGH>;
@@ -1192,6 +1240,9 @@
reg = <0 0x00a80000 0 0x4000>;
clock-names = "se";
clocks = <&gcc GCC_QUPV3_WRAP1_S0_CLK>;
+ dmas = <&gpi_dma1 0 0 QCOM_GPI_I2C>,
+ <&gpi_dma1 1 0 QCOM_GPI_I2C>;
+ dma-names = "tx", "rx";
pinctrl-names = "default";
pinctrl-0 = <&qup_i2c8_default>;
interrupts = <GIC_SPI 353 IRQ_TYPE_LEVEL_HIGH>;
@@ -1206,6 +1257,9 @@
reg-names = "se";
clock-names = "se";
clocks = <&gcc GCC_QUPV3_WRAP1_S0_CLK>;
+ dmas = <&gpi_dma1 0 0 QCOM_GPI_SPI>,
+ <&gpi_dma1 1 0 QCOM_GPI_SPI>;
+ dma-names = "tx", "rx";
pinctrl-names = "default";
pinctrl-0 = <&qup_spi8_default>;
interrupts = <GIC_SPI 353 IRQ_TYPE_LEVEL_HIGH>;
@@ -1220,6 +1274,9 @@
reg = <0 0x00a84000 0 0x4000>;
clock-names = "se";
clocks = <&gcc GCC_QUPV3_WRAP1_S1_CLK>;
+ dmas = <&gpi_dma1 0 1 QCOM_GPI_I2C>,
+ <&gpi_dma1 1 1 QCOM_GPI_I2C>;
+ dma-names = "tx", "rx";
pinctrl-names = "default";
pinctrl-0 = <&qup_i2c9_default>;
interrupts = <GIC_SPI 354 IRQ_TYPE_LEVEL_HIGH>;
@@ -1234,6 +1291,9 @@
reg-names = "se";
clock-names = "se";
clocks = <&gcc GCC_QUPV3_WRAP1_S1_CLK>;
+ dmas = <&gpi_dma1 0 1 QCOM_GPI_SPI>,
+ <&gpi_dma1 1 1 QCOM_GPI_SPI>;
+ dma-names = "tx", "rx";
pinctrl-names = "default";
pinctrl-0 = <&qup_spi9_default>;
interrupts = <GIC_SPI 354 IRQ_TYPE_LEVEL_HIGH>;
@@ -1248,6 +1308,9 @@
reg = <0 0x00a88000 0 0x4000>;
clock-names = "se";
clocks = <&gcc GCC_QUPV3_WRAP1_S2_CLK>;
+ dmas = <&gpi_dma1 0 2 QCOM_GPI_I2C>,
+ <&gpi_dma1 1 2 QCOM_GPI_I2C>;
+ dma-names = "tx", "rx";
pinctrl-names = "default";
pinctrl-0 = <&qup_i2c10_default>;
interrupts = <GIC_SPI 355 IRQ_TYPE_LEVEL_HIGH>;
@@ -1262,6 +1325,9 @@
reg-names = "se";
clock-names = "se";
clocks = <&gcc GCC_QUPV3_WRAP1_S2_CLK>;
+ dmas = <&gpi_dma1 0 2 QCOM_GPI_SPI>,
+ <&gpi_dma1 1 2 QCOM_GPI_SPI>;
+ dma-names = "tx", "rx";
pinctrl-names = "default";
pinctrl-0 = <&qup_spi10_default>;
interrupts = <GIC_SPI 355 IRQ_TYPE_LEVEL_HIGH>;
@@ -1276,6 +1342,9 @@
reg = <0 0x00a8c000 0 0x4000>;
clock-names = "se";
clocks = <&gcc GCC_QUPV3_WRAP1_S3_CLK>;
+ dmas = <&gpi_dma1 0 3 QCOM_GPI_I2C>,
+ <&gpi_dma1 1 3 QCOM_GPI_I2C>;
+ dma-names = "tx", "rx";
pinctrl-names = "default";
pinctrl-0 = <&qup_i2c11_default>;
interrupts = <GIC_SPI 356 IRQ_TYPE_LEVEL_HIGH>;
@@ -1290,6 +1359,9 @@
reg-names = "se";
clock-names = "se";
clocks = <&gcc GCC_QUPV3_WRAP1_S3_CLK>;
+ dmas = <&gpi_dma1 0 3 QCOM_GPI_SPI>,
+ <&gpi_dma1 1 3 QCOM_GPI_SPI>;
+ dma-names = "tx", "rx";
pinctrl-names = "default";
pinctrl-0 = <&qup_spi11_default>;
interrupts = <GIC_SPI 356 IRQ_TYPE_LEVEL_HIGH>;
@@ -1313,6 +1385,9 @@
reg = <0 0x00a90000 0 0x4000>;
clock-names = "se";
clocks = <&gcc GCC_QUPV3_WRAP1_S4_CLK>;
+ dmas = <&gpi_dma1 0 4 QCOM_GPI_I2C>,
+ <&gpi_dma1 1 4 QCOM_GPI_I2C>;
+ dma-names = "tx", "rx";
pinctrl-names = "default";
pinctrl-0 = <&qup_i2c12_default>;
interrupts = <GIC_SPI 357 IRQ_TYPE_LEVEL_HIGH>;
@@ -1327,6 +1402,9 @@
reg-names = "se";
clock-names = "se";
clocks = <&gcc GCC_QUPV3_WRAP1_S4_CLK>;
+ dmas = <&gpi_dma1 0 4 QCOM_GPI_SPI>,
+ <&gpi_dma1 1 4 QCOM_GPI_SPI>;
+ dma-names = "tx", "rx";
pinctrl-names = "default";
pinctrl-0 = <&qup_spi12_default>;
interrupts = <GIC_SPI 357 IRQ_TYPE_LEVEL_HIGH>;
@@ -1341,6 +1419,9 @@
reg = <0 0x0094000 0 0x4000>;
clock-names = "se";
clocks = <&gcc GCC_QUPV3_WRAP1_S5_CLK>;
+ dmas = <&gpi_dma2 0 5 QCOM_GPI_I2C>,
+ <&gpi_dma2 1 5 QCOM_GPI_I2C>;
+ dma-names = "tx", "rx";
pinctrl-names = "default";
pinctrl-0 = <&qup_i2c16_default>;
interrupts = <GIC_SPI 358 IRQ_TYPE_LEVEL_HIGH>;
@@ -1355,6 +1436,9 @@
reg-names = "se";
clock-names = "se";
clocks = <&gcc GCC_QUPV3_WRAP1_S5_CLK>;
+ dmas = <&gpi_dma2 0 5 QCOM_GPI_SPI>,
+ <&gpi_dma2 1 5 QCOM_GPI_SPI>;
+ dma-names = "tx", "rx";
pinctrl-names = "default";
pinctrl-0 = <&qup_spi16_default>;
interrupts = <GIC_SPI 358 IRQ_TYPE_LEVEL_HIGH>;
@@ -1406,6 +1490,9 @@
reg = <0 0x00c80000 0 0x4000>;
clock-names = "se";
clocks = <&gcc GCC_QUPV3_WRAP2_S0_CLK>;
+ dmas = <&gpi_dma2 0 0 QCOM_GPI_I2C>,
+ <&gpi_dma2 1 0 QCOM_GPI_I2C>;
+ dma-names = "tx", "rx";
pinctrl-names = "default";
pinctrl-0 = <&qup_i2c17_default>;
interrupts = <GIC_SPI 373 IRQ_TYPE_LEVEL_HIGH>;
@@ -1420,6 +1507,9 @@
reg-names = "se";
clock-names = "se";
clocks = <&gcc GCC_QUPV3_WRAP2_S0_CLK>;
+ dmas = <&gpi_dma2 0 0 QCOM_GPI_SPI>,
+ <&gpi_dma2 1 0 QCOM_GPI_SPI>;
+ dma-names = "tx", "rx";
pinctrl-names = "default";
pinctrl-0 = <&qup_spi17_default>;
interrupts = <GIC_SPI 373 IRQ_TYPE_LEVEL_HIGH>;
@@ -1434,6 +1524,9 @@
reg = <0 0x00c84000 0 0x4000>;
clock-names = "se";
clocks = <&gcc GCC_QUPV3_WRAP2_S1_CLK>;
+ dmas = <&gpi_dma2 0 1 QCOM_GPI_I2C>,
+ <&gpi_dma2 1 1 QCOM_GPI_I2C>;
+ dma-names = "tx", "rx";
pinctrl-names = "default";
pinctrl-0 = <&qup_i2c18_default>;
interrupts = <GIC_SPI 583 IRQ_TYPE_LEVEL_HIGH>;
@@ -1448,6 +1541,9 @@
reg-names = "se";
clock-names = "se";
clocks = <&gcc GCC_QUPV3_WRAP2_S1_CLK>;
+ dmas = <&gpi_dma2 0 1 QCOM_GPI_SPI>,
+ <&gpi_dma2 1 1 QCOM_GPI_SPI>;
+ dma-names = "tx", "rx";
pinctrl-names = "default";
pinctrl-0 = <&qup_spi18_default>;
interrupts = <GIC_SPI 583 IRQ_TYPE_LEVEL_HIGH>;
@@ -1462,6 +1558,9 @@
reg = <0 0x00c88000 0 0x4000>;
clock-names = "se";
clocks = <&gcc GCC_QUPV3_WRAP2_S2_CLK>;
+ dmas = <&gpi_dma2 0 2 QCOM_GPI_I2C>,
+ <&gpi_dma2 1 2 QCOM_GPI_I2C>;
+ dma-names = "tx", "rx";
pinctrl-names = "default";
pinctrl-0 = <&qup_i2c19_default>;
interrupts = <GIC_SPI 584 IRQ_TYPE_LEVEL_HIGH>;
@@ -1476,6 +1575,9 @@
reg-names = "se";
clock-names = "se";
clocks = <&gcc GCC_QUPV3_WRAP2_S2_CLK>;
+ dmas = <&gpi_dma2 0 2 QCOM_GPI_SPI>,
+ <&gpi_dma2 1 2 QCOM_GPI_SPI>;
+ dma-names = "tx", "rx";
pinctrl-names = "default";
pinctrl-0 = <&qup_spi19_default>;
interrupts = <GIC_SPI 584 IRQ_TYPE_LEVEL_HIGH>;
@@ -1490,6 +1592,9 @@
reg = <0 0x00c8c000 0 0x4000>;
clock-names = "se";
clocks = <&gcc GCC_QUPV3_WRAP2_S3_CLK>;
+ dmas = <&gpi_dma2 0 3 QCOM_GPI_I2C>,
+ <&gpi_dma2 1 3 QCOM_GPI_I2C>;
+ dma-names = "tx", "rx";
pinctrl-names = "default";
pinctrl-0 = <&qup_i2c13_default>;
interrupts = <GIC_SPI 585 IRQ_TYPE_LEVEL_HIGH>;
@@ -1504,6 +1609,9 @@
reg-names = "se";
clock-names = "se";
clocks = <&gcc GCC_QUPV3_WRAP2_S3_CLK>;
+ dmas = <&gpi_dma2 0 3 QCOM_GPI_SPI>,
+ <&gpi_dma2 1 3 QCOM_GPI_SPI>;
+ dma-names = "tx", "rx";
pinctrl-names = "default";
pinctrl-0 = <&qup_spi13_default>;
interrupts = <GIC_SPI 585 IRQ_TYPE_LEVEL_HIGH>;
@@ -1518,6 +1626,9 @@
reg = <0 0x00c90000 0 0x4000>;
clock-names = "se";
clocks = <&gcc GCC_QUPV3_WRAP2_S4_CLK>;
+ dmas = <&gpi_dma2 0 4 QCOM_GPI_I2C>,
+ <&gpi_dma2 1 4 QCOM_GPI_I2C>;
+ dma-names = "tx", "rx";
pinctrl-names = "default";
pinctrl-0 = <&qup_i2c14_default>;
interrupts = <GIC_SPI 586 IRQ_TYPE_LEVEL_HIGH>;
@@ -1532,6 +1643,9 @@
reg-names = "se";
clock-names = "se";
clocks = <&gcc GCC_QUPV3_WRAP2_S4_CLK>;
+ dmas = <&gpi_dma2 0 4 QCOM_GPI_SPI>,
+ <&gpi_dma2 1 4 QCOM_GPI_SPI>;
+ dma-names = "tx", "rx";
pinctrl-names = "default";
pinctrl-0 = <&qup_spi14_default>;
interrupts = <GIC_SPI 586 IRQ_TYPE_LEVEL_HIGH>;
@@ -1546,6 +1660,9 @@
reg = <0 0x00c94000 0 0x4000>;
clock-names = "se";
clocks = <&gcc GCC_QUPV3_WRAP2_S5_CLK>;
+ dmas = <&gpi_dma2 0 5 QCOM_GPI_I2C>,
+ <&gpi_dma2 1 5 QCOM_GPI_I2C>;
+ dma-names = "tx", "rx";
pinctrl-names = "default";
pinctrl-0 = <&qup_i2c15_default>;
interrupts = <GIC_SPI 587 IRQ_TYPE_LEVEL_HIGH>;
@@ -1560,6 +1677,9 @@
reg-names = "se";
clock-names = "se";
clocks = <&gcc GCC_QUPV3_WRAP2_S5_CLK>;
+ dmas = <&gpi_dma2 0 5 QCOM_GPI_SPI>,
+ <&gpi_dma2 1 5 QCOM_GPI_SPI>;
+ dma-names = "tx", "rx";
pinctrl-names = "default";
pinctrl-0 = <&qup_spi15_default>;
interrupts = <GIC_SPI 587 IRQ_TYPE_LEVEL_HIGH>;
@@ -3556,9 +3676,9 @@
qcom,tcs-offset = <0xd00>;
qcom,drv-id = <2>;
qcom,tcs-config = <ACTIVE_TCS 2>,
- <SLEEP_TCS 1>,
- <WAKE_TCS 1>,
- <CONTROL_TCS 0>;
+ <SLEEP_TCS 3>,
+ <WAKE_TCS 3>,
+ <CONTROL_TCS 1>;
rpmhcc: clock-controller {
compatible = "qcom,sm8150-rpmh-clk";
@@ -3649,6 +3769,30 @@
#freq-domain-cells = <1>;
};
+ lmh_cluster1: lmh@18350800 {
+ compatible = "qcom,sm8150-lmh";
+ reg = <0 0x18350800 0 0x400>;
+ interrupts = <GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>;
+ cpus = <&CPU4>;
+ qcom,lmh-temp-arm-millicelsius = <60000>;
+ qcom,lmh-temp-low-millicelsius = <84500>;
+ qcom,lmh-temp-high-millicelsius = <85000>;
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ };
+
+ lmh_cluster0: lmh@18358800 {
+ compatible = "qcom,sm8150-lmh";
+ reg = <0 0x18358800 0 0x400>;
+ interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
+ cpus = <&CPU0>;
+ qcom,lmh-temp-arm-millicelsius = <60000>;
+ qcom,lmh-temp-low-millicelsius = <84500>;
+ qcom,lmh-temp-high-millicelsius = <85000>;
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ };
+
wifi: wifi@18800000 {
compatible = "qcom,wcn3990-wifi";
reg = <0 0x18800000 0 0x800000>;
@@ -4265,7 +4409,7 @@
};
};
- gpu-thermal-top {
+ gpu-top-thermal {
polling-delay-passive = <250>;
polling-delay = <1000>;
@@ -4445,7 +4589,7 @@
};
};
- gpu-thermal-bottom {
+ gpu-bottom-thermal {
polling-delay-passive = <250>;
polling-delay = <1000>;
diff --git a/arch/arm64/boot/dts/qcom/sm8250.dtsi b/arch/arm64/boot/dts/qcom/sm8250.dtsi
index 5617a46e5ccd..fdaf303ba047 100644
--- a/arch/arm64/boot/dts/qcom/sm8250.dtsi
+++ b/arch/arm64/boot/dts/qcom/sm8250.dtsi
@@ -98,6 +98,8 @@
capacity-dmips-mhz = <448>;
dynamic-power-coefficient = <205>;
next-level-cache = <&L2_0>;
+ power-domains = <&CPU_PD0>;
+ power-domain-names = "psci";
qcom,freq-domain = <&cpufreq_hw 0>;
operating-points-v2 = <&cpu0_opp_table>;
interconnects = <&gem_noc MASTER_AMPSS_M0 &mc_virt SLAVE_EBI_CH0>,
@@ -120,6 +122,8 @@
capacity-dmips-mhz = <448>;
dynamic-power-coefficient = <205>;
next-level-cache = <&L2_100>;
+ power-domains = <&CPU_PD1>;
+ power-domain-names = "psci";
qcom,freq-domain = <&cpufreq_hw 0>;
operating-points-v2 = <&cpu0_opp_table>;
interconnects = <&gem_noc MASTER_AMPSS_M0 &mc_virt SLAVE_EBI_CH0>,
@@ -139,6 +143,8 @@
capacity-dmips-mhz = <448>;
dynamic-power-coefficient = <205>;
next-level-cache = <&L2_200>;
+ power-domains = <&CPU_PD2>;
+ power-domain-names = "psci";
qcom,freq-domain = <&cpufreq_hw 0>;
operating-points-v2 = <&cpu0_opp_table>;
interconnects = <&gem_noc MASTER_AMPSS_M0 &mc_virt SLAVE_EBI_CH0>,
@@ -158,6 +164,8 @@
capacity-dmips-mhz = <448>;
dynamic-power-coefficient = <205>;
next-level-cache = <&L2_300>;
+ power-domains = <&CPU_PD3>;
+ power-domain-names = "psci";
qcom,freq-domain = <&cpufreq_hw 0>;
operating-points-v2 = <&cpu0_opp_table>;
interconnects = <&gem_noc MASTER_AMPSS_M0 &mc_virt SLAVE_EBI_CH0>,
@@ -177,6 +185,8 @@
capacity-dmips-mhz = <1024>;
dynamic-power-coefficient = <379>;
next-level-cache = <&L2_400>;
+ power-domains = <&CPU_PD4>;
+ power-domain-names = "psci";
qcom,freq-domain = <&cpufreq_hw 1>;
operating-points-v2 = <&cpu4_opp_table>;
interconnects = <&gem_noc MASTER_AMPSS_M0 &mc_virt SLAVE_EBI_CH0>,
@@ -196,6 +206,8 @@
capacity-dmips-mhz = <1024>;
dynamic-power-coefficient = <379>;
next-level-cache = <&L2_500>;
+ power-domains = <&CPU_PD5>;
+ power-domain-names = "psci";
qcom,freq-domain = <&cpufreq_hw 1>;
operating-points-v2 = <&cpu4_opp_table>;
interconnects = <&gem_noc MASTER_AMPSS_M0 &mc_virt SLAVE_EBI_CH0>,
@@ -216,6 +228,8 @@
capacity-dmips-mhz = <1024>;
dynamic-power-coefficient = <379>;
next-level-cache = <&L2_600>;
+ power-domains = <&CPU_PD6>;
+ power-domain-names = "psci";
qcom,freq-domain = <&cpufreq_hw 1>;
operating-points-v2 = <&cpu4_opp_table>;
interconnects = <&gem_noc MASTER_AMPSS_M0 &mc_virt SLAVE_EBI_CH0>,
@@ -235,6 +249,8 @@
capacity-dmips-mhz = <1024>;
dynamic-power-coefficient = <444>;
next-level-cache = <&L2_700>;
+ power-domains = <&CPU_PD7>;
+ power-domain-names = "psci";
qcom,freq-domain = <&cpufreq_hw 2>;
operating-points-v2 = <&cpu7_opp_table>;
interconnects = <&gem_noc MASTER_AMPSS_M0 &mc_virt SLAVE_EBI_CH0>,
@@ -281,6 +297,42 @@
};
};
};
+
+ idle-states {
+ entry-method = "psci";
+
+ LITTLE_CPU_SLEEP_0: cpu-sleep-0-0 {
+ compatible = "arm,idle-state";
+ idle-state-name = "silver-rail-power-collapse";
+ arm,psci-suspend-param = <0x40000004>;
+ entry-latency-us = <360>;
+ exit-latency-us = <531>;
+ min-residency-us = <3934>;
+ local-timer-stop;
+ };
+
+ BIG_CPU_SLEEP_0: cpu-sleep-1-0 {
+ compatible = "arm,idle-state";
+ idle-state-name = "gold-rail-power-collapse";
+ arm,psci-suspend-param = <0x40000004>;
+ entry-latency-us = <702>;
+ exit-latency-us = <1061>;
+ min-residency-us = <4488>;
+ local-timer-stop;
+ };
+ };
+
+ domain-idle-states {
+ CLUSTER_SLEEP_0: cluster-sleep-0 {
+ compatible = "domain-idle-state";
+ idle-state-name = "cluster-llcc-off";
+ arm,psci-suspend-param = <0x4100c244>;
+ entry-latency-us = <3264>;
+ exit-latency-us = <6562>;
+ min-residency-us = <9987>;
+ local-timer-stop;
+ };
+ };
};
cpu0_opp_table: cpu0_opp_table {
@@ -594,6 +646,59 @@
psci {
compatible = "arm,psci-1.0";
method = "smc";
+
+ CPU_PD0: cpu0 {
+ #power-domain-cells = <0>;
+ power-domains = <&CLUSTER_PD>;
+ domain-idle-states = <&LITTLE_CPU_SLEEP_0>;
+ };
+
+ CPU_PD1: cpu1 {
+ #power-domain-cells = <0>;
+ power-domains = <&CLUSTER_PD>;
+ domain-idle-states = <&LITTLE_CPU_SLEEP_0>;
+ };
+
+ CPU_PD2: cpu2 {
+ #power-domain-cells = <0>;
+ power-domains = <&CLUSTER_PD>;
+ domain-idle-states = <&LITTLE_CPU_SLEEP_0>;
+ };
+
+ CPU_PD3: cpu3 {
+ #power-domain-cells = <0>;
+ power-domains = <&CLUSTER_PD>;
+ domain-idle-states = <&LITTLE_CPU_SLEEP_0>;
+ };
+
+ CPU_PD4: cpu4 {
+ #power-domain-cells = <0>;
+ power-domains = <&CLUSTER_PD>;
+ domain-idle-states = <&BIG_CPU_SLEEP_0>;
+ };
+
+ CPU_PD5: cpu5 {
+ #power-domain-cells = <0>;
+ power-domains = <&CLUSTER_PD>;
+ domain-idle-states = <&BIG_CPU_SLEEP_0>;
+ };
+
+ CPU_PD6: cpu6 {
+ #power-domain-cells = <0>;
+ power-domains = <&CLUSTER_PD>;
+ domain-idle-states = <&BIG_CPU_SLEEP_0>;
+ };
+
+ CPU_PD7: cpu7 {
+ #power-domain-cells = <0>;
+ power-domains = <&CLUSTER_PD>;
+ domain-idle-states = <&BIG_CPU_SLEEP_0>;
+ };
+
+ CLUSTER_PD: cpu-cluster0 {
+ #power-domain-cells = <0>;
+ domain-idle-states = <&CLUSTER_SLEEP_0>;
+ };
};
reserved-memory {
@@ -1740,8 +1845,8 @@
phys = <&pcie0_lane>;
phy-names = "pciephy";
- perst-gpio = <&tlmm 79 GPIO_ACTIVE_LOW>;
- enable-gpio = <&tlmm 81 GPIO_ACTIVE_HIGH>;
+ perst-gpios = <&tlmm 79 GPIO_ACTIVE_LOW>;
+ wake-gpios = <&tlmm 81 GPIO_ACTIVE_HIGH>;
pinctrl-names = "default";
pinctrl-0 = <&pcie0_default_state>;
@@ -1801,7 +1906,7 @@
ranges = <0x01000000 0x0 0x40200000 0x0 0x40200000 0x0 0x100000>,
<0x02000000 0x0 0x40300000 0x0 0x40300000 0x0 0x1fd00000>;
- interrupts = <GIC_SPI 306 IRQ_TYPE_EDGE_RISING>;
+ interrupts = <GIC_SPI 307 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "msi";
#interrupt-cells = <1>;
interrupt-map-mask = <0 0 0 0x7>;
@@ -1844,8 +1949,8 @@
phys = <&pcie1_lane>;
phy-names = "pciephy";
- perst-gpio = <&tlmm 82 GPIO_ACTIVE_LOW>;
- enable-gpio = <&tlmm 84 GPIO_ACTIVE_HIGH>;
+ perst-gpios = <&tlmm 82 GPIO_ACTIVE_LOW>;
+ wake-gpios = <&tlmm 84 GPIO_ACTIVE_HIGH>;
pinctrl-names = "default";
pinctrl-0 = <&pcie1_default_state>;
@@ -1907,7 +2012,7 @@
ranges = <0x01000000 0x0 0x64200000 0x0 0x64200000 0x0 0x100000>,
<0x02000000 0x0 0x64300000 0x0 0x64300000 0x0 0x3d00000>;
- interrupts = <GIC_SPI 236 IRQ_TYPE_EDGE_RISING>;
+ interrupts = <GIC_SPI 243 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "msi";
#interrupt-cells = <1>;
interrupt-map-mask = <0 0 0 0x7>;
@@ -1950,8 +2055,8 @@
phys = <&pcie2_lane>;
phy-names = "pciephy";
- perst-gpio = <&tlmm 85 GPIO_ACTIVE_LOW>;
- enable-gpio = <&tlmm 87 GPIO_ACTIVE_HIGH>;
+ perst-gpios = <&tlmm 85 GPIO_ACTIVE_LOW>;
+ wake-gpios = <&tlmm 87 GPIO_ACTIVE_HIGH>;
pinctrl-names = "default";
pinctrl-0 = <&pcie2_default_state>;
@@ -4320,7 +4425,7 @@
apr {
compatible = "qcom,apr-v2";
qcom,glink-channels = "apr_audio_svc";
- qcom,apr-domain = <APR_DOMAIN_ADSP>;
+ qcom,domain = <APR_DOMAIN_ADSP>;
#address-cells = <1>;
#size-cells = <0>;
@@ -4571,7 +4676,10 @@
clocks = <&rpmhcc RPMH_CXO_CLK>, <&gcc GPLL0>;
clock-names = "xo", "alternate";
-
+ interrupts = <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "dcvsh-irq-0", "dcvsh-irq-1", "dcvsh-irq-2";
#freq-domain-cells = <1>;
};
};
@@ -5172,7 +5280,7 @@
};
};
- gpu-thermal-top {
+ gpu-top-thermal {
polling-delay-passive = <250>;
polling-delay = <1000>;
@@ -5307,7 +5415,7 @@
};
};
- gpu-thermal-bottom {
+ gpu-bottom-thermal {
polling-delay-passive = <250>;
polling-delay = <1000>;
diff --git a/arch/arm64/boot/dts/qcom/sm8350.dtsi b/arch/arm64/boot/dts/qcom/sm8350.dtsi
index 53b39e718fb6..d242bab69c2e 100644
--- a/arch/arm64/boot/dts/qcom/sm8350.dtsi
+++ b/arch/arm64/boot/dts/qcom/sm8350.dtsi
@@ -35,6 +35,24 @@
clock-frequency = <32000>;
#clock-cells = <0>;
};
+
+ ufs_phy_rx_symbol_0_clk: ufs-phy-rx-symbol-0 {
+ compatible = "fixed-clock";
+ clock-frequency = <1000>;
+ #clock-cells = <0>;
+ };
+
+ ufs_phy_rx_symbol_1_clk: ufs-phy-rx-symbol-1 {
+ compatible = "fixed-clock";
+ clock-frequency = <1000>;
+ #clock-cells = <0>;
+ };
+
+ ufs_phy_tx_symbol_0_clk: ufs-phy-tx-symbol-0 {
+ compatible = "fixed-clock";
+ clock-frequency = <1000>;
+ #clock-cells = <0>;
+ };
};
cpus {
@@ -603,9 +621,9 @@
<0>,
<0>,
<0>,
- <0>,
- <0>,
- <0>,
+ <&ufs_phy_rx_symbol_0_clk>,
+ <&ufs_phy_rx_symbol_1_clk>,
+ <&ufs_phy_tx_symbol_0_clk>,
<0>,
<0>;
};
@@ -1425,6 +1443,8 @@
interconnect-names = "memory",
"config";
+ qcom,qmp = <&aoss_qmp>;
+
qcom,smem-states = <&ipa_smp2p_out 0>,
<&ipa_smp2p_out 1>;
qcom,smem-state-names = "ipa-clock-enabled-valid",
@@ -1802,7 +1822,7 @@
qcom,tcs-offset = <0xd00>;
qcom,drv-id = <2>;
qcom,tcs-config = <ACTIVE_TCS 2>, <SLEEP_TCS 3>,
- <WAKE_TCS 3>, <CONTROL_TCS 1>;
+ <WAKE_TCS 3>, <CONTROL_TCS 0>;
rpmhcc: clock-controller {
compatible = "qcom,sm8350-rpmh-clk";
@@ -1923,8 +1943,8 @@
<75000000 300000000>,
<0 0>,
<0 0>,
- <75000000 300000000>,
- <75000000 300000000>;
+ <0 0>,
+ <0 0>;
status = "disabled";
};
@@ -2991,7 +3011,7 @@
};
};
- gpu-thermal-top {
+ gpu-top-thermal {
polling-delay-passive = <250>;
polling-delay = <1000>;
@@ -3006,7 +3026,7 @@
};
};
- gpu-thermal-bottom {
+ gpu-bottom-thermal {
polling-delay-passive = <250>;
polling-delay = <1000>;
@@ -3096,7 +3116,7 @@
};
};
- modem1-thermal-top {
+ modem1-top-thermal {
polling-delay-passive = <250>;
polling-delay = <1000>;
@@ -3111,7 +3131,7 @@
};
};
- modem2-thermal-top {
+ modem2-top-thermal {
polling-delay-passive = <250>;
polling-delay = <1000>;
@@ -3126,7 +3146,7 @@
};
};
- modem3-thermal-top {
+ modem3-top-thermal {
polling-delay-passive = <250>;
polling-delay = <1000>;
@@ -3141,7 +3161,7 @@
};
};
- modem4-thermal-top {
+ modem4-top-thermal {
polling-delay-passive = <250>;
polling-delay = <1000>;
@@ -3156,7 +3176,7 @@
};
};
- camera-thermal-top {
+ camera-top-thermal {
polling-delay-passive = <250>;
polling-delay = <1000>;
@@ -3171,7 +3191,7 @@
};
};
- cam-thermal-bottom {
+ cam-bottom-thermal {
polling-delay-passive = <250>;
polling-delay = <1000>;
diff --git a/arch/arm64/boot/dts/qcom/sm8450-hdk.dts b/arch/arm64/boot/dts/qcom/sm8450-hdk.dts
new file mode 100644
index 000000000000..f0fcb1428449
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sm8450-hdk.dts
@@ -0,0 +1,405 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2022, Linaro Limited
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/regulator/qcom,rpmh-regulator.h>
+#include "sm8450.dtsi"
+
+/ {
+ model = "Qualcomm Technologies, Inc. SM8450 HDK";
+ compatible = "qcom,sm8450-hdk", "qcom,sm8450";
+
+ aliases {
+ serial0 = &uart7;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+
+ vph_pwr: vph-pwr-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "vph_pwr";
+ regulator-min-microvolt = <3700000>;
+ regulator-max-microvolt = <3700000>;
+
+ regulator-always-on;
+ regulator-boot-on;
+ };
+};
+
+&apps_rsc {
+ pm8350-rpmh-regulators {
+ compatible = "qcom,pm8350-rpmh-regulators";
+ qcom,pmic-id = "b";
+
+ vdd-s1-supply = <&vph_pwr>;
+ vdd-s2-supply = <&vph_pwr>;
+ vdd-s3-supply = <&vph_pwr>;
+ vdd-s4-supply = <&vph_pwr>;
+ vdd-s5-supply = <&vph_pwr>;
+ vdd-s6-supply = <&vph_pwr>;
+ vdd-s7-supply = <&vph_pwr>;
+ vdd-s8-supply = <&vph_pwr>;
+ vdd-s9-supply = <&vph_pwr>;
+ vdd-s10-supply = <&vph_pwr>;
+ vdd-s11-supply = <&vph_pwr>;
+ vdd-s12-supply = <&vph_pwr>;
+
+ vdd-l1-l4-supply = <&vreg_s11b_0p95>;
+ vdd-l2-l7-supply = <&vreg_bob>;
+ vdd-l3-l5-supply = <&vreg_bob>;
+ vdd-l6-l9-l10-supply = <&vreg_s12b_1p25>;
+ vdd-l8-supply = <&vreg_s2h_0p95>;
+
+ vreg_s10b_1p8: smps10 {
+ regulator-name = "vreg_s10b_1p8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ vreg_s11b_0p95: smps11 {
+ regulator-name = "vreg_s11b_0p95";
+ regulator-min-microvolt = <966000>;
+ regulator-max-microvolt = <1104000>;
+ };
+
+ vreg_s12b_1p25: smps12 {
+ regulator-name = "vreg_s12b_1p25";
+ regulator-min-microvolt = <1350000>;
+ regulator-max-microvolt = <1400000>;
+ };
+
+ vreg_l1b_0p91: ldo1 {
+ regulator-name = "vreg_l1b_0p91";
+ regulator-min-microvolt = <912000>;
+ regulator-max-microvolt = <920000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l2b_3p07: ldo2 {
+ regulator-name = "vreg_l2b_3p07";
+ regulator-min-microvolt = <3072000>;
+ regulator-max-microvolt = <3072000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l3b_0p9: ldo3 {
+ regulator-name = "vreg_l3b_0p9";
+ regulator-min-microvolt = <904000>;
+ regulator-max-microvolt = <904000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l5b_0p88: ldo5 {
+ regulator-name = "vreg_l5b_0p88";
+ regulator-min-microvolt = <880000>;
+ regulator-max-microvolt = <888000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l6b_1p2: ldo6 {
+ regulator-name = "vreg_l6b_1p2";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l7b_2p5: ldo7 {
+ regulator-name = "vreg_l7b_2p5";
+ regulator-min-microvolt = <2504000>;
+ regulator-max-microvolt = <2504000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l9b_1p2: ldo9 {
+ regulator-name = "vreg_l9b_1p2";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+ };
+
+ pm8350c-rpmh-regulators {
+ compatible = "qcom,pm8350c-rpmh-regulators";
+ qcom,pmic-id = "c";
+
+ vdd-s1-supply = <&vph_pwr>;
+ vdd-s2-supply = <&vph_pwr>;
+ vdd-s3-supply = <&vph_pwr>;
+ vdd-s4-supply = <&vph_pwr>;
+ vdd-s5-supply = <&vph_pwr>;
+ vdd-s6-supply = <&vph_pwr>;
+ vdd-s7-supply = <&vph_pwr>;
+ vdd-s8-supply = <&vph_pwr>;
+ vdd-s9-supply = <&vph_pwr>;
+ vdd-s10-supply = <&vph_pwr>;
+
+ vdd-l1-l12-supply = <&vreg_bob>;
+ vdd-l2-l8-supply = <&vreg_bob>;
+ vdd-l3-l4-l5-l7-l13-supply = <&vreg_bob>;
+ vdd-l6-l9-l11-supply = <&vreg_bob>;
+ vdd-l10-supply = <&vreg_s12b_1p25>;
+
+ vdd-bob-supply = <&vph_pwr>;
+
+ vreg_s1c_1p86: smps1 {
+ regulator-name = "vreg_s1c_1p86";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <2024000>;
+ };
+
+ vreg_s10c_1p05: smps10 {
+ regulator-name = "vreg_s10c_1p05";
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1100000>;
+ };
+
+ vreg_bob: bob {
+ regulator-name = "vreg_bob";
+ regulator-min-microvolt = <3008000>;
+ regulator-max-microvolt = <3960000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_AUTO>;
+ };
+
+ vreg_l1c_1p8: ldo1 {
+ regulator-name = "vreg_l1c_1p8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l3c_3p0: ldo3 {
+ regulator-name = "vreg_l3c_3p0";
+ regulator-min-microvolt = <3296000>;
+ regulator-max-microvolt = <3304000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l4c_1p8: ldo4 {
+ regulator-name = "vreg_l4c_1p8";
+ regulator-min-microvolt = <1704000>;
+ regulator-max-microvolt = <3000000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l5c_1p8: ldo5 {
+ regulator-name = "vreg_l5c_1p8";
+ regulator-min-microvolt = <1704000>;
+ regulator-max-microvolt = <3000000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l6c_1p8: ldo6 {
+ regulator-name = "vreg_l6c_1p8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3008000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l7c_3p0: ldo7 {
+ regulator-name = "vreg_l7c_3p0";
+ regulator-min-microvolt = <3008000>;
+ regulator-max-microvolt = <3008000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l8c_1p8: ldo8 {
+ regulator-name = "vreg_l8c_1p8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l9c_2p96: ldo9 {
+ regulator-name = "vreg_l9c_2p96";
+ regulator-min-microvolt = <2960000>;
+ regulator-max-microvolt = <3008000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l12c_1p8: ldo12 {
+ regulator-name = "vreg_l12c_1p8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1968000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l13c_3p0: ldo13 {
+ regulator-name = "vreg_l13c_3p0";
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3000000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+ };
+
+ pm8450-rpmh-regulators {
+ compatible = "qcom,pm8450-rpmh-regulators";
+ qcom,pmic-id = "h";
+
+ vdd-s1-supply = <&vph_pwr>;
+ vdd-s2-supply = <&vph_pwr>;
+ vdd-s3-supply = <&vph_pwr>;
+ vdd-s4-supply = <&vph_pwr>;
+ vdd-s5-supply = <&vph_pwr>;
+ vdd-s6-supply = <&vph_pwr>;
+
+ vdd-l2-supply = <&vreg_bob>;
+ vdd-l3-supply = <&vreg_bob>;
+ vdd-l4-supply = <&vreg_bob>;
+
+ vreg_s2h_0p95: smps2 {
+ regulator-name = "vreg_s2h_0p95";
+ regulator-min-microvolt = <848000>;
+ regulator-max-microvolt = <1104000>;
+ };
+
+ vreg_s3h_0p5: smps3 {
+ regulator-name = "vreg_s3h_0p5";
+ regulator-min-microvolt = <500000>;
+ regulator-max-microvolt = <500000>;
+ };
+
+ vreg_l2h_0p91: ldo2 {
+ regulator-name = "vreg_l2h_0p91";
+ regulator-min-microvolt = <880000>;
+ regulator-max-microvolt = <912000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ vreg_l3h_0p91: ldo3 {
+ regulator-name = "vreg_l3h_0p91";
+ regulator-min-microvolt = <912000>;
+ regulator-max-microvolt = <912000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ };
+
+ pmr735a-rpmh-regulators {
+ compatible = "qcom,pmr735a-rpmh-regulators";
+ qcom,pmic-id = "e";
+
+ vdd-s1-supply = <&vph_pwr>;
+ vdd-s2-supply = <&vph_pwr>;
+ vdd-s3-supply = <&vph_pwr>;
+
+ vdd-l1-l2-supply = <&vreg_s2e_0p85>;
+ vdd-l3-supply = <&vreg_s1e_1p25>;
+ vdd-l4-supply = <&vreg_s1c_1p86>;
+ vdd-l5-l6-supply = <&vreg_s1c_1p86>;
+ vdd-l7-bob-supply = <&vreg_bob>;
+
+ vreg_s1e_1p25: smps1 {
+ regulator-name = "vreg_s1e_1p25";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1296000>;
+ };
+
+ vreg_s2e_0p85: smps2 {
+ regulator-name = "vreg_s2e_0p85";
+ regulator-min-microvolt = <500000>;
+ regulator-max-microvolt = <1040000>;
+ };
+
+ vreg_l1e_0p8: ldo1 {
+ regulator-name = "vreg_l1e_0p8";
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <800000>;
+ };
+
+ vreg_l2e_0p8: ldo2 {
+ regulator-name = "vreg_l2e_0p8";
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <800000>;
+ };
+
+ vreg_l3e_1p2: ldo3 {
+ regulator-name = "vreg_l3e_1p2";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ };
+
+ vreg_l4e_1p7: ldo4 {
+ regulator-name = "vreg_l4e_1p7";
+ regulator-min-microvolt = <1776000>;
+ regulator-max-microvolt = <1776000>;
+ };
+
+ vreg_l5e_0p88: ldo5 {
+ regulator-name = "vreg_l5e_0p88";
+ regulator-min-microvolt = <880000>;
+ regulator-max-microvolt = <880000>;
+ };
+
+ vreg_l6e_1p2: ldo6 {
+ regulator-name = "vreg_l6e_1p2";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ };
+
+ vreg_l7e_2p8: ldo7 {
+ regulator-name = "vreg_l7e_2p8";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ };
+ };
+};
+
+&qupv3_id_0 {
+ status = "okay";
+};
+
+&tlmm {
+ gpio-reserved-ranges = <28 4>, <36 4>;
+};
+
+&uart7 {
+ status = "okay";
+};
+
+&ufs_mem_hc {
+ status = "okay";
+
+ reset-gpios = <&tlmm 210 GPIO_ACTIVE_LOW>;
+
+ vcc-supply = <&vreg_l7b_2p5>;
+ vcc-max-microamp = <1100000>;
+ vccq-supply = <&vreg_l9b_1p2>;
+ vccq-max-microamp = <1200000>;
+};
+
+&ufs_mem_phy {
+ status = "okay";
+
+ vdda-phy-supply = <&vreg_l5b_0p88>;
+ vdda-pll-supply = <&vreg_l6b_1p2>;
+ vdda-max-microamp = <173000>;
+ vdda-pll-max-microamp = <24900>;
+};
+
+&usb_1 {
+ status = "okay";
+};
+
+&usb_1_dwc3 {
+ dr_mode = "peripheral";
+};
+
+&usb_1_hsphy {
+ status = "okay";
+
+ vdda-pll-supply = <&vreg_l5b_0p88>;
+ vdda18-supply = <&vreg_l1c_1p8>;
+ vdda33-supply = <&vreg_l2b_3p07>;
+};
+
+&usb_1_qmpphy {
+ status = "okay";
+
+ vdda-phy-supply = <&vreg_l6b_1p2>;
+ vdda-pll-supply = <&vreg_l1b_0p91>;
+};
diff --git a/arch/arm64/boot/dts/qcom/sm8450-qrd.dts b/arch/arm64/boot/dts/qcom/sm8450-qrd.dts
index b68ab247e6ae..9526632d4029 100644
--- a/arch/arm64/boot/dts/qcom/sm8450-qrd.dts
+++ b/arch/arm64/boot/dts/qcom/sm8450-qrd.dts
@@ -346,6 +346,26 @@
status = "okay";
};
+&remoteproc_adsp {
+ status = "okay";
+ firmware-name = "qcom/sm8450/adsp.mbn";
+};
+
+&remoteproc_cdsp {
+ status = "okay";
+ firmware-name = "qcom/sm8450/cdsp.mbn";
+};
+
+&remoteproc_mpss {
+ status = "okay";
+ firmware-name = "qcom/sm8450/modem.mbn";
+};
+
+&remoteproc_slpi {
+ status = "okay";
+ firmware-name = "qcom/sm8450/slpi.mbn";
+};
+
&tlmm {
gpio-reserved-ranges = <28 4>, <36 4>;
};
diff --git a/arch/arm64/boot/dts/qcom/sm8450.dtsi b/arch/arm64/boot/dts/qcom/sm8450.dtsi
index 10c25ad2d0c7..934e29b9e153 100644
--- a/arch/arm64/boot/dts/qcom/sm8450.dtsi
+++ b/arch/arm64/boot/dts/qcom/sm8450.dtsi
@@ -7,7 +7,9 @@
#include <dt-bindings/clock/qcom,gcc-sm8450.h>
#include <dt-bindings/clock/qcom,rpmh.h>
#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/mailbox/qcom-ipcc.h>
#include <dt-bindings/power/qcom-rpmpd.h>
+#include <dt-bindings/interconnect/qcom,sm8450.h>
#include <dt-bindings/soc/qcom,rpmh-rsc.h>
/ {
@@ -203,9 +205,9 @@
compatible = "arm,idle-state";
idle-state-name = "silver-rail-power-collapse";
arm,psci-suspend-param = <0x40000004>;
- entry-latency-us = <274>;
- exit-latency-us = <480>;
- min-residency-us = <3934>;
+ entry-latency-us = <800>;
+ exit-latency-us = <750>;
+ min-residency-us = <4090>;
local-timer-stop;
};
@@ -213,9 +215,9 @@
compatible = "arm,idle-state";
idle-state-name = "gold-rail-power-collapse";
arm,psci-suspend-param = <0x40000004>;
- entry-latency-us = <327>;
- exit-latency-us = <1502>;
- min-residency-us = <4488>;
+ entry-latency-us = <600>;
+ exit-latency-us = <1550>;
+ min-residency-us = <4791>;
local-timer-stop;
};
};
@@ -224,10 +226,10 @@
CLUSTER_SLEEP_0: cluster-sleep-0 {
compatible = "domain-idle-state";
idle-state-name = "cluster-l3-off";
- arm,psci-suspend-param = <0x4100c344>;
- entry-latency-us = <584>;
- exit-latency-us = <2332>;
- min-residency-us = <6118>;
+ arm,psci-suspend-param = <0x41000044>;
+ entry-latency-us = <1050>;
+ exit-latency-us = <2500>;
+ min-residency-us = <5309>;
local-timer-stop;
};
@@ -235,9 +237,9 @@
compatible = "domain-idle-state";
idle-state-name = "cluster-power-collapse";
arm,psci-suspend-param = <0x4100c344>;
- entry-latency-us = <2893>;
- exit-latency-us = <4023>;
- min-residency-us = <9987>;
+ entry-latency-us = <2700>;
+ exit-latency-us = <3500>;
+ min-residency-us = <13959>;
local-timer-stop;
};
};
@@ -250,6 +252,18 @@
};
};
+ clk_virt: interconnect@0 {
+ compatible = "qcom,sm8450-clk-virt";
+ #interconnect-cells = <2>;
+ qcom,bcm-voters = <&apps_bcm_voter>;
+ };
+
+ mc_virt: interconnect@1 {
+ compatible = "qcom,sm8450-mc-virt";
+ #interconnect-cells = <2>;
+ qcom,bcm-voters = <&apps_bcm_voter>;
+ };
+
memory@a0000000 {
device_type = "memory";
/* We expect the bootloader to fill in the size */
@@ -315,7 +329,7 @@
CLUSTER_PD: cpu-cluster0 {
#power-domain-cells = <0>;
- domain-idle-states = <&CLUSTER_SLEEP_0>;
+ domain-idle-states = <&CLUSTER_SLEEP_0>, <&CLUSTER_SLEEP_1>;
};
};
@@ -460,6 +474,15 @@
no-map;
};
+ rmtfs_mem: memory@9fd00000 {
+ compatible = "qcom,rmtfs-mem";
+ reg = <0x0 0x9fd00000 0x0 0x280000>;
+ no-map;
+
+ qcom,client-id = <1>;
+ qcom,vmid = <15>;
+ };
+
global_sync_mem: memory@a6f00000 {
reg = <0x0 0xa6f00000 0x0 0x100000>;
no-map;
@@ -540,6 +563,113 @@
};
};
+ smp2p-adsp {
+ compatible = "qcom,smp2p";
+ qcom,smem = <443>, <429>;
+ interrupts-extended = <&ipcc IPCC_CLIENT_LPASS
+ IPCC_MPROC_SIGNAL_SMP2P
+ IRQ_TYPE_EDGE_RISING>;
+ mboxes = <&ipcc IPCC_CLIENT_LPASS
+ IPCC_MPROC_SIGNAL_SMP2P>;
+
+ 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";
+ qcom,smem = <94>, <432>;
+ interrupts-extended = <&ipcc IPCC_CLIENT_CDSP
+ IPCC_MPROC_SIGNAL_SMP2P
+ IRQ_TYPE_EDGE_RISING>;
+ mboxes = <&ipcc IPCC_CLIENT_CDSP
+ IPCC_MPROC_SIGNAL_SMP2P>;
+
+ 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>;
+ };
+ };
+
+ smp2p-modem {
+ compatible = "qcom,smp2p";
+ qcom,smem = <435>, <428>;
+ interrupts-extended = <&ipcc IPCC_CLIENT_MPSS
+ IPCC_MPROC_SIGNAL_SMP2P
+ IRQ_TYPE_EDGE_RISING>;
+ mboxes = <&ipcc IPCC_CLIENT_MPSS
+ IPCC_MPROC_SIGNAL_SMP2P>;
+
+ qcom,local-pid = <0>;
+ qcom,remote-pid = <1>;
+
+ smp2p_modem_out: master-kernel {
+ qcom,entry-name = "master-kernel";
+ #qcom,smem-state-cells = <1>;
+ };
+
+ smp2p_modem_in: slave-kernel {
+ qcom,entry-name = "slave-kernel";
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ ipa_smp2p_out: ipa-ap-to-modem {
+ qcom,entry-name = "ipa";
+ #qcom,smem-state-cells = <1>;
+ };
+
+ ipa_smp2p_in: ipa-modem-to-ap {
+ qcom,entry-name = "ipa";
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+ };
+
+ smp2p-slpi {
+ compatible = "qcom,smp2p";
+ qcom,smem = <481>, <430>;
+ interrupts-extended = <&ipcc IPCC_CLIENT_SLPI
+ IPCC_MPROC_SIGNAL_SMP2P
+ IRQ_TYPE_EDGE_RISING>;
+ mboxes = <&ipcc IPCC_CLIENT_SLPI
+ IPCC_MPROC_SIGNAL_SMP2P>;
+
+ qcom,local-pid = <0>;
+ qcom,remote-pid = <3>;
+
+ smp2p_slpi_out: master-kernel {
+ qcom,entry-name = "master-kernel";
+ #qcom,smem-state-cells = <1>;
+ };
+
+ smp2p_slpi_in: slave-kernel {
+ qcom,entry-name = "slave-kernel";
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+ };
+
soc: soc@0 {
#address-cells = <2>;
#size-cells = <2>;
@@ -620,6 +750,54 @@
};
};
+ config_noc: interconnect@1500000 {
+ compatible = "qcom,sm8450-config-noc";
+ reg = <0 0x01500000 0 0x1c000>;
+ #interconnect-cells = <2>;
+ qcom,bcm-voters = <&apps_bcm_voter>;
+ };
+
+ system_noc: interconnect@1680000 {
+ compatible = "qcom,sm8450-system-noc";
+ reg = <0 0x01680000 0 0x1e200>;
+ #interconnect-cells = <2>;
+ qcom,bcm-voters = <&apps_bcm_voter>;
+ };
+
+ pcie_noc: interconnect@16c0000 {
+ compatible = "qcom,sm8450-pcie-anoc";
+ reg = <0 0x016c0000 0 0xe280>;
+ #interconnect-cells = <2>;
+ qcom,bcm-voters = <&apps_bcm_voter>;
+ };
+
+ aggre1_noc: interconnect@16e0000 {
+ compatible = "qcom,sm8450-aggre1-noc";
+ reg = <0 0x016e0000 0 0x1c080>;
+ #interconnect-cells = <2>;
+ clocks = <&gcc GCC_AGGRE_UFS_PHY_AXI_CLK>,
+ <&gcc GCC_AGGRE_USB3_PRIM_AXI_CLK>;
+ qcom,bcm-voters = <&apps_bcm_voter>;
+ };
+
+ aggre2_noc: interconnect@1700000 {
+ compatible = "qcom,sm8450-aggre2-noc";
+ reg = <0 0x01700000 0 0x31080>;
+ #interconnect-cells = <2>;
+ qcom,bcm-voters = <&apps_bcm_voter>;
+ clocks = <&gcc GCC_AGGRE_NOC_PCIE_0_AXI_CLK>,
+ <&gcc GCC_AGGRE_NOC_PCIE_1_AXI_CLK>,
+ <&gcc GCC_AGGRE_UFS_PHY_AXI_CLK>,
+ <&rpmhcc RPMH_IPA_CLK>;
+ };
+
+ mmss_noc: interconnect@1740000 {
+ compatible = "qcom,sm8450-mmss-noc";
+ reg = <0 0x01740000 0 0x1f080>;
+ #interconnect-cells = <2>;
+ qcom,bcm-voters = <&apps_bcm_voter>;
+ };
+
tcsr_mutex: hwlock@1f40000 {
compatible = "qcom,tcsr-mutex";
reg = <0x0 0x01f40000 0x0 0x40000>;
@@ -672,6 +850,167 @@
};
};
+ remoteproc_slpi: remoteproc@2400000 {
+ compatible = "qcom,sm8450-slpi-pas";
+ reg = <0 0x02400000 0 0x4000>;
+
+ interrupts-extended = <&pdc 9 IRQ_TYPE_LEVEL_HIGH>,
+ <&smp2p_slpi_in 0 IRQ_TYPE_EDGE_RISING>,
+ <&smp2p_slpi_in 1 IRQ_TYPE_EDGE_RISING>,
+ <&smp2p_slpi_in 2 IRQ_TYPE_EDGE_RISING>,
+ <&smp2p_slpi_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 SM8450_LCX>,
+ <&rpmhpd SM8450_LMX>;
+ power-domain-names = "lcx", "lmx";
+
+ memory-region = <&slpi_mem>;
+
+ qcom,qmp = <&aoss_qmp>;
+
+ qcom,smem-states = <&smp2p_slpi_out 0>;
+ qcom,smem-state-names = "stop";
+
+ status = "disabled";
+
+ glink-edge {
+ interrupts-extended = <&ipcc IPCC_CLIENT_SLPI
+ IPCC_MPROC_SIGNAL_GLINK_QMP
+ IRQ_TYPE_EDGE_RISING>;
+ mboxes = <&ipcc IPCC_CLIENT_SLPI
+ IPCC_MPROC_SIGNAL_GLINK_QMP>;
+
+ label = "slpi";
+ qcom,remote-pid = <3>;
+ };
+ };
+
+ remoteproc_adsp: remoteproc@30000000 {
+ compatible = "qcom,sm8450-adsp-pas";
+ reg = <0 0x030000000 0 0x100>;
+
+ interrupts-extended = <&pdc 6 IRQ_TYPE_LEVEL_HIGH>,
+ <&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 SM8450_LCX>,
+ <&rpmhpd SM8450_LMX>;
+ power-domain-names = "lcx", "lmx";
+
+ memory-region = <&adsp_mem>;
+
+ qcom,qmp = <&aoss_qmp>;
+
+ qcom,smem-states = <&smp2p_adsp_out 0>;
+ qcom,smem-state-names = "stop";
+
+ status = "disabled";
+
+ remoteproc_adsp_glink: 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>;
+ };
+ };
+
+ remoteproc_cdsp: remoteproc@32300000 {
+ compatible = "qcom,sm8450-cdsp-pas";
+ reg = <0 0x032300000 0 0x1400000>;
+
+ interrupts-extended = <&intc GIC_SPI 578 IRQ_TYPE_LEVEL_HIGH>,
+ <&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 SM8450_CX>,
+ <&rpmhpd SM8450_MXC>;
+ power-domain-names = "cx", "mxc";
+
+ memory-region = <&cdsp_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>;
+ };
+ };
+
+ remoteproc_mpss: remoteproc@4080000 {
+ compatible = "qcom,sm8450-mpss-pas";
+ reg = <0x0 0x04080000 0x0 0x4040>;
+
+ interrupts-extended = <&intc GIC_SPI 264 IRQ_TYPE_LEVEL_HIGH>,
+ <&smp2p_modem_in 0 IRQ_TYPE_EDGE_RISING>,
+ <&smp2p_modem_in 1 IRQ_TYPE_EDGE_RISING>,
+ <&smp2p_modem_in 2 IRQ_TYPE_EDGE_RISING>,
+ <&smp2p_modem_in 3 IRQ_TYPE_EDGE_RISING>,
+ <&smp2p_modem_in 7 IRQ_TYPE_EDGE_RISING>;
+ interrupt-names = "wdog", "fatal", "ready", "handover",
+ "stop-ack", "shutdown-ack";
+
+ clocks = <&rpmhcc RPMH_CXO_CLK>;
+ clock-names = "xo";
+
+ power-domains = <&rpmhpd 0>,
+ <&rpmhpd 12>;
+ power-domain-names = "cx", "mss";
+
+ memory-region = <&mpss_mem>;
+
+ qcom,qmp = <&aoss_qmp>;
+
+ qcom,smem-states = <&smp2p_modem_out 0>;
+ qcom,smem-state-names = "stop";
+
+ status = "disabled";
+
+ glink-edge {
+ interrupts-extended = <&ipcc IPCC_CLIENT_MPSS
+ IPCC_MPROC_SIGNAL_GLINK_QMP
+ IRQ_TYPE_EDGE_RISING>;
+ mboxes = <&ipcc IPCC_CLIENT_MPSS
+ IPCC_MPROC_SIGNAL_GLINK_QMP>;
+ interrupts = <GIC_SPI 449 IRQ_TYPE_EDGE_RISING>;
+ label = "modem";
+ qcom,remote-pid = <1>;
+ };
+ };
+
pdc: interrupt-controller@b220000 {
compatible = "qcom,sm8450-pdc", "qcom,pdc";
reg = <0 0x0b220000 0 0x30000>, <0 0x174000f0 0 0x64>;
@@ -682,6 +1021,25 @@
interrupt-controller;
};
+ aoss_qmp: power-controller@c300000 {
+ compatible = "qcom,sm8450-aoss-qmp", "qcom,aoss-qmp";
+ reg = <0 0x0c300000 0 0x400>;
+ 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>;
+ };
+
+ ipcc: mailbox@ed18000 {
+ compatible = "qcom,sm8450-ipcc", "qcom,ipcc";
+ reg = <0 0x0ed18000 0 0x1000>;
+ interrupts = <GIC_SPI 229 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-controller;
+ #interrupt-cells = <3>;
+ #mbox-cells = <2>;
+ };
+
tlmm: pinctrl@f100000 {
compatible = "qcom,sm8450-tlmm";
reg = <0 0x0f100000 0 0x300000>;
@@ -726,7 +1084,7 @@
compatible = "qcom,sm8450-smmu-500", "arm,mmu-500";
reg = <0 0x15000000 0 0x100000>;
#iommu-cells = <2>;
- #global-interrupts = <2>;
+ #global-interrupts = <1>;
interrupts = <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 97 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>,
@@ -813,6 +1171,7 @@
<GIC_SPI 412 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 421 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 707 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 423 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 424 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 425 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 690 IRQ_TYPE_LEVEL_HIGH>,
@@ -988,6 +1347,20 @@
#freq-domain-cells = <1>;
};
+ gem_noc: interconnect@19100000 {
+ compatible = "qcom,sm8450-gem-noc";
+ reg = <0 0x19100000 0 0xbb800>;
+ #interconnect-cells = <2>;
+ qcom,bcm-voters = <&apps_bcm_voter>;
+ };
+
+ system-cache-controller@19200000 {
+ compatible = "qcom,sm8450-llcc";
+ reg = <0 0x19200000 0 0x580000>, <0 0x19a00000 0 0x80000>;
+ reg-names = "llcc_base", "llcc_broadcast_base";
+ interrupts = <GIC_SPI 266 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
ufs_mem_hc: ufshc@1d84000 {
compatible = "qcom,sm8450-ufshc", "qcom,ufshc",
"jedec,ufs-2.0";
@@ -1004,6 +1377,9 @@
iommus = <&apps_smmu 0xe0 0x0>;
+ interconnects = <&aggre1_noc MASTER_UFS_MEM &mc_virt SLAVE_EBI1>,
+ <&gem_noc MASTER_APPSS_PROC &config_noc SLAVE_UFS_MEM_CFG>;
+ interconnect-names = "ufs-ddr", "cpu-ufs";
clock-names =
"core_clk",
"bus_aggr_clk",
@@ -1072,9 +1448,10 @@
<&gcc GCC_USB30_PRIM_MASTER_CLK>,
<&gcc GCC_AGGRE_USB3_PRIM_AXI_CLK>,
<&gcc GCC_USB30_PRIM_MOCK_UTMI_CLK>,
- <&gcc GCC_USB30_PRIM_SLEEP_CLK>;
+ <&gcc GCC_USB30_PRIM_SLEEP_CLK>,
+ <&gcc GCC_USB3_0_CLKREF_EN>;
clock-names = "cfg_noc", "core", "iface", "mock_utmi",
- "sleep";
+ "sleep", "xo";
assigned-clocks = <&gcc GCC_USB30_PRIM_MOCK_UTMI_CLK>,
<&gcc GCC_USB30_PRIM_MASTER_CLK>;
@@ -1102,6 +1479,20 @@
phy-names = "usb2-phy", "usb3-phy";
};
};
+
+ nsp_noc: interconnect@320c0000 {
+ compatible = "qcom,sm8450-nsp-noc";
+ reg = <0 0x320c0000 0 0x10000>;
+ #interconnect-cells = <2>;
+ qcom,bcm-voters = <&apps_bcm_voter>;
+ };
+
+ lpass_ag_noc: interconnect@3c40000 {
+ compatible = "qcom,sm8450-lpass-ag-noc";
+ reg = <0 0x3c40000 0 0x17200>;
+ #interconnect-cells = <2>;
+ qcom,bcm-voters = <&apps_bcm_voter>;
+ };
};
timer {
diff --git a/arch/arm64/boot/dts/renesas/Makefile b/arch/arm64/boot/dts/renesas/Makefile
index 5bc8065a7864..d000f6b131dc 100644
--- a/arch/arm64/boot/dts/renesas/Makefile
+++ b/arch/arm64/boot/dts/renesas/Makefile
@@ -75,4 +75,7 @@ dtb-$(CONFIG_ARCH_R8A77961) += r8a779m3-ulcb-kf.dtb
dtb-$(CONFIG_ARCH_R8A77965) += r8a779m5-salvator-xs.dtb
+dtb-$(CONFIG_ARCH_R9A07G044) += r9a07g044c2-smarc.dtb
dtb-$(CONFIG_ARCH_R9A07G044) += r9a07g044l2-smarc.dtb
+
+dtb-$(CONFIG_ARCH_R9A07G054) += r9a07g054l2-smarc.dtb
diff --git a/arch/arm64/boot/dts/renesas/beacon-renesom-baseboard.dtsi b/arch/arm64/boot/dts/renesas/beacon-renesom-baseboard.dtsi
index 2692cc64bff6..5ad6cd1864c1 100644
--- a/arch/arm64/boot/dts/renesas/beacon-renesom-baseboard.dtsi
+++ b/arch/arm64/boot/dts/renesas/beacon-renesom-baseboard.dtsi
@@ -359,11 +359,10 @@
clocks = <&x304_clk>;
clock-names = "xin";
- assigned-clocks = <&versaclock6_bb 1>,
- <&versaclock6_bb 2>,
- <&versaclock6_bb 3>,
- <&versaclock6_bb 4>;
- assigned-clock-rates = <24000000>, <24000000>, <24000000>, <24576000>;
+ assigned-clocks = <&versaclock6_bb 1>, <&versaclock6_bb 2>,
+ <&versaclock6_bb 3>, <&versaclock6_bb 4>;
+ assigned-clock-rates = <24000000>, <24000000>, <24000000>,
+ <24576000>;
OUT1 {
idt,mode = <VC5_CMOS>;
diff --git a/arch/arm64/boot/dts/renesas/beacon-renesom-som.dtsi b/arch/arm64/boot/dts/renesas/beacon-renesom-som.dtsi
index 0d136809eb96..877d076ffcc9 100644
--- a/arch/arm64/boot/dts/renesas/beacon-renesom-som.dtsi
+++ b/arch/arm64/boot/dts/renesas/beacon-renesom-som.dtsi
@@ -77,7 +77,7 @@
};
&gpio6 {
- usb_hub_reset {
+ usb-hub-reset-hog {
gpio-hog;
gpios = <10 GPIO_ACTIVE_HIGH>;
output-high;
@@ -293,7 +293,6 @@
vqmmc-supply = <&reg_1p8v>;
non-removable;
cap-power-off-card;
- pm-ignore-notify;
keep-power-in-suspend;
mmc-pwrseq = <&wlan_pwrseq>;
status = "okay";
diff --git a/arch/arm64/boot/dts/renesas/gmsl-cameras.dtsi b/arch/arm64/boot/dts/renesas/gmsl-cameras.dtsi
new file mode 100644
index 000000000000..d45f072f8cdf
--- /dev/null
+++ b/arch/arm64/boot/dts/renesas/gmsl-cameras.dtsi
@@ -0,0 +1,332 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2017 Ideas on Board <kieran.bingham@ideasonboard.com>
+ * Copyright (C) 2021 Jacopo Mondi <jacopo+renesas@jmondi.org>
+ *
+ * Device Tree Source (overlay) that describes GMSL camera connected to
+ * Fakra connectors for the Eagle V3M and Condor V3H (and compatible) boards.
+ *
+ * The following cameras are currently supported: RDACM20 and RDACM21.
+ *
+ * The board .dts file that include this has to select which cameras are in use
+ * by specifying the camera model with:
+ *
+ * #define GMSL_CAMERA_RDACM20
+ * or
+ * #define GMSL_CAMERA_RDACM21
+ *
+ * And which cameras are connected to the board by defining:
+ * for GMSL channel 0:
+ * #define GMSL_CAMERA_0
+ * #define GMSL_CAMERA_1
+ * #define GMSL_CAMERA_2
+ * #define GMSL_CAMERA_3
+ *
+ * for GMSL channel 1:
+ * #define GMSL_CAMERA_4
+ * #define GMSL_CAMERA_5
+ * #define GMSL_CAMERA_6
+ * #define GMSL_CAMERA_7
+ */
+
+#include <dt-bindings/gpio/gpio.h>
+
+/* Validate the board file settings. */
+#if !defined(GMSL_CAMERA_RDACM20) && !defined(GMSL_CAMERA_RDACM21)
+#error "Camera model should be defined by the board file"
+#endif
+
+#if defined(GMSL_CAMERA_RDACM20) && defined(GMSL_CAMERA_RDACM21)
+#error "A single camera model should be selected"
+#endif
+
+#if !defined(GMSL_CAMERA_0) && !defined(GMSL_CAMERA_1) && \
+ !defined(GMSL_CAMERA_2) && !defined(GMSL_CAMERA_3) && \
+ !defined(GMSL_CAMERA_4) && !defined(GMSL_CAMERA_5) && \
+ !defined(GMSL_CAMERA_6) && !defined(GMSL_CAMERA_7)
+#error "At least one camera should be selected"
+#endif
+
+/* Deduce from the enabled cameras which GMSL channels are active. */
+#if defined(GMSL_CAMERA_0) || defined(GMSL_CAMERA_1) || \
+ defined(GMSL_CAMERA_2) || defined(GMSL_CAMERA_3)
+#define GMSL_0
+#endif
+
+#if defined(GMSL_CAMERA_4) || defined(GMSL_CAMERA_5) || \
+ defined(GMSL_CAMERA_6) || defined(GMSL_CAMERA_7)
+#define GMSL_1
+#endif
+
+/* Deduce the camera model compatible string. */
+#if defined(GMSL_CAMERA_RDACM20)
+#define GMSL_CAMERA_MODEL "imi,rdacm20"
+#elif defined(GMSL_CAMERA_RDACM21)
+#define GMSL_CAMERA_MODEL "imi,rdacm21"
+#endif
+
+#ifdef GMSL_0
+&vin0 {
+ status = "okay";
+};
+
+&vin1 {
+ status = "okay";
+};
+
+&vin2 {
+ status = "okay";
+};
+
+&vin3 {
+ status = "okay";
+};
+
+&gmsl0 {
+ status = "okay";
+
+#if defined(GMSL_CAMERA_RDACM21)
+ maxim,reverse-channel-microvolt = <100000>;
+#endif
+
+ ports {
+#ifdef GMSL_CAMERA_0
+ port@0 {
+ max9286_in0: endpoint {
+ remote-endpoint = <&fakra_con0>;
+ };
+ };
+#endif
+
+#ifdef GMSL_CAMERA_1
+ port@1 {
+ max9286_in1: endpoint{
+ remote-endpoint = <&fakra_con1>;
+ };
+
+ };
+#endif
+
+#ifdef GMSL_CAMERA_2
+ port@2 {
+ max9286_in2: endpoint {
+ remote-endpoint = <&fakra_con2>;
+ };
+
+ };
+#endif
+
+#ifdef GMSL_CAMERA_3
+ port@3 {
+ max9286_in3: endpoint {
+ remote-endpoint = <&fakra_con3>;
+ };
+
+ };
+#endif
+ };
+
+ i2c-mux {
+#ifdef GMSL_CAMERA_0
+ i2c@0 {
+ status = "okay";
+
+ camera@51 {
+ compatible = GMSL_CAMERA_MODEL;
+ reg = <0x51>, <0x61>;
+
+ port {
+ fakra_con0: endpoint {
+ remote-endpoint = <&max9286_in0>;
+ };
+ };
+ };
+ };
+#endif
+
+#ifdef GMSL_CAMERA_1
+ i2c@1 {
+ status = "okay";
+
+ camera@52 {
+ compatible = GMSL_CAMERA_MODEL;
+ reg = <0x52>, <0x62>;
+
+ port {
+ fakra_con1: endpoint {
+ remote-endpoint = <&max9286_in1>;
+ };
+ };
+ };
+ };
+#endif
+
+#ifdef GMSL_CAMERA_2
+ i2c@2 {
+ status = "okay";
+
+ camera@53 {
+ compatible = GMSL_CAMERA_MODEL;
+ reg = <0x53>, <0x63>;
+
+ port {
+ fakra_con2: endpoint {
+ remote-endpoint = <&max9286_in2>;
+ };
+ };
+ };
+ };
+#endif
+
+#ifdef GMSL_CAMERA_3
+ i2c@3 {
+ status = "okay";
+
+ camera@54 {
+ compatible = GMSL_CAMERA_MODEL;
+ reg = <0x54>, <0x64>;
+
+ port {
+ fakra_con3: endpoint {
+ remote-endpoint = <&max9286_in3>;
+ };
+ };
+ };
+ };
+#endif
+ };
+};
+#endif /* ifdef GMSL_0 */
+
+#ifdef GMSL_1
+&vin4 {
+ status = "okay";
+};
+
+&vin5 {
+ status = "okay";
+};
+
+&vin6 {
+ status = "okay";
+};
+
+&vin7 {
+ status = "okay";
+};
+
+&gmsl1 {
+ status = "okay";
+
+#if defined(GMSL_CAMERA_RDACM21)
+ maxim,reverse-channel-microvolt = <100000>;
+#endif
+
+ ports {
+#ifdef GMSL_CAMERA_4
+ port@0 {
+ max9286_in4: endpoint {
+ remote-endpoint = <&fakra_con4>;
+ };
+ };
+#endif
+
+#ifdef GMSL_CAMERA_5
+ port@1 {
+ max9286_in5: endpoint{
+ remote-endpoint = <&fakra_con5>;
+ };
+
+ };
+#endif
+
+#ifdef GMSL_CAMERA_6
+ port@2 {
+ max9286_in6: endpoint {
+ remote-endpoint = <&fakra_con6>;
+ };
+
+ };
+#endif
+
+#ifdef GMSL_CAMERA_7
+ port@3 {
+ max9286_in7: endpoint {
+ remote-endpoint = <&fakra_con7>;
+ };
+
+ };
+#endif
+ };
+
+ i2c-mux {
+#ifdef GMSL_CAMERA_4
+ i2c@0 {
+ status = "okay";
+
+ camera@55 {
+ compatible = GMSL_CAMERA_MODEL;
+ reg = <0x55>, <0x65>;
+
+ port {
+ fakra_con4: endpoint {
+ remote-endpoint = <&max9286_in4>;
+ };
+ };
+ };
+ };
+#endif
+
+#ifdef GMSL_CAMERA_5
+ i2c@1 {
+ status = "okay";
+
+ camera@56 {
+ compatible = GMSL_CAMERA_MODEL;
+ reg = <0x56>, <0x66>;
+
+ port {
+ fakra_con5: endpoint {
+ remote-endpoint = <&max9286_in5>;
+ };
+ };
+ };
+ };
+#endif
+
+#ifdef GMSL_CAMERA_6
+ i2c@2 {
+ status = "okay";
+
+ camera@57 {
+ compatible = GMSL_CAMERA_MODEL;
+ reg = <0x57>, <0x67>;
+
+ port {
+ fakra_con6: endpoint {
+ remote-endpoint = <&max9286_in6>;
+ };
+ };
+ };
+ };
+#endif
+
+#ifdef GMSL_CAMERA_7
+ i2c@3 {
+ status = "okay";
+
+ camera@58 {
+ compatible = GMSL_CAMERA_MODEL;
+ reg = <0x58>, <0x68>;
+
+ port {
+ fakra_con7: endpoint {
+ remote-endpoint = <&max9286_in7>;
+ };
+ };
+ };
+ };
+#endif
+ };
+};
+#endif /* ifdef GMSL_1 */
diff --git a/arch/arm64/boot/dts/renesas/hihope-common.dtsi b/arch/arm64/boot/dts/renesas/hihope-common.dtsi
index 0c7e6f790590..935d06515aa6 100644
--- a/arch/arm64/boot/dts/renesas/hihope-common.dtsi
+++ b/arch/arm64/boot/dts/renesas/hihope-common.dtsi
@@ -140,7 +140,7 @@
};
&gpio6 {
- usb1-reset {
+ usb1-reset-hog {
gpio-hog;
gpios = <10 GPIO_ACTIVE_LOW>;
output-low;
diff --git a/arch/arm64/boot/dts/renesas/hihope-rzg2-ex-lvds.dtsi b/arch/arm64/boot/dts/renesas/hihope-rzg2-ex-lvds.dtsi
index 40c5e8d6d841..d66d17e34694 100644
--- a/arch/arm64/boot/dts/renesas/hihope-rzg2-ex-lvds.dtsi
+++ b/arch/arm64/boot/dts/renesas/hihope-rzg2-ex-lvds.dtsi
@@ -20,7 +20,7 @@
* When GP1_20 is LOW LVDS0 is connected to the LVDS connector
* When GP1_20 is HIGH LVDS0 is connected to the LT8918L
*/
- lvds-connector-en-gpio {
+ lvds-connector-en-hog {
gpio-hog;
gpios = <20 GPIO_ACTIVE_HIGH>;
output-low;
diff --git a/arch/arm64/boot/dts/renesas/r8a774a1.dtsi b/arch/arm64/boot/dts/renesas/r8a774a1.dtsi
index eda6a840371a..12846125a4c9 100644
--- a/arch/arm64/boot/dts/renesas/r8a774a1.dtsi
+++ b/arch/arm64/boot/dts/renesas/r8a774a1.dtsi
@@ -1698,12 +1698,12 @@
* clkout : #clock-cells = <0>; <&rcar_sound>;
* clkout0/1/2/3: #clock-cells = <1>; <&rcar_sound N>;
*/
- compatible = "renesas,rcar_sound-r8a774a1", "renesas,rcar_sound-gen3";
- reg = <0 0xec500000 0 0x1000>, /* SCU */
- <0 0xec5a0000 0 0x100>, /* ADG */
- <0 0xec540000 0 0x1000>, /* SSIU */
- <0 0xec541000 0 0x280>, /* SSI */
- <0 0xec760000 0 0x200>; /* Audio DMAC peri peri*/
+ compatible = "renesas,rcar_sound-r8a774a1", "renesas,rcar_sound-gen3";
+ reg = <0 0xec500000 0 0x1000>, /* SCU */
+ <0 0xec5a0000 0 0x100>, /* ADG */
+ <0 0xec540000 0 0x1000>, /* SSIU */
+ <0 0xec541000 0 0x280>, /* SSI */
+ <0 0xec760000 0 0x200>; /* Audio DMAC peri peri*/
reg-names = "scu", "adg", "ssiu", "ssi", "audmapp";
clocks = <&cpg CPG_MOD 1005>,
@@ -2010,7 +2010,7 @@
dma-names = "rx", "tx";
};
ssiu40: ssiu-32 {
- dmas = <&audma0 0x71>, <&audma1 0x72>;
+ dmas = <&audma0 0x71>, <&audma1 0x72>;
dma-names = "rx", "tx";
};
ssiu41: ssiu-33 {
diff --git a/arch/arm64/boot/dts/renesas/r8a774b1-beacon-rzg2n-kit.dts b/arch/arm64/boot/dts/renesas/r8a774b1-beacon-rzg2n-kit.dts
index 3c0d59def8ee..89d708346ba8 100644
--- a/arch/arm64/boot/dts/renesas/r8a774b1-beacon-rzg2n-kit.dts
+++ b/arch/arm64/boot/dts/renesas/r8a774b1-beacon-rzg2n-kit.dts
@@ -11,7 +11,7 @@
/ {
model = "Beacon Embedded Works RZ/G2N Development Kit";
- compatible = "beacon,beacon-rzg2n", "renesas,r8a774b1";
+ compatible = "beacon,beacon-rzg2n", "renesas,r8a774b1";
aliases {
serial0 = &scif2;
diff --git a/arch/arm64/boot/dts/renesas/r8a774b1.dtsi b/arch/arm64/boot/dts/renesas/r8a774b1.dtsi
index 44f79fbd75dc..a4b406a346f9 100644
--- a/arch/arm64/boot/dts/renesas/r8a774b1.dtsi
+++ b/arch/arm64/boot/dts/renesas/r8a774b1.dtsi
@@ -1571,7 +1571,7 @@
* clkout : #clock-cells = <0>; <&rcar_sound>;
* clkout0/1/2/3: #clock-cells = <1>; <&rcar_sound N>;
*/
- compatible = "renesas,rcar_sound-r8a774b1", "renesas,rcar_sound-gen3";
+ compatible = "renesas,rcar_sound-r8a774b1", "renesas,rcar_sound-gen3";
reg = <0 0xec500000 0 0x1000>, /* SCU */
<0 0xec5a0000 0 0x100>, /* ADG */
<0 0xec540000 0 0x1000>, /* SSIU */
@@ -1883,7 +1883,7 @@
dma-names = "rx", "tx";
};
ssiu40: ssiu-32 {
- dmas = <&audma0 0x71>, <&audma1 0x72>;
+ dmas = <&audma0 0x71>, <&audma1 0x72>;
dma-names = "rx", "tx";
};
ssiu41: ssiu-33 {
diff --git a/arch/arm64/boot/dts/renesas/r8a774c0-ek874-idk-2121wr.dts b/arch/arm64/boot/dts/renesas/r8a774c0-ek874-idk-2121wr.dts
index a7b27d09f6c2..c1812d1ef06a 100644
--- a/arch/arm64/boot/dts/renesas/r8a774c0-ek874-idk-2121wr.dts
+++ b/arch/arm64/boot/dts/renesas/r8a774c0-ek874-idk-2121wr.dts
@@ -68,7 +68,7 @@
* When GP0_17 is low LVDS[01] are connected to the LVDS connector
* When GP0_17 is high LVDS[01] are connected to the LT8918L
*/
- lvds-connector-en-gpio{
+ lvds-connector-en-hog {
gpio-hog;
gpios = <17 GPIO_ACTIVE_HIGH>;
output-low;
diff --git a/arch/arm64/boot/dts/renesas/r8a774c0.dtsi b/arch/arm64/boot/dts/renesas/r8a774c0.dtsi
index b8dcbbbf3db5..e123c8d1bab9 100644
--- a/arch/arm64/boot/dts/renesas/r8a774c0.dtsi
+++ b/arch/arm64/boot/dts/renesas/r8a774c0.dtsi
@@ -1328,11 +1328,11 @@
*/
compatible = "renesas,rcar_sound-r8a774c0",
"renesas,rcar_sound-gen3";
- reg = <0 0xec500000 0 0x1000>, /* SCU */
- <0 0xec5a0000 0 0x100>, /* ADG */
- <0 0xec540000 0 0x1000>, /* SSIU */
- <0 0xec541000 0 0x280>, /* SSI */
- <0 0xec760000 0 0x200>; /* Audio DMAC peri peri*/
+ reg = <0 0xec500000 0 0x1000>, /* SCU */
+ <0 0xec5a0000 0 0x100>, /* ADG */
+ <0 0xec540000 0 0x1000>, /* SSIU */
+ <0 0xec541000 0 0x280>, /* SSI */
+ <0 0xec760000 0 0x200>; /* Audio DMAC peri peri*/
reg-names = "scu", "adg", "ssiu", "ssi", "audmapp";
clocks = <&cpg CPG_MOD 1005>,
diff --git a/arch/arm64/boot/dts/renesas/r8a774e1-beacon-rzg2h-kit.dts b/arch/arm64/boot/dts/renesas/r8a774e1-beacon-rzg2h-kit.dts
index 7b6649a3ded0..3e9ced3b2d33 100644
--- a/arch/arm64/boot/dts/renesas/r8a774e1-beacon-rzg2h-kit.dts
+++ b/arch/arm64/boot/dts/renesas/r8a774e1-beacon-rzg2h-kit.dts
@@ -11,7 +11,7 @@
/ {
model = "Beacon Embedded Works RZ/G2H Development Kit";
- compatible = "beacon,beacon-rzg2h", "renesas,r8a774e1";
+ compatible = "beacon,beacon-rzg2h", "renesas,r8a774e1";
aliases {
serial0 = &scif2;
diff --git a/arch/arm64/boot/dts/renesas/r8a774e1.dtsi b/arch/arm64/boot/dts/renesas/r8a774e1.dtsi
index e6d8610730a8..989c1c00dcdc 100644
--- a/arch/arm64/boot/dts/renesas/r8a774e1.dtsi
+++ b/arch/arm64/boot/dts/renesas/r8a774e1.dtsi
@@ -1784,7 +1784,7 @@
* clkout : #clock-cells = <0>; <&rcar_sound>;
* clkout0/1/2/3: #clock-cells = <1>; <&rcar_sound N>;
*/
- compatible = "renesas,rcar_sound-r8a774e1", "renesas,rcar_sound-gen3";
+ compatible = "renesas,rcar_sound-r8a774e1", "renesas,rcar_sound-gen3";
reg = <0 0xec500000 0 0x1000>, /* SCU */
<0 0xec5a0000 0 0x100>, /* ADG */
<0 0xec540000 0 0x1000>, /* SSIU */
@@ -2043,7 +2043,7 @@
dma-names = "rx", "tx";
};
ssiu40: ssiu-32 {
- dmas = <&audma0 0x71>, <&audma1 0x72>;
+ dmas = <&audma0 0x71>, <&audma1 0x72>;
dma-names = "rx", "tx";
};
ssiu41: ssiu-33 {
diff --git a/arch/arm64/boot/dts/renesas/r8a77951.dtsi b/arch/arm64/boot/dts/renesas/r8a77951.dtsi
index 9265a5702792..4e87e8776a2b 100644
--- a/arch/arm64/boot/dts/renesas/r8a77951.dtsi
+++ b/arch/arm64/boot/dts/renesas/r8a77951.dtsi
@@ -2018,12 +2018,12 @@
* clkout : #clock-cells = <0>; <&rcar_sound>;
* clkout0/1/2/3: #clock-cells = <1>; <&rcar_sound N>;
*/
- compatible = "renesas,rcar_sound-r8a7795", "renesas,rcar_sound-gen3";
- reg = <0 0xec500000 0 0x1000>, /* SCU */
- <0 0xec5a0000 0 0x100>, /* ADG */
- <0 0xec540000 0 0x1000>, /* SSIU */
- <0 0xec541000 0 0x280>, /* SSI */
- <0 0xec760000 0 0x200>; /* Audio DMAC peri peri*/
+ compatible = "renesas,rcar_sound-r8a7795", "renesas,rcar_sound-gen3";
+ reg = <0 0xec500000 0 0x1000>, /* SCU */
+ <0 0xec5a0000 0 0x100>, /* ADG */
+ <0 0xec540000 0 0x1000>, /* SSIU */
+ <0 0xec541000 0 0x280>, /* SSI */
+ <0 0xec760000 0 0x200>; /* Audio DMAC peri peri*/
reg-names = "scu", "adg", "ssiu", "ssi", "audmapp";
clocks = <&cpg CPG_MOD 1005>,
@@ -2277,7 +2277,7 @@
dma-names = "rx", "tx";
};
ssiu40: ssiu-32 {
- dmas = <&audma0 0x71>, <&audma1 0x72>;
+ dmas = <&audma0 0x71>, <&audma1 0x72>;
dma-names = "rx", "tx";
};
ssiu41: ssiu-33 {
@@ -2412,6 +2412,18 @@
};
};
+ mlp: mlp@ec520000 {
+ compatible = "renesas,r8a7795-mlp",
+ "renesas,rcar-gen3-mlp";
+ reg = <0 0xec520000 0 0x800>;
+ interrupts = <GIC_SPI 384 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 385 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 802>;
+ power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
+ resets = <&cpg 802>;
+ status = "disabled";
+ };
+
audma0: dma-controller@ec700000 {
compatible = "renesas,dmac-r8a7795",
"renesas,rcar-dmac";
diff --git a/arch/arm64/boot/dts/renesas/r8a77960.dtsi b/arch/arm64/boot/dts/renesas/r8a77960.dtsi
index 26f7103d11da..6f79da8cc8c0 100644
--- a/arch/arm64/boot/dts/renesas/r8a77960.dtsi
+++ b/arch/arm64/boot/dts/renesas/r8a77960.dtsi
@@ -1890,12 +1890,12 @@
* clkout : #clock-cells = <0>; <&rcar_sound>;
* clkout0/1/2/3: #clock-cells = <1>; <&rcar_sound N>;
*/
- compatible = "renesas,rcar_sound-r8a7796", "renesas,rcar_sound-gen3";
- reg = <0 0xec500000 0 0x1000>, /* SCU */
- <0 0xec5a0000 0 0x100>, /* ADG */
- <0 0xec540000 0 0x1000>, /* SSIU */
- <0 0xec541000 0 0x280>, /* SSI */
- <0 0xec760000 0 0x200>; /* Audio DMAC peri peri*/
+ compatible = "renesas,rcar_sound-r8a7796", "renesas,rcar_sound-gen3";
+ reg = <0 0xec500000 0 0x1000>, /* SCU */
+ <0 0xec5a0000 0 0x100>, /* ADG */
+ <0 0xec540000 0 0x1000>, /* SSIU */
+ <0 0xec541000 0 0x280>, /* SSI */
+ <0 0xec760000 0 0x200>; /* Audio DMAC peri peri*/
reg-names = "scu", "adg", "ssiu", "ssi", "audmapp";
clocks = <&cpg CPG_MOD 1005>,
@@ -2202,7 +2202,7 @@
dma-names = "rx", "tx";
};
ssiu40: ssiu-32 {
- dmas = <&audma0 0x71>, <&audma1 0x72>;
+ dmas = <&audma0 0x71>, <&audma1 0x72>;
dma-names = "rx", "tx";
};
ssiu41: ssiu-33 {
@@ -2284,6 +2284,18 @@
};
};
+ mlp: mlp@ec520000 {
+ compatible = "renesas,r8a7796-mlp",
+ "renesas,rcar-gen3-mlp";
+ reg = <0 0xec520000 0 0x800>;
+ interrupts = <GIC_SPI 384 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 385 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 802>;
+ power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
+ resets = <&cpg 802>;
+ status = "disabled";
+ };
+
audma0: dma-controller@ec700000 {
compatible = "renesas,dmac-r8a7796",
"renesas,rcar-dmac";
diff --git a/arch/arm64/boot/dts/renesas/r8a77961.dtsi b/arch/arm64/boot/dts/renesas/r8a77961.dtsi
index ac9b587f6fc5..68cbbb322acf 100644
--- a/arch/arm64/boot/dts/renesas/r8a77961.dtsi
+++ b/arch/arm64/boot/dts/renesas/r8a77961.dtsi
@@ -1734,7 +1734,7 @@
* clkout : #clock-cells = <0>; <&rcar_sound>;
* clkout0/1/2/3: #clock-cells = <1>; <&rcar_sound N>;
*/
- compatible = "renesas,rcar_sound-r8a77961", "renesas,rcar_sound-gen3";
+ compatible = "renesas,rcar_sound-r8a77961", "renesas,rcar_sound-gen3";
reg = <0 0xec500000 0 0x1000>, /* SCU */
<0 0xec5a0000 0 0x100>, /* ADG */
<0 0xec540000 0 0x1000>, /* SSIU */
@@ -2046,7 +2046,7 @@
dma-names = "rx", "tx";
};
ssiu40: ssiu-32 {
- dmas = <&audma0 0x71>, <&audma1 0x72>;
+ dmas = <&audma0 0x71>, <&audma1 0x72>;
dma-names = "rx", "tx";
};
ssiu41: ssiu-33 {
@@ -2128,6 +2128,18 @@
};
};
+ mlp: mlp@ec520000 {
+ compatible = "renesas,r8a77961-mlp",
+ "renesas,rcar-gen3-mlp";
+ reg = <0 0xec520000 0 0x800>;
+ interrupts = <GIC_SPI 384 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 385 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 802>;
+ power-domains = <&sysc R8A77961_PD_ALWAYS_ON>;
+ resets = <&cpg 802>;
+ status = "disabled";
+ };
+
audma0: dma-controller@ec700000 {
compatible = "renesas,dmac-r8a77961",
"renesas,rcar-dmac";
@@ -2722,6 +2734,33 @@
port@2 {
reg = <2>;
du_out_lvds0: endpoint {
+ remote-endpoint = <&lvds0_in>;
+ };
+ };
+ };
+ };
+
+ lvds0: lvds@feb90000 {
+ compatible = "renesas,r8a77961-lvds";
+ reg = <0 0xfeb90000 0 0x14>;
+ clocks = <&cpg CPG_MOD 727>;
+ power-domains = <&sysc R8A77961_PD_ALWAYS_ON>;
+ resets = <&cpg 727>;
+ status = "disabled";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+ lvds0_in: endpoint {
+ remote-endpoint = <&du_out_lvds0>;
+ };
+ };
+ port@1 {
+ reg = <1>;
+ lvds0_out: endpoint {
};
};
};
diff --git a/arch/arm64/boot/dts/renesas/r8a77965.dtsi b/arch/arm64/boot/dts/renesas/r8a77965.dtsi
index f898aad72b9d..9f858af8b762 100644
--- a/arch/arm64/boot/dts/renesas/r8a77965.dtsi
+++ b/arch/arm64/boot/dts/renesas/r8a77965.dtsi
@@ -1753,12 +1753,12 @@
* clkout : #clock-cells = <0>; <&rcar_sound>;
* clkout0/1/2/3: #clock-cells = <1>; <&rcar_sound N>;
*/
- compatible = "renesas,rcar_sound-r8a77965", "renesas,rcar_sound-gen3";
- reg = <0 0xec500000 0 0x1000>, /* SCU */
- <0 0xec5a0000 0 0x100>, /* ADG */
- <0 0xec540000 0 0x1000>, /* SSIU */
- <0 0xec541000 0 0x280>, /* SSI */
- <0 0xec760000 0 0x200>; /* Audio DMAC peri peri*/
+ compatible = "renesas,rcar_sound-r8a77965", "renesas,rcar_sound-gen3";
+ reg = <0 0xec500000 0 0x1000>, /* SCU */
+ <0 0xec5a0000 0 0x100>, /* ADG */
+ <0 0xec540000 0 0x1000>, /* SSIU */
+ <0 0xec541000 0 0x280>, /* SSI */
+ <0 0xec760000 0 0x200>; /* Audio DMAC peri peri*/
reg-names = "scu", "adg", "ssiu", "ssi", "audmapp";
clocks = <&cpg CPG_MOD 1005>,
@@ -2012,7 +2012,7 @@
dma-names = "rx", "tx";
};
ssiu40: ssiu-32 {
- dmas = <&audma0 0x71>, <&audma1 0x72>;
+ dmas = <&audma0 0x71>, <&audma1 0x72>;
dma-names = "rx", "tx";
};
ssiu41: ssiu-33 {
@@ -2147,6 +2147,18 @@
};
};
+ mlp: mlp@ec520000 {
+ compatible = "renesas,r8a77965-mlp",
+ "renesas,rcar-gen3-mlp";
+ reg = <0 0xec520000 0 0x800>;
+ interrupts = <GIC_SPI 384 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 385 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 802>;
+ power-domains = <&sysc R8A77965_PD_ALWAYS_ON>;
+ resets = <&cpg 802>;
+ status = "disabled";
+ };
+
audma0: dma-controller@ec700000 {
compatible = "renesas,dmac-r8a77965",
"renesas,rcar-dmac";
diff --git a/arch/arm64/boot/dts/renesas/r8a77970-eagle.dts b/arch/arm64/boot/dts/renesas/r8a77970-eagle.dts
index b579d3189a93..49d1a929aef7 100644
--- a/arch/arm64/boot/dts/renesas/r8a77970-eagle.dts
+++ b/arch/arm64/boot/dts/renesas/r8a77970-eagle.dts
@@ -113,6 +113,20 @@
};
};
+&csi40 {
+ status = "okay";
+
+ ports {
+ port@0 {
+ csi40_in: endpoint {
+ clock-lanes = <0>;
+ data-lanes = <1 2 3 4>;
+ remote-endpoint = <&max9286_out0>;
+ };
+ };
+ };
+};
+
&du {
clocks = <&cpg CPG_MOD 724>, <&x1_clk>;
clock-names = "du.0", "dclkin.0";
@@ -172,6 +186,89 @@
};
};
+&i2c3 {
+ pinctrl-0 = <&i2c3_pins>;
+ pinctrl-names = "default";
+
+ status = "okay";
+ clock-frequency = <400000>;
+
+ gmsl0: gmsl-deserializer@48 {
+ compatible = "maxim,max9286";
+ reg = <0x48>;
+
+ maxim,gpio-poc = <0 GPIO_ACTIVE_LOW>;
+ enable-gpios = <&io_expander 0 GPIO_ACTIVE_HIGH>;
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+ };
+
+ port@1 {
+ reg = <1>;
+ };
+
+ port@2 {
+ reg = <2>;
+ };
+
+ port@3 {
+ reg = <3>;
+ };
+
+ port@4 {
+ reg = <4>;
+ max9286_out0: endpoint {
+ clock-lanes = <0>;
+ data-lanes = <1 2 3 4>;
+ remote-endpoint = <&csi40_in>;
+ };
+ };
+ };
+
+ i2c-mux {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ i2c@0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0>;
+
+ status = "disabled";
+ };
+
+ i2c@1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <1>;
+
+ status = "disabled";
+ };
+
+ i2c@2 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <2>;
+
+ status = "disabled";
+ };
+
+ i2c@3 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <3>;
+
+ status = "disabled";
+ };
+ };
+ };
+};
+
&lvds0 {
status = "okay";
@@ -200,6 +297,11 @@
function = "i2c0";
};
+ i2c3_pins: i2c3 {
+ groups = "i2c3_a";
+ function = "i2c3";
+ };
+
qspi0_pins: qspi0 {
groups = "qspi0_ctrl", "qspi0_data4";
function = "qspi0";
diff --git a/arch/arm64/boot/dts/renesas/r8a77980-condor.dts b/arch/arm64/boot/dts/renesas/r8a77980-condor.dts
index 3d6d10c82f48..43ed033eb512 100644
--- a/arch/arm64/boot/dts/renesas/r8a77980-condor.dts
+++ b/arch/arm64/boot/dts/renesas/r8a77980-condor.dts
@@ -108,6 +108,34 @@
};
};
+&csi40 {
+ status = "okay";
+
+ ports {
+ port@0 {
+ csi40_in: endpoint {
+ clock-lanes = <0>;
+ data-lanes = <1 2 3 4>;
+ remote-endpoint = <&max9286_out0>;
+ };
+ };
+ };
+};
+
+&csi41 {
+ status = "okay";
+
+ ports {
+ port@0 {
+ csi41_in: endpoint {
+ clock-lanes = <0>;
+ data-lanes = <1 2 3 4>;
+ remote-endpoint = <&max9286_out1>;
+ };
+ };
+ };
+};
+
&du {
clocks = <&cpg CPG_MOD 724>,
<&x1_clk>;
@@ -200,6 +228,164 @@
};
};
+&i2c1 {
+ pinctrl-0 = <&i2c1_pins>;
+ pinctrl-names = "default";
+
+ status = "okay";
+ clock-frequency = <400000>;
+
+ gmsl0: gmsl-deserializer@48 {
+ compatible = "maxim,max9286";
+ reg = <0x48>;
+
+ maxim,gpio-poc = <0 GPIO_ACTIVE_LOW>;
+ enable-gpios = <&io_expander0 0 GPIO_ACTIVE_HIGH>;
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+ };
+
+ port@1 {
+ reg = <1>;
+ };
+
+ port@2 {
+ reg = <2>;
+ };
+
+ port@3 {
+ reg = <3>;
+ };
+
+ port@4 {
+ reg = <4>;
+ max9286_out0: endpoint {
+ clock-lanes = <0>;
+ data-lanes = <1 2 3 4>;
+ remote-endpoint = <&csi40_in>;
+ };
+ };
+ };
+
+ i2c-mux {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ i2c@0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0>;
+
+ status = "disabled";
+ };
+
+ i2c@1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <1>;
+
+ status = "disabled";
+ };
+
+ i2c@2 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <2>;
+
+ status = "disabled";
+ };
+
+ i2c@3 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <3>;
+
+ status = "disabled";
+ };
+ };
+ };
+
+ gmsl1: gmsl-deserializer@4a {
+ compatible = "maxim,max9286";
+ reg = <0x4a>;
+
+ maxim,gpio-poc = <0 GPIO_ACTIVE_LOW>;
+ enable-gpios = <&io_expander1 0 GPIO_ACTIVE_HIGH>;
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+ };
+
+ port@1 {
+ reg = <1>;
+ };
+
+ port@2 {
+ reg = <2>;
+ };
+
+ port@3 {
+ reg = <3>;
+ };
+
+ port@4 {
+ reg = <4>;
+ max9286_out1: endpoint {
+ clock-lanes = <0>;
+ data-lanes = <1 2 3 4>;
+ remote-endpoint = <&csi41_in>;
+ };
+ };
+ };
+
+ i2c-mux {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ i2c@0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0>;
+
+ status = "disabled";
+ };
+
+ i2c@1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <1>;
+
+ status = "disabled";
+ };
+
+ i2c@2 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <2>;
+
+ status = "disabled";
+ };
+
+ i2c@3 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <3>;
+
+ status = "disabled";
+ };
+ };
+ };
+};
+
&lvds0 {
status = "okay";
@@ -256,6 +442,11 @@
function = "i2c0";
};
+ i2c1_pins: i2c1 {
+ groups = "i2c1";
+ function = "i2c1";
+ };
+
mmc_pins: mmc {
groups = "mmc_data8", "mmc_ctrl", "mmc_ds";
function = "mmc";
diff --git a/arch/arm64/boot/dts/renesas/r8a77990.dtsi b/arch/arm64/boot/dts/renesas/r8a77990.dtsi
index 14caedd0c959..7e0f1aab2135 100644
--- a/arch/arm64/boot/dts/renesas/r8a77990.dtsi
+++ b/arch/arm64/boot/dts/renesas/r8a77990.dtsi
@@ -1489,12 +1489,12 @@
* clkout : #clock-cells = <0>; <&rcar_sound>;
* clkout0/1/2/3: #clock-cells = <1>; <&rcar_sound N>;
*/
- compatible = "renesas,rcar_sound-r8a77990", "renesas,rcar_sound-gen3";
- reg = <0 0xec500000 0 0x1000>, /* SCU */
- <0 0xec5a0000 0 0x100>, /* ADG */
- <0 0xec540000 0 0x1000>, /* SSIU */
- <0 0xec541000 0 0x280>, /* SSI */
- <0 0xec760000 0 0x200>; /* Audio DMAC peri peri*/
+ compatible = "renesas,rcar_sound-r8a77990", "renesas,rcar_sound-gen3";
+ reg = <0 0xec500000 0 0x1000>, /* SCU */
+ <0 0xec5a0000 0 0x100>, /* ADG */
+ <0 0xec540000 0 0x1000>, /* SSIU */
+ <0 0xec541000 0 0x280>, /* SSI */
+ <0 0xec760000 0 0x200>; /* Audio DMAC peri peri*/
reg-names = "scu", "adg", "ssiu", "ssi", "audmapp";
clocks = <&cpg CPG_MOD 1005>,
@@ -1682,6 +1682,18 @@
};
};
+ mlp: mlp@ec520000 {
+ compatible = "renesas,r8a77990-mlp",
+ "renesas,rcar-gen3-mlp";
+ reg = <0 0xec520000 0 0x800>;
+ interrupts = <GIC_SPI 384 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 385 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 802>;
+ power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
+ resets = <&cpg 802>;
+ status = "disabled";
+ };
+
audma0: dma-controller@ec700000 {
compatible = "renesas,dmac-r8a77990",
"renesas,rcar-dmac";
diff --git a/arch/arm64/boot/dts/renesas/r8a77995.dtsi b/arch/arm64/boot/dts/renesas/r8a77995.dtsi
index f29f3982a492..cac1f9467ffa 100644
--- a/arch/arm64/boot/dts/renesas/r8a77995.dtsi
+++ b/arch/arm64/boot/dts/renesas/r8a77995.dtsi
@@ -1046,12 +1046,12 @@
* clkout : #clock-cells = <0>; <&rcar_sound>;
* clkout0/1/2/3: #clock-cells = <1>; <&rcar_sound N>;
*/
- compatible = "renesas,rcar_sound-r8a77995", "renesas,rcar_sound-gen3";
- reg = <0 0xec500000 0 0x1000>, /* SCU */
- <0 0xec5a0000 0 0x100>, /* ADG */
- <0 0xec540000 0 0x1000>, /* SSIU */
- <0 0xec541000 0 0x280>, /* SSI */
- <0 0xec740000 0 0x200>; /* Audio DMAC peri peri*/
+ compatible = "renesas,rcar_sound-r8a77995", "renesas,rcar_sound-gen3";
+ reg = <0 0xec500000 0 0x1000>, /* SCU */
+ <0 0xec5a0000 0 0x100>, /* ADG */
+ <0 0xec540000 0 0x1000>, /* SSIU */
+ <0 0xec541000 0 0x280>, /* SSI */
+ <0 0xec740000 0 0x200>; /* Audio DMAC peri peri*/
reg-names = "scu", "adg", "ssiu", "ssi", "audmapp";
clocks = <&cpg CPG_MOD 1005>,
@@ -1132,6 +1132,18 @@
};
};
+ mlp: mlp@ec520000 {
+ compatible = "renesas,r8a77995-mlp",
+ "renesas,rcar-gen3-mlp";
+ reg = <0 0xec520000 0 0x800>;
+ interrupts = <GIC_SPI 384 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 385 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 802>;
+ power-domains = <&sysc R8A77995_PD_ALWAYS_ON>;
+ resets = <&cpg 802>;
+ status = "disabled";
+ };
+
audma0: dma-controller@ec700000 {
compatible = "renesas,dmac-r8a77995",
"renesas,rcar-dmac";
diff --git a/arch/arm64/boot/dts/renesas/r8a779a0-falcon-csi-dsi.dtsi b/arch/arm64/boot/dts/renesas/r8a779a0-falcon-csi-dsi.dtsi
index f791c76f1bcf..e06b8eda85e1 100644
--- a/arch/arm64/boot/dts/renesas/r8a779a0-falcon-csi-dsi.dtsi
+++ b/arch/arm64/boot/dts/renesas/r8a779a0-falcon-csi-dsi.dtsi
@@ -5,6 +5,63 @@
* Copyright (C) 2021 Glider bv
*/
+&csi40 {
+ status = "okay";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ csi40_in: endpoint {
+ clock-lanes = <0>;
+ data-lanes = <1 2 3 4>;
+ remote-endpoint = <&max96712_out0>;
+ };
+ };
+ };
+};
+
+&csi42 {
+ status = "okay";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ csi42_in: endpoint {
+ clock-lanes = <0>;
+ data-lanes = <1 2 3 4>;
+ remote-endpoint = <&max96712_out1>;
+ };
+ };
+ };
+};
+
+&csi43 {
+ status = "okay";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ csi43_in: endpoint {
+ clock-lanes = <0>;
+ data-lanes = <1 2 3 4>;
+ remote-endpoint = <&max96712_out2>;
+ };
+ };
+ };
+};
+
&i2c0 {
pca9654_a: gpio@21 {
compatible = "onnn,pca9654";
@@ -34,3 +91,175 @@
pagesize = <8>;
};
};
+
+&i2c1 {
+ gmsl0: gmsl-deserializer@49 {
+ compatible = "maxim,max96712";
+ reg = <0x49>;
+ enable-gpios = <&pca9654_a 0 GPIO_ACTIVE_HIGH>;
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@4 {
+ reg = <4>;
+ max96712_out0: endpoint {
+ clock-lanes = <0>;
+ data-lanes = <1 2 3 4>;
+ remote-endpoint = <&csi40_in>;
+ };
+ };
+ };
+ };
+
+ gmsl1: gmsl-deserializer@4b {
+ compatible = "maxim,max96712";
+ reg = <0x4b>;
+ enable-gpios = <&pca9654_b 0 GPIO_ACTIVE_HIGH>;
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@4 {
+ reg = <4>;
+ max96712_out1: endpoint {
+ clock-lanes = <0>;
+ data-lanes = <1 2 3 4>;
+ lane-polarities = <0 0 0 0 1>;
+ remote-endpoint = <&csi42_in>;
+ };
+ };
+ };
+ };
+
+ gmsl2: gmsl-deserializer@6b {
+ compatible = "maxim,max96712";
+ reg = <0x6b>;
+ enable-gpios = <&pca9654_c 0 GPIO_ACTIVE_HIGH>;
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@4 {
+ reg = <4>;
+ max96712_out2: endpoint {
+ clock-lanes = <0>;
+ data-lanes = <1 2 3 4>;
+ lane-polarities = <0 0 0 0 1>;
+ remote-endpoint = <&csi43_in>;
+ };
+ };
+ };
+ };
+};
+
+&isp0 {
+ status = "okay";
+};
+
+&isp2 {
+ status = "okay";
+};
+
+&isp3 {
+ status = "okay";
+};
+
+&vin00 {
+ status = "okay";
+};
+
+&vin01 {
+ status = "okay";
+};
+
+&vin02 {
+ status = "okay";
+};
+
+&vin03 {
+ status = "okay";
+};
+
+&vin04 {
+ status = "okay";
+};
+
+&vin05 {
+ status = "okay";
+};
+
+&vin06 {
+ status = "okay";
+};
+
+&vin07 {
+ status = "okay";
+};
+
+&vin16 {
+ status = "okay";
+};
+
+&vin17 {
+ status = "okay";
+};
+
+&vin18 {
+ status = "okay";
+};
+
+&vin19 {
+ status = "okay";
+};
+
+&vin20 {
+ status = "okay";
+};
+
+&vin21 {
+ status = "okay";
+};
+
+&vin22 {
+ status = "okay";
+};
+
+&vin23 {
+ status = "okay";
+};
+
+&vin24 {
+ status = "okay";
+};
+
+&vin25 {
+ status = "okay";
+};
+
+&vin26 {
+ status = "okay";
+};
+
+&vin27 {
+ status = "okay";
+};
+
+&vin28 {
+ status = "okay";
+};
+
+&vin29 {
+ status = "okay";
+};
+
+&vin30 {
+ status = "okay";
+};
+
+&vin31 {
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/renesas/r8a779a0.dtsi b/arch/arm64/boot/dts/renesas/r8a779a0.dtsi
index 1e7ed12ebc87..c4be288b1912 100644
--- a/arch/arm64/boot/dts/renesas/r8a779a0.dtsi
+++ b/arch/arm64/boot/dts/renesas/r8a779a0.dtsi
@@ -102,7 +102,7 @@
interrupts = <GIC_SPI 832 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&cpg CPG_MOD 916>;
power-domains = <&sysc R8A779A0_PD_ALWAYS_ON>;
- resets = <&cpg 916>;
+ resets = <&cpg 916>;
gpio-controller;
#gpio-cells = <2>;
gpio-ranges = <&pfc 0 0 28>;
@@ -116,7 +116,7 @@
interrupts = <GIC_SPI 836 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&cpg CPG_MOD 915>;
power-domains = <&sysc R8A779A0_PD_ALWAYS_ON>;
- resets = <&cpg 915>;
+ resets = <&cpg 915>;
gpio-controller;
#gpio-cells = <2>;
gpio-ranges = <&pfc 0 32 31>;
@@ -130,7 +130,7 @@
interrupts = <GIC_SPI 840 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&cpg CPG_MOD 915>;
power-domains = <&sysc R8A779A0_PD_ALWAYS_ON>;
- resets = <&cpg 915>;
+ resets = <&cpg 915>;
gpio-controller;
#gpio-cells = <2>;
gpio-ranges = <&pfc 0 64 25>;
@@ -144,7 +144,7 @@
interrupts = <GIC_SPI 844 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&cpg CPG_MOD 916>;
power-domains = <&sysc R8A779A0_PD_ALWAYS_ON>;
- resets = <&cpg 916>;
+ resets = <&cpg 916>;
gpio-controller;
#gpio-cells = <2>;
gpio-ranges = <&pfc 0 96 17>;
@@ -158,7 +158,7 @@
interrupts = <GIC_SPI 848 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&cpg CPG_MOD 917>;
power-domains = <&sysc R8A779A0_PD_ALWAYS_ON>;
- resets = <&cpg 917>;
+ resets = <&cpg 917>;
gpio-controller;
#gpio-cells = <2>;
gpio-ranges = <&pfc 0 128 27>;
@@ -172,7 +172,7 @@
interrupts = <GIC_SPI 852 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&cpg CPG_MOD 917>;
power-domains = <&sysc R8A779A0_PD_ALWAYS_ON>;
- resets = <&cpg 917>;
+ resets = <&cpg 917>;
gpio-controller;
#gpio-cells = <2>;
gpio-ranges = <&pfc 0 160 21>;
@@ -186,7 +186,7 @@
interrupts = <GIC_SPI 856 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&cpg CPG_MOD 918>;
power-domains = <&sysc R8A779A0_PD_ALWAYS_ON>;
- resets = <&cpg 918>;
+ resets = <&cpg 918>;
gpio-controller;
#gpio-cells = <2>;
gpio-ranges = <&pfc 0 192 21>;
@@ -200,7 +200,7 @@
interrupts = <GIC_SPI 860 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&cpg CPG_MOD 918>;
power-domains = <&sysc R8A779A0_PD_ALWAYS_ON>;
- resets = <&cpg 918>;
+ resets = <&cpg 918>;
gpio-controller;
#gpio-cells = <2>;
gpio-ranges = <&pfc 0 224 21>;
@@ -214,7 +214,7 @@
interrupts = <GIC_SPI 864 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&cpg CPG_MOD 918>;
power-domains = <&sysc R8A779A0_PD_ALWAYS_ON>;
- resets = <&cpg 918>;
+ resets = <&cpg 918>;
gpio-controller;
#gpio-cells = <2>;
gpio-ranges = <&pfc 0 256 21>;
@@ -228,7 +228,7 @@
interrupts = <GIC_SPI 868 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&cpg CPG_MOD 918>;
power-domains = <&sysc R8A779A0_PD_ALWAYS_ON>;
- resets = <&cpg 918>;
+ resets = <&cpg 918>;
gpio-controller;
#gpio-cells = <2>;
gpio-ranges = <&pfc 0 288 21>;
@@ -340,6 +340,21 @@
#thermal-sensor-cells = <1>;
};
+ intc_ex: interrupt-controller@e61c0000 {
+ compatible = "renesas,intc-ex-r8a779a0", "renesas,irqc";
+ #interrupt-cells = <2>;
+ interrupt-controller;
+ reg = <0 0xe61c0000 0 0x200>;
+ interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_CORE R8A779A0_CLK_CP>;
+ power-domains = <&sysc R8A779A0_PD_ALWAYS_ON>;
+ };
+
tmu0: timer@e61e0000 {
compatible = "renesas,tmu-r8a779a0", "renesas,tmu";
reg = <0 0xe61e0000 0 0x30>;
diff --git a/arch/arm64/boot/dts/renesas/r8a779f0-spider-cpu.dtsi b/arch/arm64/boot/dts/renesas/r8a779f0-spider-cpu.dtsi
index 156586532c84..6e07c54148e7 100644
--- a/arch/arm64/boot/dts/renesas/r8a779f0-spider-cpu.dtsi
+++ b/arch/arm64/boot/dts/renesas/r8a779f0-spider-cpu.dtsi
@@ -31,6 +31,34 @@
clock-frequency = <32768>;
};
+&pfc {
+ pinctrl-0 = <&scif_clk_pins>;
+ pinctrl-names = "default";
+
+ scif3_pins: scif3 {
+ groups = "scif3_data", "scif3_ctrl";
+ function = "scif3";
+ };
+
+ scif_clk_pins: scif_clk {
+ groups = "scif_clk";
+ function = "scif_clk";
+ };
+};
+
+&rwdt {
+ timeout-sec = <60>;
+ status = "okay";
+};
+
&scif3 {
+ pinctrl-0 = <&scif3_pins>;
+ pinctrl-names = "default";
+
+ uart-has-rtscts;
status = "okay";
};
+
+&scif_clk {
+ clock-frequency = <24000000>;
+};
diff --git a/arch/arm64/boot/dts/renesas/r8a779f0.dtsi b/arch/arm64/boot/dts/renesas/r8a779f0.dtsi
index eda597766eaf..f4e549867371 100644
--- a/arch/arm64/boot/dts/renesas/r8a779f0.dtsi
+++ b/arch/arm64/boot/dts/renesas/r8a779f0.dtsi
@@ -59,6 +59,22 @@
#size-cells = <2>;
ranges;
+ rwdt: watchdog@e6020000 {
+ compatible = "renesas,r8a779f0-wdt",
+ "renesas,rcar-gen4-wdt";
+ reg = <0 0xe6020000 0 0x0c>;
+ clocks = <&cpg CPG_MOD 907>;
+ power-domains = <&sysc R8A779F0_PD_ALWAYS_ON>;
+ resets = <&cpg 907>;
+ status = "disabled";
+ };
+
+ pfc: pinctrl@e6050000 {
+ compatible = "renesas,pfc-r8a779f0";
+ reg = <0 0xe6050000 0 0x16c>, <0 0xe6050800 0 0x16c>,
+ <0 0xe6051000 0 0x16c>, <0 0xe6051800 0 0x16c>;
+ };
+
cpg: clock-controller@e6150000 {
compatible = "renesas,r8a779f0-cpg-mssr";
reg = <0 0xe6150000 0 0x4000>;
@@ -94,6 +110,76 @@
status = "disabled";
};
+ dmac0: dma-controller@e7350000 {
+ compatible = "renesas,dmac-r8a779f0",
+ "renesas,rcar-gen4-dmac";
+ reg = <0 0xe7350000 0 0x1000>,
+ <0 0xe7300000 0 0x10000>;
+ interrupts = <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 102 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 104 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 105 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 107 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 111 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 115 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>;
+ 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 R8A779F0_PD_ALWAYS_ON>;
+ resets = <&cpg 709>;
+ #dma-cells = <1>;
+ dma-channels = <16>;
+ };
+
+ dmac1: dma-controller@e7351000 {
+ compatible = "renesas,dmac-r8a779f0",
+ "renesas,rcar-gen4-dmac";
+ reg = <0 0xe7351000 0 0x1000>,
+ <0 0xe7310000 0 0x10000>;
+ interrupts = <GIC_SPI 119 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 124 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 125 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 126 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 127 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 147 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 149 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 150 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 151 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 152 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 153 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 154 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "error",
+ "ch0", "ch1", "ch2", "ch3", "ch4",
+ "ch5", "ch6", "ch7", "ch8", "ch9",
+ "ch10", "ch11", "ch12", "ch13",
+ "ch14", "ch15";
+ clocks = <&cpg CPG_MOD 710>;
+ clock-names = "fck";
+ power-domains = <&sysc R8A779F0_PD_ALWAYS_ON>;
+ resets = <&cpg 710>;
+ #dma-cells = <1>;
+ dma-channels = <16>;
+ };
+
gic: interrupt-controller@f1000000 {
compatible = "arm,gic-v3";
#interrupt-cells = <3>;
diff --git a/arch/arm64/boot/dts/renesas/r9a07g044c1.dtsi b/arch/arm64/boot/dts/renesas/r9a07g044c1.dtsi
new file mode 100644
index 000000000000..1d57df706939
--- /dev/null
+++ b/arch/arm64/boot/dts/renesas/r9a07g044c1.dtsi
@@ -0,0 +1,32 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+/*
+ * Device Tree Source for the RZ/G2LC R9A07G044C1 SoC specific parts
+ *
+ * Copyright (C) 2021 Renesas Electronics Corp.
+ */
+
+/dts-v1/;
+#include "r9a07g044.dtsi"
+
+/ {
+ compatible = "renesas,r9a07g044c1", "renesas,r9a07g044";
+
+ cpus {
+ /delete-node/ cpu-map;
+ /delete-node/ cpu@100;
+ };
+
+ timer {
+ interrupts-extended = <&gic GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(1) | IRQ_TYPE_LEVEL_LOW)>,
+ <&gic GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(1) | IRQ_TYPE_LEVEL_LOW)>,
+ <&gic GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(1) | IRQ_TYPE_LEVEL_LOW)>,
+ <&gic GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(1) | IRQ_TYPE_LEVEL_LOW)>;
+ };
+};
+
+&soc {
+ /delete-node/ ssi@1004a800;
+ /delete-node/ serial@1004c800;
+ /delete-node/ adc@10059000;
+ /delete-node/ ethernet@11c30000;
+};
diff --git a/arch/arm64/boot/dts/renesas/r9a07g044c2-smarc.dts b/arch/arm64/boot/dts/renesas/r9a07g044c2-smarc.dts
new file mode 100644
index 000000000000..5a5cea82a5d9
--- /dev/null
+++ b/arch/arm64/boot/dts/renesas/r9a07g044c2-smarc.dts
@@ -0,0 +1,91 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+/*
+ * Device Tree Source for the RZ/G2LC SMARC EVK board
+ *
+ * Copyright (C) 2021 Renesas Electronics Corp.
+ */
+
+/dts-v1/;
+#include "r9a07g044c2.dtsi"
+#include "rzg2lc-smarc.dtsi"
+
+/ {
+ model = "Renesas SMARC EVK based on r9a07g044c2";
+ compatible = "renesas,smarc-evk", "renesas,r9a07g044c2", "renesas,r9a07g044";
+};
+
+&ehci0 {
+ /delete-property/ pinctrl-0;
+ /delete-property/ pinctrl-names;
+ status = "disabled";
+};
+
+&ehci1 {
+ /delete-property/ pinctrl-0;
+ /delete-property/ pinctrl-names;
+ status = "disabled";
+};
+
+&hsusb {
+ /delete-property/ pinctrl-0;
+ /delete-property/ pinctrl-names;
+ status = "disabled";
+};
+
+&i2c0 {
+ /delete-property/ pinctrl-0;
+ /delete-property/ pinctrl-names;
+ status = "disabled";
+};
+
+&i2c1 {
+ /delete-property/ pinctrl-0;
+ /delete-property/ pinctrl-names;
+ status = "disabled";
+};
+
+&i2c3 {
+ /delete-property/ pinctrl-0;
+ /delete-property/ pinctrl-names;
+ status = "disabled";
+};
+
+&ohci0 {
+ /delete-property/ pinctrl-0;
+ /delete-property/ pinctrl-names;
+ status = "disabled";
+};
+
+&ohci1 {
+ /delete-property/ pinctrl-0;
+ /delete-property/ pinctrl-names;
+ status = "disabled";
+};
+
+&phyrst {
+ status = "disabled";
+};
+
+&spi1 {
+ /delete-property/ pinctrl-0;
+ /delete-property/ pinctrl-names;
+ status = "disabled";
+};
+
+&ssi0 {
+ /delete-property/ pinctrl-0;
+ /delete-property/ pinctrl-names;
+ status = "disabled";
+};
+
+&usb2_phy0 {
+ /delete-property/ pinctrl-0;
+ /delete-property/ pinctrl-names;
+ status = "disabled";
+};
+
+&usb2_phy1 {
+ /delete-property/ pinctrl-0;
+ /delete-property/ pinctrl-names;
+ status = "disabled";
+};
diff --git a/arch/arm64/boot/dts/renesas/r9a07g044c2.dtsi b/arch/arm64/boot/dts/renesas/r9a07g044c2.dtsi
new file mode 100644
index 000000000000..7bb8917fe421
--- /dev/null
+++ b/arch/arm64/boot/dts/renesas/r9a07g044c2.dtsi
@@ -0,0 +1,20 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+/*
+ * Device Tree Source for the RZ/G2LC R9A07G044C2 SoC specific parts
+ *
+ * Copyright (C) 2021 Renesas Electronics Corp.
+ */
+
+/dts-v1/;
+#include "r9a07g044.dtsi"
+
+/ {
+ compatible = "renesas,r9a07g044c2", "renesas,r9a07g044";
+};
+
+&soc {
+ /delete-node/ ssi@1004a800;
+ /delete-node/ serial@1004c800;
+ /delete-node/ adc@10059000;
+ /delete-node/ ethernet@11c30000;
+};
diff --git a/arch/arm64/boot/dts/renesas/r9a07g044l2-smarc.dts b/arch/arm64/boot/dts/renesas/r9a07g044l2-smarc.dts
index 247b0b3f1b58..bc2af6c92ccd 100644
--- a/arch/arm64/boot/dts/renesas/r9a07g044l2-smarc.dts
+++ b/arch/arm64/boot/dts/renesas/r9a07g044l2-smarc.dts
@@ -8,6 +8,8 @@
/dts-v1/;
#include "r9a07g044l2.dtsi"
#include "rzg2l-smarc-som.dtsi"
+#include "rzg2l-smarc-pinfunction.dtsi"
+#include "rz-smarc-common.dtsi"
#include "rzg2l-smarc.dtsi"
/ {
diff --git a/arch/arm64/boot/dts/renesas/r9a07g054.dtsi b/arch/arm64/boot/dts/renesas/r9a07g054.dtsi
new file mode 100644
index 000000000000..5d39e765c291
--- /dev/null
+++ b/arch/arm64/boot/dts/renesas/r9a07g054.dtsi
@@ -0,0 +1,491 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+/*
+ * Device Tree Source for the RZ/V2L SoC
+ *
+ * Copyright (C) 2021 Renesas Electronics Corp.
+ */
+
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/clock/r9a07g054-cpg.h>
+
+/ {
+ compatible = "renesas,r9a07g054";
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ audio_clk1: audio_clk1 {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ /* This value must be overridden by boards that provide it */
+ clock-frequency = <0>;
+ };
+
+ audio_clk2: audio_clk2 {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ /* This value must be overridden by boards that provide it */
+ clock-frequency = <0>;
+ };
+
+ /* External CAN clock - to be overridden by boards that provide it */
+ can_clk: can {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <0>;
+ };
+
+ /* clock can be either from exclk or crystal oscillator (XIN/XOUT) */
+ extal_clk: extal {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ /* This value must be overridden by the board */
+ clock-frequency = <0>;
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu-map {
+ cluster0 {
+ core0 {
+ cpu = <&cpu0>;
+ };
+ core1 {
+ cpu = <&cpu1>;
+ };
+ };
+ };
+
+ cpu0: cpu@0 {
+ compatible = "arm,cortex-a55";
+ reg = <0>;
+ device_type = "cpu";
+ #cooling-cells = <2>;
+ next-level-cache = <&L3_CA55>;
+ enable-method = "psci";
+ clocks = <&cpg CPG_CORE R9A07G054_CLK_I>;
+ };
+
+ cpu1: cpu@100 {
+ compatible = "arm,cortex-a55";
+ reg = <0x100>;
+ device_type = "cpu";
+ next-level-cache = <&L3_CA55>;
+ enable-method = "psci";
+ clocks = <&cpg CPG_CORE R9A07G054_CLK_I>;
+ };
+
+ L3_CA55: cache-controller-0 {
+ compatible = "cache";
+ cache-unified;
+ cache-size = <0x40000>;
+ };
+ };
+
+ psci {
+ compatible = "arm,psci-1.0", "arm,psci-0.2";
+ method = "smc";
+ };
+
+ soc: soc {
+ compatible = "simple-bus";
+ interrupt-parent = <&gic>;
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ ssi0: ssi@10049c00 {
+ reg = <0 0x10049c00 0 0x400>;
+ #sound-dai-cells = <0>;
+ /* place holder */
+ };
+
+ spi1: spi@1004b000 {
+ reg = <0 0x1004b000 0 0x400>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ /* place holder */
+ };
+
+ scif0: serial@1004b800 {
+ compatible = "renesas,scif-r9a07g054",
+ "renesas,scif-r9a07g044";
+ reg = <0 0x1004b800 0 0x400>;
+ interrupts = <GIC_SPI 380 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 382 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 383 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 381 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 384 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 384 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "eri", "rxi", "txi",
+ "bri", "dri", "tei";
+ clocks = <&cpg CPG_MOD R9A07G054_SCIF0_CLK_PCK>;
+ clock-names = "fck";
+ power-domains = <&cpg>;
+ resets = <&cpg R9A07G054_SCIF0_RST_SYSTEM_N>;
+ status = "disabled";
+ };
+
+ scif1: serial@1004bc00 {
+ compatible = "renesas,scif-r9a07g054",
+ "renesas,scif-r9a07g044";
+ reg = <0 0x1004bc00 0 0x400>;
+ interrupts = <GIC_SPI 385 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 387 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 388 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 386 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 389 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 389 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "eri", "rxi", "txi",
+ "bri", "dri", "tei";
+ clocks = <&cpg CPG_MOD R9A07G054_SCIF1_CLK_PCK>;
+ clock-names = "fck";
+ power-domains = <&cpg>;
+ resets = <&cpg R9A07G054_SCIF1_RST_SYSTEM_N>;
+ status = "disabled";
+ };
+
+ scif2: serial@1004c000 {
+ compatible = "renesas,scif-r9a07g054",
+ "renesas,scif-r9a07g044";
+ reg = <0 0x1004c000 0 0x400>;
+ interrupts = <GIC_SPI 390 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 392 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 393 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 391 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 394 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 394 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "eri", "rxi", "txi",
+ "bri", "dri", "tei";
+ clocks = <&cpg CPG_MOD R9A07G054_SCIF2_CLK_PCK>;
+ clock-names = "fck";
+ power-domains = <&cpg>;
+ resets = <&cpg R9A07G054_SCIF2_RST_SYSTEM_N>;
+ status = "disabled";
+ };
+
+ scif3: serial@1004c400 {
+ compatible = "renesas,scif-r9a07g054",
+ "renesas,scif-r9a07g044";
+ reg = <0 0x1004c400 0 0x400>;
+ interrupts = <GIC_SPI 395 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 397 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 398 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 396 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 399 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 399 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "eri", "rxi", "txi",
+ "bri", "dri", "tei";
+ clocks = <&cpg CPG_MOD R9A07G054_SCIF3_CLK_PCK>;
+ clock-names = "fck";
+ power-domains = <&cpg>;
+ resets = <&cpg R9A07G054_SCIF3_RST_SYSTEM_N>;
+ status = "disabled";
+ };
+
+ scif4: serial@1004c800 {
+ compatible = "renesas,scif-r9a07g054",
+ "renesas,scif-r9a07g044";
+ reg = <0 0x1004c800 0 0x400>;
+ interrupts = <GIC_SPI 400 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 402 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 403 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 401 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 404 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 404 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "eri", "rxi", "txi",
+ "bri", "dri", "tei";
+ clocks = <&cpg CPG_MOD R9A07G054_SCIF4_CLK_PCK>;
+ clock-names = "fck";
+ power-domains = <&cpg>;
+ resets = <&cpg R9A07G054_SCIF4_RST_SYSTEM_N>;
+ status = "disabled";
+ };
+
+ sci0: serial@1004d000 {
+ compatible = "renesas,r9a07g054-sci", "renesas,sci";
+ reg = <0 0x1004d000 0 0x400>;
+ interrupts = <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>;
+ interrupt-names = "eri", "rxi", "txi", "tei";
+ clocks = <&cpg CPG_MOD R9A07G054_SCI0_CLKP>;
+ clock-names = "fck";
+ power-domains = <&cpg>;
+ resets = <&cpg R9A07G054_SCI0_RST>;
+ status = "disabled";
+ };
+
+ sci1: serial@1004d400 {
+ compatible = "renesas,r9a07g054-sci", "renesas,sci";
+ reg = <0 0x1004d400 0 0x400>;
+ interrupts = <GIC_SPI 409 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 410 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 411 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 412 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "eri", "rxi", "txi", "tei";
+ clocks = <&cpg CPG_MOD R9A07G054_SCI1_CLKP>;
+ clock-names = "fck";
+ power-domains = <&cpg>;
+ resets = <&cpg R9A07G054_SCI1_RST>;
+ status = "disabled";
+ };
+
+ canfd: can@10050000 {
+ reg = <0 0x10050000 0 0x8000>;
+ /* place holder */
+ };
+
+ i2c0: i2c@10058000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0 0x10058000 0 0x400>;
+ /* place holder */
+ };
+
+ i2c1: i2c@10058400 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0 0x10058400 0 0x400>;
+ /* place holder */
+ };
+
+ i2c3: i2c@10058c00 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0 0x10058c00 0 0x400>;
+ /* place holder */
+ };
+
+ adc: adc@10059000 {
+ reg = <0 0x10059000 0 0x400>;
+ /* place holder */
+ };
+
+ sbc: spi@10060000 {
+ reg = <0 0x10060000 0 0x10000>,
+ <0 0x20000000 0 0x10000000>,
+ <0 0x10070000 0 0x10000>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ /* place holder */
+ };
+
+ cpg: clock-controller@11010000 {
+ compatible = "renesas,r9a07g054-cpg";
+ reg = <0 0x11010000 0 0x10000>;
+ clocks = <&extal_clk>;
+ clock-names = "extal";
+ #clock-cells = <2>;
+ #reset-cells = <1>;
+ #power-domain-cells = <0>;
+ };
+
+ sysc: system-controller@11020000 {
+ compatible = "renesas,r9a07g054-sysc";
+ reg = <0 0x11020000 0 0x10000>;
+ interrupts = <GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "lpm_int", "ca55stbydone_int",
+ "cm33stbyr_int", "ca55_deny";
+ status = "disabled";
+ };
+
+ pinctrl: pinctrl@11030000 {
+ compatible = "renesas,r9a07g054-pinctrl",
+ "renesas,r9a07g044-pinctrl";
+ reg = <0 0x11030000 0 0x10000>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ gpio-ranges = <&pinctrl 0 0 392>;
+ clocks = <&cpg CPG_MOD R9A07G054_GPIO_HCLK>;
+ power-domains = <&cpg>;
+ resets = <&cpg R9A07G054_GPIO_RSTN>,
+ <&cpg R9A07G054_GPIO_PORT_RESETN>,
+ <&cpg R9A07G054_GPIO_SPARE_RESETN>;
+ };
+
+ dmac: dma-controller@11820000 {
+ compatible = "renesas,r9a07g054-dmac",
+ "renesas,rz-dmac";
+ reg = <0 0x11820000 0 0x10000>,
+ <0 0x11830000 0 0x10000>;
+ interrupts = <GIC_SPI 141 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 125 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 126 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 127 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 128 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 129 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 130 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 131 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 132 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 133 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 134 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 135 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 136 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 137 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 138 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 139 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 140 IRQ_TYPE_EDGE_RISING>;
+ interrupt-names = "error",
+ "ch0", "ch1", "ch2", "ch3",
+ "ch4", "ch5", "ch6", "ch7",
+ "ch8", "ch9", "ch10", "ch11",
+ "ch12", "ch13", "ch14", "ch15";
+ clocks = <&cpg CPG_MOD R9A07G054_DMAC_ACLK>,
+ <&cpg CPG_MOD R9A07G054_DMAC_PCLK>;
+ power-domains = <&cpg>;
+ resets = <&cpg R9A07G054_DMAC_ARESETN>,
+ <&cpg R9A07G054_DMAC_RST_ASYNC>;
+ #dma-cells = <1>;
+ dma-channels = <16>;
+ };
+
+ gpu: gpu@11840000 {
+ reg = <0x0 0x11840000 0x0 0x10000>;
+ /* place holder */
+ };
+
+ gic: interrupt-controller@11900000 {
+ compatible = "arm,gic-v3";
+ #interrupt-cells = <3>;
+ #address-cells = <0>;
+ interrupt-controller;
+ reg = <0x0 0x11900000 0 0x40000>,
+ <0x0 0x11940000 0 0x60000>;
+ interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_LOW>;
+ };
+
+ sdhi0: mmc@11c00000 {
+ reg = <0x0 0x11c00000 0 0x10000>;
+ /* place holder */
+ };
+
+ sdhi1: mmc@11c10000 {
+ reg = <0x0 0x11c10000 0 0x10000>;
+ /* place holder */
+ };
+
+ eth0: ethernet@11c20000 {
+ compatible = "renesas,r9a07g054-gbeth",
+ "renesas,rzg2l-gbeth";
+ reg = <0 0x11c20000 0 0x10000>;
+ interrupts = <GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "mux", "fil", "arp_ns";
+ phy-mode = "rgmii";
+ clocks = <&cpg CPG_MOD R9A07G054_ETH0_CLK_AXI>,
+ <&cpg CPG_MOD R9A07G054_ETH0_CLK_CHI>,
+ <&cpg CPG_CORE R9A07G054_CLK_HP>;
+ clock-names = "axi", "chi", "refclk";
+ resets = <&cpg R9A07G054_ETH0_RST_HW_N>;
+ power-domains = <&cpg>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ eth1: ethernet@11c30000 {
+ compatible = "renesas,r9a07g054-gbeth",
+ "renesas,rzg2l-gbeth";
+ reg = <0 0x11c30000 0 0x10000>;
+ interrupts = <GIC_SPI 87 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 88 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 89 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "mux", "fil", "arp_ns";
+ phy-mode = "rgmii";
+ clocks = <&cpg CPG_MOD R9A07G054_ETH1_CLK_AXI>,
+ <&cpg CPG_MOD R9A07G054_ETH1_CLK_CHI>,
+ <&cpg CPG_CORE R9A07G054_CLK_HP>;
+ clock-names = "axi", "chi", "refclk";
+ resets = <&cpg R9A07G054_ETH1_RST_HW_N>;
+ power-domains = <&cpg>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ phyrst: usbphy-ctrl@11c40000 {
+ reg = <0 0x11c40000 0 0x10000>;
+ /* place holder */
+ };
+
+ ohci0: usb@11c50000 {
+ reg = <0 0x11c50000 0 0x100>;
+ /* place holder */
+ };
+
+ ohci1: usb@11c70000 {
+ reg = <0 0x11c70000 0 0x100>;
+ /* place holder */
+ };
+
+ ehci0: usb@11c50100 {
+ reg = <0 0x11c50100 0 0x100>;
+ /* place holder */
+ };
+
+ ehci1: usb@11c70100 {
+ reg = <0 0x11c70100 0 0x100>;
+ /* place holder */
+ };
+
+ usb2_phy0: usb-phy@11c50200 {
+ reg = <0 0x11c50200 0 0x700>;
+ /* place holder */
+ };
+
+ usb2_phy1: usb-phy@11c70200 {
+ reg = <0 0x11c70200 0 0x700>;
+ /* place holder */
+ };
+
+ hsusb: usb@11c60000 {
+ reg = <0 0x11c60000 0 0x10000>;
+ /* place holder */
+ };
+
+ wdt0: watchdog@12800800 {
+ reg = <0 0x12800800 0 0x400>;
+ /* place holder */
+ };
+
+ wdt1: watchdog@12800c00 {
+ reg = <0 0x12800C00 0 0x400>;
+ /* place holder */
+ };
+
+ wdt2: watchdog@12800400 {
+ reg = <0 0x12800400 0 0x400>;
+ /* place holder */
+ };
+
+ ostm0: timer@12801000 {
+ reg = <0x0 0x12801000 0x0 0x400>;
+ /* place holder */
+ };
+
+ ostm1: timer@12801400 {
+ reg = <0x0 0x12801400 0x0 0x400>;
+ /* place holder */
+ };
+
+ ostm2: timer@12801800 {
+ reg = <0x0 0x12801800 0x0 0x400>;
+ /* place holder */
+ };
+ };
+
+ timer {
+ compatible = "arm,armv8-timer";
+ interrupts-extended = <&gic GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
+ <&gic GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
+ <&gic GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
+ <&gic GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>;
+ };
+};
diff --git a/arch/arm64/boot/dts/renesas/r9a07g054l1.dtsi b/arch/arm64/boot/dts/renesas/r9a07g054l1.dtsi
new file mode 100644
index 000000000000..c448cc6634c1
--- /dev/null
+++ b/arch/arm64/boot/dts/renesas/r9a07g054l1.dtsi
@@ -0,0 +1,25 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+/*
+ * Device Tree Source for the RZ/V2L R9A07G054L1 SoC specific parts
+ *
+ * Copyright (C) 2021 Renesas Electronics Corp.
+ */
+
+/dts-v1/;
+#include "r9a07g054.dtsi"
+
+/ {
+ compatible = "renesas,r9a07g054l1", "renesas,r9a07g054";
+
+ cpus {
+ /delete-node/ cpu-map;
+ /delete-node/ cpu@100;
+ };
+
+ timer {
+ interrupts-extended = <&gic GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(1) | IRQ_TYPE_LEVEL_LOW)>,
+ <&gic GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(1) | IRQ_TYPE_LEVEL_LOW)>,
+ <&gic GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(1) | IRQ_TYPE_LEVEL_LOW)>,
+ <&gic GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(1) | IRQ_TYPE_LEVEL_LOW)>;
+ };
+};
diff --git a/arch/arm64/boot/dts/renesas/r9a07g054l2-smarc.dts b/arch/arm64/boot/dts/renesas/r9a07g054l2-smarc.dts
new file mode 100644
index 000000000000..fc334b4c2aa4
--- /dev/null
+++ b/arch/arm64/boot/dts/renesas/r9a07g054l2-smarc.dts
@@ -0,0 +1,26 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+/*
+ * Device Tree Source for the RZ/G2L SMARC EVK board
+ *
+ * Copyright (C) 2021 Renesas Electronics Corp.
+ */
+
+/dts-v1/;
+#include "r9a07g054l2.dtsi"
+#include "rzg2l-smarc-som.dtsi"
+#include "rzg2l-smarc-pinfunction.dtsi"
+#include "rz-smarc-common.dtsi"
+#include "rzg2l-smarc.dtsi"
+
+/ {
+ model = "Renesas SMARC EVK based on r9a07g054l2";
+ compatible = "renesas,smarc-evk", "renesas,r9a07g054l2", "renesas,r9a07g054";
+};
+
+&pinctrl {
+ /delete-node/ can0-stb-hog;
+ /delete-node/ can1-stb-hog;
+ /delete-node/ gpio-sd0-pwr-en-hog;
+ /delete-node/ sd0-dev-sel-hog;
+ /delete-node/ sd1-pwr-en-hog;
+};
diff --git a/arch/arm64/boot/dts/renesas/r9a07g054l2.dtsi b/arch/arm64/boot/dts/renesas/r9a07g054l2.dtsi
new file mode 100644
index 000000000000..4d5914bc95d3
--- /dev/null
+++ b/arch/arm64/boot/dts/renesas/r9a07g054l2.dtsi
@@ -0,0 +1,13 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+/*
+ * Device Tree Source for the RZ/V2L R9A07G054L2 SoC specific parts
+ *
+ * Copyright (C) 2021 Renesas Electronics Corp.
+ */
+
+/dts-v1/;
+#include "r9a07g054.dtsi"
+
+/ {
+ compatible = "renesas,r9a07g054l2", "renesas,r9a07g054";
+};
diff --git a/arch/arm64/boot/dts/renesas/rz-smarc-common.dtsi b/arch/arm64/boot/dts/renesas/rz-smarc-common.dtsi
new file mode 100644
index 000000000000..588117aafaca
--- /dev/null
+++ b/arch/arm64/boot/dts/renesas/rz-smarc-common.dtsi
@@ -0,0 +1,207 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+/*
+ * Device Tree Source for the RZ/{G2L,G2LC,V2L} SMARC EVK common parts
+ *
+ * Copyright (C) 2022 Renesas Electronics Corp.
+ */
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/pinctrl/rzg2l-pinctrl.h>
+
+/*
+ * SSI-WM8978
+ *
+ * This command is required when Playback/Capture
+ *
+ * amixer cset name='Left Input Mixer L2 Switch' on
+ * amixer cset name='Right Input Mixer R2 Switch' on
+ * amixer cset name='Headphone Playback Volume' 100
+ * amixer cset name='PCM Volume' 100%
+ * amixer cset name='Input PGA Volume' 25
+ *
+ */
+
+/ {
+ aliases {
+ serial0 = &scif0;
+ i2c0 = &i2c0;
+ i2c1 = &i2c1;
+ i2c3 = &i2c3;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+
+ audio_mclock: audio_mclock {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <11289600>;
+ };
+
+ snd_rzg2l: sound {
+ compatible = "simple-audio-card";
+ simple-audio-card,format = "i2s";
+ simple-audio-card,bitclock-master = <&cpu_dai>;
+ simple-audio-card,frame-master = <&cpu_dai>;
+ simple-audio-card,mclk-fs = <256>;
+
+ simple-audio-card,widgets = "Microphone", "Microphone Jack";
+ simple-audio-card,routing =
+ "L2", "Mic Bias",
+ "R2", "Mic Bias",
+ "Mic Bias", "Microphone Jack";
+
+ cpu_dai: simple-audio-card,cpu {
+ sound-dai = <&ssi0>;
+ };
+
+ codec_dai: simple-audio-card,codec {
+ clocks = <&audio_mclock>;
+ sound-dai = <&wm8978>;
+ };
+ };
+
+ usb0_vbus_otg: regulator-usb0-vbus-otg {
+ compatible = "regulator-fixed";
+
+ regulator-name = "USB0_VBUS_OTG";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ };
+
+ vccq_sdhi1: regulator-vccq-sdhi1 {
+ compatible = "regulator-gpio";
+ regulator-name = "SDHI1 VccQ";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ gpios = <&pinctrl RZG2L_GPIO(39, 1) GPIO_ACTIVE_HIGH>;
+ gpios-states = <1>;
+ states = <3300000 1>, <1800000 0>;
+ };
+};
+
+&audio_clk1{
+ clock-frequency = <11289600>;
+};
+
+&audio_clk2{
+ clock-frequency = <12288000>;
+};
+
+&canfd {
+ pinctrl-0 = <&can0_pins &can1_pins>;
+ pinctrl-names = "default";
+ status = "okay";
+
+ channel0 {
+ status = "okay";
+ };
+
+ channel1 {
+ status = "okay";
+ };
+};
+
+&ehci0 {
+ dr_mode = "otg";
+ status = "okay";
+};
+
+&ehci1 {
+ status = "okay";
+};
+
+&hsusb {
+ dr_mode = "otg";
+ status = "okay";
+};
+
+&i2c0 {
+ pinctrl-0 = <&i2c0_pins>;
+ pinctrl-names = "default";
+
+ status = "okay";
+};
+
+&i2c1 {
+ pinctrl-0 = <&i2c1_pins>;
+ pinctrl-names = "default";
+
+ status = "okay";
+};
+
+&i2c3 {
+ pinctrl-0 = <&i2c3_pins>;
+ pinctrl-names = "default";
+ clock-frequency = <400000>;
+
+ status = "okay";
+
+ wm8978: codec@1a {
+ compatible = "wlf,wm8978";
+ #sound-dai-cells = <0>;
+ reg = <0x1a>;
+ };
+};
+
+&ohci0 {
+ dr_mode = "otg";
+ status = "okay";
+};
+
+&ohci1 {
+ status = "okay";
+};
+
+&phyrst {
+ status = "okay";
+};
+
+&scif0 {
+ pinctrl-0 = <&scif0_pins>;
+ pinctrl-names = "default";
+ status = "okay";
+};
+
+&sdhi1 {
+ pinctrl-0 = <&sdhi1_pins>;
+ pinctrl-1 = <&sdhi1_pins_uhs>;
+ pinctrl-names = "default", "state_uhs";
+
+ vmmc-supply = <&reg_3p3v>;
+ vqmmc-supply = <&vccq_sdhi1>;
+ bus-width = <4>;
+ sd-uhs-sdr50;
+ sd-uhs-sdr104;
+ status = "okay";
+};
+
+&spi1 {
+ pinctrl-0 = <&spi1_pins>;
+ pinctrl-names = "default";
+
+ status = "okay";
+};
+
+&ssi0 {
+ pinctrl-0 = <&ssi0_pins>;
+ pinctrl-names = "default";
+
+ status = "okay";
+};
+
+&usb2_phy0 {
+ pinctrl-0 = <&usb0_pins>;
+ pinctrl-names = "default";
+
+ vbus-supply = <&usb0_vbus_otg>;
+ status = "okay";
+};
+
+&usb2_phy1 {
+ pinctrl-0 = <&usb1_pins>;
+ pinctrl-names = "default";
+
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/renesas/rzg2l-smarc-pinfunction.dtsi b/arch/arm64/boot/dts/renesas/rzg2l-smarc-pinfunction.dtsi
new file mode 100644
index 000000000000..9085d8c76ce1
--- /dev/null
+++ b/arch/arm64/boot/dts/renesas/rzg2l-smarc-pinfunction.dtsi
@@ -0,0 +1,137 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+/*
+ * Device Tree Source for the RZ/{G2L,V2L} SMARC pincontrol parts
+ *
+ * Copyright (C) 2021 Renesas Electronics Corp.
+ */
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/pinctrl/rzg2l-pinctrl.h>
+
+&pinctrl {
+ pinctrl-0 = <&sound_clk_pins>;
+ pinctrl-names = "default";
+
+ can0_pins: can0 {
+ pinmux = <RZG2L_PORT_PINMUX(10, 1, 2)>, /* TX */
+ <RZG2L_PORT_PINMUX(11, 0, 2)>; /* RX */
+ };
+
+ /* SW7 should be at position 2->3 so that GPIO8_CAN0_STB line is activated */
+ can0-stb-hog {
+ gpio-hog;
+ gpios = <RZG2L_GPIO(42, 2) GPIO_ACTIVE_HIGH>;
+ output-low;
+ line-name = "can0_stb";
+ };
+
+ can1_pins: can1 {
+ pinmux = <RZG2L_PORT_PINMUX(12, 1, 2)>, /* TX */
+ <RZG2L_PORT_PINMUX(13, 0, 2)>; /* RX */
+ };
+
+ /* SW8 should be at position 2->3 so that GPIO9_CAN1_STB line is activated */
+ can1-stb-hog {
+ gpio-hog;
+ gpios = <RZG2L_GPIO(42, 3) GPIO_ACTIVE_HIGH>;
+ output-low;
+ line-name = "can1_stb";
+ };
+
+ i2c0_pins: i2c0 {
+ pins = "RIIC0_SDA", "RIIC0_SCL";
+ input-enable;
+ };
+
+ i2c1_pins: i2c1 {
+ pins = "RIIC1_SDA", "RIIC1_SCL";
+ input-enable;
+ };
+
+ i2c3_pins: i2c3 {
+ pinmux = <RZG2L_PORT_PINMUX(18, 0, 3)>, /* SDA */
+ <RZG2L_PORT_PINMUX(18, 1, 3)>; /* SCL */
+ };
+
+ scif0_pins: scif0 {
+ pinmux = <RZG2L_PORT_PINMUX(38, 0, 1)>, /* TxD */
+ <RZG2L_PORT_PINMUX(38, 1, 1)>; /* RxD */
+ };
+
+ scif2_pins: scif2 {
+ pinmux = <RZG2L_PORT_PINMUX(48, 0, 1)>, /* TxD */
+ <RZG2L_PORT_PINMUX(48, 1, 1)>, /* RxD */
+ <RZG2L_PORT_PINMUX(48, 3, 1)>, /* CTS# */
+ <RZG2L_PORT_PINMUX(48, 4, 1)>; /* RTS# */
+ };
+
+ sd1-pwr-en-hog {
+ gpio-hog;
+ gpios = <RZG2L_GPIO(39, 2) GPIO_ACTIVE_HIGH>;
+ output-high;
+ line-name = "sd1_pwr_en";
+ };
+
+ sdhi1_pins: sd1 {
+ sd1_data {
+ pins = "SD1_DATA0", "SD1_DATA1", "SD1_DATA2", "SD1_DATA3";
+ power-source = <3300>;
+ };
+
+ sd1_ctrl {
+ pins = "SD1_CLK", "SD1_CMD";
+ power-source = <3300>;
+ };
+
+ sd1_mux {
+ pinmux = <RZG2L_PORT_PINMUX(19, 0, 1)>; /* SD1_CD */
+ };
+ };
+
+ sdhi1_pins_uhs: sd1_uhs {
+ sd1_data_uhs {
+ pins = "SD1_DATA0", "SD1_DATA1", "SD1_DATA2", "SD1_DATA3";
+ power-source = <1800>;
+ };
+
+ sd1_ctrl_uhs {
+ pins = "SD1_CLK", "SD1_CMD";
+ power-source = <1800>;
+ };
+
+ sd1_mux_uhs {
+ pinmux = <RZG2L_PORT_PINMUX(19, 0, 1)>; /* SD1_CD */
+ };
+ };
+
+ sound_clk_pins: sound_clk {
+ pins = "AUDIO_CLK1", "AUDIO_CLK2";
+ input-enable;
+ };
+
+ spi1_pins: spi1 {
+ pinmux = <RZG2L_PORT_PINMUX(44, 0, 1)>, /* CK */
+ <RZG2L_PORT_PINMUX(44, 1, 1)>, /* MOSI */
+ <RZG2L_PORT_PINMUX(44, 2, 1)>, /* MISO */
+ <RZG2L_PORT_PINMUX(44, 3, 1)>; /* SSL */
+ };
+
+ ssi0_pins: ssi0 {
+ pinmux = <RZG2L_PORT_PINMUX(45, 0, 1)>, /* BCK */
+ <RZG2L_PORT_PINMUX(45, 1, 1)>, /* RCK */
+ <RZG2L_PORT_PINMUX(45, 2, 1)>, /* TXD */
+ <RZG2L_PORT_PINMUX(45, 3, 1)>; /* RXD */
+ };
+
+ usb0_pins: usb0 {
+ pinmux = <RZG2L_PORT_PINMUX(4, 0, 1)>, /* VBUS */
+ <RZG2L_PORT_PINMUX(5, 0, 1)>, /* OVC */
+ <RZG2L_PORT_PINMUX(5, 1, 1)>; /* OTG_ID */
+ };
+
+ usb1_pins: usb1 {
+ pinmux = <RZG2L_PORT_PINMUX(42, 0, 1)>, /* VBUS */
+ <RZG2L_PORT_PINMUX(42, 1, 1)>; /* OVC */
+ };
+};
+
diff --git a/arch/arm64/boot/dts/renesas/rzg2l-smarc-som.dtsi b/arch/arm64/boot/dts/renesas/rzg2l-smarc-som.dtsi
index 9112e79079a1..aeacd22e9eb0 100644
--- a/arch/arm64/boot/dts/renesas/rzg2l-smarc-som.dtsi
+++ b/arch/arm64/boot/dts/renesas/rzg2l-smarc-som.dtsi
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
/*
- * Device Tree Source for the RZ/G2L SMARC SOM common parts
+ * Device Tree Source for the RZ/{G2L,V2L} SMARC SOM common parts
*
* Copyright (C) 2021 Renesas Electronics Corp.
*/
diff --git a/arch/arm64/boot/dts/renesas/rzg2l-smarc.dtsi b/arch/arm64/boot/dts/renesas/rzg2l-smarc.dtsi
index 6f2a8bdfa225..33ddfd18bd56 100644
--- a/arch/arm64/boot/dts/renesas/rzg2l-smarc.dtsi
+++ b/arch/arm64/boot/dts/renesas/rzg2l-smarc.dtsi
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
/*
- * Device Tree Source for the RZ/G2L SMARC EVK common parts
+ * Device Tree Source for the RZ/{G2L,V2L} SMARC EVK common parts
*
* Copyright (C) 2021 Renesas Electronics Corp.
*/
@@ -8,293 +8,15 @@
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/pinctrl/rzg2l-pinctrl.h>
-/*
- * SSI-WM8978
- *
- * This command is required when Playback/Capture
- *
- * amixer cset name='Left Input Mixer L2 Switch' on
- * amixer cset name='Right Input Mixer R2 Switch' on
- * amixer cset name='Headphone Playback Volume' 100
- * amixer cset name='PCM Volume' 100%
- * amixer cset name='Input PGA Volume' 25
- *
- */
-
/* comment the #define statement to disable SCIF2 (SER0) on PMOD1 (CN7) */
#define PMOD1_SER0 1
/ {
aliases {
- serial0 = &scif0;
serial1 = &scif2;
- i2c0 = &i2c0;
- i2c1 = &i2c1;
- i2c3 = &i2c3;
- };
-
- chosen {
- stdout-path = "serial0:115200n8";
- };
-
- audio_mclock: audio_mclock {
- compatible = "fixed-clock";
- #clock-cells = <0>;
- clock-frequency = <11289600>;
- };
-
- snd_rzg2l: sound {
- compatible = "simple-audio-card";
- simple-audio-card,format = "i2s";
- simple-audio-card,bitclock-master = <&cpu_dai>;
- simple-audio-card,frame-master = <&cpu_dai>;
- simple-audio-card,mclk-fs = <256>;
-
- simple-audio-card,widgets = "Microphone", "Microphone Jack";
- simple-audio-card,routing =
- "L2", "Mic Bias",
- "R2", "Mic Bias",
- "Mic Bias", "Microphone Jack";
-
- cpu_dai: simple-audio-card,cpu {
- sound-dai = <&ssi0>;
- };
-
- codec_dai: simple-audio-card,codec {
- clocks = <&audio_mclock>;
- sound-dai = <&wm8978>;
- };
- };
-
- usb0_vbus_otg: regulator-usb0-vbus-otg {
- compatible = "regulator-fixed";
-
- regulator-name = "USB0_VBUS_OTG";
- regulator-min-microvolt = <5000000>;
- regulator-max-microvolt = <5000000>;
- };
-
- vccq_sdhi1: regulator-vccq-sdhi1 {
- compatible = "regulator-gpio";
- regulator-name = "SDHI1 VccQ";
- regulator-min-microvolt = <1800000>;
- regulator-max-microvolt = <3300000>;
- gpios = <&pinctrl RZG2L_GPIO(39, 1) GPIO_ACTIVE_HIGH>;
- gpios-states = <1>;
- states = <3300000 1>, <1800000 0>;
- };
-};
-
-&audio_clk1{
- clock-frequency = <11289600>;
-};
-
-&audio_clk2{
- clock-frequency = <12288000>;
-};
-
-&canfd {
- pinctrl-0 = <&can0_pins &can1_pins>;
- pinctrl-names = "default";
- status = "okay";
-
- channel0 {
- status = "okay";
- };
-
- channel1 {
- status = "okay";
- };
-};
-
-&ehci0 {
- dr_mode = "otg";
- status = "okay";
-};
-
-&ehci1 {
- status = "okay";
-};
-
-&hsusb {
- dr_mode = "otg";
- status = "okay";
-};
-
-&i2c0 {
- pinctrl-0 = <&i2c0_pins>;
- pinctrl-names = "default";
-
- status = "okay";
-};
-
-&i2c1 {
- pinctrl-0 = <&i2c1_pins>;
- pinctrl-names = "default";
-
- status = "okay";
-};
-
-&i2c3 {
- pinctrl-0 = <&i2c3_pins>;
- pinctrl-names = "default";
- clock-frequency = <400000>;
-
- status = "okay";
-
- wm8978: codec@1a {
- compatible = "wlf,wm8978";
- #sound-dai-cells = <0>;
- reg = <0x1a>;
- };
-};
-
-&ohci0 {
- dr_mode = "otg";
- status = "okay";
-};
-
-&ohci1 {
- status = "okay";
-};
-
-&phyrst {
- status = "okay";
-};
-
-&pinctrl {
- pinctrl-0 = <&sound_clk_pins>;
- pinctrl-names = "default";
-
- can0_pins: can0 {
- pinmux = <RZG2L_PORT_PINMUX(10, 1, 2)>, /* TX */
- <RZG2L_PORT_PINMUX(11, 0, 2)>; /* RX */
- };
-
- /* SW7 should be at position 2->3 so that GPIO8_CAN0_STB line is activated */
- can0-stb {
- gpio-hog;
- gpios = <RZG2L_GPIO(42, 2) GPIO_ACTIVE_HIGH>;
- output-low;
- line-name = "can0_stb";
- };
-
- can1_pins: can1 {
- pinmux = <RZG2L_PORT_PINMUX(12, 1, 2)>, /* TX */
- <RZG2L_PORT_PINMUX(13, 0, 2)>; /* RX */
- };
-
- /* SW8 should be at position 2->3 so that GPIO9_CAN1_STB line is activated */
- can1-stb {
- gpio-hog;
- gpios = <RZG2L_GPIO(42, 3) GPIO_ACTIVE_HIGH>;
- output-low;
- line-name = "can1_stb";
- };
-
- i2c0_pins: i2c0 {
- pins = "RIIC0_SDA", "RIIC0_SCL";
- input-enable;
- };
-
- i2c1_pins: i2c1 {
- pins = "RIIC1_SDA", "RIIC1_SCL";
- input-enable;
- };
-
- i2c3_pins: i2c3 {
- pinmux = <RZG2L_PORT_PINMUX(18, 0, 3)>, /* SDA */
- <RZG2L_PORT_PINMUX(18, 1, 3)>; /* SCL */
- };
-
- scif0_pins: scif0 {
- pinmux = <RZG2L_PORT_PINMUX(38, 0, 1)>, /* TxD */
- <RZG2L_PORT_PINMUX(38, 1, 1)>; /* RxD */
- };
-
- scif2_pins: scif2 {
- pinmux = <RZG2L_PORT_PINMUX(48, 0, 1)>, /* TxD */
- <RZG2L_PORT_PINMUX(48, 1, 1)>, /* RxD */
- <RZG2L_PORT_PINMUX(48, 3, 1)>, /* CTS# */
- <RZG2L_PORT_PINMUX(48, 4, 1)>; /* RTS# */
- };
-
- sd1-pwr-en-hog {
- gpio-hog;
- gpios = <RZG2L_GPIO(39, 2) GPIO_ACTIVE_HIGH>;
- output-high;
- line-name = "sd1_pwr_en";
- };
-
- sdhi1_pins: sd1 {
- sd1_data {
- pins = "SD1_DATA0", "SD1_DATA1", "SD1_DATA2", "SD1_DATA3";
- power-source = <3300>;
- };
-
- sd1_ctrl {
- pins = "SD1_CLK", "SD1_CMD";
- power-source = <3300>;
- };
-
- sd1_mux {
- pinmux = <RZG2L_PORT_PINMUX(19, 0, 1)>; /* SD1_CD */
- };
- };
-
- sdhi1_pins_uhs: sd1_uhs {
- sd1_data_uhs {
- pins = "SD1_DATA0", "SD1_DATA1", "SD1_DATA2", "SD1_DATA3";
- power-source = <1800>;
- };
-
- sd1_ctrl_uhs {
- pins = "SD1_CLK", "SD1_CMD";
- power-source = <1800>;
- };
-
- sd1_mux_uhs {
- pinmux = <RZG2L_PORT_PINMUX(19, 0, 1)>; /* SD1_CD */
- };
- };
-
- sound_clk_pins: sound_clk {
- pins = "AUDIO_CLK1", "AUDIO_CLK2";
- input-enable;
- };
-
- spi1_pins: spi1 {
- pinmux = <RZG2L_PORT_PINMUX(44, 0, 1)>, /* CK */
- <RZG2L_PORT_PINMUX(44, 1, 1)>, /* MOSI */
- <RZG2L_PORT_PINMUX(44, 2, 1)>, /* MISO */
- <RZG2L_PORT_PINMUX(44, 3, 1)>; /* SSL */
- };
-
- ssi0_pins: ssi0 {
- pinmux = <RZG2L_PORT_PINMUX(45, 0, 1)>, /* BCK */
- <RZG2L_PORT_PINMUX(45, 1, 1)>, /* RCK */
- <RZG2L_PORT_PINMUX(45, 2, 1)>, /* TXD */
- <RZG2L_PORT_PINMUX(45, 3, 1)>; /* RXD */
- };
-
- usb0_pins: usb0 {
- pinmux = <RZG2L_PORT_PINMUX(4, 0, 1)>, /* VBUS */
- <RZG2L_PORT_PINMUX(5, 0, 1)>, /* OVC */
- <RZG2L_PORT_PINMUX(5, 1, 1)>; /* OTG_ID */
- };
-
- usb1_pins: usb1 {
- pinmux = <RZG2L_PORT_PINMUX(42, 0, 1)>, /* VBUS */
- <RZG2L_PORT_PINMUX(42, 1, 1)>; /* OVC */
};
};
-&scif0 {
- pinctrl-0 = <&scif0_pins>;
- pinctrl-names = "default";
- status = "okay";
-};
-
/*
* To enable SCIF2 (SER0) on PMOD1 (CN7)
* SW1 should be at position 2->3 so that SER0_CTS# line is activated
@@ -311,45 +33,3 @@
status = "okay";
};
#endif
-
-&sdhi1 {
- pinctrl-0 = <&sdhi1_pins>;
- pinctrl-1 = <&sdhi1_pins_uhs>;
- pinctrl-names = "default", "state_uhs";
-
- vmmc-supply = <&reg_3p3v>;
- vqmmc-supply = <&vccq_sdhi1>;
- bus-width = <4>;
- sd-uhs-sdr50;
- sd-uhs-sdr104;
- status = "okay";
-};
-
-&spi1 {
- pinctrl-0 = <&spi1_pins>;
- pinctrl-names = "default";
-
- status = "okay";
-};
-
-&ssi0 {
- pinctrl-0 = <&ssi0_pins>;
- pinctrl-names = "default";
-
- status = "okay";
-};
-
-&usb2_phy0 {
- pinctrl-0 = <&usb0_pins>;
- pinctrl-names = "default";
-
- vbus-supply = <&usb0_vbus_otg>;
- status = "okay";
-};
-
-&usb2_phy1 {
- pinctrl-0 = <&usb1_pins>;
- pinctrl-names = "default";
-
- status = "okay";
-};
diff --git a/arch/arm64/boot/dts/renesas/rzg2lc-smarc-pinfunction.dtsi b/arch/arm64/boot/dts/renesas/rzg2lc-smarc-pinfunction.dtsi
new file mode 100644
index 000000000000..37ff2091582e
--- /dev/null
+++ b/arch/arm64/boot/dts/renesas/rzg2lc-smarc-pinfunction.dtsi
@@ -0,0 +1,94 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+/*
+ * Device Tree Source for the RZ/G2LC SMARC pincontrol parts
+ *
+ * Copyright (C) 2021 Renesas Electronics Corp.
+ */
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/pinctrl/rzg2l-pinctrl.h>
+
+&pinctrl {
+ pinctrl-0 = <&sound_clk_pins>;
+ pinctrl-names = "default";
+
+ scif0_pins: scif0 {
+ pinmux = <RZG2L_PORT_PINMUX(38, 0, 1)>, /* TxD */
+ <RZG2L_PORT_PINMUX(38, 1, 1)>; /* RxD */
+ };
+
+#if SW_SCIF_CAN
+ /* SW8 should be at position 2->1 */
+ can1_pins: can1 {
+ pinmux = <RZG2L_PORT_PINMUX(40, 0, 3)>, /* TxD */
+ <RZG2L_PORT_PINMUX(40, 1, 3)>; /* RxD */
+ };
+#endif
+
+ scif1_pins: scif1 {
+ pinmux = <RZG2L_PORT_PINMUX(40, 0, 1)>, /* TxD */
+ <RZG2L_PORT_PINMUX(40, 1, 1)>, /* RxD */
+ <RZG2L_PORT_PINMUX(41, 0, 1)>, /* CTS# */
+ <RZG2L_PORT_PINMUX(41, 1, 1)>; /* RTS# */
+ };
+
+#if SW_RSPI_CAN
+ /* SW8 should be at position 2->3 so that GPIO9_CAN1_STB line is activated */
+ can1-stb-hog {
+ gpio-hog;
+ gpios = <RZG2L_GPIO(44, 3) GPIO_ACTIVE_HIGH>;
+ output-low;
+ line-name = "can1_stb";
+ };
+
+ can1_pins: can1 {
+ pinmux = <RZG2L_PORT_PINMUX(44, 0, 3)>, /* TxD */
+ <RZG2L_PORT_PINMUX(44, 1, 3)>; /* RxD */
+ };
+#endif
+
+ sd1-pwr-en-hog {
+ gpio-hog;
+ gpios = <RZG2L_GPIO(39, 2) GPIO_ACTIVE_HIGH>;
+ output-high;
+ line-name = "sd1_pwr_en";
+ };
+
+ sdhi1_pins: sd1 {
+ sd1_data {
+ pins = "SD1_DATA0", "SD1_DATA1", "SD1_DATA2", "SD1_DATA3";
+ power-source = <3300>;
+ };
+
+ sd1_ctrl {
+ pins = "SD1_CLK", "SD1_CMD";
+ power-source = <3300>;
+ };
+
+ sd1_mux {
+ pinmux = <RZG2L_PORT_PINMUX(19, 0, 1)>; /* SD1_CD */
+ };
+ };
+
+ sdhi1_pins_uhs: sd1_uhs {
+ sd1_data_uhs {
+ pins = "SD1_DATA0", "SD1_DATA1", "SD1_DATA2", "SD1_DATA3";
+ power-source = <1800>;
+ };
+
+ sd1_ctrl_uhs {
+ pins = "SD1_CLK", "SD1_CMD";
+ power-source = <1800>;
+ };
+
+ sd1_mux_uhs {
+ pinmux = <RZG2L_PORT_PINMUX(19, 0, 1)>; /* SD1_CD */
+ };
+ };
+
+ sound_clk_pins: sound_clk {
+ pins = "AUDIO_CLK1", "AUDIO_CLK2";
+ input-enable;
+ };
+};
+
diff --git a/arch/arm64/boot/dts/renesas/rzg2lc-smarc-som.dtsi b/arch/arm64/boot/dts/renesas/rzg2lc-smarc-som.dtsi
new file mode 100644
index 000000000000..88a7938017aa
--- /dev/null
+++ b/arch/arm64/boot/dts/renesas/rzg2lc-smarc-som.dtsi
@@ -0,0 +1,222 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+/*
+ * Device Tree Source for the RZ/G2LC SMARC SOM common parts
+ *
+ * Copyright (C) 2021 Renesas Electronics Corp.
+ */
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/pinctrl/rzg2l-pinctrl.h>
+
+/ {
+ aliases {
+ ethernet0 = &eth0;
+ };
+
+ chosen {
+ bootargs = "ignore_loglevel rw root=/dev/nfs ip=on";
+ };
+
+ memory@48000000 {
+ device_type = "memory";
+ /* first 128MB is reserved for secure area. */
+ reg = <0x0 0x48000000 0x0 0x38000000>;
+ };
+
+ reg_1p8v: regulator0 {
+ compatible = "regulator-fixed";
+ regulator-name = "fixed-1.8V";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ reg_3p3v: regulator1 {
+ compatible = "regulator-fixed";
+ regulator-name = "fixed-3.3V";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ vccq_sdhi0: regulator-vccq-sdhi0 {
+ compatible = "regulator-gpio";
+
+ regulator-name = "SDHI0 VccQ";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ states = <3300000 1>, <1800000 0>;
+ regulator-boot-on;
+ gpios = <&pinctrl RZG2L_GPIO(39, 0) GPIO_ACTIVE_HIGH>;
+ regulator-always-on;
+ };
+};
+
+&eth0 {
+ pinctrl-0 = <&eth0_pins>;
+ pinctrl-names = "default";
+ phy-handle = <&phy0>;
+ phy-mode = "rgmii-id";
+ status = "okay";
+
+ phy0: ethernet-phy@7 {
+ compatible = "ethernet-phy-id0022.1640",
+ "ethernet-phy-ieee802.3-c22";
+ reg = <7>;
+ rxc-skew-psec = <2400>;
+ txc-skew-psec = <2400>;
+ rxdv-skew-psec = <0>;
+ txdv-skew-psec = <0>;
+ rxd0-skew-psec = <0>;
+ rxd1-skew-psec = <0>;
+ rxd2-skew-psec = <0>;
+ rxd3-skew-psec = <0>;
+ txd0-skew-psec = <0>;
+ txd1-skew-psec = <0>;
+ txd2-skew-psec = <0>;
+ txd3-skew-psec = <0>;
+ };
+};
+
+&extal_clk {
+ clock-frequency = <24000000>;
+};
+
+&pinctrl {
+ eth0_pins: eth0 {
+ pinmux = <RZG2L_PORT_PINMUX(28, 1, 1)>, /* ET0_LINKSTA */
+ <RZG2L_PORT_PINMUX(27, 1, 1)>, /* ET0_MDC */
+ <RZG2L_PORT_PINMUX(28, 0, 1)>, /* ET0_MDIO */
+ <RZG2L_PORT_PINMUX(20, 0, 1)>, /* ET0_TXC */
+ <RZG2L_PORT_PINMUX(20, 1, 1)>, /* ET0_TX_CTL */
+ <RZG2L_PORT_PINMUX(20, 2, 1)>, /* ET0_TXD0 */
+ <RZG2L_PORT_PINMUX(21, 0, 1)>, /* ET0_TXD1 */
+ <RZG2L_PORT_PINMUX(21, 1, 1)>, /* ET0_TXD2 */
+ <RZG2L_PORT_PINMUX(22, 0, 1)>, /* ET0_TXD3 */
+ <RZG2L_PORT_PINMUX(24, 0, 1)>, /* ET0_RXC */
+ <RZG2L_PORT_PINMUX(24, 1, 1)>, /* ET0_RX_CTL */
+ <RZG2L_PORT_PINMUX(25, 0, 1)>, /* ET0_RXD0 */
+ <RZG2L_PORT_PINMUX(25, 1, 1)>, /* ET0_RXD1 */
+ <RZG2L_PORT_PINMUX(26, 0, 1)>, /* ET0_RXD2 */
+ <RZG2L_PORT_PINMUX(26, 1, 1)>; /* ET0_RXD3 */
+ };
+
+ gpio-sd0-pwr-en-hog {
+ gpio-hog;
+ gpios = <RZG2L_GPIO(18, 1) GPIO_ACTIVE_HIGH>;
+ output-high;
+ line-name = "gpio_sd0_pwr_en";
+ };
+
+ /*
+ * SD0 device selection is XOR between GPIO_SD0_DEV_SEL and SW1[2]
+ * The below switch logic can be used to select the device between
+ * eMMC and microSD, after setting GPIO_SD0_DEV_SEL to high in DT.
+ * SW1[2] should be at OFF position to enable 64 GB eMMC
+ * SW1[2] should be at position ON to enable uSD card CN3
+ */
+ gpio-sd0-dev-sel-hog {
+ gpio-hog;
+ gpios = <RZG2L_GPIO(40, 2) GPIO_ACTIVE_HIGH>;
+ output-high;
+ line-name = "gpio_sd0_dev_sel";
+ };
+
+ sdhi0_emmc_pins: sd0emmc {
+ sd0_emmc_data {
+ pins = "SD0_DATA0", "SD0_DATA1", "SD0_DATA2", "SD0_DATA3",
+ "SD0_DATA4", "SD0_DATA5", "SD0_DATA6", "SD0_DATA7";
+ power-source = <1800>;
+ };
+
+ sd0_emmc_ctrl {
+ pins = "SD0_CLK", "SD0_CMD";
+ power-source = <1800>;
+ };
+
+ sd0_emmc_rst {
+ pins = "SD0_RST#";
+ power-source = <1800>;
+ };
+ };
+
+ sdhi0_pins: sd0 {
+ sd0_data {
+ pins = "SD0_DATA0", "SD0_DATA1", "SD0_DATA2", "SD0_DATA3";
+ power-source = <3300>;
+ };
+
+ sd0_ctrl {
+ pins = "SD0_CLK", "SD0_CMD";
+ power-source = <3300>;
+ };
+
+ sd0_mux {
+ pinmux = <RZG2L_PORT_PINMUX(18, 0, 1)>; /* SD0_CD */
+ };
+ };
+
+ sdhi0_pins_uhs: sd0_uhs {
+ sd0_data_uhs {
+ pins = "SD0_DATA0", "SD0_DATA1", "SD0_DATA2", "SD0_DATA3";
+ power-source = <1800>;
+ };
+
+ sd0_ctrl_uhs {
+ pins = "SD0_CLK", "SD0_CMD";
+ power-source = <1800>;
+ };
+
+ sd0_mux_uhs {
+ pinmux = <RZG2L_PORT_PINMUX(18, 0, 1)>; /* SD0_CD */
+ };
+ };
+};
+
+#if (!SW_SD0_DEV_SEL)
+&sdhi0 {
+ pinctrl-0 = <&sdhi0_pins>;
+ pinctrl-1 = <&sdhi0_pins_uhs>;
+ pinctrl-names = "default", "state_uhs";
+
+ vmmc-supply = <&reg_3p3v>;
+ vqmmc-supply = <&vccq_sdhi0>;
+ bus-width = <4>;
+ sd-uhs-sdr50;
+ sd-uhs-sdr104;
+ status = "okay";
+};
+#endif
+
+#if SW_SD0_DEV_SEL
+&sdhi0 {
+ pinctrl-0 = <&sdhi0_emmc_pins>;
+ pinctrl-1 = <&sdhi0_emmc_pins>;
+ pinctrl-names = "default", "state_uhs";
+
+ vmmc-supply = <&reg_3p3v>;
+ vqmmc-supply = <&reg_1p8v>;
+ bus-width = <8>;
+ mmc-hs200-1_8v;
+ non-removable;
+ fixed-emmc-driver-type = <1>;
+ status = "okay";
+};
+#endif
+
+&wdt0 {
+ status = "okay";
+ timeout-sec = <60>;
+};
+
+&wdt1 {
+ status = "okay";
+ timeout-sec = <60>;
+};
+
+&wdt2 {
+ status = "okay";
+ timeout-sec = <60>;
+};
diff --git a/arch/arm64/boot/dts/renesas/rzg2lc-smarc.dtsi b/arch/arm64/boot/dts/renesas/rzg2lc-smarc.dtsi
new file mode 100644
index 000000000000..df7631fe5fac
--- /dev/null
+++ b/arch/arm64/boot/dts/renesas/rzg2lc-smarc.dtsi
@@ -0,0 +1,77 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+/*
+ * Device Tree Source for the RZ/G2LC SMARC EVK parts
+ *
+ * Copyright (C) 2022 Renesas Electronics Corp.
+ */
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/pinctrl/rzg2l-pinctrl.h>
+
+/*
+ * DIP-Switch SW1 setting on SoM
+ * 1 : High; 0: Low
+ * SW1-2 : SW_SD0_DEV_SEL (1: eMMC; 0: uSD)
+ * SW1-3 : SW_SCIF_CAN (1: CAN1; 0: SCIF1)
+ * SW1-4 : SW_RSPI_CAN (1: CAN1; 0: RSPI1)
+ * SW1-5 : SW_I2S0_I2S1 (1: I2S2 (HDMI audio); 0: I2S0)
+ * Please change below macros according to SW1 setting
+ */
+
+#define SW_SD0_DEV_SEL 1
+
+#define SW_SCIF_CAN 0
+#if (SW_SCIF_CAN)
+/* Due to HW routing, SW_RSPI_CAN is always 0 when SW_SCIF_CAN is set to 1 */
+#define SW_RSPI_CAN 0
+#else
+/* Please set SW_RSPI_CAN. Default value is 1 */
+#define SW_RSPI_CAN 1
+#endif
+
+#if (SW_SCIF_CAN & SW_RSPI_CAN)
+#error "Can not set 1 to both SW_SCIF_CAN and SW_RSPI_CAN due to HW routing"
+#endif
+
+#include "rzg2lc-smarc-som.dtsi"
+#include "rzg2lc-smarc-pinfunction.dtsi"
+#include "rz-smarc-common.dtsi"
+
+/* comment the #define statement to disable SCIF1 (SER0) on PMOD1 (CN7) */
+#define PMOD1_SER0 1
+
+/ {
+ aliases {
+ serial1 = &scif1;
+ };
+};
+
+#if (SW_SCIF_CAN || SW_RSPI_CAN)
+&canfd {
+ pinctrl-0 = <&can1_pins>;
+ /delete-node/ channel@0;
+};
+#else
+&canfd {
+ /delete-property/ pinctrl-0;
+ /delete-property/ pinctrl-names;
+ status = "disabled";
+};
+#endif
+
+/*
+ * To enable SCIF1 (SER0) on PMOD1 (CN7), On connector board
+ * SW1 should be at position 2->3 so that SER0_CTS# line is activated
+ * SW2 should be at position 2->3 so that SER0_TX line is activated
+ * SW3 should be at position 2->3 so that SER0_RX line is activated
+ * SW4 should be at position 2->3 so that SER0_RTS# line is activated
+ */
+#if (!SW_SCIF_CAN && PMOD1_SER0)
+&scif1 {
+ pinctrl-0 = <&scif1_pins>;
+ pinctrl-names = "default";
+
+ uart-has-rtscts;
+ status = "okay";
+};
+#endif
diff --git a/arch/arm64/boot/dts/renesas/ulcb-kf.dtsi b/arch/arm64/boot/dts/renesas/ulcb-kf.dtsi
index 61bd4df09df0..ae532cd21708 100644
--- a/arch/arm64/boot/dts/renesas/ulcb-kf.dtsi
+++ b/arch/arm64/boot/dts/renesas/ulcb-kf.dtsi
@@ -26,6 +26,38 @@
select-gpios = <&gpio_exp_75 13 GPIO_ACTIVE_HIGH>;
};
+ hdmi1-out {
+ compatible = "hdmi-connector";
+ type = "a";
+
+ port {
+ hdmi1_con: endpoint {
+ remote-endpoint = <&adv7513_out>;
+ };
+ };
+ };
+
+ accel_3v3: regulator-acc-3v3 {
+ 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-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ hdmi_3v3: regulator-hdmi-3v3 {
+ compatible = "regulator-fixed";
+ regulator-name = "hdmi-3v3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
snd_3p3v: regulator-snd_3p3v {
compatible = "regulator-fixed";
regulator-name = "snd-3.3v";
@@ -65,6 +97,10 @@
status = "okay";
};
+&du_out_rgb {
+ remote-endpoint = <&adv7513_in>;
+};
+
&ehci0 {
dr_mode = "otg";
status = "okay";
@@ -91,12 +127,72 @@
reg = <0x71>;
reset-gpios = <&gpio5 3 GPIO_ACTIVE_LOW>;
+ /* HDMIoSDA, HDMIoSCL */
+ i2c@4 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <4>;
+
+ hdmi@3d {
+ compatible = "adi,adv7513";
+ reg = <0x3d>;
+
+ pinctrl-0 = <&hdmi1_pins>;
+ pinctrl-names = "default";
+
+ interrupt-parent = <&gpio2>;
+ interrupts = <14 IRQ_TYPE_LEVEL_LOW>;
+
+ clocks = <&cs2000>;
+ clock-names = "cec";
+
+ 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>;
+
+ adi,input-depth = <8>;
+ adi,input-colorspace = "rgb";
+ adi,input-clock = "1x";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+ adv7513_in: endpoint {
+ remote-endpoint = <&du_out_rgb>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+ adv7513_out: endpoint {
+ remote-endpoint = <&hdmi1_con>;
+ };
+ };
+ };
+ };
+ };
+
/* Audio_SDA, Audio_SCL */
i2c@7 {
#address-cells = <1>;
#size-cells = <0>;
reg = <7>;
+ accelerometer@1d {
+ compatible = "st,lsm9ds0-imu";
+ reg = <0x1d>;
+
+ vdd-supply = <&accel_3v3>;
+ vddio-supply = <&accel_3v3>;
+ };
+
pcm3168a: audio-codec@44 {
#sound-dai-cells = <0>;
compatible = "ti,pcm3168a";
@@ -131,6 +227,14 @@
};
};
};
+
+ gyroscope@6b {
+ compatible = "st,lsm9ds0-gyro";
+ reg = <0x6b>;
+
+ vdd-supply = <&accel_3v3>;
+ vddio-supply = <&accel_3v3>;
+ };
};
};
@@ -264,6 +368,19 @@
function = "can1";
};
+ hdmi1_pins: hdmi1 {
+ adv7513-interrupt {
+ pins = "GP_2_14";
+ bias-pull-up;
+ };
+
+ du {
+ groups = "du_rgb888", "du_sync", "du_clk_out_0",
+ "du_disp";
+ function = "du";
+ };
+ };
+
hscif0_pins: hscif0 {
groups = "hscif0_data", "hscif0_ctrl";
function = "hscif0";
@@ -297,17 +414,14 @@
&sound_pcm_pins>;
ports {
- /* rsnd_port0/1 are on salvator-common */
+ /* rsnd_port0/1 are defined in ulcb.dtsi */
rsnd_port2: port@2 {
reg = <2>;
rsnd_for_pcm3168a_play: endpoint {
remote-endpoint = <&pcm3168a_endpoint_p>;
-
- dai-format = "i2s";
- bitclock-master = <&rsnd_for_pcm3168a_play>;
- frame-master = <&rsnd_for_pcm3168a_play>;
+ bitclock-master;
+ frame-master;
dai-tdm-slot-num = <8>;
-
playback = <&ssi3>;
};
};
@@ -315,12 +429,9 @@
reg = <3>;
rsnd_for_pcm3168a_capture: endpoint {
remote-endpoint = <&pcm3168a_endpoint_c>;
-
- dai-format = "i2s";
- bitclock-master = <&rsnd_for_pcm3168a_capture>;
- frame-master = <&rsnd_for_pcm3168a_capture>;
+ bitclock-master;
+ frame-master;
dai-tdm-slot-num = <6>;
-
capture = <&ssi4>;
};
};
@@ -360,10 +471,10 @@
};
&sound_card {
- dais = <&rsnd_port0 /* ak4613 */
- &rsnd_port1 /* HDMI0 */
- &rsnd_port2 /* pcm3168a playback */
- &rsnd_port3 /* pcm3168a capture */
+ links = <&rsnd_port0 /* ak4613 */
+ &rsnd_port1 /* HDMI0 */
+ &rsnd_port2 /* pcm3168a playback */
+ &rsnd_port3 /* pcm3168a capture */
>;
};
diff --git a/arch/arm64/boot/dts/renesas/ulcb.dtsi b/arch/arm64/boot/dts/renesas/ulcb.dtsi
index a7e93df4ced8..b4bdb2d7e4ba 100644
--- a/arch/arm64/boot/dts/renesas/ulcb.dtsi
+++ b/arch/arm64/boot/dts/renesas/ulcb.dtsi
@@ -95,11 +95,11 @@
};
sound_card: sound {
- compatible = "audio-graph-card";
+ compatible = "audio-graph-card2";
label = "rcar-sound";
- dais = <&rsnd_port0 /* ak4613 */
- &rsnd_port1 /* HDMI0 */
+ links = <&rsnd_port0 /* ak4613 */
+ &rsnd_port1 /* HDMI0 */
>;
};
@@ -408,11 +408,8 @@
reg = <0>;
rsnd_for_ak4613: endpoint {
remote-endpoint = <&ak4613_endpoint>;
-
- dai-format = "left_j";
- bitclock-master = <&rsnd_for_ak4613>;
- frame-master = <&rsnd_for_ak4613>;
-
+ bitclock-master;
+ frame-master;
playback = <&ssi0>, <&src0>, <&dvc0>;
capture = <&ssi1>, <&src1>, <&dvc1>;
};
@@ -421,11 +418,8 @@
reg = <1>;
rsnd_for_hdmi: endpoint {
remote-endpoint = <&dw_hdmi0_snd_in>;
-
- dai-format = "i2s";
- bitclock-master = <&rsnd_for_hdmi>;
- frame-master = <&rsnd_for_hdmi>;
-
+ bitclock-master;
+ frame-master;
playback = <&ssi2>;
};
};
diff --git a/arch/arm64/boot/dts/rockchip/Makefile b/arch/arm64/boot/dts/rockchip/Makefile
index 479906f3ad7b..4ae9f35434b8 100644
--- a/arch/arm64/boot/dts/rockchip/Makefile
+++ b/arch/arm64/boot/dts/rockchip/Makefile
@@ -56,5 +56,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-pinenote-v1.1.dtb
+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-pinenote-v1.2.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-quartz64-a.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-evb1-v10.dtb
+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-bpi-r2-pro.dtb
diff --git a/arch/arm64/boot/dts/rockchip/px30.dtsi b/arch/arm64/boot/dts/rockchip/px30.dtsi
index f972704dfe7a..56dfbb2e2fa6 100644
--- a/arch/arm64/boot/dts/rockchip/px30.dtsi
+++ b/arch/arm64/boot/dts/rockchip/px30.dtsi
@@ -711,7 +711,7 @@
clock-names = "pclk", "timer";
};
- dmac: dmac@ff240000 {
+ dmac: dma-controller@ff240000 {
compatible = "arm,pl330", "arm,primecell";
reg = <0x0 0xff240000 0x0 0x4000>;
interrupts = <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>,
diff --git a/arch/arm64/boot/dts/rockchip/rk3328-a1.dts b/arch/arm64/boot/dts/rockchip/rk3328-a1.dts
index de2d3e88e27f..40bf808642b9 100644
--- a/arch/arm64/boot/dts/rockchip/rk3328-a1.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3328-a1.dts
@@ -160,6 +160,7 @@
pinctrl-0 = <&pmic_int_l>;
rockchip,system-power-controller;
wakeup-source;
+ #clock-cells = <0>;
vcc1-supply = <&vcc_sys>;
vcc2-supply = <&vcc_sys>;
diff --git a/arch/arm64/boot/dts/rockchip/rk3328.dtsi b/arch/arm64/boot/dts/rockchip/rk3328.dtsi
index 39db0b85b4da..b822533dc7f1 100644
--- a/arch/arm64/boot/dts/rockchip/rk3328.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3328.dtsi
@@ -489,7 +489,7 @@
status = "disabled";
};
- dmac: dmac@ff1f0000 {
+ dmac: dma-controller@ff1f0000 {
compatible = "arm,pl330", "arm,primecell";
reg = <0x0 0xff1f0000 0x0 0x4000>;
interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>,
diff --git a/arch/arm64/boot/dts/rockchip/rk3399-firefly.dts b/arch/arm64/boot/dts/rockchip/rk3399-firefly.dts
index c4dd2a6b4836..c654b6b02f3f 100644
--- a/arch/arm64/boot/dts/rockchip/rk3399-firefly.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3399-firefly.dts
@@ -245,12 +245,12 @@
vdd_log: vdd-log {
compatible = "pwm-regulator";
pwms = <&pwm2 0 25000 1>;
+ pwm-supply = <&vcc_sys>;
regulator-name = "vdd_log";
regulator-always-on;
regulator-boot-on;
regulator-min-microvolt = <430000>;
regulator-max-microvolt = <1400000>;
- vin-supply = <&vcc_sys>;
};
};
@@ -298,6 +298,11 @@
status = "okay";
};
+&gpu {
+ mali-supply = <&vdd_gpu>;
+ status = "okay";
+};
+
&hdmi {
ddc-i2c-bus = <&i2c3>;
pinctrl-names = "default";
@@ -770,8 +775,8 @@
sd-uhs-sdr104;
/* Power supply */
- vqmmc-supply = &vcc1v8_s3; /* IO line */
- vmmc-supply = &vcc_sdio; /* card's power */
+ vqmmc-supply = <&vcc1v8_s3>; /* IO line */
+ vmmc-supply = <&vcc_sdio>; /* card's power */
#address-cells = <1>;
#size-cells = <0>;
diff --git a/arch/arm64/boot/dts/rockchip/rk3399-gru-chromebook.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-gru-chromebook.dtsi
index 9b2c679f5eca..3355fb90fa54 100644
--- a/arch/arm64/boot/dts/rockchip/rk3399-gru-chromebook.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3399-gru-chromebook.dtsi
@@ -462,7 +462,7 @@ ap_i2c_tp: &i2c5 {
};
&cros_ec {
- cros_ec_pwm: ec-pwm {
+ cros_ec_pwm: pwm {
compatible = "google,cros-ec-pwm";
#pwm-cells = <1>;
};
diff --git a/arch/arm64/boot/dts/rockchip/rk3399-gru.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-gru.dtsi
index 45a5ae5d2027..162f08bca0d4 100644
--- a/arch/arm64/boot/dts/rockchip/rk3399-gru.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3399-gru.dtsi
@@ -286,7 +286,7 @@
sound: sound {
compatible = "rockchip,rk3399-gru-sound";
- rockchip,cpu = <&i2s0 &i2s2>;
+ rockchip,cpu = <&i2s0 &spdif>;
};
};
@@ -437,10 +437,6 @@ ap_i2c_audio: &i2c8 {
status = "okay";
};
-&i2s2 {
- status = "okay";
-};
-
&io_domains {
status = "okay";
@@ -537,6 +533,17 @@ ap_i2c_audio: &i2c8 {
vqmmc-supply = <&ppvar_sd_card_io>;
};
+&spdif {
+ status = "okay";
+
+ /*
+ * SPDIF is routed internally to DP; we either don't use these pins, or
+ * mux them to something else.
+ */
+ /delete-property/ pinctrl-0;
+ /delete-property/ pinctrl-names;
+};
+
&spi1 {
status = "okay";
diff --git a/arch/arm64/boot/dts/rockchip/rk3399-khadas-edge.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-khadas-edge.dtsi
index f1fcc6b5b402..7ba3ed24084b 100644
--- a/arch/arm64/boot/dts/rockchip/rk3399-khadas-edge.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3399-khadas-edge.dtsi
@@ -80,12 +80,12 @@
vdd_log: vdd-log {
compatible = "pwm-regulator";
pwms = <&pwm2 0 25000 1>;
+ pwm-supply = <&vsys_3v3>;
regulator-name = "vdd_log";
regulator-always-on;
regulator-boot-on;
regulator-min-microvolt = <800000>;
regulator-max-microvolt = <1400000>;
- vin-supply = <&vsys_3v3>;
};
vsys: vsys {
diff --git a/arch/arm64/boot/dts/rockchip/rk3399-leez-p710.dts b/arch/arm64/boot/dts/rockchip/rk3399-leez-p710.dts
index e890166e7fd4..5bbe74bed0ea 100644
--- a/arch/arm64/boot/dts/rockchip/rk3399-leez-p710.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3399-leez-p710.dts
@@ -102,12 +102,12 @@
vdd_log: vdd-log {
compatible = "pwm-regulator";
pwms = <&pwm2 0 25000 1>;
+ pwm-supply = <&vcc5v0_sys>;
regulator-name = "vdd_log";
regulator-always-on;
regulator-boot-on;
regulator-min-microvolt = <800000>;
regulator-max-microvolt = <1400000>;
- vin-supply = <&vcc5v0_sys>;
};
};
diff --git a/arch/arm64/boot/dts/rockchip/rk3399-orangepi.dts b/arch/arm64/boot/dts/rockchip/rk3399-orangepi.dts
index 04b54abea3cc..9d3a718f66f6 100644
--- a/arch/arm64/boot/dts/rockchip/rk3399-orangepi.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3399-orangepi.dts
@@ -166,12 +166,12 @@
vdd_log: vdd-log {
compatible = "pwm-regulator";
pwms = <&pwm2 0 25000 1>;
+ pwm-supply = <&vcc_sys>;
regulator-name = "vdd_log";
regulator-always-on;
regulator-boot-on;
regulator-min-microvolt = <800000>;
regulator-max-microvolt = <1400000>;
- vin-supply = <&vcc_sys>;
};
};
diff --git a/arch/arm64/boot/dts/rockchip/rk3399-pinebook-pro.dts b/arch/arm64/boot/dts/rockchip/rk3399-pinebook-pro.dts
index c2f021a1a18f..d6b68d77d63a 100644
--- a/arch/arm64/boot/dts/rockchip/rk3399-pinebook-pro.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3399-pinebook-pro.dts
@@ -243,12 +243,12 @@
vdd_log: vdd-log {
compatible = "pwm-regulator";
pwms = <&pwm2 0 25000 1>;
+ pwm-supply = <&vcc_sysin>;
regulator-name = "vdd_log";
regulator-always-on;
regulator-boot-on;
regulator-min-microvolt = <800000>;
regulator-max-microvolt = <1400000>;
- vin-supply = <&vcc_sysin>;
regulator-state-mem {
regulator-on-in-suspend;
@@ -472,8 +472,6 @@
vcc10-supply = <&vcc_sysin>;
vcc11-supply = <&vcc_sysin>;
vcc12-supply = <&vcc3v3_sys>;
- vcc13-supply = <&vcc_sysin>;
- vcc14-supply = <&vcc_sysin>;
regulators {
/* rk3399 center logic supply */
diff --git a/arch/arm64/boot/dts/rockchip/rk3399-puma-haikou.dts b/arch/arm64/boot/dts/rockchip/rk3399-puma-haikou.dts
index 292bb7e80cf3..3ae5d727e367 100644
--- a/arch/arm64/boot/dts/rockchip/rk3399-puma-haikou.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3399-puma-haikou.dts
@@ -232,6 +232,7 @@
&usbdrd_dwc3_0 {
dr_mode = "otg";
+ extcon = <&extcon_usb3>;
status = "okay";
};
diff --git a/arch/arm64/boot/dts/rockchip/rk3399-puma.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-puma.dtsi
index fb67db4619ea..b1ac3a89f259 100644
--- a/arch/arm64/boot/dts/rockchip/rk3399-puma.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3399-puma.dtsi
@@ -25,6 +25,13 @@
};
};
+ extcon_usb3: extcon-usb3 {
+ compatible = "linux,extcon-usb-gpio";
+ id-gpio = <&gpio1 RK_PC2 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&usb3_id>;
+ };
+
clkin_gmac: external-gmac-clock {
compatible = "fixed-clock";
clock-frequency = <125000000>;
@@ -71,6 +78,17 @@
regulator-min-microvolt = <5000000>;
regulator-max-microvolt = <5000000>;
};
+
+ vdd_log: vdd-log {
+ compatible = "pwm-regulator";
+ pwms = <&pwm2 0 25000 1>;
+ pwm-supply = <&vcc5v0_sys>;
+ regulator-name = "vdd_log";
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1400000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
};
&cpu_b0 {
@@ -422,9 +440,22 @@
<4 RK_PA3 RK_FUNC_GPIO &pcfg_pull_none>;
};
};
+
+ usb3 {
+ usb3_id: usb3-id {
+ rockchip,pins =
+ <1 RK_PC2 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
};
&sdhci {
+ /*
+ * Signal integrity isn't great at 200MHz but 100MHz has proven stable
+ * enough.
+ */
+ max-frequency = <100000000>;
+
bus-width = <8>;
mmc-hs400-1_8v;
mmc-hs400-enhanced-strobe;
diff --git a/arch/arm64/boot/dts/rockchip/rk3399-roc-pc.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-roc-pc.dtsi
index d1aaf8e83391..0e45cc2d195b 100644
--- a/arch/arm64/boot/dts/rockchip/rk3399-roc-pc.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3399-roc-pc.dtsi
@@ -310,8 +310,6 @@
vcc10-supply = <&vcc3v3_sys>;
vcc11-supply = <&vcc3v3_sys>;
vcc12-supply = <&vcc3v3_sys>;
- vcc13-supply = <&vcc3v3_sys>;
- vcc14-supply = <&vcc3v3_sys>;
vddio-supply = <&vcc_3v0>;
regulators {
diff --git a/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtsi
index 92acf6ea299b..401e1ae9d944 100644
--- a/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtsi
@@ -144,12 +144,12 @@
vdd_log: vdd-log {
compatible = "pwm-regulator";
pwms = <&pwm2 0 25000 1>;
+ pwm-supply = <&vcc5v0_sys>;
regulator-name = "vdd_log";
regulator-always-on;
regulator-boot-on;
regulator-min-microvolt = <800000>;
regulator-max-microvolt = <1400000>;
- vin-supply = <&vcc5v0_sys>;
};
};
diff --git a/arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dtsi
index 83db4ca67334..45e77f86d329 100644
--- a/arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dtsi
@@ -213,12 +213,12 @@
vdd_log: vdd-log {
compatible = "pwm-regulator";
pwms = <&pwm2 0 25000 1>;
+ pwm-supply = <&vcc5v0_sys>;
regulator-name = "vdd_log";
regulator-always-on;
regulator-boot-on;
regulator-min-microvolt = <800000>;
regulator-max-microvolt = <1700000>;
- vin-supply = <&vcc5v0_sys>;
};
};
diff --git a/arch/arm64/boot/dts/rockchip/rk3399-sapphire.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-sapphire.dtsi
index 46b0f97a0b1c..2aa0fad8f893 100644
--- a/arch/arm64/boot/dts/rockchip/rk3399-sapphire.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3399-sapphire.dtsi
@@ -133,12 +133,12 @@
vdd_log: vdd-log {
compatible = "pwm-regulator";
pwms = <&pwm2 0 25000 1>;
+ pwm-supply = <&vcc_sys>;
regulator-name = "vdd_log";
regulator-always-on;
regulator-boot-on;
regulator-min-microvolt = <800000>;
regulator-max-microvolt = <1400000>;
- vin-supply = <&vcc_sys>;
};
};
diff --git a/arch/arm64/boot/dts/rockchip/rk3399.dtsi b/arch/arm64/boot/dts/rockchip/rk3399.dtsi
index d3cdf6f42a30..080457a68e3c 100644
--- a/arch/arm64/boot/dts/rockchip/rk3399.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3399.dtsi
@@ -1881,10 +1881,10 @@
interrupts = <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH 0>;
clocks = <&cru PCLK_HDMI_CTRL>,
<&cru SCLK_HDMI_SFR>,
- <&cru PLL_VPLL>,
+ <&cru SCLK_HDMI_CEC>,
<&cru PCLK_VIO_GRF>,
- <&cru SCLK_HDMI_CEC>;
- clock-names = "iahb", "isfr", "vpll", "grf", "cec";
+ <&cru PLL_VPLL>;
+ clock-names = "iahb", "isfr", "cec", "grf", "vpll";
power-domains = <&power RK3399_PD_HDCP>;
reg-io-width = <4>;
rockchip,grf = <&grf>;
diff --git a/arch/arm64/boot/dts/rockchip/rk3566-pinenote-v1.1.dts b/arch/arm64/boot/dts/rockchip/rk3566-pinenote-v1.1.dts
new file mode 100644
index 000000000000..5b0b7ebf9fee
--- /dev/null
+++ b/arch/arm64/boot/dts/rockchip/rk3566-pinenote-v1.1.dts
@@ -0,0 +1,18 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+
+/dts-v1/;
+
+#include "rk3566-pinenote.dtsi"
+
+/ {
+ model = "Pine64 PineNote v1.1";
+ compatible = "pine64,pinenote-v1.1", "pine64,pinenote", "rockchip,rk3566";
+};
+
+&pmu_io_domains {
+ vccio7-supply = <&vcc_1v8>;
+};
+
+&spk_amp {
+ VCC-supply = <&dcdc_boost>;
+};
diff --git a/arch/arm64/boot/dts/rockchip/rk3566-pinenote-v1.2.dts b/arch/arm64/boot/dts/rockchip/rk3566-pinenote-v1.2.dts
new file mode 100644
index 000000000000..6bbc4c675d64
--- /dev/null
+++ b/arch/arm64/boot/dts/rockchip/rk3566-pinenote-v1.2.dts
@@ -0,0 +1,18 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+
+/dts-v1/;
+
+#include "rk3566-pinenote.dtsi"
+
+/ {
+ model = "Pine64 PineNote v1.2";
+ compatible = "pine64,pinenote-v1.2", "pine64,pinenote", "rockchip,rk3566";
+};
+
+&pmu_io_domains {
+ vccio7-supply = <&vcc_3v3>;
+};
+
+&spk_amp {
+ VCC-supply = <&vcc_bat>;
+};
diff --git a/arch/arm64/boot/dts/rockchip/rk3566-pinenote.dtsi b/arch/arm64/boot/dts/rockchip/rk3566-pinenote.dtsi
new file mode 100644
index 000000000000..fea748adfa90
--- /dev/null
+++ b/arch/arm64/boot/dts/rockchip/rk3566-pinenote.dtsi
@@ -0,0 +1,639 @@
+// 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 "rk3566.dtsi"
+
+/ {
+ aliases {
+ mmc0 = &sdhci;
+ };
+
+ chosen {
+ stdout-path = "serial2:1500000n8";
+ };
+
+ adc-keys {
+ compatible = "adc-keys";
+ io-channels = <&saradc 0>;
+ io-channel-names = "buttons";
+ keyup-threshold-microvolt = <1750000>;
+
+ recovery {
+ label = "recovery";
+ linux,code = <KEY_VENDOR>;
+ press-threshold-microvolt = <0>;
+ };
+ };
+
+ spk_amp: audio-amplifier {
+ compatible = "simple-audio-amplifier";
+ enable-gpios = <&gpio3 RK_PC4 GPIO_ACTIVE_HIGH>;
+ pinctrl-0 = <&spk_amp_enable_h>;
+ pinctrl-names = "default";
+ sound-name-prefix = "Speaker Amp";
+ };
+
+ dmic_codec: dmic-codec {
+ compatible = "dmic-codec";
+ num-channels = <6>;
+ #sound-dai-cells = <0>;
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+ pinctrl-0 = <&hall_int_l>;
+ pinctrl-names = "default";
+
+ cover {
+ label = "cover";
+ gpios = <&gpio0 RK_PC7 GPIO_ACTIVE_LOW>;
+ linux,input-type = <EV_SW>;
+ linux,code = <SW_MACHINE_COVER>;
+ linux,can-disable;
+ wakeup-event-action = <EV_ACT_DEASSERTED>;
+ wakeup-source;
+ };
+ };
+
+ gpio-leds {
+ compatible = "gpio-leds";
+ pinctrl-0 = <&led_pin>;
+ pinctrl-names = "default";
+
+ led-0 {
+ color = <LED_COLOR_ID_WHITE>;
+ function = LED_FUNCTION_CHARGING;
+ gpios = <&gpio3 RK_PC5 GPIO_ACTIVE_HIGH>;
+ };
+ };
+
+ sdio_pwrseq: sdio-pwrseq {
+ compatible = "mmc-pwrseq-simple";
+ clocks = <&rk817 1>;
+ clock-names = "ext_clock";
+ pinctrl-0 = <&wifi_enable_h>;
+ pinctrl-names = "default";
+ reset-gpios = <&gpio0 RK_PC6 GPIO_ACTIVE_LOW>;
+ };
+
+ sound {
+ compatible = "simple-audio-card";
+ simple-audio-card,name = "PineNote";
+ simple-audio-card,aux-devs = <&spk_amp>;
+ simple-audio-card,widgets = "Headphone", "Headphones",
+ "Speaker", "Internal Speakers";
+ simple-audio-card,routing = "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";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ simple-audio-card,dai-link@0 {
+ reg = <0>;
+ bitclock-master = <&link0_cpu>;
+ format = "i2s";
+ frame-master = <&link0_cpu>;
+ mclk-fs = <256>;
+
+ link0_cpu: cpu {
+ sound-dai = <&i2s1_8ch>;
+ };
+
+ link0_codec: codec {
+ sound-dai = <&rk817>;
+ };
+ };
+
+ simple-audio-card,dai-link@1 {
+ reg = <1>;
+ bitclock-master = <&link1_cpu>;
+ format = "pdm";
+ frame-master = <&link1_cpu>;
+
+ link1_cpu: cpu {
+ sound-dai = <&pdm>;
+ };
+
+ link1_codec: codec {
+ sound-dai = <&dmic_codec>;
+ };
+ };
+ };
+
+ vbat_4g: vbat-4g {
+ compatible = "regulator-fixed";
+ regulator-name = "vbat_4g";
+ regulator-min-microvolt = <3800000>;
+ regulator-max-microvolt = <3800000>;
+ /* powered by vcc_bat, enabled by vbat_4g_en */
+ vin-supply = <&vbat_4g_en>;
+ };
+
+ vcc_1v8: vcc-1v8 {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc_1v8";
+ regulator-always-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ /* powered by vcc_sys, enabled by vcc_1v8_en */
+ vin-supply = <&vcc_1v8_en>;
+ };
+
+ vcc_bat: vcc-bat {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc_bat";
+ regulator-always-on;
+ regulator-min-microvolt = <3800000>;
+ regulator-max-microvolt = <3800000>;
+ };
+
+ vcc_hall_3v3: vcc-hall-3v3 {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc_hall_3v3";
+ regulator-always-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ vin-supply = <&vcc_sys>;
+ };
+
+ vcc_sys: vcc-sys {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc_sys";
+ regulator-always-on;
+ regulator-min-microvolt = <3800000>;
+ regulator-max-microvolt = <3800000>;
+ vin-supply = <&vcc_bat>;
+ };
+
+ vcc_wl: vcc-wl {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ gpio = <&gpio0 RK_PA0 GPIO_ACTIVE_HIGH>;
+ pinctrl-0 = <&vcc_wl_pin>;
+ pinctrl-names = "default";
+ regulator-name = "vcc_wl";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ vin-supply = <&vcc_bat>;
+ };
+
+ vdda_0v9: vdda-0v9 {
+ compatible = "regulator-fixed";
+ regulator-name = "vdda_0v9";
+ regulator-always-on;
+ regulator-min-microvolt = <900000>;
+ regulator-max-microvolt = <900000>;
+ /* powered by vcc_sys, enabled by vcc_1v8_en */
+ vin-supply = <&vcc_1v8_en>;
+ };
+};
+
+&cpu0 {
+ cpu-supply = <&vdd_cpu>;
+};
+
+&cpu1 {
+ cpu-supply = <&vdd_cpu>;
+};
+
+&cpu2 {
+ cpu-supply = <&vdd_cpu>;
+};
+
+&cpu3 {
+ cpu-supply = <&vdd_cpu>;
+};
+
+&i2c0 {
+ status = "okay";
+
+ vdd_cpu: regulator@1c {
+ compatible = "tcs,tcs4525";
+ reg = <0x1c>;
+ fcs,suspend-voltage-selector = <0>;
+ regulator-name = "vdd_cpu";
+ regulator-min-microvolt = <712500>;
+ regulator-max-microvolt = <1390000>;
+ regulator-ramp-delay = <2300>;
+ regulator-always-on;
+ vin-supply = <&vcc_sys>;
+
+ regulator-state-mem {
+ regulator-on-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>;
+ clocks = <&cru I2S1_MCLKOUT_TX>;
+ clock-names = "mclk";
+ #clock-cells = <1>;
+ pinctrl-0 = <&i2s1m0_mclk>, <&pmic_int_l>, <&pmic_sleep>;
+ pinctrl-names = "default";
+ 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 = <&dcdc_boost>;
+
+ regulators {
+ vdd_logic: DCDC_REG1 {
+ regulator-name = "vdd_logic";
+ regulator-always-on;
+ regulator-min-microvolt = <500000>;
+ regulator-max-microvolt = <1350000>;
+ regulator-init-microvolt = <900000>;
+ regulator-ramp-delay = <6001>;
+ regulator-initial-mode = <0x2>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ regulator-suspend-microvolt = <900000>;
+ };
+ };
+
+ vdd_gpu_npu: DCDC_REG2 {
+ regulator-name = "vdd_gpu_npu";
+ regulator-min-microvolt = <500000>;
+ regulator-max-microvolt = <1350000>;
+ regulator-init-microvolt = <900000>;
+ regulator-ramp-delay = <6001>;
+ regulator-initial-mode = <0x2>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vcc_ddr: DCDC_REG3 {
+ regulator-name = "vcc_ddr";
+ regulator-always-on;
+ regulator-initial-mode = <0x2>;
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ };
+ };
+
+ vcc_3v3: DCDC_REG4 {
+ regulator-name = "vcc_3v3";
+ regulator-always-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-initial-mode = <0x2>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vcca_1v8_pmu: LDO_REG1 {
+ regulator-name = "vcca_1v8_pmu";
+ regulator-always-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ };
+ };
+
+ /* unused */
+ vdda_0v9_ldo: LDO_REG2 {
+ regulator-name = "vdda_0v9_ldo";
+ regulator-min-microvolt = <900000>;
+ regulator-max-microvolt = <900000>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vdda_0v9_pmu: LDO_REG3 {
+ regulator-name = "vdda_0v9_pmu";
+ regulator-always-on;
+ regulator-min-microvolt = <900000>;
+ regulator-max-microvolt = <900000>;
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ };
+ };
+
+ vccio_acodec: LDO_REG4 {
+ regulator-name = "vccio_acodec";
+ regulator-always-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ /* unused */
+ vccio_sd: LDO_REG5 {
+ regulator-name = "vccio_sd";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vcc_3v3_pmu: LDO_REG6 {
+ regulator-name = "vcc_3v3_pmu";
+ regulator-always-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ };
+ };
+
+ vcc_1v8_en: LDO_REG7 {
+ regulator-name = "vcc_1v8_en";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vbat_4g_en: LDO_REG8 {
+ regulator-name = "vbat_4g_en";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ sleep_sta_ctl: LDO_REG9 {
+ regulator-name = "sleep_sta_ctl";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ };
+ };
+
+ dcdc_boost: BOOST {
+ regulator-name = "boost";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ otg_switch: OTG_SWITCH {
+ regulator-name = "otg_switch";
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+ };
+ };
+};
+
+&i2c1 {
+ status = "okay";
+
+ digitizer@9 {
+ compatible = "wacom,w9013", "hid-over-i2c";
+ reg = <0x09>;
+ interrupt-parent = <&gpio0>;
+ interrupts = <RK_PB6 IRQ_TYPE_LEVEL_LOW>;
+ hid-descr-addr = <0x1>;
+ pinctrl-0 = <&pen_fwe>, <&pen_irq_l>, <&pen_rst_l>;
+ pinctrl-names = "default";
+ vdd-supply = <&vcc_3v3_pmu>;
+ };
+};
+
+&i2c3 {
+ pinctrl-0 = <&i2c3m1_xfer>;
+ status = "okay";
+
+ led-controller@36 {
+ compatible = "ti,lm3630a";
+ reg = <0x36>;
+ enable-gpios = <&gpio0 RK_PB7 GPIO_ACTIVE_HIGH>;
+ pinctrl-0 = <&backlight_hwen_h>;
+ pinctrl-names = "default";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ led@0 {
+ reg = <0>;
+ label = "backlight_cool";
+ default-brightness = <0>;
+ };
+
+ led@1 {
+ reg = <1>;
+ label = "backlight_warm";
+ default-brightness = <0>;
+ };
+ };
+};
+
+&i2s1_8ch {
+ pinctrl-0 = <&i2s1m0_lrcktx>, <&i2s1m0_sclktx>, <&i2s1m0_sdi0>, <&i2s1m0_sdo0>;
+ rockchip,trcm-sync-tx-only;
+ status = "okay";
+};
+
+&pdm {
+ pinctrl-0 = <&pdmm0_clk1>, <&pdmm0_sdi1>, <&pdmm0_sdi2>;
+ /* microphones are on channels 1 and 2 */
+ rockchip,path-map = <1>, <2>, <0>, <3>;
+ status = "okay";
+};
+
+&pinctrl {
+ audio-amplifier {
+ spk_amp_enable_h: spk-amp-enable-h {
+ rockchip,pins = <3 RK_PC4 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ backlight {
+ backlight_hwen_h: backlight-hwen-h {
+ rockchip,pins = <0 RK_PB7 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ bt {
+ bt_enable_h: bt-enable-h {
+ rockchip,pins = <0 RK_PC4 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+
+ bt_host_wake_l: bt-host-wake-l {
+ rockchip,pins = <0 RK_PC3 RK_FUNC_GPIO &pcfg_pull_up>;
+ };
+
+ bt_wake_h: bt-wake-h {
+ rockchip,pins = <0 RK_PC2 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ led {
+ led_pin: led-pin {
+ rockchip,pins = <3 RK_PC5 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ hall {
+ hall_int_l: hall-int-l {
+ rockchip,pins = <0 RK_PC7 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ pen {
+ pen_fwe: pen-fwe {
+ rockchip,pins = <3 RK_PB7 RK_FUNC_GPIO &pcfg_pull_down>;
+ };
+
+ pen_irq_l: pen-irq-l {
+ rockchip,pins = <0 RK_PB6 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+
+ pen_rst_l: pen-rst-l {
+ rockchip,pins = <0 RK_PC1 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ pmic {
+ pmic_int_l: pmic-int-l {
+ rockchip,pins = <0 RK_PA3 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+
+ pmic_sleep: pmic-sleep {
+ rockchip,pins = <0 RK_PA2 1 &pcfg_pull_none>;
+ };
+ };
+
+ sdio-pwrseq {
+ wifi_enable_h: wifi-enable-h {
+ rockchip,pins = <0 RK_PC6 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ vcc-wl {
+ vcc_wl_pin: vcc-wl-pin {
+ rockchip,pins = <0 RK_PA0 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ wifi {
+ wifi_host_wake_l: wifi-host-wake-l {
+ rockchip,pins = <0 RK_PC5 RK_FUNC_GPIO &pcfg_pull_up>;
+ };
+ };
+};
+
+&pmu_io_domains {
+ pmuio1-supply = <&vcc_3v3_pmu>;
+ pmuio2-supply = <&vcc_3v3_pmu>;
+ vccio1-supply = <&vccio_acodec>;
+ vccio2-supply = <&vcc_1v8>;
+ vccio3-supply = <&vcc_3v3>;
+ vccio4-supply = <&vcca_1v8_pmu>;
+ vccio5-supply = <&vcc_3v3>;
+ vccio6-supply = <&vcc_3v3>;
+ status = "okay";
+};
+
+&saradc {
+ vref-supply = <&vcc_1v8>;
+ status = "okay";
+};
+
+&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";
+};
+
+&sdmmc1 {
+ bus-width = <4>;
+ cap-sd-highspeed;
+ cap-sdio-irq;
+ keep-power-in-suspend;
+ mmc-pwrseq = <&sdio_pwrseq>;
+ non-removable;
+ pinctrl-0 = <&sdmmc1_bus4>, <&sdmmc1_clk>, <&sdmmc1_cmd>;
+ pinctrl-names = "default";
+ sd-uhs-sdr104;
+ vmmc-supply = <&vcc_wl>;
+ vqmmc-supply = <&vcca_1v8_pmu>;
+ status = "okay";
+};
+
+&tsadc {
+ /* tshut mode 0:CRU 1:GPIO */
+ rockchip,hw-tshut-mode = <1>;
+ /* tshut polarity 0:LOW 1:HIGH */
+ rockchip,hw-tshut-polarity = <0>;
+ status = "okay";
+};
+
+&uart1 {
+ pinctrl-0 = <&uart1m0_ctsn>, <&uart1m0_rtsn>, <&uart1m0_xfer>;
+ pinctrl-names = "default";
+ uart-has-rtscts;
+ status = "okay";
+
+ bluetooth {
+ compatible = "brcm,bcm43438-bt";
+ clocks = <&rk817 1>;
+ clock-names = "lpo";
+ device-wake-gpios = <&gpio0 RK_PC2 GPIO_ACTIVE_HIGH>;
+ host-wake-gpios = <&gpio0 RK_PC3 GPIO_ACTIVE_HIGH>;
+ reset-gpios = <&gpio0 RK_PC4 GPIO_ACTIVE_LOW>;
+ pinctrl-0 = <&bt_enable_h>, <&bt_host_wake_l>, <&bt_wake_h>;
+ pinctrl-names = "default";
+ vbat-supply = <&vcc_wl>;
+ vddio-supply = <&vcca_1v8_pmu>;
+ };
+};
+
+&uart2 {
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts b/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts
index 166399b7f13f..dd7f4b9b686b 100644
--- a/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts
@@ -73,6 +73,17 @@
};
};
+ sdio_pwrseq: sdio-pwrseq {
+ compatible = "mmc-pwrseq-simple";
+ clocks = <&rk817 1>;
+ clock-names = "ext_clock";
+ pinctrl-names = "default";
+ pinctrl-0 = <&wifi_enable_h>;
+ post-power-on-delay-ms = <100>;
+ power-off-delay-us = <5000000>;
+ reset-gpios = <&gpio2 RK_PC2 GPIO_ACTIVE_LOW>;
+ };
+
spdif_dit: spdif-dit {
compatible = "linux,spdif-dit";
#sound-dai-cells = <0>;
@@ -124,6 +135,22 @@
vin-supply = <&vcc12v_dcin>;
};
+ /* all four ports are controlled by one gpio
+ * the host ports are sourced from vcc5v0_usb
+ * the otg port is sourced from vcc5v0_midu
+ */
+ vcc5v0_usb20_host: vcc5v0_usb20_host {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ gpio = <&gpio4 RK_PB5 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&vcc5v0_usb20_host_en>;
+ regulator-name = "vcc5v0_usb20_host";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ vin-supply = <&vcc5v0_usb>;
+ };
+
vcc3v3_sd: vcc3v3_sd {
compatible = "regulator-fixed";
enable-active-low;
@@ -147,6 +174,17 @@
regulator-max-microvolt = <4400000>;
vin-supply = <&vbus>;
};
+
+ /* sourced from vcc_sys, sdio module operates internally at 3.3v */
+ vcc_wl: vcc_wl {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc_wl";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ vin-supply = <&vcc_sys>;
+ };
};
&cpu0 {
@@ -205,6 +243,11 @@
status = "okay";
};
+&gpu {
+ mali-supply = <&vdd_gpu>;
+ status = "okay";
+};
+
&i2c0 {
status = "okay";
@@ -285,8 +328,6 @@
vcc_ddr: DCDC_REG3 {
regulator-always-on;
regulator-boot-on;
- regulator-min-microvolt = <1100000>;
- regulator-max-microvolt = <1100000>;
regulator-initial-mode = <0x2>;
regulator-name = "vcc_ddr";
regulator-state-mem {
@@ -429,6 +470,14 @@
};
};
+/* i2c3 is exposed on con40
+ * pin 3 - i2c3_sda_m0, pullup to vcc_3v3
+ * pin 5 - i2c3_scl_m0, pullup to vcc_3v3
+ */
+&i2c3 {
+ status = "okay";
+};
+
&i2s1_8ch {
pinctrl-names = "default";
pinctrl-0 = <&i2s1m0_sclktx
@@ -477,6 +526,18 @@
};
};
+ usb2 {
+ vcc5v0_usb20_host_en: vcc5v0-usb20-host-en {
+ rockchip,pins = <4 RK_PB5 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ sdio-pwrseq {
+ wifi_enable_h: wifi-enable-h {
+ rockchip,pins = <2 RK_PC2 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
vcc_sd {
vcc_sd_h: vcc-sd-h {
rockchip,pins = <0 RK_PA5 RK_FUNC_GPIO &pcfg_pull_none>;
@@ -484,6 +545,19 @@
};
};
+&pmu_io_domains {
+ pmuio1-supply = <&vcc3v3_pmu>;
+ pmuio2-supply = <&vcc3v3_pmu>;
+ vccio1-supply = <&vccio_acodec>;
+ vccio2-supply = <&vcc_1v8>;
+ vccio3-supply = <&vccio_sd>;
+ vccio4-supply = <&vcc_1v8>;
+ vccio5-supply = <&vcc_3v3>;
+ vccio6-supply = <&vcc1v8_dvp>;
+ vccio7-supply = <&vcc_3v3>;
+ status = "okay";
+};
+
&sdhci {
bus-width = <8>;
mmc-hs200-1_8v;
@@ -505,10 +579,32 @@
status = "okay";
};
+&sdmmc1 {
+ bus-width = <4>;
+ cap-sd-highspeed;
+ cap-sdio-irq;
+ keep-power-in-suspend;
+ mmc-pwrseq = <&sdio_pwrseq>;
+ non-removable;
+ pinctrl-names = "default";
+ pinctrl-0 = <&sdmmc1_bus4 &sdmmc1_cmd &sdmmc1_clk>;
+ sd-uhs-sdr104;
+ vmmc-supply = <&vcc_wl>;
+ vqmmc-supply = <&vcc_1v8>;
+ status = "okay";
+};
+
+/* spdif is exposed on con40 pin 18 */
&spdif {
status = "okay";
};
+/* spi1 is exposed on con40
+ * pin 11 - spi1_mosi_m1
+ * pin 13 - spi1_miso_m1
+ * pin 15 - spi1_clk_m1
+ * pin 17 - spi1_cs0_m1
+ */
&spi1 {
pinctrl-names = "default";
pinctrl-0 = <&spi1m1_cs0 &spi1m1_pins>;
@@ -522,6 +618,10 @@
status = "okay";
};
+/* uart0 is exposed on con40
+ * pin 12 - uart0_tx
+ * pin 14 - uart0_rx
+ */
&uart0 {
pinctrl-names = "default";
pinctrl-0 = <&uart0_xfer>;
@@ -548,6 +648,40 @@
};
};
+/* uart2 is exposed on con40
+ * pin 8 - uart2_tx_m0_debug
+ * pin 10 - uart2_rx_m0_debug
+ */
&uart2 {
status = "okay";
};
+
+&usb_host0_ehci {
+ status = "okay";
+};
+
+&usb_host0_ohci {
+ status = "okay";
+};
+
+&usb_host1_ehci {
+ status = "okay";
+};
+
+&usb_host1_ohci {
+ status = "okay";
+};
+
+&usb2phy1 {
+ status = "okay";
+};
+
+&usb2phy1_host {
+ phy-supply = <&vcc5v0_usb20_host>;
+ status = "okay";
+};
+
+&usb2phy1_otg {
+ phy-supply = <&vcc5v0_usb20_host>;
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/rockchip/rk3568-bpi-r2-pro.dts b/arch/arm64/boot/dts/rockchip/rk3568-bpi-r2-pro.dts
new file mode 100644
index 000000000000..a01886b467ed
--- /dev/null
+++ b/arch/arm64/boot/dts/rockchip/rk3568-bpi-r2-pro.dts
@@ -0,0 +1,457 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Author: Frank Wunderlich <frank-w@public-files.de>
+ *
+ */
+
+/dts-v1/;
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/leds/common.h>
+#include <dt-bindings/pinctrl/rockchip.h>
+#include "rk3568.dtsi"
+
+/ {
+ model = "Bananapi-R2 Pro (RK3568) DDR4 Board";
+ compatible = "rockchip,rk3568-bpi-r2pro", "rockchip,rk3568";
+
+ aliases {
+ ethernet0 = &gmac0;
+ mmc0 = &sdmmc0;
+ mmc1 = &sdhci;
+ };
+
+ chosen: chosen {
+ stdout-path = "serial2:1500000n8";
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ pinctrl-names = "default";
+ pinctrl-0 = <&blue_led_pin &green_led_pin>;
+
+ blue_led: led-0 {
+ color = <LED_COLOR_ID_BLUE>;
+ default-state = "off";
+ function = LED_FUNCTION_STATUS;
+ gpios = <&gpio0 RK_PD6 GPIO_ACTIVE_HIGH>;
+ };
+
+ green_led: led-1 {
+ color = <LED_COLOR_ID_GREEN>;
+ default-state = "on";
+ function = LED_FUNCTION_POWER;
+ gpios = <&gpio0 RK_PD5 GPIO_ACTIVE_HIGH>;
+ };
+ };
+
+ dc_12v: dc-12v {
+ compatible = "regulator-fixed";
+ regulator-name = "dc_12v";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <12000000>;
+ regulator-max-microvolt = <12000000>;
+ };
+
+ vcc3v3_sys: vcc3v3-sys {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc3v3_sys";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ vin-supply = <&dc_12v>;
+ };
+
+ vcc5v0_sys: vcc5v0-sys {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc5v0_sys";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ vin-supply = <&dc_12v>;
+ };
+};
+
+&gmac0 {
+ assigned-clocks = <&cru SCLK_GMAC0_RX_TX>, <&cru SCLK_GMAC0>;
+ assigned-clock-parents = <&cru SCLK_GMAC0_RGMII_SPEED>, <&cru CLK_MAC0_2TOP>;
+ clock_in_out = "input";
+ phy-handle = <&rgmii_phy0>;
+ phy-mode = "rgmii";
+ pinctrl-names = "default";
+ pinctrl-0 = <&gmac0_miim
+ &gmac0_tx_bus2
+ &gmac0_rx_bus2
+ &gmac0_rgmii_clk
+ &gmac0_rgmii_bus>;
+ snps,reset-gpio = <&gpio3 RK_PB7 GPIO_ACTIVE_LOW>;
+ snps,reset-active-low;
+ /* Reset time is 20ms, 100ms for rtl8211f */
+ snps,reset-delays-us = <0 20000 100000>;
+ tx_delay = <0x3c>;
+ rx_delay = <0x2f>;
+ status = "okay";
+};
+
+&i2c0 {
+ status = "okay";
+
+ rk809: pmic@20 {
+ compatible = "rockchip,rk809";
+ reg = <0x20>;
+ interrupt-parent = <&gpio0>;
+ interrupts = <RK_PA3 IRQ_TYPE_LEVEL_LOW>;
+ #clock-cells = <1>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pmic_int>;
+ rockchip,system-power-controller;
+ vcc1-supply = <&vcc3v3_sys>;
+ vcc2-supply = <&vcc3v3_sys>;
+ vcc3-supply = <&vcc3v3_sys>;
+ vcc4-supply = <&vcc3v3_sys>;
+ vcc5-supply = <&vcc3v3_sys>;
+ vcc6-supply = <&vcc3v3_sys>;
+ vcc7-supply = <&vcc3v3_sys>;
+ vcc8-supply = <&vcc3v3_sys>;
+ vcc9-supply = <&vcc3v3_sys>;
+ wakeup-source;
+
+ regulators {
+ vdd_logic: DCDC_REG1 {
+ regulator-name = "vdd_logic";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-init-microvolt = <900000>;
+ regulator-initial-mode = <0x2>;
+ regulator-min-microvolt = <500000>;
+ regulator-max-microvolt = <1350000>;
+ regulator-ramp-delay = <6001>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vdd_gpu: DCDC_REG2 {
+ regulator-name = "vdd_gpu";
+ regulator-init-microvolt = <900000>;
+ regulator-initial-mode = <0x2>;
+ regulator-min-microvolt = <500000>;
+ regulator-max-microvolt = <1350000>;
+ regulator-ramp-delay = <6001>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vcc_ddr: DCDC_REG3 {
+ regulator-name = "vcc_ddr";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-initial-mode = <0x2>;
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ };
+ };
+
+ vdd_npu: DCDC_REG4 {
+ regulator-name = "vdd_npu";
+ regulator-init-microvolt = <900000>;
+ regulator-initial-mode = <0x2>;
+ regulator-min-microvolt = <500000>;
+ regulator-max-microvolt = <1350000>;
+ regulator-ramp-delay = <6001>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vcc_1v8: DCDC_REG5 {
+ regulator-name = "vcc_1v8";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vdda0v9_image: LDO_REG1 {
+ regulator-name = "vdda0v9_image";
+ regulator-min-microvolt = <900000>;
+ regulator-max-microvolt = <900000>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vdda_0v9: LDO_REG2 {
+ regulator-name = "vdda_0v9";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <900000>;
+ regulator-max-microvolt = <900000>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vdda0v9_pmu: LDO_REG3 {
+ regulator-name = "vdda0v9_pmu";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <900000>;
+ regulator-max-microvolt = <900000>;
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <900000>;
+ };
+ };
+
+ vccio_acodec: LDO_REG4 {
+ regulator-name = "vccio_acodec";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vccio_sd: LDO_REG5 {
+ regulator-name = "vccio_sd";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vcc3v3_pmu: LDO_REG6 {
+ regulator-name = "vcc3v3_pmu";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <3300000>;
+ };
+ };
+
+ vcca_1v8: LDO_REG7 {
+ regulator-name = "vcca_1v8";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vcca1v8_pmu: LDO_REG8 {
+ regulator-name = "vcca1v8_pmu";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <1800000>;
+ };
+ };
+
+ vcca1v8_image: LDO_REG9 {
+ regulator-name = "vcca1v8_image";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vcc_3v3: SWITCH_REG1 {
+ regulator-name = "vcc_3v3";
+ regulator-always-on;
+ regulator-boot-on;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vcc3v3_sd: SWITCH_REG2 {
+ regulator-name = "vcc3v3_sd";
+ regulator-always-on;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+ };
+ };
+};
+
+&i2c5 {
+ /* pin 3 (SDA) + 4 (SCL) of header con2 */
+ status = "disabled";
+};
+
+&mdio0 {
+ rgmii_phy0: ethernet-phy@0 {
+ compatible = "ethernet-phy-ieee802.3-c22";
+ reg = <0x0>;
+ };
+};
+
+&pinctrl {
+ leds {
+ blue_led_pin: blue-led-pin {
+ rockchip,pins = <0 RK_PD6 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ green_led_pin: green-led-pin {
+ rockchip,pins = <0 RK_PD5 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ pmic {
+ pmic_int: pmic_int {
+ rockchip,pins =
+ <0 RK_PA3 RK_FUNC_GPIO &pcfg_pull_up>;
+ };
+ };
+};
+
+&pmu_io_domains {
+ pmuio1-supply = <&vcc3v3_pmu>;
+ pmuio2-supply = <&vcc3v3_pmu>;
+ vccio1-supply = <&vccio_acodec>;
+ vccio3-supply = <&vccio_sd>;
+ vccio4-supply = <&vcc_1v8>;
+ vccio5-supply = <&vcc_3v3>;
+ vccio6-supply = <&vcc_3v3>;
+ vccio7-supply = <&vcc_3v3>;
+ status = "okay";
+};
+
+&pwm8 {
+ /* fan 5v - gnd - pwm */
+ status = "okay";
+};
+
+&pwm10 {
+ /* pin 7 of header con2 */
+ status = "disabled";
+};
+
+&pwm11 {
+ /* pin 15 of header con2 */
+ status = "disabled";
+};
+
+&pwm12 {
+ /* pin 21 of header con2 */
+ /* shared with uart9 + spi3 */
+ pinctrl-0 = <&pwm12m1_pins>;
+ status = "disabled";
+};
+
+&pwm13 {
+ /* pin 24 of header con2 */
+ /* shared with uart9 */
+ pinctrl-0 = <&pwm13m1_pins>;
+ status = "disabled";
+};
+
+&pwm14 {
+ /* pin 23 of header con2 */
+ /* shared with spi3 */
+ pinctrl-0 = <&pwm14m1_pins>;
+ status = "disabled";
+};
+
+&pwm15 {
+ /* pin 19 of header con2 */
+ /* shared with spi3 */
+ pinctrl-0 = <&pwm15m1_pins>;
+ status = "disabled";
+};
+
+&saradc {
+ vref-supply = <&vcca_1v8>;
+ status = "okay";
+};
+
+&sdhci {
+ bus-width = <8>;
+ max-frequency = <200000000>;
+ non-removable;
+ pinctrl-names = "default";
+ pinctrl-0 = <&emmc_bus8 &emmc_clk &emmc_cmd &emmc_datastrobe>;
+ 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";
+};
+
+&spi3 {
+ /* pin 19 (MO) + 21 (MI) + 23 (CK) of header con2 */
+ /* shared with pwm12/14/15 and uart9 */
+ pinctrl-0 = <&spi3m1_pins>;
+ status = "disabled";
+};
+
+&tsadc {
+ status = "okay";
+};
+
+&uart0 {
+ /* pin 8 (TX) + 10 (RX) (RTS:16, CTS:18) of header con2 */
+ status = "disabled";
+};
+
+&uart2 {
+ /* debug-uart */
+ status = "okay";
+};
+
+&uart7 {
+ /* pin 11 (TX) + 13 (RX) of header con2 */
+ pinctrl-0 = <&uart7m1_xfer>;
+ status = "disabled";
+};
+
+&uart9 {
+ /* pin 21 (TX) + 24 (RX) of header con2 */
+ /* shared with pwm13 and pwm12/spi3 */
+ pinctrl-0 = <&uart9m1_xfer>;
+ status = "disabled";
+};
diff --git a/arch/arm64/boot/dts/rockchip/rk3568-evb1-v10.dts b/arch/arm64/boot/dts/rockchip/rk3568-evb1-v10.dts
index 184e2aa2416a..a794a0ea5c70 100644
--- a/arch/arm64/boot/dts/rockchip/rk3568-evb1-v10.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3568-evb1-v10.dts
@@ -6,6 +6,7 @@
/dts-v1/;
#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/leds/common.h>
#include <dt-bindings/pinctrl/rockchip.h>
#include "rk3568.dtsi"
@@ -33,6 +34,33 @@
regulator-max-microvolt = <12000000>;
};
+ leds {
+ compatible = "gpio-leds";
+
+ led_work: led-0 {
+ gpios = <&gpio0 RK_PC0 GPIO_ACTIVE_HIGH>;
+ function = LED_FUNCTION_HEARTBEAT;
+ color = <LED_COLOR_ID_BLUE>;
+ linux,default-trigger = "heartbeat";
+ pinctrl-names = "default";
+ pinctrl-0 = <&led_work_en>;
+ };
+ };
+
+ rk809-sound {
+ compatible = "simple-audio-card";
+ simple-audio-card,format = "i2s";
+ simple-audio-card,name = "Analog RK809";
+ simple-audio-card,mclk-fs = <256>;
+
+ simple-audio-card,cpu {
+ sound-dai = <&i2s1_8ch>;
+ };
+ simple-audio-card,codec {
+ sound-dai = <&rk809>;
+ };
+ };
+
vcc3v3_sys: vcc3v3-sys {
compatible = "regulator-fixed";
regulator-name = "vcc3v3_sys";
@@ -53,10 +81,38 @@
vin-supply = <&dc_12v>;
};
+ vcc5v0_usb: vcc5v0-usb {
+ 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>;
+ };
+
+ vcc5v0_usb_host: vcc5v0-usb-host {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ gpio = <&gpio0 RK_PA6 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&vcc5v0_usb_host_en>;
+ regulator-name = "vcc5v0_usb_host";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ vin-supply = <&vcc5v0_usb>;
+ };
+
vcc3v3_lcd0_n: vcc3v3-lcd0-n {
compatible = "regulator-fixed";
regulator-name = "vcc3v3_lcd0_n";
- regulator-boot-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ enable-active-high;
+ gpio = <&gpio0 RK_PC7 GPIO_ACTIVE_HIGH>;
+ vin-supply = <&vcc3v3_sys>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&vcc3v3_lcd0_n_en>;
regulator-state-mem {
regulator-off-in-suspend;
@@ -66,7 +122,13 @@
vcc3v3_lcd1_n: vcc3v3-lcd1-n {
compatible = "regulator-fixed";
regulator-name = "vcc3v3_lcd1_n";
- regulator-boot-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ enable-active-high;
+ gpio = <&gpio0 RK_PC5 GPIO_ACTIVE_HIGH>;
+ vin-supply = <&vcc3v3_sys>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&vcc3v3_lcd1_n_en>;
regulator-state-mem {
regulator-off-in-suspend;
@@ -74,6 +136,22 @@
};
};
+&cpu0 {
+ cpu-supply = <&vdd_cpu>;
+};
+
+&cpu1 {
+ cpu-supply = <&vdd_cpu>;
+};
+
+&cpu2 {
+ cpu-supply = <&vdd_cpu>;
+};
+
+&cpu3 {
+ cpu-supply = <&vdd_cpu>;
+};
+
&gmac0 {
assigned-clocks = <&cru SCLK_GMAC0_RX_TX>, <&cru SCLK_GMAC0>;
assigned-clock-parents = <&cru SCLK_GMAC0_RGMII_SPEED>;
@@ -106,18 +184,45 @@
status = "okay";
};
+&gpu {
+ mali-supply = <&vdd_gpu>;
+ status = "okay";
+};
+
&i2c0 {
status = "okay";
+ vdd_cpu: regulator@1c {
+ compatible = "tcs,tcs4525";
+ reg = <0x1c>;
+ fcs,suspend-voltage-selector = <1>;
+ regulator-name = "vdd_cpu";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1150000>;
+ regulator-ramp-delay = <2300>;
+ vin-supply = <&vcc5v0_sys>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
rk809: pmic@20 {
compatible = "rockchip,rk809";
reg = <0x20>;
interrupt-parent = <&gpio0>;
interrupts = <RK_PA3 IRQ_TYPE_LEVEL_LOW>;
+ assigned-clocks = <&cru I2S1_MCLKOUT_TX>;
+ assigned-clock-parents = <&cru CLK_I2S1_8CH_TX>;
#clock-cells = <1>;
+ clock-names = "mclk";
+ clocks = <&cru I2S1_MCLKOUT_TX>;
pinctrl-names = "default";
- pinctrl-0 = <&pmic_int>;
+ pinctrl-0 = <&pmic_int>, <&i2s1m0_mclk>;
rockchip,system-power-controller;
+ #sound-dai-cells = <0>;
vcc1-supply = <&vcc3v3_sys>;
vcc2-supply = <&vcc3v3_sys>;
vcc3-supply = <&vcc3v3_sys>;
@@ -147,6 +252,7 @@
vdd_gpu: DCDC_REG2 {
regulator-name = "vdd_gpu";
+ regulator-always-on;
regulator-init-microvolt = <900000>;
regulator-initial-mode = <0x2>;
regulator-min-microvolt = <500000>;
@@ -231,6 +337,7 @@
vccio_acodec: LDO_REG4 {
regulator-name = "vccio_acodec";
+ regulator-always-on;
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
@@ -315,9 +422,35 @@
};
};
};
+
+ codec {
+ mic-in-differential;
+ };
};
};
+&i2c1 {
+ status = "okay";
+
+ touchscreen0: goodix@14 {
+ compatible = "goodix,gt1151";
+ reg = <0x14>;
+ interrupt-parent = <&gpio0>;
+ interrupts = <RK_PB5 IRQ_TYPE_EDGE_FALLING>;
+ AVDD28-supply = <&vcc3v3_lcd0_n>;
+ irq-gpios = <&gpio0 RK_PB5 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&touch_int &touch_rst>;
+ reset-gpios = <&gpio0 RK_PB6 GPIO_ACTIVE_HIGH>;
+ VDDIO-supply = <&vcc3v3_lcd0_n>;
+ };
+};
+
+&i2s1_8ch {
+ rockchip,trcm-sync-tx-only;
+ status = "okay";
+};
+
&mdio0 {
rgmii_phy0: ethernet-phy@0 {
compatible = "ethernet-phy-ieee802.3-c22";
@@ -339,12 +472,42 @@
};
&pinctrl {
+ display {
+ vcc3v3_lcd0_n_en: vcc3v3_lcd0_n_en {
+ rockchip,pins = <0 RK_PC7 0 &pcfg_pull_none>;
+ };
+ vcc3v3_lcd1_n_en: vcc3v3_lcd1_n_en {
+ rockchip,pins = <0 RK_PC5 0 &pcfg_pull_none>;
+ };
+ };
+
+ leds {
+ led_work_en: led_work_en {
+ rockchip,pins = <0 RK_PC0 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
pmic {
pmic_int: pmic_int {
rockchip,pins =
<0 RK_PA3 RK_FUNC_GPIO &pcfg_pull_up>;
};
};
+
+ touchscreen {
+ touch_int: touch_int {
+ rockchip,pins = <0 RK_PB5 RK_FUNC_GPIO &pcfg_pull_up>;
+ };
+ touch_rst: touch_rst {
+ rockchip,pins = <0 RK_PB6 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ usb {
+ vcc5v0_usb_host_en: vcc5v0_usb_host_en {
+ rockchip,pins = <0 RK_PA6 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
};
&pmu_io_domains {
@@ -387,6 +550,42 @@
status = "okay";
};
+&tsadc {
+ rockchip,hw-tshut-mode = <1>;
+ rockchip,hw-tshut-polarity = <0>;
+ status = "okay";
+};
+
&uart2 {
status = "okay";
};
+
+&usb_host0_ehci {
+ status = "okay";
+};
+
+&usb_host0_ohci {
+ status = "okay";
+};
+
+&usb_host1_ehci {
+ status = "okay";
+};
+
+&usb_host1_ohci {
+ status = "okay";
+};
+
+&usb2phy1 {
+ status = "okay";
+};
+
+&usb2phy1_host {
+ phy-supply = <&vcc5v0_usb_host>;
+ status = "okay";
+};
+
+&usb2phy1_otg {
+ phy-supply = <&vcc5v0_usb_host>;
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/rockchip/rk3568.dtsi b/arch/arm64/boot/dts/rockchip/rk3568.dtsi
index 2fd313a295f8..5b0f528d6818 100644
--- a/arch/arm64/boot/dts/rockchip/rk3568.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3568.dtsi
@@ -8,6 +8,11 @@
/ {
compatible = "rockchip,rk3568";
+ pipe_phy_grf0: syscon@fdc70000 {
+ compatible = "rockchip,rk3568-pipe-phy-grf", "syscon";
+ reg = <0x0 0xfdc70000 0x0 0x1000>;
+ };
+
qos_pcie3x1: qos@fe190080 {
compatible = "rockchip,rk3568-qos", "syscon";
reg = <0x0 0xfe190080 0x0 0x20>;
@@ -32,13 +37,11 @@
clocks = <&cru SCLK_GMAC0>, <&cru SCLK_GMAC0_RX_TX>,
<&cru SCLK_GMAC0_RX_TX>, <&cru CLK_MAC0_REFOUT>,
<&cru ACLK_GMAC0>, <&cru PCLK_GMAC0>,
- <&cru SCLK_GMAC0_RX_TX>, <&cru CLK_GMAC0_PTP_REF>,
- <&cru PCLK_XPCS>;
+ <&cru SCLK_GMAC0_RX_TX>, <&cru CLK_GMAC0_PTP_REF>;
clock-names = "stmmaceth", "mac_clk_rx",
"mac_clk_tx", "clk_mac_refout",
"aclk_mac", "pclk_mac",
- "clk_mac_speed", "ptp_ref",
- "pclk_xpcs";
+ "clk_mac_speed", "ptp_ref";
resets = <&cru SRST_A_GMAC0>;
reset-names = "stmmaceth";
rockchip,grf = <&grf>;
@@ -71,6 +74,22 @@
queue0 {};
};
};
+
+ combphy0: phy@fe820000 {
+ compatible = "rockchip,rk3568-naneng-combphy";
+ reg = <0x0 0xfe820000 0x0 0x100>;
+ clocks = <&pmucru CLK_PCIEPHY0_REF>,
+ <&cru PCLK_PIPEPHY0>,
+ <&cru PCLK_PIPE>;
+ clock-names = "ref", "apb", "pipe";
+ assigned-clocks = <&pmucru CLK_PCIEPHY0_REF>;
+ assigned-clock-rates = <100000000>;
+ resets = <&cru SRST_PIPEPHY0>;
+ rockchip,pipe-grf = <&pipegrf>;
+ rockchip,pipe-phy-grf = <&pipe_phy_grf0>;
+ #phy-cells = <1>;
+ status = "disabled";
+ };
};
&cpu0_opp_table {
diff --git a/arch/arm64/boot/dts/rockchip/rk356x.dtsi b/arch/arm64/boot/dts/rockchip/rk356x.dtsi
index a68033a23975..7cdef800cb3c 100644
--- a/arch/arm64/boot/dts/rockchip/rk356x.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk356x.dtsi
@@ -144,6 +144,40 @@
};
};
+ gpu_opp_table: opp-table-1 {
+ compatible = "operating-points-v2";
+
+ opp-200000000 {
+ opp-hz = /bits/ 64 <200000000>;
+ opp-microvolt = <825000>;
+ };
+
+ opp-300000000 {
+ opp-hz = /bits/ 64 <300000000>;
+ opp-microvolt = <825000>;
+ };
+
+ opp-400000000 {
+ opp-hz = /bits/ 64 <400000000>;
+ opp-microvolt = <825000>;
+ };
+
+ opp-600000000 {
+ opp-hz = /bits/ 64 <600000000>;
+ opp-microvolt = <825000>;
+ };
+
+ opp-700000000 {
+ opp-hz = /bits/ 64 <700000000>;
+ opp-microvolt = <900000>;
+ };
+
+ opp-800000000 {
+ opp-hz = /bits/ 64 <800000000>;
+ opp-microvolt = <1000000>;
+ };
+ };
+
pmu {
compatible = "arm,cortex-a55-pmu";
interrupts = <GIC_SPI 228 IRQ_TYPE_LEVEL_HIGH>,
@@ -208,6 +242,50 @@
msi-controller;
};
+ usb_host0_ehci: usb@fd800000 {
+ compatible = "generic-ehci";
+ reg = <0x0 0xfd800000 0x0 0x40000>;
+ interrupts = <GIC_SPI 130 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru HCLK_USB2HOST0>, <&cru HCLK_USB2HOST0_ARB>,
+ <&cru PCLK_USB>;
+ phys = <&usb2phy1_otg>;
+ phy-names = "usb";
+ status = "disabled";
+ };
+
+ usb_host0_ohci: usb@fd840000 {
+ compatible = "generic-ohci";
+ reg = <0x0 0xfd840000 0x0 0x40000>;
+ interrupts = <GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru HCLK_USB2HOST0>, <&cru HCLK_USB2HOST0_ARB>,
+ <&cru PCLK_USB>;
+ phys = <&usb2phy1_otg>;
+ phy-names = "usb";
+ status = "disabled";
+ };
+
+ usb_host1_ehci: usb@fd880000 {
+ compatible = "generic-ehci";
+ reg = <0x0 0xfd880000 0x0 0x40000>;
+ interrupts = <GIC_SPI 133 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru HCLK_USB2HOST1>, <&cru HCLK_USB2HOST1_ARB>,
+ <&cru PCLK_USB>;
+ phys = <&usb2phy1_host>;
+ phy-names = "usb";
+ status = "disabled";
+ };
+
+ usb_host1_ohci: usb@fd8c0000 {
+ compatible = "generic-ohci";
+ reg = <0x0 0xfd8c0000 0x0 0x40000>;
+ interrupts = <GIC_SPI 134 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru HCLK_USB2HOST1>, <&cru HCLK_USB2HOST1_ARB>,
+ <&cru PCLK_USB>;
+ phys = <&usb2phy1_host>;
+ phy-names = "usb";
+ status = "disabled";
+ };
+
pmugrf: syscon@fdc20000 {
compatible = "rockchip,rk3568-pmugrf", "syscon", "simple-mfd";
reg = <0x0 0xfdc20000 0x0 0x10000>;
@@ -218,11 +296,36 @@
};
};
+ pipegrf: syscon@fdc50000 {
+ compatible = "rockchip,rk3568-pipe-grf", "syscon";
+ reg = <0x0 0xfdc50000 0x0 0x1000>;
+ };
+
grf: syscon@fdc60000 {
compatible = "rockchip,rk3568-grf", "syscon", "simple-mfd";
reg = <0x0 0xfdc60000 0x0 0x10000>;
};
+ pipe_phy_grf1: syscon@fdc80000 {
+ compatible = "rockchip,rk3568-pipe-phy-grf", "syscon";
+ reg = <0x0 0xfdc80000 0x0 0x1000>;
+ };
+
+ pipe_phy_grf2: syscon@fdc90000 {
+ compatible = "rockchip,rk3568-pipe-phy-grf", "syscon";
+ reg = <0x0 0xfdc90000 0x0 0x1000>;
+ };
+
+ usb2phy0_grf: syscon@fdca0000 {
+ compatible = "rockchip,rk3568-usb2phy-grf", "syscon";
+ reg = <0x0 0xfdca0000 0x0 0x8000>;
+ };
+
+ usb2phy1_grf: syscon@fdca8000 {
+ compatible = "rockchip,rk3568-usb2phy-grf", "syscon";
+ reg = <0x0 0xfdca8000 0x0 0x8000>;
+ };
+
pmucru: clock-controller@fdd00000 {
compatible = "rockchip,rk3568-pmucru";
reg = <0x0 0xfdd00000 0x0 0x1000>;
@@ -390,6 +493,21 @@
};
};
+ gpu: gpu@fde60000 {
+ compatible = "rockchip,rk3568-mali", "arm,mali-bifrost";
+ reg = <0x0 0xfde60000 0x0 0x4000>;
+ interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 39 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "job", "mmu", "gpu";
+ clocks = <&scmi_clk 1>, <&cru CLK_GPU>;
+ clock-names = "gpu", "bus";
+ #cooling-cells = <2>;
+ operating-points-v2 = <&gpu_opp_table>;
+ power-domains = <&power RK3568_PD_GPU>;
+ status = "disabled";
+ };
+
sdmmc2: mmc@fe000000 {
compatible = "rockchip,rk3568-dw-mshc", "rockchip,rk3288-dw-mshc";
reg = <0x0 0xfe000000 0x0 0x4000>;
@@ -651,7 +769,44 @@
status = "disabled";
};
- dmac0: dmac@fe530000 {
+ i2s3_2ch: i2s@fe430000 {
+ compatible = "rockchip,rk3568-i2s-tdm";
+ reg = <0x0 0xfe430000 0x0 0x1000>;
+ interrupts = <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru MCLK_I2S3_2CH_TX>, <&cru MCLK_I2S3_2CH_RX>,
+ <&cru HCLK_I2S3_2CH>;
+ clock-names = "mclk_tx", "mclk_rx", "hclk";
+ dmas = <&dmac1 6>, <&dmac1 7>;
+ dma-names = "tx", "rx";
+ resets = <&cru SRST_M_I2S3_2CH_TX>, <&cru SRST_M_I2S3_2CH_RX>;
+ reset-names = "tx-m", "rx-m";
+ rockchip,grf = <&grf>;
+ #sound-dai-cells = <0>;
+ status = "disabled";
+ };
+
+ pdm: pdm@fe440000 {
+ compatible = "rockchip,rk3568-pdm";
+ reg = <0x0 0xfe440000 0x0 0x1000>;
+ interrupts = <GIC_SPI 76 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru MCLK_PDM>, <&cru HCLK_PDM>;
+ clock-names = "pdm_clk", "pdm_hclk";
+ dmas = <&dmac1 9>;
+ dma-names = "rx";
+ pinctrl-0 = <&pdmm0_clk
+ &pdmm0_clk1
+ &pdmm0_sdi0
+ &pdmm0_sdi1
+ &pdmm0_sdi2
+ &pdmm0_sdi3>;
+ pinctrl-names = "default";
+ resets = <&cru SRST_M_PDM>;
+ reset-names = "pdm-m";
+ #sound-dai-cells = <0>;
+ status = "disabled";
+ };
+
+ dmac0: dma-controller@fe530000 {
compatible = "arm,pl330", "arm,primecell";
reg = <0x0 0xfe530000 0x0 0x4000>;
interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>,
@@ -662,7 +817,7 @@
#dma-cells = <1>;
};
- dmac1: dmac@fe550000 {
+ dmac1: dma-controller@fe550000 {
compatible = "arm,pl330", "arm,primecell";
reg = <0x0 0xfe550000 0x0 0x4000>;
interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>,
@@ -974,6 +1129,32 @@
polling-delay = <1000>; /* milliseconds */
thermal-sensors = <&tsadc 1>;
+
+ trips {
+ gpu_threshold: gpu-threshold {
+ temperature = <70000>;
+ hysteresis = <2000>;
+ type = "passive";
+ };
+ gpu_target: gpu-target {
+ temperature = <75000>;
+ hysteresis = <2000>;
+ type = "passive";
+ };
+ gpu_crit: gpu-crit {
+ temperature = <95000>;
+ hysteresis = <2000>;
+ type = "critical";
+ };
+ };
+
+ cooling-maps {
+ map0 {
+ trip = <&gpu_target>;
+ cooling-device =
+ <&gpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
};
};
@@ -1141,6 +1322,82 @@
status = "disabled";
};
+ combphy1: phy@fe830000 {
+ compatible = "rockchip,rk3568-naneng-combphy";
+ reg = <0x0 0xfe830000 0x0 0x100>;
+ clocks = <&pmucru CLK_PCIEPHY1_REF>,
+ <&cru PCLK_PIPEPHY1>,
+ <&cru PCLK_PIPE>;
+ clock-names = "ref", "apb", "pipe";
+ assigned-clocks = <&pmucru CLK_PCIEPHY1_REF>;
+ assigned-clock-rates = <100000000>;
+ resets = <&cru SRST_PIPEPHY1>;
+ rockchip,pipe-grf = <&pipegrf>;
+ rockchip,pipe-phy-grf = <&pipe_phy_grf1>;
+ #phy-cells = <1>;
+ status = "disabled";
+ };
+
+ combphy2: phy@fe840000 {
+ compatible = "rockchip,rk3568-naneng-combphy";
+ reg = <0x0 0xfe840000 0x0 0x100>;
+ clocks = <&pmucru CLK_PCIEPHY2_REF>,
+ <&cru PCLK_PIPEPHY2>,
+ <&cru PCLK_PIPE>;
+ clock-names = "ref", "apb", "pipe";
+ assigned-clocks = <&pmucru CLK_PCIEPHY2_REF>;
+ assigned-clock-rates = <100000000>;
+ resets = <&cru SRST_PIPEPHY2>;
+ rockchip,pipe-grf = <&pipegrf>;
+ rockchip,pipe-phy-grf = <&pipe_phy_grf2>;
+ #phy-cells = <1>;
+ status = "disabled";
+ };
+
+ usb2phy0: usb2phy@fe8a0000 {
+ compatible = "rockchip,rk3568-usb2phy";
+ reg = <0x0 0xfe8a0000 0x0 0x10000>;
+ clocks = <&pmucru CLK_USBPHY0_REF>;
+ clock-names = "phyclk";
+ clock-output-names = "clk_usbphy0_480m";
+ interrupts = <GIC_SPI 135 IRQ_TYPE_LEVEL_HIGH>;
+ rockchip,usbgrf = <&usb2phy0_grf>;
+ #clock-cells = <0>;
+ status = "disabled";
+
+ usb2phy0_host: host-port {
+ #phy-cells = <0>;
+ status = "disabled";
+ };
+
+ usb2phy0_otg: otg-port {
+ #phy-cells = <0>;
+ status = "disabled";
+ };
+ };
+
+ usb2phy1: usb2phy@fe8b0000 {
+ compatible = "rockchip,rk3568-usb2phy";
+ reg = <0x0 0xfe8b0000 0x0 0x10000>;
+ clocks = <&pmucru CLK_USBPHY1_REF>;
+ clock-names = "phyclk";
+ clock-output-names = "clk_usbphy1_480m";
+ interrupts = <GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>;
+ rockchip,usbgrf = <&usb2phy1_grf>;
+ #clock-cells = <0>;
+ status = "disabled";
+
+ usb2phy1_host: host-port {
+ #phy-cells = <0>;
+ status = "disabled";
+ };
+
+ usb2phy1_otg: otg-port {
+ #phy-cells = <0>;
+ status = "disabled";
+ };
+ };
+
pinctrl: pinctrl {
compatible = "rockchip,rk3568-pinctrl";
rockchip,grf = <&grf>;
diff --git a/arch/arm64/boot/dts/tesla/Makefile b/arch/arm64/boot/dts/tesla/Makefile
new file mode 100644
index 000000000000..a1ee50e2fd06
--- /dev/null
+++ b/arch/arm64/boot/dts/tesla/Makefile
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0
+dtb-$(CONFIG_ARCH_TESLA_FSD) += \
+ fsd-evb.dtb
diff --git a/arch/arm64/boot/dts/tesla/fsd-evb.dts b/arch/arm64/boot/dts/tesla/fsd-evb.dts
new file mode 100644
index 000000000000..5af560c1b5e6
--- /dev/null
+++ b/arch/arm64/boot/dts/tesla/fsd-evb.dts
@@ -0,0 +1,39 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+/*
+ * Tesla FSD board device tree source
+ *
+ * Copyright (c) 2017-2021 Samsung Electronics Co., Ltd.
+ * https://www.samsung.com
+ * Copyright (c) 2017-2021 Tesla, Inc.
+ * https://www.tesla.com
+ */
+
+/dts-v1/;
+#include "fsd.dtsi"
+
+/ {
+ model = "Tesla Full Self-Driving (FSD) Evaluation board";
+ compatible = "tesla,fsd-evb", "tesla,fsd";
+
+ aliases {
+ serial0 = &serial_0;
+ serial1 = &serial_1;
+ };
+
+ chosen {
+ stdout-path = &serial_0;
+ };
+
+ memory@80000000 {
+ device_type = "memory";
+ reg = <0x0 0x80000000 0x2 0x00000000>;
+ };
+};
+
+&fin_pll {
+ clock-frequency = <24000000>;
+};
+
+&serial_0 {
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/tesla/fsd-pinctrl.dtsi b/arch/arm64/boot/dts/tesla/fsd-pinctrl.dtsi
new file mode 100644
index 000000000000..d4d0cb005712
--- /dev/null
+++ b/arch/arm64/boot/dts/tesla/fsd-pinctrl.dtsi
@@ -0,0 +1,335 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Tesla Full Self-Driving SoC device tree source
+ *
+ * Copyright (c) 2017-2021 Samsung Electronics Co., Ltd.
+ * https://www.samsung.com
+ * Copyright (c) 2017-2021 Tesla, Inc.
+ * https://www.tesla.com
+ */
+
+#include <dt-bindings/pinctrl/samsung.h>
+
+&pinctrl_fsys0 {
+ gpf0: gpf0-gpio-bank {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpf1: gpf1-gpio-bank {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpf6: gpf6-gpio-bank {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpf4: gpf4-gpio-bank {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpf5: gpf5-gpio-bank {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+};
+
+&pinctrl_peric {
+ gpc8: gpc8-gpio-bank {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpf2: gpf2-gpio-bank {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpf3: gpf3-gpio-bank {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpd0: gpd0-gpio-bank {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpb0: gpb0-gpio-bank {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpb1: gpb1-gpio-bank {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpb4: gpb4-gpio-bank {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpb5: gpb5-gpio-bank {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpb6: gpb6-gpio-bank {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpb7: gpb7-gpio-bank {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpd1: gpd1-gpio-bank {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpd2: gpd2-gpio-bank {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpd3: gpd3-gpio-bank {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpg0: gpg0-gpio-bank {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpg1: gpg1-gpio-bank {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpg2: gpg2-gpio-bank {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpg3: gpg3-gpio-bank {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpg4: gpg4-gpio-bank {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpg5: gpg5-gpio-bank {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpg6: gpg6-gpio-bank {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpg7: gpg7-gpio-bank {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ pwm0_out: pwm0-out-pins {
+ samsung,pins = "gpb6-1";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+ samsung,pin-drv = <EXYNOS4_PIN_DRV_LV2>;
+ };
+
+ pwm1_out: pwm1-out-pins {
+ samsung,pins = "gpb6-5";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+ samsung,pin-drv = <EXYNOS4_PIN_DRV_LV2>;
+ };
+
+ hs_i2c0_bus: hs-i2c0-bus-pins {
+ samsung,pins = "gpb0-0", "gpb0-1";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+ samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+ };
+
+ hs_i2c1_bus: hs-i2c1-bus-pins {
+ samsung,pins = "gpb0-2", "gpb0-3";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+ samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+ };
+
+ hs_i2c2_bus: hs-i2c2-bus-pins {
+ samsung,pins = "gpb0-4", "gpb0-5";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+ samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+ };
+
+ hs_i2c3_bus: hs-i2c3-bus-pins {
+ samsung,pins = "gpb0-6", "gpb0-7";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+ samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+ };
+
+ hs_i2c4_bus: hs-i2c4-bus-pins {
+ samsung,pins = "gpb1-0", "gpb1-1";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+ samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+ };
+
+ hs_i2c5_bus: hs-i2c5-bus-pins {
+ samsung,pins = "gpb1-2", "gpb1-3";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+ samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+ };
+
+ hs_i2c6_bus: hs-i2c6-bus-pins {
+ samsung,pins = "gpb1-4", "gpb1-5";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+ samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+ };
+
+ hs_i2c7_bus: hs-i2c7-bus-pins {
+ samsung,pins = "gpb1-6", "gpb1-7";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+ samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+ };
+
+ uart0_data: uart0-data-pins {
+ samsung,pins = "gpb7-0", "gpb7-1";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+ samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+ };
+
+ uart1_data: uart1-data-pins {
+ samsung,pins = "gpb7-4", "gpb7-5";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+ samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+ };
+
+ spi0_bus: spi0-bus-pins {
+ samsung,pins = "gpb4-0", "gpb4-2", "gpb4-3";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+ samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+ };
+
+ spi1_bus: spi1-bus-pins {
+ samsung,pins = "gpb4-4", "gpb4-6", "gpb4-7";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+ samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+ };
+
+ spi2_bus: spi2-bus-pins {
+ samsung,pins = "gpb5-0", "gpb5-2", "gpb5-3";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+ samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+ };
+};
+
+&pinctrl_pmu {
+ gpq0: gpq0-gpio-bank {
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+};
diff --git a/arch/arm64/boot/dts/tesla/fsd.dtsi b/arch/arm64/boot/dts/tesla/fsd.dtsi
new file mode 100644
index 000000000000..9a652abcbcac
--- /dev/null
+++ b/arch/arm64/boot/dts/tesla/fsd.dtsi
@@ -0,0 +1,754 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Tesla Full Self-Driving SoC device tree source
+ *
+ * Copyright (c) 2017-2022 Samsung Electronics Co., Ltd.
+ * https://www.samsung.com
+ * Copyright (c) 2017-2022 Tesla, Inc.
+ * https://www.tesla.com
+ */
+
+#include <dt-bindings/clock/fsd-clk.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+/ {
+ compatible = "tesla,fsd";
+ interrupt-parent = <&gic>;
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ aliases {
+ i2c0 = &hsi2c_0;
+ i2c1 = &hsi2c_1;
+ i2c2 = &hsi2c_2;
+ i2c3 = &hsi2c_3;
+ i2c4 = &hsi2c_4;
+ i2c5 = &hsi2c_5;
+ i2c6 = &hsi2c_6;
+ i2c7 = &hsi2c_7;
+ pinctrl0 = &pinctrl_fsys0;
+ pinctrl1 = &pinctrl_peric;
+ pinctrl2 = &pinctrl_pmu;
+ spi0 = &spi_0;
+ spi1 = &spi_1;
+ spi2 = &spi_2;
+ };
+
+ cpus {
+ #address-cells = <2>;
+ #size-cells = <0>;
+
+ cpu-map {
+ cluster0 {
+ core0 {
+ cpu = <&cpucl0_0>;
+ };
+ core1 {
+ cpu = <&cpucl0_1>;
+ };
+ core2 {
+ cpu = <&cpucl0_2>;
+ };
+ core3 {
+ cpu = <&cpucl0_3>;
+ };
+ };
+
+ cluster1 {
+ core0 {
+ cpu = <&cpucl1_0>;
+ };
+ core1 {
+ cpu = <&cpucl1_1>;
+ };
+ core2 {
+ cpu = <&cpucl1_2>;
+ };
+ core3 {
+ cpu = <&cpucl1_3>;
+ };
+ };
+
+ cluster2 {
+ core0 {
+ cpu = <&cpucl2_0>;
+ };
+ core1 {
+ cpu = <&cpucl2_1>;
+ };
+ core2 {
+ cpu = <&cpucl2_2>;
+ };
+ core3 {
+ cpu = <&cpucl2_3>;
+ };
+ };
+ };
+
+ /* Cluster 0 */
+ cpucl0_0: cpu@0 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a72";
+ reg = <0x0 0x000>;
+ enable-method = "psci";
+ clock-frequency = <2400000000>;
+ cpu-idle-states = <&CPU_SLEEP>;
+ };
+
+ cpucl0_1: cpu@1 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a72";
+ reg = <0x0 0x001>;
+ enable-method = "psci";
+ clock-frequency = <2400000000>;
+ cpu-idle-states = <&CPU_SLEEP>;
+ };
+
+ cpucl0_2: cpu@2 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a72";
+ reg = <0x0 0x002>;
+ enable-method = "psci";
+ clock-frequency = <2400000000>;
+ cpu-idle-states = <&CPU_SLEEP>;
+ };
+
+ cpucl0_3: cpu@3 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a72";
+ reg = <0x0 0x003>;
+ enable-method = "psci";
+ cpu-idle-states = <&CPU_SLEEP>;
+ };
+
+ /* Cluster 1 */
+ cpucl1_0: cpu@100 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a72";
+ reg = <0x0 0x100>;
+ enable-method = "psci";
+ clock-frequency = <2400000000>;
+ cpu-idle-states = <&CPU_SLEEP>;
+ };
+
+ cpucl1_1: cpu@101 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a72";
+ reg = <0x0 0x101>;
+ enable-method = "psci";
+ clock-frequency = <2400000000>;
+ cpu-idle-states = <&CPU_SLEEP>;
+ };
+
+ cpucl1_2: cpu@102 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a72";
+ reg = <0x0 0x102>;
+ enable-method = "psci";
+ clock-frequency = <2400000000>;
+ cpu-idle-states = <&CPU_SLEEP>;
+ };
+
+ cpucl1_3: cpu@103 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a72";
+ reg = <0x0 0x103>;
+ enable-method = "psci";
+ clock-frequency = <2400000000>;
+ cpu-idle-states = <&CPU_SLEEP>;
+ };
+
+ /* Cluster 2 */
+ cpucl2_0: cpu@200 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a72";
+ reg = <0x0 0x200>;
+ enable-method = "psci";
+ clock-frequency = <2400000000>;
+ cpu-idle-states = <&CPU_SLEEP>;
+ };
+
+ cpucl2_1: cpu@201 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a72";
+ reg = <0x0 0x201>;
+ enable-method = "psci";
+ clock-frequency = <2400000000>;
+ cpu-idle-states = <&CPU_SLEEP>;
+ };
+
+ cpucl2_2: cpu@202 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a72";
+ reg = <0x0 0x202>;
+ enable-method = "psci";
+ clock-frequency = <2400000000>;
+ cpu-idle-states = <&CPU_SLEEP>;
+ };
+
+ cpucl2_3: cpu@203 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a72";
+ reg = <0x0 0x203>;
+ enable-method = "psci";
+ clock-frequency = <2400000000>;
+ cpu-idle-states = <&CPU_SLEEP>;
+ };
+
+ idle-states {
+ entry-method = "psci";
+
+ CPU_SLEEP: cpu-sleep {
+ idle-state-name = "c2";
+ compatible = "arm,idle-state";
+ local-timer-stop;
+ arm,psci-suspend-param = <0x0010000>;
+ entry-latency-us = <30>;
+ exit-latency-us = <75>;
+ min-residency-us = <300>;
+ };
+ };
+ };
+
+ arm-pmu {
+ compatible = "arm,armv8-pmuv3";
+ interrupts = <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>,
+ <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 384 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 385 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 386 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 387 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-affinity = <&cpucl0_0>, <&cpucl0_1>, <&cpucl0_2>,
+ <&cpucl0_3>, <&cpucl1_0>, <&cpucl1_1>,
+ <&cpucl1_2>, <&cpucl1_3>, <&cpucl2_0>,
+ <&cpucl2_1>, <&cpucl2_2>, <&cpucl2_3>;
+ };
+
+ psci {
+ compatible = "arm,psci-1.0";
+ method = "smc";
+ };
+
+ timer {
+ compatible = "arm,armv8-timer";
+ interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_LOW>,
+ <GIC_PPI 14 IRQ_TYPE_LEVEL_LOW>,
+ <GIC_PPI 11 IRQ_TYPE_LEVEL_LOW>,
+ <GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>;
+ };
+
+ fin_pll: clock {
+ compatible = "fixed-clock";
+ clock-output-names = "fin_pll";
+ #clock-cells = <0>;
+ };
+
+ soc: soc@0 {
+ compatible = "simple-bus";
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges = <0x0 0x0 0x0 0x0 0x0 0x18000000>;
+ dma-ranges = <0x0 0x0 0x0 0x0 0x10 0x0>;
+
+ gic: interrupt-controller@10400000 {
+ compatible = "arm,gic-v3";
+ #interrupt-cells = <3>;
+ interrupt-controller;
+ reg = <0x0 0x10400000 0x0 0x10000>, /* GICD */
+ <0x0 0x10600000 0x0 0x200000>; /* GICR_RD+GICR_SGI */
+ interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ smmu_imem: iommu@10200000 {
+ compatible = "arm,mmu-500";
+ reg = <0x0 0x10200000 0x0 0x10000>;
+ #iommu-cells = <2>;
+ #global-interrupts = <7>;
+ interrupts = <GIC_SPI 438 IRQ_TYPE_LEVEL_HIGH>, /* Global secure fault */
+ <GIC_SPI 439 IRQ_TYPE_LEVEL_HIGH>, /* Global non-secure fault */
+ <GIC_SPI 451 IRQ_TYPE_LEVEL_HIGH>, /* Combined secure interrupt */
+ <GIC_SPI 450 IRQ_TYPE_LEVEL_HIGH>, /* Combined non-secure interrupt */
+ /* Performance counter interrupts */
+ <GIC_SPI 441 IRQ_TYPE_LEVEL_HIGH>, /* for FSYS1_0 */
+ <GIC_SPI 442 IRQ_TYPE_LEVEL_HIGH>, /* for FSYS1_1 */
+ <GIC_SPI 443 IRQ_TYPE_LEVEL_HIGH>, /* for IMEM_0 */
+ /* Per context non-secure context interrupts, 0-3 interrupts */
+ <GIC_SPI 446 IRQ_TYPE_LEVEL_HIGH>, /* for CONTEXT_0 */
+ <GIC_SPI 447 IRQ_TYPE_LEVEL_HIGH>, /* for CONTEXT_1 */
+ <GIC_SPI 448 IRQ_TYPE_LEVEL_HIGH>, /* for CONTEXT_2 */
+ <GIC_SPI 449 IRQ_TYPE_LEVEL_HIGH>; /* for CONTEXT_3 */
+ };
+
+ smmu_isp: iommu@12100000 {
+ compatible = "arm,mmu-500";
+ reg = <0x0 0x12100000 0x0 0x10000>;
+ #iommu-cells = <2>;
+ #global-interrupts = <11>;
+ interrupts = <GIC_SPI 321 IRQ_TYPE_LEVEL_HIGH>, /* Global secure fault */
+ <GIC_SPI 322 IRQ_TYPE_LEVEL_HIGH>, /* Global non-secure fault */
+ <GIC_SPI 346 IRQ_TYPE_LEVEL_HIGH>, /* Combined secure interrupt */
+ <GIC_SPI 345 IRQ_TYPE_LEVEL_HIGH>, /* Combined non-secure interrupt */
+ /* Performance counter interrupts */
+ <GIC_SPI 323 IRQ_TYPE_LEVEL_HIGH>, /* for CAM_CSI */
+ <GIC_SPI 324 IRQ_TYPE_LEVEL_HIGH>, /* for CAM_DP_0 */
+ <GIC_SPI 325 IRQ_TYPE_LEVEL_HIGH>, /* for CAM_DP_1 */
+ <GIC_SPI 326 IRQ_TYPE_LEVEL_HIGH>, /* for CAM_ISP_0 */
+ <GIC_SPI 327 IRQ_TYPE_LEVEL_HIGH>, /* for CAM_ISP_1 */
+ <GIC_SPI 328 IRQ_TYPE_LEVEL_HIGH>, /* for CAM_MFC_0 */
+ <GIC_SPI 329 IRQ_TYPE_LEVEL_HIGH>, /* for CAM_MFC_1 */
+ /* Per context non-secure context interrupts, 0-7 interrupts */
+ <GIC_SPI 330 IRQ_TYPE_LEVEL_HIGH>, /* for CONTEXT_0 */
+ <GIC_SPI 331 IRQ_TYPE_LEVEL_HIGH>, /* for CONTEXT_1 */
+ <GIC_SPI 332 IRQ_TYPE_LEVEL_HIGH>, /* for CONTEXT_2 */
+ <GIC_SPI 333 IRQ_TYPE_LEVEL_HIGH>, /* for CONTEXT_3 */
+ <GIC_SPI 334 IRQ_TYPE_LEVEL_HIGH>, /* for CONTEXT_4 */
+ <GIC_SPI 335 IRQ_TYPE_LEVEL_HIGH>, /* for CONTEXT_5 */
+ <GIC_SPI 336 IRQ_TYPE_LEVEL_HIGH>, /* for CONTEXT_6 */
+ <GIC_SPI 337 IRQ_TYPE_LEVEL_HIGH>; /* for CONTEXT_7 */
+ };
+
+ smmu_peric: iommu@14900000 {
+ compatible = "arm,mmu-500";
+ reg = <0x0 0x14900000 0x0 0x10000>;
+ #iommu-cells = <2>;
+ #global-interrupts = <5>;
+ interrupts = <GIC_SPI 197 IRQ_TYPE_LEVEL_HIGH>, /* Global secure fault */
+ <GIC_SPI 196 IRQ_TYPE_LEVEL_HIGH>, /* Global non-secure fault */
+ <GIC_SPI 193 IRQ_TYPE_LEVEL_HIGH>, /* Combined secure interrupt */
+ <GIC_SPI 192 IRQ_TYPE_LEVEL_HIGH>, /* Combined non-secure interrupt */
+ /* Performance counter interrupts */
+ <GIC_SPI 198 IRQ_TYPE_LEVEL_HIGH>, /* for PERIC */
+ /* Per context non-secure context interrupts, 0-1 interrupts */
+ <GIC_SPI 194 IRQ_TYPE_LEVEL_HIGH>, /* for CONTEXT_0 */
+ <GIC_SPI 195 IRQ_TYPE_LEVEL_HIGH>; /* for CONTEXT_1 */
+ };
+
+ smmu_fsys0: iommu@15450000 {
+ compatible = "arm,mmu-500";
+ reg = <0x0 0x15450000 0x0 0x10000>;
+ #iommu-cells = <2>;
+ #global-interrupts = <5>;
+ interrupts = <GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>, /* Global secure fault */
+ <GIC_SPI 99 IRQ_TYPE_LEVEL_HIGH>, /* Global non-secure fault */
+ <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>, /* Combined secure interrupt */
+ <GIC_SPI 95 IRQ_TYPE_LEVEL_HIGH>, /* Combined non-secure interrupt */
+ /* Performance counter interrupts */
+ <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>, /* for FSYS0 */
+ /* Per context non-secure context interrupts, 0-1 interrupts */
+ <GIC_SPI 97 IRQ_TYPE_LEVEL_HIGH>, /* for CONTEXT_0 */
+ <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>; /* for CONTEXT_1 */
+ };
+
+ clock_imem: clock-controller@10010000 {
+ compatible = "tesla,fsd-clock-imem";
+ reg = <0x0 0x10010000 0x0 0x3000>;
+ #clock-cells = <1>;
+ clocks = <&fin_pll>,
+ <&clock_cmu DOUT_CMU_IMEM_TCUCLK>,
+ <&clock_cmu DOUT_CMU_IMEM_ACLK>,
+ <&clock_cmu DOUT_CMU_IMEM_DMACLK>;
+ clock-names = "fin_pll",
+ "dout_cmu_imem_tcuclk",
+ "dout_cmu_imem_aclk",
+ "dout_cmu_imem_dmaclk";
+ };
+
+ clock_cmu: clock-controller@11c10000 {
+ compatible = "tesla,fsd-clock-cmu";
+ reg = <0x0 0x11c10000 0x0 0x3000>;
+ #clock-cells = <1>;
+ clocks = <&fin_pll>;
+ clock-names = "fin_pll";
+ };
+
+ clock_csi: clock-controller@12610000 {
+ compatible = "tesla,fsd-clock-cam_csi";
+ reg = <0x0 0x12610000 0x0 0x3000>;
+ #clock-cells = <1>;
+ clocks = <&fin_pll>;
+ clock-names = "fin_pll";
+ };
+
+ clock_mfc: clock-controller@12810000 {
+ compatible = "tesla,fsd-clock-mfc";
+ reg = <0x0 0x12810000 0x0 0x3000>;
+ #clock-cells = <1>;
+ clocks = <&fin_pll>;
+ clock-names = "fin_pll";
+ };
+
+ clock_peric: clock-controller@14010000 {
+ compatible = "tesla,fsd-clock-peric";
+ reg = <0x0 0x14010000 0x0 0x3000>;
+ #clock-cells = <1>;
+ clocks = <&fin_pll>,
+ <&clock_cmu DOUT_CMU_PLL_SHARED0_DIV4>,
+ <&clock_cmu DOUT_CMU_PERIC_SHARED1DIV36>,
+ <&clock_cmu DOUT_CMU_PERIC_SHARED0DIV3_TBUCLK>,
+ <&clock_cmu DOUT_CMU_PERIC_SHARED0DIV20>,
+ <&clock_cmu DOUT_CMU_PERIC_SHARED1DIV4_DMACLK>;
+ clock-names = "fin_pll",
+ "dout_cmu_pll_shared0_div4",
+ "dout_cmu_peric_shared1div36",
+ "dout_cmu_peric_shared0div3_tbuclk",
+ "dout_cmu_peric_shared0div20",
+ "dout_cmu_peric_shared1div4_dmaclk";
+ };
+
+ clock_fsys0: clock-controller@15010000 {
+ compatible = "tesla,fsd-clock-fsys0";
+ reg = <0x0 0x15010000 0x0 0x3000>;
+ #clock-cells = <1>;
+ clocks = <&fin_pll>,
+ <&clock_cmu DOUT_CMU_PLL_SHARED0_DIV6>,
+ <&clock_cmu DOUT_CMU_FSYS0_SHARED1DIV4>,
+ <&clock_cmu DOUT_CMU_FSYS0_SHARED0DIV4>;
+ clock-names = "fin_pll",
+ "dout_cmu_pll_shared0_div6",
+ "dout_cmu_fsys0_shared1div4",
+ "dout_cmu_fsys0_shared0div4";
+ };
+
+ clock_fsys1: clock-controller@16810000 {
+ compatible = "tesla,fsd-clock-fsys1";
+ reg = <0x0 0x16810000 0x0 0x3000>;
+ #clock-cells = <1>;
+ clocks = <&fin_pll>,
+ <&clock_cmu DOUT_CMU_FSYS1_SHARED0DIV8>,
+ <&clock_cmu DOUT_CMU_FSYS1_SHARED0DIV4>;
+ clock-names = "fin_pll",
+ "dout_cmu_fsys1_shared0div8",
+ "dout_cmu_fsys1_shared0div4";
+ };
+
+ mdma0: dma-controller@10100000 {
+ compatible = "arm,pl330", "arm,primecell";
+ reg = <0x0 0x10100000 0x0 0x1000>;
+ interrupts = <GIC_SPI 424 IRQ_TYPE_LEVEL_HIGH>;
+ #dma-cells = <1>;
+ #dma-channels = <8>;
+ #dma-requests = <32>;
+ clocks = <&clock_imem IMEM_DMA0_IPCLKPORT_ACLK>;
+ clock-names = "apb_pclk";
+ iommus = <&smmu_imem 0x800 0x0>;
+ };
+
+ mdma1: dma-controller@10110000 {
+ compatible = "arm,pl330", "arm,primecell";
+ reg = <0x0 0x10110000 0x0 0x1000>;
+ interrupts = <GIC_SPI 425 IRQ_TYPE_LEVEL_HIGH>;
+ #dma-cells = <1>;
+ #dma-channels = <8>;
+ #dma-requests = <32>;
+ clocks = <&clock_imem IMEM_DMA1_IPCLKPORT_ACLK>;
+ clock-names = "apb_pclk";
+ iommus = <&smmu_imem 0x801 0x0>;
+ };
+
+ pdma0: dma-controller@14280000 {
+ compatible = "arm,pl330", "arm,primecell";
+ reg = <0x0 0x14280000 0x0 0x1000>;
+ interrupts = <GIC_SPI 190 IRQ_TYPE_LEVEL_HIGH>;
+ #dma-cells = <1>;
+ #dma-channels = <8>;
+ #dma-requests = <32>;
+ clocks = <&clock_peric PERIC_DMA0_IPCLKPORT_ACLK>;
+ clock-names = "apb_pclk";
+ iommus = <&smmu_peric 0x2 0x0>;
+ };
+
+ pdma1: dma-controller@14290000 {
+ compatible = "arm,pl330", "arm,primecell";
+ reg = <0x0 0x14290000 0x0 0x1000>;
+ interrupts = <GIC_SPI 191 IRQ_TYPE_LEVEL_HIGH>;
+ #dma-cells = <1>;
+ #dma-channels = <8>;
+ #dma-requests = <32>;
+ clocks = <&clock_peric PERIC_DMA1_IPCLKPORT_ACLK>;
+ clock-names = "apb_pclk";
+ iommus = <&smmu_peric 0x1 0x0>;
+ };
+
+ serial_0: serial@14180000 {
+ compatible = "samsung,exynos4210-uart";
+ reg = <0x0 0x14180000 0x0 0x100>;
+ interrupts = <GIC_SPI 171 IRQ_TYPE_LEVEL_HIGH>;
+ dmas = <&pdma1 1>, <&pdma1 0>;
+ dma-names = "rx", "tx";
+ clocks = <&clock_peric PERIC_PCLK_UART0>,
+ <&clock_peric PERIC_SCLK_UART0>;
+ clock-names = "uart", "clk_uart_baud0";
+ status = "disabled";
+ };
+
+ serial_1: serial@14190000 {
+ compatible = "samsung,exynos4210-uart";
+ reg = <0x0 0x14190000 0x0 0x100>;
+ interrupts = <GIC_SPI 172 IRQ_TYPE_LEVEL_HIGH>;
+ dmas = <&pdma1 3>, <&pdma1 2>;
+ dma-names = "rx", "tx";
+ clocks = <&clock_peric PERIC_PCLK_UART1>,
+ <&clock_peric PERIC_SCLK_UART1>;
+ clock-names = "uart", "clk_uart_baud0";
+ status = "disabled";
+ };
+
+ pmu_system_controller: system-controller@11400000 {
+ compatible = "samsung,exynos7-pmu", "syscon";
+ reg = <0x0 0x11400000 0x0 0x5000>;
+ };
+
+ watchdog_0: watchdog@100a0000 {
+ compatible = "samsung,exynos7-wdt";
+ reg = <0x0 0x100a0000 0x0 0x100>;
+ interrupts = <GIC_SPI 471 IRQ_TYPE_LEVEL_HIGH>;
+ samsung,syscon-phandle = <&pmu_system_controller>;
+ clocks = <&fin_pll>;
+ clock-names = "watchdog";
+ };
+
+ watchdog_1: watchdog@100b0000 {
+ compatible = "samsung,exynos7-wdt";
+ reg = <0x0 0x100b0000 0x0 0x100>;
+ interrupts = <GIC_SPI 472 IRQ_TYPE_LEVEL_HIGH>;
+ samsung,syscon-phandle = <&pmu_system_controller>;
+ clocks = <&fin_pll>;
+ clock-names = "watchdog";
+ };
+
+ watchdog_2: watchdog@100c0000 {
+ compatible = "samsung,exynos7-wdt";
+ reg = <0x0 0x100c0000 0x0 0x100>;
+ interrupts = <GIC_SPI 473 IRQ_TYPE_LEVEL_HIGH>;
+ samsung,syscon-phandle = <&pmu_system_controller>;
+ clocks = <&fin_pll>;
+ clock-names = "watchdog";
+ };
+
+ pwm_0: pwm@14100000 {
+ compatible = "samsung,exynos4210-pwm";
+ reg = <0x0 0x14100000 0x0 0x100>;
+ samsung,pwm-outputs = <0>, <1>, <2>, <3>;
+ #pwm-cells = <3>;
+ clocks = <&clock_peric PERIC_PWM0_IPCLKPORT_I_PCLK_S0>;
+ clock-names = "timers";
+ status = "disabled";
+ };
+
+ pwm_1: pwm@14110000 {
+ compatible = "samsung,exynos4210-pwm";
+ reg = <0x0 0x14110000 0x0 0x100>;
+ samsung,pwm-outputs = <0>, <1>, <2>, <3>;
+ #pwm-cells = <3>;
+ clocks = <&clock_peric PERIC_PWM1_IPCLKPORT_I_PCLK_S0>;
+ clock-names = "timers";
+ status = "disabled";
+ };
+
+ hsi2c_0: i2c@14200000 {
+ compatible = "samsung,exynos7-hsi2c";
+ reg = <0x0 0x14200000 0x0 0x1000>;
+ interrupts = <GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&hs_i2c0_bus>;
+ clocks = <&clock_peric PERIC_PCLK_HSI2C0>;
+ clock-names = "hsi2c";
+ status = "disabled";
+ };
+
+ hsi2c_1: i2c@14210000 {
+ compatible = "samsung,exynos7-hsi2c";
+ reg = <0x0 0x14210000 0x0 0x1000>;
+ interrupts = <GIC_SPI 149 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&hs_i2c1_bus>;
+ clocks = <&clock_peric PERIC_PCLK_HSI2C1>;
+ clock-names = "hsi2c";
+ status = "disabled";
+ };
+
+ hsi2c_2: i2c@14220000 {
+ compatible = "samsung,exynos7-hsi2c";
+ reg = <0x0 0x14220000 0x0 0x1000>;
+ interrupts = <GIC_SPI 150 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&hs_i2c2_bus>;
+ clocks = <&clock_peric PERIC_PCLK_HSI2C2>;
+ clock-names = "hsi2c";
+ status = "disabled";
+ };
+
+ hsi2c_3: i2c@14230000 {
+ compatible = "samsung,exynos7-hsi2c";
+ reg = <0x0 0x14230000 0x0 0x1000>;
+ interrupts = <GIC_SPI 151 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&hs_i2c3_bus>;
+ clocks = <&clock_peric PERIC_PCLK_HSI2C3>;
+ clock-names = "hsi2c";
+ status = "disabled";
+ };
+
+ hsi2c_4: i2c@14240000 {
+ compatible = "samsung,exynos7-hsi2c";
+ reg = <0x0 0x14240000 0x0 0x1000>;
+ interrupts = <GIC_SPI 152 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&hs_i2c4_bus>;
+ clocks = <&clock_peric PERIC_PCLK_HSI2C4>;
+ clock-names = "hsi2c";
+ status = "disabled";
+ };
+
+ hsi2c_5: i2c@14250000 {
+ compatible = "samsung,exynos7-hsi2c";
+ reg = <0x0 0x14250000 0x0 0x1000>;
+ interrupts = <GIC_SPI 153 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&hs_i2c5_bus>;
+ clocks = <&clock_peric PERIC_PCLK_HSI2C5>;
+ clock-names = "hsi2c";
+ status = "disabled";
+ };
+
+ hsi2c_6: i2c@14260000 {
+ compatible = "samsung,exynos7-hsi2c";
+ reg = <0x0 0x14260000 0x0 0x1000>;
+ interrupts = <GIC_SPI 154 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&hs_i2c6_bus>;
+ clocks = <&clock_peric PERIC_PCLK_HSI2C6>;
+ clock-names = "hsi2c";
+ status = "disabled";
+ };
+
+ hsi2c_7: i2c@14270000 {
+ compatible = "samsung,exynos7-hsi2c";
+ reg = <0x0 0x14270000 0x0 0x1000>;
+ interrupts = <GIC_SPI 155 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&hs_i2c7_bus>;
+ clocks = <&clock_peric PERIC_PCLK_HSI2C7>;
+ clock-names = "hsi2c";
+ status = "disabled";
+ };
+
+ pinctrl_pmu: pinctrl@114f0000 {
+ compatible = "tesla,fsd-pinctrl";
+ reg = <0x0 0x114f0000 0x0 0x1000>;
+ };
+
+ pinctrl_peric: pinctrl@141f0000 {
+ compatible = "tesla,fsd-pinctrl";
+ reg = <0x0 0x141f0000 0x0 0x1000>;
+ interrupts = <GIC_SPI 189 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ pinctrl_fsys0: pinctrl@15020000 {
+ compatible = "tesla,fsd-pinctrl";
+ reg = <0x0 0x15020000 0x0 0x1000>;
+ interrupts = <GIC_SPI 79 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ spi_0: spi@14140000 {
+ compatible = "tesla,fsd-spi";
+ reg = <0x0 0x14140000 0x0 0x100>;
+ interrupts = <GIC_SPI 156 IRQ_TYPE_LEVEL_HIGH>;
+ dmas = <&pdma1 4>, <&pdma1 5>;
+ dma-names = "tx", "rx";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&clock_peric PERIC_PCLK_SPI0>,
+ <&clock_peric PERIC_SCLK_SPI0>;
+ clock-names = "spi", "spi_busclk0";
+ samsung,spi-src-clk = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi0_bus>;
+ num-cs = <1>;
+ status = "disabled";
+ };
+
+ spi_1: spi@14150000 {
+ compatible = "tesla,fsd-spi";
+ reg = <0x0 0x14150000 0x0 0x100>;
+ interrupts = <GIC_SPI 157 IRQ_TYPE_LEVEL_HIGH>;
+ dmas = <&pdma1 6>, <&pdma1 7>;
+ dma-names = "tx", "rx";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&clock_peric PERIC_PCLK_SPI1>,
+ <&clock_peric PERIC_SCLK_SPI1>;
+ clock-names = "spi", "spi_busclk0";
+ samsung,spi-src-clk = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi1_bus>;
+ num-cs = <1>;
+ status = "disabled";
+ };
+
+ spi_2: spi@14160000 {
+ compatible = "tesla,fsd-spi";
+ reg = <0x0 0x14160000 0x0 0x100>;
+ interrupts = <GIC_SPI 158 IRQ_TYPE_LEVEL_HIGH>;
+ dmas = <&pdma1 8>, <&pdma1 9>;
+ dma-names = "tx", "rx";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&clock_peric PERIC_PCLK_SPI2>,
+ <&clock_peric PERIC_SCLK_SPI2>;
+ clock-names = "spi", "spi_busclk0";
+ samsung,spi-src-clk = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi2_bus>;
+ num-cs = <1>;
+ status = "disabled";
+ };
+
+ timer@10040000 {
+ compatible = "samsung,exynos4210-mct";
+ reg = <0x0 0x10040000 0x0 0x800>;
+ interrupts = <GIC_SPI 455 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 456 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 457 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 458 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 459 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 460 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 461 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 462 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 463 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 470 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&fin_pll>, <&clock_imem IMEM_MCT_PCLK>;
+ clock-names = "fin_pll", "mct";
+ };
+ };
+};
+
+#include "fsd-pinctrl.dtsi"
diff --git a/arch/arm64/boot/dts/ti/Makefile b/arch/arm64/boot/dts/ti/Makefile
index 90be511bc4d0..02e5d80344d0 100644
--- a/arch/arm64/boot/dts/ti/Makefile
+++ b/arch/arm64/boot/dts/ti/Makefile
@@ -21,3 +21,5 @@ dtb-$(CONFIG_ARCH_K3) += k3-j721s2-common-proc-board.dtb
dtb-$(CONFIG_ARCH_K3) += k3-am642-evm.dtb
dtb-$(CONFIG_ARCH_K3) += k3-am642-sk.dtb
+
+dtb-$(CONFIG_ARCH_K3) += k3-am625-sk.dtb
diff --git a/arch/arm64/boot/dts/ti/k3-am62-main.dtsi b/arch/arm64/boot/dts/ti/k3-am62-main.dtsi
new file mode 100644
index 000000000000..c68472c692f4
--- /dev/null
+++ b/arch/arm64/boot/dts/ti/k3-am62-main.dtsi
@@ -0,0 +1,267 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Device Tree Source for AM625 SoC Family Main Domain peripherals
+ *
+ * Copyright (C) 2020-2022 Texas Instruments Incorporated - https://www.ti.com/
+ */
+
+&cbass_main {
+ gic500: interrupt-controller@1800000 {
+ compatible = "arm,gic-v3";
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+ #interrupt-cells = <3>;
+ interrupt-controller;
+ reg = <0x00 0x01800000 0x00 0x10000>, /* GICD */
+ <0x00 0x01880000 0x00 0xc0000>, /* GICR */
+ <0x00 0x01880000 0x00 0xc0000>, /* GICR */
+ <0x01 0x00000000 0x00 0x2000>, /* GICC */
+ <0x01 0x00010000 0x00 0x1000>, /* GICH */
+ <0x01 0x00020000 0x00 0x2000>; /* GICV */
+ /*
+ * vcpumntirq:
+ * virtual CPU interface maintenance interrupt
+ */
+ interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>;
+
+ gic_its: msi-controller@1820000 {
+ compatible = "arm,gic-v3-its";
+ reg = <0x00 0x01820000 0x00 0x10000>;
+ socionext,synquacer-pre-its = <0x1000000 0x400000>;
+ msi-controller;
+ #msi-cells = <1>;
+ };
+ };
+
+ main_conf: syscon@100000 {
+ compatible = "syscon", "simple-mfd";
+ reg = <0x00 0x00100000 0x00 0x20000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0x0 0x00 0x00100000 0x20000>;
+ };
+
+ dmss: bus@48000000 {
+ compatible = "simple-mfd";
+ #address-cells = <2>;
+ #size-cells = <2>;
+ dma-ranges;
+ ranges = <0x00 0x48000000 0x00 0x48000000 0x00 0x06400000>;
+
+ ti,sci-dev-id = <25>;
+
+ secure_proxy_main: mailbox@4d000000 {
+ compatible = "ti,am654-secure-proxy";
+ #mbox-cells = <1>;
+ reg-names = "target_data", "rt", "scfg";
+ reg = <0x00 0x4d000000 0x00 0x80000>,
+ <0x00 0x4a600000 0x00 0x80000>,
+ <0x00 0x4a400000 0x00 0x80000>;
+ interrupt-names = "rx_012";
+ interrupts = <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>;
+ };
+ };
+
+ dmsc: system-controller@44043000 {
+ compatible = "ti,k2g-sci";
+ ti,host-id = <12>;
+ mbox-names = "rx", "tx";
+ mboxes= <&secure_proxy_main 12>,
+ <&secure_proxy_main 13>;
+ reg-names = "debug_messages";
+ reg = <0x00 0x44043000 0x00 0xfe0>;
+
+ k3_pds: power-controller {
+ compatible = "ti,sci-pm-domain";
+ #power-domain-cells = <2>;
+ };
+
+ k3_clks: clock-controller {
+ compatible = "ti,k2g-sci-clk";
+ #clock-cells = <2>;
+ };
+
+ k3_reset: reset-controller {
+ compatible = "ti,sci-reset";
+ #reset-cells = <2>;
+ };
+ };
+
+ main_pmx0: pinctrl@f4000 {
+ compatible = "pinctrl-single";
+ reg = <0x00 0xf4000 0x00 0x2ac>;
+ #pinctrl-cells = <1>;
+ pinctrl-single,register-width = <32>;
+ pinctrl-single,function-mask = <0xffffffff>;
+ };
+
+ main_uart0: serial@2800000 {
+ compatible = "ti,am64-uart", "ti,am654-uart";
+ reg = <0x00 0x02800000 0x00 0x100>;
+ interrupts = <GIC_SPI 178 IRQ_TYPE_LEVEL_HIGH>;
+ power-domains = <&k3_pds 146 TI_SCI_PD_EXCLUSIVE>;
+ clocks = <&k3_clks 146 0>;
+ clock-names = "fclk";
+ };
+
+ main_uart1: serial@2810000 {
+ compatible = "ti,am64-uart", "ti,am654-uart";
+ reg = <0x00 0x02810000 0x00 0x100>;
+ interrupts = <GIC_SPI 179 IRQ_TYPE_LEVEL_HIGH>;
+ power-domains = <&k3_pds 152 TI_SCI_PD_EXCLUSIVE>;
+ clocks = <&k3_clks 152 0>;
+ clock-names = "fclk";
+ };
+
+ main_uart2: serial@2820000 {
+ compatible = "ti,am64-uart", "ti,am654-uart";
+ reg = <0x00 0x02820000 0x00 0x100>;
+ interrupts = <GIC_SPI 180 IRQ_TYPE_LEVEL_HIGH>;
+ power-domains = <&k3_pds 153 TI_SCI_PD_EXCLUSIVE>;
+ clocks = <&k3_clks 153 0>;
+ clock-names = "fclk";
+ };
+
+ main_uart3: serial@2830000 {
+ compatible = "ti,am64-uart", "ti,am654-uart";
+ reg = <0x00 0x02830000 0x00 0x100>;
+ interrupts = <GIC_SPI 181 IRQ_TYPE_LEVEL_HIGH>;
+ power-domains = <&k3_pds 154 TI_SCI_PD_EXCLUSIVE>;
+ clocks = <&k3_clks 154 0>;
+ clock-names = "fclk";
+ };
+
+ main_uart4: serial@2840000 {
+ compatible = "ti,am64-uart", "ti,am654-uart";
+ reg = <0x00 0x02840000 0x00 0x100>;
+ interrupts = <GIC_SPI 182 IRQ_TYPE_LEVEL_HIGH>;
+ power-domains = <&k3_pds 155 TI_SCI_PD_EXCLUSIVE>;
+ clocks = <&k3_clks 155 0>;
+ clock-names = "fclk";
+ };
+
+ main_uart5: serial@2850000 {
+ compatible = "ti,am64-uart", "ti,am654-uart";
+ reg = <0x00 0x02850000 0x00 0x100>;
+ interrupts = <GIC_SPI 183 IRQ_TYPE_LEVEL_HIGH>;
+ power-domains = <&k3_pds 156 TI_SCI_PD_EXCLUSIVE>;
+ clocks = <&k3_clks 156 0>;
+ clock-names = "fclk";
+ };
+
+ main_uart6: serial@2860000 {
+ compatible = "ti,am64-uart", "ti,am654-uart";
+ reg = <0x00 0x02860000 0x00 0x100>;
+ interrupts = <GIC_SPI 184 IRQ_TYPE_LEVEL_HIGH>;
+ power-domains = <&k3_pds 158 TI_SCI_PD_EXCLUSIVE>;
+ clocks = <&k3_clks 158 0>;
+ clock-names = "fclk";
+ };
+
+ main_i2c0: i2c@20000000 {
+ compatible = "ti,am64-i2c", "ti,omap4-i2c";
+ reg = <0x00 0x20000000 0x00 0x100>;
+ interrupts = <GIC_SPI 161 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ power-domains = <&k3_pds 102 TI_SCI_PD_EXCLUSIVE>;
+ clocks = <&k3_clks 102 2>;
+ clock-names = "fck";
+ };
+
+ main_i2c1: i2c@20010000 {
+ compatible = "ti,am64-i2c", "ti,omap4-i2c";
+ reg = <0x00 0x20010000 0x00 0x100>;
+ interrupts = <GIC_SPI 162 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ power-domains = <&k3_pds 103 TI_SCI_PD_EXCLUSIVE>;
+ clocks = <&k3_clks 103 2>;
+ clock-names = "fck";
+ };
+
+ main_i2c2: i2c@20020000 {
+ compatible = "ti,am64-i2c", "ti,omap4-i2c";
+ reg = <0x00 0x20020000 0x00 0x100>;
+ interrupts = <GIC_SPI 163 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ power-domains = <&k3_pds 104 TI_SCI_PD_EXCLUSIVE>;
+ clocks = <&k3_clks 104 2>;
+ clock-names = "fck";
+ };
+
+ main_i2c3: i2c@20030000 {
+ compatible = "ti,am64-i2c", "ti,omap4-i2c";
+ reg = <0x00 0x20030000 0x00 0x100>;
+ interrupts = <GIC_SPI 164 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ power-domains = <&k3_pds 105 TI_SCI_PD_EXCLUSIVE>;
+ clocks = <&k3_clks 105 2>;
+ clock-names = "fck";
+ };
+
+ main_gpio_intr: interrupt-controller@a00000 {
+ compatible = "ti,sci-intr";
+ reg = <0x00 0x00a00000 0x00 0x800>;
+ ti,intr-trigger-type = <1>;
+ interrupt-controller;
+ interrupt-parent = <&gic500>;
+ #interrupt-cells = <1>;
+ ti,sci = <&dmsc>;
+ ti,sci-dev-id = <3>;
+ ti,interrupt-ranges = <0 32 16>;
+ };
+
+ main_gpio0: gpio@600000 {
+ compatible = "ti,am64-gpio", "ti,keystone-gpio";
+ reg = <0x0 0x00600000 0x0 0x100>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-parent = <&main_gpio_intr>;
+ interrupts = <190>, <191>, <192>,
+ <193>, <194>, <195>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ ti,ngpio = <87>;
+ ti,davinci-gpio-unbanked = <0>;
+ power-domains = <&k3_pds 77 TI_SCI_PD_EXCLUSIVE>;
+ clocks = <&k3_clks 77 0>;
+ clock-names = "gpio";
+ };
+
+ main_gpio1: gpio@601000 {
+ compatible = "ti,am64-gpio", "ti,keystone-gpio";
+ reg = <0x0 0x00601000 0x0 0x100>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-parent = <&main_gpio_intr>;
+ interrupts = <180>, <181>, <182>,
+ <183>, <184>, <185>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ ti,ngpio = <88>;
+ ti,davinci-gpio-unbanked = <0>;
+ power-domains = <&k3_pds 78 TI_SCI_PD_EXCLUSIVE>;
+ clocks = <&k3_clks 78 0>;
+ clock-names = "gpio";
+ };
+
+ hwspinlock: spinlock@2a000000 {
+ compatible = "ti,am64-hwspinlock";
+ reg = <0x00 0x2a000000 0x00 0x1000>;
+ #hwlock-cells = <1>;
+ };
+
+ mailbox0_cluster0: mailbox@29000000 {
+ compatible = "ti,am64-mailbox";
+ reg = <0x00 0x29000000 0x00 0x200>;
+ interrupts = <GIC_SPI 76 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>;
+ #mbox-cells = <1>;
+ ti,mbox-num-users = <4>;
+ ti,mbox-num-fifos = <16>;
+ };
+};
diff --git a/arch/arm64/boot/dts/ti/k3-am62-mcu.dtsi b/arch/arm64/boot/dts/ti/k3-am62-mcu.dtsi
new file mode 100644
index 000000000000..9d210d55fc71
--- /dev/null
+++ b/arch/arm64/boot/dts/ti/k3-am62-mcu.dtsi
@@ -0,0 +1,36 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Device Tree Source for AM625 SoC Family MCU Domain peripherals
+ *
+ * Copyright (C) 2020-2022 Texas Instruments Incorporated - https://www.ti.com/
+ */
+
+&cbass_mcu {
+ mcu_pmx0: pinctrl@4084000 {
+ compatible = "pinctrl-single";
+ reg = <0x00 0x04084000 0x00 0x88>;
+ #pinctrl-cells = <1>;
+ pinctrl-single,register-width = <32>;
+ pinctrl-single,function-mask = <0xffffffff>;
+ };
+
+ mcu_uart0: serial@4a00000 {
+ compatible = "ti,am64-uart", "ti,am654-uart";
+ reg = <0x00 0x04a00000 0x00 0x100>;
+ interrupts = <GIC_SPI 185 IRQ_TYPE_LEVEL_HIGH>;
+ power-domains = <&k3_pds 149 TI_SCI_PD_EXCLUSIVE>;
+ clocks = <&k3_clks 149 0>;
+ clock-names = "fclk";
+ };
+
+ mcu_i2c0: i2c@4900000 {
+ compatible = "ti,am64-i2c", "ti,omap4-i2c";
+ reg = <0x00 0x04900000 0x00 0x100>;
+ interrupts = <GIC_SPI 107 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ power-domains = <&k3_pds 106 TI_SCI_PD_EXCLUSIVE>;
+ clocks = <&k3_clks 106 2>;
+ clock-names = "fck";
+ };
+};
diff --git a/arch/arm64/boot/dts/ti/k3-am62-wakeup.dtsi b/arch/arm64/boot/dts/ti/k3-am62-wakeup.dtsi
new file mode 100644
index 000000000000..4090134676cf
--- /dev/null
+++ b/arch/arm64/boot/dts/ti/k3-am62-wakeup.dtsi
@@ -0,0 +1,41 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Device Tree Source for AM625 SoC Family Wakeup Domain peripherals
+ *
+ * Copyright (C) 2020-2022 Texas Instruments Incorporated - https://www.ti.com/
+ */
+
+&cbass_wakeup {
+ wkup_conf: syscon@43000000 {
+ compatible = "syscon", "simple-mfd";
+ reg = <0x00 0x43000000 0x00 0x20000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0x0 0x00 0x43000000 0x20000>;
+
+ chipid: chipid@14 {
+ compatible = "ti,am654-chipid";
+ reg = <0x14 0x4>;
+ };
+ };
+
+ wkup_uart0: serial@2b300000 {
+ compatible = "ti,am64-uart", "ti,am654-uart";
+ reg = <0x00 0x2b300000 0x00 0x100>;
+ interrupts = <GIC_SPI 186 IRQ_TYPE_LEVEL_HIGH>;
+ power-domains = <&k3_pds 114 TI_SCI_PD_EXCLUSIVE>;
+ clocks = <&k3_clks 114 0>;
+ clock-names = "fclk";
+ };
+
+ wkup_i2c0: i2c@2b200000 {
+ compatible = "ti,am64-i2c", "ti,omap4-i2c";
+ reg = <0x00 0x02b200000 0x00 0x100>;
+ interrupts = <GIC_SPI 165 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ power-domains = <&k3_pds 107 TI_SCI_PD_EXCLUSIVE>;
+ clocks = <&k3_clks 107 4>;
+ clock-names = "fck";
+ };
+};
diff --git a/arch/arm64/boot/dts/ti/k3-am62.dtsi b/arch/arm64/boot/dts/ti/k3-am62.dtsi
new file mode 100644
index 000000000000..bc2997b18556
--- /dev/null
+++ b/arch/arm64/boot/dts/ti/k3-am62.dtsi
@@ -0,0 +1,105 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Device Tree Source for AM62 SoC Family
+ *
+ * Copyright (C) 2020-2022 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/pinctrl/k3.h>
+#include <dt-bindings/soc/ti,sci_pm_domain.h>
+
+/ {
+ model = "Texas Instruments K3 AM625 SoC";
+ compatible = "ti,am625";
+ interrupt-parent = <&gic500>;
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ chosen { };
+
+ firmware {
+ optee {
+ compatible = "linaro,optee-tz";
+ method = "smc";
+ };
+
+ psci: psci {
+ compatible = "arm,psci-1.0";
+ method = "smc";
+ };
+ };
+
+ a53_timer0: timer-cl0-cpu0 {
+ compatible = "arm,armv8-timer";
+ interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_LOW>, /* cntpsirq */
+ <GIC_PPI 14 IRQ_TYPE_LEVEL_LOW>, /* cntpnsirq */
+ <GIC_PPI 11 IRQ_TYPE_LEVEL_LOW>, /* cntvirq */
+ <GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>; /* cnthpirq */
+ };
+
+ pmu: pmu {
+ compatible = "arm,cortex-a53-pmu";
+ interrupts = <GIC_PPI 7 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ cbass_main: bus@f0000 {
+ compatible = "simple-bus";
+ #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 0x0e000000 0x00 0x0e000000 0x00 0x01d20000>, /* Second peripheral window */
+ <0x00 0x0fd00000 0x00 0x0fd00000 0x00 0x00020000>, /* GPU */
+ <0x00 0x20000000 0x00 0x20000000 0x00 0x0a008000>, /* Third peripheral window */
+ <0x00 0x30040000 0x00 0x30040000 0x00 0x00080000>, /* PRUSS-M */
+ <0x00 0x30101000 0x00 0x30101000 0x00 0x00010100>, /* CSI window */
+ <0x00 0x30200000 0x00 0x30200000 0x00 0x00010000>, /* DSS */
+ <0x00 0x31000000 0x00 0x31000000 0x00 0x00050000>, /* USB0 DWC3 Core window */
+ <0x00 0x31100000 0x00 0x31100000 0x00 0x00050000>, /* USB1 DWC3 Core window */
+ <0x00 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 0x60000000 0x00 0x60000000 0x00 0x08000000>, /* FSS0 DAT1 */
+ <0x00 0x70000000 0x00 0x70000000 0x00 0x00010000>, /* OCSRAM */
+ <0x01 0x00000000 0x01 0x00000000 0x00 0x00310000>, /* A53 PERIPHBASE */
+ <0x05 0x00000000 0x05 0x00000000 0x01 0x00000000>, /* FSS0 DAT3 */
+
+ /* MCU Domain Range */
+ <0x00 0x04000000 0x00 0x04000000 0x00 0x01ff1400>,
+
+ /* Wakeup Domain Range */
+ <0x00 0x2b000000 0x00 0x2b000000 0x00 0x00300400>,
+ <0x00 0x43000000 0x00 0x43000000 0x00 0x00020000>;
+
+ cbass_mcu: bus@4000000 {
+ compatible = "simple-bus";
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges = <0x00 0x04000000 0x00 0x04000000 0x00 0x01ff1400>; /* Peripheral window */
+ };
+
+ cbass_wakeup: bus@2b000000 {
+ compatible = "simple-bus";
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges = <0x00 0x2b000000 0x00 0x2b000000 0x00 0x00300400>, /* Peripheral Window */
+ <0x00 0x43000000 0x00 0x43000000 0x00 0x00020000>;
+ };
+ };
+};
+
+/* Now include the peripherals for each bus segments */
+#include "k3-am62-main.dtsi"
+#include "k3-am62-mcu.dtsi"
+#include "k3-am62-wakeup.dtsi"
diff --git a/arch/arm64/boot/dts/ti/k3-am625-sk.dts b/arch/arm64/boot/dts/ti/k3-am625-sk.dts
new file mode 100644
index 000000000000..0de4113ccd5d
--- /dev/null
+++ b/arch/arm64/boot/dts/ti/k3-am625-sk.dts
@@ -0,0 +1,206 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * AM625 SK: https://www.ti.com/lit/zip/sprr448
+ *
+ * Copyright (C) 2021-2022 Texas Instruments Incorporated - https://www.ti.com/
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/leds/common.h>
+#include <dt-bindings/gpio/gpio.h>
+#include "k3-am625.dtsi"
+
+/ {
+ compatible = "ti,am625-sk", "ti,am625";
+ model = "Texas Instruments AM625 SK";
+
+ aliases {
+ serial2 = &main_uart0;
+ };
+
+ chosen {
+ stdout-path = "serial2:115200n8";
+ bootargs = "console=ttyS2,115200n8 earlycon=ns16550a,mmio32,0x02800000";
+ };
+
+ memory@80000000 {
+ device_type = "memory";
+ /* 2G RAM */
+ reg = <0x00000000 0x80000000 0x00000000 0x80000000>;
+
+ };
+
+ reserved-memory {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ secure_tfa_ddr: tfa@9e780000 {
+ reg = <0x00 0x9e780000 0x00 0x80000>;
+ alignment = <0x1000>;
+ no-map;
+ };
+
+ secure_ddr: optee@9e800000 {
+ reg = <0x00 0x9e800000 0x00 0x01800000>; /* for OP-TEE */
+ alignment = <0x1000>;
+ no-map;
+ };
+
+ wkup_r5fss0_core0_dma_memory_region: r5f-dma-memory@9db00000 {
+ compatible = "shared-dma-pool";
+ reg = <0x00 0x9db00000 0x00 0xc00000>;
+ 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;
+ };
+
+ vcc_5v0: regulator-1 {
+ /* Output of LM34936 */
+ compatible = "regulator-fixed";
+ regulator-name = "vcc_5v0";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ vin-supply = <&vmain_pd>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ vcc_3v3_sys: regulator-2 {
+ /* output of LM61460-Q1 */
+ compatible = "regulator-fixed";
+ regulator-name = "vcc_3v3_sys";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ vin-supply = <&vmain_pd>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ pinctrl-names = "default";
+ pinctrl-0 = <&usr_led_pins_default>;
+
+ led-0 {
+ label = "am62-sk:green:heartbeat";
+ gpios = <&main_gpio1 49 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "heartbeat";
+ function = LED_FUNCTION_HEARTBEAT;
+ default-state = "off";
+ };
+ };
+};
+
+&main_pmx0 {
+ main_uart0_pins_default: main-uart0-pins-default {
+ pinctrl-single,pins = <
+ AM62X_IOPAD(0x1c8, PIN_INPUT, 0) /* (D14) UART0_RXD */
+ AM62X_IOPAD(0x1cc, PIN_OUTPUT, 0) /* (E14) UART0_TXD */
+ >;
+ };
+
+ main_i2c0_pins_default: main-i2c0-pins-default {
+ pinctrl-single,pins = <
+ AM62X_IOPAD(0x1e0, PIN_INPUT_PULLUP, 0) /* (B16) I2C0_SCL */
+ AM62X_IOPAD(0x1e4, PIN_INPUT_PULLUP, 0) /* (A16) I2C0_SDA */
+ >;
+ };
+
+ main_i2c1_pins_default: main-i2c1-pins-default {
+ pinctrl-single,pins = <
+ AM62X_IOPAD(0x1e8, PIN_INPUT_PULLUP, 0) /* (B17) I2C1_SCL */
+ AM62X_IOPAD(0x1ec, PIN_INPUT_PULLUP, 0) /* (A17) I2C1_SDA */
+ >;
+ };
+
+ usr_led_pins_default: usr-led-pins-default {
+ pinctrl-single,pins = <
+ AM62X_IOPAD(0x244, PIN_OUTPUT, 7) /* (C17) MMC1_SDWP.GPIO1_49 */
+ >;
+ };
+};
+
+&wkup_uart0 {
+ /* WKUP UART0 is used by DM firmware */
+ status = "reserved";
+};
+
+&mcu_uart0 {
+ status = "disabled";
+};
+
+&main_uart0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&main_uart0_pins_default>;
+};
+
+&main_uart1 {
+ /* Main UART1 is used by TIFS firmware */
+ status = "reserved";
+};
+
+&main_uart2 {
+ status = "disabled";
+};
+
+&main_uart3 {
+ status = "disabled";
+};
+
+&main_uart4 {
+ status = "disabled";
+};
+
+&main_uart5 {
+ status = "disabled";
+};
+
+&main_uart6 {
+ status = "disabled";
+};
+
+&mcu_i2c0 {
+ status = "disabled";
+};
+
+&wkup_i2c0 {
+ status = "disabled";
+};
+
+&main_i2c0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&main_i2c0_pins_default>;
+ clock-frequency = <400000>;
+};
+
+&main_i2c1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&main_i2c1_pins_default>;
+ clock-frequency = <400000>;
+};
+
+&main_i2c2 {
+ status = "disabled";
+};
+
+&main_i2c3 {
+ status = "disabled";
+};
+
+&mailbox0_cluster0 {
+ mbox_m4_0: mbox-m4-0 {
+ ti,mbox-rx = <0 0 0>;
+ ti,mbox-tx = <1 0 0>;
+ };
+};
diff --git a/arch/arm64/boot/dts/ti/k3-am625.dtsi b/arch/arm64/boot/dts/ti/k3-am625.dtsi
new file mode 100644
index 000000000000..887f31c23fef
--- /dev/null
+++ b/arch/arm64/boot/dts/ti/k3-am625.dtsi
@@ -0,0 +1,103 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * 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/
+ */
+
+/dts-v1/;
+
+#include "k3-am62.dtsi"
+
+/ {
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu-map {
+ cluster0: cluster0 {
+ core0 {
+ cpu = <&cpu0>;
+ };
+
+ core1 {
+ cpu = <&cpu1>;
+ };
+
+ core2 {
+ cpu = <&cpu2>;
+ };
+
+ core3 {
+ cpu = <&cpu3>;
+ };
+ };
+ };
+
+ cpu0: cpu@0 {
+ compatible = "arm,cortex-a53";
+ reg = <0x000>;
+ device_type = "cpu";
+ enable-method = "psci";
+ i-cache-size = <0x8000>;
+ i-cache-line-size = <64>;
+ i-cache-sets = <256>;
+ d-cache-size = <0x8000>;
+ d-cache-line-size = <64>;
+ d-cache-sets = <128>;
+ next-level-cache = <&L2_0>;
+ };
+
+ cpu1: cpu@1 {
+ compatible = "arm,cortex-a53";
+ reg = <0x001>;
+ device_type = "cpu";
+ enable-method = "psci";
+ i-cache-size = <0x8000>;
+ i-cache-line-size = <64>;
+ i-cache-sets = <256>;
+ d-cache-size = <0x8000>;
+ d-cache-line-size = <64>;
+ d-cache-sets = <128>;
+ next-level-cache = <&L2_0>;
+ };
+
+ cpu2: cpu@2 {
+ compatible = "arm,cortex-a53";
+ reg = <0x002>;
+ device_type = "cpu";
+ enable-method = "psci";
+ i-cache-size = <0x8000>;
+ i-cache-line-size = <64>;
+ i-cache-sets = <256>;
+ d-cache-size = <0x8000>;
+ d-cache-line-size = <64>;
+ d-cache-sets = <128>;
+ next-level-cache = <&L2_0>;
+ };
+
+ cpu3: cpu@3 {
+ compatible = "arm,cortex-a53";
+ reg = <0x003>;
+ device_type = "cpu";
+ enable-method = "psci";
+ i-cache-size = <0x8000>;
+ i-cache-line-size = <64>;
+ i-cache-sets = <256>;
+ d-cache-size = <0x8000>;
+ d-cache-line-size = <64>;
+ d-cache-sets = <128>;
+ next-level-cache = <&L2_0>;
+ };
+ };
+
+ L2_0: l2-cache0 {
+ compatible = "cache";
+ cache-level = <2>;
+ cache-size = <0x40000>;
+ cache-line-size = <64>;
+ cache-sets = <512>;
+ };
+};
diff --git a/arch/arm64/boot/dts/ti/k3-am64-main.dtsi b/arch/arm64/boot/dts/ti/k3-am64-main.dtsi
index 012011dc619a..f64b368c6c37 100644
--- a/arch/arm64/boot/dts/ti/k3-am64-main.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am64-main.dtsi
@@ -59,7 +59,10 @@
#interrupt-cells = <3>;
interrupt-controller;
reg = <0x00 0x01800000 0x00 0x10000>, /* GICD */
- <0x00 0x01840000 0x00 0xC0000>; /* GICR */
+ <0x00 0x01840000 0x00 0xC0000>, /* GICR */
+ <0x01 0x00000000 0x00 0x2000>, /* GICC */
+ <0x01 0x00010000 0x00 0x1000>, /* GICH */
+ <0x01 0x00020000 0x00 0x2000>; /* GICV */
/*
* vcpumntirq:
* virtual CPU interface maintenance interrupt
@@ -982,6 +985,24 @@
clock-names = "fck";
};
+ main_rti0: watchdog@e000000 {
+ compatible = "ti,j7-rti-wdt";
+ reg = <0x00 0xe000000 0x00 0x100>;
+ clocks = <&k3_clks 125 0>;
+ power-domains = <&k3_pds 125 TI_SCI_PD_EXCLUSIVE>;
+ assigned-clocks = <&k3_clks 125 0>;
+ assigned-clock-parents = <&k3_clks 125 2>;
+ };
+
+ main_rti1: watchdog@e010000 {
+ compatible = "ti,j7-rti-wdt";
+ reg = <0x00 0xe010000 0x00 0x100>;
+ clocks = <&k3_clks 126 0>;
+ power-domains = <&k3_pds 126 TI_SCI_PD_EXCLUSIVE>;
+ assigned-clocks = <&k3_clks 126 0>;
+ assigned-clock-parents = <&k3_clks 126 2>;
+ };
+
icssg0: icssg@30000000 {
compatible = "ti,am642-icssg";
reg = <0x00 0x30000000 0x00 0x80000>;
diff --git a/arch/arm64/boot/dts/ti/k3-am64.dtsi b/arch/arm64/boot/dts/ti/k3-am64.dtsi
index 120974726be8..016dd8511ca6 100644
--- a/arch/arm64/boot/dts/ti/k3-am64.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am64.dtsi
@@ -66,11 +66,14 @@
#address-cells = <2>;
#size-cells = <2>;
ranges = <0x00 0x000f4000 0x00 0x000f4000 0x00 0x000002d0>, /* PINCTRL */
+ <0x00 0x00420000 0x00 0x00420000 0x00 0x00001000>, /* ESM0 */
<0x00 0x00600000 0x00 0x00600000 0x00 0x00001100>, /* GPIO */
<0x00 0x00a40000 0x00 0x00a40000 0x00 0x00000800>, /* Timesync router */
<0x00 0x01000000 0x00 0x01000000 0x00 0x02330400>, /* First peripheral window */
<0x00 0x08000000 0x00 0x08000000 0x00 0x00200000>, /* Main CPSW */
<0x00 0x0d000000 0x00 0x0d000000 0x00 0x00800000>, /* PCIE_CORE */
+ <0x00 0x0e000000 0x00 0x0e000000 0x00 0x00000100>, /* Main RTI0 */
+ <0x00 0x0e010000 0x00 0x0e010000 0x00 0x00000100>, /* Main RTI1 */
<0x00 0x0f000000 0x00 0x0f000000 0x00 0x00c44200>, /* Second peripheral window */
<0x00 0x20000000 0x00 0x20000000 0x00 0x0a008000>, /* Third peripheral window */
<0x00 0x30000000 0x00 0x30000000 0x00 0x000bc100>, /* ICSSG0/1 */
@@ -87,6 +90,7 @@
<0x00 0x68000000 0x00 0x68000000 0x00 0x08000000>, /* PCIe DAT0 */
<0x00 0x70000000 0x00 0x70000000 0x00 0x00200000>, /* OC SRAM */
<0x00 0x78000000 0x00 0x78000000 0x00 0x00800000>, /* Main R5FSS */
+ <0x01 0x00000000 0x01 0x00000000 0x00 0x00310000>, /* A53 PERIPHBASE */
<0x06 0x00000000 0x06 0x00000000 0x01 0x00000000>, /* PCIe DAT1 */
<0x05 0x00000000 0x05 0x00000000 0x01 0x00000000>, /* FSS0 DAT3 */
diff --git a/arch/arm64/boot/dts/ti/k3-am642-evm.dts b/arch/arm64/boot/dts/ti/k3-am642-evm.dts
index e94ae178b1ae..8e7893e58b03 100644
--- a/arch/arm64/boot/dts/ti/k3-am642-evm.dts
+++ b/arch/arm64/boot/dts/ti/k3-am642-evm.dts
@@ -498,7 +498,7 @@
pinctrl-names = "default";
pinctrl-0 = <&ospi0_pins_default>;
- flash@0{
+ flash@0 {
compatible = "jedec,spi-nor";
reg = <0x0>;
spi-tx-bus-width = <8>;
@@ -509,8 +509,6 @@
cdns,tchsh-ns = <60>;
cdns,tslch-ns = <60>;
cdns,read-delay = <4>;
- #address-cells = <1>;
- #size-cells = <1>;
};
};
diff --git a/arch/arm64/boot/dts/ti/k3-am642-sk.dts b/arch/arm64/boot/dts/ti/k3-am642-sk.dts
index a9785bec12df..1d7db8bf3a5c 100644
--- a/arch/arm64/boot/dts/ti/k3-am642-sk.dts
+++ b/arch/arm64/boot/dts/ti/k3-am642-sk.dts
@@ -369,7 +369,7 @@
pinctrl-names = "default";
pinctrl-0 = <&ospi0_pins_default>;
- flash@0{
+ flash@0 {
compatible = "jedec,spi-nor";
reg = <0x0>;
spi-tx-bus-width = <8>;
@@ -380,8 +380,6 @@
cdns,tchsh-ns = <60>;
cdns,tslch-ns = <60>;
cdns,read-delay = <4>;
- #address-cells = <1>;
- #size-cells = <1>;
};
};
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 3079eaee01c0..6e41f2fa044a 100644
--- a/arch/arm64/boot/dts/ti/k3-am65-iot2050-common.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am65-iot2050-common.dtsi
@@ -603,8 +603,6 @@
cdns,tchsh-ns = <60>;
cdns,tslch-ns = <60>;
cdns,read-delay = <2>;
- #address-cells = <1>;
- #size-cells = <1>;
};
};
diff --git a/arch/arm64/boot/dts/ti/k3-am65-main.dtsi b/arch/arm64/boot/dts/ti/k3-am65-main.dtsi
index ce8bb4a61011..e749343acced 100644
--- a/arch/arm64/boot/dts/ti/k3-am65-main.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am65-main.dtsi
@@ -35,7 +35,10 @@
#interrupt-cells = <3>;
interrupt-controller;
reg = <0x00 0x01800000 0x00 0x10000>, /* GICD */
- <0x00 0x01880000 0x00 0x90000>; /* GICR */
+ <0x00 0x01880000 0x00 0x90000>, /* GICR */
+ <0x00 0x6f000000 0x00 0x2000>, /* GICC */
+ <0x00 0x6f010000 0x00 0x1000>, /* GICH */
+ <0x00 0x6f020000 0x00 0x2000>; /* GICV */
/*
* vcpumntirq:
* virtual CPU interface maintenance interrupt
diff --git a/arch/arm64/boot/dts/ti/k3-am65.dtsi b/arch/arm64/boot/dts/ti/k3-am65.dtsi
index a58a39fa42db..c538a0bf3cdd 100644
--- a/arch/arm64/boot/dts/ti/k3-am65.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am65.dtsi
@@ -86,6 +86,7 @@
<0x00 0x46000000 0x00 0x46000000 0x00 0x00200000>,
<0x00 0x47000000 0x00 0x47000000 0x00 0x00068400>,
<0x00 0x50000000 0x00 0x50000000 0x00 0x8000000>,
+ <0x00 0x6f000000 0x00 0x6f000000 0x00 0x00310000>, /* A53 PERIPHBASE */
<0x00 0x70000000 0x00 0x70000000 0x00 0x200000>,
<0x05 0x00000000 0x05 0x00000000 0x01 0x0000000>,
<0x07 0x00000000 0x07 0x00000000 0x01 0x0000000>;
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 9043f91c9bec..57497cb1ed68 100644
--- a/arch/arm64/boot/dts/ti/k3-am654-base-board.dts
+++ b/arch/arm64/boot/dts/ti/k3-am654-base-board.dts
@@ -333,14 +333,12 @@
#size-cells= <0>;
ti,pindir-d0-out-d1-in;
- flash@0{
+ flash@0 {
compatible = "jedec,spi-nor";
reg = <0x0>;
spi-tx-bus-width = <1>;
spi-rx-bus-width = <1>;
spi-max-frequency = <48000000>;
- #address-cells = <1>;
- #size-cells= <1>;
};
};
@@ -498,7 +496,7 @@
pinctrl-names = "default";
pinctrl-0 = <&mcu_fss0_ospi0_pins_default>;
- flash@0{
+ flash@0 {
compatible = "jedec,spi-nor";
reg = <0x0>;
spi-tx-bus-width = <8>;
@@ -509,8 +507,6 @@
cdns,tchsh-ns = <60>;
cdns,tslch-ns = <60>;
cdns,read-delay = <0>;
- #address-cells = <1>;
- #size-cells = <1>;
};
};
diff --git a/arch/arm64/boot/dts/ti/k3-j7200-main.dtsi b/arch/arm64/boot/dts/ti/k3-j7200-main.dtsi
index 05a627ad6cdc..16684a2f054d 100644
--- a/arch/arm64/boot/dts/ti/k3-j7200-main.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-j7200-main.dtsi
@@ -54,7 +54,10 @@
#interrupt-cells = <3>;
interrupt-controller;
reg = <0x00 0x01800000 0x00 0x10000>, /* GICD */
- <0x00 0x01900000 0x00 0x100000>; /* GICR */
+ <0x00 0x01900000 0x00 0x100000>, /* GICR */
+ <0x00 0x6f000000 0x00 0x2000>, /* GICC */
+ <0x00 0x6f010000 0x00 0x1000>, /* GICH */
+ <0x00 0x6f020000 0x00 0x2000>; /* GICV */
/* vcpumntirq: virtual CPU interface maintenance interrupt */
interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>;
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 34724440171a..2d615c3e9fa1 100644
--- a/arch/arm64/boot/dts/ti/k3-j7200-som-p0.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-j7200-som-p0.dtsi
@@ -256,7 +256,7 @@
pinctrl-names = "default";
pinctrl-0 = <&mcu_fss0_ospi0_pins_default>;
- flash@0{
+ flash@0 {
compatible = "jedec,spi-nor";
reg = <0x0>;
spi-tx-bus-width = <8>;
@@ -267,7 +267,5 @@
cdns,tchsh-ns = <60>;
cdns,tslch-ns = <60>;
cdns,read-delay = <4>;
- #address-cells = <1>;
- #size-cells = <1>;
};
};
diff --git a/arch/arm64/boot/dts/ti/k3-j7200.dtsi b/arch/arm64/boot/dts/ti/k3-j7200.dtsi
index 64fef4e67d76..b6da0454cc5b 100644
--- a/arch/arm64/boot/dts/ti/k3-j7200.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-j7200.dtsi
@@ -129,6 +129,7 @@
<0x00 0x00a40000 0x00 0x00a40000 0x00 0x00000800>, /* timesync router */
<0x00 0x01000000 0x00 0x01000000 0x00 0x0d000000>, /* Most peripherals */
<0x00 0x30000000 0x00 0x30000000 0x00 0x0c400000>, /* MAIN NAVSS */
+ <0x00 0x6f000000 0x00 0x6f000000 0x00 0x00310000>, /* A72 PERIPHBASE */
<0x00 0x70000000 0x00 0x70000000 0x00 0x00800000>, /* MSMC RAM */
<0x00 0x18000000 0x00 0x18000000 0x00 0x08000000>, /* PCIe1 DAT0 */
<0x41 0x00000000 0x41 0x00000000 0x01 0x00000000>, /* PCIe1 DAT1 */
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 2d7596911b27..f5ca8e26ed99 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
@@ -482,7 +482,7 @@
pinctrl-names = "default";
pinctrl-0 = <&mcu_fss0_ospi1_pins_default>;
- flash@0{
+ flash@0 {
compatible = "jedec,spi-nor";
reg = <0x0>;
spi-tx-bus-width = <1>;
@@ -493,8 +493,6 @@
cdns,tchsh-ns = <60>;
cdns,tslch-ns = <60>;
cdns,read-delay = <2>;
- #address-cells = <1>;
- #size-cells = <1>;
};
};
diff --git a/arch/arm64/boot/dts/ti/k3-j721e-main.dtsi b/arch/arm64/boot/dts/ti/k3-j721e-main.dtsi
index 599861259a30..db0669985e42 100644
--- a/arch/arm64/boot/dts/ti/k3-j721e-main.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-j721e-main.dtsi
@@ -76,7 +76,10 @@
#interrupt-cells = <3>;
interrupt-controller;
reg = <0x00 0x01800000 0x00 0x10000>, /* GICD */
- <0x00 0x01900000 0x00 0x100000>; /* GICR */
+ <0x00 0x01900000 0x00 0x100000>, /* GICR */
+ <0x00 0x6f000000 0x00 0x2000>, /* GICC */
+ <0x00 0x6f010000 0x00 0x1000>, /* GICH */
+ <0x00 0x6f020000 0x00 0x2000>; /* GICV */
/* vcpumntirq: virtual CPU interface maintenance interrupt */
interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>;
diff --git a/arch/arm64/boot/dts/ti/k3-j721e-sk.dts b/arch/arm64/boot/dts/ti/k3-j721e-sk.dts
index b726310d867c..f25d85169e0d 100644
--- a/arch/arm64/boot/dts/ti/k3-j721e-sk.dts
+++ b/arch/arm64/boot/dts/ti/k3-j721e-sk.dts
@@ -475,8 +475,6 @@
cdns,tchsh-ns = <60>;
cdns,tslch-ns = <60>;
cdns,read-delay = <4>;
- #address-cells = <1>;
- #size-cells = <1>;
};
};
diff --git a/arch/arm64/boot/dts/ti/k3-j721e-som-p0.dtsi b/arch/arm64/boot/dts/ti/k3-j721e-som-p0.dtsi
index 2fee2906183d..e36335232cf8 100644
--- a/arch/arm64/boot/dts/ti/k3-j721e-som-p0.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-j721e-som-p0.dtsi
@@ -171,7 +171,7 @@
pinctrl-names = "default";
pinctrl-0 = <&mcu_fss0_ospi0_pins_default>;
- flash@0{
+ flash@0 {
compatible = "jedec,spi-nor";
reg = <0x0>;
spi-tx-bus-width = <8>;
@@ -182,8 +182,6 @@
cdns,tchsh-ns = <60>;
cdns,tslch-ns = <60>;
cdns,read-delay = <0>;
- #address-cells = <1>;
- #size-cells = <1>;
};
};
diff --git a/arch/arm64/boot/dts/ti/k3-j721e.dtsi b/arch/arm64/boot/dts/ti/k3-j721e.dtsi
index 4a3872fce533..0e23886c9fd1 100644
--- a/arch/arm64/boot/dts/ti/k3-j721e.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-j721e.dtsi
@@ -139,6 +139,7 @@
<0x00 0x0e000000 0x00 0x0e000000 0x00 0x01800000>, /* PCIe Core*/
<0x00 0x10000000 0x00 0x10000000 0x00 0x10000000>, /* PCIe DAT */
<0x00 0x64800000 0x00 0x64800000 0x00 0x00800000>, /* C71 */
+ <0x00 0x6f000000 0x00 0x6f000000 0x00 0x00310000>, /* A72 PERIPHBASE */
<0x44 0x00000000 0x44 0x00000000 0x00 0x08000000>, /* PCIe2 DAT */
<0x44 0x10000000 0x44 0x10000000 0x00 0x08000000>, /* PCIe3 DAT */
<0x4d 0x80800000 0x4d 0x80800000 0x00 0x00800000>, /* C66_0 */
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 a5a24f9f46c5..b210cc07c539 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
@@ -15,8 +15,18 @@
model = "Texas Instruments J721S2 EVM";
chosen {
- stdout-path = "serial10:115200n8";
- bootargs = "console=ttyS10,115200n8 earlycon=ns16550a,mmio32,2880000";
+ stdout-path = "serial2:115200n8";
+ bootargs = "console=ttyS2,115200n8 earlycon=ns16550a,mmio32,2880000";
+ };
+
+ aliases {
+ serial1 = &mcu_uart0;
+ serial2 = &main_uart8;
+ mmc0 = &main_sdhci0;
+ mmc1 = &main_sdhci1;
+ can0 = &main_mcan16;
+ can1 = &mcu_mcan0;
+ can2 = &mcu_mcan1;
};
evm_12v0: fixedregulator-evm12v0 {
diff --git a/arch/arm64/boot/dts/ti/k3-j721s2-main.dtsi b/arch/arm64/boot/dts/ti/k3-j721s2-main.dtsi
index b04db1d3ab61..be7f39299894 100644
--- a/arch/arm64/boot/dts/ti/k3-j721s2-main.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-j721s2-main.dtsi
@@ -34,7 +34,10 @@
#interrupt-cells = <3>;
interrupt-controller;
reg = <0x00 0x01800000 0x00 0x200000>, /* GICD */
- <0x00 0x01900000 0x00 0x100000>; /* GICR */
+ <0x00 0x01900000 0x00 0x100000>, /* GICR */
+ <0x00 0x6f000000 0x00 0x2000>, /* GICC */
+ <0x00 0x6f010000 0x00 0x1000>, /* GICH */
+ <0x00 0x6f020000 0x00 0x2000>; /* GICV */
/* vcpumntirq: virtual CPU interface maintenance interrupt */
interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>;
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 7521963719ff..6c5c02edb375 100644
--- a/arch/arm64/boot/dts/ti/k3-j721s2-mcu-wakeup.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-j721s2-mcu-wakeup.dtsi
@@ -108,7 +108,7 @@
reg = <0x00 0x42110000 0x00 0x100>;
gpio-controller;
#gpio-cells = <2>;
- interrupt-parent = <&main_gpio_intr>;
+ interrupt-parent = <&wkup_gpio_intr>;
interrupts = <103>, <104>, <105>, <106>, <107>, <108>;
interrupt-controller;
#interrupt-cells = <2>;
@@ -124,7 +124,7 @@
reg = <0x00 0x42100000 0x00 0x100>;
gpio-controller;
#gpio-cells = <2>;
- interrupt-parent = <&main_gpio_intr>;
+ interrupt-parent = <&wkup_gpio_intr>;
interrupts = <112>, <113>, <114>, <115>, <116>, <117>;
interrupt-controller;
#interrupt-cells = <2>;
diff --git a/arch/arm64/boot/dts/ti/k3-j721s2.dtsi b/arch/arm64/boot/dts/ti/k3-j721s2.dtsi
index 80d3cae03e88..7b930a85a29d 100644
--- a/arch/arm64/boot/dts/ti/k3-j721s2.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-j721s2.dtsi
@@ -21,28 +21,6 @@
#address-cells = <2>;
#size-cells = <2>;
- aliases {
- serial0 = &wkup_uart0;
- serial1 = &mcu_uart0;
- serial2 = &main_uart0;
- serial3 = &main_uart1;
- serial4 = &main_uart2;
- serial5 = &main_uart3;
- serial6 = &main_uart4;
- serial7 = &main_uart5;
- serial8 = &main_uart6;
- serial9 = &main_uart7;
- serial10 = &main_uart8;
- serial11 = &main_uart9;
- mmc0 = &main_sdhci0;
- mmc1 = &main_sdhci1;
- can0 = &main_mcan16;
- can1 = &mcu_mcan0;
- can2 = &mcu_mcan1;
- can3 = &main_mcan3;
- can4 = &main_mcan5;
- };
-
chosen { };
cpus {
@@ -141,6 +119,7 @@
<0x00 0x18000000 0x00 0x18000000 0x00 0x08000000>, /* PCIe1 DAT0 */
<0x00 0x64800000 0x00 0x64800000 0x00 0x0070c000>, /* C71_1 */
<0x00 0x65800000 0x00 0x65800000 0x00 0x0070c000>, /* C71_2 */
+ <0x00 0x6f000000 0x00 0x6f000000 0x00 0x00310000>, /* A72 PERIPHBASE */
<0x00 0x70000000 0x00 0x70000000 0x00 0x00400000>, /* MSMC RAM */
<0x00 0x30000000 0x00 0x30000000 0x00 0x0c400000>, /* MAIN NAVSS */
<0x41 0x00000000 0x41 0x00000000 0x01 0x00000000>, /* PCIe1 DAT1 */
diff --git a/arch/arm64/boot/dts/xilinx/zynqmp.dtsi b/arch/arm64/boot/dts/xilinx/zynqmp.dtsi
index 74e66443e4ce..056761c974fd 100644
--- a/arch/arm64/boot/dts/xilinx/zynqmp.dtsi
+++ b/arch/arm64/boot/dts/xilinx/zynqmp.dtsi
@@ -254,106 +254,106 @@
};
/* GDMA */
- fpd_dma_chan1: dma@fd500000 {
+ fpd_dma_chan1: dma-controller@fd500000 {
status = "disabled";
compatible = "xlnx,zynqmp-dma-1.0";
reg = <0x0 0xfd500000 0x0 0x1000>;
interrupt-parent = <&gic>;
interrupts = <0 124 4>;
clock-names = "clk_main", "clk_apb";
+ #dma-cells = <1>;
xlnx,bus-width = <128>;
- #stream-id-cells = <1>;
iommus = <&smmu 0x14e8>;
power-domains = <&zynqmp_firmware PD_GDMA>;
};
- fpd_dma_chan2: dma@fd510000 {
+ fpd_dma_chan2: dma-controller@fd510000 {
status = "disabled";
compatible = "xlnx,zynqmp-dma-1.0";
reg = <0x0 0xfd510000 0x0 0x1000>;
interrupt-parent = <&gic>;
interrupts = <0 125 4>;
clock-names = "clk_main", "clk_apb";
+ #dma-cells = <1>;
xlnx,bus-width = <128>;
- #stream-id-cells = <1>;
iommus = <&smmu 0x14e9>;
power-domains = <&zynqmp_firmware PD_GDMA>;
};
- fpd_dma_chan3: dma@fd520000 {
+ fpd_dma_chan3: dma-controller@fd520000 {
status = "disabled";
compatible = "xlnx,zynqmp-dma-1.0";
reg = <0x0 0xfd520000 0x0 0x1000>;
interrupt-parent = <&gic>;
interrupts = <0 126 4>;
clock-names = "clk_main", "clk_apb";
+ #dma-cells = <1>;
xlnx,bus-width = <128>;
- #stream-id-cells = <1>;
iommus = <&smmu 0x14ea>;
power-domains = <&zynqmp_firmware PD_GDMA>;
};
- fpd_dma_chan4: dma@fd530000 {
+ fpd_dma_chan4: dma-controller@fd530000 {
status = "disabled";
compatible = "xlnx,zynqmp-dma-1.0";
reg = <0x0 0xfd530000 0x0 0x1000>;
interrupt-parent = <&gic>;
interrupts = <0 127 4>;
clock-names = "clk_main", "clk_apb";
+ #dma-cells = <1>;
xlnx,bus-width = <128>;
- #stream-id-cells = <1>;
iommus = <&smmu 0x14eb>;
power-domains = <&zynqmp_firmware PD_GDMA>;
};
- fpd_dma_chan5: dma@fd540000 {
+ fpd_dma_chan5: dma-controller@fd540000 {
status = "disabled";
compatible = "xlnx,zynqmp-dma-1.0";
reg = <0x0 0xfd540000 0x0 0x1000>;
interrupt-parent = <&gic>;
interrupts = <0 128 4>;
clock-names = "clk_main", "clk_apb";
+ #dma-cells = <1>;
xlnx,bus-width = <128>;
- #stream-id-cells = <1>;
iommus = <&smmu 0x14ec>;
power-domains = <&zynqmp_firmware PD_GDMA>;
};
- fpd_dma_chan6: dma@fd550000 {
+ fpd_dma_chan6: dma-controller@fd550000 {
status = "disabled";
compatible = "xlnx,zynqmp-dma-1.0";
reg = <0x0 0xfd550000 0x0 0x1000>;
interrupt-parent = <&gic>;
interrupts = <0 129 4>;
clock-names = "clk_main", "clk_apb";
+ #dma-cells = <1>;
xlnx,bus-width = <128>;
- #stream-id-cells = <1>;
iommus = <&smmu 0x14ed>;
power-domains = <&zynqmp_firmware PD_GDMA>;
};
- fpd_dma_chan7: dma@fd560000 {
+ fpd_dma_chan7: dma-controller@fd560000 {
status = "disabled";
compatible = "xlnx,zynqmp-dma-1.0";
reg = <0x0 0xfd560000 0x0 0x1000>;
interrupt-parent = <&gic>;
interrupts = <0 130 4>;
clock-names = "clk_main", "clk_apb";
+ #dma-cells = <1>;
xlnx,bus-width = <128>;
- #stream-id-cells = <1>;
iommus = <&smmu 0x14ee>;
power-domains = <&zynqmp_firmware PD_GDMA>;
};
- fpd_dma_chan8: dma@fd570000 {
+ fpd_dma_chan8: dma-controller@fd570000 {
status = "disabled";
compatible = "xlnx,zynqmp-dma-1.0";
reg = <0x0 0xfd570000 0x0 0x1000>;
interrupt-parent = <&gic>;
interrupts = <0 131 4>;
clock-names = "clk_main", "clk_apb";
+ #dma-cells = <1>;
xlnx,bus-width = <128>;
- #stream-id-cells = <1>;
iommus = <&smmu 0x14ef>;
power-domains = <&zynqmp_firmware PD_GDMA>;
};
@@ -375,106 +375,106 @@
* These dma channels, Users should ensure that these dma
* Channels are allowed for non secure access.
*/
- lpd_dma_chan1: dma@ffa80000 {
+ lpd_dma_chan1: dma-controller@ffa80000 {
status = "disabled";
compatible = "xlnx,zynqmp-dma-1.0";
reg = <0x0 0xffa80000 0x0 0x1000>;
interrupt-parent = <&gic>;
interrupts = <0 77 4>;
clock-names = "clk_main", "clk_apb";
+ #dma-cells = <1>;
xlnx,bus-width = <64>;
- #stream-id-cells = <1>;
iommus = <&smmu 0x868>;
power-domains = <&zynqmp_firmware PD_ADMA>;
};
- lpd_dma_chan2: dma@ffa90000 {
+ lpd_dma_chan2: dma-controller@ffa90000 {
status = "disabled";
compatible = "xlnx,zynqmp-dma-1.0";
reg = <0x0 0xffa90000 0x0 0x1000>;
interrupt-parent = <&gic>;
interrupts = <0 78 4>;
clock-names = "clk_main", "clk_apb";
+ #dma-cells = <1>;
xlnx,bus-width = <64>;
- #stream-id-cells = <1>;
iommus = <&smmu 0x869>;
power-domains = <&zynqmp_firmware PD_ADMA>;
};
- lpd_dma_chan3: dma@ffaa0000 {
+ lpd_dma_chan3: dma-controller@ffaa0000 {
status = "disabled";
compatible = "xlnx,zynqmp-dma-1.0";
reg = <0x0 0xffaa0000 0x0 0x1000>;
interrupt-parent = <&gic>;
interrupts = <0 79 4>;
clock-names = "clk_main", "clk_apb";
+ #dma-cells = <1>;
xlnx,bus-width = <64>;
- #stream-id-cells = <1>;
iommus = <&smmu 0x86a>;
power-domains = <&zynqmp_firmware PD_ADMA>;
};
- lpd_dma_chan4: dma@ffab0000 {
+ lpd_dma_chan4: dma-controller@ffab0000 {
status = "disabled";
compatible = "xlnx,zynqmp-dma-1.0";
reg = <0x0 0xffab0000 0x0 0x1000>;
interrupt-parent = <&gic>;
interrupts = <0 80 4>;
clock-names = "clk_main", "clk_apb";
+ #dma-cells = <1>;
xlnx,bus-width = <64>;
- #stream-id-cells = <1>;
iommus = <&smmu 0x86b>;
power-domains = <&zynqmp_firmware PD_ADMA>;
};
- lpd_dma_chan5: dma@ffac0000 {
+ lpd_dma_chan5: dma-controller@ffac0000 {
status = "disabled";
compatible = "xlnx,zynqmp-dma-1.0";
reg = <0x0 0xffac0000 0x0 0x1000>;
interrupt-parent = <&gic>;
interrupts = <0 81 4>;
clock-names = "clk_main", "clk_apb";
+ #dma-cells = <1>;
xlnx,bus-width = <64>;
- #stream-id-cells = <1>;
iommus = <&smmu 0x86c>;
power-domains = <&zynqmp_firmware PD_ADMA>;
};
- lpd_dma_chan6: dma@ffad0000 {
+ lpd_dma_chan6: dma-controller@ffad0000 {
status = "disabled";
compatible = "xlnx,zynqmp-dma-1.0";
reg = <0x0 0xffad0000 0x0 0x1000>;
interrupt-parent = <&gic>;
interrupts = <0 82 4>;
clock-names = "clk_main", "clk_apb";
+ #dma-cells = <1>;
xlnx,bus-width = <64>;
- #stream-id-cells = <1>;
iommus = <&smmu 0x86d>;
power-domains = <&zynqmp_firmware PD_ADMA>;
};
- lpd_dma_chan7: dma@ffae0000 {
+ lpd_dma_chan7: dma-controller@ffae0000 {
status = "disabled";
compatible = "xlnx,zynqmp-dma-1.0";
reg = <0x0 0xffae0000 0x0 0x1000>;
interrupt-parent = <&gic>;
interrupts = <0 83 4>;
clock-names = "clk_main", "clk_apb";
+ #dma-cells = <1>;
xlnx,bus-width = <64>;
- #stream-id-cells = <1>;
iommus = <&smmu 0x86e>;
power-domains = <&zynqmp_firmware PD_ADMA>;
};
- lpd_dma_chan8: dma@ffaf0000 {
+ lpd_dma_chan8: dma-controller@ffaf0000 {
status = "disabled";
compatible = "xlnx,zynqmp-dma-1.0";
reg = <0x0 0xffaf0000 0x0 0x1000>;
interrupt-parent = <&gic>;
interrupts = <0 84 4>;
clock-names = "clk_main", "clk_apb";
+ #dma-cells = <1>;
xlnx,bus-width = <64>;
- #stream-id-cells = <1>;
iommus = <&smmu 0x86f>;
power-domains = <&zynqmp_firmware PD_ADMA>;
};
@@ -495,7 +495,6 @@
interrupts = <0 14 4>;
#address-cells = <1>;
#size-cells = <0>;
- #stream-id-cells = <1>;
iommus = <&smmu 0x872>;
power-domains = <&zynqmp_firmware PD_NAND>;
};
@@ -509,9 +508,10 @@
clock-names = "pclk", "hclk", "tx_clk";
#address-cells = <1>;
#size-cells = <0>;
- #stream-id-cells = <1>;
iommus = <&smmu 0x874>;
power-domains = <&zynqmp_firmware PD_ETH_0>;
+ resets = <&zynqmp_reset ZYNQMP_RESET_GEM0>;
+ reset-names = "gem0_rst";
};
gem1: ethernet@ff0c0000 {
@@ -523,9 +523,10 @@
clock-names = "pclk", "hclk", "tx_clk";
#address-cells = <1>;
#size-cells = <0>;
- #stream-id-cells = <1>;
iommus = <&smmu 0x875>;
power-domains = <&zynqmp_firmware PD_ETH_1>;
+ resets = <&zynqmp_reset ZYNQMP_RESET_GEM1>;
+ reset-names = "gem1_rst";
};
gem2: ethernet@ff0d0000 {
@@ -537,9 +538,10 @@
clock-names = "pclk", "hclk", "tx_clk";
#address-cells = <1>;
#size-cells = <0>;
- #stream-id-cells = <1>;
iommus = <&smmu 0x876>;
power-domains = <&zynqmp_firmware PD_ETH_2>;
+ resets = <&zynqmp_reset ZYNQMP_RESET_GEM2>;
+ reset-names = "gem2_rst";
};
gem3: ethernet@ff0e0000 {
@@ -551,9 +553,10 @@
clock-names = "pclk", "hclk", "tx_clk";
#address-cells = <1>;
#size-cells = <0>;
- #stream-id-cells = <1>;
iommus = <&smmu 0x877>;
power-domains = <&zynqmp_firmware PD_ETH_3>;
+ resets = <&zynqmp_reset ZYNQMP_RESET_GEM3>;
+ reset-names = "gem3_rst";
};
gpio: gpio@ff0a0000 {
@@ -621,7 +624,6 @@
<0x0 0x0 0x0 0x2 &pcie_intc 0x2>,
<0x0 0x0 0x0 0x3 &pcie_intc 0x3>,
<0x0 0x0 0x0 0x4 &pcie_intc 0x4>;
- #stream-id-cells = <1>;
iommus = <&smmu 0x4d0>;
power-domains = <&zynqmp_firmware PD_PCIE>;
pcie_intc: legacy-interrupt-controller {
@@ -642,7 +644,6 @@
<0x0 0xc0000000 0x0 0x8000000>;
#address-cells = <1>;
#size-cells = <0>;
- #stream-id-cells = <1>;
iommus = <&smmu 0x873>;
power-domains = <&zynqmp_firmware PD_QSPI>;
};
@@ -674,7 +675,6 @@
interrupts = <0 133 4>;
power-domains = <&zynqmp_firmware PD_SATA>;
resets = <&zynqmp_reset ZYNQMP_RESET_SATA>;
- #stream-id-cells = <4>;
iommus = <&smmu 0x4c0>, <&smmu 0x4c1>,
<&smmu 0x4c2>, <&smmu 0x4c3>;
};
@@ -686,7 +686,6 @@
interrupts = <0 48 4>;
reg = <0x0 0xff160000 0x0 0x1000>;
clock-names = "clk_xin", "clk_ahb";
- #stream-id-cells = <1>;
iommus = <&smmu 0x870>;
#clock-cells = <1>;
clock-output-names = "clk_out_sd0", "clk_in_sd0";
@@ -700,7 +699,6 @@
interrupts = <0 49 4>;
reg = <0x0 0xff170000 0x0 0x1000>;
clock-names = "clk_xin", "clk_ahb";
- #stream-id-cells = <1>;
iommus = <&smmu 0x871>;
#clock-cells = <1>;
clock-output-names = "clk_out_sd1", "clk_in_sd1";
@@ -825,7 +823,6 @@
interrupt-parent = <&gic>;
interrupt-names = "dwc_usb3", "otg";
interrupts = <0 65 4>, <0 69 4>;
- #stream-id-cells = <1>;
iommus = <&smmu 0x860>;
snps,quirk-frame-length-adjustment = <0x20>;
/* dma-coherent; */
@@ -852,7 +849,6 @@
interrupt-parent = <&gic>;
interrupt-names = "dwc_usb3", "otg";
interrupts = <0 70 4>, <0 74 4>;
- #stream-id-cells = <1>;
iommus = <&smmu 0x861>;
snps,quirk-frame-length-adjustment = <0x20>;
/* dma-coherent; */
diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index 30516dc0b70e..50aa3d75ab4f 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -3,17 +3,19 @@ CONFIG_POSIX_MQUEUE=y
CONFIG_AUDIT=y
CONFIG_NO_HZ_IDLE=y
CONFIG_HIGH_RES_TIMERS=y
+CONFIG_BPF_SYSCALL=y
+CONFIG_BPF_JIT=y
CONFIG_PREEMPT=y
CONFIG_IRQ_TIME_ACCOUNTING=y
CONFIG_BSD_PROCESS_ACCT=y
CONFIG_BSD_PROCESS_ACCT_V3=y
+CONFIG_TASKSTATS=y
CONFIG_TASK_XACCT=y
CONFIG_TASK_IO_ACCOUNTING=y
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_NUMA_BALANCING=y
CONFIG_MEMCG=y
-CONFIG_MEMCG_SWAP=y
CONFIG_BLK_CGROUP=y
CONFIG_CGROUP_PIDS=y
CONFIG_CGROUP_HUGETLB=y
@@ -21,6 +23,7 @@ CONFIG_CPUSETS=y
CONFIG_CGROUP_DEVICE=y
CONFIG_CGROUP_CPUACCT=y
CONFIG_CGROUP_PERF=y
+CONFIG_CGROUP_BPF=y
CONFIG_USER_NS=y
CONFIG_SCHED_AUTOGROUP=y
CONFIG_BLK_DEV_INITRD=y
@@ -54,6 +57,7 @@ CONFIG_ARCH_SEATTLE=y
CONFIG_ARCH_INTEL_SOCFPGA=y
CONFIG_ARCH_SYNQUACER=y
CONFIG_ARCH_TEGRA=y
+CONFIG_ARCH_TESLA_FSD=y
CONFIG_ARCH_SPRD=y
CONFIG_ARCH_THUNDER=y
CONFIG_ARCH_THUNDER2=y
@@ -66,7 +70,6 @@ CONFIG_ARM64_VA_BITS_48=y
CONFIG_SCHED_MC=y
CONFIG_SCHED_SMT=y
CONFIG_NUMA=y
-CONFIG_SECCOMP=y
CONFIG_KEXEC=y
CONFIG_KEXEC_FILE=y
CONFIG_CRASH_DUMP=y
@@ -84,7 +87,6 @@ CONFIG_CPU_FREQ_GOV_POWERSAVE=m
CONFIG_CPU_FREQ_GOV_USERSPACE=y
CONFIG_CPU_FREQ_GOV_ONDEMAND=y
CONFIG_CPU_FREQ_GOV_CONSERVATIVE=m
-CONFIG_CPU_FREQ_GOV_SCHEDUTIL=y
CONFIG_CPUFREQ_DT=y
CONFIG_ACPI_CPPC_CPUFREQ=m
CONFIG_ARM_ALLWINNER_SUN50I_CPUFREQ_NVMEM=m
@@ -96,16 +98,8 @@ CONFIG_ARM_QCOM_CPUFREQ_HW=y
CONFIG_ARM_RASPBERRYPI_CPUFREQ=m
CONFIG_ARM_SCMI_CPUFREQ=y
CONFIG_ARM_TEGRA186_CPUFREQ=y
+CONFIG_ARM_MEDIATEK_CPUFREQ=y
CONFIG_QORIQ_CPUFREQ=y
-CONFIG_ARM_SCMI_PROTOCOL=y
-CONFIG_ARM_SCPI_PROTOCOL=y
-CONFIG_RASPBERRYPI_FIRMWARE=y
-CONFIG_INTEL_STRATIX10_SERVICE=y
-CONFIG_INTEL_STRATIX10_RSU=m
-CONFIG_QCOM_SCM=y
-CONFIG_EFI_CAPSULE_LOADER=y
-CONFIG_IMX_SCU=y
-CONFIG_IMX_SCU_PD=y
CONFIG_ACPI=y
CONFIG_ACPI_APEI=y
CONFIG_ACPI_APEI_GHES=y
@@ -127,6 +121,7 @@ CONFIG_CRYPTO_AES_ARM64_CE_BLK=y
CONFIG_CRYPTO_CHACHA20_NEON=m
CONFIG_CRYPTO_AES_ARM64_BS=m
CONFIG_JUMP_LABEL=y
+CONFIG_SECCOMP=y
CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y
# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
@@ -182,14 +177,13 @@ CONFIG_NET_ACT_GATE=m
CONFIG_QRTR=m
CONFIG_QRTR_SMD=m
CONFIG_QRTR_TUN=m
-CONFIG_BPF_JIT=y
CONFIG_CAN=m
+CONFIG_CAN_FLEXCAN=m
CONFIG_CAN_RCAR=m
CONFIG_CAN_RCAR_CANFD=m
-CONFIG_CAN_FLEXCAN=m
+CONFIG_CAN_MCP251XFD=m
CONFIG_BT=m
CONFIG_BT_HIDP=m
-# CONFIG_BT_HS is not set
# CONFIG_BT_LE is not set
CONFIG_BT_LEDS=y
# CONFIG_BT_DEBUGFS is not set
@@ -198,6 +192,9 @@ CONFIG_BT_HCIUART=m
CONFIG_BT_HCIUART_LL=y
CONFIG_BT_HCIUART_BCM=y
CONFIG_BT_HCIUART_QCA=y
+CONFIG_BT_HCIUART_MRVL=y
+CONFIG_BT_MRVL=m
+CONFIG_BT_MRVL_SDIO=m
CONFIG_BT_QCOMSMD=m
CONFIG_CFG80211=m
CONFIG_MAC80211=m
@@ -210,6 +207,7 @@ CONFIG_NFC_NCI=m
CONFIG_NFC_S3FWRN5_I2C=m
CONFIG_PCI=y
CONFIG_PCIEPORTBUS=y
+CONFIG_PCIEAER=y
CONFIG_PCI_IOV=y
CONFIG_PCI_PASID=y
CONFIG_HOTPLUG_PCI=y
@@ -228,7 +226,6 @@ CONFIG_PCIE_ROCKCHIP_HOST=m
CONFIG_PCIE_BRCMSTB=m
CONFIG_PCI_IMX6=y
CONFIG_PCI_LAYERSCAPE=y
-CONFIG_PCIE_LAYERSCAPE_GEN4=y
CONFIG_PCI_HISI=y
CONFIG_PCIE_QCOM=y
CONFIG_PCIE_ARMADA_8K=y
@@ -236,6 +233,7 @@ CONFIG_PCIE_KIRIN=y
CONFIG_PCIE_HISI_STB=y
CONFIG_PCIE_TEGRA194_HOST=m
CONFIG_PCIE_VISCONTI_HOST=y
+CONFIG_PCIE_LAYERSCAPE_GEN4=y
CONFIG_PCI_ENDPOINT=y
CONFIG_PCI_ENDPOINT_CONFIGFS=y
CONFIG_PCI_EPF_TEST=m
@@ -243,8 +241,15 @@ CONFIG_DEVTMPFS=y
CONFIG_DEVTMPFS_MOUNT=y
CONFIG_FW_LOADER_USER_HELPER=y
CONFIG_HISILICON_LPC=y
-CONFIG_FSL_MC_BUS=y
CONFIG_TEGRA_ACONNECT=m
+CONFIG_ARM_SCMI_PROTOCOL=y
+CONFIG_ARM_SCPI_PROTOCOL=y
+CONFIG_RASPBERRYPI_FIRMWARE=y
+CONFIG_INTEL_STRATIX10_SERVICE=y
+CONFIG_INTEL_STRATIX10_RSU=m
+CONFIG_EFI_CAPSULE_LOADER=y
+CONFIG_IMX_SCU=y
+CONFIG_IMX_SCU_PD=y
CONFIG_GNSS=m
CONFIG_GNSS_MTK_SERIAL=m
CONFIG_MTD=y
@@ -259,13 +264,12 @@ CONFIG_MTD_PHYSMAP_OF=y
CONFIG_MTD_DATAFLASH=y
CONFIG_MTD_SST25L=y
CONFIG_MTD_RAW_NAND=y
+CONFIG_MTD_NAND_BRCMNAND=m
CONFIG_MTD_NAND_DENALI_DT=y
CONFIG_MTD_NAND_MARVELL=y
CONFIG_MTD_NAND_FSL_IFC=y
CONFIG_MTD_NAND_QCOM=y
CONFIG_MTD_SPI_NOR=y
-CONFIG_MTK_DEVAPC=m
-CONFIG_SPI_CADENCE_QUADSPI=y
CONFIG_BLK_DEV_LOOP=y
CONFIG_BLK_DEV_NBD=m
CONFIG_VIRTIO_BLK=y
@@ -290,6 +294,7 @@ CONFIG_SCSI_UFS_EXYNOS=y
CONFIG_ATA=y
CONFIG_SATA_AHCI=y
CONFIG_SATA_AHCI_PLATFORM=y
+CONFIG_AHCI_BRCM=m
CONFIG_AHCI_CEVA=y
CONFIG_AHCI_MVEBU=y
CONFIG_AHCI_XGENE=y
@@ -309,11 +314,13 @@ CONFIG_MACVTAP=m
CONFIG_TUN=y
CONFIG_VETH=m
CONFIG_VIRTIO_NET=y
+CONFIG_NET_DSA_BCM_SF2=m
CONFIG_NET_DSA_MSCC_FELIX=m
CONFIG_AMD_XGBE=y
CONFIG_NET_XGENE=y
CONFIG_ATL1C=m
CONFIG_BCMGENET=m
+CONFIG_SYSTEMPORT=m
CONFIG_BNX2X=m
CONFIG_MACB=y
CONFIG_THUNDER_NIC_PF=y
@@ -342,6 +349,7 @@ CONFIG_MLX5_CORE=m
CONFIG_MLX5_CORE_EN=y
CONFIG_QCOM_EMAC=m
CONFIG_RMNET=m
+CONFIG_R8169=m
CONFIG_SH_ETH=y
CONFIG_RAVB=y
CONFIG_SMC91X=y
@@ -351,13 +359,11 @@ CONFIG_SNI_NETSEC=y
CONFIG_STMMAC_ETH=m
CONFIG_TI_K3_AM65_CPSW_NUSS=y
CONFIG_QCOM_IPA=m
-CONFIG_MDIO_BUS_MUX_MMIOREG=y
-CONFIG_MDIO_BUS_MUX_MULTIPLEXER=y
+CONFIG_MESON_GXL_PHY=m
CONFIG_AQUANTIA_PHY=y
CONFIG_BCM54140_PHY=m
CONFIG_MARVELL_PHY=m
CONFIG_MARVELL_10G_PHY=m
-CONFIG_MESON_GXL_PHY=m
CONFIG_MICREL_PHY=y
CONFIG_MICROSEMI_PHY=y
CONFIG_AT803X_PHY=y
@@ -365,6 +371,9 @@ CONFIG_REALTEK_PHY=y
CONFIG_ROCKCHIP_PHY=y
CONFIG_DP83867_PHY=y
CONFIG_VITESSE_PHY=y
+CONFIG_MDIO_BUS_MUX_MULTIPLEXER=y
+CONFIG_MDIO_BUS_MUX_MMIOREG=y
+CONFIG_USB_BRCMSTB=m
CONFIG_USB_PEGASUS=m
CONFIG_USB_RTL8150=m
CONFIG_USB_RTL8152=m
@@ -382,6 +391,7 @@ CONFIG_ATH10K_SNOC=m
CONFIG_WCN36XX=m
CONFIG_BRCMFMAC=m
CONFIG_MWIFIEX=m
+CONFIG_MWIFIEX_SDIO=m
CONFIG_MWIFIEX_PCIE=m
CONFIG_WL18XX=m
CONFIG_WLCORE_SDIO=m
@@ -473,6 +483,7 @@ CONFIG_SPI=y
CONFIG_SPI_ARMADA_3700=y
CONFIG_SPI_BCM2835=m
CONFIG_SPI_BCM2835AUX=m
+CONFIG_SPI_CADENCE_QUADSPI=y
CONFIG_SPI_DESIGNWARE=m
CONFIG_SPI_DW_DMA=y
CONFIG_SPI_DW_MMIO=m
@@ -487,6 +498,7 @@ CONFIG_SPI_ORION=y
CONFIG_SPI_PL022=y
CONFIG_SPI_ROCKCHIP=y
CONFIG_SPI_RPCIF=m
+CONFIG_SPI_RSPI=m
CONFIG_SPI_QCOM_QSPI=m
CONFIG_SPI_QUP=y
CONFIG_SPI_QCOM_GENI=m
@@ -495,8 +507,8 @@ CONFIG_SPI_SH_MSIOF=m
CONFIG_SPI_SUN6I=y
CONFIG_SPI_SPIDEV=m
CONFIG_SPMI=y
-CONFIG_PINCTRL_SINGLE=y
CONFIG_PINCTRL_MAX77620=y
+CONFIG_PINCTRL_SINGLE=y
CONFIG_PINCTRL_OWL=y
CONFIG_PINCTRL_S700=y
CONFIG_PINCTRL_S900=y
@@ -524,6 +536,7 @@ CONFIG_PINCTRL_SDM845=y
CONFIG_PINCTRL_SM8150=y
CONFIG_PINCTRL_SM8250=y
CONFIG_PINCTRL_SM8350=y
+CONFIG_PINCTRL_SM8450=y
CONFIG_PINCTRL_LPASS_LPI=m
CONFIG_GPIO_ALTERA=m
CONFIG_GPIO_DAVINCI=y
@@ -544,9 +557,6 @@ CONFIG_GPIO_PCA953X_IRQ=y
CONFIG_GPIO_BD9571MWV=m
CONFIG_GPIO_MAX77620=y
CONFIG_GPIO_SL28CPLD=m
-CONFIG_POWER_AVS=y
-CONFIG_QCOM_CPR=y
-CONFIG_ROCKCHIP_IODOMAIN=y
CONFIG_POWER_RESET_MSM=y
CONFIG_POWER_RESET_QCOM_PON=m
CONFIG_POWER_RESET_XGENE=y
@@ -554,12 +564,13 @@ CONFIG_POWER_RESET_SYSCON=y
CONFIG_SYSCON_REBOOT_MODE=y
CONFIG_BATTERY_SBS=m
CONFIG_BATTERY_BQ27XXX=y
-CONFIG_SENSORS_ARM_SCMI=y
CONFIG_BATTERY_MAX17042=m
CONFIG_CHARGER_BQ25890=m
CONFIG_CHARGER_BQ25980=m
+CONFIG_SENSORS_ARM_SCMI=y
CONFIG_SENSORS_ARM_SCPI=y
CONFIG_SENSORS_JC42=m
+CONFIG_SENSORS_LM75=m
CONFIG_SENSORS_LM90=m
CONFIG_SENSORS_PWM_FAN=m
CONFIG_SENSORS_RASPBERRYPI_HWMON=m
@@ -569,20 +580,21 @@ CONFIG_SENSORS_INA3221=m
CONFIG_THERMAL_GOV_POWER_ALLOCATOR=y
CONFIG_CPU_THERMAL=y
CONFIG_THERMAL_EMULATION=y
-CONFIG_QORIQ_THERMAL=m
-CONFIG_SUN8I_THERMAL=y
CONFIG_IMX_SC_THERMAL=m
CONFIG_IMX8MM_THERMAL=m
+CONFIG_QORIQ_THERMAL=m
+CONFIG_SUN8I_THERMAL=y
CONFIG_ROCKCHIP_THERMAL=m
CONFIG_RCAR_THERMAL=y
CONFIG_RCAR_GEN3_THERMAL=y
+CONFIG_RZG2L_THERMAL=y
CONFIG_ARMADA_THERMAL=y
CONFIG_BCM2711_THERMAL=m
CONFIG_BCM2835_THERMAL=m
CONFIG_BRCMSTB_THERMAL=m
CONFIG_EXYNOS_THERMAL=y
-CONFIG_TEGRA_BPMP_THERMAL=m
CONFIG_TEGRA_SOCTHERM=m
+CONFIG_TEGRA_BPMP_THERMAL=m
CONFIG_QCOM_TSENS=y
CONFIG_QCOM_SPMI_TEMP_ALARM=m
CONFIG_QCOM_LMH=m
@@ -591,8 +603,8 @@ CONFIG_WATCHDOG=y
CONFIG_SL28CPLD_WATCHDOG=m
CONFIG_ARM_SP805_WATCHDOG=y
CONFIG_ARM_SBSA_WATCHDOG=y
-CONFIG_ARM_SMC_WATCHDOG=y
CONFIG_S3C2410_WATCHDOG=y
+CONFIG_BCM7038_WDT=m
CONFIG_DW_WATCHDOG=y
CONFIG_SUNXI_WATCHDOG=m
CONFIG_IMX2_WDT=y
@@ -600,7 +612,9 @@ CONFIG_IMX_SC_WDT=m
CONFIG_QCOM_WDT=m
CONFIG_MESON_GXBB_WATCHDOG=m
CONFIG_MESON_WATCHDOG=m
+CONFIG_ARM_SMC_WATCHDOG=y
CONFIG_RENESAS_WDT=y
+CONFIG_RENESAS_RZG2LWDT=y
CONFIG_UNIPHIER_WATCHDOG=y
CONFIG_BCM2835_WDT=y
CONFIG_MFD_ALTERA_SYSMGR=y
@@ -652,16 +666,16 @@ CONFIG_MEDIA_CAMERA_SUPPORT=y
CONFIG_MEDIA_ANALOG_TV_SUPPORT=y
CONFIG_MEDIA_DIGITAL_TV_SUPPORT=y
CONFIG_MEDIA_SDR_SUPPORT=y
-CONFIG_MEDIA_CONTROLLER=y
-CONFIG_VIDEO_V4L2_SUBDEV_API=y
CONFIG_MEDIA_PLATFORM_SUPPORT=y
# CONFIG_DVB_NET is not set
CONFIG_MEDIA_USB_SUPPORT=y
CONFIG_USB_VIDEO_CLASS=m
CONFIG_V4L_PLATFORM_DRIVERS=y
+CONFIG_VIDEO_QCOM_CAMSS=m
CONFIG_VIDEO_RCAR_CSI2=m
CONFIG_VIDEO_RCAR_VIN=m
CONFIG_VIDEO_SUN6I_CSI=m
+CONFIG_VIDEO_RCAR_ISP=m
CONFIG_V4L_MEM2MEM_DRIVERS=y
CONFIG_VIDEO_SAMSUNG_S5P_JPEG=m
CONFIG_VIDEO_SAMSUNG_S5P_MFC=m
@@ -675,7 +689,6 @@ CONFIG_VIDEO_RCAR_DRIF=m
CONFIG_VIDEO_IMX219=m
CONFIG_VIDEO_OV5640=m
CONFIG_VIDEO_OV5645=m
-CONFIG_VIDEO_QCOM_CAMSS=m
CONFIG_DRM=m
CONFIG_DRM_I2C_NXP_TDA998X=m
CONFIG_DRM_MALI_DISPLAY=m
@@ -696,30 +709,30 @@ CONFIG_ROCKCHIP_INNO_HDMI=y
CONFIG_ROCKCHIP_LVDS=y
CONFIG_DRM_RCAR_DU=m
CONFIG_DRM_RCAR_DW_HDMI=m
+CONFIG_DRM_RCAR_MIPI_DSI=m
CONFIG_DRM_SUN4I=m
CONFIG_DRM_SUN6I_DSI=m
CONFIG_DRM_SUN8I_DW_HDMI=m
CONFIG_DRM_SUN8I_MIXER=m
CONFIG_DRM_MSM=m
CONFIG_DRM_TEGRA=m
+CONFIG_DRM_PANEL_BOE_TV101WUM_NL6=m
CONFIG_DRM_PANEL_LVDS=m
CONFIG_DRM_PANEL_SIMPLE=m
CONFIG_DRM_PANEL_EDP=m
-CONFIG_DRM_PANEL_BOE_TV101WUM_NL6=m
CONFIG_DRM_PANEL_MANTIX_MLAF057WE51=m
CONFIG_DRM_PANEL_RAYDIUM_RM67191=m
CONFIG_DRM_PANEL_SITRONIX_ST7703=m
CONFIG_DRM_PANEL_TRULY_NT35597_WQXGA=m
-CONFIG_DRM_DISPLAY_CONNECTOR=m
CONFIG_DRM_LONTIUM_LT8912B=m
-CONFIG_DRM_NWL_MIPI_DSI=m
CONFIG_DRM_LONTIUM_LT9611=m
+CONFIG_DRM_LONTIUM_LT9611UXC=m
+CONFIG_DRM_NWL_MIPI_DSI=m
CONFIG_DRM_PARADE_PS8640=m
CONFIG_DRM_SII902X=m
CONFIG_DRM_SIMPLE_BRIDGE=m
CONFIG_DRM_THINE_THC63LVD1024=m
CONFIG_DRM_TI_SN65DSI86=m
-CONFIG_DRM_LONTIUM_LT9611UXC=m
CONFIG_DRM_I2C_ADV7511=m
CONFIG_DRM_I2C_ADV7511_AUDIO=y
CONFIG_DRM_DW_HDMI_AHB_AUDIO=m
@@ -750,15 +763,14 @@ CONFIG_SND_HDA_TEGRA=m
CONFIG_SND_HDA_CODEC_HDMI=m
CONFIG_SND_SOC=y
CONFIG_SND_BCM2835_SOC_I2S=m
-CONFIG_SND_SOC_FSL_SAI=m
CONFIG_SND_SOC_FSL_ASRC=m
CONFIG_SND_SOC_FSL_MICFIL=m
CONFIG_SND_SOC_FSL_EASRC=m
CONFIG_SND_IMX_SOC=m
CONFIG_SND_SOC_IMX_SGTL5000=m
CONFIG_SND_SOC_IMX_SPDIF=m
-CONFIG_SND_SOC_IMX_AUDMIX=m
CONFIG_SND_SOC_FSL_ASOC_CARD=m
+CONFIG_SND_SOC_IMX_AUDMIX=m
CONFIG_SND_MESON_AXG_SOUND_CARD=m
CONFIG_SND_MESON_GX_SOUND_CARD=m
CONFIG_SND_SOC_QCOM=m
@@ -805,18 +817,18 @@ CONFIG_SND_SOC_WM8960=m
CONFIG_SND_SOC_WM8962=m
CONFIG_SND_SOC_WM8978=m
CONFIG_SND_SOC_WSA881X=m
+CONFIG_SND_SOC_NAU8822=m
CONFIG_SND_SOC_LPASS_WSA_MACRO=m
CONFIG_SND_SOC_LPASS_VA_MACRO=m
CONFIG_SND_SIMPLE_CARD=m
CONFIG_SND_AUDIO_GRAPH_CARD=m
+CONFIG_SND_AUDIO_GRAPH_CARD2=m
CONFIG_HID_MULTITOUCH=m
CONFIG_I2C_HID_ACPI=m
CONFIG_I2C_HID_OF=m
-CONFIG_USB_CONN_GPIO=m
CONFIG_USB=y
CONFIG_USB_OTG=y
CONFIG_USB_XHCI_HCD=y
-CONFIG_USB_XHCI_PCI=m
CONFIG_USB_XHCI_PCI_RENESAS=m
CONFIG_USB_XHCI_TEGRA=y
CONFIG_USB_EHCI_HCD=y
@@ -829,6 +841,10 @@ CONFIG_USB_RENESAS_USBHS_HCD=m
CONFIG_USB_RENESAS_USBHS=m
CONFIG_USB_ACM=m
CONFIG_USB_STORAGE=y
+CONFIG_USB_CDNS_SUPPORT=m
+CONFIG_USB_CDNS3=m
+CONFIG_USB_CDNS3_GADGET=y
+CONFIG_USB_CDNS3_HOST=y
CONFIG_USB_MTU3=y
CONFIG_USB_MUSB_HDRC=y
CONFIG_USB_MUSB_SUNXI=y
@@ -863,8 +879,8 @@ CONFIG_TYPEC=m
CONFIG_TYPEC_TCPM=m
CONFIG_TYPEC_TCPCI=m
CONFIG_TYPEC_FUSB302=m
-CONFIG_TYPEC_HD3SS3220=m
CONFIG_TYPEC_TPS6598X=m
+CONFIG_TYPEC_HD3SS3220=m
CONFIG_MMC=y
CONFIG_MMC_BLOCK_MINORS=32
CONFIG_MMC_ARMMMCI=y
@@ -935,16 +951,18 @@ CONFIG_RTC_DRV_TEGRA=y
CONFIG_RTC_DRV_SNVS=m
CONFIG_RTC_DRV_IMX_SC=m
CONFIG_RTC_DRV_XGENE=y
+CONFIG_RTC_DRV_MT6397=m
CONFIG_DMADEVICES=y
CONFIG_DMA_BCM2835=y
CONFIG_DMA_SUN6I=m
CONFIG_FSL_EDMA=y
-CONFIG_IMX_SDMA=y
+CONFIG_IMX_SDMA=m
CONFIG_K3_DMA=y
CONFIG_MV_XOR=y
CONFIG_MV_XOR_V2=y
CONFIG_OWL_DMA=y
CONFIG_PL330_DMA=y
+CONFIG_TEGRA186_GPC_DMA=m
CONFIG_TEGRA20_APB_DMA=y
CONFIG_TEGRA210_ADMA=m
CONFIG_QCOM_BAM_DMA=y
@@ -962,7 +980,6 @@ CONFIG_VIRTIO_BALLOON=y
CONFIG_VIRTIO_MMIO=y
CONFIG_XEN_GNTDEV=y
CONFIG_XEN_GRANT_DEV_ALLOC=y
-CONFIG_MFD_CROS_EC_DEV=y
CONFIG_STAGING=y
CONFIG_STAGING_MEDIA=y
CONFIG_VIDEO_HANTRO=m
@@ -972,15 +989,14 @@ CONFIG_CROS_EC=y
CONFIG_CROS_EC_I2C=y
CONFIG_CROS_EC_SPI=y
CONFIG_CROS_EC_CHARDEV=m
-CONFIG_COMMON_CLK_SCMI=y
CONFIG_COMMON_CLK_RK808=y
+CONFIG_COMMON_CLK_SCMI=y
CONFIG_COMMON_CLK_SCPI=y
CONFIG_COMMON_CLK_CS2000_CP=y
CONFIG_COMMON_CLK_FSL_SAI=y
CONFIG_COMMON_CLK_S2MPS11=y
CONFIG_COMMON_CLK_PWM=y
CONFIG_COMMON_CLK_VC5=y
-CONFIG_COMMON_CLK_ZYNQMP=y
CONFIG_COMMON_CLK_BD718XX=m
CONFIG_CLK_RASPBERRYPI=m
CONFIG_CLK_IMX8MM=y
@@ -996,8 +1012,8 @@ CONFIG_QCOM_CLK_APCS_MSM8916=y
CONFIG_QCOM_CLK_APCC_MSM8996=y
CONFIG_QCOM_CLK_SMD_RPM=y
CONFIG_QCOM_CLK_RPMH=y
-CONFIG_IPQ_GCC_8074=y
CONFIG_IPQ_GCC_6018=y
+CONFIG_IPQ_GCC_8074=y
CONFIG_MSM_GCC_8916=y
CONFIG_MSM_GCC_8994=y
CONFIG_MSM_MMCC_8996=y
@@ -1006,21 +1022,19 @@ CONFIG_QCS_GCC_404=y
CONFIG_SC_GCC_7180=y
CONFIG_SC_GCC_7280=y
CONFIG_SDM_CAMCC_845=m
-CONFIG_SDM_GCC_845=y
CONFIG_SDM_GPUCC_845=y
CONFIG_SDM_VIDEOCC_845=y
CONFIG_SDM_DISPCC_845=y
-CONFIG_SM_GCC_8150=y
-CONFIG_SM_GCC_8250=y
CONFIG_SM_GCC_8350=y
+CONFIG_SM_GCC_8450=y
CONFIG_SM_GPUCC_8150=y
CONFIG_SM_GPUCC_8250=y
-CONFIG_SM_DISPCC_8250=y
CONFIG_QCOM_HFPLL=y
CONFIG_CLK_GFM_LPASS_SM8250=m
CONFIG_CLK_RCAR_USB2_CLOCK_SEL=y
CONFIG_HWSPINLOCK=y
CONFIG_HWSPINLOCK_QCOM=y
+CONFIG_RENESAS_OSTM=y
CONFIG_ARM_MHU=y
CONFIG_IMX_MBOX=y
CONFIG_PLATFORM_MHU=y
@@ -1049,9 +1063,11 @@ CONFIG_RASPBERRYPI_POWER=y
CONFIG_FSL_DPAA=y
CONFIG_FSL_MC_DPIO=y
CONFIG_FSL_RCPM=y
+CONFIG_MTK_DEVAPC=m
CONFIG_MTK_PMIC_WRAP=y
CONFIG_QCOM_AOSS_QMP=y
CONFIG_QCOM_COMMAND_DB=y
+CONFIG_QCOM_CPR=y
CONFIG_QCOM_GENI_SE=y
CONFIG_QCOM_RMTFS_MEM=m
CONFIG_QCOM_RPMH=y
@@ -1062,25 +1078,26 @@ CONFIG_QCOM_SMD_RPM=y
CONFIG_QCOM_SMP2P=y
CONFIG_QCOM_SMSM=y
CONFIG_QCOM_SOCINFO=m
-CONFIG_QCOM_WCNSS_CTRL=m
CONFIG_QCOM_STATS=m
+CONFIG_QCOM_WCNSS_CTRL=m
CONFIG_QCOM_APR=m
-CONFIG_ARCH_R8A774A1=y
-CONFIG_ARCH_R8A774B1=y
-CONFIG_ARCH_R8A774C0=y
-CONFIG_ARCH_R8A774E1=y
+CONFIG_ARCH_R8A77995=y
+CONFIG_ARCH_R8A77990=y
CONFIG_ARCH_R8A77950=y
CONFIG_ARCH_R8A77951=y
+CONFIG_ARCH_R8A77965=y
CONFIG_ARCH_R8A77960=y
CONFIG_ARCH_R8A77961=y
-CONFIG_ARCH_R8A77965=y
-CONFIG_ARCH_R8A77970=y
+CONFIG_ARCH_R8A779F0=y
CONFIG_ARCH_R8A77980=y
-CONFIG_ARCH_R8A77990=y
-CONFIG_ARCH_R8A77995=y
+CONFIG_ARCH_R8A77970=y
CONFIG_ARCH_R8A779A0=y
-CONFIG_ARCH_R8A779F0=y
+CONFIG_ARCH_R8A774C0=y
+CONFIG_ARCH_R8A774E1=y
+CONFIG_ARCH_R8A774A1=y
+CONFIG_ARCH_R8A774B1=y
CONFIG_ARCH_R9A07G044=y
+CONFIG_ROCKCHIP_IODOMAIN=y
CONFIG_ROCKCHIP_PM_DOMAINS=y
CONFIG_ARCH_TEGRA_132_SOC=y
CONFIG_ARCH_TEGRA_210_SOC=y
@@ -1101,6 +1118,7 @@ CONFIG_QCOM_SPMI_VADC=m
CONFIG_QCOM_SPMI_ADC5=m
CONFIG_ROCKCHIP_SARADC=m
CONFIG_RZG2L_ADC=m
+CONFIG_TI_ADS1015=m
CONFIG_IIO_CROS_EC_SENSORS_CORE=m
CONFIG_IIO_CROS_EC_SENSORS=m
CONFIG_IIO_ST_LSM6DSX=m
@@ -1112,6 +1130,7 @@ CONFIG_IIO_CROS_EC_BARO=m
CONFIG_MPL3115=m
CONFIG_PWM=y
CONFIG_PWM_BCM2835=m
+CONFIG_PWM_BRCMSTB=m
CONFIG_PWM_CROS_EC=m
CONFIG_PWM_IMX27=m
CONFIG_PWM_MESON=m
@@ -1134,7 +1153,9 @@ CONFIG_RESET_RZG2L_USBPHY_CTRL=y
CONFIG_RESET_TI_SCI=y
CONFIG_PHY_XGENE=y
CONFIG_PHY_SUN4I_USB=y
+CONFIG_PHY_CADENCE_SIERRA=m
CONFIG_PHY_MIXEL_MIPI_DPHY=m
+CONFIG_PHY_FSL_IMX8M_PCIE=y
CONFIG_PHY_HI6220_USB=y
CONFIG_PHY_HISTB_COMBPHY=y
CONFIG_PHY_HISI_INNO_USB2=y
@@ -1157,21 +1178,25 @@ CONFIG_PHY_SAMSUNG_UFS=y
CONFIG_PHY_UNIPHIER_USB2=y
CONFIG_PHY_UNIPHIER_USB3=y
CONFIG_PHY_TEGRA_XUSB=y
+CONFIG_PHY_AM654_SERDES=m
+CONFIG_PHY_J721E_WIZ=m
CONFIG_ARM_SMMU_V3_PMU=m
CONFIG_FSL_IMX8_DDR_PMU=m
-CONFIG_HISI_PMU=y
CONFIG_QCOM_L2_PMU=y
CONFIG_QCOM_L3_PMU=y
+CONFIG_HISI_PMU=y
CONFIG_NVMEM_IMX_OCOTP=y
CONFIG_NVMEM_IMX_OCOTP_SCU=y
-CONFIG_QCOM_QFPROM=y
CONFIG_MTK_EFUSE=y
+CONFIG_QCOM_QFPROM=y
CONFIG_ROCKCHIP_EFUSE=y
CONFIG_NVMEM_SUNXI_SID=y
CONFIG_UNIPHIER_EFUSE=y
CONFIG_MESON_EFUSE=m
CONFIG_NVMEM_RMEM=m
+CONFIG_NVMEM_LAYERSCAPE_SFP=m
CONFIG_FPGA=y
+CONFIG_FPGA_MGR_ALTERA_CVP=m
CONFIG_FPGA_MGR_STRATIX10_SOC=m
CONFIG_FPGA_BRIDGE=m
CONFIG_ALTERA_FREEZE_BRIDGE=m
@@ -1179,10 +1204,10 @@ CONFIG_FPGA_REGION=m
CONFIG_OF_FPGA_REGION=m
CONFIG_TEE=y
CONFIG_OPTEE=y
+CONFIG_MUX_MMIO=y
CONFIG_SLIMBUS=m
CONFIG_SLIM_QCOM_CTRL=m
CONFIG_SLIM_QCOM_NGD_CTRL=m
-CONFIG_MUX_MMIO=y
CONFIG_INTERCONNECT=y
CONFIG_INTERCONNECT_IMX=m
CONFIG_INTERCONNECT_IMX8MM=m
@@ -1196,6 +1221,7 @@ CONFIG_INTERCONNECT_QCOM_SDM845=y
CONFIG_INTERCONNECT_QCOM_SM8150=m
CONFIG_INTERCONNECT_QCOM_SM8250=m
CONFIG_INTERCONNECT_QCOM_SM8350=m
+CONFIG_INTERCONNECT_QCOM_SM8450=m
CONFIG_EXT2_FS=y
CONFIG_EXT3_FS=y
CONFIG_EXT4_FS_POSIX_ACL=y
diff --git a/arch/arm64/crypto/Kconfig b/arch/arm64/crypto/Kconfig
index addfa413650b..2a965aa0188d 100644
--- a/arch/arm64/crypto/Kconfig
+++ b/arch/arm64/crypto/Kconfig
@@ -45,7 +45,7 @@ config CRYPTO_SM3_ARM64_CE
tristate "SM3 digest algorithm (ARMv8.2 Crypto Extensions)"
depends on KERNEL_MODE_NEON
select CRYPTO_HASH
- select CRYPTO_SM3
+ select CRYPTO_LIB_SM3
config CRYPTO_SM4_ARM64_CE
tristate "SM4 symmetric cipher (ARMv8.2 Crypto Extensions)"
diff --git a/arch/arm64/crypto/aes-glue.c b/arch/arm64/crypto/aes-glue.c
index 30b7cc6a7079..561dd2332571 100644
--- a/arch/arm64/crypto/aes-glue.c
+++ b/arch/arm64/crypto/aes-glue.c
@@ -24,7 +24,6 @@
#ifdef USE_V8_CRYPTO_EXTENSIONS
#define MODE "ce"
#define PRIO 300
-#define STRIDE 5
#define aes_expandkey ce_aes_expandkey
#define aes_ecb_encrypt ce_aes_ecb_encrypt
#define aes_ecb_decrypt ce_aes_ecb_decrypt
@@ -42,7 +41,6 @@ MODULE_DESCRIPTION("AES-ECB/CBC/CTR/XTS using ARMv8 Crypto Extensions");
#else
#define MODE "neon"
#define PRIO 200
-#define STRIDE 4
#define aes_ecb_encrypt neon_aes_ecb_encrypt
#define aes_ecb_decrypt neon_aes_ecb_decrypt
#define aes_cbc_encrypt neon_aes_cbc_encrypt
@@ -89,7 +87,7 @@ asmlinkage void aes_cbc_cts_decrypt(u8 out[], u8 const in[], u32 const rk[],
int rounds, int bytes, u8 const iv[]);
asmlinkage void aes_ctr_encrypt(u8 out[], u8 const in[], u32 const rk[],
- int rounds, int bytes, u8 ctr[], u8 finalbuf[]);
+ int rounds, int bytes, u8 ctr[]);
asmlinkage void aes_xts_encrypt(u8 out[], u8 const in[], u32 const rk1[],
int rounds, int bytes, u32 const rk2[], u8 iv[],
@@ -458,26 +456,21 @@ static int __maybe_unused ctr_encrypt(struct skcipher_request *req)
unsigned int nbytes = walk.nbytes;
u8 *dst = walk.dst.virt.addr;
u8 buf[AES_BLOCK_SIZE];
- unsigned int tail;
if (unlikely(nbytes < AES_BLOCK_SIZE))
- src = memcpy(buf, src, nbytes);
+ src = dst = memcpy(buf + sizeof(buf) - nbytes,
+ src, nbytes);
else if (nbytes < walk.total)
nbytes &= ~(AES_BLOCK_SIZE - 1);
kernel_neon_begin();
aes_ctr_encrypt(dst, src, ctx->key_enc, rounds, nbytes,
- walk.iv, buf);
+ walk.iv);
kernel_neon_end();
- tail = nbytes % (STRIDE * AES_BLOCK_SIZE);
- if (tail > 0 && tail < AES_BLOCK_SIZE)
- /*
- * The final partial block could not be returned using
- * an overlapping store, so it was passed via buf[]
- * instead.
- */
- memcpy(dst + nbytes - tail, buf, tail);
+ if (unlikely(nbytes < AES_BLOCK_SIZE))
+ memcpy(walk.dst.virt.addr,
+ buf + sizeof(buf) - nbytes, nbytes);
err = skcipher_walk_done(&walk, walk.nbytes - nbytes);
}
@@ -983,6 +976,7 @@ module_cpu_feature_match(AES, aes_init);
module_init(aes_init);
EXPORT_SYMBOL(neon_aes_ecb_encrypt);
EXPORT_SYMBOL(neon_aes_cbc_encrypt);
+EXPORT_SYMBOL(neon_aes_ctr_encrypt);
EXPORT_SYMBOL(neon_aes_xts_encrypt);
EXPORT_SYMBOL(neon_aes_xts_decrypt);
#endif
diff --git a/arch/arm64/crypto/aes-modes.S b/arch/arm64/crypto/aes-modes.S
index ff01f0167ba2..dc35eb0245c5 100644
--- a/arch/arm64/crypto/aes-modes.S
+++ b/arch/arm64/crypto/aes-modes.S
@@ -321,7 +321,7 @@ AES_FUNC_END(aes_cbc_cts_decrypt)
/*
* aes_ctr_encrypt(u8 out[], u8 const in[], u8 const rk[], int rounds,
- * int bytes, u8 ctr[], u8 finalbuf[])
+ * int bytes, u8 ctr[])
*/
AES_FUNC_START(aes_ctr_encrypt)
@@ -414,8 +414,8 @@ ST5( st1 {v4.16b}, [x0], #16 )
.Lctrtail:
/* XOR up to MAX_STRIDE * 16 - 1 bytes of in/output with v0 ... v3/v4 */
mov x16, #16
- ands x13, x4, #0xf
- csel x13, x13, x16, ne
+ ands x6, x4, #0xf
+ csel x13, x6, x16, ne
ST5( cmp w4, #64 - (MAX_STRIDE << 4) )
ST5( csel x14, x16, xzr, gt )
@@ -424,10 +424,10 @@ ST5( csel x14, x16, xzr, gt )
cmp w4, #32 - (MAX_STRIDE << 4)
csel x16, x16, xzr, gt
cmp w4, #16 - (MAX_STRIDE << 4)
- ble .Lctrtail1x
adr_l x12, .Lcts_permute_table
add x12, x12, x13
+ ble .Lctrtail1x
ST5( ld1 {v5.16b}, [x1], x14 )
ld1 {v6.16b}, [x1], x15
@@ -462,11 +462,19 @@ ST5( st1 {v5.16b}, [x0], x14 )
b .Lctrout
.Lctrtail1x:
- csel x0, x0, x6, eq // use finalbuf if less than a full block
+ sub x7, x6, #16
+ csel x6, x6, x7, eq
+ add x1, x1, x6
+ add x0, x0, x6
ld1 {v5.16b}, [x1]
+ ld1 {v6.16b}, [x0]
ST5( mov v3.16b, v4.16b )
encrypt_block v3, w3, x2, x8, w7
+ ld1 {v10.16b-v11.16b}, [x12]
+ tbl v3.16b, {v3.16b}, v10.16b
+ sshr v11.16b, v11.16b, #7
eor v5.16b, v5.16b, v3.16b
+ bif v5.16b, v6.16b, v11.16b
st1 {v5.16b}, [x0]
b .Lctrout
AES_FUNC_END(aes_ctr_encrypt)
diff --git a/arch/arm64/crypto/aes-neonbs-core.S b/arch/arm64/crypto/aes-neonbs-core.S
index a3405b8c344b..d427f4556b6e 100644
--- a/arch/arm64/crypto/aes-neonbs-core.S
+++ b/arch/arm64/crypto/aes-neonbs-core.S
@@ -735,119 +735,67 @@ SYM_FUNC_END(aesbs_cbc_decrypt)
* int blocks, u8 iv[])
*/
SYM_FUNC_START_LOCAL(__xts_crypt8)
- mov x6, #1
- lsl x6, x6, x23
- subs w23, w23, #8
- csel x23, x23, xzr, pl
- csel x6, x6, xzr, mi
+ movi v18.2s, #0x1
+ movi v19.2s, #0x87
+ uzp1 v18.4s, v18.4s, v19.4s
+
+ ld1 {v0.16b-v3.16b}, [x1], #64
+ ld1 {v4.16b-v7.16b}, [x1], #64
+
+ next_tweak v26, v25, v18, v19
+ next_tweak v27, v26, v18, v19
+ next_tweak v28, v27, v18, v19
+ next_tweak v29, v28, v18, v19
+ next_tweak v30, v29, v18, v19
+ next_tweak v31, v30, v18, v19
+ next_tweak v16, v31, v18, v19
+ next_tweak v17, v16, v18, v19
- ld1 {v0.16b}, [x20], #16
- next_tweak v26, v25, v30, v31
eor v0.16b, v0.16b, v25.16b
- tbnz x6, #1, 0f
-
- ld1 {v1.16b}, [x20], #16
- next_tweak v27, v26, v30, v31
eor v1.16b, v1.16b, v26.16b
- tbnz x6, #2, 0f
-
- ld1 {v2.16b}, [x20], #16
- next_tweak v28, v27, v30, v31
eor v2.16b, v2.16b, v27.16b
- tbnz x6, #3, 0f
-
- ld1 {v3.16b}, [x20], #16
- next_tweak v29, v28, v30, v31
eor v3.16b, v3.16b, v28.16b
- tbnz x6, #4, 0f
-
- ld1 {v4.16b}, [x20], #16
- str q29, [sp, #.Lframe_local_offset]
eor v4.16b, v4.16b, v29.16b
- next_tweak v29, v29, v30, v31
- tbnz x6, #5, 0f
-
- ld1 {v5.16b}, [x20], #16
- str q29, [sp, #.Lframe_local_offset + 16]
- eor v5.16b, v5.16b, v29.16b
- next_tweak v29, v29, v30, v31
- tbnz x6, #6, 0f
-
- ld1 {v6.16b}, [x20], #16
- str q29, [sp, #.Lframe_local_offset + 32]
- eor v6.16b, v6.16b, v29.16b
- next_tweak v29, v29, v30, v31
- tbnz x6, #7, 0f
+ eor v5.16b, v5.16b, v30.16b
+ eor v6.16b, v6.16b, v31.16b
+ eor v7.16b, v7.16b, v16.16b
- ld1 {v7.16b}, [x20], #16
- str q29, [sp, #.Lframe_local_offset + 48]
- eor v7.16b, v7.16b, v29.16b
- next_tweak v29, v29, v30, v31
+ stp q16, q17, [sp, #16]
-0: mov bskey, x21
- mov rounds, x22
+ mov bskey, x2
+ mov rounds, x3
br x16
SYM_FUNC_END(__xts_crypt8)
.macro __xts_crypt, do8, o0, o1, o2, o3, o4, o5, o6, o7
- frame_push 6, 64
-
- mov x19, x0
- mov x20, x1
- mov x21, x2
- mov x22, x3
- mov x23, x4
- mov x24, x5
+ stp x29, x30, [sp, #-48]!
+ mov x29, sp
- movi v30.2s, #0x1
- movi v25.2s, #0x87
- uzp1 v30.4s, v30.4s, v25.4s
- ld1 {v25.16b}, [x24]
+ ld1 {v25.16b}, [x5]
-99: adr x16, \do8
+0: adr x16, \do8
bl __xts_crypt8
- ldp q16, q17, [sp, #.Lframe_local_offset]
- ldp q18, q19, [sp, #.Lframe_local_offset + 32]
+ eor v16.16b, \o0\().16b, v25.16b
+ eor v17.16b, \o1\().16b, v26.16b
+ eor v18.16b, \o2\().16b, v27.16b
+ eor v19.16b, \o3\().16b, v28.16b
- eor \o0\().16b, \o0\().16b, v25.16b
- eor \o1\().16b, \o1\().16b, v26.16b
- eor \o2\().16b, \o2\().16b, v27.16b
- eor \o3\().16b, \o3\().16b, v28.16b
+ ldp q24, q25, [sp, #16]
- st1 {\o0\().16b}, [x19], #16
- mov v25.16b, v26.16b
- tbnz x6, #1, 1f
- st1 {\o1\().16b}, [x19], #16
- mov v25.16b, v27.16b
- tbnz x6, #2, 1f
- st1 {\o2\().16b}, [x19], #16
- mov v25.16b, v28.16b
- tbnz x6, #3, 1f
- st1 {\o3\().16b}, [x19], #16
- mov v25.16b, v29.16b
- tbnz x6, #4, 1f
+ eor v20.16b, \o4\().16b, v29.16b
+ eor v21.16b, \o5\().16b, v30.16b
+ eor v22.16b, \o6\().16b, v31.16b
+ eor v23.16b, \o7\().16b, v24.16b
- eor \o4\().16b, \o4\().16b, v16.16b
- eor \o5\().16b, \o5\().16b, v17.16b
- eor \o6\().16b, \o6\().16b, v18.16b
- eor \o7\().16b, \o7\().16b, v19.16b
+ st1 {v16.16b-v19.16b}, [x0], #64
+ st1 {v20.16b-v23.16b}, [x0], #64
- st1 {\o4\().16b}, [x19], #16
- tbnz x6, #5, 1f
- st1 {\o5\().16b}, [x19], #16
- tbnz x6, #6, 1f
- st1 {\o6\().16b}, [x19], #16
- tbnz x6, #7, 1f
- st1 {\o7\().16b}, [x19], #16
+ subs x4, x4, #8
+ b.gt 0b
- cbz x23, 1f
- st1 {v25.16b}, [x24]
-
- b 99b
-
-1: st1 {v25.16b}, [x24]
- frame_pop
+ st1 {v25.16b}, [x5]
+ ldp x29, x30, [sp], #48
ret
.endm
@@ -869,133 +817,51 @@ SYM_FUNC_END(aesbs_xts_decrypt)
/*
* aesbs_ctr_encrypt(u8 out[], u8 const in[], u8 const rk[],
- * int rounds, int blocks, u8 iv[], u8 final[])
+ * int rounds, int blocks, u8 iv[])
*/
SYM_FUNC_START(aesbs_ctr_encrypt)
- frame_push 8
-
- mov x19, x0
- mov x20, x1
- mov x21, x2
- mov x22, x3
- mov x23, x4
- mov x24, x5
- mov x25, x6
+ stp x29, x30, [sp, #-16]!
+ mov x29, sp
- cmp x25, #0
- cset x26, ne
- add x23, x23, x26 // do one extra block if final
-
- ldp x7, x8, [x24]
- ld1 {v0.16b}, [x24]
+ ldp x7, x8, [x5]
+ ld1 {v0.16b}, [x5]
CPU_LE( rev x7, x7 )
CPU_LE( rev x8, x8 )
adds x8, x8, #1
adc x7, x7, xzr
-99: mov x9, #1
- lsl x9, x9, x23
- subs w23, w23, #8
- csel x23, x23, xzr, pl
- csel x9, x9, xzr, le
-
- tbnz x9, #1, 0f
- next_ctr v1
- tbnz x9, #2, 0f
+0: next_ctr v1
next_ctr v2
- tbnz x9, #3, 0f
next_ctr v3
- tbnz x9, #4, 0f
next_ctr v4
- tbnz x9, #5, 0f
next_ctr v5
- tbnz x9, #6, 0f
next_ctr v6
- tbnz x9, #7, 0f
next_ctr v7
-0: mov bskey, x21
- mov rounds, x22
+ mov bskey, x2
+ mov rounds, x3
bl aesbs_encrypt8
- lsr x9, x9, x26 // disregard the extra block
- tbnz x9, #0, 0f
-
- ld1 {v8.16b}, [x20], #16
- eor v0.16b, v0.16b, v8.16b
- st1 {v0.16b}, [x19], #16
- tbnz x9, #1, 1f
+ ld1 { v8.16b-v11.16b}, [x1], #64
+ ld1 {v12.16b-v15.16b}, [x1], #64
- ld1 {v9.16b}, [x20], #16
- eor v1.16b, v1.16b, v9.16b
- st1 {v1.16b}, [x19], #16
- tbnz x9, #2, 2f
+ eor v8.16b, v0.16b, v8.16b
+ eor v9.16b, v1.16b, v9.16b
+ eor v10.16b, v4.16b, v10.16b
+ eor v11.16b, v6.16b, v11.16b
+ eor v12.16b, v3.16b, v12.16b
+ eor v13.16b, v7.16b, v13.16b
+ eor v14.16b, v2.16b, v14.16b
+ eor v15.16b, v5.16b, v15.16b
- ld1 {v10.16b}, [x20], #16
- eor v4.16b, v4.16b, v10.16b
- st1 {v4.16b}, [x19], #16
- tbnz x9, #3, 3f
+ st1 { v8.16b-v11.16b}, [x0], #64
+ st1 {v12.16b-v15.16b}, [x0], #64
- ld1 {v11.16b}, [x20], #16
- eor v6.16b, v6.16b, v11.16b
- st1 {v6.16b}, [x19], #16
- tbnz x9, #4, 4f
-
- ld1 {v12.16b}, [x20], #16
- eor v3.16b, v3.16b, v12.16b
- st1 {v3.16b}, [x19], #16
- tbnz x9, #5, 5f
-
- ld1 {v13.16b}, [x20], #16
- eor v7.16b, v7.16b, v13.16b
- st1 {v7.16b}, [x19], #16
- tbnz x9, #6, 6f
+ next_ctr v0
+ subs x4, x4, #8
+ b.gt 0b
- ld1 {v14.16b}, [x20], #16
- eor v2.16b, v2.16b, v14.16b
- st1 {v2.16b}, [x19], #16
- tbnz x9, #7, 7f
-
- ld1 {v15.16b}, [x20], #16
- eor v5.16b, v5.16b, v15.16b
- st1 {v5.16b}, [x19], #16
-
-8: next_ctr v0
- st1 {v0.16b}, [x24]
- cbz x23, .Lctr_done
-
- b 99b
-
-.Lctr_done:
- frame_pop
+ st1 {v0.16b}, [x5]
+ ldp x29, x30, [sp], #16
ret
-
- /*
- * If we are handling the tail of the input (x6 != NULL), return the
- * final keystream block back to the caller.
- */
-0: cbz x25, 8b
- st1 {v0.16b}, [x25]
- b 8b
-1: cbz x25, 8b
- st1 {v1.16b}, [x25]
- b 8b
-2: cbz x25, 8b
- st1 {v4.16b}, [x25]
- b 8b
-3: cbz x25, 8b
- st1 {v6.16b}, [x25]
- b 8b
-4: cbz x25, 8b
- st1 {v3.16b}, [x25]
- b 8b
-5: cbz x25, 8b
- st1 {v7.16b}, [x25]
- b 8b
-6: cbz x25, 8b
- st1 {v2.16b}, [x25]
- b 8b
-7: cbz x25, 8b
- st1 {v5.16b}, [x25]
- b 8b
SYM_FUNC_END(aesbs_ctr_encrypt)
diff --git a/arch/arm64/crypto/aes-neonbs-glue.c b/arch/arm64/crypto/aes-neonbs-glue.c
index 8df6ad8cb09d..bac4cabef607 100644
--- a/arch/arm64/crypto/aes-neonbs-glue.c
+++ b/arch/arm64/crypto/aes-neonbs-glue.c
@@ -34,7 +34,7 @@ asmlinkage void aesbs_cbc_decrypt(u8 out[], u8 const in[], u8 const rk[],
int rounds, int blocks, u8 iv[]);
asmlinkage void aesbs_ctr_encrypt(u8 out[], u8 const in[], u8 const rk[],
- int rounds, int blocks, u8 iv[], u8 final[]);
+ int rounds, int blocks, u8 iv[]);
asmlinkage void aesbs_xts_encrypt(u8 out[], u8 const in[], u8 const rk[],
int rounds, int blocks, u8 iv[]);
@@ -46,6 +46,8 @@ asmlinkage void neon_aes_ecb_encrypt(u8 out[], u8 const in[], u32 const rk[],
int rounds, int blocks);
asmlinkage void neon_aes_cbc_encrypt(u8 out[], u8 const in[], u32 const rk[],
int rounds, int blocks, u8 iv[]);
+asmlinkage void neon_aes_ctr_encrypt(u8 out[], u8 const in[], u32 const rk[],
+ int rounds, int bytes, u8 ctr[]);
asmlinkage void neon_aes_xts_encrypt(u8 out[], u8 const in[],
u32 const rk1[], int rounds, int bytes,
u32 const rk2[], u8 iv[], int first);
@@ -58,7 +60,7 @@ struct aesbs_ctx {
int rounds;
} __aligned(AES_BLOCK_SIZE);
-struct aesbs_cbc_ctx {
+struct aesbs_cbc_ctr_ctx {
struct aesbs_ctx key;
u32 enc[AES_MAX_KEYLENGTH_U32];
};
@@ -128,10 +130,10 @@ static int ecb_decrypt(struct skcipher_request *req)
return __ecb_crypt(req, aesbs_ecb_decrypt);
}
-static int aesbs_cbc_setkey(struct crypto_skcipher *tfm, const u8 *in_key,
+static int aesbs_cbc_ctr_setkey(struct crypto_skcipher *tfm, const u8 *in_key,
unsigned int key_len)
{
- struct aesbs_cbc_ctx *ctx = crypto_skcipher_ctx(tfm);
+ struct aesbs_cbc_ctr_ctx *ctx = crypto_skcipher_ctx(tfm);
struct crypto_aes_ctx rk;
int err;
@@ -154,7 +156,7 @@ static int aesbs_cbc_setkey(struct crypto_skcipher *tfm, const u8 *in_key,
static int cbc_encrypt(struct skcipher_request *req)
{
struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
- struct aesbs_cbc_ctx *ctx = crypto_skcipher_ctx(tfm);
+ struct aesbs_cbc_ctr_ctx *ctx = crypto_skcipher_ctx(tfm);
struct skcipher_walk walk;
int err;
@@ -177,7 +179,7 @@ static int cbc_encrypt(struct skcipher_request *req)
static int cbc_decrypt(struct skcipher_request *req)
{
struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
- struct aesbs_cbc_ctx *ctx = crypto_skcipher_ctx(tfm);
+ struct aesbs_cbc_ctr_ctx *ctx = crypto_skcipher_ctx(tfm);
struct skcipher_walk walk;
int err;
@@ -205,40 +207,32 @@ static int cbc_decrypt(struct skcipher_request *req)
static int ctr_encrypt(struct skcipher_request *req)
{
struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
- struct aesbs_ctx *ctx = crypto_skcipher_ctx(tfm);
+ struct aesbs_cbc_ctr_ctx *ctx = crypto_skcipher_ctx(tfm);
struct skcipher_walk walk;
- u8 buf[AES_BLOCK_SIZE];
int err;
err = skcipher_walk_virt(&walk, req, false);
while (walk.nbytes > 0) {
- unsigned int blocks = walk.nbytes / AES_BLOCK_SIZE;
- u8 *final = (walk.total % AES_BLOCK_SIZE) ? buf : NULL;
-
- if (walk.nbytes < walk.total) {
- blocks = round_down(blocks,
- walk.stride / AES_BLOCK_SIZE);
- final = NULL;
- }
+ int blocks = (walk.nbytes / AES_BLOCK_SIZE) & ~7;
+ int nbytes = walk.nbytes % (8 * AES_BLOCK_SIZE);
+ const u8 *src = walk.src.virt.addr;
+ u8 *dst = walk.dst.virt.addr;
kernel_neon_begin();
- aesbs_ctr_encrypt(walk.dst.virt.addr, walk.src.virt.addr,
- ctx->rk, ctx->rounds, blocks, walk.iv, final);
- kernel_neon_end();
-
- if (final) {
- u8 *dst = walk.dst.virt.addr + blocks * AES_BLOCK_SIZE;
- u8 *src = walk.src.virt.addr + blocks * AES_BLOCK_SIZE;
-
- crypto_xor_cpy(dst, src, final,
- walk.total % AES_BLOCK_SIZE);
-
- err = skcipher_walk_done(&walk, 0);
- break;
+ if (blocks >= 8) {
+ aesbs_ctr_encrypt(dst, src, ctx->key.rk, ctx->key.rounds,
+ blocks, walk.iv);
+ dst += blocks * AES_BLOCK_SIZE;
+ src += blocks * AES_BLOCK_SIZE;
}
- err = skcipher_walk_done(&walk,
- walk.nbytes - blocks * AES_BLOCK_SIZE);
+ if (nbytes && walk.nbytes == walk.total) {
+ neon_aes_ctr_encrypt(dst, src, ctx->enc, ctx->key.rounds,
+ nbytes, walk.iv);
+ nbytes = 0;
+ }
+ kernel_neon_end();
+ err = skcipher_walk_done(&walk, nbytes);
}
return err;
}
@@ -308,23 +302,18 @@ static int __xts_crypt(struct skcipher_request *req, bool encrypt,
return err;
while (walk.nbytes >= AES_BLOCK_SIZE) {
- unsigned int blocks = walk.nbytes / AES_BLOCK_SIZE;
-
- if (walk.nbytes < walk.total || walk.nbytes % AES_BLOCK_SIZE)
- blocks = round_down(blocks,
- walk.stride / AES_BLOCK_SIZE);
-
+ int blocks = (walk.nbytes / AES_BLOCK_SIZE) & ~7;
out = walk.dst.virt.addr;
in = walk.src.virt.addr;
nbytes = walk.nbytes;
kernel_neon_begin();
- if (likely(blocks > 6)) { /* plain NEON is faster otherwise */
- if (first)
+ if (blocks >= 8) {
+ if (first == 1)
neon_aes_ecb_encrypt(walk.iv, walk.iv,
ctx->twkey,
ctx->key.rounds, 1);
- first = 0;
+ first = 2;
fn(out, in, ctx->key.rk, ctx->key.rounds, blocks,
walk.iv);
@@ -333,10 +322,17 @@ static int __xts_crypt(struct skcipher_request *req, bool encrypt,
in += blocks * AES_BLOCK_SIZE;
nbytes -= blocks * AES_BLOCK_SIZE;
}
-
- if (walk.nbytes == walk.total && nbytes > 0)
- goto xts_tail;
-
+ if (walk.nbytes == walk.total && nbytes > 0) {
+ if (encrypt)
+ neon_aes_xts_encrypt(out, in, ctx->cts.key_enc,
+ ctx->key.rounds, nbytes,
+ ctx->twkey, walk.iv, first);
+ else
+ neon_aes_xts_decrypt(out, in, ctx->cts.key_dec,
+ ctx->key.rounds, nbytes,
+ ctx->twkey, walk.iv, first);
+ nbytes = first = 0;
+ }
kernel_neon_end();
err = skcipher_walk_done(&walk, nbytes);
}
@@ -361,13 +357,12 @@ static int __xts_crypt(struct skcipher_request *req, bool encrypt,
nbytes = walk.nbytes;
kernel_neon_begin();
-xts_tail:
if (encrypt)
neon_aes_xts_encrypt(out, in, ctx->cts.key_enc, ctx->key.rounds,
- nbytes, ctx->twkey, walk.iv, first ?: 2);
+ nbytes, ctx->twkey, walk.iv, first);
else
neon_aes_xts_decrypt(out, in, ctx->cts.key_dec, ctx->key.rounds,
- nbytes, ctx->twkey, walk.iv, first ?: 2);
+ nbytes, ctx->twkey, walk.iv, first);
kernel_neon_end();
return skcipher_walk_done(&walk, 0);
@@ -402,14 +397,14 @@ static struct skcipher_alg aes_algs[] = { {
.base.cra_driver_name = "cbc-aes-neonbs",
.base.cra_priority = 250,
.base.cra_blocksize = AES_BLOCK_SIZE,
- .base.cra_ctxsize = sizeof(struct aesbs_cbc_ctx),
+ .base.cra_ctxsize = sizeof(struct aesbs_cbc_ctr_ctx),
.base.cra_module = THIS_MODULE,
.min_keysize = AES_MIN_KEY_SIZE,
.max_keysize = AES_MAX_KEY_SIZE,
.walksize = 8 * AES_BLOCK_SIZE,
.ivsize = AES_BLOCK_SIZE,
- .setkey = aesbs_cbc_setkey,
+ .setkey = aesbs_cbc_ctr_setkey,
.encrypt = cbc_encrypt,
.decrypt = cbc_decrypt,
}, {
@@ -417,7 +412,7 @@ static struct skcipher_alg aes_algs[] = { {
.base.cra_driver_name = "ctr-aes-neonbs",
.base.cra_priority = 250,
.base.cra_blocksize = 1,
- .base.cra_ctxsize = sizeof(struct aesbs_ctx),
+ .base.cra_ctxsize = sizeof(struct aesbs_cbc_ctr_ctx),
.base.cra_module = THIS_MODULE,
.min_keysize = AES_MIN_KEY_SIZE,
@@ -425,7 +420,7 @@ static struct skcipher_alg aes_algs[] = { {
.chunksize = AES_BLOCK_SIZE,
.walksize = 8 * AES_BLOCK_SIZE,
.ivsize = AES_BLOCK_SIZE,
- .setkey = aesbs_setkey,
+ .setkey = aesbs_cbc_ctr_setkey,
.encrypt = ctr_encrypt,
.decrypt = ctr_encrypt,
}, {
diff --git a/arch/arm64/crypto/sha3-ce-glue.c b/arch/arm64/crypto/sha3-ce-glue.c
index 8c65cecf560a..250e1377c481 100644
--- a/arch/arm64/crypto/sha3-ce-glue.c
+++ b/arch/arm64/crypto/sha3-ce-glue.c
@@ -1,4 +1,4 @@
-/* SPDX-License-Identifier: GPL-2.0 */
+// SPDX-License-Identifier: GPL-2.0
/*
* sha3-ce-glue.c - core SHA-3 transform using v8.2 Crypto Extensions
*
diff --git a/arch/arm64/crypto/sha512-armv8.pl b/arch/arm64/crypto/sha512-armv8.pl
index 2d8655d5b1af..35ec9ae99fe1 100644
--- a/arch/arm64/crypto/sha512-armv8.pl
+++ b/arch/arm64/crypto/sha512-armv8.pl
@@ -43,7 +43,7 @@
# on Cortex-A53 (or by 4 cycles per round).
# (***) Super-impressive coefficients over gcc-generated code are
# indication of some compiler "pathology", most notably code
-# generated with -mgeneral-regs-only is significanty faster
+# generated with -mgeneral-regs-only is significantly faster
# and the gap is only 40-90%.
#
# October 2016.
diff --git a/arch/arm64/crypto/sha512-ce-glue.c b/arch/arm64/crypto/sha512-ce-glue.c
index e62a094a9d52..94cb7580deb7 100644
--- a/arch/arm64/crypto/sha512-ce-glue.c
+++ b/arch/arm64/crypto/sha512-ce-glue.c
@@ -1,4 +1,4 @@
-/* SPDX-License-Identifier: GPL-2.0 */
+// SPDX-License-Identifier: GPL-2.0
/*
* sha512-ce-glue.c - SHA-384/SHA-512 using ARMv8 Crypto Extensions
*
diff --git a/arch/arm64/crypto/sm3-ce-glue.c b/arch/arm64/crypto/sm3-ce-glue.c
index d71faca322f2..ee98954ae8ca 100644
--- a/arch/arm64/crypto/sm3-ce-glue.c
+++ b/arch/arm64/crypto/sm3-ce-glue.c
@@ -26,8 +26,10 @@ asmlinkage void sm3_ce_transform(struct sm3_state *sst, u8 const *src,
static int sm3_ce_update(struct shash_desc *desc, const u8 *data,
unsigned int len)
{
- if (!crypto_simd_usable())
- return crypto_sm3_update(desc, data, len);
+ if (!crypto_simd_usable()) {
+ sm3_update(shash_desc_ctx(desc), data, len);
+ return 0;
+ }
kernel_neon_begin();
sm3_base_do_update(desc, data, len, sm3_ce_transform);
@@ -38,8 +40,10 @@ static int sm3_ce_update(struct shash_desc *desc, const u8 *data,
static int sm3_ce_final(struct shash_desc *desc, u8 *out)
{
- if (!crypto_simd_usable())
- return crypto_sm3_finup(desc, NULL, 0, out);
+ if (!crypto_simd_usable()) {
+ sm3_final(shash_desc_ctx(desc), out);
+ return 0;
+ }
kernel_neon_begin();
sm3_base_do_finalize(desc, sm3_ce_transform);
@@ -51,14 +55,22 @@ static int sm3_ce_final(struct shash_desc *desc, u8 *out)
static int sm3_ce_finup(struct shash_desc *desc, const u8 *data,
unsigned int len, u8 *out)
{
- if (!crypto_simd_usable())
- return crypto_sm3_finup(desc, data, len, out);
+ if (!crypto_simd_usable()) {
+ struct sm3_state *sctx = shash_desc_ctx(desc);
+
+ if (len)
+ sm3_update(sctx, data, len);
+ sm3_final(sctx, out);
+ return 0;
+ }
kernel_neon_begin();
- sm3_base_do_update(desc, data, len, sm3_ce_transform);
+ if (len)
+ sm3_base_do_update(desc, data, len, sm3_ce_transform);
+ sm3_base_do_finalize(desc, sm3_ce_transform);
kernel_neon_end();
- return sm3_ce_final(desc, out);
+ return sm3_base_finish(desc, out);
}
static struct shash_alg sm3_alg = {
diff --git a/arch/arm64/include/asm/apple_m1_pmu.h b/arch/arm64/include/asm/apple_m1_pmu.h
new file mode 100644
index 000000000000..99483b19b99f
--- /dev/null
+++ b/arch/arm64/include/asm/apple_m1_pmu.h
@@ -0,0 +1,64 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#ifndef __ASM_APPLE_M1_PMU_h
+#define __ASM_APPLE_M1_PMU_h
+
+#include <linux/bits.h>
+#include <asm/sysreg.h>
+
+/* Counters */
+#define SYS_IMP_APL_PMC0_EL1 sys_reg(3, 2, 15, 0, 0)
+#define SYS_IMP_APL_PMC1_EL1 sys_reg(3, 2, 15, 1, 0)
+#define SYS_IMP_APL_PMC2_EL1 sys_reg(3, 2, 15, 2, 0)
+#define SYS_IMP_APL_PMC3_EL1 sys_reg(3, 2, 15, 3, 0)
+#define SYS_IMP_APL_PMC4_EL1 sys_reg(3, 2, 15, 4, 0)
+#define SYS_IMP_APL_PMC5_EL1 sys_reg(3, 2, 15, 5, 0)
+#define SYS_IMP_APL_PMC6_EL1 sys_reg(3, 2, 15, 6, 0)
+#define SYS_IMP_APL_PMC7_EL1 sys_reg(3, 2, 15, 7, 0)
+#define SYS_IMP_APL_PMC8_EL1 sys_reg(3, 2, 15, 9, 0)
+#define SYS_IMP_APL_PMC9_EL1 sys_reg(3, 2, 15, 10, 0)
+
+/* Core PMC control register */
+#define SYS_IMP_APL_PMCR0_EL1 sys_reg(3, 1, 15, 0, 0)
+#define PMCR0_CNT_ENABLE_0_7 GENMASK(7, 0)
+#define PMCR0_IMODE GENMASK(10, 8)
+#define PMCR0_IMODE_OFF 0
+#define PMCR0_IMODE_PMI 1
+#define PMCR0_IMODE_AIC 2
+#define PMCR0_IMODE_HALT 3
+#define PMCR0_IMODE_FIQ 4
+#define PMCR0_IACT BIT(11)
+#define PMCR0_PMI_ENABLE_0_7 GENMASK(19, 12)
+#define PMCR0_STOP_CNT_ON_PMI BIT(20)
+#define PMCR0_CNT_GLOB_L2C_EVT BIT(21)
+#define PMCR0_DEFER_PMI_TO_ERET BIT(22)
+#define PMCR0_ALLOW_CNT_EN_EL0 BIT(30)
+#define PMCR0_CNT_ENABLE_8_9 GENMASK(33, 32)
+#define PMCR0_PMI_ENABLE_8_9 GENMASK(45, 44)
+
+#define SYS_IMP_APL_PMCR1_EL1 sys_reg(3, 1, 15, 1, 0)
+#define PMCR1_COUNT_A64_EL0_0_7 GENMASK(15, 8)
+#define PMCR1_COUNT_A64_EL1_0_7 GENMASK(23, 16)
+#define PMCR1_COUNT_A64_EL0_8_9 GENMASK(41, 40)
+#define PMCR1_COUNT_A64_EL1_8_9 GENMASK(49, 48)
+
+#define SYS_IMP_APL_PMCR2_EL1 sys_reg(3, 1, 15, 2, 0)
+#define SYS_IMP_APL_PMCR3_EL1 sys_reg(3, 1, 15, 3, 0)
+#define SYS_IMP_APL_PMCR4_EL1 sys_reg(3, 1, 15, 4, 0)
+
+#define SYS_IMP_APL_PMESR0_EL1 sys_reg(3, 1, 15, 5, 0)
+#define PMESR0_EVT_CNT_2 GENMASK(7, 0)
+#define PMESR0_EVT_CNT_3 GENMASK(15, 8)
+#define PMESR0_EVT_CNT_4 GENMASK(23, 16)
+#define PMESR0_EVT_CNT_5 GENMASK(31, 24)
+
+#define SYS_IMP_APL_PMESR1_EL1 sys_reg(3, 1, 15, 6, 0)
+#define PMESR1_EVT_CNT_6 GENMASK(7, 0)
+#define PMESR1_EVT_CNT_7 GENMASK(15, 8)
+#define PMESR1_EVT_CNT_8 GENMASK(23, 16)
+#define PMESR1_EVT_CNT_9 GENMASK(31, 24)
+
+#define SYS_IMP_APL_PMSR_EL1 sys_reg(3, 1, 15, 13, 0)
+#define PMSR_OVERFLOW GENMASK(9, 0)
+
+#endif /* __ASM_APPLE_M1_PMU_h */
diff --git a/arch/arm64/include/asm/arch_gicv3.h b/arch/arm64/include/asm/arch_gicv3.h
index 4ad22c3135db..8bd5afc7b692 100644
--- a/arch/arm64/include/asm/arch_gicv3.h
+++ b/arch/arm64/include/asm/arch_gicv3.h
@@ -53,17 +53,36 @@ static inline u64 gic_read_iar_common(void)
* The gicv3 of ThunderX requires a modified version for reading the
* IAR status to ensure data synchronization (access to icc_iar1_el1
* is not sync'ed before and after).
+ *
+ * Erratum 38545
+ *
+ * When a IAR register read races with a GIC interrupt RELEASE event,
+ * GIC-CPU interface could wrongly return a valid INTID to the CPU
+ * for an interrupt that is already released(non activated) instead of 0x3ff.
+ *
+ * To workaround this, return a valid interrupt ID only if there is a change
+ * in the active priority list after the IAR read.
+ *
+ * Common function used for both the workarounds since,
+ * 1. On Thunderx 88xx 1.x both erratas are applicable.
+ * 2. Having extra nops doesn't add any side effects for Silicons where
+ * erratum 23154 is not applicable.
*/
static inline u64 gic_read_iar_cavium_thunderx(void)
{
- u64 irqstat;
+ u64 irqstat, apr;
+ apr = read_sysreg_s(SYS_ICC_AP1R0_EL1);
nops(8);
irqstat = read_sysreg_s(SYS_ICC_IAR1_EL1);
nops(4);
mb();
- return irqstat;
+ /* Max priority groups implemented is only 32 */
+ if (likely(apr != read_sysreg_s(SYS_ICC_AP1R0_EL1)))
+ return irqstat;
+
+ return 0x3ff;
}
static inline void gic_write_ctlr(u32 val)
diff --git a/arch/arm64/include/asm/archrandom.h b/arch/arm64/include/asm/archrandom.h
index 09e43272ccb0..d1bb5e71df25 100644
--- a/arch/arm64/include/asm/archrandom.h
+++ b/arch/arm64/include/asm/archrandom.h
@@ -42,13 +42,47 @@ static inline bool __arm64_rndr(unsigned long *v)
return ok;
}
+static inline bool __arm64_rndrrs(unsigned long *v)
+{
+ bool ok;
+
+ /*
+ * Reads of RNDRRS set PSTATE.NZCV to 0b0000 on success,
+ * and set PSTATE.NZCV to 0b0100 otherwise.
+ */
+ asm volatile(
+ __mrs_s("%0", SYS_RNDRRS_EL0) "\n"
+ " cset %w1, ne\n"
+ : "=r" (*v), "=r" (ok)
+ :
+ : "cc");
+
+ return ok;
+}
+
static inline bool __must_check arch_get_random_long(unsigned long *v)
{
+ /*
+ * Only support the generic interface after we have detected
+ * the system wide capability, avoiding complexity with the
+ * cpufeature code and with potential scheduling between CPUs
+ * with and without the feature.
+ */
+ if (cpus_have_const_cap(ARM64_HAS_RNG) && __arm64_rndr(v))
+ return true;
return false;
}
static inline bool __must_check arch_get_random_int(unsigned int *v)
{
+ if (cpus_have_const_cap(ARM64_HAS_RNG)) {
+ unsigned long val;
+
+ if (__arm64_rndr(&val)) {
+ *v = val;
+ return true;
+ }
+ }
return false;
}
@@ -71,12 +105,11 @@ static inline bool __must_check arch_get_random_seed_long(unsigned long *v)
}
/*
- * Only support the generic interface after we have detected
- * the system wide capability, avoiding complexity with the
- * cpufeature code and with potential scheduling between CPUs
- * with and without the feature.
+ * RNDRRS is not backed by an entropy source but by a DRBG that is
+ * reseeded after each invocation. This is not a 100% fit but good
+ * enough to implement this API if no other entropy source exists.
*/
- if (cpus_have_const_cap(ARM64_HAS_RNG) && __arm64_rndr(v))
+ if (cpus_have_const_cap(ARM64_HAS_RNG) && __arm64_rndrrs(v))
return true;
return false;
@@ -96,7 +129,7 @@ static inline bool __must_check arch_get_random_seed_int(unsigned int *v)
}
if (cpus_have_const_cap(ARM64_HAS_RNG)) {
- if (__arm64_rndr(&val)) {
+ if (__arm64_rndrrs(&val)) {
*v = val;
return true;
}
diff --git a/arch/arm64/include/asm/asm_pointer_auth.h b/arch/arm64/include/asm/asm_pointer_auth.h
index f1bba5fc61c4..ead62f7dd269 100644
--- a/arch/arm64/include/asm/asm_pointer_auth.h
+++ b/arch/arm64/include/asm/asm_pointer_auth.h
@@ -60,6 +60,9 @@ alternative_else_nop_endif
.macro __ptrauth_keys_init_cpu tsk, tmp1, tmp2, tmp3
mrs \tmp1, id_aa64isar1_el1
ubfx \tmp1, \tmp1, #ID_AA64ISAR1_APA_SHIFT, #8
+ mrs_s \tmp2, SYS_ID_AA64ISAR2_EL1
+ ubfx \tmp2, \tmp2, #ID_AA64ISAR2_APA3_SHIFT, #4
+ orr \tmp1, \tmp1, \tmp2
cbz \tmp1, .Lno_addr_auth\@
mov_q \tmp1, (SCTLR_ELx_ENIA | SCTLR_ELx_ENIB | \
SCTLR_ELx_ENDA | SCTLR_ELx_ENDB)
diff --git a/arch/arm64/include/asm/assembler.h b/arch/arm64/include/asm/assembler.h
index e8bd0af0141c..8c5a61aeaf8e 100644
--- a/arch/arm64/include/asm/assembler.h
+++ b/arch/arm64/include/asm/assembler.h
@@ -109,6 +109,13 @@
.endm
/*
+ * Clear Branch History instruction
+ */
+ .macro clearbhb
+ hint #22
+ .endm
+
+/*
* Speculation barrier
*/
.macro sb
@@ -535,11 +542,6 @@ alternative_endif
#define EXPORT_SYMBOL_NOKASAN(name) EXPORT_SYMBOL(name)
#endif
-#ifdef CONFIG_KASAN_HW_TAGS
-#define EXPORT_SYMBOL_NOHWKASAN(name)
-#else
-#define EXPORT_SYMBOL_NOHWKASAN(name) EXPORT_SYMBOL_NOKASAN(name)
-#endif
/*
* Emit a 64-bit absolute little endian symbol reference in a way that
* ensures that it will be resolved at build time, even when building a
@@ -850,4 +852,50 @@ alternative_endif
#endif /* GNU_PROPERTY_AARCH64_FEATURE_1_DEFAULT */
+ .macro __mitigate_spectre_bhb_loop tmp
+#ifdef CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY
+alternative_cb spectre_bhb_patch_loop_iter
+ mov \tmp, #32 // Patched to correct the immediate
+alternative_cb_end
+.Lspectre_bhb_loop\@:
+ b . + 4
+ subs \tmp, \tmp, #1
+ b.ne .Lspectre_bhb_loop\@
+ sb
+#endif /* CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY */
+ .endm
+
+ .macro mitigate_spectre_bhb_loop tmp
+#ifdef CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY
+alternative_cb spectre_bhb_patch_loop_mitigation_enable
+ b .L_spectre_bhb_loop_done\@ // Patched to NOP
+alternative_cb_end
+ __mitigate_spectre_bhb_loop \tmp
+.L_spectre_bhb_loop_done\@:
+#endif /* CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY */
+ .endm
+
+ /* Save/restores x0-x3 to the stack */
+ .macro __mitigate_spectre_bhb_fw
+#ifdef CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY
+ stp x0, x1, [sp, #-16]!
+ stp x2, x3, [sp, #-16]!
+ mov w0, #ARM_SMCCC_ARCH_WORKAROUND_3
+alternative_cb smccc_patch_fw_mitigation_conduit
+ nop // Patched to SMC/HVC #0
+alternative_cb_end
+ ldp x2, x3, [sp], #16
+ ldp x0, x1, [sp], #16
+#endif /* CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY */
+ .endm
+
+ .macro mitigate_spectre_bhb_clear_insn
+#ifdef CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY
+alternative_cb spectre_bhb_patch_clearbhb
+ /* Patched to NOP when not supported */
+ clearbhb
+ isb
+alternative_cb_end
+#endif /* CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY */
+ .endm
#endif /* __ASM_ASSEMBLER_H */
diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h
index ef6be92b1921..c62e7e5e2f0c 100644
--- a/arch/arm64/include/asm/cpufeature.h
+++ b/arch/arm64/include/asm/cpufeature.h
@@ -356,6 +356,7 @@ struct arm64_cpu_capabilities {
struct { /* Feature register checking */
u32 sys_reg;
u8 field_pos;
+ u8 field_width;
u8 min_field_value;
u8 hwcap_type;
bool sign;
@@ -576,6 +577,8 @@ static inline u64 arm64_ftr_reg_user_value(const struct arm64_ftr_reg *reg)
static inline int __attribute_const__
cpuid_feature_extract_field_width(u64 features, int field, int width, bool sign)
{
+ if (WARN_ON_ONCE(!width))
+ width = 4;
return (sign) ?
cpuid_feature_extract_signed_field_width(features, field, width) :
cpuid_feature_extract_unsigned_field_width(features, field, width);
@@ -637,6 +640,35 @@ static inline bool cpu_supports_mixed_endian_el0(void)
return id_aa64mmfr0_mixed_endian_el0(read_cpuid(ID_AA64MMFR0_EL1));
}
+
+static inline bool supports_csv2p3(int scope)
+{
+ u64 pfr0;
+ u8 csv2_val;
+
+ if (scope == SCOPE_LOCAL_CPU)
+ pfr0 = read_sysreg_s(SYS_ID_AA64PFR0_EL1);
+ else
+ pfr0 = read_sanitised_ftr_reg(SYS_ID_AA64PFR0_EL1);
+
+ csv2_val = cpuid_feature_extract_unsigned_field(pfr0,
+ ID_AA64PFR0_CSV2_SHIFT);
+ return csv2_val == 3;
+}
+
+static inline bool supports_clearbhb(int scope)
+{
+ u64 isar2;
+
+ if (scope == SCOPE_LOCAL_CPU)
+ isar2 = read_sysreg_s(SYS_ID_AA64ISAR2_EL1);
+ else
+ isar2 = read_sanitised_ftr_reg(SYS_ID_AA64ISAR2_EL1);
+
+ return cpuid_feature_extract_unsigned_field(isar2,
+ ID_AA64ISAR2_CLEARBHB_SHIFT);
+}
+
const struct cpumask *system_32bit_el0_cpumask(void);
DECLARE_STATIC_KEY_FALSE(arm64_mismatched_32bit_el0);
@@ -854,6 +886,7 @@ static inline unsigned int get_vmid_bits(u64 mmfr1)
extern struct arm64_ftr_override id_aa64mmfr1_override;
extern struct arm64_ftr_override id_aa64pfr1_override;
extern struct arm64_ftr_override id_aa64isar1_override;
+extern struct arm64_ftr_override id_aa64isar2_override;
u32 get_kvm_ipa_limit(void);
void dump_cpu_features(void);
diff --git a/arch/arm64/include/asm/cputype.h b/arch/arm64/include/asm/cputype.h
index 19b8441aa8f2..232b439cbaf3 100644
--- a/arch/arm64/include/asm/cputype.h
+++ b/arch/arm64/include/asm/cputype.h
@@ -73,8 +73,14 @@
#define ARM_CPU_PART_CORTEX_A76 0xD0B
#define ARM_CPU_PART_NEOVERSE_N1 0xD0C
#define ARM_CPU_PART_CORTEX_A77 0xD0D
+#define ARM_CPU_PART_NEOVERSE_V1 0xD40
+#define ARM_CPU_PART_CORTEX_A78 0xD41
+#define ARM_CPU_PART_CORTEX_X1 0xD44
+#define ARM_CPU_PART_CORTEX_A510 0xD46
#define ARM_CPU_PART_CORTEX_A710 0xD47
+#define ARM_CPU_PART_CORTEX_X2 0xD48
#define ARM_CPU_PART_NEOVERSE_N2 0xD49
+#define ARM_CPU_PART_CORTEX_A78C 0xD4B
#define APM_CPU_PART_POTENZA 0x000
@@ -82,6 +88,13 @@
#define CAVIUM_CPU_PART_THUNDERX_81XX 0x0A2
#define CAVIUM_CPU_PART_THUNDERX_83XX 0x0A3
#define CAVIUM_CPU_PART_THUNDERX2 0x0AF
+/* OcteonTx2 series */
+#define CAVIUM_CPU_PART_OCTX2_98XX 0x0B1
+#define CAVIUM_CPU_PART_OCTX2_96XX 0x0B2
+#define CAVIUM_CPU_PART_OCTX2_95XX 0x0B3
+#define CAVIUM_CPU_PART_OCTX2_95XXN 0x0B4
+#define CAVIUM_CPU_PART_OCTX2_95XXMM 0x0B5
+#define CAVIUM_CPU_PART_OCTX2_95XXO 0x0B6
#define BRCM_CPU_PART_BRAHMA_B53 0x100
#define BRCM_CPU_PART_VULCAN 0x516
@@ -115,11 +128,23 @@
#define MIDR_CORTEX_A76 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A76)
#define MIDR_NEOVERSE_N1 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_N1)
#define MIDR_CORTEX_A77 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A77)
+#define MIDR_NEOVERSE_V1 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_V1)
+#define MIDR_CORTEX_A78 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A78)
+#define MIDR_CORTEX_X1 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_X1)
+#define MIDR_CORTEX_A510 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A510)
#define MIDR_CORTEX_A710 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A710)
+#define MIDR_CORTEX_X2 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_X2)
#define MIDR_NEOVERSE_N2 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_N2)
+#define MIDR_CORTEX_A78C MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A78C)
#define MIDR_THUNDERX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX)
#define MIDR_THUNDERX_81XX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX_81XX)
#define MIDR_THUNDERX_83XX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX_83XX)
+#define MIDR_OCTX2_98XX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_OCTX2_98XX)
+#define MIDR_OCTX2_96XX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_OCTX2_96XX)
+#define MIDR_OCTX2_95XX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_OCTX2_95XX)
+#define MIDR_OCTX2_95XXN MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_OCTX2_95XXN)
+#define MIDR_OCTX2_95XXMM MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_OCTX2_95XXMM)
+#define MIDR_OCTX2_95XXO MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_OCTX2_95XXO)
#define MIDR_CAVIUM_THUNDERX2 MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX2)
#define MIDR_BRAHMA_B53 MIDR_CPU_MODEL(ARM_CPU_IMP_BRCM, BRCM_CPU_PART_BRAHMA_B53)
#define MIDR_BRCM_VULCAN MIDR_CPU_MODEL(ARM_CPU_IMP_BRCM, BRCM_CPU_PART_VULCAN)
diff --git a/arch/arm64/include/asm/debug-monitors.h b/arch/arm64/include/asm/debug-monitors.h
index 657c921fd784..00c291067e57 100644
--- a/arch/arm64/include/asm/debug-monitors.h
+++ b/arch/arm64/include/asm/debug-monitors.h
@@ -34,18 +34,6 @@
*/
#define BREAK_INSTR_SIZE AARCH64_INSN_SIZE
-/*
- * BRK instruction encoding
- * The #imm16 value should be placed at bits[20:5] within BRK ins
- */
-#define AARCH64_BREAK_MON 0xd4200000
-
-/*
- * BRK instruction for provoking a fault on purpose
- * Unlike kgdb, #imm16 value with unallocated handler is used for faulting.
- */
-#define AARCH64_BREAK_FAULT (AARCH64_BREAK_MON | (FAULT_BRK_IMM << 5))
-
#define AARCH64_BREAK_KGDB_DYN_DBG \
(AARCH64_BREAK_MON | (KGDB_DYN_DBG_BRK_IMM << 5))
diff --git a/arch/arm64/include/asm/el2_setup.h b/arch/arm64/include/asm/el2_setup.h
index 3198acb2aad8..7f3c87f7a0ce 100644
--- a/arch/arm64/include/asm/el2_setup.h
+++ b/arch/arm64/include/asm/el2_setup.h
@@ -106,7 +106,7 @@
msr_s SYS_ICC_SRE_EL2, x0
isb // Make sure SRE is now set
mrs_s x0, SYS_ICC_SRE_EL2 // Read SRE back,
- tbz x0, #0, 1f // and check that it sticks
+ tbz x0, #0, .Lskip_gicv3_\@ // and check that it sticks
msr_s SYS_ICH_HCR_EL2, xzr // Reset ICC_HCR_EL2 to defaults
.Lskip_gicv3_\@:
.endm
diff --git a/arch/arm64/include/asm/fixmap.h b/arch/arm64/include/asm/fixmap.h
index 4335800201c9..daff882883f9 100644
--- a/arch/arm64/include/asm/fixmap.h
+++ b/arch/arm64/include/asm/fixmap.h
@@ -62,9 +62,11 @@ enum fixed_addresses {
#endif /* CONFIG_ACPI_APEI_GHES */
#ifdef CONFIG_UNMAP_KERNEL_AT_EL0
+ FIX_ENTRY_TRAMP_TEXT3,
+ FIX_ENTRY_TRAMP_TEXT2,
+ FIX_ENTRY_TRAMP_TEXT1,
FIX_ENTRY_TRAMP_DATA,
- FIX_ENTRY_TRAMP_TEXT,
-#define TRAMP_VALIAS (__fix_to_virt(FIX_ENTRY_TRAMP_TEXT))
+#define TRAMP_VALIAS (__fix_to_virt(FIX_ENTRY_TRAMP_TEXT1))
#endif /* CONFIG_UNMAP_KERNEL_AT_EL0 */
__end_of_permanent_fixed_addresses,
diff --git a/arch/arm64/include/asm/hwcap.h b/arch/arm64/include/asm/hwcap.h
index f68fbb207473..8db5ec0089db 100644
--- a/arch/arm64/include/asm/hwcap.h
+++ b/arch/arm64/include/asm/hwcap.h
@@ -108,6 +108,7 @@
#define KERNEL_HWCAP_ECV __khwcap2_feature(ECV)
#define KERNEL_HWCAP_AFP __khwcap2_feature(AFP)
#define KERNEL_HWCAP_RPRES __khwcap2_feature(RPRES)
+#define KERNEL_HWCAP_MTE3 __khwcap2_feature(MTE3)
/*
* This yields a mask that user programs can use to figure out what
diff --git a/arch/arm64/include/asm/insn-def.h b/arch/arm64/include/asm/insn-def.h
index 2c075f615c6a..1a7d0d483698 100644
--- a/arch/arm64/include/asm/insn-def.h
+++ b/arch/arm64/include/asm/insn-def.h
@@ -3,7 +3,21 @@
#ifndef __ASM_INSN_DEF_H
#define __ASM_INSN_DEF_H
+#include <asm/brk-imm.h>
+
/* A64 instructions are always 32 bits. */
#define AARCH64_INSN_SIZE 4
+/*
+ * BRK instruction encoding
+ * The #imm16 value should be placed at bits[20:5] within BRK ins
+ */
+#define AARCH64_BREAK_MON 0xd4200000
+
+/*
+ * BRK instruction for provoking a fault on purpose
+ * Unlike kgdb, #imm16 value with unallocated handler is used for faulting.
+ */
+#define AARCH64_BREAK_FAULT (AARCH64_BREAK_MON | (FAULT_BRK_IMM << 5))
+
#endif /* __ASM_INSN_DEF_H */
diff --git a/arch/arm64/include/asm/insn.h b/arch/arm64/include/asm/insn.h
index 6b776c8667b2..1e5760d567ae 100644
--- a/arch/arm64/include/asm/insn.h
+++ b/arch/arm64/include/asm/insn.h
@@ -65,6 +65,7 @@ enum aarch64_insn_hint_cr_op {
AARCH64_INSN_HINT_PSB = 0x11 << 5,
AARCH64_INSN_HINT_TSB = 0x12 << 5,
AARCH64_INSN_HINT_CSDB = 0x14 << 5,
+ AARCH64_INSN_HINT_CLEARBHB = 0x16 << 5,
AARCH64_INSN_HINT_BTI = 0x20 << 5,
AARCH64_INSN_HINT_BTIC = 0x22 << 5,
@@ -205,7 +206,9 @@ enum aarch64_insn_ldst_type {
AARCH64_INSN_LDST_LOAD_PAIR_POST_INDEX,
AARCH64_INSN_LDST_STORE_PAIR_POST_INDEX,
AARCH64_INSN_LDST_LOAD_EX,
+ AARCH64_INSN_LDST_LOAD_ACQ_EX,
AARCH64_INSN_LDST_STORE_EX,
+ AARCH64_INSN_LDST_STORE_REL_EX,
};
enum aarch64_insn_adsb_type {
@@ -280,6 +283,36 @@ enum aarch64_insn_adr_type {
AARCH64_INSN_ADR_TYPE_ADR,
};
+enum aarch64_insn_mem_atomic_op {
+ AARCH64_INSN_MEM_ATOMIC_ADD,
+ AARCH64_INSN_MEM_ATOMIC_CLR,
+ AARCH64_INSN_MEM_ATOMIC_EOR,
+ AARCH64_INSN_MEM_ATOMIC_SET,
+ AARCH64_INSN_MEM_ATOMIC_SWP,
+};
+
+enum aarch64_insn_mem_order_type {
+ AARCH64_INSN_MEM_ORDER_NONE,
+ AARCH64_INSN_MEM_ORDER_ACQ,
+ AARCH64_INSN_MEM_ORDER_REL,
+ AARCH64_INSN_MEM_ORDER_ACQREL,
+};
+
+enum aarch64_insn_mb_type {
+ AARCH64_INSN_MB_SY,
+ AARCH64_INSN_MB_ST,
+ AARCH64_INSN_MB_LD,
+ AARCH64_INSN_MB_ISH,
+ AARCH64_INSN_MB_ISHST,
+ AARCH64_INSN_MB_ISHLD,
+ AARCH64_INSN_MB_NSH,
+ AARCH64_INSN_MB_NSHST,
+ AARCH64_INSN_MB_NSHLD,
+ AARCH64_INSN_MB_OSH,
+ AARCH64_INSN_MB_OSHST,
+ AARCH64_INSN_MB_OSHLD,
+};
+
#define __AARCH64_INSN_FUNCS(abbr, mask, val) \
static __always_inline bool aarch64_insn_is_##abbr(u32 code) \
{ \
@@ -303,6 +336,11 @@ __AARCH64_INSN_FUNCS(store_post, 0x3FE00C00, 0x38000400)
__AARCH64_INSN_FUNCS(load_post, 0x3FE00C00, 0x38400400)
__AARCH64_INSN_FUNCS(str_reg, 0x3FE0EC00, 0x38206800)
__AARCH64_INSN_FUNCS(ldadd, 0x3F20FC00, 0x38200000)
+__AARCH64_INSN_FUNCS(ldclr, 0x3F20FC00, 0x38201000)
+__AARCH64_INSN_FUNCS(ldeor, 0x3F20FC00, 0x38202000)
+__AARCH64_INSN_FUNCS(ldset, 0x3F20FC00, 0x38203000)
+__AARCH64_INSN_FUNCS(swp, 0x3F20FC00, 0x38208000)
+__AARCH64_INSN_FUNCS(cas, 0x3FA07C00, 0x08A07C00)
__AARCH64_INSN_FUNCS(ldr_reg, 0x3FE0EC00, 0x38606800)
__AARCH64_INSN_FUNCS(ldr_lit, 0xBF000000, 0x18000000)
__AARCH64_INSN_FUNCS(ldrsw_lit, 0xFF000000, 0x98000000)
@@ -474,13 +512,6 @@ u32 aarch64_insn_gen_load_store_ex(enum aarch64_insn_register reg,
enum aarch64_insn_register state,
enum aarch64_insn_size_type size,
enum aarch64_insn_ldst_type type);
-u32 aarch64_insn_gen_ldadd(enum aarch64_insn_register result,
- enum aarch64_insn_register address,
- enum aarch64_insn_register value,
- enum aarch64_insn_size_type size);
-u32 aarch64_insn_gen_stadd(enum aarch64_insn_register address,
- enum aarch64_insn_register value,
- enum aarch64_insn_size_type size);
u32 aarch64_insn_gen_add_sub_imm(enum aarch64_insn_register dst,
enum aarch64_insn_register src,
int imm, enum aarch64_insn_variant variant,
@@ -541,6 +572,42 @@ u32 aarch64_insn_gen_prefetch(enum aarch64_insn_register base,
enum aarch64_insn_prfm_type type,
enum aarch64_insn_prfm_target target,
enum aarch64_insn_prfm_policy policy);
+#ifdef CONFIG_ARM64_LSE_ATOMICS
+u32 aarch64_insn_gen_atomic_ld_op(enum aarch64_insn_register result,
+ enum aarch64_insn_register address,
+ enum aarch64_insn_register value,
+ enum aarch64_insn_size_type size,
+ enum aarch64_insn_mem_atomic_op op,
+ enum aarch64_insn_mem_order_type order);
+u32 aarch64_insn_gen_cas(enum aarch64_insn_register result,
+ enum aarch64_insn_register address,
+ enum aarch64_insn_register value,
+ enum aarch64_insn_size_type size,
+ enum aarch64_insn_mem_order_type order);
+#else
+static inline
+u32 aarch64_insn_gen_atomic_ld_op(enum aarch64_insn_register result,
+ enum aarch64_insn_register address,
+ enum aarch64_insn_register value,
+ enum aarch64_insn_size_type size,
+ enum aarch64_insn_mem_atomic_op op,
+ enum aarch64_insn_mem_order_type order)
+{
+ return AARCH64_BREAK_FAULT;
+}
+
+static inline
+u32 aarch64_insn_gen_cas(enum aarch64_insn_register result,
+ enum aarch64_insn_register address,
+ enum aarch64_insn_register value,
+ enum aarch64_insn_size_type size,
+ enum aarch64_insn_mem_order_type order)
+{
+ return AARCH64_BREAK_FAULT;
+}
+#endif
+u32 aarch64_insn_gen_dmb(enum aarch64_insn_mb_type type);
+
s32 aarch64_get_branch_offset(u32 insn);
u32 aarch64_set_branch_offset(u32 insn, s32 offset);
diff --git a/arch/arm64/include/asm/kvm_arm.h b/arch/arm64/include/asm/kvm_arm.h
index 01d47c5886dc..1767ded83888 100644
--- a/arch/arm64/include/asm/kvm_arm.h
+++ b/arch/arm64/include/asm/kvm_arm.h
@@ -355,8 +355,8 @@
ECN(SOFTSTP_CUR), ECN(WATCHPT_LOW), ECN(WATCHPT_CUR), \
ECN(BKPT32), ECN(VECTOR32), ECN(BRK64)
-#define CPACR_EL1_FPEN (3 << 20)
#define CPACR_EL1_TTA (1 << 28)
-#define CPACR_EL1_DEFAULT (CPACR_EL1_FPEN | CPACR_EL1_ZEN_EL1EN)
+#define CPACR_EL1_DEFAULT (CPACR_EL1_FPEN_EL0EN | CPACR_EL1_FPEN_EL1EN |\
+ CPACR_EL1_ZEN_EL1EN)
#endif /* __ARM64_KVM_ARM_H__ */
diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 5bc01e62c08a..e3b25dc6c367 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -50,6 +50,8 @@
#define KVM_DIRTY_LOG_MANUAL_CAPS (KVM_DIRTY_LOG_MANUAL_PROTECT_ENABLE | \
KVM_DIRTY_LOG_INITIALLY_SET)
+#define KVM_HAVE_MMU_RWLOCK
+
/*
* Mode of operation configurable with kvm-arm.mode early param.
* See Documentation/admin-guide/kernel-parameters.txt for more information.
@@ -71,9 +73,7 @@ int kvm_reset_vcpu(struct kvm_vcpu *vcpu);
void kvm_arm_vcpu_destroy(struct kvm_vcpu *vcpu);
struct kvm_vmid {
- /* The VMID generation used for the virt. memory system */
- u64 vmid_gen;
- u32 vmid;
+ atomic64_t id;
};
struct kvm_s2_mmu {
@@ -122,20 +122,24 @@ struct kvm_arch {
* should) opt in to this feature if KVM_CAP_ARM_NISV_TO_USER is
* supported.
*/
- bool return_nisv_io_abort_to_user;
+#define KVM_ARCH_FLAG_RETURN_NISV_IO_ABORT_TO_USER 0
+ /* Memory Tagging Extension enabled for the guest */
+#define KVM_ARCH_FLAG_MTE_ENABLED 1
+ /* At least one vCPU has ran in the VM */
+#define KVM_ARCH_FLAG_HAS_RAN_ONCE 2
+ unsigned long flags;
/*
* VM-wide PMU filter, implemented as a bitmap and big enough for
* up to 2^10 events (ARMv8.0) or 2^16 events (ARMv8.1+).
*/
unsigned long *pmu_filter;
- unsigned int pmuver;
+ struct arm_pmu *arm_pmu;
+
+ cpumask_var_t supported_cpus;
u8 pfr0_csv2;
u8 pfr0_csv3;
-
- /* Memory Tagging Extension enabled for the guest */
- bool mte_enabled;
};
struct kvm_vcpu_fault_info {
@@ -171,6 +175,7 @@ enum vcpu_sysreg {
PAR_EL1, /* Physical Address Register */
MDSCR_EL1, /* Monitor Debug System Control Register */
MDCCINT_EL1, /* Monitor Debug Comms Channel Interrupt Enable Reg */
+ OSLSR_EL1, /* OS Lock Status Register */
DISR_EL1, /* Deferred Interrupt Status Register */
/* Performance Monitors Registers */
@@ -435,6 +440,7 @@ struct kvm_vcpu_arch {
#define KVM_ARM64_DEBUG_STATE_SAVE_SPE (1 << 12) /* Save SPE context if active */
#define KVM_ARM64_DEBUG_STATE_SAVE_TRBE (1 << 13) /* Save TRBE context if active */
#define KVM_ARM64_FP_FOREIGN_FPSTATE (1 << 14)
+#define KVM_ARM64_ON_UNSUPPORTED_CPU (1 << 15) /* Physical CPU not in supported_cpus */
#define KVM_GUESTDBG_VALID_MASK (KVM_GUESTDBG_ENABLE | \
KVM_GUESTDBG_USE_SW_BP | \
@@ -453,6 +459,15 @@ struct kvm_vcpu_arch {
#define vcpu_has_ptrauth(vcpu) false
#endif
+#define vcpu_on_unsupported_cpu(vcpu) \
+ ((vcpu)->arch.flags & KVM_ARM64_ON_UNSUPPORTED_CPU)
+
+#define vcpu_set_on_unsupported_cpu(vcpu) \
+ ((vcpu)->arch.flags |= KVM_ARM64_ON_UNSUPPORTED_CPU)
+
+#define vcpu_clear_on_unsupported_cpu(vcpu) \
+ ((vcpu)->arch.flags &= ~KVM_ARM64_ON_UNSUPPORTED_CPU)
+
#define vcpu_gp_regs(v) (&(v)->arch.ctxt.regs)
/*
@@ -692,6 +707,12 @@ int kvm_arm_pvtime_get_attr(struct kvm_vcpu *vcpu,
int kvm_arm_pvtime_has_attr(struct kvm_vcpu *vcpu,
struct kvm_device_attr *attr);
+extern unsigned int kvm_arm_vmid_bits;
+int kvm_arm_vmid_alloc_init(void);
+void kvm_arm_vmid_alloc_free(void);
+void kvm_arm_vmid_update(struct kvm_vmid *kvm_vmid);
+void kvm_arm_vmid_clear_active(void);
+
static inline void kvm_arm_pvtime_vcpu_init(struct kvm_vcpu_arch *vcpu_arch)
{
vcpu_arch->steal.base = GPA_INVALID;
@@ -714,6 +735,11 @@ static inline void kvm_init_host_cpu_context(struct kvm_cpu_context *cpu_ctxt)
ctxt_sys_reg(cpu_ctxt, MPIDR_EL1) = read_cpuid_mpidr();
}
+static inline bool kvm_system_needs_idmapped_vectors(void)
+{
+ return cpus_have_const_cap(ARM64_SPECTRE_V3A);
+}
+
void kvm_arm_vcpu_ptrauth_trap(struct kvm_vcpu *vcpu);
static inline void kvm_arch_hardware_unsetup(void) {}
@@ -725,6 +751,10 @@ void kvm_arm_vcpu_init_debug(struct kvm_vcpu *vcpu);
void kvm_arm_setup_debug(struct kvm_vcpu *vcpu);
void kvm_arm_clear_debug(struct kvm_vcpu *vcpu);
void kvm_arm_reset_debug_ptr(struct kvm_vcpu *vcpu);
+
+#define kvm_vcpu_os_lock_enabled(vcpu) \
+ (!!(__vcpu_sys_reg(vcpu, OSLSR_EL1) & SYS_OSLSR_OSLK))
+
int kvm_arm_vcpu_arch_set_attr(struct kvm_vcpu *vcpu,
struct kvm_device_attr *attr);
int kvm_arm_vcpu_arch_get_attr(struct kvm_vcpu *vcpu,
@@ -786,7 +816,9 @@ bool kvm_arm_vcpu_is_finalized(struct kvm_vcpu *vcpu);
#define kvm_arm_vcpu_sve_finalized(vcpu) \
((vcpu)->arch.flags & KVM_ARM64_VCPU_SVE_FINALIZED)
-#define kvm_has_mte(kvm) (system_supports_mte() && (kvm)->arch.mte_enabled)
+#define kvm_has_mte(kvm) \
+ (system_supports_mte() && \
+ test_bit(KVM_ARCH_FLAG_MTE_ENABLED, &(kvm)->arch.flags))
#define kvm_vcpu_has_pmu(vcpu) \
(test_bit(KVM_ARM_VCPU_PMU_V3, (vcpu)->arch.features))
diff --git a/arch/arm64/include/asm/kvm_hyp.h b/arch/arm64/include/asm/kvm_hyp.h
index 462882f356c7..aa7fa2a08f06 100644
--- a/arch/arm64/include/asm/kvm_hyp.h
+++ b/arch/arm64/include/asm/kvm_hyp.h
@@ -118,6 +118,7 @@ extern u64 kvm_nvhe_sym(id_aa64pfr0_el1_sys_val);
extern u64 kvm_nvhe_sym(id_aa64pfr1_el1_sys_val);
extern u64 kvm_nvhe_sym(id_aa64isar0_el1_sys_val);
extern u64 kvm_nvhe_sym(id_aa64isar1_el1_sys_val);
+extern u64 kvm_nvhe_sym(id_aa64isar2_el1_sys_val);
extern u64 kvm_nvhe_sym(id_aa64mmfr0_el1_sys_val);
extern u64 kvm_nvhe_sym(id_aa64mmfr1_el1_sys_val);
extern u64 kvm_nvhe_sym(id_aa64mmfr2_el1_sys_val);
diff --git a/arch/arm64/include/asm/kvm_mmu.h b/arch/arm64/include/asm/kvm_mmu.h
index 81839e9a8a24..74735a864eee 100644
--- a/arch/arm64/include/asm/kvm_mmu.h
+++ b/arch/arm64/include/asm/kvm_mmu.h
@@ -115,6 +115,7 @@ alternative_cb_end
#include <asm/cache.h>
#include <asm/cacheflush.h>
#include <asm/mmu_context.h>
+#include <asm/kvm_host.h>
void kvm_update_va_mask(struct alt_instr *alt,
__le32 *origptr, __le32 *updptr, int nr_inst);
@@ -266,7 +267,8 @@ static __always_inline u64 kvm_get_vttbr(struct kvm_s2_mmu *mmu)
u64 cnp = system_supports_cnp() ? VTTBR_CNP_BIT : 0;
baddr = mmu->pgd_phys;
- vmid_field = (u64)READ_ONCE(vmid->vmid) << VTTBR_VMID_SHIFT;
+ vmid_field = atomic64_read(&vmid->id) << VTTBR_VMID_SHIFT;
+ vmid_field &= VTTBR_VMID_MASK(kvm_arm_vmid_bits);
return kvm_phys_to_vttbr(baddr) | vmid_field | cnp;
}
diff --git a/arch/arm64/include/asm/linkage.h b/arch/arm64/include/asm/linkage.h
index b77e9b3f5371..43f8c25b3fda 100644
--- a/arch/arm64/include/asm/linkage.h
+++ b/arch/arm64/include/asm/linkage.h
@@ -39,28 +39,4 @@
SYM_START(name, SYM_L_WEAK, SYM_A_NONE) \
bti c ;
-/*
- * Annotate a function as position independent, i.e., safe to be called before
- * the kernel virtual mapping is activated.
- */
-#define SYM_FUNC_START_PI(x) \
- SYM_FUNC_START_ALIAS(__pi_##x); \
- SYM_FUNC_START(x)
-
-#define SYM_FUNC_START_WEAK_PI(x) \
- SYM_FUNC_START_ALIAS(__pi_##x); \
- SYM_FUNC_START_WEAK(x)
-
-#define SYM_FUNC_START_WEAK_ALIAS_PI(x) \
- SYM_FUNC_START_ALIAS(__pi_##x); \
- SYM_START(x, SYM_L_WEAK, SYM_A_ALIGN)
-
-#define SYM_FUNC_END_PI(x) \
- SYM_FUNC_END(x); \
- SYM_FUNC_END_ALIAS(__pi_##x)
-
-#define SYM_FUNC_END_ALIAS_PI(x) \
- SYM_FUNC_END_ALIAS(x); \
- SYM_FUNC_END_ALIAS(__pi_##x)
-
#endif
diff --git a/arch/arm64/include/asm/lse.h b/arch/arm64/include/asm/lse.h
index 5d10051c3e62..29c85810ae69 100644
--- a/arch/arm64/include/asm/lse.h
+++ b/arch/arm64/include/asm/lse.h
@@ -17,12 +17,10 @@
#include <asm/cpucaps.h>
extern struct static_key_false cpu_hwcap_keys[ARM64_NCAPS];
-extern struct static_key_false arm64_const_caps_ready;
-static inline bool system_uses_lse_atomics(void)
+static __always_inline bool system_uses_lse_atomics(void)
{
- return (static_branch_likely(&arm64_const_caps_ready)) &&
- static_branch_likely(&cpu_hwcap_keys[ARM64_HAS_LSE_ATOMICS]);
+ return static_branch_likely(&cpu_hwcap_keys[ARM64_HAS_LSE_ATOMICS]);
}
#define __lse_ll_sc_body(op, ...) \
diff --git a/arch/arm64/include/asm/module.lds.h b/arch/arm64/include/asm/module.lds.h
index a11ccadd47d2..094701ec5500 100644
--- a/arch/arm64/include/asm/module.lds.h
+++ b/arch/arm64/include/asm/module.lds.h
@@ -1,8 +1,8 @@
SECTIONS {
#ifdef CONFIG_ARM64_MODULE_PLTS
- .plt 0 (NOLOAD) : { BYTE(0) }
- .init.plt 0 (NOLOAD) : { BYTE(0) }
- .text.ftrace_trampoline 0 (NOLOAD) : { BYTE(0) }
+ .plt 0 : { BYTE(0) }
+ .init.plt 0 : { BYTE(0) }
+ .text.ftrace_trampoline 0 : { BYTE(0) }
#endif
#ifdef CONFIG_KASAN_SW_TAGS
diff --git a/arch/arm64/include/asm/mte-def.h b/arch/arm64/include/asm/mte-def.h
index 626d359b396e..14ee86b019c2 100644
--- a/arch/arm64/include/asm/mte-def.h
+++ b/arch/arm64/include/asm/mte-def.h
@@ -11,6 +11,7 @@
#define MTE_TAG_SHIFT 56
#define MTE_TAG_SIZE 4
#define MTE_TAG_MASK GENMASK((MTE_TAG_SHIFT + (MTE_TAG_SIZE - 1)), MTE_TAG_SHIFT)
+#define MTE_PAGE_TAG_STORAGE (MTE_GRANULES_PER_PAGE * MTE_TAG_SIZE / 8)
#define __MTE_PREAMBLE ARM64_ASM_PREAMBLE ".arch_extension memtag\n"
diff --git a/arch/arm64/include/asm/mte-kasan.h b/arch/arm64/include/asm/mte-kasan.h
index e4704a403237..a857bcacf0fe 100644
--- a/arch/arm64/include/asm/mte-kasan.h
+++ b/arch/arm64/include/asm/mte-kasan.h
@@ -5,6 +5,7 @@
#ifndef __ASM_MTE_KASAN_H
#define __ASM_MTE_KASAN_H
+#include <asm/compiler.h>
#include <asm/mte-def.h>
#ifndef __ASSEMBLY__
diff --git a/arch/arm64/include/asm/mte.h b/arch/arm64/include/asm/mte.h
index 075539f5f1c8..adcb937342f1 100644
--- a/arch/arm64/include/asm/mte.h
+++ b/arch/arm64/include/asm/mte.h
@@ -11,7 +11,9 @@
#ifndef __ASSEMBLY__
#include <linux/bitfield.h>
+#include <linux/kasan-enabled.h>
#include <linux/page-flags.h>
+#include <linux/sched.h>
#include <linux/types.h>
#include <asm/pgtable-types.h>
@@ -86,6 +88,26 @@ static inline int mte_ptrace_copy_tags(struct task_struct *child,
#endif /* CONFIG_ARM64_MTE */
+static inline void mte_disable_tco_entry(struct task_struct *task)
+{
+ if (!system_supports_mte())
+ return;
+
+ /*
+ * Re-enable tag checking (TCO set on exception entry). This is only
+ * necessary if MTE is enabled in either the kernel or the userspace
+ * task in synchronous or asymmetric mode (SCTLR_EL1.TCF0 bit 0 is set
+ * for both). With MTE disabled in the kernel and disabled or
+ * asynchronous in userspace, tag check faults (including in uaccesses)
+ * are not reported, therefore there is no need to re-enable checking.
+ * This is beneficial on microarchitectures where re-enabling TCO is
+ * expensive.
+ */
+ if (kasan_hw_tags_enabled() ||
+ (task->thread.sctlr_user & (1UL << SCTLR_EL1_TCF0_SHIFT)))
+ asm volatile(SET_PSTATE_TCO(0));
+}
+
#ifdef CONFIG_KASAN_HW_TAGS
/* Whether the MTE asynchronous mode is enabled. */
DECLARE_STATIC_KEY_FALSE(mte_async_or_asymm_mode);
diff --git a/arch/arm64/include/asm/paravirt_api_clock.h b/arch/arm64/include/asm/paravirt_api_clock.h
new file mode 100644
index 000000000000..65ac7cee0dad
--- /dev/null
+++ b/arch/arm64/include/asm/paravirt_api_clock.h
@@ -0,0 +1 @@
+#include <asm/paravirt.h>
diff --git a/arch/arm64/include/asm/perf_event.h b/arch/arm64/include/asm/perf_event.h
index 4ef6f19331f9..3eaf462f5752 100644
--- a/arch/arm64/include/asm/perf_event.h
+++ b/arch/arm64/include/asm/perf_event.h
@@ -15,70 +15,70 @@
/*
* Common architectural and microarchitectural event numbers.
*/
-#define ARMV8_PMUV3_PERFCTR_SW_INCR 0x00
-#define ARMV8_PMUV3_PERFCTR_L1I_CACHE_REFILL 0x01
-#define ARMV8_PMUV3_PERFCTR_L1I_TLB_REFILL 0x02
-#define ARMV8_PMUV3_PERFCTR_L1D_CACHE_REFILL 0x03
-#define ARMV8_PMUV3_PERFCTR_L1D_CACHE 0x04
-#define ARMV8_PMUV3_PERFCTR_L1D_TLB_REFILL 0x05
-#define ARMV8_PMUV3_PERFCTR_LD_RETIRED 0x06
-#define ARMV8_PMUV3_PERFCTR_ST_RETIRED 0x07
-#define ARMV8_PMUV3_PERFCTR_INST_RETIRED 0x08
-#define ARMV8_PMUV3_PERFCTR_EXC_TAKEN 0x09
-#define ARMV8_PMUV3_PERFCTR_EXC_RETURN 0x0A
-#define ARMV8_PMUV3_PERFCTR_CID_WRITE_RETIRED 0x0B
-#define ARMV8_PMUV3_PERFCTR_PC_WRITE_RETIRED 0x0C
-#define ARMV8_PMUV3_PERFCTR_BR_IMMED_RETIRED 0x0D
-#define ARMV8_PMUV3_PERFCTR_BR_RETURN_RETIRED 0x0E
-#define ARMV8_PMUV3_PERFCTR_UNALIGNED_LDST_RETIRED 0x0F
-#define ARMV8_PMUV3_PERFCTR_BR_MIS_PRED 0x10
-#define ARMV8_PMUV3_PERFCTR_CPU_CYCLES 0x11
-#define ARMV8_PMUV3_PERFCTR_BR_PRED 0x12
-#define ARMV8_PMUV3_PERFCTR_MEM_ACCESS 0x13
-#define ARMV8_PMUV3_PERFCTR_L1I_CACHE 0x14
-#define ARMV8_PMUV3_PERFCTR_L1D_CACHE_WB 0x15
-#define ARMV8_PMUV3_PERFCTR_L2D_CACHE 0x16
-#define ARMV8_PMUV3_PERFCTR_L2D_CACHE_REFILL 0x17
-#define ARMV8_PMUV3_PERFCTR_L2D_CACHE_WB 0x18
-#define ARMV8_PMUV3_PERFCTR_BUS_ACCESS 0x19
-#define ARMV8_PMUV3_PERFCTR_MEMORY_ERROR 0x1A
-#define ARMV8_PMUV3_PERFCTR_INST_SPEC 0x1B
-#define ARMV8_PMUV3_PERFCTR_TTBR_WRITE_RETIRED 0x1C
-#define ARMV8_PMUV3_PERFCTR_BUS_CYCLES 0x1D
-#define ARMV8_PMUV3_PERFCTR_CHAIN 0x1E
-#define ARMV8_PMUV3_PERFCTR_L1D_CACHE_ALLOCATE 0x1F
-#define ARMV8_PMUV3_PERFCTR_L2D_CACHE_ALLOCATE 0x20
-#define ARMV8_PMUV3_PERFCTR_BR_RETIRED 0x21
-#define ARMV8_PMUV3_PERFCTR_BR_MIS_PRED_RETIRED 0x22
-#define ARMV8_PMUV3_PERFCTR_STALL_FRONTEND 0x23
-#define ARMV8_PMUV3_PERFCTR_STALL_BACKEND 0x24
-#define ARMV8_PMUV3_PERFCTR_L1D_TLB 0x25
-#define ARMV8_PMUV3_PERFCTR_L1I_TLB 0x26
-#define ARMV8_PMUV3_PERFCTR_L2I_CACHE 0x27
-#define ARMV8_PMUV3_PERFCTR_L2I_CACHE_REFILL 0x28
-#define ARMV8_PMUV3_PERFCTR_L3D_CACHE_ALLOCATE 0x29
-#define ARMV8_PMUV3_PERFCTR_L3D_CACHE_REFILL 0x2A
-#define ARMV8_PMUV3_PERFCTR_L3D_CACHE 0x2B
-#define ARMV8_PMUV3_PERFCTR_L3D_CACHE_WB 0x2C
-#define ARMV8_PMUV3_PERFCTR_L2D_TLB_REFILL 0x2D
-#define ARMV8_PMUV3_PERFCTR_L2I_TLB_REFILL 0x2E
-#define ARMV8_PMUV3_PERFCTR_L2D_TLB 0x2F
-#define ARMV8_PMUV3_PERFCTR_L2I_TLB 0x30
-#define ARMV8_PMUV3_PERFCTR_REMOTE_ACCESS 0x31
-#define ARMV8_PMUV3_PERFCTR_LL_CACHE 0x32
-#define ARMV8_PMUV3_PERFCTR_LL_CACHE_MISS 0x33
-#define ARMV8_PMUV3_PERFCTR_DTLB_WALK 0x34
-#define ARMV8_PMUV3_PERFCTR_ITLB_WALK 0x35
-#define ARMV8_PMUV3_PERFCTR_LL_CACHE_RD 0x36
-#define ARMV8_PMUV3_PERFCTR_LL_CACHE_MISS_RD 0x37
-#define ARMV8_PMUV3_PERFCTR_REMOTE_ACCESS_RD 0x38
-#define ARMV8_PMUV3_PERFCTR_L1D_CACHE_LMISS_RD 0x39
-#define ARMV8_PMUV3_PERFCTR_OP_RETIRED 0x3A
-#define ARMV8_PMUV3_PERFCTR_OP_SPEC 0x3B
-#define ARMV8_PMUV3_PERFCTR_STALL 0x3C
-#define ARMV8_PMUV3_PERFCTR_STALL_SLOT_BACKEND 0x3D
-#define ARMV8_PMUV3_PERFCTR_STALL_SLOT_FRONTEND 0x3E
-#define ARMV8_PMUV3_PERFCTR_STALL_SLOT 0x3F
+#define ARMV8_PMUV3_PERFCTR_SW_INCR 0x0000
+#define ARMV8_PMUV3_PERFCTR_L1I_CACHE_REFILL 0x0001
+#define ARMV8_PMUV3_PERFCTR_L1I_TLB_REFILL 0x0002
+#define ARMV8_PMUV3_PERFCTR_L1D_CACHE_REFILL 0x0003
+#define ARMV8_PMUV3_PERFCTR_L1D_CACHE 0x0004
+#define ARMV8_PMUV3_PERFCTR_L1D_TLB_REFILL 0x0005
+#define ARMV8_PMUV3_PERFCTR_LD_RETIRED 0x0006
+#define ARMV8_PMUV3_PERFCTR_ST_RETIRED 0x0007
+#define ARMV8_PMUV3_PERFCTR_INST_RETIRED 0x0008
+#define ARMV8_PMUV3_PERFCTR_EXC_TAKEN 0x0009
+#define ARMV8_PMUV3_PERFCTR_EXC_RETURN 0x000A
+#define ARMV8_PMUV3_PERFCTR_CID_WRITE_RETIRED 0x000B
+#define ARMV8_PMUV3_PERFCTR_PC_WRITE_RETIRED 0x000C
+#define ARMV8_PMUV3_PERFCTR_BR_IMMED_RETIRED 0x000D
+#define ARMV8_PMUV3_PERFCTR_BR_RETURN_RETIRED 0x000E
+#define ARMV8_PMUV3_PERFCTR_UNALIGNED_LDST_RETIRED 0x000F
+#define ARMV8_PMUV3_PERFCTR_BR_MIS_PRED 0x0010
+#define ARMV8_PMUV3_PERFCTR_CPU_CYCLES 0x0011
+#define ARMV8_PMUV3_PERFCTR_BR_PRED 0x0012
+#define ARMV8_PMUV3_PERFCTR_MEM_ACCESS 0x0013
+#define ARMV8_PMUV3_PERFCTR_L1I_CACHE 0x0014
+#define ARMV8_PMUV3_PERFCTR_L1D_CACHE_WB 0x0015
+#define ARMV8_PMUV3_PERFCTR_L2D_CACHE 0x0016
+#define ARMV8_PMUV3_PERFCTR_L2D_CACHE_REFILL 0x0017
+#define ARMV8_PMUV3_PERFCTR_L2D_CACHE_WB 0x0018
+#define ARMV8_PMUV3_PERFCTR_BUS_ACCESS 0x0019
+#define ARMV8_PMUV3_PERFCTR_MEMORY_ERROR 0x001A
+#define ARMV8_PMUV3_PERFCTR_INST_SPEC 0x001B
+#define ARMV8_PMUV3_PERFCTR_TTBR_WRITE_RETIRED 0x001C
+#define ARMV8_PMUV3_PERFCTR_BUS_CYCLES 0x001D
+#define ARMV8_PMUV3_PERFCTR_CHAIN 0x001E
+#define ARMV8_PMUV3_PERFCTR_L1D_CACHE_ALLOCATE 0x001F
+#define ARMV8_PMUV3_PERFCTR_L2D_CACHE_ALLOCATE 0x0020
+#define ARMV8_PMUV3_PERFCTR_BR_RETIRED 0x0021
+#define ARMV8_PMUV3_PERFCTR_BR_MIS_PRED_RETIRED 0x0022
+#define ARMV8_PMUV3_PERFCTR_STALL_FRONTEND 0x0023
+#define ARMV8_PMUV3_PERFCTR_STALL_BACKEND 0x0024
+#define ARMV8_PMUV3_PERFCTR_L1D_TLB 0x0025
+#define ARMV8_PMUV3_PERFCTR_L1I_TLB 0x0026
+#define ARMV8_PMUV3_PERFCTR_L2I_CACHE 0x0027
+#define ARMV8_PMUV3_PERFCTR_L2I_CACHE_REFILL 0x0028
+#define ARMV8_PMUV3_PERFCTR_L3D_CACHE_ALLOCATE 0x0029
+#define ARMV8_PMUV3_PERFCTR_L3D_CACHE_REFILL 0x002A
+#define ARMV8_PMUV3_PERFCTR_L3D_CACHE 0x002B
+#define ARMV8_PMUV3_PERFCTR_L3D_CACHE_WB 0x002C
+#define ARMV8_PMUV3_PERFCTR_L2D_TLB_REFILL 0x002D
+#define ARMV8_PMUV3_PERFCTR_L2I_TLB_REFILL 0x002E
+#define ARMV8_PMUV3_PERFCTR_L2D_TLB 0x002F
+#define ARMV8_PMUV3_PERFCTR_L2I_TLB 0x0030
+#define ARMV8_PMUV3_PERFCTR_REMOTE_ACCESS 0x0031
+#define ARMV8_PMUV3_PERFCTR_LL_CACHE 0x0032
+#define ARMV8_PMUV3_PERFCTR_LL_CACHE_MISS 0x0033
+#define ARMV8_PMUV3_PERFCTR_DTLB_WALK 0x0034
+#define ARMV8_PMUV3_PERFCTR_ITLB_WALK 0x0035
+#define ARMV8_PMUV3_PERFCTR_LL_CACHE_RD 0x0036
+#define ARMV8_PMUV3_PERFCTR_LL_CACHE_MISS_RD 0x0037
+#define ARMV8_PMUV3_PERFCTR_REMOTE_ACCESS_RD 0x0038
+#define ARMV8_PMUV3_PERFCTR_L1D_CACHE_LMISS_RD 0x0039
+#define ARMV8_PMUV3_PERFCTR_OP_RETIRED 0x003A
+#define ARMV8_PMUV3_PERFCTR_OP_SPEC 0x003B
+#define ARMV8_PMUV3_PERFCTR_STALL 0x003C
+#define ARMV8_PMUV3_PERFCTR_STALL_SLOT_BACKEND 0x003D
+#define ARMV8_PMUV3_PERFCTR_STALL_SLOT_FRONTEND 0x003E
+#define ARMV8_PMUV3_PERFCTR_STALL_SLOT 0x003F
/* Statistical profiling extension microarchitectural events */
#define ARMV8_SPE_PERFCTR_SAMPLE_POP 0x4000
@@ -96,6 +96,20 @@
#define ARMV8_PMUV3_PERFCTR_L2I_CACHE_LMISS 0x400A
#define ARMV8_PMUV3_PERFCTR_L3D_CACHE_LMISS_RD 0x400B
+/* Trace buffer events */
+#define ARMV8_PMUV3_PERFCTR_TRB_WRAP 0x400C
+#define ARMV8_PMUV3_PERFCTR_TRB_TRIG 0x400E
+
+/* Trace unit events */
+#define ARMV8_PMUV3_PERFCTR_TRCEXTOUT0 0x4010
+#define ARMV8_PMUV3_PERFCTR_TRCEXTOUT1 0x4011
+#define ARMV8_PMUV3_PERFCTR_TRCEXTOUT2 0x4012
+#define ARMV8_PMUV3_PERFCTR_TRCEXTOUT3 0x4013
+#define ARMV8_PMUV3_PERFCTR_CTI_TRIGOUT4 0x4018
+#define ARMV8_PMUV3_PERFCTR_CTI_TRIGOUT5 0x4019
+#define ARMV8_PMUV3_PERFCTR_CTI_TRIGOUT6 0x401A
+#define ARMV8_PMUV3_PERFCTR_CTI_TRIGOUT7 0x401B
+
/* additional latency from alignment events */
#define ARMV8_PMUV3_PERFCTR_LDST_ALIGN_LAT 0x4020
#define ARMV8_PMUV3_PERFCTR_LD_ALIGN_LAT 0x4021
@@ -107,91 +121,91 @@
#define ARMV8_MTE_PERFCTR_MEM_ACCESS_CHECKED_WR 0x4026
/* ARMv8 recommended implementation defined event types */
-#define ARMV8_IMPDEF_PERFCTR_L1D_CACHE_RD 0x40
-#define ARMV8_IMPDEF_PERFCTR_L1D_CACHE_WR 0x41
-#define ARMV8_IMPDEF_PERFCTR_L1D_CACHE_REFILL_RD 0x42
-#define ARMV8_IMPDEF_PERFCTR_L1D_CACHE_REFILL_WR 0x43
-#define ARMV8_IMPDEF_PERFCTR_L1D_CACHE_REFILL_INNER 0x44
-#define ARMV8_IMPDEF_PERFCTR_L1D_CACHE_REFILL_OUTER 0x45
-#define ARMV8_IMPDEF_PERFCTR_L1D_CACHE_WB_VICTIM 0x46
-#define ARMV8_IMPDEF_PERFCTR_L1D_CACHE_WB_CLEAN 0x47
-#define ARMV8_IMPDEF_PERFCTR_L1D_CACHE_INVAL 0x48
-
-#define ARMV8_IMPDEF_PERFCTR_L1D_TLB_REFILL_RD 0x4C
-#define ARMV8_IMPDEF_PERFCTR_L1D_TLB_REFILL_WR 0x4D
-#define ARMV8_IMPDEF_PERFCTR_L1D_TLB_RD 0x4E
-#define ARMV8_IMPDEF_PERFCTR_L1D_TLB_WR 0x4F
-#define ARMV8_IMPDEF_PERFCTR_L2D_CACHE_RD 0x50
-#define ARMV8_IMPDEF_PERFCTR_L2D_CACHE_WR 0x51
-#define ARMV8_IMPDEF_PERFCTR_L2D_CACHE_REFILL_RD 0x52
-#define ARMV8_IMPDEF_PERFCTR_L2D_CACHE_REFILL_WR 0x53
-
-#define ARMV8_IMPDEF_PERFCTR_L2D_CACHE_WB_VICTIM 0x56
-#define ARMV8_IMPDEF_PERFCTR_L2D_CACHE_WB_CLEAN 0x57
-#define ARMV8_IMPDEF_PERFCTR_L2D_CACHE_INVAL 0x58
-
-#define ARMV8_IMPDEF_PERFCTR_L2D_TLB_REFILL_RD 0x5C
-#define ARMV8_IMPDEF_PERFCTR_L2D_TLB_REFILL_WR 0x5D
-#define ARMV8_IMPDEF_PERFCTR_L2D_TLB_RD 0x5E
-#define ARMV8_IMPDEF_PERFCTR_L2D_TLB_WR 0x5F
-#define ARMV8_IMPDEF_PERFCTR_BUS_ACCESS_RD 0x60
-#define ARMV8_IMPDEF_PERFCTR_BUS_ACCESS_WR 0x61
-#define ARMV8_IMPDEF_PERFCTR_BUS_ACCESS_SHARED 0x62
-#define ARMV8_IMPDEF_PERFCTR_BUS_ACCESS_NOT_SHARED 0x63
-#define ARMV8_IMPDEF_PERFCTR_BUS_ACCESS_NORMAL 0x64
-#define ARMV8_IMPDEF_PERFCTR_BUS_ACCESS_PERIPH 0x65
-#define ARMV8_IMPDEF_PERFCTR_MEM_ACCESS_RD 0x66
-#define ARMV8_IMPDEF_PERFCTR_MEM_ACCESS_WR 0x67
-#define ARMV8_IMPDEF_PERFCTR_UNALIGNED_LD_SPEC 0x68
-#define ARMV8_IMPDEF_PERFCTR_UNALIGNED_ST_SPEC 0x69
-#define ARMV8_IMPDEF_PERFCTR_UNALIGNED_LDST_SPEC 0x6A
-
-#define ARMV8_IMPDEF_PERFCTR_LDREX_SPEC 0x6C
-#define ARMV8_IMPDEF_PERFCTR_STREX_PASS_SPEC 0x6D
-#define ARMV8_IMPDEF_PERFCTR_STREX_FAIL_SPEC 0x6E
-#define ARMV8_IMPDEF_PERFCTR_STREX_SPEC 0x6F
-#define ARMV8_IMPDEF_PERFCTR_LD_SPEC 0x70
-#define ARMV8_IMPDEF_PERFCTR_ST_SPEC 0x71
-#define ARMV8_IMPDEF_PERFCTR_LDST_SPEC 0x72
-#define ARMV8_IMPDEF_PERFCTR_DP_SPEC 0x73
-#define ARMV8_IMPDEF_PERFCTR_ASE_SPEC 0x74
-#define ARMV8_IMPDEF_PERFCTR_VFP_SPEC 0x75
-#define ARMV8_IMPDEF_PERFCTR_PC_WRITE_SPEC 0x76
-#define ARMV8_IMPDEF_PERFCTR_CRYPTO_SPEC 0x77
-#define ARMV8_IMPDEF_PERFCTR_BR_IMMED_SPEC 0x78
-#define ARMV8_IMPDEF_PERFCTR_BR_RETURN_SPEC 0x79
-#define ARMV8_IMPDEF_PERFCTR_BR_INDIRECT_SPEC 0x7A
-
-#define ARMV8_IMPDEF_PERFCTR_ISB_SPEC 0x7C
-#define ARMV8_IMPDEF_PERFCTR_DSB_SPEC 0x7D
-#define ARMV8_IMPDEF_PERFCTR_DMB_SPEC 0x7E
-
-#define ARMV8_IMPDEF_PERFCTR_EXC_UNDEF 0x81
-#define ARMV8_IMPDEF_PERFCTR_EXC_SVC 0x82
-#define ARMV8_IMPDEF_PERFCTR_EXC_PABORT 0x83
-#define ARMV8_IMPDEF_PERFCTR_EXC_DABORT 0x84
-
-#define ARMV8_IMPDEF_PERFCTR_EXC_IRQ 0x86
-#define ARMV8_IMPDEF_PERFCTR_EXC_FIQ 0x87
-#define ARMV8_IMPDEF_PERFCTR_EXC_SMC 0x88
-
-#define ARMV8_IMPDEF_PERFCTR_EXC_HVC 0x8A
-#define ARMV8_IMPDEF_PERFCTR_EXC_TRAP_PABORT 0x8B
-#define ARMV8_IMPDEF_PERFCTR_EXC_TRAP_DABORT 0x8C
-#define ARMV8_IMPDEF_PERFCTR_EXC_TRAP_OTHER 0x8D
-#define ARMV8_IMPDEF_PERFCTR_EXC_TRAP_IRQ 0x8E
-#define ARMV8_IMPDEF_PERFCTR_EXC_TRAP_FIQ 0x8F
-#define ARMV8_IMPDEF_PERFCTR_RC_LD_SPEC 0x90
-#define ARMV8_IMPDEF_PERFCTR_RC_ST_SPEC 0x91
-
-#define ARMV8_IMPDEF_PERFCTR_L3D_CACHE_RD 0xA0
-#define ARMV8_IMPDEF_PERFCTR_L3D_CACHE_WR 0xA1
-#define ARMV8_IMPDEF_PERFCTR_L3D_CACHE_REFILL_RD 0xA2
-#define ARMV8_IMPDEF_PERFCTR_L3D_CACHE_REFILL_WR 0xA3
-
-#define ARMV8_IMPDEF_PERFCTR_L3D_CACHE_WB_VICTIM 0xA6
-#define ARMV8_IMPDEF_PERFCTR_L3D_CACHE_WB_CLEAN 0xA7
-#define ARMV8_IMPDEF_PERFCTR_L3D_CACHE_INVAL 0xA8
+#define ARMV8_IMPDEF_PERFCTR_L1D_CACHE_RD 0x0040
+#define ARMV8_IMPDEF_PERFCTR_L1D_CACHE_WR 0x0041
+#define ARMV8_IMPDEF_PERFCTR_L1D_CACHE_REFILL_RD 0x0042
+#define ARMV8_IMPDEF_PERFCTR_L1D_CACHE_REFILL_WR 0x0043
+#define ARMV8_IMPDEF_PERFCTR_L1D_CACHE_REFILL_INNER 0x0044
+#define ARMV8_IMPDEF_PERFCTR_L1D_CACHE_REFILL_OUTER 0x0045
+#define ARMV8_IMPDEF_PERFCTR_L1D_CACHE_WB_VICTIM 0x0046
+#define ARMV8_IMPDEF_PERFCTR_L1D_CACHE_WB_CLEAN 0x0047
+#define ARMV8_IMPDEF_PERFCTR_L1D_CACHE_INVAL 0x0048
+
+#define ARMV8_IMPDEF_PERFCTR_L1D_TLB_REFILL_RD 0x004C
+#define ARMV8_IMPDEF_PERFCTR_L1D_TLB_REFILL_WR 0x004D
+#define ARMV8_IMPDEF_PERFCTR_L1D_TLB_RD 0x004E
+#define ARMV8_IMPDEF_PERFCTR_L1D_TLB_WR 0x004F
+#define ARMV8_IMPDEF_PERFCTR_L2D_CACHE_RD 0x0050
+#define ARMV8_IMPDEF_PERFCTR_L2D_CACHE_WR 0x0051
+#define ARMV8_IMPDEF_PERFCTR_L2D_CACHE_REFILL_RD 0x0052
+#define ARMV8_IMPDEF_PERFCTR_L2D_CACHE_REFILL_WR 0x0053
+
+#define ARMV8_IMPDEF_PERFCTR_L2D_CACHE_WB_VICTIM 0x0056
+#define ARMV8_IMPDEF_PERFCTR_L2D_CACHE_WB_CLEAN 0x0057
+#define ARMV8_IMPDEF_PERFCTR_L2D_CACHE_INVAL 0x0058
+
+#define ARMV8_IMPDEF_PERFCTR_L2D_TLB_REFILL_RD 0x005C
+#define ARMV8_IMPDEF_PERFCTR_L2D_TLB_REFILL_WR 0x005D
+#define ARMV8_IMPDEF_PERFCTR_L2D_TLB_RD 0x005E
+#define ARMV8_IMPDEF_PERFCTR_L2D_TLB_WR 0x005F
+#define ARMV8_IMPDEF_PERFCTR_BUS_ACCESS_RD 0x0060
+#define ARMV8_IMPDEF_PERFCTR_BUS_ACCESS_WR 0x0061
+#define ARMV8_IMPDEF_PERFCTR_BUS_ACCESS_SHARED 0x0062
+#define ARMV8_IMPDEF_PERFCTR_BUS_ACCESS_NOT_SHARED 0x0063
+#define ARMV8_IMPDEF_PERFCTR_BUS_ACCESS_NORMAL 0x0064
+#define ARMV8_IMPDEF_PERFCTR_BUS_ACCESS_PERIPH 0x0065
+#define ARMV8_IMPDEF_PERFCTR_MEM_ACCESS_RD 0x0066
+#define ARMV8_IMPDEF_PERFCTR_MEM_ACCESS_WR 0x0067
+#define ARMV8_IMPDEF_PERFCTR_UNALIGNED_LD_SPEC 0x0068
+#define ARMV8_IMPDEF_PERFCTR_UNALIGNED_ST_SPEC 0x0069
+#define ARMV8_IMPDEF_PERFCTR_UNALIGNED_LDST_SPEC 0x006A
+
+#define ARMV8_IMPDEF_PERFCTR_LDREX_SPEC 0x006C
+#define ARMV8_IMPDEF_PERFCTR_STREX_PASS_SPEC 0x006D
+#define ARMV8_IMPDEF_PERFCTR_STREX_FAIL_SPEC 0x006E
+#define ARMV8_IMPDEF_PERFCTR_STREX_SPEC 0x006F
+#define ARMV8_IMPDEF_PERFCTR_LD_SPEC 0x0070
+#define ARMV8_IMPDEF_PERFCTR_ST_SPEC 0x0071
+#define ARMV8_IMPDEF_PERFCTR_LDST_SPEC 0x0072
+#define ARMV8_IMPDEF_PERFCTR_DP_SPEC 0x0073
+#define ARMV8_IMPDEF_PERFCTR_ASE_SPEC 0x0074
+#define ARMV8_IMPDEF_PERFCTR_VFP_SPEC 0x0075
+#define ARMV8_IMPDEF_PERFCTR_PC_WRITE_SPEC 0x0076
+#define ARMV8_IMPDEF_PERFCTR_CRYPTO_SPEC 0x0077
+#define ARMV8_IMPDEF_PERFCTR_BR_IMMED_SPEC 0x0078
+#define ARMV8_IMPDEF_PERFCTR_BR_RETURN_SPEC 0x0079
+#define ARMV8_IMPDEF_PERFCTR_BR_INDIRECT_SPEC 0x007A
+
+#define ARMV8_IMPDEF_PERFCTR_ISB_SPEC 0x007C
+#define ARMV8_IMPDEF_PERFCTR_DSB_SPEC 0x007D
+#define ARMV8_IMPDEF_PERFCTR_DMB_SPEC 0x007E
+
+#define ARMV8_IMPDEF_PERFCTR_EXC_UNDEF 0x0081
+#define ARMV8_IMPDEF_PERFCTR_EXC_SVC 0x0082
+#define ARMV8_IMPDEF_PERFCTR_EXC_PABORT 0x0083
+#define ARMV8_IMPDEF_PERFCTR_EXC_DABORT 0x0084
+
+#define ARMV8_IMPDEF_PERFCTR_EXC_IRQ 0x0086
+#define ARMV8_IMPDEF_PERFCTR_EXC_FIQ 0x0087
+#define ARMV8_IMPDEF_PERFCTR_EXC_SMC 0x0088
+
+#define ARMV8_IMPDEF_PERFCTR_EXC_HVC 0x008A
+#define ARMV8_IMPDEF_PERFCTR_EXC_TRAP_PABORT 0x008B
+#define ARMV8_IMPDEF_PERFCTR_EXC_TRAP_DABORT 0x008C
+#define ARMV8_IMPDEF_PERFCTR_EXC_TRAP_OTHER 0x008D
+#define ARMV8_IMPDEF_PERFCTR_EXC_TRAP_IRQ 0x008E
+#define ARMV8_IMPDEF_PERFCTR_EXC_TRAP_FIQ 0x008F
+#define ARMV8_IMPDEF_PERFCTR_RC_LD_SPEC 0x0090
+#define ARMV8_IMPDEF_PERFCTR_RC_ST_SPEC 0x0091
+
+#define ARMV8_IMPDEF_PERFCTR_L3D_CACHE_RD 0x00A0
+#define ARMV8_IMPDEF_PERFCTR_L3D_CACHE_WR 0x00A1
+#define ARMV8_IMPDEF_PERFCTR_L3D_CACHE_REFILL_RD 0x00A2
+#define ARMV8_IMPDEF_PERFCTR_L3D_CACHE_REFILL_WR 0x00A3
+
+#define ARMV8_IMPDEF_PERFCTR_L3D_CACHE_WB_VICTIM 0x00A6
+#define ARMV8_IMPDEF_PERFCTR_L3D_CACHE_WB_CLEAN 0x00A7
+#define ARMV8_IMPDEF_PERFCTR_L3D_CACHE_INVAL 0x00A8
/*
* Per-CPU PMCR: config reg
diff --git a/arch/arm64/include/asm/pgtable-hwdef.h b/arch/arm64/include/asm/pgtable-hwdef.h
index 40085e53f573..66671ff05183 100644
--- a/arch/arm64/include/asm/pgtable-hwdef.h
+++ b/arch/arm64/include/asm/pgtable-hwdef.h
@@ -273,6 +273,8 @@
#define TCR_NFD1 (UL(1) << 54)
#define TCR_E0PD0 (UL(1) << 55)
#define TCR_E0PD1 (UL(1) << 56)
+#define TCR_TCMA0 (UL(1) << 57)
+#define TCR_TCMA1 (UL(1) << 58)
/*
* TTBR.
diff --git a/arch/arm64/include/asm/pgtable-prot.h b/arch/arm64/include/asm/pgtable-prot.h
index 7032f04c8ac6..b1e1b74d993c 100644
--- a/arch/arm64/include/asm/pgtable-prot.h
+++ b/arch/arm64/include/asm/pgtable-prot.h
@@ -92,7 +92,7 @@ extern bool arm64_use_ng_mappings;
#define __P001 PAGE_READONLY
#define __P010 PAGE_READONLY
#define __P011 PAGE_READONLY
-#define __P100 PAGE_EXECONLY
+#define __P100 PAGE_READONLY_EXEC /* PAGE_EXECONLY if Enhanced PAN */
#define __P101 PAGE_READONLY_EXEC
#define __P110 PAGE_READONLY_EXEC
#define __P111 PAGE_READONLY_EXEC
@@ -101,7 +101,7 @@ extern bool arm64_use_ng_mappings;
#define __S001 PAGE_READONLY
#define __S010 PAGE_SHARED
#define __S011 PAGE_SHARED
-#define __S100 PAGE_EXECONLY
+#define __S100 PAGE_READONLY_EXEC /* PAGE_EXECONLY if Enhanced PAN */
#define __S101 PAGE_READONLY_EXEC
#define __S110 PAGE_SHARED_EXEC
#define __S111 PAGE_SHARED_EXEC
diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
index c4ba047a82d2..94e147e5456c 100644
--- a/arch/arm64/include/asm/pgtable.h
+++ b/arch/arm64/include/asm/pgtable.h
@@ -1017,17 +1017,6 @@ static inline bool arch_wants_old_prefaulted_pte(void)
}
#define arch_wants_old_prefaulted_pte arch_wants_old_prefaulted_pte
-static inline pgprot_t arch_filter_pgprot(pgprot_t prot)
-{
- if (cpus_have_const_cap(ARM64_HAS_EPAN))
- return prot;
-
- if (pgprot_val(prot) != pgprot_val(PAGE_EXECONLY))
- return prot;
-
- return PAGE_READONLY_EXEC;
-}
-
static inline bool pud_sect_supported(void)
{
return PAGE_SIZE == SZ_4K;
diff --git a/arch/arm64/include/asm/preempt.h b/arch/arm64/include/asm/preempt.h
index e83f0982b99c..0159b625cc7f 100644
--- a/arch/arm64/include/asm/preempt.h
+++ b/arch/arm64/include/asm/preempt.h
@@ -2,6 +2,7 @@
#ifndef __ASM_PREEMPT_H
#define __ASM_PREEMPT_H
+#include <linux/jump_label.h>
#include <linux/thread_info.h>
#define PREEMPT_NEED_RESCHED BIT(32)
@@ -80,10 +81,24 @@ static inline bool should_resched(int preempt_offset)
}
#ifdef CONFIG_PREEMPTION
+
void preempt_schedule(void);
-#define __preempt_schedule() preempt_schedule()
void preempt_schedule_notrace(void);
-#define __preempt_schedule_notrace() preempt_schedule_notrace()
+
+#ifdef CONFIG_PREEMPT_DYNAMIC
+
+DECLARE_STATIC_KEY_TRUE(sk_dynamic_irqentry_exit_cond_resched);
+void dynamic_preempt_schedule(void);
+#define __preempt_schedule() dynamic_preempt_schedule()
+void dynamic_preempt_schedule_notrace(void);
+#define __preempt_schedule_notrace() dynamic_preempt_schedule_notrace()
+
+#else /* CONFIG_PREEMPT_DYNAMIC */
+
+#define __preempt_schedule() preempt_schedule()
+#define __preempt_schedule_notrace() preempt_schedule_notrace()
+
+#endif /* CONFIG_PREEMPT_DYNAMIC */
#endif /* CONFIG_PREEMPTION */
#endif /* __ASM_PREEMPT_H */
diff --git a/arch/arm64/include/asm/processor.h b/arch/arm64/include/asm/processor.h
index 6f41b65f9962..73e38d9a540c 100644
--- a/arch/arm64/include/asm/processor.h
+++ b/arch/arm64/include/asm/processor.h
@@ -21,6 +21,7 @@
#define MTE_CTRL_TCF_SYNC (1UL << 16)
#define MTE_CTRL_TCF_ASYNC (1UL << 17)
+#define MTE_CTRL_TCF_ASYMM (1UL << 18)
#ifndef __ASSEMBLY__
diff --git a/arch/arm64/include/asm/rwonce.h b/arch/arm64/include/asm/rwonce.h
index 1bce62fa908a..56f7b1d4d54b 100644
--- a/arch/arm64/include/asm/rwonce.h
+++ b/arch/arm64/include/asm/rwonce.h
@@ -5,7 +5,7 @@
#ifndef __ASM_RWONCE_H
#define __ASM_RWONCE_H
-#ifdef CONFIG_LTO
+#if defined(CONFIG_LTO) && !defined(__ASSEMBLY__)
#include <linux/compiler_types.h>
#include <asm/alternative-macros.h>
@@ -66,7 +66,7 @@
})
#endif /* !BUILD_VDSO */
-#endif /* CONFIG_LTO */
+#endif /* CONFIG_LTO && !__ASSEMBLY__ */
#include <asm-generic/rwonce.h>
diff --git a/arch/arm64/include/asm/sections.h b/arch/arm64/include/asm/sections.h
index 152cb35bf9df..40971ac1303f 100644
--- a/arch/arm64/include/asm/sections.h
+++ b/arch/arm64/include/asm/sections.h
@@ -23,4 +23,9 @@ extern char __mmuoff_data_start[], __mmuoff_data_end[];
extern char __entry_tramp_text_start[], __entry_tramp_text_end[];
extern char __relocate_new_kernel_start[], __relocate_new_kernel_end[];
+static inline size_t entry_tramp_text_size(void)
+{
+ return __entry_tramp_text_end - __entry_tramp_text_start;
+}
+
#endif /* __ASM_SECTIONS_H */
diff --git a/arch/arm64/include/asm/spectre.h b/arch/arm64/include/asm/spectre.h
index f62ca39da6c5..aa3d3607d5c8 100644
--- a/arch/arm64/include/asm/spectre.h
+++ b/arch/arm64/include/asm/spectre.h
@@ -67,7 +67,8 @@ struct bp_hardening_data {
DECLARE_PER_CPU_READ_MOSTLY(struct bp_hardening_data, bp_hardening_data);
-static inline void arm64_apply_bp_hardening(void)
+/* Called during entry so must be __always_inline */
+static __always_inline void arm64_apply_bp_hardening(void)
{
struct bp_hardening_data *d;
@@ -93,5 +94,9 @@ void spectre_v4_enable_task_mitigation(struct task_struct *tsk);
enum mitigation_state arm64_get_meltdown_state(void);
+enum mitigation_state arm64_get_spectre_bhb_state(void);
+bool is_spectre_bhb_affected(const struct arm64_cpu_capabilities *entry, int scope);
+u8 spectre_bhb_loop_affected(int scope);
+void spectre_bhb_enable_mitigation(const struct arm64_cpu_capabilities *__unused);
#endif /* __ASSEMBLY__ */
#endif /* __ASM_SPECTRE_H */
diff --git a/arch/arm64/include/asm/string.h b/arch/arm64/include/asm/string.h
index 95f7686b728d..3a3264ff47b9 100644
--- a/arch/arm64/include/asm/string.h
+++ b/arch/arm64/include/asm/string.h
@@ -12,13 +12,11 @@ extern char *strrchr(const char *, int c);
#define __HAVE_ARCH_STRCHR
extern char *strchr(const char *, int c);
-#ifndef CONFIG_KASAN_HW_TAGS
#define __HAVE_ARCH_STRCMP
extern int strcmp(const char *, const char *);
#define __HAVE_ARCH_STRNCMP
extern int strncmp(const char *, const char *, __kernel_size_t);
-#endif
#define __HAVE_ARCH_STRLEN
extern __kernel_size_t strlen(const char *);
diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
index 898bee0004ae..fbf5f8bb9055 100644
--- a/arch/arm64/include/asm/sysreg.h
+++ b/arch/arm64/include/asm/sysreg.h
@@ -128,8 +128,16 @@
#define SYS_DBGWVRn_EL1(n) sys_reg(2, 0, 0, n, 6)
#define SYS_DBGWCRn_EL1(n) sys_reg(2, 0, 0, n, 7)
#define SYS_MDRAR_EL1 sys_reg(2, 0, 1, 0, 0)
+
#define SYS_OSLAR_EL1 sys_reg(2, 0, 1, 0, 4)
+#define SYS_OSLAR_OSLK BIT(0)
+
#define SYS_OSLSR_EL1 sys_reg(2, 0, 1, 1, 4)
+#define SYS_OSLSR_OSLM_MASK (BIT(3) | BIT(0))
+#define SYS_OSLSR_OSLM_NI 0
+#define SYS_OSLSR_OSLM_IMPLEMENTED BIT(3)
+#define SYS_OSLSR_OSLK BIT(1)
+
#define SYS_OSDLR_EL1 sys_reg(2, 0, 1, 3, 4)
#define SYS_DBGPRCR_EL1 sys_reg(2, 0, 1, 4, 4)
#define SYS_DBGCLAIMSET_EL1 sys_reg(2, 0, 7, 8, 6)
@@ -773,6 +781,9 @@
#define ID_AA64ISAR1_GPI_IMP_DEF 0x1
/* id_aa64isar2 */
+#define ID_AA64ISAR2_CLEARBHB_SHIFT 28
+#define ID_AA64ISAR2_APA3_SHIFT 12
+#define ID_AA64ISAR2_GPA3_SHIFT 8
#define ID_AA64ISAR2_RPRES_SHIFT 4
#define ID_AA64ISAR2_WFXT_SHIFT 0
@@ -786,6 +797,16 @@
#define ID_AA64ISAR2_WFXT_NI 0x0
#define ID_AA64ISAR2_WFXT_SUPPORTED 0x2
+#define ID_AA64ISAR2_APA3_NI 0x0
+#define ID_AA64ISAR2_APA3_ARCHITECTED 0x1
+#define ID_AA64ISAR2_APA3_ARCH_EPAC 0x2
+#define ID_AA64ISAR2_APA3_ARCH_EPAC2 0x3
+#define ID_AA64ISAR2_APA3_ARCH_EPAC2_FPAC 0x4
+#define ID_AA64ISAR2_APA3_ARCH_EPAC2_FPAC_CMB 0x5
+
+#define ID_AA64ISAR2_GPA3_NI 0x0
+#define ID_AA64ISAR2_GPA3_ARCHITECTED 0x1
+
/* id_aa64pfr0 */
#define ID_AA64PFR0_CSV3_SHIFT 60
#define ID_AA64PFR0_CSV2_SHIFT 56
@@ -904,6 +925,7 @@
#endif
/* id_aa64mmfr1 */
+#define ID_AA64MMFR1_ECBHB_SHIFT 60
#define ID_AA64MMFR1_AFP_SHIFT 44
#define ID_AA64MMFR1_ETS_SHIFT 36
#define ID_AA64MMFR1_TWED_SHIFT 32
@@ -1097,13 +1119,11 @@
#define ZCR_ELx_LEN_SIZE 9
#define ZCR_ELx_LEN_MASK 0x1ff
+#define CPACR_EL1_FPEN_EL1EN (BIT(20)) /* enable EL1 access */
+#define CPACR_EL1_FPEN_EL0EN (BIT(21)) /* enable EL0 access, if EL1EN set */
+
#define CPACR_EL1_ZEN_EL1EN (BIT(16)) /* enable EL1 access */
#define CPACR_EL1_ZEN_EL0EN (BIT(17)) /* enable EL0 access, if EL1EN set */
-#define CPACR_EL1_ZEN (CPACR_EL1_ZEN_EL1EN | CPACR_EL1_ZEN_EL0EN)
-
-/* TCR EL1 Bit Definitions */
-#define SYS_TCR_EL1_TCMA1 (BIT(58))
-#define SYS_TCR_EL1_TCMA0 (BIT(57))
/* GCR_EL1 Definitions */
#define SYS_GCR_EL1_RRND (BIT(16))
diff --git a/arch/arm64/include/asm/topology.h b/arch/arm64/include/asm/topology.h
index f386b90a79c8..9fab663dd2de 100644
--- a/arch/arm64/include/asm/topology.h
+++ b/arch/arm64/include/asm/topology.h
@@ -24,6 +24,10 @@ void update_freq_counters_refs(void);
#define arch_scale_freq_capacity topology_get_freq_scale
#define arch_scale_freq_invariant topology_scale_freq_invariant
+#ifdef CONFIG_ACPI_CPPC_LIB
+#define arch_init_invariance_cppc topology_init_cpu_capacity_cppc
+#endif
+
/* Replace task scheduler's default cpu-invariant accounting */
#define arch_scale_cpu_capacity topology_get_cpu_scale
diff --git a/arch/arm64/include/asm/uaccess.h b/arch/arm64/include/asm/uaccess.h
index 3a5ff5e20586..e8dce0cc5eaa 100644
--- a/arch/arm64/include/asm/uaccess.h
+++ b/arch/arm64/include/asm/uaccess.h
@@ -26,7 +26,7 @@
#include <asm/memory.h>
#include <asm/extable.h>
-#define HAVE_GET_KERNEL_NOFAULT
+static inline int __access_ok(const void __user *ptr, unsigned long size);
/*
* Test whether a block of memory is a valid user space address.
@@ -35,10 +35,8 @@
* This is equivalent to the following test:
* (u65)addr + (u65)size <= (u65)TASK_SIZE_MAX
*/
-static inline unsigned long __range_ok(const void __user *addr, unsigned long size)
+static inline int access_ok(const void __user *addr, unsigned long size)
{
- unsigned long ret, limit = TASK_SIZE_MAX - 1;
-
/*
* Asynchronous I/O running in a kernel thread does not have the
* TIF_TAGGED_ADDR flag of the process owning the mm, so always untag
@@ -48,28 +46,11 @@ static inline unsigned long __range_ok(const void __user *addr, unsigned long si
(current->flags & PF_KTHREAD || test_thread_flag(TIF_TAGGED_ADDR)))
addr = untagged_addr(addr);
- __chk_user_ptr(addr);
- asm volatile(
- // A + B <= C + 1 for all A,B,C, in four easy steps:
- // 1: X = A + B; X' = X % 2^64
- " adds %0, %3, %2\n"
- // 2: Set C = 0 if X > 2^64, to guarantee X' > C in step 4
- " csel %1, xzr, %1, hi\n"
- // 3: Set X' = ~0 if X >= 2^64. For X == 2^64, this decrements X'
- // to compensate for the carry flag being set in step 4. For
- // X > 2^64, X' merely has to remain nonzero, which it does.
- " csinv %0, %0, xzr, cc\n"
- // 4: For X < 2^64, this gives us X' - C - 1 <= 0, where the -1
- // comes from the carry in being clear. Otherwise, we are
- // testing X' - C == 0, subject to the previous adjustments.
- " sbcs xzr, %0, %1\n"
- " cset %0, ls\n"
- : "=&r" (ret), "+r" (limit) : "Ir" (size), "0" (addr) : "cc");
-
- return ret;
+ return likely(__access_ok(addr, size));
}
+#define access_ok access_ok
-#define access_ok(addr, size) __range_ok(addr, size)
+#include <asm-generic/access_ok.h>
/*
* User access enabling/disabling.
diff --git a/arch/arm64/include/asm/vectors.h b/arch/arm64/include/asm/vectors.h
new file mode 100644
index 000000000000..bc9a2145f419
--- /dev/null
+++ b/arch/arm64/include/asm/vectors.h
@@ -0,0 +1,73 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2022 ARM Ltd.
+ */
+#ifndef __ASM_VECTORS_H
+#define __ASM_VECTORS_H
+
+#include <linux/bug.h>
+#include <linux/percpu.h>
+
+#include <asm/fixmap.h>
+
+extern char vectors[];
+extern char tramp_vectors[];
+extern char __bp_harden_el1_vectors[];
+
+/*
+ * Note: the order of this enum corresponds to two arrays in entry.S:
+ * tramp_vecs and __bp_harden_el1_vectors. By default the canonical
+ * 'full fat' vectors are used directly.
+ */
+enum arm64_bp_harden_el1_vectors {
+#ifdef CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY
+ /*
+ * Perform the BHB loop mitigation, before branching to the canonical
+ * vectors.
+ */
+ EL1_VECTOR_BHB_LOOP,
+
+ /*
+ * Make the SMC call for firmware mitigation, before branching to the
+ * canonical vectors.
+ */
+ EL1_VECTOR_BHB_FW,
+
+ /*
+ * Use the ClearBHB instruction, before branching to the canonical
+ * vectors.
+ */
+ EL1_VECTOR_BHB_CLEAR_INSN,
+#endif /* CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY */
+
+ /*
+ * Remap the kernel before branching to the canonical vectors.
+ */
+ EL1_VECTOR_KPTI,
+};
+
+#ifndef CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY
+#define EL1_VECTOR_BHB_LOOP -1
+#define EL1_VECTOR_BHB_FW -1
+#define EL1_VECTOR_BHB_CLEAR_INSN -1
+#endif /* !CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY */
+
+/* The vectors to use on return from EL0. e.g. to remap the kernel */
+DECLARE_PER_CPU_READ_MOSTLY(const char *, this_cpu_vector);
+
+#ifndef CONFIG_UNMAP_KERNEL_AT_EL0
+#define TRAMP_VALIAS 0ul
+#endif
+
+static inline const char *
+arm64_get_bp_hardening_vector(enum arm64_bp_harden_el1_vectors slot)
+{
+ if (arm64_kernel_unmapped_at_el0())
+ return (char *)(TRAMP_VALIAS + SZ_2K * slot);
+
+ WARN_ON_ONCE(slot == EL1_VECTOR_KPTI);
+
+ return __bp_harden_el1_vectors + SZ_2K * slot;
+}
+
+#endif /* __ASM_VECTORS_H */
diff --git a/arch/arm64/include/asm/xor.h b/arch/arm64/include/asm/xor.h
index 947f6a4f1aa0..befcd8a7abc9 100644
--- a/arch/arm64/include/asm/xor.h
+++ b/arch/arm64/include/asm/xor.h
@@ -16,7 +16,8 @@
extern struct xor_block_template const xor_block_inner_neon;
static void
-xor_neon_2(unsigned long bytes, unsigned long *p1, unsigned long *p2)
+xor_neon_2(unsigned long bytes, unsigned long * __restrict p1,
+ const unsigned long * __restrict p2)
{
kernel_neon_begin();
xor_block_inner_neon.do_2(bytes, p1, p2);
@@ -24,8 +25,9 @@ xor_neon_2(unsigned long bytes, unsigned long *p1, unsigned long *p2)
}
static void
-xor_neon_3(unsigned long bytes, unsigned long *p1, unsigned long *p2,
- unsigned long *p3)
+xor_neon_3(unsigned long bytes, unsigned long * __restrict p1,
+ const unsigned long * __restrict p2,
+ const unsigned long * __restrict p3)
{
kernel_neon_begin();
xor_block_inner_neon.do_3(bytes, p1, p2, p3);
@@ -33,8 +35,10 @@ xor_neon_3(unsigned long bytes, unsigned long *p1, unsigned long *p2,
}
static void
-xor_neon_4(unsigned long bytes, unsigned long *p1, unsigned long *p2,
- unsigned long *p3, unsigned long *p4)
+xor_neon_4(unsigned long bytes, unsigned long * __restrict p1,
+ const unsigned long * __restrict p2,
+ const unsigned long * __restrict p3,
+ const unsigned long * __restrict p4)
{
kernel_neon_begin();
xor_block_inner_neon.do_4(bytes, p1, p2, p3, p4);
@@ -42,8 +46,11 @@ xor_neon_4(unsigned long bytes, unsigned long *p1, unsigned long *p2,
}
static void
-xor_neon_5(unsigned long bytes, unsigned long *p1, unsigned long *p2,
- unsigned long *p3, unsigned long *p4, unsigned long *p5)
+xor_neon_5(unsigned long bytes, unsigned long * __restrict p1,
+ const unsigned long * __restrict p2,
+ const unsigned long * __restrict p3,
+ const unsigned long * __restrict p4,
+ const unsigned long * __restrict p5)
{
kernel_neon_begin();
xor_block_inner_neon.do_5(bytes, p1, p2, p3, p4, p5);
diff --git a/arch/arm64/include/uapi/asm/hwcap.h b/arch/arm64/include/uapi/asm/hwcap.h
index f03731847d9d..99cb5d383048 100644
--- a/arch/arm64/include/uapi/asm/hwcap.h
+++ b/arch/arm64/include/uapi/asm/hwcap.h
@@ -78,5 +78,6 @@
#define HWCAP2_ECV (1 << 19)
#define HWCAP2_AFP (1 << 20)
#define HWCAP2_RPRES (1 << 21)
+#define HWCAP2_MTE3 (1 << 22)
#endif /* _UAPI__ASM_HWCAP_H */
diff --git a/arch/arm64/include/uapi/asm/kvm.h b/arch/arm64/include/uapi/asm/kvm.h
index b3edde68bc3e..c1b6ddc02d2f 100644
--- a/arch/arm64/include/uapi/asm/kvm.h
+++ b/arch/arm64/include/uapi/asm/kvm.h
@@ -281,6 +281,11 @@ struct kvm_arm_copy_mte_tags {
#define KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_NOT_REQUIRED 3
#define KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_ENABLED (1U << 4)
+#define KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_3 KVM_REG_ARM_FW_REG(3)
+#define KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_3_NOT_AVAIL 0
+#define KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_3_AVAIL 1
+#define KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_3_NOT_REQUIRED 2
+
/* SVE registers */
#define KVM_REG_ARM64_SVE (0x15 << KVM_REG_ARM_COPROC_SHIFT)
@@ -362,6 +367,7 @@ struct kvm_arm_copy_mte_tags {
#define KVM_ARM_VCPU_PMU_V3_IRQ 0
#define KVM_ARM_VCPU_PMU_V3_INIT 1
#define KVM_ARM_VCPU_PMU_V3_FILTER 2
+#define KVM_ARM_VCPU_PMU_V3_SET_PMU 3
#define KVM_ARM_VCPU_TIMER_CTRL 1
#define KVM_ARM_VCPU_TIMER_IRQ_VTIMER 0
#define KVM_ARM_VCPU_TIMER_IRQ_PTIMER 1
@@ -413,6 +419,16 @@ struct kvm_arm_copy_mte_tags {
#define KVM_PSCI_RET_INVAL PSCI_RET_INVALID_PARAMS
#define KVM_PSCI_RET_DENIED PSCI_RET_DENIED
+/* arm64-specific kvm_run::system_event flags */
+/*
+ * Reset caused by a PSCI v1.1 SYSTEM_RESET2 call.
+ * Valid only when the system event has a type of KVM_SYSTEM_EVENT_RESET.
+ */
+#define KVM_SYSTEM_EVENT_RESET_FLAG_PSCI_RESET2 (1ULL << 0)
+
+/* run->fail_entry.hardware_entry_failure_reason codes. */
+#define KVM_EXIT_FAIL_ENTRY_CPU_UNSUPPORTED (1ULL << 0)
+
#endif
#endif /* __ARM_KVM_H__ */
diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile
index 88b3e2a21408..986837d7ec82 100644
--- a/arch/arm64/kernel/Makefile
+++ b/arch/arm64/kernel/Makefile
@@ -61,6 +61,7 @@ obj-$(CONFIG_ARM64_ACPI_PARKING_PROTOCOL) += acpi_parking_protocol.o
obj-$(CONFIG_PARAVIRT) += paravirt.o
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 \
cpu-reset.o
obj-$(CONFIG_KEXEC_FILE) += machine_kexec_file.o kexec_image.o
diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c
index 9e1c1aef9ebd..4c9b5b4b7a0b 100644
--- a/arch/arm64/kernel/cpu_errata.c
+++ b/arch/arm64/kernel/cpu_errata.c
@@ -214,6 +214,21 @@ static const struct arm64_cpu_capabilities arm64_repeat_tlbi_list[] = {
};
#endif
+#ifdef CONFIG_CAVIUM_ERRATUM_23154
+const struct midr_range cavium_erratum_23154_cpus[] = {
+ MIDR_ALL_VERSIONS(MIDR_THUNDERX),
+ MIDR_ALL_VERSIONS(MIDR_THUNDERX_81XX),
+ MIDR_ALL_VERSIONS(MIDR_THUNDERX_83XX),
+ MIDR_ALL_VERSIONS(MIDR_OCTX2_98XX),
+ MIDR_ALL_VERSIONS(MIDR_OCTX2_96XX),
+ MIDR_ALL_VERSIONS(MIDR_OCTX2_95XX),
+ MIDR_ALL_VERSIONS(MIDR_OCTX2_95XXN),
+ MIDR_ALL_VERSIONS(MIDR_OCTX2_95XXMM),
+ MIDR_ALL_VERSIONS(MIDR_OCTX2_95XXO),
+ {},
+};
+#endif
+
#ifdef CONFIG_CAVIUM_ERRATUM_27456
const struct midr_range cavium_erratum_27456_cpus[] = {
/* Cavium ThunderX, T88 pass 1.x - 2.1 */
@@ -347,6 +362,7 @@ static const struct midr_range trbe_overwrite_fill_mode_cpus[] = {
#endif
#ifdef CONFIG_ARM64_ERRATUM_2119858
MIDR_ALL_VERSIONS(MIDR_CORTEX_A710),
+ MIDR_RANGE(MIDR_CORTEX_X2, 0, 0, 2, 0),
#endif
{},
};
@@ -371,6 +387,7 @@ static struct midr_range trbe_write_out_of_range_cpus[] = {
#endif
#ifdef CONFIG_ARM64_ERRATUM_2224489
MIDR_ALL_VERSIONS(MIDR_CORTEX_A710),
+ MIDR_RANGE(MIDR_CORTEX_X2, 0, 0, 2, 0),
#endif
{},
};
@@ -423,10 +440,10 @@ const struct arm64_cpu_capabilities arm64_errata[] = {
#endif
#ifdef CONFIG_CAVIUM_ERRATUM_23154
{
- /* Cavium ThunderX, pass 1.x */
- .desc = "Cavium erratum 23154",
+ .desc = "Cavium errata 23154 and 38545",
.capability = ARM64_WORKAROUND_CAVIUM_23154,
- ERRATA_MIDR_REV_RANGE(MIDR_THUNDERX, 0, 0, 1),
+ .type = ARM64_CPUCAP_LOCAL_CPU_ERRATUM,
+ ERRATA_MIDR_RANGE_LIST(cavium_erratum_23154_cpus),
},
#endif
#ifdef CONFIG_CAVIUM_ERRATUM_27456
@@ -500,6 +517,13 @@ const struct arm64_cpu_capabilities arm64_errata[] = {
.matches = has_spectre_v4,
.cpu_enable = spectre_v4_enable_mitigation,
},
+ {
+ .desc = "Spectre-BHB",
+ .capability = ARM64_SPECTRE_BHB,
+ .type = ARM64_CPUCAP_LOCAL_CPU_ERRATUM,
+ .matches = is_spectre_bhb_affected,
+ .cpu_enable = spectre_bhb_enable_mitigation,
+ },
#ifdef CONFIG_ARM64_ERRATUM_1418040
{
.desc = "ARM erratum 1418040",
@@ -598,6 +622,40 @@ const struct arm64_cpu_capabilities arm64_errata[] = {
CAP_MIDR_RANGE_LIST(trbe_write_out_of_range_cpus),
},
#endif
+#ifdef CONFIG_ARM64_ERRATUM_2077057
+ {
+ .desc = "ARM erratum 2077057",
+ .capability = ARM64_WORKAROUND_2077057,
+ ERRATA_MIDR_REV_RANGE(MIDR_CORTEX_A510, 0, 0, 2),
+ },
+#endif
+#ifdef CONFIG_ARM64_ERRATUM_2064142
+ {
+ .desc = "ARM erratum 2064142",
+ .capability = ARM64_WORKAROUND_2064142,
+
+ /* Cortex-A510 r0p0 - r0p2 */
+ ERRATA_MIDR_REV_RANGE(MIDR_CORTEX_A510, 0, 0, 2)
+ },
+#endif
+#ifdef CONFIG_ARM64_ERRATUM_2038923
+ {
+ .desc = "ARM erratum 2038923",
+ .capability = ARM64_WORKAROUND_2038923,
+
+ /* Cortex-A510 r0p0 - r0p2 */
+ ERRATA_MIDR_REV_RANGE(MIDR_CORTEX_A510, 0, 0, 2)
+ },
+#endif
+#ifdef CONFIG_ARM64_ERRATUM_1902691
+ {
+ .desc = "ARM erratum 1902691",
+ .capability = ARM64_WORKAROUND_1902691,
+
+ /* Cortex-A510 r0p0 - r0p1 */
+ ERRATA_MIDR_REV_RANGE(MIDR_CORTEX_A510, 0, 0, 1)
+ },
+#endif
{
}
};
diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
index a46ab3b1c4d5..d72c4b4d389c 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -73,6 +73,8 @@
#include <linux/mm.h>
#include <linux/cpu.h>
#include <linux/kasan.h>
+#include <linux/percpu.h>
+
#include <asm/cpu.h>
#include <asm/cpufeature.h>
#include <asm/cpu_ops.h>
@@ -85,6 +87,7 @@
#include <asm/smp.h>
#include <asm/sysreg.h>
#include <asm/traps.h>
+#include <asm/vectors.h>
#include <asm/virt.h>
/* Kernel representation of AT_HWCAP and AT_HWCAP2 */
@@ -110,6 +113,8 @@ DECLARE_BITMAP(boot_capabilities, ARM64_NPATCHABLE);
bool arm64_use_ng_mappings = false;
EXPORT_SYMBOL(arm64_use_ng_mappings);
+DEFINE_PER_CPU_READ_MOSTLY(const char *, this_cpu_vector) = vectors;
+
/*
* Permit PER_LINUX32 and execve() of 32-bit binaries even if not all CPUs
* support it?
@@ -226,6 +231,11 @@ static const struct arm64_ftr_bits ftr_id_aa64isar1[] = {
};
static const struct arm64_ftr_bits ftr_id_aa64isar2[] = {
+ ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_HIGHER_SAFE, ID_AA64ISAR2_CLEARBHB_SHIFT, 4, 0),
+ ARM64_FTR_BITS(FTR_VISIBLE_IF_IS_ENABLED(CONFIG_ARM64_PTR_AUTH),
+ FTR_STRICT, FTR_EXACT, ID_AA64ISAR2_APA3_SHIFT, 4, 0),
+ ARM64_FTR_BITS(FTR_VISIBLE_IF_IS_ENABLED(CONFIG_ARM64_PTR_AUTH),
+ FTR_STRICT, FTR_LOWER_SAFE, ID_AA64ISAR2_GPA3_SHIFT, 4, 0),
ARM64_FTR_BITS(FTR_VISIBLE, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64ISAR2_RPRES_SHIFT, 4, 0),
ARM64_FTR_END,
};
@@ -596,6 +606,7 @@ static const struct arm64_ftr_bits ftr_raz[] = {
struct arm64_ftr_override __ro_after_init id_aa64mmfr1_override;
struct arm64_ftr_override __ro_after_init id_aa64pfr1_override;
struct arm64_ftr_override __ro_after_init id_aa64isar1_override;
+struct arm64_ftr_override __ro_after_init id_aa64isar2_override;
static const struct __ftr_reg_entry {
u32 sys_id;
@@ -644,6 +655,8 @@ static const struct __ftr_reg_entry {
ARM64_FTR_REG_OVERRIDE(SYS_ID_AA64ISAR1_EL1, ftr_id_aa64isar1,
&id_aa64isar1_override),
ARM64_FTR_REG(SYS_ID_AA64ISAR2_EL1, ftr_id_aa64isar2),
+ ARM64_FTR_REG_OVERRIDE(SYS_ID_AA64ISAR2_EL1, ftr_id_aa64isar2,
+ &id_aa64isar2_override),
/* Op1 = 0, CRn = 0, CRm = 7 */
ARM64_FTR_REG(SYS_ID_AA64MMFR0_EL1, ftr_id_aa64mmfr0),
@@ -1307,7 +1320,9 @@ u64 __read_sysreg_by_encoding(u32 sys_id)
static bool
feature_matches(u64 reg, const struct arm64_cpu_capabilities *entry)
{
- int val = cpuid_feature_extract_field(reg, entry->field_pos, entry->sign);
+ int val = cpuid_feature_extract_field_width(reg, entry->field_pos,
+ entry->field_width,
+ entry->sign);
return val >= entry->min_field_value;
}
@@ -1590,6 +1605,12 @@ kpti_install_ng_mappings(const struct arm64_cpu_capabilities *__unused)
int cpu = smp_processor_id();
+ if (__this_cpu_read(this_cpu_vector) == vectors) {
+ const char *v = arm64_get_bp_hardening_vector(EL1_VECTOR_KPTI);
+
+ __this_cpu_write(this_cpu_vector, v);
+ }
+
/*
* We don't need to rewrite the page-tables if either we've done
* it already or we have KASLR enabled and therefore have not
@@ -1646,6 +1667,9 @@ static bool cpu_has_broken_dbm(void)
/* Kryo4xx Silver (rdpe => r1p0) */
MIDR_REV(MIDR_QCOM_KRYO_4XX_SILVER, 0xd, 0xe),
#endif
+#ifdef CONFIG_ARM64_ERRATUM_2051678
+ MIDR_REV_RANGE(MIDR_CORTEX_A510, 0, 0, 2),
+#endif
{},
};
@@ -1772,14 +1796,6 @@ static void cpu_copy_el2regs(const struct arm64_cpu_capabilities *__unused)
write_sysreg(read_sysreg(tpidr_el1), tpidr_el2);
}
-static void cpu_has_fwb(const struct arm64_cpu_capabilities *__unused)
-{
- u64 val = read_sysreg_s(SYS_CLIDR_EL1);
-
- /* Check that CLIDR_EL1.LOU{U,IS} are both 0 */
- WARN_ON(CLIDR_LOUU(val) || CLIDR_LOUIS(val));
-}
-
#ifdef CONFIG_ARM64_PAN
static void cpu_enable_pan(const struct arm64_cpu_capabilities *__unused)
{
@@ -1826,21 +1842,27 @@ static bool has_address_auth_cpucap(const struct arm64_cpu_capabilities *entry,
/* Now check for the secondary CPUs with SCOPE_LOCAL_CPU scope */
sec_val = cpuid_feature_extract_field(__read_sysreg_by_encoding(entry->sys_reg),
entry->field_pos, entry->sign);
- return sec_val == boot_val;
+ return (sec_val >= entry->min_field_value) && (sec_val == boot_val);
}
static bool has_address_auth_metacap(const struct arm64_cpu_capabilities *entry,
int scope)
{
- return has_address_auth_cpucap(cpu_hwcaps_ptrs[ARM64_HAS_ADDRESS_AUTH_ARCH], scope) ||
- has_address_auth_cpucap(cpu_hwcaps_ptrs[ARM64_HAS_ADDRESS_AUTH_IMP_DEF], scope);
+ bool api = has_address_auth_cpucap(cpu_hwcaps_ptrs[ARM64_HAS_ADDRESS_AUTH_IMP_DEF], scope);
+ bool apa = has_address_auth_cpucap(cpu_hwcaps_ptrs[ARM64_HAS_ADDRESS_AUTH_ARCH_QARMA5], scope);
+ bool apa3 = has_address_auth_cpucap(cpu_hwcaps_ptrs[ARM64_HAS_ADDRESS_AUTH_ARCH_QARMA3], scope);
+
+ return apa || apa3 || api;
}
static bool has_generic_auth(const struct arm64_cpu_capabilities *entry,
int __unused)
{
- return __system_matches_cap(ARM64_HAS_GENERIC_AUTH_ARCH) ||
- __system_matches_cap(ARM64_HAS_GENERIC_AUTH_IMP_DEF);
+ bool gpi = __system_matches_cap(ARM64_HAS_GENERIC_AUTH_IMP_DEF);
+ bool gpa = __system_matches_cap(ARM64_HAS_GENERIC_AUTH_ARCH_QARMA5);
+ bool gpa3 = __system_matches_cap(ARM64_HAS_GENERIC_AUTH_ARCH_QARMA3);
+
+ return gpa || gpa3 || gpi;
}
#endif /* CONFIG_ARM64_PTR_AUTH */
@@ -1942,6 +1964,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
.matches = has_useable_gicv3_cpuif,
.sys_reg = SYS_ID_AA64PFR0_EL1,
.field_pos = ID_AA64PFR0_GIC_SHIFT,
+ .field_width = 4,
.sign = FTR_UNSIGNED,
.min_field_value = 1,
},
@@ -1952,6 +1975,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
.matches = has_cpuid_feature,
.sys_reg = SYS_ID_AA64MMFR0_EL1,
.field_pos = ID_AA64MMFR0_ECV_SHIFT,
+ .field_width = 4,
.sign = FTR_UNSIGNED,
.min_field_value = 1,
},
@@ -1963,6 +1987,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
.matches = has_cpuid_feature,
.sys_reg = SYS_ID_AA64MMFR1_EL1,
.field_pos = ID_AA64MMFR1_PAN_SHIFT,
+ .field_width = 4,
.sign = FTR_UNSIGNED,
.min_field_value = 1,
.cpu_enable = cpu_enable_pan,
@@ -1976,6 +2001,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
.matches = has_cpuid_feature,
.sys_reg = SYS_ID_AA64MMFR1_EL1,
.field_pos = ID_AA64MMFR1_PAN_SHIFT,
+ .field_width = 4,
.sign = FTR_UNSIGNED,
.min_field_value = 3,
},
@@ -1988,6 +2014,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
.matches = has_cpuid_feature,
.sys_reg = SYS_ID_AA64ISAR0_EL1,
.field_pos = ID_AA64ISAR0_ATOMICS_SHIFT,
+ .field_width = 4,
.sign = FTR_UNSIGNED,
.min_field_value = 2,
},
@@ -2012,6 +2039,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
.sys_reg = SYS_ID_AA64PFR0_EL1,
.sign = FTR_UNSIGNED,
.field_pos = ID_AA64PFR0_EL0_SHIFT,
+ .field_width = 4,
.min_field_value = ID_AA64PFR0_ELx_32BIT_64BIT,
},
#ifdef CONFIG_KVM
@@ -2023,6 +2051,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
.sys_reg = SYS_ID_AA64PFR0_EL1,
.sign = FTR_UNSIGNED,
.field_pos = ID_AA64PFR0_EL1_SHIFT,
+ .field_width = 4,
.min_field_value = ID_AA64PFR0_ELx_32BIT_64BIT,
},
{
@@ -2043,6 +2072,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
*/
.sys_reg = SYS_ID_AA64PFR0_EL1,
.field_pos = ID_AA64PFR0_CSV3_SHIFT,
+ .field_width = 4,
.min_field_value = 1,
.matches = unmap_kernel_at_el0,
.cpu_enable = kpti_install_ng_mappings,
@@ -2062,6 +2092,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
.matches = has_cpuid_feature,
.sys_reg = SYS_ID_AA64ISAR1_EL1,
.field_pos = ID_AA64ISAR1_DPB_SHIFT,
+ .field_width = 4,
.min_field_value = 1,
},
{
@@ -2072,6 +2103,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
.sys_reg = SYS_ID_AA64ISAR1_EL1,
.sign = FTR_UNSIGNED,
.field_pos = ID_AA64ISAR1_DPB_SHIFT,
+ .field_width = 4,
.min_field_value = 2,
},
#endif
@@ -2083,6 +2115,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
.sys_reg = SYS_ID_AA64PFR0_EL1,
.sign = FTR_UNSIGNED,
.field_pos = ID_AA64PFR0_SVE_SHIFT,
+ .field_width = 4,
.min_field_value = ID_AA64PFR0_SVE,
.matches = has_cpuid_feature,
.cpu_enable = sve_kernel_enable,
@@ -2097,6 +2130,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
.sys_reg = SYS_ID_AA64PFR0_EL1,
.sign = FTR_UNSIGNED,
.field_pos = ID_AA64PFR0_RAS_SHIFT,
+ .field_width = 4,
.min_field_value = ID_AA64PFR0_RAS_V1,
.cpu_enable = cpu_clear_disr,
},
@@ -2115,6 +2149,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
.sys_reg = SYS_ID_AA64PFR0_EL1,
.sign = FTR_UNSIGNED,
.field_pos = ID_AA64PFR0_AMU_SHIFT,
+ .field_width = 4,
.min_field_value = ID_AA64PFR0_AMU,
.cpu_enable = cpu_amu_enable,
},
@@ -2139,9 +2174,9 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
.sys_reg = SYS_ID_AA64MMFR2_EL1,
.sign = FTR_UNSIGNED,
.field_pos = ID_AA64MMFR2_FWB_SHIFT,
+ .field_width = 4,
.min_field_value = 1,
.matches = has_cpuid_feature,
- .cpu_enable = cpu_has_fwb,
},
{
.desc = "ARMv8.4 Translation Table Level",
@@ -2150,6 +2185,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
.sys_reg = SYS_ID_AA64MMFR2_EL1,
.sign = FTR_UNSIGNED,
.field_pos = ID_AA64MMFR2_TTL_SHIFT,
+ .field_width = 4,
.min_field_value = 1,
.matches = has_cpuid_feature,
},
@@ -2160,6 +2196,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
.matches = has_cpuid_feature,
.sys_reg = SYS_ID_AA64ISAR0_EL1,
.field_pos = ID_AA64ISAR0_TLB_SHIFT,
+ .field_width = 4,
.sign = FTR_UNSIGNED,
.min_field_value = ID_AA64ISAR0_TLB_RANGE,
},
@@ -2178,6 +2215,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
.sys_reg = SYS_ID_AA64MMFR1_EL1,
.sign = FTR_UNSIGNED,
.field_pos = ID_AA64MMFR1_HADBS_SHIFT,
+ .field_width = 4,
.min_field_value = 2,
.matches = has_hw_dbm,
.cpu_enable = cpu_enable_hw_dbm,
@@ -2190,6 +2228,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
.matches = has_cpuid_feature,
.sys_reg = SYS_ID_AA64ISAR0_EL1,
.field_pos = ID_AA64ISAR0_CRC32_SHIFT,
+ .field_width = 4,
.min_field_value = 1,
},
{
@@ -2199,6 +2238,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
.matches = has_cpuid_feature,
.sys_reg = SYS_ID_AA64PFR1_EL1,
.field_pos = ID_AA64PFR1_SSBS_SHIFT,
+ .field_width = 4,
.sign = FTR_UNSIGNED,
.min_field_value = ID_AA64PFR1_SSBS_PSTATE_ONLY,
},
@@ -2211,6 +2251,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
.sys_reg = SYS_ID_AA64MMFR2_EL1,
.sign = FTR_UNSIGNED,
.field_pos = ID_AA64MMFR2_CNP_SHIFT,
+ .field_width = 4,
.min_field_value = 1,
.cpu_enable = cpu_enable_cnp,
},
@@ -2222,27 +2263,41 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
.matches = has_cpuid_feature,
.sys_reg = SYS_ID_AA64ISAR1_EL1,
.field_pos = ID_AA64ISAR1_SB_SHIFT,
+ .field_width = 4,
.sign = FTR_UNSIGNED,
.min_field_value = 1,
},
#ifdef CONFIG_ARM64_PTR_AUTH
{
- .desc = "Address authentication (architected algorithm)",
- .capability = ARM64_HAS_ADDRESS_AUTH_ARCH,
+ .desc = "Address authentication (architected QARMA5 algorithm)",
+ .capability = ARM64_HAS_ADDRESS_AUTH_ARCH_QARMA5,
.type = ARM64_CPUCAP_BOOT_CPU_FEATURE,
.sys_reg = SYS_ID_AA64ISAR1_EL1,
.sign = FTR_UNSIGNED,
.field_pos = ID_AA64ISAR1_APA_SHIFT,
+ .field_width = 4,
.min_field_value = ID_AA64ISAR1_APA_ARCHITECTED,
.matches = has_address_auth_cpucap,
},
{
+ .desc = "Address authentication (architected QARMA3 algorithm)",
+ .capability = ARM64_HAS_ADDRESS_AUTH_ARCH_QARMA3,
+ .type = ARM64_CPUCAP_BOOT_CPU_FEATURE,
+ .sys_reg = SYS_ID_AA64ISAR2_EL1,
+ .sign = FTR_UNSIGNED,
+ .field_pos = ID_AA64ISAR2_APA3_SHIFT,
+ .field_width = 4,
+ .min_field_value = ID_AA64ISAR2_APA3_ARCHITECTED,
+ .matches = has_address_auth_cpucap,
+ },
+ {
.desc = "Address authentication (IMP DEF algorithm)",
.capability = ARM64_HAS_ADDRESS_AUTH_IMP_DEF,
.type = ARM64_CPUCAP_BOOT_CPU_FEATURE,
.sys_reg = SYS_ID_AA64ISAR1_EL1,
.sign = FTR_UNSIGNED,
.field_pos = ID_AA64ISAR1_API_SHIFT,
+ .field_width = 4,
.min_field_value = ID_AA64ISAR1_API_IMP_DEF,
.matches = has_address_auth_cpucap,
},
@@ -2252,22 +2307,35 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
.matches = has_address_auth_metacap,
},
{
- .desc = "Generic authentication (architected algorithm)",
- .capability = ARM64_HAS_GENERIC_AUTH_ARCH,
+ .desc = "Generic authentication (architected QARMA5 algorithm)",
+ .capability = ARM64_HAS_GENERIC_AUTH_ARCH_QARMA5,
.type = ARM64_CPUCAP_SYSTEM_FEATURE,
.sys_reg = SYS_ID_AA64ISAR1_EL1,
.sign = FTR_UNSIGNED,
.field_pos = ID_AA64ISAR1_GPA_SHIFT,
+ .field_width = 4,
.min_field_value = ID_AA64ISAR1_GPA_ARCHITECTED,
.matches = has_cpuid_feature,
},
{
+ .desc = "Generic authentication (architected QARMA3 algorithm)",
+ .capability = ARM64_HAS_GENERIC_AUTH_ARCH_QARMA3,
+ .type = ARM64_CPUCAP_SYSTEM_FEATURE,
+ .sys_reg = SYS_ID_AA64ISAR2_EL1,
+ .sign = FTR_UNSIGNED,
+ .field_pos = ID_AA64ISAR2_GPA3_SHIFT,
+ .field_width = 4,
+ .min_field_value = ID_AA64ISAR2_GPA3_ARCHITECTED,
+ .matches = has_cpuid_feature,
+ },
+ {
.desc = "Generic authentication (IMP DEF algorithm)",
.capability = ARM64_HAS_GENERIC_AUTH_IMP_DEF,
.type = ARM64_CPUCAP_SYSTEM_FEATURE,
.sys_reg = SYS_ID_AA64ISAR1_EL1,
.sign = FTR_UNSIGNED,
.field_pos = ID_AA64ISAR1_GPI_SHIFT,
+ .field_width = 4,
.min_field_value = ID_AA64ISAR1_GPI_IMP_DEF,
.matches = has_cpuid_feature,
},
@@ -2288,6 +2356,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
.matches = can_use_gic_priorities,
.sys_reg = SYS_ID_AA64PFR0_EL1,
.field_pos = ID_AA64PFR0_GIC_SHIFT,
+ .field_width = 4,
.sign = FTR_UNSIGNED,
.min_field_value = 1,
},
@@ -2299,6 +2368,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
.type = ARM64_CPUCAP_SYSTEM_FEATURE,
.sys_reg = SYS_ID_AA64MMFR2_EL1,
.sign = FTR_UNSIGNED,
+ .field_width = 4,
.field_pos = ID_AA64MMFR2_E0PD_SHIFT,
.matches = has_cpuid_feature,
.min_field_value = 1,
@@ -2313,6 +2383,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
.matches = has_cpuid_feature,
.sys_reg = SYS_ID_AA64ISAR0_EL1,
.field_pos = ID_AA64ISAR0_RNDR_SHIFT,
+ .field_width = 4,
.sign = FTR_UNSIGNED,
.min_field_value = 1,
},
@@ -2330,6 +2401,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
.cpu_enable = bti_enable,
.sys_reg = SYS_ID_AA64PFR1_EL1,
.field_pos = ID_AA64PFR1_BT_SHIFT,
+ .field_width = 4,
.min_field_value = ID_AA64PFR1_BT_BTI,
.sign = FTR_UNSIGNED,
},
@@ -2342,6 +2414,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
.matches = has_cpuid_feature,
.sys_reg = SYS_ID_AA64PFR1_EL1,
.field_pos = ID_AA64PFR1_MTE_SHIFT,
+ .field_width = 4,
.min_field_value = ID_AA64PFR1_MTE,
.sign = FTR_UNSIGNED,
.cpu_enable = cpu_enable_mte,
@@ -2353,6 +2426,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
.matches = has_cpuid_feature,
.sys_reg = SYS_ID_AA64PFR1_EL1,
.field_pos = ID_AA64PFR1_MTE_SHIFT,
+ .field_width = 4,
.min_field_value = ID_AA64PFR1_MTE_ASYMM,
.sign = FTR_UNSIGNED,
},
@@ -2364,16 +2438,18 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
.sys_reg = SYS_ID_AA64ISAR1_EL1,
.sign = FTR_UNSIGNED,
.field_pos = ID_AA64ISAR1_LRCPC_SHIFT,
+ .field_width = 4,
.matches = has_cpuid_feature,
.min_field_value = 1,
},
{},
};
-#define HWCAP_CPUID_MATCH(reg, field, s, min_value) \
+#define HWCAP_CPUID_MATCH(reg, field, width, s, min_value) \
.matches = has_cpuid_feature, \
.sys_reg = reg, \
.field_pos = field, \
+ .field_width = width, \
.sign = s, \
.min_field_value = min_value,
@@ -2383,10 +2459,10 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
.hwcap_type = cap_type, \
.hwcap = cap, \
-#define HWCAP_CAP(reg, field, s, min_value, cap_type, cap) \
+#define HWCAP_CAP(reg, field, width, s, min_value, cap_type, cap) \
{ \
__HWCAP_CAP(#cap, cap_type, cap) \
- HWCAP_CPUID_MATCH(reg, field, s, min_value) \
+ HWCAP_CPUID_MATCH(reg, field, width, s, min_value) \
}
#define HWCAP_MULTI_CAP(list, cap_type, cap) \
@@ -2406,11 +2482,16 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
static const struct arm64_cpu_capabilities ptr_auth_hwcap_addr_matches[] = {
{
HWCAP_CPUID_MATCH(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_APA_SHIFT,
- FTR_UNSIGNED, ID_AA64ISAR1_APA_ARCHITECTED)
+ 4, FTR_UNSIGNED,
+ ID_AA64ISAR1_APA_ARCHITECTED)
+ },
+ {
+ HWCAP_CPUID_MATCH(SYS_ID_AA64ISAR2_EL1, ID_AA64ISAR2_APA3_SHIFT,
+ 4, FTR_UNSIGNED, ID_AA64ISAR2_APA3_ARCHITECTED)
},
{
HWCAP_CPUID_MATCH(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_API_SHIFT,
- FTR_UNSIGNED, ID_AA64ISAR1_API_IMP_DEF)
+ 4, FTR_UNSIGNED, ID_AA64ISAR1_API_IMP_DEF)
},
{},
};
@@ -2418,77 +2499,82 @@ static const struct arm64_cpu_capabilities ptr_auth_hwcap_addr_matches[] = {
static const struct arm64_cpu_capabilities ptr_auth_hwcap_gen_matches[] = {
{
HWCAP_CPUID_MATCH(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_GPA_SHIFT,
- FTR_UNSIGNED, ID_AA64ISAR1_GPA_ARCHITECTED)
+ 4, FTR_UNSIGNED, ID_AA64ISAR1_GPA_ARCHITECTED)
+ },
+ {
+ HWCAP_CPUID_MATCH(SYS_ID_AA64ISAR2_EL1, ID_AA64ISAR2_GPA3_SHIFT,
+ 4, FTR_UNSIGNED, ID_AA64ISAR2_GPA3_ARCHITECTED)
},
{
HWCAP_CPUID_MATCH(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_GPI_SHIFT,
- FTR_UNSIGNED, ID_AA64ISAR1_GPI_IMP_DEF)
+ 4, FTR_UNSIGNED, ID_AA64ISAR1_GPI_IMP_DEF)
},
{},
};
#endif
static const struct arm64_cpu_capabilities arm64_elf_hwcaps[] = {
- HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_AES_SHIFT, FTR_UNSIGNED, 2, CAP_HWCAP, KERNEL_HWCAP_PMULL),
- HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_AES_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_AES),
- HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_SHA1_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_SHA1),
- HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_SHA2_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_SHA2),
- HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_SHA2_SHIFT, FTR_UNSIGNED, 2, CAP_HWCAP, KERNEL_HWCAP_SHA512),
- HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_CRC32_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_CRC32),
- HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_ATOMICS_SHIFT, FTR_UNSIGNED, 2, CAP_HWCAP, KERNEL_HWCAP_ATOMICS),
- HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_RDM_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_ASIMDRDM),
- HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_SHA3_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_SHA3),
- HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_SM3_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_SM3),
- HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_SM4_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_SM4),
- HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_DP_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_ASIMDDP),
- HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_FHM_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_ASIMDFHM),
- HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_TS_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_FLAGM),
- HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_TS_SHIFT, FTR_UNSIGNED, 2, CAP_HWCAP, KERNEL_HWCAP_FLAGM2),
- HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_RNDR_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_RNG),
- HWCAP_CAP(SYS_ID_AA64PFR0_EL1, ID_AA64PFR0_FP_SHIFT, FTR_SIGNED, 0, CAP_HWCAP, KERNEL_HWCAP_FP),
- HWCAP_CAP(SYS_ID_AA64PFR0_EL1, ID_AA64PFR0_FP_SHIFT, FTR_SIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_FPHP),
- HWCAP_CAP(SYS_ID_AA64PFR0_EL1, ID_AA64PFR0_ASIMD_SHIFT, FTR_SIGNED, 0, CAP_HWCAP, KERNEL_HWCAP_ASIMD),
- HWCAP_CAP(SYS_ID_AA64PFR0_EL1, ID_AA64PFR0_ASIMD_SHIFT, FTR_SIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_ASIMDHP),
- HWCAP_CAP(SYS_ID_AA64PFR0_EL1, ID_AA64PFR0_DIT_SHIFT, FTR_SIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_DIT),
- HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_DPB_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_DCPOP),
- HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_DPB_SHIFT, FTR_UNSIGNED, 2, CAP_HWCAP, KERNEL_HWCAP_DCPODP),
- HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_JSCVT_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_JSCVT),
- HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_FCMA_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_FCMA),
- HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_LRCPC_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_LRCPC),
- HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_LRCPC_SHIFT, FTR_UNSIGNED, 2, CAP_HWCAP, KERNEL_HWCAP_ILRCPC),
- HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_FRINTTS_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_FRINT),
- HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_SB_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_SB),
- HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_BF16_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_BF16),
- HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_DGH_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_DGH),
- HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_I8MM_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_I8MM),
- HWCAP_CAP(SYS_ID_AA64MMFR2_EL1, ID_AA64MMFR2_AT_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_USCAT),
+ HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_AES_SHIFT, 4, FTR_UNSIGNED, 2, CAP_HWCAP, KERNEL_HWCAP_PMULL),
+ HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_AES_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_AES),
+ HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_SHA1_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_SHA1),
+ HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_SHA2_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_SHA2),
+ HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_SHA2_SHIFT, 4, FTR_UNSIGNED, 2, CAP_HWCAP, KERNEL_HWCAP_SHA512),
+ HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_CRC32_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_CRC32),
+ HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_ATOMICS_SHIFT, 4, FTR_UNSIGNED, 2, CAP_HWCAP, KERNEL_HWCAP_ATOMICS),
+ HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_RDM_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_ASIMDRDM),
+ HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_SHA3_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_SHA3),
+ HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_SM3_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_SM3),
+ HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_SM4_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_SM4),
+ HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_DP_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_ASIMDDP),
+ HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_FHM_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_ASIMDFHM),
+ HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_TS_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_FLAGM),
+ HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_TS_SHIFT, 4, FTR_UNSIGNED, 2, CAP_HWCAP, KERNEL_HWCAP_FLAGM2),
+ HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_RNDR_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_RNG),
+ HWCAP_CAP(SYS_ID_AA64PFR0_EL1, ID_AA64PFR0_FP_SHIFT, 4, FTR_SIGNED, 0, CAP_HWCAP, KERNEL_HWCAP_FP),
+ HWCAP_CAP(SYS_ID_AA64PFR0_EL1, ID_AA64PFR0_FP_SHIFT, 4, FTR_SIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_FPHP),
+ HWCAP_CAP(SYS_ID_AA64PFR0_EL1, ID_AA64PFR0_ASIMD_SHIFT, 4, FTR_SIGNED, 0, CAP_HWCAP, KERNEL_HWCAP_ASIMD),
+ HWCAP_CAP(SYS_ID_AA64PFR0_EL1, ID_AA64PFR0_ASIMD_SHIFT, 4, FTR_SIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_ASIMDHP),
+ HWCAP_CAP(SYS_ID_AA64PFR0_EL1, ID_AA64PFR0_DIT_SHIFT, 4, FTR_SIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_DIT),
+ HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_DPB_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_DCPOP),
+ HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_DPB_SHIFT, 4, FTR_UNSIGNED, 2, CAP_HWCAP, KERNEL_HWCAP_DCPODP),
+ HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_JSCVT_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_JSCVT),
+ HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_FCMA_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_FCMA),
+ HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_LRCPC_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_LRCPC),
+ HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_LRCPC_SHIFT, 4, FTR_UNSIGNED, 2, CAP_HWCAP, KERNEL_HWCAP_ILRCPC),
+ HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_FRINTTS_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_FRINT),
+ HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_SB_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_SB),
+ HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_BF16_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_BF16),
+ HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_DGH_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_DGH),
+ HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_I8MM_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_I8MM),
+ HWCAP_CAP(SYS_ID_AA64MMFR2_EL1, ID_AA64MMFR2_AT_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_USCAT),
#ifdef CONFIG_ARM64_SVE
- HWCAP_CAP(SYS_ID_AA64PFR0_EL1, ID_AA64PFR0_SVE_SHIFT, FTR_UNSIGNED, ID_AA64PFR0_SVE, CAP_HWCAP, KERNEL_HWCAP_SVE),
- HWCAP_CAP(SYS_ID_AA64ZFR0_EL1, ID_AA64ZFR0_SVEVER_SHIFT, FTR_UNSIGNED, ID_AA64ZFR0_SVEVER_SVE2, CAP_HWCAP, KERNEL_HWCAP_SVE2),
- HWCAP_CAP(SYS_ID_AA64ZFR0_EL1, ID_AA64ZFR0_AES_SHIFT, FTR_UNSIGNED, ID_AA64ZFR0_AES, CAP_HWCAP, KERNEL_HWCAP_SVEAES),
- HWCAP_CAP(SYS_ID_AA64ZFR0_EL1, ID_AA64ZFR0_AES_SHIFT, FTR_UNSIGNED, ID_AA64ZFR0_AES_PMULL, CAP_HWCAP, KERNEL_HWCAP_SVEPMULL),
- HWCAP_CAP(SYS_ID_AA64ZFR0_EL1, ID_AA64ZFR0_BITPERM_SHIFT, FTR_UNSIGNED, ID_AA64ZFR0_BITPERM, CAP_HWCAP, KERNEL_HWCAP_SVEBITPERM),
- HWCAP_CAP(SYS_ID_AA64ZFR0_EL1, ID_AA64ZFR0_BF16_SHIFT, FTR_UNSIGNED, ID_AA64ZFR0_BF16, CAP_HWCAP, KERNEL_HWCAP_SVEBF16),
- HWCAP_CAP(SYS_ID_AA64ZFR0_EL1, ID_AA64ZFR0_SHA3_SHIFT, FTR_UNSIGNED, ID_AA64ZFR0_SHA3, CAP_HWCAP, KERNEL_HWCAP_SVESHA3),
- HWCAP_CAP(SYS_ID_AA64ZFR0_EL1, ID_AA64ZFR0_SM4_SHIFT, FTR_UNSIGNED, ID_AA64ZFR0_SM4, CAP_HWCAP, KERNEL_HWCAP_SVESM4),
- HWCAP_CAP(SYS_ID_AA64ZFR0_EL1, ID_AA64ZFR0_I8MM_SHIFT, FTR_UNSIGNED, ID_AA64ZFR0_I8MM, CAP_HWCAP, KERNEL_HWCAP_SVEI8MM),
- HWCAP_CAP(SYS_ID_AA64ZFR0_EL1, ID_AA64ZFR0_F32MM_SHIFT, FTR_UNSIGNED, ID_AA64ZFR0_F32MM, CAP_HWCAP, KERNEL_HWCAP_SVEF32MM),
- HWCAP_CAP(SYS_ID_AA64ZFR0_EL1, ID_AA64ZFR0_F64MM_SHIFT, FTR_UNSIGNED, ID_AA64ZFR0_F64MM, CAP_HWCAP, KERNEL_HWCAP_SVEF64MM),
+ HWCAP_CAP(SYS_ID_AA64PFR0_EL1, ID_AA64PFR0_SVE_SHIFT, 4, FTR_UNSIGNED, ID_AA64PFR0_SVE, CAP_HWCAP, KERNEL_HWCAP_SVE),
+ HWCAP_CAP(SYS_ID_AA64ZFR0_EL1, ID_AA64ZFR0_SVEVER_SHIFT, 4, FTR_UNSIGNED, ID_AA64ZFR0_SVEVER_SVE2, CAP_HWCAP, KERNEL_HWCAP_SVE2),
+ HWCAP_CAP(SYS_ID_AA64ZFR0_EL1, ID_AA64ZFR0_AES_SHIFT, 4, FTR_UNSIGNED, ID_AA64ZFR0_AES, CAP_HWCAP, KERNEL_HWCAP_SVEAES),
+ HWCAP_CAP(SYS_ID_AA64ZFR0_EL1, ID_AA64ZFR0_AES_SHIFT, 4, FTR_UNSIGNED, ID_AA64ZFR0_AES_PMULL, CAP_HWCAP, KERNEL_HWCAP_SVEPMULL),
+ HWCAP_CAP(SYS_ID_AA64ZFR0_EL1, ID_AA64ZFR0_BITPERM_SHIFT, 4, FTR_UNSIGNED, ID_AA64ZFR0_BITPERM, CAP_HWCAP, KERNEL_HWCAP_SVEBITPERM),
+ HWCAP_CAP(SYS_ID_AA64ZFR0_EL1, ID_AA64ZFR0_BF16_SHIFT, 4, FTR_UNSIGNED, ID_AA64ZFR0_BF16, CAP_HWCAP, KERNEL_HWCAP_SVEBF16),
+ HWCAP_CAP(SYS_ID_AA64ZFR0_EL1, ID_AA64ZFR0_SHA3_SHIFT, 4, FTR_UNSIGNED, ID_AA64ZFR0_SHA3, CAP_HWCAP, KERNEL_HWCAP_SVESHA3),
+ HWCAP_CAP(SYS_ID_AA64ZFR0_EL1, ID_AA64ZFR0_SM4_SHIFT, 4, FTR_UNSIGNED, ID_AA64ZFR0_SM4, CAP_HWCAP, KERNEL_HWCAP_SVESM4),
+ HWCAP_CAP(SYS_ID_AA64ZFR0_EL1, ID_AA64ZFR0_I8MM_SHIFT, 4, FTR_UNSIGNED, ID_AA64ZFR0_I8MM, CAP_HWCAP, KERNEL_HWCAP_SVEI8MM),
+ HWCAP_CAP(SYS_ID_AA64ZFR0_EL1, ID_AA64ZFR0_F32MM_SHIFT, 4, FTR_UNSIGNED, ID_AA64ZFR0_F32MM, CAP_HWCAP, KERNEL_HWCAP_SVEF32MM),
+ HWCAP_CAP(SYS_ID_AA64ZFR0_EL1, ID_AA64ZFR0_F64MM_SHIFT, 4, FTR_UNSIGNED, ID_AA64ZFR0_F64MM, CAP_HWCAP, KERNEL_HWCAP_SVEF64MM),
#endif
- HWCAP_CAP(SYS_ID_AA64PFR1_EL1, ID_AA64PFR1_SSBS_SHIFT, FTR_UNSIGNED, ID_AA64PFR1_SSBS_PSTATE_INSNS, CAP_HWCAP, KERNEL_HWCAP_SSBS),
+ HWCAP_CAP(SYS_ID_AA64PFR1_EL1, ID_AA64PFR1_SSBS_SHIFT, 4, FTR_UNSIGNED, ID_AA64PFR1_SSBS_PSTATE_INSNS, CAP_HWCAP, KERNEL_HWCAP_SSBS),
#ifdef CONFIG_ARM64_BTI
- HWCAP_CAP(SYS_ID_AA64PFR1_EL1, ID_AA64PFR1_BT_SHIFT, FTR_UNSIGNED, ID_AA64PFR1_BT_BTI, CAP_HWCAP, KERNEL_HWCAP_BTI),
+ HWCAP_CAP(SYS_ID_AA64PFR1_EL1, ID_AA64PFR1_BT_SHIFT, 4, FTR_UNSIGNED, ID_AA64PFR1_BT_BTI, CAP_HWCAP, KERNEL_HWCAP_BTI),
#endif
#ifdef CONFIG_ARM64_PTR_AUTH
HWCAP_MULTI_CAP(ptr_auth_hwcap_addr_matches, CAP_HWCAP, KERNEL_HWCAP_PACA),
HWCAP_MULTI_CAP(ptr_auth_hwcap_gen_matches, CAP_HWCAP, KERNEL_HWCAP_PACG),
#endif
#ifdef CONFIG_ARM64_MTE
- HWCAP_CAP(SYS_ID_AA64PFR1_EL1, ID_AA64PFR1_MTE_SHIFT, FTR_UNSIGNED, ID_AA64PFR1_MTE, CAP_HWCAP, KERNEL_HWCAP_MTE),
+ HWCAP_CAP(SYS_ID_AA64PFR1_EL1, ID_AA64PFR1_MTE_SHIFT, 4, FTR_UNSIGNED, ID_AA64PFR1_MTE, CAP_HWCAP, KERNEL_HWCAP_MTE),
+ HWCAP_CAP(SYS_ID_AA64PFR1_EL1, ID_AA64PFR1_MTE_SHIFT, 4, FTR_UNSIGNED, ID_AA64PFR1_MTE_ASYMM, CAP_HWCAP, KERNEL_HWCAP_MTE3),
#endif /* CONFIG_ARM64_MTE */
- HWCAP_CAP(SYS_ID_AA64MMFR0_EL1, ID_AA64MMFR0_ECV_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_ECV),
- HWCAP_CAP(SYS_ID_AA64MMFR1_EL1, ID_AA64MMFR1_AFP_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_AFP),
- HWCAP_CAP(SYS_ID_AA64ISAR2_EL1, ID_AA64ISAR2_RPRES_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_RPRES),
+ HWCAP_CAP(SYS_ID_AA64MMFR0_EL1, ID_AA64MMFR0_ECV_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_ECV),
+ HWCAP_CAP(SYS_ID_AA64MMFR1_EL1, ID_AA64MMFR1_AFP_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_AFP),
+ HWCAP_CAP(SYS_ID_AA64ISAR2_EL1, ID_AA64ISAR2_RPRES_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_RPRES),
{},
};
@@ -2517,15 +2603,15 @@ static bool compat_has_neon(const struct arm64_cpu_capabilities *cap, int scope)
static const struct arm64_cpu_capabilities compat_elf_hwcaps[] = {
#ifdef CONFIG_COMPAT
HWCAP_CAP_MATCH(compat_has_neon, CAP_COMPAT_HWCAP, COMPAT_HWCAP_NEON),
- HWCAP_CAP(SYS_MVFR1_EL1, MVFR1_SIMDFMAC_SHIFT, FTR_UNSIGNED, 1, CAP_COMPAT_HWCAP, COMPAT_HWCAP_VFPv4),
+ HWCAP_CAP(SYS_MVFR1_EL1, MVFR1_SIMDFMAC_SHIFT, 4, FTR_UNSIGNED, 1, CAP_COMPAT_HWCAP, COMPAT_HWCAP_VFPv4),
/* Arm v8 mandates MVFR0.FPDP == {0, 2}. So, piggy back on this for the presence of VFP support */
- HWCAP_CAP(SYS_MVFR0_EL1, MVFR0_FPDP_SHIFT, FTR_UNSIGNED, 2, CAP_COMPAT_HWCAP, COMPAT_HWCAP_VFP),
- HWCAP_CAP(SYS_MVFR0_EL1, MVFR0_FPDP_SHIFT, FTR_UNSIGNED, 2, CAP_COMPAT_HWCAP, COMPAT_HWCAP_VFPv3),
- HWCAP_CAP(SYS_ID_ISAR5_EL1, ID_ISAR5_AES_SHIFT, FTR_UNSIGNED, 2, CAP_COMPAT_HWCAP2, COMPAT_HWCAP2_PMULL),
- HWCAP_CAP(SYS_ID_ISAR5_EL1, ID_ISAR5_AES_SHIFT, FTR_UNSIGNED, 1, CAP_COMPAT_HWCAP2, COMPAT_HWCAP2_AES),
- HWCAP_CAP(SYS_ID_ISAR5_EL1, ID_ISAR5_SHA1_SHIFT, FTR_UNSIGNED, 1, CAP_COMPAT_HWCAP2, COMPAT_HWCAP2_SHA1),
- HWCAP_CAP(SYS_ID_ISAR5_EL1, ID_ISAR5_SHA2_SHIFT, FTR_UNSIGNED, 1, CAP_COMPAT_HWCAP2, COMPAT_HWCAP2_SHA2),
- HWCAP_CAP(SYS_ID_ISAR5_EL1, ID_ISAR5_CRC32_SHIFT, FTR_UNSIGNED, 1, CAP_COMPAT_HWCAP2, COMPAT_HWCAP2_CRC32),
+ HWCAP_CAP(SYS_MVFR0_EL1, MVFR0_FPDP_SHIFT, 4, FTR_UNSIGNED, 2, CAP_COMPAT_HWCAP, COMPAT_HWCAP_VFP),
+ HWCAP_CAP(SYS_MVFR0_EL1, MVFR0_FPDP_SHIFT, 4, FTR_UNSIGNED, 2, CAP_COMPAT_HWCAP, COMPAT_HWCAP_VFPv3),
+ HWCAP_CAP(SYS_ID_ISAR5_EL1, ID_ISAR5_AES_SHIFT, 4, FTR_UNSIGNED, 2, CAP_COMPAT_HWCAP2, COMPAT_HWCAP2_PMULL),
+ HWCAP_CAP(SYS_ID_ISAR5_EL1, ID_ISAR5_AES_SHIFT, 4, FTR_UNSIGNED, 1, CAP_COMPAT_HWCAP2, COMPAT_HWCAP2_AES),
+ HWCAP_CAP(SYS_ID_ISAR5_EL1, ID_ISAR5_SHA1_SHIFT, 4, FTR_UNSIGNED, 1, CAP_COMPAT_HWCAP2, COMPAT_HWCAP2_SHA1),
+ HWCAP_CAP(SYS_ID_ISAR5_EL1, ID_ISAR5_SHA2_SHIFT, 4, FTR_UNSIGNED, 1, CAP_COMPAT_HWCAP2, COMPAT_HWCAP2_SHA2),
+ HWCAP_CAP(SYS_ID_ISAR5_EL1, ID_ISAR5_CRC32_SHIFT, 4, FTR_UNSIGNED, 1, CAP_COMPAT_HWCAP2, COMPAT_HWCAP2_CRC32),
#endif
{},
};
diff --git a/arch/arm64/kernel/cpuidle.c b/arch/arm64/kernel/cpuidle.c
index 03991eeff643..3006f4324808 100644
--- a/arch/arm64/kernel/cpuidle.c
+++ b/arch/arm64/kernel/cpuidle.c
@@ -54,6 +54,9 @@ static int psci_acpi_cpu_init_idle(unsigned int cpu)
struct acpi_lpi_state *lpi;
struct acpi_processor *pr = per_cpu(processors, cpu);
+ if (unlikely(!pr || !pr->flags.has_lpi))
+ return -EINVAL;
+
/*
* If the PSCI cpu_suspend function hook has not been initialized
* idle states must not be enabled, so bail out
@@ -61,9 +64,6 @@ static int psci_acpi_cpu_init_idle(unsigned int cpu)
if (!psci_ops.cpu_suspend)
return -EOPNOTSUPP;
- if (unlikely(!pr || !pr->flags.has_lpi))
- return -EINVAL;
-
count = pr->power.count - 1;
if (count <= 0)
return -ENODEV;
diff --git a/arch/arm64/kernel/cpuinfo.c b/arch/arm64/kernel/cpuinfo.c
index 591c18a889a5..330b92ea863a 100644
--- a/arch/arm64/kernel/cpuinfo.c
+++ b/arch/arm64/kernel/cpuinfo.c
@@ -97,6 +97,7 @@ static const char *const hwcap_str[] = {
[KERNEL_HWCAP_ECV] = "ecv",
[KERNEL_HWCAP_AFP] = "afp",
[KERNEL_HWCAP_RPRES] = "rpres",
+ [KERNEL_HWCAP_MTE3] = "mte3",
};
#ifdef CONFIG_COMPAT
diff --git a/arch/arm64/kernel/crash_core.c b/arch/arm64/kernel/crash_core.c
index 314391a156ee..2b65aae332ce 100644
--- a/arch/arm64/kernel/crash_core.c
+++ b/arch/arm64/kernel/crash_core.c
@@ -20,6 +20,12 @@ void arch_crash_save_vmcoreinfo(void)
{
VMCOREINFO_NUMBER(VA_BITS);
/* 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);
vmcoreinfo_append_str("NUMBER(kimage_voffset)=0x%llx\n",
kimage_voffset);
vmcoreinfo_append_str("NUMBER(PHYS_OFFSET)=0x%llx\n",
diff --git a/arch/arm64/kernel/elfcore.c b/arch/arm64/kernel/elfcore.c
new file mode 100644
index 000000000000..3ed39c61a510
--- /dev/null
+++ b/arch/arm64/kernel/elfcore.c
@@ -0,0 +1,134 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+#include <linux/coredump.h>
+#include <linux/elfcore.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+
+#include <asm/cpufeature.h>
+#include <asm/mte.h>
+
+#ifndef VMA_ITERATOR
+#define VMA_ITERATOR(name, mm, addr) \
+ struct mm_struct *name = mm
+#define for_each_vma(vmi, vma) \
+ for (vma = vmi->mmap; vma; vma = vma->vm_next)
+#endif
+
+#define for_each_mte_vma(vmi, vma) \
+ if (system_supports_mte()) \
+ for_each_vma(vmi, vma) \
+ if (vma->vm_flags & VM_MTE)
+
+static unsigned long mte_vma_tag_dump_size(struct vm_area_struct *vma)
+{
+ if (vma->vm_flags & VM_DONTDUMP)
+ return 0;
+
+ return vma_pages(vma) * MTE_PAGE_TAG_STORAGE;
+}
+
+/* Derived from dump_user_range(); start/end must be page-aligned */
+static int mte_dump_tag_range(struct coredump_params *cprm,
+ unsigned long start, unsigned long end)
+{
+ unsigned long addr;
+
+ for (addr = start; addr < end; addr += PAGE_SIZE) {
+ char tags[MTE_PAGE_TAG_STORAGE];
+ struct page *page = get_dump_page(addr);
+
+ /*
+ * get_dump_page() returns NULL when encountering an empty
+ * page table entry that would otherwise have been filled with
+ * the zero page. Skip the equivalent tag dump which would
+ * have been all zeros.
+ */
+ if (!page) {
+ dump_skip(cprm, MTE_PAGE_TAG_STORAGE);
+ continue;
+ }
+
+ /*
+ * Pages mapped in user space as !pte_access_permitted() (e.g.
+ * PROT_EXEC only) may not have the PG_mte_tagged flag set.
+ */
+ if (!test_bit(PG_mte_tagged, &page->flags)) {
+ put_page(page);
+ dump_skip(cprm, MTE_PAGE_TAG_STORAGE);
+ continue;
+ }
+
+ mte_save_page_tags(page_address(page), tags);
+ put_page(page);
+ if (!dump_emit(cprm, tags, MTE_PAGE_TAG_STORAGE))
+ return 0;
+ }
+
+ return 1;
+}
+
+Elf_Half elf_core_extra_phdrs(void)
+{
+ struct vm_area_struct *vma;
+ int vma_count = 0;
+ VMA_ITERATOR(vmi, current->mm, 0);
+
+ for_each_mte_vma(vmi, vma)
+ vma_count++;
+
+ return vma_count;
+}
+
+int elf_core_write_extra_phdrs(struct coredump_params *cprm, loff_t offset)
+{
+ struct vm_area_struct *vma;
+ VMA_ITERATOR(vmi, current->mm, 0);
+
+ for_each_mte_vma(vmi, vma) {
+ struct elf_phdr phdr;
+
+ phdr.p_type = PT_ARM_MEMTAG_MTE;
+ phdr.p_offset = offset;
+ phdr.p_vaddr = vma->vm_start;
+ phdr.p_paddr = 0;
+ phdr.p_filesz = mte_vma_tag_dump_size(vma);
+ phdr.p_memsz = vma->vm_end - vma->vm_start;
+ offset += phdr.p_filesz;
+ phdr.p_flags = 0;
+ phdr.p_align = 0;
+
+ if (!dump_emit(cprm, &phdr, sizeof(phdr)))
+ return 0;
+ }
+
+ return 1;
+}
+
+size_t elf_core_extra_data_size(void)
+{
+ struct vm_area_struct *vma;
+ size_t data_size = 0;
+ VMA_ITERATOR(vmi, current->mm, 0);
+
+ for_each_mte_vma(vmi, vma)
+ data_size += mte_vma_tag_dump_size(vma);
+
+ return data_size;
+}
+
+int elf_core_write_extra_data(struct coredump_params *cprm)
+{
+ struct vm_area_struct *vma;
+ VMA_ITERATOR(vmi, current->mm, 0);
+
+ for_each_mte_vma(vmi, vma) {
+ if (vma->vm_flags & VM_DONTDUMP)
+ continue;
+
+ if (!mte_dump_tag_range(cprm, vma->vm_start, vma->vm_end))
+ return 0;
+ }
+
+ return 1;
+}
diff --git a/arch/arm64/kernel/entry-common.c b/arch/arm64/kernel/entry-common.c
index ef7fcefb96bd..878c65aa7206 100644
--- a/arch/arm64/kernel/entry-common.c
+++ b/arch/arm64/kernel/entry-common.c
@@ -6,6 +6,7 @@
*/
#include <linux/context_tracking.h>
+#include <linux/kasan.h>
#include <linux/linkage.h>
#include <linux/lockdep.h>
#include <linux/ptrace.h>
@@ -56,6 +57,7 @@ static void noinstr enter_from_kernel_mode(struct pt_regs *regs)
{
__enter_from_kernel_mode(regs);
mte_check_tfsr_entry();
+ mte_disable_tco_entry(current);
}
/*
@@ -103,6 +105,7 @@ static __always_inline void __enter_from_user_mode(void)
CT_WARN_ON(ct_state() != CONTEXT_USER);
user_exit_irqoff();
trace_hardirqs_off_finish();
+ mte_disable_tco_entry(current);
}
static __always_inline void enter_from_user_mode(struct pt_regs *regs)
@@ -220,9 +223,26 @@ static void noinstr arm64_exit_el1_dbg(struct pt_regs *regs)
lockdep_hardirqs_on(CALLER_ADDR0);
}
+#ifdef CONFIG_PREEMPT_DYNAMIC
+DEFINE_STATIC_KEY_TRUE(sk_dynamic_irqentry_exit_cond_resched);
+#define need_irq_preemption() \
+ (static_branch_unlikely(&sk_dynamic_irqentry_exit_cond_resched))
+#else
+#define need_irq_preemption() (IS_ENABLED(CONFIG_PREEMPTION))
+#endif
+
static void __sched arm64_preempt_schedule_irq(void)
{
- lockdep_assert_irqs_disabled();
+ if (!need_irq_preemption())
+ return;
+
+ /*
+ * Note: thread_info::preempt_count includes both thread_info::count
+ * and thread_info::need_resched, and is not equivalent to
+ * preempt_count().
+ */
+ if (READ_ONCE(current_thread_info()->preempt_count) != 0)
+ return;
/*
* DAIF.DA are cleared at the start of IRQ/FIQ handling, and when GIC
@@ -438,14 +458,7 @@ static __always_inline void __el1_irq(struct pt_regs *regs,
do_interrupt_handler(regs, handler);
irq_exit_rcu();
- /*
- * Note: thread_info::preempt_count includes both thread_info::count
- * and thread_info::need_resched, and is not equivalent to
- * preempt_count().
- */
- if (IS_ENABLED(CONFIG_PREEMPTION) &&
- READ_ONCE(current_thread_info()->preempt_count) == 0)
- arm64_preempt_schedule_irq();
+ arm64_preempt_schedule_irq();
exit_to_kernel_mode(regs);
}
diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S
index 772ec2ecf488..ede028dee81b 100644
--- a/arch/arm64/kernel/entry.S
+++ b/arch/arm64/kernel/entry.S
@@ -37,18 +37,21 @@
.macro kernel_ventry, el:req, ht:req, regsize:req, label:req
.align 7
-#ifdef CONFIG_UNMAP_KERNEL_AT_EL0
+.Lventry_start\@:
.if \el == 0
-alternative_if ARM64_UNMAP_KERNEL_AT_EL0
+ /*
+ * This must be the first instruction of the EL0 vector entries. It is
+ * skipped by the trampoline vectors, to trigger the cleanup.
+ */
+ b .Lskip_tramp_vectors_cleanup\@
.if \regsize == 64
mrs x30, tpidrro_el0
msr tpidrro_el0, xzr
.else
mov x30, xzr
.endif
-alternative_else_nop_endif
+.Lskip_tramp_vectors_cleanup\@:
.endif
-#endif
sub sp, sp, #PT_REGS_SIZE
#ifdef CONFIG_VMAP_STACK
@@ -95,11 +98,15 @@ alternative_else_nop_endif
mrs x0, tpidrro_el0
#endif
b el\el\ht\()_\regsize\()_\label
+.org .Lventry_start\@ + 128 // Did we overflow the ventry slot?
.endm
- .macro tramp_alias, dst, sym
+ .macro tramp_alias, dst, sym, tmp
mov_q \dst, TRAMP_VALIAS
- add \dst, \dst, #(\sym - .entry.tramp.text)
+ adr_l \tmp, \sym
+ add \dst, \dst, \tmp
+ adr_l \tmp, .entry.tramp.text
+ sub \dst, \dst, \tmp
.endm
/*
@@ -116,7 +123,7 @@ alternative_cb_end
tbnz \tmp2, #TIF_SSBD, .L__asm_ssbd_skip\@
mov w0, #ARM_SMCCC_ARCH_WORKAROUND_2
mov w1, #\state
-alternative_cb spectre_v4_patch_fw_mitigation_conduit
+alternative_cb smccc_patch_fw_mitigation_conduit
nop // Patched to SMC/HVC #0
alternative_cb_end
.L__asm_ssbd_skip\@:
@@ -300,6 +307,7 @@ alternative_else_nop_endif
str w21, [sp, #S_SYSCALLNO]
.endif
+#ifdef CONFIG_ARM64_PSEUDO_NMI
/* Save pmr */
alternative_if ARM64_HAS_IRQ_PRIO_MASKING
mrs_s x20, SYS_ICC_PMR_EL1
@@ -307,12 +315,6 @@ alternative_if ARM64_HAS_IRQ_PRIO_MASKING
mov x20, #GIC_PRIO_IRQON | GIC_PRIO_PSR_I_SET
msr_s SYS_ICC_PMR_EL1, x20
alternative_else_nop_endif
-
- /* Re-enable tag checking (TCO set on exception entry) */
-#ifdef CONFIG_ARM64_MTE
-alternative_if ARM64_MTE
- SET_PSTATE_TCO(0)
-alternative_else_nop_endif
#endif
/*
@@ -330,6 +332,7 @@ alternative_else_nop_endif
disable_daif
.endif
+#ifdef CONFIG_ARM64_PSEUDO_NMI
/* Restore pmr */
alternative_if ARM64_HAS_IRQ_PRIO_MASKING
ldr x20, [sp, #S_PMR_SAVE]
@@ -339,6 +342,7 @@ alternative_if ARM64_HAS_IRQ_PRIO_MASKING
dsb sy // Ensure priority change is seen by redistributor
.L__skip_pmr_sync\@:
alternative_else_nop_endif
+#endif
ldp x21, x22, [sp, #S_PC] // load ELR, SPSR
@@ -413,21 +417,26 @@ alternative_else_nop_endif
ldp x24, x25, [sp, #16 * 12]
ldp x26, x27, [sp, #16 * 13]
ldp x28, x29, [sp, #16 * 14]
- ldr lr, [sp, #S_LR]
- add sp, sp, #PT_REGS_SIZE // restore sp
.if \el == 0
-alternative_insn eret, nop, ARM64_UNMAP_KERNEL_AT_EL0
+alternative_if_not ARM64_UNMAP_KERNEL_AT_EL0
+ ldr lr, [sp, #S_LR]
+ add sp, sp, #PT_REGS_SIZE // restore sp
+ eret
+alternative_else_nop_endif
#ifdef CONFIG_UNMAP_KERNEL_AT_EL0
bne 4f
- msr far_el1, x30
- tramp_alias x30, tramp_exit_native
+ msr far_el1, x29
+ tramp_alias x30, tramp_exit_native, x29
br x30
4:
- tramp_alias x30, tramp_exit_compat
+ tramp_alias x30, tramp_exit_compat, x29
br x30
#endif
.else
+ ldr lr, [sp, #S_LR]
+ add sp, sp, #PT_REGS_SIZE // restore sp
+
/* Ensure any device/NC reads complete */
alternative_insn nop, "dmb sy", ARM64_WORKAROUND_1508412
@@ -594,12 +603,6 @@ SYM_CODE_END(ret_to_user)
.popsection // .entry.text
-#ifdef CONFIG_UNMAP_KERNEL_AT_EL0
-/*
- * Exception vectors trampoline.
- */
- .pushsection ".entry.tramp.text", "ax"
-
// Move from tramp_pg_dir to swapper_pg_dir
.macro tramp_map_kernel, tmp
mrs \tmp, ttbr1_el1
@@ -633,12 +636,47 @@ alternative_else_nop_endif
*/
.endm
- .macro tramp_ventry, regsize = 64
+ .macro tramp_data_page dst
+ adr_l \dst, .entry.tramp.text
+ sub \dst, \dst, PAGE_SIZE
+ .endm
+
+ .macro tramp_data_read_var dst, var
+#ifdef CONFIG_RANDOMIZE_BASE
+ tramp_data_page \dst
+ add \dst, \dst, #:lo12:__entry_tramp_data_\var
+ ldr \dst, [\dst]
+#else
+ ldr \dst, =\var
+#endif
+ .endm
+
+#define BHB_MITIGATION_NONE 0
+#define BHB_MITIGATION_LOOP 1
+#define BHB_MITIGATION_FW 2
+#define BHB_MITIGATION_INSN 3
+
+ .macro tramp_ventry, vector_start, regsize, kpti, bhb
.align 7
1:
.if \regsize == 64
msr tpidrro_el0, x30 // Restored in kernel_ventry
.endif
+
+ .if \bhb == BHB_MITIGATION_LOOP
+ /*
+ * This sequence must appear before the first indirect branch. i.e. the
+ * ret out of tramp_ventry. It appears here because x30 is free.
+ */
+ __mitigate_spectre_bhb_loop x30
+ .endif // \bhb == BHB_MITIGATION_LOOP
+
+ .if \bhb == BHB_MITIGATION_INSN
+ clearbhb
+ isb
+ .endif // \bhb == BHB_MITIGATION_INSN
+
+ .if \kpti == 1
/*
* Defend against branch aliasing attacks by pushing a dummy
* entry onto the return stack and using a RET instruction to
@@ -648,46 +686,75 @@ alternative_else_nop_endif
b .
2:
tramp_map_kernel x30
-#ifdef CONFIG_RANDOMIZE_BASE
- adr x30, tramp_vectors + PAGE_SIZE
alternative_insn isb, nop, ARM64_WORKAROUND_QCOM_FALKOR_E1003
- ldr x30, [x30]
-#else
- ldr x30, =vectors
-#endif
+ tramp_data_read_var x30, vectors
alternative_if_not ARM64_WORKAROUND_CAVIUM_TX2_219_PRFM
- prfm plil1strm, [x30, #(1b - tramp_vectors)]
+ prfm plil1strm, [x30, #(1b - \vector_start)]
alternative_else_nop_endif
+
msr vbar_el1, x30
- add x30, x30, #(1b - tramp_vectors)
isb
+ .else
+ ldr x30, =vectors
+ .endif // \kpti == 1
+
+ .if \bhb == BHB_MITIGATION_FW
+ /*
+ * The firmware sequence must appear before the first indirect branch.
+ * i.e. the ret out of tramp_ventry. But it also needs the stack to be
+ * mapped to save/restore the registers the SMC clobbers.
+ */
+ __mitigate_spectre_bhb_fw
+ .endif // \bhb == BHB_MITIGATION_FW
+
+ add x30, x30, #(1b - \vector_start + 4)
ret
+.org 1b + 128 // Did we overflow the ventry slot?
.endm
.macro tramp_exit, regsize = 64
- adr x30, tramp_vectors
+ tramp_data_read_var x30, this_cpu_vector
+ get_this_cpu_offset x29
+ ldr x30, [x30, x29]
+
msr vbar_el1, x30
- tramp_unmap_kernel x30
+ ldr lr, [sp, #S_LR]
+ tramp_unmap_kernel x29
.if \regsize == 64
- mrs x30, far_el1
+ mrs x29, far_el1
.endif
+ add sp, sp, #PT_REGS_SIZE // restore sp
eret
sb
.endm
- .align 11
-SYM_CODE_START_NOALIGN(tramp_vectors)
+ .macro generate_tramp_vector, kpti, bhb
+.Lvector_start\@:
.space 0x400
- tramp_ventry
- tramp_ventry
- tramp_ventry
- tramp_ventry
+ .rept 4
+ tramp_ventry .Lvector_start\@, 64, \kpti, \bhb
+ .endr
+ .rept 4
+ tramp_ventry .Lvector_start\@, 32, \kpti, \bhb
+ .endr
+ .endm
- tramp_ventry 32
- tramp_ventry 32
- tramp_ventry 32
- tramp_ventry 32
+#ifdef CONFIG_UNMAP_KERNEL_AT_EL0
+/*
+ * Exception vectors trampoline.
+ * The order must match __bp_harden_el1_vectors and the
+ * arm64_bp_harden_el1_vectors enum.
+ */
+ .pushsection ".entry.tramp.text", "ax"
+ .align 11
+SYM_CODE_START_NOALIGN(tramp_vectors)
+#ifdef CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY
+ generate_tramp_vector kpti=1, bhb=BHB_MITIGATION_LOOP
+ generate_tramp_vector kpti=1, bhb=BHB_MITIGATION_FW
+ generate_tramp_vector kpti=1, bhb=BHB_MITIGATION_INSN
+#endif /* CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY */
+ generate_tramp_vector kpti=1, bhb=BHB_MITIGATION_NONE
SYM_CODE_END(tramp_vectors)
SYM_CODE_START(tramp_exit_native)
@@ -704,13 +771,57 @@ SYM_CODE_END(tramp_exit_compat)
.pushsection ".rodata", "a"
.align PAGE_SHIFT
SYM_DATA_START(__entry_tramp_data_start)
+__entry_tramp_data_vectors:
.quad vectors
+#ifdef CONFIG_ARM_SDE_INTERFACE
+__entry_tramp_data___sdei_asm_handler:
+ .quad __sdei_asm_handler
+#endif /* CONFIG_ARM_SDE_INTERFACE */
+__entry_tramp_data_this_cpu_vector:
+ .quad this_cpu_vector
SYM_DATA_END(__entry_tramp_data_start)
.popsection // .rodata
#endif /* CONFIG_RANDOMIZE_BASE */
#endif /* CONFIG_UNMAP_KERNEL_AT_EL0 */
/*
+ * Exception vectors for spectre mitigations on entry from EL1 when
+ * kpti is not in use.
+ */
+ .macro generate_el1_vector, bhb
+.Lvector_start\@:
+ kernel_ventry 1, t, 64, sync // Synchronous EL1t
+ kernel_ventry 1, t, 64, irq // IRQ EL1t
+ kernel_ventry 1, t, 64, fiq // FIQ EL1h
+ kernel_ventry 1, t, 64, error // Error EL1t
+
+ kernel_ventry 1, h, 64, sync // Synchronous EL1h
+ kernel_ventry 1, h, 64, irq // IRQ EL1h
+ kernel_ventry 1, h, 64, fiq // FIQ EL1h
+ kernel_ventry 1, h, 64, error // Error EL1h
+
+ .rept 4
+ tramp_ventry .Lvector_start\@, 64, 0, \bhb
+ .endr
+ .rept 4
+ tramp_ventry .Lvector_start\@, 32, 0, \bhb
+ .endr
+ .endm
+
+/* The order must match tramp_vecs and the arm64_bp_harden_el1_vectors enum. */
+ .pushsection ".entry.text", "ax"
+ .align 11
+SYM_CODE_START(__bp_harden_el1_vectors)
+#ifdef CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY
+ generate_el1_vector bhb=BHB_MITIGATION_LOOP
+ generate_el1_vector bhb=BHB_MITIGATION_FW
+ generate_el1_vector bhb=BHB_MITIGATION_INSN
+#endif /* CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY */
+SYM_CODE_END(__bp_harden_el1_vectors)
+ .popsection
+
+
+/*
* Register switch for AArch64. The callee-saved registers need to be saved
* and restored. On entry:
* x0 = previous task_struct (must be preserved across the switch)
@@ -835,14 +946,7 @@ SYM_CODE_START(__sdei_asm_entry_trampoline)
* Remember whether to unmap the kernel on exit.
*/
1: str x4, [x1, #(SDEI_EVENT_INTREGS + S_SDEI_TTBR1)]
-
-#ifdef CONFIG_RANDOMIZE_BASE
- adr x4, tramp_vectors + PAGE_SIZE
- add x4, x4, #:lo12:__sdei_asm_trampoline_next_handler
- ldr x4, [x4]
-#else
- ldr x4, =__sdei_asm_handler
-#endif
+ tramp_data_read_var x4, __sdei_asm_handler
br x4
SYM_CODE_END(__sdei_asm_entry_trampoline)
NOKPROBE(__sdei_asm_entry_trampoline)
@@ -865,13 +969,6 @@ SYM_CODE_END(__sdei_asm_exit_trampoline)
NOKPROBE(__sdei_asm_exit_trampoline)
.ltorg
.popsection // .entry.tramp.text
-#ifdef CONFIG_RANDOMIZE_BASE
-.pushsection ".rodata", "a"
-SYM_DATA_START(__sdei_asm_trampoline_next_handler)
- .quad __sdei_asm_handler
-SYM_DATA_END(__sdei_asm_trampoline_next_handler)
-.popsection // .rodata
-#endif /* CONFIG_RANDOMIZE_BASE */
#endif /* CONFIG_UNMAP_KERNEL_AT_EL0 */
/*
@@ -981,7 +1078,7 @@ alternative_if_not ARM64_UNMAP_KERNEL_AT_EL0
alternative_else_nop_endif
#ifdef CONFIG_UNMAP_KERNEL_AT_EL0
- tramp_alias dst=x5, sym=__sdei_asm_exit_trampoline
+ tramp_alias dst=x5, sym=__sdei_asm_exit_trampoline, tmp=x3
br x5
#endif
SYM_CODE_END(__sdei_asm_handler)
diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c
index 5280e098cfb5..47af76e53221 100644
--- a/arch/arm64/kernel/fpsimd.c
+++ b/arch/arm64/kernel/fpsimd.c
@@ -348,7 +348,13 @@ static void task_fpsimd_load(void)
/*
* Ensure FPSIMD/SVE storage in memory for the loaded context is up to
- * date with respect to the CPU registers.
+ * date with respect to the CPU registers. Note carefully that the
+ * current context is the context last bound to the CPU stored in
+ * last, if KVM is involved this may be the guest VM context rather
+ * than the host thread for the VM pointed to by current. This means
+ * that we must always reference the state storage via last rather
+ * than via current, other than the TIF_ flags which KVM will
+ * carefully maintain for us.
*/
static void fpsimd_save(void)
{
diff --git a/arch/arm64/kernel/idreg-override.c b/arch/arm64/kernel/idreg-override.c
index d8e606fe3c21..8a2ceb591686 100644
--- a/arch/arm64/kernel/idreg-override.c
+++ b/arch/arm64/kernel/idreg-override.c
@@ -17,7 +17,7 @@
#define FTR_DESC_NAME_LEN 20
#define FTR_DESC_FIELD_LEN 10
#define FTR_ALIAS_NAME_LEN 30
-#define FTR_ALIAS_OPTION_LEN 80
+#define FTR_ALIAS_OPTION_LEN 116
struct ftr_set_desc {
char name[FTR_DESC_NAME_LEN];
@@ -71,6 +71,16 @@ static const struct ftr_set_desc isar1 __initconst = {
},
};
+static const struct ftr_set_desc isar2 __initconst = {
+ .name = "id_aa64isar2",
+ .override = &id_aa64isar2_override,
+ .fields = {
+ { "gpa3", ID_AA64ISAR2_GPA3_SHIFT },
+ { "apa3", ID_AA64ISAR2_APA3_SHIFT },
+ {}
+ },
+};
+
extern struct arm64_ftr_override kaslr_feature_override;
static const struct ftr_set_desc kaslr __initconst = {
@@ -88,6 +98,7 @@ static const struct ftr_set_desc * const regs[] __initconst = {
&mmfr1,
&pfr1,
&isar1,
+ &isar2,
&kaslr,
};
@@ -100,7 +111,8 @@ static const struct {
{ "arm64.nobti", "id_aa64pfr1.bt=0" },
{ "arm64.nopauth",
"id_aa64isar1.gpi=0 id_aa64isar1.gpa=0 "
- "id_aa64isar1.api=0 id_aa64isar1.apa=0" },
+ "id_aa64isar1.api=0 id_aa64isar1.apa=0 "
+ "id_aa64isar2.gpa3=0 id_aa64isar2.apa3=0" },
{ "arm64.nomte", "id_aa64pfr1.mte=0" },
{ "nokaslr", "kaslr.disabled=1" },
};
diff --git a/arch/arm64/kernel/image-vars.h b/arch/arm64/kernel/image-vars.h
index 7eaf1f7c4168..241c86b67d01 100644
--- a/arch/arm64/kernel/image-vars.h
+++ b/arch/arm64/kernel/image-vars.h
@@ -66,6 +66,10 @@ KVM_NVHE_ALIAS(kvm_patch_vector_branch);
KVM_NVHE_ALIAS(kvm_update_va_mask);
KVM_NVHE_ALIAS(kvm_get_kimage_voffset);
KVM_NVHE_ALIAS(kvm_compute_final_ctr_el0);
+KVM_NVHE_ALIAS(spectre_bhb_patch_loop_iter);
+KVM_NVHE_ALIAS(spectre_bhb_patch_loop_mitigation_enable);
+KVM_NVHE_ALIAS(spectre_bhb_patch_wa3);
+KVM_NVHE_ALIAS(spectre_bhb_patch_clearbhb);
/* Global kernel state accessed by nVHE hyp code. */
KVM_NVHE_ALIAS(kvm_vgic_global_state);
@@ -79,6 +83,9 @@ KVM_NVHE_ALIAS(__hyp_stub_vectors);
/* Kernel symbol used by icache_is_vpipt(). */
KVM_NVHE_ALIAS(__icache_flags);
+/* VMID bits set by the KVM VMID allocator */
+KVM_NVHE_ALIAS(kvm_arm_vmid_bits);
+
/* Kernel symbols needed for cpus_have_final/const_caps checks. */
KVM_NVHE_ALIAS(arm64_const_caps_ready);
KVM_NVHE_ALIAS(cpu_hwcap_keys);
diff --git a/arch/arm64/kernel/mte.c b/arch/arm64/kernel/mte.c
index f418ebc65f95..78b3e0f8e997 100644
--- a/arch/arm64/kernel/mte.c
+++ b/arch/arm64/kernel/mte.c
@@ -186,6 +186,11 @@ void mte_check_tfsr_el1(void)
}
#endif
+/*
+ * This is where we actually resolve the system and process MTE mode
+ * configuration into an actual value in SCTLR_EL1 that affects
+ * userspace.
+ */
static void mte_update_sctlr_user(struct task_struct *task)
{
/*
@@ -199,9 +204,20 @@ static void mte_update_sctlr_user(struct task_struct *task)
unsigned long pref, resolved_mte_tcf;
pref = __this_cpu_read(mte_tcf_preferred);
+ /*
+ * If there is no overlap between the system preferred and
+ * program requested values go with what was requested.
+ */
resolved_mte_tcf = (mte_ctrl & pref) ? pref : mte_ctrl;
sctlr &= ~SCTLR_EL1_TCF0_MASK;
- if (resolved_mte_tcf & MTE_CTRL_TCF_ASYNC)
+ /*
+ * Pick an actual setting. The order in which we check for
+ * set bits and map into register values determines our
+ * default order.
+ */
+ if (resolved_mte_tcf & MTE_CTRL_TCF_ASYMM)
+ sctlr |= SCTLR_EL1_TCF0_ASYMM;
+ else if (resolved_mte_tcf & MTE_CTRL_TCF_ASYNC)
sctlr |= SCTLR_EL1_TCF0_ASYNC;
else if (resolved_mte_tcf & MTE_CTRL_TCF_SYNC)
sctlr |= SCTLR_EL1_TCF0_SYNC;
@@ -253,6 +269,9 @@ void mte_thread_switch(struct task_struct *next)
mte_update_sctlr_user(next);
mte_update_gcr_excl(next);
+ /* TCO may not have been disabled on exception entry for the current task. */
+ mte_disable_tco_entry(next);
+
/*
* Check if an async tag exception occurred at EL1.
*
@@ -293,6 +312,17 @@ long set_mte_ctrl(struct task_struct *task, unsigned long arg)
if (arg & PR_MTE_TCF_SYNC)
mte_ctrl |= MTE_CTRL_TCF_SYNC;
+ /*
+ * If the system supports it and both sync and async modes are
+ * specified then implicitly enable asymmetric mode.
+ * Userspace could see a mix of both sync and async anyway due
+ * to differing or changing defaults on CPUs.
+ */
+ if (cpus_have_cap(ARM64_MTE_ASYMM) &&
+ (arg & PR_MTE_TCF_ASYNC) &&
+ (arg & PR_MTE_TCF_SYNC))
+ mte_ctrl |= MTE_CTRL_TCF_ASYMM;
+
task->thread.mte_ctrl = mte_ctrl;
if (task == current) {
preempt_disable();
@@ -467,6 +497,8 @@ static ssize_t mte_tcf_preferred_show(struct device *dev,
return sysfs_emit(buf, "async\n");
case MTE_CTRL_TCF_SYNC:
return sysfs_emit(buf, "sync\n");
+ case MTE_CTRL_TCF_ASYMM:
+ return sysfs_emit(buf, "asymm\n");
default:
return sysfs_emit(buf, "???\n");
}
@@ -482,6 +514,8 @@ static ssize_t mte_tcf_preferred_store(struct device *dev,
tcf = MTE_CTRL_TCF_ASYNC;
else if (sysfs_streq(buf, "sync"))
tcf = MTE_CTRL_TCF_SYNC;
+ else if (cpus_have_cap(ARM64_MTE_ASYMM) && sysfs_streq(buf, "asymm"))
+ tcf = MTE_CTRL_TCF_ASYMM;
else
return -EINVAL;
diff --git a/arch/arm64/kernel/perf_event.c b/arch/arm64/kernel/perf_event.c
index cab678ed6618..cb69ff1e6138 100644
--- a/arch/arm64/kernel/perf_event.c
+++ b/arch/arm64/kernel/perf_event.c
@@ -242,6 +242,16 @@ static struct attribute *armv8_pmuv3_event_attrs[] = {
ARMV8_EVENT_ATTR(l2d_cache_lmiss_rd, ARMV8_PMUV3_PERFCTR_L2D_CACHE_LMISS_RD),
ARMV8_EVENT_ATTR(l2i_cache_lmiss, ARMV8_PMUV3_PERFCTR_L2I_CACHE_LMISS),
ARMV8_EVENT_ATTR(l3d_cache_lmiss_rd, ARMV8_PMUV3_PERFCTR_L3D_CACHE_LMISS_RD),
+ ARMV8_EVENT_ATTR(trb_wrap, ARMV8_PMUV3_PERFCTR_TRB_WRAP),
+ ARMV8_EVENT_ATTR(trb_trig, ARMV8_PMUV3_PERFCTR_TRB_TRIG),
+ ARMV8_EVENT_ATTR(trcextout0, ARMV8_PMUV3_PERFCTR_TRCEXTOUT0),
+ ARMV8_EVENT_ATTR(trcextout1, ARMV8_PMUV3_PERFCTR_TRCEXTOUT1),
+ ARMV8_EVENT_ATTR(trcextout2, ARMV8_PMUV3_PERFCTR_TRCEXTOUT2),
+ ARMV8_EVENT_ATTR(trcextout3, ARMV8_PMUV3_PERFCTR_TRCEXTOUT3),
+ ARMV8_EVENT_ATTR(cti_trigout4, ARMV8_PMUV3_PERFCTR_CTI_TRIGOUT4),
+ ARMV8_EVENT_ATTR(cti_trigout5, ARMV8_PMUV3_PERFCTR_CTI_TRIGOUT5),
+ ARMV8_EVENT_ATTR(cti_trigout6, ARMV8_PMUV3_PERFCTR_CTI_TRIGOUT6),
+ ARMV8_EVENT_ATTR(cti_trigout7, ARMV8_PMUV3_PERFCTR_CTI_TRIGOUT7),
ARMV8_EVENT_ATTR(ldst_align_lat, ARMV8_PMUV3_PERFCTR_LDST_ALIGN_LAT),
ARMV8_EVENT_ATTR(ld_align_lat, ARMV8_PMUV3_PERFCTR_LD_ALIGN_LAT),
ARMV8_EVENT_ATTR(st_align_lat, ARMV8_PMUV3_PERFCTR_ST_ALIGN_LAT),
diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c
index 5369e649fa79..7fa97df55e3a 100644
--- a/arch/arm64/kernel/process.c
+++ b/arch/arm64/kernel/process.c
@@ -635,7 +635,8 @@ long set_tagged_addr_ctrl(struct task_struct *task, unsigned long arg)
return -EINVAL;
if (system_supports_mte())
- valid_mask |= PR_MTE_TCF_MASK | PR_MTE_TAG_MASK;
+ valid_mask |= PR_MTE_TCF_SYNC | PR_MTE_TCF_ASYNC \
+ | PR_MTE_TAG_MASK;
if (arg & ~valid_mask)
return -EINVAL;
diff --git a/arch/arm64/kernel/proton-pack.c b/arch/arm64/kernel/proton-pack.c
index 902e4084c477..5777929d35bf 100644
--- a/arch/arm64/kernel/proton-pack.c
+++ b/arch/arm64/kernel/proton-pack.c
@@ -18,15 +18,18 @@
*/
#include <linux/arm-smccc.h>
+#include <linux/bpf.h>
#include <linux/cpu.h>
#include <linux/device.h>
#include <linux/nospec.h>
#include <linux/prctl.h>
#include <linux/sched/task_stack.h>
+#include <asm/debug-monitors.h>
#include <asm/insn.h>
#include <asm/spectre.h>
#include <asm/traps.h>
+#include <asm/vectors.h>
#include <asm/virt.h>
/*
@@ -96,14 +99,51 @@ static bool spectre_v2_mitigations_off(void)
return ret;
}
+static const char *get_bhb_affected_string(enum mitigation_state bhb_state)
+{
+ switch (bhb_state) {
+ case SPECTRE_UNAFFECTED:
+ return "";
+ default:
+ case SPECTRE_VULNERABLE:
+ return ", but not BHB";
+ case SPECTRE_MITIGATED:
+ return ", BHB";
+ }
+}
+
+static bool _unprivileged_ebpf_enabled(void)
+{
+#ifdef CONFIG_BPF_SYSCALL
+ return !sysctl_unprivileged_bpf_disabled;
+#else
+ return false;
+#endif
+}
+
ssize_t cpu_show_spectre_v2(struct device *dev, struct device_attribute *attr,
char *buf)
{
+ enum mitigation_state bhb_state = arm64_get_spectre_bhb_state();
+ const char *bhb_str = get_bhb_affected_string(bhb_state);
+ const char *v2_str = "Branch predictor hardening";
+
switch (spectre_v2_state) {
case SPECTRE_UNAFFECTED:
- return sprintf(buf, "Not affected\n");
+ if (bhb_state == SPECTRE_UNAFFECTED)
+ return sprintf(buf, "Not affected\n");
+
+ /*
+ * Platforms affected by Spectre-BHB can't report
+ * "Not affected" for Spectre-v2.
+ */
+ v2_str = "CSV2";
+ fallthrough;
case SPECTRE_MITIGATED:
- return sprintf(buf, "Mitigation: Branch predictor hardening\n");
+ if (bhb_state == SPECTRE_MITIGATED && _unprivileged_ebpf_enabled())
+ return sprintf(buf, "Vulnerable: Unprivileged eBPF enabled\n");
+
+ return sprintf(buf, "Mitigation: %s%s\n", v2_str, bhb_str);
case SPECTRE_VULNERABLE:
fallthrough;
default:
@@ -193,17 +233,20 @@ static void install_bp_hardening_cb(bp_hardening_cb_t fn)
__this_cpu_write(bp_hardening_data.slot, HYP_VECTOR_SPECTRE_DIRECT);
}
-static void call_smc_arch_workaround_1(void)
+/* Called during entry so must be noinstr */
+static noinstr void call_smc_arch_workaround_1(void)
{
arm_smccc_1_1_smc(ARM_SMCCC_ARCH_WORKAROUND_1, NULL);
}
-static void call_hvc_arch_workaround_1(void)
+/* Called during entry so must be noinstr */
+static noinstr void call_hvc_arch_workaround_1(void)
{
arm_smccc_1_1_hvc(ARM_SMCCC_ARCH_WORKAROUND_1, NULL);
}
-static void qcom_link_stack_sanitisation(void)
+/* Called during entry so must be noinstr */
+static noinstr void qcom_link_stack_sanitisation(void)
{
u64 tmp;
@@ -554,9 +597,9 @@ void __init spectre_v4_patch_fw_mitigation_enable(struct alt_instr *alt,
* Patch a NOP in the Spectre-v4 mitigation code with an SMC/HVC instruction
* to call into firmware to adjust the mitigation state.
*/
-void __init spectre_v4_patch_fw_mitigation_conduit(struct alt_instr *alt,
- __le32 *origptr,
- __le32 *updptr, int nr_inst)
+void __init smccc_patch_fw_mitigation_conduit(struct alt_instr *alt,
+ __le32 *origptr,
+ __le32 *updptr, int nr_inst)
{
u32 insn;
@@ -770,3 +813,344 @@ int arch_prctl_spec_ctrl_get(struct task_struct *task, unsigned long which)
return -ENODEV;
}
}
+
+/*
+ * Spectre BHB.
+ *
+ * A CPU is either:
+ * - Mitigated by a branchy loop a CPU specific number of times, and listed
+ * in our "loop mitigated list".
+ * - Mitigated in software by the firmware Spectre v2 call.
+ * - Has the ClearBHB instruction to perform the mitigation.
+ * - Has the 'Exception Clears Branch History Buffer' (ECBHB) feature, so no
+ * software mitigation in the vectors is needed.
+ * - Has CSV2.3, so is unaffected.
+ */
+static enum mitigation_state spectre_bhb_state;
+
+enum mitigation_state arm64_get_spectre_bhb_state(void)
+{
+ return spectre_bhb_state;
+}
+
+enum bhb_mitigation_bits {
+ BHB_LOOP,
+ BHB_FW,
+ BHB_HW,
+ BHB_INSN,
+};
+static unsigned long system_bhb_mitigations;
+
+/*
+ * This must be called with SCOPE_LOCAL_CPU for each type of CPU, before any
+ * SCOPE_SYSTEM call will give the right answer.
+ */
+u8 spectre_bhb_loop_affected(int scope)
+{
+ u8 k = 0;
+ static u8 max_bhb_k;
+
+ if (scope == SCOPE_LOCAL_CPU) {
+ static const struct midr_range spectre_bhb_k32_list[] = {
+ MIDR_ALL_VERSIONS(MIDR_CORTEX_A78),
+ MIDR_ALL_VERSIONS(MIDR_CORTEX_A78C),
+ MIDR_ALL_VERSIONS(MIDR_CORTEX_X1),
+ MIDR_ALL_VERSIONS(MIDR_CORTEX_A710),
+ MIDR_ALL_VERSIONS(MIDR_CORTEX_X2),
+ MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N2),
+ MIDR_ALL_VERSIONS(MIDR_NEOVERSE_V1),
+ {},
+ };
+ static const struct midr_range spectre_bhb_k24_list[] = {
+ MIDR_ALL_VERSIONS(MIDR_CORTEX_A76),
+ MIDR_ALL_VERSIONS(MIDR_CORTEX_A77),
+ MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N1),
+ {},
+ };
+ static const struct midr_range spectre_bhb_k8_list[] = {
+ MIDR_ALL_VERSIONS(MIDR_CORTEX_A72),
+ MIDR_ALL_VERSIONS(MIDR_CORTEX_A57),
+ {},
+ };
+
+ if (is_midr_in_range_list(read_cpuid_id(), spectre_bhb_k32_list))
+ k = 32;
+ else if (is_midr_in_range_list(read_cpuid_id(), spectre_bhb_k24_list))
+ k = 24;
+ else if (is_midr_in_range_list(read_cpuid_id(), spectre_bhb_k8_list))
+ k = 8;
+
+ max_bhb_k = max(max_bhb_k, k);
+ } else {
+ k = max_bhb_k;
+ }
+
+ return k;
+}
+
+static enum mitigation_state spectre_bhb_get_cpu_fw_mitigation_state(void)
+{
+ int ret;
+ struct arm_smccc_res res;
+
+ arm_smccc_1_1_invoke(ARM_SMCCC_ARCH_FEATURES_FUNC_ID,
+ ARM_SMCCC_ARCH_WORKAROUND_3, &res);
+
+ ret = res.a0;
+ switch (ret) {
+ case SMCCC_RET_SUCCESS:
+ return SPECTRE_MITIGATED;
+ case SMCCC_ARCH_WORKAROUND_RET_UNAFFECTED:
+ return SPECTRE_UNAFFECTED;
+ default:
+ fallthrough;
+ case SMCCC_RET_NOT_SUPPORTED:
+ return SPECTRE_VULNERABLE;
+ }
+}
+
+static bool is_spectre_bhb_fw_affected(int scope)
+{
+ static bool system_affected;
+ enum mitigation_state fw_state;
+ bool has_smccc = arm_smccc_1_1_get_conduit() != SMCCC_CONDUIT_NONE;
+ static const struct midr_range spectre_bhb_firmware_mitigated_list[] = {
+ MIDR_ALL_VERSIONS(MIDR_CORTEX_A73),
+ MIDR_ALL_VERSIONS(MIDR_CORTEX_A75),
+ {},
+ };
+ bool cpu_in_list = is_midr_in_range_list(read_cpuid_id(),
+ spectre_bhb_firmware_mitigated_list);
+
+ if (scope != SCOPE_LOCAL_CPU)
+ return system_affected;
+
+ fw_state = spectre_bhb_get_cpu_fw_mitigation_state();
+ if (cpu_in_list || (has_smccc && fw_state == SPECTRE_MITIGATED)) {
+ system_affected = true;
+ return true;
+ }
+
+ return false;
+}
+
+static bool supports_ecbhb(int scope)
+{
+ u64 mmfr1;
+
+ if (scope == SCOPE_LOCAL_CPU)
+ mmfr1 = read_sysreg_s(SYS_ID_AA64MMFR1_EL1);
+ else
+ mmfr1 = read_sanitised_ftr_reg(SYS_ID_AA64MMFR1_EL1);
+
+ return cpuid_feature_extract_unsigned_field(mmfr1,
+ ID_AA64MMFR1_ECBHB_SHIFT);
+}
+
+bool is_spectre_bhb_affected(const struct arm64_cpu_capabilities *entry,
+ int scope)
+{
+ WARN_ON(scope != SCOPE_LOCAL_CPU || preemptible());
+
+ if (supports_csv2p3(scope))
+ return false;
+
+ if (supports_clearbhb(scope))
+ return true;
+
+ if (spectre_bhb_loop_affected(scope))
+ return true;
+
+ if (is_spectre_bhb_fw_affected(scope))
+ return true;
+
+ return false;
+}
+
+static void this_cpu_set_vectors(enum arm64_bp_harden_el1_vectors slot)
+{
+ const char *v = arm64_get_bp_hardening_vector(slot);
+
+ if (slot < 0)
+ return;
+
+ __this_cpu_write(this_cpu_vector, v);
+
+ /*
+ * When KPTI is in use, the vectors are switched when exiting to
+ * user-space.
+ */
+ if (arm64_kernel_unmapped_at_el0())
+ return;
+
+ write_sysreg(v, vbar_el1);
+ isb();
+}
+
+void spectre_bhb_enable_mitigation(const struct arm64_cpu_capabilities *entry)
+{
+ bp_hardening_cb_t cpu_cb;
+ enum mitigation_state fw_state, state = SPECTRE_VULNERABLE;
+ struct bp_hardening_data *data = this_cpu_ptr(&bp_hardening_data);
+
+ if (!is_spectre_bhb_affected(entry, SCOPE_LOCAL_CPU))
+ return;
+
+ if (arm64_get_spectre_v2_state() == SPECTRE_VULNERABLE) {
+ /* No point mitigating Spectre-BHB alone. */
+ } else if (!IS_ENABLED(CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY)) {
+ pr_info_once("spectre-bhb mitigation disabled by compile time option\n");
+ } else if (cpu_mitigations_off()) {
+ pr_info_once("spectre-bhb mitigation disabled by command line option\n");
+ } else if (supports_ecbhb(SCOPE_LOCAL_CPU)) {
+ state = SPECTRE_MITIGATED;
+ set_bit(BHB_HW, &system_bhb_mitigations);
+ } else if (supports_clearbhb(SCOPE_LOCAL_CPU)) {
+ /*
+ * Ensure KVM uses the indirect vector which will have ClearBHB
+ * added.
+ */
+ if (!data->slot)
+ data->slot = HYP_VECTOR_INDIRECT;
+
+ this_cpu_set_vectors(EL1_VECTOR_BHB_CLEAR_INSN);
+ state = SPECTRE_MITIGATED;
+ set_bit(BHB_INSN, &system_bhb_mitigations);
+ } else if (spectre_bhb_loop_affected(SCOPE_LOCAL_CPU)) {
+ /*
+ * Ensure KVM uses the indirect vector which will have the
+ * branchy-loop added. A57/A72-r0 will already have selected
+ * the spectre-indirect vector, which is sufficient for BHB
+ * too.
+ */
+ if (!data->slot)
+ data->slot = HYP_VECTOR_INDIRECT;
+
+ this_cpu_set_vectors(EL1_VECTOR_BHB_LOOP);
+ state = SPECTRE_MITIGATED;
+ set_bit(BHB_LOOP, &system_bhb_mitigations);
+ } else if (is_spectre_bhb_fw_affected(SCOPE_LOCAL_CPU)) {
+ fw_state = spectre_bhb_get_cpu_fw_mitigation_state();
+ if (fw_state == SPECTRE_MITIGATED) {
+ /*
+ * Ensure KVM uses one of the spectre bp_hardening
+ * vectors. The indirect vector doesn't include the EL3
+ * call, so needs upgrading to
+ * HYP_VECTOR_SPECTRE_INDIRECT.
+ */
+ if (!data->slot || data->slot == HYP_VECTOR_INDIRECT)
+ data->slot += 1;
+
+ this_cpu_set_vectors(EL1_VECTOR_BHB_FW);
+
+ /*
+ * The WA3 call in the vectors supersedes the WA1 call
+ * made during context-switch. Uninstall any firmware
+ * bp_hardening callback.
+ */
+ cpu_cb = spectre_v2_get_sw_mitigation_cb();
+ if (__this_cpu_read(bp_hardening_data.fn) != cpu_cb)
+ __this_cpu_write(bp_hardening_data.fn, NULL);
+
+ state = SPECTRE_MITIGATED;
+ set_bit(BHB_FW, &system_bhb_mitigations);
+ }
+ }
+
+ update_mitigation_state(&spectre_bhb_state, state);
+}
+
+/* Patched to NOP when enabled */
+void noinstr spectre_bhb_patch_loop_mitigation_enable(struct alt_instr *alt,
+ __le32 *origptr,
+ __le32 *updptr, int nr_inst)
+{
+ BUG_ON(nr_inst != 1);
+
+ if (test_bit(BHB_LOOP, &system_bhb_mitigations))
+ *updptr++ = cpu_to_le32(aarch64_insn_gen_nop());
+}
+
+/* Patched to NOP when enabled */
+void noinstr spectre_bhb_patch_fw_mitigation_enabled(struct alt_instr *alt,
+ __le32 *origptr,
+ __le32 *updptr, int nr_inst)
+{
+ BUG_ON(nr_inst != 1);
+
+ if (test_bit(BHB_FW, &system_bhb_mitigations))
+ *updptr++ = cpu_to_le32(aarch64_insn_gen_nop());
+}
+
+/* Patched to correct the immediate */
+void noinstr spectre_bhb_patch_loop_iter(struct alt_instr *alt,
+ __le32 *origptr, __le32 *updptr, int nr_inst)
+{
+ u8 rd;
+ u32 insn;
+ u16 loop_count = spectre_bhb_loop_affected(SCOPE_SYSTEM);
+
+ BUG_ON(nr_inst != 1); /* MOV -> MOV */
+
+ if (!IS_ENABLED(CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY))
+ return;
+
+ insn = le32_to_cpu(*origptr);
+ rd = aarch64_insn_decode_register(AARCH64_INSN_REGTYPE_RD, insn);
+ insn = aarch64_insn_gen_movewide(rd, loop_count, 0,
+ AARCH64_INSN_VARIANT_64BIT,
+ AARCH64_INSN_MOVEWIDE_ZERO);
+ *updptr++ = cpu_to_le32(insn);
+}
+
+/* Patched to mov WA3 when supported */
+void noinstr spectre_bhb_patch_wa3(struct alt_instr *alt,
+ __le32 *origptr, __le32 *updptr, int nr_inst)
+{
+ u8 rd;
+ u32 insn;
+
+ BUG_ON(nr_inst != 1); /* MOV -> MOV */
+
+ if (!IS_ENABLED(CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY) ||
+ !test_bit(BHB_FW, &system_bhb_mitigations))
+ return;
+
+ insn = le32_to_cpu(*origptr);
+ rd = aarch64_insn_decode_register(AARCH64_INSN_REGTYPE_RD, insn);
+
+ insn = aarch64_insn_gen_logical_immediate(AARCH64_INSN_LOGIC_ORR,
+ AARCH64_INSN_VARIANT_32BIT,
+ AARCH64_INSN_REG_ZR, rd,
+ ARM_SMCCC_ARCH_WORKAROUND_3);
+ if (WARN_ON_ONCE(insn == AARCH64_BREAK_FAULT))
+ return;
+
+ *updptr++ = cpu_to_le32(insn);
+}
+
+/* Patched to NOP when not supported */
+void __init spectre_bhb_patch_clearbhb(struct alt_instr *alt,
+ __le32 *origptr, __le32 *updptr, int nr_inst)
+{
+ BUG_ON(nr_inst != 2);
+
+ if (test_bit(BHB_INSN, &system_bhb_mitigations))
+ return;
+
+ *updptr++ = cpu_to_le32(aarch64_insn_gen_nop());
+ *updptr++ = cpu_to_le32(aarch64_insn_gen_nop());
+}
+
+#ifdef CONFIG_BPF_SYSCALL
+#define EBPF_WARN "Unprivileged eBPF is enabled, data leaks possible via Spectre v2 BHB attacks!\n"
+void unpriv_ebpf_notify(int new_state)
+{
+ if (spectre_v2_state == SPECTRE_VULNERABLE ||
+ spectre_bhb_state != SPECTRE_MITIGATED)
+ return;
+
+ if (!new_state)
+ pr_err("WARNING: %s", EBPF_WARN);
+}
+#endif
diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
index f70573928f1b..3505789cf4bd 100644
--- a/arch/arm64/kernel/setup.c
+++ b/arch/arm64/kernel/setup.c
@@ -406,9 +406,6 @@ static int __init topology_init(void)
{
int i;
- for_each_online_node(i)
- register_one_node(i);
-
for_each_possible_cpu(i) {
struct cpu *cpu = &per_cpu(cpu_data.cpu, i);
cpu->hotpluggable = cpu_can_disable(i);
diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c
index d8aaf4b6f432..50fe8eaf7df0 100644
--- a/arch/arm64/kernel/signal.c
+++ b/arch/arm64/kernel/signal.c
@@ -11,7 +11,6 @@
#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/signal.h>
-#include <linux/personality.h>
#include <linux/freezer.h>
#include <linux/stddef.h>
#include <linux/uaccess.h>
@@ -577,10 +576,12 @@ static int setup_sigframe_layout(struct rt_sigframe_user_layout *user,
{
int err;
- err = sigframe_alloc(user, &user->fpsimd_offset,
- sizeof(struct fpsimd_context));
- if (err)
- return err;
+ if (system_supports_fpsimd()) {
+ err = sigframe_alloc(user, &user->fpsimd_offset,
+ sizeof(struct fpsimd_context));
+ if (err)
+ return err;
+ }
/* fault information, if valid */
if (add_all || current->thread.fault_code) {
diff --git a/arch/arm64/kernel/stacktrace.c b/arch/arm64/kernel/stacktrace.c
index 0fb58fed54cb..e4103e085681 100644
--- a/arch/arm64/kernel/stacktrace.c
+++ b/arch/arm64/kernel/stacktrace.c
@@ -33,8 +33,8 @@
*/
-static void start_backtrace(struct stackframe *frame, unsigned long fp,
- unsigned long pc)
+static notrace void start_backtrace(struct stackframe *frame, unsigned long fp,
+ unsigned long pc)
{
frame->fp = fp;
frame->pc = pc;
@@ -55,6 +55,7 @@ static void start_backtrace(struct stackframe *frame, unsigned long fp,
frame->prev_fp = 0;
frame->prev_type = STACK_TYPE_UNKNOWN;
}
+NOKPROBE_SYMBOL(start_backtrace);
/*
* Unwind from one frame record (A) to the next frame record (B).
diff --git a/arch/arm64/kernel/sys_compat.c b/arch/arm64/kernel/sys_compat.c
index db5159a3055f..12c6864e51e1 100644
--- a/arch/arm64/kernel/sys_compat.c
+++ b/arch/arm64/kernel/sys_compat.c
@@ -9,7 +9,6 @@
#include <linux/compat.h>
#include <linux/cpufeature.h>
-#include <linux/personality.h>
#include <linux/sched.h>
#include <linux/sched/signal.h>
#include <linux/slab.h>
diff --git a/arch/arm64/kernel/traps.c b/arch/arm64/kernel/traps.c
index 70fc42470f13..0529fd57567e 100644
--- a/arch/arm64/kernel/traps.c
+++ b/arch/arm64/kernel/traps.c
@@ -9,7 +9,6 @@
#include <linux/bug.h>
#include <linux/context_tracking.h>
#include <linux/signal.h>
-#include <linux/personality.h>
#include <linux/kallsyms.h>
#include <linux/kprobes.h>
#include <linux/spinlock.h>
@@ -519,7 +518,7 @@ void do_ptrauth_fault(struct pt_regs *regs, unsigned int esr)
NOKPROBE_SYMBOL(do_ptrauth_fault);
#define __user_cache_maint(insn, address, res) \
- if (address >= user_addr_max()) { \
+ if (address >= TASK_SIZE_MAX) { \
res = -EFAULT; \
} else { \
uaccess_ttbr0_enable(); \
diff --git a/arch/arm64/kernel/vdso/Makefile b/arch/arm64/kernel/vdso/Makefile
index 60813497a381..172452f79e46 100644
--- a/arch/arm64/kernel/vdso/Makefile
+++ b/arch/arm64/kernel/vdso/Makefile
@@ -29,8 +29,11 @@ ldflags-y := -shared -soname=linux-vdso.so.1 --hash-style=sysv \
ccflags-y := -fno-common -fno-builtin -fno-stack-protector -ffixed-x18
ccflags-y += -DDISABLE_BRANCH_PROFILING -DBUILD_VDSO
+# -Wmissing-prototypes and -Wmissing-declarations are removed from
+# the CFLAGS of vgettimeofday.c to make possible to build the
+# kernel with CONFIG_WERROR enabled.
CFLAGS_REMOVE_vgettimeofday.o = $(CC_FLAGS_FTRACE) -Os $(CC_FLAGS_SCS) $(GCC_PLUGINS_CFLAGS) \
- $(CC_FLAGS_LTO)
+ $(CC_FLAGS_LTO) -Wmissing-prototypes -Wmissing-declarations
KASAN_SANITIZE := n
KCSAN_SANITIZE := n
UBSAN_SANITIZE := n
diff --git a/arch/arm64/kernel/vmlinux.lds.S b/arch/arm64/kernel/vmlinux.lds.S
index 50bab186c49b..edaf0faf766f 100644
--- a/arch/arm64/kernel/vmlinux.lds.S
+++ b/arch/arm64/kernel/vmlinux.lds.S
@@ -341,7 +341,7 @@ ASSERT(__hibernate_exit_text_end - (__hibernate_exit_text_start & ~(SZ_4K - 1))
<= SZ_4K, "Hibernate exit text too big or misaligned")
#endif
#ifdef CONFIG_UNMAP_KERNEL_AT_EL0
-ASSERT((__entry_tramp_text_end - __entry_tramp_text_start) == PAGE_SIZE,
+ASSERT((__entry_tramp_text_end - __entry_tramp_text_start) <= 3*PAGE_SIZE,
"Entry trampoline text too big")
#endif
#ifdef CONFIG_KVM
diff --git a/arch/arm64/kvm/Makefile b/arch/arm64/kvm/Makefile
index 91861fd8b897..261644b1a6bb 100644
--- a/arch/arm64/kvm/Makefile
+++ b/arch/arm64/kvm/Makefile
@@ -14,7 +14,7 @@ kvm-y += arm.o mmu.o mmio.o psci.o hypercalls.o pvtime.o \
inject_fault.o va_layout.o handle_exit.o \
guest.o debug.o reset.o sys_regs.o \
vgic-sys-reg-v3.o fpsimd.o pmu.o pkvm.o \
- arch_timer.o trng.o\
+ arch_timer.o trng.o vmid.o \
vgic/vgic.o vgic/vgic-init.o \
vgic/vgic-irqfd.o vgic/vgic-v2.o \
vgic/vgic-v3.o vgic/vgic-v4.o \
diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
index a4a0063df456..523bc934fe2f 100644
--- a/arch/arm64/kvm/arm.c
+++ b/arch/arm64/kvm/arm.c
@@ -53,11 +53,6 @@ static DEFINE_PER_CPU(unsigned long, kvm_arm_hyp_stack_page);
unsigned long kvm_arm_hyp_percpu_base[NR_CPUS];
DECLARE_KVM_NVHE_PER_CPU(struct kvm_nvhe_init_params, kvm_init_params);
-/* The VMID used in the VTTBR */
-static atomic64_t kvm_vmid_gen = ATOMIC64_INIT(1);
-static u32 kvm_next_vmid;
-static DEFINE_SPINLOCK(kvm_vmid_lock);
-
static bool vgic_present;
static DEFINE_PER_CPU(unsigned char, kvm_arm_hardware_enabled);
@@ -89,7 +84,8 @@ int kvm_vm_ioctl_enable_cap(struct kvm *kvm,
switch (cap->cap) {
case KVM_CAP_ARM_NISV_TO_USER:
r = 0;
- kvm->arch.return_nisv_io_abort_to_user = true;
+ set_bit(KVM_ARCH_FLAG_RETURN_NISV_IO_ABORT_TO_USER,
+ &kvm->arch.flags);
break;
case KVM_CAP_ARM_MTE:
mutex_lock(&kvm->lock);
@@ -97,7 +93,7 @@ int kvm_vm_ioctl_enable_cap(struct kvm *kvm,
r = -EINVAL;
} else {
r = 0;
- kvm->arch.mte_enabled = true;
+ set_bit(KVM_ARCH_FLAG_MTE_ENABLED, &kvm->arch.flags);
}
mutex_unlock(&kvm->lock);
break;
@@ -150,6 +146,10 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type)
if (ret)
goto out_free_stage2_pgd;
+ if (!zalloc_cpumask_var(&kvm->arch.supported_cpus, GFP_KERNEL))
+ goto out_free_stage2_pgd;
+ cpumask_copy(kvm->arch.supported_cpus, cpu_possible_mask);
+
kvm_vgic_early_init(kvm);
/* The maximum number of VCPUs is limited by the host's GIC model */
@@ -176,6 +176,7 @@ vm_fault_t kvm_arch_vcpu_fault(struct kvm_vcpu *vcpu, struct vm_fault *vmf)
void kvm_arch_destroy_vm(struct kvm *kvm)
{
bitmap_free(kvm->arch.pmu_filter);
+ free_cpumask_var(kvm->arch.supported_cpus);
kvm_vgic_destroy(kvm);
@@ -411,6 +412,9 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
if (vcpu_has_ptrauth(vcpu))
vcpu_ptrauth_disable(vcpu);
kvm_arch_vcpu_load_debug_state_flags(vcpu);
+
+ if (!cpumask_test_cpu(smp_processor_id(), vcpu->kvm->arch.supported_cpus))
+ vcpu_set_on_unsupported_cpu(vcpu);
}
void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)
@@ -422,7 +426,9 @@ void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)
kvm_timer_vcpu_put(vcpu);
kvm_vgic_put(vcpu);
kvm_vcpu_pmu_restore_host(vcpu);
+ kvm_arm_vmid_clear_active();
+ vcpu_clear_on_unsupported_cpu(vcpu);
vcpu->cpu = -1;
}
@@ -489,87 +495,6 @@ unsigned long kvm_arch_vcpu_get_ip(struct kvm_vcpu *vcpu)
}
#endif
-/* Just ensure a guest exit from a particular CPU */
-static void exit_vm_noop(void *info)
-{
-}
-
-void force_vm_exit(const cpumask_t *mask)
-{
- preempt_disable();
- smp_call_function_many(mask, exit_vm_noop, NULL, true);
- preempt_enable();
-}
-
-/**
- * need_new_vmid_gen - check that the VMID is still valid
- * @vmid: The VMID to check
- *
- * return true if there is a new generation of VMIDs being used
- *
- * The hardware supports a limited set of values with the value zero reserved
- * for the host, so we check if an assigned value belongs to a previous
- * generation, which requires us to assign a new value. If we're the first to
- * use a VMID for the new generation, we must flush necessary caches and TLBs
- * on all CPUs.
- */
-static bool need_new_vmid_gen(struct kvm_vmid *vmid)
-{
- u64 current_vmid_gen = atomic64_read(&kvm_vmid_gen);
- smp_rmb(); /* Orders read of kvm_vmid_gen and kvm->arch.vmid */
- return unlikely(READ_ONCE(vmid->vmid_gen) != current_vmid_gen);
-}
-
-/**
- * update_vmid - Update the vmid with a valid VMID for the current generation
- * @vmid: The stage-2 VMID information struct
- */
-static void update_vmid(struct kvm_vmid *vmid)
-{
- if (!need_new_vmid_gen(vmid))
- return;
-
- spin_lock(&kvm_vmid_lock);
-
- /*
- * We need to re-check the vmid_gen here to ensure that if another vcpu
- * already allocated a valid vmid for this vm, then this vcpu should
- * use the same vmid.
- */
- if (!need_new_vmid_gen(vmid)) {
- spin_unlock(&kvm_vmid_lock);
- return;
- }
-
- /* First user of a new VMID generation? */
- if (unlikely(kvm_next_vmid == 0)) {
- atomic64_inc(&kvm_vmid_gen);
- kvm_next_vmid = 1;
-
- /*
- * On SMP we know no other CPUs can use this CPU's or each
- * other's VMID after force_vm_exit returns since the
- * kvm_vmid_lock blocks them from reentry to the guest.
- */
- force_vm_exit(cpu_all_mask);
- /*
- * Now broadcast TLB + ICACHE invalidation over the inner
- * shareable domain to make sure all data structures are
- * clean.
- */
- kvm_call_hyp(__kvm_flush_vm_context);
- }
-
- WRITE_ONCE(vmid->vmid, kvm_next_vmid);
- kvm_next_vmid++;
- kvm_next_vmid &= (1 << kvm_get_vmid_bits()) - 1;
-
- smp_wmb();
- WRITE_ONCE(vmid->vmid_gen, atomic64_read(&kvm_vmid_gen));
-
- spin_unlock(&kvm_vmid_lock);
-}
-
static int kvm_vcpu_initialized(struct kvm_vcpu *vcpu)
{
return vcpu->arch.target >= 0;
@@ -634,6 +559,10 @@ int kvm_arch_vcpu_run_pid_change(struct kvm_vcpu *vcpu)
if (kvm_vm_is_protected(kvm))
kvm_call_hyp_nvhe(__pkvm_vcpu_init_traps, vcpu);
+ mutex_lock(&kvm->lock);
+ set_bit(KVM_ARCH_FLAG_HAS_RAN_ONCE, &kvm->arch.flags);
+ mutex_unlock(&kvm->lock);
+
return ret;
}
@@ -792,11 +721,36 @@ static bool kvm_vcpu_exit_request(struct kvm_vcpu *vcpu, int *ret)
}
}
+ if (unlikely(vcpu_on_unsupported_cpu(vcpu))) {
+ run->exit_reason = KVM_EXIT_FAIL_ENTRY;
+ run->fail_entry.hardware_entry_failure_reason = KVM_EXIT_FAIL_ENTRY_CPU_UNSUPPORTED;
+ run->fail_entry.cpu = smp_processor_id();
+ *ret = 0;
+ return true;
+ }
+
return kvm_request_pending(vcpu) ||
- need_new_vmid_gen(&vcpu->arch.hw_mmu->vmid) ||
xfer_to_guest_mode_work_pending();
}
+/*
+ * Actually run the vCPU, entering an RCU extended quiescent state (EQS) while
+ * the vCPU is running.
+ *
+ * This must be noinstr as instrumentation may make use of RCU, and this is not
+ * safe during the EQS.
+ */
+static int noinstr kvm_arm_vcpu_enter_exit(struct kvm_vcpu *vcpu)
+{
+ int ret;
+
+ guest_state_enter_irqoff();
+ ret = kvm_call_hyp_ret(__kvm_vcpu_run, vcpu);
+ guest_state_exit_irqoff();
+
+ return ret;
+}
+
/**
* kvm_arch_vcpu_ioctl_run - the main VCPU run function to execute guest code
* @vcpu: The VCPU pointer
@@ -837,8 +791,6 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu)
if (!ret)
ret = 1;
- update_vmid(&vcpu->arch.hw_mmu->vmid);
-
check_vcpu_requests(vcpu);
/*
@@ -848,6 +800,15 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu)
*/
preempt_disable();
+ /*
+ * The VMID allocator only tracks active VMIDs per
+ * physical CPU, and therefore the VMID allocated may not be
+ * preserved on VMID roll-over if the task was preempted,
+ * making a thread's VMID inactive. So we need to call
+ * kvm_arm_vmid_update() in non-premptible context.
+ */
+ kvm_arm_vmid_update(&vcpu->arch.hw_mmu->vmid);
+
kvm_pmu_flush_hwstate(vcpu);
local_irq_disable();
@@ -881,9 +842,9 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu)
* Enter the guest
*/
trace_kvm_entry(*vcpu_pc(vcpu));
- guest_enter_irqoff();
+ guest_timing_enter_irqoff();
- ret = kvm_call_hyp_ret(__kvm_vcpu_run, vcpu);
+ ret = kvm_arm_vcpu_enter_exit(vcpu);
vcpu->mode = OUTSIDE_GUEST_MODE;
vcpu->stat.exits++;
@@ -918,26 +879,25 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu)
kvm_arch_vcpu_ctxsync_fp(vcpu);
/*
- * We may have taken a host interrupt in HYP mode (ie
- * while executing the guest). This interrupt is still
- * pending, as we haven't serviced it yet!
+ * We must ensure that any pending interrupts are taken before
+ * we exit guest timing so that timer ticks are accounted as
+ * guest time. Transiently unmask interrupts so that any
+ * pending interrupts are taken.
*
- * We're now back in SVC mode, with interrupts
- * disabled. Enabling the interrupts now will have
- * the effect of taking the interrupt again, in SVC
- * mode this time.
+ * Per ARM DDI 0487G.b section D1.13.4, an ISB (or other
+ * context synchronization event) is necessary to ensure that
+ * pending interrupts are taken.
*/
+ if (ARM_EXCEPTION_CODE(ret) == ARM_EXCEPTION_IRQ) {
+ local_irq_enable();
+ isb();
+ local_irq_disable();
+ }
+
+ guest_timing_exit_irqoff();
+
local_irq_enable();
- /*
- * We do local_irq_enable() before calling guest_exit() so
- * that if a timer interrupt hits while running the guest we
- * account that tick as being spent in the guest. We enable
- * preemption after calling guest_exit() so that if we get
- * preempted we make sure ticks after that is not counted as
- * guest time.
- */
- guest_exit();
trace_kvm_exit(ret, kvm_vcpu_trap_get_class(vcpu), *vcpu_pc(vcpu));
/* Exit types that need handling before we can be preempted */
@@ -1476,10 +1436,7 @@ static int kvm_init_vector_slots(void)
base = kern_hyp_va(kvm_ksym_ref(__bp_harden_hyp_vecs));
kvm_init_vector_slot(base, HYP_VECTOR_SPECTRE_DIRECT);
- if (!cpus_have_const_cap(ARM64_SPECTRE_V3A))
- return 0;
-
- if (!has_vhe()) {
+ if (kvm_system_needs_idmapped_vectors() && !has_vhe()) {
err = create_hyp_exec_mappings(__pa_symbol(__bp_harden_hyp_vecs),
__BP_HARDEN_HYP_VECS_SZ, &base);
if (err)
@@ -1730,7 +1687,7 @@ static void init_cpu_logical_map(void)
/*
* Copy the MPIDR <-> logical CPU ID mapping to hyp.
- * Only copy the set of online CPUs whose features have been chacked
+ * Only copy the set of online CPUs whose features have been checked
* against the finalized system capabilities. The hypervisor will not
* allow any other CPUs from the `possible` set to boot.
*/
@@ -1855,6 +1812,7 @@ static int kvm_hyp_init_protection(u32 hyp_va_bits)
kvm_nvhe_sym(id_aa64pfr1_el1_sys_val) = read_sanitised_ftr_reg(SYS_ID_AA64PFR1_EL1);
kvm_nvhe_sym(id_aa64isar0_el1_sys_val) = read_sanitised_ftr_reg(SYS_ID_AA64ISAR0_EL1);
kvm_nvhe_sym(id_aa64isar1_el1_sys_val) = read_sanitised_ftr_reg(SYS_ID_AA64ISAR1_EL1);
+ kvm_nvhe_sym(id_aa64isar2_el1_sys_val) = read_sanitised_ftr_reg(SYS_ID_AA64ISAR2_EL1);
kvm_nvhe_sym(id_aa64mmfr0_el1_sys_val) = read_sanitised_ftr_reg(SYS_ID_AA64MMFR0_EL1);
kvm_nvhe_sym(id_aa64mmfr1_el1_sys_val) = read_sanitised_ftr_reg(SYS_ID_AA64MMFR1_EL1);
kvm_nvhe_sym(id_aa64mmfr2_el1_sys_val) = read_sanitised_ftr_reg(SYS_ID_AA64MMFR2_EL1);
@@ -2146,6 +2104,12 @@ int kvm_arch_init(void *opaque)
if (err)
return err;
+ err = kvm_arm_vmid_alloc_init();
+ if (err) {
+ kvm_err("Failed to initialize VMID allocator.\n");
+ return err;
+ }
+
if (!in_hyp_mode) {
err = init_hyp_mode();
if (err)
@@ -2185,6 +2149,7 @@ out_hyp:
if (!in_hyp_mode)
teardown_hyp_mode();
out_err:
+ kvm_arm_vmid_alloc_free();
return err;
}
diff --git a/arch/arm64/kvm/debug.c b/arch/arm64/kvm/debug.c
index db9361338b2a..4fd5c216c4bb 100644
--- a/arch/arm64/kvm/debug.c
+++ b/arch/arm64/kvm/debug.c
@@ -105,9 +105,11 @@ static void kvm_arm_setup_mdcr_el2(struct kvm_vcpu *vcpu)
* - Userspace is using the hardware to debug the guest
* (KVM_GUESTDBG_USE_HW is set).
* - The guest is not using debug (KVM_ARM64_DEBUG_DIRTY is clear).
+ * - The guest has enabled the OS Lock (debug exceptions are blocked).
*/
if ((vcpu->guest_debug & KVM_GUESTDBG_USE_HW) ||
- !(vcpu->arch.flags & KVM_ARM64_DEBUG_DIRTY))
+ !(vcpu->arch.flags & KVM_ARM64_DEBUG_DIRTY) ||
+ kvm_vcpu_os_lock_enabled(vcpu))
vcpu->arch.mdcr_el2 |= MDCR_EL2_TDA;
trace_kvm_arm_set_dreg32("MDCR_EL2", vcpu->arch.mdcr_el2);
@@ -160,8 +162,8 @@ void kvm_arm_setup_debug(struct kvm_vcpu *vcpu)
kvm_arm_setup_mdcr_el2(vcpu);
- /* Is Guest debugging in effect? */
- if (vcpu->guest_debug) {
+ /* Check if we need to use the debug registers. */
+ if (vcpu->guest_debug || kvm_vcpu_os_lock_enabled(vcpu)) {
/* Save guest debug state */
save_guest_debug_regs(vcpu);
@@ -223,6 +225,19 @@ void kvm_arm_setup_debug(struct kvm_vcpu *vcpu)
trace_kvm_arm_set_regset("WAPTS", get_num_wrps(),
&vcpu->arch.debug_ptr->dbg_wcr[0],
&vcpu->arch.debug_ptr->dbg_wvr[0]);
+
+ /*
+ * The OS Lock blocks debug exceptions in all ELs when it is
+ * enabled. If the guest has enabled the OS Lock, constrain its
+ * effects to the guest. Emulate the behavior by clearing
+ * MDSCR_EL1.MDE. In so doing, we ensure that host debug
+ * exceptions are unaffected by guest configuration of the OS
+ * Lock.
+ */
+ } else if (kvm_vcpu_os_lock_enabled(vcpu)) {
+ mdscr = vcpu_read_sys_reg(vcpu, MDSCR_EL1);
+ mdscr &= ~DBG_MDSCR_MDE;
+ vcpu_write_sys_reg(vcpu, mdscr, MDSCR_EL1);
}
}
@@ -244,7 +259,10 @@ void kvm_arm_clear_debug(struct kvm_vcpu *vcpu)
{
trace_kvm_arm_clear_debug(vcpu->guest_debug);
- if (vcpu->guest_debug) {
+ /*
+ * Restore the guest's debug registers if we were using them.
+ */
+ if (vcpu->guest_debug || kvm_vcpu_os_lock_enabled(vcpu)) {
restore_guest_debug_regs(vcpu);
/*
diff --git a/arch/arm64/kvm/fpsimd.c b/arch/arm64/kvm/fpsimd.c
index 2f48fd362a8c..397fdac75cb1 100644
--- a/arch/arm64/kvm/fpsimd.c
+++ b/arch/arm64/kvm/fpsimd.c
@@ -84,6 +84,11 @@ void kvm_arch_vcpu_load_fp(struct kvm_vcpu *vcpu)
vcpu->arch.flags |= KVM_ARM64_HOST_SVE_ENABLED;
}
+/*
+ * Called just before entering the guest once we are no longer
+ * preemptable. Syncs the host's TIF_FOREIGN_FPSTATE with the KVM
+ * mirror of the flag used by the hypervisor.
+ */
void kvm_arch_vcpu_ctxflush_fp(struct kvm_vcpu *vcpu)
{
if (test_thread_flag(TIF_FOREIGN_FPSTATE))
@@ -93,10 +98,11 @@ void kvm_arch_vcpu_ctxflush_fp(struct kvm_vcpu *vcpu)
}
/*
- * If the guest FPSIMD state was loaded, update the host's context
- * tracking data mark the CPU FPSIMD regs as dirty and belonging to vcpu
- * so that they will be written back if the kernel clobbers them due to
- * kernel-mode NEON before re-entry into the guest.
+ * Called just after exiting the guest. If the guest FPSIMD state
+ * was loaded, update the host's context tracking data mark the CPU
+ * FPSIMD regs as dirty and belonging to vcpu so that they will be
+ * written back if the kernel clobbers them due to kernel-mode NEON
+ * before re-entry into the guest.
*/
void kvm_arch_vcpu_ctxsync_fp(struct kvm_vcpu *vcpu)
{
diff --git a/arch/arm64/kvm/guest.c b/arch/arm64/kvm/guest.c
index e116c7767730..7e15b03fbdf8 100644
--- a/arch/arm64/kvm/guest.c
+++ b/arch/arm64/kvm/guest.c
@@ -282,7 +282,7 @@ static int set_core_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
break;
/*
- * Otherwide, this is a priviledged mode, and *all* the
+ * Otherwise, this is a privileged mode, and *all* the
* registers must be narrowed to 32bit.
*/
default:
diff --git a/arch/arm64/kvm/handle_exit.c b/arch/arm64/kvm/handle_exit.c
index fd2dd26caf91..97fe14aab1a3 100644
--- a/arch/arm64/kvm/handle_exit.c
+++ b/arch/arm64/kvm/handle_exit.c
@@ -228,6 +228,14 @@ int handle_exit(struct kvm_vcpu *vcpu, int exception_index)
{
struct kvm_run *run = vcpu->run;
+ if (ARM_SERROR_PENDING(exception_index)) {
+ /*
+ * The SError is handled by handle_exit_early(). If the guest
+ * survives it will re-execute the original instruction.
+ */
+ return 1;
+ }
+
exception_index = ARM_EXCEPTION_CODE(exception_index);
switch (exception_index) {
@@ -240,7 +248,7 @@ int handle_exit(struct kvm_vcpu *vcpu, int exception_index)
case ARM_EXCEPTION_HYP_GONE:
/*
* EL2 has been reset to the hyp-stub. This happens when a guest
- * is pre-empted by kvm_reboot()'s shutdown call.
+ * is pre-emptied by kvm_reboot()'s shutdown call.
*/
run->exit_reason = KVM_EXIT_FAIL_ENTRY;
return 0;
diff --git a/arch/arm64/kvm/hyp/exception.c b/arch/arm64/kvm/hyp/exception.c
index 0418399e0a20..c5d009715402 100644
--- a/arch/arm64/kvm/hyp/exception.c
+++ b/arch/arm64/kvm/hyp/exception.c
@@ -38,7 +38,10 @@ static inline void __vcpu_write_sys_reg(struct kvm_vcpu *vcpu, u64 val, int reg)
static void __vcpu_write_spsr(struct kvm_vcpu *vcpu, u64 val)
{
- write_sysreg_el1(val, SYS_SPSR);
+ if (has_vhe())
+ write_sysreg_el1(val, SYS_SPSR);
+ else
+ __vcpu_sys_reg(vcpu, SPSR_EL1) = val;
}
static void __vcpu_write_spsr_abt(struct kvm_vcpu *vcpu, u64 val)
diff --git a/arch/arm64/kvm/hyp/hyp-entry.S b/arch/arm64/kvm/hyp/hyp-entry.S
index b6b6801d96d5..7839d075729b 100644
--- a/arch/arm64/kvm/hyp/hyp-entry.S
+++ b/arch/arm64/kvm/hyp/hyp-entry.S
@@ -62,6 +62,10 @@ el1_sync: // Guest trapped into EL2
/* ARM_SMCCC_ARCH_WORKAROUND_2 handling */
eor w1, w1, #(ARM_SMCCC_ARCH_WORKAROUND_1 ^ \
ARM_SMCCC_ARCH_WORKAROUND_2)
+ cbz w1, wa_epilogue
+
+ eor w1, w1, #(ARM_SMCCC_ARCH_WORKAROUND_2 ^ \
+ ARM_SMCCC_ARCH_WORKAROUND_3)
cbnz w1, el1_trap
wa_epilogue:
@@ -192,7 +196,10 @@ SYM_CODE_END(__kvm_hyp_vector)
sub sp, sp, #(8 * 4)
stp x2, x3, [sp, #(8 * 0)]
stp x0, x1, [sp, #(8 * 2)]
+ alternative_cb spectre_bhb_patch_wa3
+ /* Patched to mov WA3 when supported */
mov w0, #ARM_SMCCC_ARCH_WORKAROUND_1
+ alternative_cb_end
smc #0
ldp x2, x3, [sp, #(8 * 0)]
add sp, sp, #(8 * 2)
@@ -205,6 +212,8 @@ SYM_CODE_END(__kvm_hyp_vector)
spectrev2_smccc_wa1_smc
.else
stp x0, x1, [sp, #-16]!
+ mitigate_spectre_bhb_loop x0
+ mitigate_spectre_bhb_clear_insn
.endif
.if \indirect != 0
alternative_cb kvm_patch_vector_branch
diff --git a/arch/arm64/kvm/hyp/include/hyp/switch.h b/arch/arm64/kvm/hyp/include/hyp/switch.h
index 58e14f8ead23..5d31f6c64c8c 100644
--- a/arch/arm64/kvm/hyp/include/hyp/switch.h
+++ b/arch/arm64/kvm/hyp/include/hyp/switch.h
@@ -173,10 +173,12 @@ static bool kvm_hyp_handle_fpsimd(struct kvm_vcpu *vcpu, u64 *exit_code)
return false;
/* Valid trap. Switch the context: */
+
+ /* First disable enough traps to allow us to update the registers */
if (has_vhe()) {
- reg = CPACR_EL1_FPEN;
+ reg = CPACR_EL1_FPEN_EL0EN | CPACR_EL1_FPEN_EL1EN;
if (sve_guest)
- reg |= CPACR_EL1_ZEN;
+ reg |= CPACR_EL1_ZEN_EL0EN | CPACR_EL1_ZEN_EL1EN;
sysreg_clear_set(cpacr_el1, 0, reg);
} else {
@@ -188,11 +190,13 @@ static bool kvm_hyp_handle_fpsimd(struct kvm_vcpu *vcpu, u64 *exit_code)
}
isb();
+ /* Write out the host state if it's in the registers */
if (vcpu->arch.flags & KVM_ARM64_FP_HOST) {
__fpsimd_save_state(vcpu->arch.host_fpsimd_state);
vcpu->arch.flags &= ~KVM_ARM64_FP_HOST;
}
+ /* Restore the guest state */
if (sve_guest)
__hyp_sve_restore_guest(vcpu);
else
@@ -402,6 +406,24 @@ static inline bool kvm_hyp_handle_exit(struct kvm_vcpu *vcpu, u64 *exit_code)
return false;
}
+static inline void synchronize_vcpu_pstate(struct kvm_vcpu *vcpu, u64 *exit_code)
+{
+ /*
+ * Check for the conditions of Cortex-A510's #2077057. When these occur
+ * SPSR_EL2 can't be trusted, but isn't needed either as it is
+ * unchanged from the value in vcpu_gp_regs(vcpu)->pstate.
+ * Are we single-stepping the guest, and took a PAC exception from the
+ * active-not-pending state?
+ */
+ if (cpus_have_final_cap(ARM64_WORKAROUND_2077057) &&
+ vcpu->guest_debug & KVM_GUESTDBG_SINGLESTEP &&
+ *vcpu_cpsr(vcpu) & DBG_SPSR_SS &&
+ ESR_ELx_EC(read_sysreg_el2(SYS_ESR)) == ESR_ELx_EC_PAC)
+ write_sysreg_el2(*vcpu_cpsr(vcpu), SYS_SPSR);
+
+ vcpu->arch.ctxt.regs.pstate = read_sysreg_el2(SYS_SPSR);
+}
+
/*
* Return true when we were able to fixup the guest exit and should return to
* the guest, false when we should restore the host state and return to the
@@ -413,7 +435,7 @@ static inline bool fixup_guest_exit(struct kvm_vcpu *vcpu, u64 *exit_code)
* Save PSTATE early so that we can evaluate the vcpu mode
* early on.
*/
- vcpu->arch.ctxt.regs.pstate = read_sysreg_el2(SYS_SPSR);
+ synchronize_vcpu_pstate(vcpu, exit_code);
/*
* Check whether we want to repaint the state one way or
@@ -424,7 +446,8 @@ static inline bool fixup_guest_exit(struct kvm_vcpu *vcpu, u64 *exit_code)
if (ARM_EXCEPTION_CODE(*exit_code) != ARM_EXCEPTION_IRQ)
vcpu->arch.fault.esr_el2 = read_sysreg_el2(SYS_ESR);
- if (ARM_SERROR_PENDING(*exit_code)) {
+ if (ARM_SERROR_PENDING(*exit_code) &&
+ ARM_EXCEPTION_CODE(*exit_code) != ARM_EXCEPTION_IRQ) {
u8 esr_ec = kvm_vcpu_trap_get_class(vcpu);
/*
diff --git a/arch/arm64/kvm/hyp/include/nvhe/fixed_config.h b/arch/arm64/kvm/hyp/include/nvhe/fixed_config.h
index eea1f6a53723..5ad626527d41 100644
--- a/arch/arm64/kvm/hyp/include/nvhe/fixed_config.h
+++ b/arch/arm64/kvm/hyp/include/nvhe/fixed_config.h
@@ -192,6 +192,11 @@
ARM64_FEATURE_MASK(ID_AA64ISAR1_I8MM) \
)
+#define PVM_ID_AA64ISAR2_ALLOW (\
+ ARM64_FEATURE_MASK(ID_AA64ISAR2_GPA3) | \
+ ARM64_FEATURE_MASK(ID_AA64ISAR2_APA3) \
+ )
+
u64 pvm_read_id_reg(const struct kvm_vcpu *vcpu, u32 id);
bool kvm_handle_pvm_sysreg(struct kvm_vcpu *vcpu, u64 *exit_code);
bool kvm_handle_pvm_restricted(struct kvm_vcpu *vcpu, u64 *exit_code);
diff --git a/arch/arm64/kvm/hyp/nvhe/Makefile b/arch/arm64/kvm/hyp/nvhe/Makefile
index 24b2c2425b38..f9fe4dc21b1f 100644
--- a/arch/arm64/kvm/hyp/nvhe/Makefile
+++ b/arch/arm64/kvm/hyp/nvhe/Makefile
@@ -13,10 +13,11 @@ lib-objs := clear_page.o copy_page.o memcpy.o memset.o
lib-objs := $(addprefix ../../../lib/, $(lib-objs))
obj-y := timer-sr.o sysreg-sr.o debug-sr.o switch.o tlb.o hyp-init.o host.o \
- hyp-main.o hyp-smp.o psci-relay.o early_alloc.o stub.o page_alloc.o \
+ hyp-main.o hyp-smp.o psci-relay.o early_alloc.o page_alloc.o \
cache.o setup.o mm.o mem_protect.o sys_regs.o pkvm.o
obj-y += ../vgic-v3-sr.o ../aarch32.o ../vgic-v2-cpuif-proxy.o ../entry.o \
../fpsimd.o ../hyp-entry.o ../exception.o ../pgtable.o
+obj-$(CONFIG_DEBUG_LIST) += list_debug.o
obj-y += $(lib-objs)
##
diff --git a/arch/arm64/kvm/hyp/nvhe/cache.S b/arch/arm64/kvm/hyp/nvhe/cache.S
index 958734f4d6b0..0c367eb5f4e2 100644
--- a/arch/arm64/kvm/hyp/nvhe/cache.S
+++ b/arch/arm64/kvm/hyp/nvhe/cache.S
@@ -7,7 +7,8 @@
#include <asm/assembler.h>
#include <asm/alternative.h>
-SYM_FUNC_START_PI(dcache_clean_inval_poc)
+SYM_FUNC_START(__pi_dcache_clean_inval_poc)
dcache_by_line_op civac, sy, x0, x1, x2, x3
ret
-SYM_FUNC_END_PI(dcache_clean_inval_poc)
+SYM_FUNC_END(__pi_dcache_clean_inval_poc)
+SYM_FUNC_ALIAS(dcache_clean_inval_poc, __pi_dcache_clean_inval_poc)
diff --git a/arch/arm64/kvm/hyp/nvhe/list_debug.c b/arch/arm64/kvm/hyp/nvhe/list_debug.c
new file mode 100644
index 000000000000..d68abd7ea124
--- /dev/null
+++ b/arch/arm64/kvm/hyp/nvhe/list_debug.c
@@ -0,0 +1,54 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2022 - Google LLC
+ * Author: Keir Fraser <keirf@google.com>
+ */
+
+#include <linux/list.h>
+#include <linux/bug.h>
+
+static inline __must_check bool nvhe_check_data_corruption(bool v)
+{
+ return v;
+}
+
+#define NVHE_CHECK_DATA_CORRUPTION(condition) \
+ nvhe_check_data_corruption(({ \
+ bool corruption = unlikely(condition); \
+ if (corruption) { \
+ if (IS_ENABLED(CONFIG_BUG_ON_DATA_CORRUPTION)) { \
+ BUG_ON(1); \
+ } else \
+ WARN_ON(1); \
+ } \
+ corruption; \
+ }))
+
+/* The predicates checked here are taken from lib/list_debug.c. */
+
+bool __list_add_valid(struct list_head *new, struct list_head *prev,
+ struct list_head *next)
+{
+ if (NVHE_CHECK_DATA_CORRUPTION(next->prev != prev) ||
+ NVHE_CHECK_DATA_CORRUPTION(prev->next != next) ||
+ NVHE_CHECK_DATA_CORRUPTION(new == prev || new == next))
+ return false;
+
+ return true;
+}
+
+bool __list_del_entry_valid(struct list_head *entry)
+{
+ struct list_head *prev, *next;
+
+ prev = entry->prev;
+ next = entry->next;
+
+ if (NVHE_CHECK_DATA_CORRUPTION(next == LIST_POISON1) ||
+ NVHE_CHECK_DATA_CORRUPTION(prev == LIST_POISON2) ||
+ NVHE_CHECK_DATA_CORRUPTION(prev->next != entry) ||
+ NVHE_CHECK_DATA_CORRUPTION(next->prev != entry))
+ return false;
+
+ return true;
+}
diff --git a/arch/arm64/kvm/hyp/nvhe/mem_protect.c b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
index 674f10564373..78edf077fa3b 100644
--- a/arch/arm64/kvm/hyp/nvhe/mem_protect.c
+++ b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
@@ -138,8 +138,7 @@ int kvm_host_prepare_stage2(void *pgt_pool_base)
mmu->pgd_phys = __hyp_pa(host_kvm.pgt.pgd);
mmu->pgt = &host_kvm.pgt;
- WRITE_ONCE(mmu->vmid.vmid_gen, 0);
- WRITE_ONCE(mmu->vmid.vmid, 0);
+ atomic64_set(&mmu->vmid.id, 0);
return 0;
}
diff --git a/arch/arm64/kvm/hyp/nvhe/mm.c b/arch/arm64/kvm/hyp/nvhe/mm.c
index 526a7d6fa86f..cdbe8e246418 100644
--- a/arch/arm64/kvm/hyp/nvhe/mm.c
+++ b/arch/arm64/kvm/hyp/nvhe/mm.c
@@ -148,8 +148,10 @@ int hyp_map_vectors(void)
phys_addr_t phys;
void *bp_base;
- if (!cpus_have_const_cap(ARM64_SPECTRE_V3A))
+ if (!kvm_system_needs_idmapped_vectors()) {
+ __hyp_bp_vect_base = __bp_harden_hyp_vecs;
return 0;
+ }
phys = __hyp_pa(__bp_harden_hyp_vecs);
bp_base = (void *)__pkvm_create_private_mapping(phys,
diff --git a/arch/arm64/kvm/hyp/nvhe/page_alloc.c b/arch/arm64/kvm/hyp/nvhe/page_alloc.c
index 543cad6c376a..d40f0b30b534 100644
--- a/arch/arm64/kvm/hyp/nvhe/page_alloc.c
+++ b/arch/arm64/kvm/hyp/nvhe/page_alloc.c
@@ -102,7 +102,7 @@ static void __hyp_attach_page(struct hyp_pool *pool,
* Only the first struct hyp_page of a high-order page (otherwise known
* as the 'head') should have p->order set. The non-head pages should
* have p->order = HYP_NO_ORDER. Here @p may no longer be the head
- * after coallescing, so make sure to mark it HYP_NO_ORDER proactively.
+ * after coalescing, so make sure to mark it HYP_NO_ORDER proactively.
*/
p->order = HYP_NO_ORDER;
for (; (order + 1) < pool->max_order; order++) {
@@ -110,7 +110,7 @@ static void __hyp_attach_page(struct hyp_pool *pool,
if (!buddy)
break;
- /* Take the buddy out of its list, and coallesce with @p */
+ /* Take the buddy out of its list, and coalesce with @p */
page_remove_from_list(buddy);
buddy->order = HYP_NO_ORDER;
p = min(p, buddy);
diff --git a/arch/arm64/kvm/hyp/nvhe/stub.c b/arch/arm64/kvm/hyp/nvhe/stub.c
deleted file mode 100644
index c0aa6bbfd79d..000000000000
--- a/arch/arm64/kvm/hyp/nvhe/stub.c
+++ /dev/null
@@ -1,22 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * Stubs for out-of-line function calls caused by re-using kernel
- * infrastructure at EL2.
- *
- * Copyright (C) 2020 - Google LLC
- */
-
-#include <linux/list.h>
-
-#ifdef CONFIG_DEBUG_LIST
-bool __list_add_valid(struct list_head *new, struct list_head *prev,
- struct list_head *next)
-{
- return true;
-}
-
-bool __list_del_entry_valid(struct list_head *entry)
-{
- return true;
-}
-#endif
diff --git a/arch/arm64/kvm/hyp/nvhe/sys_regs.c b/arch/arm64/kvm/hyp/nvhe/sys_regs.c
index 792cf6e6ac92..33f5181af330 100644
--- a/arch/arm64/kvm/hyp/nvhe/sys_regs.c
+++ b/arch/arm64/kvm/hyp/nvhe/sys_regs.c
@@ -22,6 +22,7 @@ u64 id_aa64pfr0_el1_sys_val;
u64 id_aa64pfr1_el1_sys_val;
u64 id_aa64isar0_el1_sys_val;
u64 id_aa64isar1_el1_sys_val;
+u64 id_aa64isar2_el1_sys_val;
u64 id_aa64mmfr0_el1_sys_val;
u64 id_aa64mmfr1_el1_sys_val;
u64 id_aa64mmfr2_el1_sys_val;
@@ -183,6 +184,17 @@ static u64 get_pvm_id_aa64isar1(const struct kvm_vcpu *vcpu)
return id_aa64isar1_el1_sys_val & allow_mask;
}
+static u64 get_pvm_id_aa64isar2(const struct kvm_vcpu *vcpu)
+{
+ u64 allow_mask = PVM_ID_AA64ISAR2_ALLOW;
+
+ if (!vcpu_has_ptrauth(vcpu))
+ allow_mask &= ~(ARM64_FEATURE_MASK(ID_AA64ISAR2_APA3) |
+ ARM64_FEATURE_MASK(ID_AA64ISAR2_GPA3));
+
+ return id_aa64isar2_el1_sys_val & allow_mask;
+}
+
static u64 get_pvm_id_aa64mmfr0(const struct kvm_vcpu *vcpu)
{
u64 set_mask;
@@ -225,6 +237,8 @@ u64 pvm_read_id_reg(const struct kvm_vcpu *vcpu, u32 id)
return get_pvm_id_aa64isar0(vcpu);
case SYS_ID_AA64ISAR1_EL1:
return get_pvm_id_aa64isar1(vcpu);
+ case SYS_ID_AA64ISAR2_EL1:
+ return get_pvm_id_aa64isar2(vcpu);
case SYS_ID_AA64MMFR0_EL1:
return get_pvm_id_aa64mmfr0(vcpu);
case SYS_ID_AA64MMFR1_EL1:
diff --git a/arch/arm64/kvm/hyp/pgtable.c b/arch/arm64/kvm/hyp/pgtable.c
index 844a6f003fd5..2cb3867eb7c2 100644
--- a/arch/arm64/kvm/hyp/pgtable.c
+++ b/arch/arm64/kvm/hyp/pgtable.c
@@ -983,13 +983,9 @@ static int stage2_unmap_walker(u64 addr, u64 end, u32 level, kvm_pte_t *ptep,
*/
stage2_put_pte(ptep, mmu, addr, level, mm_ops);
- if (need_flush) {
- kvm_pte_t *pte_follow = kvm_pte_follow(pte, mm_ops);
-
- dcache_clean_inval_poc((unsigned long)pte_follow,
- (unsigned long)pte_follow +
- kvm_granule_size(level));
- }
+ if (need_flush && mm_ops->dcache_clean_inval_poc)
+ mm_ops->dcache_clean_inval_poc(kvm_pte_follow(pte, mm_ops),
+ kvm_granule_size(level));
if (childp)
mm_ops->put_page(childp);
@@ -1151,15 +1147,13 @@ static int stage2_flush_walker(u64 addr, u64 end, u32 level, kvm_pte_t *ptep,
struct kvm_pgtable *pgt = arg;
struct kvm_pgtable_mm_ops *mm_ops = pgt->mm_ops;
kvm_pte_t pte = *ptep;
- kvm_pte_t *pte_follow;
if (!kvm_pte_valid(pte) || !stage2_pte_cacheable(pgt, pte))
return 0;
- pte_follow = kvm_pte_follow(pte, mm_ops);
- dcache_clean_inval_poc((unsigned long)pte_follow,
- (unsigned long)pte_follow +
- kvm_granule_size(level));
+ if (mm_ops->dcache_clean_inval_poc)
+ mm_ops->dcache_clean_inval_poc(kvm_pte_follow(pte, mm_ops),
+ kvm_granule_size(level));
return 0;
}
diff --git a/arch/arm64/kvm/hyp/vgic-v3-sr.c b/arch/arm64/kvm/hyp/vgic-v3-sr.c
index 20db2f281cf2..4fb419f7b8b6 100644
--- a/arch/arm64/kvm/hyp/vgic-v3-sr.c
+++ b/arch/arm64/kvm/hyp/vgic-v3-sr.c
@@ -983,6 +983,9 @@ static void __vgic_v3_read_ctlr(struct kvm_vcpu *vcpu, u32 vmcr, int rt)
val = ((vtr >> 29) & 7) << ICC_CTLR_EL1_PRI_BITS_SHIFT;
/* IDbits */
val |= ((vtr >> 23) & 7) << ICC_CTLR_EL1_ID_BITS_SHIFT;
+ /* SEIS */
+ if (kvm_vgic_global_state.ich_vtr_el2 & ICH_VTR_SEIS_MASK)
+ val |= BIT(ICC_CTLR_EL1_SEIS_SHIFT);
/* A3V */
val |= ((vtr >> 21) & 1) << ICC_CTLR_EL1_A3V_SHIFT;
/* EOImode */
diff --git a/arch/arm64/kvm/hyp/vhe/switch.c b/arch/arm64/kvm/hyp/vhe/switch.c
index 11d053fdd604..262dfe03134d 100644
--- a/arch/arm64/kvm/hyp/vhe/switch.c
+++ b/arch/arm64/kvm/hyp/vhe/switch.c
@@ -10,6 +10,7 @@
#include <linux/kvm_host.h>
#include <linux/types.h>
#include <linux/jump_label.h>
+#include <linux/percpu.h>
#include <uapi/linux/psci.h>
#include <kvm/arm_psci.h>
@@ -24,6 +25,8 @@
#include <asm/fpsimd.h>
#include <asm/debug-monitors.h>
#include <asm/processor.h>
+#include <asm/thread_info.h>
+#include <asm/vectors.h>
/* VHE specific context */
DEFINE_PER_CPU(struct kvm_host_data, kvm_host_data);
@@ -38,7 +41,7 @@ static void __activate_traps(struct kvm_vcpu *vcpu)
val = read_sysreg(cpacr_el1);
val |= CPACR_EL1_TTA;
- val &= ~CPACR_EL1_ZEN;
+ val &= ~(CPACR_EL1_ZEN_EL0EN | CPACR_EL1_ZEN_EL1EN);
/*
* With VHE (HCR.E2H == 1), accesses to CPACR_EL1 are routed to
@@ -53,9 +56,9 @@ static void __activate_traps(struct kvm_vcpu *vcpu)
if (update_fp_enabled(vcpu)) {
if (vcpu_has_sve(vcpu))
- val |= CPACR_EL1_ZEN;
+ val |= CPACR_EL1_ZEN_EL0EN | CPACR_EL1_ZEN_EL1EN;
} else {
- val &= ~CPACR_EL1_FPEN;
+ val &= ~(CPACR_EL1_FPEN_EL0EN | CPACR_EL1_FPEN_EL1EN);
__activate_traps_fpsimd32(vcpu);
}
@@ -67,7 +70,7 @@ NOKPROBE_SYMBOL(__activate_traps);
static void __deactivate_traps(struct kvm_vcpu *vcpu)
{
- extern char vectors[]; /* kernel exception vectors */
+ const char *host_vectors = vectors;
___deactivate_traps(vcpu);
@@ -81,7 +84,10 @@ static void __deactivate_traps(struct kvm_vcpu *vcpu)
asm(ALTERNATIVE("nop", "isb", ARM64_WORKAROUND_SPECULATIVE_AT));
write_sysreg(CPACR_EL1_DEFAULT, cpacr_el1);
- write_sysreg(vectors, vbar_el1);
+
+ if (!arm64_kernel_unmapped_at_el0())
+ host_vectors = __this_cpu_read(this_cpu_vector);
+ write_sysreg(host_vectors, vbar_el1);
}
NOKPROBE_SYMBOL(__deactivate_traps);
diff --git a/arch/arm64/kvm/hypercalls.c b/arch/arm64/kvm/hypercalls.c
index 30da78f72b3b..202b8c455724 100644
--- a/arch/arm64/kvm/hypercalls.c
+++ b/arch/arm64/kvm/hypercalls.c
@@ -107,6 +107,18 @@ int kvm_hvc_call_handler(struct kvm_vcpu *vcpu)
break;
}
break;
+ case ARM_SMCCC_ARCH_WORKAROUND_3:
+ switch (arm64_get_spectre_bhb_state()) {
+ case SPECTRE_VULNERABLE:
+ break;
+ case SPECTRE_MITIGATED:
+ val[0] = SMCCC_RET_SUCCESS;
+ break;
+ case SPECTRE_UNAFFECTED:
+ val[0] = SMCCC_ARCH_WORKAROUND_RET_UNAFFECTED;
+ break;
+ }
+ break;
case ARM_SMCCC_HV_PV_TIME_FEATURES:
val[0] = SMCCC_RET_SUCCESS;
break;
diff --git a/arch/arm64/kvm/mmio.c b/arch/arm64/kvm/mmio.c
index 3e2d8ba11a02..3dd38a151d2a 100644
--- a/arch/arm64/kvm/mmio.c
+++ b/arch/arm64/kvm/mmio.c
@@ -135,7 +135,8 @@ int io_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa)
* volunteered to do so, and bail out otherwise.
*/
if (!kvm_vcpu_dabt_isvalid(vcpu)) {
- if (vcpu->kvm->arch.return_nisv_io_abort_to_user) {
+ if (test_bit(KVM_ARCH_FLAG_RETURN_NISV_IO_ABORT_TO_USER,
+ &vcpu->kvm->arch.flags)) {
run->exit_reason = KVM_EXIT_ARM_NISV;
run->arm_nisv.esr_iss = kvm_vcpu_dabt_iss_nisv_sanitized(vcpu);
run->arm_nisv.fault_ipa = fault_ipa;
diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c
index bc2aba953299..0d19259454d8 100644
--- a/arch/arm64/kvm/mmu.c
+++ b/arch/arm64/kvm/mmu.c
@@ -58,7 +58,7 @@ static int stage2_apply_range(struct kvm *kvm, phys_addr_t addr,
break;
if (resched && next != end)
- cond_resched_lock(&kvm->mmu_lock);
+ cond_resched_rwlock_write(&kvm->mmu_lock);
} while (addr = next, addr != end);
return ret;
@@ -179,7 +179,7 @@ static void __unmap_stage2_range(struct kvm_s2_mmu *mmu, phys_addr_t start, u64
struct kvm *kvm = kvm_s2_mmu_to_kvm(mmu);
phys_addr_t end = start + size;
- assert_spin_locked(&kvm->mmu_lock);
+ lockdep_assert_held_write(&kvm->mmu_lock);
WARN_ON(size & ~PAGE_MASK);
WARN_ON(stage2_apply_range(kvm, start, end, kvm_pgtable_stage2_unmap,
may_block));
@@ -213,13 +213,13 @@ static void stage2_flush_vm(struct kvm *kvm)
int idx, bkt;
idx = srcu_read_lock(&kvm->srcu);
- spin_lock(&kvm->mmu_lock);
+ write_lock(&kvm->mmu_lock);
slots = kvm_memslots(kvm);
kvm_for_each_memslot(memslot, bkt, slots)
stage2_flush_memslot(kvm, memslot);
- spin_unlock(&kvm->mmu_lock);
+ write_unlock(&kvm->mmu_lock);
srcu_read_unlock(&kvm->srcu, idx);
}
@@ -615,7 +615,7 @@ static struct kvm_pgtable_mm_ops kvm_s2_mm_ops = {
};
/**
- * kvm_init_stage2_mmu - Initialise a S2 MMU strucrure
+ * kvm_init_stage2_mmu - Initialise a S2 MMU structure
* @kvm: The pointer to the KVM structure
* @mmu: The pointer to the s2 MMU structure
*
@@ -653,7 +653,6 @@ int kvm_init_stage2_mmu(struct kvm *kvm, struct kvm_s2_mmu *mmu)
mmu->pgt = pgt;
mmu->pgd_phys = __pa(pgt->pgd);
- WRITE_ONCE(mmu->vmid.vmid_gen, 0);
return 0;
out_destroy_pgtable:
@@ -720,13 +719,13 @@ void stage2_unmap_vm(struct kvm *kvm)
idx = srcu_read_lock(&kvm->srcu);
mmap_read_lock(current->mm);
- spin_lock(&kvm->mmu_lock);
+ write_lock(&kvm->mmu_lock);
slots = kvm_memslots(kvm);
kvm_for_each_memslot(memslot, bkt, slots)
stage2_unmap_memslot(kvm, memslot);
- spin_unlock(&kvm->mmu_lock);
+ write_unlock(&kvm->mmu_lock);
mmap_read_unlock(current->mm);
srcu_read_unlock(&kvm->srcu, idx);
}
@@ -736,14 +735,14 @@ void kvm_free_stage2_pgd(struct kvm_s2_mmu *mmu)
struct kvm *kvm = kvm_s2_mmu_to_kvm(mmu);
struct kvm_pgtable *pgt = NULL;
- spin_lock(&kvm->mmu_lock);
+ write_lock(&kvm->mmu_lock);
pgt = mmu->pgt;
if (pgt) {
mmu->pgd_phys = 0;
mmu->pgt = NULL;
free_percpu(mmu->last_vcpu_ran);
}
- spin_unlock(&kvm->mmu_lock);
+ write_unlock(&kvm->mmu_lock);
if (pgt) {
kvm_pgtable_stage2_destroy(pgt);
@@ -783,10 +782,10 @@ int kvm_phys_addr_ioremap(struct kvm *kvm, phys_addr_t guest_ipa,
if (ret)
break;
- spin_lock(&kvm->mmu_lock);
+ write_lock(&kvm->mmu_lock);
ret = kvm_pgtable_stage2_map(pgt, addr, PAGE_SIZE, pa, prot,
&cache);
- spin_unlock(&kvm->mmu_lock);
+ write_unlock(&kvm->mmu_lock);
if (ret)
break;
@@ -834,9 +833,9 @@ static void kvm_mmu_wp_memory_region(struct kvm *kvm, int slot)
start = memslot->base_gfn << PAGE_SHIFT;
end = (memslot->base_gfn + memslot->npages) << PAGE_SHIFT;
- spin_lock(&kvm->mmu_lock);
+ write_lock(&kvm->mmu_lock);
stage2_wp_range(&kvm->arch.mmu, start, end);
- spin_unlock(&kvm->mmu_lock);
+ write_unlock(&kvm->mmu_lock);
kvm_flush_remote_tlbs(kvm);
}
@@ -1080,6 +1079,7 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
gfn_t gfn;
kvm_pfn_t pfn;
bool logging_active = memslot_is_logging(memslot);
+ bool logging_perm_fault = false;
unsigned long fault_level = kvm_vcpu_trap_get_fault_level(vcpu);
unsigned long vma_pagesize, fault_granule;
enum kvm_pgtable_prot prot = KVM_PGTABLE_PROT_R;
@@ -1114,6 +1114,7 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
if (logging_active) {
force_pte = true;
vma_shift = PAGE_SHIFT;
+ logging_perm_fault = (fault_status == FSC_PERM && write_fault);
} else {
vma_shift = get_vma_page_shift(vma, hva);
}
@@ -1212,7 +1213,15 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
if (exec_fault && device)
return -ENOEXEC;
- spin_lock(&kvm->mmu_lock);
+ /*
+ * To reduce MMU contentions and enhance concurrency during dirty
+ * logging dirty logging, only acquire read lock for permission
+ * relaxation.
+ */
+ if (logging_perm_fault)
+ read_lock(&kvm->mmu_lock);
+ else
+ write_lock(&kvm->mmu_lock);
pgt = vcpu->arch.hw_mmu->pgt;
if (mmu_notifier_retry(kvm, mmu_seq))
goto out_unlock;
@@ -1271,7 +1280,10 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
}
out_unlock:
- spin_unlock(&kvm->mmu_lock);
+ if (logging_perm_fault)
+ read_unlock(&kvm->mmu_lock);
+ else
+ write_unlock(&kvm->mmu_lock);
kvm_set_pfn_accessed(pfn);
kvm_release_pfn_clean(pfn);
return ret != -EAGAIN ? ret : 0;
@@ -1286,10 +1298,10 @@ static void handle_access_fault(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa)
trace_kvm_access_fault(fault_ipa);
- spin_lock(&vcpu->kvm->mmu_lock);
+ write_lock(&vcpu->kvm->mmu_lock);
mmu = vcpu->arch.hw_mmu;
kpte = kvm_pgtable_stage2_mkyoung(mmu->pgt, fault_ipa);
- spin_unlock(&vcpu->kvm->mmu_lock);
+ write_unlock(&vcpu->kvm->mmu_lock);
pte = __pte(kpte);
if (pte_valid(pte))
@@ -1692,9 +1704,9 @@ void kvm_arch_flush_shadow_memslot(struct kvm *kvm,
gpa_t gpa = slot->base_gfn << PAGE_SHIFT;
phys_addr_t size = slot->npages << PAGE_SHIFT;
- spin_lock(&kvm->mmu_lock);
+ write_lock(&kvm->mmu_lock);
unmap_stage2_range(&kvm->arch.mmu, gpa, size);
- spin_unlock(&kvm->mmu_lock);
+ write_unlock(&kvm->mmu_lock);
}
/*
diff --git a/arch/arm64/kvm/pmu-emul.c b/arch/arm64/kvm/pmu-emul.c
index fbcfd4ec6f92..78fdc443adc7 100644
--- a/arch/arm64/kvm/pmu-emul.c
+++ b/arch/arm64/kvm/pmu-emul.c
@@ -7,6 +7,7 @@
#include <linux/cpu.h>
#include <linux/kvm.h>
#include <linux/kvm_host.h>
+#include <linux/list.h>
#include <linux/perf_event.h>
#include <linux/perf/arm_pmu.h>
#include <linux/uaccess.h>
@@ -16,6 +17,9 @@
DEFINE_STATIC_KEY_FALSE(kvm_arm_pmu_available);
+static LIST_HEAD(arm_pmus);
+static DEFINE_MUTEX(arm_pmus_lock);
+
static void kvm_pmu_create_perf_event(struct kvm_vcpu *vcpu, u64 select_idx);
static void kvm_pmu_update_pmc_chained(struct kvm_vcpu *vcpu, u64 select_idx);
static void kvm_pmu_stop_counter(struct kvm_vcpu *vcpu, struct kvm_pmc *pmc);
@@ -24,7 +28,11 @@ static void kvm_pmu_stop_counter(struct kvm_vcpu *vcpu, struct kvm_pmc *pmc);
static u32 kvm_pmu_event_mask(struct kvm *kvm)
{
- switch (kvm->arch.pmuver) {
+ unsigned int pmuver;
+
+ pmuver = kvm->arch.arm_pmu->pmuver;
+
+ switch (pmuver) {
case ID_AA64DFR0_PMUVER_8_0:
return GENMASK(9, 0);
case ID_AA64DFR0_PMUVER_8_1:
@@ -33,7 +41,7 @@ static u32 kvm_pmu_event_mask(struct kvm *kvm)
case ID_AA64DFR0_PMUVER_8_7:
return GENMASK(15, 0);
default: /* Shouldn't be here, just for sanity */
- WARN_ONCE(1, "Unknown PMU version %d\n", kvm->arch.pmuver);
+ WARN_ONCE(1, "Unknown PMU version %d\n", pmuver);
return 0;
}
}
@@ -600,6 +608,7 @@ static bool kvm_pmu_counter_is_enabled(struct kvm_vcpu *vcpu, u64 select_idx)
*/
static void kvm_pmu_create_perf_event(struct kvm_vcpu *vcpu, u64 select_idx)
{
+ struct arm_pmu *arm_pmu = vcpu->kvm->arch.arm_pmu;
struct kvm_pmu *pmu = &vcpu->arch.pmu;
struct kvm_pmc *pmc;
struct perf_event *event;
@@ -636,7 +645,7 @@ static void kvm_pmu_create_perf_event(struct kvm_vcpu *vcpu, u64 select_idx)
return;
memset(&attr, 0, sizeof(struct perf_event_attr));
- attr.type = PERF_TYPE_RAW;
+ attr.type = arm_pmu->pmu.type;
attr.size = sizeof(attr);
attr.pinned = 1;
attr.disabled = !kvm_pmu_counter_is_enabled(vcpu, pmc->idx);
@@ -745,17 +754,33 @@ void kvm_pmu_set_counter_event_type(struct kvm_vcpu *vcpu, u64 data,
void kvm_host_pmu_init(struct arm_pmu *pmu)
{
- if (pmu->pmuver != 0 && pmu->pmuver != ID_AA64DFR0_PMUVER_IMP_DEF &&
- !kvm_arm_support_pmu_v3() && !is_protected_kvm_enabled())
+ struct arm_pmu_entry *entry;
+
+ if (pmu->pmuver == 0 || pmu->pmuver == ID_AA64DFR0_PMUVER_IMP_DEF ||
+ is_protected_kvm_enabled())
+ return;
+
+ mutex_lock(&arm_pmus_lock);
+
+ entry = kmalloc(sizeof(*entry), GFP_KERNEL);
+ if (!entry)
+ goto out_unlock;
+
+ entry->arm_pmu = pmu;
+ list_add_tail(&entry->entry, &arm_pmus);
+
+ if (list_is_singular(&arm_pmus))
static_branch_enable(&kvm_arm_pmu_available);
+
+out_unlock:
+ mutex_unlock(&arm_pmus_lock);
}
-static int kvm_pmu_probe_pmuver(void)
+static struct arm_pmu *kvm_pmu_probe_armpmu(void)
{
struct perf_event_attr attr = { };
struct perf_event *event;
- struct arm_pmu *pmu;
- int pmuver = ID_AA64DFR0_PMUVER_IMP_DEF;
+ struct arm_pmu *pmu = NULL;
/*
* Create a dummy event that only counts user cycles. As we'll never
@@ -780,19 +805,20 @@ static int kvm_pmu_probe_pmuver(void)
if (IS_ERR(event)) {
pr_err_once("kvm: pmu event creation failed %ld\n",
PTR_ERR(event));
- return ID_AA64DFR0_PMUVER_IMP_DEF;
+ return NULL;
}
if (event->pmu) {
pmu = to_arm_pmu(event->pmu);
- if (pmu->pmuver)
- pmuver = pmu->pmuver;
+ if (pmu->pmuver == 0 ||
+ pmu->pmuver == ID_AA64DFR0_PMUVER_IMP_DEF)
+ pmu = NULL;
}
perf_event_disable(event);
perf_event_release_kernel(event);
- return pmuver;
+ return pmu;
}
u64 kvm_pmu_get_pmceid(struct kvm_vcpu *vcpu, bool pmceid1)
@@ -810,7 +836,7 @@ u64 kvm_pmu_get_pmceid(struct kvm_vcpu *vcpu, bool pmceid1)
* Don't advertise STALL_SLOT, as PMMIR_EL0 is handled
* as RAZ
*/
- if (vcpu->kvm->arch.pmuver >= ID_AA64DFR0_PMUVER_8_4)
+ if (vcpu->kvm->arch.arm_pmu->pmuver >= ID_AA64DFR0_PMUVER_8_4)
val &= ~BIT_ULL(ARMV8_PMUV3_PERFCTR_STALL_SLOT - 32);
base = 32;
}
@@ -922,26 +948,64 @@ static bool pmu_irq_is_valid(struct kvm *kvm, int irq)
return true;
}
+static int kvm_arm_pmu_v3_set_pmu(struct kvm_vcpu *vcpu, int pmu_id)
+{
+ struct kvm *kvm = vcpu->kvm;
+ struct arm_pmu_entry *entry;
+ struct arm_pmu *arm_pmu;
+ int ret = -ENXIO;
+
+ mutex_lock(&kvm->lock);
+ mutex_lock(&arm_pmus_lock);
+
+ list_for_each_entry(entry, &arm_pmus, entry) {
+ arm_pmu = entry->arm_pmu;
+ if (arm_pmu->pmu.type == pmu_id) {
+ if (test_bit(KVM_ARCH_FLAG_HAS_RAN_ONCE, &kvm->arch.flags) ||
+ (kvm->arch.pmu_filter && kvm->arch.arm_pmu != arm_pmu)) {
+ ret = -EBUSY;
+ break;
+ }
+
+ kvm->arch.arm_pmu = arm_pmu;
+ cpumask_copy(kvm->arch.supported_cpus, &arm_pmu->supported_cpus);
+ ret = 0;
+ break;
+ }
+ }
+
+ mutex_unlock(&arm_pmus_lock);
+ mutex_unlock(&kvm->lock);
+ return ret;
+}
+
int kvm_arm_pmu_v3_set_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr)
{
+ struct kvm *kvm = vcpu->kvm;
+
if (!kvm_vcpu_has_pmu(vcpu))
return -ENODEV;
if (vcpu->arch.pmu.created)
return -EBUSY;
- if (!vcpu->kvm->arch.pmuver)
- vcpu->kvm->arch.pmuver = kvm_pmu_probe_pmuver();
-
- if (vcpu->kvm->arch.pmuver == ID_AA64DFR0_PMUVER_IMP_DEF)
- return -ENODEV;
+ mutex_lock(&kvm->lock);
+ if (!kvm->arch.arm_pmu) {
+ /* No PMU set, get the default one */
+ kvm->arch.arm_pmu = kvm_pmu_probe_armpmu();
+ if (!kvm->arch.arm_pmu) {
+ mutex_unlock(&kvm->lock);
+ return -ENODEV;
+ }
+ }
+ mutex_unlock(&kvm->lock);
switch (attr->attr) {
case KVM_ARM_VCPU_PMU_V3_IRQ: {
int __user *uaddr = (int __user *)(long)attr->addr;
int irq;
- if (!irqchip_in_kernel(vcpu->kvm))
+ if (!irqchip_in_kernel(kvm))
return -EINVAL;
if (get_user(irq, uaddr))
@@ -951,7 +1015,7 @@ int kvm_arm_pmu_v3_set_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr)
if (!(irq_is_ppi(irq) || irq_is_spi(irq)))
return -EINVAL;
- if (!pmu_irq_is_valid(vcpu->kvm, irq))
+ if (!pmu_irq_is_valid(kvm, irq))
return -EINVAL;
if (kvm_arm_pmu_irq_initialized(vcpu))
@@ -966,7 +1030,7 @@ int kvm_arm_pmu_v3_set_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr)
struct kvm_pmu_event_filter filter;
int nr_events;
- nr_events = kvm_pmu_event_mask(vcpu->kvm) + 1;
+ nr_events = kvm_pmu_event_mask(kvm) + 1;
uaddr = (struct kvm_pmu_event_filter __user *)(long)attr->addr;
@@ -978,12 +1042,17 @@ int kvm_arm_pmu_v3_set_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr)
filter.action != KVM_PMU_EVENT_DENY))
return -EINVAL;
- mutex_lock(&vcpu->kvm->lock);
+ mutex_lock(&kvm->lock);
- if (!vcpu->kvm->arch.pmu_filter) {
- vcpu->kvm->arch.pmu_filter = bitmap_alloc(nr_events, GFP_KERNEL_ACCOUNT);
- if (!vcpu->kvm->arch.pmu_filter) {
- mutex_unlock(&vcpu->kvm->lock);
+ if (test_bit(KVM_ARCH_FLAG_HAS_RAN_ONCE, &kvm->arch.flags)) {
+ mutex_unlock(&kvm->lock);
+ return -EBUSY;
+ }
+
+ if (!kvm->arch.pmu_filter) {
+ kvm->arch.pmu_filter = bitmap_alloc(nr_events, GFP_KERNEL_ACCOUNT);
+ if (!kvm->arch.pmu_filter) {
+ mutex_unlock(&kvm->lock);
return -ENOMEM;
}
@@ -994,20 +1063,29 @@ int kvm_arm_pmu_v3_set_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr)
* events, the default is to allow.
*/
if (filter.action == KVM_PMU_EVENT_ALLOW)
- bitmap_zero(vcpu->kvm->arch.pmu_filter, nr_events);
+ bitmap_zero(kvm->arch.pmu_filter, nr_events);
else
- bitmap_fill(vcpu->kvm->arch.pmu_filter, nr_events);
+ bitmap_fill(kvm->arch.pmu_filter, nr_events);
}
if (filter.action == KVM_PMU_EVENT_ALLOW)
- bitmap_set(vcpu->kvm->arch.pmu_filter, filter.base_event, filter.nevents);
+ bitmap_set(kvm->arch.pmu_filter, filter.base_event, filter.nevents);
else
- bitmap_clear(vcpu->kvm->arch.pmu_filter, filter.base_event, filter.nevents);
+ bitmap_clear(kvm->arch.pmu_filter, filter.base_event, filter.nevents);
- mutex_unlock(&vcpu->kvm->lock);
+ mutex_unlock(&kvm->lock);
return 0;
}
+ case KVM_ARM_VCPU_PMU_V3_SET_PMU: {
+ int __user *uaddr = (int __user *)(long)attr->addr;
+ int pmu_id;
+
+ if (get_user(pmu_id, uaddr))
+ return -EFAULT;
+
+ return kvm_arm_pmu_v3_set_pmu(vcpu, pmu_id);
+ }
case KVM_ARM_VCPU_PMU_V3_INIT:
return kvm_arm_pmu_v3_init(vcpu);
}
@@ -1045,6 +1123,7 @@ int kvm_arm_pmu_v3_has_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr)
case KVM_ARM_VCPU_PMU_V3_IRQ:
case KVM_ARM_VCPU_PMU_V3_INIT:
case KVM_ARM_VCPU_PMU_V3_FILTER:
+ case KVM_ARM_VCPU_PMU_V3_SET_PMU:
if (kvm_vcpu_has_pmu(vcpu))
return 0;
}
diff --git a/arch/arm64/kvm/psci.c b/arch/arm64/kvm/psci.c
index 3eae32876897..372da09a2fab 100644
--- a/arch/arm64/kvm/psci.c
+++ b/arch/arm64/kvm/psci.c
@@ -46,8 +46,7 @@ static unsigned long kvm_psci_vcpu_suspend(struct kvm_vcpu *vcpu)
* specification (ARM DEN 0022A). This means all suspend states
* for KVM will preserve the register state.
*/
- kvm_vcpu_halt(vcpu);
- kvm_clear_request(KVM_REQ_UNHALT, vcpu);
+ kvm_vcpu_wfi(vcpu);
return PSCI_RET_SUCCESS;
}
@@ -85,7 +84,7 @@ static unsigned long kvm_psci_vcpu_on(struct kvm_vcpu *source_vcpu)
if (!vcpu)
return PSCI_RET_INVALID_PARAMS;
if (!vcpu->arch.power_off) {
- if (kvm_psci_version(source_vcpu, kvm) != KVM_ARM_PSCI_0_1)
+ if (kvm_psci_version(source_vcpu) != KVM_ARM_PSCI_0_1)
return PSCI_RET_ALREADY_ON;
else
return PSCI_RET_INVALID_PARAMS;
@@ -162,7 +161,7 @@ static unsigned long kvm_psci_vcpu_affinity_info(struct kvm_vcpu *vcpu)
return PSCI_0_2_AFFINITY_LEVEL_OFF;
}
-static void kvm_prepare_system_event(struct kvm_vcpu *vcpu, u32 type)
+static void kvm_prepare_system_event(struct kvm_vcpu *vcpu, u32 type, u64 flags)
{
unsigned long i;
struct kvm_vcpu *tmp;
@@ -182,17 +181,24 @@ static void kvm_prepare_system_event(struct kvm_vcpu *vcpu, u32 type)
memset(&vcpu->run->system_event, 0, sizeof(vcpu->run->system_event));
vcpu->run->system_event.type = type;
+ vcpu->run->system_event.flags = flags;
vcpu->run->exit_reason = KVM_EXIT_SYSTEM_EVENT;
}
static void kvm_psci_system_off(struct kvm_vcpu *vcpu)
{
- kvm_prepare_system_event(vcpu, KVM_SYSTEM_EVENT_SHUTDOWN);
+ kvm_prepare_system_event(vcpu, KVM_SYSTEM_EVENT_SHUTDOWN, 0);
}
static void kvm_psci_system_reset(struct kvm_vcpu *vcpu)
{
- kvm_prepare_system_event(vcpu, KVM_SYSTEM_EVENT_RESET);
+ kvm_prepare_system_event(vcpu, KVM_SYSTEM_EVENT_RESET, 0);
+}
+
+static void kvm_psci_system_reset2(struct kvm_vcpu *vcpu)
+{
+ kvm_prepare_system_event(vcpu, KVM_SYSTEM_EVENT_RESET,
+ KVM_SYSTEM_EVENT_RESET_FLAG_PSCI_RESET2);
}
static void kvm_psci_narrow_to_32bit(struct kvm_vcpu *vcpu)
@@ -305,24 +311,27 @@ out:
return ret;
}
-static int kvm_psci_1_0_call(struct kvm_vcpu *vcpu)
+static int kvm_psci_1_x_call(struct kvm_vcpu *vcpu, u32 minor)
{
u32 psci_fn = smccc_get_function(vcpu);
- u32 feature;
+ u32 arg;
unsigned long val;
int ret = 1;
+ if (minor > 1)
+ return -EINVAL;
+
switch(psci_fn) {
case PSCI_0_2_FN_PSCI_VERSION:
- val = KVM_ARM_PSCI_1_0;
+ val = minor == 0 ? KVM_ARM_PSCI_1_0 : KVM_ARM_PSCI_1_1;
break;
case PSCI_1_0_FN_PSCI_FEATURES:
- feature = smccc_get_arg1(vcpu);
- val = kvm_psci_check_allowed_function(vcpu, feature);
+ arg = smccc_get_arg1(vcpu);
+ val = kvm_psci_check_allowed_function(vcpu, arg);
if (val)
break;
- switch(feature) {
+ switch(arg) {
case PSCI_0_2_FN_PSCI_VERSION:
case PSCI_0_2_FN_CPU_SUSPEND:
case PSCI_0_2_FN64_CPU_SUSPEND:
@@ -338,11 +347,36 @@ static int kvm_psci_1_0_call(struct kvm_vcpu *vcpu)
case ARM_SMCCC_VERSION_FUNC_ID:
val = 0;
break;
+ case PSCI_1_1_FN_SYSTEM_RESET2:
+ case PSCI_1_1_FN64_SYSTEM_RESET2:
+ if (minor >= 1) {
+ val = 0;
+ break;
+ }
+ fallthrough;
default:
val = PSCI_RET_NOT_SUPPORTED;
break;
}
break;
+ case PSCI_1_1_FN_SYSTEM_RESET2:
+ kvm_psci_narrow_to_32bit(vcpu);
+ fallthrough;
+ case PSCI_1_1_FN64_SYSTEM_RESET2:
+ if (minor >= 1) {
+ arg = smccc_get_arg1(vcpu);
+
+ if (arg <= PSCI_1_1_RESET_TYPE_SYSTEM_WARM_RESET ||
+ arg >= PSCI_1_1_RESET_TYPE_VENDOR_START) {
+ kvm_psci_system_reset2(vcpu);
+ vcpu_set_reg(vcpu, 0, PSCI_RET_INTERNAL_FAILURE);
+ return 0;
+ }
+
+ val = PSCI_RET_INVALID_PARAMS;
+ break;
+ }
+ fallthrough;
default:
return kvm_psci_0_2_call(vcpu);
}
@@ -392,21 +426,23 @@ static int kvm_psci_0_1_call(struct kvm_vcpu *vcpu)
*/
int kvm_psci_call(struct kvm_vcpu *vcpu)
{
- switch (kvm_psci_version(vcpu, vcpu->kvm)) {
+ switch (kvm_psci_version(vcpu)) {
+ case KVM_ARM_PSCI_1_1:
+ return kvm_psci_1_x_call(vcpu, 1);
case KVM_ARM_PSCI_1_0:
- return kvm_psci_1_0_call(vcpu);
+ return kvm_psci_1_x_call(vcpu, 0);
case KVM_ARM_PSCI_0_2:
return kvm_psci_0_2_call(vcpu);
case KVM_ARM_PSCI_0_1:
return kvm_psci_0_1_call(vcpu);
default:
return -EINVAL;
- };
+ }
}
int kvm_arm_get_fw_num_regs(struct kvm_vcpu *vcpu)
{
- return 3; /* PSCI version and two workaround registers */
+ return 4; /* PSCI version and three workaround registers */
}
int kvm_arm_copy_fw_reg_indices(struct kvm_vcpu *vcpu, u64 __user *uindices)
@@ -420,6 +456,9 @@ int kvm_arm_copy_fw_reg_indices(struct kvm_vcpu *vcpu, u64 __user *uindices)
if (put_user(KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2, uindices++))
return -EFAULT;
+ if (put_user(KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_3, uindices++))
+ return -EFAULT;
+
return 0;
}
@@ -459,6 +498,17 @@ static int get_kernel_wa_level(u64 regid)
case SPECTRE_VULNERABLE:
return KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_NOT_AVAIL;
}
+ break;
+ case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_3:
+ switch (arm64_get_spectre_bhb_state()) {
+ case SPECTRE_VULNERABLE:
+ return KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_3_NOT_AVAIL;
+ case SPECTRE_MITIGATED:
+ return KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_3_AVAIL;
+ case SPECTRE_UNAFFECTED:
+ return KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_3_NOT_REQUIRED;
+ }
+ return KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_3_NOT_AVAIL;
}
return -EINVAL;
@@ -471,10 +521,11 @@ int kvm_arm_get_fw_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
switch (reg->id) {
case KVM_REG_ARM_PSCI_VERSION:
- val = kvm_psci_version(vcpu, vcpu->kvm);
+ val = kvm_psci_version(vcpu);
break;
case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_1:
case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2:
+ case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_3:
val = get_kernel_wa_level(reg->id) & KVM_REG_FEATURE_LEVEL_MASK;
break;
default:
@@ -511,6 +562,7 @@ int kvm_arm_set_fw_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
return 0;
case KVM_ARM_PSCI_0_2:
case KVM_ARM_PSCI_1_0:
+ case KVM_ARM_PSCI_1_1:
if (!wants_02)
return -EINVAL;
vcpu->kvm->arch.psci_version = val;
@@ -520,6 +572,7 @@ int kvm_arm_set_fw_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
}
case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_1:
+ case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_3:
if (val & ~KVM_REG_FEATURE_LEVEL_MASK)
return -EINVAL;
diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index 4dc2fba316ff..7b45c040cc27 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -44,6 +44,10 @@
* 64bit interface.
*/
+static int reg_from_user(u64 *val, const void __user *uaddr, u64 id);
+static int reg_to_user(void __user *uaddr, const u64 *val, u64 id);
+static u64 sys_reg_to_index(const struct sys_reg_desc *reg);
+
static bool read_from_write_only(struct kvm_vcpu *vcpu,
struct sys_reg_params *params,
const struct sys_reg_desc *r)
@@ -287,16 +291,55 @@ static bool trap_loregion(struct kvm_vcpu *vcpu,
return trap_raz_wi(vcpu, p, r);
}
+static bool trap_oslar_el1(struct kvm_vcpu *vcpu,
+ struct sys_reg_params *p,
+ const struct sys_reg_desc *r)
+{
+ u64 oslsr;
+
+ if (!p->is_write)
+ return read_from_write_only(vcpu, p, r);
+
+ /* Forward the OSLK bit to OSLSR */
+ oslsr = __vcpu_sys_reg(vcpu, OSLSR_EL1) & ~SYS_OSLSR_OSLK;
+ if (p->regval & SYS_OSLAR_OSLK)
+ oslsr |= SYS_OSLSR_OSLK;
+
+ __vcpu_sys_reg(vcpu, OSLSR_EL1) = oslsr;
+ return true;
+}
+
static bool trap_oslsr_el1(struct kvm_vcpu *vcpu,
struct sys_reg_params *p,
const struct sys_reg_desc *r)
{
- if (p->is_write) {
- return ignore_write(vcpu, p);
- } else {
- p->regval = (1 << 3);
- return true;
- }
+ if (p->is_write)
+ return write_to_read_only(vcpu, p, r);
+
+ p->regval = __vcpu_sys_reg(vcpu, r->reg);
+ return true;
+}
+
+static int set_oslsr_el1(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd,
+ const struct kvm_one_reg *reg, void __user *uaddr)
+{
+ u64 id = sys_reg_to_index(rd);
+ u64 val;
+ int err;
+
+ err = reg_from_user(&val, uaddr, id);
+ if (err)
+ return err;
+
+ /*
+ * The only modifiable bit is the OSLK bit. Refuse the write if
+ * userspace attempts to change any other bit in the register.
+ */
+ if ((val ^ rd->val) & ~SYS_OSLSR_OSLK)
+ return -EINVAL;
+
+ __vcpu_sys_reg(vcpu, rd->reg) = val;
+ return 0;
}
static bool trap_dbgauthstatus_el1(struct kvm_vcpu *vcpu,
@@ -1097,6 +1140,11 @@ static u64 read_id_reg(const struct kvm_vcpu *vcpu,
ARM64_FEATURE_MASK(ID_AA64ISAR1_GPA) |
ARM64_FEATURE_MASK(ID_AA64ISAR1_GPI));
break;
+ case SYS_ID_AA64ISAR2_EL1:
+ if (!vcpu_has_ptrauth(vcpu))
+ val &= ~(ARM64_FEATURE_MASK(ID_AA64ISAR2_APA3) |
+ ARM64_FEATURE_MASK(ID_AA64ISAR2_GPA3));
+ break;
case SYS_ID_AA64DFR0_EL1:
/* Limit debug to ARMv8.0 */
val &= ~ARM64_FEATURE_MASK(ID_AA64DFR0_DEBUGVER);
@@ -1164,10 +1212,6 @@ static bool access_raz_id_reg(struct kvm_vcpu *vcpu,
return __access_id_reg(vcpu, p, r, true);
}
-static int reg_from_user(u64 *val, const void __user *uaddr, u64 id);
-static int reg_to_user(void __user *uaddr, const u64 *val, u64 id);
-static u64 sys_reg_to_index(const struct sys_reg_desc *reg);
-
/* Visibility overrides for SVE-specific control registers */
static unsigned int sve_visibility(const struct kvm_vcpu *vcpu,
const struct sys_reg_desc *rd)
@@ -1418,9 +1462,9 @@ static unsigned int mte_visibility(const struct kvm_vcpu *vcpu,
* Debug handling: We do trap most, if not all debug related system
* registers. The implementation is good enough to ensure that a guest
* can use these with minimal performance degradation. The drawback is
- * that we don't implement any of the external debug, none of the
- * OSlock protocol. This should be revisited if we ever encounter a
- * more demanding guest...
+ * that we don't implement any of the external debug architecture.
+ * This should be revisited if we ever encounter a more demanding
+ * guest...
*/
static const struct sys_reg_desc sys_reg_descs[] = {
{ SYS_DESC(SYS_DC_ISW), access_dcsw },
@@ -1447,8 +1491,9 @@ static const struct sys_reg_desc sys_reg_descs[] = {
DBG_BCR_BVR_WCR_WVR_EL1(15),
{ SYS_DESC(SYS_MDRAR_EL1), trap_raz_wi },
- { SYS_DESC(SYS_OSLAR_EL1), trap_raz_wi },
- { SYS_DESC(SYS_OSLSR_EL1), trap_oslsr_el1 },
+ { SYS_DESC(SYS_OSLAR_EL1), trap_oslar_el1 },
+ { SYS_DESC(SYS_OSLSR_EL1), trap_oslsr_el1, reset_val, OSLSR_EL1,
+ SYS_OSLSR_OSLM_IMPLEMENTED, .set_user = set_oslsr_el1, },
{ SYS_DESC(SYS_OSDLR_EL1), trap_raz_wi },
{ SYS_DESC(SYS_DBGPRCR_EL1), trap_raz_wi },
{ SYS_DESC(SYS_DBGCLAIMSET_EL1), trap_raz_wi },
@@ -1920,10 +1965,10 @@ static const struct sys_reg_desc cp14_regs[] = {
DBGBXVR(0),
/* DBGOSLAR */
- { Op1( 0), CRn( 1), CRm( 0), Op2( 4), trap_raz_wi },
+ { Op1( 0), CRn( 1), CRm( 0), Op2( 4), trap_oslar_el1 },
DBGBXVR(1),
/* DBGOSLSR */
- { Op1( 0), CRn( 1), CRm( 1), Op2( 4), trap_oslsr_el1 },
+ { Op1( 0), CRn( 1), CRm( 1), Op2( 4), trap_oslsr_el1, NULL, OSLSR_EL1 },
DBGBXVR(2),
DBGBXVR(3),
/* DBGOSDLR */
diff --git a/arch/arm64/kvm/vgic/vgic-mmio.c b/arch/arm64/kvm/vgic/vgic-mmio.c
index 7068da080799..49837d3a3ef5 100644
--- a/arch/arm64/kvm/vgic/vgic-mmio.c
+++ b/arch/arm64/kvm/vgic/vgic-mmio.c
@@ -248,6 +248,8 @@ unsigned long vgic_mmio_read_pending(struct kvm_vcpu *vcpu,
IRQCHIP_STATE_PENDING,
&val);
WARN_RATELIMIT(err, "IRQ %d", irq->host_irq);
+ } else if (vgic_irq_is_mapped_level(irq)) {
+ val = vgic_get_phys_line_level(irq);
} else {
val = irq_is_pending(irq);
}
diff --git a/arch/arm64/kvm/vgic/vgic-v3.c b/arch/arm64/kvm/vgic/vgic-v3.c
index a33d4366b326..b549af8b1dc2 100644
--- a/arch/arm64/kvm/vgic/vgic-v3.c
+++ b/arch/arm64/kvm/vgic/vgic-v3.c
@@ -609,6 +609,18 @@ static int __init early_gicv4_enable(char *buf)
}
early_param("kvm-arm.vgic_v4_enable", early_gicv4_enable);
+static const struct midr_range broken_seis[] = {
+ MIDR_ALL_VERSIONS(MIDR_APPLE_M1_ICESTORM),
+ MIDR_ALL_VERSIONS(MIDR_APPLE_M1_FIRESTORM),
+ {},
+};
+
+static bool vgic_v3_broken_seis(void)
+{
+ return ((kvm_vgic_global_state.ich_vtr_el2 & ICH_VTR_SEIS_MASK) &&
+ is_midr_in_range_list(read_cpuid_id(), broken_seis));
+}
+
/**
* vgic_v3_probe - probe for a VGICv3 compatible interrupt controller
* @info: pointer to the GIC description
@@ -676,9 +688,10 @@ int vgic_v3_probe(const struct gic_kvm_info *info)
group1_trap = true;
}
- if (kvm_vgic_global_state.ich_vtr_el2 & ICH_VTR_SEIS_MASK) {
- kvm_info("GICv3 with locally generated SEI\n");
+ if (vgic_v3_broken_seis()) {
+ kvm_info("GICv3 with broken locally generated SEI\n");
+ kvm_vgic_global_state.ich_vtr_el2 &= ~ICH_VTR_SEIS_MASK;
group0_trap = true;
group1_trap = true;
if (ich_vtr_el2 & ICH_VTR_TDS_MASK)
diff --git a/arch/arm64/kvm/vgic/vgic.c b/arch/arm64/kvm/vgic/vgic.c
index 9b98876a8a93..d97e6080b421 100644
--- a/arch/arm64/kvm/vgic/vgic.c
+++ b/arch/arm64/kvm/vgic/vgic.c
@@ -37,7 +37,7 @@ struct vgic_global kvm_vgic_global_state __ro_after_init = {
* If you need to take multiple locks, always take the upper lock first,
* then the lower ones, e.g. first take the its_lock, then the irq_lock.
* If you are already holding a lock and need to take a higher one, you
- * have to drop the lower ranking lock first and re-aquire it after having
+ * have to drop the lower ranking lock first and re-acquire it after having
* taken the upper one.
*
* When taking more than one ap_list_lock at the same time, always take the
diff --git a/arch/arm64/kvm/vmid.c b/arch/arm64/kvm/vmid.c
new file mode 100644
index 000000000000..8d5f0506fd87
--- /dev/null
+++ b/arch/arm64/kvm/vmid.c
@@ -0,0 +1,196 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * VMID allocator.
+ *
+ * Based on Arm64 ASID allocator algorithm.
+ * Please refer arch/arm64/mm/context.c for detailed
+ * comments on algorithm.
+ *
+ * Copyright (C) 2002-2003 Deep Blue Solutions Ltd, all rights reserved.
+ * Copyright (C) 2012 ARM Ltd.
+ */
+
+#include <linux/bitfield.h>
+#include <linux/bitops.h>
+
+#include <asm/kvm_asm.h>
+#include <asm/kvm_mmu.h>
+
+unsigned int kvm_arm_vmid_bits;
+static DEFINE_RAW_SPINLOCK(cpu_vmid_lock);
+
+static atomic64_t vmid_generation;
+static unsigned long *vmid_map;
+
+static DEFINE_PER_CPU(atomic64_t, active_vmids);
+static DEFINE_PER_CPU(u64, reserved_vmids);
+
+#define VMID_MASK (~GENMASK(kvm_arm_vmid_bits - 1, 0))
+#define VMID_FIRST_VERSION (1UL << kvm_arm_vmid_bits)
+
+#define NUM_USER_VMIDS VMID_FIRST_VERSION
+#define vmid2idx(vmid) ((vmid) & ~VMID_MASK)
+#define idx2vmid(idx) vmid2idx(idx)
+
+/*
+ * As vmid #0 is always reserved, we will never allocate one
+ * as below and can be treated as invalid. This is used to
+ * set the active_vmids on vCPU schedule out.
+ */
+#define VMID_ACTIVE_INVALID VMID_FIRST_VERSION
+
+#define vmid_gen_match(vmid) \
+ (!(((vmid) ^ atomic64_read(&vmid_generation)) >> kvm_arm_vmid_bits))
+
+static void flush_context(void)
+{
+ int cpu;
+ u64 vmid;
+
+ bitmap_clear(vmid_map, 0, NUM_USER_VMIDS);
+
+ for_each_possible_cpu(cpu) {
+ vmid = atomic64_xchg_relaxed(&per_cpu(active_vmids, cpu), 0);
+
+ /* Preserve reserved VMID */
+ if (vmid == 0)
+ vmid = per_cpu(reserved_vmids, cpu);
+ __set_bit(vmid2idx(vmid), vmid_map);
+ per_cpu(reserved_vmids, cpu) = vmid;
+ }
+
+ /*
+ * Unlike ASID allocator, we expect less frequent rollover in
+ * case of VMIDs. Hence, instead of marking the CPU as
+ * flush_pending and issuing a local context invalidation on
+ * the next context-switch, we broadcast TLB flush + I-cache
+ * invalidation over the inner shareable domain on rollover.
+ */
+ kvm_call_hyp(__kvm_flush_vm_context);
+}
+
+static bool check_update_reserved_vmid(u64 vmid, u64 newvmid)
+{
+ int cpu;
+ bool hit = false;
+
+ /*
+ * Iterate over the set of reserved VMIDs looking for a match
+ * and update to use newvmid (i.e. the same VMID in the current
+ * generation).
+ */
+ for_each_possible_cpu(cpu) {
+ if (per_cpu(reserved_vmids, cpu) == vmid) {
+ hit = true;
+ per_cpu(reserved_vmids, cpu) = newvmid;
+ }
+ }
+
+ return hit;
+}
+
+static u64 new_vmid(struct kvm_vmid *kvm_vmid)
+{
+ static u32 cur_idx = 1;
+ u64 vmid = atomic64_read(&kvm_vmid->id);
+ u64 generation = atomic64_read(&vmid_generation);
+
+ if (vmid != 0) {
+ u64 newvmid = generation | (vmid & ~VMID_MASK);
+
+ if (check_update_reserved_vmid(vmid, newvmid)) {
+ atomic64_set(&kvm_vmid->id, newvmid);
+ return newvmid;
+ }
+
+ if (!__test_and_set_bit(vmid2idx(vmid), vmid_map)) {
+ atomic64_set(&kvm_vmid->id, newvmid);
+ return newvmid;
+ }
+ }
+
+ vmid = find_next_zero_bit(vmid_map, NUM_USER_VMIDS, cur_idx);
+ if (vmid != NUM_USER_VMIDS)
+ goto set_vmid;
+
+ /* We're out of VMIDs, so increment the global generation count */
+ generation = atomic64_add_return_relaxed(VMID_FIRST_VERSION,
+ &vmid_generation);
+ flush_context();
+
+ /* We have more VMIDs than CPUs, so this will always succeed */
+ vmid = find_next_zero_bit(vmid_map, NUM_USER_VMIDS, 1);
+
+set_vmid:
+ __set_bit(vmid, vmid_map);
+ cur_idx = vmid;
+ vmid = idx2vmid(vmid) | generation;
+ atomic64_set(&kvm_vmid->id, vmid);
+ return vmid;
+}
+
+/* Called from vCPU sched out with preemption disabled */
+void kvm_arm_vmid_clear_active(void)
+{
+ atomic64_set(this_cpu_ptr(&active_vmids), VMID_ACTIVE_INVALID);
+}
+
+void kvm_arm_vmid_update(struct kvm_vmid *kvm_vmid)
+{
+ unsigned long flags;
+ u64 vmid, old_active_vmid;
+
+ vmid = atomic64_read(&kvm_vmid->id);
+
+ /*
+ * Please refer comments in check_and_switch_context() in
+ * arch/arm64/mm/context.c.
+ *
+ * Unlike ASID allocator, we set the active_vmids to
+ * VMID_ACTIVE_INVALID on vCPU schedule out to avoid
+ * reserving the VMID space needlessly on rollover.
+ * Hence explicitly check here for a "!= 0" to
+ * handle the sync with a concurrent rollover.
+ */
+ old_active_vmid = atomic64_read(this_cpu_ptr(&active_vmids));
+ if (old_active_vmid != 0 && vmid_gen_match(vmid) &&
+ 0 != atomic64_cmpxchg_relaxed(this_cpu_ptr(&active_vmids),
+ old_active_vmid, vmid))
+ return;
+
+ raw_spin_lock_irqsave(&cpu_vmid_lock, flags);
+
+ /* Check that our VMID belongs to the current generation. */
+ vmid = atomic64_read(&kvm_vmid->id);
+ if (!vmid_gen_match(vmid))
+ vmid = new_vmid(kvm_vmid);
+
+ atomic64_set(this_cpu_ptr(&active_vmids), vmid);
+ raw_spin_unlock_irqrestore(&cpu_vmid_lock, flags);
+}
+
+/*
+ * Initialize the VMID allocator
+ */
+int kvm_arm_vmid_alloc_init(void)
+{
+ kvm_arm_vmid_bits = kvm_get_vmid_bits();
+
+ /*
+ * Expect allocation after rollover to fail if we don't have
+ * at least one more VMID than CPUs. VMID #0 is always reserved.
+ */
+ WARN_ON(NUM_USER_VMIDS - 1 <= num_possible_cpus());
+ atomic64_set(&vmid_generation, VMID_FIRST_VERSION);
+ vmid_map = kcalloc(BITS_TO_LONGS(NUM_USER_VMIDS),
+ sizeof(*vmid_map), GFP_KERNEL);
+ if (!vmid_map)
+ return -ENOMEM;
+
+ return 0;
+}
+
+void kvm_arm_vmid_alloc_free(void)
+{
+ kfree(vmid_map);
+}
diff --git a/arch/arm64/lib/clear_page.S b/arch/arm64/lib/clear_page.S
index 1fd5d790ab80..ebde40e7fa2b 100644
--- a/arch/arm64/lib/clear_page.S
+++ b/arch/arm64/lib/clear_page.S
@@ -14,7 +14,7 @@
* Parameters:
* x0 - dest
*/
-SYM_FUNC_START_PI(clear_page)
+SYM_FUNC_START(__pi_clear_page)
mrs x1, dczid_el0
tbnz x1, #4, 2f /* Branch if DC ZVA is prohibited */
and w1, w1, #0xf
@@ -35,5 +35,6 @@ SYM_FUNC_START_PI(clear_page)
tst x0, #(PAGE_SIZE - 1)
b.ne 2b
ret
-SYM_FUNC_END_PI(clear_page)
+SYM_FUNC_END(__pi_clear_page)
+SYM_FUNC_ALIAS(clear_page, __pi_clear_page)
EXPORT_SYMBOL(clear_page)
diff --git a/arch/arm64/lib/copy_page.S b/arch/arm64/lib/copy_page.S
index 29144f4cd449..c336d2ffdec5 100644
--- a/arch/arm64/lib/copy_page.S
+++ b/arch/arm64/lib/copy_page.S
@@ -17,7 +17,7 @@
* x0 - dest
* x1 - src
*/
-SYM_FUNC_START_PI(copy_page)
+SYM_FUNC_START(__pi_copy_page)
alternative_if ARM64_HAS_NO_HW_PREFETCH
// Prefetch three cache lines ahead.
prfm pldl1strm, [x1, #128]
@@ -75,5 +75,6 @@ alternative_else_nop_endif
stnp x16, x17, [x0, #112 - 256]
ret
-SYM_FUNC_END_PI(copy_page)
+SYM_FUNC_END(__pi_copy_page)
+SYM_FUNC_ALIAS(copy_page, __pi_copy_page)
EXPORT_SYMBOL(copy_page)
diff --git a/arch/arm64/lib/crc32.S b/arch/arm64/lib/crc32.S
index 0f9e10ecda23..8340dccff46f 100644
--- a/arch/arm64/lib/crc32.S
+++ b/arch/arm64/lib/crc32.S
@@ -11,7 +11,44 @@
.arch armv8-a+crc
- .macro __crc32, c
+ .macro byteorder, reg, be
+ .if \be
+CPU_LE( rev \reg, \reg )
+ .else
+CPU_BE( rev \reg, \reg )
+ .endif
+ .endm
+
+ .macro byteorder16, reg, be
+ .if \be
+CPU_LE( rev16 \reg, \reg )
+ .else
+CPU_BE( rev16 \reg, \reg )
+ .endif
+ .endm
+
+ .macro bitorder, reg, be
+ .if \be
+ rbit \reg, \reg
+ .endif
+ .endm
+
+ .macro bitorder16, reg, be
+ .if \be
+ rbit \reg, \reg
+ lsr \reg, \reg, #16
+ .endif
+ .endm
+
+ .macro bitorder8, reg, be
+ .if \be
+ rbit \reg, \reg
+ lsr \reg, \reg, #24
+ .endif
+ .endm
+
+ .macro __crc32, c, be=0
+ bitorder w0, \be
cmp x2, #16
b.lt 8f // less than 16 bytes
@@ -24,10 +61,14 @@
add x8, x8, x1
add x1, x1, x7
ldp x5, x6, [x8]
-CPU_BE( rev x3, x3 )
-CPU_BE( rev x4, x4 )
-CPU_BE( rev x5, x5 )
-CPU_BE( rev x6, x6 )
+ byteorder x3, \be
+ byteorder x4, \be
+ byteorder x5, \be
+ byteorder x6, \be
+ bitorder x3, \be
+ bitorder x4, \be
+ bitorder x5, \be
+ bitorder x6, \be
tst x7, #8
crc32\c\()x w8, w0, x3
@@ -55,33 +96,43 @@ CPU_BE( rev x6, x6 )
32: ldp x3, x4, [x1], #32
sub x2, x2, #32
ldp x5, x6, [x1, #-16]
-CPU_BE( rev x3, x3 )
-CPU_BE( rev x4, x4 )
-CPU_BE( rev x5, x5 )
-CPU_BE( rev x6, x6 )
+ byteorder x3, \be
+ byteorder x4, \be
+ byteorder x5, \be
+ byteorder x6, \be
+ bitorder x3, \be
+ bitorder x4, \be
+ bitorder x5, \be
+ bitorder x6, \be
crc32\c\()x w0, w0, x3
crc32\c\()x w0, w0, x4
crc32\c\()x w0, w0, x5
crc32\c\()x w0, w0, x6
cbnz x2, 32b
-0: ret
+0: bitorder w0, \be
+ ret
8: tbz x2, #3, 4f
ldr x3, [x1], #8
-CPU_BE( rev x3, x3 )
+ byteorder x3, \be
+ bitorder x3, \be
crc32\c\()x w0, w0, x3
4: tbz x2, #2, 2f
ldr w3, [x1], #4
-CPU_BE( rev w3, w3 )
+ byteorder w3, \be
+ bitorder w3, \be
crc32\c\()w w0, w0, w3
2: tbz x2, #1, 1f
ldrh w3, [x1], #2
-CPU_BE( rev16 w3, w3 )
+ byteorder16 w3, \be
+ bitorder16 w3, \be
crc32\c\()h w0, w0, w3
1: tbz x2, #0, 0f
ldrb w3, [x1]
+ bitorder8 w3, \be
crc32\c\()b w0, w0, w3
-0: ret
+0: bitorder w0, \be
+ ret
.endm
.align 5
@@ -99,3 +150,11 @@ alternative_if_not ARM64_HAS_CRC32
alternative_else_nop_endif
__crc32 c
SYM_FUNC_END(__crc32c_le)
+
+ .align 5
+SYM_FUNC_START(crc32_be)
+alternative_if_not ARM64_HAS_CRC32
+ b crc32_be_base
+alternative_else_nop_endif
+ __crc32 be=1
+SYM_FUNC_END(crc32_be)
diff --git a/arch/arm64/lib/insn.c b/arch/arm64/lib/insn.c
index fccfe363e567..5e90887deec4 100644
--- a/arch/arm64/lib/insn.c
+++ b/arch/arm64/lib/insn.c
@@ -578,10 +578,16 @@ u32 aarch64_insn_gen_load_store_ex(enum aarch64_insn_register reg,
switch (type) {
case AARCH64_INSN_LDST_LOAD_EX:
+ case AARCH64_INSN_LDST_LOAD_ACQ_EX:
insn = aarch64_insn_get_load_ex_value();
+ if (type == AARCH64_INSN_LDST_LOAD_ACQ_EX)
+ insn |= BIT(15);
break;
case AARCH64_INSN_LDST_STORE_EX:
+ case AARCH64_INSN_LDST_STORE_REL_EX:
insn = aarch64_insn_get_store_ex_value();
+ if (type == AARCH64_INSN_LDST_STORE_REL_EX)
+ insn |= BIT(15);
break;
default:
pr_err("%s: unknown load/store exclusive encoding %d\n", __func__, type);
@@ -603,12 +609,65 @@ u32 aarch64_insn_gen_load_store_ex(enum aarch64_insn_register reg,
state);
}
-u32 aarch64_insn_gen_ldadd(enum aarch64_insn_register result,
- enum aarch64_insn_register address,
- enum aarch64_insn_register value,
- enum aarch64_insn_size_type size)
+#ifdef CONFIG_ARM64_LSE_ATOMICS
+static u32 aarch64_insn_encode_ldst_order(enum aarch64_insn_mem_order_type type,
+ u32 insn)
{
- u32 insn = aarch64_insn_get_ldadd_value();
+ u32 order;
+
+ switch (type) {
+ case AARCH64_INSN_MEM_ORDER_NONE:
+ order = 0;
+ break;
+ case AARCH64_INSN_MEM_ORDER_ACQ:
+ order = 2;
+ break;
+ case AARCH64_INSN_MEM_ORDER_REL:
+ order = 1;
+ break;
+ case AARCH64_INSN_MEM_ORDER_ACQREL:
+ order = 3;
+ break;
+ default:
+ pr_err("%s: unknown mem order %d\n", __func__, type);
+ return AARCH64_BREAK_FAULT;
+ }
+
+ insn &= ~GENMASK(23, 22);
+ insn |= order << 22;
+
+ return insn;
+}
+
+u32 aarch64_insn_gen_atomic_ld_op(enum aarch64_insn_register result,
+ enum aarch64_insn_register address,
+ enum aarch64_insn_register value,
+ enum aarch64_insn_size_type size,
+ enum aarch64_insn_mem_atomic_op op,
+ enum aarch64_insn_mem_order_type order)
+{
+ u32 insn;
+
+ switch (op) {
+ case AARCH64_INSN_MEM_ATOMIC_ADD:
+ insn = aarch64_insn_get_ldadd_value();
+ break;
+ case AARCH64_INSN_MEM_ATOMIC_CLR:
+ insn = aarch64_insn_get_ldclr_value();
+ break;
+ case AARCH64_INSN_MEM_ATOMIC_EOR:
+ insn = aarch64_insn_get_ldeor_value();
+ break;
+ case AARCH64_INSN_MEM_ATOMIC_SET:
+ insn = aarch64_insn_get_ldset_value();
+ break;
+ case AARCH64_INSN_MEM_ATOMIC_SWP:
+ insn = aarch64_insn_get_swp_value();
+ break;
+ default:
+ pr_err("%s: unimplemented mem atomic op %d\n", __func__, op);
+ return AARCH64_BREAK_FAULT;
+ }
switch (size) {
case AARCH64_INSN_SIZE_32:
@@ -621,6 +680,8 @@ u32 aarch64_insn_gen_ldadd(enum aarch64_insn_register result,
insn = aarch64_insn_encode_ldst_size(size, insn);
+ insn = aarch64_insn_encode_ldst_order(order, insn);
+
insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RT, insn,
result);
@@ -631,17 +692,68 @@ u32 aarch64_insn_gen_ldadd(enum aarch64_insn_register result,
value);
}
-u32 aarch64_insn_gen_stadd(enum aarch64_insn_register address,
- enum aarch64_insn_register value,
- enum aarch64_insn_size_type size)
+static u32 aarch64_insn_encode_cas_order(enum aarch64_insn_mem_order_type type,
+ u32 insn)
{
- /*
- * STADD is simply encoded as an alias for LDADD with XZR as
- * the destination register.
- */
- return aarch64_insn_gen_ldadd(AARCH64_INSN_REG_ZR, address,
- value, size);
+ u32 order;
+
+ switch (type) {
+ case AARCH64_INSN_MEM_ORDER_NONE:
+ order = 0;
+ break;
+ case AARCH64_INSN_MEM_ORDER_ACQ:
+ order = BIT(22);
+ break;
+ case AARCH64_INSN_MEM_ORDER_REL:
+ order = BIT(15);
+ break;
+ case AARCH64_INSN_MEM_ORDER_ACQREL:
+ order = BIT(15) | BIT(22);
+ break;
+ default:
+ pr_err("%s: unknown mem order %d\n", __func__, type);
+ return AARCH64_BREAK_FAULT;
+ }
+
+ insn &= ~(BIT(15) | BIT(22));
+ insn |= order;
+
+ return insn;
+}
+
+u32 aarch64_insn_gen_cas(enum aarch64_insn_register result,
+ enum aarch64_insn_register address,
+ enum aarch64_insn_register value,
+ enum aarch64_insn_size_type size,
+ enum aarch64_insn_mem_order_type order)
+{
+ u32 insn;
+
+ switch (size) {
+ case AARCH64_INSN_SIZE_32:
+ case AARCH64_INSN_SIZE_64:
+ break;
+ default:
+ pr_err("%s: unimplemented size encoding %d\n", __func__, size);
+ return AARCH64_BREAK_FAULT;
+ }
+
+ insn = aarch64_insn_get_cas_value();
+
+ insn = aarch64_insn_encode_ldst_size(size, insn);
+
+ insn = aarch64_insn_encode_cas_order(order, insn);
+
+ insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RT, insn,
+ result);
+
+ insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RN, insn,
+ address);
+
+ return aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RS, insn,
+ value);
}
+#endif
static u32 aarch64_insn_encode_prfm_imm(enum aarch64_insn_prfm_type type,
enum aarch64_insn_prfm_target target,
@@ -1379,7 +1491,7 @@ static u32 aarch64_encode_immediate(u64 imm,
* Compute the rotation to get a continuous set of
* ones, with the first bit set at position 0
*/
- ror = fls(~imm);
+ ror = fls64(~imm);
}
/*
@@ -1456,3 +1568,48 @@ u32 aarch64_insn_gen_extr(enum aarch64_insn_variant variant,
insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RN, insn, Rn);
return aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RM, insn, Rm);
}
+
+u32 aarch64_insn_gen_dmb(enum aarch64_insn_mb_type type)
+{
+ u32 opt;
+ u32 insn;
+
+ switch (type) {
+ case AARCH64_INSN_MB_SY:
+ opt = 0xf;
+ break;
+ case AARCH64_INSN_MB_ST:
+ opt = 0xe;
+ break;
+ case AARCH64_INSN_MB_LD:
+ opt = 0xd;
+ break;
+ case AARCH64_INSN_MB_ISH:
+ opt = 0xb;
+ break;
+ case AARCH64_INSN_MB_ISHST:
+ opt = 0xa;
+ break;
+ case AARCH64_INSN_MB_ISHLD:
+ opt = 0x9;
+ break;
+ case AARCH64_INSN_MB_NSH:
+ opt = 0x7;
+ break;
+ case AARCH64_INSN_MB_NSHST:
+ opt = 0x6;
+ break;
+ case AARCH64_INSN_MB_NSHLD:
+ opt = 0x5;
+ break;
+ default:
+ pr_err("%s: unknown dmb type %d\n", __func__, type);
+ return AARCH64_BREAK_FAULT;
+ }
+
+ insn = aarch64_insn_get_dmb_value();
+ insn &= ~GENMASK(11, 8);
+ insn |= (opt << 8);
+
+ return insn;
+}
diff --git a/arch/arm64/lib/memchr.S b/arch/arm64/lib/memchr.S
index 7c2276fdab54..37a9f2a4f7f4 100644
--- a/arch/arm64/lib/memchr.S
+++ b/arch/arm64/lib/memchr.S
@@ -38,7 +38,7 @@
.p2align 4
nop
-SYM_FUNC_START_WEAK_PI(memchr)
+SYM_FUNC_START(__pi_memchr)
and chrin, chrin, #0xff
lsr wordcnt, cntin, #3
cbz wordcnt, L(byte_loop)
@@ -71,5 +71,6 @@ CPU_LE( rev tmp, tmp)
L(not_found):
mov result, #0
ret
-SYM_FUNC_END_PI(memchr)
+SYM_FUNC_END(__pi_memchr)
+SYM_FUNC_ALIAS_WEAK(memchr, __pi_memchr)
EXPORT_SYMBOL_NOKASAN(memchr)
diff --git a/arch/arm64/lib/memcmp.S b/arch/arm64/lib/memcmp.S
index 7d956384222f..a5ccf2c55f91 100644
--- a/arch/arm64/lib/memcmp.S
+++ b/arch/arm64/lib/memcmp.S
@@ -32,7 +32,7 @@
#define tmp1 x7
#define tmp2 x8
-SYM_FUNC_START_WEAK_PI(memcmp)
+SYM_FUNC_START(__pi_memcmp)
subs limit, limit, 8
b.lo L(less8)
@@ -134,6 +134,6 @@ L(byte_loop):
b.eq L(byte_loop)
sub result, data1w, data2w
ret
-
-SYM_FUNC_END_PI(memcmp)
+SYM_FUNC_END(__pi_memcmp)
+SYM_FUNC_ALIAS_WEAK(memcmp, __pi_memcmp)
EXPORT_SYMBOL_NOKASAN(memcmp)
diff --git a/arch/arm64/lib/memcpy.S b/arch/arm64/lib/memcpy.S
index b82fd64ee1e1..4ab48d49c451 100644
--- a/arch/arm64/lib/memcpy.S
+++ b/arch/arm64/lib/memcpy.S
@@ -57,10 +57,7 @@
The loop tail is handled by always copying 64 bytes from the end.
*/
-SYM_FUNC_START_ALIAS(__memmove)
-SYM_FUNC_START_WEAK_ALIAS_PI(memmove)
-SYM_FUNC_START_ALIAS(__memcpy)
-SYM_FUNC_START_WEAK_PI(memcpy)
+SYM_FUNC_START(__pi_memcpy)
add srcend, src, count
add dstend, dstin, count
cmp count, 128
@@ -241,12 +238,16 @@ L(copy64_from_start):
stp B_l, B_h, [dstin, 16]
stp C_l, C_h, [dstin]
ret
+SYM_FUNC_END(__pi_memcpy)
-SYM_FUNC_END_PI(memcpy)
-EXPORT_SYMBOL(memcpy)
-SYM_FUNC_END_ALIAS(__memcpy)
+SYM_FUNC_ALIAS(__memcpy, __pi_memcpy)
EXPORT_SYMBOL(__memcpy)
-SYM_FUNC_END_ALIAS_PI(memmove)
-EXPORT_SYMBOL(memmove)
-SYM_FUNC_END_ALIAS(__memmove)
+SYM_FUNC_ALIAS_WEAK(memcpy, __memcpy)
+EXPORT_SYMBOL(memcpy)
+
+SYM_FUNC_ALIAS(__pi_memmove, __pi_memcpy)
+
+SYM_FUNC_ALIAS(__memmove, __pi_memmove)
EXPORT_SYMBOL(__memmove)
+SYM_FUNC_ALIAS_WEAK(memmove, __memmove)
+EXPORT_SYMBOL(memmove)
diff --git a/arch/arm64/lib/memset.S b/arch/arm64/lib/memset.S
index a9c1c9a01ea9..a5aebe82ad73 100644
--- a/arch/arm64/lib/memset.S
+++ b/arch/arm64/lib/memset.S
@@ -42,8 +42,7 @@ dst .req x8
tmp3w .req w9
tmp3 .req x9
-SYM_FUNC_START_ALIAS(__memset)
-SYM_FUNC_START_WEAK_PI(memset)
+SYM_FUNC_START(__pi_memset)
mov dst, dstin /* Preserve return value. */
and A_lw, val, #255
orr A_lw, A_lw, A_lw, lsl #8
@@ -202,7 +201,10 @@ SYM_FUNC_START_WEAK_PI(memset)
ands count, count, zva_bits_x
b.ne .Ltail_maybe_long
ret
-SYM_FUNC_END_PI(memset)
-EXPORT_SYMBOL(memset)
-SYM_FUNC_END_ALIAS(__memset)
+SYM_FUNC_END(__pi_memset)
+
+SYM_FUNC_ALIAS(__memset, __pi_memset)
EXPORT_SYMBOL(__memset)
+
+SYM_FUNC_ALIAS_WEAK(memset, __pi_memset)
+EXPORT_SYMBOL(memset)
diff --git a/arch/arm64/lib/mte.S b/arch/arm64/lib/mte.S
index f531dcb95174..8590af3c98c0 100644
--- a/arch/arm64/lib/mte.S
+++ b/arch/arm64/lib/mte.S
@@ -134,7 +134,7 @@ SYM_FUNC_END(mte_copy_tags_to_user)
/*
* Save the tags in a page
* x0 - page address
- * x1 - tag storage
+ * x1 - tag storage, MTE_PAGE_TAG_STORAGE bytes
*/
SYM_FUNC_START(mte_save_page_tags)
multitag_transfer_size x7, x5
@@ -158,7 +158,7 @@ SYM_FUNC_END(mte_save_page_tags)
/*
* Restore the tags in a page
* x0 - page address
- * x1 - tag storage
+ * x1 - tag storage, MTE_PAGE_TAG_STORAGE bytes
*/
SYM_FUNC_START(mte_restore_page_tags)
multitag_transfer_size x7, x5
diff --git a/arch/arm64/lib/strchr.S b/arch/arm64/lib/strchr.S
index 1f47eae3b0d6..94ee67a6b212 100644
--- a/arch/arm64/lib/strchr.S
+++ b/arch/arm64/lib/strchr.S
@@ -18,7 +18,7 @@
* Returns:
* x0 - address of first occurrence of 'c' or 0
*/
-SYM_FUNC_START_WEAK(strchr)
+SYM_FUNC_START(__pi_strchr)
and w1, w1, #0xff
1: ldrb w2, [x0], #1
cmp w2, w1
@@ -28,5 +28,7 @@ SYM_FUNC_START_WEAK(strchr)
cmp w2, w1
csel x0, x0, xzr, eq
ret
-SYM_FUNC_END(strchr)
+SYM_FUNC_END(__pi_strchr)
+
+SYM_FUNC_ALIAS_WEAK(strchr, __pi_strchr)
EXPORT_SYMBOL_NOKASAN(strchr)
diff --git a/arch/arm64/lib/strcmp.S b/arch/arm64/lib/strcmp.S
index 83bcad72ec97..9b89b4533607 100644
--- a/arch/arm64/lib/strcmp.S
+++ b/arch/arm64/lib/strcmp.S
@@ -1,9 +1,9 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
- * Copyright (c) 2012-2021, Arm Limited.
+ * Copyright (c) 2012-2022, Arm Limited.
*
* Adapted from the original at:
- * https://github.com/ARM-software/optimized-routines/blob/afd6244a1f8d9229/string/aarch64/strcmp.S
+ * https://github.com/ARM-software/optimized-routines/blob/189dfefe37d54c5b/string/aarch64/strcmp.S
*/
#include <linux/linkage.h>
@@ -11,166 +11,180 @@
/* Assumptions:
*
- * ARMv8-a, AArch64
+ * ARMv8-a, AArch64.
+ * MTE compatible.
*/
#define L(label) .L ## label
#define REP8_01 0x0101010101010101
#define REP8_7f 0x7f7f7f7f7f7f7f7f
-#define REP8_80 0x8080808080808080
-/* Parameters and result. */
#define src1 x0
#define src2 x1
#define result x0
-/* Internal variables. */
#define data1 x2
#define data1w w2
#define data2 x3
#define data2w w3
#define has_nul x4
#define diff x5
+#define off1 x5
#define syndrome x6
-#define tmp1 x7
-#define tmp2 x8
-#define tmp3 x9
-#define zeroones x10
-#define pos x11
-
- /* Start of performance-critical section -- one 64B cache line. */
- .align 6
-SYM_FUNC_START_WEAK_PI(strcmp)
- eor tmp1, src1, src2
- mov zeroones, #REP8_01
- tst tmp1, #7
+#define tmp x6
+#define data3 x7
+#define zeroones x8
+#define shift x9
+#define off2 x10
+
+/* On big-endian early bytes are at MSB and on little-endian LSB.
+ LS_FW means shifting towards early bytes. */
+#ifdef __AARCH64EB__
+# define LS_FW lsl
+#else
+# define LS_FW lsr
+#endif
+
+/* NUL detection works on the principle that (X - 1) & (~X) & 0x80
+ (=> (X - 1) & ~(X | 0x7f)) is non-zero iff a byte is zero, and
+ can be done in parallel across the entire word.
+ Since carry propagation makes 0x1 bytes before a NUL byte appear
+ NUL too in big-endian, byte-reverse the data before the NUL check. */
+
+
+SYM_FUNC_START(__pi_strcmp)
+ sub off2, src2, src1
+ mov zeroones, REP8_01
+ and tmp, src1, 7
+ tst off2, 7
b.ne L(misaligned8)
- ands tmp1, src1, #7
- b.ne L(mutual_align)
- /* NUL detection works on the principle that (X - 1) & (~X) & 0x80
- (=> (X - 1) & ~(X | 0x7f)) is non-zero iff a byte is zero, and
- can be done in parallel across the entire word. */
+ cbnz tmp, L(mutual_align)
+
+ .p2align 4
+
L(loop_aligned):
- ldr data1, [src1], #8
- ldr data2, [src2], #8
+ ldr data2, [src1, off2]
+ ldr data1, [src1], 8
L(start_realigned):
- sub tmp1, data1, zeroones
- orr tmp2, data1, #REP8_7f
- eor diff, data1, data2 /* Non-zero if differences found. */
- bic has_nul, tmp1, tmp2 /* Non-zero if NUL terminator. */
+#ifdef __AARCH64EB__
+ rev tmp, data1
+ sub has_nul, tmp, zeroones
+ orr tmp, tmp, REP8_7f
+#else
+ sub has_nul, data1, zeroones
+ orr tmp, data1, REP8_7f
+#endif
+ bics has_nul, has_nul, tmp /* Non-zero if NUL terminator. */
+ ccmp data1, data2, 0, eq
+ b.eq L(loop_aligned)
+#ifdef __AARCH64EB__
+ rev has_nul, has_nul
+#endif
+ eor diff, data1, data2
orr syndrome, diff, has_nul
- cbz syndrome, L(loop_aligned)
- /* End of performance-critical section -- one 64B cache line. */
-
L(end):
-#ifndef __AARCH64EB__
+#ifndef __AARCH64EB__
rev syndrome, syndrome
rev data1, data1
- /* The MS-non-zero bit of the syndrome marks either the first bit
- that is different, or the top bit of the first zero byte.
- Shifting left now will bring the critical information into the
- top bits. */
- clz pos, syndrome
rev data2, data2
- lsl data1, data1, pos
- lsl data2, data2, pos
- /* But we need to zero-extend (char is unsigned) the value and then
- perform a signed 32-bit subtraction. */
- lsr data1, data1, #56
- sub result, data1, data2, lsr #56
- ret
-#else
- /* For big-endian we cannot use the trick with the syndrome value
- as carry-propagation can corrupt the upper bits if the trailing
- bytes in the string contain 0x01. */
- /* However, if there is no NUL byte in the dword, we can generate
- the result directly. We can't just subtract the bytes as the
- MSB might be significant. */
- cbnz has_nul, 1f
- cmp data1, data2
- cset result, ne
- cneg result, result, lo
- ret
-1:
- /* Re-compute the NUL-byte detection, using a byte-reversed value. */
- rev tmp3, data1
- sub tmp1, tmp3, zeroones
- orr tmp2, tmp3, #REP8_7f
- bic has_nul, tmp1, tmp2
- rev has_nul, has_nul
- orr syndrome, diff, has_nul
- clz pos, syndrome
- /* The MS-non-zero bit of the syndrome marks either the first bit
- that is different, or the top bit of the first zero byte.
+#endif
+ clz shift, syndrome
+ /* The most-significant-non-zero bit of the syndrome marks either the
+ first bit that is different, or the top bit of the first zero byte.
Shifting left now will bring the critical information into the
top bits. */
- lsl data1, data1, pos
- lsl data2, data2, pos
+ lsl data1, data1, shift
+ lsl data2, data2, shift
/* But we need to zero-extend (char is unsigned) the value and then
perform a signed 32-bit subtraction. */
- lsr data1, data1, #56
- sub result, data1, data2, lsr #56
+ lsr data1, data1, 56
+ sub result, data1, data2, lsr 56
ret
-#endif
+
+ .p2align 4
L(mutual_align):
/* Sources are mutually aligned, but are not currently at an
alignment boundary. Round down the addresses and then mask off
- the bytes that preceed the start point. */
- bic src1, src1, #7
- bic src2, src2, #7
- lsl tmp1, tmp1, #3 /* Bytes beyond alignment -> bits. */
- ldr data1, [src1], #8
- neg tmp1, tmp1 /* Bits to alignment -64. */
- ldr data2, [src2], #8
- mov tmp2, #~0
-#ifdef __AARCH64EB__
- /* Big-endian. Early bytes are at MSB. */
- lsl tmp2, tmp2, tmp1 /* Shift (tmp1 & 63). */
-#else
- /* Little-endian. Early bytes are at LSB. */
- lsr tmp2, tmp2, tmp1 /* Shift (tmp1 & 63). */
-#endif
- orr data1, data1, tmp2
- orr data2, data2, tmp2
+ the bytes that precede the start point. */
+ bic src1, src1, 7
+ ldr data2, [src1, off2]
+ ldr data1, [src1], 8
+ neg shift, src2, lsl 3 /* Bits to alignment -64. */
+ mov tmp, -1
+ LS_FW tmp, tmp, shift
+ orr data1, data1, tmp
+ orr data2, data2, tmp
b L(start_realigned)
L(misaligned8):
/* Align SRC1 to 8 bytes and then compare 8 bytes at a time, always
- checking to make sure that we don't access beyond page boundary in
- SRC2. */
- tst src1, #7
- b.eq L(loop_misaligned)
+ checking to make sure that we don't access beyond the end of SRC2. */
+ cbz tmp, L(src1_aligned)
L(do_misaligned):
- ldrb data1w, [src1], #1
- ldrb data2w, [src2], #1
- cmp data1w, #1
- ccmp data1w, data2w, #0, cs /* NZCV = 0b0000. */
+ ldrb data1w, [src1], 1
+ ldrb data2w, [src2], 1
+ cmp data1w, 0
+ ccmp data1w, data2w, 0, ne /* NZCV = 0b0000. */
b.ne L(done)
- tst src1, #7
+ tst src1, 7
b.ne L(do_misaligned)
-L(loop_misaligned):
- /* Test if we are within the last dword of the end of a 4K page. If
- yes then jump back to the misaligned loop to copy a byte at a time. */
- and tmp1, src2, #0xff8
- eor tmp1, tmp1, #0xff8
- cbz tmp1, L(do_misaligned)
- ldr data1, [src1], #8
- ldr data2, [src2], #8
-
- sub tmp1, data1, zeroones
- orr tmp2, data1, #REP8_7f
- eor diff, data1, data2 /* Non-zero if differences found. */
- bic has_nul, tmp1, tmp2 /* Non-zero if NUL terminator. */
+L(src1_aligned):
+ neg shift, src2, lsl 3
+ bic src2, src2, 7
+ ldr data3, [src2], 8
+#ifdef __AARCH64EB__
+ rev data3, data3
+#endif
+ lsr tmp, zeroones, shift
+ orr data3, data3, tmp
+ sub has_nul, data3, zeroones
+ orr tmp, data3, REP8_7f
+ bics has_nul, has_nul, tmp
+ b.ne L(tail)
+
+ sub off1, src2, src1
+
+ .p2align 4
+
+L(loop_unaligned):
+ ldr data3, [src1, off1]
+ ldr data2, [src1, off2]
+#ifdef __AARCH64EB__
+ rev data3, data3
+#endif
+ sub has_nul, data3, zeroones
+ orr tmp, data3, REP8_7f
+ ldr data1, [src1], 8
+ bics has_nul, has_nul, tmp
+ ccmp data1, data2, 0, eq
+ b.eq L(loop_unaligned)
+
+ lsl tmp, has_nul, shift
+#ifdef __AARCH64EB__
+ rev tmp, tmp
+#endif
+ eor diff, data1, data2
+ orr syndrome, diff, tmp
+ cbnz syndrome, L(end)
+L(tail):
+ ldr data1, [src1]
+ neg shift, shift
+ lsr data2, data3, shift
+ lsr has_nul, has_nul, shift
+#ifdef __AARCH64EB__
+ rev data2, data2
+ rev has_nul, has_nul
+#endif
+ eor diff, data1, data2
orr syndrome, diff, has_nul
- cbz syndrome, L(loop_misaligned)
b L(end)
L(done):
sub result, data1, data2
ret
-
-SYM_FUNC_END_PI(strcmp)
-EXPORT_SYMBOL_NOHWKASAN(strcmp)
+SYM_FUNC_END(__pi_strcmp)
+SYM_FUNC_ALIAS_WEAK(strcmp, __pi_strcmp)
+EXPORT_SYMBOL_NOKASAN(strcmp)
diff --git a/arch/arm64/lib/strlen.S b/arch/arm64/lib/strlen.S
index 1648790e91b3..4919fe81ae54 100644
--- a/arch/arm64/lib/strlen.S
+++ b/arch/arm64/lib/strlen.S
@@ -79,7 +79,7 @@
whether the first fetch, which may be misaligned, crosses a page
boundary. */
-SYM_FUNC_START_WEAK_PI(strlen)
+SYM_FUNC_START(__pi_strlen)
and tmp1, srcin, MIN_PAGE_SIZE - 1
mov zeroones, REP8_01
cmp tmp1, MIN_PAGE_SIZE - 16
@@ -208,6 +208,6 @@ L(page_cross):
csel data1, data1, tmp4, eq
csel data2, data2, tmp2, eq
b L(page_cross_entry)
-
-SYM_FUNC_END_PI(strlen)
+SYM_FUNC_END(__pi_strlen)
+SYM_FUNC_ALIAS_WEAK(strlen, __pi_strlen)
EXPORT_SYMBOL_NOKASAN(strlen)
diff --git a/arch/arm64/lib/strncmp.S b/arch/arm64/lib/strncmp.S
index e42bcfcd37e6..fe7bbc0b42a7 100644
--- a/arch/arm64/lib/strncmp.S
+++ b/arch/arm64/lib/strncmp.S
@@ -1,9 +1,9 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
- * Copyright (c) 2013-2021, Arm Limited.
+ * Copyright (c) 2013-2022, Arm Limited.
*
* Adapted from the original at:
- * https://github.com/ARM-software/optimized-routines/blob/e823e3abf5f89ecb/string/aarch64/strncmp.S
+ * https://github.com/ARM-software/optimized-routines/blob/189dfefe37d54c5b/string/aarch64/strncmp.S
*/
#include <linux/linkage.h>
@@ -11,14 +11,14 @@
/* Assumptions:
*
- * ARMv8-a, AArch64
+ * ARMv8-a, AArch64.
+ * MTE compatible.
*/
#define L(label) .L ## label
#define REP8_01 0x0101010101010101
#define REP8_7f 0x7f7f7f7f7f7f7f7f
-#define REP8_80 0x8080808080808080
/* Parameters and result. */
#define src1 x0
@@ -39,12 +39,26 @@
#define tmp3 x10
#define zeroones x11
#define pos x12
-#define limit_wd x13
-#define mask x14
-#define endloop x15
+#define mask x13
+#define endloop x14
#define count mask
+#define offset pos
+#define neg_offset x15
-SYM_FUNC_START_WEAK_PI(strncmp)
+/* Define endian dependent shift operations.
+ On big-endian early bytes are at MSB and on little-endian LSB.
+ LS_FW means shifting towards early bytes.
+ LS_BK means shifting towards later bytes.
+ */
+#ifdef __AARCH64EB__
+#define LS_FW lsl
+#define LS_BK lsr
+#else
+#define LS_FW lsr
+#define LS_BK lsl
+#endif
+
+SYM_FUNC_START(__pi_strncmp)
cbz limit, L(ret0)
eor tmp1, src1, src2
mov zeroones, #REP8_01
@@ -52,9 +66,6 @@ SYM_FUNC_START_WEAK_PI(strncmp)
and count, src1, #7
b.ne L(misaligned8)
cbnz count, L(mutual_align)
- /* Calculate the number of full and partial words -1. */
- sub limit_wd, limit, #1 /* limit != 0, so no underflow. */
- lsr limit_wd, limit_wd, #3 /* Convert to Dwords. */
/* NUL detection works on the principle that (X - 1) & (~X) & 0x80
(=> (X - 1) & ~(X | 0x7f)) is non-zero iff a byte is zero, and
@@ -64,56 +75,52 @@ L(loop_aligned):
ldr data1, [src1], #8
ldr data2, [src2], #8
L(start_realigned):
- subs limit_wd, limit_wd, #1
+ subs limit, limit, #8
sub tmp1, data1, zeroones
orr tmp2, data1, #REP8_7f
eor diff, data1, data2 /* Non-zero if differences found. */
- csinv endloop, diff, xzr, pl /* Last Dword or differences. */
+ csinv endloop, diff, xzr, hi /* Last Dword or differences. */
bics has_nul, tmp1, tmp2 /* Non-zero if NUL terminator. */
ccmp endloop, #0, #0, eq
b.eq L(loop_aligned)
/* End of main loop */
- /* Not reached the limit, must have found the end or a diff. */
- tbz limit_wd, #63, L(not_limit)
-
- /* Limit % 8 == 0 => all bytes significant. */
- ands limit, limit, #7
- b.eq L(not_limit)
-
- lsl limit, limit, #3 /* Bits -> bytes. */
- mov mask, #~0
-#ifdef __AARCH64EB__
- lsr mask, mask, limit
-#else
- lsl mask, mask, limit
-#endif
- bic data1, data1, mask
- bic data2, data2, mask
-
- /* Make sure that the NUL byte is marked in the syndrome. */
- orr has_nul, has_nul, mask
-
-L(not_limit):
+L(full_check):
+#ifndef __AARCH64EB__
orr syndrome, diff, has_nul
-
-#ifndef __AARCH64EB__
+ add limit, limit, 8 /* Rewind limit to before last subs. */
+L(syndrome_check):
+ /* Limit was reached. Check if the NUL byte or the difference
+ is before the limit. */
rev syndrome, syndrome
rev data1, data1
- /* The MS-non-zero bit of the syndrome marks either the first bit
- that is different, or the top bit of the first zero byte.
- Shifting left now will bring the critical information into the
- top bits. */
clz pos, syndrome
rev data2, data2
lsl data1, data1, pos
+ cmp limit, pos, lsr #3
lsl data2, data2, pos
/* But we need to zero-extend (char is unsigned) the value and then
perform a signed 32-bit subtraction. */
lsr data1, data1, #56
sub result, data1, data2, lsr #56
+ csel result, result, xzr, hi
ret
#else
+ /* Not reached the limit, must have found the end or a diff. */
+ tbz limit, #63, L(not_limit)
+ add tmp1, limit, 8
+ cbz limit, L(not_limit)
+
+ lsl limit, tmp1, #3 /* Bits -> bytes. */
+ mov mask, #~0
+ lsr mask, mask, limit
+ bic data1, data1, mask
+ bic data2, data2, mask
+
+ /* Make sure that the NUL byte is marked in the syndrome. */
+ orr has_nul, has_nul, mask
+
+L(not_limit):
/* For big-endian we cannot use the trick with the syndrome value
as carry-propagation can corrupt the upper bits if the trailing
bytes in the string contain 0x01. */
@@ -134,10 +141,11 @@ L(not_limit):
rev has_nul, has_nul
orr syndrome, diff, has_nul
clz pos, syndrome
- /* The MS-non-zero bit of the syndrome marks either the first bit
- that is different, or the top bit of the first zero byte.
+ /* The most-significant-non-zero bit of the syndrome marks either the
+ first bit that is different, or the top bit of the first zero byte.
Shifting left now will bring the critical information into the
top bits. */
+L(end_quick):
lsl data1, data1, pos
lsl data2, data2, pos
/* But we need to zero-extend (char is unsigned) the value and then
@@ -159,22 +167,12 @@ L(mutual_align):
neg tmp3, count, lsl #3 /* 64 - bits(bytes beyond align). */
ldr data2, [src2], #8
mov tmp2, #~0
- sub limit_wd, limit, #1 /* limit != 0, so no underflow. */
-#ifdef __AARCH64EB__
- /* Big-endian. Early bytes are at MSB. */
- lsl tmp2, tmp2, tmp3 /* Shift (count & 63). */
-#else
- /* Little-endian. Early bytes are at LSB. */
- lsr tmp2, tmp2, tmp3 /* Shift (count & 63). */
-#endif
- and tmp3, limit_wd, #7
- lsr limit_wd, limit_wd, #3
- /* Adjust the limit. Only low 3 bits used, so overflow irrelevant. */
- add limit, limit, count
- add tmp3, tmp3, count
+ LS_FW tmp2, tmp2, tmp3 /* Shift (count & 63). */
+ /* Adjust the limit and ensure it doesn't overflow. */
+ adds limit, limit, count
+ csinv limit, limit, xzr, lo
orr data1, data1, tmp2
orr data2, data2, tmp2
- add limit_wd, limit_wd, tmp3, lsr #3
b L(start_realigned)
.p2align 4
@@ -197,13 +195,11 @@ L(done):
/* Align the SRC1 to a dword by doing a bytewise compare and then do
the dword loop. */
L(try_misaligned_words):
- lsr limit_wd, limit, #3
- cbz count, L(do_misaligned)
+ cbz count, L(src1_aligned)
neg count, count
and count, count, #7
sub limit, limit, count
- lsr limit_wd, limit, #3
L(page_end_loop):
ldrb data1w, [src1], #1
@@ -214,48 +210,101 @@ L(page_end_loop):
subs count, count, #1
b.hi L(page_end_loop)
-L(do_misaligned):
- /* Prepare ourselves for the next page crossing. Unlike the aligned
- loop, we fetch 1 less dword because we risk crossing bounds on
- SRC2. */
- mov count, #8
- subs limit_wd, limit_wd, #1
- b.lo L(done_loop)
-L(loop_misaligned):
- and tmp2, src2, #0xff8
- eor tmp2, tmp2, #0xff8
- cbz tmp2, L(page_end_loop)
+ /* The following diagram explains the comparison of misaligned strings.
+ The bytes are shown in natural order. For little-endian, it is
+ reversed in the registers. The "x" bytes are before the string.
+ The "|" separates data that is loaded at one time.
+ src1 | a a a a a a a a | b b b c c c c c | . . .
+ src2 | x x x x x a a a a a a a a b b b | c c c c c . . .
+
+ After shifting in each step, the data looks like this:
+ STEP_A STEP_B STEP_C
+ data1 a a a a a a a a b b b c c c c c b b b c c c c c
+ data2 a a a a a a a a b b b 0 0 0 0 0 0 0 0 c c c c c
+ The bytes with "0" are eliminated from the syndrome via mask.
+
+ Align SRC2 down to 16 bytes. This way we can read 16 bytes at a
+ time from SRC2. The comparison happens in 3 steps. After each step
+ the loop can exit, or read from SRC1 or SRC2. */
+L(src1_aligned):
+ /* Calculate offset from 8 byte alignment to string start in bits. No
+ need to mask offset since shifts are ignoring upper bits. */
+ lsl offset, src2, #3
+ bic src2, src2, #0xf
+ mov mask, -1
+ neg neg_offset, offset
ldr data1, [src1], #8
- ldr data2, [src2], #8
- sub tmp1, data1, zeroones
- orr tmp2, data1, #REP8_7f
- eor diff, data1, data2 /* Non-zero if differences found. */
- bics has_nul, tmp1, tmp2 /* Non-zero if NUL terminator. */
- ccmp diff, #0, #0, eq
- b.ne L(not_limit)
- subs limit_wd, limit_wd, #1
- b.pl L(loop_misaligned)
+ ldp tmp1, tmp2, [src2], #16
+ LS_BK mask, mask, neg_offset
+ and neg_offset, neg_offset, #63 /* Need actual value for cmp later. */
+ /* Skip the first compare if data in tmp1 is irrelevant. */
+ tbnz offset, 6, L(misaligned_mid_loop)
-L(done_loop):
- /* We found a difference or a NULL before the limit was reached. */
- and limit, limit, #7
- cbz limit, L(not_limit)
- /* Read the last word. */
- sub src1, src1, 8
- sub src2, src2, 8
- ldr data1, [src1, limit]
- ldr data2, [src2, limit]
- sub tmp1, data1, zeroones
- orr tmp2, data1, #REP8_7f
+L(loop_misaligned):
+ /* STEP_A: Compare full 8 bytes when there is enough data from SRC2.*/
+ LS_FW data2, tmp1, offset
+ LS_BK tmp1, tmp2, neg_offset
+ subs limit, limit, #8
+ orr data2, data2, tmp1 /* 8 bytes from SRC2 combined from two regs.*/
+ sub has_nul, data1, zeroones
eor diff, data1, data2 /* Non-zero if differences found. */
- bics has_nul, tmp1, tmp2 /* Non-zero if NUL terminator. */
- ccmp diff, #0, #0, eq
- b.ne L(not_limit)
+ orr tmp3, data1, #REP8_7f
+ csinv endloop, diff, xzr, hi /* If limit, set to all ones. */
+ bic has_nul, has_nul, tmp3 /* Non-zero if NUL byte found in SRC1. */
+ orr tmp3, endloop, has_nul
+ cbnz tmp3, L(full_check)
+
+ ldr data1, [src1], #8
+L(misaligned_mid_loop):
+ /* STEP_B: Compare first part of data1 to second part of tmp2. */
+ LS_FW data2, tmp2, offset
+#ifdef __AARCH64EB__
+ /* For big-endian we do a byte reverse to avoid carry-propagation
+ problem described above. This way we can reuse the has_nul in the
+ next step and also use syndrome value trick at the end. */
+ rev tmp3, data1
+ #define data1_fixed tmp3
+#else
+ #define data1_fixed data1
+#endif
+ sub has_nul, data1_fixed, zeroones
+ orr tmp3, data1_fixed, #REP8_7f
+ eor diff, data2, data1 /* Non-zero if differences found. */
+ bic has_nul, has_nul, tmp3 /* Non-zero if NUL terminator. */
+#ifdef __AARCH64EB__
+ rev has_nul, has_nul
+#endif
+ cmp limit, neg_offset, lsr #3
+ orr syndrome, diff, has_nul
+ bic syndrome, syndrome, mask /* Ignore later bytes. */
+ csinv tmp3, syndrome, xzr, hi /* If limit, set to all ones. */
+ cbnz tmp3, L(syndrome_check)
+
+ /* STEP_C: Compare second part of data1 to first part of tmp1. */
+ ldp tmp1, tmp2, [src2], #16
+ cmp limit, #8
+ LS_BK data2, tmp1, neg_offset
+ eor diff, data2, data1 /* Non-zero if differences found. */
+ orr syndrome, diff, has_nul
+ and syndrome, syndrome, mask /* Ignore earlier bytes. */
+ csinv tmp3, syndrome, xzr, hi /* If limit, set to all ones. */
+ cbnz tmp3, L(syndrome_check)
+
+ ldr data1, [src1], #8
+ sub limit, limit, #8
+ b L(loop_misaligned)
+
+#ifdef __AARCH64EB__
+L(syndrome_check):
+ clz pos, syndrome
+ cmp pos, limit, lsl #3
+ b.lo L(end_quick)
+#endif
L(ret0):
mov result, #0
ret
-
-SYM_FUNC_END_PI(strncmp)
-EXPORT_SYMBOL_NOHWKASAN(strncmp)
+SYM_FUNC_END(__pi_strncmp)
+SYM_FUNC_ALIAS_WEAK(strncmp, __pi_strncmp)
+EXPORT_SYMBOL_NOKASAN(strncmp)
diff --git a/arch/arm64/lib/strnlen.S b/arch/arm64/lib/strnlen.S
index b72913a99038..d5ac0e10a01d 100644
--- a/arch/arm64/lib/strnlen.S
+++ b/arch/arm64/lib/strnlen.S
@@ -47,7 +47,7 @@ limit_wd .req x14
#define REP8_7f 0x7f7f7f7f7f7f7f7f
#define REP8_80 0x8080808080808080
-SYM_FUNC_START_WEAK_PI(strnlen)
+SYM_FUNC_START(__pi_strnlen)
cbz limit, .Lhit_limit
mov zeroones, #REP8_01
bic src, srcin, #15
@@ -156,5 +156,7 @@ CPU_LE( lsr tmp2, tmp2, tmp4 ) /* Shift (tmp1 & 63). */
.Lhit_limit:
mov len, limit
ret
-SYM_FUNC_END_PI(strnlen)
+SYM_FUNC_END(__pi_strnlen)
+
+SYM_FUNC_ALIAS_WEAK(strnlen, __pi_strnlen)
EXPORT_SYMBOL_NOKASAN(strnlen)
diff --git a/arch/arm64/lib/strrchr.S b/arch/arm64/lib/strrchr.S
index 13132d1ed6d1..a5123cf0ce12 100644
--- a/arch/arm64/lib/strrchr.S
+++ b/arch/arm64/lib/strrchr.S
@@ -18,7 +18,7 @@
* Returns:
* x0 - address of last occurrence of 'c' or 0
*/
-SYM_FUNC_START_WEAK_PI(strrchr)
+SYM_FUNC_START(__pi_strrchr)
mov x3, #0
and w1, w1, #0xff
1: ldrb w2, [x0], #1
@@ -29,5 +29,6 @@ SYM_FUNC_START_WEAK_PI(strrchr)
b 1b
2: mov x0, x3
ret
-SYM_FUNC_END_PI(strrchr)
+SYM_FUNC_END(__pi_strrchr)
+SYM_FUNC_ALIAS_WEAK(strrchr, __pi_strrchr)
EXPORT_SYMBOL_NOKASAN(strrchr)
diff --git a/arch/arm64/lib/xor-neon.c b/arch/arm64/lib/xor-neon.c
index d189cf4e70ea..96b171995d19 100644
--- a/arch/arm64/lib/xor-neon.c
+++ b/arch/arm64/lib/xor-neon.c
@@ -10,8 +10,8 @@
#include <linux/module.h>
#include <asm/neon-intrinsics.h>
-void xor_arm64_neon_2(unsigned long bytes, unsigned long *p1,
- unsigned long *p2)
+void xor_arm64_neon_2(unsigned long bytes, unsigned long * __restrict p1,
+ const unsigned long * __restrict p2)
{
uint64_t *dp1 = (uint64_t *)p1;
uint64_t *dp2 = (uint64_t *)p2;
@@ -37,8 +37,9 @@ void xor_arm64_neon_2(unsigned long bytes, unsigned long *p1,
} while (--lines > 0);
}
-void xor_arm64_neon_3(unsigned long bytes, unsigned long *p1,
- unsigned long *p2, unsigned long *p3)
+void xor_arm64_neon_3(unsigned long bytes, unsigned long * __restrict p1,
+ const unsigned long * __restrict p2,
+ const unsigned long * __restrict p3)
{
uint64_t *dp1 = (uint64_t *)p1;
uint64_t *dp2 = (uint64_t *)p2;
@@ -72,8 +73,10 @@ void xor_arm64_neon_3(unsigned long bytes, unsigned long *p1,
} while (--lines > 0);
}
-void xor_arm64_neon_4(unsigned long bytes, unsigned long *p1,
- unsigned long *p2, unsigned long *p3, unsigned long *p4)
+void xor_arm64_neon_4(unsigned long bytes, unsigned long * __restrict p1,
+ const unsigned long * __restrict p2,
+ const unsigned long * __restrict p3,
+ const unsigned long * __restrict p4)
{
uint64_t *dp1 = (uint64_t *)p1;
uint64_t *dp2 = (uint64_t *)p2;
@@ -115,9 +118,11 @@ void xor_arm64_neon_4(unsigned long bytes, unsigned long *p1,
} while (--lines > 0);
}
-void xor_arm64_neon_5(unsigned long bytes, unsigned long *p1,
- unsigned long *p2, unsigned long *p3,
- unsigned long *p4, unsigned long *p5)
+void xor_arm64_neon_5(unsigned long bytes, unsigned long * __restrict p1,
+ const unsigned long * __restrict p2,
+ const unsigned long * __restrict p3,
+ const unsigned long * __restrict p4,
+ const unsigned long * __restrict p5)
{
uint64_t *dp1 = (uint64_t *)p1;
uint64_t *dp2 = (uint64_t *)p2;
@@ -186,8 +191,10 @@ static inline uint64x2_t eor3(uint64x2_t p, uint64x2_t q, uint64x2_t r)
return res;
}
-static void xor_arm64_eor3_3(unsigned long bytes, unsigned long *p1,
- unsigned long *p2, unsigned long *p3)
+static void xor_arm64_eor3_3(unsigned long bytes,
+ unsigned long * __restrict p1,
+ const unsigned long * __restrict p2,
+ const unsigned long * __restrict p3)
{
uint64_t *dp1 = (uint64_t *)p1;
uint64_t *dp2 = (uint64_t *)p2;
@@ -219,9 +226,11 @@ static void xor_arm64_eor3_3(unsigned long bytes, unsigned long *p1,
} while (--lines > 0);
}
-static void xor_arm64_eor3_4(unsigned long bytes, unsigned long *p1,
- unsigned long *p2, unsigned long *p3,
- unsigned long *p4)
+static void xor_arm64_eor3_4(unsigned long bytes,
+ unsigned long * __restrict p1,
+ const unsigned long * __restrict p2,
+ const unsigned long * __restrict p3,
+ const unsigned long * __restrict p4)
{
uint64_t *dp1 = (uint64_t *)p1;
uint64_t *dp2 = (uint64_t *)p2;
@@ -261,9 +270,12 @@ static void xor_arm64_eor3_4(unsigned long bytes, unsigned long *p1,
} while (--lines > 0);
}
-static void xor_arm64_eor3_5(unsigned long bytes, unsigned long *p1,
- unsigned long *p2, unsigned long *p3,
- unsigned long *p4, unsigned long *p5)
+static void xor_arm64_eor3_5(unsigned long bytes,
+ unsigned long * __restrict p1,
+ const unsigned long * __restrict p2,
+ const unsigned long * __restrict p3,
+ const unsigned long * __restrict p4,
+ const unsigned long * __restrict p5)
{
uint64_t *dp1 = (uint64_t *)p1;
uint64_t *dp2 = (uint64_t *)p2;
diff --git a/arch/arm64/mm/cache.S b/arch/arm64/mm/cache.S
index 7d0563db4201..0ea6cc25dc66 100644
--- a/arch/arm64/mm/cache.S
+++ b/arch/arm64/mm/cache.S
@@ -107,10 +107,11 @@ SYM_FUNC_END(icache_inval_pou)
* - start - virtual start address of region
* - end - virtual end address of region
*/
-SYM_FUNC_START_PI(dcache_clean_inval_poc)
+SYM_FUNC_START(__pi_dcache_clean_inval_poc)
dcache_by_line_op civac, sy, x0, x1, x2, x3
ret
-SYM_FUNC_END_PI(dcache_clean_inval_poc)
+SYM_FUNC_END(__pi_dcache_clean_inval_poc)
+SYM_FUNC_ALIAS(dcache_clean_inval_poc, __pi_dcache_clean_inval_poc)
/*
* dcache_clean_pou(start, end)
@@ -140,7 +141,7 @@ SYM_FUNC_END(dcache_clean_pou)
* - start - kernel start address of region
* - end - kernel end address of region
*/
-SYM_FUNC_START_PI(dcache_inval_poc)
+SYM_FUNC_START(__pi_dcache_inval_poc)
dcache_line_size x2, x3
sub x3, x2, #1
tst x1, x3 // end cache line aligned?
@@ -158,7 +159,8 @@ SYM_FUNC_START_PI(dcache_inval_poc)
b.lo 2b
dsb sy
ret
-SYM_FUNC_END_PI(dcache_inval_poc)
+SYM_FUNC_END(__pi_dcache_inval_poc)
+SYM_FUNC_ALIAS(dcache_inval_poc, __pi_dcache_inval_poc)
/*
* dcache_clean_poc(start, end)
@@ -169,10 +171,11 @@ SYM_FUNC_END_PI(dcache_inval_poc)
* - start - virtual start address of region
* - end - virtual end address of region
*/
-SYM_FUNC_START_PI(dcache_clean_poc)
+SYM_FUNC_START(__pi_dcache_clean_poc)
dcache_by_line_op cvac, sy, x0, x1, x2, x3
ret
-SYM_FUNC_END_PI(dcache_clean_poc)
+SYM_FUNC_END(__pi_dcache_clean_poc)
+SYM_FUNC_ALIAS(dcache_clean_poc, __pi_dcache_clean_poc)
/*
* dcache_clean_pop(start, end)
@@ -183,13 +186,14 @@ SYM_FUNC_END_PI(dcache_clean_poc)
* - start - virtual start address of region
* - end - virtual end address of region
*/
-SYM_FUNC_START_PI(dcache_clean_pop)
+SYM_FUNC_START(__pi_dcache_clean_pop)
alternative_if_not ARM64_HAS_DCPOP
b dcache_clean_poc
alternative_else_nop_endif
dcache_by_line_op cvap, sy, x0, x1, x2, x3
ret
-SYM_FUNC_END_PI(dcache_clean_pop)
+SYM_FUNC_END(__pi_dcache_clean_pop)
+SYM_FUNC_ALIAS(dcache_clean_pop, __pi_dcache_clean_pop)
/*
* __dma_flush_area(start, size)
@@ -199,11 +203,12 @@ SYM_FUNC_END_PI(dcache_clean_pop)
* - start - virtual start address of region
* - size - size in question
*/
-SYM_FUNC_START_PI(__dma_flush_area)
+SYM_FUNC_START(__pi___dma_flush_area)
add x1, x0, x1
dcache_by_line_op civac, sy, x0, x1, x2, x3
ret
-SYM_FUNC_END_PI(__dma_flush_area)
+SYM_FUNC_END(__pi___dma_flush_area)
+SYM_FUNC_ALIAS(__dma_flush_area, __pi___dma_flush_area)
/*
* __dma_map_area(start, size, dir)
@@ -211,12 +216,13 @@ SYM_FUNC_END_PI(__dma_flush_area)
* - size - size of region
* - dir - DMA direction
*/
-SYM_FUNC_START_PI(__dma_map_area)
+SYM_FUNC_START(__pi___dma_map_area)
add x1, x0, x1
cmp w2, #DMA_FROM_DEVICE
b.eq __pi_dcache_inval_poc
b __pi_dcache_clean_poc
-SYM_FUNC_END_PI(__dma_map_area)
+SYM_FUNC_END(__pi___dma_map_area)
+SYM_FUNC_ALIAS(__dma_map_area, __pi___dma_map_area)
/*
* __dma_unmap_area(start, size, dir)
@@ -224,9 +230,10 @@ SYM_FUNC_END_PI(__dma_map_area)
* - size - size of region
* - dir - DMA direction
*/
-SYM_FUNC_START_PI(__dma_unmap_area)
+SYM_FUNC_START(__pi___dma_unmap_area)
add x1, x0, x1
cmp w2, #DMA_TO_DEVICE
b.ne __pi_dcache_inval_poc
ret
-SYM_FUNC_END_PI(__dma_unmap_area)
+SYM_FUNC_END(__pi___dma_unmap_area)
+SYM_FUNC_ALIAS(__dma_unmap_area, __pi___dma_unmap_area)
diff --git a/arch/arm64/mm/extable.c b/arch/arm64/mm/extable.c
index c0181e60cc98..489455309695 100644
--- a/arch/arm64/mm/extable.c
+++ b/arch/arm64/mm/extable.c
@@ -40,8 +40,8 @@ static bool
ex_handler_load_unaligned_zeropad(const struct exception_table_entry *ex,
struct pt_regs *regs)
{
- int reg_data = FIELD_GET(EX_DATA_REG_DATA, ex->type);
- int reg_addr = FIELD_GET(EX_DATA_REG_ADDR, ex->type);
+ int reg_data = FIELD_GET(EX_DATA_REG_DATA, ex->data);
+ int reg_addr = FIELD_GET(EX_DATA_REG_ADDR, ex->data);
unsigned long data, addr, offset;
addr = pt_regs_read_reg(regs, reg_addr);
diff --git a/arch/arm64/mm/flush.c b/arch/arm64/mm/flush.c
index 2aaf950b906c..a06c6ac770d4 100644
--- a/arch/arm64/mm/flush.c
+++ b/arch/arm64/mm/flush.c
@@ -52,6 +52,13 @@ void __sync_icache_dcache(pte_t pte)
{
struct page *page = pte_page(pte);
+ /*
+ * HugeTLB pages are always fully mapped, so only setting head page's
+ * PG_dcache_clean flag is enough.
+ */
+ if (PageHuge(page))
+ page = compound_head(page);
+
if (!test_bit(PG_dcache_clean, &page->flags)) {
sync_icache_aliases((unsigned long)page_address(page),
(unsigned long)page_address(page) +
diff --git a/arch/arm64/mm/hugetlbpage.c b/arch/arm64/mm/hugetlbpage.c
index ffb9c229610a..cbace1c9e137 100644
--- a/arch/arm64/mm/hugetlbpage.c
+++ b/arch/arm64/mm/hugetlbpage.c
@@ -56,25 +56,34 @@ void __init arm64_hugetlb_cma_reserve(void)
}
#endif /* CONFIG_CMA */
-#ifdef CONFIG_ARCH_ENABLE_HUGEPAGE_MIGRATION
-bool arch_hugetlb_migration_supported(struct hstate *h)
+static bool __hugetlb_valid_size(unsigned long size)
{
- size_t pagesize = huge_page_size(h);
-
- switch (pagesize) {
+ switch (size) {
#ifndef __PAGETABLE_PMD_FOLDED
case PUD_SIZE:
return pud_sect_supported();
#endif
- case PMD_SIZE:
case CONT_PMD_SIZE:
+ case PMD_SIZE:
case CONT_PTE_SIZE:
return true;
}
- pr_warn("%s: unrecognized huge page size 0x%lx\n",
- __func__, pagesize);
+
return false;
}
+
+#ifdef CONFIG_ARCH_ENABLE_HUGEPAGE_MIGRATION
+bool arch_hugetlb_migration_supported(struct hstate *h)
+{
+ size_t pagesize = huge_page_size(h);
+
+ if (!__hugetlb_valid_size(pagesize)) {
+ pr_warn("%s: unrecognized huge page size 0x%lx\n",
+ __func__, pagesize);
+ return false;
+ }
+ return true;
+}
#endif
int pmd_huge(pmd_t pmd)
@@ -347,6 +356,7 @@ pte_t arch_make_huge_pte(pte_t entry, unsigned int shift, vm_flags_t flags)
{
size_t pagesize = 1UL << shift;
+ entry = pte_mkhuge(entry);
if (pagesize == CONT_PTE_SIZE) {
entry = pte_mkcont(entry);
} else if (pagesize == CONT_PMD_SIZE) {
@@ -506,16 +516,5 @@ arch_initcall(hugetlbpage_init);
bool __init arch_hugetlb_valid_size(unsigned long size)
{
- switch (size) {
-#ifndef __PAGETABLE_PMD_FOLDED
- case PUD_SIZE:
- return pud_sect_supported();
-#endif
- case CONT_PMD_SIZE:
- case PMD_SIZE:
- case CONT_PTE_SIZE:
- return true;
- }
-
- return false;
+ return __hugetlb_valid_size(size);
}
diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
index db63cc885771..8ac25f19084e 100644
--- a/arch/arm64/mm/init.c
+++ b/arch/arm64/mm/init.c
@@ -61,10 +61,35 @@ EXPORT_SYMBOL(memstart_addr);
* unless restricted on specific platforms (e.g. 30-bit on Raspberry Pi 4).
* In such case, ZONE_DMA32 covers the rest of the 32-bit addressable memory,
* otherwise it is empty.
+ *
+ * Memory reservation for crash kernel either done early or deferred
+ * depending on DMA memory zones configs (ZONE_DMA) --
+ *
+ * In absence of ZONE_DMA configs arm64_dma_phys_limit initialized
+ * here instead of max_zone_phys(). This lets early reservation of
+ * crash kernel memory which has a dependency on arm64_dma_phys_limit.
+ * Reserving memory early for crash kernel allows linear creation of block
+ * mappings (greater than page-granularity) for all the memory bank rangs.
+ * In this scheme a comparatively quicker boot is observed.
+ *
+ * If ZONE_DMA configs are defined, crash kernel memory reservation
+ * is delayed until DMA zone memory range size initilazation performed in
+ * zone_sizes_init(). The defer is necessary to steer clear of DMA zone
+ * memory range to avoid overlap allocation. So crash kernel memory boundaries
+ * are not known when mapping all bank memory ranges, which otherwise means
+ * not possible to exclude crash kernel range from creating block mappings
+ * so page-granularity mappings are created for the entire memory range.
+ * Hence a slightly slower boot is observed.
+ *
+ * Note: Page-granularity mapppings are necessary for crash kernel memory
+ * range for shrinking its size via /sys/kernel/kexec_crash_size interface.
*/
-phys_addr_t arm64_dma_phys_limit __ro_after_init;
+#if IS_ENABLED(CONFIG_ZONE_DMA) || IS_ENABLED(CONFIG_ZONE_DMA32)
+phys_addr_t __ro_after_init arm64_dma_phys_limit;
+#else
+phys_addr_t __ro_after_init arm64_dma_phys_limit = PHYS_MASK + 1;
+#endif
-#ifdef CONFIG_KEXEC_CORE
/*
* reserve_crashkernel() - reserves memory for crash kernel
*
@@ -78,6 +103,9 @@ static void __init reserve_crashkernel(void)
unsigned long long crash_max = arm64_dma_phys_limit;
int ret;
+ if (!IS_ENABLED(CONFIG_KEXEC_CORE))
+ return;
+
ret = parse_crashkernel(boot_command_line, memblock_phys_mem_size(),
&crash_size, &crash_base);
/* no crashkernel= or invalid value specified */
@@ -110,11 +138,6 @@ static void __init reserve_crashkernel(void)
crashk_res.start = crash_base;
crashk_res.end = crash_base + crash_size - 1;
}
-#else
-static void __init reserve_crashkernel(void)
-{
-}
-#endif /* CONFIG_KEXEC_CORE */
/*
* Return the maximum physical address for a zone accessible by the given bits
@@ -153,8 +176,6 @@ static void __init zone_sizes_init(unsigned long min, unsigned long max)
if (!arm64_dma_phys_limit)
arm64_dma_phys_limit = dma32_phys_limit;
#endif
- if (!arm64_dma_phys_limit)
- arm64_dma_phys_limit = PHYS_MASK + 1;
max_zone_pfns[ZONE_NORMAL] = max;
free_area_init(max_zone_pfns);
@@ -315,6 +336,9 @@ void __init arm64_memblock_init(void)
early_init_fdt_scan_reserved_mem();
+ if (!IS_ENABLED(CONFIG_ZONE_DMA) && !IS_ENABLED(CONFIG_ZONE_DMA32))
+ reserve_crashkernel();
+
high_memory = __va(memblock_end_of_DRAM() - 1) + 1;
}
@@ -361,7 +385,8 @@ void __init bootmem_init(void)
* request_standard_resources() depends on crashkernel's memory being
* reserved, so do it here.
*/
- reserve_crashkernel();
+ if (IS_ENABLED(CONFIG_ZONE_DMA) || IS_ENABLED(CONFIG_ZONE_DMA32))
+ reserve_crashkernel();
memblock_dump_all();
}
diff --git a/arch/arm64/mm/mmap.c b/arch/arm64/mm/mmap.c
index a38f54cd638c..77ada00280d9 100644
--- a/arch/arm64/mm/mmap.c
+++ b/arch/arm64/mm/mmap.c
@@ -7,8 +7,10 @@
#include <linux/io.h>
#include <linux/memblock.h>
+#include <linux/mm.h>
#include <linux/types.h>
+#include <asm/cpufeature.h>
#include <asm/page.h>
/*
@@ -38,3 +40,18 @@ int valid_mmap_phys_addr_range(unsigned long pfn, size_t size)
{
return !(((pfn << PAGE_SHIFT) + size) & ~PHYS_MASK);
}
+
+static int __init adjust_protection_map(void)
+{
+ /*
+ * With Enhanced PAN we can honour the execute-only permissions as
+ * there is no PAN override with such mappings.
+ */
+ if (cpus_have_const_cap(ARM64_HAS_EPAN)) {
+ protection_map[VM_EXEC] = PAGE_EXECONLY;
+ protection_map[VM_EXEC | VM_SHARED] = PAGE_EXECONLY;
+ }
+
+ return 0;
+}
+arch_initcall(adjust_protection_map);
diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
index acfae9b41cc8..626ec32873c6 100644
--- a/arch/arm64/mm/mmu.c
+++ b/arch/arm64/mm/mmu.c
@@ -17,6 +17,7 @@
#include <linux/mman.h>
#include <linux/nodemask.h>
#include <linux/memblock.h>
+#include <linux/memremap.h>
#include <linux/memory.h>
#include <linux/fs.h>
#include <linux/io.h>
@@ -63,6 +64,7 @@ static pmd_t bm_pmd[PTRS_PER_PMD] __page_aligned_bss __maybe_unused;
static pud_t bm_pud[PTRS_PER_PUD] __page_aligned_bss __maybe_unused;
static DEFINE_SPINLOCK(swapper_pgdir_lock);
+static DEFINE_MUTEX(fixmap_lock);
void set_swapper_pgd(pgd_t *pgdp, pgd_t pgd)
{
@@ -294,18 +296,6 @@ static void alloc_init_cont_pmd(pud_t *pudp, unsigned long addr,
} while (addr = next, addr != end);
}
-static inline bool use_1G_block(unsigned long addr, unsigned long next,
- unsigned long phys)
-{
- if (PAGE_SHIFT != 12)
- return false;
-
- if (((addr | next | phys) & ~PUD_MASK) != 0)
- return false;
-
- return true;
-}
-
static void alloc_init_pud(pgd_t *pgdp, unsigned long addr, unsigned long end,
phys_addr_t phys, pgprot_t prot,
phys_addr_t (*pgtable_alloc)(int),
@@ -329,6 +319,12 @@ static void alloc_init_pud(pgd_t *pgdp, unsigned long addr, unsigned long end,
}
BUG_ON(p4d_bad(p4d));
+ /*
+ * No need for locking during early boot. And it doesn't work as
+ * expected with KASLR enabled.
+ */
+ if (system_state != SYSTEM_BOOTING)
+ mutex_lock(&fixmap_lock);
pudp = pud_set_fixmap_offset(p4dp, addr);
do {
pud_t old_pud = READ_ONCE(*pudp);
@@ -338,7 +334,8 @@ static void alloc_init_pud(pgd_t *pgdp, unsigned long addr, unsigned long end,
/*
* For 4K granule only, attempt to put down a 1GB block
*/
- if (use_1G_block(addr, next, phys) &&
+ if (pud_sect_supported() &&
+ ((addr | next | phys) & ~PUD_MASK) == 0 &&
(flags & NO_BLOCK_MAPPINGS) == 0) {
pud_set_huge(pudp, phys, prot);
@@ -359,6 +356,8 @@ static void alloc_init_pud(pgd_t *pgdp, unsigned long addr, unsigned long end,
} while (pudp++, addr = next, addr != end);
pud_clear_fixmap();
+ if (system_state != SYSTEM_BOOTING)
+ mutex_unlock(&fixmap_lock);
}
static void __create_pgd_mapping(pgd_t *pgdir, phys_addr_t phys,
@@ -517,7 +516,7 @@ static void __init map_mem(pgd_t *pgdp)
*/
BUILD_BUG_ON(pgd_index(direct_map_end - 1) == pgd_index(direct_map_end));
- if (can_set_direct_map() || crash_mem_map || IS_ENABLED(CONFIG_KFENCE))
+ if (can_set_direct_map() || IS_ENABLED(CONFIG_KFENCE))
flags |= NO_BLOCK_MAPPINGS | NO_CONT_MAPPINGS;
/*
@@ -528,6 +527,17 @@ static void __init map_mem(pgd_t *pgdp)
*/
memblock_mark_nomap(kernel_start, kernel_end - kernel_start);
+#ifdef CONFIG_KEXEC_CORE
+ if (crash_mem_map) {
+ if (IS_ENABLED(CONFIG_ZONE_DMA) ||
+ IS_ENABLED(CONFIG_ZONE_DMA32))
+ flags |= NO_BLOCK_MAPPINGS | NO_CONT_MAPPINGS;
+ else if (crashk_res.end)
+ memblock_mark_nomap(crashk_res.start,
+ resource_size(&crashk_res));
+ }
+#endif
+
/* map all the memory banks */
for_each_mem_range(i, &start, &end) {
if (start >= end)
@@ -554,6 +564,25 @@ static void __init map_mem(pgd_t *pgdp)
__map_memblock(pgdp, kernel_start, kernel_end,
PAGE_KERNEL, NO_CONT_MAPPINGS);
memblock_clear_nomap(kernel_start, kernel_end - kernel_start);
+
+ /*
+ * Use page-level mappings here so that we can shrink the region
+ * in page granularity and put back unused memory to buddy system
+ * through /sys/kernel/kexec_crash_size interface.
+ */
+#ifdef CONFIG_KEXEC_CORE
+ if (crash_mem_map &&
+ !IS_ENABLED(CONFIG_ZONE_DMA) && !IS_ENABLED(CONFIG_ZONE_DMA32)) {
+ if (crashk_res.end) {
+ __map_memblock(pgdp, crashk_res.start,
+ crashk_res.end + 1,
+ PAGE_KERNEL,
+ NO_BLOCK_MAPPINGS | NO_CONT_MAPPINGS);
+ memblock_clear_nomap(crashk_res.start,
+ resource_size(&crashk_res));
+ }
+ }
+#endif
}
void mark_rodata_ro(void)
@@ -617,6 +646,8 @@ early_param("rodata", parse_rodata);
#ifdef CONFIG_UNMAP_KERNEL_AT_EL0
static int __init map_entry_trampoline(void)
{
+ int i;
+
pgprot_t prot = rodata_enabled ? PAGE_KERNEL_ROX : PAGE_KERNEL_EXEC;
phys_addr_t pa_start = __pa_symbol(__entry_tramp_text_start);
@@ -625,11 +656,15 @@ static int __init map_entry_trampoline(void)
/* Map only the text into the trampoline page table */
memset(tramp_pg_dir, 0, PGD_SIZE);
- __create_pgd_mapping(tramp_pg_dir, pa_start, TRAMP_VALIAS, PAGE_SIZE,
- prot, __pgd_pgtable_alloc, 0);
+ __create_pgd_mapping(tramp_pg_dir, pa_start, TRAMP_VALIAS,
+ entry_tramp_text_size(), prot,
+ __pgd_pgtable_alloc, NO_BLOCK_MAPPINGS);
/* Map both the text and data into the kernel page table */
- __set_fixmap(FIX_ENTRY_TRAMP_TEXT, pa_start, prot);
+ for (i = 0; i < DIV_ROUND_UP(entry_tramp_text_size(), PAGE_SIZE); i++)
+ __set_fixmap(FIX_ENTRY_TRAMP_TEXT1 - i,
+ pa_start + i * PAGE_SIZE, prot);
+
if (IS_ENABLED(CONFIG_RANDOMIZE_BASE)) {
extern char __entry_tramp_data_start[];
diff --git a/arch/arm64/mm/mteswap.c b/arch/arm64/mm/mteswap.c
index 7c4ef56265ee..a9e50e930484 100644
--- a/arch/arm64/mm/mteswap.c
+++ b/arch/arm64/mm/mteswap.c
@@ -12,7 +12,7 @@ static DEFINE_XARRAY(mte_pages);
void *mte_allocate_tag_storage(void)
{
/* tags granule is 16 bytes, 2 tags stored per byte */
- return kmalloc(PAGE_SIZE / 16 / 2, GFP_KERNEL);
+ return kmalloc(MTE_PAGE_TAG_STORAGE, GFP_KERNEL);
}
void mte_free_tag_storage(char *storage)
diff --git a/arch/arm64/mm/proc.S b/arch/arm64/mm/proc.S
index d35c90d2e47a..50bbed947bec 100644
--- a/arch/arm64/mm/proc.S
+++ b/arch/arm64/mm/proc.S
@@ -46,7 +46,7 @@
#endif
#ifdef CONFIG_KASAN_HW_TAGS
-#define TCR_MTE_FLAGS SYS_TCR_EL1_TCMA1 | TCR_TBI1 | TCR_TBID1
+#define TCR_MTE_FLAGS TCR_TCMA1 | TCR_TBI1 | TCR_TBID1
#else
/*
* The mte_zero_clear_page_tags() implementation uses DC GZVA, which relies on
diff --git a/arch/arm64/net/bpf_jit.h b/arch/arm64/net/bpf_jit.h
index cc0cf0f5c7c3..dd59b5ad8fe4 100644
--- a/arch/arm64/net/bpf_jit.h
+++ b/arch/arm64/net/bpf_jit.h
@@ -88,10 +88,42 @@
/* [Rn] = Rt; (atomic) Rs = [state] */
#define A64_STXR(sf, Rt, Rn, Rs) \
A64_LSX(sf, Rt, Rn, Rs, STORE_EX)
+/* [Rn] = Rt (store release); (atomic) Rs = [state] */
+#define A64_STLXR(sf, Rt, Rn, Rs) \
+ aarch64_insn_gen_load_store_ex(Rt, Rn, Rs, A64_SIZE(sf), \
+ AARCH64_INSN_LDST_STORE_REL_EX)
+
+/*
+ * LSE atomics
+ *
+ * ST{ADD,CLR,SET,EOR} is simply encoded as an alias for
+ * LDD{ADD,CLR,SET,EOR} with XZR as the destination register.
+ */
+#define A64_ST_OP(sf, Rn, Rs, op) \
+ aarch64_insn_gen_atomic_ld_op(A64_ZR, Rn, Rs, \
+ A64_SIZE(sf), AARCH64_INSN_MEM_ATOMIC_##op, \
+ AARCH64_INSN_MEM_ORDER_NONE)
+/* [Rn] <op>= Rs */
+#define A64_STADD(sf, Rn, Rs) A64_ST_OP(sf, Rn, Rs, ADD)
+#define A64_STCLR(sf, Rn, Rs) A64_ST_OP(sf, Rn, Rs, CLR)
+#define A64_STEOR(sf, Rn, Rs) A64_ST_OP(sf, Rn, Rs, EOR)
+#define A64_STSET(sf, Rn, Rs) A64_ST_OP(sf, Rn, Rs, SET)
-/* LSE atomics */
-#define A64_STADD(sf, Rn, Rs) \
- aarch64_insn_gen_stadd(Rn, Rs, A64_SIZE(sf))
+#define A64_LD_OP_AL(sf, Rt, Rn, Rs, op) \
+ aarch64_insn_gen_atomic_ld_op(Rt, Rn, Rs, \
+ A64_SIZE(sf), AARCH64_INSN_MEM_ATOMIC_##op, \
+ AARCH64_INSN_MEM_ORDER_ACQREL)
+/* Rt = [Rn] (load acquire); [Rn] <op>= Rs (store release) */
+#define A64_LDADDAL(sf, Rt, Rn, Rs) A64_LD_OP_AL(sf, Rt, Rn, Rs, ADD)
+#define A64_LDCLRAL(sf, Rt, Rn, Rs) A64_LD_OP_AL(sf, Rt, Rn, Rs, CLR)
+#define A64_LDEORAL(sf, Rt, Rn, Rs) A64_LD_OP_AL(sf, Rt, Rn, Rs, EOR)
+#define A64_LDSETAL(sf, Rt, Rn, Rs) A64_LD_OP_AL(sf, Rt, Rn, Rs, SET)
+/* Rt = [Rn] (load acquire); [Rn] = Rs (store release) */
+#define A64_SWPAL(sf, Rt, Rn, Rs) A64_LD_OP_AL(sf, Rt, Rn, Rs, SWP)
+/* Rs = CAS(Rn, Rs, Rt) (load acquire & store release) */
+#define A64_CASAL(sf, Rt, Rn, Rs) \
+ aarch64_insn_gen_cas(Rt, Rn, Rs, A64_SIZE(sf), \
+ AARCH64_INSN_MEM_ORDER_ACQREL)
/* Add/subtract (immediate) */
#define A64_ADDSUB_IMM(sf, Rd, Rn, imm12, type) \
@@ -196,6 +228,9 @@
#define A64_ANDS(sf, Rd, Rn, Rm) A64_LOGIC_SREG(sf, Rd, Rn, Rm, AND_SETFLAGS)
/* Rn & Rm; set condition flags */
#define A64_TST(sf, Rn, Rm) A64_ANDS(sf, A64_ZR, Rn, Rm)
+/* Rd = ~Rm (alias of ORN with A64_ZR as Rn) */
+#define A64_MVN(sf, Rd, Rm) \
+ A64_LOGIC_SREG(sf, Rd, A64_ZR, Rm, ORN)
/* Logical (immediate) */
#define A64_LOGIC_IMM(sf, Rd, Rn, imm, type) ({ \
@@ -219,4 +254,7 @@
#define A64_BTI_J A64_HINT(AARCH64_INSN_HINT_BTIJ)
#define A64_BTI_JC A64_HINT(AARCH64_INSN_HINT_BTIJC)
+/* DMB */
+#define A64_DMB_ISH aarch64_insn_gen_dmb(AARCH64_INSN_MB_ISH)
+
#endif /* _BPF_JIT_H */
diff --git a/arch/arm64/net/bpf_jit_comp.c b/arch/arm64/net/bpf_jit_comp.c
index e96d4d87291f..e850c69e128c 100644
--- a/arch/arm64/net/bpf_jit_comp.c
+++ b/arch/arm64/net/bpf_jit_comp.c
@@ -27,6 +27,17 @@
#define TCALL_CNT (MAX_BPF_JIT_REG + 2)
#define TMP_REG_3 (MAX_BPF_JIT_REG + 3)
+#define check_imm(bits, imm) do { \
+ if ((((imm) > 0) && ((imm) >> (bits))) || \
+ (((imm) < 0) && (~(imm) >> (bits)))) { \
+ pr_info("[%2d] imm=%d(0x%x) out of range\n", \
+ i, imm, imm); \
+ return -EINVAL; \
+ } \
+} while (0)
+#define check_imm19(imm) check_imm(19, imm)
+#define check_imm26(imm) check_imm(26, imm)
+
/* Map BPF registers to A64 registers */
static const int bpf2a64[] = {
/* return value from in-kernel function, and exit value from eBPF */
@@ -329,6 +340,170 @@ static int emit_bpf_tail_call(struct jit_ctx *ctx)
#undef jmp_offset
}
+#ifdef CONFIG_ARM64_LSE_ATOMICS
+static int emit_lse_atomic(const struct bpf_insn *insn, struct jit_ctx *ctx)
+{
+ const u8 code = insn->code;
+ const u8 dst = bpf2a64[insn->dst_reg];
+ const u8 src = bpf2a64[insn->src_reg];
+ const u8 tmp = bpf2a64[TMP_REG_1];
+ const u8 tmp2 = bpf2a64[TMP_REG_2];
+ const bool isdw = BPF_SIZE(code) == BPF_DW;
+ const s16 off = insn->off;
+ u8 reg;
+
+ if (!off) {
+ reg = dst;
+ } else {
+ emit_a64_mov_i(1, tmp, off, ctx);
+ emit(A64_ADD(1, tmp, tmp, dst), ctx);
+ reg = tmp;
+ }
+
+ switch (insn->imm) {
+ /* lock *(u32/u64 *)(dst_reg + off) <op>= src_reg */
+ case BPF_ADD:
+ emit(A64_STADD(isdw, reg, src), ctx);
+ break;
+ case BPF_AND:
+ emit(A64_MVN(isdw, tmp2, src), ctx);
+ emit(A64_STCLR(isdw, reg, tmp2), ctx);
+ break;
+ case BPF_OR:
+ emit(A64_STSET(isdw, reg, src), ctx);
+ break;
+ case BPF_XOR:
+ emit(A64_STEOR(isdw, reg, src), ctx);
+ break;
+ /* src_reg = atomic_fetch_<op>(dst_reg + off, src_reg) */
+ case BPF_ADD | BPF_FETCH:
+ emit(A64_LDADDAL(isdw, src, reg, src), ctx);
+ break;
+ case BPF_AND | BPF_FETCH:
+ emit(A64_MVN(isdw, tmp2, src), ctx);
+ emit(A64_LDCLRAL(isdw, src, reg, tmp2), ctx);
+ break;
+ case BPF_OR | BPF_FETCH:
+ emit(A64_LDSETAL(isdw, src, reg, src), ctx);
+ break;
+ case BPF_XOR | BPF_FETCH:
+ emit(A64_LDEORAL(isdw, src, reg, src), ctx);
+ break;
+ /* src_reg = atomic_xchg(dst_reg + off, src_reg); */
+ case BPF_XCHG:
+ emit(A64_SWPAL(isdw, src, reg, src), ctx);
+ break;
+ /* r0 = atomic_cmpxchg(dst_reg + off, r0, src_reg); */
+ case BPF_CMPXCHG:
+ emit(A64_CASAL(isdw, src, reg, bpf2a64[BPF_REG_0]), ctx);
+ break;
+ default:
+ pr_err_once("unknown atomic op code %02x\n", insn->imm);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+#else
+static inline int emit_lse_atomic(const struct bpf_insn *insn, struct jit_ctx *ctx)
+{
+ return -EINVAL;
+}
+#endif
+
+static int emit_ll_sc_atomic(const struct bpf_insn *insn, struct jit_ctx *ctx)
+{
+ const u8 code = insn->code;
+ const u8 dst = bpf2a64[insn->dst_reg];
+ const u8 src = bpf2a64[insn->src_reg];
+ const u8 tmp = bpf2a64[TMP_REG_1];
+ const u8 tmp2 = bpf2a64[TMP_REG_2];
+ const u8 tmp3 = bpf2a64[TMP_REG_3];
+ const int i = insn - ctx->prog->insnsi;
+ const s32 imm = insn->imm;
+ const s16 off = insn->off;
+ const bool isdw = BPF_SIZE(code) == BPF_DW;
+ u8 reg;
+ s32 jmp_offset;
+
+ if (!off) {
+ reg = dst;
+ } else {
+ emit_a64_mov_i(1, tmp, off, ctx);
+ emit(A64_ADD(1, tmp, tmp, dst), ctx);
+ reg = tmp;
+ }
+
+ if (imm == BPF_ADD || imm == BPF_AND ||
+ imm == BPF_OR || imm == BPF_XOR) {
+ /* lock *(u32/u64 *)(dst_reg + off) <op>= src_reg */
+ emit(A64_LDXR(isdw, tmp2, reg), ctx);
+ if (imm == BPF_ADD)
+ emit(A64_ADD(isdw, tmp2, tmp2, src), ctx);
+ else if (imm == BPF_AND)
+ emit(A64_AND(isdw, tmp2, tmp2, src), ctx);
+ else if (imm == BPF_OR)
+ emit(A64_ORR(isdw, tmp2, tmp2, src), ctx);
+ else
+ emit(A64_EOR(isdw, tmp2, tmp2, src), ctx);
+ emit(A64_STXR(isdw, tmp2, reg, tmp3), ctx);
+ jmp_offset = -3;
+ check_imm19(jmp_offset);
+ emit(A64_CBNZ(0, tmp3, jmp_offset), ctx);
+ } else if (imm == (BPF_ADD | BPF_FETCH) ||
+ imm == (BPF_AND | BPF_FETCH) ||
+ imm == (BPF_OR | BPF_FETCH) ||
+ imm == (BPF_XOR | BPF_FETCH)) {
+ /* src_reg = atomic_fetch_<op>(dst_reg + off, src_reg) */
+ const u8 ax = bpf2a64[BPF_REG_AX];
+
+ emit(A64_MOV(isdw, ax, src), ctx);
+ emit(A64_LDXR(isdw, src, reg), ctx);
+ if (imm == (BPF_ADD | BPF_FETCH))
+ emit(A64_ADD(isdw, tmp2, src, ax), ctx);
+ else if (imm == (BPF_AND | BPF_FETCH))
+ emit(A64_AND(isdw, tmp2, src, ax), ctx);
+ else if (imm == (BPF_OR | BPF_FETCH))
+ emit(A64_ORR(isdw, tmp2, src, ax), ctx);
+ else
+ emit(A64_EOR(isdw, tmp2, src, ax), ctx);
+ emit(A64_STLXR(isdw, tmp2, reg, tmp3), ctx);
+ jmp_offset = -3;
+ check_imm19(jmp_offset);
+ emit(A64_CBNZ(0, tmp3, jmp_offset), ctx);
+ emit(A64_DMB_ISH, ctx);
+ } else if (imm == BPF_XCHG) {
+ /* src_reg = atomic_xchg(dst_reg + off, src_reg); */
+ emit(A64_MOV(isdw, tmp2, src), ctx);
+ emit(A64_LDXR(isdw, src, reg), ctx);
+ emit(A64_STLXR(isdw, tmp2, reg, tmp3), ctx);
+ jmp_offset = -2;
+ check_imm19(jmp_offset);
+ emit(A64_CBNZ(0, tmp3, jmp_offset), ctx);
+ emit(A64_DMB_ISH, ctx);
+ } else if (imm == BPF_CMPXCHG) {
+ /* r0 = atomic_cmpxchg(dst_reg + off, r0, src_reg); */
+ const u8 r0 = bpf2a64[BPF_REG_0];
+
+ emit(A64_MOV(isdw, tmp2, r0), ctx);
+ emit(A64_LDXR(isdw, r0, reg), ctx);
+ emit(A64_EOR(isdw, tmp3, r0, tmp2), ctx);
+ jmp_offset = 4;
+ check_imm19(jmp_offset);
+ emit(A64_CBNZ(isdw, tmp3, jmp_offset), ctx);
+ emit(A64_STLXR(isdw, src, reg, tmp3), ctx);
+ jmp_offset = -4;
+ check_imm19(jmp_offset);
+ emit(A64_CBNZ(0, tmp3, jmp_offset), ctx);
+ emit(A64_DMB_ISH, ctx);
+ } else {
+ pr_err_once("unknown atomic op code %02x\n", imm);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
static void build_epilogue(struct jit_ctx *ctx)
{
const u8 r0 = bpf2a64[BPF_REG_0];
@@ -434,29 +609,16 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx,
const u8 src = bpf2a64[insn->src_reg];
const u8 tmp = bpf2a64[TMP_REG_1];
const u8 tmp2 = bpf2a64[TMP_REG_2];
- const u8 tmp3 = bpf2a64[TMP_REG_3];
const s16 off = insn->off;
const s32 imm = insn->imm;
const int i = insn - ctx->prog->insnsi;
const bool is64 = BPF_CLASS(code) == BPF_ALU64 ||
BPF_CLASS(code) == BPF_JMP;
- const bool isdw = BPF_SIZE(code) == BPF_DW;
- u8 jmp_cond, reg;
+ u8 jmp_cond;
s32 jmp_offset;
u32 a64_insn;
int ret;
-#define check_imm(bits, imm) do { \
- if ((((imm) > 0) && ((imm) >> (bits))) || \
- (((imm) < 0) && (~(imm) >> (bits)))) { \
- pr_info("[%2d] imm=%d(0x%x) out of range\n", \
- i, imm, imm); \
- return -EINVAL; \
- } \
-} while (0)
-#define check_imm19(imm) check_imm(19, imm)
-#define check_imm26(imm) check_imm(26, imm)
-
switch (code) {
/* dst = src */
case BPF_ALU | BPF_MOV | BPF_X:
@@ -891,33 +1053,12 @@ emit_cond_jmp:
case BPF_STX | BPF_ATOMIC | BPF_W:
case BPF_STX | BPF_ATOMIC | BPF_DW:
- if (insn->imm != BPF_ADD) {
- pr_err_once("unknown atomic op code %02x\n", insn->imm);
- return -EINVAL;
- }
-
- /* STX XADD: lock *(u32 *)(dst + off) += src
- * and
- * STX XADD: lock *(u64 *)(dst + off) += src
- */
-
- if (!off) {
- reg = dst;
- } else {
- emit_a64_mov_i(1, tmp, off, ctx);
- emit(A64_ADD(1, tmp, tmp, dst), ctx);
- reg = tmp;
- }
- if (cpus_have_cap(ARM64_HAS_LSE_ATOMICS)) {
- emit(A64_STADD(isdw, reg, src), ctx);
- } else {
- emit(A64_LDXR(isdw, tmp2, reg), ctx);
- emit(A64_ADD(isdw, tmp2, tmp2, src), ctx);
- emit(A64_STXR(isdw, tmp2, reg, tmp3), ctx);
- jmp_offset = -3;
- check_imm19(jmp_offset);
- emit(A64_CBNZ(0, tmp3, jmp_offset), ctx);
- }
+ if (cpus_have_cap(ARM64_HAS_LSE_ATOMICS))
+ ret = emit_lse_atomic(insn, ctx);
+ else
+ ret = emit_ll_sc_atomic(insn, ctx);
+ if (ret)
+ return ret;
break;
default:
@@ -1049,15 +1190,18 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog)
goto out_off;
}
- /* 1. Initial fake pass to compute ctx->idx. */
-
- /* Fake pass to fill in ctx->offset. */
- if (build_body(&ctx, extra_pass)) {
+ /*
+ * 1. Initial fake pass to compute ctx->idx and ctx->offset.
+ *
+ * BPF line info needs ctx->offset[i] to be the offset of
+ * instruction[i] in jited image, so build prologue first.
+ */
+ if (build_prologue(&ctx, was_classic)) {
prog = orig_prog;
goto out_off;
}
- if (build_prologue(&ctx, was_classic)) {
+ if (build_body(&ctx, extra_pass)) {
prog = orig_prog;
goto out_off;
}
@@ -1130,6 +1274,11 @@ skip_init_ctx:
prog->jited_len = prog_size;
if (!prog->is_func || extra_pass) {
+ int i;
+
+ /* offset[prog->len] is the size of program */
+ for (i = 0; i <= prog->len; i++)
+ ctx.offset[i] *= AARCH64_INSN_SIZE;
bpf_prog_fill_jited_linfo(prog, ctx.offset + 1);
out_off:
kfree(ctx.offset);
@@ -1143,6 +1292,11 @@ out:
return prog;
}
+bool bpf_jit_supports_kfunc_call(void)
+{
+ return true;
+}
+
u64 bpf_jit_alloc_exec_limit(void)
{
return VMALLOC_END - VMALLOC_START;
diff --git a/arch/arm64/tools/Makefile b/arch/arm64/tools/Makefile
index 932b4fe5c768..cf1307188150 100644
--- a/arch/arm64/tools/Makefile
+++ b/arch/arm64/tools/Makefile
@@ -5,18 +5,14 @@ kapi := $(gen)/asm
kapi-hdrs-y := $(kapi)/cpucaps.h
-targets += $(addprefix ../../../,$(gen-y) $(kapi-hdrs-y))
+targets += $(addprefix ../../../, $(kapi-hdrs-y))
PHONY += kapi
-kapi: $(kapi-hdrs-y) $(gen-y)
-
-# Create output directory if not already present
-_dummy := $(shell [ -d '$(kapi)' ] || mkdir -p '$(kapi)')
+kapi: $(kapi-hdrs-y)
quiet_cmd_gen_cpucaps = GEN $@
- cmd_gen_cpucaps = mkdir -p $(dir $@) && \
- $(AWK) -f $(filter-out $(PHONY),$^) > $@
+ cmd_gen_cpucaps = mkdir -p $(dir $@); $(AWK) -f $(real-prereqs) > $@
$(kapi)/cpucaps.h: $(src)/gen-cpucaps.awk $(src)/cpucaps FORCE
$(call if_changed,gen_cpucaps)
diff --git a/arch/arm64/tools/cpucaps b/arch/arm64/tools/cpucaps
index 870c39537dd0..3ed418f70e3b 100644
--- a/arch/arm64/tools/cpucaps
+++ b/arch/arm64/tools/cpucaps
@@ -7,7 +7,8 @@ BTI
HAS_32BIT_EL0_DO_NOT_USE
HAS_32BIT_EL1
HAS_ADDRESS_AUTH
-HAS_ADDRESS_AUTH_ARCH
+HAS_ADDRESS_AUTH_ARCH_QARMA3
+HAS_ADDRESS_AUTH_ARCH_QARMA5
HAS_ADDRESS_AUTH_IMP_DEF
HAS_AMU_EXTN
HAS_ARMv8_4_TTL
@@ -21,7 +22,8 @@ HAS_E0PD
HAS_ECV
HAS_EPAN
HAS_GENERIC_AUTH
-HAS_GENERIC_AUTH_ARCH
+HAS_GENERIC_AUTH_ARCH_QARMA3
+HAS_GENERIC_AUTH_ARCH_QARMA5
HAS_GENERIC_AUTH_IMP_DEF
HAS_IRQ_PRIO_MASKING
HAS_LDAPR
@@ -44,6 +46,7 @@ MTE_ASYMM
SPECTRE_V2
SPECTRE_V3A
SPECTRE_V4
+SPECTRE_BHB
SSBS
SVE
UNMAP_KERNEL_AT_EL0
@@ -55,6 +58,10 @@ WORKAROUND_1418040
WORKAROUND_1463225
WORKAROUND_1508412
WORKAROUND_1542419
+WORKAROUND_1902691
+WORKAROUND_2038923
+WORKAROUND_2064142
+WORKAROUND_2077057
WORKAROUND_TRBE_OVERWRITE_FILL_MODE
WORKAROUND_TSB_FLUSH_FAILURE
WORKAROUND_TRBE_WRITE_OUT_OF_RANGE
diff --git a/arch/csky/Kconfig b/arch/csky/Kconfig
index 132f43f12dd8..75ef86605d69 100644
--- a/arch/csky/Kconfig
+++ b/arch/csky/Kconfig
@@ -79,7 +79,6 @@ config CSKY
select PCI_DOMAINS_GENERIC if PCI
select PCI_SYSCALL if PCI
select PCI_MSI if PCI
- select SET_FS
select TRACE_IRQFLAGS_SUPPORT
config LOCKDEP_SUPPORT
diff --git a/arch/csky/include/asm/pgtable.h b/arch/csky/include/asm/pgtable.h
index 151607ed5158..bbe245117777 100644
--- a/arch/csky/include/asm/pgtable.h
+++ b/arch/csky/include/asm/pgtable.h
@@ -30,6 +30,7 @@
#define pgd_ERROR(e) \
pr_err("%s:%d: bad pgd %08lx.\n", __FILE__, __LINE__, pgd_val(e))
+#define pmd_pfn(pmd) (pmd_phys(pmd) >> PAGE_SHIFT)
#define pmd_page(pmd) (pfn_to_page(pmd_phys(pmd) >> PAGE_SHIFT))
#define pte_clear(mm, addr, ptep) set_pte((ptep), \
(((unsigned int) addr >= PAGE_OFFSET) ? __pte(_PAGE_GLOBAL) : __pte(0)))
diff --git a/arch/csky/include/asm/processor.h b/arch/csky/include/asm/processor.h
index 817dd60ff152..688c7548b559 100644
--- a/arch/csky/include/asm/processor.h
+++ b/arch/csky/include/asm/processor.h
@@ -4,7 +4,6 @@
#define __ASM_CSKY_PROCESSOR_H
#include <linux/bitops.h>
-#include <asm/segment.h>
#include <asm/ptrace.h>
#include <asm/current.h>
#include <asm/cache.h>
@@ -59,7 +58,6 @@ struct thread_struct {
*/
#define start_thread(_regs, _pc, _usp) \
do { \
- set_fs(USER_DS); /* reads from user space */ \
(_regs)->pc = (_pc); \
(_regs)->regs[1] = 0; /* ABIV1 is R7, uClibc_main rtdl arg */ \
(_regs)->regs[2] = 0; \
diff --git a/arch/csky/include/asm/segment.h b/arch/csky/include/asm/segment.h
deleted file mode 100644
index 5bc1cc62b87f..000000000000
--- a/arch/csky/include/asm/segment.h
+++ /dev/null
@@ -1,10 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-
-#ifndef __ASM_CSKY_SEGMENT_H
-#define __ASM_CSKY_SEGMENT_H
-
-typedef struct {
- unsigned long seg;
-} mm_segment_t;
-
-#endif /* __ASM_CSKY_SEGMENT_H */
diff --git a/arch/csky/include/asm/thread_info.h b/arch/csky/include/asm/thread_info.h
index 8c349a8f904d..b5ed788f0c68 100644
--- a/arch/csky/include/asm/thread_info.h
+++ b/arch/csky/include/asm/thread_info.h
@@ -16,7 +16,6 @@ struct thread_info {
unsigned long flags;
int preempt_count;
unsigned long tp_value;
- mm_segment_t addr_limit;
struct restart_block restart_block;
struct pt_regs *regs;
unsigned int cpu;
@@ -26,7 +25,6 @@ struct thread_info {
{ \
.task = &tsk, \
.preempt_count = INIT_PREEMPT_COUNT, \
- .addr_limit = KERNEL_DS, \
.cpu = 0, \
.restart_block = { \
.fn = do_no_restart_syscall, \
diff --git a/arch/csky/include/asm/uaccess.h b/arch/csky/include/asm/uaccess.h
index c40f06ee8d3e..2e927c21d8a1 100644
--- a/arch/csky/include/asm/uaccess.h
+++ b/arch/csky/include/asm/uaccess.h
@@ -3,17 +3,6 @@
#ifndef __ASM_CSKY_UACCESS_H
#define __ASM_CSKY_UACCESS_H
-#define user_addr_max() \
- (uaccess_kernel() ? KERNEL_DS.seg : get_fs().seg)
-
-static inline int __access_ok(unsigned long addr, unsigned long size)
-{
- unsigned long limit = current_thread_info()->addr_limit.seg;
-
- return ((addr < limit) && ((addr + size) < limit));
-}
-#define __access_ok __access_ok
-
/*
* __put_user_fn
*/
@@ -209,7 +198,6 @@ unsigned long raw_copy_to_user(void *to, const void *from, unsigned long n);
unsigned long __clear_user(void __user *to, unsigned long n);
#define __clear_user __clear_user
-#include <asm/segment.h>
#include <asm-generic/uaccess.h>
#endif /* __ASM_CSKY_UACCESS_H */
diff --git a/arch/csky/kernel/asm-offsets.c b/arch/csky/kernel/asm-offsets.c
index 1cbcba4b0dd1..d1e903579473 100644
--- a/arch/csky/kernel/asm-offsets.c
+++ b/arch/csky/kernel/asm-offsets.c
@@ -25,7 +25,6 @@ int main(void)
/* offsets into the thread_info struct */
DEFINE(TINFO_FLAGS, offsetof(struct thread_info, flags));
DEFINE(TINFO_PREEMPT, offsetof(struct thread_info, preempt_count));
- DEFINE(TINFO_ADDR_LIMIT, offsetof(struct thread_info, addr_limit));
DEFINE(TINFO_TP_VALUE, offsetof(struct thread_info, tp_value));
DEFINE(TINFO_TASK, offsetof(struct thread_info, task));
diff --git a/arch/csky/kernel/perf_callchain.c b/arch/csky/kernel/perf_callchain.c
index 92057de08f4f..1612f4354087 100644
--- a/arch/csky/kernel/perf_callchain.c
+++ b/arch/csky/kernel/perf_callchain.c
@@ -49,7 +49,7 @@ static unsigned long user_backtrace(struct perf_callchain_entry_ctx *entry,
{
struct stackframe buftail;
unsigned long lr = 0;
- unsigned long *user_frame_tail = (unsigned long *)fp;
+ unsigned long __user *user_frame_tail = (unsigned long __user *)fp;
/* Check accessibility of one struct frame_tail beyond */
if (!access_ok(user_frame_tail, sizeof(buftail)))
diff --git a/arch/csky/kernel/signal.c b/arch/csky/kernel/signal.c
index c7b763d2f526..8867ddf3e6c7 100644
--- a/arch/csky/kernel/signal.c
+++ b/arch/csky/kernel/signal.c
@@ -136,7 +136,7 @@ static inline void __user *get_sigframe(struct ksignal *ksig,
static int
setup_rt_frame(struct ksignal *ksig, sigset_t *set, struct pt_regs *regs)
{
- struct rt_sigframe *frame;
+ struct rt_sigframe __user *frame;
int err = 0;
frame = get_sigframe(ksig, regs, sizeof(*frame));
diff --git a/arch/h8300/Kconfig b/arch/h8300/Kconfig
index 3e3e0f16f7e0..fe48c4f26cc8 100644
--- a/arch/h8300/Kconfig
+++ b/arch/h8300/Kconfig
@@ -24,7 +24,6 @@ config H8300
select HAVE_ARCH_KGDB
select HAVE_ARCH_HASH
select CPU_NO_EFFICIENT_FFS
- select SET_FS
select UACCESS_MEMCPY
config CPU_BIG_ENDIAN
diff --git a/arch/h8300/include/asm/processor.h b/arch/h8300/include/asm/processor.h
index 141a23eb62b7..ba171aa4dacb 100644
--- a/arch/h8300/include/asm/processor.h
+++ b/arch/h8300/include/asm/processor.h
@@ -13,7 +13,6 @@
#define __ASM_H8300_PROCESSOR_H
#include <linux/compiler.h>
-#include <asm/segment.h>
#include <asm/ptrace.h>
#include <asm/current.h>
diff --git a/arch/h8300/include/asm/segment.h b/arch/h8300/include/asm/segment.h
deleted file mode 100644
index 37950725d9b9..000000000000
--- a/arch/h8300/include/asm/segment.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _H8300_SEGMENT_H
-#define _H8300_SEGMENT_H
-
-/* define constants */
-#define USER_DATA (1)
-#ifndef __USER_DS
-#define __USER_DS (USER_DATA)
-#endif
-#define USER_PROGRAM (2)
-#define SUPER_DATA (3)
-#ifndef __KERNEL_DS
-#define __KERNEL_DS (SUPER_DATA)
-#endif
-#define SUPER_PROGRAM (4)
-
-#ifndef __ASSEMBLY__
-
-typedef struct {
- unsigned long seg;
-} mm_segment_t;
-
-#define MAKE_MM_SEG(s) ((mm_segment_t) { (s) })
-#define USER_DS MAKE_MM_SEG(__USER_DS)
-#define KERNEL_DS MAKE_MM_SEG(__KERNEL_DS)
-
-/*
- * Get/set the SFC/DFC registers for MOVES instructions
- */
-
-static inline mm_segment_t get_fs(void)
-{
- return USER_DS;
-}
-
-#define uaccess_kernel() (get_fs().seg == KERNEL_DS.seg)
-
-#endif /* __ASSEMBLY__ */
-
-#endif /* _H8300_SEGMENT_H */
diff --git a/arch/h8300/include/asm/thread_info.h b/arch/h8300/include/asm/thread_info.h
index a518214d4ddd..ff2d873749a4 100644
--- a/arch/h8300/include/asm/thread_info.h
+++ b/arch/h8300/include/asm/thread_info.h
@@ -10,7 +10,6 @@
#define _ASM_THREAD_INFO_H
#include <asm/page.h>
-#include <asm/segment.h>
#ifdef __KERNEL__
@@ -31,7 +30,6 @@ struct thread_info {
unsigned long flags; /* low level flags */
int cpu; /* cpu we're on */
int preempt_count; /* 0 => preemptable, <0 => BUG */
- mm_segment_t addr_limit;
};
/*
@@ -43,7 +41,6 @@ struct thread_info {
.flags = 0, \
.cpu = 0, \
.preempt_count = INIT_PREEMPT_COUNT, \
- .addr_limit = KERNEL_DS, \
}
/* how to get the thread information struct from C */
diff --git a/arch/h8300/include/uapi/asm/signal.h b/arch/h8300/include/uapi/asm/signal.h
index 2cd0dce2b6a6..1165481f80f6 100644
--- a/arch/h8300/include/uapi/asm/signal.h
+++ b/arch/h8300/include/uapi/asm/signal.h
@@ -85,7 +85,7 @@ struct sigaction {
typedef struct sigaltstack {
void *ss_sp;
int ss_flags;
- size_t ss_size;
+ __kernel_size_t ss_size;
} stack_t;
diff --git a/arch/h8300/kernel/entry.S b/arch/h8300/kernel/entry.S
index c6e289b5f1f2..42db87c17917 100644
--- a/arch/h8300/kernel/entry.S
+++ b/arch/h8300/kernel/entry.S
@@ -17,7 +17,6 @@
#include <linux/sys.h>
#include <asm/unistd.h>
#include <asm/setup.h>
-#include <asm/segment.h>
#include <asm/linkage.h>
#include <asm/asm-offsets.h>
#include <asm/thread_info.h>
diff --git a/arch/h8300/kernel/head_ram.S b/arch/h8300/kernel/head_ram.S
index dbf8429f5fab..489462f0ee57 100644
--- a/arch/h8300/kernel/head_ram.S
+++ b/arch/h8300/kernel/head_ram.S
@@ -4,7 +4,6 @@
#include <linux/init.h>
#include <asm/unistd.h>
#include <asm/setup.h>
-#include <asm/segment.h>
#include <asm/linkage.h>
#include <asm/asm-offsets.h>
#include <asm/thread_info.h>
diff --git a/arch/h8300/mm/init.c b/arch/h8300/mm/init.c
index f7bf4693e3b2..9fa13312720a 100644
--- a/arch/h8300/mm/init.c
+++ b/arch/h8300/mm/init.c
@@ -34,7 +34,6 @@
#include <linux/gfp.h>
#include <asm/setup.h>
-#include <asm/segment.h>
#include <asm/page.h>
#include <asm/sections.h>
@@ -71,11 +70,6 @@ void __init paging_init(void)
panic("%s: Failed to allocate %lu bytes align=0x%lx\n",
__func__, PAGE_SIZE, PAGE_SIZE);
- /*
- * Set up SFC/DFC registers (user data space).
- */
- set_fs(USER_DS);
-
pr_debug("before free_area_init\n");
pr_debug("free_area_init -> start_mem is %#lx\nvirtual_end is %#lx\n",
diff --git a/arch/h8300/mm/memory.c b/arch/h8300/mm/memory.c
index 4a60e2b5eb96..c950571064d2 100644
--- a/arch/h8300/mm/memory.c
+++ b/arch/h8300/mm/memory.c
@@ -24,7 +24,6 @@
#include <linux/types.h>
#include <asm/setup.h>
-#include <asm/segment.h>
#include <asm/page.h>
#include <asm/traps.h>
#include <asm/io.h>
diff --git a/arch/hexagon/Kconfig b/arch/hexagon/Kconfig
index 15dd8f38b698..54eadf265178 100644
--- a/arch/hexagon/Kconfig
+++ b/arch/hexagon/Kconfig
@@ -30,7 +30,6 @@ config HEXAGON
select GENERIC_CLOCKEVENTS_BROADCAST
select MODULES_USE_ELF_RELA
select GENERIC_CPU_DEVICES
- select SET_FS
select ARCH_WANT_LD_ORPHAN_WARN
select TRACE_IRQFLAGS_SUPPORT
help
diff --git a/arch/hexagon/include/asm/pgtable.h b/arch/hexagon/include/asm/pgtable.h
index 18cd6ea9ab23..0610724d6a28 100644
--- a/arch/hexagon/include/asm/pgtable.h
+++ b/arch/hexagon/include/asm/pgtable.h
@@ -236,6 +236,11 @@ static inline int pmd_bad(pmd_t pmd)
}
/*
+ * pmd_pfn - converts a PMD entry to a page frame number
+ */
+#define pmd_pfn(pmd) (pmd_val(pmd) >> PAGE_SHIFT)
+
+/*
* pmd_page - converts a PMD entry to a page pointer
*/
#define pmd_page(pmd) (pfn_to_page(pmd_val(pmd) >> PAGE_SHIFT))
diff --git a/arch/hexagon/include/asm/thread_info.h b/arch/hexagon/include/asm/thread_info.h
index 535976665bf0..e90f280b9ce3 100644
--- a/arch/hexagon/include/asm/thread_info.h
+++ b/arch/hexagon/include/asm/thread_info.h
@@ -22,10 +22,6 @@
#ifndef __ASSEMBLY__
-typedef struct {
- unsigned long seg;
-} mm_segment_t;
-
/*
* This is union'd with the "bottom" of the kernel stack.
* It keeps track of thread info which is handy for routines
@@ -37,7 +33,6 @@ struct thread_info {
unsigned long flags; /* low level flags */
__u32 cpu; /* current cpu */
int preempt_count; /* 0=>preemptible,<0=>BUG */
- mm_segment_t addr_limit; /* segmentation sux */
/*
* used for syscalls somehow;
* seems to have a function pointer and four arguments
@@ -66,7 +61,6 @@ struct thread_info {
.flags = 0, \
.cpu = 0, \
.preempt_count = 1, \
- .addr_limit = KERNEL_DS, \
.sp = 0, \
.regs = NULL, \
}
diff --git a/arch/hexagon/include/asm/uaccess.h b/arch/hexagon/include/asm/uaccess.h
index ef5bfef8d490..bff77efc0d9a 100644
--- a/arch/hexagon/include/asm/uaccess.h
+++ b/arch/hexagon/include/asm/uaccess.h
@@ -13,31 +13,6 @@
#include <asm/sections.h>
/*
- * access_ok: - Checks if a user space pointer is valid
- * @addr: User space pointer to start of block to check
- * @size: Size of block to check
- *
- * Context: User context only. This function may sleep if pagefaults are
- * enabled.
- *
- * Checks if a pointer to a block of memory in user space is valid.
- *
- * Returns true (nonzero) if the memory block *may* be valid, false (zero)
- * if it is definitely invalid.
- *
- * User address space in Hexagon, like x86, goes to 0xbfffffff, so the
- * simple MSB-based tests used by MIPS won't work. Some further
- * optimization is probably possible here, but for now, keep it
- * reasonably simple and not *too* slow. After all, we've got the
- * MMU for backup.
- */
-
-#define __access_ok(addr, size) \
- ((get_fs().seg == KERNEL_DS.seg) || \
- (((unsigned long)addr < get_fs().seg) && \
- (unsigned long)size < (get_fs().seg - (unsigned long)addr)))
-
-/*
* When a kernel-mode page fault is taken, the faulting instruction
* address is checked against a table of exception_table_entries.
* Each entry is a tuple of the address of an instruction that may
diff --git a/arch/hexagon/kernel/process.c b/arch/hexagon/kernel/process.c
index 232dfd8956aa..dfa6b2757c05 100644
--- a/arch/hexagon/kernel/process.c
+++ b/arch/hexagon/kernel/process.c
@@ -105,7 +105,6 @@ int copy_thread(unsigned long clone_flags, unsigned long usp, unsigned long arg,
/*
* Parent sees new pid -- not necessary, not even possible at
* this point in the fork process
- * Might also want to set things like ti->addr_limit
*/
return 0;
diff --git a/arch/hexagon/mm/init.c b/arch/hexagon/mm/init.c
index f01e91e10d95..3167a3b5c97b 100644
--- a/arch/hexagon/mm/init.c
+++ b/arch/hexagon/mm/init.c
@@ -29,8 +29,6 @@ int max_kernel_seg = 0x303;
/* indicate pfn's of high memory */
unsigned long highstart_pfn, highend_pfn;
-DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
-
/* Default cache attribute for newly created page tables */
unsigned long _dflt_cache_att = CACHEDEF;
diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig
index 703952819e10..b2317324827f 100644
--- a/arch/ia64/Kconfig
+++ b/arch/ia64/Kconfig
@@ -8,6 +8,7 @@ menu "Processor type and features"
config IA64
bool
+ select ARCH_BINFMT_ELF_EXTRA_PHDRS
select ARCH_HAS_DMA_MARK_CLEAN
select ARCH_HAS_STRNCPY_FROM_USER
select ARCH_HAS_STRNLEN_USER
@@ -61,7 +62,6 @@ config IA64
select NEED_SG_DMA_LENGTH
select NUMA if !FLATMEM
select PCI_MSI_ARCH_FALLBACKS if PCI_MSI
- select SET_FS
select ZONE_DMA32
default y
help
@@ -318,7 +318,7 @@ config ARCH_PROC_KCORE_TEXT
depends on PROC_KCORE
config IA64_MCA_RECOVERY
- tristate "MCA recovery from errors other than TLB."
+ bool "MCA recovery from errors other than TLB."
config IA64_PALINFO
tristate "/proc/pal support"
diff --git a/arch/ia64/configs/zx1_defconfig b/arch/ia64/configs/zx1_defconfig
index 629cb9cdf723..851d8594cdb8 100644
--- a/arch/ia64/configs/zx1_defconfig
+++ b/arch/ia64/configs/zx1_defconfig
@@ -106,7 +106,6 @@ CONFIG_HUGETLBFS=y
CONFIG_NFS_FS=y
CONFIG_NFS_V4=y
CONFIG_NFSD=y
-CONFIG_NFSD_V3=y
CONFIG_NLS_CODEPAGE_437=y
CONFIG_NLS_CODEPAGE_737=y
CONFIG_NLS_CODEPAGE_775=y
diff --git a/arch/ia64/include/asm/pgtable.h b/arch/ia64/include/asm/pgtable.h
index 9584b2c5f394..7aa8f2330fb1 100644
--- a/arch/ia64/include/asm/pgtable.h
+++ b/arch/ia64/include/asm/pgtable.h
@@ -267,6 +267,7 @@ ia64_phys_addr_valid (unsigned long addr)
#define pmd_present(pmd) (pmd_val(pmd) != 0UL)
#define pmd_clear(pmdp) (pmd_val(*(pmdp)) = 0UL)
#define pmd_page_vaddr(pmd) ((unsigned long) __va(pmd_val(pmd) & _PFN_MASK))
+#define pmd_pfn(pmd) ((pmd_val(pmd) & _PFN_MASK) >> PAGE_SHIFT)
#define pmd_page(pmd) virt_to_page((pmd_val(pmd) + PAGE_OFFSET))
#define pud_none(pud) (!pud_val(pud))
diff --git a/arch/ia64/include/asm/processor.h b/arch/ia64/include/asm/processor.h
index 45365c2ef598..7cbce290f4e5 100644
--- a/arch/ia64/include/asm/processor.h
+++ b/arch/ia64/include/asm/processor.h
@@ -243,10 +243,6 @@ DECLARE_PER_CPU(struct cpuinfo_ia64, ia64_cpu_info);
extern void print_cpu_info (struct cpuinfo_ia64 *);
-typedef struct {
- unsigned long seg;
-} mm_segment_t;
-
#define SET_UNALIGN_CTL(task,value) \
({ \
(task)->thread.flags = (((task)->thread.flags & ~IA64_THREAD_UAC_MASK) \
diff --git a/arch/ia64/include/asm/sal.h b/arch/ia64/include/asm/sal.h
index 78f4f7b40435..22749a201e92 100644
--- a/arch/ia64/include/asm/sal.h
+++ b/arch/ia64/include/asm/sal.h
@@ -420,7 +420,7 @@ typedef struct sal_log_processor_info {
* The rest of this structure consists of variable-length arrays, which can't be
* expressed in C.
*/
- sal_log_mod_error_info_t info[0];
+ sal_log_mod_error_info_t info[];
/*
* This is what the rest looked like if C supported variable-length arrays:
*
diff --git a/arch/ia64/include/asm/thread_info.h b/arch/ia64/include/asm/thread_info.h
index 51d20cb37706..21b257117e0a 100644
--- a/arch/ia64/include/asm/thread_info.h
+++ b/arch/ia64/include/asm/thread_info.h
@@ -27,7 +27,6 @@ struct thread_info {
__u32 cpu; /* current CPU */
__u32 last_cpu; /* Last CPU thread ran on */
__u32 status; /* Thread synchronous flags */
- mm_segment_t addr_limit; /* user-level address space limit */
int preempt_count; /* 0=premptable, <0=BUG; will also serve as bh-counter */
#ifdef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE
__u64 utime;
@@ -48,22 +47,21 @@ struct thread_info {
.task = &tsk, \
.flags = 0, \
.cpu = 0, \
- .addr_limit = KERNEL_DS, \
.preempt_count = INIT_PREEMPT_COUNT, \
}
#ifndef ASM_OFFSETS_C
/* how to get the thread information struct from C */
#define current_thread_info() ((struct thread_info *) ((char *) current + IA64_TASK_SIZE))
-#define alloc_thread_stack_node(tsk, node) \
+#define arch_alloc_thread_stack_node(tsk, node) \
((unsigned long *) ((char *) (tsk) + IA64_TASK_SIZE))
#define task_thread_info(tsk) ((struct thread_info *) ((char *) (tsk) + IA64_TASK_SIZE))
#else
#define current_thread_info() ((struct thread_info *) 0)
-#define alloc_thread_stack_node(tsk, node) ((unsigned long *) 0)
+#define arch_alloc_thread_stack_node(tsk, node) ((unsigned long *) 0)
#define task_thread_info(tsk) ((struct thread_info *) 0)
#endif
-#define free_thread_stack(tsk) /* nothing */
+#define arch_free_thread_stack(tsk) /* nothing */
#define task_stack_page(tsk) ((void *)(tsk))
#define __HAVE_THREAD_FUNCTIONS
diff --git a/arch/ia64/include/asm/uaccess.h b/arch/ia64/include/asm/uaccess.h
index e19d2dcc0ced..60adadeb3e9e 100644
--- a/arch/ia64/include/asm/uaccess.h
+++ b/arch/ia64/include/asm/uaccess.h
@@ -42,30 +42,20 @@
#include <asm/extable.h>
/*
- * For historical reasons, the following macros are grossly misnamed:
- */
-#define KERNEL_DS ((mm_segment_t) { ~0UL }) /* cf. access_ok() */
-#define USER_DS ((mm_segment_t) { TASK_SIZE-1 }) /* cf. access_ok() */
-
-#define get_fs() (current_thread_info()->addr_limit)
-#define set_fs(x) (current_thread_info()->addr_limit = (x))
-
-#define uaccess_kernel() (get_fs().seg == KERNEL_DS.seg)
-
-/*
- * When accessing user memory, we need to make sure the entire area really is in
- * user-level space. In order to do this efficiently, we make sure that the page at
- * address TASK_SIZE is never valid. We also need to make sure that the address doesn't
+ * When accessing user memory, we need to make sure the entire area really is
+ * in user-level space. We also need to make sure that the address doesn't
* point inside the virtually mapped linear page table.
*/
static inline int __access_ok(const void __user *p, unsigned long size)
{
+ unsigned long limit = TASK_SIZE;
unsigned long addr = (unsigned long)p;
- unsigned long seg = get_fs().seg;
- return likely(addr <= seg) &&
- (seg == KERNEL_DS.seg || likely(REGION_OFFSET(addr) < RGN_MAP_LIMIT));
+
+ return likely((size <= limit) && (addr <= (limit - size)) &&
+ likely(REGION_OFFSET(addr) < RGN_MAP_LIMIT));
}
-#define access_ok(addr, size) __access_ok((addr), (size))
+#define __access_ok __access_ok
+#include <asm-generic/access_ok.h>
/*
* These are the main single-value transfer routines. They automatically
diff --git a/arch/ia64/include/asm/xor.h b/arch/ia64/include/asm/xor.h
index 673051bf9d7d..6785f70d3208 100644
--- a/arch/ia64/include/asm/xor.h
+++ b/arch/ia64/include/asm/xor.h
@@ -4,13 +4,20 @@
*/
-extern void xor_ia64_2(unsigned long, unsigned long *, unsigned long *);
-extern void xor_ia64_3(unsigned long, unsigned long *, unsigned long *,
- unsigned long *);
-extern void xor_ia64_4(unsigned long, unsigned long *, unsigned long *,
- unsigned long *, unsigned long *);
-extern void xor_ia64_5(unsigned long, unsigned long *, unsigned long *,
- unsigned long *, unsigned long *, unsigned long *);
+extern void xor_ia64_2(unsigned long bytes, unsigned long * __restrict p1,
+ const unsigned long * __restrict p2);
+extern void xor_ia64_3(unsigned long bytes, unsigned long * __restrict p1,
+ const unsigned long * __restrict p2,
+ const unsigned long * __restrict p3);
+extern void xor_ia64_4(unsigned long bytes, unsigned long * __restrict p1,
+ const unsigned long * __restrict p2,
+ const unsigned long * __restrict p3,
+ const unsigned long * __restrict p4);
+extern void xor_ia64_5(unsigned long bytes, unsigned long * __restrict p1,
+ const unsigned long * __restrict p2,
+ const unsigned long * __restrict p3,
+ const unsigned long * __restrict p4,
+ const unsigned long * __restrict p5);
static struct xor_block_template xor_block_ia64 = {
.name = "ia64",
diff --git a/arch/ia64/include/uapi/asm/signal.h b/arch/ia64/include/uapi/asm/signal.h
index 38166a88e4c9..63d574e802a2 100644
--- a/arch/ia64/include/uapi/asm/signal.h
+++ b/arch/ia64/include/uapi/asm/signal.h
@@ -90,7 +90,7 @@ struct siginfo;
typedef struct sigaltstack {
void __user *ss_sp;
int ss_flags;
- size_t ss_size;
+ __kernel_size_t ss_size;
} stack_t;
diff --git a/arch/ia64/kernel/topology.c b/arch/ia64/kernel/topology.c
index e4992917a24b..94a848b06f15 100644
--- a/arch/ia64/kernel/topology.c
+++ b/arch/ia64/kernel/topology.c
@@ -70,16 +70,6 @@ static int __init topology_init(void)
{
int i, err = 0;
-#ifdef CONFIG_NUMA
- /*
- * MCD - Do we want to register all ONLINE nodes, or all POSSIBLE nodes?
- */
- for_each_online_node(i) {
- if ((err = register_one_node(i)))
- goto out;
- }
-#endif
-
sysfs_cpus = kcalloc(NR_CPUS, sizeof(struct ia64_cpu), GFP_KERNEL);
if (!sysfs_cpus)
panic("kzalloc in topology_init failed - NR_CPUS too big?");
diff --git a/arch/ia64/kernel/unaligned.c b/arch/ia64/kernel/unaligned.c
index 6c1a8951dfbb..0acb5a0cd7ab 100644
--- a/arch/ia64/kernel/unaligned.c
+++ b/arch/ia64/kernel/unaligned.c
@@ -749,9 +749,25 @@ emulate_load_updates (update_t type, load_store_t ld, struct pt_regs *regs, unsi
}
}
+static int emulate_store(unsigned long ifa, void *val, int len, bool kernel_mode)
+{
+ if (kernel_mode)
+ return copy_to_kernel_nofault((void *)ifa, val, len);
+
+ return copy_to_user((void __user *)ifa, val, len);
+}
+
+static int emulate_load(void *val, unsigned long ifa, int len, bool kernel_mode)
+{
+ if (kernel_mode)
+ return copy_from_kernel_nofault(val, (void *)ifa, len);
+
+ return copy_from_user(val, (void __user *)ifa, len);
+}
static int
-emulate_load_int (unsigned long ifa, load_store_t ld, struct pt_regs *regs)
+emulate_load_int (unsigned long ifa, load_store_t ld, struct pt_regs *regs,
+ bool kernel_mode)
{
unsigned int len = 1 << ld.x6_sz;
unsigned long val = 0;
@@ -774,7 +790,7 @@ emulate_load_int (unsigned long ifa, load_store_t ld, struct pt_regs *regs)
return -1;
}
/* this assumes little-endian byte-order: */
- if (copy_from_user(&val, (void __user *) ifa, len))
+ if (emulate_load(&val, ifa, len, kernel_mode))
return -1;
setreg(ld.r1, val, 0, regs);
@@ -872,7 +888,8 @@ emulate_load_int (unsigned long ifa, load_store_t ld, struct pt_regs *regs)
}
static int
-emulate_store_int (unsigned long ifa, load_store_t ld, struct pt_regs *regs)
+emulate_store_int (unsigned long ifa, load_store_t ld, struct pt_regs *regs,
+ bool kernel_mode)
{
unsigned long r2;
unsigned int len = 1 << ld.x6_sz;
@@ -901,7 +918,7 @@ emulate_store_int (unsigned long ifa, load_store_t ld, struct pt_regs *regs)
}
/* this assumes little-endian byte-order: */
- if (copy_to_user((void __user *) ifa, &r2, len))
+ if (emulate_store(ifa, &r2, len, kernel_mode))
return -1;
/*
@@ -1021,7 +1038,7 @@ float2mem_double (struct ia64_fpreg *init, struct ia64_fpreg *final)
}
static int
-emulate_load_floatpair (unsigned long ifa, load_store_t ld, struct pt_regs *regs)
+emulate_load_floatpair (unsigned long ifa, load_store_t ld, struct pt_regs *regs, bool kernel_mode)
{
struct ia64_fpreg fpr_init[2];
struct ia64_fpreg fpr_final[2];
@@ -1050,8 +1067,8 @@ emulate_load_floatpair (unsigned long ifa, load_store_t ld, struct pt_regs *regs
* This assumes little-endian byte-order. Note that there is no "ldfpe"
* instruction:
*/
- if (copy_from_user(&fpr_init[0], (void __user *) ifa, len)
- || copy_from_user(&fpr_init[1], (void __user *) (ifa + len), len))
+ if (emulate_load(&fpr_init[0], ifa, len, kernel_mode)
+ || emulate_load(&fpr_init[1], (ifa + len), len, kernel_mode))
return -1;
DPRINT("ld.r1=%d ld.imm=%d x6_sz=%d\n", ld.r1, ld.imm, ld.x6_sz);
@@ -1126,7 +1143,8 @@ emulate_load_floatpair (unsigned long ifa, load_store_t ld, struct pt_regs *regs
static int
-emulate_load_float (unsigned long ifa, load_store_t ld, struct pt_regs *regs)
+emulate_load_float (unsigned long ifa, load_store_t ld, struct pt_regs *regs,
+ bool kernel_mode)
{
struct ia64_fpreg fpr_init;
struct ia64_fpreg fpr_final;
@@ -1152,7 +1170,7 @@ emulate_load_float (unsigned long ifa, load_store_t ld, struct pt_regs *regs)
* See comments in ldX for descriptions on how the various loads are handled.
*/
if (ld.x6_op != 0x2) {
- if (copy_from_user(&fpr_init, (void __user *) ifa, len))
+ if (emulate_load(&fpr_init, ifa, len, kernel_mode))
return -1;
DPRINT("ld.r1=%d x6_sz=%d\n", ld.r1, ld.x6_sz);
@@ -1202,7 +1220,8 @@ emulate_load_float (unsigned long ifa, load_store_t ld, struct pt_regs *regs)
static int
-emulate_store_float (unsigned long ifa, load_store_t ld, struct pt_regs *regs)
+emulate_store_float (unsigned long ifa, load_store_t ld, struct pt_regs *regs,
+ bool kernel_mode)
{
struct ia64_fpreg fpr_init;
struct ia64_fpreg fpr_final;
@@ -1244,7 +1263,7 @@ emulate_store_float (unsigned long ifa, load_store_t ld, struct pt_regs *regs)
DDUMP("fpr_init =", &fpr_init, len);
DDUMP("fpr_final =", &fpr_final, len);
- if (copy_to_user((void __user *) ifa, &fpr_final, len))
+ if (emulate_store(ifa, &fpr_final, len, kernel_mode))
return -1;
/*
@@ -1295,7 +1314,6 @@ void
ia64_handle_unaligned (unsigned long ifa, struct pt_regs *regs)
{
struct ia64_psr *ipsr = ia64_psr(regs);
- mm_segment_t old_fs = get_fs();
unsigned long bundle[2];
unsigned long opcode;
const struct exception_table_entry *eh = NULL;
@@ -1304,6 +1322,7 @@ ia64_handle_unaligned (unsigned long ifa, struct pt_regs *regs)
load_store_t insn;
} u;
int ret = -1;
+ bool kernel_mode = false;
if (ia64_psr(regs)->be) {
/* we don't support big-endian accesses */
@@ -1367,13 +1386,13 @@ ia64_handle_unaligned (unsigned long ifa, struct pt_regs *regs)
if (unaligned_dump_stack)
dump_stack();
}
- set_fs(KERNEL_DS);
+ kernel_mode = true;
}
DPRINT("iip=%lx ifa=%lx isr=%lx (ei=%d, sp=%d)\n",
regs->cr_iip, ifa, regs->cr_ipsr, ipsr->ri, ipsr->it);
- if (__copy_from_user(bundle, (void __user *) regs->cr_iip, 16))
+ if (emulate_load(bundle, regs->cr_iip, 16, kernel_mode))
goto failure;
/*
@@ -1467,7 +1486,7 @@ ia64_handle_unaligned (unsigned long ifa, struct pt_regs *regs)
case LDCCLR_IMM_OP:
case LDCNC_IMM_OP:
case LDCCLRACQ_IMM_OP:
- ret = emulate_load_int(ifa, u.insn, regs);
+ ret = emulate_load_int(ifa, u.insn, regs, kernel_mode);
break;
case ST_OP:
@@ -1478,7 +1497,7 @@ ia64_handle_unaligned (unsigned long ifa, struct pt_regs *regs)
fallthrough;
case ST_IMM_OP:
case STREL_IMM_OP:
- ret = emulate_store_int(ifa, u.insn, regs);
+ ret = emulate_store_int(ifa, u.insn, regs, kernel_mode);
break;
case LDF_OP:
@@ -1486,21 +1505,21 @@ ia64_handle_unaligned (unsigned long ifa, struct pt_regs *regs)
case LDFCCLR_OP:
case LDFCNC_OP:
if (u.insn.x)
- ret = emulate_load_floatpair(ifa, u.insn, regs);
+ ret = emulate_load_floatpair(ifa, u.insn, regs, kernel_mode);
else
- ret = emulate_load_float(ifa, u.insn, regs);
+ ret = emulate_load_float(ifa, u.insn, regs, kernel_mode);
break;
case LDF_IMM_OP:
case LDFA_IMM_OP:
case LDFCCLR_IMM_OP:
case LDFCNC_IMM_OP:
- ret = emulate_load_float(ifa, u.insn, regs);
+ ret = emulate_load_float(ifa, u.insn, regs, kernel_mode);
break;
case STF_OP:
case STF_IMM_OP:
- ret = emulate_store_float(ifa, u.insn, regs);
+ ret = emulate_store_float(ifa, u.insn, regs, kernel_mode);
break;
default:
@@ -1521,7 +1540,6 @@ ia64_handle_unaligned (unsigned long ifa, struct pt_regs *regs)
DPRINT("ipsr->ri=%d iip=%lx\n", ipsr->ri, regs->cr_iip);
done:
- set_fs(old_fs); /* restore original address limit */
return;
failure:
diff --git a/arch/ia64/mm/discontig.c b/arch/ia64/mm/discontig.c
index 791d4176e4a6..73d0db36edb6 100644
--- a/arch/ia64/mm/discontig.c
+++ b/arch/ia64/mm/discontig.c
@@ -608,17 +608,11 @@ void __init paging_init(void)
zero_page_memmap_ptr = virt_to_page(ia64_imva(empty_zero_page));
}
-#ifdef CONFIG_MEMORY_HOTPLUG
-pg_data_t *arch_alloc_nodedata(int nid)
+pg_data_t * __init arch_alloc_nodedata(int nid)
{
unsigned long size = compute_pernodesize(nid);
- return kzalloc(size, GFP_KERNEL);
-}
-
-void arch_free_nodedata(pg_data_t *pgdat)
-{
- kfree(pgdat);
+ return memblock_alloc(size, SMP_CACHE_BYTES);
}
void arch_refresh_nodedata(int update_node, pg_data_t *update_pgdat)
@@ -626,7 +620,6 @@ void arch_refresh_nodedata(int update_node, pg_data_t *update_pgdat)
pgdat_list[update_node] = update_pgdat;
scatter_node_data();
}
-#endif
#ifdef CONFIG_SPARSEMEM_VMEMMAP
int __meminit vmemmap_populate(unsigned long start, unsigned long end, int node,
diff --git a/arch/ia64/pci/fixup.c b/arch/ia64/pci/fixup.c
index acb55a41260d..2bcdd7d3a1ad 100644
--- a/arch/ia64/pci/fixup.c
+++ b/arch/ia64/pci/fixup.c
@@ -76,5 +76,5 @@ static void pci_fixup_video(struct pci_dev *pdev)
}
}
}
-DECLARE_PCI_FIXUP_CLASS_FINAL(PCI_ANY_ID, PCI_ANY_ID,
- PCI_CLASS_DISPLAY_VGA, 8, pci_fixup_video);
+DECLARE_PCI_FIXUP_CLASS_HEADER(PCI_ANY_ID, PCI_ANY_ID,
+ PCI_CLASS_DISPLAY_VGA, 8, pci_fixup_video);
diff --git a/arch/m68k/68000/dragen2.c b/arch/m68k/68000/dragen2.c
index 62f10a9e1ab7..1a57eff28cfe 100644
--- a/arch/m68k/68000/dragen2.c
+++ b/arch/m68k/68000/dragen2.c
@@ -11,6 +11,7 @@
#include <linux/init.h>
#include <asm/machdep.h>
#include <asm/MC68VZ328.h>
+#include "m68328.h"
#include "screen.h"
/***************************************************************************/
diff --git a/arch/m68k/68000/screen.h b/arch/m68k/68000/screen.h
index 2089bdf02688..8f7418008908 100644
--- a/arch/m68k/68000/screen.h
+++ b/arch/m68k/68000/screen.h
@@ -1,4 +1,5 @@
/* Created with The GIMP */
+#ifdef CONFIG_INIT_LCD
#define screen_width 320
#define screen_height 240
static unsigned char screen_bits[] = {
@@ -802,3 +803,4 @@ static unsigned char screen_bits[] = {
0x93, 0x10, 0xe2, 0x11, 0x00, 0x94, 0x22, 0x52, 0x69, 0x53, 0x52, 0x45,
0x49, 0x22, 0xa4, 0x4a, 0x55, 0x29, 0x2a, 0xa4, 0x52, 0x42, 0xaa, 0xa5,
0x52, 0xa8, 0xaa, 0x55, 0x4a, 0xab, 0xa9, 0x4a, 0x54, 0x49, 0x32, 0x24 };
+#endif /* CONFIG_INIT_LCD */
diff --git a/arch/m68k/68000/ucsimm.c b/arch/m68k/68000/ucsimm.c
index 7c6cbf643712..c54fde75eae8 100644
--- a/arch/m68k/68000/ucsimm.c
+++ b/arch/m68k/68000/ucsimm.c
@@ -16,19 +16,18 @@
#include "m68328.h"
-unsigned char *cs8900a_hwaddr;
static int errno;
-_bsc0(char *, getserialnum)
-_bsc1(unsigned char *, gethwaddr, int, a)
-_bsc1(char *, getbenv, char *, a)
+static _bsc0(char *, getserialnum)
+static _bsc1(unsigned char *, gethwaddr, int, a)
+static _bsc1(char *, getbenv, char *, a)
void __init init_ucsimm(char *command, int size)
{
char *p;
pr_info("uCsimm/uCdimm serial string [%s]\n", getserialnum());
- p = cs8900a_hwaddr = gethwaddr(0);
+ p = gethwaddr(0);
pr_info("uCsimm/uCdimm hwaddr %pM\n", p);
p = getbenv("APPEND");
if (p)
diff --git a/arch/m68k/Kconfig b/arch/m68k/Kconfig
index 936e1803c7c7..936cce42ae9a 100644
--- a/arch/m68k/Kconfig
+++ b/arch/m68k/Kconfig
@@ -4,6 +4,7 @@ config M68K
default y
select ARCH_32BIT_OFF_T
select ARCH_HAS_BINFMT_FLAT
+ select ARCH_HAS_CURRENT_STACK_POINTER
select ARCH_HAS_DMA_PREP_COHERENT if HAS_DMA && MMU && !COLDFIRE
select ARCH_HAS_SYNC_DMA_FOR_DEVICE if HAS_DMA
select ARCH_HAVE_NMI_SAFE_CMPXCHG if RMW_INSNS
@@ -17,7 +18,6 @@ config M68K
select GENERIC_CPU_DEVICES
select GENERIC_IOMAP
select GENERIC_IRQ_SHOW
- select HAVE_AOUT if MMU
select HAVE_ASM_MODVERSIONS
select HAVE_DEBUG_BUGVERBOSE
select HAVE_EFFICIENT_UNALIGNED_ACCESS if !CPU_HAS_NO_UNALIGNED
diff --git a/arch/m68k/Kconfig.cpu b/arch/m68k/Kconfig.cpu
index 0d00ef5117dc..16ea9a67723c 100644
--- a/arch/m68k/Kconfig.cpu
+++ b/arch/m68k/Kconfig.cpu
@@ -453,6 +453,7 @@ config CPU_HAS_NO_UNALIGNED
config CPU_HAS_ADDRESS_SPACES
bool
+ select ALTERNATE_USER_ADDRESS_SPACE
config FPU
bool
diff --git a/arch/m68k/amiga/config.c b/arch/m68k/amiga/config.c
index be2dfab48fd4..3137b45750df 100644
--- a/arch/m68k/amiga/config.c
+++ b/arch/m68k/amiga/config.c
@@ -37,6 +37,7 @@
#include <asm/irq.h>
#include <asm/machdep.h>
#include <asm/io.h>
+#include <asm/config.h>
static unsigned long amiga_model;
diff --git a/arch/m68k/apollo/config.c b/arch/m68k/apollo/config.c
index 581a5f68d102..42a8b8e2b664 100644
--- a/arch/m68k/apollo/config.c
+++ b/arch/m68k/apollo/config.c
@@ -16,6 +16,7 @@
#include <asm/apollohw.h>
#include <asm/irq.h>
#include <asm/machdep.h>
+#include <asm/config.h>
u_long sio01_physaddr;
u_long sio23_physaddr;
diff --git a/arch/m68k/atari/config.c b/arch/m68k/atari/config.c
index 261a0f57cc9a..38a7c0578105 100644
--- a/arch/m68k/atari/config.c
+++ b/arch/m68k/atari/config.c
@@ -46,6 +46,7 @@
#include <asm/machdep.h>
#include <asm/hwtest.h>
#include <asm/io.h>
+#include <asm/config.h>
u_long atari_mch_cookie;
EXPORT_SYMBOL(atari_mch_cookie);
diff --git a/arch/m68k/atari/stdma.c b/arch/m68k/atari/stdma.c
index ba65f942d0c7..ce6818eff75e 100644
--- a/arch/m68k/atari/stdma.c
+++ b/arch/m68k/atari/stdma.c
@@ -30,7 +30,6 @@
#include <linux/types.h>
#include <linux/kdev_t.h>
-#include <linux/genhd.h>
#include <linux/sched.h>
#include <linux/init.h>
#include <linux/interrupt.h>
diff --git a/arch/m68k/bvme6000/config.c b/arch/m68k/bvme6000/config.c
index 0c6feafbbd11..3a1d90e399e0 100644
--- a/arch/m68k/bvme6000/config.c
+++ b/arch/m68k/bvme6000/config.c
@@ -23,7 +23,6 @@
#include <linux/linkage.h>
#include <linux/init.h>
#include <linux/major.h>
-#include <linux/genhd.h>
#include <linux/rtc.h>
#include <linux/interrupt.h>
#include <linux/bcd.h>
@@ -36,6 +35,7 @@
#include <asm/traps.h>
#include <asm/machdep.h>
#include <asm/bvme6000hw.h>
+#include <asm/config.h>
static void bvme6000_get_model(char *model);
extern void bvme6000_sched_init(void);
diff --git a/arch/m68k/coldfire/device.c b/arch/m68k/coldfire/device.c
index 0386252e9d04..4218750414bb 100644
--- a/arch/m68k/coldfire/device.c
+++ b/arch/m68k/coldfire/device.c
@@ -480,7 +480,7 @@ static struct platform_device mcf_i2c5 = {
#endif /* MCFI2C_BASE5 */
#endif /* IS_ENABLED(CONFIG_I2C_IMX) */
-#if IS_ENABLED(CONFIG_MCF_EDMA)
+#ifdef MCFEDMA_BASE
static const struct dma_slave_map mcf_edma_map[] = {
{ "dreq0", "rx-tx", MCF_EDMA_FILTER_PARAM(0) },
@@ -552,7 +552,7 @@ static struct platform_device mcf_edma = {
.platform_data = &mcf_edma_data,
}
};
-#endif /* IS_ENABLED(CONFIG_MCF_EDMA) */
+#endif /* MCFEDMA_BASE */
#ifdef MCFSDHC_BASE
static struct mcf_esdhc_platform_data mcf_esdhc_data = {
@@ -651,7 +651,7 @@ static struct platform_device *mcf_devices[] __initdata = {
&mcf_i2c5,
#endif
#endif
-#if IS_ENABLED(CONFIG_MCF_EDMA)
+#ifdef MCFEDMA_BASE
&mcf_edma,
#endif
#ifdef MCFSDHC_BASE
diff --git a/arch/m68k/coldfire/m5441x.c b/arch/m68k/coldfire/m5441x.c
index 39855044090d..405e9d5c832c 100644
--- a/arch/m68k/coldfire/m5441x.c
+++ b/arch/m68k/coldfire/m5441x.c
@@ -181,7 +181,6 @@ static struct clk * const disable_clks[] __initconst = {
&__clk_0_47, /* ssi.0 */
&__clk_0_49, /* rng */
&__clk_0_50, /* ssi.1 */
- &__clk_0_51, /* eSDHC */
&__clk_0_53, /* enet-fec */
&__clk_0_54, /* enet-fec */
&__clk_0_55, /* switch.0 */
diff --git a/arch/m68k/configs/amiga_defconfig b/arch/m68k/configs/amiga_defconfig
index bc9952f8be66..114aaa3f955a 100644
--- a/arch/m68k/configs/amiga_defconfig
+++ b/arch/m68k/configs/amiga_defconfig
@@ -104,7 +104,6 @@ CONFIG_NF_TABLES_NETDEV=y
CONFIG_NFT_NUMGEN=m
CONFIG_NFT_CT=m
CONFIG_NFT_FLOW_OFFLOAD=m
-CONFIG_NFT_COUNTER=m
CONFIG_NFT_CONNLIMIT=m
CONFIG_NFT_LOG=m
CONFIG_NFT_LIMIT=m
@@ -204,7 +203,6 @@ CONFIG_IP_SET_LIST_SET=m
CONFIG_NFT_DUP_IPV4=m
CONFIG_NFT_FIB_IPV4=m
CONFIG_NF_TABLES_ARP=y
-CONFIG_NF_FLOW_TABLE_IPV4=m
CONFIG_NF_LOG_ARP=m
CONFIG_NF_LOG_IPV4=m
CONFIG_IP_NF_IPTABLES=m
@@ -229,7 +227,6 @@ CONFIG_IP_NF_ARPFILTER=m
CONFIG_IP_NF_ARP_MANGLE=m
CONFIG_NFT_DUP_IPV6=m
CONFIG_NFT_FIB_IPV6=m
-CONFIG_NF_FLOW_TABLE_IPV6=m
CONFIG_IP6_NF_IPTABLES=m
CONFIG_IP6_NF_MATCH_AH=m
CONFIG_IP6_NF_MATCH_EUI64=m
@@ -435,6 +432,7 @@ CONFIG_FB_AMIGA_ECS=y
CONFIG_FB_AMIGA_AGA=y
CONFIG_FB_FM2=y
CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE_LEGACY_ACCELERATION=y
CONFIG_LOGO=y
CONFIG_SOUND=m
CONFIG_DMASOUND_PAULA=m
@@ -500,7 +498,6 @@ CONFIG_NFS_V4=m
CONFIG_NFS_SWAP=y
CONFIG_ROOT_NFS=y
CONFIG_NFSD=m
-CONFIG_NFSD_V3=y
CONFIG_CIFS=m
# CONFIG_CIFS_STATS2 is not set
# CONFIG_CIFS_DEBUG is not set
@@ -643,7 +640,7 @@ CONFIG_TEST_UUID=m
CONFIG_TEST_XARRAY=m
CONFIG_TEST_OVERFLOW=m
CONFIG_TEST_RHASHTABLE=m
-CONFIG_TEST_HASH=m
+CONFIG_TEST_SIPHASH=m
CONFIG_TEST_IDA=m
CONFIG_TEST_BITOPS=m
CONFIG_TEST_VMALLOC=m
diff --git a/arch/m68k/configs/apollo_defconfig b/arch/m68k/configs/apollo_defconfig
index a77269c6e5ba..30b9d932b930 100644
--- a/arch/m68k/configs/apollo_defconfig
+++ b/arch/m68k/configs/apollo_defconfig
@@ -100,7 +100,6 @@ CONFIG_NF_TABLES_NETDEV=y
CONFIG_NFT_NUMGEN=m
CONFIG_NFT_CT=m
CONFIG_NFT_FLOW_OFFLOAD=m
-CONFIG_NFT_COUNTER=m
CONFIG_NFT_CONNLIMIT=m
CONFIG_NFT_LOG=m
CONFIG_NFT_LIMIT=m
@@ -200,7 +199,6 @@ CONFIG_IP_SET_LIST_SET=m
CONFIG_NFT_DUP_IPV4=m
CONFIG_NFT_FIB_IPV4=m
CONFIG_NF_TABLES_ARP=y
-CONFIG_NF_FLOW_TABLE_IPV4=m
CONFIG_NF_LOG_ARP=m
CONFIG_NF_LOG_IPV4=m
CONFIG_IP_NF_IPTABLES=m
@@ -225,7 +223,6 @@ CONFIG_IP_NF_ARPFILTER=m
CONFIG_IP_NF_ARP_MANGLE=m
CONFIG_NFT_DUP_IPV6=m
CONFIG_NFT_FIB_IPV6=m
-CONFIG_NF_FLOW_TABLE_IPV6=m
CONFIG_IP6_NF_IPTABLES=m
CONFIG_IP6_NF_MATCH_AH=m
CONFIG_IP6_NF_MATCH_EUI64=m
@@ -393,6 +390,7 @@ CONFIG_PTP_1588_CLOCK=m
# CONFIG_HWMON is not set
CONFIG_FB=y
CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE_LEGACY_ACCELERATION=y
CONFIG_LOGO=y
# CONFIG_LOGO_LINUX_VGA16 is not set
# CONFIG_LOGO_LINUX_CLUT224 is not set
@@ -457,7 +455,6 @@ CONFIG_NFS_V4=m
CONFIG_NFS_SWAP=y
CONFIG_ROOT_NFS=y
CONFIG_NFSD=m
-CONFIG_NFSD_V3=y
CONFIG_CIFS=m
# CONFIG_CIFS_STATS2 is not set
# CONFIG_CIFS_DEBUG is not set
@@ -599,7 +596,7 @@ CONFIG_TEST_UUID=m
CONFIG_TEST_XARRAY=m
CONFIG_TEST_OVERFLOW=m
CONFIG_TEST_RHASHTABLE=m
-CONFIG_TEST_HASH=m
+CONFIG_TEST_SIPHASH=m
CONFIG_TEST_IDA=m
CONFIG_TEST_BITOPS=m
CONFIG_TEST_VMALLOC=m
diff --git a/arch/m68k/configs/atari_defconfig b/arch/m68k/configs/atari_defconfig
index 7a74efa6b9a1..51ff3180e69d 100644
--- a/arch/m68k/configs/atari_defconfig
+++ b/arch/m68k/configs/atari_defconfig
@@ -107,7 +107,6 @@ CONFIG_NF_TABLES_NETDEV=y
CONFIG_NFT_NUMGEN=m
CONFIG_NFT_CT=m
CONFIG_NFT_FLOW_OFFLOAD=m
-CONFIG_NFT_COUNTER=m
CONFIG_NFT_CONNLIMIT=m
CONFIG_NFT_LOG=m
CONFIG_NFT_LIMIT=m
@@ -207,7 +206,6 @@ CONFIG_IP_SET_LIST_SET=m
CONFIG_NFT_DUP_IPV4=m
CONFIG_NFT_FIB_IPV4=m
CONFIG_NF_TABLES_ARP=y
-CONFIG_NF_FLOW_TABLE_IPV4=m
CONFIG_NF_LOG_ARP=m
CONFIG_NF_LOG_IPV4=m
CONFIG_IP_NF_IPTABLES=m
@@ -232,7 +230,6 @@ CONFIG_IP_NF_ARPFILTER=m
CONFIG_IP_NF_ARP_MANGLE=m
CONFIG_NFT_DUP_IPV6=m
CONFIG_NFT_FIB_IPV6=m
-CONFIG_NF_FLOW_TABLE_IPV6=m
CONFIG_IP6_NF_IPTABLES=m
CONFIG_IP6_NF_MATCH_AH=m
CONFIG_IP6_NF_MATCH_EUI64=m
@@ -478,7 +475,6 @@ CONFIG_NFS_V4=m
CONFIG_NFS_SWAP=y
CONFIG_ROOT_NFS=y
CONFIG_NFSD=m
-CONFIG_NFSD_V3=y
CONFIG_CIFS=m
# CONFIG_CIFS_STATS2 is not set
# CONFIG_CIFS_DEBUG is not set
@@ -621,7 +617,7 @@ CONFIG_TEST_UUID=m
CONFIG_TEST_XARRAY=m
CONFIG_TEST_OVERFLOW=m
CONFIG_TEST_RHASHTABLE=m
-CONFIG_TEST_HASH=m
+CONFIG_TEST_SIPHASH=m
CONFIG_TEST_IDA=m
CONFIG_TEST_BITOPS=m
CONFIG_TEST_VMALLOC=m
diff --git a/arch/m68k/configs/bvme6000_defconfig b/arch/m68k/configs/bvme6000_defconfig
index a5323bf2eb33..7d95ca4366e4 100644
--- a/arch/m68k/configs/bvme6000_defconfig
+++ b/arch/m68k/configs/bvme6000_defconfig
@@ -97,7 +97,6 @@ CONFIG_NF_TABLES_NETDEV=y
CONFIG_NFT_NUMGEN=m
CONFIG_NFT_CT=m
CONFIG_NFT_FLOW_OFFLOAD=m
-CONFIG_NFT_COUNTER=m
CONFIG_NFT_CONNLIMIT=m
CONFIG_NFT_LOG=m
CONFIG_NFT_LIMIT=m
@@ -197,7 +196,6 @@ CONFIG_IP_SET_LIST_SET=m
CONFIG_NFT_DUP_IPV4=m
CONFIG_NFT_FIB_IPV4=m
CONFIG_NF_TABLES_ARP=y
-CONFIG_NF_FLOW_TABLE_IPV4=m
CONFIG_NF_LOG_ARP=m
CONFIG_NF_LOG_IPV4=m
CONFIG_IP_NF_IPTABLES=m
@@ -222,7 +220,6 @@ CONFIG_IP_NF_ARPFILTER=m
CONFIG_IP_NF_ARP_MANGLE=m
CONFIG_NFT_DUP_IPV6=m
CONFIG_NFT_FIB_IPV6=m
-CONFIG_NF_FLOW_TABLE_IPV6=m
CONFIG_IP6_NF_IPTABLES=m
CONFIG_IP6_NF_MATCH_AH=m
CONFIG_IP6_NF_MATCH_EUI64=m
@@ -450,7 +447,6 @@ CONFIG_NFS_V4=m
CONFIG_NFS_SWAP=y
CONFIG_ROOT_NFS=y
CONFIG_NFSD=m
-CONFIG_NFSD_V3=y
CONFIG_CIFS=m
# CONFIG_CIFS_STATS2 is not set
# CONFIG_CIFS_DEBUG is not set
@@ -592,7 +588,7 @@ CONFIG_TEST_UUID=m
CONFIG_TEST_XARRAY=m
CONFIG_TEST_OVERFLOW=m
CONFIG_TEST_RHASHTABLE=m
-CONFIG_TEST_HASH=m
+CONFIG_TEST_SIPHASH=m
CONFIG_TEST_IDA=m
CONFIG_TEST_BITOPS=m
CONFIG_TEST_VMALLOC=m
diff --git a/arch/m68k/configs/hp300_defconfig b/arch/m68k/configs/hp300_defconfig
index 5e80aa0869d5..e306e3813607 100644
--- a/arch/m68k/configs/hp300_defconfig
+++ b/arch/m68k/configs/hp300_defconfig
@@ -99,7 +99,6 @@ CONFIG_NF_TABLES_NETDEV=y
CONFIG_NFT_NUMGEN=m
CONFIG_NFT_CT=m
CONFIG_NFT_FLOW_OFFLOAD=m
-CONFIG_NFT_COUNTER=m
CONFIG_NFT_CONNLIMIT=m
CONFIG_NFT_LOG=m
CONFIG_NFT_LIMIT=m
@@ -199,7 +198,6 @@ CONFIG_IP_SET_LIST_SET=m
CONFIG_NFT_DUP_IPV4=m
CONFIG_NFT_FIB_IPV4=m
CONFIG_NF_TABLES_ARP=y
-CONFIG_NF_FLOW_TABLE_IPV4=m
CONFIG_NF_LOG_ARP=m
CONFIG_NF_LOG_IPV4=m
CONFIG_IP_NF_IPTABLES=m
@@ -224,7 +222,6 @@ CONFIG_IP_NF_ARPFILTER=m
CONFIG_IP_NF_ARP_MANGLE=m
CONFIG_NFT_DUP_IPV6=m
CONFIG_NFT_FIB_IPV6=m
-CONFIG_NF_FLOW_TABLE_IPV6=m
CONFIG_IP6_NF_IPTABLES=m
CONFIG_IP6_NF_MATCH_AH=m
CONFIG_IP6_NF_MATCH_EUI64=m
@@ -395,6 +392,7 @@ CONFIG_PTP_1588_CLOCK=m
# CONFIG_HWMON is not set
CONFIG_FB=y
CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE_LEGACY_ACCELERATION=y
CONFIG_LOGO=y
# CONFIG_LOGO_LINUX_MONO is not set
# CONFIG_LOGO_LINUX_VGA16 is not set
@@ -459,7 +457,6 @@ CONFIG_NFS_V4=m
CONFIG_NFS_SWAP=y
CONFIG_ROOT_NFS=y
CONFIG_NFSD=m
-CONFIG_NFSD_V3=y
CONFIG_CIFS=m
# CONFIG_CIFS_STATS2 is not set
# CONFIG_CIFS_DEBUG is not set
@@ -601,7 +598,7 @@ CONFIG_TEST_UUID=m
CONFIG_TEST_XARRAY=m
CONFIG_TEST_OVERFLOW=m
CONFIG_TEST_RHASHTABLE=m
-CONFIG_TEST_HASH=m
+CONFIG_TEST_SIPHASH=m
CONFIG_TEST_IDA=m
CONFIG_TEST_BITOPS=m
CONFIG_TEST_VMALLOC=m
diff --git a/arch/m68k/configs/mac_defconfig b/arch/m68k/configs/mac_defconfig
index e84326a3f62d..41316cf02441 100644
--- a/arch/m68k/configs/mac_defconfig
+++ b/arch/m68k/configs/mac_defconfig
@@ -98,7 +98,6 @@ CONFIG_NF_TABLES_NETDEV=y
CONFIG_NFT_NUMGEN=m
CONFIG_NFT_CT=m
CONFIG_NFT_FLOW_OFFLOAD=m
-CONFIG_NFT_COUNTER=m
CONFIG_NFT_CONNLIMIT=m
CONFIG_NFT_LOG=m
CONFIG_NFT_LIMIT=m
@@ -198,7 +197,6 @@ CONFIG_IP_SET_LIST_SET=m
CONFIG_NFT_DUP_IPV4=m
CONFIG_NFT_FIB_IPV4=m
CONFIG_NF_TABLES_ARP=y
-CONFIG_NF_FLOW_TABLE_IPV4=m
CONFIG_NF_LOG_ARP=m
CONFIG_NF_LOG_IPV4=m
CONFIG_IP_NF_IPTABLES=m
@@ -223,7 +221,6 @@ CONFIG_IP_NF_ARPFILTER=m
CONFIG_IP_NF_ARP_MANGLE=m
CONFIG_NFT_DUP_IPV6=m
CONFIG_NFT_FIB_IPV6=m
-CONFIG_NF_FLOW_TABLE_IPV6=m
CONFIG_IP6_NF_IPTABLES=m
CONFIG_IP6_NF_MATCH_AH=m
CONFIG_IP6_NF_MATCH_EUI64=m
@@ -480,7 +477,6 @@ CONFIG_NFS_V4=m
CONFIG_NFS_SWAP=y
CONFIG_ROOT_NFS=y
CONFIG_NFSD=m
-CONFIG_NFSD_V3=y
CONFIG_CIFS=m
# CONFIG_CIFS_STATS2 is not set
# CONFIG_CIFS_DEBUG is not set
@@ -623,7 +619,7 @@ CONFIG_TEST_UUID=m
CONFIG_TEST_XARRAY=m
CONFIG_TEST_OVERFLOW=m
CONFIG_TEST_RHASHTABLE=m
-CONFIG_TEST_HASH=m
+CONFIG_TEST_SIPHASH=m
CONFIG_TEST_IDA=m
CONFIG_TEST_BITOPS=m
CONFIG_TEST_VMALLOC=m
diff --git a/arch/m68k/configs/multi_defconfig b/arch/m68k/configs/multi_defconfig
index 337552f43339..2fc3f0df6d43 100644
--- a/arch/m68k/configs/multi_defconfig
+++ b/arch/m68k/configs/multi_defconfig
@@ -118,7 +118,6 @@ CONFIG_NF_TABLES_NETDEV=y
CONFIG_NFT_NUMGEN=m
CONFIG_NFT_CT=m
CONFIG_NFT_FLOW_OFFLOAD=m
-CONFIG_NFT_COUNTER=m
CONFIG_NFT_CONNLIMIT=m
CONFIG_NFT_LOG=m
CONFIG_NFT_LIMIT=m
@@ -218,7 +217,6 @@ CONFIG_IP_SET_LIST_SET=m
CONFIG_NFT_DUP_IPV4=m
CONFIG_NFT_FIB_IPV4=m
CONFIG_NF_TABLES_ARP=y
-CONFIG_NF_FLOW_TABLE_IPV4=m
CONFIG_NF_LOG_ARP=m
CONFIG_NF_LOG_IPV4=m
CONFIG_IP_NF_IPTABLES=m
@@ -243,7 +241,6 @@ CONFIG_IP_NF_ARPFILTER=m
CONFIG_IP_NF_ARP_MANGLE=m
CONFIG_NFT_DUP_IPV6=m
CONFIG_NFT_FIB_IPV6=m
-CONFIG_NF_FLOW_TABLE_IPV6=m
CONFIG_IP6_NF_IPTABLES=m
CONFIG_IP6_NF_MATCH_AH=m
CONFIG_IP6_NF_MATCH_EUI64=m
@@ -497,6 +494,7 @@ CONFIG_FB_ATARI=y
CONFIG_FB_VALKYRIE=y
CONFIG_FB_MAC=y
CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE_LEGACY_ACCELERATION=y
CONFIG_LOGO=y
CONFIG_SOUND=m
CONFIG_DMASOUND_ATARI=m
@@ -565,7 +563,6 @@ CONFIG_NFS_V4=m
CONFIG_NFS_SWAP=y
CONFIG_ROOT_NFS=y
CONFIG_NFSD=m
-CONFIG_NFSD_V3=y
CONFIG_CIFS=m
# CONFIG_CIFS_STATS2 is not set
# CONFIG_CIFS_DEBUG is not set
@@ -708,7 +705,7 @@ CONFIG_TEST_UUID=m
CONFIG_TEST_XARRAY=m
CONFIG_TEST_OVERFLOW=m
CONFIG_TEST_RHASHTABLE=m
-CONFIG_TEST_HASH=m
+CONFIG_TEST_SIPHASH=m
CONFIG_TEST_IDA=m
CONFIG_TEST_BITOPS=m
CONFIG_TEST_VMALLOC=m
diff --git a/arch/m68k/configs/mvme147_defconfig b/arch/m68k/configs/mvme147_defconfig
index 7b688f7d272a..9603f4396469 100644
--- a/arch/m68k/configs/mvme147_defconfig
+++ b/arch/m68k/configs/mvme147_defconfig
@@ -96,7 +96,6 @@ CONFIG_NF_TABLES_NETDEV=y
CONFIG_NFT_NUMGEN=m
CONFIG_NFT_CT=m
CONFIG_NFT_FLOW_OFFLOAD=m
-CONFIG_NFT_COUNTER=m
CONFIG_NFT_CONNLIMIT=m
CONFIG_NFT_LOG=m
CONFIG_NFT_LIMIT=m
@@ -196,7 +195,6 @@ CONFIG_IP_SET_LIST_SET=m
CONFIG_NFT_DUP_IPV4=m
CONFIG_NFT_FIB_IPV4=m
CONFIG_NF_TABLES_ARP=y
-CONFIG_NF_FLOW_TABLE_IPV4=m
CONFIG_NF_LOG_ARP=m
CONFIG_NF_LOG_IPV4=m
CONFIG_IP_NF_IPTABLES=m
@@ -221,7 +219,6 @@ CONFIG_IP_NF_ARPFILTER=m
CONFIG_IP_NF_ARP_MANGLE=m
CONFIG_NFT_DUP_IPV6=m
CONFIG_NFT_FIB_IPV6=m
-CONFIG_NF_FLOW_TABLE_IPV6=m
CONFIG_IP6_NF_IPTABLES=m
CONFIG_IP6_NF_MATCH_AH=m
CONFIG_IP6_NF_MATCH_EUI64=m
@@ -449,7 +446,6 @@ CONFIG_NFS_V4=m
CONFIG_NFS_SWAP=y
CONFIG_ROOT_NFS=y
CONFIG_NFSD=m
-CONFIG_NFSD_V3=y
CONFIG_CIFS=m
# CONFIG_CIFS_STATS2 is not set
# CONFIG_CIFS_DEBUG is not set
@@ -591,7 +587,7 @@ CONFIG_TEST_UUID=m
CONFIG_TEST_XARRAY=m
CONFIG_TEST_OVERFLOW=m
CONFIG_TEST_RHASHTABLE=m
-CONFIG_TEST_HASH=m
+CONFIG_TEST_SIPHASH=m
CONFIG_TEST_IDA=m
CONFIG_TEST_BITOPS=m
CONFIG_TEST_VMALLOC=m
diff --git a/arch/m68k/configs/mvme16x_defconfig b/arch/m68k/configs/mvme16x_defconfig
index 7c2cb31d63dd..c9cabd3344df 100644
--- a/arch/m68k/configs/mvme16x_defconfig
+++ b/arch/m68k/configs/mvme16x_defconfig
@@ -97,7 +97,6 @@ CONFIG_NF_TABLES_NETDEV=y
CONFIG_NFT_NUMGEN=m
CONFIG_NFT_CT=m
CONFIG_NFT_FLOW_OFFLOAD=m
-CONFIG_NFT_COUNTER=m
CONFIG_NFT_CONNLIMIT=m
CONFIG_NFT_LOG=m
CONFIG_NFT_LIMIT=m
@@ -197,7 +196,6 @@ CONFIG_IP_SET_LIST_SET=m
CONFIG_NFT_DUP_IPV4=m
CONFIG_NFT_FIB_IPV4=m
CONFIG_NF_TABLES_ARP=y
-CONFIG_NF_FLOW_TABLE_IPV4=m
CONFIG_NF_LOG_ARP=m
CONFIG_NF_LOG_IPV4=m
CONFIG_IP_NF_IPTABLES=m
@@ -222,7 +220,6 @@ CONFIG_IP_NF_ARPFILTER=m
CONFIG_IP_NF_ARP_MANGLE=m
CONFIG_NFT_DUP_IPV6=m
CONFIG_NFT_FIB_IPV6=m
-CONFIG_NF_FLOW_TABLE_IPV6=m
CONFIG_IP6_NF_IPTABLES=m
CONFIG_IP6_NF_MATCH_AH=m
CONFIG_IP6_NF_MATCH_EUI64=m
@@ -450,7 +447,6 @@ CONFIG_NFS_V4=m
CONFIG_NFS_SWAP=y
CONFIG_ROOT_NFS=y
CONFIG_NFSD=m
-CONFIG_NFSD_V3=y
CONFIG_CIFS=m
# CONFIG_CIFS_STATS2 is not set
# CONFIG_CIFS_DEBUG is not set
@@ -592,7 +588,7 @@ CONFIG_TEST_UUID=m
CONFIG_TEST_XARRAY=m
CONFIG_TEST_OVERFLOW=m
CONFIG_TEST_RHASHTABLE=m
-CONFIG_TEST_HASH=m
+CONFIG_TEST_SIPHASH=m
CONFIG_TEST_IDA=m
CONFIG_TEST_BITOPS=m
CONFIG_TEST_VMALLOC=m
diff --git a/arch/m68k/configs/q40_defconfig b/arch/m68k/configs/q40_defconfig
index ca43897af26d..5f994bf44fb8 100644
--- a/arch/m68k/configs/q40_defconfig
+++ b/arch/m68k/configs/q40_defconfig
@@ -98,7 +98,6 @@ CONFIG_NF_TABLES_NETDEV=y
CONFIG_NFT_NUMGEN=m
CONFIG_NFT_CT=m
CONFIG_NFT_FLOW_OFFLOAD=m
-CONFIG_NFT_COUNTER=m
CONFIG_NFT_CONNLIMIT=m
CONFIG_NFT_LOG=m
CONFIG_NFT_LIMIT=m
@@ -198,7 +197,6 @@ CONFIG_IP_SET_LIST_SET=m
CONFIG_NFT_DUP_IPV4=m
CONFIG_NFT_FIB_IPV4=m
CONFIG_NF_TABLES_ARP=y
-CONFIG_NF_FLOW_TABLE_IPV4=m
CONFIG_NF_LOG_ARP=m
CONFIG_NF_LOG_IPV4=m
CONFIG_IP_NF_IPTABLES=m
@@ -223,7 +221,6 @@ CONFIG_IP_NF_ARPFILTER=m
CONFIG_IP_NF_ARP_MANGLE=m
CONFIG_NFT_DUP_IPV6=m
CONFIG_NFT_FIB_IPV6=m
-CONFIG_NF_FLOW_TABLE_IPV6=m
CONFIG_IP6_NF_IPTABLES=m
CONFIG_IP6_NF_MATCH_AH=m
CONFIG_IP6_NF_MATCH_EUI64=m
@@ -467,7 +464,6 @@ CONFIG_NFS_V4=m
CONFIG_NFS_SWAP=y
CONFIG_ROOT_NFS=y
CONFIG_NFSD=m
-CONFIG_NFSD_V3=y
CONFIG_CIFS=m
# CONFIG_CIFS_STATS2 is not set
# CONFIG_CIFS_DEBUG is not set
@@ -610,7 +606,7 @@ CONFIG_TEST_UUID=m
CONFIG_TEST_XARRAY=m
CONFIG_TEST_OVERFLOW=m
CONFIG_TEST_RHASHTABLE=m
-CONFIG_TEST_HASH=m
+CONFIG_TEST_SIPHASH=m
CONFIG_TEST_IDA=m
CONFIG_TEST_BITOPS=m
CONFIG_TEST_VMALLOC=m
diff --git a/arch/m68k/configs/sun3_defconfig b/arch/m68k/configs/sun3_defconfig
index e3d515f37144..183e33f7d4a0 100644
--- a/arch/m68k/configs/sun3_defconfig
+++ b/arch/m68k/configs/sun3_defconfig
@@ -94,7 +94,6 @@ CONFIG_NF_TABLES_NETDEV=y
CONFIG_NFT_NUMGEN=m
CONFIG_NFT_CT=m
CONFIG_NFT_FLOW_OFFLOAD=m
-CONFIG_NFT_COUNTER=m
CONFIG_NFT_CONNLIMIT=m
CONFIG_NFT_LOG=m
CONFIG_NFT_LIMIT=m
@@ -194,7 +193,6 @@ CONFIG_IP_SET_LIST_SET=m
CONFIG_NFT_DUP_IPV4=m
CONFIG_NFT_FIB_IPV4=m
CONFIG_NF_TABLES_ARP=y
-CONFIG_NF_FLOW_TABLE_IPV4=m
CONFIG_NF_LOG_ARP=m
CONFIG_NF_LOG_IPV4=m
CONFIG_IP_NF_IPTABLES=m
@@ -219,7 +217,6 @@ CONFIG_IP_NF_ARPFILTER=m
CONFIG_IP_NF_ARP_MANGLE=m
CONFIG_NFT_DUP_IPV6=m
CONFIG_NFT_FIB_IPV6=m
-CONFIG_NF_FLOW_TABLE_IPV6=m
CONFIG_IP6_NF_IPTABLES=m
CONFIG_IP6_NF_MATCH_AH=m
CONFIG_IP6_NF_MATCH_EUI64=m
@@ -388,9 +385,6 @@ CONFIG_NTP_PPS=y
CONFIG_PPS_CLIENT_LDISC=m
CONFIG_PTP_1588_CLOCK=m
# CONFIG_HWMON is not set
-CONFIG_FB=y
-CONFIG_FRAMEBUFFER_CONSOLE=y
-CONFIG_LOGO=y
CONFIG_HID=m
CONFIG_HIDRAW=y
CONFIG_UHID=m
@@ -452,7 +446,6 @@ CONFIG_NFS_V4=m
CONFIG_NFS_SWAP=y
CONFIG_ROOT_NFS=y
CONFIG_NFSD=m
-CONFIG_NFSD_V3=y
CONFIG_CIFS=m
# CONFIG_CIFS_STATS2 is not set
# CONFIG_CIFS_DEBUG is not set
@@ -593,7 +586,7 @@ CONFIG_TEST_UUID=m
CONFIG_TEST_XARRAY=m
CONFIG_TEST_OVERFLOW=m
CONFIG_TEST_RHASHTABLE=m
-CONFIG_TEST_HASH=m
+CONFIG_TEST_SIPHASH=m
CONFIG_TEST_IDA=m
CONFIG_TEST_BITOPS=m
CONFIG_TEST_VMALLOC=m
diff --git a/arch/m68k/configs/sun3x_defconfig b/arch/m68k/configs/sun3x_defconfig
index d601606c969b..8214263b9ab8 100644
--- a/arch/m68k/configs/sun3x_defconfig
+++ b/arch/m68k/configs/sun3x_defconfig
@@ -94,7 +94,6 @@ CONFIG_NF_TABLES_NETDEV=y
CONFIG_NFT_NUMGEN=m
CONFIG_NFT_CT=m
CONFIG_NFT_FLOW_OFFLOAD=m
-CONFIG_NFT_COUNTER=m
CONFIG_NFT_CONNLIMIT=m
CONFIG_NFT_LOG=m
CONFIG_NFT_LIMIT=m
@@ -194,7 +193,6 @@ CONFIG_IP_SET_LIST_SET=m
CONFIG_NFT_DUP_IPV4=m
CONFIG_NFT_FIB_IPV4=m
CONFIG_NF_TABLES_ARP=y
-CONFIG_NF_FLOW_TABLE_IPV4=m
CONFIG_NF_LOG_ARP=m
CONFIG_NF_LOG_IPV4=m
CONFIG_IP_NF_IPTABLES=m
@@ -219,7 +217,6 @@ CONFIG_IP_NF_ARPFILTER=m
CONFIG_IP_NF_ARP_MANGLE=m
CONFIG_NFT_DUP_IPV6=m
CONFIG_NFT_FIB_IPV6=m
-CONFIG_NF_FLOW_TABLE_IPV6=m
CONFIG_IP6_NF_IPTABLES=m
CONFIG_IP6_NF_MATCH_AH=m
CONFIG_IP6_NF_MATCH_EUI64=m
@@ -387,9 +384,6 @@ CONFIG_NTP_PPS=y
CONFIG_PPS_CLIENT_LDISC=m
CONFIG_PTP_1588_CLOCK=m
# CONFIG_HWMON is not set
-CONFIG_FB=y
-CONFIG_FRAMEBUFFER_CONSOLE=y
-CONFIG_LOGO=y
CONFIG_HID=m
CONFIG_HIDRAW=y
CONFIG_UHID=m
@@ -451,7 +445,6 @@ CONFIG_NFS_V4=m
CONFIG_NFS_SWAP=y
CONFIG_ROOT_NFS=y
CONFIG_NFSD=m
-CONFIG_NFSD_V3=y
CONFIG_CIFS=m
# CONFIG_CIFS_STATS2 is not set
# CONFIG_CIFS_DEBUG is not set
@@ -593,7 +586,7 @@ CONFIG_TEST_UUID=m
CONFIG_TEST_XARRAY=m
CONFIG_TEST_OVERFLOW=m
CONFIG_TEST_RHASHTABLE=m
-CONFIG_TEST_HASH=m
+CONFIG_TEST_SIPHASH=m
CONFIG_TEST_IDA=m
CONFIG_TEST_BITOPS=m
CONFIG_TEST_VMALLOC=m
diff --git a/arch/m68k/emu/nfblock.c b/arch/m68k/emu/nfblock.c
index 9c57b245dc12..267b02cc5655 100644
--- a/arch/m68k/emu/nfblock.c
+++ b/arch/m68k/emu/nfblock.c
@@ -13,7 +13,6 @@
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/types.h>
-#include <linux/genhd.h>
#include <linux/blkdev.h>
#include <linux/hdreg.h>
#include <linux/slab.h>
diff --git a/arch/m68k/hp300/config.c b/arch/m68k/hp300/config.c
index ce1eb3d3d55d..2c92843397c3 100644
--- a/arch/m68k/hp300/config.c
+++ b/arch/m68k/hp300/config.c
@@ -22,6 +22,7 @@
#include <asm/blinken.h>
#include <asm/io.h> /* readb() and writeb() */
#include <asm/hp300hw.h>
+#include <asm/config.h>
#include "time.h"
diff --git a/arch/m68k/include/asm/cmpxchg.h b/arch/m68k/include/asm/cmpxchg.h
index e8ca4b0ccefa..6cf464cdab06 100644
--- a/arch/m68k/include/asm/cmpxchg.h
+++ b/arch/m68k/include/asm/cmpxchg.h
@@ -4,8 +4,7 @@
#include <linux/irqflags.h>
-struct __xchg_dummy { unsigned long a[100]; };
-#define __xg(x) ((volatile struct __xchg_dummy *)(x))
+#define __xg(type, x) ((volatile type *)(x))
extern unsigned long __invalid_xchg_size(unsigned long, volatile void *, int);
@@ -50,7 +49,7 @@ static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int siz
"1:\n\t"
"casb %0,%1,%2\n\t"
"jne 1b"
- : "=&d" (x) : "d" (x), "m" (*__xg(ptr)) : "memory");
+ : "=&d" (x) : "d" (x), "m" (*__xg(u8, ptr)) : "memory");
break;
case 2:
__asm__ __volatile__
@@ -58,7 +57,7 @@ static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int siz
"1:\n\t"
"casw %0,%1,%2\n\t"
"jne 1b"
- : "=&d" (x) : "d" (x), "m" (*__xg(ptr)) : "memory");
+ : "=&d" (x) : "d" (x), "m" (*__xg(u16, ptr)) : "memory");
break;
case 4:
__asm__ __volatile__
@@ -66,7 +65,7 @@ static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int siz
"1:\n\t"
"casl %0,%1,%2\n\t"
"jne 1b"
- : "=&d" (x) : "d" (x), "m" (*__xg(ptr)) : "memory");
+ : "=&d" (x) : "d" (x), "m" (*__xg(u32, ptr)) : "memory");
break;
default:
x = __invalid_xchg_size(x, ptr, size);
diff --git a/arch/m68k/include/asm/config.h b/arch/m68k/include/asm/config.h
new file mode 100644
index 000000000000..e73ffa23c4f5
--- /dev/null
+++ b/arch/m68k/include/asm/config.h
@@ -0,0 +1,33 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+/*
+ * This file contains prototypes provided by each m68k machine
+ * to parse bootinfo data structures and to configure the machine
+ */
+
+#ifndef _M68K_CONFIG_H
+#define _M68K_CONFIG_H
+
+extern int amiga_parse_bootinfo(const struct bi_record *record);
+extern int apollo_parse_bootinfo(const struct bi_record *record);
+extern int atari_parse_bootinfo(const struct bi_record *record);
+extern int bvme6000_parse_bootinfo(const struct bi_record *record);
+extern int hp300_parse_bootinfo(const struct bi_record *record);
+extern int mac_parse_bootinfo(const struct bi_record *record);
+extern int mvme147_parse_bootinfo(const struct bi_record *record);
+extern int mvme16x_parse_bootinfo(const struct bi_record *record);
+extern int q40_parse_bootinfo(const struct bi_record *record);
+
+extern void config_amiga(void);
+extern void config_apollo(void);
+extern void config_atari(void);
+extern void config_bvme6000(void);
+extern void config_hp300(void);
+extern void config_mac(void);
+extern void config_mvme147(void);
+extern void config_mvme16x(void);
+extern void config_q40(void);
+extern void config_sun3(void);
+extern void config_sun3x(void);
+
+#endif /* _M68K_CONFIG_H */
diff --git a/arch/m68k/include/asm/current.h b/arch/m68k/include/asm/current.h
index 6390ef2f7f86..c117907e1276 100644
--- a/arch/m68k/include/asm/current.h
+++ b/arch/m68k/include/asm/current.h
@@ -24,6 +24,8 @@ static inline struct task_struct *get_current(void)
#define current get_current()
-#endif /* CONFNIG_MMU */
+#endif /* CONFIG_MMU */
+
+register unsigned long current_stack_pointer __asm__("sp");
#endif /* !(_M68K_CURRENT_H) */
diff --git a/arch/m68k/include/asm/mcf_pgtable.h b/arch/m68k/include/asm/mcf_pgtable.h
index 6f2b87d7a50d..94f38d76e278 100644
--- a/arch/m68k/include/asm/mcf_pgtable.h
+++ b/arch/m68k/include/asm/mcf_pgtable.h
@@ -322,6 +322,7 @@ extern pgd_t kernel_pg_dir[PTRS_PER_PGD];
#define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) })
#define __swp_entry_to_pte(x) (__pte((x).val))
+#define pmd_pfn(pmd) (pmd_val(pmd) >> PAGE_SHIFT)
#define pmd_page(pmd) (pfn_to_page(pmd_val(pmd) >> PAGE_SHIFT))
#define pfn_pte(pfn, prot) __pte(((pfn) << PAGE_SHIFT) | pgprot_val(prot))
diff --git a/arch/m68k/include/asm/motorola_pgtable.h b/arch/m68k/include/asm/motorola_pgtable.h
index 022c3abc280d..7c9b56e2a750 100644
--- a/arch/m68k/include/asm/motorola_pgtable.h
+++ b/arch/m68k/include/asm/motorola_pgtable.h
@@ -147,6 +147,7 @@ static inline void pud_set(pud_t *pudp, pmd_t *pmdp)
#define pmd_present(pmd) (pmd_val(pmd) & _PAGE_TABLE)
#define pmd_clear(pmdp) ({ pmd_val(*pmdp) = 0; })
+#define pmd_pfn(pmd) ((pmd_val(pmd) & _TABLE_MASK) >> PAGE_SHIFT)
/*
* m68k does not have huge pages (020/030 actually could), but generic code
* expects pmd_page() to exists, only to then DCE it all. Provide a dummy to
diff --git a/arch/m68k/include/asm/sun3_pgtable.h b/arch/m68k/include/asm/sun3_pgtable.h
index 5b24283a0a42..5e4e753f0d24 100644
--- a/arch/m68k/include/asm/sun3_pgtable.h
+++ b/arch/m68k/include/asm/sun3_pgtable.h
@@ -130,6 +130,7 @@ static inline void pte_clear (struct mm_struct *mm, unsigned long addr, pte_t *p
({ pte_t __pte; pte_val(__pte) = pfn | pgprot_val(pgprot); __pte; })
#define pte_page(pte) virt_to_page(__pte_page(pte))
+#define pmd_pfn(pmd) (pmd_val(pmd) >> PAGE_SHIFT)
#define pmd_page(pmd) virt_to_page(pmd_page_vaddr(pmd))
diff --git a/arch/m68k/include/asm/uaccess.h b/arch/m68k/include/asm/uaccess.h
index ba670523885c..64914872a5c9 100644
--- a/arch/m68k/include/asm/uaccess.h
+++ b/arch/m68k/include/asm/uaccess.h
@@ -10,17 +10,7 @@
#include <linux/compiler.h>
#include <linux/types.h>
#include <asm/extable.h>
-
-/* We let the MMU do all checking */
-static inline int access_ok(const void __user *addr,
- unsigned long size)
-{
- /*
- * XXX: for !CONFIG_CPU_HAS_ADDRESS_SPACES this really needs to check
- * for TASK_SIZE!
- */
- return 1;
-}
+#include <asm-generic/access_ok.h>
/*
* Not all varients of the 68k family support the notion of address spaces.
@@ -390,8 +380,6 @@ raw_copy_to_user(void __user *to, const void *from, unsigned long n)
#define INLINE_COPY_FROM_USER
#define INLINE_COPY_TO_USER
-#define HAVE_GET_KERNEL_NOFAULT
-
#define __get_kernel_nofault(dst, src, type, err_label) \
do { \
type *__gk_dst = (type *)(dst); \
diff --git a/arch/m68k/include/uapi/asm/signal.h b/arch/m68k/include/uapi/asm/signal.h
index 4619291df601..80f520b9b10b 100644
--- a/arch/m68k/include/uapi/asm/signal.h
+++ b/arch/m68k/include/uapi/asm/signal.h
@@ -83,7 +83,7 @@ struct sigaction {
typedef struct sigaltstack {
void __user *ss_sp;
int ss_flags;
- size_t ss_size;
+ __kernel_size_t ss_size;
} stack_t;
#endif /* _UAPI_M68K_SIGNAL_H */
diff --git a/arch/m68k/kernel/setup_mm.c b/arch/m68k/kernel/setup_mm.c
index 49e573b94326..8f94feed969c 100644
--- a/arch/m68k/kernel/setup_mm.c
+++ b/arch/m68k/kernel/setup_mm.c
@@ -16,7 +16,6 @@
#include <linux/interrupt.h>
#include <linux/fs.h>
#include <linux/console.h>
-#include <linux/genhd.h>
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/init.h>
@@ -47,6 +46,7 @@
#endif
#include <asm/macintosh.h>
#include <asm/natfeat.h>
+#include <asm/config.h>
#if !FPSTATESIZE || !NR_IRQS
#warning No CPU/platform type selected, your kernel will not work!
@@ -113,28 +113,6 @@ EXPORT_SYMBOL(isa_type);
EXPORT_SYMBOL(isa_sex);
#endif
-extern int amiga_parse_bootinfo(const struct bi_record *);
-extern int atari_parse_bootinfo(const struct bi_record *);
-extern int mac_parse_bootinfo(const struct bi_record *);
-extern int q40_parse_bootinfo(const struct bi_record *);
-extern int bvme6000_parse_bootinfo(const struct bi_record *);
-extern int mvme16x_parse_bootinfo(const struct bi_record *);
-extern int mvme147_parse_bootinfo(const struct bi_record *);
-extern int hp300_parse_bootinfo(const struct bi_record *);
-extern int apollo_parse_bootinfo(const struct bi_record *);
-
-extern void config_amiga(void);
-extern void config_atari(void);
-extern void config_mac(void);
-extern void config_sun3(void);
-extern void config_apollo(void);
-extern void config_mvme147(void);
-extern void config_mvme16x(void);
-extern void config_bvme6000(void);
-extern void config_hp300(void);
-extern void config_q40(void);
-extern void config_sun3x(void);
-
#define MASK_256K 0xfffc0000
extern void paging_init(void);
diff --git a/arch/m68k/mac/config.c b/arch/m68k/mac/config.c
index 5d16f9b47aa9..65d124ec80bb 100644
--- a/arch/m68k/mac/config.c
+++ b/arch/m68k/mac/config.c
@@ -47,6 +47,7 @@
#include <asm/mac_via.h>
#include <asm/mac_oss.h>
#include <asm/mac_psc.h>
+#include <asm/config.h>
/* Mac bootinfo struct */
struct mac_booter_data mac_bi_data;
diff --git a/arch/m68k/mm/fault.c b/arch/m68k/mm/fault.c
index 1493cf5eac1e..71aa9f6315dc 100644
--- a/arch/m68k/mm/fault.c
+++ b/arch/m68k/mm/fault.c
@@ -93,8 +93,6 @@ retry:
vma = find_vma(mm, address);
if (!vma)
goto map_err;
- if (vma->vm_flags & VM_IO)
- goto acc_err;
if (vma->vm_start <= address)
goto good_area;
if (!(vma->vm_flags & VM_GROWSDOWN))
diff --git a/arch/m68k/mvme147/config.c b/arch/m68k/mvme147/config.c
index dfd6202fd403..4e6218115f43 100644
--- a/arch/m68k/mvme147/config.c
+++ b/arch/m68k/mvme147/config.c
@@ -22,7 +22,6 @@
#include <linux/linkage.h>
#include <linux/init.h>
#include <linux/major.h>
-#include <linux/genhd.h>
#include <linux/rtc.h>
#include <linux/interrupt.h>
@@ -34,6 +33,7 @@
#include <asm/traps.h>
#include <asm/machdep.h>
#include <asm/mvme147hw.h>
+#include <asm/config.h>
static void mvme147_get_model(char *model);
diff --git a/arch/m68k/mvme16x/config.c b/arch/m68k/mvme16x/config.c
index b4422c2dfbbf..f00c7aa058de 100644
--- a/arch/m68k/mvme16x/config.c
+++ b/arch/m68k/mvme16x/config.c
@@ -24,7 +24,6 @@
#include <linux/linkage.h>
#include <linux/init.h>
#include <linux/major.h>
-#include <linux/genhd.h>
#include <linux/rtc.h>
#include <linux/interrupt.h>
#include <linux/module.h>
@@ -37,6 +36,7 @@
#include <asm/traps.h>
#include <asm/machdep.h>
#include <asm/mvme16xhw.h>
+#include <asm/config.h>
extern t_bdid mvme_bdid;
diff --git a/arch/m68k/q40/config.c b/arch/m68k/q40/config.c
index 5caf1e5be1c2..9237243077ce 100644
--- a/arch/m68k/q40/config.c
+++ b/arch/m68k/q40/config.c
@@ -34,6 +34,7 @@
#include <asm/traps.h>
#include <asm/machdep.h>
#include <asm/q40_master.h>
+#include <asm/config.h>
extern void q40_init_IRQ(void);
static void q40_get_model(char *model);
diff --git a/arch/microblaze/Kconfig b/arch/microblaze/Kconfig
index 59798e43cdb0..8cf429ad1c84 100644
--- a/arch/microblaze/Kconfig
+++ b/arch/microblaze/Kconfig
@@ -42,9 +42,10 @@ config MICROBLAZE
select CPU_NO_EFFICIENT_FFS
select MMU_GATHER_NO_RANGE
select SPARSE_IRQ
- select SET_FS
select ZONE_DMA
select TRACE_IRQFLAGS_SUPPORT
+ select GENERIC_IRQ_MULTI_HANDLER
+ select HANDLE_DOMAIN_IRQ
# Endianness selection
choice
diff --git a/arch/microblaze/include/asm/irq.h b/arch/microblaze/include/asm/irq.h
index 0a28e80bbab0..cb6ab55d1d01 100644
--- a/arch/microblaze/include/asm/irq.h
+++ b/arch/microblaze/include/asm/irq.h
@@ -11,7 +11,4 @@
struct pt_regs;
extern void do_IRQ(struct pt_regs *regs);
-/* should be defined in each interrupt controller driver */
-extern unsigned int xintc_get_irq(void);
-
#endif /* _ASM_MICROBLAZE_IRQ_H */
diff --git a/arch/microblaze/include/asm/pgtable.h b/arch/microblaze/include/asm/pgtable.h
index c136a01e467e..0c72646370e1 100644
--- a/arch/microblaze/include/asm/pgtable.h
+++ b/arch/microblaze/include/asm/pgtable.h
@@ -399,6 +399,9 @@ static inline unsigned long pmd_page_vaddr(pmd_t pmd)
return ((unsigned long) (pmd_val(pmd) & PAGE_MASK));
}
+/* returns pfn of the pmd entry*/
+#define pmd_pfn(pmd) (__pa(pmd_val(pmd)) >> PAGE_SHIFT)
+
/* returns struct *page of the pmd entry*/
#define pmd_page(pmd) (pfn_to_page(__pa(pmd_val(pmd)) >> PAGE_SHIFT))
diff --git a/arch/microblaze/include/asm/thread_info.h b/arch/microblaze/include/asm/thread_info.h
index 44f5ca331862..a0ddd2a36fb9 100644
--- a/arch/microblaze/include/asm/thread_info.h
+++ b/arch/microblaze/include/asm/thread_info.h
@@ -56,17 +56,12 @@ struct cpu_context {
__u32 fsr;
};
-typedef struct {
- unsigned long seg;
-} mm_segment_t;
-
struct thread_info {
struct task_struct *task; /* main task structure */
unsigned long flags; /* low level flags */
unsigned long status; /* thread-synchronous flags */
__u32 cpu; /* current CPU */
__s32 preempt_count; /* 0 => preemptable,< 0 => BUG*/
- mm_segment_t addr_limit; /* thread address space */
struct cpu_context cpu_context;
};
@@ -80,7 +75,6 @@ struct thread_info {
.flags = 0, \
.cpu = 0, \
.preempt_count = INIT_PREEMPT_COUNT, \
- .addr_limit = KERNEL_DS, \
}
/* how to get the thread information struct from C */
diff --git a/arch/microblaze/include/asm/uaccess.h b/arch/microblaze/include/asm/uaccess.h
index d2a8ef9f8978..3aab2f17e046 100644
--- a/arch/microblaze/include/asm/uaccess.h
+++ b/arch/microblaze/include/asm/uaccess.h
@@ -15,48 +15,7 @@
#include <linux/pgtable.h>
#include <asm/extable.h>
#include <linux/string.h>
-
-/*
- * On Microblaze the fs value is actually the top of the corresponding
- * address space.
- *
- * The fs value determines whether argument validity checking should be
- * performed or not. If get_fs() == USER_DS, checking is performed, with
- * get_fs() == KERNEL_DS, checking is bypassed.
- *
- * For historical reasons, these macros are grossly misnamed.
- *
- * For non-MMU arch like Microblaze, KERNEL_DS and USER_DS is equal.
- */
-# define MAKE_MM_SEG(s) ((mm_segment_t) { (s) })
-
-# define KERNEL_DS MAKE_MM_SEG(0xFFFFFFFF)
-# define USER_DS MAKE_MM_SEG(TASK_SIZE - 1)
-
-# define get_fs() (current_thread_info()->addr_limit)
-# define set_fs(val) (current_thread_info()->addr_limit = (val))
-# define user_addr_max() get_fs().seg
-
-# define uaccess_kernel() (get_fs().seg == KERNEL_DS.seg)
-
-static inline int access_ok(const void __user *addr, unsigned long size)
-{
- if (!size)
- goto ok;
-
- if ((get_fs().seg < ((unsigned long)addr)) ||
- (get_fs().seg < ((unsigned long)addr + size - 1))) {
- pr_devel("ACCESS fail at 0x%08x (size 0x%x), seg 0x%08x\n",
- (__force u32)addr, (u32)size,
- (u32)get_fs().seg);
- return 0;
- }
-ok:
- pr_devel("ACCESS OK at 0x%08x (size 0x%x), seg 0x%08x\n",
- (__force u32)addr, (u32)size,
- (u32)get_fs().seg);
- return 1;
-}
+#include <asm-generic/access_ok.h>
# define __FIXUP_SECTION ".section .fixup,\"ax\"\n"
# define __EX_TABLE_SECTION ".section __ex_table,\"a\"\n"
@@ -141,27 +100,27 @@ extern long __user_bad(void);
#define __get_user(x, ptr) \
({ \
- unsigned long __gu_val = 0; \
long __gu_err; \
switch (sizeof(*(ptr))) { \
case 1: \
- __get_user_asm("lbu", (ptr), __gu_val, __gu_err); \
+ __get_user_asm("lbu", (ptr), x, __gu_err); \
break; \
case 2: \
- __get_user_asm("lhu", (ptr), __gu_val, __gu_err); \
+ __get_user_asm("lhu", (ptr), x, __gu_err); \
break; \
case 4: \
- __get_user_asm("lw", (ptr), __gu_val, __gu_err); \
+ __get_user_asm("lw", (ptr), x, __gu_err); \
break; \
- case 8: \
- __gu_err = __copy_from_user(&__gu_val, ptr, 8); \
- if (__gu_err) \
- __gu_err = -EFAULT; \
+ case 8: { \
+ __u64 __x = 0; \
+ __gu_err = raw_copy_from_user(&__x, ptr, 8) ? \
+ -EFAULT : 0; \
+ (x) = (typeof(x))(typeof((x) - (x)))__x; \
break; \
+ } \
default: \
/* __gu_val = 0; __gu_err = -EINVAL;*/ __gu_err = __user_bad();\
} \
- x = (__force __typeof__(*(ptr))) __gu_val; \
__gu_err; \
})
diff --git a/arch/microblaze/kernel/asm-offsets.c b/arch/microblaze/kernel/asm-offsets.c
index b77dd188dec4..47ee409508b1 100644
--- a/arch/microblaze/kernel/asm-offsets.c
+++ b/arch/microblaze/kernel/asm-offsets.c
@@ -86,7 +86,6 @@ int main(int argc, char *argv[])
/* struct thread_info */
DEFINE(TI_TASK, offsetof(struct thread_info, task));
DEFINE(TI_FLAGS, offsetof(struct thread_info, flags));
- DEFINE(TI_ADDR_LIMIT, offsetof(struct thread_info, addr_limit));
DEFINE(TI_CPU_CONTEXT, offsetof(struct thread_info, cpu_context));
DEFINE(TI_PREEMPT_COUNT, offsetof(struct thread_info, preempt_count));
BLANK();
diff --git a/arch/microblaze/kernel/irq.c b/arch/microblaze/kernel/irq.c
index 903dad822fad..1f8cb4c4f74f 100644
--- a/arch/microblaze/kernel/irq.c
+++ b/arch/microblaze/kernel/irq.c
@@ -20,27 +20,13 @@
#include <linux/irqchip.h>
#include <linux/of_irq.h>
-static u32 concurrent_irq;
-
void __irq_entry do_IRQ(struct pt_regs *regs)
{
- unsigned int irq;
struct pt_regs *old_regs = set_irq_regs(regs);
trace_hardirqs_off();
irq_enter();
- irq = xintc_get_irq();
-next_irq:
- BUG_ON(!irq);
- generic_handle_irq(irq);
-
- irq = xintc_get_irq();
- if (irq != -1U) {
- pr_debug("next irq: %d\n", irq);
- ++concurrent_irq;
- goto next_irq;
- }
-
+ handle_arch_irq(regs);
irq_exit();
set_irq_regs(old_regs);
trace_hardirqs_on();
diff --git a/arch/microblaze/kernel/process.c b/arch/microblaze/kernel/process.c
index 5e2b91c1e8ce..1b944d319d73 100644
--- a/arch/microblaze/kernel/process.c
+++ b/arch/microblaze/kernel/process.c
@@ -18,7 +18,6 @@
#include <linux/tick.h>
#include <linux/bitops.h>
#include <linux/ptrace.h>
-#include <linux/uaccess.h> /* for USER_DS macros */
#include <asm/cacheflush.h>
void show_regs(struct pt_regs *regs)
diff --git a/arch/mips/boot/dts/ingenic/ci20.dts b/arch/mips/boot/dts/ingenic/ci20.dts
index 3e336b3dbb10..ab6e3dc0bc1d 100644
--- a/arch/mips/boot/dts/ingenic/ci20.dts
+++ b/arch/mips/boot/dts/ingenic/ci20.dts
@@ -83,6 +83,8 @@
label = "HDMI OUT";
type = "a";
+ ddc-en-gpios = <&gpa 25 GPIO_ACTIVE_HIGH>;
+
port {
hdmi_con: endpoint {
remote-endpoint = <&dw_hdmi_out>;
@@ -114,17 +116,6 @@
gpio = <&gpf 14 GPIO_ACTIVE_LOW>;
enable-active-high;
};
-
- hdmi_power: fixedregulator@3 {
- compatible = "regulator-fixed";
-
- regulator-name = "hdmi_power";
- regulator-min-microvolt = <5000000>;
- regulator-max-microvolt = <5000000>;
-
- gpio = <&gpa 25 0>;
- enable-active-high;
- };
};
&ext {
@@ -576,8 +567,6 @@
pinctrl-names = "default";
pinctrl-0 = <&pins_hdmi_ddc>;
- hdmi-5v-supply = <&hdmi_power>;
-
ports {
#address-cells = <1>;
#size-cells = <0>;
diff --git a/arch/mips/cavium-octeon/octeon-memcpy.S b/arch/mips/cavium-octeon/octeon-memcpy.S
index 0a515cde1c18..25860fba6218 100644
--- a/arch/mips/cavium-octeon/octeon-memcpy.S
+++ b/arch/mips/cavium-octeon/octeon-memcpy.S
@@ -74,7 +74,7 @@
#define EXC(inst_reg,addr,handler) \
9: inst_reg, addr; \
.section __ex_table,"a"; \
- PTR 9b, handler; \
+ PTR_WD 9b, handler; \
.previous
/*
diff --git a/arch/mips/configs/cobalt_defconfig b/arch/mips/configs/cobalt_defconfig
index c6a652ad34f7..e835730ea7fa 100644
--- a/arch/mips/configs/cobalt_defconfig
+++ b/arch/mips/configs/cobalt_defconfig
@@ -69,6 +69,5 @@ CONFIG_CONFIGFS_FS=y
CONFIG_NFS_FS=y
CONFIG_NFS_V3_ACL=y
CONFIG_NFSD=y
-CONFIG_NFSD_V3=y
CONFIG_NFSD_V3_ACL=y
CONFIG_LIBCRC32C=y
diff --git a/arch/mips/configs/decstation_64_defconfig b/arch/mips/configs/decstation_64_defconfig
index e2ed105f8c97..0021427a1bbe 100644
--- a/arch/mips/configs/decstation_64_defconfig
+++ b/arch/mips/configs/decstation_64_defconfig
@@ -159,7 +159,6 @@ CONFIG_NFS_V3_ACL=y
CONFIG_NFS_SWAP=y
CONFIG_ROOT_NFS=y
CONFIG_NFSD=m
-CONFIG_NFSD_V3=y
CONFIG_NFSD_V3_ACL=y
# CONFIG_RPCSEC_GSS_KRB5 is not set
CONFIG_NLS_ISO8859_8=m
diff --git a/arch/mips/configs/decstation_defconfig b/arch/mips/configs/decstation_defconfig
index 7e987d6f5e34..7a97a0818ce4 100644
--- a/arch/mips/configs/decstation_defconfig
+++ b/arch/mips/configs/decstation_defconfig
@@ -154,7 +154,6 @@ CONFIG_NFS_V3_ACL=y
CONFIG_NFS_SWAP=y
CONFIG_ROOT_NFS=y
CONFIG_NFSD=m
-CONFIG_NFSD_V3=y
CONFIG_NFSD_V3_ACL=y
# CONFIG_RPCSEC_GSS_KRB5 is not set
CONFIG_NLS_ISO8859_8=m
diff --git a/arch/mips/configs/decstation_r4k_defconfig b/arch/mips/configs/decstation_r4k_defconfig
index 6df5f6f2ac8e..a0643363526d 100644
--- a/arch/mips/configs/decstation_r4k_defconfig
+++ b/arch/mips/configs/decstation_r4k_defconfig
@@ -154,7 +154,6 @@ CONFIG_NFS_V3_ACL=y
CONFIG_NFS_SWAP=y
CONFIG_ROOT_NFS=y
CONFIG_NFSD=m
-CONFIG_NFSD_V3=y
CONFIG_NFSD_V3_ACL=y
# CONFIG_RPCSEC_GSS_KRB5 is not set
CONFIG_NLS_ISO8859_8=m
diff --git a/arch/mips/configs/ip22_defconfig b/arch/mips/configs/ip22_defconfig
index 21a1168ae301..70a4ba90f491 100644
--- a/arch/mips/configs/ip22_defconfig
+++ b/arch/mips/configs/ip22_defconfig
@@ -269,7 +269,6 @@ CONFIG_UFS_FS=m
CONFIG_NFS_FS=m
CONFIG_NFS_V3_ACL=y
CONFIG_NFSD=m
-CONFIG_NFSD_V3=y
CONFIG_NFSD_V3_ACL=y
CONFIG_CIFS=m
CONFIG_CIFS_UPCALL=y
diff --git a/arch/mips/configs/ip32_defconfig b/arch/mips/configs/ip32_defconfig
index 1ae48f7d9ddd..74020aa3440b 100644
--- a/arch/mips/configs/ip32_defconfig
+++ b/arch/mips/configs/ip32_defconfig
@@ -112,7 +112,6 @@ CONFIG_CONFIGFS_FS=y
CONFIG_NFS_FS=y
CONFIG_ROOT_NFS=y
CONFIG_NFSD=m
-CONFIG_NFSD_V3=y
CONFIG_CIFS=m
CONFIG_NLS=y
CONFIG_NLS_CODEPAGE_437=m
diff --git a/arch/mips/configs/jazz_defconfig b/arch/mips/configs/jazz_defconfig
index 8c223035921f..843f360da5f2 100644
--- a/arch/mips/configs/jazz_defconfig
+++ b/arch/mips/configs/jazz_defconfig
@@ -92,5 +92,4 @@ CONFIG_TMPFS=y
CONFIG_UFS_FS=m
CONFIG_NFS_FS=m
CONFIG_NFSD=m
-CONFIG_NFSD_V3=y
CONFIG_CIFS=m
diff --git a/arch/mips/configs/malta_defconfig b/arch/mips/configs/malta_defconfig
index 3321bb576944..1c220d152a50 100644
--- a/arch/mips/configs/malta_defconfig
+++ b/arch/mips/configs/malta_defconfig
@@ -363,7 +363,6 @@ CONFIG_UFS_FS=m
CONFIG_NFS_FS=y
CONFIG_ROOT_NFS=y
CONFIG_NFSD=y
-CONFIG_NFSD_V3=y
CONFIG_NLS_CODEPAGE_437=m
CONFIG_NLS_CODEPAGE_737=m
CONFIG_NLS_CODEPAGE_775=m
diff --git a/arch/mips/configs/malta_kvm_defconfig b/arch/mips/configs/malta_kvm_defconfig
index 009b30372226..b5ba08d7ab57 100644
--- a/arch/mips/configs/malta_kvm_defconfig
+++ b/arch/mips/configs/malta_kvm_defconfig
@@ -371,7 +371,6 @@ CONFIG_UFS_FS=m
CONFIG_NFS_FS=y
CONFIG_ROOT_NFS=y
CONFIG_NFSD=y
-CONFIG_NFSD_V3=y
CONFIG_NLS_CODEPAGE_437=m
CONFIG_NLS_CODEPAGE_737=m
CONFIG_NLS_CODEPAGE_775=m
diff --git a/arch/mips/configs/maltaup_xpa_defconfig b/arch/mips/configs/maltaup_xpa_defconfig
index e214e136101c..8d58653f1b4e 100644
--- a/arch/mips/configs/maltaup_xpa_defconfig
+++ b/arch/mips/configs/maltaup_xpa_defconfig
@@ -370,7 +370,6 @@ CONFIG_UFS_FS=m
CONFIG_NFS_FS=y
CONFIG_ROOT_NFS=y
CONFIG_NFSD=y
-CONFIG_NFSD_V3=y
CONFIG_NLS_CODEPAGE_437=m
CONFIG_NLS_CODEPAGE_737=m
CONFIG_NLS_CODEPAGE_775=m
diff --git a/arch/mips/configs/rm200_defconfig b/arch/mips/configs/rm200_defconfig
index 3dc2da2bee0d..7d6f235e8ccb 100644
--- a/arch/mips/configs/rm200_defconfig
+++ b/arch/mips/configs/rm200_defconfig
@@ -354,7 +354,6 @@ CONFIG_SYSV_FS=m
CONFIG_UFS_FS=m
CONFIG_NFS_FS=m
CONFIG_NFSD=m
-CONFIG_NFSD_V3=y
CONFIG_CIFS=m
CONFIG_CODA_FS=m
CONFIG_AFS_FS=m
diff --git a/arch/mips/configs/tb0219_defconfig b/arch/mips/configs/tb0219_defconfig
index 6547f84750b5..c56d8ab14ba6 100644
--- a/arch/mips/configs/tb0219_defconfig
+++ b/arch/mips/configs/tb0219_defconfig
@@ -72,6 +72,5 @@ CONFIG_ROMFS_FS=m
CONFIG_NFS_FS=y
CONFIG_ROOT_NFS=y
CONFIG_NFSD=y
-CONFIG_NFSD_V3=y
CONFIG_CMDLINE_BOOL=y
CONFIG_CMDLINE="cca=3 mem=64M console=ttyVR0,115200 ip=any root=/dev/nfs"
diff --git a/arch/mips/configs/tb0226_defconfig b/arch/mips/configs/tb0226_defconfig
index 7e099f7c2286..6e1423428f02 100644
--- a/arch/mips/configs/tb0226_defconfig
+++ b/arch/mips/configs/tb0226_defconfig
@@ -67,6 +67,5 @@ CONFIG_ROMFS_FS=m
CONFIG_NFS_FS=y
CONFIG_ROOT_NFS=y
CONFIG_NFSD=m
-CONFIG_NFSD_V3=y
CONFIG_CMDLINE_BOOL=y
CONFIG_CMDLINE="cca=3 mem=32M console=ttyVR0,115200"
diff --git a/arch/mips/configs/tb0287_defconfig b/arch/mips/configs/tb0287_defconfig
index 0d881dd862c0..cf65a0879ece 100644
--- a/arch/mips/configs/tb0287_defconfig
+++ b/arch/mips/configs/tb0287_defconfig
@@ -77,7 +77,6 @@ CONFIG_ROMFS_FS=m
CONFIG_NFS_FS=y
CONFIG_ROOT_NFS=y
CONFIG_NFSD=m
-CONFIG_NFSD_V3=y
CONFIG_FONTS=y
CONFIG_FONT_8x8=y
CONFIG_FONT_8x16=y
diff --git a/arch/mips/configs/workpad_defconfig b/arch/mips/configs/workpad_defconfig
index 4798dc86c9ce..7e16da0bde8c 100644
--- a/arch/mips/configs/workpad_defconfig
+++ b/arch/mips/configs/workpad_defconfig
@@ -63,6 +63,5 @@ CONFIG_TMPFS=y
CONFIG_TMPFS_POSIX_ACL=y
CONFIG_NFS_FS=m
CONFIG_NFSD=m
-CONFIG_NFSD_V3=y
CONFIG_CMDLINE_BOOL=y
CONFIG_CMDLINE="console=ttyVR0,19200 ide0=0x170,0x376,49 mem=16M"
diff --git a/arch/mips/include/asm/asm.h b/arch/mips/include/asm/asm.h
index 6ffdd4b5e1d0..336ac9b65235 100644
--- a/arch/mips/include/asm/asm.h
+++ b/arch/mips/include/asm/asm.h
@@ -285,7 +285,7 @@ symbol = value
#define PTR_SCALESHIFT 2
-#define PTR .word
+#define PTR_WD .word
#define PTRSIZE 4
#define PTRLOG 2
#endif
@@ -310,7 +310,7 @@ symbol = value
#define PTR_SCALESHIFT 3
-#define PTR .dword
+#define PTR_WD .dword
#define PTRSIZE 8
#define PTRLOG 3
#endif
diff --git a/arch/mips/include/asm/ftrace.h b/arch/mips/include/asm/ftrace.h
index b463f2aa5a61..db497a8167da 100644
--- a/arch/mips/include/asm/ftrace.h
+++ b/arch/mips/include/asm/ftrace.h
@@ -32,7 +32,7 @@ do { \
".previous\n" \
\
".section\t__ex_table,\"a\"\n\t" \
- STR(PTR) "\t1b, 3b\n\t" \
+ STR(PTR_WD) "\t1b, 3b\n\t" \
".previous\n" \
\
: [tmp_dst] "=&r" (dst), [tmp_err] "=r" (error)\
@@ -54,7 +54,7 @@ do { \
".previous\n" \
\
".section\t__ex_table,\"a\"\n\t"\
- STR(PTR) "\t1b, 3b\n\t" \
+ STR(PTR_WD) "\t1b, 3b\n\t" \
".previous\n" \
\
: [tmp_err] "=r" (error) \
diff --git a/arch/mips/include/asm/pgtable.h b/arch/mips/include/asm/pgtable.h
index 7b8037f25d9e..374c6322775d 100644
--- a/arch/mips/include/asm/pgtable.h
+++ b/arch/mips/include/asm/pgtable.h
@@ -86,6 +86,11 @@ extern void paging_init(void);
*/
#define pmd_phys(pmd) virt_to_phys((void *)pmd_val(pmd))
+static inline unsigned long pmd_pfn(pmd_t pmd)
+{
+ return pmd_val(pmd) >> _PFN_SHIFT;
+}
+
#ifndef CONFIG_MIPS_HUGE_TLB_SUPPORT
#define pmd_page(pmd) (pfn_to_page(pmd_phys(pmd) >> PAGE_SHIFT))
#endif /* CONFIG_MIPS_HUGE_TLB_SUPPORT */
@@ -422,11 +427,6 @@ static inline int pmd_write(pmd_t pmd)
return !!(pmd_val(pmd) & _PAGE_WRITE);
}
-static inline unsigned long pmd_pfn(pmd_t pmd)
-{
- return pmd_val(pmd) >> _PFN_SHIFT;
-}
-
static inline struct page *pmd_page(pmd_t pmd)
{
if (pmd_val(pmd) & _PAGE_HUGE)
diff --git a/arch/mips/include/asm/r4kcache.h b/arch/mips/include/asm/r4kcache.h
index af3788589ee6..431a1c9d53fc 100644
--- a/arch/mips/include/asm/r4kcache.h
+++ b/arch/mips/include/asm/r4kcache.h
@@ -119,7 +119,7 @@ static inline void flush_scache_line(unsigned long addr)
" j 2b \n" \
" .previous \n" \
" .section __ex_table,\"a\" \n" \
- " "STR(PTR)" 1b, 3b \n" \
+ " "STR(PTR_WD)" 1b, 3b \n" \
" .previous" \
: "+r" (__err) \
: "i" (op), "r" (addr), "i" (-EFAULT)); \
@@ -142,7 +142,7 @@ static inline void flush_scache_line(unsigned long addr)
" j 2b \n" \
" .previous \n" \
" .section __ex_table,\"a\" \n" \
- " "STR(PTR)" 1b, 3b \n" \
+ " "STR(PTR_WD)" 1b, 3b \n" \
" .previous" \
: "+r" (__err) \
: "i" (op), "r" (addr), "i" (-EFAULT)); \
diff --git a/arch/mips/include/asm/uaccess.h b/arch/mips/include/asm/uaccess.h
index f8f74f9f5883..c0cede273c7c 100644
--- a/arch/mips/include/asm/uaccess.h
+++ b/arch/mips/include/asm/uaccess.h
@@ -19,6 +19,7 @@
#ifdef CONFIG_32BIT
#define __UA_LIMIT 0x80000000UL
+#define TASK_SIZE_MAX KSEG0
#define __UA_ADDR ".word"
#define __UA_LA "la"
@@ -33,6 +34,7 @@
extern u64 __ua_limit;
#define __UA_LIMIT __ua_limit
+#define TASK_SIZE_MAX XKSSEG
#define __UA_ADDR ".dword"
#define __UA_LA "dla"
@@ -42,50 +44,7 @@ extern u64 __ua_limit;
#endif /* CONFIG_64BIT */
-/*
- * Is a address valid? This does a straightforward calculation rather
- * than tests.
- *
- * Address valid if:
- * - "addr" doesn't have any high-bits set
- * - AND "size" doesn't have any high-bits set
- * - AND "addr+size" doesn't have any high-bits set
- * - OR we are in kernel mode.
- *
- * __ua_size() is a trick to avoid runtime checking of positive constant
- * sizes; for those we already know at compile time that the size is ok.
- */
-#define __ua_size(size) \
- ((__builtin_constant_p(size) && (signed long) (size) > 0) ? 0 : (size))
-
-/*
- * access_ok: - Checks if a user space pointer is valid
- * @addr: User space pointer to start of block to check
- * @size: Size of block to check
- *
- * Context: User context only. This function may sleep if pagefaults are
- * enabled.
- *
- * Checks if a pointer to a block of memory in user space is valid.
- *
- * Returns true (nonzero) if the memory block may be valid, false (zero)
- * if it is definitely invalid.
- *
- * Note that, depending on architecture, this function probably just
- * checks that the pointer is in the user space range - after calling
- * this function, memory access functions may still return -EFAULT.
- */
-
-static inline int __access_ok(const void __user *p, unsigned long size)
-{
- unsigned long addr = (unsigned long)p;
- unsigned long end = addr + size - !!size;
-
- return (__UA_LIMIT & (addr | end | __ua_size(size))) == 0;
-}
-
-#define access_ok(addr, size) \
- likely(__access_ok((addr), (size)))
+#include <asm-generic/access_ok.h>
/*
* put_user: - Write a simple value into user space.
@@ -296,8 +255,6 @@ struct __large_struct { unsigned long buf[100]; };
(val) = __gu_tmp.t; \
}
-#define HAVE_GET_KERNEL_NOFAULT
-
#define __get_kernel_nofault(dst, src, type, err_label) \
do { \
int __gu_err; \
diff --git a/arch/mips/include/asm/unaligned-emul.h b/arch/mips/include/asm/unaligned-emul.h
index 2022b18944b9..9af0f4d3d288 100644
--- a/arch/mips/include/asm/unaligned-emul.h
+++ b/arch/mips/include/asm/unaligned-emul.h
@@ -20,8 +20,8 @@ do { \
"j\t3b\n\t" \
".previous\n\t" \
".section\t__ex_table,\"a\"\n\t" \
- STR(PTR)"\t1b, 4b\n\t" \
- STR(PTR)"\t2b, 4b\n\t" \
+ STR(PTR_WD)"\t1b, 4b\n\t" \
+ STR(PTR_WD)"\t2b, 4b\n\t" \
".previous" \
: "=&r" (value), "=r" (res) \
: "r" (addr), "i" (-EFAULT)); \
@@ -41,8 +41,8 @@ do { \
"j\t3b\n\t" \
".previous\n\t" \
".section\t__ex_table,\"a\"\n\t" \
- STR(PTR)"\t1b, 4b\n\t" \
- STR(PTR)"\t2b, 4b\n\t" \
+ STR(PTR_WD)"\t1b, 4b\n\t" \
+ STR(PTR_WD)"\t2b, 4b\n\t" \
".previous" \
: "=&r" (value), "=r" (res) \
: "r" (addr), "i" (-EFAULT)); \
@@ -74,10 +74,10 @@ do { \
"j\t10b\n\t" \
".previous\n\t" \
".section\t__ex_table,\"a\"\n\t" \
- STR(PTR)"\t1b, 11b\n\t" \
- STR(PTR)"\t2b, 11b\n\t" \
- STR(PTR)"\t3b, 11b\n\t" \
- STR(PTR)"\t4b, 11b\n\t" \
+ STR(PTR_WD)"\t1b, 11b\n\t" \
+ STR(PTR_WD)"\t2b, 11b\n\t" \
+ STR(PTR_WD)"\t3b, 11b\n\t" \
+ STR(PTR_WD)"\t4b, 11b\n\t" \
".previous" \
: "=&r" (value), "=r" (res) \
: "r" (addr), "i" (-EFAULT)); \
@@ -102,8 +102,8 @@ do { \
"j\t3b\n\t" \
".previous\n\t" \
".section\t__ex_table,\"a\"\n\t" \
- STR(PTR)"\t1b, 4b\n\t" \
- STR(PTR)"\t2b, 4b\n\t" \
+ STR(PTR_WD)"\t1b, 4b\n\t" \
+ STR(PTR_WD)"\t2b, 4b\n\t" \
".previous" \
: "=&r" (value), "=r" (res) \
: "r" (addr), "i" (-EFAULT)); \
@@ -125,8 +125,8 @@ do { \
"j\t3b\n\t" \
".previous\n\t" \
".section\t__ex_table,\"a\"\n\t" \
- STR(PTR)"\t1b, 4b\n\t" \
- STR(PTR)"\t2b, 4b\n\t" \
+ STR(PTR_WD)"\t1b, 4b\n\t" \
+ STR(PTR_WD)"\t2b, 4b\n\t" \
".previous" \
: "=&r" (value), "=r" (res) \
: "r" (addr), "i" (-EFAULT)); \
@@ -145,8 +145,8 @@ do { \
"j\t3b\n\t" \
".previous\n\t" \
".section\t__ex_table,\"a\"\n\t" \
- STR(PTR)"\t1b, 4b\n\t" \
- STR(PTR)"\t2b, 4b\n\t" \
+ STR(PTR_WD)"\t1b, 4b\n\t" \
+ STR(PTR_WD)"\t2b, 4b\n\t" \
".previous" \
: "=&r" (value), "=r" (res) \
: "r" (addr), "i" (-EFAULT)); \
@@ -178,10 +178,10 @@ do { \
"j\t10b\n\t" \
".previous\n\t" \
".section\t__ex_table,\"a\"\n\t" \
- STR(PTR)"\t1b, 11b\n\t" \
- STR(PTR)"\t2b, 11b\n\t" \
- STR(PTR)"\t3b, 11b\n\t" \
- STR(PTR)"\t4b, 11b\n\t" \
+ STR(PTR_WD)"\t1b, 11b\n\t" \
+ STR(PTR_WD)"\t2b, 11b\n\t" \
+ STR(PTR_WD)"\t3b, 11b\n\t" \
+ STR(PTR_WD)"\t4b, 11b\n\t" \
".previous" \
: "=&r" (value), "=r" (res) \
: "r" (addr), "i" (-EFAULT)); \
@@ -223,14 +223,14 @@ do { \
"j\t10b\n\t" \
".previous\n\t" \
".section\t__ex_table,\"a\"\n\t" \
- STR(PTR)"\t1b, 11b\n\t" \
- STR(PTR)"\t2b, 11b\n\t" \
- STR(PTR)"\t3b, 11b\n\t" \
- STR(PTR)"\t4b, 11b\n\t" \
- STR(PTR)"\t5b, 11b\n\t" \
- STR(PTR)"\t6b, 11b\n\t" \
- STR(PTR)"\t7b, 11b\n\t" \
- STR(PTR)"\t8b, 11b\n\t" \
+ STR(PTR_WD)"\t1b, 11b\n\t" \
+ STR(PTR_WD)"\t2b, 11b\n\t" \
+ STR(PTR_WD)"\t3b, 11b\n\t" \
+ STR(PTR_WD)"\t4b, 11b\n\t" \
+ STR(PTR_WD)"\t5b, 11b\n\t" \
+ STR(PTR_WD)"\t6b, 11b\n\t" \
+ STR(PTR_WD)"\t7b, 11b\n\t" \
+ STR(PTR_WD)"\t8b, 11b\n\t" \
".previous" \
: "=&r" (value), "=r" (res) \
: "r" (addr), "i" (-EFAULT)); \
@@ -255,8 +255,8 @@ do { \
"j\t3b\n\t" \
".previous\n\t" \
".section\t__ex_table,\"a\"\n\t" \
- STR(PTR)"\t1b, 4b\n\t" \
- STR(PTR)"\t2b, 4b\n\t" \
+ STR(PTR_WD)"\t1b, 4b\n\t" \
+ STR(PTR_WD)"\t2b, 4b\n\t" \
".previous" \
: "=r" (res) \
: "r" (value), "r" (addr), "i" (-EFAULT));\
@@ -276,8 +276,8 @@ do { \
"j\t3b\n\t" \
".previous\n\t" \
".section\t__ex_table,\"a\"\n\t" \
- STR(PTR)"\t1b, 4b\n\t" \
- STR(PTR)"\t2b, 4b\n\t" \
+ STR(PTR_WD)"\t1b, 4b\n\t" \
+ STR(PTR_WD)"\t2b, 4b\n\t" \
".previous" \
: "=r" (res) \
: "r" (value), "r" (addr), "i" (-EFAULT)); \
@@ -296,8 +296,8 @@ do { \
"j\t3b\n\t" \
".previous\n\t" \
".section\t__ex_table,\"a\"\n\t" \
- STR(PTR)"\t1b, 4b\n\t" \
- STR(PTR)"\t2b, 4b\n\t" \
+ STR(PTR_WD)"\t1b, 4b\n\t" \
+ STR(PTR_WD)"\t2b, 4b\n\t" \
".previous" \
: "=r" (res) \
: "r" (value), "r" (addr), "i" (-EFAULT)); \
@@ -325,10 +325,10 @@ do { \
"j\t10b\n\t" \
".previous\n\t" \
".section\t__ex_table,\"a\"\n\t" \
- STR(PTR)"\t1b, 11b\n\t" \
- STR(PTR)"\t2b, 11b\n\t" \
- STR(PTR)"\t3b, 11b\n\t" \
- STR(PTR)"\t4b, 11b\n\t" \
+ STR(PTR_WD)"\t1b, 11b\n\t" \
+ STR(PTR_WD)"\t2b, 11b\n\t" \
+ STR(PTR_WD)"\t3b, 11b\n\t" \
+ STR(PTR_WD)"\t4b, 11b\n\t" \
".previous" \
: "=&r" (res) \
: "r" (value), "r" (addr), "i" (-EFAULT) \
@@ -365,14 +365,14 @@ do { \
"j\t10b\n\t" \
".previous\n\t" \
".section\t__ex_table,\"a\"\n\t" \
- STR(PTR)"\t1b, 11b\n\t" \
- STR(PTR)"\t2b, 11b\n\t" \
- STR(PTR)"\t3b, 11b\n\t" \
- STR(PTR)"\t4b, 11b\n\t" \
- STR(PTR)"\t5b, 11b\n\t" \
- STR(PTR)"\t6b, 11b\n\t" \
- STR(PTR)"\t7b, 11b\n\t" \
- STR(PTR)"\t8b, 11b\n\t" \
+ STR(PTR_WD)"\t1b, 11b\n\t" \
+ STR(PTR_WD)"\t2b, 11b\n\t" \
+ STR(PTR_WD)"\t3b, 11b\n\t" \
+ STR(PTR_WD)"\t4b, 11b\n\t" \
+ STR(PTR_WD)"\t5b, 11b\n\t" \
+ STR(PTR_WD)"\t6b, 11b\n\t" \
+ STR(PTR_WD)"\t7b, 11b\n\t" \
+ STR(PTR_WD)"\t8b, 11b\n\t" \
".previous" \
: "=&r" (res) \
: "r" (value), "r" (addr), "i" (-EFAULT) \
@@ -398,8 +398,8 @@ do { \
"j\t3b\n\t" \
".previous\n\t" \
".section\t__ex_table,\"a\"\n\t" \
- STR(PTR)"\t1b, 4b\n\t" \
- STR(PTR)"\t2b, 4b\n\t" \
+ STR(PTR_WD)"\t1b, 4b\n\t" \
+ STR(PTR_WD)"\t2b, 4b\n\t" \
".previous" \
: "=&r" (value), "=r" (res) \
: "r" (addr), "i" (-EFAULT)); \
@@ -419,8 +419,8 @@ do { \
"j\t3b\n\t" \
".previous\n\t" \
".section\t__ex_table,\"a\"\n\t" \
- STR(PTR)"\t1b, 4b\n\t" \
- STR(PTR)"\t2b, 4b\n\t" \
+ STR(PTR_WD)"\t1b, 4b\n\t" \
+ STR(PTR_WD)"\t2b, 4b\n\t" \
".previous" \
: "=&r" (value), "=r" (res) \
: "r" (addr), "i" (-EFAULT)); \
@@ -452,10 +452,10 @@ do { \
"j\t10b\n\t" \
".previous\n\t" \
".section\t__ex_table,\"a\"\n\t" \
- STR(PTR)"\t1b, 11b\n\t" \
- STR(PTR)"\t2b, 11b\n\t" \
- STR(PTR)"\t3b, 11b\n\t" \
- STR(PTR)"\t4b, 11b\n\t" \
+ STR(PTR_WD)"\t1b, 11b\n\t" \
+ STR(PTR_WD)"\t2b, 11b\n\t" \
+ STR(PTR_WD)"\t3b, 11b\n\t" \
+ STR(PTR_WD)"\t4b, 11b\n\t" \
".previous" \
: "=&r" (value), "=r" (res) \
: "r" (addr), "i" (-EFAULT)); \
@@ -481,8 +481,8 @@ do { \
"j\t3b\n\t" \
".previous\n\t" \
".section\t__ex_table,\"a\"\n\t" \
- STR(PTR)"\t1b, 4b\n\t" \
- STR(PTR)"\t2b, 4b\n\t" \
+ STR(PTR_WD)"\t1b, 4b\n\t" \
+ STR(PTR_WD)"\t2b, 4b\n\t" \
".previous" \
: "=&r" (value), "=r" (res) \
: "r" (addr), "i" (-EFAULT)); \
@@ -504,8 +504,8 @@ do { \
"j\t3b\n\t" \
".previous\n\t" \
".section\t__ex_table,\"a\"\n\t" \
- STR(PTR)"\t1b, 4b\n\t" \
- STR(PTR)"\t2b, 4b\n\t" \
+ STR(PTR_WD)"\t1b, 4b\n\t" \
+ STR(PTR_WD)"\t2b, 4b\n\t" \
".previous" \
: "=&r" (value), "=r" (res) \
: "r" (addr), "i" (-EFAULT)); \
@@ -524,8 +524,8 @@ do { \
"j\t3b\n\t" \
".previous\n\t" \
".section\t__ex_table,\"a\"\n\t" \
- STR(PTR)"\t1b, 4b\n\t" \
- STR(PTR)"\t2b, 4b\n\t" \
+ STR(PTR_WD)"\t1b, 4b\n\t" \
+ STR(PTR_WD)"\t2b, 4b\n\t" \
".previous" \
: "=&r" (value), "=r" (res) \
: "r" (addr), "i" (-EFAULT)); \
@@ -557,10 +557,10 @@ do { \
"j\t10b\n\t" \
".previous\n\t" \
".section\t__ex_table,\"a\"\n\t" \
- STR(PTR)"\t1b, 11b\n\t" \
- STR(PTR)"\t2b, 11b\n\t" \
- STR(PTR)"\t3b, 11b\n\t" \
- STR(PTR)"\t4b, 11b\n\t" \
+ STR(PTR_WD)"\t1b, 11b\n\t" \
+ STR(PTR_WD)"\t2b, 11b\n\t" \
+ STR(PTR_WD)"\t3b, 11b\n\t" \
+ STR(PTR_WD)"\t4b, 11b\n\t" \
".previous" \
: "=&r" (value), "=r" (res) \
: "r" (addr), "i" (-EFAULT)); \
@@ -602,14 +602,14 @@ do { \
"j\t10b\n\t" \
".previous\n\t" \
".section\t__ex_table,\"a\"\n\t" \
- STR(PTR)"\t1b, 11b\n\t" \
- STR(PTR)"\t2b, 11b\n\t" \
- STR(PTR)"\t3b, 11b\n\t" \
- STR(PTR)"\t4b, 11b\n\t" \
- STR(PTR)"\t5b, 11b\n\t" \
- STR(PTR)"\t6b, 11b\n\t" \
- STR(PTR)"\t7b, 11b\n\t" \
- STR(PTR)"\t8b, 11b\n\t" \
+ STR(PTR_WD)"\t1b, 11b\n\t" \
+ STR(PTR_WD)"\t2b, 11b\n\t" \
+ STR(PTR_WD)"\t3b, 11b\n\t" \
+ STR(PTR_WD)"\t4b, 11b\n\t" \
+ STR(PTR_WD)"\t5b, 11b\n\t" \
+ STR(PTR_WD)"\t6b, 11b\n\t" \
+ STR(PTR_WD)"\t7b, 11b\n\t" \
+ STR(PTR_WD)"\t8b, 11b\n\t" \
".previous" \
: "=&r" (value), "=r" (res) \
: "r" (addr), "i" (-EFAULT)); \
@@ -632,8 +632,8 @@ do { \
"j\t3b\n\t" \
".previous\n\t" \
".section\t__ex_table,\"a\"\n\t" \
- STR(PTR)"\t1b, 4b\n\t" \
- STR(PTR)"\t2b, 4b\n\t" \
+ STR(PTR_WD)"\t1b, 4b\n\t" \
+ STR(PTR_WD)"\t2b, 4b\n\t" \
".previous" \
: "=r" (res) \
: "r" (value), "r" (addr), "i" (-EFAULT));\
@@ -653,8 +653,8 @@ do { \
"j\t3b\n\t" \
".previous\n\t" \
".section\t__ex_table,\"a\"\n\t" \
- STR(PTR)"\t1b, 4b\n\t" \
- STR(PTR)"\t2b, 4b\n\t" \
+ STR(PTR_WD)"\t1b, 4b\n\t" \
+ STR(PTR_WD)"\t2b, 4b\n\t" \
".previous" \
: "=r" (res) \
: "r" (value), "r" (addr), "i" (-EFAULT)); \
@@ -673,8 +673,8 @@ do { \
"j\t3b\n\t" \
".previous\n\t" \
".section\t__ex_table,\"a\"\n\t" \
- STR(PTR)"\t1b, 4b\n\t" \
- STR(PTR)"\t2b, 4b\n\t" \
+ STR(PTR_WD)"\t1b, 4b\n\t" \
+ STR(PTR_WD)"\t2b, 4b\n\t" \
".previous" \
: "=r" (res) \
: "r" (value), "r" (addr), "i" (-EFAULT)); \
@@ -703,10 +703,10 @@ do { \
"j\t10b\n\t" \
".previous\n\t" \
".section\t__ex_table,\"a\"\n\t" \
- STR(PTR)"\t1b, 11b\n\t" \
- STR(PTR)"\t2b, 11b\n\t" \
- STR(PTR)"\t3b, 11b\n\t" \
- STR(PTR)"\t4b, 11b\n\t" \
+ STR(PTR_WD)"\t1b, 11b\n\t" \
+ STR(PTR_WD)"\t2b, 11b\n\t" \
+ STR(PTR_WD)"\t3b, 11b\n\t" \
+ STR(PTR_WD)"\t4b, 11b\n\t" \
".previous" \
: "=&r" (res) \
: "r" (value), "r" (addr), "i" (-EFAULT) \
@@ -743,14 +743,14 @@ do { \
"j\t10b\n\t" \
".previous\n\t" \
".section\t__ex_table,\"a\"\n\t" \
- STR(PTR)"\t1b, 11b\n\t" \
- STR(PTR)"\t2b, 11b\n\t" \
- STR(PTR)"\t3b, 11b\n\t" \
- STR(PTR)"\t4b, 11b\n\t" \
- STR(PTR)"\t5b, 11b\n\t" \
- STR(PTR)"\t6b, 11b\n\t" \
- STR(PTR)"\t7b, 11b\n\t" \
- STR(PTR)"\t8b, 11b\n\t" \
+ STR(PTR_WD)"\t1b, 11b\n\t" \
+ STR(PTR_WD)"\t2b, 11b\n\t" \
+ STR(PTR_WD)"\t3b, 11b\n\t" \
+ STR(PTR_WD)"\t4b, 11b\n\t" \
+ STR(PTR_WD)"\t5b, 11b\n\t" \
+ STR(PTR_WD)"\t6b, 11b\n\t" \
+ STR(PTR_WD)"\t7b, 11b\n\t" \
+ STR(PTR_WD)"\t8b, 11b\n\t" \
".previous" \
: "=&r" (res) \
: "r" (value), "r" (addr), "i" (-EFAULT) \
diff --git a/arch/mips/include/uapi/asm/shmbuf.h b/arch/mips/include/uapi/asm/shmbuf.h
index 680bb95b2240..eb74d304b779 100644
--- a/arch/mips/include/uapi/asm/shmbuf.h
+++ b/arch/mips/include/uapi/asm/shmbuf.h
@@ -2,6 +2,9 @@
#ifndef _ASM_SHMBUF_H
#define _ASM_SHMBUF_H
+#include <asm/ipcbuf.h>
+#include <asm/posix_types.h>
+
/*
* The shmid64_ds structure for the MIPS architecture.
* Note extra padding because this structure is passed back and forth
@@ -16,7 +19,7 @@
#ifdef __mips64
struct shmid64_ds {
struct ipc64_perm shm_perm; /* operation perms */
- size_t shm_segsz; /* size of segment (bytes) */
+ __kernel_size_t shm_segsz; /* size of segment (bytes) */
long shm_atime; /* last attach time */
long shm_dtime; /* last detach time */
long shm_ctime; /* last change time */
@@ -29,7 +32,7 @@ struct shmid64_ds {
#else
struct shmid64_ds {
struct ipc64_perm shm_perm; /* operation perms */
- size_t shm_segsz; /* size of segment (bytes) */
+ __kernel_size_t shm_segsz; /* size of segment (bytes) */
unsigned long shm_atime; /* last attach time */
unsigned long shm_dtime; /* last detach time */
unsigned long shm_ctime; /* last change time */
diff --git a/arch/mips/include/uapi/asm/signal.h b/arch/mips/include/uapi/asm/signal.h
index e6c78a15cb2f..94a00f82e373 100644
--- a/arch/mips/include/uapi/asm/signal.h
+++ b/arch/mips/include/uapi/asm/signal.h
@@ -100,7 +100,7 @@ struct sigaction {
/* IRIX compatible stack_t */
typedef struct sigaltstack {
void __user *ss_sp;
- size_t ss_size;
+ __kernel_size_t ss_size;
int ss_flags;
} stack_t;
diff --git a/arch/mips/include/uapi/asm/socket.h b/arch/mips/include/uapi/asm/socket.h
index 24e0efb360f6..1d55e57b8466 100644
--- a/arch/mips/include/uapi/asm/socket.h
+++ b/arch/mips/include/uapi/asm/socket.h
@@ -144,6 +144,8 @@
#define SO_RESERVE_MEM 73
+#define SO_TXREHASH 74
+
#if !defined(__KERNEL__)
#if __BITS_PER_LONG == 64
diff --git a/arch/mips/kernel/mips-r2-to-r6-emul.c b/arch/mips/kernel/mips-r2-to-r6-emul.c
index a39ec755e4c2..750fe569862b 100644
--- a/arch/mips/kernel/mips-r2-to-r6-emul.c
+++ b/arch/mips/kernel/mips-r2-to-r6-emul.c
@@ -1258,10 +1258,10 @@ fpu_emul:
" j 10b\n"
" .previous\n"
" .section __ex_table,\"a\"\n"
- STR(PTR) " 1b,8b\n"
- STR(PTR) " 2b,8b\n"
- STR(PTR) " 3b,8b\n"
- STR(PTR) " 4b,8b\n"
+ STR(PTR_WD) " 1b,8b\n"
+ STR(PTR_WD) " 2b,8b\n"
+ STR(PTR_WD) " 3b,8b\n"
+ STR(PTR_WD) " 4b,8b\n"
" .previous\n"
" .set pop\n"
: "+&r"(rt), "=&r"(rs),
@@ -1333,10 +1333,10 @@ fpu_emul:
" j 10b\n"
" .previous\n"
" .section __ex_table,\"a\"\n"
- STR(PTR) " 1b,8b\n"
- STR(PTR) " 2b,8b\n"
- STR(PTR) " 3b,8b\n"
- STR(PTR) " 4b,8b\n"
+ STR(PTR_WD) " 1b,8b\n"
+ STR(PTR_WD) " 2b,8b\n"
+ STR(PTR_WD) " 3b,8b\n"
+ STR(PTR_WD) " 4b,8b\n"
" .previous\n"
" .set pop\n"
: "+&r"(rt), "=&r"(rs),
@@ -1404,10 +1404,10 @@ fpu_emul:
" j 9b\n"
" .previous\n"
" .section __ex_table,\"a\"\n"
- STR(PTR) " 1b,8b\n"
- STR(PTR) " 2b,8b\n"
- STR(PTR) " 3b,8b\n"
- STR(PTR) " 4b,8b\n"
+ STR(PTR_WD) " 1b,8b\n"
+ STR(PTR_WD) " 2b,8b\n"
+ STR(PTR_WD) " 3b,8b\n"
+ STR(PTR_WD) " 4b,8b\n"
" .previous\n"
" .set pop\n"
: "+&r"(rt), "=&r"(rs),
@@ -1474,10 +1474,10 @@ fpu_emul:
" j 9b\n"
" .previous\n"
" .section __ex_table,\"a\"\n"
- STR(PTR) " 1b,8b\n"
- STR(PTR) " 2b,8b\n"
- STR(PTR) " 3b,8b\n"
- STR(PTR) " 4b,8b\n"
+ STR(PTR_WD) " 1b,8b\n"
+ STR(PTR_WD) " 2b,8b\n"
+ STR(PTR_WD) " 3b,8b\n"
+ STR(PTR_WD) " 4b,8b\n"
" .previous\n"
" .set pop\n"
: "+&r"(rt), "=&r"(rs),
@@ -1589,14 +1589,14 @@ fpu_emul:
" j 9b\n"
" .previous\n"
" .section __ex_table,\"a\"\n"
- STR(PTR) " 1b,8b\n"
- STR(PTR) " 2b,8b\n"
- STR(PTR) " 3b,8b\n"
- STR(PTR) " 4b,8b\n"
- STR(PTR) " 5b,8b\n"
- STR(PTR) " 6b,8b\n"
- STR(PTR) " 7b,8b\n"
- STR(PTR) " 0b,8b\n"
+ STR(PTR_WD) " 1b,8b\n"
+ STR(PTR_WD) " 2b,8b\n"
+ STR(PTR_WD) " 3b,8b\n"
+ STR(PTR_WD) " 4b,8b\n"
+ STR(PTR_WD) " 5b,8b\n"
+ STR(PTR_WD) " 6b,8b\n"
+ STR(PTR_WD) " 7b,8b\n"
+ STR(PTR_WD) " 0b,8b\n"
" .previous\n"
" .set pop\n"
: "+&r"(rt), "=&r"(rs),
@@ -1708,14 +1708,14 @@ fpu_emul:
" j 9b\n"
" .previous\n"
" .section __ex_table,\"a\"\n"
- STR(PTR) " 1b,8b\n"
- STR(PTR) " 2b,8b\n"
- STR(PTR) " 3b,8b\n"
- STR(PTR) " 4b,8b\n"
- STR(PTR) " 5b,8b\n"
- STR(PTR) " 6b,8b\n"
- STR(PTR) " 7b,8b\n"
- STR(PTR) " 0b,8b\n"
+ STR(PTR_WD) " 1b,8b\n"
+ STR(PTR_WD) " 2b,8b\n"
+ STR(PTR_WD) " 3b,8b\n"
+ STR(PTR_WD) " 4b,8b\n"
+ STR(PTR_WD) " 5b,8b\n"
+ STR(PTR_WD) " 6b,8b\n"
+ STR(PTR_WD) " 7b,8b\n"
+ STR(PTR_WD) " 0b,8b\n"
" .previous\n"
" .set pop\n"
: "+&r"(rt), "=&r"(rs),
@@ -1827,14 +1827,14 @@ fpu_emul:
" j 9b\n"
" .previous\n"
" .section __ex_table,\"a\"\n"
- STR(PTR) " 1b,8b\n"
- STR(PTR) " 2b,8b\n"
- STR(PTR) " 3b,8b\n"
- STR(PTR) " 4b,8b\n"
- STR(PTR) " 5b,8b\n"
- STR(PTR) " 6b,8b\n"
- STR(PTR) " 7b,8b\n"
- STR(PTR) " 0b,8b\n"
+ STR(PTR_WD) " 1b,8b\n"
+ STR(PTR_WD) " 2b,8b\n"
+ STR(PTR_WD) " 3b,8b\n"
+ STR(PTR_WD) " 4b,8b\n"
+ STR(PTR_WD) " 5b,8b\n"
+ STR(PTR_WD) " 6b,8b\n"
+ STR(PTR_WD) " 7b,8b\n"
+ STR(PTR_WD) " 0b,8b\n"
" .previous\n"
" .set pop\n"
: "+&r"(rt), "=&r"(rs),
@@ -1945,14 +1945,14 @@ fpu_emul:
" j 9b\n"
" .previous\n"
" .section __ex_table,\"a\"\n"
- STR(PTR) " 1b,8b\n"
- STR(PTR) " 2b,8b\n"
- STR(PTR) " 3b,8b\n"
- STR(PTR) " 4b,8b\n"
- STR(PTR) " 5b,8b\n"
- STR(PTR) " 6b,8b\n"
- STR(PTR) " 7b,8b\n"
- STR(PTR) " 0b,8b\n"
+ STR(PTR_WD) " 1b,8b\n"
+ STR(PTR_WD) " 2b,8b\n"
+ STR(PTR_WD) " 3b,8b\n"
+ STR(PTR_WD) " 4b,8b\n"
+ STR(PTR_WD) " 5b,8b\n"
+ STR(PTR_WD) " 6b,8b\n"
+ STR(PTR_WD) " 7b,8b\n"
+ STR(PTR_WD) " 0b,8b\n"
" .previous\n"
" .set pop\n"
: "+&r"(rt), "=&r"(rs),
@@ -2007,7 +2007,7 @@ fpu_emul:
"j 2b\n"
".previous\n"
".section __ex_table,\"a\"\n"
- STR(PTR) " 1b,3b\n"
+ STR(PTR_WD) " 1b,3b\n"
".previous\n"
: "=&r"(res), "+&r"(err)
: "r"(vaddr), "i"(SIGSEGV)
@@ -2065,7 +2065,7 @@ fpu_emul:
"j 2b\n"
".previous\n"
".section __ex_table,\"a\"\n"
- STR(PTR) " 1b,3b\n"
+ STR(PTR_WD) " 1b,3b\n"
".previous\n"
: "+&r"(res), "+&r"(err)
: "r"(vaddr), "i"(SIGSEGV));
@@ -2126,7 +2126,7 @@ fpu_emul:
"j 2b\n"
".previous\n"
".section __ex_table,\"a\"\n"
- STR(PTR) " 1b,3b\n"
+ STR(PTR_WD) " 1b,3b\n"
".previous\n"
: "=&r"(res), "+&r"(err)
: "r"(vaddr), "i"(SIGSEGV)
@@ -2189,7 +2189,7 @@ fpu_emul:
"j 2b\n"
".previous\n"
".section __ex_table,\"a\"\n"
- STR(PTR) " 1b,3b\n"
+ STR(PTR_WD) " 1b,3b\n"
".previous\n"
: "+&r"(res), "+&r"(err)
: "r"(vaddr), "i"(SIGSEGV));
diff --git a/arch/mips/kernel/r2300_fpu.S b/arch/mips/kernel/r2300_fpu.S
index cbf6db98cfb3..2748c55820c2 100644
--- a/arch/mips/kernel/r2300_fpu.S
+++ b/arch/mips/kernel/r2300_fpu.S
@@ -23,14 +23,14 @@
#define EX(a,b) \
9: a,##b; \
.section __ex_table,"a"; \
- PTR 9b,fault; \
+ PTR_WD 9b,fault; \
.previous
#define EX2(a,b) \
9: a,##b; \
.section __ex_table,"a"; \
- PTR 9b,fault; \
- PTR 9b+4,fault; \
+ PTR_WD 9b,fault; \
+ PTR_WD 9b+4,fault; \
.previous
.set mips1
diff --git a/arch/mips/kernel/r4k_fpu.S b/arch/mips/kernel/r4k_fpu.S
index b91e91106475..2e687c60bc4f 100644
--- a/arch/mips/kernel/r4k_fpu.S
+++ b/arch/mips/kernel/r4k_fpu.S
@@ -31,7 +31,7 @@
.ex\@: \insn \reg, \src
.set pop
.section __ex_table,"a"
- PTR .ex\@, fault
+ PTR_WD .ex\@, fault
.previous
.endm
diff --git a/arch/mips/kernel/relocate_kernel.S b/arch/mips/kernel/relocate_kernel.S
index f3c908abdbb8..cfde14b48fd8 100644
--- a/arch/mips/kernel/relocate_kernel.S
+++ b/arch/mips/kernel/relocate_kernel.S
@@ -147,10 +147,10 @@ LEAF(kexec_smp_wait)
kexec_args:
EXPORT(kexec_args)
-arg0: PTR 0x0
-arg1: PTR 0x0
-arg2: PTR 0x0
-arg3: PTR 0x0
+arg0: PTR_WD 0x0
+arg1: PTR_WD 0x0
+arg2: PTR_WD 0x0
+arg3: PTR_WD 0x0
.size kexec_args,PTRSIZE*4
#ifdef CONFIG_SMP
@@ -161,10 +161,10 @@ arg3: PTR 0x0
*/
secondary_kexec_args:
EXPORT(secondary_kexec_args)
-s_arg0: PTR 0x0
-s_arg1: PTR 0x0
-s_arg2: PTR 0x0
-s_arg3: PTR 0x0
+s_arg0: PTR_WD 0x0
+s_arg1: PTR_WD 0x0
+s_arg2: PTR_WD 0x0
+s_arg3: PTR_WD 0x0
.size secondary_kexec_args,PTRSIZE*4
kexec_flag:
LONG 0x1
@@ -173,17 +173,17 @@ kexec_flag:
kexec_start_address:
EXPORT(kexec_start_address)
- PTR 0x0
+ PTR_WD 0x0
.size kexec_start_address, PTRSIZE
kexec_indirection_page:
EXPORT(kexec_indirection_page)
- PTR 0
+ PTR_WD 0
.size kexec_indirection_page, PTRSIZE
relocate_new_kernel_end:
relocate_new_kernel_size:
EXPORT(relocate_new_kernel_size)
- PTR relocate_new_kernel_end - relocate_new_kernel
+ PTR_WD relocate_new_kernel_end - relocate_new_kernel
.size relocate_new_kernel_size, PTRSIZE
diff --git a/arch/mips/kernel/scall32-o32.S b/arch/mips/kernel/scall32-o32.S
index b1b2e106f711..9bfce5f75f60 100644
--- a/arch/mips/kernel/scall32-o32.S
+++ b/arch/mips/kernel/scall32-o32.S
@@ -72,10 +72,10 @@ loads_done:
.set pop
.section __ex_table,"a"
- PTR load_a4, bad_stack_a4
- PTR load_a5, bad_stack_a5
- PTR load_a6, bad_stack_a6
- PTR load_a7, bad_stack_a7
+ PTR_WD load_a4, bad_stack_a4
+ PTR_WD load_a5, bad_stack_a5
+ PTR_WD load_a6, bad_stack_a6
+ PTR_WD load_a7, bad_stack_a7
.previous
lw t0, TI_FLAGS($28) # syscall tracing enabled?
@@ -216,7 +216,7 @@ einval: li v0, -ENOSYS
#endif /* CONFIG_MIPS_MT_FPAFF */
#define __SYSCALL_WITH_COMPAT(nr, native, compat) __SYSCALL(nr, native)
-#define __SYSCALL(nr, entry) PTR entry
+#define __SYSCALL(nr, entry) PTR_WD entry
.align 2
.type sys_call_table, @object
EXPORT(sys_call_table)
diff --git a/arch/mips/kernel/scall64-n32.S b/arch/mips/kernel/scall64-n32.S
index f650c55a17dc..97456b2ca7dc 100644
--- a/arch/mips/kernel/scall64-n32.S
+++ b/arch/mips/kernel/scall64-n32.S
@@ -101,7 +101,7 @@ not_n32_scall:
END(handle_sysn32)
-#define __SYSCALL(nr, entry) PTR entry
+#define __SYSCALL(nr, entry) PTR_WD entry
.type sysn32_call_table, @object
EXPORT(sysn32_call_table)
#include <asm/syscall_table_n32.h>
diff --git a/arch/mips/kernel/scall64-n64.S b/arch/mips/kernel/scall64-n64.S
index 5d7bfc65e4d0..5f6ed4b4c399 100644
--- a/arch/mips/kernel/scall64-n64.S
+++ b/arch/mips/kernel/scall64-n64.S
@@ -109,7 +109,7 @@ illegal_syscall:
j n64_syscall_exit
END(handle_sys64)
-#define __SYSCALL(nr, entry) PTR entry
+#define __SYSCALL(nr, entry) PTR_WD entry
.align 3
.type sys_call_table, @object
EXPORT(sys_call_table)
diff --git a/arch/mips/kernel/scall64-o32.S b/arch/mips/kernel/scall64-o32.S
index cedc8bd88804..d3c2616cba22 100644
--- a/arch/mips/kernel/scall64-o32.S
+++ b/arch/mips/kernel/scall64-o32.S
@@ -73,10 +73,10 @@ load_a7: lw a7, 28(t0) # argument #8 from usp
loads_done:
.section __ex_table,"a"
- PTR load_a4, bad_stack_a4
- PTR load_a5, bad_stack_a5
- PTR load_a6, bad_stack_a6
- PTR load_a7, bad_stack_a7
+ PTR_WD load_a4, bad_stack_a4
+ PTR_WD load_a5, bad_stack_a5
+ PTR_WD load_a6, bad_stack_a6
+ PTR_WD load_a7, bad_stack_a7
.previous
li t1, _TIF_WORK_SYSCALL_ENTRY
@@ -214,7 +214,7 @@ einval: li v0, -ENOSYS
END(sys32_syscall)
#define __SYSCALL_WITH_COMPAT(nr, native, compat) __SYSCALL(nr, compat)
-#define __SYSCALL(nr, entry) PTR entry
+#define __SYSCALL(nr, entry) PTR_WD entry
.align 3
.type sys32_call_table,@object
EXPORT(sys32_call_table)
diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c
index f979adfd4fc2..ef73ba1e0ec1 100644
--- a/arch/mips/kernel/setup.c
+++ b/arch/mips/kernel/setup.c
@@ -803,7 +803,7 @@ early_param("coherentio", setcoherentio);
static int __init setnocoherentio(char *str)
{
- dma_default_coherent = true;
+ dma_default_coherent = false;
pr_info("Software DMA cache coherency (command line)\n");
return 0;
}
diff --git a/arch/mips/kernel/smp.c b/arch/mips/kernel/smp.c
index d542fb7af3ba..1986d1309410 100644
--- a/arch/mips/kernel/smp.c
+++ b/arch/mips/kernel/smp.c
@@ -351,6 +351,9 @@ asmlinkage void start_secondary(void)
cpu = smp_processor_id();
cpu_data[cpu].udelay_val = loops_per_jiffy;
+ set_cpu_sibling_map(cpu);
+ set_cpu_core_map(cpu);
+
cpumask_set_cpu(cpu, &cpu_coherent_mask);
notify_cpu_starting(cpu);
@@ -362,9 +365,6 @@ asmlinkage void start_secondary(void)
/* The CPU is running and counters synchronised, now mark it online */
set_cpu_online(cpu, true);
- set_cpu_sibling_map(cpu);
- set_cpu_core_map(cpu);
-
calculate_cpu_foreign_map();
/*
diff --git a/arch/mips/kernel/syscall.c b/arch/mips/kernel/syscall.c
index 5512cd586e6e..ae93a607ddf7 100644
--- a/arch/mips/kernel/syscall.c
+++ b/arch/mips/kernel/syscall.c
@@ -122,8 +122,8 @@ static inline int mips_atomic_set(unsigned long addr, unsigned long new)
" j 3b \n"
" .previous \n"
" .section __ex_table,\"a\" \n"
- " "STR(PTR)" 1b, 4b \n"
- " "STR(PTR)" 2b, 4b \n"
+ " "STR(PTR_WD)" 1b, 4b \n"
+ " "STR(PTR_WD)" 2b, 4b \n"
" .previous \n"
" .set pop \n"
: [old] "=&r" (old),
@@ -152,8 +152,8 @@ static inline int mips_atomic_set(unsigned long addr, unsigned long new)
" j 3b \n"
" .previous \n"
" .section __ex_table,\"a\" \n"
- " "STR(PTR)" 1b, 5b \n"
- " "STR(PTR)" 2b, 5b \n"
+ " "STR(PTR_WD)" 1b, 5b \n"
+ " "STR(PTR_WD)" 2b, 5b \n"
" .previous \n"
" .set pop \n"
: [old] "=&r" (old),
diff --git a/arch/mips/kernel/topology.c b/arch/mips/kernel/topology.c
index 08ad6371fbe0..9429d85a4703 100644
--- a/arch/mips/kernel/topology.c
+++ b/arch/mips/kernel/topology.c
@@ -12,11 +12,6 @@ static int __init topology_init(void)
{
int i, ret;
-#ifdef CONFIG_NUMA
- for_each_online_node(i)
- register_one_node(i);
-#endif /* CONFIG_NUMA */
-
for_each_present_cpu(i) {
struct cpu *c = &per_cpu(cpu_devices, i);
diff --git a/arch/mips/kernel/unaligned.c b/arch/mips/kernel/unaligned.c
index df4b708c04a9..7b5aba5df02e 100644
--- a/arch/mips/kernel/unaligned.c
+++ b/arch/mips/kernel/unaligned.c
@@ -1480,6 +1480,23 @@ asmlinkage void do_ade(struct pt_regs *regs)
prev_state = exception_enter();
perf_sw_event(PERF_COUNT_SW_ALIGNMENT_FAULTS,
1, regs, regs->cp0_badvaddr);
+
+#ifdef CONFIG_64BIT
+ /*
+ * check, if we are hitting space between CPU implemented maximum
+ * virtual user address and 64bit maximum virtual user address
+ * and do exception handling to get EFAULTs for get_user/put_user
+ */
+ if ((regs->cp0_badvaddr >= (1UL << cpu_vmbits)) &&
+ (regs->cp0_badvaddr < XKSSEG)) {
+ if (fixup_exception(regs)) {
+ current->thread.cp0_baduaddr = regs->cp0_badvaddr;
+ return;
+ }
+ goto sigbus;
+ }
+#endif
+
/*
* Did we catch a fault trying to load an instruction?
*/
diff --git a/arch/mips/kvm/mips.c b/arch/mips/kvm/mips.c
index e59cb6246f76..a25e0b73ee70 100644
--- a/arch/mips/kvm/mips.c
+++ b/arch/mips/kvm/mips.c
@@ -414,6 +414,24 @@ int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu,
return -ENOIOCTLCMD;
}
+/*
+ * Actually run the vCPU, entering an RCU extended quiescent state (EQS) while
+ * the vCPU is running.
+ *
+ * This must be noinstr as instrumentation may make use of RCU, and this is not
+ * safe during the EQS.
+ */
+static int noinstr kvm_mips_vcpu_enter_exit(struct kvm_vcpu *vcpu)
+{
+ int ret;
+
+ guest_state_enter_irqoff();
+ ret = kvm_mips_callbacks->vcpu_run(vcpu);
+ guest_state_exit_irqoff();
+
+ return ret;
+}
+
int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu)
{
int r = -EINTR;
@@ -434,7 +452,7 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu)
lose_fpu(1);
local_irq_disable();
- guest_enter_irqoff();
+ guest_timing_enter_irqoff();
trace_kvm_enter(vcpu);
/*
@@ -445,10 +463,23 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu)
*/
smp_store_mb(vcpu->mode, IN_GUEST_MODE);
- r = kvm_mips_callbacks->vcpu_run(vcpu);
+ r = kvm_mips_vcpu_enter_exit(vcpu);
+
+ /*
+ * We must ensure that any pending interrupts are taken before
+ * we exit guest timing so that timer ticks are accounted as
+ * guest time. Transiently unmask interrupts so that any
+ * pending interrupts are taken.
+ *
+ * TODO: is there a barrier which ensures that pending interrupts are
+ * recognised? Currently this just hopes that the CPU takes any pending
+ * interrupts between the enable and disable.
+ */
+ local_irq_enable();
+ local_irq_disable();
trace_kvm_out(vcpu);
- guest_exit_irqoff();
+ guest_timing_exit_irqoff();
local_irq_enable();
out:
@@ -1168,7 +1199,7 @@ static void kvm_mips_set_c0_status(void)
/*
* Return value is in the form (errcode<<2 | RESUME_FLAG_HOST | RESUME_FLAG_NV)
*/
-int kvm_mips_handle_exit(struct kvm_vcpu *vcpu)
+static int __kvm_mips_handle_exit(struct kvm_vcpu *vcpu)
{
struct kvm_run *run = vcpu->run;
u32 cause = vcpu->arch.host_cp0_cause;
@@ -1357,6 +1388,17 @@ int kvm_mips_handle_exit(struct kvm_vcpu *vcpu)
return ret;
}
+int noinstr kvm_mips_handle_exit(struct kvm_vcpu *vcpu)
+{
+ int ret;
+
+ guest_state_exit_irqoff();
+ ret = __kvm_mips_handle_exit(vcpu);
+ guest_state_enter_irqoff();
+
+ return ret;
+}
+
/* Enable FPU for guest and restore context */
void kvm_own_fpu(struct kvm_vcpu *vcpu)
{
diff --git a/arch/mips/kvm/vz.c b/arch/mips/kvm/vz.c
index 4adca5abbc72..c706f5890a05 100644
--- a/arch/mips/kvm/vz.c
+++ b/arch/mips/kvm/vz.c
@@ -458,8 +458,8 @@ void kvm_vz_acquire_htimer(struct kvm_vcpu *vcpu)
/**
* _kvm_vz_save_htimer() - Switch to software emulation of guest timer.
* @vcpu: Virtual CPU.
- * @compare: Pointer to write compare value to.
- * @cause: Pointer to write cause value to.
+ * @out_compare: Pointer to write compare value to.
+ * @out_cause: Pointer to write cause value to.
*
* Save VZ guest timer state and switch to software emulation of guest CP0
* timer. The hard timer must already be in use, so preemption should be
@@ -1541,11 +1541,14 @@ static int kvm_trap_vz_handle_guest_exit(struct kvm_vcpu *vcpu)
}
/**
- * kvm_trap_vz_handle_cop_unusuable() - Guest used unusable coprocessor.
+ * kvm_trap_vz_handle_cop_unusable() - Guest used unusable coprocessor.
* @vcpu: Virtual CPU context.
*
* Handle when the guest attempts to use a coprocessor which hasn't been allowed
* by the root context.
+ *
+ * Return: value indicating whether to resume the host or the guest
+ * (RESUME_HOST or RESUME_GUEST)
*/
static int kvm_trap_vz_handle_cop_unusable(struct kvm_vcpu *vcpu)
{
@@ -1592,6 +1595,9 @@ static int kvm_trap_vz_handle_cop_unusable(struct kvm_vcpu *vcpu)
*
* Handle when the guest attempts to use MSA when it is disabled in the root
* context.
+ *
+ * Return: value indicating whether to resume the host or the guest
+ * (RESUME_HOST or RESUME_GUEST)
*/
static int kvm_trap_vz_handle_msa_disabled(struct kvm_vcpu *vcpu)
{
diff --git a/arch/mips/lib/csum_partial.S b/arch/mips/lib/csum_partial.S
index a46db0807195..7767137c3e49 100644
--- a/arch/mips/lib/csum_partial.S
+++ b/arch/mips/lib/csum_partial.S
@@ -347,7 +347,7 @@ EXPORT_SYMBOL(csum_partial)
.if \mode == LEGACY_MODE; \
9: insn reg, addr; \
.section __ex_table,"a"; \
- PTR 9b, .L_exc; \
+ PTR_WD 9b, .L_exc; \
.previous; \
/* This is enabled in EVA mode */ \
.else; \
@@ -356,7 +356,7 @@ EXPORT_SYMBOL(csum_partial)
((\to == USEROP) && (type == ST_INSN)); \
9: __BUILD_EVA_INSN(insn##e, reg, addr); \
.section __ex_table,"a"; \
- PTR 9b, .L_exc; \
+ PTR_WD 9b, .L_exc; \
.previous; \
.else; \
/* EVA without exception */ \
diff --git a/arch/mips/lib/memcpy.S b/arch/mips/lib/memcpy.S
index 277c32296636..18a43f2e29c8 100644
--- a/arch/mips/lib/memcpy.S
+++ b/arch/mips/lib/memcpy.S
@@ -116,7 +116,7 @@
.if \mode == LEGACY_MODE; \
9: insn reg, addr; \
.section __ex_table,"a"; \
- PTR 9b, handler; \
+ PTR_WD 9b, handler; \
.previous; \
/* This is assembled in EVA mode */ \
.else; \
@@ -125,7 +125,7 @@
((\to == USEROP) && (type == ST_INSN)); \
9: __BUILD_EVA_INSN(insn##e, reg, addr); \
.section __ex_table,"a"; \
- PTR 9b, handler; \
+ PTR_WD 9b, handler; \
.previous; \
.else; \
/* \
diff --git a/arch/mips/lib/memset.S b/arch/mips/lib/memset.S
index b0baa3c79fad..0b342bae9a98 100644
--- a/arch/mips/lib/memset.S
+++ b/arch/mips/lib/memset.S
@@ -52,7 +52,7 @@
9: ___BUILD_EVA_INSN(insn, reg, addr); \
.endif; \
.section __ex_table,"a"; \
- PTR 9b, handler; \
+ PTR_WD 9b, handler; \
.previous
.macro f_fill64 dst, offset, val, fixup, mode
diff --git a/arch/mips/lib/strncpy_user.S b/arch/mips/lib/strncpy_user.S
index 556acf684d7b..13aaa9927ad1 100644
--- a/arch/mips/lib/strncpy_user.S
+++ b/arch/mips/lib/strncpy_user.S
@@ -15,7 +15,7 @@
#define EX(insn,reg,addr,handler) \
9: insn reg, addr; \
.section __ex_table,"a"; \
- PTR 9b, handler; \
+ PTR_WD 9b, handler; \
.previous
/*
@@ -59,7 +59,7 @@ LEAF(__strncpy_from_user_asm)
jr ra
.section __ex_table,"a"
- PTR 1b, .Lfault
+ PTR_WD 1b, .Lfault
.previous
EXPORT_SYMBOL(__strncpy_from_user_asm)
diff --git a/arch/mips/lib/strnlen_user.S b/arch/mips/lib/strnlen_user.S
index 92b63f20ec05..6de31b616f9c 100644
--- a/arch/mips/lib/strnlen_user.S
+++ b/arch/mips/lib/strnlen_user.S
@@ -14,7 +14,7 @@
#define EX(insn,reg,addr,handler) \
9: insn reg, addr; \
.section __ex_table,"a"; \
- PTR 9b, handler; \
+ PTR_WD 9b, handler; \
.previous
/*
diff --git a/arch/mips/loongson64/vbios_quirk.c b/arch/mips/loongson64/vbios_quirk.c
index 9a29e94d3db1..3115d4de982c 100644
--- a/arch/mips/loongson64/vbios_quirk.c
+++ b/arch/mips/loongson64/vbios_quirk.c
@@ -3,7 +3,7 @@
#include <linux/pci.h>
#include <loongson.h>
-static void pci_fixup_radeon(struct pci_dev *pdev)
+static void pci_fixup_video(struct pci_dev *pdev)
{
struct resource *res = &pdev->resource[PCI_ROM_RESOURCE];
@@ -22,8 +22,7 @@ static void pci_fixup_radeon(struct pci_dev *pdev)
res->flags = IORESOURCE_MEM | IORESOURCE_ROM_SHADOW |
IORESOURCE_PCI_FIXED;
- dev_info(&pdev->dev, "BAR %d: assigned %pR for Radeon ROM\n",
- PCI_ROM_RESOURCE, res);
+ dev_info(&pdev->dev, "Video device with shadowed ROM at %pR\n", res);
}
-DECLARE_PCI_FIXUP_CLASS_FINAL(PCI_VENDOR_ID_ATI, 0x9615,
- PCI_CLASS_DISPLAY_VGA, 8, pci_fixup_radeon);
+DECLARE_PCI_FIXUP_CLASS_HEADER(PCI_VENDOR_ID_ATI, 0x9615,
+ PCI_CLASS_DISPLAY_VGA, 8, pci_fixup_video);
diff --git a/arch/mips/ralink/mt7621.c b/arch/mips/ralink/mt7621.c
index d6efffd4dd20..fb0565bc34fd 100644
--- a/arch/mips/ralink/mt7621.c
+++ b/arch/mips/ralink/mt7621.c
@@ -22,7 +22,9 @@
#include "common.h"
-static void *detect_magic __initdata = detect_memory_region;
+#define MT7621_MEM_TEST_PATTERN 0xaa5555aa
+
+static u32 detect_magic __initdata;
int pcibios_root_bridge_prepare(struct pci_host_bridge *bridge)
{
@@ -58,24 +60,32 @@ phys_addr_t mips_cpc_default_phys_base(void)
panic("Cannot detect cpc address");
}
+static bool __init mt7621_addr_wraparound_test(phys_addr_t size)
+{
+ void *dm = (void *)KSEG1ADDR(&detect_magic);
+
+ if (CPHYSADDR(dm + size) >= MT7621_LOWMEM_MAX_SIZE)
+ return true;
+ __raw_writel(MT7621_MEM_TEST_PATTERN, dm);
+ if (__raw_readl(dm) != __raw_readl(dm + size))
+ return false;
+ __raw_writel(~MT7621_MEM_TEST_PATTERN, dm);
+ return __raw_readl(dm) == __raw_readl(dm + size);
+}
+
static void __init mt7621_memory_detect(void)
{
- void *dm = &detect_magic;
phys_addr_t size;
- for (size = 32 * SZ_1M; size < 256 * SZ_1M; size <<= 1) {
- if (!__builtin_memcmp(dm, dm + size, sizeof(detect_magic)))
- break;
+ for (size = 32 * SZ_1M; size <= 256 * SZ_1M; size <<= 1) {
+ if (mt7621_addr_wraparound_test(size)) {
+ memblock_add(MT7621_LOWMEM_BASE, size);
+ return;
+ }
}
- if ((size == 256 * SZ_1M) &&
- (CPHYSADDR(dm + size) < MT7621_LOWMEM_MAX_SIZE) &&
- __builtin_memcmp(dm, dm + size, sizeof(detect_magic))) {
- memblock_add(MT7621_LOWMEM_BASE, MT7621_LOWMEM_MAX_SIZE);
- memblock_add(MT7621_HIGHMEM_BASE, MT7621_HIGHMEM_SIZE);
- } else {
- memblock_add(MT7621_LOWMEM_BASE, size);
- }
+ memblock_add(MT7621_LOWMEM_BASE, MT7621_LOWMEM_MAX_SIZE);
+ memblock_add(MT7621_HIGHMEM_BASE, MT7621_HIGHMEM_SIZE);
}
void __init ralink_of_remap(void)
diff --git a/arch/nds32/Kconfig b/arch/nds32/Kconfig
deleted file mode 100644
index 4d1421b18734..000000000000
--- a/arch/nds32/Kconfig
+++ /dev/null
@@ -1,102 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0-only
-#
-# For a description of the syntax of this configuration file,
-# see Documentation/kbuild/kconfig-language.rst.
-#
-
-config NDS32
- def_bool y
- select ARCH_32BIT_OFF_T
- select ARCH_HAS_DMA_PREP_COHERENT
- select ARCH_HAS_SYNC_DMA_FOR_CPU
- select ARCH_HAS_SYNC_DMA_FOR_DEVICE
- select ARCH_WANT_FRAME_POINTERS if FTRACE
- select CLKSRC_MMIO
- select CLONE_BACKWARDS
- select COMMON_CLK
- select DMA_DIRECT_REMAP
- select GENERIC_ATOMIC64
- select GENERIC_CPU_DEVICES
- select GENERIC_IRQ_CHIP
- select GENERIC_IRQ_SHOW
- select GENERIC_IOREMAP
- select GENERIC_LIB_ASHLDI3
- select GENERIC_LIB_ASHRDI3
- select GENERIC_LIB_CMPDI2
- select GENERIC_LIB_LSHRDI3
- select GENERIC_LIB_MULDI3
- select GENERIC_LIB_UCMPDI2
- select GENERIC_TIME_VSYSCALL
- select HAVE_ARCH_TRACEHOOK
- select HAVE_DEBUG_KMEMLEAK
- select HAVE_EXIT_THREAD
- select HAVE_REGS_AND_STACK_ACCESS_API
- select HAVE_PERF_EVENTS
- select IRQ_DOMAIN
- select LOCKDEP_SUPPORT
- select MODULES_USE_ELF_RELA
- select OF
- select OF_EARLY_FLATTREE
- select NO_IOPORT_MAP
- select RTC_LIB
- select THREAD_INFO_IN_TASK
- select HAVE_FUNCTION_TRACER
- select HAVE_FUNCTION_GRAPH_TRACER
- select HAVE_FTRACE_MCOUNT_RECORD
- select HAVE_DYNAMIC_FTRACE
- select SET_FS
- select TRACE_IRQFLAGS_SUPPORT
- help
- Andes(nds32) Linux support.
-
-config GENERIC_CALIBRATE_DELAY
- def_bool y
-
-config GENERIC_CSUM
- def_bool y
-
-config GENERIC_HWEIGHT
- def_bool y
-
-config GENERIC_LOCKBREAK
- def_bool y
- depends on PREEMPTION
-
-config STACKTRACE_SUPPORT
- def_bool y
-
-config FIX_EARLYCON_MEM
- def_bool y
-
-config PGTABLE_LEVELS
- default 2
-
-menu "System Type"
-source "arch/nds32/Kconfig.cpu"
-config NR_CPUS
- int
- default 1
-
-config MMU
- def_bool y
-
-config NDS32_BUILTIN_DTB
- string "Builtin DTB"
- default ""
- help
- User can use it to specify the dts of the SoC
-endmenu
-
-menu "Kernel Features"
-source "kernel/Kconfig.hz"
-endmenu
-
-menu "Power management options"
-config SYS_SUPPORTS_APM_EMULATION
- bool
-
-config ARCH_SUSPEND_POSSIBLE
- def_bool y
-
-source "kernel/power/Kconfig"
-endmenu
diff --git a/arch/nds32/Kconfig.cpu b/arch/nds32/Kconfig.cpu
deleted file mode 100644
index c10759952485..000000000000
--- a/arch/nds32/Kconfig.cpu
+++ /dev/null
@@ -1,218 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0-only
-comment "Processor Features"
-
-config CPU_BIG_ENDIAN
- def_bool !CPU_LITTLE_ENDIAN
-
-config CPU_LITTLE_ENDIAN
- bool "Little endian"
- default y
-
-config FPU
- bool "FPU support"
- default n
- help
- If FPU ISA is used in user space, this configuration shall be Y to
- enable required support in kernel such as fpu context switch and
- fpu exception handler.
-
- If no FPU ISA is used in user space, say N.
-
-config LAZY_FPU
- bool "lazy FPU support"
- depends on FPU
- default y
- help
- Say Y here to enable the lazy FPU scheme. The lazy FPU scheme can
- enhance system performance by reducing the context switch
- frequency of the FPU register.
-
- For normal case, say Y.
-
-config SUPPORT_DENORMAL_ARITHMETIC
- bool "Denormal arithmetic support"
- depends on FPU
- default n
- help
- Say Y here to enable arithmetic of denormalized number. Enabling
- this feature can enhance the precision for tininess number.
- However, performance loss in float point calculations is
- possibly significant due to additional FPU exception.
-
- If the calculated tolerance for tininess number is not critical,
- say N to prevent performance loss.
-
-config HWZOL
- bool "hardware zero overhead loop support"
- depends on CPU_D10 || CPU_D15
- default n
- help
- A set of Zero-Overhead Loop mechanism is provided to reduce the
- instruction fetch and execution overhead of loop-control instructions.
- It will save 3 registers($LB, $LC, $LE) for context saving if say Y.
- You don't need to save these registers if you can make sure your user
- program doesn't use these registers.
-
- If unsure, say N.
-
-config CPU_CACHE_ALIASING
- bool "Aliasing cache"
- depends on CPU_N10 || CPU_D10 || CPU_N13 || CPU_V3
- default y
- help
- If this CPU is using VIPT data cache and its cache way size is larger
- than page size, say Y. If it is using PIPT data cache, say N.
-
- If unsure, say Y.
-
-choice
- prompt "minimum CPU type"
- default CPU_V3
- help
- The data cache of N15/D15 is implemented as PIPT and it will not cause
- the cache aliasing issue. The rest cpus(N13, N10 and D10) are
- implemented as VIPT data cache. It may cause the cache aliasing issue
- if its cache way size is larger than page size. You can specify the
- CPU type directly or choose CPU_V3 if unsure.
-
- A kernel built for N10 is able to run on N15, D15, N13, N10 or D10.
- A kernel built for N15 is able to run on N15 or D15.
- A kernel built for D10 is able to run on D10 or D15.
- A kernel built for D15 is able to run on D15.
- A kernel built for N13 is able to run on N15, N13 or D15.
-
-config CPU_N15
- bool "AndesCore N15"
-config CPU_N13
- bool "AndesCore N13"
- select CPU_CACHE_ALIASING if ANDES_PAGE_SIZE_4KB
-config CPU_N10
- bool "AndesCore N10"
- select CPU_CACHE_ALIASING
-config CPU_D15
- bool "AndesCore D15"
-config CPU_D10
- bool "AndesCore D10"
- select CPU_CACHE_ALIASING
-config CPU_V3
- bool "AndesCore v3 compatible"
- select CPU_CACHE_ALIASING
-endchoice
-choice
- prompt "Paging -- page size "
- default ANDES_PAGE_SIZE_4KB
-config ANDES_PAGE_SIZE_4KB
- bool "use 4KB page size"
-config ANDES_PAGE_SIZE_8KB
- bool "use 8KB page size"
-endchoice
-
-config CPU_ICACHE_DISABLE
- bool "Disable I-Cache"
- help
- Say Y here to disable the processor instruction cache. Unless
- you have a reason not to or are unsure, say N.
-
-config CPU_DCACHE_DISABLE
- bool "Disable D-Cache"
- help
- Say Y here to disable the processor data cache. Unless
- you have a reason not to or are unsure, say N.
-
-config CPU_DCACHE_WRITETHROUGH
- bool "Force write through D-cache"
- depends on !CPU_DCACHE_DISABLE
- help
- Say Y here to use the data cache in writethrough mode. Unless you
- specifically require this or are unsure, say N.
-
-config WBNA
- bool "WBNA"
- default n
- help
- Say Y here to enable write-back memory with no-write-allocation policy.
-
-config ALIGNMENT_TRAP
- bool "Kernel support unaligned access handling by sw"
- depends on PROC_FS
- default n
- help
- Andes processors cannot load/store information which is not
- naturally aligned on the bus, i.e., a 4 byte load must start at an
- address divisible by 4. On 32-bit Andes processors, these non-aligned
- load/store instructions will be emulated in software if you say Y
- here, which has a severe performance impact. With an IP-only
- configuration it is safe to say N, otherwise say Y.
-
-config HW_SUPPORT_UNALIGNMENT_ACCESS
- bool "Kernel support unaligned access handling by hw"
- depends on !ALIGNMENT_TRAP
- default n
- help
- Andes processors load/store world/half-word instructions can access
- unaligned memory locations without generating the Data Alignment
- Check exceptions. With an IP-only configuration it is safe to say N,
- otherwise say Y.
-
-config HIGHMEM
- bool "High Memory Support"
- depends on MMU && !CPU_CACHE_ALIASING
- select KMAP_LOCAL
- help
- The address space of Andes processors is only 4 Gigabytes large
- and it has to accommodate user address space, kernel address
- space as well as some memory mapped IO. That means that, if you
- have a large amount of physical memory and/or IO, not all of the
- memory can be "permanently mapped" by the kernel. The physical
- memory that is not permanently mapped is called "high memory".
-
- Depending on the selected kernel/user memory split, minimum
- vmalloc space and actual amount of RAM, you may not need this
- option which should result in a slightly faster kernel.
-
- If unsure, say N.
-
-config CACHE_L2
- bool "Support L2 cache"
- default y
- help
- Say Y here to enable L2 cache if your SoC are integrated with L2CC.
- If unsure, say N.
-
-config HW_PRE
- bool "Enable hardware prefetcher"
- default y
- help
- Say Y here to enable hardware prefetcher feature.
- Only when CPU_VER.REV >= 0x09 can support.
-
-menu "Memory configuration"
-
-choice
- prompt "Memory split"
- depends on MMU
- default VMSPLIT_3G_OPT
- help
- Select the desired split between kernel and user memory.
-
- If you are not absolutely sure what you are doing, leave this
- option alone!
-
- config VMSPLIT_3G
- bool "3G/1G user/kernel split"
- config VMSPLIT_3G_OPT
- bool "3G/1G user/kernel split (for full 1G low memory)"
- config VMSPLIT_2G
- bool "2G/2G user/kernel split"
- config VMSPLIT_1G
- bool "1G/3G user/kernel split"
-endchoice
-
-config PAGE_OFFSET
- hex
- default 0x40000000 if VMSPLIT_1G
- default 0x80000000 if VMSPLIT_2G
- default 0xB0000000 if VMSPLIT_3G_OPT
- default 0xC0000000
-
-endmenu
diff --git a/arch/nds32/Makefile b/arch/nds32/Makefile
deleted file mode 100644
index b33d5d81b6ae..000000000000
--- a/arch/nds32/Makefile
+++ /dev/null
@@ -1,63 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0-only
-LDFLAGS_vmlinux := --no-undefined -X
-OBJCOPYFLAGS := -O binary -R .note -R .note.gnu.build-id -R .comment -S
-
-ifdef CONFIG_FUNCTION_TRACER
-arch-y += -malways-save-lp -mno-relax
-endif
-
-# Avoid generating FPU instructions
-arch-y += -mno-ext-fpu-sp -mno-ext-fpu-dp -mfloat-abi=soft
-
-# Enable <nds32_intrinsic.h>
-KBUILD_CFLAGS += -isystem $(shell $(CC) -print-file-name=include)
-KBUILD_CFLAGS += $(call cc-option, -mno-sched-prolog-epilog)
-KBUILD_CFLAGS += -mcmodel=large
-
-KBUILD_CFLAGS +=$(arch-y) $(tune-y)
-KBUILD_AFLAGS +=$(arch-y) $(tune-y)
-
-#Default value
-head-y := arch/nds32/kernel/head.o
-textaddr-y := $(CONFIG_PAGE_OFFSET)+0xc000
-
-TEXTADDR := $(textaddr-y)
-
-export TEXTADDR
-
-
-# If we have a machine-specific directory, then include it in the build.
-core-y += arch/nds32/kernel/ arch/nds32/mm/
-core-$(CONFIG_FPU) += arch/nds32/math-emu/
-libs-y += arch/nds32/lib/
-
-ifdef CONFIG_CPU_LITTLE_ENDIAN
-KBUILD_CFLAGS += $(call cc-option, -EL)
-KBUILD_AFLAGS += $(call cc-option, -EL)
-KBUILD_LDFLAGS += $(call cc-option, -EL)
-CHECKFLAGS += -D__NDS32_EL__
-else
-KBUILD_CFLAGS += $(call cc-option, -EB)
-KBUILD_AFLAGS += $(call cc-option, -EB)
-KBUILD_LDFLAGS += $(call cc-option, -EB)
-CHECKFLAGS += -D__NDS32_EB__
-endif
-
-boot := arch/nds32/boot
-core-y += $(boot)/dts/
-
-Image: vmlinux
- $(Q)$(MAKE) $(build)=$(boot) $(boot)/$@
-
-
-PHONY += vdso_install
-vdso_install:
- $(Q)$(MAKE) $(build)=arch/nds32/kernel/vdso $@
-
-prepare: vdso_prepare
-vdso_prepare: prepare0
- $(Q)$(MAKE) $(build)=arch/nds32/kernel/vdso include/generated/vdso-offsets.h
-
-define archhelp
- echo ' Image - kernel image (arch/$(ARCH)/boot/Image)'
-endef
diff --git a/arch/nds32/boot/.gitignore b/arch/nds32/boot/.gitignore
deleted file mode 100644
index 9182a3a1ea0a..000000000000
--- a/arch/nds32/boot/.gitignore
+++ /dev/null
@@ -1,2 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0-only
-/Image
diff --git a/arch/nds32/boot/Makefile b/arch/nds32/boot/Makefile
deleted file mode 100644
index c4cc0c2689f7..000000000000
--- a/arch/nds32/boot/Makefile
+++ /dev/null
@@ -1,16 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0-only
-targets := Image Image.gz
-
-$(obj)/Image: vmlinux FORCE
- $(call if_changed,objcopy)
-
-$(obj)/Image.gz: $(obj)/Image FORCE
- $(call if_changed,gzip)
-
-install: $(obj)/Image
- $(CONFIG_SHELL) $(srctree)/$(src)/install.sh $(KERNELRELEASE) \
- $(obj)/Image System.map "$(INSTALL_PATH)"
-
-zinstall: $(obj)/Image.gz
- $(CONFIG_SHELL) $(srctree)/$(src)/install.sh $(KERNELRELEASE) \
- $(obj)/Image.gz System.map "$(INSTALL_PATH)"
diff --git a/arch/nds32/boot/dts/Makefile b/arch/nds32/boot/dts/Makefile
deleted file mode 100644
index 4fc69562eae8..000000000000
--- a/arch/nds32/boot/dts/Makefile
+++ /dev/null
@@ -1,2 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0-only
-obj-$(CONFIG_OF) += $(addsuffix .dtb.o, $(CONFIG_NDS32_BUILTIN_DTB))
diff --git a/arch/nds32/boot/dts/ae3xx.dts b/arch/nds32/boot/dts/ae3xx.dts
deleted file mode 100644
index 16a9f54a805e..000000000000
--- a/arch/nds32/boot/dts/ae3xx.dts
+++ /dev/null
@@ -1,90 +0,0 @@
-/dts-v1/;
-/ {
- compatible = "andestech,ae3xx";
- #address-cells = <1>;
- #size-cells = <1>;
- interrupt-parent = <&intc>;
-
- chosen {
- stdout-path = &serial0;
- };
-
- memory@0 {
- device_type = "memory";
- reg = <0x00000000 0x40000000>;
- };
-
- cpus {
- #address-cells = <1>;
- #size-cells = <0>;
- cpu@0 {
- device_type = "cpu";
- compatible = "andestech,n13", "andestech,nds32v3";
- reg = <0>;
- clock-frequency = <60000000>;
- next-level-cache = <&L2>;
- };
- };
-
- intc: interrupt-controller {
- compatible = "andestech,ativic32";
- #interrupt-cells = <1>;
- interrupt-controller;
- };
-
- clock: clk {
- #clock-cells = <0>;
- compatible = "fixed-clock";
- clock-frequency = <30000000>;
- };
-
- apb {
- compatible = "simple-bus";
- #address-cells = <1>;
- #size-cells = <1>;
- ranges;
-
- serial0: serial@f0300000 {
- compatible = "andestech,uart16550", "ns16550a";
- reg = <0xf0300000 0x1000>;
- interrupts = <8>;
- clock-frequency = <14745600>;
- reg-shift = <2>;
- reg-offset = <32>;
- no-loopback-test = <1>;
- };
-
- timer0: timer@f0400000 {
- compatible = "andestech,atcpit100";
- reg = <0xf0400000 0x1000>;
- interrupts = <2>;
- clocks = <&clock>;
- clock-names = "PCLK";
- };
- };
-
- ahb {
- compatible = "simple-bus";
- #address-cells = <1>;
- #size-cells = <1>;
- ranges;
-
- L2: cache-controller@e0500000 {
- compatible = "andestech,atl2c";
- reg = <0xe0500000 0x1000>;
- cache-unified;
- cache-level = <2>;
- };
-
- mac0: ethernet@e0100000 {
- compatible = "andestech,atmac100";
- reg = <0xe0100000 0x1000>;
- interrupts = <18>;
- };
- };
-
- pmu {
- compatible = "andestech,nds32v3-pmu";
- interrupts= <13>;
- };
-};
diff --git a/arch/nds32/configs/defconfig b/arch/nds32/configs/defconfig
deleted file mode 100644
index f9a89cf00aa6..000000000000
--- a/arch/nds32/configs/defconfig
+++ /dev/null
@@ -1,104 +0,0 @@
-CONFIG_SYSVIPC=y
-CONFIG_POSIX_MQUEUE=y
-CONFIG_HIGH_RES_TIMERS=y
-CONFIG_BSD_PROCESS_ACCT=y
-CONFIG_BSD_PROCESS_ACCT_V3=y
-CONFIG_IKCONFIG=y
-CONFIG_IKCONFIG_PROC=y
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_USER_NS=y
-CONFIG_RELAY=y
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_KALLSYMS_ALL=y
-CONFIG_PROFILING=y
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_BLK_DEV_BSG is not set
-# CONFIG_CACHE_L2 is not set
-CONFIG_PREEMPT=y
-# CONFIG_COMPACTION is not set
-CONFIG_HZ_100=y
-# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
-CONFIG_NET=y
-CONFIG_PACKET=y
-CONFIG_UNIX=y
-CONFIG_NET_KEY=y
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
-# CONFIG_INET_XFRM_MODE_TUNNEL is not set
-# CONFIG_INET_XFRM_MODE_BEET is not set
-# CONFIG_INET_DIAG is not set
-# CONFIG_IPV6 is not set
-# CONFIG_BLK_DEV is not set
-CONFIG_NETDEVICES=y
-# CONFIG_NET_CADENCE is not set
-# CONFIG_NET_VENDOR_BROADCOM is not set
-CONFIG_FTMAC100=y
-# CONFIG_NET_VENDOR_INTEL is not set
-# CONFIG_NET_VENDOR_MARVELL is not set
-# CONFIG_NET_VENDOR_MICREL is not set
-# CONFIG_NET_VENDOR_NATSEMI is not set
-# CONFIG_NET_VENDOR_SEEQ is not set
-# CONFIG_NET_VENDOR_STMICRO is not set
-# CONFIG_NET_VENDOR_WIZNET is not set
-CONFIG_INPUT_EVDEV=y
-# CONFIG_INPUT_KEYBOARD is not set
-# CONFIG_INPUT_MOUSE is not set
-CONFIG_INPUT_TOUCHSCREEN=y
-# CONFIG_SERIO is not set
-CONFIG_VT_HW_CONSOLE_BINDING=y
-CONFIG_SERIAL_8250=y
-# CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set
-CONFIG_SERIAL_8250_CONSOLE=y
-CONFIG_SERIAL_8250_NR_UARTS=3
-CONFIG_SERIAL_8250_RUNTIME_UARTS=3
-CONFIG_SERIAL_OF_PLATFORM=y
-# CONFIG_HW_RANDOM is not set
-# CONFIG_HWMON is not set
-# CONFIG_HID_A4TECH is not set
-# CONFIG_HID_APPLE is not set
-# CONFIG_HID_BELKIN is not set
-# CONFIG_HID_CHERRY is not set
-# CONFIG_HID_CHICONY is not set
-# CONFIG_HID_CYPRESS is not set
-# CONFIG_HID_EZKEY is not set
-# CONFIG_HID_ITE is not set
-# CONFIG_HID_KENSINGTON is not set
-# CONFIG_HID_LOGITECH is not set
-# CONFIG_HID_MICROSOFT is not set
-# CONFIG_HID_MONTEREY is not set
-# CONFIG_USB_SUPPORT is not set
-CONFIG_GENERIC_PHY=y
-CONFIG_EXT4_FS=y
-CONFIG_EXT4_FS_POSIX_ACL=y
-CONFIG_EXT4_FS_SECURITY=y
-CONFIG_FS_ENCRYPTION=y
-CONFIG_FUSE_FS=y
-CONFIG_MSDOS_FS=y
-CONFIG_VFAT_FS=y
-CONFIG_TMPFS=y
-CONFIG_TMPFS_POSIX_ACL=y
-CONFIG_CONFIGFS_FS=y
-CONFIG_NFS_FS=y
-CONFIG_NFS_V3_ACL=y
-CONFIG_NFS_V4=y
-CONFIG_NFS_V4_1=y
-CONFIG_NFS_USE_LEGACY_DNS=y
-CONFIG_NLS_CODEPAGE_437=y
-CONFIG_NLS_ISO8859_1=y
-CONFIG_DEBUG_INFO=y
-CONFIG_DEBUG_INFO_DWARF4=y
-CONFIG_GDB_SCRIPTS=y
-CONFIG_READABLE_ASM=y
-CONFIG_HEADERS_INSTALL=y
-CONFIG_HEADERS_CHECK=y
-CONFIG_DEBUG_SECTION_MISMATCH=y
-CONFIG_MAGIC_SYSRQ=y
-CONFIG_DEBUG_KERNEL=y
-CONFIG_PANIC_ON_OOPS=y
-# CONFIG_SCHED_DEBUG is not set
-# CONFIG_DEBUG_PREEMPT is not set
-CONFIG_STACKTRACE=y
-CONFIG_RCU_CPU_STALL_TIMEOUT=300
-# CONFIG_CRYPTO_HW is not set
diff --git a/arch/nds32/include/asm/Kbuild b/arch/nds32/include/asm/Kbuild
deleted file mode 100644
index 82a4453c9c2d..000000000000
--- a/arch/nds32/include/asm/Kbuild
+++ /dev/null
@@ -1,8 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-generic-y += asm-offsets.h
-generic-y += cmpxchg.h
-generic-y += export.h
-generic-y += gpio.h
-generic-y += kvm_para.h
-generic-y += parport.h
-generic-y += user.h
diff --git a/arch/nds32/include/asm/assembler.h b/arch/nds32/include/asm/assembler.h
deleted file mode 100644
index 5e7c56926049..000000000000
--- a/arch/nds32/include/asm/assembler.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-// Copyright (C) 2005-2017 Andes Technology Corporation
-
-#ifndef __NDS32_ASSEMBLER_H__
-#define __NDS32_ASSEMBLER_H__
-
-.macro gie_disable
- setgie.d
- dsb
-.endm
-
-.macro gie_enable
- setgie.e
- dsb
-.endm
-
-.macro gie_save oldpsw
- mfsr \oldpsw, $ir0
- setgie.d
- dsb
-.endm
-
-.macro gie_restore oldpsw
- andi \oldpsw, \oldpsw, #0x1
- beqz \oldpsw, 7001f
- setgie.e
- dsb
-7001:
-.endm
-
-
-#define USER(insn, reg, addr, opr) \
-9999: insn reg, addr, opr; \
- .section __ex_table,"a"; \
- .align 3; \
- .long 9999b, 9001f; \
- .previous
-
-#endif /* __NDS32_ASSEMBLER_H__ */
diff --git a/arch/nds32/include/asm/barrier.h b/arch/nds32/include/asm/barrier.h
deleted file mode 100644
index 16413172fd50..000000000000
--- a/arch/nds32/include/asm/barrier.h
+++ /dev/null
@@ -1,15 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-// Copyright (C) 2005-2017 Andes Technology Corporation
-
-#ifndef __NDS32_ASM_BARRIER_H
-#define __NDS32_ASM_BARRIER_H
-
-#ifndef __ASSEMBLY__
-#define mb() asm volatile("msync all":::"memory")
-#define rmb() asm volatile("msync all":::"memory")
-#define wmb() asm volatile("msync store":::"memory")
-#include <asm-generic/barrier.h>
-
-#endif /* __ASSEMBLY__ */
-
-#endif /* __NDS32_ASM_BARRIER_H */
diff --git a/arch/nds32/include/asm/bitfield.h b/arch/nds32/include/asm/bitfield.h
deleted file mode 100644
index b02a58e71f80..000000000000
--- a/arch/nds32/include/asm/bitfield.h
+++ /dev/null
@@ -1,985 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-// Copyright (C) 2005-2017 Andes Technology Corporation
-
-#ifndef __NDS32_BITFIELD_H__
-#define __NDS32_BITFIELD_H__
-/******************************************************************************
- * cr0: CPU_VER (CPU Version Register)
- *****************************************************************************/
-#define CPU_VER_offCFGID 0 /* Minor configuration */
-#define CPU_VER_offREV 16 /* Revision of the CPU version */
-#define CPU_VER_offCPUID 24 /* Major CPU versions */
-
-#define CPU_VER_mskCFGID ( 0xFFFF << CPU_VER_offCFGID )
-#define CPU_VER_mskREV ( 0xFF << CPU_VER_offREV )
-#define CPU_VER_mskCPUID ( 0xFF << CPU_VER_offCPUID )
-
-/******************************************************************************
- * cr1: ICM_CFG (Instruction Cache/Memory Configuration Register)
- *****************************************************************************/
-#define ICM_CFG_offISET 0 /* I-cache sets (# of cache lines) per way */
-#define ICM_CFG_offIWAY 3 /* I-cache ways */
-#define ICM_CFG_offISZ 6 /* I-cache line size */
-#define ICM_CFG_offILCK 9 /* I-cache locking support */
-#define ICM_CFG_offILMB 10 /* On-chip ILM banks */
-#define ICM_CFG_offBSAV 13 /* ILM base register alignment version */
-/* bit 15:31 reserved */
-
-#define ICM_CFG_mskISET ( 0x7 << ICM_CFG_offISET )
-#define ICM_CFG_mskIWAY ( 0x7 << ICM_CFG_offIWAY )
-#define ICM_CFG_mskISZ ( 0x7 << ICM_CFG_offISZ )
-#define ICM_CFG_mskILCK ( 0x1 << ICM_CFG_offILCK )
-#define ICM_CFG_mskILMB ( 0x7 << ICM_CFG_offILMB )
-#define ICM_CFG_mskBSAV ( 0x3 << ICM_CFG_offBSAV )
-
-/******************************************************************************
- * cr2: DCM_CFG (Data Cache/Memory Configuration Register)
- *****************************************************************************/
-#define DCM_CFG_offDSET 0 /* D-cache sets (# of cache lines) per way */
-#define DCM_CFG_offDWAY 3 /* D-cache ways */
-#define DCM_CFG_offDSZ 6 /* D-cache line size */
-#define DCM_CFG_offDLCK 9 /* D-cache locking support */
-#define DCM_CFG_offDLMB 10 /* On-chip DLM banks */
-#define DCM_CFG_offBSAV 13 /* DLM base register alignment version */
-/* bit 15:31 reserved */
-
-#define DCM_CFG_mskDSET ( 0x7 << DCM_CFG_offDSET )
-#define DCM_CFG_mskDWAY ( 0x7 << DCM_CFG_offDWAY )
-#define DCM_CFG_mskDSZ ( 0x7 << DCM_CFG_offDSZ )
-#define DCM_CFG_mskDLCK ( 0x1 << DCM_CFG_offDLCK )
-#define DCM_CFG_mskDLMB ( 0x7 << DCM_CFG_offDLMB )
-#define DCM_CFG_mskBSAV ( 0x3 << DCM_CFG_offBSAV )
-
-/******************************************************************************
- * cr3: MMU_CFG (MMU Configuration Register)
- *****************************************************************************/
-#define MMU_CFG_offMMPS 0 /* Memory management protection scheme */
-#define MMU_CFG_offMMPV 2 /* Memory management protection version number */
-#define MMU_CFG_offFATB 7 /* Fully-associative or non-fully-associative TLB */
-
-#define MMU_CFG_offTBW 8 /* TLB ways(non-associative) TBS */
-#define MMU_CFG_offTBS 11 /* TLB sets per way(non-associative) TBS */
-/* bit 14:14 reserved */
-
-#define MMU_CFG_offEP8MIN4 15 /* 8KB page supported while minimum page is 4KB */
-#define MMU_CFG_offfEPSZ 16 /* Extra page size supported */
-#define MMU_CFG_offTLBLCK 24 /* TLB locking support */
-#define MMU_CFG_offHPTWK 25 /* Hardware Page Table Walker implemented */
-#define MMU_CFG_offDE 26 /* Default endian */
-#define MMU_CFG_offNTPT 27 /* Partitions for non-translated attributes */
-#define MMU_CFG_offIVTB 28 /* Invisible TLB */
-#define MMU_CFG_offVLPT 29 /* VLPT for fast TLB fill handling implemented */
-#define MMU_CFG_offNTME 30 /* Non-translated VA to PA mapping */
-/* bit 31 reserved */
-
-#define MMU_CFG_mskMMPS ( 0x3 << MMU_CFG_offMMPS )
-#define MMU_CFG_mskMMPV ( 0x1F << MMU_CFG_offMMPV )
-#define MMU_CFG_mskFATB ( 0x1 << MMU_CFG_offFATB )
-#define MMU_CFG_mskTBW ( 0x7 << MMU_CFG_offTBW )
-#define MMU_CFG_mskTBS ( 0x7 << MMU_CFG_offTBS )
-#define MMU_CFG_mskEP8MIN4 ( 0x1 << MMU_CFG_offEP8MIN4 )
-#define MMU_CFG_mskfEPSZ ( 0xFF << MMU_CFG_offfEPSZ )
-#define MMU_CFG_mskTLBLCK ( 0x1 << MMU_CFG_offTLBLCK )
-#define MMU_CFG_mskHPTWK ( 0x1 << MMU_CFG_offHPTWK )
-#define MMU_CFG_mskDE ( 0x1 << MMU_CFG_offDE )
-#define MMU_CFG_mskNTPT ( 0x1 << MMU_CFG_offNTPT )
-#define MMU_CFG_mskIVTB ( 0x1 << MMU_CFG_offIVTB )
-#define MMU_CFG_mskVLPT ( 0x1 << MMU_CFG_offVLPT )
-#define MMU_CFG_mskNTME ( 0x1 << MMU_CFG_offNTME )
-
-/******************************************************************************
- * cr4: MSC_CFG (Misc Configuration Register)
- *****************************************************************************/
-#define MSC_CFG_offEDM 0
-#define MSC_CFG_offLMDMA 1
-#define MSC_CFG_offPFM 2
-#define MSC_CFG_offHSMP 3
-#define MSC_CFG_offTRACE 4
-#define MSC_CFG_offDIV 5
-#define MSC_CFG_offMAC 6
-#define MSC_CFG_offAUDIO 7
-#define MSC_CFG_offL2C 9
-#define MSC_CFG_offRDREG 10
-#define MSC_CFG_offADR24 11
-#define MSC_CFG_offINTLC 12
-#define MSC_CFG_offBASEV 13
-#define MSC_CFG_offNOD 16
-/* bit 13:31 reserved */
-
-#define MSC_CFG_mskEDM ( 0x1 << MSC_CFG_offEDM )
-#define MSC_CFG_mskLMDMA ( 0x1 << MSC_CFG_offLMDMA )
-#define MSC_CFG_mskPFM ( 0x1 << MSC_CFG_offPFM )
-#define MSC_CFG_mskHSMP ( 0x1 << MSC_CFG_offHSMP )
-#define MSC_CFG_mskTRACE ( 0x1 << MSC_CFG_offTRACE )
-#define MSC_CFG_mskDIV ( 0x1 << MSC_CFG_offDIV )
-#define MSC_CFG_mskMAC ( 0x1 << MSC_CFG_offMAC )
-#define MSC_CFG_mskAUDIO ( 0x3 << MSC_CFG_offAUDIO )
-#define MSC_CFG_mskL2C ( 0x1 << MSC_CFG_offL2C )
-#define MSC_CFG_mskRDREG ( 0x1 << MSC_CFG_offRDREG )
-#define MSC_CFG_mskADR24 ( 0x1 << MSC_CFG_offADR24 )
-#define MSC_CFG_mskINTLC ( 0x1 << MSC_CFG_offINTLC )
-#define MSC_CFG_mskBASEV ( 0x7 << MSC_CFG_offBASEV )
-#define MSC_CFG_mskNOD ( 0x1 << MSC_CFG_offNOD )
-
-/******************************************************************************
- * cr5: CORE_CFG (Core Identification Register)
- *****************************************************************************/
-#define CORE_ID_offCOREID 0
-/* bit 4:31 reserved */
-
-#define CORE_ID_mskCOREID ( 0xF << CORE_ID_offCOREID )
-
-/******************************************************************************
- * cr6: FUCOP_EXIST (FPU and Coprocessor Existence Configuration Register)
- *****************************************************************************/
-#define FUCOP_EXIST_offCP0EX 0
-#define FUCOP_EXIST_offCP1EX 1
-#define FUCOP_EXIST_offCP2EX 2
-#define FUCOP_EXIST_offCP3EX 3
-#define FUCOP_EXIST_offCP0ISFPU 31
-
-#define FUCOP_EXIST_mskCP0EX ( 0x1 << FUCOP_EXIST_offCP0EX )
-#define FUCOP_EXIST_mskCP1EX ( 0x1 << FUCOP_EXIST_offCP1EX )
-#define FUCOP_EXIST_mskCP2EX ( 0x1 << FUCOP_EXIST_offCP2EX )
-#define FUCOP_EXIST_mskCP3EX ( 0x1 << FUCOP_EXIST_offCP3EX )
-#define FUCOP_EXIST_mskCP0ISFPU ( 0x1 << FUCOP_EXIST_offCP0ISFPU )
-
-/******************************************************************************
- * ir0: PSW (Processor Status Word Register)
- * ir1: IPSW (Interruption PSW Register)
- * ir2: P_IPSW (Previous IPSW Register)
- *****************************************************************************/
-#define PSW_offGIE 0 /* Global Interrupt Enable */
-#define PSW_offINTL 1 /* Interruption Stack Level */
-#define PSW_offPOM 3 /* Processor Operation Mode, User/Superuser */
-#define PSW_offBE 5 /* Endianness for data memory access, 1:MSB, 0:LSB */
-#define PSW_offIT 6 /* Enable instruction address translation */
-#define PSW_offDT 7 /* Enable data address translation */
-#define PSW_offIME 8 /* Instruction Machine Error flag */
-#define PSW_offDME 9 /* Data Machine Error flag */
-#define PSW_offDEX 10 /* Debug Exception */
-#define PSW_offHSS 11 /* Hardware Single Stepping */
-#define PSW_offDRBE 12 /* Device Register Endian Mode */
-#define PSW_offAEN 13 /* Audio ISA special feature */
-#define PSW_offWBNA 14 /* Write Back Non-Allocate */
-#define PSW_offIFCON 15 /* IFC On */
-#define PSW_offCPL 16 /* Current Priority Level */
-/* bit 19:31 reserved */
-
-#define PSW_mskGIE ( 0x1 << PSW_offGIE )
-#define PSW_mskINTL ( 0x3 << PSW_offINTL )
-#define PSW_mskPOM ( 0x3 << PSW_offPOM )
-#define PSW_mskBE ( 0x1 << PSW_offBE )
-#define PSW_mskIT ( 0x1 << PSW_offIT )
-#define PSW_mskDT ( 0x1 << PSW_offDT )
-#define PSW_mskIME ( 0x1 << PSW_offIME )
-#define PSW_mskDME ( 0x1 << PSW_offDME )
-#define PSW_mskDEX ( 0x1 << PSW_offDEX )
-#define PSW_mskHSS ( 0x1 << PSW_offHSS )
-#define PSW_mskDRBE ( 0x1 << PSW_offDRBE )
-#define PSW_mskAEN ( 0x1 << PSW_offAEN )
-#define PSW_mskWBNA ( 0x1 << PSW_offWBNA )
-#define PSW_mskIFCON ( 0x1 << PSW_offIFCON )
-#define PSW_mskCPL ( 0x7 << PSW_offCPL )
-
-#define PSW_SYSTEM ( 1 << PSW_offPOM )
-#define PSW_INTL_1 ( 1 << PSW_offINTL )
-#define PSW_CPL_NO ( 0 << PSW_offCPL )
-#define PSW_CPL_ANY ( 7 << PSW_offCPL )
-
-#define PSW_clr (PSW_mskGIE|PSW_mskINTL|PSW_mskPOM|PSW_mskIT|PSW_mskDT|PSW_mskIME|PSW_mskWBNA)
-#ifdef __NDS32_EB__
-#ifdef CONFIG_WBNA
-#define PSW_init (PSW_mskWBNA|(1<<PSW_offINTL)|(1<<PSW_offPOM)|PSW_mskIT|PSW_mskDT|PSW_mskBE)
-#else
-#define PSW_init ((1<<PSW_offINTL)|(1<<PSW_offPOM)|PSW_mskIT|PSW_mskDT|PSW_mskBE)
-#endif
-#else
-#ifdef CONFIG_WBNA
-#define PSW_init (PSW_mskWBNA|(1<<PSW_offINTL)|(1<<PSW_offPOM)|PSW_mskIT|PSW_mskDT)
-#else
-#define PSW_init ((1<<PSW_offINTL)|(1<<PSW_offPOM)|PSW_mskIT|PSW_mskDT)
-#endif
-#endif
-/******************************************************************************
- * ir3: IVB (Interruption Vector Base Register)
- *****************************************************************************/
-/* bit 0:12 reserved */
-#define IVB_offNIVIC 1 /* Number of input for IVIC Controller */
-#define IVB_offIVIC_VER 11 /* IVIC Version */
-#define IVB_offEVIC 13 /* External Vector Interrupt Controller mode */
-#define IVB_offESZ 14 /* Size of each vector entry */
-#define IVB_offIVBASE 16 /* BasePA of interrupt vector table */
-
-#define IVB_mskNIVIC ( 0x7 << IVB_offNIVIC )
-#define IVB_mskIVIC_VER ( 0x3 << IVB_offIVIC_VER )
-#define IVB_mskEVIC ( 0x1 << IVB_offEVIC )
-#define IVB_mskESZ ( 0x3 << IVB_offESZ )
-#define IVB_mskIVBASE ( 0xFFFF << IVB_offIVBASE )
-
-#define IVB_valESZ4 0
-#define IVB_valESZ16 1
-#define IVB_valESZ64 2
-#define IVB_valESZ256 3
-/******************************************************************************
- * ir4: EVA (Exception Virtual Address Register)
- * ir5: P_EVA (Previous EVA Register)
- *****************************************************************************/
-
- /* This register contains the VA that causes the exception */
-
-/******************************************************************************
- * ir6: ITYPE (Interruption Type Register)
- * ir7: P_ITYPE (Previous ITYPE Register)
- *****************************************************************************/
-#define ITYPE_offETYPE 0 /* Exception Type */
-#define ITYPE_offINST 4 /* Exception caused by insn fetch or data access */
-/* bit 5:15 reserved */
-#define ITYPE_offVECTOR 5 /* Vector */
-#define ITYPE_offSWID 16 /* SWID of debugging exception */
-/* bit 31:31 reserved */
-
-#define ITYPE_mskETYPE ( 0xF << ITYPE_offETYPE )
-#define ITYPE_mskINST ( 0x1 << ITYPE_offINST )
-#define ITYPE_mskVECTOR ( 0x7F << ITYPE_offVECTOR )
-#define ITYPE_mskSWID ( 0x7FFF << ITYPE_offSWID )
-
-/* Additional definitions for ITYPE register */
-#define ITYPE_offSTYPE 16 /* Arithmetic Sub Type */
-#define ITYPE_offCPID 20 /* Co-Processor ID which generate the exception */
-
-#define ITYPE_mskSTYPE ( 0xF << ITYPE_offSTYPE )
-#define ITYPE_mskCPID ( 0x3 << ITYPE_offCPID )
-
-/* Additional definitions of ITYPE register for FPU */
-#define FPU_DISABLE_EXCEPTION (0x1 << ITYPE_offSTYPE)
-#define FPU_EXCEPTION (0x2 << ITYPE_offSTYPE)
-#define FPU_CPID 0 /* FPU Co-Processor ID is 0 */
-
-#define NDS32_VECTOR_mskNONEXCEPTION 0x78
-#define NDS32_VECTOR_offEXCEPTION 8
-#define NDS32_VECTOR_offINTERRUPT 9
-
-/* Interrupt vector entry */
-#define ENTRY_RESET_NMI 0
-#define ENTRY_TLB_FILL 1
-#define ENTRY_PTE_NOT_PRESENT 2
-#define ENTRY_TLB_MISC 3
-#define ENTRY_TLB_VLPT_MISS 4
-#define ENTRY_MACHINE_ERROR 5
-#define ENTRY_DEBUG_RELATED 6
-#define ENTRY_GENERAL_EXCPETION 7
-#define ENTRY_SYSCALL 8
-
-/* PTE not present exception definition */
-#define ETYPE_NON_LEAF_PTE_NOT_PRESENT 0
-#define ETYPE_LEAF_PTE_NOT_PRESENT 1
-
-/* General exception ETYPE definition */
-#define ETYPE_ALIGNMENT_CHECK 0
-#define ETYPE_RESERVED_INSTRUCTION 1
-#define ETYPE_TRAP 2
-#define ETYPE_ARITHMETIC 3
-#define ETYPE_PRECISE_BUS_ERROR 4
-#define ETYPE_IMPRECISE_BUS_ERROR 5
-#define ETYPE_COPROCESSOR 6
-#define ETYPE_RESERVED_VALUE 7
-#define ETYPE_NONEXISTENT_MEM_ADDRESS 8
-#define ETYPE_MPZIU_CONTROL 9
-#define ETYPE_NEXT_PRECISE_STACK_OFL 10
-
-/* Kerenl reserves software ID */
-#define SWID_RAISE_INTERRUPT_LEVEL 0x1a /* SWID_RAISE_INTERRUPT_LEVEL is used to
- * raise interrupt level for debug exception
- */
-
-/******************************************************************************
- * ir8: MERR (Machine Error Log Register)
- *****************************************************************************/
-/* bit 0:30 reserved */
-#define MERR_offBUSERR 31 /* Bus error caused by a load insn */
-
-#define MERR_mskBUSERR ( 0x1 << MERR_offBUSERR )
-
-/******************************************************************************
- * ir9: IPC (Interruption Program Counter Register)
- * ir10: P_IPC (Previous IPC Register)
- * ir11: OIPC (Overflow Interruption Program Counter Register)
- *****************************************************************************/
-
- /* This is the shadow stack register of the Program Counter */
-
-/******************************************************************************
- * ir12: P_P0 (Previous P0 Register)
- * ir13: P_P1 (Previous P1 Register)
- *****************************************************************************/
-
- /* These are shadow registers of $p0 and $p1 */
-
-/******************************************************************************
- * ir14: INT_MASK (Interruption Masking Register)
- *****************************************************************************/
-#define INT_MASK_offH0IM 0 /* Hardware Interrupt 0 Mask bit */
-#define INT_MASK_offH1IM 1 /* Hardware Interrupt 1 Mask bit */
-#define INT_MASK_offH2IM 2 /* Hardware Interrupt 2 Mask bit */
-#define INT_MASK_offH3IM 3 /* Hardware Interrupt 3 Mask bit */
-#define INT_MASK_offH4IM 4 /* Hardware Interrupt 4 Mask bit */
-#define INT_MASK_offH5IM 5 /* Hardware Interrupt 5 Mask bit */
-/* bit 6:15 reserved */
-#define INT_MASK_offSIM 16 /* Software Interrupt Mask bit */
-/* bit 17:29 reserved */
-#define INT_MASK_offIDIVZE 30 /* Enable detection for Divide-By-Zero */
-#define INT_MASK_offDSSIM 31 /* Default Single Stepping Interruption Mask */
-
-#define INT_MASK_mskH0IM ( 0x1 << INT_MASK_offH0IM )
-#define INT_MASK_mskH1IM ( 0x1 << INT_MASK_offH1IM )
-#define INT_MASK_mskH2IM ( 0x1 << INT_MASK_offH2IM )
-#define INT_MASK_mskH3IM ( 0x1 << INT_MASK_offH3IM )
-#define INT_MASK_mskH4IM ( 0x1 << INT_MASK_offH4IM )
-#define INT_MASK_mskH5IM ( 0x1 << INT_MASK_offH5IM )
-#define INT_MASK_mskSIM ( 0x1 << INT_MASK_offSIM )
-#define INT_MASK_mskIDIVZE ( 0x1 << INT_MASK_offIDIVZE )
-#define INT_MASK_mskDSSIM ( 0x1 << INT_MASK_offDSSIM )
-
-#define INT_MASK_INITAIAL_VAL (INT_MASK_mskDSSIM|INT_MASK_mskIDIVZE)
-
-/******************************************************************************
- * ir15: INT_PEND (Interrupt Pending Register)
- *****************************************************************************/
-#define INT_PEND_offH0I 0 /* Hardware Interrupt 0 pending bit */
-#define INT_PEND_offH1I 1 /* Hardware Interrupt 1 pending bit */
-#define INT_PEND_offH2I 2 /* Hardware Interrupt 2 pending bit */
-#define INT_PEND_offH3I 3 /* Hardware Interrupt 3 pending bit */
-#define INT_PEND_offH4I 4 /* Hardware Interrupt 4 pending bit */
-#define INT_PEND_offH5I 5 /* Hardware Interrupt 5 pending bit */
-
-#define INT_PEND_offCIPL 0 /* Current Interrupt Priority Level */
-
-/* bit 6:15 reserved */
-#define INT_PEND_offSWI 16 /* Software Interrupt pending bit */
-/* bit 17:31 reserved */
-
-#define INT_PEND_mskH0I ( 0x1 << INT_PEND_offH0I )
-#define INT_PEND_mskH1I ( 0x1 << INT_PEND_offH1I )
-#define INT_PEND_mskH2I ( 0x1 << INT_PEND_offH2I )
-#define INT_PEND_mskH3I ( 0x1 << INT_PEND_offH3I )
-#define INT_PEND_mskH4I ( 0x1 << INT_PEND_offH4I )
-#define INT_PEND_mskH5I ( 0x1 << INT_PEND_offH5I )
-#define INT_PEND_mskCIPL ( 0x1 << INT_PEND_offCIPL )
-#define INT_PEND_mskSWI ( 0x1 << INT_PEND_offSWI )
-
-/******************************************************************************
- * mr0: MMU_CTL (MMU Control Register)
- *****************************************************************************/
-#define MMU_CTL_offD 0 /* Default minimum page size */
-#define MMU_CTL_offNTC0 1 /* Non-Translated Cachebility of partition 0 */
-#define MMU_CTL_offNTC1 3 /* Non-Translated Cachebility of partition 1 */
-#define MMU_CTL_offNTC2 5 /* Non-Translated Cachebility of partition 2 */
-#define MMU_CTL_offNTC3 7 /* Non-Translated Cachebility of partition 3 */
-#define MMU_CTL_offTBALCK 9 /* TLB all-lock resolution scheme */
-#define MMU_CTL_offMPZIU 10 /* Multiple Page Size In Use bit */
-#define MMU_CTL_offNTM0 11 /* Non-Translated VA to PA of partition 0 */
-#define MMU_CTL_offNTM1 13 /* Non-Translated VA to PA of partition 1 */
-#define MMU_CTL_offNTM2 15 /* Non-Translated VA to PA of partition 2 */
-#define MMU_CTL_offNTM3 17 /* Non-Translated VA to PA of partition 3 */
-#define MMU_CTL_offUNA 23 /* Unaligned access */
-/* bit 24:31 reserved */
-
-#define MMU_CTL_mskD ( 0x1 << MMU_CTL_offD )
-#define MMU_CTL_mskNTC0 ( 0x3 << MMU_CTL_offNTC0 )
-#define MMU_CTL_mskNTC1 ( 0x3 << MMU_CTL_offNTC1 )
-#define MMU_CTL_mskNTC2 ( 0x3 << MMU_CTL_offNTC2 )
-#define MMU_CTL_mskNTC3 ( 0x3 << MMU_CTL_offNTC3 )
-#define MMU_CTL_mskTBALCK ( 0x1 << MMU_CTL_offTBALCK )
-#define MMU_CTL_mskMPZIU ( 0x1 << MMU_CTL_offMPZIU )
-#define MMU_CTL_mskNTM0 ( 0x3 << MMU_CTL_offNTM0 )
-#define MMU_CTL_mskNTM1 ( 0x3 << MMU_CTL_offNTM1 )
-#define MMU_CTL_mskNTM2 ( 0x3 << MMU_CTL_offNTM2 )
-#define MMU_CTL_mskNTM3 ( 0x3 << MMU_CTL_offNTM3 )
-
-#define MMU_CTL_D4KB 0
-#define MMU_CTL_D8KB 1
-#define MMU_CTL_UNA ( 0x1 << MMU_CTL_offUNA )
-
-#define MMU_CTL_CACHEABLE_NON 0
-#define MMU_CTL_CACHEABLE_WB 2
-#define MMU_CTL_CACHEABLE_WT 3
-
-/******************************************************************************
- * mr1: L1_PPTB (L1 Physical Page Table Base Register)
- *****************************************************************************/
-#define L1_PPTB_offNV 0 /* Enable Hardware Page Table Walker (HPTWK) */
-/* bit 1:11 reserved */
-#define L1_PPTB_offBASE 12 /* First level physical page table base address */
-
-#define L1_PPTB_mskNV ( 0x1 << L1_PPTB_offNV )
-#define L1_PPTB_mskBASE ( 0xFFFFF << L1_PPTB_offBASE )
-
-/******************************************************************************
- * mr2: TLB_VPN (TLB Access VPN Register)
- *****************************************************************************/
-/* bit 0:11 reserved */
-#define TLB_VPN_offVPN 12 /* Virtual Page Number */
-
-#define TLB_VPN_mskVPN ( 0xFFFFF << TLB_VPN_offVPN )
-
-/******************************************************************************
- * mr3: TLB_DATA (TLB Access Data Register)
- *****************************************************************************/
-#define TLB_DATA_offV 0 /* PTE is valid and present */
-#define TLB_DATA_offM 1 /* Page read/write access privilege */
-#define TLB_DATA_offD 4 /* Dirty bit */
-#define TLB_DATA_offX 5 /* Executable bit */
-#define TLB_DATA_offA 6 /* Access bit */
-#define TLB_DATA_offG 7 /* Global page (shared across contexts) */
-#define TLB_DATA_offC 8 /* Cacheability atribute */
-/* bit 11:11 reserved */
-#define TLB_DATA_offPPN 12 /* Phisical Page Number */
-
-#define TLB_DATA_mskV ( 0x1 << TLB_DATA_offV )
-#define TLB_DATA_mskM ( 0x7 << TLB_DATA_offM )
-#define TLB_DATA_mskD ( 0x1 << TLB_DATA_offD )
-#define TLB_DATA_mskX ( 0x1 << TLB_DATA_offX )
-#define TLB_DATA_mskA ( 0x1 << TLB_DATA_offA )
-#define TLB_DATA_mskG ( 0x1 << TLB_DATA_offG )
-#define TLB_DATA_mskC ( 0x7 << TLB_DATA_offC )
-#define TLB_DATA_mskPPN ( 0xFFFFF << TLB_DATA_offPPN )
-
-#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
-#define TLB_DATA_kernel_text_attr (TLB_DATA_mskV|TLB_DATA_mskM|TLB_DATA_mskD|TLB_DATA_mskX|TLB_DATA_mskG|TLB_DATA_mskC)
-#else
-#define TLB_DATA_kernel_text_attr (TLB_DATA_mskV|TLB_DATA_mskM|TLB_DATA_mskD|TLB_DATA_mskX|TLB_DATA_mskG|(0x6 << TLB_DATA_offC))
-#endif
-
-/******************************************************************************
- * mr4: TLB_MISC (TLB Access Misc Register)
- *****************************************************************************/
-#define TLB_MISC_offACC_PSZ 0 /* Page size of a PTE entry */
-#define TLB_MISC_offCID 4 /* Context id */
-/* bit 13:31 reserved */
-
-#define TLB_MISC_mskACC_PSZ ( 0xF << TLB_MISC_offACC_PSZ )
-#define TLB_MISC_mskCID ( 0x1FF << TLB_MISC_offCID )
-
-/******************************************************************************
- * mr5: VLPT_IDX (Virtual Linear Page Table Index Register)
- *****************************************************************************/
-#define VLPT_IDX_offZERO 0 /* Always 0 */
-#define VLPT_IDX_offEVPN 2 /* Exception Virtual Page Number */
-#define VLPT_IDX_offVLPTB 22 /* Base VA of VLPT */
-
-#define VLPT_IDX_mskZERO ( 0x3 << VLPT_IDX_offZERO )
-#define VLPT_IDX_mskEVPN ( 0xFFFFF << VLPT_IDX_offEVPN )
-#define VLPT_IDX_mskVLPTB ( 0x3FF << VLPT_IDX_offVLPTB )
-
-/******************************************************************************
- * mr6: ILMB (Instruction Local Memory Base Register)
- *****************************************************************************/
-#define ILMB_offIEN 0 /* Enable ILM */
-#define ILMB_offILMSZ 1 /* Size of ILM */
-/* bit 5:19 reserved */
-#define ILMB_offIBPA 20 /* Base PA of ILM */
-
-#define ILMB_mskIEN ( 0x1 << ILMB_offIEN )
-#define ILMB_mskILMSZ ( 0xF << ILMB_offILMSZ )
-#define ILMB_mskIBPA ( 0xFFF << ILMB_offIBPA )
-
-/******************************************************************************
- * mr7: DLMB (Data Local Memory Base Register)
- *****************************************************************************/
-#define DLMB_offDEN 0 /* Enable DLM */
-#define DLMB_offDLMSZ 1 /* Size of DLM */
-#define DLMB_offDBM 5 /* Enable Double-Buffer Mode for DLM */
-#define DLMB_offDBB 6 /* Double-buffer bank which can be accessed by the processor */
-/* bit 7:19 reserved */
-#define DLMB_offDBPA 20 /* Base PA of DLM */
-
-#define DLMB_mskDEN ( 0x1 << DLMB_offDEN )
-#define DLMB_mskDLMSZ ( 0xF << DLMB_offDLMSZ )
-#define DLMB_mskDBM ( 0x1 << DLMB_offDBM )
-#define DLMB_mskDBB ( 0x1 << DLMB_offDBB )
-#define DLMB_mskDBPA ( 0xFFF << DLMB_offDBPA )
-
-/******************************************************************************
- * mr8: CACHE_CTL (Cache Control Register)
- *****************************************************************************/
-#define CACHE_CTL_offIC_EN 0 /* Enable I-cache */
-#define CACHE_CTL_offDC_EN 1 /* Enable D-cache */
-#define CACHE_CTL_offICALCK 2 /* I-cache all-lock resolution scheme */
-#define CACHE_CTL_offDCALCK 3 /* D-cache all-lock resolution scheme */
-#define CACHE_CTL_offDCCWF 4 /* Enable D-cache Critical Word Forwarding */
-#define CACHE_CTL_offDCPMW 5 /* Enable D-cache concurrent miss and write-back processing */
-/* bit 6:31 reserved */
-
-#define CACHE_CTL_mskIC_EN ( 0x1 << CACHE_CTL_offIC_EN )
-#define CACHE_CTL_mskDC_EN ( 0x1 << CACHE_CTL_offDC_EN )
-#define CACHE_CTL_mskICALCK ( 0x1 << CACHE_CTL_offICALCK )
-#define CACHE_CTL_mskDCALCK ( 0x1 << CACHE_CTL_offDCALCK )
-#define CACHE_CTL_mskDCCWF ( 0x1 << CACHE_CTL_offDCCWF )
-#define CACHE_CTL_mskDCPMW ( 0x1 << CACHE_CTL_offDCPMW )
-
-/******************************************************************************
- * mr9: HSMP_SADDR (High Speed Memory Port Starting Address)
- *****************************************************************************/
-#define HSMP_SADDR_offEN 0 /* Enable control bit for the High Speed Memory port */
-/* bit 1:19 reserved */
-
-#define HSMP_SADDR_offRANGE 1 /* Denote the address range (only defined in HSMP v2 ) */
-#define HSMP_SADDR_offSADDR 20 /* Starting base PA of the High Speed Memory Port region */
-
-#define HSMP_SADDR_mskEN ( 0x1 << HSMP_SADDR_offEN )
-#define HSMP_SADDR_mskRANGE ( 0xFFF << HSMP_SADDR_offRANGE )
-#define HSMP_SADDR_mskSADDR ( 0xFFF << HSMP_SADDR_offSADDR )
-
-/******************************************************************************
- * mr10: HSMP_EADDR (High Speed Memory Port Ending Address)
- *****************************************************************************/
-/* bit 0:19 reserved */
-#define HSMP_EADDR_offEADDR 20
-
-#define HSMP_EADDR_mskEADDR ( 0xFFF << HSMP_EADDR_offEADDR )
-
-/******************************************************************************
- * dr0+(n*5): BPCn (n=0-7) (Breakpoint Control Register)
- *****************************************************************************/
-#define BPC_offWP 0 /* Configuration of BPAn */
-#define BPC_offEL 1 /* Enable BPAn */
-#define BPC_offS 2 /* Data address comparison for a store instruction */
-#define BPC_offP 3 /* Compared data address is PA */
-#define BPC_offC 4 /* CID value is compared with the BPCIDn register */
-#define BPC_offBE0 5 /* Enable byte mask for the comparison with register */
-#define BPC_offBE1 6 /* Enable byte mask for the comparison with register */
-#define BPC_offBE2 7 /* Enable byte mask for the comparison with register */
-#define BPC_offBE3 8 /* Enable byte mask for the comparison with register */
-#define BPC_offT 9 /* Enable breakpoint Embedded Tracer triggering operation */
-
-#define BPC_mskWP ( 0x1 << BPC_offWP )
-#define BPC_mskEL ( 0x1 << BPC_offEL )
-#define BPC_mskS ( 0x1 << BPC_offS )
-#define BPC_mskP ( 0x1 << BPC_offP )
-#define BPC_mskC ( 0x1 << BPC_offC )
-#define BPC_mskBE0 ( 0x1 << BPC_offBE0 )
-#define BPC_mskBE1 ( 0x1 << BPC_offBE1 )
-#define BPC_mskBE2 ( 0x1 << BPC_offBE2 )
-#define BPC_mskBE3 ( 0x1 << BPC_offBE3 )
-#define BPC_mskT ( 0x1 << BPC_offT )
-
-/******************************************************************************
- * dr1+(n*5): BPAn (n=0-7) (Breakpoint Address Register)
- *****************************************************************************/
-
- /* These registers contain break point address */
-
-/******************************************************************************
- * dr2+(n*5): BPAMn (n=0-7) (Breakpoint Address Mask Register)
- *****************************************************************************/
-
- /* These registerd contain the address comparison mask for the BPAn register */
-
-/******************************************************************************
- * dr3+(n*5): BPVn (n=0-7) Breakpoint Data Value Register
- *****************************************************************************/
-
- /* The BPVn register contains the data value that will be compared with the
- * incoming load/store data value */
-
-/******************************************************************************
- * dr4+(n*5): BPCIDn (n=0-7) (Breakpoint Context ID Register)
- *****************************************************************************/
-#define BPCID_offCID 0 /* CID that will be compared with a process's CID */
-/* bit 9:31 reserved */
-
-#define BPCID_mskCID ( 0x1FF << BPCID_offCID )
-
-/******************************************************************************
- * dr40: EDM_CFG (EDM Configuration Register)
- *****************************************************************************/
-#define EDM_CFG_offBC 0 /* Number of hardware breakpoint sets implemented */
-#define EDM_CFG_offDIMU 3 /* Debug Instruction Memory Unit exists */
-/* bit 4:15 reserved */
-#define EDM_CFG_offVER 16 /* EDM version */
-
-#define EDM_CFG_mskBC ( 0x7 << EDM_CFG_offBC )
-#define EDM_CFG_mskDIMU ( 0x1 << EDM_CFG_offDIMU )
-#define EDM_CFG_mskVER ( 0xFFFF << EDM_CFG_offVER )
-
-/******************************************************************************
- * dr41: EDMSW (EDM Status Word)
- *****************************************************************************/
-#define EDMSW_offWV 0 /* Write Valid */
-#define EDMSW_offRV 1 /* Read Valid */
-#define EDMSW_offDE 2 /* Debug exception has occurred for this core */
-/* bit 3:31 reserved */
-
-#define EDMSW_mskWV ( 0x1 << EDMSW_offWV )
-#define EDMSW_mskRV ( 0x1 << EDMSW_offRV )
-#define EDMSW_mskDE ( 0x1 << EDMSW_offDE )
-
-/******************************************************************************
- * dr42: EDM_CTL (EDM Control Register)
- *****************************************************************************/
-/* bit 0:30 reserved */
-#define EDM_CTL_offV3_EDM_MODE 6 /* EDM compatibility control bit */
-#define EDM_CTL_offDEH_SEL 31 /* Controls where debug exception is directed to */
-
-#define EDM_CTL_mskV3_EDM_MODE ( 0x1 << EDM_CTL_offV3_EDM_MODE )
-#define EDM_CTL_mskDEH_SEL ( 0x1 << EDM_CTL_offDEH_SEL )
-
-/******************************************************************************
- * dr43: EDM_DTR (EDM Data Transfer Register)
- *****************************************************************************/
-
- /* This is used to exchange data between the embedded EDM logic
- * and the processor core */
-
-/******************************************************************************
- * dr44: BPMTC (Breakpoint Match Trigger Counter Register)
- *****************************************************************************/
-#define BPMTC_offBPMTC 0 /* Breakpoint match trigger counter value */
-/* bit 16:31 reserved */
-
-#define BPMTC_mskBPMTC ( 0xFFFF << BPMTC_offBPMTC )
-
-/******************************************************************************
- * dr45: DIMBR (Debug Instruction Memory Base Register)
- *****************************************************************************/
-/* bit 0:11 reserved */
-#define DIMBR_offDIMB 12 /* Base address of the Debug Instruction Memory (DIM) */
-#define DIMBR_mskDIMB ( 0xFFFFF << DIMBR_offDIMB )
-
-/******************************************************************************
- * dr46: TECR0(Trigger Event Control register 0)
- * dr47: TECR1 (Trigger Event Control register 1)
- *****************************************************************************/
-#define TECR_offBP 0 /* Controld which BP is used as a trigger source */
-#define TECR_offNMI 8 /* Use NMI as a trigger source */
-#define TECR_offHWINT 9 /* Corresponding interrupt is used as a trigger source */
-#define TECR_offEVIC 15 /* Enable HWINT as a trigger source in EVIC mode */
-#define TECR_offSYS 16 /* Enable SYSCALL instruction as a trigger source */
-#define TECR_offDBG 17 /* Enable debug exception as a trigger source */
-#define TECR_offMRE 18 /* Enable MMU related exception as a trigger source */
-#define TECR_offE 19 /* An exception is used as a trigger source */
-/* bit 20:30 reserved */
-#define TECR_offL 31 /* Link/Cascade TECR0 trigger event to TECR1 trigger event */
-
-#define TECR_mskBP ( 0xFF << TECR_offBP )
-#define TECR_mskNMI ( 0x1 << TECR_offBNMI )
-#define TECR_mskHWINT ( 0x3F << TECR_offBHWINT )
-#define TECR_mskEVIC ( 0x1 << TECR_offBEVIC )
-#define TECR_mskSYS ( 0x1 << TECR_offBSYS )
-#define TECR_mskDBG ( 0x1 << TECR_offBDBG )
-#define TECR_mskMRE ( 0x1 << TECR_offBMRE )
-#define TECR_mskE ( 0x1 << TECR_offE )
-#define TECR_mskL ( 0x1 << TECR_offL )
-
-/******************************************************************************
- * pfr0-2: PFMC0-2 (Performance Counter Register 0-2)
- *****************************************************************************/
-
- /* These registers contains performance event count */
-
-/******************************************************************************
- * pfr3: PFM_CTL (Performance Counter Control Register)
- *****************************************************************************/
-#define PFM_CTL_offEN0 0 /* Enable PFMC0 */
-#define PFM_CTL_offEN1 1 /* Enable PFMC1 */
-#define PFM_CTL_offEN2 2 /* Enable PFMC2 */
-#define PFM_CTL_offIE0 3 /* Enable interrupt for PFMC0 */
-#define PFM_CTL_offIE1 4 /* Enable interrupt for PFMC1 */
-#define PFM_CTL_offIE2 5 /* Enable interrupt for PFMC2 */
-#define PFM_CTL_offOVF0 6 /* Overflow bit of PFMC0 */
-#define PFM_CTL_offOVF1 7 /* Overflow bit of PFMC1 */
-#define PFM_CTL_offOVF2 8 /* Overflow bit of PFMC2 */
-#define PFM_CTL_offKS0 9 /* Enable superuser mode event counting for PFMC0 */
-#define PFM_CTL_offKS1 10 /* Enable superuser mode event counting for PFMC1 */
-#define PFM_CTL_offKS2 11 /* Enable superuser mode event counting for PFMC2 */
-#define PFM_CTL_offKU0 12 /* Enable user mode event counting for PFMC0 */
-#define PFM_CTL_offKU1 13 /* Enable user mode event counting for PFMC1 */
-#define PFM_CTL_offKU2 14 /* Enable user mode event counting for PFMC2 */
-#define PFM_CTL_offSEL0 15 /* The event selection for PFMC0 */
-#define PFM_CTL_offSEL1 16 /* The event selection for PFMC1 */
-#define PFM_CTL_offSEL2 22 /* The event selection for PFMC2 */
-/* bit 28:31 reserved */
-
-#define PFM_CTL_mskEN0 ( 0x01 << PFM_CTL_offEN0 )
-#define PFM_CTL_mskEN1 ( 0x01 << PFM_CTL_offEN1 )
-#define PFM_CTL_mskEN2 ( 0x01 << PFM_CTL_offEN2 )
-#define PFM_CTL_mskIE0 ( 0x01 << PFM_CTL_offIE0 )
-#define PFM_CTL_mskIE1 ( 0x01 << PFM_CTL_offIE1 )
-#define PFM_CTL_mskIE2 ( 0x01 << PFM_CTL_offIE2 )
-#define PFM_CTL_mskOVF0 ( 0x01 << PFM_CTL_offOVF0 )
-#define PFM_CTL_mskOVF1 ( 0x01 << PFM_CTL_offOVF1 )
-#define PFM_CTL_mskOVF2 ( 0x01 << PFM_CTL_offOVF2 )
-#define PFM_CTL_mskKS0 ( 0x01 << PFM_CTL_offKS0 )
-#define PFM_CTL_mskKS1 ( 0x01 << PFM_CTL_offKS1 )
-#define PFM_CTL_mskKS2 ( 0x01 << PFM_CTL_offKS2 )
-#define PFM_CTL_mskKU0 ( 0x01 << PFM_CTL_offKU0 )
-#define PFM_CTL_mskKU1 ( 0x01 << PFM_CTL_offKU1 )
-#define PFM_CTL_mskKU2 ( 0x01 << PFM_CTL_offKU2 )
-#define PFM_CTL_mskSEL0 ( 0x01 << PFM_CTL_offSEL0 )
-#define PFM_CTL_mskSEL1 ( 0x3F << PFM_CTL_offSEL1 )
-#define PFM_CTL_mskSEL2 ( 0x3F << PFM_CTL_offSEL2 )
-
-/******************************************************************************
- * SDZ_CTL (Structure Downsizing Control Register)
- *****************************************************************************/
-#define SDZ_CTL_offICDZ 0 /* I-cache downsizing control */
-#define SDZ_CTL_offDCDZ 3 /* D-cache downsizing control */
-#define SDZ_CTL_offMTBDZ 6 /* MTLB downsizing control */
-#define SDZ_CTL_offBTBDZ 9 /* Branch Target Table downsizing control */
-/* bit 12:31 reserved */
-#define SDZ_CTL_mskICDZ ( 0x07 << SDZ_CTL_offICDZ )
-#define SDZ_CTL_mskDCDZ ( 0x07 << SDZ_CTL_offDCDZ )
-#define SDZ_CTL_mskMTBDZ ( 0x07 << SDZ_CTL_offMTBDZ )
-#define SDZ_CTL_mskBTBDZ ( 0x07 << SDZ_CTL_offBTBDZ )
-
-/******************************************************************************
- * N13MISC_CTL (N13 Miscellaneous Control Register)
- *****************************************************************************/
-#define N13MISC_CTL_offBTB 0 /* Disable Branch Target Buffer */
-#define N13MISC_CTL_offRTP 1 /* Disable Return Target Predictor */
-#define N13MISC_CTL_offPTEPF 2 /* Disable HPTWK L2 PTE pefetch */
-#define N13MISC_CTL_offSP_SHADOW_EN 4 /* Enable shadow stack pointers */
-#define MISC_CTL_offHWPRE 11 /* Enable HardWare PREFETCH */
-/* bit 6, 9:31 reserved */
-
-#define N13MISC_CTL_makBTB ( 0x1 << N13MISC_CTL_offBTB )
-#define N13MISC_CTL_makRTP ( 0x1 << N13MISC_CTL_offRTP )
-#define N13MISC_CTL_makPTEPF ( 0x1 << N13MISC_CTL_offPTEPF )
-#define N13MISC_CTL_makSP_SHADOW_EN ( 0x1 << N13MISC_CTL_offSP_SHADOW_EN )
-#define MISC_CTL_makHWPRE_EN ( 0x1 << MISC_CTL_offHWPRE )
-
-#ifdef CONFIG_HW_PRE
-#define MISC_init (N13MISC_CTL_makBTB|N13MISC_CTL_makRTP|N13MISC_CTL_makSP_SHADOW_EN|MISC_CTL_makHWPRE_EN)
-#else
-#define MISC_init (N13MISC_CTL_makBTB|N13MISC_CTL_makRTP|N13MISC_CTL_makSP_SHADOW_EN)
-#endif
-
-/******************************************************************************
- * PRUSR_ACC_CTL (Privileged Resource User Access Control Registers)
- *****************************************************************************/
-#define PRUSR_ACC_CTL_offDMA_EN 0 /* Allow user mode access of DMA registers */
-#define PRUSR_ACC_CTL_offPFM_EN 1 /* Allow user mode access of PFM registers */
-
-#define PRUSR_ACC_CTL_mskDMA_EN ( 0x1 << PRUSR_ACC_CTL_offDMA_EN )
-#define PRUSR_ACC_CTL_mskPFM_EN ( 0x1 << PRUSR_ACC_CTL_offPFM_EN )
-
-/******************************************************************************
- * dmar0: DMA_CFG (DMA Configuration Register)
- *****************************************************************************/
-#define DMA_CFG_offNCHN 0 /* The number of DMA channels implemented */
-#define DMA_CFG_offUNEA 2 /* Un-aligned External Address transfer feature */
-#define DMA_CFG_off2DET 3 /* 2-D Element Transfer feature */
-/* bit 4:15 reserved */
-#define DMA_CFG_offVER 16 /* DMA architecture and implementation version */
-
-#define DMA_CFG_mskNCHN ( 0x3 << DMA_CFG_offNCHN )
-#define DMA_CFG_mskUNEA ( 0x1 << DMA_CFG_offUNEA )
-#define DMA_CFG_msk2DET ( 0x1 << DMA_CFG_off2DET )
-#define DMA_CFG_mskVER ( 0xFFFF << DMA_CFG_offVER )
-
-/******************************************************************************
- * dmar1: DMA_GCSW (DMA Global Control and Status Word Register)
- *****************************************************************************/
-#define DMA_GCSW_offC0STAT 0 /* DMA channel 0 state */
-#define DMA_GCSW_offC1STAT 3 /* DMA channel 1 state */
-/* bit 6:11 reserved */
-#define DMA_GCSW_offC0INT 12 /* DMA channel 0 generate interrupt */
-#define DMA_GCSW_offC1INT 13 /* DMA channel 1 generate interrupt */
-/* bit 14:30 reserved */
-#define DMA_GCSW_offEN 31 /* Enable DMA engine */
-
-#define DMA_GCSW_mskC0STAT ( 0x7 << DMA_GCSW_offC0STAT )
-#define DMA_GCSW_mskC1STAT ( 0x7 << DMA_GCSW_offC1STAT )
-#define DMA_GCSW_mskC0INT ( 0x1 << DMA_GCSW_offC0INT )
-#define DMA_GCSW_mskC1INT ( 0x1 << DMA_GCSW_offC1INT )
-#define DMA_GCSW_mskEN ( 0x1 << DMA_GCSW_offEN )
-
-/******************************************************************************
- * dmar2: DMA_CHNSEL (DMA Channel Selection Register)
- *****************************************************************************/
-#define DMA_CHNSEL_offCHAN 0 /* Selected channel number */
-/* bit 2:31 reserved */
-
-#define DMA_CHNSEL_mskCHAN ( 0x3 << DMA_CHNSEL_offCHAN )
-
-/******************************************************************************
- * dmar3: DMA_ACT (DMA Action Register)
- *****************************************************************************/
-#define DMA_ACT_offACMD 0 /* DMA Action Command */
-/* bit 2:31 reserved */
-#define DMA_ACT_mskACMD ( 0x3 << DMA_ACT_offACMD )
-
-/******************************************************************************
- * dmar4: DMA_SETUP (DMA Setup Register)
- *****************************************************************************/
-#define DMA_SETUP_offLM 0 /* Local Memory Selection */
-#define DMA_SETUP_offTDIR 1 /* Transfer Direction */
-#define DMA_SETUP_offTES 2 /* Transfer Element Size */
-#define DMA_SETUP_offESTR 4 /* External memory transfer Stride */
-#define DMA_SETUP_offCIE 16 /* Interrupt Enable on Completion */
-#define DMA_SETUP_offSIE 17 /* Interrupt Enable on explicit Stop */
-#define DMA_SETUP_offEIE 18 /* Interrupt Enable on Error */
-#define DMA_SETUP_offUE 19 /* Enable the Un-aligned External Address */
-#define DMA_SETUP_off2DE 20 /* Enable the 2-D External Transfer */
-#define DMA_SETUP_offCOA 21 /* Transfer Coalescable */
-/* bit 22:31 reserved */
-
-#define DMA_SETUP_mskLM ( 0x1 << DMA_SETUP_offLM )
-#define DMA_SETUP_mskTDIR ( 0x1 << DMA_SETUP_offTDIR )
-#define DMA_SETUP_mskTES ( 0x3 << DMA_SETUP_offTES )
-#define DMA_SETUP_mskESTR ( 0xFFF << DMA_SETUP_offESTR )
-#define DMA_SETUP_mskCIE ( 0x1 << DMA_SETUP_offCIE )
-#define DMA_SETUP_mskSIE ( 0x1 << DMA_SETUP_offSIE )
-#define DMA_SETUP_mskEIE ( 0x1 << DMA_SETUP_offEIE )
-#define DMA_SETUP_mskUE ( 0x1 << DMA_SETUP_offUE )
-#define DMA_SETUP_msk2DE ( 0x1 << DMA_SETUP_off2DE )
-#define DMA_SETUP_mskCOA ( 0x1 << DMA_SETUP_offCOA )
-
-/******************************************************************************
- * dmar5: DMA_ISADDR (DMA Internal Start Address Register)
- *****************************************************************************/
-#define DMA_ISADDR_offISADDR 0 /* Internal Start Address */
-/* bit 20:31 reserved */
-#define DMA_ISADDR_mskISADDR ( 0xFFFFF << DMA_ISADDR_offISADDR )
-
-/******************************************************************************
- * dmar6: DMA_ESADDR (DMA External Start Address Register)
- *****************************************************************************/
-/* This register holds External Start Address */
-
-/******************************************************************************
- * dmar7: DMA_TCNT (DMA Transfer Element Count Register)
- *****************************************************************************/
-#define DMA_TCNT_offTCNT 0 /* DMA transfer element count */
-/* bit 18:31 reserved */
-#define DMA_TCNT_mskTCNT ( 0x3FFFF << DMA_TCNT_offTCNT )
-
-/******************************************************************************
- * dmar8: DMA_STATUS (DMA Status Register)
- *****************************************************************************/
-#define DMA_STATUS_offSTAT 0 /* DMA channel state */
-#define DMA_STATUS_offSTUNA 3 /* Un-aligned error on External Stride value */
-#define DMA_STATUS_offDERR 4 /* DMA Transfer Disruption Error */
-#define DMA_STATUS_offEUNA 5 /* Un-aligned error on the External address */
-#define DMA_STATUS_offIUNA 6 /* Un-aligned error on the Internal address */
-#define DMA_STATUS_offIOOR 7 /* Out-Of-Range error on the Internal address */
-#define DMA_STATUS_offEBUS 8 /* Bus Error on an External DMA transfer */
-#define DMA_STATUS_offESUP 9 /* DMA setup error */
-/* bit 10:31 reserved */
-
-#define DMA_STATUS_mskSTAT ( 0x7 << DMA_STATUS_offSTAT )
-#define DMA_STATUS_mskSTUNA ( 0x1 << DMDMA_STATUS_offSTUNA )
-#define DMA_STATUS_mskDERR ( 0x1 << DMDMA_STATUS_offDERR )
-#define DMA_STATUS_mskEUNA ( 0x1 << DMDMA_STATUS_offEUNA )
-#define DMA_STATUS_mskIUNA ( 0x1 << DMDMA_STATUS_offIUNA )
-#define DMA_STATUS_mskIOOR ( 0x1 << DMDMA_STATUS_offIOOR )
-#define DMA_STATUS_mskEBUS ( 0x1 << DMDMA_STATUS_offEBUS )
-#define DMA_STATUS_mskESUP ( 0x1 << DMDMA_STATUS_offESUP )
-
-/******************************************************************************
- * dmar9: DMA_2DSET (DMA 2D Setup Register)
- *****************************************************************************/
-#define DMA_2DSET_offWECNT 0 /* The Width Element Count for a 2-D region */
-#define DMA_2DSET_offHTSTR 16 /* The Height Stride for a 2-D region */
-
-#define DMA_2DSET_mskHTSTR ( 0xFFFF << DMA_2DSET_offHTSTR )
-#define DMA_2DSET_mskWECNT ( 0xFFFF << DMA_2DSET_offWECNT )
-
-/******************************************************************************
- * dmar10: DMA_2DSCTL (DMA 2D Startup Control Register)
- *****************************************************************************/
-#define DMA_2DSCTL_offSTWECNT 0 /* Startup Width Element Count for a 2-D region */
-/* bit 16:31 reserved */
-
-#define DMA_2DSCTL_mskSTWECNT ( 0xFFFF << DMA_2DSCTL_offSTWECNT )
-
-/******************************************************************************
- * fpcsr: FPCSR (Floating-Point Control Status Register)
- *****************************************************************************/
-#define FPCSR_offRM 0
-#define FPCSR_offIVO 2
-#define FPCSR_offDBZ 3
-#define FPCSR_offOVF 4
-#define FPCSR_offUDF 5
-#define FPCSR_offIEX 6
-#define FPCSR_offIVOE 7
-#define FPCSR_offDBZE 8
-#define FPCSR_offOVFE 9
-#define FPCSR_offUDFE 10
-#define FPCSR_offIEXE 11
-#define FPCSR_offDNZ 12
-#define FPCSR_offIVOT 13
-#define FPCSR_offDBZT 14
-#define FPCSR_offOVFT 15
-#define FPCSR_offUDFT 16
-#define FPCSR_offIEXT 17
-#define FPCSR_offDNIT 18
-#define FPCSR_offRIT 19
-
-#define FPCSR_mskRM ( 0x3 << FPCSR_offRM )
-#define FPCSR_mskIVO ( 0x1 << FPCSR_offIVO )
-#define FPCSR_mskDBZ ( 0x1 << FPCSR_offDBZ )
-#define FPCSR_mskOVF ( 0x1 << FPCSR_offOVF )
-#define FPCSR_mskUDF ( 0x1 << FPCSR_offUDF )
-#define FPCSR_mskIEX ( 0x1 << FPCSR_offIEX )
-#define FPCSR_mskIVOE ( 0x1 << FPCSR_offIVOE )
-#define FPCSR_mskDBZE ( 0x1 << FPCSR_offDBZE )
-#define FPCSR_mskOVFE ( 0x1 << FPCSR_offOVFE )
-#define FPCSR_mskUDFE ( 0x1 << FPCSR_offUDFE )
-#define FPCSR_mskIEXE ( 0x1 << FPCSR_offIEXE )
-#define FPCSR_mskDNZ ( 0x1 << FPCSR_offDNZ )
-#define FPCSR_mskIVOT ( 0x1 << FPCSR_offIVOT )
-#define FPCSR_mskDBZT ( 0x1 << FPCSR_offDBZT )
-#define FPCSR_mskOVFT ( 0x1 << FPCSR_offOVFT )
-#define FPCSR_mskUDFT ( 0x1 << FPCSR_offUDFT )
-#define FPCSR_mskIEXT ( 0x1 << FPCSR_offIEXT )
-#define FPCSR_mskDNIT ( 0x1 << FPCSR_offDNIT )
-#define FPCSR_mskRIT ( 0x1 << FPCSR_offRIT )
-#define FPCSR_mskALL (FPCSR_mskIVO | FPCSR_mskDBZ | FPCSR_mskOVF | FPCSR_mskUDF | FPCSR_mskIEX)
-#define FPCSR_mskALLE_NO_UDF_IEXE (FPCSR_mskIVOE | FPCSR_mskDBZE | FPCSR_mskOVFE)
-#define FPCSR_mskALLE (FPCSR_mskIVOE | FPCSR_mskDBZE | FPCSR_mskOVFE | FPCSR_mskUDFE | FPCSR_mskIEXE)
-#define FPCSR_mskALLT (FPCSR_mskIVOT | FPCSR_mskDBZT | FPCSR_mskOVFT | FPCSR_mskUDFT | FPCSR_mskIEXT |FPCSR_mskDNIT | FPCSR_mskRIT)
-
-/******************************************************************************
- * fpcfg: FPCFG (Floating-Point Configuration Register)
- *****************************************************************************/
-#define FPCFG_offSP 0
-#define FPCFG_offDP 1
-#define FPCFG_offFREG 2
-#define FPCFG_offFMA 4
-#define FPCFG_offIMVER 22
-#define FPCFG_offAVER 27
-
-#define FPCFG_mskSP ( 0x1 << FPCFG_offSP )
-#define FPCFG_mskDP ( 0x1 << FPCFG_offDP )
-#define FPCFG_mskFREG ( 0x3 << FPCFG_offFREG )
-#define FPCFG_mskFMA ( 0x1 << FPCFG_offFMA )
-#define FPCFG_mskIMVER ( 0x1F << FPCFG_offIMVER )
-#define FPCFG_mskAVER ( 0x1F << FPCFG_offAVER )
-
-/* 8 Single precision or 4 double precision registers are available */
-#define SP8_DP4_reg 0
-/* 16 Single precision or 8 double precision registers are available */
-#define SP16_DP8_reg 1
-/* 32 Single precision or 16 double precision registers are available */
-#define SP32_DP16_reg 2
-/* 32 Single precision or 32 double precision registers are available */
-#define SP32_DP32_reg 3
-
-/******************************************************************************
- * fucpr: FUCOP_CTL (FPU and Coprocessor Enable Control Register)
- *****************************************************************************/
-#define FUCOP_CTL_offCP0EN 0
-#define FUCOP_CTL_offCP1EN 1
-#define FUCOP_CTL_offCP2EN 2
-#define FUCOP_CTL_offCP3EN 3
-#define FUCOP_CTL_offAUEN 31
-
-#define FUCOP_CTL_mskCP0EN ( 0x1 << FUCOP_CTL_offCP0EN )
-#define FUCOP_CTL_mskCP1EN ( 0x1 << FUCOP_CTL_offCP1EN )
-#define FUCOP_CTL_mskCP2EN ( 0x1 << FUCOP_CTL_offCP2EN )
-#define FUCOP_CTL_mskCP3EN ( 0x1 << FUCOP_CTL_offCP3EN )
-#define FUCOP_CTL_mskAUEN ( 0x1 << FUCOP_CTL_offAUEN )
-
-#endif /* __NDS32_BITFIELD_H__ */
diff --git a/arch/nds32/include/asm/cache.h b/arch/nds32/include/asm/cache.h
deleted file mode 100644
index fc3c41b59169..000000000000
--- a/arch/nds32/include/asm/cache.h
+++ /dev/null
@@ -1,12 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-// Copyright (C) 2005-2017 Andes Technology Corporation
-
-#ifndef __NDS32_CACHE_H__
-#define __NDS32_CACHE_H__
-
-#define L1_CACHE_BYTES 32
-#define L1_CACHE_SHIFT 5
-
-#define ARCH_DMA_MINALIGN L1_CACHE_BYTES
-
-#endif /* __NDS32_CACHE_H__ */
diff --git a/arch/nds32/include/asm/cache_info.h b/arch/nds32/include/asm/cache_info.h
deleted file mode 100644
index e89d8078f3a6..000000000000
--- a/arch/nds32/include/asm/cache_info.h
+++ /dev/null
@@ -1,13 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-// Copyright (C) 2005-2017 Andes Technology Corporation
-
-struct cache_info {
- unsigned char ways;
- unsigned char line_size;
- unsigned short sets;
- unsigned short size;
-#if defined(CONFIG_CPU_CACHE_ALIASING)
- unsigned short aliasing_num;
- unsigned int aliasing_mask;
-#endif
-};
diff --git a/arch/nds32/include/asm/cacheflush.h b/arch/nds32/include/asm/cacheflush.h
deleted file mode 100644
index c2a222ebfa2a..000000000000
--- a/arch/nds32/include/asm/cacheflush.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-// Copyright (C) 2005-2017 Andes Technology Corporation
-
-#ifndef __NDS32_CACHEFLUSH_H__
-#define __NDS32_CACHEFLUSH_H__
-
-#include <linux/mm.h>
-
-#define PG_dcache_dirty PG_arch_1
-
-void flush_icache_range(unsigned long start, unsigned long end);
-#define flush_icache_range flush_icache_range
-
-void flush_icache_page(struct vm_area_struct *vma, struct page *page);
-#define flush_icache_page flush_icache_page
-
-#ifdef CONFIG_CPU_CACHE_ALIASING
-void flush_cache_mm(struct mm_struct *mm);
-void flush_cache_dup_mm(struct mm_struct *mm);
-void flush_cache_range(struct vm_area_struct *vma,
- unsigned long start, unsigned long end);
-void flush_cache_page(struct vm_area_struct *vma,
- unsigned long addr, unsigned long pfn);
-void flush_cache_kmaps(void);
-void flush_cache_vmap(unsigned long start, unsigned long end);
-void flush_cache_vunmap(unsigned long start, unsigned long end);
-
-#define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 1
-void flush_dcache_page(struct page *page);
-void copy_to_user_page(struct vm_area_struct *vma, struct page *page,
- unsigned long vaddr, void *dst, void *src, int len);
-void copy_from_user_page(struct vm_area_struct *vma, struct page *page,
- unsigned long vaddr, void *dst, void *src, int len);
-
-#define ARCH_HAS_FLUSH_ANON_PAGE
-void flush_anon_page(struct vm_area_struct *vma,
- struct page *page, unsigned long vaddr);
-
-#define ARCH_IMPLEMENTS_FLUSH_KERNEL_VMAP_RANGE 1
-void flush_kernel_vmap_range(void *addr, int size);
-void invalidate_kernel_vmap_range(void *addr, int size);
-#define flush_dcache_mmap_lock(mapping) xa_lock_irq(&(mapping)->i_pages)
-#define flush_dcache_mmap_unlock(mapping) xa_unlock_irq(&(mapping)->i_pages)
-
-#else
-void flush_icache_user_page(struct vm_area_struct *vma, struct page *page,
- unsigned long addr, int len);
-#define flush_icache_user_page flush_icache_user_page
-
-#include <asm-generic/cacheflush.h>
-#endif
-
-#endif /* __NDS32_CACHEFLUSH_H__ */
diff --git a/arch/nds32/include/asm/current.h b/arch/nds32/include/asm/current.h
deleted file mode 100644
index 65d30096142b..000000000000
--- a/arch/nds32/include/asm/current.h
+++ /dev/null
@@ -1,12 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-// Copyright (C) 2005-2017 Andes Technology Corporation
-
-#ifndef _ASM_NDS32_CURRENT_H
-#define _ASM_NDS32_CURRENT_H
-
-#ifndef __ASSEMBLY__
-register struct task_struct *current asm("$r25");
-#endif /* __ASSEMBLY__ */
-#define tsk $r25
-
-#endif /* _ASM_NDS32_CURRENT_H */
diff --git a/arch/nds32/include/asm/delay.h b/arch/nds32/include/asm/delay.h
deleted file mode 100644
index 56ea3894f8f8..000000000000
--- a/arch/nds32/include/asm/delay.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-// Copyright (C) 2005-2017 Andes Technology Corporation
-
-#ifndef __NDS32_DELAY_H__
-#define __NDS32_DELAY_H__
-
-#include <asm/param.h>
-
-/* There is no clocksource cycle counter in the CPU. */
-static inline void __delay(unsigned long loops)
-{
- __asm__ __volatile__(".align 2\n"
- "1:\n"
- "\taddi\t%0, %0, -1\n"
- "\tbgtz\t%0, 1b\n"
- :"=r"(loops)
- :"0"(loops));
-}
-
-static inline void __udelay(unsigned long usecs, unsigned long lpj)
-{
- usecs *= (unsigned long)(((0x8000000000000000ULL / (500000 / HZ)) +
- 0x80000000ULL) >> 32);
- usecs = (unsigned long)(((unsigned long long)usecs * lpj) >> 32);
- __delay(usecs);
-}
-
-#define udelay(usecs) __udelay((usecs), loops_per_jiffy)
-
-/* make sure "usecs *= ..." in udelay do not overflow. */
-#if HZ >= 1000
-#define MAX_UDELAY_MS 1
-#elif HZ <= 200
-#define MAX_UDELAY_MS 5
-#else
-#define MAX_UDELAY_MS (1000 / HZ)
-#endif
-
-#endif
diff --git a/arch/nds32/include/asm/elf.h b/arch/nds32/include/asm/elf.h
deleted file mode 100644
index 1853dc89b8ac..000000000000
--- a/arch/nds32/include/asm/elf.h
+++ /dev/null
@@ -1,180 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-// Copyright (C) 2005-2017 Andes Technology Corporation
-
-#ifndef __ASMNDS32_ELF_H
-#define __ASMNDS32_ELF_H
-
-/*
- * ELF register definitions..
- */
-
-#include <asm/ptrace.h>
-#include <asm/fpu.h>
-#include <linux/elf-em.h>
-
-typedef unsigned long elf_greg_t;
-typedef unsigned long elf_freg_t[3];
-
-extern unsigned int elf_hwcap;
-
-#define R_NDS32_NONE 0
-#define R_NDS32_16_RELA 19
-#define R_NDS32_32_RELA 20
-#define R_NDS32_9_PCREL_RELA 22
-#define R_NDS32_15_PCREL_RELA 23
-#define R_NDS32_17_PCREL_RELA 24
-#define R_NDS32_25_PCREL_RELA 25
-#define R_NDS32_HI20_RELA 26
-#define R_NDS32_LO12S3_RELA 27
-#define R_NDS32_LO12S2_RELA 28
-#define R_NDS32_LO12S1_RELA 29
-#define R_NDS32_LO12S0_RELA 30
-#define R_NDS32_SDA15S3_RELA 31
-#define R_NDS32_SDA15S2_RELA 32
-#define R_NDS32_SDA15S1_RELA 33
-#define R_NDS32_SDA15S0_RELA 34
-#define R_NDS32_GOT20 37
-#define R_NDS32_25_PLTREL 38
-#define R_NDS32_COPY 39
-#define R_NDS32_GLOB_DAT 40
-#define R_NDS32_JMP_SLOT 41
-#define R_NDS32_RELATIVE 42
-#define R_NDS32_GOTOFF 43
-#define R_NDS32_GOTPC20 44
-#define R_NDS32_GOT_HI20 45
-#define R_NDS32_GOT_LO12 46
-#define R_NDS32_GOTPC_HI20 47
-#define R_NDS32_GOTPC_LO12 48
-#define R_NDS32_GOTOFF_HI20 49
-#define R_NDS32_GOTOFF_LO12 50
-#define R_NDS32_INSN16 51
-#define R_NDS32_LABEL 52
-#define R_NDS32_LONGCALL1 53
-#define R_NDS32_LONGCALL2 54
-#define R_NDS32_LONGCALL3 55
-#define R_NDS32_LONGJUMP1 56
-#define R_NDS32_LONGJUMP2 57
-#define R_NDS32_LONGJUMP3 58
-#define R_NDS32_LOADSTORE 59
-#define R_NDS32_9_FIXED_RELA 60
-#define R_NDS32_15_FIXED_RELA 61
-#define R_NDS32_17_FIXED_RELA 62
-#define R_NDS32_25_FIXED_RELA 63
-#define R_NDS32_PLTREL_HI20 64
-#define R_NDS32_PLTREL_LO12 65
-#define R_NDS32_PLT_GOTREL_HI20 66
-#define R_NDS32_PLT_GOTREL_LO12 67
-#define R_NDS32_LO12S0_ORI_RELA 72
-#define R_NDS32_DWARF2_OP1_RELA 77
-#define R_NDS32_DWARF2_OP2_RELA 78
-#define R_NDS32_DWARF2_LEB_RELA 79
-#define R_NDS32_WORD_9_PCREL_RELA 94
-#define R_NDS32_LONGCALL4 107
-#define R_NDS32_RELA_NOP_MIX 192
-#define R_NDS32_RELA_NOP_MAX 255
-
-#define ELF_NGREG (sizeof (struct user_pt_regs) / sizeof(elf_greg_t))
-#define ELF_CORE_COPY_REGS(dest, regs) \
- *(struct user_pt_regs *)&(dest) = (regs)->user_regs;
-
-typedef elf_greg_t elf_gregset_t[ELF_NGREG];
-
-/* Core file format: The core file is written in such a way that gdb
- can understand it and provide useful information to the user (under
- linux we use the 'trad-core' bfd). There are quite a number of
- obstacles to being able to view the contents of the floating point
- registers, and until these are solved you will not be able to view the
- contents of them. Actually, you can read in the core file and look at
- the contents of the user struct to find out what the floating point
- registers contain.
- The actual file contents are as follows:
- UPAGE: 1 page consisting of a user struct that tells gdb what is present
- in the file. Directly after this is a copy of the task_struct, which
- is currently not used by gdb, but it may come in useful at some point.
- All of the registers are stored as part of the upage. The upage should
- always be only one page.
- DATA: The data area is stored. We use current->end_text to
- current->brk to pick up all of the user variables, plus any memory
- that may have been malloced. No attempt is made to determine if a page
- is demand-zero or if a page is totally unused, we just cover the entire
- range. All of the addresses are rounded in such a way that an integral
- number of pages is written.
- STACK: We need the stack information in order to get a meaningful
- backtrace. We need to write the data from (esp) to
- current->start_stack, so we round each of these off in order to be able
- to write an integer number of pages.
- The minimum core file size is 3 pages, or 12288 bytes.
-*/
-
-struct user_fp {
- unsigned long long fd_regs[32];
- unsigned long fpcsr;
-};
-
-typedef struct user_fp elf_fpregset_t;
-
-struct elf32_hdr;
-#define elf_check_arch(x) ((x)->e_machine == EM_NDS32)
-
-/*
- * These are used to set parameters in the core dumps.
- */
-#define ELF_CLASS ELFCLASS32
-#ifdef __NDS32_EB__
-#define ELF_DATA ELFDATA2MSB
-#else
-#define ELF_DATA ELFDATA2LSB
-#endif
-#define ELF_ARCH EM_NDS32
-#define ELF_EXEC_PAGESIZE PAGE_SIZE
-
-/* This is the location that an ET_DYN program is loaded if exec'ed. Typical
- use of this is to invoke "./ld.so someprog" to test out a new version of
- the loader. We need to make sure that it is out of the way of the program
- that it will "exec", and that there is sufficient room for the brk. */
-
-#define ELF_ET_DYN_BASE (2 * TASK_SIZE / 3)
-
-/* When the program starts, a1 contains a pointer to a function to be
- registered with atexit, as per the SVR4 ABI. A value of 0 means we
- have no such handler. */
-#define ELF_PLAT_INIT(_r, load_addr) (_r)->uregs[0] = 0
-
-/* This yields a mask that user programs can use to figure out what
- instruction set this cpu supports. */
-
-#define ELF_HWCAP (elf_hwcap)
-
-#ifdef __KERNEL__
-
-#define ELF_PLATFORM (NULL)
-
-/* Old NetWinder binaries were compiled in such a way that the iBCS
- heuristic always trips on them. Until these binaries become uncommon
- enough not to care, don't trust the `ibcs' flag here. In any case
- there is no other ELF system currently supported by iBCS.
- @@ Could print a warning message to encourage users to upgrade. */
-#define SET_PERSONALITY(ex) set_personality(PER_LINUX)
-
-#endif
-
-
-#if IS_ENABLED(CONFIG_FPU)
-#define FPU_AUX_ENT NEW_AUX_ENT(AT_FPUCW, FPCSR_INIT)
-#else
-#define FPU_AUX_ENT NEW_AUX_ENT(AT_IGNORE, 0)
-#endif
-
-#define ARCH_DLINFO \
-do { \
- /* Optional FPU initialization */ \
- FPU_AUX_ENT; \
- \
- NEW_AUX_ENT(AT_SYSINFO_EHDR, \
- (elf_addr_t)current->mm->context.vdso); \
-} while (0)
-#define ARCH_HAS_SETUP_ADDITIONAL_PAGES 1
-struct linux_binprm;
-int arch_setup_additional_pages(struct linux_binprm *, int);
-
-#endif
diff --git a/arch/nds32/include/asm/fixmap.h b/arch/nds32/include/asm/fixmap.h
deleted file mode 100644
index 2fa09a2de428..000000000000
--- a/arch/nds32/include/asm/fixmap.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-// Copyright (C) 2005-2017 Andes Technology Corporation
-
-#ifndef __ASM_NDS32_FIXMAP_H
-#define __ASM_NDS32_FIXMAP_H
-
-#ifdef CONFIG_HIGHMEM
-#include <linux/threads.h>
-#include <asm/kmap_size.h>
-#endif
-
-enum fixed_addresses {
- FIX_HOLE,
- FIX_KMAP_RESERVED,
- FIX_KMAP_BEGIN,
-#ifdef CONFIG_HIGHMEM
- FIX_KMAP_END = FIX_KMAP_BEGIN + (KM_MAX_IDX * NR_CPUS) - 1,
-#endif
- FIX_EARLYCON_MEM_BASE,
- __end_of_fixed_addresses
-};
-#define FIXADDR_TOP ((unsigned long) (-(16 * PAGE_SIZE)))
-#define FIXADDR_SIZE ((__end_of_fixed_addresses) << PAGE_SHIFT)
-#define FIXADDR_START (FIXADDR_TOP - FIXADDR_SIZE)
-#define FIXMAP_PAGE_IO __pgprot(PAGE_DEVICE)
-void __set_fixmap(enum fixed_addresses idx, phys_addr_t phys, pgprot_t prot);
-
-#include <asm-generic/fixmap.h>
-#endif /* __ASM_NDS32_FIXMAP_H */
diff --git a/arch/nds32/include/asm/fpu.h b/arch/nds32/include/asm/fpu.h
deleted file mode 100644
index 8294ed4aaa2c..000000000000
--- a/arch/nds32/include/asm/fpu.h
+++ /dev/null
@@ -1,126 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/* Copyright (C) 2005-2018 Andes Technology Corporation */
-
-#ifndef __ASM_NDS32_FPU_H
-#define __ASM_NDS32_FPU_H
-
-#if IS_ENABLED(CONFIG_FPU)
-#ifndef __ASSEMBLY__
-#include <linux/sched/task_stack.h>
-#include <linux/preempt.h>
-#include <asm/ptrace.h>
-
-extern bool has_fpu;
-
-extern void save_fpu(struct task_struct *__tsk);
-extern void load_fpu(const struct fpu_struct *fpregs);
-extern bool do_fpu_exception(unsigned int subtype, struct pt_regs *regs);
-extern int do_fpuemu(struct pt_regs *regs, struct fpu_struct *fpu);
-
-#define test_tsk_fpu(regs) (regs->fucop_ctl & FUCOP_CTL_mskCP0EN)
-
-/*
- * Initially load the FPU with signalling NANS. This bit pattern
- * has the property that no matter whether considered as single or as
- * double precision, it still represents a signalling NAN.
- */
-
-#define sNAN64 0xFFFFFFFFFFFFFFFFULL
-#define sNAN32 0xFFFFFFFFUL
-
-#if IS_ENABLED(CONFIG_SUPPORT_DENORMAL_ARITHMETIC)
-/*
- * Denormalized number is unsupported by nds32 FPU. Hence the operation
- * is treated as underflow cases when the final result is a denormalized
- * number. To enhance precision, underflow exception trap should be
- * enabled by default and kerenl will re-execute it by fpu emulator
- * when getting underflow exception.
- */
-#define FPCSR_INIT (FPCSR_mskUDFE | FPCSR_mskIEXE)
-#else
-#define FPCSR_INIT 0x0UL
-#endif
-
-extern const struct fpu_struct init_fpuregs;
-
-static inline void disable_ptreg_fpu(struct pt_regs *regs)
-{
- regs->fucop_ctl &= ~FUCOP_CTL_mskCP0EN;
-}
-
-static inline void enable_ptreg_fpu(struct pt_regs *regs)
-{
- regs->fucop_ctl |= FUCOP_CTL_mskCP0EN;
-}
-
-static inline void enable_fpu(void)
-{
- unsigned long fucop_ctl;
-
- fucop_ctl = __nds32__mfsr(NDS32_SR_FUCOP_CTL) | FUCOP_CTL_mskCP0EN;
- __nds32__mtsr(fucop_ctl, NDS32_SR_FUCOP_CTL);
- __nds32__isb();
-}
-
-static inline void disable_fpu(void)
-{
- unsigned long fucop_ctl;
-
- fucop_ctl = __nds32__mfsr(NDS32_SR_FUCOP_CTL) & ~FUCOP_CTL_mskCP0EN;
- __nds32__mtsr(fucop_ctl, NDS32_SR_FUCOP_CTL);
- __nds32__isb();
-}
-
-static inline void lose_fpu(void)
-{
- preempt_disable();
-#if IS_ENABLED(CONFIG_LAZY_FPU)
- if (last_task_used_math == current) {
- last_task_used_math = NULL;
-#else
- if (test_tsk_fpu(task_pt_regs(current))) {
-#endif
- save_fpu(current);
- }
- disable_ptreg_fpu(task_pt_regs(current));
- preempt_enable();
-}
-
-static inline void own_fpu(void)
-{
- preempt_disable();
-#if IS_ENABLED(CONFIG_LAZY_FPU)
- if (last_task_used_math != current) {
- if (last_task_used_math != NULL)
- save_fpu(last_task_used_math);
- load_fpu(&current->thread.fpu);
- last_task_used_math = current;
- }
-#else
- if (!test_tsk_fpu(task_pt_regs(current))) {
- load_fpu(&current->thread.fpu);
- }
-#endif
- enable_ptreg_fpu(task_pt_regs(current));
- preempt_enable();
-}
-
-#if !IS_ENABLED(CONFIG_LAZY_FPU)
-static inline void unlazy_fpu(struct task_struct *tsk)
-{
- preempt_disable();
- if (test_tsk_fpu(task_pt_regs(tsk)))
- save_fpu(tsk);
- preempt_enable();
-}
-#endif /* !CONFIG_LAZY_FPU */
-static inline void clear_fpu(struct pt_regs *regs)
-{
- preempt_disable();
- if (test_tsk_fpu(regs))
- disable_ptreg_fpu(regs);
- preempt_enable();
-}
-#endif /* CONFIG_FPU */
-#endif /* __ASSEMBLY__ */
-#endif /* __ASM_NDS32_FPU_H */
diff --git a/arch/nds32/include/asm/fpuemu.h b/arch/nds32/include/asm/fpuemu.h
deleted file mode 100644
index 63e7ef5f7969..000000000000
--- a/arch/nds32/include/asm/fpuemu.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/* Copyright (C) 2005-2018 Andes Technology Corporation */
-
-#ifndef __ARCH_NDS32_FPUEMU_H
-#define __ARCH_NDS32_FPUEMU_H
-
-/*
- * single precision
- */
-
-void fadds(void *ft, void *fa, void *fb);
-void fsubs(void *ft, void *fa, void *fb);
-void fmuls(void *ft, void *fa, void *fb);
-void fdivs(void *ft, void *fa, void *fb);
-void fs2d(void *ft, void *fa);
-void fs2si(void *ft, void *fa);
-void fs2si_z(void *ft, void *fa);
-void fs2ui(void *ft, void *fa);
-void fs2ui_z(void *ft, void *fa);
-void fsi2s(void *ft, void *fa);
-void fui2s(void *ft, void *fa);
-void fsqrts(void *ft, void *fa);
-void fnegs(void *ft, void *fa);
-int fcmps(void *ft, void *fa, void *fb, int cop);
-
-/*
- * double precision
- */
-void faddd(void *ft, void *fa, void *fb);
-void fsubd(void *ft, void *fa, void *fb);
-void fmuld(void *ft, void *fa, void *fb);
-void fdivd(void *ft, void *fa, void *fb);
-void fsqrtd(void *ft, void *fa);
-void fd2s(void *ft, void *fa);
-void fd2si(void *ft, void *fa);
-void fd2si_z(void *ft, void *fa);
-void fd2ui(void *ft, void *fa);
-void fd2ui_z(void *ft, void *fa);
-void fsi2d(void *ft, void *fa);
-void fui2d(void *ft, void *fa);
-void fnegd(void *ft, void *fa);
-int fcmpd(void *ft, void *fa, void *fb, int cop);
-
-#endif /* __ARCH_NDS32_FPUEMU_H */
diff --git a/arch/nds32/include/asm/ftrace.h b/arch/nds32/include/asm/ftrace.h
deleted file mode 100644
index 2f96cc96aa35..000000000000
--- a/arch/nds32/include/asm/ftrace.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-
-#ifndef __ASM_NDS32_FTRACE_H
-#define __ASM_NDS32_FTRACE_H
-
-#ifdef CONFIG_FUNCTION_TRACER
-
-#define HAVE_FUNCTION_GRAPH_FP_TEST
-
-#define MCOUNT_ADDR ((unsigned long)(_mcount))
-/* mcount call is composed of three instructions:
- * sethi + ori + jral
- */
-#define MCOUNT_INSN_SIZE 12
-
-extern void _mcount(unsigned long parent_ip);
-
-#ifdef CONFIG_DYNAMIC_FTRACE
-
-#define FTRACE_ADDR ((unsigned long)_ftrace_caller)
-
-#ifdef __NDS32_EL__
-#define INSN_NOP 0x09000040
-#define INSN_SIZE(insn) (((insn & 0x00000080) == 0) ? 4 : 2)
-#define IS_SETHI(insn) ((insn & 0x000000fe) == 0x00000046)
-#define ENDIAN_CONVERT(insn) be32_to_cpu(insn)
-#else /* __NDS32_EB__ */
-#define INSN_NOP 0x40000009
-#define INSN_SIZE(insn) (((insn & 0x80000000) == 0) ? 4 : 2)
-#define IS_SETHI(insn) ((insn & 0xfe000000) == 0x46000000)
-#define ENDIAN_CONVERT(insn) (insn)
-#endif
-
-extern void _ftrace_caller(unsigned long parent_ip);
-static inline unsigned long ftrace_call_adjust(unsigned long addr)
-{
- return addr;
-}
-struct dyn_arch_ftrace {
-};
-
-#endif /* CONFIG_DYNAMIC_FTRACE */
-
-#endif /* CONFIG_FUNCTION_TRACER */
-
-#endif /* __ASM_NDS32_FTRACE_H */
diff --git a/arch/nds32/include/asm/futex.h b/arch/nds32/include/asm/futex.h
deleted file mode 100644
index 4223f473bd36..000000000000
--- a/arch/nds32/include/asm/futex.h
+++ /dev/null
@@ -1,101 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-// Copyright (C) 2005-2017 Andes Technology Corporation
-
-#ifndef __NDS32_FUTEX_H__
-#define __NDS32_FUTEX_H__
-
-#include <linux/futex.h>
-#include <linux/uaccess.h>
-#include <asm/errno.h>
-
-#define __futex_atomic_ex_table(err_reg) \
- " .pushsection __ex_table,\"a\"\n" \
- " .align 3\n" \
- " .long 1b, 4f\n" \
- " .long 2b, 4f\n" \
- " .popsection\n" \
- " .pushsection .fixup,\"ax\"\n" \
- "4: move %0, " err_reg "\n" \
- " b 3b\n" \
- " .popsection"
-
-#define __futex_atomic_op(insn, ret, oldval, tmp, uaddr, oparg) \
- smp_mb(); \
- asm volatile( \
- " movi $ta, #0\n" \
- "1: llw %1, [%2+$ta]\n" \
- " " insn "\n" \
- "2: scw %0, [%2+$ta]\n" \
- " beqz %0, 1b\n" \
- " movi %0, #0\n" \
- "3:\n" \
- __futex_atomic_ex_table("%4") \
- : "=&r" (ret), "=&r" (oldval) \
- : "r" (uaddr), "r" (oparg), "i" (-EFAULT) \
- : "cc", "memory")
-static inline int
-futex_atomic_cmpxchg_inatomic(u32 * uval, u32 __user * uaddr,
- u32 oldval, u32 newval)
-{
- int ret = 0;
- u32 val, tmp, flags;
-
- if (!access_ok(uaddr, sizeof(u32)))
- return -EFAULT;
-
- smp_mb();
- asm volatile (" movi $ta, #0\n"
- "1: llw %1, [%6 + $ta]\n"
- " sub %3, %1, %4\n"
- " cmovz %2, %5, %3\n"
- " cmovn %2, %1, %3\n"
- "2: scw %2, [%6 + $ta]\n"
- " beqz %2, 1b\n"
- "3:\n " __futex_atomic_ex_table("%7")
- :"+&r"(ret), "=&r"(val), "=&r"(tmp), "=&r"(flags)
- :"r"(oldval), "r"(newval), "r"(uaddr), "i"(-EFAULT)
- :"$ta", "memory");
- smp_mb();
-
- *uval = val;
- return ret;
-}
-
-static inline int
-arch_futex_atomic_op_inuser(int op, int oparg, int *oval, u32 __user *uaddr)
-{
- int oldval = 0, ret;
-
- if (!access_ok(uaddr, sizeof(u32)))
- return -EFAULT;
- switch (op) {
- case FUTEX_OP_SET:
- __futex_atomic_op("move %0, %3", ret, oldval, tmp, uaddr,
- oparg);
- break;
- case FUTEX_OP_ADD:
- __futex_atomic_op("add %0, %1, %3", ret, oldval, tmp, uaddr,
- oparg);
- break;
- case FUTEX_OP_OR:
- __futex_atomic_op("or %0, %1, %3", ret, oldval, tmp, uaddr,
- oparg);
- break;
- case FUTEX_OP_ANDN:
- __futex_atomic_op("and %0, %1, %3", ret, oldval, tmp, uaddr,
- ~oparg);
- break;
- case FUTEX_OP_XOR:
- __futex_atomic_op("xor %0, %1, %3", ret, oldval, tmp, uaddr,
- oparg);
- break;
- default:
- ret = -ENOSYS;
- }
-
- if (!ret)
- *oval = oldval;
-
- return ret;
-}
-#endif /* __NDS32_FUTEX_H__ */
diff --git a/arch/nds32/include/asm/highmem.h b/arch/nds32/include/asm/highmem.h
deleted file mode 100644
index 16159a8716f2..000000000000
--- a/arch/nds32/include/asm/highmem.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-// Copyright (C) 2005-2017 Andes Technology Corporation
-
-#ifndef _ASM_HIGHMEM_H
-#define _ASM_HIGHMEM_H
-
-#include <asm/proc-fns.h>
-#include <asm/fixmap.h>
-
-/*
- * Right now we initialize only a single pte table. It can be extended
- * easily, subsequent pte tables have to be allocated in one physical
- * chunk of RAM.
- */
-/*
- * Ordering is (from lower to higher memory addresses):
- *
- * high_memory
- * Persistent kmap area
- * PKMAP_BASE
- * fixed_addresses
- * FIXADDR_START
- * FIXADDR_TOP
- * Vmalloc area
- * VMALLOC_START
- * VMALLOC_END
- */
-#define PKMAP_BASE ((FIXADDR_START - PGDIR_SIZE) & (PGDIR_MASK))
-#define LAST_PKMAP PTRS_PER_PTE
-#define LAST_PKMAP_MASK (LAST_PKMAP - 1)
-#define PKMAP_NR(virt) (((virt) - (PKMAP_BASE)) >> PAGE_SHIFT)
-#define PKMAP_ADDR(nr) (PKMAP_BASE + ((nr) << PAGE_SHIFT))
-
-static inline void flush_cache_kmaps(void)
-{
- cpu_dcache_wbinval_all();
-}
-
-/* declarations for highmem.c */
-extern unsigned long highstart_pfn, highend_pfn;
-
-extern pte_t *pkmap_page_table;
-
-extern void kmap_init(void);
-
-/*
- * FIXME: The below looks broken vs. a kmap_atomic() in task context which
- * is interupted and another kmap_atomic() happens in interrupt context.
- * But what do I know about nds32. -- tglx
- */
-#define arch_kmap_local_post_map(vaddr, pteval) \
- do { \
- __nds32__tlbop_inv(vaddr); \
- __nds32__mtsr_dsb(vaddr, NDS32_SR_TLB_VPN); \
- __nds32__tlbop_rwr(pteval); \
- __nds32__isb(); \
- } while (0)
-
-#define arch_kmap_local_pre_unmap(vaddr) \
- do { \
- __nds32__tlbop_inv(vaddr); \
- __nds32__isb(); \
- } while (0)
-
-#endif
diff --git a/arch/nds32/include/asm/io.h b/arch/nds32/include/asm/io.h
deleted file mode 100644
index e57378d04006..000000000000
--- a/arch/nds32/include/asm/io.h
+++ /dev/null
@@ -1,84 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-// Copyright (C) 2005-2017 Andes Technology Corporation
-
-#ifndef __ASM_NDS32_IO_H
-#define __ASM_NDS32_IO_H
-
-#include <linux/types.h>
-
-#define __raw_writeb __raw_writeb
-static inline void __raw_writeb(u8 val, volatile void __iomem *addr)
-{
- asm volatile("sbi %0, [%1]" : : "r" (val), "r" (addr));
-}
-
-#define __raw_writew __raw_writew
-static inline void __raw_writew(u16 val, volatile void __iomem *addr)
-{
- asm volatile("shi %0, [%1]" : : "r" (val), "r" (addr));
-}
-
-#define __raw_writel __raw_writel
-static inline void __raw_writel(u32 val, volatile void __iomem *addr)
-{
- asm volatile("swi %0, [%1]" : : "r" (val), "r" (addr));
-}
-
-#define __raw_readb __raw_readb
-static inline u8 __raw_readb(const volatile void __iomem *addr)
-{
- u8 val;
-
- asm volatile("lbi %0, [%1]" : "=r" (val) : "r" (addr));
- return val;
-}
-
-#define __raw_readw __raw_readw
-static inline u16 __raw_readw(const volatile void __iomem *addr)
-{
- u16 val;
-
- asm volatile("lhi %0, [%1]" : "=r" (val) : "r" (addr));
- return val;
-}
-
-#define __raw_readl __raw_readl
-static inline u32 __raw_readl(const volatile void __iomem *addr)
-{
- u32 val;
-
- asm volatile("lwi %0, [%1]" : "=r" (val) : "r" (addr));
- return val;
-}
-
-#define __iormb() rmb()
-#define __iowmb() wmb()
-
-/*
- * {read,write}{b,w,l,q}_relaxed() are like the regular version, but
- * are not guaranteed to provide ordering against spinlocks or memory
- * accesses.
- */
-
-#define readb_relaxed(c) ({ u8 __v = __raw_readb(c); __v; })
-#define readw_relaxed(c) ({ u16 __v = le16_to_cpu((__force __le16)__raw_readw(c)); __v; })
-#define readl_relaxed(c) ({ u32 __v = le32_to_cpu((__force __le32)__raw_readl(c)); __v; })
-#define writeb_relaxed(v,c) ((void)__raw_writeb((v),(c)))
-#define writew_relaxed(v,c) ((void)__raw_writew((__force u16)cpu_to_le16(v),(c)))
-#define writel_relaxed(v,c) ((void)__raw_writel((__force u32)cpu_to_le32(v),(c)))
-
-/*
- * {read,write}{b,w,l,q}() access little endian memory and return result in
- * native endianness.
- */
-#define readb(c) ({ u8 __v = readb_relaxed(c); __iormb(); __v; })
-#define readw(c) ({ u16 __v = readw_relaxed(c); __iormb(); __v; })
-#define readl(c) ({ u32 __v = readl_relaxed(c); __iormb(); __v; })
-
-#define writeb(v,c) ({ __iowmb(); writeb_relaxed((v),(c)); })
-#define writew(v,c) ({ __iowmb(); writew_relaxed((v),(c)); })
-#define writel(v,c) ({ __iowmb(); writel_relaxed((v),(c)); })
-
-#include <asm-generic/io.h>
-
-#endif /* __ASM_NDS32_IO_H */
diff --git a/arch/nds32/include/asm/irqflags.h b/arch/nds32/include/asm/irqflags.h
deleted file mode 100644
index 51ef800bb301..000000000000
--- a/arch/nds32/include/asm/irqflags.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-// Copyright (C) 2005-2017 Andes Technology Corporation
-
-#include <asm/nds32.h>
-#include <nds32_intrinsic.h>
-
-#define arch_local_irq_disable() \
- GIE_DISABLE();
-
-#define arch_local_irq_enable() \
- GIE_ENABLE();
-static inline unsigned long arch_local_irq_save(void)
-{
- unsigned long flags;
- flags = __nds32__mfsr(NDS32_SR_PSW) & PSW_mskGIE;
- GIE_DISABLE();
- return flags;
-}
-
-static inline unsigned long arch_local_save_flags(void)
-{
- unsigned long flags;
- flags = __nds32__mfsr(NDS32_SR_PSW) & PSW_mskGIE;
- return flags;
-}
-
-static inline void arch_local_irq_restore(unsigned long flags)
-{
- if(flags)
- GIE_ENABLE();
-}
-
-static inline int arch_irqs_disabled_flags(unsigned long flags)
-{
- return !flags;
-}
-
-static inline int arch_irqs_disabled(void)
-{
- return arch_irqs_disabled_flags(arch_local_save_flags());
-}
diff --git a/arch/nds32/include/asm/l2_cache.h b/arch/nds32/include/asm/l2_cache.h
deleted file mode 100644
index 3ea48e19e6de..000000000000
--- a/arch/nds32/include/asm/l2_cache.h
+++ /dev/null
@@ -1,137 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-// Copyright (C) 2005-2017 Andes Technology Corporation
-
-#ifndef L2_CACHE_H
-#define L2_CACHE_H
-
-/* CCTL_CMD_OP */
-#define L2_CA_CONF_OFF 0x0
-#define L2_IF_CONF_OFF 0x4
-#define L2CC_SETUP_OFF 0x8
-#define L2CC_PROT_OFF 0xC
-#define L2CC_CTRL_OFF 0x10
-#define L2_INT_EN_OFF 0x20
-#define L2_STA_OFF 0x24
-#define RDERR_ADDR_OFF 0x28
-#define WRERR_ADDR_OFF 0x2c
-#define EVDPTERR_ADDR_OFF 0x30
-#define IMPL3ERR_ADDR_OFF 0x34
-#define L2_CNT0_CTRL_OFF 0x40
-#define L2_EVNT_CNT0_OFF 0x44
-#define L2_CNT1_CTRL_OFF 0x48
-#define L2_EVNT_CNT1_OFF 0x4c
-#define L2_CCTL_CMD_OFF 0x60
-#define L2_CCTL_STATUS_OFF 0x64
-#define L2_LINE_TAG_OFF 0x68
-#define L2_LINE_DPT_OFF 0x70
-
-#define CCTL_CMD_L2_IX_INVAL 0x0
-#define CCTL_CMD_L2_PA_INVAL 0x1
-#define CCTL_CMD_L2_IX_WB 0x2
-#define CCTL_CMD_L2_PA_WB 0x3
-#define CCTL_CMD_L2_PA_WBINVAL 0x5
-#define CCTL_CMD_L2_SYNC 0xa
-
-/* CCTL_CMD_TYPE */
-#define CCTL_SINGLE_CMD 0
-#define CCTL_BLOCK_CMD 0x10
-#define CCTL_ALL_CMD 0x10
-
-/******************************************************************************
- * L2_CA_CONF (Cache architecture configuration)
- *****************************************************************************/
-#define L2_CA_CONF_offL2SET 0
-#define L2_CA_CONF_offL2WAY 4
-#define L2_CA_CONF_offL2CLSZ 8
-#define L2_CA_CONF_offL2DW 11
-#define L2_CA_CONF_offL2PT 14
-#define L2_CA_CONF_offL2VER 16
-
-#define L2_CA_CONF_mskL2SET (0xFUL << L2_CA_CONF_offL2SET)
-#define L2_CA_CONF_mskL2WAY (0xFUL << L2_CA_CONF_offL2WAY)
-#define L2_CA_CONF_mskL2CLSZ (0x7UL << L2_CA_CONF_offL2CLSZ)
-#define L2_CA_CONF_mskL2DW (0x7UL << L2_CA_CONF_offL2DW)
-#define L2_CA_CONF_mskL2PT (0x3UL << L2_CA_CONF_offL2PT)
-#define L2_CA_CONF_mskL2VER (0xFFFFUL << L2_CA_CONF_offL2VER)
-
-/******************************************************************************
- * L2CC_SETUP (L2CC Setup register)
- *****************************************************************************/
-#define L2CC_SETUP_offPART 0
-#define L2CC_SETUP_mskPART (0x3UL << L2CC_SETUP_offPART)
-#define L2CC_SETUP_offDDLATC 4
-#define L2CC_SETUP_mskDDLATC (0x3UL << L2CC_SETUP_offDDLATC)
-#define L2CC_SETUP_offTDLATC 8
-#define L2CC_SETUP_mskTDLATC (0x3UL << L2CC_SETUP_offTDLATC)
-
-/******************************************************************************
- * L2CC_PROT (L2CC Protect register)
- *****************************************************************************/
-#define L2CC_PROT_offMRWEN 31
-#define L2CC_PROT_mskMRWEN (0x1UL << L2CC_PROT_offMRWEN)
-
-/******************************************************************************
- * L2_CCTL_STATUS_Mn (The L2CCTL command working status for Master n)
- *****************************************************************************/
-#define L2CC_CTRL_offEN 31
-#define L2CC_CTRL_mskEN (0x1UL << L2CC_CTRL_offEN)
-
-/******************************************************************************
- * L2_CCTL_STATUS_Mn (The L2CCTL command working status for Master n)
- *****************************************************************************/
-#define L2_CCTL_STATUS_offCMD_COMP 31
-#define L2_CCTL_STATUS_mskCMD_COMP (0x1 << L2_CCTL_STATUS_offCMD_COMP)
-
-extern void __iomem *atl2c_base;
-#include <linux/smp.h>
-#include <asm/io.h>
-#include <asm/bitfield.h>
-
-#define L2C_R_REG(offset) readl(atl2c_base + offset)
-#define L2C_W_REG(offset, value) writel(value, atl2c_base + offset)
-
-#define L2_CMD_RDY() \
- do{;}while((L2C_R_REG(L2_CCTL_STATUS_OFF) & L2_CCTL_STATUS_mskCMD_COMP) == 0)
-
-static inline unsigned long L2_CACHE_SET(void)
-{
- return 64 << ((L2C_R_REG(L2_CA_CONF_OFF) & L2_CA_CONF_mskL2SET) >>
- L2_CA_CONF_offL2SET);
-}
-
-static inline unsigned long L2_CACHE_WAY(void)
-{
- return 1 +
- ((L2C_R_REG(L2_CA_CONF_OFF) & L2_CA_CONF_mskL2WAY) >>
- L2_CA_CONF_offL2WAY);
-}
-
-static inline unsigned long L2_CACHE_LINE_SIZE(void)
-{
-
- return 4 << ((L2C_R_REG(L2_CA_CONF_OFF) & L2_CA_CONF_mskL2CLSZ) >>
- L2_CA_CONF_offL2CLSZ);
-}
-
-static inline unsigned long GET_L2CC_CTRL_CPU(unsigned long cpu)
-{
- if (cpu == smp_processor_id())
- return L2C_R_REG(L2CC_CTRL_OFF);
- return L2C_R_REG(L2CC_CTRL_OFF + (cpu << 8));
-}
-
-static inline void SET_L2CC_CTRL_CPU(unsigned long cpu, unsigned long val)
-{
- if (cpu == smp_processor_id())
- L2C_W_REG(L2CC_CTRL_OFF, val);
- else
- L2C_W_REG(L2CC_CTRL_OFF + (cpu << 8), val);
-}
-
-static inline unsigned long GET_L2CC_STATUS_CPU(unsigned long cpu)
-{
- if (cpu == smp_processor_id())
- return L2C_R_REG(L2_CCTL_STATUS_OFF);
- return L2C_R_REG(L2_CCTL_STATUS_OFF + (cpu << 8));
-}
-#endif
diff --git a/arch/nds32/include/asm/linkage.h b/arch/nds32/include/asm/linkage.h
deleted file mode 100644
index a696469abb70..000000000000
--- a/arch/nds32/include/asm/linkage.h
+++ /dev/null
@@ -1,11 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-// Copyright (C) 2005-2017 Andes Technology Corporation
-
-#ifndef __ASM_LINKAGE_H
-#define __ASM_LINKAGE_H
-
-/* This file is required by include/linux/linkage.h */
-#define __ALIGN .align 2
-#define __ALIGN_STR ".align 2"
-
-#endif
diff --git a/arch/nds32/include/asm/memory.h b/arch/nds32/include/asm/memory.h
deleted file mode 100644
index 62faafbc28e4..000000000000
--- a/arch/nds32/include/asm/memory.h
+++ /dev/null
@@ -1,91 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-// Copyright (C) 2005-2017 Andes Technology Corporation
-
-#ifndef __ASM_NDS32_MEMORY_H
-#define __ASM_NDS32_MEMORY_H
-
-#include <linux/compiler.h>
-#include <linux/sizes.h>
-
-#ifndef __ASSEMBLY__
-#include <asm/page.h>
-#endif
-
-#ifndef PHYS_OFFSET
-#define PHYS_OFFSET (0x0)
-#endif
-
-/*
- * TASK_SIZE - the maximum size of a user space task.
- * TASK_UNMAPPED_BASE - the lower boundary of the mmap VM area
- */
-#define TASK_SIZE ((CONFIG_PAGE_OFFSET) - (SZ_32M))
-#define TASK_UNMAPPED_BASE ALIGN(TASK_SIZE / 3, SZ_32M)
-#define PAGE_OFFSET (CONFIG_PAGE_OFFSET)
-
-/*
- * Physical vs virtual RAM address space conversion. These are
- * private definitions which should NOT be used outside memory.h
- * files. Use virt_to_phys/phys_to_virt/__pa/__va instead.
- */
-#ifndef __virt_to_phys
-#define __virt_to_phys(x) ((x) - PAGE_OFFSET + PHYS_OFFSET)
-#define __phys_to_virt(x) ((x) - PHYS_OFFSET + PAGE_OFFSET)
-#endif
-
-/*
- * The module space lives between the addresses given by TASK_SIZE
- * and PAGE_OFFSET - it must be within 32MB of the kernel text.
- */
-#define MODULES_END (PAGE_OFFSET)
-#define MODULES_VADDR (MODULES_END - SZ_32M)
-
-#if TASK_SIZE > MODULES_VADDR
-#error Top of user space clashes with start of module space
-#endif
-
-#ifndef __ASSEMBLY__
-
-/*
- * PFNs are used to describe any physical page; this means
- * PFN 0 == physical address 0.
- *
- * This is the PFN of the first RAM page in the kernel
- * direct-mapped view. We assume this is the first page
- * of RAM in the mem_map as well.
- */
-#define PHYS_PFN_OFFSET (PHYS_OFFSET >> PAGE_SHIFT)
-
-/*
- * Drivers should NOT use these either.
- */
-#define __pa(x) __virt_to_phys((unsigned long)(x))
-#define __va(x) ((void *)__phys_to_virt((unsigned long)(x)))
-
-/*
- * Conversion between a struct page and a physical address.
- *
- * Note: when converting an unknown physical address to a
- * struct page, the resulting pointer must be validated
- * using VALID_PAGE(). It must return an invalid struct page
- * for any physical address not corresponding to a system
- * RAM address.
- *
- * pfn_valid(pfn) indicates whether a PFN number is valid
- *
- * virt_to_page(k) convert a _valid_ virtual address to struct page *
- * virt_addr_valid(k) indicates whether a virtual address is valid
- */
-#define ARCH_PFN_OFFSET PHYS_PFN_OFFSET
-#define pfn_valid(pfn) ((pfn) >= PHYS_PFN_OFFSET && (pfn) < (PHYS_PFN_OFFSET + max_mapnr))
-
-#define virt_to_page(kaddr) (pfn_to_page(__pa(kaddr) >> PAGE_SHIFT))
-#define virt_addr_valid(kaddr) ((unsigned long)(kaddr) >= PAGE_OFFSET && (unsigned long)(kaddr) < (unsigned long)high_memory)
-
-#define page_to_phys(page) (page_to_pfn(page) << PAGE_SHIFT)
-
-#endif
-
-#include <asm-generic/memory_model.h>
-
-#endif
diff --git a/arch/nds32/include/asm/mmu.h b/arch/nds32/include/asm/mmu.h
deleted file mode 100644
index 89d63afee455..000000000000
--- a/arch/nds32/include/asm/mmu.h
+++ /dev/null
@@ -1,12 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-// Copyright (C) 2005-2017 Andes Technology Corporation
-
-#ifndef __NDS32_MMU_H
-#define __NDS32_MMU_H
-
-typedef struct {
- unsigned int id;
- void *vdso;
-} mm_context_t;
-
-#endif
diff --git a/arch/nds32/include/asm/mmu_context.h b/arch/nds32/include/asm/mmu_context.h
deleted file mode 100644
index c651bc8cacdc..000000000000
--- a/arch/nds32/include/asm/mmu_context.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-// Copyright (C) 2005-2017 Andes Technology Corporation
-
-#ifndef __ASM_NDS32_MMU_CONTEXT_H
-#define __ASM_NDS32_MMU_CONTEXT_H
-
-#include <linux/spinlock.h>
-#include <asm/tlbflush.h>
-#include <asm/proc-fns.h>
-#include <asm-generic/mm_hooks.h>
-
-#define init_new_context init_new_context
-static inline int
-init_new_context(struct task_struct *tsk, struct mm_struct *mm)
-{
- mm->context.id = 0;
- return 0;
-}
-
-#define CID_BITS 9
-extern spinlock_t cid_lock;
-extern unsigned int cpu_last_cid;
-
-static inline void __new_context(struct mm_struct *mm)
-{
- unsigned int cid;
- unsigned long flags;
-
- spin_lock_irqsave(&cid_lock, flags);
- cid = cpu_last_cid;
- cpu_last_cid += 1 << TLB_MISC_offCID;
- if (cpu_last_cid == 0)
- cpu_last_cid = 1 << TLB_MISC_offCID << CID_BITS;
-
- if ((cid & TLB_MISC_mskCID) == 0)
- flush_tlb_all();
- spin_unlock_irqrestore(&cid_lock, flags);
-
- mm->context.id = cid;
-}
-
-static inline void check_context(struct mm_struct *mm)
-{
- if (unlikely
- ((mm->context.id ^ cpu_last_cid) >> TLB_MISC_offCID >> CID_BITS))
- __new_context(mm);
-}
-
-static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
- struct task_struct *tsk)
-{
- unsigned int cpu = smp_processor_id();
-
- if (!cpumask_test_and_set_cpu(cpu, mm_cpumask(next)) || prev != next) {
- check_context(next);
- cpu_switch_mm(next);
- }
-}
-
-#include <asm-generic/mmu_context.h>
-
-#endif
diff --git a/arch/nds32/include/asm/nds32.h b/arch/nds32/include/asm/nds32.h
deleted file mode 100644
index 4994f6a9e0a0..000000000000
--- a/arch/nds32/include/asm/nds32.h
+++ /dev/null
@@ -1,82 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-// Copyright (C) 2005-2017 Andes Technology Corporation
-
-#ifndef _ASM_NDS32_NDS32_H_
-#define _ASM_NDS32_NDS32_H_
-
-#include <asm/bitfield.h>
-#include <asm/cachectl.h>
-
-#ifndef __ASSEMBLY__
-#include <linux/init.h>
-#include <asm/barrier.h>
-#include <nds32_intrinsic.h>
-
-#ifdef CONFIG_CC_OPTIMIZE_FOR_SIZE
-#define FP_OFFSET (-3)
-#else
-#define FP_OFFSET (-2)
-#endif
-#define LP_OFFSET (-1)
-
-extern void __init early_trap_init(void);
-static inline void GIE_ENABLE(void)
-{
- mb();
- __nds32__gie_en();
-}
-
-static inline void GIE_DISABLE(void)
-{
- mb();
- __nds32__gie_dis();
-}
-
-static inline unsigned long CACHE_SET(unsigned char cache)
-{
-
- if (cache == ICACHE)
- return 64 << ((__nds32__mfsr(NDS32_SR_ICM_CFG) & ICM_CFG_mskISET) >>
- ICM_CFG_offISET);
- else
- return 64 << ((__nds32__mfsr(NDS32_SR_DCM_CFG) & DCM_CFG_mskDSET) >>
- DCM_CFG_offDSET);
-}
-
-static inline unsigned long CACHE_WAY(unsigned char cache)
-{
-
- if (cache == ICACHE)
- return 1 +
- ((__nds32__mfsr(NDS32_SR_ICM_CFG) & ICM_CFG_mskIWAY) >> ICM_CFG_offIWAY);
- else
- return 1 +
- ((__nds32__mfsr(NDS32_SR_DCM_CFG) & DCM_CFG_mskDWAY) >> DCM_CFG_offDWAY);
-}
-
-static inline unsigned long CACHE_LINE_SIZE(unsigned char cache)
-{
-
- if (cache == ICACHE)
- return 8 <<
- (((__nds32__mfsr(NDS32_SR_ICM_CFG) & ICM_CFG_mskISZ) >> ICM_CFG_offISZ) - 1);
- else
- return 8 <<
- (((__nds32__mfsr(NDS32_SR_DCM_CFG) & DCM_CFG_mskDSZ) >> DCM_CFG_offDSZ) - 1);
-}
-
-#endif /* __ASSEMBLY__ */
-
-#define IVB_BASE PHYS_OFFSET /* in user space for intr/exc/trap/break table base, 64KB aligned
- * We defined at the start of the physical memory */
-
-/* dispatched sub-entry exception handler numbering */
-#define RD_PROT 0 /* read protrection */
-#define WRT_PROT 1 /* write protection */
-#define NOEXEC 2 /* non executable */
-#define PAGE_MODIFY 3 /* page modified */
-#define ACC_BIT 4 /* access bit */
-#define RESVED_PTE 5 /* reserved PTE attribute */
-/* reserved 6 ~ 16 */
-
-#endif /* _ASM_NDS32_NDS32_H_ */
diff --git a/arch/nds32/include/asm/nds32_fpu_inst.h b/arch/nds32/include/asm/nds32_fpu_inst.h
deleted file mode 100644
index 1e4b86a90a48..000000000000
--- a/arch/nds32/include/asm/nds32_fpu_inst.h
+++ /dev/null
@@ -1,109 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/* Copyright (C) 2005-2018 Andes Technology Corporation */
-
-#ifndef __NDS32_FPU_INST_H
-#define __NDS32_FPU_INST_H
-
-#define cop0_op 0x35
-
-/*
- * COP0 field of opcodes.
- */
-#define fs1_op 0x0
-#define fs2_op 0x4
-#define fd1_op 0x8
-#define fd2_op 0xc
-
-/*
- * FS1 opcode.
- */
-enum fs1 {
- fadds_op, fsubs_op, fcpynss_op, fcpyss_op,
- fmadds_op, fmsubs_op, fcmovns_op, fcmovzs_op,
- fnmadds_op, fnmsubs_op,
- fmuls_op = 0xc, fdivs_op,
- fs1_f2op_op = 0xf
-};
-
-/*
- * FS1/F2OP opcode.
- */
-enum fs1_f2 {
- fs2d_op, fsqrts_op,
- fui2s_op = 0x8, fsi2s_op = 0xc,
- fs2ui_op = 0x10, fs2ui_z_op = 0x14,
- fs2si_op = 0x18, fs2si_z_op = 0x1c
-};
-
-/*
- * FS2 opcode.
- */
-enum fs2 {
- fcmpeqs_op, fcmpeqs_e_op, fcmplts_op, fcmplts_e_op,
- fcmples_op, fcmples_e_op, fcmpuns_op, fcmpuns_e_op
-};
-
-/*
- * FD1 opcode.
- */
-enum fd1 {
- faddd_op, fsubd_op, fcpynsd_op, fcpysd_op,
- fmaddd_op, fmsubd_op, fcmovnd_op, fcmovzd_op,
- fnmaddd_op, fnmsubd_op,
- fmuld_op = 0xc, fdivd_op, fd1_f2op_op = 0xf
-};
-
-/*
- * FD1/F2OP opcode.
- */
-enum fd1_f2 {
- fd2s_op, fsqrtd_op,
- fui2d_op = 0x8, fsi2d_op = 0xc,
- fd2ui_op = 0x10, fd2ui_z_op = 0x14,
- fd2si_op = 0x18, fd2si_z_op = 0x1c
-};
-
-/*
- * FD2 opcode.
- */
-enum fd2 {
- fcmpeqd_op, fcmpeqd_e_op, fcmpltd_op, fcmpltd_e_op,
- fcmpled_op, fcmpled_e_op, fcmpund_op, fcmpund_e_op
-};
-
-#define NDS32Insn(x) x
-
-#define I_OPCODE_off 25
-#define NDS32Insn_OPCODE(x) (NDS32Insn(x) >> I_OPCODE_off)
-
-#define I_OPCODE_offRt 20
-#define I_OPCODE_mskRt (0x1fUL << I_OPCODE_offRt)
-#define NDS32Insn_OPCODE_Rt(x) \
- ((NDS32Insn(x) & I_OPCODE_mskRt) >> I_OPCODE_offRt)
-
-#define I_OPCODE_offRa 15
-#define I_OPCODE_mskRa (0x1fUL << I_OPCODE_offRa)
-#define NDS32Insn_OPCODE_Ra(x) \
- ((NDS32Insn(x) & I_OPCODE_mskRa) >> I_OPCODE_offRa)
-
-#define I_OPCODE_offRb 10
-#define I_OPCODE_mskRb (0x1fUL << I_OPCODE_offRb)
-#define NDS32Insn_OPCODE_Rb(x) \
- ((NDS32Insn(x) & I_OPCODE_mskRb) >> I_OPCODE_offRb)
-
-#define I_OPCODE_offbit1014 10
-#define I_OPCODE_mskbit1014 (0x1fUL << I_OPCODE_offbit1014)
-#define NDS32Insn_OPCODE_BIT1014(x) \
- ((NDS32Insn(x) & I_OPCODE_mskbit1014) >> I_OPCODE_offbit1014)
-
-#define I_OPCODE_offbit69 6
-#define I_OPCODE_mskbit69 (0xfUL << I_OPCODE_offbit69)
-#define NDS32Insn_OPCODE_BIT69(x) \
- ((NDS32Insn(x) & I_OPCODE_mskbit69) >> I_OPCODE_offbit69)
-
-#define I_OPCODE_offCOP0 0
-#define I_OPCODE_mskCOP0 (0x3fUL << I_OPCODE_offCOP0)
-#define NDS32Insn_OPCODE_COP0(x) \
- ((NDS32Insn(x) & I_OPCODE_mskCOP0) >> I_OPCODE_offCOP0)
-
-#endif /* __NDS32_FPU_INST_H */
diff --git a/arch/nds32/include/asm/page.h b/arch/nds32/include/asm/page.h
deleted file mode 100644
index add33a7f02c8..000000000000
--- a/arch/nds32/include/asm/page.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C) 2005-2017 Andes Technology Corporation
- */
-
-#ifndef _ASMNDS32_PAGE_H
-#define _ASMNDS32_PAGE_H
-
-#ifdef CONFIG_ANDES_PAGE_SIZE_4KB
-#define PAGE_SHIFT 12
-#endif
-#ifdef CONFIG_ANDES_PAGE_SIZE_8KB
-#define PAGE_SHIFT 13
-#endif
-#include <linux/const.h>
-#define PAGE_SIZE (_AC(1,UL) << PAGE_SHIFT)
-#define PAGE_MASK (~(PAGE_SIZE-1))
-
-#ifdef __KERNEL__
-
-#ifndef __ASSEMBLY__
-
-struct page;
-struct vm_area_struct;
-#ifdef CONFIG_CPU_CACHE_ALIASING
-extern void copy_user_highpage(struct page *to, struct page *from,
- unsigned long vaddr, struct vm_area_struct *vma);
-extern void clear_user_highpage(struct page *page, unsigned long vaddr);
-
-void copy_user_page(void *vto, void *vfrom, unsigned long vaddr,
- struct page *to);
-void clear_user_page(void *addr, unsigned long vaddr, struct page *page);
-#define __HAVE_ARCH_COPY_USER_HIGHPAGE
-#define clear_user_highpage clear_user_highpage
-#else
-#define clear_user_page(page, vaddr, pg) clear_page(page)
-#define copy_user_page(to, from, vaddr, pg) copy_page(to, from)
-#endif
-
-void clear_page(void *page);
-void copy_page(void *to, void *from);
-
-typedef unsigned long pte_t;
-typedef unsigned long pgd_t;
-typedef unsigned long pgprot_t;
-
-#define pte_val(x) (x)
-#define pgd_val(x) (x)
-#define pgprot_val(x) (x)
-
-#define __pte(x) (x)
-#define __pgd(x) (x)
-#define __pgprot(x) (x)
-
-typedef struct page *pgtable_t;
-
-#include <asm/memory.h>
-#include <asm-generic/getorder.h>
-
-#endif /* !__ASSEMBLY__ */
-
-#endif /* __KERNEL__ */
-
-#endif
diff --git a/arch/nds32/include/asm/perf_event.h b/arch/nds32/include/asm/perf_event.h
deleted file mode 100644
index fcdff02acc14..000000000000
--- a/arch/nds32/include/asm/perf_event.h
+++ /dev/null
@@ -1,16 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/* Copyright (C) 2008-2018 Andes Technology Corporation */
-
-#ifndef __ASM_PERF_EVENT_H
-#define __ASM_PERF_EVENT_H
-
-/*
- * This file is request by Perf,
- * please refer to tools/perf/design.txt for more details
- */
-struct pt_regs;
-unsigned long perf_instruction_pointer(struct pt_regs *regs);
-unsigned long perf_misc_flags(struct pt_regs *regs);
-#define perf_misc_flags(regs) perf_misc_flags(regs)
-
-#endif
diff --git a/arch/nds32/include/asm/pgalloc.h b/arch/nds32/include/asm/pgalloc.h
deleted file mode 100644
index a08e1ebca70e..000000000000
--- a/arch/nds32/include/asm/pgalloc.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-// Copyright (C) 2005-2017 Andes Technology Corporation
-
-#ifndef _ASMNDS32_PGALLOC_H
-#define _ASMNDS32_PGALLOC_H
-
-#include <asm/processor.h>
-#include <asm/cacheflush.h>
-#include <asm/tlbflush.h>
-#include <asm/proc-fns.h>
-
-#define __HAVE_ARCH_PTE_ALLOC_ONE
-#include <asm-generic/pgalloc.h> /* for pte_{alloc,free}_one */
-
-extern pgd_t *pgd_alloc(struct mm_struct *mm);
-extern void pgd_free(struct mm_struct *mm, pgd_t * pgd);
-
-static inline pgtable_t pte_alloc_one(struct mm_struct *mm)
-{
- pgtable_t pte;
-
- pte = __pte_alloc_one(mm, GFP_PGTABLE_USER);
- if (pte)
- cpu_dcache_wb_page((unsigned long)page_address(pte));
-
- return pte;
-}
-
-/*
- * Populate the pmdp entry with a pointer to the pte. This pmd is part
- * of the mm address space.
- *
- * Ensure that we always set both PMD entries.
- */
-static inline void
-pmd_populate_kernel(struct mm_struct *mm, pmd_t * pmdp, pte_t * ptep)
-{
- unsigned long pte_ptr = (unsigned long)ptep;
- unsigned long pmdval;
-
- BUG_ON(mm != &init_mm);
-
- /*
- * The pmd must be loaded with the physical
- * address of the PTE table
- */
- pmdval = __pa(pte_ptr) | _PAGE_KERNEL_TABLE;
- set_pmd(pmdp, __pmd(pmdval));
-}
-
-static inline void
-pmd_populate(struct mm_struct *mm, pmd_t * pmdp, pgtable_t ptep)
-{
- unsigned long pmdval;
-
- BUG_ON(mm == &init_mm);
-
- pmdval = page_to_pfn(ptep) << PAGE_SHIFT | _PAGE_USER_TABLE;
- set_pmd(pmdp, __pmd(pmdval));
-}
-
-#endif
diff --git a/arch/nds32/include/asm/pgtable.h b/arch/nds32/include/asm/pgtable.h
deleted file mode 100644
index 419f984eef70..000000000000
--- a/arch/nds32/include/asm/pgtable.h
+++ /dev/null
@@ -1,377 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-// Copyright (C) 2005-2017 Andes Technology Corporation
-
-#ifndef _ASMNDS32_PGTABLE_H
-#define _ASMNDS32_PGTABLE_H
-
-#include <asm-generic/pgtable-nopmd.h>
-#include <linux/sizes.h>
-
-#include <asm/memory.h>
-#include <asm/nds32.h>
-#ifndef __ASSEMBLY__
-#include <asm/fixmap.h>
-#include <nds32_intrinsic.h>
-#endif
-
-#ifdef CONFIG_ANDES_PAGE_SIZE_4KB
-#define PGDIR_SHIFT 22
-#define PTRS_PER_PGD 1024
-#define PTRS_PER_PTE 1024
-#endif
-
-#ifdef CONFIG_ANDES_PAGE_SIZE_8KB
-#define PGDIR_SHIFT 24
-#define PTRS_PER_PGD 256
-#define PTRS_PER_PTE 2048
-#endif
-
-#ifndef __ASSEMBLY__
-extern void __pte_error(const char *file, int line, unsigned long val);
-extern void __pgd_error(const char *file, int line, unsigned long val);
-
-#define pte_ERROR(pte) __pte_error(__FILE__, __LINE__, pte_val(pte))
-#define pgd_ERROR(pgd) __pgd_error(__FILE__, __LINE__, pgd_val(pgd))
-#endif /* !__ASSEMBLY__ */
-
-#define PMD_SIZE (1UL << PMD_SHIFT)
-#define PMD_MASK (~(PMD_SIZE-1))
-#define PGDIR_SIZE (1UL << PGDIR_SHIFT)
-#define PGDIR_MASK (~(PGDIR_SIZE-1))
-
-/*
- * This is the lowest virtual address we can permit any user space
- * mapping to be mapped at. This is particularly important for
- * non-high vector CPUs.
- */
-#define FIRST_USER_ADDRESS 0x8000
-
-#ifdef CONFIG_HIGHMEM
-#define CONSISTENT_BASE ((PKMAP_BASE) - (SZ_2M))
-#define CONSISTENT_END (PKMAP_BASE)
-#else
-#define CONSISTENT_BASE (FIXADDR_START - SZ_2M)
-#define CONSISTENT_END (FIXADDR_START)
-#endif
-#define CONSISTENT_OFFSET(x) (((unsigned long)(x) - CONSISTENT_BASE) >> PAGE_SHIFT)
-
-#ifdef CONFIG_HIGHMEM
-#ifndef __ASSEMBLY__
-#include <asm/highmem.h>
-#endif
-#endif
-
-#define VMALLOC_RESERVE SZ_128M
-#define VMALLOC_END (CONSISTENT_BASE - PAGE_SIZE)
-#define VMALLOC_START ((VMALLOC_END) - VMALLOC_RESERVE)
-#define VMALLOC_VMADDR(x) ((unsigned long)(x))
-#define MAXMEM __pa(VMALLOC_START)
-#define MAXMEM_PFN PFN_DOWN(MAXMEM)
-
-#define FIRST_USER_PGD_NR 0
-#define USER_PTRS_PER_PGD ((TASK_SIZE/PGDIR_SIZE) + FIRST_USER_PGD_NR)
-
-/* L2 PTE */
-#define _PAGE_V (1UL << 0)
-
-#define _PAGE_M_XKRW (0UL << 1)
-#define _PAGE_M_UR_KR (1UL << 1)
-#define _PAGE_M_UR_KRW (2UL << 1)
-#define _PAGE_M_URW_KRW (3UL << 1)
-#define _PAGE_M_KR (5UL << 1)
-#define _PAGE_M_KRW (7UL << 1)
-
-#define _PAGE_D (1UL << 4)
-#define _PAGE_E (1UL << 5)
-#define _PAGE_A (1UL << 6)
-#define _PAGE_G (1UL << 7)
-
-#define _PAGE_C_DEV (0UL << 8)
-#define _PAGE_C_DEV_WB (1UL << 8)
-#define _PAGE_C_MEM (2UL << 8)
-#define _PAGE_C_MEM_SHRD_WB (4UL << 8)
-#define _PAGE_C_MEM_SHRD_WT (5UL << 8)
-#define _PAGE_C_MEM_WB (6UL << 8)
-#define _PAGE_C_MEM_WT (7UL << 8)
-
-#define _PAGE_L (1UL << 11)
-
-#define _HAVE_PAGE_L (_PAGE_L)
-#define _PAGE_FILE (1UL << 1)
-#define _PAGE_YOUNG 0
-#define _PAGE_M_MASK _PAGE_M_KRW
-#define _PAGE_C_MASK _PAGE_C_MEM_WT
-
-#ifdef CONFIG_SMP
-#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
-#define _PAGE_CACHE_SHRD _PAGE_C_MEM_SHRD_WT
-#else
-#define _PAGE_CACHE_SHRD _PAGE_C_MEM_SHRD_WB
-#endif
-#else
-#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
-#define _PAGE_CACHE_SHRD _PAGE_C_MEM_WT
-#else
-#define _PAGE_CACHE_SHRD _PAGE_C_MEM_WB
-#endif
-#endif
-
-#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
-#define _PAGE_CACHE _PAGE_C_MEM_WT
-#else
-#define _PAGE_CACHE _PAGE_C_MEM_WB
-#endif
-
-#define _PAGE_IOREMAP \
- (_PAGE_V | _PAGE_M_KRW | _PAGE_D | _PAGE_G | _PAGE_C_DEV)
-
-/*
- * + Level 1 descriptor (PMD)
- */
-#define PMD_TYPE_TABLE 0
-
-#ifndef __ASSEMBLY__
-
-#define _PAGE_USER_TABLE PMD_TYPE_TABLE
-#define _PAGE_KERNEL_TABLE PMD_TYPE_TABLE
-
-#define PAGE_EXEC __pgprot(_PAGE_V | _PAGE_M_XKRW | _PAGE_E)
-#define PAGE_NONE __pgprot(_PAGE_V | _PAGE_M_KRW | _PAGE_A)
-#define PAGE_READ __pgprot(_PAGE_V | _PAGE_M_UR_KR)
-#define PAGE_RDWR __pgprot(_PAGE_V | _PAGE_M_URW_KRW | _PAGE_D)
-#define PAGE_COPY __pgprot(_PAGE_V | _PAGE_M_UR_KR)
-
-#define PAGE_UXKRWX_V1 __pgprot(_PAGE_V | _PAGE_M_KRW | _PAGE_D | _PAGE_E | _PAGE_G | _PAGE_CACHE_SHRD)
-#define PAGE_UXKRWX_V2 __pgprot(_PAGE_V | _PAGE_M_XKRW | _PAGE_D | _PAGE_E | _PAGE_G | _PAGE_CACHE_SHRD)
-#define PAGE_URXKRWX_V2 __pgprot(_PAGE_V | _PAGE_M_UR_KRW | _PAGE_D | _PAGE_E | _PAGE_G | _PAGE_CACHE_SHRD)
-#define PAGE_CACHE_L1 __pgprot(_HAVE_PAGE_L | _PAGE_V | _PAGE_M_KRW | _PAGE_D | _PAGE_E | _PAGE_G | _PAGE_CACHE)
-#define PAGE_MEMORY __pgprot(_HAVE_PAGE_L | _PAGE_V | _PAGE_M_KRW | _PAGE_D | _PAGE_E | _PAGE_G | _PAGE_CACHE_SHRD)
-#define PAGE_KERNEL __pgprot(_PAGE_V | _PAGE_M_KRW | _PAGE_D | _PAGE_E | _PAGE_G | _PAGE_CACHE_SHRD)
-#define PAGE_SHARED __pgprot(_PAGE_V | _PAGE_M_URW_KRW | _PAGE_D | _PAGE_CACHE_SHRD)
-#define PAGE_DEVICE __pgprot(_PAGE_V | _PAGE_M_KRW | _PAGE_D | _PAGE_G | _PAGE_C_DEV)
-#endif /* __ASSEMBLY__ */
-
-/* xwr */
-#define __P000 (PAGE_NONE | _PAGE_CACHE_SHRD)
-#define __P001 (PAGE_READ | _PAGE_CACHE_SHRD)
-#define __P010 (PAGE_COPY | _PAGE_CACHE_SHRD)
-#define __P011 (PAGE_COPY | _PAGE_CACHE_SHRD)
-#define __P100 (PAGE_EXEC | _PAGE_CACHE_SHRD)
-#define __P101 (PAGE_READ | _PAGE_E | _PAGE_CACHE_SHRD)
-#define __P110 (PAGE_COPY | _PAGE_E | _PAGE_CACHE_SHRD)
-#define __P111 (PAGE_COPY | _PAGE_E | _PAGE_CACHE_SHRD)
-
-#define __S000 (PAGE_NONE | _PAGE_CACHE_SHRD)
-#define __S001 (PAGE_READ | _PAGE_CACHE_SHRD)
-#define __S010 (PAGE_RDWR | _PAGE_CACHE_SHRD)
-#define __S011 (PAGE_RDWR | _PAGE_CACHE_SHRD)
-#define __S100 (PAGE_EXEC | _PAGE_CACHE_SHRD)
-#define __S101 (PAGE_READ | _PAGE_E | _PAGE_CACHE_SHRD)
-#define __S110 (PAGE_RDWR | _PAGE_E | _PAGE_CACHE_SHRD)
-#define __S111 (PAGE_RDWR | _PAGE_E | _PAGE_CACHE_SHRD)
-
-#ifndef __ASSEMBLY__
-/*
- * ZERO_PAGE is a global shared page that is always zero: used
- * for zero-mapped memory areas etc..
- */
-extern struct page *empty_zero_page;
-extern void paging_init(void);
-#define ZERO_PAGE(vaddr) (empty_zero_page)
-
-#define pte_pfn(pte) (pte_val(pte) >> PAGE_SHIFT)
-#define pfn_pte(pfn,prot) (__pte(((pfn) << PAGE_SHIFT) | pgprot_val(prot)))
-
-#define pte_none(pte) !(pte_val(pte))
-#define pte_clear(mm,addr,ptep) set_pte_at((mm),(addr),(ptep), __pte(0))
-#define pte_page(pte) (pfn_to_page(pte_pfn(pte)))
-
-static unsigned long pmd_page_vaddr(pmd_t pmd)
-{
- return ((unsigned long) __va(pmd_val(pmd) & PAGE_MASK));
-}
-
-#define set_pte_at(mm,addr,ptep,pteval) set_pte(ptep,pteval)
-/*
- * Set a level 1 translation table entry, and clean it out of
- * any caches such that the MMUs can load it correctly.
- */
-static inline void set_pmd(pmd_t * pmdp, pmd_t pmd)
-{
-
- *pmdp = pmd;
-#if !defined(CONFIG_CPU_DCACHE_DISABLE) && !defined(CONFIG_CPU_DCACHE_WRITETHROUGH)
- __asm__ volatile ("\n\tcctl %0, L1D_VA_WB"::"r" (pmdp):"memory");
- __nds32__msync_all();
- __nds32__dsb();
-#endif
-}
-
-/*
- * Set a PTE and flush it out
- */
-static inline void set_pte(pte_t * ptep, pte_t pte)
-{
-
- *ptep = pte;
-#if !defined(CONFIG_CPU_DCACHE_DISABLE) && !defined(CONFIG_CPU_DCACHE_WRITETHROUGH)
- __asm__ volatile ("\n\tcctl %0, L1D_VA_WB"::"r" (ptep):"memory");
- __nds32__msync_all();
- __nds32__dsb();
-#endif
-}
-
-/*
- * The following only work if pte_present() is true.
- * Undefined behaviour if not..
- */
-
-/*
- * pte_write: this page is writeable for user mode
- * pte_read: this page is readable for user mode
- * pte_kernel_write: this page is writeable for kernel mode
- *
- * We don't have pte_kernel_read because kernel always can read.
- *
- * */
-
-#define pte_present(pte) (pte_val(pte) & _PAGE_V)
-#define pte_write(pte) ((pte_val(pte) & _PAGE_M_MASK) == _PAGE_M_URW_KRW)
-#define pte_read(pte) (((pte_val(pte) & _PAGE_M_MASK) == _PAGE_M_UR_KR) || \
- ((pte_val(pte) & _PAGE_M_MASK) == _PAGE_M_UR_KRW) || \
- ((pte_val(pte) & _PAGE_M_MASK) == _PAGE_M_URW_KRW))
-#define pte_kernel_write(pte) (((pte_val(pte) & _PAGE_M_MASK) == _PAGE_M_URW_KRW) || \
- ((pte_val(pte) & _PAGE_M_MASK) == _PAGE_M_UR_KRW) || \
- ((pte_val(pte) & _PAGE_M_MASK) == _PAGE_M_KRW) || \
- (((pte_val(pte) & _PAGE_M_MASK) == _PAGE_M_XKRW) && pte_exec(pte)))
-#define pte_exec(pte) (pte_val(pte) & _PAGE_E)
-#define pte_dirty(pte) (pte_val(pte) & _PAGE_D)
-#define pte_young(pte) (pte_val(pte) & _PAGE_YOUNG)
-
-/*
- * The following only works if pte_present() is not true.
- */
-#define pte_file(pte) (pte_val(pte) & _PAGE_FILE)
-#define pte_to_pgoff(x) (pte_val(x) >> 2)
-#define pgoff_to_pte(x) __pte(((x) << 2) | _PAGE_FILE)
-
-#define PTE_FILE_MAX_BITS 29
-
-#define PTE_BIT_FUNC(fn,op) \
-static inline pte_t pte_##fn(pte_t pte) { pte_val(pte) op; return pte; }
-
-static inline pte_t pte_wrprotect(pte_t pte)
-{
- pte_val(pte) = pte_val(pte) & ~_PAGE_M_MASK;
- pte_val(pte) = pte_val(pte) | _PAGE_M_UR_KR;
- return pte;
-}
-
-static inline pte_t pte_mkwrite(pte_t pte)
-{
- pte_val(pte) = pte_val(pte) & ~_PAGE_M_MASK;
- pte_val(pte) = pte_val(pte) | _PAGE_M_URW_KRW;
- return pte;
-}
-
-PTE_BIT_FUNC(exprotect, &=~_PAGE_E);
-PTE_BIT_FUNC(mkexec, |=_PAGE_E);
-PTE_BIT_FUNC(mkclean, &=~_PAGE_D);
-PTE_BIT_FUNC(mkdirty, |=_PAGE_D);
-PTE_BIT_FUNC(mkold, &=~_PAGE_YOUNG);
-PTE_BIT_FUNC(mkyoung, |=_PAGE_YOUNG);
-
-/*
- * Mark the prot value as uncacheable and unbufferable.
- */
-#define pgprot_noncached(prot) __pgprot((pgprot_val(prot)&~_PAGE_C_MASK) | _PAGE_C_DEV)
-#define pgprot_writecombine(prot) __pgprot((pgprot_val(prot)&~_PAGE_C_MASK) | _PAGE_C_DEV_WB)
-
-#define pmd_none(pmd) (pmd_val(pmd)&0x1)
-#define pmd_present(pmd) (!pmd_none(pmd))
-#define pmd_bad(pmd) pmd_none(pmd)
-
-#define copy_pmd(pmdpd,pmdps) set_pmd((pmdpd), *(pmdps))
-#define pmd_clear(pmdp) set_pmd((pmdp), __pmd(1))
-
-static inline pmd_t __mk_pmd(pte_t * ptep, unsigned long prot)
-{
- unsigned long ptr = (unsigned long)ptep;
- pmd_t pmd;
-
- /*
- * The pmd must be loaded with the physical
- * address of the PTE table
- */
-
- pmd_val(pmd) = __virt_to_phys(ptr) | prot;
- return pmd;
-}
-
-#define pmd_page(pmd) virt_to_page(__va(pmd_val(pmd)))
-
-/*
- * Permanent address of a page. We never have highmem, so this is trivial.
- */
-#define pages_to_mb(x) ((x) >> (20 - PAGE_SHIFT))
-
-/*
- * Conversion functions: convert a page and protection to a page entry,
- * and a page entry and page directory to the page they refer to.
- */
-#define mk_pte(page,prot) pfn_pte(page_to_pfn(page),prot)
-
-/*
- * The "pgd_xxx()" functions here are trivial for a folded two-level
- * setup: the pgd is never bad, and a pmd always exists (as it's folded
- * into the pgd entry)
- */
-#define pgd_none(pgd) (0)
-#define pgd_bad(pgd) (0)
-#define pgd_present(pgd) (1)
-#define pgd_clear(pgdp) do { } while (0)
-
-#define page_pte_prot(page,prot) mk_pte(page, prot)
-#define page_pte(page) mk_pte(page, __pgprot(0))
-/*
- * L1PTE = $mr1 + ((virt >> PMD_SHIFT) << 2);
- * L2PTE = (((virt >> PAGE_SHIFT) & (PTRS_PER_PTE -1 )) << 2);
- * PPN = (phys & 0xfffff000);
- *
-*/
-
-static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
-{
- const unsigned long mask = 0xfff;
- pte_val(pte) = (pte_val(pte) & ~mask) | (pgprot_val(newprot) & mask);
- return pte;
-}
-
-extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
-
-/* Encode and decode a swap entry.
- *
- * We support up to 32GB of swap on 4k machines
- */
-#define __swp_type(x) (((x).val >> 2) & 0x7f)
-#define __swp_offset(x) ((x).val >> 9)
-#define __swp_entry(type,offset) ((swp_entry_t) { ((type) << 2) | ((offset) << 9) })
-#define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) })
-#define __swp_entry_to_pte(swp) ((pte_t) { (swp).val })
-
-/* Needs to be defined here and not in linux/mm.h, as it is arch dependent */
-#define kern_addr_valid(addr) (1)
-
-/*
- * We provide our own arch_get_unmapped_area to cope with VIPT caches.
- */
-#define HAVE_ARCH_UNMAPPED_AREA
-
-/*
- * remap a physical address `phys' of size `size' with page protection `prot'
- * into virtual address `from'
- */
-
-#endif /* !__ASSEMBLY__ */
-
-#endif /* _ASMNDS32_PGTABLE_H */
diff --git a/arch/nds32/include/asm/pmu.h b/arch/nds32/include/asm/pmu.h
deleted file mode 100644
index e1ac0b0b8bcf..000000000000
--- a/arch/nds32/include/asm/pmu.h
+++ /dev/null
@@ -1,386 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/* Copyright (C) 2008-2018 Andes Technology Corporation */
-
-#ifndef __ASM_PMU_H
-#define __ASM_PMU_H
-
-#include <linux/interrupt.h>
-#include <linux/perf_event.h>
-#include <asm/unistd.h>
-#include <asm/bitfield.h>
-
-/* Has special meaning for perf core implementation */
-#define HW_OP_UNSUPPORTED 0x0
-#define C(_x) PERF_COUNT_HW_CACHE_##_x
-#define CACHE_OP_UNSUPPORTED 0x0
-
-/* Enough for both software and hardware defined events */
-#define SOFTWARE_EVENT_MASK 0xFF
-
-#define PFM_OFFSET_MAGIC_0 2 /* DO NOT START FROM 0 */
-#define PFM_OFFSET_MAGIC_1 (PFM_OFFSET_MAGIC_0 + 36)
-#define PFM_OFFSET_MAGIC_2 (PFM_OFFSET_MAGIC_1 + 36)
-
-enum { PFMC0, PFMC1, PFMC2, MAX_COUNTERS };
-
-u32 PFM_CTL_OVF[3] = { PFM_CTL_mskOVF0, PFM_CTL_mskOVF1,
- PFM_CTL_mskOVF2 };
-u32 PFM_CTL_EN[3] = { PFM_CTL_mskEN0, PFM_CTL_mskEN1,
- PFM_CTL_mskEN2 };
-u32 PFM_CTL_OFFSEL[3] = { PFM_CTL_offSEL0, PFM_CTL_offSEL1,
- PFM_CTL_offSEL2 };
-u32 PFM_CTL_IE[3] = { PFM_CTL_mskIE0, PFM_CTL_mskIE1, PFM_CTL_mskIE2 };
-u32 PFM_CTL_KS[3] = { PFM_CTL_mskKS0, PFM_CTL_mskKS1, PFM_CTL_mskKS2 };
-u32 PFM_CTL_KU[3] = { PFM_CTL_mskKU0, PFM_CTL_mskKU1, PFM_CTL_mskKU2 };
-u32 PFM_CTL_SEL[3] = { PFM_CTL_mskSEL0, PFM_CTL_mskSEL1, PFM_CTL_mskSEL2 };
-/*
- * Perf Events' indices
- */
-#define NDS32_IDX_CYCLE_COUNTER 0
-#define NDS32_IDX_COUNTER0 1
-#define NDS32_IDX_COUNTER1 2
-
-/* The events for a given PMU register set. */
-struct pmu_hw_events {
- /*
- * The events that are active on the PMU for the given index.
- */
- struct perf_event *events[MAX_COUNTERS];
-
- /*
- * A 1 bit for an index indicates that the counter is being used for
- * an event. A 0 means that the counter can be used.
- */
- unsigned long used_mask[BITS_TO_LONGS(MAX_COUNTERS)];
-
- /*
- * Hardware lock to serialize accesses to PMU registers. Needed for the
- * read/modify/write sequences.
- */
- raw_spinlock_t pmu_lock;
-};
-
-struct nds32_pmu {
- struct pmu pmu;
- cpumask_t active_irqs;
- char *name;
- irqreturn_t (*handle_irq)(int irq_num, void *dev);
- void (*enable)(struct perf_event *event);
- void (*disable)(struct perf_event *event);
- int (*get_event_idx)(struct pmu_hw_events *hw_events,
- struct perf_event *event);
- int (*set_event_filter)(struct hw_perf_event *evt,
- struct perf_event_attr *attr);
- u32 (*read_counter)(struct perf_event *event);
- void (*write_counter)(struct perf_event *event, u32 val);
- void (*start)(struct nds32_pmu *nds32_pmu);
- void (*stop)(struct nds32_pmu *nds32_pmu);
- void (*reset)(void *data);
- int (*request_irq)(struct nds32_pmu *nds32_pmu, irq_handler_t handler);
- void (*free_irq)(struct nds32_pmu *nds32_pmu);
- int (*map_event)(struct perf_event *event);
- int num_events;
- atomic_t active_events;
- u64 max_period;
- struct platform_device *plat_device;
- struct pmu_hw_events *(*get_hw_events)(void);
-};
-
-#define to_nds32_pmu(p) (container_of(p, struct nds32_pmu, pmu))
-
-int nds32_pmu_register(struct nds32_pmu *nds32_pmu, int type);
-
-u64 nds32_pmu_event_update(struct perf_event *event);
-
-int nds32_pmu_event_set_period(struct perf_event *event);
-
-/*
- * Common NDS32 SPAv3 event types
- *
- * Note: An implementation may not be able to count all of these events
- * but the encodings are considered to be `reserved' in the case that
- * they are not available.
- *
- * SEL_TOTAL_CYCLES will add an offset is due to ZERO is defined as
- * NOT_SUPPORTED EVENT mapping in generic perf code.
- * You will need to deal it in the event writing implementation.
- */
-enum spav3_counter_0_perf_types {
- SPAV3_0_SEL_BASE = -1 + PFM_OFFSET_MAGIC_0, /* counting symbol */
- SPAV3_0_SEL_TOTAL_CYCLES = 0 + PFM_OFFSET_MAGIC_0,
- SPAV3_0_SEL_COMPLETED_INSTRUCTION = 1 + PFM_OFFSET_MAGIC_0,
- SPAV3_0_SEL_LAST /* counting symbol */
-};
-
-enum spav3_counter_1_perf_types {
- SPAV3_1_SEL_BASE = -1 + PFM_OFFSET_MAGIC_1, /* counting symbol */
- SPAV3_1_SEL_TOTAL_CYCLES = 0 + PFM_OFFSET_MAGIC_1,
- SPAV3_1_SEL_COMPLETED_INSTRUCTION = 1 + PFM_OFFSET_MAGIC_1,
- SPAV3_1_SEL_CONDITIONAL_BRANCH = 2 + PFM_OFFSET_MAGIC_1,
- SPAV3_1_SEL_TAKEN_CONDITIONAL_BRANCH = 3 + PFM_OFFSET_MAGIC_1,
- SPAV3_1_SEL_PREFETCH_INSTRUCTION = 4 + PFM_OFFSET_MAGIC_1,
- SPAV3_1_SEL_RET_INST = 5 + PFM_OFFSET_MAGIC_1,
- SPAV3_1_SEL_JR_INST = 6 + PFM_OFFSET_MAGIC_1,
- SPAV3_1_SEL_JAL_JRAL_INST = 7 + PFM_OFFSET_MAGIC_1,
- SPAV3_1_SEL_NOP_INST = 8 + PFM_OFFSET_MAGIC_1,
- SPAV3_1_SEL_SCW_INST = 9 + PFM_OFFSET_MAGIC_1,
- SPAV3_1_SEL_ISB_DSB_INST = 10 + PFM_OFFSET_MAGIC_1,
- SPAV3_1_SEL_CCTL_INST = 11 + PFM_OFFSET_MAGIC_1,
- SPAV3_1_SEL_TAKEN_INTERRUPTS = 12 + PFM_OFFSET_MAGIC_1,
- SPAV3_1_SEL_LOADS_COMPLETED = 13 + PFM_OFFSET_MAGIC_1,
- SPAV3_1_SEL_UITLB_ACCESS = 14 + PFM_OFFSET_MAGIC_1,
- SPAV3_1_SEL_UDTLB_ACCESS = 15 + PFM_OFFSET_MAGIC_1,
- SPAV3_1_SEL_MTLB_ACCESS = 16 + PFM_OFFSET_MAGIC_1,
- SPAV3_1_SEL_CODE_CACHE_ACCESS = 17 + PFM_OFFSET_MAGIC_1,
- SPAV3_1_SEL_DATA_DEPENDENCY_STALL_CYCLES = 18 + PFM_OFFSET_MAGIC_1,
- SPAV3_1_SEL_DATA_CACHE_MISS_STALL_CYCLES = 19 + PFM_OFFSET_MAGIC_1,
- SPAV3_1_SEL_DATA_CACHE_ACCESS = 20 + PFM_OFFSET_MAGIC_1,
- SPAV3_1_SEL_DATA_CACHE_MISS = 21 + PFM_OFFSET_MAGIC_1,
- SPAV3_1_SEL_LOAD_DATA_CACHE_ACCESS = 22 + PFM_OFFSET_MAGIC_1,
- SPAV3_1_SEL_STORE_DATA_CACHE_ACCESS = 23 + PFM_OFFSET_MAGIC_1,
- SPAV3_1_SEL_ILM_ACCESS = 24 + PFM_OFFSET_MAGIC_1,
- SPAV3_1_SEL_LSU_BIU_CYCLES = 25 + PFM_OFFSET_MAGIC_1,
- SPAV3_1_SEL_HPTWK_BIU_CYCLES = 26 + PFM_OFFSET_MAGIC_1,
- SPAV3_1_SEL_DMA_BIU_CYCLES = 27 + PFM_OFFSET_MAGIC_1,
- SPAV3_1_SEL_CODE_CACHE_FILL_BIU_CYCLES = 28 + PFM_OFFSET_MAGIC_1,
- SPAV3_1_SEL_LEGAL_UNALIGN_DCACHE_ACCESS = 29 + PFM_OFFSET_MAGIC_1,
- SPAV3_1_SEL_PUSH25 = 30 + PFM_OFFSET_MAGIC_1,
- SPAV3_1_SEL_SYSCALLS_INST = 31 + PFM_OFFSET_MAGIC_1,
- SPAV3_1_SEL_LAST /* counting symbol */
-};
-
-enum spav3_counter_2_perf_types {
- SPAV3_2_SEL_BASE = -1 + PFM_OFFSET_MAGIC_2, /* counting symbol */
- SPAV3_2_SEL_TOTAL_CYCLES = 0 + PFM_OFFSET_MAGIC_2,
- SPAV3_2_SEL_COMPLETED_INSTRUCTION = 1 + PFM_OFFSET_MAGIC_2,
- SPAV3_2_SEL_CONDITIONAL_BRANCH_MISPREDICT = 2 + PFM_OFFSET_MAGIC_2,
- SPAV3_2_SEL_TAKEN_CONDITIONAL_BRANCH_MISPREDICT =
- 3 + PFM_OFFSET_MAGIC_2,
- SPAV3_2_SEL_PREFETCH_INSTRUCTION_CACHE_HIT = 4 + PFM_OFFSET_MAGIC_2,
- SPAV3_1_SEL_RET_MISPREDICT = 5 + PFM_OFFSET_MAGIC_2,
- SPAV3_1_SEL_IMMEDIATE_J_INST = 6 + PFM_OFFSET_MAGIC_2,
- SPAV3_1_SEL_MULTIPLY_INST = 7 + PFM_OFFSET_MAGIC_2,
- SPAV3_1_SEL_16_BIT_INST = 8 + PFM_OFFSET_MAGIC_2,
- SPAV3_1_SEL_FAILED_SCW_INST = 9 + PFM_OFFSET_MAGIC_2,
- SPAV3_1_SEL_LD_AFTER_ST_CONFLICT_REPLAYS = 10 + PFM_OFFSET_MAGIC_2,
- SPAV3_1_SEL_TAKEN_EXCEPTIONS = 12 + PFM_OFFSET_MAGIC_2,
- SPAV3_1_SEL_STORES_COMPLETED = 13 + PFM_OFFSET_MAGIC_2,
- SPAV3_2_SEL_UITLB_MISS = 14 + PFM_OFFSET_MAGIC_2,
- SPAV3_2_SEL_UDTLB_MISS = 15 + PFM_OFFSET_MAGIC_2,
- SPAV3_2_SEL_MTLB_MISS = 16 + PFM_OFFSET_MAGIC_2,
- SPAV3_2_SEL_CODE_CACHE_MISS = 17 + PFM_OFFSET_MAGIC_2,
- SPAV3_1_SEL_EMPTY_INST_QUEUE_STALL_CYCLES = 18 + PFM_OFFSET_MAGIC_2,
- SPAV3_1_SEL_DATA_WRITE_BACK = 19 + PFM_OFFSET_MAGIC_2,
- SPAV3_2_SEL_DATA_CACHE_MISS = 21 + PFM_OFFSET_MAGIC_2,
- SPAV3_2_SEL_LOAD_DATA_CACHE_MISS = 22 + PFM_OFFSET_MAGIC_2,
- SPAV3_2_SEL_STORE_DATA_CACHE_MISS = 23 + PFM_OFFSET_MAGIC_2,
- SPAV3_1_SEL_DLM_ACCESS = 24 + PFM_OFFSET_MAGIC_2,
- SPAV3_1_SEL_LSU_BIU_REQUEST = 25 + PFM_OFFSET_MAGIC_2,
- SPAV3_1_SEL_HPTWK_BIU_REQUEST = 26 + PFM_OFFSET_MAGIC_2,
- SPAV3_1_SEL_DMA_BIU_REQUEST = 27 + PFM_OFFSET_MAGIC_2,
- SPAV3_1_SEL_CODE_CACHE_FILL_BIU_REQUEST = 28 + PFM_OFFSET_MAGIC_2,
- SPAV3_1_SEL_EXTERNAL_EVENTS = 29 + PFM_OFFSET_MAGIC_2,
- SPAV3_1_SEL_POP25 = 30 + PFM_OFFSET_MAGIC_2,
- SPAV3_2_SEL_LAST /* counting symbol */
-};
-
-/* Get converted event counter index */
-static inline int get_converted_event_idx(unsigned long event)
-{
- int idx;
-
- if ((event) > SPAV3_0_SEL_BASE && event < SPAV3_0_SEL_LAST) {
- idx = 0;
- } else if ((event) > SPAV3_1_SEL_BASE && event < SPAV3_1_SEL_LAST) {
- idx = 1;
- } else if ((event) > SPAV3_2_SEL_BASE && event < SPAV3_2_SEL_LAST) {
- idx = 2;
- } else {
- pr_err("GET_CONVERTED_EVENT_IDX PFM counter range error\n");
- return -EPERM;
- }
-
- return idx;
-}
-
-/* Get converted hardware event number */
-static inline u32 get_converted_evet_hw_num(u32 event)
-{
- if (event > SPAV3_0_SEL_BASE && event < SPAV3_0_SEL_LAST)
- event -= PFM_OFFSET_MAGIC_0;
- else if (event > SPAV3_1_SEL_BASE && event < SPAV3_1_SEL_LAST)
- event -= PFM_OFFSET_MAGIC_1;
- else if (event > SPAV3_2_SEL_BASE && event < SPAV3_2_SEL_LAST)
- event -= PFM_OFFSET_MAGIC_2;
- else if (event != 0)
- pr_err("GET_CONVERTED_EVENT_HW_NUM PFM counter range error\n");
-
- return event;
-}
-
-/*
- * NDS32 HW events mapping
- *
- * The hardware events that we support. We do support cache operations but
- * we have harvard caches and no way to combine instruction and data
- * accesses/misses in hardware.
- */
-static const unsigned int nds32_pfm_perf_map[PERF_COUNT_HW_MAX] = {
- [PERF_COUNT_HW_CPU_CYCLES] = SPAV3_0_SEL_TOTAL_CYCLES,
- [PERF_COUNT_HW_INSTRUCTIONS] = SPAV3_1_SEL_COMPLETED_INSTRUCTION,
- [PERF_COUNT_HW_CACHE_REFERENCES] = SPAV3_1_SEL_DATA_CACHE_ACCESS,
- [PERF_COUNT_HW_CACHE_MISSES] = SPAV3_2_SEL_DATA_CACHE_MISS,
- [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = HW_OP_UNSUPPORTED,
- [PERF_COUNT_HW_BRANCH_MISSES] = HW_OP_UNSUPPORTED,
- [PERF_COUNT_HW_BUS_CYCLES] = HW_OP_UNSUPPORTED,
- [PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = HW_OP_UNSUPPORTED,
- [PERF_COUNT_HW_STALLED_CYCLES_BACKEND] = HW_OP_UNSUPPORTED,
- [PERF_COUNT_HW_REF_CPU_CYCLES] = HW_OP_UNSUPPORTED
-};
-
-static const unsigned int nds32_pfm_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
- [PERF_COUNT_HW_CACHE_OP_MAX]
- [PERF_COUNT_HW_CACHE_RESULT_MAX] = {
- [C(L1D)] = {
- [C(OP_READ)] = {
- [C(RESULT_ACCESS)] =
- SPAV3_1_SEL_LOAD_DATA_CACHE_ACCESS,
- [C(RESULT_MISS)] =
- SPAV3_2_SEL_LOAD_DATA_CACHE_MISS,
- },
- [C(OP_WRITE)] = {
- [C(RESULT_ACCESS)] =
- SPAV3_1_SEL_STORE_DATA_CACHE_ACCESS,
- [C(RESULT_MISS)] =
- SPAV3_2_SEL_STORE_DATA_CACHE_MISS,
- },
- [C(OP_PREFETCH)] = {
- [C(RESULT_ACCESS)] =
- CACHE_OP_UNSUPPORTED,
- [C(RESULT_MISS)] =
- CACHE_OP_UNSUPPORTED,
- },
- },
- [C(L1I)] = {
- [C(OP_READ)] = {
- [C(RESULT_ACCESS)] =
- SPAV3_1_SEL_CODE_CACHE_ACCESS,
- [C(RESULT_MISS)] =
- SPAV3_2_SEL_CODE_CACHE_MISS,
- },
- [C(OP_WRITE)] = {
- [C(RESULT_ACCESS)] =
- SPAV3_1_SEL_CODE_CACHE_ACCESS,
- [C(RESULT_MISS)] =
- SPAV3_2_SEL_CODE_CACHE_MISS,
- },
- [C(OP_PREFETCH)] = {
- [C(RESULT_ACCESS)] =
- CACHE_OP_UNSUPPORTED,
- [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
- },
- },
- /* TODO: L2CC */
- [C(LL)] = {
- [C(OP_READ)] = {
- [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
- [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
- },
- [C(OP_WRITE)] = {
- [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
- [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
- },
- [C(OP_PREFETCH)] = {
- [C(RESULT_ACCESS)] =
- CACHE_OP_UNSUPPORTED,
- [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
- },
- },
- /* NDS32 PMU does not support TLB read/write hit/miss,
- * However, it can count access/miss, which mixed with read and write.
- * Therefore, only READ counter will use it.
- * We do as possible as we can.
- */
- [C(DTLB)] = {
- [C(OP_READ)] = {
- [C(RESULT_ACCESS)] =
- SPAV3_1_SEL_UDTLB_ACCESS,
- [C(RESULT_MISS)] =
- SPAV3_2_SEL_UDTLB_MISS,
- },
- [C(OP_WRITE)] = {
- [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
- [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
- },
- [C(OP_PREFETCH)] = {
- [C(RESULT_ACCESS)] =
- CACHE_OP_UNSUPPORTED,
- [C(RESULT_MISS)] =
- CACHE_OP_UNSUPPORTED,
- },
- },
- [C(ITLB)] = {
- [C(OP_READ)] = {
- [C(RESULT_ACCESS)] =
- SPAV3_1_SEL_UITLB_ACCESS,
- [C(RESULT_MISS)] =
- SPAV3_2_SEL_UITLB_MISS,
- },
- [C(OP_WRITE)] = {
- [C(RESULT_ACCESS)] =
- CACHE_OP_UNSUPPORTED,
- [C(RESULT_MISS)] =
- CACHE_OP_UNSUPPORTED,
- },
- [C(OP_PREFETCH)] = {
- [C(RESULT_ACCESS)] =
- CACHE_OP_UNSUPPORTED,
- [C(RESULT_MISS)] =
- CACHE_OP_UNSUPPORTED,
- },
- },
- [C(BPU)] = { /* What is BPU? */
- [C(OP_READ)] = {
- [C(RESULT_ACCESS)] =
- CACHE_OP_UNSUPPORTED,
- [C(RESULT_MISS)] =
- CACHE_OP_UNSUPPORTED,
- },
- [C(OP_WRITE)] = {
- [C(RESULT_ACCESS)] =
- CACHE_OP_UNSUPPORTED,
- [C(RESULT_MISS)] =
- CACHE_OP_UNSUPPORTED,
- },
- [C(OP_PREFETCH)] = {
- [C(RESULT_ACCESS)] =
- CACHE_OP_UNSUPPORTED,
- [C(RESULT_MISS)] =
- CACHE_OP_UNSUPPORTED,
- },
- },
- [C(NODE)] = { /* What is NODE? */
- [C(OP_READ)] = {
- [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
- [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
- },
- [C(OP_WRITE)] = {
- [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
- [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
- },
- [C(OP_PREFETCH)] = {
- [C(RESULT_ACCESS)] =
- CACHE_OP_UNSUPPORTED,
- [C(RESULT_MISS)] =
- CACHE_OP_UNSUPPORTED,
- },
- },
-};
-
-int nds32_pmu_map_event(struct perf_event *event,
- const unsigned int (*event_map)[PERF_COUNT_HW_MAX],
- const unsigned int (*cache_map)[PERF_COUNT_HW_CACHE_MAX]
- [PERF_COUNT_HW_CACHE_OP_MAX]
- [PERF_COUNT_HW_CACHE_RESULT_MAX], u32 raw_event_mask);
-
-#endif /* __ASM_PMU_H */
diff --git a/arch/nds32/include/asm/proc-fns.h b/arch/nds32/include/asm/proc-fns.h
deleted file mode 100644
index 27c617fa77af..000000000000
--- a/arch/nds32/include/asm/proc-fns.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-// Copyright (C) 2005-2017 Andes Technology Corporation
-
-#ifndef __NDS32_PROCFNS_H__
-#define __NDS32_PROCFNS_H__
-
-#ifdef __KERNEL__
-#include <asm/page.h>
-
-struct mm_struct;
-struct vm_area_struct;
-extern void cpu_proc_init(void);
-extern void cpu_proc_fin(void);
-extern void cpu_do_idle(void);
-extern void cpu_reset(unsigned long reset);
-extern void cpu_switch_mm(struct mm_struct *mm);
-
-extern void cpu_dcache_inval_all(void);
-extern void cpu_dcache_wbinval_all(void);
-extern void cpu_dcache_inval_page(unsigned long page);
-extern void cpu_dcache_wb_page(unsigned long page);
-extern void cpu_dcache_wbinval_page(unsigned long page);
-extern void cpu_dcache_inval_range(unsigned long start, unsigned long end);
-extern void cpu_dcache_wb_range(unsigned long start, unsigned long end);
-extern void cpu_dcache_wbinval_range(unsigned long start, unsigned long end);
-
-extern void cpu_icache_inval_all(void);
-extern void cpu_icache_inval_page(unsigned long page);
-extern void cpu_icache_inval_range(unsigned long start, unsigned long end);
-
-extern void cpu_cache_wbinval_page(unsigned long page, int flushi);
-extern void cpu_cache_wbinval_range(unsigned long start,
- unsigned long end, int flushi);
-extern void cpu_cache_wbinval_range_check(struct vm_area_struct *vma,
- unsigned long start,
- unsigned long end, bool flushi,
- bool wbd);
-
-extern void cpu_dma_wb_range(unsigned long start, unsigned long end);
-extern void cpu_dma_inval_range(unsigned long start, unsigned long end);
-extern void cpu_dma_wbinval_range(unsigned long start, unsigned long end);
-
-#endif /* __KERNEL__ */
-#endif /* __NDS32_PROCFNS_H__ */
diff --git a/arch/nds32/include/asm/processor.h b/arch/nds32/include/asm/processor.h
deleted file mode 100644
index e6bfc74972bb..000000000000
--- a/arch/nds32/include/asm/processor.h
+++ /dev/null
@@ -1,104 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-// Copyright (C) 2005-2017 Andes Technology Corporation
-
-#ifndef __ASM_NDS32_PROCESSOR_H
-#define __ASM_NDS32_PROCESSOR_H
-
-#ifdef __KERNEL__
-
-#include <asm/ptrace.h>
-#include <asm/types.h>
-#include <asm/sigcontext.h>
-
-#define KERNEL_STACK_SIZE PAGE_SIZE
-#define STACK_TOP TASK_SIZE
-#define STACK_TOP_MAX TASK_SIZE
-
-struct cpu_context {
- unsigned long r6;
- unsigned long r7;
- unsigned long r8;
- unsigned long r9;
- unsigned long r10;
- unsigned long r11;
- unsigned long r12;
- unsigned long r13;
- unsigned long r14;
- unsigned long fp;
- unsigned long pc;
- unsigned long sp;
-};
-
-struct thread_struct {
- struct cpu_context cpu_context; /* cpu context */
- /* fault info */
- unsigned long address;
- unsigned long trap_no;
- unsigned long error_code;
-
- struct fpu_struct fpu;
-};
-
-#define INIT_THREAD { }
-
-#ifdef __NDS32_EB__
-#define PSW_DE PSW_mskBE
-#else
-#define PSW_DE 0x0
-#endif
-
-#ifdef CONFIG_WBNA
-#define PSW_valWBNA PSW_mskWBNA
-#else
-#define PSW_valWBNA 0x0
-#endif
-
-#ifdef CONFIG_HWZOL
-#define PSW_valINIT (PSW_CPL_ANY | PSW_mskAEN | PSW_valWBNA | PSW_mskDT | PSW_mskIT | PSW_DE | PSW_mskGIE)
-#else
-#define PSW_valINIT (PSW_CPL_ANY | PSW_valWBNA | PSW_mskDT | PSW_mskIT | PSW_DE | PSW_mskGIE)
-#endif
-
-#define start_thread(regs,pc,stack) \
-({ \
- memzero(regs, sizeof(struct pt_regs)); \
- forget_syscall(regs); \
- regs->ipsw = PSW_valINIT; \
- regs->ir0 = (PSW_CPL_ANY | PSW_valWBNA | PSW_mskDT | PSW_mskIT | PSW_DE | PSW_SYSTEM | PSW_INTL_1); \
- regs->ipc = pc; \
- regs->sp = stack; \
-})
-
-/* Forward declaration, a strange C thing */
-struct task_struct;
-
-/* Free all resources held by a thread. */
-#define release_thread(thread) do { } while(0)
-#if IS_ENABLED(CONFIG_FPU)
-#if !IS_ENABLED(CONFIG_UNLAZU_FPU)
-extern struct task_struct *last_task_used_math;
-#endif
-#endif
-
-/* Prepare to copy thread state - unlazy all lazy status */
-#define prepare_to_copy(tsk) do { } while (0)
-
-unsigned long __get_wchan(struct task_struct *p);
-
-#define cpu_relax() barrier()
-
-#define task_pt_regs(task) \
- ((struct pt_regs *) (task_stack_page(task) + THREAD_SIZE \
- - 8) - 1)
-
-/*
- * Create a new kernel thread
- */
-extern int kernel_thread(int (*fn) (void *), void *arg, unsigned long flags);
-
-#define KSTK_EIP(tsk) instruction_pointer(task_pt_regs(tsk))
-#define KSTK_ESP(tsk) user_stack_pointer(task_pt_regs(tsk))
-
-#endif
-
-#endif /* __ASM_NDS32_PROCESSOR_H */
diff --git a/arch/nds32/include/asm/ptrace.h b/arch/nds32/include/asm/ptrace.h
deleted file mode 100644
index 919ee223620c..000000000000
--- a/arch/nds32/include/asm/ptrace.h
+++ /dev/null
@@ -1,77 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-// Copyright (C) 2005-2017 Andes Technology Corporation
-
-#ifndef __ASM_NDS32_PTRACE_H
-#define __ASM_NDS32_PTRACE_H
-
-#include <uapi/asm/ptrace.h>
-
-/*
- * If pt_regs.syscallno == NO_SYSCALL, then the thread is not executing
- * a syscall -- i.e., its most recent entry into the kernel from
- * userspace was not via syscall, or otherwise a tracer cancelled the
- * syscall.
- *
- * This must have the value -1, for ABI compatibility with ptrace etc.
- */
-#define NO_SYSCALL (-1)
-#ifndef __ASSEMBLY__
-#include <linux/types.h>
-
-struct pt_regs {
- union {
- struct user_pt_regs user_regs;
- struct {
- long uregs[26];
- long fp;
- long gp;
- long lp;
- long sp;
- long ipc;
-#if defined(CONFIG_HWZOL)
- long lb;
- long le;
- long lc;
-#else
- long dummy[3];
-#endif
- long syscallno;
- };
- };
- long orig_r0;
- long ir0;
- long ipsw;
- long pipsw;
- long pipc;
- long pp0;
- long pp1;
- long fucop_ctl;
- long osp;
-};
-
-static inline bool in_syscall(struct pt_regs const *regs)
-{
- return regs->syscallno != NO_SYSCALL;
-}
-
-static inline void forget_syscall(struct pt_regs *regs)
-{
- regs->syscallno = NO_SYSCALL;
-}
-static inline unsigned long regs_return_value(struct pt_regs *regs)
-{
- return regs->uregs[0];
-}
-extern void show_regs(struct pt_regs *);
-/* Avoid circular header include via sched.h */
-struct task_struct;
-
-#define arch_has_single_step() (1)
-#define user_mode(regs) (((regs)->ipsw & PSW_mskPOM) == 0)
-#define interrupts_enabled(regs) (!!((regs)->ipsw & PSW_mskGIE))
-#define user_stack_pointer(regs) ((regs)->sp)
-#define instruction_pointer(regs) ((regs)->ipc)
-#define profile_pc(regs) instruction_pointer(regs)
-
-#endif /* __ASSEMBLY__ */
-#endif
diff --git a/arch/nds32/include/asm/sfp-machine.h b/arch/nds32/include/asm/sfp-machine.h
deleted file mode 100644
index b1a5caa332b5..000000000000
--- a/arch/nds32/include/asm/sfp-machine.h
+++ /dev/null
@@ -1,158 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/* Copyright (C) 2005-2018 Andes Technology Corporation */
-
-#include <asm/bitfield.h>
-
-#define _FP_W_TYPE_SIZE 32
-#define _FP_W_TYPE unsigned long
-#define _FP_WS_TYPE signed long
-#define _FP_I_TYPE long
-
-#define __ll_B ((UWtype) 1 << (W_TYPE_SIZE / 2))
-#define __ll_lowpart(t) ((UWtype) (t) & (__ll_B - 1))
-#define __ll_highpart(t) ((UWtype) (t) >> (W_TYPE_SIZE / 2))
-
-#define _FP_MUL_MEAT_S(R, X, Y) \
- _FP_MUL_MEAT_1_wide(_FP_WFRACBITS_S, R, X, Y, umul_ppmm)
-#define _FP_MUL_MEAT_D(R, X, Y) \
- _FP_MUL_MEAT_2_wide(_FP_WFRACBITS_D, R, X, Y, umul_ppmm)
-#define _FP_MUL_MEAT_Q(R, X, Y) \
- _FP_MUL_MEAT_4_wide(_FP_WFRACBITS_Q, R, X, Y, umul_ppmm)
-
-#define _FP_MUL_MEAT_DW_S(R, X, Y) \
- _FP_MUL_MEAT_DW_1_wide(_FP_WFRACBITS_S, R, X, Y, umul_ppmm)
-#define _FP_MUL_MEAT_DW_D(R, X, Y) \
- _FP_MUL_MEAT_DW_2_wide(_FP_WFRACBITS_D, R, X, Y, umul_ppmm)
-
-#define _FP_DIV_MEAT_S(R, X, Y) _FP_DIV_MEAT_1_udiv_norm(S, R, X, Y)
-#define _FP_DIV_MEAT_D(R, X, Y) _FP_DIV_MEAT_2_udiv(D, R, X, Y)
-
-#define _FP_NANFRAC_S ((_FP_QNANBIT_S << 1) - 1)
-#define _FP_NANFRAC_D ((_FP_QNANBIT_D << 1) - 1), -1
-#define _FP_NANFRAC_Q ((_FP_QNANBIT_Q << 1) - 1), -1, -1, -1
-#define _FP_NANSIGN_S 0
-#define _FP_NANSIGN_D 0
-#define _FP_NANSIGN_Q 0
-
-#define _FP_KEEPNANFRACP 1
-#define _FP_QNANNEGATEDP 0
-
-#define _FP_CHOOSENAN(fs, wc, R, X, Y, OP) \
-do { \
- if ((_FP_FRAC_HIGH_RAW_##fs(X) & _FP_QNANBIT_##fs) \
- && !(_FP_FRAC_HIGH_RAW_##fs(Y) & _FP_QNANBIT_##fs)) { \
- R##_s = Y##_s; \
- _FP_FRAC_COPY_##wc(R, Y); \
- } else { \
- R##_s = X##_s; \
- _FP_FRAC_COPY_##wc(R, X); \
- } \
- R##_c = FP_CLS_NAN; \
-} while (0)
-
-#define __FPU_FPCSR (current->thread.fpu.fpcsr)
-
-/* Obtain the current rounding mode. */
-#define FP_ROUNDMODE \
-({ \
- __FPU_FPCSR & FPCSR_mskRM; \
-})
-
-#define FP_RND_NEAREST 0
-#define FP_RND_PINF 1
-#define FP_RND_MINF 2
-#define FP_RND_ZERO 3
-
-#define FP_EX_INVALID FPCSR_mskIVO
-#define FP_EX_DIVZERO FPCSR_mskDBZ
-#define FP_EX_OVERFLOW FPCSR_mskOVF
-#define FP_EX_UNDERFLOW FPCSR_mskUDF
-#define FP_EX_INEXACT FPCSR_mskIEX
-
-#define SF_CEQ 2
-#define SF_CLT 1
-#define SF_CGT 3
-#define SF_CUN 4
-
-#include <asm/byteorder.h>
-
-#ifdef __BIG_ENDIAN__
-#define __BYTE_ORDER __BIG_ENDIAN
-#define __LITTLE_ENDIAN 0
-#else
-#define __BYTE_ORDER __LITTLE_ENDIAN
-#define __BIG_ENDIAN 0
-#endif
-
-#define abort() do { } while (0)
-#define umul_ppmm(w1, w0, u, v) \
-do { \
- UWtype __x0, __x1, __x2, __x3; \
- UHWtype __ul, __vl, __uh, __vh; \
- \
- __ul = __ll_lowpart(u); \
- __uh = __ll_highpart(u); \
- __vl = __ll_lowpart(v); \
- __vh = __ll_highpart(v); \
- \
- __x0 = (UWtype) __ul * __vl; \
- __x1 = (UWtype) __ul * __vh; \
- __x2 = (UWtype) __uh * __vl; \
- __x3 = (UWtype) __uh * __vh; \
- \
- __x1 += __ll_highpart(__x0); \
- __x1 += __x2; \
- if (__x1 < __x2) \
- __x3 += __ll_B; \
- \
- (w1) = __x3 + __ll_highpart(__x1); \
- (w0) = __ll_lowpart(__x1) * __ll_B + __ll_lowpart(__x0); \
-} while (0)
-
-#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
-do { \
- UWtype __x; \
- __x = (al) + (bl); \
- (sh) = (ah) + (bh) + (__x < (al)); \
- (sl) = __x; \
-} while (0)
-
-#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
-do { \
- UWtype __x; \
- __x = (al) - (bl); \
- (sh) = (ah) - (bh) - (__x > (al)); \
- (sl) = __x; \
-} while (0)
-
-#define udiv_qrnnd(q, r, n1, n0, d) \
-do { \
- UWtype __d1, __d0, __q1, __q0, __r1, __r0, __m; \
- __d1 = __ll_highpart(d); \
- __d0 = __ll_lowpart(d); \
- \
- __r1 = (n1) % __d1; \
- __q1 = (n1) / __d1; \
- __m = (UWtype) __q1 * __d0; \
- __r1 = __r1 * __ll_B | __ll_highpart(n0); \
- if (__r1 < __m) { \
- __q1--, __r1 += (d); \
- if (__r1 >= (d)) \
- if (__r1 < __m) \
- __q1--, __r1 += (d); \
- } \
- __r1 -= __m; \
- __r0 = __r1 % __d1; \
- __q0 = __r1 / __d1; \
- __m = (UWtype) __q0 * __d0; \
- __r0 = __r0 * __ll_B | __ll_lowpart(n0); \
- if (__r0 < __m) { \
- __q0--, __r0 += (d); \
- if (__r0 >= (d)) \
- if (__r0 < __m) \
- __q0--, __r0 += (d); \
- } \
- __r0 -= __m; \
- (q) = (UWtype) __q1 * __ll_B | __q0; \
- (r) = __r0; \
-} while (0)
diff --git a/arch/nds32/include/asm/shmparam.h b/arch/nds32/include/asm/shmparam.h
deleted file mode 100644
index 3aeee946973d..000000000000
--- a/arch/nds32/include/asm/shmparam.h
+++ /dev/null
@@ -1,19 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-// Copyright (C) 2005-2017 Andes Technology Corporation
-
-#ifndef _ASMNDS32_SHMPARAM_H
-#define _ASMNDS32_SHMPARAM_H
-
-/*
- * This should be the size of the virtually indexed cache/ways,
- * whichever is greater since the cache aliases every size/ways
- * bytes.
- */
-#define SHMLBA (4 * SZ_8K) /* attach addr a multiple of this */
-
-/*
- * Enforce SHMLBA in shmat
- */
-#define __ARCH_FORCE_SHMLBA
-
-#endif /* _ASMNDS32_SHMPARAM_H */
diff --git a/arch/nds32/include/asm/stacktrace.h b/arch/nds32/include/asm/stacktrace.h
deleted file mode 100644
index 6bf7c777bda4..000000000000
--- a/arch/nds32/include/asm/stacktrace.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/* Copyright (C) 2008-2018 Andes Technology Corporation */
-
-#ifndef __ASM_STACKTRACE_H
-#define __ASM_STACKTRACE_H
-
-/* Kernel callchain */
-struct stackframe {
- unsigned long fp;
- unsigned long sp;
- unsigned long lp;
-};
-
-/*
- * struct frame_tail: User callchain
- * IMPORTANT:
- * This struct is used for call-stack walking,
- * the order and types matters.
- * Do not use array, it only stores sizeof(pointer)
- *
- * The details can refer to arch/arm/kernel/perf_event.c
- */
-struct frame_tail {
- unsigned long stack_fp;
- unsigned long stack_lp;
-};
-
-/* For User callchain with optimize for size */
-struct frame_tail_opt_size {
- unsigned long stack_r6;
- unsigned long stack_fp;
- unsigned long stack_gp;
- unsigned long stack_lp;
-};
-
-extern void
-get_real_ret_addr(unsigned long *addr, struct task_struct *tsk, int *graph);
-
-#endif /* __ASM_STACKTRACE_H */
diff --git a/arch/nds32/include/asm/string.h b/arch/nds32/include/asm/string.h
deleted file mode 100644
index cae8fe16de98..000000000000
--- a/arch/nds32/include/asm/string.h
+++ /dev/null
@@ -1,17 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-// Copyright (C) 2005-2017 Andes Technology Corporation
-
-#ifndef __ASM_NDS32_STRING_H
-#define __ASM_NDS32_STRING_H
-
-#define __HAVE_ARCH_MEMCPY
-extern void *memcpy(void *, const void *, __kernel_size_t);
-
-#define __HAVE_ARCH_MEMMOVE
-extern void *memmove(void *, const void *, __kernel_size_t);
-
-#define __HAVE_ARCH_MEMSET
-extern void *memset(void *, int, __kernel_size_t);
-
-extern void *memzero(void *ptr, __kernel_size_t n);
-#endif
diff --git a/arch/nds32/include/asm/suspend.h b/arch/nds32/include/asm/suspend.h
deleted file mode 100644
index 6ed2418af1ac..000000000000
--- a/arch/nds32/include/asm/suspend.h
+++ /dev/null
@@ -1,11 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-// Copyright (C) 2008-2017 Andes Technology Corporation
-
-#ifndef __ASM_NDS32_SUSPEND_H
-#define __ASM_NDS32_SUSPEND_H
-
-extern void suspend2ram(void);
-extern void cpu_resume(void);
-extern unsigned long wake_mask;
-
-#endif
diff --git a/arch/nds32/include/asm/swab.h b/arch/nds32/include/asm/swab.h
deleted file mode 100644
index 362a466f2976..000000000000
--- a/arch/nds32/include/asm/swab.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-// Copyright (C) 2005-2017 Andes Technology Corporation
-
-#ifndef __NDS32_SWAB_H__
-#define __NDS32_SWAB_H__
-
-#include <linux/types.h>
-#include <linux/compiler.h>
-
-static __inline__ __attribute_const__ __u32 ___arch__swab32(__u32 x)
-{
- __asm__("wsbh %0, %0\n\t" /* word swap byte within halfword */
- "rotri %0, %0, #16\n"
- :"=r"(x)
- :"0"(x));
- return x;
-}
-
-static __inline__ __attribute_const__ __u16 ___arch__swab16(__u16 x)
-{
- __asm__("wsbh %0, %0\n" /* word swap byte within halfword */
- :"=r"(x)
- :"0"(x));
- return x;
-}
-
-#define __arch_swab32(x) ___arch__swab32(x)
-#define __arch_swab16(x) ___arch__swab16(x)
-
-#if !defined(__STRICT_ANSI__) || defined(__KERNEL__)
-#define __BYTEORDER_HAS_U64__
-#define __SWAB_64_THRU_32__
-#endif
-
-#endif /* __NDS32_SWAB_H__ */
diff --git a/arch/nds32/include/asm/syscall.h b/arch/nds32/include/asm/syscall.h
deleted file mode 100644
index 90aa56c94af1..000000000000
--- a/arch/nds32/include/asm/syscall.h
+++ /dev/null
@@ -1,142 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-// Copyright (C) 2008-2009 Red Hat, Inc. All rights reserved.
-// Copyright (C) 2005-2017 Andes Technology Corporation
-
-#ifndef _ASM_NDS32_SYSCALL_H
-#define _ASM_NDS32_SYSCALL_H 1
-
-#include <uapi/linux/audit.h>
-#include <linux/err.h>
-struct task_struct;
-struct pt_regs;
-
-/**
- * syscall_get_nr - find what system call a task is executing
- * @task: task of interest, must be blocked
- * @regs: task_pt_regs() of @task
- *
- * If @task is executing a system call or is at system call
- * tracing about to attempt one, returns the system call number.
- * If @task is not executing a system call, i.e. it's blocked
- * inside the kernel for a fault or signal, returns -1.
- *
- * Note this returns int even on 64-bit machines. Only 32 bits of
- * system call number can be meaningful. If the actual arch value
- * is 64 bits, this truncates to 32 bits so 0xffffffff means -1.
- *
- * It's only valid to call this when @task is known to be blocked.
- */
-static inline int
-syscall_get_nr(struct task_struct *task, struct pt_regs *regs)
-{
- return regs->syscallno;
-}
-
-/**
- * syscall_rollback - roll back registers after an aborted system call
- * @task: task of interest, must be in system call exit tracing
- * @regs: task_pt_regs() of @task
- *
- * It's only valid to call this when @task is stopped for system
- * call exit tracing (due to TIF_SYSCALL_TRACE or TIF_SYSCALL_AUDIT),
- * after tracehook_report_syscall_entry() returned nonzero to prevent
- * the system call from taking place.
- *
- * This rolls back the register state in @regs so it's as if the
- * system call instruction was a no-op. The registers containing
- * the system call number and arguments are as they were before the
- * system call instruction. This may not be the same as what the
- * register state looked like at system call entry tracing.
- */
-static inline void
-syscall_rollback(struct task_struct *task, struct pt_regs *regs)
-{
- regs->uregs[0] = regs->orig_r0;
-}
-
-/**
- * syscall_get_error - check result of traced system call
- * @task: task of interest, must be blocked
- * @regs: task_pt_regs() of @task
- *
- * Returns 0 if the system call succeeded, or -ERRORCODE if it failed.
- *
- * It's only valid to call this when @task is stopped for tracing on exit
- * from a system call, due to %TIF_SYSCALL_TRACE or %TIF_SYSCALL_AUDIT.
- */
-static inline long
-syscall_get_error(struct task_struct *task, struct pt_regs *regs)
-{
- unsigned long error = regs->uregs[0];
- return IS_ERR_VALUE(error) ? error : 0;
-}
-
-/**
- * syscall_get_return_value - get the return value of a traced system call
- * @task: task of interest, must be blocked
- * @regs: task_pt_regs() of @task
- *
- * Returns the return value of the successful system call.
- * This value is meaningless if syscall_get_error() returned nonzero.
- *
- * It's only valid to call this when @task is stopped for tracing on exit
- * from a system call, due to %TIF_SYSCALL_TRACE or %TIF_SYSCALL_AUDIT.
- */
-static inline long
-syscall_get_return_value(struct task_struct *task, struct pt_regs *regs)
-{
- return regs->uregs[0];
-}
-
-/**
- * syscall_set_return_value - change the return value of a traced system call
- * @task: task of interest, must be blocked
- * @regs: task_pt_regs() of @task
- * @error: negative error code, or zero to indicate success
- * @val: user return value if @error is zero
- *
- * This changes the results of the system call that user mode will see.
- * If @error is zero, the user sees a successful system call with a
- * return value of @val. If @error is nonzero, it's a negated errno
- * code; the user sees a failed system call with this errno code.
- *
- * It's only valid to call this when @task is stopped for tracing on exit
- * from a system call, due to %TIF_SYSCALL_TRACE or %TIF_SYSCALL_AUDIT.
- */
-static inline void
-syscall_set_return_value(struct task_struct *task, struct pt_regs *regs,
- int error, long val)
-{
- regs->uregs[0] = (long)error ? error : val;
-}
-
-/**
- * syscall_get_arguments - extract system call parameter values
- * @task: task of interest, must be blocked
- * @regs: task_pt_regs() of @task
- * @args: array filled with argument values
- *
- * Fetches 6 arguments to the system call (from 0 through 5). The first
- * argument is stored in @args[0], and so on.
- *
- * It's only valid to call this when @task is stopped for tracing on
- * entry to a system call, due to %TIF_SYSCALL_TRACE or %TIF_SYSCALL_AUDIT.
- */
-#define SYSCALL_MAX_ARGS 6
-static inline void
-syscall_get_arguments(struct task_struct *task, struct pt_regs *regs,
- unsigned long *args)
-{
- args[0] = regs->orig_r0;
- args++;
- memcpy(args, &regs->uregs[0] + 1, 5 * sizeof(args[0]));
-}
-
-static inline int
-syscall_get_arch(struct task_struct *task)
-{
- return IS_ENABLED(CONFIG_CPU_BIG_ENDIAN)
- ? AUDIT_ARCH_NDS32BE : AUDIT_ARCH_NDS32;
-}
-
-#endif /* _ASM_NDS32_SYSCALL_H */
diff --git a/arch/nds32/include/asm/syscalls.h b/arch/nds32/include/asm/syscalls.h
deleted file mode 100644
index 4e7216082a67..000000000000
--- a/arch/nds32/include/asm/syscalls.h
+++ /dev/null
@@ -1,14 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-// Copyright (C) 2005-2017 Andes Technology Corporation
-
-#ifndef __ASM_NDS32_SYSCALLS_H
-#define __ASM_NDS32_SYSCALLS_H
-
-asmlinkage long sys_cacheflush(unsigned long addr, unsigned long len, unsigned int op);
-asmlinkage long sys_fadvise64_64_wrapper(int fd, int advice, loff_t offset, loff_t len);
-asmlinkage long sys_rt_sigreturn_wrapper(void);
-asmlinkage long sys_fp_udfiex_crtl(int cmd, int act);
-
-#include <asm-generic/syscalls.h>
-
-#endif /* __ASM_NDS32_SYSCALLS_H */
diff --git a/arch/nds32/include/asm/thread_info.h b/arch/nds32/include/asm/thread_info.h
deleted file mode 100644
index d3967ad184f0..000000000000
--- a/arch/nds32/include/asm/thread_info.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-// Copyright (C) 2005-2017 Andes Technology Corporation
-
-#ifndef __ASM_NDS32_THREAD_INFO_H
-#define __ASM_NDS32_THREAD_INFO_H
-
-#ifdef __KERNEL__
-
-#define THREAD_SIZE_ORDER (1)
-#define THREAD_SIZE (PAGE_SIZE << THREAD_SIZE_ORDER)
-
-#ifndef __ASSEMBLY__
-
-struct task_struct;
-
-#include <asm/ptrace.h>
-#include <asm/types.h>
-
-typedef unsigned long mm_segment_t;
-
-/*
- * low level task data that entry.S needs immediate access to.
- * __switch_to() assumes cpu_context follows immediately after cpu_domain.
- */
-struct thread_info {
- unsigned long flags; /* low level flags */
- __s32 preempt_count; /* 0 => preemptable, <0 => bug */
- mm_segment_t addr_limit; /* address limit */
-};
-#define INIT_THREAD_INFO(tsk) \
-{ \
- .preempt_count = INIT_PREEMPT_COUNT, \
- .addr_limit = KERNEL_DS, \
-}
-#define thread_saved_pc(tsk) ((unsigned long)(tsk->thread.cpu_context.pc))
-#define thread_saved_fp(tsk) ((unsigned long)(tsk->thread.cpu_context.fp))
-#endif
-
-/*
- * thread information flags:
- * TIF_SYSCALL_TRACE - syscall trace active
- * TIF_SIGPENDING - signal pending
- * TIF_NEED_RESCHED - rescheduling necessary
- * TIF_NOTIFY_RESUME - callback before returning to user
- * TIF_POLLING_NRFLAG - true if poll_idle() is polling TIF_NEED_RESCHED
- */
-#define TIF_SIGPENDING 1
-#define TIF_NEED_RESCHED 2
-#define TIF_SINGLESTEP 3
-#define TIF_NOTIFY_RESUME 4 /* callback before returning to user */
-#define TIF_NOTIFY_SIGNAL 5 /* signal notifications exist */
-#define TIF_SYSCALL_TRACE 8
-#define TIF_POLLING_NRFLAG 17
-#define TIF_MEMDIE 18
-#define TIF_FREEZE 19
-#define TIF_RESTORE_SIGMASK 20
-
-#define _TIF_SIGPENDING (1 << TIF_SIGPENDING)
-#define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED)
-#define _TIF_NOTIFY_RESUME (1 << TIF_NOTIFY_RESUME)
-#define _TIF_NOTIFY_SIGNAL (1 << TIF_NOTIFY_SIGNAL)
-#define _TIF_SINGLESTEP (1 << TIF_SINGLESTEP)
-#define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE)
-#define _TIF_POLLING_NRFLAG (1 << TIF_POLLING_NRFLAG)
-#define _TIF_FREEZE (1 << TIF_FREEZE)
-#define _TIF_RESTORE_SIGMASK (1 << TIF_RESTORE_SIGMASK)
-
-/*
- * Change these and you break ASM code in entry-common.S
- */
-#define _TIF_WORK_MASK 0x000000ff
-#define _TIF_WORK_SYSCALL_ENTRY (_TIF_SYSCALL_TRACE | _TIF_SINGLESTEP)
-#define _TIF_WORK_SYSCALL_LEAVE (_TIF_SYSCALL_TRACE | _TIF_SINGLESTEP)
-
-#endif /* __KERNEL__ */
-#endif /* __ASM_NDS32_THREAD_INFO_H */
diff --git a/arch/nds32/include/asm/tlb.h b/arch/nds32/include/asm/tlb.h
deleted file mode 100644
index 672603804a3b..000000000000
--- a/arch/nds32/include/asm/tlb.h
+++ /dev/null
@@ -1,11 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-// Copyright (C) 2005-2017 Andes Technology Corporation
-
-#ifndef __ASMNDS32_TLB_H
-#define __ASMNDS32_TLB_H
-
-#include <asm-generic/tlb.h>
-
-#define __pte_free_tlb(tlb, pte, addr) pte_free((tlb)->mm, pte)
-
-#endif
diff --git a/arch/nds32/include/asm/tlbflush.h b/arch/nds32/include/asm/tlbflush.h
deleted file mode 100644
index 97155366ea01..000000000000
--- a/arch/nds32/include/asm/tlbflush.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-// Copyright (C) 2005-2017 Andes Technology Corporation
-
-#ifndef _ASMNDS32_TLBFLUSH_H
-#define _ASMNDS32_TLBFLUSH_H
-
-#include <linux/spinlock.h>
-#include <linux/mm.h>
-#include <nds32_intrinsic.h>
-
-static inline void local_flush_tlb_all(void)
-{
- __nds32__tlbop_flua();
- __nds32__isb();
-}
-
-static inline void local_flush_tlb_mm(struct mm_struct *mm)
-{
- __nds32__tlbop_flua();
- __nds32__isb();
-}
-
-static inline void local_flush_tlb_kernel_range(unsigned long start,
- unsigned long end)
-{
- while (start < end) {
- __nds32__tlbop_inv(start);
- __nds32__isb();
- start += PAGE_SIZE;
- }
-}
-
-void local_flush_tlb_range(struct vm_area_struct *vma,
- unsigned long start, unsigned long end);
-void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long addr);
-
-#define flush_tlb_all local_flush_tlb_all
-#define flush_tlb_mm local_flush_tlb_mm
-#define flush_tlb_range local_flush_tlb_range
-#define flush_tlb_page local_flush_tlb_page
-#define flush_tlb_kernel_range local_flush_tlb_kernel_range
-
-void update_mmu_cache(struct vm_area_struct *vma,
- unsigned long address, pte_t * pte);
-
-#endif
diff --git a/arch/nds32/include/asm/uaccess.h b/arch/nds32/include/asm/uaccess.h
deleted file mode 100644
index d4cbf069dc22..000000000000
--- a/arch/nds32/include/asm/uaccess.h
+++ /dev/null
@@ -1,286 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-// Copyright (C) 2005-2017 Andes Technology Corporation
-
-#ifndef _ASMANDES_UACCESS_H
-#define _ASMANDES_UACCESS_H
-
-/*
- * User space memory access functions
- */
-#include <linux/sched.h>
-#include <asm/errno.h>
-#include <asm/memory.h>
-#include <asm/types.h>
-
-#define __asmeq(x, y) ".ifnc " x "," y " ; .err ; .endif\n\t"
-
-/*
- * The exception table consists of pairs of addresses: the first is the
- * address of an instruction that is allowed to fault, and the second is
- * the address at which the program should continue. No registers are
- * modified, so it is entirely up to the continuation code to figure out
- * what to do.
- *
- * All the routines below use bits of fixup code that are out of line
- * with the main instruction path. This means when everything is well,
- * we don't even have to jump over them. Further, they do not intrude
- * on our cache or tlb entries.
- */
-
-struct exception_table_entry {
- unsigned long insn, fixup;
-};
-
-extern int fixup_exception(struct pt_regs *regs);
-
-#define KERNEL_DS ((mm_segment_t) { ~0UL })
-#define USER_DS ((mm_segment_t) {TASK_SIZE - 1})
-
-#define get_fs() (current_thread_info()->addr_limit)
-#define user_addr_max get_fs
-
-static inline void set_fs(mm_segment_t fs)
-{
- current_thread_info()->addr_limit = fs;
-}
-
-#define uaccess_kernel() (get_fs() == KERNEL_DS)
-
-#define __range_ok(addr, size) (size <= get_fs() && addr <= (get_fs() -size))
-
-#define access_ok(addr, size) \
- __range_ok((unsigned long)addr, (unsigned long)size)
-/*
- * Single-value transfer routines. They automatically use the right
- * size if we just have the right pointer type. Note that the functions
- * which read from user space (*get_*) need to take care not to leak
- * kernel data even if the calling code is buggy and fails to check
- * the return value. This means zeroing out the destination variable
- * or buffer on error. Normally this is done out of line by the
- * fixup code, but there are a few places where it intrudes on the
- * main code path. When we only write to user space, there is no
- * problem.
- *
- * The "__xxx" versions of the user access functions do not verify the
- * address space - it must have been done previously with a separate
- * "access_ok()" call.
- *
- * The "xxx_error" versions set the third argument to EFAULT if an
- * error occurs, and leave it unchanged on success. Note that these
- * versions are void (ie, don't return a value as such).
- */
-
-#define get_user __get_user \
-
-#define __get_user(x, ptr) \
-({ \
- long __gu_err = 0; \
- __get_user_check((x), (ptr), __gu_err); \
- __gu_err; \
-})
-
-#define __get_user_error(x, ptr, err) \
-({ \
- __get_user_check((x), (ptr), (err)); \
- (void)0; \
-})
-
-#define __get_user_check(x, ptr, err) \
-({ \
- const __typeof__(*(ptr)) __user *__p = (ptr); \
- might_fault(); \
- if (access_ok(__p, sizeof(*__p))) { \
- __get_user_err((x), __p, (err)); \
- } else { \
- (x) = 0; (err) = -EFAULT; \
- } \
-})
-
-#define __get_user_err(x, ptr, err) \
-do { \
- unsigned long __gu_val; \
- __chk_user_ptr(ptr); \
- switch (sizeof(*(ptr))) { \
- case 1: \
- __get_user_asm("lbi", __gu_val, (ptr), (err)); \
- break; \
- case 2: \
- __get_user_asm("lhi", __gu_val, (ptr), (err)); \
- break; \
- case 4: \
- __get_user_asm("lwi", __gu_val, (ptr), (err)); \
- break; \
- case 8: \
- __get_user_asm_dword(__gu_val, (ptr), (err)); \
- break; \
- default: \
- BUILD_BUG(); \
- break; \
- } \
- (x) = (__force __typeof__(*(ptr)))__gu_val; \
-} while (0)
-
-#define __get_user_asm(inst, x, addr, err) \
- __asm__ __volatile__ ( \
- "1: "inst" %1,[%2]\n" \
- "2:\n" \
- " .section .fixup,\"ax\"\n" \
- " .align 2\n" \
- "3: move %0, %3\n" \
- " move %1, #0\n" \
- " b 2b\n" \
- " .previous\n" \
- " .section __ex_table,\"a\"\n" \
- " .align 3\n" \
- " .long 1b, 3b\n" \
- " .previous" \
- : "+r" (err), "=&r" (x) \
- : "r" (addr), "i" (-EFAULT) \
- : "cc")
-
-#ifdef __NDS32_EB__
-#define __gu_reg_oper0 "%H1"
-#define __gu_reg_oper1 "%L1"
-#else
-#define __gu_reg_oper0 "%L1"
-#define __gu_reg_oper1 "%H1"
-#endif
-
-#define __get_user_asm_dword(x, addr, err) \
- __asm__ __volatile__ ( \
- "\n1:\tlwi " __gu_reg_oper0 ",[%2]\n" \
- "\n2:\tlwi " __gu_reg_oper1 ",[%2+4]\n" \
- "3:\n" \
- " .section .fixup,\"ax\"\n" \
- " .align 2\n" \
- "4: move %0, %3\n" \
- " b 3b\n" \
- " .previous\n" \
- " .section __ex_table,\"a\"\n" \
- " .align 3\n" \
- " .long 1b, 4b\n" \
- " .long 2b, 4b\n" \
- " .previous" \
- : "+r"(err), "=&r"(x) \
- : "r"(addr), "i"(-EFAULT) \
- : "cc")
-
-#define put_user __put_user \
-
-#define __put_user(x, ptr) \
-({ \
- long __pu_err = 0; \
- __put_user_err((x), (ptr), __pu_err); \
- __pu_err; \
-})
-
-#define __put_user_error(x, ptr, err) \
-({ \
- __put_user_err((x), (ptr), (err)); \
- (void)0; \
-})
-
-#define __put_user_check(x, ptr, err) \
-({ \
- __typeof__(*(ptr)) __user *__p = (ptr); \
- might_fault(); \
- if (access_ok(__p, sizeof(*__p))) { \
- __put_user_err((x), __p, (err)); \
- } else { \
- (err) = -EFAULT; \
- } \
-})
-
-#define __put_user_err(x, ptr, err) \
-do { \
- __typeof__(*(ptr)) __pu_val = (x); \
- __chk_user_ptr(ptr); \
- switch (sizeof(*(ptr))) { \
- case 1: \
- __put_user_asm("sbi", __pu_val, (ptr), (err)); \
- break; \
- case 2: \
- __put_user_asm("shi", __pu_val, (ptr), (err)); \
- break; \
- case 4: \
- __put_user_asm("swi", __pu_val, (ptr), (err)); \
- break; \
- case 8: \
- __put_user_asm_dword(__pu_val, (ptr), (err)); \
- break; \
- default: \
- BUILD_BUG(); \
- break; \
- } \
-} while (0)
-
-#define __put_user_asm(inst, x, addr, err) \
- __asm__ __volatile__ ( \
- "1: "inst" %1,[%2]\n" \
- "2:\n" \
- " .section .fixup,\"ax\"\n" \
- " .align 2\n" \
- "3: move %0, %3\n" \
- " b 2b\n" \
- " .previous\n" \
- " .section __ex_table,\"a\"\n" \
- " .align 3\n" \
- " .long 1b, 3b\n" \
- " .previous" \
- : "+r" (err) \
- : "r" (x), "r" (addr), "i" (-EFAULT) \
- : "cc")
-
-#ifdef __NDS32_EB__
-#define __pu_reg_oper0 "%H2"
-#define __pu_reg_oper1 "%L2"
-#else
-#define __pu_reg_oper0 "%L2"
-#define __pu_reg_oper1 "%H2"
-#endif
-
-#define __put_user_asm_dword(x, addr, err) \
- __asm__ __volatile__ ( \
- "\n1:\tswi " __pu_reg_oper0 ",[%1]\n" \
- "\n2:\tswi " __pu_reg_oper1 ",[%1+4]\n" \
- "3:\n" \
- " .section .fixup,\"ax\"\n" \
- " .align 2\n" \
- "4: move %0, %3\n" \
- " b 3b\n" \
- " .previous\n" \
- " .section __ex_table,\"a\"\n" \
- " .align 3\n" \
- " .long 1b, 4b\n" \
- " .long 2b, 4b\n" \
- " .previous" \
- : "+r"(err) \
- : "r"(addr), "r"(x), "i"(-EFAULT) \
- : "cc")
-
-extern unsigned long __arch_clear_user(void __user * addr, unsigned long n);
-extern long strncpy_from_user(char *dest, const char __user * src, long count);
-extern __must_check long strnlen_user(const char __user * str, long n);
-extern unsigned long __arch_copy_from_user(void *to, const void __user * from,
- unsigned long n);
-extern unsigned long __arch_copy_to_user(void __user * to, const void *from,
- unsigned long n);
-
-#define raw_copy_from_user __arch_copy_from_user
-#define raw_copy_to_user __arch_copy_to_user
-
-#define INLINE_COPY_FROM_USER
-#define INLINE_COPY_TO_USER
-static inline unsigned long clear_user(void __user * to, unsigned long n)
-{
- if (access_ok(to, n))
- n = __arch_clear_user(to, n);
- return n;
-}
-
-static inline unsigned long __clear_user(void __user * to, unsigned long n)
-{
- return __arch_clear_user(to, n);
-}
-
-#endif /* _ASMNDS32_UACCESS_H */
diff --git a/arch/nds32/include/asm/unistd.h b/arch/nds32/include/asm/unistd.h
deleted file mode 100644
index bf5e2d440913..000000000000
--- a/arch/nds32/include/asm/unistd.h
+++ /dev/null
@@ -1,6 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-// Copyright (C) 2005-2017 Andes Technology Corporation
-
-#define __ARCH_WANT_SYS_CLONE
-
-#include <uapi/asm/unistd.h>
diff --git a/arch/nds32/include/asm/vdso.h b/arch/nds32/include/asm/vdso.h
deleted file mode 100644
index 89b113ffc3dc..000000000000
--- a/arch/nds32/include/asm/vdso.h
+++ /dev/null
@@ -1,24 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C) 2005-2017 Andes Technology Corporation
- */
-
-#ifndef __ASM_VDSO_H
-#define __ASM_VDSO_H
-
-#ifdef __KERNEL__
-
-#ifndef __ASSEMBLY__
-
-#include <generated/vdso-offsets.h>
-
-#define VDSO_SYMBOL(base, name) \
-({ \
- (unsigned long)(vdso_offset_##name + (unsigned long)(base)); \
-})
-
-#endif /* !__ASSEMBLY__ */
-
-#endif /* __KERNEL__ */
-
-#endif /* __ASM_VDSO_H */
diff --git a/arch/nds32/include/asm/vdso_datapage.h b/arch/nds32/include/asm/vdso_datapage.h
deleted file mode 100644
index 74c68802021e..000000000000
--- a/arch/nds32/include/asm/vdso_datapage.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-// Copyright (C) 2012 ARM Limited
-// Copyright (C) 2005-2017 Andes Technology Corporation
-#ifndef __ASM_VDSO_DATAPAGE_H
-#define __ASM_VDSO_DATAPAGE_H
-
-#ifdef __KERNEL__
-
-#ifndef __ASSEMBLY__
-
-struct vdso_data {
- bool cycle_count_down; /* timer cyclye counter is decrease with time */
- u32 cycle_count_offset; /* offset of timer cycle counter register */
- u32 seq_count; /* sequence count - odd during updates */
- u32 xtime_coarse_sec; /* coarse time */
- u32 xtime_coarse_nsec;
-
- u32 wtm_clock_sec; /* wall to monotonic offset */
- u32 wtm_clock_nsec;
- u32 xtime_clock_sec; /* CLOCK_REALTIME - seconds */
- u32 cs_mult; /* clocksource multiplier */
- u32 cs_shift; /* Cycle to nanosecond divisor (power of two) */
- u32 hrtimer_res; /* hrtimer resolution */
-
- u64 cs_cycle_last; /* last cycle value */
- u64 cs_mask; /* clocksource mask */
-
- u64 xtime_clock_nsec; /* CLOCK_REALTIME sub-ns base */
- u32 tz_minuteswest; /* timezone info for gettimeofday(2) */
- u32 tz_dsttime;
-};
-
-#endif /* !__ASSEMBLY__ */
-
-#endif /* __KERNEL__ */
-
-#endif /* __ASM_VDSO_DATAPAGE_H */
diff --git a/arch/nds32/include/asm/vdso_timer_info.h b/arch/nds32/include/asm/vdso_timer_info.h
deleted file mode 100644
index 328439ce37db..000000000000
--- a/arch/nds32/include/asm/vdso_timer_info.h
+++ /dev/null
@@ -1,14 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-// Copyright (C) 2005-2017 Andes Technology Corporation
-
-extern struct timer_info_t timer_info;
-#define EMPTY_VALUE ~(0UL)
-#define EMPTY_TIMER_MAPPING EMPTY_VALUE
-#define EMPTY_REG_OFFSET EMPTY_VALUE
-
-struct timer_info_t
-{
- bool cycle_count_down;
- unsigned long mapping_base;
- unsigned long cycle_count_reg_offset;
-};
diff --git a/arch/nds32/include/asm/vermagic.h b/arch/nds32/include/asm/vermagic.h
deleted file mode 100644
index f772e7ba33f1..000000000000
--- a/arch/nds32/include/asm/vermagic.h
+++ /dev/null
@@ -1,9 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-// Copyright (C) 2005-2017 Andes Technology Corporation
-
-#ifndef _ASM_VERMAGIC_H
-#define _ASM_VERMAGIC_H
-
-#define MODULE_ARCH_VERMAGIC "NDS32v3"
-
-#endif /* _ASM_VERMAGIC_H */
diff --git a/arch/nds32/include/asm/vmalloc.h b/arch/nds32/include/asm/vmalloc.h
deleted file mode 100644
index caeed3898419..000000000000
--- a/arch/nds32/include/asm/vmalloc.h
+++ /dev/null
@@ -1,4 +0,0 @@
-#ifndef _ASM_NDS32_VMALLOC_H
-#define _ASM_NDS32_VMALLOC_H
-
-#endif /* _ASM_NDS32_VMALLOC_H */
diff --git a/arch/nds32/include/uapi/asm/auxvec.h b/arch/nds32/include/uapi/asm/auxvec.h
deleted file mode 100644
index bc0b92ab8c15..000000000000
--- a/arch/nds32/include/uapi/asm/auxvec.h
+++ /dev/null
@@ -1,19 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
-// Copyright (C) 2005-2017 Andes Technology Corporation
-
-#ifndef __ASM_AUXVEC_H
-#define __ASM_AUXVEC_H
-
-/*
- * This entry gives some information about the FPU initialization
- * performed by the kernel.
- */
-#define AT_FPUCW 18 /* Used FPU control word. */
-
-
-/* VDSO location */
-#define AT_SYSINFO_EHDR 33
-
-#define AT_VECTOR_SIZE_ARCH 1
-
-#endif
diff --git a/arch/nds32/include/uapi/asm/byteorder.h b/arch/nds32/include/uapi/asm/byteorder.h
deleted file mode 100644
index c264ef12c49c..000000000000
--- a/arch/nds32/include/uapi/asm/byteorder.h
+++ /dev/null
@@ -1,13 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
-// Copyright (C) 2005-2017 Andes Technology Corporation
-
-#ifndef __NDS32_BYTEORDER_H__
-#define __NDS32_BYTEORDER_H__
-
-#ifdef __NDS32_EB__
-#include <linux/byteorder/big_endian.h>
-#else
-#include <linux/byteorder/little_endian.h>
-#endif
-
-#endif /* __NDS32_BYTEORDER_H__ */
diff --git a/arch/nds32/include/uapi/asm/cachectl.h b/arch/nds32/include/uapi/asm/cachectl.h
deleted file mode 100644
index 31b9b439d819..000000000000
--- a/arch/nds32/include/uapi/asm/cachectl.h
+++ /dev/null
@@ -1,14 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
-// Copyright (C) 1994, 1995, 1996 by Ralf Baechle
-// Copyright (C) 2005-2017 Andes Technology Corporation
-#ifndef _ASM_CACHECTL
-#define _ASM_CACHECTL
-
-/*
- * Options for cacheflush system call
- */
-#define ICACHE 0 /* flush instruction cache */
-#define DCACHE 1 /* writeback and flush data cache */
-#define BCACHE 2 /* flush instruction cache + writeback and flush data cache */
-
-#endif /* _ASM_CACHECTL */
diff --git a/arch/nds32/include/uapi/asm/fp_udfiex_crtl.h b/arch/nds32/include/uapi/asm/fp_udfiex_crtl.h
deleted file mode 100644
index f17396db16ec..000000000000
--- a/arch/nds32/include/uapi/asm/fp_udfiex_crtl.h
+++ /dev/null
@@ -1,16 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
-/* Copyright (C) 2005-2019 Andes Technology Corporation */
-#ifndef _FP_UDF_IEX_CRTL_H
-#define _FP_UDF_IEX_CRTL_H
-
-/*
- * The cmd list of sys_fp_udfiex_crtl()
- */
-/* Disable UDF or IEX trap based on the content of parameter act */
-#define DISABLE_UDF_IEX_TRAP 0
-/* Enable UDF or IEX trap based on the content of parameter act */
-#define ENABLE_UDF_IEX_TRAP 1
-/* Get current status of UDF and IEX trap */
-#define GET_UDF_IEX_TRAP 2
-
-#endif /* _FP_UDF_IEX_CRTL_H */
diff --git a/arch/nds32/include/uapi/asm/param.h b/arch/nds32/include/uapi/asm/param.h
deleted file mode 100644
index 48d00328d328..000000000000
--- a/arch/nds32/include/uapi/asm/param.h
+++ /dev/null
@@ -1,11 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
-// Copyright (C) 2005-2017 Andes Technology Corporation
-
-#ifndef __ASM_NDS32_PARAM_H
-#define __ASM_NDS32_PARAM_H
-
-#define EXEC_PAGESIZE 8192
-
-#include <asm-generic/param.h>
-
-#endif /* __ASM_NDS32_PARAM_H */
diff --git a/arch/nds32/include/uapi/asm/ptrace.h b/arch/nds32/include/uapi/asm/ptrace.h
deleted file mode 100644
index d76217c7c010..000000000000
--- a/arch/nds32/include/uapi/asm/ptrace.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
-// Copyright (C) 2005-2017 Andes Technology Corporation
-
-#ifndef __UAPI_ASM_NDS32_PTRACE_H
-#define __UAPI_ASM_NDS32_PTRACE_H
-
-#ifndef __ASSEMBLY__
-
-/*
- * User structures for general purpose register.
- */
-struct user_pt_regs {
- long uregs[26];
- long fp;
- long gp;
- long lp;
- long sp;
- long ipc;
- long lb;
- long le;
- long lc;
- long syscallno;
-};
-#endif
-#endif
diff --git a/arch/nds32/include/uapi/asm/sigcontext.h b/arch/nds32/include/uapi/asm/sigcontext.h
deleted file mode 100644
index 6c1e6648878f..000000000000
--- a/arch/nds32/include/uapi/asm/sigcontext.h
+++ /dev/null
@@ -1,84 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
-// Copyright (C) 2005-2017 Andes Technology Corporation
-
-#ifndef _ASMNDS32_SIGCONTEXT_H
-#define _ASMNDS32_SIGCONTEXT_H
-
-/*
- * Signal context structure - contains all info to do with the state
- * before the signal handler was invoked. Note: only add new entries
- * to the end of the structure.
- */
-struct fpu_struct {
- unsigned long long fd_regs[32];
- unsigned long fpcsr;
- /*
- * When CONFIG_SUPPORT_DENORMAL_ARITHMETIC is defined, kernel prevents
- * hardware from treating the denormalized output as an underflow case
- * and rounding it to a normal number. Hence kernel enables the UDF and
- * IEX trap in the fpcsr register to step in the calculation.
- * However, the UDF and IEX trap enable bit in $fpcsr also lose
- * their use.
- *
- * UDF_IEX_trap replaces the feature of UDF and IEX trap enable bit in
- * $fpcsr to control the trap of underflow and inexact. The bit filed
- * of UDF_IEX_trap is the same as $fpcsr, 10th bit is used to enable UDF
- * exception trapping and 11th bit is used to enable IEX exception
- * trapping.
- *
- * UDF_IEX_trap is only modified through fp_udfiex_crtl syscall.
- * Therefore, UDF_IEX_trap needn't be saved and restored in each
- * context switch.
- */
- unsigned long UDF_IEX_trap;
-};
-
-struct zol_struct {
- unsigned long nds32_lc; /* $LC */
- unsigned long nds32_le; /* $LE */
- unsigned long nds32_lb; /* $LB */
-};
-
-struct sigcontext {
- unsigned long trap_no;
- unsigned long error_code;
- unsigned long oldmask;
- unsigned long nds32_r0;
- unsigned long nds32_r1;
- unsigned long nds32_r2;
- unsigned long nds32_r3;
- unsigned long nds32_r4;
- unsigned long nds32_r5;
- unsigned long nds32_r6;
- unsigned long nds32_r7;
- unsigned long nds32_r8;
- unsigned long nds32_r9;
- unsigned long nds32_r10;
- unsigned long nds32_r11;
- unsigned long nds32_r12;
- unsigned long nds32_r13;
- unsigned long nds32_r14;
- unsigned long nds32_r15;
- unsigned long nds32_r16;
- unsigned long nds32_r17;
- unsigned long nds32_r18;
- unsigned long nds32_r19;
- unsigned long nds32_r20;
- unsigned long nds32_r21;
- unsigned long nds32_r22;
- unsigned long nds32_r23;
- unsigned long nds32_r24;
- unsigned long nds32_r25;
- unsigned long nds32_fp; /* $r28 */
- unsigned long nds32_gp; /* $r29 */
- unsigned long nds32_lp; /* $r30 */
- unsigned long nds32_sp; /* $r31 */
- unsigned long nds32_ipc;
- unsigned long fault_address;
- unsigned long used_math_flag;
- /* FPU Registers */
- struct fpu_struct fpu;
- struct zol_struct zol;
-};
-
-#endif
diff --git a/arch/nds32/include/uapi/asm/unistd.h b/arch/nds32/include/uapi/asm/unistd.h
deleted file mode 100644
index 410795e280fe..000000000000
--- a/arch/nds32/include/uapi/asm/unistd.h
+++ /dev/null
@@ -1,16 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
-// Copyright (C) 2005-2017 Andes Technology Corporation
-
-#define __ARCH_WANT_STAT64
-#define __ARCH_WANT_SYNC_FILE_RANGE2
-#define __ARCH_WANT_SET_GET_RLIMIT
-#define __ARCH_WANT_TIME32_SYSCALLS
-
-/* Use the standard ABI for syscalls */
-#include <asm-generic/unistd.h>
-
-/* Additional NDS32 specific syscalls. */
-#define __NR_cacheflush (__NR_arch_specific_syscall)
-#define __NR_fp_udfiex_crtl (__NR_arch_specific_syscall + 1)
-__SYSCALL(__NR_cacheflush, sys_cacheflush)
-__SYSCALL(__NR_fp_udfiex_crtl, sys_fp_udfiex_crtl)
diff --git a/arch/nds32/kernel/Makefile b/arch/nds32/kernel/Makefile
deleted file mode 100644
index 394df3f6442c..000000000000
--- a/arch/nds32/kernel/Makefile
+++ /dev/null
@@ -1,33 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0-only
-#
-# Makefile for the linux kernel.
-#
-
-CPPFLAGS_vmlinux.lds := -DTEXTADDR=$(TEXTADDR)
-AFLAGS_head.o := -DTEXTADDR=$(TEXTADDR)
-# Object file lists.
-
-obj-y := ex-entry.o ex-exit.o ex-scall.o irq.o \
- process.o ptrace.o setup.o signal.o \
- sys_nds32.o time.o traps.o cacheinfo.o \
- dma.o syscall_table.o vdso.o
-
-obj-$(CONFIG_MODULES) += nds32_ksyms.o module.o
-obj-$(CONFIG_STACKTRACE) += stacktrace.o
-obj-$(CONFIG_FPU) += fpu.o
-obj-$(CONFIG_OF) += devtree.o
-obj-$(CONFIG_CACHE_L2) += atl2c.o
-obj-$(CONFIG_PERF_EVENTS) += perf_event_cpu.o
-obj-$(CONFIG_PM) += pm.o sleep.o
-extra-y := head.o vmlinux.lds
-
-CFLAGS_fpu.o += -mext-fpu-sp -mext-fpu-dp
-
-
-obj-y += vdso/
-
-obj-$(CONFIG_FUNCTION_TRACER) += ftrace.o
-
-ifdef CONFIG_FUNCTION_TRACER
-CFLAGS_REMOVE_ftrace.o = $(CC_FLAGS_FTRACE)
-endif
diff --git a/arch/nds32/kernel/asm-offsets.c b/arch/nds32/kernel/asm-offsets.c
deleted file mode 100644
index 3541d5981de7..000000000000
--- a/arch/nds32/kernel/asm-offsets.c
+++ /dev/null
@@ -1,28 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-// Copyright (C) 2005-2017 Andes Technology Corporation
-
-#include <linux/sched.h>
-#include <linux/sched/task_stack.h>
-#include <linux/kbuild.h>
-#include <asm/thread_info.h>
-#include <asm/ptrace.h>
-
-int main(void)
-{
- DEFINE(TSK_TI_FLAGS, offsetof(struct task_struct, thread_info.flags));
- DEFINE(TSK_TI_PREEMPT,
- offsetof(struct task_struct, thread_info.preempt_count));
- DEFINE(THREAD_CPU_CONTEXT,
- offsetof(struct task_struct, thread.cpu_context));
- DEFINE(OSP_OFFSET, offsetof(struct pt_regs, osp));
- DEFINE(SP_OFFSET, offsetof(struct pt_regs, sp));
- DEFINE(FUCOP_CTL_OFFSET, offsetof(struct pt_regs, fucop_ctl));
- DEFINE(IPSW_OFFSET, offsetof(struct pt_regs, ipsw));
- DEFINE(SYSCALLNO_OFFSET, offsetof(struct pt_regs, syscallno));
- DEFINE(IPC_OFFSET, offsetof(struct pt_regs, ipc));
- DEFINE(R0_OFFSET, offsetof(struct pt_regs, uregs[0]));
- DEFINE(R15_OFFSET, offsetof(struct pt_regs, uregs[15]));
- DEFINE(CLOCK_REALTIME_RES, MONOTONIC_RES_NSEC);
- DEFINE(CLOCK_COARSE_RES, LOW_RES_NSEC);
- return 0;
-}
diff --git a/arch/nds32/kernel/atl2c.c b/arch/nds32/kernel/atl2c.c
deleted file mode 100644
index 0c5386e72098..000000000000
--- a/arch/nds32/kernel/atl2c.c
+++ /dev/null
@@ -1,65 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-// Copyright (C) 2005-2017 Andes Technology Corporation
-
-#include <linux/compiler.h>
-#include <linux/of_address.h>
-#include <linux/of_fdt.h>
-#include <linux/of_platform.h>
-#include <asm/l2_cache.h>
-
-void __iomem *atl2c_base;
-static const struct of_device_id atl2c_ids[] __initconst = {
- {.compatible = "andestech,atl2c",},
- {}
-};
-
-static int __init atl2c_of_init(void)
-{
- struct device_node *np;
- struct resource res;
- unsigned long tmp = 0;
- unsigned long l2set, l2way, l2clsz;
-
- if (!(__nds32__mfsr(NDS32_SR_MSC_CFG) & MSC_CFG_mskL2C))
- return -ENODEV;
-
- np = of_find_matching_node(NULL, atl2c_ids);
- if (!np)
- return -ENODEV;
-
- if (of_address_to_resource(np, 0, &res))
- return -ENODEV;
-
- atl2c_base = ioremap(res.start, resource_size(&res));
- if (!atl2c_base)
- return -ENOMEM;
-
- l2set =
- 64 << ((L2C_R_REG(L2_CA_CONF_OFF) & L2_CA_CONF_mskL2SET) >>
- L2_CA_CONF_offL2SET);
- l2way =
- 1 +
- ((L2C_R_REG(L2_CA_CONF_OFF) & L2_CA_CONF_mskL2WAY) >>
- L2_CA_CONF_offL2WAY);
- l2clsz =
- 4 << ((L2C_R_REG(L2_CA_CONF_OFF) & L2_CA_CONF_mskL2CLSZ) >>
- L2_CA_CONF_offL2CLSZ);
- pr_info("L2:%luKB/%luS/%luW/%luB\n",
- l2set * l2way * l2clsz / 1024, l2set, l2way, l2clsz);
-
- tmp = L2C_R_REG(L2CC_PROT_OFF);
- tmp &= ~L2CC_PROT_mskMRWEN;
- L2C_W_REG(L2CC_PROT_OFF, tmp);
-
- tmp = L2C_R_REG(L2CC_SETUP_OFF);
- tmp &= ~L2CC_SETUP_mskPART;
- L2C_W_REG(L2CC_SETUP_OFF, tmp);
-
- tmp = L2C_R_REG(L2CC_CTRL_OFF);
- tmp |= L2CC_CTRL_mskEN;
- L2C_W_REG(L2CC_CTRL_OFF, tmp);
-
- return 0;
-}
-
-subsys_initcall(atl2c_of_init);
diff --git a/arch/nds32/kernel/cacheinfo.c b/arch/nds32/kernel/cacheinfo.c
deleted file mode 100644
index aab98e447feb..000000000000
--- a/arch/nds32/kernel/cacheinfo.c
+++ /dev/null
@@ -1,49 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-// Copyright (C) 2005-2017 Andes Technology Corporation
-
-#include <linux/bitops.h>
-#include <linux/cacheinfo.h>
-#include <linux/cpu.h>
-
-static void ci_leaf_init(struct cacheinfo *this_leaf,
- enum cache_type type, unsigned int level)
-{
- char cache_type = (type & CACHE_TYPE_INST ? ICACHE : DCACHE);
-
- this_leaf->level = level;
- this_leaf->type = type;
- this_leaf->coherency_line_size = CACHE_LINE_SIZE(cache_type);
- this_leaf->number_of_sets = CACHE_SET(cache_type);
- this_leaf->ways_of_associativity = CACHE_WAY(cache_type);
- this_leaf->size = this_leaf->number_of_sets *
- this_leaf->coherency_line_size * this_leaf->ways_of_associativity;
-#if defined(CONFIG_CPU_DCACHE_WRITETHROUGH)
- this_leaf->attributes = CACHE_WRITE_THROUGH;
-#else
- this_leaf->attributes = CACHE_WRITE_BACK;
-#endif
-}
-
-int init_cache_level(unsigned int cpu)
-{
- struct cpu_cacheinfo *this_cpu_ci = get_cpu_cacheinfo(cpu);
-
- /* Only 1 level and I/D cache seperate. */
- this_cpu_ci->num_levels = 1;
- this_cpu_ci->num_leaves = 2;
- return 0;
-}
-
-int populate_cache_leaves(unsigned int cpu)
-{
- unsigned int level, idx;
- struct cpu_cacheinfo *this_cpu_ci = get_cpu_cacheinfo(cpu);
- struct cacheinfo *this_leaf = this_cpu_ci->info_list;
-
- for (idx = 0, level = 1; level <= this_cpu_ci->num_levels &&
- idx < this_cpu_ci->num_leaves; idx++, level++) {
- ci_leaf_init(this_leaf++, CACHE_TYPE_DATA, level);
- ci_leaf_init(this_leaf++, CACHE_TYPE_INST, level);
- }
- return 0;
-}
diff --git a/arch/nds32/kernel/devtree.c b/arch/nds32/kernel/devtree.c
deleted file mode 100644
index bdce0fe5af9f..000000000000
--- a/arch/nds32/kernel/devtree.c
+++ /dev/null
@@ -1,19 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-// Copyright (C) 2005-2017 Andes Technology Corporation
-
-#include <linux/bug.h>
-#include <linux/printk.h>
-#include <linux/of_fdt.h>
-
-void __init early_init_devtree(void *params)
-{
- if (!params || !early_init_dt_scan(params)) {
- pr_crit("\n"
- "Error: invalid device tree blob at (virtual address 0x%p)\n"
- "\nPlease check your bootloader.", params);
-
- BUG_ON(1);
- }
-
- dump_stack_set_arch_desc("%s (DT)", of_flat_dt_get_machine_name());
-}
diff --git a/arch/nds32/kernel/dma.c b/arch/nds32/kernel/dma.c
deleted file mode 100644
index 2ac8e6c82a61..000000000000
--- a/arch/nds32/kernel/dma.c
+++ /dev/null
@@ -1,82 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-// Copyright (C) 2005-2017 Andes Technology Corporation
-
-#include <linux/types.h>
-#include <linux/mm.h>
-#include <linux/dma-map-ops.h>
-#include <linux/cache.h>
-#include <linux/highmem.h>
-#include <asm/cacheflush.h>
-#include <asm/tlbflush.h>
-#include <asm/proc-fns.h>
-
-static inline void cache_op(phys_addr_t paddr, size_t size,
- void (*fn)(unsigned long start, unsigned long end))
-{
- struct page *page = pfn_to_page(paddr >> PAGE_SHIFT);
- unsigned offset = paddr & ~PAGE_MASK;
- size_t left = size;
- unsigned long start;
-
- do {
- size_t len = left;
-
- if (PageHighMem(page)) {
- void *addr;
-
- if (offset + len > PAGE_SIZE) {
- if (offset >= PAGE_SIZE) {
- page += offset >> PAGE_SHIFT;
- offset &= ~PAGE_MASK;
- }
- len = PAGE_SIZE - offset;
- }
-
- addr = kmap_atomic(page);
- start = (unsigned long)(addr + offset);
- fn(start, start + len);
- kunmap_atomic(addr);
- } else {
- start = (unsigned long)phys_to_virt(paddr);
- fn(start, start + size);
- }
- offset = 0;
- page++;
- left -= len;
- } while (left);
-}
-
-void arch_sync_dma_for_device(phys_addr_t paddr, size_t size,
- enum dma_data_direction dir)
-{
- switch (dir) {
- case DMA_FROM_DEVICE:
- break;
- case DMA_TO_DEVICE:
- case DMA_BIDIRECTIONAL:
- cache_op(paddr, size, cpu_dma_wb_range);
- break;
- default:
- BUG();
- }
-}
-
-void arch_sync_dma_for_cpu(phys_addr_t paddr, size_t size,
- enum dma_data_direction dir)
-{
- switch (dir) {
- case DMA_TO_DEVICE:
- break;
- case DMA_FROM_DEVICE:
- case DMA_BIDIRECTIONAL:
- cache_op(paddr, size, cpu_dma_inval_range);
- break;
- default:
- BUG();
- }
-}
-
-void arch_dma_prep_coherent(struct page *page, size_t size)
-{
- cache_op(page_to_phys(page), size, cpu_dma_wbinval_range);
-}
diff --git a/arch/nds32/kernel/ex-entry.S b/arch/nds32/kernel/ex-entry.S
deleted file mode 100644
index 107d98a1d1b8..000000000000
--- a/arch/nds32/kernel/ex-entry.S
+++ /dev/null
@@ -1,177 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-// Copyright (C) 2005-2017 Andes Technology Corporation
-
-#include <linux/linkage.h>
-#include <asm/memory.h>
-#include <asm/nds32.h>
-#include <asm/errno.h>
-#include <asm/asm-offsets.h>
-#include <asm/page.h>
-#include <asm/fpu.h>
-
-#ifdef CONFIG_HWZOL
- .macro push_zol
- mfusr $r14, $LB
- mfusr $r15, $LE
- mfusr $r16, $LC
- .endm
-#endif
- .macro skip_save_fucop_ctl
-#if defined(CONFIG_FPU)
-skip_fucop_ctl:
- smw.adm $p0, [$sp], $p0, #0x1
- j fucop_ctl_done
-#endif
- .endm
-
- .macro save_user_regs
-#if defined(CONFIG_FPU)
- sethi $p0, hi20(has_fpu)
- lbsi $p0, [$p0+lo12(has_fpu)]
- beqz $p0, skip_fucop_ctl
- mfsr $p0, $FUCOP_CTL
- smw.adm $p0, [$sp], $p0, #0x1
- bclr $p0, $p0, #FUCOP_CTL_offCP0EN
- mtsr $p0, $FUCOP_CTL
-fucop_ctl_done:
- /* move $SP to the bottom of pt_regs */
- addi $sp, $sp, -FUCOP_CTL_OFFSET
-#else
- smw.adm $sp, [$sp], $sp, #0x1
- /* move $SP to the bottom of pt_regs */
- addi $sp, $sp, -OSP_OFFSET
-#endif
-
- /* push $r0 ~ $r25 */
- smw.bim $r0, [$sp], $r25
- /* push $fp, $gp, $lp */
- smw.bim $sp, [$sp], $sp, #0xe
-
- mfsr $r12, $SP_USR
- mfsr $r13, $IPC
-#ifdef CONFIG_HWZOL
- push_zol
-#endif
- movi $r17, -1
- move $r18, $r0
- mfsr $r19, $PSW
- mfsr $r20, $IPSW
- mfsr $r21, $P_IPSW
- mfsr $r22, $P_IPC
- mfsr $r23, $P_P0
- mfsr $r24, $P_P1
- smw.bim $r12, [$sp], $r24, #0
- addi $sp, $sp, -FUCOP_CTL_OFFSET
-
- /* Initialize kernel space $fp */
- andi $p0, $r20, #PSW_mskPOM
- movi $p1, #0x0
- cmovz $fp, $p1, $p0
-
- andi $r16, $r19, #PSW_mskINTL
- slti $r17, $r16, #4
- bnez $r17, 1f
- addi $r17, $r19, #-2
- mtsr $r17, $PSW
- isb
-1:
- /* If it was superuser mode, we don't need to update $r25 */
- bnez $p0, 2f
- la $p0, __entry_task
- lw $r25, [$p0]
-2:
- .endm
-
- .text
-
-/*
- * Exception Vector
- */
-exception_handlers:
- .long unhandled_exceptions !Reset/NMI
- .long unhandled_exceptions !TLB fill
- .long do_page_fault !PTE not present
- .long do_dispatch_tlb_misc !TLB misc
- .long unhandled_exceptions !TLB VLPT
- .long unhandled_exceptions !Machine Error
- .long do_debug_trap !Debug related
- .long do_dispatch_general !General exception
- .long eh_syscall !Syscall
- .long asm_do_IRQ !IRQ
-
- skip_save_fucop_ctl
-common_exception_handler:
- save_user_regs
- mfsr $p0, $ITYPE
- andi $p0, $p0, #ITYPE_mskVECTOR
- srli $p0, $p0, #ITYPE_offVECTOR
- andi $p1, $p0, #NDS32_VECTOR_mskNONEXCEPTION
- bnez $p1, 1f
- sethi $lp, hi20(ret_from_exception)
- ori $lp, $lp, lo12(ret_from_exception)
- sethi $p1, hi20(exception_handlers)
- ori $p1, $p1, lo12(exception_handlers)
- lw $p1, [$p1+$p0<<2]
- move $r0, $p0
- mfsr $r1, $EVA
- mfsr $r2, $ITYPE
- move $r3, $sp
- mfsr $r4, $OIPC
- /* enable gie if it is enabled in IPSW. */
- mfsr $r21, $PSW
- andi $r20, $r20, #PSW_mskGIE /* r20 is $IPSW*/
- or $r21, $r21, $r20
- mtsr $r21, $PSW
- dsb
- jr $p1
- /* syscall */
-1:
- addi $p1, $p0, #-NDS32_VECTOR_offEXCEPTION
- bnez $p1, 2f
- sethi $lp, hi20(ret_from_exception)
- ori $lp, $lp, lo12(ret_from_exception)
- sethi $p1, hi20(exception_handlers)
- ori $p1, $p1, lo12(exception_handlers)
- lwi $p1, [$p1+#NDS32_VECTOR_offEXCEPTION<<2]
- jr $p1
-
- /* interrupt */
-2:
-#ifdef CONFIG_TRACE_IRQFLAGS
- jal __trace_hardirqs_off
-#endif
- move $r0, $sp
- sethi $lp, hi20(ret_from_intr)
- ori $lp, $lp, lo12(ret_from_intr)
- sethi $p0, hi20(exception_handlers)
- ori $p0, $p0, lo12(exception_handlers)
- lwi $p0, [$p0+#NDS32_VECTOR_offINTERRUPT<<2]
- jr $p0
-
- .macro EXCEPTION_VECTOR_DEBUG
- .align 4
- mfsr $p0, $EDM_CTL
- andi $p0, $p0, EDM_CTL_mskV3_EDM_MODE
- tnez $p0, SWID_RAISE_INTERRUPT_LEVEL
- .endm
-
- .macro EXCEPTION_VECTOR
- .align 4
- sethi $p0, hi20(common_exception_handler)
- ori $p0, $p0, lo12(common_exception_handler)
- jral.ton $p0, $p0
- .endm
-
- .section ".text.init", #alloc, #execinstr
- .global exception_vector
-exception_vector:
-.rept 6
- EXCEPTION_VECTOR
-.endr
- EXCEPTION_VECTOR_DEBUG
-.rept 121
- EXCEPTION_VECTOR
-.endr
- .align 4
- .global exception_vector_end
-exception_vector_end:
diff --git a/arch/nds32/kernel/ex-exit.S b/arch/nds32/kernel/ex-exit.S
deleted file mode 100644
index b30699911b81..000000000000
--- a/arch/nds32/kernel/ex-exit.S
+++ /dev/null
@@ -1,193 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-// Copyright (C) 2005-2017 Andes Technology Corporation
-
-#include <linux/linkage.h>
-#include <asm/unistd.h>
-#include <asm/assembler.h>
-#include <asm/nds32.h>
-#include <asm/asm-offsets.h>
-#include <asm/thread_info.h>
-#include <asm/current.h>
-#include <asm/fpu.h>
-
-
-
-#ifdef CONFIG_HWZOL
- .macro pop_zol
- mtusr $r14, $LB
- mtusr $r15, $LE
- mtusr $r16, $LC
- .endm
-#endif
-
- .macro restore_user_regs_first
- setgie.d
- isb
-#if defined(CONFIG_FPU)
- addi $sp, $sp, OSP_OFFSET
- lmw.adm $r12, [$sp], $r25, #0x0
- sethi $p0, hi20(has_fpu)
- lbsi $p0, [$p0+lo12(has_fpu)]
- beqz $p0, 2f
- mtsr $r25, $FUCOP_CTL
-2:
-#else
- addi $sp, $sp, FUCOP_CTL_OFFSET
- lmw.adm $r12, [$sp], $r24, #0x0
-#endif
- mtsr $r12, $SP_USR
- mtsr $r13, $IPC
-#ifdef CONFIG_HWZOL
- pop_zol
-#endif
- mtsr $r19, $PSW
- mtsr $r20, $IPSW
- mtsr $r21, $P_IPSW
- mtsr $r22, $P_IPC
- mtsr $r23, $P_P0
- mtsr $r24, $P_P1
- lmw.adm $sp, [$sp], $sp, #0xe
- .endm
-
- .macro restore_user_regs_last
- pop $p0
- cmovn $sp, $p0, $p0
-
- iret
- nop
-
- .endm
-
- .macro restore_user_regs
- restore_user_regs_first
- lmw.adm $r0, [$sp], $r25, #0x0
- addi $sp, $sp, OSP_OFFSET
- restore_user_regs_last
- .endm
-
- .macro fast_restore_user_regs
- restore_user_regs_first
- lmw.adm $r1, [$sp], $r25, #0x0
- addi $sp, $sp, OSP_OFFSET-4
- restore_user_regs_last
- .endm
-
-#ifdef CONFIG_PREEMPTION
- .macro preempt_stop
- .endm
-#else
- .macro preempt_stop
- setgie.d
- isb
- .endm
-#define resume_kernel no_work_pending
-#endif
-
-ENTRY(ret_from_exception)
- preempt_stop
-ENTRY(ret_from_intr)
-
-/*
- * judge Kernel or user mode
- *
- */
- lwi $p0, [$sp+(#IPSW_OFFSET)] ! Check if in nested interrupt
- andi $p0, $p0, #PSW_mskINTL
- bnez $p0, resume_kernel ! done with iret
- j resume_userspace
-
-
-/*
- * This is the fast syscall return path. We do as little as
- * possible here, and this includes saving $r0 back into the SVC
- * stack.
- * fixed: tsk - $r25, syscall # - $r7, syscall table pointer - $r8
- */
-ENTRY(ret_fast_syscall)
- gie_disable
- lwi $r1, [tsk+#TSK_TI_FLAGS]
- andi $p1, $r1, #_TIF_WORK_MASK
- bnez $p1, fast_work_pending
- fast_restore_user_regs ! iret
-
-/*
- * Ok, we need to do extra processing,
- * enter the slow path returning from syscall, while pending work.
- */
-fast_work_pending:
- swi $r0, [$sp+(#R0_OFFSET)] ! what is different from ret_from_exception
-work_pending:
- andi $p1, $r1, #_TIF_NEED_RESCHED
- bnez $p1, work_resched
-
- andi $p1, $r1, #_TIF_SIGPENDING|#_TIF_NOTIFY_RESUME|#_TIF_NOTIFY_SIGNAL
- beqz $p1, no_work_pending
-
- move $r0, $sp ! 'regs'
- gie_enable
- bal do_notify_resume
- b ret_slow_syscall
-work_resched:
- bal schedule ! path, return to user mode
-
-/*
- * "slow" syscall return path.
- */
-ENTRY(resume_userspace)
-ENTRY(ret_slow_syscall)
- gie_disable
- lwi $p0, [$sp+(#IPSW_OFFSET)] ! Check if in nested interrupt
- andi $p0, $p0, #PSW_mskINTL
- bnez $p0, no_work_pending ! done with iret
- lwi $r1, [tsk+#TSK_TI_FLAGS]
- andi $p1, $r1, #_TIF_WORK_MASK
- bnez $p1, work_pending ! handle work_resched, sig_pend
-
-no_work_pending:
-#ifdef CONFIG_TRACE_IRQFLAGS
- lwi $p0, [$sp+(#IPSW_OFFSET)]
- andi $p0, $p0, #0x1
- la $r10, __trace_hardirqs_off
- la $r9, __trace_hardirqs_on
- cmovz $r9, $p0, $r10
- jral $r9
-#endif
- restore_user_regs ! return from iret
-
-
-/*
- * preemptive kernel
- */
-#ifdef CONFIG_PREEMPTION
-resume_kernel:
- gie_disable
- lwi $t0, [tsk+#TSK_TI_PREEMPT]
- bnez $t0, no_work_pending
-
- lwi $t0, [tsk+#TSK_TI_FLAGS]
- andi $p1, $t0, #_TIF_NEED_RESCHED
- beqz $p1, no_work_pending
-
- lwi $t0, [$sp+(#IPSW_OFFSET)] ! Interrupts off?
- andi $t0, $t0, #1
- beqz $t0, no_work_pending
-
- jal preempt_schedule_irq
- b no_work_pending
-#endif
-
-/*
- * This is how we return from a fork.
- */
-ENTRY(ret_from_fork)
- bal schedule_tail
- beqz $r6, 1f ! r6 stores fn for kernel thread
- move $r0, $r7 ! prepare kernel thread arg
- jral $r6
-1:
- lwi $r1, [tsk+#TSK_TI_FLAGS] ! check for syscall tracing
- andi $p1, $r1, #_TIF_WORK_SYSCALL_LEAVE ! are we tracing syscalls?
- beqz $p1, ret_slow_syscall
- move $r0, $sp
- bal syscall_trace_leave
- b ret_slow_syscall
diff --git a/arch/nds32/kernel/ex-scall.S b/arch/nds32/kernel/ex-scall.S
deleted file mode 100644
index 270050f1b7b1..000000000000
--- a/arch/nds32/kernel/ex-scall.S
+++ /dev/null
@@ -1,100 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-// Copyright (C) 2005-2017 Andes Technology Corporation
-
-#include <linux/linkage.h>
-#include <asm/unistd.h>
-#include <asm/assembler.h>
-#include <asm/nds32.h>
-#include <asm/asm-offsets.h>
-#include <asm/thread_info.h>
-#include <asm/current.h>
-
-/*
- * $r0 = previous task_struct,
- * $r1 = next task_struct,
- * previous and next are guaranteed not to be the same.
- */
-
-ENTRY(__switch_to)
-
- la $p0, __entry_task
- sw $r1, [$p0]
- addi $p1, $r0, #THREAD_CPU_CONTEXT
- smw.bi $r6, [$p1], $r14, #0xb ! push r6~r14, fp, lp, sp
- move $r25, $r1
-#if defined(CONFIG_FPU)
- call _switch_fpu
-#endif
- addi $r1, $r25, #THREAD_CPU_CONTEXT
- lmw.bi $r6, [$r1], $r14, #0xb ! pop r6~r14, fp, lp, sp
- ret
-
-
-#define tbl $r8
-
-/*
- * $r7 will be writen as syscall nr
- */
- .macro get_scno
- lwi $r7, [$sp + R15_OFFSET]
- swi $r7, [$sp + SYSCALLNO_OFFSET]
- .endm
-
- .macro updateipc
- addi $r17, $r13, #4 ! $r13 is $IPC
- swi $r17, [$sp + IPC_OFFSET]
- .endm
-
-ENTRY(eh_syscall)
- updateipc
-
- get_scno
- gie_enable
-
- lwi $p0, [tsk+#TSK_TI_FLAGS] ! check for syscall tracing
-
- andi $p1, $p0, #_TIF_WORK_SYSCALL_ENTRY ! are we tracing syscalls?
- bnez $p1, __sys_trace
-
- la $lp, ret_fast_syscall ! return address
-jmp_systbl:
- addi $p1, $r7, #-__NR_syscalls ! syscall number of syscall instruction is guarded by addembler
- bgez $p1, _SCNO_EXCEED ! call sys_* routine
- la tbl, sys_call_table ! load syscall table pointer
- slli $p1, $r7, #2
- add $p1, tbl, $p1
- lwi $p1, [$p1]
- jr $p1 ! no return
-
-_SCNO_EXCEED:
- ori $r0, $r7, #0
- ori $r1, $sp, #0
- b bad_syscall
-
-/*
- * This is the really slow path. We're going to be doing
- * context switches, and waiting for our parent to respond.
- */
-__sys_trace:
- move $r0, $sp
- bal syscall_trace_enter
- move $r7, $r0
- la $lp, __sys_trace_return ! return address
-
- addi $p1, $r7, #1
- beqz $p1, ret_slow_syscall ! fatal signal is pending
-
- addi $p1, $sp, #R0_OFFSET ! pointer to regs
- lmw.bi $r0, [$p1], $r5 ! have to reload $r0 - $r5
- b jmp_systbl
-
-__sys_trace_return:
- swi $r0, [$sp+#R0_OFFSET] ! T: save returned $r0
- move $r0, $sp ! set pt_regs for syscall_trace_leave
- bal syscall_trace_leave
- b ret_slow_syscall
-
-ENTRY(sys_rt_sigreturn_wrapper)
- addi $r0, $sp, #0
- b sys_rt_sigreturn
-ENDPROC(sys_rt_sigreturn_wrapper)
diff --git a/arch/nds32/kernel/fpu.c b/arch/nds32/kernel/fpu.c
deleted file mode 100644
index 701c09a668de..000000000000
--- a/arch/nds32/kernel/fpu.c
+++ /dev/null
@@ -1,266 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-// Copyright (C) 2005-2018 Andes Technology Corporation
-
-#include <linux/sched.h>
-#include <linux/signal.h>
-#include <linux/sched/signal.h>
-#include <asm/processor.h>
-#include <asm/user.h>
-#include <asm/io.h>
-#include <asm/bitfield.h>
-#include <asm/fpu.h>
-
-const struct fpu_struct init_fpuregs = {
- .fd_regs = {[0 ... 31] = sNAN64},
- .fpcsr = FPCSR_INIT,
-#if IS_ENABLED(CONFIG_SUPPORT_DENORMAL_ARITHMETIC)
- .UDF_IEX_trap = 0
-#endif
-};
-
-void save_fpu(struct task_struct *tsk)
-{
- unsigned int fpcfg, fpcsr;
-
- enable_fpu();
- fpcfg = ((__nds32__fmfcfg() & FPCFG_mskFREG) >> FPCFG_offFREG);
- switch (fpcfg) {
- case SP32_DP32_reg:
- asm volatile ("fsdi $fd31, [%0+0xf8]\n\t"
- "fsdi $fd30, [%0+0xf0]\n\t"
- "fsdi $fd29, [%0+0xe8]\n\t"
- "fsdi $fd28, [%0+0xe0]\n\t"
- "fsdi $fd27, [%0+0xd8]\n\t"
- "fsdi $fd26, [%0+0xd0]\n\t"
- "fsdi $fd25, [%0+0xc8]\n\t"
- "fsdi $fd24, [%0+0xc0]\n\t"
- "fsdi $fd23, [%0+0xb8]\n\t"
- "fsdi $fd22, [%0+0xb0]\n\t"
- "fsdi $fd21, [%0+0xa8]\n\t"
- "fsdi $fd20, [%0+0xa0]\n\t"
- "fsdi $fd19, [%0+0x98]\n\t"
- "fsdi $fd18, [%0+0x90]\n\t"
- "fsdi $fd17, [%0+0x88]\n\t"
- "fsdi $fd16, [%0+0x80]\n\t"
- : /* no output */
- : "r" (&tsk->thread.fpu)
- : "memory");
- fallthrough;
- case SP32_DP16_reg:
- asm volatile ("fsdi $fd15, [%0+0x78]\n\t"
- "fsdi $fd14, [%0+0x70]\n\t"
- "fsdi $fd13, [%0+0x68]\n\t"
- "fsdi $fd12, [%0+0x60]\n\t"
- "fsdi $fd11, [%0+0x58]\n\t"
- "fsdi $fd10, [%0+0x50]\n\t"
- "fsdi $fd9, [%0+0x48]\n\t"
- "fsdi $fd8, [%0+0x40]\n\t"
- : /* no output */
- : "r" (&tsk->thread.fpu)
- : "memory");
- fallthrough;
- case SP16_DP8_reg:
- asm volatile ("fsdi $fd7, [%0+0x38]\n\t"
- "fsdi $fd6, [%0+0x30]\n\t"
- "fsdi $fd5, [%0+0x28]\n\t"
- "fsdi $fd4, [%0+0x20]\n\t"
- : /* no output */
- : "r" (&tsk->thread.fpu)
- : "memory");
- fallthrough;
- case SP8_DP4_reg:
- asm volatile ("fsdi $fd3, [%1+0x18]\n\t"
- "fsdi $fd2, [%1+0x10]\n\t"
- "fsdi $fd1, [%1+0x8]\n\t"
- "fsdi $fd0, [%1+0x0]\n\t"
- "fmfcsr %0\n\t"
- "swi %0, [%1+0x100]\n\t"
- : "=&r" (fpcsr)
- : "r"(&tsk->thread.fpu)
- : "memory");
- }
- disable_fpu();
-}
-
-void load_fpu(const struct fpu_struct *fpregs)
-{
- unsigned int fpcfg, fpcsr;
-
- enable_fpu();
- fpcfg = ((__nds32__fmfcfg() & FPCFG_mskFREG) >> FPCFG_offFREG);
- switch (fpcfg) {
- case SP32_DP32_reg:
- asm volatile ("fldi $fd31, [%0+0xf8]\n\t"
- "fldi $fd30, [%0+0xf0]\n\t"
- "fldi $fd29, [%0+0xe8]\n\t"
- "fldi $fd28, [%0+0xe0]\n\t"
- "fldi $fd27, [%0+0xd8]\n\t"
- "fldi $fd26, [%0+0xd0]\n\t"
- "fldi $fd25, [%0+0xc8]\n\t"
- "fldi $fd24, [%0+0xc0]\n\t"
- "fldi $fd23, [%0+0xb8]\n\t"
- "fldi $fd22, [%0+0xb0]\n\t"
- "fldi $fd21, [%0+0xa8]\n\t"
- "fldi $fd20, [%0+0xa0]\n\t"
- "fldi $fd19, [%0+0x98]\n\t"
- "fldi $fd18, [%0+0x90]\n\t"
- "fldi $fd17, [%0+0x88]\n\t"
- "fldi $fd16, [%0+0x80]\n\t"
- : /* no output */
- : "r" (fpregs));
- fallthrough;
- case SP32_DP16_reg:
- asm volatile ("fldi $fd15, [%0+0x78]\n\t"
- "fldi $fd14, [%0+0x70]\n\t"
- "fldi $fd13, [%0+0x68]\n\t"
- "fldi $fd12, [%0+0x60]\n\t"
- "fldi $fd11, [%0+0x58]\n\t"
- "fldi $fd10, [%0+0x50]\n\t"
- "fldi $fd9, [%0+0x48]\n\t"
- "fldi $fd8, [%0+0x40]\n\t"
- : /* no output */
- : "r" (fpregs));
- fallthrough;
- case SP16_DP8_reg:
- asm volatile ("fldi $fd7, [%0+0x38]\n\t"
- "fldi $fd6, [%0+0x30]\n\t"
- "fldi $fd5, [%0+0x28]\n\t"
- "fldi $fd4, [%0+0x20]\n\t"
- : /* no output */
- : "r" (fpregs));
- fallthrough;
- case SP8_DP4_reg:
- asm volatile ("fldi $fd3, [%1+0x18]\n\t"
- "fldi $fd2, [%1+0x10]\n\t"
- "fldi $fd1, [%1+0x8]\n\t"
- "fldi $fd0, [%1+0x0]\n\t"
- "lwi %0, [%1+0x100]\n\t"
- "fmtcsr %0\n\t":"=&r" (fpcsr)
- : "r"(fpregs));
- }
- disable_fpu();
-}
-void store_fpu_for_suspend(void)
-{
-#ifdef CONFIG_LAZY_FPU
- if (last_task_used_math != NULL)
- save_fpu(last_task_used_math);
- last_task_used_math = NULL;
-#else
- if (!used_math())
- return;
- unlazy_fpu(current);
-#endif
- clear_fpu(task_pt_regs(current));
-}
-inline void do_fpu_context_switch(struct pt_regs *regs)
-{
- /* Enable to use FPU. */
-
- if (!user_mode(regs)) {
- pr_err("BUG: FPU is used in kernel mode.\n");
- BUG();
- return;
- }
-
- enable_ptreg_fpu(regs);
-#ifdef CONFIG_LAZY_FPU //Lazy FPU is used
- if (last_task_used_math == current)
- return;
- if (last_task_used_math != NULL)
- /* Other processes fpu state, save away */
- save_fpu(last_task_used_math);
- last_task_used_math = current;
-#endif
- if (used_math()) {
- load_fpu(&current->thread.fpu);
- } else {
- /* First time FPU user. */
- load_fpu(&init_fpuregs);
-#if IS_ENABLED(CONFIG_SUPPORT_DENORMAL_ARITHMETIC)
- current->thread.fpu.UDF_IEX_trap = init_fpuregs.UDF_IEX_trap;
-#endif
- set_used_math();
- }
-
-}
-
-inline void fill_sigfpe_signo(unsigned int fpcsr, int *signo)
-{
- if (fpcsr & FPCSR_mskOVFT)
- *signo = FPE_FLTOVF;
-#ifndef CONFIG_SUPPORT_DENORMAL_ARITHMETIC
- else if (fpcsr & FPCSR_mskUDFT)
- *signo = FPE_FLTUND;
-#endif
- else if (fpcsr & FPCSR_mskIVOT)
- *signo = FPE_FLTINV;
- else if (fpcsr & FPCSR_mskDBZT)
- *signo = FPE_FLTDIV;
- else if (fpcsr & FPCSR_mskIEXT)
- *signo = FPE_FLTRES;
-}
-
-inline void handle_fpu_exception(struct pt_regs *regs)
-{
- unsigned int fpcsr;
- int si_code = 0, si_signo = SIGFPE;
-#if IS_ENABLED(CONFIG_SUPPORT_DENORMAL_ARITHMETIC)
- unsigned long redo_except = FPCSR_mskDNIT|FPCSR_mskUDFT|FPCSR_mskIEXT;
-#else
- unsigned long redo_except = FPCSR_mskDNIT;
-#endif
-
- lose_fpu();
- fpcsr = current->thread.fpu.fpcsr;
-
- if (fpcsr & redo_except) {
- si_signo = do_fpuemu(regs, &current->thread.fpu);
- fpcsr = current->thread.fpu.fpcsr;
- if (!si_signo) {
- current->thread.fpu.fpcsr &= ~(redo_except);
- goto done;
- }
- } else if (fpcsr & FPCSR_mskRIT) {
- if (!user_mode(regs))
- make_task_dead(SIGILL);
- si_signo = SIGILL;
- }
-
- switch (si_signo) {
- case SIGFPE:
- fill_sigfpe_signo(fpcsr, &si_code);
- break;
- case SIGILL:
- show_regs(regs);
- si_code = ILL_COPROC;
- break;
- case SIGBUS:
- si_code = BUS_ADRERR;
- break;
- default:
- break;
- }
-
- force_sig_fault(si_signo, si_code,
- (void __user *)instruction_pointer(regs));
-done:
- own_fpu();
-}
-
-bool do_fpu_exception(unsigned int subtype, struct pt_regs *regs)
-{
- int done = true;
- /* Coprocessor disabled exception */
- if (subtype == FPU_DISABLE_EXCEPTION) {
- preempt_disable();
- do_fpu_context_switch(regs);
- preempt_enable();
- }
- /* Coprocessor exception such as underflow and overflow */
- else if (subtype == FPU_EXCEPTION)
- handle_fpu_exception(regs);
- else
- done = false;
- return done;
-}
diff --git a/arch/nds32/kernel/ftrace.c b/arch/nds32/kernel/ftrace.c
deleted file mode 100644
index 711bc8cd186d..000000000000
--- a/arch/nds32/kernel/ftrace.c
+++ /dev/null
@@ -1,278 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-
-#include <linux/ftrace.h>
-#include <linux/uaccess.h>
-#include <asm/cacheflush.h>
-
-#ifndef CONFIG_DYNAMIC_FTRACE
-extern void (*ftrace_trace_function)(unsigned long, unsigned long,
- struct ftrace_ops*, struct ftrace_regs*);
-extern void ftrace_graph_caller(void);
-
-noinline void __naked ftrace_stub(unsigned long ip, unsigned long parent_ip,
- struct ftrace_ops *op, struct ftrace_regs *fregs)
-{
- __asm__ (""); /* avoid to optimize as pure function */
-}
-
-noinline void _mcount(unsigned long parent_ip)
-{
- /* save all state by the compiler prologue */
-
- unsigned long ip = (unsigned long)__builtin_return_address(0);
-
- if (ftrace_trace_function != ftrace_stub)
- ftrace_trace_function(ip - MCOUNT_INSN_SIZE, parent_ip,
- NULL, NULL);
-
-#ifdef CONFIG_FUNCTION_GRAPH_TRACER
- if (ftrace_graph_return != (trace_func_graph_ret_t)ftrace_stub
- || ftrace_graph_entry != ftrace_graph_entry_stub)
- ftrace_graph_caller();
-#endif
-
- /* restore all state by the compiler epilogue */
-}
-EXPORT_SYMBOL(_mcount);
-
-#else /* CONFIG_DYNAMIC_FTRACE */
-
-noinline void __naked ftrace_stub(unsigned long ip, unsigned long parent_ip,
- struct ftrace_ops *op, struct ftrace_regs *fregs)
-{
- __asm__ (""); /* avoid to optimize as pure function */
-}
-
-noinline void __naked _mcount(unsigned long parent_ip)
-{
- __asm__ (""); /* avoid to optimize as pure function */
-}
-EXPORT_SYMBOL(_mcount);
-
-#define XSTR(s) STR(s)
-#define STR(s) #s
-void _ftrace_caller(unsigned long parent_ip)
-{
- /* save all state needed by the compiler prologue */
-
- /*
- * prepare arguments for real tracing function
- * first arg : __builtin_return_address(0) - MCOUNT_INSN_SIZE
- * second arg : parent_ip
- */
- __asm__ __volatile__ (
- "move $r1, %0 \n\t"
- "addi $r0, %1, #-" XSTR(MCOUNT_INSN_SIZE) "\n\t"
- :
- : "r" (parent_ip), "r" (__builtin_return_address(0)));
-
- /* a placeholder for the call to a real tracing function */
- __asm__ __volatile__ (
- "ftrace_call: \n\t"
- "nop \n\t"
- "nop \n\t"
- "nop \n\t");
-
-#ifdef CONFIG_FUNCTION_GRAPH_TRACER
- /* a placeholder for the call to ftrace_graph_caller */
- __asm__ __volatile__ (
- "ftrace_graph_call: \n\t"
- "nop \n\t"
- "nop \n\t"
- "nop \n\t");
-#endif
- /* restore all state needed by the compiler epilogue */
-}
-
-static unsigned long gen_sethi_insn(unsigned long addr)
-{
- unsigned long opcode = 0x46000000;
- unsigned long imm = addr >> 12;
- unsigned long rt_num = 0xf << 20;
-
- return ENDIAN_CONVERT(opcode | rt_num | imm);
-}
-
-static unsigned long gen_ori_insn(unsigned long addr)
-{
- unsigned long opcode = 0x58000000;
- unsigned long imm = addr & 0x0000fff;
- unsigned long rt_num = 0xf << 20;
- unsigned long ra_num = 0xf << 15;
-
- return ENDIAN_CONVERT(opcode | rt_num | ra_num | imm);
-}
-
-static unsigned long gen_jral_insn(unsigned long addr)
-{
- unsigned long opcode = 0x4a000001;
- unsigned long rt_num = 0x1e << 20;
- unsigned long rb_num = 0xf << 10;
-
- return ENDIAN_CONVERT(opcode | rt_num | rb_num);
-}
-
-static void ftrace_gen_call_insn(unsigned long *call_insns,
- unsigned long addr)
-{
- call_insns[0] = gen_sethi_insn(addr); /* sethi $r15, imm20u */
- call_insns[1] = gen_ori_insn(addr); /* ori $r15, $r15, imm15u */
- call_insns[2] = gen_jral_insn(addr); /* jral $lp, $r15 */
-}
-
-static int __ftrace_modify_code(unsigned long pc, unsigned long *old_insn,
- unsigned long *new_insn, bool validate)
-{
- unsigned long orig_insn[3];
-
- if (validate) {
- if (copy_from_kernel_nofault(orig_insn, (void *)pc,
- MCOUNT_INSN_SIZE))
- return -EFAULT;
- if (memcmp(orig_insn, old_insn, MCOUNT_INSN_SIZE))
- return -EINVAL;
- }
-
- if (copy_to_kernel_nofault((void *)pc, new_insn, MCOUNT_INSN_SIZE))
- return -EPERM;
-
- return 0;
-}
-
-static int ftrace_modify_code(unsigned long pc, unsigned long *old_insn,
- unsigned long *new_insn, bool validate)
-{
- int ret;
-
- ret = __ftrace_modify_code(pc, old_insn, new_insn, validate);
- if (ret)
- return ret;
-
- flush_icache_range(pc, pc + MCOUNT_INSN_SIZE);
-
- return ret;
-}
-
-int ftrace_update_ftrace_func(ftrace_func_t func)
-{
- unsigned long pc = (unsigned long)&ftrace_call;
- unsigned long old_insn[3] = {INSN_NOP, INSN_NOP, INSN_NOP};
- unsigned long new_insn[3] = {INSN_NOP, INSN_NOP, INSN_NOP};
-
- if (func != ftrace_stub)
- ftrace_gen_call_insn(new_insn, (unsigned long)func);
-
- return ftrace_modify_code(pc, old_insn, new_insn, false);
-}
-
-int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
-{
- unsigned long pc = rec->ip;
- unsigned long nop_insn[3] = {INSN_NOP, INSN_NOP, INSN_NOP};
- unsigned long call_insn[3] = {INSN_NOP, INSN_NOP, INSN_NOP};
-
- ftrace_gen_call_insn(call_insn, addr);
-
- return ftrace_modify_code(pc, nop_insn, call_insn, true);
-}
-
-int ftrace_make_nop(struct module *mod, struct dyn_ftrace *rec,
- unsigned long addr)
-{
- unsigned long pc = rec->ip;
- unsigned long nop_insn[3] = {INSN_NOP, INSN_NOP, INSN_NOP};
- unsigned long call_insn[3] = {INSN_NOP, INSN_NOP, INSN_NOP};
-
- ftrace_gen_call_insn(call_insn, addr);
-
- return ftrace_modify_code(pc, call_insn, nop_insn, true);
-}
-#endif /* CONFIG_DYNAMIC_FTRACE */
-
-#ifdef CONFIG_FUNCTION_GRAPH_TRACER
-void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr,
- unsigned long frame_pointer)
-{
- unsigned long return_hooker = (unsigned long)&return_to_handler;
- unsigned long old;
-
- if (unlikely(atomic_read(&current->tracing_graph_pause)))
- return;
-
- old = *parent;
-
- if (!function_graph_enter(old, self_addr, frame_pointer, NULL))
- *parent = return_hooker;
-}
-
-noinline void ftrace_graph_caller(void)
-{
- unsigned long *parent_ip =
- (unsigned long *)(__builtin_frame_address(2) - 4);
-
- unsigned long selfpc =
- (unsigned long)(__builtin_return_address(1) - MCOUNT_INSN_SIZE);
-
- unsigned long frame_pointer =
- (unsigned long)__builtin_frame_address(3);
-
- prepare_ftrace_return(parent_ip, selfpc, frame_pointer);
-}
-
-extern unsigned long ftrace_return_to_handler(unsigned long frame_pointer);
-void __naked return_to_handler(void)
-{
- __asm__ __volatile__ (
- /* save state needed by the ABI */
- "smw.adm $r0,[$sp],$r1,#0x0 \n\t"
-
- /* get original return address */
- "move $r0, $fp \n\t"
- "bal ftrace_return_to_handler\n\t"
- "move $lp, $r0 \n\t"
-
- /* restore state needed by the ABI */
- "lmw.bim $r0,[$sp],$r1,#0x0 \n\t");
-}
-
-#ifdef CONFIG_DYNAMIC_FTRACE
-extern unsigned long ftrace_graph_call;
-
-static int ftrace_modify_graph_caller(bool enable)
-{
- unsigned long pc = (unsigned long)&ftrace_graph_call;
- unsigned long nop_insn[3] = {INSN_NOP, INSN_NOP, INSN_NOP};
- unsigned long call_insn[3] = {INSN_NOP, INSN_NOP, INSN_NOP};
-
- ftrace_gen_call_insn(call_insn, (unsigned long)ftrace_graph_caller);
-
- if (enable)
- return ftrace_modify_code(pc, nop_insn, call_insn, true);
- else
- return ftrace_modify_code(pc, call_insn, nop_insn, true);
-}
-
-int ftrace_enable_ftrace_graph_caller(void)
-{
- return ftrace_modify_graph_caller(true);
-}
-
-int ftrace_disable_ftrace_graph_caller(void)
-{
- return ftrace_modify_graph_caller(false);
-}
-#endif /* CONFIG_DYNAMIC_FTRACE */
-
-#endif /* CONFIG_FUNCTION_GRAPH_TRACER */
-
-
-#ifdef CONFIG_TRACE_IRQFLAGS
-noinline void __trace_hardirqs_off(void)
-{
- trace_hardirqs_off();
-}
-noinline void __trace_hardirqs_on(void)
-{
- trace_hardirqs_on();
-}
-#endif /* CONFIG_TRACE_IRQFLAGS */
diff --git a/arch/nds32/kernel/head.S b/arch/nds32/kernel/head.S
deleted file mode 100644
index 7347f00451a9..000000000000
--- a/arch/nds32/kernel/head.S
+++ /dev/null
@@ -1,197 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-// Copyright (C) 2005-2017 Andes Technology Corporation
-
-#include <linux/linkage.h>
-#include <linux/init.h>
-#include <linux/pgtable.h>
-#include <asm/ptrace.h>
-#include <asm/asm-offsets.h>
-#include <asm/page.h>
-#include <linux/sizes.h>
-#include <asm/thread_info.h>
-
-#ifdef CONFIG_CPU_BIG_ENDIAN
-#define OF_DT_MAGIC 0xd00dfeed
-#else
-#define OF_DT_MAGIC 0xedfe0dd0
-#endif
-
- .globl swapper_pg_dir
- .equ swapper_pg_dir, TEXTADDR - 0x4000
-
-/*
- * Kernel startup entry point.
- */
- .section ".head.text", "ax"
- .type _stext, %function
-ENTRY(_stext)
- setgie.d ! Disable interrupt
- isb
-/*
- * Disable I/D-cache and enable it at a proper time
- */
- mfsr $r0, $mr8
- li $r1, #~(CACHE_CTL_mskIC_EN|CACHE_CTL_mskDC_EN)
- and $r0, $r0, $r1
- mtsr $r0, $mr8
-
-/*
- * Process device tree blob
- */
- andi $r0,$r2,#0x3
- li $r10, 0
- bne $r0, $r10, _nodtb
- lwi $r0, [$r2]
- li $r1, OF_DT_MAGIC
- bne $r0, $r1, _nodtb
- move $r10, $r2
-_nodtb:
-
-/*
- * Create a temporary mapping area for booting, before start_kernel
- */
- sethi $r4, hi20(swapper_pg_dir)
- li $p0, (PAGE_OFFSET - PHYS_OFFSET)
- sub $r4, $r4, $p0
- tlbop FlushAll ! invalidate TLB\n"
- isb
- mtsr $r4, $L1_PPTB ! load page table pointer\n"
-
-#ifdef CONFIG_CPU_DCACHE_DISABLE
- #define MMU_CTL_NTCC MMU_CTL_CACHEABLE_NON
-#else
- #ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
- #define MMU_CTL_NTCC MMU_CTL_CACHEABLE_WT
- #else
- #define MMU_CTL_NTCC MMU_CTL_CACHEABLE_WB
- #endif
-#endif
-
-/* set NTC cacheability, mutliple page size in use */
- mfsr $r3, $MMU_CTL
-#if CONFIG_MEMORY_START >= 0xc0000000
- ori $r3, $r3, (MMU_CTL_NTCC << MMU_CTL_offNTC3)
-#elif CONFIG_MEMORY_START >= 0x80000000
- ori $r3, $r3, (MMU_CTL_NTCC << MMU_CTL_offNTC2)
-#elif CONFIG_MEMORY_START >= 0x40000000
- ori $r3, $r3, (MMU_CTL_NTCC << MMU_CTL_offNTC1)
-#else
- ori $r3, $r3, (MMU_CTL_NTCC << MMU_CTL_offNTC0)
-#endif
-
-#ifdef CONFIG_ANDES_PAGE_SIZE_4KB
- ori $r3, $r3, #(MMU_CTL_mskMPZIU)
-#else
- ori $r3, $r3, #(MMU_CTL_mskMPZIU|MMU_CTL_D8KB)
-#endif
-#ifdef CONFIG_HW_SUPPORT_UNALIGNMENT_ACCESS
- li $r0, #MMU_CTL_UNA
- or $r3, $r3, $r0
-#endif
- mtsr $r3, $MMU_CTL
- isb
-
-/* set page size and size of kernel image */
- mfsr $r0, $MMU_CFG
- srli $r3, $r0, MMU_CFG_offfEPSZ
- zeb $r3, $r3
- bnez $r3, _extra_page_size_support
-#ifdef CONFIG_ANDES_PAGE_SIZE_4KB
- li $r5, #SZ_4K ! Use 4KB page size
-#else
- li $r5, #SZ_8K ! Use 8KB page size
- li $r3, #1
-#endif
- mtsr $r3, $TLB_MISC
- b _image_size_check
-
-_extra_page_size_support: ! Use epzs pages size
- clz $r6, $r3
- subri $r2, $r6, #31
- li $r3, #1
- sll $r3, $r3, $r2
- /* MMU_CFG.EPSZ value -> meaning */
- mul $r5, $r3, $r3
- slli $r5, $r5, #14
- /* MMU_CFG.EPSZ -> TLB_MISC.ACC_PSZ */
- addi $r3, $r2, #0x2
- mtsr $r3, $TLB_MISC
-
-_image_size_check:
- /* calculate the image maximum size accepted by TLB config */
- andi $r6, $r0, MMU_CFG_mskTBW
- andi $r0, $r0, MMU_CFG_mskTBS
- srli $r6, $r6, MMU_CFG_offTBW
- srli $r0, $r0, MMU_CFG_offTBS
- addi $r6, $r6, #0x1 ! MMU_CFG.TBW value -> meaning
- addi $r0, $r0, #0x2 ! MMU_CFG.TBS value -> meaning
- sll $r0, $r6, $r0 ! entries = k-way * n-set
- mul $r6, $r0, $r5 ! max size = entries * page size
- /* check kernel image size */
- la $r3, (_end - PAGE_OFFSET)
- bgt $r3, $r6, __error
-
- li $r2, #(PHYS_OFFSET + TLB_DATA_kernel_text_attr)
- li $r3, PAGE_OFFSET
- add $r6, $r6, $r3
-
-_tlb:
- mtsr $r3, $TLB_VPN
- dsb
- tlbop $r2, RWR
- isb
- add $r3, $r3, $r5
- add $r2, $r2, $r5
- bgt $r6, $r3, _tlb
- mfsr $r3, $TLB_MISC ! setup access page size
- li $r2, #~0xf
- and $r3, $r3, $r2
-#ifdef CONFIG_ANDES_PAGE_SIZE_8KB
- ori $r3, $r3, #0x1
-#endif
- mtsr $r3, $TLB_MISC
-
- mfsr $r0, $MISC_CTL ! Enable BTB, RTP, shadow sp, and HW_PRE
- ori $r0, $r0, #MISC_init
- mtsr $r0, $MISC_CTL
-
- mfsr $p1, $PSW
- li $r15, #~PSW_clr ! clear WBNA|DME|IME|DT|IT|POM|INTL|GIE
- and $p1, $p1, $r15
- ori $p1, $p1, #PSW_init
- mtsr $p1, $IPSW ! when iret, it will automatically enable MMU
- la $lp, __mmap_switched
- mtsr $lp, $IPC
- iret
- nop
-
- .type __switch_data, %object
-__switch_data:
- .long __bss_start ! $r6
- .long _end ! $r7
- .long __atags_pointer ! $atag_pointer
- .long init_task ! $r9, move to $r25
- .long init_thread_union + THREAD_SIZE ! $sp
-
-
-/*
- * The following fragment of code is executed with the MMU on in MMU mode,
- * and uses absolute addresses; this is not position independent.
- */
- .align
- .type __mmap_switched, %function
-__mmap_switched:
- la $r3, __switch_data
- lmw.bim $r6, [$r3], $r9, #0b0001
- move $r25, $r9
- move $fp, #0 ! Clear BSS (and zero $fp)
- beq $r7, $r6, _RRT
-1: swi.bi $fp, [$r6], #4
- bne $r7, $r6, 1b
- swi $r10, [$r8]
-
-_RRT:
- b start_kernel
-
-__error:
- b __error
diff --git a/arch/nds32/kernel/irq.c b/arch/nds32/kernel/irq.c
deleted file mode 100644
index 6ff5a672be27..000000000000
--- a/arch/nds32/kernel/irq.c
+++ /dev/null
@@ -1,9 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-// Copyright (C) 2005-2017 Andes Technology Corporation
-
-#include <linux/irqchip.h>
-
-void __init init_IRQ(void)
-{
- irqchip_init();
-}
diff --git a/arch/nds32/kernel/module.c b/arch/nds32/kernel/module.c
deleted file mode 100644
index 3897fd14a21d..000000000000
--- a/arch/nds32/kernel/module.c
+++ /dev/null
@@ -1,278 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-// Copyright (C) 2005-2017 Andes Technology Corporation
-
-#include <linux/module.h>
-#include <linux/elf.h>
-#include <linux/vmalloc.h>
-#include <linux/moduleloader.h>
-#include <linux/pgtable.h>
-
-void *module_alloc(unsigned long size)
-{
- return __vmalloc_node_range(size, 1, MODULES_VADDR, MODULES_END,
- GFP_KERNEL, PAGE_KERNEL, 0, NUMA_NO_NODE,
- __builtin_return_address(0));
-}
-
-void module_free(struct module *module, void *region)
-{
- vfree(region);
-}
-
-int module_frob_arch_sections(Elf_Ehdr * hdr,
- Elf_Shdr * sechdrs,
- char *secstrings, struct module *mod)
-{
- return 0;
-}
-
-void do_reloc16(unsigned int val, unsigned int *loc, unsigned int val_mask,
- unsigned int val_shift, unsigned int loc_mask,
- unsigned int partial_in_place, unsigned int swap)
-{
- unsigned int tmp = 0, tmp2 = 0;
-
- __asm__ __volatile__("\tlhi.bi\t%0, [%2], 0\n"
- "\tbeqz\t%3, 1f\n"
- "\twsbh\t%0, %1\n"
- "1:\n":"=r"(tmp):"0"(tmp), "r"(loc), "r"(swap)
- );
-
- tmp2 = tmp & loc_mask;
- if (partial_in_place) {
- tmp &= (~loc_mask);
- tmp =
- tmp2 | ((tmp + ((val & val_mask) >> val_shift)) & val_mask);
- } else {
- tmp = tmp2 | ((val & val_mask) >> val_shift);
- }
-
- __asm__ __volatile__("\tbeqz\t%3, 2f\n"
- "\twsbh\t%0, %1\n"
- "2:\n"
- "\tshi.bi\t%0, [%2], 0\n":"=r"(tmp):"0"(tmp),
- "r"(loc), "r"(swap)
- );
-}
-
-void do_reloc32(unsigned int val, unsigned int *loc, unsigned int val_mask,
- unsigned int val_shift, unsigned int loc_mask,
- unsigned int partial_in_place, unsigned int swap)
-{
- unsigned int tmp = 0, tmp2 = 0;
-
- __asm__ __volatile__("\tlmw.bi\t%0, [%2], %0, 0\n"
- "\tbeqz\t%3, 1f\n"
- "\twsbh\t%0, %1\n"
- "\trotri\t%0, %1, 16\n"
- "1:\n":"=r"(tmp):"0"(tmp), "r"(loc), "r"(swap)
- );
-
- tmp2 = tmp & loc_mask;
- if (partial_in_place) {
- tmp &= (~loc_mask);
- tmp =
- tmp2 | ((tmp + ((val & val_mask) >> val_shift)) & val_mask);
- } else {
- tmp = tmp2 | ((val & val_mask) >> val_shift);
- }
-
- __asm__ __volatile__("\tbeqz\t%3, 2f\n"
- "\twsbh\t%0, %1\n"
- "\trotri\t%0, %1, 16\n"
- "2:\n"
- "\tsmw.bi\t%0, [%2], %0, 0\n":"=r"(tmp):"0"(tmp),
- "r"(loc), "r"(swap)
- );
-}
-
-static inline int exceed_limit(int offset, unsigned int val_mask,
- struct module *module, Elf32_Rela * rel,
- unsigned int relindex, unsigned int reloc_order)
-{
- int abs_off = offset < 0 ? ~offset : offset;
-
- if (abs_off & (~val_mask)) {
- pr_err("\n%s: relocation type %d out of range.\n"
- "please rebuild the kernel module with gcc option \"-Wa,-mno-small-text\".\n",
- module->name, ELF32_R_TYPE(rel->r_info));
- pr_err("section %d reloc %d offset 0x%x relative 0x%x.\n",
- relindex, reloc_order, rel->r_offset, offset);
- return true;
- }
- return false;
-}
-
-#ifdef __NDS32_EL__
-#define NEED_SWAP 1
-#else
-#define NEED_SWAP 0
-#endif
-
-int
-apply_relocate_add(Elf32_Shdr * sechdrs, const char *strtab,
- unsigned int symindex, unsigned int relindex,
- struct module *module)
-{
- Elf32_Shdr *symsec = sechdrs + symindex;
- Elf32_Shdr *relsec = sechdrs + relindex;
- Elf32_Shdr *dstsec = sechdrs + relsec->sh_info;
- Elf32_Rela *rel = (void *)relsec->sh_addr;
- unsigned int i;
-
- for (i = 0; i < relsec->sh_size / sizeof(Elf32_Rela); i++, rel++) {
- Elf32_Addr *loc;
- Elf32_Sym *sym;
- Elf32_Addr v;
- s32 offset;
-
- offset = ELF32_R_SYM(rel->r_info);
- if (offset < 0
- || offset > (symsec->sh_size / sizeof(Elf32_Sym))) {
- pr_err("%s: bad relocation\n", module->name);
- pr_err("section %d reloc %d\n", relindex, i);
- return -ENOEXEC;
- }
-
- sym = ((Elf32_Sym *) symsec->sh_addr) + offset;
-
- if (rel->r_offset < 0
- || rel->r_offset > dstsec->sh_size - sizeof(u16)) {
- pr_err("%s: out of bounds relocation\n", module->name);
- pr_err("section %d reloc %d offset 0x%0x size %d\n",
- relindex, i, rel->r_offset, dstsec->sh_size);
- return -ENOEXEC;
- }
-
- loc = (Elf32_Addr *) (dstsec->sh_addr + rel->r_offset);
- v = sym->st_value + rel->r_addend;
-
- switch (ELF32_R_TYPE(rel->r_info)) {
- case R_NDS32_NONE:
- case R_NDS32_INSN16:
- case R_NDS32_LABEL:
- case R_NDS32_LONGCALL1:
- case R_NDS32_LONGCALL2:
- case R_NDS32_LONGCALL3:
- case R_NDS32_LONGCALL4:
- case R_NDS32_LONGJUMP1:
- case R_NDS32_LONGJUMP2:
- case R_NDS32_LONGJUMP3:
- case R_NDS32_9_FIXED_RELA:
- case R_NDS32_15_FIXED_RELA:
- case R_NDS32_17_FIXED_RELA:
- case R_NDS32_25_FIXED_RELA:
- case R_NDS32_LOADSTORE:
- case R_NDS32_DWARF2_OP1_RELA:
- case R_NDS32_DWARF2_OP2_RELA:
- case R_NDS32_DWARF2_LEB_RELA:
- case R_NDS32_RELA_NOP_MIX ... R_NDS32_RELA_NOP_MAX:
- break;
-
- case R_NDS32_32_RELA:
- do_reloc32(v, loc, 0xffffffff, 0, 0, 0, 0);
- break;
-
- case R_NDS32_HI20_RELA:
- do_reloc32(v, loc, 0xfffff000, 12, 0xfff00000, 0,
- NEED_SWAP);
- break;
-
- case R_NDS32_LO12S3_RELA:
- do_reloc32(v, loc, 0x00000fff, 3, 0xfffff000, 0,
- NEED_SWAP);
- break;
-
- case R_NDS32_LO12S2_RELA:
- do_reloc32(v, loc, 0x00000fff, 2, 0xfffff000, 0,
- NEED_SWAP);
- break;
-
- case R_NDS32_LO12S1_RELA:
- do_reloc32(v, loc, 0x00000fff, 1, 0xfffff000, 0,
- NEED_SWAP);
- break;
-
- case R_NDS32_LO12S0_RELA:
- case R_NDS32_LO12S0_ORI_RELA:
- do_reloc32(v, loc, 0x00000fff, 0, 0xfffff000, 0,
- NEED_SWAP);
- break;
-
- case R_NDS32_9_PCREL_RELA:
- if (exceed_limit
- ((v - (Elf32_Addr) loc), 0x000000ff, module, rel,
- relindex, i))
- return -ENOEXEC;
- do_reloc16(v - (Elf32_Addr) loc, loc, 0x000001ff, 1,
- 0xffffff00, 0, NEED_SWAP);
- break;
-
- case R_NDS32_15_PCREL_RELA:
- if (exceed_limit
- ((v - (Elf32_Addr) loc), 0x00003fff, module, rel,
- relindex, i))
- return -ENOEXEC;
- do_reloc32(v - (Elf32_Addr) loc, loc, 0x00007fff, 1,
- 0xffffc000, 0, NEED_SWAP);
- break;
-
- case R_NDS32_17_PCREL_RELA:
- if (exceed_limit
- ((v - (Elf32_Addr) loc), 0x0000ffff, module, rel,
- relindex, i))
- return -ENOEXEC;
- do_reloc32(v - (Elf32_Addr) loc, loc, 0x0001ffff, 1,
- 0xffff0000, 0, NEED_SWAP);
- break;
-
- case R_NDS32_25_PCREL_RELA:
- if (exceed_limit
- ((v - (Elf32_Addr) loc), 0x00ffffff, module, rel,
- relindex, i))
- return -ENOEXEC;
- do_reloc32(v - (Elf32_Addr) loc, loc, 0x01ffffff, 1,
- 0xff000000, 0, NEED_SWAP);
- break;
- case R_NDS32_WORD_9_PCREL_RELA:
- if (exceed_limit
- ((v - (Elf32_Addr) loc), 0x000000ff, module, rel,
- relindex, i))
- return -ENOEXEC;
- do_reloc32(v - (Elf32_Addr) loc, loc, 0x000001ff, 1,
- 0xffffff00, 0, NEED_SWAP);
- break;
-
- case R_NDS32_SDA15S3_RELA:
- case R_NDS32_SDA15S2_RELA:
- case R_NDS32_SDA15S1_RELA:
- case R_NDS32_SDA15S0_RELA:
- pr_err("%s: unsupported relocation type %d.\n",
- module->name, ELF32_R_TYPE(rel->r_info));
- pr_err
- ("Small data section access doesn't work in the kernel space; "
- "please rebuild the kernel module with gcc option -mcmodel=large.\n");
- pr_err("section %d reloc %d offset 0x%x size %d\n",
- relindex, i, rel->r_offset, dstsec->sh_size);
- break;
-
- default:
- pr_err("%s: unsupported relocation type %d.\n",
- module->name, ELF32_R_TYPE(rel->r_info));
- pr_err("section %d reloc %d offset 0x%x size %d\n",
- relindex, i, rel->r_offset, dstsec->sh_size);
- }
- }
- return 0;
-}
-
-int
-module_finalize(const Elf32_Ehdr * hdr, const Elf_Shdr * sechdrs,
- struct module *module)
-{
- return 0;
-}
-
-void module_arch_cleanup(struct module *mod)
-{
-}
diff --git a/arch/nds32/kernel/nds32_ksyms.c b/arch/nds32/kernel/nds32_ksyms.c
deleted file mode 100644
index 20719e42ae36..000000000000
--- a/arch/nds32/kernel/nds32_ksyms.c
+++ /dev/null
@@ -1,25 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-// Copyright (C) 2005-2017 Andes Technology Corporation
-
-#include <linux/module.h>
-#include <linux/string.h>
-#include <linux/delay.h>
-#include <linux/in6.h>
-#include <linux/syscalls.h>
-#include <linux/uaccess.h>
-
-#include <asm/checksum.h>
-#include <asm/io.h>
-#include <asm/ftrace.h>
-#include <asm/proc-fns.h>
-
-/* mem functions */
-EXPORT_SYMBOL(memset);
-EXPORT_SYMBOL(memcpy);
-EXPORT_SYMBOL(memmove);
-EXPORT_SYMBOL(memzero);
-
-/* user mem (segment) */
-EXPORT_SYMBOL(__arch_copy_from_user);
-EXPORT_SYMBOL(__arch_copy_to_user);
-EXPORT_SYMBOL(__arch_clear_user);
diff --git a/arch/nds32/kernel/perf_event_cpu.c b/arch/nds32/kernel/perf_event_cpu.c
deleted file mode 100644
index a78a879e7ef1..000000000000
--- a/arch/nds32/kernel/perf_event_cpu.c
+++ /dev/null
@@ -1,1500 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Copyright (C) 2008-2017 Andes Technology Corporation
- *
- * Reference ARMv7: Jean Pihet <jpihet@mvista.com>
- * 2010 (c) MontaVista Software, LLC.
- */
-
-#include <linux/perf_event.h>
-#include <linux/bitmap.h>
-#include <linux/export.h>
-#include <linux/kernel.h>
-#include <linux/of.h>
-#include <linux/platform_device.h>
-#include <linux/slab.h>
-#include <linux/spinlock.h>
-#include <linux/pm_runtime.h>
-#include <linux/ftrace.h>
-#include <linux/uaccess.h>
-#include <linux/sched/clock.h>
-#include <linux/percpu-defs.h>
-
-#include <asm/pmu.h>
-#include <asm/irq_regs.h>
-#include <asm/nds32.h>
-#include <asm/stacktrace.h>
-#include <asm/perf_event.h>
-#include <nds32_intrinsic.h>
-
-/* Set at runtime when we know what CPU type we are. */
-static struct nds32_pmu *cpu_pmu;
-
-static DEFINE_PER_CPU(struct pmu_hw_events, cpu_hw_events);
-static void nds32_pmu_start(struct nds32_pmu *cpu_pmu);
-static void nds32_pmu_stop(struct nds32_pmu *cpu_pmu);
-static struct platform_device_id cpu_pmu_plat_device_ids[] = {
- {.name = "nds32-pfm"},
- {},
-};
-
-static int nds32_pmu_map_cache_event(const unsigned int (*cache_map)
- [PERF_COUNT_HW_CACHE_MAX]
- [PERF_COUNT_HW_CACHE_OP_MAX]
- [PERF_COUNT_HW_CACHE_RESULT_MAX], u64 config)
-{
- unsigned int cache_type, cache_op, cache_result, ret;
-
- cache_type = (config >> 0) & 0xff;
- if (cache_type >= PERF_COUNT_HW_CACHE_MAX)
- return -EINVAL;
-
- cache_op = (config >> 8) & 0xff;
- if (cache_op >= PERF_COUNT_HW_CACHE_OP_MAX)
- return -EINVAL;
-
- cache_result = (config >> 16) & 0xff;
- if (cache_result >= PERF_COUNT_HW_CACHE_RESULT_MAX)
- return -EINVAL;
-
- ret = (int)(*cache_map)[cache_type][cache_op][cache_result];
-
- if (ret == CACHE_OP_UNSUPPORTED)
- return -ENOENT;
-
- return ret;
-}
-
-static int
-nds32_pmu_map_hw_event(const unsigned int (*event_map)[PERF_COUNT_HW_MAX],
- u64 config)
-{
- int mapping;
-
- if (config >= PERF_COUNT_HW_MAX)
- return -ENOENT;
-
- mapping = (*event_map)[config];
- return mapping == HW_OP_UNSUPPORTED ? -ENOENT : mapping;
-}
-
-static int nds32_pmu_map_raw_event(u32 raw_event_mask, u64 config)
-{
- int ev_type = (int)(config & raw_event_mask);
- int idx = config >> 8;
-
- switch (idx) {
- case 0:
- ev_type = PFM_OFFSET_MAGIC_0 + ev_type;
- if (ev_type >= SPAV3_0_SEL_LAST || ev_type <= SPAV3_0_SEL_BASE)
- return -ENOENT;
- break;
- case 1:
- ev_type = PFM_OFFSET_MAGIC_1 + ev_type;
- if (ev_type >= SPAV3_1_SEL_LAST || ev_type <= SPAV3_1_SEL_BASE)
- return -ENOENT;
- break;
- case 2:
- ev_type = PFM_OFFSET_MAGIC_2 + ev_type;
- if (ev_type >= SPAV3_2_SEL_LAST || ev_type <= SPAV3_2_SEL_BASE)
- return -ENOENT;
- break;
- default:
- return -ENOENT;
- }
-
- return ev_type;
-}
-
-int
-nds32_pmu_map_event(struct perf_event *event,
- const unsigned int (*event_map)[PERF_COUNT_HW_MAX],
- const unsigned int (*cache_map)
- [PERF_COUNT_HW_CACHE_MAX]
- [PERF_COUNT_HW_CACHE_OP_MAX]
- [PERF_COUNT_HW_CACHE_RESULT_MAX], u32 raw_event_mask)
-{
- u64 config = event->attr.config;
-
- switch (event->attr.type) {
- case PERF_TYPE_HARDWARE:
- return nds32_pmu_map_hw_event(event_map, config);
- case PERF_TYPE_HW_CACHE:
- return nds32_pmu_map_cache_event(cache_map, config);
- case PERF_TYPE_RAW:
- return nds32_pmu_map_raw_event(raw_event_mask, config);
- }
-
- return -ENOENT;
-}
-
-static int nds32_spav3_map_event(struct perf_event *event)
-{
- return nds32_pmu_map_event(event, &nds32_pfm_perf_map,
- &nds32_pfm_perf_cache_map, SOFTWARE_EVENT_MASK);
-}
-
-static inline u32 nds32_pfm_getreset_flags(void)
-{
- /* Read overflow status */
- u32 val = __nds32__mfsr(NDS32_SR_PFM_CTL);
- u32 old_val = val;
-
- /* Write overflow bit to clear status, and others keep it 0 */
- u32 ov_flag = PFM_CTL_OVF[0] | PFM_CTL_OVF[1] | PFM_CTL_OVF[2];
-
- __nds32__mtsr(val | ov_flag, NDS32_SR_PFM_CTL);
-
- return old_val;
-}
-
-static inline int nds32_pfm_has_overflowed(u32 pfm)
-{
- u32 ov_flag = PFM_CTL_OVF[0] | PFM_CTL_OVF[1] | PFM_CTL_OVF[2];
-
- return pfm & ov_flag;
-}
-
-static inline int nds32_pfm_counter_has_overflowed(u32 pfm, int idx)
-{
- u32 mask = 0;
-
- switch (idx) {
- case 0:
- mask = PFM_CTL_OVF[0];
- break;
- case 1:
- mask = PFM_CTL_OVF[1];
- break;
- case 2:
- mask = PFM_CTL_OVF[2];
- break;
- default:
- pr_err("%s index wrong\n", __func__);
- break;
- }
- return pfm & mask;
-}
-
-/*
- * Set the next IRQ period, based on the hwc->period_left value.
- * To be called with the event disabled in hw:
- */
-int nds32_pmu_event_set_period(struct perf_event *event)
-{
- struct nds32_pmu *nds32_pmu = to_nds32_pmu(event->pmu);
- struct hw_perf_event *hwc = &event->hw;
- s64 left = local64_read(&hwc->period_left);
- s64 period = hwc->sample_period;
- int ret = 0;
-
- /* The period may have been changed by PERF_EVENT_IOC_PERIOD */
- if (unlikely(period != hwc->last_period))
- left = period - (hwc->last_period - left);
-
- if (unlikely(left <= -period)) {
- left = period;
- local64_set(&hwc->period_left, left);
- hwc->last_period = period;
- ret = 1;
- }
-
- if (unlikely(left <= 0)) {
- left += period;
- local64_set(&hwc->period_left, left);
- hwc->last_period = period;
- ret = 1;
- }
-
- if (left > (s64)nds32_pmu->max_period)
- left = nds32_pmu->max_period;
-
- /*
- * The hw event starts counting from this event offset,
- * mark it to be able to extract future "deltas":
- */
- local64_set(&hwc->prev_count, (u64)(-left));
-
- nds32_pmu->write_counter(event, (u64)(-left) & nds32_pmu->max_period);
-
- perf_event_update_userpage(event);
-
- return ret;
-}
-
-static irqreturn_t nds32_pmu_handle_irq(int irq_num, void *dev)
-{
- u32 pfm;
- struct perf_sample_data data;
- struct nds32_pmu *cpu_pmu = (struct nds32_pmu *)dev;
- struct pmu_hw_events *cpuc = cpu_pmu->get_hw_events();
- struct pt_regs *regs;
- int idx;
- /*
- * Get and reset the IRQ flags
- */
- pfm = nds32_pfm_getreset_flags();
-
- /*
- * Did an overflow occur?
- */
- if (!nds32_pfm_has_overflowed(pfm))
- return IRQ_NONE;
-
- /*
- * Handle the counter(s) overflow(s)
- */
- regs = get_irq_regs();
-
- nds32_pmu_stop(cpu_pmu);
- for (idx = 0; idx < cpu_pmu->num_events; ++idx) {
- struct perf_event *event = cpuc->events[idx];
- struct hw_perf_event *hwc;
-
- /* Ignore if we don't have an event. */
- if (!event)
- continue;
-
- /*
- * We have a single interrupt for all counters. Check that
- * each counter has overflowed before we process it.
- */
- if (!nds32_pfm_counter_has_overflowed(pfm, idx))
- continue;
-
- hwc = &event->hw;
- nds32_pmu_event_update(event);
- perf_sample_data_init(&data, 0, hwc->last_period);
- if (!nds32_pmu_event_set_period(event))
- continue;
-
- if (perf_event_overflow(event, &data, regs))
- cpu_pmu->disable(event);
- }
- nds32_pmu_start(cpu_pmu);
- /*
- * Handle the pending perf events.
- *
- * Note: this call *must* be run with interrupts disabled. For
- * platforms that can have the PMU interrupts raised as an NMI, this
- * will not work.
- */
- irq_work_run();
-
- return IRQ_HANDLED;
-}
-
-static inline int nds32_pfm_counter_valid(struct nds32_pmu *cpu_pmu, int idx)
-{
- return ((idx >= 0) && (idx < cpu_pmu->num_events));
-}
-
-static inline int nds32_pfm_disable_counter(int idx)
-{
- unsigned int val = __nds32__mfsr(NDS32_SR_PFM_CTL);
- u32 mask = 0;
-
- mask = PFM_CTL_EN[idx];
- val &= ~mask;
- val &= ~(PFM_CTL_OVF[0] | PFM_CTL_OVF[1] | PFM_CTL_OVF[2]);
- __nds32__mtsr_isb(val, NDS32_SR_PFM_CTL);
- return idx;
-}
-
-/*
- * Add an event filter to a given event.
- */
-static int nds32_pmu_set_event_filter(struct hw_perf_event *event,
- struct perf_event_attr *attr)
-{
- unsigned long config_base = 0;
- int idx = event->idx;
- unsigned long no_kernel_tracing = 0;
- unsigned long no_user_tracing = 0;
- /* If index is -1, do not do anything */
- if (idx == -1)
- return 0;
-
- no_kernel_tracing = PFM_CTL_KS[idx];
- no_user_tracing = PFM_CTL_KU[idx];
- /*
- * Default: enable both kernel and user mode tracing.
- */
- if (attr->exclude_user)
- config_base |= no_user_tracing;
-
- if (attr->exclude_kernel)
- config_base |= no_kernel_tracing;
-
- /*
- * Install the filter into config_base as this is used to
- * construct the event type.
- */
- event->config_base |= config_base;
- return 0;
-}
-
-static inline void nds32_pfm_write_evtsel(int idx, u32 evnum)
-{
- u32 offset = 0;
- u32 ori_val = __nds32__mfsr(NDS32_SR_PFM_CTL);
- u32 ev_mask = 0;
- u32 no_kernel_mask = 0;
- u32 no_user_mask = 0;
- u32 val;
-
- offset = PFM_CTL_OFFSEL[idx];
- /* Clear previous mode selection, and write new one */
- no_kernel_mask = PFM_CTL_KS[idx];
- no_user_mask = PFM_CTL_KU[idx];
- ori_val &= ~no_kernel_mask;
- ori_val &= ~no_user_mask;
- if (evnum & no_kernel_mask)
- ori_val |= no_kernel_mask;
-
- if (evnum & no_user_mask)
- ori_val |= no_user_mask;
-
- /* Clear previous event selection */
- ev_mask = PFM_CTL_SEL[idx];
- ori_val &= ~ev_mask;
- evnum &= SOFTWARE_EVENT_MASK;
-
- /* undo the linear mapping */
- evnum = get_converted_evet_hw_num(evnum);
- val = ori_val | (evnum << offset);
- val &= ~(PFM_CTL_OVF[0] | PFM_CTL_OVF[1] | PFM_CTL_OVF[2]);
- __nds32__mtsr_isb(val, NDS32_SR_PFM_CTL);
-}
-
-static inline int nds32_pfm_enable_counter(int idx)
-{
- unsigned int val = __nds32__mfsr(NDS32_SR_PFM_CTL);
- u32 mask = 0;
-
- mask = PFM_CTL_EN[idx];
- val |= mask;
- val &= ~(PFM_CTL_OVF[0] | PFM_CTL_OVF[1] | PFM_CTL_OVF[2]);
- __nds32__mtsr_isb(val, NDS32_SR_PFM_CTL);
- return idx;
-}
-
-static inline int nds32_pfm_enable_intens(int idx)
-{
- unsigned int val = __nds32__mfsr(NDS32_SR_PFM_CTL);
- u32 mask = 0;
-
- mask = PFM_CTL_IE[idx];
- val |= mask;
- val &= ~(PFM_CTL_OVF[0] | PFM_CTL_OVF[1] | PFM_CTL_OVF[2]);
- __nds32__mtsr_isb(val, NDS32_SR_PFM_CTL);
- return idx;
-}
-
-static inline int nds32_pfm_disable_intens(int idx)
-{
- unsigned int val = __nds32__mfsr(NDS32_SR_PFM_CTL);
- u32 mask = 0;
-
- mask = PFM_CTL_IE[idx];
- val &= ~mask;
- val &= ~(PFM_CTL_OVF[0] | PFM_CTL_OVF[1] | PFM_CTL_OVF[2]);
- __nds32__mtsr_isb(val, NDS32_SR_PFM_CTL);
- return idx;
-}
-
-static int event_requires_mode_exclusion(struct perf_event_attr *attr)
-{
- /* Other modes NDS32 does not support */
- return attr->exclude_user || attr->exclude_kernel;
-}
-
-static void nds32_pmu_enable_event(struct perf_event *event)
-{
- unsigned long flags;
- unsigned int evnum = 0;
- struct hw_perf_event *hwc = &event->hw;
- struct nds32_pmu *cpu_pmu = to_nds32_pmu(event->pmu);
- struct pmu_hw_events *events = cpu_pmu->get_hw_events();
- int idx = hwc->idx;
-
- if (!nds32_pfm_counter_valid(cpu_pmu, idx)) {
- pr_err("CPU enabling wrong pfm counter IRQ enable\n");
- return;
- }
-
- /*
- * Enable counter and interrupt, and set the counter to count
- * the event that we're interested in.
- */
- raw_spin_lock_irqsave(&events->pmu_lock, flags);
-
- /*
- * Disable counter
- */
- nds32_pfm_disable_counter(idx);
-
- /*
- * Check whether we need to exclude the counter from certain modes.
- */
- if ((!cpu_pmu->set_event_filter ||
- cpu_pmu->set_event_filter(hwc, &event->attr)) &&
- event_requires_mode_exclusion(&event->attr)) {
- pr_notice
- ("NDS32 performance counters do not support mode exclusion\n");
- hwc->config_base = 0;
- }
- /* Write event */
- evnum = hwc->config_base;
- nds32_pfm_write_evtsel(idx, evnum);
-
- /*
- * Enable interrupt for this counter
- */
- nds32_pfm_enable_intens(idx);
-
- /*
- * Enable counter
- */
- nds32_pfm_enable_counter(idx);
-
- raw_spin_unlock_irqrestore(&events->pmu_lock, flags);
-}
-
-static void nds32_pmu_disable_event(struct perf_event *event)
-{
- unsigned long flags;
- struct hw_perf_event *hwc = &event->hw;
- struct nds32_pmu *cpu_pmu = to_nds32_pmu(event->pmu);
- struct pmu_hw_events *events = cpu_pmu->get_hw_events();
- int idx = hwc->idx;
-
- if (!nds32_pfm_counter_valid(cpu_pmu, idx)) {
- pr_err("CPU disabling wrong pfm counter IRQ enable %d\n", idx);
- return;
- }
-
- /*
- * Disable counter and interrupt
- */
- raw_spin_lock_irqsave(&events->pmu_lock, flags);
-
- /*
- * Disable counter
- */
- nds32_pfm_disable_counter(idx);
-
- /*
- * Disable interrupt for this counter
- */
- nds32_pfm_disable_intens(idx);
-
- raw_spin_unlock_irqrestore(&events->pmu_lock, flags);
-}
-
-static inline u32 nds32_pmu_read_counter(struct perf_event *event)
-{
- struct nds32_pmu *cpu_pmu = to_nds32_pmu(event->pmu);
- struct hw_perf_event *hwc = &event->hw;
- int idx = hwc->idx;
- u32 count = 0;
-
- if (!nds32_pfm_counter_valid(cpu_pmu, idx)) {
- pr_err("CPU reading wrong counter %d\n", idx);
- } else {
- switch (idx) {
- case PFMC0:
- count = __nds32__mfsr(NDS32_SR_PFMC0);
- break;
- case PFMC1:
- count = __nds32__mfsr(NDS32_SR_PFMC1);
- break;
- case PFMC2:
- count = __nds32__mfsr(NDS32_SR_PFMC2);
- break;
- default:
- pr_err
- ("%s: CPU has no performance counters %d\n",
- __func__, idx);
- }
- }
- return count;
-}
-
-static inline void nds32_pmu_write_counter(struct perf_event *event, u32 value)
-{
- struct nds32_pmu *cpu_pmu = to_nds32_pmu(event->pmu);
- struct hw_perf_event *hwc = &event->hw;
- int idx = hwc->idx;
-
- if (!nds32_pfm_counter_valid(cpu_pmu, idx)) {
- pr_err("CPU writing wrong counter %d\n", idx);
- } else {
- switch (idx) {
- case PFMC0:
- __nds32__mtsr_isb(value, NDS32_SR_PFMC0);
- break;
- case PFMC1:
- __nds32__mtsr_isb(value, NDS32_SR_PFMC1);
- break;
- case PFMC2:
- __nds32__mtsr_isb(value, NDS32_SR_PFMC2);
- break;
- default:
- pr_err
- ("%s: CPU has no performance counters %d\n",
- __func__, idx);
- }
- }
-}
-
-static int nds32_pmu_get_event_idx(struct pmu_hw_events *cpuc,
- struct perf_event *event)
-{
- int idx;
- struct hw_perf_event *hwc = &event->hw;
- /*
- * Current implementation maps cycles, instruction count and cache-miss
- * to specific counter.
- * However, multiple of the 3 counters are able to count these events.
- *
- *
- * SOFTWARE_EVENT_MASK mask for getting event num ,
- * This is defined by Jia-Rung, you can change the polocies.
- * However, do not exceed 8 bits. This is hardware specific.
- * The last number is SPAv3_2_SEL_LAST.
- */
- unsigned long evtype = hwc->config_base & SOFTWARE_EVENT_MASK;
-
- idx = get_converted_event_idx(evtype);
- /*
- * Try to get the counter for correpsonding event
- */
- if (evtype == SPAV3_0_SEL_TOTAL_CYCLES) {
- if (!test_and_set_bit(idx, cpuc->used_mask))
- return idx;
- if (!test_and_set_bit(NDS32_IDX_COUNTER0, cpuc->used_mask))
- return NDS32_IDX_COUNTER0;
- if (!test_and_set_bit(NDS32_IDX_COUNTER1, cpuc->used_mask))
- return NDS32_IDX_COUNTER1;
- } else if (evtype == SPAV3_1_SEL_COMPLETED_INSTRUCTION) {
- if (!test_and_set_bit(idx, cpuc->used_mask))
- return idx;
- else if (!test_and_set_bit(NDS32_IDX_COUNTER1, cpuc->used_mask))
- return NDS32_IDX_COUNTER1;
- else if (!test_and_set_bit
- (NDS32_IDX_CYCLE_COUNTER, cpuc->used_mask))
- return NDS32_IDX_CYCLE_COUNTER;
- } else {
- if (!test_and_set_bit(idx, cpuc->used_mask))
- return idx;
- }
- return -EAGAIN;
-}
-
-static void nds32_pmu_start(struct nds32_pmu *cpu_pmu)
-{
- unsigned long flags;
- unsigned int val;
- struct pmu_hw_events *events = cpu_pmu->get_hw_events();
-
- raw_spin_lock_irqsave(&events->pmu_lock, flags);
-
- /* Enable all counters , NDS PFM has 3 counters */
- val = __nds32__mfsr(NDS32_SR_PFM_CTL);
- val |= (PFM_CTL_EN[0] | PFM_CTL_EN[1] | PFM_CTL_EN[2]);
- val &= ~(PFM_CTL_OVF[0] | PFM_CTL_OVF[1] | PFM_CTL_OVF[2]);
- __nds32__mtsr_isb(val, NDS32_SR_PFM_CTL);
-
- raw_spin_unlock_irqrestore(&events->pmu_lock, flags);
-}
-
-static void nds32_pmu_stop(struct nds32_pmu *cpu_pmu)
-{
- unsigned long flags;
- unsigned int val;
- struct pmu_hw_events *events = cpu_pmu->get_hw_events();
-
- raw_spin_lock_irqsave(&events->pmu_lock, flags);
-
- /* Disable all counters , NDS PFM has 3 counters */
- val = __nds32__mfsr(NDS32_SR_PFM_CTL);
- val &= ~(PFM_CTL_EN[0] | PFM_CTL_EN[1] | PFM_CTL_EN[2]);
- val &= ~(PFM_CTL_OVF[0] | PFM_CTL_OVF[1] | PFM_CTL_OVF[2]);
- __nds32__mtsr_isb(val, NDS32_SR_PFM_CTL);
-
- raw_spin_unlock_irqrestore(&events->pmu_lock, flags);
-}
-
-static void nds32_pmu_reset(void *info)
-{
- u32 val = 0;
-
- val |= (PFM_CTL_OVF[0] | PFM_CTL_OVF[1] | PFM_CTL_OVF[2]);
- __nds32__mtsr(val, NDS32_SR_PFM_CTL);
- __nds32__mtsr(0, NDS32_SR_PFM_CTL);
- __nds32__mtsr(0, NDS32_SR_PFMC0);
- __nds32__mtsr(0, NDS32_SR_PFMC1);
- __nds32__mtsr(0, NDS32_SR_PFMC2);
-}
-
-static void nds32_pmu_init(struct nds32_pmu *cpu_pmu)
-{
- cpu_pmu->handle_irq = nds32_pmu_handle_irq;
- cpu_pmu->enable = nds32_pmu_enable_event;
- cpu_pmu->disable = nds32_pmu_disable_event;
- cpu_pmu->read_counter = nds32_pmu_read_counter;
- cpu_pmu->write_counter = nds32_pmu_write_counter;
- cpu_pmu->get_event_idx = nds32_pmu_get_event_idx;
- cpu_pmu->start = nds32_pmu_start;
- cpu_pmu->stop = nds32_pmu_stop;
- cpu_pmu->reset = nds32_pmu_reset;
- cpu_pmu->max_period = 0xFFFFFFFF; /* Maximum counts */
-};
-
-static u32 nds32_read_num_pfm_events(void)
-{
- /* NDS32 SPAv3 PMU support 3 counter */
- return 3;
-}
-
-static int device_pmu_init(struct nds32_pmu *cpu_pmu)
-{
- nds32_pmu_init(cpu_pmu);
- /*
- * This name should be devive-specific name, whatever you like :)
- * I think "PMU" will be a good generic name.
- */
- cpu_pmu->name = "nds32v3-pmu";
- cpu_pmu->map_event = nds32_spav3_map_event;
- cpu_pmu->num_events = nds32_read_num_pfm_events();
- cpu_pmu->set_event_filter = nds32_pmu_set_event_filter;
- return 0;
-}
-
-/*
- * CPU PMU identification and probing.
- */
-static int probe_current_pmu(struct nds32_pmu *pmu)
-{
- int ret;
-
- get_cpu();
- ret = -ENODEV;
- /*
- * If ther are various CPU types with its own PMU, initialize with
- *
- * the corresponding one
- */
- device_pmu_init(pmu);
- put_cpu();
- return ret;
-}
-
-static void nds32_pmu_enable(struct pmu *pmu)
-{
- struct nds32_pmu *nds32_pmu = to_nds32_pmu(pmu);
- struct pmu_hw_events *hw_events = nds32_pmu->get_hw_events();
- int enabled = bitmap_weight(hw_events->used_mask,
- nds32_pmu->num_events);
-
- if (enabled)
- nds32_pmu->start(nds32_pmu);
-}
-
-static void nds32_pmu_disable(struct pmu *pmu)
-{
- struct nds32_pmu *nds32_pmu = to_nds32_pmu(pmu);
-
- nds32_pmu->stop(nds32_pmu);
-}
-
-static void nds32_pmu_release_hardware(struct nds32_pmu *nds32_pmu)
-{
- nds32_pmu->free_irq(nds32_pmu);
- pm_runtime_put_sync(&nds32_pmu->plat_device->dev);
-}
-
-static irqreturn_t nds32_pmu_dispatch_irq(int irq, void *dev)
-{
- struct nds32_pmu *nds32_pmu = (struct nds32_pmu *)dev;
- int ret;
- u64 start_clock, finish_clock;
-
- start_clock = local_clock();
- ret = nds32_pmu->handle_irq(irq, dev);
- finish_clock = local_clock();
-
- perf_sample_event_took(finish_clock - start_clock);
- return ret;
-}
-
-static int nds32_pmu_reserve_hardware(struct nds32_pmu *nds32_pmu)
-{
- int err;
- struct platform_device *pmu_device = nds32_pmu->plat_device;
-
- if (!pmu_device)
- return -ENODEV;
-
- pm_runtime_get_sync(&pmu_device->dev);
- err = nds32_pmu->request_irq(nds32_pmu, nds32_pmu_dispatch_irq);
- if (err) {
- nds32_pmu_release_hardware(nds32_pmu);
- return err;
- }
-
- return 0;
-}
-
-static int
-validate_event(struct pmu *pmu, struct pmu_hw_events *hw_events,
- struct perf_event *event)
-{
- struct nds32_pmu *nds32_pmu = to_nds32_pmu(event->pmu);
-
- if (is_software_event(event))
- return 1;
-
- if (event->pmu != pmu)
- return 0;
-
- if (event->state < PERF_EVENT_STATE_OFF)
- return 1;
-
- if (event->state == PERF_EVENT_STATE_OFF && !event->attr.enable_on_exec)
- return 1;
-
- return nds32_pmu->get_event_idx(hw_events, event) >= 0;
-}
-
-static int validate_group(struct perf_event *event)
-{
- struct perf_event *sibling, *leader = event->group_leader;
- struct pmu_hw_events fake_pmu;
- DECLARE_BITMAP(fake_used_mask, MAX_COUNTERS);
- /*
- * Initialize the fake PMU. We only need to populate the
- * used_mask for the purposes of validation.
- */
- memset(fake_used_mask, 0, sizeof(fake_used_mask));
-
- if (!validate_event(event->pmu, &fake_pmu, leader))
- return -EINVAL;
-
- for_each_sibling_event(sibling, leader) {
- if (!validate_event(event->pmu, &fake_pmu, sibling))
- return -EINVAL;
- }
-
- if (!validate_event(event->pmu, &fake_pmu, event))
- return -EINVAL;
-
- return 0;
-}
-
-static int __hw_perf_event_init(struct perf_event *event)
-{
- struct nds32_pmu *nds32_pmu = to_nds32_pmu(event->pmu);
- struct hw_perf_event *hwc = &event->hw;
- int mapping;
-
- mapping = nds32_pmu->map_event(event);
-
- if (mapping < 0) {
- pr_debug("event %x:%llx not supported\n", event->attr.type,
- event->attr.config);
- return mapping;
- }
-
- /*
- * We don't assign an index until we actually place the event onto
- * hardware. Use -1 to signify that we haven't decided where to put it
- * yet. For SMP systems, each core has it's own PMU so we can't do any
- * clever allocation or constraints checking at this point.
- */
- hwc->idx = -1;
- hwc->config_base = 0;
- hwc->config = 0;
- hwc->event_base = 0;
-
- /*
- * Check whether we need to exclude the counter from certain modes.
- */
- if ((!nds32_pmu->set_event_filter ||
- nds32_pmu->set_event_filter(hwc, &event->attr)) &&
- event_requires_mode_exclusion(&event->attr)) {
- pr_debug
- ("NDS performance counters do not support mode exclusion\n");
- return -EOPNOTSUPP;
- }
-
- /*
- * Store the event encoding into the config_base field.
- */
- hwc->config_base |= (unsigned long)mapping;
-
- if (!hwc->sample_period) {
- /*
- * For non-sampling runs, limit the sample_period to half
- * of the counter width. That way, the new counter value
- * is far less likely to overtake the previous one unless
- * you have some serious IRQ latency issues.
- */
- hwc->sample_period = nds32_pmu->max_period >> 1;
- hwc->last_period = hwc->sample_period;
- local64_set(&hwc->period_left, hwc->sample_period);
- }
-
- if (event->group_leader != event) {
- if (validate_group(event) != 0)
- return -EINVAL;
- }
-
- return 0;
-}
-
-static int nds32_pmu_event_init(struct perf_event *event)
-{
- struct nds32_pmu *nds32_pmu = to_nds32_pmu(event->pmu);
- int err = 0;
- atomic_t *active_events = &nds32_pmu->active_events;
-
- /* does not support taken branch sampling */
- if (has_branch_stack(event))
- return -EOPNOTSUPP;
-
- if (nds32_pmu->map_event(event) == -ENOENT)
- return -ENOENT;
-
- if (!atomic_inc_not_zero(active_events)) {
- if (atomic_read(active_events) == 0) {
- /* Register irq handler */
- err = nds32_pmu_reserve_hardware(nds32_pmu);
- }
-
- if (!err)
- atomic_inc(active_events);
- }
-
- if (err)
- return err;
-
- err = __hw_perf_event_init(event);
-
- return err;
-}
-
-static void nds32_start(struct perf_event *event, int flags)
-{
- struct nds32_pmu *nds32_pmu = to_nds32_pmu(event->pmu);
- struct hw_perf_event *hwc = &event->hw;
- /*
- * NDS pmu always has to reprogram the period, so ignore
- * PERF_EF_RELOAD, see the comment below.
- */
- if (flags & PERF_EF_RELOAD)
- WARN_ON_ONCE(!(hwc->state & PERF_HES_UPTODATE));
-
- hwc->state = 0;
- /* Set the period for the event. */
- nds32_pmu_event_set_period(event);
-
- nds32_pmu->enable(event);
-}
-
-static int nds32_pmu_add(struct perf_event *event, int flags)
-{
- struct nds32_pmu *nds32_pmu = to_nds32_pmu(event->pmu);
- struct pmu_hw_events *hw_events = nds32_pmu->get_hw_events();
- struct hw_perf_event *hwc = &event->hw;
- int idx;
- int err = 0;
-
- perf_pmu_disable(event->pmu);
-
- /* If we don't have a space for the counter then finish early. */
- idx = nds32_pmu->get_event_idx(hw_events, event);
- if (idx < 0) {
- err = idx;
- goto out;
- }
-
- /*
- * If there is an event in the counter we are going to use then make
- * sure it is disabled.
- */
- event->hw.idx = idx;
- nds32_pmu->disable(event);
- hw_events->events[idx] = event;
-
- hwc->state = PERF_HES_STOPPED | PERF_HES_UPTODATE;
- if (flags & PERF_EF_START)
- nds32_start(event, PERF_EF_RELOAD);
-
- /* Propagate our changes to the userspace mapping. */
- perf_event_update_userpage(event);
-
-out:
- perf_pmu_enable(event->pmu);
- return err;
-}
-
-u64 nds32_pmu_event_update(struct perf_event *event)
-{
- struct nds32_pmu *nds32_pmu = to_nds32_pmu(event->pmu);
- struct hw_perf_event *hwc = &event->hw;
- u64 delta, prev_raw_count, new_raw_count;
-
-again:
- prev_raw_count = local64_read(&hwc->prev_count);
- new_raw_count = nds32_pmu->read_counter(event);
-
- if (local64_cmpxchg(&hwc->prev_count, prev_raw_count,
- new_raw_count) != prev_raw_count) {
- goto again;
- }
- /*
- * Whether overflow or not, "unsigned substraction"
- * will always get their delta
- */
- delta = (new_raw_count - prev_raw_count) & nds32_pmu->max_period;
-
- local64_add(delta, &event->count);
- local64_sub(delta, &hwc->period_left);
-
- return new_raw_count;
-}
-
-static void nds32_stop(struct perf_event *event, int flags)
-{
- struct nds32_pmu *nds32_pmu = to_nds32_pmu(event->pmu);
- struct hw_perf_event *hwc = &event->hw;
- /*
- * NDS pmu always has to update the counter, so ignore
- * PERF_EF_UPDATE, see comments in nds32_start().
- */
- if (!(hwc->state & PERF_HES_STOPPED)) {
- nds32_pmu->disable(event);
- nds32_pmu_event_update(event);
- hwc->state |= PERF_HES_STOPPED | PERF_HES_UPTODATE;
- }
-}
-
-static void nds32_pmu_del(struct perf_event *event, int flags)
-{
- struct nds32_pmu *nds32_pmu = to_nds32_pmu(event->pmu);
- struct pmu_hw_events *hw_events = nds32_pmu->get_hw_events();
- struct hw_perf_event *hwc = &event->hw;
- int idx = hwc->idx;
-
- nds32_stop(event, PERF_EF_UPDATE);
- hw_events->events[idx] = NULL;
- clear_bit(idx, hw_events->used_mask);
-
- perf_event_update_userpage(event);
-}
-
-static void nds32_pmu_read(struct perf_event *event)
-{
- nds32_pmu_event_update(event);
-}
-
-/* Please refer to SPAv3 for more hardware specific details */
-PMU_FORMAT_ATTR(event, "config:0-63");
-
-static struct attribute *nds32_arch_formats_attr[] = {
- &format_attr_event.attr,
- NULL,
-};
-
-static struct attribute_group nds32_pmu_format_group = {
- .name = "format",
- .attrs = nds32_arch_formats_attr,
-};
-
-static ssize_t nds32_pmu_cpumask_show(struct device *dev,
- struct device_attribute *attr,
- char *buf)
-{
- return 0;
-}
-
-static DEVICE_ATTR(cpus, 0444, nds32_pmu_cpumask_show, NULL);
-
-static struct attribute *nds32_pmu_common_attrs[] = {
- &dev_attr_cpus.attr,
- NULL,
-};
-
-static struct attribute_group nds32_pmu_common_group = {
- .attrs = nds32_pmu_common_attrs,
-};
-
-static const struct attribute_group *nds32_pmu_attr_groups[] = {
- &nds32_pmu_format_group,
- &nds32_pmu_common_group,
- NULL,
-};
-
-static void nds32_init(struct nds32_pmu *nds32_pmu)
-{
- atomic_set(&nds32_pmu->active_events, 0);
-
- nds32_pmu->pmu = (struct pmu) {
- .pmu_enable = nds32_pmu_enable,
- .pmu_disable = nds32_pmu_disable,
- .attr_groups = nds32_pmu_attr_groups,
- .event_init = nds32_pmu_event_init,
- .add = nds32_pmu_add,
- .del = nds32_pmu_del,
- .start = nds32_start,
- .stop = nds32_stop,
- .read = nds32_pmu_read,
- };
-}
-
-int nds32_pmu_register(struct nds32_pmu *nds32_pmu, int type)
-{
- nds32_init(nds32_pmu);
- pm_runtime_enable(&nds32_pmu->plat_device->dev);
- pr_info("enabled with %s PMU driver, %d counters available\n",
- nds32_pmu->name, nds32_pmu->num_events);
- return perf_pmu_register(&nds32_pmu->pmu, nds32_pmu->name, type);
-}
-
-static struct pmu_hw_events *cpu_pmu_get_cpu_events(void)
-{
- return this_cpu_ptr(&cpu_hw_events);
-}
-
-static int cpu_pmu_request_irq(struct nds32_pmu *cpu_pmu, irq_handler_t handler)
-{
- int err, irq, irqs;
- struct platform_device *pmu_device = cpu_pmu->plat_device;
-
- if (!pmu_device)
- return -ENODEV;
-
- irqs = min(pmu_device->num_resources, num_possible_cpus());
- if (irqs < 1) {
- pr_err("no irqs for PMUs defined\n");
- return -ENODEV;
- }
-
- irq = platform_get_irq(pmu_device, 0);
- err = request_irq(irq, handler, IRQF_NOBALANCING, "nds32-pfm",
- cpu_pmu);
- if (err) {
- pr_err("unable to request IRQ%d for NDS PMU counters\n",
- irq);
- return err;
- }
- return 0;
-}
-
-static void cpu_pmu_free_irq(struct nds32_pmu *cpu_pmu)
-{
- int irq;
- struct platform_device *pmu_device = cpu_pmu->plat_device;
-
- irq = platform_get_irq(pmu_device, 0);
- if (irq >= 0)
- free_irq(irq, cpu_pmu);
-}
-
-static void cpu_pmu_init(struct nds32_pmu *cpu_pmu)
-{
- int cpu;
- struct pmu_hw_events *events = &per_cpu(cpu_hw_events, cpu);
-
- raw_spin_lock_init(&events->pmu_lock);
-
- cpu_pmu->get_hw_events = cpu_pmu_get_cpu_events;
- cpu_pmu->request_irq = cpu_pmu_request_irq;
- cpu_pmu->free_irq = cpu_pmu_free_irq;
-
- /* Ensure the PMU has sane values out of reset. */
- if (cpu_pmu->reset)
- on_each_cpu(cpu_pmu->reset, cpu_pmu, 1);
-}
-
-static const struct of_device_id cpu_pmu_of_device_ids[] = {
- {.compatible = "andestech,nds32v3-pmu",
- .data = device_pmu_init},
- {},
-};
-
-static int cpu_pmu_device_probe(struct platform_device *pdev)
-{
- const struct of_device_id *of_id;
- int (*init_fn)(struct nds32_pmu *nds32_pmu);
- struct device_node *node = pdev->dev.of_node;
- struct nds32_pmu *pmu;
- int ret = -ENODEV;
-
- if (cpu_pmu) {
- pr_notice("[perf] attempt to register multiple PMU devices!\n");
- return -ENOSPC;
- }
-
- pmu = kzalloc(sizeof(*pmu), GFP_KERNEL);
- if (!pmu)
- return -ENOMEM;
-
- of_id = of_match_node(cpu_pmu_of_device_ids, pdev->dev.of_node);
- if (node && of_id) {
- init_fn = of_id->data;
- ret = init_fn(pmu);
- } else {
- ret = probe_current_pmu(pmu);
- }
-
- if (ret) {
- pr_notice("[perf] failed to probe PMU!\n");
- goto out_free;
- }
-
- cpu_pmu = pmu;
- cpu_pmu->plat_device = pdev;
- cpu_pmu_init(cpu_pmu);
- ret = nds32_pmu_register(cpu_pmu, PERF_TYPE_RAW);
-
- if (!ret)
- return 0;
-
-out_free:
- pr_notice("[perf] failed to register PMU devices!\n");
- kfree(pmu);
- return ret;
-}
-
-static struct platform_driver cpu_pmu_driver = {
- .driver = {
- .name = "nds32-pfm",
- .of_match_table = cpu_pmu_of_device_ids,
- },
- .probe = cpu_pmu_device_probe,
- .id_table = cpu_pmu_plat_device_ids,
-};
-
-static int __init register_pmu_driver(void)
-{
- int err = 0;
-
- err = platform_driver_register(&cpu_pmu_driver);
- if (err)
- pr_notice("[perf] PMU initialization failed\n");
- else
- pr_notice("[perf] PMU initialization done\n");
-
- return err;
-}
-
-device_initcall(register_pmu_driver);
-
-/*
- * References: arch/nds32/kernel/traps.c:__dump()
- * You will need to know the NDS ABI first.
- */
-static int unwind_frame_kernel(struct stackframe *frame)
-{
- int graph = 0;
-#ifdef CONFIG_FRAME_POINTER
- /* 0x3 means misalignment */
- if (!kstack_end((void *)frame->fp) &&
- !((unsigned long)frame->fp & 0x3) &&
- ((unsigned long)frame->fp >= TASK_SIZE)) {
- /*
- * The array index is based on the ABI, the below graph
- * illustrate the reasons.
- * Function call procedure: "smw" and "lmw" will always
- * update SP and FP for you automatically.
- *
- * Stack Relative Address
- * | | 0
- * ----
- * |LP| <-- SP(before smw) <-- FP(after smw) -1
- * ----
- * |FP| -2
- * ----
- * | | <-- SP(after smw) -3
- */
- frame->lp = ((unsigned long *)frame->fp)[-1];
- frame->fp = ((unsigned long *)frame->fp)[FP_OFFSET];
- /* make sure CONFIG_FUNCTION_GRAPH_TRACER is turned on */
- if (__kernel_text_address(frame->lp))
- frame->lp = ftrace_graph_ret_addr
- (NULL, &graph, frame->lp, NULL);
-
- return 0;
- } else {
- return -EPERM;
- }
-#else
- /*
- * You can refer to arch/nds32/kernel/traps.c:__dump()
- * Treat "sp" as "fp", but the "sp" is one frame ahead of "fp".
- * And, the "sp" is not always correct.
- *
- * Stack Relative Address
- * | | 0
- * ----
- * |LP| <-- SP(before smw) -1
- * ----
- * | | <-- SP(after smw) -2
- * ----
- */
- if (!kstack_end((void *)frame->sp)) {
- frame->lp = ((unsigned long *)frame->sp)[1];
- /* TODO: How to deal with the value in first
- * "sp" is not correct?
- */
- if (__kernel_text_address(frame->lp))
- frame->lp = ftrace_graph_ret_addr
- (tsk, &graph, frame->lp, NULL);
-
- frame->sp = ((unsigned long *)frame->sp) + 1;
-
- return 0;
- } else {
- return -EPERM;
- }
-#endif
-}
-
-static void notrace
-walk_stackframe(struct stackframe *frame,
- int (*fn_record)(struct stackframe *, void *),
- void *data)
-{
- while (1) {
- int ret;
-
- if (fn_record(frame, data))
- break;
-
- ret = unwind_frame_kernel(frame);
- if (ret < 0)
- break;
- }
-}
-
-/*
- * Gets called by walk_stackframe() for every stackframe. This will be called
- * whist unwinding the stackframe and is like a subroutine return so we use
- * the PC.
- */
-static int callchain_trace(struct stackframe *fr, void *data)
-{
- struct perf_callchain_entry_ctx *entry = data;
-
- perf_callchain_store(entry, fr->lp);
- return 0;
-}
-
-/*
- * Get the return address for a single stackframe and return a pointer to the
- * next frame tail.
- */
-static unsigned long
-user_backtrace(struct perf_callchain_entry_ctx *entry, unsigned long fp)
-{
- struct frame_tail buftail;
- unsigned long lp = 0;
- unsigned long *user_frame_tail =
- (unsigned long *)(fp - (unsigned long)sizeof(buftail));
-
- /* Check accessibility of one struct frame_tail beyond */
- if (!access_ok(user_frame_tail, sizeof(buftail)))
- return 0;
- if (__copy_from_user_inatomic
- (&buftail, user_frame_tail, sizeof(buftail)))
- return 0;
-
- /*
- * Refer to unwind_frame_kernel() for more illurstration
- */
- lp = buftail.stack_lp; /* ((unsigned long *)fp)[-1] */
- fp = buftail.stack_fp; /* ((unsigned long *)fp)[FP_OFFSET] */
- perf_callchain_store(entry, lp);
- return fp;
-}
-
-static unsigned long
-user_backtrace_opt_size(struct perf_callchain_entry_ctx *entry,
- unsigned long fp)
-{
- struct frame_tail_opt_size buftail;
- unsigned long lp = 0;
-
- unsigned long *user_frame_tail =
- (unsigned long *)(fp - (unsigned long)sizeof(buftail));
-
- /* Check accessibility of one struct frame_tail beyond */
- if (!access_ok(user_frame_tail, sizeof(buftail)))
- return 0;
- if (__copy_from_user_inatomic
- (&buftail, user_frame_tail, sizeof(buftail)))
- return 0;
-
- /*
- * Refer to unwind_frame_kernel() for more illurstration
- */
- lp = buftail.stack_lp; /* ((unsigned long *)fp)[-1] */
- fp = buftail.stack_fp; /* ((unsigned long *)fp)[FP_OFFSET] */
-
- perf_callchain_store(entry, lp);
- return fp;
-}
-
-/*
- * This will be called when the target is in user mode
- * This function will only be called when we use
- * "PERF_SAMPLE_CALLCHAIN" in
- * kernel/events/core.c:perf_prepare_sample()
- *
- * How to trigger perf_callchain_[user/kernel] :
- * $ perf record -e cpu-clock --call-graph fp ./program
- * $ perf report --call-graph
- */
-unsigned long leaf_fp;
-void
-perf_callchain_user(struct perf_callchain_entry_ctx *entry,
- struct pt_regs *regs)
-{
- unsigned long fp = 0;
- unsigned long gp = 0;
- unsigned long lp = 0;
- unsigned long sp = 0;
- unsigned long *user_frame_tail;
-
- leaf_fp = 0;
-
- perf_callchain_store(entry, regs->ipc);
- fp = regs->fp;
- gp = regs->gp;
- lp = regs->lp;
- sp = regs->sp;
- if (entry->nr < PERF_MAX_STACK_DEPTH &&
- (unsigned long)fp && !((unsigned long)fp & 0x7) && fp > sp) {
- user_frame_tail =
- (unsigned long *)(fp - (unsigned long)sizeof(fp));
-
- if (!access_ok(user_frame_tail, sizeof(fp)))
- return;
-
- if (__copy_from_user_inatomic
- (&leaf_fp, user_frame_tail, sizeof(fp)))
- return;
-
- if (leaf_fp == lp) {
- /*
- * Maybe this is non leaf function
- * with optimize for size,
- * or maybe this is the function
- * with optimize for size
- */
- struct frame_tail buftail;
-
- user_frame_tail =
- (unsigned long *)(fp -
- (unsigned long)sizeof(buftail));
-
- if (!access_ok(user_frame_tail, sizeof(buftail)))
- return;
-
- if (__copy_from_user_inatomic
- (&buftail, user_frame_tail, sizeof(buftail)))
- return;
-
- if (buftail.stack_fp == gp) {
- /* non leaf function with optimize
- * for size condition
- */
- struct frame_tail_opt_size buftail_opt_size;
-
- user_frame_tail =
- (unsigned long *)(fp - (unsigned long)
- sizeof(buftail_opt_size));
-
- if (!access_ok(user_frame_tail,
- sizeof(buftail_opt_size)))
- return;
-
- if (__copy_from_user_inatomic
- (&buftail_opt_size, user_frame_tail,
- sizeof(buftail_opt_size)))
- return;
-
- perf_callchain_store(entry, lp);
- fp = buftail_opt_size.stack_fp;
-
- while ((entry->nr < PERF_MAX_STACK_DEPTH) &&
- (unsigned long)fp &&
- !((unsigned long)fp & 0x7) &&
- fp > sp) {
- sp = fp;
- fp = user_backtrace_opt_size(entry, fp);
- }
-
- } else {
- /* this is the function
- * without optimize for size
- */
- fp = buftail.stack_fp;
- perf_callchain_store(entry, lp);
- while ((entry->nr < PERF_MAX_STACK_DEPTH) &&
- (unsigned long)fp &&
- !((unsigned long)fp & 0x7) &&
- fp > sp) {
- sp = fp;
- fp = user_backtrace(entry, fp);
- }
- }
- } else {
- /* this is leaf function */
- fp = leaf_fp;
- perf_callchain_store(entry, lp);
-
- /* previous function callcahin */
- while ((entry->nr < PERF_MAX_STACK_DEPTH) &&
- (unsigned long)fp &&
- !((unsigned long)fp & 0x7) && fp > sp) {
- sp = fp;
- fp = user_backtrace(entry, fp);
- }
- }
- return;
- }
-}
-
-/* This will be called when the target is in kernel mode */
-void
-perf_callchain_kernel(struct perf_callchain_entry_ctx *entry,
- struct pt_regs *regs)
-{
- struct stackframe fr;
-
- fr.fp = regs->fp;
- fr.lp = regs->lp;
- fr.sp = regs->sp;
- walk_stackframe(&fr, callchain_trace, entry);
-}
-
-unsigned long perf_instruction_pointer(struct pt_regs *regs)
-{
- return instruction_pointer(regs);
-}
-
-unsigned long perf_misc_flags(struct pt_regs *regs)
-{
- int misc = 0;
-
- if (user_mode(regs))
- misc |= PERF_RECORD_MISC_USER;
- else
- misc |= PERF_RECORD_MISC_KERNEL;
-
- return misc;
-}
diff --git a/arch/nds32/kernel/pm.c b/arch/nds32/kernel/pm.c
deleted file mode 100644
index e25700e125d8..000000000000
--- a/arch/nds32/kernel/pm.c
+++ /dev/null
@@ -1,80 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-// Copyright (C) 2008-2017 Andes Technology Corporation
-
-#include <linux/init.h>
-#include <linux/suspend.h>
-#include <linux/device.h>
-#include <linux/printk.h>
-#include <asm/suspend.h>
-#include <nds32_intrinsic.h>
-
-unsigned int resume_addr;
-unsigned int *phy_addr_sp_tmp;
-
-static void nds32_suspend2ram(void)
-{
- pgd_t *pgdv;
- p4d_t *p4dv;
- pud_t *pudv;
- pmd_t *pmdv;
- pte_t *ptev;
-
- pgdv = (pgd_t *)__va((__nds32__mfsr(NDS32_SR_L1_PPTB) &
- L1_PPTB_mskBASE)) + pgd_index((unsigned int)cpu_resume);
-
- p4dv = p4d_offset(pgdv, (unsigned int)cpu_resume);
- pudv = pud_offset(p4dv, (unsigned int)cpu_resume);
- pmdv = pmd_offset(pudv, (unsigned int)cpu_resume);
- ptev = pte_offset_map(pmdv, (unsigned int)cpu_resume);
-
- resume_addr = ((*ptev) & TLB_DATA_mskPPN)
- | ((unsigned int)cpu_resume & 0x00000fff);
-
- suspend2ram();
-}
-
-static void nds32_suspend_cpu(void)
-{
- while (!(__nds32__mfsr(NDS32_SR_INT_PEND) & wake_mask))
- __asm__ volatile ("standby no_wake_grant\n\t");
-}
-
-static int nds32_pm_valid(suspend_state_t state)
-{
- switch (state) {
- case PM_SUSPEND_ON:
- case PM_SUSPEND_STANDBY:
- case PM_SUSPEND_MEM:
- return 1;
- default:
- return 0;
- }
-}
-
-static int nds32_pm_enter(suspend_state_t state)
-{
- pr_debug("%s:state:%d\n", __func__, state);
- switch (state) {
- case PM_SUSPEND_STANDBY:
- nds32_suspend_cpu();
- return 0;
- case PM_SUSPEND_MEM:
- nds32_suspend2ram();
- return 0;
- default:
- return -EINVAL;
- }
-}
-
-static const struct platform_suspend_ops nds32_pm_ops = {
- .valid = nds32_pm_valid,
- .enter = nds32_pm_enter,
-};
-
-static int __init nds32_pm_init(void)
-{
- pr_debug("Enter %s\n", __func__);
- suspend_set_ops(&nds32_pm_ops);
- return 0;
-}
-late_initcall(nds32_pm_init);
diff --git a/arch/nds32/kernel/process.c b/arch/nds32/kernel/process.c
deleted file mode 100644
index 49fab9e39cbf..000000000000
--- a/arch/nds32/kernel/process.c
+++ /dev/null
@@ -1,257 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-// Copyright (C) 2005-2017 Andes Technology Corporation
-
-#include <linux/sched.h>
-#include <linux/sched/debug.h>
-#include <linux/sched/task_stack.h>
-#include <linux/delay.h>
-#include <linux/kallsyms.h>
-#include <linux/uaccess.h>
-#include <asm/elf.h>
-#include <asm/proc-fns.h>
-#include <asm/fpu.h>
-#include <linux/ptrace.h>
-#include <linux/reboot.h>
-
-#if IS_ENABLED(CONFIG_LAZY_FPU)
-struct task_struct *last_task_used_math;
-#endif
-
-extern void setup_mm_for_reboot(char mode);
-
-extern inline void arch_reset(char mode)
-{
- if (mode == 's') {
- /* Use cpu handler, jump to 0 */
- cpu_reset(0);
- }
-}
-
-void (*pm_power_off) (void);
-EXPORT_SYMBOL(pm_power_off);
-
-static char reboot_mode_nds32 = 'h';
-
-int __init reboot_setup(char *str)
-{
- reboot_mode_nds32 = str[0];
- return 1;
-}
-
-static int cpub_pwroff(void)
-{
- return 0;
-}
-
-__setup("reboot=", reboot_setup);
-
-void machine_halt(void)
-{
- cpub_pwroff();
-}
-
-EXPORT_SYMBOL(machine_halt);
-
-void machine_power_off(void)
-{
- if (pm_power_off)
- pm_power_off();
-}
-
-EXPORT_SYMBOL(machine_power_off);
-
-void machine_restart(char *cmd)
-{
- /*
- * Clean and disable cache, and turn off interrupts
- */
- cpu_proc_fin();
-
- /*
- * Tell the mm system that we are going to reboot -
- * we may need it to insert some 1:1 mappings so that
- * soft boot works.
- */
- setup_mm_for_reboot(reboot_mode_nds32);
-
- /* Execute kernel restart handler call chain */
- do_kernel_restart(cmd);
-
- /*
- * Now call the architecture specific reboot code.
- */
- arch_reset(reboot_mode_nds32);
-
- /*
- * Whoops - the architecture was unable to reboot.
- * Tell the user!
- */
- mdelay(1000);
- pr_info("Reboot failed -- System halted\n");
- while (1) ;
-}
-
-EXPORT_SYMBOL(machine_restart);
-
-void show_regs(struct pt_regs *regs)
-{
- printk("PC is at %pS\n", (void *)instruction_pointer(regs));
- printk("LP is at %pS\n", (void *)regs->lp);
- pr_info("pc : [<%08lx>] lp : [<%08lx>] %s\n"
- "sp : %08lx fp : %08lx gp : %08lx\n",
- instruction_pointer(regs),
- regs->lp, print_tainted(), regs->sp, regs->fp, regs->gp);
- pr_info("r25: %08lx r24: %08lx\n", regs->uregs[25], regs->uregs[24]);
-
- pr_info("r23: %08lx r22: %08lx r21: %08lx r20: %08lx\n",
- regs->uregs[23], regs->uregs[22],
- regs->uregs[21], regs->uregs[20]);
- pr_info("r19: %08lx r18: %08lx r17: %08lx r16: %08lx\n",
- regs->uregs[19], regs->uregs[18],
- regs->uregs[17], regs->uregs[16]);
- pr_info("r15: %08lx r14: %08lx r13: %08lx r12: %08lx\n",
- regs->uregs[15], regs->uregs[14],
- regs->uregs[13], regs->uregs[12]);
- pr_info("r11: %08lx r10: %08lx r9 : %08lx r8 : %08lx\n",
- regs->uregs[11], regs->uregs[10],
- regs->uregs[9], regs->uregs[8]);
- pr_info("r7 : %08lx r6 : %08lx r5 : %08lx r4 : %08lx\n",
- regs->uregs[7], regs->uregs[6], regs->uregs[5], regs->uregs[4]);
- pr_info("r3 : %08lx r2 : %08lx r1 : %08lx r0 : %08lx\n",
- regs->uregs[3], regs->uregs[2], regs->uregs[1], regs->uregs[0]);
- pr_info(" IRQs o%s Segment %s\n",
- interrupts_enabled(regs) ? "n" : "ff",
- uaccess_kernel() ? "kernel" : "user");
-}
-
-EXPORT_SYMBOL(show_regs);
-
-void exit_thread(struct task_struct *tsk)
-{
-#if defined(CONFIG_FPU) && defined(CONFIG_LAZY_FPU)
- if (last_task_used_math == tsk)
- last_task_used_math = NULL;
-#endif
-}
-
-void flush_thread(void)
-{
-#if defined(CONFIG_FPU)
- clear_fpu(task_pt_regs(current));
- clear_used_math();
-# ifdef CONFIG_LAZY_FPU
- if (last_task_used_math == current)
- last_task_used_math = NULL;
-# endif
-#endif
-}
-
-DEFINE_PER_CPU(struct task_struct *, __entry_task);
-
-asmlinkage void ret_from_fork(void) __asm__("ret_from_fork");
-int copy_thread(unsigned long clone_flags, unsigned long stack_start,
- unsigned long stk_sz, struct task_struct *p, unsigned long tls)
-{
- struct pt_regs *childregs = task_pt_regs(p);
-
- memset(&p->thread.cpu_context, 0, sizeof(struct cpu_context));
-
- if (unlikely(p->flags & (PF_KTHREAD | PF_IO_WORKER))) {
- memset(childregs, 0, sizeof(struct pt_regs));
- /* kernel thread fn */
- p->thread.cpu_context.r6 = stack_start;
- /* kernel thread argument */
- p->thread.cpu_context.r7 = stk_sz;
- } else {
- *childregs = *current_pt_regs();
- if (stack_start)
- childregs->sp = stack_start;
- /* child get zero as ret. */
- childregs->uregs[0] = 0;
- childregs->osp = 0;
- if (clone_flags & CLONE_SETTLS)
- childregs->uregs[25] = tls;
- }
- /* cpu context switching */
- p->thread.cpu_context.pc = (unsigned long)ret_from_fork;
- p->thread.cpu_context.sp = (unsigned long)childregs;
-
-#if IS_ENABLED(CONFIG_FPU)
- if (used_math()) {
-# if !IS_ENABLED(CONFIG_LAZY_FPU)
- unlazy_fpu(current);
-# else
- preempt_disable();
- if (last_task_used_math == current)
- save_fpu(current);
- preempt_enable();
-# endif
- p->thread.fpu = current->thread.fpu;
- clear_fpu(task_pt_regs(p));
- set_stopped_child_used_math(p);
- }
-#endif
-
-#ifdef CONFIG_HWZOL
- childregs->lb = 0;
- childregs->le = 0;
- childregs->lc = 0;
-#endif
-
- return 0;
-}
-
-#if IS_ENABLED(CONFIG_FPU)
-struct task_struct *_switch_fpu(struct task_struct *prev, struct task_struct *next)
-{
-#if !IS_ENABLED(CONFIG_LAZY_FPU)
- unlazy_fpu(prev);
-#endif
- if (!(next->flags & PF_KTHREAD))
- clear_fpu(task_pt_regs(next));
- return prev;
-}
-#endif
-
-/*
- * fill in the fpe structure for a core dump...
- */
-int dump_fpu(struct pt_regs *regs, elf_fpregset_t * fpu)
-{
- int fpvalid = 0;
-#if IS_ENABLED(CONFIG_FPU)
- struct task_struct *tsk = current;
-
- fpvalid = tsk_used_math(tsk);
- if (fpvalid) {
- lose_fpu();
- memcpy(fpu, &tsk->thread.fpu, sizeof(*fpu));
- }
-#endif
- return fpvalid;
-}
-
-EXPORT_SYMBOL(dump_fpu);
-
-unsigned long __get_wchan(struct task_struct *p)
-{
- unsigned long fp, lr;
- unsigned long stack_start, stack_end;
- int count = 0;
-
- if (IS_ENABLED(CONFIG_FRAME_POINTER)) {
- stack_start = (unsigned long)end_of_stack(p);
- stack_end = (unsigned long)task_stack_page(p) + THREAD_SIZE;
-
- fp = thread_saved_fp(p);
- do {
- if (fp < stack_start || fp > stack_end)
- return 0;
- lr = ((unsigned long *)fp)[0];
- if (!in_sched_functions(lr))
- return lr;
- fp = *(unsigned long *)(fp + 4);
- } while (count++ < 16);
- }
- return 0;
-}
diff --git a/arch/nds32/kernel/ptrace.c b/arch/nds32/kernel/ptrace.c
deleted file mode 100644
index d0eda870fbc2..000000000000
--- a/arch/nds32/kernel/ptrace.c
+++ /dev/null
@@ -1,118 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-// Copyright (C) 2005-2017 Andes Technology Corporation
-
-#include <linux/ptrace.h>
-#include <linux/regset.h>
-#include <linux/tracehook.h>
-#include <linux/elf.h>
-#include <linux/sched/task_stack.h>
-
-enum nds32_regset {
- REGSET_GPR,
-};
-
-static int gpr_get(struct task_struct *target,
- const struct user_regset *regset,
- struct membuf to)
-{
- return membuf_write(&to, &task_pt_regs(target)->user_regs,
- sizeof(struct user_pt_regs));
-}
-
-static int gpr_set(struct task_struct *target, const struct user_regset *regset,
- unsigned int pos, unsigned int count,
- const void *kbuf, const void __user * ubuf)
-{
- int err;
- struct user_pt_regs newregs = task_pt_regs(target)->user_regs;
-
- err = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &newregs, 0, -1);
- if (err)
- return err;
-
- task_pt_regs(target)->user_regs = newregs;
- return 0;
-}
-
-static const struct user_regset nds32_regsets[] = {
- [REGSET_GPR] = {
- .core_note_type = NT_PRSTATUS,
- .n = sizeof(struct user_pt_regs) / sizeof(u32),
- .size = sizeof(elf_greg_t),
- .align = sizeof(elf_greg_t),
- .regset_get = gpr_get,
- .set = gpr_set}
-};
-
-static const struct user_regset_view nds32_user_view = {
- .name = "nds32",
- .e_machine = EM_NDS32,
- .regsets = nds32_regsets,
- .n = ARRAY_SIZE(nds32_regsets)
-};
-
-const struct user_regset_view *task_user_regset_view(struct task_struct *task)
-{
- return &nds32_user_view;
-}
-
-void ptrace_disable(struct task_struct *child)
-{
- user_disable_single_step(child);
-}
-
-/* do_ptrace()
- *
- * Provide ptrace defined service.
- */
-long arch_ptrace(struct task_struct *child, long request, unsigned long addr,
- unsigned long data)
-{
- int ret = -EIO;
-
- switch (request) {
- default:
- ret = ptrace_request(child, request, addr, data);
- break;
- }
-
- return ret;
-}
-
-void user_enable_single_step(struct task_struct *child)
-{
- struct pt_regs *regs;
- regs = task_pt_regs(child);
- regs->ipsw |= PSW_mskHSS;
- set_tsk_thread_flag(child, TIF_SINGLESTEP);
-}
-
-void user_disable_single_step(struct task_struct *child)
-{
- struct pt_regs *regs;
- regs = task_pt_regs(child);
- regs->ipsw &= ~PSW_mskHSS;
- clear_tsk_thread_flag(child, TIF_SINGLESTEP);
-}
-
-/* sys_trace()
- *
- * syscall trace handler.
- */
-
-asmlinkage int syscall_trace_enter(struct pt_regs *regs)
-{
- if (test_thread_flag(TIF_SYSCALL_TRACE)) {
- if (tracehook_report_syscall_entry(regs))
- forget_syscall(regs);
- }
- return regs->syscallno;
-}
-
-asmlinkage void syscall_trace_leave(struct pt_regs *regs)
-{
- int step = test_thread_flag(TIF_SINGLESTEP);
- if (step || test_thread_flag(TIF_SYSCALL_TRACE))
- tracehook_report_syscall_exit(regs, step);
-
-}
diff --git a/arch/nds32/kernel/setup.c b/arch/nds32/kernel/setup.c
deleted file mode 100644
index b3d34d646652..000000000000
--- a/arch/nds32/kernel/setup.c
+++ /dev/null
@@ -1,369 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-// Copyright (C) 2005-2017 Andes Technology Corporation
-
-#include <linux/cpu.h>
-#include <linux/memblock.h>
-#include <linux/seq_file.h>
-#include <linux/console.h>
-#include <linux/screen_info.h>
-#include <linux/delay.h>
-#include <linux/dma-mapping.h>
-#include <linux/of_fdt.h>
-#include <linux/of_platform.h>
-#include <asm/setup.h>
-#include <asm/sections.h>
-#include <asm/proc-fns.h>
-#include <asm/cache_info.h>
-#include <asm/elf.h>
-#include <asm/fpu.h>
-#include <nds32_intrinsic.h>
-
-#define HWCAP_MFUSR_PC 0x000001
-#define HWCAP_EXT 0x000002
-#define HWCAP_EXT2 0x000004
-#define HWCAP_FPU 0x000008
-#define HWCAP_AUDIO 0x000010
-#define HWCAP_BASE16 0x000020
-#define HWCAP_STRING 0x000040
-#define HWCAP_REDUCED_REGS 0x000080
-#define HWCAP_VIDEO 0x000100
-#define HWCAP_ENCRYPT 0x000200
-#define HWCAP_EDM 0x000400
-#define HWCAP_LMDMA 0x000800
-#define HWCAP_PFM 0x001000
-#define HWCAP_HSMP 0x002000
-#define HWCAP_TRACE 0x004000
-#define HWCAP_DIV 0x008000
-#define HWCAP_MAC 0x010000
-#define HWCAP_L2C 0x020000
-#define HWCAP_FPU_DP 0x040000
-#define HWCAP_V2 0x080000
-#define HWCAP_DX_REGS 0x100000
-#define HWCAP_HWPRE 0x200000
-
-unsigned long cpu_id, cpu_rev, cpu_cfgid;
-bool has_fpu = false;
-char cpu_series;
-char *endianness = NULL;
-
-unsigned int __atags_pointer __initdata;
-unsigned int elf_hwcap;
-EXPORT_SYMBOL(elf_hwcap);
-
-/*
- * The following string table, must sync with HWCAP_xx bitmask,
- * which is defined above
- */
-static const char *hwcap_str[] = {
- "mfusr_pc",
- "perf1",
- "perf2",
- "fpu",
- "audio",
- "16b",
- "string",
- "reduced_regs",
- "video",
- "encrypt",
- "edm",
- "lmdma",
- "pfm",
- "hsmp",
- "trace",
- "div",
- "mac",
- "l2c",
- "fpu_dp",
- "v2",
- "dx_regs",
- "hw_pre",
- NULL,
-};
-
-#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
-#define WRITE_METHOD "write through"
-#else
-#define WRITE_METHOD "write back"
-#endif
-
-struct cache_info L1_cache_info[2];
-static void __init dump_cpu_info(int cpu)
-{
- int i, p = 0;
- char str[sizeof(hwcap_str) + 16];
-
- for (i = 0; hwcap_str[i]; i++) {
- if (elf_hwcap & (1 << i)) {
- sprintf(str + p, "%s ", hwcap_str[i]);
- p += strlen(hwcap_str[i]) + 1;
- }
- }
-
- pr_info("CPU%d Features: %s\n", cpu, str);
-
- L1_cache_info[ICACHE].ways = CACHE_WAY(ICACHE);
- L1_cache_info[ICACHE].line_size = CACHE_LINE_SIZE(ICACHE);
- L1_cache_info[ICACHE].sets = CACHE_SET(ICACHE);
- L1_cache_info[ICACHE].size =
- L1_cache_info[ICACHE].ways * L1_cache_info[ICACHE].line_size *
- L1_cache_info[ICACHE].sets / 1024;
- pr_info("L1I:%dKB/%dS/%dW/%dB\n", L1_cache_info[ICACHE].size,
- L1_cache_info[ICACHE].sets, L1_cache_info[ICACHE].ways,
- L1_cache_info[ICACHE].line_size);
- L1_cache_info[DCACHE].ways = CACHE_WAY(DCACHE);
- L1_cache_info[DCACHE].line_size = CACHE_LINE_SIZE(DCACHE);
- L1_cache_info[DCACHE].sets = CACHE_SET(DCACHE);
- L1_cache_info[DCACHE].size =
- L1_cache_info[DCACHE].ways * L1_cache_info[DCACHE].line_size *
- L1_cache_info[DCACHE].sets / 1024;
- pr_info("L1D:%dKB/%dS/%dW/%dB\n", L1_cache_info[DCACHE].size,
- L1_cache_info[DCACHE].sets, L1_cache_info[DCACHE].ways,
- L1_cache_info[DCACHE].line_size);
- pr_info("L1 D-Cache is %s\n", WRITE_METHOD);
- if (L1_cache_info[DCACHE].size != L1_CACHE_BYTES)
- pr_crit
- ("The cache line size(%d) of this processor is not the same as L1_CACHE_BYTES(%d).\n",
- L1_cache_info[DCACHE].size, L1_CACHE_BYTES);
-#ifdef CONFIG_CPU_CACHE_ALIASING
- {
- int aliasing_num;
- aliasing_num =
- L1_cache_info[ICACHE].size * 1024 / PAGE_SIZE /
- L1_cache_info[ICACHE].ways;
- L1_cache_info[ICACHE].aliasing_num = aliasing_num;
- L1_cache_info[ICACHE].aliasing_mask =
- (aliasing_num - 1) << PAGE_SHIFT;
- aliasing_num =
- L1_cache_info[DCACHE].size * 1024 / PAGE_SIZE /
- L1_cache_info[DCACHE].ways;
- L1_cache_info[DCACHE].aliasing_num = aliasing_num;
- L1_cache_info[DCACHE].aliasing_mask =
- (aliasing_num - 1) << PAGE_SHIFT;
- }
-#endif
-#ifdef CONFIG_FPU
- /* Disable fpu and enable when it is used. */
- if (has_fpu)
- disable_fpu();
-#endif
-}
-
-static void __init setup_cpuinfo(void)
-{
- unsigned long tmp = 0, cpu_name;
-
- cpu_dcache_inval_all();
- cpu_icache_inval_all();
- __nds32__isb();
-
- cpu_id = (__nds32__mfsr(NDS32_SR_CPU_VER) & CPU_VER_mskCPUID) >> CPU_VER_offCPUID;
- cpu_name = ((cpu_id) & 0xf0) >> 4;
- cpu_series = cpu_name ? cpu_name - 10 + 'A' : 'N';
- cpu_id = cpu_id & 0xf;
- cpu_rev = (__nds32__mfsr(NDS32_SR_CPU_VER) & CPU_VER_mskREV) >> CPU_VER_offREV;
- cpu_cfgid = (__nds32__mfsr(NDS32_SR_CPU_VER) & CPU_VER_mskCFGID) >> CPU_VER_offCFGID;
-
- pr_info("CPU:%c%ld, CPU_VER 0x%08x(id %lu, rev %lu, cfg %lu)\n",
- cpu_series, cpu_id, __nds32__mfsr(NDS32_SR_CPU_VER), cpu_id, cpu_rev, cpu_cfgid);
-
- elf_hwcap |= HWCAP_MFUSR_PC;
-
- if (((__nds32__mfsr(NDS32_SR_MSC_CFG) & MSC_CFG_mskBASEV) >> MSC_CFG_offBASEV) == 0) {
- if (__nds32__mfsr(NDS32_SR_MSC_CFG) & MSC_CFG_mskDIV)
- elf_hwcap |= HWCAP_DIV;
-
- if ((__nds32__mfsr(NDS32_SR_MSC_CFG) & MSC_CFG_mskMAC)
- || (cpu_id == 12 && cpu_rev < 4))
- elf_hwcap |= HWCAP_MAC;
- } else {
- elf_hwcap |= HWCAP_V2;
- elf_hwcap |= HWCAP_DIV;
- elf_hwcap |= HWCAP_MAC;
- }
-
- if (cpu_cfgid & 0x0001)
- elf_hwcap |= HWCAP_EXT;
-
- if (cpu_cfgid & 0x0002)
- elf_hwcap |= HWCAP_BASE16;
-
- if (cpu_cfgid & 0x0004)
- elf_hwcap |= HWCAP_EXT2;
-
- if (cpu_cfgid & 0x0008) {
- elf_hwcap |= HWCAP_FPU;
- has_fpu = true;
- }
- if (cpu_cfgid & 0x0010)
- elf_hwcap |= HWCAP_STRING;
-
- if (__nds32__mfsr(NDS32_SR_MMU_CFG) & MMU_CFG_mskDE)
- endianness = "MSB";
- else
- endianness = "LSB";
-
- if (__nds32__mfsr(NDS32_SR_MSC_CFG) & MSC_CFG_mskEDM)
- elf_hwcap |= HWCAP_EDM;
-
- if (__nds32__mfsr(NDS32_SR_MSC_CFG) & MSC_CFG_mskLMDMA)
- elf_hwcap |= HWCAP_LMDMA;
-
- if (__nds32__mfsr(NDS32_SR_MSC_CFG) & MSC_CFG_mskPFM)
- elf_hwcap |= HWCAP_PFM;
-
- if (__nds32__mfsr(NDS32_SR_MSC_CFG) & MSC_CFG_mskHSMP)
- elf_hwcap |= HWCAP_HSMP;
-
- if (__nds32__mfsr(NDS32_SR_MSC_CFG) & MSC_CFG_mskTRACE)
- elf_hwcap |= HWCAP_TRACE;
-
- if (__nds32__mfsr(NDS32_SR_MSC_CFG) & MSC_CFG_mskAUDIO)
- elf_hwcap |= HWCAP_AUDIO;
-
- if (__nds32__mfsr(NDS32_SR_MSC_CFG) & MSC_CFG_mskL2C)
- elf_hwcap |= HWCAP_L2C;
-
-#ifdef CONFIG_HW_PRE
- if (__nds32__mfsr(NDS32_SR_MISC_CTL) & MISC_CTL_makHWPRE_EN)
- elf_hwcap |= HWCAP_HWPRE;
-#endif
-
- tmp = __nds32__mfsr(NDS32_SR_CACHE_CTL);
- if (!IS_ENABLED(CONFIG_CPU_DCACHE_DISABLE))
- tmp |= CACHE_CTL_mskDC_EN;
-
- if (!IS_ENABLED(CONFIG_CPU_ICACHE_DISABLE))
- tmp |= CACHE_CTL_mskIC_EN;
- __nds32__mtsr_isb(tmp, NDS32_SR_CACHE_CTL);
-
- dump_cpu_info(smp_processor_id());
-}
-
-static void __init setup_memory(void)
-{
- unsigned long ram_start_pfn;
- unsigned long free_ram_start_pfn;
- phys_addr_t memory_start, memory_end;
-
- memory_end = memory_start = 0;
-
- /* Find main memory where is the kernel */
- memory_start = memblock_start_of_DRAM();
- memory_end = memblock_end_of_DRAM();
-
- if (!memory_end) {
- panic("No memory!");
- }
-
- ram_start_pfn = PFN_UP(memblock_start_of_DRAM());
- /* free_ram_start_pfn is first page after kernel */
- free_ram_start_pfn = PFN_UP(__pa(&_end));
- max_pfn = PFN_DOWN(memblock_end_of_DRAM());
- /* it could update max_pfn */
- if (max_pfn - ram_start_pfn <= MAXMEM_PFN)
- max_low_pfn = max_pfn;
- else {
- max_low_pfn = MAXMEM_PFN + ram_start_pfn;
- if (!IS_ENABLED(CONFIG_HIGHMEM))
- max_pfn = MAXMEM_PFN + ram_start_pfn;
- }
- /* high_memory is related with VMALLOC */
- high_memory = (void *)__va(max_low_pfn * PAGE_SIZE);
- min_low_pfn = free_ram_start_pfn;
-
- /*
- * initialize the boot-time allocator (with low memory only).
- *
- * This makes the memory from the end of the kernel to the end of
- * RAM usable.
- */
- memblock_set_bottom_up(true);
- memblock_reserve(PFN_PHYS(ram_start_pfn), PFN_PHYS(free_ram_start_pfn - ram_start_pfn));
-
- early_init_fdt_reserve_self();
- early_init_fdt_scan_reserved_mem();
-
- memblock_dump_all();
-}
-
-void __init setup_arch(char **cmdline_p)
-{
- early_init_devtree(__atags_pointer ? \
- phys_to_virt(__atags_pointer) : __dtb_start);
-
- setup_cpuinfo();
-
- setup_initial_init_mm(_stext, _etext, _edata, _end);
-
- /* setup bootmem allocator */
- setup_memory();
-
- /* paging_init() sets up the MMU and marks all pages as reserved */
- paging_init();
-
- /* invalidate all TLB entries because the new mapping is created */
- __nds32__tlbop_flua();
-
- /* use generic way to parse */
- parse_early_param();
-
- unflatten_and_copy_device_tree();
-
- *cmdline_p = boot_command_line;
- early_trap_init();
-}
-
-static int c_show(struct seq_file *m, void *v)
-{
- int i;
-
- seq_printf(m, "Processor\t: %c%ld (id %lu, rev %lu, cfg %lu)\n",
- cpu_series, cpu_id, cpu_id, cpu_rev, cpu_cfgid);
-
- seq_printf(m, "L1I\t\t: %luKB/%luS/%luW/%luB\n",
- CACHE_SET(ICACHE) * CACHE_WAY(ICACHE) *
- CACHE_LINE_SIZE(ICACHE) / 1024, CACHE_SET(ICACHE),
- CACHE_WAY(ICACHE), CACHE_LINE_SIZE(ICACHE));
-
- seq_printf(m, "L1D\t\t: %luKB/%luS/%luW/%luB\n",
- CACHE_SET(DCACHE) * CACHE_WAY(DCACHE) *
- CACHE_LINE_SIZE(DCACHE) / 1024, CACHE_SET(DCACHE),
- CACHE_WAY(DCACHE), CACHE_LINE_SIZE(DCACHE));
-
- seq_printf(m, "BogoMIPS\t: %lu.%02lu\n",
- loops_per_jiffy / (500000 / HZ),
- (loops_per_jiffy / (5000 / HZ)) % 100);
-
- /* dump out the processor features */
- seq_puts(m, "Features\t: ");
-
- for (i = 0; hwcap_str[i]; i++)
- if (elf_hwcap & (1 << i))
- seq_printf(m, "%s ", hwcap_str[i]);
-
- seq_puts(m, "\n\n");
-
- return 0;
-}
-
-static void *c_start(struct seq_file *m, loff_t * pos)
-{
- return *pos < 1 ? (void *)1 : NULL;
-}
-
-static void *c_next(struct seq_file *m, void *v, loff_t * pos)
-{
- ++*pos;
- return NULL;
-}
-
-static void c_stop(struct seq_file *m, void *v)
-{
-}
-
-struct seq_operations cpuinfo_op = {
- .start = c_start,
- .next = c_next,
- .stop = c_stop,
- .show = c_show
-};
diff --git a/arch/nds32/kernel/signal.c b/arch/nds32/kernel/signal.c
deleted file mode 100644
index 7e3ca430a223..000000000000
--- a/arch/nds32/kernel/signal.c
+++ /dev/null
@@ -1,384 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-// Copyright (C) 2005-2017 Andes Technology Corporation
-
-#include <linux/errno.h>
-#include <linux/signal.h>
-#include <linux/ptrace.h>
-#include <linux/personality.h>
-#include <linux/freezer.h>
-#include <linux/tracehook.h>
-#include <linux/uaccess.h>
-
-#include <asm/cacheflush.h>
-#include <asm/ucontext.h>
-#include <asm/unistd.h>
-#include <asm/fpu.h>
-
-#include <asm/ptrace.h>
-#include <asm/vdso.h>
-
-struct rt_sigframe {
- struct siginfo info;
- struct ucontext uc;
-};
-#if IS_ENABLED(CONFIG_FPU)
-static inline int restore_sigcontext_fpu(struct pt_regs *regs,
- struct sigcontext __user *sc)
-{
- struct task_struct *tsk = current;
- unsigned long used_math_flag;
- int ret = 0;
-
- clear_used_math();
- __get_user_error(used_math_flag, &sc->used_math_flag, ret);
-
- if (!used_math_flag)
- return 0;
- set_used_math();
-
-#if IS_ENABLED(CONFIG_LAZY_FPU)
- preempt_disable();
- if (current == last_task_used_math) {
- last_task_used_math = NULL;
- disable_ptreg_fpu(regs);
- }
- preempt_enable();
-#else
- clear_fpu(regs);
-#endif
-
- return __copy_from_user(&tsk->thread.fpu, &sc->fpu,
- sizeof(struct fpu_struct));
-}
-
-static inline int setup_sigcontext_fpu(struct pt_regs *regs,
- struct sigcontext __user *sc)
-{
- struct task_struct *tsk = current;
- int ret = 0;
-
- __put_user_error(used_math(), &sc->used_math_flag, ret);
-
- if (!used_math())
- return ret;
-
- preempt_disable();
-#if IS_ENABLED(CONFIG_LAZY_FPU)
- if (last_task_used_math == tsk)
- save_fpu(last_task_used_math);
-#else
- unlazy_fpu(tsk);
-#endif
- ret = __copy_to_user(&sc->fpu, &tsk->thread.fpu,
- sizeof(struct fpu_struct));
- preempt_enable();
- return ret;
-}
-#endif
-
-static int restore_sigframe(struct pt_regs *regs,
- struct rt_sigframe __user * sf)
-{
- sigset_t set;
- int err;
-
- err = __copy_from_user(&set, &sf->uc.uc_sigmask, sizeof(set));
- if (err == 0) {
- set_current_blocked(&set);
- }
-
- __get_user_error(regs->uregs[0], &sf->uc.uc_mcontext.nds32_r0, err);
- __get_user_error(regs->uregs[1], &sf->uc.uc_mcontext.nds32_r1, err);
- __get_user_error(regs->uregs[2], &sf->uc.uc_mcontext.nds32_r2, err);
- __get_user_error(regs->uregs[3], &sf->uc.uc_mcontext.nds32_r3, err);
- __get_user_error(regs->uregs[4], &sf->uc.uc_mcontext.nds32_r4, err);
- __get_user_error(regs->uregs[5], &sf->uc.uc_mcontext.nds32_r5, err);
- __get_user_error(regs->uregs[6], &sf->uc.uc_mcontext.nds32_r6, err);
- __get_user_error(regs->uregs[7], &sf->uc.uc_mcontext.nds32_r7, err);
- __get_user_error(regs->uregs[8], &sf->uc.uc_mcontext.nds32_r8, err);
- __get_user_error(regs->uregs[9], &sf->uc.uc_mcontext.nds32_r9, err);
- __get_user_error(regs->uregs[10], &sf->uc.uc_mcontext.nds32_r10, err);
- __get_user_error(regs->uregs[11], &sf->uc.uc_mcontext.nds32_r11, err);
- __get_user_error(regs->uregs[12], &sf->uc.uc_mcontext.nds32_r12, err);
- __get_user_error(regs->uregs[13], &sf->uc.uc_mcontext.nds32_r13, err);
- __get_user_error(regs->uregs[14], &sf->uc.uc_mcontext.nds32_r14, err);
- __get_user_error(regs->uregs[15], &sf->uc.uc_mcontext.nds32_r15, err);
- __get_user_error(regs->uregs[16], &sf->uc.uc_mcontext.nds32_r16, err);
- __get_user_error(regs->uregs[17], &sf->uc.uc_mcontext.nds32_r17, err);
- __get_user_error(regs->uregs[18], &sf->uc.uc_mcontext.nds32_r18, err);
- __get_user_error(regs->uregs[19], &sf->uc.uc_mcontext.nds32_r19, err);
- __get_user_error(regs->uregs[20], &sf->uc.uc_mcontext.nds32_r20, err);
- __get_user_error(regs->uregs[21], &sf->uc.uc_mcontext.nds32_r21, err);
- __get_user_error(regs->uregs[22], &sf->uc.uc_mcontext.nds32_r22, err);
- __get_user_error(regs->uregs[23], &sf->uc.uc_mcontext.nds32_r23, err);
- __get_user_error(regs->uregs[24], &sf->uc.uc_mcontext.nds32_r24, err);
- __get_user_error(regs->uregs[25], &sf->uc.uc_mcontext.nds32_r25, err);
-
- __get_user_error(regs->fp, &sf->uc.uc_mcontext.nds32_fp, err);
- __get_user_error(regs->gp, &sf->uc.uc_mcontext.nds32_gp, err);
- __get_user_error(regs->lp, &sf->uc.uc_mcontext.nds32_lp, err);
- __get_user_error(regs->sp, &sf->uc.uc_mcontext.nds32_sp, err);
- __get_user_error(regs->ipc, &sf->uc.uc_mcontext.nds32_ipc, err);
-#if defined(CONFIG_HWZOL)
- __get_user_error(regs->lc, &sf->uc.uc_mcontext.zol.nds32_lc, err);
- __get_user_error(regs->le, &sf->uc.uc_mcontext.zol.nds32_le, err);
- __get_user_error(regs->lb, &sf->uc.uc_mcontext.zol.nds32_lb, err);
-#endif
-#if IS_ENABLED(CONFIG_FPU)
- err |= restore_sigcontext_fpu(regs, &sf->uc.uc_mcontext);
-#endif
- /*
- * Avoid sys_rt_sigreturn() restarting.
- */
- forget_syscall(regs);
- return err;
-}
-
-asmlinkage long sys_rt_sigreturn(struct pt_regs *regs)
-{
- struct rt_sigframe __user *frame;
-
- /* Always make any pending restarted system calls return -EINTR */
- current->restart_block.fn = do_no_restart_syscall;
-
- /*
- * Since we stacked the signal on a 64-bit boundary,
- * then 'sp' should be two-word aligned here. If it's
- * not, then the user is trying to mess with us.
- */
- if (regs->sp & 7)
- goto badframe;
-
- frame = (struct rt_sigframe __user *)regs->sp;
-
- if (!access_ok(frame, sizeof(*frame)))
- goto badframe;
-
- if (restore_sigframe(regs, frame))
- goto badframe;
-
- if (restore_altstack(&frame->uc.uc_stack))
- goto badframe;
-
- return regs->uregs[0];
-
-badframe:
- force_sig(SIGSEGV);
- return 0;
-}
-
-static int
-setup_sigframe(struct rt_sigframe __user * sf, struct pt_regs *regs,
- sigset_t * set)
-{
- int err = 0;
-
- __put_user_error(regs->uregs[0], &sf->uc.uc_mcontext.nds32_r0, err);
- __put_user_error(regs->uregs[1], &sf->uc.uc_mcontext.nds32_r1, err);
- __put_user_error(regs->uregs[2], &sf->uc.uc_mcontext.nds32_r2, err);
- __put_user_error(regs->uregs[3], &sf->uc.uc_mcontext.nds32_r3, err);
- __put_user_error(regs->uregs[4], &sf->uc.uc_mcontext.nds32_r4, err);
- __put_user_error(regs->uregs[5], &sf->uc.uc_mcontext.nds32_r5, err);
- __put_user_error(regs->uregs[6], &sf->uc.uc_mcontext.nds32_r6, err);
- __put_user_error(regs->uregs[7], &sf->uc.uc_mcontext.nds32_r7, err);
- __put_user_error(regs->uregs[8], &sf->uc.uc_mcontext.nds32_r8, err);
- __put_user_error(regs->uregs[9], &sf->uc.uc_mcontext.nds32_r9, err);
- __put_user_error(regs->uregs[10], &sf->uc.uc_mcontext.nds32_r10, err);
- __put_user_error(regs->uregs[11], &sf->uc.uc_mcontext.nds32_r11, err);
- __put_user_error(regs->uregs[12], &sf->uc.uc_mcontext.nds32_r12, err);
- __put_user_error(regs->uregs[13], &sf->uc.uc_mcontext.nds32_r13, err);
- __put_user_error(regs->uregs[14], &sf->uc.uc_mcontext.nds32_r14, err);
- __put_user_error(regs->uregs[15], &sf->uc.uc_mcontext.nds32_r15, err);
- __put_user_error(regs->uregs[16], &sf->uc.uc_mcontext.nds32_r16, err);
- __put_user_error(regs->uregs[17], &sf->uc.uc_mcontext.nds32_r17, err);
- __put_user_error(regs->uregs[18], &sf->uc.uc_mcontext.nds32_r18, err);
- __put_user_error(regs->uregs[19], &sf->uc.uc_mcontext.nds32_r19, err);
- __put_user_error(regs->uregs[20], &sf->uc.uc_mcontext.nds32_r20, err);
-
- __put_user_error(regs->uregs[21], &sf->uc.uc_mcontext.nds32_r21, err);
- __put_user_error(regs->uregs[22], &sf->uc.uc_mcontext.nds32_r22, err);
- __put_user_error(regs->uregs[23], &sf->uc.uc_mcontext.nds32_r23, err);
- __put_user_error(regs->uregs[24], &sf->uc.uc_mcontext.nds32_r24, err);
- __put_user_error(regs->uregs[25], &sf->uc.uc_mcontext.nds32_r25, err);
- __put_user_error(regs->fp, &sf->uc.uc_mcontext.nds32_fp, err);
- __put_user_error(regs->gp, &sf->uc.uc_mcontext.nds32_gp, err);
- __put_user_error(regs->lp, &sf->uc.uc_mcontext.nds32_lp, err);
- __put_user_error(regs->sp, &sf->uc.uc_mcontext.nds32_sp, err);
- __put_user_error(regs->ipc, &sf->uc.uc_mcontext.nds32_ipc, err);
-#if defined(CONFIG_HWZOL)
- __put_user_error(regs->lc, &sf->uc.uc_mcontext.zol.nds32_lc, err);
- __put_user_error(regs->le, &sf->uc.uc_mcontext.zol.nds32_le, err);
- __put_user_error(regs->lb, &sf->uc.uc_mcontext.zol.nds32_lb, err);
-#endif
-#if IS_ENABLED(CONFIG_FPU)
- err |= setup_sigcontext_fpu(regs, &sf->uc.uc_mcontext);
-#endif
-
- __put_user_error(current->thread.trap_no, &sf->uc.uc_mcontext.trap_no,
- err);
- __put_user_error(current->thread.error_code,
- &sf->uc.uc_mcontext.error_code, err);
- __put_user_error(current->thread.address,
- &sf->uc.uc_mcontext.fault_address, err);
- __put_user_error(set->sig[0], &sf->uc.uc_mcontext.oldmask, err);
-
- err |= __copy_to_user(&sf->uc.uc_sigmask, set, sizeof(*set));
-
- return err;
-}
-
-static inline void __user *get_sigframe(struct ksignal *ksig,
- struct pt_regs *regs, int framesize)
-{
- unsigned long sp;
-
- /* Default to using normal stack */
- sp = regs->sp;
-
- /*
- * If we are on the alternate signal stack and would overflow it, don't.
- * Return an always-bogus address instead so we will die with SIGSEGV.
- */
- if (on_sig_stack(sp) && !likely(on_sig_stack(sp - framesize)))
- return (void __user __force *)(-1UL);
-
- /* This is the X/Open sanctioned signal stack switching. */
- sp = (sigsp(sp, ksig) - framesize);
-
- /*
- * nds32 mandates 8-byte alignment
- */
- sp &= ~0x7UL;
-
- return (void __user *)sp;
-}
-
-static int
-setup_return(struct pt_regs *regs, struct ksignal *ksig, void __user * frame)
-{
- unsigned long handler = (unsigned long)ksig->ka.sa.sa_handler;
- unsigned long retcode;
-
- retcode = VDSO_SYMBOL(current->mm->context.vdso, rt_sigtramp);
- regs->uregs[0] = ksig->sig;
- regs->sp = (unsigned long)frame;
- regs->lp = retcode;
- regs->ipc = handler;
-
- return 0;
-}
-
-static int
-setup_rt_frame(struct ksignal *ksig, sigset_t * set, struct pt_regs *regs)
-{
- struct rt_sigframe __user *frame =
- get_sigframe(ksig, regs, sizeof(*frame));
- int err = 0;
-
- if (!access_ok(frame, sizeof(*frame)))
- return -EFAULT;
-
- __put_user_error(0, &frame->uc.uc_flags, err);
- __put_user_error(NULL, &frame->uc.uc_link, err);
-
- err |= __save_altstack(&frame->uc.uc_stack, regs->sp);
- err |= setup_sigframe(frame, regs, set);
- if (err == 0) {
- setup_return(regs, ksig, frame);
- if (ksig->ka.sa.sa_flags & SA_SIGINFO) {
- err |= copy_siginfo_to_user(&frame->info, &ksig->info);
- regs->uregs[1] = (unsigned long)&frame->info;
- regs->uregs[2] = (unsigned long)&frame->uc;
- }
- }
- return err;
-}
-
-/*
- * OK, we're invoking a handler
- */
-static void handle_signal(struct ksignal *ksig, struct pt_regs *regs)
-{
- int ret;
- sigset_t *oldset = sigmask_to_save();
-
- if (in_syscall(regs)) {
- /* Avoid additional syscall restarting via ret_slow_syscall. */
- forget_syscall(regs);
-
- switch (regs->uregs[0]) {
- case -ERESTART_RESTARTBLOCK:
- case -ERESTARTNOHAND:
- regs->uregs[0] = -EINTR;
- break;
- case -ERESTARTSYS:
- if (!(ksig->ka.sa.sa_flags & SA_RESTART)) {
- regs->uregs[0] = -EINTR;
- break;
- }
- fallthrough;
- case -ERESTARTNOINTR:
- regs->uregs[0] = regs->orig_r0;
- regs->ipc -= 4;
- break;
- }
- }
- /*
- * Set up the stack frame
- */
- ret = setup_rt_frame(ksig, oldset, regs);
-
- signal_setup_done(ret, ksig, 0);
-}
-
-/*
- * Note that 'init' is a special process: it doesn't get signals it doesn't
- * want to handle. Thus you cannot kill init even with a SIGKILL even by
- * mistake.
- *
- * Note that we go through the signals twice: once to check the signals that
- * 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)
-{
- struct ksignal ksig;
-
- if (get_signal(&ksig)) {
- handle_signal(&ksig, regs);
- return;
- }
-
- /*
- * If we were from a system call, check for system call restarting...
- */
- if (in_syscall(regs)) {
- /* Restart the system call - no handlers present */
-
- /* Avoid additional syscall restarting via ret_slow_syscall. */
- forget_syscall(regs);
-
- switch (regs->uregs[0]) {
- case -ERESTART_RESTARTBLOCK:
- regs->uregs[15] = __NR_restart_syscall;
- fallthrough;
- case -ERESTARTNOHAND:
- case -ERESTARTSYS:
- case -ERESTARTNOINTR:
- regs->uregs[0] = regs->orig_r0;
- regs->ipc -= 0x4;
- break;
- }
- }
- restore_saved_sigmask();
-}
-
-asmlinkage void
-do_notify_resume(struct pt_regs *regs, unsigned int thread_flags)
-{
- if (thread_flags & (_TIF_SIGPENDING | _TIF_NOTIFY_SIGNAL))
- do_signal(regs);
-
- if (thread_flags & _TIF_NOTIFY_RESUME)
- tracehook_notify_resume(regs);
-}
diff --git a/arch/nds32/kernel/sleep.S b/arch/nds32/kernel/sleep.S
deleted file mode 100644
index ca4e61f3656f..000000000000
--- a/arch/nds32/kernel/sleep.S
+++ /dev/null
@@ -1,131 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/* Copyright (C) 2017 Andes Technology Corporation */
-
-#include <asm/memory.h>
-
-.data
-.global sp_tmp
-sp_tmp:
-.long
-
-.text
-.globl suspend2ram
-.globl cpu_resume
-
-suspend2ram:
- pushm $r0, $r31
-#if defined(CONFIG_HWZOL)
- mfusr $r0, $lc
- mfusr $r1, $le
- mfusr $r2, $lb
-#endif
- mfsr $r3, $mr0
- mfsr $r4, $mr1
- mfsr $r5, $mr4
- mfsr $r6, $mr6
- mfsr $r7, $mr7
- mfsr $r8, $mr8
- mfsr $r9, $ir0
- mfsr $r10, $ir1
- mfsr $r11, $ir2
- mfsr $r12, $ir3
- mfsr $r13, $ir9
- mfsr $r14, $ir10
- mfsr $r15, $ir12
- mfsr $r16, $ir13
- mfsr $r17, $ir14
- mfsr $r18, $ir15
- pushm $r0, $r19
-#if defined(CONFIG_FPU)
- jal store_fpu_for_suspend
-#endif
- tlbop FlushAll
- isb
-
- // transfer $sp from va to pa
- sethi $r0, hi20(PAGE_OFFSET)
- ori $r0, $r0, lo12(PAGE_OFFSET)
- movi $r2, PHYS_OFFSET
- sub $r1, $sp, $r0
- add $r2, $r1, $r2
-
- // store pa($sp) to sp_tmp
- sethi $r1, hi20(sp_tmp)
- swi $r2, [$r1 + lo12(sp_tmp)]
-
- pushm $r16, $r25
- pushm $r29, $r30
-#ifdef CONFIG_CACHE_L2
- jal dcache_wb_all_level
-#else
- jal cpu_dcache_wb_all
-#endif
- popm $r29, $r30
- popm $r16, $r25
-
- // get wake_mask and loop in standby
- la $r1, wake_mask
- lwi $r1, [$r1]
-self_loop:
- standby wake_grant
- mfsr $r2, $ir15
- and $r2, $r1, $r2
- beqz $r2, self_loop
-
- // set ipc to resume address
- la $r1, resume_addr
- lwi $r1, [$r1]
- mtsr $r1, $ipc
- isb
-
- // reset psw, turn off the address translation
- li $r2, 0x7000a
- mtsr $r2, $ipsw
- isb
-
- iret
-cpu_resume:
- // translate the address of sp_tmp variable to pa
- la $r1, sp_tmp
- sethi $r0, hi20(PAGE_OFFSET)
- ori $r0, $r0, lo12(PAGE_OFFSET)
- movi $r2, PHYS_OFFSET
- sub $r1, $r1, $r0
- add $r1, $r1, $r2
-
- // access the sp_tmp to get stack pointer
- lwi $sp, [$r1]
-
- popm $r0, $r19
-#if defined(CONFIG_HWZOL)
- mtusr $r0, $lb
- mtusr $r1, $lc
- mtusr $r2, $le
-#endif
- mtsr $r3, $mr0
- mtsr $r4, $mr1
- mtsr $r5, $mr4
- mtsr $r6, $mr6
- mtsr $r7, $mr7
- mtsr $r8, $mr8
- // set original psw to ipsw
- mtsr $r9, $ir1
-
- mtsr $r11, $ir2
- mtsr $r12, $ir3
-
- // set ipc to RR
- la $r13, RR
- mtsr $r13, $ir9
-
- mtsr $r14, $ir10
- mtsr $r15, $ir12
- mtsr $r16, $ir13
- mtsr $r17, $ir14
- mtsr $r18, $ir15
- popm $r0, $r31
-
- isb
- iret
-RR:
- ret
diff --git a/arch/nds32/kernel/stacktrace.c b/arch/nds32/kernel/stacktrace.c
deleted file mode 100644
index d974c0c1c65f..000000000000
--- a/arch/nds32/kernel/stacktrace.c
+++ /dev/null
@@ -1,53 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-// Copyright (C) 2005-2017 Andes Technology Corporation
-
-#include <linux/sched/debug.h>
-#include <linux/sched/task_stack.h>
-#include <linux/stacktrace.h>
-#include <linux/ftrace.h>
-
-void save_stack_trace(struct stack_trace *trace)
-{
- save_stack_trace_tsk(current, trace);
-}
-EXPORT_SYMBOL_GPL(save_stack_trace);
-
-void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace)
-{
- unsigned long *fpn;
- int skip = trace->skip;
- int savesched;
- int graph_idx = 0;
-
- if (tsk == current) {
- __asm__ __volatile__("\tori\t%0, $fp, #0\n":"=r"(fpn));
- savesched = 1;
- } else {
- fpn = (unsigned long *)thread_saved_fp(tsk);
- savesched = 0;
- }
-
- while (!kstack_end(fpn) && !((unsigned long)fpn & 0x3)
- && (fpn >= (unsigned long *)TASK_SIZE)) {
- unsigned long lpp, fpp;
-
- lpp = fpn[LP_OFFSET];
- fpp = fpn[FP_OFFSET];
- if (!__kernel_text_address(lpp))
- break;
- else
- lpp = ftrace_graph_ret_addr(tsk, &graph_idx, lpp, NULL);
-
- if (savesched || !in_sched_functions(lpp)) {
- if (skip) {
- skip--;
- } else {
- trace->entries[trace->nr_entries++] = lpp;
- if (trace->nr_entries >= trace->max_entries)
- break;
- }
- }
- fpn = (unsigned long *)fpp;
- }
-}
-EXPORT_SYMBOL_GPL(save_stack_trace_tsk);
diff --git a/arch/nds32/kernel/sys_nds32.c b/arch/nds32/kernel/sys_nds32.c
deleted file mode 100644
index cb2d1e219bb3..000000000000
--- a/arch/nds32/kernel/sys_nds32.c
+++ /dev/null
@@ -1,84 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-// Copyright (C) 2005-2017 Andes Technology Corporation
-
-#include <linux/syscalls.h>
-#include <linux/uaccess.h>
-
-#include <asm/cachectl.h>
-#include <asm/proc-fns.h>
-#include <asm/fpu.h>
-#include <asm/fp_udfiex_crtl.h>
-
-SYSCALL_DEFINE6(mmap2, unsigned long, addr, unsigned long, len,
- unsigned long, prot, unsigned long, flags,
- unsigned long, fd, unsigned long, pgoff)
-{
- if (pgoff & (~PAGE_MASK >> 12))
- return -EINVAL;
-
- return sys_mmap_pgoff(addr, len, prot, flags, fd,
- pgoff >> (PAGE_SHIFT - 12));
-}
-
-SYSCALL_DEFINE4(fadvise64_64_wrapper,int, fd, int, advice, loff_t, offset,
- loff_t, len)
-{
- return sys_fadvise64_64(fd, offset, len, advice);
-}
-
-SYSCALL_DEFINE3(cacheflush, unsigned int, start, unsigned int, end, int, cache)
-{
- struct vm_area_struct *vma;
- bool flushi = true, wbd = true;
-
- vma = find_vma(current->mm, start);
- if (!vma)
- return -EFAULT;
- switch (cache) {
- case ICACHE:
- wbd = false;
- break;
- case DCACHE:
- flushi = false;
- break;
- case BCACHE:
- break;
- default:
- return -EINVAL;
- }
- cpu_cache_wbinval_range_check(vma, start, end, flushi, wbd);
-
- return 0;
-}
-
-SYSCALL_DEFINE2(fp_udfiex_crtl, unsigned int, cmd, unsigned int, act)
-{
-#if IS_ENABLED(CONFIG_SUPPORT_DENORMAL_ARITHMETIC)
- int old_udf_iex;
-
- if (!used_math()) {
- load_fpu(&init_fpuregs);
- current->thread.fpu.UDF_IEX_trap = init_fpuregs.UDF_IEX_trap;
- set_used_math();
- }
-
- old_udf_iex = current->thread.fpu.UDF_IEX_trap;
- act &= (FPCSR_mskUDFE | FPCSR_mskIEXE);
-
- switch (cmd) {
- case DISABLE_UDF_IEX_TRAP:
- current->thread.fpu.UDF_IEX_trap &= ~act;
- break;
- case ENABLE_UDF_IEX_TRAP:
- current->thread.fpu.UDF_IEX_trap |= act;
- break;
- case GET_UDF_IEX_TRAP:
- break;
- default:
- return -EINVAL;
- }
- return old_udf_iex;
-#else
- return -ENOTSUPP;
-#endif
-}
diff --git a/arch/nds32/kernel/syscall_table.c b/arch/nds32/kernel/syscall_table.c
deleted file mode 100644
index 7879c061b87f..000000000000
--- a/arch/nds32/kernel/syscall_table.c
+++ /dev/null
@@ -1,17 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-// Copyright (C) 2005-2017 Andes Technology Corporation
-
-#include <linux/syscalls.h>
-#include <linux/signal.h>
-#include <linux/unistd.h>
-#include <asm/syscalls.h>
-
-#undef __SYSCALL
-#define __SYSCALL(nr, call) [nr] = (call),
-
-#define sys_rt_sigreturn sys_rt_sigreturn_wrapper
-#define sys_fadvise64_64 sys_fadvise64_64_wrapper
-void *sys_call_table[__NR_syscalls] __aligned(8192) = {
- [0 ... __NR_syscalls - 1] = sys_ni_syscall,
-#include <asm/unistd.h>
-};
diff --git a/arch/nds32/kernel/time.c b/arch/nds32/kernel/time.c
deleted file mode 100644
index 574a3d0a8539..000000000000
--- a/arch/nds32/kernel/time.c
+++ /dev/null
@@ -1,11 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-// Copyright (C) 2005-2017 Andes Technology Corporation
-
-#include <linux/clocksource.h>
-#include <linux/of_clk.h>
-
-void __init time_init(void)
-{
- of_clk_init(NULL);
- timer_probe();
-}
diff --git a/arch/nds32/kernel/traps.c b/arch/nds32/kernel/traps.c
deleted file mode 100644
index c0a8f3344fb9..000000000000
--- a/arch/nds32/kernel/traps.c
+++ /dev/null
@@ -1,354 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-// Copyright (C) 2005-2017 Andes Technology Corporation
-
-#include <linux/module.h>
-#include <linux/personality.h>
-#include <linux/kallsyms.h>
-#include <linux/hardirq.h>
-#include <linux/kdebug.h>
-#include <linux/sched/task_stack.h>
-#include <linux/uaccess.h>
-#include <linux/ftrace.h>
-
-#include <asm/proc-fns.h>
-#include <asm/unistd.h>
-#include <asm/fpu.h>
-
-#include <linux/ptrace.h>
-#include <nds32_intrinsic.h>
-
-extern void show_pte(struct mm_struct *mm, unsigned long addr);
-
-/*
- * Dump out the contents of some memory nicely...
- */
-void dump_mem(const char *lvl, unsigned long bottom, unsigned long top)
-{
- unsigned long first;
- int i;
-
- pr_emerg("%s(0x%08lx to 0x%08lx)\n", lvl, bottom, top);
-
- for (first = bottom & ~31; first < top; first += 32) {
- unsigned long p;
- char str[sizeof(" 12345678") * 8 + 1];
-
- memset(str, ' ', sizeof(str));
- str[sizeof(str) - 1] = '\0';
-
- for (p = first, i = 0; i < 8 && p < top; i++, p += 4) {
- if (p >= bottom && p < top) {
- unsigned long val;
-
- if (get_kernel_nofault(val,
- (unsigned long *)p) == 0)
- sprintf(str + i * 9, " %08lx", val);
- else
- sprintf(str + i * 9, " ????????");
- }
- }
- pr_emerg("%s%04lx:%s\n", lvl, first & 0xffff, str);
- }
-}
-
-EXPORT_SYMBOL(dump_mem);
-
-#define LOOP_TIMES (100)
-static void __dump(struct task_struct *tsk, unsigned long *base_reg,
- const char *loglvl)
-{
- unsigned long ret_addr;
- int cnt = LOOP_TIMES, graph = 0;
- printk("%sCall Trace:\n", loglvl);
- if (!IS_ENABLED(CONFIG_FRAME_POINTER)) {
- while (!kstack_end(base_reg)) {
- ret_addr = *base_reg++;
- if (__kernel_text_address(ret_addr)) {
- ret_addr = ftrace_graph_ret_addr(
- tsk, &graph, ret_addr, NULL);
- print_ip_sym(loglvl, ret_addr);
- }
- if (--cnt < 0)
- break;
- }
- } else {
- while (!kstack_end((void *)base_reg) &&
- !((unsigned long)base_reg & 0x3) &&
- ((unsigned long)base_reg >= TASK_SIZE)) {
- unsigned long next_fp;
- ret_addr = base_reg[LP_OFFSET];
- next_fp = base_reg[FP_OFFSET];
- if (__kernel_text_address(ret_addr)) {
-
- ret_addr = ftrace_graph_ret_addr(
- tsk, &graph, ret_addr, NULL);
- print_ip_sym(loglvl, ret_addr);
- }
- if (--cnt < 0)
- break;
- base_reg = (unsigned long *)next_fp;
- }
- }
- printk("%s\n", loglvl);
-}
-
-void show_stack(struct task_struct *tsk, unsigned long *sp, const char *loglvl)
-{
- unsigned long *base_reg;
-
- if (!tsk)
- tsk = current;
- if (!IS_ENABLED(CONFIG_FRAME_POINTER)) {
- if (tsk != current)
- base_reg = (unsigned long *)(tsk->thread.cpu_context.sp);
- else
- __asm__ __volatile__("\tori\t%0, $sp, #0\n":"=r"(base_reg));
- } else {
- if (tsk != current)
- base_reg = (unsigned long *)(tsk->thread.cpu_context.fp);
- else
- __asm__ __volatile__("\tori\t%0, $fp, #0\n":"=r"(base_reg));
- }
- __dump(tsk, base_reg, loglvl);
- barrier();
-}
-
-DEFINE_SPINLOCK(die_lock);
-
-/*
- * This function is protected against re-entrancy.
- */
-void __noreturn die(const char *str, struct pt_regs *regs, int err)
-{
- struct task_struct *tsk = current;
- static int die_counter;
-
- console_verbose();
- spin_lock_irq(&die_lock);
- bust_spinlocks(1);
-
- pr_emerg("Internal error: %s: %x [#%d]\n", str, err, ++die_counter);
- print_modules();
- pr_emerg("CPU: %i\n", smp_processor_id());
- show_regs(regs);
- pr_emerg("Process %s (pid: %d, stack limit = 0x%p)\n",
- tsk->comm, tsk->pid, end_of_stack(tsk));
-
- if (!user_mode(regs) || in_interrupt()) {
- dump_mem("Stack: ", regs->sp, (regs->sp + PAGE_SIZE) & PAGE_MASK);
- dump_stack();
- }
-
- bust_spinlocks(0);
- spin_unlock_irq(&die_lock);
- make_task_dead(SIGSEGV);
-}
-
-EXPORT_SYMBOL(die);
-
-void die_if_kernel(const char *str, struct pt_regs *regs, int err)
-{
- if (user_mode(regs))
- return;
-
- die(str, regs, err);
-}
-
-int bad_syscall(int n, struct pt_regs *regs)
-{
- if (current->personality != PER_LINUX) {
- send_sig(SIGSEGV, current, 1);
- return regs->uregs[0];
- }
-
- force_sig_fault(SIGILL, ILL_ILLTRP,
- (void __user *)instruction_pointer(regs) - 4);
- die_if_kernel("Oops - bad syscall", regs, n);
- return regs->uregs[0];
-}
-
-void __pte_error(const char *file, int line, unsigned long val)
-{
- pr_emerg("%s:%d: bad pte %08lx.\n", file, line, val);
-}
-
-void __pmd_error(const char *file, int line, unsigned long val)
-{
- pr_emerg("%s:%d: bad pmd %08lx.\n", file, line, val);
-}
-
-void __pgd_error(const char *file, int line, unsigned long val)
-{
- pr_emerg("%s:%d: bad pgd %08lx.\n", file, line, val);
-}
-
-extern char *exception_vector, *exception_vector_end;
-void __init early_trap_init(void)
-{
- unsigned long ivb = 0;
- unsigned long base = PAGE_OFFSET;
-
- memcpy((unsigned long *)base, (unsigned long *)&exception_vector,
- ((unsigned long)&exception_vector_end -
- (unsigned long)&exception_vector));
- ivb = __nds32__mfsr(NDS32_SR_IVB);
- /* Check platform support. */
- if (((ivb & IVB_mskNIVIC) >> IVB_offNIVIC) < 2)
- panic
- ("IVIC mode is not allowed on the platform with interrupt controller\n");
- __nds32__mtsr((ivb & ~IVB_mskESZ) | (IVB_valESZ16 << IVB_offESZ) |
- IVB_BASE, NDS32_SR_IVB);
- __nds32__mtsr(INT_MASK_INITAIAL_VAL, NDS32_SR_INT_MASK);
-
- /*
- * 0x800 = 128 vectors * 16byte.
- * It should be enough to flush a page.
- */
- cpu_cache_wbinval_page(base, true);
-}
-
-static void send_sigtrap(struct pt_regs *regs, int error_code, int si_code)
-{
- struct task_struct *tsk = current;
-
- tsk->thread.trap_no = ENTRY_DEBUG_RELATED;
- tsk->thread.error_code = error_code;
-
- force_sig_fault(SIGTRAP, si_code,
- (void __user *)instruction_pointer(regs));
-}
-
-void do_debug_trap(unsigned long entry, unsigned long addr,
- unsigned long type, struct pt_regs *regs)
-{
- if (notify_die(DIE_OOPS, "Oops", regs, addr, type, SIGTRAP)
- == NOTIFY_STOP)
- return;
-
- if (user_mode(regs)) {
- /* trap_signal */
- send_sigtrap(regs, 0, TRAP_BRKPT);
- } else {
- /* kernel_trap */
- if (!fixup_exception(regs))
- die("unexpected kernel_trap", regs, 0);
- }
-}
-
-void unhandled_interruption(struct pt_regs *regs)
-{
- pr_emerg("unhandled_interruption\n");
- show_regs(regs);
- if (!user_mode(regs))
- make_task_dead(SIGKILL);
- force_sig(SIGKILL);
-}
-
-void unhandled_exceptions(unsigned long entry, unsigned long addr,
- unsigned long type, struct pt_regs *regs)
-{
- pr_emerg("Unhandled Exception: entry: %lx addr:%lx itype:%lx\n", entry,
- addr, type);
- show_regs(regs);
- if (!user_mode(regs))
- make_task_dead(SIGKILL);
- force_sig(SIGKILL);
-}
-
-extern int do_page_fault(unsigned long entry, unsigned long addr,
- unsigned int error_code, struct pt_regs *regs);
-
-/*
- * 2:DEF dispatch for TLB MISC exception handler
-*/
-
-void do_dispatch_tlb_misc(unsigned long entry, unsigned long addr,
- unsigned long type, struct pt_regs *regs)
-{
- type = type & (ITYPE_mskINST | ITYPE_mskETYPE);
- if ((type & ITYPE_mskETYPE) < 5) {
- /* Permission exceptions */
- do_page_fault(entry, addr, type, regs);
- } else
- unhandled_exceptions(entry, addr, type, regs);
-}
-
-void do_revinsn(struct pt_regs *regs)
-{
- pr_emerg("Reserved Instruction\n");
- show_regs(regs);
- if (!user_mode(regs))
- make_task_dead(SIGILL);
- force_sig(SIGILL);
-}
-
-#ifdef CONFIG_ALIGNMENT_TRAP
-extern int unalign_access_mode;
-extern int do_unaligned_access(unsigned long addr, struct pt_regs *regs);
-#endif
-void do_dispatch_general(unsigned long entry, unsigned long addr,
- unsigned long itype, struct pt_regs *regs,
- unsigned long oipc)
-{
- unsigned int swid = itype >> ITYPE_offSWID;
- unsigned long type = itype & (ITYPE_mskINST | ITYPE_mskETYPE);
- if (type == ETYPE_ALIGNMENT_CHECK) {
-#ifdef CONFIG_ALIGNMENT_TRAP
- /* Alignment check */
- if (user_mode(regs) && unalign_access_mode) {
- int ret;
- ret = do_unaligned_access(addr, regs);
-
- if (ret == 0)
- return;
-
- if (ret == -EFAULT)
- pr_emerg
- ("Unhandled unaligned access exception\n");
- }
-#endif
- do_page_fault(entry, addr, type, regs);
- } else if (type == ETYPE_RESERVED_INSTRUCTION) {
- /* Reserved instruction */
- do_revinsn(regs);
- } else if (type == ETYPE_COPROCESSOR) {
- /* Coprocessor */
-#if IS_ENABLED(CONFIG_FPU)
- unsigned int fucop_exist = __nds32__mfsr(NDS32_SR_FUCOP_EXIST);
- unsigned int cpid = ((itype & ITYPE_mskCPID) >> ITYPE_offCPID);
-
- if ((cpid == FPU_CPID) &&
- (fucop_exist & FUCOP_EXIST_mskCP0ISFPU)) {
- unsigned int subtype = (itype & ITYPE_mskSTYPE);
-
- if (true == do_fpu_exception(subtype, regs))
- return;
- }
-#endif
- unhandled_exceptions(entry, addr, type, regs);
- } else if (type == ETYPE_TRAP && swid == SWID_RAISE_INTERRUPT_LEVEL) {
- /* trap, used on v3 EDM target debugging workaround */
- /*
- * DIPC(OIPC) is passed as parameter before
- * interrupt is enabled, so the DIPC will not be corrupted
- * even though interrupts are coming in
- */
- /*
- * 1. update ipc
- * 2. update pt_regs ipc with oipc
- * 3. update pt_regs ipsw (clear DEX)
- */
- __asm__ volatile ("mtsr %0, $IPC\n\t"::"r" (oipc));
- regs->ipc = oipc;
- if (regs->pipsw & PSW_mskDEX) {
- pr_emerg
- ("Nested Debug exception is possibly happened\n");
- pr_emerg("ipc:%08x pipc:%08x\n",
- (unsigned int)regs->ipc,
- (unsigned int)regs->pipc);
- }
- do_debug_trap(entry, addr, itype, regs);
- regs->ipsw &= ~PSW_mskDEX;
- } else
- unhandled_exceptions(entry, addr, type, regs);
-}
diff --git a/arch/nds32/kernel/vdso.c b/arch/nds32/kernel/vdso.c
deleted file mode 100644
index e16009a07971..000000000000
--- a/arch/nds32/kernel/vdso.c
+++ /dev/null
@@ -1,231 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-// Copyright (C) 2012 ARM Limited
-// Copyright (C) 2005-2017 Andes Technology Corporation
-
-#include <linux/cache.h>
-#include <linux/clocksource.h>
-#include <linux/elf.h>
-#include <linux/err.h>
-#include <linux/errno.h>
-#include <linux/gfp.h>
-#include <linux/kernel.h>
-#include <linux/mm.h>
-#include <linux/sched.h>
-#include <linux/signal.h>
-#include <linux/slab.h>
-#include <linux/timekeeper_internal.h>
-#include <linux/vmalloc.h>
-#include <linux/random.h>
-
-#include <asm/cacheflush.h>
-#include <asm/vdso.h>
-#include <asm/vdso_datapage.h>
-#include <asm/vdso_timer_info.h>
-#include <asm/cache_info.h>
-extern struct cache_info L1_cache_info[2];
-extern char vdso_start[], vdso_end[];
-static unsigned long vdso_pages __ro_after_init;
-static unsigned long timer_mapping_base;
-
-struct timer_info_t timer_info = {
- .cycle_count_down = true,
- .mapping_base = EMPTY_TIMER_MAPPING,
- .cycle_count_reg_offset = EMPTY_REG_OFFSET
-};
-/*
- * The vDSO data page.
- */
-static struct page *no_pages[] = { NULL };
-
-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 struct vm_special_mapping vdso_spec[2] __ro_after_init = {
- {
- .name = "[vvar]",
- .pages = no_pages,
- },
- {
- .name = "[vdso]",
- },
-};
-
-static void get_timer_node_info(void)
-{
- timer_mapping_base = timer_info.mapping_base;
- vdso_data->cycle_count_offset =
- timer_info.cycle_count_reg_offset;
- vdso_data->cycle_count_down =
- timer_info.cycle_count_down;
-}
-
-static int __init vdso_init(void)
-{
- int i;
- struct page **vdso_pagelist;
-
- if (memcmp(vdso_start, "\177ELF", 4)) {
- pr_err("vDSO is not a valid ELF object!\n");
- return -EINVAL;
- }
- /* Creat a timer io mapping to get clock cycles counter */
- get_timer_node_info();
-
- vdso_pages = (vdso_end - vdso_start) >> PAGE_SHIFT;
- pr_info("vdso: %ld pages (%ld code @ %p, %ld data @ %p)\n",
- vdso_pages + 1, vdso_pages, vdso_start, 1L, vdso_data);
-
- /* Allocate the vDSO pagelist */
- vdso_pagelist = kcalloc(vdso_pages, sizeof(struct page *), GFP_KERNEL);
- if (vdso_pagelist == NULL)
- return -ENOMEM;
-
- for (i = 0; i < vdso_pages; i++)
- vdso_pagelist[i] = virt_to_page(vdso_start + i * PAGE_SIZE);
- vdso_spec[1].pages = &vdso_pagelist[0];
-
- return 0;
-}
-
-arch_initcall(vdso_init);
-
-unsigned long inline vdso_random_addr(unsigned long vdso_mapping_len)
-{
- unsigned long start = current->mm->mmap_base, end, offset, addr;
- start = PAGE_ALIGN(start);
-
- /* Round the lowest possible end address up to a PMD boundary. */
- end = (start + vdso_mapping_len + PMD_SIZE - 1) & PMD_MASK;
- if (end >= TASK_SIZE)
- end = TASK_SIZE;
- end -= vdso_mapping_len;
-
- if (end > start) {
- offset = get_random_int() % (((end - start) >> PAGE_SHIFT) + 1);
- addr = start + (offset << PAGE_SHIFT);
- } else {
- addr = start;
- }
- return addr;
-}
-
-int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
-{
- struct mm_struct *mm = current->mm;
- unsigned long vdso_base, vdso_text_len, vdso_mapping_len;
- struct vm_area_struct *vma;
- unsigned long addr = 0;
- pgprot_t prot;
- int ret, vvar_page_num = 2;
-
- vdso_text_len = vdso_pages << PAGE_SHIFT;
-
- if(timer_mapping_base == EMPTY_VALUE)
- vvar_page_num = 1;
- /* Be sure to map the data page */
- vdso_mapping_len = vdso_text_len + vvar_page_num * PAGE_SIZE;
-#ifdef CONFIG_CPU_CACHE_ALIASING
- vdso_mapping_len += L1_cache_info[DCACHE].aliasing_num - 1;
-#endif
-
- if (mmap_write_lock_killable(mm))
- return -EINTR;
-
- addr = vdso_random_addr(vdso_mapping_len);
- vdso_base = get_unmapped_area(NULL, addr, vdso_mapping_len, 0, 0);
- if (IS_ERR_VALUE(vdso_base)) {
- ret = vdso_base;
- goto up_fail;
- }
-
-#ifdef CONFIG_CPU_CACHE_ALIASING
- {
- unsigned int aliasing_mask =
- L1_cache_info[DCACHE].aliasing_mask;
- unsigned int page_colour_ofs;
- page_colour_ofs = ((unsigned int)vdso_data & aliasing_mask) -
- (vdso_base & aliasing_mask);
- vdso_base += page_colour_ofs & aliasing_mask;
- }
-#endif
-
- vma = _install_special_mapping(mm, vdso_base, vvar_page_num * PAGE_SIZE,
- VM_READ | VM_MAYREAD, &vdso_spec[0]);
- if (IS_ERR(vma)) {
- ret = PTR_ERR(vma);
- goto up_fail;
- }
-
- /*Map vdata to user space */
- ret = io_remap_pfn_range(vma, vdso_base,
- virt_to_phys(vdso_data) >> PAGE_SHIFT,
- PAGE_SIZE, vma->vm_page_prot);
- if (ret)
- goto up_fail;
-
- /*Map timer to user space */
- vdso_base += PAGE_SIZE;
- prot = __pgprot(_PAGE_V | _PAGE_M_UR_KR | _PAGE_D | _PAGE_C_DEV);
- ret = io_remap_pfn_range(vma, vdso_base, timer_mapping_base >> PAGE_SHIFT,
- PAGE_SIZE, prot);
- if (ret)
- goto up_fail;
-
- /*Map vdso to user space */
- vdso_base += PAGE_SIZE;
- mm->context.vdso = (void *)vdso_base;
- vma = _install_special_mapping(mm, vdso_base, vdso_text_len,
- VM_READ | VM_EXEC |
- VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC,
- &vdso_spec[1]);
- if (IS_ERR(vma)) {
- ret = PTR_ERR(vma);
- goto up_fail;
- }
-
- mmap_write_unlock(mm);
- return 0;
-
-up_fail:
- mm->context.vdso = NULL;
- mmap_write_unlock(mm);
- return ret;
-}
-
-static void vdso_write_begin(struct vdso_data *vdata)
-{
- ++vdso_data->seq_count;
- smp_wmb(); /* Pairs with smp_rmb in vdso_read_retry */
-}
-
-static void vdso_write_end(struct vdso_data *vdata)
-{
- smp_wmb(); /* Pairs with smp_rmb in vdso_read_begin */
- ++vdso_data->seq_count;
-}
-
-void update_vsyscall(struct timekeeper *tk)
-{
- vdso_write_begin(vdso_data);
- vdso_data->cs_mask = tk->tkr_mono.mask;
- vdso_data->cs_mult = tk->tkr_mono.mult;
- vdso_data->cs_shift = tk->tkr_mono.shift;
- vdso_data->cs_cycle_last = tk->tkr_mono.cycle_last;
- vdso_data->wtm_clock_sec = tk->wall_to_monotonic.tv_sec;
- vdso_data->wtm_clock_nsec = tk->wall_to_monotonic.tv_nsec;
- vdso_data->xtime_clock_sec = tk->xtime_sec;
- vdso_data->xtime_clock_nsec = tk->tkr_mono.xtime_nsec;
- vdso_data->xtime_coarse_sec = tk->xtime_sec;
- vdso_data->xtime_coarse_nsec = tk->tkr_mono.xtime_nsec >>
- tk->tkr_mono.shift;
- vdso_data->hrtimer_res = hrtimer_resolution;
- vdso_write_end(vdso_data);
-}
-
-void update_vsyscall_tz(void)
-{
- vdso_data->tz_minuteswest = sys_tz.tz_minuteswest;
- vdso_data->tz_dsttime = sys_tz.tz_dsttime;
-}
diff --git a/arch/nds32/kernel/vdso/Makefile b/arch/nds32/kernel/vdso/Makefile
deleted file mode 100644
index 55df25ef0057..000000000000
--- a/arch/nds32/kernel/vdso/Makefile
+++ /dev/null
@@ -1,79 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0-only
-#
-# Building a vDSO image for AArch64.
-#
-# Author: Will Deacon <will.deacon@arm.com>
-# Heavily based on the vDSO Makefiles for other archs.
-#
-
-obj-vdso := note.o datapage.o sigreturn.o gettimeofday.o
-
-# Build rules
-targets := $(obj-vdso) vdso.so vdso.so.dbg
-obj-vdso := $(addprefix $(obj)/, $(obj-vdso))
-
-ccflags-y := -shared -fno-common -fno-builtin -nostdlib -fPIC -Wl,-shared -g \
- -Wl,-soname=linux-vdso.so.1 -Wl,--hash-style=sysv
-
-# Disable gcov profiling for VDSO code
-GCOV_PROFILE := n
-
-
-obj-y += vdso.o
-targets += vdso.lds
-CPPFLAGS_vdso.lds += -P -C -U$(ARCH)
-
-# Force dependency
-$(obj)/vdso.o : $(obj)/vdso.so
-
-# Link rule for the .so file, .lds has to be first
-$(obj)/vdso.so.dbg: $(obj)/vdso.lds $(obj-vdso) FORCE
- $(call if_changed,vdsold)
-
-
-# Strip rule for the .so file
-$(obj)/%.so: OBJCOPYFLAGS := -S
-$(obj)/%.so: $(obj)/%.so.dbg FORCE
- $(call if_changed,objcopy)
-
-# Generate VDSO offsets using helper script
-gen-vdsosym := $(srctree)/$(src)/gen_vdso_offsets.sh
-quiet_cmd_vdsosym = VDSOSYM $@
- cmd_vdsosym = $(NM) $< | $(gen-vdsosym) | LC_ALL=C sort > $@
-
-include/generated/vdso-offsets.h: $(obj)/vdso.so.dbg FORCE
- $(call if_changed,vdsosym)
-
-
-
-# Assembly rules for the .S files
-
-sigreturn.o : sigreturn.S
- $(call if_changed_dep,vdsoas)
-
-note.o : note.S
- $(call if_changed_dep,vdsoas)
-
-datapage.o : datapage.S
- $(call if_changed_dep,vdsoas)
-
-gettimeofday.o : gettimeofday.c FORCE
- $(call if_changed_dep,vdsocc)
-
-# Actual build commands
-quiet_cmd_vdsold = VDSOL $@
- cmd_vdsold = $(CC) $(c_flags) -Wl,-n -Wl,-T $(real-prereqs) -o $@
-quiet_cmd_vdsoas = VDSOA $@
- cmd_vdsoas = $(CC) $(a_flags) -c -o $@ $<
-quiet_cmd_vdsocc = VDSOA $@
- cmd_vdsocc = $(CC) $(c_flags) -c -o $@ $<
-
-# Install commands for the unstripped file
-quiet_cmd_vdso_install = INSTALL $@
- cmd_vdso_install = cp $(obj)/$@.dbg $(MODLIB)/vdso/$@
-
-vdso.so: $(obj)/vdso.so.dbg
- @mkdir -p $(MODLIB)/vdso
- $(call cmd,vdso_install)
-
-vdso_install: vdso.so
diff --git a/arch/nds32/kernel/vdso/datapage.S b/arch/nds32/kernel/vdso/datapage.S
deleted file mode 100644
index 4a62c3cab1c8..000000000000
--- a/arch/nds32/kernel/vdso/datapage.S
+++ /dev/null
@@ -1,21 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-// Copyright (C) 2005-2017 Andes Technology Corporation
-
-#include <linux/linkage.h>
-#include <asm/page.h>
-
-ENTRY(__get_timerpage)
- sethi $r0, hi20(. + PAGE_SIZE + 8)
- ori $r0, $r0, lo12(. + PAGE_SIZE + 4)
- mfusr $r1, $pc
- sub $r0, $r1, $r0
- ret
-ENDPROC(__get_timerpage)
-
-ENTRY(__get_datapage)
- sethi $r0, hi20(. + 2*PAGE_SIZE + 8)
- ori $r0, $r0, lo12(. + 2*PAGE_SIZE + 4)
- mfusr $r1, $pc
- sub $r0, $r1, $r0
- ret
-ENDPROC(__get_datapage)
diff --git a/arch/nds32/kernel/vdso/gettimeofday.c b/arch/nds32/kernel/vdso/gettimeofday.c
deleted file mode 100644
index 9ec03cf0ec54..000000000000
--- a/arch/nds32/kernel/vdso/gettimeofday.c
+++ /dev/null
@@ -1,269 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-// Copyright (C) 2005-2017 Andes Technology Corporation
-
-#include <linux/compiler.h>
-#include <linux/hrtimer.h>
-#include <linux/time.h>
-#include <asm/io.h>
-#include <asm/barrier.h>
-#include <asm/bug.h>
-#include <asm/page.h>
-#include <asm/unistd.h>
-#include <asm/vdso_datapage.h>
-#include <asm/vdso_timer_info.h>
-#include <asm/asm-offsets.h>
-
-#define X(x) #x
-#define Y(x) X(x)
-
-extern struct vdso_data *__get_datapage(void);
-extern struct vdso_data *__get_timerpage(void);
-
-static notrace unsigned int __vdso_read_begin(const struct vdso_data *vdata)
-{
- u32 seq;
-repeat:
- seq = READ_ONCE(vdata->seq_count);
- if (seq & 1) {
- cpu_relax();
- goto repeat;
- }
- return seq;
-}
-
-static notrace unsigned int vdso_read_begin(const struct vdso_data *vdata)
-{
- unsigned int seq;
-
- seq = __vdso_read_begin(vdata);
-
- smp_rmb(); /* Pairs with smp_wmb in vdso_write_end */
- return seq;
-}
-
-static notrace int vdso_read_retry(const struct vdso_data *vdata, u32 start)
-{
- smp_rmb(); /* Pairs with smp_wmb in vdso_write_begin */
- return vdata->seq_count != start;
-}
-
-static notrace long clock_gettime_fallback(clockid_t _clkid,
- struct __kernel_old_timespec *_ts)
-{
- register struct __kernel_old_timespec *ts asm("$r1") = _ts;
- register clockid_t clkid asm("$r0") = _clkid;
- register long ret asm("$r0");
-
- asm volatile ("movi $r15, %3\n"
- "syscall 0x0\n"
- :"=r" (ret)
- :"r"(clkid), "r"(ts), "i"(__NR_clock_gettime)
- :"$r15", "memory");
-
- return ret;
-}
-
-static notrace int do_realtime_coarse(struct __kernel_old_timespec *ts,
- struct vdso_data *vdata)
-{
- u32 seq;
-
- do {
- seq = vdso_read_begin(vdata);
-
- ts->tv_sec = vdata->xtime_coarse_sec;
- ts->tv_nsec = vdata->xtime_coarse_nsec;
-
- } while (vdso_read_retry(vdata, seq));
- return 0;
-}
-
-static notrace int do_monotonic_coarse(struct __kernel_old_timespec *ts,
- struct vdso_data *vdata)
-{
- u32 seq;
- u64 ns;
-
- do {
- seq = vdso_read_begin(vdata);
-
- ts->tv_sec = vdata->xtime_coarse_sec + vdata->wtm_clock_sec;
- ns = vdata->xtime_coarse_nsec + vdata->wtm_clock_nsec;
-
- } while (vdso_read_retry(vdata, seq));
-
- ts->tv_sec += __iter_div_u64_rem(ns, NSEC_PER_SEC, &ns);
- ts->tv_nsec = ns;
-
- return 0;
-}
-
-static notrace inline u64 vgetsns(struct vdso_data *vdso)
-{
- u32 cycle_now;
- u32 cycle_delta;
- u32 *timer_cycle_base;
-
- timer_cycle_base =
- (u32 *) ((char *)__get_timerpage() + vdso->cycle_count_offset);
- cycle_now = readl_relaxed(timer_cycle_base);
- if (true == vdso->cycle_count_down)
- cycle_now = ~(*timer_cycle_base);
- cycle_delta = cycle_now - (u32) vdso->cs_cycle_last;
- return ((u64) cycle_delta & vdso->cs_mask) * vdso->cs_mult;
-}
-
-static notrace int do_realtime(struct __kernel_old_timespec *ts, struct vdso_data *vdata)
-{
- unsigned count;
- u64 ns;
- do {
- count = vdso_read_begin(vdata);
- ts->tv_sec = vdata->xtime_clock_sec;
- ns = vdata->xtime_clock_nsec;
- ns += vgetsns(vdata);
- ns >>= vdata->cs_shift;
- } while (vdso_read_retry(vdata, count));
-
- ts->tv_sec += __iter_div_u64_rem(ns, NSEC_PER_SEC, &ns);
- ts->tv_nsec = ns;
-
- return 0;
-}
-
-static notrace int do_monotonic(struct __kernel_old_timespec *ts, struct vdso_data *vdata)
-{
- u64 ns;
- u32 seq;
-
- do {
- seq = vdso_read_begin(vdata);
-
- ts->tv_sec = vdata->xtime_clock_sec;
- ns = vdata->xtime_clock_nsec;
- ns += vgetsns(vdata);
- ns >>= vdata->cs_shift;
-
- ts->tv_sec += vdata->wtm_clock_sec;
- ns += vdata->wtm_clock_nsec;
-
- } while (vdso_read_retry(vdata, seq));
-
- ts->tv_sec += __iter_div_u64_rem(ns, NSEC_PER_SEC, &ns);
- ts->tv_nsec = ns;
-
- return 0;
-}
-
-notrace int __vdso_clock_gettime(clockid_t clkid, struct __kernel_old_timespec *ts)
-{
- struct vdso_data *vdata;
- int ret = -1;
-
- vdata = __get_datapage();
- if (vdata->cycle_count_offset == EMPTY_REG_OFFSET)
- return clock_gettime_fallback(clkid, ts);
-
- switch (clkid) {
- case CLOCK_REALTIME_COARSE:
- ret = do_realtime_coarse(ts, vdata);
- break;
- case CLOCK_MONOTONIC_COARSE:
- ret = do_monotonic_coarse(ts, vdata);
- break;
- case CLOCK_REALTIME:
- ret = do_realtime(ts, vdata);
- break;
- case CLOCK_MONOTONIC:
- ret = do_monotonic(ts, vdata);
- break;
- default:
- break;
- }
-
- if (ret)
- ret = clock_gettime_fallback(clkid, ts);
-
- return ret;
-}
-
-static notrace int clock_getres_fallback(clockid_t _clk_id,
- struct __kernel_old_timespec *_res)
-{
- register clockid_t clk_id asm("$r0") = _clk_id;
- register struct __kernel_old_timespec *res asm("$r1") = _res;
- register int ret asm("$r0");
-
- asm volatile ("movi $r15, %3\n"
- "syscall 0x0\n"
- :"=r" (ret)
- :"r"(clk_id), "r"(res), "i"(__NR_clock_getres)
- :"$r15", "memory");
-
- return ret;
-}
-
-notrace int __vdso_clock_getres(clockid_t clk_id, struct __kernel_old_timespec *res)
-{
- struct vdso_data *vdata = __get_datapage();
-
- if (res == NULL)
- return 0;
- switch (clk_id) {
- case CLOCK_REALTIME:
- case CLOCK_MONOTONIC:
- case CLOCK_MONOTONIC_RAW:
- res->tv_sec = 0;
- res->tv_nsec = vdata->hrtimer_res;
- break;
- case CLOCK_REALTIME_COARSE:
- case CLOCK_MONOTONIC_COARSE:
- res->tv_sec = 0;
- res->tv_nsec = CLOCK_COARSE_RES;
- break;
- default:
- return clock_getres_fallback(clk_id, res);
- }
- return 0;
-}
-
-static notrace inline int gettimeofday_fallback(struct __kernel_old_timeval *_tv,
- struct timezone *_tz)
-{
- register struct __kernel_old_timeval *tv asm("$r0") = _tv;
- register struct timezone *tz asm("$r1") = _tz;
- register int ret asm("$r0");
-
- asm volatile ("movi $r15, %3\n"
- "syscall 0x0\n"
- :"=r" (ret)
- :"r"(tv), "r"(tz), "i"(__NR_gettimeofday)
- :"$r15", "memory");
-
- return ret;
-}
-
-notrace int __vdso_gettimeofday(struct __kernel_old_timeval *tv, struct timezone *tz)
-{
- struct __kernel_old_timespec ts;
- struct vdso_data *vdata;
- int ret;
-
- vdata = __get_datapage();
-
- if (vdata->cycle_count_offset == EMPTY_REG_OFFSET)
- return gettimeofday_fallback(tv, tz);
-
- ret = do_realtime(&ts, vdata);
-
- if (tv) {
- tv->tv_sec = ts.tv_sec;
- tv->tv_usec = ts.tv_nsec / 1000;
- }
- if (tz) {
- tz->tz_minuteswest = vdata->tz_minuteswest;
- tz->tz_dsttime = vdata->tz_dsttime;
- }
-
- return ret;
-}
diff --git a/arch/nds32/kernel/vdso/note.S b/arch/nds32/kernel/vdso/note.S
deleted file mode 100644
index 0aeaa19b05f0..000000000000
--- a/arch/nds32/kernel/vdso/note.S
+++ /dev/null
@@ -1,11 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-// Copyright (C) 2012 ARM Limited
-// Copyright (C) 2005-2017 Andes Technology Corporation
-
-#include <linux/uts.h>
-#include <linux/version.h>
-#include <linux/elfnote.h>
-
-ELFNOTE_START(Linux, 0, "a")
- .long LINUX_VERSION_CODE
-ELFNOTE_END
diff --git a/arch/nds32/kernel/vdso/sigreturn.S b/arch/nds32/kernel/vdso/sigreturn.S
deleted file mode 100644
index 67e4d1d1612a..000000000000
--- a/arch/nds32/kernel/vdso/sigreturn.S
+++ /dev/null
@@ -1,19 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-// Copyright (C) 2012 ARM Limited
-// Copyright (C) 2005-2017 Andes Technology Corporation
-
-#include <linux/linkage.h>
-#include <asm/unistd.h>
-
- .text
-
-ENTRY(__kernel_rt_sigreturn)
- .cfi_startproc
- movi $r15, __NR_rt_sigreturn
- /*
- * The SWID of syscall should be __NR_rt_sigreturn to synchronize
- * the unwinding scheme in gcc
- */
- syscall __NR_rt_sigreturn
- .cfi_endproc
-ENDPROC(__kernel_rt_sigreturn)
diff --git a/arch/nds32/kernel/vdso/vdso.S b/arch/nds32/kernel/vdso/vdso.S
deleted file mode 100644
index 16737c11e55b..000000000000
--- a/arch/nds32/kernel/vdso/vdso.S
+++ /dev/null
@@ -1,18 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-// Copyright (C) 2012 ARM Limited
-// Copyright (C) 2005-2017 Andes Technology Corporation
-
-#include <linux/init.h>
-#include <linux/linkage.h>
-#include <linux/const.h>
-#include <asm/page.h>
-
- .globl vdso_start, vdso_end
- .section .rodata
- .balign PAGE_SIZE
-vdso_start:
- .incbin "arch/nds32/kernel/vdso/vdso.so"
- .balign PAGE_SIZE
-vdso_end:
-
- .previous
diff --git a/arch/nds32/kernel/vdso/vdso.lds.S b/arch/nds32/kernel/vdso/vdso.lds.S
deleted file mode 100644
index 1f2b16004594..000000000000
--- a/arch/nds32/kernel/vdso/vdso.lds.S
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * SPDX-License-Identifier: GPL-2.0
- * Copyright (C) 2005-2017 Andes Technology Corporation
- */
-
-
-#include <linux/const.h>
-#include <asm/page.h>
-#include <asm/vdso.h>
-
-OUTPUT_ARCH(nds32)
-
-SECTIONS
-{
- . = SIZEOF_HEADERS;
-
- .hash : { *(.hash) } :text
- .gnu.hash : { *(.gnu.hash) }
- .dynsym : { *(.dynsym) }
- .dynstr : { *(.dynstr) }
- .gnu.version : { *(.gnu.version) }
- .gnu.version_d : { *(.gnu.version_d) }
- .gnu.version_r : { *(.gnu.version_r) }
-
- .note : { *(.note.*) } :text :note
-
-
- .text : { *(.text*) } :text
-
- .eh_frame_hdr : { *(.eh_frame_hdr) } :text :eh_frame_hdr
- .eh_frame : { KEEP (*(.eh_frame)) } :text
-
- .dynamic : { *(.dynamic) } :text :dynamic
-
- .rodata : { *(.rodata*) } :text
-
-
- /DISCARD/ : {
- *(.note.GNU-stack)
- *(.data .data.* .gnu.linkonce.d.* .sdata*)
- *(.bss .sbss .dynbss .dynsbss)
- }
-}
-
-/*
- * We must supply the ELF program headers explicitly to get just one
- * PT_LOAD segment, and set the flags explicitly to make segments read-only.
- */
-PHDRS
-{
- text PT_LOAD FLAGS(5) FILEHDR PHDRS; /* PF_R|PF_X */
- dynamic PT_DYNAMIC FLAGS(4); /* PF_R */
- note PT_NOTE FLAGS(4); /* PF_R */
- eh_frame_hdr PT_GNU_EH_FRAME;
-}
-
-/*
- * This controls what symbols we export from the DSO.
- */
-VERSION
-{
- LINUX_4 {
- global:
- __kernel_rt_sigreturn;
- __vdso_gettimeofday;
- __vdso_clock_getres;
- __vdso_clock_gettime;
- local: *;
- };
-}
-
-/*
- * Make the rt_sigreturn code visible to the kernel.
- */
-VDSO_rt_sigtramp = __kernel_rt_sigreturn;
diff --git a/arch/nds32/kernel/vmlinux.lds.S b/arch/nds32/kernel/vmlinux.lds.S
deleted file mode 100644
index 6a91b965fb1e..000000000000
--- a/arch/nds32/kernel/vmlinux.lds.S
+++ /dev/null
@@ -1,70 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-// Copyright (C) 2005-2017 Andes Technology Corporation
-
-#include <asm/page.h>
-#include <asm/thread_info.h>
-#include <asm/cache.h>
-#include <asm/memory.h>
-
-#define LOAD_OFFSET (PAGE_OFFSET - PHYS_OFFSET)
-#include <asm-generic/vmlinux.lds.h>
-
-OUTPUT_ARCH(nds32)
-ENTRY(_stext_lma)
-jiffies = jiffies_64;
-
-#if defined(CONFIG_GCOV_KERNEL)
-#define NDS32_EXIT_KEEP(x) x
-#else
-#define NDS32_EXIT_KEEP(x)
-#endif
-
-SECTIONS
-{
- _stext_lma = TEXTADDR - LOAD_OFFSET;
- . = TEXTADDR;
- __init_begin = .;
- HEAD_TEXT_SECTION
- .exit.text : {
- NDS32_EXIT_KEEP(EXIT_TEXT)
- }
- INIT_TEXT_SECTION(PAGE_SIZE)
- INIT_DATA_SECTION(16)
- .exit.data : {
- NDS32_EXIT_KEEP(EXIT_DATA)
- }
- PERCPU_SECTION(L1_CACHE_BYTES)
- __init_end = .;
-
- . = ALIGN(PAGE_SIZE);
- _stext = .;
- /* Real text segment */
- .text : AT(ADDR(.text) - LOAD_OFFSET) {
- _text = .; /* Text and read-only data */
- TEXT_TEXT
- SCHED_TEXT
- CPUIDLE_TEXT
- LOCK_TEXT
- KPROBES_TEXT
- IRQENTRY_TEXT
- SOFTIRQENTRY_TEXT
- *(.fixup)
- }
-
- _etext = .; /* End of text and rodata section */
-
- _sdata = .;
- RO_DATA(PAGE_SIZE)
- RW_DATA(L1_CACHE_BYTES, PAGE_SIZE, THREAD_SIZE)
- _edata = .;
-
- EXCEPTION_TABLE(16)
- BSS_SECTION(4, 4, 4)
- _end = .;
-
- STABS_DEBUG
- DWARF_DEBUG
- ELF_DETAILS
-
- DISCARDS
-}
diff --git a/arch/nds32/lib/Makefile b/arch/nds32/lib/Makefile
deleted file mode 100644
index dddbc15d6b37..000000000000
--- a/arch/nds32/lib/Makefile
+++ /dev/null
@@ -1,4 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0-only
-lib-y := copy_page.o memcpy.o memmove.o \
- memset.o memzero.o \
- copy_from_user.o copy_to_user.o clear_user.o
diff --git a/arch/nds32/lib/clear_user.S b/arch/nds32/lib/clear_user.S
deleted file mode 100644
index 805dfcd25bf8..000000000000
--- a/arch/nds32/lib/clear_user.S
+++ /dev/null
@@ -1,42 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-// Copyright (C) 2005-2017 Andes Technology Corporation
-
-#include <linux/linkage.h>
-#include <asm/assembler.h>
-#include <asm/errno.h>
-
-/* Prototype: int __arch_clear_user(void *addr, size_t sz)
- * Purpose : clear some user memory
- * Params : addr - user memory address to clear
- * : sz - number of bytes to clear
- * Returns : number of bytes NOT cleared
- */
- .text
- .align 5
-ENTRY(__arch_clear_user)
- add $r5, $r0, $r1
- beqz $r1, clear_exit
- xor $p1, $p1, $p1 ! Use $p1=0 to clear mem
- srli $p0, $r1, #2 ! $p0 = number of word to clear
- andi $r1, $r1, #3 ! Bytes less than a word to copy
- beqz $p0, byte_clear ! Only less than a word to clear
-word_clear:
-USER( smw.bim,$p1, [$r0], $p1) ! Clear the word
- addi $p0, $p0, #-1 ! Decrease word count
- bnez $p0, word_clear ! Continue looping to clear all words
- beqz $r1, clear_exit ! No left bytes to copy
-byte_clear:
-USER( sbi.bi, $p1, [$r0], #1) ! Clear the byte
- addi $r1, $r1, #-1 ! Decrease byte count
- bnez $r1, byte_clear ! Continue looping to clear all left bytes
-clear_exit:
- move $r0, $r1 ! Set return value
- ret
-
- .section .fixup,"ax"
- .align 0
-9001:
- sub $r0, $r5, $r0 ! Bytes left to copy
- ret
- .previous
-ENDPROC(__arch_clear_user)
diff --git a/arch/nds32/lib/copy_from_user.S b/arch/nds32/lib/copy_from_user.S
deleted file mode 100644
index ad1857b20067..000000000000
--- a/arch/nds32/lib/copy_from_user.S
+++ /dev/null
@@ -1,45 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-// Copyright (C) 2005-2017 Andes Technology Corporation
-
-#include <linux/linkage.h>
-#include <asm/assembler.h>
-#include <asm/errno.h>
-
-.macro lbi1 dst, addr, adj
-USER( lbi.bi, \dst, [\addr], \adj)
-.endm
-
-.macro sbi1 src, addr, adj
-sbi.bi \src, [\addr], \adj
-.endm
-
-.macro lmw1 start_reg, addr, end_reg
-USER( lmw.bim, \start_reg, [\addr], \end_reg)
-.endm
-
-.macro smw1 start_reg, addr, end_reg
-smw.bim \start_reg, [\addr], \end_reg
-.endm
-
-
-/* Prototype: int __arch_copy_from_user(void *to, const char *from, size_t n)
- * Purpose : copy a block from user memory to kernel memory
- * Params : to - kernel memory
- * : from - user memory
- * : n - number of bytes to copy
- * Returns : Number of bytes NOT copied.
- */
-
-.text
-ENTRY(__arch_copy_from_user)
- add $r5, $r0, $r2
-#include "copy_template.S"
- move $r0, $r2
- ret
-.section .fixup,"ax"
-.align 2
-9001:
- sub $r0, $r5, $r0
- ret
-.previous
-ENDPROC(__arch_copy_from_user)
diff --git a/arch/nds32/lib/copy_page.S b/arch/nds32/lib/copy_page.S
deleted file mode 100644
index f8701ed161a8..000000000000
--- a/arch/nds32/lib/copy_page.S
+++ /dev/null
@@ -1,40 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-// Copyright (C) 2005-2017 Andes Technology Corporation
-
-#include <linux/linkage.h>
-#include <asm/export.h>
-#include <asm/page.h>
-
- .text
-ENTRY(copy_page)
- pushm $r2, $r10
- movi $r2, PAGE_SIZE >> 5
-.Lcopy_loop:
- lmw.bim $r3, [$r1], $r10
- smw.bim $r3, [$r0], $r10
- subi45 $r2, #1
- bnez38 $r2, .Lcopy_loop
- popm $r2, $r10
- ret
-ENDPROC(copy_page)
-EXPORT_SYMBOL(copy_page)
-
-ENTRY(clear_page)
- pushm $r1, $r9
- movi $r1, PAGE_SIZE >> 5
- movi55 $r2, #0
- movi55 $r3, #0
- movi55 $r4, #0
- movi55 $r5, #0
- movi55 $r6, #0
- movi55 $r7, #0
- movi55 $r8, #0
- movi55 $r9, #0
-.Lclear_loop:
- smw.bim $r2, [$r0], $r9
- subi45 $r1, #1
- bnez38 $r1, .Lclear_loop
- popm $r1, $r9
- ret
-ENDPROC(clear_page)
-EXPORT_SYMBOL(clear_page)
diff --git a/arch/nds32/lib/copy_template.S b/arch/nds32/lib/copy_template.S
deleted file mode 100644
index 3a9a2de468c2..000000000000
--- a/arch/nds32/lib/copy_template.S
+++ /dev/null
@@ -1,69 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-// Copyright (C) 2005-2017 Andes Technology Corporation
-
-
- beq $r1, $r0, quit_memcpy
- beqz $r2, quit_memcpy
- srli $r3, $r2, #5 ! check if len < cache-line size 32
- beqz $r3, word_copy_entry
- andi $r4, $r0, #0x3 ! check byte-align
- beqz $r4, unalign_word_copy_entry
-
- addi $r4, $r4,#-4
- abs $r4, $r4 ! check how many un-align byte to copy
- sub $r2, $r2, $r4 ! update $R2
-
-unalign_byte_copy:
- lbi1 $r3, $r1, #1
- addi $r4, $r4, #-1
- sbi1 $r3, $r0, #1
- bnez $r4, unalign_byte_copy
- beqz $r2, quit_memcpy
-
-unalign_word_copy_entry:
- andi $r3, $r0, 0x1f ! check cache-line unaligncount
- beqz $r3, cache_copy
-
- addi $r3, $r3, #-32
- abs $r3, $r3
- sub $r2, $r2, $r3 ! update $R2
-
-unalign_word_copy:
- lmw1 $r4, $r1, $r4
- addi $r3, $r3, #-4
- smw1 $r4, $r0, $r4
- bnez $r3, unalign_word_copy
- beqz $r2, quit_memcpy
-
- addi $r3, $r2, #-32 ! to check $r2< cache_line , than go to word_copy
- bltz $r3, word_copy_entry
-cache_copy:
- srli $r3, $r2, #5
- beqz $r3, word_copy_entry
-3:
- lmw1 $r17, $r1, $r24
- addi $r3, $r3, #-1
- smw1 $r17, $r0, $r24
- bnez $r3, 3b
-
-word_copy_entry:
- andi $r2, $r2, #31
-
- beqz $r2, quit_memcpy
-5:
- srli $r3, $r2, #2
- beqz $r3, byte_copy
-word_copy:
- lmw1 $r4, $r1, $r4
- addi $r3, $r3, #-1
- smw1 $r4, $r0, $r4
- bnez $r3, word_copy
- andi $r2, $r2, #3
- beqz $r2, quit_memcpy
-byte_copy:
- lbi1 $r3, $r1, #1
- addi $r2, $r2, #-1
-
- sbi1 $r3, $r0, #1
- bnez $r2, byte_copy
-quit_memcpy:
diff --git a/arch/nds32/lib/copy_to_user.S b/arch/nds32/lib/copy_to_user.S
deleted file mode 100644
index 3230044dcfb8..000000000000
--- a/arch/nds32/lib/copy_to_user.S
+++ /dev/null
@@ -1,45 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-// Copyright (C) 2005-2017 Andes Technology Corporation
-
-#include <linux/linkage.h>
-#include <asm/assembler.h>
-#include <asm/errno.h>
-
-.macro lbi1 dst, addr, adj
-lbi.bi \dst, [\addr], \adj
-.endm
-
-.macro sbi1 src, addr, adj
-USER( sbi.bi, \src, [\addr], \adj)
-.endm
-
-.macro lmw1 start_reg, addr, end_reg
-lmw.bim \start_reg, [\addr], \end_reg
-.endm
-
-.macro smw1 start_reg, addr, end_reg
-USER( smw.bim, \start_reg, [\addr], \end_reg)
-.endm
-
-
-/* Prototype: int __arch_copy_to_user(void *to, const char *from, size_t n)
- * Purpose : copy a block to user memory from kernel memory
- * Params : to - user memory
- * : from - kernel memory
- * : n - number of bytes to copy
- * Returns : Number of bytes NOT copied.
- */
-
-.text
-ENTRY(__arch_copy_to_user)
- add $r5, $r0, $r2
-#include "copy_template.S"
- move $r0, $r2
- ret
-.section .fixup,"ax"
-.align 2
-9001:
- sub $r0, $r5, $r0
- ret
-.previous
-ENDPROC(__arch_copy_to_user)
diff --git a/arch/nds32/lib/memcpy.S b/arch/nds32/lib/memcpy.S
deleted file mode 100644
index a2345ea721e4..000000000000
--- a/arch/nds32/lib/memcpy.S
+++ /dev/null
@@ -1,30 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-// Copyright (C) 2005-2017 Andes Technology Corporation
-
-#include <linux/linkage.h>
-
-
-.macro lbi1 dst, addr, adj
-lbi.bi \dst, [\addr], \adj
-.endm
-
-.macro sbi1 src, addr, adj
-sbi.bi \src, [\addr], \adj
-.endm
-
-.macro lmw1 start_reg, addr, end_reg
-lmw.bim \start_reg, [\addr], \end_reg
-.endm
-
-.macro smw1 start_reg, addr, end_reg
-smw.bim \start_reg, [\addr], \end_reg
-.endm
-
-.text
-ENTRY(memcpy)
- move $r5, $r0
-#include "copy_template.S"
- move $r0, $r5
- ret
-
-ENDPROC(memcpy)
diff --git a/arch/nds32/lib/memmove.S b/arch/nds32/lib/memmove.S
deleted file mode 100644
index c823aada2271..000000000000
--- a/arch/nds32/lib/memmove.S
+++ /dev/null
@@ -1,70 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-// Copyright (C) 2005-2017 Andes Technology Corporation
-
-#include <linux/linkage.h>
-
-/*
- void *memmove(void *dst, const void *src, int n);
-
- dst: $r0
- src: $r1
- n : $r2
- ret: $r0 - pointer to the memory area dst.
-*/
- .text
-
-ENTRY(memmove)
- move $r5, $r0 ! Set return value = det
- beq $r0, $r1, exit_memcpy ! Exit when det = src
- beqz $r2, exit_memcpy ! Exit when n = 0
- pushm $t0, $t1 ! Save reg
- srli $p1, $r2, #2 ! $p1 is how many words to copy
-
- ! Avoid data lost when memory overlap
- ! Copy data reversely when src < dst
- slt $p0, $r0, $r1 ! check if $r0 < $r1
- beqz $p0, do_reverse ! branch if dst > src
-
- ! No reverse, dst < src
- andi $r2, $r2, #3 ! How many bytes are less than a word
- li $t0, #1 ! Determining copy direction in byte_cpy
- beqz $p1, byte_cpy ! When n is less than a word
-
-word_cpy:
- lmw.bim $p0, [$r1], $p0 ! Read a word from src
- addi $p1, $p1, #-1 ! How many words left to copy
- smw.bim $p0, [$r0], $p0 ! Copy the word to det
- bnez $p1, word_cpy ! If remained words > 0
- beqz $r2, end_memcpy ! No left bytes to copy
- b byte_cpy
-
-do_reverse:
- add $r0, $r0, $r2 ! Start with the end of $r0
- add $r1, $r1, $r2 ! Start with the end of $r1
- andi $r2, $r2, #3 ! How many bytes are less than a word
- li $t0, #-1 ! Determining copy direction in byte_cpy
- beqz $p1, reverse_byte_cpy ! When n is less than a word
-
-reverse_word_cpy:
- lmw.adm $p0, [$r1], $p0 ! Read a word from src
- addi $p1, $p1, #-1 ! How many words left to copy
- smw.adm $p0, [$r0], $p0 ! Copy the word to det
- bnez $p1, reverse_word_cpy ! If remained words > 0
- beqz $r2, end_memcpy ! No left bytes to copy
-
-reverse_byte_cpy:
- addi $r0, $r0, #-1
- addi $r1, $r1, #-1
-byte_cpy: ! Less than 4 bytes to copy now
- lb.bi $p0, [$r1], $t0 ! Read a byte from src
- addi $r2, $r2, #-1 ! How many bytes left to copy
- sb.bi $p0, [$r0], $t0 ! copy the byte to det
- bnez $r2, byte_cpy ! If remained bytes > 0
-
-end_memcpy:
- popm $t0, $t1
-exit_memcpy:
- move $r0, $r5
- ret
-
-ENDPROC(memmove)
diff --git a/arch/nds32/lib/memset.S b/arch/nds32/lib/memset.S
deleted file mode 100644
index 193cb6ce21a9..000000000000
--- a/arch/nds32/lib/memset.S
+++ /dev/null
@@ -1,33 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-// Copyright (C) 2005-2017 Andes Technology Corporation
-
-#include <linux/linkage.h>
-
- .text
-ENTRY(memset)
- move $r5, $r0 ! Return value
- beqz $r2, end_memset ! Exit when len = 0
- srli $p1, $r2, 2 ! $p1 is how many words to copy
- andi $r2, $r2, 3 ! How many bytes are less than a word
- beqz $p1, byte_set ! When n is less than a word
-
- ! set $r1 from ??????ab to abababab
- andi $r1, $r1, #0x00ff ! $r1 = 000000ab
- slli $p0, $r1, #8 ! $p0 = 0000ab00
- or $r1, $r1, $p0 ! $r1 = 0000abab
- slli $p0, $r1, #16 ! $p0 = abab0000
- or $r1, $r1, $p0 ! $r1 = abababab
-word_set:
- addi $p1, $p1, #-1 ! How many words left to copy
- smw.bim $r1, [$r0], $r1 ! Copy the word to det
- bnez $p1, word_set ! Still words to set, continue looping
- beqz $r2, end_memset ! No left byte to set
-byte_set: ! Less than 4 bytes left to set
- addi $r2, $r2, #-1 ! Decrease len by 1
- sbi.bi $r1, [$r0], #1 ! Set data of the next byte to $r1
- bnez $r2, byte_set ! Still bytes left to set
-end_memset:
- move $r0, $r5
- ret
-
-ENDPROC(memset)
diff --git a/arch/nds32/lib/memzero.S b/arch/nds32/lib/memzero.S
deleted file mode 100644
index f055972c9343..000000000000
--- a/arch/nds32/lib/memzero.S
+++ /dev/null
@@ -1,18 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-// Copyright (C) 2005-2017 Andes Technology Corporation
-
-#include <linux/linkage.h>
-
- .text
-ENTRY(memzero)
- beqz $r1, 1f
- push $lp
- move $r2, $r1
- move $r1, #0
- push $r0
- bal memset
- pop $r0
- pop $lp
-1:
- ret
-ENDPROC(memzero)
diff --git a/arch/nds32/math-emu/Makefile b/arch/nds32/math-emu/Makefile
deleted file mode 100644
index 3bed7e5d5d05..000000000000
--- a/arch/nds32/math-emu/Makefile
+++ /dev/null
@@ -1,10 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0-only
-#
-# Makefile for the Linux/nds32 kernel FPU emulation.
-#
-
-obj-y := fpuemu.o \
- fdivd.o fmuld.o fsubd.o faddd.o fs2d.o fsqrtd.o fcmpd.o fnegs.o \
- fd2si.o fd2ui.o fd2siz.o fd2uiz.o fsi2d.o fui2d.o \
- fdivs.o fmuls.o fsubs.o fadds.o fd2s.o fsqrts.o fcmps.o fnegd.o \
- fs2si.o fs2ui.o fs2siz.o fs2uiz.o fsi2s.o fui2s.o
diff --git a/arch/nds32/math-emu/faddd.c b/arch/nds32/math-emu/faddd.c
deleted file mode 100644
index f7fd4e3c3904..000000000000
--- a/arch/nds32/math-emu/faddd.c
+++ /dev/null
@@ -1,24 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-// Copyright (C) 2005-2018 Andes Technology Corporation
-#include <linux/uaccess.h>
-
-#include <asm/sfp-machine.h>
-#include <math-emu/soft-fp.h>
-#include <math-emu/double.h>
-void faddd(void *ft, void *fa, void *fb)
-{
- FP_DECL_D(A);
- FP_DECL_D(B);
- FP_DECL_D(R);
- FP_DECL_EX;
-
- FP_UNPACK_DP(A, fa);
- FP_UNPACK_DP(B, fb);
-
- FP_ADD_D(R, A, B);
-
- FP_PACK_DP(ft, R);
-
- __FPU_FPCSR |= FP_CUR_EXCEPTIONS;
-
-}
diff --git a/arch/nds32/math-emu/fadds.c b/arch/nds32/math-emu/fadds.c
deleted file mode 100644
index f5af6ca8cca5..000000000000
--- a/arch/nds32/math-emu/fadds.c
+++ /dev/null
@@ -1,24 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-// Copyright (C) 2005-2018 Andes Technology Corporation
-#include <linux/uaccess.h>
-
-#include <asm/sfp-machine.h>
-#include <math-emu/soft-fp.h>
-#include <math-emu/single.h>
-void fadds(void *ft, void *fa, void *fb)
-{
- FP_DECL_S(A);
- FP_DECL_S(B);
- FP_DECL_S(R);
- FP_DECL_EX;
-
- FP_UNPACK_SP(A, fa);
- FP_UNPACK_SP(B, fb);
-
- FP_ADD_S(R, A, B);
-
- FP_PACK_SP(ft, R);
-
- __FPU_FPCSR |= FP_CUR_EXCEPTIONS;
-
-}
diff --git a/arch/nds32/math-emu/fcmpd.c b/arch/nds32/math-emu/fcmpd.c
deleted file mode 100644
index 0ea225abe880..000000000000
--- a/arch/nds32/math-emu/fcmpd.c
+++ /dev/null
@@ -1,24 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-// Copyright (C) 2005-2018 Andes Technology Corporation
-#include <asm/sfp-machine.h>
-#include <math-emu/soft-fp.h>
-#include <math-emu/double.h>
-int fcmpd(void *ft, void *fa, void *fb, int cmpop)
-{
- FP_DECL_D(A);
- FP_DECL_D(B);
- FP_DECL_EX;
- long cmp;
-
- FP_UNPACK_DP(A, fa);
- FP_UNPACK_DP(B, fb);
-
- FP_CMP_D(cmp, A, B, SF_CUN);
- cmp += 2;
- if (cmp == SF_CGT)
- *(long *)ft = 0;
- else
- *(long *)ft = (cmp & cmpop) ? 1 : 0;
-
- return 0;
-}
diff --git a/arch/nds32/math-emu/fcmps.c b/arch/nds32/math-emu/fcmps.c
deleted file mode 100644
index 681480758213..000000000000
--- a/arch/nds32/math-emu/fcmps.c
+++ /dev/null
@@ -1,24 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-// Copyright (C) 2005-2018 Andes Technology Corporation
-#include <asm/sfp-machine.h>
-#include <math-emu/soft-fp.h>
-#include <math-emu/single.h>
-int fcmps(void *ft, void *fa, void *fb, int cmpop)
-{
- FP_DECL_S(A);
- FP_DECL_S(B);
- FP_DECL_EX;
- long cmp;
-
- FP_UNPACK_SP(A, fa);
- FP_UNPACK_SP(B, fb);
-
- FP_CMP_S(cmp, A, B, SF_CUN);
- cmp += 2;
- if (cmp == SF_CGT)
- *(int *)ft = 0x0;
- else
- *(int *)ft = (cmp & cmpop) ? 0x1 : 0x0;
-
- return 0;
-}
diff --git a/arch/nds32/math-emu/fd2s.c b/arch/nds32/math-emu/fd2s.c
deleted file mode 100644
index 1328371e8170..000000000000
--- a/arch/nds32/math-emu/fd2s.c
+++ /dev/null
@@ -1,22 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-// Copyright (C) 2005-2018 Andes Technology Corporation
-#include <linux/uaccess.h>
-
-#include <asm/sfp-machine.h>
-#include <math-emu/double.h>
-#include <math-emu/single.h>
-#include <math-emu/soft-fp.h>
-void fd2s(void *ft, void *fa)
-{
- FP_DECL_D(A);
- FP_DECL_S(R);
- FP_DECL_EX;
-
- FP_UNPACK_DP(A, fa);
-
- FP_CONV(S, D, 1, 2, R, A);
-
- FP_PACK_SP(ft, R);
-
- __FPU_FPCSR |= FP_CUR_EXCEPTIONS;
-}
diff --git a/arch/nds32/math-emu/fd2si.c b/arch/nds32/math-emu/fd2si.c
deleted file mode 100644
index fae3e16a0a10..000000000000
--- a/arch/nds32/math-emu/fd2si.c
+++ /dev/null
@@ -1,30 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-// Copyright (C) 2005-2019 Andes Technology Corporation
-#include <linux/uaccess.h>
-
-#include <asm/sfp-machine.h>
-#include <math-emu/soft-fp.h>
-#include <math-emu/double.h>
-
-void fd2si(void *ft, void *fa)
-{
- int r;
-
- FP_DECL_D(A);
- FP_DECL_EX;
-
- FP_UNPACK_DP(A, fa);
-
- if (A_c == FP_CLS_INF) {
- *(int *)ft = (A_s == 0) ? 0x7fffffff : 0x80000000;
- __FPU_FPCSR |= FP_EX_INVALID;
- } else if (A_c == FP_CLS_NAN) {
- *(int *)ft = 0xffffffff;
- __FPU_FPCSR |= FP_EX_INVALID;
- } else {
- FP_TO_INT_ROUND_D(r, A, 32, 1);
- __FPU_FPCSR |= FP_CUR_EXCEPTIONS;
- *(int *)ft = r;
- }
-
-}
diff --git a/arch/nds32/math-emu/fd2siz.c b/arch/nds32/math-emu/fd2siz.c
deleted file mode 100644
index 92fe6774f112..000000000000
--- a/arch/nds32/math-emu/fd2siz.c
+++ /dev/null
@@ -1,30 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-// Copyright (C) 2005-2019 Andes Technology Corporation
-#include <linux/uaccess.h>
-
-#include <asm/sfp-machine.h>
-#include <math-emu/soft-fp.h>
-#include <math-emu/double.h>
-
-void fd2si_z(void *ft, void *fa)
-{
- int r;
-
- FP_DECL_D(A);
- FP_DECL_EX;
-
- FP_UNPACK_DP(A, fa);
-
- if (A_c == FP_CLS_INF) {
- *(int *)ft = (A_s == 0) ? 0x7fffffff : 0x80000000;
- __FPU_FPCSR |= FP_EX_INVALID;
- } else if (A_c == FP_CLS_NAN) {
- *(int *)ft = 0xffffffff;
- __FPU_FPCSR |= FP_EX_INVALID;
- } else {
- FP_TO_INT_D(r, A, 32, 1);
- __FPU_FPCSR |= FP_CUR_EXCEPTIONS;
- *(int *)ft = r;
- }
-
-}
diff --git a/arch/nds32/math-emu/fd2ui.c b/arch/nds32/math-emu/fd2ui.c
deleted file mode 100644
index a0423b699aa4..000000000000
--- a/arch/nds32/math-emu/fd2ui.c
+++ /dev/null
@@ -1,30 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-// Copyright (C) 2005-2019 Andes Technology Corporation
-#include <linux/uaccess.h>
-
-#include <asm/sfp-machine.h>
-#include <math-emu/soft-fp.h>
-#include <math-emu/double.h>
-
-void fd2ui(void *ft, void *fa)
-{
- unsigned int r;
-
- FP_DECL_D(A);
- FP_DECL_EX;
-
- FP_UNPACK_DP(A, fa);
-
- if (A_c == FP_CLS_INF) {
- *(unsigned int *)ft = (A_s == 0) ? 0xffffffff : 0x00000000;
- __FPU_FPCSR |= FP_EX_INVALID;
- } else if (A_c == FP_CLS_NAN) {
- *(unsigned int *)ft = 0xffffffff;
- __FPU_FPCSR |= FP_EX_INVALID;
- } else {
- FP_TO_INT_ROUND_D(r, A, 32, 0);
- __FPU_FPCSR |= FP_CUR_EXCEPTIONS;
- *(unsigned int *)ft = r;
- }
-
-}
diff --git a/arch/nds32/math-emu/fd2uiz.c b/arch/nds32/math-emu/fd2uiz.c
deleted file mode 100644
index 8ae17cfce90d..000000000000
--- a/arch/nds32/math-emu/fd2uiz.c
+++ /dev/null
@@ -1,30 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-// Copyright (C) 2005-2019 Andes Technology Corporation
-#include <linux/uaccess.h>
-
-#include <asm/sfp-machine.h>
-#include <math-emu/soft-fp.h>
-#include <math-emu/double.h>
-
-void fd2ui_z(void *ft, void *fa)
-{
- unsigned int r;
-
- FP_DECL_D(A);
- FP_DECL_EX;
-
- FP_UNPACK_DP(A, fa);
-
- if (A_c == FP_CLS_INF) {
- *(unsigned int *)ft = (A_s == 0) ? 0xffffffff : 0x00000000;
- __FPU_FPCSR |= FP_EX_INVALID;
- } else if (A_c == FP_CLS_NAN) {
- *(unsigned int *)ft = 0xffffffff;
- __FPU_FPCSR |= FP_EX_INVALID;
- } else {
- FP_TO_INT_D(r, A, 32, 0);
- __FPU_FPCSR |= FP_CUR_EXCEPTIONS;
- *(unsigned int *)ft = r;
- }
-
-}
diff --git a/arch/nds32/math-emu/fdivd.c b/arch/nds32/math-emu/fdivd.c
deleted file mode 100644
index 458e7e98b08e..000000000000
--- a/arch/nds32/math-emu/fdivd.c
+++ /dev/null
@@ -1,27 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-// Copyright (C) 2005-2018 Andes Technology Corporation
-
-#include <linux/uaccess.h>
-#include <asm/sfp-machine.h>
-#include <math-emu/soft-fp.h>
-#include <math-emu/double.h>
-
-void fdivd(void *ft, void *fa, void *fb)
-{
- FP_DECL_D(A);
- FP_DECL_D(B);
- FP_DECL_D(R);
- FP_DECL_EX;
-
- FP_UNPACK_DP(A, fa);
- FP_UNPACK_DP(B, fb);
-
- if (B_c == FP_CLS_ZERO && A_c != FP_CLS_ZERO)
- FP_SET_EXCEPTION(FP_EX_DIVZERO);
-
- FP_DIV_D(R, A, B);
-
- FP_PACK_DP(ft, R);
-
- __FPU_FPCSR |= FP_CUR_EXCEPTIONS;
-}
diff --git a/arch/nds32/math-emu/fdivs.c b/arch/nds32/math-emu/fdivs.c
deleted file mode 100644
index c7d202159ce2..000000000000
--- a/arch/nds32/math-emu/fdivs.c
+++ /dev/null
@@ -1,26 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-// Copyright (C) 2005-2018 Andes Technology Corporation
-#include <linux/uaccess.h>
-
-#include <asm/sfp-machine.h>
-#include <math-emu/soft-fp.h>
-#include <math-emu/single.h>
-void fdivs(void *ft, void *fa, void *fb)
-{
- FP_DECL_S(A);
- FP_DECL_S(B);
- FP_DECL_S(R);
- FP_DECL_EX;
-
- FP_UNPACK_SP(A, fa);
- FP_UNPACK_SP(B, fb);
-
- if (B_c == FP_CLS_ZERO && A_c != FP_CLS_ZERO)
- FP_SET_EXCEPTION(FP_EX_DIVZERO);
-
- FP_DIV_S(R, A, B);
-
- FP_PACK_SP(ft, R);
-
- __FPU_FPCSR |= FP_CUR_EXCEPTIONS;
-}
diff --git a/arch/nds32/math-emu/fmuld.c b/arch/nds32/math-emu/fmuld.c
deleted file mode 100644
index f3c77a45ddc2..000000000000
--- a/arch/nds32/math-emu/fmuld.c
+++ /dev/null
@@ -1,23 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-// Copyright (C) 2005-2018 Andes Technology Corporation
-#include <linux/uaccess.h>
-
-#include <asm/sfp-machine.h>
-#include <math-emu/soft-fp.h>
-#include <math-emu/double.h>
-void fmuld(void *ft, void *fa, void *fb)
-{
- FP_DECL_D(A);
- FP_DECL_D(B);
- FP_DECL_D(R);
- FP_DECL_EX;
-
- FP_UNPACK_DP(A, fa);
- FP_UNPACK_DP(B, fb);
-
- FP_MUL_D(R, A, B);
-
- FP_PACK_DP(ft, R);
-
- __FPU_FPCSR |= FP_CUR_EXCEPTIONS;
-}
diff --git a/arch/nds32/math-emu/fmuls.c b/arch/nds32/math-emu/fmuls.c
deleted file mode 100644
index cf150df938f9..000000000000
--- a/arch/nds32/math-emu/fmuls.c
+++ /dev/null
@@ -1,23 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-// Copyright (C) 2005-2018 Andes Technology Corporation
-#include <linux/uaccess.h>
-
-#include <asm/sfp-machine.h>
-#include <math-emu/soft-fp.h>
-#include <math-emu/single.h>
-void fmuls(void *ft, void *fa, void *fb)
-{
- FP_DECL_S(A);
- FP_DECL_S(B);
- FP_DECL_S(R);
- FP_DECL_EX;
-
- FP_UNPACK_SP(A, fa);
- FP_UNPACK_SP(B, fb);
-
- FP_MUL_S(R, A, B);
-
- FP_PACK_SP(ft, R);
-
- __FPU_FPCSR |= FP_CUR_EXCEPTIONS;
-}
diff --git a/arch/nds32/math-emu/fnegd.c b/arch/nds32/math-emu/fnegd.c
deleted file mode 100644
index de7ea6a0873e..000000000000
--- a/arch/nds32/math-emu/fnegd.c
+++ /dev/null
@@ -1,21 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-// Copyright (C) 2005-2018 Andes Technology Corporation
-#include <linux/uaccess.h>
-
-#include <asm/sfp-machine.h>
-#include <math-emu/soft-fp.h>
-#include <math-emu/double.h>
-void fnegd(void *ft, void *fa)
-{
- FP_DECL_D(A);
- FP_DECL_D(R);
- FP_DECL_EX;
-
- FP_UNPACK_DP(A, fa);
-
- FP_NEG_D(R, A);
-
- FP_PACK_DP(ft, R);
-
- __FPU_FPCSR |= FP_CUR_EXCEPTIONS;
-}
diff --git a/arch/nds32/math-emu/fnegs.c b/arch/nds32/math-emu/fnegs.c
deleted file mode 100644
index 07270b326a77..000000000000
--- a/arch/nds32/math-emu/fnegs.c
+++ /dev/null
@@ -1,21 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-// Copyright (C) 2005-2018 Andes Technology Corporation
-#include <linux/uaccess.h>
-
-#include <asm/sfp-machine.h>
-#include <math-emu/soft-fp.h>
-#include <math-emu/single.h>
-void fnegs(void *ft, void *fa)
-{
- FP_DECL_S(A);
- FP_DECL_S(R);
- FP_DECL_EX;
-
- FP_UNPACK_SP(A, fa);
-
- FP_NEG_S(R, A);
-
- FP_PACK_SP(ft, R);
-
- __FPU_FPCSR |= FP_CUR_EXCEPTIONS;
-}
diff --git a/arch/nds32/math-emu/fpuemu.c b/arch/nds32/math-emu/fpuemu.c
deleted file mode 100644
index 46558a15c0dc..000000000000
--- a/arch/nds32/math-emu/fpuemu.c
+++ /dev/null
@@ -1,406 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-// Copyright (C) 2005-2018 Andes Technology Corporation
-
-#include <asm/bitfield.h>
-#include <asm/uaccess.h>
-#include <asm/sfp-machine.h>
-#include <asm/fpuemu.h>
-#include <asm/nds32_fpu_inst.h>
-
-#define DPFROMREG(dp, x) (dp = (void *)((unsigned long *)fpu_reg + 2*x))
-#ifdef __NDS32_EL__
-#define SPFROMREG(sp, x)\
- ((sp) = (void *)((unsigned long *)fpu_reg + (x^1)))
-#else
-#define SPFROMREG(sp, x) ((sp) = (void *)((unsigned long *)fpu_reg + x))
-#endif
-
-#define DEF3OP(name, p, f1, f2) \
-void fpemu_##name##p(void *ft, void *fa, void *fb) \
-{ \
- f1(fa, fa, fb); \
- f2(ft, ft, fa); \
-}
-
-#define DEF3OPNEG(name, p, f1, f2, f3) \
-void fpemu_##name##p(void *ft, void *fa, void *fb) \
-{ \
- f1(fa, fa, fb); \
- f2(ft, ft, fa); \
- f3(ft, ft); \
-}
-DEF3OP(fmadd, s, fmuls, fadds);
-DEF3OP(fmsub, s, fmuls, fsubs);
-DEF3OP(fmadd, d, fmuld, faddd);
-DEF3OP(fmsub, d, fmuld, fsubd);
-DEF3OPNEG(fnmadd, s, fmuls, fadds, fnegs);
-DEF3OPNEG(fnmsub, s, fmuls, fsubs, fnegs);
-DEF3OPNEG(fnmadd, d, fmuld, faddd, fnegd);
-DEF3OPNEG(fnmsub, d, fmuld, fsubd, fnegd);
-
-static const unsigned char cmptab[8] = {
- SF_CEQ,
- SF_CEQ,
- SF_CLT,
- SF_CLT,
- SF_CLT | SF_CEQ,
- SF_CLT | SF_CEQ,
- SF_CUN,
- SF_CUN
-};
-
-enum ARGTYPE {
- S1S = 1,
- S2S,
- S1D,
- CS,
- D1D,
- D2D,
- D1S,
- CD
-};
-union func_t {
- void (*t)(void *ft, void *fa, void *fb);
- void (*b)(void *ft, void *fa);
-};
-/*
- * Emulate a single FPU arithmetic instruction.
- */
-static int fpu_emu(struct fpu_struct *fpu_reg, unsigned long insn)
-{
- int rfmt; /* resulting format */
- union func_t func;
- int ftype = 0;
-
- switch (rfmt = NDS32Insn_OPCODE_COP0(insn)) {
- case fs1_op:{
- switch (NDS32Insn_OPCODE_BIT69(insn)) {
- case fadds_op:
- func.t = fadds;
- ftype = S2S;
- break;
- case fsubs_op:
- func.t = fsubs;
- ftype = S2S;
- break;
- case fmadds_op:
- func.t = fpemu_fmadds;
- ftype = S2S;
- break;
- case fmsubs_op:
- func.t = fpemu_fmsubs;
- ftype = S2S;
- break;
- case fnmadds_op:
- func.t = fpemu_fnmadds;
- ftype = S2S;
- break;
- case fnmsubs_op:
- func.t = fpemu_fnmsubs;
- ftype = S2S;
- break;
- case fmuls_op:
- func.t = fmuls;
- ftype = S2S;
- break;
- case fdivs_op:
- func.t = fdivs;
- ftype = S2S;
- break;
- case fs1_f2op_op:
- switch (NDS32Insn_OPCODE_BIT1014(insn)) {
- case fs2d_op:
- func.b = fs2d;
- ftype = S1D;
- break;
- case fs2si_op:
- func.b = fs2si;
- ftype = S1S;
- break;
- case fs2si_z_op:
- func.b = fs2si_z;
- ftype = S1S;
- break;
- case fs2ui_op:
- func.b = fs2ui;
- ftype = S1S;
- break;
- case fs2ui_z_op:
- func.b = fs2ui_z;
- ftype = S1S;
- break;
- case fsi2s_op:
- func.b = fsi2s;
- ftype = S1S;
- break;
- case fui2s_op:
- func.b = fui2s;
- ftype = S1S;
- break;
- case fsqrts_op:
- func.b = fsqrts;
- ftype = S1S;
- break;
- default:
- return SIGILL;
- }
- break;
- default:
- return SIGILL;
- }
- break;
- }
- case fs2_op:
- switch (NDS32Insn_OPCODE_BIT69(insn)) {
- case fcmpeqs_op:
- case fcmpeqs_e_op:
- case fcmplts_op:
- case fcmplts_e_op:
- case fcmples_op:
- case fcmples_e_op:
- case fcmpuns_op:
- case fcmpuns_e_op:
- ftype = CS;
- break;
- default:
- return SIGILL;
- }
- break;
- case fd1_op:{
- switch (NDS32Insn_OPCODE_BIT69(insn)) {
- case faddd_op:
- func.t = faddd;
- ftype = D2D;
- break;
- case fsubd_op:
- func.t = fsubd;
- ftype = D2D;
- break;
- case fmaddd_op:
- func.t = fpemu_fmaddd;
- ftype = D2D;
- break;
- case fmsubd_op:
- func.t = fpemu_fmsubd;
- ftype = D2D;
- break;
- case fnmaddd_op:
- func.t = fpemu_fnmaddd;
- ftype = D2D;
- break;
- case fnmsubd_op:
- func.t = fpemu_fnmsubd;
- ftype = D2D;
- break;
- case fmuld_op:
- func.t = fmuld;
- ftype = D2D;
- break;
- case fdivd_op:
- func.t = fdivd;
- ftype = D2D;
- break;
- case fd1_f2op_op:
- switch (NDS32Insn_OPCODE_BIT1014(insn)) {
- case fd2s_op:
- func.b = fd2s;
- ftype = D1S;
- break;
- case fd2si_op:
- func.b = fd2si;
- ftype = D1S;
- break;
- case fd2si_z_op:
- func.b = fd2si_z;
- ftype = D1S;
- break;
- case fd2ui_op:
- func.b = fd2ui;
- ftype = D1S;
- break;
- case fd2ui_z_op:
- func.b = fd2ui_z;
- ftype = D1S;
- break;
- case fsi2d_op:
- func.b = fsi2d;
- ftype = D1S;
- break;
- case fui2d_op:
- func.b = fui2d;
- ftype = D1S;
- break;
- case fsqrtd_op:
- func.b = fsqrtd;
- ftype = D1D;
- break;
- default:
- return SIGILL;
- }
- break;
- default:
- return SIGILL;
-
- }
- break;
- }
-
- case fd2_op:
- switch (NDS32Insn_OPCODE_BIT69(insn)) {
- case fcmpeqd_op:
- case fcmpeqd_e_op:
- case fcmpltd_op:
- case fcmpltd_e_op:
- case fcmpled_op:
- case fcmpled_e_op:
- case fcmpund_op:
- case fcmpund_e_op:
- ftype = CD;
- break;
- default:
- return SIGILL;
- }
- break;
-
- default:
- return SIGILL;
- }
-
- switch (ftype) {
- case S1S:{
- void *ft, *fa;
-
- SPFROMREG(ft, NDS32Insn_OPCODE_Rt(insn));
- SPFROMREG(fa, NDS32Insn_OPCODE_Ra(insn));
- func.b(ft, fa);
- break;
- }
- case S2S:{
- void *ft, *fa, *fb;
-
- SPFROMREG(ft, NDS32Insn_OPCODE_Rt(insn));
- SPFROMREG(fa, NDS32Insn_OPCODE_Ra(insn));
- SPFROMREG(fb, NDS32Insn_OPCODE_Rb(insn));
- func.t(ft, fa, fb);
- break;
- }
- case S1D:{
- void *ft, *fa;
-
- DPFROMREG(ft, NDS32Insn_OPCODE_Rt(insn));
- SPFROMREG(fa, NDS32Insn_OPCODE_Ra(insn));
- func.b(ft, fa);
- break;
- }
- case CS:{
- unsigned int cmpop = NDS32Insn_OPCODE_BIT69(insn);
- void *ft, *fa, *fb;
-
- SPFROMREG(ft, NDS32Insn_OPCODE_Rt(insn));
- SPFROMREG(fa, NDS32Insn_OPCODE_Ra(insn));
- SPFROMREG(fb, NDS32Insn_OPCODE_Rb(insn));
- if (cmpop < 0x8) {
- cmpop = cmptab[cmpop];
- fcmps(ft, fa, fb, cmpop);
- } else
- return SIGILL;
- break;
- }
- case D1D:{
- void *ft, *fa;
-
- DPFROMREG(ft, NDS32Insn_OPCODE_Rt(insn));
- DPFROMREG(fa, NDS32Insn_OPCODE_Ra(insn));
- func.b(ft, fa);
- break;
- }
- case D2D:{
- void *ft, *fa, *fb;
-
- DPFROMREG(ft, NDS32Insn_OPCODE_Rt(insn));
- DPFROMREG(fa, NDS32Insn_OPCODE_Ra(insn));
- DPFROMREG(fb, NDS32Insn_OPCODE_Rb(insn));
- func.t(ft, fa, fb);
- break;
- }
- case D1S:{
- void *ft, *fa;
-
- SPFROMREG(ft, NDS32Insn_OPCODE_Rt(insn));
- DPFROMREG(fa, NDS32Insn_OPCODE_Ra(insn));
- func.b(ft, fa);
- break;
- }
- case CD:{
- unsigned int cmpop = NDS32Insn_OPCODE_BIT69(insn);
- void *ft, *fa, *fb;
-
- SPFROMREG(ft, NDS32Insn_OPCODE_Rt(insn));
- DPFROMREG(fa, NDS32Insn_OPCODE_Ra(insn));
- DPFROMREG(fb, NDS32Insn_OPCODE_Rb(insn));
- if (cmpop < 0x8) {
- cmpop = cmptab[cmpop];
- fcmpd(ft, fa, fb, cmpop);
- } else
- return SIGILL;
- break;
- }
- default:
- return SIGILL;
- }
-
- /*
- * If an exception is required, generate a tidy SIGFPE exception.
- */
-#if IS_ENABLED(CONFIG_SUPPORT_DENORMAL_ARITHMETIC)
- if (((fpu_reg->fpcsr << 5) & fpu_reg->fpcsr & FPCSR_mskALLE_NO_UDF_IEXE)
- || ((fpu_reg->fpcsr << 5) & (fpu_reg->UDF_IEX_trap))) {
-#else
- if ((fpu_reg->fpcsr << 5) & fpu_reg->fpcsr & FPCSR_mskALLE) {
-#endif
- return SIGFPE;
- }
- return 0;
-}
-
-int do_fpuemu(struct pt_regs *regs, struct fpu_struct *fpu)
-{
- unsigned long insn = 0, addr = regs->ipc;
- unsigned long emulpc, contpc;
- unsigned char *pc = (void *)&insn;
- char c;
- int i = 0, ret;
-
- for (i = 0; i < 4; i++) {
- if (__get_user(c, (unsigned char *)addr++))
- return SIGBUS;
- *pc++ = c;
- }
-
- insn = be32_to_cpu(insn);
-
- emulpc = regs->ipc;
- contpc = regs->ipc + 4;
-
- if (NDS32Insn_OPCODE(insn) != cop0_op)
- return SIGILL;
-
- switch (NDS32Insn_OPCODE_COP0(insn)) {
- case fs1_op:
- case fs2_op:
- case fd1_op:
- case fd2_op:
- {
- /* a real fpu computation instruction */
- ret = fpu_emu(fpu, insn);
- if (!ret)
- regs->ipc = contpc;
- }
- break;
-
- default:
- return SIGILL;
- }
-
- return ret;
-}
diff --git a/arch/nds32/math-emu/fs2d.c b/arch/nds32/math-emu/fs2d.c
deleted file mode 100644
index 0e8db9035631..000000000000
--- a/arch/nds32/math-emu/fs2d.c
+++ /dev/null
@@ -1,23 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-// Copyright (C) 2005-2018 Andes Technology Corporation
-
-#include <linux/uaccess.h>
-#include <asm/sfp-machine.h>
-#include <math-emu/double.h>
-#include <math-emu/single.h>
-#include <math-emu/soft-fp.h>
-
-void fs2d(void *ft, void *fa)
-{
- FP_DECL_S(A);
- FP_DECL_D(R);
- FP_DECL_EX;
-
- FP_UNPACK_SP(A, fa);
-
- FP_CONV(D, S, 2, 1, R, A);
-
- FP_PACK_DP(ft, R);
-
- __FPU_FPCSR |= FP_CUR_EXCEPTIONS;
-}
diff --git a/arch/nds32/math-emu/fs2si.c b/arch/nds32/math-emu/fs2si.c
deleted file mode 100644
index b4931d60980e..000000000000
--- a/arch/nds32/math-emu/fs2si.c
+++ /dev/null
@@ -1,29 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-// Copyright (C) 2005-2019 Andes Technology Corporation
-#include <linux/uaccess.h>
-
-#include <asm/sfp-machine.h>
-#include <math-emu/soft-fp.h>
-#include <math-emu/single.h>
-
-void fs2si(void *ft, void *fa)
-{
- int r;
-
- FP_DECL_S(A);
- FP_DECL_EX;
-
- FP_UNPACK_SP(A, fa);
-
- if (A_c == FP_CLS_INF) {
- *(int *)ft = (A_s == 0) ? 0x7fffffff : 0x80000000;
- __FPU_FPCSR |= FP_EX_INVALID;
- } else if (A_c == FP_CLS_NAN) {
- *(int *)ft = 0xffffffff;
- __FPU_FPCSR |= FP_EX_INVALID;
- } else {
- FP_TO_INT_ROUND_S(r, A, 32, 1);
- __FPU_FPCSR |= FP_CUR_EXCEPTIONS;
- *(int *)ft = r;
- }
-}
diff --git a/arch/nds32/math-emu/fs2siz.c b/arch/nds32/math-emu/fs2siz.c
deleted file mode 100644
index 1c2b99ce3e38..000000000000
--- a/arch/nds32/math-emu/fs2siz.c
+++ /dev/null
@@ -1,29 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-// Copyright (C) 2005-2019 Andes Technology Corporation
-#include <linux/uaccess.h>
-
-#include <asm/sfp-machine.h>
-#include <math-emu/soft-fp.h>
-#include <math-emu/single.h>
-
-void fs2si_z(void *ft, void *fa)
-{
- int r;
-
- FP_DECL_S(A);
- FP_DECL_EX;
-
- FP_UNPACK_SP(A, fa);
-
- if (A_c == FP_CLS_INF) {
- *(int *)ft = (A_s == 0) ? 0x7fffffff : 0x80000000;
- __FPU_FPCSR |= FP_EX_INVALID;
- } else if (A_c == FP_CLS_NAN) {
- *(int *)ft = 0xffffffff;
- __FPU_FPCSR |= FP_EX_INVALID;
- } else {
- FP_TO_INT_S(r, A, 32, 1);
- __FPU_FPCSR |= FP_CUR_EXCEPTIONS;
- *(int *)ft = r;
- }
-}
diff --git a/arch/nds32/math-emu/fs2ui.c b/arch/nds32/math-emu/fs2ui.c
deleted file mode 100644
index c337f0384d06..000000000000
--- a/arch/nds32/math-emu/fs2ui.c
+++ /dev/null
@@ -1,29 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-// Copyright (C) 2005-2019 Andes Technology Corporation
-#include <linux/uaccess.h>
-
-#include <asm/sfp-machine.h>
-#include <math-emu/soft-fp.h>
-#include <math-emu/single.h>
-
-void fs2ui(void *ft, void *fa)
-{
- unsigned int r;
-
- FP_DECL_S(A);
- FP_DECL_EX;
-
- FP_UNPACK_SP(A, fa);
-
- if (A_c == FP_CLS_INF) {
- *(unsigned int *)ft = (A_s == 0) ? 0xffffffff : 0x00000000;
- __FPU_FPCSR |= FP_EX_INVALID;
- } else if (A_c == FP_CLS_NAN) {
- *(unsigned int *)ft = 0xffffffff;
- __FPU_FPCSR |= FP_EX_INVALID;
- } else {
- FP_TO_INT_ROUND_S(r, A, 32, 0);
- __FPU_FPCSR |= FP_CUR_EXCEPTIONS;
- *(unsigned int *)ft = r;
- }
-}
diff --git a/arch/nds32/math-emu/fs2uiz.c b/arch/nds32/math-emu/fs2uiz.c
deleted file mode 100644
index 22c5e4768044..000000000000
--- a/arch/nds32/math-emu/fs2uiz.c
+++ /dev/null
@@ -1,30 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-// Copyright (C) 2005-2019 Andes Technology Corporation
-#include <linux/uaccess.h>
-
-#include <asm/sfp-machine.h>
-#include <math-emu/soft-fp.h>
-#include <math-emu/single.h>
-
-void fs2ui_z(void *ft, void *fa)
-{
- unsigned int r;
-
- FP_DECL_S(A);
- FP_DECL_EX;
-
- FP_UNPACK_SP(A, fa);
-
- if (A_c == FP_CLS_INF) {
- *(unsigned int *)ft = (A_s == 0) ? 0xffffffff : 0x00000000;
- __FPU_FPCSR |= FP_EX_INVALID;
- } else if (A_c == FP_CLS_NAN) {
- *(unsigned int *)ft = 0xffffffff;
- __FPU_FPCSR |= FP_EX_INVALID;
- } else {
- FP_TO_INT_S(r, A, 32, 0);
- __FPU_FPCSR |= FP_CUR_EXCEPTIONS;
- *(unsigned int *)ft = r;
- }
-
-}
diff --git a/arch/nds32/math-emu/fsi2d.c b/arch/nds32/math-emu/fsi2d.c
deleted file mode 100644
index 6b04cec0c5c5..000000000000
--- a/arch/nds32/math-emu/fsi2d.c
+++ /dev/null
@@ -1,22 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-// Copyright (C) 2005-2019 Andes Technology Corporation
-#include <linux/uaccess.h>
-
-#include <asm/sfp-machine.h>
-#include <math-emu/soft-fp.h>
-#include <math-emu/double.h>
-
-void fsi2d(void *ft, void *fa)
-{
- int a = *(int *)fa;
-
- FP_DECL_D(R);
- FP_DECL_EX;
-
- FP_FROM_INT_D(R, a, 32, int);
-
- FP_PACK_DP(ft, R);
-
- __FPU_FPCSR |= FP_CUR_EXCEPTIONS;
-
-}
diff --git a/arch/nds32/math-emu/fsi2s.c b/arch/nds32/math-emu/fsi2s.c
deleted file mode 100644
index 689864a5df90..000000000000
--- a/arch/nds32/math-emu/fsi2s.c
+++ /dev/null
@@ -1,22 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-// Copyright (C) 2005-2019 Andes Technology Corporation
-#include <linux/uaccess.h>
-
-#include <asm/sfp-machine.h>
-#include <math-emu/soft-fp.h>
-#include <math-emu/single.h>
-
-void fsi2s(void *ft, void *fa)
-{
- int a = *(int *)fa;
-
- FP_DECL_S(R);
- FP_DECL_EX;
-
- FP_FROM_INT_S(R, a, 32, int);
-
- FP_PACK_SP(ft, R);
-
- __FPU_FPCSR |= FP_CUR_EXCEPTIONS;
-
-}
diff --git a/arch/nds32/math-emu/fsqrtd.c b/arch/nds32/math-emu/fsqrtd.c
deleted file mode 100644
index c3a8dbd81d4e..000000000000
--- a/arch/nds32/math-emu/fsqrtd.c
+++ /dev/null
@@ -1,21 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-// Copyright (C) 2005-2018 Andes Technology Corporation
-
-#include <linux/uaccess.h>
-#include <asm/sfp-machine.h>
-#include <math-emu/soft-fp.h>
-#include <math-emu/double.h>
-void fsqrtd(void *ft, void *fa)
-{
- FP_DECL_D(A);
- FP_DECL_D(R);
- FP_DECL_EX;
-
- FP_UNPACK_DP(A, fa);
-
- FP_SQRT_D(R, A);
-
- FP_PACK_DP(ft, R);
-
- __FPU_FPCSR |= FP_CUR_EXCEPTIONS;
-}
diff --git a/arch/nds32/math-emu/fsqrts.c b/arch/nds32/math-emu/fsqrts.c
deleted file mode 100644
index 4c6f94b27328..000000000000
--- a/arch/nds32/math-emu/fsqrts.c
+++ /dev/null
@@ -1,21 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-// Copyright (C) 2005-2018 Andes Technology Corporation
-
-#include <linux/uaccess.h>
-#include <asm/sfp-machine.h>
-#include <math-emu/soft-fp.h>
-#include <math-emu/single.h>
-void fsqrts(void *ft, void *fa)
-{
- FP_DECL_S(A);
- FP_DECL_S(R);
- FP_DECL_EX;
-
- FP_UNPACK_SP(A, fa);
-
- FP_SQRT_S(R, A);
-
- FP_PACK_SP(ft, R);
-
- __FPU_FPCSR |= FP_CUR_EXCEPTIONS;
-}
diff --git a/arch/nds32/math-emu/fsubd.c b/arch/nds32/math-emu/fsubd.c
deleted file mode 100644
index 81b6a0d02a1f..000000000000
--- a/arch/nds32/math-emu/fsubd.c
+++ /dev/null
@@ -1,27 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-// Copyright (C) 2005-2018 Andes Technology Corporation
-#include <linux/uaccess.h>
-
-#include <asm/sfp-machine.h>
-#include <math-emu/soft-fp.h>
-#include <math-emu/double.h>
-void fsubd(void *ft, void *fa, void *fb)
-{
-
- FP_DECL_D(A);
- FP_DECL_D(B);
- FP_DECL_D(R);
- FP_DECL_EX;
-
- FP_UNPACK_DP(A, fa);
- FP_UNPACK_DP(B, fb);
-
- if (B_c != FP_CLS_NAN)
- B_s ^= 1;
-
- FP_ADD_D(R, A, B);
-
- FP_PACK_DP(ft, R);
-
- __FPU_FPCSR |= FP_CUR_EXCEPTIONS;
-}
diff --git a/arch/nds32/math-emu/fsubs.c b/arch/nds32/math-emu/fsubs.c
deleted file mode 100644
index 61ddd9708465..000000000000
--- a/arch/nds32/math-emu/fsubs.c
+++ /dev/null
@@ -1,27 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-// Copyright (C) 2005-2018 Andes Technology Corporation
-#include <linux/uaccess.h>
-
-#include <asm/sfp-machine.h>
-#include <math-emu/soft-fp.h>
-#include <math-emu/single.h>
-void fsubs(void *ft, void *fa, void *fb)
-{
-
- FP_DECL_S(A);
- FP_DECL_S(B);
- FP_DECL_S(R);
- FP_DECL_EX;
-
- FP_UNPACK_SP(A, fa);
- FP_UNPACK_SP(B, fb);
-
- if (B_c != FP_CLS_NAN)
- B_s ^= 1;
-
- FP_ADD_S(R, A, B);
-
- FP_PACK_SP(ft, R);
-
- __FPU_FPCSR |= FP_CUR_EXCEPTIONS;
-}
diff --git a/arch/nds32/math-emu/fui2d.c b/arch/nds32/math-emu/fui2d.c
deleted file mode 100644
index 9689d33a8d50..000000000000
--- a/arch/nds32/math-emu/fui2d.c
+++ /dev/null
@@ -1,22 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-// Copyright (C) 2005-2019 Andes Technology Corporation
-#include <linux/uaccess.h>
-
-#include <asm/sfp-machine.h>
-#include <math-emu/soft-fp.h>
-#include <math-emu/double.h>
-
-void fui2d(void *ft, void *fa)
-{
- unsigned int a = *(unsigned int *)fa;
-
- FP_DECL_D(R);
- FP_DECL_EX;
-
- FP_FROM_INT_D(R, a, 32, int);
-
- FP_PACK_DP(ft, R);
-
- __FPU_FPCSR |= FP_CUR_EXCEPTIONS;
-
-}
diff --git a/arch/nds32/math-emu/fui2s.c b/arch/nds32/math-emu/fui2s.c
deleted file mode 100644
index f70f0762547d..000000000000
--- a/arch/nds32/math-emu/fui2s.c
+++ /dev/null
@@ -1,22 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-// Copyright (C) 2005-2019 Andes Technology Corporation
-#include <linux/uaccess.h>
-
-#include <asm/sfp-machine.h>
-#include <math-emu/soft-fp.h>
-#include <math-emu/single.h>
-
-void fui2s(void *ft, void *fa)
-{
- unsigned int a = *(unsigned int *)fa;
-
- FP_DECL_S(R);
- FP_DECL_EX;
-
- FP_FROM_INT_S(R, a, 32, int);
-
- FP_PACK_SP(ft, R);
-
- __FPU_FPCSR |= FP_CUR_EXCEPTIONS;
-
-}
diff --git a/arch/nds32/mm/Makefile b/arch/nds32/mm/Makefile
deleted file mode 100644
index 14fb2e8eb036..000000000000
--- a/arch/nds32/mm/Makefile
+++ /dev/null
@@ -1,10 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0-only
-obj-y := extable.o tlb.o fault.o init.o mmap.o \
- mm-nds32.o cacheflush.o proc.o
-
-obj-$(CONFIG_ALIGNMENT_TRAP) += alignment.o
-
-ifdef CONFIG_FUNCTION_TRACER
-CFLAGS_REMOVE_proc.o = $(CC_FLAGS_FTRACE)
-endif
-CFLAGS_proc.o += -fomit-frame-pointer
diff --git a/arch/nds32/mm/alignment.c b/arch/nds32/mm/alignment.c
deleted file mode 100644
index 1eb7ded6992b..000000000000
--- a/arch/nds32/mm/alignment.c
+++ /dev/null
@@ -1,578 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-// Copyright (C) 2005-2017 Andes Technology Corporation
-
-#include <linux/proc_fs.h>
-#include <linux/uaccess.h>
-#include <linux/sysctl.h>
-#include <asm/unaligned.h>
-
-#define DEBUG(enable, tagged, ...) \
- do{ \
- if (enable) { \
- if (tagged) \
- pr_warn("[ %30s() ] ", __func__); \
- pr_warn(__VA_ARGS__); \
- } \
- } while (0)
-
-#define RT(inst) (((inst) >> 20) & 0x1FUL)
-#define RA(inst) (((inst) >> 15) & 0x1FUL)
-#define RB(inst) (((inst) >> 10) & 0x1FUL)
-#define SV(inst) (((inst) >> 8) & 0x3UL)
-#define IMM(inst) (((inst) >> 0) & 0x7FFFUL)
-
-#define RA3(inst) (((inst) >> 3) & 0x7UL)
-#define RT3(inst) (((inst) >> 6) & 0x7UL)
-#define IMM3U(inst) (((inst) >> 0) & 0x7UL)
-
-#define RA5(inst) (((inst) >> 0) & 0x1FUL)
-#define RT4(inst) (((inst) >> 5) & 0xFUL)
-
-#define GET_IMMSVAL(imm_value) \
- (((imm_value >> 14) & 0x1) ? (imm_value - 0x8000) : imm_value)
-
-#define __get8_data(val,addr,err) \
- __asm__( \
- "1: lbi.bi %1, [%2], #1\n" \
- "2:\n" \
- " .pushsection .text.fixup,\"ax\"\n" \
- " .align 2\n" \
- "3: movi %0, #1\n" \
- " j 2b\n" \
- " .popsection\n" \
- " .pushsection __ex_table,\"a\"\n" \
- " .align 3\n" \
- " .long 1b, 3b\n" \
- " .popsection\n" \
- : "=r" (err), "=&r" (val), "=r" (addr) \
- : "0" (err), "2" (addr))
-
-#define get16_data(addr, val_ptr) \
- do { \
- unsigned int err = 0, v, a = addr; \
- __get8_data(v,a,err); \
- *val_ptr = v << 0; \
- __get8_data(v,a,err); \
- *val_ptr |= v << 8; \
- if (err) \
- goto fault; \
- *val_ptr = le16_to_cpu(*val_ptr); \
- } while(0)
-
-#define get32_data(addr, val_ptr) \
- do { \
- unsigned int err = 0, v, a = addr; \
- __get8_data(v,a,err); \
- *val_ptr = v << 0; \
- __get8_data(v,a,err); \
- *val_ptr |= v << 8; \
- __get8_data(v,a,err); \
- *val_ptr |= v << 16; \
- __get8_data(v,a,err); \
- *val_ptr |= v << 24; \
- if (err) \
- goto fault; \
- *val_ptr = le32_to_cpu(*val_ptr); \
- } while(0)
-
-#define get_data(addr, val_ptr, len) \
- if (len == 2) \
- get16_data(addr, val_ptr); \
- else \
- get32_data(addr, val_ptr);
-
-#define set16_data(addr, val) \
- do { \
- unsigned int err = 0, *ptr = addr ; \
- val = le32_to_cpu(val); \
- __asm__( \
- "1: sbi.bi %2, [%1], #1\n" \
- " srli %2, %2, #8\n" \
- "2: sbi %2, [%1]\n" \
- "3:\n" \
- " .pushsection .text.fixup,\"ax\"\n" \
- " .align 2\n" \
- "4: movi %0, #1\n" \
- " j 3b\n" \
- " .popsection\n" \
- " .pushsection __ex_table,\"a\"\n" \
- " .align 3\n" \
- " .long 1b, 4b\n" \
- " .long 2b, 4b\n" \
- " .popsection\n" \
- : "=r" (err), "+r" (ptr), "+r" (val) \
- : "0" (err) \
- ); \
- if (err) \
- goto fault; \
- } while(0)
-
-#define set32_data(addr, val) \
- do { \
- unsigned int err = 0, *ptr = addr ; \
- val = le32_to_cpu(val); \
- __asm__( \
- "1: sbi.bi %2, [%1], #1\n" \
- " srli %2, %2, #8\n" \
- "2: sbi.bi %2, [%1], #1\n" \
- " srli %2, %2, #8\n" \
- "3: sbi.bi %2, [%1], #1\n" \
- " srli %2, %2, #8\n" \
- "4: sbi %2, [%1]\n" \
- "5:\n" \
- " .pushsection .text.fixup,\"ax\"\n" \
- " .align 2\n" \
- "6: movi %0, #1\n" \
- " j 5b\n" \
- " .popsection\n" \
- " .pushsection __ex_table,\"a\"\n" \
- " .align 3\n" \
- " .long 1b, 6b\n" \
- " .long 2b, 6b\n" \
- " .long 3b, 6b\n" \
- " .long 4b, 6b\n" \
- " .popsection\n" \
- : "=r" (err), "+r" (ptr), "+r" (val) \
- : "0" (err) \
- ); \
- if (err) \
- goto fault; \
- } while(0)
-#define set_data(addr, val, len) \
- if (len == 2) \
- set16_data(addr, val); \
- else \
- set32_data(addr, val);
-#define NDS32_16BIT_INSTRUCTION 0x80000000
-
-extern pte_t va_present(struct mm_struct *mm, unsigned long addr);
-extern pte_t va_kernel_present(unsigned long addr);
-extern int va_readable(struct pt_regs *regs, unsigned long addr);
-extern int va_writable(struct pt_regs *regs, unsigned long addr);
-
-int unalign_access_mode = 0, unalign_access_debug = 0;
-
-static inline unsigned long *idx_to_addr(struct pt_regs *regs, int idx)
-{
- /* this should be consistent with ptrace.h */
- if (idx >= 0 && idx <= 25) /* R0-R25 */
- return &regs->uregs[0] + idx;
- else if (idx >= 28 && idx <= 30) /* FP, GP, LP */
- return &regs->fp + (idx - 28);
- else if (idx == 31) /* SP */
- return &regs->sp;
- else
- return NULL; /* cause a segfault */
-}
-
-static inline unsigned long get_inst(unsigned long addr)
-{
- return be32_to_cpu(get_unaligned((u32 *) addr));
-}
-
-static inline unsigned long sign_extend(unsigned long val, int len)
-{
- unsigned long ret = 0;
- unsigned char *s, *t;
- int i = 0;
-
- val = cpu_to_le32(val);
-
- s = (void *)&val;
- t = (void *)&ret;
-
- while (i++ < len)
- *t++ = *s++;
-
- if (((*(t - 1)) & 0x80) && (i < 4)) {
-
- while (i++ <= 4)
- *t++ = 0xff;
- }
-
- return le32_to_cpu(ret);
-}
-
-static inline int do_16(unsigned long inst, struct pt_regs *regs)
-{
- int imm, regular, load, len, addr_mode, idx_mode;
- unsigned long unaligned_addr, target_val, source_idx, target_idx,
- shift = 0;
- switch ((inst >> 9) & 0x3F) {
-
- case 0x12: /* LHI333 */
- imm = 1;
- regular = 1;
- load = 1;
- len = 2;
- addr_mode = 3;
- idx_mode = 3;
- break;
- case 0x10: /* LWI333 */
- imm = 1;
- regular = 1;
- load = 1;
- len = 4;
- addr_mode = 3;
- idx_mode = 3;
- break;
- case 0x11: /* LWI333.bi */
- imm = 1;
- regular = 0;
- load = 1;
- len = 4;
- addr_mode = 3;
- idx_mode = 3;
- break;
- case 0x1A: /* LWI450 */
- imm = 0;
- regular = 1;
- load = 1;
- len = 4;
- addr_mode = 5;
- idx_mode = 4;
- break;
- case 0x16: /* SHI333 */
- imm = 1;
- regular = 1;
- load = 0;
- len = 2;
- addr_mode = 3;
- idx_mode = 3;
- break;
- case 0x14: /* SWI333 */
- imm = 1;
- regular = 1;
- load = 0;
- len = 4;
- addr_mode = 3;
- idx_mode = 3;
- break;
- case 0x15: /* SWI333.bi */
- imm = 1;
- regular = 0;
- load = 0;
- len = 4;
- addr_mode = 3;
- idx_mode = 3;
- break;
- case 0x1B: /* SWI450 */
- imm = 0;
- regular = 1;
- load = 0;
- len = 4;
- addr_mode = 5;
- idx_mode = 4;
- break;
-
- default:
- return -EFAULT;
- }
-
- if (addr_mode == 3) {
- unaligned_addr = *idx_to_addr(regs, RA3(inst));
- source_idx = RA3(inst);
- } else {
- unaligned_addr = *idx_to_addr(regs, RA5(inst));
- source_idx = RA5(inst);
- }
-
- if (idx_mode == 3)
- target_idx = RT3(inst);
- else
- target_idx = RT4(inst);
-
- if (imm)
- shift = IMM3U(inst) * len;
-
- if (regular)
- unaligned_addr += shift;
-
- if (load) {
- if (!access_ok((void *)unaligned_addr, len))
- return -EACCES;
-
- get_data(unaligned_addr, &target_val, len);
- *idx_to_addr(regs, target_idx) = target_val;
- } else {
- if (!access_ok((void *)unaligned_addr, len))
- return -EACCES;
- target_val = *idx_to_addr(regs, target_idx);
- set_data((void *)unaligned_addr, target_val, len);
- }
-
- if (!regular)
- *idx_to_addr(regs, source_idx) = unaligned_addr + shift;
- regs->ipc += 2;
-
- return 0;
-fault:
- return -EACCES;
-}
-
-static inline int do_32(unsigned long inst, struct pt_regs *regs)
-{
- int imm, regular, load, len, sign_ext;
- unsigned long unaligned_addr, target_val, shift;
-
- unaligned_addr = *idx_to_addr(regs, RA(inst));
-
- switch ((inst >> 25) << 1) {
-
- case 0x02: /* LHI */
- imm = 1;
- regular = 1;
- load = 1;
- len = 2;
- sign_ext = 0;
- break;
- case 0x0A: /* LHI.bi */
- imm = 1;
- regular = 0;
- load = 1;
- len = 2;
- sign_ext = 0;
- break;
- case 0x22: /* LHSI */
- imm = 1;
- regular = 1;
- load = 1;
- len = 2;
- sign_ext = 1;
- break;
- case 0x2A: /* LHSI.bi */
- imm = 1;
- regular = 0;
- load = 1;
- len = 2;
- sign_ext = 1;
- break;
- case 0x04: /* LWI */
- imm = 1;
- regular = 1;
- load = 1;
- len = 4;
- sign_ext = 0;
- break;
- case 0x0C: /* LWI.bi */
- imm = 1;
- regular = 0;
- load = 1;
- len = 4;
- sign_ext = 0;
- break;
- case 0x12: /* SHI */
- imm = 1;
- regular = 1;
- load = 0;
- len = 2;
- sign_ext = 0;
- break;
- case 0x1A: /* SHI.bi */
- imm = 1;
- regular = 0;
- load = 0;
- len = 2;
- sign_ext = 0;
- break;
- case 0x14: /* SWI */
- imm = 1;
- regular = 1;
- load = 0;
- len = 4;
- sign_ext = 0;
- break;
- case 0x1C: /* SWI.bi */
- imm = 1;
- regular = 0;
- load = 0;
- len = 4;
- sign_ext = 0;
- break;
-
- default:
- switch (inst & 0xff) {
-
- case 0x01: /* LH */
- imm = 0;
- regular = 1;
- load = 1;
- len = 2;
- sign_ext = 0;
- break;
- case 0x05: /* LH.bi */
- imm = 0;
- regular = 0;
- load = 1;
- len = 2;
- sign_ext = 0;
- break;
- case 0x11: /* LHS */
- imm = 0;
- regular = 1;
- load = 1;
- len = 2;
- sign_ext = 1;
- break;
- case 0x15: /* LHS.bi */
- imm = 0;
- regular = 0;
- load = 1;
- len = 2;
- sign_ext = 1;
- break;
- case 0x02: /* LW */
- imm = 0;
- regular = 1;
- load = 1;
- len = 4;
- sign_ext = 0;
- break;
- case 0x06: /* LW.bi */
- imm = 0;
- regular = 0;
- load = 1;
- len = 4;
- sign_ext = 0;
- break;
- case 0x09: /* SH */
- imm = 0;
- regular = 1;
- load = 0;
- len = 2;
- sign_ext = 0;
- break;
- case 0x0D: /* SH.bi */
- imm = 0;
- regular = 0;
- load = 0;
- len = 2;
- sign_ext = 0;
- break;
- case 0x0A: /* SW */
- imm = 0;
- regular = 1;
- load = 0;
- len = 4;
- sign_ext = 0;
- break;
- case 0x0E: /* SW.bi */
- imm = 0;
- regular = 0;
- load = 0;
- len = 4;
- sign_ext = 0;
- break;
-
- default:
- return -EFAULT;
- }
- }
-
- if (imm)
- shift = GET_IMMSVAL(IMM(inst)) * len;
- else
- shift = *idx_to_addr(regs, RB(inst)) << SV(inst);
-
- if (regular)
- unaligned_addr += shift;
-
- if (load) {
-
- if (!access_ok((void *)unaligned_addr, len))
- return -EACCES;
-
- get_data(unaligned_addr, &target_val, len);
-
- if (sign_ext)
- *idx_to_addr(regs, RT(inst)) =
- sign_extend(target_val, len);
- else
- *idx_to_addr(regs, RT(inst)) = target_val;
- } else {
-
- if (!access_ok((void *)unaligned_addr, len))
- return -EACCES;
-
- target_val = *idx_to_addr(regs, RT(inst));
- set_data((void *)unaligned_addr, target_val, len);
- }
-
- if (!regular)
- *idx_to_addr(regs, RA(inst)) = unaligned_addr + shift;
-
- regs->ipc += 4;
-
- return 0;
-fault:
- return -EACCES;
-}
-
-int do_unaligned_access(unsigned long addr, struct pt_regs *regs)
-{
- unsigned long inst;
- int ret = -EFAULT;
- mm_segment_t seg;
-
- inst = get_inst(regs->ipc);
-
- DEBUG((unalign_access_debug > 0), 1,
- "Faulting addr: 0x%08lx, pc: 0x%08lx [inst: 0x%08lx ]\n", addr,
- regs->ipc, inst);
-
- seg = force_uaccess_begin();
- if (inst & NDS32_16BIT_INSTRUCTION)
- ret = do_16((inst >> 16) & 0xffff, regs);
- else
- ret = do_32(inst, regs);
- force_uaccess_end(seg);
-
- return ret;
-}
-
-#ifdef CONFIG_PROC_FS
-
-static struct ctl_table alignment_tbl[3] = {
- {
- .procname = "enable",
- .data = &unalign_access_mode,
- .maxlen = sizeof(unalign_access_mode),
- .mode = 0666,
- .proc_handler = &proc_dointvec
- }
- ,
- {
- .procname = "debug_info",
- .data = &unalign_access_debug,
- .maxlen = sizeof(unalign_access_debug),
- .mode = 0644,
- .proc_handler = &proc_dointvec
- }
- ,
- {}
-};
-
-static struct ctl_table nds32_sysctl_table[2] = {
- {
- .procname = "unaligned_access",
- .mode = 0555,
- .child = alignment_tbl},
- {}
-};
-
-static struct ctl_path nds32_path[2] = {
- {.procname = "nds32"},
- {}
-};
-
-/*
- * Initialize nds32 alignment-correction interface
- */
-static int __init nds32_sysctl_init(void)
-{
- register_sysctl_paths(nds32_path, nds32_sysctl_table);
- return 0;
-}
-
-__initcall(nds32_sysctl_init);
-#endif /* CONFIG_PROC_FS */
diff --git a/arch/nds32/mm/cacheflush.c b/arch/nds32/mm/cacheflush.c
deleted file mode 100644
index 07aac65d1cab..000000000000
--- a/arch/nds32/mm/cacheflush.c
+++ /dev/null
@@ -1,338 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-// Copyright (C) 2005-2017 Andes Technology Corporation
-
-#include <linux/mm.h>
-#include <linux/sched.h>
-#include <linux/fs.h>
-#include <linux/pagemap.h>
-#include <linux/module.h>
-#include <asm/cacheflush.h>
-#include <asm/proc-fns.h>
-#include <asm/shmparam.h>
-#include <asm/cache_info.h>
-
-extern struct cache_info L1_cache_info[2];
-
-void flush_icache_range(unsigned long start, unsigned long end)
-{
- unsigned long line_size, flags;
- line_size = L1_cache_info[DCACHE].line_size;
- start = start & ~(line_size - 1);
- end = (end + line_size - 1) & ~(line_size - 1);
- local_irq_save(flags);
- cpu_cache_wbinval_range(start, end, 1);
- local_irq_restore(flags);
-}
-EXPORT_SYMBOL(flush_icache_range);
-
-void flush_icache_page(struct vm_area_struct *vma, struct page *page)
-{
- unsigned long flags;
- unsigned long kaddr;
- local_irq_save(flags);
- kaddr = (unsigned long)kmap_atomic(page);
- cpu_cache_wbinval_page(kaddr, vma->vm_flags & VM_EXEC);
- kunmap_atomic((void *)kaddr);
- local_irq_restore(flags);
-}
-
-void flush_icache_user_page(struct vm_area_struct *vma, struct page *page,
- unsigned long addr, int len)
-{
- unsigned long kaddr;
- kaddr = (unsigned long)kmap_atomic(page) + (addr & ~PAGE_MASK);
- flush_icache_range(kaddr, kaddr + len);
- kunmap_atomic((void *)kaddr);
-}
-
-void update_mmu_cache(struct vm_area_struct *vma, unsigned long addr,
- pte_t * pte)
-{
- struct page *page;
- unsigned long pfn = pte_pfn(*pte);
- unsigned long flags;
-
- if (!pfn_valid(pfn))
- return;
-
- if (vma->vm_mm == current->active_mm) {
- local_irq_save(flags);
- __nds32__mtsr_dsb(addr, NDS32_SR_TLB_VPN);
- __nds32__tlbop_rwr(*pte);
- __nds32__isb();
- local_irq_restore(flags);
- }
- page = pfn_to_page(pfn);
-
- if ((test_and_clear_bit(PG_dcache_dirty, &page->flags)) ||
- (vma->vm_flags & VM_EXEC)) {
- unsigned long kaddr;
- local_irq_save(flags);
- kaddr = (unsigned long)kmap_atomic(page);
- cpu_cache_wbinval_page(kaddr, vma->vm_flags & VM_EXEC);
- kunmap_atomic((void *)kaddr);
- local_irq_restore(flags);
- }
-}
-#ifdef CONFIG_CPU_CACHE_ALIASING
-extern pte_t va_present(struct mm_struct *mm, unsigned long addr);
-
-static inline unsigned long aliasing(unsigned long addr, unsigned long page)
-{
- return ((addr & PAGE_MASK) ^ page) & (SHMLBA - 1);
-}
-
-static inline unsigned long kremap0(unsigned long uaddr, unsigned long pa)
-{
- unsigned long kaddr, pte;
-
-#define BASE_ADDR0 0xffffc000
- kaddr = BASE_ADDR0 | (uaddr & L1_cache_info[DCACHE].aliasing_mask);
- pte = (pa | PAGE_KERNEL);
- __nds32__mtsr_dsb(kaddr, NDS32_SR_TLB_VPN);
- __nds32__tlbop_rwlk(pte);
- __nds32__isb();
- return kaddr;
-}
-
-static inline void kunmap01(unsigned long kaddr)
-{
- __nds32__tlbop_unlk(kaddr);
- __nds32__tlbop_inv(kaddr);
- __nds32__isb();
-}
-
-static inline unsigned long kremap1(unsigned long uaddr, unsigned long pa)
-{
- unsigned long kaddr, pte;
-
-#define BASE_ADDR1 0xffff8000
- kaddr = BASE_ADDR1 | (uaddr & L1_cache_info[DCACHE].aliasing_mask);
- pte = (pa | PAGE_KERNEL);
- __nds32__mtsr_dsb(kaddr, NDS32_SR_TLB_VPN);
- __nds32__tlbop_rwlk(pte);
- __nds32__isb();
- return kaddr;
-}
-
-void flush_cache_mm(struct mm_struct *mm)
-{
- unsigned long flags;
-
- local_irq_save(flags);
- cpu_dcache_wbinval_all();
- cpu_icache_inval_all();
- local_irq_restore(flags);
-}
-
-void flush_cache_dup_mm(struct mm_struct *mm)
-{
-}
-
-void flush_cache_range(struct vm_area_struct *vma,
- unsigned long start, unsigned long end)
-{
- unsigned long flags;
-
- if ((end - start) > 8 * PAGE_SIZE) {
- cpu_dcache_wbinval_all();
- if (vma->vm_flags & VM_EXEC)
- cpu_icache_inval_all();
- return;
- }
- local_irq_save(flags);
- while (start < end) {
- if (va_present(vma->vm_mm, start))
- cpu_cache_wbinval_page(start, vma->vm_flags & VM_EXEC);
- start += PAGE_SIZE;
- }
- local_irq_restore(flags);
- return;
-}
-
-void flush_cache_page(struct vm_area_struct *vma,
- unsigned long addr, unsigned long pfn)
-{
- unsigned long vto, flags;
-
- local_irq_save(flags);
- vto = kremap0(addr, pfn << PAGE_SHIFT);
- cpu_cache_wbinval_page(vto, vma->vm_flags & VM_EXEC);
- kunmap01(vto);
- local_irq_restore(flags);
-}
-
-void flush_cache_vmap(unsigned long start, unsigned long end)
-{
- cpu_dcache_wbinval_all();
- cpu_icache_inval_all();
-}
-
-void flush_cache_vunmap(unsigned long start, unsigned long end)
-{
- cpu_dcache_wbinval_all();
- cpu_icache_inval_all();
-}
-
-void copy_user_page(void *vto, void *vfrom, unsigned long vaddr,
- struct page *to)
-{
- cpu_dcache_wbinval_page((unsigned long)vaddr);
- cpu_icache_inval_page((unsigned long)vaddr);
- copy_page(vto, vfrom);
- cpu_dcache_wbinval_page((unsigned long)vto);
- cpu_icache_inval_page((unsigned long)vto);
-}
-
-void clear_user_page(void *addr, unsigned long vaddr, struct page *page)
-{
- cpu_dcache_wbinval_page((unsigned long)vaddr);
- cpu_icache_inval_page((unsigned long)vaddr);
- clear_page(addr);
- cpu_dcache_wbinval_page((unsigned long)addr);
- cpu_icache_inval_page((unsigned long)addr);
-}
-
-void copy_user_highpage(struct page *to, struct page *from,
- unsigned long vaddr, struct vm_area_struct *vma)
-{
- unsigned long vto, vfrom, flags, kto, kfrom, pfrom, pto;
- kto = ((unsigned long)page_address(to) & PAGE_MASK);
- kfrom = ((unsigned long)page_address(from) & PAGE_MASK);
- pto = page_to_phys(to);
- pfrom = page_to_phys(from);
-
- local_irq_save(flags);
- if (aliasing(vaddr, (unsigned long)kfrom))
- cpu_dcache_wb_page((unsigned long)kfrom);
- vto = kremap0(vaddr, pto);
- vfrom = kremap1(vaddr, pfrom);
- copy_page((void *)vto, (void *)vfrom);
- kunmap01(vfrom);
- kunmap01(vto);
- local_irq_restore(flags);
-}
-
-EXPORT_SYMBOL(copy_user_highpage);
-
-void clear_user_highpage(struct page *page, unsigned long vaddr)
-{
- unsigned long vto, flags, kto;
-
- kto = ((unsigned long)page_address(page) & PAGE_MASK);
-
- local_irq_save(flags);
- if (aliasing(kto, vaddr) && kto != 0) {
- cpu_dcache_inval_page(kto);
- cpu_icache_inval_page(kto);
- }
- vto = kremap0(vaddr, page_to_phys(page));
- clear_page((void *)vto);
- kunmap01(vto);
- local_irq_restore(flags);
-}
-
-EXPORT_SYMBOL(clear_user_highpage);
-
-void flush_dcache_page(struct page *page)
-{
- struct address_space *mapping;
-
- mapping = page_mapping_file(page);
- if (mapping && !mapping_mapped(mapping))
- set_bit(PG_dcache_dirty, &page->flags);
- else {
- unsigned long kaddr, flags;
-
- kaddr = (unsigned long)page_address(page);
- local_irq_save(flags);
- cpu_dcache_wbinval_page(kaddr);
- if (mapping) {
- unsigned long vaddr, kto;
-
- vaddr = page->index << PAGE_SHIFT;
- if (aliasing(vaddr, kaddr)) {
- kto = kremap0(vaddr, page_to_phys(page));
- cpu_dcache_wbinval_page(kto);
- kunmap01(kto);
- }
- }
- local_irq_restore(flags);
- }
-}
-EXPORT_SYMBOL(flush_dcache_page);
-
-void copy_to_user_page(struct vm_area_struct *vma, struct page *page,
- unsigned long vaddr, void *dst, void *src, int len)
-{
- unsigned long line_size, start, end, vto, flags;
-
- local_irq_save(flags);
- vto = kremap0(vaddr, page_to_phys(page));
- dst = (void *)(vto | (vaddr & (PAGE_SIZE - 1)));
- memcpy(dst, src, len);
- if (vma->vm_flags & VM_EXEC) {
- line_size = L1_cache_info[DCACHE].line_size;
- start = (unsigned long)dst & ~(line_size - 1);
- end =
- ((unsigned long)dst + len + line_size - 1) & ~(line_size -
- 1);
- cpu_cache_wbinval_range(start, end, 1);
- }
- kunmap01(vto);
- local_irq_restore(flags);
-}
-
-void copy_from_user_page(struct vm_area_struct *vma, struct page *page,
- unsigned long vaddr, void *dst, void *src, int len)
-{
- unsigned long vto, flags;
-
- local_irq_save(flags);
- vto = kremap0(vaddr, page_to_phys(page));
- src = (void *)(vto | (vaddr & (PAGE_SIZE - 1)));
- memcpy(dst, src, len);
- kunmap01(vto);
- local_irq_restore(flags);
-}
-
-void flush_anon_page(struct vm_area_struct *vma,
- struct page *page, unsigned long vaddr)
-{
- unsigned long kaddr, flags, ktmp;
- if (!PageAnon(page))
- return;
-
- if (vma->vm_mm != current->active_mm)
- return;
-
- local_irq_save(flags);
- if (vma->vm_flags & VM_EXEC)
- cpu_icache_inval_page(vaddr & PAGE_MASK);
- kaddr = (unsigned long)page_address(page);
- if (aliasing(vaddr, kaddr)) {
- ktmp = kremap0(vaddr, page_to_phys(page));
- cpu_dcache_wbinval_page(ktmp);
- kunmap01(ktmp);
- }
- local_irq_restore(flags);
-}
-
-void flush_kernel_vmap_range(void *addr, int size)
-{
- unsigned long flags;
- local_irq_save(flags);
- cpu_dcache_wb_range((unsigned long)addr, (unsigned long)addr + size);
- local_irq_restore(flags);
-}
-EXPORT_SYMBOL(flush_kernel_vmap_range);
-
-void invalidate_kernel_vmap_range(void *addr, int size)
-{
- unsigned long flags;
- local_irq_save(flags);
- cpu_dcache_inval_range((unsigned long)addr, (unsigned long)addr + size);
- local_irq_restore(flags);
-}
-EXPORT_SYMBOL(invalidate_kernel_vmap_range);
-#endif
diff --git a/arch/nds32/mm/extable.c b/arch/nds32/mm/extable.c
deleted file mode 100644
index db7f0a7c8966..000000000000
--- a/arch/nds32/mm/extable.c
+++ /dev/null
@@ -1,16 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-// Copyright (C) 2005-2017 Andes Technology Corporation
-
-#include <linux/extable.h>
-#include <linux/uaccess.h>
-
-int fixup_exception(struct pt_regs *regs)
-{
- const struct exception_table_entry *fixup;
-
- fixup = search_exception_tables(instruction_pointer(regs));
- if (fixup)
- regs->ipc = fixup->fixup;
-
- return fixup != NULL;
-}
diff --git a/arch/nds32/mm/fault.c b/arch/nds32/mm/fault.c
deleted file mode 100644
index 636977a1c8b9..000000000000
--- a/arch/nds32/mm/fault.c
+++ /dev/null
@@ -1,396 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-// Copyright (C) 2005-2017 Andes Technology Corporation
-
-#include <linux/extable.h>
-#include <linux/module.h>
-#include <linux/signal.h>
-#include <linux/ptrace.h>
-#include <linux/mm.h>
-#include <linux/init.h>
-#include <linux/hardirq.h>
-#include <linux/uaccess.h>
-#include <linux/perf_event.h>
-
-#include <asm/tlbflush.h>
-
-extern void __noreturn die(const char *str, struct pt_regs *regs, long err);
-
-/*
- * This is useful to dump out the page tables associated with
- * 'addr' in mm 'mm'.
- */
-void show_pte(struct mm_struct *mm, unsigned long addr)
-{
- pgd_t *pgd;
- if (!mm)
- mm = &init_mm;
-
- pr_alert("pgd = %p\n", mm->pgd);
- pgd = pgd_offset(mm, addr);
- pr_alert("[%08lx] *pgd=%08lx", addr, pgd_val(*pgd));
-
- do {
- p4d_t *p4d;
- pud_t *pud;
- pmd_t *pmd;
-
- if (pgd_none(*pgd))
- break;
-
- if (pgd_bad(*pgd)) {
- pr_alert("(bad)");
- break;
- }
-
- p4d = p4d_offset(pgd, addr);
- pud = pud_offset(p4d, addr);
- pmd = pmd_offset(pud, addr);
-#if PTRS_PER_PMD != 1
- pr_alert(", *pmd=%08lx", pmd_val(*pmd));
-#endif
-
- if (pmd_none(*pmd))
- break;
-
- if (pmd_bad(*pmd)) {
- pr_alert("(bad)");
- break;
- }
-
- if (IS_ENABLED(CONFIG_HIGHMEM))
- {
- pte_t *pte;
- /* We must not map this if we have highmem enabled */
- pte = pte_offset_map(pmd, addr);
- pr_alert(", *pte=%08lx", pte_val(*pte));
- pte_unmap(pte);
- }
- } while (0);
-
- pr_alert("\n");
-}
-
-void do_page_fault(unsigned long entry, unsigned long addr,
- unsigned int error_code, struct pt_regs *regs)
-{
- struct task_struct *tsk;
- struct mm_struct *mm;
- struct vm_area_struct *vma;
- int si_code;
- vm_fault_t fault;
- unsigned int mask = VM_ACCESS_FLAGS;
- unsigned int flags = FAULT_FLAG_DEFAULT;
-
- error_code = error_code & (ITYPE_mskINST | ITYPE_mskETYPE);
- tsk = current;
- mm = tsk->mm;
- si_code = SEGV_MAPERR;
- /*
- * We fault-in kernel-space virtual memory on-demand. The
- * 'reference' page table is init_mm.pgd.
- *
- * NOTE! We MUST NOT take any locks for this case. We may
- * be in an interrupt or a critical region, and should
- * only copy the information from the master page table,
- * nothing more.
- */
- if (addr >= TASK_SIZE) {
- if (user_mode(regs))
- goto bad_area_nosemaphore;
-
- if (addr >= TASK_SIZE && addr < VMALLOC_END
- && (entry == ENTRY_PTE_NOT_PRESENT))
- goto vmalloc_fault;
- else
- goto no_context;
- }
-
- /* Send a signal to the task for handling the unalignment access. */
- if (entry == ENTRY_GENERAL_EXCPETION
- && error_code == ETYPE_ALIGNMENT_CHECK) {
- if (user_mode(regs))
- goto bad_area_nosemaphore;
- else
- goto no_context;
- }
-
- /*
- * If we're in an interrupt or have no user
- * context, we must not take the fault..
- */
- if (unlikely(faulthandler_disabled() || !mm))
- goto no_context;
-
- perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS, 1, regs, addr);
-
- /*
- * As per x86, we may deadlock here. However, since the kernel only
- * validly references user space from well defined areas of the code,
- * we can bug out early if this is from code which shouldn't.
- */
- if (unlikely(!mmap_read_trylock(mm))) {
- if (!user_mode(regs) &&
- !search_exception_tables(instruction_pointer(regs)))
- goto no_context;
-retry:
- mmap_read_lock(mm);
- } else {
- /*
- * The above down_read_trylock() might have succeeded in which
- * case, we'll have missed the might_sleep() from down_read().
- */
- might_sleep();
- if (IS_ENABLED(CONFIG_DEBUG_VM)) {
- if (!user_mode(regs) &&
- !search_exception_tables(instruction_pointer(regs)))
- goto no_context;
- }
- }
-
- vma = find_vma(mm, addr);
-
- if (unlikely(!vma))
- goto bad_area;
-
- if (vma->vm_start <= addr)
- goto good_area;
-
- if (unlikely(!(vma->vm_flags & VM_GROWSDOWN)))
- goto bad_area;
-
- if (unlikely(expand_stack(vma, addr)))
- goto bad_area;
-
- /*
- * Ok, we have a good vm_area for this memory access, so
- * we can handle it..
- */
-
-good_area:
- si_code = SEGV_ACCERR;
-
- /* first do some preliminary protection checks */
- if (entry == ENTRY_PTE_NOT_PRESENT) {
- if (error_code & ITYPE_mskINST)
- mask = VM_EXEC;
- else {
- mask = VM_READ | VM_WRITE;
- }
- } else if (entry == ENTRY_TLB_MISC) {
- switch (error_code & ITYPE_mskETYPE) {
- case RD_PROT:
- mask = VM_READ;
- break;
- case WRT_PROT:
- mask = VM_WRITE;
- flags |= FAULT_FLAG_WRITE;
- break;
- case NOEXEC:
- mask = VM_EXEC;
- break;
- case PAGE_MODIFY:
- mask = VM_WRITE;
- flags |= FAULT_FLAG_WRITE;
- break;
- case ACC_BIT:
- BUG();
- default:
- break;
- }
-
- }
- if (!(vma->vm_flags & mask))
- goto bad_area;
-
- /*
- * If for any reason at all we couldn't handle the fault,
- * make sure we exit gracefully rather than endlessly redo
- * the fault.
- */
-
- fault = handle_mm_fault(vma, addr, flags, regs);
-
- /*
- * If we need to retry but a fatal signal is pending, handle the
- * signal first. We do not need to release the mmap_lock because it
- * would already be released in __lock_page_or_retry in mm/filemap.c.
- */
- if (fault_signal_pending(fault, regs)) {
- if (!user_mode(regs))
- goto no_context;
- return;
- }
-
- if (unlikely(fault & VM_FAULT_ERROR)) {
- if (fault & VM_FAULT_OOM)
- goto out_of_memory;
- else if (fault & VM_FAULT_SIGBUS)
- goto do_sigbus;
- else
- goto bad_area;
- }
-
- if (fault & VM_FAULT_RETRY) {
- flags |= FAULT_FLAG_TRIED;
-
- /* No need to mmap_read_unlock(mm) as we would
- * have already released it in __lock_page_or_retry
- * in mm/filemap.c.
- */
- goto retry;
- }
-
- mmap_read_unlock(mm);
- return;
-
- /*
- * Something tried to access memory that isn't in our memory map..
- * Fix it, but check if it's kernel or user first..
- */
-bad_area:
- mmap_read_unlock(mm);
-
-bad_area_nosemaphore:
-
- /* User mode accesses just cause a SIGSEGV */
-
- if (user_mode(regs)) {
- tsk->thread.address = addr;
- tsk->thread.error_code = error_code;
- tsk->thread.trap_no = entry;
- force_sig_fault(SIGSEGV, si_code, (void __user *)addr);
- return;
- }
-
-no_context:
-
- /* Are we prepared to handle this kernel fault?
- *
- * (The kernel has valid exception-points in the source
- * when it acesses user-memory. When it fails in one
- * of those points, we find it in a table and do a jump
- * to some fixup code that loads an appropriate error
- * code)
- */
-
- {
- const struct exception_table_entry *entry;
-
- if ((entry =
- search_exception_tables(instruction_pointer(regs))) !=
- NULL) {
- /* Adjust the instruction pointer in the stackframe */
- instruction_pointer(regs) = entry->fixup;
- return;
- }
- }
-
- /*
- * Oops. The kernel tried to access some bad page. We'll have to
- * terminate things with extreme prejudice.
- */
-
- bust_spinlocks(1);
- pr_alert("Unable to handle kernel %s at virtual address %08lx\n",
- (addr < PAGE_SIZE) ? "NULL pointer dereference" :
- "paging request", addr);
-
- show_pte(mm, addr);
- die("Oops", regs, error_code);
-
- /*
- * We ran out of memory, or some other thing happened to us that made
- * us unable to handle the page fault gracefully.
- */
-
-out_of_memory:
- mmap_read_unlock(mm);
- if (!user_mode(regs))
- goto no_context;
- pagefault_out_of_memory();
- return;
-
-do_sigbus:
- mmap_read_unlock(mm);
-
- /* Kernel mode? Handle exceptions or die */
- if (!user_mode(regs))
- goto no_context;
-
- /*
- * Send a sigbus
- */
- tsk->thread.address = addr;
- tsk->thread.error_code = error_code;
- tsk->thread.trap_no = entry;
- force_sig_fault(SIGBUS, BUS_ADRERR, (void __user *)addr);
-
- return;
-
-vmalloc_fault:
- {
- /*
- * Synchronize this task's top level page-table
- * with the 'reference' page table.
- *
- * Use current_pgd instead of tsk->active_mm->pgd
- * since the latter might be unavailable if this
- * code is executed in a misfortunately run irq
- * (like inside schedule() between switch_mm and
- * switch_to...).
- */
-
- unsigned int index = pgd_index(addr);
- pgd_t *pgd, *pgd_k;
- p4d_t *p4d, *p4d_k;
- pud_t *pud, *pud_k;
- pmd_t *pmd, *pmd_k;
- pte_t *pte_k;
-
- pgd = (pgd_t *) __va(__nds32__mfsr(NDS32_SR_L1_PPTB)) + index;
- pgd_k = init_mm.pgd + index;
-
- if (!pgd_present(*pgd_k))
- goto no_context;
-
- p4d = p4d_offset(pgd, addr);
- p4d_k = p4d_offset(pgd_k, addr);
- if (!p4d_present(*p4d_k))
- goto no_context;
-
- pud = pud_offset(p4d, addr);
- pud_k = pud_offset(p4d_k, addr);
- if (!pud_present(*pud_k))
- goto no_context;
-
- pmd = pmd_offset(pud, addr);
- pmd_k = pmd_offset(pud_k, addr);
- if (!pmd_present(*pmd_k))
- goto no_context;
-
- if (!pmd_present(*pmd))
- set_pmd(pmd, *pmd_k);
- else
- BUG_ON(pmd_page(*pmd) != pmd_page(*pmd_k));
-
- /*
- * Since the vmalloc area is global, we don't
- * need to copy individual PTE's, it is enough to
- * copy the pgd pointer into the pte page of the
- * root task. If that is there, we'll find our pte if
- * it exists.
- */
-
- /* Make sure the actual PTE exists as well to
- * catch kernel vmalloc-area accesses to non-mapped
- * addres. If we don't do this, this will just
- * silently loop forever.
- */
-
- pte_k = pte_offset_kernel(pmd_k, addr);
- if (!pte_present(*pte_k))
- goto no_context;
-
- return;
- }
-}
diff --git a/arch/nds32/mm/init.c b/arch/nds32/mm/init.c
deleted file mode 100644
index f63f839738c4..000000000000
--- a/arch/nds32/mm/init.c
+++ /dev/null
@@ -1,263 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-// Copyright (C) 1995-2005 Russell King
-// Copyright (C) 2012 ARM Ltd.
-// Copyright (C) 2013-2017 Andes Technology Corporation
-
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/swap.h>
-#include <linux/init.h>
-#include <linux/memblock.h>
-#include <linux/mman.h>
-#include <linux/nodemask.h>
-#include <linux/initrd.h>
-#include <linux/highmem.h>
-
-#include <asm/sections.h>
-#include <asm/setup.h>
-#include <asm/tlb.h>
-#include <asm/page.h>
-
-DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
-DEFINE_SPINLOCK(anon_alias_lock);
-extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
-
-/*
- * empty_zero_page is a special page that is used for
- * zero-initialized data and COW.
- */
-struct page *empty_zero_page;
-EXPORT_SYMBOL(empty_zero_page);
-
-static void __init zone_sizes_init(void)
-{
- unsigned long max_zone_pfn[MAX_NR_ZONES] = { 0 };
-
- max_zone_pfn[ZONE_NORMAL] = max_low_pfn;
-#ifdef CONFIG_HIGHMEM
- max_zone_pfn[ZONE_HIGHMEM] = max_pfn;
-#endif
- free_area_init(max_zone_pfn);
-
-}
-
-/*
- * Map all physical memory under high_memory into kernel's address space.
- *
- * This is explicitly coded for two-level page tables, so if you need
- * something else then this needs to change.
- */
-static void __init map_ram(void)
-{
- unsigned long v, p, e;
- pgd_t *pge;
- p4d_t *p4e;
- pud_t *pue;
- pmd_t *pme;
- pte_t *pte;
- /* These mark extents of read-only kernel pages...
- * ...from vmlinux.lds.S
- */
-
- p = (u32) memblock_start_of_DRAM() & PAGE_MASK;
- e = min((u32) memblock_end_of_DRAM(), (u32) __pa(high_memory));
-
- v = (u32) __va(p);
- pge = pgd_offset_k(v);
-
- while (p < e) {
- int j;
- p4e = p4d_offset(pge, v);
- pue = pud_offset(p4e, v);
- pme = pmd_offset(pue, v);
-
- if ((u32) pue != (u32) pge || (u32) pme != (u32) pge) {
- panic("%s: Kernel hardcoded for "
- "two-level page tables", __func__);
- }
-
- /* Alloc one page for holding PTE's... */
- pte = memblock_alloc(PAGE_SIZE, PAGE_SIZE);
- if (!pte)
- panic("%s: Failed to allocate %lu bytes align=0x%lx\n",
- __func__, PAGE_SIZE, PAGE_SIZE);
- set_pmd(pme, __pmd(__pa(pte) + _PAGE_KERNEL_TABLE));
-
- /* Fill the newly allocated page with PTE'S */
- for (j = 0; p < e && j < PTRS_PER_PTE;
- v += PAGE_SIZE, p += PAGE_SIZE, j++, pte++) {
- /* Create mapping between p and v. */
- /* TODO: more fine grant for page access permission */
- set_pte(pte, __pte(p + pgprot_val(PAGE_KERNEL)));
- }
-
- pge++;
- }
-}
-static pmd_t *fixmap_pmd_p;
-static void __init fixedrange_init(void)
-{
- unsigned long vaddr;
- pmd_t *pmd;
-#ifdef CONFIG_HIGHMEM
- pte_t *pte;
-#endif /* CONFIG_HIGHMEM */
-
- /*
- * Fixed mappings:
- */
- vaddr = __fix_to_virt(__end_of_fixed_addresses - 1);
- pmd = pmd_off_k(vaddr);
- fixmap_pmd_p = memblock_alloc(PAGE_SIZE, PAGE_SIZE);
- if (!fixmap_pmd_p)
- panic("%s: Failed to allocate %lu bytes align=0x%lx\n",
- __func__, PAGE_SIZE, PAGE_SIZE);
- set_pmd(pmd, __pmd(__pa(fixmap_pmd_p) + _PAGE_KERNEL_TABLE));
-
-#ifdef CONFIG_HIGHMEM
- /*
- * Permanent kmaps:
- */
- vaddr = PKMAP_BASE;
-
- pmd = pmd_off_k(vaddr);
- pte = memblock_alloc(PAGE_SIZE, PAGE_SIZE);
- if (!pte)
- panic("%s: Failed to allocate %lu bytes align=0x%lx\n",
- __func__, PAGE_SIZE, PAGE_SIZE);
- set_pmd(pmd, __pmd(__pa(pte) + _PAGE_KERNEL_TABLE));
- pkmap_page_table = pte;
-#endif /* CONFIG_HIGHMEM */
-}
-
-/*
- * paging_init() sets up the page tables, initialises the zone memory
- * maps, and sets up the zero page, bad page and bad page tables.
- */
-void __init paging_init(void)
-{
- int i;
- void *zero_page;
-
- pr_info("Setting up paging and PTEs.\n");
- /* clear out the init_mm.pgd that will contain the kernel's mappings */
- for (i = 0; i < PTRS_PER_PGD; i++)
- swapper_pg_dir[i] = __pgd(1);
-
- map_ram();
-
- fixedrange_init();
-
- /* allocate space for empty_zero_page */
- zero_page = memblock_alloc(PAGE_SIZE, PAGE_SIZE);
- if (!zero_page)
- panic("%s: Failed to allocate %lu bytes align=0x%lx\n",
- __func__, PAGE_SIZE, PAGE_SIZE);
- zone_sizes_init();
-
- empty_zero_page = virt_to_page(zero_page);
- flush_dcache_page(empty_zero_page);
-}
-
-static inline void __init free_highmem(void)
-{
-#ifdef CONFIG_HIGHMEM
- unsigned long pfn;
- for (pfn = PFN_UP(__pa(high_memory)); pfn < max_pfn; pfn++) {
- phys_addr_t paddr = (phys_addr_t) pfn << PAGE_SHIFT;
- if (!memblock_is_reserved(paddr))
- free_highmem_page(pfn_to_page(pfn));
- }
-#endif
-}
-
-static void __init set_max_mapnr_init(void)
-{
- max_mapnr = max_pfn;
-}
-
-/*
- * mem_init() marks the free areas in the mem_map and tells us how much
- * memory is free. This is done after various parts of the system have
- * claimed their memory after the kernel image.
- */
-void __init mem_init(void)
-{
- phys_addr_t memory_start = memblock_start_of_DRAM();
- BUG_ON(!mem_map);
- set_max_mapnr_init();
-
- free_highmem();
-
- /* this will put all low memory onto the freelists */
- memblock_free_all();
-
- pr_info("virtual kernel memory layout:\n"
- " fixmap : 0x%08lx - 0x%08lx (%4ld kB)\n"
-#ifdef CONFIG_HIGHMEM
- " pkmap : 0x%08lx - 0x%08lx (%4ld kB)\n"
-#endif
- " consist : 0x%08lx - 0x%08lx (%4ld MB)\n"
- " vmalloc : 0x%08lx - 0x%08lx (%4ld MB)\n"
- " lowmem : 0x%08lx - 0x%08lx (%4ld MB)\n"
- " .init : 0x%08lx - 0x%08lx (%4ld kB)\n"
- " .data : 0x%08lx - 0x%08lx (%4ld kB)\n"
- " .text : 0x%08lx - 0x%08lx (%4ld kB)\n",
- FIXADDR_START, FIXADDR_TOP, (FIXADDR_TOP - FIXADDR_START) >> 10,
-#ifdef CONFIG_HIGHMEM
- PKMAP_BASE, PKMAP_BASE + LAST_PKMAP * PAGE_SIZE,
- (LAST_PKMAP * PAGE_SIZE) >> 10,
-#endif
- CONSISTENT_BASE, CONSISTENT_END,
- ((CONSISTENT_END) - (CONSISTENT_BASE)) >> 20, VMALLOC_START,
- (unsigned long)VMALLOC_END, (VMALLOC_END - VMALLOC_START) >> 20,
- (unsigned long)__va(memory_start), (unsigned long)high_memory,
- ((unsigned long)high_memory -
- (unsigned long)__va(memory_start)) >> 20,
- (unsigned long)&__init_begin, (unsigned long)&__init_end,
- ((unsigned long)&__init_end -
- (unsigned long)&__init_begin) >> 10, (unsigned long)&_etext,
- (unsigned long)&_edata,
- ((unsigned long)&_edata - (unsigned long)&_etext) >> 10,
- (unsigned long)&_text, (unsigned long)&_etext,
- ((unsigned long)&_etext - (unsigned long)&_text) >> 10);
-
- /*
- * Check boundaries twice: Some fundamental inconsistencies can
- * be detected at build time already.
- */
-#ifdef CONFIG_HIGHMEM
- BUILD_BUG_ON(PKMAP_BASE + LAST_PKMAP * PAGE_SIZE > FIXADDR_START);
- BUILD_BUG_ON((CONSISTENT_END) > PKMAP_BASE);
-#endif
- BUILD_BUG_ON(VMALLOC_END > CONSISTENT_BASE);
- BUILD_BUG_ON(VMALLOC_START >= VMALLOC_END);
-
-#ifdef CONFIG_HIGHMEM
- BUG_ON(PKMAP_BASE + LAST_PKMAP * PAGE_SIZE > FIXADDR_START);
- BUG_ON(CONSISTENT_END > PKMAP_BASE);
-#endif
- BUG_ON(VMALLOC_END > CONSISTENT_BASE);
- BUG_ON(VMALLOC_START >= VMALLOC_END);
- BUG_ON((unsigned long)high_memory > VMALLOC_START);
-
- return;
-}
-
-void __set_fixmap(enum fixed_addresses idx,
- phys_addr_t phys, pgprot_t flags)
-{
- unsigned long addr = __fix_to_virt(idx);
- pte_t *pte;
-
- BUG_ON(idx <= FIX_HOLE || idx >= __end_of_fixed_addresses);
-
- pte = (pte_t *)&fixmap_pmd_p[pte_index(addr)];
-
- if (pgprot_val(flags)) {
- set_pte(pte, pfn_pte(phys >> PAGE_SHIFT, flags));
- } else {
- pte_clear(&init_mm, addr, pte);
- flush_tlb_kernel_range(addr, addr + PAGE_SIZE);
- }
-}
diff --git a/arch/nds32/mm/mm-nds32.c b/arch/nds32/mm/mm-nds32.c
deleted file mode 100644
index f2778f2b39f6..000000000000
--- a/arch/nds32/mm/mm-nds32.c
+++ /dev/null
@@ -1,96 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-// Copyright (C) 2005-2017 Andes Technology Corporation
-
-#include <linux/init_task.h>
-
-#define __HAVE_ARCH_PGD_FREE
-#include <asm/pgalloc.h>
-
-#define FIRST_KERNEL_PGD_NR (USER_PTRS_PER_PGD)
-
-/*
- * need to get a page for level 1
- */
-
-pgd_t *pgd_alloc(struct mm_struct *mm)
-{
- pgd_t *new_pgd, *init_pgd;
- int i;
-
- new_pgd = (pgd_t *) __get_free_pages(GFP_KERNEL, 0);
- if (!new_pgd)
- return NULL;
- for (i = 0; i < PTRS_PER_PGD; i++) {
- (*new_pgd) = 1;
- new_pgd++;
- }
- new_pgd -= PTRS_PER_PGD;
-
- init_pgd = pgd_offset_k(0);
-
- memcpy(new_pgd + FIRST_KERNEL_PGD_NR, init_pgd + FIRST_KERNEL_PGD_NR,
- (PTRS_PER_PGD - FIRST_KERNEL_PGD_NR) * sizeof(pgd_t));
-
- cpu_dcache_wb_range((unsigned long)new_pgd,
- (unsigned long)new_pgd +
- PTRS_PER_PGD * sizeof(pgd_t));
- inc_lruvec_page_state(virt_to_page((unsigned long *)new_pgd),
- NR_PAGETABLE);
-
- return new_pgd;
-}
-
-void pgd_free(struct mm_struct *mm, pgd_t * pgd)
-{
- pmd_t *pmd;
- struct page *pte;
-
- if (!pgd)
- return;
-
- pmd = (pmd_t *) pgd;
- if (pmd_none(*pmd))
- goto free;
- if (pmd_bad(*pmd)) {
- pmd_ERROR(*pmd);
- pmd_clear(pmd);
- goto free;
- }
-
- pte = pmd_page(*pmd);
- pmd_clear(pmd);
- dec_lruvec_page_state(virt_to_page((unsigned long *)pgd), NR_PAGETABLE);
- pte_free(mm, pte);
- mm_dec_nr_ptes(mm);
- pmd_free(mm, pmd);
-free:
- free_pages((unsigned long)pgd, 0);
-}
-
-/*
- * In order to soft-boot, we need to insert a 1:1 mapping in place of
- * the user-mode pages. This will then ensure that we have predictable
- * results when turning the mmu off
- */
-void setup_mm_for_reboot(char mode)
-{
- unsigned long pmdval;
- pgd_t *pgd;
- p4d_t *p4d;
- pud_t *pud;
- pmd_t *pmd;
- int i;
-
- if (current->mm && current->mm->pgd)
- pgd = current->mm->pgd;
- else
- pgd = init_mm.pgd;
-
- for (i = 0; i < USER_PTRS_PER_PGD; i++) {
- pmdval = (i << PGDIR_SHIFT);
- p4d = p4d_offset(pgd, i << PGDIR_SHIFT);
- pud = pud_offset(p4d, i << PGDIR_SHIFT);
- pmd = pmd_offset(pud + i, i << PGDIR_SHIFT);
- set_pmd(pmd, __pmd(pmdval));
- }
-}
diff --git a/arch/nds32/mm/mmap.c b/arch/nds32/mm/mmap.c
deleted file mode 100644
index 1bdf5e7d1b43..000000000000
--- a/arch/nds32/mm/mmap.c
+++ /dev/null
@@ -1,73 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-// Copyright (C) 2005-2017 Andes Technology Corporation
-
-#include <linux/sched.h>
-#include <linux/mman.h>
-#include <linux/shm.h>
-
-#define COLOUR_ALIGN(addr,pgoff) \
- ((((addr)+SHMLBA-1)&~(SHMLBA-1)) + \
- (((pgoff)<<PAGE_SHIFT) & (SHMLBA-1)))
-
-/*
- * We need to ensure that shared mappings are correctly aligned to
- * avoid aliasing issues with VIPT caches. We need to ensure that
- * a specific page of an object is always mapped at a multiple of
- * SHMLBA bytes.
- *
- * We unconditionally provide this function for all cases, however
- * in the VIVT case, we optimise out the alignment rules.
- */
-unsigned long
-arch_get_unmapped_area(struct file *filp, unsigned long addr,
- unsigned long len, unsigned long pgoff,
- unsigned long flags)
-{
- struct mm_struct *mm = current->mm;
- struct vm_area_struct *vma;
- int do_align = 0;
- struct vm_unmapped_area_info info;
- int aliasing = 0;
- if(IS_ENABLED(CONFIG_CPU_CACHE_ALIASING))
- aliasing = 1;
-
- /*
- * We only need to do colour alignment if either the I or D
- * caches alias.
- */
- if (aliasing)
- do_align = filp || (flags & MAP_SHARED);
-
- /*
- * We enforce the MAP_FIXED case.
- */
- if (flags & MAP_FIXED) {
- if (aliasing && flags & MAP_SHARED &&
- (addr - (pgoff << PAGE_SHIFT)) & (SHMLBA - 1))
- return -EINVAL;
- return addr;
- }
-
- if (len > TASK_SIZE)
- return -ENOMEM;
-
- if (addr) {
- if (do_align)
- addr = COLOUR_ALIGN(addr, pgoff);
- else
- addr = PAGE_ALIGN(addr);
-
- vma = find_vma(mm, addr);
- if (TASK_SIZE - len >= addr &&
- (!vma || addr + len <= vm_start_gap(vma)))
- return addr;
- }
-
- info.flags = 0;
- info.length = len;
- info.low_limit = mm->mmap_base;
- info.high_limit = TASK_SIZE;
- info.align_mask = do_align ? (PAGE_MASK & (SHMLBA - 1)) : 0;
- info.align_offset = pgoff << PAGE_SHIFT;
- return vm_unmapped_area(&info);
-}
diff --git a/arch/nds32/mm/proc.c b/arch/nds32/mm/proc.c
deleted file mode 100644
index 848c845f5f33..000000000000
--- a/arch/nds32/mm/proc.c
+++ /dev/null
@@ -1,536 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-// Copyright (C) 2005-2017 Andes Technology Corporation
-
-#include <linux/module.h>
-#include <linux/sched.h>
-#include <linux/mm.h>
-#include <asm/nds32.h>
-#include <asm/tlbflush.h>
-#include <asm/cacheflush.h>
-#include <asm/l2_cache.h>
-#include <nds32_intrinsic.h>
-
-#include <asm/cache_info.h>
-extern struct cache_info L1_cache_info[2];
-
-int va_kernel_present(unsigned long addr)
-{
- pmd_t *pmd;
- pte_t *ptep, pte;
-
- pmd = pmd_off_k(addr);
- if (!pmd_none(*pmd)) {
- ptep = pte_offset_map(pmd, addr);
- pte = *ptep;
- if (pte_present(pte))
- return pte;
- }
- return 0;
-}
-
-pte_t va_present(struct mm_struct * mm, unsigned long addr)
-{
- pgd_t *pgd;
- p4d_t *p4d;
- pud_t *pud;
- pmd_t *pmd;
- pte_t *ptep, pte;
-
- pgd = pgd_offset(mm, addr);
- if (!pgd_none(*pgd)) {
- p4d = p4d_offset(pgd, addr);
- if (!p4d_none(*p4d)) {
- pud = pud_offset(p4d, addr);
- if (!pud_none(*pud)) {
- pmd = pmd_offset(pud, addr);
- if (!pmd_none(*pmd)) {
- ptep = pte_offset_map(pmd, addr);
- pte = *ptep;
- if (pte_present(pte))
- return pte;
- }
- }
- }
- }
- return 0;
-
-}
-
-int va_readable(struct pt_regs *regs, unsigned long addr)
-{
- struct mm_struct *mm = current->mm;
- pte_t pte;
- int ret = 0;
-
- if (user_mode(regs)) {
- /* user mode */
- pte = va_present(mm, addr);
- if (!pte && pte_read(pte))
- ret = 1;
- } else {
- /* superuser mode is always readable, so we can only
- * check it is present or not*/
- return (! !va_kernel_present(addr));
- }
- return ret;
-}
-
-int va_writable(struct pt_regs *regs, unsigned long addr)
-{
- struct mm_struct *mm = current->mm;
- pte_t pte;
- int ret = 0;
-
- if (user_mode(regs)) {
- /* user mode */
- pte = va_present(mm, addr);
- if (!pte && pte_write(pte))
- ret = 1;
- } else {
- /* superuser mode */
- pte = va_kernel_present(addr);
- if (!pte && pte_kernel_write(pte))
- ret = 1;
- }
- return ret;
-}
-
-/*
- * All
- */
-void cpu_icache_inval_all(void)
-{
- unsigned long end, line_size;
-
- line_size = L1_cache_info[ICACHE].line_size;
- end =
- line_size * L1_cache_info[ICACHE].ways * L1_cache_info[ICACHE].sets;
-
- do {
- end -= line_size;
- __asm__ volatile ("\n\tcctl %0, L1I_IX_INVAL"::"r" (end));
- end -= line_size;
- __asm__ volatile ("\n\tcctl %0, L1I_IX_INVAL"::"r" (end));
- end -= line_size;
- __asm__ volatile ("\n\tcctl %0, L1I_IX_INVAL"::"r" (end));
- end -= line_size;
- __asm__ volatile ("\n\tcctl %0, L1I_IX_INVAL"::"r" (end));
- } while (end > 0);
- __nds32__isb();
-}
-
-void cpu_dcache_inval_all(void)
-{
- __nds32__cctl_l1d_invalall();
-}
-
-#ifdef CONFIG_CACHE_L2
-void dcache_wb_all_level(void)
-{
- unsigned long flags, cmd;
- local_irq_save(flags);
- __nds32__cctl_l1d_wball_alvl();
- /* Section 1: Ensure the section 2 & 3 program code execution after */
- __nds32__cctlidx_read(NDS32_CCTL_L1D_IX_RWD,0);
-
- /* Section 2: Confirm the writeback all level is done in CPU and L2C */
- cmd = CCTL_CMD_L2_SYNC;
- L2_CMD_RDY();
- L2C_W_REG(L2_CCTL_CMD_OFF, cmd);
- L2_CMD_RDY();
-
- /* Section 3: Writeback whole L2 cache */
- cmd = CCTL_ALL_CMD | CCTL_CMD_L2_IX_WB;
- L2_CMD_RDY();
- L2C_W_REG(L2_CCTL_CMD_OFF, cmd);
- L2_CMD_RDY();
- __nds32__msync_all();
- local_irq_restore(flags);
-}
-EXPORT_SYMBOL(dcache_wb_all_level);
-#endif
-
-void cpu_dcache_wb_all(void)
-{
- __nds32__cctl_l1d_wball_one_lvl();
- __nds32__cctlidx_read(NDS32_CCTL_L1D_IX_RWD,0);
-}
-
-void cpu_dcache_wbinval_all(void)
-{
-#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
- unsigned long flags;
- local_irq_save(flags);
-#endif
- cpu_dcache_wb_all();
- cpu_dcache_inval_all();
-#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
- local_irq_restore(flags);
-#endif
-}
-
-/*
- * Page
- */
-void cpu_icache_inval_page(unsigned long start)
-{
- unsigned long line_size, end;
-
- line_size = L1_cache_info[ICACHE].line_size;
- end = start + PAGE_SIZE;
-
- do {
- end -= line_size;
- __asm__ volatile ("\n\tcctl %0, L1I_VA_INVAL"::"r" (end));
- end -= line_size;
- __asm__ volatile ("\n\tcctl %0, L1I_VA_INVAL"::"r" (end));
- end -= line_size;
- __asm__ volatile ("\n\tcctl %0, L1I_VA_INVAL"::"r" (end));
- end -= line_size;
- __asm__ volatile ("\n\tcctl %0, L1I_VA_INVAL"::"r" (end));
- } while (end != start);
- __nds32__isb();
-}
-
-void cpu_dcache_inval_page(unsigned long start)
-{
- unsigned long line_size, end;
-
- line_size = L1_cache_info[DCACHE].line_size;
- end = start + PAGE_SIZE;
-
- do {
- end -= line_size;
- __asm__ volatile ("\n\tcctl %0, L1D_VA_INVAL"::"r" (end));
- end -= line_size;
- __asm__ volatile ("\n\tcctl %0, L1D_VA_INVAL"::"r" (end));
- end -= line_size;
- __asm__ volatile ("\n\tcctl %0, L1D_VA_INVAL"::"r" (end));
- end -= line_size;
- __asm__ volatile ("\n\tcctl %0, L1D_VA_INVAL"::"r" (end));
- } while (end != start);
-}
-
-void cpu_dcache_wb_page(unsigned long start)
-{
-#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
- unsigned long line_size, end;
-
- line_size = L1_cache_info[DCACHE].line_size;
- end = start + PAGE_SIZE;
-
- do {
- end -= line_size;
- __asm__ volatile ("\n\tcctl %0, L1D_VA_WB"::"r" (end));
- end -= line_size;
- __asm__ volatile ("\n\tcctl %0, L1D_VA_WB"::"r" (end));
- end -= line_size;
- __asm__ volatile ("\n\tcctl %0, L1D_VA_WB"::"r" (end));
- end -= line_size;
- __asm__ volatile ("\n\tcctl %0, L1D_VA_WB"::"r" (end));
- } while (end != start);
- __nds32__cctlidx_read(NDS32_CCTL_L1D_IX_RWD,0);
-#endif
-}
-
-void cpu_dcache_wbinval_page(unsigned long start)
-{
- unsigned long line_size, end;
-
- line_size = L1_cache_info[DCACHE].line_size;
- end = start + PAGE_SIZE;
-
- do {
- end -= line_size;
-#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
- __asm__ volatile ("\n\tcctl %0, L1D_VA_WB"::"r" (end));
-#endif
- __asm__ volatile ("\n\tcctl %0, L1D_VA_INVAL"::"r" (end));
- end -= line_size;
-#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
- __asm__ volatile ("\n\tcctl %0, L1D_VA_WB"::"r" (end));
-#endif
- __asm__ volatile ("\n\tcctl %0, L1D_VA_INVAL"::"r" (end));
- end -= line_size;
-#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
- __asm__ volatile ("\n\tcctl %0, L1D_VA_WB"::"r" (end));
-#endif
- __asm__ volatile ("\n\tcctl %0, L1D_VA_INVAL"::"r" (end));
- end -= line_size;
-#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
- __asm__ volatile ("\n\tcctl %0, L1D_VA_WB"::"r" (end));
-#endif
- __asm__ volatile ("\n\tcctl %0, L1D_VA_INVAL"::"r" (end));
- } while (end != start);
- __nds32__cctlidx_read(NDS32_CCTL_L1D_IX_RWD,0);
-}
-
-void cpu_cache_wbinval_page(unsigned long page, int flushi)
-{
- cpu_dcache_wbinval_page(page);
- if (flushi)
- cpu_icache_inval_page(page);
-}
-
-/*
- * Range
- */
-void cpu_icache_inval_range(unsigned long start, unsigned long end)
-{
- unsigned long line_size;
-
- line_size = L1_cache_info[ICACHE].line_size;
-
- while (end > start) {
- __asm__ volatile ("\n\tcctl %0, L1I_VA_INVAL"::"r" (start));
- start += line_size;
- }
- __nds32__isb();
-}
-
-void cpu_dcache_inval_range(unsigned long start, unsigned long end)
-{
- unsigned long line_size;
-
- line_size = L1_cache_info[DCACHE].line_size;
-
- while (end > start) {
- __asm__ volatile ("\n\tcctl %0, L1D_VA_INVAL"::"r" (start));
- start += line_size;
- }
-}
-
-void cpu_dcache_wb_range(unsigned long start, unsigned long end)
-{
-#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
- unsigned long line_size;
-
- line_size = L1_cache_info[DCACHE].line_size;
-
- while (end > start) {
- __asm__ volatile ("\n\tcctl %0, L1D_VA_WB"::"r" (start));
- start += line_size;
- }
- __nds32__cctlidx_read(NDS32_CCTL_L1D_IX_RWD,0);
-#endif
-}
-
-void cpu_dcache_wbinval_range(unsigned long start, unsigned long end)
-{
- unsigned long line_size;
-
- line_size = L1_cache_info[DCACHE].line_size;
-
- while (end > start) {
-#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
- __asm__ volatile ("\n\tcctl %0, L1D_VA_WB"::"r" (start));
-#endif
- __asm__ volatile ("\n\tcctl %0, L1D_VA_INVAL"::"r" (start));
- start += line_size;
- }
- __nds32__cctlidx_read(NDS32_CCTL_L1D_IX_RWD,0);
-}
-
-void cpu_cache_wbinval_range(unsigned long start, unsigned long end, int flushi)
-{
- unsigned long line_size, align_start, align_end;
-
- line_size = L1_cache_info[DCACHE].line_size;
- align_start = start & ~(line_size - 1);
- align_end = (end + line_size - 1) & ~(line_size - 1);
- cpu_dcache_wbinval_range(align_start, align_end);
-
- if (flushi) {
- line_size = L1_cache_info[ICACHE].line_size;
- align_start = start & ~(line_size - 1);
- align_end = (end + line_size - 1) & ~(line_size - 1);
- cpu_icache_inval_range(align_start, align_end);
- }
-}
-
-void cpu_cache_wbinval_range_check(struct vm_area_struct *vma,
- unsigned long start, unsigned long end,
- bool flushi, bool wbd)
-{
- unsigned long line_size, t_start, t_end;
-
- if (!flushi && !wbd)
- return;
- line_size = L1_cache_info[DCACHE].line_size;
- start = start & ~(line_size - 1);
- end = (end + line_size - 1) & ~(line_size - 1);
-
- if ((end - start) > (8 * PAGE_SIZE)) {
- if (wbd)
- cpu_dcache_wbinval_all();
- if (flushi)
- cpu_icache_inval_all();
- return;
- }
-
- t_start = (start + PAGE_SIZE) & PAGE_MASK;
- t_end = ((end - 1) & PAGE_MASK);
-
- if ((start & PAGE_MASK) == t_end) {
- if (va_present(vma->vm_mm, start)) {
- if (wbd)
- cpu_dcache_wbinval_range(start, end);
- if (flushi)
- cpu_icache_inval_range(start, end);
- }
- return;
- }
-
- if (va_present(vma->vm_mm, start)) {
- if (wbd)
- cpu_dcache_wbinval_range(start, t_start);
- if (flushi)
- cpu_icache_inval_range(start, t_start);
- }
-
- if (va_present(vma->vm_mm, end - 1)) {
- if (wbd)
- cpu_dcache_wbinval_range(t_end, end);
- if (flushi)
- cpu_icache_inval_range(t_end, end);
- }
-
- while (t_start < t_end) {
- if (va_present(vma->vm_mm, t_start)) {
- if (wbd)
- cpu_dcache_wbinval_page(t_start);
- if (flushi)
- cpu_icache_inval_page(t_start);
- }
- t_start += PAGE_SIZE;
- }
-}
-
-#ifdef CONFIG_CACHE_L2
-static inline void cpu_l2cache_op(unsigned long start, unsigned long end, unsigned long op)
-{
- if (atl2c_base) {
- unsigned long p_start = __pa(start);
- unsigned long p_end = __pa(end);
- unsigned long cmd;
- unsigned long line_size;
- /* TODO Can Use PAGE Mode to optimize if range large than PAGE_SIZE */
- line_size = L2_CACHE_LINE_SIZE();
- p_start = p_start & (~(line_size - 1));
- p_end = (p_end + line_size - 1) & (~(line_size - 1));
- cmd =
- (p_start & ~(line_size - 1)) | op |
- CCTL_SINGLE_CMD;
- do {
- L2_CMD_RDY();
- L2C_W_REG(L2_CCTL_CMD_OFF, cmd);
- cmd += line_size;
- p_start += line_size;
- } while (p_end > p_start);
- cmd = CCTL_CMD_L2_SYNC;
- L2_CMD_RDY();
- L2C_W_REG(L2_CCTL_CMD_OFF, cmd);
- L2_CMD_RDY();
- }
-}
-#else
-#define cpu_l2cache_op(start,end,op) do { } while (0)
-#endif
-/*
- * DMA
- */
-void cpu_dma_wb_range(unsigned long start, unsigned long end)
-{
- unsigned long line_size;
- unsigned long flags;
- line_size = L1_cache_info[DCACHE].line_size;
- start = start & (~(line_size - 1));
- end = (end + line_size - 1) & (~(line_size - 1));
- if (unlikely(start == end))
- return;
-
- local_irq_save(flags);
- cpu_dcache_wb_range(start, end);
- cpu_l2cache_op(start, end, CCTL_CMD_L2_PA_WB);
- __nds32__msync_all();
- local_irq_restore(flags);
-}
-
-void cpu_dma_inval_range(unsigned long start, unsigned long end)
-{
- unsigned long line_size;
- unsigned long old_start = start;
- unsigned long old_end = end;
- unsigned long flags;
- line_size = L1_cache_info[DCACHE].line_size;
- start = start & (~(line_size - 1));
- end = (end + line_size - 1) & (~(line_size - 1));
- if (unlikely(start == end))
- return;
- local_irq_save(flags);
- if (start != old_start) {
- cpu_dcache_wbinval_range(start, start + line_size);
- cpu_l2cache_op(start, start + line_size, CCTL_CMD_L2_PA_WBINVAL);
- }
- if (end != old_end) {
- cpu_dcache_wbinval_range(end - line_size, end);
- cpu_l2cache_op(end - line_size, end, CCTL_CMD_L2_PA_WBINVAL);
- }
- cpu_dcache_inval_range(start, end);
- cpu_l2cache_op(start, end, CCTL_CMD_L2_PA_INVAL);
- __nds32__msync_all();
- local_irq_restore(flags);
-
-}
-
-void cpu_dma_wbinval_range(unsigned long start, unsigned long end)
-{
- unsigned long line_size;
- unsigned long flags;
- line_size = L1_cache_info[DCACHE].line_size;
- start = start & (~(line_size - 1));
- end = (end + line_size - 1) & (~(line_size - 1));
- if (unlikely(start == end))
- return;
-
- local_irq_save(flags);
- cpu_dcache_wbinval_range(start, end);
- cpu_l2cache_op(start, end, CCTL_CMD_L2_PA_WBINVAL);
- __nds32__msync_all();
- local_irq_restore(flags);
-}
-
-void cpu_proc_init(void)
-{
-}
-
-void cpu_proc_fin(void)
-{
-}
-
-void cpu_do_idle(void)
-{
- __nds32__standby_no_wake_grant();
-}
-
-void cpu_reset(unsigned long reset)
-{
- u32 tmp;
- GIE_DISABLE();
- tmp = __nds32__mfsr(NDS32_SR_CACHE_CTL);
- tmp &= ~(CACHE_CTL_mskIC_EN | CACHE_CTL_mskDC_EN);
- __nds32__mtsr_isb(tmp, NDS32_SR_CACHE_CTL);
- cpu_dcache_wbinval_all();
- cpu_icache_inval_all();
-
- __asm__ __volatile__("jr.toff %0\n\t"::"r"(reset));
-}
-
-void cpu_switch_mm(struct mm_struct *mm)
-{
- unsigned long cid;
- cid = __nds32__mfsr(NDS32_SR_TLB_MISC);
- cid = (cid & ~TLB_MISC_mskCID) | mm->context.id;
- __nds32__mtsr_dsb(cid, NDS32_SR_TLB_MISC);
- __nds32__mtsr_isb(__pa(mm->pgd), NDS32_SR_L1_PPTB);
-}
diff --git a/arch/nds32/mm/tlb.c b/arch/nds32/mm/tlb.c
deleted file mode 100644
index dd41f5e0712f..000000000000
--- a/arch/nds32/mm/tlb.c
+++ /dev/null
@@ -1,50 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-// Copyright (C) 2005-2017 Andes Technology Corporation
-
-#include <linux/spinlock_types.h>
-#include <linux/mm.h>
-#include <linux/sched.h>
-#include <asm/nds32.h>
-#include <nds32_intrinsic.h>
-
-unsigned int cpu_last_cid = { TLB_MISC_mskCID + (2 << TLB_MISC_offCID) };
-
-DEFINE_SPINLOCK(cid_lock);
-
-void local_flush_tlb_range(struct vm_area_struct *vma,
- unsigned long start, unsigned long end)
-{
- unsigned long flags, ocid, ncid;
-
- if ((end - start) > 0x400000) {
- __nds32__tlbop_flua();
- __nds32__isb();
- return;
- }
-
- spin_lock_irqsave(&cid_lock, flags);
- ocid = __nds32__mfsr(NDS32_SR_TLB_MISC);
- ncid = (ocid & ~TLB_MISC_mskCID) | vma->vm_mm->context.id;
- __nds32__mtsr_dsb(ncid, NDS32_SR_TLB_MISC);
- while (start < end) {
- __nds32__tlbop_inv(start);
- __nds32__isb();
- start += PAGE_SIZE;
- }
- __nds32__mtsr_dsb(ocid, NDS32_SR_TLB_MISC);
- spin_unlock_irqrestore(&cid_lock, flags);
-}
-
-void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long addr)
-{
- unsigned long flags, ocid, ncid;
-
- spin_lock_irqsave(&cid_lock, flags);
- ocid = __nds32__mfsr(NDS32_SR_TLB_MISC);
- ncid = (ocid & ~TLB_MISC_mskCID) | vma->vm_mm->context.id;
- __nds32__mtsr_dsb(ncid, NDS32_SR_TLB_MISC);
- __nds32__tlbop_inv(addr);
- __nds32__isb();
- __nds32__mtsr_dsb(ocid, NDS32_SR_TLB_MISC);
- spin_unlock_irqrestore(&cid_lock, flags);
-}
diff --git a/arch/nios2/Kconfig b/arch/nios2/Kconfig
index 33fd06f5fa41..4167f1eb4cd8 100644
--- a/arch/nios2/Kconfig
+++ b/arch/nios2/Kconfig
@@ -24,7 +24,6 @@ config NIOS2
select USB_ARCH_HAS_HCD if USB_SUPPORT
select CPU_NO_EFFICIENT_FFS
select MMU_GATHER_NO_RANGE if MMU
- select SET_FS
config GENERIC_CSUM
def_bool y
diff --git a/arch/nios2/include/asm/pgtable.h b/arch/nios2/include/asm/pgtable.h
index 4a995fa628ee..262d0609268c 100644
--- a/arch/nios2/include/asm/pgtable.h
+++ b/arch/nios2/include/asm/pgtable.h
@@ -235,6 +235,7 @@ static inline void pte_clear(struct mm_struct *mm,
* and a page entry and page directory to the page they refer to.
*/
#define pmd_phys(pmd) virt_to_phys((void *)pmd_val(pmd))
+#define pmd_pfn(pmd) (pmd_phys(pmd) >> PAGE_SHIFT)
#define pmd_page(pmd) (pfn_to_page(pmd_phys(pmd) >> PAGE_SHIFT))
static inline unsigned long pmd_page_vaddr(pmd_t pmd)
diff --git a/arch/nios2/include/asm/thread_info.h b/arch/nios2/include/asm/thread_info.h
index 272d2c72a727..bcc0e9915ebd 100644
--- a/arch/nios2/include/asm/thread_info.h
+++ b/arch/nios2/include/asm/thread_info.h
@@ -26,10 +26,6 @@
#ifndef __ASSEMBLY__
-typedef struct {
- unsigned long seg;
-} mm_segment_t;
-
/*
* low level task data that entry.S needs immediate access to
* - this struct should fit entirely inside of one cache line
@@ -42,10 +38,6 @@ struct thread_info {
unsigned long flags; /* low level flags */
__u32 cpu; /* current CPU */
int preempt_count; /* 0 => preemptable,<0 => BUG */
- mm_segment_t addr_limit; /* thread address space:
- 0-0x7FFFFFFF for user-thead
- 0-0xFFFFFFFF for kernel-thread
- */
struct pt_regs *regs;
};
@@ -60,7 +52,6 @@ struct thread_info {
.flags = 0, \
.cpu = 0, \
.preempt_count = INIT_PREEMPT_COUNT, \
- .addr_limit = KERNEL_DS, \
}
/* how to get the thread information struct from C */
diff --git a/arch/nios2/include/asm/uaccess.h b/arch/nios2/include/asm/uaccess.h
index ba9340e96fd4..b8299082adbe 100644
--- a/arch/nios2/include/asm/uaccess.h
+++ b/arch/nios2/include/asm/uaccess.h
@@ -18,31 +18,10 @@
#include <asm/page.h>
#include <asm/extable.h>
-
-/*
- * Segment stuff
- */
-#define MAKE_MM_SEG(s) ((mm_segment_t) { (s) })
-#define USER_DS MAKE_MM_SEG(0x80000000UL)
-#define KERNEL_DS MAKE_MM_SEG(0)
-
-
-#define get_fs() (current_thread_info()->addr_limit)
-#define set_fs(seg) (current_thread_info()->addr_limit = (seg))
-
-#define uaccess_kernel() (get_fs().seg == KERNEL_DS.seg)
-
-#define __access_ok(addr, len) \
- (((signed long)(((long)get_fs().seg) & \
- ((long)(addr) | (((long)(addr)) + (len)) | (len)))) == 0)
-
-#define access_ok(addr, len) \
- likely(__access_ok((unsigned long)(addr), (unsigned long)(len)))
+#include <asm-generic/access_ok.h>
# define __EX_TABLE_SECTION ".section __ex_table,\"a\"\n"
-#define user_addr_max() (uaccess_kernel() ? ~0UL : TASK_SIZE)
-
/*
* Zero Userspace
*/
@@ -88,6 +67,7 @@ extern __must_check long strnlen_user(const char __user *s, long n);
/* Optimized macros */
#define __get_user_asm(val, insn, addr, err) \
{ \
+ unsigned long __gu_val; \
__asm__ __volatile__( \
" movi %0, %3\n" \
"1: " insn " %1, 0(%2)\n" \
@@ -96,14 +76,20 @@ extern __must_check long strnlen_user(const char __user *s, long n);
" .section __ex_table,\"a\"\n" \
" .word 1b, 2b\n" \
" .previous" \
- : "=&r" (err), "=r" (val) \
+ : "=&r" (err), "=r" (__gu_val) \
: "r" (addr), "i" (-EFAULT)); \
+ val = (__force __typeof__(*(addr)))__gu_val; \
}
-#define __get_user_unknown(val, size, ptr, err) do { \
+extern void __get_user_unknown(void);
+
+#define __get_user_8(val, ptr, err) do { \
+ u64 __val = 0; \
err = 0; \
- if (__copy_from_user(&(val), ptr, size)) { \
+ if (raw_copy_from_user(&(__val), ptr, sizeof(val))) { \
err = -EFAULT; \
+ } else { \
+ val = (typeof(val))(typeof((val) - (val)))__val; \
} \
} while (0)
@@ -119,8 +105,11 @@ do { \
case 4: \
__get_user_asm(val, "ldw", ptr, err); \
break; \
+ case 8: \
+ __get_user_8(val, ptr, err); \
+ break; \
default: \
- __get_user_unknown(val, size, ptr, err); \
+ __get_user_unknown(); \
break; \
} \
} while (0)
@@ -129,9 +118,7 @@ do { \
({ \
long __gu_err = -EFAULT; \
const __typeof__(*(ptr)) __user *__gu_ptr = (ptr); \
- unsigned long __gu_val = 0; \
- __get_user_common(__gu_val, sizeof(*(ptr)), __gu_ptr, __gu_err);\
- (x) = (__force __typeof__(x))__gu_val; \
+ __get_user_common(x, sizeof(*(ptr)), __gu_ptr, __gu_err); \
__gu_err; \
})
@@ -139,11 +126,9 @@ do { \
({ \
long __gu_err = -EFAULT; \
const __typeof__(*(ptr)) __user *__gu_ptr = (ptr); \
- unsigned long __gu_val = 0; \
if (access_ok( __gu_ptr, sizeof(*__gu_ptr))) \
- __get_user_common(__gu_val, sizeof(*__gu_ptr), \
+ __get_user_common(x, sizeof(*__gu_ptr), \
__gu_ptr, __gu_err); \
- (x) = (__force __typeof__(x))__gu_val; \
__gu_err; \
})
@@ -161,34 +146,44 @@ do { \
: "r" (val), "r" (ptr), "i" (-EFAULT)); \
}
-#define put_user(x, ptr) \
+#define __put_user_common(__pu_val, __pu_ptr) \
({ \
long __pu_err = -EFAULT; \
- __typeof__(*(ptr)) __user *__pu_ptr = (ptr); \
- __typeof__(*(ptr)) __pu_val = (__typeof(*ptr))(x); \
- if (access_ok(__pu_ptr, sizeof(*__pu_ptr))) { \
- switch (sizeof(*__pu_ptr)) { \
- case 1: \
- __put_user_asm(__pu_val, "stb", __pu_ptr, __pu_err); \
- break; \
- case 2: \
- __put_user_asm(__pu_val, "sth", __pu_ptr, __pu_err); \
- break; \
- case 4: \
- __put_user_asm(__pu_val, "stw", __pu_ptr, __pu_err); \
- break; \
- default: \
- /* XXX: This looks wrong... */ \
- __pu_err = 0; \
- if (copy_to_user(__pu_ptr, &(__pu_val), \
- sizeof(*__pu_ptr))) \
- __pu_err = -EFAULT; \
- break; \
- } \
+ switch (sizeof(*__pu_ptr)) { \
+ case 1: \
+ __put_user_asm(__pu_val, "stb", __pu_ptr, __pu_err); \
+ break; \
+ case 2: \
+ __put_user_asm(__pu_val, "sth", __pu_ptr, __pu_err); \
+ break; \
+ case 4: \
+ __put_user_asm(__pu_val, "stw", __pu_ptr, __pu_err); \
+ break; \
+ default: \
+ /* XXX: This looks wrong... */ \
+ __pu_err = 0; \
+ if (__copy_to_user(__pu_ptr, &(__pu_val), \
+ sizeof(*__pu_ptr))) \
+ __pu_err = -EFAULT; \
+ break; \
} \
__pu_err; \
})
-#define __put_user(x, ptr) put_user(x, ptr)
+#define __put_user(x, ptr) \
+({ \
+ __auto_type __pu_ptr = (ptr); \
+ typeof(*__pu_ptr) __pu_val = (typeof(*__pu_ptr))(x); \
+ __put_user_common(__pu_val, __pu_ptr); \
+})
+
+#define put_user(x, ptr) \
+({ \
+ __auto_type __pu_ptr = (ptr); \
+ typeof(*__pu_ptr) __pu_val = (typeof(*__pu_ptr))(x); \
+ access_ok(__pu_ptr, sizeof(*__pu_ptr)) ? \
+ __put_user_common(__pu_val, __pu_ptr) : \
+ -EFAULT; \
+})
#endif /* _ASM_NIOS2_UACCESS_H */
diff --git a/arch/nios2/kernel/signal.c b/arch/nios2/kernel/signal.c
index 2009ae2d3c3b..386e46443b60 100644
--- a/arch/nios2/kernel/signal.c
+++ b/arch/nios2/kernel/signal.c
@@ -36,10 +36,10 @@ struct rt_sigframe {
static inline int rt_restore_ucontext(struct pt_regs *regs,
struct switch_stack *sw,
- struct ucontext *uc, int *pr2)
+ struct ucontext __user *uc, int *pr2)
{
int temp;
- unsigned long *gregs = uc->uc_mcontext.gregs;
+ unsigned long __user *gregs = uc->uc_mcontext.gregs;
int err;
/* Always make any pending restarted system calls return -EINTR */
@@ -102,10 +102,11 @@ asmlinkage int do_rt_sigreturn(struct switch_stack *sw)
{
struct pt_regs *regs = (struct pt_regs *)(sw + 1);
/* Verify, can we follow the stack back */
- struct rt_sigframe *frame = (struct rt_sigframe *) regs->sp;
+ struct rt_sigframe __user *frame;
sigset_t set;
int rval;
+ frame = (struct rt_sigframe __user *) regs->sp;
if (!access_ok(frame, sizeof(*frame)))
goto badframe;
@@ -124,10 +125,10 @@ badframe:
return 0;
}
-static inline int rt_setup_ucontext(struct ucontext *uc, struct pt_regs *regs)
+static inline int rt_setup_ucontext(struct ucontext __user *uc, struct pt_regs *regs)
{
struct switch_stack *sw = (struct switch_stack *)regs - 1;
- unsigned long *gregs = uc->uc_mcontext.gregs;
+ unsigned long __user *gregs = uc->uc_mcontext.gregs;
int err = 0;
err |= __put_user(MCONTEXT_VERSION, &uc->uc_mcontext.version);
@@ -162,8 +163,9 @@ static inline int rt_setup_ucontext(struct ucontext *uc, struct pt_regs *regs)
return err;
}
-static inline void *get_sigframe(struct ksignal *ksig, struct pt_regs *regs,
- size_t frame_size)
+static inline void __user *get_sigframe(struct ksignal *ksig,
+ struct pt_regs *regs,
+ size_t frame_size)
{
unsigned long usp;
@@ -174,13 +176,13 @@ static inline void *get_sigframe(struct ksignal *ksig, struct pt_regs *regs,
usp = sigsp(usp, ksig);
/* Verify, is it 32 or 64 bit aligned */
- return (void *)((usp - frame_size) & -8UL);
+ return (void __user *)((usp - frame_size) & -8UL);
}
static int setup_rt_frame(struct ksignal *ksig, sigset_t *set,
struct pt_regs *regs)
{
- struct rt_sigframe *frame;
+ struct rt_sigframe __user *frame;
int err = 0;
frame = get_sigframe(ksig, regs, sizeof(*frame));
diff --git a/arch/openrisc/Kconfig b/arch/openrisc/Kconfig
index f724b3f1aeed..0d68adf6e02b 100644
--- a/arch/openrisc/Kconfig
+++ b/arch/openrisc/Kconfig
@@ -36,7 +36,6 @@ config OPENRISC
select ARCH_WANT_FRAME_POINTERS
select GENERIC_IRQ_MULTI_HANDLER
select MMU_GATHER_NO_RANGE if MMU
- select SET_FS
select TRACE_IRQFLAGS_SUPPORT
config CPU_BIG_ENDIAN
diff --git a/arch/openrisc/include/asm/pgtable.h b/arch/openrisc/include/asm/pgtable.h
index cdd657f80bfa..c3abbf71e09f 100644
--- a/arch/openrisc/include/asm/pgtable.h
+++ b/arch/openrisc/include/asm/pgtable.h
@@ -361,6 +361,7 @@ static inline void pmd_set(pmd_t *pmdp, pte_t *ptep)
pmd_val(*pmdp) = _KERNPG_TABLE | (unsigned long) ptep;
}
+#define pmd_pfn(pmd) (pmd_val(pmd) >> PAGE_SHIFT)
#define pmd_page(pmd) (pfn_to_page(pmd_val(pmd) >> PAGE_SHIFT))
static inline unsigned long pmd_page_vaddr(pmd_t pmd)
diff --git a/arch/openrisc/include/asm/thread_info.h b/arch/openrisc/include/asm/thread_info.h
index 659834ab87fa..4af3049c34c2 100644
--- a/arch/openrisc/include/asm/thread_info.h
+++ b/arch/openrisc/include/asm/thread_info.h
@@ -40,18 +40,12 @@
*/
#ifndef __ASSEMBLY__
-typedef unsigned long mm_segment_t;
-
struct thread_info {
struct task_struct *task; /* main task structure */
unsigned long flags; /* low level flags */
__u32 cpu; /* current CPU */
__s32 preempt_count; /* 0 => preemptable, <0 => BUG */
- mm_segment_t addr_limit; /* thread address space:
- 0-0x7FFFFFFF for user-thead
- 0-0xFFFFFFFF for kernel-thread
- */
__u8 supervisor_stack[0];
/* saved context data */
@@ -71,7 +65,6 @@ struct thread_info {
.flags = 0, \
.cpu = 0, \
.preempt_count = INIT_PREEMPT_COUNT, \
- .addr_limit = KERNEL_DS, \
.ksp = 0, \
}
diff --git a/arch/openrisc/include/asm/uaccess.h b/arch/openrisc/include/asm/uaccess.h
index 120f5005461b..d6500a374e18 100644
--- a/arch/openrisc/include/asm/uaccess.h
+++ b/arch/openrisc/include/asm/uaccess.h
@@ -22,44 +22,7 @@
#include <linux/string.h>
#include <asm/page.h>
#include <asm/extable.h>
-
-/*
- * The fs value determines whether argument validity checking should be
- * performed or not. If get_fs() == USER_DS, checking is performed, with
- * get_fs() == KERNEL_DS, checking is bypassed.
- *
- * For historical reasons, these macros are grossly misnamed.
- */
-
-/* addr_limit is the maximum accessible address for the task. we misuse
- * the KERNEL_DS and USER_DS values to both assign and compare the
- * addr_limit values through the equally misnamed get/set_fs macros.
- * (see above)
- */
-
-#define KERNEL_DS (~0UL)
-
-#define USER_DS (TASK_SIZE)
-#define get_fs() (current_thread_info()->addr_limit)
-#define set_fs(x) (current_thread_info()->addr_limit = (x))
-
-#define uaccess_kernel() (get_fs() == KERNEL_DS)
-
-/* Ensure that the range from addr to addr+size is all within the process'
- * address space
- */
-static inline int __range_ok(unsigned long addr, unsigned long size)
-{
- const mm_segment_t fs = get_fs();
-
- return size <= fs && addr <= (fs - size);
-}
-
-#define access_ok(addr, size) \
-({ \
- __chk_user_ptr(addr); \
- __range_ok((unsigned long)(addr), (size)); \
-})
+#include <asm-generic/access_ok.h>
/*
* These are the main single-value transfer routines. They automatically
@@ -268,9 +231,6 @@ clear_user(void __user *addr, unsigned long size)
return size;
}
-#define user_addr_max() \
- (uaccess_kernel() ? ~0UL : TASK_SIZE)
-
extern long strncpy_from_user(char *dest, const char __user *src, long count);
extern __must_check long strnlen_user(const char __user *str, long n);
diff --git a/arch/openrisc/mm/init.c b/arch/openrisc/mm/init.c
index 97305bde1b16..3a021ab6f1ae 100644
--- a/arch/openrisc/mm/init.c
+++ b/arch/openrisc/mm/init.c
@@ -38,8 +38,6 @@
int mem_init_done;
-DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
-
static void __init zone_sizes_init(void)
{
unsigned long max_zone_pfn[MAX_NR_ZONES] = { 0 };
diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig
index 43c1c880def6..00cb889bd9a6 100644
--- a/arch/parisc/Kconfig
+++ b/arch/parisc/Kconfig
@@ -1,6 +1,7 @@
# SPDX-License-Identifier: GPL-2.0
config PARISC
def_bool y
+ select ALTERNATE_USER_ADDRESS_SPACE
select ARCH_32BIT_OFF_T if !64BIT
select ARCH_MIGHT_HAVE_PC_PARPORT
select HAVE_FUNCTION_TRACER
@@ -10,10 +11,12 @@ config PARISC
select ARCH_HAS_ELF_RANDOMIZE
select ARCH_HAS_STRICT_KERNEL_RWX
select ARCH_HAS_UBSAN_SANITIZE_ALL
+ select ARCH_HAS_PTE_SPECIAL
select ARCH_NO_SG_CHAIN
select ARCH_SUPPORTS_HUGETLBFS if PA20
select ARCH_SUPPORTS_MEMORY_FAILURE
select ARCH_STACKWALK
+ select ARCH_HAS_DEBUG_VM_PGTABLE
select HAVE_RELIABLE_STACKTRACE
select DMA_OPS
select RTC_CLASS
@@ -259,18 +262,6 @@ config PARISC_PAGE_SIZE_64KB
endchoice
-config PARISC_SELF_EXTRACT
- bool "Build kernel as self-extracting executable"
- default y
- help
- Say Y if you want to build the parisc kernel as a kind of
- self-extracting executable.
-
- If you say N here, the kernel will be compressed with gzip
- which can be loaded by the palo bootloader directly too.
-
- If you don't know what to do here, say Y.
-
config SMP
bool "Symmetric multi-processing support"
help
diff --git a/arch/parisc/Makefile b/arch/parisc/Makefile
index 82d77f4b0d08..2a9387a93592 100644
--- a/arch/parisc/Makefile
+++ b/arch/parisc/Makefile
@@ -15,12 +15,8 @@
# Mike Shaver, Helge Deller and Martin K. Petersen
#
-ifdef CONFIG_PARISC_SELF_EXTRACT
boot := arch/parisc/boot
KBUILD_IMAGE := $(boot)/bzImage
-else
-KBUILD_IMAGE := vmlinuz
-endif
NM = sh $(srctree)/arch/parisc/nm
CHECKFLAGS += -D__hppa__=1
@@ -44,6 +40,16 @@ endif
export LD_BFD
+# Set default 32 bits cross compilers for vdso
+CC_ARCHES_32 = hppa hppa2.0 hppa1.1
+CC_SUFFIXES = linux linux-gnu unknown-linux-gnu
+CROSS32_COMPILE := $(call cc-cross-prefix, \
+ $(foreach a,$(CC_ARCHES_32), \
+ $(foreach s,$(CC_SUFFIXES),$(a)-$(s)-)))
+CROSS32CC := $(CROSS32_COMPILE)gcc
+export CROSS32CC
+
+# Set default cross compiler for kernel build
ifdef cross_compiling
ifeq ($(CROSS_COMPILE),)
CC_SUFFIXES = linux linux-gnu unknown-linux-gnu
@@ -155,14 +161,29 @@ Image: vmlinux
bzImage: vmlinux
$(Q)$(MAKE) $(build)=$(boot) $(boot)/$@
-ifdef CONFIG_PARISC_SELF_EXTRACT
vmlinuz: bzImage
$(OBJCOPY) $(boot)/bzImage $@
-else
-vmlinuz: vmlinux
- @$(KGZIP) -cf -9 $< > $@
+
+ifeq ($(KBUILD_EXTMOD),)
+# We need to generate vdso-offsets.h before compiling certain files in kernel/.
+# In order to do that, we should use the archprepare target, but we can't since
+# asm-offsets.h is included in some files used to generate vdso-offsets.h, and
+# asm-offsets.h is built in prepare0, for which archprepare is a dependency.
+# Therefore we need to generate the header after prepare0 has been made, hence
+# this hack.
+prepare: vdso_prepare
+vdso_prepare: prepare0
+ $(if $(CONFIG_64BIT),$(Q)$(MAKE) \
+ $(build)=arch/parisc/kernel/vdso64 include/generated/vdso64-offsets.h)
+ $(Q)$(MAKE) $(build)=arch/parisc/kernel/vdso32 include/generated/vdso32-offsets.h
endif
+PHONY += vdso_install
+
+vdso_install:
+ $(Q)$(MAKE) $(build)=arch/parisc/kernel/vdso $@
+ $(if $(CONFIG_COMPAT_VDSO), \
+ $(Q)$(MAKE) $(build)=arch/parisc/kernel/vdso32 $@)
install:
$(CONFIG_SHELL) $(srctree)/arch/parisc/install.sh \
$(KERNELRELEASE) vmlinux System.map "$(INSTALL_PATH)"
diff --git a/arch/parisc/configs/generic-32bit_defconfig b/arch/parisc/configs/generic-32bit_defconfig
index 53061cb2cf7f..a5fee10d76ee 100644
--- a/arch/parisc/configs/generic-32bit_defconfig
+++ b/arch/parisc/configs/generic-32bit_defconfig
@@ -210,7 +210,6 @@ CONFIG_TMPFS_XATTR=y
CONFIG_NFS_FS=m
# CONFIG_NFS_V2 is not set
CONFIG_NFSD=m
-CONFIG_NFSD_V3=y
CONFIG_CIFS=m
CONFIG_CIFS_XATTR=y
CONFIG_CIFS_POSIX=y
diff --git a/arch/parisc/include/asm/agp.h b/arch/parisc/include/asm/agp.h
index cb04470e63d0..14ae54cfd368 100644
--- a/arch/parisc/include/asm/agp.h
+++ b/arch/parisc/include/asm/agp.h
@@ -8,8 +8,8 @@
*
*/
-#define map_page_into_agp(page) /* nothing */
-#define unmap_page_from_agp(page) /* nothing */
+#define map_page_into_agp(page) do { } while (0)
+#define unmap_page_from_agp(page) do { } while (0)
#define flush_agp_cache() mb()
/* GATT allocation. Returns/accepts GATT kernel virtual address. */
diff --git a/arch/parisc/include/asm/assembly.h b/arch/parisc/include/asm/assembly.h
index 6369082c6c74..ea0cb318b13d 100644
--- a/arch/parisc/include/asm/assembly.h
+++ b/arch/parisc/include/asm/assembly.h
@@ -47,6 +47,12 @@
#define PRIV_USER 3
#define PRIV_KERNEL 0
+/* Space register used inside kernel */
+#define SR_KERNEL 0
+#define SR_TEMP1 1
+#define SR_TEMP2 2
+#define SR_USER 3
+
#ifdef __ASSEMBLY__
#ifdef CONFIG_64BIT
diff --git a/arch/parisc/include/asm/bitops.h b/arch/parisc/include/asm/bitops.h
index 0ec9cfc5131f..56ffd260c669 100644
--- a/arch/parisc/include/asm/bitops.h
+++ b/arch/parisc/include/asm/bitops.h
@@ -12,6 +12,14 @@
#include <asm/barrier.h>
#include <linux/atomic.h>
+/* compiler build environment sanity checks: */
+#if !defined(CONFIG_64BIT) && defined(__LP64__)
+#error "Please use 'ARCH=parisc' to build the 32-bit kernel."
+#endif
+#if defined(CONFIG_64BIT) && !defined(__LP64__)
+#error "Please use 'ARCH=parisc64' to build the 64-bit kernel."
+#endif
+
/* See http://marc.theaimsgroup.com/?t=108826637900003 for discussion
* on use of volatile and __*_bit() (set/clear/change):
* *_bit() want use of volatile.
diff --git a/arch/parisc/include/asm/cache.h b/arch/parisc/include/asm/cache.h
index d53e9e27dba0..5032e758594e 100644
--- a/arch/parisc/include/asm/cache.h
+++ b/arch/parisc/include/asm/cache.h
@@ -39,16 +39,13 @@ extern int icache_stride;
extern struct pdc_cache_info cache_info;
void parisc_setup_cache_timing(void);
-#define pdtlb(addr) asm volatile("pdtlb 0(%%sr1,%0)" \
+#define pdtlb(sr, addr) asm volatile("pdtlb 0(%%sr%0,%1)" \
ALTERNATIVE(ALT_COND_NO_SMP, INSN_PxTLB) \
- : : "r" (addr) : "memory")
-#define pitlb(addr) asm volatile("pitlb 0(%%sr1,%0)" \
+ : : "i"(sr), "r" (addr) : "memory")
+#define pitlb(sr, addr) asm volatile("pitlb 0(%%sr%0,%1)" \
ALTERNATIVE(ALT_COND_NO_SMP, INSN_PxTLB) \
ALTERNATIVE(ALT_COND_NO_SPLIT_TLB, INSN_NOP) \
- : : "r" (addr) : "memory")
-#define pdtlb_kernel(addr) asm volatile("pdtlb 0(%0)" \
- ALTERNATIVE(ALT_COND_NO_SMP, INSN_PxTLB) \
- : : "r" (addr) : "memory")
+ : : "i"(sr), "r" (addr) : "memory")
#define asm_io_fdc(addr) asm volatile("fdc %%r0(%0)" \
ALTERNATIVE(ALT_COND_NO_DCACHE, INSN_NOP) \
diff --git a/arch/parisc/include/asm/cacheflush.h b/arch/parisc/include/asm/cacheflush.h
index 859b8a34adcf..e8b4a03343d3 100644
--- a/arch/parisc/include/asm/cacheflush.h
+++ b/arch/parisc/include/asm/cacheflush.h
@@ -9,16 +9,11 @@
/* The usual comment is "Caches aren't brain-dead on the <architecture>".
* Unfortunately, that doesn't apply to PA-RISC. */
-/* Internal implementation */
-void flush_data_cache_local(void *); /* flushes local data-cache only */
-void flush_instruction_cache_local(void *); /* flushes local code-cache only */
-#ifdef CONFIG_SMP
-void flush_data_cache(void); /* flushes data-cache only (all processors) */
-void flush_instruction_cache(void); /* flushes i-cache only (all processors) */
-#else
-#define flush_data_cache() flush_data_cache_local(NULL)
-#define flush_instruction_cache() flush_instruction_cache_local(NULL)
-#endif
+#include <linux/jump_label.h>
+
+DECLARE_STATIC_KEY_TRUE(parisc_has_cache);
+DECLARE_STATIC_KEY_TRUE(parisc_has_dcache);
+DECLARE_STATIC_KEY_TRUE(parisc_has_icache);
#define flush_cache_dup_mm(mm) flush_cache_mm(mm)
diff --git a/arch/parisc/include/asm/current.h b/arch/parisc/include/asm/current.h
index 568b739e42af..dc7aea07c3f3 100644
--- a/arch/parisc/include/asm/current.h
+++ b/arch/parisc/include/asm/current.h
@@ -2,14 +2,16 @@
#ifndef _ASM_PARISC_CURRENT_H
#define _ASM_PARISC_CURRENT_H
-#include <asm/special_insns.h>
-
#ifndef __ASSEMBLY__
struct task_struct;
static __always_inline struct task_struct *get_current(void)
{
- return (struct task_struct *) mfctl(30);
+ struct task_struct *ts;
+
+ /* do not use mfctl() macro as it is marked volatile */
+ asm( "mfctl %%cr30,%0" : "=r" (ts) );
+ return ts;
}
#define current get_current()
diff --git a/arch/parisc/include/asm/elf.h b/arch/parisc/include/asm/elf.h
index 3bd465a27791..cc426d365892 100644
--- a/arch/parisc/include/asm/elf.h
+++ b/arch/parisc/include/asm/elf.h
@@ -359,4 +359,19 @@ struct mm_struct;
extern unsigned long arch_randomize_brk(struct mm_struct *);
#define arch_randomize_brk arch_randomize_brk
+
+#define ARCH_HAS_SETUP_ADDITIONAL_PAGES 1
+struct linux_binprm;
+extern int arch_setup_additional_pages(struct linux_binprm *bprm,
+ int executable_stack);
+#define VDSO_AUX_ENT(a, b) NEW_AUX_ENT(a, b)
+#define VDSO_CURRENT_BASE current->mm->context.vdso_base
+
+#define ARCH_DLINFO \
+do { \
+ if (VDSO_CURRENT_BASE) { \
+ NEW_AUX_ENT(AT_SYSINFO_EHDR, VDSO_CURRENT_BASE);\
+ } \
+} while (0)
+
#endif
diff --git a/arch/parisc/include/asm/futex.h b/arch/parisc/include/asm/futex.h
index b5835325d44b..3222206cb3ea 100644
--- a/arch/parisc/include/asm/futex.h
+++ b/arch/parisc/include/asm/futex.h
@@ -96,12 +96,6 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
u32 val;
unsigned long flags;
- /* futex.c wants to do a cmpxchg_inatomic on kernel NULL, which is
- * our gateway page, and causes no end of trouble...
- */
- if (uaccess_kernel() && !uaddr)
- return -EFAULT;
-
if (!access_ok(uaddr, sizeof(u32)))
return -EFAULT;
diff --git a/arch/parisc/include/asm/kprobes.h b/arch/parisc/include/asm/kprobes.h
index 904034da4974..0a175ac87698 100644
--- a/arch/parisc/include/asm/kprobes.h
+++ b/arch/parisc/include/asm/kprobes.h
@@ -18,8 +18,9 @@
#include <linux/notifier.h>
#define PARISC_KPROBES_BREAK_INSN 0x3ff801f
+#define PARISC_KPROBES_BREAK_INSN2 0x3ff801e
#define __ARCH_WANT_KPROBES_INSN_SLOT
-#define MAX_INSN_SIZE 1
+#define MAX_INSN_SIZE 2
typedef u32 kprobe_opcode_t;
struct kprobe;
@@ -29,7 +30,7 @@ void arch_remove_kprobe(struct kprobe *p);
#define flush_insn_slot(p) \
flush_icache_range((unsigned long)&(p)->ainsn.insn[0], \
(unsigned long)&(p)->ainsn.insn[0] + \
- sizeof(kprobe_opcode_t))
+ MAX_INSN_SIZE*sizeof(kprobe_opcode_t))
#define kretprobe_blacklist_size 0
diff --git a/arch/parisc/include/asm/mmu.h b/arch/parisc/include/asm/mmu.h
index 3fb70a601d5c..44fd062b62ed 100644
--- a/arch/parisc/include/asm/mmu.h
+++ b/arch/parisc/include/asm/mmu.h
@@ -2,7 +2,9 @@
#ifndef _PARISC_MMU_H_
#define _PARISC_MMU_H_
-/* On parisc, we store the space id here */
-typedef unsigned long mm_context_t;
+typedef struct {
+ unsigned long space_id;
+ unsigned long vdso_base;
+} mm_context_t;
#endif /* _PARISC_MMU_H_ */
diff --git a/arch/parisc/include/asm/mmu_context.h b/arch/parisc/include/asm/mmu_context.h
index 726257648d9f..c9187fe836a3 100644
--- a/arch/parisc/include/asm/mmu_context.h
+++ b/arch/parisc/include/asm/mmu_context.h
@@ -20,7 +20,7 @@ init_new_context(struct task_struct *tsk, struct mm_struct *mm)
{
BUG_ON(atomic_read(&mm->mm_users) != 1);
- mm->context = alloc_sid();
+ mm->context.space_id = alloc_sid();
return 0;
}
@@ -28,22 +28,22 @@ init_new_context(struct task_struct *tsk, struct mm_struct *mm)
static inline void
destroy_context(struct mm_struct *mm)
{
- free_sid(mm->context);
- mm->context = 0;
+ free_sid(mm->context.space_id);
+ mm->context.space_id = 0;
}
static inline unsigned long __space_to_prot(mm_context_t context)
{
#if SPACEID_SHIFT == 0
- return context << 1;
+ return context.space_id << 1;
#else
- return context >> (SPACEID_SHIFT - 1);
+ return context.space_id >> (SPACEID_SHIFT - 1);
#endif
}
static inline void load_context(mm_context_t context)
{
- mtsp(context, 3);
+ mtsp(context.space_id, SR_USER);
mtctl(__space_to_prot(context), 8);
}
@@ -89,8 +89,8 @@ static inline void activate_mm(struct mm_struct *prev, struct mm_struct *next)
BUG_ON(next == &init_mm); /* Should never happen */
- if (next->context == 0)
- next->context = alloc_sid();
+ if (next->context.space_id == 0)
+ next->context.space_id = alloc_sid();
switch_mm(prev,next,current);
}
diff --git a/arch/parisc/include/asm/pgtable.h b/arch/parisc/include/asm/pgtable.h
index 3e7cf882639f..939db6fe620b 100644
--- a/arch/parisc/include/asm/pgtable.h
+++ b/arch/parisc/include/asm/pgtable.h
@@ -70,9 +70,9 @@ static inline void purge_tlb_entries(struct mm_struct *mm, unsigned long addr)
unsigned long flags;
purge_tlb_start(flags);
- mtsp(mm->context, 1);
- pdtlb(addr);
- pitlb(addr);
+ mtsp(mm->context.space_id, SR_TEMP1);
+ pdtlb(SR_TEMP1, addr);
+ pitlb(SR_TEMP1, addr);
purge_tlb_end(flags);
}
@@ -219,9 +219,10 @@ extern void __update_cache(pte_t pte);
#define _PAGE_PRESENT (1 << xlate_pabit(_PAGE_PRESENT_BIT))
#define _PAGE_HUGE (1 << xlate_pabit(_PAGE_HPAGE_BIT))
#define _PAGE_USER (1 << xlate_pabit(_PAGE_USER_BIT))
+#define _PAGE_SPECIAL (_PAGE_DMB)
#define _PAGE_TABLE (_PAGE_PRESENT | _PAGE_READ | _PAGE_WRITE | _PAGE_DIRTY | _PAGE_ACCESSED)
-#define _PAGE_CHG_MASK (PAGE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY)
+#define _PAGE_CHG_MASK (PAGE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY | _PAGE_SPECIAL)
#define _PAGE_KERNEL_RO (_PAGE_PRESENT | _PAGE_READ | _PAGE_DIRTY | _PAGE_ACCESSED)
#define _PAGE_KERNEL_EXEC (_PAGE_KERNEL_RO | _PAGE_EXEC)
#define _PAGE_KERNEL_RWX (_PAGE_KERNEL_EXEC | _PAGE_WRITE)
@@ -348,6 +349,7 @@ static inline void pud_clear(pud_t *pud) {
static inline int pte_dirty(pte_t pte) { return pte_val(pte) & _PAGE_DIRTY; }
static inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED; }
static inline int pte_write(pte_t pte) { return pte_val(pte) & _PAGE_WRITE; }
+static inline int pte_special(pte_t pte) { return pte_val(pte) & _PAGE_SPECIAL; }
static inline pte_t pte_mkclean(pte_t pte) { pte_val(pte) &= ~_PAGE_DIRTY; return pte; }
static inline pte_t pte_mkold(pte_t pte) { pte_val(pte) &= ~_PAGE_ACCESSED; return pte; }
@@ -355,6 +357,7 @@ static inline pte_t pte_wrprotect(pte_t pte) { pte_val(pte) &= ~_PAGE_WRITE; ret
static inline pte_t pte_mkdirty(pte_t pte) { pte_val(pte) |= _PAGE_DIRTY; return pte; }
static inline pte_t pte_mkyoung(pte_t pte) { pte_val(pte) |= _PAGE_ACCESSED; return pte; }
static inline pte_t pte_mkwrite(pte_t pte) { pte_val(pte) |= _PAGE_WRITE; return pte; }
+static inline pte_t pte_mkspecial(pte_t pte) { pte_val(pte) |= _PAGE_SPECIAL; return pte; }
/*
* Huge pte definitions.
@@ -405,6 +408,7 @@ static inline unsigned long pmd_page_vaddr(pmd_t pmd)
return ((unsigned long) __va(pmd_address(pmd)));
}
+#define pmd_pfn(pmd) (pmd_address(pmd) >> PAGE_SHIFT)
#define __pmd_page(pmd) ((unsigned long) __va(pmd_address(pmd)))
#define pmd_page(pmd) virt_to_page((void *)__pmd_page(pmd))
diff --git a/arch/parisc/include/asm/processor.h b/arch/parisc/include/asm/processor.h
index 3a3d05438408..006364212795 100644
--- a/arch/parisc/include/asm/processor.h
+++ b/arch/parisc/include/asm/processor.h
@@ -236,7 +236,7 @@ on downward growing arches, it looks like this:
#define start_thread(regs, new_pc, new_sp) do { \
elf_addr_t *sp = (elf_addr_t *)new_sp; \
- __u32 spaceid = (__u32)current->mm->context; \
+ __u32 spaceid = (__u32)current->mm->context.space_id; \
elf_addr_t pc = (elf_addr_t)new_pc | 3; \
elf_caddr_t *argv = (elf_caddr_t *)bprm->exec + 1; \
\
diff --git a/arch/parisc/include/asm/rt_sigframe.h b/arch/parisc/include/asm/rt_sigframe.h
index 2b3010ade00e..bb7fb4153327 100644
--- a/arch/parisc/include/asm/rt_sigframe.h
+++ b/arch/parisc/include/asm/rt_sigframe.h
@@ -2,16 +2,8 @@
#ifndef _ASM_PARISC_RT_SIGFRAME_H
#define _ASM_PARISC_RT_SIGFRAME_H
-#define SIGRETURN_TRAMP 4
-#define SIGRESTARTBLOCK_TRAMP 5
-#define TRAMP_SIZE (SIGRETURN_TRAMP + SIGRESTARTBLOCK_TRAMP)
-
struct rt_sigframe {
- /* XXX: Must match trampoline size in arch/parisc/kernel/signal.c
- Secondary to that it must protect the ERESTART_RESTARTBLOCK
- trampoline we left on the stack (we were bad and didn't
- change sp so we could run really fast.) */
- unsigned int tramp[TRAMP_SIZE];
+ unsigned int tramp[2]; /* holds original return address */
struct siginfo info;
struct ucontext uc;
};
diff --git a/arch/parisc/include/asm/special_insns.h b/arch/parisc/include/asm/special_insns.h
index 16ee41e77174..41b3ddbd344c 100644
--- a/arch/parisc/include/asm/special_insns.h
+++ b/arch/parisc/include/asm/special_insns.h
@@ -55,8 +55,8 @@ static inline void set_eiem(unsigned long val)
#define mfsp(reg) ({ \
unsigned long cr; \
__asm__ __volatile__( \
- "mfsp " #reg ",%0" : \
- "=r" (cr) \
+ "mfsp %%sr%1,%0" \
+ : "=r" (cr) : "i"(reg) \
); \
cr; \
})
diff --git a/arch/parisc/include/asm/tlbflush.h b/arch/parisc/include/asm/tlbflush.h
index c5ded01d45be..5ffd7c17f593 100644
--- a/arch/parisc/include/asm/tlbflush.h
+++ b/arch/parisc/include/asm/tlbflush.h
@@ -17,7 +17,7 @@ int __flush_tlb_range(unsigned long sid,
unsigned long start, unsigned long end);
#define flush_tlb_range(vma, start, end) \
- __flush_tlb_range((vma)->vm_mm->context, start, end)
+ __flush_tlb_range((vma)->vm_mm->context.space_id, start, end)
#define flush_tlb_kernel_range(start, end) \
__flush_tlb_range(0, start, end)
diff --git a/arch/parisc/include/asm/traps.h b/arch/parisc/include/asm/traps.h
index 34619f010c63..0ccdb738a9a3 100644
--- a/arch/parisc/include/asm/traps.h
+++ b/arch/parisc/include/asm/traps.h
@@ -18,6 +18,7 @@ unsigned long parisc_acctyp(unsigned long code, unsigned int inst);
const char *trap_name(unsigned long code);
void do_page_fault(struct pt_regs *regs, unsigned long code,
unsigned long address);
+int handle_nadtlb_fault(struct pt_regs *regs);
#endif
#endif
diff --git a/arch/parisc/include/asm/uaccess.h b/arch/parisc/include/asm/uaccess.h
index ebf8a845b017..2bf660eabe42 100644
--- a/arch/parisc/include/asm/uaccess.h
+++ b/arch/parisc/include/asm/uaccess.h
@@ -11,15 +11,9 @@
#include <linux/bug.h>
#include <linux/string.h>
-/*
- * Note that since kernel addresses are in a separate address space on
- * parisc, we don't need to do anything for access_ok().
- * We just let the page fault handler do the right thing. This also means
- * that put_user is the same as __put_user, etc.
- */
-
-#define access_ok(uaddr, size) \
- ( (uaddr) == (uaddr) )
+#define TASK_SIZE_MAX DEFAULT_TASK_SIZE
+#include <asm/pgtable.h>
+#include <asm-generic/access_ok.h>
#define put_user __put_user
#define get_user __get_user
@@ -79,28 +73,27 @@ struct exception_table_entry {
#define __get_user(val, ptr) \
({ \
- __get_user_internal("%%sr3,", val, ptr); \
+ __get_user_internal(SR_USER, val, ptr); \
})
#define __get_user_asm(sr, val, ldx, ptr) \
{ \
register long __gu_val; \
\
- __asm__("1: " ldx " 0(" sr "%2),%0\n" \
+ __asm__("1: " ldx " 0(%%sr%2,%3),%0\n" \
"9:\n" \
ASM_EXCEPTIONTABLE_ENTRY_EFAULT(1b, 9b) \
- : "=r"(__gu_val), "=r"(__gu_err) \
- : "r"(ptr), "1"(__gu_err)); \
+ : "=r"(__gu_val), "+r"(__gu_err) \
+ : "i"(sr), "r"(ptr)); \
\
(val) = (__force __typeof__(*(ptr))) __gu_val; \
}
-#define HAVE_GET_KERNEL_NOFAULT
#define __get_kernel_nofault(dst, src, type, err_label) \
{ \
type __z; \
long __err; \
- __err = __get_user_internal("%%sr0,", __z, (type *)(src)); \
+ __err = __get_user_internal(SR_KERNEL, __z, (type *)(src)); \
if (unlikely(__err)) \
goto err_label; \
else \
@@ -118,13 +111,13 @@ struct exception_table_entry {
} __gu_tmp; \
\
__asm__(" copy %%r0,%R0\n" \
- "1: ldw 0(" sr "%2),%0\n" \
- "2: ldw 4(" sr "%2),%R0\n" \
+ "1: ldw 0(%%sr%2,%3),%0\n" \
+ "2: ldw 4(%%sr%2,%3),%R0\n" \
"9:\n" \
ASM_EXCEPTIONTABLE_ENTRY_EFAULT(1b, 9b) \
ASM_EXCEPTIONTABLE_ENTRY_EFAULT(2b, 9b) \
- : "=&r"(__gu_tmp.l), "=r"(__gu_err) \
- : "r"(ptr), "1"(__gu_err)); \
+ : "=&r"(__gu_tmp.l), "+r"(__gu_err) \
+ : "i"(sr), "r"(ptr)); \
\
(val) = __gu_tmp.t; \
}
@@ -135,13 +128,12 @@ struct exception_table_entry {
#define __put_user_internal(sr, x, ptr) \
({ \
ASM_EXCEPTIONTABLE_VAR(__pu_err); \
- __typeof__(*(ptr)) __x = (__typeof__(*(ptr)))(x); \
\
switch (sizeof(*(ptr))) { \
- case 1: __put_user_asm(sr, "stb", __x, ptr); break; \
- case 2: __put_user_asm(sr, "sth", __x, ptr); break; \
- case 4: __put_user_asm(sr, "stw", __x, ptr); break; \
- case 8: STD_USER(sr, __x, ptr); break; \
+ case 1: __put_user_asm(sr, "stb", x, ptr); break; \
+ case 2: __put_user_asm(sr, "sth", x, ptr); break; \
+ case 4: __put_user_asm(sr, "stw", x, ptr); break; \
+ case 8: STD_USER(sr, x, ptr); break; \
default: BUILD_BUG(); \
} \
\
@@ -150,14 +142,16 @@ struct exception_table_entry {
#define __put_user(x, ptr) \
({ \
- __put_user_internal("%%sr3,", x, ptr); \
+ __typeof__(&*(ptr)) __ptr = ptr; \
+ __typeof__(*(__ptr)) __x = (__typeof__(*(__ptr)))(x); \
+ __put_user_internal(SR_USER, __x, __ptr); \
})
#define __put_kernel_nofault(dst, src, type, err_label) \
{ \
type __z = *(type *)(src); \
long __err; \
- __err = __put_user_internal("%%sr0,", __z, (type *)(dst)); \
+ __err = __put_user_internal(SR_KERNEL, __z, (type *)(dst)); \
if (unlikely(__err)) \
goto err_label; \
}
@@ -177,24 +171,24 @@ struct exception_table_entry {
#define __put_user_asm(sr, stx, x, ptr) \
__asm__ __volatile__ ( \
- "1: " stx " %2,0(" sr "%1)\n" \
+ "1: " stx " %1,0(%%sr%2,%3)\n" \
"9:\n" \
ASM_EXCEPTIONTABLE_ENTRY_EFAULT(1b, 9b) \
- : "=r"(__pu_err) \
- : "r"(ptr), "r"(x), "0"(__pu_err))
+ : "+r"(__pu_err) \
+ : "r"(x), "i"(sr), "r"(ptr))
#if !defined(CONFIG_64BIT)
#define __put_user_asm64(sr, __val, ptr) do { \
__asm__ __volatile__ ( \
- "1: stw %2,0(" sr "%1)\n" \
- "2: stw %R2,4(" sr "%1)\n" \
+ "1: stw %1,0(%%sr%2,%3)\n" \
+ "2: stw %R1,4(%%sr%2,%3)\n" \
"9:\n" \
ASM_EXCEPTIONTABLE_ENTRY_EFAULT(1b, 9b) \
ASM_EXCEPTIONTABLE_ENTRY_EFAULT(2b, 9b) \
- : "=r"(__pu_err) \
- : "r"(ptr), "r"(__val), "0"(__pu_err)); \
+ : "+r"(__pu_err) \
+ : "r"(__val), "i"(sr), "r"(ptr)); \
} while (0)
#endif /* !defined(CONFIG_64BIT) */
diff --git a/arch/parisc/include/asm/unistd.h b/arch/parisc/include/asm/unistd.h
index cd438e4150f6..7708a5806f09 100644
--- a/arch/parisc/include/asm/unistd.h
+++ b/arch/parisc/include/asm/unistd.h
@@ -63,10 +63,6 @@
); \
__sys_res = (long)__res; \
} \
- if ( (unsigned long)__sys_res >= (unsigned long)-4095 ){ \
- errno = -__sys_res; \
- __sys_res = -1; \
- } \
__sys_res; \
})
diff --git a/arch/parisc/include/asm/vdso.h b/arch/parisc/include/asm/vdso.h
new file mode 100644
index 000000000000..ef8206193f82
--- /dev/null
+++ b/arch/parisc/include/asm/vdso.h
@@ -0,0 +1,24 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __PARISC_VDSO_H__
+#define __PARISC_VDSO_H__
+
+#ifndef __ASSEMBLY__
+
+#ifdef CONFIG_64BIT
+#include <generated/vdso64-offsets.h>
+#endif
+#include <generated/vdso32-offsets.h>
+
+#define VDSO64_SYMBOL(tsk, name) ((tsk)->mm->context.vdso_base + (vdso64_offset_##name))
+#define VDSO32_SYMBOL(tsk, name) ((tsk)->mm->context.vdso_base + (vdso32_offset_##name))
+
+extern struct vdso_data *vdso_data;
+
+#endif /* __ASSEMBLY __ */
+
+/* Default link addresses for the vDSOs */
+#define VDSO_LBASE 0
+
+#define VDSO_VERSION_STRING LINUX_5.18
+
+#endif /* __PARISC_VDSO_H__ */
diff --git a/arch/parisc/include/uapi/asm/auxvec.h b/arch/parisc/include/uapi/asm/auxvec.h
new file mode 100644
index 000000000000..90d2aa699cf3
--- /dev/null
+++ b/arch/parisc/include/uapi/asm/auxvec.h
@@ -0,0 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
+#ifndef _UAPI_PARISC_AUXVEC_H
+#define _UAPI_PARISC_AUXVEC_H
+
+/* The vDSO location. */
+#define AT_SYSINFO_EHDR 33
+
+#endif /* _UAPI_PARISC_AUXVEC_H */
diff --git a/arch/parisc/include/uapi/asm/shmbuf.h b/arch/parisc/include/uapi/asm/shmbuf.h
index 5da3089be65e..532da742fb56 100644
--- a/arch/parisc/include/uapi/asm/shmbuf.h
+++ b/arch/parisc/include/uapi/asm/shmbuf.h
@@ -3,6 +3,8 @@
#define _PARISC_SHMBUF_H
#include <asm/bitsperlong.h>
+#include <asm/ipcbuf.h>
+#include <asm/posix_types.h>
/*
* The shmid64_ds structure for parisc architecture.
diff --git a/arch/parisc/include/uapi/asm/signal.h b/arch/parisc/include/uapi/asm/signal.h
index e5a2657477ac..8e4895c5ea5d 100644
--- a/arch/parisc/include/uapi/asm/signal.h
+++ b/arch/parisc/include/uapi/asm/signal.h
@@ -67,7 +67,7 @@ struct siginfo;
typedef struct sigaltstack {
void __user *ss_sp;
int ss_flags;
- size_t ss_size;
+ __kernel_size_t ss_size;
} stack_t;
#endif /* !__ASSEMBLY */
diff --git a/arch/parisc/include/uapi/asm/socket.h b/arch/parisc/include/uapi/asm/socket.h
index 845ddc63c882..654061e0964e 100644
--- a/arch/parisc/include/uapi/asm/socket.h
+++ b/arch/parisc/include/uapi/asm/socket.h
@@ -125,6 +125,8 @@
#define SO_RESERVE_MEM 0x4047
+#define SO_TXREHASH 0x4048
+
#if !defined(__KERNEL__)
#if __BITS_PER_LONG == 64
diff --git a/arch/parisc/kernel/Makefile b/arch/parisc/kernel/Makefile
index 8fb819bbbb17..d579243edc2f 100644
--- a/arch/parisc/kernel/Makefile
+++ b/arch/parisc/kernel/Makefile
@@ -39,3 +39,8 @@ obj-$(CONFIG_KGDB) += kgdb.o
obj-$(CONFIG_KPROBES) += kprobes.o
obj-$(CONFIG_KEXEC_CORE) += kexec.o relocate_kernel.o
obj-$(CONFIG_KEXEC_FILE) += kexec_file.o
+
+# vdso
+obj-y += vdso.o
+obj-$(CONFIG_64BIT) += vdso64/
+obj-y += vdso32/
diff --git a/arch/parisc/kernel/alternative.c b/arch/parisc/kernel/alternative.c
index fa28c4c9f972..daa1e9047275 100644
--- a/arch/parisc/kernel/alternative.c
+++ b/arch/parisc/kernel/alternative.c
@@ -8,6 +8,7 @@
#include <asm/processor.h>
#include <asm/sections.h>
#include <asm/alternative.h>
+#include <asm/cacheflush.h>
#include <linux/module.h>
@@ -107,5 +108,14 @@ void __init apply_alternatives_all(void)
apply_alternatives((struct alt_instr *) &__alt_instructions,
(struct alt_instr *) &__alt_instructions_end, NULL);
+ if (cache_info.dc_size == 0 && cache_info.ic_size == 0) {
+ pr_info("alternatives: optimizing cache-flushes.\n");
+ static_branch_disable(&parisc_has_cache);
+ }
+ if (cache_info.dc_size == 0)
+ static_branch_disable(&parisc_has_dcache);
+ if (cache_info.ic_size == 0)
+ static_branch_disable(&parisc_has_icache);
+
set_kernel_text_rw(0);
}
diff --git a/arch/parisc/kernel/asm-offsets.c b/arch/parisc/kernel/asm-offsets.c
index 2a83ef36d216..2673d57eeb00 100644
--- a/arch/parisc/kernel/asm-offsets.c
+++ b/arch/parisc/kernel/asm-offsets.c
@@ -26,7 +26,11 @@
#include <asm/ptrace.h>
#include <asm/processor.h>
#include <asm/pdc.h>
+#include <uapi/asm/sigcontext.h>
+#include <asm/ucontext.h>
+#include <asm/rt_sigframe.h>
#include <linux/uaccess.h>
+#include "signal32.h"
/* Add FRAME_SIZE to the size x and align it to y. All definitions
* that use align_frame will include space for a frame.
@@ -218,6 +222,11 @@ int main(void)
DEFINE(TI_FLAGS, offsetof(struct thread_info, flags));
DEFINE(TI_PRE_COUNT, offsetof(struct task_struct, thread_info.preempt_count));
BLANK();
+ DEFINE(ASM_SIGFRAME_SIZE, PARISC_RT_SIGFRAME_SIZE);
+ DEFINE(SIGFRAME_CONTEXT_REGS, offsetof(struct rt_sigframe, uc.uc_mcontext) - PARISC_RT_SIGFRAME_SIZE);
+ DEFINE(ASM_SIGFRAME_SIZE32, PARISC_RT_SIGFRAME_SIZE32);
+ DEFINE(SIGFRAME_CONTEXT_REGS32, offsetof(struct compat_rt_sigframe, uc.uc_mcontext) - PARISC_RT_SIGFRAME_SIZE32);
+ BLANK();
DEFINE(ICACHE_BASE, offsetof(struct pdc_cache_info, ic_base));
DEFINE(ICACHE_STRIDE, offsetof(struct pdc_cache_info, ic_stride));
DEFINE(ICACHE_COUNT, offsetof(struct pdc_cache_info, ic_count));
diff --git a/arch/parisc/kernel/cache.c b/arch/parisc/kernel/cache.c
index 94150b91c96f..456e879d34a8 100644
--- a/arch/parisc/kernel/cache.c
+++ b/arch/parisc/kernel/cache.c
@@ -38,6 +38,9 @@ EXPORT_SYMBOL(flush_dcache_page_asm);
void purge_dcache_page_asm(unsigned long phys_addr, unsigned long vaddr);
void flush_icache_page_asm(unsigned long phys_addr, unsigned long vaddr);
+/* Internal implementation in arch/parisc/kernel/pacache.S */
+void flush_data_cache_local(void *); /* flushes local data-cache only */
+void flush_instruction_cache_local(void); /* flushes local code-cache only */
/* On some machines (i.e., ones with the Merced bus), there can be
* only a single PxTLB broadcast at a time; this must be guaranteed
@@ -58,26 +61,35 @@ struct pdc_cache_info cache_info __ro_after_init;
static struct pdc_btlb_info btlb_info __ro_after_init;
#endif
-#ifdef CONFIG_SMP
-void
-flush_data_cache(void)
+DEFINE_STATIC_KEY_TRUE(parisc_has_cache);
+DEFINE_STATIC_KEY_TRUE(parisc_has_dcache);
+DEFINE_STATIC_KEY_TRUE(parisc_has_icache);
+
+static void cache_flush_local_cpu(void *dummy)
{
- on_each_cpu(flush_data_cache_local, NULL, 1);
+ if (static_branch_likely(&parisc_has_icache))
+ flush_instruction_cache_local();
+ if (static_branch_likely(&parisc_has_dcache))
+ flush_data_cache_local(NULL);
}
-void
-flush_instruction_cache(void)
+
+void flush_cache_all_local(void)
{
- on_each_cpu(flush_instruction_cache_local, NULL, 1);
+ cache_flush_local_cpu(NULL);
}
-#endif
-void
-flush_cache_all_local(void)
+void flush_cache_all(void)
{
- flush_instruction_cache_local(NULL);
- flush_data_cache_local(NULL);
+ if (static_branch_likely(&parisc_has_cache))
+ on_each_cpu(cache_flush_local_cpu, NULL, 1);
}
-EXPORT_SYMBOL(flush_cache_all_local);
+
+static inline void flush_data_cache(void)
+{
+ if (static_branch_likely(&parisc_has_dcache))
+ on_each_cpu(flush_data_cache_local, NULL, 1);
+}
+
/* Virtual address of pfn. */
#define pfn_va(pfn) __va(PFN_PHYS(pfn))
@@ -303,6 +315,8 @@ static inline void
__flush_cache_page(struct vm_area_struct *vma, unsigned long vmaddr,
unsigned long physaddr)
{
+ if (!static_branch_likely(&parisc_has_cache))
+ return;
preempt_disable();
flush_dcache_page_asm(physaddr, vmaddr);
if (vma->vm_flags & VM_EXEC)
@@ -314,6 +328,8 @@ static inline void
__purge_cache_page(struct vm_area_struct *vma, unsigned long vmaddr,
unsigned long physaddr)
{
+ if (!static_branch_likely(&parisc_has_cache))
+ return;
preempt_disable();
purge_dcache_page_asm(physaddr, vmaddr);
if (vma->vm_flags & VM_EXEC)
@@ -375,7 +391,6 @@ EXPORT_SYMBOL(flush_dcache_page);
/* Defined in arch/parisc/kernel/pacache.S */
EXPORT_SYMBOL(flush_kernel_dcache_range_asm);
-EXPORT_SYMBOL(flush_data_cache_local);
EXPORT_SYMBOL(flush_kernel_icache_range_asm);
#define FLUSH_THRESHOLD 0x80000 /* 0.5MB */
@@ -388,7 +403,7 @@ void __init parisc_setup_cache_timing(void)
{
unsigned long rangetime, alltime;
unsigned long size;
- unsigned long threshold;
+ unsigned long threshold, threshold2;
alltime = mfctl(16);
flush_data_cache();
@@ -403,8 +418,20 @@ void __init parisc_setup_cache_timing(void)
alltime, size, rangetime);
threshold = L1_CACHE_ALIGN(size * alltime / rangetime);
- if (threshold > cache_info.dc_size)
- threshold = cache_info.dc_size;
+
+ /*
+ * The threshold computed above isn't very reliable since the
+ * flush times depend greatly on the percentage of dirty lines
+ * in the flush range. Further, the whole cache time doesn't
+ * include the time to refill lines that aren't in the mm/vma
+ * being flushed. By timing glibc build and checks on mako cpus,
+ * the following formula seems to work reasonably well. The
+ * value from the timing calculation is too small, and increases
+ * build and check times by almost a factor two.
+ */
+ threshold2 = cache_info.dc_size * num_online_cpus();
+ if (threshold2 > threshold)
+ threshold = threshold2;
if (threshold)
parisc_cache_flush_threshold = threshold;
printk(KERN_INFO "Cache flush threshold set to %lu KiB\n",
@@ -457,7 +484,7 @@ void flush_kernel_dcache_page_addr(void *addr)
flush_kernel_dcache_page_asm(addr);
purge_tlb_start(flags);
- pdtlb_kernel(addr);
+ pdtlb(SR_KERNEL, addr);
purge_tlb_end(flags);
}
EXPORT_SYMBOL(flush_kernel_dcache_page_addr);
@@ -496,25 +523,15 @@ int __flush_tlb_range(unsigned long sid, unsigned long start,
but cause a purge request to be broadcast to other TLBs. */
while (start < end) {
purge_tlb_start(flags);
- mtsp(sid, 1);
- pdtlb(start);
- pitlb(start);
+ mtsp(sid, SR_TEMP1);
+ pdtlb(SR_TEMP1, start);
+ pitlb(SR_TEMP1, start);
purge_tlb_end(flags);
start += PAGE_SIZE;
}
return 0;
}
-static void cacheflush_h_tmp_function(void *dummy)
-{
- flush_cache_all_local();
-}
-
-void flush_cache_all(void)
-{
- on_each_cpu(cacheflush_h_tmp_function, NULL, 1);
-}
-
static inline unsigned long mm_total_size(struct mm_struct *mm)
{
struct vm_area_struct *vma;
@@ -558,15 +575,6 @@ static void flush_cache_pages(struct vm_area_struct *vma, struct mm_struct *mm,
}
}
-static void flush_user_cache_tlb(struct vm_area_struct *vma,
- unsigned long start, unsigned long end)
-{
- flush_user_dcache_range_asm(start, end);
- if (vma->vm_flags & VM_EXEC)
- flush_user_icache_range_asm(start, end);
- flush_tlb_range(vma, start, end);
-}
-
void flush_cache_mm(struct mm_struct *mm)
{
struct vm_area_struct *vma;
@@ -575,23 +583,14 @@ void flush_cache_mm(struct mm_struct *mm)
rp3440, etc. So, avoid it if the mm isn't too big. */
if ((!IS_ENABLED(CONFIG_SMP) || !arch_irqs_disabled()) &&
mm_total_size(mm) >= parisc_cache_flush_threshold) {
- if (mm->context)
+ if (mm->context.space_id)
flush_tlb_all();
flush_cache_all();
return;
}
- preempt_disable();
- if (mm->context == mfsp(3)) {
- for (vma = mm->mmap; vma; vma = vma->vm_next)
- flush_user_cache_tlb(vma, vma->vm_start, vma->vm_end);
- preempt_enable();
- return;
- }
-
for (vma = mm->mmap; vma; vma = vma->vm_next)
flush_cache_pages(vma, mm, vma->vm_start, vma->vm_end);
- preempt_enable();
}
void flush_cache_range(struct vm_area_struct *vma,
@@ -599,29 +598,21 @@ void flush_cache_range(struct vm_area_struct *vma,
{
if ((!IS_ENABLED(CONFIG_SMP) || !arch_irqs_disabled()) &&
end - start >= parisc_cache_flush_threshold) {
- if (vma->vm_mm->context)
+ if (vma->vm_mm->context.space_id)
flush_tlb_range(vma, start, end);
flush_cache_all();
return;
}
- preempt_disable();
- if (vma->vm_mm->context == mfsp(3)) {
- flush_user_cache_tlb(vma, start, end);
- preempt_enable();
- return;
- }
-
- flush_cache_pages(vma, vma->vm_mm, vma->vm_start, vma->vm_end);
- preempt_enable();
+ flush_cache_pages(vma, vma->vm_mm, start, end);
}
void
flush_cache_page(struct vm_area_struct *vma, unsigned long vmaddr, unsigned long pfn)
{
if (pfn_valid(pfn)) {
- if (likely(vma->vm_mm->context)) {
- flush_tlb_page(vma, vmaddr);
+ flush_tlb_page(vma, vmaddr);
+ if (likely(vma->vm_mm->context.space_id)) {
__flush_cache_page(vma, vmaddr, PFN_PHYS(pfn));
} else {
__purge_cache_page(vma, vmaddr, PFN_PHYS(pfn));
@@ -633,6 +624,7 @@ void flush_kernel_vmap_range(void *vaddr, int size)
{
unsigned long start = (unsigned long)vaddr;
unsigned long end = start + size;
+ unsigned long flags, physaddr;
if ((!IS_ENABLED(CONFIG_SMP) || !arch_irqs_disabled()) &&
(unsigned long)size >= parisc_cache_flush_threshold) {
@@ -641,8 +633,14 @@ void flush_kernel_vmap_range(void *vaddr, int size)
return;
}
- flush_kernel_dcache_range_asm(start, end);
- flush_tlb_kernel_range(start, end);
+ while (start < end) {
+ physaddr = lpa(start);
+ purge_tlb_start(flags);
+ pdtlb(SR_KERNEL, start);
+ purge_tlb_end(flags);
+ flush_dcache_page_asm(physaddr, start);
+ start += PAGE_SIZE;
+ }
}
EXPORT_SYMBOL(flush_kernel_vmap_range);
@@ -650,6 +648,7 @@ void invalidate_kernel_vmap_range(void *vaddr, int size)
{
unsigned long start = (unsigned long)vaddr;
unsigned long end = start + size;
+ unsigned long flags, physaddr;
if ((!IS_ENABLED(CONFIG_SMP) || !arch_irqs_disabled()) &&
(unsigned long)size >= parisc_cache_flush_threshold) {
@@ -658,7 +657,13 @@ void invalidate_kernel_vmap_range(void *vaddr, int size)
return;
}
- purge_kernel_dcache_range_asm(start, end);
- flush_tlb_kernel_range(start, end);
+ while (start < end) {
+ physaddr = lpa(start);
+ purge_tlb_start(flags);
+ pdtlb(SR_KERNEL, start);
+ purge_tlb_end(flags);
+ purge_dcache_page_asm(physaddr, start);
+ start += PAGE_SIZE;
+ }
}
EXPORT_SYMBOL(invalidate_kernel_vmap_range);
diff --git a/arch/parisc/kernel/entry.S b/arch/parisc/kernel/entry.S
index 6e9cdb269862..ecf50159359e 100644
--- a/arch/parisc/kernel/entry.S
+++ b/arch/parisc/kernel/entry.S
@@ -1288,74 +1288,12 @@ nadtlb_check_alias_20:
nadtlb_emulate:
/*
- * Non access misses can be caused by fdc,fic,pdc,lpa,probe and
- * probei instructions. We don't want to fault for these
- * instructions (not only does it not make sense, it can cause
- * deadlocks, since some flushes are done with the mmap
- * semaphore held). If the translation doesn't exist, we can't
- * insert a translation, so have to emulate the side effects
- * of the instruction. Since we don't insert a translation
- * we can get a lot of faults during a flush loop, so it makes
- * sense to try to do it here with minimum overhead. We only
- * emulate fdc,fic,pdc,probew,prober instructions whose base
- * and index registers are not shadowed. We defer everything
- * else to the "slow" path.
+ * Non-access misses can be caused by fdc,fic,pdc,lpa,probe and
+ * probei instructions. The kernel no longer faults doing flushes.
+ * Use of lpa and probe instructions is rare. Given the issue
+ * with shadow registers, we defer everything to the "slow" path.
*/
-
- mfctl %cr19,%r9 /* Get iir */
-
- /* PA 2.0 Arch Ref. Book pg 382 has a good description of the insn bits.
- Checks for fdc,fdce,pdc,"fic,4f",prober,probeir,probew, probeiw */
-
- /* Checks for fdc,fdce,pdc,"fic,4f" only */
- ldi 0x280,%r16
- and %r9,%r16,%r17
- cmpb,<>,n %r16,%r17,nadtlb_probe_check
- bb,>=,n %r9,26,nadtlb_nullify /* m bit not set, just nullify */
- BL get_register,%r25
- extrw,u %r9,15,5,%r8 /* Get index register # */
- cmpib,COND(=),n -1,%r1,nadtlb_fault /* have to use slow path */
- copy %r1,%r24
- BL get_register,%r25
- extrw,u %r9,10,5,%r8 /* Get base register # */
- cmpib,COND(=),n -1,%r1,nadtlb_fault /* have to use slow path */
- BL set_register,%r25
- add,l %r1,%r24,%r1 /* doesn't affect c/b bits */
-
-nadtlb_nullify:
- mfctl %ipsw,%r8
- ldil L%PSW_N,%r9
- or %r8,%r9,%r8 /* Set PSW_N */
- mtctl %r8,%ipsw
-
- rfir
- nop
-
- /*
- When there is no translation for the probe address then we
- must nullify the insn and return zero in the target register.
- This will indicate to the calling code that it does not have
- write/read privileges to this address.
-
- This should technically work for prober and probew in PA 1.1,
- and also probe,r and probe,w in PA 2.0
-
- WARNING: USE ONLY NON-SHADOW REGISTERS WITH PROBE INSN!
- THE SLOW-PATH EMULATION HAS NOT BEEN WRITTEN YET.
-
- */
-nadtlb_probe_check:
- ldi 0x80,%r16
- and %r9,%r16,%r17
- cmpb,<>,n %r16,%r17,nadtlb_fault /* Must be probe,[rw]*/
- BL get_register,%r25 /* Find the target register */
- extrw,u %r9,31,5,%r8 /* Get target register */
- cmpib,COND(=),n -1,%r1,nadtlb_fault /* have to use slow path */
- BL set_register,%r25
- copy %r0,%r1 /* Write zero to target register */
- b nadtlb_nullify /* Nullify return insn */
- nop
-
+ b,n nadtlb_fault
#ifdef CONFIG_64BIT
itlb_miss_20w:
diff --git a/arch/parisc/kernel/kprobes.c b/arch/parisc/kernel/kprobes.c
index e2bdb5a5f93e..3343d2fb7889 100644
--- a/arch/parisc/kernel/kprobes.c
+++ b/arch/parisc/kernel/kprobes.c
@@ -5,6 +5,7 @@
* PA-RISC kprobes implementation
*
* Copyright (c) 2019 Sven Schnelle <svens@stackframe.org>
+ * Copyright (c) 2022 Helge Deller <deller@gmx.de>
*/
#include <linux/types.h>
@@ -25,9 +26,14 @@ int __kprobes arch_prepare_kprobe(struct kprobe *p)
if (!p->ainsn.insn)
return -ENOMEM;
- memcpy(p->ainsn.insn, p->addr,
- MAX_INSN_SIZE * sizeof(kprobe_opcode_t));
+ /*
+ * Set up new instructions. Second break instruction will
+ * trigger call of parisc_kprobe_ss_handler().
+ */
p->opcode = *p->addr;
+ p->ainsn.insn[0] = p->opcode;
+ p->ainsn.insn[1] = PARISC_KPROBES_BREAK_INSN2;
+
flush_insn_slot(p);
return 0;
}
@@ -73,9 +79,7 @@ static void __kprobes setup_singlestep(struct kprobe *p,
{
kcb->iaoq[0] = regs->iaoq[0];
kcb->iaoq[1] = regs->iaoq[1];
- regs->iaoq[0] = (unsigned long)p->ainsn.insn;
- mtctl(0, 0);
- regs->gr[0] |= PSW_R;
+ instruction_pointer_set(regs, (unsigned long)p->ainsn.insn);
}
int __kprobes parisc_kprobe_break_handler(struct pt_regs *regs)
@@ -165,9 +169,8 @@ int __kprobes parisc_kprobe_ss_handler(struct pt_regs *regs)
regs->iaoq[0] = kcb->iaoq[1];
break;
default:
- regs->iaoq[1] = kcb->iaoq[0];
- regs->iaoq[1] += (regs->iaoq[1] - regs->iaoq[0]) + 4;
regs->iaoq[0] = kcb->iaoq[1];
+ regs->iaoq[1] = regs->iaoq[0] + 4;
break;
}
kcb->kprobe_status = KPROBE_HIT_SSDONE;
@@ -191,14 +194,17 @@ static struct kprobe trampoline_p = {
static int __kprobes trampoline_probe_handler(struct kprobe *p,
struct pt_regs *regs)
{
- unsigned long orig_ret_address;
-
- orig_ret_address = __kretprobe_trampoline_handler(regs, NULL);
- instruction_pointer_set(regs, orig_ret_address);
+ __kretprobe_trampoline_handler(regs, NULL);
return 1;
}
+void arch_kretprobe_fixup_return(struct pt_regs *regs,
+ kprobe_opcode_t *correct_ret_addr)
+{
+ regs->gr[2] = (unsigned long)correct_ret_addr;
+}
+
void __kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri,
struct pt_regs *regs)
{
diff --git a/arch/parisc/kernel/pci-dma.c b/arch/parisc/kernel/pci-dma.c
index 36a57aa38e87..160996f2198e 100644
--- a/arch/parisc/kernel/pci-dma.c
+++ b/arch/parisc/kernel/pci-dma.c
@@ -91,7 +91,7 @@ static inline int map_pte_uncached(pte_t * pte,
printk(KERN_ERR "map_pte_uncached: page already exists\n");
purge_tlb_start(flags);
set_pte(pte, __mk_pte(*paddr_ptr, PAGE_KERNEL_UNC));
- pdtlb_kernel(orig_vaddr);
+ pdtlb(SR_KERNEL, orig_vaddr);
purge_tlb_end(flags);
vaddr += PAGE_SIZE;
orig_vaddr += PAGE_SIZE;
@@ -175,7 +175,7 @@ static inline void unmap_uncached_pte(pmd_t * pmd, unsigned long vaddr,
pte_clear(&init_mm, vaddr, pte);
purge_tlb_start(flags);
- pdtlb_kernel(orig_vaddr);
+ pdtlb(SR_KERNEL, orig_vaddr);
purge_tlb_end(flags);
vaddr += PAGE_SIZE;
orig_vaddr += PAGE_SIZE;
diff --git a/arch/parisc/kernel/signal.c b/arch/parisc/kernel/signal.c
index 46b1050640b8..3dd672e2e301 100644
--- a/arch/parisc/kernel/signal.c
+++ b/arch/parisc/kernel/signal.c
@@ -1,16 +1,13 @@
// SPDX-License-Identifier: GPL-2.0
/*
- * linux/arch/parisc/kernel/signal.c: Architecture-specific signal
- * handling support.
+ * PA-RISC architecture-specific signal handling support.
*
* Copyright (C) 2000 David Huggins-Daines <dhd@debian.org>
* Copyright (C) 2000 Linuxcare, Inc.
+ * Copyright (C) 2000-2022 Helge Deller <deller@gmx.de>
+ * Copyright (C) 2022 John David Anglin <dave.anglin@bell.net>
*
* Based on the ia64, i386, and alpha versions.
- *
- * Like the IA-64, we are a recent enough port (we are *starting*
- * with glibc2.2) that we do not need to support the old non-realtime
- * Linux signals. Therefore we don't.
*/
#include <linux/sched.h>
@@ -32,6 +29,7 @@
#include <linux/uaccess.h>
#include <asm/cacheflush.h>
#include <asm/asm-offsets.h>
+#include <asm/vdso.h>
#ifdef CONFIG_COMPAT
#include "signal32.h"
@@ -59,14 +57,6 @@
* Do a signal return - restore sigcontext.
*/
-/* Trampoline for calling rt_sigreturn() */
-#define INSN_LDI_R25_0 0x34190000 /* ldi 0,%r25 (in_syscall=0) */
-#define INSN_LDI_R25_1 0x34190002 /* ldi 1,%r25 (in_syscall=1) */
-#define INSN_LDI_R20 0x3414015a /* ldi __NR_rt_sigreturn,%r20 */
-#define INSN_BLE_SR2_R0 0xe4008200 /* be,l 0x100(%sr2,%r0),%sr0,%r31 */
-/* For debugging */
-#define INSN_DIE_HORRIBLY 0x68000ccc /* stw %r0,0x666(%sr0,%r0) */
-
static long
restore_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs)
{
@@ -77,9 +67,9 @@ restore_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs)
err |= __copy_from_user(regs->iaoq, sc->sc_iaoq, sizeof(regs->iaoq));
err |= __copy_from_user(regs->iasq, sc->sc_iasq, sizeof(regs->iasq));
err |= __get_user(regs->sar, &sc->sc_sar);
- DBG(2,"restore_sigcontext: iaoq is %#lx / %#lx\n",
- regs->iaoq[0],regs->iaoq[1]);
- DBG(2,"restore_sigcontext: r28 is %ld\n", regs->gr[28]);
+ DBG(2, "%s: iaoq is %#lx / %#lx\n",
+ __func__, regs->iaoq[0], regs->iaoq[1]);
+ DBG(2, "%s: r28 is %ld\n", __func__, regs->gr[28]);
return err;
}
@@ -102,7 +92,7 @@ sys_rt_sigreturn(struct pt_regs *regs, int in_syscall)
/* Unwind the user stack to get the rt_sigframe structure. */
frame = (struct rt_sigframe __user *)
(usp - sigframe_size);
- DBG(2,"sys_rt_sigreturn: frame is %p\n", frame);
+ DBG(2, "%s: frame is %p pid %d\n", __func__, frame, task_pid_nr(current));
regs->orig_r28 = 1; /* no restarts for sigreturn */
@@ -110,7 +100,6 @@ sys_rt_sigreturn(struct pt_regs *regs, int in_syscall)
compat_frame = (struct compat_rt_sigframe __user *)frame;
if (is_compat_task()) {
- DBG(2,"sys_rt_sigreturn: ELF32 process.\n");
if (get_compat_sigset(&set, &compat_frame->uc.uc_sigmask))
goto give_sigsegv;
} else
@@ -125,25 +114,25 @@ sys_rt_sigreturn(struct pt_regs *regs, int in_syscall)
/* Good thing we saved the old gr[30], eh? */
#ifdef CONFIG_64BIT
if (is_compat_task()) {
- DBG(1,"sys_rt_sigreturn: compat_frame->uc.uc_mcontext 0x%p\n",
- &compat_frame->uc.uc_mcontext);
+ DBG(1, "%s: compat_frame->uc.uc_mcontext 0x%p\n",
+ __func__, &compat_frame->uc.uc_mcontext);
// FIXME: Load upper half from register file
if (restore_sigcontext32(&compat_frame->uc.uc_mcontext,
&compat_frame->regs, regs))
goto give_sigsegv;
- DBG(1,"sys_rt_sigreturn: usp %#08lx stack 0x%p\n",
- usp, &compat_frame->uc.uc_stack);
+ DBG(1, "%s: usp %#08lx stack 0x%p\n",
+ __func__, usp, &compat_frame->uc.uc_stack);
if (compat_restore_altstack(&compat_frame->uc.uc_stack))
goto give_sigsegv;
} else
#endif
{
- DBG(1,"sys_rt_sigreturn: frame->uc.uc_mcontext 0x%p\n",
- &frame->uc.uc_mcontext);
+ DBG(1, "%s: frame->uc.uc_mcontext 0x%p\n",
+ __func__, &frame->uc.uc_mcontext);
if (restore_sigcontext(&frame->uc.uc_mcontext, regs))
goto give_sigsegv;
- DBG(1,"sys_rt_sigreturn: usp %#08lx stack 0x%p\n",
- usp, &frame->uc.uc_stack);
+ DBG(1, "%s: usp %#08lx stack 0x%p\n",
+ __func__, usp, &frame->uc.uc_stack);
if (restore_altstack(&frame->uc.uc_stack))
goto give_sigsegv;
}
@@ -155,14 +144,11 @@ sys_rt_sigreturn(struct pt_regs *regs, int in_syscall)
*/
if (in_syscall)
regs->gr[31] = regs->iaoq[0];
-#if DEBUG_SIG
- DBG(1,"sys_rt_sigreturn: returning to %#lx, DUMPING REGS:\n", regs->iaoq[0]);
- show_regs(regs);
-#endif
+
return;
give_sigsegv:
- DBG(1,"sys_rt_sigreturn: Sending SIGSEGV\n");
+ DBG(1, "%s: Sending SIGSEGV\n", __func__);
force_sig(SIGSEGV);
return;
}
@@ -177,15 +163,15 @@ get_sigframe(struct k_sigaction *ka, unsigned long sp, size_t frame_size)
/*FIXME: ELF32 vs. ELF64 has different frame_size, but since we
don't use the parameter it doesn't matter */
- DBG(1,"get_sigframe: ka = %#lx, sp = %#lx, frame_size = %#lx\n",
- (unsigned long)ka, sp, frame_size);
+ DBG(1, "%s: ka = %#lx, sp = %#lx, frame_size = %zu\n",
+ __func__, (unsigned long)ka, sp, frame_size);
/* Align alternate stack and reserve 64 bytes for the signal
handler's frame marker. */
if ((ka->sa.sa_flags & SA_ONSTACK) != 0 && ! sas_ss_flags(sp))
sp = (current->sas_ss_sp + 0x7f) & ~0x3f; /* Stacks grow up! */
- DBG(1,"get_sigframe: Returning sp = %#lx\n", (unsigned long)sp);
+ DBG(1, "%s: Returning sp = %#lx\n", __func__, (unsigned long)sp);
return (void __user *) sp; /* Stacks grow up. Fun. */
}
@@ -205,20 +191,20 @@ setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs, int in_sysc
err |= __put_user(regs->gr[31]+4, &sc->sc_iaoq[1]);
err |= __put_user(regs->sr[3], &sc->sc_iasq[0]);
err |= __put_user(regs->sr[3], &sc->sc_iasq[1]);
- DBG(1,"setup_sigcontext: iaoq %#lx / %#lx (in syscall)\n",
- regs->gr[31], regs->gr[31]+4);
+ DBG(1, "%s: iaoq %#lx / %#lx (in syscall)\n",
+ __func__, regs->gr[31], regs->gr[31]+4);
} else {
err |= __copy_to_user(sc->sc_iaoq, regs->iaoq, sizeof(regs->iaoq));
err |= __copy_to_user(sc->sc_iasq, regs->iasq, sizeof(regs->iasq));
- DBG(1,"setup_sigcontext: iaoq %#lx / %#lx (not in syscall)\n",
- regs->iaoq[0], regs->iaoq[1]);
+ DBG(1, "%s: iaoq %#lx / %#lx (not in syscall)\n",
+ __func__, regs->iaoq[0], regs->iaoq[1]);
}
err |= __put_user(flags, &sc->sc_flags);
err |= __copy_to_user(sc->sc_gr, regs->gr, sizeof(regs->gr));
err |= __copy_to_user(sc->sc_fr, regs->fr, sizeof(regs->fr));
err |= __put_user(regs->sar, &sc->sc_sar);
- DBG(1,"setup_sigcontext: r28 is %ld\n", regs->gr[28]);
+ DBG(1, "%s: r28 is %ld\n", __func__, regs->gr[28]);
return err;
}
@@ -230,7 +216,7 @@ setup_rt_frame(struct ksignal *ksig, sigset_t *set, struct pt_regs *regs,
struct rt_sigframe __user *frame;
unsigned long rp, usp;
unsigned long haddr, sigframe_size;
- unsigned long start, end;
+ unsigned long start;
int err = 0;
#ifdef CONFIG_64BIT
struct compat_rt_sigframe __user * compat_frame;
@@ -247,11 +233,10 @@ setup_rt_frame(struct ksignal *ksig, sigset_t *set, struct pt_regs *regs,
#endif
frame = get_sigframe(&ksig->ka, usp, sigframe_size);
- DBG(1,"SETUP_RT_FRAME: START\n");
- DBG(1,"setup_rt_frame: frame %p info %p\n", frame, ksig->info);
+ DBG(1, "%s: frame %p info %p\n", __func__, frame, &ksig->info);
start = (unsigned long) frame;
- if (start >= user_addr_max() - sigframe_size)
+ if (start >= TASK_SIZE_MAX - sigframe_size)
return -EFAULT;
#ifdef CONFIG_64BIT
@@ -259,11 +244,12 @@ setup_rt_frame(struct ksignal *ksig, sigset_t *set, struct pt_regs *regs,
compat_frame = (struct compat_rt_sigframe __user *)frame;
if (is_compat_task()) {
- DBG(1,"setup_rt_frame: frame->info = 0x%p\n", &compat_frame->info);
+ DBG(1, "%s: frame->info = 0x%p\n", __func__, &compat_frame->info);
err |= copy_siginfo_to_user32(&compat_frame->info, &ksig->info);
err |= __compat_save_altstack( &compat_frame->uc.uc_stack, regs->gr[30]);
- DBG(1,"setup_rt_frame: frame->uc = 0x%p\n", &compat_frame->uc);
- DBG(1,"setup_rt_frame: frame->uc.uc_mcontext = 0x%p\n", &compat_frame->uc.uc_mcontext);
+ DBG(1, "%s: frame->uc = 0x%p\n", __func__, &compat_frame->uc);
+ DBG(1, "%s: frame->uc.uc_mcontext = 0x%p\n",
+ __func__, &compat_frame->uc.uc_mcontext);
err |= setup_sigcontext32(&compat_frame->uc.uc_mcontext,
&compat_frame->regs, regs, in_syscall);
err |= put_compat_sigset(&compat_frame->uc.uc_sigmask, set,
@@ -271,11 +257,12 @@ setup_rt_frame(struct ksignal *ksig, sigset_t *set, struct pt_regs *regs,
} else
#endif
{
- DBG(1,"setup_rt_frame: frame->info = 0x%p\n", &frame->info);
+ DBG(1, "%s: frame->info = 0x%p\n", __func__, &frame->info);
err |= copy_siginfo_to_user(&frame->info, &ksig->info);
err |= __save_altstack(&frame->uc.uc_stack, regs->gr[30]);
- DBG(1,"setup_rt_frame: frame->uc = 0x%p\n", &frame->uc);
- DBG(1,"setup_rt_frame: frame->uc.uc_mcontext = 0x%p\n", &frame->uc.uc_mcontext);
+ DBG(1, "%s: frame->uc = 0x%p\n", __func__, &frame->uc);
+ DBG(1, "%s: frame->uc.uc_mcontext = 0x%p\n",
+ __func__, &frame->uc.uc_mcontext);
err |= setup_sigcontext(&frame->uc.uc_mcontext, regs, in_syscall);
/* FIXME: Should probably be converted as well for the compat case */
err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
@@ -284,32 +271,15 @@ setup_rt_frame(struct ksignal *ksig, sigset_t *set, struct pt_regs *regs,
if (err)
return -EFAULT;
- /* Set up to return from userspace. If provided, use a stub
- already in userspace. The first words of tramp are used to
- save the previous sigrestartblock trampoline that might be
- on the stack. We start the sigreturn trampoline at
- SIGRESTARTBLOCK_TRAMP+X. */
- err |= __put_user(in_syscall ? INSN_LDI_R25_1 : INSN_LDI_R25_0,
- &frame->tramp[SIGRESTARTBLOCK_TRAMP+0]);
- err |= __put_user(INSN_LDI_R20,
- &frame->tramp[SIGRESTARTBLOCK_TRAMP+1]);
- err |= __put_user(INSN_BLE_SR2_R0,
- &frame->tramp[SIGRESTARTBLOCK_TRAMP+2]);
- err |= __put_user(INSN_NOP, &frame->tramp[SIGRESTARTBLOCK_TRAMP+3]);
-
- start = (unsigned long) &frame->tramp[0];
- end = (unsigned long) &frame->tramp[TRAMP_SIZE];
- flush_user_dcache_range_asm(start, end);
- flush_user_icache_range_asm(start, end);
-
- /* TRAMP Words 0-4, Length 5 = SIGRESTARTBLOCK_TRAMP
- * TRAMP Words 5-9, Length 4 = SIGRETURN_TRAMP
- * So the SIGRETURN_TRAMP is at the end of SIGRESTARTBLOCK_TRAMP
- */
- rp = (unsigned long) &frame->tramp[SIGRESTARTBLOCK_TRAMP];
+#ifdef CONFIG_64BIT
+ if (!is_compat_task())
+ rp = VDSO64_SYMBOL(current, sigtramp_rt);
+ else
+#endif
+ rp = VDSO32_SYMBOL(current, sigtramp_rt);
- if (err)
- return -EFAULT;
+ if (in_syscall)
+ rp += 4*4; /* skip 4 instructions and start at ldi 1,%r25 */
haddr = A(ksig->ka.sa.sa_handler);
/* The sa_handler may be a pointer to a function descriptor */
@@ -340,8 +310,8 @@ setup_rt_frame(struct ksignal *ksig, sigset_t *set, struct pt_regs *regs,
haddr = fdesc.addr;
regs->gr[19] = fdesc.gp;
- DBG(1,"setup_rt_frame: 64 bit signal, exe=%#lx, r19=%#lx, in_syscall=%d\n",
- haddr, regs->gr[19], in_syscall);
+ DBG(1, "%s: 64 bit signal, exe=%#lx, r19=%#lx, in_syscall=%d\n",
+ __func__, haddr, regs->gr[19], in_syscall);
}
#endif
@@ -351,7 +321,7 @@ setup_rt_frame(struct ksignal *ksig, sigset_t *set, struct pt_regs *regs,
regs->gr[31] = haddr;
#ifdef CONFIG_64BIT
if (!test_thread_flag(TIF_32BIT))
- sigframe_size |= 1;
+ sigframe_size |= 1; /* XXX ???? */
#endif
} else {
unsigned long psw = USER_PSW;
@@ -373,11 +343,11 @@ setup_rt_frame(struct ksignal *ksig, sigset_t *set, struct pt_regs *regs,
}
regs->gr[0] = psw;
- regs->iaoq[0] = haddr | 3;
+ regs->iaoq[0] = haddr | PRIV_USER;
regs->iaoq[1] = regs->iaoq[0] + 4;
}
- regs->gr[2] = rp; /* userland return pointer */
+ regs->gr[2] = rp; /* userland return pointer */
regs->gr[26] = ksig->sig; /* signal number */
#ifdef CONFIG_64BIT
@@ -391,15 +361,15 @@ setup_rt_frame(struct ksignal *ksig, sigset_t *set, struct pt_regs *regs,
regs->gr[24] = A(&frame->uc); /* ucontext pointer */
}
- DBG(1,"setup_rt_frame: making sigreturn frame: %#lx + %#lx = %#lx\n",
+ DBG(1, "%s: making sigreturn frame: %#lx + %#lx = %#lx\n", __func__,
regs->gr[30], sigframe_size,
regs->gr[30] + sigframe_size);
/* Raise the user stack pointer to make a proper call frame. */
regs->gr[30] = (A(frame) + sigframe_size);
- DBG(1,"setup_rt_frame: sig deliver (%s,%d) frame=0x%p sp=%#lx iaoq=%#lx/%#lx rp=%#lx\n",
- current->comm, current->pid, frame, regs->gr[30],
+ DBG(1, "%s: sig deliver (%s,%d) frame=0x%p sp=%#lx iaoq=%#lx/%#lx rp=%#lx\n",
+ __func__, current->comm, current->pid, frame, regs->gr[30],
regs->iaoq[0], regs->iaoq[1], rp);
return 0;
@@ -415,8 +385,8 @@ handle_signal(struct ksignal *ksig, struct pt_regs *regs, int in_syscall)
int ret;
sigset_t *oldset = sigmask_to_save();
- DBG(1,"handle_signal: sig=%ld, ka=%p, info=%p, oldset=%p, regs=%p\n",
- ksig->sig, ksig->ka, ksig->info, oldset, regs);
+ DBG(1, "%s: sig=%d, ka=%p, info=%p, oldset=%p, regs=%p\n",
+ __func__, ksig->sig, &ksig->ka, &ksig->info, oldset, regs);
/* Set up the stack frame */
ret = setup_rt_frame(ksig, oldset, regs, in_syscall);
@@ -424,8 +394,8 @@ handle_signal(struct ksignal *ksig, struct pt_regs *regs, int in_syscall)
signal_setup_done(ret, ksig, test_thread_flag(TIF_SINGLESTEP) ||
test_thread_flag(TIF_BLOCKSTEP));
- DBG(1,KERN_DEBUG "do_signal: Exit (success), regs->gr[28] = %ld\n",
- regs->gr[28]);
+ DBG(1, "%s: Exit (success), regs->gr[28] = %ld\n",
+ __func__, regs->gr[28]);
}
/*
@@ -483,21 +453,27 @@ syscall_restart(struct pt_regs *regs, struct k_sigaction *ka)
if (regs->orig_r28)
return;
regs->orig_r28 = 1; /* no more restarts */
+
+ DBG(1, "%s: orig_r28 = %ld pid %d r20 %ld\n",
+ __func__, regs->orig_r28, task_pid_nr(current), regs->gr[20]);
+
/* Check the return code */
switch (regs->gr[28]) {
case -ERESTART_RESTARTBLOCK:
case -ERESTARTNOHAND:
- DBG(1,"ERESTARTNOHAND: returning -EINTR\n");
+ DBG(1, "%s: ERESTARTNOHAND: returning -EINTR\n", __func__);
regs->gr[28] = -EINTR;
break;
case -ERESTARTSYS:
if (!(ka->sa.sa_flags & SA_RESTART)) {
- DBG(1,"ERESTARTSYS: putting -EINTR\n");
+ DBG(1, "%s: ERESTARTSYS: putting -EINTR pid %d\n",
+ __func__, task_pid_nr(current));
regs->gr[28] = -EINTR;
break;
}
fallthrough;
case -ERESTARTNOINTR:
+ DBG(1, "%s: %ld\n", __func__, regs->gr[28]);
check_syscallno_in_delay_branch(regs);
break;
}
@@ -509,50 +485,52 @@ insert_restart_trampoline(struct pt_regs *regs)
if (regs->orig_r28)
return;
regs->orig_r28 = 1; /* no more restarts */
- switch(regs->gr[28]) {
+
+ DBG(2, "%s: gr28 = %ld pid %d\n",
+ __func__, regs->gr[28], task_pid_nr(current));
+
+ switch (regs->gr[28]) {
case -ERESTART_RESTARTBLOCK: {
/* Restart the system call - no handlers present */
unsigned int *usp = (unsigned int *)regs->gr[30];
- unsigned long start = (unsigned long) &usp[2];
- unsigned long end = (unsigned long) &usp[5];
+ unsigned long rp;
long err = 0;
/* check that we don't exceed the stack */
- if (A(&usp[0]) >= user_addr_max() - 5 * sizeof(int))
+ if (A(&usp[0]) >= TASK_SIZE_MAX - 5 * sizeof(int))
return;
- /* Setup a trampoline to restart the syscall
- * with __NR_restart_syscall
+ /* Call trampoline in vdso to restart the syscall
+ * with __NR_restart_syscall.
+ * Original return addresses are on stack like this:
*
* 0: <return address (orig r31)>
* 4: <2nd half for 64-bit>
- * 8: ldw 0(%sp), %r31
- * 12: be 0x100(%sr2, %r0)
- * 16: ldi __NR_restart_syscall, %r20
*/
#ifdef CONFIG_64BIT
- err |= put_user(regs->gr[31] >> 32, &usp[0]);
- err |= put_user(regs->gr[31] & 0xffffffff, &usp[1]);
- err |= put_user(0x0fc010df, &usp[2]);
-#else
- err |= put_user(regs->gr[31], &usp[0]);
- err |= put_user(0x0fc0109f, &usp[2]);
+ if (!is_compat_task()) {
+ err |= put_user(regs->gr[31] >> 32, &usp[0]);
+ err |= put_user(regs->gr[31] & 0xffffffff, &usp[1]);
+ rp = VDSO64_SYMBOL(current, restart_syscall);
+ } else
#endif
- err |= put_user(0xe0008200, &usp[3]);
- err |= put_user(0x34140000, &usp[4]);
-
+ {
+ err |= put_user(regs->gr[31], &usp[0]);
+ rp = VDSO32_SYMBOL(current, restart_syscall);
+ }
WARN_ON(err);
- /* flush data/instruction cache for new insns */
- flush_user_dcache_range_asm(start, end);
- flush_user_icache_range_asm(start, end);
-
- regs->gr[31] = regs->gr[30] + 8;
+ regs->gr[31] = rp;
+ DBG(1, "%s: ERESTART_RESTARTBLOCK\n", __func__);
return;
}
+ case -EINTR:
+ /* ok, was handled before and should be returned. */
+ break;
case -ERESTARTNOHAND:
case -ERESTARTSYS:
case -ERESTARTNOINTR:
+ DBG(1, "%s: Type %ld\n", __func__, regs->gr[28]);
check_syscallno_in_delay_branch(regs);
return;
default:
@@ -567,30 +545,35 @@ insert_restart_trampoline(struct pt_regs *regs)
* registers). As noted below, the syscall number gets restored for
* us due to the magic of delayed branching.
*/
-asmlinkage void
-do_signal(struct pt_regs *regs, long in_syscall)
+static void do_signal(struct pt_regs *regs, long in_syscall)
{
struct ksignal ksig;
+ int restart_syscall;
+ bool has_handler;
- DBG(1,"\ndo_signal: regs=0x%p, sr7 %#lx, in_syscall=%d\n",
- regs, regs->sr[7], in_syscall);
+ has_handler = get_signal(&ksig);
- if (get_signal(&ksig)) {
- DBG(3,"do_signal: signr = %d, regs->gr[28] = %ld\n", signr, regs->gr[28]);
+ restart_syscall = 0;
+ if (in_syscall)
+ restart_syscall = 1;
+
+ if (has_handler) {
/* Restart a system call if necessary. */
- if (in_syscall)
+ if (restart_syscall)
syscall_restart(regs, &ksig.ka);
handle_signal(&ksig, regs, in_syscall);
+ DBG(1, "%s: Handled signal pid %d\n",
+ __func__, task_pid_nr(current));
return;
}
- /* Did we come from a system call? */
- if (in_syscall)
+ /* Do we need to restart the system call? */
+ if (restart_syscall)
insert_restart_trampoline(regs);
- DBG(1,"do_signal: Exit (not delivered), regs->gr[28] = %ld\n",
- regs->gr[28]);
+ DBG(1, "%s: Exit (not delivered), regs->gr[28] = %ld orig_r28 = %ld pid %d\n",
+ __func__, regs->gr[28], regs->orig_r28, task_pid_nr(current));
restore_saved_sigmask();
}
diff --git a/arch/parisc/kernel/signal32.h b/arch/parisc/kernel/signal32.h
index f166250f2d06..c03eb1ed4c53 100644
--- a/arch/parisc/kernel/signal32.h
+++ b/arch/parisc/kernel/signal32.h
@@ -36,21 +36,12 @@ struct compat_regfile {
compat_int_t rf_sar;
};
-#define COMPAT_SIGRETURN_TRAMP 4
-#define COMPAT_SIGRESTARTBLOCK_TRAMP 5
-#define COMPAT_TRAMP_SIZE (COMPAT_SIGRETURN_TRAMP + \
- COMPAT_SIGRESTARTBLOCK_TRAMP)
-
struct compat_rt_sigframe {
- /* XXX: Must match trampoline size in arch/parisc/kernel/signal.c
- Secondary to that it must protect the ERESTART_RESTARTBLOCK
- trampoline we left on the stack (we were bad and didn't
- change sp so we could run really fast.) */
- compat_uint_t tramp[COMPAT_TRAMP_SIZE];
- compat_siginfo_t info;
- struct compat_ucontext uc;
- /* Hidden location of truncated registers, *must* be last. */
- struct compat_regfile regs;
+ unsigned int tramp[2]; /* holds original return address */
+ compat_siginfo_t info;
+ struct compat_ucontext uc;
+ /* Hidden location of truncated registers, *must* be last. */
+ struct compat_regfile regs;
};
/*
diff --git a/arch/parisc/kernel/topology.c b/arch/parisc/kernel/topology.c
index 0a10e4ddc528..e88a6ce7c96d 100644
--- a/arch/parisc/kernel/topology.c
+++ b/arch/parisc/kernel/topology.c
@@ -101,8 +101,8 @@ void __init store_cpu_topology(unsigned int cpuid)
update_siblings_masks(cpuid);
- pr_info("CPU%u: thread %d, cpu %d, socket %d\n",
- cpuid, cpu_topology[cpuid].thread_id,
+ pr_info("CPU%u: cpu core %d of socket %d\n",
+ cpuid,
cpu_topology[cpuid].core_id,
cpu_topology[cpuid].socket_id);
}
diff --git a/arch/parisc/kernel/traps.c b/arch/parisc/kernel/traps.c
index b6fdebddc8e9..a6e61cf2cad0 100644
--- a/arch/parisc/kernel/traps.c
+++ b/arch/parisc/kernel/traps.c
@@ -302,7 +302,10 @@ static void handle_break(struct pt_regs *regs)
parisc_kprobe_break_handler(regs);
return;
}
-
+ if (unlikely(iir == PARISC_KPROBES_BREAK_INSN2)) {
+ parisc_kprobe_ss_handler(regs);
+ return;
+ }
#endif
#ifdef CONFIG_KGDB
@@ -539,11 +542,6 @@ void notrace handle_interruption(int code, struct pt_regs *regs)
/* Recovery counter trap */
regs->gr[0] &= ~PSW_R;
-#ifdef CONFIG_KPROBES
- if (parisc_kprobe_ss_handler(regs))
- return;
-#endif
-
#ifdef CONFIG_KGDB
if (kgdb_single_step) {
kgdb_handle_exception(0, SIGTRAP, 0, regs);
@@ -662,6 +660,8 @@ void notrace handle_interruption(int code, struct pt_regs *regs)
by hand. Technically we need to emulate:
fdc,fdce,pdc,"fic,4f",prober,probeir,probew, probeiw
*/
+ if (code == 17 && handle_nadtlb_fault(regs))
+ return;
fault_address = regs->ior;
fault_space = regs->isr;
break;
diff --git a/arch/parisc/kernel/unaligned.c b/arch/parisc/kernel/unaligned.c
index 237d20dd5622..ed1e88a74dc4 100644
--- a/arch/parisc/kernel/unaligned.c
+++ b/arch/parisc/kernel/unaligned.c
@@ -3,14 +3,11 @@
* Unaligned memory access handler
*
* Copyright (C) 2001 Randolph Chung <tausq@debian.org>
+ * Copyright (C) 2022 Helge Deller <deller@gmx.de>
* Significantly tweaked by LaMont Jones <lamont@debian.org>
*/
-#include <linux/jiffies.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
#include <linux/sched/signal.h>
-#include <linux/sched/debug.h>
#include <linux/signal.h>
#include <linux/ratelimit.h>
#include <linux/uaccess.h>
@@ -25,18 +22,7 @@
#define DPRINTF(fmt, args...)
#endif
-#ifdef CONFIG_64BIT
-#define RFMT "%016lx"
-#else
-#define RFMT "%08lx"
-#endif
-
-#define FIXUP_BRANCH(lbl) \
- "\tldil L%%" #lbl ", %%r1\n" \
- "\tldo R%%" #lbl "(%%r1), %%r1\n" \
- "\tbv,n %%r0(%%r1)\n"
-/* If you use FIXUP_BRANCH, then you must list this clobber */
-#define FIXUP_BRANCH_CLOBBER "r1"
+#define RFMT "%#08lx"
/* 1111 1100 0000 0000 0001 0011 1100 0000 */
#define OPCODE1(a,b,c) ((a)<<26|(b)<<12|(c)<<6)
@@ -114,37 +100,30 @@
#define IM14(i) IM((i),14)
#define ERR_NOTHANDLED -1
-#define ERR_PAGEFAULT -2
int unaligned_enabled __read_mostly = 1;
static int emulate_ldh(struct pt_regs *regs, int toreg)
{
unsigned long saddr = regs->ior;
- unsigned long val = 0;
- int ret;
+ unsigned long val = 0, temp1;
+ ASM_EXCEPTIONTABLE_VAR(ret);
DPRINTF("load " RFMT ":" RFMT " to r%d for 2 bytes\n",
regs->isr, regs->ior, toreg);
__asm__ __volatile__ (
" mtsp %4, %%sr1\n"
-"1: ldbs 0(%%sr1,%3), %%r20\n"
+"1: ldbs 0(%%sr1,%3), %2\n"
"2: ldbs 1(%%sr1,%3), %0\n"
-" depw %%r20, 23, 24, %0\n"
-" copy %%r0, %1\n"
+" depw %2, 23, 24, %0\n"
"3: \n"
-" .section .fixup,\"ax\"\n"
-"4: ldi -2, %1\n"
- FIXUP_BRANCH(3b)
-" .previous\n"
- ASM_EXCEPTIONTABLE_ENTRY(1b, 4b)
- ASM_EXCEPTIONTABLE_ENTRY(2b, 4b)
- : "=r" (val), "=r" (ret)
- : "0" (val), "r" (saddr), "r" (regs->isr)
- : "r20", FIXUP_BRANCH_CLOBBER );
+ ASM_EXCEPTIONTABLE_ENTRY_EFAULT(1b, 3b)
+ ASM_EXCEPTIONTABLE_ENTRY_EFAULT(2b, 3b)
+ : "+r" (val), "+r" (ret), "=&r" (temp1)
+ : "r" (saddr), "r" (regs->isr) );
- DPRINTF("val = 0x" RFMT "\n", val);
+ DPRINTF("val = " RFMT "\n", val);
if (toreg)
regs->gr[toreg] = val;
@@ -155,34 +134,28 @@ static int emulate_ldh(struct pt_regs *regs, int toreg)
static int emulate_ldw(struct pt_regs *regs, int toreg, int flop)
{
unsigned long saddr = regs->ior;
- unsigned long val = 0;
- int ret;
+ unsigned long val = 0, temp1, temp2;
+ ASM_EXCEPTIONTABLE_VAR(ret);
DPRINTF("load " RFMT ":" RFMT " to r%d for 4 bytes\n",
regs->isr, regs->ior, toreg);
__asm__ __volatile__ (
-" zdep %3,28,2,%%r19\n" /* r19=(ofs&3)*8 */
-" mtsp %4, %%sr1\n"
-" depw %%r0,31,2,%3\n"
-"1: ldw 0(%%sr1,%3),%0\n"
-"2: ldw 4(%%sr1,%3),%%r20\n"
-" subi 32,%%r19,%%r19\n"
-" mtctl %%r19,11\n"
-" vshd %0,%%r20,%0\n"
-" copy %%r0, %1\n"
+" zdep %4,28,2,%2\n" /* r19=(ofs&3)*8 */
+" mtsp %5, %%sr1\n"
+" depw %%r0,31,2,%4\n"
+"1: ldw 0(%%sr1,%4),%0\n"
+"2: ldw 4(%%sr1,%4),%3\n"
+" subi 32,%4,%2\n"
+" mtctl %2,11\n"
+" vshd %0,%3,%0\n"
"3: \n"
-" .section .fixup,\"ax\"\n"
-"4: ldi -2, %1\n"
- FIXUP_BRANCH(3b)
-" .previous\n"
- ASM_EXCEPTIONTABLE_ENTRY(1b, 4b)
- ASM_EXCEPTIONTABLE_ENTRY(2b, 4b)
- : "=r" (val), "=r" (ret)
- : "0" (val), "r" (saddr), "r" (regs->isr)
- : "r19", "r20", FIXUP_BRANCH_CLOBBER );
+ ASM_EXCEPTIONTABLE_ENTRY_EFAULT(1b, 3b)
+ ASM_EXCEPTIONTABLE_ENTRY_EFAULT(2b, 3b)
+ : "+r" (val), "+r" (ret), "=&r" (temp1), "=&r" (temp2)
+ : "r" (saddr), "r" (regs->isr) );
- DPRINTF("val = 0x" RFMT "\n", val);
+ DPRINTF("val = " RFMT "\n", val);
if (flop)
((__u32*)(regs->fr))[toreg] = val;
@@ -195,16 +168,15 @@ static int emulate_ldd(struct pt_regs *regs, int toreg, int flop)
{
unsigned long saddr = regs->ior;
__u64 val = 0;
- int ret;
+ ASM_EXCEPTIONTABLE_VAR(ret);
DPRINTF("load " RFMT ":" RFMT " to r%d for 8 bytes\n",
regs->isr, regs->ior, toreg);
-#ifdef CONFIG_PA20
-#ifndef CONFIG_64BIT
- if (!flop)
- return -1;
-#endif
+ if (!IS_ENABLED(CONFIG_64BIT) && !flop)
+ return ERR_NOTHANDLED;
+
+#ifdef CONFIG_64BIT
__asm__ __volatile__ (
" depd,z %3,60,3,%%r19\n" /* r19=(ofs&7)*8 */
" mtsp %4, %%sr1\n"
@@ -214,44 +186,32 @@ static int emulate_ldd(struct pt_regs *regs, int toreg, int flop)
" subi 64,%%r19,%%r19\n"
" mtsar %%r19\n"
" shrpd %0,%%r20,%%sar,%0\n"
-" copy %%r0, %1\n"
"3: \n"
-" .section .fixup,\"ax\"\n"
-"4: ldi -2, %1\n"
- FIXUP_BRANCH(3b)
-" .previous\n"
- ASM_EXCEPTIONTABLE_ENTRY(1b,4b)
- ASM_EXCEPTIONTABLE_ENTRY(2b,4b)
- : "=r" (val), "=r" (ret)
+ ASM_EXCEPTIONTABLE_ENTRY_EFAULT(1b, 3b)
+ ASM_EXCEPTIONTABLE_ENTRY_EFAULT(2b, 3b)
+ : "=r" (val), "+r" (ret)
: "0" (val), "r" (saddr), "r" (regs->isr)
- : "r19", "r20", FIXUP_BRANCH_CLOBBER );
+ : "r19", "r20" );
#else
{
- unsigned long valh=0,vall=0;
+ unsigned long shift, temp1;
__asm__ __volatile__ (
-" zdep %5,29,2,%%r19\n" /* r19=(ofs&3)*8 */
-" mtsp %6, %%sr1\n"
-" dep %%r0,31,2,%5\n"
-"1: ldw 0(%%sr1,%5),%0\n"
-"2: ldw 4(%%sr1,%5),%1\n"
-"3: ldw 8(%%sr1,%5),%%r20\n"
-" subi 32,%%r19,%%r19\n"
-" mtsar %%r19\n"
-" vshd %0,%1,%0\n"
-" vshd %1,%%r20,%1\n"
-" copy %%r0, %2\n"
+" zdep %2,29,2,%3\n" /* r19=(ofs&3)*8 */
+" mtsp %5, %%sr1\n"
+" dep %%r0,31,2,%2\n"
+"1: ldw 0(%%sr1,%2),%0\n"
+"2: ldw 4(%%sr1,%2),%R0\n"
+"3: ldw 8(%%sr1,%2),%4\n"
+" subi 32,%3,%3\n"
+" mtsar %3\n"
+" vshd %0,%R0,%0\n"
+" vshd %R0,%4,%R0\n"
"4: \n"
-" .section .fixup,\"ax\"\n"
-"5: ldi -2, %2\n"
- FIXUP_BRANCH(4b)
-" .previous\n"
- ASM_EXCEPTIONTABLE_ENTRY(1b,5b)
- ASM_EXCEPTIONTABLE_ENTRY(2b,5b)
- ASM_EXCEPTIONTABLE_ENTRY(3b,5b)
- : "=r" (valh), "=r" (vall), "=r" (ret)
- : "0" (valh), "1" (vall), "r" (saddr), "r" (regs->isr)
- : "r19", "r20", FIXUP_BRANCH_CLOBBER );
- val=((__u64)valh<<32)|(__u64)vall;
+ ASM_EXCEPTIONTABLE_ENTRY_EFAULT(1b, 4b)
+ ASM_EXCEPTIONTABLE_ENTRY_EFAULT(2b, 4b)
+ ASM_EXCEPTIONTABLE_ENTRY_EFAULT(3b, 4b)
+ : "+r" (val), "+r" (ret), "+r" (saddr), "=&r" (shift), "=&r" (temp1)
+ : "r" (regs->isr) );
}
#endif
@@ -267,31 +227,25 @@ static int emulate_ldd(struct pt_regs *regs, int toreg, int flop)
static int emulate_sth(struct pt_regs *regs, int frreg)
{
- unsigned long val = regs->gr[frreg];
- int ret;
+ unsigned long val = regs->gr[frreg], temp1;
+ ASM_EXCEPTIONTABLE_VAR(ret);
if (!frreg)
val = 0;
- DPRINTF("store r%d (0x" RFMT ") to " RFMT ":" RFMT " for 2 bytes\n", frreg,
+ DPRINTF("store r%d (" RFMT ") to " RFMT ":" RFMT " for 2 bytes\n", frreg,
val, regs->isr, regs->ior);
__asm__ __volatile__ (
-" mtsp %3, %%sr1\n"
-" extrw,u %1, 23, 8, %%r19\n"
-"1: stb %1, 1(%%sr1, %2)\n"
-"2: stb %%r19, 0(%%sr1, %2)\n"
-" copy %%r0, %0\n"
+" mtsp %4, %%sr1\n"
+" extrw,u %2, 23, 8, %1\n"
+"1: stb %1, 0(%%sr1, %3)\n"
+"2: stb %2, 1(%%sr1, %3)\n"
"3: \n"
-" .section .fixup,\"ax\"\n"
-"4: ldi -2, %0\n"
- FIXUP_BRANCH(3b)
-" .previous\n"
- ASM_EXCEPTIONTABLE_ENTRY(1b,4b)
- ASM_EXCEPTIONTABLE_ENTRY(2b,4b)
- : "=r" (ret)
- : "r" (val), "r" (regs->ior), "r" (regs->isr)
- : "r19", FIXUP_BRANCH_CLOBBER );
+ ASM_EXCEPTIONTABLE_ENTRY_EFAULT(1b, 3b)
+ ASM_EXCEPTIONTABLE_ENTRY_EFAULT(2b, 3b)
+ : "+r" (ret), "=&r" (temp1)
+ : "r" (val), "r" (regs->ior), "r" (regs->isr) );
return ret;
}
@@ -299,7 +253,7 @@ static int emulate_sth(struct pt_regs *regs, int frreg)
static int emulate_stw(struct pt_regs *regs, int frreg, int flop)
{
unsigned long val;
- int ret;
+ ASM_EXCEPTIONTABLE_VAR(ret);
if (flop)
val = ((__u32*)(regs->fr))[frreg];
@@ -308,7 +262,7 @@ static int emulate_stw(struct pt_regs *regs, int frreg, int flop)
else
val = 0;
- DPRINTF("store r%d (0x" RFMT ") to " RFMT ":" RFMT " for 4 bytes\n", frreg,
+ DPRINTF("store r%d (" RFMT ") to " RFMT ":" RFMT " for 4 bytes\n", frreg,
val, regs->isr, regs->ior);
@@ -328,24 +282,19 @@ static int emulate_stw(struct pt_regs *regs, int frreg, int flop)
" or %%r1, %%r21, %%r21\n"
" stw %%r20,0(%%sr1,%2)\n"
" stw %%r21,4(%%sr1,%2)\n"
-" copy %%r0, %0\n"
"3: \n"
-" .section .fixup,\"ax\"\n"
-"4: ldi -2, %0\n"
- FIXUP_BRANCH(3b)
-" .previous\n"
- ASM_EXCEPTIONTABLE_ENTRY(1b,4b)
- ASM_EXCEPTIONTABLE_ENTRY(2b,4b)
- : "=r" (ret)
+ ASM_EXCEPTIONTABLE_ENTRY_EFAULT(1b, 3b)
+ ASM_EXCEPTIONTABLE_ENTRY_EFAULT(2b, 3b)
+ : "+r" (ret)
: "r" (val), "r" (regs->ior), "r" (regs->isr)
- : "r19", "r20", "r21", "r22", "r1", FIXUP_BRANCH_CLOBBER );
+ : "r19", "r20", "r21", "r22", "r1" );
- return 0;
+ return ret;
}
static int emulate_std(struct pt_regs *regs, int frreg, int flop)
{
__u64 val;
- int ret;
+ ASM_EXCEPTIONTABLE_VAR(ret);
if (flop)
val = regs->fr[frreg];
@@ -357,11 +306,10 @@ static int emulate_std(struct pt_regs *regs, int frreg, int flop)
DPRINTF("store r%d (0x%016llx) to " RFMT ":" RFMT " for 8 bytes\n", frreg,
val, regs->isr, regs->ior);
-#ifdef CONFIG_PA20
-#ifndef CONFIG_64BIT
- if (!flop)
- return -1;
-#endif
+ if (!IS_ENABLED(CONFIG_64BIT) && !flop)
+ return ERR_NOTHANDLED;
+
+#ifdef CONFIG_64BIT
__asm__ __volatile__ (
" mtsp %3, %%sr1\n"
" depd,z %2, 60, 3, %%r19\n"
@@ -378,26 +326,21 @@ static int emulate_std(struct pt_regs *regs, int frreg, int flop)
" or %%r1, %%r21, %%r21\n"
"3: std %%r20,0(%%sr1,%2)\n"
"4: std %%r21,8(%%sr1,%2)\n"
-" copy %%r0, %0\n"
"5: \n"
-" .section .fixup,\"ax\"\n"
-"6: ldi -2, %0\n"
- FIXUP_BRANCH(5b)
-" .previous\n"
- ASM_EXCEPTIONTABLE_ENTRY(1b,6b)
- ASM_EXCEPTIONTABLE_ENTRY(2b,6b)
- ASM_EXCEPTIONTABLE_ENTRY(3b,6b)
- ASM_EXCEPTIONTABLE_ENTRY(4b,6b)
- : "=r" (ret)
+ ASM_EXCEPTIONTABLE_ENTRY_EFAULT(1b, 5b)
+ ASM_EXCEPTIONTABLE_ENTRY_EFAULT(2b, 5b)
+ ASM_EXCEPTIONTABLE_ENTRY_EFAULT(3b, 5b)
+ ASM_EXCEPTIONTABLE_ENTRY_EFAULT(4b, 5b)
+ : "+r" (ret)
: "r" (val), "r" (regs->ior), "r" (regs->isr)
- : "r19", "r20", "r21", "r22", "r1", FIXUP_BRANCH_CLOBBER );
+ : "r19", "r20", "r21", "r22", "r1" );
#else
{
unsigned long valh=(val>>32),vall=(val&0xffffffffl);
__asm__ __volatile__ (
" mtsp %4, %%sr1\n"
" zdep %2, 29, 2, %%r19\n"
-" dep %%r0, 31, 2, %2\n"
+" dep %%r0, 31, 2, %3\n"
" mtsar %%r19\n"
" zvdepi -2, 32, %%r19\n"
"1: ldw 0(%%sr1,%3),%%r20\n"
@@ -409,23 +352,18 @@ static int emulate_std(struct pt_regs *regs, int frreg, int flop)
" andcm %%r21, %%r19, %%r21\n"
" or %1, %%r20, %1\n"
" or %2, %%r21, %2\n"
-"3: stw %1,0(%%sr1,%1)\n"
+"3: stw %1,0(%%sr1,%3)\n"
"4: stw %%r1,4(%%sr1,%3)\n"
"5: stw %2,8(%%sr1,%3)\n"
-" copy %%r0, %0\n"
"6: \n"
-" .section .fixup,\"ax\"\n"
-"7: ldi -2, %0\n"
- FIXUP_BRANCH(6b)
-" .previous\n"
- ASM_EXCEPTIONTABLE_ENTRY(1b,7b)
- ASM_EXCEPTIONTABLE_ENTRY(2b,7b)
- ASM_EXCEPTIONTABLE_ENTRY(3b,7b)
- ASM_EXCEPTIONTABLE_ENTRY(4b,7b)
- ASM_EXCEPTIONTABLE_ENTRY(5b,7b)
- : "=r" (ret)
+ ASM_EXCEPTIONTABLE_ENTRY_EFAULT(1b, 6b)
+ ASM_EXCEPTIONTABLE_ENTRY_EFAULT(2b, 6b)
+ ASM_EXCEPTIONTABLE_ENTRY_EFAULT(3b, 6b)
+ ASM_EXCEPTIONTABLE_ENTRY_EFAULT(4b, 6b)
+ ASM_EXCEPTIONTABLE_ENTRY_EFAULT(5b, 6b)
+ : "+r" (ret)
: "r" (valh), "r" (vall), "r" (regs->ior), "r" (regs->isr)
- : "r19", "r20", "r21", "r1", FIXUP_BRANCH_CLOBBER );
+ : "r19", "r20", "r21", "r1" );
}
#endif
@@ -438,7 +376,6 @@ void handle_unaligned(struct pt_regs *regs)
unsigned long newbase = R1(regs->iir)?regs->gr[R1(regs->iir)]:0;
int modify = 0;
int ret = ERR_NOTHANDLED;
- register int flop=0; /* true if this is a flop */
__inc_irq_stat(irq_unaligned_count);
@@ -450,10 +387,10 @@ void handle_unaligned(struct pt_regs *regs)
if (!(current->thread.flags & PARISC_UAC_NOPRINT) &&
__ratelimit(&ratelimit)) {
- char buf[256];
- sprintf(buf, "%s(%d): unaligned access to 0x" RFMT " at ip=0x" RFMT "\n",
- current->comm, task_pid_nr(current), regs->ior, regs->iaoq[0]);
- printk(KERN_WARNING "%s", buf);
+ printk(KERN_WARNING "%s(%d): unaligned access to " RFMT
+ " at ip " RFMT " (iir " RFMT ")\n",
+ current->comm, task_pid_nr(current), regs->ior,
+ regs->iaoq[0], regs->iir);
#ifdef DEBUG_UNALIGNED
show_regs(regs);
#endif
@@ -547,7 +484,7 @@ void handle_unaligned(struct pt_regs *regs)
ret = emulate_stw(regs, R2(regs->iir),0);
break;
-#ifdef CONFIG_PA20
+#ifdef CONFIG_64BIT
case OPCODE_LDD_I:
case OPCODE_LDDA_I:
case OPCODE_LDD_S:
@@ -565,13 +502,11 @@ void handle_unaligned(struct pt_regs *regs)
case OPCODE_FLDWS:
case OPCODE_FLDWXR:
case OPCODE_FLDWSR:
- flop=1;
ret = emulate_ldw(regs,FR3(regs->iir),1);
break;
case OPCODE_FLDDX:
case OPCODE_FLDDS:
- flop=1;
ret = emulate_ldd(regs,R3(regs->iir),1);
break;
@@ -579,13 +514,11 @@ void handle_unaligned(struct pt_regs *regs)
case OPCODE_FSTWS:
case OPCODE_FSTWXR:
case OPCODE_FSTWSR:
- flop=1;
ret = emulate_stw(regs,FR3(regs->iir),1);
break;
case OPCODE_FSTDX:
case OPCODE_FSTDS:
- flop=1;
ret = emulate_std(regs,R3(regs->iir),1);
break;
@@ -596,37 +529,33 @@ void handle_unaligned(struct pt_regs *regs)
ret = ERR_NOTHANDLED; /* "undefined", but lets kill them. */
break;
}
-#ifdef CONFIG_PA20
switch (regs->iir & OPCODE2_MASK)
{
case OPCODE_FLDD_L:
- flop=1;
ret = emulate_ldd(regs,R2(regs->iir),1);
break;
case OPCODE_FSTD_L:
- flop=1;
ret = emulate_std(regs, R2(regs->iir),1);
break;
+#ifdef CONFIG_64BIT
case OPCODE_LDD_L:
ret = emulate_ldd(regs, R2(regs->iir),0);
break;
case OPCODE_STD_L:
ret = emulate_std(regs, R2(regs->iir),0);
break;
- }
#endif
+ }
switch (regs->iir & OPCODE3_MASK)
{
case OPCODE_FLDW_L:
- flop=1;
- ret = emulate_ldw(regs, R2(regs->iir),0);
+ ret = emulate_ldw(regs, R2(regs->iir), 1);
break;
case OPCODE_LDW_M:
- ret = emulate_ldw(regs, R2(regs->iir),1);
+ ret = emulate_ldw(regs, R2(regs->iir), 0);
break;
case OPCODE_FSTW_L:
- flop=1;
ret = emulate_stw(regs, R2(regs->iir),1);
break;
case OPCODE_STW_M:
@@ -673,7 +602,7 @@ void handle_unaligned(struct pt_regs *regs)
printk(KERN_CRIT "Unaligned handler failed, ret = %d\n", ret);
die_if_kernel("Unaligned data reference", regs, 28);
- if (ret == ERR_PAGEFAULT)
+ if (ret == -EFAULT)
{
force_sig_fault(SIGSEGV, SEGV_MAPERR,
(void __user *)regs->ior);
diff --git a/arch/parisc/kernel/vdso.c b/arch/parisc/kernel/vdso.c
new file mode 100644
index 000000000000..63dc44c4c246
--- /dev/null
+++ b/arch/parisc/kernel/vdso.c
@@ -0,0 +1,122 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2022 Helge Deller <deller@gmx.de>
+ *
+ * based on arch/s390/kernel/vdso.c which is
+ * Copyright IBM Corp. 2008
+ * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com)
+ */
+
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/slab.h>
+#include <linux/elf.h>
+#include <linux/timekeeper_internal.h>
+#include <linux/compat.h>
+#include <linux/nsproxy.h>
+#include <linux/time_namespace.h>
+#include <linux/random.h>
+
+#include <asm/pgtable.h>
+#include <asm/page.h>
+#include <asm/sections.h>
+#include <asm/vdso.h>
+#include <asm/cacheflush.h>
+
+extern char vdso32_start, vdso32_end;
+extern char vdso64_start, vdso64_end;
+
+static int vdso_mremap(const struct vm_special_mapping *sm,
+ struct vm_area_struct *vma)
+{
+ current->mm->context.vdso_base = vma->vm_start;
+ return 0;
+}
+
+#ifdef CONFIG_64BIT
+static struct vm_special_mapping vdso64_mapping = {
+ .name = "[vdso]",
+ .mremap = vdso_mremap,
+};
+#endif
+
+static struct vm_special_mapping vdso32_mapping = {
+ .name = "[vdso]",
+ .mremap = vdso_mremap,
+};
+
+/*
+ * This is called from binfmt_elf, we create the special vma for the
+ * vDSO and insert it into the mm struct tree
+ */
+int arch_setup_additional_pages(struct linux_binprm *bprm,
+ int executable_stack)
+{
+
+ unsigned long vdso_text_start, vdso_text_len, map_base;
+ struct vm_special_mapping *vdso_mapping;
+ struct mm_struct *mm = current->mm;
+ struct vm_area_struct *vma;
+ int rc;
+
+ if (mmap_write_lock_killable(mm))
+ return -EINTR;
+
+#ifdef CONFIG_64BIT
+ if (!is_compat_task()) {
+ vdso_text_len = &vdso64_end - &vdso64_start;
+ vdso_mapping = &vdso64_mapping;
+ } else
+#endif
+ {
+ vdso_text_len = &vdso32_end - &vdso32_start;
+ vdso_mapping = &vdso32_mapping;
+ }
+
+ map_base = mm->mmap_base;
+ if (current->flags & PF_RANDOMIZE)
+ map_base -= (get_random_int() & 0x1f) * PAGE_SIZE;
+
+ vdso_text_start = get_unmapped_area(NULL, map_base, vdso_text_len, 0, 0);
+
+ /* VM_MAYWRITE for COW so gdb can set breakpoints */
+ vma = _install_special_mapping(mm, vdso_text_start, vdso_text_len,
+ VM_READ|VM_EXEC|
+ VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC,
+ vdso_mapping);
+ if (IS_ERR(vma)) {
+ do_munmap(mm, vdso_text_start, PAGE_SIZE, NULL);
+ rc = PTR_ERR(vma);
+ } else {
+ current->mm->context.vdso_base = vdso_text_start;
+ rc = 0;
+ }
+
+ mmap_write_unlock(mm);
+ return rc;
+}
+
+static struct page ** __init vdso_setup_pages(void *start, void *end)
+{
+ int pages = (end - start) >> PAGE_SHIFT;
+ struct page **pagelist;
+ int i;
+
+ pagelist = kcalloc(pages + 1, sizeof(struct page *), GFP_KERNEL);
+ if (!pagelist)
+ panic("%s: Cannot allocate page list for VDSO", __func__);
+ for (i = 0; i < pages; i++)
+ pagelist[i] = virt_to_page(start + i * PAGE_SIZE);
+ return pagelist;
+}
+
+static int __init vdso_init(void)
+{
+#ifdef CONFIG_64BIT
+ vdso64_mapping.pages = vdso_setup_pages(&vdso64_start, &vdso64_end);
+#endif
+ if (IS_ENABLED(CONFIG_COMPAT) || !IS_ENABLED(CONFIG_64BIT))
+ vdso32_mapping.pages = vdso_setup_pages(&vdso32_start, &vdso32_end);
+ return 0;
+}
+arch_initcall(vdso_init);
diff --git a/arch/parisc/kernel/vdso32/Makefile b/arch/parisc/kernel/vdso32/Makefile
new file mode 100644
index 000000000000..85b1c6d261d1
--- /dev/null
+++ b/arch/parisc/kernel/vdso32/Makefile
@@ -0,0 +1,53 @@
+# List of files in the vdso, has to be asm only for now
+
+obj-vdso32 = note.o sigtramp.o restart_syscall.o
+
+# Build rules
+
+targets := $(obj-vdso32) vdso32.so
+obj-vdso32 := $(addprefix $(obj)/, $(obj-vdso32))
+
+ccflags-y := -shared -fno-common -fbuiltin -mno-fast-indirect-calls -O2 -mno-long-calls
+# -march=1.1 -mschedule=7100LC
+ccflags-y += -nostdlib -Wl,-soname=linux-vdso32.so.1 \
+ $(call ld-option, -Wl$(comma)--hash-style=sysv)
+asflags-y := -D__VDSO32__ -s
+
+KBUILD_AFLAGS += -DBUILD_VDSO
+KBUILD_CFLAGS += -DBUILD_VDSO -DDISABLE_BRANCH_PROFILING
+
+VDSO_LIBGCC := $(shell $(CROSS32CC) -print-libgcc-file-name)
+
+obj-y += vdso32_wrapper.o
+extra-y += vdso32.lds
+CPPFLAGS_vdso32.lds += -P -C # -U$(ARCH)
+
+$(obj)/vdso32_wrapper.o : $(obj)/vdso32.so FORCE
+
+# Force dependency (incbin is bad)
+# link rule for the .so file, .lds has to be first
+$(obj)/vdso32.so: $(src)/vdso32.lds $(obj-vdso32) $(obj-cvdso32) $(VDSO_LIBGCC)
+ $(call if_changed,vdso32ld)
+
+# assembly rules for the .S files
+$(obj-vdso32): %.o: %.S FORCE
+ $(call if_changed_dep,vdso32as)
+
+$(obj-cvdso32): %.o: %.c FORCE
+ $(call if_changed_dep,vdso32cc)
+
+# actual build commands
+quiet_cmd_vdso32ld = VDSO32L $@
+ cmd_vdso32ld = $(CROSS32CC) $(c_flags) -Wl,-T $^ -o $@
+quiet_cmd_vdso32as = VDSO32A $@
+ cmd_vdso32as = $(CROSS32CC) $(a_flags) -c -o $@ $<
+quiet_cmd_vdso32cc = VDSO32C $@
+ cmd_vdso32cc = $(CROSS32CC) $(c_flags) -c -fPIC -mno-fast-indirect-calls -o $@ $<
+
+# Generate VDSO offsets using helper script
+gen-vdsosym := $(srctree)/$(src)/gen_vdso_offsets.sh
+quiet_cmd_vdsosym = VDSOSYM $@
+ cmd_vdsosym = $(NM) $< | $(gen-vdsosym) | LC_ALL=C sort > $@
+
+include/generated/vdso32-offsets.h: $(obj)/vdso32.so FORCE
+ $(call if_changed,vdsosym)
diff --git a/arch/nds32/kernel/vdso/gen_vdso_offsets.sh b/arch/parisc/kernel/vdso32/gen_vdso_offsets.sh
index 01924ff071ad..da39d6cff7f1 100755
--- a/arch/nds32/kernel/vdso/gen_vdso_offsets.sh
+++ b/arch/parisc/kernel/vdso32/gen_vdso_offsets.sh
@@ -1,4 +1,5 @@
#!/bin/sh
+# SPDX-License-Identifier: GPL-2.0
#
# Match symbols in the DSO that look like VDSO_*; produce a header file
@@ -7,9 +8,8 @@
# Doing this inside the Makefile will break the $(filter-out) function,
# causing Kbuild to rebuild the vdso-offsets header file every time.
#
-# Author: Will Deacon <will.deacon@arm.com
+# Inspired by arm64 version.
#
LC_ALL=C
-sed -n -e 's/^00*/0/' -e \
-'s/^\([0-9a-fA-F]*\) . VDSO_\([a-zA-Z0-9_]*\)$/\#define vdso_offset_\2\t0x\1/p'
+sed -n 's/\([0-9a-f]*\) . __kernel_\(.*\)/\#define vdso32_offset_\2\t0x\1/p'
diff --git a/arch/parisc/kernel/vdso32/note.S b/arch/parisc/kernel/vdso32/note.S
new file mode 100644
index 000000000000..bb350918bebd
--- /dev/null
+++ b/arch/parisc/kernel/vdso32/note.S
@@ -0,0 +1,26 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * This supplies .note.* sections to go into the PT_NOTE inside the vDSO text.
+ * Here we can supply some information useful to userland.
+ */
+
+#include <linux/uts.h>
+#include <linux/version.h>
+
+#define ASM_ELF_NOTE_BEGIN(name, flags, vendor, type) \
+ .section name, flags; \
+ .balign 4; \
+ .long 1f - 0f; /* name length */ \
+ .long 3f - 2f; /* data length */ \
+ .long type; /* note type */ \
+0: .asciz vendor; /* vendor name */ \
+1: .balign 4; \
+2:
+
+#define ASM_ELF_NOTE_END \
+3: .balign 4; /* pad out section */ \
+ .previous
+
+ ASM_ELF_NOTE_BEGIN(".note.kernel-version", "a", UTS_SYSNAME, 0)
+ .long LINUX_VERSION_CODE
+ ASM_ELF_NOTE_END
diff --git a/arch/parisc/kernel/vdso32/restart_syscall.S b/arch/parisc/kernel/vdso32/restart_syscall.S
new file mode 100644
index 000000000000..7e82008d7e40
--- /dev/null
+++ b/arch/parisc/kernel/vdso32/restart_syscall.S
@@ -0,0 +1,32 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Syscall restart trampoline for 32 and 64 bits processes.
+ *
+ * Copyright (C) 2018-2022 Helge Deller <deller@gmx.de>
+ * Copyright (C) 2022 John David Anglin <dave.anglin@bell.net>
+ */
+
+#include <asm/unistd.h>
+#include <asm/vdso.h>
+
+#include <linux/linkage.h>
+
+ .text
+
+ENTRY_CFI(__kernel_restart_syscall)
+ /*
+ * Setup a trampoline to restart the syscall
+ * with __NR_restart_syscall
+ */
+
+ /* load return pointer */
+#if defined(__VDSO64__)
+ ldd 0(%sp), %r31
+#elif defined(__VDSO32__)
+ ldw 0(%sp), %r31
+#endif
+
+ be 0x100(%sr2, %r0)
+ ldi __NR_restart_syscall, %r20
+
+ENDPROC_CFI(__kernel_restart_syscall)
diff --git a/arch/parisc/kernel/vdso32/sigtramp.S b/arch/parisc/kernel/vdso32/sigtramp.S
new file mode 100644
index 000000000000..192da7077869
--- /dev/null
+++ b/arch/parisc/kernel/vdso32/sigtramp.S
@@ -0,0 +1,195 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Signal trampolines for 32 bit processes.
+ *
+ * Copyright (C) 2006 Randolph Chung <tausq@debian.org>
+ * Copyright (C) 2018-2022 Helge Deller <deller@gmx.de>
+ * Copyright (C) 2022 John David Anglin <dave.anglin@bell.net>
+ */
+#include <asm/unistd.h>
+#include <linux/linkage.h>
+#include <generated/asm-offsets.h>
+
+ .text
+
+/* Gdb expects the trampoline is on the stack and the pc is offset from
+ a 64-byte boundary by 0, 4 or 5 instructions. Since the vdso trampoline
+ is not on the stack, we need a new variant with different offsets and
+ data to tell gdb where to find the signal context on the stack.
+
+ Here we put the offset to the context data at the start of the trampoline
+ region and offset the first trampoline by 2 instructions. Please do
+ not change the trampoline as the code in gdb depends on the following
+ instruction sequence exactly.
+ */
+ .align 64
+ .word SIGFRAME_CONTEXT_REGS32
+
+/* The nop here is a hack. The dwarf2 unwind routines subtract 1 from
+ the return address to get an address in the middle of the presumed
+ call instruction. Since we don't have a call here, we artifically
+ extend the range covered by the unwind info by adding a nop before
+ the real start.
+ */
+ nop
+
+ .globl __kernel_sigtramp_rt
+ .type __kernel_sigtramp_rt, @function
+__kernel_sigtramp_rt:
+ .proc
+ .callinfo FRAME=ASM_SIGFRAME_SIZE32,CALLS,SAVE_RP
+ .entry
+
+.Lsigrt_start = . - 4
+0: ldi 0, %r25 /* (in_syscall=0) */
+ ldi __NR_rt_sigreturn, %r20
+ ble 0x100(%sr2, %r0)
+ nop
+
+1: ldi 1, %r25 /* (in_syscall=1) */
+ ldi __NR_rt_sigreturn, %r20
+ ble 0x100(%sr2, %r0)
+ nop
+.Lsigrt_end:
+ .exit
+ .procend
+ .size __kernel_sigtramp_rt,.-__kernel_sigtramp_rt
+
+
+ .section .eh_frame,"a",@progbits
+
+/* This is where the mcontext_t struct can be found on the stack. */
+#define PTREGS SIGFRAME_CONTEXT_REGS32 /* 32-bit process offset is -672 */
+
+/* Register REGNO can be found at offset OFS of the mcontext_t structure. */
+ .macro rsave regno,ofs
+ .byte 0x05 /* DW_CFA_offset_extended */
+ .uleb128 \regno; /* regno */
+ .uleb128 \ofs /* factored offset */
+ .endm
+
+.Lcie:
+ .long .Lcie_end - .Lcie_start
+.Lcie_start:
+ .long 0 /* CIE ID */
+ .byte 1 /* Version number */
+ .stringz "zRS" /* NUL-terminated augmentation string */
+ .uleb128 4 /* Code alignment factor */
+ .sleb128 4 /* Data alignment factor */
+ .byte 89 /* Return address register column, iaoq[0] */
+ .uleb128 1 /* Augmentation value length */
+ .byte 0x1b /* DW_EH_PE_pcrel | DW_EH_PE_sdata4. */
+ .byte 0x0f /* DW_CFA_def_cfa_expresion */
+ .uleb128 9f - 1f /* length */
+1:
+ .byte 0x8e /* DW_OP_breg30 */
+ .sleb128 PTREGS
+9:
+ .balign 4
+.Lcie_end:
+
+ .long .Lfde0_end - .Lfde0_start
+.Lfde0_start:
+ .long .Lfde0_start - .Lcie /* CIE pointer. */
+ .long .Lsigrt_start - . /* PC start, length */
+ .long .Lsigrt_end - .Lsigrt_start
+ .uleb128 0 /* Augmentation */
+
+ /* General registers */
+ rsave 1, 2
+ rsave 2, 3
+ rsave 3, 4
+ rsave 4, 5
+ rsave 5, 6
+ rsave 6, 7
+ rsave 7, 8
+ rsave 8, 9
+ rsave 9, 10
+ rsave 10, 11
+ rsave 11, 12
+ rsave 12, 13
+ rsave 13, 14
+ rsave 14, 15
+ rsave 15, 16
+ rsave 16, 17
+ rsave 17, 18
+ rsave 18, 19
+ rsave 19, 20
+ rsave 20, 21
+ rsave 21, 22
+ rsave 22, 23
+ rsave 23, 24
+ rsave 24, 25
+ rsave 25, 26
+ rsave 26, 27
+ rsave 27, 28
+ rsave 28, 29
+ rsave 29, 30
+ rsave 30, 31
+ rsave 31, 32
+
+ /* Floating-point registers */
+ rsave 32, 42
+ rsave 33, 43
+ rsave 34, 44
+ rsave 35, 45
+ rsave 36, 46
+ rsave 37, 47
+ rsave 38, 48
+ rsave 39, 49
+ rsave 40, 50
+ rsave 41, 51
+ rsave 42, 52
+ rsave 43, 53
+ rsave 44, 54
+ rsave 45, 55
+ rsave 46, 56
+ rsave 47, 57
+ rsave 48, 58
+ rsave 49, 59
+ rsave 50, 60
+ rsave 51, 61
+ rsave 52, 62
+ rsave 53, 63
+ rsave 54, 64
+ rsave 55, 65
+ rsave 56, 66
+ rsave 57, 67
+ rsave 58, 68
+ rsave 59, 69
+ rsave 60, 70
+ rsave 61, 71
+ rsave 62, 72
+ rsave 63, 73
+ rsave 64, 74
+ rsave 65, 75
+ rsave 66, 76
+ rsave 67, 77
+ rsave 68, 78
+ rsave 69, 79
+ rsave 70, 80
+ rsave 71, 81
+ rsave 72, 82
+ rsave 73, 83
+ rsave 74, 84
+ rsave 75, 85
+ rsave 76, 86
+ rsave 77, 87
+ rsave 78, 88
+ rsave 79, 89
+ rsave 80, 90
+ rsave 81, 91
+ rsave 82, 92
+ rsave 83, 93
+ rsave 84, 94
+ rsave 85, 95
+ rsave 86, 96
+ rsave 87, 97
+
+ /* SAR register */
+ rsave 88, 102
+
+ /* iaoq[0] return address register */
+ rsave 89, 100
+ .balign 4
+.Lfde0_end:
diff --git a/arch/parisc/kernel/vdso32/vdso32.lds.S b/arch/parisc/kernel/vdso32/vdso32.lds.S
new file mode 100644
index 000000000000..d4aff3af5262
--- /dev/null
+++ b/arch/parisc/kernel/vdso32/vdso32.lds.S
@@ -0,0 +1,111 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * This is the infamous ld script for the 32 bits vdso library
+ */
+#include <asm/vdso.h>
+#include <asm/page.h>
+
+/* Default link addresses for the vDSOs */
+OUTPUT_FORMAT("elf32-hppa-linux")
+OUTPUT_ARCH(hppa)
+ENTRY(_start)
+
+SECTIONS
+{
+ . = VDSO_LBASE + SIZEOF_HEADERS;
+ .hash : { *(.hash) } :text
+ .gnu.hash : { *(.gnu.hash) }
+ .dynsym : { *(.dynsym) }
+ .dynstr : { *(.dynstr) }
+ .gnu.version : { *(.gnu.version) }
+ .gnu.version_d : { *(.gnu.version_d) }
+ .gnu.version_r : { *(.gnu.version_r) }
+
+ .note : { *(.note.*) } :text :note
+
+ . = ALIGN (16);
+ .text :
+ {
+ *(.text .stub .text.* .gnu.linkonce.t.*)
+ }
+ PROVIDE (__etext = .);
+ PROVIDE (_etext = .);
+ PROVIDE (etext = .);
+
+ /* Other stuff is appended to the text segment: */
+ .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) }
+ .rodata1 : { *(.rodata1) }
+ .rodata2 : { *(.data.rel.ro) }
+
+ .eh_frame_hdr : { *(.eh_frame_hdr) } :text :eh_frame_hdr
+ .eh_frame : { KEEP (*(.eh_frame)) } :text
+ .gcc_except_table : { *(.gcc_except_table) }
+ .fixup : { *(.fixup) }
+
+ .dynamic : { *(.dynamic) } :text :dynamic
+ .plt : { *(.plt) }
+ .got : { *(.got) }
+
+ _end = .;
+ __end = .;
+ PROVIDE (end = .);
+
+
+ /* Stabs debugging sections are here too
+ */
+ .stab 0 : { *(.stab) }
+ .stabstr 0 : { *(.stabstr) }
+ .stab.excl 0 : { *(.stab.excl) }
+ .stab.exclstr 0 : { *(.stab.exclstr) }
+ .stab.index 0 : { *(.stab.index) }
+ .stab.indexstr 0 : { *(.stab.indexstr) }
+ .comment 0 : { *(.comment) }
+ .debug 0 : { *(.debug) }
+ .line 0 : { *(.line) }
+
+ .debug_srcinfo 0 : { *(.debug_srcinfo) }
+ .debug_sfnames 0 : { *(.debug_sfnames) }
+
+ .debug_aranges 0 : { *(.debug_aranges) }
+ .debug_pubnames 0 : { *(.debug_pubnames) }
+
+ .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
+ .debug_abbrev 0 : { *(.debug_abbrev) }
+ .debug_line 0 : { *(.debug_line) }
+ .debug_frame 0 : { *(.debug_frame) }
+ .debug_str 0 : { *(.debug_str) }
+ .debug_loc 0 : { *(.debug_loc) }
+ .debug_macinfo 0 : { *(.debug_macinfo) }
+
+ .debug_weaknames 0 : { *(.debug_weaknames) }
+ .debug_funcnames 0 : { *(.debug_funcnames) }
+ .debug_typenames 0 : { *(.debug_typenames) }
+ .debug_varnames 0 : { *(.debug_varnames) }
+
+ /DISCARD/ : { *(.note.GNU-stack) }
+ /DISCARD/ : { *(.data .data.* .gnu.linkonce.d.* .sdata*) }
+ /DISCARD/ : { *(.bss .sbss .dynbss .dynsbss) }
+}
+
+
+PHDRS
+{
+ text PT_LOAD FILEHDR PHDRS FLAGS(5); /* PF_R|PF_X */
+ note PT_NOTE FLAGS(4); /* PF_R */
+ dynamic PT_DYNAMIC FLAGS(4); /* PF_R */
+ eh_frame_hdr PT_GNU_EH_FRAME;
+}
+
+
+/*
+ * This controls what symbols we export from the DSO.
+ */
+VERSION
+{
+ VDSO_VERSION_STRING {
+ global:
+ __kernel_sigtramp_rt32;
+ __kernel_restart_syscall32;
+ local: *;
+ };
+}
diff --git a/arch/parisc/kernel/vdso32/vdso32_wrapper.S b/arch/parisc/kernel/vdso32/vdso32_wrapper.S
new file mode 100644
index 000000000000..5ac06093e8ec
--- /dev/null
+++ b/arch/parisc/kernel/vdso32/vdso32_wrapper.S
@@ -0,0 +1,14 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#include <linux/linkage.h>
+#include <asm/page.h>
+
+ __PAGE_ALIGNED_DATA
+
+ .globl vdso32_start, vdso32_end
+ .balign PAGE_SIZE
+vdso32_start:
+ .incbin "arch/parisc/kernel/vdso32/vdso32.so"
+ .balign PAGE_SIZE
+vdso32_end:
+
+ .previous
diff --git a/arch/parisc/kernel/vdso64/Makefile b/arch/parisc/kernel/vdso64/Makefile
new file mode 100644
index 000000000000..a30f5ec5eb4b
--- /dev/null
+++ b/arch/parisc/kernel/vdso64/Makefile
@@ -0,0 +1,48 @@
+# List of files in the vdso, has to be asm only for now
+
+obj-vdso64 = note.o sigtramp.o restart_syscall.o
+
+# Build rules
+
+targets := $(obj-vdso64) vdso64.so
+obj-vdso64 := $(addprefix $(obj)/, $(obj-vdso64))
+
+
+ccflags-y := -shared -fno-common -fno-builtin
+ccflags-y += -nostdlib -Wl,-soname=linux-vdso64.so.1 \
+ $(call ld-option, -Wl$(comma)--hash-style=sysv)
+asflags-y := -D__VDSO64__ -s
+
+KBUILD_AFLAGS += -DBUILD_VDSO
+KBUILD_CFLAGS += -DBUILD_VDSO -DDISABLE_BRANCH_PROFILING
+
+VDSO_LIBGCC := $(shell $(CC) -print-libgcc-file-name)
+
+obj-y += vdso64_wrapper.o
+extra-y += vdso64.lds
+CPPFLAGS_vdso64.lds += -P -C -U$(ARCH)
+
+$(obj)/vdso64_wrapper.o : $(obj)/vdso64.so FORCE
+
+# Force dependency (incbin is bad)
+# link rule for the .so file, .lds has to be first
+$(obj)/vdso64.so: $(src)/vdso64.lds $(obj-vdso64) $(VDSO_LIBGCC)
+ $(call if_changed,vdso64ld)
+
+# assembly rules for the .S files
+$(obj-vdso64): %.o: %.S FORCE
+ $(call if_changed_dep,vdso64as)
+
+# actual build commands
+quiet_cmd_vdso64ld = VDSO64L $@
+ cmd_vdso64ld = $(CC) $(c_flags) -Wl,-T $^ -o $@
+quiet_cmd_vdso64as = VDSO64A $@
+ cmd_vdso64as = $(CC) $(a_flags) -c -o $@ $<
+
+# Generate VDSO offsets using helper script
+gen-vdsosym := $(srctree)/$(src)/gen_vdso_offsets.sh
+quiet_cmd_vdsosym = VDSOSYM $@
+ cmd_vdsosym = $(NM) $< | $(gen-vdsosym) | LC_ALL=C sort > $@
+
+include/generated/vdso64-offsets.h: $(obj)/vdso64.so FORCE
+ $(call if_changed,vdsosym)
diff --git a/arch/parisc/kernel/vdso64/gen_vdso_offsets.sh b/arch/parisc/kernel/vdso64/gen_vdso_offsets.sh
new file mode 100755
index 000000000000..37f05cb38dad
--- /dev/null
+++ b/arch/parisc/kernel/vdso64/gen_vdso_offsets.sh
@@ -0,0 +1,15 @@
+#!/bin/sh
+# SPDX-License-Identifier: GPL-2.0
+
+#
+# Match symbols in the DSO that look like VDSO_*; produce a header file
+# of constant offsets into the shared object.
+#
+# Doing this inside the Makefile will break the $(filter-out) function,
+# causing Kbuild to rebuild the vdso-offsets header file every time.
+#
+# Inspired by arm64 version.
+#
+
+LC_ALL=C
+sed -n 's/\([0-9a-f]*\) . __kernel_\(.*\)/\#define vdso64_offset_\2\t0x\1/p'
diff --git a/arch/parisc/kernel/vdso64/note.S b/arch/parisc/kernel/vdso64/note.S
new file mode 100644
index 000000000000..bd1fa23597d6
--- /dev/null
+++ b/arch/parisc/kernel/vdso64/note.S
@@ -0,0 +1,2 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#include "../vdso32/note.S"
diff --git a/arch/parisc/kernel/vdso64/restart_syscall.S b/arch/parisc/kernel/vdso64/restart_syscall.S
new file mode 100644
index 000000000000..83004451f6b1
--- /dev/null
+++ b/arch/parisc/kernel/vdso64/restart_syscall.S
@@ -0,0 +1,3 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+#include "../vdso32/restart_syscall.S"
diff --git a/arch/parisc/kernel/vdso64/sigtramp.S b/arch/parisc/kernel/vdso64/sigtramp.S
new file mode 100644
index 000000000000..66a6d2b241e1
--- /dev/null
+++ b/arch/parisc/kernel/vdso64/sigtramp.S
@@ -0,0 +1,166 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Signal trampolines for 64 bit processes.
+ *
+ * Copyright (C) 2006 Randolph Chung <tausq@debian.org>
+ * Copyright (C) 2018-2022 Helge Deller <deller@gmx.de>
+ * Copyright (C) 2022 John David Anglin <dave.anglin@bell.net>
+ */
+#include <asm/unistd.h>
+#include <linux/linkage.h>
+#include <generated/asm-offsets.h>
+
+ .text
+
+/* Gdb expects the trampoline is on the stack and the pc is offset from
+ a 64-byte boundary by 0, 4 or 5 instructions. Since the vdso trampoline
+ is not on the stack, we need a new variant with different offsets and
+ data to tell gdb where to find the signal context on the stack.
+
+ Here we put the offset to the context data at the start of the trampoline
+ region and offset the first trampoline by 2 instructions. Please do
+ not change the trampoline as the code in gdb depends on the following
+ instruction sequence exactly.
+ */
+ .align 64
+ .word SIGFRAME_CONTEXT_REGS
+
+/* The nop here is a hack. The dwarf2 unwind routines subtract 1 from
+ the return address to get an address in the middle of the presumed
+ call instruction. Since we don't have a call here, we artifically
+ extend the range covered by the unwind info by adding a nop before
+ the real start.
+ */
+ nop
+
+ .globl __kernel_sigtramp_rt
+ .type __kernel_sigtramp_rt, @function
+__kernel_sigtramp_rt:
+ .proc
+ .callinfo FRAME=ASM_SIGFRAME_SIZE,CALLS,SAVE_RP
+ .entry
+
+.Lsigrt_start = . - 4
+0: ldi 0, %r25 /* (in_syscall=0) */
+ ldi __NR_rt_sigreturn, %r20
+ ble 0x100(%sr2, %r0)
+ nop
+
+1: ldi 1, %r25 /* (in_syscall=1) */
+ ldi __NR_rt_sigreturn, %r20
+ ble 0x100(%sr2, %r0)
+ nop
+.Lsigrt_end:
+ .exit
+ .procend
+ .size __kernel_sigtramp_rt,.-__kernel_sigtramp_rt
+
+ .section .eh_frame,"a",@progbits
+
+/* This is where the mcontext_t struct can be found on the stack. */
+#define PTREGS SIGFRAME_CONTEXT_REGS /* 64-bit process offset is -720 */
+
+/* Register REGNO can be found at offset OFS of the mcontext_t structure. */
+ .macro rsave regno,ofs
+ .byte 0x05 /* DW_CFA_offset_extended */
+ .uleb128 \regno; /* regno */
+ .uleb128 \ofs /* factored offset */
+ .endm
+
+.Lcie:
+ .long .Lcie_end - .Lcie_start
+.Lcie_start:
+ .long 0 /* CIE ID */
+ .byte 1 /* Version number */
+ .stringz "zRS" /* NUL-terminated augmentation string */
+ .uleb128 4 /* Code alignment factor */
+ .sleb128 8 /* Data alignment factor */
+ .byte 61 /* Return address register column, iaoq[0] */
+ .uleb128 1 /* Augmentation value length */
+ .byte 0x1b /* DW_EH_PE_pcrel | DW_EH_PE_sdata4. */
+ .byte 0x0f /* DW_CFA_def_cfa_expresion */
+ .uleb128 9f - 1f /* length */
+1:
+ .byte 0x8e /* DW_OP_breg30 */
+ .sleb128 PTREGS
+9:
+ .balign 8
+.Lcie_end:
+
+ .long .Lfde0_end - .Lfde0_start
+.Lfde0_start:
+ .long .Lfde0_start - .Lcie /* CIE pointer. */
+ .long .Lsigrt_start - . /* PC start, length */
+ .long .Lsigrt_end - .Lsigrt_start
+ .uleb128 0 /* Augmentation */
+
+ /* General registers */
+ rsave 1, 2
+ rsave 2, 3
+ rsave 3, 4
+ rsave 4, 5
+ rsave 5, 6
+ rsave 6, 7
+ rsave 7, 8
+ rsave 8, 9
+ rsave 9, 10
+ rsave 10, 11
+ rsave 11, 12
+ rsave 12, 13
+ rsave 13, 14
+ rsave 14, 15
+ rsave 15, 16
+ rsave 16, 17
+ rsave 17, 18
+ rsave 18, 19
+ rsave 19, 20
+ rsave 20, 21
+ rsave 21, 22
+ rsave 22, 23
+ rsave 23, 24
+ rsave 24, 25
+ rsave 25, 26
+ rsave 26, 27
+ rsave 27, 28
+ rsave 28, 29
+ rsave 29, 30
+ rsave 30, 31
+ rsave 31, 32
+
+ /* Floating-point registers */
+ rsave 32, 36
+ rsave 33, 37
+ rsave 34, 38
+ rsave 35, 39
+ rsave 36, 40
+ rsave 37, 41
+ rsave 38, 42
+ rsave 39, 43
+ rsave 40, 44
+ rsave 41, 45
+ rsave 42, 46
+ rsave 43, 47
+ rsave 44, 48
+ rsave 45, 49
+ rsave 46, 50
+ rsave 47, 51
+ rsave 48, 52
+ rsave 49, 53
+ rsave 50, 54
+ rsave 51, 55
+ rsave 52, 56
+ rsave 53, 57
+ rsave 54, 58
+ rsave 55, 59
+ rsave 56, 60
+ rsave 57, 61
+ rsave 58, 62
+ rsave 59, 63
+
+ /* SAR register */
+ rsave 60, 67
+
+ /* iaoq[0] return address register */
+ rsave 61, 65
+ .balign 8
+.Lfde0_end:
diff --git a/arch/parisc/kernel/vdso64/vdso64.lds.S b/arch/parisc/kernel/vdso64/vdso64.lds.S
new file mode 100644
index 000000000000..de1fb4b19286
--- /dev/null
+++ b/arch/parisc/kernel/vdso64/vdso64.lds.S
@@ -0,0 +1,109 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * This is the infamous ld script for the 64 bits vdso library
+ */
+#include <asm/vdso.h>
+
+/* Default link addresses for the vDSOs */
+OUTPUT_FORMAT("elf64-hppa-linux")
+OUTPUT_ARCH(hppa:hppa2.0w)
+ENTRY(_start)
+
+SECTIONS
+{
+ . = VDSO_LBASE + SIZEOF_HEADERS;
+ .hash : { *(.hash) } :text
+ .gnu.hash : { *(.gnu.hash) }
+ .dynsym : { *(.dynsym) }
+ .dynstr : { *(.dynstr) }
+ .gnu.version : { *(.gnu.version) }
+ .gnu.version_d : { *(.gnu.version_d) }
+ .gnu.version_r : { *(.gnu.version_r) }
+
+ .note : { *(.note.*) } :text :note
+
+ . = ALIGN (16);
+ .text :
+ {
+ *(.text .stub .text.* .gnu.linkonce.t.*)
+ }
+ PROVIDE (__etext = .);
+ PROVIDE (_etext = .);
+ PROVIDE (etext = .);
+
+ /* Other stuff is appended to the text segment: */
+ .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) }
+ .rodata1 : { *(.rodata1) }
+
+ .eh_frame_hdr : { *(.eh_frame_hdr) } :text :eh_frame_hdr
+ .eh_frame : { KEEP (*(.eh_frame)) } :text
+ .gcc_except_table : { *(.gcc_except_table) }
+ .fixup : { *(.fixup) }
+
+ .dynamic : { *(.dynamic) } :text :dynamic
+ .plt : { *(.plt) }
+ .got : { *(.got) }
+
+ _end = .;
+ __end = .;
+ PROVIDE (end = .);
+
+
+ /* Stabs debugging sections are here too
+ */
+ .stab 0 : { *(.stab) }
+ .stabstr 0 : { *(.stabstr) }
+ .stab.excl 0 : { *(.stab.excl) }
+ .stab.exclstr 0 : { *(.stab.exclstr) }
+ .stab.index 0 : { *(.stab.index) }
+ .stab.indexstr 0 : { *(.stab.indexstr) }
+ .comment 0 : { *(.comment) }
+ .debug 0 : { *(.debug) }
+ .line 0 : { *(.line) }
+
+ .debug_srcinfo 0 : { *(.debug_srcinfo) }
+ .debug_sfnames 0 : { *(.debug_sfnames) }
+
+ .debug_aranges 0 : { *(.debug_aranges) }
+ .debug_pubnames 0 : { *(.debug_pubnames) }
+
+ .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
+ .debug_abbrev 0 : { *(.debug_abbrev) }
+ .debug_line 0 : { *(.debug_line) }
+ .debug_frame 0 : { *(.debug_frame) }
+ .debug_str 0 : { *(.debug_str) }
+ .debug_loc 0 : { *(.debug_loc) }
+ .debug_macinfo 0 : { *(.debug_macinfo) }
+
+ .debug_weaknames 0 : { *(.debug_weaknames) }
+ .debug_funcnames 0 : { *(.debug_funcnames) }
+ .debug_typenames 0 : { *(.debug_typenames) }
+ .debug_varnames 0 : { *(.debug_varnames) }
+
+ /DISCARD/ : { *(.note.GNU-stack) }
+ /DISCARD/ : { *(.data .data.* .gnu.linkonce.d.* .sdata*) }
+ /DISCARD/ : { *(.bss .sbss .dynbss .dynsbss) }
+}
+
+
+PHDRS
+{
+ text PT_LOAD FILEHDR PHDRS FLAGS(5); /* PF_R|PF_X */
+ note PT_NOTE FLAGS(4); /* PF_R */
+ dynamic PT_DYNAMIC FLAGS(4); /* PF_R */
+ eh_frame_hdr PT_GNU_EH_FRAME;
+}
+
+
+/*
+ * This controls what symbols we export from the DSO.
+ */
+VERSION
+{
+ VDSO_VERSION_STRING {
+ global:
+ __kernel_sigtramp_rt64;
+ __kernel_restart_syscall64;
+ local: *;
+ };
+}
diff --git a/arch/parisc/kernel/vdso64/vdso64_wrapper.S b/arch/parisc/kernel/vdso64/vdso64_wrapper.S
new file mode 100644
index 000000000000..66f929482d3d
--- /dev/null
+++ b/arch/parisc/kernel/vdso64/vdso64_wrapper.S
@@ -0,0 +1,14 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#include <linux/linkage.h>
+#include <asm/page.h>
+
+ __PAGE_ALIGNED_DATA
+
+ .globl vdso64_start, vdso64_end
+ .balign PAGE_SIZE
+vdso64_start:
+ .incbin "arch/parisc/kernel/vdso64/vdso64.so"
+ .balign PAGE_SIZE
+vdso64_end:
+
+ .previous
diff --git a/arch/parisc/lib/iomap.c b/arch/parisc/lib/iomap.c
index 367f6397bda7..860385058085 100644
--- a/arch/parisc/lib/iomap.c
+++ b/arch/parisc/lib/iomap.c
@@ -346,6 +346,16 @@ u64 ioread64be(const void __iomem *addr)
return *((u64 *)addr);
}
+u64 ioread64_lo_hi(const void __iomem *addr)
+{
+ u32 low, high;
+
+ low = ioread32(addr);
+ high = ioread32(addr + sizeof(u32));
+
+ return low + ((u64)high << 32);
+}
+
u64 ioread64_hi_lo(const void __iomem *addr)
{
u32 low, high;
@@ -419,6 +429,12 @@ void iowrite64be(u64 datum, void __iomem *addr)
}
}
+void iowrite64_lo_hi(u64 val, void __iomem *addr)
+{
+ iowrite32(val, addr);
+ iowrite32(val >> 32, addr + sizeof(u32));
+}
+
void iowrite64_hi_lo(u64 val, void __iomem *addr)
{
iowrite32(val >> 32, addr + sizeof(u32));
@@ -530,6 +546,7 @@ EXPORT_SYMBOL(ioread32);
EXPORT_SYMBOL(ioread32be);
EXPORT_SYMBOL(ioread64);
EXPORT_SYMBOL(ioread64be);
+EXPORT_SYMBOL(ioread64_lo_hi);
EXPORT_SYMBOL(ioread64_hi_lo);
EXPORT_SYMBOL(iowrite8);
EXPORT_SYMBOL(iowrite16);
@@ -538,6 +555,7 @@ EXPORT_SYMBOL(iowrite32);
EXPORT_SYMBOL(iowrite32be);
EXPORT_SYMBOL(iowrite64);
EXPORT_SYMBOL(iowrite64be);
+EXPORT_SYMBOL(iowrite64_lo_hi);
EXPORT_SYMBOL(iowrite64_hi_lo);
EXPORT_SYMBOL(ioread8_rep);
EXPORT_SYMBOL(ioread16_rep);
diff --git a/arch/parisc/lib/memcpy.c b/arch/parisc/lib/memcpy.c
index ea70a0e08321..5fc0c852c84c 100644
--- a/arch/parisc/lib/memcpy.c
+++ b/arch/parisc/lib/memcpy.c
@@ -13,8 +13,8 @@
#include <linux/compiler.h>
#include <linux/uaccess.h>
-#define get_user_space() (uaccess_kernel() ? 0 : mfsp(3))
-#define get_kernel_space() (0)
+#define get_user_space() mfsp(SR_USER)
+#define get_kernel_space() SR_KERNEL
/* Returns 0 for success, otherwise, returns number of bytes not transferred. */
extern unsigned long pa_memcpy(void *dst, const void *src,
@@ -23,8 +23,8 @@ extern unsigned long pa_memcpy(void *dst, const void *src,
unsigned long raw_copy_to_user(void __user *dst, const void *src,
unsigned long len)
{
- mtsp(get_kernel_space(), 1);
- mtsp(get_user_space(), 2);
+ mtsp(get_kernel_space(), SR_TEMP1);
+ mtsp(get_user_space(), SR_TEMP2);
return pa_memcpy((void __force *)dst, src, len);
}
EXPORT_SYMBOL(raw_copy_to_user);
@@ -32,16 +32,16 @@ EXPORT_SYMBOL(raw_copy_to_user);
unsigned long raw_copy_from_user(void *dst, const void __user *src,
unsigned long len)
{
- mtsp(get_user_space(), 1);
- mtsp(get_kernel_space(), 2);
+ mtsp(get_user_space(), SR_TEMP1);
+ mtsp(get_kernel_space(), SR_TEMP2);
return pa_memcpy(dst, (void __force *)src, len);
}
EXPORT_SYMBOL(raw_copy_from_user);
void * memcpy(void * dst,const void *src, size_t count)
{
- mtsp(get_kernel_space(), 1);
- mtsp(get_kernel_space(), 2);
+ mtsp(get_kernel_space(), SR_TEMP1);
+ mtsp(get_kernel_space(), SR_TEMP2);
pa_memcpy(dst, src, count);
return dst;
}
diff --git a/arch/parisc/mm/fault.c b/arch/parisc/mm/fault.c
index e9eabf8f14d7..f114e102aaf2 100644
--- a/arch/parisc/mm/fault.c
+++ b/arch/parisc/mm/fault.c
@@ -425,3 +425,92 @@ out_of_memory:
}
pagefault_out_of_memory();
}
+
+/* Handle non-access data TLB miss faults.
+ *
+ * For probe instructions, accesses to userspace are considered allowed
+ * if they lie in a valid VMA and the access type matches. We are not
+ * allowed to handle MM faults here so there may be situations where an
+ * actual access would fail even though a probe was successful.
+ */
+int
+handle_nadtlb_fault(struct pt_regs *regs)
+{
+ unsigned long insn = regs->iir;
+ int breg, treg, xreg, val = 0;
+ struct vm_area_struct *vma, *prev_vma;
+ struct task_struct *tsk;
+ struct mm_struct *mm;
+ unsigned long address;
+ unsigned long acc_type;
+
+ switch (insn & 0x380) {
+ case 0x280:
+ /* FDC instruction */
+ fallthrough;
+ case 0x380:
+ /* PDC and FIC instructions */
+ if (printk_ratelimit()) {
+ pr_warn("BUG: nullifying cache flush/purge instruction\n");
+ show_regs(regs);
+ }
+ if (insn & 0x20) {
+ /* Base modification */
+ breg = (insn >> 21) & 0x1f;
+ xreg = (insn >> 16) & 0x1f;
+ if (breg && xreg)
+ regs->gr[breg] += regs->gr[xreg];
+ }
+ regs->gr[0] |= PSW_N;
+ return 1;
+
+ case 0x180:
+ /* PROBE instruction */
+ treg = insn & 0x1f;
+ if (regs->isr) {
+ tsk = current;
+ mm = tsk->mm;
+ if (mm) {
+ /* Search for VMA */
+ address = regs->ior;
+ mmap_read_lock(mm);
+ vma = find_vma_prev(mm, address, &prev_vma);
+ mmap_read_unlock(mm);
+
+ /*
+ * Check if access to the VMA is okay.
+ * We don't allow for stack expansion.
+ */
+ acc_type = (insn & 0x40) ? VM_WRITE : VM_READ;
+ if (vma
+ && address >= vma->vm_start
+ && (vma->vm_flags & acc_type) == acc_type)
+ val = 1;
+ }
+ }
+ if (treg)
+ regs->gr[treg] = val;
+ regs->gr[0] |= PSW_N;
+ return 1;
+
+ case 0x300:
+ /* LPA instruction */
+ if (insn & 0x20) {
+ /* Base modification */
+ breg = (insn >> 21) & 0x1f;
+ xreg = (insn >> 16) & 0x1f;
+ if (breg && xreg)
+ regs->gr[breg] += regs->gr[xreg];
+ }
+ treg = insn & 0x1f;
+ if (treg)
+ regs->gr[treg] = 0;
+ regs->gr[0] |= PSW_N;
+ return 1;
+
+ default:
+ break;
+ }
+
+ return 0;
+}
diff --git a/arch/parisc/mm/init.c b/arch/parisc/mm/init.c
index 1ae31db9988f..1dc2e88e7b04 100644
--- a/arch/parisc/mm/init.c
+++ b/arch/parisc/mm/init.c
@@ -337,9 +337,9 @@ static void __init setup_bootmem(void)
static bool kernel_set_to_readonly;
-static void __init map_pages(unsigned long start_vaddr,
- unsigned long start_paddr, unsigned long size,
- pgprot_t pgprot, int force)
+static void __ref map_pages(unsigned long start_vaddr,
+ unsigned long start_paddr, unsigned long size,
+ pgprot_t pgprot, int force)
{
pmd_t *pmd;
pte_t *pg_table;
@@ -449,7 +449,7 @@ void __init set_kernel_text_rw(int enable_read_write)
flush_tlb_all();
}
-void __ref free_initmem(void)
+void free_initmem(void)
{
unsigned long init_begin = (unsigned long)__init_begin;
unsigned long init_end = (unsigned long)__init_end;
@@ -463,7 +463,6 @@ void __ref free_initmem(void)
/* The init text pages are marked R-X. We have to
* flush the icache and mark them RW-
*
- * This is tricky, because map_pages is in the init section.
* Do a dummy remap of the data section first (the data
* section is already PAGE_KERNEL) to pull in the TLB entries
* for map_kernel */
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index b779603978e1..7e7387bd7d53 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -108,6 +108,7 @@ config PPC
select ARCH_ENABLE_MEMORY_HOTPLUG
select ARCH_ENABLE_MEMORY_HOTREMOVE
select ARCH_HAS_COPY_MC if PPC64
+ select ARCH_HAS_CURRENT_STACK_POINTER
select ARCH_HAS_DEBUG_VIRTUAL
select ARCH_HAS_DEBUG_VM_PGTABLE
select ARCH_HAS_DEBUG_WX if STRICT_KERNEL_RWX
diff --git a/arch/powerpc/configs/linkstation_defconfig b/arch/powerpc/configs/linkstation_defconfig
index d4be64f190ff..fa707de761be 100644
--- a/arch/powerpc/configs/linkstation_defconfig
+++ b/arch/powerpc/configs/linkstation_defconfig
@@ -120,7 +120,6 @@ CONFIG_NFS_V3_ACL=y
CONFIG_NFS_V4=y
CONFIG_ROOT_NFS=y
CONFIG_NFSD=m
-CONFIG_NFSD_V3=y
CONFIG_CIFS=m
CONFIG_NLS_CODEPAGE_437=m
CONFIG_NLS_CODEPAGE_932=m
diff --git a/arch/powerpc/configs/mvme5100_defconfig b/arch/powerpc/configs/mvme5100_defconfig
index 1fed6be95d53..d1c7fd5bf34b 100644
--- a/arch/powerpc/configs/mvme5100_defconfig
+++ b/arch/powerpc/configs/mvme5100_defconfig
@@ -101,7 +101,6 @@ CONFIG_NFS_V3_ACL=y
CONFIG_NFS_V4=y
CONFIG_ROOT_NFS=y
CONFIG_NFSD=m
-CONFIG_NFSD_V3=y
CONFIG_CIFS=m
CONFIG_NLS=y
CONFIG_NLS_CODEPAGE_437=m
diff --git a/arch/powerpc/include/asm/agp.h b/arch/powerpc/include/asm/agp.h
index b29b1186f819..6b6485c988dd 100644
--- a/arch/powerpc/include/asm/agp.h
+++ b/arch/powerpc/include/asm/agp.h
@@ -5,8 +5,8 @@
#include <asm/io.h>
-#define map_page_into_agp(page)
-#define unmap_page_from_agp(page)
+#define map_page_into_agp(page) do {} while (0)
+#define unmap_page_from_agp(page) do {} while (0)
#define flush_agp_cache() mb()
/* GATT allocation. Returns/accepts GATT kernel virtual address. */
diff --git a/arch/powerpc/include/asm/book3s/32/mmu-hash.h b/arch/powerpc/include/asm/book3s/32/mmu-hash.h
index 7be27862329f..78c6a5fde1d6 100644
--- a/arch/powerpc/include/asm/book3s/32/mmu-hash.h
+++ b/arch/powerpc/include/asm/book3s/32/mmu-hash.h
@@ -223,6 +223,8 @@ static __always_inline void update_user_segments(u32 val)
update_user_segment(15, val);
}
+int __init find_free_bat(void);
+unsigned int bat_block_size(unsigned long base, unsigned long top);
#endif /* !__ASSEMBLY__ */
/* We happily ignore the smaller BATs on 601, we don't actually use
diff --git a/arch/powerpc/include/asm/book3s/32/pgtable.h b/arch/powerpc/include/asm/book3s/32/pgtable.h
index 609c80f67194..95e06f2a8e23 100644
--- a/arch/powerpc/include/asm/book3s/32/pgtable.h
+++ b/arch/powerpc/include/asm/book3s/32/pgtable.h
@@ -178,6 +178,7 @@ static inline bool pte_user(pte_t pte)
#ifndef __ASSEMBLY__
int map_kernel_page(unsigned long va, phys_addr_t pa, pgprot_t prot);
+void unmap_kernel_page(unsigned long va);
#endif /* !__ASSEMBLY__ */
@@ -371,8 +372,8 @@ static inline void __ptep_set_access_flags(struct vm_area_struct *vma,
#define __HAVE_ARCH_PTE_SAME
#define pte_same(A,B) (((pte_val(A) ^ pte_val(B)) & ~_PAGE_HASHPTE) == 0)
-#define pmd_page(pmd) \
- pfn_to_page(pmd_val(pmd) >> PAGE_SHIFT)
+#define pmd_pfn(pmd) (pmd_val(pmd) >> PAGE_SHIFT)
+#define pmd_page(pmd) pfn_to_page(pmd_pfn(pmd))
/*
* Encode and decode a swap entry.
diff --git a/arch/powerpc/include/asm/book3s/64/mmu.h b/arch/powerpc/include/asm/book3s/64/mmu.h
index ba5b1becf518..006cbec70ffe 100644
--- a/arch/powerpc/include/asm/book3s/64/mmu.h
+++ b/arch/powerpc/include/asm/book3s/64/mmu.h
@@ -202,7 +202,6 @@ static inline struct subpage_prot_table *mm_ctx_subpage_prot(mm_context_t *ctx)
/*
* The current system page and segment sizes
*/
-extern int mmu_linear_psize;
extern int mmu_virtual_psize;
extern int mmu_vmalloc_psize;
extern int mmu_io_psize;
@@ -213,6 +212,7 @@ extern int mmu_io_psize;
#define mmu_virtual_psize MMU_PAGE_4K
#endif
#endif
+extern int mmu_linear_psize;
extern int mmu_vmemmap_psize;
/* MMU initialization */
diff --git a/arch/powerpc/include/asm/book3s/64/pgtable.h b/arch/powerpc/include/asm/book3s/64/pgtable.h
index 33e073d6b0c4..875730d5af40 100644
--- a/arch/powerpc/include/asm/book3s/64/pgtable.h
+++ b/arch/powerpc/include/asm/book3s/64/pgtable.h
@@ -1082,6 +1082,8 @@ static inline int map_kernel_page(unsigned long ea, unsigned long pa, pgprot_t p
return hash__map_kernel_page(ea, pa, prot);
}
+void unmap_kernel_page(unsigned long va);
+
static inline int __meminit vmemmap_create_mapping(unsigned long start,
unsigned long page_size,
unsigned long phys)
diff --git a/arch/powerpc/include/asm/checksum.h b/arch/powerpc/include/asm/checksum.h
index 350de8f90250..ab3832b93f0a 100644
--- a/arch/powerpc/include/asm/checksum.h
+++ b/arch/powerpc/include/asm/checksum.h
@@ -112,6 +112,13 @@ static __always_inline __wsum csum_add(__wsum csum, __wsum addend)
#endif
}
+#define HAVE_ARCH_CSUM_SHIFT
+static __always_inline __wsum csum_shift(__wsum sum, int offset)
+{
+ /* rotate sum to align it with a 16b boundary */
+ return (__force __wsum)rol32((__force u32)sum, (offset & 1) << 3);
+}
+
/*
* This is a version of ip_compute_csum() optimized for IP headers,
* which always checksum on 4 octet boundaries. ihl is the number
diff --git a/arch/powerpc/include/asm/fadump-internal.h b/arch/powerpc/include/asm/fadump-internal.h
index 52189928ec08..81bcb9abb371 100644
--- a/arch/powerpc/include/asm/fadump-internal.h
+++ b/arch/powerpc/include/asm/fadump-internal.h
@@ -19,11 +19,6 @@
#define memblock_num_regions(memblock_type) (memblock.memblock_type.cnt)
-/* Alignment per CMA requirement. */
-#define FADUMP_CMA_ALIGNMENT (PAGE_SIZE << \
- max_t(unsigned long, MAX_ORDER - 1, \
- pageblock_order))
-
/* FAD commands */
#define FADUMP_REGISTER 1
#define FADUMP_UNREGISTER 2
diff --git a/arch/powerpc/include/asm/fixmap.h b/arch/powerpc/include/asm/fixmap.h
index 947b5b9c4424..a832aeafe560 100644
--- a/arch/powerpc/include/asm/fixmap.h
+++ b/arch/powerpc/include/asm/fixmap.h
@@ -111,8 +111,10 @@ static inline void __set_fixmap(enum fixed_addresses idx,
BUILD_BUG_ON(idx >= __end_of_fixed_addresses);
else if (WARN_ON(idx >= __end_of_fixed_addresses))
return;
-
- map_kernel_page(__fix_to_virt(idx), phys, flags);
+ if (pgprot_val(flags))
+ map_kernel_page(__fix_to_virt(idx), phys, flags);
+ else
+ unmap_kernel_page(__fix_to_virt(idx));
}
#define __early_set_fixmap __set_fixmap
diff --git a/arch/powerpc/include/asm/hw_irq.h b/arch/powerpc/include/asm/hw_irq.h
index a58fb4aa6c81..674e5aaafcbd 100644
--- a/arch/powerpc/include/asm/hw_irq.h
+++ b/arch/powerpc/include/asm/hw_irq.h
@@ -473,7 +473,7 @@ static inline bool arch_irq_disabled_regs(struct pt_regs *regs)
return !(regs->msr & MSR_EE);
}
-static inline bool should_hard_irq_enable(void)
+static __always_inline bool should_hard_irq_enable(void)
{
return false;
}
diff --git a/arch/powerpc/include/asm/kexec_ranges.h b/arch/powerpc/include/asm/kexec_ranges.h
index 7a90000f8d15..f83866a19e87 100644
--- a/arch/powerpc/include/asm/kexec_ranges.h
+++ b/arch/powerpc/include/asm/kexec_ranges.h
@@ -9,7 +9,7 @@ struct crash_mem *realloc_mem_ranges(struct crash_mem **mem_ranges);
int add_mem_range(struct crash_mem **mem_ranges, u64 base, u64 size);
int add_tce_mem_ranges(struct crash_mem **mem_ranges);
int add_initrd_mem_range(struct crash_mem **mem_ranges);
-#ifdef CONFIG_PPC_BOOK3S_64
+#ifdef CONFIG_PPC_64S_HASH_MMU
int add_htab_mem_range(struct crash_mem **mem_ranges);
#else
static inline int add_htab_mem_range(struct crash_mem **mem_ranges)
diff --git a/arch/powerpc/include/asm/kvm_book3s_64.h b/arch/powerpc/include/asm/kvm_book3s_64.h
index fe07558173ef..827038a33064 100644
--- a/arch/powerpc/include/asm/kvm_book3s_64.h
+++ b/arch/powerpc/include/asm/kvm_book3s_64.h
@@ -39,7 +39,6 @@ struct kvm_nested_guest {
pgd_t *shadow_pgtable; /* our page table for this guest */
u64 l1_gr_to_hr; /* L1's addr of part'n-scoped table */
u64 process_table; /* process table entry for this guest */
- u64 hfscr; /* HFSCR that the L1 requested for this nested guest */
long refcnt; /* number of pointers to this struct */
struct mutex tlb_lock; /* serialize page faults and tlbies */
struct kvm_nested_guest *next;
diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h
index a770443cd6e0..d9bf60bf0816 100644
--- a/arch/powerpc/include/asm/kvm_host.h
+++ b/arch/powerpc/include/asm/kvm_host.h
@@ -818,6 +818,7 @@ struct kvm_vcpu_arch {
/* For support of nested guests */
struct kvm_nested_guest *nested;
+ u64 nested_hfscr; /* HFSCR that the L1 requested for the nested guest */
u32 nested_vcpu_id;
gpa_t nested_io_gpr;
#endif
diff --git a/arch/powerpc/include/asm/mmu_context.h b/arch/powerpc/include/asm/mmu_context.h
index fd277b15635c..b8527a74bd4d 100644
--- a/arch/powerpc/include/asm/mmu_context.h
+++ b/arch/powerpc/include/asm/mmu_context.h
@@ -21,7 +21,6 @@ extern void destroy_context(struct mm_struct *mm);
#ifdef CONFIG_SPAPR_TCE_IOMMU
struct mm_iommu_table_group_mem_t;
-extern int isolate_lru_page(struct page *page); /* from internal.h */
extern bool mm_iommu_preregistered(struct mm_struct *mm);
extern long mm_iommu_new(struct mm_struct *mm,
unsigned long ua, unsigned long entries,
diff --git a/arch/powerpc/include/asm/nmi.h b/arch/powerpc/include/asm/nmi.h
index 160abcb8e9fa..ea0e487f87b1 100644
--- a/arch/powerpc/include/asm/nmi.h
+++ b/arch/powerpc/include/asm/nmi.h
@@ -9,7 +9,7 @@ long soft_nmi_interrupt(struct pt_regs *regs);
static inline void arch_touch_nmi_watchdog(void) {}
#endif
-#if defined(CONFIG_NMI_IPI) && defined(CONFIG_STACKTRACE)
+#ifdef CONFIG_NMI_IPI
extern void arch_trigger_cpumask_backtrace(const cpumask_t *mask,
bool exclude_self);
#define arch_trigger_cpumask_backtrace arch_trigger_cpumask_backtrace
diff --git a/arch/powerpc/include/asm/nohash/32/hugetlb-8xx.h b/arch/powerpc/include/asm/nohash/32/hugetlb-8xx.h
index 64b6c608eca4..de092b04ee1a 100644
--- a/arch/powerpc/include/asm/nohash/32/hugetlb-8xx.h
+++ b/arch/powerpc/include/asm/nohash/32/hugetlb-8xx.h
@@ -71,9 +71,9 @@ static inline pte_t arch_make_huge_pte(pte_t entry, unsigned int shift, vm_flags
size_t size = 1UL << shift;
if (size == SZ_16K)
- return __pte(pte_val(entry) & ~_PAGE_HUGE);
+ return __pte(pte_val(entry) | _PAGE_SPS);
else
- return entry;
+ return __pte(pte_val(entry) | _PAGE_SPS | _PAGE_HUGE);
}
#define arch_make_huge_pte arch_make_huge_pte
#endif
diff --git a/arch/powerpc/include/asm/nohash/32/pgtable.h b/arch/powerpc/include/asm/nohash/32/pgtable.h
index b67742e2a9b2..dcc9b338e042 100644
--- a/arch/powerpc/include/asm/nohash/32/pgtable.h
+++ b/arch/powerpc/include/asm/nohash/32/pgtable.h
@@ -64,6 +64,7 @@ extern int icache_44x_need_flush;
#ifndef __ASSEMBLY__
int map_kernel_page(unsigned long va, phys_addr_t pa, pgprot_t prot);
+void unmap_kernel_page(unsigned long va);
#endif /* !__ASSEMBLY__ */
@@ -348,15 +349,14 @@ static inline int pte_young(pte_t pte)
* of the pte page. -- paulus
*/
#ifndef CONFIG_BOOKE
-#define pmd_page(pmd) \
- pfn_to_page(pmd_val(pmd) >> PAGE_SHIFT)
+#define pmd_pfn(pmd) (pmd_val(pmd) >> PAGE_SHIFT)
#else
#define pmd_page_vaddr(pmd) \
((unsigned long)(pmd_val(pmd) & ~(PTE_TABLE_SIZE - 1)))
-#define pmd_page(pmd) \
- pfn_to_page((__pa(pmd_val(pmd)) >> PAGE_SHIFT))
+#define pmd_pfn(pmd) (__pa(pmd_val(pmd)) >> PAGE_SHIFT)
#endif
+#define pmd_page(pmd) pfn_to_page(pmd_pfn(pmd))
/*
* Encode and decode a swap entry.
* Note that the bits we use in a PTE for representing a swap entry
diff --git a/arch/powerpc/include/asm/nohash/64/pgtable.h b/arch/powerpc/include/asm/nohash/64/pgtable.h
index a3313e853e5e..78888b0c30f6 100644
--- a/arch/powerpc/include/asm/nohash/64/pgtable.h
+++ b/arch/powerpc/include/asm/nohash/64/pgtable.h
@@ -142,6 +142,7 @@ static inline pte_t pmd_pte(pmd_t pmd)
#define pmd_present(pmd) (!pmd_none(pmd))
#define pmd_page_vaddr(pmd) (pmd_val(pmd) & ~PMD_MASKED_BITS)
extern struct page *pmd_page(pmd_t pmd);
+#define pmd_pfn(pmd) (page_to_pfn(pmd_page(pmd)))
static inline void pud_set(pud_t *pudp, unsigned long val)
{
@@ -308,6 +309,7 @@ static inline void __ptep_set_access_flags(struct vm_area_struct *vma,
#define __swp_entry_to_pte(x) __pte((x).val)
int map_kernel_page(unsigned long ea, unsigned long pa, pgprot_t prot);
+void unmap_kernel_page(unsigned long va);
extern int __meminit vmemmap_create_mapping(unsigned long start,
unsigned long page_size,
unsigned long phys);
diff --git a/arch/powerpc/include/asm/ppc-opcode.h b/arch/powerpc/include/asm/ppc-opcode.h
index efad07081cc0..9675303b724e 100644
--- a/arch/powerpc/include/asm/ppc-opcode.h
+++ b/arch/powerpc/include/asm/ppc-opcode.h
@@ -500,6 +500,7 @@
#define PPC_RAW_LDX(r, base, b) (0x7c00002a | ___PPC_RT(r) | ___PPC_RA(base) | ___PPC_RB(b))
#define PPC_RAW_LHZ(r, base, i) (0xa0000000 | ___PPC_RT(r) | ___PPC_RA(base) | IMM_L(i))
#define PPC_RAW_LHBRX(r, base, b) (0x7c00062c | ___PPC_RT(r) | ___PPC_RA(base) | ___PPC_RB(b))
+#define PPC_RAW_LWBRX(r, base, b) (0x7c00042c | ___PPC_RT(r) | ___PPC_RA(base) | ___PPC_RB(b))
#define PPC_RAW_LDBRX(r, base, b) (0x7c000428 | ___PPC_RT(r) | ___PPC_RA(base) | ___PPC_RB(b))
#define PPC_RAW_STWCX(s, a, b) (0x7c00012d | ___PPC_RS(s) | ___PPC_RA(a) | ___PPC_RB(b))
#define PPC_RAW_CMPWI(a, i) (0x2c000000 | ___PPC_RA(a) | IMM_L(i))
diff --git a/arch/powerpc/include/asm/syscall.h b/arch/powerpc/include/asm/syscall.h
index 52d05b465e3e..25fc8ad9a27a 100644
--- a/arch/powerpc/include/asm/syscall.h
+++ b/arch/powerpc/include/asm/syscall.h
@@ -90,7 +90,7 @@ static inline void syscall_get_arguments(struct task_struct *task,
unsigned long val, mask = -1UL;
unsigned int n = 6;
- if (is_32bit_task())
+ if (is_tsk_32bit_task(task))
mask = 0xffffffff;
while (n--) {
@@ -105,7 +105,7 @@ static inline void syscall_get_arguments(struct task_struct *task,
static inline int syscall_get_arch(struct task_struct *task)
{
- if (is_32bit_task())
+ if (is_tsk_32bit_task(task))
return AUDIT_ARCH_PPC;
else if (IS_ENABLED(CONFIG_CPU_LITTLE_ENDIAN))
return AUDIT_ARCH_PPC64LE;
diff --git a/arch/powerpc/include/asm/thread_info.h b/arch/powerpc/include/asm/thread_info.h
index 5725029aaa29..d6e649b3c70b 100644
--- a/arch/powerpc/include/asm/thread_info.h
+++ b/arch/powerpc/include/asm/thread_info.h
@@ -168,8 +168,10 @@ static inline bool test_thread_local_flags(unsigned int flags)
#ifdef CONFIG_COMPAT
#define is_32bit_task() (test_thread_flag(TIF_32BIT))
+#define is_tsk_32bit_task(tsk) (test_tsk_thread_flag(tsk, TIF_32BIT))
#else
#define is_32bit_task() (IS_ENABLED(CONFIG_PPC32))
+#define is_tsk_32bit_task(tsk) (IS_ENABLED(CONFIG_PPC32))
#endif
#if defined(CONFIG_PPC64)
diff --git a/arch/powerpc/include/asm/uaccess.h b/arch/powerpc/include/asm/uaccess.h
index 63316100080c..2e83217f52de 100644
--- a/arch/powerpc/include/asm/uaccess.h
+++ b/arch/powerpc/include/asm/uaccess.h
@@ -11,18 +11,9 @@
#ifdef __powerpc64__
/* We use TASK_SIZE_USER64 as TASK_SIZE is not constant */
#define TASK_SIZE_MAX TASK_SIZE_USER64
-#else
-#define TASK_SIZE_MAX TASK_SIZE
#endif
-static inline bool __access_ok(unsigned long addr, unsigned long size)
-{
- return addr < TASK_SIZE_MAX && size <= TASK_SIZE_MAX - addr;
-}
-
-#define access_ok(addr, size) \
- (__chk_user_ptr(addr), \
- __access_ok((unsigned long)(addr), (size)))
+#include <asm-generic/access_ok.h>
/*
* These are the main single-value transfer routines. They automatically
@@ -467,8 +458,6 @@ do { \
unsafe_put_user(*(u8*)(_src + _i), (u8 __user *)(_dst + _i), e); \
} while (0)
-#define HAVE_GET_KERNEL_NOFAULT
-
#define __get_kernel_nofault(dst, src, type, err_label) \
__get_user_size_goto(*((type *)(dst)), \
(__force type __user *)(src), sizeof(type), err_label)
diff --git a/arch/powerpc/include/asm/xor_altivec.h b/arch/powerpc/include/asm/xor_altivec.h
index 6ca923510b59..294620a25f80 100644
--- a/arch/powerpc/include/asm/xor_altivec.h
+++ b/arch/powerpc/include/asm/xor_altivec.h
@@ -3,17 +3,20 @@
#define _ASM_POWERPC_XOR_ALTIVEC_H
#ifdef CONFIG_ALTIVEC
-
-void xor_altivec_2(unsigned long bytes, unsigned long *v1_in,
- unsigned long *v2_in);
-void xor_altivec_3(unsigned long bytes, unsigned long *v1_in,
- unsigned long *v2_in, unsigned long *v3_in);
-void xor_altivec_4(unsigned long bytes, unsigned long *v1_in,
- unsigned long *v2_in, unsigned long *v3_in,
- unsigned long *v4_in);
-void xor_altivec_5(unsigned long bytes, unsigned long *v1_in,
- unsigned long *v2_in, unsigned long *v3_in,
- unsigned long *v4_in, unsigned long *v5_in);
+void xor_altivec_2(unsigned long bytes, unsigned long * __restrict p1,
+ const unsigned long * __restrict p2);
+void xor_altivec_3(unsigned long bytes, unsigned long * __restrict p1,
+ const unsigned long * __restrict p2,
+ const unsigned long * __restrict p3);
+void xor_altivec_4(unsigned long bytes, unsigned long * __restrict p1,
+ const unsigned long * __restrict p2,
+ const unsigned long * __restrict p3,
+ const unsigned long * __restrict p4);
+void xor_altivec_5(unsigned long bytes, unsigned long * __restrict p1,
+ const unsigned long * __restrict p2,
+ const unsigned long * __restrict p3,
+ const unsigned long * __restrict p4,
+ const unsigned long * __restrict p5);
#endif
#endif /* _ASM_POWERPC_XOR_ALTIVEC_H */
diff --git a/arch/powerpc/include/uapi/asm/shmbuf.h b/arch/powerpc/include/uapi/asm/shmbuf.h
index 00422b2f3c63..439a3a02ba64 100644
--- a/arch/powerpc/include/uapi/asm/shmbuf.h
+++ b/arch/powerpc/include/uapi/asm/shmbuf.h
@@ -2,6 +2,9 @@
#ifndef _ASM_POWERPC_SHMBUF_H
#define _ASM_POWERPC_SHMBUF_H
+#include <asm/ipcbuf.h>
+#include <asm/posix_types.h>
+
/*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -34,7 +37,7 @@ struct shmid64_ds {
unsigned long shm_ctime; /* last change time */
unsigned long __unused4;
#endif
- size_t shm_segsz; /* size of segment (bytes) */
+ __kernel_size_t shm_segsz; /* size of segment (bytes) */
__kernel_pid_t shm_cpid; /* pid of creator */
__kernel_pid_t shm_lpid; /* pid of last operator */
unsigned long shm_nattch; /* no. of current attaches */
diff --git a/arch/powerpc/include/uapi/asm/signal.h b/arch/powerpc/include/uapi/asm/signal.h
index 04873dd311c2..37d41d87c45b 100644
--- a/arch/powerpc/include/uapi/asm/signal.h
+++ b/arch/powerpc/include/uapi/asm/signal.h
@@ -86,7 +86,7 @@ struct sigaction {
typedef struct sigaltstack {
void __user *ss_sp;
int ss_flags;
- size_t ss_size;
+ __kernel_size_t ss_size;
} stack_t;
diff --git a/arch/powerpc/kernel/fadump.c b/arch/powerpc/kernel/fadump.c
index d03e488cfe9c..4fdb7c77fda1 100644
--- a/arch/powerpc/kernel/fadump.c
+++ b/arch/powerpc/kernel/fadump.c
@@ -113,6 +113,12 @@ static int __init fadump_cma_init(void)
}
/*
+ * If CMA activation fails, keep the pages reserved, instead of
+ * exposing them to buddy allocator. Same as 'fadump=nocma' case.
+ */
+ cma_reserve_pages_on_error(fadump_cma);
+
+ /*
* So we now have successfully initialized cma area for fadump.
*/
pr_info("Initialized 0x%lx bytes cma area at %ldMB from 0x%lx "
@@ -544,7 +550,7 @@ int __init fadump_reserve_mem(void)
if (!fw_dump.nocma) {
fw_dump.boot_memory_size =
ALIGN(fw_dump.boot_memory_size,
- FADUMP_CMA_ALIGNMENT);
+ CMA_MIN_ALIGNMENT_BYTES);
}
#endif
diff --git a/arch/powerpc/kernel/head_book3s_32.S b/arch/powerpc/kernel/head_book3s_32.S
index fa84744d6b24..b876ef8c70a7 100644
--- a/arch/powerpc/kernel/head_book3s_32.S
+++ b/arch/powerpc/kernel/head_book3s_32.S
@@ -421,14 +421,14 @@ InstructionTLBMiss:
*/
/* Get PTE (linux-style) and check access */
mfspr r3,SPRN_IMISS
-#ifdef CONFIG_MODULES
+#if defined(CONFIG_MODULES) || defined(CONFIG_DEBUG_PAGEALLOC) || defined(CONFIG_KFENCE)
lis r1, TASK_SIZE@h /* check if kernel address */
cmplw 0,r1,r3
#endif
mfspr r2, SPRN_SDR1
li r1,_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_EXEC | _PAGE_USER
rlwinm r2, r2, 28, 0xfffff000
-#ifdef CONFIG_MODULES
+#if defined(CONFIG_MODULES) || defined(CONFIG_DEBUG_PAGEALLOC) || defined(CONFIG_KFENCE)
bgt- 112f
lis r2, (swapper_pg_dir - PAGE_OFFSET)@ha /* if kernel address, use */
li r1,_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_EXEC
diff --git a/arch/powerpc/kernel/interrupt_64.S b/arch/powerpc/kernel/interrupt_64.S
index 92088f848266..7bab2d7de372 100644
--- a/arch/powerpc/kernel/interrupt_64.S
+++ b/arch/powerpc/kernel/interrupt_64.S
@@ -30,6 +30,7 @@ COMPAT_SYS_CALL_TABLE:
.ifc \srr,srr
mfspr r11,SPRN_SRR0
ld r12,_NIP(r1)
+ clrrdi r11,r11,2
clrrdi r12,r12,2
100: tdne r11,r12
EMIT_WARN_ENTRY 100b,__FILE__,__LINE__,(BUGFLAG_WARNING | BUGFLAG_ONCE)
@@ -40,6 +41,7 @@ COMPAT_SYS_CALL_TABLE:
.else
mfspr r11,SPRN_HSRR0
ld r12,_NIP(r1)
+ clrrdi r11,r11,2
clrrdi r12,r12,2
100: tdne r11,r12
EMIT_WARN_ENTRY 100b,__FILE__,__LINE__,(BUGFLAG_WARNING | BUGFLAG_ONCE)
diff --git a/arch/powerpc/kernel/sysfs.c b/arch/powerpc/kernel/sysfs.c
index d45a415d5374..2069bbb90a9a 100644
--- a/arch/powerpc/kernel/sysfs.c
+++ b/arch/powerpc/kernel/sysfs.c
@@ -1110,14 +1110,6 @@ EXPORT_SYMBOL_GPL(cpu_remove_dev_attr_group);
/* NUMA stuff */
#ifdef CONFIG_NUMA
-static void __init register_nodes(void)
-{
- int i;
-
- for (i = 0; i < MAX_NUMNODES; i++)
- register_one_node(i);
-}
-
int sysfs_add_device_to_node(struct device *dev, int nid)
{
struct node *node = node_devices[nid];
@@ -1132,13 +1124,6 @@ void sysfs_remove_device_from_node(struct device *dev, int nid)
sysfs_remove_link(&node->dev.kobj, kobject_name(&dev->kobj));
}
EXPORT_SYMBOL_GPL(sysfs_remove_device_from_node);
-
-#else
-static void __init register_nodes(void)
-{
- return;
-}
-
#endif
/* Only valid if CPU is present. */
@@ -1155,8 +1140,6 @@ static int __init topology_init(void)
{
int cpu, r;
- register_nodes();
-
for_each_possible_cpu(cpu) {
struct cpu *c = &per_cpu(cpu_devices, cpu);
diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c
index 62361cc7281c..cd0b8b71ecdd 100644
--- a/arch/powerpc/kernel/time.c
+++ b/arch/powerpc/kernel/time.c
@@ -649,8 +649,9 @@ DEFINE_INTERRUPT_HANDLER_ASYNC(timer_interrupt)
__this_cpu_inc(irq_stat.timer_irqs_event);
} else {
now = *next_tb - now;
- if (now <= decrementer_max)
- set_dec_or_work(now);
+ if (now > decrementer_max)
+ now = decrementer_max;
+ set_dec_or_work(now);
__this_cpu_inc(irq_stat.timer_irqs_others);
}
diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c
index d1817cd9a691..84c89f08ae9a 100644
--- a/arch/powerpc/kvm/book3s_hv.c
+++ b/arch/powerpc/kvm/book3s_hv.c
@@ -1816,7 +1816,6 @@ static int kvmppc_handle_exit_hv(struct kvm_vcpu *vcpu,
static int kvmppc_handle_nested_exit(struct kvm_vcpu *vcpu)
{
- struct kvm_nested_guest *nested = vcpu->arch.nested;
int r;
int srcu_idx;
@@ -1922,7 +1921,7 @@ static int kvmppc_handle_nested_exit(struct kvm_vcpu *vcpu)
* it into a HEAI.
*/
if (!(vcpu->arch.hfscr_permitted & (1UL << cause)) ||
- (nested->hfscr & (1UL << cause))) {
+ (vcpu->arch.nested_hfscr & (1UL << cause))) {
vcpu->arch.trap = BOOK3S_INTERRUPT_H_EMUL_ASSIST;
/*
diff --git a/arch/powerpc/kvm/book3s_hv_nested.c b/arch/powerpc/kvm/book3s_hv_nested.c
index 8f8daaeeb3b7..9d373f8963ee 100644
--- a/arch/powerpc/kvm/book3s_hv_nested.c
+++ b/arch/powerpc/kvm/book3s_hv_nested.c
@@ -363,7 +363,7 @@ long kvmhv_enter_nested_guest(struct kvm_vcpu *vcpu)
/* set L1 state to L2 state */
vcpu->arch.nested = l2;
vcpu->arch.nested_vcpu_id = l2_hv.vcpu_token;
- l2->hfscr = l2_hv.hfscr;
+ vcpu->arch.nested_hfscr = l2_hv.hfscr;
vcpu->arch.regs = l2_regs;
/* Guest must always run with ME enabled, HV disabled. */
diff --git a/arch/powerpc/kvm/book3s_hv_uvmem.c b/arch/powerpc/kvm/book3s_hv_uvmem.c
index e414ca44839f..45c993dd05f5 100644
--- a/arch/powerpc/kvm/book3s_hv_uvmem.c
+++ b/arch/powerpc/kvm/book3s_hv_uvmem.c
@@ -91,6 +91,7 @@
#include <linux/kvm_host.h>
#include <linux/ksm.h>
#include <linux/of.h>
+#include <linux/memremap.h>
#include <asm/ultravisor.h>
#include <asm/mman.h>
#include <asm/kvm_ppc.h>
@@ -251,7 +252,7 @@ int kvmppc_uvmem_slot_init(struct kvm *kvm, const struct kvm_memory_slot *slot)
p = kzalloc(sizeof(*p), GFP_KERNEL);
if (!p)
return -ENOMEM;
- p->pfns = vzalloc(array_size(slot->npages, sizeof(*p->pfns)));
+ p->pfns = vcalloc(slot->npages, sizeof(*p->pfns));
if (!p->pfns) {
kfree(p);
return -ENOMEM;
@@ -712,7 +713,6 @@ static struct page *kvmppc_uvmem_get_page(unsigned long gpa, struct kvm *kvm)
dpage = pfn_to_page(uvmem_pfn);
dpage->zone_device_data = pvt;
- get_page(dpage);
lock_page(dpage);
return dpage;
out_clear:
diff --git a/arch/powerpc/lib/sstep.c b/arch/powerpc/lib/sstep.c
index a94b0cd0bdc5..5ed88fbee0db 100644
--- a/arch/powerpc/lib/sstep.c
+++ b/arch/powerpc/lib/sstep.c
@@ -112,9 +112,9 @@ static nokprobe_inline long address_ok(struct pt_regs *regs,
{
if (!user_mode(regs))
return 1;
- if (__access_ok(ea, nb))
+ if (access_ok((void __user *)ea, nb))
return 1;
- if (__access_ok(ea, 1))
+ if (access_ok((void __user *)ea, 1))
/* Access overlaps the end of the user region */
regs->dar = TASK_SIZE_MAX - 1;
else
@@ -3264,12 +3264,14 @@ void emulate_update_regs(struct pt_regs *regs, struct instruction_op *op)
case BARRIER_EIEIO:
eieio();
break;
+#ifdef CONFIG_PPC64
case BARRIER_LWSYNC:
asm volatile("lwsync" : : : "memory");
break;
case BARRIER_PTESYNC:
asm volatile("ptesync" : : : "memory");
break;
+#endif
}
break;
diff --git a/arch/powerpc/lib/xor_vmx.c b/arch/powerpc/lib/xor_vmx.c
index 54e61979e80e..aab49d056d18 100644
--- a/arch/powerpc/lib/xor_vmx.c
+++ b/arch/powerpc/lib/xor_vmx.c
@@ -49,8 +49,9 @@ typedef vector signed char unative_t;
V1##_3 = vec_xor(V1##_3, V2##_3); \
} while (0)
-void __xor_altivec_2(unsigned long bytes, unsigned long *v1_in,
- unsigned long *v2_in)
+void __xor_altivec_2(unsigned long bytes,
+ unsigned long * __restrict v1_in,
+ const unsigned long * __restrict v2_in)
{
DEFINE(v1);
DEFINE(v2);
@@ -67,8 +68,10 @@ void __xor_altivec_2(unsigned long bytes, unsigned long *v1_in,
} while (--lines > 0);
}
-void __xor_altivec_3(unsigned long bytes, unsigned long *v1_in,
- unsigned long *v2_in, unsigned long *v3_in)
+void __xor_altivec_3(unsigned long bytes,
+ unsigned long * __restrict v1_in,
+ const unsigned long * __restrict v2_in,
+ const unsigned long * __restrict v3_in)
{
DEFINE(v1);
DEFINE(v2);
@@ -89,9 +92,11 @@ void __xor_altivec_3(unsigned long bytes, unsigned long *v1_in,
} while (--lines > 0);
}
-void __xor_altivec_4(unsigned long bytes, unsigned long *v1_in,
- unsigned long *v2_in, unsigned long *v3_in,
- unsigned long *v4_in)
+void __xor_altivec_4(unsigned long bytes,
+ unsigned long * __restrict v1_in,
+ const unsigned long * __restrict v2_in,
+ const unsigned long * __restrict v3_in,
+ const unsigned long * __restrict v4_in)
{
DEFINE(v1);
DEFINE(v2);
@@ -116,9 +121,12 @@ void __xor_altivec_4(unsigned long bytes, unsigned long *v1_in,
} while (--lines > 0);
}
-void __xor_altivec_5(unsigned long bytes, unsigned long *v1_in,
- unsigned long *v2_in, unsigned long *v3_in,
- unsigned long *v4_in, unsigned long *v5_in)
+void __xor_altivec_5(unsigned long bytes,
+ unsigned long * __restrict v1_in,
+ const unsigned long * __restrict v2_in,
+ const unsigned long * __restrict v3_in,
+ const unsigned long * __restrict v4_in,
+ const unsigned long * __restrict v5_in)
{
DEFINE(v1);
DEFINE(v2);
diff --git a/arch/powerpc/lib/xor_vmx.h b/arch/powerpc/lib/xor_vmx.h
index 5c2b0839b179..573c41d90dac 100644
--- a/arch/powerpc/lib/xor_vmx.h
+++ b/arch/powerpc/lib/xor_vmx.h
@@ -6,16 +6,17 @@
* outside of the enable/disable altivec block.
*/
-void __xor_altivec_2(unsigned long bytes, unsigned long *v1_in,
- unsigned long *v2_in);
-
-void __xor_altivec_3(unsigned long bytes, unsigned long *v1_in,
- unsigned long *v2_in, unsigned long *v3_in);
-
-void __xor_altivec_4(unsigned long bytes, unsigned long *v1_in,
- unsigned long *v2_in, unsigned long *v3_in,
- unsigned long *v4_in);
-
-void __xor_altivec_5(unsigned long bytes, unsigned long *v1_in,
- unsigned long *v2_in, unsigned long *v3_in,
- unsigned long *v4_in, unsigned long *v5_in);
+void __xor_altivec_2(unsigned long bytes, unsigned long * __restrict p1,
+ const unsigned long * __restrict p2);
+void __xor_altivec_3(unsigned long bytes, unsigned long * __restrict p1,
+ const unsigned long * __restrict p2,
+ const unsigned long * __restrict p3);
+void __xor_altivec_4(unsigned long bytes, unsigned long * __restrict p1,
+ const unsigned long * __restrict p2,
+ const unsigned long * __restrict p3,
+ const unsigned long * __restrict p4);
+void __xor_altivec_5(unsigned long bytes, unsigned long * __restrict p1,
+ const unsigned long * __restrict p2,
+ const unsigned long * __restrict p3,
+ const unsigned long * __restrict p4,
+ const unsigned long * __restrict p5);
diff --git a/arch/powerpc/lib/xor_vmx_glue.c b/arch/powerpc/lib/xor_vmx_glue.c
index 80dba916c367..35d917ece4d1 100644
--- a/arch/powerpc/lib/xor_vmx_glue.c
+++ b/arch/powerpc/lib/xor_vmx_glue.c
@@ -12,47 +12,51 @@
#include <asm/xor_altivec.h>
#include "xor_vmx.h"
-void xor_altivec_2(unsigned long bytes, unsigned long *v1_in,
- unsigned long *v2_in)
+void xor_altivec_2(unsigned long bytes, unsigned long * __restrict p1,
+ const unsigned long * __restrict p2)
{
preempt_disable();
enable_kernel_altivec();
- __xor_altivec_2(bytes, v1_in, v2_in);
+ __xor_altivec_2(bytes, p1, p2);
disable_kernel_altivec();
preempt_enable();
}
EXPORT_SYMBOL(xor_altivec_2);
-void xor_altivec_3(unsigned long bytes, unsigned long *v1_in,
- unsigned long *v2_in, unsigned long *v3_in)
+void xor_altivec_3(unsigned long bytes, unsigned long * __restrict p1,
+ const unsigned long * __restrict p2,
+ const unsigned long * __restrict p3)
{
preempt_disable();
enable_kernel_altivec();
- __xor_altivec_3(bytes, v1_in, v2_in, v3_in);
+ __xor_altivec_3(bytes, p1, p2, p3);
disable_kernel_altivec();
preempt_enable();
}
EXPORT_SYMBOL(xor_altivec_3);
-void xor_altivec_4(unsigned long bytes, unsigned long *v1_in,
- unsigned long *v2_in, unsigned long *v3_in,
- unsigned long *v4_in)
+void xor_altivec_4(unsigned long bytes, unsigned long * __restrict p1,
+ const unsigned long * __restrict p2,
+ const unsigned long * __restrict p3,
+ const unsigned long * __restrict p4)
{
preempt_disable();
enable_kernel_altivec();
- __xor_altivec_4(bytes, v1_in, v2_in, v3_in, v4_in);
+ __xor_altivec_4(bytes, p1, p2, p3, p4);
disable_kernel_altivec();
preempt_enable();
}
EXPORT_SYMBOL(xor_altivec_4);
-void xor_altivec_5(unsigned long bytes, unsigned long *v1_in,
- unsigned long *v2_in, unsigned long *v3_in,
- unsigned long *v4_in, unsigned long *v5_in)
+void xor_altivec_5(unsigned long bytes, unsigned long * __restrict p1,
+ const unsigned long * __restrict p2,
+ const unsigned long * __restrict p3,
+ const unsigned long * __restrict p4,
+ const unsigned long * __restrict p5)
{
preempt_disable();
enable_kernel_altivec();
- __xor_altivec_5(bytes, v1_in, v2_in, v3_in, v4_in, v5_in);
+ __xor_altivec_5(bytes, p1, p2, p3, p4, p5);
disable_kernel_altivec();
preempt_enable();
}
diff --git a/arch/powerpc/mm/book3s32/mmu.c b/arch/powerpc/mm/book3s32/mmu.c
index 94045b265b6b..203735caf691 100644
--- a/arch/powerpc/mm/book3s32/mmu.c
+++ b/arch/powerpc/mm/book3s32/mmu.c
@@ -76,7 +76,7 @@ unsigned long p_block_mapped(phys_addr_t pa)
return 0;
}
-static int __init find_free_bat(void)
+int __init find_free_bat(void)
{
int b;
int n = mmu_has_feature(MMU_FTR_USE_HIGH_BATS) ? 8 : 4;
@@ -100,7 +100,7 @@ static int __init find_free_bat(void)
* - block size has to be a power of two. This is calculated by finding the
* highest bit set to 1.
*/
-static unsigned int block_size(unsigned long base, unsigned long top)
+unsigned int bat_block_size(unsigned long base, unsigned long top)
{
unsigned int max_size = SZ_256M;
unsigned int base_shift = (ffs(base) - 1) & 31;
@@ -145,7 +145,7 @@ static unsigned long __init __mmu_mapin_ram(unsigned long base, unsigned long to
int idx;
while ((idx = find_free_bat()) != -1 && base != top) {
- unsigned int size = block_size(base, top);
+ unsigned int size = bat_block_size(base, top);
if (size < 128 << 10)
break;
@@ -201,12 +201,12 @@ void mmu_mark_initmem_nx(void)
unsigned long size;
for (i = 0; i < nb - 1 && base < top;) {
- size = block_size(base, top);
+ size = bat_block_size(base, top);
setibat(i++, PAGE_OFFSET + base, base, size, PAGE_KERNEL_TEXT);
base += size;
}
if (base < top) {
- size = block_size(base, top);
+ size = bat_block_size(base, top);
if ((top - base) > size) {
size <<= 1;
if (strict_kernel_rwx_enabled() && base + size > border)
diff --git a/arch/powerpc/mm/book3s64/pgtable.c b/arch/powerpc/mm/book3s64/pgtable.c
index 79ce3c22a29d..052e6590f84f 100644
--- a/arch/powerpc/mm/book3s64/pgtable.c
+++ b/arch/powerpc/mm/book3s64/pgtable.c
@@ -6,6 +6,7 @@
#include <linux/sched.h>
#include <linux/mm_types.h>
#include <linux/memblock.h>
+#include <linux/memremap.h>
#include <linux/debugfs.h>
#include <misc/cxl-base.h>
diff --git a/arch/powerpc/mm/kasan/book3s_32.c b/arch/powerpc/mm/kasan/book3s_32.c
index 35b287b0a8da..450a67ef0bbe 100644
--- a/arch/powerpc/mm/kasan/book3s_32.c
+++ b/arch/powerpc/mm/kasan/book3s_32.c
@@ -10,48 +10,51 @@ int __init kasan_init_region(void *start, size_t size)
{
unsigned long k_start = (unsigned long)kasan_mem_to_shadow(start);
unsigned long k_end = (unsigned long)kasan_mem_to_shadow(start + size);
- unsigned long k_cur = k_start;
- int k_size = k_end - k_start;
- int k_size_base = 1 << (ffs(k_size) - 1);
+ unsigned long k_nobat = k_start;
+ unsigned long k_cur;
+ phys_addr_t phys;
int ret;
- void *block;
- block = memblock_alloc(k_size, k_size_base);
-
- if (block && k_size_base >= SZ_128K && k_start == ALIGN(k_start, k_size_base)) {
- int shift = ffs(k_size - k_size_base);
- int k_size_more = shift ? 1 << (shift - 1) : 0;
-
- setbat(-1, k_start, __pa(block), k_size_base, PAGE_KERNEL);
- if (k_size_more >= SZ_128K)
- setbat(-1, k_start + k_size_base, __pa(block) + k_size_base,
- k_size_more, PAGE_KERNEL);
- if (v_block_mapped(k_start))
- k_cur = k_start + k_size_base;
- if (v_block_mapped(k_start + k_size_base))
- k_cur = k_start + k_size_base + k_size_more;
-
- update_bats();
+ while (k_nobat < k_end) {
+ unsigned int k_size = bat_block_size(k_nobat, k_end);
+ int idx = find_free_bat();
+
+ if (idx == -1)
+ break;
+ if (k_size < SZ_128K)
+ break;
+ phys = memblock_phys_alloc_range(k_size, k_size, 0,
+ MEMBLOCK_ALLOC_ANYWHERE);
+ if (!phys)
+ break;
+
+ setbat(idx, k_nobat, phys, k_size, PAGE_KERNEL);
+ k_nobat += k_size;
}
+ if (k_nobat != k_start)
+ update_bats();
- if (!block)
- block = memblock_alloc(k_size, PAGE_SIZE);
- if (!block)
- return -ENOMEM;
+ if (k_nobat < k_end) {
+ phys = memblock_phys_alloc_range(k_end - k_nobat, PAGE_SIZE, 0,
+ MEMBLOCK_ALLOC_ANYWHERE);
+ if (!phys)
+ return -ENOMEM;
+ }
ret = kasan_init_shadow_page_tables(k_start, k_end);
if (ret)
return ret;
- kasan_update_early_region(k_start, k_cur, __pte(0));
+ kasan_update_early_region(k_start, k_nobat, __pte(0));
- for (; k_cur < k_end; k_cur += PAGE_SIZE) {
+ for (k_cur = k_nobat; k_cur < k_end; k_cur += PAGE_SIZE) {
pmd_t *pmd = pmd_off_k(k_cur);
- void *va = block + k_cur - k_start;
- pte_t pte = pfn_pte(PHYS_PFN(__pa(va)), PAGE_KERNEL);
+ pte_t pte = pfn_pte(PHYS_PFN(phys + k_cur - k_nobat), PAGE_KERNEL);
__set_pte_at(&init_mm, k_cur, pte_offset_kernel(pmd, k_cur), pte, 0);
}
flush_tlb_kernel_range(k_start, k_end);
+ memset(kasan_mem_to_shadow(start), 0, k_end - k_start);
+
return 0;
}
diff --git a/arch/powerpc/mm/pgtable.c b/arch/powerpc/mm/pgtable.c
index abb3198bd277..6ec5a7dd7913 100644
--- a/arch/powerpc/mm/pgtable.c
+++ b/arch/powerpc/mm/pgtable.c
@@ -206,6 +206,15 @@ void set_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep,
__set_pte_at(mm, addr, ptep, pte, 0);
}
+void unmap_kernel_page(unsigned long va)
+{
+ pmd_t *pmdp = pmd_off_k(va);
+ pte_t *ptep = pte_offset_kernel(pmdp, va);
+
+ pte_clear(&init_mm, va, ptep);
+ flush_tlb_kernel_range(va, va + PAGE_SIZE);
+}
+
/*
* This is called when relaxing access to a PTE. It's also called in the page
* fault path when we don't hit any of the major fault cases, ie, a minor
diff --git a/arch/powerpc/net/bpf_jit_comp.c b/arch/powerpc/net/bpf_jit_comp.c
index d6ffdd0f2309..a4f4d347e6bd 100644
--- a/arch/powerpc/net/bpf_jit_comp.c
+++ b/arch/powerpc/net/bpf_jit_comp.c
@@ -23,15 +23,15 @@ static void bpf_jit_fill_ill_insns(void *area, unsigned int size)
memset32(area, BREAKPOINT_INSTRUCTION, size / 4);
}
-/* Fix the branch target addresses for subprog calls */
-static int bpf_jit_fixup_subprog_calls(struct bpf_prog *fp, u32 *image,
- struct codegen_context *ctx, u32 *addrs)
+/* Fix updated addresses (for subprog calls, ldimm64, et al) during extra pass */
+static int bpf_jit_fixup_addresses(struct bpf_prog *fp, u32 *image,
+ struct codegen_context *ctx, u32 *addrs)
{
const struct bpf_insn *insn = fp->insnsi;
bool func_addr_fixed;
u64 func_addr;
u32 tmp_idx;
- int i, ret;
+ int i, j, ret;
for (i = 0; i < fp->len; i++) {
/*
@@ -66,6 +66,23 @@ static int bpf_jit_fixup_subprog_calls(struct bpf_prog *fp, u32 *image,
* of the JITed sequence remains unchanged.
*/
ctx->idx = tmp_idx;
+ } else if (insn[i].code == (BPF_LD | BPF_IMM | BPF_DW)) {
+ tmp_idx = ctx->idx;
+ ctx->idx = addrs[i] / 4;
+#ifdef CONFIG_PPC32
+ PPC_LI32(ctx->b2p[insn[i].dst_reg] - 1, (u32)insn[i + 1].imm);
+ PPC_LI32(ctx->b2p[insn[i].dst_reg], (u32)insn[i].imm);
+ for (j = ctx->idx - addrs[i] / 4; j < 4; j++)
+ EMIT(PPC_RAW_NOP());
+#else
+ func_addr = ((u64)(u32)insn[i].imm) | (((u64)(u32)insn[i + 1].imm) << 32);
+ PPC_LI64(b2p[insn[i].dst_reg], func_addr);
+ /* overwrite rest with nops */
+ for (j = ctx->idx - addrs[i] / 4; j < 5; j++)
+ EMIT(PPC_RAW_NOP());
+#endif
+ ctx->idx = tmp_idx;
+ i++;
}
}
@@ -200,13 +217,13 @@ skip_init_ctx:
/*
* Do not touch the prologue and epilogue as they will remain
* unchanged. Only fix the branch target address for subprog
- * calls in the body.
+ * calls in the body, and ldimm64 instructions.
*
* This does not change the offsets and lengths of the subprog
* call instruction sequences and hence, the size of the JITed
* image as well.
*/
- bpf_jit_fixup_subprog_calls(fp, code_base, &cgctx, addrs);
+ bpf_jit_fixup_addresses(fp, code_base, &cgctx, addrs);
/* There is no need to perform the usual passes. */
goto skip_codegen_passes;
@@ -247,7 +264,7 @@ skip_codegen_passes:
fp->jited = 1;
fp->jited_len = proglen + FUNCTION_DESCR_SIZE;
- bpf_flush_icache(bpf_hdr, (u8 *)bpf_hdr + (bpf_hdr->pages * PAGE_SIZE));
+ bpf_flush_icache(bpf_hdr, (u8 *)bpf_hdr + bpf_hdr->size);
if (!fp->is_func || extra_pass) {
bpf_jit_binary_lock_ro(bpf_hdr);
bpf_prog_fill_jited_linfo(fp, addrs);
diff --git a/arch/powerpc/net/bpf_jit_comp32.c b/arch/powerpc/net/bpf_jit_comp32.c
index faaebd446cad..cf8dd8aea386 100644
--- a/arch/powerpc/net/bpf_jit_comp32.c
+++ b/arch/powerpc/net/bpf_jit_comp32.c
@@ -191,6 +191,9 @@ void bpf_jit_emit_func_call_rel(u32 *image, struct codegen_context *ctx, u64 fun
if (image && rel < 0x2000000 && rel >= -0x2000000) {
PPC_BL_ABS(func);
+ EMIT(PPC_RAW_NOP());
+ EMIT(PPC_RAW_NOP());
+ EMIT(PPC_RAW_NOP());
} else {
/* Load function address into r0 */
EMIT(PPC_RAW_LIS(_R0, IMM_H(func)));
@@ -290,6 +293,8 @@ int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, struct codegen_context *
bool func_addr_fixed;
u64 func_addr;
u32 true_cond;
+ u32 tmp_idx;
+ int j;
/*
* addrs[] maps a BPF bytecode address into a real offset from
@@ -905,8 +910,12 @@ int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, struct codegen_context *
* 16 byte instruction that uses two 'struct bpf_insn'
*/
case BPF_LD | BPF_IMM | BPF_DW: /* dst = (u64) imm */
+ tmp_idx = ctx->idx;
PPC_LI32(dst_reg_h, (u32)insn[i + 1].imm);
PPC_LI32(dst_reg, (u32)insn[i].imm);
+ /* padding to allow full 4 instructions for later patching */
+ for (j = ctx->idx - tmp_idx; j < 4; j++)
+ EMIT(PPC_RAW_NOP());
/* Adjust for two bpf instructions */
addrs[++i] = ctx->idx * 4;
break;
diff --git a/arch/powerpc/net/bpf_jit_comp64.c b/arch/powerpc/net/bpf_jit_comp64.c
index 9eae8d8ed340..e1e8c934308a 100644
--- a/arch/powerpc/net/bpf_jit_comp64.c
+++ b/arch/powerpc/net/bpf_jit_comp64.c
@@ -319,6 +319,7 @@ int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, struct codegen_context *
u64 imm64;
u32 true_cond;
u32 tmp_idx;
+ int j;
/*
* addrs[] maps a BPF bytecode address into a real offset from
@@ -633,17 +634,21 @@ bpf_alu32_trunc:
EMIT(PPC_RAW_MR(dst_reg, b2p[TMP_REG_1]));
break;
case 64:
- /*
- * Way easier and faster(?) to store the value
- * into stack and then use ldbrx
- *
- * ctx->seen will be reliable in pass2, but
- * the instructions generated will remain the
- * same across all passes
- */
+ /* Store the value to stack and then use byte-reverse loads */
PPC_BPF_STL(dst_reg, 1, bpf_jit_stack_local(ctx));
EMIT(PPC_RAW_ADDI(b2p[TMP_REG_1], 1, bpf_jit_stack_local(ctx)));
- EMIT(PPC_RAW_LDBRX(dst_reg, 0, b2p[TMP_REG_1]));
+ if (cpu_has_feature(CPU_FTR_ARCH_206)) {
+ EMIT(PPC_RAW_LDBRX(dst_reg, 0, b2p[TMP_REG_1]));
+ } else {
+ EMIT(PPC_RAW_LWBRX(dst_reg, 0, b2p[TMP_REG_1]));
+ if (IS_ENABLED(CONFIG_CPU_LITTLE_ENDIAN))
+ EMIT(PPC_RAW_SLDI(dst_reg, dst_reg, 32));
+ EMIT(PPC_RAW_LI(b2p[TMP_REG_2], 4));
+ EMIT(PPC_RAW_LWBRX(b2p[TMP_REG_2], b2p[TMP_REG_2], b2p[TMP_REG_1]));
+ if (IS_ENABLED(CONFIG_CPU_BIG_ENDIAN))
+ EMIT(PPC_RAW_SLDI(b2p[TMP_REG_2], b2p[TMP_REG_2], 32));
+ EMIT(PPC_RAW_OR(dst_reg, dst_reg, b2p[TMP_REG_2]));
+ }
break;
}
break;
@@ -848,9 +853,13 @@ emit_clear:
case BPF_LD | BPF_IMM | BPF_DW: /* dst = (u64) imm */
imm64 = ((u64)(u32) insn[i].imm) |
(((u64)(u32) insn[i+1].imm) << 32);
+ tmp_idx = ctx->idx;
+ PPC_LI64(dst_reg, imm64);
+ /* padding to allow full 5 instructions for later patching */
+ for (j = ctx->idx - tmp_idx; j < 5; j++)
+ EMIT(PPC_RAW_NOP());
/* Adjust for two bpf instructions */
addrs[++i] = ctx->idx * 4;
- PPC_LI64(dst_reg, imm64);
break;
/*
diff --git a/arch/powerpc/perf/core-book3s.c b/arch/powerpc/perf/core-book3s.c
index a684901b6965..b5b42cf0a703 100644
--- a/arch/powerpc/perf/core-book3s.c
+++ b/arch/powerpc/perf/core-book3s.c
@@ -776,6 +776,34 @@ static void pmao_restore_workaround(bool ebb)
mtspr(SPRN_PMC6, pmcs[5]);
}
+/*
+ * If the perf subsystem wants performance monitor interrupts as soon as
+ * possible (e.g., to sample the instruction address and stack chain),
+ * this should return true. The IRQ masking code can then enable MSR[EE]
+ * in some places (e.g., interrupt handlers) that allows PMI interrupts
+ * through to improve accuracy of profiles, at the cost of some performance.
+ *
+ * The PMU counters can be enabled by other means (e.g., sysfs raw SPR
+ * access), but in that case there is no need for prompt PMI handling.
+ *
+ * This currently returns true if any perf counter is being used. It
+ * could possibly return false if only events are being counted rather than
+ * samples being taken, but for now this is good enough.
+ */
+bool power_pmu_wants_prompt_pmi(void)
+{
+ struct cpu_hw_events *cpuhw;
+
+ /*
+ * This could simply test local_paca->pmcregs_in_use if that were not
+ * under ifdef KVM.
+ */
+ if (!ppmu)
+ return false;
+
+ cpuhw = this_cpu_ptr(&cpu_hw_events);
+ return cpuhw->n_events;
+}
#endif /* CONFIG_PPC64 */
static void perf_event_interrupt(struct pt_regs *regs);
@@ -1327,9 +1355,20 @@ static void power_pmu_disable(struct pmu *pmu)
* Otherwise provide a warning if there is PMI pending, but
* no counter is found overflown.
*/
- if (any_pmc_overflown(cpuhw))
- clear_pmi_irq_pending();
- else
+ if (any_pmc_overflown(cpuhw)) {
+ /*
+ * Since power_pmu_disable runs under local_irq_save, it
+ * could happen that code hits a PMC overflow without PMI
+ * pending in paca. Hence only clear PMI pending if it was
+ * set.
+ *
+ * If a PMI is pending, then MSR[EE] must be disabled (because
+ * the masked PMI handler disabling EE). So it is safe to
+ * call clear_pmi_irq_pending().
+ */
+ if (pmi_irq_pending())
+ clear_pmi_irq_pending();
+ } else
WARN_ON(pmi_irq_pending());
val = mmcra = cpuhw->mmcr.mmcra;
@@ -2438,36 +2477,6 @@ static void perf_event_interrupt(struct pt_regs *regs)
perf_sample_event_took(sched_clock() - start_clock);
}
-/*
- * If the perf subsystem wants performance monitor interrupts as soon as
- * possible (e.g., to sample the instruction address and stack chain),
- * this should return true. The IRQ masking code can then enable MSR[EE]
- * in some places (e.g., interrupt handlers) that allows PMI interrupts
- * though to improve accuracy of profiles, at the cost of some performance.
- *
- * The PMU counters can be enabled by other means (e.g., sysfs raw SPR
- * access), but in that case there is no need for prompt PMI handling.
- *
- * This currently returns true if any perf counter is being used. It
- * could possibly return false if only events are being counted rather than
- * samples being taken, but for now this is good enough.
- */
-bool power_pmu_wants_prompt_pmi(void)
-{
- struct cpu_hw_events *cpuhw;
-
- /*
- * This could simply test local_paca->pmcregs_in_use if that were not
- * under ifdef KVM.
- */
-
- if (!ppmu)
- return false;
-
- cpuhw = this_cpu_ptr(&cpu_hw_events);
- return cpuhw->n_events;
-}
-
static int power_pmu_prepare_cpu(unsigned int cpu)
{
struct cpu_hw_events *cpuhw = &per_cpu(cpu_hw_events, cpu);
diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
index 5adcbd9b5e88..0804b9a11934 100644
--- a/arch/riscv/Kconfig
+++ b/arch/riscv/Kconfig
@@ -40,6 +40,7 @@ config RISCV
select ARCH_USE_MEMTEST
select ARCH_WANT_DEFAULT_TOPDOWN_MMAP_LAYOUT if MMU
select ARCH_WANT_FRAME_POINTERS
+ select ARCH_WANT_GENERAL_HUGETLB
select ARCH_WANT_HUGE_PMD_SHARE if 64BIT
select BINFMT_FLAT_NO_DATA_START_OFFSET if !MMU
select BUILDTIME_TABLE_SORT if MMU
@@ -171,9 +172,6 @@ config ARCH_SPARSEMEM_ENABLE
config ARCH_SELECT_MEMORY_MODEL
def_bool ARCH_SPARSEMEM_ENABLE
-config ARCH_WANT_GENERAL_HUGETLB
- def_bool y
-
config ARCH_SUPPORTS_UPROBES
def_bool y
diff --git a/arch/riscv/Kconfig.erratas b/arch/riscv/Kconfig.erratas
index b44d6ecdb46e..0aacd7052585 100644
--- a/arch/riscv/Kconfig.erratas
+++ b/arch/riscv/Kconfig.erratas
@@ -2,6 +2,7 @@ menu "CPU errata selection"
config RISCV_ERRATA_ALTERNATIVE
bool "RISC-V alternative scheme"
+ depends on !XIP_KERNEL
default y
help
This Kconfig allows the kernel to automatically patch the
diff --git a/arch/riscv/Kconfig.socs b/arch/riscv/Kconfig.socs
index 6ec44a22278a..c112ab2a9052 100644
--- a/arch/riscv/Kconfig.socs
+++ b/arch/riscv/Kconfig.socs
@@ -14,8 +14,8 @@ config SOC_SIFIVE
select CLK_SIFIVE
select CLK_SIFIVE_PRCI
select SIFIVE_PLIC
- select RISCV_ERRATA_ALTERNATIVE
- select ERRATA_SIFIVE
+ select RISCV_ERRATA_ALTERNATIVE if !XIP_KERNEL
+ select ERRATA_SIFIVE if !XIP_KERNEL
help
This enables support for SiFive SoC platform hardware.
diff --git a/arch/riscv/Makefile b/arch/riscv/Makefile
index 8a107ed18b0d..7d81102cffd4 100644
--- a/arch/riscv/Makefile
+++ b/arch/riscv/Makefile
@@ -50,6 +50,12 @@ riscv-march-$(CONFIG_ARCH_RV32I) := rv32ima
riscv-march-$(CONFIG_ARCH_RV64I) := rv64ima
riscv-march-$(CONFIG_FPU) := $(riscv-march-y)fd
riscv-march-$(CONFIG_RISCV_ISA_C) := $(riscv-march-y)c
+
+# Newer binutils versions default to ISA spec version 20191213 which moves some
+# instructions from the I extension to the Zicsr and Zifencei extensions.
+toolchain-need-zicsr-zifencei := $(call cc-option-yn, -march=$(riscv-march-y)_zicsr_zifencei)
+riscv-march-$(toolchain-need-zicsr-zifencei) := $(riscv-march-y)_zicsr_zifencei
+
KBUILD_CFLAGS += -march=$(subst fd,,$(riscv-march-y))
KBUILD_AFLAGS += -march=$(riscv-march-y)
diff --git a/arch/riscv/boot/dts/canaan/k210.dtsi b/arch/riscv/boot/dts/canaan/k210.dtsi
index 56f57118c633..44d338514761 100644
--- a/arch/riscv/boot/dts/canaan/k210.dtsi
+++ b/arch/riscv/boot/dts/canaan/k210.dtsi
@@ -113,7 +113,8 @@
compatible = "canaan,k210-plic", "sifive,plic-1.0.0";
reg = <0xC000000 0x4000000>;
interrupt-controller;
- interrupts-extended = <&cpu0_intc 11>, <&cpu1_intc 11>;
+ interrupts-extended = <&cpu0_intc 11>, <&cpu0_intc 9>,
+ <&cpu1_intc 11>, <&cpu1_intc 9>;
riscv,ndev = <65>;
};
diff --git a/arch/riscv/configs/nommu_k210_sdcard_defconfig b/arch/riscv/configs/nommu_k210_sdcard_defconfig
index 2a82a3b2992b..af64b95e88cc 100644
--- a/arch/riscv/configs/nommu_k210_sdcard_defconfig
+++ b/arch/riscv/configs/nommu_k210_sdcard_defconfig
@@ -23,7 +23,7 @@ CONFIG_SLOB=y
CONFIG_SOC_CANAAN=y
CONFIG_SMP=y
CONFIG_NR_CPUS=2
-CONFIG_CMDLINE="earlycon console=ttySIF0 rootdelay=2 root=/dev/mmcblk0p1 ro"
+CONFIG_CMDLINE="earlycon console=ttySIF0 root=/dev/mmcblk0p1 rootwait ro"
CONFIG_CMDLINE_FORCE=y
# CONFIG_SECCOMP is not set
# CONFIG_STACKPROTECTOR is not set
diff --git a/arch/riscv/include/asm/kvm_host.h b/arch/riscv/include/asm/kvm_host.h
index 99ef6a120617..78da839657e5 100644
--- a/arch/riscv/include/asm/kvm_host.h
+++ b/arch/riscv/include/asm/kvm_host.h
@@ -228,6 +228,7 @@ void kvm_riscv_stage2_vmid_update(struct kvm_vcpu *vcpu);
void __kvm_riscv_unpriv_trap(void);
+void kvm_riscv_vcpu_wfi(struct kvm_vcpu *vcpu);
unsigned long kvm_riscv_vcpu_unpriv_read(struct kvm_vcpu *vcpu,
bool read_insn,
unsigned long guest_addr,
diff --git a/arch/riscv/include/asm/kvm_vcpu_sbi.h b/arch/riscv/include/asm/kvm_vcpu_sbi.h
index 76e4e17a3e00..83d6d4d2b1df 100644
--- a/arch/riscv/include/asm/kvm_vcpu_sbi.h
+++ b/arch/riscv/include/asm/kvm_vcpu_sbi.h
@@ -12,7 +12,7 @@
#define KVM_SBI_IMPID 3
#define KVM_SBI_VERSION_MAJOR 0
-#define KVM_SBI_VERSION_MINOR 2
+#define KVM_SBI_VERSION_MINOR 3
struct kvm_vcpu_sbi_extension {
unsigned long extid_start;
@@ -28,6 +28,9 @@ struct kvm_vcpu_sbi_extension {
};
void kvm_riscv_vcpu_sbi_forward(struct kvm_vcpu *vcpu, struct kvm_run *run);
+void kvm_riscv_vcpu_sbi_system_reset(struct kvm_vcpu *vcpu,
+ struct kvm_run *run,
+ u32 type, u64 flags);
const struct kvm_vcpu_sbi_extension *kvm_vcpu_sbi_find_ext(unsigned long extid);
#endif /* __RISCV_KVM_VCPU_SBI_H__ */
diff --git a/arch/riscv/include/asm/page.h b/arch/riscv/include/asm/page.h
index 160e3a1e8f8b..004372f8da54 100644
--- a/arch/riscv/include/asm/page.h
+++ b/arch/riscv/include/asm/page.h
@@ -119,7 +119,7 @@ extern phys_addr_t phys_ram_base;
((x) >= kernel_map.virt_addr && (x) < (kernel_map.virt_addr + kernel_map.size))
#define is_linear_mapping(x) \
- ((x) >= PAGE_OFFSET && (!IS_ENABLED(CONFIG_64BIT) || (x) < kernel_map.virt_addr))
+ ((x) >= PAGE_OFFSET && (!IS_ENABLED(CONFIG_64BIT) || (x) < PAGE_OFFSET + KERN_VIRT_SIZE))
#define linear_mapping_pa_to_va(x) ((void *)((unsigned long)(x) + kernel_map.va_pa_offset))
#define kernel_mapping_pa_to_va(y) ({ \
diff --git a/arch/riscv/include/asm/pgtable.h b/arch/riscv/include/asm/pgtable.h
index 7e949f25c933..e3549e50de95 100644
--- a/arch/riscv/include/asm/pgtable.h
+++ b/arch/riscv/include/asm/pgtable.h
@@ -13,6 +13,7 @@
#ifndef CONFIG_MMU
#define KERNEL_LINK_ADDR PAGE_OFFSET
+#define KERN_VIRT_SIZE (UL(-1))
#else
#define ADDRESS_SPACE_END (UL(-1))
diff --git a/arch/riscv/include/asm/sbi.h b/arch/riscv/include/asm/sbi.h
index d1c37479d828..06133b4f8e20 100644
--- a/arch/riscv/include/asm/sbi.h
+++ b/arch/riscv/include/asm/sbi.h
@@ -71,15 +71,32 @@ enum sbi_ext_hsm_fid {
SBI_EXT_HSM_HART_START = 0,
SBI_EXT_HSM_HART_STOP,
SBI_EXT_HSM_HART_STATUS,
+ SBI_EXT_HSM_HART_SUSPEND,
};
-enum sbi_hsm_hart_status {
- SBI_HSM_HART_STATUS_STARTED = 0,
- SBI_HSM_HART_STATUS_STOPPED,
- SBI_HSM_HART_STATUS_START_PENDING,
- SBI_HSM_HART_STATUS_STOP_PENDING,
+enum sbi_hsm_hart_state {
+ SBI_HSM_STATE_STARTED = 0,
+ SBI_HSM_STATE_STOPPED,
+ SBI_HSM_STATE_START_PENDING,
+ SBI_HSM_STATE_STOP_PENDING,
+ SBI_HSM_STATE_SUSPENDED,
+ SBI_HSM_STATE_SUSPEND_PENDING,
+ SBI_HSM_STATE_RESUME_PENDING,
};
+#define SBI_HSM_SUSP_BASE_MASK 0x7fffffff
+#define SBI_HSM_SUSP_NON_RET_BIT 0x80000000
+#define SBI_HSM_SUSP_PLAT_BASE 0x10000000
+
+#define SBI_HSM_SUSPEND_RET_DEFAULT 0x00000000
+#define SBI_HSM_SUSPEND_RET_PLATFORM SBI_HSM_SUSP_PLAT_BASE
+#define SBI_HSM_SUSPEND_RET_LAST SBI_HSM_SUSP_BASE_MASK
+#define SBI_HSM_SUSPEND_NON_RET_DEFAULT SBI_HSM_SUSP_NON_RET_BIT
+#define SBI_HSM_SUSPEND_NON_RET_PLATFORM (SBI_HSM_SUSP_NON_RET_BIT | \
+ SBI_HSM_SUSP_PLAT_BASE)
+#define SBI_HSM_SUSPEND_NON_RET_LAST (SBI_HSM_SUSP_NON_RET_BIT | \
+ SBI_HSM_SUSP_BASE_MASK)
+
enum sbi_ext_srst_fid {
SBI_EXT_SRST_RESET = 0,
};
diff --git a/arch/riscv/include/asm/uaccess.h b/arch/riscv/include/asm/uaccess.h
index c701a5e57a2b..855450bed9f5 100644
--- a/arch/riscv/include/asm/uaccess.h
+++ b/arch/riscv/include/asm/uaccess.h
@@ -21,42 +21,13 @@
#include <asm/byteorder.h>
#include <asm/extable.h>
#include <asm/asm.h>
+#include <asm-generic/access_ok.h>
#define __enable_user_access() \
__asm__ __volatile__ ("csrs sstatus, %0" : : "r" (SR_SUM) : "memory")
#define __disable_user_access() \
__asm__ __volatile__ ("csrc sstatus, %0" : : "r" (SR_SUM) : "memory")
-/**
- * access_ok: - Checks if a user space pointer is valid
- * @addr: User space pointer to start of block to check
- * @size: Size of block to check
- *
- * Context: User context only. This function may sleep.
- *
- * Checks if a pointer to a block of memory in user space is valid.
- *
- * Returns true (nonzero) if the memory block may be valid, false (zero)
- * if it is definitely invalid.
- *
- * Note that, depending on architecture, this function probably just
- * checks that the pointer is in the user space range - after calling
- * this function, memory access functions may still return -EFAULT.
- */
-#define access_ok(addr, size) ({ \
- __chk_user_ptr(addr); \
- likely(__access_ok((unsigned long __force)(addr), (size))); \
-})
-
-/*
- * Ensure that the range [addr, addr+size) is within the process's
- * address space
- */
-static inline int __access_ok(unsigned long addr, unsigned long size)
-{
- return size <= TASK_SIZE && addr <= TASK_SIZE - size;
-}
-
/*
* The exception table consists of pairs of addresses: the first is the
* address of an instruction that is allowed to fault, and the second is
@@ -346,8 +317,6 @@ unsigned long __must_check clear_user(void __user *to, unsigned long n)
__clear_user(to, n) : n;
}
-#define HAVE_GET_KERNEL_NOFAULT
-
#define __get_kernel_nofault(dst, src, type, err_label) \
do { \
long __kr_err; \
diff --git a/arch/riscv/kernel/Makefile b/arch/riscv/kernel/Makefile
index 612556faa527..ffc87e76b1dd 100644
--- a/arch/riscv/kernel/Makefile
+++ b/arch/riscv/kernel/Makefile
@@ -51,6 +51,8 @@ obj-$(CONFIG_MODULE_SECTIONS) += module-sections.o
obj-$(CONFIG_FUNCTION_TRACER) += mcount.o ftrace.o
obj-$(CONFIG_DYNAMIC_FTRACE) += mcount-dyn.o
+obj-$(CONFIG_TRACE_IRQFLAGS) += trace_irq.o
+
obj-$(CONFIG_RISCV_BASE_PMU) += perf_event.o
obj-$(CONFIG_PERF_EVENTS) += perf_callchain.o
obj-$(CONFIG_HAVE_PERF_REGS) += perf_regs.o
diff --git a/arch/riscv/kernel/cpu-hotplug.c b/arch/riscv/kernel/cpu-hotplug.c
index be7f05b542bb..f7a832e3a1d1 100644
--- a/arch/riscv/kernel/cpu-hotplug.c
+++ b/arch/riscv/kernel/cpu-hotplug.c
@@ -12,6 +12,7 @@
#include <linux/sched/hotplug.h>
#include <asm/irq.h>
#include <asm/cpu_ops.h>
+#include <asm/numa.h>
#include <asm/sbi.h>
bool cpu_has_hotplug(unsigned int cpu)
@@ -40,6 +41,7 @@ int __cpu_disable(void)
return ret;
remove_cpu_topology(cpu);
+ numa_remove_cpu(cpu);
set_cpu_online(cpu, false);
irq_migrate_all_off_this_cpu();
diff --git a/arch/riscv/kernel/cpu_ops_sbi.c b/arch/riscv/kernel/cpu_ops_sbi.c
index dae29cbfe550..2e16f6732cdf 100644
--- a/arch/riscv/kernel/cpu_ops_sbi.c
+++ b/arch/riscv/kernel/cpu_ops_sbi.c
@@ -111,7 +111,7 @@ static int sbi_cpu_is_stopped(unsigned int cpuid)
rc = sbi_hsm_hart_get_status(hartid);
- if (rc == SBI_HSM_HART_STATUS_STOPPED)
+ if (rc == SBI_HSM_STATE_STOPPED)
return 0;
return rc;
}
diff --git a/arch/riscv/kernel/entry.S b/arch/riscv/kernel/entry.S
index ed29e9c8f660..d6a46ed0bf05 100644
--- a/arch/riscv/kernel/entry.S
+++ b/arch/riscv/kernel/entry.S
@@ -108,7 +108,7 @@ _save_context:
.option pop
#ifdef CONFIG_TRACE_IRQFLAGS
- call trace_hardirqs_off
+ call __trace_hardirqs_off
#endif
#ifdef CONFIG_CONTEXT_TRACKING
@@ -143,7 +143,7 @@ skip_context_tracking:
li t0, EXC_BREAKPOINT
beq s4, t0, 1f
#ifdef CONFIG_TRACE_IRQFLAGS
- call trace_hardirqs_on
+ call __trace_hardirqs_on
#endif
csrs CSR_STATUS, SR_IE
@@ -234,7 +234,7 @@ ret_from_exception:
REG_L s0, PT_STATUS(sp)
csrc CSR_STATUS, SR_IE
#ifdef CONFIG_TRACE_IRQFLAGS
- call trace_hardirqs_off
+ call __trace_hardirqs_off
#endif
#ifdef CONFIG_RISCV_M_MODE
/* the MPP value is too large to be used as an immediate arg for addi */
@@ -270,10 +270,10 @@ restore_all:
REG_L s1, PT_STATUS(sp)
andi t0, s1, SR_PIE
beqz t0, 1f
- call trace_hardirqs_on
+ call __trace_hardirqs_on
j 2f
1:
- call trace_hardirqs_off
+ call __trace_hardirqs_off
2:
#endif
REG_L a0, PT_STATUS(sp)
diff --git a/arch/riscv/kernel/head.S b/arch/riscv/kernel/head.S
index 2363b43312fc..ec07f991866a 100644
--- a/arch/riscv/kernel/head.S
+++ b/arch/riscv/kernel/head.S
@@ -22,14 +22,13 @@
add \reg, \reg, t0
.endm
.macro XIP_FIXUP_FLASH_OFFSET reg
- la t1, __data_loc
- li t0, XIP_OFFSET_MASK
- and t1, t1, t0
- li t1, XIP_OFFSET
- sub t0, t0, t1
- sub \reg, \reg, t0
+ la t0, __data_loc
+ REG_L t1, _xip_phys_offset
+ sub \reg, \reg, t1
+ add \reg, \reg, t0
.endm
_xip_fixup: .dword CONFIG_PHYS_RAM_BASE - CONFIG_XIP_PHYS_ADDR - XIP_OFFSET
+_xip_phys_offset: .dword CONFIG_XIP_PHYS_ADDR + XIP_OFFSET
#else
.macro XIP_FIXUP_OFFSET reg
.endm
diff --git a/arch/riscv/kernel/module.c b/arch/riscv/kernel/module.c
index 68a9e3d1fe16..4a48287513c3 100644
--- a/arch/riscv/kernel/module.c
+++ b/arch/riscv/kernel/module.c
@@ -13,6 +13,19 @@
#include <linux/pgtable.h>
#include <asm/sections.h>
+/*
+ * The auipc+jalr instruction pair can reach any PC-relative offset
+ * in the range [-2^31 - 2^11, 2^31 - 2^11)
+ */
+static bool riscv_insn_valid_32bit_offset(ptrdiff_t val)
+{
+#ifdef CONFIG_32BIT
+ return true;
+#else
+ return (-(1L << 31) - (1L << 11)) <= val && val < ((1L << 31) - (1L << 11));
+#endif
+}
+
static int apply_r_riscv_32_rela(struct module *me, u32 *location, Elf_Addr v)
{
if (v != (u32)v) {
@@ -95,7 +108,7 @@ static int apply_r_riscv_pcrel_hi20_rela(struct module *me, u32 *location,
ptrdiff_t offset = (void *)v - (void *)location;
s32 hi20;
- if (offset != (s32)offset) {
+ if (!riscv_insn_valid_32bit_offset(offset)) {
pr_err(
"%s: target %016llx can not be addressed by the 32-bit offset from PC = %p\n",
me->name, (long long)v, location);
@@ -197,10 +210,9 @@ static int apply_r_riscv_call_plt_rela(struct module *me, u32 *location,
Elf_Addr v)
{
ptrdiff_t offset = (void *)v - (void *)location;
- s32 fill_v = offset;
u32 hi20, lo12;
- if (offset != fill_v) {
+ if (!riscv_insn_valid_32bit_offset(offset)) {
/* Only emit the plt entry if offset over 32-bit range */
if (IS_ENABLED(CONFIG_MODULE_SECTIONS)) {
offset = module_emit_plt_entry(me, v);
@@ -224,10 +236,9 @@ static int apply_r_riscv_call_rela(struct module *me, u32 *location,
Elf_Addr v)
{
ptrdiff_t offset = (void *)v - (void *)location;
- s32 fill_v = offset;
u32 hi20, lo12;
- if (offset != fill_v) {
+ if (!riscv_insn_valid_32bit_offset(offset)) {
pr_err(
"%s: target %016llx can not be addressed by the 32-bit offset from PC = %p\n",
me->name, (long long)v, location);
diff --git a/arch/riscv/kernel/perf_callchain.c b/arch/riscv/kernel/perf_callchain.c
index 1fc075b8f764..55faa4991b87 100644
--- a/arch/riscv/kernel/perf_callchain.c
+++ b/arch/riscv/kernel/perf_callchain.c
@@ -15,8 +15,8 @@ static unsigned long user_backtrace(struct perf_callchain_entry_ctx *entry,
{
struct stackframe buftail;
unsigned long ra = 0;
- unsigned long *user_frame_tail =
- (unsigned long *)(fp - sizeof(struct stackframe));
+ unsigned long __user *user_frame_tail =
+ (unsigned long __user *)(fp - sizeof(struct stackframe));
/* Check accessibility of one struct frame_tail beyond */
if (!access_ok(user_frame_tail, sizeof(buftail)))
diff --git a/arch/riscv/kernel/sbi.c b/arch/riscv/kernel/sbi.c
index f72527fcb347..775d3322b422 100644
--- a/arch/riscv/kernel/sbi.c
+++ b/arch/riscv/kernel/sbi.c
@@ -5,6 +5,7 @@
* Copyright (c) 2020 Western Digital Corporation or its affiliates.
*/
+#include <linux/bits.h>
#include <linux/init.h>
#include <linux/pm.h>
#include <linux/reboot.h>
@@ -85,7 +86,7 @@ static unsigned long __sbi_v01_cpumask_to_hartmask(const struct cpumask *cpu_mas
pr_warn("Unable to send any request to hartid > BITS_PER_LONG for SBI v0.1\n");
break;
}
- hmask |= 1 << hartid;
+ hmask |= BIT(hartid);
}
return hmask;
@@ -160,7 +161,7 @@ static int __sbi_send_ipi_v01(const struct cpumask *cpu_mask)
{
unsigned long hart_mask;
- if (!cpu_mask)
+ if (!cpu_mask || cpumask_empty(cpu_mask))
cpu_mask = cpu_online_mask;
hart_mask = __sbi_v01_cpumask_to_hartmask(cpu_mask);
@@ -176,7 +177,7 @@ static int __sbi_rfence_v01(int fid, const struct cpumask *cpu_mask,
int result = 0;
unsigned long hart_mask;
- if (!cpu_mask)
+ if (!cpu_mask || cpumask_empty(cpu_mask))
cpu_mask = cpu_online_mask;
hart_mask = __sbi_v01_cpumask_to_hartmask(cpu_mask);
@@ -249,26 +250,37 @@ static void __sbi_set_timer_v02(uint64_t stime_value)
static int __sbi_send_ipi_v02(const struct cpumask *cpu_mask)
{
- unsigned long hartid, cpuid, hmask = 0, hbase = 0;
+ unsigned long hartid, cpuid, hmask = 0, hbase = 0, htop = 0;
struct sbiret ret = {0};
int result;
- if (!cpu_mask)
+ if (!cpu_mask || cpumask_empty(cpu_mask))
cpu_mask = cpu_online_mask;
for_each_cpu(cpuid, cpu_mask) {
hartid = cpuid_to_hartid_map(cpuid);
- if (hmask && ((hbase + BITS_PER_LONG) <= hartid)) {
- ret = sbi_ecall(SBI_EXT_IPI, SBI_EXT_IPI_SEND_IPI,
- hmask, hbase, 0, 0, 0, 0);
- if (ret.error)
- goto ecall_failed;
- hmask = 0;
- hbase = 0;
+ if (hmask) {
+ if (hartid + BITS_PER_LONG <= htop ||
+ hbase + BITS_PER_LONG <= hartid) {
+ ret = sbi_ecall(SBI_EXT_IPI,
+ SBI_EXT_IPI_SEND_IPI, hmask,
+ hbase, 0, 0, 0, 0);
+ if (ret.error)
+ goto ecall_failed;
+ hmask = 0;
+ } else if (hartid < hbase) {
+ /* shift the mask to fit lower hartid */
+ hmask <<= hbase - hartid;
+ hbase = hartid;
+ }
}
- if (!hmask)
+ if (!hmask) {
hbase = hartid;
- hmask |= 1UL << (hartid - hbase);
+ htop = hartid;
+ } else if (hartid > htop) {
+ htop = hartid;
+ }
+ hmask |= BIT(hartid - hbase);
}
if (hmask) {
@@ -344,25 +356,35 @@ static int __sbi_rfence_v02(int fid, const struct cpumask *cpu_mask,
unsigned long start, unsigned long size,
unsigned long arg4, unsigned long arg5)
{
- unsigned long hartid, cpuid, hmask = 0, hbase = 0;
+ unsigned long hartid, cpuid, hmask = 0, hbase = 0, htop = 0;
int result;
- if (!cpu_mask)
+ if (!cpu_mask || cpumask_empty(cpu_mask))
cpu_mask = cpu_online_mask;
for_each_cpu(cpuid, cpu_mask) {
hartid = cpuid_to_hartid_map(cpuid);
- if (hmask && ((hbase + BITS_PER_LONG) <= hartid)) {
- result = __sbi_rfence_v02_call(fid, hmask, hbase,
- start, size, arg4, arg5);
- if (result)
- return result;
- hmask = 0;
- hbase = 0;
+ if (hmask) {
+ if (hartid + BITS_PER_LONG <= htop ||
+ hbase + BITS_PER_LONG <= hartid) {
+ result = __sbi_rfence_v02_call(fid, hmask,
+ hbase, start, size, arg4, arg5);
+ if (result)
+ return result;
+ hmask = 0;
+ } else if (hartid < hbase) {
+ /* shift the mask to fit lower hartid */
+ hmask <<= hbase - hartid;
+ hbase = hartid;
+ }
}
- if (!hmask)
+ if (!hmask) {
hbase = hartid;
- hmask |= 1UL << (hartid - hbase);
+ htop = hartid;
+ } else if (hartid > htop) {
+ htop = hartid;
+ }
+ hmask |= BIT(hartid - hbase);
}
if (hmask) {
diff --git a/arch/riscv/kernel/setup.c b/arch/riscv/kernel/setup.c
index b42bfdc67482..834eb652a7b9 100644
--- a/arch/riscv/kernel/setup.c
+++ b/arch/riscv/kernel/setup.c
@@ -301,9 +301,6 @@ static int __init topology_init(void)
{
int i, ret;
- for_each_online_node(i)
- register_one_node(i);
-
for_each_possible_cpu(i) {
struct cpu *cpu = &per_cpu(cpu_devices, i);
diff --git a/arch/riscv/kernel/stacktrace.c b/arch/riscv/kernel/stacktrace.c
index 201ee206fb57..14d2b53ec322 100644
--- a/arch/riscv/kernel/stacktrace.c
+++ b/arch/riscv/kernel/stacktrace.c
@@ -22,15 +22,16 @@ void notrace walk_stackframe(struct task_struct *task, struct pt_regs *regs,
bool (*fn)(void *, unsigned long), void *arg)
{
unsigned long fp, sp, pc;
+ int level = 0;
if (regs) {
fp = frame_pointer(regs);
sp = user_stack_pointer(regs);
pc = instruction_pointer(regs);
} else if (task == NULL || task == current) {
- fp = (unsigned long)__builtin_frame_address(1);
- sp = (unsigned long)__builtin_frame_address(0);
- pc = (unsigned long)__builtin_return_address(0);
+ fp = (unsigned long)__builtin_frame_address(0);
+ sp = sp_in_global;
+ pc = (unsigned long)walk_stackframe;
} else {
/* task blocked in __switch_to */
fp = task->thread.s[0];
@@ -42,7 +43,7 @@ void notrace walk_stackframe(struct task_struct *task, struct pt_regs *regs,
unsigned long low, high;
struct stackframe *frame;
- if (unlikely(!__kernel_text_address(pc) || !fn(arg, pc)))
+ if (unlikely(!__kernel_text_address(pc) || (level++ >= 1 && !fn(arg, pc))))
break;
/* Validate frame pointer */
diff --git a/arch/riscv/kernel/trace_irq.c b/arch/riscv/kernel/trace_irq.c
new file mode 100644
index 000000000000..095ac976d7da
--- /dev/null
+++ b/arch/riscv/kernel/trace_irq.c
@@ -0,0 +1,27 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2022 Changbin Du <changbin.du@gmail.com>
+ */
+
+#include <linux/irqflags.h>
+#include <linux/kprobes.h>
+#include "trace_irq.h"
+
+/*
+ * trace_hardirqs_on/off require the caller to setup frame pointer properly.
+ * Otherwise, CALLER_ADDR1 might trigger an pagging exception in kernel.
+ * Here we add one extra level so they can be safely called by low
+ * level entry code which $fp is used for other purpose.
+ */
+
+void __trace_hardirqs_on(void)
+{
+ trace_hardirqs_on();
+}
+NOKPROBE_SYMBOL(__trace_hardirqs_on);
+
+void __trace_hardirqs_off(void)
+{
+ trace_hardirqs_off();
+}
+NOKPROBE_SYMBOL(__trace_hardirqs_off);
diff --git a/arch/riscv/kernel/trace_irq.h b/arch/riscv/kernel/trace_irq.h
new file mode 100644
index 000000000000..99fe67377e5e
--- /dev/null
+++ b/arch/riscv/kernel/trace_irq.h
@@ -0,0 +1,11 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2022 Changbin Du <changbin.du@gmail.com>
+ */
+#ifndef __TRACE_IRQ_H
+#define __TRACE_IRQ_H
+
+void __trace_hardirqs_on(void);
+void __trace_hardirqs_off(void);
+
+#endif /* __TRACE_IRQ_H */
diff --git a/arch/riscv/kvm/vcpu.c b/arch/riscv/kvm/vcpu.c
index 0c5239e05721..624166004e36 100644
--- a/arch/riscv/kvm/vcpu.c
+++ b/arch/riscv/kvm/vcpu.c
@@ -90,6 +90,7 @@ int kvm_arch_vcpu_precreate(struct kvm *kvm, unsigned int id)
int kvm_arch_vcpu_create(struct kvm_vcpu *vcpu)
{
struct kvm_cpu_context *cntx;
+ struct kvm_vcpu_csr *reset_csr = &vcpu->arch.guest_reset_csr;
/* Mark this VCPU never ran */
vcpu->arch.ran_atleast_once = false;
@@ -106,6 +107,9 @@ int kvm_arch_vcpu_create(struct kvm_vcpu *vcpu)
cntx->hstatus |= HSTATUS_SPVP;
cntx->hstatus |= HSTATUS_SPV;
+ /* By default, make CY, TM, and IR counters accessible in VU mode */
+ reset_csr->scounteren = 0x7;
+
/* Setup VCPU timer */
kvm_riscv_vcpu_timer_init(vcpu);
@@ -699,6 +703,20 @@ static void kvm_riscv_update_hvip(struct kvm_vcpu *vcpu)
csr_write(CSR_HVIP, csr->hvip);
}
+/*
+ * Actually run the vCPU, entering an RCU extended quiescent state (EQS) while
+ * the vCPU is running.
+ *
+ * This must be noinstr as instrumentation may make use of RCU, and this is not
+ * safe during the EQS.
+ */
+static void noinstr kvm_riscv_vcpu_enter_exit(struct kvm_vcpu *vcpu)
+{
+ guest_state_enter_irqoff();
+ __kvm_riscv_switch_to(&vcpu->arch);
+ guest_state_exit_irqoff();
+}
+
int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu)
{
int ret;
@@ -790,9 +808,9 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu)
continue;
}
- guest_enter_irqoff();
+ guest_timing_enter_irqoff();
- __kvm_riscv_switch_to(&vcpu->arch);
+ kvm_riscv_vcpu_enter_exit(vcpu);
vcpu->mode = OUTSIDE_GUEST_MODE;
vcpu->stat.exits++;
@@ -812,25 +830,21 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu)
kvm_riscv_vcpu_sync_interrupts(vcpu);
/*
- * We may have taken a host interrupt in VS/VU-mode (i.e.
- * while executing the guest). This interrupt is still
- * pending, as we haven't serviced it yet!
+ * We must ensure that any pending interrupts are taken before
+ * we exit guest timing so that timer ticks are accounted as
+ * guest time. Transiently unmask interrupts so that any
+ * pending interrupts are taken.
*
- * We're now back in HS-mode with interrupts disabled
- * so enabling the interrupts now will have the effect
- * of taking the interrupt again, in HS-mode this time.
+ * There's no barrier which ensures that pending interrupts are
+ * recognised, so we just hope that the CPU takes any pending
+ * interrupts between the enable and disable.
*/
local_irq_enable();
+ local_irq_disable();
- /*
- * We do local_irq_enable() before calling guest_exit() so
- * that if a timer interrupt hits while running the guest
- * we account that tick as being spent in the guest. We
- * enable preemption after calling guest_exit() so that if
- * we get preempted we make sure ticks after that is not
- * counted as guest time.
- */
- guest_exit();
+ guest_timing_exit_irqoff();
+
+ local_irq_enable();
preempt_enable();
diff --git a/arch/riscv/kvm/vcpu_exit.c b/arch/riscv/kvm/vcpu_exit.c
index 571f319e995a..aa8af129e4bb 100644
--- a/arch/riscv/kvm/vcpu_exit.c
+++ b/arch/riscv/kvm/vcpu_exit.c
@@ -144,12 +144,7 @@ static int system_opcode_insn(struct kvm_vcpu *vcpu,
{
if ((insn & INSN_MASK_WFI) == INSN_MATCH_WFI) {
vcpu->stat.wfi_exit_stat++;
- if (!kvm_arch_vcpu_runnable(vcpu)) {
- srcu_read_unlock(&vcpu->kvm->srcu, vcpu->arch.srcu_idx);
- kvm_vcpu_halt(vcpu);
- vcpu->arch.srcu_idx = srcu_read_lock(&vcpu->kvm->srcu);
- kvm_clear_request(KVM_REQ_UNHALT, vcpu);
- }
+ kvm_riscv_vcpu_wfi(vcpu);
vcpu->arch.guest_context.sepc += INSN_LEN(insn);
return 1;
}
@@ -454,6 +449,21 @@ static int stage2_page_fault(struct kvm_vcpu *vcpu, struct kvm_run *run,
}
/**
+ * kvm_riscv_vcpu_wfi -- Emulate wait for interrupt (WFI) behaviour
+ *
+ * @vcpu: The VCPU pointer
+ */
+void kvm_riscv_vcpu_wfi(struct kvm_vcpu *vcpu)
+{
+ if (!kvm_arch_vcpu_runnable(vcpu)) {
+ srcu_read_unlock(&vcpu->kvm->srcu, vcpu->arch.srcu_idx);
+ kvm_vcpu_halt(vcpu);
+ vcpu->arch.srcu_idx = srcu_read_lock(&vcpu->kvm->srcu);
+ kvm_clear_request(KVM_REQ_UNHALT, vcpu);
+ }
+}
+
+/**
* kvm_riscv_vcpu_unpriv_read -- Read machine word from Guest memory
*
* @vcpu: The VCPU pointer
diff --git a/arch/riscv/kvm/vcpu_sbi.c b/arch/riscv/kvm/vcpu_sbi.c
index 78aa3db76225..a09ecb97b890 100644
--- a/arch/riscv/kvm/vcpu_sbi.c
+++ b/arch/riscv/kvm/vcpu_sbi.c
@@ -45,6 +45,7 @@ extern const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_base;
extern const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_time;
extern const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_ipi;
extern const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_rfence;
+extern const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_srst;
extern const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_hsm;
extern const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_experimental;
extern const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_vendor;
@@ -55,6 +56,7 @@ static const struct kvm_vcpu_sbi_extension *sbi_ext[] = {
&vcpu_sbi_ext_time,
&vcpu_sbi_ext_ipi,
&vcpu_sbi_ext_rfence,
+ &vcpu_sbi_ext_srst,
&vcpu_sbi_ext_hsm,
&vcpu_sbi_ext_experimental,
&vcpu_sbi_ext_vendor,
@@ -79,6 +81,23 @@ void kvm_riscv_vcpu_sbi_forward(struct kvm_vcpu *vcpu, struct kvm_run *run)
run->riscv_sbi.ret[1] = cp->a1;
}
+void kvm_riscv_vcpu_sbi_system_reset(struct kvm_vcpu *vcpu,
+ struct kvm_run *run,
+ u32 type, u64 flags)
+{
+ unsigned long i;
+ struct kvm_vcpu *tmp;
+
+ kvm_for_each_vcpu(i, tmp, vcpu->kvm)
+ tmp->arch.power_off = true;
+ kvm_make_all_cpus_request(vcpu->kvm, KVM_REQ_SLEEP);
+
+ memset(&run->system_event, 0, sizeof(run->system_event));
+ run->system_event.type = type;
+ run->system_event.flags = flags;
+ run->exit_reason = KVM_EXIT_SYSTEM_EVENT;
+}
+
int kvm_riscv_vcpu_sbi_return(struct kvm_vcpu *vcpu, struct kvm_run *run)
{
struct kvm_cpu_context *cp = &vcpu->arch.guest_context;
diff --git a/arch/riscv/kvm/vcpu_sbi_base.c b/arch/riscv/kvm/vcpu_sbi_base.c
index 4ecf377f483b..48f431091cdb 100644
--- a/arch/riscv/kvm/vcpu_sbi_base.c
+++ b/arch/riscv/kvm/vcpu_sbi_base.c
@@ -9,6 +9,7 @@
#include <linux/errno.h>
#include <linux/err.h>
#include <linux/kvm_host.h>
+#include <linux/version.h>
#include <asm/csr.h>
#include <asm/sbi.h>
#include <asm/kvm_vcpu_timer.h>
@@ -32,7 +33,7 @@ static int kvm_sbi_ext_base_handler(struct kvm_vcpu *vcpu, struct kvm_run *run,
*out_val = KVM_SBI_IMPID;
break;
case SBI_EXT_BASE_GET_IMP_VERSION:
- *out_val = 0;
+ *out_val = LINUX_VERSION_CODE;
break;
case SBI_EXT_BASE_PROBE_EXT:
if ((cp->a0 >= SBI_EXT_EXPERIMENTAL_START &&
diff --git a/arch/riscv/kvm/vcpu_sbi_hsm.c b/arch/riscv/kvm/vcpu_sbi_hsm.c
index 2e383687fa48..239dec0a628a 100644
--- a/arch/riscv/kvm/vcpu_sbi_hsm.c
+++ b/arch/riscv/kvm/vcpu_sbi_hsm.c
@@ -60,9 +60,11 @@ static int kvm_sbi_hsm_vcpu_get_status(struct kvm_vcpu *vcpu)
if (!target_vcpu)
return -EINVAL;
if (!target_vcpu->arch.power_off)
- return SBI_HSM_HART_STATUS_STARTED;
+ return SBI_HSM_STATE_STARTED;
+ else if (vcpu->stat.generic.blocking)
+ return SBI_HSM_STATE_SUSPENDED;
else
- return SBI_HSM_HART_STATUS_STOPPED;
+ return SBI_HSM_STATE_STOPPED;
}
static int kvm_sbi_ext_hsm_handler(struct kvm_vcpu *vcpu, struct kvm_run *run,
@@ -91,6 +93,18 @@ static int kvm_sbi_ext_hsm_handler(struct kvm_vcpu *vcpu, struct kvm_run *run,
ret = 0;
}
break;
+ case SBI_EXT_HSM_HART_SUSPEND:
+ switch (cp->a0) {
+ case SBI_HSM_SUSPEND_RET_DEFAULT:
+ kvm_riscv_vcpu_wfi(vcpu);
+ break;
+ case SBI_HSM_SUSPEND_NON_RET_DEFAULT:
+ ret = -EOPNOTSUPP;
+ break;
+ default:
+ ret = -EINVAL;
+ }
+ break;
default:
ret = -EOPNOTSUPP;
}
diff --git a/arch/riscv/kvm/vcpu_sbi_replace.c b/arch/riscv/kvm/vcpu_sbi_replace.c
index 1bc0608a5bfd..0f217365c287 100644
--- a/arch/riscv/kvm/vcpu_sbi_replace.c
+++ b/arch/riscv/kvm/vcpu_sbi_replace.c
@@ -130,3 +130,47 @@ const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_rfence = {
.extid_end = SBI_EXT_RFENCE,
.handler = kvm_sbi_ext_rfence_handler,
};
+
+static int kvm_sbi_ext_srst_handler(struct kvm_vcpu *vcpu,
+ struct kvm_run *run,
+ unsigned long *out_val,
+ struct kvm_cpu_trap *utrap, bool *exit)
+{
+ struct kvm_cpu_context *cp = &vcpu->arch.guest_context;
+ unsigned long funcid = cp->a6;
+ u32 reason = cp->a1;
+ u32 type = cp->a0;
+ int ret = 0;
+
+ switch (funcid) {
+ case SBI_EXT_SRST_RESET:
+ switch (type) {
+ case SBI_SRST_RESET_TYPE_SHUTDOWN:
+ kvm_riscv_vcpu_sbi_system_reset(vcpu, run,
+ KVM_SYSTEM_EVENT_SHUTDOWN,
+ reason);
+ *exit = true;
+ break;
+ case SBI_SRST_RESET_TYPE_COLD_REBOOT:
+ case SBI_SRST_RESET_TYPE_WARM_REBOOT:
+ kvm_riscv_vcpu_sbi_system_reset(vcpu, run,
+ KVM_SYSTEM_EVENT_RESET,
+ reason);
+ *exit = true;
+ break;
+ default:
+ ret = -EOPNOTSUPP;
+ }
+ break;
+ default:
+ ret = -EOPNOTSUPP;
+ }
+
+ return ret;
+}
+
+const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_srst = {
+ .extid_start = SBI_EXT_SRST,
+ .extid_end = SBI_EXT_SRST,
+ .handler = kvm_sbi_ext_srst_handler,
+};
diff --git a/arch/riscv/kvm/vcpu_sbi_v01.c b/arch/riscv/kvm/vcpu_sbi_v01.c
index 07e2de14433a..da4d6c99c2cf 100644
--- a/arch/riscv/kvm/vcpu_sbi_v01.c
+++ b/arch/riscv/kvm/vcpu_sbi_v01.c
@@ -14,21 +14,6 @@
#include <asm/kvm_vcpu_timer.h>
#include <asm/kvm_vcpu_sbi.h>
-static void kvm_sbi_system_shutdown(struct kvm_vcpu *vcpu,
- struct kvm_run *run, u32 type)
-{
- unsigned long i;
- struct kvm_vcpu *tmp;
-
- kvm_for_each_vcpu(i, tmp, vcpu->kvm)
- tmp->arch.power_off = true;
- kvm_make_all_cpus_request(vcpu->kvm, KVM_REQ_SLEEP);
-
- memset(&run->system_event, 0, sizeof(run->system_event));
- run->system_event.type = type;
- run->exit_reason = KVM_EXIT_SYSTEM_EVENT;
-}
-
static int kvm_sbi_ext_v01_handler(struct kvm_vcpu *vcpu, struct kvm_run *run,
unsigned long *out_val,
struct kvm_cpu_trap *utrap,
@@ -80,7 +65,8 @@ static int kvm_sbi_ext_v01_handler(struct kvm_vcpu *vcpu, struct kvm_run *run,
}
break;
case SBI_EXT_0_1_SHUTDOWN:
- kvm_sbi_system_shutdown(vcpu, run, KVM_SYSTEM_EVENT_SHUTDOWN);
+ kvm_riscv_vcpu_sbi_system_reset(vcpu, run,
+ KVM_SYSTEM_EVENT_SHUTDOWN, 0);
*exit = true;
break;
case SBI_EXT_0_1_REMOTE_FENCE_I:
@@ -111,7 +97,7 @@ static int kvm_sbi_ext_v01_handler(struct kvm_vcpu *vcpu, struct kvm_run *run,
default:
ret = -EINVAL;
break;
- };
+ }
return ret;
}
diff --git a/arch/riscv/kvm/vcpu_switch.S b/arch/riscv/kvm/vcpu_switch.S
index 029a28a195c6..d74df8eb4d71 100644
--- a/arch/riscv/kvm/vcpu_switch.S
+++ b/arch/riscv/kvm/vcpu_switch.S
@@ -41,33 +41,37 @@ ENTRY(__kvm_riscv_switch_to)
REG_S s10, (KVM_ARCH_HOST_S10)(a0)
REG_S s11, (KVM_ARCH_HOST_S11)(a0)
- /* Save Host and Restore Guest SSTATUS */
+ /* Load Guest CSR values */
REG_L t0, (KVM_ARCH_GUEST_SSTATUS)(a0)
+ REG_L t1, (KVM_ARCH_GUEST_HSTATUS)(a0)
+ REG_L t2, (KVM_ARCH_GUEST_SCOUNTEREN)(a0)
+ la t4, __kvm_switch_return
+ REG_L t5, (KVM_ARCH_GUEST_SEPC)(a0)
+
+ /* Save Host and Restore Guest SSTATUS */
csrrw t0, CSR_SSTATUS, t0
- REG_S t0, (KVM_ARCH_HOST_SSTATUS)(a0)
/* Save Host and Restore Guest HSTATUS */
- REG_L t1, (KVM_ARCH_GUEST_HSTATUS)(a0)
csrrw t1, CSR_HSTATUS, t1
- REG_S t1, (KVM_ARCH_HOST_HSTATUS)(a0)
/* Save Host and Restore Guest SCOUNTEREN */
- REG_L t2, (KVM_ARCH_GUEST_SCOUNTEREN)(a0)
csrrw t2, CSR_SCOUNTEREN, t2
- REG_S t2, (KVM_ARCH_HOST_SCOUNTEREN)(a0)
-
- /* Save Host SSCRATCH and change it to struct kvm_vcpu_arch pointer */
- csrrw t3, CSR_SSCRATCH, a0
- REG_S t3, (KVM_ARCH_HOST_SSCRATCH)(a0)
/* Save Host STVEC and change it to return path */
- la t4, __kvm_switch_return
csrrw t4, CSR_STVEC, t4
- REG_S t4, (KVM_ARCH_HOST_STVEC)(a0)
+
+ /* Save Host SSCRATCH and change it to struct kvm_vcpu_arch pointer */
+ csrrw t3, CSR_SSCRATCH, a0
/* Restore Guest SEPC */
- REG_L t0, (KVM_ARCH_GUEST_SEPC)(a0)
- csrw CSR_SEPC, t0
+ csrw CSR_SEPC, t5
+
+ /* Store Host CSR values */
+ REG_S t0, (KVM_ARCH_HOST_SSTATUS)(a0)
+ REG_S t1, (KVM_ARCH_HOST_HSTATUS)(a0)
+ REG_S t2, (KVM_ARCH_HOST_SCOUNTEREN)(a0)
+ REG_S t3, (KVM_ARCH_HOST_SSCRATCH)(a0)
+ REG_S t4, (KVM_ARCH_HOST_STVEC)(a0)
/* Restore Guest GPRs (except A0) */
REG_L ra, (KVM_ARCH_GUEST_RA)(a0)
@@ -145,32 +149,36 @@ __kvm_switch_return:
REG_S t5, (KVM_ARCH_GUEST_T5)(a0)
REG_S t6, (KVM_ARCH_GUEST_T6)(a0)
+ /* Load Host CSR values */
+ REG_L t1, (KVM_ARCH_HOST_STVEC)(a0)
+ REG_L t2, (KVM_ARCH_HOST_SSCRATCH)(a0)
+ REG_L t3, (KVM_ARCH_HOST_SCOUNTEREN)(a0)
+ REG_L t4, (KVM_ARCH_HOST_HSTATUS)(a0)
+ REG_L t5, (KVM_ARCH_HOST_SSTATUS)(a0)
+
/* Save Guest SEPC */
csrr t0, CSR_SEPC
- REG_S t0, (KVM_ARCH_GUEST_SEPC)(a0)
-
- /* Restore Host STVEC */
- REG_L t1, (KVM_ARCH_HOST_STVEC)(a0)
- csrw CSR_STVEC, t1
/* Save Guest A0 and Restore Host SSCRATCH */
- REG_L t2, (KVM_ARCH_HOST_SSCRATCH)(a0)
csrrw t2, CSR_SSCRATCH, t2
- REG_S t2, (KVM_ARCH_GUEST_A0)(a0)
+
+ /* Restore Host STVEC */
+ csrw CSR_STVEC, t1
/* Save Guest and Restore Host SCOUNTEREN */
- REG_L t3, (KVM_ARCH_HOST_SCOUNTEREN)(a0)
csrrw t3, CSR_SCOUNTEREN, t3
- REG_S t3, (KVM_ARCH_GUEST_SCOUNTEREN)(a0)
/* Save Guest and Restore Host HSTATUS */
- REG_L t4, (KVM_ARCH_HOST_HSTATUS)(a0)
csrrw t4, CSR_HSTATUS, t4
- REG_S t4, (KVM_ARCH_GUEST_HSTATUS)(a0)
/* Save Guest and Restore Host SSTATUS */
- REG_L t5, (KVM_ARCH_HOST_SSTATUS)(a0)
csrrw t5, CSR_SSTATUS, t5
+
+ /* Store Guest CSR values */
+ REG_S t0, (KVM_ARCH_GUEST_SEPC)(a0)
+ REG_S t2, (KVM_ARCH_GUEST_A0)(a0)
+ REG_S t3, (KVM_ARCH_GUEST_SCOUNTEREN)(a0)
+ REG_S t4, (KVM_ARCH_GUEST_HSTATUS)(a0)
REG_S t5, (KVM_ARCH_GUEST_SSTATUS)(a0)
/* Restore Host GPRs (except A0 and T0-T6) */
diff --git a/arch/riscv/mm/Makefile b/arch/riscv/mm/Makefile
index 7ebaef10ea1b..ac7a25298a04 100644
--- a/arch/riscv/mm/Makefile
+++ b/arch/riscv/mm/Makefile
@@ -24,6 +24,9 @@ obj-$(CONFIG_KASAN) += kasan_init.o
ifdef CONFIG_KASAN
KASAN_SANITIZE_kasan_init.o := n
KASAN_SANITIZE_init.o := n
+ifdef CONFIG_DEBUG_VIRTUAL
+KASAN_SANITIZE_physaddr.o := n
+endif
endif
obj-$(CONFIG_DEBUG_VIRTUAL) += physaddr.o
diff --git a/arch/riscv/mm/extable.c b/arch/riscv/mm/extable.c
index 05978f78579f..35484d830fd6 100644
--- a/arch/riscv/mm/extable.c
+++ b/arch/riscv/mm/extable.c
@@ -33,7 +33,7 @@ static inline void regs_set_gpr(struct pt_regs *regs, unsigned int offset,
if (unlikely(offset > MAX_REG_OFFSET))
return;
- if (!offset)
+ if (offset)
*(unsigned long *)((unsigned long)regs + offset) = val;
}
@@ -43,8 +43,8 @@ static bool ex_handler_uaccess_err_zero(const struct exception_table_entry *ex,
int reg_err = FIELD_GET(EX_DATA_REG_ERR, ex->data);
int reg_zero = FIELD_GET(EX_DATA_REG_ZERO, ex->data);
- regs_set_gpr(regs, reg_err, -EFAULT);
- regs_set_gpr(regs, reg_zero, 0);
+ regs_set_gpr(regs, reg_err * sizeof(unsigned long), -EFAULT);
+ regs_set_gpr(regs, reg_zero * sizeof(unsigned long), 0);
regs->epc = get_ex_fixup(ex);
return true;
diff --git a/arch/riscv/mm/init.c b/arch/riscv/mm/init.c
index cf4d018b7d66..f6275b317129 100644
--- a/arch/riscv/mm/init.c
+++ b/arch/riscv/mm/init.c
@@ -125,7 +125,6 @@ void __init mem_init(void)
else
swiotlb_force = SWIOTLB_NO_FORCE;
#endif
- high_memory = (void *)(__va(PFN_PHYS(max_low_pfn)));
memblock_free_all();
print_vm_layout();
@@ -195,6 +194,7 @@ static void __init setup_bootmem(void)
min_low_pfn = PFN_UP(phys_ram_base);
max_low_pfn = max_pfn = PFN_DOWN(phys_ram_end);
+ high_memory = (void *)(__va(PFN_PHYS(max_low_pfn)));
dma32_phys_limit = min(4UL * SZ_1G, (unsigned long)PFN_PHYS(max_low_pfn));
set_max_mapnr(max_low_pfn - ARCH_PFN_OFFSET);
@@ -232,6 +232,7 @@ static pmd_t __maybe_unused early_dtb_pmd[PTRS_PER_PMD] __initdata __aligned(PAG
#ifdef CONFIG_XIP_KERNEL
#define pt_ops (*(struct pt_alloc_ops *)XIP_FIXUP(&pt_ops))
+#define riscv_pfn_base (*(unsigned long *)XIP_FIXUP(&riscv_pfn_base))
#define trampoline_pg_dir ((pgd_t *)XIP_FIXUP(trampoline_pg_dir))
#define fixmap_pte ((pte_t *)XIP_FIXUP(fixmap_pte))
#define early_pg_dir ((pgd_t *)XIP_FIXUP(early_pg_dir))
@@ -522,6 +523,7 @@ static uintptr_t __init best_map_size(phys_addr_t base, phys_addr_t size)
}
#ifdef CONFIG_XIP_KERNEL
+#define phys_ram_base (*(phys_addr_t *)XIP_FIXUP(&phys_ram_base))
extern char _xiprom[], _exiprom[], __data_loc;
/* called from head.S with MMU off */
@@ -955,7 +957,6 @@ static inline void setup_vm_final(void)
}
#endif /* CONFIG_MMU */
-#ifdef CONFIG_KEXEC_CORE
/*
* reserve_crashkernel() - reserves memory for crash kernel
*
@@ -972,6 +973,8 @@ static void __init reserve_crashkernel(void)
int ret = 0;
+ if (!IS_ENABLED(CONFIG_KEXEC_CORE))
+ return;
/*
* Don't reserve a region for a crash kernel on a crash kernel
* since it doesn't make much sense and we have limited memory
@@ -1021,7 +1024,6 @@ static void __init reserve_crashkernel(void)
crashk_res.start = crash_base;
crashk_res.end = crash_base + crash_size - 1;
}
-#endif /* CONFIG_KEXEC_CORE */
void __init paging_init(void)
{
@@ -1035,9 +1037,7 @@ void __init misc_mem_init(void)
arch_numa_init();
sparse_init();
zone_sizes_init();
-#ifdef CONFIG_KEXEC_CORE
reserve_crashkernel();
-#endif
memblock_dump_all();
}
diff --git a/arch/riscv/mm/kasan_init.c b/arch/riscv/mm/kasan_init.c
index f61f7ca6fe0f..cd1a145257b7 100644
--- a/arch/riscv/mm/kasan_init.c
+++ b/arch/riscv/mm/kasan_init.c
@@ -113,8 +113,11 @@ static void __init kasan_populate_pud(pgd_t *pgd,
base_pud = pt_ops.get_pud_virt(pfn_to_phys(_pgd_pfn(*pgd)));
} else {
base_pud = (pud_t *)pgd_page_vaddr(*pgd);
- if (base_pud == lm_alias(kasan_early_shadow_pud))
+ if (base_pud == lm_alias(kasan_early_shadow_pud)) {
base_pud = memblock_alloc(PTRS_PER_PUD * sizeof(pud_t), PAGE_SIZE);
+ memcpy(base_pud, (void *)kasan_early_shadow_pud,
+ sizeof(pud_t) * PTRS_PER_PUD);
+ }
}
pudp = base_pud + pud_index(vaddr);
@@ -202,8 +205,7 @@ asmlinkage void __init kasan_early_init(void)
for (i = 0; i < PTRS_PER_PTE; ++i)
set_pte(kasan_early_shadow_pte + i,
- mk_pte(virt_to_page(kasan_early_shadow_page),
- PAGE_KERNEL));
+ pfn_pte(virt_to_pfn(kasan_early_shadow_page), PAGE_KERNEL));
for (i = 0; i < PTRS_PER_PMD; ++i)
set_pmd(kasan_early_shadow_pmd + i,
diff --git a/arch/riscv/mm/physaddr.c b/arch/riscv/mm/physaddr.c
index e7fd0c253c7b..19cf25a74ee2 100644
--- a/arch/riscv/mm/physaddr.c
+++ b/arch/riscv/mm/physaddr.c
@@ -8,12 +8,10 @@
phys_addr_t __virt_to_phys(unsigned long x)
{
- phys_addr_t y = x - PAGE_OFFSET;
-
/*
* Boundary checking aginst the kernel linear mapping space.
*/
- WARN(y >= KERN_VIRT_SIZE,
+ WARN(!is_linear_mapping(x) && !is_kernel_mapping(x),
"virt_to_phys used for non-linear address: %pK (%pS)\n",
(void *)x, (void *)x);
diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig
index 9750f92380f5..2e11ef97c8b9 100644
--- a/arch/s390/Kconfig
+++ b/arch/s390/Kconfig
@@ -55,11 +55,13 @@ config S390
# Note: keep this list sorted alphabetically
#
imply IMA_SECURE_AND_OR_TRUSTED_BOOT
+ select ALTERNATE_USER_ADDRESS_SPACE
select ARCH_32BIT_USTAT_F_TINODE
select ARCH_BINFMT_ELF_STATE
select ARCH_ENABLE_MEMORY_HOTPLUG if SPARSEMEM
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_VM_PGTABLE
select ARCH_HAS_DEBUG_WX
select ARCH_HAS_DEVMEM_IS_ALLOWED
@@ -945,6 +947,9 @@ config S390_GUEST
endmenu
+config S390_MODULES_SANITY_TEST_HELPERS
+ def_bool n
+
menu "Selftests"
config S390_UNWIND_SELFTEST
@@ -971,4 +976,16 @@ config S390_KPROBES_SANITY_TEST
Say N if you are unsure.
+config S390_MODULES_SANITY_TEST
+ def_tristate n
+ depends on KUNIT
+ default KUNIT_ALL_TESTS
+ prompt "Enable s390 specific modules tests"
+ select S390_MODULES_SANITY_TEST_HELPERS
+ help
+ This option enables an s390 specific modules test. This option is
+ not useful for distributions or general kernels, but only for
+ kernel developers working on architecture code.
+
+ Say N if you are unsure.
endmenu
diff --git a/arch/s390/configs/debug_defconfig b/arch/s390/configs/debug_defconfig
index 7fe8975b49ec..498bed9b261b 100644
--- a/arch/s390/configs/debug_defconfig
+++ b/arch/s390/configs/debug_defconfig
@@ -63,6 +63,7 @@ CONFIG_APPLDATA_BASE=y
CONFIG_KVM=m
CONFIG_S390_UNWIND_SELFTEST=m
CONFIG_S390_KPROBES_SANITY_TEST=m
+CONFIG_S390_MODULES_SANITY_TEST=m
CONFIG_KPROBES=y
CONFIG_JUMP_LABEL=y
CONFIG_STATIC_KEYS_SELFTEST=y
@@ -96,7 +97,6 @@ CONFIG_MEMORY_HOTPLUG=y
CONFIG_MEMORY_HOTREMOVE=y
CONFIG_KSM=y
CONFIG_TRANSPARENT_HUGEPAGE=y
-CONFIG_FRONTSWAP=y
CONFIG_CMA_DEBUG=y
CONFIG_CMA_DEBUGFS=y
CONFIG_CMA_SYSFS=y
@@ -109,6 +109,7 @@ CONFIG_DEFERRED_STRUCT_PAGE_INIT=y
CONFIG_IDLE_PAGE_TRACKING=y
CONFIG_PERCPU_STATS=y
CONFIG_GUP_TEST=y
+CONFIG_ANON_VMA_NAME=y
CONFIG_NET=y
CONFIG_PACKET=y
CONFIG_PACKET_DIAG=m
@@ -116,7 +117,6 @@ CONFIG_UNIX=y
CONFIG_UNIX_DIAG=m
CONFIG_XFRM_USER=m
CONFIG_NET_KEY=m
-CONFIG_NET_SWITCHDEV=y
CONFIG_SMC=m
CONFIG_SMC_DIAG=m
CONFIG_INET=y
@@ -185,7 +185,6 @@ CONFIG_NF_CT_NETLINK_TIMEOUT=m
CONFIG_NF_TABLES=m
CONFIG_NF_TABLES_INET=y
CONFIG_NFT_CT=m
-CONFIG_NFT_COUNTER=m
CONFIG_NFT_LOG=m
CONFIG_NFT_LIMIT=m
CONFIG_NFT_NAT=m
@@ -391,6 +390,7 @@ CONFIG_OPENVSWITCH=m
CONFIG_VSOCKETS=m
CONFIG_VIRTIO_VSOCKETS=m
CONFIG_NETLINK_DIAG=m
+CONFIG_NET_SWITCHDEV=y
CONFIG_CGROUP_NET_PRIO=y
CONFIG_NET_PKTGEN=m
CONFIG_PCI=y
@@ -400,6 +400,7 @@ CONFIG_PCI_IOV=y
CONFIG_HOTPLUG_PCI=y
CONFIG_HOTPLUG_PCI_S390=y
CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_SAFE=y
CONFIG_CONNECTOR=y
CONFIG_ZRAM=y
CONFIG_BLK_DEV_LOOP=m
@@ -501,6 +502,7 @@ CONFIG_NLMON=m
# CONFIG_NET_VENDOR_DEC is not set
# CONFIG_NET_VENDOR_DLINK is not set
# CONFIG_NET_VENDOR_EMULEX is not set
+# CONFIG_NET_VENDOR_ENGLEDER is not set
# CONFIG_NET_VENDOR_EZCHIP is not set
# CONFIG_NET_VENDOR_GOOGLE is not set
# CONFIG_NET_VENDOR_HUAWEI is not set
@@ -511,7 +513,6 @@ CONFIG_NLMON=m
CONFIG_MLX4_EN=m
CONFIG_MLX5_CORE=m
CONFIG_MLX5_CORE_EN=y
-CONFIG_MLX5_ESWITCH=y
# CONFIG_NET_VENDOR_MICREL is not set
# CONFIG_NET_VENDOR_MICROCHIP is not set
# CONFIG_NET_VENDOR_MICROSEMI is not set
@@ -542,6 +543,7 @@ CONFIG_MLX5_ESWITCH=y
# CONFIG_NET_VENDOR_SYNOPSYS is not set
# CONFIG_NET_VENDOR_TEHUTI is not set
# CONFIG_NET_VENDOR_TI is not set
+# CONFIG_NET_VENDOR_VERTEXCOM is not set
# CONFIG_NET_VENDOR_VIA is not set
# CONFIG_NET_VENDOR_WIZNET is not set
# CONFIG_NET_VENDOR_XILINX is not set
@@ -592,6 +594,7 @@ CONFIG_VIRTIO_BALLOON=m
CONFIG_VIRTIO_INPUT=y
CONFIG_VHOST_NET=m
CONFIG_VHOST_VSOCK=m
+# CONFIG_SURFACE_PLATFORMS is not set
CONFIG_S390_CCW_IOMMU=y
CONFIG_S390_AP_IOMMU=y
CONFIG_EXT4_FS=y
@@ -756,9 +759,6 @@ CONFIG_CRYPTO_USER_API_SKCIPHER=m
CONFIG_CRYPTO_USER_API_RNG=m
CONFIG_CRYPTO_USER_API_AEAD=m
CONFIG_CRYPTO_STATS=y
-CONFIG_CRYPTO_LIB_BLAKE2S=m
-CONFIG_CRYPTO_LIB_CURVE25519=m
-CONFIG_CRYPTO_LIB_CHACHA20POLY1305=m
CONFIG_ZCRYPT=m
CONFIG_PKEY=m
CONFIG_CRYPTO_PAES_S390=m
@@ -774,6 +774,8 @@ CONFIG_CRYPTO_GHASH_S390=m
CONFIG_CRYPTO_CRC32_S390=y
CONFIG_CRYPTO_DEV_VIRTIO=m
CONFIG_CORDIC=m
+CONFIG_CRYPTO_LIB_CURVE25519=m
+CONFIG_CRYPTO_LIB_CHACHA20POLY1305=m
CONFIG_CRC32_SELFTEST=y
CONFIG_CRC4=m
CONFIG_CRC7=m
@@ -807,7 +809,6 @@ CONFIG_SLUB_DEBUG_ON=y
CONFIG_SLUB_STATS=y
CONFIG_DEBUG_STACK_USAGE=y
CONFIG_DEBUG_VM=y
-CONFIG_DEBUG_VM_VMACACHE=y
CONFIG_DEBUG_VM_PGFLAGS=y
CONFIG_DEBUG_MEMORY_INIT=y
CONFIG_MEMORY_NOTIFIER_ERROR_INJECT=m
@@ -819,12 +820,11 @@ CONFIG_PANIC_ON_OOPS=y
CONFIG_DETECT_HUNG_TASK=y
CONFIG_WQ_WATCHDOG=y
CONFIG_TEST_LOCKUP=m
-CONFIG_DEBUG_TIMEKEEPING=y
CONFIG_PROVE_LOCKING=y
CONFIG_LOCK_STAT=y
-CONFIG_DEBUG_LOCKDEP=y
CONFIG_DEBUG_ATOMIC_SLEEP=y
CONFIG_DEBUG_LOCKING_API_SELFTESTS=y
+CONFIG_DEBUG_IRQFLAGS=y
CONFIG_DEBUG_SG=y
CONFIG_DEBUG_NOTIFIERS=y
CONFIG_BUG_ON_DATA_CORRUPTION=y
diff --git a/arch/s390/configs/defconfig b/arch/s390/configs/defconfig
index 466780c465f5..61e36b999f67 100644
--- a/arch/s390/configs/defconfig
+++ b/arch/s390/configs/defconfig
@@ -61,6 +61,7 @@ CONFIG_APPLDATA_BASE=y
CONFIG_KVM=m
CONFIG_S390_UNWIND_SELFTEST=m
CONFIG_S390_KPROBES_SANITY_TEST=m
+CONFIG_S390_MODULES_SANITY_TEST=m
CONFIG_KPROBES=y
CONFIG_JUMP_LABEL=y
# CONFIG_GCC_PLUGINS is not set
@@ -91,7 +92,6 @@ CONFIG_MEMORY_HOTPLUG=y
CONFIG_MEMORY_HOTREMOVE=y
CONFIG_KSM=y
CONFIG_TRANSPARENT_HUGEPAGE=y
-CONFIG_FRONTSWAP=y
CONFIG_CMA_SYSFS=y
CONFIG_CMA_AREAS=7
CONFIG_MEM_SOFT_DIRTY=y
@@ -101,6 +101,7 @@ CONFIG_ZSMALLOC_STAT=y
CONFIG_DEFERRED_STRUCT_PAGE_INIT=y
CONFIG_IDLE_PAGE_TRACKING=y
CONFIG_PERCPU_STATS=y
+CONFIG_ANON_VMA_NAME=y
CONFIG_NET=y
CONFIG_PACKET=y
CONFIG_PACKET_DIAG=m
@@ -108,7 +109,6 @@ CONFIG_UNIX=y
CONFIG_UNIX_DIAG=m
CONFIG_XFRM_USER=m
CONFIG_NET_KEY=m
-CONFIG_NET_SWITCHDEV=y
CONFIG_SMC=m
CONFIG_SMC_DIAG=m
CONFIG_INET=y
@@ -177,7 +177,6 @@ CONFIG_NF_CT_NETLINK_TIMEOUT=m
CONFIG_NF_TABLES=m
CONFIG_NF_TABLES_INET=y
CONFIG_NFT_CT=m
-CONFIG_NFT_COUNTER=m
CONFIG_NFT_LOG=m
CONFIG_NFT_LIMIT=m
CONFIG_NFT_NAT=m
@@ -382,6 +381,7 @@ CONFIG_OPENVSWITCH=m
CONFIG_VSOCKETS=m
CONFIG_VIRTIO_VSOCKETS=m
CONFIG_NETLINK_DIAG=m
+CONFIG_NET_SWITCHDEV=y
CONFIG_CGROUP_NET_PRIO=y
CONFIG_NET_PKTGEN=m
CONFIG_PCI=y
@@ -391,6 +391,7 @@ CONFIG_HOTPLUG_PCI=y
CONFIG_HOTPLUG_PCI_S390=y
CONFIG_UEVENT_HELPER=y
CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_SAFE=y
CONFIG_CONNECTOR=y
CONFIG_ZRAM=y
CONFIG_BLK_DEV_LOOP=m
@@ -492,6 +493,7 @@ CONFIG_NLMON=m
# CONFIG_NET_VENDOR_DEC is not set
# CONFIG_NET_VENDOR_DLINK is not set
# CONFIG_NET_VENDOR_EMULEX is not set
+# CONFIG_NET_VENDOR_ENGLEDER is not set
# CONFIG_NET_VENDOR_EZCHIP is not set
# CONFIG_NET_VENDOR_GOOGLE is not set
# CONFIG_NET_VENDOR_HUAWEI is not set
@@ -502,7 +504,6 @@ CONFIG_NLMON=m
CONFIG_MLX4_EN=m
CONFIG_MLX5_CORE=m
CONFIG_MLX5_CORE_EN=y
-CONFIG_MLX5_ESWITCH=y
# CONFIG_NET_VENDOR_MICREL is not set
# CONFIG_NET_VENDOR_MICROCHIP is not set
# CONFIG_NET_VENDOR_MICROSEMI is not set
@@ -533,6 +534,7 @@ CONFIG_MLX5_ESWITCH=y
# CONFIG_NET_VENDOR_SYNOPSYS is not set
# CONFIG_NET_VENDOR_TEHUTI is not set
# CONFIG_NET_VENDOR_TI is not set
+# CONFIG_NET_VENDOR_VERTEXCOM is not set
# CONFIG_NET_VENDOR_VIA is not set
# CONFIG_NET_VENDOR_WIZNET is not set
# CONFIG_NET_VENDOR_XILINX is not set
@@ -582,6 +584,7 @@ CONFIG_VIRTIO_BALLOON=m
CONFIG_VIRTIO_INPUT=y
CONFIG_VHOST_NET=m
CONFIG_VHOST_VSOCK=m
+# CONFIG_SURFACE_PLATFORMS is not set
CONFIG_S390_CCW_IOMMU=y
CONFIG_S390_AP_IOMMU=y
CONFIG_EXT4_FS=y
@@ -743,9 +746,6 @@ CONFIG_CRYPTO_USER_API_SKCIPHER=m
CONFIG_CRYPTO_USER_API_RNG=m
CONFIG_CRYPTO_USER_API_AEAD=m
CONFIG_CRYPTO_STATS=y
-CONFIG_CRYPTO_LIB_BLAKE2S=m
-CONFIG_CRYPTO_LIB_CURVE25519=m
-CONFIG_CRYPTO_LIB_CHACHA20POLY1305=m
CONFIG_ZCRYPT=m
CONFIG_PKEY=m
CONFIG_CRYPTO_PAES_S390=m
@@ -762,6 +762,8 @@ CONFIG_CRYPTO_CRC32_S390=y
CONFIG_CRYPTO_DEV_VIRTIO=m
CONFIG_CORDIC=m
CONFIG_PRIME_NUMBERS=m
+CONFIG_CRYPTO_LIB_CURVE25519=m
+CONFIG_CRYPTO_LIB_CHACHA20POLY1305=m
CONFIG_CRC4=m
CONFIG_CRC7=m
CONFIG_CRC8=m
diff --git a/arch/s390/configs/zfcpdump_defconfig b/arch/s390/configs/zfcpdump_defconfig
index eed3b9acfa71..c55c668dc3c7 100644
--- a/arch/s390/configs/zfcpdump_defconfig
+++ b/arch/s390/configs/zfcpdump_defconfig
@@ -1,6 +1,7 @@
# CONFIG_SWAP is not set
CONFIG_NO_HZ_IDLE=y
CONFIG_HIGH_RES_TIMERS=y
+CONFIG_BPF_SYSCALL=y
# CONFIG_CPU_ISOLATION is not set
# CONFIG_UTS_NS is not set
# CONFIG_TIME_NS is not set
@@ -34,6 +35,7 @@ CONFIG_NET=y
# CONFIG_PCPU_DEV_REFCNT is not set
# CONFIG_ETHTOOL_NETLINK is not set
CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_SAFE=y
CONFIG_BLK_DEV_RAM=y
# CONFIG_DCSSBLK is not set
# CONFIG_DASD is not set
@@ -58,6 +60,7 @@ CONFIG_ZFCP=y
# CONFIG_HID is not set
# CONFIG_VIRTIO_MENU is not set
# CONFIG_VHOST_MENU is not set
+# CONFIG_SURFACE_PLATFORMS is not set
# CONFIG_IOMMU_SUPPORT is not set
# CONFIG_DNOTIFY is not set
# CONFIG_INOTIFY_USER is not set
diff --git a/arch/s390/hypfs/hypfs_vm.c b/arch/s390/hypfs/hypfs_vm.c
index 33f973ff9744..e8f15dbb89d0 100644
--- a/arch/s390/hypfs/hypfs_vm.c
+++ b/arch/s390/hypfs/hypfs_vm.c
@@ -20,6 +20,7 @@
static char local_guest[] = " ";
static char all_guests[] = "* ";
+static char *all_groups = all_guests;
static char *guest_query;
struct diag2fc_data {
@@ -62,10 +63,11 @@ static int diag2fc(int size, char* query, void *addr)
memcpy(parm_list.userid, query, NAME_LEN);
ASCEBC(parm_list.userid, NAME_LEN);
- parm_list.addr = (unsigned long) addr ;
+ memcpy(parm_list.aci_grp, all_groups, NAME_LEN);
+ ASCEBC(parm_list.aci_grp, NAME_LEN);
+ parm_list.addr = (unsigned long)addr;
parm_list.size = size;
parm_list.fmt = 0x02;
- memset(parm_list.aci_grp, 0x40, NAME_LEN);
rc = -1;
diag_stat_inc(DIAG_STAT_X2FC);
diff --git a/arch/s390/include/asm/ccwgroup.h b/arch/s390/include/asm/ccwgroup.h
index aa995d91cd1d..11d2fb3de4f5 100644
--- a/arch/s390/include/asm/ccwgroup.h
+++ b/arch/s390/include/asm/ccwgroup.h
@@ -25,7 +25,7 @@ struct ccwgroup_device {
unsigned int count;
struct device dev;
struct work_struct ungroup_work;
- struct ccw_device *cdev[0];
+ struct ccw_device *cdev[];
};
/**
diff --git a/arch/s390/include/asm/chsc.h b/arch/s390/include/asm/chsc.h
index ae4d2549cd67..bb48ea380c0d 100644
--- a/arch/s390/include/asm/chsc.h
+++ b/arch/s390/include/asm/chsc.h
@@ -63,7 +63,7 @@ struct chsc_pnso_area {
struct chsc_header response;
u32:32;
struct chsc_pnso_naihdr naihdr;
- struct chsc_pnso_naid_l2 entries[0];
+ struct chsc_pnso_naid_l2 entries[];
} __packed __aligned(PAGE_SIZE);
#endif /* _ASM_S390_CHSC_H */
diff --git a/arch/s390/include/asm/ctl_reg.h b/arch/s390/include/asm/ctl_reg.h
index 04dc65f8901d..c800199a376b 100644
--- a/arch/s390/include/asm/ctl_reg.h
+++ b/arch/s390/include/asm/ctl_reg.h
@@ -12,6 +12,8 @@
#define CR0_CLOCK_COMPARATOR_SIGN BIT(63 - 10)
#define CR0_LOW_ADDRESS_PROTECTION BIT(63 - 35)
+#define CR0_FETCH_PROTECTION_OVERRIDE BIT(63 - 38)
+#define CR0_STORAGE_PROTECTION_OVERRIDE BIT(63 - 39)
#define CR0_EMERGENCY_SIGNAL_SUBMASK BIT(63 - 49)
#define CR0_EXTERNAL_CALL_SUBMASK BIT(63 - 50)
#define CR0_CLOCK_COMPARATOR_SUBMASK BIT(63 - 52)
diff --git a/arch/s390/include/asm/eadm.h b/arch/s390/include/asm/eadm.h
index 445fe4c8184a..06f795855af7 100644
--- a/arch/s390/include/asm/eadm.h
+++ b/arch/s390/include/asm/eadm.h
@@ -78,7 +78,7 @@ struct aob {
struct aob_rq_header {
struct scm_device *scmdev;
- char data[0];
+ char data[];
};
struct scm_device {
diff --git a/arch/s390/include/asm/extable.h b/arch/s390/include/asm/extable.h
index 16dc57dd90b3..8511f0e59290 100644
--- a/arch/s390/include/asm/extable.h
+++ b/arch/s390/include/asm/extable.h
@@ -69,8 +69,13 @@ static inline void swap_ex_entry_fixup(struct exception_table_entry *a,
{
a->fixup = b->fixup + delta;
b->fixup = tmp.fixup - delta;
- a->handler = b->handler + delta;
- b->handler = tmp.handler - delta;
+ a->handler = b->handler;
+ if (a->handler)
+ a->handler += delta;
+ b->handler = tmp.handler;
+ if (b->handler)
+ b->handler -= delta;
}
+#define swap_ex_entry_fixup swap_ex_entry_fixup
#endif
diff --git a/arch/s390/include/asm/fcx.h b/arch/s390/include/asm/fcx.h
index cff0749e9657..b8a028a36173 100644
--- a/arch/s390/include/asm/fcx.h
+++ b/arch/s390/include/asm/fcx.h
@@ -214,7 +214,7 @@ struct dcw_intrg_data {
u32 :32;
u64 time;
u64 prog_id;
- u8 prog_data[0];
+ u8 prog_data[];
} __attribute__ ((packed));
#define DCW_FLAGS_CC (1 << (7 - 1))
@@ -241,7 +241,7 @@ struct dcw {
u32 :8;
u32 cd_count:8;
u32 count;
- u8 cd[0];
+ u8 cd[];
} __attribute__ ((packed));
#define TCCB_FORMAT_DEFAULT 0x7f
diff --git a/arch/s390/include/asm/ftrace.h b/arch/s390/include/asm/ftrace.h
index 267f70f4393f..6f80ec9c04be 100644
--- a/arch/s390/include/asm/ftrace.h
+++ b/arch/s390/include/asm/ftrace.h
@@ -47,15 +47,17 @@ struct ftrace_regs {
static __always_inline struct pt_regs *arch_ftrace_get_regs(struct ftrace_regs *fregs)
{
- return &fregs->regs;
+ struct pt_regs *regs = &fregs->regs;
+
+ if (test_pt_regs_flag(regs, PIF_FTRACE_FULL_REGS))
+ return regs;
+ return NULL;
}
static __always_inline void ftrace_instruction_pointer_set(struct ftrace_regs *fregs,
unsigned long ip)
{
- struct pt_regs *regs = arch_ftrace_get_regs(fregs);
-
- regs->psw.addr = ip;
+ fregs->regs.psw.addr = ip;
}
/*
diff --git a/arch/s390/include/asm/idals.h b/arch/s390/include/asm/idals.h
index 6fb7aced104a..40eae2c08d61 100644
--- a/arch/s390/include/asm/idals.h
+++ b/arch/s390/include/asm/idals.h
@@ -108,7 +108,7 @@ clear_normalized_cda(struct ccw1 * ccw)
struct idal_buffer {
size_t size;
size_t page_order;
- void *data[0];
+ void *data[];
};
/*
diff --git a/arch/s390/include/asm/kvm_host.h b/arch/s390/include/asm/kvm_host.h
index a22c9266ea05..766028d54a3e 100644
--- a/arch/s390/include/asm/kvm_host.h
+++ b/arch/s390/include/asm/kvm_host.h
@@ -45,6 +45,8 @@
#define KVM_REQ_START_MIGRATION KVM_ARCH_REQ(3)
#define KVM_REQ_STOP_MIGRATION KVM_ARCH_REQ(4)
#define KVM_REQ_VSIE_RESTART KVM_ARCH_REQ(5)
+#define KVM_REQ_REFRESH_GUEST_PREFIX \
+ KVM_ARCH_REQ_FLAGS(6, KVM_REQUEST_WAIT | KVM_REQUEST_NO_WAKEUP)
#define SIGP_CTRL_C 0x80
#define SIGP_CTRL_SCN_MASK 0x3f
diff --git a/arch/s390/include/asm/page.h b/arch/s390/include/asm/page.h
index d98d17a36c7b..cfc4d6fb2385 100644
--- a/arch/s390/include/asm/page.h
+++ b/arch/s390/include/asm/page.h
@@ -20,6 +20,8 @@
#define PAGE_SIZE _PAGE_SIZE
#define PAGE_MASK _PAGE_MASK
#define PAGE_DEFAULT_ACC 0
+/* storage-protection override */
+#define PAGE_SPO_ACC 9
#define PAGE_DEFAULT_KEY (PAGE_DEFAULT_ACC << 4)
#define HPAGE_SHIFT 20
diff --git a/arch/s390/include/asm/ptrace.h b/arch/s390/include/asm/ptrace.h
index 4ffa8e7f0ed3..ddb70fb13fbc 100644
--- a/arch/s390/include/asm/ptrace.h
+++ b/arch/s390/include/asm/ptrace.h
@@ -15,11 +15,13 @@
#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)
#ifndef __ASSEMBLY__
diff --git a/arch/s390/include/asm/sclp.h b/arch/s390/include/asm/sclp.h
index c68ea35de498..22b3213c6c9d 100644
--- a/arch/s390/include/asm/sclp.h
+++ b/arch/s390/include/asm/sclp.h
@@ -112,7 +112,7 @@ struct zpci_report_error_header {
* (OpenCrypto Successful Diagnostics Execution)
*/
u16 length; /* Length of Subsequent Data (up to 4K – SCLP header */
- u8 data[0]; /* Subsequent Data passed verbatim to SCLP ET 24 */
+ u8 data[]; /* Subsequent Data passed verbatim to SCLP ET 24 */
} __packed;
extern char *sclp_early_sccb;
diff --git a/arch/s390/include/asm/sysinfo.h b/arch/s390/include/asm/sysinfo.h
index fe7b3f8f0791..ab1c6316055c 100644
--- a/arch/s390/include/asm/sysinfo.h
+++ b/arch/s390/include/asm/sysinfo.h
@@ -67,12 +67,12 @@ struct sysinfo_1_2_2 {
unsigned short cpus_configured;
unsigned short cpus_standby;
unsigned short cpus_reserved;
- unsigned short adjustment[0];
+ unsigned short adjustment[];
};
struct sysinfo_1_2_2_extension {
unsigned int alt_capability;
- unsigned short alt_adjustment[0];
+ unsigned short alt_adjustment[];
};
struct sysinfo_2_2_1 {
@@ -181,7 +181,7 @@ struct sysinfo_15_1_x {
unsigned char reserved1;
unsigned char mnest;
unsigned char reserved2[4];
- union topology_entry tle[0];
+ union topology_entry tle[];
};
int stsi(void *sysinfo, int fc, int sel1, int sel2);
diff --git a/arch/s390/include/asm/uaccess.h b/arch/s390/include/asm/uaccess.h
index 147cb3534ce4..e1be769cbf9f 100644
--- a/arch/s390/include/asm/uaccess.h
+++ b/arch/s390/include/asm/uaccess.h
@@ -17,22 +17,10 @@
#include <asm/ctl_reg.h>
#include <asm/extable.h>
#include <asm/facility.h>
+#include <asm-generic/access_ok.h>
void debug_user_asce(int exit);
-static inline int __range_ok(unsigned long addr, unsigned long size)
-{
- return 1;
-}
-
-#define __access_ok(addr, size) \
-({ \
- __chk_user_ptr(addr); \
- __range_ok((unsigned long)(addr), (size)); \
-})
-
-#define access_ok(addr, size) __access_ok(addr, size)
-
unsigned long __must_check
raw_copy_from_user(void *to, const void __user *from, unsigned long n);
@@ -44,11 +32,31 @@ raw_copy_to_user(void __user *to, const void *from, unsigned long n);
#define INLINE_COPY_TO_USER
#endif
+unsigned long __must_check
+_copy_from_user_key(void *to, const void __user *from, unsigned long n, unsigned long key);
+
+static __always_inline unsigned long __must_check
+copy_from_user_key(void *to, const void __user *from, unsigned long n, unsigned long key)
+{
+ if (likely(check_copy_size(to, n, false)))
+ n = _copy_from_user_key(to, from, n, key);
+ return n;
+}
+
+unsigned long __must_check
+_copy_to_user_key(void __user *to, const void *from, unsigned long n, unsigned long key);
+
+static __always_inline unsigned long __must_check
+copy_to_user_key(void __user *to, const void *from, unsigned long n, unsigned long key)
+{
+ if (likely(check_copy_size(from, n, true)))
+ n = _copy_to_user_key(to, from, n, key);
+ return n;
+}
+
int __put_user_bad(void) __attribute__((noreturn));
int __get_user_bad(void) __attribute__((noreturn));
-#ifdef CONFIG_HAVE_MARCH_Z10_FEATURES
-
union oac {
unsigned int val;
struct {
@@ -71,6 +79,8 @@ union oac {
};
};
+#ifdef CONFIG_HAVE_MARCH_Z10_FEATURES
+
#define __put_get_user_asm(to, from, size, oac_spec) \
({ \
int __rc; \
@@ -282,8 +292,6 @@ static inline unsigned long __must_check clear_user(void __user *to, unsigned lo
int copy_to_user_real(void __user *dest, void *src, unsigned long count);
void *s390_kernel_write(void *dst, const void *src, size_t size);
-#define HAVE_GET_KERNEL_NOFAULT
-
int __noreturn __put_kernel_bad(void);
#define __put_kernel_asm(val, to, insn) \
diff --git a/arch/s390/include/asm/uv.h b/arch/s390/include/asm/uv.h
index 86218382d29c..a2d376b8bce3 100644
--- a/arch/s390/include/asm/uv.h
+++ b/arch/s390/include/asm/uv.h
@@ -80,6 +80,7 @@ enum uv_cmds_inst {
enum uv_feat_ind {
BIT_UV_FEAT_MISC = 0,
+ BIT_UV_FEAT_AIV = 1,
};
struct uv_cb_header {
diff --git a/arch/s390/include/uapi/asm/signal.h b/arch/s390/include/uapi/asm/signal.h
index 0189f326aac5..e74d6ba1bd3b 100644
--- a/arch/s390/include/uapi/asm/signal.h
+++ b/arch/s390/include/uapi/asm/signal.h
@@ -108,7 +108,7 @@ struct sigaction {
typedef struct sigaltstack {
void __user *ss_sp;
int ss_flags;
- size_t ss_size;
+ __kernel_size_t ss_size;
} stack_t;
diff --git a/arch/s390/kernel/ftrace.c b/arch/s390/kernel/ftrace.c
index 21d62d8b6b9a..89c0870d5679 100644
--- a/arch/s390/kernel/ftrace.c
+++ b/arch/s390/kernel/ftrace.c
@@ -159,9 +159,38 @@ int ftrace_init_nop(struct module *mod, struct dyn_ftrace *rec)
return 0;
}
+static struct ftrace_hotpatch_trampoline *ftrace_get_trampoline(struct dyn_ftrace *rec)
+{
+ struct ftrace_hotpatch_trampoline *trampoline;
+ struct ftrace_insn insn;
+ s64 disp;
+ u16 opc;
+
+ if (copy_from_kernel_nofault(&insn, (void *)rec->ip, sizeof(insn)))
+ return ERR_PTR(-EFAULT);
+ disp = (s64)insn.disp * 2;
+ trampoline = (void *)(rec->ip + disp);
+ if (get_kernel_nofault(opc, &trampoline->brasl_opc))
+ return ERR_PTR(-EFAULT);
+ if (opc != 0xc015)
+ return ERR_PTR(-EINVAL);
+ return trampoline;
+}
+
int ftrace_modify_call(struct dyn_ftrace *rec, unsigned long old_addr,
unsigned long addr)
{
+ struct ftrace_hotpatch_trampoline *trampoline;
+ u64 old;
+
+ trampoline = ftrace_get_trampoline(rec);
+ if (IS_ERR(trampoline))
+ return PTR_ERR(trampoline);
+ if (get_kernel_nofault(old, &trampoline->interceptor))
+ return -EFAULT;
+ if (old != old_addr)
+ return -EINVAL;
+ s390_kernel_write(&trampoline->interceptor, &addr, sizeof(addr));
return 0;
}
@@ -188,6 +217,12 @@ static void brcl_enable(void *brcl)
int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
{
+ struct ftrace_hotpatch_trampoline *trampoline;
+
+ trampoline = ftrace_get_trampoline(rec);
+ if (IS_ERR(trampoline))
+ return PTR_ERR(trampoline);
+ s390_kernel_write(&trampoline->interceptor, &addr, sizeof(addr));
brcl_enable((void *)rec->ip);
return 0;
}
@@ -291,7 +326,7 @@ void kprobe_ftrace_handler(unsigned long ip, unsigned long parent_ip,
regs = ftrace_get_regs(fregs);
p = get_kprobe((kprobe_opcode_t *)ip);
- if (unlikely(!p) || kprobe_disabled(p))
+ if (!regs || unlikely(!p) || kprobe_disabled(p))
goto out;
if (kprobe_running()) {
diff --git a/arch/s390/kernel/mcount.S b/arch/s390/kernel/mcount.S
index 39bcc0e39a10..a24177dcd12a 100644
--- a/arch/s390/kernel/mcount.S
+++ b/arch/s390/kernel/mcount.S
@@ -27,6 +27,7 @@ ENDPROC(ftrace_stub)
#define STACK_PTREGS_GPRS (STACK_PTREGS + __PT_GPRS)
#define STACK_PTREGS_PSW (STACK_PTREGS + __PT_PSW)
#define STACK_PTREGS_ORIG_GPR2 (STACK_PTREGS + __PT_ORIG_GPR2)
+#define STACK_PTREGS_FLAGS (STACK_PTREGS + __PT_FLAGS)
#ifdef __PACK_STACK
/* allocate just enough for r14, r15 and backchain */
#define TRACED_FUNC_FRAME_SIZE 24
@@ -57,6 +58,14 @@ ENDPROC(ftrace_stub)
.if \allregs == 1
stg %r14,(STACK_PTREGS_PSW)(%r15)
stosm (STACK_PTREGS_PSW)(%r15),0
+#ifdef CONFIG_HAVE_MARCH_Z10_FEATURES
+ mvghi STACK_PTREGS_FLAGS(%r15),_PIF_FTRACE_FULL_REGS
+#else
+ lghi %r14,_PIF_FTRACE_FULL_REGS
+ stg %r14,STACK_PTREGS_FLAGS(%r15)
+#endif
+ .else
+ xc STACK_PTREGS_FLAGS(8,%r15),STACK_PTREGS_FLAGS(%r15)
.endif
lg %r14,(__SF_GPRS+8*8)(%r1) # restore original return address
diff --git a/arch/s390/kernel/module.c b/arch/s390/kernel/module.c
index d52d85367bf7..b032e556eeb7 100644
--- a/arch/s390/kernel/module.c
+++ b/arch/s390/kernel/module.c
@@ -33,7 +33,7 @@
#define DEBUGP(fmt , ...)
#endif
-#define PLT_ENTRY_SIZE 20
+#define PLT_ENTRY_SIZE 22
void *module_alloc(unsigned long size)
{
@@ -341,27 +341,26 @@ static int apply_rela(Elf_Rela *rela, Elf_Addr base, Elf_Sym *symtab,
case R_390_PLTOFF32: /* 32 bit offset from GOT to PLT. */
case R_390_PLTOFF64: /* 16 bit offset from GOT to PLT. */
if (info->plt_initialized == 0) {
- unsigned int insn[5];
- unsigned int *ip = me->core_layout.base +
- me->arch.plt_offset +
- info->plt_offset;
-
- insn[0] = 0x0d10e310; /* basr 1,0 */
- insn[1] = 0x100a0004; /* lg 1,10(1) */
+ unsigned char insn[PLT_ENTRY_SIZE];
+ char *plt_base;
+ char *ip;
+
+ plt_base = me->core_layout.base + me->arch.plt_offset;
+ ip = plt_base + info->plt_offset;
+ *(int *)insn = 0x0d10e310; /* basr 1,0 */
+ *(int *)&insn[4] = 0x100c0004; /* lg 1,12(1) */
if (IS_ENABLED(CONFIG_EXPOLINE) && !nospec_disable) {
- unsigned int *ij;
- ij = me->core_layout.base +
- me->arch.plt_offset +
- me->arch.plt_size - PLT_ENTRY_SIZE;
- insn[2] = 0xa7f40000 + /* j __jump_r1 */
- (unsigned int)(u16)
- (((unsigned long) ij - 8 -
- (unsigned long) ip) / 2);
+ char *jump_r1;
+
+ jump_r1 = plt_base + me->arch.plt_size -
+ PLT_ENTRY_SIZE;
+ /* brcl 0xf,__jump_r1 */
+ *(short *)&insn[8] = 0xc0f4;
+ *(int *)&insn[10] = (jump_r1 - (ip + 8)) / 2;
} else {
- insn[2] = 0x07f10000; /* br %r1 */
+ *(int *)&insn[8] = 0x07f10000; /* br %r1 */
}
- insn[3] = (unsigned int) (val >> 32);
- insn[4] = (unsigned int) val;
+ *(long *)&insn[14] = val;
write(ip, insn, sizeof(insn));
info->plt_initialized = 1;
diff --git a/arch/s390/kernel/nmi.c b/arch/s390/kernel/nmi.c
index 0c9e894913dc..651a51914e34 100644
--- a/arch/s390/kernel/nmi.c
+++ b/arch/s390/kernel/nmi.c
@@ -264,7 +264,14 @@ static int notrace s390_validate_registers(union mci mci, int umode)
/* Validate vector registers */
union ctlreg0 cr0;
- if (!mci.vr) {
+ /*
+ * 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)) {
/*
* Vector registers can't be restored. If the kernel
* currently uses vector registers the system is
@@ -307,11 +314,21 @@ static int notrace s390_validate_registers(union mci mci, int umode)
if (cr2.gse) {
if (!mci.gs) {
/*
- * Guarded storage register can't be restored and
- * the current processes uses guarded storage.
- * It has to be terminated.
+ * 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.
*/
- kill_task = 1;
+ if (!test_cpu_flag(CIF_MCCK_GUEST))
+ kill_task = 1;
} else {
load_gs_cb((struct gs_cb *)mcesa->guarded_storage_save_area);
}
diff --git a/arch/s390/kernel/numa.c b/arch/s390/kernel/numa.c
index 51c5a9f6e525..23ab9f02f278 100644
--- a/arch/s390/kernel/numa.c
+++ b/arch/s390/kernel/numa.c
@@ -33,10 +33,3 @@ void __init numa_setup(void)
NODE_DATA(0)->node_spanned_pages = memblock_end_of_DRAM() >> PAGE_SHIFT;
NODE_DATA(0)->node_id = 0;
}
-
-static int __init numa_init_late(void)
-{
- register_one_node(0);
- return 0;
-}
-arch_initcall(numa_init_late);
diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c
index f2c25d113e7b..05327be3a982 100644
--- a/arch/s390/kernel/setup.c
+++ b/arch/s390/kernel/setup.c
@@ -800,6 +800,8 @@ static void __init check_initrd(void)
static void __init reserve_kernel(void)
{
memblock_reserve(0, STARTUP_NORMAL_OFFSET);
+ memblock_reserve(OLDMEM_BASE, sizeof(unsigned long));
+ memblock_reserve(OLDMEM_SIZE, sizeof(unsigned long));
memblock_reserve(__amode31_base, __eamode31 - __samode31);
memblock_reserve(__pa(sclp_early_sccb), EXT_SCCB_READ_SCP);
memblock_reserve(__pa(_stext), _end - _stext);
diff --git a/arch/s390/kvm/gaccess.c b/arch/s390/kvm/gaccess.c
index 4460808c3b9a..d53a183c2005 100644
--- a/arch/s390/kvm/gaccess.c
+++ b/arch/s390/kvm/gaccess.c
@@ -10,6 +10,7 @@
#include <linux/mm_types.h>
#include <linux/err.h>
#include <linux/pgtable.h>
+#include <linux/bitfield.h>
#include <asm/gmap.h>
#include "kvm-s390.h"
@@ -794,6 +795,108 @@ static int low_address_protection_enabled(struct kvm_vcpu *vcpu,
return 1;
}
+static int vm_check_access_key(struct kvm *kvm, u8 access_key,
+ enum gacc_mode mode, gpa_t gpa)
+{
+ u8 storage_key, access_control;
+ bool fetch_protected;
+ unsigned long hva;
+ int r;
+
+ if (access_key == 0)
+ return 0;
+
+ hva = gfn_to_hva(kvm, gpa_to_gfn(gpa));
+ if (kvm_is_error_hva(hva))
+ return PGM_ADDRESSING;
+
+ mmap_read_lock(current->mm);
+ r = get_guest_storage_key(current->mm, hva, &storage_key);
+ mmap_read_unlock(current->mm);
+ if (r)
+ return r;
+ access_control = FIELD_GET(_PAGE_ACC_BITS, storage_key);
+ if (access_control == access_key)
+ return 0;
+ fetch_protected = storage_key & _PAGE_FP_BIT;
+ if ((mode == GACC_FETCH || mode == GACC_IFETCH) && !fetch_protected)
+ return 0;
+ return PGM_PROTECTION;
+}
+
+static bool fetch_prot_override_applicable(struct kvm_vcpu *vcpu, enum gacc_mode mode,
+ union asce asce)
+{
+ psw_t *psw = &vcpu->arch.sie_block->gpsw;
+ unsigned long override;
+
+ if (mode == GACC_FETCH || mode == GACC_IFETCH) {
+ /* check if fetch protection override enabled */
+ override = vcpu->arch.sie_block->gcr[0];
+ override &= CR0_FETCH_PROTECTION_OVERRIDE;
+ /* not applicable if subject to DAT && private space */
+ override = override && !(psw_bits(*psw).dat && asce.p);
+ return override;
+ }
+ return false;
+}
+
+static bool fetch_prot_override_applies(unsigned long ga, unsigned int len)
+{
+ return ga < 2048 && ga + len <= 2048;
+}
+
+static bool storage_prot_override_applicable(struct kvm_vcpu *vcpu)
+{
+ /* check if storage protection override enabled */
+ return vcpu->arch.sie_block->gcr[0] & CR0_STORAGE_PROTECTION_OVERRIDE;
+}
+
+static bool storage_prot_override_applies(u8 access_control)
+{
+ /* matches special storage protection override key (9) -> allow */
+ return access_control == PAGE_SPO_ACC;
+}
+
+static int vcpu_check_access_key(struct kvm_vcpu *vcpu, u8 access_key,
+ enum gacc_mode mode, union asce asce, gpa_t gpa,
+ unsigned long ga, unsigned int len)
+{
+ u8 storage_key, access_control;
+ unsigned long hva;
+ int r;
+
+ /* access key 0 matches any storage key -> allow */
+ if (access_key == 0)
+ return 0;
+ /*
+ * caller needs to ensure that gfn is accessible, so we can
+ * assume that this cannot fail
+ */
+ hva = gfn_to_hva(vcpu->kvm, gpa_to_gfn(gpa));
+ mmap_read_lock(current->mm);
+ r = get_guest_storage_key(current->mm, hva, &storage_key);
+ mmap_read_unlock(current->mm);
+ if (r)
+ return r;
+ access_control = FIELD_GET(_PAGE_ACC_BITS, storage_key);
+ /* access key matches storage key -> allow */
+ if (access_control == access_key)
+ return 0;
+ if (mode == GACC_FETCH || mode == GACC_IFETCH) {
+ /* it is a fetch and fetch protection is off -> allow */
+ if (!(storage_key & _PAGE_FP_BIT))
+ return 0;
+ if (fetch_prot_override_applicable(vcpu, mode, asce) &&
+ fetch_prot_override_applies(ga, len))
+ return 0;
+ }
+ if (storage_prot_override_applicable(vcpu) &&
+ storage_prot_override_applies(access_control))
+ return 0;
+ return PGM_PROTECTION;
+}
+
/**
* guest_range_to_gpas() - Calculate guest physical addresses of page fragments
* covering a logical range
@@ -804,6 +907,7 @@ static int low_address_protection_enabled(struct kvm_vcpu *vcpu,
* @len: length of range in bytes
* @asce: address-space-control element to use for translation
* @mode: access mode
+ * @access_key: access key to mach the range's storage keys against
*
* Translate a logical range to a series of guest absolute addresses,
* such that the concatenation of page fragments starting at each gpa make up
@@ -830,7 +934,8 @@ static int low_address_protection_enabled(struct kvm_vcpu *vcpu,
*/
static int guest_range_to_gpas(struct kvm_vcpu *vcpu, unsigned long ga, u8 ar,
unsigned long *gpas, unsigned long len,
- const union asce asce, enum gacc_mode mode)
+ const union asce asce, enum gacc_mode mode,
+ u8 access_key)
{
psw_t *psw = &vcpu->arch.sie_block->gpsw;
unsigned int offset = offset_in_page(ga);
@@ -857,6 +962,10 @@ static int guest_range_to_gpas(struct kvm_vcpu *vcpu, unsigned long ga, u8 ar,
}
if (rc)
return trans_exc(vcpu, rc, ga, ar, mode, prot);
+ rc = vcpu_check_access_key(vcpu, access_key, mode, asce, gpa, ga,
+ fragment_len);
+ if (rc)
+ return trans_exc(vcpu, rc, ga, ar, mode, PROT_TYPE_KEYC);
if (gpas)
*gpas++ = gpa;
offset = 0;
@@ -880,16 +989,74 @@ static int access_guest_page(struct kvm *kvm, enum gacc_mode mode, gpa_t gpa,
return rc;
}
-int access_guest(struct kvm_vcpu *vcpu, unsigned long ga, u8 ar, void *data,
- unsigned long len, enum gacc_mode mode)
+static int
+access_guest_page_with_key(struct kvm *kvm, enum gacc_mode mode, gpa_t gpa,
+ void *data, unsigned int len, u8 access_key)
+{
+ struct kvm_memory_slot *slot;
+ bool writable;
+ gfn_t gfn;
+ hva_t hva;
+ int rc;
+
+ gfn = gpa >> PAGE_SHIFT;
+ slot = gfn_to_memslot(kvm, gfn);
+ hva = gfn_to_hva_memslot_prot(slot, gfn, &writable);
+
+ if (kvm_is_error_hva(hva))
+ return PGM_ADDRESSING;
+ /*
+ * Check if it's a ro memslot, even tho that can't occur (they're unsupported).
+ * Don't try to actually handle that case.
+ */
+ if (!writable && mode == GACC_STORE)
+ return -EOPNOTSUPP;
+ hva += offset_in_page(gpa);
+ if (mode == GACC_STORE)
+ rc = copy_to_user_key((void __user *)hva, data, len, access_key);
+ else
+ rc = copy_from_user_key(data, (void __user *)hva, len, access_key);
+ if (rc)
+ return PGM_PROTECTION;
+ if (mode == GACC_STORE)
+ mark_page_dirty_in_slot(kvm, slot, gfn);
+ return 0;
+}
+
+int access_guest_abs_with_key(struct kvm *kvm, gpa_t gpa, void *data,
+ unsigned long len, enum gacc_mode mode, u8 access_key)
+{
+ int offset = offset_in_page(gpa);
+ int fragment_len;
+ int rc;
+
+ while (min(PAGE_SIZE - offset, len) > 0) {
+ fragment_len = min(PAGE_SIZE - offset, len);
+ rc = access_guest_page_with_key(kvm, mode, gpa, data, fragment_len, access_key);
+ if (rc)
+ return rc;
+ offset = 0;
+ len -= fragment_len;
+ data += fragment_len;
+ gpa += fragment_len;
+ }
+ return 0;
+}
+
+int access_guest_with_key(struct kvm_vcpu *vcpu, unsigned long ga, u8 ar,
+ void *data, unsigned long len, enum gacc_mode mode,
+ u8 access_key)
{
psw_t *psw = &vcpu->arch.sie_block->gpsw;
unsigned long nr_pages, idx;
unsigned long gpa_array[2];
unsigned int fragment_len;
unsigned long *gpas;
+ enum prot_type prot;
int need_ipte_lock;
union asce asce;
+ bool try_storage_prot_override;
+ bool try_fetch_prot_override;
int rc;
if (!len)
@@ -904,16 +1071,47 @@ int access_guest(struct kvm_vcpu *vcpu, unsigned long ga, u8 ar, void *data,
gpas = vmalloc(array_size(nr_pages, sizeof(unsigned long)));
if (!gpas)
return -ENOMEM;
+ try_fetch_prot_override = fetch_prot_override_applicable(vcpu, mode, asce);
+ try_storage_prot_override = storage_prot_override_applicable(vcpu);
need_ipte_lock = psw_bits(*psw).dat && !asce.r;
if (need_ipte_lock)
ipte_lock(vcpu);
- rc = guest_range_to_gpas(vcpu, ga, ar, gpas, len, asce, mode);
- for (idx = 0; idx < nr_pages && !rc; idx++) {
+ /*
+ * Since we do the access further down ultimately via a move instruction
+ * that does key checking and returns an error in case of a protection
+ * violation, we don't need to do the check during address translation.
+ * Skip it by passing access key 0, which matches any storage key,
+ * obviating the need for any further checks. As a result the check is
+ * handled entirely in hardware on access, we only need to take care to
+ * forego key protection checking if fetch protection override applies or
+ * retry with the special key 9 in case of storage protection override.
+ */
+ rc = guest_range_to_gpas(vcpu, ga, ar, gpas, len, asce, mode, 0);
+ if (rc)
+ goto out_unlock;
+ for (idx = 0; idx < nr_pages; idx++) {
fragment_len = min(PAGE_SIZE - offset_in_page(gpas[idx]), len);
- rc = access_guest_page(vcpu->kvm, mode, gpas[idx], data, fragment_len);
+ if (try_fetch_prot_override && fetch_prot_override_applies(ga, fragment_len)) {
+ rc = access_guest_page(vcpu->kvm, mode, gpas[idx],
+ data, fragment_len);
+ } else {
+ rc = access_guest_page_with_key(vcpu->kvm, mode, gpas[idx],
+ data, fragment_len, access_key);
+ }
+ if (rc == PGM_PROTECTION && try_storage_prot_override)
+ rc = access_guest_page_with_key(vcpu->kvm, mode, gpas[idx],
+ data, fragment_len, PAGE_SPO_ACC);
+ if (rc == PGM_PROTECTION)
+ prot = PROT_TYPE_KEYC;
+ if (rc)
+ break;
len -= fragment_len;
data += fragment_len;
+ ga = kvm_s390_logical_to_effective(vcpu, ga + fragment_len);
}
+ if (rc > 0)
+ rc = trans_exc(vcpu, rc, ga, ar, mode, prot);
+out_unlock:
if (need_ipte_lock)
ipte_unlock(vcpu);
if (nr_pages > ARRAY_SIZE(gpa_array))
@@ -940,12 +1138,13 @@ int access_guest_real(struct kvm_vcpu *vcpu, unsigned long gra,
}
/**
- * guest_translate_address - translate guest logical into guest absolute address
+ * guest_translate_address_with_key - translate guest logical into guest absolute address
* @vcpu: virtual cpu
* @gva: Guest virtual address
* @ar: Access register
* @gpa: Guest physical address
* @mode: Translation access mode
+ * @access_key: access key to mach the storage key with
*
* Parameter semantics are the same as the ones from guest_translate.
* The memory contents at the guest address are not changed.
@@ -953,8 +1152,9 @@ int access_guest_real(struct kvm_vcpu *vcpu, unsigned long gra,
* Note: The IPTE lock is not taken during this function, so the caller
* has to take care of this.
*/
-int guest_translate_address(struct kvm_vcpu *vcpu, unsigned long gva, u8 ar,
- unsigned long *gpa, enum gacc_mode mode)
+int guest_translate_address_with_key(struct kvm_vcpu *vcpu, unsigned long gva, u8 ar,
+ unsigned long *gpa, enum gacc_mode mode,
+ u8 access_key)
{
union asce asce;
int rc;
@@ -963,7 +1163,8 @@ int guest_translate_address(struct kvm_vcpu *vcpu, unsigned long gva, u8 ar,
rc = get_vcpu_asce(vcpu, &asce, gva, ar, mode);
if (rc)
return rc;
- return guest_range_to_gpas(vcpu, gva, ar, gpa, 1, asce, mode);
+ return guest_range_to_gpas(vcpu, gva, ar, gpa, 1, asce, mode,
+ access_key);
}
/**
@@ -973,9 +1174,10 @@ int guest_translate_address(struct kvm_vcpu *vcpu, unsigned long gva, u8 ar,
* @ar: Access register
* @length: Length of test range
* @mode: Translation access mode
+ * @access_key: access key to mach the storage keys with
*/
int check_gva_range(struct kvm_vcpu *vcpu, unsigned long gva, u8 ar,
- unsigned long length, enum gacc_mode mode)
+ unsigned long length, enum gacc_mode mode, u8 access_key)
{
union asce asce;
int rc = 0;
@@ -984,13 +1186,37 @@ int check_gva_range(struct kvm_vcpu *vcpu, unsigned long gva, u8 ar,
if (rc)
return rc;
ipte_lock(vcpu);
- rc = guest_range_to_gpas(vcpu, gva, ar, NULL, length, asce, mode);
+ rc = guest_range_to_gpas(vcpu, gva, ar, NULL, length, asce, mode,
+ access_key);
ipte_unlock(vcpu);
return rc;
}
/**
+ * check_gpa_range - test a range of guest physical addresses for accessibility
+ * @kvm: virtual machine instance
+ * @gpa: guest physical address
+ * @length: length of test range
+ * @mode: access mode to test, relevant for storage keys
+ * @access_key: access key to mach the storage keys with
+ */
+int check_gpa_range(struct kvm *kvm, unsigned long gpa, unsigned long length,
+ enum gacc_mode mode, u8 access_key)
+{
+ unsigned int fragment_len;
+ int rc = 0;
+
+ while (length && !rc) {
+ fragment_len = min(PAGE_SIZE - offset_in_page(gpa), length);
+ rc = vm_check_access_key(kvm, access_key, mode, gpa);
+ length -= fragment_len;
+ gpa += fragment_len;
+ }
+ return rc;
+}
+
+/**
* kvm_s390_check_low_addr_prot_real - check for low-address protection
* @vcpu: virtual cpu
* @gra: Guest real address
diff --git a/arch/s390/kvm/gaccess.h b/arch/s390/kvm/gaccess.h
index 7c72a5e3449f..1124ff282012 100644
--- a/arch/s390/kvm/gaccess.h
+++ b/arch/s390/kvm/gaccess.h
@@ -186,24 +186,34 @@ enum gacc_mode {
GACC_IFETCH,
};
-int guest_translate_address(struct kvm_vcpu *vcpu, unsigned long gva,
- u8 ar, unsigned long *gpa, enum gacc_mode mode);
+int guest_translate_address_with_key(struct kvm_vcpu *vcpu, unsigned long gva, u8 ar,
+ unsigned long *gpa, enum gacc_mode mode,
+ u8 access_key);
+
int check_gva_range(struct kvm_vcpu *vcpu, unsigned long gva, u8 ar,
- unsigned long length, enum gacc_mode mode);
+ unsigned long length, enum gacc_mode mode, u8 access_key);
+
+int check_gpa_range(struct kvm *kvm, unsigned long gpa, unsigned long length,
+ enum gacc_mode mode, u8 access_key);
+
+int access_guest_abs_with_key(struct kvm *kvm, gpa_t gpa, void *data,
+ unsigned long len, enum gacc_mode mode, u8 access_key);
-int access_guest(struct kvm_vcpu *vcpu, unsigned long ga, u8 ar, void *data,
- unsigned long len, enum gacc_mode mode);
+int access_guest_with_key(struct kvm_vcpu *vcpu, unsigned long ga, u8 ar,
+ void *data, unsigned long len, enum gacc_mode mode,
+ u8 access_key);
int access_guest_real(struct kvm_vcpu *vcpu, unsigned long gra,
void *data, unsigned long len, enum gacc_mode mode);
/**
- * write_guest - copy data from kernel space to guest space
+ * write_guest_with_key - copy data from kernel space to guest space
* @vcpu: virtual cpu
* @ga: guest address
* @ar: access register
* @data: source address in kernel space
* @len: number of bytes to copy
+ * @access_key: access key the storage key needs to match
*
* Copy @len bytes from @data (kernel space) to @ga (guest address).
* In order to copy data to guest space the PSW of the vcpu is inspected:
@@ -214,8 +224,8 @@ int access_guest_real(struct kvm_vcpu *vcpu, unsigned long gra,
* The addressing mode of the PSW is also inspected, so that address wrap
* around is taken into account for 24-, 31- and 64-bit addressing mode,
* if the to be copied data crosses page boundaries in guest address space.
- * In addition also low address and DAT protection are inspected before
- * copying any data (key protection is currently not implemented).
+ * In addition low address, DAT and key protection checks are performed before
+ * copying any data.
*
* This function modifies the 'struct kvm_s390_pgm_info pgm' member of @vcpu.
* In case of an access exception (e.g. protection exception) pgm will contain
@@ -243,10 +253,53 @@ int access_guest_real(struct kvm_vcpu *vcpu, unsigned long gra,
* if data has been changed in guest space in case of an exception.
*/
static inline __must_check
+int write_guest_with_key(struct kvm_vcpu *vcpu, unsigned long ga, u8 ar,
+ void *data, unsigned long len, u8 access_key)
+{
+ return access_guest_with_key(vcpu, ga, ar, data, len, GACC_STORE,
+ access_key);
+}
+
+/**
+ * write_guest - copy data from kernel space to guest space
+ * @vcpu: virtual cpu
+ * @ga: guest address
+ * @ar: access register
+ * @data: source address in kernel space
+ * @len: number of bytes to copy
+ *
+ * The behaviour of write_guest is identical to write_guest_with_key, except
+ * that the PSW access key is used instead of an explicit argument.
+ */
+static inline __must_check
int write_guest(struct kvm_vcpu *vcpu, unsigned long ga, u8 ar, void *data,
unsigned long len)
{
- return access_guest(vcpu, ga, ar, data, len, GACC_STORE);
+ u8 access_key = psw_bits(vcpu->arch.sie_block->gpsw).key;
+
+ return write_guest_with_key(vcpu, ga, ar, data, len, access_key);
+}
+
+/**
+ * read_guest_with_key - copy data from guest space to kernel space
+ * @vcpu: virtual cpu
+ * @ga: guest address
+ * @ar: access register
+ * @data: destination address in kernel space
+ * @len: number of bytes to copy
+ * @access_key: access key the storage key needs to match
+ *
+ * Copy @len bytes from @ga (guest address) to @data (kernel space).
+ *
+ * The behaviour of read_guest_with_key is identical to write_guest_with_key,
+ * except that data will be copied from guest space to kernel space.
+ */
+static inline __must_check
+int read_guest_with_key(struct kvm_vcpu *vcpu, unsigned long ga, u8 ar,
+ void *data, unsigned long len, u8 access_key)
+{
+ return access_guest_with_key(vcpu, ga, ar, data, len, GACC_FETCH,
+ access_key);
}
/**
@@ -259,14 +312,16 @@ int write_guest(struct kvm_vcpu *vcpu, unsigned long ga, u8 ar, void *data,
*
* Copy @len bytes from @ga (guest address) to @data (kernel space).
*
- * The behaviour of read_guest is identical to write_guest, except that
- * data will be copied from guest space to kernel space.
+ * The behaviour of read_guest is identical to read_guest_with_key, except
+ * that the PSW access key is used instead of an explicit argument.
*/
static inline __must_check
int read_guest(struct kvm_vcpu *vcpu, unsigned long ga, u8 ar, void *data,
unsigned long len)
{
- return access_guest(vcpu, ga, ar, data, len, GACC_FETCH);
+ u8 access_key = psw_bits(vcpu->arch.sie_block->gpsw).key;
+
+ return read_guest_with_key(vcpu, ga, ar, data, len, access_key);
}
/**
@@ -287,7 +342,10 @@ static inline __must_check
int read_guest_instr(struct kvm_vcpu *vcpu, unsigned long ga, void *data,
unsigned long len)
{
- return access_guest(vcpu, ga, 0, data, len, GACC_IFETCH);
+ u8 access_key = psw_bits(vcpu->arch.sie_block->gpsw).key;
+
+ return access_guest_with_key(vcpu, ga, 0, data, len, GACC_IFETCH,
+ access_key);
}
/**
diff --git a/arch/s390/kvm/intercept.c b/arch/s390/kvm/intercept.c
index d07ff646d844..8bd42a20d924 100644
--- a/arch/s390/kvm/intercept.c
+++ b/arch/s390/kvm/intercept.c
@@ -331,18 +331,18 @@ static int handle_mvpg_pei(struct kvm_vcpu *vcpu)
kvm_s390_get_regs_rre(vcpu, &reg1, &reg2);
- /* Make sure that the source is paged-in */
- rc = guest_translate_address(vcpu, vcpu->run->s.regs.gprs[reg2],
- reg2, &srcaddr, GACC_FETCH);
+ /* Ensure that the source is paged-in, no actual access -> no key checking */
+ rc = guest_translate_address_with_key(vcpu, vcpu->run->s.regs.gprs[reg2],
+ reg2, &srcaddr, GACC_FETCH, 0);
if (rc)
return kvm_s390_inject_prog_cond(vcpu, rc);
rc = kvm_arch_fault_in_page(vcpu, srcaddr, 0);
if (rc != 0)
return rc;
- /* Make sure that the destination is paged-in */
- rc = guest_translate_address(vcpu, vcpu->run->s.regs.gprs[reg1],
- reg1, &dstaddr, GACC_STORE);
+ /* Ensure that the source is paged-in, no actual access -> no key checking */
+ rc = guest_translate_address_with_key(vcpu, vcpu->run->s.regs.gprs[reg1],
+ reg1, &dstaddr, GACC_STORE, 0);
if (rc)
return kvm_s390_inject_prog_cond(vcpu, rc);
rc = kvm_arch_fault_in_page(vcpu, dstaddr, 1);
diff --git a/arch/s390/kvm/interrupt.c b/arch/s390/kvm/interrupt.c
index db933c252dbc..9b30beac904d 100644
--- a/arch/s390/kvm/interrupt.c
+++ b/arch/s390/kvm/interrupt.c
@@ -1901,13 +1901,12 @@ static int __inject_io(struct kvm *kvm, struct kvm_s390_interrupt_info *inti)
isc = int_word_to_isc(inti->io.io_int_word);
/*
- * Do not make use of gisa in protected mode. We do not use the lock
- * checking variant as this is just a performance optimization and we
- * do not hold the lock here. This is ok as the code will pick
- * interrupts from both "lists" for delivery.
+ * We do not use the lock checking variant as this is just a
+ * performance optimization and we do not hold the lock here.
+ * This is ok as the code will pick interrupts from both "lists"
+ * for delivery.
*/
- if (!kvm_s390_pv_get_handle(kvm) &&
- gi->origin && inti->type & KVM_S390_INT_IO_AI_MASK) {
+ if (gi->origin && inti->type & KVM_S390_INT_IO_AI_MASK) {
VM_EVENT(kvm, 4, "%s isc %1u", "inject: I/O (AI/gisa)", isc);
gisa_set_ipm_gisc(gi->origin, isc);
kfree(inti);
@@ -3171,9 +3170,33 @@ void kvm_s390_gisa_init(struct kvm *kvm)
VM_EVENT(kvm, 3, "gisa 0x%pK initialized", gi->origin);
}
+void kvm_s390_gisa_enable(struct kvm *kvm)
+{
+ struct kvm_s390_gisa_interrupt *gi = &kvm->arch.gisa_int;
+ struct kvm_vcpu *vcpu;
+ unsigned long i;
+ u32 gisa_desc;
+
+ if (gi->origin)
+ return;
+ kvm_s390_gisa_init(kvm);
+ gisa_desc = kvm_s390_get_gisa_desc(kvm);
+ if (!gisa_desc)
+ return;
+ kvm_for_each_vcpu(i, vcpu, kvm) {
+ mutex_lock(&vcpu->mutex);
+ vcpu->arch.sie_block->gd = gisa_desc;
+ vcpu->arch.sie_block->eca |= ECA_AIV;
+ VCPU_EVENT(vcpu, 3, "AIV gisa format-%u enabled for cpu %03u",
+ vcpu->arch.sie_block->gd & 0x3, vcpu->vcpu_id);
+ mutex_unlock(&vcpu->mutex);
+ }
+}
+
void kvm_s390_gisa_destroy(struct kvm *kvm)
{
struct kvm_s390_gisa_interrupt *gi = &kvm->arch.gisa_int;
+ struct kvm_s390_gisa *gisa = gi->origin;
if (!gi->origin)
return;
@@ -3184,6 +3207,25 @@ void kvm_s390_gisa_destroy(struct kvm *kvm)
cpu_relax();
hrtimer_cancel(&gi->timer);
gi->origin = NULL;
+ VM_EVENT(kvm, 3, "gisa 0x%pK destroyed", gisa);
+}
+
+void kvm_s390_gisa_disable(struct kvm *kvm)
+{
+ struct kvm_s390_gisa_interrupt *gi = &kvm->arch.gisa_int;
+ struct kvm_vcpu *vcpu;
+ unsigned long i;
+
+ if (!gi->origin)
+ return;
+ kvm_for_each_vcpu(i, vcpu, kvm) {
+ mutex_lock(&vcpu->mutex);
+ vcpu->arch.sie_block->eca &= ~ECA_AIV;
+ vcpu->arch.sie_block->gd = 0U;
+ mutex_unlock(&vcpu->mutex);
+ VCPU_EVENT(vcpu, 3, "AIV disabled for cpu %03u", vcpu->vcpu_id);
+ }
+ kvm_s390_gisa_destroy(kvm);
}
/**
diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c
index 577f1ead6a51..ca96f84db2cc 100644
--- a/arch/s390/kvm/kvm-s390.c
+++ b/arch/s390/kvm/kvm-s390.c
@@ -564,6 +564,7 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
case KVM_CAP_S390_VCPU_RESETS:
case KVM_CAP_SET_GUEST_DEBUG:
case KVM_CAP_S390_DIAG318:
+ case KVM_CAP_S390_MEM_OP_EXTENSION:
r = 1;
break;
case KVM_CAP_SET_GUEST_DEBUG2:
@@ -2194,6 +2195,9 @@ static int kvm_s390_cpus_from_pv(struct kvm *kvm, u16 *rcp, u16 *rrcp)
}
mutex_unlock(&vcpu->mutex);
}
+ /* Ensure that we re-enable gisa if the non-PV guest used it but the PV guest did not. */
+ if (use_gisa)
+ kvm_s390_gisa_enable(kvm);
return ret;
}
@@ -2205,6 +2209,10 @@ static int kvm_s390_cpus_to_pv(struct kvm *kvm, u16 *rc, u16 *rrc)
struct kvm_vcpu *vcpu;
+ /* Disable the GISA if the ultravisor does not support AIV. */
+ if (!test_bit_inv(BIT_UV_FEAT_AIV, &uv_info.uv_feature_indications))
+ kvm_s390_gisa_disable(kvm);
+
kvm_for_each_vcpu(i, vcpu, kvm) {
mutex_lock(&vcpu->mutex);
r = kvm_s390_pv_create_cpu(vcpu, rc, rrc);
@@ -2359,6 +2367,83 @@ static int kvm_s390_handle_pv(struct kvm *kvm, struct kvm_pv_cmd *cmd)
return r;
}
+static bool access_key_invalid(u8 access_key)
+{
+ return access_key > 0xf;
+}
+
+static int kvm_s390_vm_mem_op(struct kvm *kvm, struct kvm_s390_mem_op *mop)
+{
+ void __user *uaddr = (void __user *)mop->buf;
+ u64 supported_flags;
+ void *tmpbuf = NULL;
+ int r, srcu_idx;
+
+ supported_flags = KVM_S390_MEMOP_F_SKEY_PROTECTION
+ | KVM_S390_MEMOP_F_CHECK_ONLY;
+ if (mop->flags & ~supported_flags || !mop->size)
+ return -EINVAL;
+ if (mop->size > MEM_OP_MAX_SIZE)
+ return -E2BIG;
+ if (kvm_s390_pv_is_protected(kvm))
+ return -EINVAL;
+ if (mop->flags & KVM_S390_MEMOP_F_SKEY_PROTECTION) {
+ if (access_key_invalid(mop->key))
+ return -EINVAL;
+ } else {
+ mop->key = 0;
+ }
+ if (!(mop->flags & KVM_S390_MEMOP_F_CHECK_ONLY)) {
+ tmpbuf = vmalloc(mop->size);
+ if (!tmpbuf)
+ return -ENOMEM;
+ }
+
+ srcu_idx = srcu_read_lock(&kvm->srcu);
+
+ if (kvm_is_error_gpa(kvm, mop->gaddr)) {
+ r = PGM_ADDRESSING;
+ goto out_unlock;
+ }
+
+ switch (mop->op) {
+ case KVM_S390_MEMOP_ABSOLUTE_READ: {
+ if (mop->flags & KVM_S390_MEMOP_F_CHECK_ONLY) {
+ r = check_gpa_range(kvm, mop->gaddr, mop->size, GACC_FETCH, mop->key);
+ } else {
+ r = access_guest_abs_with_key(kvm, mop->gaddr, tmpbuf,
+ mop->size, GACC_FETCH, mop->key);
+ if (r == 0) {
+ if (copy_to_user(uaddr, tmpbuf, mop->size))
+ r = -EFAULT;
+ }
+ }
+ break;
+ }
+ case KVM_S390_MEMOP_ABSOLUTE_WRITE: {
+ if (mop->flags & KVM_S390_MEMOP_F_CHECK_ONLY) {
+ r = check_gpa_range(kvm, mop->gaddr, mop->size, GACC_STORE, mop->key);
+ } else {
+ if (copy_from_user(tmpbuf, uaddr, mop->size)) {
+ r = -EFAULT;
+ break;
+ }
+ r = access_guest_abs_with_key(kvm, mop->gaddr, tmpbuf,
+ mop->size, GACC_STORE, mop->key);
+ }
+ break;
+ }
+ default:
+ r = -EINVAL;
+ }
+
+out_unlock:
+ srcu_read_unlock(&kvm->srcu, srcu_idx);
+
+ vfree(tmpbuf);
+ return r;
+}
+
long kvm_arch_vm_ioctl(struct file *filp,
unsigned int ioctl, unsigned long arg)
{
@@ -2483,6 +2568,15 @@ long kvm_arch_vm_ioctl(struct file *filp,
}
break;
}
+ case KVM_S390_MEM_OP: {
+ struct kvm_s390_mem_op mem_op;
+
+ if (copy_from_user(&mem_op, argp, sizeof(mem_op)) == 0)
+ r = kvm_s390_vm_mem_op(kvm, &mem_op);
+ else
+ r = -EFAULT;
+ break;
+ }
default:
r = -ENOTTY;
}
@@ -3263,9 +3357,7 @@ int kvm_arch_vcpu_create(struct kvm_vcpu *vcpu)
vcpu->arch.sie_block->icpua = vcpu->vcpu_id;
spin_lock_init(&vcpu->arch.local_int.lock);
- vcpu->arch.sie_block->gd = (u32)(u64)vcpu->kvm->arch.gisa_int.origin;
- if (vcpu->arch.sie_block->gd && sclp.has_gisaf)
- vcpu->arch.sie_block->gd |= GISA_FORMAT1;
+ vcpu->arch.sie_block->gd = kvm_s390_get_gisa_desc(vcpu->kvm);
seqcount_init(&vcpu->arch.cputm_seqcount);
vcpu->arch.pfault_token = KVM_S390_PFAULT_TOKEN_INVALID;
@@ -3394,7 +3486,7 @@ static void kvm_gmap_notifier(struct gmap *gmap, unsigned long start,
if (prefix <= end && start <= prefix + 2*PAGE_SIZE - 1) {
VCPU_EVENT(vcpu, 2, "gmap notifier for %lx-%lx",
start, end);
- kvm_s390_sync_request(KVM_REQ_MMU_RELOAD, vcpu);
+ kvm_s390_sync_request(KVM_REQ_REFRESH_GUEST_PREFIX, vcpu);
}
}
}
@@ -3796,19 +3888,19 @@ retry:
if (!kvm_request_pending(vcpu))
return 0;
/*
- * We use MMU_RELOAD just to re-arm the ipte notifier for the
+ * If the guest prefix changed, re-arm the ipte notifier for the
* guest prefix page. gmap_mprotect_notify will wait on the ptl lock.
* This ensures that the ipte instruction for this request has
* already finished. We might race against a second unmapper that
* wants to set the blocking bit. Lets just retry the request loop.
*/
- if (kvm_check_request(KVM_REQ_MMU_RELOAD, vcpu)) {
+ if (kvm_check_request(KVM_REQ_REFRESH_GUEST_PREFIX, vcpu)) {
int rc;
rc = gmap_mprotect_notify(vcpu->arch.gmap,
kvm_s390_get_prefix(vcpu),
PAGE_SIZE * 2, PROT_WRITE);
if (rc) {
- kvm_make_request(KVM_REQ_MMU_RELOAD, vcpu);
+ kvm_make_request(KVM_REQ_REFRESH_GUEST_PREFIX, vcpu);
return rc;
}
goto retry;
@@ -3869,14 +3961,12 @@ retry:
return 0;
}
-void kvm_s390_set_tod_clock(struct kvm *kvm,
- const struct kvm_s390_vm_tod_clock *gtod)
+static void __kvm_s390_set_tod_clock(struct kvm *kvm, const struct kvm_s390_vm_tod_clock *gtod)
{
struct kvm_vcpu *vcpu;
union tod_clock clk;
unsigned long i;
- mutex_lock(&kvm->lock);
preempt_disable();
store_tod_clock_ext(&clk);
@@ -3897,7 +3987,22 @@ void kvm_s390_set_tod_clock(struct kvm *kvm,
kvm_s390_vcpu_unblock_all(kvm);
preempt_enable();
+}
+
+void kvm_s390_set_tod_clock(struct kvm *kvm, const struct kvm_s390_vm_tod_clock *gtod)
+{
+ mutex_lock(&kvm->lock);
+ __kvm_s390_set_tod_clock(kvm, gtod);
+ mutex_unlock(&kvm->lock);
+}
+
+int kvm_s390_try_set_tod_clock(struct kvm *kvm, const struct kvm_s390_vm_tod_clock *gtod)
+{
+ if (!mutex_trylock(&kvm->lock))
+ return 0;
+ __kvm_s390_set_tod_clock(kvm, gtod);
mutex_unlock(&kvm->lock);
+ return 1;
}
/**
@@ -4655,8 +4760,8 @@ static int kvm_vcpu_ioctl_enable_cap(struct kvm_vcpu *vcpu,
return r;
}
-static long kvm_s390_guest_sida_op(struct kvm_vcpu *vcpu,
- struct kvm_s390_mem_op *mop)
+static long kvm_s390_vcpu_sida_op(struct kvm_vcpu *vcpu,
+ struct kvm_s390_mem_op *mop)
{
void __user *uaddr = (void __user *)mop->buf;
int r = 0;
@@ -4667,6 +4772,8 @@ static long kvm_s390_guest_sida_op(struct kvm_vcpu *vcpu,
return -EINVAL;
if (mop->size + mop->sida_offset > sida_size(vcpu->arch.sie_block))
return -E2BIG;
+ if (!kvm_s390_pv_cpu_is_protected(vcpu))
+ return -EINVAL;
switch (mop->op) {
case KVM_S390_MEMOP_SIDA_READ:
@@ -4683,24 +4790,29 @@ static long kvm_s390_guest_sida_op(struct kvm_vcpu *vcpu,
}
return r;
}
-static long kvm_s390_guest_mem_op(struct kvm_vcpu *vcpu,
- struct kvm_s390_mem_op *mop)
+
+static long kvm_s390_vcpu_mem_op(struct kvm_vcpu *vcpu,
+ struct kvm_s390_mem_op *mop)
{
void __user *uaddr = (void __user *)mop->buf;
void *tmpbuf = NULL;
int r = 0;
const u64 supported_flags = KVM_S390_MEMOP_F_INJECT_EXCEPTION
- | KVM_S390_MEMOP_F_CHECK_ONLY;
+ | KVM_S390_MEMOP_F_CHECK_ONLY
+ | KVM_S390_MEMOP_F_SKEY_PROTECTION;
if (mop->flags & ~supported_flags || mop->ar >= NUM_ACRS || !mop->size)
return -EINVAL;
-
if (mop->size > MEM_OP_MAX_SIZE)
return -E2BIG;
-
if (kvm_s390_pv_cpu_is_protected(vcpu))
return -EINVAL;
-
+ if (mop->flags & KVM_S390_MEMOP_F_SKEY_PROTECTION) {
+ if (access_key_invalid(mop->key))
+ return -EINVAL;
+ } else {
+ mop->key = 0;
+ }
if (!(mop->flags & KVM_S390_MEMOP_F_CHECK_ONLY)) {
tmpbuf = vmalloc(mop->size);
if (!tmpbuf)
@@ -4710,11 +4822,12 @@ static long kvm_s390_guest_mem_op(struct kvm_vcpu *vcpu,
switch (mop->op) {
case KVM_S390_MEMOP_LOGICAL_READ:
if (mop->flags & KVM_S390_MEMOP_F_CHECK_ONLY) {
- r = check_gva_range(vcpu, mop->gaddr, mop->ar,
- mop->size, GACC_FETCH);
+ r = check_gva_range(vcpu, mop->gaddr, mop->ar, mop->size,
+ GACC_FETCH, mop->key);
break;
}
- r = read_guest(vcpu, mop->gaddr, mop->ar, tmpbuf, mop->size);
+ r = read_guest_with_key(vcpu, mop->gaddr, mop->ar, tmpbuf,
+ mop->size, mop->key);
if (r == 0) {
if (copy_to_user(uaddr, tmpbuf, mop->size))
r = -EFAULT;
@@ -4722,15 +4835,16 @@ static long kvm_s390_guest_mem_op(struct kvm_vcpu *vcpu,
break;
case KVM_S390_MEMOP_LOGICAL_WRITE:
if (mop->flags & KVM_S390_MEMOP_F_CHECK_ONLY) {
- r = check_gva_range(vcpu, mop->gaddr, mop->ar,
- mop->size, GACC_STORE);
+ r = check_gva_range(vcpu, mop->gaddr, mop->ar, mop->size,
+ GACC_STORE, mop->key);
break;
}
if (copy_from_user(tmpbuf, uaddr, mop->size)) {
r = -EFAULT;
break;
}
- r = write_guest(vcpu, mop->gaddr, mop->ar, tmpbuf, mop->size);
+ r = write_guest_with_key(vcpu, mop->gaddr, mop->ar, tmpbuf,
+ mop->size, mop->key);
break;
}
@@ -4741,8 +4855,8 @@ static long kvm_s390_guest_mem_op(struct kvm_vcpu *vcpu,
return r;
}
-static long kvm_s390_guest_memsida_op(struct kvm_vcpu *vcpu,
- struct kvm_s390_mem_op *mop)
+static long kvm_s390_vcpu_memsida_op(struct kvm_vcpu *vcpu,
+ struct kvm_s390_mem_op *mop)
{
int r, srcu_idx;
@@ -4751,12 +4865,12 @@ static long kvm_s390_guest_memsida_op(struct kvm_vcpu *vcpu,
switch (mop->op) {
case KVM_S390_MEMOP_LOGICAL_READ:
case KVM_S390_MEMOP_LOGICAL_WRITE:
- r = kvm_s390_guest_mem_op(vcpu, mop);
+ r = kvm_s390_vcpu_mem_op(vcpu, mop);
break;
case KVM_S390_MEMOP_SIDA_READ:
case KVM_S390_MEMOP_SIDA_WRITE:
/* we are locked against sida going away by the vcpu->mutex */
- r = kvm_s390_guest_sida_op(vcpu, mop);
+ r = kvm_s390_vcpu_sida_op(vcpu, mop);
break;
default:
r = -EINVAL;
@@ -4919,7 +5033,7 @@ long kvm_arch_vcpu_ioctl(struct file *filp,
struct kvm_s390_mem_op mem_op;
if (copy_from_user(&mem_op, argp, sizeof(mem_op)) == 0)
- r = kvm_s390_guest_memsida_op(vcpu, &mem_op);
+ r = kvm_s390_vcpu_memsida_op(vcpu, &mem_op);
else
r = -EFAULT;
break;
diff --git a/arch/s390/kvm/kvm-s390.h b/arch/s390/kvm/kvm-s390.h
index 098831e815e6..497d52a83c78 100644
--- a/arch/s390/kvm/kvm-s390.h
+++ b/arch/s390/kvm/kvm-s390.h
@@ -105,7 +105,7 @@ static inline void kvm_s390_set_prefix(struct kvm_vcpu *vcpu, u32 prefix)
prefix);
vcpu->arch.sie_block->prefix = prefix >> GUEST_PREFIX_SHIFT;
kvm_make_request(KVM_REQ_TLB_FLUSH, vcpu);
- kvm_make_request(KVM_REQ_MMU_RELOAD, vcpu);
+ kvm_make_request(KVM_REQ_REFRESH_GUEST_PREFIX, vcpu);
}
static inline u64 kvm_s390_get_base_disp_s(struct kvm_vcpu *vcpu, u8 *ar)
@@ -231,6 +231,15 @@ static inline unsigned long kvm_s390_get_gfn_end(struct kvm_memslots *slots)
return ms->base_gfn + ms->npages;
}
+static inline u32 kvm_s390_get_gisa_desc(struct kvm *kvm)
+{
+ u32 gd = (u32)(u64)kvm->arch.gisa_int.origin;
+
+ if (gd && sclp.has_gisaf)
+ gd |= GISA_FORMAT1;
+ return gd;
+}
+
/* implemented in pv.c */
int kvm_s390_pv_destroy_cpu(struct kvm_vcpu *vcpu, u16 *rc, u16 *rrc);
int kvm_s390_pv_create_cpu(struct kvm_vcpu *vcpu, u16 *rc, u16 *rrc);
@@ -349,8 +358,8 @@ int kvm_s390_handle_sigp(struct kvm_vcpu *vcpu);
int kvm_s390_handle_sigp_pei(struct kvm_vcpu *vcpu);
/* implemented in kvm-s390.c */
-void kvm_s390_set_tod_clock(struct kvm *kvm,
- const struct kvm_s390_vm_tod_clock *gtod);
+void kvm_s390_set_tod_clock(struct kvm *kvm, const struct kvm_s390_vm_tod_clock *gtod);
+int kvm_s390_try_set_tod_clock(struct kvm *kvm, const struct kvm_s390_vm_tod_clock *gtod);
long kvm_arch_fault_in_page(struct kvm_vcpu *vcpu, gpa_t gpa, int writable);
int kvm_s390_store_status_unloaded(struct kvm_vcpu *vcpu, unsigned long addr);
int kvm_s390_vcpu_store_status(struct kvm_vcpu *vcpu, unsigned long addr);
@@ -450,6 +459,8 @@ int kvm_s390_get_irq_state(struct kvm_vcpu *vcpu,
void kvm_s390_gisa_init(struct kvm *kvm);
void kvm_s390_gisa_clear(struct kvm *kvm);
void kvm_s390_gisa_destroy(struct kvm *kvm);
+void kvm_s390_gisa_disable(struct kvm *kvm);
+void kvm_s390_gisa_enable(struct kvm *kvm);
int kvm_s390_gib_init(u8 nisc);
void kvm_s390_gib_destroy(void);
diff --git a/arch/s390/kvm/priv.c b/arch/s390/kvm/priv.c
index 417154b314a6..5beb7a4a11b3 100644
--- a/arch/s390/kvm/priv.c
+++ b/arch/s390/kvm/priv.c
@@ -102,7 +102,20 @@ static int handle_set_clock(struct kvm_vcpu *vcpu)
return kvm_s390_inject_prog_cond(vcpu, rc);
VCPU_EVENT(vcpu, 3, "SCK: setting guest TOD to 0x%llx", gtod.tod);
- kvm_s390_set_tod_clock(vcpu->kvm, &gtod);
+ /*
+ * To set the TOD clock the kvm lock must be taken, but the vcpu lock
+ * is already held in handle_set_clock. The usual lock order is the
+ * opposite. As SCK is deprecated and should not be used in several
+ * cases, for example when the multiple epoch facility or TOD clock
+ * steering facility is installed (see Principles of Operation), a
+ * slow path can be used. If the lock can not be taken via try_lock,
+ * the instruction will be retried via -EAGAIN at a later point in
+ * time.
+ */
+ if (!kvm_s390_try_set_tod_clock(vcpu->kvm, &gtod)) {
+ kvm_s390_retry_instr(vcpu);
+ return -EAGAIN;
+ }
kvm_s390_set_psw_cc(vcpu, 0);
return 0;
@@ -1443,10 +1456,11 @@ int kvm_s390_handle_eb(struct kvm_vcpu *vcpu)
static int handle_tprot(struct kvm_vcpu *vcpu)
{
- u64 address1, address2;
- unsigned long hva, gpa;
- int ret = 0, cc = 0;
+ u64 address, operand2;
+ unsigned long gpa;
+ u8 access_key;
bool writable;
+ int ret, cc;
u8 ar;
vcpu->stat.instruction_tprot++;
@@ -1454,43 +1468,46 @@ static int handle_tprot(struct kvm_vcpu *vcpu)
if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PSTATE)
return kvm_s390_inject_program_int(vcpu, PGM_PRIVILEGED_OP);
- kvm_s390_get_base_disp_sse(vcpu, &address1, &address2, &ar, NULL);
+ kvm_s390_get_base_disp_sse(vcpu, &address, &operand2, &ar, NULL);
+ access_key = (operand2 & 0xf0) >> 4;
- /* we only handle the Linux memory detection case:
- * access key == 0
- * everything else goes to userspace. */
- if (address2 & 0xf0)
- return -EOPNOTSUPP;
if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_DAT)
ipte_lock(vcpu);
- ret = guest_translate_address(vcpu, address1, ar, &gpa, GACC_STORE);
- if (ret == PGM_PROTECTION) {
+
+ ret = guest_translate_address_with_key(vcpu, address, ar, &gpa,
+ GACC_STORE, access_key);
+ if (ret == 0) {
+ gfn_to_hva_prot(vcpu->kvm, gpa_to_gfn(gpa), &writable);
+ } else if (ret == PGM_PROTECTION) {
+ writable = false;
/* Write protected? Try again with read-only... */
- cc = 1;
- ret = guest_translate_address(vcpu, address1, ar, &gpa,
- GACC_FETCH);
+ ret = guest_translate_address_with_key(vcpu, address, ar, &gpa,
+ GACC_FETCH, access_key);
}
- if (ret) {
- if (ret == PGM_ADDRESSING || ret == PGM_TRANSLATION_SPEC) {
- ret = kvm_s390_inject_program_int(vcpu, ret);
- } else if (ret > 0) {
- /* Translation not available */
- kvm_s390_set_psw_cc(vcpu, 3);
+ if (ret >= 0) {
+ cc = -1;
+
+ /* Fetching permitted; storing permitted */
+ if (ret == 0 && writable)
+ cc = 0;
+ /* Fetching permitted; storing not permitted */
+ else if (ret == 0 && !writable)
+ cc = 1;
+ /* Fetching not permitted; storing not permitted */
+ else if (ret == PGM_PROTECTION)
+ cc = 2;
+ /* Translation not available */
+ else if (ret != PGM_ADDRESSING && ret != PGM_TRANSLATION_SPEC)
+ cc = 3;
+
+ if (cc != -1) {
+ kvm_s390_set_psw_cc(vcpu, cc);
ret = 0;
+ } else {
+ ret = kvm_s390_inject_program_int(vcpu, ret);
}
- goto out_unlock;
}
- hva = gfn_to_hva_prot(vcpu->kvm, gpa_to_gfn(gpa), &writable);
- if (kvm_is_error_hva(hva)) {
- ret = kvm_s390_inject_program_int(vcpu, PGM_ADDRESSING);
- } else {
- if (!writable)
- cc = 1; /* Write not permitted ==> read-only */
- kvm_s390_set_psw_cc(vcpu, cc);
- /* Note: CC2 only occurs for storage keys (not supported yet) */
- }
-out_unlock:
if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_DAT)
ipte_unlock(vcpu);
return ret;
diff --git a/arch/s390/lib/Makefile b/arch/s390/lib/Makefile
index 707cd4622c13..69feb8ed3312 100644
--- a/arch/s390/lib/Makefile
+++ b/arch/s390/lib/Makefile
@@ -17,4 +17,7 @@ KASAN_SANITIZE_uaccess.o := n
obj-$(CONFIG_S390_UNWIND_SELFTEST) += test_unwind.o
CFLAGS_test_unwind.o += -fno-optimize-sibling-calls
+obj-$(CONFIG_S390_MODULES_SANITY_TEST) += test_modules.o
+obj-$(CONFIG_S390_MODULES_SANITY_TEST_HELPERS) += test_modules_helpers.o
+
lib-$(CONFIG_FUNCTION_ERROR_INJECTION) += error-inject.o
diff --git a/arch/s390/lib/test_modules.c b/arch/s390/lib/test_modules.c
new file mode 100644
index 000000000000..9894009fc1f2
--- /dev/null
+++ b/arch/s390/lib/test_modules.c
@@ -0,0 +1,32 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+#include <kunit/test.h>
+#include <linux/module.h>
+
+#include "test_modules.h"
+
+/*
+ * Test that modules with many relocations are loaded properly.
+ */
+static void test_modules_many_vmlinux_relocs(struct kunit *test)
+{
+ int result = 0;
+
+#define CALL_RETURN(i) result += test_modules_return_ ## i()
+ REPEAT_10000(CALL_RETURN);
+ KUNIT_ASSERT_EQ(test, result, 49995000);
+}
+
+static struct kunit_case modules_testcases[] = {
+ KUNIT_CASE(test_modules_many_vmlinux_relocs),
+ {}
+};
+
+static struct kunit_suite modules_test_suite = {
+ .name = "modules_test_s390",
+ .test_cases = modules_testcases,
+};
+
+kunit_test_suites(&modules_test_suite);
+
+MODULE_LICENSE("GPL");
diff --git a/arch/s390/lib/test_modules.h b/arch/s390/lib/test_modules.h
new file mode 100644
index 000000000000..6371fcf17684
--- /dev/null
+++ b/arch/s390/lib/test_modules.h
@@ -0,0 +1,53 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+#ifndef TEST_MODULES_H
+#define TEST_MODULES_H
+
+#define __REPEAT_10000_3(f, x) \
+ f(x ## 0); \
+ f(x ## 1); \
+ f(x ## 2); \
+ f(x ## 3); \
+ f(x ## 4); \
+ f(x ## 5); \
+ f(x ## 6); \
+ f(x ## 7); \
+ f(x ## 8); \
+ f(x ## 9)
+#define __REPEAT_10000_2(f, x) \
+ __REPEAT_10000_3(f, x ## 0); \
+ __REPEAT_10000_3(f, x ## 1); \
+ __REPEAT_10000_3(f, x ## 2); \
+ __REPEAT_10000_3(f, x ## 3); \
+ __REPEAT_10000_3(f, x ## 4); \
+ __REPEAT_10000_3(f, x ## 5); \
+ __REPEAT_10000_3(f, x ## 6); \
+ __REPEAT_10000_3(f, x ## 7); \
+ __REPEAT_10000_3(f, x ## 8); \
+ __REPEAT_10000_3(f, x ## 9)
+#define __REPEAT_10000_1(f, x) \
+ __REPEAT_10000_2(f, x ## 0); \
+ __REPEAT_10000_2(f, x ## 1); \
+ __REPEAT_10000_2(f, x ## 2); \
+ __REPEAT_10000_2(f, x ## 3); \
+ __REPEAT_10000_2(f, x ## 4); \
+ __REPEAT_10000_2(f, x ## 5); \
+ __REPEAT_10000_2(f, x ## 6); \
+ __REPEAT_10000_2(f, x ## 7); \
+ __REPEAT_10000_2(f, x ## 8); \
+ __REPEAT_10000_2(f, x ## 9)
+#define REPEAT_10000(f) \
+ __REPEAT_10000_1(f, 0); \
+ __REPEAT_10000_1(f, 1); \
+ __REPEAT_10000_1(f, 2); \
+ __REPEAT_10000_1(f, 3); \
+ __REPEAT_10000_1(f, 4); \
+ __REPEAT_10000_1(f, 5); \
+ __REPEAT_10000_1(f, 6); \
+ __REPEAT_10000_1(f, 7); \
+ __REPEAT_10000_1(f, 8); \
+ __REPEAT_10000_1(f, 9)
+
+#define DECLARE_RETURN(i) int test_modules_return_ ## i(void)
+REPEAT_10000(DECLARE_RETURN);
+
+#endif
diff --git a/arch/s390/lib/test_modules_helpers.c b/arch/s390/lib/test_modules_helpers.c
new file mode 100644
index 000000000000..1670349a03eb
--- /dev/null
+++ b/arch/s390/lib/test_modules_helpers.c
@@ -0,0 +1,13 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+#include <linux/export.h>
+
+#include "test_modules.h"
+
+#define DEFINE_RETURN(i) \
+ int test_modules_return_ ## i(void) \
+ { \
+ return 1 ## i - 10000; \
+ } \
+ EXPORT_SYMBOL_GPL(test_modules_return_ ## i)
+REPEAT_10000(DEFINE_RETURN);
diff --git a/arch/s390/lib/uaccess.c b/arch/s390/lib/uaccess.c
index 8a5d21461889..b709239feb5d 100644
--- a/arch/s390/lib/uaccess.c
+++ b/arch/s390/lib/uaccess.c
@@ -59,11 +59,13 @@ static inline int copy_with_mvcos(void)
#endif
static inline unsigned long copy_from_user_mvcos(void *x, const void __user *ptr,
- unsigned long size)
+ unsigned long size, unsigned long key)
{
unsigned long tmp1, tmp2;
union oac spec = {
+ .oac2.key = key,
.oac2.as = PSW_BITS_AS_SECONDARY,
+ .oac2.k = 1,
.oac2.a = 1,
};
@@ -94,19 +96,19 @@ static inline unsigned long copy_from_user_mvcos(void *x, const void __user *ptr
}
static inline unsigned long copy_from_user_mvcp(void *x, const void __user *ptr,
- unsigned long size)
+ unsigned long size, unsigned long key)
{
unsigned long tmp1, tmp2;
tmp1 = -256UL;
asm volatile(
" sacf 0\n"
- "0: mvcp 0(%0,%2),0(%1),%3\n"
+ "0: mvcp 0(%0,%2),0(%1),%[key]\n"
"7: jz 5f\n"
"1: algr %0,%3\n"
" la %1,256(%1)\n"
" la %2,256(%2)\n"
- "2: mvcp 0(%0,%2),0(%1),%3\n"
+ "2: mvcp 0(%0,%2),0(%1),%[key]\n"
"8: jnz 1b\n"
" j 5f\n"
"3: la %4,255(%1)\n" /* %4 = ptr + 255 */
@@ -115,7 +117,7 @@ static inline unsigned long copy_from_user_mvcp(void *x, const void __user *ptr,
" slgr %4,%1\n"
" clgr %0,%4\n" /* copy crosses next page boundary? */
" jnh 6f\n"
- "4: mvcp 0(%4,%2),0(%1),%3\n"
+ "4: mvcp 0(%4,%2),0(%1),%[key]\n"
"9: slgr %0,%4\n"
" j 6f\n"
"5: slgr %0,%0\n"
@@ -123,24 +125,49 @@ static inline unsigned long copy_from_user_mvcp(void *x, const void __user *ptr,
EX_TABLE(0b,3b) EX_TABLE(2b,3b) EX_TABLE(4b,6b)
EX_TABLE(7b,3b) EX_TABLE(8b,3b) EX_TABLE(9b,6b)
: "+a" (size), "+a" (ptr), "+a" (x), "+a" (tmp1), "=a" (tmp2)
- : : "cc", "memory");
+ : [key] "d" (key << 4)
+ : "cc", "memory");
return size;
}
-unsigned long raw_copy_from_user(void *to, const void __user *from, unsigned long n)
+static unsigned long raw_copy_from_user_key(void *to, const void __user *from,
+ unsigned long n, unsigned long key)
{
if (copy_with_mvcos())
- return copy_from_user_mvcos(to, from, n);
- return copy_from_user_mvcp(to, from, n);
+ return copy_from_user_mvcos(to, from, n, key);
+ return copy_from_user_mvcp(to, from, n, key);
+}
+
+unsigned long raw_copy_from_user(void *to, const void __user *from, unsigned long n)
+{
+ return raw_copy_from_user_key(to, from, n, 0);
}
EXPORT_SYMBOL(raw_copy_from_user);
+unsigned long _copy_from_user_key(void *to, const void __user *from,
+ unsigned long n, unsigned long key)
+{
+ unsigned long res = n;
+
+ might_fault();
+ if (!should_fail_usercopy()) {
+ instrument_copy_from_user(to, from, n);
+ res = raw_copy_from_user_key(to, from, n, key);
+ }
+ if (unlikely(res))
+ memset(to + (n - res), 0, res);
+ return res;
+}
+EXPORT_SYMBOL(_copy_from_user_key);
+
static inline unsigned long copy_to_user_mvcos(void __user *ptr, const void *x,
- unsigned long size)
+ unsigned long size, unsigned long key)
{
unsigned long tmp1, tmp2;
union oac spec = {
+ .oac1.key = key,
.oac1.as = PSW_BITS_AS_SECONDARY,
+ .oac1.k = 1,
.oac1.a = 1,
};
@@ -171,19 +198,19 @@ static inline unsigned long copy_to_user_mvcos(void __user *ptr, const void *x,
}
static inline unsigned long copy_to_user_mvcs(void __user *ptr, const void *x,
- unsigned long size)
+ unsigned long size, unsigned long key)
{
unsigned long tmp1, tmp2;
tmp1 = -256UL;
asm volatile(
" sacf 0\n"
- "0: mvcs 0(%0,%1),0(%2),%3\n"
+ "0: mvcs 0(%0,%1),0(%2),%[key]\n"
"7: jz 5f\n"
"1: algr %0,%3\n"
" la %1,256(%1)\n"
" la %2,256(%2)\n"
- "2: mvcs 0(%0,%1),0(%2),%3\n"
+ "2: mvcs 0(%0,%1),0(%2),%[key]\n"
"8: jnz 1b\n"
" j 5f\n"
"3: la %4,255(%1)\n" /* %4 = ptr + 255 */
@@ -192,7 +219,7 @@ static inline unsigned long copy_to_user_mvcs(void __user *ptr, const void *x,
" slgr %4,%1\n"
" clgr %0,%4\n" /* copy crosses next page boundary? */
" jnh 6f\n"
- "4: mvcs 0(%4,%1),0(%2),%3\n"
+ "4: mvcs 0(%4,%1),0(%2),%[key]\n"
"9: slgr %0,%4\n"
" j 6f\n"
"5: slgr %0,%0\n"
@@ -200,18 +227,36 @@ static inline unsigned long copy_to_user_mvcs(void __user *ptr, const void *x,
EX_TABLE(0b,3b) EX_TABLE(2b,3b) EX_TABLE(4b,6b)
EX_TABLE(7b,3b) EX_TABLE(8b,3b) EX_TABLE(9b,6b)
: "+a" (size), "+a" (ptr), "+a" (x), "+a" (tmp1), "=a" (tmp2)
- : : "cc", "memory");
+ : [key] "d" (key << 4)
+ : "cc", "memory");
return size;
}
-unsigned long raw_copy_to_user(void __user *to, const void *from, unsigned long n)
+static unsigned long raw_copy_to_user_key(void __user *to, const void *from,
+ unsigned long n, unsigned long key)
{
if (copy_with_mvcos())
- return copy_to_user_mvcos(to, from, n);
- return copy_to_user_mvcs(to, from, n);
+ return copy_to_user_mvcos(to, from, n, key);
+ return copy_to_user_mvcs(to, from, n, key);
+}
+
+unsigned long raw_copy_to_user(void __user *to, const void *from, unsigned long n)
+{
+ return raw_copy_to_user_key(to, from, n, 0);
}
EXPORT_SYMBOL(raw_copy_to_user);
+unsigned long _copy_to_user_key(void __user *to, const void *from,
+ unsigned long n, unsigned long key)
+{
+ might_fault();
+ if (should_fail_usercopy())
+ return n;
+ instrument_copy_to_user(to, from, n);
+ return raw_copy_to_user_key(to, from, n, key);
+}
+EXPORT_SYMBOL(_copy_to_user_key);
+
static inline unsigned long clear_user_mvcos(void __user *to, unsigned long size)
{
unsigned long tmp1, tmp2;
diff --git a/arch/s390/lib/xor.c b/arch/s390/lib/xor.c
index a963c3d8ad0d..fb924a8041dc 100644
--- a/arch/s390/lib/xor.c
+++ b/arch/s390/lib/xor.c
@@ -11,7 +11,8 @@
#include <linux/raid/xor.h>
#include <asm/xor.h>
-static void xor_xc_2(unsigned long bytes, unsigned long *p1, unsigned long *p2)
+static void xor_xc_2(unsigned long bytes, unsigned long * __restrict p1,
+ const unsigned long * __restrict p2)
{
asm volatile(
" larl 1,2f\n"
@@ -32,8 +33,9 @@ static void xor_xc_2(unsigned long bytes, unsigned long *p1, unsigned long *p2)
: "0", "1", "cc", "memory");
}
-static void xor_xc_3(unsigned long bytes, unsigned long *p1, unsigned long *p2,
- unsigned long *p3)
+static void xor_xc_3(unsigned long bytes, unsigned long * __restrict p1,
+ const unsigned long * __restrict p2,
+ const unsigned long * __restrict p3)
{
asm volatile(
" larl 1,2f\n"
@@ -58,8 +60,10 @@ static void xor_xc_3(unsigned long bytes, unsigned long *p1, unsigned long *p2,
: : "0", "1", "cc", "memory");
}
-static void xor_xc_4(unsigned long bytes, unsigned long *p1, unsigned long *p2,
- unsigned long *p3, unsigned long *p4)
+static void xor_xc_4(unsigned long bytes, unsigned long * __restrict p1,
+ const unsigned long * __restrict p2,
+ const unsigned long * __restrict p3,
+ const unsigned long * __restrict p4)
{
asm volatile(
" larl 1,2f\n"
@@ -88,8 +92,11 @@ static void xor_xc_4(unsigned long bytes, unsigned long *p1, unsigned long *p2,
: : "0", "1", "cc", "memory");
}
-static void xor_xc_5(unsigned long bytes, unsigned long *p1, unsigned long *p2,
- unsigned long *p3, unsigned long *p4, unsigned long *p5)
+static void xor_xc_5(unsigned long bytes, unsigned long * __restrict p1,
+ const unsigned long * __restrict p2,
+ const unsigned long * __restrict p3,
+ const unsigned long * __restrict p4,
+ const unsigned long * __restrict p5)
{
asm volatile(
" larl 1,2f\n"
diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig
index 2474a04ceac4..5f220e903e5a 100644
--- a/arch/sh/Kconfig
+++ b/arch/sh/Kconfig
@@ -7,6 +7,7 @@ config SUPERH
select ARCH_HAVE_CUSTOM_GPIO_H
select ARCH_HAVE_NMI_SAFE_CMPXCHG if (GUSA_RB || CPU_SH4A)
select ARCH_HAS_BINFMT_FLAT if !MMU
+ select ARCH_HAS_CURRENT_STACK_POINTER
select ARCH_HAS_GIGANTIC_PAGE
select ARCH_HAS_GCOV_PROFILE_ALL
select ARCH_HAS_PTE_SPECIAL
@@ -65,7 +66,6 @@ config SUPERH
select PERF_EVENTS
select PERF_USE_VMALLOC
select RTC_LIB
- select SET_FS
select SPARSE_IRQ
select TRACE_IRQFLAGS_SUPPORT
help
diff --git a/arch/sh/configs/ap325rxa_defconfig b/arch/sh/configs/ap325rxa_defconfig
index 5193b3e099b9..4d83576b89c6 100644
--- a/arch/sh/configs/ap325rxa_defconfig
+++ b/arch/sh/configs/ap325rxa_defconfig
@@ -93,7 +93,6 @@ CONFIG_NFS_FS=y
CONFIG_NFS_V3=y
CONFIG_ROOT_NFS=y
CONFIG_NFSD=y
-CONFIG_NFSD_V3=y
CONFIG_NLS_CODEPAGE_437=y
CONFIG_NLS_CODEPAGE_932=y
CONFIG_NLS_ISO8859_1=y
diff --git a/arch/sh/configs/ecovec24_defconfig b/arch/sh/configs/ecovec24_defconfig
index 03cb916819fa..d90d29d44469 100644
--- a/arch/sh/configs/ecovec24_defconfig
+++ b/arch/sh/configs/ecovec24_defconfig
@@ -123,7 +123,6 @@ CONFIG_NFS_FS=y
CONFIG_NFS_V3=y
CONFIG_ROOT_NFS=y
CONFIG_NFSD=y
-CONFIG_NFSD_V3=y
CONFIG_NLS_CODEPAGE_437=y
CONFIG_NLS_CODEPAGE_932=y
CONFIG_NLS_ISO8859_1=y
diff --git a/arch/sh/configs/landisk_defconfig b/arch/sh/configs/landisk_defconfig
index e6c5ddf070c0..492a0a2e0e36 100644
--- a/arch/sh/configs/landisk_defconfig
+++ b/arch/sh/configs/landisk_defconfig
@@ -108,7 +108,6 @@ CONFIG_UFS_FS=m
CONFIG_NFS_FS=m
CONFIG_NFS_V3=y
CONFIG_NFSD=m
-CONFIG_NFSD_V3=y
CONFIG_SMB_FS=m
CONFIG_NLS_CODEPAGE_437=y
CONFIG_NLS_CODEPAGE_932=y
diff --git a/arch/sh/configs/sdk7780_defconfig b/arch/sh/configs/sdk7780_defconfig
index 6c719ab4332a..7d6d32359848 100644
--- a/arch/sh/configs/sdk7780_defconfig
+++ b/arch/sh/configs/sdk7780_defconfig
@@ -120,7 +120,6 @@ CONFIG_NFS_FS=y
CONFIG_NFS_V3=y
CONFIG_ROOT_NFS=y
CONFIG_NFSD=y
-CONFIG_NFSD_V3=y
CONFIG_NLS_CODEPAGE_437=y
CONFIG_NLS_ASCII=y
CONFIG_NLS_ISO8859_1=y
diff --git a/arch/sh/configs/se7724_defconfig b/arch/sh/configs/se7724_defconfig
index a26f7f1841c7..d817df7cc4a7 100644
--- a/arch/sh/configs/se7724_defconfig
+++ b/arch/sh/configs/se7724_defconfig
@@ -122,7 +122,6 @@ CONFIG_NFS_FS=y
CONFIG_NFS_V3=y
CONFIG_ROOT_NFS=y
CONFIG_NFSD=y
-CONFIG_NFSD_V3=y
CONFIG_NLS_CODEPAGE_437=y
CONFIG_NLS_CODEPAGE_932=y
CONFIG_NLS_ISO8859_1=y
diff --git a/arch/sh/configs/sh03_defconfig b/arch/sh/configs/sh03_defconfig
index ff502683132e..9fcf68b22dba 100644
--- a/arch/sh/configs/sh03_defconfig
+++ b/arch/sh/configs/sh03_defconfig
@@ -75,7 +75,6 @@ CONFIG_NFS_V3=y
CONFIG_NFS_V4=y
CONFIG_ROOT_NFS=y
CONFIG_NFSD=y
-CONFIG_NFSD_V3=y
CONFIG_PARTITION_ADVANCED=y
CONFIG_NLS_CODEPAGE_437=m
CONFIG_NLS_CODEPAGE_737=m
diff --git a/arch/sh/configs/sh7785lcr_32bit_defconfig b/arch/sh/configs/sh7785lcr_32bit_defconfig
index 5c725c75fcef..7eb3c10f28ad 100644
--- a/arch/sh/configs/sh7785lcr_32bit_defconfig
+++ b/arch/sh/configs/sh7785lcr_32bit_defconfig
@@ -129,7 +129,6 @@ CONFIG_NFS_V3=y
CONFIG_NFS_V4=y
CONFIG_ROOT_NFS=y
CONFIG_NFSD=m
-CONFIG_NFSD_V3=y
CONFIG_NLS_CODEPAGE_437=y
CONFIG_NLS_CODEPAGE_932=y
CONFIG_NLS_ISO8859_1=y
diff --git a/arch/sh/configs/titan_defconfig b/arch/sh/configs/titan_defconfig
index cd5c58916c65..73a0d68b0de6 100644
--- a/arch/sh/configs/titan_defconfig
+++ b/arch/sh/configs/titan_defconfig
@@ -239,7 +239,6 @@ CONFIG_NFS_FS=y
CONFIG_NFS_V3=y
CONFIG_ROOT_NFS=y
CONFIG_NFSD=y
-CONFIG_NFSD_V3=y
CONFIG_SMB_FS=m
CONFIG_CIFS=m
CONFIG_PARTITION_ADVANCED=y
diff --git a/arch/sh/include/asm/pgtable_32.h b/arch/sh/include/asm/pgtable_32.h
index 41be43e99cff..d0240decacca 100644
--- a/arch/sh/include/asm/pgtable_32.h
+++ b/arch/sh/include/asm/pgtable_32.h
@@ -406,6 +406,7 @@ static inline unsigned long pmd_page_vaddr(pmd_t pmd)
return (unsigned long)pmd_val(pmd);
}
+#define pmd_pfn(pmd) (__pa(pmd_val(pmd)) >> PAGE_SHIFT)
#define pmd_page(pmd) (virt_to_page(pmd_val(pmd)))
#ifdef CONFIG_X2TLB
diff --git a/arch/sh/include/asm/processor.h b/arch/sh/include/asm/processor.h
index 3820d698846e..85a6c1c3c16e 100644
--- a/arch/sh/include/asm/processor.h
+++ b/arch/sh/include/asm/processor.h
@@ -3,7 +3,6 @@
#define __ASM_SH_PROCESSOR_H
#include <asm/cpu-features.h>
-#include <asm/segment.h>
#include <asm/cache.h>
#ifndef __ASSEMBLY__
diff --git a/arch/sh/include/asm/segment.h b/arch/sh/include/asm/segment.h
deleted file mode 100644
index 02e54a3335d6..000000000000
--- a/arch/sh/include/asm/segment.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef __ASM_SH_SEGMENT_H
-#define __ASM_SH_SEGMENT_H
-
-#ifndef __ASSEMBLY__
-
-typedef struct {
- unsigned long seg;
-} mm_segment_t;
-
-#define MAKE_MM_SEG(s) ((mm_segment_t) { (s) })
-
-/*
- * The fs value determines whether argument validity checking should be
- * performed or not. If get_fs() == USER_DS, checking is performed, with
- * get_fs() == KERNEL_DS, checking is bypassed.
- *
- * For historical reasons, these macros are grossly misnamed.
- */
-#define KERNEL_DS MAKE_MM_SEG(0xFFFFFFFFUL)
-#ifdef CONFIG_MMU
-#define USER_DS MAKE_MM_SEG(PAGE_OFFSET)
-#else
-#define USER_DS KERNEL_DS
-#endif
-
-#define uaccess_kernel() (get_fs().seg == KERNEL_DS.seg)
-
-#define get_fs() (current_thread_info()->addr_limit)
-#define set_fs(x) (current_thread_info()->addr_limit = (x))
-
-#endif /* __ASSEMBLY__ */
-#endif /* __ASM_SH_SEGMENT_H */
diff --git a/arch/sh/include/asm/thread_info.h b/arch/sh/include/asm/thread_info.h
index 598d0184ffea..1400fbb8b423 100644
--- a/arch/sh/include/asm/thread_info.h
+++ b/arch/sh/include/asm/thread_info.h
@@ -30,10 +30,9 @@ struct thread_info {
__u32 status; /* thread synchronous flags */
__u32 cpu;
int preempt_count; /* 0 => preemptable, <0 => BUG */
- mm_segment_t addr_limit; /* thread address space */
unsigned long previous_sp; /* sp of previous stack in case
of nested IRQ stacks */
- __u8 supervisor_stack[0];
+ __u8 supervisor_stack[];
};
#endif
@@ -58,7 +57,6 @@ struct thread_info {
.status = 0, \
.cpu = 0, \
.preempt_count = INIT_PREEMPT_COUNT, \
- .addr_limit = KERNEL_DS, \
}
/* how to get the current stack pointer from C */
diff --git a/arch/sh/include/asm/uaccess.h b/arch/sh/include/asm/uaccess.h
index 8867bb04b00e..a79609eb14be 100644
--- a/arch/sh/include/asm/uaccess.h
+++ b/arch/sh/include/asm/uaccess.h
@@ -2,30 +2,8 @@
#ifndef __ASM_SH_UACCESS_H
#define __ASM_SH_UACCESS_H
-#include <asm/segment.h>
#include <asm/extable.h>
-
-#define __addr_ok(addr) \
- ((unsigned long __force)(addr) < current_thread_info()->addr_limit.seg)
-
-/*
- * __access_ok: Check if address with size is OK or not.
- *
- * Uhhuh, this needs 33-bit arithmetic. We have a carry..
- *
- * sum := addr + size; carry? --> flag = true;
- * if (sum >= addr_limit) flag = true;
- */
-#define __access_ok(addr, size) ({ \
- unsigned long __ao_a = (addr), __ao_b = (size); \
- unsigned long __ao_end = __ao_a + __ao_b - !!__ao_b; \
- __ao_end >= __ao_a && __addr_ok(__ao_end); })
-
-#define access_ok(addr, size) \
- (__chk_user_ptr(addr), \
- __access_ok((unsigned long __force)(addr), (size)))
-
-#define user_addr_max() (current_thread_info()->addr_limit.seg)
+#include <asm-generic/access_ok.h>
/*
* Uh, these should become the main single-value transfer routines ...
diff --git a/arch/sh/kernel/io_trapped.c b/arch/sh/kernel/io_trapped.c
index 004ad0130b10..e803b14ef12e 100644
--- a/arch/sh/kernel/io_trapped.c
+++ b/arch/sh/kernel/io_trapped.c
@@ -270,7 +270,6 @@ static struct mem_access trapped_io_access = {
int handle_trapped_io(struct pt_regs *regs, unsigned long address)
{
- mm_segment_t oldfs;
insn_size_t instruction;
int tmp;
@@ -281,16 +280,12 @@ int handle_trapped_io(struct pt_regs *regs, unsigned long address)
WARN_ON(user_mode(regs));
- oldfs = get_fs();
- set_fs(KERNEL_DS);
- if (copy_from_user(&instruction, (void *)(regs->pc),
- sizeof(instruction))) {
- set_fs(oldfs);
+ if (copy_from_kernel_nofault(&instruction, (void *)(regs->pc),
+ sizeof(instruction))) {
return 0;
}
tmp = handle_unaligned_access(instruction, regs,
&trapped_io_access, 1, address);
- set_fs(oldfs);
return tmp == 0;
}
diff --git a/arch/sh/kernel/process_32.c b/arch/sh/kernel/process_32.c
index 1c28e3cddb60..ca01286a0610 100644
--- a/arch/sh/kernel/process_32.c
+++ b/arch/sh/kernel/process_32.c
@@ -123,7 +123,6 @@ int copy_thread(unsigned long clone_flags, unsigned long usp, unsigned long arg,
#if defined(CONFIG_SH_FPU)
childregs->sr |= SR_FD;
#endif
- ti->addr_limit = KERNEL_DS;
ti->status &= ~TS_USEDFPU;
p->thread.fpu_counter = 0;
return 0;
@@ -132,7 +131,6 @@ int copy_thread(unsigned long clone_flags, unsigned long usp, unsigned long arg,
if (usp)
childregs->regs[15] = usp;
- ti->addr_limit = USER_DS;
if (clone_flags & CLONE_SETTLS)
childregs->gbr = tls;
diff --git a/arch/sh/kernel/topology.c b/arch/sh/kernel/topology.c
index 76af6db9daa2..2d2a7509b565 100644
--- a/arch/sh/kernel/topology.c
+++ b/arch/sh/kernel/topology.c
@@ -46,11 +46,6 @@ static int __init topology_init(void)
{
int i, ret;
-#ifdef CONFIG_NUMA
- for_each_online_node(i)
- register_one_node(i);
-#endif
-
for_each_present_cpu(i) {
struct cpu *c = &per_cpu(cpu_devices, i);
diff --git a/arch/sh/kernel/traps_32.c b/arch/sh/kernel/traps_32.c
index b3c715bc254b..6cdda3a621a1 100644
--- a/arch/sh/kernel/traps_32.c
+++ b/arch/sh/kernel/traps_32.c
@@ -75,6 +75,23 @@ static struct mem_access user_mem_access = {
copy_to_user,
};
+static unsigned long copy_from_kernel_wrapper(void *dst, const void __user *src,
+ unsigned long cnt)
+{
+ return copy_from_kernel_nofault(dst, (const void __force *)src, cnt);
+}
+
+static unsigned long copy_to_kernel_wrapper(void __user *dst, const void *src,
+ unsigned long cnt)
+{
+ return copy_to_kernel_nofault((void __force *)dst, src, cnt);
+}
+
+static struct mem_access kernel_mem_access = {
+ copy_from_kernel_wrapper,
+ copy_to_kernel_wrapper,
+};
+
/*
* handle an instruction that does an unaligned memory access by emulating the
* desired behaviour
@@ -473,7 +490,6 @@ asmlinkage void do_address_error(struct pt_regs *regs,
unsigned long address)
{
unsigned long error_code = 0;
- mm_segment_t oldfs;
insn_size_t instruction;
int tmp;
@@ -489,13 +505,10 @@ asmlinkage void do_address_error(struct pt_regs *regs,
local_irq_enable();
inc_unaligned_user_access();
- oldfs = force_uaccess_begin();
if (copy_from_user(&instruction, (insn_size_t __user *)(regs->pc & ~1),
sizeof(instruction))) {
- force_uaccess_end(oldfs);
goto uspace_segv;
}
- force_uaccess_end(oldfs);
/* shout about userspace fixups */
unaligned_fixups_notify(current, instruction, regs);
@@ -518,11 +531,9 @@ fixup:
goto uspace_segv;
}
- oldfs = force_uaccess_begin();
tmp = handle_unaligned_access(instruction, regs,
&user_mem_access, 0,
address);
- force_uaccess_end(oldfs);
if (tmp == 0)
return; /* sorted */
@@ -538,21 +549,18 @@ uspace_segv:
if (regs->pc & 1)
die("unaligned program counter", regs, error_code);
- set_fs(KERNEL_DS);
- if (copy_from_user(&instruction, (void __user *)(regs->pc),
+ if (copy_from_kernel_nofault(&instruction, (void *)(regs->pc),
sizeof(instruction))) {
/* Argh. Fault on the instruction itself.
This should never happen non-SMP
*/
- set_fs(oldfs);
die("insn faulting in do_address_error", regs, 0);
}
unaligned_fixups_notify(current, instruction, regs);
- handle_unaligned_access(instruction, regs, &user_mem_access,
+ handle_unaligned_access(instruction, regs, &kernel_mem_access,
0, address);
- set_fs(oldfs);
}
}
diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig
index 1cab1b284f1a..9200bc04701c 100644
--- a/arch/sparc/Kconfig
+++ b/arch/sparc/Kconfig
@@ -46,7 +46,6 @@ config SPARC
select LOCKDEP_SMALL if LOCKDEP
select NEED_DMA_MAP_STATE
select NEED_SG_DMA_LENGTH
- select SET_FS
select TRACE_IRQFLAGS_SUPPORT
config SPARC32
@@ -62,6 +61,7 @@ config SPARC32
config SPARC64
def_bool 64BIT
+ select ALTERNATE_USER_ADDRESS_SPACE
select HAVE_FUNCTION_TRACER
select HAVE_FUNCTION_GRAPH_TRACER
select HAVE_KRETPROBES
diff --git a/arch/sparc/include/asm/agp.h b/arch/sparc/include/asm/agp.h
index efe0d6a12e5a..2d0ff84cee3f 100644
--- a/arch/sparc/include/asm/agp.h
+++ b/arch/sparc/include/asm/agp.h
@@ -4,9 +4,9 @@
/* dummy for now */
-#define map_page_into_agp(page)
-#define unmap_page_from_agp(page)
-#define flush_agp_cache() mb()
+#define map_page_into_agp(page) do { } while (0)
+#define unmap_page_from_agp(page) do { } while (0)
+#define flush_agp_cache() mb()
/* GATT allocation. Returns/accepts GATT kernel virtual address. */
#define alloc_gatt_pages(order) \
diff --git a/arch/sparc/include/asm/pgtable_32.h b/arch/sparc/include/asm/pgtable_32.h
index ffccfe3b22ed..4866625da314 100644
--- a/arch/sparc/include/asm/pgtable_32.h
+++ b/arch/sparc/include/asm/pgtable_32.h
@@ -127,11 +127,16 @@ static inline int srmmu_device_memory(unsigned long x)
return ((x & 0xF0000000) != 0);
}
+static inline unsigned long pmd_pfn(pmd_t pmd)
+{
+ return (pmd_val(pmd) & SRMMU_PTD_PMASK) >> (PAGE_SHIFT-4);
+}
+
static inline struct page *pmd_page(pmd_t pmd)
{
if (srmmu_device_memory(pmd_val(pmd)))
BUG();
- return pfn_to_page((pmd_val(pmd) & SRMMU_PTD_PMASK) >> (PAGE_SHIFT-4));
+ return pfn_to_page(pmd_pfn(pmd));
}
static inline unsigned long __pmd_page(pmd_t pmd)
diff --git a/arch/sparc/include/asm/processor_32.h b/arch/sparc/include/asm/processor_32.h
index 647bf0ac7beb..b26c35336b51 100644
--- a/arch/sparc/include/asm/processor_32.h
+++ b/arch/sparc/include/asm/processor_32.h
@@ -32,10 +32,6 @@ struct fpq {
};
#endif
-typedef struct {
- int seg;
-} mm_segment_t;
-
/* The Sparc processor specific thread struct. */
struct thread_struct {
struct pt_regs *kregs;
@@ -50,11 +46,9 @@ struct thread_struct {
unsigned long fsr;
unsigned long fpqdepth;
struct fpq fpqueue[16];
- mm_segment_t current_ds;
};
#define INIT_THREAD { \
- .current_ds = KERNEL_DS, \
.kregs = (struct pt_regs *)(init_stack+THREAD_SIZE)-1 \
}
diff --git a/arch/sparc/include/asm/processor_64.h b/arch/sparc/include/asm/processor_64.h
index ae851e8fce4c..89850dff6b03 100644
--- a/arch/sparc/include/asm/processor_64.h
+++ b/arch/sparc/include/asm/processor_64.h
@@ -47,10 +47,6 @@
#ifndef __ASSEMBLY__
-typedef struct {
- unsigned char seg;
-} mm_segment_t;
-
/* The Sparc processor specific thread struct. */
/* XXX This should die, everything can go into thread_info now. */
struct thread_struct {
diff --git a/arch/sparc/include/asm/switch_to_64.h b/arch/sparc/include/asm/switch_to_64.h
index b1d4e2e3210f..14f3c49bfdbc 100644
--- a/arch/sparc/include/asm/switch_to_64.h
+++ b/arch/sparc/include/asm/switch_to_64.h
@@ -20,10 +20,8 @@ do { \
*/
#define switch_to(prev, next, last) \
do { save_and_clear_fpu(); \
- /* If you are tempted to conditionalize the following */ \
- /* so that ASI is only written if it changes, think again. */ \
__asm__ __volatile__("wr %%g0, %0, %%asi" \
- : : "r" (task_thread_info(next)->current_ds));\
+ : : "r" (ASI_AIUS)); \
trap_block[current_thread_info()->cpu].thread = \
task_thread_info(next); \
__asm__ __volatile__( \
diff --git a/arch/sparc/include/asm/thread_info_64.h b/arch/sparc/include/asm/thread_info_64.h
index 8047a9caab2f..1a44372e2bc0 100644
--- a/arch/sparc/include/asm/thread_info_64.h
+++ b/arch/sparc/include/asm/thread_info_64.h
@@ -46,7 +46,7 @@ struct thread_info {
struct pt_regs *kregs;
int preempt_count; /* 0 => preemptable, <0 => BUG */
__u8 new_child;
- __u8 current_ds;
+ __u8 __pad;
__u16 cpu;
unsigned long *utraps;
@@ -81,7 +81,6 @@ struct thread_info {
#define TI_KREGS 0x00000028
#define TI_PRE_COUNT 0x00000030
#define TI_NEW_CHILD 0x00000034
-#define TI_CURRENT_DS 0x00000035
#define TI_CPU 0x00000036
#define TI_UTRAPS 0x00000038
#define TI_REG_WINDOW 0x00000040
@@ -116,7 +115,6 @@ struct thread_info {
#define INIT_THREAD_INFO(tsk) \
{ \
.task = &tsk, \
- .current_ds = ASI_P, \
.preempt_count = INIT_PREEMPT_COUNT, \
.kregs = (struct pt_regs *)(init_stack+THREAD_SIZE)-1 \
}
diff --git a/arch/sparc/include/asm/uaccess.h b/arch/sparc/include/asm/uaccess.h
index 390094200fc4..ee75f69e3fcd 100644
--- a/arch/sparc/include/asm/uaccess.h
+++ b/arch/sparc/include/asm/uaccess.h
@@ -10,9 +10,6 @@
#include <asm/uaccess_32.h>
#endif
-#define user_addr_max() \
- (uaccess_kernel() ? ~0UL : TASK_SIZE)
-
long strncpy_from_user(char *dest, const char __user *src, long count);
#endif
diff --git a/arch/sparc/include/asm/uaccess_32.h b/arch/sparc/include/asm/uaccess_32.h
index 4a12346bb69c..9fd6c53644b6 100644
--- a/arch/sparc/include/asm/uaccess_32.h
+++ b/arch/sparc/include/asm/uaccess_32.h
@@ -12,30 +12,7 @@
#include <linux/string.h>
#include <asm/processor.h>
-
-/* Sparc is not segmented, however we need to be able to fool access_ok()
- * when doing system calls from kernel mode legitimately.
- *
- * "For historical reasons, these macros are grossly misnamed." -Linus
- */
-
-#define KERNEL_DS ((mm_segment_t) { 0 })
-#define USER_DS ((mm_segment_t) { -1 })
-
-#define get_fs() (current->thread.current_ds)
-#define set_fs(val) ((current->thread.current_ds) = (val))
-
-#define uaccess_kernel() (get_fs().seg == KERNEL_DS.seg)
-
-/* We have there a nice not-mapped page at PAGE_OFFSET - PAGE_SIZE, so that this test
- * can be fairly lightweight.
- * No one can read/write anything from userland in the kernel space by setting
- * large size and address near to PAGE_OFFSET - a fault will break his intentions.
- */
-#define __user_ok(addr, size) ({ (void)(size); (addr) < STACK_TOP; })
-#define __kernel_ok (uaccess_kernel())
-#define __access_ok(addr, size) (__user_ok((addr) & get_fs().seg, (size)))
-#define access_ok(addr, size) __access_ok((unsigned long)(addr), size)
+#include <asm-generic/access_ok.h>
/* Uh, these should become the main single-value transfer routines..
* They automatically use the right size if we just have the right
@@ -47,13 +24,13 @@
* and hide all the ugliness from the user.
*/
#define put_user(x, ptr) ({ \
- unsigned long __pu_addr = (unsigned long)(ptr); \
+ void __user *__pu_addr = (ptr); \
__chk_user_ptr(ptr); \
__put_user_check((__typeof__(*(ptr)))(x), __pu_addr, sizeof(*(ptr))); \
})
#define get_user(x, ptr) ({ \
- unsigned long __gu_addr = (unsigned long)(ptr); \
+ const void __user *__gu_addr = (ptr); \
__chk_user_ptr(ptr); \
__get_user_check((x), __gu_addr, sizeof(*(ptr)), __typeof__(*(ptr))); \
})
@@ -232,7 +209,7 @@ static inline unsigned long __clear_user(void __user *addr, unsigned long size)
static inline unsigned long clear_user(void __user *addr, unsigned long n)
{
- if (n && __access_ok((unsigned long) addr, n))
+ if (n && __access_ok(addr, n))
return __clear_user(addr, n);
else
return n;
diff --git a/arch/sparc/include/asm/uaccess_64.h b/arch/sparc/include/asm/uaccess_64.h
index 30eb4c6414d1..94266a5c5b04 100644
--- a/arch/sparc/include/asm/uaccess_64.h
+++ b/arch/sparc/include/asm/uaccess_64.h
@@ -12,33 +12,15 @@
#include <asm/spitfire.h>
#include <asm/processor.h>
+#include <asm-generic/access_ok.h>
/*
* Sparc64 is segmented, though more like the M68K than the I386.
* We use the secondary ASI to address user memory, which references a
* completely different VM map, thus there is zero chance of the user
* doing something queer and tricking us into poking kernel memory.
- *
- * What is left here is basically what is needed for the other parts of
- * the kernel that expect to be able to manipulate, erum, "segments".
- * Or perhaps more properly, permissions.
- *
- * "For historical reasons, these macros are grossly misnamed." -Linus
*/
-#define KERNEL_DS ((mm_segment_t) { ASI_P })
-#define USER_DS ((mm_segment_t) { ASI_AIUS }) /* har har har */
-
-#define get_fs() ((mm_segment_t){(current_thread_info()->current_ds)})
-
-#define uaccess_kernel() (get_fs().seg == KERNEL_DS.seg)
-
-#define set_fs(val) \
-do { \
- current_thread_info()->current_ds = (val).seg; \
- __asm__ __volatile__ ("wr %%g0, %0, %%asi" : : "r" ((val).seg)); \
-} while(0)
-
/*
* Test whether a block of memory is a valid user space address.
* Returns 0 if the range is valid, nonzero otherwise.
@@ -61,16 +43,6 @@ static inline bool __chk_range_not_ok(unsigned long addr, unsigned long size, un
__chk_range_not_ok((unsigned long __force)(addr), size, limit); \
})
-static inline int __access_ok(const void __user * addr, unsigned long size)
-{
- return 1;
-}
-
-static inline int access_ok(const void __user * addr, unsigned long size)
-{
- return 1;
-}
-
void __retl_efault(void);
/* Uh, these should become the main single-value transfer routines..
@@ -100,6 +72,42 @@ void __retl_efault(void);
struct __large_struct { unsigned long buf[100]; };
#define __m(x) ((struct __large_struct *)(x))
+#define __put_kernel_nofault(dst, src, type, label) \
+do { \
+ type *addr = (type __force *)(dst); \
+ type data = *(type *)src; \
+ register int __pu_ret; \
+ switch (sizeof(type)) { \
+ case 1: __put_kernel_asm(data, b, addr, __pu_ret); break; \
+ case 2: __put_kernel_asm(data, h, addr, __pu_ret); break; \
+ case 4: __put_kernel_asm(data, w, addr, __pu_ret); break; \
+ case 8: __put_kernel_asm(data, x, addr, __pu_ret); break; \
+ default: __pu_ret = __put_user_bad(); break; \
+ } \
+ if (__pu_ret) \
+ goto label; \
+} while (0)
+
+#define __put_kernel_asm(x, size, addr, ret) \
+__asm__ __volatile__( \
+ "/* Put kernel asm, inline. */\n" \
+ "1:\t" "st"#size " %1, [%2]\n\t" \
+ "clr %0\n" \
+ "2:\n\n\t" \
+ ".section .fixup,#alloc,#execinstr\n\t" \
+ ".align 4\n" \
+ "3:\n\t" \
+ "sethi %%hi(2b), %0\n\t" \
+ "jmpl %0 + %%lo(2b), %%g0\n\t" \
+ " mov %3, %0\n\n\t" \
+ ".previous\n\t" \
+ ".section __ex_table,\"a\"\n\t" \
+ ".align 4\n\t" \
+ ".word 1b, 3b\n\t" \
+ ".previous\n\n\t" \
+ : "=r" (ret) : "r" (x), "r" (__m(addr)), \
+ "i" (-EFAULT))
+
#define __put_user_nocheck(data, addr, size) ({ \
register int __pu_ret; \
switch (size) { \
@@ -134,6 +142,46 @@ __asm__ __volatile__( \
int __put_user_bad(void);
+#define __get_kernel_nofault(dst, src, type, label) \
+do { \
+ type *addr = (type __force *)(src); \
+ register int __gu_ret; \
+ register unsigned long __gu_val; \
+ switch (sizeof(type)) { \
+ case 1: __get_kernel_asm(__gu_val, ub, addr, __gu_ret); break; \
+ case 2: __get_kernel_asm(__gu_val, uh, addr, __gu_ret); break; \
+ case 4: __get_kernel_asm(__gu_val, uw, addr, __gu_ret); break; \
+ case 8: __get_kernel_asm(__gu_val, x, addr, __gu_ret); break; \
+ default: \
+ __gu_val = 0; \
+ __gu_ret = __get_user_bad(); \
+ break; \
+ } \
+ if (__gu_ret) \
+ goto label; \
+ *(type *)dst = (__force type) __gu_val; \
+} while (0)
+#define __get_kernel_asm(x, size, addr, ret) \
+__asm__ __volatile__( \
+ "/* Get kernel asm, inline. */\n" \
+ "1:\t" "ld"#size " [%2], %1\n\t" \
+ "clr %0\n" \
+ "2:\n\n\t" \
+ ".section .fixup,#alloc,#execinstr\n\t" \
+ ".align 4\n" \
+ "3:\n\t" \
+ "sethi %%hi(2b), %0\n\t" \
+ "clr %1\n\t" \
+ "jmpl %0 + %%lo(2b), %%g0\n\t" \
+ " mov %3, %0\n\n\t" \
+ ".previous\n\t" \
+ ".section __ex_table,\"a\"\n\t" \
+ ".align 4\n\t" \
+ ".word 1b, 3b\n\n\t" \
+ ".previous\n\t" \
+ : "=r" (ret), "=r" (x) : "r" (__m(addr)), \
+ "i" (-EFAULT))
+
#define __get_user_nocheck(data, addr, size, type) ({ \
register int __gu_ret; \
register unsigned long __gu_val; \
diff --git a/arch/sparc/include/asm/vio.h b/arch/sparc/include/asm/vio.h
index 8a1a83bbb6d5..2d7bdf665fd3 100644
--- a/arch/sparc/include/asm/vio.h
+++ b/arch/sparc/include/asm/vio.h
@@ -70,7 +70,7 @@ struct vio_dring_register {
#define VIO_RX_DRING_DATA 0x0004
u16 resv;
u32 num_cookies;
- struct ldc_trans_cookie cookies[0];
+ struct ldc_trans_cookie cookies[];
};
struct vio_dring_unregister {
@@ -161,7 +161,7 @@ struct vio_disk_desc {
u64 size;
u32 ncookies;
u32 resv2;
- struct ldc_trans_cookie cookies[0];
+ struct ldc_trans_cookie cookies[];
};
#define VIO_DISK_VNAME_LEN 8
@@ -200,13 +200,13 @@ struct vio_disk_devid {
u16 resv;
u16 type;
u32 len;
- char id[0];
+ char id[];
};
struct vio_disk_efi {
u64 lba;
u64 len;
- char data[0];
+ char data[];
};
/* VIO net specific structures and defines */
@@ -246,7 +246,7 @@ struct vio_net_desc {
struct vio_dring_hdr hdr;
u32 size;
u32 ncookies;
- struct ldc_trans_cookie cookies[0];
+ struct ldc_trans_cookie cookies[];
};
struct vio_net_dext {
diff --git a/arch/sparc/include/asm/xor_32.h b/arch/sparc/include/asm/xor_32.h
index 3e5af37e4b9c..0351813cf3af 100644
--- a/arch/sparc/include/asm/xor_32.h
+++ b/arch/sparc/include/asm/xor_32.h
@@ -13,7 +13,8 @@
*/
static void
-sparc_2(unsigned long bytes, unsigned long *p1, unsigned long *p2)
+sparc_2(unsigned long bytes, unsigned long * __restrict p1,
+ const unsigned long * __restrict p2)
{
int lines = bytes / (sizeof (long)) / 8;
@@ -50,8 +51,9 @@ sparc_2(unsigned long bytes, unsigned long *p1, unsigned long *p2)
}
static void
-sparc_3(unsigned long bytes, unsigned long *p1, unsigned long *p2,
- unsigned long *p3)
+sparc_3(unsigned long bytes, unsigned long * __restrict p1,
+ const unsigned long * __restrict p2,
+ const unsigned long * __restrict p3)
{
int lines = bytes / (sizeof (long)) / 8;
@@ -101,8 +103,10 @@ sparc_3(unsigned long bytes, unsigned long *p1, unsigned long *p2,
}
static void
-sparc_4(unsigned long bytes, unsigned long *p1, unsigned long *p2,
- unsigned long *p3, unsigned long *p4)
+sparc_4(unsigned long bytes, unsigned long * __restrict p1,
+ const unsigned long * __restrict p2,
+ const unsigned long * __restrict p3,
+ const unsigned long * __restrict p4)
{
int lines = bytes / (sizeof (long)) / 8;
@@ -165,8 +169,11 @@ sparc_4(unsigned long bytes, unsigned long *p1, unsigned long *p2,
}
static void
-sparc_5(unsigned long bytes, unsigned long *p1, unsigned long *p2,
- unsigned long *p3, unsigned long *p4, unsigned long *p5)
+sparc_5(unsigned long bytes, unsigned long * __restrict p1,
+ const unsigned long * __restrict p2,
+ const unsigned long * __restrict p3,
+ const unsigned long * __restrict p4,
+ const unsigned long * __restrict p5)
{
int lines = bytes / (sizeof (long)) / 8;
diff --git a/arch/sparc/include/asm/xor_64.h b/arch/sparc/include/asm/xor_64.h
index 16169f3edcd5..caaddea8ad79 100644
--- a/arch/sparc/include/asm/xor_64.h
+++ b/arch/sparc/include/asm/xor_64.h
@@ -12,13 +12,20 @@
#include <asm/spitfire.h>
-void xor_vis_2(unsigned long, unsigned long *, unsigned long *);
-void xor_vis_3(unsigned long, unsigned long *, unsigned long *,
- unsigned long *);
-void xor_vis_4(unsigned long, unsigned long *, unsigned long *,
- unsigned long *, unsigned long *);
-void xor_vis_5(unsigned long, unsigned long *, unsigned long *,
- unsigned long *, unsigned long *, unsigned long *);
+void xor_vis_2(unsigned long bytes, unsigned long * __restrict p1,
+ const unsigned long * __restrict p2);
+void xor_vis_3(unsigned long bytes, unsigned long * __restrict p1,
+ const unsigned long * __restrict p2,
+ const unsigned long * __restrict p3);
+void xor_vis_4(unsigned long bytes, unsigned long * __restrict p1,
+ const unsigned long * __restrict p2,
+ const unsigned long * __restrict p3,
+ const unsigned long * __restrict p4);
+void xor_vis_5(unsigned long bytes, unsigned long * __restrict p1,
+ const unsigned long * __restrict p2,
+ const unsigned long * __restrict p3,
+ const unsigned long * __restrict p4,
+ const unsigned long * __restrict p5);
/* XXX Ugh, write cheetah versions... -DaveM */
@@ -30,13 +37,20 @@ static struct xor_block_template xor_block_VIS = {
.do_5 = xor_vis_5,
};
-void xor_niagara_2(unsigned long, unsigned long *, unsigned long *);
-void xor_niagara_3(unsigned long, unsigned long *, unsigned long *,
- unsigned long *);
-void xor_niagara_4(unsigned long, unsigned long *, unsigned long *,
- unsigned long *, unsigned long *);
-void xor_niagara_5(unsigned long, unsigned long *, unsigned long *,
- unsigned long *, unsigned long *, unsigned long *);
+void xor_niagara_2(unsigned long bytes, unsigned long * __restrict p1,
+ const unsigned long * __restrict p2);
+void xor_niagara_3(unsigned long bytes, unsigned long * __restrict p1,
+ const unsigned long * __restrict p2,
+ const unsigned long * __restrict p3);
+void xor_niagara_4(unsigned long bytes, unsigned long * __restrict p1,
+ const unsigned long * __restrict p2,
+ const unsigned long * __restrict p3,
+ const unsigned long * __restrict p4);
+void xor_niagara_5(unsigned long bytes, unsigned long * __restrict p1,
+ const unsigned long * __restrict p2,
+ const unsigned long * __restrict p3,
+ const unsigned long * __restrict p4,
+ const unsigned long * __restrict p5);
static struct xor_block_template xor_block_niagara = {
.name = "Niagara",
diff --git a/arch/sparc/include/uapi/asm/shmbuf.h b/arch/sparc/include/uapi/asm/shmbuf.h
index a5d7d8d681c4..ed4f061c7a15 100644
--- a/arch/sparc/include/uapi/asm/shmbuf.h
+++ b/arch/sparc/include/uapi/asm/shmbuf.h
@@ -2,6 +2,9 @@
#ifndef _SPARC_SHMBUF_H
#define _SPARC_SHMBUF_H
+#include <asm/ipcbuf.h>
+#include <asm/posix_types.h>
+
/*
* The shmid64_ds structure for sparc architecture.
* Note extra padding because this structure is passed back and forth
@@ -25,7 +28,7 @@ struct shmid64_ds {
unsigned long shm_ctime_high;
unsigned long shm_ctime; /* last change time */
#endif
- size_t shm_segsz; /* size of segment (bytes) */
+ __kernel_size_t shm_segsz; /* size of segment (bytes) */
__kernel_pid_t shm_cpid; /* pid of creator */
__kernel_pid_t shm_lpid; /* pid of last operator */
unsigned long shm_nattch; /* no. of current attaches */
diff --git a/arch/sparc/include/uapi/asm/signal.h b/arch/sparc/include/uapi/asm/signal.h
index 53758d53ac0e..b61382924725 100644
--- a/arch/sparc/include/uapi/asm/signal.h
+++ b/arch/sparc/include/uapi/asm/signal.h
@@ -151,6 +151,7 @@ struct sigstack {
#include <asm-generic/signal-defs.h>
+#include <asm/posix_types.h>
#ifndef __KERNEL__
struct __new_sigaction {
@@ -171,7 +172,7 @@ struct __old_sigaction {
typedef struct sigaltstack {
void __user *ss_sp;
int ss_flags;
- size_t ss_size;
+ __kernel_size_t ss_size;
} stack_t;
diff --git a/arch/sparc/include/uapi/asm/socket.h b/arch/sparc/include/uapi/asm/socket.h
index 2672dd03faf3..666f81e617ea 100644
--- a/arch/sparc/include/uapi/asm/socket.h
+++ b/arch/sparc/include/uapi/asm/socket.h
@@ -126,6 +126,8 @@
#define SO_RESERVE_MEM 0x0052
+#define SO_TXREHASH 0x0053
+
#if !defined(__KERNEL__)
diff --git a/arch/sparc/kernel/process_32.c b/arch/sparc/kernel/process_32.c
index 2dc0bf9fe62e..88c0c14aaff0 100644
--- a/arch/sparc/kernel/process_32.c
+++ b/arch/sparc/kernel/process_32.c
@@ -300,7 +300,6 @@ int copy_thread(unsigned long clone_flags, unsigned long sp, unsigned long arg,
extern int nwindows;
unsigned long psr;
memset(new_stack, 0, STACKFRAME_SZ + TRACEREG_SZ);
- p->thread.current_ds = KERNEL_DS;
ti->kpc = (((unsigned long) ret_from_kernel_thread) - 0x8);
childregs->u_regs[UREG_G1] = sp; /* function */
childregs->u_regs[UREG_G2] = arg;
@@ -311,7 +310,6 @@ int copy_thread(unsigned long clone_flags, unsigned long sp, unsigned long arg,
}
memcpy(new_stack, (char *)regs - STACKFRAME_SZ, STACKFRAME_SZ + TRACEREG_SZ);
childregs->u_regs[UREG_FP] = sp;
- p->thread.current_ds = USER_DS;
ti->kpc = (((unsigned long) ret_from_fork) - 0x8);
ti->kpsr = current->thread.fork_kpsr | PSR_PIL;
ti->kwim = current->thread.fork_kwim;
diff --git a/arch/sparc/kernel/process_64.c b/arch/sparc/kernel/process_64.c
index f5b2cac8669f..9a2ceb080ac9 100644
--- a/arch/sparc/kernel/process_64.c
+++ b/arch/sparc/kernel/process_64.c
@@ -106,18 +106,13 @@ static void show_regwindow32(struct pt_regs *regs)
{
struct reg_window32 __user *rw;
struct reg_window32 r_w;
- mm_segment_t old_fs;
__asm__ __volatile__ ("flushw");
rw = compat_ptr((unsigned int)regs->u_regs[14]);
- old_fs = get_fs();
- set_fs (USER_DS);
if (copy_from_user (&r_w, rw, sizeof(r_w))) {
- set_fs (old_fs);
return;
}
- set_fs (old_fs);
printk("l0: %08x l1: %08x l2: %08x l3: %08x "
"l4: %08x l5: %08x l6: %08x l7: %08x\n",
r_w.locals[0], r_w.locals[1], r_w.locals[2], r_w.locals[3],
@@ -136,7 +131,6 @@ static void show_regwindow(struct pt_regs *regs)
struct reg_window __user *rw;
struct reg_window *rwk;
struct reg_window r_w;
- mm_segment_t old_fs;
if ((regs->tstate & TSTATE_PRIV) || !(test_thread_flag(TIF_32BIT))) {
__asm__ __volatile__ ("flushw");
@@ -145,14 +139,10 @@ static void show_regwindow(struct pt_regs *regs)
rwk = (struct reg_window *)
(regs->u_regs[14] + STACK_BIAS);
if (!(regs->tstate & TSTATE_PRIV)) {
- old_fs = get_fs();
- set_fs (USER_DS);
if (copy_from_user (&r_w, rw, sizeof(r_w))) {
- set_fs (old_fs);
return;
}
rwk = &r_w;
- set_fs (old_fs);
}
} else {
show_regwindow32(regs);
@@ -598,7 +588,6 @@ int copy_thread(unsigned long clone_flags, unsigned long sp, unsigned long arg,
memset(child_trap_frame, 0, child_stack_sz);
__thread_flag_byte_ptr(t)[TI_FLAG_BYTE_CWP] =
(current_pt_regs()->tstate + 1) & TSTATE_CWP;
- t->current_ds = ASI_P;
t->kregs->u_regs[UREG_G1] = sp; /* function */
t->kregs->u_regs[UREG_G2] = arg;
return 0;
@@ -613,7 +602,6 @@ int copy_thread(unsigned long clone_flags, unsigned long sp, unsigned long arg,
t->kregs->u_regs[UREG_FP] = sp;
__thread_flag_byte_ptr(t)[TI_FLAG_BYTE_CWP] =
(regs->tstate + 1) & TSTATE_CWP;
- t->current_ds = ASI_AIUS;
if (sp != regs->u_regs[UREG_FP]) {
unsigned long csp;
diff --git a/arch/sparc/kernel/signal_32.c b/arch/sparc/kernel/signal_32.c
index ffab16369bea..74f80443b195 100644
--- a/arch/sparc/kernel/signal_32.c
+++ b/arch/sparc/kernel/signal_32.c
@@ -65,7 +65,7 @@ struct rt_signal_frame {
*/
static inline bool invalid_frame_pointer(void __user *fp, int fplen)
{
- if ((((unsigned long) fp) & 15) || !__access_ok((unsigned long)fp, fplen))
+ if ((((unsigned long) fp) & 15) || !access_ok(fp, fplen))
return true;
return false;
diff --git a/arch/sparc/kernel/sysfs.c b/arch/sparc/kernel/sysfs.c
index 6d60d416f0dd..f19487e4cc71 100644
--- a/arch/sparc/kernel/sysfs.c
+++ b/arch/sparc/kernel/sysfs.c
@@ -244,22 +244,10 @@ static void __init check_mmu_stats(void)
mmu_stats_supported = 1;
}
-static void register_nodes(void)
-{
-#ifdef CONFIG_NUMA
- int i;
-
- for (i = 0; i < MAX_NUMNODES; i++)
- register_one_node(i);
-#endif
-}
-
static int __init topology_init(void)
{
int cpu, ret;
- register_nodes();
-
check_mmu_stats();
for_each_possible_cpu(cpu) {
diff --git a/arch/sparc/kernel/traps_64.c b/arch/sparc/kernel/traps_64.c
index 21077821f427..5b4de4a89dec 100644
--- a/arch/sparc/kernel/traps_64.c
+++ b/arch/sparc/kernel/traps_64.c
@@ -2857,8 +2857,6 @@ void __init trap_init(void)
TI_PRE_COUNT != offsetof(struct thread_info,
preempt_count) ||
TI_NEW_CHILD != offsetof(struct thread_info, new_child) ||
- TI_CURRENT_DS != offsetof(struct thread_info,
- current_ds) ||
TI_KUNA_REGS != offsetof(struct thread_info,
kern_una_regs) ||
TI_KUNA_INSN != offsetof(struct thread_info,
diff --git a/arch/sparc/lib/NGmemcpy.S b/arch/sparc/lib/NGmemcpy.S
index 8e4d22a6ba0b..ee51c1230689 100644
--- a/arch/sparc/lib/NGmemcpy.S
+++ b/arch/sparc/lib/NGmemcpy.S
@@ -10,8 +10,7 @@
#include <asm/thread_info.h>
#define GLOBAL_SPARE %g7
#define RESTORE_ASI(TMP) \
- ldub [%g6 + TI_CURRENT_DS], TMP; \
- wr TMP, 0x0, %asi;
+ wr %g0, ASI_AIUS, %asi
#else
#define GLOBAL_SPARE %g5
#define RESTORE_ASI(TMP) \
diff --git a/arch/sparc/mm/hugetlbpage.c b/arch/sparc/mm/hugetlbpage.c
index 0f49fada2093..d8e0e3c7038d 100644
--- a/arch/sparc/mm/hugetlbpage.c
+++ b/arch/sparc/mm/hugetlbpage.c
@@ -181,6 +181,7 @@ pte_t arch_make_huge_pte(pte_t entry, unsigned int shift, vm_flags_t flags)
{
pte_t pte;
+ entry = pte_mkhuge(entry);
pte = hugepage_shift_to_tte(entry, shift);
#ifdef CONFIG_SPARC64
diff --git a/arch/sparc/mm/init_64.c b/arch/sparc/mm/init_64.c
index 1b23639e2fcd..8b1911591581 100644
--- a/arch/sparc/mm/init_64.c
+++ b/arch/sparc/mm/init_64.c
@@ -709,9 +709,10 @@ static void __init inherit_prom_mappings(void)
void prom_world(int enter)
{
- if (!enter)
- set_fs(get_fs());
-
+ /*
+ * No need to change the address space any more, just flush
+ * the register windows
+ */
__asm__ __volatile__("flushw");
}
diff --git a/arch/sparc/net/bpf_jit_comp_64.c b/arch/sparc/net/bpf_jit_comp_64.c
index b1e38784eb23..fa0759bfe498 100644
--- a/arch/sparc/net/bpf_jit_comp_64.c
+++ b/arch/sparc/net/bpf_jit_comp_64.c
@@ -1599,7 +1599,7 @@ skip_init_ctx:
if (bpf_jit_enable > 1)
bpf_jit_dump(prog->len, image_size, pass, ctx.image);
- bpf_flush_icache(header, (u8 *)header + (header->pages * PAGE_SIZE));
+ bpf_flush_icache(header, (u8 *)header + header->size);
if (!prog->is_func || extra_pass) {
bpf_jit_binary_lock_ro(header);
diff --git a/arch/um/include/asm/pgtable.h b/arch/um/include/asm/pgtable.h
index b9e20bbe2f75..167e236d9bb8 100644
--- a/arch/um/include/asm/pgtable.h
+++ b/arch/um/include/asm/pgtable.h
@@ -109,6 +109,7 @@ extern unsigned long end_iomem;
#define p4d_newpage(x) (p4d_val(x) & _PAGE_NEWPAGE)
#define p4d_mkuptodate(x) (p4d_val(x) &= ~_PAGE_NEWPAGE)
+#define pmd_pfn(pmd) (pmd_val(pmd) >> PAGE_SHIFT)
#define pmd_page(pmd) phys_to_page(pmd_val(pmd) & PAGE_MASK)
#define pte_page(x) pfn_to_page(pte_pfn(x))
diff --git a/arch/um/include/asm/uaccess.h b/arch/um/include/asm/uaccess.h
index 17d18cfd82a5..7d9d60e41e4e 100644
--- a/arch/um/include/asm/uaccess.h
+++ b/arch/um/include/asm/uaccess.h
@@ -25,7 +25,7 @@
extern unsigned long raw_copy_from_user(void *to, const void __user *from, unsigned long n);
extern unsigned long raw_copy_to_user(void __user *to, const void *from, unsigned long n);
extern unsigned long __clear_user(void __user *mem, unsigned long len);
-static inline int __access_ok(unsigned long addr, unsigned long size);
+static inline int __access_ok(const void __user *ptr, unsigned long size);
/* Teach asm-generic/uaccess.h that we have C functions for these. */
#define __access_ok __access_ok
@@ -36,16 +36,15 @@ static inline int __access_ok(unsigned long addr, unsigned long size);
#include <asm-generic/uaccess.h>
-static inline int __access_ok(unsigned long addr, unsigned long size)
+static inline int __access_ok(const void __user *ptr, unsigned long size)
{
+ unsigned long addr = (unsigned long)ptr;
return __addr_range_nowrap(addr, size) &&
(__under_task_size(addr, size) ||
__access_ok_vsyscall(addr, size));
}
/* no pagefaults for kernel addresses in um */
-#define HAVE_GET_KERNEL_NOFAULT 1
-
#define __get_kernel_nofault(dst, src, type, err_label) \
do { \
*((type *)dst) = get_unaligned((type *)(src)); \
diff --git a/arch/um/include/shared/net_kern.h b/arch/um/include/shared/net_kern.h
index 441a8a309329..67b2e9a1f2e5 100644
--- a/arch/um/include/shared/net_kern.h
+++ b/arch/um/include/shared/net_kern.h
@@ -39,7 +39,7 @@ struct uml_net_private {
void (*add_address)(unsigned char *, unsigned char *, void *);
void (*delete_address)(unsigned char *, unsigned char *, void *);
- char user[0];
+ char user[];
};
struct net_kern_info {
diff --git a/arch/um/os-Linux/execvp.c b/arch/um/os-Linux/execvp.c
index 84a0777c2a45..c09a5fd5e225 100644
--- a/arch/um/os-Linux/execvp.c
+++ b/arch/um/os-Linux/execvp.c
@@ -93,6 +93,7 @@ int execvp_noalloc(char *buf, const char *file, char *const argv[])
up finding no executable we can use, we want to diagnose
that we did find one but were denied access. */
got_eacces = 1;
+ break;
case ENOENT:
case ESTALE:
case ENOTDIR:
diff --git a/arch/x86/Kbuild b/arch/x86/Kbuild
index f384cb1a4f7a..5a83da703e87 100644
--- a/arch/x86/Kbuild
+++ b/arch/x86/Kbuild
@@ -1,4 +1,6 @@
# SPDX-License-Identifier: GPL-2.0
+obj-$(CONFIG_ARCH_HAS_CC_PLATFORM) += coco/
+
obj-y += entry/
obj-$(CONFIG_PERF_EVENTS) += events/
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index ebe8fc76949a..b037fe7be374 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -69,6 +69,7 @@ config X86
select ARCH_ENABLE_THP_MIGRATION if X86_64 && TRANSPARENT_HUGEPAGE
select ARCH_HAS_ACPI_TABLE_UPGRADE if ACPI
select ARCH_HAS_CACHE_LINE_SIZE
+ select ARCH_HAS_CURRENT_STACK_POINTER
select ARCH_HAS_DEBUG_VIRTUAL
select ARCH_HAS_DEBUG_VM_PGTABLE if !X86_PAE
select ARCH_HAS_DEVMEM_IS_ALLOWED
@@ -118,8 +119,10 @@ config X86
select ARCH_WANT_DEFAULT_BPF_JIT if X86_64
select ARCH_WANTS_DYNAMIC_TASK_STRUCT
select ARCH_WANTS_NO_INSTR
+ select ARCH_WANT_GENERAL_HUGETLB
select ARCH_WANT_HUGE_PMD_SHARE
select ARCH_WANT_LD_ORPHAN_WARN
+ select ARCH_WANTS_RT_DELAYED_SIGNALS
select ARCH_WANTS_THP_SWAP if X86_64
select ARCH_HAS_PARANOID_L1D_FLUSH
select BUILDTIME_TABLE_SORT
@@ -158,6 +161,7 @@ config X86
select HAVE_ALIGNED_STRUCT_PAGE if SLUB
select HAVE_ARCH_AUDITSYSCALL
select HAVE_ARCH_HUGE_VMAP if X86_64 || X86_PAE
+ select HAVE_ARCH_HUGE_VMALLOC if X86_64
select HAVE_ARCH_JUMP_LABEL
select HAVE_ARCH_JUMP_LABEL_RELATIVE
select HAVE_ARCH_KASAN if X86_64
@@ -186,6 +190,7 @@ config X86
select HAVE_CONTEXT_TRACKING_OFFSTACK if HAVE_CONTEXT_TRACKING
select HAVE_C_RECORDMCOUNT
select HAVE_OBJTOOL_MCOUNT if STACK_VALIDATION
+ select HAVE_BUILDTIME_MCOUNT_SORT
select HAVE_DEBUG_KMEMLEAK
select HAVE_DMA_CONTIGUOUS
select HAVE_DYNAMIC_FTRACE
@@ -245,7 +250,7 @@ config X86
select HAVE_STACK_VALIDATION if X86_64
select HAVE_STATIC_CALL
select HAVE_STATIC_CALL_INLINE if HAVE_STACK_VALIDATION
- select HAVE_PREEMPT_DYNAMIC
+ select HAVE_PREEMPT_DYNAMIC_CALL
select HAVE_RSEQ
select HAVE_SYSCALL_TRACEPOINTS
select HAVE_UNSTABLE_SCHED_CLOCK
@@ -346,9 +351,6 @@ config ARCH_NR_GPIO
config ARCH_SUSPEND_POSSIBLE
def_bool y
-config ARCH_WANT_GENERAL_HUGETLB
- def_bool y
-
config AUDIT_ARCH
def_bool y if X86_64
@@ -1274,23 +1276,6 @@ config TOSHIBA
Say Y if you intend to run this kernel on a Toshiba portable.
Say N otherwise.
-config I8K
- tristate "Dell i8k legacy laptop support"
- depends on HWMON
- depends on PROC_FS
- select SENSORS_DELL_SMM
- help
- This option enables legacy /proc/i8k userspace interface in hwmon
- dell-smm-hwmon driver. Character file /proc/i8k reports bios version,
- temperature and allows controlling fan speeds of Dell laptops via
- System Management Mode. For old Dell laptops (like Dell Inspiron 8000)
- it reports also power and hotkey status. For fan speed control is
- needed userspace package i8kutils.
-
- Say Y if you intend to run this kernel on old Dell laptops or want to
- use userspace package i8kutils.
- Say N otherwise.
-
config X86_REBOOTFIXUPS
bool "Enable X86 board specific fixups for reboot"
depends on X86_32
@@ -1637,7 +1622,7 @@ config ARCH_SPARSEMEM_DEFAULT
config ARCH_SELECT_MEMORY_MODEL
def_bool y
- depends on ARCH_SPARSEMEM_ENABLE
+ depends on ARCH_SPARSEMEM_ENABLE && ARCH_FLATMEM_ENABLE
config ARCH_MEMORY_PROBE
bool "Enable sysfs memory/probe interface"
diff --git a/arch/x86/boot/compressed/head_32.S b/arch/x86/boot/compressed/head_32.S
index 659fad53ca82..3b354eb9516d 100644
--- a/arch/x86/boot/compressed/head_32.S
+++ b/arch/x86/boot/compressed/head_32.S
@@ -152,14 +152,13 @@ SYM_FUNC_END(startup_32)
#ifdef CONFIG_EFI_STUB
SYM_FUNC_START(efi32_stub_entry)
-SYM_FUNC_START_ALIAS(efi_stub_entry)
add $0x4, %esp
movl 8(%esp), %esi /* save boot_params pointer */
call efi_main
/* efi_main returns the possibly relocated address of startup_32 */
jmp *%eax
SYM_FUNC_END(efi32_stub_entry)
-SYM_FUNC_END_ALIAS(efi_stub_entry)
+SYM_FUNC_ALIAS(efi_stub_entry, efi32_stub_entry)
#endif
.text
diff --git a/arch/x86/boot/compressed/head_64.S b/arch/x86/boot/compressed/head_64.S
index fd9441f40457..dea95301196b 100644
--- a/arch/x86/boot/compressed/head_64.S
+++ b/arch/x86/boot/compressed/head_64.S
@@ -535,7 +535,6 @@ SYM_CODE_END(startup_64)
#ifdef CONFIG_EFI_STUB
.org 0x390
SYM_FUNC_START(efi64_stub_entry)
-SYM_FUNC_START_ALIAS(efi_stub_entry)
and $~0xf, %rsp /* realign the stack */
movq %rdx, %rbx /* save boot_params pointer */
call efi_main
@@ -543,7 +542,7 @@ SYM_FUNC_START_ALIAS(efi_stub_entry)
leaq rva(startup_64)(%rax), %rax
jmp *%rax
SYM_FUNC_END(efi64_stub_entry)
-SYM_FUNC_END_ALIAS(efi_stub_entry)
+SYM_FUNC_ALIAS(efi_stub_entry, efi64_stub_entry)
#endif
.text
diff --git a/arch/x86/coco/Makefile b/arch/x86/coco/Makefile
new file mode 100644
index 000000000000..c1ead00017a7
--- /dev/null
+++ b/arch/x86/coco/Makefile
@@ -0,0 +1,6 @@
+# SPDX-License-Identifier: GPL-2.0
+CFLAGS_REMOVE_core.o = -pg
+KASAN_SANITIZE_core.o := n
+CFLAGS_core.o += -fno-stack-protector
+
+obj-y += core.o
diff --git a/arch/x86/kernel/cc_platform.c b/arch/x86/coco/core.c
index 6a6ffcd978f6..fc1365dd927e 100644
--- a/arch/x86/kernel/cc_platform.c
+++ b/arch/x86/coco/core.c
@@ -9,18 +9,16 @@
#include <linux/export.h>
#include <linux/cc_platform.h>
-#include <linux/mem_encrypt.h>
-#include <asm/mshyperv.h>
+#include <asm/coco.h>
#include <asm/processor.h>
-static bool __maybe_unused intel_cc_platform_has(enum cc_attr attr)
+static enum cc_vendor vendor __ro_after_init;
+static u64 cc_mask __ro_after_init;
+
+static bool intel_cc_platform_has(enum cc_attr attr)
{
-#ifdef CONFIG_INTEL_TDX_GUEST
- return false;
-#else
return false;
-#endif
}
/*
@@ -74,12 +72,46 @@ static bool hyperv_cc_platform_has(enum cc_attr attr)
bool cc_platform_has(enum cc_attr attr)
{
- if (sme_me_mask)
+ switch (vendor) {
+ case CC_VENDOR_AMD:
return amd_cc_platform_has(attr);
-
- if (hv_is_isolation_supported())
+ case CC_VENDOR_INTEL:
+ return intel_cc_platform_has(attr);
+ case CC_VENDOR_HYPERV:
return hyperv_cc_platform_has(attr);
-
- return false;
+ default:
+ return false;
+ }
}
EXPORT_SYMBOL_GPL(cc_platform_has);
+
+u64 cc_mkenc(u64 val)
+{
+ switch (vendor) {
+ case CC_VENDOR_AMD:
+ return val | cc_mask;
+ default:
+ return val;
+ }
+}
+
+u64 cc_mkdec(u64 val)
+{
+ switch (vendor) {
+ case CC_VENDOR_AMD:
+ return val & ~cc_mask;
+ default:
+ return val;
+ }
+}
+EXPORT_SYMBOL_GPL(cc_mkdec);
+
+__init void cc_set_vendor(enum cc_vendor v)
+{
+ vendor = v;
+}
+
+__init void cc_set_mask(u64 mask)
+{
+ cc_mask = mask;
+}
diff --git a/arch/x86/crypto/Makefile b/arch/x86/crypto/Makefile
index c3af959648e6..2831685adf6f 100644
--- a/arch/x86/crypto/Makefile
+++ b/arch/x86/crypto/Makefile
@@ -90,6 +90,9 @@ nhpoly1305-avx2-y := nh-avx2-x86_64.o nhpoly1305-avx2-glue.o
obj-$(CONFIG_CRYPTO_CURVE25519_X86) += curve25519-x86_64.o
+obj-$(CONFIG_CRYPTO_SM3_AVX_X86_64) += sm3-avx-x86_64.o
+sm3-avx-x86_64-y := sm3-avx-asm_64.o sm3_avx_glue.o
+
obj-$(CONFIG_CRYPTO_SM4_AESNI_AVX_X86_64) += sm4-aesni-avx-x86_64.o
sm4-aesni-avx-x86_64-y := sm4-aesni-avx-asm_64.o sm4_aesni_avx_glue.o
diff --git a/arch/x86/crypto/aes_ctrby8_avx-x86_64.S b/arch/x86/crypto/aes_ctrby8_avx-x86_64.S
index c799838242a6..43852ba6e19c 100644
--- a/arch/x86/crypto/aes_ctrby8_avx-x86_64.S
+++ b/arch/x86/crypto/aes_ctrby8_avx-x86_64.S
@@ -1,65 +1,22 @@
+/* SPDX-License-Identifier: GPL-2.0-only OR BSD-3-Clause */
/*
- * Implement AES CTR mode by8 optimization with AVX instructions. (x86_64)
- *
- * This is AES128/192/256 CTR mode optimization implementation. It requires
- * the support of Intel(R) AESNI and AVX instructions.
- *
- * This work was inspired by the AES CTR mode optimization published
- * in Intel Optimized IPSEC Cryptograhpic library.
- * Additional information on it can be found at:
- * http://downloadcenter.intel.com/Detail_Desc.aspx?agr=Y&DwnldID=22972
- *
- * This file is provided under a dual BSD/GPLv2 license. When using or
- * redistributing this file, you may do so under either license.
- *
- * GPL LICENSE SUMMARY
+ * AES CTR mode by8 optimization with AVX instructions. (x86_64)
*
* Copyright(c) 2014 Intel Corporation.
*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
* Contact Information:
* James Guilford <james.guilford@intel.com>
* Sean Gulley <sean.m.gulley@intel.com>
* Chandramouli Narayanan <mouli@linux.intel.com>
+ */
+/*
+ * This is AES128/192/256 CTR mode optimization implementation. It requires
+ * the support of Intel(R) AESNI and AVX instructions.
*
- * BSD LICENSE
- *
- * Copyright(c) 2014 Intel Corporation.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- * Neither the name of Intel Corporation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY 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 work was inspired by the AES CTR mode optimization published
+ * in Intel Optimized IPSEC Cryptographic library.
+ * Additional information on it can be found at:
+ * https://github.com/intel/intel-ipsec-mb
*/
#include <linux/linkage.h>
diff --git a/arch/x86/crypto/aesni-intel_asm.S b/arch/x86/crypto/aesni-intel_asm.S
index 363699dd7220..837c1e0aa021 100644
--- a/arch/x86/crypto/aesni-intel_asm.S
+++ b/arch/x86/crypto/aesni-intel_asm.S
@@ -1751,8 +1751,6 @@ SYM_FUNC_END(aesni_gcm_finalize)
#endif
-
-SYM_FUNC_START_LOCAL_ALIAS(_key_expansion_128)
SYM_FUNC_START_LOCAL(_key_expansion_256a)
pshufd $0b11111111, %xmm1, %xmm1
shufps $0b00010000, %xmm0, %xmm4
@@ -1764,7 +1762,7 @@ SYM_FUNC_START_LOCAL(_key_expansion_256a)
add $0x10, TKEYP
RET
SYM_FUNC_END(_key_expansion_256a)
-SYM_FUNC_END_ALIAS(_key_expansion_128)
+SYM_FUNC_ALIAS_LOCAL(_key_expansion_128, _key_expansion_256a)
SYM_FUNC_START_LOCAL(_key_expansion_192a)
pshufd $0b01010101, %xmm1, %xmm1
diff --git a/arch/x86/crypto/blake2s-shash.c b/arch/x86/crypto/blake2s-shash.c
index f9e2fecdb761..59ae28abe35c 100644
--- a/arch/x86/crypto/blake2s-shash.c
+++ b/arch/x86/crypto/blake2s-shash.c
@@ -18,12 +18,12 @@
static int crypto_blake2s_update_x86(struct shash_desc *desc,
const u8 *in, unsigned int inlen)
{
- return crypto_blake2s_update(desc, in, inlen, blake2s_compress);
+ return crypto_blake2s_update(desc, in, inlen, false);
}
static int crypto_blake2s_final_x86(struct shash_desc *desc, u8 *out)
{
- return crypto_blake2s_final(desc, out, blake2s_compress);
+ return crypto_blake2s_final(desc, out, false);
}
#define BLAKE2S_ALG(name, driver_name, digest_size) \
diff --git a/arch/x86/crypto/blowfish_glue.c b/arch/x86/crypto/blowfish_glue.c
index a880e0b1c255..fda6066437aa 100644
--- a/arch/x86/crypto/blowfish_glue.c
+++ b/arch/x86/crypto/blowfish_glue.c
@@ -32,24 +32,12 @@ static inline void blowfish_enc_blk(struct bf_ctx *ctx, u8 *dst, const u8 *src)
__blowfish_enc_blk(ctx, dst, src, false);
}
-static inline void blowfish_enc_blk_xor(struct bf_ctx *ctx, u8 *dst,
- const u8 *src)
-{
- __blowfish_enc_blk(ctx, dst, src, true);
-}
-
static inline void blowfish_enc_blk_4way(struct bf_ctx *ctx, u8 *dst,
const u8 *src)
{
__blowfish_enc_blk_4way(ctx, dst, src, false);
}
-static inline void blowfish_enc_blk_xor_4way(struct bf_ctx *ctx, u8 *dst,
- const u8 *src)
-{
- __blowfish_enc_blk_4way(ctx, dst, src, true);
-}
-
static void blowfish_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
{
blowfish_enc_blk(crypto_tfm_ctx(tfm), dst, src);
diff --git a/arch/x86/crypto/des3_ede_glue.c b/arch/x86/crypto/des3_ede_glue.c
index 787c234d2469..abb8b1fe123b 100644
--- a/arch/x86/crypto/des3_ede_glue.c
+++ b/arch/x86/crypto/des3_ede_glue.c
@@ -45,14 +45,6 @@ static inline void des3_ede_dec_blk(struct des3_ede_x86_ctx *ctx, u8 *dst,
des3_ede_x86_64_crypt_blk(dec_ctx, dst, src);
}
-static inline void des3_ede_enc_blk_3way(struct des3_ede_x86_ctx *ctx, u8 *dst,
- const u8 *src)
-{
- u32 *enc_ctx = ctx->enc.expkey;
-
- des3_ede_x86_64_crypt_blk_3way(enc_ctx, dst, src);
-}
-
static inline void des3_ede_dec_blk_3way(struct des3_ede_x86_ctx *ctx, u8 *dst,
const u8 *src)
{
diff --git a/arch/x86/crypto/sm3-avx-asm_64.S b/arch/x86/crypto/sm3-avx-asm_64.S
new file mode 100644
index 000000000000..71e6aae23e17
--- /dev/null
+++ b/arch/x86/crypto/sm3-avx-asm_64.S
@@ -0,0 +1,517 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * SM3 AVX accelerated transform.
+ * specified in: https://datatracker.ietf.org/doc/html/draft-sca-cfrg-sm3-02
+ *
+ * Copyright (C) 2021 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ * Copyright (C) 2021 Tianjia Zhang <tianjia.zhang@linux.alibaba.com>
+ */
+
+/* Based on SM3 AES/BMI2 accelerated work by libgcrypt at:
+ * https://gnupg.org/software/libgcrypt/index.html
+ */
+
+#include <linux/linkage.h>
+#include <asm/frame.h>
+
+/* Context structure */
+
+#define state_h0 0
+#define state_h1 4
+#define state_h2 8
+#define state_h3 12
+#define state_h4 16
+#define state_h5 20
+#define state_h6 24
+#define state_h7 28
+
+/* Constants */
+
+/* Round constant macros */
+
+#define K0 2043430169 /* 0x79cc4519 */
+#define K1 -208106958 /* 0xf3988a32 */
+#define K2 -416213915 /* 0xe7311465 */
+#define K3 -832427829 /* 0xce6228cb */
+#define K4 -1664855657 /* 0x9cc45197 */
+#define K5 965255983 /* 0x3988a32f */
+#define K6 1930511966 /* 0x7311465e */
+#define K7 -433943364 /* 0xe6228cbc */
+#define K8 -867886727 /* 0xcc451979 */
+#define K9 -1735773453 /* 0x988a32f3 */
+#define K10 823420391 /* 0x311465e7 */
+#define K11 1646840782 /* 0x6228cbce */
+#define K12 -1001285732 /* 0xc451979c */
+#define K13 -2002571463 /* 0x88a32f39 */
+#define K14 289824371 /* 0x11465e73 */
+#define K15 579648742 /* 0x228cbce6 */
+#define K16 -1651869049 /* 0x9d8a7a87 */
+#define K17 991229199 /* 0x3b14f50f */
+#define K18 1982458398 /* 0x7629ea1e */
+#define K19 -330050500 /* 0xec53d43c */
+#define K20 -660100999 /* 0xd8a7a879 */
+#define K21 -1320201997 /* 0xb14f50f3 */
+#define K22 1654563303 /* 0x629ea1e7 */
+#define K23 -985840690 /* 0xc53d43ce */
+#define K24 -1971681379 /* 0x8a7a879d */
+#define K25 351604539 /* 0x14f50f3b */
+#define K26 703209078 /* 0x29ea1e76 */
+#define K27 1406418156 /* 0x53d43cec */
+#define K28 -1482130984 /* 0xa7a879d8 */
+#define K29 1330705329 /* 0x4f50f3b1 */
+#define K30 -1633556638 /* 0x9ea1e762 */
+#define K31 1027854021 /* 0x3d43cec5 */
+#define K32 2055708042 /* 0x7a879d8a */
+#define K33 -183551212 /* 0xf50f3b14 */
+#define K34 -367102423 /* 0xea1e7629 */
+#define K35 -734204845 /* 0xd43cec53 */
+#define K36 -1468409689 /* 0xa879d8a7 */
+#define K37 1358147919 /* 0x50f3b14f */
+#define K38 -1578671458 /* 0xa1e7629e */
+#define K39 1137624381 /* 0x43cec53d */
+#define K40 -2019718534 /* 0x879d8a7a */
+#define K41 255530229 /* 0x0f3b14f5 */
+#define K42 511060458 /* 0x1e7629ea */
+#define K43 1022120916 /* 0x3cec53d4 */
+#define K44 2044241832 /* 0x79d8a7a8 */
+#define K45 -206483632 /* 0xf3b14f50 */
+#define K46 -412967263 /* 0xe7629ea1 */
+#define K47 -825934525 /* 0xcec53d43 */
+#define K48 -1651869049 /* 0x9d8a7a87 */
+#define K49 991229199 /* 0x3b14f50f */
+#define K50 1982458398 /* 0x7629ea1e */
+#define K51 -330050500 /* 0xec53d43c */
+#define K52 -660100999 /* 0xd8a7a879 */
+#define K53 -1320201997 /* 0xb14f50f3 */
+#define K54 1654563303 /* 0x629ea1e7 */
+#define K55 -985840690 /* 0xc53d43ce */
+#define K56 -1971681379 /* 0x8a7a879d */
+#define K57 351604539 /* 0x14f50f3b */
+#define K58 703209078 /* 0x29ea1e76 */
+#define K59 1406418156 /* 0x53d43cec */
+#define K60 -1482130984 /* 0xa7a879d8 */
+#define K61 1330705329 /* 0x4f50f3b1 */
+#define K62 -1633556638 /* 0x9ea1e762 */
+#define K63 1027854021 /* 0x3d43cec5 */
+
+/* Register macros */
+
+#define RSTATE %rdi
+#define RDATA %rsi
+#define RNBLKS %rdx
+
+#define t0 %eax
+#define t1 %ebx
+#define t2 %ecx
+
+#define a %r8d
+#define b %r9d
+#define c %r10d
+#define d %r11d
+#define e %r12d
+#define f %r13d
+#define g %r14d
+#define h %r15d
+
+#define W0 %xmm0
+#define W1 %xmm1
+#define W2 %xmm2
+#define W3 %xmm3
+#define W4 %xmm4
+#define W5 %xmm5
+
+#define XTMP0 %xmm6
+#define XTMP1 %xmm7
+#define XTMP2 %xmm8
+#define XTMP3 %xmm9
+#define XTMP4 %xmm10
+#define XTMP5 %xmm11
+#define XTMP6 %xmm12
+
+#define BSWAP_REG %xmm15
+
+/* Stack structure */
+
+#define STACK_W_SIZE (32 * 2 * 3)
+#define STACK_REG_SAVE_SIZE (64)
+
+#define STACK_W (0)
+#define STACK_REG_SAVE (STACK_W + STACK_W_SIZE)
+#define STACK_SIZE (STACK_REG_SAVE + STACK_REG_SAVE_SIZE)
+
+/* Instruction helpers. */
+
+#define roll2(v, reg) \
+ roll $(v), reg;
+
+#define roll3mov(v, src, dst) \
+ movl src, dst; \
+ roll $(v), dst;
+
+#define roll3(v, src, dst) \
+ rorxl $(32-(v)), src, dst;
+
+#define addl2(a, out) \
+ leal (a, out), out;
+
+/* Round function macros. */
+
+#define GG1(x, y, z, o, t) \
+ movl x, o; \
+ xorl y, o; \
+ xorl z, o;
+
+#define FF1(x, y, z, o, t) GG1(x, y, z, o, t)
+
+#define GG2(x, y, z, o, t) \
+ andnl z, x, o; \
+ movl y, t; \
+ andl x, t; \
+ addl2(t, o);
+
+#define FF2(x, y, z, o, t) \
+ movl y, o; \
+ xorl x, o; \
+ movl y, t; \
+ andl x, t; \
+ andl z, o; \
+ xorl t, o;
+
+#define R(i, a, b, c, d, e, f, g, h, round, widx, wtype) \
+ /* rol(a, 12) => t0 */ \
+ roll3mov(12, a, t0); /* rorxl here would reduce perf by 6% on zen3 */ \
+ /* rol (t0 + e + t), 7) => t1 */ \
+ leal K##round(t0, e, 1), t1; \
+ roll2(7, t1); \
+ /* h + w1 => h */ \
+ addl wtype##_W1_ADDR(round, widx), h; \
+ /* h + t1 => h */ \
+ addl2(t1, h); \
+ /* t1 ^ t0 => t0 */ \
+ xorl t1, t0; \
+ /* w1w2 + d => d */ \
+ addl wtype##_W1W2_ADDR(round, widx), d; \
+ /* FF##i(a,b,c) => t1 */ \
+ FF##i(a, b, c, t1, t2); \
+ /* d + t1 => d */ \
+ addl2(t1, d); \
+ /* GG#i(e,f,g) => t2 */ \
+ GG##i(e, f, g, t2, t1); \
+ /* h + t2 => h */ \
+ addl2(t2, h); \
+ /* rol (f, 19) => f */ \
+ roll2(19, f); \
+ /* d + t0 => d */ \
+ addl2(t0, d); \
+ /* rol (b, 9) => b */ \
+ roll2(9, b); \
+ /* P0(h) => h */ \
+ roll3(9, h, t2); \
+ roll3(17, h, t1); \
+ xorl t2, h; \
+ xorl t1, h;
+
+#define R1(a, b, c, d, e, f, g, h, round, widx, wtype) \
+ R(1, a, b, c, d, e, f, g, h, round, widx, wtype)
+
+#define R2(a, b, c, d, e, f, g, h, round, widx, wtype) \
+ R(2, a, b, c, d, e, f, g, h, round, widx, wtype)
+
+/* Input expansion macros. */
+
+/* Byte-swapped input address. */
+#define IW_W_ADDR(round, widx, offs) \
+ (STACK_W + ((round) / 4) * 64 + (offs) + ((widx) * 4))(%rsp)
+
+/* Expanded input address. */
+#define XW_W_ADDR(round, widx, offs) \
+ (STACK_W + ((((round) / 3) - 4) % 2) * 64 + (offs) + ((widx) * 4))(%rsp)
+
+/* Rounds 1-12, byte-swapped input block addresses. */
+#define IW_W1_ADDR(round, widx) IW_W_ADDR(round, widx, 0)
+#define IW_W1W2_ADDR(round, widx) IW_W_ADDR(round, widx, 32)
+
+/* Rounds 1-12, expanded input block addresses. */
+#define XW_W1_ADDR(round, widx) XW_W_ADDR(round, widx, 0)
+#define XW_W1W2_ADDR(round, widx) XW_W_ADDR(round, widx, 32)
+
+/* Input block loading. */
+#define LOAD_W_XMM_1() \
+ vmovdqu 0*16(RDATA), XTMP0; /* XTMP0: w3, w2, w1, w0 */ \
+ vmovdqu 1*16(RDATA), XTMP1; /* XTMP1: w7, w6, w5, w4 */ \
+ vmovdqu 2*16(RDATA), XTMP2; /* XTMP2: w11, w10, w9, w8 */ \
+ vmovdqu 3*16(RDATA), XTMP3; /* XTMP3: w15, w14, w13, w12 */ \
+ vpshufb BSWAP_REG, XTMP0, XTMP0; \
+ vpshufb BSWAP_REG, XTMP1, XTMP1; \
+ vpshufb BSWAP_REG, XTMP2, XTMP2; \
+ vpshufb BSWAP_REG, XTMP3, XTMP3; \
+ vpxor XTMP0, XTMP1, XTMP4; \
+ vpxor XTMP1, XTMP2, XTMP5; \
+ vpxor XTMP2, XTMP3, XTMP6; \
+ leaq 64(RDATA), RDATA; \
+ vmovdqa XTMP0, IW_W1_ADDR(0, 0); \
+ vmovdqa XTMP4, IW_W1W2_ADDR(0, 0); \
+ vmovdqa XTMP1, IW_W1_ADDR(4, 0); \
+ vmovdqa XTMP5, IW_W1W2_ADDR(4, 0);
+
+#define LOAD_W_XMM_2() \
+ vmovdqa XTMP2, IW_W1_ADDR(8, 0); \
+ vmovdqa XTMP6, IW_W1W2_ADDR(8, 0);
+
+#define LOAD_W_XMM_3() \
+ vpshufd $0b00000000, XTMP0, W0; /* W0: xx, w0, xx, xx */ \
+ vpshufd $0b11111001, XTMP0, W1; /* W1: xx, w3, w2, w1 */ \
+ vmovdqa XTMP1, W2; /* W2: xx, w6, w5, w4 */ \
+ vpalignr $12, XTMP1, XTMP2, W3; /* W3: xx, w9, w8, w7 */ \
+ vpalignr $8, XTMP2, XTMP3, W4; /* W4: xx, w12, w11, w10 */ \
+ vpshufd $0b11111001, XTMP3, W5; /* W5: xx, w15, w14, w13 */
+
+/* Message scheduling. Note: 3 words per XMM register. */
+#define SCHED_W_0(round, w0, w1, w2, w3, w4, w5) \
+ /* Load (w[i - 16]) => XTMP0 */ \
+ vpshufd $0b10111111, w0, XTMP0; \
+ vpalignr $12, XTMP0, w1, XTMP0; /* XTMP0: xx, w2, w1, w0 */ \
+ /* Load (w[i - 13]) => XTMP1 */ \
+ vpshufd $0b10111111, w1, XTMP1; \
+ vpalignr $12, XTMP1, w2, XTMP1; \
+ /* w[i - 9] == w3 */ \
+ /* XMM3 ^ XTMP0 => XTMP0 */ \
+ vpxor w3, XTMP0, XTMP0;
+
+#define SCHED_W_1(round, w0, w1, w2, w3, w4, w5) \
+ /* w[i - 3] == w5 */ \
+ /* rol(XMM5, 15) ^ XTMP0 => XTMP0 */ \
+ vpslld $15, w5, XTMP2; \
+ vpsrld $(32-15), w5, XTMP3; \
+ vpxor XTMP2, XTMP3, XTMP3; \
+ vpxor XTMP3, XTMP0, XTMP0; \
+ /* rol(XTMP1, 7) => XTMP1 */ \
+ vpslld $7, XTMP1, XTMP5; \
+ vpsrld $(32-7), XTMP1, XTMP1; \
+ vpxor XTMP5, XTMP1, XTMP1; \
+ /* XMM4 ^ XTMP1 => XTMP1 */ \
+ vpxor w4, XTMP1, XTMP1; \
+ /* w[i - 6] == XMM4 */ \
+ /* P1(XTMP0) ^ XTMP1 => XMM0 */ \
+ vpslld $15, XTMP0, XTMP5; \
+ vpsrld $(32-15), XTMP0, XTMP6; \
+ vpslld $23, XTMP0, XTMP2; \
+ vpsrld $(32-23), XTMP0, XTMP3; \
+ vpxor XTMP0, XTMP1, XTMP1; \
+ vpxor XTMP6, XTMP5, XTMP5; \
+ vpxor XTMP3, XTMP2, XTMP2; \
+ vpxor XTMP2, XTMP5, XTMP5; \
+ vpxor XTMP5, XTMP1, w0;
+
+#define SCHED_W_2(round, w0, w1, w2, w3, w4, w5) \
+ /* W1 in XMM12 */ \
+ vpshufd $0b10111111, w4, XTMP4; \
+ vpalignr $12, XTMP4, w5, XTMP4; \
+ vmovdqa XTMP4, XW_W1_ADDR((round), 0); \
+ /* W1 ^ W2 => XTMP1 */ \
+ vpxor w0, XTMP4, XTMP1; \
+ vmovdqa XTMP1, XW_W1W2_ADDR((round), 0);
+
+
+.section .rodata.cst16, "aM", @progbits, 16
+.align 16
+
+.Lbe32mask:
+ .long 0x00010203, 0x04050607, 0x08090a0b, 0x0c0d0e0f
+
+.text
+
+/*
+ * Transform nblocks*64 bytes (nblocks*16 32-bit words) at DATA.
+ *
+ * void sm3_transform_avx(struct sm3_state *state,
+ * const u8 *data, int nblocks);
+ */
+.align 16
+SYM_FUNC_START(sm3_transform_avx)
+ /* input:
+ * %rdi: ctx, CTX
+ * %rsi: data (64*nblks bytes)
+ * %rdx: nblocks
+ */
+ vzeroupper;
+
+ pushq %rbp;
+ movq %rsp, %rbp;
+
+ movq %rdx, RNBLKS;
+
+ subq $STACK_SIZE, %rsp;
+ andq $(~63), %rsp;
+
+ movq %rbx, (STACK_REG_SAVE + 0 * 8)(%rsp);
+ movq %r15, (STACK_REG_SAVE + 1 * 8)(%rsp);
+ movq %r14, (STACK_REG_SAVE + 2 * 8)(%rsp);
+ movq %r13, (STACK_REG_SAVE + 3 * 8)(%rsp);
+ movq %r12, (STACK_REG_SAVE + 4 * 8)(%rsp);
+
+ vmovdqa .Lbe32mask (%rip), BSWAP_REG;
+
+ /* Get the values of the chaining variables. */
+ movl state_h0(RSTATE), a;
+ movl state_h1(RSTATE), b;
+ movl state_h2(RSTATE), c;
+ movl state_h3(RSTATE), d;
+ movl state_h4(RSTATE), e;
+ movl state_h5(RSTATE), f;
+ movl state_h6(RSTATE), g;
+ movl state_h7(RSTATE), h;
+
+.align 16
+.Loop:
+ /* Load data part1. */
+ LOAD_W_XMM_1();
+
+ leaq -1(RNBLKS), RNBLKS;
+
+ /* Transform 0-3 + Load data part2. */
+ R1(a, b, c, d, e, f, g, h, 0, 0, IW); LOAD_W_XMM_2();
+ R1(d, a, b, c, h, e, f, g, 1, 1, IW);
+ R1(c, d, a, b, g, h, e, f, 2, 2, IW);
+ R1(b, c, d, a, f, g, h, e, 3, 3, IW); LOAD_W_XMM_3();
+
+ /* Transform 4-7 + Precalc 12-14. */
+ R1(a, b, c, d, e, f, g, h, 4, 0, IW);
+ R1(d, a, b, c, h, e, f, g, 5, 1, IW);
+ R1(c, d, a, b, g, h, e, f, 6, 2, IW); SCHED_W_0(12, W0, W1, W2, W3, W4, W5);
+ R1(b, c, d, a, f, g, h, e, 7, 3, IW); SCHED_W_1(12, W0, W1, W2, W3, W4, W5);
+
+ /* Transform 8-11 + Precalc 12-17. */
+ R1(a, b, c, d, e, f, g, h, 8, 0, IW); SCHED_W_2(12, W0, W1, W2, W3, W4, W5);
+ R1(d, a, b, c, h, e, f, g, 9, 1, IW); SCHED_W_0(15, W1, W2, W3, W4, W5, W0);
+ R1(c, d, a, b, g, h, e, f, 10, 2, IW); SCHED_W_1(15, W1, W2, W3, W4, W5, W0);
+ R1(b, c, d, a, f, g, h, e, 11, 3, IW); SCHED_W_2(15, W1, W2, W3, W4, W5, W0);
+
+ /* Transform 12-14 + Precalc 18-20 */
+ R1(a, b, c, d, e, f, g, h, 12, 0, XW); SCHED_W_0(18, W2, W3, W4, W5, W0, W1);
+ R1(d, a, b, c, h, e, f, g, 13, 1, XW); SCHED_W_1(18, W2, W3, W4, W5, W0, W1);
+ R1(c, d, a, b, g, h, e, f, 14, 2, XW); SCHED_W_2(18, W2, W3, W4, W5, W0, W1);
+
+ /* Transform 15-17 + Precalc 21-23 */
+ R1(b, c, d, a, f, g, h, e, 15, 0, XW); SCHED_W_0(21, W3, W4, W5, W0, W1, W2);
+ R2(a, b, c, d, e, f, g, h, 16, 1, XW); SCHED_W_1(21, W3, W4, W5, W0, W1, W2);
+ R2(d, a, b, c, h, e, f, g, 17, 2, XW); SCHED_W_2(21, W3, W4, W5, W0, W1, W2);
+
+ /* Transform 18-20 + Precalc 24-26 */
+ R2(c, d, a, b, g, h, e, f, 18, 0, XW); SCHED_W_0(24, W4, W5, W0, W1, W2, W3);
+ R2(b, c, d, a, f, g, h, e, 19, 1, XW); SCHED_W_1(24, W4, W5, W0, W1, W2, W3);
+ R2(a, b, c, d, e, f, g, h, 20, 2, XW); SCHED_W_2(24, W4, W5, W0, W1, W2, W3);
+
+ /* Transform 21-23 + Precalc 27-29 */
+ R2(d, a, b, c, h, e, f, g, 21, 0, XW); SCHED_W_0(27, W5, W0, W1, W2, W3, W4);
+ R2(c, d, a, b, g, h, e, f, 22, 1, XW); SCHED_W_1(27, W5, W0, W1, W2, W3, W4);
+ R2(b, c, d, a, f, g, h, e, 23, 2, XW); SCHED_W_2(27, W5, W0, W1, W2, W3, W4);
+
+ /* Transform 24-26 + Precalc 30-32 */
+ R2(a, b, c, d, e, f, g, h, 24, 0, XW); SCHED_W_0(30, W0, W1, W2, W3, W4, W5);
+ R2(d, a, b, c, h, e, f, g, 25, 1, XW); SCHED_W_1(30, W0, W1, W2, W3, W4, W5);
+ R2(c, d, a, b, g, h, e, f, 26, 2, XW); SCHED_W_2(30, W0, W1, W2, W3, W4, W5);
+
+ /* Transform 27-29 + Precalc 33-35 */
+ R2(b, c, d, a, f, g, h, e, 27, 0, XW); SCHED_W_0(33, W1, W2, W3, W4, W5, W0);
+ R2(a, b, c, d, e, f, g, h, 28, 1, XW); SCHED_W_1(33, W1, W2, W3, W4, W5, W0);
+ R2(d, a, b, c, h, e, f, g, 29, 2, XW); SCHED_W_2(33, W1, W2, W3, W4, W5, W0);
+
+ /* Transform 30-32 + Precalc 36-38 */
+ R2(c, d, a, b, g, h, e, f, 30, 0, XW); SCHED_W_0(36, W2, W3, W4, W5, W0, W1);
+ R2(b, c, d, a, f, g, h, e, 31, 1, XW); SCHED_W_1(36, W2, W3, W4, W5, W0, W1);
+ R2(a, b, c, d, e, f, g, h, 32, 2, XW); SCHED_W_2(36, W2, W3, W4, W5, W0, W1);
+
+ /* Transform 33-35 + Precalc 39-41 */
+ R2(d, a, b, c, h, e, f, g, 33, 0, XW); SCHED_W_0(39, W3, W4, W5, W0, W1, W2);
+ R2(c, d, a, b, g, h, e, f, 34, 1, XW); SCHED_W_1(39, W3, W4, W5, W0, W1, W2);
+ R2(b, c, d, a, f, g, h, e, 35, 2, XW); SCHED_W_2(39, W3, W4, W5, W0, W1, W2);
+
+ /* Transform 36-38 + Precalc 42-44 */
+ R2(a, b, c, d, e, f, g, h, 36, 0, XW); SCHED_W_0(42, W4, W5, W0, W1, W2, W3);
+ R2(d, a, b, c, h, e, f, g, 37, 1, XW); SCHED_W_1(42, W4, W5, W0, W1, W2, W3);
+ R2(c, d, a, b, g, h, e, f, 38, 2, XW); SCHED_W_2(42, W4, W5, W0, W1, W2, W3);
+
+ /* Transform 39-41 + Precalc 45-47 */
+ R2(b, c, d, a, f, g, h, e, 39, 0, XW); SCHED_W_0(45, W5, W0, W1, W2, W3, W4);
+ R2(a, b, c, d, e, f, g, h, 40, 1, XW); SCHED_W_1(45, W5, W0, W1, W2, W3, W4);
+ R2(d, a, b, c, h, e, f, g, 41, 2, XW); SCHED_W_2(45, W5, W0, W1, W2, W3, W4);
+
+ /* Transform 42-44 + Precalc 48-50 */
+ R2(c, d, a, b, g, h, e, f, 42, 0, XW); SCHED_W_0(48, W0, W1, W2, W3, W4, W5);
+ R2(b, c, d, a, f, g, h, e, 43, 1, XW); SCHED_W_1(48, W0, W1, W2, W3, W4, W5);
+ R2(a, b, c, d, e, f, g, h, 44, 2, XW); SCHED_W_2(48, W0, W1, W2, W3, W4, W5);
+
+ /* Transform 45-47 + Precalc 51-53 */
+ R2(d, a, b, c, h, e, f, g, 45, 0, XW); SCHED_W_0(51, W1, W2, W3, W4, W5, W0);
+ R2(c, d, a, b, g, h, e, f, 46, 1, XW); SCHED_W_1(51, W1, W2, W3, W4, W5, W0);
+ R2(b, c, d, a, f, g, h, e, 47, 2, XW); SCHED_W_2(51, W1, W2, W3, W4, W5, W0);
+
+ /* Transform 48-50 + Precalc 54-56 */
+ R2(a, b, c, d, e, f, g, h, 48, 0, XW); SCHED_W_0(54, W2, W3, W4, W5, W0, W1);
+ R2(d, a, b, c, h, e, f, g, 49, 1, XW); SCHED_W_1(54, W2, W3, W4, W5, W0, W1);
+ R2(c, d, a, b, g, h, e, f, 50, 2, XW); SCHED_W_2(54, W2, W3, W4, W5, W0, W1);
+
+ /* Transform 51-53 + Precalc 57-59 */
+ R2(b, c, d, a, f, g, h, e, 51, 0, XW); SCHED_W_0(57, W3, W4, W5, W0, W1, W2);
+ R2(a, b, c, d, e, f, g, h, 52, 1, XW); SCHED_W_1(57, W3, W4, W5, W0, W1, W2);
+ R2(d, a, b, c, h, e, f, g, 53, 2, XW); SCHED_W_2(57, W3, W4, W5, W0, W1, W2);
+
+ /* Transform 54-56 + Precalc 60-62 */
+ R2(c, d, a, b, g, h, e, f, 54, 0, XW); SCHED_W_0(60, W4, W5, W0, W1, W2, W3);
+ R2(b, c, d, a, f, g, h, e, 55, 1, XW); SCHED_W_1(60, W4, W5, W0, W1, W2, W3);
+ R2(a, b, c, d, e, f, g, h, 56, 2, XW); SCHED_W_2(60, W4, W5, W0, W1, W2, W3);
+
+ /* Transform 57-59 + Precalc 63 */
+ R2(d, a, b, c, h, e, f, g, 57, 0, XW); SCHED_W_0(63, W5, W0, W1, W2, W3, W4);
+ R2(c, d, a, b, g, h, e, f, 58, 1, XW);
+ R2(b, c, d, a, f, g, h, e, 59, 2, XW); SCHED_W_1(63, W5, W0, W1, W2, W3, W4);
+
+ /* Transform 60-62 + Precalc 63 */
+ R2(a, b, c, d, e, f, g, h, 60, 0, XW);
+ R2(d, a, b, c, h, e, f, g, 61, 1, XW); SCHED_W_2(63, W5, W0, W1, W2, W3, W4);
+ R2(c, d, a, b, g, h, e, f, 62, 2, XW);
+
+ /* Transform 63 */
+ R2(b, c, d, a, f, g, h, e, 63, 0, XW);
+
+ /* Update the chaining variables. */
+ xorl state_h0(RSTATE), a;
+ xorl state_h1(RSTATE), b;
+ xorl state_h2(RSTATE), c;
+ xorl state_h3(RSTATE), d;
+ movl a, state_h0(RSTATE);
+ movl b, state_h1(RSTATE);
+ movl c, state_h2(RSTATE);
+ movl d, state_h3(RSTATE);
+ xorl state_h4(RSTATE), e;
+ xorl state_h5(RSTATE), f;
+ xorl state_h6(RSTATE), g;
+ xorl state_h7(RSTATE), h;
+ movl e, state_h4(RSTATE);
+ movl f, state_h5(RSTATE);
+ movl g, state_h6(RSTATE);
+ movl h, state_h7(RSTATE);
+
+ cmpq $0, RNBLKS;
+ jne .Loop;
+
+ vzeroall;
+
+ movq (STACK_REG_SAVE + 0 * 8)(%rsp), %rbx;
+ movq (STACK_REG_SAVE + 1 * 8)(%rsp), %r15;
+ movq (STACK_REG_SAVE + 2 * 8)(%rsp), %r14;
+ movq (STACK_REG_SAVE + 3 * 8)(%rsp), %r13;
+ movq (STACK_REG_SAVE + 4 * 8)(%rsp), %r12;
+
+ vmovdqa %xmm0, IW_W1_ADDR(0, 0);
+ vmovdqa %xmm0, IW_W1W2_ADDR(0, 0);
+ vmovdqa %xmm0, IW_W1_ADDR(4, 0);
+ vmovdqa %xmm0, IW_W1W2_ADDR(4, 0);
+ vmovdqa %xmm0, IW_W1_ADDR(8, 0);
+ vmovdqa %xmm0, IW_W1W2_ADDR(8, 0);
+
+ movq %rbp, %rsp;
+ popq %rbp;
+ ret;
+SYM_FUNC_END(sm3_transform_avx)
diff --git a/arch/x86/crypto/sm3_avx_glue.c b/arch/x86/crypto/sm3_avx_glue.c
new file mode 100644
index 000000000000..661b6f22ffcd
--- /dev/null
+++ b/arch/x86/crypto/sm3_avx_glue.c
@@ -0,0 +1,134 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * SM3 Secure Hash Algorithm, AVX assembler accelerated.
+ * specified in: https://datatracker.ietf.org/doc/html/draft-sca-cfrg-sm3-02
+ *
+ * Copyright (C) 2021 Tianjia Zhang <tianjia.zhang@linux.alibaba.com>
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <crypto/internal/hash.h>
+#include <crypto/internal/simd.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <crypto/sm3.h>
+#include <crypto/sm3_base.h>
+#include <asm/simd.h>
+
+asmlinkage void sm3_transform_avx(struct sm3_state *state,
+ const u8 *data, int nblocks);
+
+static int sm3_avx_update(struct shash_desc *desc, const u8 *data,
+ unsigned int len)
+{
+ struct sm3_state *sctx = shash_desc_ctx(desc);
+
+ if (!crypto_simd_usable() ||
+ (sctx->count % SM3_BLOCK_SIZE) + len < SM3_BLOCK_SIZE) {
+ sm3_update(sctx, data, len);
+ return 0;
+ }
+
+ /*
+ * Make sure struct sm3_state begins directly with the SM3
+ * 256-bit internal state, as this is what the asm functions expect.
+ */
+ BUILD_BUG_ON(offsetof(struct sm3_state, state) != 0);
+
+ kernel_fpu_begin();
+ sm3_base_do_update(desc, data, len, sm3_transform_avx);
+ kernel_fpu_end();
+
+ return 0;
+}
+
+static int sm3_avx_finup(struct shash_desc *desc, const u8 *data,
+ unsigned int len, u8 *out)
+{
+ if (!crypto_simd_usable()) {
+ struct sm3_state *sctx = shash_desc_ctx(desc);
+
+ if (len)
+ sm3_update(sctx, data, len);
+
+ sm3_final(sctx, out);
+ return 0;
+ }
+
+ kernel_fpu_begin();
+ if (len)
+ sm3_base_do_update(desc, data, len, sm3_transform_avx);
+ sm3_base_do_finalize(desc, sm3_transform_avx);
+ kernel_fpu_end();
+
+ return sm3_base_finish(desc, out);
+}
+
+static int sm3_avx_final(struct shash_desc *desc, u8 *out)
+{
+ if (!crypto_simd_usable()) {
+ sm3_final(shash_desc_ctx(desc), out);
+ return 0;
+ }
+
+ kernel_fpu_begin();
+ sm3_base_do_finalize(desc, sm3_transform_avx);
+ kernel_fpu_end();
+
+ return sm3_base_finish(desc, out);
+}
+
+static struct shash_alg sm3_avx_alg = {
+ .digestsize = SM3_DIGEST_SIZE,
+ .init = sm3_base_init,
+ .update = sm3_avx_update,
+ .final = sm3_avx_final,
+ .finup = sm3_avx_finup,
+ .descsize = sizeof(struct sm3_state),
+ .base = {
+ .cra_name = "sm3",
+ .cra_driver_name = "sm3-avx",
+ .cra_priority = 300,
+ .cra_blocksize = SM3_BLOCK_SIZE,
+ .cra_module = THIS_MODULE,
+ }
+};
+
+static int __init sm3_avx_mod_init(void)
+{
+ const char *feature_name;
+
+ if (!boot_cpu_has(X86_FEATURE_AVX)) {
+ pr_info("AVX instruction are not detected.\n");
+ return -ENODEV;
+ }
+
+ if (!boot_cpu_has(X86_FEATURE_BMI2)) {
+ pr_info("BMI2 instruction are not detected.\n");
+ return -ENODEV;
+ }
+
+ if (!cpu_has_xfeatures(XFEATURE_MASK_SSE | XFEATURE_MASK_YMM,
+ &feature_name)) {
+ pr_info("CPU feature '%s' is not supported.\n", feature_name);
+ return -ENODEV;
+ }
+
+ return crypto_register_shash(&sm3_avx_alg);
+}
+
+static void __exit sm3_avx_mod_exit(void)
+{
+ crypto_unregister_shash(&sm3_avx_alg);
+}
+
+module_init(sm3_avx_mod_init);
+module_exit(sm3_avx_mod_exit);
+
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Tianjia Zhang <tianjia.zhang@linux.alibaba.com>");
+MODULE_DESCRIPTION("SM3 Secure Hash Algorithm, AVX assembler accelerated");
+MODULE_ALIAS_CRYPTO("sm3");
+MODULE_ALIAS_CRYPTO("sm3-avx");
diff --git a/arch/x86/events/core.c b/arch/x86/events/core.c
index e686c5e0537b..eef816fc216d 100644
--- a/arch/x86/events/core.c
+++ b/arch/x86/events/core.c
@@ -2794,7 +2794,7 @@ perf_callchain_kernel(struct perf_callchain_entry_ctx *entry, struct pt_regs *re
static inline int
valid_user_frame(const void __user *fp, unsigned long size)
{
- return (__range_not_ok(fp, size, TASK_SIZE) == 0);
+ return __access_ok(fp, size);
}
static unsigned long get_segment_base(unsigned int segment)
diff --git a/arch/x86/events/intel/core.c b/arch/x86/events/intel/core.c
index fd9f908debe5..e88791b420ee 100644
--- a/arch/x86/events/intel/core.c
+++ b/arch/x86/events/intel/core.c
@@ -181,6 +181,27 @@ static struct event_constraint intel_gen_event_constraints[] __read_mostly =
EVENT_CONSTRAINT_END
};
+static struct event_constraint intel_v5_gen_event_constraints[] __read_mostly =
+{
+ FIXED_EVENT_CONSTRAINT(0x00c0, 0), /* INST_RETIRED.ANY */
+ FIXED_EVENT_CONSTRAINT(0x003c, 1), /* CPU_CLK_UNHALTED.CORE */
+ FIXED_EVENT_CONSTRAINT(0x0300, 2), /* CPU_CLK_UNHALTED.REF */
+ FIXED_EVENT_CONSTRAINT(0x0400, 3), /* SLOTS */
+ FIXED_EVENT_CONSTRAINT(0x0500, 4),
+ FIXED_EVENT_CONSTRAINT(0x0600, 5),
+ FIXED_EVENT_CONSTRAINT(0x0700, 6),
+ FIXED_EVENT_CONSTRAINT(0x0800, 7),
+ FIXED_EVENT_CONSTRAINT(0x0900, 8),
+ FIXED_EVENT_CONSTRAINT(0x0a00, 9),
+ FIXED_EVENT_CONSTRAINT(0x0b00, 10),
+ FIXED_EVENT_CONSTRAINT(0x0c00, 11),
+ FIXED_EVENT_CONSTRAINT(0x0d00, 12),
+ FIXED_EVENT_CONSTRAINT(0x0e00, 13),
+ FIXED_EVENT_CONSTRAINT(0x0f00, 14),
+ FIXED_EVENT_CONSTRAINT(0x1000, 15),
+ EVENT_CONSTRAINT_END
+};
+
static struct event_constraint intel_slm_event_constraints[] __read_mostly =
{
FIXED_EVENT_CONSTRAINT(0x00c0, 0), /* INST_RETIRED.ANY */
@@ -4703,6 +4724,19 @@ static __initconst const struct x86_pmu intel_pmu = {
.lbr_read = intel_pmu_lbr_read_64,
.lbr_save = intel_pmu_lbr_save,
.lbr_restore = intel_pmu_lbr_restore,
+
+ /*
+ * SMM has access to all 4 rings and while traditionally SMM code only
+ * ran in CPL0, 2021-era firmware is starting to make use of CPL3 in SMM.
+ *
+ * Since the EVENTSEL.{USR,OS} CPL filtering makes no distinction
+ * between SMM or not, this results in what should be pure userspace
+ * counters including SMM data.
+ *
+ * This is a clear privilege issue, therefore globally disable
+ * counting SMM by default.
+ */
+ .attr_freeze_on_smi = 1,
};
static __init void intel_clovertown_quirk(void)
@@ -6236,6 +6270,19 @@ __init int intel_pmu_init(void)
pmu->num_counters = x86_pmu.num_counters;
pmu->num_counters_fixed = x86_pmu.num_counters_fixed;
}
+
+ /*
+ * Quirk: For some Alder Lake machine, when all E-cores are disabled in
+ * a BIOS, the leaf 0xA will enumerate all counters of P-cores. However,
+ * the X86_FEATURE_HYBRID_CPU is still set. The above codes will
+ * mistakenly add extra counters for P-cores. Correct the number of
+ * counters here.
+ */
+ if ((pmu->num_counters > 8) || (pmu->num_counters_fixed > 4)) {
+ pmu->num_counters = x86_pmu.num_counters;
+ pmu->num_counters_fixed = x86_pmu.num_counters_fixed;
+ }
+
pmu->max_pebs_events = min_t(unsigned, MAX_PEBS_EVENTS, pmu->num_counters);
pmu->unconstrained = (struct event_constraint)
__EVENT_CONSTRAINT(0, (1ULL << pmu->num_counters) - 1,
@@ -6282,7 +6329,9 @@ __init int intel_pmu_init(void)
pr_cont("generic architected perfmon v1, ");
name = "generic_arch_v1";
break;
- default:
+ case 2:
+ case 3:
+ case 4:
/*
* default constraints for v2 and up
*/
@@ -6290,6 +6339,21 @@ __init int intel_pmu_init(void)
pr_cont("generic architected perfmon, ");
name = "generic_arch_v2+";
break;
+ default:
+ /*
+ * The default constraints for v5 and up can support up to
+ * 16 fixed counters. For the fixed counters 4 and later,
+ * the pseudo-encoding is applied.
+ * The constraints may be cut according to the CPUID enumeration
+ * by inserting the EVENT_CONSTRAINT_END.
+ */
+ if (x86_pmu.num_counters_fixed > INTEL_PMC_MAX_FIXED)
+ x86_pmu.num_counters_fixed = INTEL_PMC_MAX_FIXED;
+ intel_v5_gen_event_constraints[x86_pmu.num_counters_fixed].weight = -1;
+ x86_pmu.event_constraints = intel_v5_gen_event_constraints;
+ pr_cont("generic architected perfmon, ");
+ name = "generic_arch_v5+";
+ break;
}
}
@@ -6340,6 +6404,8 @@ __init int intel_pmu_init(void)
}
if (x86_pmu.lbr_nr) {
+ intel_pmu_lbr_init();
+
pr_cont("%d-deep LBR, ", x86_pmu.lbr_nr);
/* only support branch_stack snapshot for perfmon >= v2 */
diff --git a/arch/x86/events/intel/ds.c b/arch/x86/events/intel/ds.c
index 2e215369df4a..376cc3d66094 100644
--- a/arch/x86/events/intel/ds.c
+++ b/arch/x86/events/intel/ds.c
@@ -1203,7 +1203,10 @@ static void intel_pmu_pebs_via_pt_enable(struct perf_event *event)
if (hwc->idx >= INTEL_PMC_IDX_FIXED) {
base = MSR_RELOAD_FIXED_CTR0;
idx = hwc->idx - INTEL_PMC_IDX_FIXED;
- value = ds->pebs_event_reset[MAX_PEBS_EVENTS + idx];
+ if (x86_pmu.intel_cap.pebs_format < 5)
+ value = ds->pebs_event_reset[MAX_PEBS_EVENTS_FMT4 + idx];
+ else
+ value = ds->pebs_event_reset[MAX_PEBS_EVENTS + idx];
}
wrmsrl(base + idx, value);
}
@@ -1232,8 +1235,12 @@ void intel_pmu_pebs_enable(struct perf_event *event)
}
}
- if (idx >= INTEL_PMC_IDX_FIXED)
- idx = MAX_PEBS_EVENTS + (idx - INTEL_PMC_IDX_FIXED);
+ if (idx >= INTEL_PMC_IDX_FIXED) {
+ if (x86_pmu.intel_cap.pebs_format < 5)
+ idx = MAX_PEBS_EVENTS_FMT4 + (idx - INTEL_PMC_IDX_FIXED);
+ else
+ idx = MAX_PEBS_EVENTS + (idx - INTEL_PMC_IDX_FIXED);
+ }
/*
* Use auto-reload if possible to save a MSR write in the PMI.
@@ -2204,6 +2211,7 @@ void __init intel_ds_init(void)
break;
case 4:
+ case 5:
x86_pmu.drain_pebs = intel_pmu_drain_pebs_icl;
x86_pmu.pebs_record_size = sizeof(struct pebs_basic);
if (x86_pmu.intel_cap.pebs_baseline) {
diff --git a/arch/x86/events/intel/lbr.c b/arch/x86/events/intel/lbr.c
index 8043213b75a5..fe1742c4ca49 100644
--- a/arch/x86/events/intel/lbr.c
+++ b/arch/x86/events/intel/lbr.c
@@ -8,14 +8,6 @@
#include "../perf_event.h"
-static const enum {
- LBR_EIP_FLAGS = 1,
- LBR_TSX = 2,
-} lbr_desc[LBR_FORMAT_MAX_KNOWN + 1] = {
- [LBR_FORMAT_EIP_FLAGS] = LBR_EIP_FLAGS,
- [LBR_FORMAT_EIP_FLAGS2] = LBR_EIP_FLAGS | LBR_TSX,
-};
-
/*
* Intel LBR_SELECT bits
* Intel Vol3a, April 2011, Section 16.7 Table 16-10
@@ -243,7 +235,7 @@ void intel_pmu_lbr_reset_64(void)
for (i = 0; i < x86_pmu.lbr_nr; i++) {
wrmsrl(x86_pmu.lbr_from + i, 0);
wrmsrl(x86_pmu.lbr_to + i, 0);
- if (x86_pmu.intel_cap.lbr_format == LBR_FORMAT_INFO)
+ if (x86_pmu.lbr_has_info)
wrmsrl(x86_pmu.lbr_info + i, 0);
}
}
@@ -305,11 +297,10 @@ enum {
*/
static inline bool lbr_from_signext_quirk_needed(void)
{
- int lbr_format = x86_pmu.intel_cap.lbr_format;
bool tsx_support = boot_cpu_has(X86_FEATURE_HLE) ||
boot_cpu_has(X86_FEATURE_RTM);
- return !tsx_support && (lbr_desc[lbr_format] & LBR_TSX);
+ return !tsx_support && x86_pmu.lbr_has_tsx;
}
static DEFINE_STATIC_KEY_FALSE(lbr_from_quirk_key);
@@ -427,12 +418,12 @@ rdlbr_all(struct lbr_entry *lbr, unsigned int idx, bool need_info)
void intel_pmu_lbr_restore(void *ctx)
{
- bool need_info = x86_pmu.intel_cap.lbr_format == LBR_FORMAT_INFO;
struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
struct x86_perf_task_context *task_ctx = ctx;
- int i;
- unsigned lbr_idx, mask;
+ bool need_info = x86_pmu.lbr_has_info;
u64 tos = task_ctx->tos;
+ unsigned lbr_idx, mask;
+ int i;
mask = x86_pmu.lbr_nr - 1;
for (i = 0; i < task_ctx->valid_lbrs; i++) {
@@ -444,7 +435,7 @@ void intel_pmu_lbr_restore(void *ctx)
lbr_idx = (tos - i) & mask;
wrlbr_from(lbr_idx, 0);
wrlbr_to(lbr_idx, 0);
- if (x86_pmu.intel_cap.lbr_format == LBR_FORMAT_INFO)
+ if (need_info)
wrlbr_info(lbr_idx, 0);
}
@@ -519,9 +510,9 @@ static void __intel_pmu_lbr_restore(void *ctx)
void intel_pmu_lbr_save(void *ctx)
{
- bool need_info = x86_pmu.intel_cap.lbr_format == LBR_FORMAT_INFO;
struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
struct x86_perf_task_context *task_ctx = ctx;
+ bool need_info = x86_pmu.lbr_has_info;
unsigned lbr_idx, mask;
u64 tos;
int i;
@@ -816,7 +807,6 @@ void intel_pmu_lbr_read_64(struct cpu_hw_events *cpuc)
{
bool need_info = false, call_stack = false;
unsigned long mask = x86_pmu.lbr_nr - 1;
- int lbr_format = x86_pmu.intel_cap.lbr_format;
u64 tos = intel_pmu_lbr_tos();
int i;
int out = 0;
@@ -831,9 +821,7 @@ void intel_pmu_lbr_read_64(struct cpu_hw_events *cpuc)
for (i = 0; i < num; i++) {
unsigned long lbr_idx = (tos - i) & mask;
u64 from, to, mis = 0, pred = 0, in_tx = 0, abort = 0;
- int skip = 0;
u16 cycles = 0;
- int lbr_flags = lbr_desc[lbr_format];
from = rdlbr_from(lbr_idx, NULL);
to = rdlbr_to(lbr_idx, NULL);
@@ -845,37 +833,39 @@ void intel_pmu_lbr_read_64(struct cpu_hw_events *cpuc)
if (call_stack && !from)
break;
- if (lbr_format == LBR_FORMAT_INFO && need_info) {
- u64 info;
-
- info = rdlbr_info(lbr_idx, NULL);
- mis = !!(info & LBR_INFO_MISPRED);
- pred = !mis;
- in_tx = !!(info & LBR_INFO_IN_TX);
- abort = !!(info & LBR_INFO_ABORT);
- cycles = (info & LBR_INFO_CYCLES);
- }
-
- if (lbr_format == LBR_FORMAT_TIME) {
- mis = !!(from & LBR_FROM_FLAG_MISPRED);
- pred = !mis;
- skip = 1;
- cycles = ((to >> 48) & LBR_INFO_CYCLES);
-
- to = (u64)((((s64)to) << 16) >> 16);
- }
-
- if (lbr_flags & LBR_EIP_FLAGS) {
- mis = !!(from & LBR_FROM_FLAG_MISPRED);
- pred = !mis;
- skip = 1;
- }
- if (lbr_flags & LBR_TSX) {
- in_tx = !!(from & LBR_FROM_FLAG_IN_TX);
- abort = !!(from & LBR_FROM_FLAG_ABORT);
- skip = 3;
+ if (x86_pmu.lbr_has_info) {
+ if (need_info) {
+ u64 info;
+
+ info = rdlbr_info(lbr_idx, NULL);
+ mis = !!(info & LBR_INFO_MISPRED);
+ pred = !mis;
+ cycles = (info & LBR_INFO_CYCLES);
+ if (x86_pmu.lbr_has_tsx) {
+ in_tx = !!(info & LBR_INFO_IN_TX);
+ abort = !!(info & LBR_INFO_ABORT);
+ }
+ }
+ } else {
+ int skip = 0;
+
+ if (x86_pmu.lbr_from_flags) {
+ mis = !!(from & LBR_FROM_FLAG_MISPRED);
+ pred = !mis;
+ skip = 1;
+ }
+ if (x86_pmu.lbr_has_tsx) {
+ in_tx = !!(from & LBR_FROM_FLAG_IN_TX);
+ abort = !!(from & LBR_FROM_FLAG_ABORT);
+ skip = 3;
+ }
+ from = (u64)((((s64)from) << skip) >> skip);
+
+ if (x86_pmu.lbr_to_cycles) {
+ cycles = ((to >> 48) & LBR_INFO_CYCLES);
+ to = (u64)((((s64)to) << 16) >> 16);
+ }
}
- from = (u64)((((s64)from) << skip) >> skip);
/*
* Some CPUs report duplicated abort records,
@@ -903,37 +893,40 @@ void intel_pmu_lbr_read_64(struct cpu_hw_events *cpuc)
cpuc->lbr_stack.hw_idx = tos;
}
+static DEFINE_STATIC_KEY_FALSE(x86_lbr_mispred);
+static DEFINE_STATIC_KEY_FALSE(x86_lbr_cycles);
+static DEFINE_STATIC_KEY_FALSE(x86_lbr_type);
+
static __always_inline int get_lbr_br_type(u64 info)
{
- if (!static_cpu_has(X86_FEATURE_ARCH_LBR) || !x86_pmu.lbr_br_type)
- return 0;
+ int type = 0;
- return (info & LBR_INFO_BR_TYPE) >> LBR_INFO_BR_TYPE_OFFSET;
+ if (static_branch_likely(&x86_lbr_type))
+ type = (info & LBR_INFO_BR_TYPE) >> LBR_INFO_BR_TYPE_OFFSET;
+
+ return type;
}
static __always_inline bool get_lbr_mispred(u64 info)
{
- if (static_cpu_has(X86_FEATURE_ARCH_LBR) && !x86_pmu.lbr_mispred)
- return 0;
+ bool mispred = 0;
- return !!(info & LBR_INFO_MISPRED);
-}
+ if (static_branch_likely(&x86_lbr_mispred))
+ mispred = !!(info & LBR_INFO_MISPRED);
-static __always_inline bool get_lbr_predicted(u64 info)
-{
- if (static_cpu_has(X86_FEATURE_ARCH_LBR) && !x86_pmu.lbr_mispred)
- return 0;
-
- return !(info & LBR_INFO_MISPRED);
+ return mispred;
}
static __always_inline u16 get_lbr_cycles(u64 info)
{
+ u16 cycles = info & LBR_INFO_CYCLES;
+
if (static_cpu_has(X86_FEATURE_ARCH_LBR) &&
- !(x86_pmu.lbr_timed_lbr && info & LBR_INFO_CYC_CNT_VALID))
- return 0;
+ (!static_branch_likely(&x86_lbr_cycles) ||
+ !(info & LBR_INFO_CYC_CNT_VALID)))
+ cycles = 0;
- return info & LBR_INFO_CYCLES;
+ return cycles;
}
static void intel_pmu_store_lbr(struct cpu_hw_events *cpuc,
@@ -961,7 +954,7 @@ static void intel_pmu_store_lbr(struct cpu_hw_events *cpuc,
e->from = from;
e->to = to;
e->mispred = get_lbr_mispred(info);
- e->predicted = get_lbr_predicted(info);
+ e->predicted = !e->mispred;
e->in_tx = !!(info & LBR_INFO_IN_TX);
e->abort = !!(info & LBR_INFO_ABORT);
e->cycles = get_lbr_cycles(info);
@@ -1120,7 +1113,7 @@ static int intel_pmu_setup_hw_lbr_filter(struct perf_event *event)
if ((br_type & PERF_SAMPLE_BRANCH_NO_CYCLES) &&
(br_type & PERF_SAMPLE_BRANCH_NO_FLAGS) &&
- (x86_pmu.intel_cap.lbr_format == LBR_FORMAT_INFO))
+ x86_pmu.lbr_has_info)
reg->config |= LBR_NO_INFO;
return 0;
@@ -1336,10 +1329,10 @@ static int branch_map[X86_BR_TYPE_MAP_MAX] = {
PERF_BR_SYSCALL, /* X86_BR_SYSCALL */
PERF_BR_SYSRET, /* X86_BR_SYSRET */
PERF_BR_UNKNOWN, /* X86_BR_INT */
- PERF_BR_UNKNOWN, /* X86_BR_IRET */
+ PERF_BR_ERET, /* X86_BR_IRET */
PERF_BR_COND, /* X86_BR_JCC */
PERF_BR_UNCOND, /* X86_BR_JMP */
- PERF_BR_UNKNOWN, /* X86_BR_IRQ */
+ PERF_BR_IRQ, /* X86_BR_IRQ */
PERF_BR_IND_CALL, /* X86_BR_IND_CALL */
PERF_BR_UNKNOWN, /* X86_BR_ABORT */
PERF_BR_UNKNOWN, /* X86_BR_IN_TX */
@@ -1706,6 +1699,38 @@ void intel_pmu_lbr_init_knl(void)
x86_pmu.intel_cap.lbr_format = LBR_FORMAT_EIP_FLAGS;
}
+void intel_pmu_lbr_init(void)
+{
+ switch (x86_pmu.intel_cap.lbr_format) {
+ case LBR_FORMAT_EIP_FLAGS2:
+ x86_pmu.lbr_has_tsx = 1;
+ fallthrough;
+ case LBR_FORMAT_EIP_FLAGS:
+ x86_pmu.lbr_from_flags = 1;
+ break;
+
+ case LBR_FORMAT_INFO:
+ x86_pmu.lbr_has_tsx = 1;
+ fallthrough;
+ case LBR_FORMAT_INFO2:
+ x86_pmu.lbr_has_info = 1;
+ break;
+
+ case LBR_FORMAT_TIME:
+ x86_pmu.lbr_from_flags = 1;
+ x86_pmu.lbr_to_cycles = 1;
+ break;
+ }
+
+ if (x86_pmu.lbr_has_info) {
+ /*
+ * Only used in combination with baseline pebs.
+ */
+ static_branch_enable(&x86_lbr_mispred);
+ static_branch_enable(&x86_lbr_cycles);
+ }
+}
+
/*
* LBR state size is variable based on the max number of registers.
* This calculates the expected state size, which should match
@@ -1726,6 +1751,9 @@ static bool is_arch_lbr_xsave_available(void)
* Check the LBR state with the corresponding software structure.
* Disable LBR XSAVES support if the size doesn't match.
*/
+ if (xfeature_size(XFEATURE_LBR) == 0)
+ return false;
+
if (WARN_ON(xfeature_size(XFEATURE_LBR) != get_lbr_state_size()))
return false;
@@ -1765,6 +1793,12 @@ void __init intel_pmu_arch_lbr_init(void)
x86_pmu.lbr_br_type = ecx.split.lbr_br_type;
x86_pmu.lbr_nr = lbr_nr;
+ if (x86_pmu.lbr_mispred)
+ static_branch_enable(&x86_lbr_mispred);
+ if (x86_pmu.lbr_timed_lbr)
+ static_branch_enable(&x86_lbr_cycles);
+ if (x86_pmu.lbr_br_type)
+ static_branch_enable(&x86_lbr_type);
arch_lbr_xsave = is_arch_lbr_xsave_available();
if (arch_lbr_xsave) {
diff --git a/arch/x86/events/intel/pt.c b/arch/x86/events/intel/pt.c
index 7f406c14715f..82ef87e9a897 100644
--- a/arch/x86/events/intel/pt.c
+++ b/arch/x86/events/intel/pt.c
@@ -13,6 +13,8 @@
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/types.h>
+#include <linux/bits.h>
+#include <linux/limits.h>
#include <linux/slab.h>
#include <linux/device.h>
@@ -57,6 +59,8 @@ static struct pt_cap_desc {
PT_CAP(mtc, 0, CPUID_EBX, BIT(3)),
PT_CAP(ptwrite, 0, CPUID_EBX, BIT(4)),
PT_CAP(power_event_trace, 0, CPUID_EBX, BIT(5)),
+ PT_CAP(event_trace, 0, CPUID_EBX, BIT(7)),
+ PT_CAP(tnt_disable, 0, CPUID_EBX, BIT(8)),
PT_CAP(topa_output, 0, CPUID_ECX, BIT(0)),
PT_CAP(topa_multiple_entries, 0, CPUID_ECX, BIT(1)),
PT_CAP(single_range_output, 0, CPUID_ECX, BIT(2)),
@@ -108,6 +112,8 @@ PMU_FORMAT_ATTR(tsc, "config:10" );
PMU_FORMAT_ATTR(noretcomp, "config:11" );
PMU_FORMAT_ATTR(ptw, "config:12" );
PMU_FORMAT_ATTR(branch, "config:13" );
+PMU_FORMAT_ATTR(event, "config:31" );
+PMU_FORMAT_ATTR(notnt, "config:55" );
PMU_FORMAT_ATTR(mtc_period, "config:14-17" );
PMU_FORMAT_ATTR(cyc_thresh, "config:19-22" );
PMU_FORMAT_ATTR(psb_period, "config:24-27" );
@@ -116,6 +122,8 @@ static struct attribute *pt_formats_attr[] = {
&format_attr_pt.attr,
&format_attr_cyc.attr,
&format_attr_pwr_evt.attr,
+ &format_attr_event.attr,
+ &format_attr_notnt.attr,
&format_attr_fup_on_ptw.attr,
&format_attr_mtc.attr,
&format_attr_tsc.attr,
@@ -296,6 +304,8 @@ fail:
RTIT_CTL_CYC_PSB | \
RTIT_CTL_MTC | \
RTIT_CTL_PWR_EVT_EN | \
+ RTIT_CTL_EVENT_EN | \
+ RTIT_CTL_NOTNT | \
RTIT_CTL_FUP_ON_PTW | \
RTIT_CTL_PTW_EN)
@@ -350,6 +360,14 @@ static bool pt_event_valid(struct perf_event *event)
!intel_pt_validate_hw_cap(PT_CAP_power_event_trace))
return false;
+ if (config & RTIT_CTL_EVENT_EN &&
+ !intel_pt_validate_hw_cap(PT_CAP_event_trace))
+ return false;
+
+ if (config & RTIT_CTL_NOTNT &&
+ !intel_pt_validate_hw_cap(PT_CAP_tnt_disable))
+ return false;
+
if (config & RTIT_CTL_PTW) {
if (!intel_pt_validate_hw_cap(PT_CAP_ptwrite))
return false;
@@ -472,7 +490,7 @@ static u64 pt_config_filters(struct perf_event *event)
pt->filters.filter[range].msr_b = filter->msr_b;
}
- rtit_ctl |= filter->config << pt_address_ranges[range].reg_off;
+ rtit_ctl |= (u64)filter->config << pt_address_ranges[range].reg_off;
}
return rtit_ctl;
@@ -897,8 +915,9 @@ static void pt_handle_status(struct pt *pt)
* means we are already losing data; need to let the decoder
* know.
*/
- if (!intel_pt_validate_hw_cap(PT_CAP_topa_multiple_entries) ||
- buf->output_off == pt_buffer_region_size(buf)) {
+ if (!buf->single &&
+ (!intel_pt_validate_hw_cap(PT_CAP_topa_multiple_entries) ||
+ buf->output_off == pt_buffer_region_size(buf))) {
perf_aux_output_flag(&pt->handle,
PERF_AUX_FLAG_TRUNCATED);
advance++;
@@ -1347,10 +1366,26 @@ static void pt_addr_filters_fini(struct perf_event *event)
event->hw.addr_filters = NULL;
}
-static inline bool valid_kernel_ip(unsigned long ip)
+#ifdef CONFIG_X86_64
+/* Clamp to a canonical address greater-than-or-equal-to the address given */
+static u64 clamp_to_ge_canonical_addr(u64 vaddr, u8 vaddr_bits)
+{
+ return __is_canonical_address(vaddr, vaddr_bits) ?
+ vaddr :
+ -BIT_ULL(vaddr_bits - 1);
+}
+
+/* Clamp to a canonical address less-than-or-equal-to the address given */
+static u64 clamp_to_le_canonical_addr(u64 vaddr, u8 vaddr_bits)
{
- return virt_addr_valid(ip) && kernel_ip(ip);
+ return __is_canonical_address(vaddr, vaddr_bits) ?
+ vaddr :
+ BIT_ULL(vaddr_bits - 1) - 1;
}
+#else
+#define clamp_to_ge_canonical_addr(x, y) (x)
+#define clamp_to_le_canonical_addr(x, y) (x)
+#endif
static int pt_event_addr_filters_validate(struct list_head *filters)
{
@@ -1366,14 +1401,6 @@ static int pt_event_addr_filters_validate(struct list_head *filters)
filter->action == PERF_ADDR_FILTER_ACTION_START)
return -EOPNOTSUPP;
- if (!filter->path.dentry) {
- if (!valid_kernel_ip(filter->offset))
- return -EINVAL;
-
- if (!valid_kernel_ip(filter->offset + filter->size))
- return -EINVAL;
- }
-
if (++range > intel_pt_validate_hw_cap(PT_CAP_num_address_ranges))
return -EOPNOTSUPP;
}
@@ -1397,9 +1424,26 @@ static void pt_event_addr_filters_sync(struct perf_event *event)
if (filter->path.dentry && !fr[range].start) {
msr_a = msr_b = 0;
} else {
- /* apply the offset */
- msr_a = fr[range].start;
- msr_b = msr_a + fr[range].size - 1;
+ unsigned long n = fr[range].size - 1;
+ unsigned long a = fr[range].start;
+ unsigned long b;
+
+ if (a > ULONG_MAX - n)
+ b = ULONG_MAX;
+ else
+ b = a + n;
+ /*
+ * Apply the offset. 64-bit addresses written to the
+ * MSRs must be canonical, but the range can encompass
+ * non-canonical addresses. Since software cannot
+ * execute at non-canonical addresses, adjusting to
+ * canonical addresses does not affect the result of the
+ * address filter.
+ */
+ msr_a = clamp_to_ge_canonical_addr(a, boot_cpu_data.x86_virt_bits);
+ msr_b = clamp_to_le_canonical_addr(b, boot_cpu_data.x86_virt_bits);
+ if (msr_b < msr_a)
+ msr_a = msr_b = 0;
}
filters->filter[range].msr_a = msr_a;
diff --git a/arch/x86/events/intel/uncore.c b/arch/x86/events/intel/uncore.c
index f1ba6ab2e97e..e497da9bf427 100644
--- a/arch/x86/events/intel/uncore.c
+++ b/arch/x86/events/intel/uncore.c
@@ -1762,7 +1762,7 @@ static const struct intel_uncore_init_fun rkl_uncore_init __initconst = {
static const struct intel_uncore_init_fun adl_uncore_init __initconst = {
.cpu_init = adl_uncore_cpu_init,
- .mmio_init = tgl_uncore_mmio_init,
+ .mmio_init = adl_uncore_mmio_init,
};
static const struct intel_uncore_init_fun icx_uncore_init __initconst = {
diff --git a/arch/x86/events/intel/uncore.h b/arch/x86/events/intel/uncore.h
index b9687980aab6..2adeaf4de4df 100644
--- a/arch/x86/events/intel/uncore.h
+++ b/arch/x86/events/intel/uncore.h
@@ -584,10 +584,11 @@ void snb_uncore_cpu_init(void);
void nhm_uncore_cpu_init(void);
void skl_uncore_cpu_init(void);
void icl_uncore_cpu_init(void);
-void adl_uncore_cpu_init(void);
void tgl_uncore_cpu_init(void);
+void adl_uncore_cpu_init(void);
void tgl_uncore_mmio_init(void);
void tgl_l_uncore_mmio_init(void);
+void adl_uncore_mmio_init(void);
int snb_pci2phy_map_init(int devid);
/* uncore_snbep.c */
diff --git a/arch/x86/events/intel/uncore_discovery.c b/arch/x86/events/intel/uncore_discovery.c
index 3049c646fa20..5fd72d4b8bbb 100644
--- a/arch/x86/events/intel/uncore_discovery.c
+++ b/arch/x86/events/intel/uncore_discovery.c
@@ -215,10 +215,18 @@ static int parse_discovery_table(struct pci_dev *dev, int die,
pci_read_config_dword(dev, bar_offset, &val);
- if (val & UNCORE_DISCOVERY_MASK)
+ if (val & ~PCI_BASE_ADDRESS_MEM_MASK & ~PCI_BASE_ADDRESS_MEM_TYPE_64)
return -EINVAL;
- addr = (resource_size_t)(val & ~UNCORE_DISCOVERY_MASK);
+ addr = (resource_size_t)(val & PCI_BASE_ADDRESS_MEM_MASK);
+#ifdef CONFIG_PHYS_ADDR_T_64BIT
+ if ((val & PCI_BASE_ADDRESS_MEM_TYPE_MASK) == PCI_BASE_ADDRESS_MEM_TYPE_64) {
+ u32 val2;
+
+ pci_read_config_dword(dev, bar_offset + 4, &val2);
+ addr |= ((resource_size_t)val2) << 32;
+ }
+#endif
size = UNCORE_DISCOVERY_GLOBAL_MAP_SIZE;
io_addr = ioremap(addr, size);
if (!io_addr)
@@ -444,7 +452,7 @@ static struct intel_uncore_ops generic_uncore_pci_ops = {
#define UNCORE_GENERIC_MMIO_SIZE 0x4000
-static unsigned int generic_uncore_mmio_box_ctl(struct intel_uncore_box *box)
+static u64 generic_uncore_mmio_box_ctl(struct intel_uncore_box *box)
{
struct intel_uncore_type *type = box->pmu->type;
@@ -456,7 +464,7 @@ static unsigned int generic_uncore_mmio_box_ctl(struct intel_uncore_box *box)
void intel_generic_uncore_mmio_init_box(struct intel_uncore_box *box)
{
- unsigned int box_ctl = generic_uncore_mmio_box_ctl(box);
+ u64 box_ctl = generic_uncore_mmio_box_ctl(box);
struct intel_uncore_type *type = box->pmu->type;
resource_size_t addr;
@@ -494,8 +502,8 @@ void intel_generic_uncore_mmio_enable_box(struct intel_uncore_box *box)
writel(0, box->io_addr);
}
-static void intel_generic_uncore_mmio_enable_event(struct intel_uncore_box *box,
- struct perf_event *event)
+void intel_generic_uncore_mmio_enable_event(struct intel_uncore_box *box,
+ struct perf_event *event)
{
struct hw_perf_event *hwc = &event->hw;
diff --git a/arch/x86/events/intel/uncore_discovery.h b/arch/x86/events/intel/uncore_discovery.h
index 6d735611c281..f4439357779a 100644
--- a/arch/x86/events/intel/uncore_discovery.h
+++ b/arch/x86/events/intel/uncore_discovery.h
@@ -18,8 +18,6 @@
#define UNCORE_DISCOVERY_BIR_BASE 0x10
/* Discovery table BAR step */
#define UNCORE_DISCOVERY_BIR_STEP 0x4
-/* Mask of the discovery table offset */
-#define UNCORE_DISCOVERY_MASK 0xf
/* Global discovery table size */
#define UNCORE_DISCOVERY_GLOBAL_MAP_SIZE 0x20
@@ -139,6 +137,8 @@ void intel_generic_uncore_mmio_disable_box(struct intel_uncore_box *box);
void intel_generic_uncore_mmio_enable_box(struct intel_uncore_box *box);
void intel_generic_uncore_mmio_disable_event(struct intel_uncore_box *box,
struct perf_event *event);
+void intel_generic_uncore_mmio_enable_event(struct intel_uncore_box *box,
+ struct perf_event *event);
void intel_generic_uncore_pci_init_box(struct intel_uncore_box *box);
void intel_generic_uncore_pci_disable_box(struct intel_uncore_box *box);
diff --git a/arch/x86/events/intel/uncore_snb.c b/arch/x86/events/intel/uncore_snb.c
index 0f63706cdadf..f698a55bde81 100644
--- a/arch/x86/events/intel/uncore_snb.c
+++ b/arch/x86/events/intel/uncore_snb.c
@@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0
/* Nehalem/SandBridge/Haswell/Broadwell/Skylake uncore support */
#include "uncore.h"
+#include "uncore_discovery.h"
/* Uncore IMC PCI IDs */
#define PCI_DEVICE_ID_INTEL_SNB_IMC 0x0100
@@ -64,6 +65,20 @@
#define PCI_DEVICE_ID_INTEL_RKL_2_IMC 0x4c53
#define PCI_DEVICE_ID_INTEL_ADL_1_IMC 0x4660
#define PCI_DEVICE_ID_INTEL_ADL_2_IMC 0x4641
+#define PCI_DEVICE_ID_INTEL_ADL_3_IMC 0x4601
+#define PCI_DEVICE_ID_INTEL_ADL_4_IMC 0x4602
+#define PCI_DEVICE_ID_INTEL_ADL_5_IMC 0x4609
+#define PCI_DEVICE_ID_INTEL_ADL_6_IMC 0x460a
+#define PCI_DEVICE_ID_INTEL_ADL_7_IMC 0x4621
+#define PCI_DEVICE_ID_INTEL_ADL_8_IMC 0x4623
+#define PCI_DEVICE_ID_INTEL_ADL_9_IMC 0x4629
+#define PCI_DEVICE_ID_INTEL_ADL_10_IMC 0x4637
+#define PCI_DEVICE_ID_INTEL_ADL_11_IMC 0x463b
+#define PCI_DEVICE_ID_INTEL_ADL_12_IMC 0x4648
+#define PCI_DEVICE_ID_INTEL_ADL_13_IMC 0x4649
+#define PCI_DEVICE_ID_INTEL_ADL_14_IMC 0x4650
+#define PCI_DEVICE_ID_INTEL_ADL_15_IMC 0x4668
+#define PCI_DEVICE_ID_INTEL_ADL_16_IMC 0x4670
/* SNB event control */
#define SNB_UNC_CTL_EV_SEL_MASK 0x000000ff
@@ -155,6 +170,7 @@
DEFINE_UNCORE_FORMAT_ATTR(event, event, "config:0-7");
DEFINE_UNCORE_FORMAT_ATTR(umask, umask, "config:8-15");
+DEFINE_UNCORE_FORMAT_ATTR(chmask, chmask, "config:8-11");
DEFINE_UNCORE_FORMAT_ATTR(edge, edge, "config:18");
DEFINE_UNCORE_FORMAT_ATTR(inv, inv, "config:23");
DEFINE_UNCORE_FORMAT_ATTR(cmask5, cmask, "config:24-28");
@@ -1334,6 +1350,62 @@ static const struct pci_device_id tgl_uncore_pci_ids[] = {
PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ADL_2_IMC),
.driver_data = UNCORE_PCI_DEV_DATA(SNB_PCI_UNCORE_IMC, 0),
},
+ { /* IMC */
+ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ADL_3_IMC),
+ .driver_data = UNCORE_PCI_DEV_DATA(SNB_PCI_UNCORE_IMC, 0),
+ },
+ { /* IMC */
+ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ADL_4_IMC),
+ .driver_data = UNCORE_PCI_DEV_DATA(SNB_PCI_UNCORE_IMC, 0),
+ },
+ { /* IMC */
+ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ADL_5_IMC),
+ .driver_data = UNCORE_PCI_DEV_DATA(SNB_PCI_UNCORE_IMC, 0),
+ },
+ { /* IMC */
+ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ADL_6_IMC),
+ .driver_data = UNCORE_PCI_DEV_DATA(SNB_PCI_UNCORE_IMC, 0),
+ },
+ { /* IMC */
+ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ADL_7_IMC),
+ .driver_data = UNCORE_PCI_DEV_DATA(SNB_PCI_UNCORE_IMC, 0),
+ },
+ { /* IMC */
+ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ADL_8_IMC),
+ .driver_data = UNCORE_PCI_DEV_DATA(SNB_PCI_UNCORE_IMC, 0),
+ },
+ { /* IMC */
+ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ADL_9_IMC),
+ .driver_data = UNCORE_PCI_DEV_DATA(SNB_PCI_UNCORE_IMC, 0),
+ },
+ { /* IMC */
+ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ADL_10_IMC),
+ .driver_data = UNCORE_PCI_DEV_DATA(SNB_PCI_UNCORE_IMC, 0),
+ },
+ { /* IMC */
+ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ADL_11_IMC),
+ .driver_data = UNCORE_PCI_DEV_DATA(SNB_PCI_UNCORE_IMC, 0),
+ },
+ { /* IMC */
+ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ADL_12_IMC),
+ .driver_data = UNCORE_PCI_DEV_DATA(SNB_PCI_UNCORE_IMC, 0),
+ },
+ { /* IMC */
+ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ADL_13_IMC),
+ .driver_data = UNCORE_PCI_DEV_DATA(SNB_PCI_UNCORE_IMC, 0),
+ },
+ { /* IMC */
+ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ADL_14_IMC),
+ .driver_data = UNCORE_PCI_DEV_DATA(SNB_PCI_UNCORE_IMC, 0),
+ },
+ { /* IMC */
+ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ADL_15_IMC),
+ .driver_data = UNCORE_PCI_DEV_DATA(SNB_PCI_UNCORE_IMC, 0),
+ },
+ { /* IMC */
+ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ADL_16_IMC),
+ .driver_data = UNCORE_PCI_DEV_DATA(SNB_PCI_UNCORE_IMC, 0),
+ },
{ /* end: all zeroes */ }
};
@@ -1390,7 +1462,8 @@ static struct pci_dev *tgl_uncore_get_mc_dev(void)
#define TGL_UNCORE_MMIO_IMC_MEM_OFFSET 0x10000
#define TGL_UNCORE_PCI_IMC_MAP_SIZE 0xe000
-static void tgl_uncore_imc_freerunning_init_box(struct intel_uncore_box *box)
+static void __uncore_imc_init_box(struct intel_uncore_box *box,
+ unsigned int base_offset)
{
struct pci_dev *pdev = tgl_uncore_get_mc_dev();
struct intel_uncore_pmu *pmu = box->pmu;
@@ -1417,11 +1490,17 @@ static void tgl_uncore_imc_freerunning_init_box(struct intel_uncore_box *box)
addr |= ((resource_size_t)mch_bar << 32);
#endif
+ addr += base_offset;
box->io_addr = ioremap(addr, type->mmio_map_size);
if (!box->io_addr)
pr_warn("perf uncore: Failed to ioremap for %s.\n", type->name);
}
+static void tgl_uncore_imc_freerunning_init_box(struct intel_uncore_box *box)
+{
+ __uncore_imc_init_box(box, 0);
+}
+
static struct intel_uncore_ops tgl_uncore_imc_freerunning_ops = {
.init_box = tgl_uncore_imc_freerunning_init_box,
.exit_box = uncore_mmio_exit_box,
@@ -1469,3 +1548,136 @@ void tgl_uncore_mmio_init(void)
}
/* end of Tiger Lake MMIO uncore support */
+
+/* Alder Lake MMIO uncore support */
+#define ADL_UNCORE_IMC_BASE 0xd900
+#define ADL_UNCORE_IMC_MAP_SIZE 0x200
+#define ADL_UNCORE_IMC_CTR 0xe8
+#define ADL_UNCORE_IMC_CTRL 0xd0
+#define ADL_UNCORE_IMC_GLOBAL_CTL 0xc0
+#define ADL_UNCORE_IMC_BOX_CTL 0xc4
+#define ADL_UNCORE_IMC_FREERUNNING_BASE 0xd800
+#define ADL_UNCORE_IMC_FREERUNNING_MAP_SIZE 0x100
+
+#define ADL_UNCORE_IMC_CTL_FRZ (1 << 0)
+#define ADL_UNCORE_IMC_CTL_RST_CTRL (1 << 1)
+#define ADL_UNCORE_IMC_CTL_RST_CTRS (1 << 2)
+#define ADL_UNCORE_IMC_CTL_INT (ADL_UNCORE_IMC_CTL_RST_CTRL | \
+ ADL_UNCORE_IMC_CTL_RST_CTRS)
+
+static void adl_uncore_imc_init_box(struct intel_uncore_box *box)
+{
+ __uncore_imc_init_box(box, ADL_UNCORE_IMC_BASE);
+
+ /* The global control in MC1 can control both MCs. */
+ if (box->io_addr && (box->pmu->pmu_idx == 1))
+ writel(ADL_UNCORE_IMC_CTL_INT, box->io_addr + ADL_UNCORE_IMC_GLOBAL_CTL);
+}
+
+static void adl_uncore_mmio_disable_box(struct intel_uncore_box *box)
+{
+ if (!box->io_addr)
+ return;
+
+ writel(ADL_UNCORE_IMC_CTL_FRZ, box->io_addr + uncore_mmio_box_ctl(box));
+}
+
+static void adl_uncore_mmio_enable_box(struct intel_uncore_box *box)
+{
+ if (!box->io_addr)
+ return;
+
+ writel(0, box->io_addr + uncore_mmio_box_ctl(box));
+}
+
+static struct intel_uncore_ops adl_uncore_mmio_ops = {
+ .init_box = adl_uncore_imc_init_box,
+ .exit_box = uncore_mmio_exit_box,
+ .disable_box = adl_uncore_mmio_disable_box,
+ .enable_box = adl_uncore_mmio_enable_box,
+ .disable_event = intel_generic_uncore_mmio_disable_event,
+ .enable_event = intel_generic_uncore_mmio_enable_event,
+ .read_counter = uncore_mmio_read_counter,
+};
+
+#define ADL_UNC_CTL_CHMASK_MASK 0x00000f00
+#define ADL_UNC_IMC_EVENT_MASK (SNB_UNC_CTL_EV_SEL_MASK | \
+ ADL_UNC_CTL_CHMASK_MASK | \
+ SNB_UNC_CTL_EDGE_DET)
+
+static struct attribute *adl_uncore_imc_formats_attr[] = {
+ &format_attr_event.attr,
+ &format_attr_chmask.attr,
+ &format_attr_edge.attr,
+ NULL,
+};
+
+static const struct attribute_group adl_uncore_imc_format_group = {
+ .name = "format",
+ .attrs = adl_uncore_imc_formats_attr,
+};
+
+static struct intel_uncore_type adl_uncore_imc = {
+ .name = "imc",
+ .num_counters = 5,
+ .num_boxes = 2,
+ .perf_ctr_bits = 64,
+ .perf_ctr = ADL_UNCORE_IMC_CTR,
+ .event_ctl = ADL_UNCORE_IMC_CTRL,
+ .event_mask = ADL_UNC_IMC_EVENT_MASK,
+ .box_ctl = ADL_UNCORE_IMC_BOX_CTL,
+ .mmio_offset = 0,
+ .mmio_map_size = ADL_UNCORE_IMC_MAP_SIZE,
+ .ops = &adl_uncore_mmio_ops,
+ .format_group = &adl_uncore_imc_format_group,
+};
+
+enum perf_adl_uncore_imc_freerunning_types {
+ ADL_MMIO_UNCORE_IMC_DATA_TOTAL,
+ ADL_MMIO_UNCORE_IMC_DATA_READ,
+ ADL_MMIO_UNCORE_IMC_DATA_WRITE,
+ ADL_MMIO_UNCORE_IMC_FREERUNNING_TYPE_MAX
+};
+
+static struct freerunning_counters adl_uncore_imc_freerunning[] = {
+ [ADL_MMIO_UNCORE_IMC_DATA_TOTAL] = { 0x40, 0x0, 0x0, 1, 64 },
+ [ADL_MMIO_UNCORE_IMC_DATA_READ] = { 0x58, 0x0, 0x0, 1, 64 },
+ [ADL_MMIO_UNCORE_IMC_DATA_WRITE] = { 0xA0, 0x0, 0x0, 1, 64 },
+};
+
+static void adl_uncore_imc_freerunning_init_box(struct intel_uncore_box *box)
+{
+ __uncore_imc_init_box(box, ADL_UNCORE_IMC_FREERUNNING_BASE);
+}
+
+static struct intel_uncore_ops adl_uncore_imc_freerunning_ops = {
+ .init_box = adl_uncore_imc_freerunning_init_box,
+ .exit_box = uncore_mmio_exit_box,
+ .read_counter = uncore_mmio_read_counter,
+ .hw_config = uncore_freerunning_hw_config,
+};
+
+static struct intel_uncore_type adl_uncore_imc_free_running = {
+ .name = "imc_free_running",
+ .num_counters = 3,
+ .num_boxes = 2,
+ .num_freerunning_types = ADL_MMIO_UNCORE_IMC_FREERUNNING_TYPE_MAX,
+ .mmio_map_size = ADL_UNCORE_IMC_FREERUNNING_MAP_SIZE,
+ .freerunning = adl_uncore_imc_freerunning,
+ .ops = &adl_uncore_imc_freerunning_ops,
+ .event_descs = tgl_uncore_imc_events,
+ .format_group = &tgl_uncore_imc_format_group,
+};
+
+static struct intel_uncore_type *adl_mmio_uncores[] = {
+ &adl_uncore_imc,
+ &adl_uncore_imc_free_running,
+ NULL
+};
+
+void adl_uncore_mmio_init(void)
+{
+ uncore_mmio_uncores = adl_mmio_uncores;
+}
+
+/* end of Alder Lake MMIO uncore support */
diff --git a/arch/x86/events/intel/uncore_snbep.c b/arch/x86/events/intel/uncore_snbep.c
index 3660f698fb2a..ed869443efb2 100644
--- a/arch/x86/events/intel/uncore_snbep.c
+++ b/arch/x86/events/intel/uncore_snbep.c
@@ -5482,7 +5482,7 @@ static struct intel_uncore_type icx_uncore_imc = {
.fixed_ctr_bits = 48,
.fixed_ctr = SNR_IMC_MMIO_PMON_FIXED_CTR,
.fixed_ctl = SNR_IMC_MMIO_PMON_FIXED_CTL,
- .event_descs = hswep_uncore_imc_events,
+ .event_descs = snr_uncore_imc_events,
.perf_ctr = SNR_IMC_MMIO_PMON_CTR0,
.event_ctl = SNR_IMC_MMIO_PMON_CTL0,
.event_mask = SNBEP_PMON_RAW_EVENT_MASK,
diff --git a/arch/x86/events/perf_event.h b/arch/x86/events/perf_event.h
index 9d376e528dfc..150261d929b9 100644
--- a/arch/x86/events/perf_event.h
+++ b/arch/x86/events/perf_event.h
@@ -215,7 +215,8 @@ enum {
LBR_FORMAT_EIP_FLAGS2 = 0x04,
LBR_FORMAT_INFO = 0x05,
LBR_FORMAT_TIME = 0x06,
- LBR_FORMAT_MAX_KNOWN = LBR_FORMAT_TIME,
+ LBR_FORMAT_INFO2 = 0x07,
+ LBR_FORMAT_MAX_KNOWN = LBR_FORMAT_INFO2,
};
enum {
@@ -840,6 +841,11 @@ struct x86_pmu {
bool lbr_double_abort; /* duplicated lbr aborts */
bool lbr_pt_coexist; /* (LBR|BTS) may coexist with PT */
+ unsigned int lbr_has_info:1;
+ unsigned int lbr_has_tsx:1;
+ unsigned int lbr_from_flags:1;
+ unsigned int lbr_to_cycles:1;
+
/*
* Intel Architectural LBR CPUID Enumeration
*/
@@ -1392,6 +1398,8 @@ void intel_pmu_lbr_init_skl(void);
void intel_pmu_lbr_init_knl(void);
+void intel_pmu_lbr_init(void);
+
void intel_pmu_arch_lbr_init(void);
void intel_pmu_pebs_data_source_nhm(void);
diff --git a/arch/x86/events/rapl.c b/arch/x86/events/rapl.c
index 85feafacc445..77e3a47af5ad 100644
--- a/arch/x86/events/rapl.c
+++ b/arch/x86/events/rapl.c
@@ -536,11 +536,14 @@ static struct perf_msr intel_rapl_spr_msrs[] = {
* - perf_msr_probe(PERF_RAPL_MAX)
* - want to use same event codes across both architectures
*/
-static struct perf_msr amd_rapl_msrs[PERF_RAPL_MAX] = {
- [PERF_RAPL_PKG] = { MSR_AMD_PKG_ENERGY_STATUS, &rapl_events_pkg_group, test_msr },
+static struct perf_msr amd_rapl_msrs[] = {
+ [PERF_RAPL_PP0] = { 0, &rapl_events_cores_group, 0, false, 0 },
+ [PERF_RAPL_PKG] = { MSR_AMD_PKG_ENERGY_STATUS, &rapl_events_pkg_group, test_msr, false, RAPL_MSR_MASK },
+ [PERF_RAPL_RAM] = { 0, &rapl_events_ram_group, 0, false, 0 },
+ [PERF_RAPL_PP1] = { 0, &rapl_events_gpu_group, 0, false, 0 },
+ [PERF_RAPL_PSYS] = { 0, &rapl_events_psys_group, 0, false, 0 },
};
-
static int rapl_cpu_offline(unsigned int cpu)
{
struct rapl_pmu *pmu = cpu_to_rapl_pmu(cpu);
diff --git a/arch/x86/include/asm/bug.h b/arch/x86/include/asm/bug.h
index 84b87538a15d..bab883c0b6fe 100644
--- a/arch/x86/include/asm/bug.h
+++ b/arch/x86/include/asm/bug.h
@@ -22,7 +22,7 @@
#ifdef CONFIG_DEBUG_BUGVERBOSE
-#define _BUG_FLAGS(ins, flags) \
+#define _BUG_FLAGS(ins, flags, extra) \
do { \
asm_inline volatile("1:\t" ins "\n" \
".pushsection __bug_table,\"aw\"\n" \
@@ -31,7 +31,8 @@ do { \
"\t.word %c1" "\t# bug_entry::line\n" \
"\t.word %c2" "\t# bug_entry::flags\n" \
"\t.org 2b+%c3\n" \
- ".popsection" \
+ ".popsection\n" \
+ extra \
: : "i" (__FILE__), "i" (__LINE__), \
"i" (flags), \
"i" (sizeof(struct bug_entry))); \
@@ -39,14 +40,15 @@ do { \
#else /* !CONFIG_DEBUG_BUGVERBOSE */
-#define _BUG_FLAGS(ins, flags) \
+#define _BUG_FLAGS(ins, flags, extra) \
do { \
asm_inline volatile("1:\t" ins "\n" \
".pushsection __bug_table,\"aw\"\n" \
"2:\t" __BUG_REL(1b) "\t# bug_entry::bug_addr\n" \
"\t.word %c0" "\t# bug_entry::flags\n" \
"\t.org 2b+%c1\n" \
- ".popsection" \
+ ".popsection\n" \
+ extra \
: : "i" (flags), \
"i" (sizeof(struct bug_entry))); \
} while (0)
@@ -55,7 +57,7 @@ do { \
#else
-#define _BUG_FLAGS(ins, flags) asm volatile(ins)
+#define _BUG_FLAGS(ins, flags, extra) asm volatile(ins)
#endif /* CONFIG_GENERIC_BUG */
@@ -63,8 +65,8 @@ do { \
#define BUG() \
do { \
instrumentation_begin(); \
- _BUG_FLAGS(ASM_UD2, 0); \
- unreachable(); \
+ _BUG_FLAGS(ASM_UD2, 0, ""); \
+ __builtin_unreachable(); \
} while (0)
/*
@@ -75,9 +77,9 @@ do { \
*/
#define __WARN_FLAGS(flags) \
do { \
+ __auto_type f = BUGFLAG_WARNING|(flags); \
instrumentation_begin(); \
- _BUG_FLAGS(ASM_UD2, BUGFLAG_WARNING|(flags)); \
- annotate_reachable(); \
+ _BUG_FLAGS(ASM_UD2, f, ASM_REACHABLE); \
instrumentation_end(); \
} while (0)
diff --git a/arch/x86/include/asm/coco.h b/arch/x86/include/asm/coco.h
new file mode 100644
index 000000000000..3d98c3a60d34
--- /dev/null
+++ b/arch/x86/include/asm/coco.h
@@ -0,0 +1,32 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _ASM_X86_COCO_H
+#define _ASM_X86_COCO_H
+
+#include <asm/types.h>
+
+enum cc_vendor {
+ CC_VENDOR_NONE,
+ CC_VENDOR_AMD,
+ CC_VENDOR_HYPERV,
+ CC_VENDOR_INTEL,
+};
+
+void cc_set_vendor(enum cc_vendor v);
+void cc_set_mask(u64 mask);
+
+#ifdef CONFIG_ARCH_HAS_CC_PLATFORM
+u64 cc_mkenc(u64 val);
+u64 cc_mkdec(u64 val);
+#else
+static inline u64 cc_mkenc(u64 val)
+{
+ return val;
+}
+
+static inline u64 cc_mkdec(u64 val)
+{
+ return val;
+}
+#endif
+
+#endif /* _ASM_X86_COCO_H */
diff --git a/arch/x86/include/asm/cpufeatures.h b/arch/x86/include/asm/cpufeatures.h
index 6db4e2932b3d..3edf05e98e58 100644
--- a/arch/x86/include/asm/cpufeatures.h
+++ b/arch/x86/include/asm/cpufeatures.h
@@ -204,7 +204,7 @@
/* FREE! ( 7*32+10) */
#define X86_FEATURE_PTI ( 7*32+11) /* Kernel Page Table Isolation enabled */
#define X86_FEATURE_RETPOLINE ( 7*32+12) /* "" Generic Retpoline mitigation for Spectre variant 2 */
-#define X86_FEATURE_RETPOLINE_AMD ( 7*32+13) /* "" AMD Retpoline mitigation for Spectre variant 2 */
+#define X86_FEATURE_RETPOLINE_LFENCE ( 7*32+13) /* "" Use LFENCE for Spectre variant 2 */
#define X86_FEATURE_INTEL_PPIN ( 7*32+14) /* Intel Processor Inventory Number */
#define X86_FEATURE_CDP_L2 ( 7*32+15) /* Code and Data Prioritization L2 */
#define X86_FEATURE_MSR_SPEC_CTRL ( 7*32+16) /* "" MSR SPEC_CTRL is implemented */
@@ -299,9 +299,6 @@
/* Intel-defined CPU features, CPUID level 0x00000007:1 (EAX), word 12 */
#define X86_FEATURE_AVX_VNNI (12*32+ 4) /* AVX VNNI instructions */
#define X86_FEATURE_AVX512_BF16 (12*32+ 5) /* AVX512 BFLOAT16 instructions */
-#define X86_FEATURE_AMX_BF16 (18*32+22) /* AMX bf16 Support */
-#define X86_FEATURE_AMX_TILE (18*32+24) /* AMX tile Support */
-#define X86_FEATURE_AMX_INT8 (18*32+25) /* AMX int8 Support */
/* AMD-defined CPU features, CPUID level 0x80000008 (EBX), word 13 */
#define X86_FEATURE_CLZERO (13*32+ 0) /* CLZERO instruction */
@@ -330,6 +327,7 @@
#define X86_FEATURE_HWP_ACT_WINDOW (14*32+ 9) /* HWP Activity Window */
#define X86_FEATURE_HWP_EPP (14*32+10) /* HWP Energy Perf. Preference */
#define X86_FEATURE_HWP_PKG_REQ (14*32+11) /* HWP Package Level Request */
+#define X86_FEATURE_HFI (14*32+19) /* Hardware Feedback Interface */
/* AMD SVM Feature Identification, CPUID level 0x8000000a (EDX), word 15 */
#define X86_FEATURE_NPT (15*32+ 0) /* Nested Page Table support */
@@ -390,7 +388,10 @@
#define X86_FEATURE_TSXLDTRK (18*32+16) /* TSX Suspend Load Address Tracking */
#define X86_FEATURE_PCONFIG (18*32+18) /* Intel PCONFIG */
#define X86_FEATURE_ARCH_LBR (18*32+19) /* Intel ARCH LBR */
+#define X86_FEATURE_AMX_BF16 (18*32+22) /* AMX bf16 Support */
#define X86_FEATURE_AVX512_FP16 (18*32+23) /* AVX512 FP16 */
+#define X86_FEATURE_AMX_TILE (18*32+24) /* AMX tile Support */
+#define X86_FEATURE_AMX_INT8 (18*32+25) /* AMX int8 Support */
#define X86_FEATURE_SPEC_CTRL (18*32+26) /* "" Speculation Control (IBRS + IBPB) */
#define X86_FEATURE_INTEL_STIBP (18*32+27) /* "" Single Thread Indirect Branch Predictors */
#define X86_FEATURE_FLUSH_L1D (18*32+28) /* Flush L1D cache */
diff --git a/arch/x86/include/asm/cpumask.h b/arch/x86/include/asm/cpumask.h
index 3afa990d756b..c5aed9e9226c 100644
--- a/arch/x86/include/asm/cpumask.h
+++ b/arch/x86/include/asm/cpumask.h
@@ -20,11 +20,21 @@ static __always_inline bool arch_cpu_online(int cpu)
{
return arch_test_bit(cpu, cpumask_bits(cpu_online_mask));
}
+
+static __always_inline void arch_cpumask_clear_cpu(int cpu, struct cpumask *dstp)
+{
+ arch_clear_bit(cpumask_check(cpu), cpumask_bits(dstp));
+}
#else
static __always_inline bool arch_cpu_online(int cpu)
{
return cpu == 0;
}
+
+static __always_inline void arch_cpumask_clear_cpu(int cpu, struct cpumask *dstp)
+{
+ return;
+}
#endif
#define arch_cpu_is_offline(cpu) unlikely(!arch_cpu_online(cpu))
diff --git a/arch/x86/include/asm/disabled-features.h b/arch/x86/include/asm/disabled-features.h
index 8f28fafa98b3..1231d63f836d 100644
--- a/arch/x86/include/asm/disabled-features.h
+++ b/arch/x86/include/asm/disabled-features.h
@@ -56,8 +56,11 @@
# define DISABLE_PTI (1 << (X86_FEATURE_PTI & 31))
#endif
-/* Force disable because it's broken beyond repair */
-#define DISABLE_ENQCMD (1 << (X86_FEATURE_ENQCMD & 31))
+#ifdef CONFIG_INTEL_IOMMU_SVM
+# define DISABLE_ENQCMD 0
+#else
+# define DISABLE_ENQCMD (1 << (X86_FEATURE_ENQCMD & 31))
+#endif
#ifdef CONFIG_X86_SGX
# define DISABLE_SGX 0
diff --git a/arch/x86/include/asm/insn.h b/arch/x86/include/asm/insn.h
index 05a6ab940f45..1b29f58f730f 100644
--- a/arch/x86/include/asm/insn.h
+++ b/arch/x86/include/asm/insn.h
@@ -124,7 +124,7 @@ struct insn {
#define X86_VEX_B(vex) ((vex) & 0x20) /* VEX3 Byte1 */
#define X86_VEX_L(vex) ((vex) & 0x04) /* VEX3 Byte2, VEX2 Byte1 */
/* VEX bit fields */
-#define X86_EVEX_M(vex) ((vex) & 0x03) /* EVEX Byte1 */
+#define X86_EVEX_M(vex) ((vex) & 0x07) /* EVEX Byte1 */
#define X86_VEX3_M(vex) ((vex) & 0x1f) /* VEX3 Byte1 */
#define X86_VEX2_M 1 /* VEX2.M always 1 */
#define X86_VEX_V(vex) (((vex) & 0x78) >> 3) /* VEX3 Byte2, VEX2 Byte1 */
diff --git a/arch/x86/include/asm/intel_ds.h b/arch/x86/include/asm/intel_ds.h
index 8380c3ddd4b2..2f9eeb5c3069 100644
--- a/arch/x86/include/asm/intel_ds.h
+++ b/arch/x86/include/asm/intel_ds.h
@@ -7,8 +7,9 @@
#define PEBS_BUFFER_SIZE (PAGE_SIZE << 4)
/* The maximal number of PEBS events: */
-#define MAX_PEBS_EVENTS 8
-#define MAX_FIXED_PEBS_EVENTS 4
+#define MAX_PEBS_EVENTS_FMT4 8
+#define MAX_PEBS_EVENTS 32
+#define MAX_FIXED_PEBS_EVENTS 16
/*
* A debug store configuration.
diff --git a/arch/x86/include/asm/intel_pt.h b/arch/x86/include/asm/intel_pt.h
index ebe8d2ea44fe..c796e9bc98b6 100644
--- a/arch/x86/include/asm/intel_pt.h
+++ b/arch/x86/include/asm/intel_pt.h
@@ -13,6 +13,8 @@ enum pt_capabilities {
PT_CAP_mtc,
PT_CAP_ptwrite,
PT_CAP_power_event_trace,
+ PT_CAP_event_trace,
+ PT_CAP_tnt_disable,
PT_CAP_topa_output,
PT_CAP_topa_multiple_entries,
PT_CAP_single_range_output,
diff --git a/arch/x86/include/asm/kvm-x86-ops.h b/arch/x86/include/asm/kvm-x86-ops.h
index 631d5040b31e..3c368b639c04 100644
--- a/arch/x86/include/asm/kvm-x86-ops.h
+++ b/arch/x86/include/asm/kvm-x86-ops.h
@@ -1,29 +1,30 @@
/* SPDX-License-Identifier: GPL-2.0 */
-#if !defined(KVM_X86_OP) || !defined(KVM_X86_OP_NULL)
+#if !defined(KVM_X86_OP) || !defined(KVM_X86_OP_OPTIONAL)
BUILD_BUG_ON(1)
#endif
/*
- * KVM_X86_OP() and KVM_X86_OP_NULL() are used to help generate
- * "static_call()"s. They are also intended for use when defining
- * the vmx/svm kvm_x86_ops. KVM_X86_OP() can be used for those
- * functions that follow the [svm|vmx]_func_name convention.
- * KVM_X86_OP_NULL() can leave a NULL definition for the
- * case where there is no definition or a function name that
- * doesn't match the typical naming convention is supplied.
+ * KVM_X86_OP() and KVM_X86_OP_OPTIONAL() are used to help generate
+ * both DECLARE/DEFINE_STATIC_CALL() invocations and
+ * "static_call_update()" calls.
+ *
+ * KVM_X86_OP_OPTIONAL() can be used for those functions that can have
+ * a NULL definition, for example if "static_call_cond()" will be used
+ * at the call sites. KVM_X86_OP_OPTIONAL_RET0() can be used likewise
+ * to make a definition optional, but in this case the default will
+ * be __static_call_return0.
*/
-KVM_X86_OP_NULL(hardware_enable)
-KVM_X86_OP_NULL(hardware_disable)
-KVM_X86_OP_NULL(hardware_unsetup)
-KVM_X86_OP_NULL(cpu_has_accelerated_tpr)
+KVM_X86_OP(hardware_enable)
+KVM_X86_OP(hardware_disable)
+KVM_X86_OP(hardware_unsetup)
KVM_X86_OP(has_emulated_msr)
KVM_X86_OP(vcpu_after_set_cpuid)
KVM_X86_OP(vm_init)
-KVM_X86_OP_NULL(vm_destroy)
+KVM_X86_OP_OPTIONAL(vm_destroy)
KVM_X86_OP(vcpu_create)
KVM_X86_OP(vcpu_free)
KVM_X86_OP(vcpu_reset)
-KVM_X86_OP(prepare_guest_switch)
+KVM_X86_OP(prepare_switch_to_guest)
KVM_X86_OP(vcpu_load)
KVM_X86_OP(vcpu_put)
KVM_X86_OP(update_exception_bitmap)
@@ -33,9 +34,9 @@ KVM_X86_OP(get_segment_base)
KVM_X86_OP(get_segment)
KVM_X86_OP(get_cpl)
KVM_X86_OP(set_segment)
-KVM_X86_OP_NULL(get_cs_db_l_bits)
+KVM_X86_OP(get_cs_db_l_bits)
KVM_X86_OP(set_cr0)
-KVM_X86_OP_NULL(post_set_cr3)
+KVM_X86_OP_OPTIONAL(post_set_cr3)
KVM_X86_OP(is_valid_cr4)
KVM_X86_OP(set_cr4)
KVM_X86_OP(set_efer)
@@ -49,22 +50,22 @@ KVM_X86_OP(cache_reg)
KVM_X86_OP(get_rflags)
KVM_X86_OP(set_rflags)
KVM_X86_OP(get_if_flag)
-KVM_X86_OP(tlb_flush_all)
-KVM_X86_OP(tlb_flush_current)
-KVM_X86_OP_NULL(tlb_remote_flush)
-KVM_X86_OP_NULL(tlb_remote_flush_with_range)
-KVM_X86_OP(tlb_flush_gva)
-KVM_X86_OP(tlb_flush_guest)
+KVM_X86_OP(flush_tlb_all)
+KVM_X86_OP(flush_tlb_current)
+KVM_X86_OP_OPTIONAL(tlb_remote_flush)
+KVM_X86_OP_OPTIONAL(tlb_remote_flush_with_range)
+KVM_X86_OP(flush_tlb_gva)
+KVM_X86_OP(flush_tlb_guest)
KVM_X86_OP(vcpu_pre_run)
-KVM_X86_OP(run)
-KVM_X86_OP_NULL(handle_exit)
-KVM_X86_OP_NULL(skip_emulated_instruction)
-KVM_X86_OP_NULL(update_emulated_instruction)
+KVM_X86_OP(vcpu_run)
+KVM_X86_OP(handle_exit)
+KVM_X86_OP(skip_emulated_instruction)
+KVM_X86_OP_OPTIONAL(update_emulated_instruction)
KVM_X86_OP(set_interrupt_shadow)
KVM_X86_OP(get_interrupt_shadow)
KVM_X86_OP(patch_hypercall)
-KVM_X86_OP(set_irq)
-KVM_X86_OP(set_nmi)
+KVM_X86_OP(inject_irq)
+KVM_X86_OP(inject_nmi)
KVM_X86_OP(queue_exception)
KVM_X86_OP(cancel_injection)
KVM_X86_OP(interrupt_allowed)
@@ -73,22 +74,22 @@ KVM_X86_OP(get_nmi_mask)
KVM_X86_OP(set_nmi_mask)
KVM_X86_OP(enable_nmi_window)
KVM_X86_OP(enable_irq_window)
-KVM_X86_OP(update_cr8_intercept)
+KVM_X86_OP_OPTIONAL(update_cr8_intercept)
KVM_X86_OP(check_apicv_inhibit_reasons)
KVM_X86_OP(refresh_apicv_exec_ctrl)
-KVM_X86_OP(hwapic_irr_update)
-KVM_X86_OP(hwapic_isr_update)
-KVM_X86_OP_NULL(guest_apic_has_interrupt)
-KVM_X86_OP(load_eoi_exitmap)
-KVM_X86_OP(set_virtual_apic_mode)
-KVM_X86_OP_NULL(set_apic_access_page_addr)
-KVM_X86_OP(deliver_posted_interrupt)
-KVM_X86_OP_NULL(sync_pir_to_irr)
-KVM_X86_OP(set_tss_addr)
-KVM_X86_OP(set_identity_map_addr)
+KVM_X86_OP_OPTIONAL(hwapic_irr_update)
+KVM_X86_OP_OPTIONAL(hwapic_isr_update)
+KVM_X86_OP_OPTIONAL_RET0(guest_apic_has_interrupt)
+KVM_X86_OP_OPTIONAL(load_eoi_exitmap)
+KVM_X86_OP_OPTIONAL(set_virtual_apic_mode)
+KVM_X86_OP_OPTIONAL(set_apic_access_page_addr)
+KVM_X86_OP(deliver_interrupt)
+KVM_X86_OP_OPTIONAL(sync_pir_to_irr)
+KVM_X86_OP_OPTIONAL_RET0(set_tss_addr)
+KVM_X86_OP_OPTIONAL_RET0(set_identity_map_addr)
KVM_X86_OP(get_mt_mask)
KVM_X86_OP(load_mmu_pgd)
-KVM_X86_OP_NULL(has_wbinvd_exit)
+KVM_X86_OP(has_wbinvd_exit)
KVM_X86_OP(get_l2_tsc_offset)
KVM_X86_OP(get_l2_tsc_multiplier)
KVM_X86_OP(write_tsc_offset)
@@ -96,32 +97,36 @@ 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_NULL(request_immediate_exit)
+KVM_X86_OP(request_immediate_exit)
KVM_X86_OP(sched_in)
-KVM_X86_OP_NULL(update_cpu_dirty_logging)
-KVM_X86_OP_NULL(vcpu_blocking)
-KVM_X86_OP_NULL(vcpu_unblocking)
-KVM_X86_OP_NULL(update_pi_irte)
-KVM_X86_OP_NULL(start_assignment)
-KVM_X86_OP_NULL(apicv_post_state_restore)
-KVM_X86_OP_NULL(dy_apicv_has_pending_interrupt)
-KVM_X86_OP_NULL(set_hv_timer)
-KVM_X86_OP_NULL(cancel_hv_timer)
+KVM_X86_OP_OPTIONAL(update_cpu_dirty_logging)
+KVM_X86_OP_OPTIONAL(vcpu_blocking)
+KVM_X86_OP_OPTIONAL(vcpu_unblocking)
+KVM_X86_OP_OPTIONAL(pi_update_irte)
+KVM_X86_OP_OPTIONAL(pi_start_assignment)
+KVM_X86_OP_OPTIONAL(apicv_post_state_restore)
+KVM_X86_OP_OPTIONAL_RET0(dy_apicv_has_pending_interrupt)
+KVM_X86_OP_OPTIONAL(set_hv_timer)
+KVM_X86_OP_OPTIONAL(cancel_hv_timer)
KVM_X86_OP(setup_mce)
KVM_X86_OP(smi_allowed)
KVM_X86_OP(enter_smm)
KVM_X86_OP(leave_smm)
KVM_X86_OP(enable_smi_window)
-KVM_X86_OP_NULL(mem_enc_op)
-KVM_X86_OP_NULL(mem_enc_reg_region)
-KVM_X86_OP_NULL(mem_enc_unreg_region)
+KVM_X86_OP_OPTIONAL(mem_enc_ioctl)
+KVM_X86_OP_OPTIONAL(mem_enc_register_region)
+KVM_X86_OP_OPTIONAL(mem_enc_unregister_region)
+KVM_X86_OP_OPTIONAL(vm_copy_enc_context_from)
+KVM_X86_OP_OPTIONAL(vm_move_enc_context_from)
KVM_X86_OP(get_msr_feature)
KVM_X86_OP(can_emulate_instruction)
KVM_X86_OP(apic_init_signal_blocked)
-KVM_X86_OP_NULL(enable_direct_tlbflush)
-KVM_X86_OP_NULL(migrate_timers)
+KVM_X86_OP_OPTIONAL(enable_direct_tlbflush)
+KVM_X86_OP_OPTIONAL(migrate_timers)
KVM_X86_OP(msr_filter_changed)
-KVM_X86_OP_NULL(complete_emulated_msr)
+KVM_X86_OP(complete_emulated_msr)
+KVM_X86_OP(vcpu_deliver_sipi_vector)
#undef KVM_X86_OP
-#undef KVM_X86_OP_NULL
+#undef KVM_X86_OP_OPTIONAL
+#undef KVM_X86_OP_OPTIONAL_RET0
diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index 1384517d7709..4138939532c6 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -15,6 +15,7 @@
#include <linux/cpumask.h>
#include <linux/irq_work.h>
#include <linux/irq.h>
+#include <linux/workqueue.h>
#include <linux/kvm.h>
#include <linux/kvm_para.h>
@@ -102,6 +103,8 @@
#define KVM_REQ_MSR_FILTER_CHANGED KVM_ARCH_REQ(29)
#define KVM_REQ_UPDATE_CPU_DIRTY_LOGGING \
KVM_ARCH_REQ_FLAGS(30, KVM_REQUEST_WAIT | KVM_REQUEST_NO_WAKEUP)
+#define KVM_REQ_MMU_FREE_OBSOLETE_ROOTS \
+ KVM_ARCH_REQ_FLAGS(31, KVM_REQUEST_WAIT | KVM_REQUEST_NO_WAKEUP)
#define CR0_RESERVED_BITS \
(~(unsigned long)(X86_CR0_PE | X86_CR0_MP | X86_CR0_EM | X86_CR0_TS \
@@ -432,8 +435,7 @@ struct kvm_mmu {
int (*sync_page)(struct kvm_vcpu *vcpu,
struct kvm_mmu_page *sp);
void (*invlpg)(struct kvm_vcpu *vcpu, gva_t gva, hpa_t root_hpa);
- hpa_t root_hpa;
- gpa_t root_pgd;
+ struct kvm_mmu_root_info root;
union kvm_mmu_role mmu_role;
u8 root_level;
u8 shadow_root_level;
@@ -498,6 +500,7 @@ struct kvm_pmc {
bool intr;
};
+#define KVM_PMC_MAX_FIXED 3
struct kvm_pmu {
unsigned nr_arch_gp_counters;
unsigned nr_arch_fixed_counters;
@@ -511,7 +514,7 @@ struct kvm_pmu {
u64 reserved_bits;
u8 version;
struct kvm_pmc gp_counters[INTEL_PMC_MAX_GENERIC];
- struct kvm_pmc fixed_counters[INTEL_PMC_MAX_FIXED];
+ struct kvm_pmc fixed_counters[KVM_PMC_MAX_FIXED];
struct irq_work irq_work;
DECLARE_BITMAP(reprogram_pmi, X86_PMC_IDX_MAX);
DECLARE_BITMAP(all_valid_pmc_idx, X86_PMC_IDX_MAX);
@@ -703,7 +706,6 @@ struct kvm_vcpu_arch {
struct fpu_guest guest_fpu;
u64 xcr0;
- u64 guest_supported_xcr0;
struct kvm_pio_request pio;
void *pio_data;
@@ -1128,10 +1130,6 @@ struct kvm_arch {
struct kvm_hv hyperv;
struct kvm_xen xen;
- #ifdef CONFIG_KVM_MMU_AUDIT
- int audit_point;
- #endif
-
bool backwards_tsc_observed;
bool boot_vcpu_runs_old_kvmclock;
u32 bsp_vcpu_id;
@@ -1151,6 +1149,7 @@ struct kvm_arch {
bool exception_payload_enabled;
bool bus_lock_detection_enabled;
+ bool enable_pmu;
/*
* If exit_on_emulation_error is set, and the in-kernel instruction
* emulator fails to emulate an instruction, allow userspace
@@ -1220,6 +1219,7 @@ struct kvm_arch {
* the thread holds the MMU lock in write mode.
*/
spinlock_t tdp_mmu_pages_lock;
+ struct workqueue_struct *tdp_mmu_zap_wq;
#endif /* CONFIG_X86_64 */
/*
@@ -1318,7 +1318,6 @@ struct kvm_x86_ops {
int (*hardware_enable)(void);
void (*hardware_disable)(void);
void (*hardware_unsetup)(void);
- bool (*cpu_has_accelerated_tpr)(void);
bool (*has_emulated_msr)(struct kvm *kvm, u32 index);
void (*vcpu_after_set_cpuid)(struct kvm_vcpu *vcpu);
@@ -1331,7 +1330,7 @@ struct kvm_x86_ops {
void (*vcpu_free)(struct kvm_vcpu *vcpu);
void (*vcpu_reset)(struct kvm_vcpu *vcpu, bool init_event);
- void (*prepare_guest_switch)(struct kvm_vcpu *vcpu);
+ void (*prepare_switch_to_guest)(struct kvm_vcpu *vcpu);
void (*vcpu_load)(struct kvm_vcpu *vcpu, int cpu);
void (*vcpu_put)(struct kvm_vcpu *vcpu);
@@ -1361,8 +1360,8 @@ struct kvm_x86_ops {
void (*set_rflags)(struct kvm_vcpu *vcpu, unsigned long rflags);
bool (*get_if_flag)(struct kvm_vcpu *vcpu);
- void (*tlb_flush_all)(struct kvm_vcpu *vcpu);
- void (*tlb_flush_current)(struct kvm_vcpu *vcpu);
+ void (*flush_tlb_all)(struct kvm_vcpu *vcpu);
+ void (*flush_tlb_current)(struct kvm_vcpu *vcpu);
int (*tlb_remote_flush)(struct kvm *kvm);
int (*tlb_remote_flush_with_range)(struct kvm *kvm,
struct kvm_tlb_range *range);
@@ -1373,16 +1372,16 @@ struct kvm_x86_ops {
* Can potentially get non-canonical addresses through INVLPGs, which
* the implementation may choose to ignore if appropriate.
*/
- void (*tlb_flush_gva)(struct kvm_vcpu *vcpu, gva_t addr);
+ void (*flush_tlb_gva)(struct kvm_vcpu *vcpu, gva_t addr);
/*
* Flush any TLB entries created by the guest. Like tlb_flush_gva(),
* does not need to flush GPA->HPA mappings.
*/
- void (*tlb_flush_guest)(struct kvm_vcpu *vcpu);
+ void (*flush_tlb_guest)(struct kvm_vcpu *vcpu);
int (*vcpu_pre_run)(struct kvm_vcpu *vcpu);
- enum exit_fastpath_completion (*run)(struct kvm_vcpu *vcpu);
+ enum exit_fastpath_completion (*vcpu_run)(struct kvm_vcpu *vcpu);
int (*handle_exit)(struct kvm_vcpu *vcpu,
enum exit_fastpath_completion exit_fastpath);
int (*skip_emulated_instruction)(struct kvm_vcpu *vcpu);
@@ -1391,8 +1390,8 @@ struct kvm_x86_ops {
u32 (*get_interrupt_shadow)(struct kvm_vcpu *vcpu);
void (*patch_hypercall)(struct kvm_vcpu *vcpu,
unsigned char *hypercall_addr);
- void (*set_irq)(struct kvm_vcpu *vcpu);
- void (*set_nmi)(struct kvm_vcpu *vcpu);
+ void (*inject_irq)(struct kvm_vcpu *vcpu);
+ void (*inject_nmi)(struct kvm_vcpu *vcpu);
void (*queue_exception)(struct kvm_vcpu *vcpu);
void (*cancel_injection)(struct kvm_vcpu *vcpu);
int (*interrupt_allowed)(struct kvm_vcpu *vcpu, bool for_injection);
@@ -1410,7 +1409,8 @@ struct kvm_x86_ops {
void (*load_eoi_exitmap)(struct kvm_vcpu *vcpu, u64 *eoi_exit_bitmap);
void (*set_virtual_apic_mode)(struct kvm_vcpu *vcpu);
void (*set_apic_access_page_addr)(struct kvm_vcpu *vcpu);
- int (*deliver_posted_interrupt)(struct kvm_vcpu *vcpu, int vector);
+ void (*deliver_interrupt)(struct kvm_lapic *apic, int delivery_mode,
+ int trig_mode, int vector);
int (*sync_pir_to_irr)(struct kvm_vcpu *vcpu);
int (*set_tss_addr)(struct kvm *kvm, unsigned int addr);
int (*set_identity_map_addr)(struct kvm *kvm, u64 ident_addr);
@@ -1458,9 +1458,9 @@ struct kvm_x86_ops {
void (*vcpu_blocking)(struct kvm_vcpu *vcpu);
void (*vcpu_unblocking)(struct kvm_vcpu *vcpu);
- int (*update_pi_irte)(struct kvm *kvm, unsigned int host_irq,
+ int (*pi_update_irte)(struct kvm *kvm, unsigned int host_irq,
uint32_t guest_irq, bool set);
- void (*start_assignment)(struct kvm *kvm);
+ void (*pi_start_assignment)(struct kvm *kvm);
void (*apicv_post_state_restore)(struct kvm_vcpu *vcpu);
bool (*dy_apicv_has_pending_interrupt)(struct kvm_vcpu *vcpu);
@@ -1475,15 +1475,16 @@ struct kvm_x86_ops {
int (*leave_smm)(struct kvm_vcpu *vcpu, const char *smstate);
void (*enable_smi_window)(struct kvm_vcpu *vcpu);
- int (*mem_enc_op)(struct kvm *kvm, void __user *argp);
- int (*mem_enc_reg_region)(struct kvm *kvm, struct kvm_enc_region *argp);
- int (*mem_enc_unreg_region)(struct kvm *kvm, struct kvm_enc_region *argp);
+ int (*mem_enc_ioctl)(struct kvm *kvm, void __user *argp);
+ int (*mem_enc_register_region)(struct kvm *kvm, struct kvm_enc_region *argp);
+ int (*mem_enc_unregister_region)(struct kvm *kvm, struct kvm_enc_region *argp);
int (*vm_copy_enc_context_from)(struct kvm *kvm, unsigned int source_fd);
int (*vm_move_enc_context_from)(struct kvm *kvm, unsigned int source_fd);
int (*get_msr_feature)(struct kvm_msr_entry *entry);
- bool (*can_emulate_instruction)(struct kvm_vcpu *vcpu, void *insn, int insn_len);
+ bool (*can_emulate_instruction)(struct kvm_vcpu *vcpu, int emul_type,
+ void *insn, int insn_len);
bool (*apic_init_signal_blocked)(struct kvm_vcpu *vcpu);
int (*enable_direct_tlbflush)(struct kvm_vcpu *vcpu);
@@ -1496,6 +1497,7 @@ struct kvm_x86_ops {
};
struct kvm_x86_nested_ops {
+ void (*leave_nested)(struct kvm_vcpu *vcpu);
int (*check_events)(struct kvm_vcpu *vcpu);
bool (*hv_timer_pending)(struct kvm_vcpu *vcpu);
void (*triple_fault)(struct kvm_vcpu *vcpu);
@@ -1538,15 +1540,22 @@ extern struct kvm_x86_ops kvm_x86_ops;
#define KVM_X86_OP(func) \
DECLARE_STATIC_CALL(kvm_x86_##func, *(((struct kvm_x86_ops *)0)->func));
-#define KVM_X86_OP_NULL KVM_X86_OP
+#define KVM_X86_OP_OPTIONAL KVM_X86_OP
+#define KVM_X86_OP_OPTIONAL_RET0 KVM_X86_OP
#include <asm/kvm-x86-ops.h>
static inline void kvm_ops_static_call_update(void)
{
-#define KVM_X86_OP(func) \
+#define __KVM_X86_OP(func) \
static_call_update(kvm_x86_##func, kvm_x86_ops.func);
-#define KVM_X86_OP_NULL KVM_X86_OP
+#define KVM_X86_OP(func) \
+ WARN_ON(!kvm_x86_ops.func); __KVM_X86_OP(func)
+#define KVM_X86_OP_OPTIONAL __KVM_X86_OP
+#define KVM_X86_OP_OPTIONAL_RET0(func) \
+ static_call_update(kvm_x86_##func, (void *)kvm_x86_ops.func ? : \
+ (void *)__static_call_return0);
#include <asm/kvm-x86-ops.h>
+#undef __KVM_X86_OP
}
#define __KVM_HAVE_ARCH_VM_ALLOC
@@ -1584,6 +1593,13 @@ void kvm_mmu_reset_context(struct kvm_vcpu *vcpu);
void kvm_mmu_slot_remove_write_access(struct kvm *kvm,
const struct kvm_memory_slot *memslot,
int start_level);
+void kvm_mmu_slot_try_split_huge_pages(struct kvm *kvm,
+ const struct kvm_memory_slot *memslot,
+ int target_level);
+void kvm_mmu_try_split_huge_pages(struct kvm *kvm,
+ const struct kvm_memory_slot *memslot,
+ u64 start, u64 end,
+ int target_level);
void kvm_mmu_zap_collapsible_sptes(struct kvm *kvm,
const struct kvm_memory_slot *memslot);
void kvm_mmu_slot_leaf_clear_dirty(struct kvm *kvm,
@@ -1721,7 +1737,6 @@ 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_cr8(struct kvm_vcpu *vcpu);
void kvm_lmsw(struct kvm_vcpu *vcpu, unsigned long msw);
-void kvm_get_cs_db_l_bits(struct kvm_vcpu *vcpu, int *db, int *l);
int kvm_emulate_xsetbv(struct kvm_vcpu *vcpu);
int kvm_get_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr);
@@ -1766,9 +1781,9 @@ void kvm_inject_nmi(struct kvm_vcpu *vcpu);
void kvm_update_dr7(struct kvm_vcpu *vcpu);
int kvm_mmu_unprotect_page(struct kvm *kvm, gfn_t gfn);
-void kvm_mmu_free_roots(struct kvm_vcpu *vcpu, struct kvm_mmu *mmu,
+void kvm_mmu_free_roots(struct kvm *kvm, struct kvm_mmu *mmu,
ulong roots_to_free);
-void kvm_mmu_free_guest_mode_roots(struct kvm_vcpu *vcpu, struct kvm_mmu *mmu);
+void kvm_mmu_free_guest_mode_roots(struct kvm *kvm, struct kvm_mmu *mmu);
gpa_t kvm_mmu_gva_to_gpa_read(struct kvm_vcpu *vcpu, gva_t gva,
struct x86_exception *exception);
gpa_t kvm_mmu_gva_to_gpa_fetch(struct kvm_vcpu *vcpu, gva_t gva,
@@ -1861,7 +1876,6 @@ int kvm_cpu_has_extint(struct kvm_vcpu *v);
int kvm_arch_interrupt_allowed(struct kvm_vcpu *vcpu);
int kvm_cpu_get_interrupt(struct kvm_vcpu *v);
void kvm_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event);
-void kvm_vcpu_reload_apic_access_page(struct kvm_vcpu *vcpu);
int kvm_pv_send_ipi(struct kvm *kvm, unsigned long ipi_bitmap_low,
unsigned long ipi_bitmap_high, u32 min,
@@ -1876,7 +1890,7 @@ static inline bool kvm_is_supported_user_return_msr(u32 msr)
return kvm_find_user_return_msr(msr) >= 0;
}
-u64 kvm_scale_tsc(struct kvm_vcpu *vcpu, u64 tsc, u64 ratio);
+u64 kvm_scale_tsc(u64 tsc, u64 ratio);
u64 kvm_read_l1_tsc(struct kvm_vcpu *vcpu, u64 host_tsc);
u64 kvm_calc_nested_tsc_offset(u64 l1_offset, u64 l2_offset, u64 l2_multiplier);
u64 kvm_calc_nested_tsc_multiplier(u64 l1_multiplier, u64 l2_multiplier);
@@ -1953,4 +1967,11 @@ int memslot_rmap_alloc(struct kvm_memory_slot *slot, unsigned long npages);
#define KVM_CLOCK_VALID_FLAGS \
(KVM_CLOCK_TSC_STABLE | KVM_CLOCK_REALTIME | KVM_CLOCK_HOST_TSC)
+#define KVM_X86_VALID_QUIRKS \
+ (KVM_X86_QUIRK_LINT0_REENABLED | \
+ KVM_X86_QUIRK_CD_NW_CLEARED | \
+ KVM_X86_QUIRK_LAPIC_MMIO_HOLE | \
+ KVM_X86_QUIRK_OUT_7E_INC_RIP | \
+ KVM_X86_QUIRK_MISC_ENABLE_NO_MWAIT)
+
#endif /* _ASM_X86_KVM_HOST_H */
diff --git a/arch/x86/include/asm/microcode_amd.h b/arch/x86/include/asm/microcode_amd.h
index 7063b5a43220..ac31f9140d07 100644
--- a/arch/x86/include/asm/microcode_amd.h
+++ b/arch/x86/include/asm/microcode_amd.h
@@ -38,7 +38,7 @@ struct microcode_header_amd {
struct microcode_amd {
struct microcode_header_amd hdr;
- unsigned int mpb[0];
+ unsigned int mpb[];
};
#define PATCH_MAX_SIZE (3 * PAGE_SIZE)
diff --git a/arch/x86/include/asm/microcode_intel.h b/arch/x86/include/asm/microcode_intel.h
index d85a07d7154f..4c92cea7e4b5 100644
--- a/arch/x86/include/asm/microcode_intel.h
+++ b/arch/x86/include/asm/microcode_intel.h
@@ -19,7 +19,7 @@ struct microcode_header_intel {
struct microcode_intel {
struct microcode_header_intel hdr;
- unsigned int bits[0];
+ unsigned int bits[];
};
/* microcode format is extended from prescott processors */
@@ -33,7 +33,7 @@ struct extended_sigtable {
unsigned int count;
unsigned int cksum;
unsigned int reserved[3];
- struct extended_signature sigs[0];
+ struct extended_signature sigs[];
};
#define DEFAULT_UCODE_DATASIZE (2000)
diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h
index 3faf0f97edb1..9f1741ac4769 100644
--- a/arch/x86/include/asm/msr-index.h
+++ b/arch/x86/include/asm/msr-index.h
@@ -205,6 +205,8 @@
#define RTIT_CTL_DISRETC BIT(11)
#define RTIT_CTL_PTW_EN BIT(12)
#define RTIT_CTL_BRANCH_EN BIT(13)
+#define RTIT_CTL_EVENT_EN BIT(31)
+#define RTIT_CTL_NOTNT BIT_ULL(55)
#define RTIT_CTL_MTC_RANGE_OFFSET 14
#define RTIT_CTL_MTC_RANGE (0x0full << RTIT_CTL_MTC_RANGE_OFFSET)
#define RTIT_CTL_CYC_THRESH_OFFSET 19
@@ -476,6 +478,7 @@
#define MSR_AMD64_ICIBSEXTDCTL 0xc001103c
#define MSR_AMD64_IBSOPDATA4 0xc001103d
#define MSR_AMD64_IBS_REG_COUNT_MAX 8 /* includes MSR_AMD64_IBSBRTARGET */
+#define MSR_AMD64_SVM_AVIC_DOORBELL 0xc001011b
#define MSR_AMD64_VM_PAGE_FLUSH 0xc001011e
#define MSR_AMD64_SEV_ES_GHCB 0xc0010130
#define MSR_AMD64_SEV 0xc0010131
@@ -704,12 +707,14 @@
#define PACKAGE_THERM_STATUS_PROCHOT (1 << 0)
#define PACKAGE_THERM_STATUS_POWER_LIMIT (1 << 10)
+#define PACKAGE_THERM_STATUS_HFI_UPDATED (1 << 26)
#define MSR_IA32_PACKAGE_THERM_INTERRUPT 0x000001b2
#define PACKAGE_THERM_INT_HIGH_ENABLE (1 << 0)
#define PACKAGE_THERM_INT_LOW_ENABLE (1 << 1)
#define PACKAGE_THERM_INT_PLN_ENABLE (1 << 24)
+#define PACKAGE_THERM_INT_HFI_ENABLE (1 << 25)
/* Thermal Thresholds Support */
#define THERM_INT_THRESHOLD0_ENABLE (1 << 15)
@@ -958,4 +963,8 @@
#define MSR_VM_IGNNE 0xc0010115
#define MSR_VM_HSAVE_PA 0xc0010117
+/* Hardware Feedback Interface */
+#define MSR_IA32_HW_FEEDBACK_PTR 0x17d0
+#define MSR_IA32_HW_FEEDBACK_CONFIG 0x17d1
+
#endif /* _ASM_X86_MSR_INDEX_H */
diff --git a/arch/x86/include/asm/nospec-branch.h b/arch/x86/include/asm/nospec-branch.h
index cc74dc584836..acbaeaf83b61 100644
--- a/arch/x86/include/asm/nospec-branch.h
+++ b/arch/x86/include/asm/nospec-branch.h
@@ -84,7 +84,7 @@
#ifdef CONFIG_RETPOLINE
ALTERNATIVE_2 __stringify(ANNOTATE_RETPOLINE_SAFE; jmp *%\reg), \
__stringify(jmp __x86_indirect_thunk_\reg), X86_FEATURE_RETPOLINE, \
- __stringify(lfence; ANNOTATE_RETPOLINE_SAFE; jmp *%\reg), X86_FEATURE_RETPOLINE_AMD
+ __stringify(lfence; ANNOTATE_RETPOLINE_SAFE; jmp *%\reg), X86_FEATURE_RETPOLINE_LFENCE
#else
jmp *%\reg
#endif
@@ -94,7 +94,7 @@
#ifdef CONFIG_RETPOLINE
ALTERNATIVE_2 __stringify(ANNOTATE_RETPOLINE_SAFE; call *%\reg), \
__stringify(call __x86_indirect_thunk_\reg), X86_FEATURE_RETPOLINE, \
- __stringify(lfence; ANNOTATE_RETPOLINE_SAFE; call *%\reg), X86_FEATURE_RETPOLINE_AMD
+ __stringify(lfence; ANNOTATE_RETPOLINE_SAFE; call *%\reg), X86_FEATURE_RETPOLINE_LFENCE
#else
call *%\reg
#endif
@@ -146,7 +146,7 @@ extern retpoline_thunk_t __x86_indirect_thunk_array[];
"lfence;\n" \
ANNOTATE_RETPOLINE_SAFE \
"call *%[thunk_target]\n", \
- X86_FEATURE_RETPOLINE_AMD)
+ X86_FEATURE_RETPOLINE_LFENCE)
# define THUNK_TARGET(addr) [thunk_target] "r" (addr)
@@ -176,7 +176,7 @@ extern retpoline_thunk_t __x86_indirect_thunk_array[];
"lfence;\n" \
ANNOTATE_RETPOLINE_SAFE \
"call *%[thunk_target]\n", \
- X86_FEATURE_RETPOLINE_AMD)
+ X86_FEATURE_RETPOLINE_LFENCE)
# define THUNK_TARGET(addr) [thunk_target] "rm" (addr)
#endif
@@ -188,9 +188,11 @@ extern retpoline_thunk_t __x86_indirect_thunk_array[];
/* The Spectre V2 mitigation variants */
enum spectre_v2_mitigation {
SPECTRE_V2_NONE,
- SPECTRE_V2_RETPOLINE_GENERIC,
- SPECTRE_V2_RETPOLINE_AMD,
- SPECTRE_V2_IBRS_ENHANCED,
+ SPECTRE_V2_RETPOLINE,
+ SPECTRE_V2_LFENCE,
+ SPECTRE_V2_EIBRS,
+ SPECTRE_V2_EIBRS_RETPOLINE,
+ SPECTRE_V2_EIBRS_LFENCE,
};
/* The indirect branch speculation control variants */
diff --git a/arch/x86/include/asm/page.h b/arch/x86/include/asm/page.h
index 4d5810c8fab7..9cc82f305f4b 100644
--- a/arch/x86/include/asm/page.h
+++ b/arch/x86/include/asm/page.h
@@ -71,6 +71,16 @@ static inline void copy_user_page(void *to, void *from, unsigned long vaddr,
extern bool __virt_addr_valid(unsigned long kaddr);
#define virt_addr_valid(kaddr) __virt_addr_valid((unsigned long) (kaddr))
+static __always_inline u64 __canonical_address(u64 vaddr, u8 vaddr_bits)
+{
+ return ((s64)vaddr << (64 - vaddr_bits)) >> (64 - vaddr_bits);
+}
+
+static __always_inline u64 __is_canonical_address(u64 vaddr, u8 vaddr_bits)
+{
+ return __canonical_address(vaddr, vaddr_bits) == vaddr;
+}
+
#endif /* __ASSEMBLY__ */
#include <asm-generic/memory_model.h>
diff --git a/arch/x86/include/asm/paravirt_api_clock.h b/arch/x86/include/asm/paravirt_api_clock.h
new file mode 100644
index 000000000000..65ac7cee0dad
--- /dev/null
+++ b/arch/x86/include/asm/paravirt_api_clock.h
@@ -0,0 +1 @@
+#include <asm/paravirt.h>
diff --git a/arch/x86/include/asm/paravirt_types.h b/arch/x86/include/asm/paravirt_types.h
index a69012e1903f..e1591467668e 100644
--- a/arch/x86/include/asm/paravirt_types.h
+++ b/arch/x86/include/asm/paravirt_types.h
@@ -279,7 +279,7 @@ extern void (*paravirt_iret)(void);
#define paravirt_type(op) \
[paravirt_typenum] "i" (PARAVIRT_PATCH(op)), \
- [paravirt_opptr] "i" (&(pv_ops.op))
+ [paravirt_opptr] "m" (pv_ops.op)
#define paravirt_clobber(clobber) \
[paravirt_clobber] "i" (clobber)
@@ -316,7 +316,7 @@ int paravirt_disable_iospace(void);
*/
#define PARAVIRT_CALL \
ANNOTATE_RETPOLINE_SAFE \
- "call *%c[paravirt_opptr];"
+ "call *%[paravirt_opptr];"
/*
* These macros are intended to wrap calls through one of the paravirt
diff --git a/arch/x86/include/asm/pci.h b/arch/x86/include/asm/pci.h
index d2c76c8d8cfd..f3fd5928bcbb 100644
--- a/arch/x86/include/asm/pci.h
+++ b/arch/x86/include/asm/pci.h
@@ -135,7 +135,7 @@ struct pci_setup_rom {
unsigned long bus;
unsigned long device;
unsigned long function;
- uint8_t romdata[0];
+ uint8_t romdata[];
};
#endif /* _ASM_X86_PCI_H */
diff --git a/arch/x86/include/asm/pci_x86.h b/arch/x86/include/asm/pci_x86.h
index 490411dba438..3fb6fc596095 100644
--- a/arch/x86/include/asm/pci_x86.h
+++ b/arch/x86/include/asm/pci_x86.h
@@ -87,7 +87,7 @@ struct irq_routing_table {
u32 miniport_data; /* Crap */
u8 rfu[11];
u8 checksum; /* Modulo 256 checksum must give 0 */
- struct irq_info slots[0];
+ struct irq_info slots[];
} __attribute__((packed));
extern unsigned int pcibios_irq_mask;
diff --git a/arch/x86/include/asm/perf_event.h b/arch/x86/include/asm/perf_event.h
index 8fc1b5003713..58d9e4b1fa0a 100644
--- a/arch/x86/include/asm/perf_event.h
+++ b/arch/x86/include/asm/perf_event.h
@@ -7,7 +7,7 @@
*/
#define INTEL_PMC_MAX_GENERIC 32
-#define INTEL_PMC_MAX_FIXED 4
+#define INTEL_PMC_MAX_FIXED 16
#define INTEL_PMC_IDX_FIXED 32
#define X86_PMC_IDX_MAX 64
diff --git a/arch/x86/include/asm/pgtable.h b/arch/x86/include/asm/pgtable.h
index 8a9432fb3802..62ab07e24aef 100644
--- a/arch/x86/include/asm/pgtable.h
+++ b/arch/x86/include/asm/pgtable.h
@@ -15,17 +15,12 @@
cachemode2protval(_PAGE_CACHE_MODE_UC_MINUS))) \
: (prot))
-/*
- * Macros to add or remove encryption attribute
- */
-#define pgprot_encrypted(prot) __pgprot(__sme_set(pgprot_val(prot)))
-#define pgprot_decrypted(prot) __pgprot(__sme_clr(pgprot_val(prot)))
-
#ifndef __ASSEMBLY__
#include <linux/spinlock.h>
#include <asm/x86_init.h>
#include <asm/pkru.h>
#include <asm/fpu/api.h>
+#include <asm/coco.h>
#include <asm-generic/pgtable_uffd.h>
#include <linux/page_table_check.h>
@@ -38,6 +33,12 @@ void ptdump_walk_pgd_level_debugfs(struct seq_file *m, struct mm_struct *mm,
void ptdump_walk_pgd_level_checkwx(void);
void ptdump_walk_user_pgd_level_checkwx(void);
+/*
+ * Macros to add or remove encryption attribute
+ */
+#define pgprot_encrypted(prot) __pgprot(cc_mkenc(pgprot_val(prot)))
+#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()
diff --git a/arch/x86/include/asm/preempt.h b/arch/x86/include/asm/preempt.h
index fe5efbcba824..5f6daea1ee24 100644
--- a/arch/x86/include/asm/preempt.h
+++ b/arch/x86/include/asm/preempt.h
@@ -108,16 +108,18 @@ static __always_inline bool should_resched(int preempt_offset)
extern asmlinkage void preempt_schedule(void);
extern asmlinkage void preempt_schedule_thunk(void);
-#define __preempt_schedule_func preempt_schedule_thunk
+#define preempt_schedule_dynamic_enabled preempt_schedule_thunk
+#define preempt_schedule_dynamic_disabled NULL
extern asmlinkage void preempt_schedule_notrace(void);
extern asmlinkage void preempt_schedule_notrace_thunk(void);
-#define __preempt_schedule_notrace_func preempt_schedule_notrace_thunk
+#define preempt_schedule_notrace_dynamic_enabled preempt_schedule_notrace_thunk
+#define preempt_schedule_notrace_dynamic_disabled NULL
#ifdef CONFIG_PREEMPT_DYNAMIC
-DECLARE_STATIC_CALL(preempt_schedule, __preempt_schedule_func);
+DECLARE_STATIC_CALL(preempt_schedule, preempt_schedule_dynamic_enabled);
#define __preempt_schedule() \
do { \
@@ -125,7 +127,7 @@ do { \
asm volatile ("call " STATIC_CALL_TRAMP_STR(preempt_schedule) : ASM_CALL_CONSTRAINT); \
} while (0)
-DECLARE_STATIC_CALL(preempt_schedule_notrace, __preempt_schedule_notrace_func);
+DECLARE_STATIC_CALL(preempt_schedule_notrace, preempt_schedule_notrace_dynamic_enabled);
#define __preempt_schedule_notrace() \
do { \
diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h
index 2c5f12ae7d04..a87e7c33d5ac 100644
--- a/arch/x86/include/asm/processor.h
+++ b/arch/x86/include/asm/processor.h
@@ -119,6 +119,8 @@ struct cpuinfo_x86 {
int x86_cache_mbm_width_offset;
int x86_power;
unsigned long loops_per_jiffy;
+ /* protected processor identification number */
+ u64 ppin;
/* cpuid returned max cores value: */
u16 x86_max_cores;
u16 apicid;
diff --git a/arch/x86/include/asm/ptrace.h b/arch/x86/include/asm/ptrace.h
index 703663175a5a..4357e0f2cd5f 100644
--- a/arch/x86/include/asm/ptrace.h
+++ b/arch/x86/include/asm/ptrace.h
@@ -137,7 +137,7 @@ static __always_inline int user_mode(struct pt_regs *regs)
#endif
}
-static inline int v8086_mode(struct pt_regs *regs)
+static __always_inline int v8086_mode(struct pt_regs *regs)
{
#ifdef CONFIG_X86_32
return (regs->flags & X86_VM_MASK);
diff --git a/arch/x86/include/asm/set_memory.h b/arch/x86/include/asm/set_memory.h
index ff0f2d90338a..78ca53512486 100644
--- a/arch/x86/include/asm/set_memory.h
+++ b/arch/x86/include/asm/set_memory.h
@@ -53,7 +53,6 @@ int set_memory_global(unsigned long addr, int numpages);
int set_pages_array_uc(struct page **pages, int addrinarray);
int set_pages_array_wc(struct page **pages, int addrinarray);
-int set_pages_array_wt(struct page **pages, int addrinarray);
int set_pages_array_wb(struct page **pages, int addrinarray);
/*
@@ -84,7 +83,6 @@ int set_pages_rw(struct page *page, int numpages);
int set_direct_map_invalid_noflush(struct page *page);
int set_direct_map_default_noflush(struct page *page);
bool kernel_page_present(struct page *page);
-void notify_range_enc_status_changed(unsigned long vaddr, int npages, bool enc);
extern int kernel_set_to_readonly;
diff --git a/arch/x86/include/asm/svm.h b/arch/x86/include/asm/svm.h
index b00dbc5fac2b..7eb2df5417fb 100644
--- a/arch/x86/include/asm/svm.h
+++ b/arch/x86/include/asm/svm.h
@@ -220,6 +220,42 @@ struct __attribute__ ((__packed__)) vmcb_control_area {
#define SVM_NESTED_CTL_SEV_ENABLE BIT(1)
#define SVM_NESTED_CTL_SEV_ES_ENABLE BIT(2)
+
+/* AVIC */
+#define AVIC_LOGICAL_ID_ENTRY_GUEST_PHYSICAL_ID_MASK (0xFF)
+#define AVIC_LOGICAL_ID_ENTRY_VALID_BIT 31
+#define AVIC_LOGICAL_ID_ENTRY_VALID_MASK (1 << 31)
+
+#define AVIC_PHYSICAL_ID_ENTRY_HOST_PHYSICAL_ID_MASK GENMASK_ULL(11, 0)
+#define AVIC_PHYSICAL_ID_ENTRY_BACKING_PAGE_MASK (0xFFFFFFFFFFULL << 12)
+#define AVIC_PHYSICAL_ID_ENTRY_IS_RUNNING_MASK (1ULL << 62)
+#define AVIC_PHYSICAL_ID_ENTRY_VALID_MASK (1ULL << 63)
+#define AVIC_PHYSICAL_ID_TABLE_SIZE_MASK (0xFF)
+
+#define AVIC_DOORBELL_PHYSICAL_ID_MASK (0xFF)
+
+#define AVIC_UNACCEL_ACCESS_WRITE_MASK 1
+#define AVIC_UNACCEL_ACCESS_OFFSET_MASK 0xFF0
+#define AVIC_UNACCEL_ACCESS_VECTOR_MASK 0xFFFFFFFF
+
+enum avic_ipi_failure_cause {
+ AVIC_IPI_FAILURE_INVALID_INT_TYPE,
+ AVIC_IPI_FAILURE_TARGET_NOT_RUNNING,
+ AVIC_IPI_FAILURE_INVALID_TARGET,
+ AVIC_IPI_FAILURE_INVALID_BACKING_PAGE,
+};
+
+
+/*
+ * 0xff is broadcast, so the max index allowed for physical APIC ID
+ * table is 0xfe. APIC IDs above 0xff are reserved.
+ */
+#define AVIC_MAX_PHYSICAL_ID_COUNT 0xff
+
+#define AVIC_HPA_MASK ~((0xFFFULL << 52) | 0xFFF)
+#define VMCB_AVIC_APIC_BAR_MASK 0xFFFFFFFFFF000ULL
+
+
struct vmcb_seg {
u16 selector;
u16 attrib;
diff --git a/arch/x86/include/asm/text-patching.h b/arch/x86/include/asm/text-patching.h
index b7421780e4e9..4cc18ba1b75e 100644
--- a/arch/x86/include/asm/text-patching.h
+++ b/arch/x86/include/asm/text-patching.h
@@ -44,6 +44,7 @@ extern void text_poke_early(void *addr, const void *opcode, size_t len);
extern void *text_poke(void *addr, const void *opcode, size_t len);
extern void text_poke_sync(void);
extern void *text_poke_kgdb(void *addr, const void *opcode, size_t len);
+extern void *text_poke_copy(void *addr, const void *opcode, size_t len);
extern int poke_int3_handler(struct pt_regs *regs);
extern void text_poke_bp(void *addr, const void *opcode, size_t len, const void *emulate);
diff --git a/arch/x86/include/asm/topology.h b/arch/x86/include/asm/topology.h
index 2f0b6be8eaab..9619385bf749 100644
--- a/arch/x86/include/asm/topology.h
+++ b/arch/x86/include/asm/topology.h
@@ -110,6 +110,7 @@ extern const struct cpumask *cpu_clustergroup_mask(int cpu);
#define topology_logical_die_id(cpu) (cpu_data(cpu).logical_die_id)
#define topology_die_id(cpu) (cpu_data(cpu).cpu_die_id)
#define topology_core_id(cpu) (cpu_data(cpu).cpu_core_id)
+#define topology_ppin(cpu) (cpu_data(cpu).ppin)
extern unsigned int __max_die_per_package;
@@ -215,15 +216,26 @@ extern void arch_scale_freq_tick(void);
#define arch_scale_freq_tick arch_scale_freq_tick
extern void arch_set_max_freq_ratio(bool turbo_disabled);
+void init_freq_invariance(bool secondary, bool cppc_ready);
#else
static inline void arch_set_max_freq_ratio(bool turbo_disabled)
{
}
+static inline void init_freq_invariance(bool secondary, bool cppc_ready)
+{
+}
#endif
-#if defined(CONFIG_ACPI_CPPC_LIB) && defined(CONFIG_SMP)
+#ifdef CONFIG_ACPI_CPPC_LIB
void init_freq_invariance_cppc(void);
-#define init_freq_invariance_cppc init_freq_invariance_cppc
+#define arch_init_invariance_cppc init_freq_invariance_cppc
+
+bool amd_set_max_freq_ratio(u64 *ratio);
+#else
+static inline bool amd_set_max_freq_ratio(u64 *ratio)
+{
+ return false;
+}
#endif
#endif /* _ASM_X86_TOPOLOGY_H */
diff --git a/arch/x86/include/asm/uaccess.h b/arch/x86/include/asm/uaccess.h
index ac96f9b2d64b..f78e2b3501a1 100644
--- a/arch/x86/include/asm/uaccess.h
+++ b/arch/x86/include/asm/uaccess.h
@@ -12,35 +12,6 @@
#include <asm/smap.h>
#include <asm/extable.h>
-/*
- * Test whether a block of memory is a valid user space address.
- * Returns 0 if the range is valid, nonzero otherwise.
- */
-static inline bool __chk_range_not_ok(unsigned long addr, unsigned long size, unsigned long limit)
-{
- /*
- * If we have used "sizeof()" for the size,
- * we know it won't overflow the limit (but
- * it might overflow the 'addr', so it's
- * important to subtract the size from the
- * limit, not add it to the address).
- */
- if (__builtin_constant_p(size))
- return unlikely(addr > limit - size);
-
- /* Arbitrary sizes? Be careful about overflow */
- addr += size;
- if (unlikely(addr < size))
- return true;
- return unlikely(addr > limit);
-}
-
-#define __range_not_ok(addr, size, limit) \
-({ \
- __chk_user_ptr(addr); \
- __chk_range_not_ok((unsigned long __force)(addr), size, limit); \
-})
-
#ifdef CONFIG_DEBUG_ATOMIC_SLEEP
static inline bool pagefault_disabled(void);
# define WARN_ON_IN_IRQ() \
@@ -69,9 +40,11 @@ static inline bool pagefault_disabled(void);
#define access_ok(addr, size) \
({ \
WARN_ON_IN_IRQ(); \
- likely(!__range_not_ok(addr, size, TASK_SIZE_MAX)); \
+ likely(__access_ok(addr, size)); \
})
+#include <asm-generic/access_ok.h>
+
extern int __get_user_1(void);
extern int __get_user_2(void);
extern int __get_user_4(void);
@@ -524,8 +497,6 @@ do { \
unsafe_copy_loop(__ucu_dst, __ucu_src, __ucu_len, u8, label); \
} while (0)
-#define HAVE_GET_KERNEL_NOFAULT
-
#ifdef CONFIG_CC_HAS_ASM_GOTO_OUTPUT
#define __get_kernel_nofault(dst, src, type, err_label) \
__get_user_size(*((type *)(dst)), (__force type __user *)(src), \
diff --git a/arch/x86/include/asm/x86_init.h b/arch/x86/include/asm/x86_init.h
index 22b7412c08f6..e9170457697e 100644
--- a/arch/x86/include/asm/x86_init.h
+++ b/arch/x86/include/asm/x86_init.h
@@ -142,6 +142,21 @@ struct x86_init_acpi {
};
/**
+ * struct x86_guest - Functions used by misc guest incarnations like SEV, TDX, etc.
+ *
+ * @enc_status_change_prepare Notify HV before the encryption status of a range is changed
+ * @enc_status_change_finish Notify HV after the encryption status of a range is changed
+ * @enc_tlb_flush_required Returns true if a TLB flush is needed before changing page encryption status
+ * @enc_cache_flush_required Returns true if a cache flush is needed before changing page encryption status
+ */
+struct x86_guest {
+ void (*enc_status_change_prepare)(unsigned long vaddr, int npages, bool enc);
+ bool (*enc_status_change_finish)(unsigned long vaddr, int npages, bool enc);
+ bool (*enc_tlb_flush_required)(bool enc);
+ bool (*enc_cache_flush_required)(void);
+};
+
+/**
* struct x86_init_ops - functions for platform specific setup
*
*/
@@ -287,6 +302,7 @@ struct x86_platform_ops {
struct x86_legacy_features legacy;
void (*set_legacy_features)(void);
struct x86_hyper_runtime hyper;
+ struct x86_guest guest;
};
struct x86_apic_ops {
diff --git a/arch/x86/include/asm/xen/cpuid.h b/arch/x86/include/asm/xen/cpuid.h
index a9630104f1c4..78e667a31d6c 100644
--- a/arch/x86/include/asm/xen/cpuid.h
+++ b/arch/x86/include/asm/xen/cpuid.h
@@ -100,6 +100,13 @@
/* Memory mapped from other domains has valid IOMMU entries */
#define XEN_HVM_CPUID_IOMMU_MAPPINGS (1u << 2)
#define XEN_HVM_CPUID_VCPU_ID_PRESENT (1u << 3) /* vcpu id is present in EBX */
+#define XEN_HVM_CPUID_DOMID_PRESENT (1u << 4) /* domid is present in ECX */
+/*
+ * Bits 55:49 from the IO-APIC RTE and bits 11:5 from the MSI address can be
+ * used to store high bits for the Destination ID. This expands the Destination
+ * ID field from 8 to 15 bits, allowing to target APIC IDs up 32768.
+ */
+#define XEN_HVM_CPUID_EXT_DEST_ID (1u << 5)
/*
* Leaf 6 (0x40000x05)
diff --git a/arch/x86/include/asm/xen/hypervisor.h b/arch/x86/include/asm/xen/hypervisor.h
index 1bf2ad34188a..16f548a661cf 100644
--- a/arch/x86/include/asm/xen/hypervisor.h
+++ b/arch/x86/include/asm/xen/hypervisor.h
@@ -43,20 +43,6 @@ static inline uint32_t xen_cpuid_base(void)
return hypervisor_cpuid_base("XenVMMXenVMM", 2);
}
-#ifdef CONFIG_XEN
-extern bool __init xen_hvm_need_lapic(void);
-
-static inline bool __init xen_x2apic_para_available(void)
-{
- return xen_hvm_need_lapic();
-}
-#else
-static inline bool __init xen_x2apic_para_available(void)
-{
- return (xen_cpuid_base() != 0);
-}
-#endif
-
struct pci_dev;
#ifdef CONFIG_XEN_PV_DOM0
diff --git a/arch/x86/include/asm/xor.h b/arch/x86/include/asm/xor.h
index 2ee95a7769e6..7b0307acc410 100644
--- a/arch/x86/include/asm/xor.h
+++ b/arch/x86/include/asm/xor.h
@@ -57,7 +57,8 @@
op(i + 3, 3)
static void
-xor_sse_2(unsigned long bytes, unsigned long *p1, unsigned long *p2)
+xor_sse_2(unsigned long bytes, unsigned long * __restrict p1,
+ const unsigned long * __restrict p2)
{
unsigned long lines = bytes >> 8;
@@ -108,7 +109,8 @@ xor_sse_2(unsigned long bytes, unsigned long *p1, unsigned long *p2)
}
static void
-xor_sse_2_pf64(unsigned long bytes, unsigned long *p1, unsigned long *p2)
+xor_sse_2_pf64(unsigned long bytes, unsigned long * __restrict p1,
+ const unsigned long * __restrict p2)
{
unsigned long lines = bytes >> 8;
@@ -142,8 +144,9 @@ xor_sse_2_pf64(unsigned long bytes, unsigned long *p1, unsigned long *p2)
}
static void
-xor_sse_3(unsigned long bytes, unsigned long *p1, unsigned long *p2,
- unsigned long *p3)
+xor_sse_3(unsigned long bytes, unsigned long * __restrict p1,
+ const unsigned long * __restrict p2,
+ const unsigned long * __restrict p3)
{
unsigned long lines = bytes >> 8;
@@ -201,8 +204,9 @@ xor_sse_3(unsigned long bytes, unsigned long *p1, unsigned long *p2,
}
static void
-xor_sse_3_pf64(unsigned long bytes, unsigned long *p1, unsigned long *p2,
- unsigned long *p3)
+xor_sse_3_pf64(unsigned long bytes, unsigned long * __restrict p1,
+ const unsigned long * __restrict p2,
+ const unsigned long * __restrict p3)
{
unsigned long lines = bytes >> 8;
@@ -238,8 +242,10 @@ xor_sse_3_pf64(unsigned long bytes, unsigned long *p1, unsigned long *p2,
}
static void
-xor_sse_4(unsigned long bytes, unsigned long *p1, unsigned long *p2,
- unsigned long *p3, unsigned long *p4)
+xor_sse_4(unsigned long bytes, unsigned long * __restrict p1,
+ const unsigned long * __restrict p2,
+ const unsigned long * __restrict p3,
+ const unsigned long * __restrict p4)
{
unsigned long lines = bytes >> 8;
@@ -304,8 +310,10 @@ xor_sse_4(unsigned long bytes, unsigned long *p1, unsigned long *p2,
}
static void
-xor_sse_4_pf64(unsigned long bytes, unsigned long *p1, unsigned long *p2,
- unsigned long *p3, unsigned long *p4)
+xor_sse_4_pf64(unsigned long bytes, unsigned long * __restrict p1,
+ const unsigned long * __restrict p2,
+ const unsigned long * __restrict p3,
+ const unsigned long * __restrict p4)
{
unsigned long lines = bytes >> 8;
@@ -343,8 +351,11 @@ xor_sse_4_pf64(unsigned long bytes, unsigned long *p1, unsigned long *p2,
}
static void
-xor_sse_5(unsigned long bytes, unsigned long *p1, unsigned long *p2,
- unsigned long *p3, unsigned long *p4, unsigned long *p5)
+xor_sse_5(unsigned long bytes, unsigned long * __restrict p1,
+ const unsigned long * __restrict p2,
+ const unsigned long * __restrict p3,
+ const unsigned long * __restrict p4,
+ const unsigned long * __restrict p5)
{
unsigned long lines = bytes >> 8;
@@ -416,8 +427,11 @@ xor_sse_5(unsigned long bytes, unsigned long *p1, unsigned long *p2,
}
static void
-xor_sse_5_pf64(unsigned long bytes, unsigned long *p1, unsigned long *p2,
- unsigned long *p3, unsigned long *p4, unsigned long *p5)
+xor_sse_5_pf64(unsigned long bytes, unsigned long * __restrict p1,
+ const unsigned long * __restrict p2,
+ const unsigned long * __restrict p3,
+ const unsigned long * __restrict p4,
+ const unsigned long * __restrict p5)
{
unsigned long lines = bytes >> 8;
diff --git a/arch/x86/include/asm/xor_32.h b/arch/x86/include/asm/xor_32.h
index 67ceb790e639..7a6b9474591e 100644
--- a/arch/x86/include/asm/xor_32.h
+++ b/arch/x86/include/asm/xor_32.h
@@ -21,7 +21,8 @@
#include <asm/fpu/api.h>
static void
-xor_pII_mmx_2(unsigned long bytes, unsigned long *p1, unsigned long *p2)
+xor_pII_mmx_2(unsigned long bytes, unsigned long * __restrict p1,
+ const unsigned long * __restrict p2)
{
unsigned long lines = bytes >> 7;
@@ -64,8 +65,9 @@ xor_pII_mmx_2(unsigned long bytes, unsigned long *p1, unsigned long *p2)
}
static void
-xor_pII_mmx_3(unsigned long bytes, unsigned long *p1, unsigned long *p2,
- unsigned long *p3)
+xor_pII_mmx_3(unsigned long bytes, unsigned long * __restrict p1,
+ const unsigned long * __restrict p2,
+ const unsigned long * __restrict p3)
{
unsigned long lines = bytes >> 7;
@@ -113,8 +115,10 @@ xor_pII_mmx_3(unsigned long bytes, unsigned long *p1, unsigned long *p2,
}
static void
-xor_pII_mmx_4(unsigned long bytes, unsigned long *p1, unsigned long *p2,
- unsigned long *p3, unsigned long *p4)
+xor_pII_mmx_4(unsigned long bytes, unsigned long * __restrict p1,
+ const unsigned long * __restrict p2,
+ const unsigned long * __restrict p3,
+ const unsigned long * __restrict p4)
{
unsigned long lines = bytes >> 7;
@@ -168,8 +172,11 @@ xor_pII_mmx_4(unsigned long bytes, unsigned long *p1, unsigned long *p2,
static void
-xor_pII_mmx_5(unsigned long bytes, unsigned long *p1, unsigned long *p2,
- unsigned long *p3, unsigned long *p4, unsigned long *p5)
+xor_pII_mmx_5(unsigned long bytes, unsigned long * __restrict p1,
+ const unsigned long * __restrict p2,
+ const unsigned long * __restrict p3,
+ const unsigned long * __restrict p4,
+ const unsigned long * __restrict p5)
{
unsigned long lines = bytes >> 7;
@@ -248,7 +255,8 @@ xor_pII_mmx_5(unsigned long bytes, unsigned long *p1, unsigned long *p2,
#undef BLOCK
static void
-xor_p5_mmx_2(unsigned long bytes, unsigned long *p1, unsigned long *p2)
+xor_p5_mmx_2(unsigned long bytes, unsigned long * __restrict p1,
+ const unsigned long * __restrict p2)
{
unsigned long lines = bytes >> 6;
@@ -295,8 +303,9 @@ xor_p5_mmx_2(unsigned long bytes, unsigned long *p1, unsigned long *p2)
}
static void
-xor_p5_mmx_3(unsigned long bytes, unsigned long *p1, unsigned long *p2,
- unsigned long *p3)
+xor_p5_mmx_3(unsigned long bytes, unsigned long * __restrict p1,
+ const unsigned long * __restrict p2,
+ const unsigned long * __restrict p3)
{
unsigned long lines = bytes >> 6;
@@ -352,8 +361,10 @@ xor_p5_mmx_3(unsigned long bytes, unsigned long *p1, unsigned long *p2,
}
static void
-xor_p5_mmx_4(unsigned long bytes, unsigned long *p1, unsigned long *p2,
- unsigned long *p3, unsigned long *p4)
+xor_p5_mmx_4(unsigned long bytes, unsigned long * __restrict p1,
+ const unsigned long * __restrict p2,
+ const unsigned long * __restrict p3,
+ const unsigned long * __restrict p4)
{
unsigned long lines = bytes >> 6;
@@ -418,8 +429,11 @@ xor_p5_mmx_4(unsigned long bytes, unsigned long *p1, unsigned long *p2,
}
static void
-xor_p5_mmx_5(unsigned long bytes, unsigned long *p1, unsigned long *p2,
- unsigned long *p3, unsigned long *p4, unsigned long *p5)
+xor_p5_mmx_5(unsigned long bytes, unsigned long * __restrict p1,
+ const unsigned long * __restrict p2,
+ const unsigned long * __restrict p3,
+ const unsigned long * __restrict p4,
+ const unsigned long * __restrict p5)
{
unsigned long lines = bytes >> 6;
diff --git a/arch/x86/include/asm/xor_avx.h b/arch/x86/include/asm/xor_avx.h
index 0c4e5b5e3852..7f81dd5897f4 100644
--- a/arch/x86/include/asm/xor_avx.h
+++ b/arch/x86/include/asm/xor_avx.h
@@ -26,7 +26,8 @@
BLOCK4(8) \
BLOCK4(12)
-static void xor_avx_2(unsigned long bytes, unsigned long *p0, unsigned long *p1)
+static void xor_avx_2(unsigned long bytes, unsigned long * __restrict p0,
+ const unsigned long * __restrict p1)
{
unsigned long lines = bytes >> 9;
@@ -52,8 +53,9 @@ do { \
kernel_fpu_end();
}
-static void xor_avx_3(unsigned long bytes, unsigned long *p0, unsigned long *p1,
- unsigned long *p2)
+static void xor_avx_3(unsigned long bytes, unsigned long * __restrict p0,
+ const unsigned long * __restrict p1,
+ const unsigned long * __restrict p2)
{
unsigned long lines = bytes >> 9;
@@ -82,8 +84,10 @@ do { \
kernel_fpu_end();
}
-static void xor_avx_4(unsigned long bytes, unsigned long *p0, unsigned long *p1,
- unsigned long *p2, unsigned long *p3)
+static void xor_avx_4(unsigned long bytes, unsigned long * __restrict p0,
+ const unsigned long * __restrict p1,
+ const unsigned long * __restrict p2,
+ const unsigned long * __restrict p3)
{
unsigned long lines = bytes >> 9;
@@ -115,8 +119,11 @@ do { \
kernel_fpu_end();
}
-static void xor_avx_5(unsigned long bytes, unsigned long *p0, unsigned long *p1,
- unsigned long *p2, unsigned long *p3, unsigned long *p4)
+static void xor_avx_5(unsigned long bytes, unsigned long * __restrict p0,
+ const unsigned long * __restrict p1,
+ const unsigned long * __restrict p2,
+ const unsigned long * __restrict p3,
+ const unsigned long * __restrict p4)
{
unsigned long lines = bytes >> 9;
diff --git a/arch/x86/include/uapi/asm/kvm.h b/arch/x86/include/uapi/asm/kvm.h
index 2da3316bb559..bf6e96011dfe 100644
--- a/arch/x86/include/uapi/asm/kvm.h
+++ b/arch/x86/include/uapi/asm/kvm.h
@@ -452,6 +452,9 @@ struct kvm_sync_regs {
#define KVM_STATE_VMX_PREEMPTION_TIMER_DEADLINE 0x00000001
+/* attributes for system fd (group 0) */
+#define KVM_X86_XCOMP_GUEST_SUPP 0
+
struct kvm_vmx_nested_state_data {
__u8 vmcs12[KVM_STATE_NESTED_VMX_VMCS_SIZE];
__u8 shadow_vmcs12[KVM_STATE_NESTED_VMX_VMCS_SIZE];
diff --git a/arch/x86/include/uapi/asm/shmbuf.h b/arch/x86/include/uapi/asm/shmbuf.h
index fce18eaa070c..13775bfdfee2 100644
--- a/arch/x86/include/uapi/asm/shmbuf.h
+++ b/arch/x86/include/uapi/asm/shmbuf.h
@@ -5,6 +5,10 @@
#if !defined(__x86_64__) || !defined(__ILP32__)
#include <asm-generic/shmbuf.h>
#else
+
+#include <asm/ipcbuf.h>
+#include <asm/posix_types.h>
+
/*
* The shmid64_ds structure for x86 architecture with x32 ABI.
*
@@ -15,7 +19,7 @@
struct shmid64_ds {
struct ipc64_perm shm_perm; /* operation perms */
- size_t shm_segsz; /* size of segment (bytes) */
+ __kernel_size_t shm_segsz; /* size of segment (bytes) */
__kernel_long_t shm_atime; /* last attach time */
__kernel_long_t shm_dtime; /* last detach time */
__kernel_long_t shm_ctime; /* last change time */
diff --git a/arch/x86/include/uapi/asm/signal.h b/arch/x86/include/uapi/asm/signal.h
index 164a22a72984..777c3a0f4e23 100644
--- a/arch/x86/include/uapi/asm/signal.h
+++ b/arch/x86/include/uapi/asm/signal.h
@@ -104,7 +104,7 @@ struct sigaction {
typedef struct sigaltstack {
void __user *ss_sp;
int ss_flags;
- size_t ss_size;
+ __kernel_size_t ss_size;
} stack_t;
#endif /* __ASSEMBLY__ */
diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile
index 6aef9ee28a39..6462e3dd98f4 100644
--- a/arch/x86/kernel/Makefile
+++ b/arch/x86/kernel/Makefile
@@ -21,7 +21,6 @@ CFLAGS_REMOVE_ftrace.o = -pg
CFLAGS_REMOVE_early_printk.o = -pg
CFLAGS_REMOVE_head64.o = -pg
CFLAGS_REMOVE_sev.o = -pg
-CFLAGS_REMOVE_cc_platform.o = -pg
endif
KASAN_SANITIZE_head$(BITS).o := n
@@ -30,7 +29,6 @@ KASAN_SANITIZE_dumpstack_$(BITS).o := n
KASAN_SANITIZE_stacktrace.o := n
KASAN_SANITIZE_paravirt.o := n
KASAN_SANITIZE_sev.o := n
-KASAN_SANITIZE_cc_platform.o := n
# With some compiler versions the generated code results in boot hangs, caused
# by several compilation units. To be safe, disable all instrumentation.
@@ -49,7 +47,6 @@ endif
KCOV_INSTRUMENT := n
CFLAGS_head$(BITS).o += -fno-stack-protector
-CFLAGS_cc_platform.o += -fno-stack-protector
CFLAGS_irq.o := -I $(srctree)/$(src)/../include/asm/trace
@@ -151,8 +148,6 @@ obj-$(CONFIG_UNWINDER_GUESS) += unwind_guess.o
obj-$(CONFIG_AMD_MEM_ENCRYPT) += sev.o
-obj-$(CONFIG_ARCH_HAS_CC_PLATFORM) += cc_platform.o
-
###
# 64 bit specific files
ifeq ($(CONFIG_X86_64),y)
diff --git a/arch/x86/kernel/acpi/Makefile b/arch/x86/kernel/acpi/Makefile
index cf340d85946a..fc17b3f136fe 100644
--- a/arch/x86/kernel/acpi/Makefile
+++ b/arch/x86/kernel/acpi/Makefile
@@ -3,7 +3,7 @@
obj-$(CONFIG_ACPI) += boot.o
obj-$(CONFIG_ACPI_SLEEP) += sleep.o wakeup_$(BITS).o
obj-$(CONFIG_ACPI_APEI) += apei.o
-obj-$(CONFIG_ACPI_CPPC_LIB) += cppc_msr.o
+obj-$(CONFIG_ACPI_CPPC_LIB) += cppc.o
ifneq ($(CONFIG_ACPI_PROCESSOR),)
obj-y += cstate.o
diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c
index 5b6d1a95776f..0d01e7f5078c 100644
--- a/arch/x86/kernel/acpi/boot.c
+++ b/arch/x86/kernel/acpi/boot.c
@@ -1328,6 +1328,17 @@ static int __init disable_acpi_pci(const struct dmi_system_id *d)
return 0;
}
+static int __init disable_acpi_xsdt(const struct dmi_system_id *d)
+{
+ if (!acpi_force) {
+ pr_notice("%s detected: force use of acpi=rsdt\n", d->ident);
+ acpi_gbl_do_not_use_xsdt = TRUE;
+ } else {
+ pr_notice("Warning: DMI blacklist says broken, but acpi XSDT forced\n");
+ }
+ return 0;
+}
+
static int __init dmi_disable_acpi(const struct dmi_system_id *d)
{
if (!acpi_force) {
@@ -1451,6 +1462,19 @@ static const struct dmi_system_id acpi_dmi_table[] __initconst = {
DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 360"),
},
},
+ /*
+ * Boxes that need ACPI XSDT use disabled due to corrupted tables
+ */
+ {
+ .callback = disable_acpi_xsdt,
+ .ident = "Advantech DAC-BJ01",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "NEC"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Bearlake CRB Board"),
+ DMI_MATCH(DMI_BIOS_VERSION, "V1.12"),
+ DMI_MATCH(DMI_BIOS_DATE, "02/01/2011"),
+ },
+ },
{}
};
diff --git a/arch/x86/kernel/acpi/cppc.c b/arch/x86/kernel/acpi/cppc.c
new file mode 100644
index 000000000000..df1644d9b3b6
--- /dev/null
+++ b/arch/x86/kernel/acpi/cppc.c
@@ -0,0 +1,103 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * cppc.c: CPPC Interface for x86
+ * Copyright (c) 2016, Intel Corporation.
+ */
+
+#include <acpi/cppc_acpi.h>
+#include <asm/msr.h>
+#include <asm/processor.h>
+#include <asm/topology.h>
+
+/* Refer to drivers/acpi/cppc_acpi.c for the description of functions */
+
+bool cpc_ffh_supported(void)
+{
+ return true;
+}
+
+int cpc_read_ffh(int cpunum, struct cpc_reg *reg, u64 *val)
+{
+ int err;
+
+ err = rdmsrl_safe_on_cpu(cpunum, reg->address, val);
+ if (!err) {
+ u64 mask = GENMASK_ULL(reg->bit_offset + reg->bit_width - 1,
+ reg->bit_offset);
+
+ *val &= mask;
+ *val >>= reg->bit_offset;
+ }
+ return err;
+}
+
+int cpc_write_ffh(int cpunum, struct cpc_reg *reg, u64 val)
+{
+ u64 rd_val;
+ int err;
+
+ err = rdmsrl_safe_on_cpu(cpunum, reg->address, &rd_val);
+ if (!err) {
+ u64 mask = GENMASK_ULL(reg->bit_offset + reg->bit_width - 1,
+ reg->bit_offset);
+
+ val <<= reg->bit_offset;
+ val &= mask;
+ rd_val &= ~mask;
+ rd_val |= val;
+ err = wrmsrl_safe_on_cpu(cpunum, reg->address, rd_val);
+ }
+ return err;
+}
+
+bool amd_set_max_freq_ratio(u64 *ratio)
+{
+ struct cppc_perf_caps perf_caps;
+ u64 highest_perf, nominal_perf;
+ u64 perf_ratio;
+ int rc;
+
+ if (!ratio)
+ return false;
+
+ rc = cppc_get_perf_caps(0, &perf_caps);
+ if (rc) {
+ pr_debug("Could not retrieve perf counters (%d)\n", rc);
+ return false;
+ }
+
+ highest_perf = amd_get_highest_perf();
+ nominal_perf = perf_caps.nominal_perf;
+
+ if (!highest_perf || !nominal_perf) {
+ pr_debug("Could not retrieve highest or nominal performance\n");
+ return false;
+ }
+
+ perf_ratio = div_u64(highest_perf * SCHED_CAPACITY_SCALE, nominal_perf);
+ /* midpoint between max_boost and max_P */
+ perf_ratio = (perf_ratio + SCHED_CAPACITY_SCALE) >> 1;
+ if (!perf_ratio) {
+ pr_debug("Non-zero highest/nominal perf values led to a 0 ratio\n");
+ return false;
+ }
+
+ *ratio = perf_ratio;
+ arch_set_max_freq_ratio(false);
+
+ return true;
+}
+
+static DEFINE_MUTEX(freq_invariance_lock);
+
+void init_freq_invariance_cppc(void)
+{
+ static bool secondary;
+
+ mutex_lock(&freq_invariance_lock);
+
+ init_freq_invariance(secondary, true);
+ secondary = true;
+
+ mutex_unlock(&freq_invariance_lock);
+}
diff --git a/arch/x86/kernel/acpi/cppc_msr.c b/arch/x86/kernel/acpi/cppc_msr.c
deleted file mode 100644
index b961de569e7e..000000000000
--- a/arch/x86/kernel/acpi/cppc_msr.c
+++ /dev/null
@@ -1,49 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * cppc_msr.c: MSR Interface for CPPC
- * Copyright (c) 2016, Intel Corporation.
- */
-
-#include <acpi/cppc_acpi.h>
-#include <asm/msr.h>
-
-/* Refer to drivers/acpi/cppc_acpi.c for the description of functions */
-
-bool cpc_ffh_supported(void)
-{
- return true;
-}
-
-int cpc_read_ffh(int cpunum, struct cpc_reg *reg, u64 *val)
-{
- int err;
-
- err = rdmsrl_safe_on_cpu(cpunum, reg->address, val);
- if (!err) {
- u64 mask = GENMASK_ULL(reg->bit_offset + reg->bit_width - 1,
- reg->bit_offset);
-
- *val &= mask;
- *val >>= reg->bit_offset;
- }
- return err;
-}
-
-int cpc_write_ffh(int cpunum, struct cpc_reg *reg, u64 val)
-{
- u64 rd_val;
- int err;
-
- err = rdmsrl_safe_on_cpu(cpunum, reg->address, &rd_val);
- if (!err) {
- u64 mask = GENMASK_ULL(reg->bit_offset + reg->bit_width - 1,
- reg->bit_offset);
-
- val <<= reg->bit_offset;
- val &= mask;
- rd_val &= ~mask;
- rd_val |= val;
- err = wrmsrl_safe_on_cpu(cpunum, reg->address, rd_val);
- }
- return err;
-}
diff --git a/arch/x86/kernel/acpi/sleep.c b/arch/x86/kernel/acpi/sleep.c
index 1e97f944b47d..3b7f4cdbf2e0 100644
--- a/arch/x86/kernel/acpi/sleep.c
+++ b/arch/x86/kernel/acpi/sleep.c
@@ -15,6 +15,7 @@
#include <asm/desc.h>
#include <asm/cacheflush.h>
#include <asm/realmode.h>
+#include <asm/hypervisor.h>
#include <linux/ftrace.h>
#include "../../realmode/rm/wakeup.h"
@@ -140,9 +141,9 @@ static int __init acpi_sleep_setup(char *str)
acpi_realmode_flags |= 4;
#ifdef CONFIG_HIBERNATION
if (strncmp(str, "s4_hwsig", 8) == 0)
- acpi_check_s4_hw_signature(1);
+ acpi_check_s4_hw_signature = 1;
if (strncmp(str, "s4_nohwsig", 10) == 0)
- acpi_check_s4_hw_signature(0);
+ acpi_check_s4_hw_signature = 0;
#endif
if (strncmp(str, "nonvs", 5) == 0)
acpi_nvs_nosave();
@@ -160,3 +161,21 @@ static int __init acpi_sleep_setup(char *str)
}
__setup("acpi_sleep=", acpi_sleep_setup);
+
+#if defined(CONFIG_HIBERNATION) && defined(CONFIG_HYPERVISOR_GUEST)
+static int __init init_s4_sigcheck(void)
+{
+ /*
+ * If running on a hypervisor, honour the ACPI specification
+ * by default and trigger a clean reboot when the hardware
+ * signature in FACS is changed after hibernation.
+ */
+ if (acpi_check_s4_hw_signature == -1 &&
+ !hypervisor_is_type(X86_HYPER_NATIVE))
+ acpi_check_s4_hw_signature = 1;
+
+ return 0;
+}
+/* This must happen before acpi_init() which is a subsys initcall */
+arch_initcall(init_s4_sigcheck);
+#endif
diff --git a/arch/x86/kernel/alternative.c b/arch/x86/kernel/alternative.c
index 5007c3ffe96f..b4e576600969 100644
--- a/arch/x86/kernel/alternative.c
+++ b/arch/x86/kernel/alternative.c
@@ -389,7 +389,7 @@ static int emit_indirect(int op, int reg, u8 *bytes)
*
* CALL *%\reg
*
- * It also tries to inline spectre_v2=retpoline,amd when size permits.
+ * It also tries to inline spectre_v2=retpoline,lfence when size permits.
*/
static int patch_retpoline(void *addr, struct insn *insn, u8 *bytes)
{
@@ -407,7 +407,7 @@ static int patch_retpoline(void *addr, struct insn *insn, u8 *bytes)
BUG_ON(reg == 4);
if (cpu_feature_enabled(X86_FEATURE_RETPOLINE) &&
- !cpu_feature_enabled(X86_FEATURE_RETPOLINE_AMD))
+ !cpu_feature_enabled(X86_FEATURE_RETPOLINE_LFENCE))
return -1;
op = insn->opcode.bytes[0];
@@ -438,9 +438,9 @@ static int patch_retpoline(void *addr, struct insn *insn, u8 *bytes)
}
/*
- * For RETPOLINE_AMD: prepend the indirect CALL/JMP with an LFENCE.
+ * For RETPOLINE_LFENCE: prepend the indirect CALL/JMP with an LFENCE.
*/
- if (cpu_feature_enabled(X86_FEATURE_RETPOLINE_AMD)) {
+ if (cpu_feature_enabled(X86_FEATURE_RETPOLINE_LFENCE)) {
bytes[i++] = 0x0f;
bytes[i++] = 0xae;
bytes[i++] = 0xe8; /* LFENCE */
@@ -1102,6 +1102,40 @@ void *text_poke_kgdb(void *addr, const void *opcode, size_t len)
return __text_poke(addr, opcode, len);
}
+/**
+ * text_poke_copy - Copy instructions into (an unused part of) RX memory
+ * @addr: address to modify
+ * @opcode: source of the copy
+ * @len: length to copy, could be more than 2x PAGE_SIZE
+ *
+ * Not safe against concurrent execution; useful for JITs to dump
+ * new code blocks into unused regions of RX memory. Can be used in
+ * conjunction with synchronize_rcu_tasks() to wait for existing
+ * execution to quiesce after having made sure no existing functions
+ * pointers are live.
+ */
+void *text_poke_copy(void *addr, const void *opcode, size_t len)
+{
+ unsigned long start = (unsigned long)addr;
+ size_t patched = 0;
+
+ if (WARN_ON_ONCE(core_kernel_text(start)))
+ return NULL;
+
+ mutex_lock(&text_mutex);
+ while (patched < len) {
+ unsigned long ptr = start + patched;
+ size_t s;
+
+ s = min_t(size_t, PAGE_SIZE * 2 - offset_in_page(ptr), len - patched);
+
+ __text_poke((void *)ptr, opcode + patched, s);
+ patched += s;
+ }
+ mutex_unlock(&text_mutex);
+ return addr;
+}
+
static void do_sync_core(void *info)
{
sync_core();
diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c
index 4edb6f0f628c..0c0b09796ced 100644
--- a/arch/x86/kernel/cpu/amd.c
+++ b/arch/x86/kernel/cpu/amd.c
@@ -394,35 +394,6 @@ static void amd_detect_cmp(struct cpuinfo_x86 *c)
per_cpu(cpu_llc_id, cpu) = c->cpu_die_id = c->phys_proc_id;
}
-static void amd_detect_ppin(struct cpuinfo_x86 *c)
-{
- unsigned long long val;
-
- if (!cpu_has(c, X86_FEATURE_AMD_PPIN))
- return;
-
- /* When PPIN is defined in CPUID, still need to check PPIN_CTL MSR */
- if (rdmsrl_safe(MSR_AMD_PPIN_CTL, &val))
- goto clear_ppin;
-
- /* PPIN is locked in disabled mode, clear feature bit */
- if ((val & 3UL) == 1UL)
- goto clear_ppin;
-
- /* If PPIN is disabled, try to enable it */
- if (!(val & 2UL)) {
- wrmsrl_safe(MSR_AMD_PPIN_CTL, val | 2UL);
- rdmsrl_safe(MSR_AMD_PPIN_CTL, &val);
- }
-
- /* If PPIN_EN bit is 1, return from here; otherwise fall through */
- if (val & 2UL)
- return;
-
-clear_ppin:
- clear_cpu_cap(c, X86_FEATURE_AMD_PPIN);
-}
-
u32 amd_get_nodes_per_socket(void)
{
return nodes_per_socket;
@@ -585,6 +556,8 @@ static void early_detect_mem_encrypt(struct cpuinfo_x86 *c)
* the SME physical address space reduction value.
* If BIOS has not enabled SME then don't advertise the
* 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).
*
@@ -607,6 +580,9 @@ static void early_detect_mem_encrypt(struct cpuinfo_x86 *c)
if (IS_ENABLED(CONFIG_X86_32))
goto clear_all;
+ if (!sme_me_mask)
+ setup_clear_cpu_cap(X86_FEATURE_SME);
+
rdmsrl(MSR_K7_HWCR, msr);
if (!(msr & MSR_K7_HWCR_SMMLOCK))
goto clear_sev;
@@ -947,7 +923,6 @@ static void init_amd(struct cpuinfo_x86 *c)
amd_detect_cmp(c);
amd_get_topology(c);
srat_detect_node(c);
- amd_detect_ppin(c);
init_amd_cacheinfo(c);
diff --git a/arch/x86/kernel/cpu/aperfmperf.c b/arch/x86/kernel/cpu/aperfmperf.c
index 22911deacb6e..9ca008f9e9b1 100644
--- a/arch/x86/kernel/cpu/aperfmperf.c
+++ b/arch/x86/kernel/cpu/aperfmperf.c
@@ -91,7 +91,7 @@ unsigned int aperfmperf_get_khz(int cpu)
if (!boot_cpu_has(X86_FEATURE_APERFMPERF))
return 0;
- if (!housekeeping_cpu(cpu, HK_FLAG_MISC))
+ if (!housekeeping_cpu(cpu, HK_TYPE_MISC))
return 0;
if (rcu_is_idle_cpu(cpu))
@@ -114,7 +114,7 @@ void arch_freq_prepare_all(void)
return;
for_each_online_cpu(cpu) {
- if (!housekeeping_cpu(cpu, HK_FLAG_MISC))
+ if (!housekeeping_cpu(cpu, HK_TYPE_MISC))
continue;
if (rcu_is_idle_cpu(cpu))
continue; /* Idle CPUs are completely uninteresting. */
@@ -136,7 +136,7 @@ unsigned int arch_freq_get_on_cpu(int cpu)
if (!boot_cpu_has(X86_FEATURE_APERFMPERF))
return 0;
- if (!housekeeping_cpu(cpu, HK_FLAG_MISC))
+ if (!housekeeping_cpu(cpu, HK_TYPE_MISC))
return 0;
if (aperfmperf_snapshot_cpu(cpu, ktime_get(), true))
diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c
index 1c1f218a701d..6296e1ebed1d 100644
--- a/arch/x86/kernel/cpu/bugs.c
+++ b/arch/x86/kernel/cpu/bugs.c
@@ -16,6 +16,7 @@
#include <linux/prctl.h>
#include <linux/sched/smt.h>
#include <linux/pgtable.h>
+#include <linux/bpf.h>
#include <asm/spec-ctrl.h>
#include <asm/cmdline.h>
@@ -650,6 +651,32 @@ static inline const char *spectre_v2_module_string(void)
static inline const char *spectre_v2_module_string(void) { return ""; }
#endif
+#define SPECTRE_V2_LFENCE_MSG "WARNING: LFENCE mitigation is not recommended for this CPU, data leaks possible!\n"
+#define SPECTRE_V2_EIBRS_EBPF_MSG "WARNING: Unprivileged eBPF is enabled with eIBRS on, data leaks possible via Spectre v2 BHB attacks!\n"
+#define SPECTRE_V2_EIBRS_LFENCE_EBPF_SMT_MSG "WARNING: Unprivileged eBPF is enabled with eIBRS+LFENCE mitigation and SMT, data leaks possible via Spectre v2 BHB attacks!\n"
+
+#ifdef CONFIG_BPF_SYSCALL
+void unpriv_ebpf_notify(int new_state)
+{
+ if (new_state)
+ return;
+
+ /* Unprivileged eBPF is enabled */
+
+ switch (spectre_v2_enabled) {
+ case SPECTRE_V2_EIBRS:
+ pr_err(SPECTRE_V2_EIBRS_EBPF_MSG);
+ break;
+ case SPECTRE_V2_EIBRS_LFENCE:
+ if (sched_smt_active())
+ pr_err(SPECTRE_V2_EIBRS_LFENCE_EBPF_SMT_MSG);
+ break;
+ default:
+ break;
+ }
+}
+#endif
+
static inline bool match_option(const char *arg, int arglen, const char *opt)
{
int len = strlen(opt);
@@ -664,7 +691,10 @@ enum spectre_v2_mitigation_cmd {
SPECTRE_V2_CMD_FORCE,
SPECTRE_V2_CMD_RETPOLINE,
SPECTRE_V2_CMD_RETPOLINE_GENERIC,
- SPECTRE_V2_CMD_RETPOLINE_AMD,
+ SPECTRE_V2_CMD_RETPOLINE_LFENCE,
+ SPECTRE_V2_CMD_EIBRS,
+ SPECTRE_V2_CMD_EIBRS_RETPOLINE,
+ SPECTRE_V2_CMD_EIBRS_LFENCE,
};
enum spectre_v2_user_cmd {
@@ -737,6 +767,13 @@ spectre_v2_parse_user_cmdline(enum spectre_v2_mitigation_cmd v2_cmd)
return SPECTRE_V2_USER_CMD_AUTO;
}
+static inline bool spectre_v2_in_eibrs_mode(enum spectre_v2_mitigation mode)
+{
+ return (mode == SPECTRE_V2_EIBRS ||
+ mode == SPECTRE_V2_EIBRS_RETPOLINE ||
+ mode == SPECTRE_V2_EIBRS_LFENCE);
+}
+
static void __init
spectre_v2_user_select_mitigation(enum spectre_v2_mitigation_cmd v2_cmd)
{
@@ -804,7 +841,7 @@ spectre_v2_user_select_mitigation(enum spectre_v2_mitigation_cmd v2_cmd)
*/
if (!boot_cpu_has(X86_FEATURE_STIBP) ||
!smt_possible ||
- spectre_v2_enabled == SPECTRE_V2_IBRS_ENHANCED)
+ spectre_v2_in_eibrs_mode(spectre_v2_enabled))
return;
/*
@@ -824,9 +861,11 @@ set_mode:
static const char * const spectre_v2_strings[] = {
[SPECTRE_V2_NONE] = "Vulnerable",
- [SPECTRE_V2_RETPOLINE_GENERIC] = "Mitigation: Full generic retpoline",
- [SPECTRE_V2_RETPOLINE_AMD] = "Mitigation: Full AMD retpoline",
- [SPECTRE_V2_IBRS_ENHANCED] = "Mitigation: Enhanced IBRS",
+ [SPECTRE_V2_RETPOLINE] = "Mitigation: Retpolines",
+ [SPECTRE_V2_LFENCE] = "Mitigation: LFENCE",
+ [SPECTRE_V2_EIBRS] = "Mitigation: Enhanced IBRS",
+ [SPECTRE_V2_EIBRS_LFENCE] = "Mitigation: Enhanced IBRS + LFENCE",
+ [SPECTRE_V2_EIBRS_RETPOLINE] = "Mitigation: Enhanced IBRS + Retpolines",
};
static const struct {
@@ -837,8 +876,12 @@ static const struct {
{ "off", SPECTRE_V2_CMD_NONE, false },
{ "on", SPECTRE_V2_CMD_FORCE, true },
{ "retpoline", SPECTRE_V2_CMD_RETPOLINE, false },
- { "retpoline,amd", SPECTRE_V2_CMD_RETPOLINE_AMD, false },
+ { "retpoline,amd", SPECTRE_V2_CMD_RETPOLINE_LFENCE, false },
+ { "retpoline,lfence", SPECTRE_V2_CMD_RETPOLINE_LFENCE, false },
{ "retpoline,generic", SPECTRE_V2_CMD_RETPOLINE_GENERIC, false },
+ { "eibrs", SPECTRE_V2_CMD_EIBRS, false },
+ { "eibrs,lfence", SPECTRE_V2_CMD_EIBRS_LFENCE, false },
+ { "eibrs,retpoline", SPECTRE_V2_CMD_EIBRS_RETPOLINE, false },
{ "auto", SPECTRE_V2_CMD_AUTO, false },
};
@@ -875,10 +918,30 @@ static enum spectre_v2_mitigation_cmd __init spectre_v2_parse_cmdline(void)
}
if ((cmd == SPECTRE_V2_CMD_RETPOLINE ||
- cmd == SPECTRE_V2_CMD_RETPOLINE_AMD ||
- cmd == SPECTRE_V2_CMD_RETPOLINE_GENERIC) &&
+ cmd == SPECTRE_V2_CMD_RETPOLINE_LFENCE ||
+ cmd == SPECTRE_V2_CMD_RETPOLINE_GENERIC ||
+ cmd == SPECTRE_V2_CMD_EIBRS_LFENCE ||
+ cmd == SPECTRE_V2_CMD_EIBRS_RETPOLINE) &&
!IS_ENABLED(CONFIG_RETPOLINE)) {
- pr_err("%s selected but not compiled in. Switching to AUTO select\n", mitigation_options[i].option);
+ pr_err("%s selected but not compiled in. Switching to AUTO select\n",
+ mitigation_options[i].option);
+ return SPECTRE_V2_CMD_AUTO;
+ }
+
+ if ((cmd == SPECTRE_V2_CMD_EIBRS ||
+ cmd == SPECTRE_V2_CMD_EIBRS_LFENCE ||
+ cmd == SPECTRE_V2_CMD_EIBRS_RETPOLINE) &&
+ !boot_cpu_has(X86_FEATURE_IBRS_ENHANCED)) {
+ pr_err("%s selected but CPU doesn't have eIBRS. Switching to AUTO select\n",
+ mitigation_options[i].option);
+ return SPECTRE_V2_CMD_AUTO;
+ }
+
+ if ((cmd == SPECTRE_V2_CMD_RETPOLINE_LFENCE ||
+ cmd == SPECTRE_V2_CMD_EIBRS_LFENCE) &&
+ !boot_cpu_has(X86_FEATURE_LFENCE_RDTSC)) {
+ pr_err("%s selected, but CPU doesn't have a serializing LFENCE. Switching to AUTO select\n",
+ mitigation_options[i].option);
return SPECTRE_V2_CMD_AUTO;
}
@@ -887,6 +950,16 @@ static enum spectre_v2_mitigation_cmd __init spectre_v2_parse_cmdline(void)
return cmd;
}
+static enum spectre_v2_mitigation __init spectre_v2_select_retpoline(void)
+{
+ if (!IS_ENABLED(CONFIG_RETPOLINE)) {
+ pr_err("Kernel not compiled with retpoline; no mitigation available!");
+ return SPECTRE_V2_NONE;
+ }
+
+ return SPECTRE_V2_RETPOLINE;
+}
+
static void __init spectre_v2_select_mitigation(void)
{
enum spectre_v2_mitigation_cmd cmd = spectre_v2_parse_cmdline();
@@ -907,49 +980,64 @@ static void __init spectre_v2_select_mitigation(void)
case SPECTRE_V2_CMD_FORCE:
case SPECTRE_V2_CMD_AUTO:
if (boot_cpu_has(X86_FEATURE_IBRS_ENHANCED)) {
- mode = SPECTRE_V2_IBRS_ENHANCED;
- /* Force it so VMEXIT will restore correctly */
- x86_spec_ctrl_base |= SPEC_CTRL_IBRS;
- wrmsrl(MSR_IA32_SPEC_CTRL, x86_spec_ctrl_base);
- goto specv2_set_mode;
+ mode = SPECTRE_V2_EIBRS;
+ break;
}
- if (IS_ENABLED(CONFIG_RETPOLINE))
- goto retpoline_auto;
+
+ mode = spectre_v2_select_retpoline();
break;
- case SPECTRE_V2_CMD_RETPOLINE_AMD:
- if (IS_ENABLED(CONFIG_RETPOLINE))
- goto retpoline_amd;
+
+ case SPECTRE_V2_CMD_RETPOLINE_LFENCE:
+ pr_err(SPECTRE_V2_LFENCE_MSG);
+ mode = SPECTRE_V2_LFENCE;
break;
+
case SPECTRE_V2_CMD_RETPOLINE_GENERIC:
- if (IS_ENABLED(CONFIG_RETPOLINE))
- goto retpoline_generic;
+ mode = SPECTRE_V2_RETPOLINE;
break;
+
case SPECTRE_V2_CMD_RETPOLINE:
- if (IS_ENABLED(CONFIG_RETPOLINE))
- goto retpoline_auto;
+ mode = spectre_v2_select_retpoline();
+ break;
+
+ case SPECTRE_V2_CMD_EIBRS:
+ mode = SPECTRE_V2_EIBRS;
+ break;
+
+ case SPECTRE_V2_CMD_EIBRS_LFENCE:
+ mode = SPECTRE_V2_EIBRS_LFENCE;
+ break;
+
+ case SPECTRE_V2_CMD_EIBRS_RETPOLINE:
+ mode = SPECTRE_V2_EIBRS_RETPOLINE;
break;
}
- pr_err("Spectre mitigation: kernel not compiled with retpoline; no mitigation available!");
- return;
-retpoline_auto:
- if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD ||
- boot_cpu_data.x86_vendor == X86_VENDOR_HYGON) {
- retpoline_amd:
- if (!boot_cpu_has(X86_FEATURE_LFENCE_RDTSC)) {
- pr_err("Spectre mitigation: LFENCE not serializing, switching to generic retpoline\n");
- goto retpoline_generic;
- }
- mode = SPECTRE_V2_RETPOLINE_AMD;
- setup_force_cpu_cap(X86_FEATURE_RETPOLINE_AMD);
- setup_force_cpu_cap(X86_FEATURE_RETPOLINE);
- } else {
- retpoline_generic:
- mode = SPECTRE_V2_RETPOLINE_GENERIC;
+ if (mode == SPECTRE_V2_EIBRS && unprivileged_ebpf_enabled())
+ pr_err(SPECTRE_V2_EIBRS_EBPF_MSG);
+
+ if (spectre_v2_in_eibrs_mode(mode)) {
+ /* Force it so VMEXIT will restore correctly */
+ x86_spec_ctrl_base |= SPEC_CTRL_IBRS;
+ wrmsrl(MSR_IA32_SPEC_CTRL, x86_spec_ctrl_base);
+ }
+
+ switch (mode) {
+ case SPECTRE_V2_NONE:
+ case SPECTRE_V2_EIBRS:
+ break;
+
+ case SPECTRE_V2_LFENCE:
+ case SPECTRE_V2_EIBRS_LFENCE:
+ setup_force_cpu_cap(X86_FEATURE_RETPOLINE_LFENCE);
+ fallthrough;
+
+ case SPECTRE_V2_RETPOLINE:
+ case SPECTRE_V2_EIBRS_RETPOLINE:
setup_force_cpu_cap(X86_FEATURE_RETPOLINE);
+ break;
}
-specv2_set_mode:
spectre_v2_enabled = mode;
pr_info("%s\n", spectre_v2_strings[mode]);
@@ -975,7 +1063,7 @@ specv2_set_mode:
* the CPU supports Enhanced IBRS, kernel might un-intentionally not
* enable IBRS around firmware calls.
*/
- if (boot_cpu_has(X86_FEATURE_IBRS) && mode != SPECTRE_V2_IBRS_ENHANCED) {
+ if (boot_cpu_has(X86_FEATURE_IBRS) && !spectre_v2_in_eibrs_mode(mode)) {
setup_force_cpu_cap(X86_FEATURE_USE_IBRS_FW);
pr_info("Enabling Restricted Speculation for firmware calls\n");
}
@@ -1045,6 +1133,10 @@ void cpu_bugs_smt_update(void)
{
mutex_lock(&spec_ctrl_mutex);
+ if (sched_smt_active() && unprivileged_ebpf_enabled() &&
+ spectre_v2_enabled == SPECTRE_V2_EIBRS_LFENCE)
+ pr_warn_once(SPECTRE_V2_EIBRS_LFENCE_EBPF_SMT_MSG);
+
switch (spectre_v2_user_stibp) {
case SPECTRE_V2_USER_NONE:
break;
@@ -1684,7 +1776,7 @@ static ssize_t tsx_async_abort_show_state(char *buf)
static char *stibp_state(void)
{
- if (spectre_v2_enabled == SPECTRE_V2_IBRS_ENHANCED)
+ if (spectre_v2_in_eibrs_mode(spectre_v2_enabled))
return "";
switch (spectre_v2_user_stibp) {
@@ -1714,6 +1806,27 @@ static char *ibpb_state(void)
return "";
}
+static ssize_t spectre_v2_show_state(char *buf)
+{
+ if (spectre_v2_enabled == SPECTRE_V2_LFENCE)
+ return sprintf(buf, "Vulnerable: LFENCE\n");
+
+ if (spectre_v2_enabled == SPECTRE_V2_EIBRS && unprivileged_ebpf_enabled())
+ return sprintf(buf, "Vulnerable: eIBRS with unprivileged eBPF\n");
+
+ if (sched_smt_active() && unprivileged_ebpf_enabled() &&
+ spectre_v2_enabled == SPECTRE_V2_EIBRS_LFENCE)
+ return sprintf(buf, "Vulnerable: eIBRS+LFENCE with unprivileged eBPF and SMT\n");
+
+ return sprintf(buf, "%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" : "",
+ stibp_state(),
+ boot_cpu_has(X86_FEATURE_RSB_CTXSW) ? ", RSB filling" : "",
+ spectre_v2_module_string());
+}
+
static ssize_t srbds_show_state(char *buf)
{
return sprintf(buf, "%s\n", srbds_strings[srbds_mitigation]);
@@ -1739,12 +1852,7 @@ static ssize_t cpu_show_common(struct device *dev, struct device_attribute *attr
return sprintf(buf, "%s\n", spectre_v1_strings[spectre_v1_mitigation]);
case X86_BUG_SPECTRE_V2:
- return sprintf(buf, "%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" : "",
- stibp_state(),
- boot_cpu_has(X86_FEATURE_RSB_CTXSW) ? ", RSB filling" : "",
- spectre_v2_module_string());
+ return spectre_v2_show_state(buf);
case X86_BUG_SPEC_STORE_BYPASS:
return sprintf(buf, "%s\n", ssb_strings[ssb_mode]);
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
index 7b8382c11788..64deb7727d00 100644
--- a/arch/x86/kernel/cpu/common.c
+++ b/arch/x86/kernel/cpu/common.c
@@ -88,6 +88,83 @@ EXPORT_SYMBOL_GPL(get_llc_id);
/* L2 cache ID of each logical CPU */
DEFINE_PER_CPU_READ_MOSTLY(u16, cpu_l2c_id) = BAD_APICID;
+static struct ppin_info {
+ int feature;
+ int msr_ppin_ctl;
+ int msr_ppin;
+} ppin_info[] = {
+ [X86_VENDOR_INTEL] = {
+ .feature = X86_FEATURE_INTEL_PPIN,
+ .msr_ppin_ctl = MSR_PPIN_CTL,
+ .msr_ppin = MSR_PPIN
+ },
+ [X86_VENDOR_AMD] = {
+ .feature = X86_FEATURE_AMD_PPIN,
+ .msr_ppin_ctl = MSR_AMD_PPIN_CTL,
+ .msr_ppin = MSR_AMD_PPIN
+ },
+};
+
+static const struct x86_cpu_id ppin_cpuids[] = {
+ X86_MATCH_FEATURE(X86_FEATURE_AMD_PPIN, &ppin_info[X86_VENDOR_AMD]),
+ X86_MATCH_FEATURE(X86_FEATURE_INTEL_PPIN, &ppin_info[X86_VENDOR_INTEL]),
+
+ /* Legacy models without CPUID enumeration */
+ X86_MATCH_INTEL_FAM6_MODEL(IVYBRIDGE_X, &ppin_info[X86_VENDOR_INTEL]),
+ X86_MATCH_INTEL_FAM6_MODEL(HASWELL_X, &ppin_info[X86_VENDOR_INTEL]),
+ X86_MATCH_INTEL_FAM6_MODEL(BROADWELL_D, &ppin_info[X86_VENDOR_INTEL]),
+ X86_MATCH_INTEL_FAM6_MODEL(BROADWELL_X, &ppin_info[X86_VENDOR_INTEL]),
+ X86_MATCH_INTEL_FAM6_MODEL(SKYLAKE_X, &ppin_info[X86_VENDOR_INTEL]),
+ X86_MATCH_INTEL_FAM6_MODEL(ICELAKE_X, &ppin_info[X86_VENDOR_INTEL]),
+ X86_MATCH_INTEL_FAM6_MODEL(ICELAKE_D, &ppin_info[X86_VENDOR_INTEL]),
+ X86_MATCH_INTEL_FAM6_MODEL(SAPPHIRERAPIDS_X, &ppin_info[X86_VENDOR_INTEL]),
+ X86_MATCH_INTEL_FAM6_MODEL(XEON_PHI_KNL, &ppin_info[X86_VENDOR_INTEL]),
+ X86_MATCH_INTEL_FAM6_MODEL(XEON_PHI_KNM, &ppin_info[X86_VENDOR_INTEL]),
+
+ {}
+};
+
+static void ppin_init(struct cpuinfo_x86 *c)
+{
+ const struct x86_cpu_id *id;
+ unsigned long long val;
+ struct ppin_info *info;
+
+ id = x86_match_cpu(ppin_cpuids);
+ if (!id)
+ return;
+
+ /*
+ * Testing the presence of the MSR is not enough. Need to check
+ * that the PPIN_CTL allows reading of the PPIN.
+ */
+ info = (struct ppin_info *)id->driver_data;
+
+ if (rdmsrl_safe(info->msr_ppin_ctl, &val))
+ goto clear_ppin;
+
+ if ((val & 3UL) == 1UL) {
+ /* PPIN locked in disabled mode */
+ goto clear_ppin;
+ }
+
+ /* If PPIN is disabled, try to enable */
+ if (!(val & 2UL)) {
+ wrmsrl_safe(info->msr_ppin_ctl, val | 2UL);
+ rdmsrl_safe(info->msr_ppin_ctl, &val);
+ }
+
+ /* Is the enable bit set? */
+ if (val & 2UL) {
+ c->ppin = __rdmsr(info->msr_ppin);
+ set_cpu_cap(c, info->feature);
+ return;
+ }
+
+clear_ppin:
+ clear_cpu_cap(c, info->feature);
+}
+
/* correctly size the local cpu masks */
void __init setup_cpu_local_masks(void)
{
@@ -1655,6 +1732,8 @@ static void identify_cpu(struct cpuinfo_x86 *c)
c->x86_capability[i] |= boot_cpu_data.x86_capability[i];
}
+ ppin_init(c);
+
/* Init Machine Check Exception if available. */
mcheck_cpu_init(c);
diff --git a/arch/x86/kernel/cpu/mce/amd.c b/arch/x86/kernel/cpu/mce/amd.c
index a1e2f41796dc..1940d305db1c 100644
--- a/arch/x86/kernel/cpu/mce/amd.c
+++ b/arch/x86/kernel/cpu/mce/amd.c
@@ -423,7 +423,7 @@ static void threshold_restart_bank(void *_tr)
u32 hi, lo;
/* sysfs write might race against an offline operation */
- if (this_cpu_read(threshold_banks))
+ if (!this_cpu_read(threshold_banks) && !tr->set_lvt_off)
return;
rdmsr(tr->b->address, lo, hi);
@@ -993,6 +993,7 @@ static struct attribute *default_attrs[] = {
NULL, /* possibly interrupt_enable if supported, see below */
NULL,
};
+ATTRIBUTE_GROUPS(default);
#define to_block(k) container_of(k, struct threshold_block, kobj)
#define to_attr(a) container_of(a, struct threshold_attr, attr)
@@ -1029,7 +1030,7 @@ static void threshold_block_release(struct kobject *kobj);
static struct kobj_type threshold_ktype = {
.sysfs_ops = &threshold_ops,
- .default_attrs = default_attrs,
+ .default_groups = default_groups,
.release = threshold_block_release,
};
@@ -1101,10 +1102,10 @@ static int allocate_threshold_blocks(unsigned int cpu, struct threshold_bank *tb
b->threshold_limit = THRESHOLD_MAX;
if (b->interrupt_capable) {
- threshold_ktype.default_attrs[2] = &interrupt_enable.attr;
+ default_attrs[2] = &interrupt_enable.attr;
b->interrupt_enable = 1;
} else {
- threshold_ktype.default_attrs[2] = NULL;
+ default_attrs[2] = NULL;
}
INIT_LIST_HEAD(&b->miscj);
diff --git a/arch/x86/kernel/cpu/mce/core.c b/arch/x86/kernel/cpu/mce/core.c
index 5818b837fd4d..e53d3e6096fb 100644
--- a/arch/x86/kernel/cpu/mce/core.c
+++ b/arch/x86/kernel/cpu/mce/core.c
@@ -138,12 +138,7 @@ void mce_setup(struct mce *m)
m->socketid = cpu_data(m->extcpu).phys_proc_id;
m->apicid = cpu_data(m->extcpu).initial_apicid;
m->mcgcap = __rdmsr(MSR_IA32_MCG_CAP);
-
- if (this_cpu_has(X86_FEATURE_INTEL_PPIN))
- m->ppin = __rdmsr(MSR_PPIN);
- else if (this_cpu_has(X86_FEATURE_AMD_PPIN))
- m->ppin = __rdmsr(MSR_AMD_PPIN);
-
+ m->ppin = cpu_data(m->extcpu).ppin;
m->microcode = boot_cpu_data.microcode;
}
@@ -1304,10 +1299,12 @@ static void kill_me_maybe(struct callback_head *cb)
/*
* -EHWPOISON from memory_failure() means that it already sent SIGBUS
- * to the current process with the proper error info, so no need to
- * send SIGBUS here again.
+ * to the current process with the proper error info,
+ * -EOPNOTSUPP means hwpoison_filter() filtered the error event,
+ *
+ * In both cases, no further processing is required.
*/
- if (ret == -EHWPOISON)
+ if (ret == -EHWPOISON || ret == -EOPNOTSUPP)
return;
pr_err("Memory error not recovered");
diff --git a/arch/x86/kernel/cpu/mce/intel.c b/arch/x86/kernel/cpu/mce/intel.c
index bb9a46a804bf..95275a5e57e0 100644
--- a/arch/x86/kernel/cpu/mce/intel.c
+++ b/arch/x86/kernel/cpu/mce/intel.c
@@ -470,46 +470,6 @@ void intel_clear_lmce(void)
wrmsrl(MSR_IA32_MCG_EXT_CTL, val);
}
-static void intel_ppin_init(struct cpuinfo_x86 *c)
-{
- unsigned long long val;
-
- /*
- * Even if testing the presence of the MSR would be enough, we don't
- * want to risk the situation where other models reuse this MSR for
- * other purposes.
- */
- switch (c->x86_model) {
- case INTEL_FAM6_IVYBRIDGE_X:
- case INTEL_FAM6_HASWELL_X:
- case INTEL_FAM6_BROADWELL_D:
- case INTEL_FAM6_BROADWELL_X:
- case INTEL_FAM6_SKYLAKE_X:
- case INTEL_FAM6_ICELAKE_X:
- case INTEL_FAM6_SAPPHIRERAPIDS_X:
- case INTEL_FAM6_XEON_PHI_KNL:
- case INTEL_FAM6_XEON_PHI_KNM:
-
- if (rdmsrl_safe(MSR_PPIN_CTL, &val))
- return;
-
- if ((val & 3UL) == 1UL) {
- /* PPIN locked in disabled mode */
- return;
- }
-
- /* If PPIN is disabled, try to enable */
- if (!(val & 2UL)) {
- wrmsrl_safe(MSR_PPIN_CTL, val | 2UL);
- rdmsrl_safe(MSR_PPIN_CTL, &val);
- }
-
- /* Is the enable bit set? */
- if (val & 2UL)
- set_cpu_cap(c, X86_FEATURE_INTEL_PPIN);
- }
-}
-
/*
* Enable additional error logs from the integrated
* memory controller on processors that support this.
@@ -534,7 +494,6 @@ void mce_intel_feature_init(struct cpuinfo_x86 *c)
{
intel_init_cmci();
intel_init_lmce();
- intel_ppin_init(c);
intel_imc_init(c);
}
diff --git a/arch/x86/kernel/cpu/mshyperv.c b/arch/x86/kernel/cpu/mshyperv.c
index 5a99f993e639..4b67094215bb 100644
--- a/arch/x86/kernel/cpu/mshyperv.c
+++ b/arch/x86/kernel/cpu/mshyperv.c
@@ -33,6 +33,7 @@
#include <asm/nmi.h>
#include <clocksource/hyperv_timer.h>
#include <asm/numa.h>
+#include <asm/coco.h>
/* Is Linux running as the root partition? */
bool hv_root_partition;
@@ -309,10 +310,10 @@ static void __init ms_hyperv_init_platform(void)
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_eax, hv_host_info_ebx >> 16,
- hv_host_info_ebx & 0xFFFF, hv_host_info_ecx,
- hv_host_info_edx >> 24, hv_host_info_edx & 0xFFFFFF);
+ 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 &&
@@ -344,6 +345,11 @@ static void __init ms_hyperv_init_platform(void)
*/
swiotlb_force = SWIOTLB_FORCE;
#endif
+ /* Isolation VMs are unenlightened SEV-based VMs, thus this check: */
+ if (IS_ENABLED(CONFIG_AMD_MEM_ENCRYPT)) {
+ if (hv_get_isolation_type() != HV_ISOLATION_TYPE_NONE)
+ cc_set_vendor(CC_VENDOR_HYPERV);
+ }
}
if (hv_max_functions_eax >= HYPERV_CPUID_NESTED_FEATURES) {
diff --git a/arch/x86/kernel/cpu/scattered.c b/arch/x86/kernel/cpu/scattered.c
index 21d1f062895a..4143b1e4c5c6 100644
--- a/arch/x86/kernel/cpu/scattered.c
+++ b/arch/x86/kernel/cpu/scattered.c
@@ -26,6 +26,7 @@ struct cpuid_bit {
static const struct cpuid_bit cpuid_bits[] = {
{ X86_FEATURE_APERFMPERF, CPUID_ECX, 0, 0x00000006, 0 },
{ X86_FEATURE_EPB, CPUID_ECX, 3, 0x00000006, 0 },
+ { X86_FEATURE_INTEL_PPIN, CPUID_EBX, 0, 0x00000007, 1 },
{ 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 },
diff --git a/arch/x86/kernel/cpu/sgx/encl.c b/arch/x86/kernel/cpu/sgx/encl.c
index 001808e3901c..7c63a1911fae 100644
--- a/arch/x86/kernel/cpu/sgx/encl.c
+++ b/arch/x86/kernel/cpu/sgx/encl.c
@@ -13,6 +13,30 @@
#include "sgx.h"
/*
+ * Calculate byte offset of a PCMD struct associated with an enclave page. PCMD's
+ * follow right after the EPC data in the backing storage. In addition to the
+ * visible enclave pages, there's one extra page slot for SECS, before PCMD
+ * structs.
+ */
+static inline pgoff_t sgx_encl_get_backing_page_pcmd_offset(struct sgx_encl *encl,
+ unsigned long page_index)
+{
+ pgoff_t epc_end_off = encl->size + sizeof(struct sgx_secs);
+
+ return epc_end_off + page_index * sizeof(struct sgx_pcmd);
+}
+
+/*
+ * Free a page from the backing storage in the given page index.
+ */
+static inline void sgx_encl_truncate_backing_page(struct sgx_encl *encl, unsigned long page_index)
+{
+ struct inode *inode = file_inode(encl->backing);
+
+ shmem_truncate_range(inode, PFN_PHYS(page_index), PFN_PHYS(page_index) + PAGE_SIZE - 1);
+}
+
+/*
* ELDU: Load an EPC page as unblocked. For more info, see "OS Management of EPC
* Pages" in the SDM.
*/
@@ -22,9 +46,11 @@ static int __sgx_encl_eldu(struct sgx_encl_page *encl_page,
{
unsigned long va_offset = encl_page->desc & SGX_ENCL_PAGE_VA_OFFSET_MASK;
struct sgx_encl *encl = encl_page->encl;
+ pgoff_t page_index, page_pcmd_off;
struct sgx_pageinfo pginfo;
struct sgx_backing b;
- pgoff_t page_index;
+ bool pcmd_page_empty;
+ u8 *pcmd_page;
int ret;
if (secs_page)
@@ -32,14 +58,16 @@ static int __sgx_encl_eldu(struct sgx_encl_page *encl_page,
else
page_index = PFN_DOWN(encl->size);
+ page_pcmd_off = sgx_encl_get_backing_page_pcmd_offset(encl, page_index);
+
ret = sgx_encl_get_backing(encl, page_index, &b);
if (ret)
return ret;
pginfo.addr = encl_page->desc & PAGE_MASK;
pginfo.contents = (unsigned long)kmap_atomic(b.contents);
- pginfo.metadata = (unsigned long)kmap_atomic(b.pcmd) +
- b.pcmd_offset;
+ pcmd_page = kmap_atomic(b.pcmd);
+ pginfo.metadata = (unsigned long)pcmd_page + b.pcmd_offset;
if (secs_page)
pginfo.secs = (u64)sgx_get_epc_virt_addr(secs_page);
@@ -55,11 +83,24 @@ static int __sgx_encl_eldu(struct sgx_encl_page *encl_page,
ret = -EFAULT;
}
- kunmap_atomic((void *)(unsigned long)(pginfo.metadata - b.pcmd_offset));
+ memset(pcmd_page + b.pcmd_offset, 0, sizeof(struct sgx_pcmd));
+
+ /*
+ * The area for the PCMD in the page was zeroed above. Check if the
+ * whole page is now empty meaning that all PCMD's have been zeroed:
+ */
+ pcmd_page_empty = !memchr_inv(pcmd_page, 0, PAGE_SIZE);
+
+ kunmap_atomic(pcmd_page);
kunmap_atomic((void *)(unsigned long)pginfo.contents);
sgx_encl_put_backing(&b, false);
+ sgx_encl_truncate_backing_page(encl, page_index);
+
+ if (pcmd_page_empty)
+ sgx_encl_truncate_backing_page(encl, PFN_DOWN(page_pcmd_off));
+
return ret;
}
@@ -410,6 +451,8 @@ void sgx_encl_release(struct kref *ref)
}
kfree(entry);
+ /* Invoke scheduler to prevent soft lockups. */
+ cond_resched();
}
xa_destroy(&encl->page_array);
@@ -577,7 +620,7 @@ static struct page *sgx_encl_get_backing_page(struct sgx_encl *encl,
int sgx_encl_get_backing(struct sgx_encl *encl, unsigned long page_index,
struct sgx_backing *backing)
{
- pgoff_t pcmd_index = PFN_DOWN(encl->size) + 1 + (page_index >> 5);
+ pgoff_t page_pcmd_off = sgx_encl_get_backing_page_pcmd_offset(encl, page_index);
struct page *contents;
struct page *pcmd;
@@ -585,7 +628,7 @@ int sgx_encl_get_backing(struct sgx_encl *encl, unsigned long page_index,
if (IS_ERR(contents))
return PTR_ERR(contents);
- pcmd = sgx_encl_get_backing_page(encl, pcmd_index);
+ pcmd = sgx_encl_get_backing_page(encl, PFN_DOWN(page_pcmd_off));
if (IS_ERR(pcmd)) {
put_page(contents);
return PTR_ERR(pcmd);
@@ -594,9 +637,7 @@ int sgx_encl_get_backing(struct sgx_encl *encl, unsigned long page_index,
backing->page_index = page_index;
backing->contents = contents;
backing->pcmd = pcmd;
- backing->pcmd_offset =
- (page_index & (PAGE_SIZE / sizeof(struct sgx_pcmd) - 1)) *
- sizeof(struct sgx_pcmd);
+ backing->pcmd_offset = page_pcmd_off & (PAGE_SIZE - 1);
return 0;
}
diff --git a/arch/x86/kernel/cpu/sgx/main.c b/arch/x86/kernel/cpu/sgx/main.c
index 4b41efc9e367..8e4bc6453d26 100644
--- a/arch/x86/kernel/cpu/sgx/main.c
+++ b/arch/x86/kernel/cpu/sgx/main.c
@@ -344,10 +344,8 @@ static void sgx_reclaim_pages(void)
{
struct sgx_epc_page *chunk[SGX_NR_TO_SCAN];
struct sgx_backing backing[SGX_NR_TO_SCAN];
- struct sgx_epc_section *section;
struct sgx_encl_page *encl_page;
struct sgx_epc_page *epc_page;
- struct sgx_numa_node *node;
pgoff_t page_index;
int cnt = 0;
int ret;
@@ -418,13 +416,7 @@ skip:
kref_put(&encl_page->encl->refcount, sgx_encl_release);
epc_page->flags &= ~SGX_EPC_PAGE_RECLAIMER_TRACKED;
- section = &sgx_epc_sections[epc_page->section];
- node = section->node;
-
- spin_lock(&node->lock);
- list_add_tail(&epc_page->list, &node->free_page_list);
- spin_unlock(&node->lock);
- atomic_long_inc(&sgx_nr_free_pages);
+ sgx_free_epc_page(epc_page);
}
}
diff --git a/arch/x86/kernel/dumpstack.c b/arch/x86/kernel/dumpstack.c
index 53de044e5654..afae4dd77495 100644
--- a/arch/x86/kernel/dumpstack.c
+++ b/arch/x86/kernel/dumpstack.c
@@ -81,12 +81,6 @@ static int copy_code(struct pt_regs *regs, u8 *buf, unsigned long src,
/* The user space code from other tasks cannot be accessed. */
if (regs != task_pt_regs(current))
return -EPERM;
- /*
- * Make sure userspace isn't trying to trick us into dumping kernel
- * memory by pointing the userspace instruction pointer at it.
- */
- if (__chk_range_not_ok(src, nbytes, TASK_SIZE_MAX))
- return -EINVAL;
/*
* Even if named copy_from_user_nmi() this can be invoked from
diff --git a/arch/x86/kernel/e820.c b/arch/x86/kernel/e820.c
index bc0657f0deed..f267205f2d5a 100644
--- a/arch/x86/kernel/e820.c
+++ b/arch/x86/kernel/e820.c
@@ -995,8 +995,10 @@ early_param("memmap", parse_memmap_opt);
*/
void __init e820__reserve_setup_data(void)
{
+ struct setup_indirect *indirect;
struct setup_data *data;
- u64 pa_data;
+ u64 pa_data, pa_next;
+ u32 len;
pa_data = boot_params.hdr.setup_data;
if (!pa_data)
@@ -1004,6 +1006,14 @@ void __init e820__reserve_setup_data(void)
while (pa_data) {
data = early_memremap(pa_data, sizeof(*data));
+ if (!data) {
+ pr_warn("e820: failed to memremap setup_data entry\n");
+ return;
+ }
+
+ len = sizeof(*data);
+ pa_next = data->next;
+
e820__range_update(pa_data, sizeof(*data)+data->len, E820_TYPE_RAM, E820_TYPE_RESERVED_KERN);
/*
@@ -1015,18 +1025,27 @@ void __init e820__reserve_setup_data(void)
sizeof(*data) + data->len,
E820_TYPE_RAM, E820_TYPE_RESERVED_KERN);
- if (data->type == SETUP_INDIRECT &&
- ((struct setup_indirect *)data->data)->type != SETUP_INDIRECT) {
- e820__range_update(((struct setup_indirect *)data->data)->addr,
- ((struct setup_indirect *)data->data)->len,
- E820_TYPE_RAM, E820_TYPE_RESERVED_KERN);
- e820__range_update_kexec(((struct setup_indirect *)data->data)->addr,
- ((struct setup_indirect *)data->data)->len,
- E820_TYPE_RAM, E820_TYPE_RESERVED_KERN);
+ if (data->type == SETUP_INDIRECT) {
+ len += data->len;
+ early_memunmap(data, sizeof(*data));
+ data = early_memremap(pa_data, len);
+ if (!data) {
+ pr_warn("e820: failed to memremap indirect setup_data\n");
+ return;
+ }
+
+ indirect = (struct setup_indirect *)data->data;
+
+ 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 = data->next;
- early_memunmap(data, sizeof(*data));
+ pa_data = pa_next;
+ early_memunmap(data, len);
}
e820__update_table(e820_table);
diff --git a/arch/x86/kernel/early-quirks.c b/arch/x86/kernel/early-quirks.c
index dc7da08bc700..bd6dad83c65b 100644
--- a/arch/x86/kernel/early-quirks.c
+++ b/arch/x86/kernel/early-quirks.c
@@ -555,6 +555,7 @@ static const struct pci_device_id intel_early_ids[] __initconst = {
INTEL_RKL_IDS(&gen11_early_ops),
INTEL_ADLS_IDS(&gen11_early_ops),
INTEL_ADLP_IDS(&gen11_early_ops),
+ INTEL_ADLN_IDS(&gen11_early_ops),
INTEL_RPLS_IDS(&gen11_early_ops),
};
diff --git a/arch/x86/kernel/fpu/core.c b/arch/x86/kernel/fpu/core.c
index 8dea01ffc5c1..19821f027cb3 100644
--- a/arch/x86/kernel/fpu/core.c
+++ b/arch/x86/kernel/fpu/core.c
@@ -612,6 +612,13 @@ int fpu_clone(struct task_struct *dst, unsigned long clone_flags)
fpu_inherit_perms(dst_fpu);
fpregs_unlock();
+ /*
+ * Children never inherit PASID state.
+ * Force it to have its init value:
+ */
+ if (use_xsave())
+ dst_fpu->fpstate->regs.xsave.header.xfeatures &= ~XFEATURE_MASK_PASID;
+
trace_x86_fpu_copy_src(src_fpu);
trace_x86_fpu_copy_dst(dst_fpu);
diff --git a/arch/x86/kernel/fpu/regset.c b/arch/x86/kernel/fpu/regset.c
index 437d7c930c0b..75ffaef8c299 100644
--- a/arch/x86/kernel/fpu/regset.c
+++ b/arch/x86/kernel/fpu/regset.c
@@ -91,11 +91,9 @@ int xfpregs_set(struct task_struct *target, const struct user_regset *regset,
const void *kbuf, const void __user *ubuf)
{
struct fpu *fpu = &target->thread.fpu;
- struct user32_fxsr_struct newstate;
+ struct fxregs_state newstate;
int ret;
- BUILD_BUG_ON(sizeof(newstate) != sizeof(struct fxregs_state));
-
if (!cpu_feature_enabled(X86_FEATURE_FXSR))
return -ENODEV;
@@ -116,9 +114,10 @@ int xfpregs_set(struct task_struct *target, const struct user_regset *regset,
/* Copy the state */
memcpy(&fpu->fpstate->regs.fxsave, &newstate, sizeof(newstate));
- /* Clear xmm8..15 */
+ /* Clear xmm8..15 for 32-bit callers */
BUILD_BUG_ON(sizeof(fpu->__fpstate.regs.fxsave.xmm_space) != 16 * 16);
- memset(&fpu->fpstate->regs.fxsave.xmm_space[8], 0, 8 * 16);
+ if (in_ia32_syscall())
+ memset(&fpu->fpstate->regs.fxsave.xmm_space[8*4], 0, 8 * 16);
/* Mark FP and SSE as in use when XSAVE is enabled */
if (use_xsave())
diff --git a/arch/x86/kernel/fpu/xstate.c b/arch/x86/kernel/fpu/xstate.c
index 02b3ddaf4f75..7c7824ae7862 100644
--- a/arch/x86/kernel/fpu/xstate.c
+++ b/arch/x86/kernel/fpu/xstate.c
@@ -1558,7 +1558,10 @@ static int fpstate_realloc(u64 xfeatures, unsigned int ksize,
fpregs_restore_userregs();
newfps->xfeatures = curfps->xfeatures | xfeatures;
- newfps->user_xfeatures = curfps->user_xfeatures | xfeatures;
+
+ if (!guest_fpu)
+ newfps->user_xfeatures = curfps->user_xfeatures | xfeatures;
+
newfps->xfd = curfps->xfd & ~xfeatures;
/* Do the final updates within the locked region */
diff --git a/arch/x86/kernel/head64.c b/arch/x86/kernel/head64.c
index de563db9cdcd..4f5ecbbaae77 100644
--- a/arch/x86/kernel/head64.c
+++ b/arch/x86/kernel/head64.c
@@ -126,7 +126,7 @@ static bool __head check_la57_support(unsigned long physaddr)
}
#endif
-static unsigned long sme_postprocess_startup(struct boot_params *bp, pmdval_t *pmd)
+static unsigned long __head sme_postprocess_startup(struct boot_params *bp, pmdval_t *pmd)
{
unsigned long vaddr, vaddr_end;
int i;
diff --git a/arch/x86/kernel/kdebugfs.c b/arch/x86/kernel/kdebugfs.c
index 64b6da95af98..e2e89bebcbc3 100644
--- a/arch/x86/kernel/kdebugfs.c
+++ b/arch/x86/kernel/kdebugfs.c
@@ -88,11 +88,13 @@ create_setup_data_node(struct dentry *parent, int no,
static int __init create_setup_data_nodes(struct dentry *parent)
{
+ struct setup_indirect *indirect;
struct setup_data_node *node;
struct setup_data *data;
- int error;
+ u64 pa_data, pa_next;
struct dentry *d;
- u64 pa_data;
+ int error;
+ u32 len;
int no = 0;
d = debugfs_create_dir("setup_data", parent);
@@ -112,12 +114,29 @@ static int __init create_setup_data_nodes(struct dentry *parent)
error = -ENOMEM;
goto err_dir;
}
-
- if (data->type == SETUP_INDIRECT &&
- ((struct setup_indirect *)data->data)->type != SETUP_INDIRECT) {
- node->paddr = ((struct setup_indirect *)data->data)->addr;
- node->type = ((struct setup_indirect *)data->data)->type;
- node->len = ((struct setup_indirect *)data->data)->len;
+ pa_next = data->next;
+
+ if (data->type == SETUP_INDIRECT) {
+ len = sizeof(*data) + data->len;
+ memunmap(data);
+ data = memremap(pa_data, len, MEMREMAP_WB);
+ if (!data) {
+ kfree(node);
+ error = -ENOMEM;
+ goto err_dir;
+ }
+
+ indirect = (struct setup_indirect *)data->data;
+
+ if (indirect->type != SETUP_INDIRECT) {
+ node->paddr = indirect->addr;
+ node->type = indirect->type;
+ node->len = indirect->len;
+ } else {
+ node->paddr = pa_data;
+ node->type = data->type;
+ node->len = data->len;
+ }
} else {
node->paddr = pa_data;
node->type = data->type;
@@ -125,7 +144,7 @@ static int __init create_setup_data_nodes(struct dentry *parent)
}
create_setup_data_node(d, no, node);
- pa_data = data->next;
+ pa_data = pa_next;
memunmap(data);
no++;
diff --git a/arch/x86/kernel/ksysfs.c b/arch/x86/kernel/ksysfs.c
index d0a19121c6a4..257892fcefa7 100644
--- a/arch/x86/kernel/ksysfs.c
+++ b/arch/x86/kernel/ksysfs.c
@@ -91,26 +91,41 @@ static int get_setup_data_paddr(int nr, u64 *paddr)
static int __init get_setup_data_size(int nr, size_t *size)
{
- int i = 0;
+ u64 pa_data = boot_params.hdr.setup_data, pa_next;
+ struct setup_indirect *indirect;
struct setup_data *data;
- u64 pa_data = boot_params.hdr.setup_data;
+ int i = 0;
+ u32 len;
while (pa_data) {
data = memremap(pa_data, sizeof(*data), MEMREMAP_WB);
if (!data)
return -ENOMEM;
+ pa_next = data->next;
+
if (nr == i) {
- if (data->type == SETUP_INDIRECT &&
- ((struct setup_indirect *)data->data)->type != SETUP_INDIRECT)
- *size = ((struct setup_indirect *)data->data)->len;
- else
+ if (data->type == SETUP_INDIRECT) {
+ len = sizeof(*data) + data->len;
+ memunmap(data);
+ data = memremap(pa_data, len, MEMREMAP_WB);
+ if (!data)
+ return -ENOMEM;
+
+ indirect = (struct setup_indirect *)data->data;
+
+ if (indirect->type != SETUP_INDIRECT)
+ *size = indirect->len;
+ else
+ *size = data->len;
+ } else {
*size = data->len;
+ }
memunmap(data);
return 0;
}
- pa_data = data->next;
+ pa_data = pa_next;
memunmap(data);
i++;
}
@@ -120,9 +135,11 @@ static int __init get_setup_data_size(int nr, size_t *size)
static ssize_t type_show(struct kobject *kobj,
struct kobj_attribute *attr, char *buf)
{
+ struct setup_indirect *indirect;
+ struct setup_data *data;
int nr, ret;
u64 paddr;
- struct setup_data *data;
+ u32 len;
ret = kobj_to_setup_data_nr(kobj, &nr);
if (ret)
@@ -135,10 +152,20 @@ static ssize_t type_show(struct kobject *kobj,
if (!data)
return -ENOMEM;
- if (data->type == SETUP_INDIRECT)
- ret = sprintf(buf, "0x%x\n", ((struct setup_indirect *)data->data)->type);
- else
+ if (data->type == SETUP_INDIRECT) {
+ len = sizeof(*data) + data->len;
+ memunmap(data);
+ data = memremap(paddr, len, MEMREMAP_WB);
+ if (!data)
+ return -ENOMEM;
+
+ indirect = (struct setup_indirect *)data->data;
+
+ ret = sprintf(buf, "0x%x\n", indirect->type);
+ } else {
ret = sprintf(buf, "0x%x\n", data->type);
+ }
+
memunmap(data);
return ret;
}
@@ -149,9 +176,10 @@ static ssize_t setup_data_data_read(struct file *fp,
char *buf,
loff_t off, size_t count)
{
+ struct setup_indirect *indirect;
+ struct setup_data *data;
int nr, ret = 0;
u64 paddr, len;
- struct setup_data *data;
void *p;
ret = kobj_to_setup_data_nr(kobj, &nr);
@@ -165,10 +193,27 @@ static ssize_t setup_data_data_read(struct file *fp,
if (!data)
return -ENOMEM;
- if (data->type == SETUP_INDIRECT &&
- ((struct setup_indirect *)data->data)->type != SETUP_INDIRECT) {
- paddr = ((struct setup_indirect *)data->data)->addr;
- len = ((struct setup_indirect *)data->data)->len;
+ if (data->type == SETUP_INDIRECT) {
+ len = sizeof(*data) + data->len;
+ memunmap(data);
+ data = memremap(paddr, len, MEMREMAP_WB);
+ if (!data)
+ return -ENOMEM;
+
+ indirect = (struct setup_indirect *)data->data;
+
+ if (indirect->type != SETUP_INDIRECT) {
+ paddr = indirect->addr;
+ len = indirect->len;
+ } else {
+ /*
+ * Even though this is technically undefined, return
+ * the data as though it is a normal setup_data struct.
+ * This will at least allow it to be inspected.
+ */
+ paddr += sizeof(*data);
+ len = data->len;
+ }
} else {
paddr += sizeof(*data);
len = data->len;
diff --git a/arch/x86/kernel/kvm.c b/arch/x86/kernel/kvm.c
index a438217cbfac..d77481ecb0d5 100644
--- a/arch/x86/kernel/kvm.c
+++ b/arch/x86/kernel/kvm.c
@@ -462,19 +462,24 @@ static bool pv_tlb_flush_supported(void)
{
return (kvm_para_has_feature(KVM_FEATURE_PV_TLB_FLUSH) &&
!kvm_para_has_hint(KVM_HINTS_REALTIME) &&
- kvm_para_has_feature(KVM_FEATURE_STEAL_TIME));
+ kvm_para_has_feature(KVM_FEATURE_STEAL_TIME) &&
+ !boot_cpu_has(X86_FEATURE_MWAIT) &&
+ (num_possible_cpus() != 1));
}
static bool pv_ipi_supported(void)
{
- return kvm_para_has_feature(KVM_FEATURE_PV_SEND_IPI);
+ return (kvm_para_has_feature(KVM_FEATURE_PV_SEND_IPI) &&
+ (num_possible_cpus() != 1));
}
static bool pv_sched_yield_supported(void)
{
return (kvm_para_has_feature(KVM_FEATURE_PV_SCHED_YIELD) &&
!kvm_para_has_hint(KVM_HINTS_REALTIME) &&
- kvm_para_has_feature(KVM_FEATURE_STEAL_TIME));
+ kvm_para_has_feature(KVM_FEATURE_STEAL_TIME) &&
+ !boot_cpu_has(X86_FEATURE_MWAIT) &&
+ (num_possible_cpus() != 1));
}
#define KVM_IPI_CLUSTER_SIZE (2 * BITS_PER_LONG)
@@ -619,7 +624,7 @@ static void kvm_smp_send_call_func_ipi(const struct cpumask *mask)
/* Make sure other vCPUs get a chance to run if they need to. */
for_each_cpu(cpu, mask) {
- if (vcpu_is_preempted(cpu)) {
+ if (!idle_cpu(cpu) && vcpu_is_preempted(cpu)) {
kvm_hypercall1(KVM_HC_SCHED_YIELD, per_cpu(x86_cpu_to_apicid, cpu));
break;
}
diff --git a/arch/x86/kernel/kvmclock.c b/arch/x86/kernel/kvmclock.c
index a35cbf9107af..c5caa7311bd8 100644
--- a/arch/x86/kernel/kvmclock.c
+++ b/arch/x86/kernel/kvmclock.c
@@ -239,6 +239,9 @@ static void __init kvmclock_init_mem(void)
static int __init kvm_setup_vsyscall_timeinfo(void)
{
+ if (!kvm_para_available() || !kvmclock)
+ return 0;
+
kvmclock_init_mem();
#ifdef CONFIG_X86_64
diff --git a/arch/x86/kernel/module.c b/arch/x86/kernel/module.c
index 95fa745e310a..96d7c27b7093 100644
--- a/arch/x86/kernel/module.c
+++ b/arch/x86/kernel/module.c
@@ -273,6 +273,14 @@ int module_finalize(const Elf_Ehdr *hdr,
retpolines = s;
}
+ /*
+ * See alternative_instructions() for the ordering rules between the
+ * various patching types.
+ */
+ if (para) {
+ void *pseg = (void *)para->sh_addr;
+ apply_paravirt(pseg, pseg + para->sh_size);
+ }
if (retpolines) {
void *rseg = (void *)retpolines->sh_addr;
apply_retpolines(rseg, rseg + retpolines->sh_size);
@@ -290,11 +298,6 @@ int module_finalize(const Elf_Ehdr *hdr,
tseg, tseg + text->sh_size);
}
- if (para) {
- void *pseg = (void *)para->sh_addr;
- apply_paravirt(pseg, pseg + para->sh_size);
- }
-
/* make jump label nops */
jump_label_apply_nops(me);
diff --git a/arch/x86/kernel/nmi.c b/arch/x86/kernel/nmi.c
index 4bce802d25fb..e73f7df362f5 100644
--- a/arch/x86/kernel/nmi.c
+++ b/arch/x86/kernel/nmi.c
@@ -292,7 +292,6 @@ unknown_nmi_error(unsigned char reason, struct pt_regs *regs)
pr_emerg("Uhhuh. NMI received for unknown reason %02x on CPU %d.\n",
reason, smp_processor_id());
- pr_emerg("Do you have a strange power saving mode enabled?\n");
if (unknown_nmi_panic || panic_on_unrecovered_nmi)
nmi_panic(regs, "NMI: Not continuing");
diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c
index 81d8ef036637..e131d71b3cae 100644
--- a/arch/x86/kernel/process.c
+++ b/arch/x86/kernel/process.c
@@ -765,8 +765,11 @@ void stop_this_cpu(void *dummy)
* without the encryption bit, they don't race each other when flushed
* and potentially end up with the wrong entry being committed to
* memory.
+ *
+ * Test the CPUID bit directly because the machine might've cleared
+ * X86_FEATURE_SME due to cmdline options.
*/
- if (boot_cpu_has(X86_FEATURE_SME))
+ if (cpuid_eax(0x8000001f) & BIT(0))
native_wbinvd();
for (;;) {
/*
diff --git a/arch/x86/kernel/ptrace.c b/arch/x86/kernel/ptrace.c
index 6d2244c94799..8d2f2f995539 100644
--- a/arch/x86/kernel/ptrace.c
+++ b/arch/x86/kernel/ptrace.c
@@ -1224,7 +1224,7 @@ static struct user_regset x86_64_regsets[] __ro_after_init = {
},
[REGSET_FP] = {
.core_note_type = NT_PRFPREG,
- .n = sizeof(struct user_i387_struct) / sizeof(long),
+ .n = sizeof(struct fxregs_state) / sizeof(long),
.size = sizeof(long), .align = sizeof(long),
.active = regset_xregset_fpregs_active, .regset_get = xfpregs_get, .set = xfpregs_set
},
@@ -1271,7 +1271,7 @@ static struct user_regset x86_32_regsets[] __ro_after_init = {
},
[REGSET_XFP] = {
.core_note_type = NT_PRXFPREG,
- .n = sizeof(struct user32_fxsr_struct) / sizeof(u32),
+ .n = sizeof(struct fxregs_state) / sizeof(u32),
.size = sizeof(u32), .align = sizeof(u32),
.active = regset_xregset_fpregs_active, .regset_get = xfpregs_get, .set = xfpregs_set
},
diff --git a/arch/x86/kernel/resource.c b/arch/x86/kernel/resource.c
index 9ae64f9af956..9b9fb7882c20 100644
--- a/arch/x86/kernel/resource.c
+++ b/arch/x86/kernel/resource.c
@@ -1,5 +1,4 @@
// SPDX-License-Identifier: GPL-2.0
-#include <linux/dmi.h>
#include <linux/ioport.h>
#include <asm/e820/api.h>
@@ -24,31 +23,11 @@ static void resource_clip(struct resource *res, resource_size_t start,
res->start = end + 1;
}
-/*
- * Some BIOS-es contain a bug where they add addresses which map to
- * system RAM in the PCI host bridge window returned by the ACPI _CRS
- * method, see commit 4dc2287c1805 ("x86: avoid E820 regions when
- * allocating address space"). To avoid this Linux by default excludes
- * E820 reservations when allocating addresses since 2010.
- * In 2019 some systems have shown-up with E820 reservations which cover
- * the entire _CRS returned PCI host bridge window, causing all attempts
- * to assign memory to PCI BARs to fail if Linux uses E820 reservations.
- *
- * Ideally Linux would fully stop using E820 reservations, but then
- * the old systems this was added for will regress.
- * Instead keep the old behavior for old systems, while ignoring the
- * E820 reservations for any systems from now on.
- */
static void remove_e820_regions(struct resource *avail)
{
- int i, year = dmi_get_bios_year();
+ int i;
struct e820_entry *entry;
- if (year >= 2018)
- return;
-
- pr_info_once("PCI: Removing E820 reservations from host bridge windows\n");
-
for (i = 0; i < e820_table->nr_entries; i++) {
entry = &e820_table->entries[i];
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index f7a132eb794d..c95b9ac5a457 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -369,21 +369,41 @@ static void __init parse_setup_data(void)
static void __init memblock_x86_reserve_range_setup_data(void)
{
+ struct setup_indirect *indirect;
struct setup_data *data;
- u64 pa_data;
+ u64 pa_data, pa_next;
+ u32 len;
pa_data = boot_params.hdr.setup_data;
while (pa_data) {
data = early_memremap(pa_data, sizeof(*data));
+ if (!data) {
+ pr_warn("setup: failed to memremap setup_data entry\n");
+ return;
+ }
+
+ len = sizeof(*data);
+ pa_next = data->next;
+
memblock_reserve(pa_data, sizeof(*data) + data->len);
- if (data->type == SETUP_INDIRECT &&
- ((struct setup_indirect *)data->data)->type != SETUP_INDIRECT)
- memblock_reserve(((struct setup_indirect *)data->data)->addr,
- ((struct setup_indirect *)data->data)->len);
+ if (data->type == SETUP_INDIRECT) {
+ len += data->len;
+ early_memunmap(data, sizeof(*data));
+ data = early_memremap(pa_data, len);
+ if (!data) {
+ pr_warn("setup: failed to memremap indirect setup_data\n");
+ return;
+ }
- pa_data = data->next;
- early_memunmap(data, sizeof(*data));
+ indirect = (struct setup_indirect *)data->data;
+
+ if (indirect->type != SETUP_INDIRECT)
+ memblock_reserve(indirect->addr, indirect->len);
+ }
+
+ pa_data = pa_next;
+ early_memunmap(data, len);
}
}
@@ -391,8 +411,6 @@ static void __init memblock_x86_reserve_range_setup_data(void)
* --------- Crashkernel reservation ------------------------------
*/
-#ifdef CONFIG_KEXEC_CORE
-
/* 16M alignment for crash kernel regions */
#define CRASH_ALIGN SZ_16M
@@ -470,6 +488,9 @@ static void __init reserve_crashkernel(void)
bool high = false;
int ret;
+ if (!IS_ENABLED(CONFIG_KEXEC_CORE))
+ return;
+
total_mem = memblock_phys_mem_size();
/* crashkernel=XM */
@@ -535,11 +556,6 @@ static void __init reserve_crashkernel(void)
crashk_res.end = crash_base + crash_size - 1;
insert_resource(&iomem_resource, &crashk_res);
}
-#else
-static void __init reserve_crashkernel(void)
-{
-}
-#endif
static struct resource standard_io_resources[] = {
{ .name = "dma1", .start = 0x00, .end = 0x1f,
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c
index 617012f4619f..2ef14772dc04 100644
--- a/arch/x86/kernel/smpboot.c
+++ b/arch/x86/kernel/smpboot.c
@@ -83,10 +83,6 @@
#include <asm/hw_irq.h>
#include <asm/stackprotector.h>
-#ifdef CONFIG_ACPI_CPPC_LIB
-#include <acpi/cppc_acpi.h>
-#endif
-
/* representing HT siblings of each logical CPU */
DEFINE_PER_CPU_READ_MOSTLY(cpumask_var_t, cpu_sibling_map);
EXPORT_PER_CPU_SYMBOL(cpu_sibling_map);
@@ -155,8 +151,6 @@ static inline void smpboot_restore_warm_reset_vector(void)
*((volatile u32 *)phys_to_virt(TRAMPOLINE_PHYS_LOW)) = 0;
}
-static void init_freq_invariance(bool secondary, bool cppc_ready);
-
/*
* Report back to the Boot Processor during boot time or to the caller processor
* during CPU online.
@@ -2097,48 +2091,6 @@ out:
return true;
}
-#ifdef CONFIG_ACPI_CPPC_LIB
-static bool amd_set_max_freq_ratio(void)
-{
- struct cppc_perf_caps perf_caps;
- u64 highest_perf, nominal_perf;
- u64 perf_ratio;
- int rc;
-
- rc = cppc_get_perf_caps(0, &perf_caps);
- if (rc) {
- pr_debug("Could not retrieve perf counters (%d)\n", rc);
- return false;
- }
-
- highest_perf = amd_get_highest_perf();
- nominal_perf = perf_caps.nominal_perf;
-
- if (!highest_perf || !nominal_perf) {
- pr_debug("Could not retrieve highest or nominal performance\n");
- return false;
- }
-
- perf_ratio = div_u64(highest_perf * SCHED_CAPACITY_SCALE, nominal_perf);
- /* midpoint between max_boost and max_P */
- perf_ratio = (perf_ratio + SCHED_CAPACITY_SCALE) >> 1;
- if (!perf_ratio) {
- pr_debug("Non-zero highest/nominal perf values led to a 0 ratio\n");
- return false;
- }
-
- arch_turbo_freq_ratio = perf_ratio;
- arch_set_max_freq_ratio(false);
-
- return true;
-}
-#else
-static bool amd_set_max_freq_ratio(void)
-{
- return false;
-}
-#endif
-
static void init_counter_refs(void)
{
u64 aperf, mperf;
@@ -2167,7 +2119,7 @@ static void register_freq_invariance_syscore_ops(void)
static inline void register_freq_invariance_syscore_ops(void) {}
#endif
-static void init_freq_invariance(bool secondary, bool cppc_ready)
+void init_freq_invariance(bool secondary, bool cppc_ready)
{
bool ret = false;
@@ -2187,7 +2139,7 @@ static void init_freq_invariance(bool secondary, bool cppc_ready)
if (!cppc_ready) {
return;
}
- ret = amd_set_max_freq_ratio();
+ ret = amd_set_max_freq_ratio(&arch_turbo_freq_ratio);
}
if (ret) {
@@ -2200,22 +2152,6 @@ static void init_freq_invariance(bool secondary, bool cppc_ready)
}
}
-#ifdef CONFIG_ACPI_CPPC_LIB
-static DEFINE_MUTEX(freq_invariance_lock);
-
-void init_freq_invariance_cppc(void)
-{
- static bool secondary;
-
- mutex_lock(&freq_invariance_lock);
-
- init_freq_invariance(secondary, true);
- secondary = true;
-
- mutex_unlock(&freq_invariance_lock);
-}
-#endif
-
static void disable_freq_invariance_workfn(struct work_struct *work)
{
static_branch_disable(&arch_scale_freq_key);
@@ -2264,8 +2200,4 @@ error:
pr_warn("Scheduler frequency invariance went wobbly, disabling!\n");
schedule_work(&disable_freq_invariance_work);
}
-#else
-static inline void init_freq_invariance(bool secondary, bool cppc_ready)
-{
-}
#endif /* CONFIG_X86_64 */
diff --git a/arch/x86/kernel/stacktrace.c b/arch/x86/kernel/stacktrace.c
index 15b058eefc4e..ee117fcf46ed 100644
--- a/arch/x86/kernel/stacktrace.c
+++ b/arch/x86/kernel/stacktrace.c
@@ -90,7 +90,7 @@ copy_stack_frame(const struct stack_frame_user __user *fp,
{
int ret;
- if (__range_not_ok(fp, sizeof(*frame), TASK_SIZE))
+ if (!__access_ok(fp, sizeof(*frame)))
return 0;
ret = 1;
diff --git a/arch/x86/kernel/topology.c b/arch/x86/kernel/topology.c
index bd83748e2bde..8617d1ed9d31 100644
--- a/arch/x86/kernel/topology.c
+++ b/arch/x86/kernel/topology.c
@@ -154,11 +154,6 @@ static int __init topology_init(void)
{
int i;
-#ifdef CONFIG_NUMA
- for_each_online_node(i)
- register_one_node(i);
-#endif
-
for_each_present_cpu(i)
arch_register_cpu(i);
diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c
index c9d566dcf89a..2e37862e3a8c 100644
--- a/arch/x86/kernel/traps.c
+++ b/arch/x86/kernel/traps.c
@@ -39,6 +39,7 @@
#include <linux/io.h>
#include <linux/hardirq.h>
#include <linux/atomic.h>
+#include <linux/ioasid.h>
#include <asm/stacktrace.h>
#include <asm/processor.h>
@@ -559,6 +560,57 @@ static bool fixup_iopl_exception(struct pt_regs *regs)
return true;
}
+/*
+ * The unprivileged ENQCMD instruction generates #GPs if the
+ * IA32_PASID MSR has not been populated. If possible, populate
+ * the MSR from a PASID previously allocated to the mm.
+ */
+static bool try_fixup_enqcmd_gp(void)
+{
+#ifdef CONFIG_IOMMU_SVA
+ u32 pasid;
+
+ /*
+ * MSR_IA32_PASID is managed using XSAVE. Directly
+ * writing to the MSR is only possible when fpregs
+ * are valid and the fpstate is not. This is
+ * guaranteed when handling a userspace exception
+ * in *before* interrupts are re-enabled.
+ */
+ lockdep_assert_irqs_disabled();
+
+ /*
+ * Hardware without ENQCMD will not generate
+ * #GPs that can be fixed up here.
+ */
+ if (!cpu_feature_enabled(X86_FEATURE_ENQCMD))
+ return false;
+
+ pasid = current->mm->pasid;
+
+ /*
+ * If the mm has not been allocated a
+ * PASID, the #GP can not be fixed up.
+ */
+ if (!pasid_valid(pasid))
+ return false;
+
+ /*
+ * Did this thread already have its PASID activated?
+ * If so, the #GP must be from something else.
+ */
+ if (current->pasid_activated)
+ return false;
+
+ wrmsrl(MSR_IA32_PASID, pasid | MSR_IA32_PASID_VALID);
+ current->pasid_activated = 1;
+
+ return true;
+#else
+ return false;
+#endif
+}
+
DEFINE_IDTENTRY_ERRORCODE(exc_general_protection)
{
char desc[sizeof(GPFSTR) + 50 + 2*sizeof(unsigned long) + 1] = GPFSTR;
@@ -567,6 +619,9 @@ DEFINE_IDTENTRY_ERRORCODE(exc_general_protection)
unsigned long gp_addr;
int ret;
+ if (user_mode(regs) && try_fixup_enqcmd_gp())
+ return;
+
cond_local_irq_enable(regs);
if (static_cpu_has(X86_FEATURE_UMIP)) {
@@ -659,6 +714,7 @@ static bool do_int3(struct pt_regs *regs)
return res == NOTIFY_STOP;
}
+NOKPROBE_SYMBOL(do_int3);
static void do_int3_user(struct pt_regs *regs)
{
diff --git a/arch/x86/kernel/x86_init.c b/arch/x86/kernel/x86_init.c
index 7d20c1d34a3c..e84ee5cdbd8c 100644
--- a/arch/x86/kernel/x86_init.c
+++ b/arch/x86/kernel/x86_init.c
@@ -129,6 +129,11 @@ struct x86_cpuinit_ops x86_cpuinit = {
static void default_nmi_init(void) { };
+static void enc_status_change_prepare_noop(unsigned long vaddr, int npages, bool enc) { }
+static bool enc_status_change_finish_noop(unsigned long vaddr, int npages, bool enc) { return false; }
+static bool enc_tlb_flush_required_noop(bool enc) { return false; }
+static bool enc_cache_flush_required_noop(void) { return false; }
+
struct x86_platform_ops x86_platform __ro_after_init = {
.calibrate_cpu = native_calibrate_cpu_early,
.calibrate_tsc = native_calibrate_tsc,
@@ -138,9 +143,16 @@ struct x86_platform_ops x86_platform __ro_after_init = {
.is_untracked_pat_range = is_ISA_range,
.nmi_init = default_nmi_init,
.get_nmi_reason = default_get_nmi_reason,
- .save_sched_clock_state = tsc_save_sched_clock_state,
- .restore_sched_clock_state = tsc_restore_sched_clock_state,
+ .save_sched_clock_state = tsc_save_sched_clock_state,
+ .restore_sched_clock_state = tsc_restore_sched_clock_state,
.hyper.pin_vcpu = x86_op_int_noop,
+
+ .guest = {
+ .enc_status_change_prepare = enc_status_change_prepare_noop,
+ .enc_status_change_finish = enc_status_change_finish_noop,
+ .enc_tlb_flush_required = enc_tlb_flush_required_noop,
+ .enc_cache_flush_required = enc_cache_flush_required_noop,
+ },
};
EXPORT_SYMBOL_GPL(x86_platform);
diff --git a/arch/x86/kvm/Kconfig b/arch/x86/kvm/Kconfig
index 2b1548da00eb..e3cbd7706136 100644
--- a/arch/x86/kvm/Kconfig
+++ b/arch/x86/kvm/Kconfig
@@ -126,13 +126,6 @@ config KVM_XEN
If in doubt, say "N".
-config KVM_MMU_AUDIT
- bool "Audit KVM MMU"
- depends on KVM && TRACEPOINTS
- help
- This option adds a R/W kVM module parameter 'mmu_audit', which allows
- auditing of KVM MMU events at runtime.
-
config KVM_EXTERNAL_WRITE_TRACKING
bool
diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c
index 3902c28fb6cb..a00cd97b2623 100644
--- a/arch/x86/kvm/cpuid.c
+++ b/arch/x86/kvm/cpuid.c
@@ -133,6 +133,7 @@ static int kvm_cpuid_check_equal(struct kvm_vcpu *vcpu, struct kvm_cpuid_entry2
orig = &vcpu->arch.cpuid_entries[i];
if (e2[i].function != orig->function ||
e2[i].index != orig->index ||
+ e2[i].flags != orig->flags ||
e2[i].eax != orig->eax || e2[i].ebx != orig->ebx ||
e2[i].ecx != orig->ecx || e2[i].edx != orig->edx)
return -EINVAL;
@@ -196,10 +197,26 @@ void kvm_update_pv_runtime(struct kvm_vcpu *vcpu)
vcpu->arch.pv_cpuid.features = best->eax;
}
+/*
+ * Calculate guest's supported XCR0 taking into account guest CPUID data and
+ * supported_xcr0 (comprised of host configuration and KVM_SUPPORTED_XCR0).
+ */
+static u64 cpuid_get_supported_xcr0(struct kvm_cpuid_entry2 *entries, int nent)
+{
+ struct kvm_cpuid_entry2 *best;
+
+ best = cpuid_entry2_find(entries, nent, 0xd, 0);
+ if (!best)
+ return 0;
+
+ return (best->eax | ((u64)best->edx << 32)) & supported_xcr0;
+}
+
static void __kvm_update_cpuid_runtime(struct kvm_vcpu *vcpu, struct kvm_cpuid_entry2 *entries,
int nent)
{
struct kvm_cpuid_entry2 *best;
+ u64 guest_supported_xcr0 = cpuid_get_supported_xcr0(entries, nent);
best = cpuid_entry2_find(entries, nent, 1, 0);
if (best) {
@@ -238,6 +255,21 @@ static void __kvm_update_cpuid_runtime(struct kvm_vcpu *vcpu, struct kvm_cpuid_e
vcpu->arch.ia32_misc_enable_msr &
MSR_IA32_MISC_ENABLE_MWAIT);
}
+
+ /*
+ * Bits 127:0 of the allowed SECS.ATTRIBUTES (CPUID.0x12.0x1) enumerate
+ * the supported XSAVE Feature Request Mask (XFRM), i.e. the enclave's
+ * requested XCR0 value. The enclave's XFRM must be a subset of XCRO
+ * at the time of EENTER, thus adjust the allowed XFRM by the guest's
+ * supported XCR0. Similar to XCR0 handling, FP and SSE are forced to
+ * '1' even on CPUs that don't support XSAVE.
+ */
+ best = cpuid_entry2_find(entries, nent, 0x12, 0x1);
+ if (best) {
+ best->ecx &= guest_supported_xcr0 & 0xffffffff;
+ best->edx &= guest_supported_xcr0 >> 32;
+ best->ecx |= XFEATURE_MASK_FPSSE;
+ }
}
void kvm_update_cpuid_runtime(struct kvm_vcpu *vcpu)
@@ -250,6 +282,7 @@ static void kvm_vcpu_after_set_cpuid(struct kvm_vcpu *vcpu)
{
struct kvm_lapic *apic = vcpu->arch.apic;
struct kvm_cpuid_entry2 *best;
+ u64 guest_supported_xcr0;
best = kvm_find_cpuid_entry(vcpu, 1, 0);
if (best && apic) {
@@ -261,27 +294,10 @@ static void kvm_vcpu_after_set_cpuid(struct kvm_vcpu *vcpu)
kvm_apic_set_version(vcpu);
}
- best = kvm_find_cpuid_entry(vcpu, 0xD, 0);
- if (!best)
- vcpu->arch.guest_supported_xcr0 = 0;
- else
- vcpu->arch.guest_supported_xcr0 =
- (best->eax | ((u64)best->edx << 32)) & supported_xcr0;
+ guest_supported_xcr0 =
+ cpuid_get_supported_xcr0(vcpu->arch.cpuid_entries, vcpu->arch.cpuid_nent);
- /*
- * Bits 127:0 of the allowed SECS.ATTRIBUTES (CPUID.0x12.0x1) enumerate
- * the supported XSAVE Feature Request Mask (XFRM), i.e. the enclave's
- * requested XCR0 value. The enclave's XFRM must be a subset of XCRO
- * at the time of EENTER, thus adjust the allowed XFRM by the guest's
- * supported XCR0. Similar to XCR0 handling, FP and SSE are forced to
- * '1' even on CPUs that don't support XSAVE.
- */
- best = kvm_find_cpuid_entry(vcpu, 0x12, 0x1);
- if (best) {
- best->ecx &= vcpu->arch.guest_supported_xcr0 & 0xffffffff;
- best->edx &= vcpu->arch.guest_supported_xcr0 >> 32;
- best->ecx |= XFEATURE_MASK_FPSSE;
- }
+ vcpu->arch.guest_fpu.fpstate->user_xfeatures = guest_supported_xcr0;
kvm_update_pv_runtime(vcpu);
@@ -346,8 +362,14 @@ static int kvm_set_cpuid(struct kvm_vcpu *vcpu, struct kvm_cpuid_entry2 *e2,
* KVM_SET_CPUID{,2} again. To support this legacy behavior, check
* whether the supplied CPUID data is equal to what's already set.
*/
- if (vcpu->arch.last_vmentry_cpu != -1)
- return kvm_cpuid_check_equal(vcpu, e2, nent);
+ if (vcpu->arch.last_vmentry_cpu != -1) {
+ r = kvm_cpuid_check_equal(vcpu, e2, nent);
+ if (r)
+ return r;
+
+ kvfree(e2);
+ return 0;
+ }
r = kvm_check_cpuid(vcpu, e2, nent);
if (r)
@@ -535,12 +557,13 @@ void kvm_set_cpu_caps(void)
);
kvm_cpu_cap_mask(CPUID_7_0_EBX,
- F(FSGSBASE) | F(SGX) | F(BMI1) | F(HLE) | F(AVX2) | F(SMEP) |
- F(BMI2) | F(ERMS) | F(INVPCID) | F(RTM) | 0 /*MPX*/ | F(RDSEED) |
- F(ADX) | F(SMAP) | F(AVX512IFMA) | F(AVX512F) | F(AVX512PF) |
- F(AVX512ER) | F(AVX512CD) | F(CLFLUSHOPT) | F(CLWB) | F(AVX512DQ) |
- F(SHA_NI) | F(AVX512BW) | F(AVX512VL) | 0 /*INTEL_PT*/
- );
+ F(FSGSBASE) | F(SGX) | F(BMI1) | F(HLE) | F(AVX2) |
+ F(FDP_EXCPTN_ONLY) | F(SMEP) | F(BMI2) | F(ERMS) | F(INVPCID) |
+ F(RTM) | F(ZERO_FCS_FDS) | 0 /*MPX*/ | F(AVX512F) |
+ F(AVX512DQ) | F(RDSEED) | F(ADX) | F(SMAP) | F(AVX512IFMA) |
+ F(CLFLUSHOPT) | F(CLWB) | 0 /*INTEL_PT*/ | F(AVX512PF) |
+ F(AVX512ER) | F(AVX512CD) | F(SHA_NI) | F(AVX512BW) |
+ F(AVX512VL));
kvm_cpu_cap_mask(CPUID_7_ECX,
F(AVX512VBMI) | F(LA57) | F(PKU) | 0 /*OSPKE*/ | F(RDPID) |
@@ -692,9 +715,30 @@ static struct kvm_cpuid_entry2 *do_host_cpuid(struct kvm_cpuid_array *array,
entry = &array->entries[array->nent++];
+ memset(entry, 0, sizeof(*entry));
entry->function = function;
entry->index = index;
- entry->flags = 0;
+ switch (function & 0xC0000000) {
+ case 0x40000000:
+ /* Hypervisor leaves are always synthesized by __do_cpuid_func. */
+ return entry;
+
+ case 0x80000000:
+ /*
+ * 0x80000021 is sometimes synthesized by __do_cpuid_func, which
+ * would result in out-of-bounds calls to do_host_cpuid.
+ */
+ {
+ static int max_cpuid_80000000;
+ if (!READ_ONCE(max_cpuid_80000000))
+ WRITE_ONCE(max_cpuid_80000000, cpuid_eax(0x80000000));
+ if (function > READ_ONCE(max_cpuid_80000000))
+ return entry;
+ }
+
+ default:
+ break;
+ }
cpuid_count(entry->function, entry->index,
&entry->eax, &entry->ebx, &entry->ecx, &entry->edx);
@@ -856,7 +900,8 @@ static inline int __do_cpuid_func(struct kvm_cpuid_array *array, u32 function)
eax.split.bit_width = cap.bit_width_gp;
eax.split.mask_length = cap.events_mask_len;
- edx.split.num_counters_fixed = min(cap.num_counters_fixed, MAX_FIXED_COUNTERS);
+ edx.split.num_counters_fixed =
+ min(cap.num_counters_fixed, KVM_PMC_MAX_FIXED);
edx.split.bit_width_fixed = cap.bit_width_fixed;
if (cap.version)
edx.split.anythread_deprecated = 1;
@@ -887,13 +932,14 @@ static inline int __do_cpuid_func(struct kvm_cpuid_array *array, u32 function)
}
break;
case 0xd: {
- u64 guest_perm = xstate_get_guest_group_perm();
+ u64 permitted_xcr0 = supported_xcr0 & xstate_get_guest_group_perm();
+ u64 permitted_xss = supported_xss;
- entry->eax &= supported_xcr0 & guest_perm;
- entry->ebx = xstate_required_size(supported_xcr0, false);
+ entry->eax &= permitted_xcr0;
+ entry->ebx = xstate_required_size(permitted_xcr0, false);
entry->ecx = entry->ebx;
- entry->edx &= (supported_xcr0 & guest_perm) >> 32;
- if (!supported_xcr0)
+ entry->edx &= permitted_xcr0 >> 32;
+ if (!permitted_xcr0)
break;
entry = do_host_cpuid(array, function, 1);
@@ -902,20 +948,20 @@ static inline int __do_cpuid_func(struct kvm_cpuid_array *array, u32 function)
cpuid_entry_override(entry, CPUID_D_1_EAX);
if (entry->eax & (F(XSAVES)|F(XSAVEC)))
- entry->ebx = xstate_required_size(supported_xcr0 | supported_xss,
+ entry->ebx = xstate_required_size(permitted_xcr0 | permitted_xss,
true);
else {
- WARN_ON_ONCE(supported_xss != 0);
+ WARN_ON_ONCE(permitted_xss != 0);
entry->ebx = 0;
}
- entry->ecx &= supported_xss;
- entry->edx &= supported_xss >> 32;
+ entry->ecx &= permitted_xss;
+ entry->edx &= permitted_xss >> 32;
for (i = 2; i < 64; ++i) {
bool s_state;
- if (supported_xcr0 & BIT_ULL(i))
+ if (permitted_xcr0 & BIT_ULL(i))
s_state = false;
- else if (supported_xss & BIT_ULL(i))
+ else if (permitted_xss & BIT_ULL(i))
s_state = true;
else
continue;
@@ -929,7 +975,7 @@ static inline int __do_cpuid_func(struct kvm_cpuid_array *array, u32 function)
* invalid sub-leafs. Only valid sub-leafs should
* reach this point, and they should have a non-zero
* save state size. Furthermore, check whether the
- * processor agrees with supported_xcr0/supported_xss
+ * processor agrees with permitted_xcr0/permitted_xss
* on whether this is an XCR0- or IA32_XSS-managed area.
*/
if (WARN_ON_ONCE(!entry->eax || (entry->ecx & 0x1) != s_state)) {
@@ -1036,7 +1082,15 @@ static inline int __do_cpuid_func(struct kvm_cpuid_array *array, u32 function)
entry->edx = 0;
break;
case 0x80000000:
- entry->eax = min(entry->eax, 0x8000001f);
+ entry->eax = min(entry->eax, 0x80000021);
+ /*
+ * Serializing LFENCE is reported in a multitude of ways,
+ * and NullSegClearsBase is not reported in CPUID on Zen2;
+ * help userspace by providing the CPUID leaf ourselves.
+ */
+ if (static_cpu_has(X86_FEATURE_LFENCE_RDTSC)
+ || !static_cpu_has_bug(X86_BUG_NULL_SEG))
+ entry->eax = max(entry->eax, 0x80000021);
break;
case 0x80000001:
cpuid_entry_override(entry, CPUID_8000_0001_EDX);
@@ -1107,6 +1161,27 @@ static inline int __do_cpuid_func(struct kvm_cpuid_array *array, u32 function)
entry->ebx &= ~GENMASK(11, 6);
}
break;
+ case 0x80000020:
+ entry->eax = entry->ebx = entry->ecx = entry->edx = 0;
+ break;
+ case 0x80000021:
+ entry->ebx = entry->ecx = entry->edx = 0;
+ /*
+ * Pass down these bits:
+ * EAX 0 NNDBP, Processor ignores nested data breakpoints
+ * EAX 2 LAS, LFENCE always serializing
+ * EAX 6 NSCB, Null selector clear base
+ *
+ * Other defined bits are for MSRs that KVM does not expose:
+ * EAX 3 SPCL, SMM page configuration lock
+ * EAX 13 PCMSR, Prefetch control MSR
+ */
+ entry->eax &= BIT(0) | BIT(2) | BIT(6);
+ if (static_cpu_has(X86_FEATURE_LFENCE_RDTSC))
+ entry->eax |= BIT(2);
+ if (!static_cpu_has_bug(X86_BUG_NULL_SEG))
+ entry->eax |= BIT(6);
+ break;
/*Add support for Centaur's CPUID instruction*/
case 0xC0000000:
/*Just support up to 0xC0000004 now*/
@@ -1216,8 +1291,7 @@ int kvm_dev_ioctl_get_cpuid(struct kvm_cpuid2 *cpuid,
if (sanity_check_entries(entries, cpuid->nent, type))
return -EINVAL;
- array.entries = vzalloc(array_size(sizeof(struct kvm_cpuid_entry2),
- cpuid->nent));
+ array.entries = kvcalloc(sizeof(struct kvm_cpuid_entry2), cpuid->nent, GFP_KERNEL);
if (!array.entries)
return -ENOMEM;
@@ -1235,7 +1309,7 @@ int kvm_dev_ioctl_get_cpuid(struct kvm_cpuid2 *cpuid,
r = -EFAULT;
out_free:
- vfree(array.entries);
+ kvfree(array.entries);
return r;
}
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index 5719d8cfdbd9..7ba4ec77feeb 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -429,8 +429,23 @@ static int fastop(struct x86_emulate_ctxt *ctxt, fastop_t fop);
FOP_END
/* Special case for SETcc - 1 instruction per cc */
+
+/*
+ * Depending on .config the SETcc functions look like:
+ *
+ * SETcc %al [3 bytes]
+ * RET [1 byte]
+ * INT3 [1 byte; CONFIG_SLS]
+ *
+ * Which gives possible sizes 4 or 5. When rounded up to the
+ * next power-of-two alignment they become 4 or 8.
+ */
+#define SETCC_LENGTH (4 + IS_ENABLED(CONFIG_SLS))
+#define SETCC_ALIGN (4 << IS_ENABLED(CONFIG_SLS))
+static_assert(SETCC_LENGTH <= SETCC_ALIGN);
+
#define FOP_SETCC(op) \
- ".align 4 \n\t" \
+ ".align " __stringify(SETCC_ALIGN) " \n\t" \
".type " #op ", @function \n\t" \
#op ": \n\t" \
#op " %al \n\t" \
@@ -665,7 +680,7 @@ static inline u8 ctxt_virt_addr_bits(struct x86_emulate_ctxt *ctxt)
static inline bool emul_is_noncanonical_address(u64 la,
struct x86_emulate_ctxt *ctxt)
{
- return get_canonical(la, ctxt_virt_addr_bits(ctxt)) != la;
+ return !__is_canonical_address(la, ctxt_virt_addr_bits(ctxt));
}
/*
@@ -715,7 +730,7 @@ static __always_inline int __linearize(struct x86_emulate_ctxt *ctxt,
case X86EMUL_MODE_PROT64:
*linear = la;
va_bits = ctxt_virt_addr_bits(ctxt);
- if (get_canonical(la, va_bits) != la)
+ if (!__is_canonical_address(la, va_bits))
goto bad;
*max_size = min_t(u64, ~0u, (1ull << va_bits) - la);
@@ -1047,7 +1062,7 @@ static int em_bsr_c(struct x86_emulate_ctxt *ctxt)
static __always_inline u8 test_cc(unsigned int condition, unsigned long flags)
{
u8 rc;
- void (*fop)(void) = (void *)em_setcc + 4 * (condition & 0xf);
+ void (*fop)(void) = (void *)em_setcc + SETCC_ALIGN * (condition & 0xf);
flags = (flags & EFLAGS_MASK) | X86_EFLAGS_IF;
asm("push %[flags]; popf; " CALL_NOSPEC
@@ -1608,11 +1623,6 @@ static int __load_segment_descriptor(struct x86_emulate_ctxt *ctxt,
goto exception;
}
- if (!seg_desc.p) {
- err_vec = (seg == VCPU_SREG_SS) ? SS_VECTOR : NP_VECTOR;
- goto exception;
- }
-
dpl = seg_desc.dpl;
switch (seg) {
@@ -1628,14 +1638,34 @@ static int __load_segment_descriptor(struct x86_emulate_ctxt *ctxt,
if (!(seg_desc.type & 8))
goto exception;
- if (seg_desc.type & 4) {
- /* conforming */
- if (dpl > cpl)
- goto exception;
- } else {
- /* nonconforming */
- if (rpl > cpl || dpl != cpl)
+ if (transfer == X86_TRANSFER_RET) {
+ /* RET can never return to an inner privilege level. */
+ if (rpl < cpl)
goto exception;
+ /* Outer-privilege level return is not implemented */
+ if (rpl > cpl)
+ return X86EMUL_UNHANDLEABLE;
+ }
+ if (transfer == X86_TRANSFER_RET || transfer == X86_TRANSFER_TASK_SWITCH) {
+ if (seg_desc.type & 4) {
+ /* conforming */
+ if (dpl > rpl)
+ goto exception;
+ } else {
+ /* nonconforming */
+ if (dpl != rpl)
+ goto exception;
+ }
+ } else { /* X86_TRANSFER_CALL_JMP */
+ if (seg_desc.type & 4) {
+ /* conforming */
+ if (dpl > cpl)
+ goto exception;
+ } else {
+ /* nonconforming */
+ if (rpl > cpl || dpl != cpl)
+ goto exception;
+ }
}
/* in long-mode d/b must be clear if l is set */
if (seg_desc.d && seg_desc.l) {
@@ -1652,6 +1682,10 @@ static int __load_segment_descriptor(struct x86_emulate_ctxt *ctxt,
case VCPU_SREG_TR:
if (seg_desc.s || (seg_desc.type != 1 && seg_desc.type != 9))
goto exception;
+ if (!seg_desc.p) {
+ err_vec = NP_VECTOR;
+ goto exception;
+ }
old_desc = seg_desc;
seg_desc.type |= 2; /* busy */
ret = ctxt->ops->cmpxchg_emulated(ctxt, desc_addr, &old_desc, &seg_desc,
@@ -1676,6 +1710,11 @@ static int __load_segment_descriptor(struct x86_emulate_ctxt *ctxt,
break;
}
+ if (!seg_desc.p) {
+ err_vec = (seg == VCPU_SREG_SS) ? SS_VECTOR : NP_VECTOR;
+ goto exception;
+ }
+
if (seg_desc.s) {
/* mark segment as accessed */
if (!(seg_desc.type & 1)) {
@@ -2201,9 +2240,6 @@ static int em_ret_far(struct x86_emulate_ctxt *ctxt)
rc = emulate_pop(ctxt, &cs, ctxt->op_bytes);
if (rc != X86EMUL_CONTINUE)
return rc;
- /* Outer-privilege level return is not implemented */
- if (ctxt->mode >= X86EMUL_MODE_PROT16 && (cs & 3) > cpl)
- return X86EMUL_UNHANDLEABLE;
rc = __load_segment_descriptor(ctxt, (u16)cs, VCPU_SREG_CS, cpl,
X86_TRANSFER_RET,
&new_desc);
@@ -2600,8 +2636,7 @@ emulate_shutdown:
}
static void
-setup_syscalls_segments(struct x86_emulate_ctxt *ctxt,
- struct desc_struct *cs, struct desc_struct *ss)
+setup_syscalls_segments(struct desc_struct *cs, struct desc_struct *ss)
{
cs->l = 0; /* will be adjusted later */
set_desc_base(cs, 0); /* flat segment */
@@ -2690,7 +2725,7 @@ static int em_syscall(struct x86_emulate_ctxt *ctxt)
if (!(efer & EFER_SCE))
return emulate_ud(ctxt);
- setup_syscalls_segments(ctxt, &cs, &ss);
+ setup_syscalls_segments(&cs, &ss);
ops->get_msr(ctxt, MSR_STAR, &msr_data);
msr_data >>= 32;
cs_sel = (u16)(msr_data & 0xfffc);
@@ -2758,7 +2793,7 @@ static int em_sysenter(struct x86_emulate_ctxt *ctxt)
if ((msr_data & 0xfffc) == 0x0)
return emulate_gp(ctxt, 0);
- setup_syscalls_segments(ctxt, &cs, &ss);
+ setup_syscalls_segments(&cs, &ss);
ctxt->eflags &= ~(X86_EFLAGS_VM | X86_EFLAGS_IF);
cs_sel = (u16)msr_data & ~SEGMENT_RPL_MASK;
ss_sel = cs_sel + 8;
@@ -2795,7 +2830,7 @@ static int em_sysexit(struct x86_emulate_ctxt *ctxt)
ctxt->mode == X86EMUL_MODE_VM86)
return emulate_gp(ctxt, 0);
- setup_syscalls_segments(ctxt, &cs, &ss);
+ setup_syscalls_segments(&cs, &ss);
if ((ctxt->rex_prefix & 0x8) != 0x0)
usermode = X86EMUL_MODE_PROT64;
@@ -3013,8 +3048,7 @@ static int load_state_from_tss16(struct x86_emulate_ctxt *ctxt,
return X86EMUL_CONTINUE;
}
-static int task_switch_16(struct x86_emulate_ctxt *ctxt,
- u16 tss_selector, u16 old_tss_sel,
+static int task_switch_16(struct x86_emulate_ctxt *ctxt, u16 old_tss_sel,
ulong old_tss_base, struct desc_struct *new_desc)
{
struct tss_segment_16 tss_seg;
@@ -3152,8 +3186,7 @@ static int load_state_from_tss32(struct x86_emulate_ctxt *ctxt,
return ret;
}
-static int task_switch_32(struct x86_emulate_ctxt *ctxt,
- u16 tss_selector, u16 old_tss_sel,
+static int task_switch_32(struct x86_emulate_ctxt *ctxt, u16 old_tss_sel,
ulong old_tss_base, struct desc_struct *new_desc)
{
struct tss_segment_32 tss_seg;
@@ -3261,10 +3294,9 @@ static int emulator_do_task_switch(struct x86_emulate_ctxt *ctxt,
old_tss_sel = 0xffff;
if (next_tss_desc.type & 8)
- ret = task_switch_32(ctxt, tss_selector, old_tss_sel,
- old_tss_base, &next_tss_desc);
+ ret = task_switch_32(ctxt, old_tss_sel, old_tss_base, &next_tss_desc);
else
- ret = task_switch_16(ctxt, tss_selector, old_tss_sel,
+ ret = task_switch_16(ctxt, old_tss_sel,
old_tss_base, &next_tss_desc);
if (ret != X86EMUL_CONTINUE)
return ret;
@@ -5380,8 +5412,13 @@ static int fastop(struct x86_emulate_ctxt *ctxt, fastop_t fop)
void init_decode_cache(struct x86_emulate_ctxt *ctxt)
{
- memset(&ctxt->rip_relative, 0,
- (void *)&ctxt->modrm - (void *)&ctxt->rip_relative);
+ /* Clear fields that are set conditionally but read without a guard. */
+ ctxt->rip_relative = false;
+ ctxt->rex_prefix = 0;
+ ctxt->lock_prefix = 0;
+ ctxt->rep_prefix = 0;
+ ctxt->regs_valid = 0;
+ ctxt->regs_dirty = 0;
ctxt->io_read.pos = 0;
ctxt->io_read.end = 0;
diff --git a/arch/x86/kvm/hyperv.c b/arch/x86/kvm/hyperv.c
index 6e38a7d22e97..a32f54ab84a2 100644
--- a/arch/x86/kvm/hyperv.c
+++ b/arch/x86/kvm/hyperv.c
@@ -112,6 +112,9 @@ static void synic_update_vector(struct kvm_vcpu_hv_synic *synic,
if (!!auto_eoi_old == !!auto_eoi_new)
return;
+ if (!enable_apicv)
+ return;
+
down_write(&vcpu->kvm->arch.apicv_update_lock);
if (auto_eoi_new)
@@ -1710,32 +1713,47 @@ int kvm_hv_get_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata, bool host)
return kvm_hv_get_msr(vcpu, msr, pdata, host);
}
-static __always_inline unsigned long *sparse_set_to_vcpu_mask(
- struct kvm *kvm, u64 *sparse_banks, u64 valid_bank_mask,
- u64 *vp_bitmap, unsigned long *vcpu_bitmap)
+static void sparse_set_to_vcpu_mask(struct kvm *kvm, u64 *sparse_banks,
+ u64 valid_bank_mask, unsigned long *vcpu_mask)
{
struct kvm_hv *hv = to_kvm_hv(kvm);
+ bool has_mismatch = atomic_read(&hv->num_mismatched_vp_indexes);
+ u64 vp_bitmap[KVM_HV_MAX_SPARSE_VCPU_SET_BITS];
struct kvm_vcpu *vcpu;
int bank, sbank = 0;
unsigned long i;
+ u64 *bitmap;
+
+ BUILD_BUG_ON(sizeof(vp_bitmap) >
+ sizeof(*vcpu_mask) * BITS_TO_LONGS(KVM_MAX_VCPUS));
+
+ /*
+ * If vp_index == vcpu_idx for all vCPUs, fill vcpu_mask directly, else
+ * fill a temporary buffer and manually test each vCPU's VP index.
+ */
+ if (likely(!has_mismatch))
+ bitmap = (u64 *)vcpu_mask;
+ else
+ bitmap = vp_bitmap;
- memset(vp_bitmap, 0,
- KVM_HV_MAX_SPARSE_VCPU_SET_BITS * sizeof(*vp_bitmap));
+ /*
+ * Each set of 64 VPs is packed into sparse_banks, with valid_bank_mask
+ * having a '1' for each bank that exists in sparse_banks. Sets must
+ * be in ascending order, i.e. bank0..bankN.
+ */
+ memset(bitmap, 0, sizeof(vp_bitmap));
for_each_set_bit(bank, (unsigned long *)&valid_bank_mask,
KVM_HV_MAX_SPARSE_VCPU_SET_BITS)
- vp_bitmap[bank] = sparse_banks[sbank++];
+ bitmap[bank] = sparse_banks[sbank++];
- if (likely(!atomic_read(&hv->num_mismatched_vp_indexes))) {
- /* for all vcpus vp_index == vcpu_idx */
- return (unsigned long *)vp_bitmap;
- }
+ if (likely(!has_mismatch))
+ return;
- bitmap_zero(vcpu_bitmap, KVM_MAX_VCPUS);
+ bitmap_zero(vcpu_mask, KVM_MAX_VCPUS);
kvm_for_each_vcpu(i, vcpu, kvm) {
if (test_bit(kvm_hv_get_vpindex(vcpu), (unsigned long *)vp_bitmap))
- __set_bit(i, vcpu_bitmap);
+ __set_bit(i, vcpu_mask);
}
- return vcpu_bitmap;
}
struct kvm_hv_hcall {
@@ -1743,6 +1761,7 @@ struct kvm_hv_hcall {
u64 ingpa;
u64 outgpa;
u16 code;
+ u16 var_cnt;
u16 rep_cnt;
u16 rep_idx;
bool fast;
@@ -1750,22 +1769,60 @@ struct kvm_hv_hcall {
sse128_t xmm[HV_HYPERCALL_MAX_XMM_REGISTERS];
};
-static u64 kvm_hv_flush_tlb(struct kvm_vcpu *vcpu, struct kvm_hv_hcall *hc, bool ex)
+static u64 kvm_get_sparse_vp_set(struct kvm *kvm, struct kvm_hv_hcall *hc,
+ int consumed_xmm_halves,
+ u64 *sparse_banks, gpa_t offset)
{
+ u16 var_cnt;
int i;
- gpa_t gpa;
+
+ if (hc->var_cnt > 64)
+ return -EINVAL;
+
+ /* Ignore banks that cannot possibly contain a legal VP index. */
+ var_cnt = min_t(u16, hc->var_cnt, KVM_HV_MAX_SPARSE_VCPU_SET_BITS);
+
+ if (hc->fast) {
+ /*
+ * Each XMM holds two sparse banks, but do not count halves that
+ * have already been consumed for hypercall parameters.
+ */
+ if (hc->var_cnt > 2 * HV_HYPERCALL_MAX_XMM_REGISTERS - consumed_xmm_halves)
+ return HV_STATUS_INVALID_HYPERCALL_INPUT;
+ for (i = 0; i < var_cnt; i++) {
+ int j = i + consumed_xmm_halves;
+ if (j % 2)
+ sparse_banks[i] = sse128_hi(hc->xmm[j / 2]);
+ else
+ sparse_banks[i] = sse128_lo(hc->xmm[j / 2]);
+ }
+ return 0;
+ }
+
+ return kvm_read_guest(kvm, hc->ingpa + offset, sparse_banks,
+ var_cnt * sizeof(*sparse_banks));
+}
+
+static u64 kvm_hv_flush_tlb(struct kvm_vcpu *vcpu, struct kvm_hv_hcall *hc)
+{
struct kvm *kvm = vcpu->kvm;
struct hv_tlb_flush_ex flush_ex;
struct hv_tlb_flush flush;
- u64 vp_bitmap[KVM_HV_MAX_SPARSE_VCPU_SET_BITS];
- DECLARE_BITMAP(vcpu_bitmap, KVM_MAX_VCPUS);
- unsigned long *vcpu_mask;
+ DECLARE_BITMAP(vcpu_mask, KVM_MAX_VCPUS);
u64 valid_bank_mask;
- u64 sparse_banks[64];
- int sparse_banks_len;
+ u64 sparse_banks[KVM_HV_MAX_SPARSE_VCPU_SET_BITS];
bool all_cpus;
- if (!ex) {
+ /*
+ * The Hyper-V TLFS doesn't allow more than 64 sparse banks, e.g. the
+ * valid mask is a u64. Fail the build if KVM's max allowed number of
+ * vCPUs (>4096) would exceed this limit, KVM will additional changes
+ * for Hyper-V support to avoid setting the guest up to fail.
+ */
+ BUILD_BUG_ON(KVM_HV_MAX_SPARSE_VCPU_SET_BITS > 64);
+
+ if (hc->code == HVCALL_FLUSH_VIRTUAL_ADDRESS_LIST ||
+ hc->code == HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE) {
if (hc->fast) {
flush.address_space = hc->ingpa;
flush.flags = hc->outgpa;
@@ -1812,30 +1869,22 @@ static u64 kvm_hv_flush_tlb(struct kvm_vcpu *vcpu, struct kvm_hv_hcall *hc, bool
all_cpus = flush_ex.hv_vp_set.format !=
HV_GENERIC_SET_SPARSE_4K;
- sparse_banks_len = bitmap_weight((unsigned long *)&valid_bank_mask, 64);
+ if (hc->var_cnt != bitmap_weight((unsigned long *)&valid_bank_mask, 64))
+ return HV_STATUS_INVALID_HYPERCALL_INPUT;
- if (!sparse_banks_len && !all_cpus)
+ if (all_cpus)
+ goto do_flush;
+
+ if (!hc->var_cnt)
goto ret_success;
- if (!all_cpus) {
- if (hc->fast) {
- if (sparse_banks_len > HV_HYPERCALL_MAX_XMM_REGISTERS - 1)
- return HV_STATUS_INVALID_HYPERCALL_INPUT;
- for (i = 0; i < sparse_banks_len; i += 2) {
- sparse_banks[i] = sse128_lo(hc->xmm[i / 2 + 1]);
- sparse_banks[i + 1] = sse128_hi(hc->xmm[i / 2 + 1]);
- }
- } else {
- gpa = hc->ingpa + offsetof(struct hv_tlb_flush_ex,
- hv_vp_set.bank_contents);
- if (unlikely(kvm_read_guest(kvm, gpa, sparse_banks,
- sparse_banks_len *
- sizeof(sparse_banks[0]))))
- return HV_STATUS_INVALID_HYPERCALL_INPUT;
- }
- }
+ if (kvm_get_sparse_vp_set(kvm, hc, 2, sparse_banks,
+ offsetof(struct hv_tlb_flush_ex,
+ hv_vp_set.bank_contents)))
+ return HV_STATUS_INVALID_HYPERCALL_INPUT;
}
+do_flush:
/*
* vcpu->arch.cr3 may not be up-to-date for running vCPUs so we can't
* analyze it here, flush TLB regardless of the specified address space.
@@ -1843,11 +1892,9 @@ static u64 kvm_hv_flush_tlb(struct kvm_vcpu *vcpu, struct kvm_hv_hcall *hc, bool
if (all_cpus) {
kvm_make_all_cpus_request(kvm, KVM_REQ_TLB_FLUSH_GUEST);
} else {
- vcpu_mask = sparse_set_to_vcpu_mask(kvm, sparse_banks, valid_bank_mask,
- vp_bitmap, vcpu_bitmap);
+ sparse_set_to_vcpu_mask(kvm, sparse_banks, valid_bank_mask, vcpu_mask);
- kvm_make_vcpus_request_mask(kvm, KVM_REQ_TLB_FLUSH_GUEST,
- vcpu_mask);
+ kvm_make_vcpus_request_mask(kvm, KVM_REQ_TLB_FLUSH_GUEST, vcpu_mask);
}
ret_success:
@@ -1875,21 +1922,18 @@ static void kvm_send_ipi_to_many(struct kvm *kvm, u32 vector,
}
}
-static u64 kvm_hv_send_ipi(struct kvm_vcpu *vcpu, struct kvm_hv_hcall *hc, bool ex)
+static u64 kvm_hv_send_ipi(struct kvm_vcpu *vcpu, struct kvm_hv_hcall *hc)
{
struct kvm *kvm = vcpu->kvm;
struct hv_send_ipi_ex send_ipi_ex;
struct hv_send_ipi send_ipi;
- u64 vp_bitmap[KVM_HV_MAX_SPARSE_VCPU_SET_BITS];
- DECLARE_BITMAP(vcpu_bitmap, KVM_MAX_VCPUS);
- unsigned long *vcpu_mask;
+ DECLARE_BITMAP(vcpu_mask, KVM_MAX_VCPUS);
unsigned long valid_bank_mask;
- u64 sparse_banks[64];
- int sparse_banks_len;
+ u64 sparse_banks[KVM_HV_MAX_SPARSE_VCPU_SET_BITS];
u32 vector;
bool all_cpus;
- if (!ex) {
+ if (hc->code == HVCALL_SEND_IPI) {
if (!hc->fast) {
if (unlikely(kvm_read_guest(kvm, hc->ingpa, &send_ipi,
sizeof(send_ipi))))
@@ -1908,9 +1952,15 @@ static u64 kvm_hv_send_ipi(struct kvm_vcpu *vcpu, struct kvm_hv_hcall *hc, bool
trace_kvm_hv_send_ipi(vector, sparse_banks[0]);
} else {
- if (unlikely(kvm_read_guest(kvm, hc->ingpa, &send_ipi_ex,
- sizeof(send_ipi_ex))))
- return HV_STATUS_INVALID_HYPERCALL_INPUT;
+ if (!hc->fast) {
+ if (unlikely(kvm_read_guest(kvm, hc->ingpa, &send_ipi_ex,
+ sizeof(send_ipi_ex))))
+ return HV_STATUS_INVALID_HYPERCALL_INPUT;
+ } else {
+ send_ipi_ex.vector = (u32)hc->ingpa;
+ send_ipi_ex.vp_set.format = hc->outgpa;
+ send_ipi_ex.vp_set.valid_bank_mask = sse128_lo(hc->xmm[0]);
+ }
trace_kvm_hv_send_ipi_ex(send_ipi_ex.vector,
send_ipi_ex.vp_set.format,
@@ -1918,22 +1968,20 @@ static u64 kvm_hv_send_ipi(struct kvm_vcpu *vcpu, struct kvm_hv_hcall *hc, bool
vector = send_ipi_ex.vector;
valid_bank_mask = send_ipi_ex.vp_set.valid_bank_mask;
- sparse_banks_len = bitmap_weight(&valid_bank_mask, 64) *
- sizeof(sparse_banks[0]);
-
all_cpus = send_ipi_ex.vp_set.format == HV_GENERIC_SET_ALL;
+ if (hc->var_cnt != bitmap_weight(&valid_bank_mask, 64))
+ return HV_STATUS_INVALID_HYPERCALL_INPUT;
+
if (all_cpus)
goto check_and_send_ipi;
- if (!sparse_banks_len)
+ if (!hc->var_cnt)
goto ret_success;
- if (kvm_read_guest(kvm,
- hc->ingpa + offsetof(struct hv_send_ipi_ex,
- vp_set.bank_contents),
- sparse_banks,
- sparse_banks_len))
+ if (kvm_get_sparse_vp_set(kvm, hc, 1, sparse_banks,
+ offsetof(struct hv_send_ipi_ex,
+ vp_set.bank_contents)))
return HV_STATUS_INVALID_HYPERCALL_INPUT;
}
@@ -1941,11 +1989,13 @@ check_and_send_ipi:
if ((vector < HV_IPI_LOW_VECTOR) || (vector > HV_IPI_HIGH_VECTOR))
return HV_STATUS_INVALID_HYPERCALL_INPUT;
- vcpu_mask = all_cpus ? NULL :
- sparse_set_to_vcpu_mask(kvm, sparse_banks, valid_bank_mask,
- vp_bitmap, vcpu_bitmap);
+ if (all_cpus) {
+ kvm_send_ipi_to_many(kvm, vector, NULL);
+ } else {
+ sparse_set_to_vcpu_mask(kvm, sparse_banks, valid_bank_mask, vcpu_mask);
- kvm_send_ipi_to_many(kvm, vector, vcpu_mask);
+ kvm_send_ipi_to_many(kvm, vector, vcpu_mask);
+ }
ret_success:
return HV_STATUS_SUCCESS;
@@ -2017,11 +2067,6 @@ int kvm_hv_set_enforce_cpuid(struct kvm_vcpu *vcpu, bool enforce)
return ret;
}
-bool kvm_hv_hypercall_enabled(struct kvm_vcpu *vcpu)
-{
- return vcpu->arch.hyperv_enabled && to_kvm_hv(vcpu->kvm)->hv_guest_os_id;
-}
-
static void kvm_hv_hypercall_set_result(struct kvm_vcpu *vcpu, u64 result)
{
bool longmode;
@@ -2096,6 +2141,7 @@ static bool is_xmm_fast_hypercall(struct kvm_hv_hcall *hc)
case HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE:
case HVCALL_FLUSH_VIRTUAL_ADDRESS_LIST_EX:
case HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE_EX:
+ case HVCALL_SEND_IPI_EX:
return true;
}
@@ -2191,19 +2237,25 @@ int kvm_hv_hypercall(struct kvm_vcpu *vcpu)
}
hc.code = hc.param & 0xffff;
+ hc.var_cnt = (hc.param & HV_HYPERCALL_VARHEAD_MASK) >> HV_HYPERCALL_VARHEAD_OFFSET;
hc.fast = !!(hc.param & HV_HYPERCALL_FAST_BIT);
hc.rep_cnt = (hc.param >> HV_HYPERCALL_REP_COMP_OFFSET) & 0xfff;
hc.rep_idx = (hc.param >> HV_HYPERCALL_REP_START_OFFSET) & 0xfff;
hc.rep = !!(hc.rep_cnt || hc.rep_idx);
- trace_kvm_hv_hypercall(hc.code, hc.fast, hc.rep_cnt, hc.rep_idx,
- hc.ingpa, hc.outgpa);
+ trace_kvm_hv_hypercall(hc.code, hc.fast, hc.var_cnt, hc.rep_cnt,
+ hc.rep_idx, hc.ingpa, hc.outgpa);
if (unlikely(!hv_check_hypercall_access(hv_vcpu, hc.code))) {
ret = HV_STATUS_ACCESS_DENIED;
goto hypercall_complete;
}
+ if (unlikely(hc.param & HV_HYPERCALL_RSVD_MASK)) {
+ ret = HV_STATUS_INVALID_HYPERCALL_INPUT;
+ goto hypercall_complete;
+ }
+
if (hc.fast && is_xmm_fast_hypercall(&hc)) {
if (unlikely(hv_vcpu->enforce_cpuid &&
!(hv_vcpu->cpuid_cache.features_edx &
@@ -2217,14 +2269,14 @@ int kvm_hv_hypercall(struct kvm_vcpu *vcpu)
switch (hc.code) {
case HVCALL_NOTIFY_LONG_SPIN_WAIT:
- if (unlikely(hc.rep)) {
+ if (unlikely(hc.rep || hc.var_cnt)) {
ret = HV_STATUS_INVALID_HYPERCALL_INPUT;
break;
}
kvm_vcpu_on_spin(vcpu, true);
break;
case HVCALL_SIGNAL_EVENT:
- if (unlikely(hc.rep)) {
+ if (unlikely(hc.rep || hc.var_cnt)) {
ret = HV_STATUS_INVALID_HYPERCALL_INPUT;
break;
}
@@ -2234,7 +2286,7 @@ int kvm_hv_hypercall(struct kvm_vcpu *vcpu)
fallthrough; /* maybe userspace knows this conn_id */
case HVCALL_POST_MESSAGE:
/* don't bother userspace if it has no way to handle it */
- if (unlikely(hc.rep || !to_hv_synic(vcpu)->active)) {
+ if (unlikely(hc.rep || hc.var_cnt || !to_hv_synic(vcpu)->active)) {
ret = HV_STATUS_INVALID_HYPERCALL_INPUT;
break;
}
@@ -2247,46 +2299,43 @@ int kvm_hv_hypercall(struct kvm_vcpu *vcpu)
kvm_hv_hypercall_complete_userspace;
return 0;
case HVCALL_FLUSH_VIRTUAL_ADDRESS_LIST:
- if (unlikely(!hc.rep_cnt || hc.rep_idx)) {
+ if (unlikely(hc.var_cnt)) {
ret = HV_STATUS_INVALID_HYPERCALL_INPUT;
break;
}
- ret = kvm_hv_flush_tlb(vcpu, &hc, false);
- break;
- case HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE:
- if (unlikely(hc.rep)) {
+ fallthrough;
+ case HVCALL_FLUSH_VIRTUAL_ADDRESS_LIST_EX:
+ if (unlikely(!hc.rep_cnt || hc.rep_idx)) {
ret = HV_STATUS_INVALID_HYPERCALL_INPUT;
break;
}
- ret = kvm_hv_flush_tlb(vcpu, &hc, false);
+ ret = kvm_hv_flush_tlb(vcpu, &hc);
break;
- case HVCALL_FLUSH_VIRTUAL_ADDRESS_LIST_EX:
- if (unlikely(!hc.rep_cnt || hc.rep_idx)) {
+ case HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE:
+ if (unlikely(hc.var_cnt)) {
ret = HV_STATUS_INVALID_HYPERCALL_INPUT;
break;
}
- ret = kvm_hv_flush_tlb(vcpu, &hc, true);
- break;
+ fallthrough;
case HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE_EX:
if (unlikely(hc.rep)) {
ret = HV_STATUS_INVALID_HYPERCALL_INPUT;
break;
}
- ret = kvm_hv_flush_tlb(vcpu, &hc, true);
+ ret = kvm_hv_flush_tlb(vcpu, &hc);
break;
case HVCALL_SEND_IPI:
- if (unlikely(hc.rep)) {
+ if (unlikely(hc.var_cnt)) {
ret = HV_STATUS_INVALID_HYPERCALL_INPUT;
break;
}
- ret = kvm_hv_send_ipi(vcpu, &hc, false);
- break;
+ fallthrough;
case HVCALL_SEND_IPI_EX:
- if (unlikely(hc.fast || hc.rep)) {
+ if (unlikely(hc.rep)) {
ret = HV_STATUS_INVALID_HYPERCALL_INPUT;
break;
}
- ret = kvm_hv_send_ipi(vcpu, &hc, true);
+ ret = kvm_hv_send_ipi(vcpu, &hc);
break;
case HVCALL_POST_DEBUG_DATA:
case HVCALL_RETRIEVE_DEBUG_DATA:
@@ -2417,10 +2466,6 @@ int kvm_get_hv_cpuid(struct kvm_vcpu *vcpu, struct kvm_cpuid2 *cpuid,
if (kvm_x86_ops.nested_ops->get_evmcs_version)
evmcs_ver = kvm_x86_ops.nested_ops->get_evmcs_version(vcpu);
- /* Skip NESTED_FEATURES if eVMCS is not supported */
- if (!evmcs_ver)
- --nent;
-
if (cpuid->nent < nent)
return -E2BIG;
@@ -2520,8 +2565,7 @@ int kvm_get_hv_cpuid(struct kvm_vcpu *vcpu, struct kvm_cpuid2 *cpuid,
case HYPERV_CPUID_NESTED_FEATURES:
ent->eax = evmcs_ver;
- if (evmcs_ver)
- ent->eax |= HV_X64_NESTED_MSR_BITMAP;
+ ent->eax |= HV_X64_NESTED_MSR_BITMAP;
break;
diff --git a/arch/x86/kvm/hyperv.h b/arch/x86/kvm/hyperv.h
index ed1c4e546d04..e19c00ee9ab3 100644
--- a/arch/x86/kvm/hyperv.h
+++ b/arch/x86/kvm/hyperv.h
@@ -89,7 +89,11 @@ static inline u32 kvm_hv_get_vpindex(struct kvm_vcpu *vcpu)
int kvm_hv_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data, bool host);
int kvm_hv_get_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata, bool host);
-bool kvm_hv_hypercall_enabled(struct kvm_vcpu *vcpu);
+static inline bool kvm_hv_hypercall_enabled(struct kvm_vcpu *vcpu)
+{
+ return vcpu->arch.hyperv_enabled && to_kvm_hv(vcpu->kvm)->hv_guest_os_id;
+}
+
int kvm_hv_hypercall(struct kvm_vcpu *vcpu);
void kvm_hv_irq_routing_update(struct kvm *kvm);
diff --git a/arch/x86/kvm/i8259.c b/arch/x86/kvm/i8259.c
index 814064d06016..be99dc86293d 100644
--- a/arch/x86/kvm/i8259.c
+++ b/arch/x86/kvm/i8259.c
@@ -437,13 +437,13 @@ static u32 pic_ioport_read(void *opaque, u32 addr)
return ret;
}
-static void elcr_ioport_write(void *opaque, u32 addr, u32 val)
+static void elcr_ioport_write(void *opaque, u32 val)
{
struct kvm_kpic_state *s = opaque;
s->elcr = val & s->elcr_mask;
}
-static u32 elcr_ioport_read(void *opaque, u32 addr1)
+static u32 elcr_ioport_read(void *opaque)
{
struct kvm_kpic_state *s = opaque;
return s->elcr;
@@ -474,7 +474,7 @@ static int picdev_write(struct kvm_pic *s,
case 0x4d0:
case 0x4d1:
pic_lock(s);
- elcr_ioport_write(&s->pics[addr & 1], addr, data);
+ elcr_ioport_write(&s->pics[addr & 1], data);
pic_unlock(s);
break;
default:
@@ -505,7 +505,7 @@ static int picdev_read(struct kvm_pic *s,
case 0x4d0:
case 0x4d1:
pic_lock(s);
- *data = elcr_ioport_read(&s->pics[addr & 1], addr);
+ *data = elcr_ioport_read(&s->pics[addr & 1]);
pic_unlock(s);
break;
default:
diff --git a/arch/x86/kvm/ioapic.c b/arch/x86/kvm/ioapic.c
index decfa36b7891..765943d7cfa5 100644
--- a/arch/x86/kvm/ioapic.c
+++ b/arch/x86/kvm/ioapic.c
@@ -54,9 +54,7 @@ static void kvm_ioapic_update_eoi_one(struct kvm_vcpu *vcpu,
int trigger_mode,
int pin);
-static unsigned long ioapic_read_indirect(struct kvm_ioapic *ioapic,
- unsigned long addr,
- unsigned long length)
+static unsigned long ioapic_read_indirect(struct kvm_ioapic *ioapic)
{
unsigned long result = 0;
@@ -593,7 +591,7 @@ static int ioapic_mmio_read(struct kvm_vcpu *vcpu, struct kvm_io_device *this,
break;
case IOAPIC_REG_WINDOW:
- result = ioapic_read_indirect(ioapic, addr, len);
+ result = ioapic_read_indirect(ioapic);
break;
default:
diff --git a/arch/x86/kvm/kvm_emulate.h b/arch/x86/kvm/kvm_emulate.h
index 39eded2426ff..840ddb4a9302 100644
--- a/arch/x86/kvm/kvm_emulate.h
+++ b/arch/x86/kvm/kvm_emulate.h
@@ -336,11 +336,7 @@ struct x86_emulate_ctxt {
fastop_t fop;
};
int (*check_perm)(struct x86_emulate_ctxt *ctxt);
- /*
- * The following six fields are cleared together,
- * the rest are initialized unconditionally in x86_decode_insn
- * or elsewhere
- */
+
bool rip_relative;
u8 rex_prefix;
u8 lock_prefix;
diff --git a/arch/x86/kvm/kvm_onhyperv.c b/arch/x86/kvm/kvm_onhyperv.c
index b469f45e3fe4..ee4f696a0782 100644
--- a/arch/x86/kvm/kvm_onhyperv.c
+++ b/arch/x86/kvm/kvm_onhyperv.c
@@ -92,3 +92,17 @@ int hv_remote_flush_tlb(struct kvm *kvm)
return hv_remote_flush_tlb_with_range(kvm, NULL);
}
EXPORT_SYMBOL_GPL(hv_remote_flush_tlb);
+
+void hv_track_root_tdp(struct kvm_vcpu *vcpu, hpa_t root_tdp)
+{
+ struct kvm_arch *kvm_arch = &vcpu->kvm->arch;
+
+ if (kvm_x86_ops.tlb_remote_flush == hv_remote_flush_tlb) {
+ spin_lock(&kvm_arch->hv_root_tdp_lock);
+ vcpu->arch.hv_root_tdp = root_tdp;
+ if (root_tdp != kvm_arch->hv_root_tdp)
+ kvm_arch->hv_root_tdp = INVALID_PAGE;
+ spin_unlock(&kvm_arch->hv_root_tdp_lock);
+ }
+}
+EXPORT_SYMBOL_GPL(hv_track_root_tdp);
diff --git a/arch/x86/kvm/kvm_onhyperv.h b/arch/x86/kvm/kvm_onhyperv.h
index 1c67abf2eba9..287e98ef9df3 100644
--- a/arch/x86/kvm/kvm_onhyperv.h
+++ b/arch/x86/kvm/kvm_onhyperv.h
@@ -10,19 +10,7 @@
int hv_remote_flush_tlb_with_range(struct kvm *kvm,
struct kvm_tlb_range *range);
int hv_remote_flush_tlb(struct kvm *kvm);
-
-static inline void hv_track_root_tdp(struct kvm_vcpu *vcpu, hpa_t root_tdp)
-{
- struct kvm_arch *kvm_arch = &vcpu->kvm->arch;
-
- if (kvm_x86_ops.tlb_remote_flush == hv_remote_flush_tlb) {
- spin_lock(&kvm_arch->hv_root_tdp_lock);
- vcpu->arch.hv_root_tdp = root_tdp;
- if (root_tdp != kvm_arch->hv_root_tdp)
- kvm_arch->hv_root_tdp = INVALID_PAGE;
- spin_unlock(&kvm_arch->hv_root_tdp_lock);
- }
-}
+void hv_track_root_tdp(struct kvm_vcpu *vcpu, hpa_t root_tdp);
#else /* !CONFIG_HYPERV */
static inline void hv_track_root_tdp(struct kvm_vcpu *vcpu, hpa_t root_tdp)
{
diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c
index baca9fa37a91..80a2020c4db4 100644
--- a/arch/x86/kvm/lapic.c
+++ b/arch/x86/kvm/lapic.c
@@ -68,6 +68,39 @@ static bool lapic_timer_advance_dynamic __read_mostly;
/* step-by-step approximation to mitigate fluctuation */
#define LAPIC_TIMER_ADVANCE_ADJUST_STEP 8
+static inline void __kvm_lapic_set_reg(char *regs, int reg_off, u32 val)
+{
+ *((u32 *) (regs + reg_off)) = val;
+}
+
+static inline void kvm_lapic_set_reg(struct kvm_lapic *apic, int reg_off, u32 val)
+{
+ __kvm_lapic_set_reg(apic->regs, reg_off, val);
+}
+
+static __always_inline u64 __kvm_lapic_get_reg64(char *regs, int reg)
+{
+ BUILD_BUG_ON(reg != APIC_ICR);
+ return *((u64 *) (regs + reg));
+}
+
+static __always_inline u64 kvm_lapic_get_reg64(struct kvm_lapic *apic, int reg)
+{
+ return __kvm_lapic_get_reg64(apic->regs, reg);
+}
+
+static __always_inline void __kvm_lapic_set_reg64(char *regs, int reg, u64 val)
+{
+ BUILD_BUG_ON(reg != APIC_ICR);
+ *((u64 *) (regs + reg)) = val;
+}
+
+static __always_inline void kvm_lapic_set_reg64(struct kvm_lapic *apic,
+ int reg, u64 val)
+{
+ __kvm_lapic_set_reg64(apic->regs, reg, val);
+}
+
static inline int apic_test_vector(int vec, void *bitmap)
{
return test_bit(VEC_POS(vec), (bitmap) + REG_POS(vec));
@@ -113,7 +146,8 @@ static inline u32 kvm_x2apic_id(struct kvm_lapic *apic)
static bool kvm_can_post_timer_interrupt(struct kvm_vcpu *vcpu)
{
- return pi_inject_timer && kvm_vcpu_apicv_active(vcpu);
+ return pi_inject_timer && kvm_vcpu_apicv_active(vcpu) &&
+ (kvm_mwait_in_guest(vcpu->kvm) || kvm_hlt_in_guest(vcpu->kvm));
}
bool kvm_can_use_hv_timer(struct kvm_vcpu *vcpu)
@@ -491,8 +525,7 @@ static inline void apic_clear_irr(int vec, struct kvm_lapic *apic)
if (unlikely(vcpu->arch.apicv_active)) {
/* need to update RVI */
kvm_lapic_clear_vector(vec, apic->regs + APIC_IRR);
- static_call(kvm_x86_hwapic_irr_update)(vcpu,
- apic_find_highest_irr(apic));
+ static_call_cond(kvm_x86_hwapic_irr_update)(vcpu, apic_find_highest_irr(apic));
} else {
apic->irr_pending = false;
kvm_lapic_clear_vector(vec, apic->regs + APIC_IRR);
@@ -522,7 +555,7 @@ static inline void apic_set_isr(int vec, struct kvm_lapic *apic)
* just set SVI.
*/
if (unlikely(vcpu->arch.apicv_active))
- static_call(kvm_x86_hwapic_isr_update)(vcpu, vec);
+ static_call_cond(kvm_x86_hwapic_isr_update)(vcpu, vec);
else {
++apic->isr_count;
BUG_ON(apic->isr_count > MAX_APIC_VECTOR);
@@ -570,8 +603,7 @@ static inline void apic_clear_isr(int vec, struct kvm_lapic *apic)
* and must be left alone.
*/
if (unlikely(vcpu->arch.apicv_active))
- static_call(kvm_x86_hwapic_isr_update)(vcpu,
- apic_find_highest_isr(apic));
+ static_call_cond(kvm_x86_hwapic_isr_update)(vcpu, apic_find_highest_isr(apic));
else {
--apic->isr_count;
BUG_ON(apic->isr_count < 0);
@@ -1096,14 +1128,8 @@ static int __apic_accept_irq(struct kvm_lapic *apic, int delivery_mode,
apic->regs + APIC_TMR);
}
- if (static_call(kvm_x86_deliver_posted_interrupt)(vcpu, vector)) {
- kvm_lapic_set_irr(vector, apic);
- kvm_make_request(KVM_REQ_EVENT, vcpu);
- kvm_vcpu_kick(vcpu);
- } else {
- trace_kvm_apicv_accept_irq(vcpu->vcpu_id, delivery_mode,
- trig_mode, vector);
- }
+ static_call(kvm_x86_deliver_interrupt)(apic, delivery_mode,
+ trig_mode, vector);
break;
case APIC_DM_REMRD:
@@ -1282,6 +1308,9 @@ void kvm_apic_send_ipi(struct kvm_lapic *apic, u32 icr_low, u32 icr_high)
{
struct kvm_lapic_irq irq;
+ /* KVM has no delay and should always clear the BUSY/PENDING flag. */
+ WARN_ON_ONCE(icr_low & APIC_ICR_BUSY);
+
irq.vector = icr_low & APIC_VECTOR_MASK;
irq.delivery_mode = icr_low & APIC_MODE_MASK;
irq.dest_mode = icr_low & APIC_DEST_MASK;
@@ -1298,6 +1327,7 @@ void kvm_apic_send_ipi(struct kvm_lapic *apic, u32 icr_low, u32 icr_high)
kvm_irq_delivery_to_apic(apic->vcpu->kvm, apic, &irq, NULL);
}
+EXPORT_SYMBOL_GPL(kvm_apic_send_ipi);
static u32 apic_get_tmcct(struct kvm_lapic *apic)
{
@@ -1381,8 +1411,8 @@ static inline struct kvm_lapic *to_lapic(struct kvm_io_device *dev)
#define APIC_REGS_MASK(first, count) \
(APIC_REG_MASK(first) * ((1ull << (count)) - 1))
-int kvm_lapic_reg_read(struct kvm_lapic *apic, u32 offset, int len,
- void *data)
+static int kvm_lapic_reg_read(struct kvm_lapic *apic, u32 offset, int len,
+ void *data)
{
unsigned char alignment = offset & 0xf;
u32 result;
@@ -1400,7 +1430,6 @@ int kvm_lapic_reg_read(struct kvm_lapic *apic, u32 offset, int len,
APIC_REGS_MASK(APIC_IRR, APIC_ISR_NR) |
APIC_REG_MASK(APIC_ESR) |
APIC_REG_MASK(APIC_ICR) |
- APIC_REG_MASK(APIC_ICR2) |
APIC_REG_MASK(APIC_LVTT) |
APIC_REG_MASK(APIC_LVTTHMR) |
APIC_REG_MASK(APIC_LVTPC) |
@@ -1411,9 +1440,16 @@ int kvm_lapic_reg_read(struct kvm_lapic *apic, u32 offset, int len,
APIC_REG_MASK(APIC_TMCCT) |
APIC_REG_MASK(APIC_TDCR);
- /* ARBPRI is not valid on x2APIC */
+ /*
+ * ARBPRI and ICR2 are not valid in x2APIC mode. WARN if KVM reads ICR
+ * in x2APIC mode as it's an 8-byte register in x2APIC and needs to be
+ * manually handled by the caller.
+ */
if (!apic_x2apic_mode(apic))
- valid_reg_mask |= APIC_REG_MASK(APIC_ARBPRI);
+ valid_reg_mask |= APIC_REG_MASK(APIC_ARBPRI) |
+ APIC_REG_MASK(APIC_ICR2);
+ else
+ WARN_ON_ONCE(offset == APIC_ICR);
if (alignment + len > 4)
return 1;
@@ -1438,7 +1474,6 @@ int kvm_lapic_reg_read(struct kvm_lapic *apic, u32 offset, int len,
}
return 0;
}
-EXPORT_SYMBOL_GPL(kvm_lapic_reg_read);
static int apic_mmio_in_range(struct kvm_lapic *apic, gpa_t addr)
{
@@ -1999,7 +2034,7 @@ static void apic_manage_nmi_watchdog(struct kvm_lapic *apic, u32 lvt0_val)
}
}
-int kvm_lapic_reg_write(struct kvm_lapic *apic, u32 reg, u32 val)
+static int kvm_lapic_reg_write(struct kvm_lapic *apic, u32 reg, u32 val)
{
int ret = 0;
@@ -2058,16 +2093,18 @@ int kvm_lapic_reg_write(struct kvm_lapic *apic, u32 reg, u32 val)
break;
}
case APIC_ICR:
+ WARN_ON_ONCE(apic_x2apic_mode(apic));
+
/* No delay here, so we always clear the pending bit */
- val &= ~(1 << 12);
+ val &= ~APIC_ICR_BUSY;
kvm_apic_send_ipi(apic, val, kvm_lapic_get_reg(apic, APIC_ICR2));
kvm_lapic_set_reg(apic, APIC_ICR, val);
break;
-
case APIC_ICR2:
- if (!apic_x2apic_mode(apic))
- val &= 0xff000000;
- kvm_lapic_set_reg(apic, APIC_ICR2, val);
+ if (apic_x2apic_mode(apic))
+ ret = 1;
+ else
+ kvm_lapic_set_reg(apic, APIC_ICR2, val & 0xff000000);
break;
case APIC_LVT0:
@@ -2127,10 +2164,9 @@ int kvm_lapic_reg_write(struct kvm_lapic *apic, u32 reg, u32 val)
break;
case APIC_SELF_IPI:
- if (apic_x2apic_mode(apic)) {
- kvm_lapic_reg_write(apic, APIC_ICR,
- APIC_DEST_SELF | (val & APIC_VECTOR_MASK));
- } else
+ if (apic_x2apic_mode(apic))
+ kvm_apic_send_ipi(apic, APIC_DEST_SELF | (val & APIC_VECTOR_MASK), 0);
+ else
ret = 1;
break;
default:
@@ -2138,11 +2174,15 @@ int kvm_lapic_reg_write(struct kvm_lapic *apic, u32 reg, u32 val)
break;
}
+ /*
+ * Recalculate APIC maps if necessary, e.g. if the software enable bit
+ * was toggled, the APIC ID changed, etc... The maps are marked dirty
+ * on relevant changes, i.e. this is a nop for most writes.
+ */
kvm_recalculate_apic_map(apic->vcpu->kvm);
return ret;
}
-EXPORT_SYMBOL_GPL(kvm_lapic_reg_write);
static int apic_mmio_write(struct kvm_vcpu *vcpu, struct kvm_io_device *this,
gpa_t address, int len, const void *data)
@@ -2186,12 +2226,7 @@ EXPORT_SYMBOL_GPL(kvm_lapic_set_eoi);
/* emulate APIC access in a trap manner */
void kvm_apic_write_nodecode(struct kvm_vcpu *vcpu, u32 offset)
{
- u32 val = 0;
-
- /* hw has done the conditional check and inst decode */
- offset &= 0xff0;
-
- kvm_lapic_reg_read(vcpu->arch.apic, offset, 4, &val);
+ u32 val = kvm_lapic_get_reg(vcpu->arch.apic, offset);
/* TODO: optimize to just emulate side effect w/o one more write */
kvm_lapic_reg_write(vcpu->arch.apic, offset, val);
@@ -2248,10 +2283,7 @@ void kvm_set_lapic_tscdeadline_msr(struct kvm_vcpu *vcpu, u64 data)
void kvm_lapic_set_tpr(struct kvm_vcpu *vcpu, unsigned long cr8)
{
- struct kvm_lapic *apic = vcpu->arch.apic;
-
- apic_set_tpr(apic, ((cr8 & 0x0f) << 4)
- | (kvm_lapic_get_reg(apic, APIC_TASKPRI) & 4));
+ apic_set_tpr(vcpu->arch.apic, (cr8 & 0x0f) << 4);
}
u64 kvm_lapic_get_cr8(struct kvm_vcpu *vcpu)
@@ -2293,7 +2325,7 @@ void kvm_lapic_set_base(struct kvm_vcpu *vcpu, u64 value)
kvm_apic_set_x2apic_id(apic, vcpu->vcpu_id);
if ((old_value ^ value) & (MSR_IA32_APICBASE_ENABLE | X2APIC_ENABLE))
- static_call(kvm_x86_set_virtual_apic_mode)(vcpu);
+ static_call_cond(kvm_x86_set_virtual_apic_mode)(vcpu);
apic->base_address = apic->vcpu->arch.apic_base &
MSR_IA32_APICBASE_BASE;
@@ -2312,7 +2344,12 @@ void kvm_apic_update_apicv(struct kvm_vcpu *vcpu)
apic->irr_pending = true;
apic->isr_count = 1;
} else {
- apic->irr_pending = (apic_search_irr(apic) != -1);
+ /*
+ * Don't clear irr_pending, searching the IRR can race with
+ * updates from the CPU as APICv is still active from hardware's
+ * perspective. The flag will be cleared as appropriate when
+ * KVM injects the interrupt.
+ */
apic->isr_count = count_vectors(apic->regs + APIC_ISR);
}
}
@@ -2357,8 +2394,12 @@ void kvm_lapic_reset(struct kvm_vcpu *vcpu, bool init_event)
if (!apic_x2apic_mode(apic))
kvm_apic_set_ldr(apic, 0);
kvm_lapic_set_reg(apic, APIC_ESR, 0);
- kvm_lapic_set_reg(apic, APIC_ICR, 0);
- kvm_lapic_set_reg(apic, APIC_ICR2, 0);
+ if (!apic_x2apic_mode(apic)) {
+ kvm_lapic_set_reg(apic, APIC_ICR, 0);
+ kvm_lapic_set_reg(apic, APIC_ICR2, 0);
+ } else {
+ kvm_lapic_set_reg64(apic, APIC_ICR, 0);
+ }
kvm_lapic_set_reg(apic, APIC_TDCR, 0);
kvm_lapic_set_reg(apic, APIC_TMICT, 0);
for (i = 0; i < 8; i++) {
@@ -2374,9 +2415,9 @@ void kvm_lapic_reset(struct kvm_vcpu *vcpu, bool init_event)
vcpu->arch.pv_eoi.msr_val = 0;
apic_update_ppr(apic);
if (vcpu->arch.apicv_active) {
- static_call(kvm_x86_apicv_post_state_restore)(vcpu);
- static_call(kvm_x86_hwapic_irr_update)(vcpu, -1);
- static_call(kvm_x86_hwapic_isr_update)(vcpu, -1);
+ static_call_cond(kvm_x86_apicv_post_state_restore)(vcpu);
+ static_call_cond(kvm_x86_hwapic_irr_update)(vcpu, -1);
+ static_call_cond(kvm_x86_hwapic_isr_update)(vcpu, -1);
}
vcpu->arch.apic_arb_prio = 0;
@@ -2575,6 +2616,7 @@ static int kvm_apic_state_fixup(struct kvm_vcpu *vcpu,
if (apic_x2apic_mode(vcpu->arch.apic)) {
u32 *id = (u32 *)(s->regs + APIC_ID);
u32 *ldr = (u32 *)(s->regs + APIC_LDR);
+ u64 icr;
if (vcpu->kvm->arch.x2apic_format) {
if (*id != vcpu->vcpu_id)
@@ -2586,9 +2628,21 @@ static int kvm_apic_state_fixup(struct kvm_vcpu *vcpu,
*id <<= 24;
}
- /* In x2APIC mode, the LDR is fixed and based on the id */
- if (set)
+ /*
+ * In x2APIC mode, the LDR is fixed and based on the id. And
+ * ICR is internally a single 64-bit register, but needs to be
+ * split to ICR+ICR2 in userspace for backwards compatibility.
+ */
+ if (set) {
*ldr = kvm_apic_calc_x2apic_ldr(*id);
+
+ icr = __kvm_lapic_get_reg(s->regs, APIC_ICR) |
+ (u64)__kvm_lapic_get_reg(s->regs, APIC_ICR2) << 32;
+ __kvm_lapic_set_reg64(s->regs, APIC_ICR, icr);
+ } else {
+ icr = __kvm_lapic_get_reg64(s->regs, APIC_ICR);
+ __kvm_lapic_set_reg(s->regs, APIC_ICR2, icr >> 32);
+ }
}
return 0;
@@ -2629,7 +2683,7 @@ int kvm_apic_set_state(struct kvm_vcpu *vcpu, struct kvm_lapic_state *s)
kvm_apic_set_version(vcpu);
apic_update_ppr(apic);
- hrtimer_cancel(&apic->lapic_timer.timer);
+ cancel_apic_timer(apic);
apic->lapic_timer.expired_tscdeadline = 0;
apic_update_lvtt(apic);
apic_manage_nmi_watchdog(apic, kvm_lapic_get_reg(apic, APIC_LVT0));
@@ -2639,11 +2693,9 @@ int kvm_apic_set_state(struct kvm_vcpu *vcpu, struct kvm_lapic_state *s)
kvm_apic_update_apicv(vcpu);
apic->highest_isr_cache = -1;
if (vcpu->arch.apicv_active) {
- static_call(kvm_x86_apicv_post_state_restore)(vcpu);
- static_call(kvm_x86_hwapic_irr_update)(vcpu,
- apic_find_highest_irr(apic));
- static_call(kvm_x86_hwapic_isr_update)(vcpu,
- apic_find_highest_isr(apic));
+ static_call_cond(kvm_x86_apicv_post_state_restore)(vcpu);
+ static_call_cond(kvm_x86_hwapic_irr_update)(vcpu, apic_find_highest_irr(apic));
+ static_call_cond(kvm_x86_hwapic_isr_update)(vcpu, apic_find_highest_isr(apic));
}
kvm_make_request(KVM_REQ_EVENT, vcpu);
if (ioapic_in_kernel(vcpu->kvm))
@@ -2780,73 +2832,85 @@ int kvm_lapic_set_vapic_addr(struct kvm_vcpu *vcpu, gpa_t vapic_addr)
return 0;
}
-int kvm_x2apic_msr_write(struct kvm_vcpu *vcpu, u32 msr, u64 data)
+int kvm_x2apic_icr_write(struct kvm_lapic *apic, u64 data)
{
- struct kvm_lapic *apic = vcpu->arch.apic;
- u32 reg = (msr - APIC_BASE_MSR) << 4;
+ data &= ~APIC_ICR_BUSY;
- if (!lapic_in_kernel(vcpu) || !apic_x2apic_mode(apic))
- return 1;
+ kvm_apic_send_ipi(apic, (u32)data, (u32)(data >> 32));
+ kvm_lapic_set_reg64(apic, APIC_ICR, data);
+ trace_kvm_apic_write(APIC_ICR, data);
+ return 0;
+}
+
+static int kvm_lapic_msr_read(struct kvm_lapic *apic, u32 reg, u64 *data)
+{
+ u32 low;
+
+ if (reg == APIC_ICR) {
+ *data = kvm_lapic_get_reg64(apic, APIC_ICR);
+ return 0;
+ }
- if (reg == APIC_ICR2)
+ if (kvm_lapic_reg_read(apic, reg, 4, &low))
return 1;
- /* if this is ICR write vector before command */
+ *data = low;
+
+ return 0;
+}
+
+static int kvm_lapic_msr_write(struct kvm_lapic *apic, u32 reg, u64 data)
+{
+ /*
+ * ICR is a 64-bit register in x2APIC mode (and Hyper'v PV vAPIC) and
+ * can be written as such, all other registers remain accessible only
+ * through 32-bit reads/writes.
+ */
if (reg == APIC_ICR)
- kvm_lapic_reg_write(apic, APIC_ICR2, (u32)(data >> 32));
+ return kvm_x2apic_icr_write(apic, data);
+
return kvm_lapic_reg_write(apic, reg, (u32)data);
}
-int kvm_x2apic_msr_read(struct kvm_vcpu *vcpu, u32 msr, u64 *data)
+int kvm_x2apic_msr_write(struct kvm_vcpu *vcpu, u32 msr, u64 data)
{
struct kvm_lapic *apic = vcpu->arch.apic;
- u32 reg = (msr - APIC_BASE_MSR) << 4, low, high = 0;
+ u32 reg = (msr - APIC_BASE_MSR) << 4;
if (!lapic_in_kernel(vcpu) || !apic_x2apic_mode(apic))
return 1;
- if (reg == APIC_DFR || reg == APIC_ICR2)
- return 1;
+ return kvm_lapic_msr_write(apic, reg, data);
+}
- if (kvm_lapic_reg_read(apic, reg, 4, &low))
+int kvm_x2apic_msr_read(struct kvm_vcpu *vcpu, u32 msr, u64 *data)
+{
+ struct kvm_lapic *apic = vcpu->arch.apic;
+ u32 reg = (msr - APIC_BASE_MSR) << 4;
+
+ if (!lapic_in_kernel(vcpu) || !apic_x2apic_mode(apic))
return 1;
- if (reg == APIC_ICR)
- kvm_lapic_reg_read(apic, APIC_ICR2, 4, &high);
- *data = (((u64)high) << 32) | low;
+ if (reg == APIC_DFR)
+ return 1;
- return 0;
+ return kvm_lapic_msr_read(apic, reg, data);
}
int kvm_hv_vapic_msr_write(struct kvm_vcpu *vcpu, u32 reg, u64 data)
{
- struct kvm_lapic *apic = vcpu->arch.apic;
-
if (!lapic_in_kernel(vcpu))
return 1;
- /* if this is ICR write vector before command */
- if (reg == APIC_ICR)
- kvm_lapic_reg_write(apic, APIC_ICR2, (u32)(data >> 32));
- return kvm_lapic_reg_write(apic, reg, (u32)data);
+ return kvm_lapic_msr_write(vcpu->arch.apic, reg, data);
}
int kvm_hv_vapic_msr_read(struct kvm_vcpu *vcpu, u32 reg, u64 *data)
{
- struct kvm_lapic *apic = vcpu->arch.apic;
- u32 low, high = 0;
-
if (!lapic_in_kernel(vcpu))
return 1;
- if (kvm_lapic_reg_read(apic, reg, 4, &low))
- return 1;
- if (reg == APIC_ICR)
- kvm_lapic_reg_read(apic, APIC_ICR2, 4, &high);
-
- *data = (((u64)high) << 32) | low;
-
- return 0;
+ return kvm_lapic_msr_read(vcpu->arch.apic, reg, data);
}
int kvm_lapic_set_pv_eoi(struct kvm_vcpu *vcpu, u64 data, unsigned long len)
@@ -2934,7 +2998,7 @@ int kvm_apic_accept_events(struct kvm_vcpu *vcpu)
/* evaluate pending_events before reading the vector */
smp_rmb();
sipi_vector = apic->sipi_vector;
- kvm_x86_ops.vcpu_deliver_sipi_vector(vcpu, sipi_vector);
+ static_call(kvm_x86_vcpu_deliver_sipi_vector)(vcpu, sipi_vector);
vcpu->arch.mp_state = KVM_MP_STATE_RUNNABLE;
}
}
diff --git a/arch/x86/kvm/lapic.h b/arch/x86/kvm/lapic.h
index 2b44e533fc8d..4e4f8a22754f 100644
--- a/arch/x86/kvm/lapic.h
+++ b/arch/x86/kvm/lapic.h
@@ -85,9 +85,6 @@ void kvm_lapic_set_base(struct kvm_vcpu *vcpu, u64 value);
u64 kvm_lapic_get_base(struct kvm_vcpu *vcpu);
void kvm_recalculate_apic_map(struct kvm *kvm);
void kvm_apic_set_version(struct kvm_vcpu *vcpu);
-int kvm_lapic_reg_write(struct kvm_lapic *apic, u32 reg, u32 val);
-int kvm_lapic_reg_read(struct kvm_lapic *apic, u32 offset, int len,
- void *data);
bool kvm_apic_match_dest(struct kvm_vcpu *vcpu, struct kvm_lapic *source,
int shorthand, unsigned int dest, int dest_mode);
int kvm_apic_compare_prio(struct kvm_vcpu *vcpu1, struct kvm_vcpu *vcpu2);
@@ -121,6 +118,7 @@ int kvm_lapic_set_vapic_addr(struct kvm_vcpu *vcpu, gpa_t vapic_addr);
void kvm_lapic_sync_from_vapic(struct kvm_vcpu *vcpu);
void kvm_lapic_sync_to_vapic(struct kvm_vcpu *vcpu);
+int kvm_x2apic_icr_write(struct kvm_lapic *apic, u64 data);
int kvm_x2apic_msr_write(struct kvm_vcpu *vcpu, u32 msr, u64 data);
int kvm_x2apic_msr_read(struct kvm_vcpu *vcpu, u32 msr, u64 *data);
@@ -153,19 +151,14 @@ static inline void kvm_lapic_set_irr(int vec, struct kvm_lapic *apic)
apic->irr_pending = true;
}
-static inline u32 kvm_lapic_get_reg(struct kvm_lapic *apic, int reg_off)
+static inline u32 __kvm_lapic_get_reg(char *regs, int reg_off)
{
- return *((u32 *) (apic->regs + reg_off));
+ return *((u32 *) (regs + reg_off));
}
-static inline void __kvm_lapic_set_reg(char *regs, int reg_off, u32 val)
-{
- *((u32 *) (regs + reg_off)) = val;
-}
-
-static inline void kvm_lapic_set_reg(struct kvm_lapic *apic, int reg_off, u32 val)
+static inline u32 kvm_lapic_get_reg(struct kvm_lapic *apic, int reg_off)
{
- __kvm_lapic_set_reg(apic->regs, reg_off, val);
+ return __kvm_lapic_get_reg(apic->regs, reg_off);
}
DECLARE_STATIC_KEY_FALSE(kvm_has_noapic_vcpu);
diff --git a/arch/x86/kvm/mmu.h b/arch/x86/kvm/mmu.h
index e9fbb2c8bbe2..bf8dbc4bb12a 100644
--- a/arch/x86/kvm/mmu.h
+++ b/arch/x86/kvm/mmu.h
@@ -48,6 +48,7 @@
X86_CR4_SMEP | X86_CR4_SMAP | X86_CR4_PKE)
#define KVM_MMU_CR0_ROLE_BITS (X86_CR0_PG | X86_CR0_WP)
+#define KVM_MMU_EFER_ROLE_BITS (EFER_LME | EFER_NX)
static __always_inline u64 rsvd_bits(int s, int e)
{
@@ -79,12 +80,13 @@ int kvm_handle_page_fault(struct kvm_vcpu *vcpu, u64 error_code,
int kvm_mmu_load(struct kvm_vcpu *vcpu);
void kvm_mmu_unload(struct kvm_vcpu *vcpu);
+void kvm_mmu_free_obsolete_roots(struct kvm_vcpu *vcpu);
void kvm_mmu_sync_roots(struct kvm_vcpu *vcpu);
void kvm_mmu_sync_prev_roots(struct kvm_vcpu *vcpu);
static inline int kvm_mmu_reload(struct kvm_vcpu *vcpu)
{
- if (likely(vcpu->arch.mmu->root_hpa != INVALID_PAGE))
+ if (likely(vcpu->arch.mmu->root.hpa != INVALID_PAGE))
return 0;
return kvm_mmu_load(vcpu);
@@ -106,7 +108,7 @@ static inline unsigned long kvm_get_active_pcid(struct kvm_vcpu *vcpu)
static inline void kvm_mmu_load_pgd(struct kvm_vcpu *vcpu)
{
- u64 root_hpa = vcpu->arch.mmu->root_hpa;
+ u64 root_hpa = vcpu->arch.mmu->root.hpa;
if (!VALID_PAGE(root_hpa))
return;
@@ -203,44 +205,6 @@ static inline int kvm_mmu_do_page_fault(struct kvm_vcpu *vcpu, gpa_t cr2_or_gpa,
}
/*
- * Currently, we have two sorts of write-protection, a) the first one
- * write-protects guest page to sync the guest modification, b) another one is
- * used to sync dirty bitmap when we do KVM_GET_DIRTY_LOG. The differences
- * between these two sorts are:
- * 1) the first case clears MMU-writable bit.
- * 2) the first case requires flushing tlb immediately avoiding corrupting
- * shadow page table between all vcpus so it should be in the protection of
- * mmu-lock. And the another case does not need to flush tlb until returning
- * the dirty bitmap to userspace since it only write-protects the page
- * logged in the bitmap, that means the page in the dirty bitmap is not
- * missed, so it can flush tlb out of mmu-lock.
- *
- * So, there is the problem: the first case can meet the corrupted tlb caused
- * by another case which write-protects pages but without flush tlb
- * immediately. In order to making the first case be aware this problem we let
- * it flush tlb if we try to write-protect a spte whose MMU-writable bit
- * is set, it works since another case never touches MMU-writable bit.
- *
- * Anyway, whenever a spte is updated (only permission and status bits are
- * changed) we need to check whether the spte with MMU-writable becomes
- * readonly, if that happens, we need to flush tlb. Fortunately,
- * mmu_spte_update() has already handled it perfectly.
- *
- * The rules to use MMU-writable and PT_WRITABLE_MASK:
- * - if we want to see if it has writable tlb entry or if the spte can be
- * writable on the mmu mapping, check MMU-writable, this is the most
- * case, otherwise
- * - if we fix page fault on the spte or do write-protection by dirty logging,
- * check PT_WRITABLE_MASK.
- *
- * TODO: introduce APIs to split these two cases.
- */
-static inline bool is_writable_pte(unsigned long pte)
-{
- return pte & PT_WRITABLE_MASK;
-}
-
-/*
* Check if a given access (described through the I/D, W/R and U/S bits of a
* page fault error code pfec) causes a permission fault with the given PTE
* access rights (in ACC_* format).
diff --git a/arch/x86/kvm/mmu/mmu.c b/arch/x86/kvm/mmu/mmu.c
index 593093b52395..51671cb34fb6 100644
--- a/arch/x86/kvm/mmu/mmu.c
+++ b/arch/x86/kvm/mmu/mmu.c
@@ -104,15 +104,6 @@ static int max_huge_page_level __read_mostly;
static int tdp_root_level __read_mostly;
static int max_tdp_level __read_mostly;
-enum {
- AUDIT_PRE_PAGE_FAULT,
- AUDIT_POST_PAGE_FAULT,
- AUDIT_PRE_PTE_WRITE,
- AUDIT_POST_PTE_WRITE,
- AUDIT_PRE_SYNC,
- AUDIT_POST_SYNC
-};
-
#ifdef MMU_DEBUG
bool dbg = 0;
module_param(dbg, bool, 0644);
@@ -190,8 +181,6 @@ struct kmem_cache *mmu_page_header_cache;
static struct percpu_counter kvm_total_used_mmu_pages;
static void mmu_spte_set(u64 *sptep, u64 spte);
-static union kvm_mmu_page_role
-kvm_mmu_calc_root_page_role(struct kvm_vcpu *vcpu);
struct kvm_mmu_role_regs {
const unsigned long cr0;
@@ -529,6 +518,7 @@ static u64 mmu_spte_update_no_track(u64 *sptep, u64 new_spte)
u64 old_spte = *sptep;
WARN_ON(!is_shadow_present_pte(new_spte));
+ check_spte_writable_invariants(new_spte);
if (!is_shadow_present_pte(old_spte)) {
mmu_spte_set(sptep, new_spte);
@@ -548,11 +538,9 @@ static u64 mmu_spte_update_no_track(u64 *sptep, u64 new_spte)
/* Rules for using mmu_spte_update:
* Update the state bits, it means the mapped pfn is not changed.
*
- * Whenever we overwrite a writable spte with a read-only one we
- * should flush remote TLBs. Otherwise rmap_write_protect
- * will find a read-only spte, even though the writable spte
- * might be cached on a CPU's TLB, the return value indicates this
- * case.
+ * Whenever an MMU-writable SPTE is overwritten with a read-only SPTE, remote
+ * TLBs must be flushed. Otherwise rmap_write_protect will find a read-only
+ * spte, even though the writable spte might be cached on a CPU's TLB.
*
* Returns true if the TLB needs to be flushed
*/
@@ -646,24 +634,6 @@ static u64 mmu_spte_get_lockless(u64 *sptep)
return __get_spte_lockless(sptep);
}
-/* Restore an acc-track PTE back to a regular PTE */
-static u64 restore_acc_track_spte(u64 spte)
-{
- u64 new_spte = spte;
- u64 saved_bits = (spte >> SHADOW_ACC_TRACK_SAVED_BITS_SHIFT)
- & SHADOW_ACC_TRACK_SAVED_BITS_MASK;
-
- WARN_ON_ONCE(spte_ad_enabled(spte));
- WARN_ON_ONCE(!is_access_track_spte(spte));
-
- new_spte &= ~shadow_acc_track_mask;
- new_spte &= ~(SHADOW_ACC_TRACK_SAVED_BITS_MASK <<
- SHADOW_ACC_TRACK_SAVED_BITS_SHIFT);
- new_spte |= saved_bits;
-
- return new_spte;
-}
-
/* Returns the Accessed status of the PTE and resets it at the same time. */
static bool mmu_spte_age(u64 *sptep)
{
@@ -1229,9 +1199,8 @@ static bool spte_write_protect(u64 *sptep, bool pt_protect)
return mmu_spte_update(sptep, spte);
}
-static bool __rmap_write_protect(struct kvm *kvm,
- struct kvm_rmap_head *rmap_head,
- bool pt_protect)
+static bool rmap_write_protect(struct kvm_rmap_head *rmap_head,
+ bool pt_protect)
{
u64 *sptep;
struct rmap_iterator iter;
@@ -1311,7 +1280,7 @@ static void kvm_mmu_write_protect_pt_masked(struct kvm *kvm,
while (mask) {
rmap_head = gfn_to_rmap(slot->base_gfn + gfn_offset + __ffs(mask),
PG_LEVEL_4K, slot);
- __rmap_write_protect(kvm, rmap_head, false);
+ rmap_write_protect(rmap_head, false);
/* clear the first set bit */
mask &= mask - 1;
@@ -1378,6 +1347,9 @@ void kvm_arch_mmu_enable_log_dirty_pt_masked(struct kvm *kvm,
gfn_t start = slot->base_gfn + gfn_offset + __ffs(mask);
gfn_t end = slot->base_gfn + gfn_offset + __fls(mask);
+ if (READ_ONCE(eager_page_split))
+ kvm_mmu_try_split_huge_pages(kvm, slot, start, end, PG_LEVEL_4K);
+
kvm_mmu_slot_gfn_write_protect(kvm, slot, start, PG_LEVEL_2M);
/* Cross two large pages? */
@@ -1410,7 +1382,7 @@ bool kvm_mmu_slot_gfn_write_protect(struct kvm *kvm,
if (kvm_memslots_have_rmaps(kvm)) {
for (i = min_level; i <= KVM_MAX_HUGEPAGE_LEVEL; ++i) {
rmap_head = gfn_to_rmap(gfn, i, slot);
- write_protected |= __rmap_write_protect(kvm, rmap_head, true);
+ write_protected |= rmap_write_protect(rmap_head, true);
}
}
@@ -1421,7 +1393,7 @@ bool kvm_mmu_slot_gfn_write_protect(struct kvm *kvm,
return write_protected;
}
-static bool rmap_write_protect(struct kvm_vcpu *vcpu, u64 gfn)
+static bool kvm_vcpu_write_protect_gfn(struct kvm_vcpu *vcpu, u64 gfn)
{
struct kvm_memory_slot *slot;
@@ -1921,13 +1893,6 @@ static bool kvm_mmu_remote_flush_or_zap(struct kvm *kvm,
return true;
}
-#ifdef CONFIG_KVM_MMU_AUDIT
-#include "mmu_audit.c"
-#else
-static void kvm_mmu_audit(struct kvm_vcpu *vcpu, int point) { }
-static void mmu_audit_disable(void) { }
-#endif
-
static bool is_obsolete_sp(struct kvm *kvm, struct kvm_mmu_page *sp)
{
if (sp->role.invalid)
@@ -2024,7 +1989,7 @@ static int mmu_sync_children(struct kvm_vcpu *vcpu,
bool protected = false;
for_each_sp(pages, sp, parents, i)
- protected |= rmap_write_protect(vcpu, sp->gfn);
+ protected |= kvm_vcpu_write_protect_gfn(vcpu, sp->gfn);
if (protected) {
kvm_mmu_remote_flush_or_zap(vcpu->kvm, &invalid_list, true);
@@ -2149,7 +2114,7 @@ trace_get_page:
hlist_add_head(&sp->hash_link, sp_list);
if (!direct) {
account_shadowed(vcpu->kvm, sp);
- if (level == PG_LEVEL_4K && rmap_write_protect(vcpu, gfn))
+ if (level == PG_LEVEL_4K && kvm_vcpu_write_protect_gfn(vcpu, gfn))
kvm_flush_remote_tlbs_with_address(vcpu->kvm, gfn, 1);
}
trace_kvm_mmu_get_page(sp, true);
@@ -2179,7 +2144,7 @@ static void shadow_walk_init_using_root(struct kvm_shadow_walk_iterator *iterato
* prev_root is currently only used for 64-bit hosts. So only
* the active root_hpa is valid here.
*/
- BUG_ON(root != vcpu->arch.mmu->root_hpa);
+ BUG_ON(root != vcpu->arch.mmu->root.hpa);
iterator->shadow_addr
= vcpu->arch.mmu->pae_root[(addr >> 30) & 3];
@@ -2193,7 +2158,7 @@ static void shadow_walk_init_using_root(struct kvm_shadow_walk_iterator *iterato
static void shadow_walk_init(struct kvm_shadow_walk_iterator *iterator,
struct kvm_vcpu *vcpu, u64 addr)
{
- shadow_walk_init_using_root(iterator, vcpu, vcpu->arch.mmu->root_hpa,
+ shadow_walk_init_using_root(iterator, vcpu, vcpu->arch.mmu->root.hpa,
addr);
}
@@ -2307,7 +2272,7 @@ static int kvm_mmu_page_unlink_children(struct kvm *kvm,
return zapped;
}
-static void kvm_mmu_unlink_parents(struct kvm *kvm, struct kvm_mmu_page *sp)
+static void kvm_mmu_unlink_parents(struct kvm_mmu_page *sp)
{
u64 *sptep;
struct rmap_iterator iter;
@@ -2345,13 +2310,13 @@ static bool __kvm_mmu_prepare_zap_page(struct kvm *kvm,
struct list_head *invalid_list,
int *nr_zapped)
{
- bool list_unstable;
+ bool list_unstable, zapped_root = false;
trace_kvm_mmu_prepare_zap_page(sp);
++kvm->stat.mmu_shadow_zapped;
*nr_zapped = mmu_zap_unsync_children(kvm, sp, invalid_list);
*nr_zapped += kvm_mmu_page_unlink_children(kvm, sp, invalid_list);
- kvm_mmu_unlink_parents(kvm, sp);
+ kvm_mmu_unlink_parents(sp);
/* Zapping children means active_mmu_pages has become unstable. */
list_unstable = *nr_zapped;
@@ -2387,14 +2352,20 @@ static bool __kvm_mmu_prepare_zap_page(struct kvm *kvm,
* in kvm_mmu_zap_all_fast(). Note, is_obsolete_sp() also
* treats invalid shadow pages as being obsolete.
*/
- if (!is_obsolete_sp(kvm, sp))
- kvm_reload_remote_mmus(kvm);
+ zapped_root = !is_obsolete_sp(kvm, sp);
}
if (sp->lpage_disallowed)
unaccount_huge_nx_page(kvm, sp);
sp->role.invalid = 1;
+
+ /*
+ * Make the request to free obsolete roots after marking the root
+ * invalid, otherwise other vCPUs may not see it as invalid.
+ */
+ if (zapped_root)
+ kvm_make_all_cpus_request(kvm, KVM_REQ_MMU_FREE_OBSOLETE_ROOTS);
return list_unstable;
}
@@ -3239,6 +3210,8 @@ static void mmu_free_root_page(struct kvm *kvm, hpa_t *root_hpa,
return;
sp = to_shadow_page(*root_hpa & PT64_BASE_ADDR_MASK);
+ if (WARN_ON(!sp))
+ return;
if (is_tdp_mmu_page(sp))
kvm_tdp_mmu_put_root(kvm, sp, false);
@@ -3249,18 +3222,20 @@ static void mmu_free_root_page(struct kvm *kvm, hpa_t *root_hpa,
}
/* roots_to_free must be some combination of the KVM_MMU_ROOT_* flags */
-void kvm_mmu_free_roots(struct kvm_vcpu *vcpu, struct kvm_mmu *mmu,
+void kvm_mmu_free_roots(struct kvm *kvm, struct kvm_mmu *mmu,
ulong roots_to_free)
{
- struct kvm *kvm = vcpu->kvm;
int i;
LIST_HEAD(invalid_list);
- bool free_active_root = roots_to_free & KVM_MMU_ROOT_CURRENT;
+ bool free_active_root;
BUILD_BUG_ON(KVM_MMU_NUM_PREV_ROOTS >= BITS_PER_LONG);
/* Before acquiring the MMU lock, see if we need to do any real work. */
- if (!(free_active_root && VALID_PAGE(mmu->root_hpa))) {
+ free_active_root = (roots_to_free & KVM_MMU_ROOT_CURRENT)
+ && VALID_PAGE(mmu->root.hpa);
+
+ if (!free_active_root) {
for (i = 0; i < KVM_MMU_NUM_PREV_ROOTS; i++)
if ((roots_to_free & KVM_MMU_ROOT_PREVIOUS(i)) &&
VALID_PAGE(mmu->prev_roots[i].hpa))
@@ -3278,9 +3253,8 @@ void kvm_mmu_free_roots(struct kvm_vcpu *vcpu, struct kvm_mmu *mmu,
&invalid_list);
if (free_active_root) {
- if (mmu->shadow_root_level >= PT64_ROOT_4LEVEL &&
- (mmu->root_level >= PT64_ROOT_4LEVEL || mmu->direct_map)) {
- mmu_free_root_page(kvm, &mmu->root_hpa, &invalid_list);
+ if (to_shadow_page(mmu->root.hpa)) {
+ mmu_free_root_page(kvm, &mmu->root.hpa, &invalid_list);
} else if (mmu->pae_root) {
for (i = 0; i < 4; ++i) {
if (!IS_VALID_PAE_ROOT(mmu->pae_root[i]))
@@ -3291,8 +3265,8 @@ void kvm_mmu_free_roots(struct kvm_vcpu *vcpu, struct kvm_mmu *mmu,
mmu->pae_root[i] = INVALID_PAE_ROOT;
}
}
- mmu->root_hpa = INVALID_PAGE;
- mmu->root_pgd = 0;
+ mmu->root.hpa = INVALID_PAGE;
+ mmu->root.pgd = 0;
}
kvm_mmu_commit_zap_page(kvm, &invalid_list);
@@ -3300,7 +3274,7 @@ void kvm_mmu_free_roots(struct kvm_vcpu *vcpu, struct kvm_mmu *mmu,
}
EXPORT_SYMBOL_GPL(kvm_mmu_free_roots);
-void kvm_mmu_free_guest_mode_roots(struct kvm_vcpu *vcpu, struct kvm_mmu *mmu)
+void kvm_mmu_free_guest_mode_roots(struct kvm *kvm, struct kvm_mmu *mmu)
{
unsigned long roots_to_free = 0;
hpa_t root_hpa;
@@ -3322,7 +3296,7 @@ void kvm_mmu_free_guest_mode_roots(struct kvm_vcpu *vcpu, struct kvm_mmu *mmu)
roots_to_free |= KVM_MMU_ROOT_PREVIOUS(i);
}
- kvm_mmu_free_roots(vcpu, mmu, roots_to_free);
+ kvm_mmu_free_roots(kvm, mmu, roots_to_free);
}
EXPORT_SYMBOL_GPL(kvm_mmu_free_guest_mode_roots);
@@ -3365,10 +3339,10 @@ static int mmu_alloc_direct_roots(struct kvm_vcpu *vcpu)
if (is_tdp_mmu_enabled(vcpu->kvm)) {
root = kvm_tdp_mmu_get_vcpu_root_hpa(vcpu);
- mmu->root_hpa = root;
+ mmu->root.hpa = root;
} else if (shadow_root_level >= PT64_ROOT_4LEVEL) {
root = mmu_alloc_root(vcpu, 0, 0, shadow_root_level, true);
- mmu->root_hpa = root;
+ mmu->root.hpa = root;
} else if (shadow_root_level == PT32E_ROOT_LEVEL) {
if (WARN_ON_ONCE(!mmu->pae_root)) {
r = -EIO;
@@ -3383,15 +3357,15 @@ static int mmu_alloc_direct_roots(struct kvm_vcpu *vcpu)
mmu->pae_root[i] = root | PT_PRESENT_MASK |
shadow_me_mask;
}
- mmu->root_hpa = __pa(mmu->pae_root);
+ mmu->root.hpa = __pa(mmu->pae_root);
} else {
WARN_ONCE(1, "Bad TDP root level = %d\n", shadow_root_level);
r = -EIO;
goto out_unlock;
}
- /* root_pgd is ignored for direct MMUs. */
- mmu->root_pgd = 0;
+ /* root.pgd is ignored for direct MMUs. */
+ mmu->root.pgd = 0;
out_unlock:
write_unlock(&vcpu->kvm->mmu_lock);
return r;
@@ -3504,7 +3478,7 @@ static int mmu_alloc_shadow_roots(struct kvm_vcpu *vcpu)
if (mmu->root_level >= PT64_ROOT_4LEVEL) {
root = mmu_alloc_root(vcpu, root_gfn, 0,
mmu->shadow_root_level, false);
- mmu->root_hpa = root;
+ mmu->root.hpa = root;
goto set_root_pgd;
}
@@ -3554,18 +3528,18 @@ static int mmu_alloc_shadow_roots(struct kvm_vcpu *vcpu)
}
if (mmu->shadow_root_level == PT64_ROOT_5LEVEL)
- mmu->root_hpa = __pa(mmu->pml5_root);
+ mmu->root.hpa = __pa(mmu->pml5_root);
else if (mmu->shadow_root_level == PT64_ROOT_4LEVEL)
- mmu->root_hpa = __pa(mmu->pml4_root);
+ mmu->root.hpa = __pa(mmu->pml4_root);
else
- mmu->root_hpa = __pa(mmu->pae_root);
+ mmu->root.hpa = __pa(mmu->pae_root);
set_root_pgd:
- mmu->root_pgd = root_pgd;
+ mmu->root.pgd = root_pgd;
out_unlock:
write_unlock(&vcpu->kvm->mmu_lock);
- return 0;
+ return r;
}
static int mmu_alloc_special_roots(struct kvm_vcpu *vcpu)
@@ -3660,6 +3634,14 @@ static bool is_unsync_root(hpa_t root)
*/
smp_rmb();
sp = to_shadow_page(root);
+
+ /*
+ * PAE roots (somewhat arbitrarily) aren't backed by shadow pages, the
+ * PDPTEs for a given PAE root need to be synchronized individually.
+ */
+ if (WARN_ON_ONCE(!sp))
+ return false;
+
if (sp->unsync || sp->unsync_children)
return true;
@@ -3674,30 +3656,25 @@ void kvm_mmu_sync_roots(struct kvm_vcpu *vcpu)
if (vcpu->arch.mmu->direct_map)
return;
- if (!VALID_PAGE(vcpu->arch.mmu->root_hpa))
+ if (!VALID_PAGE(vcpu->arch.mmu->root.hpa))
return;
vcpu_clear_mmio_info(vcpu, MMIO_GVA_ANY);
if (vcpu->arch.mmu->root_level >= PT64_ROOT_4LEVEL) {
- hpa_t root = vcpu->arch.mmu->root_hpa;
+ hpa_t root = vcpu->arch.mmu->root.hpa;
sp = to_shadow_page(root);
if (!is_unsync_root(root))
return;
write_lock(&vcpu->kvm->mmu_lock);
- kvm_mmu_audit(vcpu, AUDIT_PRE_SYNC);
-
mmu_sync_children(vcpu, sp, true);
-
- kvm_mmu_audit(vcpu, AUDIT_POST_SYNC);
write_unlock(&vcpu->kvm->mmu_lock);
return;
}
write_lock(&vcpu->kvm->mmu_lock);
- kvm_mmu_audit(vcpu, AUDIT_PRE_SYNC);
for (i = 0; i < 4; ++i) {
hpa_t root = vcpu->arch.mmu->pae_root[i];
@@ -3709,7 +3686,6 @@ void kvm_mmu_sync_roots(struct kvm_vcpu *vcpu)
}
}
- kvm_mmu_audit(vcpu, AUDIT_POST_SYNC);
write_unlock(&vcpu->kvm->mmu_lock);
}
@@ -3723,7 +3699,7 @@ void kvm_mmu_sync_prev_roots(struct kvm_vcpu *vcpu)
roots_to_free |= KVM_MMU_ROOT_PREVIOUS(i);
/* sync prev_roots by simply freeing them */
- kvm_mmu_free_roots(vcpu, vcpu->arch.mmu, roots_to_free);
+ kvm_mmu_free_roots(vcpu->kvm, vcpu->arch.mmu, roots_to_free);
}
static gpa_t nonpaging_gva_to_gpa(struct kvm_vcpu *vcpu, struct kvm_mmu *mmu,
@@ -3889,12 +3865,23 @@ static void shadow_page_table_clear_flood(struct kvm_vcpu *vcpu, gva_t addr)
walk_shadow_page_lockless_end(vcpu);
}
+static u32 alloc_apf_token(struct kvm_vcpu *vcpu)
+{
+ /* make sure the token value is not 0 */
+ u32 id = vcpu->arch.apf.id;
+
+ if (id << 12 == 0)
+ vcpu->arch.apf.id = 1;
+
+ return (vcpu->arch.apf.id++ << 12) | vcpu->vcpu_id;
+}
+
static bool kvm_arch_setup_async_pf(struct kvm_vcpu *vcpu, gpa_t cr2_or_gpa,
gfn_t gfn)
{
struct kvm_arch_async_pf arch;
- arch.token = (vcpu->arch.apf.id++ << 12) | vcpu->vcpu_id;
+ arch.token = alloc_apf_token(vcpu);
arch.gfn = gfn;
arch.direct_map = vcpu->arch.mmu->direct_map;
arch.cr3 = vcpu->arch.mmu->get_guest_pgd(vcpu);
@@ -3971,7 +3958,7 @@ out_retry:
static bool is_page_fault_stale(struct kvm_vcpu *vcpu,
struct kvm_page_fault *fault, int mmu_seq)
{
- struct kvm_mmu_page *sp = to_shadow_page(vcpu->arch.mmu->root_hpa);
+ struct kvm_mmu_page *sp = to_shadow_page(vcpu->arch.mmu->root.hpa);
/* Special roots, e.g. pae_root, are not backed by shadow pages. */
if (sp && is_obsolete_sp(vcpu->kvm, sp))
@@ -3985,7 +3972,7 @@ static bool is_page_fault_stale(struct kvm_vcpu *vcpu,
* previous root, then __kvm_mmu_prepare_zap_page() signals all vCPUs
* to reload even if no vCPU is actively using the root.
*/
- if (!sp && kvm_test_request(KVM_REQ_MMU_RELOAD, vcpu))
+ if (!sp && kvm_test_request(KVM_REQ_MMU_FREE_OBSOLETE_ROOTS, vcpu))
return true;
return fault->slot &&
@@ -4121,74 +4108,105 @@ static inline bool is_root_usable(struct kvm_mmu_root_info *root, gpa_t pgd,
union kvm_mmu_page_role role)
{
return (role.direct || pgd == root->pgd) &&
- VALID_PAGE(root->hpa) && to_shadow_page(root->hpa) &&
+ VALID_PAGE(root->hpa) &&
role.word == to_shadow_page(root->hpa)->role.word;
}
/*
- * Find out if a previously cached root matching the new pgd/role is available.
- * The current root is also inserted into the cache.
- * If a matching root was found, it is assigned to kvm_mmu->root_hpa and true is
- * returned.
- * Otherwise, the LRU root from the cache is assigned to kvm_mmu->root_hpa and
- * false is returned. This root should now be freed by the caller.
+ * Find out if a previously cached root matching the new pgd/role is available,
+ * and insert the current root as the MRU in the cache.
+ * If a matching root is found, it is assigned to kvm_mmu->root and
+ * true is returned.
+ * If no match is found, kvm_mmu->root is left invalid, the LRU root is
+ * evicted to make room for the current root, and false is returned.
*/
-static bool cached_root_available(struct kvm_vcpu *vcpu, gpa_t new_pgd,
- union kvm_mmu_page_role new_role)
+static bool cached_root_find_and_keep_current(struct kvm *kvm, struct kvm_mmu *mmu,
+ gpa_t new_pgd,
+ union kvm_mmu_page_role new_role)
{
uint i;
- struct kvm_mmu_root_info root;
- struct kvm_mmu *mmu = vcpu->arch.mmu;
- root.pgd = mmu->root_pgd;
- root.hpa = mmu->root_hpa;
-
- if (is_root_usable(&root, new_pgd, new_role))
+ if (is_root_usable(&mmu->root, new_pgd, new_role))
return true;
for (i = 0; i < KVM_MMU_NUM_PREV_ROOTS; i++) {
- swap(root, mmu->prev_roots[i]);
-
- if (is_root_usable(&root, new_pgd, new_role))
- break;
+ /*
+ * The swaps end up rotating the cache like this:
+ * C 0 1 2 3 (on entry to the function)
+ * 0 C 1 2 3
+ * 1 C 0 2 3
+ * 2 C 0 1 3
+ * 3 C 0 1 2 (on exit from the loop)
+ */
+ swap(mmu->root, mmu->prev_roots[i]);
+ if (is_root_usable(&mmu->root, new_pgd, new_role))
+ return true;
}
- mmu->root_hpa = root.hpa;
- mmu->root_pgd = root.pgd;
-
- return i < KVM_MMU_NUM_PREV_ROOTS;
+ kvm_mmu_free_roots(kvm, mmu, KVM_MMU_ROOT_CURRENT);
+ return false;
}
-static bool fast_pgd_switch(struct kvm_vcpu *vcpu, gpa_t new_pgd,
- union kvm_mmu_page_role new_role)
+/*
+ * Find out if a previously cached root matching the new pgd/role is available.
+ * On entry, mmu->root is invalid.
+ * If a matching root is found, it is assigned to kvm_mmu->root, the LRU entry
+ * of the cache becomes invalid, and true is returned.
+ * If no match is found, kvm_mmu->root is left invalid and false is returned.
+ */
+static bool cached_root_find_without_current(struct kvm *kvm, struct kvm_mmu *mmu,
+ gpa_t new_pgd,
+ union kvm_mmu_page_role new_role)
{
- struct kvm_mmu *mmu = vcpu->arch.mmu;
+ uint i;
+
+ for (i = 0; i < KVM_MMU_NUM_PREV_ROOTS; i++)
+ if (is_root_usable(&mmu->prev_roots[i], new_pgd, new_role))
+ goto hit;
+
+ return false;
+hit:
+ swap(mmu->root, mmu->prev_roots[i]);
+ /* Bubble up the remaining roots. */
+ for (; i < KVM_MMU_NUM_PREV_ROOTS - 1; i++)
+ mmu->prev_roots[i] = mmu->prev_roots[i + 1];
+ mmu->prev_roots[i].hpa = INVALID_PAGE;
+ return true;
+}
+
+static bool fast_pgd_switch(struct kvm *kvm, struct kvm_mmu *mmu,
+ gpa_t new_pgd, union kvm_mmu_page_role new_role)
+{
/*
- * For now, limit the fast switch to 64-bit hosts+VMs in order to avoid
+ * For now, limit the caching to 64-bit hosts+VMs in order to avoid
* having to deal with PDPTEs. We may add support for 32-bit hosts/VMs
* later if necessary.
*/
- if (mmu->shadow_root_level >= PT64_ROOT_4LEVEL &&
- mmu->root_level >= PT64_ROOT_4LEVEL)
- return cached_root_available(vcpu, new_pgd, new_role);
+ if (VALID_PAGE(mmu->root.hpa) && !to_shadow_page(mmu->root.hpa))
+ kvm_mmu_free_roots(kvm, mmu, KVM_MMU_ROOT_CURRENT);
- return false;
+ if (VALID_PAGE(mmu->root.hpa))
+ return cached_root_find_and_keep_current(kvm, mmu, new_pgd, new_role);
+ else
+ return cached_root_find_without_current(kvm, mmu, new_pgd, new_role);
}
-static void __kvm_mmu_new_pgd(struct kvm_vcpu *vcpu, gpa_t new_pgd,
- union kvm_mmu_page_role new_role)
+void kvm_mmu_new_pgd(struct kvm_vcpu *vcpu, gpa_t new_pgd)
{
- if (!fast_pgd_switch(vcpu, new_pgd, new_role)) {
- kvm_mmu_free_roots(vcpu, vcpu->arch.mmu, KVM_MMU_ROOT_CURRENT);
+ struct kvm_mmu *mmu = vcpu->arch.mmu;
+ union kvm_mmu_page_role new_role = mmu->mmu_role.base;
+
+ if (!fast_pgd_switch(vcpu->kvm, mmu, new_pgd, new_role)) {
+ /* kvm_mmu_ensure_valid_pgd will set up a new root. */
return;
}
/*
* It's possible that the cached previous root page is obsolete because
* of a change in the MMU generation number. However, changing the
- * generation number is accompanied by KVM_REQ_MMU_RELOAD, which will
- * free the root set here and allocate a new one.
+ * generation number is accompanied by KVM_REQ_MMU_FREE_OBSOLETE_ROOTS,
+ * which will free the root set here and allocate a new one.
*/
kvm_make_request(KVM_REQ_LOAD_MMU_PGD, vcpu);
@@ -4211,12 +4229,7 @@ static void __kvm_mmu_new_pgd(struct kvm_vcpu *vcpu, gpa_t new_pgd,
*/
if (!new_role.direct)
__clear_sp_write_flooding_count(
- to_shadow_page(vcpu->arch.mmu->root_hpa));
-}
-
-void kvm_mmu_new_pgd(struct kvm_vcpu *vcpu, gpa_t new_pgd)
-{
- __kvm_mmu_new_pgd(vcpu, new_pgd, kvm_mmu_calc_root_page_role(vcpu));
+ to_shadow_page(vcpu->arch.mmu->root.hpa));
}
EXPORT_SYMBOL_GPL(kvm_mmu_new_pgd);
@@ -4474,8 +4487,7 @@ static inline bool boot_cpu_is_amd(void)
* possible, however, kvm currently does not do execution-protection.
*/
static void
-reset_tdp_shadow_zero_bits_mask(struct kvm_vcpu *vcpu,
- struct kvm_mmu *context)
+reset_tdp_shadow_zero_bits_mask(struct kvm_mmu *context)
{
struct rsvd_bits_validate *shadow_zero_check;
int i;
@@ -4506,8 +4518,7 @@ reset_tdp_shadow_zero_bits_mask(struct kvm_vcpu *vcpu,
* is the shadow page table for intel nested guest.
*/
static void
-reset_ept_shadow_zero_bits_mask(struct kvm_vcpu *vcpu,
- struct kvm_mmu *context, bool execonly)
+reset_ept_shadow_zero_bits_mask(struct kvm_mmu *context, bool execonly)
{
__reset_rsvds_bits_mask_ept(&context->shadow_zero_check,
reserved_hpa_bits(), execonly,
@@ -4794,7 +4805,7 @@ static void init_kvm_tdp_mmu(struct kvm_vcpu *vcpu)
context->gva_to_gpa = paging32_gva_to_gpa;
reset_guest_paging_metadata(vcpu, context);
- reset_tdp_shadow_zero_bits_mask(vcpu, context);
+ reset_tdp_shadow_zero_bits_mask(context);
}
static union kvm_mmu_role
@@ -4888,9 +4899,8 @@ void kvm_init_shadow_npt_mmu(struct kvm_vcpu *vcpu, unsigned long cr0,
new_role = kvm_calc_shadow_npt_root_page_role(vcpu, &regs);
- __kvm_mmu_new_pgd(vcpu, nested_cr3, new_role.base);
-
shadow_mmu_init_context(vcpu, context, &regs, new_role);
+ kvm_mmu_new_pgd(vcpu, nested_cr3);
}
EXPORT_SYMBOL_GPL(kvm_init_shadow_npt_mmu);
@@ -4928,27 +4938,25 @@ void kvm_init_shadow_ept_mmu(struct kvm_vcpu *vcpu, bool execonly,
kvm_calc_shadow_ept_root_page_role(vcpu, accessed_dirty,
execonly, level);
- __kvm_mmu_new_pgd(vcpu, new_eptp, new_role.base);
-
- if (new_role.as_u64 == context->mmu_role.as_u64)
- return;
-
- context->mmu_role.as_u64 = new_role.as_u64;
-
- context->shadow_root_level = level;
-
- context->ept_ad = accessed_dirty;
- context->page_fault = ept_page_fault;
- context->gva_to_gpa = ept_gva_to_gpa;
- context->sync_page = ept_sync_page;
- context->invlpg = ept_invlpg;
- context->root_level = level;
- context->direct_map = false;
+ if (new_role.as_u64 != context->mmu_role.as_u64) {
+ context->mmu_role.as_u64 = new_role.as_u64;
+
+ context->shadow_root_level = level;
+
+ context->ept_ad = accessed_dirty;
+ context->page_fault = ept_page_fault;
+ context->gva_to_gpa = ept_gva_to_gpa;
+ context->sync_page = ept_sync_page;
+ context->invlpg = ept_invlpg;
+ context->root_level = level;
+ context->direct_map = false;
+ update_permission_bitmask(context, true);
+ context->pkru_mask = 0;
+ reset_rsvds_bits_mask_ept(vcpu, context, execonly, huge_page_level);
+ reset_ept_shadow_zero_bits_mask(context, execonly);
+ }
- update_permission_bitmask(context, true);
- context->pkru_mask = 0;
- reset_rsvds_bits_mask_ept(vcpu, context, execonly, huge_page_level);
- reset_ept_shadow_zero_bits_mask(vcpu, context, execonly);
+ kvm_mmu_new_pgd(vcpu, new_eptp);
}
EXPORT_SYMBOL_GPL(kvm_init_shadow_ept_mmu);
@@ -5033,20 +5041,6 @@ void kvm_init_mmu(struct kvm_vcpu *vcpu)
}
EXPORT_SYMBOL_GPL(kvm_init_mmu);
-static union kvm_mmu_page_role
-kvm_mmu_calc_root_page_role(struct kvm_vcpu *vcpu)
-{
- struct kvm_mmu_role_regs regs = vcpu_to_role_regs(vcpu);
- union kvm_mmu_role role;
-
- if (tdp_enabled)
- role = kvm_calc_tdp_mmu_root_page_role(vcpu, &regs, true);
- else
- role = kvm_calc_shadow_mmu_root_page_role(vcpu, &regs, true);
-
- return role.base;
-}
-
void kvm_mmu_after_set_cpuid(struct kvm_vcpu *vcpu)
{
/*
@@ -5100,17 +5094,73 @@ int kvm_mmu_load(struct kvm_vcpu *vcpu)
kvm_mmu_sync_roots(vcpu);
kvm_mmu_load_pgd(vcpu);
- static_call(kvm_x86_tlb_flush_current)(vcpu);
+
+ /*
+ * Flush any TLB entries for the new root, the provenance of the root
+ * is unknown. Even if KVM ensures there are no stale TLB entries
+ * for a freed root, in theory another hypervisor could have left
+ * stale entries. Flushing on alloc also allows KVM to skip the TLB
+ * flush when freeing a root (see kvm_tdp_mmu_put_root()).
+ */
+ static_call(kvm_x86_flush_tlb_current)(vcpu);
out:
return r;
}
void kvm_mmu_unload(struct kvm_vcpu *vcpu)
{
- kvm_mmu_free_roots(vcpu, &vcpu->arch.root_mmu, KVM_MMU_ROOTS_ALL);
- WARN_ON(VALID_PAGE(vcpu->arch.root_mmu.root_hpa));
- kvm_mmu_free_roots(vcpu, &vcpu->arch.guest_mmu, KVM_MMU_ROOTS_ALL);
- WARN_ON(VALID_PAGE(vcpu->arch.guest_mmu.root_hpa));
+ struct kvm *kvm = vcpu->kvm;
+
+ kvm_mmu_free_roots(kvm, &vcpu->arch.root_mmu, KVM_MMU_ROOTS_ALL);
+ WARN_ON(VALID_PAGE(vcpu->arch.root_mmu.root.hpa));
+ kvm_mmu_free_roots(kvm, &vcpu->arch.guest_mmu, KVM_MMU_ROOTS_ALL);
+ WARN_ON(VALID_PAGE(vcpu->arch.guest_mmu.root.hpa));
+ vcpu_clear_mmio_info(vcpu, MMIO_GVA_ANY);
+}
+
+static bool is_obsolete_root(struct kvm *kvm, hpa_t root_hpa)
+{
+ struct kvm_mmu_page *sp;
+
+ if (!VALID_PAGE(root_hpa))
+ return false;
+
+ /*
+ * When freeing obsolete roots, treat roots as obsolete if they don't
+ * have an associated shadow page. This does mean KVM will get false
+ * positives and free roots that don't strictly need to be freed, but
+ * such false positives are relatively rare:
+ *
+ * (a) only PAE paging and nested NPT has roots without shadow pages
+ * (b) remote reloads due to a memslot update obsoletes _all_ roots
+ * (c) KVM doesn't track previous roots for PAE paging, and the guest
+ * is unlikely to zap an in-use PGD.
+ */
+ sp = to_shadow_page(root_hpa);
+ return !sp || is_obsolete_sp(kvm, sp);
+}
+
+static void __kvm_mmu_free_obsolete_roots(struct kvm *kvm, struct kvm_mmu *mmu)
+{
+ unsigned long roots_to_free = 0;
+ int i;
+
+ if (is_obsolete_root(kvm, mmu->root.hpa))
+ roots_to_free |= KVM_MMU_ROOT_CURRENT;
+
+ for (i = 0; i < KVM_MMU_NUM_PREV_ROOTS; i++) {
+ if (is_obsolete_root(kvm, mmu->root.hpa))
+ roots_to_free |= KVM_MMU_ROOT_PREVIOUS(i);
+ }
+
+ if (roots_to_free)
+ kvm_mmu_free_roots(kvm, mmu, roots_to_free);
+}
+
+void kvm_mmu_free_obsolete_roots(struct kvm_vcpu *vcpu)
+{
+ __kvm_mmu_free_obsolete_roots(vcpu->kvm, &vcpu->arch.root_mmu);
+ __kvm_mmu_free_obsolete_roots(vcpu->kvm, &vcpu->arch.guest_mmu);
}
static bool need_remote_flush(u64 old, u64 new)
@@ -5260,7 +5310,6 @@ static void kvm_mmu_pte_write(struct kvm_vcpu *vcpu, gpa_t gpa,
gentry = mmu_pte_write_fetch_gpte(vcpu, &gpa, &bytes);
++vcpu->kvm->stat.mmu_pte_write;
- kvm_mmu_audit(vcpu, AUDIT_PRE_PTE_WRITE);
for_each_gfn_indirect_valid_sp(vcpu->kvm, sp, gfn) {
if (detect_write_misaligned(sp, gpa, bytes) ||
@@ -5285,7 +5334,6 @@ static void kvm_mmu_pte_write(struct kvm_vcpu *vcpu, gpa_t gpa,
}
}
kvm_mmu_remote_flush_or_zap(vcpu->kvm, &invalid_list, flush);
- kvm_mmu_audit(vcpu, AUDIT_POST_PTE_WRITE);
write_unlock(&vcpu->kvm->mmu_lock);
}
@@ -5295,7 +5343,7 @@ int kvm_mmu_page_fault(struct kvm_vcpu *vcpu, gpa_t cr2_or_gpa, u64 error_code,
int r, emulation_type = EMULTYPE_PF;
bool direct = vcpu->arch.mmu->direct_map;
- if (WARN_ON(!VALID_PAGE(vcpu->arch.mmu->root_hpa)))
+ if (WARN_ON(!VALID_PAGE(vcpu->arch.mmu->root.hpa)))
return RET_PF_RETRY;
r = RET_PF_INVALID;
@@ -5360,14 +5408,14 @@ void kvm_mmu_invalidate_gva(struct kvm_vcpu *vcpu, struct kvm_mmu *mmu,
if (is_noncanonical_address(gva, vcpu))
return;
- static_call(kvm_x86_tlb_flush_gva)(vcpu, gva);
+ static_call(kvm_x86_flush_tlb_gva)(vcpu, gva);
}
if (!mmu->invlpg)
return;
if (root_hpa == INVALID_PAGE) {
- mmu->invlpg(vcpu, gva, mmu->root_hpa);
+ mmu->invlpg(vcpu, gva, mmu->root.hpa);
/*
* INVLPG is required to invalidate any global mappings for the VA,
@@ -5403,7 +5451,7 @@ void kvm_mmu_invpcid_gva(struct kvm_vcpu *vcpu, gva_t gva, unsigned long pcid)
uint i;
if (pcid == kvm_get_active_pcid(vcpu)) {
- mmu->invlpg(vcpu, gva, mmu->root_hpa);
+ mmu->invlpg(vcpu, gva, mmu->root.hpa);
tlb_flush = true;
}
@@ -5416,7 +5464,7 @@ void kvm_mmu_invpcid_gva(struct kvm_vcpu *vcpu, gva_t gva, unsigned long pcid)
}
if (tlb_flush)
- static_call(kvm_x86_tlb_flush_gva)(vcpu, gva);
+ static_call(kvm_x86_flush_tlb_gva)(vcpu, gva);
++vcpu->stat.invlpg;
@@ -5516,8 +5564,8 @@ static int __kvm_mmu_create(struct kvm_vcpu *vcpu, struct kvm_mmu *mmu)
struct page *page;
int i;
- mmu->root_hpa = INVALID_PAGE;
- mmu->root_pgd = 0;
+ mmu->root.hpa = INVALID_PAGE;
+ mmu->root.pgd = 0;
for (i = 0; i < KVM_MMU_NUM_PREV_ROOTS; i++)
mmu->prev_roots[i] = KVM_MMU_ROOT_INFO_INVALID;
@@ -5637,9 +5685,13 @@ restart:
}
/*
- * Trigger a remote TLB flush before freeing the page tables to ensure
- * KVM is not in the middle of a lockless shadow page table walk, which
- * may reference the pages.
+ * Kick all vCPUs (via remote TLB flush) before freeing the page tables
+ * to ensure KVM is not in the middle of a lockless shadow page table
+ * walk, which may reference the pages. The remote TLB flush itself is
+ * not required and is simply a convenient way to kick vCPUs as needed.
+ * KVM performs a local TLB flush when allocating a new root (see
+ * kvm_mmu_load()), and the reload in the caller ensure no vCPUs are
+ * running with an obsolete MMU.
*/
kvm_mmu_commit_zap_page(kvm, &kvm->arch.zapped_obsolete_pages);
}
@@ -5669,11 +5721,11 @@ static void kvm_mmu_zap_all_fast(struct kvm *kvm)
*/
kvm->arch.mmu_valid_gen = kvm->arch.mmu_valid_gen ? 0 : 1;
- /* In order to ensure all threads see this change when
- * handling the MMU reload signal, this must happen in the
- * same critical section as kvm_reload_remote_mmus, and
- * before kvm_zap_obsolete_pages as kvm_zap_obsolete_pages
- * could drop the MMU lock and yield.
+ /*
+ * In order to ensure all vCPUs drop their soon-to-be invalid roots,
+ * invalidating TDP MMU roots must be done while holding mmu_lock for
+ * write and in the same critical section as making the reload request,
+ * e.g. before kvm_zap_obsolete_pages() could drop mmu_lock and yield.
*/
if (is_tdp_mmu_enabled(kvm))
kvm_tdp_mmu_invalidate_all_roots(kvm);
@@ -5686,17 +5738,22 @@ static void kvm_mmu_zap_all_fast(struct kvm *kvm)
* Note: we need to do this under the protection of mmu_lock,
* otherwise, vcpu would purge shadow page but miss tlb flush.
*/
- kvm_reload_remote_mmus(kvm);
+ kvm_make_all_cpus_request(kvm, KVM_REQ_MMU_FREE_OBSOLETE_ROOTS);
kvm_zap_obsolete_pages(kvm);
write_unlock(&kvm->mmu_lock);
- if (is_tdp_mmu_enabled(kvm)) {
- read_lock(&kvm->mmu_lock);
+ /*
+ * Zap the invalidated TDP MMU roots, all SPTEs must be dropped before
+ * returning to the caller, e.g. if the zap is in response to a memslot
+ * deletion, mmu_notifier callbacks will be unable to reach the SPTEs
+ * associated with the deleted memslot once the update completes, and
+ * Deferring the zap until the final reference to the root is put would
+ * lead to use-after-free.
+ */
+ if (is_tdp_mmu_enabled(kvm))
kvm_tdp_mmu_zap_invalidated_roots(kvm);
- read_unlock(&kvm->mmu_lock);
- }
}
static bool kvm_has_zapped_obsolete_pages(struct kvm *kvm)
@@ -5802,7 +5859,7 @@ static bool slot_rmap_write_protect(struct kvm *kvm,
struct kvm_rmap_head *rmap_head,
const struct kvm_memory_slot *slot)
{
- return __rmap_write_protect(kvm, rmap_head, false);
+ return rmap_write_protect(rmap_head, false);
}
void kvm_mmu_slot_remove_write_access(struct kvm *kvm,
@@ -5846,12 +5903,52 @@ void kvm_mmu_slot_remove_write_access(struct kvm *kvm,
* will clear a separate software-only bit (MMU-writable) and skip the
* flush if-and-only-if this bit was already clear.
*
- * See DEFAULT_SPTE_MMU_WRITEABLE for more details.
+ * See is_writable_pte() for more details.
*/
if (flush)
kvm_arch_flush_remote_tlbs_memslot(kvm, memslot);
}
+/* Must be called with the mmu_lock held in write-mode. */
+void kvm_mmu_try_split_huge_pages(struct kvm *kvm,
+ const struct kvm_memory_slot *memslot,
+ u64 start, u64 end,
+ int target_level)
+{
+ if (is_tdp_mmu_enabled(kvm))
+ kvm_tdp_mmu_try_split_huge_pages(kvm, memslot, start, end,
+ target_level, false);
+
+ /*
+ * A TLB flush is unnecessary at this point for the same resons as in
+ * kvm_mmu_slot_try_split_huge_pages().
+ */
+}
+
+void kvm_mmu_slot_try_split_huge_pages(struct kvm *kvm,
+ const struct kvm_memory_slot *memslot,
+ int target_level)
+{
+ u64 start = memslot->base_gfn;
+ u64 end = start + memslot->npages;
+
+ if (is_tdp_mmu_enabled(kvm)) {
+ read_lock(&kvm->mmu_lock);
+ kvm_tdp_mmu_try_split_huge_pages(kvm, memslot, start, end, target_level, true);
+ read_unlock(&kvm->mmu_lock);
+ }
+
+ /*
+ * No TLB flush is necessary here. KVM will flush TLBs after
+ * write-protecting and/or clearing dirty on the newly split SPTEs to
+ * ensure that guest writes are reflected in the dirty log before the
+ * ioctl to enable dirty logging on this memslot completes. Since the
+ * split SPTEs retain the write and dirty bits of the huge SPTE, it is
+ * safe for KVM to decide if a TLB flush is necessary based on the split
+ * SPTEs.
+ */
+}
+
static bool kvm_mmu_zap_collapsible_spte(struct kvm *kvm,
struct kvm_rmap_head *rmap_head,
const struct kvm_memory_slot *slot)
@@ -6191,7 +6288,6 @@ void kvm_mmu_module_exit(void)
mmu_destroy_caches();
percpu_counter_destroy(&kvm_total_used_mmu_pages);
unregister_shrinker(&mmu_shrinker);
- mmu_audit_disable();
}
/*
@@ -6261,6 +6357,13 @@ static void kvm_recover_nx_lpages(struct kvm *kvm)
rcu_idx = srcu_read_lock(&kvm->srcu);
write_lock(&kvm->mmu_lock);
+ /*
+ * Zapping TDP MMU shadow pages, including the remote TLB flush, must
+ * be done under RCU protection, because the pages are freed via RCU
+ * callback.
+ */
+ rcu_read_lock();
+
ratio = READ_ONCE(nx_huge_pages_recovery_ratio);
to_zap = ratio ? DIV_ROUND_UP(nx_lpage_splits, ratio) : 0;
for ( ; to_zap; --to_zap) {
@@ -6285,12 +6388,18 @@ static void kvm_recover_nx_lpages(struct kvm *kvm)
if (need_resched() || rwlock_needbreak(&kvm->mmu_lock)) {
kvm_mmu_remote_flush_or_zap(kvm, &invalid_list, flush);
+ rcu_read_unlock();
+
cond_resched_rwlock_write(&kvm->mmu_lock);
flush = false;
+
+ rcu_read_lock();
}
}
kvm_mmu_remote_flush_or_zap(kvm, &invalid_list, flush);
+ rcu_read_unlock();
+
write_unlock(&kvm->mmu_lock);
srcu_read_unlock(&kvm->srcu, rcu_idx);
}
diff --git a/arch/x86/kvm/mmu/mmu_audit.c b/arch/x86/kvm/mmu/mmu_audit.c
deleted file mode 100644
index 9e7dcf999f08..000000000000
--- a/arch/x86/kvm/mmu/mmu_audit.c
+++ /dev/null
@@ -1,303 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * mmu_audit.c:
- *
- * Audit code for KVM MMU
- *
- * Copyright (C) 2006 Qumranet, Inc.
- * Copyright 2010 Red Hat, Inc. and/or its affiliates.
- *
- * Authors:
- * Yaniv Kamay <yaniv@qumranet.com>
- * Avi Kivity <avi@qumranet.com>
- * Marcelo Tosatti <mtosatti@redhat.com>
- * Xiao Guangrong <xiaoguangrong@cn.fujitsu.com>
- */
-
-#include <linux/ratelimit.h>
-
-static char const *audit_point_name[] = {
- "pre page fault",
- "post page fault",
- "pre pte write",
- "post pte write",
- "pre sync",
- "post sync"
-};
-
-#define audit_printk(kvm, fmt, args...) \
- printk(KERN_ERR "audit: (%s) error: " \
- fmt, audit_point_name[kvm->arch.audit_point], ##args)
-
-typedef void (*inspect_spte_fn) (struct kvm_vcpu *vcpu, u64 *sptep, int level);
-
-static void __mmu_spte_walk(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp,
- inspect_spte_fn fn, int level)
-{
- int i;
-
- for (i = 0; i < PT64_ENT_PER_PAGE; ++i) {
- u64 *ent = sp->spt;
-
- fn(vcpu, ent + i, level);
-
- if (is_shadow_present_pte(ent[i]) &&
- !is_last_spte(ent[i], level)) {
- struct kvm_mmu_page *child;
-
- child = to_shadow_page(ent[i] & PT64_BASE_ADDR_MASK);
- __mmu_spte_walk(vcpu, child, fn, level - 1);
- }
- }
-}
-
-static void mmu_spte_walk(struct kvm_vcpu *vcpu, inspect_spte_fn fn)
-{
- int i;
- struct kvm_mmu_page *sp;
-
- if (!VALID_PAGE(vcpu->arch.mmu->root_hpa))
- return;
-
- if (vcpu->arch.mmu->root_level >= PT64_ROOT_4LEVEL) {
- hpa_t root = vcpu->arch.mmu->root_hpa;
-
- sp = to_shadow_page(root);
- __mmu_spte_walk(vcpu, sp, fn, vcpu->arch.mmu->root_level);
- return;
- }
-
- for (i = 0; i < 4; ++i) {
- hpa_t root = vcpu->arch.mmu->pae_root[i];
-
- if (IS_VALID_PAE_ROOT(root)) {
- root &= PT64_BASE_ADDR_MASK;
- sp = to_shadow_page(root);
- __mmu_spte_walk(vcpu, sp, fn, 2);
- }
- }
-
- return;
-}
-
-typedef void (*sp_handler) (struct kvm *kvm, struct kvm_mmu_page *sp);
-
-static void walk_all_active_sps(struct kvm *kvm, sp_handler fn)
-{
- struct kvm_mmu_page *sp;
-
- list_for_each_entry(sp, &kvm->arch.active_mmu_pages, link)
- fn(kvm, sp);
-}
-
-static void audit_mappings(struct kvm_vcpu *vcpu, u64 *sptep, int level)
-{
- struct kvm_mmu_page *sp;
- gfn_t gfn;
- kvm_pfn_t pfn;
- hpa_t hpa;
-
- sp = sptep_to_sp(sptep);
-
- if (sp->unsync) {
- if (level != PG_LEVEL_4K) {
- audit_printk(vcpu->kvm, "unsync sp: %p "
- "level = %d\n", sp, level);
- return;
- }
- }
-
- if (!is_shadow_present_pte(*sptep) || !is_last_spte(*sptep, level))
- return;
-
- gfn = kvm_mmu_page_get_gfn(sp, sptep - sp->spt);
- pfn = kvm_vcpu_gfn_to_pfn_atomic(vcpu, gfn);
-
- if (is_error_pfn(pfn))
- return;
-
- hpa = pfn << PAGE_SHIFT;
- if ((*sptep & PT64_BASE_ADDR_MASK) != hpa)
- audit_printk(vcpu->kvm, "levels %d pfn %llx hpa %llx "
- "ent %llxn", vcpu->arch.mmu->root_level, pfn,
- hpa, *sptep);
-}
-
-static void inspect_spte_has_rmap(struct kvm *kvm, u64 *sptep)
-{
- static DEFINE_RATELIMIT_STATE(ratelimit_state, 5 * HZ, 10);
- struct kvm_rmap_head *rmap_head;
- struct kvm_mmu_page *rev_sp;
- struct kvm_memslots *slots;
- struct kvm_memory_slot *slot;
- gfn_t gfn;
-
- rev_sp = sptep_to_sp(sptep);
- gfn = kvm_mmu_page_get_gfn(rev_sp, sptep - rev_sp->spt);
-
- slots = kvm_memslots_for_spte_role(kvm, rev_sp->role);
- slot = __gfn_to_memslot(slots, gfn);
- if (!slot) {
- if (!__ratelimit(&ratelimit_state))
- return;
- audit_printk(kvm, "no memslot for gfn %llx\n", gfn);
- audit_printk(kvm, "index %ld of sp (gfn=%llx)\n",
- (long int)(sptep - rev_sp->spt), rev_sp->gfn);
- dump_stack();
- return;
- }
-
- rmap_head = gfn_to_rmap(gfn, rev_sp->role.level, slot);
- if (!rmap_head->val) {
- if (!__ratelimit(&ratelimit_state))
- return;
- audit_printk(kvm, "no rmap for writable spte %llx\n",
- *sptep);
- dump_stack();
- }
-}
-
-static void audit_sptes_have_rmaps(struct kvm_vcpu *vcpu, u64 *sptep, int level)
-{
- if (is_shadow_present_pte(*sptep) && is_last_spte(*sptep, level))
- inspect_spte_has_rmap(vcpu->kvm, sptep);
-}
-
-static void audit_spte_after_sync(struct kvm_vcpu *vcpu, u64 *sptep, int level)
-{
- struct kvm_mmu_page *sp = sptep_to_sp(sptep);
-
- if (vcpu->kvm->arch.audit_point == AUDIT_POST_SYNC && sp->unsync)
- audit_printk(vcpu->kvm, "meet unsync sp(%p) after sync "
- "root.\n", sp);
-}
-
-static void check_mappings_rmap(struct kvm *kvm, struct kvm_mmu_page *sp)
-{
- int i;
-
- if (sp->role.level != PG_LEVEL_4K)
- return;
-
- for (i = 0; i < PT64_ENT_PER_PAGE; ++i) {
- if (!is_shadow_present_pte(sp->spt[i]))
- continue;
-
- inspect_spte_has_rmap(kvm, sp->spt + i);
- }
-}
-
-static void audit_write_protection(struct kvm *kvm, struct kvm_mmu_page *sp)
-{
- struct kvm_rmap_head *rmap_head;
- u64 *sptep;
- struct rmap_iterator iter;
- struct kvm_memslots *slots;
- struct kvm_memory_slot *slot;
-
- if (sp->role.direct || sp->unsync || sp->role.invalid)
- return;
-
- slots = kvm_memslots_for_spte_role(kvm, sp->role);
- slot = __gfn_to_memslot(slots, sp->gfn);
- rmap_head = gfn_to_rmap(sp->gfn, PG_LEVEL_4K, slot);
-
- for_each_rmap_spte(rmap_head, &iter, sptep) {
- if (is_writable_pte(*sptep))
- audit_printk(kvm, "shadow page has writable "
- "mappings: gfn %llx role %x\n",
- sp->gfn, sp->role.word);
- }
-}
-
-static void audit_sp(struct kvm *kvm, struct kvm_mmu_page *sp)
-{
- check_mappings_rmap(kvm, sp);
- audit_write_protection(kvm, sp);
-}
-
-static void audit_all_active_sps(struct kvm *kvm)
-{
- walk_all_active_sps(kvm, audit_sp);
-}
-
-static void audit_spte(struct kvm_vcpu *vcpu, u64 *sptep, int level)
-{
- audit_sptes_have_rmaps(vcpu, sptep, level);
- audit_mappings(vcpu, sptep, level);
- audit_spte_after_sync(vcpu, sptep, level);
-}
-
-static void audit_vcpu_spte(struct kvm_vcpu *vcpu)
-{
- mmu_spte_walk(vcpu, audit_spte);
-}
-
-static bool mmu_audit;
-static DEFINE_STATIC_KEY_FALSE(mmu_audit_key);
-
-static void __kvm_mmu_audit(struct kvm_vcpu *vcpu, int point)
-{
- static DEFINE_RATELIMIT_STATE(ratelimit_state, 5 * HZ, 10);
-
- if (!__ratelimit(&ratelimit_state))
- return;
-
- vcpu->kvm->arch.audit_point = point;
- audit_all_active_sps(vcpu->kvm);
- audit_vcpu_spte(vcpu);
-}
-
-static inline void kvm_mmu_audit(struct kvm_vcpu *vcpu, int point)
-{
- if (static_branch_unlikely((&mmu_audit_key)))
- __kvm_mmu_audit(vcpu, point);
-}
-
-static void mmu_audit_enable(void)
-{
- if (mmu_audit)
- return;
-
- static_branch_inc(&mmu_audit_key);
- mmu_audit = true;
-}
-
-static void mmu_audit_disable(void)
-{
- if (!mmu_audit)
- return;
-
- static_branch_dec(&mmu_audit_key);
- mmu_audit = false;
-}
-
-static int mmu_audit_set(const char *val, const struct kernel_param *kp)
-{
- int ret;
- unsigned long enable;
-
- ret = kstrtoul(val, 10, &enable);
- if (ret < 0)
- return -EINVAL;
-
- switch (enable) {
- case 0:
- mmu_audit_disable();
- break;
- case 1:
- mmu_audit_enable();
- break;
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-static const struct kernel_param_ops audit_param_ops = {
- .set = mmu_audit_set,
- .get = param_get_bool,
-};
-
-arch_param_cb(mmu_audit, &audit_param_ops, &mmu_audit, 0644);
diff --git a/arch/x86/kvm/mmu/mmu_internal.h b/arch/x86/kvm/mmu/mmu_internal.h
index da6166b5c377..1bff453f7cbe 100644
--- a/arch/x86/kvm/mmu/mmu_internal.h
+++ b/arch/x86/kvm/mmu/mmu_internal.h
@@ -30,6 +30,8 @@ extern bool dbg;
#define INVALID_PAE_ROOT 0
#define IS_VALID_PAE_ROOT(x) (!!(x))
+typedef u64 __rcu *tdp_ptep_t;
+
struct kvm_mmu_page {
/*
* Note, "link" through "spt" fit in a single 64 byte cache line on
@@ -59,8 +61,17 @@ struct kvm_mmu_page {
refcount_t tdp_mmu_root_count;
};
unsigned int unsync_children;
- struct kvm_rmap_head parent_ptes; /* rmap pointers to parent sptes */
- DECLARE_BITMAP(unsync_child_bitmap, 512);
+ union {
+ struct kvm_rmap_head parent_ptes; /* rmap pointers to parent sptes */
+ tdp_ptep_t ptep;
+ };
+ union {
+ DECLARE_BITMAP(unsync_child_bitmap, 512);
+ struct {
+ struct work_struct tdp_mmu_async_work;
+ void *tdp_mmu_async_data;
+ };
+ };
struct list_head lpage_disallowed_link;
#ifdef CONFIG_X86_32
diff --git a/arch/x86/kvm/mmu/mmutrace.h b/arch/x86/kvm/mmu/mmutrace.h
index de5e8e4e1aa7..12247b96af01 100644
--- a/arch/x86/kvm/mmu/mmutrace.h
+++ b/arch/x86/kvm/mmu/mmutrace.h
@@ -416,6 +416,29 @@ TRACE_EVENT(
)
);
+TRACE_EVENT(
+ kvm_mmu_split_huge_page,
+ TP_PROTO(u64 gfn, u64 spte, int level, int errno),
+ TP_ARGS(gfn, spte, level, errno),
+
+ TP_STRUCT__entry(
+ __field(u64, gfn)
+ __field(u64, spte)
+ __field(int, level)
+ __field(int, errno)
+ ),
+
+ TP_fast_assign(
+ __entry->gfn = gfn;
+ __entry->spte = spte;
+ __entry->level = level;
+ __entry->errno = errno;
+ ),
+
+ TP_printk("gfn %llx spte %llx level %d errno %d",
+ __entry->gfn, __entry->spte, __entry->level, __entry->errno)
+);
+
#endif /* _TRACE_KVMMMU_H */
#undef TRACE_INCLUDE_PATH
diff --git a/arch/x86/kvm/mmu/page_track.c b/arch/x86/kvm/mmu/page_track.c
index 68eb1fb548b6..2e09d1b6249f 100644
--- a/arch/x86/kvm/mmu/page_track.c
+++ b/arch/x86/kvm/mmu/page_track.c
@@ -47,8 +47,8 @@ int kvm_page_track_create_memslot(struct kvm *kvm,
continue;
slot->arch.gfn_track[i] =
- kvcalloc(npages, sizeof(*slot->arch.gfn_track[i]),
- GFP_KERNEL_ACCOUNT);
+ __vcalloc(npages, sizeof(*slot->arch.gfn_track[i]),
+ GFP_KERNEL_ACCOUNT);
if (!slot->arch.gfn_track[i])
goto track_free;
}
@@ -75,7 +75,8 @@ int kvm_page_track_write_tracking_alloc(struct kvm_memory_slot *slot)
if (slot->arch.gfn_track[KVM_PAGE_TRACK_WRITE])
return 0;
- gfn_track = kvcalloc(slot->npages, sizeof(*gfn_track), GFP_KERNEL_ACCOUNT);
+ gfn_track = __vcalloc(slot->npages, sizeof(*gfn_track),
+ GFP_KERNEL_ACCOUNT);
if (gfn_track == NULL)
return -ENOMEM;
diff --git a/arch/x86/kvm/mmu/paging_tmpl.h b/arch/x86/kvm/mmu/paging_tmpl.h
index 5b5bdac97c7b..252c77805eb9 100644
--- a/arch/x86/kvm/mmu/paging_tmpl.h
+++ b/arch/x86/kvm/mmu/paging_tmpl.h
@@ -668,7 +668,7 @@ static int FNAME(fetch)(struct kvm_vcpu *vcpu, struct kvm_page_fault *fault,
if (FNAME(gpte_changed)(vcpu, gw, top_level))
goto out_gpte_changed;
- if (WARN_ON(!VALID_PAGE(vcpu->arch.mmu->root_hpa)))
+ if (WARN_ON(!VALID_PAGE(vcpu->arch.mmu->root.hpa)))
goto out_gpte_changed;
for (shadow_walk_init(&it, vcpu, fault->addr);
@@ -904,12 +904,10 @@ static int FNAME(page_fault)(struct kvm_vcpu *vcpu, struct kvm_page_fault *fault
if (is_page_fault_stale(vcpu, fault, mmu_seq))
goto out_unlock;
- kvm_mmu_audit(vcpu, AUDIT_PRE_PAGE_FAULT);
r = make_mmu_pages_available(vcpu);
if (r)
goto out_unlock;
r = FNAME(fetch)(vcpu, fault, &walker);
- kvm_mmu_audit(vcpu, AUDIT_POST_PAGE_FAULT);
out_unlock:
write_unlock(&vcpu->kvm->mmu_lock);
diff --git a/arch/x86/kvm/mmu/spte.c b/arch/x86/kvm/mmu/spte.c
index 73cfe62fdad1..4739b53c9734 100644
--- a/arch/x86/kvm/mmu/spte.c
+++ b/arch/x86/kvm/mmu/spte.c
@@ -192,6 +192,65 @@ out:
return wrprot;
}
+static u64 make_spte_executable(u64 spte)
+{
+ bool is_access_track = is_access_track_spte(spte);
+
+ if (is_access_track)
+ spte = restore_acc_track_spte(spte);
+
+ spte &= ~shadow_nx_mask;
+ spte |= shadow_x_mask;
+
+ if (is_access_track)
+ spte = mark_spte_for_access_track(spte);
+
+ return spte;
+}
+
+/*
+ * Construct an SPTE that maps a sub-page of the given huge page SPTE where
+ * `index` identifies which sub-page.
+ *
+ * This is used during huge page splitting to build the SPTEs that make up the
+ * new page table.
+ */
+u64 make_huge_page_split_spte(u64 huge_spte, int huge_level, int index)
+{
+ u64 child_spte;
+ int child_level;
+
+ if (WARN_ON_ONCE(!is_shadow_present_pte(huge_spte)))
+ return 0;
+
+ if (WARN_ON_ONCE(!is_large_pte(huge_spte)))
+ return 0;
+
+ child_spte = huge_spte;
+ child_level = huge_level - 1;
+
+ /*
+ * The child_spte already has the base address of the huge page being
+ * split. So we just have to OR in the offset to the page at the next
+ * lower level for the given index.
+ */
+ child_spte |= (index * KVM_PAGES_PER_HPAGE(child_level)) << PAGE_SHIFT;
+
+ if (child_level == PG_LEVEL_4K) {
+ child_spte &= ~PT_PAGE_SIZE_MASK;
+
+ /*
+ * When splitting to a 4K page, mark the page executable as the
+ * NX hugepage mitigation no longer applies.
+ */
+ if (is_nx_huge_page_enabled())
+ child_spte = make_spte_executable(child_spte);
+ }
+
+ return child_spte;
+}
+
+
u64 make_nonleaf_spte(u64 *child_pt, bool ad_disabled)
{
u64 spte = SPTE_MMU_PRESENT_MASK;
@@ -250,14 +309,7 @@ u64 mark_spte_for_access_track(u64 spte)
if (is_access_track_spte(spte))
return spte;
- /*
- * Making an Access Tracking PTE will result in removal of write access
- * from the PTE. So, verify that we will be able to restore the write
- * access in the fast page fault path later on.
- */
- WARN_ONCE((spte & PT_WRITABLE_MASK) &&
- !spte_can_locklessly_be_made_writable(spte),
- "kvm: Writable SPTE is not locklessly dirty-trackable\n");
+ check_spte_writable_invariants(spte);
WARN_ONCE(spte & (SHADOW_ACC_TRACK_SAVED_BITS_MASK <<
SHADOW_ACC_TRACK_SAVED_BITS_SHIFT),
@@ -368,8 +420,8 @@ void kvm_mmu_reset_all_pte_masks(void)
shadow_acc_track_mask = 0;
shadow_me_mask = sme_me_mask;
- shadow_host_writable_mask = DEFAULT_SPTE_HOST_WRITEABLE;
- shadow_mmu_writable_mask = DEFAULT_SPTE_MMU_WRITEABLE;
+ shadow_host_writable_mask = DEFAULT_SPTE_HOST_WRITABLE;
+ shadow_mmu_writable_mask = DEFAULT_SPTE_MMU_WRITABLE;
/*
* Set a reserved PA bit in MMIO SPTEs to generate page faults with
diff --git a/arch/x86/kvm/mmu/spte.h b/arch/x86/kvm/mmu/spte.h
index be6a007a4af3..73f12615416f 100644
--- a/arch/x86/kvm/mmu/spte.h
+++ b/arch/x86/kvm/mmu/spte.h
@@ -75,33 +75,13 @@ static_assert(SPTE_TDP_AD_ENABLED_MASK == 0);
static_assert(!(SPTE_TDP_AD_MASK & SHADOW_ACC_TRACK_SAVED_MASK));
/*
- * *_SPTE_HOST_WRITEABLE (aka Host-writable) indicates whether the host permits
- * writes to the guest page mapped by the SPTE. This bit is cleared on SPTEs
- * that map guest pages in read-only memslots and read-only VMAs.
- *
- * Invariants:
- * - If Host-writable is clear, PT_WRITABLE_MASK must be clear.
- *
- *
- * *_SPTE_MMU_WRITEABLE (aka MMU-writable) indicates whether the shadow MMU
- * allows writes to the guest page mapped by the SPTE. This bit is cleared when
- * the guest page mapped by the SPTE contains a page table that is being
- * monitored for shadow paging. In this case the SPTE can only be made writable
- * by unsyncing the shadow page under the mmu_lock.
- *
- * Invariants:
- * - If MMU-writable is clear, PT_WRITABLE_MASK must be clear.
- * - If MMU-writable is set, Host-writable must be set.
- *
- * If MMU-writable is set, PT_WRITABLE_MASK is normally set but can be cleared
- * to track writes for dirty logging. For such SPTEs, KVM will locklessly set
- * PT_WRITABLE_MASK upon the next write from the guest and record the write in
- * the dirty log (see fast_page_fault()).
+ * {DEFAULT,EPT}_SPTE_{HOST,MMU}_WRITABLE are used to keep track of why a given
+ * SPTE is write-protected. See is_writable_pte() for details.
*/
/* Bits 9 and 10 are ignored by all non-EPT PTEs. */
-#define DEFAULT_SPTE_HOST_WRITEABLE BIT_ULL(9)
-#define DEFAULT_SPTE_MMU_WRITEABLE BIT_ULL(10)
+#define DEFAULT_SPTE_HOST_WRITABLE BIT_ULL(9)
+#define DEFAULT_SPTE_MMU_WRITABLE BIT_ULL(10)
/*
* Low ignored bits are at a premium for EPT, use high ignored bits, taking care
@@ -339,15 +319,86 @@ static __always_inline bool is_rsvd_spte(struct rsvd_bits_validate *rsvd_check,
__is_rsvd_bits_set(rsvd_check, spte, level);
}
-static inline bool spte_can_locklessly_be_made_writable(u64 spte)
+/*
+ * An shadow-present leaf SPTE may be non-writable for 3 possible reasons:
+ *
+ * 1. To intercept writes for dirty logging. KVM write-protects huge pages
+ * so that they can be split be split down into the dirty logging
+ * granularity (4KiB) whenever the guest writes to them. KVM also
+ * write-protects 4KiB pages so that writes can be recorded in the dirty log
+ * (e.g. if not using PML). SPTEs are write-protected for dirty logging
+ * during the VM-iotcls that enable dirty logging.
+ *
+ * 2. To intercept writes to guest page tables that KVM is shadowing. When a
+ * guest writes to its page table the corresponding shadow page table will
+ * be marked "unsync". That way KVM knows which shadow page tables need to
+ * be updated on the next TLB flush, INVLPG, etc. and which do not.
+ *
+ * 3. To prevent guest writes to read-only memory, such as for memory in a
+ * read-only memslot or guest memory backed by a read-only VMA. Writes to
+ * such pages are disallowed entirely.
+ *
+ * To keep track of why a given SPTE is write-protected, KVM uses 2
+ * software-only bits in the SPTE:
+ *
+ * shadow_mmu_writable_mask, aka MMU-writable -
+ * Cleared on SPTEs that KVM is currently write-protecting for shadow paging
+ * purposes (case 2 above).
+ *
+ * shadow_host_writable_mask, aka Host-writable -
+ * Cleared on SPTEs that are not host-writable (case 3 above)
+ *
+ * Note, not all possible combinations of PT_WRITABLE_MASK,
+ * shadow_mmu_writable_mask, and shadow_host_writable_mask are valid. A given
+ * SPTE can be in only one of the following states, which map to the
+ * aforementioned 3 cases:
+ *
+ * shadow_host_writable_mask | shadow_mmu_writable_mask | PT_WRITABLE_MASK
+ * ------------------------- | ------------------------ | ----------------
+ * 1 | 1 | 1 (writable)
+ * 1 | 1 | 0 (case 1)
+ * 1 | 0 | 0 (case 2)
+ * 0 | 0 | 0 (case 3)
+ *
+ * The valid combinations of these bits are checked by
+ * check_spte_writable_invariants() whenever an SPTE is modified.
+ *
+ * Clearing the MMU-writable bit is always done under the MMU lock and always
+ * accompanied by a TLB flush before dropping the lock to avoid corrupting the
+ * shadow page tables between vCPUs. Write-protecting an SPTE for dirty logging
+ * (which does not clear the MMU-writable bit), does not flush TLBs before
+ * dropping the lock, as it only needs to synchronize guest writes with the
+ * dirty bitmap.
+ *
+ * So, there is the problem: clearing the MMU-writable bit can encounter a
+ * write-protected SPTE while CPUs still have writable mappings for that SPTE
+ * cached in their TLB. To address this, KVM always flushes TLBs when
+ * write-protecting SPTEs if the MMU-writable bit is set on the old SPTE.
+ *
+ * The Host-writable bit is not modified on present SPTEs, it is only set or
+ * cleared when an SPTE is first faulted in from non-present and then remains
+ * immutable.
+ */
+static inline bool is_writable_pte(unsigned long pte)
{
- if (spte & shadow_mmu_writable_mask) {
- WARN_ON_ONCE(!(spte & shadow_host_writable_mask));
- return true;
- }
+ return pte & PT_WRITABLE_MASK;
+}
+
+/* Note: spte must be a shadow-present leaf SPTE. */
+static inline void check_spte_writable_invariants(u64 spte)
+{
+ if (spte & shadow_mmu_writable_mask)
+ WARN_ONCE(!(spte & shadow_host_writable_mask),
+ "kvm: MMU-writable SPTE is not Host-writable: %llx",
+ spte);
+ else
+ WARN_ONCE(is_writable_pte(spte),
+ "kvm: Writable SPTE is not MMU-writable: %llx", spte);
+}
- WARN_ON_ONCE(spte & PT_WRITABLE_MASK);
- return false;
+static inline bool spte_can_locklessly_be_made_writable(u64 spte)
+{
+ return spte & shadow_mmu_writable_mask;
}
static inline u64 get_mmio_spte_generation(u64 spte)
@@ -364,9 +415,25 @@ bool make_spte(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp,
unsigned int pte_access, gfn_t gfn, kvm_pfn_t pfn,
u64 old_spte, bool prefetch, bool can_unsync,
bool host_writable, u64 *new_spte);
+u64 make_huge_page_split_spte(u64 huge_spte, int huge_level, int index);
u64 make_nonleaf_spte(u64 *child_pt, bool ad_disabled);
u64 make_mmio_spte(struct kvm_vcpu *vcpu, u64 gfn, unsigned int access);
u64 mark_spte_for_access_track(u64 spte);
+
+/* Restore an acc-track PTE back to a regular PTE */
+static inline u64 restore_acc_track_spte(u64 spte)
+{
+ u64 saved_bits = (spte >> SHADOW_ACC_TRACK_SAVED_BITS_SHIFT)
+ & SHADOW_ACC_TRACK_SAVED_BITS_MASK;
+
+ spte &= ~shadow_acc_track_mask;
+ spte &= ~(SHADOW_ACC_TRACK_SAVED_BITS_MASK <<
+ SHADOW_ACC_TRACK_SAVED_BITS_SHIFT);
+ spte |= saved_bits;
+
+ return spte;
+}
+
u64 kvm_mmu_changed_pte_notifier_make_spte(u64 old_spte, kvm_pfn_t new_pfn);
void kvm_mmu_reset_all_pte_masks(void);
diff --git a/arch/x86/kvm/mmu/tdp_iter.c b/arch/x86/kvm/mmu/tdp_iter.c
index caa96c270b95..6d3b3e5a5533 100644
--- a/arch/x86/kvm/mmu/tdp_iter.c
+++ b/arch/x86/kvm/mmu/tdp_iter.c
@@ -12,7 +12,7 @@ static void tdp_iter_refresh_sptep(struct tdp_iter *iter)
{
iter->sptep = iter->pt_path[iter->level - 1] +
SHADOW_PT_INDEX(iter->gfn << PAGE_SHIFT, iter->level);
- iter->old_spte = READ_ONCE(*rcu_dereference(iter->sptep));
+ iter->old_spte = kvm_tdp_mmu_read_spte(iter->sptep);
}
static gfn_t round_gfn_for_level(gfn_t gfn, int level)
@@ -40,17 +40,19 @@ void tdp_iter_restart(struct tdp_iter *iter)
* Sets a TDP iterator to walk a pre-order traversal of the paging structure
* rooted at root_pt, starting with the walk to translate next_last_level_gfn.
*/
-void tdp_iter_start(struct tdp_iter *iter, u64 *root_pt, int root_level,
+void tdp_iter_start(struct tdp_iter *iter, struct kvm_mmu_page *root,
int min_level, gfn_t next_last_level_gfn)
{
+ int root_level = root->role.level;
+
WARN_ON(root_level < 1);
WARN_ON(root_level > PT64_ROOT_MAX_LEVEL);
iter->next_last_level_gfn = next_last_level_gfn;
iter->root_level = root_level;
iter->min_level = min_level;
- iter->pt_path[iter->root_level - 1] = (tdp_ptep_t)root_pt;
- iter->as_id = kvm_mmu_page_as_id(sptep_to_sp(root_pt));
+ iter->pt_path[iter->root_level - 1] = (tdp_ptep_t)root->spt;
+ iter->as_id = kvm_mmu_page_as_id(root);
tdp_iter_restart(iter);
}
@@ -87,7 +89,7 @@ static bool try_step_down(struct tdp_iter *iter)
* Reread the SPTE before stepping down to avoid traversing into page
* tables that are no longer linked from this entry.
*/
- iter->old_spte = READ_ONCE(*rcu_dereference(iter->sptep));
+ iter->old_spte = kvm_tdp_mmu_read_spte(iter->sptep);
child_pt = spte_to_child_pt(iter->old_spte, iter->level);
if (!child_pt)
@@ -121,7 +123,7 @@ static bool try_step_side(struct tdp_iter *iter)
iter->gfn += KVM_PAGES_PER_HPAGE(iter->level);
iter->next_last_level_gfn = iter->gfn;
iter->sptep++;
- iter->old_spte = READ_ONCE(*rcu_dereference(iter->sptep));
+ iter->old_spte = kvm_tdp_mmu_read_spte(iter->sptep);
return true;
}
diff --git a/arch/x86/kvm/mmu/tdp_iter.h b/arch/x86/kvm/mmu/tdp_iter.h
index e19cabbcb65c..b1eaf6ec0e0b 100644
--- a/arch/x86/kvm/mmu/tdp_iter.h
+++ b/arch/x86/kvm/mmu/tdp_iter.h
@@ -7,7 +7,20 @@
#include "mmu.h"
-typedef u64 __rcu *tdp_ptep_t;
+/*
+ * TDP MMU SPTEs are RCU protected to allow paging structures (non-leaf SPTEs)
+ * to be zapped while holding mmu_lock for read, and to allow TLB flushes to be
+ * batched without having to collect the list of zapped SPs. Flows that can
+ * remove SPs must service pending TLB flushes prior to dropping RCU protection.
+ */
+static inline u64 kvm_tdp_mmu_read_spte(tdp_ptep_t sptep)
+{
+ return READ_ONCE(*rcu_dereference(sptep));
+}
+static inline void kvm_tdp_mmu_write_spte(tdp_ptep_t sptep, u64 val)
+{
+ WRITE_ONCE(*rcu_dereference(sptep), val);
+}
/*
* A TDP iterator performs a pre-order walk over a TDP paging structure.
@@ -57,17 +70,17 @@ struct tdp_iter {
* Iterates over every SPTE mapping the GFN range [start, end) in a
* preorder traversal.
*/
-#define for_each_tdp_pte_min_level(iter, root, root_level, min_level, start, end) \
- for (tdp_iter_start(&iter, root, root_level, min_level, start); \
+#define for_each_tdp_pte_min_level(iter, root, min_level, start, end) \
+ for (tdp_iter_start(&iter, root, min_level, start); \
iter.valid && iter.gfn < end; \
tdp_iter_next(&iter))
-#define for_each_tdp_pte(iter, root, root_level, start, end) \
- for_each_tdp_pte_min_level(iter, root, root_level, PG_LEVEL_4K, start, end)
+#define for_each_tdp_pte(iter, root, start, end) \
+ for_each_tdp_pte_min_level(iter, root, PG_LEVEL_4K, start, end)
tdp_ptep_t spte_to_child_pt(u64 pte, int level);
-void tdp_iter_start(struct tdp_iter *iter, u64 *root_pt, int root_level,
+void tdp_iter_start(struct tdp_iter *iter, struct kvm_mmu_page *root,
int min_level, gfn_t next_last_level_gfn);
void tdp_iter_next(struct tdp_iter *iter);
void tdp_iter_restart(struct tdp_iter *iter);
diff --git a/arch/x86/kvm/mmu/tdp_mmu.c b/arch/x86/kvm/mmu/tdp_mmu.c
index bc9e3553fba2..e7e7876251b3 100644
--- a/arch/x86/kvm/mmu/tdp_mmu.c
+++ b/arch/x86/kvm/mmu/tdp_mmu.c
@@ -25,17 +25,22 @@ bool kvm_mmu_init_tdp_mmu(struct kvm *kvm)
INIT_LIST_HEAD(&kvm->arch.tdp_mmu_roots);
spin_lock_init(&kvm->arch.tdp_mmu_pages_lock);
INIT_LIST_HEAD(&kvm->arch.tdp_mmu_pages);
+ kvm->arch.tdp_mmu_zap_wq =
+ alloc_workqueue("kvm", WQ_UNBOUND|WQ_MEM_RECLAIM|WQ_CPU_INTENSIVE, 0);
return true;
}
-static __always_inline void kvm_lockdep_assert_mmu_lock_held(struct kvm *kvm,
+/* Arbitrarily returns true so that this may be used in if statements. */
+static __always_inline bool kvm_lockdep_assert_mmu_lock_held(struct kvm *kvm,
bool shared)
{
if (shared)
lockdep_assert_held_read(&kvm->mmu_lock);
else
lockdep_assert_held_write(&kvm->mmu_lock);
+
+ return true;
}
void kvm_mmu_uninit_tdp_mmu(struct kvm *kvm)
@@ -43,20 +48,20 @@ void kvm_mmu_uninit_tdp_mmu(struct kvm *kvm)
if (!kvm->arch.tdp_mmu_enabled)
return;
+ flush_workqueue(kvm->arch.tdp_mmu_zap_wq);
+ destroy_workqueue(kvm->arch.tdp_mmu_zap_wq);
+
WARN_ON(!list_empty(&kvm->arch.tdp_mmu_pages));
WARN_ON(!list_empty(&kvm->arch.tdp_mmu_roots));
/*
* Ensure that all the outstanding RCU callbacks to free shadow pages
- * can run before the VM is torn down.
+ * can run before the VM is torn down. Work items on tdp_mmu_zap_wq
+ * can call kvm_tdp_mmu_put_root and create new callbacks.
*/
rcu_barrier();
}
-static bool zap_gfn_range(struct kvm *kvm, struct kvm_mmu_page *root,
- gfn_t start, gfn_t end, bool can_yield, bool flush,
- bool shared);
-
static void tdp_mmu_free_sp(struct kvm_mmu_page *sp)
{
free_page((unsigned long)sp->spt);
@@ -79,6 +84,56 @@ static void tdp_mmu_free_sp_rcu_callback(struct rcu_head *head)
tdp_mmu_free_sp(sp);
}
+static void tdp_mmu_zap_root(struct kvm *kvm, struct kvm_mmu_page *root,
+ bool shared);
+
+static void tdp_mmu_zap_root_work(struct work_struct *work)
+{
+ struct kvm_mmu_page *root = container_of(work, struct kvm_mmu_page,
+ tdp_mmu_async_work);
+ struct kvm *kvm = root->tdp_mmu_async_data;
+
+ read_lock(&kvm->mmu_lock);
+
+ /*
+ * A TLB flush is not necessary as KVM performs a local TLB flush when
+ * allocating a new root (see kvm_mmu_load()), and when migrating vCPU
+ * to a different pCPU. Note, the local TLB flush on reuse also
+ * invalidates any paging-structure-cache entries, i.e. TLB entries for
+ * intermediate paging structures, that may be zapped, as such entries
+ * are associated with the ASID on both VMX and SVM.
+ */
+ tdp_mmu_zap_root(kvm, root, true);
+
+ /*
+ * Drop the refcount using kvm_tdp_mmu_put_root() to test its logic for
+ * avoiding an infinite loop. By design, the root is reachable while
+ * it's being asynchronously zapped, thus a different task can put its
+ * last reference, i.e. flowing through kvm_tdp_mmu_put_root() for an
+ * asynchronously zapped root is unavoidable.
+ */
+ kvm_tdp_mmu_put_root(kvm, root, true);
+
+ read_unlock(&kvm->mmu_lock);
+}
+
+static void tdp_mmu_schedule_zap_root(struct kvm *kvm, struct kvm_mmu_page *root)
+{
+ root->tdp_mmu_async_data = kvm;
+ INIT_WORK(&root->tdp_mmu_async_work, tdp_mmu_zap_root_work);
+ queue_work(kvm->arch.tdp_mmu_zap_wq, &root->tdp_mmu_async_work);
+}
+
+static inline bool kvm_tdp_root_mark_invalid(struct kvm_mmu_page *page)
+{
+ union kvm_mmu_page_role role = page->role;
+ role.invalid = true;
+
+ /* No need to use cmpxchg, only the invalid bit can change. */
+ role.word = xchg(&page->role.word, role.word);
+ return role.invalid;
+}
+
void kvm_tdp_mmu_put_root(struct kvm *kvm, struct kvm_mmu_page *root,
bool shared)
{
@@ -89,25 +144,63 @@ void kvm_tdp_mmu_put_root(struct kvm *kvm, struct kvm_mmu_page *root,
WARN_ON(!root->tdp_mmu_page);
+ /*
+ * The root now has refcount=0. It is valid, but readers already
+ * cannot acquire a reference to it because kvm_tdp_mmu_get_root()
+ * rejects it. This remains true for the rest of the execution
+ * of this function, because readers visit valid roots only
+ * (except for tdp_mmu_zap_root_work(), which however
+ * does not acquire any reference itself).
+ *
+ * Even though there are flows that need to visit all roots for
+ * correctness, they all take mmu_lock for write, so they cannot yet
+ * run concurrently. The same is true after kvm_tdp_root_mark_invalid,
+ * since the root still has refcount=0.
+ *
+ * However, tdp_mmu_zap_root can yield, and writers do not expect to
+ * see refcount=0 (see for example kvm_tdp_mmu_invalidate_all_roots()).
+ * So the root temporarily gets an extra reference, going to refcount=1
+ * while staying invalid. Readers still cannot acquire any reference;
+ * but writers are now allowed to run if tdp_mmu_zap_root yields and
+ * they might take an extra reference if they themselves yield.
+ * Therefore, when the reference is given back by the worker,
+ * there is no guarantee that the refcount is still 1. If not, whoever
+ * puts the last reference will free the page, but they will not have to
+ * zap the root because a root cannot go from invalid to valid.
+ */
+ if (!kvm_tdp_root_mark_invalid(root)) {
+ refcount_set(&root->tdp_mmu_root_count, 1);
+
+ /*
+ * Zapping the root in a worker is not just "nice to have";
+ * it is required because kvm_tdp_mmu_invalidate_all_roots()
+ * skips already-invalid roots. If kvm_tdp_mmu_put_root() did
+ * not add the root to the workqueue, kvm_tdp_mmu_zap_all_fast()
+ * might return with some roots not zapped yet.
+ */
+ tdp_mmu_schedule_zap_root(kvm, root);
+ return;
+ }
+
spin_lock(&kvm->arch.tdp_mmu_pages_lock);
list_del_rcu(&root->link);
spin_unlock(&kvm->arch.tdp_mmu_pages_lock);
-
- zap_gfn_range(kvm, root, 0, -1ull, false, false, shared);
-
call_rcu(&root->rcu_head, tdp_mmu_free_sp_rcu_callback);
}
/*
- * Finds the next valid root after root (or the first valid root if root
- * is NULL), takes a reference on it, and returns that next root. If root
- * is not NULL, this thread should have already taken a reference on it, and
- * that reference will be dropped. If no valid root is found, this
- * function will return NULL.
+ * Returns the next root after @prev_root (or the first root if @prev_root is
+ * NULL). A reference to the returned root is acquired, and the reference to
+ * @prev_root is released (the caller obviously must hold a reference to
+ * @prev_root if it's non-NULL).
+ *
+ * If @only_valid is true, invalid roots are skipped.
+ *
+ * Returns NULL if the end of tdp_mmu_roots was reached.
*/
static struct kvm_mmu_page *tdp_mmu_next_root(struct kvm *kvm,
struct kvm_mmu_page *prev_root,
- bool shared)
+ bool shared, bool only_valid)
{
struct kvm_mmu_page *next_root;
@@ -121,9 +214,14 @@ static struct kvm_mmu_page *tdp_mmu_next_root(struct kvm *kvm,
next_root = list_first_or_null_rcu(&kvm->arch.tdp_mmu_roots,
typeof(*next_root), link);
- while (next_root && !kvm_tdp_mmu_get_root(kvm, next_root))
+ while (next_root) {
+ if ((!only_valid || !next_root->role.invalid) &&
+ kvm_tdp_mmu_get_root(next_root))
+ break;
+
next_root = list_next_or_null_rcu(&kvm->arch.tdp_mmu_roots,
&next_root->link, typeof(*next_root), link);
+ }
rcu_read_unlock();
@@ -143,71 +241,91 @@ static struct kvm_mmu_page *tdp_mmu_next_root(struct kvm *kvm,
* mode. In the unlikely event that this thread must free a root, the lock
* will be temporarily dropped and reacquired in write mode.
*/
-#define for_each_tdp_mmu_root_yield_safe(_kvm, _root, _as_id, _shared) \
- for (_root = tdp_mmu_next_root(_kvm, NULL, _shared); \
- _root; \
- _root = tdp_mmu_next_root(_kvm, _root, _shared)) \
- if (kvm_mmu_page_as_id(_root) != _as_id) { \
- } else
-
-#define for_each_tdp_mmu_root(_kvm, _root, _as_id) \
- list_for_each_entry_rcu(_root, &_kvm->arch.tdp_mmu_roots, link, \
- lockdep_is_held_type(&kvm->mmu_lock, 0) || \
- lockdep_is_held(&kvm->arch.tdp_mmu_pages_lock)) \
- if (kvm_mmu_page_as_id(_root) != _as_id) { \
+#define __for_each_tdp_mmu_root_yield_safe(_kvm, _root, _as_id, _shared, _only_valid)\
+ for (_root = tdp_mmu_next_root(_kvm, NULL, _shared, _only_valid); \
+ _root; \
+ _root = tdp_mmu_next_root(_kvm, _root, _shared, _only_valid)) \
+ if (kvm_lockdep_assert_mmu_lock_held(_kvm, _shared) && \
+ kvm_mmu_page_as_id(_root) != _as_id) { \
} else
-static union kvm_mmu_page_role page_role_for_level(struct kvm_vcpu *vcpu,
- int level)
-{
- union kvm_mmu_page_role role;
+#define for_each_valid_tdp_mmu_root_yield_safe(_kvm, _root, _as_id, _shared) \
+ __for_each_tdp_mmu_root_yield_safe(_kvm, _root, _as_id, _shared, true)
- role = vcpu->arch.mmu->mmu_role.base;
- role.level = level;
- role.direct = true;
- role.has_4_byte_gpte = false;
- role.access = ACC_ALL;
- role.ad_disabled = !shadow_accessed_mask;
+#define for_each_tdp_mmu_root_yield_safe(_kvm, _root, _as_id) \
+ __for_each_tdp_mmu_root_yield_safe(_kvm, _root, _as_id, false, false)
- return role;
-}
+/*
+ * Iterate over all TDP MMU roots. Requires that mmu_lock be held for write,
+ * the implication being that any flow that holds mmu_lock for read is
+ * inherently yield-friendly and should use the yield-safe variant above.
+ * 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) { \
+ } else
-static struct kvm_mmu_page *alloc_tdp_mmu_page(struct kvm_vcpu *vcpu, gfn_t gfn,
- int level)
+static struct kvm_mmu_page *tdp_mmu_alloc_sp(struct kvm_vcpu *vcpu)
{
struct kvm_mmu_page *sp;
sp = kvm_mmu_memory_cache_alloc(&vcpu->arch.mmu_page_header_cache);
sp->spt = kvm_mmu_memory_cache_alloc(&vcpu->arch.mmu_shadow_page_cache);
+
+ return sp;
+}
+
+static void tdp_mmu_init_sp(struct kvm_mmu_page *sp, tdp_ptep_t sptep,
+ gfn_t gfn, union kvm_mmu_page_role role)
+{
set_page_private(virt_to_page(sp->spt), (unsigned long)sp);
- sp->role.word = page_role_for_level(vcpu, level).word;
+ sp->role = role;
sp->gfn = gfn;
+ sp->ptep = sptep;
sp->tdp_mmu_page = true;
trace_kvm_mmu_get_page(sp, true);
+}
- return sp;
+static void tdp_mmu_init_child_sp(struct kvm_mmu_page *child_sp,
+ struct tdp_iter *iter)
+{
+ struct kvm_mmu_page *parent_sp;
+ union kvm_mmu_page_role role;
+
+ parent_sp = sptep_to_sp(rcu_dereference(iter->sptep));
+
+ role = parent_sp->role;
+ role.level--;
+
+ tdp_mmu_init_sp(child_sp, iter->sptep, iter->gfn, role);
}
hpa_t kvm_tdp_mmu_get_vcpu_root_hpa(struct kvm_vcpu *vcpu)
{
- union kvm_mmu_page_role role;
+ union kvm_mmu_page_role role = vcpu->arch.mmu->mmu_role.base;
struct kvm *kvm = vcpu->kvm;
struct kvm_mmu_page *root;
lockdep_assert_held_write(&kvm->mmu_lock);
- role = page_role_for_level(vcpu, vcpu->arch.mmu->shadow_root_level);
-
- /* Check for an existing root before allocating a new one. */
+ /*
+ * Check for an existing root before allocating a new one. Note, the
+ * role check prevents consuming an invalid root.
+ */
for_each_tdp_mmu_root(kvm, root, kvm_mmu_role_as_id(role)) {
if (root->role.word == role.word &&
- kvm_tdp_mmu_get_root(kvm, root))
+ kvm_tdp_mmu_get_root(root))
goto out;
}
- root = alloc_tdp_mmu_page(vcpu, 0, vcpu->arch.mmu->shadow_root_level);
+ root = tdp_mmu_alloc_sp(vcpu);
+ tdp_mmu_init_sp(root, NULL, 0, role);
+
refcount_set(&root->tdp_mmu_root_count, 1);
spin_lock(&kvm->arch.tdp_mmu_pages_lock);
@@ -252,25 +370,7 @@ static void handle_changed_spte_dirty_log(struct kvm *kvm, int as_id, gfn_t gfn,
}
/**
- * tdp_mmu_link_page - Add a new page to the list of pages used by the TDP MMU
- *
- * @kvm: kvm instance
- * @sp: the new page
- * @account_nx: This page replaces a NX large page and should be marked for
- * eventual reclaim.
- */
-static void tdp_mmu_link_page(struct kvm *kvm, struct kvm_mmu_page *sp,
- bool account_nx)
-{
- spin_lock(&kvm->arch.tdp_mmu_pages_lock);
- list_add(&sp->link, &kvm->arch.tdp_mmu_pages);
- if (account_nx)
- account_huge_nx_page(kvm, sp);
- spin_unlock(&kvm->arch.tdp_mmu_pages_lock);
-}
-
-/**
- * tdp_mmu_unlink_page - Remove page from the list of pages used by the TDP MMU
+ * tdp_mmu_unlink_sp() - Remove a shadow page from the list of used pages
*
* @kvm: kvm instance
* @sp: the page to be removed
@@ -278,8 +378,8 @@ static void tdp_mmu_link_page(struct kvm *kvm, struct kvm_mmu_page *sp,
* the MMU lock and the operation must synchronize with other
* threads that might be adding or removing pages.
*/
-static void tdp_mmu_unlink_page(struct kvm *kvm, struct kvm_mmu_page *sp,
- bool shared)
+static void tdp_mmu_unlink_sp(struct kvm *kvm, struct kvm_mmu_page *sp,
+ bool shared)
{
if (shared)
spin_lock(&kvm->arch.tdp_mmu_pages_lock);
@@ -295,7 +395,7 @@ static void tdp_mmu_unlink_page(struct kvm *kvm, struct kvm_mmu_page *sp,
}
/**
- * handle_removed_tdp_mmu_page - handle a pt removed from the TDP structure
+ * handle_removed_pt() - handle a page table removed from the TDP structure
*
* @kvm: kvm instance
* @pt: the page removed from the paging structure
@@ -311,8 +411,7 @@ static void tdp_mmu_unlink_page(struct kvm *kvm, struct kvm_mmu_page *sp,
* this thread will be responsible for ensuring the page is freed. Hence the
* early rcu_dereferences in the function.
*/
-static void handle_removed_tdp_mmu_page(struct kvm *kvm, tdp_ptep_t pt,
- bool shared)
+static void handle_removed_pt(struct kvm *kvm, tdp_ptep_t pt, bool shared)
{
struct kvm_mmu_page *sp = sptep_to_sp(rcu_dereference(pt));
int level = sp->role.level;
@@ -321,7 +420,7 @@ static void handle_removed_tdp_mmu_page(struct kvm *kvm, tdp_ptep_t pt,
trace_kvm_mmu_prepare_zap_page(sp);
- tdp_mmu_unlink_page(kvm, sp, shared);
+ tdp_mmu_unlink_sp(kvm, sp, shared);
for (i = 0; i < PT64_ENT_PER_PAGE; i++) {
u64 *sptep = rcu_dereference(pt) + i;
@@ -372,9 +471,6 @@ static void handle_removed_tdp_mmu_page(struct kvm *kvm, tdp_ptep_t pt,
shared);
}
- kvm_flush_remote_tlbs_with_address(kvm, base_gfn,
- KVM_PAGES_PER_HPAGE(level + 1));
-
call_rcu(&sp->rcu_head, tdp_mmu_free_sp_rcu_callback);
}
@@ -435,6 +531,9 @@ static void __handle_changed_spte(struct kvm *kvm, int as_id, gfn_t gfn,
trace_kvm_tdp_mmu_spte_changed(as_id, gfn, level, old_spte, new_spte);
+ if (is_leaf)
+ check_spte_writable_invariants(new_spte);
+
/*
* The only times a SPTE should be changed from a non-present to
* non-present state is when an MMIO entry is installed/modified/
@@ -469,11 +568,13 @@ static void __handle_changed_spte(struct kvm *kvm, int as_id, gfn_t gfn,
/*
* Recursively handle child PTs if the change removed a subtree from
- * the paging structure.
+ * the paging structure. Note the WARN on the PFN changing without the
+ * SPTE being converted to a hugepage (leaf) or being zapped. Shadow
+ * pages are kernel allocations and should never be migrated.
*/
- if (was_present && !was_leaf && (pfn_changed || !is_present))
- handle_removed_tdp_mmu_page(kvm,
- spte_to_child_pt(old_spte, level), shared);
+ if (was_present && !was_leaf &&
+ (is_leaf || !is_present || WARN_ON_ONCE(pfn_changed)))
+ handle_removed_pt(kvm, spte_to_child_pt(old_spte, level), shared);
}
static void handle_changed_spte(struct kvm *kvm, int as_id, gfn_t gfn,
@@ -492,53 +593,72 @@ static void handle_changed_spte(struct kvm *kvm, int as_id, gfn_t gfn,
* and handle the associated bookkeeping. Do not mark the page dirty
* in KVM's dirty bitmaps.
*
+ * If setting the SPTE fails because it has changed, iter->old_spte will be
+ * refreshed to the current value of the spte.
+ *
* @kvm: kvm instance
* @iter: a tdp_iter instance currently on the SPTE that should be set
* @new_spte: The value the SPTE should be set to
- * Returns: true if the SPTE was set, false if it was not. If false is returned,
- * this function will have no side-effects.
+ * Return:
+ * * 0 - If the SPTE was set.
+ * * -EBUSY - If the SPTE cannot be set. In this case this function will have
+ * no side-effects other than setting iter->old_spte to the last
+ * known value of the spte.
*/
-static inline bool tdp_mmu_set_spte_atomic(struct kvm *kvm,
- struct tdp_iter *iter,
- u64 new_spte)
+static inline int tdp_mmu_set_spte_atomic(struct kvm *kvm,
+ struct tdp_iter *iter,
+ u64 new_spte)
{
- WARN_ON_ONCE(iter->yielded);
-
- lockdep_assert_held_read(&kvm->mmu_lock);
+ u64 *sptep = rcu_dereference(iter->sptep);
+ u64 old_spte;
/*
- * Do not change removed SPTEs. Only the thread that froze the SPTE
- * may modify it.
+ * The caller is responsible for ensuring the old SPTE is not a REMOVED
+ * SPTE. KVM should never attempt to zap or manipulate a REMOVED SPTE,
+ * and pre-checking before inserting a new SPTE is advantageous as it
+ * avoids unnecessary work.
*/
- if (is_removed_spte(iter->old_spte))
- return false;
+ WARN_ON_ONCE(iter->yielded || is_removed_spte(iter->old_spte));
+
+ lockdep_assert_held_read(&kvm->mmu_lock);
/*
* Note, fast_pf_fix_direct_spte() can also modify TDP MMU SPTEs and
* does not hold the mmu_lock.
*/
- if (cmpxchg64(rcu_dereference(iter->sptep), iter->old_spte,
- new_spte) != iter->old_spte)
- return false;
+ old_spte = cmpxchg64(sptep, iter->old_spte, new_spte);
+ if (old_spte != iter->old_spte) {
+ /*
+ * The page table entry was modified by a different logical
+ * CPU. Refresh iter->old_spte with the current value so the
+ * caller operates on fresh data, e.g. if it retries
+ * tdp_mmu_set_spte_atomic().
+ */
+ iter->old_spte = old_spte;
+ return -EBUSY;
+ }
__handle_changed_spte(kvm, iter->as_id, iter->gfn, iter->old_spte,
new_spte, iter->level, true);
handle_changed_spte_acc_track(iter->old_spte, new_spte, iter->level);
- return true;
+ return 0;
}
-static inline bool tdp_mmu_zap_spte_atomic(struct kvm *kvm,
- struct tdp_iter *iter)
+static inline int tdp_mmu_zap_spte_atomic(struct kvm *kvm,
+ struct tdp_iter *iter)
{
+ int ret;
+
/*
* Freeze the SPTE by setting it to a special,
* non-present value. This will stop other threads from
* immediately installing a present entry in its place
* before the TLBs are flushed.
*/
- if (!tdp_mmu_set_spte_atomic(kvm, iter, REMOVED_SPTE))
- return false;
+ ret = tdp_mmu_set_spte_atomic(kvm, iter, REMOVED_SPTE);
+ if (ret)
+ return ret;
kvm_flush_remote_tlbs_with_address(kvm, iter->gfn,
KVM_PAGES_PER_HPAGE(iter->level));
@@ -551,17 +671,21 @@ static inline bool tdp_mmu_zap_spte_atomic(struct kvm *kvm,
* here since the SPTE is going from non-present
* to non-present.
*/
- WRITE_ONCE(*rcu_dereference(iter->sptep), 0);
+ kvm_tdp_mmu_write_spte(iter->sptep, 0);
- return true;
+ return 0;
}
/*
* __tdp_mmu_set_spte - Set a TDP MMU SPTE and handle the associated bookkeeping
- * @kvm: kvm instance
- * @iter: a tdp_iter instance currently on the SPTE that should be set
- * @new_spte: The value the SPTE should be set to
+ * @kvm: KVM instance
+ * @as_id: Address space ID, i.e. regular vs. SMM
+ * @sptep: Pointer to the SPTE
+ * @old_spte: The current value of the SPTE
+ * @new_spte: The new value that will be set for the SPTE
+ * @gfn: The base GFN that was (or will be) mapped by the SPTE
+ * @level: The level _containing_ the SPTE (its parent PT's level)
* @record_acc_track: Notify the MM subsystem of changes to the accessed state
* of the page. Should be set unless handling an MMU
* notifier for access tracking. Leaving record_acc_track
@@ -573,58 +697,65 @@ static inline bool tdp_mmu_zap_spte_atomic(struct kvm *kvm,
* Leaving record_dirty_log unset in that case prevents page
* writes from being double counted.
*/
-static inline void __tdp_mmu_set_spte(struct kvm *kvm, struct tdp_iter *iter,
- u64 new_spte, bool record_acc_track,
- bool record_dirty_log)
+static void __tdp_mmu_set_spte(struct kvm *kvm, int as_id, tdp_ptep_t sptep,
+ u64 old_spte, u64 new_spte, gfn_t gfn, int level,
+ bool record_acc_track, bool record_dirty_log)
{
- WARN_ON_ONCE(iter->yielded);
-
lockdep_assert_held_write(&kvm->mmu_lock);
/*
- * No thread should be using this function to set SPTEs to the
+ * No thread should be using this function to set SPTEs to or from the
* temporary removed SPTE value.
* If operating under the MMU lock in read mode, tdp_mmu_set_spte_atomic
* should be used. If operating under the MMU lock in write mode, the
* use of the removed SPTE should not be necessary.
*/
- WARN_ON(is_removed_spte(iter->old_spte));
+ WARN_ON(is_removed_spte(old_spte) || is_removed_spte(new_spte));
- WRITE_ONCE(*rcu_dereference(iter->sptep), new_spte);
+ kvm_tdp_mmu_write_spte(sptep, new_spte);
+
+ __handle_changed_spte(kvm, as_id, gfn, old_spte, new_spte, level, false);
- __handle_changed_spte(kvm, iter->as_id, iter->gfn, iter->old_spte,
- new_spte, iter->level, false);
if (record_acc_track)
- handle_changed_spte_acc_track(iter->old_spte, new_spte,
- iter->level);
+ handle_changed_spte_acc_track(old_spte, new_spte, level);
if (record_dirty_log)
- handle_changed_spte_dirty_log(kvm, iter->as_id, iter->gfn,
- iter->old_spte, new_spte,
- iter->level);
+ handle_changed_spte_dirty_log(kvm, as_id, gfn, old_spte,
+ new_spte, level);
+}
+
+static inline void _tdp_mmu_set_spte(struct kvm *kvm, struct tdp_iter *iter,
+ u64 new_spte, bool record_acc_track,
+ bool record_dirty_log)
+{
+ WARN_ON_ONCE(iter->yielded);
+
+ __tdp_mmu_set_spte(kvm, iter->as_id, iter->sptep, iter->old_spte,
+ new_spte, iter->gfn, iter->level,
+ record_acc_track, record_dirty_log);
}
static inline void tdp_mmu_set_spte(struct kvm *kvm, struct tdp_iter *iter,
u64 new_spte)
{
- __tdp_mmu_set_spte(kvm, iter, new_spte, true, true);
+ _tdp_mmu_set_spte(kvm, iter, new_spte, true, true);
}
static inline void tdp_mmu_set_spte_no_acc_track(struct kvm *kvm,
struct tdp_iter *iter,
u64 new_spte)
{
- __tdp_mmu_set_spte(kvm, iter, new_spte, false, true);
+ _tdp_mmu_set_spte(kvm, iter, new_spte, false, true);
}
static inline void tdp_mmu_set_spte_no_dirty_log(struct kvm *kvm,
struct tdp_iter *iter,
u64 new_spte)
{
- __tdp_mmu_set_spte(kvm, iter, new_spte, true, false);
+ _tdp_mmu_set_spte(kvm, iter, new_spte, true, false);
}
#define tdp_root_for_each_pte(_iter, _root, _start, _end) \
- for_each_tdp_pte(_iter, _root->spt, _root->role.level, _start, _end)
+ for_each_tdp_pte(_iter, _root, _start, _end)
#define tdp_root_for_each_leaf_pte(_iter, _root, _start, _end) \
tdp_root_for_each_pte(_iter, _root, _start, _end) \
@@ -634,8 +765,7 @@ static inline void tdp_mmu_set_spte_no_dirty_log(struct kvm *kvm,
else
#define tdp_mmu_for_each_pte(_iter, _mmu, _start, _end) \
- for_each_tdp_pte(_iter, __va(_mmu->root_hpa), \
- _mmu->shadow_root_level, _start, _end)
+ for_each_tdp_pte(_iter, to_shadow_page(_mmu->root.hpa), _start, _end)
/*
* Yield if the MMU lock is contended or this thread needs to return control
@@ -662,11 +792,11 @@ static inline bool __must_check tdp_mmu_iter_cond_resched(struct kvm *kvm,
return false;
if (need_resched() || rwlock_needbreak(&kvm->mmu_lock)) {
- rcu_read_unlock();
-
if (flush)
kvm_flush_remote_tlbs(kvm);
+ rcu_read_unlock();
+
if (shared)
cond_resched_rwlock_read(&kvm->mmu_lock);
else
@@ -682,6 +812,99 @@ static inline bool __must_check tdp_mmu_iter_cond_resched(struct kvm *kvm,
return iter->yielded;
}
+static inline gfn_t tdp_mmu_max_gfn_host(void)
+{
+ /*
+ * Bound TDP MMU walks at host.MAXPHYADDR, guest accesses beyond that
+ * will hit a #PF(RSVD) and never hit an EPT Violation/Misconfig / #NPF,
+ * and so KVM will never install a SPTE for such addresses.
+ */
+ return 1ULL << (shadow_phys_bits - PAGE_SHIFT);
+}
+
+static void __tdp_mmu_zap_root(struct kvm *kvm, struct kvm_mmu_page *root,
+ bool shared, int zap_level)
+{
+ struct tdp_iter iter;
+
+ gfn_t end = tdp_mmu_max_gfn_host();
+ gfn_t start = 0;
+
+ for_each_tdp_pte_min_level(iter, root, zap_level, start, end) {
+retry:
+ if (tdp_mmu_iter_cond_resched(kvm, &iter, false, shared))
+ continue;
+
+ if (!is_shadow_present_pte(iter.old_spte))
+ continue;
+
+ if (iter.level > zap_level)
+ continue;
+
+ if (!shared)
+ tdp_mmu_set_spte(kvm, &iter, 0);
+ else if (tdp_mmu_set_spte_atomic(kvm, &iter, 0))
+ goto retry;
+ }
+}
+
+static void tdp_mmu_zap_root(struct kvm *kvm, struct kvm_mmu_page *root,
+ bool shared)
+{
+
+ /*
+ * The root must have an elevated refcount so that it's reachable via
+ * mmu_notifier callbacks, which allows this path to yield and drop
+ * mmu_lock. When handling an unmap/release mmu_notifier command, KVM
+ * must drop all references to relevant pages prior to completing the
+ * callback. Dropping mmu_lock with an unreachable root would result
+ * in zapping SPTEs after a relevant mmu_notifier callback completes
+ * and lead to use-after-free as zapping a SPTE triggers "writeback" of
+ * dirty accessed bits to the SPTE's associated struct page.
+ */
+ WARN_ON_ONCE(!refcount_read(&root->tdp_mmu_root_count));
+
+ kvm_lockdep_assert_mmu_lock_held(kvm, shared);
+
+ 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.
+ *
+ * Because zapping a SP recurses on its children, stepping down to
+ * PG_LEVEL_4K in the iterator itself is unnecessary.
+ */
+ __tdp_mmu_zap_root(kvm, root, shared, PG_LEVEL_1G);
+ __tdp_mmu_zap_root(kvm, root, shared, root->role.level);
+
+ rcu_read_unlock();
+}
+
+bool kvm_tdp_mmu_zap_sp(struct kvm *kvm, struct kvm_mmu_page *sp)
+{
+ u64 old_spte;
+
+ /*
+ * This helper intentionally doesn't allow zapping a root shadow page,
+ * which doesn't have a parent page table and thus no associated entry.
+ */
+ if (WARN_ON_ONCE(!sp->ptep))
+ return false;
+
+ old_spte = kvm_tdp_mmu_read_spte(sp->ptep);
+ if (WARN_ON_ONCE(!is_shadow_present_pte(old_spte)))
+ return false;
+
+ __tdp_mmu_set_spte(kvm, kvm_mmu_page_as_id(sp), sp->ptep, old_spte, 0,
+ sp->gfn, sp->role.level + 1, true, true);
+
+ return true;
+}
+
/*
* Tears down the mappings for the range of gfns, [start, end), and frees the
* non-root pages mapping GFNs strictly within that range. Returns true if
@@ -693,18 +916,11 @@ static inline bool __must_check tdp_mmu_iter_cond_resched(struct kvm *kvm,
* function cannot yield, it will not release the MMU lock or reschedule and
* the caller must ensure it does not supply too large a GFN range, or the
* operation can cause a soft lockup.
- *
- * If shared is true, this thread holds the MMU lock in read mode and must
- * account for the possibility that other threads are modifying the paging
- * structures concurrently. If shared is false, this thread should hold the
- * MMU lock in write mode.
*/
static bool zap_gfn_range(struct kvm *kvm, struct kvm_mmu_page *root,
- gfn_t start, gfn_t end, bool can_yield, bool flush,
- bool shared)
+ gfn_t start, gfn_t end, bool can_yield, bool flush)
{
- gfn_t max_gfn_host = 1ULL << (shadow_phys_bits - PAGE_SHIFT);
- bool zap_all = (start == 0 && end >= max_gfn_host);
+ bool zap_all = (start == 0 && end >= tdp_mmu_max_gfn_host());
struct tdp_iter iter;
/*
@@ -713,22 +929,15 @@ static bool zap_gfn_range(struct kvm *kvm, struct kvm_mmu_page *root,
*/
int min_level = zap_all ? root->role.level : PG_LEVEL_4K;
- /*
- * Bound the walk at host.MAXPHYADDR, guest accesses beyond that will
- * hit a #PF(RSVD) and never get to an EPT Violation/Misconfig / #NPF,
- * and so KVM will never install a SPTE for such addresses.
- */
- end = min(end, max_gfn_host);
+ end = min(end, tdp_mmu_max_gfn_host());
- kvm_lockdep_assert_mmu_lock_held(kvm, shared);
+ lockdep_assert_held_write(&kvm->mmu_lock);
rcu_read_lock();
- for_each_tdp_pte_min_level(iter, root->spt, root->role.level,
- min_level, start, end) {
-retry:
+ for_each_tdp_pte_min_level(iter, root, min_level, start, end) {
if (can_yield &&
- tdp_mmu_iter_cond_resched(kvm, &iter, flush, shared)) {
+ tdp_mmu_iter_cond_resched(kvm, &iter, flush, false)) {
flush = false;
continue;
}
@@ -747,21 +956,21 @@ retry:
!is_last_spte(iter.old_spte, iter.level))
continue;
- if (!shared) {
- tdp_mmu_set_spte(kvm, &iter, 0);
- flush = true;
- } else if (!tdp_mmu_zap_spte_atomic(kvm, &iter)) {
- /*
- * The iter must explicitly re-read the SPTE because
- * the atomic cmpxchg failed.
- */
- iter.old_spte = READ_ONCE(*rcu_dereference(iter.sptep));
- goto retry;
- }
+ tdp_mmu_set_spte(kvm, &iter, 0);
+ flush = true;
}
+ /*
+ * Need to flush before releasing RCU. TODO: do it only if intermediate
+ * page tables were zapped; there is no need to flush under RCU protection
+ * if no 'struct kvm_mmu_page' is freed.
+ */
+ if (flush)
+ kvm_flush_remote_tlbs_with_address(kvm, start, end - start);
+
rcu_read_unlock();
- return flush;
+
+ return false;
}
/*
@@ -775,107 +984,57 @@ bool __kvm_tdp_mmu_zap_gfn_range(struct kvm *kvm, int as_id, gfn_t start,
{
struct kvm_mmu_page *root;
- for_each_tdp_mmu_root_yield_safe(kvm, root, as_id, false)
- flush = zap_gfn_range(kvm, root, start, end, can_yield, flush,
- false);
+ for_each_tdp_mmu_root_yield_safe(kvm, root, as_id)
+ flush = zap_gfn_range(kvm, root, start, end, can_yield, flush);
return flush;
}
void kvm_tdp_mmu_zap_all(struct kvm *kvm)
{
- bool flush = false;
+ struct kvm_mmu_page *root;
int i;
- for (i = 0; i < KVM_ADDRESS_SPACE_NUM; i++)
- flush = kvm_tdp_mmu_zap_gfn_range(kvm, i, 0, -1ull, flush);
-
- if (flush)
- kvm_flush_remote_tlbs(kvm);
-}
-
-static struct kvm_mmu_page *next_invalidated_root(struct kvm *kvm,
- struct kvm_mmu_page *prev_root)
-{
- struct kvm_mmu_page *next_root;
-
- if (prev_root)
- next_root = list_next_or_null_rcu(&kvm->arch.tdp_mmu_roots,
- &prev_root->link,
- typeof(*prev_root), link);
- else
- next_root = list_first_or_null_rcu(&kvm->arch.tdp_mmu_roots,
- typeof(*next_root), link);
-
- while (next_root && !(next_root->role.invalid &&
- refcount_read(&next_root->tdp_mmu_root_count)))
- next_root = list_next_or_null_rcu(&kvm->arch.tdp_mmu_roots,
- &next_root->link,
- typeof(*next_root), link);
-
- return next_root;
+ /*
+ * Zap all roots, including invalid roots, as all SPTEs must be dropped
+ * before returning to the caller. Zap directly even if the root is
+ * also being zapped by a worker. Walking zapped top-level SPTEs isn't
+ * all that expensive and mmu_lock is already held, which means the
+ * worker has yielded, i.e. flushing the work instead of zapping here
+ * isn't guaranteed to be any faster.
+ *
+ * A TLB flush is unnecessary, KVM zaps everything if and only the VM
+ * is being destroyed or the userspace VMM has exited. In both cases,
+ * KVM_RUN is unreachable, i.e. no vCPUs will ever service the request.
+ */
+ for (i = 0; i < KVM_ADDRESS_SPACE_NUM; i++) {
+ for_each_tdp_mmu_root_yield_safe(kvm, root, i)
+ tdp_mmu_zap_root(kvm, root, false);
+ }
}
/*
- * Since kvm_tdp_mmu_zap_all_fast has acquired a reference to each
- * invalidated root, they will not be freed until this function drops the
- * reference. Before dropping that reference, tear down the paging
- * structure so that whichever thread does drop the last reference
- * only has to do a trivial amount of work. Since the roots are invalid,
- * no new SPTEs should be created under them.
+ * Zap all invalidated roots to ensure all SPTEs are dropped before the "fast
+ * zap" completes.
*/
void kvm_tdp_mmu_zap_invalidated_roots(struct kvm *kvm)
{
- struct kvm_mmu_page *next_root;
- struct kvm_mmu_page *root;
- bool flush = false;
-
- lockdep_assert_held_read(&kvm->mmu_lock);
-
- rcu_read_lock();
-
- root = next_invalidated_root(kvm, NULL);
-
- while (root) {
- next_root = next_invalidated_root(kvm, root);
-
- rcu_read_unlock();
-
- flush = zap_gfn_range(kvm, root, 0, -1ull, true, flush, true);
-
- /*
- * Put the reference acquired in
- * kvm_tdp_mmu_invalidate_roots
- */
- kvm_tdp_mmu_put_root(kvm, root, true);
-
- root = next_root;
-
- rcu_read_lock();
- }
-
- rcu_read_unlock();
-
- if (flush)
- kvm_flush_remote_tlbs(kvm);
+ flush_workqueue(kvm->arch.tdp_mmu_zap_wq);
}
/*
- * Mark each TDP MMU root as invalid so that other threads
- * will drop their references and allow the root count to
- * go to 0.
+ * Mark each TDP MMU root as invalid to prevent vCPUs from reusing a root that
+ * is about to be zapped, e.g. in response to a memslots update. The actual
+ * zapping is performed asynchronously, so a reference is taken on all roots.
+ * Using a separate workqueue makes it easy to ensure that the destruction is
+ * performed before the "fast zap" completes, without keeping a separate list
+ * of invalidated roots; the list is effectively the list of work items in
+ * the workqueue.
*
- * Also take a reference on all roots so that this thread
- * can do the bulk of the work required to free the roots
- * once they are invalidated. Without this reference, a
- * vCPU thread might drop the last reference to a root and
- * get stuck with tearing down the entire paging structure.
- *
- * Roots which have a zero refcount should be skipped as
- * they're already being torn down.
- * Already invalid roots should be referenced again so that
- * they aren't freed before kvm_tdp_mmu_zap_all_fast is
- * done with them.
+ * Get a reference even if the root is already invalid, the asynchronous worker
+ * assumes it was gifted a reference to the root it processes. Because mmu_lock
+ * is held for write, it should be impossible to observe a root with zero refcount,
+ * i.e. the list of roots cannot be stale.
*
* This has essentially the same effect for the TDP MMU
* as updating mmu_valid_gen does for the shadow MMU.
@@ -885,9 +1044,13 @@ void kvm_tdp_mmu_invalidate_all_roots(struct kvm *kvm)
struct kvm_mmu_page *root;
lockdep_assert_held_write(&kvm->mmu_lock);
- list_for_each_entry(root, &kvm->arch.tdp_mmu_roots, link)
- if (refcount_inc_not_zero(&root->tdp_mmu_root_count))
+ list_for_each_entry(root, &kvm->arch.tdp_mmu_roots, link) {
+ if (!root->role.invalid &&
+ !WARN_ON_ONCE(!kvm_tdp_mmu_get_root(root))) {
root->role.invalid = true;
+ tdp_mmu_schedule_zap_root(kvm, root);
+ }
+ }
}
/*
@@ -913,8 +1076,12 @@ static int tdp_mmu_map_handle_target_level(struct kvm_vcpu *vcpu,
if (new_spte == iter->old_spte)
ret = RET_PF_SPURIOUS;
- else if (!tdp_mmu_set_spte_atomic(vcpu->kvm, iter, new_spte))
+ else if (tdp_mmu_set_spte_atomic(vcpu->kvm, iter, new_spte))
return RET_PF_RETRY;
+ else if (is_shadow_present_pte(iter->old_spte) &&
+ !is_last_spte(iter->old_spte, iter->level))
+ kvm_flush_remote_tlbs_with_address(vcpu->kvm, sp->gfn,
+ KVM_PAGES_PER_HPAGE(iter->level + 1));
/*
* If the page fault was caused by a write but the page is write
@@ -947,6 +1114,44 @@ static int tdp_mmu_map_handle_target_level(struct kvm_vcpu *vcpu,
}
/*
+ * tdp_mmu_link_sp - Replace the given spte with an spte pointing to the
+ * provided page table.
+ *
+ * @kvm: kvm instance
+ * @iter: a tdp_iter instance currently on the SPTE that should be set
+ * @sp: The new TDP page table to install.
+ * @account_nx: True if this page table is being installed to split a
+ * non-executable huge page.
+ * @shared: This operation is running under the MMU lock in read mode.
+ *
+ * Returns: 0 if the new page table was installed. Non-0 if the page table
+ * could not be installed (e.g. the atomic compare-exchange failed).
+ */
+static int tdp_mmu_link_sp(struct kvm *kvm, struct tdp_iter *iter,
+ struct kvm_mmu_page *sp, bool account_nx,
+ bool shared)
+{
+ u64 spte = make_nonleaf_spte(sp->spt, !shadow_accessed_mask);
+ int ret = 0;
+
+ if (shared) {
+ ret = tdp_mmu_set_spte_atomic(kvm, iter, spte);
+ if (ret)
+ return ret;
+ } else {
+ tdp_mmu_set_spte(kvm, iter, spte);
+ }
+
+ spin_lock(&kvm->arch.tdp_mmu_pages_lock);
+ list_add(&sp->link, &kvm->arch.tdp_mmu_pages);
+ if (account_nx)
+ account_huge_nx_page(kvm, sp);
+ spin_unlock(&kvm->arch.tdp_mmu_pages_lock);
+
+ return 0;
+}
+
+/*
* Handle a TDP page fault (NPT/EPT violation/misconfiguration) by installing
* page tables and SPTEs to translate the faulting guest physical address.
*/
@@ -955,8 +1160,6 @@ int kvm_tdp_mmu_map(struct kvm_vcpu *vcpu, struct kvm_page_fault *fault)
struct kvm_mmu *mmu = vcpu->arch.mmu;
struct tdp_iter iter;
struct kvm_mmu_page *sp;
- u64 *child_pt;
- u64 new_spte;
int ret;
kvm_mmu_hugepage_adjust(vcpu, fault);
@@ -979,7 +1182,7 @@ int kvm_tdp_mmu_map(struct kvm_vcpu *vcpu, struct kvm_page_fault *fault)
*/
if (is_shadow_present_pte(iter.old_spte) &&
is_large_pte(iter.old_spte)) {
- if (!tdp_mmu_zap_spte_atomic(vcpu->kvm, &iter))
+ if (tdp_mmu_zap_spte_atomic(vcpu->kvm, &iter))
break;
/*
@@ -987,10 +1190,13 @@ int kvm_tdp_mmu_map(struct kvm_vcpu *vcpu, struct kvm_page_fault *fault)
* because the new value informs the !present
* path below.
*/
- iter.old_spte = READ_ONCE(*rcu_dereference(iter.sptep));
+ iter.old_spte = kvm_tdp_mmu_read_spte(iter.sptep);
}
if (!is_shadow_present_pte(iter.old_spte)) {
+ bool account_nx = fault->huge_page_disallowed &&
+ fault->req_level >= iter.level;
+
/*
* If SPTE has been frozen by another thread, just
* give up and retry, avoiding unnecessary page table
@@ -999,26 +1205,21 @@ int kvm_tdp_mmu_map(struct kvm_vcpu *vcpu, struct kvm_page_fault *fault)
if (is_removed_spte(iter.old_spte))
break;
- sp = alloc_tdp_mmu_page(vcpu, iter.gfn, iter.level - 1);
- child_pt = sp->spt;
+ sp = tdp_mmu_alloc_sp(vcpu);
+ tdp_mmu_init_child_sp(sp, &iter);
- new_spte = make_nonleaf_spte(child_pt,
- !shadow_accessed_mask);
-
- if (tdp_mmu_set_spte_atomic(vcpu->kvm, &iter, new_spte)) {
- tdp_mmu_link_page(vcpu->kvm, sp,
- fault->huge_page_disallowed &&
- fault->req_level >= iter.level);
-
- trace_kvm_mmu_get_page(sp, true);
- } else {
+ if (tdp_mmu_link_sp(vcpu->kvm, &iter, sp, account_nx, true)) {
tdp_mmu_free_sp(sp);
break;
}
}
}
- if (iter.level != fault->goal_level) {
+ /*
+ * Force the guest to retry the access if the upper level SPTEs aren't
+ * in place, or if the target leaf SPTE is frozen by another CPU.
+ */
+ if (iter.level != fault->goal_level || is_removed_spte(iter.old_spte)) {
rcu_read_unlock();
return RET_PF_RETRY;
}
@@ -1032,13 +1233,8 @@ int kvm_tdp_mmu_map(struct kvm_vcpu *vcpu, struct kvm_page_fault *fault)
bool kvm_tdp_mmu_unmap_gfn_range(struct kvm *kvm, struct kvm_gfn_range *range,
bool flush)
{
- struct kvm_mmu_page *root;
-
- for_each_tdp_mmu_root_yield_safe(kvm, root, range->slot->as_id, false)
- flush = zap_gfn_range(kvm, root, range->start, range->end,
- range->may_block, flush, false);
-
- return flush;
+ return __kvm_tdp_mmu_zap_gfn_range(kvm, range->slot->as_id, range->start,
+ range->end, range->may_block, flush);
}
typedef bool (*tdp_handler_t)(struct kvm *kvm, struct tdp_iter *iter,
@@ -1052,18 +1248,18 @@ static __always_inline bool kvm_tdp_mmu_handle_gfn(struct kvm *kvm,
struct tdp_iter iter;
bool ret = false;
- rcu_read_lock();
-
/*
* Don't support rescheduling, none of the MMU notifiers that funnel
* into this helper allow blocking; it'd be dead, wasteful code.
*/
for_each_tdp_mmu_root(kvm, root, range->slot->as_id) {
+ rcu_read_lock();
+
tdp_root_for_each_leaf_pte(iter, root, range->start, range->end)
ret |= handler(kvm, &iter, range);
- }
- rcu_read_unlock();
+ rcu_read_unlock();
+ }
return ret;
}
@@ -1155,13 +1351,12 @@ static bool set_spte_gfn(struct kvm *kvm, struct tdp_iter *iter,
*/
bool kvm_tdp_mmu_set_spte_gfn(struct kvm *kvm, struct kvm_gfn_range *range)
{
- bool flush = kvm_tdp_mmu_handle_gfn(kvm, range, set_spte_gfn);
-
- /* FIXME: return 'flush' instead of flushing here. */
- if (flush)
- kvm_flush_remote_tlbs_with_address(kvm, range->start, 1);
-
- return false;
+ /*
+ * No need to handle the remote TLB flush under RCU protection, the
+ * target SPTE _must_ be a leaf SPTE, i.e. cannot result in freeing a
+ * shadow page. See the WARN on pfn_changed in __handle_changed_spte().
+ */
+ return kvm_tdp_mmu_handle_gfn(kvm, range, set_spte_gfn);
}
/*
@@ -1180,8 +1375,7 @@ static bool wrprot_gfn_range(struct kvm *kvm, struct kvm_mmu_page *root,
BUG_ON(min_level > KVM_MAX_HUGEPAGE_LEVEL);
- for_each_tdp_pte_min_level(iter, root->spt, root->role.level,
- min_level, start, end) {
+ for_each_tdp_pte_min_level(iter, root, min_level, start, end) {
retry:
if (tdp_mmu_iter_cond_resched(kvm, &iter, false, true))
continue;
@@ -1193,14 +1387,9 @@ retry:
new_spte = iter.old_spte & ~PT_WRITABLE_MASK;
- if (!tdp_mmu_set_spte_atomic(kvm, &iter, new_spte)) {
- /*
- * The iter must explicitly re-read the SPTE because
- * the atomic cmpxchg failed.
- */
- iter.old_spte = READ_ONCE(*rcu_dereference(iter.sptep));
+ if (tdp_mmu_set_spte_atomic(kvm, &iter, new_spte))
goto retry;
- }
+
spte_set = true;
}
@@ -1221,13 +1410,197 @@ bool kvm_tdp_mmu_wrprot_slot(struct kvm *kvm,
lockdep_assert_held_read(&kvm->mmu_lock);
- for_each_tdp_mmu_root_yield_safe(kvm, root, slot->as_id, true)
+ for_each_valid_tdp_mmu_root_yield_safe(kvm, root, slot->as_id, true)
spte_set |= wrprot_gfn_range(kvm, root, slot->base_gfn,
slot->base_gfn + slot->npages, min_level);
return spte_set;
}
+static struct kvm_mmu_page *__tdp_mmu_alloc_sp_for_split(gfp_t gfp)
+{
+ struct kvm_mmu_page *sp;
+
+ gfp |= __GFP_ZERO;
+
+ sp = kmem_cache_alloc(mmu_page_header_cache, gfp);
+ if (!sp)
+ return NULL;
+
+ sp->spt = (void *)__get_free_page(gfp);
+ if (!sp->spt) {
+ kmem_cache_free(mmu_page_header_cache, sp);
+ return NULL;
+ }
+
+ return sp;
+}
+
+static struct kvm_mmu_page *tdp_mmu_alloc_sp_for_split(struct kvm *kvm,
+ struct tdp_iter *iter,
+ bool shared)
+{
+ struct kvm_mmu_page *sp;
+
+ /*
+ * Since we are allocating while under the MMU lock we have to be
+ * careful about GFP flags. Use GFP_NOWAIT to avoid blocking on direct
+ * reclaim and to avoid making any filesystem callbacks (which can end
+ * up invoking KVM MMU notifiers, resulting in a deadlock).
+ *
+ * If this allocation fails we drop the lock and retry with reclaim
+ * allowed.
+ */
+ sp = __tdp_mmu_alloc_sp_for_split(GFP_NOWAIT | __GFP_ACCOUNT);
+ if (sp)
+ return sp;
+
+ rcu_read_unlock();
+
+ if (shared)
+ read_unlock(&kvm->mmu_lock);
+ else
+ write_unlock(&kvm->mmu_lock);
+
+ iter->yielded = true;
+ sp = __tdp_mmu_alloc_sp_for_split(GFP_KERNEL_ACCOUNT);
+
+ if (shared)
+ read_lock(&kvm->mmu_lock);
+ else
+ write_lock(&kvm->mmu_lock);
+
+ rcu_read_lock();
+
+ return sp;
+}
+
+static int tdp_mmu_split_huge_page(struct kvm *kvm, struct tdp_iter *iter,
+ struct kvm_mmu_page *sp, bool shared)
+{
+ const u64 huge_spte = iter->old_spte;
+ const int level = iter->level;
+ int ret, i;
+
+ tdp_mmu_init_child_sp(sp, iter);
+
+ /*
+ * No need for atomics when writing to sp->spt since the page table has
+ * not been linked in yet and thus is not reachable from any other CPU.
+ */
+ for (i = 0; i < PT64_ENT_PER_PAGE; i++)
+ sp->spt[i] = make_huge_page_split_spte(huge_spte, level, i);
+
+ /*
+ * Replace the huge spte with a pointer to the populated lower level
+ * page table. Since we are making this change without a TLB flush vCPUs
+ * will see a mix of the split mappings and the original huge mapping,
+ * depending on what's currently in their TLB. This is fine from a
+ * correctness standpoint since the translation will be the same either
+ * way.
+ */
+ ret = tdp_mmu_link_sp(kvm, iter, sp, false, shared);
+ if (ret)
+ goto out;
+
+ /*
+ * tdp_mmu_link_sp_atomic() will handle subtracting the huge page we
+ * are overwriting from the page stats. But we have to manually update
+ * the page stats with the new present child pages.
+ */
+ kvm_update_page_stats(kvm, level - 1, PT64_ENT_PER_PAGE);
+
+out:
+ trace_kvm_mmu_split_huge_page(iter->gfn, huge_spte, level, ret);
+ return ret;
+}
+
+static int tdp_mmu_split_huge_pages_root(struct kvm *kvm,
+ struct kvm_mmu_page *root,
+ gfn_t start, gfn_t end,
+ int target_level, bool shared)
+{
+ struct kvm_mmu_page *sp = NULL;
+ struct tdp_iter iter;
+ int ret = 0;
+
+ rcu_read_lock();
+
+ /*
+ * Traverse the page table splitting all huge pages above the target
+ * level into one lower level. For example, if we encounter a 1GB page
+ * we split it into 512 2MB pages.
+ *
+ * Since the TDP iterator uses a pre-order traversal, we are guaranteed
+ * to visit an SPTE before ever visiting its children, which means we
+ * will correctly recursively split huge pages that are more than one
+ * level above the target level (e.g. splitting a 1GB to 512 2MB pages,
+ * and then splitting each of those to 512 4KB pages).
+ */
+ for_each_tdp_pte_min_level(iter, root, target_level + 1, start, end) {
+retry:
+ if (tdp_mmu_iter_cond_resched(kvm, &iter, false, shared))
+ continue;
+
+ if (!is_shadow_present_pte(iter.old_spte) || !is_large_pte(iter.old_spte))
+ continue;
+
+ if (!sp) {
+ sp = tdp_mmu_alloc_sp_for_split(kvm, &iter, shared);
+ if (!sp) {
+ ret = -ENOMEM;
+ trace_kvm_mmu_split_huge_page(iter.gfn,
+ iter.old_spte,
+ iter.level, ret);
+ break;
+ }
+
+ if (iter.yielded)
+ continue;
+ }
+
+ if (tdp_mmu_split_huge_page(kvm, &iter, sp, shared))
+ goto retry;
+
+ sp = NULL;
+ }
+
+ rcu_read_unlock();
+
+ /*
+ * It's possible to exit the loop having never used the last sp if, for
+ * example, a vCPU doing HugePage NX splitting wins the race and
+ * installs its own sp in place of the last sp we tried to split.
+ */
+ if (sp)
+ tdp_mmu_free_sp(sp);
+
+ return ret;
+}
+
+
+/*
+ * Try to split all huge pages mapped by the TDP MMU down to the target level.
+ */
+void kvm_tdp_mmu_try_split_huge_pages(struct kvm *kvm,
+ const struct kvm_memory_slot *slot,
+ gfn_t start, gfn_t end,
+ int target_level, bool shared)
+{
+ struct kvm_mmu_page *root;
+ int r = 0;
+
+ kvm_lockdep_assert_mmu_lock_held(kvm, shared);
+
+ for_each_valid_tdp_mmu_root_yield_safe(kvm, root, slot->as_id, shared) {
+ r = tdp_mmu_split_huge_pages_root(kvm, root, start, end, target_level, shared);
+ if (r) {
+ kvm_tdp_mmu_put_root(kvm, root, shared);
+ break;
+ }
+ }
+}
+
/*
* Clear the dirty status of all the SPTEs mapping GFNs in the memslot. If
* AD bits are enabled, this will involve clearing the dirty bit on each SPTE.
@@ -1249,6 +1622,9 @@ retry:
if (tdp_mmu_iter_cond_resched(kvm, &iter, false, true))
continue;
+ if (!is_shadow_present_pte(iter.old_spte))
+ continue;
+
if (spte_ad_need_write_protect(iter.old_spte)) {
if (is_writable_pte(iter.old_spte))
new_spte = iter.old_spte & ~PT_WRITABLE_MASK;
@@ -1261,14 +1637,9 @@ retry:
continue;
}
- if (!tdp_mmu_set_spte_atomic(kvm, &iter, new_spte)) {
- /*
- * The iter must explicitly re-read the SPTE because
- * the atomic cmpxchg failed.
- */
- iter.old_spte = READ_ONCE(*rcu_dereference(iter.sptep));
+ if (tdp_mmu_set_spte_atomic(kvm, &iter, new_spte))
goto retry;
- }
+
spte_set = true;
}
@@ -1291,7 +1662,7 @@ bool kvm_tdp_mmu_clear_dirty_slot(struct kvm *kvm,
lockdep_assert_held_read(&kvm->mmu_lock);
- for_each_tdp_mmu_root_yield_safe(kvm, root, slot->as_id, true)
+ for_each_valid_tdp_mmu_root_yield_safe(kvm, root, slot->as_id, true)
spte_set |= clear_dirty_gfn_range(kvm, root, slot->base_gfn,
slot->base_gfn + slot->npages);
@@ -1392,14 +1763,8 @@ retry:
continue;
/* Note, a successful atomic zap also does a remote TLB flush. */
- if (!tdp_mmu_zap_spte_atomic(kvm, &iter)) {
- /*
- * The iter must explicitly re-read the SPTE because
- * the atomic cmpxchg failed.
- */
- iter.old_spte = READ_ONCE(*rcu_dereference(iter.sptep));
+ if (tdp_mmu_zap_spte_atomic(kvm, &iter))
goto retry;
- }
}
rcu_read_unlock();
@@ -1416,7 +1781,7 @@ void kvm_tdp_mmu_zap_collapsible_sptes(struct kvm *kvm,
lockdep_assert_held_read(&kvm->mmu_lock);
- for_each_tdp_mmu_root_yield_safe(kvm, root, slot->as_id, true)
+ for_each_valid_tdp_mmu_root_yield_safe(kvm, root, slot->as_id, true)
zap_collapsible_spte_range(kvm, root, slot);
}
@@ -1436,8 +1801,7 @@ static bool write_protect_gfn(struct kvm *kvm, struct kvm_mmu_page *root,
rcu_read_lock();
- for_each_tdp_pte_min_level(iter, root->spt, root->role.level,
- min_level, gfn, gfn + 1) {
+ for_each_tdp_pte_min_level(iter, root, min_level, gfn, gfn + 1) {
if (!is_shadow_present_pte(iter.old_spte) ||
!is_last_spte(iter.old_spte, iter.level))
continue;
diff --git a/arch/x86/kvm/mmu/tdp_mmu.h b/arch/x86/kvm/mmu/tdp_mmu.h
index 3899004a5d91..5e5ef2576c81 100644
--- a/arch/x86/kvm/mmu/tdp_mmu.h
+++ b/arch/x86/kvm/mmu/tdp_mmu.h
@@ -7,12 +7,8 @@
hpa_t kvm_tdp_mmu_get_vcpu_root_hpa(struct kvm_vcpu *vcpu);
-__must_check static inline bool kvm_tdp_mmu_get_root(struct kvm *kvm,
- struct kvm_mmu_page *root)
+__must_check static inline bool kvm_tdp_mmu_get_root(struct kvm_mmu_page *root)
{
- if (root->role.invalid)
- return false;
-
return refcount_inc_not_zero(&root->tdp_mmu_root_count);
}
@@ -26,24 +22,8 @@ static inline bool kvm_tdp_mmu_zap_gfn_range(struct kvm *kvm, int as_id,
{
return __kvm_tdp_mmu_zap_gfn_range(kvm, as_id, start, end, true, flush);
}
-static inline bool kvm_tdp_mmu_zap_sp(struct kvm *kvm, struct kvm_mmu_page *sp)
-{
- gfn_t end = sp->gfn + KVM_PAGES_PER_HPAGE(sp->role.level + 1);
-
- /*
- * Don't allow yielding, as the caller may have a flush pending. Note,
- * if mmu_lock is held for write, zapping will never yield in this case,
- * but explicitly disallow it for safety. The TDP MMU does not yield
- * until it has made forward progress (steps sideways), and when zapping
- * a single shadow page that it's guaranteed to see (thus the mmu_lock
- * requirement), its "step sideways" will always step beyond the bounds
- * of the shadow page's gfn range and stop iterating before yielding.
- */
- lockdep_assert_held_write(&kvm->mmu_lock);
- return __kvm_tdp_mmu_zap_gfn_range(kvm, kvm_mmu_page_as_id(sp),
- sp->gfn, end, false, false);
-}
+bool kvm_tdp_mmu_zap_sp(struct kvm *kvm, struct kvm_mmu_page *sp);
void kvm_tdp_mmu_zap_all(struct kvm *kvm);
void kvm_tdp_mmu_invalidate_all_roots(struct kvm *kvm);
void kvm_tdp_mmu_zap_invalidated_roots(struct kvm *kvm);
@@ -71,6 +51,11 @@ bool kvm_tdp_mmu_write_protect_gfn(struct kvm *kvm,
struct kvm_memory_slot *slot, gfn_t gfn,
int min_level);
+void kvm_tdp_mmu_try_split_huge_pages(struct kvm *kvm,
+ const struct kvm_memory_slot *slot,
+ gfn_t start, gfn_t end,
+ int target_level, bool shared);
+
static inline void kvm_tdp_mmu_walk_lockless_begin(void)
{
rcu_read_lock();
@@ -94,7 +79,7 @@ static inline bool is_tdp_mmu_page(struct kvm_mmu_page *sp) { return sp->tdp_mmu
static inline bool is_tdp_mmu(struct kvm_mmu *mmu)
{
struct kvm_mmu_page *sp;
- hpa_t hpa = mmu->root_hpa;
+ hpa_t hpa = mmu->root.hpa;
if (WARN_ON(!VALID_PAGE(hpa)))
return false;
diff --git a/arch/x86/kvm/pmu.c b/arch/x86/kvm/pmu.c
index f614f95acc6b..b1a02993782b 100644
--- a/arch/x86/kvm/pmu.c
+++ b/arch/x86/kvm/pmu.c
@@ -95,7 +95,7 @@ static void kvm_perf_overflow(struct perf_event *perf_event,
}
static void pmc_reprogram_counter(struct kvm_pmc *pmc, u32 type,
- unsigned config, bool exclude_user,
+ u64 config, bool exclude_user,
bool exclude_kernel, bool intr,
bool in_tx, bool in_tx_cp)
{
@@ -181,7 +181,8 @@ static int cmp_u64(const void *a, const void *b)
void reprogram_gp_counter(struct kvm_pmc *pmc, u64 eventsel)
{
- unsigned config, type = PERF_TYPE_RAW;
+ u64 config;
+ u32 type = PERF_TYPE_RAW;
struct kvm *kvm = pmc->vcpu->kvm;
struct kvm_pmu_event_filter *filter;
bool allow_event = true;
@@ -220,7 +221,7 @@ void reprogram_gp_counter(struct kvm_pmc *pmc, u64 eventsel)
}
if (type == PERF_TYPE_RAW)
- config = eventsel & X86_RAW_EVENT_MASK;
+ config = eventsel & AMD64_RAW_EVENT_MASK;
if (pmc->current_config == eventsel && pmc_resume_counter(pmc))
return;
diff --git a/arch/x86/kvm/pmu.h b/arch/x86/kvm/pmu.h
index 7a7b8d5b775e..9e66fba1d6a3 100644
--- a/arch/x86/kvm/pmu.h
+++ b/arch/x86/kvm/pmu.h
@@ -15,8 +15,6 @@
#define VMWARE_BACKDOOR_PMC_REAL_TIME 0x10001
#define VMWARE_BACKDOOR_PMC_APPARENT_TIME 0x10002
-#define MAX_FIXED_COUNTERS 3
-
struct kvm_event_hw_type_mapping {
u8 eventsel;
u8 unit_mask;
diff --git a/arch/x86/kvm/svm/avic.c b/arch/x86/kvm/svm/avic.c
index 90364d02f22a..b37b353ec086 100644
--- a/arch/x86/kvm/svm/avic.c
+++ b/arch/x86/kvm/svm/avic.c
@@ -27,20 +27,6 @@
#include "irq.h"
#include "svm.h"
-#define SVM_AVIC_DOORBELL 0xc001011b
-
-#define AVIC_HPA_MASK ~((0xFFFULL << 52) | 0xFFF)
-
-/*
- * 0xff is broadcast, so the max index allowed for physical APIC ID
- * table is 0xfe. APIC IDs above 0xff are reserved.
- */
-#define AVIC_MAX_PHYSICAL_ID_COUNT 255
-
-#define AVIC_UNACCEL_ACCESS_WRITE_MASK 1
-#define AVIC_UNACCEL_ACCESS_OFFSET_MASK 0xFF0
-#define AVIC_UNACCEL_ACCESS_VECTOR_MASK 0xFFFFFFFF
-
/* AVIC GATAG is encoded using VM and VCPU IDs */
#define AVIC_VCPU_ID_BITS 8
#define AVIC_VCPU_ID_MASK ((1 << AVIC_VCPU_ID_BITS) - 1)
@@ -73,12 +59,6 @@ struct amd_svm_iommu_ir {
void *data; /* Storing pointer to struct amd_ir_data */
};
-enum avic_ipi_failure_cause {
- AVIC_IPI_FAILURE_INVALID_INT_TYPE,
- AVIC_IPI_FAILURE_TARGET_NOT_RUNNING,
- AVIC_IPI_FAILURE_INVALID_TARGET,
- AVIC_IPI_FAILURE_INVALID_BACKING_PAGE,
-};
/* Note:
* This function is called from IOMMU driver to notify
@@ -289,6 +269,22 @@ static int avic_init_backing_page(struct kvm_vcpu *vcpu)
return 0;
}
+void avic_ring_doorbell(struct kvm_vcpu *vcpu)
+{
+ /*
+ * Note, the vCPU could get migrated to a different pCPU at any point,
+ * which could result in signalling the wrong/previous pCPU. But if
+ * that happens the vCPU is guaranteed to do a VMRUN (after being
+ * migrated) and thus will process pending interrupts, i.e. a doorbell
+ * is not needed (and the spurious one is harmless).
+ */
+ int cpu = READ_ONCE(vcpu->cpu);
+
+ if (cpu != get_cpu())
+ wrmsrl(MSR_AMD64_SVM_AVIC_DOORBELL, kvm_cpu_get_apicid(cpu));
+ put_cpu();
+}
+
static void avic_kick_target_vcpus(struct kvm *kvm, struct kvm_lapic *source,
u32 icrl, u32 icrh)
{
@@ -304,8 +300,13 @@ static void avic_kick_target_vcpus(struct kvm *kvm, struct kvm_lapic *source,
kvm_for_each_vcpu(i, vcpu, kvm) {
if (kvm_apic_match_dest(vcpu, source, icrl & APIC_SHORT_MASK,
GET_APIC_DEST_FIELD(icrh),
- icrl & APIC_DEST_MASK))
- kvm_vcpu_wake_up(vcpu);
+ icrl & APIC_DEST_MASK)) {
+ vcpu->arch.apic->irr_pending = true;
+ svm_complete_interrupt_delivery(vcpu,
+ icrl & APIC_MODE_MASK,
+ icrl & APIC_INT_LEVELTRIG,
+ icrl & APIC_VECTOR_MASK);
+ }
}
}
@@ -323,18 +324,18 @@ int avic_incomplete_ipi_interception(struct kvm_vcpu *vcpu)
switch (id) {
case AVIC_IPI_FAILURE_INVALID_INT_TYPE:
/*
- * AVIC hardware handles the generation of
- * IPIs when the specified Message Type is Fixed
- * (also known as fixed delivery mode) and
- * the Trigger Mode is edge-triggered. The hardware
- * also supports self and broadcast delivery modes
- * specified via the Destination Shorthand(DSH)
- * field of the ICRL. Logical and physical APIC ID
- * formats are supported. All other IPI types cause
- * a #VMEXIT, which needs to emulated.
+ * Emulate IPIs that are not handled by AVIC hardware, which
+ * only virtualizes Fixed, Edge-Triggered INTRs. The exit is
+ * a trap, e.g. ICR holds the correct value and RIP has been
+ * advanced, KVM is responsible only for emulating the IPI.
+ * Sadly, hardware may sometimes leave the BUSY flag set, in
+ * which case KVM needs to emulate the ICR write as well in
+ * order to clear the BUSY flag.
*/
- kvm_lapic_reg_write(apic, APIC_ICR2, icrh);
- kvm_lapic_reg_write(apic, APIC_ICR, icrl);
+ if (icrl & APIC_ICR_BUSY)
+ kvm_apic_write_nodecode(vcpu, APIC_ICR);
+ else
+ kvm_apic_send_ipi(apic, icrl, icrh);
break;
case AVIC_IPI_FAILURE_TARGET_NOT_RUNNING:
/*
@@ -345,8 +346,6 @@ int avic_incomplete_ipi_interception(struct kvm_vcpu *vcpu)
avic_kick_target_vcpus(vcpu->kvm, apic, icrl, icrh);
break;
case AVIC_IPI_FAILURE_INVALID_TARGET:
- WARN_ONCE(1, "Invalid IPI target: index=%u, vcpu=%d, icr=%#0x:%#0x\n",
- index, vcpu->vcpu_id, icrh, icrl);
break;
case AVIC_IPI_FAILURE_INVALID_BACKING_PAGE:
WARN_ONCE(1, "Invalid backing page\n");
@@ -478,30 +477,28 @@ static void avic_handle_dfr_update(struct kvm_vcpu *vcpu)
svm->dfr_reg = dfr;
}
-static int avic_unaccel_trap_write(struct vcpu_svm *svm)
+static int avic_unaccel_trap_write(struct kvm_vcpu *vcpu)
{
- struct kvm_lapic *apic = svm->vcpu.arch.apic;
- u32 offset = svm->vmcb->control.exit_info_1 &
+ u32 offset = to_svm(vcpu)->vmcb->control.exit_info_1 &
AVIC_UNACCEL_ACCESS_OFFSET_MASK;
switch (offset) {
case APIC_ID:
- if (avic_handle_apic_id_update(&svm->vcpu))
+ if (avic_handle_apic_id_update(vcpu))
return 0;
break;
case APIC_LDR:
- if (avic_handle_ldr_update(&svm->vcpu))
+ if (avic_handle_ldr_update(vcpu))
return 0;
break;
case APIC_DFR:
- avic_handle_dfr_update(&svm->vcpu);
+ avic_handle_dfr_update(vcpu);
break;
default:
break;
}
- kvm_lapic_reg_write(apic, offset, kvm_lapic_get_reg(apic, offset));
-
+ kvm_apic_write_nodecode(vcpu, offset);
return 1;
}
@@ -551,7 +548,7 @@ int avic_unaccelerated_access_interception(struct kvm_vcpu *vcpu)
if (trap) {
/* Handling Trap */
WARN_ONCE(!write, "svm: Handling trap read.\n");
- ret = avic_unaccel_trap_write(svm);
+ ret = avic_unaccel_trap_write(vcpu);
} else {
/* Handling Fault */
ret = kvm_emulate_instruction(vcpu, 0);
@@ -579,7 +576,7 @@ int avic_init_vcpu(struct vcpu_svm *svm)
return ret;
}
-void avic_post_state_restore(struct kvm_vcpu *vcpu)
+void avic_apicv_post_state_restore(struct kvm_vcpu *vcpu)
{
if (avic_handle_apic_id_update(vcpu) != 0)
return;
@@ -587,20 +584,7 @@ void avic_post_state_restore(struct kvm_vcpu *vcpu)
avic_handle_ldr_update(vcpu);
}
-void svm_set_virtual_apic_mode(struct kvm_vcpu *vcpu)
-{
- return;
-}
-
-void svm_hwapic_irr_update(struct kvm_vcpu *vcpu, int max_irr)
-{
-}
-
-void svm_hwapic_isr_update(struct kvm_vcpu *vcpu, int max_isr)
-{
-}
-
-static int svm_set_pi_irte_mode(struct kvm_vcpu *vcpu, bool activate)
+static int avic_set_pi_irte_mode(struct kvm_vcpu *vcpu, bool activate)
{
int ret = 0;
unsigned long flags;
@@ -632,94 +616,6 @@ out:
return ret;
}
-void svm_refresh_apicv_exec_ctrl(struct kvm_vcpu *vcpu)
-{
- struct vcpu_svm *svm = to_svm(vcpu);
- struct vmcb *vmcb = svm->vmcb01.ptr;
- bool activated = kvm_vcpu_apicv_active(vcpu);
-
- if (!enable_apicv)
- return;
-
- if (activated) {
- /**
- * During AVIC temporary deactivation, guest could update
- * APIC ID, DFR and LDR registers, which would not be trapped
- * by avic_unaccelerated_access_interception(). In this case,
- * we need to check and update the AVIC logical APIC ID table
- * accordingly before re-activating.
- */
- avic_post_state_restore(vcpu);
- vmcb->control.int_ctl |= AVIC_ENABLE_MASK;
- } else {
- vmcb->control.int_ctl &= ~AVIC_ENABLE_MASK;
- }
- vmcb_mark_dirty(vmcb, VMCB_AVIC);
-
- if (activated)
- avic_vcpu_load(vcpu, vcpu->cpu);
- else
- avic_vcpu_put(vcpu);
-
- svm_set_pi_irte_mode(vcpu, activated);
-}
-
-void svm_load_eoi_exitmap(struct kvm_vcpu *vcpu, u64 *eoi_exit_bitmap)
-{
- return;
-}
-
-int svm_deliver_avic_intr(struct kvm_vcpu *vcpu, int vec)
-{
- if (!vcpu->arch.apicv_active)
- return -1;
-
- kvm_lapic_set_irr(vec, vcpu->arch.apic);
-
- /*
- * Pairs with the smp_mb_*() after setting vcpu->guest_mode in
- * vcpu_enter_guest() to ensure the write to the vIRR is ordered before
- * the read of guest_mode, which guarantees that either VMRUN will see
- * and process the new vIRR entry, or that the below code will signal
- * the doorbell if the vCPU is already running in the guest.
- */
- smp_mb__after_atomic();
-
- /*
- * Signal the doorbell to tell hardware to inject the IRQ if the vCPU
- * is in the guest. If the vCPU is not in the guest, hardware will
- * automatically process AVIC interrupts at VMRUN.
- */
- if (vcpu->mode == IN_GUEST_MODE) {
- int cpu = READ_ONCE(vcpu->cpu);
-
- /*
- * Note, the vCPU could get migrated to a different pCPU at any
- * point, which could result in signalling the wrong/previous
- * pCPU. But if that happens the vCPU is guaranteed to do a
- * VMRUN (after being migrated) and thus will process pending
- * interrupts, i.e. a doorbell is not needed (and the spurious
- * one is harmless).
- */
- if (cpu != get_cpu())
- wrmsrl(SVM_AVIC_DOORBELL, kvm_cpu_get_apicid(cpu));
- put_cpu();
- } else {
- /*
- * Wake the vCPU if it was blocking. KVM will then detect the
- * pending IRQ when checking if the vCPU has a wake event.
- */
- kvm_vcpu_wake_up(vcpu);
- }
-
- return 0;
-}
-
-bool svm_dy_apicv_has_pending_interrupt(struct kvm_vcpu *vcpu)
-{
- return false;
-}
-
static void svm_ir_list_del(struct vcpu_svm *svm, struct amd_iommu_pi_data *pi)
{
unsigned long flags;
@@ -817,7 +713,7 @@ get_pi_vcpu_info(struct kvm *kvm, struct kvm_kernel_irq_routing_entry *e,
}
/*
- * svm_update_pi_irte - set IRTE for Posted-Interrupts
+ * avic_pi_update_irte - set IRTE for Posted-Interrupts
*
* @kvm: kvm
* @host_irq: host irq of the interrupt
@@ -825,8 +721,8 @@ get_pi_vcpu_info(struct kvm *kvm, struct kvm_kernel_irq_routing_entry *e,
* @set: set or unset PI
* returns 0 on success, < 0 on failure
*/
-int svm_update_pi_irte(struct kvm *kvm, unsigned int host_irq,
- uint32_t guest_irq, bool set)
+int avic_pi_update_irte(struct kvm *kvm, unsigned int host_irq,
+ uint32_t guest_irq, bool set)
{
struct kvm_kernel_irq_routing_entry *e;
struct kvm_irq_routing_table *irq_rt;
@@ -926,7 +822,7 @@ out:
return ret;
}
-bool svm_check_apicv_inhibit_reasons(ulong bit)
+bool avic_check_apicv_inhibit_reasons(ulong bit)
{
ulong supported = BIT(APICV_INHIBIT_REASON_DISABLE) |
BIT(APICV_INHIBIT_REASON_ABSENT) |
@@ -971,20 +867,15 @@ out:
return ret;
}
-void avic_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
+void __avic_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
{
u64 entry;
- /* ID = 0xff (broadcast), ID > 0xff (reserved) */
int h_physical_id = kvm_cpu_get_apicid(cpu);
struct vcpu_svm *svm = to_svm(vcpu);
lockdep_assert_preemption_disabled();
- /*
- * Since the host physical APIC id is 8 bits,
- * we can support host APIC ID upto 255.
- */
- if (WARN_ON(h_physical_id > AVIC_PHYSICAL_ID_ENTRY_HOST_PHYSICAL_ID_MASK))
+ if (WARN_ON(h_physical_id & ~AVIC_PHYSICAL_ID_ENTRY_HOST_PHYSICAL_ID_MASK))
return;
/*
@@ -1008,7 +899,7 @@ void avic_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
avic_update_iommu_vcpu_affinity(vcpu, h_physical_id, true);
}
-void avic_vcpu_put(struct kvm_vcpu *vcpu)
+void __avic_vcpu_put(struct kvm_vcpu *vcpu)
{
u64 entry;
struct vcpu_svm *svm = to_svm(vcpu);
@@ -1027,13 +918,63 @@ void avic_vcpu_put(struct kvm_vcpu *vcpu)
WRITE_ONCE(*(svm->avic_physical_id_cache), entry);
}
+static void avic_vcpu_load(struct kvm_vcpu *vcpu)
+{
+ int cpu = get_cpu();
+
+ WARN_ON(cpu != vcpu->cpu);
+
+ __avic_vcpu_load(vcpu, cpu);
+
+ put_cpu();
+}
+
+static void avic_vcpu_put(struct kvm_vcpu *vcpu)
+{
+ preempt_disable();
+
+ __avic_vcpu_put(vcpu);
+
+ preempt_enable();
+}
+
+void avic_refresh_apicv_exec_ctrl(struct kvm_vcpu *vcpu)
+{
+ struct vcpu_svm *svm = to_svm(vcpu);
+ struct vmcb *vmcb = svm->vmcb01.ptr;
+ bool activated = kvm_vcpu_apicv_active(vcpu);
+
+ if (!enable_apicv)
+ return;
+
+ if (activated) {
+ /**
+ * During AVIC temporary deactivation, guest could update
+ * APIC ID, DFR and LDR registers, which would not be trapped
+ * by avic_unaccelerated_access_interception(). In this case,
+ * we need to check and update the AVIC logical APIC ID table
+ * accordingly before re-activating.
+ */
+ avic_apicv_post_state_restore(vcpu);
+ vmcb->control.int_ctl |= AVIC_ENABLE_MASK;
+ } else {
+ vmcb->control.int_ctl &= ~AVIC_ENABLE_MASK;
+ }
+ vmcb_mark_dirty(vmcb, VMCB_AVIC);
+
+ if (activated)
+ avic_vcpu_load(vcpu);
+ else
+ avic_vcpu_put(vcpu);
+
+ avic_set_pi_irte_mode(vcpu, activated);
+}
+
void avic_vcpu_blocking(struct kvm_vcpu *vcpu)
{
if (!kvm_vcpu_apicv_active(vcpu))
return;
- preempt_disable();
-
/*
* Unload the AVIC when the vCPU is about to block, _before_
* the vCPU actually blocks.
@@ -1048,21 +989,12 @@ void avic_vcpu_blocking(struct kvm_vcpu *vcpu)
* the cause of errata #1235).
*/
avic_vcpu_put(vcpu);
-
- preempt_enable();
}
void avic_vcpu_unblocking(struct kvm_vcpu *vcpu)
{
- int cpu;
-
if (!kvm_vcpu_apicv_active(vcpu))
return;
- cpu = get_cpu();
- WARN_ON(cpu != vcpu->cpu);
-
- avic_vcpu_load(vcpu, cpu);
-
- put_cpu();
+ avic_vcpu_load(vcpu);
}
diff --git a/arch/x86/kvm/svm/hyperv.h b/arch/x86/kvm/svm/hyperv.h
new file mode 100644
index 000000000000..7d6d97968fb9
--- /dev/null
+++ b/arch/x86/kvm/svm/hyperv.h
@@ -0,0 +1,35 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Common Hyper-V on KVM and KVM on Hyper-V definitions (SVM).
+ */
+
+#ifndef __ARCH_X86_KVM_SVM_HYPERV_H__
+#define __ARCH_X86_KVM_SVM_HYPERV_H__
+
+#include <asm/mshyperv.h>
+
+#include "../hyperv.h"
+
+/*
+ * Hyper-V uses the software reserved 32 bytes in VMCB
+ * control area to expose SVM enlightenments to guests.
+ */
+struct hv_enlightenments {
+ struct __packed hv_enlightenments_control {
+ u32 nested_flush_hypercall:1;
+ u32 msr_bitmap:1;
+ u32 enlightened_npt_tlb: 1;
+ u32 reserved:29;
+ } __packed hv_enlightenments_control;
+ u32 hv_vp_id;
+ u64 hv_vm_id;
+ u64 partition_assist_page;
+ u64 reserved;
+} __packed;
+
+/*
+ * Hyper-V uses the software reserved clean bit in VMCB
+ */
+#define VMCB_HV_NESTED_ENLIGHTENMENTS VMCB_SW
+
+#endif /* __ARCH_X86_KVM_SVM_HYPERV_H__ */
diff --git a/arch/x86/kvm/svm/nested.c b/arch/x86/kvm/svm/nested.c
index cf206855ebf0..96bab464967f 100644
--- a/arch/x86/kvm/svm/nested.c
+++ b/arch/x86/kvm/svm/nested.c
@@ -28,6 +28,7 @@
#include "cpuid.h"
#include "lapic.h"
#include "svm.h"
+#include "hyperv.h"
#define CC KVM_NESTED_VMENTER_CONSISTENCY_CHECK
@@ -165,14 +166,30 @@ void recalc_intercepts(struct vcpu_svm *svm)
vmcb_set_intercept(c, INTERCEPT_VMSAVE);
}
+/*
+ * Merge L0's (KVM) and L1's (Nested VMCB) MSR permission bitmaps. The function
+ * is optimized in that it only merges the parts where KVM MSR permission bitmap
+ * may contain zero bits.
+ */
static bool nested_svm_vmrun_msrpm(struct vcpu_svm *svm)
{
+ struct hv_enlightenments *hve =
+ (struct hv_enlightenments *)svm->nested.ctl.reserved_sw;
+ int i;
+
/*
- * This function merges the msr permission bitmaps of kvm and the
- * nested vmcb. It is optimized in that it only merges the parts where
- * the kvm msr permission bitmap may contain zero bits
+ * MSR bitmap update can be skipped when:
+ * - MSR bitmap for L1 hasn't changed.
+ * - Nested hypervisor (L1) is attempting to launch the same L2 as
+ * before.
+ * - Nested hypervisor (L1) is using Hyper-V emulation interface and
+ * tells KVM (L0) there were no changes in MSR bitmap for L2.
*/
- int i;
+ if (!svm->nested.force_msr_bitmap_recalc &&
+ kvm_hv_hypercall_enabled(&svm->vcpu) &&
+ hve->hv_enlightenments_control.msr_bitmap &&
+ (svm->nested.ctl.clean & BIT(VMCB_HV_NESTED_ENLIGHTENMENTS)))
+ goto set_msrpm_base_pa;
if (!(vmcb12_is_intercept(&svm->nested.ctl, INTERCEPT_MSR_PROT)))
return true;
@@ -193,6 +210,9 @@ static bool nested_svm_vmrun_msrpm(struct vcpu_svm *svm)
svm->nested.msrpm[p] = svm->msrpm[p] | value;
}
+ svm->nested.force_msr_bitmap_recalc = false;
+
+set_msrpm_base_pa:
svm->vmcb->control.msrpm_base_pa = __sme_set(__pa(svm->nested.msrpm));
return true;
@@ -298,7 +318,8 @@ static bool nested_vmcb_check_controls(struct kvm_vcpu *vcpu)
}
static
-void __nested_copy_vmcb_control_to_cache(struct vmcb_ctrl_area_cached *to,
+void __nested_copy_vmcb_control_to_cache(struct kvm_vcpu *vcpu,
+ struct vmcb_ctrl_area_cached *to,
struct vmcb_control_area *from)
{
unsigned int i;
@@ -331,12 +352,19 @@ void __nested_copy_vmcb_control_to_cache(struct vmcb_ctrl_area_cached *to,
to->asid = from->asid;
to->msrpm_base_pa &= ~0x0fffULL;
to->iopm_base_pa &= ~0x0fffULL;
+
+ /* Hyper-V extensions (Enlightened VMCB) */
+ if (kvm_hv_hypercall_enabled(vcpu)) {
+ to->clean = from->clean;
+ memcpy(to->reserved_sw, from->reserved_sw,
+ sizeof(struct hv_enlightenments));
+ }
}
void nested_copy_vmcb_control_to_cache(struct vcpu_svm *svm,
struct vmcb_control_area *control)
{
- __nested_copy_vmcb_control_to_cache(&svm->nested.ctl, control);
+ __nested_copy_vmcb_control_to_cache(&svm->vcpu, &svm->nested.ctl, control);
}
static void __nested_copy_vmcb_save_to_cache(struct vmcb_save_area_cached *to,
@@ -464,14 +492,14 @@ static int nested_svm_load_cr3(struct kvm_vcpu *vcpu, unsigned long cr3,
CC(!load_pdptrs(vcpu, cr3)))
return -EINVAL;
- if (!nested_npt)
- kvm_mmu_new_pgd(vcpu, cr3);
-
vcpu->arch.cr3 = cr3;
/* Re-initialize the MMU, e.g. to pick up CR4 MMU role changes. */
kvm_init_mmu(vcpu);
+ if (!nested_npt)
+ kvm_mmu_new_pgd(vcpu, cr3);
+
return 0;
}
@@ -494,6 +522,7 @@ static void nested_vmcb02_prepare_save(struct vcpu_svm *svm, struct vmcb *vmcb12
if (svm->nested.vmcb12_gpa != svm->nested.last_vmcb12_gpa) {
new_vmcb12 = true;
svm->nested.last_vmcb12_gpa = svm->nested.vmcb12_gpa;
+ svm->nested.force_msr_bitmap_recalc = true;
}
if (unlikely(new_vmcb12 || vmcb_is_dirty(vmcb12, VMCB_SEG))) {
@@ -983,9 +1012,9 @@ void svm_free_nested(struct vcpu_svm *svm)
/*
* Forcibly leave nested mode in order to be able to reset the VCPU later on.
*/
-void svm_leave_nested(struct vcpu_svm *svm)
+void svm_leave_nested(struct kvm_vcpu *vcpu)
{
- struct kvm_vcpu *vcpu = &svm->vcpu;
+ struct vcpu_svm *svm = to_svm(vcpu);
if (is_guest_mode(vcpu)) {
svm->nested.nested_run_pending = 0;
@@ -1302,6 +1331,7 @@ static void nested_copy_vmcb_cache_to_control(struct vmcb_control_area *dst,
dst->virt_ext = from->virt_ext;
dst->pause_filter_count = from->pause_filter_count;
dst->pause_filter_thresh = from->pause_filter_thresh;
+ /* 'clean' and 'reserved_sw' are not changed by KVM */
}
static int svm_get_nested_state(struct kvm_vcpu *vcpu,
@@ -1411,7 +1441,7 @@ static int svm_set_nested_state(struct kvm_vcpu *vcpu,
return -EINVAL;
if (!(kvm_state->flags & KVM_STATE_NESTED_GUEST_MODE)) {
- svm_leave_nested(svm);
+ svm_leave_nested(vcpu);
svm_set_gif(svm, !!(kvm_state->flags & KVM_STATE_NESTED_GIF_SET));
return 0;
}
@@ -1434,7 +1464,7 @@ static int svm_set_nested_state(struct kvm_vcpu *vcpu,
goto out_free;
ret = -EINVAL;
- __nested_copy_vmcb_control_to_cache(&ctl_cached, ctl);
+ __nested_copy_vmcb_control_to_cache(vcpu, &ctl_cached, ctl);
if (!__nested_vmcb_check_controls(vcpu, &ctl_cached))
goto out_free;
@@ -1457,18 +1487,6 @@ static int svm_set_nested_state(struct kvm_vcpu *vcpu,
!__nested_vmcb_check_save(vcpu, &save_cached))
goto out_free;
- /*
- * While the nested guest CR3 is already checked and set by
- * KVM_SET_SREGS, it was set when nested state was yet loaded,
- * thus MMU might not be initialized correctly.
- * Set it again to fix this.
- */
-
- ret = nested_svm_load_cr3(&svm->vcpu, vcpu->arch.cr3,
- nested_npt_enabled(svm), false);
- if (WARN_ON_ONCE(ret))
- goto out_free;
-
/*
* All checks done, we can enter guest mode. Userspace provides
@@ -1478,7 +1496,7 @@ static int svm_set_nested_state(struct kvm_vcpu *vcpu,
*/
if (is_guest_mode(vcpu))
- svm_leave_nested(svm);
+ svm_leave_nested(vcpu);
else
svm->nested.vmcb02.ptr->save = svm->vmcb01.ptr->save;
@@ -1494,6 +1512,21 @@ static int svm_set_nested_state(struct kvm_vcpu *vcpu,
svm_switch_vmcb(svm, &svm->nested.vmcb02);
nested_vmcb02_prepare_control(svm);
+
+ /*
+ * While the nested guest CR3 is already checked and set by
+ * KVM_SET_SREGS, it was set when nested state was yet loaded,
+ * thus MMU might not be initialized correctly.
+ * Set it again to fix this.
+ */
+
+ ret = nested_svm_load_cr3(&svm->vcpu, vcpu->arch.cr3,
+ nested_npt_enabled(svm), false);
+ if (WARN_ON_ONCE(ret))
+ goto out_free;
+
+ svm->nested.force_msr_bitmap_recalc = true;
+
kvm_make_request(KVM_REQ_GET_NESTED_STATE_PAGES, vcpu);
ret = 0;
out_free:
@@ -1532,6 +1565,7 @@ static bool svm_get_nested_state_pages(struct kvm_vcpu *vcpu)
}
struct kvm_x86_nested_ops svm_nested_ops = {
+ .leave_nested = svm_leave_nested,
.check_events = svm_check_nested_events,
.triple_fault = nested_svm_triple_fault,
.get_nested_state_pages = svm_get_nested_state_pages,
diff --git a/arch/x86/kvm/svm/pmu.c b/arch/x86/kvm/svm/pmu.c
index 5aa45f13b16d..d4de52409335 100644
--- a/arch/x86/kvm/svm/pmu.c
+++ b/arch/x86/kvm/svm/pmu.c
@@ -101,7 +101,7 @@ static inline struct kvm_pmc *get_gp_pmc_amd(struct kvm_pmu *pmu, u32 msr,
{
struct kvm_vcpu *vcpu = pmu_to_vcpu(pmu);
- if (!enable_pmu)
+ if (!vcpu->kvm->arch.enable_pmu)
return NULL;
switch (msr) {
diff --git a/arch/x86/kvm/svm/sev.c b/arch/x86/kvm/svm/sev.c
index 6a22798eaaee..75fa6dd268f0 100644
--- a/arch/x86/kvm/svm/sev.c
+++ b/arch/x86/kvm/svm/sev.c
@@ -258,6 +258,7 @@ static int sev_guest_init(struct kvm *kvm, struct kvm_sev_cmd *argp)
goto e_free;
INIT_LIST_HEAD(&sev->regions_list);
+ INIT_LIST_HEAD(&sev->mirror_vms);
return 0;
@@ -1623,9 +1624,12 @@ static void sev_unlock_vcpus_for_migration(struct kvm *kvm)
}
}
-static void sev_migrate_from(struct kvm_sev_info *dst,
- struct kvm_sev_info *src)
+static void sev_migrate_from(struct kvm *dst_kvm, struct kvm *src_kvm)
{
+ struct kvm_sev_info *dst = &to_kvm_svm(dst_kvm)->sev_info;
+ struct kvm_sev_info *src = &to_kvm_svm(src_kvm)->sev_info;
+ struct kvm_sev_info *mirror;
+
dst->active = true;
dst->asid = src->asid;
dst->handle = src->handle;
@@ -1639,6 +1643,30 @@ static void sev_migrate_from(struct kvm_sev_info *dst,
src->enc_context_owner = NULL;
list_cut_before(&dst->regions_list, &src->regions_list, &src->regions_list);
+
+ /*
+ * If this VM has mirrors, "transfer" each mirror's refcount of the
+ * source to the destination (this KVM). The caller holds a reference
+ * to the source, so there's no danger of use-after-free.
+ */
+ list_cut_before(&dst->mirror_vms, &src->mirror_vms, &src->mirror_vms);
+ list_for_each_entry(mirror, &dst->mirror_vms, mirror_entry) {
+ kvm_get_kvm(dst_kvm);
+ kvm_put_kvm(src_kvm);
+ mirror->enc_context_owner = dst_kvm;
+ }
+
+ /*
+ * If this VM is a mirror, remove the old mirror from the owners list
+ * and add the new mirror to the list.
+ */
+ if (is_mirroring_enc_context(dst_kvm)) {
+ struct kvm_sev_info *owner_sev_info =
+ &to_kvm_svm(dst->enc_context_owner)->sev_info;
+
+ list_del(&src->mirror_entry);
+ list_add_tail(&dst->mirror_entry, &owner_sev_info->mirror_vms);
+ }
}
static int sev_es_migrate_from(struct kvm *dst, struct kvm *src)
@@ -1681,7 +1709,7 @@ static int sev_es_migrate_from(struct kvm *dst, struct kvm *src)
return 0;
}
-int svm_vm_migrate_from(struct kvm *kvm, unsigned int source_fd)
+int sev_vm_move_enc_context_from(struct kvm *kvm, unsigned int source_fd)
{
struct kvm_sev_info *dst_sev = &to_kvm_svm(kvm)->sev_info;
struct kvm_sev_info *src_sev, *cg_cleanup_sev;
@@ -1708,15 +1736,6 @@ int svm_vm_migrate_from(struct kvm *kvm, unsigned int source_fd)
src_sev = &to_kvm_svm(source_kvm)->sev_info;
- /*
- * VMs mirroring src's encryption context rely on it to keep the
- * ASID allocated, but below we are clearing src_sev->asid.
- */
- if (src_sev->num_mirrored_vms) {
- ret = -EBUSY;
- goto out_unlock;
- }
-
dst_sev->misc_cg = get_current_misc_cg();
cg_cleanup_sev = dst_sev;
if (dst_sev->misc_cg != src_sev->misc_cg) {
@@ -1738,7 +1757,8 @@ int svm_vm_migrate_from(struct kvm *kvm, unsigned int source_fd)
if (ret)
goto out_source_vcpu;
}
- sev_migrate_from(dst_sev, src_sev);
+
+ sev_migrate_from(kvm, source_kvm);
kvm_vm_dead(source_kvm);
cg_cleanup_sev = src_sev;
ret = 0;
@@ -1761,7 +1781,7 @@ out_fput:
return ret;
}
-int svm_mem_enc_op(struct kvm *kvm, void __user *argp)
+int sev_mem_enc_ioctl(struct kvm *kvm, void __user *argp)
{
struct kvm_sev_cmd sev_cmd;
int r;
@@ -1858,8 +1878,8 @@ out:
return r;
}
-int svm_register_enc_region(struct kvm *kvm,
- struct kvm_enc_region *range)
+int sev_mem_enc_register_region(struct kvm *kvm,
+ struct kvm_enc_region *range)
{
struct kvm_sev_info *sev = &to_kvm_svm(kvm)->sev_info;
struct enc_region *region;
@@ -1932,8 +1952,8 @@ static void __unregister_enc_region_locked(struct kvm *kvm,
kfree(region);
}
-int svm_unregister_enc_region(struct kvm *kvm,
- struct kvm_enc_region *range)
+int sev_mem_enc_unregister_region(struct kvm *kvm,
+ struct kvm_enc_region *range)
{
struct enc_region *region;
int ret;
@@ -1972,7 +1992,7 @@ failed:
return ret;
}
-int svm_vm_copy_asid_from(struct kvm *kvm, unsigned int source_fd)
+int sev_vm_copy_enc_context_from(struct kvm *kvm, unsigned int source_fd)
{
struct file *source_kvm_file;
struct kvm *source_kvm;
@@ -2008,10 +2028,10 @@ int svm_vm_copy_asid_from(struct kvm *kvm, unsigned int source_fd)
*/
source_sev = &to_kvm_svm(source_kvm)->sev_info;
kvm_get_kvm(source_kvm);
- source_sev->num_mirrored_vms++;
+ mirror_sev = &to_kvm_svm(kvm)->sev_info;
+ list_add_tail(&mirror_sev->mirror_entry, &source_sev->mirror_vms);
/* Set enc_context_owner and copy its encryption context over */
- mirror_sev = &to_kvm_svm(kvm)->sev_info;
mirror_sev->enc_context_owner = source_kvm;
mirror_sev->active = true;
mirror_sev->asid = source_sev->asid;
@@ -2019,6 +2039,7 @@ int svm_vm_copy_asid_from(struct kvm *kvm, unsigned int source_fd)
mirror_sev->es_active = source_sev->es_active;
mirror_sev->handle = source_sev->handle;
INIT_LIST_HEAD(&mirror_sev->regions_list);
+ INIT_LIST_HEAD(&mirror_sev->mirror_vms);
ret = 0;
/*
@@ -2041,19 +2062,17 @@ void sev_vm_destroy(struct kvm *kvm)
struct list_head *head = &sev->regions_list;
struct list_head *pos, *q;
- WARN_ON(sev->num_mirrored_vms);
-
if (!sev_guest(kvm))
return;
+ WARN_ON(!list_empty(&sev->mirror_vms));
+
/* If this is a mirror_kvm release the enc_context_owner and skip sev cleanup */
if (is_mirroring_enc_context(kvm)) {
struct kvm *owner_kvm = sev->enc_context_owner;
- struct kvm_sev_info *owner_sev = &to_kvm_svm(owner_kvm)->sev_info;
mutex_lock(&owner_kvm->lock);
- if (!WARN_ON(!owner_sev->num_mirrored_vms))
- owner_sev->num_mirrored_vms--;
+ list_del(&sev->mirror_entry);
mutex_unlock(&owner_kvm->lock);
kvm_put_kvm(owner_kvm);
return;
@@ -2100,8 +2119,13 @@ void __init sev_hardware_setup(void)
if (!sev_enabled || !npt_enabled)
goto out;
- /* Does the CPU support SEV? */
- if (!boot_cpu_has(X86_FEATURE_SEV))
+ /*
+ * SEV must obviously be supported in hardware. Sanity check that the
+ * CPU supports decode assists, which is mandatory for SEV guests to
+ * support instruction emulation.
+ */
+ if (!boot_cpu_has(X86_FEATURE_SEV) ||
+ WARN_ON_ONCE(!boot_cpu_has(X86_FEATURE_DECODEASSISTS)))
goto out;
/* Retrieve SEV CPUID information */
@@ -2168,7 +2192,7 @@ out:
#endif
}
-void sev_hardware_teardown(void)
+void sev_hardware_unsetup(void)
{
if (!sev_enabled)
return;
@@ -2353,7 +2377,7 @@ static void sev_es_sync_from_ghcb(struct vcpu_svm *svm)
memset(ghcb->save.valid_bitmap, 0, sizeof(ghcb->save.valid_bitmap));
}
-static bool sev_es_validate_vmgexit(struct vcpu_svm *svm)
+static int sev_es_validate_vmgexit(struct vcpu_svm *svm)
{
struct kvm_vcpu *vcpu;
struct ghcb *ghcb;
@@ -2458,7 +2482,7 @@ static bool sev_es_validate_vmgexit(struct vcpu_svm *svm)
goto vmgexit_err;
}
- return true;
+ return 0;
vmgexit_err:
vcpu = &svm->vcpu;
@@ -2481,7 +2505,8 @@ vmgexit_err:
ghcb_set_sw_exit_info_1(ghcb, 2);
ghcb_set_sw_exit_info_2(ghcb, reason);
- return false;
+ /* Resume the guest to "return" the error code. */
+ return 1;
}
void sev_es_unmap_ghcb(struct vcpu_svm *svm)
@@ -2540,7 +2565,7 @@ void pre_sev_run(struct vcpu_svm *svm, int cpu)
}
#define GHCB_SCRATCH_AREA_LIMIT (16ULL * PAGE_SIZE)
-static bool setup_vmgexit_scratch(struct vcpu_svm *svm, bool sync, u64 len)
+static int setup_vmgexit_scratch(struct vcpu_svm *svm, bool sync, u64 len)
{
struct vmcb_control_area *control = &svm->vmcb->control;
struct ghcb *ghcb = svm->sev_es.ghcb;
@@ -2593,14 +2618,14 @@ static bool setup_vmgexit_scratch(struct vcpu_svm *svm, bool sync, u64 len)
}
scratch_va = kvzalloc(len, GFP_KERNEL_ACCOUNT);
if (!scratch_va)
- goto e_scratch;
+ return -ENOMEM;
if (kvm_read_guest(svm->vcpu.kvm, scratch_gpa_beg, scratch_va, len)) {
/* Unable to copy scratch area from guest */
pr_err("vmgexit: kvm_read_guest for scratch area failed\n");
kvfree(scratch_va);
- goto e_scratch;
+ return -EFAULT;
}
/*
@@ -2616,13 +2641,13 @@ static bool setup_vmgexit_scratch(struct vcpu_svm *svm, bool sync, u64 len)
svm->sev_es.ghcb_sa = scratch_va;
svm->sev_es.ghcb_sa_len = len;
- return true;
+ return 0;
e_scratch:
ghcb_set_sw_exit_info_1(ghcb, 2);
ghcb_set_sw_exit_info_2(ghcb, GHCB_ERR_INVALID_SCRATCH_AREA);
- return false;
+ return 1;
}
static void set_ghcb_msr_bits(struct vcpu_svm *svm, u64 value, u64 mask,
@@ -2760,17 +2785,18 @@ int sev_handle_vmgexit(struct kvm_vcpu *vcpu)
exit_code = ghcb_get_sw_exit_code(ghcb);
- if (!sev_es_validate_vmgexit(svm))
- return 1;
+ ret = sev_es_validate_vmgexit(svm);
+ if (ret)
+ return ret;
sev_es_sync_from_ghcb(svm);
ghcb_set_sw_exit_info_1(ghcb, 0);
ghcb_set_sw_exit_info_2(ghcb, 0);
- ret = 1;
switch (exit_code) {
case SVM_VMGEXIT_MMIO_READ:
- if (!setup_vmgexit_scratch(svm, true, control->exit_info_2))
+ ret = setup_vmgexit_scratch(svm, true, control->exit_info_2);
+ if (ret)
break;
ret = kvm_sev_es_mmio_read(vcpu,
@@ -2779,7 +2805,8 @@ int sev_handle_vmgexit(struct kvm_vcpu *vcpu)
svm->sev_es.ghcb_sa);
break;
case SVM_VMGEXIT_MMIO_WRITE:
- if (!setup_vmgexit_scratch(svm, false, control->exit_info_2))
+ ret = setup_vmgexit_scratch(svm, false, control->exit_info_2);
+ if (ret)
break;
ret = kvm_sev_es_mmio_write(vcpu,
@@ -2812,6 +2839,7 @@ int sev_handle_vmgexit(struct kvm_vcpu *vcpu)
ghcb_set_sw_exit_info_2(ghcb, GHCB_ERR_INVALID_INPUT);
}
+ ret = 1;
break;
}
case SVM_VMGEXIT_UNSUPPORTED_EVENT:
@@ -2831,6 +2859,7 @@ int sev_es_string_io(struct vcpu_svm *svm, int size, unsigned int port, int in)
{
int count;
int bytes;
+ int r;
if (svm->vmcb->control.exit_info_2 > INT_MAX)
return -EINVAL;
@@ -2839,8 +2868,9 @@ int sev_es_string_io(struct vcpu_svm *svm, int size, unsigned int port, int in)
if (unlikely(check_mul_overflow(count, size, &bytes)))
return -EINVAL;
- if (!setup_vmgexit_scratch(svm, in, bytes))
- return 1;
+ r = setup_vmgexit_scratch(svm, in, bytes);
+ if (r)
+ return r;
return kvm_sev_es_string_io(&svm->vcpu, size, port, svm->sev_es.ghcb_sa,
count, in);
@@ -2902,20 +2932,16 @@ void sev_es_vcpu_reset(struct vcpu_svm *svm)
sev_enc_bit));
}
-void sev_es_prepare_guest_switch(struct vcpu_svm *svm, unsigned int cpu)
+void sev_es_prepare_switch_to_guest(struct vmcb_save_area *hostsa)
{
- struct svm_cpu_data *sd = per_cpu(svm_data, cpu);
- struct vmcb_save_area *hostsa;
-
/*
* As an SEV-ES guest, hardware will restore the host state on VMEXIT,
- * of which one step is to perform a VMLOAD. Since hardware does not
- * perform a VMSAVE on VMRUN, the host savearea must be updated.
+ * of which one step is to perform a VMLOAD. KVM performs the
+ * corresponding VMSAVE in svm_prepare_guest_switch for both
+ * traditional and SEV-ES guests.
*/
- vmsave(__sme_page_pa(sd->save_area));
/* XCR0 is restored on VMEXIT, save the current host value */
- hostsa = (struct vmcb_save_area *)(page_address(sd->save_area) + 0x400);
hostsa->xcr0 = xgetbv(XCR_XFEATURE_ENABLED_MASK);
/* PKRU is restored on VMEXIT, save the current host value */
diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c
index 2c99b18d76c0..0884c3414a1b 100644
--- a/arch/x86/kvm/svm/svm.c
+++ b/arch/x86/kvm/svm/svm.c
@@ -263,7 +263,7 @@ u32 svm_msrpm_offset(u32 msr)
return MSR_INVALID;
}
-#define MAX_INST_SIZE 15
+static void svm_flush_tlb_current(struct kvm_vcpu *vcpu);
static int get_npt_level(void)
{
@@ -290,7 +290,7 @@ int svm_set_efer(struct kvm_vcpu *vcpu, u64 efer)
if ((old_efer & EFER_SVME) != (efer & EFER_SVME)) {
if (!(efer & EFER_SVME)) {
- svm_leave_nested(svm);
+ svm_leave_nested(vcpu);
svm_set_gif(svm, true);
/* #GP intercept is still needed for vmware backdoor */
if (!enable_vmware_backdoor)
@@ -312,7 +312,11 @@ int svm_set_efer(struct kvm_vcpu *vcpu, u64 efer)
return ret;
}
- if (svm_gp_erratum_intercept)
+ /*
+ * Never intercept #GP for SEV guests, KVM can't
+ * decrypt guest memory to workaround the erratum.
+ */
+ if (svm_gp_erratum_intercept && !sev_guest(vcpu->kvm))
set_exception_intercept(svm, GP_VECTOR);
}
}
@@ -349,7 +353,7 @@ static void svm_set_interrupt_shadow(struct kvm_vcpu *vcpu, int mask)
}
-static int skip_emulated_instruction(struct kvm_vcpu *vcpu)
+static int svm_skip_emulated_instruction(struct kvm_vcpu *vcpu)
{
struct vcpu_svm *svm = to_svm(vcpu);
@@ -397,7 +401,7 @@ static void svm_queue_exception(struct kvm_vcpu *vcpu)
* raises a fault that is not intercepted. Still better than
* failing in all cases.
*/
- (void)skip_emulated_instruction(vcpu);
+ (void)svm_skip_emulated_instruction(vcpu);
rip = kvm_rip_read(vcpu);
svm->int3_rip = rip + svm->vmcb->save.cs.base;
svm->int3_injected = rip - old_rip;
@@ -664,6 +668,7 @@ static bool msr_write_intercepted(struct kvm_vcpu *vcpu, u32 msr)
static void set_msr_interception_bitmap(struct kvm_vcpu *vcpu, u32 *msrpm,
u32 msr, int read, int write)
{
+ struct vcpu_svm *svm = to_svm(vcpu);
u8 bit_read, bit_write;
unsigned long tmp;
u32 offset;
@@ -694,7 +699,7 @@ static void set_msr_interception_bitmap(struct kvm_vcpu *vcpu, u32 *msrpm,
msrpm[offset] = tmp;
svm_hv_vmcb_dirty_nested_enlightenments(vcpu);
-
+ svm->nested.force_msr_bitmap_recalc = true;
}
void set_msr_interception(struct kvm_vcpu *vcpu, u32 *msrpm, u32 msr,
@@ -869,11 +874,11 @@ static void shrink_ple_window(struct kvm_vcpu *vcpu)
}
}
-static void svm_hardware_teardown(void)
+static void svm_hardware_unsetup(void)
{
int cpu;
- sev_hardware_teardown();
+ sev_hardware_unsetup();
for_each_possible_cpu(cpu)
svm_cpu_uninit(cpu);
@@ -1010,9 +1015,10 @@ static void init_vmcb(struct kvm_vcpu *vcpu)
* Guest access to VMware backdoor ports could legitimately
* trigger #GP because of TSS I/O permission bitmap.
* We intercept those #GP and allow access to them anyway
- * as VMware does.
+ * as VMware does. Don't intercept #GP for SEV guests as KVM can't
+ * decrypt guest memory to decode the faulting instruction.
*/
- if (enable_vmware_backdoor)
+ if (enable_vmware_backdoor && !sev_guest(vcpu->kvm))
set_exception_intercept(svm, GP_VECTOR);
svm_set_intercept(svm, INTERCEPT_INTR);
@@ -1170,7 +1176,7 @@ void svm_switch_vmcb(struct vcpu_svm *svm, struct kvm_vmcb_info *target_vmcb)
svm->vmcb = target_vmcb->ptr;
}
-static int svm_create_vcpu(struct kvm_vcpu *vcpu)
+static int svm_vcpu_create(struct kvm_vcpu *vcpu)
{
struct vcpu_svm *svm;
struct page *vmcb01_page;
@@ -1241,7 +1247,7 @@ static void svm_clear_current_vmcb(struct vmcb *vmcb)
cmpxchg(&per_cpu(svm_data, i)->current_vmcb, vmcb, NULL);
}
-static void svm_free_vcpu(struct kvm_vcpu *vcpu)
+static void svm_vcpu_free(struct kvm_vcpu *vcpu)
{
struct vcpu_svm *svm = to_svm(vcpu);
@@ -1260,7 +1266,7 @@ static void svm_free_vcpu(struct kvm_vcpu *vcpu)
__free_pages(virt_to_page(svm->msrpm), get_order(MSRPM_SIZE));
}
-static void svm_prepare_guest_switch(struct kvm_vcpu *vcpu)
+static void svm_prepare_switch_to_guest(struct kvm_vcpu *vcpu)
{
struct vcpu_svm *svm = to_svm(vcpu);
struct svm_cpu_data *sd = per_cpu(svm_data, vcpu->cpu);
@@ -1275,10 +1281,12 @@ static void svm_prepare_guest_switch(struct kvm_vcpu *vcpu)
* Save additional host state that will be restored on VMEXIT (sev-es)
* or subsequent vmload of host save area.
*/
+ vmsave(__sme_page_pa(sd->save_area));
if (sev_es_guest(vcpu->kvm)) {
- sev_es_prepare_guest_switch(svm, vcpu->cpu);
- } else {
- vmsave(__sme_page_pa(sd->save_area));
+ struct vmcb_save_area *hostsa;
+ hostsa = (struct vmcb_save_area *)(page_address(sd->save_area) + 0x400);
+
+ sev_es_prepare_switch_to_guest(hostsa);
}
if (tsc_scaling) {
@@ -1310,13 +1318,13 @@ static void svm_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
indirect_branch_prediction_barrier();
}
if (kvm_vcpu_apicv_active(vcpu))
- avic_vcpu_load(vcpu, cpu);
+ __avic_vcpu_load(vcpu, cpu);
}
static void svm_vcpu_put(struct kvm_vcpu *vcpu)
{
if (kvm_vcpu_apicv_active(vcpu))
- avic_vcpu_put(vcpu);
+ __avic_vcpu_put(vcpu);
svm_prepare_host_switch(vcpu);
@@ -1524,6 +1532,15 @@ static int svm_get_cpl(struct kvm_vcpu *vcpu)
return save->cpl;
}
+static void svm_get_cs_db_l_bits(struct kvm_vcpu *vcpu, int *db, int *l)
+{
+ struct kvm_segment cs;
+
+ svm_get_segment(vcpu, &cs, VCPU_SREG_CS);
+ *db = cs.db;
+ *l = cs.l;
+}
+
static void svm_get_idt(struct kvm_vcpu *vcpu, struct desc_ptr *dt)
{
struct vcpu_svm *svm = to_svm(vcpu);
@@ -1558,7 +1575,7 @@ static void svm_set_gdt(struct kvm_vcpu *vcpu, struct desc_ptr *dt)
vmcb_mark_dirty(svm->vmcb, VMCB_DT);
}
-static void svm_post_set_cr3(struct kvm_vcpu *vcpu, unsigned long cr3)
+static void sev_post_set_cr3(struct kvm_vcpu *vcpu, unsigned long cr3)
{
struct vcpu_svm *svm = to_svm(vcpu);
@@ -1580,6 +1597,7 @@ void svm_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0)
{
struct vcpu_svm *svm = to_svm(vcpu);
u64 hcr0 = cr0;
+ bool old_paging = is_paging(vcpu);
#ifdef CONFIG_X86_64
if (vcpu->arch.efer & EFER_LME && !vcpu->arch.guest_state_protected) {
@@ -1596,8 +1614,11 @@ void svm_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0)
#endif
vcpu->arch.cr0 = cr0;
- if (!npt_enabled)
+ if (!npt_enabled) {
hcr0 |= X86_CR0_PG | X86_CR0_WP;
+ if (old_paging != is_paging(vcpu))
+ svm_set_cr4(vcpu, kvm_read_cr4(vcpu));
+ }
/*
* re-enable caching here because the QEMU bios
@@ -1638,11 +1659,15 @@ void svm_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4)
unsigned long old_cr4 = vcpu->arch.cr4;
if (npt_enabled && ((old_cr4 ^ cr4) & X86_CR4_PGE))
- svm_flush_tlb(vcpu);
+ svm_flush_tlb_current(vcpu);
vcpu->arch.cr4 = cr4;
- if (!npt_enabled)
+ if (!npt_enabled) {
cr4 |= X86_CR4_PAE;
+
+ if (!is_paging(vcpu))
+ cr4 &= ~(X86_CR4_SMEP | X86_CR4_SMAP | X86_CR4_PKE);
+ }
cr4 |= host_cr4_mce;
to_svm(vcpu)->vmcb->save.cr4 = cr4;
vmcb_mark_dirty(to_svm(vcpu)->vmcb, VMCB_CR);
@@ -2091,10 +2116,6 @@ static int gp_interception(struct kvm_vcpu *vcpu)
if (error_code)
goto reinject;
- /* All SVM instructions expect page aligned RAX */
- if (svm->vmcb->save.rax & ~PAGE_MASK)
- goto reinject;
-
/* Decode the instruction for usage later */
if (x86_decode_emulated_instruction(vcpu, 0, NULL, 0) != EMULATION_OK)
goto reinject;
@@ -2112,8 +2133,13 @@ static int gp_interception(struct kvm_vcpu *vcpu)
if (!is_guest_mode(vcpu))
return kvm_emulate_instruction(vcpu,
EMULTYPE_VMWARE_GP | EMULTYPE_NO_DECODE);
- } else
+ } else {
+ /* All SVM instructions expect page aligned RAX */
+ if (svm->vmcb->save.rax & ~PAGE_MASK)
+ goto reinject;
+
return emulate_svm_instr(vcpu, opcode);
+ }
reinject:
kvm_queue_exception_e(vcpu, GP_VECTOR, error_code);
@@ -2255,7 +2281,7 @@ static int task_switch_interception(struct kvm_vcpu *vcpu)
int_type == SVM_EXITINTINFO_TYPE_SOFT ||
(int_type == SVM_EXITINTINFO_TYPE_EXEPT &&
(int_vec == OF_VECTOR || int_vec == BP_VECTOR))) {
- if (!skip_emulated_instruction(vcpu))
+ if (!svm_skip_emulated_instruction(vcpu))
return 0;
}
@@ -2679,8 +2705,23 @@ static int svm_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr)
u64 data = msr->data;
switch (ecx) {
case MSR_AMD64_TSC_RATIO:
- if (!msr->host_initiated && !svm->tsc_scaling_enabled)
- return 1;
+
+ if (!svm->tsc_scaling_enabled) {
+
+ if (!msr->host_initiated)
+ return 1;
+ /*
+ * In case TSC scaling is not enabled, always
+ * leave this MSR at the default value.
+ *
+ * Due to bug in qemu 6.2.0, it would try to set
+ * this msr to 0 if tsc scaling is not enabled.
+ * Ignore this value as well.
+ */
+ if (data != 0 && data != svm->tsc_ratio_msr)
+ return 1;
+ break;
+ }
if (data & TSC_RATIO_RSVD)
return 1;
@@ -3120,7 +3161,7 @@ static void dump_vmcb(struct kvm_vcpu *vcpu)
"excp_to:", save->last_excp_to);
}
-static bool svm_check_exit_valid(struct kvm_vcpu *vcpu, u64 exit_code)
+static bool svm_check_exit_valid(u64 exit_code)
{
return (exit_code < ARRAY_SIZE(svm_exit_handlers) &&
svm_exit_handlers[exit_code]);
@@ -3140,7 +3181,7 @@ static int svm_handle_invalid_exit(struct kvm_vcpu *vcpu, u64 exit_code)
int svm_invoke_exit_handler(struct kvm_vcpu *vcpu, u64 exit_code)
{
- if (!svm_check_exit_valid(vcpu, exit_code))
+ if (!svm_check_exit_valid(exit_code))
return svm_handle_invalid_exit(vcpu, exit_code);
#ifdef CONFIG_RETPOLINE
@@ -3175,7 +3216,7 @@ static void svm_get_exit_info(struct kvm_vcpu *vcpu, u32 *reason,
*error_code = 0;
}
-static int handle_exit(struct kvm_vcpu *vcpu, fastpath_t exit_fastpath)
+static int svm_handle_exit(struct kvm_vcpu *vcpu, fastpath_t exit_fastpath)
{
struct vcpu_svm *svm = to_svm(vcpu);
struct kvm_run *kvm_run = vcpu->run;
@@ -3272,7 +3313,7 @@ static void svm_inject_nmi(struct kvm_vcpu *vcpu)
++vcpu->stat.nmi_injections;
}
-static void svm_set_irq(struct kvm_vcpu *vcpu)
+static void svm_inject_irq(struct kvm_vcpu *vcpu)
{
struct vcpu_svm *svm = to_svm(vcpu);
@@ -3285,6 +3326,55 @@ static void svm_set_irq(struct kvm_vcpu *vcpu)
SVM_EVTINJ_VALID | SVM_EVTINJ_TYPE_INTR;
}
+void svm_complete_interrupt_delivery(struct kvm_vcpu *vcpu, int delivery_mode,
+ int trig_mode, int vector)
+{
+ /*
+ * vcpu->arch.apicv_active must be read after vcpu->mode.
+ * Pairs with smp_store_release in vcpu_enter_guest.
+ */
+ bool in_guest_mode = (smp_load_acquire(&vcpu->mode) == IN_GUEST_MODE);
+
+ if (!READ_ONCE(vcpu->arch.apicv_active)) {
+ /* Process the interrupt via inject_pending_event */
+ kvm_make_request(KVM_REQ_EVENT, vcpu);
+ kvm_vcpu_kick(vcpu);
+ return;
+ }
+
+ trace_kvm_apicv_accept_irq(vcpu->vcpu_id, delivery_mode, trig_mode, vector);
+ if (in_guest_mode) {
+ /*
+ * Signal the doorbell to tell hardware to inject the IRQ. If
+ * the vCPU exits the guest before the doorbell chimes, hardware
+ * will automatically process AVIC interrupts at the next VMRUN.
+ */
+ avic_ring_doorbell(vcpu);
+ } else {
+ /*
+ * Wake the vCPU if it was blocking. KVM will then detect the
+ * pending IRQ when checking if the vCPU has a wake event.
+ */
+ kvm_vcpu_wake_up(vcpu);
+ }
+}
+
+static void svm_deliver_interrupt(struct kvm_lapic *apic, int delivery_mode,
+ int trig_mode, int vector)
+{
+ kvm_lapic_set_irr(vector, apic);
+
+ /*
+ * Pairs with the smp_mb_*() after setting vcpu->guest_mode in
+ * vcpu_enter_guest() to ensure the write to the vIRR is ordered before
+ * the read of guest_mode. This guarantees that either VMRUN will see
+ * and process the new vIRR entry, or that svm_complete_interrupt_delivery
+ * will signal the doorbell if the CPU has already entered the guest.
+ */
+ smp_mb__after_atomic();
+ svm_complete_interrupt_delivery(apic->vcpu, delivery_mode, trig_mode, vector);
+}
+
static void svm_update_cr8_intercept(struct kvm_vcpu *vcpu, int tpr, int irr)
{
struct vcpu_svm *svm = to_svm(vcpu);
@@ -3332,11 +3422,13 @@ static int svm_nmi_allowed(struct kvm_vcpu *vcpu, bool for_injection)
if (svm->nested.nested_run_pending)
return -EBUSY;
+ if (svm_nmi_blocked(vcpu))
+ return 0;
+
/* An NMI must not be injected into L2 if it's supposed to VM-Exit. */
if (for_injection && is_guest_mode(vcpu) && nested_exit_on_nmi(svm))
return -EBUSY;
-
- return !svm_nmi_blocked(vcpu);
+ return 1;
}
static bool svm_get_nmi_mask(struct kvm_vcpu *vcpu)
@@ -3388,9 +3480,13 @@ bool svm_interrupt_blocked(struct kvm_vcpu *vcpu)
static int svm_interrupt_allowed(struct kvm_vcpu *vcpu, bool for_injection)
{
struct vcpu_svm *svm = to_svm(vcpu);
+
if (svm->nested.nested_run_pending)
return -EBUSY;
+ if (svm_interrupt_blocked(vcpu))
+ return 0;
+
/*
* An IRQ must not be injected into L2 if it's supposed to VM-Exit,
* e.g. if the IRQ arrived asynchronously after checking nested events.
@@ -3398,7 +3494,7 @@ static int svm_interrupt_allowed(struct kvm_vcpu *vcpu, bool for_injection)
if (for_injection && is_guest_mode(vcpu) && nested_exit_on_intr(svm))
return -EBUSY;
- return !svm_interrupt_blocked(vcpu);
+ return 1;
}
static void svm_enable_irq_window(struct kvm_vcpu *vcpu)
@@ -3447,17 +3543,7 @@ static void svm_enable_nmi_window(struct kvm_vcpu *vcpu)
svm->vmcb->save.rflags |= (X86_EFLAGS_TF | X86_EFLAGS_RF);
}
-static int svm_set_tss_addr(struct kvm *kvm, unsigned int addr)
-{
- return 0;
-}
-
-static int svm_set_identity_map_addr(struct kvm *kvm, u64 ident_addr)
-{
- return 0;
-}
-
-void svm_flush_tlb(struct kvm_vcpu *vcpu)
+static void svm_flush_tlb_current(struct kvm_vcpu *vcpu)
{
struct vcpu_svm *svm = to_svm(vcpu);
@@ -3609,7 +3695,7 @@ static noinstr void svm_vcpu_enter_exit(struct kvm_vcpu *vcpu)
struct vcpu_svm *svm = to_svm(vcpu);
unsigned long vmcb_pa = svm->current_vmcb->pa;
- kvm_guest_enter_irqoff();
+ guest_state_enter_irqoff();
if (sev_es_guest(vcpu->kvm)) {
__svm_sev_es_vcpu_run(vmcb_pa);
@@ -3629,7 +3715,7 @@ static noinstr void svm_vcpu_enter_exit(struct kvm_vcpu *vcpu)
vmload(__sme_page_pa(sd->save_area));
}
- kvm_guest_exit_irqoff();
+ guest_state_exit_irqoff();
}
static __no_kcsan fastpath_t svm_vcpu_run(struct kvm_vcpu *vcpu)
@@ -3831,11 +3917,6 @@ static int __init svm_check_processor_compat(void)
return 0;
}
-static bool svm_cpu_has_accelerated_tpr(void)
-{
- return false;
-}
-
/*
* The kvm parameter can be NULL (module initialization, or invocation before
* VM creation). Be sure to check the kvm parameter before using it.
@@ -4129,11 +4210,14 @@ static int svm_smi_allowed(struct kvm_vcpu *vcpu, bool for_injection)
if (svm->nested.nested_run_pending)
return -EBUSY;
+ if (svm_smi_blocked(vcpu))
+ return 0;
+
/* An SMI must not be injected into L2 if it's supposed to VM-Exit. */
if (for_injection && is_guest_mode(vcpu) && nested_exit_on_smi(svm))
return -EBUSY;
- return !svm_smi_blocked(vcpu);
+ return 1;
}
static int svm_enter_smm(struct kvm_vcpu *vcpu, char *smstate)
@@ -4167,7 +4251,7 @@ static int svm_enter_smm(struct kvm_vcpu *vcpu, char *smstate)
* by 0x400 (matches the offset of 'struct vmcb_save_area'
* within 'struct vmcb'). Note: HSAVE area may also be used by
* L1 hypervisor to save additional host context (e.g. KVM does
- * that, see svm_prepare_guest_switch()) which must be
+ * that, see svm_prepare_switch_to_guest()) which must be
* preserved.
*/
if (kvm_vcpu_map(vcpu, gpa_to_gfn(svm->nested.hsave_msr),
@@ -4227,11 +4311,18 @@ static int svm_leave_smm(struct kvm_vcpu *vcpu, const char *smstate)
* Enter the nested guest now
*/
+ vmcb_mark_all_dirty(svm->vmcb01.ptr);
+
vmcb12 = map.hva;
nested_copy_vmcb_control_to_cache(svm, &vmcb12->control);
nested_copy_vmcb_save_to_cache(svm, &vmcb12->save);
ret = enter_svm_guest_mode(vcpu, vmcb12_gpa, vmcb12, false);
+ if (ret)
+ goto unmap_save;
+
+ svm->nested.nested_run_pending = 1;
+
unmap_save:
kvm_vcpu_unmap(vcpu, &map_save, true);
unmap_map:
@@ -4252,79 +4343,140 @@ static void svm_enable_smi_window(struct kvm_vcpu *vcpu)
}
}
-static bool svm_can_emulate_instruction(struct kvm_vcpu *vcpu, void *insn, int insn_len)
+static bool svm_can_emulate_instruction(struct kvm_vcpu *vcpu, int emul_type,
+ void *insn, int insn_len)
{
bool smep, smap, is_user;
unsigned long cr4;
+ u64 error_code;
+
+ /* Emulation is always possible when KVM has access to all guest state. */
+ if (!sev_guest(vcpu->kvm))
+ return true;
+
+ /* #UD and #GP should never be intercepted for SEV guests. */
+ WARN_ON_ONCE(emul_type & (EMULTYPE_TRAP_UD |
+ EMULTYPE_TRAP_UD_FORCED |
+ EMULTYPE_VMWARE_GP));
/*
- * When the guest is an SEV-ES guest, emulation is not possible.
+ * Emulation is impossible for SEV-ES guests as KVM doesn't have access
+ * to guest register state.
*/
if (sev_es_guest(vcpu->kvm))
return false;
/*
+ * Emulation is possible if the instruction is already decoded, e.g.
+ * when completing I/O after returning from userspace.
+ */
+ if (emul_type & EMULTYPE_NO_DECODE)
+ return true;
+
+ /*
+ * Emulation is possible for SEV guests if and only if a prefilled
+ * buffer containing the bytes of the intercepted instruction is
+ * available. SEV guest memory is encrypted with a guest specific key
+ * and cannot be decrypted by KVM, i.e. KVM would read cyphertext and
+ * decode garbage.
+ *
+ * Inject #UD if KVM reached this point without an instruction buffer.
+ * In practice, this path should never be hit by a well-behaved guest,
+ * e.g. KVM doesn't intercept #UD or #GP for SEV guests, but this path
+ * is still theoretically reachable, e.g. via unaccelerated fault-like
+ * AVIC access, and needs to be handled by KVM to avoid putting the
+ * guest into an infinite loop. Injecting #UD is somewhat arbitrary,
+ * but its the least awful option given lack of insight into the guest.
+ */
+ if (unlikely(!insn)) {
+ kvm_queue_exception(vcpu, UD_VECTOR);
+ return false;
+ }
+
+ /*
+ * Emulate for SEV guests if the insn buffer is not empty. The buffer
+ * will be empty if the DecodeAssist microcode cannot fetch bytes for
+ * the faulting instruction because the code fetch itself faulted, e.g.
+ * the guest attempted to fetch from emulated MMIO or a guest page
+ * table used to translate CS:RIP resides in emulated MMIO.
+ */
+ if (likely(insn_len))
+ return true;
+
+ /*
* Detect and workaround Errata 1096 Fam_17h_00_0Fh.
*
* Errata:
- * When CPU raise #NPF on guest data access and vCPU CR4.SMAP=1, it is
- * possible that CPU microcode implementing DecodeAssist will fail
- * to read bytes of instruction which caused #NPF. In this case,
- * GuestIntrBytes field of the VMCB on a VMEXIT will incorrectly
- * return 0 instead of the correct guest instruction bytes.
+ * When CPU raises #NPF on guest data access and vCPU CR4.SMAP=1, it is
+ * possible that CPU microcode implementing DecodeAssist will fail to
+ * read guest memory at CS:RIP and vmcb.GuestIntrBytes will incorrectly
+ * be '0'. This happens because microcode reads CS:RIP using a _data_
+ * loap uop with CPL=0 privileges. If the load hits a SMAP #PF, ucode
+ * gives up and does not fill the instruction bytes buffer.
*
- * This happens because CPU microcode reading instruction bytes
- * uses a special opcode which attempts to read data using CPL=0
- * privileges. The microcode reads CS:RIP and if it hits a SMAP
- * fault, it gives up and returns no instruction bytes.
+ * As above, KVM reaches this point iff the VM is an SEV guest, the CPU
+ * supports DecodeAssist, a #NPF was raised, KVM's page fault handler
+ * triggered emulation (e.g. for MMIO), and the CPU returned 0 in the
+ * GuestIntrBytes field of the VMCB.
*
- * Detection:
- * We reach here in case CPU supports DecodeAssist, raised #NPF and
- * returned 0 in GuestIntrBytes field of the VMCB.
- * First, errata can only be triggered in case vCPU CR4.SMAP=1.
- * Second, if vCPU CR4.SMEP=1, errata could only be triggered
- * in case vCPU CPL==3 (Because otherwise guest would have triggered
- * a SMEP fault instead of #NPF).
- * Otherwise, vCPU CR4.SMEP=0, errata could be triggered by any vCPU CPL.
- * As most guests enable SMAP if they have also enabled SMEP, use above
- * logic in order to attempt minimize false-positive of detecting errata
- * while still preserving all cases semantic correctness.
+ * This does _not_ mean that the erratum has been encountered, as the
+ * DecodeAssist will also fail if the load for CS:RIP hits a legitimate
+ * #PF, e.g. if the guest attempt to execute from emulated MMIO and
+ * encountered a reserved/not-present #PF.
*
- * Workaround:
- * To determine what instruction the guest was executing, the hypervisor
- * will have to decode the instruction at the instruction pointer.
+ * To hit the erratum, the following conditions must be true:
+ * 1. CR4.SMAP=1 (obviously).
+ * 2. CR4.SMEP=0 || CPL=3. If SMEP=1 and CPL<3, the erratum cannot
+ * have been hit as the guest would have encountered a SMEP
+ * violation #PF, not a #NPF.
+ * 3. The #NPF is not due to a code fetch, in which case failure to
+ * retrieve the instruction bytes is legitimate (see abvoe).
*
- * In non SEV guest, hypervisor will be able to read the guest
- * memory to decode the instruction pointer when insn_len is zero
- * so we return true to indicate that decoding is possible.
- *
- * But in the SEV guest, the guest memory is encrypted with the
- * guest specific key and hypervisor will not be able to decode the
- * instruction pointer so we will not able to workaround it. Lets
- * print the error and request to kill the guest.
+ * In addition, don't apply the erratum workaround if the #NPF occurred
+ * while translating guest page tables (see below).
*/
- if (likely(!insn || insn_len))
- return true;
-
- /*
- * If RIP is invalid, go ahead with emulation which will cause an
- * internal error exit.
- */
- if (!kvm_vcpu_gfn_to_memslot(vcpu, kvm_rip_read(vcpu) >> PAGE_SHIFT))
- return true;
+ error_code = to_svm(vcpu)->vmcb->control.exit_info_1;
+ if (error_code & (PFERR_GUEST_PAGE_MASK | PFERR_FETCH_MASK))
+ goto resume_guest;
cr4 = kvm_read_cr4(vcpu);
smep = cr4 & X86_CR4_SMEP;
smap = cr4 & X86_CR4_SMAP;
is_user = svm_get_cpl(vcpu) == 3;
if (smap && (!smep || is_user)) {
- if (!sev_guest(vcpu->kvm))
- return true;
-
pr_err_ratelimited("KVM: SEV Guest triggered AMD Erratum 1096\n");
- kvm_make_request(KVM_REQ_TRIPLE_FAULT, vcpu);
+
+ /*
+ * If the fault occurred in userspace, arbitrarily inject #GP
+ * to avoid killing the guest and to hopefully avoid confusing
+ * the guest kernel too much, e.g. injecting #PF would not be
+ * coherent with respect to the guest's page tables. Request
+ * triple fault if the fault occurred in the kernel as there's
+ * no fault that KVM can inject without confusing the guest.
+ * In practice, the triple fault is moot as no sane SEV kernel
+ * will execute from user memory while also running with SMAP=1.
+ */
+ if (is_user)
+ kvm_inject_gp(vcpu, 0);
+ else
+ kvm_make_request(KVM_REQ_TRIPLE_FAULT, vcpu);
}
+resume_guest:
+ /*
+ * If the erratum was not hit, simply resume the guest and let it fault
+ * again. While awful, e.g. the vCPU may get stuck in an infinite loop
+ * if the fault is at CPL=0, it's the lesser of all evils. Exiting to
+ * userspace will kill the guest, and letting the emulator read garbage
+ * will yield random behavior and potentially corrupt the guest.
+ *
+ * Simply resuming the guest is technically not a violation of the SEV
+ * architecture. AMD's APM states that all code fetches and page table
+ * accesses for SEV guest are encrypted, regardless of the C-Bit. The
+ * APM also states that encrypted accesses to MMIO are "ignored", but
+ * doesn't explicitly define "ignored", i.e. doing nothing and letting
+ * the guest spin is technically "ignoring" the access.
+ */
return false;
}
@@ -4374,21 +4526,20 @@ static int svm_vm_init(struct kvm *kvm)
static struct kvm_x86_ops svm_x86_ops __initdata = {
.name = "kvm_amd",
- .hardware_unsetup = svm_hardware_teardown,
+ .hardware_unsetup = svm_hardware_unsetup,
.hardware_enable = svm_hardware_enable,
.hardware_disable = svm_hardware_disable,
- .cpu_has_accelerated_tpr = svm_cpu_has_accelerated_tpr,
.has_emulated_msr = svm_has_emulated_msr,
- .vcpu_create = svm_create_vcpu,
- .vcpu_free = svm_free_vcpu,
+ .vcpu_create = svm_vcpu_create,
+ .vcpu_free = svm_vcpu_free,
.vcpu_reset = svm_vcpu_reset,
.vm_size = sizeof(struct kvm_svm),
.vm_init = svm_vm_init,
.vm_destroy = svm_vm_destroy,
- .prepare_guest_switch = svm_prepare_guest_switch,
+ .prepare_switch_to_guest = svm_prepare_switch_to_guest,
.vcpu_load = svm_vcpu_load,
.vcpu_put = svm_vcpu_put,
.vcpu_blocking = avic_vcpu_blocking,
@@ -4402,9 +4553,9 @@ static struct kvm_x86_ops svm_x86_ops __initdata = {
.get_segment = svm_get_segment,
.set_segment = svm_set_segment,
.get_cpl = svm_get_cpl,
- .get_cs_db_l_bits = kvm_get_cs_db_l_bits,
+ .get_cs_db_l_bits = svm_get_cs_db_l_bits,
.set_cr0 = svm_set_cr0,
- .post_set_cr3 = svm_post_set_cr3,
+ .post_set_cr3 = sev_post_set_cr3,
.is_valid_cr4 = svm_is_valid_cr4,
.set_cr4 = svm_set_cr4,
.set_efer = svm_set_efer,
@@ -4419,21 +4570,21 @@ static struct kvm_x86_ops svm_x86_ops __initdata = {
.set_rflags = svm_set_rflags,
.get_if_flag = svm_get_if_flag,
- .tlb_flush_all = svm_flush_tlb,
- .tlb_flush_current = svm_flush_tlb,
- .tlb_flush_gva = svm_flush_tlb_gva,
- .tlb_flush_guest = svm_flush_tlb,
+ .flush_tlb_all = svm_flush_tlb_current,
+ .flush_tlb_current = svm_flush_tlb_current,
+ .flush_tlb_gva = svm_flush_tlb_gva,
+ .flush_tlb_guest = svm_flush_tlb_current,
.vcpu_pre_run = svm_vcpu_pre_run,
- .run = svm_vcpu_run,
- .handle_exit = handle_exit,
- .skip_emulated_instruction = skip_emulated_instruction,
+ .vcpu_run = svm_vcpu_run,
+ .handle_exit = svm_handle_exit,
+ .skip_emulated_instruction = svm_skip_emulated_instruction,
.update_emulated_instruction = NULL,
.set_interrupt_shadow = svm_set_interrupt_shadow,
.get_interrupt_shadow = svm_get_interrupt_shadow,
.patch_hypercall = svm_patch_hypercall,
- .set_irq = svm_set_irq,
- .set_nmi = svm_inject_nmi,
+ .inject_irq = svm_inject_irq,
+ .inject_nmi = svm_inject_nmi,
.queue_exception = svm_queue_exception,
.cancel_injection = svm_cancel_injection,
.interrupt_allowed = svm_interrupt_allowed,
@@ -4443,18 +4594,11 @@ static struct kvm_x86_ops svm_x86_ops __initdata = {
.enable_nmi_window = svm_enable_nmi_window,
.enable_irq_window = svm_enable_irq_window,
.update_cr8_intercept = svm_update_cr8_intercept,
- .set_virtual_apic_mode = svm_set_virtual_apic_mode,
- .refresh_apicv_exec_ctrl = svm_refresh_apicv_exec_ctrl,
- .check_apicv_inhibit_reasons = svm_check_apicv_inhibit_reasons,
- .load_eoi_exitmap = svm_load_eoi_exitmap,
- .hwapic_irr_update = svm_hwapic_irr_update,
- .hwapic_isr_update = svm_hwapic_isr_update,
- .apicv_post_state_restore = avic_post_state_restore,
-
- .set_tss_addr = svm_set_tss_addr,
- .set_identity_map_addr = svm_set_identity_map_addr,
- .get_mt_mask = svm_get_mt_mask,
+ .refresh_apicv_exec_ctrl = avic_refresh_apicv_exec_ctrl,
+ .check_apicv_inhibit_reasons = avic_check_apicv_inhibit_reasons,
+ .apicv_post_state_restore = avic_apicv_post_state_restore,
+ .get_mt_mask = svm_get_mt_mask,
.get_exit_info = svm_get_exit_info,
.vcpu_after_set_cpuid = svm_vcpu_after_set_cpuid,
@@ -4478,9 +4622,8 @@ static struct kvm_x86_ops svm_x86_ops __initdata = {
.pmu_ops = &amd_pmu_ops,
.nested_ops = &svm_nested_ops,
- .deliver_posted_interrupt = svm_deliver_avic_intr,
- .dy_apicv_has_pending_interrupt = svm_dy_apicv_has_pending_interrupt,
- .update_pi_irte = svm_update_pi_irte,
+ .deliver_interrupt = svm_deliver_interrupt,
+ .pi_update_irte = avic_pi_update_irte,
.setup_mce = svm_setup_mce,
.smi_allowed = svm_smi_allowed,
@@ -4488,12 +4631,12 @@ static struct kvm_x86_ops svm_x86_ops __initdata = {
.leave_smm = svm_leave_smm,
.enable_smi_window = svm_enable_smi_window,
- .mem_enc_op = svm_mem_enc_op,
- .mem_enc_reg_region = svm_register_enc_region,
- .mem_enc_unreg_region = svm_unregister_enc_region,
+ .mem_enc_ioctl = sev_mem_enc_ioctl,
+ .mem_enc_register_region = sev_mem_enc_register_region,
+ .mem_enc_unregister_region = sev_mem_enc_unregister_region,
- .vm_copy_enc_context_from = svm_vm_copy_asid_from,
- .vm_move_enc_context_from = svm_vm_migrate_from,
+ .vm_copy_enc_context_from = sev_vm_copy_enc_context_from,
+ .vm_move_enc_context_from = sev_vm_move_enc_context_from,
.can_emulate_instruction = svm_can_emulate_instruction,
@@ -4555,6 +4698,7 @@ static __init void svm_set_cpu_caps(void)
/* CPUID 0x80000001 and 0x8000000A (SVM features) */
if (nested) {
kvm_cpu_cap_set(X86_FEATURE_SVM);
+ kvm_cpu_cap_set(X86_FEATURE_VMCBCLEAN);
if (nrips)
kvm_cpu_cap_set(X86_FEATURE_NRIPS);
@@ -4737,7 +4881,7 @@ static __init int svm_hardware_setup(void)
return 0;
err:
- svm_hardware_teardown();
+ svm_hardware_unsetup();
return r;
}
diff --git a/arch/x86/kvm/svm/svm.h b/arch/x86/kvm/svm/svm.h
index 47ef8f4a9358..e37bb3508cfa 100644
--- a/arch/x86/kvm/svm/svm.h
+++ b/arch/x86/kvm/svm/svm.h
@@ -79,7 +79,8 @@ struct kvm_sev_info {
struct list_head regions_list; /* List of registered regions */
u64 ap_jump_table; /* SEV-ES AP Jump Table address */
struct kvm *enc_context_owner; /* Owner of copied encryption context */
- unsigned long num_mirrored_vms; /* Number of VMs sharing this ASID */
+ struct list_head mirror_vms; /* List of VMs mirroring */
+ struct list_head mirror_entry; /* Use as a list entry of mirrors */
struct misc_cg *misc_cg; /* For misc cgroup accounting */
atomic_t migration_in_progress;
};
@@ -137,6 +138,8 @@ struct vmcb_ctrl_area_cached {
u32 event_inj_err;
u64 nested_cr3;
u64 virt_ext;
+ u32 clean;
+ u8 reserved_sw[32];
};
struct svm_nested_state {
@@ -163,6 +166,15 @@ struct svm_nested_state {
struct vmcb_save_area_cached save;
bool initialized;
+
+ /*
+ * Indicates whether MSR bitmap for L2 needs to be rebuilt due to
+ * changes in MSR bitmap for L1 or switching to a different L2. Note,
+ * this flag can only be used reliably in conjunction with a paravirt L1
+ * which informs L0 whether any changes to MSR bitmap for L2 were done
+ * on its side.
+ */
+ bool force_msr_bitmap_recalc;
};
struct vcpu_sev_es_state {
@@ -304,11 +316,6 @@ static inline void vmcb_mark_all_clean(struct vmcb *vmcb)
& ~VMCB_ALWAYS_DIRTY_MASK;
}
-static inline bool vmcb_is_clean(struct vmcb *vmcb, int bit)
-{
- return (vmcb->control.clean & (1 << bit));
-}
-
static inline void vmcb_mark_dirty(struct vmcb *vmcb, int bit)
{
vmcb->control.clean &= ~(1 << bit);
@@ -326,7 +333,7 @@ static __always_inline struct vcpu_svm *to_svm(struct kvm_vcpu *vcpu)
/*
* Only the PDPTRs are loaded on demand into the shadow MMU. All other
- * fields are synchronized in handle_exit, because accessing the VMCB is cheap.
+ * fields are synchronized on VM-Exit, because accessing the VMCB is cheap.
*
* CR3 might be out of date in the VMCB but it is not marked dirty; instead,
* KVM_REQ_LOAD_MMU_PGD is always requested when the cached vcpu->arch.cr3
@@ -485,7 +492,6 @@ void svm_vcpu_free_msrpm(u32 *msrpm);
int svm_set_efer(struct kvm_vcpu *vcpu, u64 efer);
void svm_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0);
void svm_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4);
-void svm_flush_tlb(struct kvm_vcpu *vcpu);
void disable_nmi_singlestep(struct vcpu_svm *svm);
bool svm_smi_blocked(struct kvm_vcpu *vcpu);
bool svm_nmi_blocked(struct kvm_vcpu *vcpu);
@@ -494,6 +500,8 @@ void svm_set_gif(struct vcpu_svm *svm, bool value);
int svm_invoke_exit_handler(struct kvm_vcpu *vcpu, u64 exit_code);
void set_msr_interception(struct kvm_vcpu *vcpu, u32 *msrpm, u32 msr,
int read, int write);
+void svm_complete_interrupt_delivery(struct kvm_vcpu *vcpu, int delivery_mode,
+ int trig_mode, int vec);
/* nested.c */
@@ -525,7 +533,7 @@ static inline bool nested_exit_on_nmi(struct vcpu_svm *svm)
int enter_svm_guest_mode(struct kvm_vcpu *vcpu,
u64 vmcb_gpa, struct vmcb *vmcb12, bool from_vmrun);
-void svm_leave_nested(struct vcpu_svm *svm);
+void svm_leave_nested(struct kvm_vcpu *vcpu);
void svm_free_nested(struct vcpu_svm *svm);
int svm_allocate_nested(struct vcpu_svm *svm);
int nested_svm_vmrun(struct kvm_vcpu *vcpu);
@@ -565,7 +573,7 @@ extern struct kvm_x86_nested_ops svm_nested_ops;
#define AVIC_LOGICAL_ID_ENTRY_VALID_BIT 31
#define AVIC_LOGICAL_ID_ENTRY_VALID_MASK (1 << 31)
-#define AVIC_PHYSICAL_ID_ENTRY_HOST_PHYSICAL_ID_MASK (0xFFULL)
+#define AVIC_PHYSICAL_ID_ENTRY_HOST_PHYSICAL_ID_MASK GENMASK_ULL(11, 0)
#define AVIC_PHYSICAL_ID_ENTRY_BACKING_PAGE_MASK (0xFFFFFFFFFFULL << 12)
#define AVIC_PHYSICAL_ID_ENTRY_IS_RUNNING_MASK (1ULL << 62)
#define AVIC_PHYSICAL_ID_ENTRY_VALID_MASK (1ULL << 63)
@@ -579,21 +587,20 @@ void avic_init_vmcb(struct vcpu_svm *svm);
int avic_incomplete_ipi_interception(struct kvm_vcpu *vcpu);
int avic_unaccelerated_access_interception(struct kvm_vcpu *vcpu);
int avic_init_vcpu(struct vcpu_svm *svm);
-void avic_vcpu_load(struct kvm_vcpu *vcpu, int cpu);
-void avic_vcpu_put(struct kvm_vcpu *vcpu);
-void avic_post_state_restore(struct kvm_vcpu *vcpu);
-void svm_set_virtual_apic_mode(struct kvm_vcpu *vcpu);
-void svm_refresh_apicv_exec_ctrl(struct kvm_vcpu *vcpu);
-bool svm_check_apicv_inhibit_reasons(ulong bit);
-void svm_load_eoi_exitmap(struct kvm_vcpu *vcpu, u64 *eoi_exit_bitmap);
-void svm_hwapic_irr_update(struct kvm_vcpu *vcpu, int max_irr);
-void svm_hwapic_isr_update(struct kvm_vcpu *vcpu, int max_isr);
-int svm_deliver_avic_intr(struct kvm_vcpu *vcpu, int vec);
-bool svm_dy_apicv_has_pending_interrupt(struct kvm_vcpu *vcpu);
-int svm_update_pi_irte(struct kvm *kvm, unsigned int host_irq,
- uint32_t guest_irq, bool set);
+void __avic_vcpu_load(struct kvm_vcpu *vcpu, int cpu);
+void __avic_vcpu_put(struct kvm_vcpu *vcpu);
+void avic_apicv_post_state_restore(struct kvm_vcpu *vcpu);
+void avic_set_virtual_apic_mode(struct kvm_vcpu *vcpu);
+void avic_refresh_apicv_exec_ctrl(struct kvm_vcpu *vcpu);
+bool avic_check_apicv_inhibit_reasons(ulong bit);
+void avic_hwapic_irr_update(struct kvm_vcpu *vcpu, int max_irr);
+void avic_hwapic_isr_update(struct kvm_vcpu *vcpu, int max_isr);
+bool avic_dy_apicv_has_pending_interrupt(struct kvm_vcpu *vcpu);
+int avic_pi_update_irte(struct kvm *kvm, unsigned int host_irq,
+ uint32_t guest_irq, bool set);
void avic_vcpu_blocking(struct kvm_vcpu *vcpu);
void avic_vcpu_unblocking(struct kvm_vcpu *vcpu);
+void avic_ring_doorbell(struct kvm_vcpu *vcpu);
/* sev.c */
@@ -604,17 +611,17 @@ void avic_vcpu_unblocking(struct kvm_vcpu *vcpu);
extern unsigned int max_sev_asid;
void sev_vm_destroy(struct kvm *kvm);
-int svm_mem_enc_op(struct kvm *kvm, void __user *argp);
-int svm_register_enc_region(struct kvm *kvm,
- struct kvm_enc_region *range);
-int svm_unregister_enc_region(struct kvm *kvm,
- struct kvm_enc_region *range);
-int svm_vm_copy_asid_from(struct kvm *kvm, unsigned int source_fd);
-int svm_vm_migrate_from(struct kvm *kvm, unsigned int source_fd);
+int sev_mem_enc_ioctl(struct kvm *kvm, void __user *argp);
+int sev_mem_enc_register_region(struct kvm *kvm,
+ struct kvm_enc_region *range);
+int sev_mem_enc_unregister_region(struct kvm *kvm,
+ struct kvm_enc_region *range);
+int sev_vm_copy_enc_context_from(struct kvm *kvm, unsigned int source_fd);
+int sev_vm_move_enc_context_from(struct kvm *kvm, unsigned int source_fd);
void pre_sev_run(struct vcpu_svm *svm, int cpu);
void __init sev_set_cpu_caps(void);
void __init sev_hardware_setup(void);
-void sev_hardware_teardown(void);
+void sev_hardware_unsetup(void);
int sev_cpu_init(struct svm_cpu_data *sd);
void sev_free_vcpu(struct kvm_vcpu *vcpu);
int sev_handle_vmgexit(struct kvm_vcpu *vcpu);
@@ -622,7 +629,7 @@ int sev_es_string_io(struct vcpu_svm *svm, int size, unsigned int port, int in);
void sev_es_init_vmcb(struct vcpu_svm *svm);
void sev_es_vcpu_reset(struct vcpu_svm *svm);
void sev_vcpu_deliver_sipi_vector(struct kvm_vcpu *vcpu, u8 vector);
-void sev_es_prepare_guest_switch(struct vcpu_svm *svm, unsigned int cpu);
+void sev_es_prepare_switch_to_guest(struct vmcb_save_area *hostsa);
void sev_es_unmap_ghcb(struct vcpu_svm *svm);
/* vmenter.S */
diff --git a/arch/x86/kvm/svm/svm_onhyperv.h b/arch/x86/kvm/svm/svm_onhyperv.h
index c53b8bf8d013..e2fc59380465 100644
--- a/arch/x86/kvm/svm/svm_onhyperv.h
+++ b/arch/x86/kvm/svm/svm_onhyperv.h
@@ -7,35 +7,12 @@
#define __ARCH_X86_KVM_SVM_ONHYPERV_H__
#if IS_ENABLED(CONFIG_HYPERV)
-#include <asm/mshyperv.h>
-#include "hyperv.h"
#include "kvm_onhyperv.h"
+#include "svm/hyperv.h"
static struct kvm_x86_ops svm_x86_ops;
-/*
- * Hyper-V uses the software reserved 32 bytes in VMCB
- * control area to expose SVM enlightenments to guests.
- */
-struct hv_enlightenments {
- struct __packed hv_enlightenments_control {
- u32 nested_flush_hypercall:1;
- u32 msr_bitmap:1;
- u32 enlightened_npt_tlb: 1;
- u32 reserved:29;
- } __packed hv_enlightenments_control;
- u32 hv_vp_id;
- u64 hv_vm_id;
- u64 partition_assist_page;
- u64 reserved;
-} __packed;
-
-/*
- * Hyper-V uses the software reserved clean bit in VMCB
- */
-#define VMCB_HV_NESTED_ENLIGHTENMENTS VMCB_SW
-
int svm_hv_enable_direct_tlbflush(struct kvm_vcpu *vcpu);
static inline void svm_hv_init_vmcb(struct vmcb *vmcb)
@@ -46,6 +23,9 @@ static inline void svm_hv_init_vmcb(struct vmcb *vmcb)
if (npt_enabled &&
ms_hyperv.nested_features & HV_X64_NESTED_ENLIGHTENED_TLB)
hve->hv_enlightenments_control.enlightened_npt_tlb = 1;
+
+ if (ms_hyperv.nested_features & HV_X64_NESTED_MSR_BITMAP)
+ hve->hv_enlightenments_control.msr_bitmap = 1;
}
static inline void svm_hv_hardware_setup(void)
@@ -83,14 +63,7 @@ static inline void svm_hv_vmcb_dirty_nested_enlightenments(
struct hv_enlightenments *hve =
(struct hv_enlightenments *)vmcb->control.reserved_sw;
- /*
- * vmcb can be NULL if called during early vcpu init.
- * And its okay not to mark vmcb dirty during vcpu init
- * as we mark it dirty unconditionally towards end of vcpu
- * init phase.
- */
- if (vmcb_is_clean(vmcb, VMCB_HV_NESTED_ENLIGHTENMENTS) &&
- hve->hv_enlightenments_control.msr_bitmap)
+ if (hve->hv_enlightenments_control.msr_bitmap)
vmcb_mark_dirty(vmcb, VMCB_HV_NESTED_ENLIGHTENMENTS);
}
diff --git a/arch/x86/kvm/trace.h b/arch/x86/kvm/trace.h
index 92e6f6702f00..193f5ba930d1 100644
--- a/arch/x86/kvm/trace.h
+++ b/arch/x86/kvm/trace.h
@@ -64,9 +64,9 @@ TRACE_EVENT(kvm_hypercall,
* Tracepoint for hypercall.
*/
TRACE_EVENT(kvm_hv_hypercall,
- TP_PROTO(__u16 code, bool fast, __u16 rep_cnt, __u16 rep_idx,
- __u64 ingpa, __u64 outgpa),
- TP_ARGS(code, fast, rep_cnt, rep_idx, ingpa, outgpa),
+ TP_PROTO(__u16 code, bool fast, __u16 var_cnt, __u16 rep_cnt,
+ __u16 rep_idx, __u64 ingpa, __u64 outgpa),
+ TP_ARGS(code, fast, var_cnt, rep_cnt, rep_idx, ingpa, outgpa),
TP_STRUCT__entry(
__field( __u16, rep_cnt )
@@ -74,6 +74,7 @@ TRACE_EVENT(kvm_hv_hypercall,
__field( __u64, ingpa )
__field( __u64, outgpa )
__field( __u16, code )
+ __field( __u16, var_cnt )
__field( bool, fast )
),
@@ -83,13 +84,14 @@ TRACE_EVENT(kvm_hv_hypercall,
__entry->ingpa = ingpa;
__entry->outgpa = outgpa;
__entry->code = code;
+ __entry->var_cnt = var_cnt;
__entry->fast = fast;
),
- TP_printk("code 0x%x %s cnt 0x%x idx 0x%x in 0x%llx out 0x%llx",
+ TP_printk("code 0x%x %s var_cnt 0x%x rep_cnt 0x%x idx 0x%x in 0x%llx out 0x%llx",
__entry->code, __entry->fast ? "fast" : "slow",
- __entry->rep_cnt, __entry->rep_idx, __entry->ingpa,
- __entry->outgpa)
+ __entry->var_cnt, __entry->rep_cnt, __entry->rep_idx,
+ __entry->ingpa, __entry->outgpa)
);
TRACE_EVENT(kvm_hv_hypercall_done,
@@ -251,13 +253,13 @@ TRACE_EVENT(kvm_cpuid,
* Tracepoint for apic access.
*/
TRACE_EVENT(kvm_apic,
- TP_PROTO(unsigned int rw, unsigned int reg, unsigned int val),
+ TP_PROTO(unsigned int rw, unsigned int reg, u64 val),
TP_ARGS(rw, reg, val),
TP_STRUCT__entry(
__field( unsigned int, rw )
__field( unsigned int, reg )
- __field( unsigned int, val )
+ __field( u64, val )
),
TP_fast_assign(
@@ -266,7 +268,7 @@ TRACE_EVENT(kvm_apic,
__entry->val = val;
),
- TP_printk("apic_%s %s = 0x%x",
+ TP_printk("apic_%s %s = 0x%llx",
__entry->rw ? "write" : "read",
__print_symbolic(__entry->reg, kvm_trace_symbol_apic),
__entry->val)
diff --git a/arch/x86/kvm/vmx/capabilities.h b/arch/x86/kvm/vmx/capabilities.h
index 959b59d13b5a..3f430e218375 100644
--- a/arch/x86/kvm/vmx/capabilities.h
+++ b/arch/x86/kvm/vmx/capabilities.h
@@ -54,7 +54,6 @@ struct nested_vmx_msrs {
struct vmcs_config {
int size;
- int order;
u32 basic_cap;
u32 revision_id;
u32 pin_based_exec_ctrl;
diff --git a/arch/x86/kvm/vmx/evmcs.c b/arch/x86/kvm/vmx/evmcs.c
index ba6f99f584ac..87e3dc10edf4 100644
--- a/arch/x86/kvm/vmx/evmcs.c
+++ b/arch/x86/kvm/vmx/evmcs.c
@@ -12,8 +12,6 @@
DEFINE_STATIC_KEY_FALSE(enable_evmcs);
-#if IS_ENABLED(CONFIG_HYPERV)
-
#define EVMCS1_OFFSET(x) offsetof(struct hv_enlightened_vmcs, x)
#define EVMCS1_FIELD(number, name, clean_field)[ROL16(number, 6)] = \
{EVMCS1_OFFSET(name), clean_field}
@@ -296,6 +294,7 @@ const struct evmcs_field vmcs_field_to_evmcs_1[] = {
};
const unsigned int nr_evmcs_1_fields = ARRAY_SIZE(vmcs_field_to_evmcs_1);
+#if IS_ENABLED(CONFIG_HYPERV)
__init void evmcs_sanitize_exec_ctrls(struct vmcs_config *vmcs_conf)
{
vmcs_conf->pin_based_exec_ctrl &= ~EVMCS1_UNSUPPORTED_PINCTRL;
@@ -362,6 +361,7 @@ void nested_evmcs_filter_control_msr(u32 msr_index, u64 *pdata)
case MSR_IA32_VMX_PROCBASED_CTLS2:
ctl_high &= ~EVMCS1_UNSUPPORTED_2NDEXEC;
break;
+ case MSR_IA32_VMX_TRUE_PINBASED_CTLS:
case MSR_IA32_VMX_PINBASED_CTLS:
ctl_high &= ~EVMCS1_UNSUPPORTED_PINCTRL;
break;
diff --git a/arch/x86/kvm/vmx/evmcs.h b/arch/x86/kvm/vmx/evmcs.h
index 16731d2cf231..8d70f9aea94b 100644
--- a/arch/x86/kvm/vmx/evmcs.h
+++ b/arch/x86/kvm/vmx/evmcs.h
@@ -59,12 +59,12 @@ DECLARE_STATIC_KEY_FALSE(enable_evmcs);
SECONDARY_EXEC_SHADOW_VMCS | \
SECONDARY_EXEC_TSC_SCALING | \
SECONDARY_EXEC_PAUSE_LOOP_EXITING)
-#define EVMCS1_UNSUPPORTED_VMEXIT_CTRL (VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL)
+#define EVMCS1_UNSUPPORTED_VMEXIT_CTRL \
+ (VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL | \
+ VM_EXIT_SAVE_VMX_PREEMPTION_TIMER)
#define EVMCS1_UNSUPPORTED_VMENTRY_CTRL (VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL)
#define EVMCS1_UNSUPPORTED_VMFUNC (VMX_VMFUNC_EPTP_SWITCHING)
-#if IS_ENABLED(CONFIG_HYPERV)
-
struct evmcs_field {
u16 offset;
u16 clean_field;
@@ -73,26 +73,56 @@ struct evmcs_field {
extern const struct evmcs_field vmcs_field_to_evmcs_1[];
extern const unsigned int nr_evmcs_1_fields;
-static __always_inline int get_evmcs_offset(unsigned long field,
- u16 *clean_field)
+static __always_inline int evmcs_field_offset(unsigned long field,
+ u16 *clean_field)
{
unsigned int index = ROL16(field, 6);
const struct evmcs_field *evmcs_field;
- if (unlikely(index >= nr_evmcs_1_fields)) {
- WARN_ONCE(1, "KVM: accessing unsupported EVMCS field %lx\n",
- field);
+ if (unlikely(index >= nr_evmcs_1_fields))
return -ENOENT;
- }
evmcs_field = &vmcs_field_to_evmcs_1[index];
+ /*
+ * Use offset=0 to detect holes in eVMCS. This offset belongs to
+ * 'revision_id' but this field has no encoding and is supposed to
+ * be accessed directly.
+ */
+ if (unlikely(!evmcs_field->offset))
+ return -ENOENT;
+
if (clean_field)
*clean_field = evmcs_field->clean_field;
return evmcs_field->offset;
}
+static inline u64 evmcs_read_any(struct hv_enlightened_vmcs *evmcs,
+ unsigned long field, u16 offset)
+{
+ /*
+ * vmcs12_read_any() doesn't care whether the supplied structure
+ * is 'struct vmcs12' or 'struct hv_enlightened_vmcs' as it takes
+ * the exact offset of the required field, use it for convenience
+ * here.
+ */
+ return vmcs12_read_any((void *)evmcs, field, offset);
+}
+
+#if IS_ENABLED(CONFIG_HYPERV)
+
+static __always_inline int get_evmcs_offset(unsigned long field,
+ u16 *clean_field)
+{
+ int offset = evmcs_field_offset(field, clean_field);
+
+ WARN_ONCE(offset < 0, "KVM: accessing unsupported EVMCS field %lx\n",
+ field);
+
+ return offset;
+}
+
static __always_inline void evmcs_write64(unsigned long field, u64 value)
{
u16 clean_field;
diff --git a/arch/x86/kvm/vmx/nested.c b/arch/x86/kvm/vmx/nested.c
index f235f77cbc03..f18744f7ff82 100644
--- a/arch/x86/kvm/vmx/nested.c
+++ b/arch/x86/kvm/vmx/nested.c
@@ -7,6 +7,7 @@
#include <asm/mmu_context.h>
#include "cpuid.h"
+#include "evmcs.h"
#include "hyperv.h"
#include "mmu.h"
#include "nested.h"
@@ -245,8 +246,7 @@ static void vmx_sync_vmcs_host_state(struct vcpu_vmx *vmx,
src = &prev->host_state;
dest = &vmx->loaded_vmcs->host_state;
- vmx_set_vmcs_host_state(dest, src->cr3, src->fs_sel, src->gs_sel,
- src->fs_base, src->gs_base);
+ vmx_set_host_fs_gs(dest, src->fs_sel, src->gs_sel, src->fs_base, src->gs_base);
dest->ldt_sel = src->ldt_sel;
#ifdef CONFIG_X86_64
dest->ds_sel = src->ds_sel;
@@ -320,7 +320,7 @@ static void free_nested(struct kvm_vcpu *vcpu)
kvm_vcpu_unmap(vcpu, &vmx->nested.pi_desc_map, true);
vmx->nested.pi_desc = NULL;
- kvm_mmu_free_roots(vcpu, &vcpu->arch.guest_mmu, KVM_MMU_ROOTS_ALL);
+ kvm_mmu_free_roots(vcpu->kvm, &vcpu->arch.guest_mmu, KVM_MMU_ROOTS_ALL);
nested_release_evmcs(vcpu);
@@ -1125,15 +1125,15 @@ static int nested_vmx_load_cr3(struct kvm_vcpu *vcpu, unsigned long cr3,
return -EINVAL;
}
- if (!nested_ept)
- kvm_mmu_new_pgd(vcpu, cr3);
-
vcpu->arch.cr3 = cr3;
kvm_register_mark_dirty(vcpu, VCPU_EXREG_CR3);
/* Re-initialize the MMU, e.g. to pick up CR4 MMU role changes. */
kvm_init_mmu(vcpu);
+ if (!nested_ept)
+ kvm_mmu_new_pgd(vcpu, cr3);
+
return 0;
}
@@ -3055,7 +3055,7 @@ static int nested_vmx_check_guest_state(struct kvm_vcpu *vcpu,
static int nested_vmx_check_vmentry_hw(struct kvm_vcpu *vcpu)
{
struct vcpu_vmx *vmx = to_vmx(vcpu);
- unsigned long cr4;
+ unsigned long cr3, cr4;
bool vm_fail;
if (!nested_early_check)
@@ -3078,6 +3078,12 @@ static int nested_vmx_check_vmentry_hw(struct kvm_vcpu *vcpu)
*/
vmcs_writel(GUEST_RFLAGS, 0);
+ cr3 = __get_current_cr3_fast();
+ if (unlikely(cr3 != vmx->loaded_vmcs->host_state.cr3)) {
+ vmcs_writel(HOST_CR3, cr3);
+ vmx->loaded_vmcs->host_state.cr3 = cr3;
+ }
+
cr4 = cr4_read_shadow();
if (unlikely(cr4 != vmx->loaded_vmcs->host_state.cr4)) {
vmcs_writel(HOST_CR4, cr4);
@@ -4796,7 +4802,8 @@ int get_vmx_mem_address(struct kvm_vcpu *vcpu, unsigned long exit_qualification,
return 0;
}
-void nested_vmx_pmu_entry_exit_ctls_update(struct kvm_vcpu *vcpu)
+void nested_vmx_pmu_refresh(struct kvm_vcpu *vcpu,
+ bool vcpu_has_perf_global_ctrl)
{
struct vcpu_vmx *vmx;
@@ -4804,7 +4811,7 @@ void nested_vmx_pmu_entry_exit_ctls_update(struct kvm_vcpu *vcpu)
return;
vmx = to_vmx(vcpu);
- if (kvm_x86_ops.pmu_ops->is_valid_msr(vcpu, MSR_CORE_PERF_GLOBAL_CTRL)) {
+ if (vcpu_has_perf_global_ctrl) {
vmx->nested.msrs.entry_ctls_high |=
VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL;
vmx->nested.msrs.exit_ctls_high |=
@@ -4851,18 +4858,20 @@ static struct vmcs *alloc_shadow_vmcs(struct kvm_vcpu *vcpu)
struct loaded_vmcs *loaded_vmcs = vmx->loaded_vmcs;
/*
- * We should allocate a shadow vmcs for vmcs01 only when L1
- * executes VMXON and free it when L1 executes VMXOFF.
- * As it is invalid to execute VMXON twice, we shouldn't reach
- * here when vmcs01 already have an allocated shadow vmcs.
+ * KVM allocates a shadow VMCS only when L1 executes VMXON and frees it
+ * when L1 executes VMXOFF or the vCPU is forced out of nested
+ * operation. VMXON faults if the CPU is already post-VMXON, so it
+ * should be impossible to already have an allocated shadow VMCS. KVM
+ * doesn't support virtualization of VMCS shadowing, so vmcs01 should
+ * always be the loaded VMCS.
*/
- WARN_ON(loaded_vmcs == &vmx->vmcs01 && loaded_vmcs->shadow_vmcs);
+ if (WARN_ON(loaded_vmcs != &vmx->vmcs01 || loaded_vmcs->shadow_vmcs))
+ return loaded_vmcs->shadow_vmcs;
+
+ loaded_vmcs->shadow_vmcs = alloc_vmcs(true);
+ if (loaded_vmcs->shadow_vmcs)
+ vmcs_clear(loaded_vmcs->shadow_vmcs);
- if (!loaded_vmcs->shadow_vmcs) {
- loaded_vmcs->shadow_vmcs = alloc_vmcs(true);
- if (loaded_vmcs->shadow_vmcs)
- vmcs_clear(loaded_vmcs->shadow_vmcs);
- }
return loaded_vmcs->shadow_vmcs;
}
@@ -5003,7 +5012,7 @@ static inline void nested_release_vmcs12(struct kvm_vcpu *vcpu)
vmx->nested.current_vmptr >> PAGE_SHIFT,
vmx->nested.cached_vmcs12, 0, VMCS12_SIZE);
- kvm_mmu_free_roots(vcpu, &vcpu->arch.guest_mmu, KVM_MMU_ROOTS_ALL);
+ kvm_mmu_free_roots(vcpu->kvm, &vcpu->arch.guest_mmu, KVM_MMU_ROOTS_ALL);
vmx->nested.current_vmptr = INVALID_GPA;
}
@@ -5099,27 +5108,49 @@ static int handle_vmread(struct kvm_vcpu *vcpu)
if (!nested_vmx_check_permission(vcpu))
return 1;
- /*
- * In VMX non-root operation, when the VMCS-link pointer is INVALID_GPA,
- * any VMREAD sets the ALU flags for VMfailInvalid.
- */
- if (vmx->nested.current_vmptr == INVALID_GPA ||
- (is_guest_mode(vcpu) &&
- get_vmcs12(vcpu)->vmcs_link_pointer == INVALID_GPA))
- return nested_vmx_failInvalid(vcpu);
-
/* Decode instruction info and find the field to read */
field = kvm_register_read(vcpu, (((instr_info) >> 28) & 0xf));
- offset = vmcs_field_to_offset(field);
- if (offset < 0)
- return nested_vmx_fail(vcpu, VMXERR_UNSUPPORTED_VMCS_COMPONENT);
+ if (!evmptr_is_valid(vmx->nested.hv_evmcs_vmptr)) {
+ /*
+ * In VMX non-root operation, when the VMCS-link pointer is INVALID_GPA,
+ * any VMREAD sets the ALU flags for VMfailInvalid.
+ */
+ if (vmx->nested.current_vmptr == INVALID_GPA ||
+ (is_guest_mode(vcpu) &&
+ get_vmcs12(vcpu)->vmcs_link_pointer == INVALID_GPA))
+ return nested_vmx_failInvalid(vcpu);
- if (!is_guest_mode(vcpu) && is_vmcs12_ext_field(field))
- copy_vmcs02_to_vmcs12_rare(vcpu, vmcs12);
+ offset = get_vmcs12_field_offset(field);
+ if (offset < 0)
+ return nested_vmx_fail(vcpu, VMXERR_UNSUPPORTED_VMCS_COMPONENT);
- /* Read the field, zero-extended to a u64 value */
- value = vmcs12_read_any(vmcs12, field, offset);
+ if (!is_guest_mode(vcpu) && is_vmcs12_ext_field(field))
+ copy_vmcs02_to_vmcs12_rare(vcpu, vmcs12);
+
+ /* Read the field, zero-extended to a u64 value */
+ value = vmcs12_read_any(vmcs12, field, offset);
+ } else {
+ /*
+ * Hyper-V TLFS (as of 6.0b) explicitly states, that while an
+ * enlightened VMCS is active VMREAD/VMWRITE instructions are
+ * unsupported. Unfortunately, certain versions of Windows 11
+ * don't comply with this requirement which is not enforced in
+ * genuine Hyper-V. Allow VMREAD from an enlightened VMCS as a
+ * workaround, as misbehaving guests will panic on VM-Fail.
+ * Note, enlightened VMCS is incompatible with shadow VMCS so
+ * all VMREADs from L2 should go to L1.
+ */
+ if (WARN_ON_ONCE(is_guest_mode(vcpu)))
+ return nested_vmx_failInvalid(vcpu);
+
+ offset = evmcs_field_offset(field, NULL);
+ if (offset < 0)
+ return nested_vmx_fail(vcpu, VMXERR_UNSUPPORTED_VMCS_COMPONENT);
+
+ /* Read the field, zero-extended to a u64 value */
+ value = evmcs_read_any(vmx->nested.hv_evmcs, field, offset);
+ }
/*
* Now copy part of this value to register or memory, as requested.
@@ -5214,7 +5245,7 @@ static int handle_vmwrite(struct kvm_vcpu *vcpu)
field = kvm_register_read(vcpu, (((instr_info) >> 28) & 0xf));
- offset = vmcs_field_to_offset(field);
+ offset = get_vmcs12_field_offset(field);
if (offset < 0)
return nested_vmx_fail(vcpu, VMXERR_UNSUPPORTED_VMCS_COMPONENT);
@@ -5440,7 +5471,7 @@ static int handle_invept(struct kvm_vcpu *vcpu)
VMXERR_INVALID_OPERAND_TO_INVEPT_INVVPID);
roots_to_free = 0;
- if (nested_ept_root_matches(mmu->root_hpa, mmu->root_pgd,
+ if (nested_ept_root_matches(mmu->root.hpa, mmu->root.pgd,
operand.eptp))
roots_to_free |= KVM_MMU_ROOT_CURRENT;
@@ -5460,7 +5491,7 @@ static int handle_invept(struct kvm_vcpu *vcpu)
}
if (roots_to_free)
- kvm_mmu_free_roots(vcpu, mmu, roots_to_free);
+ kvm_mmu_free_roots(vcpu->kvm, mmu, roots_to_free);
return nested_vmx_succeed(vcpu);
}
@@ -5549,7 +5580,7 @@ static int handle_invvpid(struct kvm_vcpu *vcpu)
* TODO: sync only the affected SPTEs for INVDIVIDUAL_ADDR.
*/
if (!enable_ept)
- kvm_mmu_free_guest_mode_roots(vcpu, &vcpu->arch.root_mmu);
+ kvm_mmu_free_guest_mode_roots(vcpu->kvm, &vcpu->arch.root_mmu);
return nested_vmx_succeed(vcpu);
}
@@ -6462,7 +6493,7 @@ static u64 nested_vmx_calc_vmcs_enum_msr(void)
max_idx = 0;
for (i = 0; i < nr_vmcs12_fields; i++) {
/* The vmcs12 table is very, very sparsely populated. */
- if (!vmcs_field_to_offset_table[i])
+ if (!vmcs12_field_offsets[i])
continue;
idx = vmcs_field_index(VMCS12_IDX_TO_ENC(i));
@@ -6771,6 +6802,7 @@ __init int nested_vmx_hardware_setup(int (*exit_handlers[])(struct kvm_vcpu *))
}
struct kvm_x86_nested_ops vmx_nested_ops = {
+ .leave_nested = vmx_leave_nested,
.check_events = vmx_check_nested_events,
.hv_timer_pending = nested_vmx_preemption_timer_pending,
.triple_fault = nested_vmx_triple_fault,
diff --git a/arch/x86/kvm/vmx/nested.h b/arch/x86/kvm/vmx/nested.h
index b69a80f43b37..c92cea0b8ccc 100644
--- a/arch/x86/kvm/vmx/nested.h
+++ b/arch/x86/kvm/vmx/nested.h
@@ -32,7 +32,8 @@ int vmx_set_vmx_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 data);
int vmx_get_vmx_msr(struct nested_vmx_msrs *msrs, u32 msr_index, u64 *pdata);
int get_vmx_mem_address(struct kvm_vcpu *vcpu, unsigned long exit_qualification,
u32 vmx_instruction_info, bool wr, int len, gva_t *ret);
-void nested_vmx_pmu_entry_exit_ctls_update(struct kvm_vcpu *vcpu);
+void nested_vmx_pmu_refresh(struct kvm_vcpu *vcpu,
+ bool vcpu_has_perf_global_ctrl);
void nested_mark_vmcs12_pages_dirty(struct kvm_vcpu *vcpu);
bool nested_vmx_check_io_bitmaps(struct kvm_vcpu *vcpu, unsigned int port,
int size);
diff --git a/arch/x86/kvm/vmx/pmu_intel.c b/arch/x86/kvm/vmx/pmu_intel.c
index 466d18fc0c5d..0684e519181b 100644
--- a/arch/x86/kvm/vmx/pmu_intel.c
+++ b/arch/x86/kvm/vmx/pmu_intel.c
@@ -487,7 +487,7 @@ static void intel_pmu_refresh(struct kvm_vcpu *vcpu)
pmu->reserved_bits = 0xffffffff00200000ull;
entry = kvm_find_cpuid_entry(vcpu, 0xa, 0);
- if (!entry || !enable_pmu)
+ if (!entry || !vcpu->kvm->arch.enable_pmu)
return;
eax.full = entry->eax;
edx.full = entry->edx;
@@ -541,7 +541,8 @@ static void intel_pmu_refresh(struct kvm_vcpu *vcpu)
bitmap_set(pmu->all_valid_pmc_idx,
INTEL_PMC_MAX_GENERIC, pmu->nr_arch_fixed_counters);
- nested_vmx_pmu_entry_exit_ctls_update(vcpu);
+ nested_vmx_pmu_refresh(vcpu,
+ intel_is_valid_msr(vcpu, MSR_CORE_PERF_GLOBAL_CTRL));
if (intel_pmu_lbr_is_compatible(vcpu))
x86_perf_get_lbr(&lbr_desc->records);
@@ -565,7 +566,7 @@ static void intel_pmu_init(struct kvm_vcpu *vcpu)
pmu->gp_counters[i].current_config = 0;
}
- for (i = 0; i < INTEL_PMC_MAX_FIXED; i++) {
+ 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;
@@ -591,7 +592,7 @@ static void intel_pmu_reset(struct kvm_vcpu *vcpu)
pmc->counter = pmc->eventsel = 0;
}
- for (i = 0; i < INTEL_PMC_MAX_FIXED; i++) {
+ for (i = 0; i < KVM_PMC_MAX_FIXED; i++) {
pmc = &pmu->fixed_counters[i];
pmc_stop_counter(pmc);
diff --git a/arch/x86/kvm/vmx/posted_intr.c b/arch/x86/kvm/vmx/posted_intr.c
index aa1fe9085d77..3834bb30ce54 100644
--- a/arch/x86/kvm/vmx/posted_intr.c
+++ b/arch/x86/kvm/vmx/posted_intr.c
@@ -244,7 +244,7 @@ void vmx_pi_start_assignment(struct kvm *kvm)
}
/*
- * pi_update_irte - set IRTE for Posted-Interrupts
+ * vmx_pi_update_irte - set IRTE for Posted-Interrupts
*
* @kvm: kvm
* @host_irq: host irq of the interrupt
@@ -252,8 +252,8 @@ void vmx_pi_start_assignment(struct kvm *kvm)
* @set: set or unset PI
* returns 0 on success, < 0 on failure
*/
-int pi_update_irte(struct kvm *kvm, unsigned int host_irq, uint32_t guest_irq,
- bool set)
+int vmx_pi_update_irte(struct kvm *kvm, unsigned int host_irq,
+ uint32_t guest_irq, bool set)
{
struct kvm_kernel_irq_routing_entry *e;
struct kvm_irq_routing_table *irq_rt;
diff --git a/arch/x86/kvm/vmx/posted_intr.h b/arch/x86/kvm/vmx/posted_intr.h
index eb14e76b84ef..9a45d5c9f116 100644
--- a/arch/x86/kvm/vmx/posted_intr.h
+++ b/arch/x86/kvm/vmx/posted_intr.h
@@ -97,8 +97,8 @@ void vmx_vcpu_pi_put(struct kvm_vcpu *vcpu);
void pi_wakeup_handler(void);
void __init pi_init_cpu(int cpu);
bool pi_has_pending_interrupt(struct kvm_vcpu *vcpu);
-int pi_update_irte(struct kvm *kvm, unsigned int host_irq, uint32_t guest_irq,
- bool set);
+int vmx_pi_update_irte(struct kvm *kvm, unsigned int host_irq,
+ uint32_t guest_irq, bool set);
void vmx_pi_start_assignment(struct kvm *kvm);
#endif /* __KVM_X86_VMX_POSTED_INTR_H */
diff --git a/arch/x86/kvm/vmx/vmcs12.c b/arch/x86/kvm/vmx/vmcs12.c
index cab6ba7a5005..2251b60920f8 100644
--- a/arch/x86/kvm/vmx/vmcs12.c
+++ b/arch/x86/kvm/vmx/vmcs12.c
@@ -8,7 +8,7 @@
FIELD(number, name), \
[ROL16(number##_HIGH, 6)] = VMCS12_OFFSET(name) + sizeof(u32)
-const unsigned short vmcs_field_to_offset_table[] = {
+const unsigned short vmcs12_field_offsets[] = {
FIELD(VIRTUAL_PROCESSOR_ID, virtual_processor_id),
FIELD(POSTED_INTR_NV, posted_intr_nv),
FIELD(GUEST_ES_SELECTOR, guest_es_selector),
@@ -151,4 +151,4 @@ const unsigned short vmcs_field_to_offset_table[] = {
FIELD(HOST_RSP, host_rsp),
FIELD(HOST_RIP, host_rip),
};
-const unsigned int nr_vmcs12_fields = ARRAY_SIZE(vmcs_field_to_offset_table);
+const unsigned int nr_vmcs12_fields = ARRAY_SIZE(vmcs12_field_offsets);
diff --git a/arch/x86/kvm/vmx/vmcs12.h b/arch/x86/kvm/vmx/vmcs12.h
index 2a45f026ee11..746129ddd5ae 100644
--- a/arch/x86/kvm/vmx/vmcs12.h
+++ b/arch/x86/kvm/vmx/vmcs12.h
@@ -361,10 +361,10 @@ static inline void vmx_check_vmcs12_offsets(void)
CHECK_OFFSET(guest_pml_index, 996);
}
-extern const unsigned short vmcs_field_to_offset_table[];
+extern const unsigned short vmcs12_field_offsets[];
extern const unsigned int nr_vmcs12_fields;
-static inline short vmcs_field_to_offset(unsigned long field)
+static inline short get_vmcs12_field_offset(unsigned long field)
{
unsigned short offset;
unsigned int index;
@@ -377,7 +377,7 @@ static inline short vmcs_field_to_offset(unsigned long field)
return -ENOENT;
index = array_index_nospec(index, nr_vmcs12_fields);
- offset = vmcs_field_to_offset_table[index];
+ offset = vmcs12_field_offsets[index];
if (offset == 0)
return -ENOENT;
return offset;
diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c
index 4ac676066d60..e8963f5af618 100644
--- a/arch/x86/kvm/vmx/vmx.c
+++ b/arch/x86/kvm/vmx/vmx.c
@@ -541,11 +541,6 @@ static inline bool cpu_need_virtualize_apic_accesses(struct kvm_vcpu *vcpu)
return flexpriority_enabled && lapic_in_kernel(vcpu);
}
-static inline bool report_flexpriority(void)
-{
- return flexpriority_enabled;
-}
-
static int possible_passthrough_msr_slot(u32 msr)
{
u32 i;
@@ -645,10 +640,10 @@ static void __loaded_vmcs_clear(void *arg)
/*
* Ensure all writes to loaded_vmcs, including deleting it from its
- * current percpu list, complete before setting loaded_vmcs->vcpu to
- * -1, otherwise a different cpu can see vcpu == -1 first and add
- * loaded_vmcs to its percpu list before it's deleted from this cpu's
- * list. Pairs with the smp_rmb() in vmx_vcpu_load_vmcs().
+ * current percpu list, complete before setting loaded_vmcs->cpu to
+ * -1, otherwise a different cpu can see loaded_vmcs->cpu == -1 first
+ * and add loaded_vmcs to its percpu list before it's deleted from this
+ * cpu's list. Pairs with the smp_rmb() in vmx_vcpu_load_vmcs().
*/
smp_wmb();
@@ -1080,14 +1075,9 @@ static void pt_guest_exit(struct vcpu_vmx *vmx)
wrmsrl(MSR_IA32_RTIT_CTL, vmx->pt_desc.host.ctl);
}
-void vmx_set_vmcs_host_state(struct vmcs_host_state *host, unsigned long cr3,
- u16 fs_sel, u16 gs_sel,
- unsigned long fs_base, unsigned long gs_base)
+void vmx_set_host_fs_gs(struct vmcs_host_state *host, u16 fs_sel, u16 gs_sel,
+ unsigned long fs_base, unsigned long gs_base)
{
- if (unlikely(cr3 != host->cr3)) {
- vmcs_writel(HOST_CR3, cr3);
- host->cr3 = cr3;
- }
if (unlikely(fs_sel != host->fs_sel)) {
if (!(fs_sel & 7))
vmcs_write16(HOST_FS_SELECTOR, fs_sel);
@@ -1182,9 +1172,7 @@ void vmx_prepare_switch_to_guest(struct kvm_vcpu *vcpu)
gs_base = segment_base(gs_sel);
#endif
- vmx_set_vmcs_host_state(host_state, __get_current_cr3_fast(),
- fs_sel, gs_sel, fs_base, gs_base);
-
+ vmx_set_host_fs_gs(host_state, fs_sel, gs_sel, fs_base, gs_base);
vmx->guest_state_loaded = true;
}
@@ -1487,11 +1475,12 @@ static int vmx_rtit_ctl_check(struct kvm_vcpu *vcpu, u64 data)
return 0;
}
-static bool vmx_can_emulate_instruction(struct kvm_vcpu *vcpu, void *insn, int insn_len)
+static bool vmx_can_emulate_instruction(struct kvm_vcpu *vcpu, int emul_type,
+ void *insn, int insn_len)
{
/*
* Emulation of instructions in SGX enclaves is impossible as RIP does
- * not point tthe failing instruction, and even if it did, the code
+ * not point at the failing instruction, and even if it did, the code
* stream is inaccessible. Inject #UD instead of exiting to userspace
* so that guest userspace can't DoS the guest simply by triggering
* emulation (enclaves are CPL3 only).
@@ -2340,7 +2329,7 @@ fault:
return -EFAULT;
}
-static int hardware_enable(void)
+static int vmx_hardware_enable(void)
{
int cpu = raw_smp_processor_id();
u64 phys_addr = __pa(per_cpu(vmxarea, cpu));
@@ -2381,7 +2370,7 @@ static void vmclear_local_loaded_vmcss(void)
__loaded_vmcs_clear(v);
}
-static void hardware_disable(void)
+static void vmx_hardware_disable(void)
{
vmclear_local_loaded_vmcss();
@@ -2603,7 +2592,6 @@ static __init int setup_vmcs_config(struct vmcs_config *vmcs_conf,
return -EIO;
vmcs_conf->size = vmx_msr_high & 0x1fff;
- vmcs_conf->order = get_order(vmcs_conf->size);
vmcs_conf->basic_cap = vmx_msr_high & ~0x1fff;
vmcs_conf->revision_id = vmx_msr_low;
@@ -2628,7 +2616,7 @@ struct vmcs *alloc_vmcs_cpu(bool shadow, int cpu, gfp_t flags)
struct page *pages;
struct vmcs *vmcs;
- pages = __alloc_pages_node(node, flags, vmcs_config.order);
+ pages = __alloc_pages_node(node, flags, 0);
if (!pages)
return NULL;
vmcs = page_address(pages);
@@ -2647,7 +2635,7 @@ struct vmcs *alloc_vmcs_cpu(bool shadow, int cpu, gfp_t flags)
void free_vmcs(struct vmcs *vmcs)
{
- free_pages((unsigned long)vmcs, vmcs_config.order);
+ free_page((unsigned long)vmcs);
}
/*
@@ -2957,7 +2945,7 @@ static inline int vmx_get_current_vpid(struct kvm_vcpu *vcpu)
static void vmx_flush_tlb_current(struct kvm_vcpu *vcpu)
{
struct kvm_mmu *mmu = vcpu->arch.mmu;
- u64 root_hpa = mmu->root_hpa;
+ u64 root_hpa = mmu->root.hpa;
/* No flush required if the current context is invalid. */
if (!VALID_PAGE(root_hpa))
@@ -3937,31 +3925,33 @@ static inline void kvm_vcpu_trigger_posted_interrupt(struct kvm_vcpu *vcpu,
#ifdef CONFIG_SMP
if (vcpu->mode == IN_GUEST_MODE) {
/*
- * The vector of interrupt to be delivered to vcpu had
- * been set in PIR before this function.
+ * The vector of the virtual has already been set in the PIR.
+ * Send a notification event to deliver the virtual interrupt
+ * unless the vCPU is the currently running vCPU, i.e. the
+ * event is being sent from a fastpath VM-Exit handler, in
+ * which case the PIR will be synced to the vIRR before
+ * re-entering the guest.
*
- * Following cases will be reached in this block, and
- * we always send a notification event in all cases as
- * explained below.
+ * When the target is not the running vCPU, the following
+ * possibilities emerge:
*
- * Case 1: vcpu keeps in non-root mode. Sending a
- * notification event posts the interrupt to vcpu.
+ * Case 1: vCPU stays in non-root mode. Sending a notification
+ * event posts the interrupt to the vCPU.
*
- * Case 2: vcpu exits to root mode and is still
- * runnable. PIR will be synced to vIRR before the
- * next vcpu entry. Sending a notification event in
- * this case has no effect, as vcpu is not in root
- * mode.
+ * Case 2: vCPU exits to root mode and is still runnable. The
+ * PIR will be synced to the vIRR before re-entering the guest.
+ * Sending a notification event is ok as the host IRQ handler
+ * will ignore the spurious event.
*
- * Case 3: vcpu exits to root mode and is blocked.
- * vcpu_block() has already synced PIR to vIRR and
- * never blocks vcpu if vIRR is not cleared. Therefore,
- * a blocked vcpu here does not wait for any requested
- * interrupts in PIR, and sending a notification event
- * which has no effect is safe here.
+ * Case 3: vCPU exits to root mode and is blocked. vcpu_block()
+ * has already synced PIR to vIRR and never blocks the vCPU if
+ * the vIRR is not empty. Therefore, a blocked vCPU here does
+ * not wait for any requested interrupts in PIR, and sending a
+ * notification event also results in a benign, spurious event.
*/
- apic->send_IPI_mask(get_cpu_mask(vcpu->cpu), pi_vec);
+ if (vcpu != kvm_get_running_vcpu())
+ apic->send_IPI_mask(get_cpu_mask(vcpu->cpu), pi_vec);
return;
}
#endif
@@ -4041,6 +4031,21 @@ static int vmx_deliver_posted_interrupt(struct kvm_vcpu *vcpu, int vector)
return 0;
}
+static void vmx_deliver_interrupt(struct kvm_lapic *apic, int delivery_mode,
+ int trig_mode, int vector)
+{
+ struct kvm_vcpu *vcpu = apic->vcpu;
+
+ if (vmx_deliver_posted_interrupt(vcpu, vector)) {
+ kvm_lapic_set_irr(vector, apic);
+ kvm_make_request(KVM_REQ_EVENT, vcpu);
+ kvm_vcpu_kick(vcpu);
+ } else {
+ trace_kvm_apicv_accept_irq(vcpu->vcpu_id, delivery_mode,
+ trig_mode, vector);
+ }
+}
+
/*
* Set up the vmcs's constant host-state fields, i.e., host-state fields that
* will not change in the lifetime of the guest.
@@ -4094,10 +4099,14 @@ void vmx_set_constant_host_state(struct vcpu_vmx *vmx)
vmcs_write32(HOST_IA32_SYSENTER_CS, low32);
/*
- * If 32-bit syscall is enabled, vmx_vcpu_load_vcms rewrites
- * HOST_IA32_SYSENTER_ESP.
+ * SYSENTER is used for 32-bit system calls on either 32-bit or
+ * 64-bit kernels. It is always zero If neither is allowed, otherwise
+ * vmx_vcpu_load_vmcs loads it with the per-CPU entry stack (and may
+ * have already done so!).
*/
- vmcs_writel(HOST_IA32_SYSENTER_ESP, 0);
+ if (!IS_ENABLED(CONFIG_IA32_EMULATION) && !IS_ENABLED(CONFIG_X86_32))
+ vmcs_writel(HOST_IA32_SYSENTER_ESP, 0);
+
rdmsrl(MSR_IA32_SYSENTER_EIP, tmpl);
vmcs_writel(HOST_IA32_SYSENTER_EIP, tmpl); /* 22.2.3 */
@@ -4901,8 +4910,33 @@ static int handle_exception_nmi(struct kvm_vcpu *vcpu)
dr6 = vmx_get_exit_qual(vcpu);
if (!(vcpu->guest_debug &
(KVM_GUESTDBG_SINGLESTEP | KVM_GUESTDBG_USE_HW_BP))) {
+ /*
+ * If the #DB was due to ICEBP, a.k.a. INT1, skip the
+ * instruction. ICEBP generates a trap-like #DB, but
+ * despite its interception control being tied to #DB,
+ * is an instruction intercept, i.e. the VM-Exit occurs
+ * on the ICEBP itself. Note, skipping ICEBP also
+ * clears STI and MOVSS blocking.
+ *
+ * For all other #DBs, set vmcs.PENDING_DBG_EXCEPTIONS.BS
+ * if single-step is enabled in RFLAGS and STI or MOVSS
+ * blocking is active, as the CPU doesn't set the bit
+ * on VM-Exit due to #DB interception. VM-Entry has a
+ * consistency check that a single-step #DB is pending
+ * in this scenario as the previous instruction cannot
+ * have toggled RFLAGS.TF 0=>1 (because STI and POP/MOV
+ * don't modify RFLAGS), therefore the one instruction
+ * delay when activating single-step breakpoints must
+ * have already expired. Note, the CPU sets/clears BS
+ * as appropriate for all other VM-Exits types.
+ */
if (is_icebp(intr_info))
WARN_ON(!skip_emulated_instruction(vcpu));
+ else if ((vmx_get_rflags(vcpu) & X86_EFLAGS_TF) &&
+ (vmcs_read32(GUEST_INTERRUPTIBILITY_INFO) &
+ (GUEST_INTR_STATE_STI | GUEST_INTR_STATE_MOV_SS)))
+ vmcs_writel(GUEST_PENDING_DBG_EXCEPTIONS,
+ vmcs_readl(GUEST_PENDING_DBG_EXCEPTIONS) | DR6_BS);
kvm_queue_exception_p(vcpu, DB_VECTOR, dr6);
return 1;
@@ -5140,7 +5174,7 @@ static int handle_dr(struct kvm_vcpu *vcpu)
if (!kvm_require_dr(vcpu, dr))
return 1;
- if (kvm_x86_ops.get_cpl(vcpu) > 0)
+ if (vmx_get_cpl(vcpu) > 0)
goto out;
dr7 = vmcs_readl(GUEST_DR7);
@@ -5273,9 +5307,16 @@ static int handle_apic_eoi_induced(struct kvm_vcpu *vcpu)
static int handle_apic_write(struct kvm_vcpu *vcpu)
{
unsigned long exit_qualification = vmx_get_exit_qual(vcpu);
- u32 offset = exit_qualification & 0xfff;
- /* APIC-write VM exit is trap-like and thus no need to adjust IP */
+ /*
+ * APIC-write VM-Exit is trap-like, KVM doesn't need to advance RIP and
+ * hardware has done any necessary aliasing, offset adjustments, etc...
+ * for the access. I.e. the correct value has already been written to
+ * the vAPIC page for the correct 16-byte chunk. KVM needs only to
+ * retrieve the register value and emulate the access.
+ */
+ u32 offset = exit_qualification & 0xff0;
+
kvm_apic_write_nodecode(vcpu, offset);
return 1;
}
@@ -5397,7 +5438,7 @@ static int handle_ept_misconfig(struct kvm_vcpu *vcpu)
{
gpa_t gpa;
- if (!vmx_can_emulate_instruction(vcpu, NULL, 0))
+ if (!vmx_can_emulate_instruction(vcpu, EMULTYPE_PF, NULL, 0))
return 1;
/*
@@ -6725,7 +6766,7 @@ static fastpath_t vmx_exit_handlers_fastpath(struct kvm_vcpu *vcpu)
static noinstr void vmx_vcpu_enter_exit(struct kvm_vcpu *vcpu,
struct vcpu_vmx *vmx)
{
- kvm_guest_enter_irqoff();
+ guest_state_enter_irqoff();
/* L1D Flush includes CPU buffer clear to mitigate MDS */
if (static_branch_unlikely(&vmx_l1d_should_flush))
@@ -6741,13 +6782,13 @@ static noinstr void vmx_vcpu_enter_exit(struct kvm_vcpu *vcpu,
vcpu->arch.cr2 = native_read_cr2();
- kvm_guest_exit_irqoff();
+ guest_state_exit_irqoff();
}
static fastpath_t vmx_vcpu_run(struct kvm_vcpu *vcpu)
{
struct vcpu_vmx *vmx = to_vmx(vcpu);
- unsigned long cr4;
+ unsigned long cr3, cr4;
/* Record the guest's net vcpu time for enforced NMI injections. */
if (unlikely(!enable_vnmi &&
@@ -6790,6 +6831,19 @@ static fastpath_t vmx_vcpu_run(struct kvm_vcpu *vcpu)
vmcs_writel(GUEST_RIP, vcpu->arch.regs[VCPU_REGS_RIP]);
vcpu->arch.regs_dirty = 0;
+ /*
+ * Refresh vmcs.HOST_CR3 if necessary. This must be done immediately
+ * prior to VM-Enter, as the kernel may load a new ASID (PCID) any time
+ * it switches back to the current->mm, which can occur in KVM context
+ * when switching to a temporary mm to patch kernel code, e.g. if KVM
+ * toggles a static key while handling a VM-Exit.
+ */
+ cr3 = __get_current_cr3_fast();
+ if (unlikely(cr3 != vmx->loaded_vmcs->host_state.cr3)) {
+ vmcs_writel(HOST_CR3, cr3);
+ vmx->loaded_vmcs->host_state.cr3 = cr3;
+ }
+
cr4 = cr4_read_shadow();
if (unlikely(cr4 != vmx->loaded_vmcs->host_state.cr4)) {
vmcs_writel(HOST_CR4, cr4);
@@ -6925,7 +6979,7 @@ static fastpath_t vmx_vcpu_run(struct kvm_vcpu *vcpu)
return vmx_exit_handlers_fastpath(vcpu);
}
-static void vmx_free_vcpu(struct kvm_vcpu *vcpu)
+static void vmx_vcpu_free(struct kvm_vcpu *vcpu)
{
struct vcpu_vmx *vmx = to_vmx(vcpu);
@@ -6936,7 +6990,7 @@ static void vmx_free_vcpu(struct kvm_vcpu *vcpu)
free_loaded_vmcs(vmx->loaded_vmcs);
}
-static int vmx_create_vcpu(struct kvm_vcpu *vcpu)
+static int vmx_vcpu_create(struct kvm_vcpu *vcpu)
{
struct vmx_uret_msr *tsx_ctrl;
struct vcpu_vmx *vmx;
@@ -7298,11 +7352,11 @@ static void vmx_vcpu_after_set_cpuid(struct kvm_vcpu *vcpu)
vmx_secondary_exec_control(vmx));
if (nested_vmx_allowed(vcpu))
- to_vmx(vcpu)->msr_ia32_feature_control_valid_bits |=
+ vmx->msr_ia32_feature_control_valid_bits |=
FEAT_CTL_VMX_ENABLED_INSIDE_SMX |
FEAT_CTL_VMX_ENABLED_OUTSIDE_SMX;
else
- to_vmx(vcpu)->msr_ia32_feature_control_valid_bits &=
+ vmx->msr_ia32_feature_control_valid_bits &=
~(FEAT_CTL_VMX_ENABLED_INSIDE_SMX |
FEAT_CTL_VMX_ENABLED_OUTSIDE_SMX);
@@ -7615,6 +7669,7 @@ static int vmx_leave_smm(struct kvm_vcpu *vcpu, const char *smstate)
if (ret)
return ret;
+ vmx->nested.nested_run_pending = 1;
vmx->nested.smm.guest_mode = false;
}
return 0;
@@ -7640,7 +7695,7 @@ static void vmx_migrate_timers(struct kvm_vcpu *vcpu)
}
}
-static void hardware_unsetup(void)
+static void vmx_hardware_unsetup(void)
{
kvm_set_posted_intr_wakeup_handler(NULL);
@@ -7663,21 +7718,20 @@ static bool vmx_check_apicv_inhibit_reasons(ulong bit)
static struct kvm_x86_ops vmx_x86_ops __initdata = {
.name = "kvm_intel",
- .hardware_unsetup = hardware_unsetup,
+ .hardware_unsetup = vmx_hardware_unsetup,
- .hardware_enable = hardware_enable,
- .hardware_disable = hardware_disable,
- .cpu_has_accelerated_tpr = report_flexpriority,
+ .hardware_enable = vmx_hardware_enable,
+ .hardware_disable = vmx_hardware_disable,
.has_emulated_msr = vmx_has_emulated_msr,
.vm_size = sizeof(struct kvm_vmx),
.vm_init = vmx_vm_init,
- .vcpu_create = vmx_create_vcpu,
- .vcpu_free = vmx_free_vcpu,
+ .vcpu_create = vmx_vcpu_create,
+ .vcpu_free = vmx_vcpu_free,
.vcpu_reset = vmx_vcpu_reset,
- .prepare_guest_switch = vmx_prepare_switch_to_guest,
+ .prepare_switch_to_guest = vmx_prepare_switch_to_guest,
.vcpu_load = vmx_vcpu_load,
.vcpu_put = vmx_vcpu_put,
@@ -7705,21 +7759,21 @@ static struct kvm_x86_ops vmx_x86_ops __initdata = {
.set_rflags = vmx_set_rflags,
.get_if_flag = vmx_get_if_flag,
- .tlb_flush_all = vmx_flush_tlb_all,
- .tlb_flush_current = vmx_flush_tlb_current,
- .tlb_flush_gva = vmx_flush_tlb_gva,
- .tlb_flush_guest = vmx_flush_tlb_guest,
+ .flush_tlb_all = vmx_flush_tlb_all,
+ .flush_tlb_current = vmx_flush_tlb_current,
+ .flush_tlb_gva = vmx_flush_tlb_gva,
+ .flush_tlb_guest = vmx_flush_tlb_guest,
.vcpu_pre_run = vmx_vcpu_pre_run,
- .run = vmx_vcpu_run,
+ .vcpu_run = vmx_vcpu_run,
.handle_exit = vmx_handle_exit,
.skip_emulated_instruction = vmx_skip_emulated_instruction,
.update_emulated_instruction = vmx_update_emulated_instruction,
.set_interrupt_shadow = vmx_set_interrupt_shadow,
.get_interrupt_shadow = vmx_get_interrupt_shadow,
.patch_hypercall = vmx_patch_hypercall,
- .set_irq = vmx_inject_irq,
- .set_nmi = vmx_inject_nmi,
+ .inject_irq = vmx_inject_irq,
+ .inject_nmi = vmx_inject_nmi,
.queue_exception = vmx_queue_exception,
.cancel_injection = vmx_cancel_injection,
.interrupt_allowed = vmx_interrupt_allowed,
@@ -7739,7 +7793,7 @@ static struct kvm_x86_ops vmx_x86_ops __initdata = {
.hwapic_isr_update = vmx_hwapic_isr_update,
.guest_apic_has_interrupt = vmx_guest_apic_has_interrupt,
.sync_pir_to_irr = vmx_sync_pir_to_irr,
- .deliver_posted_interrupt = vmx_deliver_posted_interrupt,
+ .deliver_interrupt = vmx_deliver_interrupt,
.dy_apicv_has_pending_interrupt = pi_has_pending_interrupt,
.set_tss_addr = vmx_set_tss_addr,
@@ -7772,8 +7826,8 @@ static struct kvm_x86_ops vmx_x86_ops __initdata = {
.pmu_ops = &intel_pmu_ops,
.nested_ops = &vmx_nested_ops,
- .update_pi_irte = pi_update_irte,
- .start_assignment = vmx_pi_start_assignment,
+ .pi_update_irte = vmx_pi_update_irte,
+ .pi_start_assignment = vmx_pi_start_assignment,
#ifdef CONFIG_X86_64
.set_hv_timer = vmx_set_hv_timer,
@@ -8008,7 +8062,7 @@ static __init int hardware_setup(void)
vmx_set_cpu_caps();
r = alloc_kvm_area();
- if (r)
+ if (r && nested)
nested_vmx_hardware_unsetup();
kvm_set_posted_intr_wakeup_handler(pi_wakeup_handler);
@@ -8088,7 +8142,6 @@ static int __init vmx_init(void)
ms_hyperv.hints & HV_X64_ENLIGHTENED_VMCS_RECOMMENDED &&
(ms_hyperv.nested_features & HV_X64_ENLIGHTENED_VMCS_VERSION) >=
KVM_EVMCS_VERSION) {
- int cpu;
/* Check that we have assist pages on all online CPUs */
for_each_online_cpu(cpu) {
diff --git a/arch/x86/kvm/vmx/vmx.h b/arch/x86/kvm/vmx/vmx.h
index 7f2c82e7f38f..9c6bfcd84008 100644
--- a/arch/x86/kvm/vmx/vmx.h
+++ b/arch/x86/kvm/vmx/vmx.h
@@ -374,9 +374,8 @@ int allocate_vpid(void);
void free_vpid(int vpid);
void vmx_set_constant_host_state(struct vcpu_vmx *vmx);
void vmx_prepare_switch_to_guest(struct kvm_vcpu *vcpu);
-void vmx_set_vmcs_host_state(struct vmcs_host_state *host, unsigned long cr3,
- u16 fs_sel, u16 gs_sel,
- unsigned long fs_base, unsigned long gs_base);
+void vmx_set_host_fs_gs(struct vmcs_host_state *host, u16 fs_sel, u16 gs_sel,
+ unsigned long fs_base, unsigned long gs_base);
int vmx_get_cpl(struct kvm_vcpu *vcpu);
bool vmx_emulation_required(struct kvm_vcpu *vcpu);
unsigned long vmx_get_rflags(struct kvm_vcpu *vcpu);
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 9e43d756312f..02cf0a7e1d14 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -90,6 +90,8 @@
u64 __read_mostly kvm_mce_cap_supported = MCG_CTL_P | MCG_SER_P;
EXPORT_SYMBOL_GPL(kvm_mce_cap_supported);
+#define ERR_PTR_USR(e) ((void __user *)ERR_PTR(e))
+
#define emul_to_vcpu(ctxt) \
((struct kvm_vcpu *)(ctxt)->vcpu)
@@ -108,6 +110,8 @@ static u64 __read_mostly cr4_reserved_bits = CR4_RESERVED_BITS;
#define KVM_EXIT_HYPERCALL_VALID_MASK (1 << KVM_HC_MAP_GPA_RANGE)
+#define KVM_CAP_PMU_VALID_MASK KVM_PMU_CAP_DISABLE
+
#define KVM_X2APIC_API_VALID_FLAGS (KVM_X2APIC_API_USE_32BIT_IDS | \
KVM_X2APIC_API_DISABLE_BROADCAST_QUIRK)
@@ -124,16 +128,15 @@ static int __set_sregs2(struct kvm_vcpu *vcpu, struct kvm_sregs2 *sregs2);
static void __get_sregs2(struct kvm_vcpu *vcpu, struct kvm_sregs2 *sregs2);
struct kvm_x86_ops kvm_x86_ops __read_mostly;
-EXPORT_SYMBOL_GPL(kvm_x86_ops);
#define KVM_X86_OP(func) \
DEFINE_STATIC_CALL_NULL(kvm_x86_##func, \
*(((struct kvm_x86_ops *)0)->func));
-#define KVM_X86_OP_NULL KVM_X86_OP
+#define KVM_X86_OP_OPTIONAL KVM_X86_OP
+#define KVM_X86_OP_OPTIONAL_RET0 KVM_X86_OP
#include <asm/kvm-x86-ops.h>
EXPORT_STATIC_CALL_GPL(kvm_x86_get_cs_db_l_bits);
EXPORT_STATIC_CALL_GPL(kvm_x86_cache_reg);
-EXPORT_STATIC_CALL_GPL(kvm_x86_tlb_flush_current);
static bool __read_mostly ignore_msrs = 0;
module_param(ignore_msrs, bool, S_IRUGO | S_IWUSR);
@@ -192,6 +195,9 @@ bool __read_mostly enable_pmu = true;
EXPORT_SYMBOL_GPL(enable_pmu);
module_param(enable_pmu, bool, 0444);
+bool __read_mostly eager_page_split = true;
+module_param(eager_page_split, bool, 0644);
+
/*
* Restoring the host value for MSRs that are only consumed when running in
* usermode, e.g. SYSCALL MSRs and TSC_AUX, can be deferred until the CPU
@@ -758,7 +764,7 @@ bool kvm_inject_emulated_page_fault(struct kvm_vcpu *vcpu,
if ((fault->error_code & PFERR_PRESENT_MASK) &&
!(fault->error_code & PFERR_RSVD_MASK))
kvm_mmu_invalidate_gva(vcpu, fault_mmu, fault->address,
- fault_mmu->root_hpa);
+ fault_mmu->root.hpa);
fault_mmu->inject_page_fault(vcpu, fault);
return fault->nested_page_fault;
@@ -851,7 +857,7 @@ int load_pdptrs(struct kvm_vcpu *vcpu, unsigned long cr3)
* Shadow page roots need to be reconstructed instead.
*/
if (!tdp_enabled && memcmp(mmu->pdptrs, pdpte, sizeof(mmu->pdptrs)))
- kvm_mmu_free_roots(vcpu, mmu, KVM_MMU_ROOT_CURRENT);
+ kvm_mmu_free_roots(vcpu->kvm, mmu, KVM_MMU_ROOT_CURRENT);
memcpy(mmu->pdptrs, pdpte, sizeof(mmu->pdptrs));
kvm_register_mark_dirty(vcpu, VCPU_EXREG_PDPTR);
@@ -867,6 +873,13 @@ void kvm_post_set_cr0(struct kvm_vcpu *vcpu, unsigned long old_cr0, unsigned lon
if ((cr0 ^ old_cr0) & X86_CR0_PG) {
kvm_clear_async_pf_completion_queue(vcpu);
kvm_async_pf_hash_reset(vcpu);
+
+ /*
+ * Clearing CR0.PG is defined to flush the TLB from the guest's
+ * perspective.
+ */
+ if (!(cr0 & X86_CR0_PG))
+ kvm_make_request(KVM_REQ_TLB_FLUSH_GUEST, vcpu);
}
if ((cr0 ^ old_cr0) & KVM_MMU_CR0_ROLE_BITS)
@@ -982,6 +995,18 @@ void kvm_load_host_xsave_state(struct kvm_vcpu *vcpu)
}
EXPORT_SYMBOL_GPL(kvm_load_host_xsave_state);
+static inline u64 kvm_guest_supported_xcr0(struct kvm_vcpu *vcpu)
+{
+ return vcpu->arch.guest_fpu.fpstate->user_xfeatures;
+}
+
+#ifdef CONFIG_X86_64
+static inline u64 kvm_guest_supported_xfd(struct kvm_vcpu *vcpu)
+{
+ return kvm_guest_supported_xcr0(vcpu) & XFEATURE_MASK_USER_DYNAMIC;
+}
+#endif
+
static int __kvm_set_xcr(struct kvm_vcpu *vcpu, u32 index, u64 xcr)
{
u64 xcr0 = xcr;
@@ -1001,7 +1026,7 @@ static int __kvm_set_xcr(struct kvm_vcpu *vcpu, u32 index, u64 xcr)
* saving. However, xcr0 bit 0 is always set, even if the
* emulated CPU does not support XSAVE (see kvm_vcpu_reset()).
*/
- valid_bits = vcpu->arch.guest_supported_xcr0 | XFEATURE_MASK_FP;
+ valid_bits = kvm_guest_supported_xcr0(vcpu) | XFEATURE_MASK_FP;
if (xcr0 & ~valid_bits)
return 1;
@@ -1053,28 +1078,43 @@ EXPORT_SYMBOL_GPL(kvm_is_valid_cr4);
void kvm_post_set_cr4(struct kvm_vcpu *vcpu, unsigned long old_cr4, unsigned long cr4)
{
+ if ((cr4 ^ old_cr4) & KVM_MMU_CR4_ROLE_BITS)
+ kvm_mmu_reset_context(vcpu);
+
/*
- * If any role bit is changed, the MMU needs to be reset.
- *
- * If CR4.PCIDE is changed 1 -> 0, the guest TLB must be flushed.
* If CR4.PCIDE is changed 0 -> 1, there is no need to flush the TLB
* according to the SDM; however, stale prev_roots could be reused
* incorrectly in the future after a MOV to CR3 with NOFLUSH=1, so we
- * free them all. KVM_REQ_MMU_RELOAD is fit for the both cases; it
- * is slow, but changing CR4.PCIDE is a rare case.
- *
- * If CR4.PGE is changed, the guest TLB must be flushed.
+ * free them all. This is *not* a superset of KVM_REQ_TLB_FLUSH_GUEST
+ * or KVM_REQ_TLB_FLUSH_CURRENT, because the hardware TLB is not flushed,
+ * so fall through.
+ */
+ if (!tdp_enabled &&
+ (cr4 & X86_CR4_PCIDE) && !(old_cr4 & X86_CR4_PCIDE))
+ kvm_mmu_unload(vcpu);
+
+ /*
+ * The TLB has to be flushed for all PCIDs if any of the following
+ * (architecturally required) changes happen:
+ * - CR4.PCIDE is changed from 1 to 0
+ * - CR4.PGE is toggled
*
- * Note: resetting MMU is a superset of KVM_REQ_MMU_RELOAD and
- * KVM_REQ_MMU_RELOAD is a superset of KVM_REQ_TLB_FLUSH_GUEST, hence
- * the usage of "else if".
+ * This is a superset of KVM_REQ_TLB_FLUSH_CURRENT.
*/
- if ((cr4 ^ old_cr4) & KVM_MMU_CR4_ROLE_BITS)
- kvm_mmu_reset_context(vcpu);
- else if ((cr4 ^ old_cr4) & X86_CR4_PCIDE)
- kvm_make_request(KVM_REQ_MMU_RELOAD, vcpu);
- else if ((cr4 ^ old_cr4) & X86_CR4_PGE)
+ if (((cr4 ^ old_cr4) & X86_CR4_PGE) ||
+ (!(cr4 & X86_CR4_PCIDE) && (old_cr4 & X86_CR4_PCIDE)))
kvm_make_request(KVM_REQ_TLB_FLUSH_GUEST, vcpu);
+
+ /*
+ * The TLB has to be flushed for the current PCID if any of the
+ * following (architecturally required) changes happen:
+ * - CR4.SMEP is changed from 0 to 1
+ * - CR4.PAE is toggled
+ */
+ else if (((cr4 ^ old_cr4) & X86_CR4_PAE) ||
+ ((cr4 & X86_CR4_SMEP) && !(old_cr4 & X86_CR4_SMEP)))
+ kvm_make_request(KVM_REQ_TLB_FLUSH_CURRENT, vcpu);
+
}
EXPORT_SYMBOL_GPL(kvm_post_set_cr4);
@@ -1152,7 +1192,7 @@ static void kvm_invalidate_pcid(struct kvm_vcpu *vcpu, unsigned long pcid)
if (kvm_get_pcid(vcpu, mmu->prev_roots[i].pgd) == pcid)
roots_to_free |= KVM_MMU_ROOT_PREVIOUS(i);
- kvm_mmu_free_roots(vcpu, mmu, roots_to_free);
+ kvm_mmu_free_roots(vcpu->kvm, mmu, roots_to_free);
}
int kvm_set_cr3(struct kvm_vcpu *vcpu, unsigned long cr3)
@@ -1642,8 +1682,7 @@ static int set_efer(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
return r;
}
- /* Update reserved bits */
- if ((efer ^ old_efer) & EFER_NX)
+ if ((efer ^ old_efer) & KVM_MMU_EFER_ROLE_BITS)
kvm_mmu_reset_context(vcpu);
return 0;
@@ -1735,7 +1774,7 @@ static int __kvm_set_msr(struct kvm_vcpu *vcpu, u32 index, u64 data,
* value, and that something deterministic happens if the guest
* invokes 64-bit SYSENTER.
*/
- data = get_canonical(data, vcpu_virt_addr_bits(vcpu));
+ data = __canonical_address(data, vcpu_virt_addr_bits(vcpu));
break;
case MSR_TSC_AUX:
if (!kvm_is_supported_user_return_msr(MSR_TSC_AUX))
@@ -2012,17 +2051,10 @@ static int handle_fastpath_set_x2apic_icr_irqoff(struct kvm_vcpu *vcpu, u64 data
return 1;
if (((data & APIC_SHORT_MASK) == APIC_DEST_NOSHORT) &&
- ((data & APIC_DEST_MASK) == APIC_DEST_PHYSICAL) &&
- ((data & APIC_MODE_MASK) == APIC_DM_FIXED) &&
- ((u32)(data >> 32) != X2APIC_BROADCAST)) {
-
- data &= ~(1 << 12);
- kvm_apic_send_ipi(vcpu->arch.apic, (u32)data, (u32)(data >> 32));
- kvm_lapic_set_reg(vcpu->arch.apic, APIC_ICR2, (u32)(data >> 32));
- kvm_lapic_set_reg(vcpu->arch.apic, APIC_ICR, (u32)data);
- trace_kvm_apic_write(APIC_ICR, (u32)data);
- return 0;
- }
+ ((data & APIC_DEST_MASK) == APIC_DEST_PHYSICAL) &&
+ ((data & APIC_MODE_MASK) == APIC_DM_FIXED) &&
+ ((u32)(data >> 32) != X2APIC_BROADCAST))
+ return kvm_x2apic_icr_write(vcpu->arch.apic, data);
return 1;
}
@@ -2349,10 +2381,12 @@ static u64 compute_guest_tsc(struct kvm_vcpu *vcpu, s64 kernel_ns)
return tsc;
}
+#ifdef CONFIG_X86_64
static inline int gtod_is_based_on_tsc(int mode)
{
return mode == VDSO_CLOCKMODE_TSC || mode == VDSO_CLOCKMODE_HVCLOCK;
}
+#endif
static void kvm_track_tsc_matching(struct kvm_vcpu *vcpu)
{
@@ -2397,7 +2431,7 @@ static inline u64 __scale_tsc(u64 ratio, u64 tsc)
return mul_u64_u64_shr(tsc, ratio, kvm_tsc_scaling_ratio_frac_bits);
}
-u64 kvm_scale_tsc(struct kvm_vcpu *vcpu, u64 tsc, u64 ratio)
+u64 kvm_scale_tsc(u64 tsc, u64 ratio)
{
u64 _tsc = tsc;
@@ -2412,7 +2446,7 @@ static u64 kvm_compute_l1_tsc_offset(struct kvm_vcpu *vcpu, u64 target_tsc)
{
u64 tsc;
- tsc = kvm_scale_tsc(vcpu, rdtsc(), vcpu->arch.l1_tsc_scaling_ratio);
+ tsc = kvm_scale_tsc(rdtsc(), vcpu->arch.l1_tsc_scaling_ratio);
return target_tsc - tsc;
}
@@ -2420,7 +2454,7 @@ static u64 kvm_compute_l1_tsc_offset(struct kvm_vcpu *vcpu, u64 target_tsc)
u64 kvm_read_l1_tsc(struct kvm_vcpu *vcpu, u64 host_tsc)
{
return vcpu->arch.l1_tsc_offset +
- kvm_scale_tsc(vcpu, host_tsc, vcpu->arch.l1_tsc_scaling_ratio);
+ kvm_scale_tsc(host_tsc, vcpu->arch.l1_tsc_scaling_ratio);
}
EXPORT_SYMBOL_GPL(kvm_read_l1_tsc);
@@ -2623,7 +2657,7 @@ static inline void adjust_tsc_offset_host(struct kvm_vcpu *vcpu, s64 adjustment)
{
if (vcpu->arch.l1_tsc_scaling_ratio != kvm_default_tsc_scaling_ratio)
WARN_ON(adjustment < 0);
- adjustment = kvm_scale_tsc(vcpu, (u64) adjustment,
+ adjustment = kvm_scale_tsc((u64) adjustment,
vcpu->arch.l1_tsc_scaling_ratio);
adjust_tsc_offset_guest(vcpu, adjustment);
}
@@ -3043,7 +3077,7 @@ static int kvm_guest_time_update(struct kvm_vcpu *v)
/* With all the info we got, fill in the values */
if (kvm_has_tsc_control)
- tgt_tsc_khz = kvm_scale_tsc(v, tgt_tsc_khz,
+ tgt_tsc_khz = kvm_scale_tsc(tgt_tsc_khz,
v->arch.l1_tsc_scaling_ratio);
if (unlikely(vcpu->hw_tsc_khz != tgt_tsc_khz)) {
@@ -3266,7 +3300,7 @@ static void kvmclock_reset(struct kvm_vcpu *vcpu)
static void kvm_vcpu_flush_tlb_all(struct kvm_vcpu *vcpu)
{
++vcpu->stat.tlb_flush;
- static_call(kvm_x86_tlb_flush_all)(vcpu);
+ static_call(kvm_x86_flush_tlb_all)(vcpu);
}
static void kvm_vcpu_flush_tlb_guest(struct kvm_vcpu *vcpu)
@@ -3284,14 +3318,14 @@ static void kvm_vcpu_flush_tlb_guest(struct kvm_vcpu *vcpu)
kvm_mmu_sync_prev_roots(vcpu);
}
- static_call(kvm_x86_tlb_flush_guest)(vcpu);
+ static_call(kvm_x86_flush_tlb_guest)(vcpu);
}
static inline void kvm_vcpu_flush_tlb_current(struct kvm_vcpu *vcpu)
{
++vcpu->stat.tlb_flush;
- static_call(kvm_x86_tlb_flush_current)(vcpu);
+ static_call(kvm_x86_flush_tlb_current)(vcpu);
}
/*
@@ -3535,6 +3569,7 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
if (data & ~supported_xss)
return 1;
vcpu->arch.ia32_xss = data;
+ kvm_update_cpuid_runtime(vcpu);
break;
case MSR_SMI_COUNT:
if (!msr_info->host_initiated)
@@ -3703,8 +3738,7 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
!guest_cpuid_has(vcpu, X86_FEATURE_XFD))
return 1;
- if (data & ~(XFEATURE_MASK_USER_DYNAMIC &
- vcpu->arch.guest_supported_xcr0))
+ if (data & ~kvm_guest_supported_xfd(vcpu))
return 1;
fpu_update_guest_xfd(&vcpu->arch.guest_fpu, data);
@@ -3714,8 +3748,7 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
!guest_cpuid_has(vcpu, X86_FEATURE_XFD))
return 1;
- if (data & ~(XFEATURE_MASK_USER_DYNAMIC &
- vcpu->arch.guest_supported_xcr0))
+ if (data & ~kvm_guest_supported_xfd(vcpu))
return 1;
vcpu->arch.guest_fpu.xfd_err = data;
@@ -3854,7 +3887,7 @@ int kvm_get_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
ratio = vcpu->arch.tsc_scaling_ratio;
}
- msr_info->data = kvm_scale_tsc(vcpu, rdtsc(), ratio) + offset;
+ msr_info->data = kvm_scale_tsc(rdtsc(), ratio) + offset;
break;
}
case MSR_MTRRcap:
@@ -4229,6 +4262,9 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
case KVM_CAP_SREGS2:
case KVM_CAP_EXIT_ON_EMULATION_FAILURE:
case KVM_CAP_VCPU_ATTRIBUTES:
+ case KVM_CAP_SYS_ATTRIBUTES:
+ case KVM_CAP_VAPIC:
+ case KVM_CAP_ENABLE_CAP:
r = 1;
break;
case KVM_CAP_EXIT_HYPERCALL:
@@ -4269,9 +4305,6 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
*/
r = static_call(kvm_x86_has_emulated_msr)(kvm, MSR_IA32_SMBASE);
break;
- case KVM_CAP_VAPIC:
- r = !static_call(kvm_x86_cpu_has_accelerated_tpr)();
- break;
case KVM_CAP_NR_VCPUS:
r = min_t(unsigned int, num_online_cpus(), KVM_MAX_VCPUS);
break;
@@ -4326,12 +4359,60 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
if (r < sizeof(struct kvm_xsave))
r = sizeof(struct kvm_xsave);
break;
+ case KVM_CAP_PMU_CAPABILITY:
+ r = enable_pmu ? KVM_CAP_PMU_VALID_MASK : 0;
+ break;
}
+ case KVM_CAP_DISABLE_QUIRKS2:
+ r = KVM_X86_VALID_QUIRKS;
+ break;
default:
break;
}
return r;
+}
+static inline void __user *kvm_get_attr_addr(struct kvm_device_attr *attr)
+{
+ void __user *uaddr = (void __user*)(unsigned long)attr->addr;
+
+ if ((u64)(unsigned long)uaddr != attr->addr)
+ return ERR_PTR_USR(-EFAULT);
+ return uaddr;
+}
+
+static int kvm_x86_dev_get_attr(struct kvm_device_attr *attr)
+{
+ u64 __user *uaddr = kvm_get_attr_addr(attr);
+
+ if (attr->group)
+ return -ENXIO;
+
+ if (IS_ERR(uaddr))
+ return PTR_ERR(uaddr);
+
+ switch (attr->attr) {
+ case KVM_X86_XCOMP_GUEST_SUPP:
+ if (put_user(supported_xcr0, uaddr))
+ return -EFAULT;
+ return 0;
+ default:
+ return -ENXIO;
+ break;
+ }
+}
+
+static int kvm_x86_dev_has_attr(struct kvm_device_attr *attr)
+{
+ if (attr->group)
+ return -ENXIO;
+
+ switch (attr->attr) {
+ case KVM_X86_XCOMP_GUEST_SUPP:
+ return 0;
+ default:
+ return -ENXIO;
+ }
}
long kvm_arch_dev_ioctl(struct file *filp,
@@ -4422,6 +4503,22 @@ long kvm_arch_dev_ioctl(struct file *filp,
case KVM_GET_SUPPORTED_HV_CPUID:
r = kvm_ioctl_get_supported_hv_cpuid(NULL, argp);
break;
+ case KVM_GET_DEVICE_ATTR: {
+ struct kvm_device_attr attr;
+ r = -EFAULT;
+ if (copy_from_user(&attr, (void __user *)arg, sizeof(attr)))
+ break;
+ r = kvm_x86_dev_get_attr(&attr);
+ break;
+ }
+ case KVM_HAS_DEVICE_ATTR: {
+ struct kvm_device_attr attr;
+ r = -EFAULT;
+ if (copy_from_user(&attr, (void __user *)arg, sizeof(attr)))
+ break;
+ r = kvm_x86_dev_has_attr(&attr);
+ break;
+ }
default:
r = -EINVAL;
break;
@@ -4860,8 +4957,10 @@ static int kvm_vcpu_ioctl_x86_set_vcpu_events(struct kvm_vcpu *vcpu,
vcpu->arch.apic->sipi_vector = events->sipi_vector;
if (events->flags & KVM_VCPUEVENT_VALID_SMM) {
- if (!!(vcpu->arch.hflags & HF_SMM_MASK) != events->smi.smm)
+ if (!!(vcpu->arch.hflags & HF_SMM_MASK) != events->smi.smm) {
+ kvm_x86_ops.nested_ops->leave_nested(vcpu);
kvm_smm_changed(vcpu, events->smi.smm);
+ }
vcpu->arch.smi_pending = events->smi.pending;
@@ -5022,11 +5121,11 @@ static int kvm_arch_tsc_has_attr(struct kvm_vcpu *vcpu,
static int kvm_arch_tsc_get_attr(struct kvm_vcpu *vcpu,
struct kvm_device_attr *attr)
{
- u64 __user *uaddr = (u64 __user *)(unsigned long)attr->addr;
+ u64 __user *uaddr = kvm_get_attr_addr(attr);
int r;
- if ((u64)(unsigned long)uaddr != attr->addr)
- return -EFAULT;
+ if (IS_ERR(uaddr))
+ return PTR_ERR(uaddr);
switch (attr->attr) {
case KVM_VCPU_TSC_OFFSET:
@@ -5045,12 +5144,12 @@ static int kvm_arch_tsc_get_attr(struct kvm_vcpu *vcpu,
static int kvm_arch_tsc_set_attr(struct kvm_vcpu *vcpu,
struct kvm_device_attr *attr)
{
- u64 __user *uaddr = (u64 __user *)(unsigned long)attr->addr;
+ u64 __user *uaddr = kvm_get_attr_addr(attr);
struct kvm *kvm = vcpu->kvm;
int r;
- if ((u64)(unsigned long)uaddr != attr->addr)
- return -EFAULT;
+ if (IS_ERR(uaddr))
+ return PTR_ERR(uaddr);
switch (attr->attr) {
case KVM_VCPU_TSC_OFFSET: {
@@ -5068,7 +5167,7 @@ static int kvm_arch_tsc_set_attr(struct kvm_vcpu *vcpu,
kvm->arch.last_tsc_khz == vcpu->arch.virtual_tsc_khz &&
kvm->arch.last_tsc_offset == offset);
- tsc = kvm_scale_tsc(vcpu, rdtsc(), vcpu->arch.l1_tsc_scaling_ratio) + offset;
+ tsc = kvm_scale_tsc(rdtsc(), vcpu->arch.l1_tsc_scaling_ratio) + offset;
ns = get_kvmclock_base_ns();
__kvm_synchronize_tsc(vcpu, offset, tsc, ns, matched);
@@ -5813,6 +5912,11 @@ int kvm_vm_ioctl_enable_cap(struct kvm *kvm,
return -EINVAL;
switch (cap->cap) {
+ case KVM_CAP_DISABLE_QUIRKS2:
+ r = -EINVAL;
+ if (cap->args[0] & ~KVM_X86_VALID_QUIRKS)
+ break;
+ fallthrough;
case KVM_CAP_DISABLE_QUIRKS:
kvm->arch.disabled_quirks = cap->args[0];
r = 0;
@@ -5913,15 +6017,18 @@ split_irqchip_unlock:
#endif
case KVM_CAP_VM_COPY_ENC_CONTEXT_FROM:
r = -EINVAL;
- if (kvm_x86_ops.vm_copy_enc_context_from)
- r = kvm_x86_ops.vm_copy_enc_context_from(kvm, cap->args[0]);
- return r;
+ if (!kvm_x86_ops.vm_copy_enc_context_from)
+ break;
+
+ r = static_call(kvm_x86_vm_copy_enc_context_from)(kvm, cap->args[0]);
+ break;
case KVM_CAP_VM_MOVE_ENC_CONTEXT_FROM:
r = -EINVAL;
- if (kvm_x86_ops.vm_move_enc_context_from)
- r = kvm_x86_ops.vm_move_enc_context_from(
- kvm, cap->args[0]);
- return r;
+ if (!kvm_x86_ops.vm_move_enc_context_from)
+ break;
+
+ r = static_call(kvm_x86_vm_move_enc_context_from)(kvm, cap->args[0]);
+ break;
case KVM_CAP_EXIT_HYPERCALL:
if (cap->args[0] & ~KVM_EXIT_HYPERCALL_VALID_MASK) {
r = -EINVAL;
@@ -5937,6 +6044,18 @@ split_irqchip_unlock:
kvm->arch.exit_on_emulation_error = cap->args[0];
r = 0;
break;
+ case KVM_CAP_PMU_CAPABILITY:
+ r = -EINVAL;
+ if (!enable_pmu || (cap->args[0] & ~KVM_CAP_PMU_VALID_MASK))
+ break;
+
+ mutex_lock(&kvm->lock);
+ if (!kvm->created_vcpus) {
+ kvm->arch.enable_pmu = !(cap->args[0] & KVM_PMU_CAP_DISABLE);
+ r = 0;
+ }
+ mutex_unlock(&kvm->lock);
+ break;
default:
r = -EINVAL;
break;
@@ -6396,8 +6515,10 @@ set_pit2_out:
break;
case KVM_MEMORY_ENCRYPT_OP: {
r = -ENOTTY;
- if (kvm_x86_ops.mem_enc_op)
- r = static_call(kvm_x86_mem_enc_op)(kvm, argp);
+ if (!kvm_x86_ops.mem_enc_ioctl)
+ goto out;
+
+ r = static_call(kvm_x86_mem_enc_ioctl)(kvm, argp);
break;
}
case KVM_MEMORY_ENCRYPT_REG_REGION: {
@@ -6408,8 +6529,10 @@ set_pit2_out:
goto out;
r = -ENOTTY;
- if (kvm_x86_ops.mem_enc_reg_region)
- r = static_call(kvm_x86_mem_enc_reg_region)(kvm, &region);
+ if (!kvm_x86_ops.mem_enc_register_region)
+ goto out;
+
+ r = static_call(kvm_x86_mem_enc_register_region)(kvm, &region);
break;
}
case KVM_MEMORY_ENCRYPT_UNREG_REGION: {
@@ -6420,8 +6543,10 @@ set_pit2_out:
goto out;
r = -ENOTTY;
- if (kvm_x86_ops.mem_enc_unreg_region)
- r = static_call(kvm_x86_mem_enc_unreg_region)(kvm, &region);
+ if (!kvm_x86_ops.mem_enc_unregister_region)
+ goto out;
+
+ r = static_call(kvm_x86_mem_enc_unregister_region)(kvm, &region);
break;
}
case KVM_HYPERV_EVENTFD: {
@@ -6452,7 +6577,7 @@ static void kvm_init_msr_list(void)
u32 dummy[2];
unsigned i;
- BUILD_BUG_ON_MSG(INTEL_PMC_MAX_FIXED != 4,
+ BUILD_BUG_ON_MSG(KVM_PMC_MAX_FIXED != 3,
"Please update the fixed PMCs in msrs_to_saved_all[]");
perf_get_x86_pmu_capability(&x86_pmu);
@@ -6810,6 +6935,13 @@ int kvm_write_guest_virt_system(struct kvm_vcpu *vcpu, gva_t addr, void *val,
}
EXPORT_SYMBOL_GPL(kvm_write_guest_virt_system);
+static int kvm_can_emulate_insn(struct kvm_vcpu *vcpu, int emul_type,
+ void *insn, int insn_len)
+{
+ return static_call(kvm_x86_can_emulate_instruction)(vcpu, emul_type,
+ insn, insn_len);
+}
+
int handle_ud(struct kvm_vcpu *vcpu)
{
static const char kvm_emulate_prefix[] = { __KVM_EMULATE_PREFIX };
@@ -6817,7 +6949,7 @@ int handle_ud(struct kvm_vcpu *vcpu)
char sig[5]; /* ud2; .ascii "kvm" */
struct x86_exception e;
- if (unlikely(!static_call(kvm_x86_can_emulate_instruction)(vcpu, NULL, 0)))
+ if (unlikely(!kvm_can_emulate_insn(vcpu, emul_type, NULL, 0)))
return 1;
if (force_emulation_prefix &&
@@ -8193,7 +8325,7 @@ int x86_emulate_instruction(struct kvm_vcpu *vcpu, gpa_t cr2_or_gpa,
bool writeback = true;
bool write_fault_to_spt;
- if (unlikely(!static_call(kvm_x86_can_emulate_instruction)(vcpu, insn, insn_len)))
+ if (unlikely(!kvm_can_emulate_insn(vcpu, emulation_type, insn, insn_len)))
return 1;
vcpu->arch.l1tf_flush_l1d = true;
@@ -8342,8 +8474,7 @@ writeback:
kvm_rip_write(vcpu, ctxt->eip);
if (r && (ctxt->tf || (vcpu->guest_debug & KVM_GUESTDBG_SINGLESTEP)))
r = kvm_vcpu_do_singlestep(vcpu);
- if (kvm_x86_ops.update_emulated_instruction)
- static_call(kvm_x86_update_emulated_instruction)(vcpu);
+ static_call_cond(kvm_x86_update_emulated_instruction)(vcpu);
__kvm_set_rflags(vcpu, ctxt->eflags);
}
@@ -8742,6 +8873,12 @@ int kvm_arch_init(void *opaque)
goto out;
}
+ if (IS_ENABLED(CONFIG_PREEMPT_RT) && !boot_cpu_has(X86_FEATURE_CONSTANT_TSC)) {
+ pr_err("RT requires X86_FEATURE_CONSTANT_TSC\n");
+ r = -EOPNOTSUPP;
+ goto out;
+ }
+
r = -ENOMEM;
x86_emulator_cache = kvm_alloc_emulator_cache();
@@ -8769,7 +8906,7 @@ int kvm_arch_init(void *opaque)
}
if (pi_inject_timer == -1)
- pi_inject_timer = housekeeping_enabled(HK_FLAG_TIMER);
+ pi_inject_timer = housekeeping_enabled(HK_TYPE_TIMER);
#ifdef CONFIG_X86_64
pvclock_gtod_register_notifier(&pvclock_gtod_notifier);
@@ -8871,6 +9008,13 @@ static int kvm_pv_clock_pairing(struct kvm_vcpu *vcpu, gpa_t paddr,
if (clock_type != KVM_CLOCK_PAIRING_WALLCLOCK)
return -KVM_EOPNOTSUPP;
+ /*
+ * When tsc is in permanent catchup mode guests won't be able to use
+ * pvclock_read_retry loop to get consistent view of pvclock
+ */
+ if (vcpu->arch.tsc_always_catchup)
+ return -KVM_EOPNOTSUPP;
+
if (!kvm_get_walltime_and_clockread(&ts, &cycle))
return -KVM_EOPNOTSUPP;
@@ -8894,7 +9038,7 @@ static int kvm_pv_clock_pairing(struct kvm_vcpu *vcpu, gpa_t paddr,
*
* @apicid - apicid of vcpu to be kicked.
*/
-static void kvm_pv_kick_cpu_op(struct kvm *kvm, unsigned long flags, int apicid)
+static void kvm_pv_kick_cpu_op(struct kvm *kvm, int apicid)
{
struct kvm_lapic_irq lapic_irq;
@@ -9013,7 +9157,7 @@ int kvm_emulate_hypercall(struct kvm_vcpu *vcpu)
if (!guest_pv_has(vcpu, KVM_FEATURE_PV_UNHALT))
break;
- kvm_pv_kick_cpu_op(vcpu->kvm, a0, a1);
+ kvm_pv_kick_cpu_op(vcpu->kvm, a1);
kvm_sched_yield(vcpu, a1);
ret = 0;
break;
@@ -9089,6 +9233,7 @@ static int dm_request_for_irq_injection(struct kvm_vcpu *vcpu)
likely(!pic_in_kernel(vcpu->kvm));
}
+/* Called within kvm->srcu read side. */
static void post_kvm_run_save(struct kvm_vcpu *vcpu)
{
struct kvm_run *kvm_run = vcpu->run;
@@ -9097,16 +9242,9 @@ static void post_kvm_run_save(struct kvm_vcpu *vcpu)
kvm_run->cr8 = kvm_get_cr8(vcpu);
kvm_run->apic_base = kvm_get_apic_base(vcpu);
- /*
- * The call to kvm_ready_for_interrupt_injection() may end up in
- * kvm_xen_has_interrupt() which may require the srcu lock to be
- * held, to protect against changes in the vcpu_info address.
- */
- vcpu->srcu_idx = srcu_read_lock(&vcpu->kvm->srcu);
kvm_run->ready_for_interrupt_injection =
pic_in_kernel(vcpu->kvm) ||
kvm_vcpu_ready_for_interrupt_injection(vcpu);
- srcu_read_unlock(&vcpu->kvm->srcu, vcpu->srcu_idx);
if (is_smm(vcpu))
kvm_run->flags |= KVM_RUN_X86_SMM;
@@ -9183,10 +9321,10 @@ static int inject_pending_event(struct kvm_vcpu *vcpu, bool *req_immediate_exit)
*/
else if (!vcpu->arch.exception.pending) {
if (vcpu->arch.nmi_injected) {
- static_call(kvm_x86_set_nmi)(vcpu);
+ static_call(kvm_x86_inject_nmi)(vcpu);
can_inject = false;
} else if (vcpu->arch.interrupt.injected) {
- static_call(kvm_x86_set_irq)(vcpu);
+ static_call(kvm_x86_inject_irq)(vcpu);
can_inject = false;
}
}
@@ -9266,7 +9404,7 @@ static int inject_pending_event(struct kvm_vcpu *vcpu, bool *req_immediate_exit)
if (r) {
--vcpu->arch.nmi_pending;
vcpu->arch.nmi_injected = true;
- static_call(kvm_x86_set_nmi)(vcpu);
+ static_call(kvm_x86_inject_nmi)(vcpu);
can_inject = false;
WARN_ON(static_call(kvm_x86_nmi_allowed)(vcpu, true) < 0);
}
@@ -9280,7 +9418,7 @@ static int inject_pending_event(struct kvm_vcpu *vcpu, bool *req_immediate_exit)
goto out;
if (r) {
kvm_queue_interrupt(vcpu, kvm_cpu_get_interrupt(vcpu), false);
- static_call(kvm_x86_set_irq)(vcpu);
+ static_call(kvm_x86_inject_irq)(vcpu);
WARN_ON(static_call(kvm_x86_interrupt_allowed)(vcpu, true) < 0);
}
if (kvm_cpu_has_injectable_intr(vcpu))
@@ -9608,8 +9746,7 @@ void __kvm_request_apicv_update(struct kvm *kvm, bool activate, ulong bit)
lockdep_assert_held_write(&kvm->arch.apicv_update_lock);
- if (!kvm_x86_ops.check_apicv_inhibit_reasons ||
- !static_call(kvm_x86_check_apicv_inhibit_reasons)(bit))
+ if (!static_call(kvm_x86_check_apicv_inhibit_reasons)(bit))
return;
old = new = kvm->arch.apicv_inhibit_reasons;
@@ -9642,10 +9779,12 @@ void __kvm_request_apicv_update(struct kvm *kvm, bool activate, ulong bit)
} else
kvm->arch.apicv_inhibit_reasons = new;
}
-EXPORT_SYMBOL_GPL(__kvm_request_apicv_update);
void kvm_request_apicv_update(struct kvm *kvm, bool activate, ulong bit)
{
+ if (!enable_apicv)
+ return;
+
down_write(&kvm->arch.apicv_update_lock);
__kvm_request_apicv_update(kvm, activate, bit);
up_write(&kvm->arch.apicv_update_lock);
@@ -9684,11 +9823,11 @@ static void vcpu_load_eoi_exitmap(struct kvm_vcpu *vcpu)
bitmap_or((ulong *)eoi_exit_bitmap,
vcpu->arch.ioapic_handled_vectors,
to_hv_synic(vcpu)->vec_bitmap, 256);
- static_call(kvm_x86_load_eoi_exitmap)(vcpu, eoi_exit_bitmap);
+ static_call_cond(kvm_x86_load_eoi_exitmap)(vcpu, eoi_exit_bitmap);
return;
}
- static_call(kvm_x86_load_eoi_exitmap)(
+ static_call_cond(kvm_x86_load_eoi_exitmap)(
vcpu, (u64 *)vcpu->arch.ioapic_handled_vectors);
}
@@ -9706,15 +9845,12 @@ void kvm_arch_mmu_notifier_invalidate_range(struct kvm *kvm,
kvm_make_all_cpus_request(kvm, KVM_REQ_APIC_PAGE_RELOAD);
}
-void kvm_vcpu_reload_apic_access_page(struct kvm_vcpu *vcpu)
+static void kvm_vcpu_reload_apic_access_page(struct kvm_vcpu *vcpu)
{
if (!lapic_in_kernel(vcpu))
return;
- if (!kvm_x86_ops.set_apic_access_page_addr)
- return;
-
- static_call(kvm_x86_set_apic_access_page_addr)(vcpu);
+ static_call_cond(kvm_x86_set_apic_access_page_addr)(vcpu);
}
void __kvm_request_immediate_exit(struct kvm_vcpu *vcpu)
@@ -9724,6 +9860,7 @@ void __kvm_request_immediate_exit(struct kvm_vcpu *vcpu)
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
* exiting to the userspace. Otherwise, the value will be returned to the
* userspace.
@@ -9758,8 +9895,8 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu)
goto out;
}
}
- if (kvm_check_request(KVM_REQ_MMU_RELOAD, vcpu))
- kvm_mmu_unload(vcpu);
+ if (kvm_check_request(KVM_REQ_MMU_FREE_OBSOLETE_ROOTS, vcpu))
+ kvm_mmu_free_obsolete_roots(vcpu);
if (kvm_check_request(KVM_REQ_MIGRATE_TIMER, vcpu))
__kvm_migrate_timers(vcpu);
if (kvm_check_request(KVM_REQ_MASTERCLOCK_UPDATE, vcpu))
@@ -9904,7 +10041,7 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu)
preempt_disable();
- static_call(kvm_x86_prepare_guest_switch)(vcpu);
+ static_call(kvm_x86_prepare_switch_to_guest)(vcpu);
/*
* Disable IRQs before setting IN_GUEST_MODE. Posted interrupt
@@ -9912,7 +10049,9 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu)
* result in virtual interrupt delivery.
*/
local_irq_disable();
- vcpu->mode = IN_GUEST_MODE;
+
+ /* Store vcpu->apicv_active before vcpu->mode. */
+ smp_store_release(&vcpu->mode, IN_GUEST_MODE);
srcu_read_unlock(&vcpu->kvm->srcu, vcpu->srcu_idx);
@@ -9972,6 +10111,8 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu)
set_debugreg(0, 7);
}
+ guest_timing_enter_irqoff();
+
for (;;) {
/*
* Assert that vCPU vs. VM APICv state is consistent. An APICv
@@ -9981,7 +10122,7 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu)
*/
WARN_ON_ONCE(kvm_apicv_activated(vcpu->kvm) != kvm_vcpu_apicv_active(vcpu));
- exit_fastpath = static_call(kvm_x86_run)(vcpu);
+ exit_fastpath = static_call(kvm_x86_vcpu_run)(vcpu);
if (likely(exit_fastpath != EXIT_FASTPATH_REENTER_GUEST))
break;
@@ -10056,7 +10197,7 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu)
* of accounting via context tracking, but the loss of accuracy is
* acceptable for all known use cases.
*/
- vtime_account_guest_exit();
+ guest_timing_exit_irqoff();
if (lapic_in_kernel(vcpu)) {
s64 delta = vcpu->arch.apic->lapic_timer.advance_expire_delta;
@@ -10098,6 +10239,7 @@ out:
return r;
}
+/* Called within kvm->srcu read side. */
static inline int vcpu_block(struct kvm *kvm, struct kvm_vcpu *vcpu)
{
bool hv_timer;
@@ -10157,12 +10299,12 @@ static inline bool kvm_vcpu_running(struct kvm_vcpu *vcpu)
!vcpu->arch.apf.halted);
}
+/* Called within kvm->srcu read side. */
static int vcpu_run(struct kvm_vcpu *vcpu)
{
int r;
struct kvm *kvm = vcpu->kvm;
- vcpu->srcu_idx = srcu_read_lock(&kvm->srcu);
vcpu->arch.l1tf_flush_l1d = true;
for (;;) {
@@ -10190,14 +10332,12 @@ static int vcpu_run(struct kvm_vcpu *vcpu)
if (__xfer_to_guest_mode_work_pending()) {
srcu_read_unlock(&kvm->srcu, vcpu->srcu_idx);
r = xfer_to_guest_mode_handle_work(vcpu);
+ vcpu->srcu_idx = srcu_read_lock(&kvm->srcu);
if (r)
return r;
- vcpu->srcu_idx = srcu_read_lock(&kvm->srcu);
}
}
- srcu_read_unlock(&kvm->srcu, vcpu->srcu_idx);
-
return r;
}
@@ -10284,10 +10424,7 @@ static int complete_emulated_mmio(struct kvm_vcpu *vcpu)
/* Swap (qemu) user FPU context for the guest FPU context. */
static void kvm_load_guest_fpu(struct kvm_vcpu *vcpu)
{
- /*
- * Exclude PKRU from restore as restored separately in
- * kvm_x86_ops.run().
- */
+ /* Exclude PKRU, it's restored separately immediately after VM-Exit. */
fpu_swap_kvm_fpstate(&vcpu->arch.guest_fpu, true);
trace_kvm_fpu(1);
}
@@ -10303,6 +10440,7 @@ static void kvm_put_guest_fpu(struct kvm_vcpu *vcpu)
int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu)
{
struct kvm_run *kvm_run = vcpu->run;
+ struct kvm *kvm = vcpu->kvm;
int r;
vcpu_load(vcpu);
@@ -10310,6 +10448,7 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu)
kvm_run->flags = 0;
kvm_load_guest_fpu(vcpu);
+ vcpu->srcu_idx = srcu_read_lock(&vcpu->kvm->srcu);
if (unlikely(vcpu->arch.mp_state == KVM_MP_STATE_UNINITIALIZED)) {
if (kvm_run->immediate_exit) {
r = -EINTR;
@@ -10320,7 +10459,11 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu)
* use before KVM has ever run the vCPU.
*/
WARN_ON_ONCE(kvm_lapic_hv_timer_in_use(vcpu));
+
+ srcu_read_unlock(&kvm->srcu, vcpu->srcu_idx);
kvm_vcpu_block(vcpu);
+ vcpu->srcu_idx = srcu_read_lock(&kvm->srcu);
+
if (kvm_apic_accept_events(vcpu) < 0) {
r = 0;
goto out;
@@ -10380,8 +10523,9 @@ out:
if (kvm_run->kvm_valid_regs)
store_regs(vcpu);
post_kvm_run_save(vcpu);
- kvm_sigset_deactivate(vcpu);
+ srcu_read_unlock(&kvm->srcu, vcpu->srcu_idx);
+ kvm_sigset_deactivate(vcpu);
vcpu_put(vcpu);
return r;
}
@@ -10470,16 +10614,6 @@ int kvm_arch_vcpu_ioctl_set_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
return 0;
}
-void kvm_get_cs_db_l_bits(struct kvm_vcpu *vcpu, int *db, int *l)
-{
- struct kvm_segment cs;
-
- kvm_get_segment(vcpu, &cs, VCPU_SREG_CS);
- *db = cs.db;
- *l = cs.l;
-}
-EXPORT_SYMBOL_GPL(kvm_get_cs_db_l_bits);
-
static void __get_sregs_common(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs)
{
struct desc_ptr dt;
@@ -11209,7 +11343,8 @@ void kvm_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event)
vcpu->arch.msr_misc_features_enables = 0;
- vcpu->arch.xcr0 = XFEATURE_MASK_FP;
+ __kvm_set_xcr(vcpu, 0, XFEATURE_MASK_FP);
+ __kvm_set_msr(vcpu, MSR_IA32_XSS, 0, true);
}
/* All GPRs except RDX (handled below) are zeroed on RESET/INIT. */
@@ -11226,8 +11361,6 @@ void kvm_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event)
cpuid_0x1 = kvm_find_cpuid_entry(vcpu, 1, 0);
kvm_rdx_write(vcpu, cpuid_0x1 ? cpuid_0x1->eax : 0x600);
- vcpu->arch.ia32_xss = 0;
-
static_call(kvm_x86_vcpu_reset)(vcpu, init_event);
kvm_set_rflags(vcpu, X86_EFLAGS_FIXED);
@@ -11253,15 +11386,17 @@ void kvm_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event)
static_call(kvm_x86_update_exception_bitmap)(vcpu);
/*
- * Reset the MMU context if paging was enabled prior to INIT (which is
- * implied if CR0.PG=1 as CR0 will be '0' prior to RESET). Unlike the
- * standard CR0/CR4/EFER modification paths, only CR0.PG needs to be
- * checked because it is unconditionally cleared on INIT and all other
- * paging related bits are ignored if paging is disabled, i.e. CR0.WP,
- * CR4, and EFER changes are all irrelevant if CR0.PG was '0'.
+ * On the standard CR0/CR4/EFER modification paths, there are several
+ * complex conditions determining whether the MMU has to be reset and/or
+ * which PCIDs have to be flushed. However, CR0.WP and the paging-related
+ * bits in CR4 and EFER are irrelevant if CR0.PG was '0'; and a reset+flush
+ * is needed anyway if CR0.PG was '1' (which can only happen for INIT, as
+ * CR0 will be '0' prior to RESET). So we only need to check CR0.PG here.
*/
- if (old_cr0 & X86_CR0_PG)
+ if (old_cr0 & X86_CR0_PG) {
+ kvm_make_request(KVM_REQ_TLB_FLUSH_GUEST, vcpu);
kvm_mmu_reset_context(vcpu);
+ }
/*
* Intel's SDM states that all TLB entries are flushed on INIT. AMD's
@@ -11519,6 +11654,7 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type)
raw_spin_unlock_irqrestore(&kvm->arch.tsc_write_lock, flags);
kvm->arch.guest_can_read_msr_platform_info = true;
+ kvm->arch.enable_pmu = enable_pmu;
#if IS_ENABLED(CONFIG_HYPERV)
spin_lock_init(&kvm->arch.hv_root_tdp_lock);
@@ -11571,8 +11707,6 @@ void kvm_arch_sync_events(struct kvm *kvm)
kvm_free_pit(kvm);
}
-#define ERR_PTR_USR(e) ((void __user *)ERR_PTR(e))
-
/**
* __x86_set_memory_region: Setup KVM internal memory slot
*
@@ -11718,7 +11852,7 @@ int memslot_rmap_alloc(struct kvm_memory_slot *slot, unsigned long npages)
if (slot->arch.rmap[i])
continue;
- slot->arch.rmap[i] = kvcalloc(lpages, sz, GFP_KERNEL_ACCOUNT);
+ slot->arch.rmap[i] = __vcalloc(lpages, sz, GFP_KERNEL_ACCOUNT);
if (!slot->arch.rmap[i]) {
memslot_rmap_free(slot);
return -ENOMEM;
@@ -11755,7 +11889,7 @@ static int kvm_alloc_memslot_metadata(struct kvm *kvm,
lpages = __kvm_mmu_slot_lpages(slot, npages, level);
- linfo = kvcalloc(lpages, sizeof(*linfo), GFP_KERNEL_ACCOUNT);
+ linfo = __vcalloc(lpages, sizeof(*linfo), GFP_KERNEL_ACCOUNT);
if (!linfo)
goto out_free;
@@ -11905,6 +12039,9 @@ static void kvm_mmu_slot_apply_flags(struct kvm *kvm,
if (kvm_dirty_log_manual_protect_and_init_set(kvm))
return;
+ if (READ_ONCE(eager_page_split))
+ kvm_mmu_slot_try_split_huge_pages(kvm, new, PG_LEVEL_4K);
+
if (kvm_x86_ops.cpu_dirty_log_size) {
kvm_mmu_slot_leaf_clear_dirty(kvm, new);
kvm_mmu_slot_remove_write_access(kvm, new, PG_LEVEL_2M);
@@ -11949,8 +12086,7 @@ void kvm_arch_flush_shadow_memslot(struct kvm *kvm,
static inline bool kvm_guest_apic_has_interrupt(struct kvm_vcpu *vcpu)
{
return (is_guest_mode(vcpu) &&
- kvm_x86_ops.guest_apic_has_interrupt &&
- static_call(kvm_x86_guest_apic_has_interrupt)(vcpu));
+ static_call(kvm_x86_guest_apic_has_interrupt)(vcpu));
}
static inline bool kvm_vcpu_has_events(struct kvm_vcpu *vcpu)
@@ -12203,14 +12339,28 @@ static inline bool apf_pageready_slot_free(struct kvm_vcpu *vcpu)
static bool kvm_can_deliver_async_pf(struct kvm_vcpu *vcpu)
{
- if (!vcpu->arch.apf.delivery_as_pf_vmexit && is_guest_mode(vcpu))
+
+ if (!kvm_pv_async_pf_enabled(vcpu))
return false;
- if (!kvm_pv_async_pf_enabled(vcpu) ||
- (vcpu->arch.apf.send_user_only && static_call(kvm_x86_get_cpl)(vcpu) == 0))
+ if (vcpu->arch.apf.send_user_only &&
+ static_call(kvm_x86_get_cpl)(vcpu) == 0)
return false;
- return true;
+ if (is_guest_mode(vcpu)) {
+ /*
+ * L1 needs to opt into the special #PF vmexits that are
+ * used to deliver async page faults.
+ */
+ return vcpu->arch.apf.delivery_as_pf_vmexit;
+ } else {
+ /*
+ * Play it safe in case the guest temporarily disables paging.
+ * The real mode IDT in particular is unlikely to have a #PF
+ * exception setup.
+ */
+ return is_paging(vcpu);
+ }
}
bool kvm_can_do_async_pf(struct kvm_vcpu *vcpu)
@@ -12305,7 +12455,7 @@ bool kvm_arch_can_dequeue_async_page_present(struct kvm_vcpu *vcpu)
void kvm_arch_start_assignment(struct kvm *kvm)
{
if (atomic_inc_return(&kvm->arch.assigned_device_count) == 1)
- static_call_cond(kvm_x86_start_assignment)(kvm);
+ static_call_cond(kvm_x86_pi_start_assignment)(kvm);
}
EXPORT_SYMBOL_GPL(kvm_arch_start_assignment);
@@ -12353,7 +12503,7 @@ int kvm_arch_irq_bypass_add_producer(struct irq_bypass_consumer *cons,
irqfd->producer = prod;
kvm_arch_start_assignment(irqfd->kvm);
- ret = static_call(kvm_x86_update_pi_irte)(irqfd->kvm,
+ ret = static_call(kvm_x86_pi_update_irte)(irqfd->kvm,
prod->irq, irqfd->gsi, 1);
if (ret)
@@ -12378,7 +12528,7 @@ void kvm_arch_irq_bypass_del_producer(struct irq_bypass_consumer *cons,
* when the irq is masked/disabled or the consumer side (KVM
* int this case doesn't want to receive the interrupts.
*/
- ret = static_call(kvm_x86_update_pi_irte)(irqfd->kvm, prod->irq, irqfd->gsi, 0);
+ ret = static_call(kvm_x86_pi_update_irte)(irqfd->kvm, prod->irq, irqfd->gsi, 0);
if (ret)
printk(KERN_INFO "irq bypass consumer (token %p) unregistration"
" fails: %d\n", irqfd->consumer.token, ret);
@@ -12389,7 +12539,7 @@ void kvm_arch_irq_bypass_del_producer(struct irq_bypass_consumer *cons,
int kvm_arch_update_irqfd_routing(struct kvm *kvm, unsigned int host_irq,
uint32_t guest_irq, bool set)
{
- return static_call(kvm_x86_update_pi_irte)(kvm, host_irq, guest_irq, set);
+ return static_call(kvm_x86_pi_update_irte)(kvm, host_irq, guest_irq, set);
}
bool kvm_arch_irqfd_route_changed(struct kvm_kernel_irq_routing_entry *old,
diff --git a/arch/x86/kvm/x86.h b/arch/x86/kvm/x86.h
index 635b75f9e145..588792f00334 100644
--- a/arch/x86/kvm/x86.h
+++ b/arch/x86/kvm/x86.h
@@ -10,51 +10,6 @@
void kvm_spurious_fault(void);
-static __always_inline void kvm_guest_enter_irqoff(void)
-{
- /*
- * VMENTER enables interrupts (host state), but the kernel state is
- * interrupts disabled when this is invoked. Also tell RCU about
- * it. This is the same logic as for exit_to_user_mode().
- *
- * This ensures that e.g. latency analysis on the host observes
- * guest mode as interrupt enabled.
- *
- * guest_enter_irqoff() informs context tracking about the
- * transition to guest mode and if enabled adjusts RCU state
- * accordingly.
- */
- instrumentation_begin();
- trace_hardirqs_on_prepare();
- lockdep_hardirqs_on_prepare(CALLER_ADDR0);
- instrumentation_end();
-
- guest_enter_irqoff();
- lockdep_hardirqs_on(CALLER_ADDR0);
-}
-
-static __always_inline void kvm_guest_exit_irqoff(void)
-{
- /*
- * VMEXIT disables interrupts (host state), but tracing and lockdep
- * have them in state 'on' as recorded before entering guest mode.
- * Same as enter_from_user_mode().
- *
- * context_tracking_guest_exit() restores host context and reinstates
- * RCU if enabled and required.
- *
- * This needs to be done immediately after VM-Exit, before any code
- * that might contain tracepoints or call out to the greater world,
- * e.g. before x86_spec_ctrl_restore_host().
- */
- lockdep_hardirqs_off(CALLER_ADDR0);
- context_tracking_guest_exit();
-
- instrumentation_begin();
- trace_hardirqs_off_finish();
- instrumentation_end();
-}
-
#define KVM_NESTED_VMENTER_CONSISTENCY_CHECK(consistency_check) \
({ \
bool failed = (consistency_check); \
@@ -211,14 +166,9 @@ static inline u8 vcpu_virt_addr_bits(struct kvm_vcpu *vcpu)
return kvm_read_cr4_bits(vcpu, X86_CR4_LA57) ? 57 : 48;
}
-static inline u64 get_canonical(u64 la, u8 vaddr_bits)
-{
- return ((int64_t)la << (64 - vaddr_bits)) >> (64 - vaddr_bits);
-}
-
static inline bool is_noncanonical_address(u64 la, struct kvm_vcpu *vcpu)
{
- return get_canonical(la, vcpu_virt_addr_bits(vcpu)) != la;
+ return !__is_canonical_address(la, vcpu_virt_addr_bits(vcpu));
}
static inline void vcpu_cache_mmio_info(struct kvm_vcpu *vcpu,
@@ -352,6 +302,8 @@ extern int pi_inject_timer;
extern bool report_ignored_msrs;
+extern bool eager_page_split;
+
static inline u64 nsec_to_cycles(struct kvm_vcpu *vcpu, u64 nsec)
{
return pvclock_scale_delta(nsec, vcpu->arch.virtual_tsc_mult,
diff --git a/arch/x86/kvm/xen.c b/arch/x86/kvm/xen.c
index 0e3f7d6e9fd7..4aa0f2b31665 100644
--- a/arch/x86/kvm/xen.c
+++ b/arch/x86/kvm/xen.c
@@ -133,32 +133,57 @@ static void kvm_xen_update_runstate(struct kvm_vcpu *v, int state)
void kvm_xen_update_runstate_guest(struct kvm_vcpu *v, int state)
{
struct kvm_vcpu_xen *vx = &v->arch.xen;
+ struct gfn_to_hva_cache *ghc = &vx->runstate_cache;
+ struct kvm_memslots *slots = kvm_memslots(v->kvm);
+ bool atomic = (state == RUNSTATE_runnable);
uint64_t state_entry_time;
- unsigned int offset;
+ int __user *user_state;
+ uint64_t __user *user_times;
kvm_xen_update_runstate(v, state);
if (!vx->runstate_set)
return;
- BUILD_BUG_ON(sizeof(struct compat_vcpu_runstate_info) != 0x2c);
+ if (unlikely(slots->generation != ghc->generation || kvm_is_error_hva(ghc->hva)) &&
+ kvm_gfn_to_hva_cache_init(v->kvm, ghc, ghc->gpa, ghc->len))
+ return;
+
+ /* We made sure it fits in a single page */
+ BUG_ON(!ghc->memslot);
+
+ if (atomic)
+ pagefault_disable();
- offset = offsetof(struct compat_vcpu_runstate_info, state_entry_time);
-#ifdef CONFIG_X86_64
/*
- * The only difference is alignment of uint64_t in 32-bit.
- * So the first field 'state' is accessed directly using
- * offsetof() (where its offset happens to be zero), while the
- * remaining fields which are all uint64_t, start at 'offset'
- * which we tweak here by adding 4.
+ * The only difference between 32-bit and 64-bit versions of the
+ * runstate struct us the alignment of uint64_t in 32-bit, which
+ * means that the 64-bit version has an additional 4 bytes of
+ * padding after the first field 'state'.
+ *
+ * So we use 'int __user *user_state' to point to the state field,
+ * and 'uint64_t __user *user_times' for runstate_entry_time. So
+ * the actual array of time[] in each state starts at user_times[1].
*/
+ BUILD_BUG_ON(offsetof(struct vcpu_runstate_info, state) != 0);
+ BUILD_BUG_ON(offsetof(struct compat_vcpu_runstate_info, state) != 0);
+ user_state = (int __user *)ghc->hva;
+
+ BUILD_BUG_ON(sizeof(struct compat_vcpu_runstate_info) != 0x2c);
+
+ user_times = (uint64_t __user *)(ghc->hva +
+ offsetof(struct compat_vcpu_runstate_info,
+ state_entry_time));
+#ifdef CONFIG_X86_64
BUILD_BUG_ON(offsetof(struct vcpu_runstate_info, state_entry_time) !=
offsetof(struct compat_vcpu_runstate_info, state_entry_time) + 4);
BUILD_BUG_ON(offsetof(struct vcpu_runstate_info, time) !=
offsetof(struct compat_vcpu_runstate_info, time) + 4);
if (v->kvm->arch.xen.long_mode)
- offset = offsetof(struct vcpu_runstate_info, state_entry_time);
+ user_times = (uint64_t __user *)(ghc->hva +
+ offsetof(struct vcpu_runstate_info,
+ state_entry_time));
#endif
/*
* First write the updated state_entry_time at the appropriate
@@ -172,10 +197,8 @@ void kvm_xen_update_runstate_guest(struct kvm_vcpu *v, int state)
BUILD_BUG_ON(sizeof_field(struct compat_vcpu_runstate_info, state_entry_time) !=
sizeof(state_entry_time));
- if (kvm_write_guest_offset_cached(v->kvm, &v->arch.xen.runstate_cache,
- &state_entry_time, offset,
- sizeof(state_entry_time)))
- return;
+ if (__put_user(state_entry_time, user_times))
+ goto out;
smp_wmb();
/*
@@ -189,11 +212,8 @@ void kvm_xen_update_runstate_guest(struct kvm_vcpu *v, int state)
BUILD_BUG_ON(sizeof_field(struct compat_vcpu_runstate_info, state) !=
sizeof(vx->current_runstate));
- if (kvm_write_guest_offset_cached(v->kvm, &v->arch.xen.runstate_cache,
- &vx->current_runstate,
- offsetof(struct vcpu_runstate_info, state),
- sizeof(vx->current_runstate)))
- return;
+ if (__put_user(vx->current_runstate, user_state))
+ goto out;
/*
* Write the actual runstate times immediately after the
@@ -208,24 +228,23 @@ void kvm_xen_update_runstate_guest(struct kvm_vcpu *v, int state)
BUILD_BUG_ON(sizeof_field(struct vcpu_runstate_info, time) !=
sizeof(vx->runstate_times));
- if (kvm_write_guest_offset_cached(v->kvm, &v->arch.xen.runstate_cache,
- &vx->runstate_times[0],
- offset + sizeof(u64),
- sizeof(vx->runstate_times)))
- return;
-
+ if (__copy_to_user(user_times + 1, vx->runstate_times, sizeof(vx->runstate_times)))
+ goto out;
smp_wmb();
/*
* Finally, clear the XEN_RUNSTATE_UPDATE bit in the guest's
* runstate_entry_time field.
*/
-
state_entry_time &= ~XEN_RUNSTATE_UPDATE;
- if (kvm_write_guest_offset_cached(v->kvm, &v->arch.xen.runstate_cache,
- &state_entry_time, offset,
- sizeof(state_entry_time)))
- return;
+ __put_user(state_entry_time, user_times);
+ smp_wmb();
+
+ out:
+ mark_page_dirty_in_slot(v->kvm, ghc->memslot, ghc->gpa >> PAGE_SHIFT);
+
+ if (atomic)
+ pagefault_enable();
}
int __kvm_xen_has_interrupt(struct kvm_vcpu *v)
@@ -316,10 +335,7 @@ int __kvm_xen_has_interrupt(struct kvm_vcpu *v)
"\tnotq %0\n"
"\t" LOCK_PREFIX "andq %0, %2\n"
"2:\n"
- "\t.section .fixup,\"ax\"\n"
- "3:\tjmp\t2b\n"
- "\t.previous\n"
- _ASM_EXTABLE_UA(1b, 3b)
+ _ASM_EXTABLE_UA(1b, 2b)
: "=r" (evtchn_pending_sel),
"+m" (vi->evtchn_pending_sel),
"+m" (v->arch.xen.evtchn_pending_sel)
@@ -335,10 +351,7 @@ int __kvm_xen_has_interrupt(struct kvm_vcpu *v)
"\tnotl %0\n"
"\t" LOCK_PREFIX "andl %0, %2\n"
"2:\n"
- "\t.section .fixup,\"ax\"\n"
- "3:\tjmp\t2b\n"
- "\t.previous\n"
- _ASM_EXTABLE_UA(1b, 3b)
+ _ASM_EXTABLE_UA(1b, 2b)
: "=r" (evtchn_pending_sel32),
"+m" (vi->evtchn_pending_sel),
"+m" (v->arch.xen.evtchn_pending_sel)
@@ -449,6 +462,12 @@ int kvm_xen_vcpu_set_attr(struct kvm_vcpu *vcpu, struct kvm_xen_vcpu_attr *data)
break;
}
+ /* It must fit within a single page */
+ if ((data->u.gpa & ~PAGE_MASK) + sizeof(struct vcpu_info) > PAGE_SIZE) {
+ r = -EINVAL;
+ break;
+ }
+
r = kvm_gfn_to_hva_cache_init(vcpu->kvm,
&vcpu->arch.xen.vcpu_info_cache,
data->u.gpa,
@@ -466,6 +485,12 @@ int kvm_xen_vcpu_set_attr(struct kvm_vcpu *vcpu, struct kvm_xen_vcpu_attr *data)
break;
}
+ /* It must fit within a single page */
+ if ((data->u.gpa & ~PAGE_MASK) + sizeof(struct pvclock_vcpu_time_info) > PAGE_SIZE) {
+ r = -EINVAL;
+ break;
+ }
+
r = kvm_gfn_to_hva_cache_init(vcpu->kvm,
&vcpu->arch.xen.vcpu_time_info_cache,
data->u.gpa,
@@ -487,6 +512,12 @@ int kvm_xen_vcpu_set_attr(struct kvm_vcpu *vcpu, struct kvm_xen_vcpu_attr *data)
break;
}
+ /* It must fit within a single page */
+ if ((data->u.gpa & ~PAGE_MASK) + sizeof(struct vcpu_runstate_info) > PAGE_SIZE) {
+ r = -EINVAL;
+ break;
+ }
+
r = kvm_gfn_to_hva_cache_init(vcpu->kvm,
&vcpu->arch.xen.runstate_cache,
data->u.gpa,
@@ -701,7 +732,7 @@ int kvm_xen_write_hypercall_page(struct kvm_vcpu *vcpu, u64 data)
instructions[0] = 0xb8;
/* vmcall / vmmcall */
- kvm_x86_ops.patch_hypercall(vcpu, instructions + 5);
+ static_call(kvm_x86_patch_hypercall)(vcpu, instructions + 5);
/* ret */
instructions[8] = 0xc3;
@@ -836,7 +867,7 @@ int kvm_xen_hypercall(struct kvm_vcpu *vcpu)
vcpu->run->exit_reason = KVM_EXIT_XEN;
vcpu->run->xen.type = KVM_EXIT_XEN_HCALL;
vcpu->run->xen.u.hcall.longmode = longmode;
- vcpu->run->xen.u.hcall.cpl = kvm_x86_ops.get_cpl(vcpu);
+ vcpu->run->xen.u.hcall.cpl = static_call(kvm_x86_get_cpl)(vcpu);
vcpu->run->xen.u.hcall.input = input;
vcpu->run->xen.u.hcall.params[0] = params[0];
vcpu->run->xen.u.hcall.params[1] = params[1];
diff --git a/arch/x86/lib/memcpy_64.S b/arch/x86/lib/memcpy_64.S
index 59cf2343f3d9..d0d7b9bc6cad 100644
--- a/arch/x86/lib/memcpy_64.S
+++ b/arch/x86/lib/memcpy_64.S
@@ -27,8 +27,7 @@
* Output:
* rax original destination
*/
-SYM_FUNC_START_ALIAS(__memcpy)
-SYM_FUNC_START_WEAK(memcpy)
+SYM_FUNC_START(__memcpy)
ALTERNATIVE_2 "jmp memcpy_orig", "", X86_FEATURE_REP_GOOD, \
"jmp memcpy_erms", X86_FEATURE_ERMS
@@ -40,11 +39,12 @@ SYM_FUNC_START_WEAK(memcpy)
movl %edx, %ecx
rep movsb
RET
-SYM_FUNC_END(memcpy)
-SYM_FUNC_END_ALIAS(__memcpy)
-EXPORT_SYMBOL(memcpy)
+SYM_FUNC_END(__memcpy)
EXPORT_SYMBOL(__memcpy)
+SYM_FUNC_ALIAS_WEAK(memcpy, __memcpy)
+EXPORT_SYMBOL(memcpy)
+
/*
* memcpy_erms() - enhanced fast string memcpy. This is faster and
* simpler than memcpy. Use memcpy_erms when possible.
diff --git a/arch/x86/lib/memmove_64.S b/arch/x86/lib/memmove_64.S
index 50ea390df712..d83cba364e31 100644
--- a/arch/x86/lib/memmove_64.S
+++ b/arch/x86/lib/memmove_64.S
@@ -24,7 +24,6 @@
* Output:
* rax: dest
*/
-SYM_FUNC_START_WEAK(memmove)
SYM_FUNC_START(__memmove)
mov %rdi, %rax
@@ -207,6 +206,7 @@ SYM_FUNC_START(__memmove)
13:
RET
SYM_FUNC_END(__memmove)
-SYM_FUNC_END_ALIAS(memmove)
EXPORT_SYMBOL(__memmove)
+
+SYM_FUNC_ALIAS_WEAK(memmove, __memmove)
EXPORT_SYMBOL(memmove)
diff --git a/arch/x86/lib/memset_64.S b/arch/x86/lib/memset_64.S
index d624f2bc42f1..fc9ffd3ff3b2 100644
--- a/arch/x86/lib/memset_64.S
+++ b/arch/x86/lib/memset_64.S
@@ -17,7 +17,6 @@
*
* rax original destination
*/
-SYM_FUNC_START_WEAK(memset)
SYM_FUNC_START(__memset)
/*
* Some CPUs support enhanced REP MOVSB/STOSB feature. It is recommended
@@ -42,10 +41,11 @@ SYM_FUNC_START(__memset)
movq %r9,%rax
RET
SYM_FUNC_END(__memset)
-SYM_FUNC_END_ALIAS(memset)
-EXPORT_SYMBOL(memset)
EXPORT_SYMBOL(__memset)
+SYM_FUNC_ALIAS_WEAK(memset, __memset)
+EXPORT_SYMBOL(memset)
+
/*
* ISO C memset - set a memory block to a byte value. This function uses
* enhanced rep stosb to override the fast string function.
diff --git a/arch/x86/lib/retpoline.S b/arch/x86/lib/retpoline.S
index 89b3fb244e15..afbdda539b80 100644
--- a/arch/x86/lib/retpoline.S
+++ b/arch/x86/lib/retpoline.S
@@ -34,7 +34,7 @@ SYM_INNER_LABEL(__x86_indirect_thunk_\reg, SYM_L_GLOBAL)
ALTERNATIVE_2 __stringify(ANNOTATE_RETPOLINE_SAFE; jmp *%\reg), \
__stringify(RETPOLINE \reg), X86_FEATURE_RETPOLINE, \
- __stringify(lfence; ANNOTATE_RETPOLINE_SAFE; jmp *%\reg; int3), X86_FEATURE_RETPOLINE_AMD
+ __stringify(lfence; ANNOTATE_RETPOLINE_SAFE; jmp *%\reg; int3), X86_FEATURE_RETPOLINE_LFENCE
.endm
diff --git a/arch/x86/lib/usercopy.c b/arch/x86/lib/usercopy.c
index c3e8a62ca561..ad0139d25401 100644
--- a/arch/x86/lib/usercopy.c
+++ b/arch/x86/lib/usercopy.c
@@ -32,7 +32,7 @@ copy_from_user_nmi(void *to, const void __user *from, unsigned long n)
{
unsigned long ret;
- if (__range_not_ok(from, n, TASK_SIZE))
+ if (!__access_ok(from, n))
return n;
if (!nmi_uaccess_okay())
diff --git a/arch/x86/lib/x86-opcode-map.txt b/arch/x86/lib/x86-opcode-map.txt
index ec31f5b60323..d12d1358f96d 100644
--- a/arch/x86/lib/x86-opcode-map.txt
+++ b/arch/x86/lib/x86-opcode-map.txt
@@ -690,7 +690,10 @@ AVXcode: 2
45: vpsrlvd/q Vx,Hx,Wx (66),(v)
46: vpsravd Vx,Hx,Wx (66),(v) | vpsravd/q Vx,Hx,Wx (66),(evo)
47: vpsllvd/q Vx,Hx,Wx (66),(v)
-# Skip 0x48-0x4b
+# Skip 0x48
+49: TILERELEASE (v1),(000),(11B) | LDTILECFG Mtc (v1)(000) | STTILECFG Mtc (66),(v1),(000) | TILEZERO Vt (F2),(v1),(11B)
+# Skip 0x4a
+4b: TILELOADD Vt,Wsm (F2),(v1) | TILELOADDT1 Vt,Wsm (66),(v1) | TILESTORED Wsm,Vt (F3),(v)
4c: vrcp14ps/d Vpd,Wpd (66),(ev)
4d: vrcp14ss/d Vsd,Hpd,Wsd (66),(ev)
4e: vrsqrt14ps/d Vpd,Wpd (66),(ev)
@@ -705,7 +708,10 @@ AVXcode: 2
59: vpbroadcastq Vx,Wx (66),(v) | vbroadcasti32x2 Vx,Wx (66),(evo)
5a: vbroadcasti128 Vqq,Mdq (66),(v) | vbroadcasti32x4/64x2 Vx,Wx (66),(evo)
5b: vbroadcasti32x8/64x4 Vqq,Mdq (66),(ev)
-# Skip 0x5c-0x61
+5c: TDPBF16PS Vt,Wt,Ht (F3),(v1)
+# Skip 0x5d
+5e: TDPBSSD Vt,Wt,Ht (F2),(v1) | TDPBSUD Vt,Wt,Ht (F3),(v1) | TDPBUSD Vt,Wt,Ht (66),(v1) | TDPBUUD Vt,Wt,Ht (v1)
+# Skip 0x5f-0x61
62: vpexpandb/w Vx,Wx (66),(ev)
63: vpcompressb/w Wx,Vx (66),(ev)
64: vpblendmd/q Vx,Hx,Wx (66),(ev)
@@ -822,9 +828,9 @@ AVXcode: 3
05: vpermilpd Vx,Wx,Ib (66),(v)
06: vperm2f128 Vqq,Hqq,Wqq,Ib (66),(v)
07:
-08: vroundps Vx,Wx,Ib (66) | vrndscaleps Vx,Wx,Ib (66),(evo)
+08: vroundps Vx,Wx,Ib (66) | vrndscaleps Vx,Wx,Ib (66),(evo) | vrndscaleph Vx,Wx,Ib (evo)
09: vroundpd Vx,Wx,Ib (66) | vrndscalepd Vx,Wx,Ib (66),(evo)
-0a: vroundss Vss,Wss,Ib (66),(v1) | vrndscaless Vx,Hx,Wx,Ib (66),(evo)
+0a: vroundss Vss,Wss,Ib (66),(v1) | vrndscaless Vx,Hx,Wx,Ib (66),(evo) | vrndscalesh Vx,Hx,Wx,Ib (evo)
0b: vroundsd Vsd,Wsd,Ib (66),(v1) | vrndscalesd Vx,Hx,Wx,Ib (66),(evo)
0c: vblendps Vx,Hx,Wx,Ib (66)
0d: vblendpd Vx,Hx,Wx,Ib (66)
@@ -846,8 +852,8 @@ AVXcode: 3
22: vpinsrd/q Vdq,Hdq,Ey,Ib (66),(v1)
23: vshuff32x4/64x2 Vx,Hx,Wx,Ib (66),(ev)
25: vpternlogd/q Vx,Hx,Wx,Ib (66),(ev)
-26: vgetmantps/d Vx,Wx,Ib (66),(ev)
-27: vgetmantss/d Vx,Hx,Wx,Ib (66),(ev)
+26: vgetmantps/d Vx,Wx,Ib (66),(ev) | vgetmantph Vx,Wx,Ib (ev)
+27: vgetmantss/d Vx,Hx,Wx,Ib (66),(ev) | vgetmantsh Vx,Hx,Wx,Ib (ev)
30: kshiftrb/w Vk,Uk,Ib (66),(v)
31: kshiftrd/q Vk,Uk,Ib (66),(v)
32: kshiftlb/w Vk,Uk,Ib (66),(v)
@@ -871,23 +877,102 @@ AVXcode: 3
51: vrangess/d Vx,Hx,Wx,Ib (66),(ev)
54: vfixupimmps/d Vx,Hx,Wx,Ib (66),(ev)
55: vfixupimmss/d Vx,Hx,Wx,Ib (66),(ev)
-56: vreduceps/d Vx,Wx,Ib (66),(ev)
-57: vreducess/d Vx,Hx,Wx,Ib (66),(ev)
+56: vreduceps/d Vx,Wx,Ib (66),(ev) | vreduceph Vx,Wx,Ib (ev)
+57: vreducess/d Vx,Hx,Wx,Ib (66),(ev) | vreducesh Vx,Hx,Wx,Ib (ev)
60: vpcmpestrm Vdq,Wdq,Ib (66),(v1)
61: vpcmpestri Vdq,Wdq,Ib (66),(v1)
62: vpcmpistrm Vdq,Wdq,Ib (66),(v1)
63: vpcmpistri Vdq,Wdq,Ib (66),(v1)
-66: vfpclassps/d Vk,Wx,Ib (66),(ev)
-67: vfpclassss/d Vk,Wx,Ib (66),(ev)
+66: vfpclassps/d Vk,Wx,Ib (66),(ev) | vfpclassph Vx,Wx,Ib (ev)
+67: vfpclassss/d Vk,Wx,Ib (66),(ev) | vfpclasssh Vx,Wx,Ib (ev)
70: vpshldw Vx,Hx,Wx,Ib (66),(ev)
71: vpshldd/q Vx,Hx,Wx,Ib (66),(ev)
72: vpshrdw Vx,Hx,Wx,Ib (66),(ev)
73: vpshrdd/q Vx,Hx,Wx,Ib (66),(ev)
+c2: vcmpph Vx,Hx,Wx,Ib (ev) | vcmpsh Vx,Hx,Wx,Ib (F3),(ev)
cc: sha1rnds4 Vdq,Wdq,Ib
ce: vgf2p8affineqb Vx,Wx,Ib (66)
cf: vgf2p8affineinvqb Vx,Wx,Ib (66)
df: VAESKEYGEN Vdq,Wdq,Ib (66),(v1)
-f0: RORX Gy,Ey,Ib (F2),(v)
+f0: RORX Gy,Ey,Ib (F2),(v) | HRESET Gv,Ib (F3),(000),(11B)
+EndTable
+
+Table: EVEX map 5
+Referrer:
+AVXcode: 5
+10: vmovsh Vx,Hx,Wx (F3),(ev) | vmovsh Vx,Wx (F3),(ev)
+11: vmovsh Wx,Hx,Vx (F3),(ev) | vmovsh Wx,Vx (F3),(ev)
+1d: vcvtps2phx Vx,Wx (66),(ev) | vcvtss2sh Vx,Hx,Wx (ev)
+2a: vcvtsi2sh Vx,Hx,Wx (F3),(ev)
+2c: vcvttsh2si Vx,Wx (F3),(ev)
+2d: vcvtsh2si Vx,Wx (F3),(ev)
+2e: vucomish Vx,Wx (ev)
+2f: vcomish Vx,Wx (ev)
+51: vsqrtph Vx,Wx (ev) | vsqrtsh Vx,Hx,Wx (F3),(ev)
+58: vaddph Vx,Hx,Wx (ev) | vaddsh Vx,Hx,Wx (F3),(ev)
+59: vmulph Vx,Hx,Wx (ev) | vmulsh Vx,Hx,Wx (F3),(ev)
+5a: vcvtpd2ph Vx,Wx (66),(ev) | vcvtph2pd Vx,Wx (ev) | vcvtsd2sh Vx,Hx,Wx (F2),(ev) | vcvtsh2sd Vx,Hx,Wx (F3),(ev)
+5b: vcvtdq2ph Vx,Wx (ev) | vcvtph2dq Vx,Wx (66),(ev) | vcvtqq2ph Vx,Wx (ev) | vcvttph2dq Vx,Wx (F3),(ev)
+5c: vsubph Vx,Hx,Wx (ev) | vsubsh Vx,Hx,Wx (F3),(ev)
+5d: vminph Vx,Hx,Wx (ev) | vminsh Vx,Hx,Wx (F3),(ev)
+5e: vdivph Vx,Hx,Wx (ev) | vdivsh Vx,Hx,Wx (F3),(ev)
+5f: vmaxph Vx,Hx,Wx (ev) | vmaxsh Vx,Hx,Wx (F3),(ev)
+6e: vmovw Vx,Wx (66),(ev)
+78: vcvttph2udq Vx,Wx (ev) | vcvttph2uqq Vx,Wx (66),(ev) | vcvttsh2usi Vx,Wx (F3),(ev)
+79: vcvtph2udq Vx,Wx (ev) | vcvtph2uqq Vx,Wx (66),(ev) | vcvtsh2usi Vx,Wx (F3),(ev)
+7a: vcvttph2qq Vx,Wx (66),(ev) | vcvtudq2ph Vx,Wx (F2),(ev) | vcvtuqq2ph Vx,Wx (F2),(ev)
+7b: vcvtph2qq Vx,Wx (66),(ev) | vcvtusi2sh Vx,Hx,Wx (F3),(ev)
+7c: vcvttph2uw Vx,Wx (ev) | vcvttph2w Vx,Wx (66),(ev)
+7d: vcvtph2uw Vx,Wx (ev) | vcvtph2w Vx,Wx (66),(ev) | vcvtuw2ph Vx,Wx (F2),(ev) | vcvtw2ph Vx,Wx (F3),(ev)
+7e: vmovw Wx,Vx (66),(ev)
+EndTable
+
+Table: EVEX map 6
+Referrer:
+AVXcode: 6
+13: vcvtph2psx Vx,Wx (66),(ev) | vcvtsh2ss Vx,Hx,Wx (ev)
+2c: vscalefph Vx,Hx,Wx (66),(ev)
+2d: vscalefsh Vx,Hx,Wx (66),(ev)
+42: vgetexpph Vx,Wx (66),(ev)
+43: vgetexpsh Vx,Hx,Wx (66),(ev)
+4c: vrcpph Vx,Wx (66),(ev)
+4d: vrcpsh Vx,Hx,Wx (66),(ev)
+4e: vrsqrtph Vx,Wx (66),(ev)
+4f: vrsqrtsh Vx,Hx,Wx (66),(ev)
+56: vfcmaddcph Vx,Hx,Wx (F2),(ev) | vfmaddcph Vx,Hx,Wx (F3),(ev)
+57: vfcmaddcsh Vx,Hx,Wx (F2),(ev) | vfmaddcsh Vx,Hx,Wx (F3),(ev)
+96: vfmaddsub132ph Vx,Hx,Wx (66),(ev)
+97: vfmsubadd132ph Vx,Hx,Wx (66),(ev)
+98: vfmadd132ph Vx,Hx,Wx (66),(ev)
+99: vfmadd132sh Vx,Hx,Wx (66),(ev)
+9a: vfmsub132ph Vx,Hx,Wx (66),(ev)
+9b: vfmsub132sh Vx,Hx,Wx (66),(ev)
+9c: vfnmadd132ph Vx,Hx,Wx (66),(ev)
+9d: vfnmadd132sh Vx,Hx,Wx (66),(ev)
+9e: vfnmsub132ph Vx,Hx,Wx (66),(ev)
+9f: vfnmsub132sh Vx,Hx,Wx (66),(ev)
+a6: vfmaddsub213ph Vx,Hx,Wx (66),(ev)
+a7: vfmsubadd213ph Vx,Hx,Wx (66),(ev)
+a8: vfmadd213ph Vx,Hx,Wx (66),(ev)
+a9: vfmadd213sh Vx,Hx,Wx (66),(ev)
+aa: vfmsub213ph Vx,Hx,Wx (66),(ev)
+ab: vfmsub213sh Vx,Hx,Wx (66),(ev)
+ac: vfnmadd213ph Vx,Hx,Wx (66),(ev)
+ad: vfnmadd213sh Vx,Hx,Wx (66),(ev)
+ae: vfnmsub213ph Vx,Hx,Wx (66),(ev)
+af: vfnmsub213sh Vx,Hx,Wx (66),(ev)
+b6: vfmaddsub231ph Vx,Hx,Wx (66),(ev)
+b7: vfmsubadd231ph Vx,Hx,Wx (66),(ev)
+b8: vfmadd231ph Vx,Hx,Wx (66),(ev)
+b9: vfmadd231sh Vx,Hx,Wx (66),(ev)
+ba: vfmsub231ph Vx,Hx,Wx (66),(ev)
+bb: vfmsub231sh Vx,Hx,Wx (66),(ev)
+bc: vfnmadd231ph Vx,Hx,Wx (66),(ev)
+bd: vfnmadd231sh Vx,Hx,Wx (66),(ev)
+be: vfnmsub231ph Vx,Hx,Wx (66),(ev)
+bf: vfnmsub231sh Vx,Hx,Wx (66),(ev)
+d6: vfcmulcph Vx,Hx,Wx (F2),(ev) | vfmulcph Vx,Hx,Wx (F3),(ev)
+d7: vfcmulcsh Vx,Hx,Wx (F2),(ev) | vfmulcsh Vx,Hx,Wx (F3),(ev)
EndTable
GrpTable: Grp1
@@ -970,7 +1055,7 @@ GrpTable: Grp7
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
-5: rdpkru (110),(11B) | wrpkru (111),(11B) | SAVEPREVSSP (F3),(010),(11B) | RSTORSSP Mq (F3) | SETSSBSY (F3),(000),(11B)
+5: rdpkru (110),(11B) | wrpkru (111),(11B) | SAVEPREVSSP (F3),(010),(11B) | RSTORSSP Mq (F3) | SETSSBSY (F3),(000),(11B) | CLUI (F3),(110),(11B) | SERIALIZE (000),(11B) | STUI (F3),(111),(11B) | TESTUI (F3)(101)(11B) | UIRET (F3),(100),(11B) | XRESLDTRK (F2),(000),(11B) | XSUSLDTRK (F2),(001),(11B)
6: LMSW Ew
7: INVLPG Mb | SWAPGS (o64),(000),(11B) | RDTSCP (001),(11B)
EndTable
@@ -987,7 +1072,7 @@ GrpTable: Grp9
3: xrstors
4: xsavec
5: xsaves
-6: VMPTRLD Mq | VMCLEAR Mq (66) | VMXON Mq (F3) | RDRAND Rv (11B)
+6: VMPTRLD Mq | VMCLEAR Mq (66) | VMXON Mq (F3) | RDRAND Rv (11B) | SENDUIPI Gq (F3)
7: VMPTRST Mq | VMPTRST Mq (F3) | RDSEED Rv (11B)
EndTable
diff --git a/arch/x86/mm/ioremap.c b/arch/x86/mm/ioremap.c
index 026031b3b782..17a492c27306 100644
--- a/arch/x86/mm/ioremap.c
+++ b/arch/x86/mm/ioremap.c
@@ -615,6 +615,7 @@ static bool memremap_is_efi_data(resource_size_t phys_addr,
static bool memremap_is_setup_data(resource_size_t phys_addr,
unsigned long size)
{
+ struct setup_indirect *indirect;
struct setup_data *data;
u64 paddr, paddr_next;
@@ -627,6 +628,10 @@ static bool memremap_is_setup_data(resource_size_t phys_addr,
data = memremap(paddr, sizeof(*data),
MEMREMAP_WB | MEMREMAP_DEC);
+ if (!data) {
+ pr_warn("failed to memremap setup_data entry\n");
+ return false;
+ }
paddr_next = data->next;
len = data->len;
@@ -636,10 +641,21 @@ static bool memremap_is_setup_data(resource_size_t phys_addr,
return true;
}
- if (data->type == SETUP_INDIRECT &&
- ((struct setup_indirect *)data->data)->type != SETUP_INDIRECT) {
- paddr = ((struct setup_indirect *)data->data)->addr;
- len = ((struct setup_indirect *)data->data)->len;
+ if (data->type == SETUP_INDIRECT) {
+ memunmap(data);
+ data = memremap(paddr, sizeof(*data) + len,
+ MEMREMAP_WB | MEMREMAP_DEC);
+ if (!data) {
+ pr_warn("failed to memremap indirect setup_data\n");
+ return false;
+ }
+
+ indirect = (struct setup_indirect *)data->data;
+
+ if (indirect->type != SETUP_INDIRECT) {
+ paddr = indirect->addr;
+ len = indirect->len;
+ }
}
memunmap(data);
@@ -660,22 +676,51 @@ static bool memremap_is_setup_data(resource_size_t phys_addr,
static bool __init early_memremap_is_setup_data(resource_size_t phys_addr,
unsigned long size)
{
+ struct setup_indirect *indirect;
struct setup_data *data;
u64 paddr, paddr_next;
paddr = boot_params.hdr.setup_data;
while (paddr) {
- unsigned int len;
+ unsigned int len, size;
if (phys_addr == paddr)
return true;
data = early_memremap_decrypted(paddr, sizeof(*data));
+ if (!data) {
+ pr_warn("failed to early memremap setup_data entry\n");
+ return false;
+ }
+
+ size = sizeof(*data);
paddr_next = data->next;
len = data->len;
- early_memunmap(data, sizeof(*data));
+ if ((phys_addr > paddr) && (phys_addr < (paddr + len))) {
+ early_memunmap(data, sizeof(*data));
+ return true;
+ }
+
+ if (data->type == SETUP_INDIRECT) {
+ size += len;
+ early_memunmap(data, sizeof(*data));
+ data = early_memremap_decrypted(paddr, size);
+ if (!data) {
+ pr_warn("failed to early memremap indirect setup_data\n");
+ return false;
+ }
+
+ indirect = (struct setup_indirect *)data->data;
+
+ if (indirect->type != SETUP_INDIRECT) {
+ paddr = indirect->addr;
+ len = indirect->len;
+ }
+ }
+
+ early_memunmap(data, size);
if ((phys_addr > paddr) && (phys_addr < (paddr + len)))
return true;
diff --git a/arch/x86/mm/maccess.c b/arch/x86/mm/maccess.c
index 92ec176a7293..5a53c2cc169c 100644
--- a/arch/x86/mm/maccess.c
+++ b/arch/x86/mm/maccess.c
@@ -4,11 +4,6 @@
#include <linux/kernel.h>
#ifdef CONFIG_X86_64
-static __always_inline u64 canonical_address(u64 vaddr, u8 vaddr_bits)
-{
- return ((s64)vaddr << (64 - vaddr_bits)) >> (64 - vaddr_bits);
-}
-
bool copy_from_kernel_nofault_allowed(const void *unsafe_src, size_t size)
{
unsigned long vaddr = (unsigned long)unsafe_src;
@@ -19,7 +14,7 @@ bool copy_from_kernel_nofault_allowed(const void *unsafe_src, size_t size)
* we also need to include the userspace guard page.
*/
return vaddr >= TASK_SIZE_MAX + PAGE_SIZE &&
- canonical_address(vaddr, boot_cpu_data.x86_virt_bits) == vaddr;
+ __is_canonical_address(vaddr, boot_cpu_data.x86_virt_bits);
}
#else
bool copy_from_kernel_nofault_allowed(const void *unsafe_src, size_t size)
diff --git a/arch/x86/mm/mem_encrypt_amd.c b/arch/x86/mm/mem_encrypt_amd.c
index 2b2d018ea345..6169053c2854 100644
--- a/arch/x86/mm/mem_encrypt_amd.c
+++ b/arch/x86/mm/mem_encrypt_amd.c
@@ -177,25 +177,6 @@ void __init sme_map_bootdata(char *real_mode_data)
__sme_early_map_unmap_mem(__va(cmdline_paddr), COMMAND_LINE_SIZE, true);
}
-void __init sme_early_init(void)
-{
- unsigned int i;
-
- if (!sme_me_mask)
- return;
-
- early_pmd_flags = __sme_set(early_pmd_flags);
-
- __supported_pte_mask = __sme_set(__supported_pte_mask);
-
- /* Update the protection map with memory encryption mask */
- for (i = 0; i < ARRAY_SIZE(protection_map); i++)
- protection_map[i] = pgprot_encrypted(protection_map[i]);
-
- if (cc_platform_has(CC_ATTR_GUEST_MEM_ENCRYPT))
- swiotlb_force = SWIOTLB_FORCE;
-}
-
void __init sev_setup_arch(void)
{
phys_addr_t total_mem = memblock_phys_mem_size();
@@ -256,7 +237,17 @@ static unsigned long pg_level_to_pfn(int level, pte_t *kpte, pgprot_t *ret_prot)
return pfn;
}
-void notify_range_enc_status_changed(unsigned long vaddr, int npages, bool enc)
+static bool amd_enc_tlb_flush_required(bool enc)
+{
+ return true;
+}
+
+static bool amd_enc_cache_flush_required(void)
+{
+ return !cpu_feature_enabled(X86_FEATURE_SME_COHERENT);
+}
+
+static void enc_dec_hypercall(unsigned long vaddr, int npages, bool enc)
{
#ifdef CONFIG_PARAVIRT
unsigned long sz = npages << PAGE_SHIFT;
@@ -287,6 +278,19 @@ void notify_range_enc_status_changed(unsigned long vaddr, int npages, bool enc)
#endif
}
+static void amd_enc_status_change_prepare(unsigned long vaddr, int npages, bool enc)
+{
+}
+
+/* Return true unconditionally: return value doesn't matter for the SEV side */
+static bool amd_enc_status_change_finish(unsigned long vaddr, int npages, bool enc)
+{
+ if (!cc_platform_has(CC_ATTR_HOST_MEM_ENCRYPT))
+ enc_dec_hypercall(vaddr, npages, enc);
+
+ return true;
+}
+
static void __init __set_clr_pte_enc(pte_t *kpte, int level, bool enc)
{
pgprot_t old_prot, new_prot;
@@ -392,7 +396,7 @@ static int __init early_set_memory_enc_dec(unsigned long vaddr,
ret = 0;
- notify_range_enc_status_changed(start, PAGE_ALIGN(size) >> PAGE_SHIFT, enc);
+ early_set_mem_enc_dec_hypercall(start, PAGE_ALIGN(size) >> PAGE_SHIFT, enc);
out:
__flush_tlb_all();
return ret;
@@ -410,7 +414,31 @@ int __init early_set_memory_encrypted(unsigned long vaddr, unsigned long size)
void __init early_set_mem_enc_dec_hypercall(unsigned long vaddr, int npages, bool enc)
{
- notify_range_enc_status_changed(vaddr, npages, enc);
+ enc_dec_hypercall(vaddr, npages, enc);
+}
+
+void __init sme_early_init(void)
+{
+ unsigned int i;
+
+ if (!sme_me_mask)
+ return;
+
+ early_pmd_flags = __sme_set(early_pmd_flags);
+
+ __supported_pte_mask = __sme_set(__supported_pte_mask);
+
+ /* Update the protection map with memory encryption mask */
+ for (i = 0; i < ARRAY_SIZE(protection_map); i++)
+ protection_map[i] = pgprot_encrypted(protection_map[i]);
+
+ if (cc_platform_has(CC_ATTR_GUEST_MEM_ENCRYPT))
+ swiotlb_force = SWIOTLB_FORCE;
+
+ x86_platform.guest.enc_status_change_prepare = amd_enc_status_change_prepare;
+ x86_platform.guest.enc_status_change_finish = amd_enc_status_change_finish;
+ x86_platform.guest.enc_tlb_flush_required = amd_enc_tlb_flush_required;
+ x86_platform.guest.enc_cache_flush_required = amd_enc_cache_flush_required;
}
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 3f0abb403340..b43bc24d2bb6 100644
--- a/arch/x86/mm/mem_encrypt_identity.c
+++ b/arch/x86/mm/mem_encrypt_identity.c
@@ -44,6 +44,7 @@
#include <asm/setup.h>
#include <asm/sections.h>
#include <asm/cmdline.h>
+#include <asm/coco.h>
#include "mm_internal.h"
@@ -565,8 +566,7 @@ void __init sme_enable(struct boot_params *bp)
} else {
/* SEV state cannot be controlled by a command line option */
sme_me_mask = me_mask;
- physical_mask &= ~sme_me_mask;
- return;
+ goto out;
}
/*
@@ -600,6 +600,10 @@ void __init sme_enable(struct boot_params *bp)
sme_me_mask = 0;
else
sme_me_mask = active_by_default ? me_mask : 0;
-
- physical_mask &= ~sme_me_mask;
+out:
+ if (sme_me_mask) {
+ physical_mask &= ~sme_me_mask;
+ cc_set_vendor(CC_VENDOR_AMD);
+ cc_set_mask(sme_me_mask);
+ }
}
diff --git a/arch/x86/mm/numa.c b/arch/x86/mm/numa.c
index c6b1213086d6..e8b061557887 100644
--- a/arch/x86/mm/numa.c
+++ b/arch/x86/mm/numa.c
@@ -738,17 +738,6 @@ void __init x86_numa_init(void)
numa_init(dummy_numa_init);
}
-static void __init init_memory_less_node(int nid)
-{
- /* Allocate and initialize node data. Memory-less node is now online.*/
- alloc_node_data(nid);
- free_area_init_memoryless_node(nid);
-
- /*
- * All zonelists will be built later in start_kernel() after per cpu
- * areas are initialized.
- */
-}
/*
* A node may exist which has one or more Generic Initiators but no CPUs and no
@@ -766,9 +755,18 @@ void __init init_gi_nodes(void)
{
int nid;
+ /*
+ * Exclude this node from
+ * bringup_nonboot_cpus
+ * cpu_up
+ * __try_online_node
+ * register_one_node
+ * because node_subsys is not initialized yet.
+ * TODO remove dependency on node_online
+ */
for_each_node_state(nid, N_GENERIC_INITIATOR)
if (!node_online(nid))
- init_memory_less_node(nid);
+ node_set_online(nid);
}
/*
@@ -798,8 +796,17 @@ void __init init_cpu_to_node(void)
if (node == NUMA_NO_NODE)
continue;
+ /*
+ * Exclude this node from
+ * bringup_nonboot_cpus
+ * cpu_up
+ * __try_online_node
+ * register_one_node
+ * because node_subsys is not initialized yet.
+ * TODO remove dependency on node_online
+ */
if (!node_online(node))
- init_memory_less_node(node);
+ node_set_online(node);
numa_set_node(cpu, node);
}
diff --git a/arch/x86/mm/pat/set_memory.c b/arch/x86/mm/pat/set_memory.c
index b4072115c8ef..abf5ed76e4b7 100644
--- a/arch/x86/mm/pat/set_memory.c
+++ b/arch/x86/mm/pat/set_memory.c
@@ -1989,6 +1989,7 @@ int set_memory_global(unsigned long addr, int numpages)
*/
static int __set_memory_enc_pgtable(unsigned long addr, int numpages, bool enc)
{
+ pgprot_t empty = __pgprot(0);
struct cpa_data cpa;
int ret;
@@ -1999,18 +2000,20 @@ static int __set_memory_enc_pgtable(unsigned long addr, int numpages, bool enc)
memset(&cpa, 0, sizeof(cpa));
cpa.vaddr = &addr;
cpa.numpages = numpages;
- cpa.mask_set = enc ? __pgprot(_PAGE_ENC) : __pgprot(0);
- cpa.mask_clr = enc ? __pgprot(0) : __pgprot(_PAGE_ENC);
+ cpa.mask_set = enc ? pgprot_encrypted(empty) : pgprot_decrypted(empty);
+ cpa.mask_clr = enc ? pgprot_decrypted(empty) : pgprot_encrypted(empty);
cpa.pgd = init_mm.pgd;
/* Must avoid aliasing mappings in the highmem code */
kmap_flush_unused();
vm_unmap_aliases();
- /*
- * Before changing the encryption attribute, we need to flush caches.
- */
- cpa_flush(&cpa, !this_cpu_has(X86_FEATURE_SME_COHERENT));
+ /* Flush the caches as needed before changing the encryption attribute. */
+ if (x86_platform.guest.enc_tlb_flush_required(enc))
+ cpa_flush(&cpa, x86_platform.guest.enc_cache_flush_required());
+
+ /* Notify hypervisor that we are about to set/clr encryption attribute. */
+ x86_platform.guest.enc_status_change_prepare(addr, numpages, enc);
ret = __change_page_attr_set_clr(&cpa, 1);
@@ -2023,11 +2026,11 @@ static int __set_memory_enc_pgtable(unsigned long addr, int numpages, bool enc)
*/
cpa_flush(&cpa, 0);
- /*
- * Notify hypervisor that a given memory range is mapped encrypted
- * or decrypted.
- */
- notify_range_enc_status_changed(addr, numpages, enc);
+ /* 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;
+ }
return ret;
}
@@ -2121,12 +2124,6 @@ int set_pages_array_wc(struct page **pages, int numpages)
}
EXPORT_SYMBOL(set_pages_array_wc);
-int set_pages_array_wt(struct page **pages, int numpages)
-{
- return _set_pages_array(pages, numpages, _PAGE_CACHE_MODE_WT);
-}
-EXPORT_SYMBOL_GPL(set_pages_array_wt);
-
int set_pages_wb(struct page *page, int numpages)
{
unsigned long addr = (unsigned long)page_address(page);
diff --git a/arch/x86/net/bpf_jit_comp.c b/arch/x86/net/bpf_jit_comp.c
index 2b1e266ff95c..6efbb87f65ed 100644
--- a/arch/x86/net/bpf_jit_comp.c
+++ b/arch/x86/net/bpf_jit_comp.c
@@ -330,8 +330,7 @@ static int emit_jump(u8 **pprog, void *func, void *ip)
}
static int __bpf_arch_text_poke(void *ip, enum bpf_text_poke_type t,
- void *old_addr, void *new_addr,
- const bool text_live)
+ void *old_addr, void *new_addr)
{
const u8 *nop_insn = x86_nops[5];
u8 old_insn[X86_PATCH_SIZE];
@@ -365,10 +364,7 @@ static int __bpf_arch_text_poke(void *ip, enum bpf_text_poke_type t,
goto out;
ret = 1;
if (memcmp(ip, new_insn, X86_PATCH_SIZE)) {
- if (text_live)
- text_poke_bp(ip, new_insn, X86_PATCH_SIZE, NULL);
- else
- memcpy(ip, new_insn, X86_PATCH_SIZE);
+ text_poke_bp(ip, new_insn, X86_PATCH_SIZE, NULL);
ret = 0;
}
out:
@@ -384,7 +380,7 @@ int bpf_arch_text_poke(void *ip, enum bpf_text_poke_type t,
/* BPF poking in modules is not supported */
return -EINVAL;
- return __bpf_arch_text_poke(ip, t, old_addr, new_addr, true);
+ return __bpf_arch_text_poke(ip, t, old_addr, new_addr);
}
#define EMIT_LFENCE() EMIT3(0x0F, 0xAE, 0xE8)
@@ -394,7 +390,7 @@ static void emit_indirect_jump(u8 **pprog, int reg, u8 *ip)
u8 *prog = *pprog;
#ifdef CONFIG_RETPOLINE
- if (cpu_feature_enabled(X86_FEATURE_RETPOLINE_AMD)) {
+ if (cpu_feature_enabled(X86_FEATURE_RETPOLINE_LFENCE)) {
EMIT_LFENCE();
EMIT2(0xFF, 0xE0 + reg);
} else if (cpu_feature_enabled(X86_FEATURE_RETPOLINE)) {
@@ -558,24 +554,15 @@ static void bpf_tail_call_direct_fixup(struct bpf_prog *prog)
mutex_lock(&array->aux->poke_mutex);
target = array->ptrs[poke->tail_call.key];
if (target) {
- /* Plain memcpy is used when image is not live yet
- * and still not locked as read-only. Once poke
- * location is active (poke->tailcall_target_stable),
- * any parallel bpf_arch_text_poke() might occur
- * still on the read-write image until we finally
- * locked it as read-only. Both modifications on
- * the given image are under text_mutex to avoid
- * interference.
- */
ret = __bpf_arch_text_poke(poke->tailcall_target,
BPF_MOD_JUMP, NULL,
(u8 *)target->bpf_func +
- poke->adj_off, false);
+ poke->adj_off);
BUG_ON(ret < 0);
ret = __bpf_arch_text_poke(poke->tailcall_bypass,
BPF_MOD_JUMP,
(u8 *)poke->tailcall_target +
- X86_PATCH_SIZE, NULL, false);
+ X86_PATCH_SIZE, NULL);
BUG_ON(ret < 0);
}
WRITE_ONCE(poke->tailcall_target_stable, true);
@@ -787,7 +774,6 @@ static int emit_atomic(u8 **pprog, u8 atomic_op,
/* emit opcode */
switch (atomic_op) {
case BPF_ADD:
- case BPF_SUB:
case BPF_AND:
case BPF_OR:
case BPF_XOR:
@@ -867,7 +853,7 @@ static void emit_nops(u8 **pprog, int len)
#define INSN_SZ_DIFF (((addrs[i] - addrs[i - 1]) - (prog - temp)))
-static int do_jit(struct bpf_prog *bpf_prog, int *addrs, u8 *image,
+static int do_jit(struct bpf_prog *bpf_prog, int *addrs, u8 *image, u8 *rw_image,
int oldproglen, struct jit_context *ctx, bool jmp_padding)
{
bool tail_call_reachable = bpf_prog->aux->tail_call_reachable;
@@ -894,8 +880,8 @@ static int do_jit(struct bpf_prog *bpf_prog, int *addrs, u8 *image,
push_callee_regs(&prog, callee_regs_used);
ilen = prog - temp;
- if (image)
- memcpy(image + proglen, temp, ilen);
+ if (rw_image)
+ memcpy(rw_image + proglen, temp, ilen);
proglen += ilen;
addrs[0] = proglen;
prog = temp;
@@ -1324,6 +1310,9 @@ st: if (is_imm8(insn->off))
pr_err("extable->insn doesn't fit into 32-bit\n");
return -EFAULT;
}
+ /* switch ex to rw buffer for writes */
+ ex = (void *)rw_image + ((void *)ex - (void *)image);
+
ex->insn = delta;
ex->data = EX_TYPE_BPF;
@@ -1706,7 +1695,7 @@ emit_jmp:
pr_err("bpf_jit: fatal error\n");
return -EFAULT;
}
- memcpy(image + proglen, temp, ilen);
+ memcpy(rw_image + proglen, temp, ilen);
}
proglen += ilen;
addrs[i] = proglen;
@@ -2247,6 +2236,7 @@ int arch_prepare_bpf_dispatcher(void *image, s64 *funcs, int num_funcs)
}
struct x64_jit_data {
+ struct bpf_binary_header *rw_header;
struct bpf_binary_header *header;
int *addrs;
u8 *image;
@@ -2259,6 +2249,7 @@ struct x64_jit_data {
struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog)
{
+ struct bpf_binary_header *rw_header = NULL;
struct bpf_binary_header *header = NULL;
struct bpf_prog *tmp, *orig_prog = prog;
struct x64_jit_data *jit_data;
@@ -2267,6 +2258,7 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog)
bool tmp_blinded = false;
bool extra_pass = false;
bool padding = false;
+ u8 *rw_image = NULL;
u8 *image = NULL;
int *addrs;
int pass;
@@ -2302,6 +2294,8 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog)
oldproglen = jit_data->proglen;
image = jit_data->image;
header = jit_data->header;
+ rw_header = jit_data->rw_header;
+ rw_image = (void *)rw_header + ((void *)image - (void *)header);
extra_pass = true;
padding = true;
goto skip_init_addrs;
@@ -2332,13 +2326,22 @@ skip_init_addrs:
for (pass = 0; pass < MAX_PASSES || image; pass++) {
if (!padding && pass >= PADDING_PASSES)
padding = true;
- proglen = do_jit(prog, addrs, image, oldproglen, &ctx, padding);
+ proglen = do_jit(prog, addrs, image, rw_image, oldproglen, &ctx, padding);
if (proglen <= 0) {
out_image:
image = NULL;
- if (header)
- bpf_jit_binary_free(header);
+ if (header) {
+ bpf_arch_text_copy(&header->size, &rw_header->size,
+ sizeof(rw_header->size));
+ bpf_jit_binary_pack_free(header, rw_header);
+ }
+ /* Fall back to interpreter mode */
prog = orig_prog;
+ if (extra_pass) {
+ prog->bpf_func = NULL;
+ prog->jited = 0;
+ prog->jited_len = 0;
+ }
goto out_addrs;
}
if (image) {
@@ -2361,8 +2364,9 @@ out_image:
sizeof(struct exception_table_entry);
/* allocate module memory for x86 insns and extable */
- header = bpf_jit_binary_alloc(roundup(proglen, align) + extable_size,
- &image, align, jit_fill_hole);
+ header = bpf_jit_binary_pack_alloc(roundup(proglen, align) + extable_size,
+ &image, align, &rw_header, &rw_image,
+ jit_fill_hole);
if (!header) {
prog = orig_prog;
goto out_addrs;
@@ -2378,14 +2382,27 @@ out_image:
if (image) {
if (!prog->is_func || extra_pass) {
+ /*
+ * bpf_jit_binary_pack_finalize fails in two scenarios:
+ * 1) header is not pointing to proper module memory;
+ * 2) the arch doesn't support bpf_arch_text_copy().
+ *
+ * Both cases are serious bugs and justify WARN_ON.
+ */
+ if (WARN_ON(bpf_jit_binary_pack_finalize(prog, header, rw_header))) {
+ /* header has been freed */
+ header = NULL;
+ goto out_image;
+ }
+
bpf_tail_call_direct_fixup(prog);
- bpf_jit_binary_lock_ro(header);
} else {
jit_data->addrs = addrs;
jit_data->ctx = ctx;
jit_data->proglen = proglen;
jit_data->image = image;
jit_data->header = header;
+ jit_data->rw_header = rw_header;
}
prog->bpf_func = (void *)image;
prog->jited = 1;
@@ -2413,3 +2430,10 @@ bool bpf_jit_supports_kfunc_call(void)
{
return true;
}
+
+void *bpf_arch_text_copy(void *dst, void *src, size_t len)
+{
+ if (text_poke_copy(dst, src, len) == NULL)
+ return ERR_PTR(-EINVAL);
+ return dst;
+}
diff --git a/arch/x86/pci/fixup.c b/arch/x86/pci/fixup.c
index 2edd86649468..615a76d70019 100644
--- a/arch/x86/pci/fixup.c
+++ b/arch/x86/pci/fixup.c
@@ -353,8 +353,8 @@ static void pci_fixup_video(struct pci_dev *pdev)
}
}
}
-DECLARE_PCI_FIXUP_CLASS_FINAL(PCI_ANY_ID, PCI_ANY_ID,
- PCI_CLASS_DISPLAY_VGA, 8, pci_fixup_video);
+DECLARE_PCI_FIXUP_CLASS_HEADER(PCI_ANY_ID, PCI_ANY_ID,
+ PCI_CLASS_DISPLAY_VGA, 8, pci_fixup_video);
static const struct dmi_system_id msi_k8t_dmi_table[] = {
diff --git a/arch/x86/um/Kconfig b/arch/x86/um/Kconfig
index 40d6a06e41c8..ead7e5b3a975 100644
--- a/arch/x86/um/Kconfig
+++ b/arch/x86/um/Kconfig
@@ -8,6 +8,7 @@ endmenu
config UML_X86
def_bool y
+ select ARCH_BINFMT_ELF_EXTRA_PHDRS if X86_32
config 64BIT
bool "64-bit kernel" if "$(SUBARCH)" = "x86"
diff --git a/arch/x86/um/user-offsets.c b/arch/x86/um/user-offsets.c
index bae61554abcc..e54a9814ccf1 100644
--- a/arch/x86/um/user-offsets.c
+++ b/arch/x86/um/user-offsets.c
@@ -8,12 +8,11 @@
#define __FRAME_OFFSETS
#include <linux/ptrace.h>
#include <asm/types.h>
+#include <linux/kbuild.h>
-#define DEFINE(sym, val) \
- asm volatile("\n->" #sym " %0 " #val : : "i" (val))
-
-#define DEFINE_LONGS(sym, val) \
- asm volatile("\n->" #sym " %0 " #val : : "i" (val/sizeof(unsigned long)))
+#define DEFINE_LONGS(sym, val) \
+ COMMENT(#val " / sizeof(unsigned long)"); \
+ DEFINE(sym, val / sizeof(unsigned long))
void foo(void)
{
diff --git a/arch/x86/xen/enlighten_hvm.c b/arch/x86/xen/enlighten_hvm.c
index 42300941ec29..517a9d8d8f94 100644
--- a/arch/x86/xen/enlighten_hvm.c
+++ b/arch/x86/xen/enlighten_hvm.c
@@ -9,6 +9,7 @@
#include <xen/events.h>
#include <xen/interface/memory.h>
+#include <asm/apic.h>
#include <asm/cpu.h>
#include <asm/smp.h>
#include <asm/io_apic.h>
@@ -184,8 +185,7 @@ static int xen_cpu_dead_hvm(unsigned int cpu)
if (xen_have_vector_callback && xen_feature(XENFEAT_hvm_safe_pvclock))
xen_teardown_timer(cpu);
-
- return 0;
+ return 0;
}
static bool no_vector_callback __initdata;
@@ -242,15 +242,14 @@ static __init int xen_parse_no_vector_callback(char *arg)
}
early_param("xen_no_vector_callback", xen_parse_no_vector_callback);
-bool __init xen_hvm_need_lapic(void)
+static __init bool xen_x2apic_available(void)
{
- if (xen_pv_domain())
- return false;
- if (!xen_hvm_domain())
- return false;
- if (xen_feature(XENFEAT_hvm_pirqs) && xen_have_vector_callback)
- return false;
- return true;
+ return x2apic_supported();
+}
+
+static bool __init msi_ext_dest_id(void)
+{
+ return cpuid_eax(xen_cpuid_base() + 4) & XEN_HVM_CPUID_EXT_DEST_ID;
}
static __init void xen_hvm_guest_late_init(void)
@@ -312,9 +311,10 @@ struct hypervisor_x86 x86_hyper_xen_hvm __initdata = {
.detect = xen_platform_hvm,
.type = X86_HYPER_XEN_HVM,
.init.init_platform = xen_hvm_guest_init,
- .init.x2apic_available = xen_x2apic_para_available,
+ .init.x2apic_available = xen_x2apic_available,
.init.init_mem_mapping = xen_hvm_init_mem_mapping,
.init.guest_late_init = xen_hvm_guest_late_init,
+ .init.msi_ext_dest_id = msi_ext_dest_id,
.runtime.pin_vcpu = xen_pin_vcpu,
.ignore_nopv = true,
};
diff --git a/arch/x86/xen/enlighten_pv.c b/arch/x86/xen/enlighten_pv.c
index 5004feb16783..d47c3d176ae4 100644
--- a/arch/x86/xen/enlighten_pv.c
+++ b/arch/x86/xen/enlighten_pv.c
@@ -1341,10 +1341,6 @@ asmlinkage __visible void __init xen_start_kernel(void)
xen_acpi_sleep_register();
- /* 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;
-
xen_boot_params_init_edd();
#ifdef CONFIG_ACPI
diff --git a/arch/x86/xen/smp_pv.c b/arch/x86/xen/smp_pv.c
index 6a8f3b53ab83..4a6019238ee7 100644
--- a/arch/x86/xen/smp_pv.c
+++ b/arch/x86/xen/smp_pv.c
@@ -148,28 +148,12 @@ int xen_smp_intr_init_pv(unsigned int cpu)
return rc;
}
-static void __init xen_fill_possible_map(void)
-{
- int i, rc;
-
- if (xen_initial_domain())
- return;
-
- 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);
- }
- }
-}
-
-static void __init xen_filter_cpu_maps(void)
+static void __init _get_smp_config(unsigned int early)
{
int i, rc;
unsigned int subtract = 0;
- if (!xen_initial_domain())
+ if (early)
return;
num_processors = 0;
@@ -210,7 +194,6 @@ static void __init xen_pv_smp_prepare_boot_cpu(void)
* sure the old memory can be recycled. */
make_lowmem_page_readwrite(xen_initial_gdt);
- xen_filter_cpu_maps();
xen_setup_vcpu_info_placement();
/*
@@ -476,5 +459,8 @@ static const struct smp_ops xen_smp_ops __initconst = {
void __init xen_smp_init(void)
{
smp_ops = xen_smp_ops;
- xen_fill_possible_map();
+
+ /* Avoid searching for BIOS MP tables */
+ x86_init.mpparse.find_smp_config = x86_init_noop;
+ x86_init.mpparse.get_smp_config = _get_smp_config;
}
diff --git a/arch/x86/xen/vga.c b/arch/x86/xen/vga.c
index 31b1e3477cb6..14ea32e734d5 100644
--- a/arch/x86/xen/vga.c
+++ b/arch/x86/xen/vga.c
@@ -57,6 +57,14 @@ void __init xen_init_vga(const struct dom0_vga_console_info *info, size_t size)
screen_info->rsvd_size = info->u.vesa_lfb.rsvd_size;
screen_info->rsvd_pos = info->u.vesa_lfb.rsvd_pos;
+ if (size >= offsetof(struct dom0_vga_console_info,
+ u.vesa_lfb.ext_lfb_base)
+ + sizeof(info->u.vesa_lfb.ext_lfb_base)
+ && info->u.vesa_lfb.ext_lfb_base) {
+ screen_info->ext_lfb_base = info->u.vesa_lfb.ext_lfb_base;
+ screen_info->capabilities |= VIDEO_CAPABILITY_64BIT_BASE;
+ }
+
if (info->video_type == XEN_VGATYPE_EFI_LFB) {
screen_info->orig_video_isVGA = VIDEO_TYPE_EFI;
break;
@@ -66,14 +74,6 @@ void __init xen_init_vga(const struct dom0_vga_console_info *info, size_t size)
u.vesa_lfb.mode_attrs)
+ sizeof(info->u.vesa_lfb.mode_attrs))
screen_info->vesa_attributes = info->u.vesa_lfb.mode_attrs;
-
- if (size >= offsetof(struct dom0_vga_console_info,
- u.vesa_lfb.ext_lfb_base)
- + sizeof(info->u.vesa_lfb.ext_lfb_base)
- && info->u.vesa_lfb.ext_lfb_base) {
- screen_info->ext_lfb_base = info->u.vesa_lfb.ext_lfb_base;
- screen_info->capabilities |= VIDEO_CAPABILITY_64BIT_BASE;
- }
break;
}
}
diff --git a/arch/xtensa/Kconfig b/arch/xtensa/Kconfig
index 8ac599aa6d99..95bdbaaa5ae6 100644
--- a/arch/xtensa/Kconfig
+++ b/arch/xtensa/Kconfig
@@ -3,6 +3,7 @@ config XTENSA
def_bool y
select ARCH_32BIT_OFF_T
select ARCH_HAS_BINFMT_FLAT if !MMU
+ select ARCH_HAS_CURRENT_STACK_POINTER
select ARCH_HAS_DMA_PREP_COHERENT if MMU
select ARCH_HAS_SYNC_DMA_FOR_CPU if MMU
select ARCH_HAS_SYNC_DMA_FOR_DEVICE if MMU
@@ -40,7 +41,6 @@ config XTENSA
select IRQ_DOMAIN
select MODULES_USE_ELF_RELA
select PERF_USE_VMALLOC
- select SET_FS
select TRACE_IRQFLAGS_SUPPORT
select VIRT_TO_BUS
help
diff --git a/arch/xtensa/include/asm/asm-uaccess.h b/arch/xtensa/include/asm/asm-uaccess.h
index 7f6cf4151843..7cec869136e3 100644
--- a/arch/xtensa/include/asm/asm-uaccess.h
+++ b/arch/xtensa/include/asm/asm-uaccess.h
@@ -24,76 +24,6 @@
#include <asm/processor.h>
/*
- * These assembly macros mirror the C macros in asm/uaccess.h. They
- * should always have identical functionality. See
- * arch/xtensa/kernel/sys.S for usage.
- */
-
-#define KERNEL_DS 0
-#define USER_DS 1
-
-/*
- * get_fs reads current->thread.current_ds into a register.
- * On Entry:
- * <ad> anything
- * <sp> stack
- * On Exit:
- * <ad> contains current->thread.current_ds
- */
- .macro get_fs ad, sp
- GET_CURRENT(\ad,\sp)
-#if THREAD_CURRENT_DS > 1020
- addi \ad, \ad, TASK_THREAD
- l32i \ad, \ad, THREAD_CURRENT_DS - TASK_THREAD
-#else
- l32i \ad, \ad, THREAD_CURRENT_DS
-#endif
- .endm
-
-/*
- * set_fs sets current->thread.current_ds to some value.
- * On Entry:
- * <at> anything (temp register)
- * <av> value to write
- * <sp> stack
- * On Exit:
- * <at> destroyed (actually, current)
- * <av> preserved, value to write
- */
- .macro set_fs at, av, sp
- GET_CURRENT(\at,\sp)
- s32i \av, \at, THREAD_CURRENT_DS
- .endm
-
-/*
- * kernel_ok determines whether we should bypass addr/size checking.
- * See the equivalent C-macro version below for clarity.
- * On success, kernel_ok branches to a label indicated by parameter
- * <success>. This implies that the macro falls through to the next
- * insruction on an error.
- *
- * Note that while this macro can be used independently, we designed
- * in for optimal use in the access_ok macro below (i.e., we fall
- * through on error).
- *
- * On Entry:
- * <at> anything (temp register)
- * <success> label to branch to on success; implies
- * fall-through macro on error
- * <sp> stack pointer
- * On Exit:
- * <at> destroyed (actually, current->thread.current_ds)
- */
-
-#if ((KERNEL_DS != 0) || (USER_DS == 0))
-# error Assembly macro kernel_ok fails
-#endif
- .macro kernel_ok at, sp, success
- get_fs \at, \sp
- beqz \at, \success
- .endm
-
-/*
* user_ok determines whether the access to user-space memory is allowed.
* See the equivalent C-macro version below for clarity.
*
@@ -147,7 +77,6 @@
* <at> destroyed
*/
.macro access_ok aa, as, at, sp, error
- kernel_ok \at, \sp, .Laccess_ok_\@
user_ok \aa, \as, \at, \error
.Laccess_ok_\@:
.endm
diff --git a/arch/xtensa/include/asm/bootparam.h b/arch/xtensa/include/asm/bootparam.h
index 892aab399ac8..6333bd1eb9d2 100644
--- a/arch/xtensa/include/asm/bootparam.h
+++ b/arch/xtensa/include/asm/bootparam.h
@@ -34,7 +34,7 @@
typedef struct bp_tag {
unsigned short id; /* tag id */
unsigned short size; /* size of this record excluding the structure*/
- unsigned long data[0]; /* data */
+ unsigned long data[]; /* data */
} bp_tag_t;
struct bp_meminfo {
diff --git a/arch/xtensa/include/asm/current.h b/arch/xtensa/include/asm/current.h
index 5d98a7ad4251..08010dbf5e09 100644
--- a/arch/xtensa/include/asm/current.h
+++ b/arch/xtensa/include/asm/current.h
@@ -26,6 +26,8 @@ static inline struct task_struct *get_current(void)
#define current get_current()
+register unsigned long current_stack_pointer __asm__("a1");
+
#else
#define GET_CURRENT(reg,sp) \
diff --git a/arch/xtensa/include/asm/pgtable.h b/arch/xtensa/include/asm/pgtable.h
index bd5aeb795567..8da562f5da73 100644
--- a/arch/xtensa/include/asm/pgtable.h
+++ b/arch/xtensa/include/asm/pgtable.h
@@ -241,6 +241,7 @@ static inline void paging_init(void) { }
* The pmd contains the kernel virtual address of the pte page.
*/
#define pmd_page_vaddr(pmd) ((unsigned long)(pmd_val(pmd) & PAGE_MASK))
+#define pmd_pfn(pmd) (__pa(pmd_val(pmd)) >> PAGE_SHIFT)
#define pmd_page(pmd) virt_to_page(pmd_val(pmd))
/*
diff --git a/arch/xtensa/include/asm/processor.h b/arch/xtensa/include/asm/processor.h
index 37d3e9887fe7..abad7c3df46f 100644
--- a/arch/xtensa/include/asm/processor.h
+++ b/arch/xtensa/include/asm/processor.h
@@ -152,18 +152,12 @@
*/
#define SPILL_SLOT_CALL12(sp, reg) (*(((unsigned long *)(sp)) - 16 + (reg)))
-typedef struct {
- unsigned long seg;
-} mm_segment_t;
-
struct thread_struct {
/* kernel's return address and stack pointer for context switching */
unsigned long ra; /* kernel's a0: return address and window call size */
unsigned long sp; /* kernel's a1: stack pointer */
- mm_segment_t current_ds; /* see uaccess.h for example uses */
-
/* struct xtensa_cpuinfo info; */
unsigned long bad_vaddr; /* last user fault */
@@ -186,7 +180,6 @@ struct thread_struct {
{ \
ra: 0, \
sp: sizeof(init_stack) + (long) &init_stack, \
- current_ds: {0}, \
/*info: {0}, */ \
bad_vaddr: 0, \
bad_uaddr: 0, \
diff --git a/arch/xtensa/include/asm/stacktrace.h b/arch/xtensa/include/asm/stacktrace.h
index fe06e8ed162b..a85e785a6288 100644
--- a/arch/xtensa/include/asm/stacktrace.h
+++ b/arch/xtensa/include/asm/stacktrace.h
@@ -19,14 +19,14 @@ struct stackframe {
static __always_inline unsigned long *stack_pointer(struct task_struct *task)
{
- unsigned long *sp;
+ unsigned long sp;
if (!task || task == current)
- __asm__ __volatile__ ("mov %0, a1\n" : "=a"(sp));
+ sp = current_stack_pointer;
else
- sp = (unsigned long *)task->thread.sp;
+ sp = task->thread.sp;
- return sp;
+ return (unsigned long *)sp;
}
void walk_stackframe(unsigned long *sp,
diff --git a/arch/xtensa/include/asm/thread_info.h b/arch/xtensa/include/asm/thread_info.h
index a312333a9add..f6fcbba1d02f 100644
--- a/arch/xtensa/include/asm/thread_info.h
+++ b/arch/xtensa/include/asm/thread_info.h
@@ -52,8 +52,6 @@ struct thread_info {
__u32 cpu; /* current CPU */
__s32 preempt_count; /* 0 => preemptable,< 0 => BUG*/
- mm_segment_t addr_limit; /* thread address space */
-
unsigned long cpenable;
#if XCHAL_HAVE_EXCLUSIVE
/* result of the most recent exclusive store */
@@ -81,7 +79,6 @@ struct thread_info {
.flags = 0, \
.cpu = 0, \
.preempt_count = INIT_PREEMPT_COUNT, \
- .addr_limit = KERNEL_DS, \
}
/* how to get the thread information struct from C */
diff --git a/arch/xtensa/include/asm/uaccess.h b/arch/xtensa/include/asm/uaccess.h
index 75bd8fbf52ba..56aec6d504fe 100644
--- a/arch/xtensa/include/asm/uaccess.h
+++ b/arch/xtensa/include/asm/uaccess.h
@@ -19,31 +19,7 @@
#include <linux/prefetch.h>
#include <asm/types.h>
#include <asm/extable.h>
-
-/*
- * The fs value determines whether argument validity checking should
- * be performed or not. If get_fs() == USER_DS, checking is
- * performed, with get_fs() == KERNEL_DS, checking is bypassed.
- *
- * For historical reasons (Data Segment Register?), these macros are
- * grossly misnamed.
- */
-
-#define KERNEL_DS ((mm_segment_t) { 0 })
-#define USER_DS ((mm_segment_t) { 1 })
-
-#define get_fs() (current->thread.current_ds)
-#define set_fs(val) (current->thread.current_ds = (val))
-
-#define uaccess_kernel() (get_fs().seg == KERNEL_DS.seg)
-
-#define __kernel_ok (uaccess_kernel())
-#define __user_ok(addr, size) \
- (((size) <= TASK_SIZE)&&((addr) <= TASK_SIZE-(size)))
-#define __access_ok(addr, size) (__kernel_ok || __user_ok((addr), (size)))
-#define access_ok(addr, size) __access_ok((unsigned long)(addr), (size))
-
-#define user_addr_max() (uaccess_kernel() ? ~0UL : TASK_SIZE)
+#include <asm-generic/access_ok.h>
/*
* These are the main single-value transfer routines. They
diff --git a/arch/xtensa/include/uapi/asm/shmbuf.h b/arch/xtensa/include/uapi/asm/shmbuf.h
index 554a57a6a90f..bb8bdddae9b5 100644
--- a/arch/xtensa/include/uapi/asm/shmbuf.h
+++ b/arch/xtensa/include/uapi/asm/shmbuf.h
@@ -20,9 +20,12 @@
#ifndef _XTENSA_SHMBUF_H
#define _XTENSA_SHMBUF_H
+#include <asm/ipcbuf.h>
+#include <asm/posix_types.h>
+
struct shmid64_ds {
struct ipc64_perm shm_perm; /* operation perms */
- size_t shm_segsz; /* size of segment (bytes) */
+ __kernel_size_t shm_segsz; /* size of segment (bytes) */
unsigned long shm_atime; /* last attach time */
unsigned long shm_atime_high;
unsigned long shm_dtime; /* last detach time */
diff --git a/arch/xtensa/include/uapi/asm/signal.h b/arch/xtensa/include/uapi/asm/signal.h
index 79ddabaa4e5d..b8c824dd4b74 100644
--- a/arch/xtensa/include/uapi/asm/signal.h
+++ b/arch/xtensa/include/uapi/asm/signal.h
@@ -103,7 +103,7 @@ struct sigaction {
typedef struct sigaltstack {
void *ss_sp;
int ss_flags;
- size_t ss_size;
+ __kernel_size_t ss_size;
} stack_t;
#endif /* __ASSEMBLY__ */
diff --git a/arch/xtensa/kernel/asm-offsets.c b/arch/xtensa/kernel/asm-offsets.c
index dc5c83cad9be..f1fd1390d069 100644
--- a/arch/xtensa/kernel/asm-offsets.c
+++ b/arch/xtensa/kernel/asm-offsets.c
@@ -87,7 +87,6 @@ int main(void)
OFFSET(TI_STSTUS, thread_info, status);
OFFSET(TI_CPU, thread_info, cpu);
OFFSET(TI_PRE_COUNT, thread_info, preempt_count);
- OFFSET(TI_ADDR_LIMIT, thread_info, addr_limit);
/* struct thread_info (offset from start_struct) */
DEFINE(THREAD_RA, offsetof (struct task_struct, thread.ra));
@@ -108,8 +107,6 @@ int main(void)
#endif
DEFINE(THREAD_XTREGS_USER, offsetof (struct thread_info, xtregs_user));
DEFINE(XTREGS_USER_SIZE, sizeof(xtregs_user_t));
- DEFINE(THREAD_CURRENT_DS, offsetof (struct task_struct, \
- thread.current_ds));
/* struct mm_struct */
DEFINE(MM_USERS, offsetof(struct mm_struct, mm_users));
diff --git a/arch/xtensa/kernel/irq.c b/arch/xtensa/kernel/irq.c
index 15051a8a1539..529fe9245821 100644
--- a/arch/xtensa/kernel/irq.c
+++ b/arch/xtensa/kernel/irq.c
@@ -36,9 +36,8 @@ asmlinkage void do_IRQ(int hwirq, struct pt_regs *regs)
#ifdef CONFIG_DEBUG_STACKOVERFLOW
/* Debugging check for stack overflow: is there less than 1KB free? */
{
- unsigned long sp;
+ unsigned long sp = current_stack_pointer;
- __asm__ __volatile__ ("mov %0, a1\n" : "=a" (sp));
sp &= THREAD_SIZE - 1;
if (unlikely(sp < (sizeof(thread_info) + 1024)))
diff --git a/arch/xtensa/platforms/iss/network.c b/arch/xtensa/platforms/iss/network.c
index 962e5e145209..9fb99d18e3c2 100644
--- a/arch/xtensa/platforms/iss/network.c
+++ b/arch/xtensa/platforms/iss/network.c
@@ -304,7 +304,7 @@ static int iss_net_rx(struct net_device *dev)
lp->stats.rx_bytes += skb->len;
lp->stats.rx_packets++;
- netif_rx_ni(skb);
+ netif_rx(skb);
return pkt_len;
}
kfree_skb(skb);
diff --git a/arch/xtensa/platforms/iss/simdisk.c b/arch/xtensa/platforms/iss/simdisk.c
index 8eb6ad1a3a1d..0f0e0724397f 100644
--- a/arch/xtensa/platforms/iss/simdisk.c
+++ b/arch/xtensa/platforms/iss/simdisk.c
@@ -108,13 +108,13 @@ static void simdisk_submit_bio(struct bio *bio)
sector_t sector = bio->bi_iter.bi_sector;
bio_for_each_segment(bvec, bio, iter) {
- char *buffer = kmap_atomic(bvec.bv_page) + bvec.bv_offset;
+ char *buffer = bvec_kmap_local(&bvec);
unsigned len = bvec.bv_len >> SECTOR_SHIFT;
simdisk_transfer(dev, sector, len, buffer,
bio_data_dir(bio) == WRITE);
sector += len;
- kunmap_atomic(buffer);
+ kunmap_local(buffer);
}
bio_endio(bio);
diff --git a/block/Kconfig b/block/Kconfig
index d5d4197b7ed2..7eb5d6d53b3f 100644
--- a/block/Kconfig
+++ b/block/Kconfig
@@ -26,6 +26,16 @@ menuconfig BLOCK
if BLOCK
+config BLOCK_LEGACY_AUTOLOAD
+ bool "Legacy autoloading support"
+ default y
+ help
+ Enable loading modules and creating block device instances based on
+ accesses through their device special file. This is a historic Linux
+ feature and makes no sense in a udev world where device files are
+ created on demand, but scripts that manually create device nodes and
+ then call losetup might rely on this behavior.
+
config BLK_RQ_ALLOC_TIME
bool
@@ -218,6 +228,9 @@ config BLK_PM
config BLOCK_HOLDER_DEPRECATED
bool
+config BLK_MQ_STACKING
+ bool
+
source "block/Kconfig.iosched"
endif # BLOCK
diff --git a/block/Makefile b/block/Makefile
index f38eaa612929..3950ecbc5c26 100644
--- a/block/Makefile
+++ b/block/Makefile
@@ -36,6 +36,7 @@ obj-$(CONFIG_BLK_DEBUG_FS) += blk-mq-debugfs.o
obj-$(CONFIG_BLK_DEBUG_FS_ZONED)+= blk-mq-debugfs-zoned.o
obj-$(CONFIG_BLK_SED_OPAL) += sed-opal.o
obj-$(CONFIG_BLK_PM) += blk-pm.o
-obj-$(CONFIG_BLK_INLINE_ENCRYPTION) += blk-crypto.o blk-crypto-profile.o
+obj-$(CONFIG_BLK_INLINE_ENCRYPTION) += blk-crypto.o blk-crypto-profile.o \
+ blk-crypto-sysfs.o
obj-$(CONFIG_BLK_INLINE_ENCRYPTION_FALLBACK) += blk-crypto-fallback.o
obj-$(CONFIG_BLOCK_HOLDER_DEPRECATED) += holder.o
diff --git a/block/bdev.c b/block/bdev.c
index 102837a37051..13de871fa816 100644
--- a/block/bdev.c
+++ b/block/bdev.c
@@ -385,7 +385,7 @@ static struct kmem_cache * bdev_cachep __read_mostly;
static struct inode *bdev_alloc_inode(struct super_block *sb)
{
- struct bdev_inode *ei = kmem_cache_alloc(bdev_cachep, GFP_KERNEL);
+ struct bdev_inode *ei = alloc_inode_sb(sb, bdev_cachep, GFP_KERNEL);
if (!ei)
return NULL;
@@ -678,7 +678,7 @@ static int blkdev_get_whole(struct block_device *bdev, fmode_t mode)
if (test_bit(GD_NEED_PART_SCAN, &disk->state))
bdev_disk_changed(disk, false);
bdev->bd_openers++;
- return 0;;
+ return 0;
}
static void blkdev_put_whole(struct block_device *bdev, fmode_t mode)
@@ -733,12 +733,15 @@ struct block_device *blkdev_get_no_open(dev_t dev)
struct inode *inode;
inode = ilookup(blockdev_superblock, dev);
- if (!inode) {
+ if (!inode && IS_ENABLED(CONFIG_BLOCK_LEGACY_AUTOLOAD)) {
blk_request_module(dev);
inode = ilookup(blockdev_superblock, dev);
- if (!inode)
- return NULL;
+ if (inode)
+ pr_warn_ratelimited(
+"block device autoloading is deprecated and will be removed.\n");
}
+ if (!inode)
+ return NULL;
/* switch from the inode reference to a device mode one: */
bdev = &BDEV_I(inode)->bdev;
diff --git a/block/bfq-cgroup.c b/block/bfq-cgroup.c
index 24a5c5329bcd..420eda2589c0 100644
--- a/block/bfq-cgroup.c
+++ b/block/bfq-cgroup.c
@@ -645,8 +645,22 @@ void bfq_bfqq_move(struct bfq_data *bfqd, struct bfq_queue *bfqq,
struct bfq_group *bfqg)
{
struct bfq_entity *entity = &bfqq->entity;
+ struct bfq_group *old_parent = bfqq_group(bfqq);
/*
+ * No point to move bfqq to the same group, which can happen when
+ * root group is offlined
+ */
+ if (old_parent == bfqg)
+ return;
+
+ /*
+ * oom_bfqq is not allowed to move, oom_bfqq will hold ref to root_group
+ * until elevator exit.
+ */
+ if (bfqq == &bfqd->oom_bfqq)
+ return;
+ /*
* Get extra reference to prevent bfqq from being freed in
* next possible expire or deactivate.
*/
@@ -666,7 +680,7 @@ void bfq_bfqq_move(struct bfq_data *bfqd, struct bfq_queue *bfqq,
bfq_deactivate_bfqq(bfqd, bfqq, false, false);
else if (entity->on_st_or_in_serv)
bfq_put_idle_entity(bfq_entity_service_tree(entity), entity);
- bfqg_and_blkg_put(bfqq_group(bfqq));
+ bfqg_and_blkg_put(old_parent);
if (entity->parent &&
entity->parent->last_bfqq_created == bfqq)
diff --git a/block/bfq-iosched.c b/block/bfq-iosched.c
index 0c612a911696..2e0dd68a3cbe 100644
--- a/block/bfq-iosched.c
+++ b/block/bfq-iosched.c
@@ -774,7 +774,7 @@ bfq_pos_tree_add_move(struct bfq_data *bfqd, struct bfq_queue *bfqq)
if (!bfqq->next_rq)
return;
- bfqq->pos_root = &bfq_bfqq_to_bfqg(bfqq)->rq_pos_tree;
+ bfqq->pos_root = &bfqq_group(bfqq)->rq_pos_tree;
__bfqq = bfq_rq_pos_tree_lookup(bfqd, bfqq->pos_root,
blk_rq_pos(bfqq->next_rq), &parent, &p);
if (!__bfqq) {
@@ -2153,7 +2153,7 @@ static void bfq_check_waker(struct bfq_data *bfqd, struct bfq_queue *bfqq,
bfqq->waker_detection_started = now_ns;
bfq_bfqq_name(bfqq->tentative_waker_bfqq, waker_name,
MAX_BFQQ_NAME_LENGTH);
- bfq_log_bfqq(bfqd, bfqq, "set tenative waker %s", waker_name);
+ bfq_log_bfqq(bfqd, bfqq, "set tentative waker %s", waker_name);
} else /* Same tentative waker queue detected again */
bfqq->num_waker_detections++;
@@ -2669,7 +2669,7 @@ static struct bfq_queue *bfqq_find_close(struct bfq_data *bfqd,
struct bfq_queue *bfqq,
sector_t sector)
{
- struct rb_root *root = &bfq_bfqq_to_bfqg(bfqq)->rq_pos_tree;
+ struct rb_root *root = &bfqq_group(bfqq)->rq_pos_tree;
struct rb_node *parent, *node;
struct bfq_queue *__bfqq;
@@ -2782,6 +2782,15 @@ bfq_setup_merge(struct bfq_queue *bfqq, struct bfq_queue *new_bfqq)
* are likely to increase the throughput.
*/
bfqq->new_bfqq = new_bfqq;
+ /*
+ * The above assignment schedules the following redirections:
+ * each time some I/O for bfqq arrives, the process that
+ * generated that I/O is disassociated from bfqq and
+ * associated with new_bfqq. Here we increases new_bfqq->ref
+ * in advance, adding the number of processes that are
+ * expected to be associated with new_bfqq as they happen to
+ * issue I/O.
+ */
new_bfqq->ref += process_refs;
return new_bfqq;
}
@@ -2844,6 +2853,10 @@ bfq_setup_cooperator(struct bfq_data *bfqd, struct bfq_queue *bfqq,
{
struct bfq_queue *in_service_bfqq, *new_bfqq;
+ /* if a merge has already been setup, then proceed with that first */
+ if (bfqq->new_bfqq)
+ return bfqq->new_bfqq;
+
/*
* Check delayed stable merge for rotational or non-queueing
* devs. For this branch to be executed, bfqq must not be
@@ -2945,9 +2958,6 @@ bfq_setup_cooperator(struct bfq_data *bfqd, struct bfq_queue *bfqq,
if (bfq_too_late_for_merging(bfqq))
return NULL;
- if (bfqq->new_bfqq)
- return bfqq->new_bfqq;
-
if (!io_struct || unlikely(bfqq == &bfqd->oom_bfqq))
return NULL;
@@ -5181,7 +5191,7 @@ static struct request *bfq_dispatch_request(struct blk_mq_hw_ctx *hctx)
struct bfq_data *bfqd = hctx->queue->elevator->elevator_data;
struct request *rq;
struct bfq_queue *in_serv_queue;
- bool waiting_rq, idle_timer_disabled;
+ bool waiting_rq, idle_timer_disabled = false;
spin_lock_irq(&bfqd->lock);
@@ -5189,14 +5199,15 @@ static struct request *bfq_dispatch_request(struct blk_mq_hw_ctx *hctx)
waiting_rq = in_serv_queue && bfq_bfqq_wait_request(in_serv_queue);
rq = __bfq_dispatch_request(hctx);
-
- idle_timer_disabled =
- waiting_rq && !bfq_bfqq_wait_request(in_serv_queue);
+ if (in_serv_queue == bfqd->in_service_queue) {
+ idle_timer_disabled =
+ waiting_rq && !bfq_bfqq_wait_request(in_serv_queue);
+ }
spin_unlock_irq(&bfqd->lock);
-
- bfq_update_dispatch_stats(hctx->queue, rq, in_serv_queue,
- idle_timer_disabled);
+ bfq_update_dispatch_stats(hctx->queue, rq,
+ idle_timer_disabled ? in_serv_queue : NULL,
+ idle_timer_disabled);
return rq;
}
@@ -5448,7 +5459,7 @@ static void bfq_check_ioprio_change(struct bfq_io_cq *bic, struct bio *bio)
bfqq = bic_to_bfqq(bic, false);
if (bfqq) {
bfq_release_process_ref(bfqd, bfqq);
- bfqq = bfq_get_queue(bfqd, bio, BLK_RW_ASYNC, bic, true);
+ bfqq = bfq_get_queue(bfqd, bio, false, bic, true);
bic_set_bfqq(bic, bfqq, false);
}
@@ -7018,6 +7029,8 @@ static void bfq_exit_queue(struct elevator_queue *e)
spin_unlock_irq(&bfqd->lock);
#endif
+ wbt_enable_default(bfqd->queue);
+
kfree(bfqd);
}
diff --git a/block/bfq-iosched.h b/block/bfq-iosched.h
index 07288b9da389..3b83e3d1c2e5 100644
--- a/block/bfq-iosched.h
+++ b/block/bfq-iosched.h
@@ -8,7 +8,6 @@
#include <linux/blktrace_api.h>
#include <linux/hrtimer.h>
-#include <linux/blk-cgroup.h>
#include "blk-cgroup-rwstat.h"
@@ -1051,7 +1050,6 @@ extern struct blkcg_policy blkcg_policy_bfq;
for (parent = NULL; entity ; entity = parent)
#endif /* CONFIG_BFQ_GROUP_IOSCHED */
-struct bfq_group *bfq_bfqq_to_bfqg(struct bfq_queue *bfqq);
struct bfq_queue *bfq_entity_to_bfqq(struct bfq_entity *entity);
unsigned int bfq_tot_busy_queues(struct bfq_data *bfqd);
struct bfq_service_tree *bfq_entity_service_tree(struct bfq_entity *entity);
diff --git a/block/bfq-wf2q.c b/block/bfq-wf2q.c
index b74cc0da118e..f8eb340381cf 100644
--- a/block/bfq-wf2q.c
+++ b/block/bfq-wf2q.c
@@ -142,16 +142,6 @@ static bool bfq_update_next_in_service(struct bfq_sched_data *sd,
#ifdef CONFIG_BFQ_GROUP_IOSCHED
-struct bfq_group *bfq_bfqq_to_bfqg(struct bfq_queue *bfqq)
-{
- struct bfq_entity *group_entity = bfqq->entity.parent;
-
- if (!group_entity)
- group_entity = &bfqq->bfqd->root_group->entity;
-
- return container_of(group_entity, struct bfq_group, entity);
-}
-
/*
* Returns true if this budget changes may let next_in_service->parent
* become the next_in_service entity for its parent entity.
@@ -230,11 +220,6 @@ static bool bfq_no_longer_next_in_service(struct bfq_entity *entity)
#else /* CONFIG_BFQ_GROUP_IOSCHED */
-struct bfq_group *bfq_bfqq_to_bfqg(struct bfq_queue *bfqq)
-{
- return bfqq->bfqd->root_group;
-}
-
static bool bfq_update_parent_budget(struct bfq_entity *next_in_service)
{
return false;
@@ -519,7 +504,7 @@ unsigned short bfq_ioprio_to_weight(int ioprio)
static unsigned short bfq_weight_to_ioprio(int weight)
{
return max_t(int, 0,
- IOPRIO_NR_LEVELS * BFQ_WEIGHT_CONVERSION_COEFF - weight);
+ IOPRIO_NR_LEVELS - weight / BFQ_WEIGHT_CONVERSION_COEFF);
}
static void bfq_get_entity(struct bfq_entity *entity)
diff --git a/block/bio-integrity.c b/block/bio-integrity.c
index d25114715459..6996e7bd66e9 100644
--- a/block/bio-integrity.c
+++ b/block/bio-integrity.c
@@ -373,7 +373,7 @@ void bio_integrity_advance(struct bio *bio, unsigned int bytes_done)
struct blk_integrity *bi = blk_get_integrity(bio->bi_bdev->bd_disk);
unsigned bytes = bio_integrity_bytes(bi, bytes_done >> 9);
- bip->bip_iter.bi_sector += bytes_done >> 9;
+ bip->bip_iter.bi_sector += bio_integrity_intervals(bi, bytes_done >> 9);
bvec_iter_advance(bip->bip_vec, &bip->bip_iter, bytes);
}
@@ -420,7 +420,6 @@ int bio_integrity_clone(struct bio *bio, struct bio *bio_src,
return 0;
}
-EXPORT_SYMBOL(bio_integrity_clone);
int bioset_integrity_create(struct bio_set *bs, int pool_size)
{
diff --git a/block/bio.c b/block/bio.c
index 4312a8085396..33979f306e9e 100644
--- a/block/bio.c
+++ b/block/bio.c
@@ -15,7 +15,6 @@
#include <linux/mempool.h>
#include <linux/workqueue.h>
#include <linux/cgroup.h>
-#include <linux/blk-cgroup.h>
#include <linux/highmem.h>
#include <linux/sched/sysctl.h>
#include <linux/blk-crypto.h>
@@ -24,6 +23,7 @@
#include <trace/events/block.h>
#include "blk.h"
#include "blk-rq-qos.h"
+#include "blk-cgroup.h"
struct bio_alloc_cache {
struct bio *free_list;
@@ -249,12 +249,12 @@ static void bio_free(struct bio *bio)
* they must remember to pair any call to bio_init() with bio_uninit()
* when IO has completed, or when the bio is released.
*/
-void bio_init(struct bio *bio, struct bio_vec *table,
- unsigned short max_vecs)
+void bio_init(struct bio *bio, struct block_device *bdev, struct bio_vec *table,
+ unsigned short max_vecs, unsigned int opf)
{
bio->bi_next = NULL;
- bio->bi_bdev = NULL;
- bio->bi_opf = 0;
+ bio->bi_bdev = bdev;
+ bio->bi_opf = opf;
bio->bi_flags = 0;
bio->bi_ioprio = 0;
bio->bi_write_hint = 0;
@@ -268,6 +268,8 @@ void bio_init(struct bio *bio, struct bio_vec *table,
#ifdef CONFIG_BLK_CGROUP
bio->bi_blkg = NULL;
bio->bi_issue.value = 0;
+ if (bdev)
+ bio_associate_blkg(bio);
#ifdef CONFIG_BLK_CGROUP_IOCOST
bio->bi_iocost_cost = 0;
#endif
@@ -293,6 +295,8 @@ EXPORT_SYMBOL(bio_init);
/**
* bio_reset - reinitialize a bio
* @bio: bio to reset
+ * @bdev: block device to use the bio for
+ * @opf: operation and flags for bio
*
* Description:
* After calling bio_reset(), @bio will be in the same state as a freshly
@@ -300,11 +304,15 @@ EXPORT_SYMBOL(bio_init);
* preserved are the ones that are initialized by bio_alloc_bioset(). See
* comment in struct bio.
*/
-void bio_reset(struct bio *bio)
+void bio_reset(struct bio *bio, struct block_device *bdev, unsigned int opf)
{
bio_uninit(bio);
memset(bio, 0, BIO_RESET_BYTES);
atomic_set(&bio->__bi_remaining, 1);
+ bio->bi_bdev = bdev;
+ if (bio->bi_bdev)
+ bio_associate_blkg(bio);
+ bio->bi_opf = opf;
}
EXPORT_SYMBOL(bio_reset);
@@ -344,6 +352,20 @@ void bio_chain(struct bio *bio, struct bio *parent)
}
EXPORT_SYMBOL(bio_chain);
+struct bio *blk_next_bio(struct bio *bio, struct block_device *bdev,
+ unsigned int nr_pages, unsigned int opf, gfp_t gfp)
+{
+ struct bio *new = bio_alloc(bdev, nr_pages, opf, gfp);
+
+ if (bio) {
+ bio_chain(bio, new);
+ submit_bio(bio);
+ }
+
+ return new;
+}
+EXPORT_SYMBOL_GPL(blk_next_bio);
+
static void bio_alloc_rescue(struct work_struct *work)
{
struct bio_set *bs = container_of(work, struct bio_set, rescue_work);
@@ -400,8 +422,10 @@ static void punt_bios_to_rescuer(struct bio_set *bs)
/**
* bio_alloc_bioset - allocate a bio for I/O
+ * @bdev: block device to allocate the bio for (can be %NULL)
+ * @nr_vecs: number of bvecs to pre-allocate
+ * @opf: operation and flags for bio
* @gfp_mask: the GFP_* mask given to the slab allocator
- * @nr_iovecs: number of iovecs to pre-allocate
* @bs: the bio_set to allocate from.
*
* Allocate a bio from the mempools in @bs.
@@ -430,15 +454,16 @@ static void punt_bios_to_rescuer(struct bio_set *bs)
*
* Returns: Pointer to new bio on success, NULL on failure.
*/
-struct bio *bio_alloc_bioset(gfp_t gfp_mask, unsigned short nr_iovecs,
+struct bio *bio_alloc_bioset(struct block_device *bdev, unsigned short nr_vecs,
+ unsigned int opf, gfp_t gfp_mask,
struct bio_set *bs)
{
gfp_t saved_gfp = gfp_mask;
struct bio *bio;
void *p;
- /* should not use nobvec bioset for nr_iovecs > 0 */
- if (WARN_ON_ONCE(!mempool_initialized(&bs->bvec_pool) && nr_iovecs > 0))
+ /* should not use nobvec bioset for nr_vecs > 0 */
+ if (WARN_ON_ONCE(!mempool_initialized(&bs->bvec_pool) && nr_vecs > 0))
return NULL;
/*
@@ -475,23 +500,23 @@ struct bio *bio_alloc_bioset(gfp_t gfp_mask, unsigned short nr_iovecs,
return NULL;
bio = p + bs->front_pad;
- if (nr_iovecs > BIO_INLINE_VECS) {
+ if (nr_vecs > BIO_INLINE_VECS) {
struct bio_vec *bvl = NULL;
- bvl = bvec_alloc(&bs->bvec_pool, &nr_iovecs, gfp_mask);
+ bvl = bvec_alloc(&bs->bvec_pool, &nr_vecs, gfp_mask);
if (!bvl && gfp_mask != saved_gfp) {
punt_bios_to_rescuer(bs);
gfp_mask = saved_gfp;
- bvl = bvec_alloc(&bs->bvec_pool, &nr_iovecs, gfp_mask);
+ bvl = bvec_alloc(&bs->bvec_pool, &nr_vecs, gfp_mask);
}
if (unlikely(!bvl))
goto err_free;
- bio_init(bio, bvl, nr_iovecs);
- } else if (nr_iovecs) {
- bio_init(bio, bio->bi_inline_vecs, BIO_INLINE_VECS);
+ bio_init(bio, bdev, bvl, nr_vecs, opf);
+ } else if (nr_vecs) {
+ bio_init(bio, bdev, bio->bi_inline_vecs, BIO_INLINE_VECS, opf);
} else {
- bio_init(bio, NULL, 0);
+ bio_init(bio, bdev, NULL, 0, opf);
}
bio->bi_pool = bs;
@@ -522,7 +547,8 @@ struct bio *bio_kmalloc(gfp_t gfp_mask, unsigned short nr_iovecs)
bio = kmalloc(struct_size(bio, bi_inline_vecs, nr_iovecs), gfp_mask);
if (unlikely(!bio))
return NULL;
- bio_init(bio, nr_iovecs ? bio->bi_inline_vecs : NULL, nr_iovecs);
+ bio_init(bio, NULL, nr_iovecs ? bio->bi_inline_vecs : NULL, nr_iovecs,
+ 0);
bio->bi_pool = NULL;
return bio;
}
@@ -702,80 +728,84 @@ void bio_put(struct bio *bio)
}
EXPORT_SYMBOL(bio_put);
-/**
- * __bio_clone_fast - clone a bio that shares the original bio's biovec
- * @bio: destination bio
- * @bio_src: bio to clone
- *
- * Clone a &bio. Caller will own the returned bio, but not
- * the actual data it points to. Reference count of returned
- * bio will be one.
- *
- * Caller must ensure that @bio_src is not freed before @bio.
- */
-void __bio_clone_fast(struct bio *bio, struct bio *bio_src)
+static int __bio_clone(struct bio *bio, struct bio *bio_src, gfp_t gfp)
{
- WARN_ON_ONCE(bio->bi_pool && bio->bi_max_vecs);
-
- /*
- * most users will be overriding ->bi_bdev with a new target,
- * so we don't set nor calculate new physical/hw segment counts here
- */
- bio->bi_bdev = bio_src->bi_bdev;
bio_set_flag(bio, BIO_CLONED);
if (bio_flagged(bio_src, BIO_THROTTLED))
bio_set_flag(bio, BIO_THROTTLED);
- if (bio_flagged(bio_src, BIO_REMAPPED))
+ if (bio->bi_bdev == bio_src->bi_bdev &&
+ bio_flagged(bio_src, BIO_REMAPPED))
bio_set_flag(bio, BIO_REMAPPED);
- bio->bi_opf = bio_src->bi_opf;
bio->bi_ioprio = bio_src->bi_ioprio;
bio->bi_write_hint = bio_src->bi_write_hint;
bio->bi_iter = bio_src->bi_iter;
- bio->bi_io_vec = bio_src->bi_io_vec;
bio_clone_blkg_association(bio, bio_src);
blkcg_bio_issue_init(bio);
+
+ if (bio_crypt_clone(bio, bio_src, gfp) < 0)
+ return -ENOMEM;
+ if (bio_integrity(bio_src) &&
+ bio_integrity_clone(bio, bio_src, gfp) < 0)
+ return -ENOMEM;
+ return 0;
}
-EXPORT_SYMBOL(__bio_clone_fast);
/**
- * bio_clone_fast - clone a bio that shares the original bio's biovec
- * @bio: bio to clone
- * @gfp_mask: allocation priority
- * @bs: bio_set to allocate from
+ * bio_alloc_clone - clone a bio that shares the original bio's biovec
+ * @bdev: block_device to clone onto
+ * @bio_src: bio to clone from
+ * @gfp: allocation priority
+ * @bs: bio_set to allocate from
+ *
+ * Allocate a new bio that is a clone of @bio_src. The caller owns the returned
+ * bio, but not the actual data it points to.
*
- * Like __bio_clone_fast, only also allocates the returned bio
+ * The caller must ensure that the return bio is not freed before @bio_src.
*/
-struct bio *bio_clone_fast(struct bio *bio, gfp_t gfp_mask, struct bio_set *bs)
+struct bio *bio_alloc_clone(struct block_device *bdev, struct bio *bio_src,
+ gfp_t gfp, struct bio_set *bs)
{
- struct bio *b;
+ struct bio *bio;
- b = bio_alloc_bioset(gfp_mask, 0, bs);
- if (!b)
+ bio = bio_alloc_bioset(bdev, 0, bio_src->bi_opf, gfp, bs);
+ if (!bio)
return NULL;
- __bio_clone_fast(b, bio);
-
- if (bio_crypt_clone(b, bio, gfp_mask) < 0)
- goto err_put;
-
- if (bio_integrity(bio) &&
- bio_integrity_clone(b, bio, gfp_mask) < 0)
- goto err_put;
-
- return b;
+ if (__bio_clone(bio, bio_src, gfp) < 0) {
+ bio_put(bio);
+ return NULL;
+ }
+ bio->bi_io_vec = bio_src->bi_io_vec;
-err_put:
- bio_put(b);
- return NULL;
+ return bio;
}
-EXPORT_SYMBOL(bio_clone_fast);
+EXPORT_SYMBOL(bio_alloc_clone);
-const char *bio_devname(struct bio *bio, char *buf)
+/**
+ * bio_init_clone - clone a bio that shares the original bio's biovec
+ * @bdev: block_device to clone onto
+ * @bio: bio to clone into
+ * @bio_src: bio to clone from
+ * @gfp: allocation priority
+ *
+ * Initialize a new bio in caller provided memory that is a clone of @bio_src.
+ * The caller owns the returned bio, but not the actual data it points to.
+ *
+ * The caller must ensure that @bio_src is not freed before @bio.
+ */
+int bio_init_clone(struct block_device *bdev, struct bio *bio,
+ struct bio *bio_src, gfp_t gfp)
{
- return bdevname(bio->bi_bdev, buf);
+ int ret;
+
+ bio_init(bio, bdev, bio_src->bi_io_vec, 0, bio_src->bi_opf);
+ ret = __bio_clone(bio, bio_src, gfp);
+ if (ret)
+ bio_uninit(bio);
+ return ret;
}
-EXPORT_SYMBOL(bio_devname);
+EXPORT_SYMBOL(bio_init_clone);
/**
* bio_full - check if the bio is full
@@ -1054,7 +1084,7 @@ bool bio_add_folio(struct bio *bio, struct folio *folio, size_t len,
size_t off)
{
if (len > UINT_MAX || off > UINT_MAX)
- return 0;
+ return false;
return bio_add_page(bio, &folio->page, len, off) > 0;
}
@@ -1486,8 +1516,7 @@ again:
if (!bio_integrity_endio(bio))
return;
- if (bio->bi_bdev && bio_flagged(bio, BIO_TRACKED))
- rq_qos_done_bio(bdev_get_queue(bio->bi_bdev), bio);
+ rq_qos_done_bio(bio);
if (bio->bi_bdev && bio_flagged(bio, BIO_TRACE_COMPLETION)) {
trace_block_bio_complete(bdev_get_queue(bio->bi_bdev), bio);
@@ -1541,7 +1570,7 @@ struct bio *bio_split(struct bio *bio, int sectors,
if (WARN_ON_ONCE(bio_op(bio) == REQ_OP_ZONE_APPEND))
return NULL;
- split = bio_clone_fast(bio, gfp, bs);
+ split = bio_alloc_clone(bio->bi_bdev, bio, gfp, bs);
if (!split)
return NULL;
@@ -1636,9 +1665,9 @@ EXPORT_SYMBOL(bioset_exit);
* Note that the bio must be embedded at the END of that structure always,
* or things will break badly.
* If %BIOSET_NEED_BVECS is set in @flags, a separate pool will be allocated
- * for allocating iovecs. This pool is not needed e.g. for bio_clone_fast().
- * If %BIOSET_NEED_RESCUER is set, a workqueue is created which can be used to
- * dispatch queued requests when the mempool runs out of space.
+ * for allocating iovecs. This pool is not needed e.g. for bio_init_clone().
+ * If %BIOSET_NEED_RESCUER is set, a workqueue is created which can be used
+ * to dispatch queued requests when the mempool runs out of space.
*
*/
int bioset_init(struct bio_set *bs,
@@ -1708,7 +1737,9 @@ EXPORT_SYMBOL(bioset_init_from_src);
/**
* bio_alloc_kiocb - Allocate a bio from bio_set based on kiocb
* @kiocb: kiocb describing the IO
+ * @bdev: block device to allocate the bio for (can be %NULL)
* @nr_vecs: number of iovecs to pre-allocate
+ * @opf: operation and flags for bio
* @bs: bio_set to allocate from
*
* Description:
@@ -1719,14 +1750,14 @@ EXPORT_SYMBOL(bioset_init_from_src);
* MUST be done from process context, not hard/soft IRQ.
*
*/
-struct bio *bio_alloc_kiocb(struct kiocb *kiocb, unsigned short nr_vecs,
- struct bio_set *bs)
+struct bio *bio_alloc_kiocb(struct kiocb *kiocb, struct block_device *bdev,
+ unsigned short nr_vecs, unsigned int opf, struct bio_set *bs)
{
struct bio_alloc_cache *cache;
struct bio *bio;
if (!(kiocb->ki_flags & IOCB_ALLOC_CACHE) || nr_vecs > BIO_INLINE_VECS)
- return bio_alloc_bioset(GFP_KERNEL, nr_vecs, bs);
+ return bio_alloc_bioset(bdev, nr_vecs, opf, GFP_KERNEL, bs);
cache = per_cpu_ptr(bs->cache, get_cpu());
if (cache->free_list) {
@@ -1734,13 +1765,14 @@ struct bio *bio_alloc_kiocb(struct kiocb *kiocb, unsigned short nr_vecs,
cache->free_list = bio->bi_next;
cache->nr--;
put_cpu();
- bio_init(bio, nr_vecs ? bio->bi_inline_vecs : NULL, nr_vecs);
+ bio_init(bio, bdev, nr_vecs ? bio->bi_inline_vecs : NULL,
+ nr_vecs, opf);
bio->bi_pool = bs;
bio_set_flag(bio, BIO_PERCPU_CACHE);
return bio;
}
put_cpu();
- bio = bio_alloc_bioset(GFP_KERNEL, nr_vecs, bs);
+ bio = bio_alloc_bioset(bdev, nr_vecs, opf, GFP_KERNEL, bs);
bio_set_flag(bio, BIO_PERCPU_CACHE);
return bio;
}
diff --git a/block/blk-cgroup-rwstat.h b/block/blk-cgroup-rwstat.h
index ee746919c41f..9f2723b34b75 100644
--- a/block/blk-cgroup-rwstat.h
+++ b/block/blk-cgroup-rwstat.h
@@ -6,7 +6,7 @@
#ifndef _BLK_CGROUP_RWSTAT_H
#define _BLK_CGROUP_RWSTAT_H
-#include <linux/blk-cgroup.h>
+#include "blk-cgroup.h"
enum blkg_rwstat_type {
BLKG_RWSTAT_READ,
diff --git a/block/blk-cgroup.c b/block/blk-cgroup.c
index 650f7e27989f..d53b0d69dd73 100644
--- a/block/blk-cgroup.c
+++ b/block/blk-cgroup.c
@@ -23,15 +23,14 @@
#include <linux/blkdev.h>
#include <linux/backing-dev.h>
#include <linux/slab.h>
-#include <linux/genhd.h>
#include <linux/delay.h>
#include <linux/atomic.h>
#include <linux/ctype.h>
-#include <linux/blk-cgroup.h>
#include <linux/tracehook.h>
#include <linux/psi.h>
#include <linux/part_stat.h>
#include "blk.h"
+#include "blk-cgroup.h"
#include "blk-ioprio.h"
#include "blk-throttle.h"
@@ -83,6 +82,8 @@ static void blkg_free(struct blkcg_gq *blkg)
if (blkg->pd[i])
blkcg_policy[i]->pd_free_fn(blkg->pd[i]);
+ if (blkg->q)
+ blk_put_queue(blkg->q);
free_percpu(blkg->iostat_cpu);
percpu_ref_exit(&blkg->refcnt);
kfree(blkg);
@@ -168,6 +169,9 @@ static struct blkcg_gq *blkg_alloc(struct blkcg *blkcg, struct request_queue *q,
if (!blkg->iostat_cpu)
goto err_free;
+ if (!blk_get_queue(q))
+ goto err_free;
+
blkg->q = q;
INIT_LIST_HEAD(&blkg->q_node);
spin_lock_init(&blkg->async_bio_lock);
@@ -857,11 +861,11 @@ static void blkcg_fill_root_iostats(void)
blk_queue_root_blkg(bdev_get_queue(bdev));
struct blkg_iostat tmp;
int cpu;
+ unsigned long flags;
memset(&tmp, 0, sizeof(tmp));
for_each_possible_cpu(cpu) {
struct disk_stats *cpu_dkstats;
- unsigned long flags;
cpu_dkstats = per_cpu_ptr(bdev->bd_stats, cpu);
tmp.ios[BLKG_IOSTAT_READ] +=
@@ -877,11 +881,11 @@ static void blkcg_fill_root_iostats(void)
cpu_dkstats->sectors[STAT_WRITE] << 9;
tmp.bytes[BLKG_IOSTAT_DISCARD] +=
cpu_dkstats->sectors[STAT_DISCARD] << 9;
-
- flags = u64_stats_update_begin_irqsave(&blkg->iostat.sync);
- blkg_iostat_set(&blkg->iostat.cur, &tmp);
- u64_stats_update_end_irqrestore(&blkg->iostat.sync, flags);
}
+
+ flags = u64_stats_update_begin_irqsave(&blkg->iostat.sync);
+ blkg_iostat_set(&blkg->iostat.cur, &tmp);
+ u64_stats_update_end_irqrestore(&blkg->iostat.sync, flags);
}
}
@@ -1176,6 +1180,8 @@ int blkcg_init_queue(struct request_queue *q)
bool preloaded;
int ret;
+ INIT_LIST_HEAD(&q->blkg_list);
+
new_blkg = blkg_alloc(&blkcg_root, q, GFP_KERNEL);
if (!new_blkg)
return -ENOMEM;
diff --git a/block/blk-cgroup.h b/block/blk-cgroup.h
new file mode 100644
index 000000000000..47e1e38390c9
--- /dev/null
+++ b/block/blk-cgroup.h
@@ -0,0 +1,494 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _BLK_CGROUP_PRIVATE_H
+#define _BLK_CGROUP_PRIVATE_H
+/*
+ * block cgroup private header
+ *
+ * Based on ideas and code from CFQ, CFS and BFQ:
+ * Copyright (C) 2003 Jens Axboe <axboe@kernel.dk>
+ *
+ * Copyright (C) 2008 Fabio Checconi <fabio@gandalf.sssup.it>
+ * Paolo Valente <paolo.valente@unimore.it>
+ *
+ * Copyright (C) 2009 Vivek Goyal <vgoyal@redhat.com>
+ * Nauman Rafique <nauman@google.com>
+ */
+
+#include <linux/blk-cgroup.h>
+#include <linux/blk-mq.h>
+
+/* percpu_counter batch for blkg_[rw]stats, per-cpu drift doesn't matter */
+#define BLKG_STAT_CPU_BATCH (INT_MAX / 2)
+
+#ifdef CONFIG_BLK_CGROUP
+
+/*
+ * A blkcg_gq (blkg) is association between a block cgroup (blkcg) and a
+ * request_queue (q). This is used by blkcg policies which need to track
+ * information per blkcg - q pair.
+ *
+ * There can be multiple active blkcg policies and each blkg:policy pair is
+ * represented by a blkg_policy_data which is allocated and freed by each
+ * policy's pd_alloc/free_fn() methods. A policy can allocate private data
+ * area by allocating larger data structure which embeds blkg_policy_data
+ * at the beginning.
+ */
+struct blkg_policy_data {
+ /* the blkg and policy id this per-policy data belongs to */
+ struct blkcg_gq *blkg;
+ int plid;
+};
+
+/*
+ * Policies that need to keep per-blkcg data which is independent from any
+ * request_queue associated to it should implement cpd_alloc/free_fn()
+ * methods. A policy can allocate private data area by allocating larger
+ * data structure which embeds blkcg_policy_data at the beginning.
+ * cpd_init() is invoked to let each policy handle per-blkcg data.
+ */
+struct blkcg_policy_data {
+ /* the blkcg and policy id this per-policy data belongs to */
+ struct blkcg *blkcg;
+ int plid;
+};
+
+typedef struct blkcg_policy_data *(blkcg_pol_alloc_cpd_fn)(gfp_t gfp);
+typedef void (blkcg_pol_init_cpd_fn)(struct blkcg_policy_data *cpd);
+typedef void (blkcg_pol_free_cpd_fn)(struct blkcg_policy_data *cpd);
+typedef void (blkcg_pol_bind_cpd_fn)(struct blkcg_policy_data *cpd);
+typedef struct blkg_policy_data *(blkcg_pol_alloc_pd_fn)(gfp_t gfp,
+ struct request_queue *q, struct blkcg *blkcg);
+typedef void (blkcg_pol_init_pd_fn)(struct blkg_policy_data *pd);
+typedef void (blkcg_pol_online_pd_fn)(struct blkg_policy_data *pd);
+typedef void (blkcg_pol_offline_pd_fn)(struct blkg_policy_data *pd);
+typedef void (blkcg_pol_free_pd_fn)(struct blkg_policy_data *pd);
+typedef void (blkcg_pol_reset_pd_stats_fn)(struct blkg_policy_data *pd);
+typedef bool (blkcg_pol_stat_pd_fn)(struct blkg_policy_data *pd,
+ struct seq_file *s);
+
+struct blkcg_policy {
+ int plid;
+ /* cgroup files for the policy */
+ struct cftype *dfl_cftypes;
+ struct cftype *legacy_cftypes;
+
+ /* operations */
+ blkcg_pol_alloc_cpd_fn *cpd_alloc_fn;
+ blkcg_pol_init_cpd_fn *cpd_init_fn;
+ blkcg_pol_free_cpd_fn *cpd_free_fn;
+ blkcg_pol_bind_cpd_fn *cpd_bind_fn;
+
+ blkcg_pol_alloc_pd_fn *pd_alloc_fn;
+ blkcg_pol_init_pd_fn *pd_init_fn;
+ blkcg_pol_online_pd_fn *pd_online_fn;
+ blkcg_pol_offline_pd_fn *pd_offline_fn;
+ blkcg_pol_free_pd_fn *pd_free_fn;
+ blkcg_pol_reset_pd_stats_fn *pd_reset_stats_fn;
+ blkcg_pol_stat_pd_fn *pd_stat_fn;
+};
+
+extern struct blkcg blkcg_root;
+extern bool blkcg_debug_stats;
+
+struct blkcg_gq *blkg_lookup_slowpath(struct blkcg *blkcg,
+ struct request_queue *q, bool update_hint);
+int blkcg_init_queue(struct request_queue *q);
+void blkcg_exit_queue(struct request_queue *q);
+
+/* Blkio controller policy registration */
+int blkcg_policy_register(struct blkcg_policy *pol);
+void blkcg_policy_unregister(struct blkcg_policy *pol);
+int blkcg_activate_policy(struct request_queue *q,
+ const struct blkcg_policy *pol);
+void blkcg_deactivate_policy(struct request_queue *q,
+ const struct blkcg_policy *pol);
+
+const char *blkg_dev_name(struct blkcg_gq *blkg);
+void blkcg_print_blkgs(struct seq_file *sf, struct blkcg *blkcg,
+ u64 (*prfill)(struct seq_file *,
+ struct blkg_policy_data *, int),
+ const struct blkcg_policy *pol, int data,
+ bool show_total);
+u64 __blkg_prfill_u64(struct seq_file *sf, struct blkg_policy_data *pd, u64 v);
+
+struct blkg_conf_ctx {
+ struct block_device *bdev;
+ struct blkcg_gq *blkg;
+ char *body;
+};
+
+struct block_device *blkcg_conf_open_bdev(char **inputp);
+int blkg_conf_prep(struct blkcg *blkcg, const struct blkcg_policy *pol,
+ char *input, struct blkg_conf_ctx *ctx);
+void blkg_conf_finish(struct blkg_conf_ctx *ctx);
+
+/**
+ * blkcg_css - find the current css
+ *
+ * Find the css associated with either the kthread or the current task.
+ * This may return a dying css, so it is up to the caller to use tryget logic
+ * to confirm it is alive and well.
+ */
+static inline struct cgroup_subsys_state *blkcg_css(void)
+{
+ struct cgroup_subsys_state *css;
+
+ css = kthread_blkcg();
+ if (css)
+ return css;
+ return task_css(current, io_cgrp_id);
+}
+
+/**
+ * __bio_blkcg - internal, inconsistent version to get blkcg
+ *
+ * DO NOT USE.
+ * This function is inconsistent and consequently is dangerous to use. The
+ * first part of the function returns a blkcg where a reference is owned by the
+ * bio. This means it does not need to be rcu protected as it cannot go away
+ * with the bio owning a reference to it. However, the latter potentially gets
+ * it from task_css(). This can race against task migration and the cgroup
+ * dying. It is also semantically different as it must be called rcu protected
+ * and is susceptible to failure when trying to get a reference to it.
+ * Therefore, it is not ok to assume that *_get() will always succeed on the
+ * blkcg returned here.
+ */
+static inline struct blkcg *__bio_blkcg(struct bio *bio)
+{
+ if (bio && bio->bi_blkg)
+ return bio->bi_blkg->blkcg;
+ return css_to_blkcg(blkcg_css());
+}
+
+/**
+ * bio_issue_as_root_blkg - see if this bio needs to be issued as root blkg
+ * @return: true if this bio needs to be submitted with the root blkg context.
+ *
+ * In order to avoid priority inversions we sometimes need to issue a bio as if
+ * it were attached to the root blkg, and then backcharge to the actual owning
+ * blkg. The idea is we do bio_blkcg() to look up the actual context for the
+ * bio and attach the appropriate blkg to the bio. Then we call this helper and
+ * if it is true run with the root blkg for that queue and then do any
+ * backcharging to the originating cgroup once the io is complete.
+ */
+static inline bool bio_issue_as_root_blkg(struct bio *bio)
+{
+ return (bio->bi_opf & (REQ_META | REQ_SWAP)) != 0;
+}
+
+/**
+ * __blkg_lookup - internal version of blkg_lookup()
+ * @blkcg: blkcg of interest
+ * @q: request_queue of interest
+ * @update_hint: whether to update lookup hint with the result or not
+ *
+ * This is internal version and shouldn't be used by policy
+ * implementations. Looks up blkgs for the @blkcg - @q pair regardless of
+ * @q's bypass state. If @update_hint is %true, the caller should be
+ * holding @q->queue_lock and lookup hint is updated on success.
+ */
+static inline struct blkcg_gq *__blkg_lookup(struct blkcg *blkcg,
+ struct request_queue *q,
+ bool update_hint)
+{
+ struct blkcg_gq *blkg;
+
+ if (blkcg == &blkcg_root)
+ return q->root_blkg;
+
+ blkg = rcu_dereference(blkcg->blkg_hint);
+ if (blkg && blkg->q == q)
+ return blkg;
+
+ return blkg_lookup_slowpath(blkcg, q, update_hint);
+}
+
+/**
+ * blkg_lookup - lookup blkg for the specified blkcg - q pair
+ * @blkcg: blkcg of interest
+ * @q: request_queue of interest
+ *
+ * Lookup blkg for the @blkcg - @q pair. This function should be called
+ * under RCU read lock.
+ */
+static inline struct blkcg_gq *blkg_lookup(struct blkcg *blkcg,
+ struct request_queue *q)
+{
+ WARN_ON_ONCE(!rcu_read_lock_held());
+ return __blkg_lookup(blkcg, q, false);
+}
+
+/**
+ * blk_queue_root_blkg - return blkg for the (blkcg_root, @q) pair
+ * @q: request_queue of interest
+ *
+ * Lookup blkg for @q at the root level. See also blkg_lookup().
+ */
+static inline struct blkcg_gq *blk_queue_root_blkg(struct request_queue *q)
+{
+ return q->root_blkg;
+}
+
+/**
+ * blkg_to_pdata - get policy private data
+ * @blkg: blkg of interest
+ * @pol: policy of interest
+ *
+ * Return pointer to private data associated with the @blkg-@pol pair.
+ */
+static inline struct blkg_policy_data *blkg_to_pd(struct blkcg_gq *blkg,
+ struct blkcg_policy *pol)
+{
+ return blkg ? blkg->pd[pol->plid] : NULL;
+}
+
+static inline struct blkcg_policy_data *blkcg_to_cpd(struct blkcg *blkcg,
+ struct blkcg_policy *pol)
+{
+ return blkcg ? blkcg->cpd[pol->plid] : NULL;
+}
+
+/**
+ * pdata_to_blkg - get blkg associated with policy private data
+ * @pd: policy private data of interest
+ *
+ * @pd is policy private data. Determine the blkg it's associated with.
+ */
+static inline struct blkcg_gq *pd_to_blkg(struct blkg_policy_data *pd)
+{
+ return pd ? pd->blkg : NULL;
+}
+
+static inline struct blkcg *cpd_to_blkcg(struct blkcg_policy_data *cpd)
+{
+ return cpd ? cpd->blkcg : NULL;
+}
+
+/**
+ * blkg_path - format cgroup path of blkg
+ * @blkg: blkg of interest
+ * @buf: target buffer
+ * @buflen: target buffer length
+ *
+ * Format the path of the cgroup of @blkg into @buf.
+ */
+static inline int blkg_path(struct blkcg_gq *blkg, char *buf, int buflen)
+{
+ return cgroup_path(blkg->blkcg->css.cgroup, buf, buflen);
+}
+
+/**
+ * blkg_get - get a blkg reference
+ * @blkg: blkg to get
+ *
+ * The caller should be holding an existing reference.
+ */
+static inline void blkg_get(struct blkcg_gq *blkg)
+{
+ percpu_ref_get(&blkg->refcnt);
+}
+
+/**
+ * blkg_tryget - try and get a blkg reference
+ * @blkg: blkg to get
+ *
+ * This is for use when doing an RCU lookup of the blkg. We may be in the midst
+ * of freeing this blkg, so we can only use it if the refcnt is not zero.
+ */
+static inline bool blkg_tryget(struct blkcg_gq *blkg)
+{
+ return blkg && percpu_ref_tryget(&blkg->refcnt);
+}
+
+/**
+ * blkg_put - put a blkg reference
+ * @blkg: blkg to put
+ */
+static inline void blkg_put(struct blkcg_gq *blkg)
+{
+ percpu_ref_put(&blkg->refcnt);
+}
+
+/**
+ * blkg_for_each_descendant_pre - pre-order walk of a blkg's descendants
+ * @d_blkg: loop cursor pointing to the current descendant
+ * @pos_css: used for iteration
+ * @p_blkg: target blkg to walk descendants of
+ *
+ * Walk @c_blkg through the descendants of @p_blkg. Must be used with RCU
+ * read locked. If called under either blkcg or queue lock, the iteration
+ * is guaranteed to include all and only online blkgs. The caller may
+ * update @pos_css by calling css_rightmost_descendant() to skip subtree.
+ * @p_blkg is included in the iteration and the first node to be visited.
+ */
+#define blkg_for_each_descendant_pre(d_blkg, pos_css, p_blkg) \
+ css_for_each_descendant_pre((pos_css), &(p_blkg)->blkcg->css) \
+ if (((d_blkg) = __blkg_lookup(css_to_blkcg(pos_css), \
+ (p_blkg)->q, false)))
+
+/**
+ * blkg_for_each_descendant_post - post-order walk of a blkg's descendants
+ * @d_blkg: loop cursor pointing to the current descendant
+ * @pos_css: used for iteration
+ * @p_blkg: target blkg to walk descendants of
+ *
+ * Similar to blkg_for_each_descendant_pre() but performs post-order
+ * traversal instead. Synchronization rules are the same. @p_blkg is
+ * included in the iteration and the last node to be visited.
+ */
+#define blkg_for_each_descendant_post(d_blkg, pos_css, p_blkg) \
+ css_for_each_descendant_post((pos_css), &(p_blkg)->blkcg->css) \
+ if (((d_blkg) = __blkg_lookup(css_to_blkcg(pos_css), \
+ (p_blkg)->q, false)))
+
+bool __blkcg_punt_bio_submit(struct bio *bio);
+
+static inline bool blkcg_punt_bio_submit(struct bio *bio)
+{
+ if (bio->bi_opf & REQ_CGROUP_PUNT)
+ return __blkcg_punt_bio_submit(bio);
+ else
+ return false;
+}
+
+static inline void blkcg_bio_issue_init(struct bio *bio)
+{
+ bio_issue_init(&bio->bi_issue, bio_sectors(bio));
+}
+
+static inline void blkcg_use_delay(struct blkcg_gq *blkg)
+{
+ if (WARN_ON_ONCE(atomic_read(&blkg->use_delay) < 0))
+ return;
+ if (atomic_add_return(1, &blkg->use_delay) == 1)
+ atomic_inc(&blkg->blkcg->css.cgroup->congestion_count);
+}
+
+static inline int blkcg_unuse_delay(struct blkcg_gq *blkg)
+{
+ int old = atomic_read(&blkg->use_delay);
+
+ if (WARN_ON_ONCE(old < 0))
+ return 0;
+ if (old == 0)
+ return 0;
+
+ /*
+ * We do this song and dance because we can race with somebody else
+ * adding or removing delay. If we just did an atomic_dec we'd end up
+ * negative and we'd already be in trouble. We need to subtract 1 and
+ * then check to see if we were the last delay so we can drop the
+ * congestion count on the cgroup.
+ */
+ while (old) {
+ int cur = atomic_cmpxchg(&blkg->use_delay, old, old - 1);
+ if (cur == old)
+ break;
+ old = cur;
+ }
+
+ if (old == 0)
+ return 0;
+ if (old == 1)
+ atomic_dec(&blkg->blkcg->css.cgroup->congestion_count);
+ return 1;
+}
+
+/**
+ * blkcg_set_delay - Enable allocator delay mechanism with the specified delay amount
+ * @blkg: target blkg
+ * @delay: delay duration in nsecs
+ *
+ * When enabled with this function, the delay is not decayed and must be
+ * explicitly cleared with blkcg_clear_delay(). Must not be mixed with
+ * blkcg_[un]use_delay() and blkcg_add_delay() usages.
+ */
+static inline void blkcg_set_delay(struct blkcg_gq *blkg, u64 delay)
+{
+ int old = atomic_read(&blkg->use_delay);
+
+ /* We only want 1 person setting the congestion count for this blkg. */
+ if (!old && atomic_cmpxchg(&blkg->use_delay, old, -1) == old)
+ atomic_inc(&blkg->blkcg->css.cgroup->congestion_count);
+
+ atomic64_set(&blkg->delay_nsec, delay);
+}
+
+/**
+ * blkcg_clear_delay - Disable allocator delay mechanism
+ * @blkg: target blkg
+ *
+ * Disable use_delay mechanism. See blkcg_set_delay().
+ */
+static inline void blkcg_clear_delay(struct blkcg_gq *blkg)
+{
+ int old = atomic_read(&blkg->use_delay);
+
+ /* We only want 1 person clearing the congestion count for this blkg. */
+ if (old && atomic_cmpxchg(&blkg->use_delay, old, 0) == old)
+ atomic_dec(&blkg->blkcg->css.cgroup->congestion_count);
+}
+
+/**
+ * blk_cgroup_mergeable - Determine whether to allow or disallow merges
+ * @rq: request to merge into
+ * @bio: bio to merge
+ *
+ * @bio and @rq should belong to the same cgroup and their issue_as_root should
+ * match. The latter is necessary as we don't want to throttle e.g. a metadata
+ * update because it happens to be next to a regular IO.
+ */
+static inline bool blk_cgroup_mergeable(struct request *rq, struct bio *bio)
+{
+ return rq->bio->bi_blkg == bio->bi_blkg &&
+ bio_issue_as_root_blkg(rq->bio) == bio_issue_as_root_blkg(bio);
+}
+
+void blk_cgroup_bio_start(struct bio *bio);
+void blkcg_add_delay(struct blkcg_gq *blkg, u64 now, u64 delta);
+#else /* CONFIG_BLK_CGROUP */
+
+struct blkg_policy_data {
+};
+
+struct blkcg_policy_data {
+};
+
+struct blkcg_policy {
+};
+
+#ifdef CONFIG_BLOCK
+
+static inline struct blkcg_gq *blkg_lookup(struct blkcg *blkcg, void *key) { return NULL; }
+static inline struct blkcg_gq *blk_queue_root_blkg(struct request_queue *q)
+{ return NULL; }
+static inline int blkcg_init_queue(struct request_queue *q) { return 0; }
+static inline void blkcg_exit_queue(struct request_queue *q) { }
+static inline int blkcg_policy_register(struct blkcg_policy *pol) { return 0; }
+static inline void blkcg_policy_unregister(struct blkcg_policy *pol) { }
+static inline int blkcg_activate_policy(struct request_queue *q,
+ const struct blkcg_policy *pol) { return 0; }
+static inline void blkcg_deactivate_policy(struct request_queue *q,
+ const struct blkcg_policy *pol) { }
+
+static inline struct blkcg *__bio_blkcg(struct bio *bio) { return NULL; }
+
+static inline struct blkg_policy_data *blkg_to_pd(struct blkcg_gq *blkg,
+ struct blkcg_policy *pol) { return NULL; }
+static inline struct blkcg_gq *pd_to_blkg(struct blkg_policy_data *pd) { return NULL; }
+static inline char *blkg_path(struct blkcg_gq *blkg) { return NULL; }
+static inline void blkg_get(struct blkcg_gq *blkg) { }
+static inline void blkg_put(struct blkcg_gq *blkg) { }
+
+static inline bool blkcg_punt_bio_submit(struct bio *bio) { return false; }
+static inline void blkcg_bio_issue_init(struct bio *bio) { }
+static inline void blk_cgroup_bio_start(struct bio *bio) { }
+static inline bool blk_cgroup_mergeable(struct request *rq, struct bio *bio) { return true; }
+
+#define blk_queue_for_each_rl(rl, q) \
+ for ((rl) = &(q)->root_rl; (rl); (rl) = NULL)
+
+#endif /* CONFIG_BLOCK */
+#endif /* CONFIG_BLK_CGROUP */
+
+#endif /* _BLK_CGROUP_PRIVATE_H */
diff --git a/block/blk-core.c b/block/blk-core.c
index 535dbaa78ffe..937bb6b86331 100644
--- a/block/blk-core.c
+++ b/block/blk-core.c
@@ -34,7 +34,6 @@
#include <linux/delay.h>
#include <linux/ratelimit.h>
#include <linux/pm_runtime.h>
-#include <linux/blk-cgroup.h>
#include <linux/t10-pi.h>
#include <linux/debugfs.h>
#include <linux/bpf.h>
@@ -49,7 +48,9 @@
#include "blk.h"
#include "blk-mq-sched.h"
#include "blk-pm.h"
+#include "blk-cgroup.h"
#include "blk-throttle.h"
+#include "blk-rq-qos.h"
struct dentry *blk_debugfs_root;
@@ -163,6 +164,7 @@ static const struct {
[BLK_STS_RESOURCE] = { -ENOMEM, "kernel resource" },
[BLK_STS_DEV_RESOURCE] = { -EBUSY, "device resource" },
[BLK_STS_AGAIN] = { -EAGAIN, "nonblocking retry" },
+ [BLK_STS_OFFLINE] = { -ENODEV, "device offline" },
/* device mapper special case, should not leak out: */
[BLK_STS_DM_REQUEUE] = { -EREMCHG, "dm internal retry" },
@@ -283,13 +285,6 @@ void blk_queue_start_drain(struct request_queue *q)
wake_up_all(&q->mq_freeze_wq);
}
-void blk_set_queue_dying(struct request_queue *q)
-{
- blk_queue_flag_set(QUEUE_FLAG_DYING, q);
- blk_queue_start_drain(q);
-}
-EXPORT_SYMBOL_GPL(blk_set_queue_dying);
-
/**
* blk_cleanup_queue - shutdown a request queue
* @q: request queue to shutdown
@@ -307,7 +302,8 @@ void blk_cleanup_queue(struct request_queue *q)
WARN_ON_ONCE(blk_queue_registered(q));
/* mark @q DYING, no new request or merges will be allowed afterwards */
- blk_set_queue_dying(q);
+ blk_queue_flag_set(QUEUE_FLAG_DYING, q);
+ blk_queue_start_drain(q);
blk_queue_flag_set(QUEUE_FLAG_NOMERGES, q);
blk_queue_flag_set(QUEUE_FLAG_NOXMERGES, q);
@@ -319,6 +315,9 @@ void blk_cleanup_queue(struct request_queue *q)
*/
blk_freeze_queue(q);
+ /* cleanup rq qos structures for queue without disk */
+ rq_qos_exit(q);
+
blk_queue_flag_set(QUEUE_FLAG_DEAD, q);
blk_sync_queue(q);
@@ -340,8 +339,6 @@ void blk_cleanup_queue(struct request_queue *q)
blk_mq_sched_free_rqs(q);
mutex_unlock(&q->sysfs_lock);
- percpu_ref_exit(&q->q_usage_counter);
-
/* @q is and will stay empty, shutdown and put */
blk_put_queue(q);
}
@@ -474,9 +471,6 @@ struct request_queue *blk_alloc_queue(int node_id, bool alloc_srcu)
timer_setup(&q->timeout, blk_rq_timed_out_timer, 0);
INIT_WORK(&q->timeout_work, blk_timeout_work);
INIT_LIST_HEAD(&q->icq_list);
-#ifdef CONFIG_BLK_CGROUP
- INIT_LIST_HEAD(&q->blkg_list);
-#endif
kobject_init(&q->kobj, &blk_queue_ktype);
@@ -497,17 +491,12 @@ struct request_queue *blk_alloc_queue(int node_id, bool alloc_srcu)
PERCPU_REF_INIT_ATOMIC, GFP_KERNEL))
goto fail_stats;
- if (blkcg_init_queue(q))
- goto fail_ref;
-
blk_queue_dma_alignment(q, 511);
blk_set_default_limits(&q->limits);
q->nr_requests = BLKDEV_DEFAULT_RQ;
return q;
-fail_ref:
- percpu_ref_exit(&q->q_usage_counter);
fail_stats:
blk_free_queue_stats(q->stats);
fail_split:
@@ -541,17 +530,6 @@ bool blk_get_queue(struct request_queue *q)
}
EXPORT_SYMBOL(blk_get_queue);
-static void handle_bad_sector(struct bio *bio, sector_t maxsector)
-{
- char b[BDEVNAME_SIZE];
-
- pr_info_ratelimited("%s: attempt to access beyond end of device\n"
- "%s: rw=%d, want=%llu, limit=%llu\n",
- current->comm,
- bio_devname(bio, b), bio->bi_opf,
- bio_end_sector(bio), maxsector);
-}
-
#ifdef CONFIG_FAIL_MAKE_REQUEST
static DECLARE_FAULT_ATTR(fail_make_request);
@@ -581,14 +559,10 @@ late_initcall(fail_make_request_debugfs);
static inline bool bio_check_ro(struct bio *bio)
{
if (op_is_write(bio_op(bio)) && bdev_read_only(bio->bi_bdev)) {
- char b[BDEVNAME_SIZE];
-
if (op_is_flush(bio->bi_opf) && !bio_sectors(bio))
return false;
-
- WARN_ONCE(1,
- "Trying to write to read-only block-device %s (partno %d)\n",
- bio_devname(bio, b), bio->bi_bdev->bd_partno);
+ pr_warn("Trying to write to read-only block-device %pg\n",
+ bio->bi_bdev);
/* Older lvm-tools actually trigger this */
return false;
}
@@ -617,7 +591,11 @@ static inline int bio_check_eod(struct bio *bio)
if (nr_sectors && maxsector &&
(nr_sectors > maxsector ||
bio->bi_iter.bi_sector > maxsector - nr_sectors)) {
- handle_bad_sector(bio, maxsector);
+ pr_info_ratelimited("%s: attempt to access beyond end of device\n"
+ "%pg: rw=%d, want=%llu, limit=%llu\n",
+ current->comm,
+ bio->bi_bdev, bio->bi_opf,
+ bio_end_sector(bio), maxsector);
return -EIO;
}
return 0;
@@ -677,130 +655,19 @@ static inline blk_status_t blk_check_zone_append(struct request_queue *q,
return BLK_STS_OK;
}
-noinline_for_stack bool submit_bio_checks(struct bio *bio)
-{
- struct block_device *bdev = bio->bi_bdev;
- struct request_queue *q = bdev_get_queue(bdev);
- blk_status_t status = BLK_STS_IOERR;
- struct blk_plug *plug;
-
- might_sleep();
-
- plug = blk_mq_plug(q, bio);
- if (plug && plug->nowait)
- bio->bi_opf |= REQ_NOWAIT;
-
- /*
- * For a REQ_NOWAIT based request, return -EOPNOTSUPP
- * if queue does not support NOWAIT.
- */
- if ((bio->bi_opf & REQ_NOWAIT) && !blk_queue_nowait(q))
- goto not_supported;
-
- if (should_fail_bio(bio))
- goto end_io;
- if (unlikely(bio_check_ro(bio)))
- goto end_io;
- if (!bio_flagged(bio, BIO_REMAPPED)) {
- if (unlikely(bio_check_eod(bio)))
- goto end_io;
- if (bdev->bd_partno && unlikely(blk_partition_remap(bio)))
- goto end_io;
- }
-
- /*
- * Filter flush bio's early so that bio based drivers without flush
- * support don't have to worry about them.
- */
- if (op_is_flush(bio->bi_opf) &&
- !test_bit(QUEUE_FLAG_WC, &q->queue_flags)) {
- bio->bi_opf &= ~(REQ_PREFLUSH | REQ_FUA);
- if (!bio_sectors(bio)) {
- status = BLK_STS_OK;
- goto end_io;
- }
- }
-
- if (!test_bit(QUEUE_FLAG_POLL, &q->queue_flags))
- bio_clear_polled(bio);
-
- switch (bio_op(bio)) {
- case REQ_OP_DISCARD:
- if (!blk_queue_discard(q))
- goto not_supported;
- break;
- case REQ_OP_SECURE_ERASE:
- if (!blk_queue_secure_erase(q))
- goto not_supported;
- break;
- case REQ_OP_ZONE_APPEND:
- status = blk_check_zone_append(q, bio);
- if (status != BLK_STS_OK)
- goto end_io;
- break;
- case REQ_OP_ZONE_RESET:
- case REQ_OP_ZONE_OPEN:
- case REQ_OP_ZONE_CLOSE:
- case REQ_OP_ZONE_FINISH:
- if (!blk_queue_is_zoned(q))
- goto not_supported;
- break;
- case REQ_OP_ZONE_RESET_ALL:
- if (!blk_queue_is_zoned(q) || !blk_queue_zone_resetall(q))
- goto not_supported;
- break;
- case REQ_OP_WRITE_ZEROES:
- if (!q->limits.max_write_zeroes_sectors)
- goto not_supported;
- break;
- default:
- break;
- }
-
- if (blk_throtl_bio(bio))
- return false;
-
- blk_cgroup_bio_start(bio);
- blkcg_bio_issue_init(bio);
-
- if (!bio_flagged(bio, BIO_TRACE_COMPLETION)) {
- trace_block_bio_queue(bio);
- /* Now that enqueuing has been traced, we need to trace
- * completion as well.
- */
- bio_set_flag(bio, BIO_TRACE_COMPLETION);
- }
- return true;
-
-not_supported:
- status = BLK_STS_NOTSUPP;
-end_io:
- bio->bi_status = status;
- bio_endio(bio);
- return false;
-}
-
-static void __submit_bio_fops(struct gendisk *disk, struct bio *bio)
-{
- if (blk_crypto_bio_prep(&bio)) {
- if (likely(bio_queue_enter(bio) == 0)) {
- disk->fops->submit_bio(bio);
- blk_queue_exit(disk->queue);
- }
- }
-}
-
static void __submit_bio(struct bio *bio)
{
struct gendisk *disk = bio->bi_bdev->bd_disk;
- if (unlikely(!submit_bio_checks(bio)))
+ if (unlikely(!blk_crypto_bio_prep(&bio)))
return;
- if (!disk->fops->submit_bio)
+ if (!disk->fops->submit_bio) {
blk_mq_submit_bio(bio);
- else
- __submit_bio_fops(disk, bio);
+ } else if (likely(bio_queue_enter(bio) == 0)) {
+ disk->fops->submit_bio(bio);
+ blk_queue_exit(disk->queue);
+ }
}
/*
@@ -820,7 +687,7 @@ static void __submit_bio(struct bio *bio)
*
* bio_list_on_stack[0] contains bios submitted by the current ->submit_bio.
* bio_list_on_stack[1] contains bios that were submitted before the current
- * ->submit_bio_bio, but that haven't been processed yet.
+ * ->submit_bio, but that haven't been processed yet.
*/
static void __submit_bio_noacct(struct bio *bio)
{
@@ -879,16 +746,7 @@ static void __submit_bio_noacct_mq(struct bio *bio)
current->bio_list = NULL;
}
-/**
- * submit_bio_noacct - re-submit a bio to the block device layer for I/O
- * @bio: The bio describing the location in memory and on the device.
- *
- * This is a version of submit_bio() that shall only be used for I/O that is
- * resubmitted to lower level drivers by stacking block drivers. All file
- * systems and other upper level users of the block layer should use
- * submit_bio() instead.
- */
-void submit_bio_noacct(struct bio *bio)
+void submit_bio_noacct_nocheck(struct bio *bio)
{
/*
* We only want one ->submit_bio to be active at a time, else stack
@@ -903,6 +761,118 @@ void submit_bio_noacct(struct bio *bio)
else
__submit_bio_noacct(bio);
}
+
+/**
+ * submit_bio_noacct - re-submit a bio to the block device layer for I/O
+ * @bio: The bio describing the location in memory and on the device.
+ *
+ * This is a version of submit_bio() that shall only be used for I/O that is
+ * resubmitted to lower level drivers by stacking block drivers. All file
+ * systems and other upper level users of the block layer should use
+ * submit_bio() instead.
+ */
+void submit_bio_noacct(struct bio *bio)
+{
+ struct block_device *bdev = bio->bi_bdev;
+ struct request_queue *q = bdev_get_queue(bdev);
+ blk_status_t status = BLK_STS_IOERR;
+ struct blk_plug *plug;
+
+ might_sleep();
+
+ plug = blk_mq_plug(q, bio);
+ if (plug && plug->nowait)
+ bio->bi_opf |= REQ_NOWAIT;
+
+ /*
+ * For a REQ_NOWAIT based request, return -EOPNOTSUPP
+ * if queue does not support NOWAIT.
+ */
+ if ((bio->bi_opf & REQ_NOWAIT) && !blk_queue_nowait(q))
+ goto not_supported;
+
+ if (should_fail_bio(bio))
+ goto end_io;
+ if (unlikely(bio_check_ro(bio)))
+ goto end_io;
+ if (!bio_flagged(bio, BIO_REMAPPED)) {
+ if (unlikely(bio_check_eod(bio)))
+ goto end_io;
+ if (bdev->bd_partno && unlikely(blk_partition_remap(bio)))
+ goto end_io;
+ }
+
+ /*
+ * Filter flush bio's early so that bio based drivers without flush
+ * support don't have to worry about them.
+ */
+ if (op_is_flush(bio->bi_opf) &&
+ !test_bit(QUEUE_FLAG_WC, &q->queue_flags)) {
+ bio->bi_opf &= ~(REQ_PREFLUSH | REQ_FUA);
+ if (!bio_sectors(bio)) {
+ status = BLK_STS_OK;
+ goto end_io;
+ }
+ }
+
+ if (!test_bit(QUEUE_FLAG_POLL, &q->queue_flags))
+ bio_clear_polled(bio);
+
+ switch (bio_op(bio)) {
+ case REQ_OP_DISCARD:
+ if (!blk_queue_discard(q))
+ goto not_supported;
+ break;
+ case REQ_OP_SECURE_ERASE:
+ if (!blk_queue_secure_erase(q))
+ goto not_supported;
+ break;
+ case REQ_OP_ZONE_APPEND:
+ status = blk_check_zone_append(q, bio);
+ if (status != BLK_STS_OK)
+ goto end_io;
+ break;
+ case REQ_OP_ZONE_RESET:
+ case REQ_OP_ZONE_OPEN:
+ case REQ_OP_ZONE_CLOSE:
+ case REQ_OP_ZONE_FINISH:
+ if (!blk_queue_is_zoned(q))
+ goto not_supported;
+ break;
+ case REQ_OP_ZONE_RESET_ALL:
+ if (!blk_queue_is_zoned(q) || !blk_queue_zone_resetall(q))
+ goto not_supported;
+ break;
+ case REQ_OP_WRITE_ZEROES:
+ if (!q->limits.max_write_zeroes_sectors)
+ goto not_supported;
+ break;
+ default:
+ break;
+ }
+
+ if (blk_throtl_bio(bio))
+ return;
+
+ blk_cgroup_bio_start(bio);
+ blkcg_bio_issue_init(bio);
+
+ if (!bio_flagged(bio, BIO_TRACE_COMPLETION)) {
+ trace_block_bio_queue(bio);
+ /* Now that enqueuing has been traced, we need to trace
+ * completion as well.
+ */
+ bio_set_flag(bio, BIO_TRACE_COMPLETION);
+ }
+ submit_bio_noacct_nocheck(bio);
+ return;
+
+not_supported:
+ status = BLK_STS_NOTSUPP;
+end_io:
+ bio->bi_status = status;
+ bio_endio(bio);
+}
EXPORT_SYMBOL(submit_bio_noacct);
/**
@@ -974,21 +944,24 @@ int bio_poll(struct bio *bio, struct io_comp_batch *iob, unsigned int flags)
{
struct request_queue *q = bdev_get_queue(bio->bi_bdev);
blk_qc_t cookie = READ_ONCE(bio->bi_cookie);
- int ret;
+ int ret = 0;
if (cookie == BLK_QC_T_NONE ||
!test_bit(QUEUE_FLAG_POLL, &q->queue_flags))
return 0;
- if (current->plug)
- blk_flush_plug(current->plug, false);
+ blk_flush_plug(current->plug, false);
if (blk_queue_enter(q, BLK_MQ_REQ_NOWAIT))
return 0;
- if (WARN_ON_ONCE(!queue_is_mq(q)))
- ret = 0; /* not yet implemented, should not happen */
- else
+ if (queue_is_mq(q)) {
ret = blk_mq_poll(q, cookie, iob, flags);
+ } else {
+ struct gendisk *disk = q->disk;
+
+ if (disk && disk->fops->poll_bio)
+ ret = disk->fops->poll_bio(bio, iob, flags);
+ }
blk_queue_exit(q);
return ret;
}
@@ -1050,20 +1023,32 @@ again:
}
static unsigned long __part_start_io_acct(struct block_device *part,
- unsigned int sectors, unsigned int op)
+ unsigned int sectors, unsigned int op,
+ unsigned long start_time)
{
const int sgrp = op_stat_group(op);
- unsigned long now = READ_ONCE(jiffies);
part_stat_lock();
- update_io_ticks(part, now, false);
+ update_io_ticks(part, start_time, false);
part_stat_inc(part, ios[sgrp]);
part_stat_add(part, sectors[sgrp], sectors);
part_stat_local_inc(part, in_flight[op_is_write(op)]);
part_stat_unlock();
- return now;
+ return start_time;
+}
+
+/**
+ * bio_start_io_acct_time - start I/O accounting for bio based drivers
+ * @bio: bio to start account for
+ * @start_time: start time that should be passed back to bio_end_io_acct().
+ */
+void bio_start_io_acct_time(struct bio *bio, unsigned long start_time)
+{
+ __part_start_io_acct(bio->bi_bdev, bio_sectors(bio),
+ bio_op(bio), start_time);
}
+EXPORT_SYMBOL_GPL(bio_start_io_acct_time);
/**
* bio_start_io_acct - start I/O accounting for bio based drivers
@@ -1073,14 +1058,15 @@ static unsigned long __part_start_io_acct(struct block_device *part,
*/
unsigned long bio_start_io_acct(struct bio *bio)
{
- return __part_start_io_acct(bio->bi_bdev, bio_sectors(bio), bio_op(bio));
+ return __part_start_io_acct(bio->bi_bdev, bio_sectors(bio),
+ bio_op(bio), jiffies);
}
EXPORT_SYMBOL_GPL(bio_start_io_acct);
unsigned long disk_start_io_acct(struct gendisk *disk, unsigned int sectors,
unsigned int op)
{
- return __part_start_io_acct(disk->part0, sectors, op);
+ return __part_start_io_acct(disk->part0, sectors, op, jiffies);
}
EXPORT_SYMBOL(disk_start_io_acct);
@@ -1250,7 +1236,7 @@ struct blk_plug_cb *blk_check_plugged(blk_plug_cb_fn unplug, void *data,
}
EXPORT_SYMBOL(blk_check_plugged);
-void blk_flush_plug(struct blk_plug *plug, bool from_schedule)
+void __blk_flush_plug(struct blk_plug *plug, bool from_schedule)
{
if (!list_empty(&plug->cb_list))
flush_plug_callbacks(plug, from_schedule);
@@ -1279,7 +1265,7 @@ void blk_flush_plug(struct blk_plug *plug, bool from_schedule)
void blk_finish_plug(struct blk_plug *plug)
{
if (plug == current->plug) {
- blk_flush_plug(plug, false);
+ __blk_flush_plug(plug, false);
current->plug = NULL;
}
}
diff --git a/block/blk-crypto-fallback.c b/block/blk-crypto-fallback.c
index c87aba8584c6..18c8eafe20b9 100644
--- a/block/blk-crypto-fallback.c
+++ b/block/blk-crypto-fallback.c
@@ -10,7 +10,6 @@
#define pr_fmt(fmt) "blk-crypto-fallback: " fmt
#include <crypto/skcipher.h>
-#include <linux/blk-cgroup.h>
#include <linux/blk-crypto.h>
#include <linux/blk-crypto-profile.h>
#include <linux/blkdev.h>
@@ -20,6 +19,7 @@
#include <linux/random.h>
#include <linux/scatterlist.h>
+#include "blk-cgroup.h"
#include "blk-crypto-internal.h"
static unsigned int num_prealloc_bounce_pg = 32;
diff --git a/block/blk-crypto-internal.h b/block/blk-crypto-internal.h
index 2fb0d65a464c..e6818ffaddbf 100644
--- a/block/blk-crypto-internal.h
+++ b/block/blk-crypto-internal.h
@@ -11,6 +11,7 @@
/* Represents a crypto mode supported by blk-crypto */
struct blk_crypto_mode {
+ const char *name; /* name of this mode, shown in sysfs */
const char *cipher_str; /* crypto API name (for fallback case) */
unsigned int keysize; /* key size in bytes */
unsigned int ivsize; /* iv size in bytes */
@@ -20,6 +21,10 @@ extern const struct blk_crypto_mode blk_crypto_modes[];
#ifdef CONFIG_BLK_INLINE_ENCRYPTION
+int blk_crypto_sysfs_register(struct request_queue *q);
+
+void blk_crypto_sysfs_unregister(struct request_queue *q);
+
void bio_crypt_dun_increment(u64 dun[BLK_CRYPTO_DUN_ARRAY_SIZE],
unsigned int inc);
@@ -62,6 +67,13 @@ static inline bool blk_crypto_rq_is_encrypted(struct request *rq)
#else /* CONFIG_BLK_INLINE_ENCRYPTION */
+static inline int blk_crypto_sysfs_register(struct request_queue *q)
+{
+ return 0;
+}
+
+static inline void blk_crypto_sysfs_unregister(struct request_queue *q) { }
+
static inline bool bio_crypt_rq_ctx_compatible(struct request *rq,
struct bio *bio)
{
diff --git a/block/blk-crypto-sysfs.c b/block/blk-crypto-sysfs.c
new file mode 100644
index 000000000000..fd93bd2f33b7
--- /dev/null
+++ b/block/blk-crypto-sysfs.c
@@ -0,0 +1,172 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2021 Google LLC
+ *
+ * sysfs support for blk-crypto. This file contains the code which exports the
+ * crypto capabilities of devices via /sys/block/$disk/queue/crypto/.
+ */
+
+#include <linux/blk-crypto-profile.h>
+
+#include "blk-crypto-internal.h"
+
+struct blk_crypto_kobj {
+ struct kobject kobj;
+ struct blk_crypto_profile *profile;
+};
+
+struct blk_crypto_attr {
+ struct attribute attr;
+ ssize_t (*show)(struct blk_crypto_profile *profile,
+ struct blk_crypto_attr *attr, char *page);
+};
+
+static struct blk_crypto_profile *kobj_to_crypto_profile(struct kobject *kobj)
+{
+ return container_of(kobj, struct blk_crypto_kobj, kobj)->profile;
+}
+
+static struct blk_crypto_attr *attr_to_crypto_attr(struct attribute *attr)
+{
+ return container_of(attr, struct blk_crypto_attr, attr);
+}
+
+static ssize_t max_dun_bits_show(struct blk_crypto_profile *profile,
+ struct blk_crypto_attr *attr, char *page)
+{
+ return sysfs_emit(page, "%u\n", 8 * profile->max_dun_bytes_supported);
+}
+
+static ssize_t num_keyslots_show(struct blk_crypto_profile *profile,
+ struct blk_crypto_attr *attr, char *page)
+{
+ return sysfs_emit(page, "%u\n", profile->num_slots);
+}
+
+#define BLK_CRYPTO_RO_ATTR(_name) \
+ static struct blk_crypto_attr _name##_attr = __ATTR_RO(_name)
+
+BLK_CRYPTO_RO_ATTR(max_dun_bits);
+BLK_CRYPTO_RO_ATTR(num_keyslots);
+
+static struct attribute *blk_crypto_attrs[] = {
+ &max_dun_bits_attr.attr,
+ &num_keyslots_attr.attr,
+ NULL,
+};
+
+static const struct attribute_group blk_crypto_attr_group = {
+ .attrs = blk_crypto_attrs,
+};
+
+/*
+ * The encryption mode attributes. To avoid hard-coding the list of encryption
+ * modes, these are initialized at boot time by blk_crypto_sysfs_init().
+ */
+static struct blk_crypto_attr __blk_crypto_mode_attrs[BLK_ENCRYPTION_MODE_MAX];
+static struct attribute *blk_crypto_mode_attrs[BLK_ENCRYPTION_MODE_MAX + 1];
+
+static umode_t blk_crypto_mode_is_visible(struct kobject *kobj,
+ struct attribute *attr, int n)
+{
+ struct blk_crypto_profile *profile = kobj_to_crypto_profile(kobj);
+ struct blk_crypto_attr *a = attr_to_crypto_attr(attr);
+ int mode_num = a - __blk_crypto_mode_attrs;
+
+ if (profile->modes_supported[mode_num])
+ return 0444;
+ return 0;
+}
+
+static ssize_t blk_crypto_mode_show(struct blk_crypto_profile *profile,
+ struct blk_crypto_attr *attr, char *page)
+{
+ int mode_num = attr - __blk_crypto_mode_attrs;
+
+ return sysfs_emit(page, "0x%x\n", profile->modes_supported[mode_num]);
+}
+
+static const struct attribute_group blk_crypto_modes_attr_group = {
+ .name = "modes",
+ .attrs = blk_crypto_mode_attrs,
+ .is_visible = blk_crypto_mode_is_visible,
+};
+
+static const struct attribute_group *blk_crypto_attr_groups[] = {
+ &blk_crypto_attr_group,
+ &blk_crypto_modes_attr_group,
+ NULL,
+};
+
+static ssize_t blk_crypto_attr_show(struct kobject *kobj,
+ struct attribute *attr, char *page)
+{
+ struct blk_crypto_profile *profile = kobj_to_crypto_profile(kobj);
+ struct blk_crypto_attr *a = attr_to_crypto_attr(attr);
+
+ return a->show(profile, a, page);
+}
+
+static const struct sysfs_ops blk_crypto_attr_ops = {
+ .show = blk_crypto_attr_show,
+};
+
+static void blk_crypto_release(struct kobject *kobj)
+{
+ kfree(container_of(kobj, struct blk_crypto_kobj, kobj));
+}
+
+static struct kobj_type blk_crypto_ktype = {
+ .default_groups = blk_crypto_attr_groups,
+ .sysfs_ops = &blk_crypto_attr_ops,
+ .release = blk_crypto_release,
+};
+
+/*
+ * If the request_queue has a blk_crypto_profile, create the "crypto"
+ * subdirectory in sysfs (/sys/block/$disk/queue/crypto/).
+ */
+int blk_crypto_sysfs_register(struct request_queue *q)
+{
+ struct blk_crypto_kobj *obj;
+ int err;
+
+ if (!q->crypto_profile)
+ return 0;
+
+ obj = kzalloc(sizeof(*obj), GFP_KERNEL);
+ if (!obj)
+ return -ENOMEM;
+ obj->profile = q->crypto_profile;
+
+ err = kobject_init_and_add(&obj->kobj, &blk_crypto_ktype, &q->kobj,
+ "crypto");
+ if (err) {
+ kobject_put(&obj->kobj);
+ return err;
+ }
+ q->crypto_kobject = &obj->kobj;
+ return 0;
+}
+
+void blk_crypto_sysfs_unregister(struct request_queue *q)
+{
+ kobject_put(q->crypto_kobject);
+}
+
+static int __init blk_crypto_sysfs_init(void)
+{
+ int i;
+
+ BUILD_BUG_ON(BLK_ENCRYPTION_MODE_INVALID != 0);
+ for (i = 1; i < BLK_ENCRYPTION_MODE_MAX; i++) {
+ struct blk_crypto_attr *attr = &__blk_crypto_mode_attrs[i];
+
+ attr->attr.name = blk_crypto_modes[i].name;
+ attr->attr.mode = 0444;
+ attr->show = blk_crypto_mode_show;
+ blk_crypto_mode_attrs[i - 1] = &attr->attr;
+ }
+ return 0;
+}
+subsys_initcall(blk_crypto_sysfs_init);
diff --git a/block/blk-crypto.c b/block/blk-crypto.c
index ec9efeeeca91..a496aaef85ba 100644
--- a/block/blk-crypto.c
+++ b/block/blk-crypto.c
@@ -19,16 +19,19 @@
const struct blk_crypto_mode blk_crypto_modes[] = {
[BLK_ENCRYPTION_MODE_AES_256_XTS] = {
+ .name = "AES-256-XTS",
.cipher_str = "xts(aes)",
.keysize = 64,
.ivsize = 16,
},
[BLK_ENCRYPTION_MODE_AES_128_CBC_ESSIV] = {
+ .name = "AES-128-CBC-ESSIV",
.cipher_str = "essiv(cbc(aes),sha256)",
.keysize = 16,
.ivsize = 16,
},
[BLK_ENCRYPTION_MODE_ADIANTUM] = {
+ .name = "Adiantum",
.cipher_str = "adiantum(xchacha12,aes)",
.keysize = 32,
.ivsize = 32,
@@ -111,7 +114,6 @@ int __bio_crypt_clone(struct bio *dst, struct bio *src, gfp_t gfp_mask)
*dst->bi_crypt_context = *src->bi_crypt_context;
return 0;
}
-EXPORT_SYMBOL_GPL(__bio_crypt_clone);
/* Increments @dun by @inc, treating @dun as a multi-limb integer. */
void bio_crypt_dun_increment(u64 dun[BLK_CRYPTO_DUN_ARRAY_SIZE],
diff --git a/block/blk-flush.c b/block/blk-flush.c
index e4df894189ce..c68968724870 100644
--- a/block/blk-flush.c
+++ b/block/blk-flush.c
@@ -460,9 +460,7 @@ int blkdev_issue_flush(struct block_device *bdev)
{
struct bio bio;
- bio_init(&bio, NULL, 0);
- bio_set_dev(&bio, bdev);
- bio.bi_opf = REQ_OP_WRITE | REQ_PREFLUSH;
+ bio_init(&bio, bdev, NULL, 0, REQ_OP_WRITE | REQ_PREFLUSH);
return submit_bio_wait(&bio);
}
EXPORT_SYMBOL(blkdev_issue_flush);
diff --git a/block/blk-ia-ranges.c b/block/blk-ia-ranges.c
index b925f3db3ab7..18c68d8b9138 100644
--- a/block/blk-ia-ranges.c
+++ b/block/blk-ia-ranges.c
@@ -144,7 +144,7 @@ int disk_register_independent_access_ranges(struct gendisk *disk,
&q->kobj, "%s", "independent_access_ranges");
if (ret) {
q->ia_ranges = NULL;
- kfree(iars);
+ kobject_put(&iars->kobj);
return ret;
}
diff --git a/block/blk-iocost.c b/block/blk-iocost.c
index 769b64394298..70a0a3d680a3 100644
--- a/block/blk-iocost.c
+++ b/block/blk-iocost.c
@@ -178,12 +178,12 @@
#include <linux/time64.h>
#include <linux/parser.h>
#include <linux/sched/signal.h>
-#include <linux/blk-cgroup.h>
#include <asm/local.h>
#include <asm/local64.h>
#include "blk-rq-qos.h"
#include "blk-stat.h"
#include "blk-wbt.h"
+#include "blk-cgroup.h"
#ifdef CONFIG_TRACEPOINTS
diff --git a/block/blk-iolatency.c b/block/blk-iolatency.c
index 6593c7123b97..2f33932e72e3 100644
--- a/block/blk-iolatency.c
+++ b/block/blk-iolatency.c
@@ -74,9 +74,9 @@
#include <linux/sched/signal.h>
#include <trace/events/block.h>
#include <linux/blk-mq.h>
-#include <linux/blk-cgroup.h>
#include "blk-rq-qos.h"
#include "blk-stat.h"
+#include "blk-cgroup.h"
#include "blk.h"
#define DEFAULT_SCALE_COOKIE 1000000U
@@ -598,7 +598,7 @@ static void blkcg_iolatency_done_bio(struct rq_qos *rqos, struct bio *bio)
int inflight = 0;
blkg = bio->bi_blkg;
- if (!blkg || !bio_flagged(bio, BIO_TRACKED))
+ if (!blkg || !bio_flagged(bio, BIO_QOS_THROTTLED))
return;
iolat = blkg_to_lat(bio->bi_blkg);
diff --git a/block/blk-ioprio.c b/block/blk-ioprio.c
index 2e7f10e1c03f..79e797f5d194 100644
--- a/block/blk-ioprio.c
+++ b/block/blk-ioprio.c
@@ -12,11 +12,11 @@
* Documentation/admin-guide/cgroup-v2.rst.
*/
-#include <linux/blk-cgroup.h>
#include <linux/blk-mq.h>
#include <linux/blk_types.h>
#include <linux/kernel.h>
#include <linux/module.h>
+#include "blk-cgroup.h"
#include "blk-ioprio.h"
#include "blk-rq-qos.h"
diff --git a/block/blk-lib.c b/block/blk-lib.c
index bf5254ccdb5f..237d60d8b585 100644
--- a/block/blk-lib.c
+++ b/block/blk-lib.c
@@ -10,19 +10,6 @@
#include "blk.h"
-struct bio *blk_next_bio(struct bio *bio, unsigned int nr_pages, gfp_t gfp)
-{
- struct bio *new = bio_alloc(gfp, nr_pages);
-
- if (bio) {
- bio_chain(bio, new);
- submit_bio(bio);
- }
-
- return new;
-}
-EXPORT_SYMBOL_GPL(blk_next_bio);
-
int __blkdev_issue_discard(struct block_device *bdev, sector_t sector,
sector_t nr_sects, gfp_t gfp_mask, int flags,
struct bio **biop)
@@ -32,9 +19,6 @@ int __blkdev_issue_discard(struct block_device *bdev, sector_t sector,
unsigned int op;
sector_t bs_mask, part_offset = 0;
- if (!q)
- return -ENXIO;
-
if (bdev_read_only(bdev))
return -EPERM;
@@ -95,11 +79,8 @@ int __blkdev_issue_discard(struct block_device *bdev, sector_t sector,
WARN_ON_ONCE((req_sects << 9) > UINT_MAX);
- bio = blk_next_bio(bio, 0, gfp_mask);
+ bio = blk_next_bio(bio, bdev, 0, op, gfp_mask);
bio->bi_iter.bi_sector = sector;
- bio_set_dev(bio, bdev);
- bio_set_op_attrs(bio, op, 0);
-
bio->bi_iter.bi_size = req_sects << 9;
sector += req_sects;
nr_sects -= req_sects;
@@ -157,10 +138,6 @@ static int __blkdev_issue_write_zeroes(struct block_device *bdev,
{
struct bio *bio = *biop;
unsigned int max_write_zeroes_sectors;
- struct request_queue *q = bdev_get_queue(bdev);
-
- if (!q)
- return -ENXIO;
if (bdev_read_only(bdev))
return -EPERM;
@@ -172,10 +149,8 @@ static int __blkdev_issue_write_zeroes(struct block_device *bdev,
return -EOPNOTSUPP;
while (nr_sects) {
- bio = blk_next_bio(bio, 0, gfp_mask);
+ bio = blk_next_bio(bio, bdev, 0, REQ_OP_WRITE_ZEROES, gfp_mask);
bio->bi_iter.bi_sector = sector;
- bio_set_dev(bio, bdev);
- bio->bi_opf = REQ_OP_WRITE_ZEROES;
if (flags & BLKDEV_ZERO_NOUNMAP)
bio->bi_opf |= REQ_NOUNMAP;
@@ -211,23 +186,17 @@ static int __blkdev_issue_zero_pages(struct block_device *bdev,
sector_t sector, sector_t nr_sects, gfp_t gfp_mask,
struct bio **biop)
{
- struct request_queue *q = bdev_get_queue(bdev);
struct bio *bio = *biop;
int bi_size = 0;
unsigned int sz;
- if (!q)
- return -ENXIO;
-
if (bdev_read_only(bdev))
return -EPERM;
while (nr_sects != 0) {
- bio = blk_next_bio(bio, __blkdev_sectors_to_bio_pages(nr_sects),
- gfp_mask);
+ bio = blk_next_bio(bio, bdev, __blkdev_sectors_to_bio_pages(nr_sects),
+ REQ_OP_WRITE, gfp_mask);
bio->bi_iter.bi_sector = sector;
- bio_set_dev(bio, bdev);
- bio_set_op_attrs(bio, REQ_OP_WRITE, 0);
while (nr_sects != 0) {
sz = min((sector_t) PAGE_SIZE, nr_sects << 9);
diff --git a/block/blk-map.c b/block/blk-map.c
index 4526adde0156..c7f71d83eff1 100644
--- a/block/blk-map.c
+++ b/block/blk-map.c
@@ -446,7 +446,7 @@ static struct bio *bio_copy_kern(struct request_queue *q, void *data,
if (bytes > len)
bytes = len;
- page = alloc_page(GFP_NOIO | gfp_mask);
+ page = alloc_page(GFP_NOIO | __GFP_ZERO | gfp_mask);
if (!page)
goto cleanup;
diff --git a/block/blk-merge.c b/block/blk-merge.c
index 87cee7e82ae1..49d0d0da0bf2 100644
--- a/block/blk-merge.c
+++ b/block/blk-merge.c
@@ -9,6 +9,7 @@
#include <linux/blk-integrity.h>
#include <linux/scatterlist.h>
#include <linux/part_stat.h>
+#include <linux/blk-cgroup.h>
#include <trace/events/block.h>
@@ -348,8 +349,6 @@ void __blk_queue_split(struct request_queue *q, struct bio **bio,
trace_block_split(split, (*bio)->bi_iter.bi_sector);
submit_bio_noacct(*bio);
*bio = split;
-
- blk_throtl_charge_bio_split(*bio);
}
}
@@ -576,6 +575,9 @@ static inline unsigned int blk_rq_get_max_sectors(struct request *rq,
static inline int ll_new_hw_segment(struct request *req, struct bio *bio,
unsigned int nr_phys_segs)
{
+ if (!blk_cgroup_mergeable(req, bio))
+ goto no_merge;
+
if (blk_integrity_merge_bio(req->q, req, bio) == false)
goto no_merge;
@@ -672,6 +674,9 @@ static int ll_merge_requests_fn(struct request_queue *q, struct request *req,
if (total_phys_segments > blk_rq_get_max_segments(req))
return 0;
+ if (!blk_cgroup_mergeable(req, next->bio))
+ return 0;
+
if (blk_integrity_merge_rq(q, req, next) == false)
return 0;
@@ -869,6 +874,10 @@ bool blk_rq_merge_ok(struct request *rq, struct bio *bio)
if (bio_data_dir(bio) != rq_data_dir(rq))
return false;
+ /* don't merge across cgroup boundaries */
+ if (!blk_cgroup_mergeable(rq, bio))
+ return false;
+
/* only merge integrity protected bio into ditto rq */
if (blk_integrity_merge_bio(rq->q, rq, bio) == false)
return false;
@@ -1049,12 +1058,20 @@ bool blk_attempt_plug_merge(struct request_queue *q, struct bio *bio,
if (!plug || rq_list_empty(plug->mq_list))
return false;
- /* check the previously added entry for a quick merge attempt */
- rq = rq_list_peek(&plug->mq_list);
- if (rq->q == q) {
- if (blk_attempt_bio_merge(q, rq, bio, nr_segs, false) ==
- BIO_MERGE_OK)
- return true;
+ rq_list_for_each(&plug->mq_list, rq) {
+ if (rq->q == q) {
+ if (blk_attempt_bio_merge(q, rq, bio, nr_segs, false) ==
+ BIO_MERGE_OK)
+ return true;
+ break;
+ }
+
+ /*
+ * Only keep iterating plug list for merges if we have multiple
+ * queues
+ */
+ if (!plug->multiple_queues)
+ break;
}
return false;
}
diff --git a/block/blk-mq-debugfs.c b/block/blk-mq-debugfs.c
index 3a790eb4995c..e2880f6deb34 100644
--- a/block/blk-mq-debugfs.c
+++ b/block/blk-mq-debugfs.c
@@ -707,7 +707,7 @@ static void debugfs_create_files(struct dentry *parent, void *data,
void blk_mq_debugfs_register(struct request_queue *q)
{
struct blk_mq_hw_ctx *hctx;
- int i;
+ unsigned long i;
debugfs_create_files(q->debugfs_dir, q, blk_mq_debugfs_queue_attrs);
@@ -780,7 +780,7 @@ void blk_mq_debugfs_unregister_hctx(struct blk_mq_hw_ctx *hctx)
void blk_mq_debugfs_register_hctxs(struct request_queue *q)
{
struct blk_mq_hw_ctx *hctx;
- int i;
+ unsigned long i;
queue_for_each_hw_ctx(q, hctx, i)
blk_mq_debugfs_register_hctx(q, hctx);
@@ -789,7 +789,7 @@ void blk_mq_debugfs_register_hctxs(struct request_queue *q)
void blk_mq_debugfs_unregister_hctxs(struct request_queue *q)
{
struct blk_mq_hw_ctx *hctx;
- int i;
+ unsigned long i;
queue_for_each_hw_ctx(q, hctx, i)
blk_mq_debugfs_unregister_hctx(hctx);
diff --git a/block/blk-mq-debugfs.h b/block/blk-mq-debugfs.h
index a68aa6041a10..69918f4170d6 100644
--- a/block/blk-mq-debugfs.h
+++ b/block/blk-mq-debugfs.h
@@ -6,6 +6,8 @@
#include <linux/seq_file.h>
+struct blk_mq_hw_ctx;
+
struct blk_mq_debugfs_attr {
const char *name;
umode_t mode;
diff --git a/block/blk-mq-sched.c b/block/blk-mq-sched.c
index 55488ba97823..9e56a69422b6 100644
--- a/block/blk-mq-sched.c
+++ b/block/blk-mq-sched.c
@@ -180,11 +180,18 @@ static int __blk_mq_do_dispatch_sched(struct blk_mq_hw_ctx *hctx)
static int blk_mq_do_dispatch_sched(struct blk_mq_hw_ctx *hctx)
{
+ unsigned long end = jiffies + HZ;
int ret;
do {
ret = __blk_mq_do_dispatch_sched(hctx);
- } while (ret == 1);
+ if (ret != 1)
+ break;
+ if (need_resched() || time_is_before_jiffies(end)) {
+ blk_mq_delay_run_hw_queue(hctx, 0);
+ break;
+ }
+ } while (1);
return ret;
}
@@ -515,7 +522,7 @@ static void blk_mq_exit_sched_shared_tags(struct request_queue *queue)
static void blk_mq_sched_tags_teardown(struct request_queue *q, unsigned int flags)
{
struct blk_mq_hw_ctx *hctx;
- int i;
+ unsigned long i;
queue_for_each_hw_ctx(q, hctx, i) {
if (hctx->sched_tags) {
@@ -550,9 +557,10 @@ static int blk_mq_init_sched_shared_tags(struct request_queue *queue)
int blk_mq_init_sched(struct request_queue *q, struct elevator_type *e)
{
- unsigned int i, flags = q->tag_set->flags;
+ unsigned int flags = q->tag_set->flags;
struct blk_mq_hw_ctx *hctx;
struct elevator_queue *eq;
+ unsigned long i;
int ret;
if (!e) {
@@ -618,7 +626,7 @@ err_free_map_and_rqs:
void blk_mq_sched_free_rqs(struct request_queue *q)
{
struct blk_mq_hw_ctx *hctx;
- int i;
+ unsigned long i;
if (blk_mq_is_shared_tags(q->tag_set->flags)) {
blk_mq_free_rqs(q->tag_set, q->sched_shared_tags,
@@ -635,7 +643,7 @@ void blk_mq_sched_free_rqs(struct request_queue *q)
void blk_mq_exit_sched(struct request_queue *q, struct elevator_queue *e)
{
struct blk_mq_hw_ctx *hctx;
- unsigned int i;
+ unsigned long i;
unsigned int flags = 0;
queue_for_each_hw_ctx(q, hctx, i) {
diff --git a/block/blk-mq-sysfs.c b/block/blk-mq-sysfs.c
index 674786574075..c08426975856 100644
--- a/block/blk-mq-sysfs.c
+++ b/block/blk-mq-sysfs.c
@@ -206,7 +206,7 @@ static int blk_mq_register_hctx(struct blk_mq_hw_ctx *hctx)
void blk_mq_unregister_dev(struct device *dev, struct request_queue *q)
{
struct blk_mq_hw_ctx *hctx;
- int i;
+ unsigned long i;
lockdep_assert_held(&q->sysfs_dir_lock);
@@ -255,7 +255,8 @@ void blk_mq_sysfs_init(struct request_queue *q)
int __blk_mq_register_dev(struct device *dev, struct request_queue *q)
{
struct blk_mq_hw_ctx *hctx;
- int ret, i;
+ unsigned long i, j;
+ int ret;
WARN_ON_ONCE(!q->kobj.parent);
lockdep_assert_held(&q->sysfs_dir_lock);
@@ -278,8 +279,10 @@ out:
return ret;
unreg:
- while (--i >= 0)
- blk_mq_unregister_hctx(q->queue_hw_ctx[i]);
+ queue_for_each_hw_ctx(q, hctx, j) {
+ if (j < i)
+ blk_mq_unregister_hctx(hctx);
+ }
kobject_uevent(q->mq_kobj, KOBJ_REMOVE);
kobject_del(q->mq_kobj);
@@ -290,7 +293,7 @@ unreg:
void blk_mq_sysfs_unregister(struct request_queue *q)
{
struct blk_mq_hw_ctx *hctx;
- int i;
+ unsigned long i;
mutex_lock(&q->sysfs_dir_lock);
if (!q->mq_sysfs_init_done)
@@ -306,7 +309,8 @@ unlock:
int blk_mq_sysfs_register(struct request_queue *q)
{
struct blk_mq_hw_ctx *hctx;
- int i, ret = 0;
+ unsigned long i;
+ int ret = 0;
mutex_lock(&q->sysfs_dir_lock);
if (!q->mq_sysfs_init_done)
diff --git a/block/blk-mq-tag.c b/block/blk-mq-tag.c
index 845f74e8dd7b..68ac23d0b640 100644
--- a/block/blk-mq-tag.c
+++ b/block/blk-mq-tag.c
@@ -107,7 +107,7 @@ static int __blk_mq_get_tag(struct blk_mq_alloc_data *data,
return BLK_MQ_NO_TAG;
if (data->shallow_depth)
- return __sbitmap_queue_get_shallow(bt, data->shallow_depth);
+ return sbitmap_queue_get_shallow(bt, data->shallow_depth);
else
return __sbitmap_queue_get(bt);
}
@@ -498,7 +498,7 @@ void blk_mq_queue_tag_busy_iter(struct request_queue *q, busy_tag_iter_fn *fn,
void *priv)
{
/*
- * __blk_mq_update_nr_hw_queues() updates nr_hw_queues and queue_hw_ctx
+ * __blk_mq_update_nr_hw_queues() updates nr_hw_queues and hctx_table
* while the queue is frozen. So we can use q_usage_counter to avoid
* racing with it.
*/
@@ -515,7 +515,7 @@ void blk_mq_queue_tag_busy_iter(struct request_queue *q, busy_tag_iter_fn *fn,
bt_for_each(NULL, q, btags, fn, priv, false);
} else {
struct blk_mq_hw_ctx *hctx;
- int i;
+ unsigned long i;
queue_for_each_hw_ctx(q, hctx, i) {
struct blk_mq_tags *tags = hctx->tags;
diff --git a/block/blk-mq.c b/block/blk-mq.c
index f3bf3358a3bb..8e659dc5fcf3 100644
--- a/block/blk-mq.c
+++ b/block/blk-mq.c
@@ -71,7 +71,8 @@ static int blk_mq_poll_stats_bkt(const struct request *rq)
static inline struct blk_mq_hw_ctx *blk_qc_to_hctx(struct request_queue *q,
blk_qc_t qc)
{
- return q->queue_hw_ctx[(qc & ~BLK_QC_T_INTERNAL) >> BLK_QC_T_SHIFT];
+ return xa_load(&q->hctx_table,
+ (qc & ~BLK_QC_T_INTERNAL) >> BLK_QC_T_SHIFT);
}
static inline struct request *blk_qc_to_rq(struct blk_mq_hw_ctx *hctx,
@@ -312,7 +313,7 @@ EXPORT_SYMBOL_GPL(blk_mq_unquiesce_queue);
void blk_mq_wake_waiters(struct request_queue *q)
{
struct blk_mq_hw_ctx *hctx;
- unsigned int i;
+ unsigned long i;
queue_for_each_hw_ctx(q, hctx, i)
if (blk_mq_hw_queue_mapped(hctx))
@@ -573,7 +574,7 @@ struct request *blk_mq_alloc_request_hctx(struct request_queue *q,
* If not tell the caller that it should skip this queue.
*/
ret = -EXDEV;
- data.hctx = q->queue_hw_ctx[hctx_idx];
+ data.hctx = xa_load(&q->hctx_table, hctx_idx);
if (!blk_mq_hw_queue_mapped(data.hctx))
goto out_queue_exit;
cpu = cpumask_first_and(data.hctx->cpumask, cpu_online_mask);
@@ -736,6 +737,10 @@ static void blk_complete_request(struct request *req)
/* Completion has already been traced */
bio_clear_flag(bio, BIO_TRACE_COMPLETION);
+
+ if (req_op(req) == REQ_OP_ZONE_APPEND)
+ bio->bi_iter.bi_sector = req->__sector;
+
if (!is_flush)
bio_endio(bio);
bio = next;
@@ -789,8 +794,10 @@ bool blk_update_request(struct request *req, blk_status_t error,
#endif
if (unlikely(error && !blk_rq_is_passthrough(req) &&
- !(req->rq_flags & RQF_QUIET)))
+ !(req->rq_flags & RQF_QUIET))) {
blk_print_req_error(req, error);
+ trace_block_rq_error(req, error, nr_bytes);
+ }
blk_account_io_completion(req, nr_bytes);
@@ -881,10 +888,15 @@ static inline void blk_account_io_done(struct request *req, u64 now)
static void __blk_account_io_start(struct request *rq)
{
- /* passthrough requests can hold bios that do not have ->bi_bdev set */
- if (rq->bio && rq->bio->bi_bdev)
+ /*
+ * All non-passthrough requests are created from a bio with one
+ * exception: when a flush command that is part of a flush sequence
+ * generated by the state machine in blk-flush.c is cloned onto the
+ * lower device by dm-multipath we can get here without a bio.
+ */
+ if (rq->bio)
rq->part = rq->bio->bi_bdev;
- else if (rq->q->disk)
+ else
rq->part = rq->q->disk->part0;
part_stat_lock();
@@ -1440,7 +1452,7 @@ static void blk_mq_timeout_work(struct work_struct *work)
container_of(work, struct request_queue, timeout_work);
unsigned long next = 0;
struct blk_mq_hw_ctx *hctx;
- int i;
+ unsigned long i;
/* A deadlock might occur if a request is stuck requiring a
* timeout at the same time a queue freeze is waiting
@@ -2141,7 +2153,7 @@ static struct blk_mq_hw_ctx *blk_mq_get_sq_hctx(struct request_queue *q)
void blk_mq_run_hw_queues(struct request_queue *q, bool async)
{
struct blk_mq_hw_ctx *hctx, *sq_hctx;
- int i;
+ unsigned long i;
sq_hctx = NULL;
if (blk_mq_has_sqsched(q))
@@ -2169,7 +2181,7 @@ EXPORT_SYMBOL(blk_mq_run_hw_queues);
void blk_mq_delay_run_hw_queues(struct request_queue *q, unsigned long msecs)
{
struct blk_mq_hw_ctx *hctx, *sq_hctx;
- int i;
+ unsigned long i;
sq_hctx = NULL;
if (blk_mq_has_sqsched(q))
@@ -2178,6 +2190,14 @@ void blk_mq_delay_run_hw_queues(struct request_queue *q, unsigned long msecs)
if (blk_mq_hctx_stopped(hctx))
continue;
/*
+ * If there is already a run_work pending, leave the
+ * pending delay untouched. Otherwise, a hctx can stall
+ * if another hctx is re-delaying the other's work
+ * before the work executes.
+ */
+ if (delayed_work_pending(&hctx->run_work))
+ continue;
+ /*
* Dispatch from this hctx either if there's no hctx preferred
* by IO scheduler or if it has requests that bypass the
* scheduler.
@@ -2199,7 +2219,7 @@ EXPORT_SYMBOL(blk_mq_delay_run_hw_queues);
bool blk_mq_queue_stopped(struct request_queue *q)
{
struct blk_mq_hw_ctx *hctx;
- int i;
+ unsigned long i;
queue_for_each_hw_ctx(q, hctx, i)
if (blk_mq_hctx_stopped(hctx))
@@ -2238,7 +2258,7 @@ EXPORT_SYMBOL(blk_mq_stop_hw_queue);
void blk_mq_stop_hw_queues(struct request_queue *q)
{
struct blk_mq_hw_ctx *hctx;
- int i;
+ unsigned long i;
queue_for_each_hw_ctx(q, hctx, i)
blk_mq_stop_hw_queue(hctx);
@@ -2256,7 +2276,7 @@ EXPORT_SYMBOL(blk_mq_start_hw_queue);
void blk_mq_start_hw_queues(struct request_queue *q)
{
struct blk_mq_hw_ctx *hctx;
- int i;
+ unsigned long i;
queue_for_each_hw_ctx(q, hctx, i)
blk_mq_start_hw_queue(hctx);
@@ -2276,7 +2296,7 @@ EXPORT_SYMBOL_GPL(blk_mq_start_stopped_hw_queue);
void blk_mq_start_stopped_hw_queues(struct request_queue *q, bool async)
{
struct blk_mq_hw_ctx *hctx;
- int i;
+ unsigned long i;
queue_for_each_hw_ctx(q, hctx, i)
blk_mq_start_stopped_hw_queue(hctx, async);
@@ -2557,13 +2577,36 @@ static void __blk_mq_flush_plug_list(struct request_queue *q,
q->mq_ops->queue_rqs(&plug->mq_list);
}
+static void blk_mq_dispatch_plug_list(struct blk_plug *plug, bool from_sched)
+{
+ struct blk_mq_hw_ctx *this_hctx = NULL;
+ struct blk_mq_ctx *this_ctx = NULL;
+ struct request *requeue_list = NULL;
+ unsigned int depth = 0;
+ LIST_HEAD(list);
+
+ do {
+ struct request *rq = rq_list_pop(&plug->mq_list);
+
+ if (!this_hctx) {
+ this_hctx = rq->mq_hctx;
+ this_ctx = rq->mq_ctx;
+ } else if (this_hctx != rq->mq_hctx || this_ctx != rq->mq_ctx) {
+ rq_list_add(&requeue_list, rq);
+ continue;
+ }
+ list_add_tail(&rq->queuelist, &list);
+ depth++;
+ } while (!rq_list_empty(plug->mq_list));
+
+ plug->mq_list = requeue_list;
+ trace_block_unplug(this_hctx->queue, depth, !from_sched);
+ blk_mq_sched_insert_requests(this_hctx, this_ctx, &list, from_sched);
+}
+
void blk_mq_flush_plug_list(struct blk_plug *plug, bool from_schedule)
{
- struct blk_mq_hw_ctx *this_hctx;
- struct blk_mq_ctx *this_ctx;
struct request *rq;
- unsigned int depth;
- LIST_HEAD(list);
if (rq_list_empty(plug->mq_list))
return;
@@ -2599,35 +2642,9 @@ void blk_mq_flush_plug_list(struct blk_plug *plug, bool from_schedule)
return;
}
- this_hctx = NULL;
- this_ctx = NULL;
- depth = 0;
do {
- rq = rq_list_pop(&plug->mq_list);
-
- if (!this_hctx) {
- this_hctx = rq->mq_hctx;
- this_ctx = rq->mq_ctx;
- } else if (this_hctx != rq->mq_hctx || this_ctx != rq->mq_ctx) {
- trace_block_unplug(this_hctx->queue, depth,
- !from_schedule);
- blk_mq_sched_insert_requests(this_hctx, this_ctx,
- &list, from_schedule);
- depth = 0;
- this_hctx = rq->mq_hctx;
- this_ctx = rq->mq_ctx;
-
- }
-
- list_add(&rq->queuelist, &list);
- depth++;
+ blk_mq_dispatch_plug_list(plug, from_schedule);
} while (!rq_list_empty(plug->mq_list));
-
- if (!list_empty(&list)) {
- trace_block_unplug(this_hctx->queue, depth, !from_schedule);
- blk_mq_sched_insert_requests(this_hctx, this_ctx, &list,
- from_schedule);
- }
}
void blk_mq_try_issue_list_directly(struct blk_mq_hw_ctx *hctx,
@@ -2714,7 +2731,8 @@ static bool blk_mq_attempt_bio_merge(struct request_queue *q,
static struct request *blk_mq_get_new_requests(struct request_queue *q,
struct blk_plug *plug,
- struct bio *bio)
+ struct bio *bio,
+ unsigned int nsegs)
{
struct blk_mq_alloc_data data = {
.q = q,
@@ -2726,6 +2744,11 @@ static struct request *blk_mq_get_new_requests(struct request_queue *q,
if (unlikely(bio_queue_enter(bio)))
return NULL;
+ if (blk_mq_attempt_bio_merge(q, bio, nsegs))
+ goto queue_exit;
+
+ rq_qos_throttle(q, bio);
+
if (plug) {
data.nr_tags = plug->nr_ios;
plug->nr_ios = 1;
@@ -2738,12 +2761,13 @@ static struct request *blk_mq_get_new_requests(struct request_queue *q,
rq_qos_cleanup(q, bio);
if (bio->bi_opf & REQ_NOWAIT)
bio_wouldblock_error(bio);
+queue_exit:
blk_queue_exit(q);
return NULL;
}
static inline struct request *blk_mq_get_cached_request(struct request_queue *q,
- struct blk_plug *plug, struct bio *bio)
+ struct blk_plug *plug, struct bio **bio, unsigned int nsegs)
{
struct request *rq;
@@ -2753,12 +2777,19 @@ static inline struct request *blk_mq_get_cached_request(struct request_queue *q,
if (!rq || rq->q != q)
return NULL;
- if (blk_mq_get_hctx_type(bio->bi_opf) != rq->mq_hctx->type)
+ if (blk_mq_attempt_bio_merge(q, *bio, nsegs)) {
+ *bio = NULL;
+ return NULL;
+ }
+
+ rq_qos_throttle(q, *bio);
+
+ if (blk_mq_get_hctx_type((*bio)->bi_opf) != rq->mq_hctx->type)
return NULL;
- if (op_is_flush(rq->cmd_flags) != op_is_flush(bio->bi_opf))
+ if (op_is_flush(rq->cmd_flags) != op_is_flush((*bio)->bi_opf))
return NULL;
- rq->cmd_flags = bio->bi_opf;
+ rq->cmd_flags = (*bio)->bi_opf;
plug->cached_rq = rq_list_next(rq);
INIT_LIST_HEAD(&rq->queuelist);
return rq;
@@ -2786,9 +2817,6 @@ void blk_mq_submit_bio(struct bio *bio)
unsigned int nr_segs = 1;
blk_status_t ret;
- if (unlikely(!blk_crypto_bio_prep(&bio)))
- return;
-
blk_queue_bounce(q, &bio);
if (blk_may_split(q, bio))
__blk_queue_split(q, &bio, &nr_segs);
@@ -2796,14 +2824,11 @@ void blk_mq_submit_bio(struct bio *bio)
if (!bio_integrity_prep(bio))
return;
- if (blk_mq_attempt_bio_merge(q, bio, nr_segs))
- return;
-
- rq_qos_throttle(q, bio);
-
- rq = blk_mq_get_cached_request(q, plug, bio);
+ rq = blk_mq_get_cached_request(q, plug, &bio, nr_segs);
if (!rq) {
- rq = blk_mq_get_new_requests(q, plug, bio);
+ if (!bio)
+ return;
+ rq = blk_mq_get_new_requests(q, plug, bio, nr_segs);
if (unlikely(!rq))
return;
}
@@ -2838,27 +2863,16 @@ void blk_mq_submit_bio(struct bio *bio)
blk_mq_try_issue_directly(rq->mq_hctx, rq));
}
+#ifdef CONFIG_BLK_MQ_STACKING
/**
- * blk_cloned_rq_check_limits - Helper function to check a cloned request
- * for the new queue limits
- * @q: the queue
- * @rq: the request being checked
- *
- * Description:
- * @rq may have been made based on weaker limitations of upper-level queues
- * in request stacking drivers, and it may violate the limitation of @q.
- * Since the block layer and the underlying device driver trust @rq
- * after it is inserted to @q, it should be checked against @q before
- * the insertion using this generic function.
- *
- * Request stacking drivers like request-based dm may change the queue
- * limits when retrying requests on other queues. Those requests need
- * to be checked against the new queue limits again during dispatch.
+ * blk_insert_cloned_request - Helper for stacking drivers to submit a request
+ * @rq: the request being queued
*/
-static blk_status_t blk_cloned_rq_check_limits(struct request_queue *q,
- struct request *rq)
+blk_status_t blk_insert_cloned_request(struct request *rq)
{
+ struct request_queue *q = rq->q;
unsigned int max_sectors = blk_queue_get_max_sectors(q, req_op(rq));
+ blk_status_t ret;
if (blk_rq_sectors(rq) > max_sectors) {
/*
@@ -2890,24 +2904,7 @@ static blk_status_t blk_cloned_rq_check_limits(struct request_queue *q,
return BLK_STS_IOERR;
}
- return BLK_STS_OK;
-}
-
-/**
- * blk_insert_cloned_request - Helper for stacking drivers to submit a request
- * @q: the queue to submit the request
- * @rq: the request being queued
- */
-blk_status_t blk_insert_cloned_request(struct request_queue *q, struct request *rq)
-{
- blk_status_t ret;
-
- ret = blk_cloned_rq_check_limits(q, rq);
- if (ret != BLK_STS_OK)
- return ret;
-
- if (rq->q->disk &&
- should_fail_request(rq->q->disk->part0, blk_rq_bytes(rq)))
+ if (q->disk && should_fail_request(q->disk->part0, blk_rq_bytes(rq)))
return BLK_STS_IOERR;
if (blk_crypto_insert_cloned_request(rq))
@@ -2920,8 +2917,10 @@ blk_status_t blk_insert_cloned_request(struct request_queue *q, struct request *
* bypass a potential scheduler on the bottom device for
* insert.
*/
- blk_mq_run_dispatch_ops(rq->q,
+ blk_mq_run_dispatch_ops(q,
ret = blk_mq_request_issue_directly(rq, true));
+ if (ret)
+ blk_account_io_done(rq, ktime_get_ns());
return ret;
}
EXPORT_SYMBOL_GPL(blk_insert_cloned_request);
@@ -2973,10 +2972,10 @@ int blk_rq_prep_clone(struct request *rq, struct request *rq_src,
bs = &fs_bio_set;
__rq_for_each_bio(bio_src, rq_src) {
- bio = bio_clone_fast(bio_src, gfp_mask, bs);
+ bio = bio_alloc_clone(rq->q->disk->part0, bio_src, gfp_mask,
+ bs);
if (!bio)
goto free_and_out;
- bio->bi_bdev = rq->q->disk->part0;
if (bio_ctr && bio_ctr(bio, bio_src, data))
goto free_and_out;
@@ -3013,6 +3012,7 @@ free_and_out:
return -ENOMEM;
}
EXPORT_SYMBOL_GPL(blk_rq_prep_clone);
+#endif /* CONFIG_BLK_MQ_STACKING */
/*
* Steal bios from a request and add them to a bio list.
@@ -3083,6 +3083,9 @@ void blk_mq_free_rqs(struct blk_mq_tag_set *set, struct blk_mq_tags *tags,
struct blk_mq_tags *drv_tags;
struct page *page;
+ if (list_empty(&tags->page_list))
+ return;
+
if (blk_mq_is_shared_tags(set->flags))
drv_tags = set->shared_tags;
else
@@ -3125,15 +3128,41 @@ void blk_mq_free_rq_map(struct blk_mq_tags *tags)
blk_mq_free_tags(tags);
}
+static enum hctx_type hctx_idx_to_type(struct blk_mq_tag_set *set,
+ unsigned int hctx_idx)
+{
+ int i;
+
+ for (i = 0; i < set->nr_maps; i++) {
+ unsigned int start = set->map[i].queue_offset;
+ unsigned int end = start + set->map[i].nr_queues;
+
+ if (hctx_idx >= start && hctx_idx < end)
+ break;
+ }
+
+ if (i >= set->nr_maps)
+ i = HCTX_TYPE_DEFAULT;
+
+ return i;
+}
+
+static int blk_mq_get_hctx_node(struct blk_mq_tag_set *set,
+ unsigned int hctx_idx)
+{
+ enum hctx_type type = hctx_idx_to_type(set, hctx_idx);
+
+ return blk_mq_hw_queue_to_node(&set->map[type], hctx_idx);
+}
+
static struct blk_mq_tags *blk_mq_alloc_rq_map(struct blk_mq_tag_set *set,
unsigned int hctx_idx,
unsigned int nr_tags,
unsigned int reserved_tags)
{
+ int node = blk_mq_get_hctx_node(set, hctx_idx);
struct blk_mq_tags *tags;
- int node;
- node = blk_mq_hw_queue_to_node(&set->map[HCTX_TYPE_DEFAULT], hctx_idx);
if (node == NUMA_NO_NODE)
node = set->numa_node;
@@ -3182,10 +3211,9 @@ static int blk_mq_alloc_rqs(struct blk_mq_tag_set *set,
unsigned int hctx_idx, unsigned int depth)
{
unsigned int i, j, entries_per_page, max_order = 4;
+ int node = blk_mq_get_hctx_node(set, hctx_idx);
size_t rq_size, left;
- int node;
- node = blk_mq_hw_queue_to_node(&set->map[HCTX_TYPE_DEFAULT], hctx_idx);
if (node == NUMA_NO_NODE)
node = set->numa_node;
@@ -3430,6 +3458,8 @@ static void blk_mq_exit_hctx(struct request_queue *q,
blk_mq_remove_cpuhp(hctx);
+ xa_erase(&q->hctx_table, hctx_idx);
+
spin_lock(&q->unused_hctx_lock);
list_add(&hctx->hctx_list, &q->unused_hctx_list);
spin_unlock(&q->unused_hctx_lock);
@@ -3439,12 +3469,11 @@ static void blk_mq_exit_hw_queues(struct request_queue *q,
struct blk_mq_tag_set *set, int nr_queue)
{
struct blk_mq_hw_ctx *hctx;
- unsigned int i;
+ unsigned long i;
queue_for_each_hw_ctx(q, hctx, i) {
if (i == nr_queue)
break;
- blk_mq_debugfs_unregister_hctx(hctx);
blk_mq_exit_hctx(q, set, hctx, i);
}
}
@@ -3469,8 +3498,15 @@ static int blk_mq_init_hctx(struct request_queue *q,
if (blk_mq_init_request(set, hctx->fq->flush_rq, hctx_idx,
hctx->numa_node))
goto exit_hctx;
+
+ if (xa_insert(&q->hctx_table, hctx_idx, hctx, GFP_KERNEL))
+ goto exit_flush_rq;
+
return 0;
+ exit_flush_rq:
+ if (set->ops->exit_request)
+ set->ops->exit_request(set, hctx->fq->flush_rq, hctx_idx);
exit_hctx:
if (set->ops->exit_hctx)
set->ops->exit_hctx(hctx, hctx_idx);
@@ -3630,7 +3666,8 @@ static void __blk_mq_free_map_and_rqs(struct blk_mq_tag_set *set,
static void blk_mq_map_swqueue(struct request_queue *q)
{
- unsigned int i, j, hctx_idx;
+ unsigned int j, hctx_idx;
+ unsigned long i;
struct blk_mq_hw_ctx *hctx;
struct blk_mq_ctx *ctx;
struct blk_mq_tag_set *set = q->tag_set;
@@ -3737,7 +3774,7 @@ static void blk_mq_map_swqueue(struct request_queue *q)
static void queue_set_hctx_shared(struct request_queue *q, bool shared)
{
struct blk_mq_hw_ctx *hctx;
- int i;
+ unsigned long i;
queue_for_each_hw_ctx(q, hctx, i) {
if (shared) {
@@ -3837,7 +3874,7 @@ static int blk_mq_alloc_ctxs(struct request_queue *q)
void blk_mq_release(struct request_queue *q)
{
struct blk_mq_hw_ctx *hctx, *next;
- int i;
+ unsigned long i;
queue_for_each_hw_ctx(q, hctx, i)
WARN_ON_ONCE(hctx && list_empty(&hctx->hctx_list));
@@ -3848,7 +3885,7 @@ void blk_mq_release(struct request_queue *q)
kobject_put(&hctx->kobj);
}
- kfree(q->queue_hw_ctx);
+ xa_destroy(&q->hctx_table);
/*
* release .mq_kobj and sw queue's kobject now because
@@ -3937,52 +3974,28 @@ static struct blk_mq_hw_ctx *blk_mq_alloc_and_init_hctx(
static void blk_mq_realloc_hw_ctxs(struct blk_mq_tag_set *set,
struct request_queue *q)
{
- int i, j, end;
- struct blk_mq_hw_ctx **hctxs = q->queue_hw_ctx;
-
- if (q->nr_hw_queues < set->nr_hw_queues) {
- struct blk_mq_hw_ctx **new_hctxs;
-
- new_hctxs = kcalloc_node(set->nr_hw_queues,
- sizeof(*new_hctxs), GFP_KERNEL,
- set->numa_node);
- if (!new_hctxs)
- return;
- if (hctxs)
- memcpy(new_hctxs, hctxs, q->nr_hw_queues *
- sizeof(*hctxs));
- q->queue_hw_ctx = new_hctxs;
- kfree(hctxs);
- hctxs = new_hctxs;
- }
+ struct blk_mq_hw_ctx *hctx;
+ unsigned long i, j;
/* protect against switching io scheduler */
mutex_lock(&q->sysfs_lock);
for (i = 0; i < set->nr_hw_queues; i++) {
- int node;
- struct blk_mq_hw_ctx *hctx;
+ int old_node;
+ int node = blk_mq_get_hctx_node(set, i);
+ struct blk_mq_hw_ctx *old_hctx = xa_load(&q->hctx_table, i);
- node = blk_mq_hw_queue_to_node(&set->map[HCTX_TYPE_DEFAULT], i);
- /*
- * If the hw queue has been mapped to another numa node,
- * we need to realloc the hctx. If allocation fails, fallback
- * to use the previous one.
- */
- if (hctxs[i] && (hctxs[i]->numa_node == node))
- continue;
+ if (old_hctx) {
+ old_node = old_hctx->numa_node;
+ blk_mq_exit_hctx(q, set, old_hctx, i);
+ }
- hctx = blk_mq_alloc_and_init_hctx(set, q, i, node);
- if (hctx) {
- if (hctxs[i])
- blk_mq_exit_hctx(q, set, hctxs[i], i);
- hctxs[i] = hctx;
- } else {
- if (hctxs[i])
- pr_warn("Allocate new hctx on node %d fails,\
- fallback to previous one on node %d\n",
- node, hctxs[i]->numa_node);
- else
+ if (!blk_mq_alloc_and_init_hctx(set, q, i, node)) {
+ if (!old_hctx)
break;
+ pr_warn("Allocate new hctx on node %d fails, fallback to previous one on node %d\n",
+ node, old_node);
+ hctx = blk_mq_alloc_and_init_hctx(set, q, i, old_node);
+ WARN_ON_ONCE(!hctx);
}
}
/*
@@ -3991,24 +4004,27 @@ static void blk_mq_realloc_hw_ctxs(struct blk_mq_tag_set *set,
*/
if (i != set->nr_hw_queues) {
j = q->nr_hw_queues;
- end = i;
} else {
j = i;
- end = q->nr_hw_queues;
q->nr_hw_queues = set->nr_hw_queues;
}
- for (; j < end; j++) {
- struct blk_mq_hw_ctx *hctx = hctxs[j];
-
- if (hctx) {
- blk_mq_exit_hctx(q, set, hctx, j);
- hctxs[j] = NULL;
- }
- }
+ xa_for_each_start(&q->hctx_table, j, hctx, j)
+ blk_mq_exit_hctx(q, set, hctx, j);
mutex_unlock(&q->sysfs_lock);
}
+static void blk_mq_update_poll_flag(struct request_queue *q)
+{
+ struct blk_mq_tag_set *set = q->tag_set;
+
+ if (set->nr_maps > HCTX_TYPE_POLL &&
+ set->map[HCTX_TYPE_POLL].nr_queues)
+ blk_queue_flag_set(QUEUE_FLAG_POLL, q);
+ else
+ blk_queue_flag_clear(QUEUE_FLAG_POLL, q);
+}
+
int blk_mq_init_allocated_queue(struct blk_mq_tag_set *set,
struct request_queue *q)
{
@@ -4033,6 +4049,8 @@ int blk_mq_init_allocated_queue(struct blk_mq_tag_set *set,
INIT_LIST_HEAD(&q->unused_hctx_list);
spin_lock_init(&q->unused_hctx_lock);
+ xa_init(&q->hctx_table);
+
blk_mq_realloc_hw_ctxs(set, q);
if (!q->nr_hw_queues)
goto err_hctxs;
@@ -4043,9 +4061,7 @@ int blk_mq_init_allocated_queue(struct blk_mq_tag_set *set,
q->tag_set = set;
q->queue_flags |= QUEUE_FLAG_MQ_DEFAULT;
- if (set->nr_maps > HCTX_TYPE_POLL &&
- set->map[HCTX_TYPE_POLL].nr_queues)
- blk_queue_flag_set(QUEUE_FLAG_POLL, q);
+ blk_mq_update_poll_flag(q);
INIT_DELAYED_WORK(&q->requeue_work, blk_mq_requeue_work);
INIT_LIST_HEAD(&q->requeue_list);
@@ -4064,7 +4080,7 @@ int blk_mq_init_allocated_queue(struct blk_mq_tag_set *set,
return 0;
err_hctxs:
- kfree(q->queue_hw_ctx);
+ xa_destroy(&q->hctx_table);
q->nr_hw_queues = 0;
blk_mq_sysfs_deinit(q);
err_poll:
@@ -4352,7 +4368,8 @@ int blk_mq_update_nr_requests(struct request_queue *q, unsigned int nr)
{
struct blk_mq_tag_set *set = q->tag_set;
struct blk_mq_hw_ctx *hctx;
- int i, ret;
+ int ret;
+ unsigned long i;
if (!set)
return -EINVAL;
@@ -4511,6 +4528,7 @@ fallback:
blk_mq_update_queue_map(set);
list_for_each_entry(q, &set->tag_list, tag_set_list) {
blk_mq_realloc_hw_ctxs(set, q);
+ blk_mq_update_poll_flag(q);
if (q->nr_hw_queues != set->nr_hw_queues) {
int i = prev_nr_hw_queues;
@@ -4727,7 +4745,7 @@ void blk_mq_cancel_work_sync(struct request_queue *q)
{
if (queue_is_mq(q)) {
struct blk_mq_hw_ctx *hctx;
- int i;
+ unsigned long i;
cancel_delayed_work_sync(&q->requeue_work);
diff --git a/block/blk-mq.h b/block/blk-mq.h
index 948791ea2a3e..2615bd58bad3 100644
--- a/block/blk-mq.h
+++ b/block/blk-mq.h
@@ -83,7 +83,7 @@ static inline struct blk_mq_hw_ctx *blk_mq_map_queue_type(struct request_queue *
enum hctx_type type,
unsigned int cpu)
{
- return q->queue_hw_ctx[q->tag_set->map[type].mq_map[cpu]];
+ return xa_load(&q->hctx_table, q->tag_set->map[type].mq_map[cpu]);
}
static inline enum hctx_type blk_mq_get_hctx_type(unsigned int flags)
diff --git a/block/blk-rq-qos.h b/block/blk-rq-qos.h
index 3cfbc8668cba..68267007da1c 100644
--- a/block/blk-rq-qos.h
+++ b/block/blk-rq-qos.h
@@ -177,20 +177,20 @@ static inline void rq_qos_requeue(struct request_queue *q, struct request *rq)
__rq_qos_requeue(q->rq_qos, rq);
}
-static inline void rq_qos_done_bio(struct request_queue *q, struct bio *bio)
+static inline void rq_qos_done_bio(struct bio *bio)
{
- if (q->rq_qos)
- __rq_qos_done_bio(q->rq_qos, bio);
+ if (bio->bi_bdev && (bio_flagged(bio, BIO_QOS_THROTTLED) ||
+ bio_flagged(bio, BIO_QOS_MERGED))) {
+ struct request_queue *q = bdev_get_queue(bio->bi_bdev);
+ if (q->rq_qos)
+ __rq_qos_done_bio(q->rq_qos, bio);
+ }
}
static inline void rq_qos_throttle(struct request_queue *q, struct bio *bio)
{
- /*
- * BIO_TRACKED lets controllers know that a bio went through the
- * normal rq_qos path.
- */
if (q->rq_qos) {
- bio_set_flag(bio, BIO_TRACKED);
+ bio_set_flag(bio, BIO_QOS_THROTTLED);
__rq_qos_throttle(q->rq_qos, bio);
}
}
@@ -205,8 +205,10 @@ static inline void rq_qos_track(struct request_queue *q, struct request *rq,
static inline void rq_qos_merge(struct request_queue *q, struct request *rq,
struct bio *bio)
{
- if (q->rq_qos)
+ if (q->rq_qos) {
+ bio_set_flag(bio, BIO_QOS_MERGED);
__rq_qos_merge(q->rq_qos, rq, bio);
+ }
}
static inline void rq_qos_queue_depth_changed(struct request_queue *q)
diff --git a/block/blk-sysfs.c b/block/blk-sysfs.c
index 5e81e65574a0..88bd41d4cb59 100644
--- a/block/blk-sysfs.c
+++ b/block/blk-sysfs.c
@@ -10,7 +10,6 @@
#include <linux/backing-dev.h>
#include <linux/blktrace_api.h>
#include <linux/blk-mq.h>
-#include <linux/blk-cgroup.h>
#include <linux/debugfs.h>
#include "blk.h"
@@ -18,6 +17,7 @@
#include "blk-mq-debugfs.h"
#include "blk-mq-sched.h"
#include "blk-wbt.h"
+#include "blk-cgroup.h"
#include "blk-throttle.h"
struct queue_sysfs_entry {
@@ -738,27 +738,6 @@ static void blk_free_queue_rcu(struct rcu_head *rcu_head)
kmem_cache_free(blk_get_queue_kmem_cache(blk_queue_has_srcu(q)), q);
}
-/* Unconfigure the I/O scheduler and dissociate from the cgroup controller. */
-static void blk_exit_queue(struct request_queue *q)
-{
- /*
- * Since the I/O scheduler exit code may access cgroup information,
- * perform I/O scheduler exit before disassociating from the block
- * cgroup controller.
- */
- if (q->elevator) {
- ioc_clear_queue(q);
- elevator_exit(q);
- }
-
- /*
- * Remove all references to @q from the block cgroup controller before
- * restoring @q->queue_lock to avoid that restoring this pointer causes
- * e.g. blkcg_print_blkgs() to crash.
- */
- blkcg_exit_queue(q);
-}
-
/**
* blk_release_queue - releases all allocated resources of the request_queue
* @kobj: pointer to a kobject, whose container is a request_queue
@@ -786,12 +765,12 @@ static void blk_release_queue(struct kobject *kobj)
might_sleep();
+ percpu_ref_exit(&q->q_usage_counter);
+
if (q->poll_stat)
blk_stat_remove_callback(q, q->poll_cb);
blk_stat_free_callback(q->poll_cb);
- blk_exit_queue(q);
-
blk_free_queue_stats(q->stats);
kfree(q->poll_stat);
@@ -879,6 +858,10 @@ int blk_register_queue(struct gendisk *disk)
goto put_dev;
}
+ ret = blk_crypto_sysfs_register(q);
+ if (ret)
+ goto put_dev;
+
blk_queue_flag_set(QUEUE_FLAG_REGISTERED, q);
wbt_enable_default(q);
blk_throtl_register_queue(q);
@@ -909,6 +892,7 @@ unlock:
return ret;
put_dev:
+ elv_unregister_queue(q);
disk_unregister_independent_access_ranges(disk);
mutex_unlock(&q->sysfs_lock);
mutex_unlock(&q->sysfs_dir_lock);
@@ -953,16 +937,18 @@ void blk_unregister_queue(struct gendisk *disk)
*/
if (queue_is_mq(q))
blk_mq_unregister_dev(disk_to_dev(disk), q);
-
- kobject_uevent(&q->kobj, KOBJ_REMOVE);
- kobject_del(&q->kobj);
+ blk_crypto_sysfs_unregister(q);
blk_trace_remove_sysfs(disk_to_dev(disk));
mutex_lock(&q->sysfs_lock);
- if (q->elevator)
- elv_unregister_queue(q);
+ elv_unregister_queue(q);
disk_unregister_independent_access_ranges(disk);
mutex_unlock(&q->sysfs_lock);
+
+ /* Now that we've deleted all child objects, we can delete the queue. */
+ kobject_uevent(&q->kobj, KOBJ_REMOVE);
+ kobject_del(&q->kobj);
+
mutex_unlock(&q->sysfs_dir_lock);
kobject_put(&disk_to_dev(disk)->kobj);
diff --git a/block/blk-throttle.c b/block/blk-throttle.c
index 7c462c006b26..469c483719be 100644
--- a/block/blk-throttle.c
+++ b/block/blk-throttle.c
@@ -10,7 +10,6 @@
#include <linux/blkdev.h>
#include <linux/bio.h>
#include <linux/blktrace_api.h>
-#include <linux/blk-cgroup.h>
#include "blk.h"
#include "blk-cgroup-rwstat.h"
#include "blk-stat.h"
@@ -42,11 +41,6 @@
/* A workqueue to queue throttle related work */
static struct workqueue_struct *kthrotld_workqueue;
-enum tg_state_flags {
- THROTL_TG_PENDING = 1 << 0, /* on parent's pending tree */
- THROTL_TG_WAS_EMPTY = 1 << 1, /* bio_lists[] became non-empty */
-};
-
#define rb_entry_tg(node) rb_entry((node), struct throtl_grp, rb_node)
/* We measure latency for request size from <= 4k to >= 1M */
@@ -426,12 +420,24 @@ static void tg_update_has_rules(struct throtl_grp *tg)
struct throtl_grp *parent_tg = sq_to_tg(tg->service_queue.parent_sq);
struct throtl_data *td = tg->td;
int rw;
+ int has_iops_limit = 0;
+
+ for (rw = READ; rw <= WRITE; rw++) {
+ unsigned int iops_limit = tg_iops_limit(tg, rw);
- for (rw = READ; rw <= WRITE; rw++)
tg->has_rules[rw] = (parent_tg && parent_tg->has_rules[rw]) ||
(td->limit_valid[td->limit_index] &&
(tg_bps_limit(tg, rw) != U64_MAX ||
- tg_iops_limit(tg, rw) != UINT_MAX));
+ iops_limit != UINT_MAX));
+
+ if (iops_limit != UINT_MAX)
+ has_iops_limit = 1;
+ }
+
+ if (has_iops_limit)
+ tg->flags |= THROTL_TG_HAS_IOPS_LIMIT;
+ else
+ tg->flags &= ~THROTL_TG_HAS_IOPS_LIMIT;
}
static void throtl_pd_online(struct blkg_policy_data *pd)
@@ -634,8 +640,6 @@ static inline void throtl_start_new_slice_with_credit(struct throtl_grp *tg,
tg->bytes_disp[rw] = 0;
tg->io_disp[rw] = 0;
- atomic_set(&tg->io_split_cnt[rw], 0);
-
/*
* Previous slice has expired. We must have trimmed it after last
* bio dispatch. That means since start of last slice, we never used
@@ -659,8 +663,6 @@ static inline void throtl_start_new_slice(struct throtl_grp *tg, bool rw)
tg->slice_start[rw] = jiffies;
tg->slice_end[rw] = jiffies + tg->td->throtl_slice;
- atomic_set(&tg->io_split_cnt[rw], 0);
-
throtl_log(&tg->service_queue,
"[%c] new slice start=%lu end=%lu jiffies=%lu",
rw == READ ? 'R' : 'W', tg->slice_start[rw],
@@ -808,7 +810,8 @@ static bool tg_with_in_bps_limit(struct throtl_grp *tg, struct bio *bio,
unsigned long jiffy_elapsed, jiffy_wait, jiffy_elapsed_rnd;
unsigned int bio_size = throtl_bio_data_size(bio);
- if (bps_limit == U64_MAX) {
+ /* no need to throttle if this bio's bytes have been accounted */
+ if (bps_limit == U64_MAX || bio_flagged(bio, BIO_THROTTLED)) {
if (wait)
*wait = 0;
return true;
@@ -871,7 +874,8 @@ static bool tg_may_dispatch(struct throtl_grp *tg, struct bio *bio,
bio != throtl_peek_queued(&tg->service_queue.queued[rw]));
/* If tg->bps = -1, then BW is unlimited */
- if (bps_limit == U64_MAX && iops_limit == UINT_MAX) {
+ if ((bps_limit == U64_MAX && iops_limit == UINT_MAX) ||
+ tg->flags & THROTL_TG_CANCELING) {
if (wait)
*wait = 0;
return true;
@@ -893,9 +897,6 @@ static bool tg_may_dispatch(struct throtl_grp *tg, struct bio *bio,
jiffies + tg->td->throtl_slice);
}
- if (iops_limit != UINT_MAX)
- tg->io_disp[rw] += atomic_xchg(&tg->io_split_cnt[rw], 0);
-
if (tg_with_in_bps_limit(tg, bio, bps_limit, &bps_wait) &&
tg_with_in_iops_limit(tg, bio, iops_limit, &iops_wait)) {
if (wait)
@@ -920,9 +921,12 @@ static void throtl_charge_bio(struct throtl_grp *tg, struct bio *bio)
unsigned int bio_size = throtl_bio_data_size(bio);
/* Charge the bio to the group */
- tg->bytes_disp[rw] += bio_size;
+ if (!bio_flagged(bio, BIO_THROTTLED)) {
+ tg->bytes_disp[rw] += bio_size;
+ tg->last_bytes_disp[rw] += bio_size;
+ }
+
tg->io_disp[rw]++;
- tg->last_bytes_disp[rw] += bio_size;
tg->last_io_disp[rw]++;
/*
@@ -1134,12 +1138,22 @@ static void throtl_pending_timer_fn(struct timer_list *t)
struct throtl_service_queue *sq = from_timer(sq, t, pending_timer);
struct throtl_grp *tg = sq_to_tg(sq);
struct throtl_data *td = sq_to_td(sq);
- struct request_queue *q = td->queue;
struct throtl_service_queue *parent_sq;
+ struct request_queue *q;
bool dispatched;
int ret;
+ /* throtl_data may be gone, so figure out request queue by blkg */
+ if (tg)
+ q = tg->pd.blkg->q;
+ else
+ q = td->queue;
+
spin_lock_irq(&q->queue_lock);
+
+ if (!q->root_blkg)
+ goto out_unlock;
+
if (throtl_can_upgrade(td, NULL))
throtl_upgrade_state(td);
@@ -1219,7 +1233,7 @@ static void blk_throtl_dispatch_work_fn(struct work_struct *work)
if (!bio_list_empty(&bio_list_on_stack)) {
blk_start_plug(&plug);
while ((bio = bio_list_pop(&bio_list_on_stack)))
- submit_bio_noacct(bio);
+ submit_bio_noacct_nocheck(bio);
blk_finish_plug(&plug);
}
}
@@ -1763,6 +1777,39 @@ static bool throtl_hierarchy_can_upgrade(struct throtl_grp *tg)
return false;
}
+void blk_throtl_cancel_bios(struct request_queue *q)
+{
+ struct cgroup_subsys_state *pos_css;
+ struct blkcg_gq *blkg;
+
+ spin_lock_irq(&q->queue_lock);
+ /*
+ * queue_lock is held, rcu lock is not needed here technically.
+ * However, rcu lock is still held to emphasize that following
+ * path need RCU protection and to prevent warning from lockdep.
+ */
+ rcu_read_lock();
+ blkg_for_each_descendant_post(blkg, pos_css, q->root_blkg) {
+ struct throtl_grp *tg = blkg_to_tg(blkg);
+ struct throtl_service_queue *sq = &tg->service_queue;
+
+ /*
+ * Set the flag to make sure throtl_pending_timer_fn() won't
+ * stop until all throttled bios are dispatched.
+ */
+ blkg_to_tg(blkg)->flags |= THROTL_TG_CANCELING;
+ /*
+ * Update disptime after setting the above flag to make sure
+ * throtl_select_dispatch() won't exit without dispatching.
+ */
+ tg_update_disptime(tg);
+
+ throtl_schedule_pending_timer(sq, jiffies + 1);
+ }
+ rcu_read_unlock();
+ spin_unlock_irq(&q->queue_lock);
+}
+
static bool throtl_can_upgrade(struct throtl_data *td,
struct throtl_grp *this_tg)
{
@@ -1917,14 +1964,12 @@ static void throtl_downgrade_check(struct throtl_grp *tg)
}
if (tg->iops[READ][LIMIT_LOW]) {
- tg->last_io_disp[READ] += atomic_xchg(&tg->last_io_split_cnt[READ], 0);
iops = tg->last_io_disp[READ] * HZ / elapsed_time;
if (iops >= tg->iops[READ][LIMIT_LOW])
tg->last_low_overflow_time[READ] = now;
}
if (tg->iops[WRITE][LIMIT_LOW]) {
- tg->last_io_disp[WRITE] += atomic_xchg(&tg->last_io_split_cnt[WRITE], 0);
iops = tg->last_io_disp[WRITE] * HZ / elapsed_time;
if (iops >= tg->iops[WRITE][LIMIT_LOW])
tg->last_low_overflow_time[WRITE] = now;
@@ -2043,25 +2088,6 @@ static inline void throtl_update_latency_buckets(struct throtl_data *td)
}
#endif
-void blk_throtl_charge_bio_split(struct bio *bio)
-{
- struct blkcg_gq *blkg = bio->bi_blkg;
- struct throtl_grp *parent = blkg_to_tg(blkg);
- struct throtl_service_queue *parent_sq;
- bool rw = bio_data_dir(bio);
-
- do {
- if (!parent->has_rules[rw])
- break;
-
- atomic_inc(&parent->io_split_cnt[rw]);
- atomic_inc(&parent->last_io_split_cnt[rw]);
-
- parent_sq = parent->service_queue.parent_sq;
- parent = sq_to_tg(parent_sq);
- } while (parent);
-}
-
bool __blk_throtl_bio(struct bio *bio)
{
struct request_queue *q = bdev_get_queue(bio->bi_bdev);
diff --git a/block/blk-throttle.h b/block/blk-throttle.h
index 175f03abd9e4..c1b602996127 100644
--- a/block/blk-throttle.h
+++ b/block/blk-throttle.h
@@ -52,6 +52,13 @@ struct throtl_service_queue {
struct timer_list pending_timer; /* fires on first_pending_disptime */
};
+enum tg_state_flags {
+ THROTL_TG_PENDING = 1 << 0, /* on parent's pending tree */
+ THROTL_TG_WAS_EMPTY = 1 << 1, /* bio_lists[] became non-empty */
+ THROTL_TG_HAS_IOPS_LIMIT = 1 << 2, /* tg has iops limit */
+ THROTL_TG_CANCELING = 1 << 3, /* starts to cancel bio */
+};
+
enum {
LIMIT_LOW,
LIMIT_MAX,
@@ -132,9 +139,6 @@ struct throtl_grp {
unsigned int bad_bio_cnt; /* bios exceeding latency threshold */
unsigned long bio_cnt_reset_time;
- atomic_t io_split_cnt[2];
- atomic_t last_io_split_cnt[2];
-
struct blkg_rwstat stat_bytes;
struct blkg_rwstat stat_ios;
};
@@ -158,20 +162,23 @@ static inline struct throtl_grp *blkg_to_tg(struct blkcg_gq *blkg)
static inline int blk_throtl_init(struct request_queue *q) { return 0; }
static inline void blk_throtl_exit(struct request_queue *q) { }
static inline void blk_throtl_register_queue(struct request_queue *q) { }
-static inline void blk_throtl_charge_bio_split(struct bio *bio) { }
static inline bool blk_throtl_bio(struct bio *bio) { return false; }
+static inline void blk_throtl_cancel_bios(struct request_queue *q) { }
#else /* CONFIG_BLK_DEV_THROTTLING */
int blk_throtl_init(struct request_queue *q);
void blk_throtl_exit(struct request_queue *q);
void blk_throtl_register_queue(struct request_queue *q);
-void blk_throtl_charge_bio_split(struct bio *bio);
bool __blk_throtl_bio(struct bio *bio);
+void blk_throtl_cancel_bios(struct request_queue *q);
static inline bool blk_throtl_bio(struct bio *bio)
{
struct throtl_grp *tg = blkg_to_tg(bio->bi_blkg);
- if (bio_flagged(bio, BIO_THROTTLED))
+ /* no need to throttle bps any more if the bio has been throttled */
+ if (bio_flagged(bio, BIO_THROTTLED) &&
+ !(tg->flags & THROTL_TG_HAS_IOPS_LIMIT))
return false;
+
if (!tg->has_rules[bio_data_dir(bio)])
return false;
diff --git a/block/blk-zoned.c b/block/blk-zoned.c
index 61fb6c52f4f3..38cd840d8838 100644
--- a/block/blk-zoned.c
+++ b/block/blk-zoned.c
@@ -214,9 +214,8 @@ static int blkdev_zone_reset_all_emulated(struct block_device *bdev,
continue;
}
- bio = blk_next_bio(bio, 0, gfp_mask);
- bio_set_dev(bio, bdev);
- bio->bi_opf = REQ_OP_ZONE_RESET | REQ_SYNC;
+ bio = blk_next_bio(bio, bdev, 0, REQ_OP_ZONE_RESET | REQ_SYNC,
+ gfp_mask);
bio->bi_iter.bi_sector = sector;
sector += zone_sectors;
@@ -238,10 +237,7 @@ static int blkdev_zone_reset_all(struct block_device *bdev, gfp_t gfp_mask)
{
struct bio bio;
- bio_init(&bio, NULL, 0);
- bio_set_dev(&bio, bdev);
- bio.bi_opf = REQ_OP_ZONE_RESET_ALL | REQ_SYNC;
-
+ bio_init(&bio, bdev, NULL, 0, REQ_OP_ZONE_RESET_ALL | REQ_SYNC);
return submit_bio_wait(&bio);
}
@@ -305,9 +301,7 @@ int blkdev_zone_mgmt(struct block_device *bdev, enum req_opf op,
}
while (sector < end_sector) {
- bio = blk_next_bio(bio, 0, gfp_mask);
- bio_set_dev(bio, bdev);
- bio->bi_opf = op | REQ_SYNC;
+ bio = blk_next_bio(bio, bdev, 0, op | REQ_SYNC, gfp_mask);
bio->bi_iter.bi_sector = sector;
sector += zone_sectors;
diff --git a/block/blk.h b/block/blk.h
index c6f8c0ca569f..8ccbc6e07636 100644
--- a/block/blk.h
+++ b/block/blk.h
@@ -46,7 +46,7 @@ void blk_freeze_queue(struct request_queue *q);
void __blk_mq_unfreeze_queue(struct request_queue *q, bool force_atomic);
void blk_queue_start_drain(struct request_queue *q);
int __bio_queue_enter(struct request_queue *q, struct bio *bio);
-bool submit_bio_checks(struct bio *bio);
+void submit_bio_noacct_nocheck(struct bio *bio);
static inline bool blk_try_enter_queue(struct request_queue *q, bool pm)
{
@@ -324,7 +324,7 @@ int blk_dev_init(void);
*/
static inline bool blk_do_io_stat(struct request *rq)
{
- return (rq->rq_flags & RQF_IO_STAT) && rq->q->disk;
+ return (rq->rq_flags & RQF_IO_STAT) && !blk_rq_is_passthrough(rq);
}
void update_io_ticks(struct block_device *part, unsigned long now, bool end);
@@ -405,8 +405,6 @@ extern int blk_iolatency_init(struct request_queue *q);
static inline int blk_iolatency_init(struct request_queue *q) { return 0; }
#endif
-struct bio *blk_next_bio(struct bio *bio, unsigned int nr_pages, gfp_t gfp);
-
#ifdef CONFIG_BLK_DEV_ZONED
void blk_queue_free_zone_bitmaps(struct request_queue *q);
void blk_queue_clear_zone_settings(struct request_queue *q);
@@ -425,6 +423,7 @@ int bdev_add_partition(struct gendisk *disk, int partno, sector_t start,
int bdev_del_partition(struct gendisk *disk, int partno);
int bdev_resize_partition(struct gendisk *disk, int partno, sector_t start,
sector_t length);
+void blk_drop_partitions(struct gendisk *disk);
int bio_add_hw_page(struct request_queue *q, struct bio *bio,
struct page *page, unsigned int len, unsigned int offset,
@@ -444,6 +443,9 @@ int disk_alloc_events(struct gendisk *disk);
void disk_add_events(struct gendisk *disk);
void disk_del_events(struct gendisk *disk);
void disk_release_events(struct gendisk *disk);
+void disk_block_events(struct gendisk *disk);
+void disk_unblock_events(struct gendisk *disk);
+void disk_flush_events(struct gendisk *disk, unsigned int mask);
extern struct device_attribute dev_attr_events;
extern struct device_attribute dev_attr_events_async;
extern struct device_attribute dev_attr_events_poll_msecs;
diff --git a/block/bounce.c b/block/bounce.c
index 510360559276..2d32ff6a0f12 100644
--- a/block/bounce.c
+++ b/block/bounce.c
@@ -14,7 +14,6 @@
#include <linux/pagemap.h>
#include <linux/mempool.h>
#include <linux/blkdev.h>
-#include <linux/blk-cgroup.h>
#include <linux/backing-dev.h>
#include <linux/init.h>
#include <linux/hash.h>
@@ -24,6 +23,7 @@
#include <trace/events/block.h>
#include "blk.h"
+#include "blk-cgroup.h"
#define POOL_SIZE 64
#define ISA_POOL_SIZE 16
@@ -162,15 +162,12 @@ static struct bio *bounce_clone_bio(struct bio *bio_src)
* that does not own the bio - reason being drivers don't use it for
* iterating over the biovec anymore, so expecting it to be kept up
* to date (i.e. for clones that share the parent biovec) is just
- * asking for trouble and would force extra work on
- * __bio_clone_fast() anyways.
+ * asking for trouble and would force extra work.
*/
- bio = bio_alloc_bioset(GFP_NOIO, bio_segments(bio_src),
- &bounce_bio_set);
- bio->bi_bdev = bio_src->bi_bdev;
+ bio = bio_alloc_bioset(bio_src->bi_bdev, bio_segments(bio_src),
+ bio_src->bi_opf, GFP_NOIO, &bounce_bio_set);
if (bio_flagged(bio_src, BIO_REMAPPED))
bio_set_flag(bio, BIO_REMAPPED);
- bio->bi_opf = bio_src->bi_opf;
bio->bi_ioprio = bio_src->bi_ioprio;
bio->bi_write_hint = bio_src->bi_write_hint;
bio->bi_iter.bi_sector = bio_src->bi_iter.bi_sector;
diff --git a/block/disk-events.c b/block/disk-events.c
index 8d5496e7592a..aee25a7e1ab7 100644
--- a/block/disk-events.c
+++ b/block/disk-events.c
@@ -4,7 +4,7 @@
*/
#include <linux/export.h>
#include <linux/moduleparam.h>
-#include <linux/genhd.h>
+#include <linux/blkdev.h>
#include "blk.h"
struct disk_events {
diff --git a/block/elevator.c b/block/elevator.c
index ec98aed39c4f..c319765892bb 100644
--- a/block/elevator.c
+++ b/block/elevator.c
@@ -35,7 +35,6 @@
#include <linux/hash.h>
#include <linux/uaccess.h>
#include <linux/pm_runtime.h>
-#include <linux/blk-cgroup.h>
#include <trace/events/block.h>
@@ -44,6 +43,7 @@
#include "blk-mq-sched.h"
#include "blk-pm.h"
#include "blk-wbt.h"
+#include "blk-cgroup.h"
static DEFINE_SPINLOCK(elv_list_lock);
static LIST_HEAD(elv_list);
@@ -192,6 +192,9 @@ void elevator_exit(struct request_queue *q)
{
struct elevator_queue *e = q->elevator;
+ ioc_clear_queue(q);
+ blk_mq_sched_free_rqs(q);
+
mutex_lock(&e->sysfs_lock);
blk_mq_exit_sched(q, e);
mutex_unlock(&e->sysfs_lock);
@@ -516,17 +519,17 @@ int elv_register_queue(struct request_queue *q, bool uevent)
void elv_unregister_queue(struct request_queue *q)
{
+ struct elevator_queue *e = q->elevator;
+
lockdep_assert_held(&q->sysfs_lock);
- if (q) {
+ if (e && e->registered) {
struct elevator_queue *e = q->elevator;
kobject_uevent(&e->kobj, KOBJ_REMOVE);
kobject_del(&e->kobj);
e->registered = 0;
- /* Re-enable throttling in case elevator disabled it */
- wbt_enable_default(q);
}
}
@@ -593,11 +596,7 @@ int elevator_switch_mq(struct request_queue *q,
lockdep_assert_held(&q->sysfs_lock);
if (q->elevator) {
- if (q->elevator->registered)
- elv_unregister_queue(q);
-
- ioc_clear_queue(q);
- blk_mq_sched_free_rqs(q);
+ elv_unregister_queue(q);
elevator_exit(q);
}
@@ -608,7 +607,6 @@ int elevator_switch_mq(struct request_queue *q,
if (new_e) {
ret = elv_register_queue(q, true);
if (ret) {
- blk_mq_sched_free_rqs(q);
elevator_exit(q);
goto out;
}
diff --git a/block/fops.c b/block/fops.c
index 26bf15c770d2..e49096354dcd 100644
--- a/block/fops.c
+++ b/block/fops.c
@@ -75,8 +75,13 @@ static ssize_t __blkdev_direct_IO_simple(struct kiocb *iocb,
return -ENOMEM;
}
- bio_init(&bio, vecs, nr_pages);
- bio_set_dev(&bio, bdev);
+ if (iov_iter_rw(iter) == READ) {
+ bio_init(&bio, bdev, vecs, nr_pages, REQ_OP_READ);
+ if (iter_is_iovec(iter))
+ should_dirty = true;
+ } else {
+ bio_init(&bio, bdev, vecs, nr_pages, dio_bio_write_op(iocb));
+ }
bio.bi_iter.bi_sector = pos >> SECTOR_SHIFT;
bio.bi_write_hint = iocb->ki_hint;
bio.bi_private = current;
@@ -88,14 +93,9 @@ static ssize_t __blkdev_direct_IO_simple(struct kiocb *iocb,
goto out;
ret = bio.bi_iter.bi_size;
- if (iov_iter_rw(iter) == READ) {
- bio.bi_opf = REQ_OP_READ;
- if (iter_is_iovec(iter))
- should_dirty = true;
- } else {
- bio.bi_opf = dio_bio_write_op(iocb);
+ if (iov_iter_rw(iter) == WRITE)
task_io_account_write(ret);
- }
+
if (iocb->ki_flags & IOCB_NOWAIT)
bio.bi_opf |= REQ_NOWAIT;
if (iocb->ki_flags & IOCB_HIPRI)
@@ -190,6 +190,7 @@ static ssize_t __blkdev_direct_IO(struct kiocb *iocb, struct iov_iter *iter,
struct blkdev_dio *dio;
struct bio *bio;
bool is_read = (iov_iter_rw(iter) == READ), is_sync;
+ unsigned int opf = is_read ? REQ_OP_READ : dio_bio_write_op(iocb);
loff_t pos = iocb->ki_pos;
int ret = 0;
@@ -197,7 +198,7 @@ static ssize_t __blkdev_direct_IO(struct kiocb *iocb, struct iov_iter *iter,
(bdev_logical_block_size(bdev) - 1))
return -EINVAL;
- bio = bio_alloc_kiocb(iocb, nr_pages, &blkdev_dio_pool);
+ bio = bio_alloc_kiocb(iocb, bdev, nr_pages, opf, &blkdev_dio_pool);
dio = container_of(bio, struct blkdev_dio, bio);
atomic_set(&dio->ref, 1);
@@ -223,7 +224,6 @@ static ssize_t __blkdev_direct_IO(struct kiocb *iocb, struct iov_iter *iter,
blk_start_plug(&plug);
for (;;) {
- bio_set_dev(bio, bdev);
bio->bi_iter.bi_sector = pos >> SECTOR_SHIFT;
bio->bi_write_hint = iocb->ki_hint;
bio->bi_private = dio;
@@ -238,11 +238,9 @@ static ssize_t __blkdev_direct_IO(struct kiocb *iocb, struct iov_iter *iter,
}
if (is_read) {
- bio->bi_opf = REQ_OP_READ;
if (dio->flags & DIO_SHOULD_DIRTY)
bio_set_pages_dirty(bio);
} else {
- bio->bi_opf = dio_bio_write_op(iocb);
task_io_account_write(bio->bi_iter.bi_size);
}
if (iocb->ki_flags & IOCB_NOWAIT)
@@ -258,7 +256,7 @@ static ssize_t __blkdev_direct_IO(struct kiocb *iocb, struct iov_iter *iter,
}
atomic_inc(&dio->ref);
submit_bio(bio);
- bio = bio_alloc(GFP_KERNEL, nr_pages);
+ bio = bio_alloc(bdev, nr_pages, opf, GFP_KERNEL);
}
blk_finish_plug(&plug);
@@ -289,6 +287,8 @@ static void blkdev_bio_end_io_async(struct bio *bio)
struct kiocb *iocb = dio->iocb;
ssize_t ret;
+ WRITE_ONCE(iocb->private, NULL);
+
if (likely(!bio->bi_status)) {
ret = dio->size;
iocb->ki_pos += ret;
@@ -311,6 +311,8 @@ static ssize_t __blkdev_direct_IO_async(struct kiocb *iocb,
unsigned int nr_pages)
{
struct block_device *bdev = iocb->ki_filp->private_data;
+ bool is_read = iov_iter_rw(iter) == READ;
+ unsigned int opf = is_read ? REQ_OP_READ : dio_bio_write_op(iocb);
struct blkdev_dio *dio;
struct bio *bio;
loff_t pos = iocb->ki_pos;
@@ -320,11 +322,10 @@ static ssize_t __blkdev_direct_IO_async(struct kiocb *iocb,
(bdev_logical_block_size(bdev) - 1))
return -EINVAL;
- bio = bio_alloc_kiocb(iocb, nr_pages, &blkdev_dio_pool);
+ bio = bio_alloc_kiocb(iocb, bdev, nr_pages, opf, &blkdev_dio_pool);
dio = container_of(bio, struct blkdev_dio, bio);
dio->flags = 0;
dio->iocb = iocb;
- bio_set_dev(bio, bdev);
bio->bi_iter.bi_sector = pos >> SECTOR_SHIFT;
bio->bi_write_hint = iocb->ki_hint;
bio->bi_end_io = blkdev_bio_end_io_async;
@@ -347,14 +348,12 @@ static ssize_t __blkdev_direct_IO_async(struct kiocb *iocb,
}
dio->size = bio->bi_iter.bi_size;
- if (iov_iter_rw(iter) == READ) {
- bio->bi_opf = REQ_OP_READ;
+ if (is_read) {
if (iter_is_iovec(iter)) {
dio->flags |= DIO_SHOULD_DIRTY;
bio_set_pages_dirty(bio);
}
} else {
- bio->bi_opf = dio_bio_write_op(iocb);
task_io_account_write(bio->bi_iter.bi_size);
}
@@ -429,7 +428,8 @@ static int blkdev_writepages(struct address_space *mapping,
}
const struct address_space_operations def_blk_aops = {
- .set_page_dirty = __set_page_dirty_buffers,
+ .dirty_folio = block_dirty_folio,
+ .invalidate_folio = block_invalidate_folio,
.readpage = blkdev_readpage,
.readahead = blkdev_readahead,
.writepage = blkdev_writepage,
@@ -566,34 +566,37 @@ static ssize_t blkdev_read_iter(struct kiocb *iocb, struct iov_iter *to)
{
struct block_device *bdev = iocb->ki_filp->private_data;
loff_t size = bdev_nr_bytes(bdev);
- size_t count = iov_iter_count(to);
loff_t pos = iocb->ki_pos;
size_t shorted = 0;
ssize_t ret = 0;
+ size_t count;
- if (unlikely(pos + count > size)) {
+ if (unlikely(pos + iov_iter_count(to) > size)) {
if (pos >= size)
return 0;
size -= pos;
- if (count > size) {
- shorted = count - size;
- iov_iter_truncate(to, size);
- }
+ shorted = iov_iter_count(to) - size;
+ iov_iter_truncate(to, size);
}
+ count = iov_iter_count(to);
+ if (!count)
+ goto reexpand; /* skip atime */
+
if (iocb->ki_flags & IOCB_DIRECT) {
struct address_space *mapping = iocb->ki_filp->f_mapping;
if (iocb->ki_flags & IOCB_NOWAIT) {
- if (filemap_range_needs_writeback(mapping, iocb->ki_pos,
- iocb->ki_pos + count - 1))
- return -EAGAIN;
+ if (filemap_range_needs_writeback(mapping, pos,
+ pos + count - 1)) {
+ ret = -EAGAIN;
+ goto reexpand;
+ }
} else {
- ret = filemap_write_and_wait_range(mapping,
- iocb->ki_pos,
- iocb->ki_pos + count - 1);
+ ret = filemap_write_and_wait_range(mapping, pos,
+ pos + count - 1);
if (ret < 0)
- return ret;
+ goto reexpand;
}
file_accessed(iocb->ki_filp);
@@ -603,12 +606,14 @@ static ssize_t blkdev_read_iter(struct kiocb *iocb, struct iov_iter *to)
iocb->ki_pos += ret;
count -= ret;
}
+ iov_iter_revert(to, count - iov_iter_count(to));
if (ret < 0 || !count)
- return ret;
+ goto reexpand;
}
ret = filemap_read(iocb, to, ret);
+reexpand:
if (unlikely(shorted))
iov_iter_reexpand(to, iov_iter_count(to) + shorted);
return ret;
diff --git a/block/genhd.c b/block/genhd.c
index 626c8406f21a..c9a4fc90d3e9 100644
--- a/block/genhd.c
+++ b/block/genhd.c
@@ -8,7 +8,6 @@
#include <linux/module.h>
#include <linux/ctype.h>
#include <linux/fs.h>
-#include <linux/genhd.h>
#include <linux/kdev_t.h>
#include <linux/kernel.h>
#include <linux/blkdev.h>
@@ -26,10 +25,12 @@
#include <linux/pm_runtime.h>
#include <linux/badblocks.h>
#include <linux/part_stat.h>
+#include "blk-throttle.h"
#include "blk.h"
#include "blk-mq-sched.h"
#include "blk-rq-qos.h"
+#include "blk-cgroup.h"
static struct kobject *block_depr;
@@ -185,7 +186,9 @@ static struct blk_major_name {
struct blk_major_name *next;
int major;
char name[16];
+#ifdef CONFIG_BLOCK_LEGACY_AUTOLOAD
void (*probe)(dev_t devt);
+#endif
} *major_names[BLKDEV_MAJOR_HASH_SIZE];
static DEFINE_MUTEX(major_names_lock);
static DEFINE_SPINLOCK(major_names_spinlock);
@@ -275,7 +278,9 @@ int __register_blkdev(unsigned int major, const char *name,
}
p->major = major;
+#ifdef CONFIG_BLOCK_LEGACY_AUTOLOAD
p->probe = probe;
+#endif
strlcpy(p->name, name, sizeof(p->name));
p->next = NULL;
index = major_to_index(major);
@@ -407,6 +412,10 @@ int __must_check device_add_disk(struct device *parent, struct gendisk *disk,
struct device *ddev = disk_to_dev(disk);
int ret;
+ /* Only makes sense for bio-based to set ->poll_bio */
+ if (queue_is_mq(disk->queue) && disk->fops->poll_bio)
+ return -EINVAL;
+
/*
* The disk queue should now be all set with enough information about
* the device for the elevator code to pick an adequate default
@@ -523,6 +532,7 @@ int __must_check device_add_disk(struct device *parent, struct gendisk *disk,
disk_update_readahead(disk);
disk_add_events(disk);
+ set_bit(GD_ADDED, &disk->state);
return 0;
out_unregister_bdi:
@@ -549,6 +559,20 @@ out_free_ext_minor:
EXPORT_SYMBOL(device_add_disk);
/**
+ * blk_mark_disk_dead - mark a disk as dead
+ * @disk: disk to mark as dead
+ *
+ * Mark as disk as dead (e.g. surprise removed) and don't accept any new I/O
+ * to this disk.
+ */
+void blk_mark_disk_dead(struct gendisk *disk)
+{
+ set_bit(GD_DEAD, &disk->state);
+ blk_queue_start_drain(disk->queue);
+}
+EXPORT_SYMBOL_GPL(blk_mark_disk_dead);
+
+/**
* del_gendisk - remove the gendisk
* @disk: the struct gendisk to remove
*
@@ -622,7 +646,8 @@ void del_gendisk(struct gendisk *disk)
blk_mq_freeze_queue_wait(q);
- rq_qos_exit(q);
+ blk_throtl_cancel_bios(disk->queue);
+
blk_sync_queue(q);
blk_flush_integrity();
/*
@@ -679,6 +704,7 @@ static ssize_t disk_badblocks_store(struct device *dev,
return badblocks_store(disk->bb, page, len, 0);
}
+#ifdef CONFIG_BLOCK_LEGACY_AUTOLOAD
void blk_request_module(dev_t devt)
{
unsigned int major = MAJOR(devt);
@@ -698,6 +724,7 @@ void blk_request_module(dev_t devt)
/* Make old-style 2.4 aliases work */
request_module("block-major-%d", MAJOR(devt));
}
+#endif /* CONFIG_BLOCK_LEGACY_AUTOLOAD */
/*
* print a full list of all partitions - intended for places where the root
@@ -913,12 +940,17 @@ ssize_t part_stat_show(struct device *dev,
struct disk_stats stat;
unsigned int inflight;
- part_stat_read_all(bdev, &stat);
if (queue_is_mq(q))
inflight = blk_mq_in_flight(q, bdev);
else
inflight = part_in_flight(bdev);
+ if (inflight) {
+ part_stat_lock();
+ update_io_ticks(bdev, jiffies, true);
+ part_stat_unlock();
+ }
+ part_stat_read_all(bdev, &stat);
return sprintf(buf,
"%8lu %8lu %8llu %8u "
"%8lu %8lu %8llu %8u "
@@ -1086,6 +1118,31 @@ static const struct attribute_group *disk_attr_groups[] = {
NULL
};
+static void disk_release_mq(struct request_queue *q)
+{
+ blk_mq_cancel_work_sync(q);
+
+ /*
+ * There can't be any non non-passthrough bios in flight here, but
+ * requests stay around longer, including passthrough ones so we
+ * still need to freeze the queue here.
+ */
+ blk_mq_freeze_queue(q);
+
+ /*
+ * Since the I/O scheduler exit code may access cgroup information,
+ * perform I/O scheduler exit before disassociating from the block
+ * cgroup controller.
+ */
+ if (q->elevator) {
+ mutex_lock(&q->sysfs_lock);
+ elevator_exit(q);
+ mutex_unlock(&q->sysfs_lock);
+ }
+ rq_qos_exit(q);
+ __blk_mq_unfreeze_queue(q, true);
+}
+
/**
* disk_release - releases all allocated resources of the gendisk
* @dev: the device representing this disk
@@ -1107,13 +1164,21 @@ static void disk_release(struct device *dev)
might_sleep();
WARN_ON_ONCE(disk_live(disk));
- blk_mq_cancel_work_sync(disk->queue);
+ if (queue_is_mq(disk->queue))
+ disk_release_mq(disk->queue);
+
+ blkcg_exit_queue(disk->queue);
disk_release_events(disk);
kfree(disk->random);
xa_destroy(&disk->part_tbl);
+
disk->queue->disk = NULL;
blk_put_queue(disk->queue);
+
+ if (test_bit(GD_ADDED, &disk->state) && disk->fops->free_disk)
+ disk->fops->free_disk(disk);
+
iput(disk->part0->bd_inode); /* frees the disk */
}
@@ -1174,12 +1239,17 @@ static int diskstats_show(struct seq_file *seqf, void *v)
xa_for_each(&gp->part_tbl, idx, hd) {
if (bdev_is_partition(hd) && !bdev_nr_sectors(hd))
continue;
- part_stat_read_all(hd, &stat);
if (queue_is_mq(gp->queue))
inflight = blk_mq_in_flight(gp->queue, hd);
else
inflight = part_in_flight(hd);
+ if (inflight) {
+ part_stat_lock();
+ update_io_ticks(hd, jiffies, true);
+ part_stat_unlock();
+ }
+ part_stat_read_all(hd, &stat);
seq_printf(seqf, "%4d %7d %pg "
"%lu %lu %lu %u "
"%lu %lu %lu %u "
@@ -1308,6 +1378,9 @@ struct gendisk *__alloc_disk_node(struct request_queue *q, int node_id,
if (xa_insert(&disk->part_tbl, 0, disk->part0, GFP_KERNEL))
goto out_destroy_part_tbl;
+ if (blkcg_init_queue(q))
+ goto out_erase_part0;
+
rand_initialize_disk(disk);
disk_to_dev(disk)->class = &block_class;
disk_to_dev(disk)->type = &disk_type;
@@ -1320,6 +1393,8 @@ struct gendisk *__alloc_disk_node(struct request_queue *q, int node_id,
#endif
return disk;
+out_erase_part0:
+ xa_erase(&disk->part_tbl, 0);
out_destroy_part_tbl:
xa_destroy(&disk->part_tbl);
disk->part0->bd_disk = NULL;
diff --git a/block/holder.c b/block/holder.c
index 27cddce1b446..8d750281a1cd 100644
--- a/block/holder.c
+++ b/block/holder.c
@@ -1,5 +1,5 @@
// SPDX-License-Identifier: GPL-2.0-only
-#include <linux/genhd.h>
+#include <linux/blkdev.h>
#include <linux/slab.h>
struct bd_holder_disk {
diff --git a/block/partitions/check.h b/block/partitions/check.h
index d5b28e309d64..4ffa2359b1a3 100644
--- a/block/partitions/check.h
+++ b/block/partitions/check.h
@@ -1,7 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0 */
#include <linux/pagemap.h>
#include <linux/blkdev.h>
-#include <linux/genhd.h>
#include "../blk.h"
/*
diff --git a/block/partitions/core.c b/block/partitions/core.c
index c2a1635922b1..2ef8dfa1e5c8 100644
--- a/block/partitions/core.c
+++ b/block/partitions/core.c
@@ -8,7 +8,6 @@
#include <linux/major.h>
#include <linux/slab.h>
#include <linux/ctype.h>
-#include <linux/genhd.h>
#include <linux/vmalloc.h>
#include <linux/blktrace_api.h>
#include <linux/raid/detect.h>
diff --git a/block/partitions/efi.h b/block/partitions/efi.h
index 8cc2b88d0aa8..84b9f36b9e47 100644
--- a/block/partitions/efi.h
+++ b/block/partitions/efi.h
@@ -13,7 +13,6 @@
#include <linux/types.h>
#include <linux/fs.h>
-#include <linux/genhd.h>
#include <linux/kernel.h>
#include <linux/major.h>
#include <linux/string.h>
diff --git a/block/partitions/ldm.h b/block/partitions/ldm.h
index 8693704dcf5e..0a747a0c782d 100644
--- a/block/partitions/ldm.h
+++ b/block/partitions/ldm.h
@@ -14,7 +14,6 @@
#include <linux/types.h>
#include <linux/list.h>
-#include <linux/genhd.h>
#include <linux/fs.h>
#include <asm/unaligned.h>
#include <asm/byteorder.h>
diff --git a/block/sed-opal.c b/block/sed-opal.c
index daafadbb88ca..9700197000f2 100644
--- a/block/sed-opal.c
+++ b/block/sed-opal.c
@@ -13,7 +13,7 @@
#include <linux/device.h>
#include <linux/kernel.h>
#include <linux/list.h>
-#include <linux/genhd.h>
+#include <linux/blkdev.h>
#include <linux/slab.h>
#include <linux/uaccess.h>
#include <uapi/linux/sed-opal.h>
diff --git a/certs/system_keyring.c b/certs/system_keyring.c
index 692365dee2bd..05b66ce9d1c9 100644
--- a/certs/system_keyring.c
+++ b/certs/system_keyring.c
@@ -22,6 +22,9 @@ static struct key *builtin_trusted_keys;
#ifdef CONFIG_SECONDARY_TRUSTED_KEYRING
static struct key *secondary_trusted_keys;
#endif
+#ifdef CONFIG_INTEGRITY_MACHINE_KEYRING
+static struct key *machine_trusted_keys;
+#endif
#ifdef CONFIG_INTEGRITY_PLATFORM_KEYRING
static struct key *platform_trusted_keys;
#endif
@@ -86,11 +89,50 @@ static __init struct key_restriction *get_builtin_and_secondary_restriction(void
if (!restriction)
panic("Can't allocate secondary trusted keyring restriction\n");
- restriction->check = restrict_link_by_builtin_and_secondary_trusted;
+ if (IS_ENABLED(CONFIG_INTEGRITY_MACHINE_KEYRING))
+ restriction->check = restrict_link_by_builtin_secondary_and_machine;
+ else
+ restriction->check = restrict_link_by_builtin_and_secondary_trusted;
return restriction;
}
#endif
+#ifdef CONFIG_INTEGRITY_MACHINE_KEYRING
+void __init set_machine_trusted_keys(struct key *keyring)
+{
+ machine_trusted_keys = keyring;
+
+ if (key_link(secondary_trusted_keys, machine_trusted_keys) < 0)
+ panic("Can't link (machine) trusted keyrings\n");
+}
+
+/**
+ * restrict_link_by_builtin_secondary_and_machine - Restrict keyring addition.
+ * @dest_keyring: Keyring being linked to.
+ * @type: The type of key being added.
+ * @payload: The payload of the new key.
+ * @restrict_key: A ring of keys that can be used to vouch for the new cert.
+ *
+ * Restrict the addition of keys into a keyring based on the key-to-be-added
+ * being vouched for by a key in either the built-in, the secondary, or
+ * the machine keyrings.
+ */
+int restrict_link_by_builtin_secondary_and_machine(
+ struct key *dest_keyring,
+ const struct key_type *type,
+ const union key_payload *payload,
+ struct key *restrict_key)
+{
+ if (machine_trusted_keys && type == &key_type_keyring &&
+ dest_keyring == secondary_trusted_keys &&
+ payload == &machine_trusted_keys->payload)
+ /* Allow the machine keyring to be added to the secondary */
+ return 0;
+
+ return restrict_link_by_builtin_and_secondary_trusted(dest_keyring, type,
+ payload, restrict_key);
+}
+#endif
/*
* Create the trusted keyrings
diff --git a/crypto/Kconfig b/crypto/Kconfig
index 442765219c37..d6d7e84bb7f8 100644
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -231,6 +231,13 @@ config CRYPTO_DH
help
Generic implementation of the Diffie-Hellman algorithm.
+config CRYPTO_DH_RFC7919_GROUPS
+ bool "Support for RFC 7919 FFDHE group parameters"
+ depends on CRYPTO_DH
+ select CRYPTO_RNG_DEFAULT
+ help
+ Provide support for RFC 7919 FFDHE group parameters. If unsure, say N.
+
config CRYPTO_ECC
tristate
select CRYPTO_RNG_DEFAULT
@@ -267,7 +274,7 @@ config CRYPTO_ECRDSA
config CRYPTO_SM2
tristate "SM2 algorithm"
- select CRYPTO_SM3
+ select CRYPTO_LIB_SM3
select CRYPTO_AKCIPHER
select CRYPTO_MANAGER
select MPILIB
@@ -425,6 +432,7 @@ config CRYPTO_LRW
select CRYPTO_SKCIPHER
select CRYPTO_MANAGER
select CRYPTO_GF128MUL
+ select CRYPTO_ECB
help
LRW: Liskov Rivest Wagner, a tweakable, non malleable, non movable
narrow block cipher mode for dm-crypt. Use it with cipher
@@ -999,6 +1007,7 @@ config CRYPTO_SHA3
config CRYPTO_SM3
tristate "SM3 digest algorithm"
select CRYPTO_HASH
+ select CRYPTO_LIB_SM3
help
SM3 secure hash function as defined by OSCCA GM/T 0004-2012 SM3).
It is part of the Chinese Commercial Cryptography suite.
@@ -1007,6 +1016,19 @@ config CRYPTO_SM3
http://www.oscca.gov.cn/UpFile/20101222141857786.pdf
https://datatracker.ietf.org/doc/html/draft-shen-sm3-hash
+config CRYPTO_SM3_AVX_X86_64
+ tristate "SM3 digest algorithm (x86_64/AVX)"
+ depends on X86 && 64BIT
+ select CRYPTO_HASH
+ select CRYPTO_LIB_SM3
+ help
+ SM3 secure hash function as defined by OSCCA GM/T 0004-2012 SM3).
+ It is part of the Chinese Commercial Cryptography suite. This is
+ SM3 optimized implementation using Advanced Vector Extensions (AVX)
+ when available.
+
+ If unsure, say N.
+
config CRYPTO_STREEBOG
tristate "Streebog Hash Function"
select CRYPTO_HASH
@@ -1847,6 +1869,7 @@ config CRYPTO_JITTERENTROPY
config CRYPTO_KDF800108_CTR
tristate
+ select CRYPTO_HMAC
select CRYPTO_SHA256
config CRYPTO_USER_API
diff --git a/crypto/af_alg.c b/crypto/af_alg.c
index e1ea18536a5f..c8289b7a85ba 100644
--- a/crypto/af_alg.c
+++ b/crypto/af_alg.c
@@ -25,12 +25,9 @@ struct alg_type_list {
struct list_head list;
};
-static atomic_long_t alg_memory_allocated;
-
static struct proto alg_proto = {
.name = "ALG",
.owner = THIS_MODULE,
- .memory_allocated = &alg_memory_allocated,
.obj_size = sizeof(struct alg_sock),
};
diff --git a/crypto/algapi.c b/crypto/algapi.c
index a366cb3e8aa1..d1c99288af3e 100644
--- a/crypto/algapi.c
+++ b/crypto/algapi.c
@@ -6,6 +6,7 @@
*/
#include <crypto/algapi.h>
+#include <crypto/internal/simd.h>
#include <linux/err.h>
#include <linux/errno.h>
#include <linux/fips.h>
@@ -21,6 +22,11 @@
static LIST_HEAD(crypto_template_list);
+#ifdef CONFIG_CRYPTO_MANAGER_EXTRA_TESTS
+DEFINE_PER_CPU(bool, crypto_simd_disabled_for_test);
+EXPORT_PER_CPU_SYMBOL_GPL(crypto_simd_disabled_for_test);
+#endif
+
static inline void crypto_check_module_sig(struct module *mod)
{
if (fips_enabled && mod && !module_sig_ok(mod))
@@ -322,9 +328,17 @@ void crypto_alg_tested(const char *name, int err)
found:
q->cra_flags |= CRYPTO_ALG_DEAD;
alg = test->adult;
- if (err || list_empty(&alg->cra_list))
+
+ if (list_empty(&alg->cra_list))
goto complete;
+ if (err == -ECANCELED)
+ alg->cra_flags |= CRYPTO_ALG_FIPS_INTERNAL;
+ else if (err)
+ goto complete;
+ else
+ alg->cra_flags &= ~CRYPTO_ALG_FIPS_INTERNAL;
+
alg->cra_flags |= CRYPTO_ALG_TESTED;
/* Only satisfy larval waiters if we are the best. */
@@ -604,6 +618,7 @@ int crypto_register_instance(struct crypto_template *tmpl,
{
struct crypto_larval *larval;
struct crypto_spawn *spawn;
+ u32 fips_internal = 0;
int err;
err = crypto_check_alg(&inst->alg);
@@ -626,11 +641,15 @@ int crypto_register_instance(struct crypto_template *tmpl,
spawn->inst = inst;
spawn->registered = true;
+ fips_internal |= spawn->alg->cra_flags;
+
crypto_mod_put(spawn->alg);
spawn = next;
}
+ inst->alg.cra_flags |= (fips_internal & CRYPTO_ALG_FIPS_INTERNAL);
+
larval = __crypto_register_alg(&inst->alg);
if (IS_ERR(larval))
goto unlock;
@@ -683,7 +702,8 @@ int crypto_grab_spawn(struct crypto_spawn *spawn, struct crypto_instance *inst,
if (IS_ERR(name))
return PTR_ERR(name);
- alg = crypto_find_alg(name, spawn->frontend, type, mask);
+ alg = crypto_find_alg(name, spawn->frontend,
+ type | CRYPTO_ALG_FIPS_INTERNAL, mask);
if (IS_ERR(alg))
return PTR_ERR(alg);
@@ -1002,7 +1022,13 @@ void __crypto_xor(u8 *dst, const u8 *src1, const u8 *src2, unsigned int len)
}
while (IS_ENABLED(CONFIG_64BIT) && len >= 8 && !(relalign & 7)) {
- *(u64 *)dst = *(u64 *)src1 ^ *(u64 *)src2;
+ if (IS_ENABLED(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS)) {
+ u64 l = get_unaligned((u64 *)src1) ^
+ get_unaligned((u64 *)src2);
+ put_unaligned(l, (u64 *)dst);
+ } else {
+ *(u64 *)dst = *(u64 *)src1 ^ *(u64 *)src2;
+ }
dst += 8;
src1 += 8;
src2 += 8;
@@ -1010,7 +1036,13 @@ void __crypto_xor(u8 *dst, const u8 *src1, const u8 *src2, unsigned int len)
}
while (len >= 4 && !(relalign & 3)) {
- *(u32 *)dst = *(u32 *)src1 ^ *(u32 *)src2;
+ if (IS_ENABLED(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS)) {
+ u32 l = get_unaligned((u32 *)src1) ^
+ get_unaligned((u32 *)src2);
+ put_unaligned(l, (u32 *)dst);
+ } else {
+ *(u32 *)dst = *(u32 *)src1 ^ *(u32 *)src2;
+ }
dst += 4;
src1 += 4;
src2 += 4;
@@ -1018,7 +1050,13 @@ void __crypto_xor(u8 *dst, const u8 *src1, const u8 *src2, unsigned int len)
}
while (len >= 2 && !(relalign & 1)) {
- *(u16 *)dst = *(u16 *)src1 ^ *(u16 *)src2;
+ if (IS_ENABLED(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS)) {
+ u16 l = get_unaligned((u16 *)src1) ^
+ get_unaligned((u16 *)src2);
+ put_unaligned(l, (u16 *)dst);
+ } else {
+ *(u16 *)dst = *(u16 *)src1 ^ *(u16 *)src2;
+ }
dst += 2;
src1 += 2;
src2 += 2;
@@ -1324,3 +1362,4 @@ module_exit(crypto_algapi_exit);
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Cryptographic algorithms API");
+MODULE_SOFTDEP("pre: cryptomgr");
diff --git a/crypto/api.c b/crypto/api.c
index cf0869dd130b..69508ae9345e 100644
--- a/crypto/api.c
+++ b/crypto/api.c
@@ -223,6 +223,8 @@ static struct crypto_alg *crypto_larval_wait(struct crypto_alg *alg)
else if (crypto_is_test_larval(larval) &&
!(alg->cra_flags & CRYPTO_ALG_TESTED))
alg = ERR_PTR(-EAGAIN);
+ else if (alg->cra_flags & CRYPTO_ALG_FIPS_INTERNAL)
+ alg = ERR_PTR(-EAGAIN);
else if (!crypto_mod_get(alg))
alg = ERR_PTR(-EAGAIN);
crypto_mod_put(&larval->alg);
@@ -233,6 +235,7 @@ static struct crypto_alg *crypto_larval_wait(struct crypto_alg *alg)
static struct crypto_alg *crypto_alg_lookup(const char *name, u32 type,
u32 mask)
{
+ const u32 fips = CRYPTO_ALG_FIPS_INTERNAL;
struct crypto_alg *alg;
u32 test = 0;
@@ -240,8 +243,20 @@ static struct crypto_alg *crypto_alg_lookup(const char *name, u32 type,
test |= CRYPTO_ALG_TESTED;
down_read(&crypto_alg_sem);
- alg = __crypto_alg_lookup(name, type | test, mask | test);
- if (!alg && test) {
+ alg = __crypto_alg_lookup(name, (type | test) & ~fips,
+ (mask | test) & ~fips);
+ if (alg) {
+ if (((type | mask) ^ fips) & fips)
+ mask |= fips;
+ mask &= fips;
+
+ if (!crypto_is_larval(alg) &&
+ ((type ^ alg->cra_flags) & mask)) {
+ /* Algorithm is disallowed in FIPS mode. */
+ crypto_mod_put(alg);
+ alg = ERR_PTR(-ENOENT);
+ }
+ } else if (test) {
alg = __crypto_alg_lookup(name, type, mask);
if (alg && !crypto_is_larval(alg)) {
/* Test failed */
@@ -643,4 +658,3 @@ EXPORT_SYMBOL_GPL(crypto_req_done);
MODULE_DESCRIPTION("Cryptographic core API");
MODULE_LICENSE("GPL");
-MODULE_SOFTDEP("pre: cryptomgr");
diff --git a/crypto/asymmetric_keys/Kconfig b/crypto/asymmetric_keys/Kconfig
index 1f1f004dc757..460bc5d0a828 100644
--- a/crypto/asymmetric_keys/Kconfig
+++ b/crypto/asymmetric_keys/Kconfig
@@ -22,18 +22,6 @@ config ASYMMETRIC_PUBLIC_KEY_SUBTYPE
appropriate hash algorithms (such as SHA-1) must be available.
ENOPKG will be reported if the requisite algorithm is unavailable.
-config ASYMMETRIC_TPM_KEY_SUBTYPE
- tristate "Asymmetric TPM backed private key subtype"
- depends on TCG_TPM
- depends on TRUSTED_KEYS
- select CRYPTO_HMAC
- select CRYPTO_SHA1
- select CRYPTO_HASH_INFO
- help
- This option provides support for TPM backed private key type handling.
- Operations such as sign, verify, encrypt, decrypt are performed by
- the TPM after the private key is loaded.
-
config X509_CERTIFICATE_PARSER
tristate "X.509 certificate parser"
depends on ASYMMETRIC_PUBLIC_KEY_SUBTYPE
@@ -54,15 +42,6 @@ config PKCS8_PRIVATE_KEY_PARSER
private key data and provides the ability to instantiate a crypto key
from that data.
-config TPM_KEY_PARSER
- tristate "TPM private key parser"
- depends on ASYMMETRIC_TPM_KEY_SUBTYPE
- select ASN1
- help
- This option provides support for parsing TPM format blobs for
- private key data and provides the ability to instantiate a crypto key
- from that data.
-
config PKCS7_MESSAGE_PARSER
tristate "PKCS#7 message parser"
depends on X509_CERTIFICATE_PARSER
diff --git a/crypto/asymmetric_keys/Makefile b/crypto/asymmetric_keys/Makefile
index 28b91adba2ae..c38424f55b08 100644
--- a/crypto/asymmetric_keys/Makefile
+++ b/crypto/asymmetric_keys/Makefile
@@ -11,7 +11,6 @@ asymmetric_keys-y := \
signature.o
obj-$(CONFIG_ASYMMETRIC_PUBLIC_KEY_SUBTYPE) += public_key.o
-obj-$(CONFIG_ASYMMETRIC_TPM_KEY_SUBTYPE) += asym_tpm.o
#
# X.509 Certificate handling
@@ -75,14 +74,3 @@ verify_signed_pefile-y := \
$(obj)/mscode_parser.o: $(obj)/mscode.asn1.h $(obj)/mscode.asn1.h
$(obj)/mscode.asn1.o: $(obj)/mscode.asn1.c $(obj)/mscode.asn1.h
-
-#
-# TPM private key parsing
-#
-obj-$(CONFIG_TPM_KEY_PARSER) += tpm_key_parser.o
-tpm_key_parser-y := \
- tpm.asn1.o \
- tpm_parser.o
-
-$(obj)/tpm_parser.o: $(obj)/tpm.asn1.h
-$(obj)/tpm.asn1.o: $(obj)/tpm.asn1.c $(obj)/tpm.asn1.h
diff --git a/crypto/asymmetric_keys/asym_tpm.c b/crypto/asymmetric_keys/asym_tpm.c
deleted file mode 100644
index 0959613560b9..000000000000
--- a/crypto/asymmetric_keys/asym_tpm.c
+++ /dev/null
@@ -1,957 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-#define pr_fmt(fmt) "ASYM-TPM: "fmt
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <linux/export.h>
-#include <linux/kernel.h>
-#include <linux/seq_file.h>
-#include <linux/scatterlist.h>
-#include <linux/tpm.h>
-#include <linux/tpm_command.h>
-#include <crypto/akcipher.h>
-#include <crypto/hash.h>
-#include <crypto/sha1.h>
-#include <asm/unaligned.h>
-#include <keys/asymmetric-subtype.h>
-#include <keys/trusted_tpm.h>
-#include <crypto/asym_tpm_subtype.h>
-#include <crypto/public_key.h>
-
-#define TPM_ORD_FLUSHSPECIFIC 186
-#define TPM_ORD_LOADKEY2 65
-#define TPM_ORD_UNBIND 30
-#define TPM_ORD_SIGN 60
-
-#define TPM_RT_KEY 0x00000001
-
-/*
- * Load a TPM key from the blob provided by userspace
- */
-static int tpm_loadkey2(struct tpm_buf *tb,
- uint32_t keyhandle, unsigned char *keyauth,
- const unsigned char *keyblob, int keybloblen,
- uint32_t *newhandle)
-{
- unsigned char nonceodd[TPM_NONCE_SIZE];
- unsigned char enonce[TPM_NONCE_SIZE];
- unsigned char authdata[SHA1_DIGEST_SIZE];
- uint32_t authhandle = 0;
- unsigned char cont = 0;
- uint32_t ordinal;
- int ret;
-
- ordinal = htonl(TPM_ORD_LOADKEY2);
-
- /* session for loading the key */
- ret = oiap(tb, &authhandle, enonce);
- if (ret < 0) {
- pr_info("oiap failed (%d)\n", ret);
- return ret;
- }
-
- /* generate odd nonce */
- ret = tpm_get_random(NULL, nonceodd, TPM_NONCE_SIZE);
- if (ret < 0) {
- pr_info("tpm_get_random failed (%d)\n", ret);
- return ret;
- }
-
- /* calculate authorization HMAC value */
- ret = TSS_authhmac(authdata, keyauth, SHA1_DIGEST_SIZE, enonce,
- nonceodd, cont, sizeof(uint32_t), &ordinal,
- keybloblen, keyblob, 0, 0);
- if (ret < 0)
- return ret;
-
- /* build the request buffer */
- tpm_buf_reset(tb, TPM_TAG_RQU_AUTH1_COMMAND, TPM_ORD_LOADKEY2);
- tpm_buf_append_u32(tb, keyhandle);
- tpm_buf_append(tb, keyblob, keybloblen);
- tpm_buf_append_u32(tb, authhandle);
- tpm_buf_append(tb, nonceodd, TPM_NONCE_SIZE);
- tpm_buf_append_u8(tb, cont);
- tpm_buf_append(tb, authdata, SHA1_DIGEST_SIZE);
-
- ret = trusted_tpm_send(tb->data, MAX_BUF_SIZE);
- if (ret < 0) {
- pr_info("authhmac failed (%d)\n", ret);
- return ret;
- }
-
- ret = TSS_checkhmac1(tb->data, ordinal, nonceodd, keyauth,
- SHA1_DIGEST_SIZE, 0, 0);
- if (ret < 0) {
- pr_info("TSS_checkhmac1 failed (%d)\n", ret);
- return ret;
- }
-
- *newhandle = LOAD32(tb->data, TPM_DATA_OFFSET);
- return 0;
-}
-
-/*
- * Execute the FlushSpecific TPM command
- */
-static int tpm_flushspecific(struct tpm_buf *tb, uint32_t handle)
-{
- tpm_buf_reset(tb, TPM_TAG_RQU_COMMAND, TPM_ORD_FLUSHSPECIFIC);
- tpm_buf_append_u32(tb, handle);
- tpm_buf_append_u32(tb, TPM_RT_KEY);
-
- return trusted_tpm_send(tb->data, MAX_BUF_SIZE);
-}
-
-/*
- * Decrypt a blob provided by userspace using a specific key handle.
- * The handle is a well known handle or previously loaded by e.g. LoadKey2
- */
-static int tpm_unbind(struct tpm_buf *tb,
- uint32_t keyhandle, unsigned char *keyauth,
- const unsigned char *blob, uint32_t bloblen,
- void *out, uint32_t outlen)
-{
- unsigned char nonceodd[TPM_NONCE_SIZE];
- unsigned char enonce[TPM_NONCE_SIZE];
- unsigned char authdata[SHA1_DIGEST_SIZE];
- uint32_t authhandle = 0;
- unsigned char cont = 0;
- uint32_t ordinal;
- uint32_t datalen;
- int ret;
-
- ordinal = htonl(TPM_ORD_UNBIND);
- datalen = htonl(bloblen);
-
- /* session for loading the key */
- ret = oiap(tb, &authhandle, enonce);
- if (ret < 0) {
- pr_info("oiap failed (%d)\n", ret);
- return ret;
- }
-
- /* generate odd nonce */
- ret = tpm_get_random(NULL, nonceodd, TPM_NONCE_SIZE);
- if (ret < 0) {
- pr_info("tpm_get_random failed (%d)\n", ret);
- return ret;
- }
-
- /* calculate authorization HMAC value */
- ret = TSS_authhmac(authdata, keyauth, SHA1_DIGEST_SIZE, enonce,
- nonceodd, cont, sizeof(uint32_t), &ordinal,
- sizeof(uint32_t), &datalen,
- bloblen, blob, 0, 0);
- if (ret < 0)
- return ret;
-
- /* build the request buffer */
- tpm_buf_reset(tb, TPM_TAG_RQU_AUTH1_COMMAND, TPM_ORD_UNBIND);
- tpm_buf_append_u32(tb, keyhandle);
- tpm_buf_append_u32(tb, bloblen);
- tpm_buf_append(tb, blob, bloblen);
- tpm_buf_append_u32(tb, authhandle);
- tpm_buf_append(tb, nonceodd, TPM_NONCE_SIZE);
- tpm_buf_append_u8(tb, cont);
- tpm_buf_append(tb, authdata, SHA1_DIGEST_SIZE);
-
- ret = trusted_tpm_send(tb->data, MAX_BUF_SIZE);
- if (ret < 0) {
- pr_info("authhmac failed (%d)\n", ret);
- return ret;
- }
-
- datalen = LOAD32(tb->data, TPM_DATA_OFFSET);
-
- ret = TSS_checkhmac1(tb->data, ordinal, nonceodd,
- keyauth, SHA1_DIGEST_SIZE,
- sizeof(uint32_t), TPM_DATA_OFFSET,
- datalen, TPM_DATA_OFFSET + sizeof(uint32_t),
- 0, 0);
- if (ret < 0) {
- pr_info("TSS_checkhmac1 failed (%d)\n", ret);
- return ret;
- }
-
- memcpy(out, tb->data + TPM_DATA_OFFSET + sizeof(uint32_t),
- min(outlen, datalen));
-
- return datalen;
-}
-
-/*
- * Sign a blob provided by userspace (that has had the hash function applied)
- * using a specific key handle. The handle is assumed to have been previously
- * loaded by e.g. LoadKey2.
- *
- * Note that the key signature scheme of the used key should be set to
- * TPM_SS_RSASSAPKCS1v15_DER. This allows the hashed input to be of any size
- * up to key_length_in_bytes - 11 and not be limited to size 20 like the
- * TPM_SS_RSASSAPKCS1v15_SHA1 signature scheme.
- */
-static int tpm_sign(struct tpm_buf *tb,
- uint32_t keyhandle, unsigned char *keyauth,
- const unsigned char *blob, uint32_t bloblen,
- void *out, uint32_t outlen)
-{
- unsigned char nonceodd[TPM_NONCE_SIZE];
- unsigned char enonce[TPM_NONCE_SIZE];
- unsigned char authdata[SHA1_DIGEST_SIZE];
- uint32_t authhandle = 0;
- unsigned char cont = 0;
- uint32_t ordinal;
- uint32_t datalen;
- int ret;
-
- ordinal = htonl(TPM_ORD_SIGN);
- datalen = htonl(bloblen);
-
- /* session for loading the key */
- ret = oiap(tb, &authhandle, enonce);
- if (ret < 0) {
- pr_info("oiap failed (%d)\n", ret);
- return ret;
- }
-
- /* generate odd nonce */
- ret = tpm_get_random(NULL, nonceodd, TPM_NONCE_SIZE);
- if (ret < 0) {
- pr_info("tpm_get_random failed (%d)\n", ret);
- return ret;
- }
-
- /* calculate authorization HMAC value */
- ret = TSS_authhmac(authdata, keyauth, SHA1_DIGEST_SIZE, enonce,
- nonceodd, cont, sizeof(uint32_t), &ordinal,
- sizeof(uint32_t), &datalen,
- bloblen, blob, 0, 0);
- if (ret < 0)
- return ret;
-
- /* build the request buffer */
- tpm_buf_reset(tb, TPM_TAG_RQU_AUTH1_COMMAND, TPM_ORD_SIGN);
- tpm_buf_append_u32(tb, keyhandle);
- tpm_buf_append_u32(tb, bloblen);
- tpm_buf_append(tb, blob, bloblen);
- tpm_buf_append_u32(tb, authhandle);
- tpm_buf_append(tb, nonceodd, TPM_NONCE_SIZE);
- tpm_buf_append_u8(tb, cont);
- tpm_buf_append(tb, authdata, SHA1_DIGEST_SIZE);
-
- ret = trusted_tpm_send(tb->data, MAX_BUF_SIZE);
- if (ret < 0) {
- pr_info("authhmac failed (%d)\n", ret);
- return ret;
- }
-
- datalen = LOAD32(tb->data, TPM_DATA_OFFSET);
-
- ret = TSS_checkhmac1(tb->data, ordinal, nonceodd,
- keyauth, SHA1_DIGEST_SIZE,
- sizeof(uint32_t), TPM_DATA_OFFSET,
- datalen, TPM_DATA_OFFSET + sizeof(uint32_t),
- 0, 0);
- if (ret < 0) {
- pr_info("TSS_checkhmac1 failed (%d)\n", ret);
- return ret;
- }
-
- memcpy(out, tb->data + TPM_DATA_OFFSET + sizeof(uint32_t),
- min(datalen, outlen));
-
- return datalen;
-}
-
-/* Room to fit two u32 zeros for algo id and parameters length. */
-#define SETKEY_PARAMS_SIZE (sizeof(u32) * 2)
-
-/*
- * Maximum buffer size for the BER/DER encoded public key. The public key
- * is of the form SEQUENCE { INTEGER n, INTEGER e } where n is a maximum 2048
- * bit key and e is usually 65537
- * The encoding overhead is:
- * - max 4 bytes for SEQUENCE
- * - max 4 bytes for INTEGER n type/length
- * - 257 bytes of n
- * - max 2 bytes for INTEGER e type/length
- * - 3 bytes of e
- * - 4+4 of zeros for set_pub_key parameters (SETKEY_PARAMS_SIZE)
- */
-#define PUB_KEY_BUF_SIZE (4 + 4 + 257 + 2 + 3 + SETKEY_PARAMS_SIZE)
-
-/*
- * Provide a part of a description of the key for /proc/keys.
- */
-static void asym_tpm_describe(const struct key *asymmetric_key,
- struct seq_file *m)
-{
- struct tpm_key *tk = asymmetric_key->payload.data[asym_crypto];
-
- if (!tk)
- return;
-
- seq_printf(m, "TPM1.2/Blob");
-}
-
-static void asym_tpm_destroy(void *payload0, void *payload3)
-{
- struct tpm_key *tk = payload0;
-
- if (!tk)
- return;
-
- kfree(tk->blob);
- tk->blob_len = 0;
-
- kfree(tk);
-}
-
-/* How many bytes will it take to encode the length */
-static inline uint32_t definite_length(uint32_t len)
-{
- if (len <= 127)
- return 1;
- if (len <= 255)
- return 2;
- return 3;
-}
-
-static inline uint8_t *encode_tag_length(uint8_t *buf, uint8_t tag,
- uint32_t len)
-{
- *buf++ = tag;
-
- if (len <= 127) {
- buf[0] = len;
- return buf + 1;
- }
-
- if (len <= 255) {
- buf[0] = 0x81;
- buf[1] = len;
- return buf + 2;
- }
-
- buf[0] = 0x82;
- put_unaligned_be16(len, buf + 1);
- return buf + 3;
-}
-
-static uint32_t derive_pub_key(const void *pub_key, uint32_t len, uint8_t *buf)
-{
- uint8_t *cur = buf;
- uint32_t n_len = definite_length(len) + 1 + len + 1;
- uint32_t e_len = definite_length(3) + 1 + 3;
- uint8_t e[3] = { 0x01, 0x00, 0x01 };
-
- /* SEQUENCE */
- cur = encode_tag_length(cur, 0x30, n_len + e_len);
- /* INTEGER n */
- cur = encode_tag_length(cur, 0x02, len + 1);
- cur[0] = 0x00;
- memcpy(cur + 1, pub_key, len);
- cur += len + 1;
- cur = encode_tag_length(cur, 0x02, sizeof(e));
- memcpy(cur, e, sizeof(e));
- cur += sizeof(e);
- /* Zero parameters to satisfy set_pub_key ABI. */
- memzero_explicit(cur, SETKEY_PARAMS_SIZE);
-
- return cur - buf;
-}
-
-/*
- * Determine the crypto algorithm name.
- */
-static int determine_akcipher(const char *encoding, const char *hash_algo,
- char alg_name[CRYPTO_MAX_ALG_NAME])
-{
- if (strcmp(encoding, "pkcs1") == 0) {
- if (!hash_algo) {
- strcpy(alg_name, "pkcs1pad(rsa)");
- return 0;
- }
-
- if (snprintf(alg_name, CRYPTO_MAX_ALG_NAME, "pkcs1pad(rsa,%s)",
- hash_algo) >= CRYPTO_MAX_ALG_NAME)
- return -EINVAL;
-
- return 0;
- }
-
- if (strcmp(encoding, "raw") == 0) {
- strcpy(alg_name, "rsa");
- return 0;
- }
-
- return -ENOPKG;
-}
-
-/*
- * Query information about a key.
- */
-static int tpm_key_query(const struct kernel_pkey_params *params,
- struct kernel_pkey_query *info)
-{
- struct tpm_key *tk = params->key->payload.data[asym_crypto];
- int ret;
- char alg_name[CRYPTO_MAX_ALG_NAME];
- struct crypto_akcipher *tfm;
- uint8_t der_pub_key[PUB_KEY_BUF_SIZE];
- uint32_t der_pub_key_len;
- int len;
-
- /* TPM only works on private keys, public keys still done in software */
- ret = determine_akcipher(params->encoding, params->hash_algo, alg_name);
- if (ret < 0)
- return ret;
-
- tfm = crypto_alloc_akcipher(alg_name, 0, 0);
- if (IS_ERR(tfm))
- return PTR_ERR(tfm);
-
- der_pub_key_len = derive_pub_key(tk->pub_key, tk->pub_key_len,
- der_pub_key);
-
- ret = crypto_akcipher_set_pub_key(tfm, der_pub_key, der_pub_key_len);
- if (ret < 0)
- goto error_free_tfm;
-
- len = crypto_akcipher_maxsize(tfm);
-
- info->key_size = tk->key_len;
- info->max_data_size = tk->key_len / 8;
- info->max_sig_size = len;
- info->max_enc_size = len;
- info->max_dec_size = tk->key_len / 8;
-
- info->supported_ops = KEYCTL_SUPPORTS_ENCRYPT |
- KEYCTL_SUPPORTS_DECRYPT |
- KEYCTL_SUPPORTS_VERIFY |
- KEYCTL_SUPPORTS_SIGN;
-
- ret = 0;
-error_free_tfm:
- crypto_free_akcipher(tfm);
- pr_devel("<==%s() = %d\n", __func__, ret);
- return ret;
-}
-
-/*
- * Encryption operation is performed with the public key. Hence it is done
- * in software
- */
-static int tpm_key_encrypt(struct tpm_key *tk,
- struct kernel_pkey_params *params,
- const void *in, void *out)
-{
- char alg_name[CRYPTO_MAX_ALG_NAME];
- struct crypto_akcipher *tfm;
- struct akcipher_request *req;
- struct crypto_wait cwait;
- struct scatterlist in_sg, out_sg;
- uint8_t der_pub_key[PUB_KEY_BUF_SIZE];
- uint32_t der_pub_key_len;
- int ret;
-
- pr_devel("==>%s()\n", __func__);
-
- ret = determine_akcipher(params->encoding, params->hash_algo, alg_name);
- if (ret < 0)
- return ret;
-
- tfm = crypto_alloc_akcipher(alg_name, 0, 0);
- if (IS_ERR(tfm))
- return PTR_ERR(tfm);
-
- der_pub_key_len = derive_pub_key(tk->pub_key, tk->pub_key_len,
- der_pub_key);
-
- ret = crypto_akcipher_set_pub_key(tfm, der_pub_key, der_pub_key_len);
- if (ret < 0)
- goto error_free_tfm;
-
- ret = -ENOMEM;
- req = akcipher_request_alloc(tfm, GFP_KERNEL);
- if (!req)
- goto error_free_tfm;
-
- sg_init_one(&in_sg, in, params->in_len);
- sg_init_one(&out_sg, out, params->out_len);
- akcipher_request_set_crypt(req, &in_sg, &out_sg, params->in_len,
- params->out_len);
- crypto_init_wait(&cwait);
- akcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG |
- CRYPTO_TFM_REQ_MAY_SLEEP,
- crypto_req_done, &cwait);
-
- ret = crypto_akcipher_encrypt(req);
- ret = crypto_wait_req(ret, &cwait);
-
- if (ret == 0)
- ret = req->dst_len;
-
- akcipher_request_free(req);
-error_free_tfm:
- crypto_free_akcipher(tfm);
- pr_devel("<==%s() = %d\n", __func__, ret);
- return ret;
-}
-
-/*
- * Decryption operation is performed with the private key in the TPM.
- */
-static int tpm_key_decrypt(struct tpm_key *tk,
- struct kernel_pkey_params *params,
- const void *in, void *out)
-{
- struct tpm_buf tb;
- uint32_t keyhandle;
- uint8_t srkauth[SHA1_DIGEST_SIZE];
- uint8_t keyauth[SHA1_DIGEST_SIZE];
- int r;
-
- pr_devel("==>%s()\n", __func__);
-
- if (params->hash_algo)
- return -ENOPKG;
-
- if (strcmp(params->encoding, "pkcs1"))
- return -ENOPKG;
-
- r = tpm_buf_init(&tb, 0, 0);
- if (r)
- return r;
-
- /* TODO: Handle a non-all zero SRK authorization */
- memset(srkauth, 0, sizeof(srkauth));
-
- r = tpm_loadkey2(&tb, SRKHANDLE, srkauth,
- tk->blob, tk->blob_len, &keyhandle);
- if (r < 0) {
- pr_devel("loadkey2 failed (%d)\n", r);
- goto error;
- }
-
- /* TODO: Handle a non-all zero key authorization */
- memset(keyauth, 0, sizeof(keyauth));
-
- r = tpm_unbind(&tb, keyhandle, keyauth,
- in, params->in_len, out, params->out_len);
- if (r < 0)
- pr_devel("tpm_unbind failed (%d)\n", r);
-
- if (tpm_flushspecific(&tb, keyhandle) < 0)
- pr_devel("flushspecific failed (%d)\n", r);
-
-error:
- tpm_buf_destroy(&tb);
- pr_devel("<==%s() = %d\n", __func__, r);
- return r;
-}
-
-/*
- * Hash algorithm OIDs plus ASN.1 DER wrappings [RFC4880 sec 5.2.2].
- */
-static const u8 digest_info_md5[] = {
- 0x30, 0x20, 0x30, 0x0c, 0x06, 0x08,
- 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x02, 0x05, /* OID */
- 0x05, 0x00, 0x04, 0x10
-};
-
-static const u8 digest_info_sha1[] = {
- 0x30, 0x21, 0x30, 0x09, 0x06, 0x05,
- 0x2b, 0x0e, 0x03, 0x02, 0x1a,
- 0x05, 0x00, 0x04, 0x14
-};
-
-static const u8 digest_info_rmd160[] = {
- 0x30, 0x21, 0x30, 0x09, 0x06, 0x05,
- 0x2b, 0x24, 0x03, 0x02, 0x01,
- 0x05, 0x00, 0x04, 0x14
-};
-
-static const u8 digest_info_sha224[] = {
- 0x30, 0x2d, 0x30, 0x0d, 0x06, 0x09,
- 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x04,
- 0x05, 0x00, 0x04, 0x1c
-};
-
-static const u8 digest_info_sha256[] = {
- 0x30, 0x31, 0x30, 0x0d, 0x06, 0x09,
- 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01,
- 0x05, 0x00, 0x04, 0x20
-};
-
-static const u8 digest_info_sha384[] = {
- 0x30, 0x41, 0x30, 0x0d, 0x06, 0x09,
- 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02,
- 0x05, 0x00, 0x04, 0x30
-};
-
-static const u8 digest_info_sha512[] = {
- 0x30, 0x51, 0x30, 0x0d, 0x06, 0x09,
- 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03,
- 0x05, 0x00, 0x04, 0x40
-};
-
-static const struct asn1_template {
- const char *name;
- const u8 *data;
- size_t size;
-} asn1_templates[] = {
-#define _(X) { #X, digest_info_##X, sizeof(digest_info_##X) }
- _(md5),
- _(sha1),
- _(rmd160),
- _(sha256),
- _(sha384),
- _(sha512),
- _(sha224),
- { NULL }
-#undef _
-};
-
-static const struct asn1_template *lookup_asn1(const char *name)
-{
- const struct asn1_template *p;
-
- for (p = asn1_templates; p->name; p++)
- if (strcmp(name, p->name) == 0)
- return p;
- return NULL;
-}
-
-/*
- * Sign operation is performed with the private key in the TPM.
- */
-static int tpm_key_sign(struct tpm_key *tk,
- struct kernel_pkey_params *params,
- const void *in, void *out)
-{
- struct tpm_buf tb;
- uint32_t keyhandle;
- uint8_t srkauth[SHA1_DIGEST_SIZE];
- uint8_t keyauth[SHA1_DIGEST_SIZE];
- void *asn1_wrapped = NULL;
- uint32_t in_len = params->in_len;
- int r;
-
- pr_devel("==>%s()\n", __func__);
-
- if (strcmp(params->encoding, "pkcs1"))
- return -ENOPKG;
-
- if (params->hash_algo) {
- const struct asn1_template *asn1 =
- lookup_asn1(params->hash_algo);
-
- if (!asn1)
- return -ENOPKG;
-
- /* request enough space for the ASN.1 template + input hash */
- asn1_wrapped = kzalloc(in_len + asn1->size, GFP_KERNEL);
- if (!asn1_wrapped)
- return -ENOMEM;
-
- /* Copy ASN.1 template, then the input */
- memcpy(asn1_wrapped, asn1->data, asn1->size);
- memcpy(asn1_wrapped + asn1->size, in, in_len);
-
- in = asn1_wrapped;
- in_len += asn1->size;
- }
-
- if (in_len > tk->key_len / 8 - 11) {
- r = -EOVERFLOW;
- goto error_free_asn1_wrapped;
- }
-
- r = tpm_buf_init(&tb, 0, 0);
- if (r)
- goto error_free_asn1_wrapped;
-
- /* TODO: Handle a non-all zero SRK authorization */
- memset(srkauth, 0, sizeof(srkauth));
-
- r = tpm_loadkey2(&tb, SRKHANDLE, srkauth,
- tk->blob, tk->blob_len, &keyhandle);
- if (r < 0) {
- pr_devel("loadkey2 failed (%d)\n", r);
- goto error_free_tb;
- }
-
- /* TODO: Handle a non-all zero key authorization */
- memset(keyauth, 0, sizeof(keyauth));
-
- r = tpm_sign(&tb, keyhandle, keyauth, in, in_len, out, params->out_len);
- if (r < 0)
- pr_devel("tpm_sign failed (%d)\n", r);
-
- if (tpm_flushspecific(&tb, keyhandle) < 0)
- pr_devel("flushspecific failed (%d)\n", r);
-
-error_free_tb:
- tpm_buf_destroy(&tb);
-error_free_asn1_wrapped:
- kfree(asn1_wrapped);
- pr_devel("<==%s() = %d\n", __func__, r);
- return r;
-}
-
-/*
- * Do encryption, decryption and signing ops.
- */
-static int tpm_key_eds_op(struct kernel_pkey_params *params,
- const void *in, void *out)
-{
- struct tpm_key *tk = params->key->payload.data[asym_crypto];
- int ret = -EOPNOTSUPP;
-
- /* Perform the encryption calculation. */
- switch (params->op) {
- case kernel_pkey_encrypt:
- ret = tpm_key_encrypt(tk, params, in, out);
- break;
- case kernel_pkey_decrypt:
- ret = tpm_key_decrypt(tk, params, in, out);
- break;
- case kernel_pkey_sign:
- ret = tpm_key_sign(tk, params, in, out);
- break;
- default:
- BUG();
- }
-
- return ret;
-}
-
-/*
- * Verify a signature using a public key.
- */
-static int tpm_key_verify_signature(const struct key *key,
- const struct public_key_signature *sig)
-{
- const struct tpm_key *tk = key->payload.data[asym_crypto];
- struct crypto_wait cwait;
- struct crypto_akcipher *tfm;
- struct akcipher_request *req;
- struct scatterlist src_sg[2];
- char alg_name[CRYPTO_MAX_ALG_NAME];
- uint8_t der_pub_key[PUB_KEY_BUF_SIZE];
- uint32_t der_pub_key_len;
- int ret;
-
- pr_devel("==>%s()\n", __func__);
-
- BUG_ON(!tk);
- BUG_ON(!sig);
- BUG_ON(!sig->s);
-
- if (!sig->digest)
- return -ENOPKG;
-
- ret = determine_akcipher(sig->encoding, sig->hash_algo, alg_name);
- if (ret < 0)
- return ret;
-
- tfm = crypto_alloc_akcipher(alg_name, 0, 0);
- if (IS_ERR(tfm))
- return PTR_ERR(tfm);
-
- der_pub_key_len = derive_pub_key(tk->pub_key, tk->pub_key_len,
- der_pub_key);
-
- ret = crypto_akcipher_set_pub_key(tfm, der_pub_key, der_pub_key_len);
- if (ret < 0)
- goto error_free_tfm;
-
- ret = -ENOMEM;
- req = akcipher_request_alloc(tfm, GFP_KERNEL);
- if (!req)
- goto error_free_tfm;
-
- sg_init_table(src_sg, 2);
- sg_set_buf(&src_sg[0], sig->s, sig->s_size);
- sg_set_buf(&src_sg[1], sig->digest, sig->digest_size);
- akcipher_request_set_crypt(req, src_sg, NULL, sig->s_size,
- sig->digest_size);
- crypto_init_wait(&cwait);
- akcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG |
- CRYPTO_TFM_REQ_MAY_SLEEP,
- crypto_req_done, &cwait);
- ret = crypto_wait_req(crypto_akcipher_verify(req), &cwait);
-
- akcipher_request_free(req);
-error_free_tfm:
- crypto_free_akcipher(tfm);
- pr_devel("<==%s() = %d\n", __func__, ret);
- if (WARN_ON_ONCE(ret > 0))
- ret = -EINVAL;
- return ret;
-}
-
-/*
- * Parse enough information out of TPM_KEY structure:
- * TPM_STRUCT_VER -> 4 bytes
- * TPM_KEY_USAGE -> 2 bytes
- * TPM_KEY_FLAGS -> 4 bytes
- * TPM_AUTH_DATA_USAGE -> 1 byte
- * TPM_KEY_PARMS -> variable
- * UINT32 PCRInfoSize -> 4 bytes
- * BYTE* -> PCRInfoSize bytes
- * TPM_STORE_PUBKEY
- * UINT32 encDataSize;
- * BYTE* -> encDataSize;
- *
- * TPM_KEY_PARMS:
- * TPM_ALGORITHM_ID -> 4 bytes
- * TPM_ENC_SCHEME -> 2 bytes
- * TPM_SIG_SCHEME -> 2 bytes
- * UINT32 parmSize -> 4 bytes
- * BYTE* -> variable
- */
-static int extract_key_parameters(struct tpm_key *tk)
-{
- const void *cur = tk->blob;
- uint32_t len = tk->blob_len;
- const void *pub_key;
- uint32_t sz;
- uint32_t key_len;
-
- if (len < 11)
- return -EBADMSG;
-
- /* Ensure this is a legacy key */
- if (get_unaligned_be16(cur + 4) != 0x0015)
- return -EBADMSG;
-
- /* Skip to TPM_KEY_PARMS */
- cur += 11;
- len -= 11;
-
- if (len < 12)
- return -EBADMSG;
-
- /* Make sure this is an RSA key */
- if (get_unaligned_be32(cur) != 0x00000001)
- return -EBADMSG;
-
- /* Make sure this is TPM_ES_RSAESPKCSv15 encoding scheme */
- if (get_unaligned_be16(cur + 4) != 0x0002)
- return -EBADMSG;
-
- /* Make sure this is TPM_SS_RSASSAPKCS1v15_DER signature scheme */
- if (get_unaligned_be16(cur + 6) != 0x0003)
- return -EBADMSG;
-
- sz = get_unaligned_be32(cur + 8);
- if (len < sz + 12)
- return -EBADMSG;
-
- /* Move to TPM_RSA_KEY_PARMS */
- len -= 12;
- cur += 12;
-
- /* Grab the RSA key length */
- key_len = get_unaligned_be32(cur);
-
- switch (key_len) {
- case 512:
- case 1024:
- case 1536:
- case 2048:
- break;
- default:
- return -EINVAL;
- }
-
- /* Move just past TPM_KEY_PARMS */
- cur += sz;
- len -= sz;
-
- if (len < 4)
- return -EBADMSG;
-
- sz = get_unaligned_be32(cur);
- if (len < 4 + sz)
- return -EBADMSG;
-
- /* Move to TPM_STORE_PUBKEY */
- cur += 4 + sz;
- len -= 4 + sz;
-
- /* Grab the size of the public key, it should jive with the key size */
- sz = get_unaligned_be32(cur);
- if (sz > 256)
- return -EINVAL;
-
- pub_key = cur + 4;
-
- tk->key_len = key_len;
- tk->pub_key = pub_key;
- tk->pub_key_len = sz;
-
- return 0;
-}
-
-/* Given the blob, parse it and load it into the TPM */
-struct tpm_key *tpm_key_create(const void *blob, uint32_t blob_len)
-{
- int r;
- struct tpm_key *tk;
-
- r = tpm_is_tpm2(NULL);
- if (r < 0)
- goto error;
-
- /* We don't support TPM2 yet */
- if (r > 0) {
- r = -ENODEV;
- goto error;
- }
-
- r = -ENOMEM;
- tk = kzalloc(sizeof(struct tpm_key), GFP_KERNEL);
- if (!tk)
- goto error;
-
- tk->blob = kmemdup(blob, blob_len, GFP_KERNEL);
- if (!tk->blob)
- goto error_memdup;
-
- tk->blob_len = blob_len;
-
- r = extract_key_parameters(tk);
- if (r < 0)
- goto error_extract;
-
- return tk;
-
-error_extract:
- kfree(tk->blob);
- tk->blob_len = 0;
-error_memdup:
- kfree(tk);
-error:
- return ERR_PTR(r);
-}
-EXPORT_SYMBOL_GPL(tpm_key_create);
-
-/*
- * TPM-based asymmetric key subtype
- */
-struct asymmetric_key_subtype asym_tpm_subtype = {
- .owner = THIS_MODULE,
- .name = "asym_tpm",
- .name_len = sizeof("asym_tpm") - 1,
- .describe = asym_tpm_describe,
- .destroy = asym_tpm_destroy,
- .query = tpm_key_query,
- .eds_op = tpm_key_eds_op,
- .verify_signature = tpm_key_verify_signature,
-};
-EXPORT_SYMBOL_GPL(asym_tpm_subtype);
-
-MODULE_DESCRIPTION("TPM based asymmetric key subtype");
-MODULE_AUTHOR("Intel Corporation");
-MODULE_LICENSE("GPL v2");
diff --git a/crypto/asymmetric_keys/pkcs7_verify.c b/crypto/asymmetric_keys/pkcs7_verify.c
index 0b4d07aa8811..f6321c785714 100644
--- a/crypto/asymmetric_keys/pkcs7_verify.c
+++ b/crypto/asymmetric_keys/pkcs7_verify.c
@@ -174,12 +174,6 @@ static int pkcs7_find_key(struct pkcs7_message *pkcs7,
pr_devel("Sig %u: Found cert serial match X.509[%u]\n",
sinfo->index, certix);
- if (strcmp(x509->pub->pkey_algo, sinfo->sig->pkey_algo) != 0) {
- pr_warn("Sig %u: X.509 algo and PKCS#7 sig algo don't match\n",
- sinfo->index);
- continue;
- }
-
sinfo->signer = x509;
return 0;
}
@@ -226,9 +220,6 @@ static int pkcs7_verify_sig_chain(struct pkcs7_message *pkcs7,
return 0;
}
- if (x509->unsupported_key)
- goto unsupported_crypto_in_x509;
-
pr_debug("- issuer %s\n", x509->issuer);
sig = x509->sig;
if (sig->auth_ids[0])
@@ -245,7 +236,7 @@ static int pkcs7_verify_sig_chain(struct pkcs7_message *pkcs7,
* authority.
*/
if (x509->unsupported_sig)
- goto unsupported_crypto_in_x509;
+ goto unsupported_sig_in_x509;
x509->signer = x509;
pr_debug("- self-signed\n");
return 0;
@@ -309,7 +300,7 @@ static int pkcs7_verify_sig_chain(struct pkcs7_message *pkcs7,
might_sleep();
}
-unsupported_crypto_in_x509:
+unsupported_sig_in_x509:
/* Just prune the certificate chain at this point if we lack some
* crypto module to go further. Note, however, we don't want to set
* sinfo->unsupported_crypto as the signed info block may still be
diff --git a/crypto/asymmetric_keys/public_key.c b/crypto/asymmetric_keys/public_key.c
index 4fefb219bfdc..7c9e6be35c30 100644
--- a/crypto/asymmetric_keys/public_key.c
+++ b/crypto/asymmetric_keys/public_key.c
@@ -60,39 +60,83 @@ static void public_key_destroy(void *payload0, void *payload3)
}
/*
- * Determine the crypto algorithm name.
+ * Given a public_key, and an encoding and hash_algo to be used for signing
+ * and/or verification with that key, determine the name of the corresponding
+ * akcipher algorithm. Also check that encoding and hash_algo are allowed.
*/
-static
-int software_key_determine_akcipher(const char *encoding,
- const char *hash_algo,
- const struct public_key *pkey,
- char alg_name[CRYPTO_MAX_ALG_NAME])
+static int
+software_key_determine_akcipher(const struct public_key *pkey,
+ const char *encoding, const char *hash_algo,
+ char alg_name[CRYPTO_MAX_ALG_NAME])
{
int n;
- if (strcmp(encoding, "pkcs1") == 0) {
- /* The data wangled by the RSA algorithm is typically padded
- * and encoded in some manner, such as EMSA-PKCS1-1_5 [RFC3447
- * sec 8.2].
+ if (!encoding)
+ return -EINVAL;
+
+ if (strcmp(pkey->pkey_algo, "rsa") == 0) {
+ /*
+ * RSA signatures usually use EMSA-PKCS1-1_5 [RFC3447 sec 8.2].
+ */
+ if (strcmp(encoding, "pkcs1") == 0) {
+ if (!hash_algo)
+ n = snprintf(alg_name, CRYPTO_MAX_ALG_NAME,
+ "pkcs1pad(%s)",
+ pkey->pkey_algo);
+ else
+ n = snprintf(alg_name, CRYPTO_MAX_ALG_NAME,
+ "pkcs1pad(%s,%s)",
+ pkey->pkey_algo, hash_algo);
+ return n >= CRYPTO_MAX_ALG_NAME ? -EINVAL : 0;
+ }
+ if (strcmp(encoding, "raw") != 0)
+ return -EINVAL;
+ /*
+ * Raw RSA cannot differentiate between different hash
+ * algorithms.
+ */
+ if (hash_algo)
+ return -EINVAL;
+ } else if (strncmp(pkey->pkey_algo, "ecdsa", 5) == 0) {
+ if (strcmp(encoding, "x962") != 0)
+ return -EINVAL;
+ /*
+ * ECDSA signatures are taken over a raw hash, so they don't
+ * differentiate between different hash algorithms. That means
+ * that the verifier should hard-code a specific hash algorithm.
+ * Unfortunately, in practice ECDSA is used with multiple SHAs,
+ * so we have to allow all of them and not just one.
*/
if (!hash_algo)
- n = snprintf(alg_name, CRYPTO_MAX_ALG_NAME,
- "pkcs1pad(%s)",
- pkey->pkey_algo);
- else
- n = snprintf(alg_name, CRYPTO_MAX_ALG_NAME,
- "pkcs1pad(%s,%s)",
- pkey->pkey_algo, hash_algo);
- return n >= CRYPTO_MAX_ALG_NAME ? -EINVAL : 0;
- }
-
- if (strcmp(encoding, "raw") == 0 ||
- strcmp(encoding, "x962") == 0) {
- strcpy(alg_name, pkey->pkey_algo);
- return 0;
+ return -EINVAL;
+ if (strcmp(hash_algo, "sha1") != 0 &&
+ strcmp(hash_algo, "sha224") != 0 &&
+ strcmp(hash_algo, "sha256") != 0 &&
+ strcmp(hash_algo, "sha384") != 0 &&
+ strcmp(hash_algo, "sha512") != 0)
+ return -EINVAL;
+ } else if (strcmp(pkey->pkey_algo, "sm2") == 0) {
+ if (strcmp(encoding, "raw") != 0)
+ return -EINVAL;
+ if (!hash_algo)
+ return -EINVAL;
+ if (strcmp(hash_algo, "sm3") != 0)
+ return -EINVAL;
+ } else if (strcmp(pkey->pkey_algo, "ecrdsa") == 0) {
+ if (strcmp(encoding, "raw") != 0)
+ return -EINVAL;
+ if (!hash_algo)
+ return -EINVAL;
+ if (strcmp(hash_algo, "streebog256") != 0 &&
+ strcmp(hash_algo, "streebog512") != 0)
+ return -EINVAL;
+ } else {
+ /* Unknown public key algorithm */
+ return -ENOPKG;
}
-
- return -ENOPKG;
+ if (strscpy(alg_name, pkey->pkey_algo, CRYPTO_MAX_ALG_NAME) < 0)
+ return -EINVAL;
+ return 0;
}
static u8 *pkey_pack_u32(u8 *dst, u32 val)
@@ -113,9 +157,8 @@ static int software_key_query(const struct kernel_pkey_params *params,
u8 *key, *ptr;
int ret, len;
- ret = software_key_determine_akcipher(params->encoding,
- params->hash_algo,
- pkey, alg_name);
+ ret = software_key_determine_akcipher(pkey, params->encoding,
+ params->hash_algo, alg_name);
if (ret < 0)
return ret;
@@ -179,9 +222,8 @@ static int software_key_eds_op(struct kernel_pkey_params *params,
pr_devel("==>%s()\n", __func__);
- ret = software_key_determine_akcipher(params->encoding,
- params->hash_algo,
- pkey, alg_name);
+ ret = software_key_determine_akcipher(pkey, params->encoding,
+ params->hash_algo, alg_name);
if (ret < 0)
return ret;
@@ -325,9 +367,23 @@ int public_key_verify_signature(const struct public_key *pkey,
BUG_ON(!sig);
BUG_ON(!sig->s);
- ret = software_key_determine_akcipher(sig->encoding,
- sig->hash_algo,
- pkey, alg_name);
+ /*
+ * If the signature specifies a public key algorithm, it *must* match
+ * the key's actual public key algorithm.
+ *
+ * Small exception: ECDSA signatures don't specify the curve, but ECDSA
+ * keys do. So the strings can mismatch slightly in that case:
+ * "ecdsa-nist-*" for the key, but "ecdsa" for the signature.
+ */
+ if (sig->pkey_algo) {
+ if (strcmp(pkey->pkey_algo, sig->pkey_algo) != 0 &&
+ (strncmp(pkey->pkey_algo, "ecdsa-", 6) != 0 ||
+ strcmp(sig->pkey_algo, "ecdsa") != 0))
+ return -EKEYREJECTED;
+ }
+
+ ret = software_key_determine_akcipher(pkey, sig->encoding,
+ sig->hash_algo, alg_name);
if (ret < 0)
return ret;
diff --git a/crypto/asymmetric_keys/signature.c b/crypto/asymmetric_keys/signature.c
index 4aff3eebec17..2deff81f8af5 100644
--- a/crypto/asymmetric_keys/signature.c
+++ b/crypto/asymmetric_keys/signature.c
@@ -35,7 +35,7 @@ void public_key_signature_free(struct public_key_signature *sig)
EXPORT_SYMBOL_GPL(public_key_signature_free);
/**
- * query_asymmetric_key - Get information about an aymmetric key.
+ * query_asymmetric_key - Get information about an asymmetric key.
* @params: Various parameters.
* @info: Where to put the information.
*/
diff --git a/crypto/asymmetric_keys/tpm.asn1 b/crypto/asymmetric_keys/tpm.asn1
deleted file mode 100644
index d7f194232f30..000000000000
--- a/crypto/asymmetric_keys/tpm.asn1
+++ /dev/null
@@ -1,5 +0,0 @@
---
--- Unencryted TPM Blob. For details of the format, see:
--- http://david.woodhou.se/draft-woodhouse-cert-best-practice.html#I-D.mavrogiannopoulos-tpmuri
---
-PrivateKeyInfo ::= OCTET STRING ({ tpm_note_key })
diff --git a/crypto/asymmetric_keys/tpm_parser.c b/crypto/asymmetric_keys/tpm_parser.c
deleted file mode 100644
index 96405d8dcd98..000000000000
--- a/crypto/asymmetric_keys/tpm_parser.c
+++ /dev/null
@@ -1,102 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-#define pr_fmt(fmt) "TPM-PARSER: "fmt
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/export.h>
-#include <linux/slab.h>
-#include <linux/err.h>
-#include <keys/asymmetric-subtype.h>
-#include <keys/asymmetric-parser.h>
-#include <crypto/asym_tpm_subtype.h>
-#include "tpm.asn1.h"
-
-struct tpm_parse_context {
- const void *blob;
- u32 blob_len;
-};
-
-/*
- * Note the key data of the ASN.1 blob.
- */
-int tpm_note_key(void *context, size_t hdrlen,
- unsigned char tag,
- const void *value, size_t vlen)
-{
- struct tpm_parse_context *ctx = context;
-
- ctx->blob = value;
- ctx->blob_len = vlen;
-
- return 0;
-}
-
-/*
- * Parse a TPM-encrypted private key blob.
- */
-static struct tpm_key *tpm_parse(const void *data, size_t datalen)
-{
- struct tpm_parse_context ctx;
- long ret;
-
- memset(&ctx, 0, sizeof(ctx));
-
- /* Attempt to decode the private key */
- ret = asn1_ber_decoder(&tpm_decoder, &ctx, data, datalen);
- if (ret < 0)
- goto error;
-
- return tpm_key_create(ctx.blob, ctx.blob_len);
-
-error:
- return ERR_PTR(ret);
-}
-/*
- * Attempt to parse a data blob for a key as a TPM private key blob.
- */
-static int tpm_key_preparse(struct key_preparsed_payload *prep)
-{
- struct tpm_key *tk;
-
- /*
- * TPM 1.2 keys are max 2048 bits long, so assume the blob is no
- * more than 4x that
- */
- if (prep->datalen > 256 * 4)
- return -EMSGSIZE;
-
- tk = tpm_parse(prep->data, prep->datalen);
-
- if (IS_ERR(tk))
- return PTR_ERR(tk);
-
- /* We're pinning the module by being linked against it */
- __module_get(asym_tpm_subtype.owner);
- prep->payload.data[asym_subtype] = &asym_tpm_subtype;
- prep->payload.data[asym_key_ids] = NULL;
- prep->payload.data[asym_crypto] = tk;
- prep->payload.data[asym_auth] = NULL;
- prep->quotalen = 100;
- return 0;
-}
-
-static struct asymmetric_key_parser tpm_key_parser = {
- .owner = THIS_MODULE,
- .name = "tpm_parser",
- .parse = tpm_key_preparse,
-};
-
-static int __init tpm_key_init(void)
-{
- return register_asymmetric_key_parser(&tpm_key_parser);
-}
-
-static void __exit tpm_key_exit(void)
-{
- unregister_asymmetric_key_parser(&tpm_key_parser);
-}
-
-module_init(tpm_key_init);
-module_exit(tpm_key_exit);
-
-MODULE_DESCRIPTION("TPM private key-blob parser");
-MODULE_LICENSE("GPL v2");
diff --git a/crypto/asymmetric_keys/x509.asn1 b/crypto/asymmetric_keys/x509.asn1
index 5c9f4e4a5231..92d59c32f96a 100644
--- a/crypto/asymmetric_keys/x509.asn1
+++ b/crypto/asymmetric_keys/x509.asn1
@@ -7,7 +7,7 @@ Certificate ::= SEQUENCE {
TBSCertificate ::= SEQUENCE {
version [ 0 ] Version DEFAULT,
serialNumber CertificateSerialNumber ({ x509_note_serial }),
- signature AlgorithmIdentifier ({ x509_note_pkey_algo }),
+ signature AlgorithmIdentifier ({ x509_note_sig_algo }),
issuer Name ({ x509_note_issuer }),
validity Validity,
subject Name ({ x509_note_subject }),
diff --git a/crypto/asymmetric_keys/x509_cert_parser.c b/crypto/asymmetric_keys/x509_cert_parser.c
index 083405eb80c3..2899ed80bb18 100644
--- a/crypto/asymmetric_keys/x509_cert_parser.c
+++ b/crypto/asymmetric_keys/x509_cert_parser.c
@@ -19,15 +19,13 @@
struct x509_parse_context {
struct x509_certificate *cert; /* Certificate being constructed */
unsigned long data; /* Start of data */
- const void *cert_start; /* Start of cert content */
const void *key; /* Key data */
size_t key_size; /* Size of key data */
const void *params; /* Key parameters */
size_t params_size; /* Size of key parameters */
- enum OID key_algo; /* Public key algorithm */
+ enum OID key_algo; /* Algorithm used by the cert's key */
enum OID last_oid; /* Last OID encountered */
- enum OID algo_oid; /* Algorithm OID */
- unsigned char nr_mpi; /* Number of MPIs stored */
+ enum OID sig_algo; /* Algorithm used to sign the cert */
u8 o_size; /* Size of organizationName (O) */
u8 cn_size; /* Size of commonName (CN) */
u8 email_size; /* Size of emailAddress */
@@ -187,11 +185,10 @@ int x509_note_tbs_certificate(void *context, size_t hdrlen,
}
/*
- * Record the public key algorithm
+ * Record the algorithm that was used to sign this certificate.
*/
-int x509_note_pkey_algo(void *context, size_t hdrlen,
- unsigned char tag,
- const void *value, size_t vlen)
+int x509_note_sig_algo(void *context, size_t hdrlen, unsigned char tag,
+ const void *value, size_t vlen)
{
struct x509_parse_context *ctx = context;
@@ -263,22 +260,22 @@ int x509_note_pkey_algo(void *context, size_t hdrlen,
rsa_pkcs1:
ctx->cert->sig->pkey_algo = "rsa";
ctx->cert->sig->encoding = "pkcs1";
- ctx->algo_oid = ctx->last_oid;
+ ctx->sig_algo = ctx->last_oid;
return 0;
ecrdsa:
ctx->cert->sig->pkey_algo = "ecrdsa";
ctx->cert->sig->encoding = "raw";
- ctx->algo_oid = ctx->last_oid;
+ ctx->sig_algo = ctx->last_oid;
return 0;
sm2:
ctx->cert->sig->pkey_algo = "sm2";
ctx->cert->sig->encoding = "raw";
- ctx->algo_oid = ctx->last_oid;
+ ctx->sig_algo = ctx->last_oid;
return 0;
ecdsa:
ctx->cert->sig->pkey_algo = "ecdsa";
ctx->cert->sig->encoding = "x962";
- ctx->algo_oid = ctx->last_oid;
+ ctx->sig_algo = ctx->last_oid;
return 0;
}
@@ -291,11 +288,16 @@ int x509_note_signature(void *context, size_t hdrlen,
{
struct x509_parse_context *ctx = context;
- pr_debug("Signature type: %u size %zu\n", ctx->last_oid, vlen);
+ pr_debug("Signature: alg=%u, size=%zu\n", ctx->last_oid, vlen);
- if (ctx->last_oid != ctx->algo_oid) {
- pr_warn("Got cert with pkey (%u) and sig (%u) algorithm OIDs\n",
- ctx->algo_oid, ctx->last_oid);
+ /*
+ * In X.509 certificates, the signature's algorithm is stored in two
+ * places: inside the TBSCertificate (the data that is signed), and
+ * alongside the signature. These *must* match.
+ */
+ if (ctx->last_oid != ctx->sig_algo) {
+ pr_warn("signatureAlgorithm (%u) differs from tbsCertificate.signature (%u)\n",
+ ctx->last_oid, ctx->sig_algo);
return -EINVAL;
}
diff --git a/crypto/asymmetric_keys/x509_parser.h b/crypto/asymmetric_keys/x509_parser.h
index c233f136fb35..97a886cbe01c 100644
--- a/crypto/asymmetric_keys/x509_parser.h
+++ b/crypto/asymmetric_keys/x509_parser.h
@@ -22,7 +22,7 @@ struct x509_certificate {
time64_t valid_to;
const void *tbs; /* Signed data */
unsigned tbs_size; /* Size of signed data */
- unsigned raw_sig_size; /* Size of sigature */
+ unsigned raw_sig_size; /* Size of signature */
const void *raw_sig; /* Signature data */
const void *raw_serial; /* Raw serial number in ASN.1 */
unsigned raw_serial_size;
@@ -36,7 +36,6 @@ struct x509_certificate {
bool seen; /* Infinite recursion prevention */
bool verified;
bool self_signed; /* T if self-signed (check unsupported_sig too) */
- bool unsupported_key; /* T if key uses unsupported crypto */
bool unsupported_sig; /* T if signature uses unsupported crypto */
bool blacklisted;
};
diff --git a/crypto/asymmetric_keys/x509_public_key.c b/crypto/asymmetric_keys/x509_public_key.c
index fe14cae115b5..91a4ad50dea2 100644
--- a/crypto/asymmetric_keys/x509_public_key.c
+++ b/crypto/asymmetric_keys/x509_public_key.c
@@ -33,18 +33,6 @@ int x509_get_sig_params(struct x509_certificate *cert)
sig->data = cert->tbs;
sig->data_size = cert->tbs_size;
- if (!cert->pub->pkey_algo)
- cert->unsupported_key = true;
-
- if (!sig->pkey_algo)
- cert->unsupported_sig = true;
-
- /* We check the hash if we can - even if we can't then verify it */
- if (!sig->hash_algo) {
- cert->unsupported_sig = true;
- return 0;
- }
-
sig->s = kmemdup(cert->raw_sig, cert->raw_sig_size, GFP_KERNEL);
if (!sig->s)
return -ENOMEM;
@@ -128,12 +116,6 @@ int x509_check_for_self_signed(struct x509_certificate *cert)
goto out;
}
- ret = -EKEYREJECTED;
- if (strcmp(cert->pub->pkey_algo, cert->sig->pkey_algo) != 0 &&
- (strncmp(cert->pub->pkey_algo, "ecdsa-", 6) != 0 ||
- strcmp(cert->sig->pkey_algo, "ecdsa") != 0))
- goto out;
-
ret = public_key_verify_signature(cert->pub, cert->sig);
if (ret < 0) {
if (ret == -ENOPKG) {
@@ -173,12 +155,6 @@ static int x509_key_preparse(struct key_preparsed_payload *prep)
pr_devel("Cert Issuer: %s\n", cert->issuer);
pr_devel("Cert Subject: %s\n", cert->subject);
-
- if (cert->unsupported_key) {
- ret = -ENOPKG;
- goto error_free_cert;
- }
-
pr_devel("Cert Key Algo: %s\n", cert->pub->pkey_algo);
pr_devel("Cert Valid period: %lld-%lld\n", cert->valid_from, cert->valid_to);
diff --git a/crypto/async_tx/async_xor.c b/crypto/async_tx/async_xor.c
index d8a91521144e..1a3855284091 100644
--- a/crypto/async_tx/async_xor.c
+++ b/crypto/async_tx/async_xor.c
@@ -170,8 +170,8 @@ dma_xor_aligned_offsets(struct dma_device *device, unsigned int offset,
*
* xor_blocks always uses the dest as a source so the
* ASYNC_TX_XOR_ZERO_DST flag must be set to not include dest data in
- * the calculation. The assumption with dma eninges is that they only
- * use the destination buffer as a source when it is explicity specified
+ * the calculation. The assumption with dma engines is that they only
+ * use the destination buffer as a source when it is explicitly specified
* in the source list.
*
* src_list note: if the dest is also a source it must be at index zero.
@@ -261,8 +261,8 @@ EXPORT_SYMBOL_GPL(async_xor_offs);
*
* xor_blocks always uses the dest as a source so the
* ASYNC_TX_XOR_ZERO_DST flag must be set to not include dest data in
- * the calculation. The assumption with dma eninges is that they only
- * use the destination buffer as a source when it is explicity specified
+ * the calculation. The assumption with dma engines is that they only
+ * use the destination buffer as a source when it is explicitly specified
* in the source list.
*
* src_list note: if the dest is also a source it must be at index zero.
diff --git a/crypto/async_tx/raid6test.c b/crypto/async_tx/raid6test.c
index 66db82e5a3b1..c9d218e53bcb 100644
--- a/crypto/async_tx/raid6test.c
+++ b/crypto/async_tx/raid6test.c
@@ -217,7 +217,7 @@ static int raid6_test(void)
err += test(12, &tests);
}
- /* the 24 disk case is special for ioatdma as it is the boudary point
+ /* the 24 disk case is special for ioatdma as it is the boundary point
* at which it needs to switch from 8-source ops to 16-source
* ops for continuation (assumes DMA_HAS_PQ_CONTINUE is not set)
*/
@@ -241,7 +241,7 @@ static void raid6_test_exit(void)
}
/* when compiled-in wait for drivers to load first (assumes dma drivers
- * are also compliled-in)
+ * are also compiled-in)
*/
late_initcall(raid6_test);
module_exit(raid6_test_exit);
diff --git a/crypto/authenc.c b/crypto/authenc.c
index 670bf1a01d00..17f674a7cdff 100644
--- a/crypto/authenc.c
+++ b/crypto/authenc.c
@@ -253,7 +253,7 @@ static int crypto_authenc_decrypt_tail(struct aead_request *req,
dst = scatterwalk_ffwd(areq_ctx->dst, req->dst, req->assoclen);
skcipher_request_set_tfm(skreq, ctx->enc);
- skcipher_request_set_callback(skreq, aead_request_flags(req),
+ skcipher_request_set_callback(skreq, flags,
req->base.complete, req->base.data);
skcipher_request_set_crypt(skreq, src, dst,
req->cryptlen - authsize, req->iv);
diff --git a/crypto/blake2s_generic.c b/crypto/blake2s_generic.c
index 72fe480f9bd6..5f96a21f8788 100644
--- a/crypto/blake2s_generic.c
+++ b/crypto/blake2s_generic.c
@@ -15,12 +15,12 @@
static int crypto_blake2s_update_generic(struct shash_desc *desc,
const u8 *in, unsigned int inlen)
{
- return crypto_blake2s_update(desc, in, inlen, blake2s_compress_generic);
+ return crypto_blake2s_update(desc, in, inlen, true);
}
static int crypto_blake2s_final_generic(struct shash_desc *desc, u8 *out)
{
- return crypto_blake2s_final(desc, out, blake2s_compress_generic);
+ return crypto_blake2s_final(desc, out, true);
}
#define BLAKE2S_ALG(name, driver_name, digest_size) \
diff --git a/crypto/cfb.c b/crypto/cfb.c
index 0d664dfb47bc..5c36b7b65e2a 100644
--- a/crypto/cfb.c
+++ b/crypto/cfb.c
@@ -1,4 +1,4 @@
-//SPDX-License-Identifier: GPL-2.0
+// SPDX-License-Identifier: GPL-2.0
/*
* CFB: Cipher FeedBack mode
*
diff --git a/crypto/crypto_engine.c b/crypto/crypto_engine.c
index fb07da9920ee..6056a990c9f2 100644
--- a/crypto/crypto_engine.c
+++ b/crypto/crypto_engine.c
@@ -53,6 +53,7 @@ static void crypto_finalize_request(struct crypto_engine *engine,
dev_err(engine->dev, "failed to unprepare request\n");
}
}
+ lockdep_assert_in_softirq();
req->complete(req, err);
kthread_queue_work(engine->kworker, &engine->pump_requests);
diff --git a/crypto/dh.c b/crypto/dh.c
index 27e62a2a8027..4406aeb1ff61 100644
--- a/crypto/dh.c
+++ b/crypto/dh.c
@@ -10,11 +10,11 @@
#include <crypto/internal/kpp.h>
#include <crypto/kpp.h>
#include <crypto/dh.h>
+#include <crypto/rng.h>
#include <linux/mpi.h>
struct dh_ctx {
MPI p; /* Value is guaranteed to be set. */
- MPI q; /* Value is optional. */
MPI g; /* Value is guaranteed to be set. */
MPI xa; /* Value is guaranteed to be set. */
};
@@ -22,7 +22,6 @@ struct dh_ctx {
static void dh_clear_ctx(struct dh_ctx *ctx)
{
mpi_free(ctx->p);
- mpi_free(ctx->q);
mpi_free(ctx->g);
mpi_free(ctx->xa);
memset(ctx, 0, sizeof(*ctx));
@@ -62,12 +61,6 @@ static int dh_set_params(struct dh_ctx *ctx, struct dh *params)
if (!ctx->p)
return -EINVAL;
- if (params->q && params->q_size) {
- ctx->q = mpi_read_raw_data(params->q, params->q_size);
- if (!ctx->q)
- return -EINVAL;
- }
-
ctx->g = mpi_read_raw_data(params->g, params->g_size);
if (!ctx->g)
return -EINVAL;
@@ -104,11 +97,12 @@ err_clear_ctx:
/*
* SP800-56A public key verification:
*
- * * If Q is provided as part of the domain paramenters, a full validation
- * according to SP800-56A section 5.6.2.3.1 is performed.
+ * * For the safe-prime groups in FIPS mode, Q can be computed
+ * trivially from P and a full validation according to SP800-56A
+ * section 5.6.2.3.1 is performed.
*
- * * If Q is not provided, a partial validation according to SP800-56A section
- * 5.6.2.3.2 is performed.
+ * * For all other sets of group parameters, only a partial validation
+ * according to SP800-56A section 5.6.2.3.2 is performed.
*/
static int dh_is_pubkey_valid(struct dh_ctx *ctx, MPI y)
{
@@ -119,21 +113,40 @@ static int dh_is_pubkey_valid(struct dh_ctx *ctx, MPI y)
* Step 1: Verify that 2 <= y <= p - 2.
*
* The upper limit check is actually y < p instead of y < p - 1
- * as the mpi_sub_ui function is yet missing.
+ * in order to save one mpi_sub_ui() invocation here. Note that
+ * p - 1 is the non-trivial element of the subgroup of order 2 and
+ * thus, the check on y^q below would fail if y == p - 1.
*/
if (mpi_cmp_ui(y, 1) < 1 || mpi_cmp(y, ctx->p) >= 0)
return -EINVAL;
- /* Step 2: Verify that 1 = y^q mod p */
- if (ctx->q) {
- MPI val = mpi_alloc(0);
+ /*
+ * Step 2: Verify that 1 = y^q mod p
+ *
+ * For the safe-prime groups q = (p - 1)/2.
+ */
+ if (fips_enabled) {
+ MPI val, q;
int ret;
+ val = mpi_alloc(0);
if (!val)
return -ENOMEM;
- ret = mpi_powm(val, y, ctx->q, ctx->p);
+ q = mpi_alloc(mpi_get_nlimbs(ctx->p));
+ if (!q) {
+ mpi_free(val);
+ return -ENOMEM;
+ }
+
+ /*
+ * ->p is odd, so no need to explicitly subtract one
+ * from it before shifting to the right.
+ */
+ mpi_rshift(q, ctx->p, 1);
+ ret = mpi_powm(val, y, q, ctx->p);
+ mpi_free(q);
if (ret) {
mpi_free(val);
return ret;
@@ -263,13 +276,645 @@ static struct kpp_alg dh = {
},
};
+
+struct dh_safe_prime {
+ unsigned int max_strength;
+ unsigned int p_size;
+ const char *p;
+};
+
+static const char safe_prime_g[] = { 2 };
+
+struct dh_safe_prime_instance_ctx {
+ struct crypto_kpp_spawn dh_spawn;
+ const struct dh_safe_prime *safe_prime;
+};
+
+struct dh_safe_prime_tfm_ctx {
+ struct crypto_kpp *dh_tfm;
+};
+
+static void dh_safe_prime_free_instance(struct kpp_instance *inst)
+{
+ struct dh_safe_prime_instance_ctx *ctx = kpp_instance_ctx(inst);
+
+ crypto_drop_kpp(&ctx->dh_spawn);
+ kfree(inst);
+}
+
+static inline struct dh_safe_prime_instance_ctx *dh_safe_prime_instance_ctx(
+ struct crypto_kpp *tfm)
+{
+ return kpp_instance_ctx(kpp_alg_instance(tfm));
+}
+
+static int dh_safe_prime_init_tfm(struct crypto_kpp *tfm)
+{
+ struct dh_safe_prime_instance_ctx *inst_ctx =
+ dh_safe_prime_instance_ctx(tfm);
+ struct dh_safe_prime_tfm_ctx *tfm_ctx = kpp_tfm_ctx(tfm);
+
+ tfm_ctx->dh_tfm = crypto_spawn_kpp(&inst_ctx->dh_spawn);
+ if (IS_ERR(tfm_ctx->dh_tfm))
+ return PTR_ERR(tfm_ctx->dh_tfm);
+
+ return 0;
+}
+
+static void dh_safe_prime_exit_tfm(struct crypto_kpp *tfm)
+{
+ struct dh_safe_prime_tfm_ctx *tfm_ctx = kpp_tfm_ctx(tfm);
+
+ crypto_free_kpp(tfm_ctx->dh_tfm);
+}
+
+static u64 __add_u64_to_be(__be64 *dst, unsigned int n, u64 val)
+{
+ unsigned int i;
+
+ for (i = n; val && i > 0; --i) {
+ u64 tmp = be64_to_cpu(dst[i - 1]);
+
+ tmp += val;
+ val = tmp >= val ? 0 : 1;
+ dst[i - 1] = cpu_to_be64(tmp);
+ }
+
+ return val;
+}
+
+static void *dh_safe_prime_gen_privkey(const struct dh_safe_prime *safe_prime,
+ unsigned int *key_size)
+{
+ unsigned int n, oversampling_size;
+ __be64 *key;
+ int err;
+ u64 h, o;
+
+ /*
+ * Generate a private key following NIST SP800-56Ar3,
+ * sec. 5.6.1.1.1 and 5.6.1.1.3 resp..
+ *
+ * 5.6.1.1.1: choose key length N such that
+ * 2 * ->max_strength <= N <= log2(q) + 1 = ->p_size * 8 - 1
+ * with q = (p - 1) / 2 for the safe-prime groups.
+ * Choose the lower bound's next power of two for N in order to
+ * avoid excessively large private keys while still
+ * maintaining some extra reserve beyond the bare minimum in
+ * most cases. Note that for each entry in safe_prime_groups[],
+ * the following holds for such N:
+ * - N >= 256, in particular it is a multiple of 2^6 = 64
+ * bits and
+ * - N < log2(q) + 1, i.e. N respects the upper bound.
+ */
+ n = roundup_pow_of_two(2 * safe_prime->max_strength);
+ WARN_ON_ONCE(n & ((1u << 6) - 1));
+ n >>= 6; /* Convert N into units of u64. */
+
+ /*
+ * Reserve one extra u64 to hold the extra random bits
+ * required as per 5.6.1.1.3.
+ */
+ oversampling_size = (n + 1) * sizeof(__be64);
+ key = kmalloc(oversampling_size, GFP_KERNEL);
+ if (!key)
+ return ERR_PTR(-ENOMEM);
+
+ /*
+ * 5.6.1.1.3, step 3 (and implicitly step 4): obtain N + 64
+ * random bits and interpret them as a big endian integer.
+ */
+ err = -EFAULT;
+ if (crypto_get_default_rng())
+ goto out_err;
+
+ err = crypto_rng_get_bytes(crypto_default_rng, (u8 *)key,
+ oversampling_size);
+ crypto_put_default_rng();
+ if (err)
+ goto out_err;
+
+ /*
+ * 5.6.1.1.3, step 5 is implicit: 2^N < q and thus,
+ * M = min(2^N, q) = 2^N.
+ *
+ * For step 6, calculate
+ * key = (key[] mod (M - 1)) + 1 = (key[] mod (2^N - 1)) + 1.
+ *
+ * In order to avoid expensive divisions, note that
+ * 2^N mod (2^N - 1) = 1 and thus, for any integer h,
+ * 2^N * h mod (2^N - 1) = h mod (2^N - 1) always holds.
+ * The big endian integer key[] composed of n + 1 64bit words
+ * may be written as key[] = h * 2^N + l, with h = key[0]
+ * representing the 64 most significant bits and l
+ * corresponding to the remaining 2^N bits. With the remark
+ * from above,
+ * h * 2^N + l mod (2^N - 1) = l + h mod (2^N - 1).
+ * As both, l and h are less than 2^N, their sum after
+ * this first reduction is guaranteed to be <= 2^(N + 1) - 2.
+ * Or equivalently, that their sum can again be written as
+ * h' * 2^N + l' with h' now either zero or one and if one,
+ * then l' <= 2^N - 2. Thus, all bits at positions >= N will
+ * be zero after a second reduction:
+ * h' * 2^N + l' mod (2^N - 1) = l' + h' mod (2^N - 1).
+ * At this point, it is still possible that
+ * l' + h' = 2^N - 1, i.e. that l' + h' mod (2^N - 1)
+ * is zero. This condition will be detected below by means of
+ * the final increment overflowing in this case.
+ */
+ h = be64_to_cpu(key[0]);
+ h = __add_u64_to_be(key + 1, n, h);
+ h = __add_u64_to_be(key + 1, n, h);
+ WARN_ON_ONCE(h);
+
+ /* Increment to obtain the final result. */
+ o = __add_u64_to_be(key + 1, n, 1);
+ /*
+ * The overflow bit o from the increment is either zero or
+ * one. If zero, key[1:n] holds the final result in big-endian
+ * order. If one, key[1:n] is zero now, but needs to be set to
+ * one, c.f. above.
+ */
+ if (o)
+ key[n] = cpu_to_be64(1);
+
+ /* n is in units of u64, convert to bytes. */
+ *key_size = n << 3;
+ /* Strip the leading extra __be64, which is (virtually) zero by now. */
+ memmove(key, &key[1], *key_size);
+
+ return key;
+
+out_err:
+ kfree_sensitive(key);
+ return ERR_PTR(err);
+}
+
+static int dh_safe_prime_set_secret(struct crypto_kpp *tfm, const void *buffer,
+ unsigned int len)
+{
+ struct dh_safe_prime_instance_ctx *inst_ctx =
+ dh_safe_prime_instance_ctx(tfm);
+ struct dh_safe_prime_tfm_ctx *tfm_ctx = kpp_tfm_ctx(tfm);
+ struct dh params = {};
+ void *buf = NULL, *key = NULL;
+ unsigned int buf_size;
+ int err;
+
+ if (buffer) {
+ err = __crypto_dh_decode_key(buffer, len, &params);
+ if (err)
+ return err;
+ if (params.p_size || params.g_size)
+ return -EINVAL;
+ }
+
+ params.p = inst_ctx->safe_prime->p;
+ params.p_size = inst_ctx->safe_prime->p_size;
+ params.g = safe_prime_g;
+ params.g_size = sizeof(safe_prime_g);
+
+ if (!params.key_size) {
+ key = dh_safe_prime_gen_privkey(inst_ctx->safe_prime,
+ &params.key_size);
+ if (IS_ERR(key))
+ return PTR_ERR(key);
+ params.key = key;
+ }
+
+ buf_size = crypto_dh_key_len(&params);
+ buf = kmalloc(buf_size, GFP_KERNEL);
+ if (!buf) {
+ err = -ENOMEM;
+ goto out;
+ }
+
+ err = crypto_dh_encode_key(buf, buf_size, &params);
+ if (err)
+ goto out;
+
+ err = crypto_kpp_set_secret(tfm_ctx->dh_tfm, buf, buf_size);
+out:
+ kfree_sensitive(buf);
+ kfree_sensitive(key);
+ return err;
+}
+
+static void dh_safe_prime_complete_req(struct crypto_async_request *dh_req,
+ int err)
+{
+ struct kpp_request *req = dh_req->data;
+
+ kpp_request_complete(req, err);
+}
+
+static struct kpp_request *dh_safe_prime_prepare_dh_req(struct kpp_request *req)
+{
+ struct dh_safe_prime_tfm_ctx *tfm_ctx =
+ kpp_tfm_ctx(crypto_kpp_reqtfm(req));
+ struct kpp_request *dh_req = kpp_request_ctx(req);
+
+ kpp_request_set_tfm(dh_req, tfm_ctx->dh_tfm);
+ kpp_request_set_callback(dh_req, req->base.flags,
+ dh_safe_prime_complete_req, req);
+
+ kpp_request_set_input(dh_req, req->src, req->src_len);
+ kpp_request_set_output(dh_req, req->dst, req->dst_len);
+
+ return dh_req;
+}
+
+static int dh_safe_prime_generate_public_key(struct kpp_request *req)
+{
+ struct kpp_request *dh_req = dh_safe_prime_prepare_dh_req(req);
+
+ return crypto_kpp_generate_public_key(dh_req);
+}
+
+static int dh_safe_prime_compute_shared_secret(struct kpp_request *req)
+{
+ struct kpp_request *dh_req = dh_safe_prime_prepare_dh_req(req);
+
+ return crypto_kpp_compute_shared_secret(dh_req);
+}
+
+static unsigned int dh_safe_prime_max_size(struct crypto_kpp *tfm)
+{
+ struct dh_safe_prime_tfm_ctx *tfm_ctx = kpp_tfm_ctx(tfm);
+
+ return crypto_kpp_maxsize(tfm_ctx->dh_tfm);
+}
+
+static int __maybe_unused __dh_safe_prime_create(
+ struct crypto_template *tmpl, struct rtattr **tb,
+ const struct dh_safe_prime *safe_prime)
+{
+ struct kpp_instance *inst;
+ struct dh_safe_prime_instance_ctx *ctx;
+ const char *dh_name;
+ struct kpp_alg *dh_alg;
+ u32 mask;
+ int err;
+
+ err = crypto_check_attr_type(tb, CRYPTO_ALG_TYPE_KPP, &mask);
+ if (err)
+ return err;
+
+ dh_name = crypto_attr_alg_name(tb[1]);
+ if (IS_ERR(dh_name))
+ return PTR_ERR(dh_name);
+
+ inst = kzalloc(sizeof(*inst) + sizeof(*ctx), GFP_KERNEL);
+ if (!inst)
+ return -ENOMEM;
+
+ ctx = kpp_instance_ctx(inst);
+
+ err = crypto_grab_kpp(&ctx->dh_spawn, kpp_crypto_instance(inst),
+ dh_name, 0, mask);
+ if (err)
+ goto err_free_inst;
+
+ err = -EINVAL;
+ dh_alg = crypto_spawn_kpp_alg(&ctx->dh_spawn);
+ if (strcmp(dh_alg->base.cra_name, "dh"))
+ goto err_free_inst;
+
+ ctx->safe_prime = safe_prime;
+
+ err = crypto_inst_setname(kpp_crypto_instance(inst),
+ tmpl->name, &dh_alg->base);
+ if (err)
+ goto err_free_inst;
+
+ inst->alg.set_secret = dh_safe_prime_set_secret;
+ inst->alg.generate_public_key = dh_safe_prime_generate_public_key;
+ inst->alg.compute_shared_secret = dh_safe_prime_compute_shared_secret;
+ inst->alg.max_size = dh_safe_prime_max_size;
+ inst->alg.init = dh_safe_prime_init_tfm;
+ inst->alg.exit = dh_safe_prime_exit_tfm;
+ inst->alg.reqsize = sizeof(struct kpp_request) + dh_alg->reqsize;
+ inst->alg.base.cra_priority = dh_alg->base.cra_priority;
+ inst->alg.base.cra_module = THIS_MODULE;
+ inst->alg.base.cra_ctxsize = sizeof(struct dh_safe_prime_tfm_ctx);
+
+ inst->free = dh_safe_prime_free_instance;
+
+ err = kpp_register_instance(tmpl, inst);
+ if (err)
+ goto err_free_inst;
+
+ return 0;
+
+err_free_inst:
+ dh_safe_prime_free_instance(inst);
+
+ return err;
+}
+
+#ifdef CONFIG_CRYPTO_DH_RFC7919_GROUPS
+
+static const struct dh_safe_prime ffdhe2048_prime = {
+ .max_strength = 112,
+ .p_size = 256,
+ .p =
+ "\xff\xff\xff\xff\xff\xff\xff\xff\xad\xf8\x54\x58\xa2\xbb\x4a\x9a"
+ "\xaf\xdc\x56\x20\x27\x3d\x3c\xf1\xd8\xb9\xc5\x83\xce\x2d\x36\x95"
+ "\xa9\xe1\x36\x41\x14\x64\x33\xfb\xcc\x93\x9d\xce\x24\x9b\x3e\xf9"
+ "\x7d\x2f\xe3\x63\x63\x0c\x75\xd8\xf6\x81\xb2\x02\xae\xc4\x61\x7a"
+ "\xd3\xdf\x1e\xd5\xd5\xfd\x65\x61\x24\x33\xf5\x1f\x5f\x06\x6e\xd0"
+ "\x85\x63\x65\x55\x3d\xed\x1a\xf3\xb5\x57\x13\x5e\x7f\x57\xc9\x35"
+ "\x98\x4f\x0c\x70\xe0\xe6\x8b\x77\xe2\xa6\x89\xda\xf3\xef\xe8\x72"
+ "\x1d\xf1\x58\xa1\x36\xad\xe7\x35\x30\xac\xca\x4f\x48\x3a\x79\x7a"
+ "\xbc\x0a\xb1\x82\xb3\x24\xfb\x61\xd1\x08\xa9\x4b\xb2\xc8\xe3\xfb"
+ "\xb9\x6a\xda\xb7\x60\xd7\xf4\x68\x1d\x4f\x42\xa3\xde\x39\x4d\xf4"
+ "\xae\x56\xed\xe7\x63\x72\xbb\x19\x0b\x07\xa7\xc8\xee\x0a\x6d\x70"
+ "\x9e\x02\xfc\xe1\xcd\xf7\xe2\xec\xc0\x34\x04\xcd\x28\x34\x2f\x61"
+ "\x91\x72\xfe\x9c\xe9\x85\x83\xff\x8e\x4f\x12\x32\xee\xf2\x81\x83"
+ "\xc3\xfe\x3b\x1b\x4c\x6f\xad\x73\x3b\xb5\xfc\xbc\x2e\xc2\x20\x05"
+ "\xc5\x8e\xf1\x83\x7d\x16\x83\xb2\xc6\xf3\x4a\x26\xc1\xb2\xef\xfa"
+ "\x88\x6b\x42\x38\x61\x28\x5c\x97\xff\xff\xff\xff\xff\xff\xff\xff",
+};
+
+static const struct dh_safe_prime ffdhe3072_prime = {
+ .max_strength = 128,
+ .p_size = 384,
+ .p =
+ "\xff\xff\xff\xff\xff\xff\xff\xff\xad\xf8\x54\x58\xa2\xbb\x4a\x9a"
+ "\xaf\xdc\x56\x20\x27\x3d\x3c\xf1\xd8\xb9\xc5\x83\xce\x2d\x36\x95"
+ "\xa9\xe1\x36\x41\x14\x64\x33\xfb\xcc\x93\x9d\xce\x24\x9b\x3e\xf9"
+ "\x7d\x2f\xe3\x63\x63\x0c\x75\xd8\xf6\x81\xb2\x02\xae\xc4\x61\x7a"
+ "\xd3\xdf\x1e\xd5\xd5\xfd\x65\x61\x24\x33\xf5\x1f\x5f\x06\x6e\xd0"
+ "\x85\x63\x65\x55\x3d\xed\x1a\xf3\xb5\x57\x13\x5e\x7f\x57\xc9\x35"
+ "\x98\x4f\x0c\x70\xe0\xe6\x8b\x77\xe2\xa6\x89\xda\xf3\xef\xe8\x72"
+ "\x1d\xf1\x58\xa1\x36\xad\xe7\x35\x30\xac\xca\x4f\x48\x3a\x79\x7a"
+ "\xbc\x0a\xb1\x82\xb3\x24\xfb\x61\xd1\x08\xa9\x4b\xb2\xc8\xe3\xfb"
+ "\xb9\x6a\xda\xb7\x60\xd7\xf4\x68\x1d\x4f\x42\xa3\xde\x39\x4d\xf4"
+ "\xae\x56\xed\xe7\x63\x72\xbb\x19\x0b\x07\xa7\xc8\xee\x0a\x6d\x70"
+ "\x9e\x02\xfc\xe1\xcd\xf7\xe2\xec\xc0\x34\x04\xcd\x28\x34\x2f\x61"
+ "\x91\x72\xfe\x9c\xe9\x85\x83\xff\x8e\x4f\x12\x32\xee\xf2\x81\x83"
+ "\xc3\xfe\x3b\x1b\x4c\x6f\xad\x73\x3b\xb5\xfc\xbc\x2e\xc2\x20\x05"
+ "\xc5\x8e\xf1\x83\x7d\x16\x83\xb2\xc6\xf3\x4a\x26\xc1\xb2\xef\xfa"
+ "\x88\x6b\x42\x38\x61\x1f\xcf\xdc\xde\x35\x5b\x3b\x65\x19\x03\x5b"
+ "\xbc\x34\xf4\xde\xf9\x9c\x02\x38\x61\xb4\x6f\xc9\xd6\xe6\xc9\x07"
+ "\x7a\xd9\x1d\x26\x91\xf7\xf7\xee\x59\x8c\xb0\xfa\xc1\x86\xd9\x1c"
+ "\xae\xfe\x13\x09\x85\x13\x92\x70\xb4\x13\x0c\x93\xbc\x43\x79\x44"
+ "\xf4\xfd\x44\x52\xe2\xd7\x4d\xd3\x64\xf2\xe2\x1e\x71\xf5\x4b\xff"
+ "\x5c\xae\x82\xab\x9c\x9d\xf6\x9e\xe8\x6d\x2b\xc5\x22\x36\x3a\x0d"
+ "\xab\xc5\x21\x97\x9b\x0d\xea\xda\x1d\xbf\x9a\x42\xd5\xc4\x48\x4e"
+ "\x0a\xbc\xd0\x6b\xfa\x53\xdd\xef\x3c\x1b\x20\xee\x3f\xd5\x9d\x7c"
+ "\x25\xe4\x1d\x2b\x66\xc6\x2e\x37\xff\xff\xff\xff\xff\xff\xff\xff",
+};
+
+static const struct dh_safe_prime ffdhe4096_prime = {
+ .max_strength = 152,
+ .p_size = 512,
+ .p =
+ "\xff\xff\xff\xff\xff\xff\xff\xff\xad\xf8\x54\x58\xa2\xbb\x4a\x9a"
+ "\xaf\xdc\x56\x20\x27\x3d\x3c\xf1\xd8\xb9\xc5\x83\xce\x2d\x36\x95"
+ "\xa9\xe1\x36\x41\x14\x64\x33\xfb\xcc\x93\x9d\xce\x24\x9b\x3e\xf9"
+ "\x7d\x2f\xe3\x63\x63\x0c\x75\xd8\xf6\x81\xb2\x02\xae\xc4\x61\x7a"
+ "\xd3\xdf\x1e\xd5\xd5\xfd\x65\x61\x24\x33\xf5\x1f\x5f\x06\x6e\xd0"
+ "\x85\x63\x65\x55\x3d\xed\x1a\xf3\xb5\x57\x13\x5e\x7f\x57\xc9\x35"
+ "\x98\x4f\x0c\x70\xe0\xe6\x8b\x77\xe2\xa6\x89\xda\xf3\xef\xe8\x72"
+ "\x1d\xf1\x58\xa1\x36\xad\xe7\x35\x30\xac\xca\x4f\x48\x3a\x79\x7a"
+ "\xbc\x0a\xb1\x82\xb3\x24\xfb\x61\xd1\x08\xa9\x4b\xb2\xc8\xe3\xfb"
+ "\xb9\x6a\xda\xb7\x60\xd7\xf4\x68\x1d\x4f\x42\xa3\xde\x39\x4d\xf4"
+ "\xae\x56\xed\xe7\x63\x72\xbb\x19\x0b\x07\xa7\xc8\xee\x0a\x6d\x70"
+ "\x9e\x02\xfc\xe1\xcd\xf7\xe2\xec\xc0\x34\x04\xcd\x28\x34\x2f\x61"
+ "\x91\x72\xfe\x9c\xe9\x85\x83\xff\x8e\x4f\x12\x32\xee\xf2\x81\x83"
+ "\xc3\xfe\x3b\x1b\x4c\x6f\xad\x73\x3b\xb5\xfc\xbc\x2e\xc2\x20\x05"
+ "\xc5\x8e\xf1\x83\x7d\x16\x83\xb2\xc6\xf3\x4a\x26\xc1\xb2\xef\xfa"
+ "\x88\x6b\x42\x38\x61\x1f\xcf\xdc\xde\x35\x5b\x3b\x65\x19\x03\x5b"
+ "\xbc\x34\xf4\xde\xf9\x9c\x02\x38\x61\xb4\x6f\xc9\xd6\xe6\xc9\x07"
+ "\x7a\xd9\x1d\x26\x91\xf7\xf7\xee\x59\x8c\xb0\xfa\xc1\x86\xd9\x1c"
+ "\xae\xfe\x13\x09\x85\x13\x92\x70\xb4\x13\x0c\x93\xbc\x43\x79\x44"
+ "\xf4\xfd\x44\x52\xe2\xd7\x4d\xd3\x64\xf2\xe2\x1e\x71\xf5\x4b\xff"
+ "\x5c\xae\x82\xab\x9c\x9d\xf6\x9e\xe8\x6d\x2b\xc5\x22\x36\x3a\x0d"
+ "\xab\xc5\x21\x97\x9b\x0d\xea\xda\x1d\xbf\x9a\x42\xd5\xc4\x48\x4e"
+ "\x0a\xbc\xd0\x6b\xfa\x53\xdd\xef\x3c\x1b\x20\xee\x3f\xd5\x9d\x7c"
+ "\x25\xe4\x1d\x2b\x66\x9e\x1e\xf1\x6e\x6f\x52\xc3\x16\x4d\xf4\xfb"
+ "\x79\x30\xe9\xe4\xe5\x88\x57\xb6\xac\x7d\x5f\x42\xd6\x9f\x6d\x18"
+ "\x77\x63\xcf\x1d\x55\x03\x40\x04\x87\xf5\x5b\xa5\x7e\x31\xcc\x7a"
+ "\x71\x35\xc8\x86\xef\xb4\x31\x8a\xed\x6a\x1e\x01\x2d\x9e\x68\x32"
+ "\xa9\x07\x60\x0a\x91\x81\x30\xc4\x6d\xc7\x78\xf9\x71\xad\x00\x38"
+ "\x09\x29\x99\xa3\x33\xcb\x8b\x7a\x1a\x1d\xb9\x3d\x71\x40\x00\x3c"
+ "\x2a\x4e\xce\xa9\xf9\x8d\x0a\xcc\x0a\x82\x91\xcd\xce\xc9\x7d\xcf"
+ "\x8e\xc9\xb5\x5a\x7f\x88\xa4\x6b\x4d\xb5\xa8\x51\xf4\x41\x82\xe1"
+ "\xc6\x8a\x00\x7e\x5e\x65\x5f\x6a\xff\xff\xff\xff\xff\xff\xff\xff",
+};
+
+static const struct dh_safe_prime ffdhe6144_prime = {
+ .max_strength = 176,
+ .p_size = 768,
+ .p =
+ "\xff\xff\xff\xff\xff\xff\xff\xff\xad\xf8\x54\x58\xa2\xbb\x4a\x9a"
+ "\xaf\xdc\x56\x20\x27\x3d\x3c\xf1\xd8\xb9\xc5\x83\xce\x2d\x36\x95"
+ "\xa9\xe1\x36\x41\x14\x64\x33\xfb\xcc\x93\x9d\xce\x24\x9b\x3e\xf9"
+ "\x7d\x2f\xe3\x63\x63\x0c\x75\xd8\xf6\x81\xb2\x02\xae\xc4\x61\x7a"
+ "\xd3\xdf\x1e\xd5\xd5\xfd\x65\x61\x24\x33\xf5\x1f\x5f\x06\x6e\xd0"
+ "\x85\x63\x65\x55\x3d\xed\x1a\xf3\xb5\x57\x13\x5e\x7f\x57\xc9\x35"
+ "\x98\x4f\x0c\x70\xe0\xe6\x8b\x77\xe2\xa6\x89\xda\xf3\xef\xe8\x72"
+ "\x1d\xf1\x58\xa1\x36\xad\xe7\x35\x30\xac\xca\x4f\x48\x3a\x79\x7a"
+ "\xbc\x0a\xb1\x82\xb3\x24\xfb\x61\xd1\x08\xa9\x4b\xb2\xc8\xe3\xfb"
+ "\xb9\x6a\xda\xb7\x60\xd7\xf4\x68\x1d\x4f\x42\xa3\xde\x39\x4d\xf4"
+ "\xae\x56\xed\xe7\x63\x72\xbb\x19\x0b\x07\xa7\xc8\xee\x0a\x6d\x70"
+ "\x9e\x02\xfc\xe1\xcd\xf7\xe2\xec\xc0\x34\x04\xcd\x28\x34\x2f\x61"
+ "\x91\x72\xfe\x9c\xe9\x85\x83\xff\x8e\x4f\x12\x32\xee\xf2\x81\x83"
+ "\xc3\xfe\x3b\x1b\x4c\x6f\xad\x73\x3b\xb5\xfc\xbc\x2e\xc2\x20\x05"
+ "\xc5\x8e\xf1\x83\x7d\x16\x83\xb2\xc6\xf3\x4a\x26\xc1\xb2\xef\xfa"
+ "\x88\x6b\x42\x38\x61\x1f\xcf\xdc\xde\x35\x5b\x3b\x65\x19\x03\x5b"
+ "\xbc\x34\xf4\xde\xf9\x9c\x02\x38\x61\xb4\x6f\xc9\xd6\xe6\xc9\x07"
+ "\x7a\xd9\x1d\x26\x91\xf7\xf7\xee\x59\x8c\xb0\xfa\xc1\x86\xd9\x1c"
+ "\xae\xfe\x13\x09\x85\x13\x92\x70\xb4\x13\x0c\x93\xbc\x43\x79\x44"
+ "\xf4\xfd\x44\x52\xe2\xd7\x4d\xd3\x64\xf2\xe2\x1e\x71\xf5\x4b\xff"
+ "\x5c\xae\x82\xab\x9c\x9d\xf6\x9e\xe8\x6d\x2b\xc5\x22\x36\x3a\x0d"
+ "\xab\xc5\x21\x97\x9b\x0d\xea\xda\x1d\xbf\x9a\x42\xd5\xc4\x48\x4e"
+ "\x0a\xbc\xd0\x6b\xfa\x53\xdd\xef\x3c\x1b\x20\xee\x3f\xd5\x9d\x7c"
+ "\x25\xe4\x1d\x2b\x66\x9e\x1e\xf1\x6e\x6f\x52\xc3\x16\x4d\xf4\xfb"
+ "\x79\x30\xe9\xe4\xe5\x88\x57\xb6\xac\x7d\x5f\x42\xd6\x9f\x6d\x18"
+ "\x77\x63\xcf\x1d\x55\x03\x40\x04\x87\xf5\x5b\xa5\x7e\x31\xcc\x7a"
+ "\x71\x35\xc8\x86\xef\xb4\x31\x8a\xed\x6a\x1e\x01\x2d\x9e\x68\x32"
+ "\xa9\x07\x60\x0a\x91\x81\x30\xc4\x6d\xc7\x78\xf9\x71\xad\x00\x38"
+ "\x09\x29\x99\xa3\x33\xcb\x8b\x7a\x1a\x1d\xb9\x3d\x71\x40\x00\x3c"
+ "\x2a\x4e\xce\xa9\xf9\x8d\x0a\xcc\x0a\x82\x91\xcd\xce\xc9\x7d\xcf"
+ "\x8e\xc9\xb5\x5a\x7f\x88\xa4\x6b\x4d\xb5\xa8\x51\xf4\x41\x82\xe1"
+ "\xc6\x8a\x00\x7e\x5e\x0d\xd9\x02\x0b\xfd\x64\xb6\x45\x03\x6c\x7a"
+ "\x4e\x67\x7d\x2c\x38\x53\x2a\x3a\x23\xba\x44\x42\xca\xf5\x3e\xa6"
+ "\x3b\xb4\x54\x32\x9b\x76\x24\xc8\x91\x7b\xdd\x64\xb1\xc0\xfd\x4c"
+ "\xb3\x8e\x8c\x33\x4c\x70\x1c\x3a\xcd\xad\x06\x57\xfc\xcf\xec\x71"
+ "\x9b\x1f\x5c\x3e\x4e\x46\x04\x1f\x38\x81\x47\xfb\x4c\xfd\xb4\x77"
+ "\xa5\x24\x71\xf7\xa9\xa9\x69\x10\xb8\x55\x32\x2e\xdb\x63\x40\xd8"
+ "\xa0\x0e\xf0\x92\x35\x05\x11\xe3\x0a\xbe\xc1\xff\xf9\xe3\xa2\x6e"
+ "\x7f\xb2\x9f\x8c\x18\x30\x23\xc3\x58\x7e\x38\xda\x00\x77\xd9\xb4"
+ "\x76\x3e\x4e\x4b\x94\xb2\xbb\xc1\x94\xc6\x65\x1e\x77\xca\xf9\x92"
+ "\xee\xaa\xc0\x23\x2a\x28\x1b\xf6\xb3\xa7\x39\xc1\x22\x61\x16\x82"
+ "\x0a\xe8\xdb\x58\x47\xa6\x7c\xbe\xf9\xc9\x09\x1b\x46\x2d\x53\x8c"
+ "\xd7\x2b\x03\x74\x6a\xe7\x7f\x5e\x62\x29\x2c\x31\x15\x62\xa8\x46"
+ "\x50\x5d\xc8\x2d\xb8\x54\x33\x8a\xe4\x9f\x52\x35\xc9\x5b\x91\x17"
+ "\x8c\xcf\x2d\xd5\xca\xce\xf4\x03\xec\x9d\x18\x10\xc6\x27\x2b\x04"
+ "\x5b\x3b\x71\xf9\xdc\x6b\x80\xd6\x3f\xdd\x4a\x8e\x9a\xdb\x1e\x69"
+ "\x62\xa6\x95\x26\xd4\x31\x61\xc1\xa4\x1d\x57\x0d\x79\x38\xda\xd4"
+ "\xa4\x0e\x32\x9c\xd0\xe4\x0e\x65\xff\xff\xff\xff\xff\xff\xff\xff",
+};
+
+static const struct dh_safe_prime ffdhe8192_prime = {
+ .max_strength = 200,
+ .p_size = 1024,
+ .p =
+ "\xff\xff\xff\xff\xff\xff\xff\xff\xad\xf8\x54\x58\xa2\xbb\x4a\x9a"
+ "\xaf\xdc\x56\x20\x27\x3d\x3c\xf1\xd8\xb9\xc5\x83\xce\x2d\x36\x95"
+ "\xa9\xe1\x36\x41\x14\x64\x33\xfb\xcc\x93\x9d\xce\x24\x9b\x3e\xf9"
+ "\x7d\x2f\xe3\x63\x63\x0c\x75\xd8\xf6\x81\xb2\x02\xae\xc4\x61\x7a"
+ "\xd3\xdf\x1e\xd5\xd5\xfd\x65\x61\x24\x33\xf5\x1f\x5f\x06\x6e\xd0"
+ "\x85\x63\x65\x55\x3d\xed\x1a\xf3\xb5\x57\x13\x5e\x7f\x57\xc9\x35"
+ "\x98\x4f\x0c\x70\xe0\xe6\x8b\x77\xe2\xa6\x89\xda\xf3\xef\xe8\x72"
+ "\x1d\xf1\x58\xa1\x36\xad\xe7\x35\x30\xac\xca\x4f\x48\x3a\x79\x7a"
+ "\xbc\x0a\xb1\x82\xb3\x24\xfb\x61\xd1\x08\xa9\x4b\xb2\xc8\xe3\xfb"
+ "\xb9\x6a\xda\xb7\x60\xd7\xf4\x68\x1d\x4f\x42\xa3\xde\x39\x4d\xf4"
+ "\xae\x56\xed\xe7\x63\x72\xbb\x19\x0b\x07\xa7\xc8\xee\x0a\x6d\x70"
+ "\x9e\x02\xfc\xe1\xcd\xf7\xe2\xec\xc0\x34\x04\xcd\x28\x34\x2f\x61"
+ "\x91\x72\xfe\x9c\xe9\x85\x83\xff\x8e\x4f\x12\x32\xee\xf2\x81\x83"
+ "\xc3\xfe\x3b\x1b\x4c\x6f\xad\x73\x3b\xb5\xfc\xbc\x2e\xc2\x20\x05"
+ "\xc5\x8e\xf1\x83\x7d\x16\x83\xb2\xc6\xf3\x4a\x26\xc1\xb2\xef\xfa"
+ "\x88\x6b\x42\x38\x61\x1f\xcf\xdc\xde\x35\x5b\x3b\x65\x19\x03\x5b"
+ "\xbc\x34\xf4\xde\xf9\x9c\x02\x38\x61\xb4\x6f\xc9\xd6\xe6\xc9\x07"
+ "\x7a\xd9\x1d\x26\x91\xf7\xf7\xee\x59\x8c\xb0\xfa\xc1\x86\xd9\x1c"
+ "\xae\xfe\x13\x09\x85\x13\x92\x70\xb4\x13\x0c\x93\xbc\x43\x79\x44"
+ "\xf4\xfd\x44\x52\xe2\xd7\x4d\xd3\x64\xf2\xe2\x1e\x71\xf5\x4b\xff"
+ "\x5c\xae\x82\xab\x9c\x9d\xf6\x9e\xe8\x6d\x2b\xc5\x22\x36\x3a\x0d"
+ "\xab\xc5\x21\x97\x9b\x0d\xea\xda\x1d\xbf\x9a\x42\xd5\xc4\x48\x4e"
+ "\x0a\xbc\xd0\x6b\xfa\x53\xdd\xef\x3c\x1b\x20\xee\x3f\xd5\x9d\x7c"
+ "\x25\xe4\x1d\x2b\x66\x9e\x1e\xf1\x6e\x6f\x52\xc3\x16\x4d\xf4\xfb"
+ "\x79\x30\xe9\xe4\xe5\x88\x57\xb6\xac\x7d\x5f\x42\xd6\x9f\x6d\x18"
+ "\x77\x63\xcf\x1d\x55\x03\x40\x04\x87\xf5\x5b\xa5\x7e\x31\xcc\x7a"
+ "\x71\x35\xc8\x86\xef\xb4\x31\x8a\xed\x6a\x1e\x01\x2d\x9e\x68\x32"
+ "\xa9\x07\x60\x0a\x91\x81\x30\xc4\x6d\xc7\x78\xf9\x71\xad\x00\x38"
+ "\x09\x29\x99\xa3\x33\xcb\x8b\x7a\x1a\x1d\xb9\x3d\x71\x40\x00\x3c"
+ "\x2a\x4e\xce\xa9\xf9\x8d\x0a\xcc\x0a\x82\x91\xcd\xce\xc9\x7d\xcf"
+ "\x8e\xc9\xb5\x5a\x7f\x88\xa4\x6b\x4d\xb5\xa8\x51\xf4\x41\x82\xe1"
+ "\xc6\x8a\x00\x7e\x5e\x0d\xd9\x02\x0b\xfd\x64\xb6\x45\x03\x6c\x7a"
+ "\x4e\x67\x7d\x2c\x38\x53\x2a\x3a\x23\xba\x44\x42\xca\xf5\x3e\xa6"
+ "\x3b\xb4\x54\x32\x9b\x76\x24\xc8\x91\x7b\xdd\x64\xb1\xc0\xfd\x4c"
+ "\xb3\x8e\x8c\x33\x4c\x70\x1c\x3a\xcd\xad\x06\x57\xfc\xcf\xec\x71"
+ "\x9b\x1f\x5c\x3e\x4e\x46\x04\x1f\x38\x81\x47\xfb\x4c\xfd\xb4\x77"
+ "\xa5\x24\x71\xf7\xa9\xa9\x69\x10\xb8\x55\x32\x2e\xdb\x63\x40\xd8"
+ "\xa0\x0e\xf0\x92\x35\x05\x11\xe3\x0a\xbe\xc1\xff\xf9\xe3\xa2\x6e"
+ "\x7f\xb2\x9f\x8c\x18\x30\x23\xc3\x58\x7e\x38\xda\x00\x77\xd9\xb4"
+ "\x76\x3e\x4e\x4b\x94\xb2\xbb\xc1\x94\xc6\x65\x1e\x77\xca\xf9\x92"
+ "\xee\xaa\xc0\x23\x2a\x28\x1b\xf6\xb3\xa7\x39\xc1\x22\x61\x16\x82"
+ "\x0a\xe8\xdb\x58\x47\xa6\x7c\xbe\xf9\xc9\x09\x1b\x46\x2d\x53\x8c"
+ "\xd7\x2b\x03\x74\x6a\xe7\x7f\x5e\x62\x29\x2c\x31\x15\x62\xa8\x46"
+ "\x50\x5d\xc8\x2d\xb8\x54\x33\x8a\xe4\x9f\x52\x35\xc9\x5b\x91\x17"
+ "\x8c\xcf\x2d\xd5\xca\xce\xf4\x03\xec\x9d\x18\x10\xc6\x27\x2b\x04"
+ "\x5b\x3b\x71\xf9\xdc\x6b\x80\xd6\x3f\xdd\x4a\x8e\x9a\xdb\x1e\x69"
+ "\x62\xa6\x95\x26\xd4\x31\x61\xc1\xa4\x1d\x57\x0d\x79\x38\xda\xd4"
+ "\xa4\x0e\x32\x9c\xcf\xf4\x6a\xaa\x36\xad\x00\x4c\xf6\x00\xc8\x38"
+ "\x1e\x42\x5a\x31\xd9\x51\xae\x64\xfd\xb2\x3f\xce\xc9\x50\x9d\x43"
+ "\x68\x7f\xeb\x69\xed\xd1\xcc\x5e\x0b\x8c\xc3\xbd\xf6\x4b\x10\xef"
+ "\x86\xb6\x31\x42\xa3\xab\x88\x29\x55\x5b\x2f\x74\x7c\x93\x26\x65"
+ "\xcb\x2c\x0f\x1c\xc0\x1b\xd7\x02\x29\x38\x88\x39\xd2\xaf\x05\xe4"
+ "\x54\x50\x4a\xc7\x8b\x75\x82\x82\x28\x46\xc0\xba\x35\xc3\x5f\x5c"
+ "\x59\x16\x0c\xc0\x46\xfd\x82\x51\x54\x1f\xc6\x8c\x9c\x86\xb0\x22"
+ "\xbb\x70\x99\x87\x6a\x46\x0e\x74\x51\xa8\xa9\x31\x09\x70\x3f\xee"
+ "\x1c\x21\x7e\x6c\x38\x26\xe5\x2c\x51\xaa\x69\x1e\x0e\x42\x3c\xfc"
+ "\x99\xe9\xe3\x16\x50\xc1\x21\x7b\x62\x48\x16\xcd\xad\x9a\x95\xf9"
+ "\xd5\xb8\x01\x94\x88\xd9\xc0\xa0\xa1\xfe\x30\x75\xa5\x77\xe2\x31"
+ "\x83\xf8\x1d\x4a\x3f\x2f\xa4\x57\x1e\xfc\x8c\xe0\xba\x8a\x4f\xe8"
+ "\xb6\x85\x5d\xfe\x72\xb0\xa6\x6e\xde\xd2\xfb\xab\xfb\xe5\x8a\x30"
+ "\xfa\xfa\xbe\x1c\x5d\x71\xa8\x7e\x2f\x74\x1e\xf8\xc1\xfe\x86\xfe"
+ "\xa6\xbb\xfd\xe5\x30\x67\x7f\x0d\x97\xd1\x1d\x49\xf7\xa8\x44\x3d"
+ "\x08\x22\xe5\x06\xa9\xf4\x61\x4e\x01\x1e\x2a\x94\x83\x8f\xf8\x8c"
+ "\xd6\x8c\x8b\xb7\xc5\xc6\x42\x4c\xff\xff\xff\xff\xff\xff\xff\xff",
+};
+
+static int dh_ffdhe2048_create(struct crypto_template *tmpl,
+ struct rtattr **tb)
+{
+ return __dh_safe_prime_create(tmpl, tb, &ffdhe2048_prime);
+}
+
+static int dh_ffdhe3072_create(struct crypto_template *tmpl,
+ struct rtattr **tb)
+{
+ return __dh_safe_prime_create(tmpl, tb, &ffdhe3072_prime);
+}
+
+static int dh_ffdhe4096_create(struct crypto_template *tmpl,
+ struct rtattr **tb)
+{
+ return __dh_safe_prime_create(tmpl, tb, &ffdhe4096_prime);
+}
+
+static int dh_ffdhe6144_create(struct crypto_template *tmpl,
+ struct rtattr **tb)
+{
+ return __dh_safe_prime_create(tmpl, tb, &ffdhe6144_prime);
+}
+
+static int dh_ffdhe8192_create(struct crypto_template *tmpl,
+ struct rtattr **tb)
+{
+ return __dh_safe_prime_create(tmpl, tb, &ffdhe8192_prime);
+}
+
+static struct crypto_template crypto_ffdhe_templates[] = {
+ {
+ .name = "ffdhe2048",
+ .create = dh_ffdhe2048_create,
+ .module = THIS_MODULE,
+ },
+ {
+ .name = "ffdhe3072",
+ .create = dh_ffdhe3072_create,
+ .module = THIS_MODULE,
+ },
+ {
+ .name = "ffdhe4096",
+ .create = dh_ffdhe4096_create,
+ .module = THIS_MODULE,
+ },
+ {
+ .name = "ffdhe6144",
+ .create = dh_ffdhe6144_create,
+ .module = THIS_MODULE,
+ },
+ {
+ .name = "ffdhe8192",
+ .create = dh_ffdhe8192_create,
+ .module = THIS_MODULE,
+ },
+};
+
+#else /* ! CONFIG_CRYPTO_DH_RFC7919_GROUPS */
+
+static struct crypto_template crypto_ffdhe_templates[] = {};
+
+#endif /* CONFIG_CRYPTO_DH_RFC7919_GROUPS */
+
+
static int dh_init(void)
{
- return crypto_register_kpp(&dh);
+ int err;
+
+ err = crypto_register_kpp(&dh);
+ if (err)
+ return err;
+
+ err = crypto_register_templates(crypto_ffdhe_templates,
+ ARRAY_SIZE(crypto_ffdhe_templates));
+ if (err) {
+ crypto_unregister_kpp(&dh);
+ return err;
+ }
+
+ return 0;
}
static void dh_exit(void)
{
+ crypto_unregister_templates(crypto_ffdhe_templates,
+ ARRAY_SIZE(crypto_ffdhe_templates));
crypto_unregister_kpp(&dh);
}
diff --git a/crypto/dh_helper.c b/crypto/dh_helper.c
index 9fd5a42eea15..2d499879328b 100644
--- a/crypto/dh_helper.c
+++ b/crypto/dh_helper.c
@@ -10,7 +10,7 @@
#include <crypto/dh.h>
#include <crypto/kpp.h>
-#define DH_KPP_SECRET_MIN_SIZE (sizeof(struct kpp_secret) + 4 * sizeof(int))
+#define DH_KPP_SECRET_MIN_SIZE (sizeof(struct kpp_secret) + 3 * sizeof(int))
static inline u8 *dh_pack_data(u8 *dst, u8 *end, const void *src, size_t size)
{
@@ -28,7 +28,7 @@ static inline const u8 *dh_unpack_data(void *dst, const void *src, size_t size)
static inline unsigned int dh_data_size(const struct dh *p)
{
- return p->key_size + p->p_size + p->q_size + p->g_size;
+ return p->key_size + p->p_size + p->g_size;
}
unsigned int crypto_dh_key_len(const struct dh *p)
@@ -53,11 +53,9 @@ int crypto_dh_encode_key(char *buf, unsigned int len, const struct dh *params)
ptr = dh_pack_data(ptr, end, &params->key_size,
sizeof(params->key_size));
ptr = dh_pack_data(ptr, end, &params->p_size, sizeof(params->p_size));
- ptr = dh_pack_data(ptr, end, &params->q_size, sizeof(params->q_size));
ptr = dh_pack_data(ptr, end, &params->g_size, sizeof(params->g_size));
ptr = dh_pack_data(ptr, end, params->key, params->key_size);
ptr = dh_pack_data(ptr, end, params->p, params->p_size);
- ptr = dh_pack_data(ptr, end, params->q, params->q_size);
ptr = dh_pack_data(ptr, end, params->g, params->g_size);
if (ptr != end)
return -EINVAL;
@@ -65,7 +63,7 @@ int crypto_dh_encode_key(char *buf, unsigned int len, const struct dh *params)
}
EXPORT_SYMBOL_GPL(crypto_dh_encode_key);
-int crypto_dh_decode_key(const char *buf, unsigned int len, struct dh *params)
+int __crypto_dh_decode_key(const char *buf, unsigned int len, struct dh *params)
{
const u8 *ptr = buf;
struct kpp_secret secret;
@@ -79,28 +77,36 @@ int crypto_dh_decode_key(const char *buf, unsigned int len, struct dh *params)
ptr = dh_unpack_data(&params->key_size, ptr, sizeof(params->key_size));
ptr = dh_unpack_data(&params->p_size, ptr, sizeof(params->p_size));
- ptr = dh_unpack_data(&params->q_size, ptr, sizeof(params->q_size));
ptr = dh_unpack_data(&params->g_size, ptr, sizeof(params->g_size));
if (secret.len != crypto_dh_key_len(params))
return -EINVAL;
+ /* Don't allocate memory. Set pointers to data within
+ * the given buffer
+ */
+ params->key = (void *)ptr;
+ params->p = (void *)(ptr + params->key_size);
+ params->g = (void *)(ptr + params->key_size + params->p_size);
+
+ return 0;
+}
+
+int crypto_dh_decode_key(const char *buf, unsigned int len, struct dh *params)
+{
+ int err;
+
+ err = __crypto_dh_decode_key(buf, len, params);
+ if (err)
+ return err;
+
/*
* Don't permit the buffer for 'key' or 'g' to be larger than 'p', since
* some drivers assume otherwise.
*/
if (params->key_size > params->p_size ||
- params->g_size > params->p_size || params->q_size > params->p_size)
+ params->g_size > params->p_size)
return -EINVAL;
- /* Don't allocate memory. Set pointers to data within
- * the given buffer
- */
- params->key = (void *)ptr;
- params->p = (void *)(ptr + params->key_size);
- params->q = (void *)(ptr + params->key_size + params->p_size);
- params->g = (void *)(ptr + params->key_size + params->p_size +
- params->q_size);
-
/*
* Don't permit 'p' to be 0. It's not a prime number, and it's subject
* to corner cases such as 'mod 0' being undefined or
@@ -109,10 +115,6 @@ int crypto_dh_decode_key(const char *buf, unsigned int len, struct dh *params)
if (memchr_inv(params->p, 0, params->p_size) == NULL)
return -EINVAL;
- /* It is permissible to not provide Q. */
- if (params->q_size == 0)
- params->q = NULL;
-
return 0;
}
EXPORT_SYMBOL_GPL(crypto_dh_decode_key);
diff --git a/crypto/hmac.c b/crypto/hmac.c
index 25856aa7ccbf..3610ff0b6739 100644
--- a/crypto/hmac.c
+++ b/crypto/hmac.c
@@ -15,6 +15,7 @@
#include <crypto/internal/hash.h>
#include <crypto/scatterwalk.h>
#include <linux/err.h>
+#include <linux/fips.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
@@ -51,6 +52,9 @@ static int hmac_setkey(struct crypto_shash *parent,
SHASH_DESC_ON_STACK(shash, hash);
unsigned int i;
+ if (fips_enabled && (keylen < 112 / 8))
+ return -EINVAL;
+
shash->tfm = hash;
if (keylen > bs) {
diff --git a/crypto/kpp.c b/crypto/kpp.c
index 313b2c699963..7aa6ba4b60a4 100644
--- a/crypto/kpp.c
+++ b/crypto/kpp.c
@@ -68,9 +68,17 @@ static int crypto_kpp_init_tfm(struct crypto_tfm *tfm)
return 0;
}
+static void crypto_kpp_free_instance(struct crypto_instance *inst)
+{
+ struct kpp_instance *kpp = kpp_instance(inst);
+
+ kpp->free(kpp);
+}
+
static const struct crypto_type crypto_kpp_type = {
.extsize = crypto_alg_extsize,
.init_tfm = crypto_kpp_init_tfm,
+ .free = crypto_kpp_free_instance,
#ifdef CONFIG_PROC_FS
.show = crypto_kpp_show,
#endif
@@ -87,6 +95,15 @@ struct crypto_kpp *crypto_alloc_kpp(const char *alg_name, u32 type, u32 mask)
}
EXPORT_SYMBOL_GPL(crypto_alloc_kpp);
+int crypto_grab_kpp(struct crypto_kpp_spawn *spawn,
+ struct crypto_instance *inst,
+ const char *name, u32 type, u32 mask)
+{
+ spawn->base.frontend = &crypto_kpp_type;
+ return crypto_grab_spawn(&spawn->base, inst, name, type, mask);
+}
+EXPORT_SYMBOL_GPL(crypto_grab_kpp);
+
static void kpp_prepare_alg(struct kpp_alg *alg)
{
struct crypto_alg *base = &alg->base;
@@ -111,5 +128,17 @@ void crypto_unregister_kpp(struct kpp_alg *alg)
}
EXPORT_SYMBOL_GPL(crypto_unregister_kpp);
+int kpp_register_instance(struct crypto_template *tmpl,
+ struct kpp_instance *inst)
+{
+ if (WARN_ON(!inst->free))
+ return -EINVAL;
+
+ kpp_prepare_alg(&inst->alg);
+
+ return crypto_register_instance(tmpl, kpp_crypto_instance(inst));
+}
+EXPORT_SYMBOL_GPL(kpp_register_instance);
+
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Key-agreement Protocol Primitives");
diff --git a/crypto/lrw.c b/crypto/lrw.c
index bcf09fbc750a..8d59a66b6525 100644
--- a/crypto/lrw.c
+++ b/crypto/lrw.c
@@ -428,3 +428,4 @@ module_exit(lrw_module_exit);
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("LRW block cipher mode");
MODULE_ALIAS_CRYPTO("lrw");
+MODULE_SOFTDEP("pre: ecb");
diff --git a/crypto/memneq.c b/crypto/memneq.c
index afed1bd16aee..fb11608b1ec1 100644
--- a/crypto/memneq.c
+++ b/crypto/memneq.c
@@ -60,6 +60,7 @@
*/
#include <crypto/algapi.h>
+#include <asm/unaligned.h>
#ifndef __HAVE_ARCH_CRYPTO_MEMNEQ
@@ -71,7 +72,8 @@ __crypto_memneq_generic(const void *a, const void *b, size_t size)
#if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS)
while (size >= sizeof(unsigned long)) {
- neq |= *(unsigned long *)a ^ *(unsigned long *)b;
+ neq |= get_unaligned((unsigned long *)a) ^
+ get_unaligned((unsigned long *)b);
OPTIMIZER_HIDE_VAR(neq);
a += sizeof(unsigned long);
b += sizeof(unsigned long);
@@ -95,18 +97,24 @@ static inline unsigned long __crypto_memneq_16(const void *a, const void *b)
#ifdef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS
if (sizeof(unsigned long) == 8) {
- neq |= *(unsigned long *)(a) ^ *(unsigned long *)(b);
+ neq |= get_unaligned((unsigned long *)a) ^
+ get_unaligned((unsigned long *)b);
OPTIMIZER_HIDE_VAR(neq);
- neq |= *(unsigned long *)(a+8) ^ *(unsigned long *)(b+8);
+ neq |= get_unaligned((unsigned long *)(a + 8)) ^
+ get_unaligned((unsigned long *)(b + 8));
OPTIMIZER_HIDE_VAR(neq);
} else if (sizeof(unsigned int) == 4) {
- neq |= *(unsigned int *)(a) ^ *(unsigned int *)(b);
+ neq |= get_unaligned((unsigned int *)a) ^
+ get_unaligned((unsigned int *)b);
OPTIMIZER_HIDE_VAR(neq);
- neq |= *(unsigned int *)(a+4) ^ *(unsigned int *)(b+4);
+ neq |= get_unaligned((unsigned int *)(a + 4)) ^
+ get_unaligned((unsigned int *)(b + 4));
OPTIMIZER_HIDE_VAR(neq);
- neq |= *(unsigned int *)(a+8) ^ *(unsigned int *)(b+8);
+ neq |= get_unaligned((unsigned int *)(a + 8)) ^
+ get_unaligned((unsigned int *)(b + 8));
OPTIMIZER_HIDE_VAR(neq);
- neq |= *(unsigned int *)(a+12) ^ *(unsigned int *)(b+12);
+ neq |= get_unaligned((unsigned int *)(a + 12)) ^
+ get_unaligned((unsigned int *)(b + 12));
OPTIMIZER_HIDE_VAR(neq);
} else
#endif /* CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS */
diff --git a/crypto/rsa-pkcs1pad.c b/crypto/rsa-pkcs1pad.c
index 8ac3e73e8ea6..3285e3af43e1 100644
--- a/crypto/rsa-pkcs1pad.c
+++ b/crypto/rsa-pkcs1pad.c
@@ -385,15 +385,15 @@ static int pkcs1pad_sign(struct akcipher_request *req)
struct pkcs1pad_inst_ctx *ictx = akcipher_instance_ctx(inst);
const struct rsa_asn1_template *digest_info = ictx->digest_info;
int err;
- unsigned int ps_end, digest_size = 0;
+ unsigned int ps_end, digest_info_size = 0;
if (!ctx->key_size)
return -EINVAL;
if (digest_info)
- digest_size = digest_info->size;
+ digest_info_size = digest_info->size;
- if (req->src_len + digest_size > ctx->key_size - 11)
+ if (req->src_len + digest_info_size > ctx->key_size - 11)
return -EOVERFLOW;
if (req->dst_len < ctx->key_size) {
@@ -406,7 +406,7 @@ static int pkcs1pad_sign(struct akcipher_request *req)
if (!req_ctx->in_buf)
return -ENOMEM;
- ps_end = ctx->key_size - digest_size - req->src_len - 2;
+ ps_end = ctx->key_size - digest_info_size - req->src_len - 2;
req_ctx->in_buf[0] = 0x01;
memset(req_ctx->in_buf + 1, 0xff, ps_end - 1);
req_ctx->in_buf[ps_end] = 0x00;
@@ -441,6 +441,8 @@ static int pkcs1pad_verify_complete(struct akcipher_request *req, int err)
struct akcipher_instance *inst = akcipher_alg_instance(tfm);
struct pkcs1pad_inst_ctx *ictx = akcipher_instance_ctx(inst);
const struct rsa_asn1_template *digest_info = ictx->digest_info;
+ const unsigned int sig_size = req->src_len;
+ const unsigned int digest_size = req->dst_len;
unsigned int dst_len;
unsigned int pos;
u8 *out_buf;
@@ -476,6 +478,8 @@ static int pkcs1pad_verify_complete(struct akcipher_request *req, int err)
pos++;
if (digest_info) {
+ if (digest_info->size > dst_len - pos)
+ goto done;
if (crypto_memneq(out_buf + pos, digest_info->data,
digest_info->size))
goto done;
@@ -485,20 +489,19 @@ static int pkcs1pad_verify_complete(struct akcipher_request *req, int err)
err = 0;
- if (req->dst_len != dst_len - pos) {
+ if (digest_size != dst_len - pos) {
err = -EKEYREJECTED;
req->dst_len = dst_len - pos;
goto done;
}
/* Extract appended digest. */
sg_pcopy_to_buffer(req->src,
- sg_nents_for_len(req->src,
- req->src_len + req->dst_len),
+ sg_nents_for_len(req->src, sig_size + digest_size),
req_ctx->out_buf + ctx->key_size,
- req->dst_len, ctx->key_size);
+ digest_size, sig_size);
/* Do the actual verification step. */
if (memcmp(req_ctx->out_buf + ctx->key_size, out_buf + pos,
- req->dst_len) != 0)
+ digest_size) != 0)
err = -EKEYREJECTED;
done:
kfree_sensitive(req_ctx->out_buf);
@@ -534,14 +537,15 @@ static int pkcs1pad_verify(struct akcipher_request *req)
struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req);
struct pkcs1pad_ctx *ctx = akcipher_tfm_ctx(tfm);
struct pkcs1pad_request *req_ctx = akcipher_request_ctx(req);
+ const unsigned int sig_size = req->src_len;
+ const unsigned int digest_size = req->dst_len;
int err;
- if (WARN_ON(req->dst) ||
- WARN_ON(!req->dst_len) ||
- !ctx->key_size || req->src_len < ctx->key_size)
+ if (WARN_ON(req->dst) || WARN_ON(!digest_size) ||
+ !ctx->key_size || sig_size != ctx->key_size)
return -EINVAL;
- req_ctx->out_buf = kmalloc(ctx->key_size + req->dst_len, GFP_KERNEL);
+ req_ctx->out_buf = kmalloc(ctx->key_size + digest_size, GFP_KERNEL);
if (!req_ctx->out_buf)
return -ENOMEM;
@@ -554,8 +558,7 @@ static int pkcs1pad_verify(struct akcipher_request *req)
/* Reuse input buffer, output to a new buffer */
akcipher_request_set_crypt(&req_ctx->child_req, req->src,
- req_ctx->out_sg, req->src_len,
- ctx->key_size);
+ req_ctx->out_sg, sig_size, ctx->key_size);
err = crypto_akcipher_encrypt(&req_ctx->child_req);
if (err != -EINPROGRESS && err != -EBUSY)
@@ -621,6 +624,11 @@ static int pkcs1pad_create(struct crypto_template *tmpl, struct rtattr **tb)
rsa_alg = crypto_spawn_akcipher_alg(&ctx->spawn);
+ if (strcmp(rsa_alg->base.cra_name, "rsa") != 0) {
+ err = -EINVAL;
+ goto err_free_inst;
+ }
+
err = -ENAMETOOLONG;
hash_name = crypto_attr_alg_name(tb[2]);
if (IS_ERR(hash_name)) {
diff --git a/crypto/sm2.c b/crypto/sm2.c
index db8a4a265669..f3e1592965c0 100644
--- a/crypto/sm2.c
+++ b/crypto/sm2.c
@@ -1,4 +1,4 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
+// SPDX-License-Identifier: GPL-2.0-or-later
/*
* SM2 asymmetric public-key algorithm
* as specified by OSCCA GM/T 0003.1-2012 -- 0003.5-2012 SM2 and
@@ -13,7 +13,7 @@
#include <crypto/internal/akcipher.h>
#include <crypto/akcipher.h>
#include <crypto/hash.h>
-#include <crypto/sm3_base.h>
+#include <crypto/sm3.h>
#include <crypto/rng.h>
#include <crypto/sm2.h>
#include "sm2signature.asn1.h"
@@ -213,7 +213,7 @@ int sm2_get_signature_s(void *context, size_t hdrlen, unsigned char tag,
return 0;
}
-static int sm2_z_digest_update(struct shash_desc *desc,
+static int sm2_z_digest_update(struct sm3_state *sctx,
MPI m, unsigned int pbytes)
{
static const unsigned char zero[32];
@@ -226,20 +226,20 @@ static int sm2_z_digest_update(struct shash_desc *desc,
if (inlen < pbytes) {
/* padding with zero */
- crypto_sm3_update(desc, zero, pbytes - inlen);
- crypto_sm3_update(desc, in, inlen);
+ sm3_update(sctx, zero, pbytes - inlen);
+ sm3_update(sctx, in, inlen);
} else if (inlen > pbytes) {
/* skip the starting zero */
- crypto_sm3_update(desc, in + inlen - pbytes, pbytes);
+ sm3_update(sctx, in + inlen - pbytes, pbytes);
} else {
- crypto_sm3_update(desc, in, inlen);
+ sm3_update(sctx, in, inlen);
}
kfree(in);
return 0;
}
-static int sm2_z_digest_update_point(struct shash_desc *desc,
+static int sm2_z_digest_update_point(struct sm3_state *sctx,
MPI_POINT point, struct mpi_ec_ctx *ec, unsigned int pbytes)
{
MPI x, y;
@@ -249,8 +249,8 @@ static int sm2_z_digest_update_point(struct shash_desc *desc,
y = mpi_new(0);
if (!mpi_ec_get_affine(x, y, point, ec) &&
- !sm2_z_digest_update(desc, x, pbytes) &&
- !sm2_z_digest_update(desc, y, pbytes))
+ !sm2_z_digest_update(sctx, x, pbytes) &&
+ !sm2_z_digest_update(sctx, y, pbytes))
ret = 0;
mpi_free(x);
@@ -265,7 +265,7 @@ int sm2_compute_z_digest(struct crypto_akcipher *tfm,
struct mpi_ec_ctx *ec = akcipher_tfm_ctx(tfm);
uint16_t bits_len;
unsigned char entl[2];
- SHASH_DESC_ON_STACK(desc, NULL);
+ struct sm3_state sctx;
unsigned int pbytes;
if (id_len > (USHRT_MAX / 8) || !ec->Q)
@@ -278,17 +278,17 @@ int sm2_compute_z_digest(struct crypto_akcipher *tfm,
pbytes = MPI_NBYTES(ec->p);
/* ZA = H256(ENTLA | IDA | a | b | xG | yG | xA | yA) */
- sm3_base_init(desc);
- crypto_sm3_update(desc, entl, 2);
- crypto_sm3_update(desc, id, id_len);
-
- if (sm2_z_digest_update(desc, ec->a, pbytes) ||
- sm2_z_digest_update(desc, ec->b, pbytes) ||
- sm2_z_digest_update_point(desc, ec->G, ec, pbytes) ||
- sm2_z_digest_update_point(desc, ec->Q, ec, pbytes))
+ sm3_init(&sctx);
+ sm3_update(&sctx, entl, 2);
+ sm3_update(&sctx, id, id_len);
+
+ if (sm2_z_digest_update(&sctx, ec->a, pbytes) ||
+ sm2_z_digest_update(&sctx, ec->b, pbytes) ||
+ sm2_z_digest_update_point(&sctx, ec->G, ec, pbytes) ||
+ sm2_z_digest_update_point(&sctx, ec->Q, ec, pbytes))
return -EINVAL;
- crypto_sm3_final(desc, dgst);
+ sm3_final(&sctx, dgst);
return 0;
}
EXPORT_SYMBOL(sm2_compute_z_digest);
diff --git a/crypto/sm3_generic.c b/crypto/sm3_generic.c
index 193c4584bd00..a215c1c37e73 100644
--- a/crypto/sm3_generic.c
+++ b/crypto/sm3_generic.c
@@ -5,6 +5,7 @@
*
* Copyright (C) 2017 ARM Limited or its affiliates.
* Written by Gilad Ben-Yossef <gilad@benyossef.com>
+ * Copyright (C) 2021 Tianjia Zhang <tianjia.zhang@linux.alibaba.com>
*/
#include <crypto/internal/hash.h>
@@ -26,143 +27,29 @@ const u8 sm3_zero_message_hash[SM3_DIGEST_SIZE] = {
};
EXPORT_SYMBOL_GPL(sm3_zero_message_hash);
-static inline u32 p0(u32 x)
-{
- return x ^ rol32(x, 9) ^ rol32(x, 17);
-}
-
-static inline u32 p1(u32 x)
-{
- return x ^ rol32(x, 15) ^ rol32(x, 23);
-}
-
-static inline u32 ff(unsigned int n, u32 a, u32 b, u32 c)
-{
- return (n < 16) ? (a ^ b ^ c) : ((a & b) | (a & c) | (b & c));
-}
-
-static inline u32 gg(unsigned int n, u32 e, u32 f, u32 g)
-{
- return (n < 16) ? (e ^ f ^ g) : ((e & f) | ((~e) & g));
-}
-
-static inline u32 t(unsigned int n)
-{
- return (n < 16) ? SM3_T1 : SM3_T2;
-}
-
-static void sm3_expand(u32 *t, u32 *w, u32 *wt)
-{
- int i;
- unsigned int tmp;
-
- /* load the input */
- for (i = 0; i <= 15; i++)
- w[i] = get_unaligned_be32((__u32 *)t + i);
-
- for (i = 16; i <= 67; i++) {
- tmp = w[i - 16] ^ w[i - 9] ^ rol32(w[i - 3], 15);
- w[i] = p1(tmp) ^ (rol32(w[i - 13], 7)) ^ w[i - 6];
- }
-
- for (i = 0; i <= 63; i++)
- wt[i] = w[i] ^ w[i + 4];
-}
-
-static void sm3_compress(u32 *w, u32 *wt, u32 *m)
-{
- u32 ss1;
- u32 ss2;
- u32 tt1;
- u32 tt2;
- u32 a, b, c, d, e, f, g, h;
- int i;
-
- a = m[0];
- b = m[1];
- c = m[2];
- d = m[3];
- e = m[4];
- f = m[5];
- g = m[6];
- h = m[7];
-
- for (i = 0; i <= 63; i++) {
-
- ss1 = rol32((rol32(a, 12) + e + rol32(t(i), i & 31)), 7);
-
- ss2 = ss1 ^ rol32(a, 12);
-
- tt1 = ff(i, a, b, c) + d + ss2 + *wt;
- wt++;
-
- tt2 = gg(i, e, f, g) + h + ss1 + *w;
- w++;
-
- d = c;
- c = rol32(b, 9);
- b = a;
- a = tt1;
- h = g;
- g = rol32(f, 19);
- f = e;
- e = p0(tt2);
- }
-
- m[0] = a ^ m[0];
- m[1] = b ^ m[1];
- m[2] = c ^ m[2];
- m[3] = d ^ m[3];
- m[4] = e ^ m[4];
- m[5] = f ^ m[5];
- m[6] = g ^ m[6];
- m[7] = h ^ m[7];
-
- a = b = c = d = e = f = g = h = ss1 = ss2 = tt1 = tt2 = 0;
-}
-
-static void sm3_transform(struct sm3_state *sst, u8 const *src)
-{
- unsigned int w[68];
- unsigned int wt[64];
-
- sm3_expand((u32 *)src, w, wt);
- sm3_compress(w, wt, sst->state);
-
- memzero_explicit(w, sizeof(w));
- memzero_explicit(wt, sizeof(wt));
-}
-
-static void sm3_generic_block_fn(struct sm3_state *sst, u8 const *src,
- int blocks)
-{
- while (blocks--) {
- sm3_transform(sst, src);
- src += SM3_BLOCK_SIZE;
- }
-}
-
-int crypto_sm3_update(struct shash_desc *desc, const u8 *data,
+static int crypto_sm3_update(struct shash_desc *desc, const u8 *data,
unsigned int len)
{
- return sm3_base_do_update(desc, data, len, sm3_generic_block_fn);
+ sm3_update(shash_desc_ctx(desc), data, len);
+ return 0;
}
-EXPORT_SYMBOL(crypto_sm3_update);
-int crypto_sm3_final(struct shash_desc *desc, u8 *out)
+static int crypto_sm3_final(struct shash_desc *desc, u8 *out)
{
- sm3_base_do_finalize(desc, sm3_generic_block_fn);
- return sm3_base_finish(desc, out);
+ sm3_final(shash_desc_ctx(desc), out);
+ return 0;
}
-EXPORT_SYMBOL(crypto_sm3_final);
-int crypto_sm3_finup(struct shash_desc *desc, const u8 *data,
+static int crypto_sm3_finup(struct shash_desc *desc, const u8 *data,
unsigned int len, u8 *hash)
{
- sm3_base_do_update(desc, data, len, sm3_generic_block_fn);
- return crypto_sm3_final(desc, hash);
+ struct sm3_state *sctx = shash_desc_ctx(desc);
+
+ if (len)
+ sm3_update(sctx, data, len);
+ sm3_final(sctx, hash);
+ return 0;
}
-EXPORT_SYMBOL(crypto_sm3_finup);
static struct shash_alg sm3_alg = {
.digestsize = SM3_DIGEST_SIZE,
@@ -174,6 +61,7 @@ static struct shash_alg sm3_alg = {
.base = {
.cra_name = "sm3",
.cra_driver_name = "sm3-generic",
+ .cra_priority = 100,
.cra_blocksize = SM3_BLOCK_SIZE,
.cra_module = THIS_MODULE,
}
diff --git a/crypto/tcrypt.c b/crypto/tcrypt.c
index 00149657a4bc..2bacf8384f59 100644
--- a/crypto/tcrypt.c
+++ b/crypto/tcrypt.c
@@ -724,200 +724,6 @@ static inline int do_one_ahash_op(struct ahash_request *req, int ret)
return crypto_wait_req(ret, wait);
}
-struct test_mb_ahash_data {
- struct scatterlist sg[XBUFSIZE];
- char result[64];
- struct ahash_request *req;
- struct crypto_wait wait;
- char *xbuf[XBUFSIZE];
-};
-
-static inline int do_mult_ahash_op(struct test_mb_ahash_data *data, u32 num_mb,
- int *rc)
-{
- int i, err = 0;
-
- /* Fire up a bunch of concurrent requests */
- for (i = 0; i < num_mb; i++)
- rc[i] = crypto_ahash_digest(data[i].req);
-
- /* Wait for all requests to finish */
- for (i = 0; i < num_mb; i++) {
- rc[i] = crypto_wait_req(rc[i], &data[i].wait);
-
- if (rc[i]) {
- pr_info("concurrent request %d error %d\n", i, rc[i]);
- err = rc[i];
- }
- }
-
- return err;
-}
-
-static int test_mb_ahash_jiffies(struct test_mb_ahash_data *data, int blen,
- int secs, u32 num_mb)
-{
- unsigned long start, end;
- int bcount;
- int ret = 0;
- int *rc;
-
- rc = kcalloc(num_mb, sizeof(*rc), GFP_KERNEL);
- if (!rc)
- return -ENOMEM;
-
- for (start = jiffies, end = start + secs * HZ, bcount = 0;
- time_before(jiffies, end); bcount++) {
- ret = do_mult_ahash_op(data, num_mb, rc);
- if (ret)
- goto out;
- }
-
- pr_cont("%d operations in %d seconds (%llu bytes)\n",
- bcount * num_mb, secs, (u64)bcount * blen * num_mb);
-
-out:
- kfree(rc);
- return ret;
-}
-
-static int test_mb_ahash_cycles(struct test_mb_ahash_data *data, int blen,
- u32 num_mb)
-{
- unsigned long cycles = 0;
- int ret = 0;
- int i;
- int *rc;
-
- rc = kcalloc(num_mb, sizeof(*rc), GFP_KERNEL);
- if (!rc)
- return -ENOMEM;
-
- /* Warm-up run. */
- for (i = 0; i < 4; i++) {
- ret = do_mult_ahash_op(data, num_mb, rc);
- if (ret)
- goto out;
- }
-
- /* The real thing. */
- for (i = 0; i < 8; i++) {
- cycles_t start, end;
-
- start = get_cycles();
- ret = do_mult_ahash_op(data, num_mb, rc);
- end = get_cycles();
-
- if (ret)
- goto out;
-
- cycles += end - start;
- }
-
- pr_cont("1 operation in %lu cycles (%d bytes)\n",
- (cycles + 4) / (8 * num_mb), blen);
-
-out:
- kfree(rc);
- return ret;
-}
-
-static void test_mb_ahash_speed(const char *algo, unsigned int secs,
- struct hash_speed *speed, u32 num_mb)
-{
- struct test_mb_ahash_data *data;
- struct crypto_ahash *tfm;
- unsigned int i, j, k;
- int ret;
-
- data = kcalloc(num_mb, sizeof(*data), GFP_KERNEL);
- if (!data)
- return;
-
- tfm = crypto_alloc_ahash(algo, 0, 0);
- if (IS_ERR(tfm)) {
- pr_err("failed to load transform for %s: %ld\n",
- algo, PTR_ERR(tfm));
- goto free_data;
- }
-
- for (i = 0; i < num_mb; ++i) {
- if (testmgr_alloc_buf(data[i].xbuf))
- goto out;
-
- crypto_init_wait(&data[i].wait);
-
- data[i].req = ahash_request_alloc(tfm, GFP_KERNEL);
- if (!data[i].req) {
- pr_err("alg: hash: Failed to allocate request for %s\n",
- algo);
- goto out;
- }
-
- ahash_request_set_callback(data[i].req, 0, crypto_req_done,
- &data[i].wait);
-
- sg_init_table(data[i].sg, XBUFSIZE);
- for (j = 0; j < XBUFSIZE; j++) {
- sg_set_buf(data[i].sg + j, data[i].xbuf[j], PAGE_SIZE);
- memset(data[i].xbuf[j], 0xff, PAGE_SIZE);
- }
- }
-
- pr_info("\ntesting speed of multibuffer %s (%s)\n", algo,
- get_driver_name(crypto_ahash, tfm));
-
- for (i = 0; speed[i].blen != 0; i++) {
- /* For some reason this only tests digests. */
- if (speed[i].blen != speed[i].plen)
- continue;
-
- if (speed[i].blen > XBUFSIZE * PAGE_SIZE) {
- pr_err("template (%u) too big for tvmem (%lu)\n",
- speed[i].blen, XBUFSIZE * PAGE_SIZE);
- goto out;
- }
-
- if (klen)
- crypto_ahash_setkey(tfm, tvmem[0], klen);
-
- for (k = 0; k < num_mb; k++)
- ahash_request_set_crypt(data[k].req, data[k].sg,
- data[k].result, speed[i].blen);
-
- pr_info("test%3u "
- "(%5u byte blocks,%5u bytes per update,%4u updates): ",
- i, speed[i].blen, speed[i].plen,
- speed[i].blen / speed[i].plen);
-
- if (secs) {
- ret = test_mb_ahash_jiffies(data, speed[i].blen, secs,
- num_mb);
- cond_resched();
- } else {
- ret = test_mb_ahash_cycles(data, speed[i].blen, num_mb);
- }
-
-
- if (ret) {
- pr_err("At least one hashing failed ret=%d\n", ret);
- break;
- }
- }
-
-out:
- for (k = 0; k < num_mb; ++k)
- ahash_request_free(data[k].req);
-
- for (k = 0; k < num_mb; ++k)
- testmgr_free_buf(data[k].xbuf);
-
- crypto_free_ahash(tfm);
-
-free_data:
- kfree(data);
-}
-
static int test_ahash_jiffies_digest(struct ahash_request *req, int blen,
char *out, int secs)
{
@@ -1667,8 +1473,8 @@ static inline int tcrypt_test(const char *alg)
pr_debug("testing %s\n", alg);
ret = alg_test(alg, alg, 0, 0);
- /* non-fips algs return -EINVAL in fips mode */
- if (fips_enabled && ret == -EINVAL)
+ /* non-fips algs return -EINVAL or -ECANCELED in fips mode */
+ if (fips_enabled && (ret == -EINVAL || ret == -ECANCELED))
ret = 0;
return ret;
}
@@ -2571,33 +2377,7 @@ static int do_test(const char *alg, u32 type, u32 mask, int m, u32 num_mb)
if (mode > 400 && mode < 500) break;
fallthrough;
case 422:
- test_mb_ahash_speed("sha1", sec, generic_hash_speed_template,
- num_mb);
- if (mode > 400 && mode < 500) break;
- fallthrough;
- case 423:
- test_mb_ahash_speed("sha256", sec, generic_hash_speed_template,
- num_mb);
- if (mode > 400 && mode < 500) break;
- fallthrough;
- case 424:
- test_mb_ahash_speed("sha512", sec, generic_hash_speed_template,
- num_mb);
- if (mode > 400 && mode < 500) break;
- fallthrough;
- case 425:
- test_mb_ahash_speed("sm3", sec, generic_hash_speed_template,
- num_mb);
- if (mode > 400 && mode < 500) break;
- fallthrough;
- case 426:
- test_mb_ahash_speed("streebog256", sec,
- generic_hash_speed_template, num_mb);
- if (mode > 400 && mode < 500) break;
- fallthrough;
- case 427:
- test_mb_ahash_speed("streebog512", sec,
- generic_hash_speed_template, num_mb);
+ test_ahash_speed("sm3", sec, generic_hash_speed_template);
if (mode > 400 && mode < 500) break;
fallthrough;
case 499:
diff --git a/crypto/testmgr.c b/crypto/testmgr.c
index 5831d4bbc64f..2d632a285869 100644
--- a/crypto/testmgr.c
+++ b/crypto/testmgr.c
@@ -55,9 +55,6 @@ MODULE_PARM_DESC(noextratests, "disable expensive crypto self-tests");
static unsigned int fuzz_iterations = 100;
module_param(fuzz_iterations, uint, 0644);
MODULE_PARM_DESC(fuzz_iterations, "number of fuzz test iterations");
-
-DEFINE_PER_CPU(bool, crypto_simd_disabled_for_test);
-EXPORT_PER_CPU_SYMBOL_GPL(crypto_simd_disabled_for_test);
#endif
#ifdef CONFIG_CRYPTO_MANAGER_DISABLE_TESTS
@@ -1854,6 +1851,9 @@ static int __alg_test_hash(const struct hash_testvec *vecs,
}
for (i = 0; i < num_vecs; i++) {
+ if (fips_enabled && vecs[i].fips_skip)
+ continue;
+
err = test_hash_vec(&vecs[i], i, req, desc, tsgl, hashstate);
if (err)
goto out;
@@ -4650,7 +4650,6 @@ static const struct alg_test_desc alg_test_descs[] = {
}, {
.alg = "dh",
.test = alg_test_kpp,
- .fips_allowed = 1,
.suite = {
.kpp = __VECS(dh_tv_template)
}
@@ -4973,6 +4972,43 @@ static const struct alg_test_desc alg_test_descs[] = {
.cipher = __VECS(essiv_aes_cbc_tv_template)
}
}, {
+#if IS_ENABLED(CONFIG_CRYPTO_DH_RFC7919_GROUPS)
+ .alg = "ffdhe2048(dh)",
+ .test = alg_test_kpp,
+ .fips_allowed = 1,
+ .suite = {
+ .kpp = __VECS(ffdhe2048_dh_tv_template)
+ }
+ }, {
+ .alg = "ffdhe3072(dh)",
+ .test = alg_test_kpp,
+ .fips_allowed = 1,
+ .suite = {
+ .kpp = __VECS(ffdhe3072_dh_tv_template)
+ }
+ }, {
+ .alg = "ffdhe4096(dh)",
+ .test = alg_test_kpp,
+ .fips_allowed = 1,
+ .suite = {
+ .kpp = __VECS(ffdhe4096_dh_tv_template)
+ }
+ }, {
+ .alg = "ffdhe6144(dh)",
+ .test = alg_test_kpp,
+ .fips_allowed = 1,
+ .suite = {
+ .kpp = __VECS(ffdhe6144_dh_tv_template)
+ }
+ }, {
+ .alg = "ffdhe8192(dh)",
+ .test = alg_test_kpp,
+ .fips_allowed = 1,
+ .suite = {
+ .kpp = __VECS(ffdhe8192_dh_tv_template)
+ }
+ }, {
+#endif /* CONFIG_CRYPTO_DH_RFC7919_GROUPS */
.alg = "gcm(aes)",
.generic_driver = "gcm_base(ctr(aes-generic),ghash-generic)",
.test = alg_test_aead,
@@ -5613,6 +5649,13 @@ static int alg_find_test(const char *alg)
return -1;
}
+static int alg_fips_disabled(const char *driver, const char *alg)
+{
+ pr_info("alg: %s (%s) is disabled due to FIPS\n", alg, driver);
+
+ return -ECANCELED;
+}
+
int alg_test(const char *driver, const char *alg, u32 type, u32 mask)
{
int i;
@@ -5649,9 +5692,13 @@ int alg_test(const char *driver, const char *alg, u32 type, u32 mask)
if (i < 0 && j < 0)
goto notest;
- if (fips_enabled && ((i >= 0 && !alg_test_descs[i].fips_allowed) ||
- (j >= 0 && !alg_test_descs[j].fips_allowed)))
- goto non_fips_alg;
+ if (fips_enabled) {
+ if (j >= 0 && !alg_test_descs[j].fips_allowed)
+ return -EINVAL;
+
+ if (i >= 0 && !alg_test_descs[i].fips_allowed)
+ goto non_fips_alg;
+ }
rc = 0;
if (i >= 0)
@@ -5681,9 +5728,13 @@ test_done:
notest:
printk(KERN_INFO "alg: No test for %s (%s)\n", alg, driver);
+
+ if (type & CRYPTO_ALG_FIPS_INTERNAL)
+ return alg_fips_disabled(driver, alg);
+
return 0;
non_fips_alg:
- return -EINVAL;
+ return alg_fips_disabled(driver, alg);
}
#endif /* CONFIG_CRYPTO_MANAGER_DISABLE_TESTS */
diff --git a/crypto/testmgr.h b/crypto/testmgr.h
index a253d66ba1c1..d1aa90993bbd 100644
--- a/crypto/testmgr.h
+++ b/crypto/testmgr.h
@@ -33,6 +33,7 @@
* @ksize: Length of @key in bytes (0 if no key)
* @setkey_error: Expected error from setkey()
* @digest_error: Expected error from digest()
+ * @fips_skip: Skip the test vector in FIPS mode
*/
struct hash_testvec {
const char *key;
@@ -42,6 +43,7 @@ struct hash_testvec {
unsigned short ksize;
int setkey_error;
int digest_error;
+ bool fips_skip;
};
/*
@@ -1244,17 +1246,15 @@ static const struct kpp_testvec dh_tv_template[] = {
.secret =
#ifdef __LITTLE_ENDIAN
"\x01\x00" /* type */
- "\x15\x02" /* len */
+ "\x11\x02" /* len */
"\x00\x01\x00\x00" /* key_size */
"\x00\x01\x00\x00" /* p_size */
- "\x00\x00\x00\x00" /* q_size */
"\x01\x00\x00\x00" /* g_size */
#else
"\x00\x01" /* type */
- "\x02\x15" /* len */
+ "\x02\x11" /* len */
"\x00\x00\x01\x00" /* key_size */
"\x00\x00\x01\x00" /* p_size */
- "\x00\x00\x00\x00" /* q_size */
"\x00\x00\x00\x01" /* g_size */
#endif
/* xa */
@@ -1344,7 +1344,7 @@ static const struct kpp_testvec dh_tv_template[] = {
"\xd3\x34\x49\xad\x64\xa6\xb1\xc0\x59\x28\x75\x60\xa7\x8a\xb0\x11"
"\x56\x89\x42\x74\x11\xf5\xf6\x5e\x6f\x16\x54\x6a\xb1\x76\x4d\x50"
"\x8a\x68\xc1\x5b\x82\xb9\x0d\x00\x32\x50\xed\x88\x87\x48\x92\x17",
- .secret_size = 533,
+ .secret_size = 529,
.b_public_size = 256,
.expected_a_public_size = 256,
.expected_ss_size = 256,
@@ -1353,17 +1353,15 @@ static const struct kpp_testvec dh_tv_template[] = {
.secret =
#ifdef __LITTLE_ENDIAN
"\x01\x00" /* type */
- "\x15\x02" /* len */
+ "\x11\x02" /* len */
"\x00\x01\x00\x00" /* key_size */
"\x00\x01\x00\x00" /* p_size */
- "\x00\x00\x00\x00" /* q_size */
"\x01\x00\x00\x00" /* g_size */
#else
"\x00\x01" /* type */
- "\x02\x15" /* len */
+ "\x02\x11" /* len */
"\x00\x00\x01\x00" /* key_size */
"\x00\x00\x01\x00" /* p_size */
- "\x00\x00\x00\x00" /* q_size */
"\x00\x00\x00\x01" /* g_size */
#endif
/* xa */
@@ -1453,13 +1451,1442 @@ static const struct kpp_testvec dh_tv_template[] = {
"\x5e\x5a\x64\xbd\xf6\x85\x04\xe8\x28\x6a\xac\xef\xce\x19\x8e\x9a"
"\xfe\x75\xc0\x27\x69\xe3\xb3\x7b\x21\xa7\xb1\x16\xa4\x85\x23\xee"
"\xb0\x1b\x04\x6e\xbd\xab\x16\xde\xfd\x86\x6b\xa9\x95\xd7\x0b\xfd",
- .secret_size = 533,
+ .secret_size = 529,
.b_public_size = 256,
.expected_a_public_size = 256,
.expected_ss_size = 256,
}
};
+static const struct kpp_testvec ffdhe2048_dh_tv_template[] __maybe_unused = {
+ {
+ .secret =
+#ifdef __LITTLE_ENDIAN
+ "\x01\x00" /* type */
+ "\x10\x01" /* len */
+ "\x00\x01\x00\x00" /* key_size */
+ "\x00\x00\x00\x00" /* p_size */
+ "\x00\x00\x00\x00" /* g_size */
+#else
+ "\x00\x01" /* type */
+ "\x01\x10" /* len */
+ "\x00\x00\x01\x00" /* key_size */
+ "\x00\x00\x00\x00" /* p_size */
+ "\x00\x00\x00\x00" /* g_size */
+#endif
+ /* xa */
+ "\x23\x7d\xd0\x06\xfd\x7a\xe5\x7a\x08\xda\x98\x31\xc0\xb3\xd5\x85"
+ "\xe2\x0d\x2a\x91\x5f\x78\x4b\xa6\x62\xd0\xa6\x35\xd4\xef\x86\x39"
+ "\xf1\xdb\x71\x5e\xb0\x11\x2e\xee\x91\x3a\xaa\xf9\xe3\xdf\x8d\x8b"
+ "\x48\x41\xde\xe8\x78\x53\xc5\x5f\x93\xd2\x79\x0d\xbe\x8d\x83\xe8"
+ "\x8f\x00\xd2\xde\x13\x18\x04\x05\x20\x6d\xda\xfa\x1d\x0b\x24\x52"
+ "\x3a\x18\x2b\xe1\x1e\xae\x15\x3b\x0f\xaa\x09\x09\xf6\x01\x98\xe9"
+ "\x81\x5d\x6b\x83\x6e\x55\xf1\x5d\x6f\x6f\x0d\x9d\xa8\x72\x32\x63"
+ "\x60\xe6\x0b\xc5\x22\xe2\xf9\x46\x58\xa2\x1c\x2a\xb0\xd5\xaf\xe3"
+ "\x5b\x03\xb7\x36\xb7\xba\x55\x20\x08\x7c\x51\xd4\x89\x42\x9c\x14"
+ "\x23\xe2\x71\x3e\x15\x2a\x0d\x34\x8a\xde\xad\x84\x11\x15\x72\x18"
+ "\x42\x43\x0a\xe2\x58\x29\xb3\x90\x0f\x56\xd8\x8a\x0f\x0e\xbc\x0e"
+ "\x9c\xe7\xd5\xe6\x5b\xbf\x06\x64\x38\x12\xa5\x8d\x5b\x68\x34\xdd"
+ "\x75\x48\xc9\xa7\xa3\x58\x5a\x1c\xe1\xb2\xc5\xe3\x39\x03\xcf\xab"
+ "\xc2\x14\x07\xaf\x55\x80\xc7\x63\xe4\x03\xeb\xe9\x0a\x25\x61\x85"
+ "\x1d\x0e\x81\x52\x7b\xbc\x4a\x0c\xc8\x59\x6a\xac\x18\xfb\x8c\x0c"
+ "\xb4\x79\xbd\xa1\x4c\xbb\x02\xc9\xd5\x13\x88\x3d\x25\xaa\x77\x49",
+ .b_public =
+ "\x5c\x00\x6f\xda\xfe\x4c\x0c\xc2\x18\xff\xa9\xec\x7a\xbe\x8a\x51"
+ "\x64\x6b\x57\xf8\xed\xe2\x36\x77\xc1\x23\xbf\x56\xa6\x48\x76\x34"
+ "\x0e\xf3\x68\x05\x45\x6a\x98\x5b\x9e\x8b\xc0\x11\x29\xcb\x5b\x66"
+ "\x2d\xc2\xeb\x4c\xf1\x7d\x85\x30\xaa\xd5\xf5\xb8\xd3\x62\x1e\x97"
+ "\x1e\x34\x18\xf8\x76\x8c\x10\xca\x1f\xe4\x5d\x62\xe1\xbe\x61\xef"
+ "\xaf\x2c\x8d\x97\x15\xa5\x86\xd5\xd3\x12\x6f\xec\xe2\xa4\xb2\x5a"
+ "\x35\x1d\xd4\x91\xa6\xef\x13\x09\x65\x9c\x45\xc0\x12\xad\x7f\xee"
+ "\x93\x5d\xfa\x89\x26\x7d\xae\xee\xea\x8c\xa3\xcf\x04\x2d\xa0\xc7"
+ "\xd9\x14\x62\xaf\xdf\xa0\x33\xd7\x5e\x83\xa2\xe6\x0e\x0e\x5d\x77"
+ "\xce\xe6\x72\xe4\xec\x9d\xff\x72\x9f\x38\x95\x19\x96\xba\x4c\xe3"
+ "\x5f\xb8\x46\x4a\x1d\xe9\x62\x7b\xa8\xdc\xe7\x61\x90\x6b\xb9\xd4"
+ "\xad\x0b\xa3\x06\xb3\x70\xfa\xea\x2b\xc4\x2c\xde\x43\x37\xf6\x8d"
+ "\x72\xf0\x86\x9a\xbb\x3b\x8e\x7a\x71\x03\x30\x30\x2a\x5d\xcd\x1e"
+ "\xe4\xd3\x08\x07\x75\x17\x17\x72\x1e\x77\x6c\x98\x0d\x29\x7f\xac"
+ "\xe7\xb2\xee\xa9\x1c\x33\x9d\x08\x39\xe1\xd8\x5b\xe5\xbc\x48\xb2"
+ "\xb6\xdf\xcd\xa0\x42\x06\xcc\xfb\xed\x60\x6f\xbc\x57\xac\x09\x45",
+ .expected_a_public =
+ "\x8b\xdb\xc1\xf7\xc6\xba\xa1\x38\x95\x6a\xa1\xb6\x04\x5e\xae\x52"
+ "\x72\xfc\xef\x2d\x9d\x71\x05\x9c\xd3\x02\xa9\xfb\x55\x0f\xfa\xc9"
+ "\xb4\x34\x51\xa3\x28\x89\x8d\x93\x92\xcb\xd9\xb5\xb9\x66\xfc\x67"
+ "\x15\x92\x6f\x73\x85\x15\xe2\xfc\x11\x6b\x97\x8c\x4b\x0f\x12\xfa"
+ "\x8d\x72\x76\x9b\x8f\x3b\xfe\x31\xbe\x42\x88\x4c\xd2\xb2\x70\xa6"
+ "\xa5\xe3\x7e\x73\x07\x12\x36\xaa\xc9\x5c\x83\xe1\xf1\x46\x41\x4f"
+ "\x7c\x52\xaf\xdc\xa4\xe6\x82\xa3\x86\x83\x47\x5a\x12\x3a\x0c\xe3"
+ "\xdd\xdb\x94\x03\x2a\x59\x91\xa0\x19\xe5\xf8\x07\xdd\x54\x6a\x22"
+ "\x43\xb7\xf3\x74\xd7\xb9\x30\xfe\x9c\xe8\xd1\xcf\x06\x43\x68\xb9"
+ "\x54\x8f\x54\xa2\xe5\x3c\xf2\xc3\x4c\xee\xd4\x7c\x5d\x0e\xb1\x7b"
+ "\x16\x68\xb5\xb3\x7d\xd4\x11\x83\x5c\x77\x17\xc4\xf0\x59\x76\x7a"
+ "\x83\x40\xe5\xd9\x4c\x76\x23\x5b\x17\x6d\xee\x4a\x92\x68\x4b\x89"
+ "\xa0\x6d\x23\x8c\x80\x31\x33\x3a\x12\xf4\x50\xa6\xcb\x13\x97\x01"
+ "\xb8\x2c\xe6\xd2\x38\xdf\xd0\x7f\xc6\x27\x19\x0e\xb2\x07\xfd\x1f"
+ "\x1b\x9c\x1b\x87\xf9\x73\x6a\x3f\x7f\xb0\xf9\x2f\x3c\x19\x9f\xc9"
+ "\x8f\x97\x21\x0e\x8e\xbb\x1a\x17\x20\x15\xdd\xc6\x42\x60\xae\x4d",
+ .expected_ss =
+ "\xf3\x0e\x64\x7b\x66\xd7\x82\x7e\xab\x7e\x4a\xbe\x13\x6f\x43\x3d"
+ "\xea\x4f\x1f\x8b\x9d\x41\x56\x71\xe1\x06\x96\x02\x68\xfa\x44\x6e"
+ "\xe7\xf2\x26\xd4\x01\x4a\xf0\x28\x25\x76\xad\xd7\xe0\x17\x74\xfe"
+ "\xf9\xe1\x6d\xd3\xf7\xc7\xdf\xc0\x62\xa5\xf3\x4e\x1b\x5c\x77\x2a"
+ "\xfb\x0b\x87\xc3\xde\x1e\xc1\xe0\xd3\x7a\xb8\x02\x02\xec\x9c\x97"
+ "\xfb\x34\xa0\x20\x10\x23\x87\xb2\x9a\x72\xe3\x3d\xb2\x18\x50\xf3"
+ "\x6a\xd3\xd3\x19\xc4\x36\xd5\x59\xd6\xd6\xa7\x5c\xc3\xf9\x09\x33"
+ "\xa1\xf5\xb9\x4b\xf3\x0b\xe1\x4f\x79\x6b\x45\xf2\xec\x8b\xe5\x69"
+ "\x9f\xc6\x05\x01\xfe\x3a\x13\xfd\x6d\xea\x03\x83\x29\x7c\x7f\xf5"
+ "\x41\x55\x95\xde\x7e\x62\xae\xaf\x28\xdb\x7c\xa9\x90\x1e\xb2\xb1"
+ "\x1b\xef\xf1\x2e\xde\x47\xaa\xa8\x92\x9a\x49\x3d\xc0\xe0\x8d\xbb"
+ "\x0c\x42\x86\xaf\x00\xce\xb0\xab\x22\x7c\xe9\xbe\xb9\x72\x2f\xcf"
+ "\x5e\x5d\x62\x52\x2a\xd1\xfe\xcc\xa2\xf3\x40\xfd\x01\xa7\x54\x0a"
+ "\xa1\xfb\x1c\xf2\x44\xa6\x47\x30\x5a\xba\x2a\x05\xff\xd0\x6c\xab"
+ "\xeb\xe6\x8f\xf6\xd7\x73\xa3\x0e\x6c\x0e\xcf\xfd\x8e\x16\x5d\xe0"
+ "\x2c\x11\x05\x82\x3c\x22\x16\x6c\x52\x61\xcf\xbb\xff\xf8\x06\xd0",
+ .secret_size = 272,
+ .b_public_size = 256,
+ .expected_a_public_size = 256,
+ .expected_ss_size = 256,
+ },
+ {
+ .secret =
+#ifdef __LITTLE_ENDIAN
+ "\x01\x00" /* type */
+ "\x10\x00" /* len */
+ "\x00\x00\x00\x00" /* key_size */
+ "\x00\x00\x00\x00" /* p_size */
+ "\x00\x00\x00\x00", /* g_size */
+#else
+ "\x00\x01" /* type */
+ "\x00\x10" /* len */
+ "\x00\x00\x00\x00" /* key_size */
+ "\x00\x00\x00\x00" /* p_size */
+ "\x00\x00\x00\x00", /* g_size */
+#endif
+ .b_secret =
+#ifdef __LITTLE_ENDIAN
+ "\x01\x00" /* type */
+ "\x10\x01" /* len */
+ "\x00\x01\x00\x00" /* key_size */
+ "\x00\x00\x00\x00" /* p_size */
+ "\x00\x00\x00\x00" /* g_size */
+#else
+ "\x00\x01" /* type */
+ "\x01\x10" /* len */
+ "\x00\x00\x01\x00" /* key_size */
+ "\x00\x00\x00\x00" /* p_size */
+ "\x00\x00\x00\x00" /* g_size */
+#endif
+ /* xa */
+ "\x23\x7d\xd0\x06\xfd\x7a\xe5\x7a\x08\xda\x98\x31\xc0\xb3\xd5\x85"
+ "\xe2\x0d\x2a\x91\x5f\x78\x4b\xa6\x62\xd0\xa6\x35\xd4\xef\x86\x39"
+ "\xf1\xdb\x71\x5e\xb0\x11\x2e\xee\x91\x3a\xaa\xf9\xe3\xdf\x8d\x8b"
+ "\x48\x41\xde\xe8\x78\x53\xc5\x5f\x93\xd2\x79\x0d\xbe\x8d\x83\xe8"
+ "\x8f\x00\xd2\xde\x13\x18\x04\x05\x20\x6d\xda\xfa\x1d\x0b\x24\x52"
+ "\x3a\x18\x2b\xe1\x1e\xae\x15\x3b\x0f\xaa\x09\x09\xf6\x01\x98\xe9"
+ "\x81\x5d\x6b\x83\x6e\x55\xf1\x5d\x6f\x6f\x0d\x9d\xa8\x72\x32\x63"
+ "\x60\xe6\x0b\xc5\x22\xe2\xf9\x46\x58\xa2\x1c\x2a\xb0\xd5\xaf\xe3"
+ "\x5b\x03\xb7\x36\xb7\xba\x55\x20\x08\x7c\x51\xd4\x89\x42\x9c\x14"
+ "\x23\xe2\x71\x3e\x15\x2a\x0d\x34\x8a\xde\xad\x84\x11\x15\x72\x18"
+ "\x42\x43\x0a\xe2\x58\x29\xb3\x90\x0f\x56\xd8\x8a\x0f\x0e\xbc\x0e"
+ "\x9c\xe7\xd5\xe6\x5b\xbf\x06\x64\x38\x12\xa5\x8d\x5b\x68\x34\xdd"
+ "\x75\x48\xc9\xa7\xa3\x58\x5a\x1c\xe1\xb2\xc5\xe3\x39\x03\xcf\xab"
+ "\xc2\x14\x07\xaf\x55\x80\xc7\x63\xe4\x03\xeb\xe9\x0a\x25\x61\x85"
+ "\x1d\x0e\x81\x52\x7b\xbc\x4a\x0c\xc8\x59\x6a\xac\x18\xfb\x8c\x0c"
+ "\xb4\x79\xbd\xa1\x4c\xbb\x02\xc9\xd5\x13\x88\x3d\x25\xaa\x77\x49",
+ .b_public =
+ "\x8b\xdb\xc1\xf7\xc6\xba\xa1\x38\x95\x6a\xa1\xb6\x04\x5e\xae\x52"
+ "\x72\xfc\xef\x2d\x9d\x71\x05\x9c\xd3\x02\xa9\xfb\x55\x0f\xfa\xc9"
+ "\xb4\x34\x51\xa3\x28\x89\x8d\x93\x92\xcb\xd9\xb5\xb9\x66\xfc\x67"
+ "\x15\x92\x6f\x73\x85\x15\xe2\xfc\x11\x6b\x97\x8c\x4b\x0f\x12\xfa"
+ "\x8d\x72\x76\x9b\x8f\x3b\xfe\x31\xbe\x42\x88\x4c\xd2\xb2\x70\xa6"
+ "\xa5\xe3\x7e\x73\x07\x12\x36\xaa\xc9\x5c\x83\xe1\xf1\x46\x41\x4f"
+ "\x7c\x52\xaf\xdc\xa4\xe6\x82\xa3\x86\x83\x47\x5a\x12\x3a\x0c\xe3"
+ "\xdd\xdb\x94\x03\x2a\x59\x91\xa0\x19\xe5\xf8\x07\xdd\x54\x6a\x22"
+ "\x43\xb7\xf3\x74\xd7\xb9\x30\xfe\x9c\xe8\xd1\xcf\x06\x43\x68\xb9"
+ "\x54\x8f\x54\xa2\xe5\x3c\xf2\xc3\x4c\xee\xd4\x7c\x5d\x0e\xb1\x7b"
+ "\x16\x68\xb5\xb3\x7d\xd4\x11\x83\x5c\x77\x17\xc4\xf0\x59\x76\x7a"
+ "\x83\x40\xe5\xd9\x4c\x76\x23\x5b\x17\x6d\xee\x4a\x92\x68\x4b\x89"
+ "\xa0\x6d\x23\x8c\x80\x31\x33\x3a\x12\xf4\x50\xa6\xcb\x13\x97\x01"
+ "\xb8\x2c\xe6\xd2\x38\xdf\xd0\x7f\xc6\x27\x19\x0e\xb2\x07\xfd\x1f"
+ "\x1b\x9c\x1b\x87\xf9\x73\x6a\x3f\x7f\xb0\xf9\x2f\x3c\x19\x9f\xc9"
+ "\x8f\x97\x21\x0e\x8e\xbb\x1a\x17\x20\x15\xdd\xc6\x42\x60\xae\x4d",
+ .secret_size = 16,
+ .b_secret_size = 272,
+ .b_public_size = 256,
+ .expected_a_public_size = 256,
+ .expected_ss_size = 256,
+ .genkey = true,
+ },
+};
+
+static const struct kpp_testvec ffdhe3072_dh_tv_template[] __maybe_unused = {
+ {
+ .secret =
+#ifdef __LITTLE_ENDIAN
+ "\x01\x00" /* type */
+ "\x90\x01" /* len */
+ "\x80\x01\x00\x00" /* key_size */
+ "\x00\x00\x00\x00" /* p_size */
+ "\x00\x00\x00\x00" /* g_size */
+#else
+ "\x00\x01" /* type */
+ "\x01\x90" /* len */
+ "\x00\x00\x01\x80" /* key_size */
+ "\x00\x00\x00\x00" /* p_size */
+ "\x00\x00\x00\x00" /* g_size */
+#endif
+ /* xa */
+ "\x6b\xb4\x97\x23\xfa\xc8\x5e\xa9\x7b\x63\xe7\x3e\x0e\x99\xc3\xb9"
+ "\xda\xb7\x48\x0d\xc3\xb1\xbf\x4f\x17\xc7\xa9\x51\xf6\x64\xff\xc4"
+ "\x31\x58\x87\x25\x83\x2c\x00\xf0\x41\x29\xf7\xee\xf9\xe6\x36\x76"
+ "\xd6\x3a\x24\xbe\xa7\x07\x0b\x93\xc7\x9f\x6c\x75\x0a\x26\x75\x76"
+ "\xe3\x0c\x42\xe0\x00\x04\x69\xd9\xec\x0b\x59\x54\x28\x8f\xd7\x9a"
+ "\x63\xf4\x5b\xdf\x85\x65\xc4\xe1\x95\x27\x4a\x42\xad\x36\x47\xa9"
+ "\x0a\xf8\x14\x1c\xf3\x94\x3b\x7e\x47\x99\x35\xa8\x18\xec\x70\x10"
+ "\xdf\xcb\xd2\x78\x88\xc1\x2d\x59\x93\xc1\xa4\x6d\xd7\x1d\xb9\xd5"
+ "\xf8\x30\x06\x7f\x98\x90\x0c\x74\x5e\x89\x2f\x64\x5a\xad\x5f\x53"
+ "\xb2\xa3\xa8\x83\xbf\xfc\x37\xef\xb8\x36\x0a\x5c\x62\x81\x64\x74"
+ "\x16\x2f\x45\x39\x2a\x91\x26\x87\xc0\x12\xcc\x75\x11\xa3\xa1\xc5"
+ "\xae\x20\xcf\xcb\x20\x25\x6b\x7a\x31\x93\x9d\x38\xb9\x57\x72\x46"
+ "\xd4\x84\x65\x87\xf1\xb5\xd3\xab\xfc\xc3\x4d\x40\x92\x94\x1e\xcd"
+ "\x1c\x87\xec\x3f\xcd\xbe\xd0\x95\x6b\x40\x02\xdd\x62\xeb\x0a\xda"
+ "\x4f\xbe\x8e\x32\x48\x8b\x6d\x83\xa0\x96\x62\x23\xec\x83\x91\x44"
+ "\xf9\x72\x01\xac\xa0\xe4\x72\x1d\x5a\x75\x05\x57\x90\xae\x7e\xb4"
+ "\x71\x39\x01\x05\xdc\xe9\xee\xcb\xf0\x61\x28\x91\x69\x8c\x31\x03"
+ "\x7a\x92\x15\xa1\x58\x67\x3d\x70\x82\xa6\x2c\xfe\x10\x56\x58\xd3"
+ "\x94\x67\xe1\xbe\xee\xc1\x64\x5c\x4b\xc8\x28\x3d\xc5\x66\x3a\xab"
+ "\x22\xc1\x7e\xa1\xbb\xf3\x19\x3b\xda\x46\x82\x45\xd4\x3c\x7c\xc6"
+ "\xce\x1f\x7f\x95\xa2\x17\xff\x88\xba\xd6\x4d\xdb\xd2\xea\xde\x39"
+ "\xd6\xa5\x18\x73\xbb\x64\x6e\x79\xe9\xdc\x3f\x92\x7f\xda\x1f\x49"
+ "\x33\x70\x65\x73\xa2\xd9\x06\xb8\x1b\x29\x29\x1a\xe0\xa3\xe6\x05"
+ "\x9a\xa8\xc2\x4e\x7a\x78\x1d\x22\x57\x21\xc8\xa3\x8d\x66\x3e\x23",
+ .b_public =
+ "\x73\x40\x8b\xce\xe8\x6a\x1c\x03\x50\x54\x42\x36\x22\xc6\x1d\xe8"
+ "\xe1\xef\x5c\x89\xa5\x55\xc1\xc4\x1c\xd7\x4f\xee\x5d\xba\x62\x60"
+ "\xfe\x93\x2f\xfd\x93\x2c\x8f\x70\xc6\x47\x17\x25\xb2\x95\xd7\x7d"
+ "\x41\x81\x4d\x52\x1c\xbe\x4d\x57\x3e\x26\x51\x28\x03\x8f\x67\xf5"
+ "\x22\x16\x1c\x67\xf7\x62\xcb\xfd\xa3\xee\x8d\xe0\xfa\x15\x9a\x53"
+ "\xbe\x7b\x9f\xc0\x12\x7a\xfc\x5e\x77\x2d\x60\x06\xba\x71\xc5\xca"
+ "\xd7\x26\xaf\x3b\xba\x6f\xd3\xc4\x82\x57\x19\x26\xb0\x16\x7b\xbd"
+ "\x83\xf2\x21\x03\x79\xff\x0a\x6f\xc5\x7b\x00\x15\xad\x5b\xf4\x42"
+ "\x1f\xcb\x7f\x3d\x34\x77\x3c\xc3\xe0\x38\xa5\x40\x51\xbe\x6f\xd9"
+ "\xc9\x77\x9c\xfc\x0d\xc1\x8e\xef\x0f\xaa\x5e\xa8\xbb\x16\x4a\x3e"
+ "\x26\x55\xae\xc1\xb6\x3e\xfd\x73\xf7\x59\xd2\xe5\x4b\x91\x8e\x28"
+ "\x77\x1e\x5a\xe2\xcd\xce\x92\x35\xbb\x1e\xbb\xcf\x79\x94\xdf\x31"
+ "\xde\x31\xa8\x75\xf6\xe0\xaa\x2e\xe9\x4f\x44\xc8\xba\xb9\xab\x80"
+ "\x29\xa1\xea\x58\x2e\x40\x96\xa0\x1a\xf5\x2c\x38\x47\x43\x5d\x26"
+ "\x2c\xd8\xad\xea\xd3\xad\xe8\x51\x49\xad\x45\x2b\x25\x7c\xde\xe4"
+ "\xaf\x03\x2a\x39\x26\x86\x66\x10\xbc\xa8\x71\xda\xe0\xe8\xf1\xdd"
+ "\x50\xff\x44\xb2\xd3\xc7\xff\x66\x63\xf6\x42\xe3\x97\x9d\x9e\xf4"
+ "\xa6\x89\xb9\xab\x12\x17\xf2\x85\x56\x9c\x6b\x24\x71\x83\x57\x7d"
+ "\x3c\x7b\x2b\x88\x92\x19\xd7\x1a\x00\xd5\x38\x94\x43\x60\x4d\xa7"
+ "\x12\x9e\x0d\xf6\x5c\x9a\xd3\xe2\x9e\xb1\x21\xe8\xe2\x9e\xe9\x1e"
+ "\x9d\xa5\x94\x95\xa6\x3d\x12\x15\xd8\x8b\xac\xe0\x8c\xde\xe6\x40"
+ "\x98\xaa\x5e\x55\x4f\x3d\x86\x87\x0d\xe3\xc6\x68\x15\xe6\xde\x17"
+ "\x78\x21\xc8\x6c\x06\xc7\x94\x56\xb4\xaf\xa2\x35\x0b\x0c\x97\xd7"
+ "\xa4\x12\xee\xf4\xd2\xef\x80\x28\xb3\xee\xe9\x15\x8b\x01\x32\x79",
+ .expected_a_public =
+ "\x1b\x6a\xba\xea\xa3\xcc\x50\x69\xa9\x41\x89\xaf\x04\xe1\x44\x22"
+ "\x97\x20\xd1\xf6\x1e\xcb\x64\x36\x6f\xee\x0b\x16\xc1\xd9\x91\xbe"
+ "\x57\xc8\xd9\xf2\xa1\x96\x91\xec\x41\xc7\x79\x00\x1a\x48\x25\x55"
+ "\xbe\xf3\x20\x8c\x38\xc6\x7b\xf2\x8b\x5a\xc3\xb5\x87\x0a\x86\x3d"
+ "\xb7\xd6\xce\xb0\x96\x2e\x5d\xc4\x00\x5e\x42\xe4\xe5\x50\x4f\xb8"
+ "\x6f\x18\xa4\xe1\xd3\x20\xfc\x3c\xf5\x0a\xff\x23\xa6\x5b\xb4\x17"
+ "\x3e\x7b\xdf\xb9\xb5\x3c\x1b\x76\x29\xcd\xb4\x46\x4f\x27\x8f\xd2"
+ "\xe8\x27\x66\xdb\xe8\xb3\xf5\xe1\xd0\x04\xcd\x89\xff\xba\x76\x67"
+ "\xe8\x4d\xcf\x86\x1c\x8a\xd1\xcf\x99\x27\xfb\xa9\x78\xcc\x94\xaf"
+ "\x3d\x04\xfd\x25\xc0\x47\xfa\x29\x80\x05\xf4\xde\xad\xdb\xab\x12"
+ "\xb0\x2b\x8e\xca\x02\x06\x6d\xad\x3e\x09\xb1\x22\xa3\xf5\x4c\x6d"
+ "\x69\x99\x58\x8b\xd8\x45\x2e\xe0\xc9\x3c\xf7\x92\xce\x21\x90\x6b"
+ "\x3b\x65\x9f\x64\x79\x8d\x67\x22\x1a\x37\xd3\xee\x51\xe2\xe7\x5a"
+ "\x93\x51\xaa\x3c\x4b\x04\x16\x32\xef\xe3\x66\xbe\x18\x94\x88\x64"
+ "\x79\xce\x06\x3f\xb8\xd6\xee\xdc\x13\x79\x6f\x20\x14\xc2\x6b\xce"
+ "\xc8\xda\x42\xa5\x93\x5b\xe4\x7f\x1a\xe6\xda\x0f\xb3\xc1\x5f\x30"
+ "\x50\x76\xe8\x37\x3d\xca\x77\x2c\xa8\xe4\x3b\xf9\x6f\xe0\x17\xed"
+ "\x0e\xef\xb7\x31\x14\xb5\xea\xd9\x39\x22\x89\xb6\x40\x57\xcc\x84"
+ "\xef\x73\xa7\xe9\x27\x21\x85\x89\xfa\xaf\x03\xda\x9c\x8b\xfd\x52"
+ "\x7d\xb0\xa4\xe4\xf9\xd8\x90\x55\xc4\x39\xd6\x9d\xaf\x3b\xce\xac"
+ "\xaa\x36\x14\x7a\x9b\x8b\x12\x43\xe1\xca\x61\xae\x46\x5b\xe7\xe5"
+ "\x88\x32\x80\xa0\x2d\x51\xbb\x2f\xea\xeb\x3c\x71\xb2\xae\xce\xca"
+ "\x61\xd2\x76\xe0\x45\x46\x78\x4e\x09\x2d\xc2\x54\xc2\xa9\xc7\xa8"
+ "\x55\x8e\x72\xa4\x8b\x8a\xc9\x01\xdb\xe9\x58\x11\xa1\xc4\xe7\x12",
+ .expected_ss =
+ "\x47\x8e\xb2\x19\x09\xf0\x46\x99\x6b\x41\x86\xf7\x34\xad\xbf\x2a"
+ "\x18\x1b\x7d\xec\xa9\xb2\x47\x2f\x40\xfb\x9a\x64\x30\x44\xf3\x4c"
+ "\x01\x67\xad\x57\x5a\xbc\xd4\xc8\xef\x7e\x8a\x14\x74\x1d\x6d\x8c"
+ "\x7b\xce\xc5\x57\x5f\x95\xe8\x72\xba\xdf\xa3\xcd\x00\xbe\x09\x4c"
+ "\x06\x72\xe7\x17\xb0\xe5\xe5\xb7\x20\xa5\xcb\xd9\x68\x99\xad\x3f"
+ "\xde\xf3\xde\x1d\x1c\x00\x74\xd2\xd1\x57\x55\x5d\xce\x76\x0c\xc4"
+ "\x7a\xc4\x65\x7c\x19\x17\x0a\x09\x66\x7d\x3a\xab\xf7\x61\x3a\xe3"
+ "\x5b\xac\xcf\x69\xb0\x8b\xee\x5d\x28\x36\xbb\x3f\x74\xce\x6e\x38"
+ "\x1e\x39\xab\x26\xca\x89\xdc\x58\x59\xcb\x95\xe4\xbc\xd6\x19\x48"
+ "\xd0\x55\x68\x7b\xb4\x27\x95\x3c\xd9\x58\x10\x4f\x8f\x55\x1c\x3f"
+ "\x04\xce\x89\x1f\x82\x28\xe9\x48\x17\x47\x8f\xee\xb7\x8f\xeb\xb1"
+ "\x29\xa8\x23\x18\x73\x33\x9f\x83\x08\xca\xcd\x54\x6e\xca\xec\x78"
+ "\x7b\x16\x83\x3f\xdb\x0a\xef\xfd\x87\x94\x19\x08\x6e\x6e\x22\x57"
+ "\xd7\xd2\x79\xf9\xf6\xeb\xe0\x6c\x93\x9d\x95\xfa\x41\x7a\xa9\xd6"
+ "\x2a\xa3\x26\x9b\x24\x1b\x8b\xa0\xed\x04\xb2\xe4\x6c\x4e\xc4\x3f"
+ "\x61\xe5\xe0\x4d\x09\x28\xaf\x58\x35\x25\x0b\xd5\x38\x18\x69\x51"
+ "\x18\x51\x73\x7b\x28\x19\x9f\xe4\x69\xfc\x2c\x25\x08\x99\x8f\x62"
+ "\x65\x62\xa5\x28\xf1\xf4\xfb\x02\x29\x27\xb0\x5e\xbb\x4f\xf9\x1a"
+ "\xa7\xc4\x38\x63\x5b\x01\xfe\x00\x66\xe3\x47\x77\x21\x85\x17\xd5"
+ "\x34\x19\xd3\x87\xab\x44\x62\x08\x59\xb2\x6b\x1f\x21\x0c\x23\x84"
+ "\xf7\xba\x92\x67\xf9\x16\x85\x6a\xe0\xeb\xe7\x4f\x06\x80\x81\x81"
+ "\x28\x9c\xe8\x2e\x71\x97\x48\xe0\xd1\xbc\xce\xe9\x42\x2c\x89\xdf"
+ "\x0b\xa9\xa1\x07\x84\x33\x78\x7f\x49\x2f\x1c\x55\xc3\x7f\xc3\x37"
+ "\x40\xdf\x13\xf4\xa0\x21\x79\x6e\x3a\xe3\xb8\x23\x9e\x8a\x6e\x9c",
+ .secret_size = 400,
+ .b_public_size = 384,
+ .expected_a_public_size = 384,
+ .expected_ss_size = 384,
+ },
+ {
+ .secret =
+#ifdef __LITTLE_ENDIAN
+ "\x01\x00" /* type */
+ "\x10\x00" /* len */
+ "\x00\x00\x00\x00" /* key_size */
+ "\x00\x00\x00\x00" /* p_size */
+ "\x00\x00\x00\x00", /* g_size */
+#else
+ "\x00\x01" /* type */
+ "\x00\x10" /* len */
+ "\x00\x00\x00\x00" /* key_size */
+ "\x00\x00\x00\x00" /* p_size */
+ "\x00\x00\x00\x00", /* g_size */
+#endif
+ .b_secret =
+#ifdef __LITTLE_ENDIAN
+ "\x01\x00" /* type */
+ "\x90\x01" /* len */
+ "\x80\x01\x00\x00" /* key_size */
+ "\x00\x00\x00\x00" /* p_size */
+ "\x00\x00\x00\x00" /* g_size */
+#else
+ "\x00\x01" /* type */
+ "\x01\x90" /* len */
+ "\x00\x00\x01\x80" /* key_size */
+ "\x00\x00\x00\x00" /* p_size */
+ "\x00\x00\x00\x00" /* g_size */
+#endif
+ /* xa */
+ "\x6b\xb4\x97\x23\xfa\xc8\x5e\xa9\x7b\x63\xe7\x3e\x0e\x99\xc3\xb9"
+ "\xda\xb7\x48\x0d\xc3\xb1\xbf\x4f\x17\xc7\xa9\x51\xf6\x64\xff\xc4"
+ "\x31\x58\x87\x25\x83\x2c\x00\xf0\x41\x29\xf7\xee\xf9\xe6\x36\x76"
+ "\xd6\x3a\x24\xbe\xa7\x07\x0b\x93\xc7\x9f\x6c\x75\x0a\x26\x75\x76"
+ "\xe3\x0c\x42\xe0\x00\x04\x69\xd9\xec\x0b\x59\x54\x28\x8f\xd7\x9a"
+ "\x63\xf4\x5b\xdf\x85\x65\xc4\xe1\x95\x27\x4a\x42\xad\x36\x47\xa9"
+ "\x0a\xf8\x14\x1c\xf3\x94\x3b\x7e\x47\x99\x35\xa8\x18\xec\x70\x10"
+ "\xdf\xcb\xd2\x78\x88\xc1\x2d\x59\x93\xc1\xa4\x6d\xd7\x1d\xb9\xd5"
+ "\xf8\x30\x06\x7f\x98\x90\x0c\x74\x5e\x89\x2f\x64\x5a\xad\x5f\x53"
+ "\xb2\xa3\xa8\x83\xbf\xfc\x37\xef\xb8\x36\x0a\x5c\x62\x81\x64\x74"
+ "\x16\x2f\x45\x39\x2a\x91\x26\x87\xc0\x12\xcc\x75\x11\xa3\xa1\xc5"
+ "\xae\x20\xcf\xcb\x20\x25\x6b\x7a\x31\x93\x9d\x38\xb9\x57\x72\x46"
+ "\xd4\x84\x65\x87\xf1\xb5\xd3\xab\xfc\xc3\x4d\x40\x92\x94\x1e\xcd"
+ "\x1c\x87\xec\x3f\xcd\xbe\xd0\x95\x6b\x40\x02\xdd\x62\xeb\x0a\xda"
+ "\x4f\xbe\x8e\x32\x48\x8b\x6d\x83\xa0\x96\x62\x23\xec\x83\x91\x44"
+ "\xf9\x72\x01\xac\xa0\xe4\x72\x1d\x5a\x75\x05\x57\x90\xae\x7e\xb4"
+ "\x71\x39\x01\x05\xdc\xe9\xee\xcb\xf0\x61\x28\x91\x69\x8c\x31\x03"
+ "\x7a\x92\x15\xa1\x58\x67\x3d\x70\x82\xa6\x2c\xfe\x10\x56\x58\xd3"
+ "\x94\x67\xe1\xbe\xee\xc1\x64\x5c\x4b\xc8\x28\x3d\xc5\x66\x3a\xab"
+ "\x22\xc1\x7e\xa1\xbb\xf3\x19\x3b\xda\x46\x82\x45\xd4\x3c\x7c\xc6"
+ "\xce\x1f\x7f\x95\xa2\x17\xff\x88\xba\xd6\x4d\xdb\xd2\xea\xde\x39"
+ "\xd6\xa5\x18\x73\xbb\x64\x6e\x79\xe9\xdc\x3f\x92\x7f\xda\x1f\x49"
+ "\x33\x70\x65\x73\xa2\xd9\x06\xb8\x1b\x29\x29\x1a\xe0\xa3\xe6\x05"
+ "\x9a\xa8\xc2\x4e\x7a\x78\x1d\x22\x57\x21\xc8\xa3\x8d\x66\x3e\x23",
+ .b_public =
+ "\x1b\x6a\xba\xea\xa3\xcc\x50\x69\xa9\x41\x89\xaf\x04\xe1\x44\x22"
+ "\x97\x20\xd1\xf6\x1e\xcb\x64\x36\x6f\xee\x0b\x16\xc1\xd9\x91\xbe"
+ "\x57\xc8\xd9\xf2\xa1\x96\x91\xec\x41\xc7\x79\x00\x1a\x48\x25\x55"
+ "\xbe\xf3\x20\x8c\x38\xc6\x7b\xf2\x8b\x5a\xc3\xb5\x87\x0a\x86\x3d"
+ "\xb7\xd6\xce\xb0\x96\x2e\x5d\xc4\x00\x5e\x42\xe4\xe5\x50\x4f\xb8"
+ "\x6f\x18\xa4\xe1\xd3\x20\xfc\x3c\xf5\x0a\xff\x23\xa6\x5b\xb4\x17"
+ "\x3e\x7b\xdf\xb9\xb5\x3c\x1b\x76\x29\xcd\xb4\x46\x4f\x27\x8f\xd2"
+ "\xe8\x27\x66\xdb\xe8\xb3\xf5\xe1\xd0\x04\xcd\x89\xff\xba\x76\x67"
+ "\xe8\x4d\xcf\x86\x1c\x8a\xd1\xcf\x99\x27\xfb\xa9\x78\xcc\x94\xaf"
+ "\x3d\x04\xfd\x25\xc0\x47\xfa\x29\x80\x05\xf4\xde\xad\xdb\xab\x12"
+ "\xb0\x2b\x8e\xca\x02\x06\x6d\xad\x3e\x09\xb1\x22\xa3\xf5\x4c\x6d"
+ "\x69\x99\x58\x8b\xd8\x45\x2e\xe0\xc9\x3c\xf7\x92\xce\x21\x90\x6b"
+ "\x3b\x65\x9f\x64\x79\x8d\x67\x22\x1a\x37\xd3\xee\x51\xe2\xe7\x5a"
+ "\x93\x51\xaa\x3c\x4b\x04\x16\x32\xef\xe3\x66\xbe\x18\x94\x88\x64"
+ "\x79\xce\x06\x3f\xb8\xd6\xee\xdc\x13\x79\x6f\x20\x14\xc2\x6b\xce"
+ "\xc8\xda\x42\xa5\x93\x5b\xe4\x7f\x1a\xe6\xda\x0f\xb3\xc1\x5f\x30"
+ "\x50\x76\xe8\x37\x3d\xca\x77\x2c\xa8\xe4\x3b\xf9\x6f\xe0\x17\xed"
+ "\x0e\xef\xb7\x31\x14\xb5\xea\xd9\x39\x22\x89\xb6\x40\x57\xcc\x84"
+ "\xef\x73\xa7\xe9\x27\x21\x85\x89\xfa\xaf\x03\xda\x9c\x8b\xfd\x52"
+ "\x7d\xb0\xa4\xe4\xf9\xd8\x90\x55\xc4\x39\xd6\x9d\xaf\x3b\xce\xac"
+ "\xaa\x36\x14\x7a\x9b\x8b\x12\x43\xe1\xca\x61\xae\x46\x5b\xe7\xe5"
+ "\x88\x32\x80\xa0\x2d\x51\xbb\x2f\xea\xeb\x3c\x71\xb2\xae\xce\xca"
+ "\x61\xd2\x76\xe0\x45\x46\x78\x4e\x09\x2d\xc2\x54\xc2\xa9\xc7\xa8"
+ "\x55\x8e\x72\xa4\x8b\x8a\xc9\x01\xdb\xe9\x58\x11\xa1\xc4\xe7\x12",
+ .secret_size = 16,
+ .b_secret_size = 400,
+ .b_public_size = 384,
+ .expected_a_public_size = 384,
+ .expected_ss_size = 384,
+ .genkey = true,
+ },
+};
+
+static const struct kpp_testvec ffdhe4096_dh_tv_template[] __maybe_unused = {
+ {
+ .secret =
+#ifdef __LITTLE_ENDIAN
+ "\x01\x00" /* type */
+ "\x10\x02" /* len */
+ "\x00\x02\x00\x00" /* key_size */
+ "\x00\x00\x00\x00" /* p_size */
+ "\x00\x00\x00\x00" /* g_size */
+#else
+ "\x00\x01" /* type */
+ "\x02\x10" /* len */
+ "\x00\x00\x02\x00" /* key_size */
+ "\x00\x00\x00\x00" /* p_size */
+ "\x00\x00\x00\x00" /* g_size */
+#endif
+ /* xa */
+ "\x1a\x48\xf3\x6c\x61\x03\x42\x43\xd7\x42\x3b\xfa\xdb\x55\x6f\xa2"
+ "\xe1\x79\x52\x0b\x47\xc5\x03\x60\x2f\x26\xb9\x1a\x14\x15\x1a\xd9"
+ "\xe0\xbb\xa7\x82\x63\x41\xec\x26\x55\x00\xab\xe5\x21\x9d\x31\x14"
+ "\x0e\xe2\xc2\xb2\xb8\x37\xe6\xc3\x5a\xab\xae\x25\xdb\x71\x1e\xed"
+ "\xe8\x75\x9a\x04\xa7\x92\x2a\x99\x7e\xc0\x5b\x64\x75\x7f\xe5\xb5"
+ "\xdb\x6c\x95\x4f\xe9\xdc\x39\x76\x79\xb0\xf7\x00\x30\x8e\x86\xe7"
+ "\x36\xd1\xd2\x0c\x68\x7b\x94\xe9\x91\x85\x08\x86\xbc\x64\x87\xd2"
+ "\xf5\x5b\xaf\x03\xf6\x5f\x28\x25\xf1\xa3\x20\x5c\x1b\xb5\x26\x45"
+ "\x9a\x47\xab\xd6\xad\x49\xab\x92\x8e\x62\x6f\x48\x31\xea\xf6\x76"
+ "\xff\xa2\xb6\x28\x78\xef\x59\xc3\x71\x5d\xa8\xd9\x70\x89\xcc\xe2"
+ "\x63\x58\x5e\x3a\xa2\xa2\x88\xbf\x77\x20\x84\x33\x65\x64\x4e\x73"
+ "\xe5\x08\xd5\x89\x23\xd6\x07\xac\x29\x65\x2e\x02\xa8\x35\x96\x48"
+ "\xe7\x5d\x43\x6a\x42\xcc\xda\x98\xc4\x75\x90\x2e\xf6\xc4\xbf\xd4"
+ "\xbc\x31\x14\x0d\x54\x30\x11\xb2\xc9\xcf\xbb\xba\xbc\xc6\xf2\xcf"
+ "\xfe\x4a\x9d\xf3\xec\x78\x5d\x5d\xb4\x99\xd0\x67\x0f\x5a\x21\x1c"
+ "\x7b\x95\x2b\xcf\x49\x44\x94\x05\x1a\x21\x81\x25\x7f\xe3\x8a\x2a"
+ "\xdd\x88\xac\x44\x94\x23\x20\x3b\x75\xf6\x2a\x8a\x45\xf8\xb5\x1f"
+ "\xb9\x8b\xeb\xab\x9b\x38\x23\x26\xf1\x0f\x34\x47\x4f\x7f\xe1\x9e"
+ "\x84\x84\x78\xe5\xe3\x49\xeb\xcc\x2f\x02\x85\xa4\x18\x91\xde\x1a"
+ "\x60\x54\x33\x81\xd5\xae\xdb\x23\x9c\x4d\xa4\xdb\x22\x5b\xdf\xf4"
+ "\x8e\x05\x2b\x60\xba\xe8\x75\xfc\x34\x99\xcf\x35\xe1\x06\xba\xdc"
+ "\x79\x2a\x5e\xec\x1c\xbe\x79\x33\x63\x1c\xe7\x5f\x1e\x30\xd6\x1b"
+ "\xdb\x11\xb8\xea\x63\xff\xfe\x1a\x3c\x24\xf4\x78\x9c\xcc\x5d\x9a"
+ "\xc9\x2d\xc4\x9a\xd4\xa7\x65\x84\x98\xdb\x66\x76\xf0\x34\x31\x9f"
+ "\xce\xb5\xfb\x28\x07\xde\x1e\x0d\x9b\x01\x64\xeb\x2a\x37\x2f\x20"
+ "\xa5\x95\x72\x2b\x54\x51\x59\x91\xea\x50\x54\x0f\x2e\xb0\x1d\xf6"
+ "\xb9\x46\x43\xf9\xd0\x13\x21\x20\x47\x61\x1a\x1c\x30\xc6\x9e\x75"
+ "\x22\xe4\xf2\xb1\xab\x01\xdc\x5b\x3c\x1e\xa2\x6d\xc0\xb9\x9a\x2a"
+ "\x84\x61\xea\x85\x63\xa0\x77\xd0\xeb\x20\x68\xd5\x95\x6a\x1b\x8f"
+ "\x1f\x9a\xba\x44\x49\x8c\x77\xa6\xd9\xa0\x14\xf8\x7d\x9b\x4e\xfa"
+ "\xdc\x4f\x1c\x4d\x60\x50\x26\x7f\xd6\xc1\x91\x2b\xa6\x37\x5d\x94"
+ "\x69\xb2\x47\x59\xd6\xc3\x59\xbb\xd6\x9b\x71\x52\x85\x7a\xcb\x2d",
+ .b_public =
+ "\x24\x38\x02\x02\x2f\xeb\x54\xdd\x73\x21\x91\x4a\xd8\xa4\x0a\xbf"
+ "\xf4\xf5\x9a\x45\xb5\xcd\x42\xa3\x57\xcc\x65\x4a\x23\x2e\xee\x59"
+ "\xba\x6f\x14\x89\xae\x2e\x14\x0a\x72\x77\x23\x7f\x6c\x2e\xba\x52"
+ "\x3f\x71\xbf\xe4\x60\x03\x16\xaa\x61\xf5\x80\x1d\x8a\x45\x9e\x53"
+ "\x7b\x07\xd9\x7e\xfe\xaf\xcb\xda\xff\x20\x71\xba\x89\x39\x75\xc3"
+ "\xb3\x65\x0c\xb1\xa7\xfa\x4a\xe7\xe0\x85\xc5\x4e\x91\x47\x41\xf4"
+ "\xdd\xcd\xc5\x3d\x17\x12\xed\xee\xc0\x31\xb1\xaf\xc1\xd5\x3c\x07"
+ "\xa1\x5a\xc4\x05\x45\xe3\x10\x0c\xc3\x14\xae\x65\xca\x40\xae\x31"
+ "\x5c\x13\x0d\x32\x85\xa7\x6e\xf4\x5e\x29\x3d\x4e\xd3\xd7\x49\x58"
+ "\xe1\x73\xbb\x0a\x7b\xd6\x13\xea\x49\xd7\x20\x3d\x31\xaa\x77\xab"
+ "\x21\x74\xe9\x2f\xe9\x5e\xbe\x2f\xb4\xa2\x79\xf2\xbc\xcc\x51\x94"
+ "\xd2\x1d\xb2\xe6\xc5\x39\x66\xd7\xe5\x46\x75\x53\x76\xed\x49\xea"
+ "\x3b\xdd\x01\x27\xdb\x83\xa5\x9f\xd2\xee\xc8\xde\x9e\xde\xd2\xe7"
+ "\x99\xad\x9c\xe0\x71\x66\x29\xd8\x0d\xfe\xdc\xd1\xbc\xc7\x9a\xbe"
+ "\x8b\x26\x46\x57\xb6\x79\xfa\xad\x8b\x45\x2e\xb5\xe5\x89\x34\x01"
+ "\x93\x00\x9d\xe9\x58\x74\x8b\xda\x07\x92\xb5\x01\x4a\xe1\x44\x36"
+ "\xc7\x6c\xde\xc8\x7a\x17\xd0\xde\xee\x68\x92\xb5\xde\x21\x2b\x1c"
+ "\xbc\x65\x30\x1e\xae\x15\x3d\x9a\xaf\x20\xa3\xc4\x21\x70\xfb\x2f"
+ "\x36\x72\x31\xc0\xe8\x85\xdf\xc5\x50\x4c\x90\x10\x32\xa4\xc7\xee"
+ "\x59\x5a\x21\xf4\xf1\x33\xcf\xbe\xac\x67\xb1\x40\x7c\x0b\x3f\x64"
+ "\xe5\xd2\x2d\xb7\x7d\x0f\xce\xf7\x9b\x05\xee\x37\x61\xd2\x61\x9e"
+ "\x1a\x80\x2e\x79\xe6\x1b\x25\xb3\x61\x3d\x53\xe7\xe5\x97\x9a\xc2"
+ "\x39\xb1\xe3\x91\xc6\xee\x96\x2e\xa9\xb4\xb8\xad\xd8\x04\x3e\x11"
+ "\x31\x67\xb8\x6a\xcb\x6e\x1a\x4c\x7f\x74\xc7\x1f\x09\xd1\xd0\x6b"
+ "\x17\xde\xea\xe8\x0b\xe6\x6a\xee\x2f\xe3\x5b\x9c\x59\x5d\x00\x57"
+ "\xbf\x24\x25\xba\x22\x34\xb9\xc5\x3c\xc4\x57\x26\xd0\x6d\x89\xee"
+ "\x67\x79\x3c\x70\xf9\xc3\xb4\x30\xf0\x2e\xca\xfa\x74\x00\xd1\x00"
+ "\x6d\x03\x97\xd5\x08\x3f\x0b\x8e\xb8\x1d\xa3\x91\x7f\xa9\x3a\xf0"
+ "\x37\x57\x46\x87\x82\xa3\xb5\x8f\x51\xaa\xc7\x7b\xfe\x86\x26\xb9"
+ "\xfa\xe6\x1e\xee\x92\x9d\x3a\xed\x5b\x5e\x3f\xe5\xca\x5e\x13\x01"
+ "\xdd\x4c\x8d\x85\xf0\x60\x61\xb7\x60\x24\x83\x9f\xbe\x72\x21\x81"
+ "\x55\x7e\x7e\x6d\xf3\x28\xc8\x77\x5a\xae\x5a\x32\x86\xd5\x61\xad",
+ .expected_a_public =
+ "\x1f\xff\xd6\xc4\x59\xf3\x4a\x9e\x81\x74\x4d\x27\xa7\xc6\x6b\x35"
+ "\xd8\xf5\xb3\x24\x97\x82\xe7\x2e\xf3\x21\x91\x23\x2f\x3d\x57\x7f"
+ "\x15\x8c\x84\x71\xe7\x25\x35\xe8\x07\x14\x06\x4c\x83\xdc\x55\x4a"
+ "\xf8\x45\xc5\xe9\xfa\x6e\xae\x6e\xcf\x4d\x11\x91\x26\x16\x6f\x86"
+ "\x89\x78\xaa\xb4\x25\x54\xb2\x74\x07\xe5\x26\x26\x0c\xad\xa4\x57"
+ "\x59\x61\x66\x71\x43\x22\xff\x49\x51\xa4\x76\x0e\x55\x7b\x60\x45"
+ "\x4f\xaf\xbd\x9c\xec\x64\x3f\x80\x0b\x0c\x31\x41\xf0\xfe\x2c\xb7"
+ "\x0a\xbe\xa5\x71\x08\x0d\x8d\x1e\x8a\x77\x9a\xd2\x90\x31\x96\xd0"
+ "\x3b\x31\xdc\xc6\x18\x59\x43\xa1\x19\x5a\x84\x68\x29\xad\x5e\x58"
+ "\xa2\x50\x3e\x83\xf5\x7a\xbd\x88\x17\x60\x89\x98\x9c\x19\x89\x27"
+ "\x89\xfc\x33\x87\x42\xd5\xde\x19\x14\xf2\x95\x82\x10\x87\xad\x82"
+ "\xdd\x6b\x51\x2d\x8d\x0e\x81\x4b\xde\xb3\x35\x6c\x0f\x4b\x56\x45"
+ "\x48\x87\xe9\x5a\xf9\x70\x10\x30\x8e\xa1\xbb\xa4\x70\xbf\xa0\xab"
+ "\x10\x31\x3c\x2c\xdc\xc4\xed\xe3\x51\xdc\xee\xd2\xa5\x5c\x4e\x6e"
+ "\xf6\xed\x60\x5a\xeb\xf3\x02\x19\x2a\x95\xe9\x46\xff\x37\x1b\xf0"
+ "\x1d\x10\x4a\x8f\x4f\x3a\x6e\xf5\xfc\x02\x6d\x09\x7d\xea\x69\x7b"
+ "\x13\xb0\xb6\x80\x5c\x15\x20\xa8\x4d\x15\x56\x11\x72\x49\xdb\x48"
+ "\x54\x40\x66\xd5\xcd\x17\x3a\x26\x95\xf6\xd7\xf2\x59\xa3\xda\xbb"
+ "\x26\xd0\xe5\x46\xbf\xee\x0e\x7d\xf1\xe0\x11\x02\x4d\xd3\xdc\xe2"
+ "\x3f\xc2\x51\x7e\xc7\x90\x33\x3c\x1c\xa0\x4c\x69\xcc\x1e\xc7\xac"
+ "\x17\xe0\xe5\xf4\x8c\x05\x64\x34\xfe\x84\x70\xd7\x6b\xed\xab\xf5"
+ "\x88\x9d\x3e\x4c\x5a\x9e\xd4\x74\xfd\xdd\x91\xd5\xd4\xcb\xbf\xf8"
+ "\xb7\x56\xb5\xe9\x22\xa6\x6d\x7a\x44\x05\x41\xbf\xdb\x61\x28\xc6"
+ "\x99\x49\x87\x3d\x28\x77\xf8\x83\x23\x7e\xa9\xa7\xee\x20\xdb\x6d"
+ "\x21\x50\xb7\xc9\x52\x57\x53\xa3\xcf\xdf\xd0\xf9\xb9\x62\x96\x89"
+ "\xf5\x5c\xa9\x8a\x11\x95\x01\x25\xc9\x81\x15\x76\xae\xf0\xc7\xc5"
+ "\x50\xae\x6f\xb5\xd2\x8a\x8e\x9a\xd4\x30\x55\xc6\xe9\x2c\x81\x6e"
+ "\x95\xf6\x45\x89\x55\x28\x34\x7b\xe5\x72\x9a\x2a\xe2\x98\x09\x35"
+ "\xe0\xe9\x75\x94\xe9\x34\x95\xb9\x13\x6e\xd5\xa1\x62\x5a\x1c\x94"
+ "\x28\xed\x84\x46\x76\x6d\x10\x37\x71\xa3\x31\x46\x64\xe4\x59\x44"
+ "\x17\x70\x1c\x23\xc9\x7e\xf6\xab\x8a\x24\xae\x25\xe2\xb2\x5f\x33"
+ "\xe4\xd7\xd3\x34\x2a\x49\x22\x16\x15\x9b\x90\x40\xda\x99\xd5\xaf",
+ .expected_ss =
+ "\xe2\xce\x0e\x4b\x64\xf3\x84\x62\x38\xfd\xe3\x6f\x69\x40\x22\xb0"
+ "\x73\x27\x03\x12\x82\xa4\x6e\x03\x57\xec\x3d\xa0\xc1\x4f\x4b\x09"
+ "\xa1\xd4\xe0\x1a\x5d\x91\x2e\x08\xad\x57\xfa\xcc\x55\x90\x5f\xa0"
+ "\x52\x27\x62\x8d\xe5\x2d\xa1\x5f\xf0\x30\x43\x77\x4e\x3f\x02\x58"
+ "\xcb\xa0\x51\xae\x1d\x24\xf9\x0a\xd1\x36\x0b\x95\x0f\x07\xd9\xf7"
+ "\xe2\x36\x14\x2f\xf0\x11\xc2\xc9\xaf\x66\x4e\x0d\xb4\x60\x01\x4e"
+ "\xa8\x49\xc6\xec\x5f\xb2\xbc\x05\x48\x91\x4e\xe1\xc3\x99\x9f\xeb"
+ "\x4a\xc1\xde\x05\x9a\x65\x39\x7d\x2f\x89\x85\xb2\xcf\xec\x25\x27"
+ "\x5f\x1c\x11\x63\xcf\x7b\x86\x98\x39\xae\xc2\x16\x8f\x79\xd1\x20"
+ "\xd0\xb4\xa0\xba\x44\xd8\xf5\x3a\x0a\x08\x4c\xd1\xb9\xdd\x0a\x5b"
+ "\x9e\x62\xf3\x52\x0c\x84\x12\x43\x9b\xd7\xdf\x86\x71\x03\xdd\x04"
+ "\x98\x55\x0c\x7b\xe2\xe8\x03\x17\x25\x84\xd9\xbd\xe1\xce\x64\xbe"
+ "\xca\x55\xd4\x5b\xef\x61\x5b\x68\x4b\x80\x37\x40\xae\x28\x87\x81"
+ "\x55\x34\x96\x50\x21\x47\x49\xc0\xda\x26\x46\xb8\xe8\xcc\x5a\x27"
+ "\x9c\x9d\x0a\x3d\xcc\x4c\x63\x27\x81\x82\x2e\xf4\xa8\x91\x37\x3e"
+ "\xa7\x34\x6a\x0f\x60\x44\xdd\x2e\xdc\xf9\x19\xf2\x2e\x81\x05\x51"
+ "\x16\xbc\xc0\x85\xa5\xd5\x08\x09\x1f\xcd\xed\xa4\xc5\xdb\x16\x43"
+ "\xb5\x7a\x71\x66\x19\x2e\xef\x13\xbc\x40\x39\x0a\x00\x45\x7e\x61"
+ "\xe9\x68\x60\x83\x00\x70\xd1\x71\xd3\xa2\x61\x3e\x00\x46\x93\x0d"
+ "\xbf\xe6\xa2\x07\xe6\x40\x1a\xf4\x57\xc6\x67\x39\xd8\xd7\x6b\xc5"
+ "\xa5\xd8\x38\x78\x12\xb4\x97\x12\xbe\x97\x13\xef\xe4\x74\x0c\xe0"
+ "\x75\x89\x64\xf4\xe8\x85\xda\x84\x7b\x1d\xfe\xdd\x21\xba\xda\x01"
+ "\x52\xdc\x59\xe5\x47\x50\x7e\x15\x20\xd0\x43\x37\x6e\x48\x39\x00"
+ "\xee\xd9\x54\x6d\x00\x65\xc9\x4b\x85\xa2\x8a\x40\x55\xd0\x63\x0c"
+ "\xb5\x7a\x0d\x37\x67\x27\x73\x18\x7f\x5a\xf5\x0e\x22\xb9\xb0\x3f"
+ "\xda\xf1\xec\x7c\x24\x01\x49\xa9\x09\x0e\x0f\xc4\xa9\xef\xc8\x2b"
+ "\x13\xd1\x0a\x6f\xf8\x92\x4b\x1d\xdd\x6c\x9c\x35\xde\x75\x46\x32"
+ "\xe6\xfb\xda\x58\xba\x81\x08\xca\xa9\xb6\x69\x71\x96\x2a\x1f\x2e"
+ "\x25\xe0\x37\xfe\xee\x4d\x27\xaa\x04\xda\x95\xbb\x93\xcf\x8f\xa2"
+ "\x1d\x67\x35\xe3\x51\x8f\x87\x3b\xa9\x62\x05\xee\x44\xb7\x2e\xd0"
+ "\x07\x63\x32\xf5\xcd\x64\x18\x20\xcf\x22\x42\x28\x22\x1a\xa8\xbb"
+ "\x74\x8a\x6f\x2a\xea\x8a\x48\x0a\xad\xd7\xed\xba\xa3\x89\x37\x01",
+ .secret_size = 528,
+ .b_public_size = 512,
+ .expected_a_public_size = 512,
+ .expected_ss_size = 512,
+ },
+ {
+ .secret =
+#ifdef __LITTLE_ENDIAN
+ "\x01\x00" /* type */
+ "\x10\x00" /* len */
+ "\x00\x00\x00\x00" /* key_size */
+ "\x00\x00\x00\x00" /* p_size */
+ "\x00\x00\x00\x00", /* g_size */
+#else
+ "\x00\x01" /* type */
+ "\x00\x10" /* len */
+ "\x00\x00\x00\x00" /* key_size */
+ "\x00\x00\x00\x00" /* p_size */
+ "\x00\x00\x00\x00", /* g_size */
+#endif
+ .b_secret =
+#ifdef __LITTLE_ENDIAN
+ "\x01\x00" /* type */
+ "\x10\x02" /* len */
+ "\x00\x02\x00\x00" /* key_size */
+ "\x00\x00\x00\x00" /* p_size */
+ "\x00\x00\x00\x00" /* g_size */
+#else
+ "\x00\x01" /* type */
+ "\x02\x10" /* len */
+ "\x00\x00\x02\x00" /* key_size */
+ "\x00\x00\x00\x00" /* p_size */
+ "\x00\x00\x00\x00" /* g_size */
+#endif
+ /* xa */
+ "\x1a\x48\xf3\x6c\x61\x03\x42\x43\xd7\x42\x3b\xfa\xdb\x55\x6f\xa2"
+ "\xe1\x79\x52\x0b\x47\xc5\x03\x60\x2f\x26\xb9\x1a\x14\x15\x1a\xd9"
+ "\xe0\xbb\xa7\x82\x63\x41\xec\x26\x55\x00\xab\xe5\x21\x9d\x31\x14"
+ "\x0e\xe2\xc2\xb2\xb8\x37\xe6\xc3\x5a\xab\xae\x25\xdb\x71\x1e\xed"
+ "\xe8\x75\x9a\x04\xa7\x92\x2a\x99\x7e\xc0\x5b\x64\x75\x7f\xe5\xb5"
+ "\xdb\x6c\x95\x4f\xe9\xdc\x39\x76\x79\xb0\xf7\x00\x30\x8e\x86\xe7"
+ "\x36\xd1\xd2\x0c\x68\x7b\x94\xe9\x91\x85\x08\x86\xbc\x64\x87\xd2"
+ "\xf5\x5b\xaf\x03\xf6\x5f\x28\x25\xf1\xa3\x20\x5c\x1b\xb5\x26\x45"
+ "\x9a\x47\xab\xd6\xad\x49\xab\x92\x8e\x62\x6f\x48\x31\xea\xf6\x76"
+ "\xff\xa2\xb6\x28\x78\xef\x59\xc3\x71\x5d\xa8\xd9\x70\x89\xcc\xe2"
+ "\x63\x58\x5e\x3a\xa2\xa2\x88\xbf\x77\x20\x84\x33\x65\x64\x4e\x73"
+ "\xe5\x08\xd5\x89\x23\xd6\x07\xac\x29\x65\x2e\x02\xa8\x35\x96\x48"
+ "\xe7\x5d\x43\x6a\x42\xcc\xda\x98\xc4\x75\x90\x2e\xf6\xc4\xbf\xd4"
+ "\xbc\x31\x14\x0d\x54\x30\x11\xb2\xc9\xcf\xbb\xba\xbc\xc6\xf2\xcf"
+ "\xfe\x4a\x9d\xf3\xec\x78\x5d\x5d\xb4\x99\xd0\x67\x0f\x5a\x21\x1c"
+ "\x7b\x95\x2b\xcf\x49\x44\x94\x05\x1a\x21\x81\x25\x7f\xe3\x8a\x2a"
+ "\xdd\x88\xac\x44\x94\x23\x20\x3b\x75\xf6\x2a\x8a\x45\xf8\xb5\x1f"
+ "\xb9\x8b\xeb\xab\x9b\x38\x23\x26\xf1\x0f\x34\x47\x4f\x7f\xe1\x9e"
+ "\x84\x84\x78\xe5\xe3\x49\xeb\xcc\x2f\x02\x85\xa4\x18\x91\xde\x1a"
+ "\x60\x54\x33\x81\xd5\xae\xdb\x23\x9c\x4d\xa4\xdb\x22\x5b\xdf\xf4"
+ "\x8e\x05\x2b\x60\xba\xe8\x75\xfc\x34\x99\xcf\x35\xe1\x06\xba\xdc"
+ "\x79\x2a\x5e\xec\x1c\xbe\x79\x33\x63\x1c\xe7\x5f\x1e\x30\xd6\x1b"
+ "\xdb\x11\xb8\xea\x63\xff\xfe\x1a\x3c\x24\xf4\x78\x9c\xcc\x5d\x9a"
+ "\xc9\x2d\xc4\x9a\xd4\xa7\x65\x84\x98\xdb\x66\x76\xf0\x34\x31\x9f"
+ "\xce\xb5\xfb\x28\x07\xde\x1e\x0d\x9b\x01\x64\xeb\x2a\x37\x2f\x20"
+ "\xa5\x95\x72\x2b\x54\x51\x59\x91\xea\x50\x54\x0f\x2e\xb0\x1d\xf6"
+ "\xb9\x46\x43\xf9\xd0\x13\x21\x20\x47\x61\x1a\x1c\x30\xc6\x9e\x75"
+ "\x22\xe4\xf2\xb1\xab\x01\xdc\x5b\x3c\x1e\xa2\x6d\xc0\xb9\x9a\x2a"
+ "\x84\x61\xea\x85\x63\xa0\x77\xd0\xeb\x20\x68\xd5\x95\x6a\x1b\x8f"
+ "\x1f\x9a\xba\x44\x49\x8c\x77\xa6\xd9\xa0\x14\xf8\x7d\x9b\x4e\xfa"
+ "\xdc\x4f\x1c\x4d\x60\x50\x26\x7f\xd6\xc1\x91\x2b\xa6\x37\x5d\x94"
+ "\x69\xb2\x47\x59\xd6\xc3\x59\xbb\xd6\x9b\x71\x52\x85\x7a\xcb\x2d",
+ .b_public =
+ "\x1f\xff\xd6\xc4\x59\xf3\x4a\x9e\x81\x74\x4d\x27\xa7\xc6\x6b\x35"
+ "\xd8\xf5\xb3\x24\x97\x82\xe7\x2e\xf3\x21\x91\x23\x2f\x3d\x57\x7f"
+ "\x15\x8c\x84\x71\xe7\x25\x35\xe8\x07\x14\x06\x4c\x83\xdc\x55\x4a"
+ "\xf8\x45\xc5\xe9\xfa\x6e\xae\x6e\xcf\x4d\x11\x91\x26\x16\x6f\x86"
+ "\x89\x78\xaa\xb4\x25\x54\xb2\x74\x07\xe5\x26\x26\x0c\xad\xa4\x57"
+ "\x59\x61\x66\x71\x43\x22\xff\x49\x51\xa4\x76\x0e\x55\x7b\x60\x45"
+ "\x4f\xaf\xbd\x9c\xec\x64\x3f\x80\x0b\x0c\x31\x41\xf0\xfe\x2c\xb7"
+ "\x0a\xbe\xa5\x71\x08\x0d\x8d\x1e\x8a\x77\x9a\xd2\x90\x31\x96\xd0"
+ "\x3b\x31\xdc\xc6\x18\x59\x43\xa1\x19\x5a\x84\x68\x29\xad\x5e\x58"
+ "\xa2\x50\x3e\x83\xf5\x7a\xbd\x88\x17\x60\x89\x98\x9c\x19\x89\x27"
+ "\x89\xfc\x33\x87\x42\xd5\xde\x19\x14\xf2\x95\x82\x10\x87\xad\x82"
+ "\xdd\x6b\x51\x2d\x8d\x0e\x81\x4b\xde\xb3\x35\x6c\x0f\x4b\x56\x45"
+ "\x48\x87\xe9\x5a\xf9\x70\x10\x30\x8e\xa1\xbb\xa4\x70\xbf\xa0\xab"
+ "\x10\x31\x3c\x2c\xdc\xc4\xed\xe3\x51\xdc\xee\xd2\xa5\x5c\x4e\x6e"
+ "\xf6\xed\x60\x5a\xeb\xf3\x02\x19\x2a\x95\xe9\x46\xff\x37\x1b\xf0"
+ "\x1d\x10\x4a\x8f\x4f\x3a\x6e\xf5\xfc\x02\x6d\x09\x7d\xea\x69\x7b"
+ "\x13\xb0\xb6\x80\x5c\x15\x20\xa8\x4d\x15\x56\x11\x72\x49\xdb\x48"
+ "\x54\x40\x66\xd5\xcd\x17\x3a\x26\x95\xf6\xd7\xf2\x59\xa3\xda\xbb"
+ "\x26\xd0\xe5\x46\xbf\xee\x0e\x7d\xf1\xe0\x11\x02\x4d\xd3\xdc\xe2"
+ "\x3f\xc2\x51\x7e\xc7\x90\x33\x3c\x1c\xa0\x4c\x69\xcc\x1e\xc7\xac"
+ "\x17\xe0\xe5\xf4\x8c\x05\x64\x34\xfe\x84\x70\xd7\x6b\xed\xab\xf5"
+ "\x88\x9d\x3e\x4c\x5a\x9e\xd4\x74\xfd\xdd\x91\xd5\xd4\xcb\xbf\xf8"
+ "\xb7\x56\xb5\xe9\x22\xa6\x6d\x7a\x44\x05\x41\xbf\xdb\x61\x28\xc6"
+ "\x99\x49\x87\x3d\x28\x77\xf8\x83\x23\x7e\xa9\xa7\xee\x20\xdb\x6d"
+ "\x21\x50\xb7\xc9\x52\x57\x53\xa3\xcf\xdf\xd0\xf9\xb9\x62\x96\x89"
+ "\xf5\x5c\xa9\x8a\x11\x95\x01\x25\xc9\x81\x15\x76\xae\xf0\xc7\xc5"
+ "\x50\xae\x6f\xb5\xd2\x8a\x8e\x9a\xd4\x30\x55\xc6\xe9\x2c\x81\x6e"
+ "\x95\xf6\x45\x89\x55\x28\x34\x7b\xe5\x72\x9a\x2a\xe2\x98\x09\x35"
+ "\xe0\xe9\x75\x94\xe9\x34\x95\xb9\x13\x6e\xd5\xa1\x62\x5a\x1c\x94"
+ "\x28\xed\x84\x46\x76\x6d\x10\x37\x71\xa3\x31\x46\x64\xe4\x59\x44"
+ "\x17\x70\x1c\x23\xc9\x7e\xf6\xab\x8a\x24\xae\x25\xe2\xb2\x5f\x33"
+ "\xe4\xd7\xd3\x34\x2a\x49\x22\x16\x15\x9b\x90\x40\xda\x99\xd5\xaf",
+ .secret_size = 16,
+ .b_secret_size = 528,
+ .b_public_size = 512,
+ .expected_a_public_size = 512,
+ .expected_ss_size = 512,
+ .genkey = true,
+ },
+};
+
+static const struct kpp_testvec ffdhe6144_dh_tv_template[] __maybe_unused = {
+ {
+ .secret =
+#ifdef __LITTLE_ENDIAN
+ "\x01\x00" /* type */
+ "\x10\x03" /* len */
+ "\x00\x03\x00\x00" /* key_size */
+ "\x00\x00\x00\x00" /* p_size */
+ "\x00\x00\x00\x00" /* g_size */
+#else
+ "\x00\x01" /* type */
+ "\x03\x10" /* len */
+ "\x00\x00\x03\x00" /* key_size */
+ "\x00\x00\x00\x00" /* p_size */
+ "\x00\x00\x00\x00" /* g_size */
+#endif
+ /* xa */
+ "\x63\x3e\x6f\xe0\xfe\x9f\x4a\x01\x62\x77\xce\xf1\xc7\xcc\x49\x4d"
+ "\x92\x53\x56\xe3\x39\x15\x81\xb2\xcd\xdc\xaf\x5e\xbf\x31\x1f\x69"
+ "\xce\x41\x35\x24\xaa\x46\x53\xb5\xb7\x3f\x2b\xad\x95\x14\xfb\xe4"
+ "\x9a\x61\xcd\x0f\x1f\x02\xee\xa4\x79\x2c\x9d\x1a\x7c\x62\x82\x39"
+ "\xdd\x43\xcc\x58\x9f\x62\x47\x56\x1d\x0f\xc2\x67\xbc\x24\xd0\xf9"
+ "\x0a\x50\x1b\x10\xe7\xbb\xd1\xc2\x01\xbb\xc4\x4c\xda\x12\x60\x0e"
+ "\x95\x2b\xde\x09\xd6\x67\xe1\xbc\x4c\xb9\x67\xdf\xd0\x1f\x97\xb4"
+ "\xde\xcb\x6b\x78\x83\x51\x74\x33\x01\x7f\xf6\x0a\x95\x69\x93\x00"
+ "\x2a\xc3\x75\x8e\xef\xbe\x53\x11\x6d\xc4\xd0\x9f\x6d\x63\x48\xc1"
+ "\x91\x1f\x7d\x88\xa7\x90\x78\xd1\x7e\x52\x42\x10\x01\xb4\x27\x95"
+ "\x91\x43\xcc\x82\x91\x86\x62\xa0\x9d\xef\x65\x6e\x67\xcf\x19\x11"
+ "\x35\x37\x5e\x94\x97\x83\xa6\x83\x1c\x7e\x8a\x3e\x32\xb0\xce\xff"
+ "\x20\xdc\x7b\x6e\x18\xd9\x6b\x27\x31\xfc\xc3\xef\x47\x8d\xbe\x34"
+ "\x2b\xc7\x60\x74\x3c\x93\xb3\x8e\x54\x77\x4e\x73\xe6\x40\x72\x35"
+ "\xb0\xf0\x06\x53\x43\xbe\xd0\xc3\x87\xcc\x38\x96\xa9\x10\xa0\xd6"
+ "\x17\xed\xa5\x6a\xf4\xf6\xaa\x77\x40\xed\x7d\x2e\x58\x0f\x5b\x04"
+ "\x5a\x41\x12\x95\x22\xcb\xa3\xce\x8b\x6d\x6d\x89\xec\x7c\x1d\x25"
+ "\x27\x52\x50\xa0\x5b\x93\x8c\x5d\x3f\x56\xb9\xa6\x5e\xe5\xf7\x9b"
+ "\xc7\x9a\x4a\x2e\x79\xb5\xca\x29\x58\x52\xa0\x63\xe4\x9d\xeb\x4c"
+ "\x4c\xa8\x37\x0b\xe9\xa0\x18\xf1\x86\xf6\x4d\x32\xfb\x9e\x4f\xb3"
+ "\x7b\x5d\x58\x78\x70\xbd\x56\xac\x99\x75\x25\x71\x66\x76\x4e\x5e"
+ "\x67\x4f\xb1\x17\xa7\x8b\x55\x12\x87\x01\x4e\xd1\x66\xef\xd0\x70"
+ "\xaf\x14\x34\xee\x2a\x76\x49\x25\xa6\x2e\x43\x37\x75\x7d\x1a\xad"
+ "\x08\xd5\x01\x85\x9c\xe1\x20\xd8\x38\x5c\x57\xa5\xed\x9d\x46\x3a"
+ "\xb7\x46\x60\x29\x8b\xc4\x21\x50\x0a\x30\x9c\x57\x42\xe4\x35\xf8"
+ "\x12\x5c\x4f\xa2\x20\xc2\xc9\x43\xe3\x6d\x20\xbc\xdf\xb8\x37\x33"
+ "\x45\x43\x06\x4e\x08\x6f\x8a\xcd\x61\xc3\x1b\x05\x28\x82\xbe\xf0"
+ "\x48\x33\xe5\x93\xc9\x1a\x61\x16\x67\x03\x9d\x47\x9d\x74\xeb\xae"
+ "\x13\xf2\xb4\x1b\x09\x11\xf5\x15\xcb\x28\xfd\x50\xe0\xbc\x58\x36"
+ "\x38\x91\x2c\x07\x27\x1f\x49\x68\xf4\xce\xad\xf7\xba\xec\x5d\x3d"
+ "\xfd\x27\xe2\xcf\xf4\x56\xfe\x08\xa6\x11\x61\xcb\x6c\x9f\xf9\x3c"
+ "\x57\x0b\x8b\xaa\x00\x16\x18\xba\x1f\xe8\x4f\x01\xe2\x79\x2a\x0b"
+ "\xc1\xbd\x52\xef\xe6\xf7\x5a\x66\xfe\x07\x3b\x50\x6b\xbb\xcb\x39"
+ "\x3c\x94\xf6\x21\x0d\x68\x69\xa4\xed\x2e\xb5\x85\x03\x11\x38\x79"
+ "\xec\xb5\x22\x23\xdf\x9e\xad\xb4\xbe\xd7\xc7\xdf\xea\x30\x23\x8a"
+ "\xb7\x21\x0a\x9d\xbd\x99\x13\x7d\x5f\x7e\xaf\x28\x54\x3f\xca\x5e"
+ "\xf4\xfc\x05\x0d\x65\x67\xd8\xf6\x8e\x90\x9d\x0d\xcf\x62\x82\xd6"
+ "\x9f\x02\xf8\xca\xfa\x42\x24\x7f\x4d\xb7\xfc\x92\xa6\x4a\x51\xc4"
+ "\xd8\xae\x19\x87\xc6\xa3\x83\xbe\x7b\x6d\xc3\xf5\xb8\xad\x4a\x05"
+ "\x78\x84\x3a\x15\x2e\x40\xbe\x79\xa9\xc0\x12\xa1\x48\x39\xc3\xdb"
+ "\x47\x4f\x7d\xea\x6d\xc7\xfa\x2c\x4e\xe9\xa5\x85\x81\xea\x6c\xcd"
+ "\x8a\xe5\x74\x17\x76\x31\x31\x75\x96\x83\xca\x81\xbb\x5c\xa9\x79"
+ "\x2c\xbd\x09\xfe\xe4\x86\x0d\x8c\x76\x9c\xbc\xe8\x93\xe4\xd0\xe4"
+ "\x0f\xf8\xff\x24\x7e\x66\x61\x69\xfb\xe4\x46\x08\x94\x99\xa5\x53"
+ "\xd7\xe4\x29\x72\x86\x86\xe8\x1d\x37\xfa\xcb\xd0\x8d\x51\xd0\xbf"
+ "\x81\xcf\x55\xb9\xc5\x78\x8c\x74\xa0\x16\x3a\xd2\x19\x94\x29\x6a"
+ "\x5e\xec\xd3\x20\xa0\xb2\xfd\xce\xd4\x14\xa3\x39\x10\xa9\xf4\x4e"
+ "\xba\x21\x09\x5c\xe6\x61\x43\x51\xae\xc4\x71\xd7\x21\xef\x98\x39",
+ .b_public =
+ "\x30\x31\xbe\x43\xd0\x14\x22\x6b\x4b\x8c\x9a\xca\xc6\xdd\xe5\x99"
+ "\xce\xb8\x30\x23\xb6\xa8\x8c\x4d\xfa\xef\xad\xa6\x6a\x21\x50\xa6"
+ "\x45\x2d\x19\x2a\x29\x81\xc5\xac\xb4\xa8\x5f\x6d\x5b\xc8\x5f\x12"
+ "\x35\x21\xfb\x37\xaa\x0c\x79\xeb\xd4\x83\x01\xda\xa3\xf3\x51\x6e"
+ "\x17\xf9\xef\x3f\xbd\x2f\xd2\x43\x82\x12\x48\xeb\x61\x4c\x8e\xf2"
+ "\x6c\x76\xf9\x6d\x42\x2a\xcb\x10\x13\x3b\xf6\x9b\xcd\x46\x1e\xa2"
+ "\xa7\x2c\x08\x56\xd2\x42\xf5\x03\xf0\x3e\xef\xa2\xa2\xf2\x4c\xf2"
+ "\xdb\x4f\xeb\x40\x15\x53\x27\xf7\xd4\x8e\x58\x23\xf5\x2c\x88\x04"
+ "\x1e\xb1\xb6\xe3\xd6\x9c\x49\x08\xa1\x4b\xb8\x33\xe4\x75\x85\xa1"
+ "\x86\x97\xce\x1d\xe9\x9f\xe2\xd8\xf2\x7e\xad\xdc\x8a\x4d\xbd\x06"
+ "\x52\x00\x9a\x2c\x69\xdd\x02\x0c\x69\x5a\xf9\x1d\xfd\xdc\xfb\x82"
+ "\xb2\xe5\xf3\x24\xba\xd1\x09\x76\x90\xb5\x7a\x92\xa6\x6b\x97\xc0"
+ "\xce\x13\x9b\x4b\xbc\x30\x91\xb2\x13\x8b\x57\x6c\x8b\x66\x6e\x58"
+ "\x3e\x91\x50\xc7\x6c\xe1\x18\xec\xbf\x69\xcd\xcb\xa0\xbc\x0d\x05"
+ "\xc4\xf8\x45\x92\xe0\x05\xd3\x08\xb3\x30\x19\xc8\x80\xf8\x17\x9f"
+ "\x1e\x6a\x49\x8e\x43\xef\x7a\x49\xa5\x93\xd9\xed\xd1\x07\x03\xe4"
+ "\xa3\x55\xeb\x1e\x2f\x69\xd7\x40\x8f\x6e\x1c\xb6\x94\xfb\xba\x4e"
+ "\x46\xd0\x38\x71\x00\x88\x93\x6a\x55\xfc\x16\x95\x1f\xb1\xf6\x2f"
+ "\x26\x45\x50\x54\x30\x62\x62\xe8\x80\xe5\x24\x0b\xe4\x15\x6b\x32"
+ "\x16\xc2\x30\x9b\x56\xb4\xc9\x5e\x50\xb4\x27\x82\x86\x01\xda\x68"
+ "\x44\x4b\x15\x81\x31\x13\x52\xd8\x08\xbc\xae\xf3\xa5\x94\x1c\x81"
+ "\xe8\x42\xd6\x42\xd6\xff\x99\x58\x0f\x61\x3e\x82\x9e\x2d\x13\x03"
+ "\x54\x02\x74\xf4\x6b\x43\x43\xce\x54\x44\x36\x3f\x55\xfa\xb2\x56"
+ "\xdc\xac\xb5\x65\x89\xbe\x36\xd2\x58\x65\x79\x4c\xf3\xe2\x01\xf1"
+ "\x69\x96\x29\x20\x5d\xee\xf5\x8a\x8b\x9f\x72\xf7\x27\x02\xde\x3b"
+ "\xc7\x52\x19\xdc\x8e\x22\x36\x09\x14\x59\x07\xbb\x1e\x49\x69\x4f"
+ "\x00\x7b\x9a\x5d\x23\xe9\xbe\x0d\x52\x90\xa3\x0d\xde\xe7\x80\x57"
+ "\x53\x69\x39\xe6\xf8\x33\xeb\x92\x0d\x9e\x04\x8b\x16\x16\x16\x1c"
+ "\xa9\xe6\xe3\x0e\x0a\xc6\xf6\x61\xd1\x44\x2b\x3e\x5e\x02\xfe\xaa"
+ "\xe3\xf3\x8f\xf9\xc8\x20\x37\xad\xbc\x95\xb8\xc5\xe7\x95\xda\xfb"
+ "\x80\x5b\xf6\x40\x28\xae\xc1\x4c\x09\xde\xff\x1e\xbf\x51\xd2\xfe"
+ "\x08\xdc\xb0\x48\x21\xf5\x4c\x43\xdc\x7b\x69\x83\xc8\x69\x5c\xc4"
+ "\xa9\x98\x76\x4b\xc4\x4a\xac\x1d\xa5\x52\xe3\x35\x43\xdd\x30\xd4"
+ "\xa0\x51\x9c\xc2\x62\x4c\x7e\xa5\xfb\xd3\x2c\x8a\x09\x7f\x53\xa3"
+ "\xcd\xca\x58\x1b\x4c\xaf\xba\x21\x8b\x88\x1d\xc0\xe9\x0a\x17\x30"
+ "\x33\xd6\xa2\xa5\x49\x50\x61\x3b\xff\x37\x71\x66\xef\x61\xbc\xb2"
+ "\x53\x82\xe5\x70\xef\x32\xff\x9d\x97\xe0\x82\xe0\xbb\x49\xc2\x29"
+ "\x58\x89\xdd\xe9\x62\x52\xfb\xba\x22\xa6\xd9\x16\xfa\x55\xb3\x06"
+ "\xed\x6d\x70\x6e\xdc\x47\x7c\x67\x1a\xcc\x27\x98\xd4\xd7\xe6\xf0"
+ "\xf8\x9f\x51\x3e\xf0\xee\xad\xb6\x78\x69\x71\xb5\xcb\x09\xa3\xa6"
+ "\x3f\x29\x24\x46\xe0\x65\xbc\x9f\x6c\xe9\xf9\x49\x49\x96\x75\xe5"
+ "\xe1\xff\x82\x70\xf4\x7e\xff\x8f\xec\x47\x98\x6d\x5b\x88\x60\xee"
+ "\x43\xb1\xe2\x14\xc1\x49\x95\x74\x46\xd3\x3f\x73\xb2\xe9\x88\xe0"
+ "\xd3\xb1\xc4\x2c\xef\xee\xdd\x6c\xc5\xa1\x29\xef\x86\xd2\x36\x8a"
+ "\x2f\x7c\x9d\x28\x0a\x6d\xc9\x5a\xdb\xd4\x04\x06\x36\x96\x09\x03"
+ "\x71\x5d\x38\x67\xa2\x08\x2a\x04\xe7\xd6\x51\x5a\x19\x9d\xe7\xf1"
+ "\x5d\x6f\xe2\xff\x48\x37\xb7\x8b\xb1\x14\xb4\x96\xcd\xf0\xa7\xbd"
+ "\xef\x20\xff\x0a\x8d\x08\xb7\x15\x98\x5a\x13\xd2\xda\x2a\x27\x75",
+ .expected_a_public =
+ "\x45\x96\x5a\xb7\x78\x5c\xa4\x4d\x39\xb2\x5f\xc8\xc2\xaa\x1a\xf4"
+ "\xa6\x68\xf6\x6f\x7e\xa8\x4a\x5b\x0e\xba\x0a\x99\x85\xf9\x63\xd4"
+ "\x58\x21\x6d\xa8\x3c\xf4\x05\x10\xb0\x0d\x6f\x1c\xa0\x17\x85\xae"
+ "\x68\xbf\xcc\x00\xc8\x86\x1b\x24\x31\xc9\x49\x23\x91\xe0\x71\x29"
+ "\x06\x39\x39\x93\x49\x9c\x75\x18\x1a\x8b\x61\x73\x1c\x7f\x37\xd5"
+ "\xf1\xab\x20\x5e\x62\x25\xeb\x58\xd5\xfa\xc9\x7f\xad\x57\xd5\xcc"
+ "\x0d\xc1\x7a\x2b\x33\x2a\x76\x84\x33\x26\x97\xcf\x47\x9d\x72\x2a"
+ "\xc9\x39\xde\xa8\x42\x27\x2d\xdc\xee\x00\x60\xd2\x4f\x13\xe0\xde"
+ "\xd5\xc7\xf6\x7d\x8b\x2a\x43\x49\x40\x99\xc2\x61\x84\x8e\x57\x09"
+ "\x7c\xcc\x19\x46\xbd\x4c\xd2\x7c\x7d\x02\x4d\x88\xdf\x58\x24\x80"
+ "\xeb\x19\x3b\x2a\x13\x2b\x19\x85\x3c\xd8\x31\x03\x00\xa4\xd4\x57"
+ "\x23\x2c\x24\x37\xb3\x62\xea\x35\x29\xd0\x2c\xac\xfd\xbd\xdf\x3d"
+ "\xa6\xce\xfa\x0d\x5b\xb6\x15\x8b\xe3\x58\xe9\xad\x99\x87\x29\x51"
+ "\x8d\x97\xd7\xa9\x55\xf0\x72\x6e\x4e\x58\xcb\x2b\x4d\xbd\xd0\x48"
+ "\x7d\x14\x86\xdb\x3f\xa2\x5f\x6e\x35\x4a\xe1\x70\xb1\x53\x72\xb7"
+ "\xbc\xe9\x3d\x1b\x33\xc0\x54\x6f\x43\x55\x76\x85\x7f\x9b\xa5\xb3"
+ "\xc1\x1d\xd3\xfe\xe2\xd5\x96\x3d\xdd\x92\x04\xb1\xad\x75\xdb\x13"
+ "\x4e\x49\xfc\x35\x34\xc5\xda\x13\x98\xb8\x12\xbe\xda\x90\x55\x7c"
+ "\x11\x6c\xbe\x2b\x8c\x51\x29\x23\xc1\x51\xbc\x0c\x1c\xe2\x20\xfc"
+ "\xfe\xf2\xaa\x71\x9b\x21\xdf\x25\x1f\x68\x21\x7e\xe1\xc9\x87\xa0"
+ "\x20\xf6\x8d\x4f\x27\x8c\x3c\x0f\x9d\xf4\x69\x25\xaa\x49\xab\x94"
+ "\x22\x5a\x92\x3a\xba\xb4\xc2\x8c\x5a\xaa\x04\xbf\x46\xc5\xaa\x93"
+ "\xab\x0d\xe9\x54\x6c\x3a\x64\xa6\xa2\x21\x66\xee\x1c\x10\x21\x84"
+ "\xf2\x9e\xcc\x57\xac\xc2\x25\x62\xad\xbb\x59\xef\x25\x61\x6c\x81"
+ "\x38\x8a\xdc\x8c\xeb\x7b\x18\x1d\xaf\xa9\xc5\x9a\xf4\x49\x26\x8a"
+ "\x25\xc4\x3e\x31\x95\x28\xef\xf7\x72\xe9\xc5\xaa\x59\x72\x2b\x67"
+ "\x47\xe8\x6b\x51\x05\x24\xb8\x18\xb3\x34\x0f\x8c\x2b\x80\xba\x61"
+ "\x1c\xbe\x9e\x9a\x7c\xe3\x60\x5e\x49\x02\xff\x50\x8a\x64\x28\x64"
+ "\x46\x7b\x83\x14\x72\x6e\x59\x9b\x56\x09\xb4\xf0\xde\x52\xc3\xf3"
+ "\x58\x17\x6a\xae\xb1\x0f\xf4\x39\xcc\xd8\xce\x4d\xe1\x51\x17\x88"
+ "\xe4\x98\xd9\xd1\xa9\x55\xbc\xbf\x7e\xc4\x51\x96\xdb\x44\x1d\xcd"
+ "\x8d\x74\xad\xa7\x8f\x87\x83\x75\xfc\x36\xb7\xd2\xd4\x89\x16\x97"
+ "\xe4\xc6\x2a\xe9\x65\xc8\xca\x1c\xbd\x86\xaf\x57\x80\xf7\xdd\x42"
+ "\xc0\x3b\x3f\x87\x51\x02\x2f\xf8\xd8\x68\x0f\x3d\x95\x2d\xf1\x67"
+ "\x09\xa6\x5d\x0b\x7e\x01\xb4\xb2\x32\x01\xa8\xd0\x58\x0d\xe6\xa2"
+ "\xd8\x4b\x22\x10\x7d\x11\xf3\xc2\x4e\xb8\x43\x8e\x31\x79\x59\xe2"
+ "\xc4\x96\x29\x17\x40\x06\x0d\xdf\xdf\xc3\x02\x30\x2a\xd1\x8e\xf2"
+ "\xee\x2d\xd2\x12\x63\x5a\x1d\x3c\xba\x4a\xc4\x56\x90\xc6\x12\x0b"
+ "\xe0\x04\x3f\x35\x59\x8e\x40\x75\xf4\x4c\x10\x61\xb9\x30\x89\x7c"
+ "\x8d\x0e\x25\xb7\x5a\x6b\x97\x05\xc6\x37\x80\x6e\x94\x56\xa8\x5f"
+ "\x03\x94\x59\xc8\xc5\x3e\xdc\x23\xe5\x68\x4f\xd7\xbb\x6d\x7e\xc1"
+ "\x8d\xf9\xcc\x3f\x38\xad\x77\xb3\x18\x61\xed\x04\xc0\x71\xa7\x96"
+ "\xb1\xaf\x1d\x69\x78\xda\x6d\x89\x8b\x50\x75\x99\x44\xb3\xb2\x75"
+ "\xd1\xc8\x14\x40\xa1\x0a\xbf\xc4\x45\xc4\xee\x12\x90\x76\x26\x64"
+ "\xb7\x73\x2e\x0b\x0c\xfa\xc3\x55\x29\x24\x1b\x7a\x00\x27\x07\x26"
+ "\x36\xf0\x38\x1a\xe3\xb7\xc4\x8d\x1c\x9c\xa9\xc0\xc1\x45\x91\x9e"
+ "\x86\xdd\x82\x94\x45\xfa\xcd\x5a\x19\x12\x7d\xef\xda\x17\xad\x21"
+ "\x17\x89\x8b\x45\xa7\xf5\xed\x51\x9e\x58\x13\xdc\x84\xa4\xe6\x37",
+ .expected_ss =
+ "\x9a\x9c\x1c\xb7\x73\x2f\xf2\x12\xed\x59\x01\xbb\x75\xf7\xf5\xe4"
+ "\xa0\xa8\xbc\x3f\x3f\xb6\xf7\x74\x6e\xc4\xba\x6d\x6c\x4d\x93\x31"
+ "\x2b\xa7\xa4\xb3\x47\x8f\x77\x04\xb5\xa5\xab\xca\x6b\x5a\xe2\x86"
+ "\x02\x60\xca\xb4\xd7\x5e\xe0\x0f\x73\xdd\xa2\x38\x7c\xae\x0f\x5a"
+ "\x1a\xd7\xfd\xb6\xc8\x6f\xdd\xe0\x98\xd5\x07\xea\x1f\x2a\xbb\x9e"
+ "\xef\x01\x24\x04\xee\xf5\x89\xb1\x12\x26\x54\x95\xef\xcb\x84\xe9"
+ "\xae\x05\xef\x63\x25\x15\x65\x79\x79\x79\x91\xc3\x76\x72\xb4\x85"
+ "\x86\xd9\xd3\x03\xb0\xff\x04\x96\x05\x3c\xde\xbf\x47\x34\x76\x70"
+ "\x17\xd2\x24\x83\xb9\xbb\xcf\x70\x7c\xb8\xc6\x7b\x4e\x01\x86\x36"
+ "\xc7\xc5\xe5\x8b\x7c\x69\x74\x9a\xfe\x1f\x58\x85\x0f\x00\xf8\x4e"
+ "\xf1\x56\xdc\xd1\x11\x28\x2c\xcf\x6c\xb9\xc9\x57\x17\x2e\x19\x19"
+ "\x55\xb3\x4c\xd8\xfb\xe7\x6f\x70\x63\xf9\x53\x45\xdd\xd5\x62\x95"
+ "\xd3\x7d\x7e\xa0\x00\x1a\x62\x9f\x96\x0a\x5d\x0a\x25\x02\xbb\xff"
+ "\x5a\xe8\x9e\x5a\x66\x08\x93\xbc\x92\xaf\xd2\x28\x04\x97\xc1\x54"
+ "\xfe\xcc\x0a\x25\xa2\xf4\x1d\x5a\x9a\xb1\x3e\x9c\xba\x78\xe2\xcf"
+ "\x71\x70\xe3\x40\xea\xba\x69\x9b\x03\xdd\x99\x26\x09\x84\x9d\x69"
+ "\x4d\x3d\x0b\xe9\x3f\x51\xcd\x05\xe5\x00\xaf\x2c\xd3\xf6\xc0\x68"
+ "\xb5\x23\x53\x33\x14\xbd\x39\x1c\xbd\x1b\xe6\x72\x90\xcc\xc2\x86"
+ "\x1a\x42\x83\x55\xb3\xed\x0b\x62\x6d\x0e\xbb\x9e\x2a\x42\x32\x05"
+ "\x3f\xf2\x2c\xc8\x9f\x3c\xd2\xb1\x0b\xb6\x4c\xa0\x22\x36\xee\xb9"
+ "\x55\x23\x3e\x80\xc7\x28\x7c\x39\x11\xd3\x4a\x96\x2e\xef\x52\x34"
+ "\xf2\xda\xb1\xc6\xf5\x02\x10\xbf\x56\x6b\x50\x56\xcd\x2c\xfe\xe1"
+ "\x94\x14\x19\x24\x6e\x9a\xdf\x0c\xb8\xe2\xb8\xd5\xa3\xc1\x22\x8e"
+ "\x84\x92\x00\x16\xf1\x3f\x83\xf6\x36\x31\xa5\x38\xc6\xcf\xf8\x9b"
+ "\x03\xc7\x6f\xb9\xa1\x04\xdf\x20\x0f\x0b\x0f\x70\xff\x57\x36\x7f"
+ "\xb3\x6b\xcb\x8f\x48\xf7\xb2\xdb\x85\x05\xd1\xfe\x34\x05\xf6\x57"
+ "\xb4\x5b\xcc\x3f\x0e\xba\x36\x59\xb0\xfd\x4d\xf6\xf4\x5e\xd2\x65"
+ "\x1d\x98\x87\xb4\x5e\xff\x29\xaa\x84\x9b\x44\x0f\x06\x36\x61\xbd"
+ "\xdb\x51\xda\x56\xc2\xd6\x19\xe2\x57\x4f\xd0\x29\x71\xc8\xe4\xd6"
+ "\xfb\x8c\xd0\xfc\x4f\x25\x09\xa6\xfc\x67\xe2\xb8\xac\xd3\x88\x8f"
+ "\x1f\xf6\xa1\xe3\x45\xa6\x34\xe3\xb1\x6b\xb7\x37\x0e\x06\xc7\x63"
+ "\xde\xac\x3b\xac\x07\x91\x64\xcc\x12\x10\x46\x85\x14\x0b\x6b\x03"
+ "\xba\x4a\x85\xae\xc5\x8c\xa5\x9d\x36\x38\x33\xca\x42\x9c\x4b\x0c"
+ "\x46\xe1\x77\xe9\x1f\x80\xfe\xb7\x1d\x5a\xf4\xc6\x11\x26\x78\xea"
+ "\x81\x25\x77\x47\xed\x8b\x59\xc2\x6b\x49\xff\x83\x56\xec\xa5\xf0"
+ "\xe0\x8b\x15\xd4\x99\x40\x2a\x65\x2a\x98\xf4\x71\x35\x63\x84\x08"
+ "\x4d\xcd\x71\x85\x55\xbc\xa4\x1c\x90\x93\x03\x41\xde\xed\x78\x62"
+ "\x07\x30\x50\xac\x60\x21\x06\xc3\xab\xa4\x04\xc0\xc2\x32\x07\xc4"
+ "\x1f\x2f\xec\xe2\x32\xbf\xbe\x5e\x50\x5b\x2a\x19\x71\x44\x37\x76"
+ "\x8b\xbc\xdb\x73\x98\x65\x78\xc9\x33\x97\x7e\xdc\x60\xa8\x87\xf2"
+ "\xb5\x96\x55\x7f\x44\x07\xcb\x3b\xf3\xd7\x82\xfd\x77\x21\x82\x21"
+ "\x1a\x8b\xa2\xf5\x1f\x66\xd0\x57\x00\x4f\xa9\xa5\x33\xb8\x69\x91"
+ "\xe8\x2e\xf7\x73\x47\x89\x30\x9b\xb1\xfd\xe1\x5d\x11\xfd\x84\xd9"
+ "\xa2\x91\x1f\x8a\xa7\x7a\x77\x8e\x3b\x10\x1d\x0a\x59\x50\x34\xb0"
+ "\xc3\x90\x9f\x56\xb7\x43\xeb\x51\x99\x2b\x8e\x6d\x7b\x58\xe7\xc0"
+ "\x7f\x3d\xa0\x27\x50\xf2\x6e\xc8\x1e\x7f\x84\xb3\xe1\xf7\x09\x85"
+ "\xd2\x9b\x56\x6b\xba\xa5\x19\x2e\xec\xd8\x5c\xf5\x4e\x43\x36\x2e"
+ "\x89\x85\x41\x7f\x9c\x91\x2e\x62\xc3\x41\xcf\x0e\xa1\x7f\xeb\x50",
+ .secret_size = 784,
+ .b_public_size = 768,
+ .expected_a_public_size = 768,
+ .expected_ss_size = 768,
+ },
+ {
+ .secret =
+#ifdef __LITTLE_ENDIAN
+ "\x01\x00" /* type */
+ "\x10\x00" /* len */
+ "\x00\x00\x00\x00" /* key_size */
+ "\x00\x00\x00\x00" /* p_size */
+ "\x00\x00\x00\x00", /* g_size */
+#else
+ "\x00\x01" /* type */
+ "\x00\x10" /* len */
+ "\x00\x00\x00\x00" /* key_size */
+ "\x00\x00\x00\x00" /* p_size */
+ "\x00\x00\x00\x00", /* g_size */
+#endif
+ .b_secret =
+#ifdef __LITTLE_ENDIAN
+ "\x01\x00" /* type */
+ "\x10\x03" /* len */
+ "\x00\x03\x00\x00" /* key_size */
+ "\x00\x00\x00\x00" /* p_size */
+ "\x00\x00\x00\x00" /* g_size */
+#else
+ "\x00\x01" /* type */
+ "\x03\x10" /* len */
+ "\x00\x00\x03\x00" /* key_size */
+ "\x00\x00\x00\x00" /* p_size */
+ "\x00\x00\x00\x00" /* g_size */
+#endif
+ /* xa */
+ "\x63\x3e\x6f\xe0\xfe\x9f\x4a\x01\x62\x77\xce\xf1\xc7\xcc\x49\x4d"
+ "\x92\x53\x56\xe3\x39\x15\x81\xb2\xcd\xdc\xaf\x5e\xbf\x31\x1f\x69"
+ "\xce\x41\x35\x24\xaa\x46\x53\xb5\xb7\x3f\x2b\xad\x95\x14\xfb\xe4"
+ "\x9a\x61\xcd\x0f\x1f\x02\xee\xa4\x79\x2c\x9d\x1a\x7c\x62\x82\x39"
+ "\xdd\x43\xcc\x58\x9f\x62\x47\x56\x1d\x0f\xc2\x67\xbc\x24\xd0\xf9"
+ "\x0a\x50\x1b\x10\xe7\xbb\xd1\xc2\x01\xbb\xc4\x4c\xda\x12\x60\x0e"
+ "\x95\x2b\xde\x09\xd6\x67\xe1\xbc\x4c\xb9\x67\xdf\xd0\x1f\x97\xb4"
+ "\xde\xcb\x6b\x78\x83\x51\x74\x33\x01\x7f\xf6\x0a\x95\x69\x93\x00"
+ "\x2a\xc3\x75\x8e\xef\xbe\x53\x11\x6d\xc4\xd0\x9f\x6d\x63\x48\xc1"
+ "\x91\x1f\x7d\x88\xa7\x90\x78\xd1\x7e\x52\x42\x10\x01\xb4\x27\x95"
+ "\x91\x43\xcc\x82\x91\x86\x62\xa0\x9d\xef\x65\x6e\x67\xcf\x19\x11"
+ "\x35\x37\x5e\x94\x97\x83\xa6\x83\x1c\x7e\x8a\x3e\x32\xb0\xce\xff"
+ "\x20\xdc\x7b\x6e\x18\xd9\x6b\x27\x31\xfc\xc3\xef\x47\x8d\xbe\x34"
+ "\x2b\xc7\x60\x74\x3c\x93\xb3\x8e\x54\x77\x4e\x73\xe6\x40\x72\x35"
+ "\xb0\xf0\x06\x53\x43\xbe\xd0\xc3\x87\xcc\x38\x96\xa9\x10\xa0\xd6"
+ "\x17\xed\xa5\x6a\xf4\xf6\xaa\x77\x40\xed\x7d\x2e\x58\x0f\x5b\x04"
+ "\x5a\x41\x12\x95\x22\xcb\xa3\xce\x8b\x6d\x6d\x89\xec\x7c\x1d\x25"
+ "\x27\x52\x50\xa0\x5b\x93\x8c\x5d\x3f\x56\xb9\xa6\x5e\xe5\xf7\x9b"
+ "\xc7\x9a\x4a\x2e\x79\xb5\xca\x29\x58\x52\xa0\x63\xe4\x9d\xeb\x4c"
+ "\x4c\xa8\x37\x0b\xe9\xa0\x18\xf1\x86\xf6\x4d\x32\xfb\x9e\x4f\xb3"
+ "\x7b\x5d\x58\x78\x70\xbd\x56\xac\x99\x75\x25\x71\x66\x76\x4e\x5e"
+ "\x67\x4f\xb1\x17\xa7\x8b\x55\x12\x87\x01\x4e\xd1\x66\xef\xd0\x70"
+ "\xaf\x14\x34\xee\x2a\x76\x49\x25\xa6\x2e\x43\x37\x75\x7d\x1a\xad"
+ "\x08\xd5\x01\x85\x9c\xe1\x20\xd8\x38\x5c\x57\xa5\xed\x9d\x46\x3a"
+ "\xb7\x46\x60\x29\x8b\xc4\x21\x50\x0a\x30\x9c\x57\x42\xe4\x35\xf8"
+ "\x12\x5c\x4f\xa2\x20\xc2\xc9\x43\xe3\x6d\x20\xbc\xdf\xb8\x37\x33"
+ "\x45\x43\x06\x4e\x08\x6f\x8a\xcd\x61\xc3\x1b\x05\x28\x82\xbe\xf0"
+ "\x48\x33\xe5\x93\xc9\x1a\x61\x16\x67\x03\x9d\x47\x9d\x74\xeb\xae"
+ "\x13\xf2\xb4\x1b\x09\x11\xf5\x15\xcb\x28\xfd\x50\xe0\xbc\x58\x36"
+ "\x38\x91\x2c\x07\x27\x1f\x49\x68\xf4\xce\xad\xf7\xba\xec\x5d\x3d"
+ "\xfd\x27\xe2\xcf\xf4\x56\xfe\x08\xa6\x11\x61\xcb\x6c\x9f\xf9\x3c"
+ "\x57\x0b\x8b\xaa\x00\x16\x18\xba\x1f\xe8\x4f\x01\xe2\x79\x2a\x0b"
+ "\xc1\xbd\x52\xef\xe6\xf7\x5a\x66\xfe\x07\x3b\x50\x6b\xbb\xcb\x39"
+ "\x3c\x94\xf6\x21\x0d\x68\x69\xa4\xed\x2e\xb5\x85\x03\x11\x38\x79"
+ "\xec\xb5\x22\x23\xdf\x9e\xad\xb4\xbe\xd7\xc7\xdf\xea\x30\x23\x8a"
+ "\xb7\x21\x0a\x9d\xbd\x99\x13\x7d\x5f\x7e\xaf\x28\x54\x3f\xca\x5e"
+ "\xf4\xfc\x05\x0d\x65\x67\xd8\xf6\x8e\x90\x9d\x0d\xcf\x62\x82\xd6"
+ "\x9f\x02\xf8\xca\xfa\x42\x24\x7f\x4d\xb7\xfc\x92\xa6\x4a\x51\xc4"
+ "\xd8\xae\x19\x87\xc6\xa3\x83\xbe\x7b\x6d\xc3\xf5\xb8\xad\x4a\x05"
+ "\x78\x84\x3a\x15\x2e\x40\xbe\x79\xa9\xc0\x12\xa1\x48\x39\xc3\xdb"
+ "\x47\x4f\x7d\xea\x6d\xc7\xfa\x2c\x4e\xe9\xa5\x85\x81\xea\x6c\xcd"
+ "\x8a\xe5\x74\x17\x76\x31\x31\x75\x96\x83\xca\x81\xbb\x5c\xa9\x79"
+ "\x2c\xbd\x09\xfe\xe4\x86\x0d\x8c\x76\x9c\xbc\xe8\x93\xe4\xd0\xe4"
+ "\x0f\xf8\xff\x24\x7e\x66\x61\x69\xfb\xe4\x46\x08\x94\x99\xa5\x53"
+ "\xd7\xe4\x29\x72\x86\x86\xe8\x1d\x37\xfa\xcb\xd0\x8d\x51\xd0\xbf"
+ "\x81\xcf\x55\xb9\xc5\x78\x8c\x74\xa0\x16\x3a\xd2\x19\x94\x29\x6a"
+ "\x5e\xec\xd3\x20\xa0\xb2\xfd\xce\xd4\x14\xa3\x39\x10\xa9\xf4\x4e"
+ "\xba\x21\x09\x5c\xe6\x61\x43\x51\xae\xc4\x71\xd7\x21\xef\x98\x39",
+ .b_public =
+ "\x45\x96\x5a\xb7\x78\x5c\xa4\x4d\x39\xb2\x5f\xc8\xc2\xaa\x1a\xf4"
+ "\xa6\x68\xf6\x6f\x7e\xa8\x4a\x5b\x0e\xba\x0a\x99\x85\xf9\x63\xd4"
+ "\x58\x21\x6d\xa8\x3c\xf4\x05\x10\xb0\x0d\x6f\x1c\xa0\x17\x85\xae"
+ "\x68\xbf\xcc\x00\xc8\x86\x1b\x24\x31\xc9\x49\x23\x91\xe0\x71\x29"
+ "\x06\x39\x39\x93\x49\x9c\x75\x18\x1a\x8b\x61\x73\x1c\x7f\x37\xd5"
+ "\xf1\xab\x20\x5e\x62\x25\xeb\x58\xd5\xfa\xc9\x7f\xad\x57\xd5\xcc"
+ "\x0d\xc1\x7a\x2b\x33\x2a\x76\x84\x33\x26\x97\xcf\x47\x9d\x72\x2a"
+ "\xc9\x39\xde\xa8\x42\x27\x2d\xdc\xee\x00\x60\xd2\x4f\x13\xe0\xde"
+ "\xd5\xc7\xf6\x7d\x8b\x2a\x43\x49\x40\x99\xc2\x61\x84\x8e\x57\x09"
+ "\x7c\xcc\x19\x46\xbd\x4c\xd2\x7c\x7d\x02\x4d\x88\xdf\x58\x24\x80"
+ "\xeb\x19\x3b\x2a\x13\x2b\x19\x85\x3c\xd8\x31\x03\x00\xa4\xd4\x57"
+ "\x23\x2c\x24\x37\xb3\x62\xea\x35\x29\xd0\x2c\xac\xfd\xbd\xdf\x3d"
+ "\xa6\xce\xfa\x0d\x5b\xb6\x15\x8b\xe3\x58\xe9\xad\x99\x87\x29\x51"
+ "\x8d\x97\xd7\xa9\x55\xf0\x72\x6e\x4e\x58\xcb\x2b\x4d\xbd\xd0\x48"
+ "\x7d\x14\x86\xdb\x3f\xa2\x5f\x6e\x35\x4a\xe1\x70\xb1\x53\x72\xb7"
+ "\xbc\xe9\x3d\x1b\x33\xc0\x54\x6f\x43\x55\x76\x85\x7f\x9b\xa5\xb3"
+ "\xc1\x1d\xd3\xfe\xe2\xd5\x96\x3d\xdd\x92\x04\xb1\xad\x75\xdb\x13"
+ "\x4e\x49\xfc\x35\x34\xc5\xda\x13\x98\xb8\x12\xbe\xda\x90\x55\x7c"
+ "\x11\x6c\xbe\x2b\x8c\x51\x29\x23\xc1\x51\xbc\x0c\x1c\xe2\x20\xfc"
+ "\xfe\xf2\xaa\x71\x9b\x21\xdf\x25\x1f\x68\x21\x7e\xe1\xc9\x87\xa0"
+ "\x20\xf6\x8d\x4f\x27\x8c\x3c\x0f\x9d\xf4\x69\x25\xaa\x49\xab\x94"
+ "\x22\x5a\x92\x3a\xba\xb4\xc2\x8c\x5a\xaa\x04\xbf\x46\xc5\xaa\x93"
+ "\xab\x0d\xe9\x54\x6c\x3a\x64\xa6\xa2\x21\x66\xee\x1c\x10\x21\x84"
+ "\xf2\x9e\xcc\x57\xac\xc2\x25\x62\xad\xbb\x59\xef\x25\x61\x6c\x81"
+ "\x38\x8a\xdc\x8c\xeb\x7b\x18\x1d\xaf\xa9\xc5\x9a\xf4\x49\x26\x8a"
+ "\x25\xc4\x3e\x31\x95\x28\xef\xf7\x72\xe9\xc5\xaa\x59\x72\x2b\x67"
+ "\x47\xe8\x6b\x51\x05\x24\xb8\x18\xb3\x34\x0f\x8c\x2b\x80\xba\x61"
+ "\x1c\xbe\x9e\x9a\x7c\xe3\x60\x5e\x49\x02\xff\x50\x8a\x64\x28\x64"
+ "\x46\x7b\x83\x14\x72\x6e\x59\x9b\x56\x09\xb4\xf0\xde\x52\xc3\xf3"
+ "\x58\x17\x6a\xae\xb1\x0f\xf4\x39\xcc\xd8\xce\x4d\xe1\x51\x17\x88"
+ "\xe4\x98\xd9\xd1\xa9\x55\xbc\xbf\x7e\xc4\x51\x96\xdb\x44\x1d\xcd"
+ "\x8d\x74\xad\xa7\x8f\x87\x83\x75\xfc\x36\xb7\xd2\xd4\x89\x16\x97"
+ "\xe4\xc6\x2a\xe9\x65\xc8\xca\x1c\xbd\x86\xaf\x57\x80\xf7\xdd\x42"
+ "\xc0\x3b\x3f\x87\x51\x02\x2f\xf8\xd8\x68\x0f\x3d\x95\x2d\xf1\x67"
+ "\x09\xa6\x5d\x0b\x7e\x01\xb4\xb2\x32\x01\xa8\xd0\x58\x0d\xe6\xa2"
+ "\xd8\x4b\x22\x10\x7d\x11\xf3\xc2\x4e\xb8\x43\x8e\x31\x79\x59\xe2"
+ "\xc4\x96\x29\x17\x40\x06\x0d\xdf\xdf\xc3\x02\x30\x2a\xd1\x8e\xf2"
+ "\xee\x2d\xd2\x12\x63\x5a\x1d\x3c\xba\x4a\xc4\x56\x90\xc6\x12\x0b"
+ "\xe0\x04\x3f\x35\x59\x8e\x40\x75\xf4\x4c\x10\x61\xb9\x30\x89\x7c"
+ "\x8d\x0e\x25\xb7\x5a\x6b\x97\x05\xc6\x37\x80\x6e\x94\x56\xa8\x5f"
+ "\x03\x94\x59\xc8\xc5\x3e\xdc\x23\xe5\x68\x4f\xd7\xbb\x6d\x7e\xc1"
+ "\x8d\xf9\xcc\x3f\x38\xad\x77\xb3\x18\x61\xed\x04\xc0\x71\xa7\x96"
+ "\xb1\xaf\x1d\x69\x78\xda\x6d\x89\x8b\x50\x75\x99\x44\xb3\xb2\x75"
+ "\xd1\xc8\x14\x40\xa1\x0a\xbf\xc4\x45\xc4\xee\x12\x90\x76\x26\x64"
+ "\xb7\x73\x2e\x0b\x0c\xfa\xc3\x55\x29\x24\x1b\x7a\x00\x27\x07\x26"
+ "\x36\xf0\x38\x1a\xe3\xb7\xc4\x8d\x1c\x9c\xa9\xc0\xc1\x45\x91\x9e"
+ "\x86\xdd\x82\x94\x45\xfa\xcd\x5a\x19\x12\x7d\xef\xda\x17\xad\x21"
+ "\x17\x89\x8b\x45\xa7\xf5\xed\x51\x9e\x58\x13\xdc\x84\xa4\xe6\x37",
+ .secret_size = 16,
+ .b_secret_size = 784,
+ .b_public_size = 768,
+ .expected_a_public_size = 768,
+ .expected_ss_size = 768,
+ .genkey = true,
+ },
+};
+
+static const struct kpp_testvec ffdhe8192_dh_tv_template[] __maybe_unused = {
+ {
+ .secret =
+#ifdef __LITTLE_ENDIAN
+ "\x01\x00" /* type */
+ "\x10\x04" /* len */
+ "\x00\x04\x00\x00" /* key_size */
+ "\x00\x00\x00\x00" /* p_size */
+ "\x00\x00\x00\x00" /* g_size */
+#else
+ "\x00\x01" /* type */
+ "\x04\x10" /* len */
+ "\x00\x00\x04\x00" /* key_size */
+ "\x00\x00\x00\x00" /* p_size */
+ "\x00\x00\x00\x00" /* g_size */
+#endif
+ /* xa */
+ "\x76\x6e\xeb\xf9\xeb\x76\xae\x37\xcb\x19\x49\x8b\xeb\xaf\xb0\x4b"
+ "\x6d\xe9\x15\xad\xda\xf2\xef\x58\xe9\xd6\xdd\x4c\xb3\x56\xd0\x3b"
+ "\x00\xb0\x65\xed\xae\xe0\x2e\xdf\x8f\x45\x3f\x3c\x5d\x2f\xfa\x96"
+ "\x36\x33\xb2\x01\x8b\x0f\xe8\x46\x15\x6d\x60\x5b\xec\x32\xc3\x3b"
+ "\x06\xf3\xb4\x1b\x9a\xef\x3c\x03\x0e\xcc\xce\x1d\x24\xa0\xc9\x08"
+ "\x65\xf9\x45\xe5\xd2\x43\x08\x88\x58\xd6\x46\xe7\xbb\x25\xac\xed"
+ "\x3b\xac\x6f\x5e\xfb\xd6\x19\xa6\x20\x3a\x1d\x0c\xe8\x00\x72\x54"
+ "\xd7\xd9\xc9\x26\x49\x18\xc6\xb8\xbc\xdd\xf3\xce\xf3\x7b\x69\x04"
+ "\x5c\x6f\x11\xdb\x44\x42\x72\xb6\xb7\x84\x17\x86\x47\x3f\xc5\xa1"
+ "\xd8\x86\xef\xe2\x27\x49\x2b\x8f\x3e\x91\x12\xd9\x45\x96\xf7\xe6"
+ "\x77\x76\x36\x58\x71\x9a\xb1\xdb\xcf\x24\x9e\x7e\xad\xce\x45\xba"
+ "\xb5\xec\x8e\xb9\xd6\x7b\x3d\x76\xa4\x85\xad\xd8\x49\x9b\x80\x9d"
+ "\x7f\x9f\x85\x09\x9e\x86\x5b\x6b\xf3\x8d\x39\x5e\x6f\xe4\x30\xc8"
+ "\xa5\xf3\xdf\x68\x73\x6b\x2e\x9a\xcb\xac\x0a\x0d\x44\xc1\xaf\xb2"
+ "\x11\x1b\x7c\x43\x08\x44\x43\xe2\x4e\xfd\x93\x30\x99\x09\x12\xbb"
+ "\xf6\x31\x34\xa5\x3d\x45\x98\xee\xd7\x2a\x1a\x89\xf5\x37\x92\x33"
+ "\xa0\xdd\xf5\xfb\x1f\x90\x42\x55\x5a\x0b\x82\xff\xf0\x96\x92\x15"
+ "\x65\x5a\x55\x96\xca\x1b\xd5\xe5\xb5\x94\xde\x2e\xa6\x03\x57\x9e"
+ "\x15\xe4\x32\x2b\x1f\xb2\x22\x21\xe9\xa0\x05\xd3\x65\x6c\x11\x66"
+ "\x25\x38\xbb\xa3\x6c\xc2\x0b\x2b\xd0\x7a\x20\x26\x29\x37\x5d\x5f"
+ "\xd8\xff\x2a\xcd\x46\x6c\xd6\x6e\xe5\x77\x1a\xe6\x33\xf1\x8e\xc8"
+ "\x10\x30\x11\x00\x27\xf9\x7d\x0e\x28\x43\xa7\x67\x38\x7f\x16\xda"
+ "\xd0\x01\x8e\xa4\xe8\x6f\xcd\x23\xaf\x77\x52\x34\xad\x7e\xc3\xed"
+ "\x2d\x10\x0a\x33\xdc\xcf\x1b\x88\x0f\xcc\x48\x7f\x42\xf0\x9e\x13"
+ "\x1f\xf5\xd1\xe9\x90\x87\xbd\xfa\x5f\x1d\x77\x55\xcb\xc3\x05\xaf"
+ "\x71\xd0\xe0\xab\x46\x31\xd7\xea\x89\x54\x2d\x39\xaf\xf6\x4f\x74"
+ "\xaf\x46\x58\x89\x78\x95\x2e\xe6\x90\xb7\xaa\x00\x73\x9f\xed\xb9"
+ "\x00\xd6\xf6\x6d\x26\x59\xcd\x56\xdb\xf7\x3d\x5f\xeb\x6e\x46\x33"
+ "\xb1\x23\xed\x9f\x8d\x58\xdc\xb4\x28\x3b\x90\x09\xc4\x61\x02\x1f"
+ "\xf8\x62\xf2\x6e\xc1\x94\x71\x66\x93\x11\xdf\xaa\x3e\xd7\xb5\xe5"
+ "\xc1\x78\xe9\x14\xcd\x55\x16\x51\xdf\x8d\xd0\x94\x8c\x43\xe9\xb8"
+ "\x1d\x42\x7f\x76\xbc\x6f\x87\x42\x88\xde\xd7\x52\x78\x00\x4f\x18"
+ "\x02\xe7\x7b\xe2\x8a\xc3\xd1\x43\xa5\xac\xda\xb0\x8d\x19\x96\xd4"
+ "\x81\xe0\x75\xe9\xca\x41\x7e\x1f\x93\x0b\x26\x24\xb3\xaa\xdd\x10"
+ "\x20\xd3\xf2\x9f\x3f\xdf\x65\xde\x67\x79\xdc\x76\x9f\x3c\x72\x75"
+ "\x65\x8a\x30\xcc\xd2\xcc\x06\xb1\xab\x62\x86\x78\x5d\xb8\xce\x72"
+ "\xb3\x12\xc7\x9f\x07\xd0\x6b\x98\x82\x9b\x6c\xbb\x15\xe5\xcc\xf4"
+ "\xc8\xf4\x60\x81\xdc\xd3\x09\x1b\x5e\xd4\xf3\x55\xcf\x1c\x16\x83"
+ "\x61\xb4\x2e\xcc\x08\x67\x58\xfd\x46\x64\xbc\x29\x4b\xdd\xda\xec"
+ "\xdc\xc6\xa9\xa5\x73\xfb\xf8\xf3\xaf\x89\xa8\x9e\x25\x14\xfa\xac"
+ "\xeb\x1c\x7c\x80\x96\x66\x4d\x41\x67\x9b\x07\x4f\x0a\x97\x17\x1c"
+ "\x4d\x61\xc7\x2e\x6f\x36\x98\x29\x50\x39\x6d\xe7\x70\xda\xf0\xc8"
+ "\x05\x80\x7b\x32\xff\xfd\x12\xde\x61\x0d\xf9\x4c\x21\xf1\x56\x72"
+ "\x3d\x61\x46\xc0\x2d\x07\xd1\x6c\xd3\xbe\x9a\x21\x83\x85\xf7\xed"
+ "\x53\x95\x44\x40\x8f\x75\x12\x18\xc2\x9a\xfd\x5e\xce\x66\xa6\x7f"
+ "\x57\xc0\xd7\x73\x76\xb3\x13\xda\x2e\x58\xc6\x27\x40\xb2\x2d\xef"
+ "\x7d\x72\xb4\xa8\x75\x6f\xcc\x5f\x42\x3e\x2c\x90\x36\x59\xa0\x34"
+ "\xaa\xce\xbc\x04\x4c\xe6\x56\xc2\xcd\xa6\x1c\x59\x04\x56\x53\xcf"
+ "\x6d\xd7\xf0\xb1\x4f\x91\xfa\x84\xcf\x4b\x8d\x50\x4c\xf8\x2a\x31"
+ "\x5f\xe3\xba\x79\xb4\xcc\x59\x64\xe3\x7a\xfa\xf6\x06\x9d\x04\xbb"
+ "\xce\x61\xbf\x9e\x59\x0a\x09\x51\x6a\xbb\x0b\x80\xe0\x91\xc1\x51"
+ "\x04\x58\x67\x67\x4b\x42\x4f\x95\x68\x75\xe2\x1f\x9c\x14\x70\xfd"
+ "\x3a\x8a\xce\x8b\x04\xa1\x89\xe7\xb4\xbf\x70\xfe\xf3\x0c\x48\x04"
+ "\x3a\xd2\x85\x68\x03\xe7\xfa\xec\x5b\x55\xb7\x95\xfd\x5b\x19\x35"
+ "\xad\xcb\x4a\x63\x03\x44\x64\x2a\x48\x59\x9a\x26\x43\x96\x8c\xe6"
+ "\xbd\xb7\x90\xd4\x5f\x8d\x08\x28\xa8\xc5\x89\x70\xb9\x6e\xd3\x3b"
+ "\x76\x0e\x37\x98\x15\x27\xca\xc9\xb0\xe0\xfd\xf3\xc6\xdf\x69\xce"
+ "\xe1\x5f\x6a\x3e\x5c\x86\xe2\x58\x41\x11\xf0\x7e\x56\xec\xe4\xc9"
+ "\x0d\x87\x91\xfb\xb9\xc8\x0d\x34\xab\xb0\xc6\xf2\xa6\x00\x7b\x18"
+ "\x92\xf4\x43\x7f\x01\x85\x2e\xef\x8c\x72\x50\x10\xdb\xf1\x37\x62"
+ "\x16\x85\x71\x01\xa8\x2b\xf0\x13\xd3\x7c\x0b\xaf\xf1\xf3\xd1\xee"
+ "\x90\x41\x5f\x7d\x5b\xa9\x83\x4b\xfa\x80\x59\x50\x73\xe1\xc4\xf9"
+ "\x5e\x4b\xde\xd9\xf5\x22\x68\x5e\x65\xd9\x37\xe4\x1a\x08\x0e\xb1"
+ "\x28\x2f\x40\x9e\x37\xa8\x12\x56\xb7\xb8\x64\x94\x68\x94\xff\x9f",
+ .b_public =
+ "\x26\xa8\x3a\x97\xe0\x52\x76\x07\x26\xa7\xbb\x21\xfd\xe5\x69\xde"
+ "\xe6\xe0\xb5\xa0\xf1\xaa\x51\x2b\x56\x1c\x3c\x6c\xe5\x9f\x8f\x75"
+ "\x71\x04\x86\xf6\x43\x2f\x20\x7f\x45\x4f\x5c\xb9\xf3\x90\xbe\xa9"
+ "\xa0\xd7\xe8\x03\x0e\xfe\x99\x9b\x8a\x1c\xbe\xa7\x63\xe8\x2b\x45"
+ "\xd4\x2c\x65\x25\x4c\x33\xda\xc5\x85\x77\x5d\x62\xea\x93\xe4\x45"
+ "\x59\xff\xa1\xd2\xf1\x73\x11\xed\x02\x64\x8a\x1a\xfb\xe1\x88\xa6"
+ "\x50\x6f\xff\x87\x12\xbb\xfc\x10\xcf\x19\x41\xb0\x35\x44\x7d\x51"
+ "\xe9\xc0\x77\xf2\x73\x21\x2e\x62\xbf\x65\xa5\xd1\x3b\xb1\x3e\x19"
+ "\x75\x4b\xb7\x8e\x03\xc3\xdf\xc8\xb2\xe6\xec\x2d\x7d\xa5\x6a\xba"
+ "\x93\x47\x50\xeb\x6e\xdb\x88\x05\x45\xad\x03\x8c\xf7\x9a\xe1\xc9"
+ "\x1e\x16\x96\x37\xa5\x3e\xe9\xb9\xa8\xdc\xb9\xa9\xf6\xa1\x3d\xed"
+ "\xbe\x12\x29\x8a\x3d\x3d\x90\xfc\x94\xfe\x66\x28\x1c\x1b\xa4\x89"
+ "\x47\x66\x4f\xac\x14\x00\x22\x2d\x5c\x03\xea\x71\x4d\x19\x7d\xd6"
+ "\x58\x39\x4c\x3d\x06\x2b\x30\xa6\xdc\x2c\x8d\xd1\xde\x79\x77\xfa"
+ "\x9c\x6b\x72\x11\x8a\x7f\x7d\x37\x28\x2a\x88\xbf\x0a\xdb\xac\x3b"
+ "\xc5\xa5\xd5\x7e\x25\xec\xa6\x7f\x5b\x53\x75\x83\x49\xd4\x77\xcc"
+ "\x7d\x7e\xd3\x3d\x30\x2c\x98\x3f\x18\x9a\x11\x8a\x37\xda\x99\x0f"
+ "\x3b\x06\xe1\x87\xd5\xe9\x4e\xe0\x9c\x0e\x39\x34\xe2\xdd\xf6\x58"
+ "\x60\x63\xa6\xea\xe8\xc0\xb4\xde\xdf\xa0\xbc\x21\xc3\x2d\xf4\xa4"
+ "\xc8\x6f\x62\x6c\x0f\x71\x88\xf9\xda\x2d\x30\xd5\x95\xe1\xfc\x6d"
+ "\x88\xc5\xc3\x95\x51\x83\xde\x41\x46\x6f\x7e\x1b\x10\x48\xad\x2b"
+ "\x82\x88\xa2\x6f\x57\x4d\x4a\xbd\x90\xc8\x06\x8f\x52\x5d\x6e\xee"
+ "\x09\xe6\xa3\xcb\x30\x9c\x14\xf6\xac\x66\x9b\x81\x0a\x75\x42\x6b"
+ "\xab\x27\xec\x76\xfb\x8d\xc5\xbf\x0e\x93\x81\x7b\x81\xd4\x85\xa6"
+ "\x90\x5a\xa6\xa2\x8b\xa9\xb7\x34\xe6\x15\x36\x93\x8b\xe2\x99\xc7"
+ "\xad\x66\x7e\xd6\x89\xa9\xc8\x15\xcb\xc5\xeb\x06\x85\xd4\x2f\x6e"
+ "\x9b\x95\x7a\x06\x6c\xfa\x31\x1d\xc4\xe5\x7d\xfb\x10\x35\x88\xc2"
+ "\xbe\x1c\x16\x5d\xc2\xf4\x0d\xf3\xc9\x94\xb2\x7e\xa7\xbd\x9c\x03"
+ "\x32\xaf\x8b\x1a\xc8\xcc\x82\xd8\x87\x96\x6e\x3d\xcc\x93\xd2\x43"
+ "\x73\xf9\xde\xec\x49\x49\xf4\x56\x2a\xc8\x6e\x32\x70\x48\xf8\x70"
+ "\xa3\x96\x31\xf4\xf2\x08\xc5\x12\xd2\xeb\xb6\xea\xa3\x07\x05\x61"
+ "\x74\xa3\x04\x2f\x17\x82\x40\x5e\x4c\xd1\x51\xb8\x10\x5b\xc8\x9f"
+ "\x87\x73\x80\x0d\x6f\xc6\xb9\xf6\x7c\x31\x0a\xcc\xd9\x03\x0f\x7a"
+ "\x47\x69\xb1\x55\xab\xe9\xb5\x75\x62\x9e\x95\xbe\x7b\xa9\x53\x6e"
+ "\x28\x73\xdc\xb3\xa4\x8a\x1c\x91\xf5\x8a\xf9\x32\x2b\xbd\xa5\xdc"
+ "\x07\xb5\xaf\x49\xdb\x9c\x35\xc9\x69\xde\xac\xb1\xd0\x86\xcb\x31"
+ "\x0b\xc4\x4f\x63\x4e\x70\xa7\x80\xe3\xbc\x0b\x73\x0e\xf2\x8c\x87"
+ "\x88\x7b\xa9\x6d\xde\x8a\x73\x14\xb9\x80\x55\x03\x2b\x29\x64\x6a"
+ "\xda\x48\x0e\x78\x07\x40\x48\x46\x58\xa9\x4e\x68\x1d\xd1\xc1\xc8"
+ "\x3b\x35\x53\x61\xd5\xe3\x0d\x4c\x42\x74\x10\x67\x85\x9f\x66\x2a"
+ "\xf7\x2b\x7b\x77\x8b\x6e\xda\x2c\xc1\x5a\x20\x34\x3f\xf5\x8b\x6f"
+ "\xe4\x61\xf5\x58\xab\x72\x1a\xf1\x8d\x28\xcc\xa5\x30\x68\xb5\x50"
+ "\x7b\x81\x43\x89\x8e\xa9\xac\x63\x3a\x4a\x78\x7b\xd2\x45\xe6\xe0"
+ "\xdc\x5d\xf2\x1a\x2b\x54\x50\xa5\x9d\xf6\xe7\x9f\x25\xaf\x56\x6a"
+ "\x84\x2a\x75\xa3\x9a\xc7\xfa\x94\xec\x83\xab\xa5\xaa\xe1\xf9\x89"
+ "\x29\xa9\xf6\x53\x24\x24\xae\x4a\xe8\xbc\xe8\x9e\x5c\xd7\x54\x7c"
+ "\x65\x20\x97\x28\x94\x76\xf9\x9e\x81\xcf\x98\x6a\x3a\x7b\xec\xf3"
+ "\x09\x60\x2e\x43\x18\xb5\xf6\x8c\x44\x0f\xf2\x0a\x17\x5b\xac\x98"
+ "\x30\xab\x6e\xd5\xb3\xef\x25\x68\x50\xb6\xe1\xc0\xe4\x5a\x63\x43"
+ "\xea\xca\xda\x23\xc1\xc2\xe9\x30\xec\xb3\x9f\xbf\x1f\x09\x76\xaf"
+ "\x65\xbc\xb5\xab\x30\xac\x0b\x05\xef\x5c\xa3\x65\x77\x33\x1c\xc5"
+ "\xdf\xc9\x39\xab\xca\xf4\x3b\x88\x25\x6d\x50\x87\xb1\x79\xc2\x23"
+ "\x9d\xb5\x21\x01\xaa\xa3\xb7\x61\xa3\x48\x91\x72\x3d\x54\x85\x86"
+ "\x91\x81\x35\x78\xbf\x8f\x27\x57\xcb\x9b\x34\xab\x63\x40\xf1\xbc"
+ "\x23\x5a\x26\x6a\xba\x57\xe2\x8f\x2a\xdc\x82\xe0\x3b\x7f\xec\xd3"
+ "\xd8\x9d\xd3\x13\x54\x70\x64\xc3\xfd\xbf\xa3\x46\xa7\x53\x42\x7f"
+ "\xc1\xbd\x7b\xb3\x13\x47\x2a\x45\x1e\x76\x2c\x0d\x6d\x46\x26\x24"
+ "\xa8\xc7\x00\x2b\x10\x7f\x2a\x6c\xfc\x68\x4e\x6e\x85\x53\x00\xaf"
+ "\xd5\xfb\x59\x64\xc7\x9b\x24\xd1\x05\xdc\x34\x53\x6d\x27\xa9\x79"
+ "\xff\xd7\x5e\x7a\x40\x81\x8e\xc3\xf2\x38\xc9\x8d\x87\xb5\x38\xda"
+ "\x43\x64\x1b\x59\x62\x88\xc1\x6e\x85\x84\x33\xcd\x6d\x7b\x62\x1d"
+ "\x60\xf9\x98\xf7\xd1\xb1\xd4\xbe\x56\x6e\xa8\x6f\xff\xe7\x8b\x60"
+ "\x53\x80\xc7\x7c\xe0\x78\x89\xa9\xab\x42\x8f\x8e\x4d\x92\xac\xa7"
+ "\xfd\x47\x11\xc7\xdb\x7c\x77\xfb\xa4\x1d\x70\xaf\x56\x14\x52\xb0",
+ .expected_a_public =
+ "\xa1\x6c\x9e\xda\x45\x4d\xf6\x59\x04\x00\xc1\xc6\x8b\x12\x3b\xcd"
+ "\x07\xe4\x3e\xec\xac\x9b\xfc\xf7\x6d\x73\x39\x9e\x52\xf8\xbe\x33"
+ "\xe2\xca\xea\x99\x76\xc7\xc9\x94\x5c\xf3\x1b\xea\x6b\x66\x4b\x51"
+ "\x90\xf6\x4f\x75\xd5\x85\xf4\x28\xfd\x74\xa5\x57\xb1\x71\x0c\xb6"
+ "\xb6\x95\x70\x2d\xfa\x4b\x56\xe0\x56\x10\x21\xe5\x60\xa6\x18\xa4"
+ "\x78\x8c\x07\xc0\x2b\x59\x9c\x84\x5b\xe9\xb9\x74\xbf\xbc\x65\x48"
+ "\x27\x82\x40\x53\x46\x32\xa2\x92\x91\x9d\xf6\xd1\x07\x0e\x1d\x07"
+ "\x1b\x41\x04\xb1\xd4\xce\xae\x6e\x46\xf1\x72\x50\x7f\xff\xa8\xa2"
+ "\xbc\x3a\xc1\xbb\x28\xd7\x7d\xcd\x7a\x22\x01\xaf\x57\xb0\xa9\x02"
+ "\xd4\x8a\x92\xd5\xe6\x8e\x6f\x11\x39\xfe\x36\x87\x89\x42\x25\x42"
+ "\xd9\xbe\x67\x15\xe1\x82\x8a\x5e\x98\xc2\xd5\xde\x9e\x13\x1a\xe7"
+ "\xf9\x9f\x8e\x2d\x49\xdc\x4d\x98\x8c\xdd\xfd\x24\x7c\x46\xa9\x69"
+ "\x3b\x31\xb3\x12\xce\x54\xf6\x65\x75\x40\xc2\xf1\x04\x92\xe3\x83"
+ "\xeb\x02\x3d\x79\xc0\xf9\x7c\x28\xb3\x97\x03\xf7\x61\x1c\xce\x95"
+ "\x1a\xa0\xb3\x77\x1b\xc1\x9f\xf8\xf6\x3f\x4d\x0a\xfb\xfa\x64\x1c"
+ "\xcb\x37\x5b\xc3\x28\x60\x9f\xd1\xf2\xc4\xee\x77\xaa\x1f\xe9\xa2"
+ "\x89\x4c\xc6\xb7\xb3\xe4\xa5\xed\xa7\xe8\xac\x90\xdc\xc3\xfb\x56"
+ "\x9c\xda\x2c\x1d\x1a\x9a\x8c\x82\x92\xee\xdc\xa0\xa4\x01\x6e\x7f"
+ "\xc7\x0e\xc2\x73\x7d\xa6\xac\x12\x01\xc0\xc0\xc8\x7c\x84\x86\xc7"
+ "\xa5\x94\xe5\x33\x84\x71\x6e\x36\xe3\x3b\x81\x30\xe0\xc8\x51\x52"
+ "\x2b\x9e\x68\xa2\x6e\x09\x95\x8c\x7f\x78\x82\xbd\x53\x26\xe7\x95"
+ "\xe0\x03\xda\xc0\xc3\x6e\xcf\xdc\xb3\x14\xfc\xe9\x5b\x9b\x70\x6c"
+ "\x93\x04\xab\x13\xf7\x17\x6d\xee\xad\x32\x48\xe9\xa0\x94\x1b\x14"
+ "\x64\x4f\xa1\xb3\x8d\x6a\xca\x28\xfe\x4a\xf4\xf0\xc5\xb7\xf9\x8a"
+ "\x8e\xff\xfe\x57\x6f\x20\xdb\x04\xab\x02\x31\x22\x42\xfd\xbd\x77"
+ "\xea\xce\xe8\xc7\x5d\xe0\x8e\xd6\x66\xd0\xe4\x04\x2f\x5f\x71\xc7"
+ "\x61\x2d\xa5\x3f\x2f\x46\xf2\xd8\x5b\x25\x82\xf0\x52\x88\xc0\x59"
+ "\xd3\xa3\x90\x17\xc2\x04\x13\xc3\x13\x69\x4f\x17\xb1\xb3\x46\x4f"
+ "\xa7\xe6\x8b\x5e\x3e\x95\x0e\xf5\x42\x17\x7f\x4d\x1f\x1b\x7d\x65"
+ "\x86\xc5\xc8\xae\xae\xd8\x4f\xe7\x89\x41\x69\xfd\x06\xce\x5d\xed"
+ "\x44\x55\xad\x51\x98\x15\x78\x8d\x68\xfc\x93\x72\x9d\x22\xe5\x1d"
+ "\x21\xc3\xbe\x3a\x44\x34\xc0\xa3\x1f\xca\xdf\x45\xd0\x5c\xcd\xb7"
+ "\x72\xeb\xae\x7a\xad\x3f\x05\xa0\xe3\x6e\x5a\xd8\x52\xa7\xf1\x1e"
+ "\xb4\xf2\xcf\xe7\xdf\xa7\xf2\x22\x00\xb2\xc4\x17\x3d\x2c\x15\x04"
+ "\x71\x28\x69\x5c\x69\x21\xc8\xf1\x9b\xd8\xc7\xbc\x27\xa3\x85\xe9"
+ "\x53\x77\xd3\x65\xc3\x86\xdd\xb3\x76\x13\xfb\xa1\xd4\xee\x9d\xe4"
+ "\x51\x3f\x83\x59\xe4\x47\xa8\xa6\x0d\x68\xd5\xf6\xf4\xca\x31\xcd"
+ "\x30\x48\x34\x90\x11\x8e\x87\xe9\xea\xc9\xd0\xc3\xba\x28\xf9\xc0"
+ "\xc9\x8e\x23\xe5\xc2\xee\xf2\x47\x9c\x41\x1c\x10\x33\x27\x23\x49"
+ "\xe5\x0d\x18\xbe\x19\xc1\xba\x6c\xdc\xb7\xa1\xe7\xc5\x0d\x6f\xf0"
+ "\x8c\x62\x6e\x0d\x14\xef\xef\xf2\x8e\x01\xd2\x76\xf5\xc1\xe1\x92"
+ "\x3c\xb3\x76\xcd\xd8\xdd\x9b\xe0\x8e\xdc\x24\x34\x13\x65\x0f\x11"
+ "\xaf\x99\x7a\x2f\xe6\x1f\x7d\x17\x3e\x8a\x68\x9a\x37\xc8\x8d\x3e"
+ "\xa3\xfe\xfe\x57\x22\xe6\x0e\x50\xb5\x98\x0b\x71\xd8\x01\xa2\x8d"
+ "\x51\x96\x50\xc2\x41\x31\xd8\x23\x98\xfc\xd1\x9d\x7e\x27\xbb\x69"
+ "\x78\xe0\x87\xf7\xe4\xdd\x58\x13\x9d\xec\x00\xe4\xb9\x70\xa2\x94"
+ "\x5d\x52\x4e\xf2\x5c\xd1\xbc\xfd\xee\x9b\xb9\xe5\xc4\xc0\xa8\x77"
+ "\x67\xa4\xd1\x95\x34\xe4\x6d\x5f\x25\x02\x8d\x65\xdd\x11\x63\x55"
+ "\x04\x01\x21\x60\xc1\x5c\xef\x77\x33\x01\x1c\xa2\x11\x2b\xdd\x2b"
+ "\x74\x99\x23\x38\x05\x1b\x7e\x2e\x01\x52\xfe\x9c\x23\xde\x3e\x1a"
+ "\x72\xf4\xff\x7b\x02\xaa\x08\xcf\xe0\x5b\x83\xbe\x85\x5a\xe8\x9d"
+ "\x11\x3e\xff\x2f\xc6\x97\x67\x36\x6c\x0f\x81\x9c\x26\x29\xb1\x0f"
+ "\xbb\x53\xbd\xf4\xec\x2a\x84\x41\x28\x3b\x86\x40\x95\x69\x55\x5f"
+ "\x30\xee\xda\x1e\x6c\x4b\x25\xd6\x2f\x2c\x0e\x3c\x1a\x26\xa0\x3e"
+ "\xef\x09\xc6\x2b\xe5\xa1\x0c\x03\xa8\xf5\x39\x70\x31\xc4\x32\x79"
+ "\xd1\xd9\xc2\xcc\x32\x4a\xf1\x2f\x57\x5a\xcc\xe5\xc3\xc5\xd5\x4e"
+ "\x86\x56\xca\x64\xdb\xab\x61\x85\x8f\xf9\x20\x02\x40\x66\x76\x9e"
+ "\x5e\xd4\xac\xf0\x47\xa6\x50\x5f\xc2\xaf\x55\x9b\xa3\xc9\x8b\xf8"
+ "\x42\xd5\xcf\x1a\x95\x22\xd9\xd1\x0b\x92\x51\xca\xde\x46\x02\x0d"
+ "\x8b\xee\xd9\xa0\x04\x74\xf5\x0e\xb0\x3a\x62\xec\x3c\x91\x29\x33"
+ "\xa7\x78\x22\x92\xac\x27\xe6\x2d\x6f\x56\x8a\x5d\x72\xc2\xf1\x5c"
+ "\x54\x11\x97\x24\x61\xcb\x0c\x52\xd4\x57\x56\x22\x86\xf0\x19\x27"
+ "\x76\x30\x04\xf4\x39\x7b\x1a\x5a\x04\x0d\xec\x59\x9a\x31\x4c\x40"
+ "\x19\x6d\x3c\x41\x1b\x0c\xca\xeb\x25\x39\x6c\x96\xf8\x55\xd0\xec",
+ .expected_ss =
+ "\xf9\x55\x4f\x48\x38\x74\xb7\x46\xa3\xc4\x2e\x88\xf0\x34\xab\x1d"
+ "\xcd\xa5\x58\xa7\x95\x88\x36\x62\x6f\x8a\xbd\xf2\xfb\x6f\x3e\xb9"
+ "\x91\x65\x58\xef\x70\x2f\xd5\xc2\x97\x70\xcb\xce\x8b\x78\x1c\xe0"
+ "\xb9\xfa\x77\x34\xd2\x4a\x19\x58\x11\xfd\x93\x84\x40\xc0\x8c\x19"
+ "\x8b\x98\x50\x83\xba\xfb\xe2\xad\x8b\x81\x84\x63\x90\x41\x4b\xf8"
+ "\xe8\x78\x86\x04\x09\x8d\x84\xd1\x43\xfd\xa3\x58\x21\x2a\x3b\xb1"
+ "\xa2\x5b\x48\x74\x3c\xa9\x16\x34\x28\xf0\x8e\xde\xe2\xcf\x8e\x68"
+ "\x53\xab\x65\x06\xb7\x86\xb1\x08\x4f\x73\x97\x00\x10\x95\xd1\x84"
+ "\x72\xcf\x14\xdb\xff\xa7\x80\xd8\xe5\xf2\x2c\x89\x37\xb0\x81\x2c"
+ "\xf5\xd6\x7d\x1b\xb0\xe2\x8e\x87\x32\x3d\x37\x6a\x79\xaa\xe7\x08"
+ "\xc9\x67\x55\x5f\x1c\xae\xa6\xf5\xef\x79\x3a\xaf\x3f\x82\x14\xe2"
+ "\xf3\x69\x91\xed\xb7\x9e\xc9\xde\xd0\x29\x70\xd9\xeb\x0f\xf5\xc7"
+ "\xf6\x7c\xa7\x7f\xec\xed\xe1\xbd\x13\xe1\x43\xe4\x42\x30\xe3\x5f"
+ "\xe0\xf3\x15\x55\x2f\x7a\x42\x17\x67\xcb\xc2\x4f\xd0\x85\xfc\x6c"
+ "\xec\xe8\xfc\x25\x78\x4b\xe4\x0f\xd4\x3d\x78\x28\xd3\x53\x79\xcb"
+ "\x2c\x82\x67\x9a\xdc\x32\x55\xd2\xda\xae\xd8\x61\xce\xd6\x59\x0b"
+ "\xc5\x44\xeb\x08\x81\x8c\x65\xb2\xb7\xa6\xff\xf7\xbf\x99\xc6\x8a"
+ "\xbe\xde\xc2\x17\x56\x05\x6e\xd2\xf1\x1e\xa2\x04\xeb\x02\x74\xaa"
+ "\x04\xfc\xf0\x6b\xd4\xfc\xf0\x7a\x5f\xfe\xe2\x74\x7f\xeb\x9b\x6a"
+ "\x8a\x09\x96\x5d\xe1\x91\xb6\x9e\x37\xd7\x63\xd7\xb3\x5c\xb5\xa3"
+ "\x5f\x62\x00\xdf\xc5\xbf\x85\xba\xa7\xa9\xb6\x1f\x76\x78\x65\x01"
+ "\xfe\x1d\x6c\xfe\x15\x9e\xf4\xb1\xbc\x8d\xad\x3c\xec\x69\x27\x57"
+ "\xa4\x89\x77\x46\xe1\x49\xc7\x22\xde\x79\xe0\xf7\x3a\xa1\x59\x8b"
+ "\x59\x71\xcc\xd6\x18\x24\xc1\x8a\x2f\xe3\xdf\xdd\x6c\xf7\x62\xaa"
+ "\x15\xaa\x39\x37\x3b\xaf\x7d\x6e\x88\xeb\x19\xa8\xa0\x26\xd3\xaa"
+ "\x2d\xcc\x5f\x56\x99\x86\xa9\xed\x4d\x02\x31\x40\x97\x70\x83\xa7"
+ "\x08\x98\x7e\x49\x46\xd9\x75\xb5\x7a\x6a\x40\x69\xa0\x6d\xb2\x18"
+ "\xc0\xad\x88\x05\x02\x95\x6f\xf7\x8f\xcb\xa2\xe4\x7b\xab\x4a\x0f"
+ "\x9a\x1b\xef\xcc\xd1\x6a\x5d\x1e\x6a\x2a\x8b\x5b\x80\xbc\x5f\x38"
+ "\xdd\xaf\xad\x44\x15\xb4\xaf\x26\x1c\x1a\x4d\xa7\x4b\xec\x88\x33"
+ "\x24\x42\xb5\x0c\x9c\x56\xd4\xba\xa7\xb9\x65\xd5\x76\xb2\xbc\x16"
+ "\x8e\xfa\x0c\x7a\xc0\xa2\x2c\x5a\x39\x56\x7d\xe6\xf8\xa9\xf4\x49"
+ "\xd0\x50\xf2\x5e\x4b\x0a\x43\xe4\x9a\xbb\xea\x35\x28\x99\x84\x83"
+ "\xec\xc1\xa0\x68\x15\x9a\x2b\x01\x04\x48\x09\x11\x1b\xb6\xa4\xd8"
+ "\x03\xad\xb6\x4c\x9e\x1d\x90\xae\x88\x0f\x75\x95\x25\xa0\x27\x13"
+ "\xb7\x4f\xe2\x3e\xd5\x59\x1a\x7c\xde\x95\x14\x28\xd1\xde\x84\xe4"
+ "\x07\x7c\x5b\x06\xd6\xe6\x9c\x8a\xbe\xd2\xb4\x62\xd1\x67\x8a\x9c"
+ "\xac\x4f\xfa\x70\xd6\xc8\xc0\xeb\x5e\xf6\x3e\xdc\x48\x8e\xce\x3f"
+ "\x92\x3e\x60\x77\x63\x60\x6b\x76\x04\xa5\xba\xc9\xab\x92\x4e\x0d"
+ "\xdc\xca\x82\x44\x5f\x3a\x42\xeb\x01\xe7\xe0\x33\xb3\x32\xaf\x4b"
+ "\x81\x35\x2d\xb6\x57\x15\xfe\x52\xc7\x54\x2e\x41\x3b\x22\x6b\x12"
+ "\x72\xdb\x5c\x66\xd0\xb6\xb4\xfe\x90\xc0\x20\x34\x95\xf9\xe4\xc7"
+ "\x7e\x71\x89\x4f\x6f\xfb\x2a\xf3\xdf\x3f\xe3\xcf\x0e\x1a\xd9\xf2"
+ "\xc1\x02\x67\x5d\xdc\xf1\x7d\xe8\xcf\x64\x77\x4d\x12\x03\x77\x2c"
+ "\xfb\xe1\x59\xf7\x2c\x96\x9c\xaf\x46\x9c\xc7\x67\xcf\xee\x94\x50"
+ "\xc7\xa1\x23\xe6\x9f\x4d\x73\x92\xad\xf9\x4a\xce\xdb\x44\xd5\xe3"
+ "\x17\x05\x37\xdb\x9c\x6c\xc5\x7e\xb7\xd4\x11\x4a\x8c\x51\x03\xaa"
+ "\x73\x4b\x16\xd9\x79\xf5\xf1\x67\x20\x9b\x25\xe5\x41\x52\x59\x06"
+ "\x8b\xf2\x23\x2f\x6e\xea\xf3\x24\x0a\x94\xbb\xb8\x7e\xd9\x23\x4a"
+ "\x9f\x1f\xe1\x13\xb5\xfe\x85\x2f\x4c\xbe\x6a\x66\x02\x1d\x90\xd2"
+ "\x01\x25\x8a\xfd\x78\x3a\x28\xb8\x18\xc1\x38\x16\x21\x6b\xb4\xf9"
+ "\x64\x0f\xf1\x73\xc4\x5c\xd1\x41\xf2\xfe\xe7\x26\xad\x79\x12\x75"
+ "\x49\x48\xdb\x21\x71\x35\xf7\xb7\x46\x5a\xa1\x81\x25\x47\x31\xea"
+ "\x1d\x76\xbb\x32\x5a\x90\xb0\x42\x1a\x47\xe8\x0c\x82\x92\x43\x1c"
+ "\x0b\xdd\xe5\x25\xce\xd3\x06\xcc\x59\x5a\xc9\xa0\x01\xac\x29\x12"
+ "\x31\x2e\x3d\x1a\xed\x3b\xf3\xa7\xef\x52\xc2\x0d\x18\x1f\x03\x28"
+ "\xc9\x2b\x38\x61\xa4\x01\xc9\x3c\x11\x08\x14\xd4\xe5\x31\xe9\x3c"
+ "\x1d\xad\xf8\x76\xc4\x84\x9f\xea\x16\x61\x3d\x6d\xa3\x32\x31\xcd"
+ "\x1c\xca\xb8\x74\xc2\x45\xf3\x01\x9c\x7a\xaf\xfd\xe7\x1e\x5a\x18"
+ "\xb1\x9d\xbb\x7a\x2d\x34\x40\x17\x49\xad\x1f\xeb\x2d\xa2\x26\xb8"
+ "\x16\x28\x4b\x72\xdd\xd0\x8d\x85\x4c\xdd\xf8\x57\x48\xd5\x1d\xfb"
+ "\xbd\xec\x11\x5d\x1e\x9c\x26\x81\xbf\xf1\x16\x12\x32\xc3\xf3\x07"
+ "\x0e\x6e\x7f\x17\xec\xfb\xf4\x5d\xe2\xb1\xca\x97\xca\x46\x20\x2d"
+ "\x09\x85\x19\x25\x89\xa8\x9b\x51\x74\xae\xc9\x1b\x4c\xb6\x80\x62",
+ .secret_size = 1040,
+ .b_public_size = 1024,
+ .expected_a_public_size = 1024,
+ .expected_ss_size = 1024,
+ },
+ {
+ .secret =
+#ifdef __LITTLE_ENDIAN
+ "\x01\x00" /* type */
+ "\x10\x00" /* len */
+ "\x00\x00\x00\x00" /* key_size */
+ "\x00\x00\x00\x00" /* p_size */
+ "\x00\x00\x00\x00", /* g_size */
+#else
+ "\x00\x01" /* type */
+ "\x00\x10" /* len */
+ "\x00\x00\x00\x00" /* key_size */
+ "\x00\x00\x00\x00" /* p_size */
+ "\x00\x00\x00\x00", /* g_size */
+#endif
+ .b_secret =
+#ifdef __LITTLE_ENDIAN
+ "\x01\x00" /* type */
+ "\x10\x04" /* len */
+ "\x00\x04\x00\x00" /* key_size */
+ "\x00\x00\x00\x00" /* p_size */
+ "\x00\x00\x00\x00" /* g_size */
+#else
+ "\x00\x01" /* type */
+ "\x04\x10" /* len */
+ "\x00\x00\x04\x00" /* key_size */
+ "\x00\x00\x00\x00" /* p_size */
+ "\x00\x00\x00\x00" /* g_size */
+#endif
+ /* xa */
+ "\x76\x6e\xeb\xf9\xeb\x76\xae\x37\xcb\x19\x49\x8b\xeb\xaf\xb0\x4b"
+ "\x6d\xe9\x15\xad\xda\xf2\xef\x58\xe9\xd6\xdd\x4c\xb3\x56\xd0\x3b"
+ "\x00\xb0\x65\xed\xae\xe0\x2e\xdf\x8f\x45\x3f\x3c\x5d\x2f\xfa\x96"
+ "\x36\x33\xb2\x01\x8b\x0f\xe8\x46\x15\x6d\x60\x5b\xec\x32\xc3\x3b"
+ "\x06\xf3\xb4\x1b\x9a\xef\x3c\x03\x0e\xcc\xce\x1d\x24\xa0\xc9\x08"
+ "\x65\xf9\x45\xe5\xd2\x43\x08\x88\x58\xd6\x46\xe7\xbb\x25\xac\xed"
+ "\x3b\xac\x6f\x5e\xfb\xd6\x19\xa6\x20\x3a\x1d\x0c\xe8\x00\x72\x54"
+ "\xd7\xd9\xc9\x26\x49\x18\xc6\xb8\xbc\xdd\xf3\xce\xf3\x7b\x69\x04"
+ "\x5c\x6f\x11\xdb\x44\x42\x72\xb6\xb7\x84\x17\x86\x47\x3f\xc5\xa1"
+ "\xd8\x86\xef\xe2\x27\x49\x2b\x8f\x3e\x91\x12\xd9\x45\x96\xf7\xe6"
+ "\x77\x76\x36\x58\x71\x9a\xb1\xdb\xcf\x24\x9e\x7e\xad\xce\x45\xba"
+ "\xb5\xec\x8e\xb9\xd6\x7b\x3d\x76\xa4\x85\xad\xd8\x49\x9b\x80\x9d"
+ "\x7f\x9f\x85\x09\x9e\x86\x5b\x6b\xf3\x8d\x39\x5e\x6f\xe4\x30\xc8"
+ "\xa5\xf3\xdf\x68\x73\x6b\x2e\x9a\xcb\xac\x0a\x0d\x44\xc1\xaf\xb2"
+ "\x11\x1b\x7c\x43\x08\x44\x43\xe2\x4e\xfd\x93\x30\x99\x09\x12\xbb"
+ "\xf6\x31\x34\xa5\x3d\x45\x98\xee\xd7\x2a\x1a\x89\xf5\x37\x92\x33"
+ "\xa0\xdd\xf5\xfb\x1f\x90\x42\x55\x5a\x0b\x82\xff\xf0\x96\x92\x15"
+ "\x65\x5a\x55\x96\xca\x1b\xd5\xe5\xb5\x94\xde\x2e\xa6\x03\x57\x9e"
+ "\x15\xe4\x32\x2b\x1f\xb2\x22\x21\xe9\xa0\x05\xd3\x65\x6c\x11\x66"
+ "\x25\x38\xbb\xa3\x6c\xc2\x0b\x2b\xd0\x7a\x20\x26\x29\x37\x5d\x5f"
+ "\xd8\xff\x2a\xcd\x46\x6c\xd6\x6e\xe5\x77\x1a\xe6\x33\xf1\x8e\xc8"
+ "\x10\x30\x11\x00\x27\xf9\x7d\x0e\x28\x43\xa7\x67\x38\x7f\x16\xda"
+ "\xd0\x01\x8e\xa4\xe8\x6f\xcd\x23\xaf\x77\x52\x34\xad\x7e\xc3\xed"
+ "\x2d\x10\x0a\x33\xdc\xcf\x1b\x88\x0f\xcc\x48\x7f\x42\xf0\x9e\x13"
+ "\x1f\xf5\xd1\xe9\x90\x87\xbd\xfa\x5f\x1d\x77\x55\xcb\xc3\x05\xaf"
+ "\x71\xd0\xe0\xab\x46\x31\xd7\xea\x89\x54\x2d\x39\xaf\xf6\x4f\x74"
+ "\xaf\x46\x58\x89\x78\x95\x2e\xe6\x90\xb7\xaa\x00\x73\x9f\xed\xb9"
+ "\x00\xd6\xf6\x6d\x26\x59\xcd\x56\xdb\xf7\x3d\x5f\xeb\x6e\x46\x33"
+ "\xb1\x23\xed\x9f\x8d\x58\xdc\xb4\x28\x3b\x90\x09\xc4\x61\x02\x1f"
+ "\xf8\x62\xf2\x6e\xc1\x94\x71\x66\x93\x11\xdf\xaa\x3e\xd7\xb5\xe5"
+ "\xc1\x78\xe9\x14\xcd\x55\x16\x51\xdf\x8d\xd0\x94\x8c\x43\xe9\xb8"
+ "\x1d\x42\x7f\x76\xbc\x6f\x87\x42\x88\xde\xd7\x52\x78\x00\x4f\x18"
+ "\x02\xe7\x7b\xe2\x8a\xc3\xd1\x43\xa5\xac\xda\xb0\x8d\x19\x96\xd4"
+ "\x81\xe0\x75\xe9\xca\x41\x7e\x1f\x93\x0b\x26\x24\xb3\xaa\xdd\x10"
+ "\x20\xd3\xf2\x9f\x3f\xdf\x65\xde\x67\x79\xdc\x76\x9f\x3c\x72\x75"
+ "\x65\x8a\x30\xcc\xd2\xcc\x06\xb1\xab\x62\x86\x78\x5d\xb8\xce\x72"
+ "\xb3\x12\xc7\x9f\x07\xd0\x6b\x98\x82\x9b\x6c\xbb\x15\xe5\xcc\xf4"
+ "\xc8\xf4\x60\x81\xdc\xd3\x09\x1b\x5e\xd4\xf3\x55\xcf\x1c\x16\x83"
+ "\x61\xb4\x2e\xcc\x08\x67\x58\xfd\x46\x64\xbc\x29\x4b\xdd\xda\xec"
+ "\xdc\xc6\xa9\xa5\x73\xfb\xf8\xf3\xaf\x89\xa8\x9e\x25\x14\xfa\xac"
+ "\xeb\x1c\x7c\x80\x96\x66\x4d\x41\x67\x9b\x07\x4f\x0a\x97\x17\x1c"
+ "\x4d\x61\xc7\x2e\x6f\x36\x98\x29\x50\x39\x6d\xe7\x70\xda\xf0\xc8"
+ "\x05\x80\x7b\x32\xff\xfd\x12\xde\x61\x0d\xf9\x4c\x21\xf1\x56\x72"
+ "\x3d\x61\x46\xc0\x2d\x07\xd1\x6c\xd3\xbe\x9a\x21\x83\x85\xf7\xed"
+ "\x53\x95\x44\x40\x8f\x75\x12\x18\xc2\x9a\xfd\x5e\xce\x66\xa6\x7f"
+ "\x57\xc0\xd7\x73\x76\xb3\x13\xda\x2e\x58\xc6\x27\x40\xb2\x2d\xef"
+ "\x7d\x72\xb4\xa8\x75\x6f\xcc\x5f\x42\x3e\x2c\x90\x36\x59\xa0\x34"
+ "\xaa\xce\xbc\x04\x4c\xe6\x56\xc2\xcd\xa6\x1c\x59\x04\x56\x53\xcf"
+ "\x6d\xd7\xf0\xb1\x4f\x91\xfa\x84\xcf\x4b\x8d\x50\x4c\xf8\x2a\x31"
+ "\x5f\xe3\xba\x79\xb4\xcc\x59\x64\xe3\x7a\xfa\xf6\x06\x9d\x04\xbb"
+ "\xce\x61\xbf\x9e\x59\x0a\x09\x51\x6a\xbb\x0b\x80\xe0\x91\xc1\x51"
+ "\x04\x58\x67\x67\x4b\x42\x4f\x95\x68\x75\xe2\x1f\x9c\x14\x70\xfd"
+ "\x3a\x8a\xce\x8b\x04\xa1\x89\xe7\xb4\xbf\x70\xfe\xf3\x0c\x48\x04"
+ "\x3a\xd2\x85\x68\x03\xe7\xfa\xec\x5b\x55\xb7\x95\xfd\x5b\x19\x35"
+ "\xad\xcb\x4a\x63\x03\x44\x64\x2a\x48\x59\x9a\x26\x43\x96\x8c\xe6"
+ "\xbd\xb7\x90\xd4\x5f\x8d\x08\x28\xa8\xc5\x89\x70\xb9\x6e\xd3\x3b"
+ "\x76\x0e\x37\x98\x15\x27\xca\xc9\xb0\xe0\xfd\xf3\xc6\xdf\x69\xce"
+ "\xe1\x5f\x6a\x3e\x5c\x86\xe2\x58\x41\x11\xf0\x7e\x56\xec\xe4\xc9"
+ "\x0d\x87\x91\xfb\xb9\xc8\x0d\x34\xab\xb0\xc6\xf2\xa6\x00\x7b\x18"
+ "\x92\xf4\x43\x7f\x01\x85\x2e\xef\x8c\x72\x50\x10\xdb\xf1\x37\x62"
+ "\x16\x85\x71\x01\xa8\x2b\xf0\x13\xd3\x7c\x0b\xaf\xf1\xf3\xd1\xee"
+ "\x90\x41\x5f\x7d\x5b\xa9\x83\x4b\xfa\x80\x59\x50\x73\xe1\xc4\xf9"
+ "\x5e\x4b\xde\xd9\xf5\x22\x68\x5e\x65\xd9\x37\xe4\x1a\x08\x0e\xb1"
+ "\x28\x2f\x40\x9e\x37\xa8\x12\x56\xb7\xb8\x64\x94\x68\x94\xff\x9f",
+ .b_public =
+ "\xa1\x6c\x9e\xda\x45\x4d\xf6\x59\x04\x00\xc1\xc6\x8b\x12\x3b\xcd"
+ "\x07\xe4\x3e\xec\xac\x9b\xfc\xf7\x6d\x73\x39\x9e\x52\xf8\xbe\x33"
+ "\xe2\xca\xea\x99\x76\xc7\xc9\x94\x5c\xf3\x1b\xea\x6b\x66\x4b\x51"
+ "\x90\xf6\x4f\x75\xd5\x85\xf4\x28\xfd\x74\xa5\x57\xb1\x71\x0c\xb6"
+ "\xb6\x95\x70\x2d\xfa\x4b\x56\xe0\x56\x10\x21\xe5\x60\xa6\x18\xa4"
+ "\x78\x8c\x07\xc0\x2b\x59\x9c\x84\x5b\xe9\xb9\x74\xbf\xbc\x65\x48"
+ "\x27\x82\x40\x53\x46\x32\xa2\x92\x91\x9d\xf6\xd1\x07\x0e\x1d\x07"
+ "\x1b\x41\x04\xb1\xd4\xce\xae\x6e\x46\xf1\x72\x50\x7f\xff\xa8\xa2"
+ "\xbc\x3a\xc1\xbb\x28\xd7\x7d\xcd\x7a\x22\x01\xaf\x57\xb0\xa9\x02"
+ "\xd4\x8a\x92\xd5\xe6\x8e\x6f\x11\x39\xfe\x36\x87\x89\x42\x25\x42"
+ "\xd9\xbe\x67\x15\xe1\x82\x8a\x5e\x98\xc2\xd5\xde\x9e\x13\x1a\xe7"
+ "\xf9\x9f\x8e\x2d\x49\xdc\x4d\x98\x8c\xdd\xfd\x24\x7c\x46\xa9\x69"
+ "\x3b\x31\xb3\x12\xce\x54\xf6\x65\x75\x40\xc2\xf1\x04\x92\xe3\x83"
+ "\xeb\x02\x3d\x79\xc0\xf9\x7c\x28\xb3\x97\x03\xf7\x61\x1c\xce\x95"
+ "\x1a\xa0\xb3\x77\x1b\xc1\x9f\xf8\xf6\x3f\x4d\x0a\xfb\xfa\x64\x1c"
+ "\xcb\x37\x5b\xc3\x28\x60\x9f\xd1\xf2\xc4\xee\x77\xaa\x1f\xe9\xa2"
+ "\x89\x4c\xc6\xb7\xb3\xe4\xa5\xed\xa7\xe8\xac\x90\xdc\xc3\xfb\x56"
+ "\x9c\xda\x2c\x1d\x1a\x9a\x8c\x82\x92\xee\xdc\xa0\xa4\x01\x6e\x7f"
+ "\xc7\x0e\xc2\x73\x7d\xa6\xac\x12\x01\xc0\xc0\xc8\x7c\x84\x86\xc7"
+ "\xa5\x94\xe5\x33\x84\x71\x6e\x36\xe3\x3b\x81\x30\xe0\xc8\x51\x52"
+ "\x2b\x9e\x68\xa2\x6e\x09\x95\x8c\x7f\x78\x82\xbd\x53\x26\xe7\x95"
+ "\xe0\x03\xda\xc0\xc3\x6e\xcf\xdc\xb3\x14\xfc\xe9\x5b\x9b\x70\x6c"
+ "\x93\x04\xab\x13\xf7\x17\x6d\xee\xad\x32\x48\xe9\xa0\x94\x1b\x14"
+ "\x64\x4f\xa1\xb3\x8d\x6a\xca\x28\xfe\x4a\xf4\xf0\xc5\xb7\xf9\x8a"
+ "\x8e\xff\xfe\x57\x6f\x20\xdb\x04\xab\x02\x31\x22\x42\xfd\xbd\x77"
+ "\xea\xce\xe8\xc7\x5d\xe0\x8e\xd6\x66\xd0\xe4\x04\x2f\x5f\x71\xc7"
+ "\x61\x2d\xa5\x3f\x2f\x46\xf2\xd8\x5b\x25\x82\xf0\x52\x88\xc0\x59"
+ "\xd3\xa3\x90\x17\xc2\x04\x13\xc3\x13\x69\x4f\x17\xb1\xb3\x46\x4f"
+ "\xa7\xe6\x8b\x5e\x3e\x95\x0e\xf5\x42\x17\x7f\x4d\x1f\x1b\x7d\x65"
+ "\x86\xc5\xc8\xae\xae\xd8\x4f\xe7\x89\x41\x69\xfd\x06\xce\x5d\xed"
+ "\x44\x55\xad\x51\x98\x15\x78\x8d\x68\xfc\x93\x72\x9d\x22\xe5\x1d"
+ "\x21\xc3\xbe\x3a\x44\x34\xc0\xa3\x1f\xca\xdf\x45\xd0\x5c\xcd\xb7"
+ "\x72\xeb\xae\x7a\xad\x3f\x05\xa0\xe3\x6e\x5a\xd8\x52\xa7\xf1\x1e"
+ "\xb4\xf2\xcf\xe7\xdf\xa7\xf2\x22\x00\xb2\xc4\x17\x3d\x2c\x15\x04"
+ "\x71\x28\x69\x5c\x69\x21\xc8\xf1\x9b\xd8\xc7\xbc\x27\xa3\x85\xe9"
+ "\x53\x77\xd3\x65\xc3\x86\xdd\xb3\x76\x13\xfb\xa1\xd4\xee\x9d\xe4"
+ "\x51\x3f\x83\x59\xe4\x47\xa8\xa6\x0d\x68\xd5\xf6\xf4\xca\x31\xcd"
+ "\x30\x48\x34\x90\x11\x8e\x87\xe9\xea\xc9\xd0\xc3\xba\x28\xf9\xc0"
+ "\xc9\x8e\x23\xe5\xc2\xee\xf2\x47\x9c\x41\x1c\x10\x33\x27\x23\x49"
+ "\xe5\x0d\x18\xbe\x19\xc1\xba\x6c\xdc\xb7\xa1\xe7\xc5\x0d\x6f\xf0"
+ "\x8c\x62\x6e\x0d\x14\xef\xef\xf2\x8e\x01\xd2\x76\xf5\xc1\xe1\x92"
+ "\x3c\xb3\x76\xcd\xd8\xdd\x9b\xe0\x8e\xdc\x24\x34\x13\x65\x0f\x11"
+ "\xaf\x99\x7a\x2f\xe6\x1f\x7d\x17\x3e\x8a\x68\x9a\x37\xc8\x8d\x3e"
+ "\xa3\xfe\xfe\x57\x22\xe6\x0e\x50\xb5\x98\x0b\x71\xd8\x01\xa2\x8d"
+ "\x51\x96\x50\xc2\x41\x31\xd8\x23\x98\xfc\xd1\x9d\x7e\x27\xbb\x69"
+ "\x78\xe0\x87\xf7\xe4\xdd\x58\x13\x9d\xec\x00\xe4\xb9\x70\xa2\x94"
+ "\x5d\x52\x4e\xf2\x5c\xd1\xbc\xfd\xee\x9b\xb9\xe5\xc4\xc0\xa8\x77"
+ "\x67\xa4\xd1\x95\x34\xe4\x6d\x5f\x25\x02\x8d\x65\xdd\x11\x63\x55"
+ "\x04\x01\x21\x60\xc1\x5c\xef\x77\x33\x01\x1c\xa2\x11\x2b\xdd\x2b"
+ "\x74\x99\x23\x38\x05\x1b\x7e\x2e\x01\x52\xfe\x9c\x23\xde\x3e\x1a"
+ "\x72\xf4\xff\x7b\x02\xaa\x08\xcf\xe0\x5b\x83\xbe\x85\x5a\xe8\x9d"
+ "\x11\x3e\xff\x2f\xc6\x97\x67\x36\x6c\x0f\x81\x9c\x26\x29\xb1\x0f"
+ "\xbb\x53\xbd\xf4\xec\x2a\x84\x41\x28\x3b\x86\x40\x95\x69\x55\x5f"
+ "\x30\xee\xda\x1e\x6c\x4b\x25\xd6\x2f\x2c\x0e\x3c\x1a\x26\xa0\x3e"
+ "\xef\x09\xc6\x2b\xe5\xa1\x0c\x03\xa8\xf5\x39\x70\x31\xc4\x32\x79"
+ "\xd1\xd9\xc2\xcc\x32\x4a\xf1\x2f\x57\x5a\xcc\xe5\xc3\xc5\xd5\x4e"
+ "\x86\x56\xca\x64\xdb\xab\x61\x85\x8f\xf9\x20\x02\x40\x66\x76\x9e"
+ "\x5e\xd4\xac\xf0\x47\xa6\x50\x5f\xc2\xaf\x55\x9b\xa3\xc9\x8b\xf8"
+ "\x42\xd5\xcf\x1a\x95\x22\xd9\xd1\x0b\x92\x51\xca\xde\x46\x02\x0d"
+ "\x8b\xee\xd9\xa0\x04\x74\xf5\x0e\xb0\x3a\x62\xec\x3c\x91\x29\x33"
+ "\xa7\x78\x22\x92\xac\x27\xe6\x2d\x6f\x56\x8a\x5d\x72\xc2\xf1\x5c"
+ "\x54\x11\x97\x24\x61\xcb\x0c\x52\xd4\x57\x56\x22\x86\xf0\x19\x27"
+ "\x76\x30\x04\xf4\x39\x7b\x1a\x5a\x04\x0d\xec\x59\x9a\x31\x4c\x40"
+ "\x19\x6d\x3c\x41\x1b\x0c\xca\xeb\x25\x39\x6c\x96\xf8\x55\xd0\xec",
+ .secret_size = 16,
+ .b_secret_size = 1040,
+ .b_public_size = 1024,
+ .expected_a_public_size = 1024,
+ .expected_ss_size = 1024,
+ .genkey = true,
+ },
+};
+
static const struct kpp_testvec curve25519_tv_template[] = {
{
.secret = (u8[32]){ 0x77, 0x07, 0x6d, 0x0a, 0x73, 0x18, 0xa5, 0x7d,
@@ -5713,6 +7140,7 @@ static const struct hash_testvec hmac_sha1_tv_template[] = {
.psize = 28,
.digest = "\xef\xfc\xdf\x6a\xe5\xeb\x2f\xa2\xd2\x74"
"\x16\xd5\xf1\x84\xdf\x9c\x25\x9a\x7c\x79",
+ .fips_skip = 1,
}, {
.key = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa",
.ksize = 20,
@@ -5802,6 +7230,7 @@ static const struct hash_testvec hmac_sha224_tv_template[] = {
"\x45\x69\x0f\x3a\x7e\x9e\x6d\x0f"
"\x8b\xbe\xa2\xa3\x9e\x61\x48\x00"
"\x8f\xd0\x5e\x44",
+ .fips_skip = 1,
}, {
.key = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
@@ -5945,6 +7374,7 @@ static const struct hash_testvec hmac_sha256_tv_template[] = {
"\x6a\x04\x24\x26\x08\x95\x75\xc7"
"\x5a\x00\x3f\x08\x9d\x27\x39\x83"
"\x9d\xec\x58\xb9\x64\xec\x38\x43",
+ .fips_skip = 1,
}, {
.key = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
@@ -6443,6 +7873,7 @@ static const struct hash_testvec hmac_sha384_tv_template[] = {
"\xe4\x2e\xc3\x73\x63\x22\x44\x5e"
"\x8e\x22\x40\xca\x5e\x69\xe2\xc7"
"\x8b\x32\x39\xec\xfa\xb2\x16\x49",
+ .fips_skip = 1,
}, {
.key = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
@@ -6543,6 +7974,7 @@ static const struct hash_testvec hmac_sha512_tv_template[] = {
"\x6d\x03\x4f\x65\xf8\xf0\xe6\xfd"
"\xca\xea\xb1\xa3\x4d\x4a\x6b\x4b"
"\x63\x6e\x07\x0a\x38\xbc\xe7\x37",
+ .fips_skip = 1,
}, {
.key = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
@@ -6638,6 +8070,7 @@ static const struct hash_testvec hmac_sha3_224_tv_template[] = {
"\x1b\x79\x86\x34\xad\x38\x68\x11"
"\xc2\xcf\xc8\x5b\xfa\xf5\xd5\x2b"
"\xba\xce\x5e\x66",
+ .fips_skip = 1,
}, {
.key = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
@@ -6725,6 +8158,7 @@ static const struct hash_testvec hmac_sha3_256_tv_template[] = {
"\x35\x96\xbb\xb0\xda\x73\xb8\x87"
"\xc9\x17\x1f\x93\x09\x5b\x29\x4a"
"\xe8\x57\xfb\xe2\x64\x5e\x1b\xa5",
+ .fips_skip = 1,
}, {
.key = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
@@ -6816,6 +8250,7 @@ static const struct hash_testvec hmac_sha3_384_tv_template[] = {
"\x3c\xa1\x35\x08\xa9\x32\x43\xce"
"\x48\xc0\x45\xdc\x00\x7f\x26\xa2"
"\x1b\x3f\x5e\x0e\x9d\xf4\xc2\x0a",
+ .fips_skip = 1,
}, {
.key = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
@@ -6915,6 +8350,7 @@ static const struct hash_testvec hmac_sha3_512_tv_template[] = {
"\xee\x7a\x0c\x31\xd0\x22\xa9\x5e"
"\x1f\xc9\x2b\xa9\xd7\x7d\xf8\x83"
"\x96\x02\x75\xbe\xb4\xe6\x20\x24",
+ .fips_skip = 1,
}, {
.key = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
diff --git a/crypto/xts.c b/crypto/xts.c
index 6c12f30dbdd6..63c85b9e64e0 100644
--- a/crypto/xts.c
+++ b/crypto/xts.c
@@ -466,3 +466,4 @@ MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("XTS block cipher mode");
MODULE_ALIAS_CRYPTO("xts");
MODULE_IMPORT_NS(CRYPTO_INTERNAL);
+MODULE_SOFTDEP("pre: ecb");
diff --git a/drivers/accessibility/speakup/speakup_dectlk.c b/drivers/accessibility/speakup/speakup_dectlk.c
index 580ec796816b..78ca4987e619 100644
--- a/drivers/accessibility/speakup/speakup_dectlk.c
+++ b/drivers/accessibility/speakup/speakup_dectlk.c
@@ -44,6 +44,7 @@ static struct var_t vars[] = {
{ CAPS_START, .u.s = {"[:dv ap 160] " } },
{ CAPS_STOP, .u.s = {"[:dv ap 100 ] " } },
{ RATE, .u.n = {"[:ra %d] ", 180, 75, 650, 0, 0, NULL } },
+ { PITCH, .u.n = {"[:dv ap %d] ", 122, 50, 350, 0, 0, NULL } },
{ INFLECTION, .u.n = {"[:dv pr %d] ", 100, 0, 10000, 0, 0, NULL } },
{ VOL, .u.n = {"[:dv g5 %d] ", 86, 60, 86, 0, 0, NULL } },
{ PUNCT, .u.n = {"[:pu %c] ", 0, 0, 2, 0, 0, "nsa" } },
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
index ba45541b1f1f..1e34f846508f 100644
--- a/drivers/acpi/Kconfig
+++ b/drivers/acpi/Kconfig
@@ -11,6 +11,7 @@ menuconfig ACPI
depends on ARCH_SUPPORTS_ACPI
select PNP
select NLS
+ select CRC32
default y if X86
help
Advanced Configuration and Power Interface (ACPI) support for
@@ -301,7 +302,7 @@ config ACPI_IPMI
help
This driver enables the ACPI to access the BMC controller. And it
uses the IPMI request/response message to communicate with BMC
- controller, which can be found on on the server.
+ controller, which can be found on the server.
To compile this driver as a module, choose M here:
the module will be called as acpi_ipmi.
diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile
index bb757148e7ba..b5a8d3e00a52 100644
--- a/drivers/acpi/Makefile
+++ b/drivers/acpi/Makefile
@@ -81,6 +81,9 @@ obj-$(CONFIG_ACPI_AC) += ac.o
obj-$(CONFIG_ACPI_BUTTON) += button.o
obj-$(CONFIG_ACPI_TINY_POWER_BUTTON) += tiny-power-button.o
obj-$(CONFIG_ACPI_FAN) += fan.o
+fan-objs := fan_core.o
+fan-objs += fan_attr.o
+
obj-$(CONFIG_ACPI_VIDEO) += video.o
obj-$(CONFIG_ACPI_TAD) += acpi_tad.o
obj-$(CONFIG_ACPI_PCI_SLOT) += pci_slot.o
diff --git a/drivers/acpi/acpi_lpss.c b/drivers/acpi/acpi_lpss.c
index bcae0f03572b..fbe0756259c5 100644
--- a/drivers/acpi/acpi_lpss.c
+++ b/drivers/acpi/acpi_lpss.c
@@ -21,6 +21,7 @@
#include <linux/pm_domain.h>
#include <linux/pm_runtime.h>
#include <linux/pwm.h>
+#include <linux/pxa2xx_ssp.h>
#include <linux/suspend.h>
#include <linux/delay.h>
@@ -82,7 +83,7 @@ struct lpss_device_desc {
const char *clk_con_id;
unsigned int prv_offset;
size_t prv_size_override;
- struct property_entry *properties;
+ const struct property_entry *properties;
void (*setup)(struct lpss_private_data *pdata);
bool resume_from_noirq;
};
@@ -219,10 +220,16 @@ static void bsw_pwm_setup(struct lpss_private_data *pdata)
pwm_add_table(bsw_pwm_lookup, ARRAY_SIZE(bsw_pwm_lookup));
}
-static const struct lpss_device_desc lpt_dev_desc = {
+static const struct property_entry lpt_spi_properties[] = {
+ PROPERTY_ENTRY_U32("intel,spi-pxa2xx-type", LPSS_LPT_SSP),
+ { }
+};
+
+static const struct lpss_device_desc lpt_spi_dev_desc = {
.flags = LPSS_CLK | LPSS_CLK_GATE | LPSS_CLK_DIVIDER | LPSS_LTR
| LPSS_SAVE_CTX,
.prv_offset = 0x800,
+ .properties = lpt_spi_properties,
};
static const struct lpss_device_desc lpt_i2c_dev_desc = {
@@ -282,9 +289,15 @@ static const struct lpss_device_desc bsw_uart_dev_desc = {
.properties = uart_properties,
};
+static const struct property_entry byt_spi_properties[] = {
+ PROPERTY_ENTRY_U32("intel,spi-pxa2xx-type", LPSS_BYT_SSP),
+ { }
+};
+
static const struct lpss_device_desc byt_spi_dev_desc = {
.flags = LPSS_CLK | LPSS_CLK_GATE | LPSS_CLK_DIVIDER | LPSS_SAVE_CTX,
.prv_offset = 0x400,
+ .properties = byt_spi_properties,
};
static const struct lpss_device_desc byt_sdio_dev_desc = {
@@ -305,11 +318,17 @@ static const struct lpss_device_desc bsw_i2c_dev_desc = {
.resume_from_noirq = true,
};
+static const struct property_entry bsw_spi_properties[] = {
+ PROPERTY_ENTRY_U32("intel,spi-pxa2xx-type", LPSS_BSW_SSP),
+ { }
+};
+
static const struct lpss_device_desc bsw_spi_dev_desc = {
.flags = LPSS_CLK | LPSS_CLK_GATE | LPSS_CLK_DIVIDER | LPSS_SAVE_CTX
| LPSS_NO_D3_DELAY,
.prv_offset = 0x400,
.setup = lpss_deassert_reset,
+ .properties = bsw_spi_properties,
};
static const struct x86_cpu_id lpss_cpu_ids[] = {
@@ -329,8 +348,8 @@ static const struct acpi_device_id acpi_lpss_device_ids[] = {
{ "INTL9C60", LPSS_ADDR(lpss_dma_desc) },
/* Lynxpoint LPSS devices */
- { "INT33C0", LPSS_ADDR(lpt_dev_desc) },
- { "INT33C1", LPSS_ADDR(lpt_dev_desc) },
+ { "INT33C0", LPSS_ADDR(lpt_spi_dev_desc) },
+ { "INT33C1", LPSS_ADDR(lpt_spi_dev_desc) },
{ "INT33C2", LPSS_ADDR(lpt_i2c_dev_desc) },
{ "INT33C3", LPSS_ADDR(lpt_i2c_dev_desc) },
{ "INT33C4", LPSS_ADDR(lpt_uart_dev_desc) },
@@ -356,8 +375,8 @@ static const struct acpi_device_id acpi_lpss_device_ids[] = {
{ "808622C1", LPSS_ADDR(bsw_i2c_dev_desc) },
/* Broadwell LPSS devices */
- { "INT3430", LPSS_ADDR(lpt_dev_desc) },
- { "INT3431", LPSS_ADDR(lpt_dev_desc) },
+ { "INT3430", LPSS_ADDR(lpt_spi_dev_desc) },
+ { "INT3431", LPSS_ADDR(lpt_spi_dev_desc) },
{ "INT3432", LPSS_ADDR(lpt_i2c_dev_desc) },
{ "INT3433", LPSS_ADDR(lpt_i2c_dev_desc) },
{ "INT3434", LPSS_ADDR(lpt_uart_dev_desc) },
@@ -366,7 +385,7 @@ static const struct acpi_device_id acpi_lpss_device_ids[] = {
{ "INT3437", },
/* Wildcat Point LPSS devices */
- { "INT3438", LPSS_ADDR(lpt_dev_desc) },
+ { "INT3438", LPSS_ADDR(lpt_spi_dev_desc) },
{ }
};
diff --git a/drivers/acpi/acpi_platform.c b/drivers/acpi/acpi_platform.c
index 78d621290a35..de3cbf152dee 100644
--- a/drivers/acpi/acpi_platform.c
+++ b/drivers/acpi/acpi_platform.c
@@ -95,7 +95,7 @@ static void acpi_platform_fill_resource(struct acpi_device *adev,
* Name of the platform device will be the same as @adev's.
*/
struct platform_device *acpi_create_platform_device(struct acpi_device *adev,
- struct property_entry *properties)
+ const struct property_entry *properties)
{
struct platform_device *pdev = NULL;
struct platform_device_info pdevinfo;
diff --git a/drivers/acpi/acpica/nswalk.c b/drivers/acpi/acpica/nswalk.c
index 915c2433463d..e7c30ce06e18 100644
--- a/drivers/acpi/acpica/nswalk.c
+++ b/drivers/acpi/acpica/nswalk.c
@@ -169,6 +169,9 @@ acpi_ns_walk_namespace(acpi_object_type type,
if (start_node == ACPI_ROOT_OBJECT) {
start_node = acpi_gbl_root_node;
+ if (!start_node) {
+ return_ACPI_STATUS(AE_NO_NAMESPACE);
+ }
}
/* Null child means "get first node" */
diff --git a/drivers/acpi/apei/bert.c b/drivers/acpi/apei/bert.c
index 19e50fcbf4d6..598fd19b65fa 100644
--- a/drivers/acpi/apei/bert.c
+++ b/drivers/acpi/apei/bert.c
@@ -29,6 +29,7 @@
#undef pr_fmt
#define pr_fmt(fmt) "BERT: " fmt
+#define ACPI_BERT_PRINT_MAX_LEN 1024
static int bert_disable;
@@ -58,8 +59,11 @@ static void __init bert_print_all(struct acpi_bert_region *region,
}
pr_info_once("Error records from previous boot:\n");
-
- cper_estatus_print(KERN_INFO HW_ERR, estatus);
+ if (region_len < ACPI_BERT_PRINT_MAX_LEN)
+ cper_estatus_print(KERN_INFO HW_ERR, estatus);
+ else
+ pr_info_once("Max print length exceeded, table data is available at:\n"
+ "/sys/firmware/acpi/tables/data/BERT");
/*
* Because the boot error source is "one-time polled" type,
@@ -77,7 +81,7 @@ static int __init setup_bert_disable(char *str)
{
bert_disable = 1;
- return 0;
+ return 1;
}
__setup("bert_disable", setup_bert_disable);
diff --git a/drivers/acpi/apei/erst.c b/drivers/acpi/apei/erst.c
index 242f3c2d5533..698d67cee052 100644
--- a/drivers/acpi/apei/erst.c
+++ b/drivers/acpi/apei/erst.c
@@ -891,7 +891,7 @@ EXPORT_SYMBOL_GPL(erst_clear);
static int __init setup_erst_disable(char *str)
{
erst_disable = 1;
- return 0;
+ return 1;
}
__setup("erst_disable", setup_erst_disable);
diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c
index 0c5c9acc6254..d91ad378c00d 100644
--- a/drivers/acpi/apei/ghes.c
+++ b/drivers/acpi/apei/ghes.c
@@ -1457,33 +1457,35 @@ static struct platform_driver ghes_platform_driver = {
.remove = ghes_remove,
};
-static int __init ghes_init(void)
+void __init acpi_ghes_init(void)
{
int rc;
+ sdei_init();
+
if (acpi_disabled)
- return -ENODEV;
+ return;
switch (hest_disable) {
case HEST_NOT_FOUND:
- return -ENODEV;
+ return;
case HEST_DISABLED:
pr_info(GHES_PFX "HEST is not enabled!\n");
- return -EINVAL;
+ return;
default:
break;
}
if (ghes_disable) {
pr_info(GHES_PFX "GHES is not enabled!\n");
- return -EINVAL;
+ return;
}
ghes_nmi_init_cxt();
rc = platform_driver_register(&ghes_platform_driver);
if (rc)
- goto err;
+ return;
rc = apei_osc_setup();
if (rc == 0 && osc_sb_apei_support_acked)
@@ -1494,9 +1496,4 @@ static int __init ghes_init(void)
pr_info(GHES_PFX "APEI firmware first mode is enabled by APEI bit.\n");
else
pr_info(GHES_PFX "Failed to enable APEI firmware first mode.\n");
-
- return 0;
-err:
- return rc;
}
-device_initcall(ghes_init);
diff --git a/drivers/acpi/apei/hest.c b/drivers/acpi/apei/hest.c
index 0edc1ed47673..6aef1ee5e1bd 100644
--- a/drivers/acpi/apei/hest.c
+++ b/drivers/acpi/apei/hest.c
@@ -224,7 +224,7 @@ err:
static int __init setup_hest_disable(char *str)
{
hest_disable = HEST_DISABLED;
- return 0;
+ return 1;
}
__setup("hest_disable", setup_hest_disable);
diff --git a/drivers/acpi/arm64/Kconfig b/drivers/acpi/arm64/Kconfig
index 6dba187f4f2e..d4a72835f328 100644
--- a/drivers/acpi/arm64/Kconfig
+++ b/drivers/acpi/arm64/Kconfig
@@ -8,3 +8,13 @@ config ACPI_IORT
config ACPI_GTDT
bool
+
+config ACPI_AGDI
+ bool "Arm Generic Diagnostic Dump and Reset Device Interface"
+ depends on ARM_SDE_INTERFACE
+ help
+ Arm Generic Diagnostic Dump and Reset Device Interface (AGDI) is
+ a standard that enables issuing a non-maskable diagnostic dump and
+ reset command.
+
+ If set, the kernel parses AGDI table and listens for the command.
diff --git a/drivers/acpi/arm64/Makefile b/drivers/acpi/arm64/Makefile
index 66acbe77f46e..7b9e4045659d 100644
--- a/drivers/acpi/arm64/Makefile
+++ b/drivers/acpi/arm64/Makefile
@@ -1,4 +1,5 @@
# SPDX-License-Identifier: GPL-2.0-only
+obj-$(CONFIG_ACPI_AGDI) += agdi.o
obj-$(CONFIG_ACPI_IORT) += iort.o
obj-$(CONFIG_ACPI_GTDT) += gtdt.o
obj-y += dma.o
diff --git a/drivers/acpi/arm64/agdi.c b/drivers/acpi/arm64/agdi.c
new file mode 100644
index 000000000000..4df337d545b7
--- /dev/null
+++ b/drivers/acpi/arm64/agdi.c
@@ -0,0 +1,116 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * This file implements handling of
+ * Arm Generic Diagnostic Dump and Reset Interface table (AGDI)
+ *
+ * Copyright (c) 2022, Ampere Computing LLC
+ */
+
+#define pr_fmt(fmt) "ACPI: AGDI: " fmt
+
+#include <linux/acpi.h>
+#include <linux/arm_sdei.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+
+struct agdi_data {
+ int sdei_event;
+};
+
+static int agdi_sdei_handler(u32 sdei_event, struct pt_regs *regs, void *arg)
+{
+ nmi_panic(regs, "Arm Generic Diagnostic Dump and Reset SDEI event issued");
+ return 0;
+}
+
+static int agdi_sdei_probe(struct platform_device *pdev,
+ struct agdi_data *adata)
+{
+ int err;
+
+ err = sdei_event_register(adata->sdei_event, agdi_sdei_handler, pdev);
+ if (err) {
+ dev_err(&pdev->dev, "Failed to register for SDEI event %d",
+ adata->sdei_event);
+ return err;
+ }
+
+ err = sdei_event_enable(adata->sdei_event);
+ if (err) {
+ sdei_event_unregister(adata->sdei_event);
+ dev_err(&pdev->dev, "Failed to enable event %d\n",
+ adata->sdei_event);
+ return err;
+ }
+
+ return 0;
+}
+
+static int agdi_probe(struct platform_device *pdev)
+{
+ struct agdi_data *adata = dev_get_platdata(&pdev->dev);
+
+ if (!adata)
+ return -EINVAL;
+
+ return agdi_sdei_probe(pdev, adata);
+}
+
+static int agdi_remove(struct platform_device *pdev)
+{
+ struct agdi_data *adata = dev_get_platdata(&pdev->dev);
+ int err, i;
+
+ err = sdei_event_disable(adata->sdei_event);
+ if (err)
+ return err;
+
+ for (i = 0; i < 3; i++) {
+ err = sdei_event_unregister(adata->sdei_event);
+ if (err != -EINPROGRESS)
+ break;
+
+ schedule();
+ }
+
+ return err;
+}
+
+static struct platform_driver agdi_driver = {
+ .driver = {
+ .name = "agdi",
+ },
+ .probe = agdi_probe,
+ .remove = agdi_remove,
+};
+
+void __init acpi_agdi_init(void)
+{
+ struct acpi_table_agdi *agdi_table;
+ struct agdi_data pdata;
+ struct platform_device *pdev;
+ acpi_status status;
+
+ status = acpi_get_table(ACPI_SIG_AGDI, 0,
+ (struct acpi_table_header **) &agdi_table);
+ if (ACPI_FAILURE(status))
+ return;
+
+ if (agdi_table->flags & ACPI_AGDI_SIGNALING_MODE) {
+ pr_warn("Interrupt signaling is not supported");
+ goto err_put_table;
+ }
+
+ pdata.sdei_event = agdi_table->sdei_event;
+
+ pdev = platform_device_register_data(NULL, "agdi", 0, &pdata, sizeof(pdata));
+ if (IS_ERR(pdev))
+ goto err_put_table;
+
+ if (platform_driver_register(&agdi_driver))
+ platform_device_unregister(pdev);
+
+err_put_table:
+ acpi_put_table((struct acpi_table_header *)agdi_table);
+}
diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
index 3b23fb775ac4..f2f8f05662de 100644
--- a/drivers/acpi/arm64/iort.c
+++ b/drivers/acpi/arm64/iort.c
@@ -1361,9 +1361,17 @@ static void __init arm_smmu_v3_pmcg_init_resources(struct resource *res,
res[0].start = pmcg->page0_base_address;
res[0].end = pmcg->page0_base_address + SZ_4K - 1;
res[0].flags = IORESOURCE_MEM;
- res[1].start = pmcg->page1_base_address;
- res[1].end = pmcg->page1_base_address + SZ_4K - 1;
- res[1].flags = IORESOURCE_MEM;
+ /*
+ * The initial version in DEN0049C lacked a way to describe register
+ * page 1, which makes it broken for most PMCG implementations; in
+ * that case, just let the driver fail gracefully if it expects to
+ * find a second memory resource.
+ */
+ if (node->revision > 0) {
+ res[1].start = pmcg->page1_base_address;
+ res[1].end = pmcg->page1_base_address + SZ_4K - 1;
+ res[1].flags = IORESOURCE_MEM;
+ }
if (pmcg->overflow_gsiv)
acpi_iort_register_irq(pmcg->overflow_gsiv, "overflow",
diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c
index ea31ae01458b..dc208f5f5a1f 100644
--- a/drivers/acpi/battery.c
+++ b/drivers/acpi/battery.c
@@ -59,6 +59,10 @@ MODULE_PARM_DESC(cache_time, "cache time in milliseconds");
static const struct acpi_device_id battery_device_ids[] = {
{"PNP0C0A", 0},
+
+ /* Microsoft Surface Go 3 */
+ {"MSHW0146", 0},
+
{"", 0},
};
@@ -1148,6 +1152,14 @@ static const struct dmi_system_id bat_dmi_table[] __initconst = {
DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad"),
},
},
+ {
+ /* Microsoft Surface Go 3 */
+ .callback = battery_notification_delay_quirk,
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Surface Go 3"),
+ },
+ },
{},
};
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c
index 07f604832fd6..3e58b613a2c4 100644
--- a/drivers/acpi/bus.c
+++ b/drivers/acpi/bus.c
@@ -26,6 +26,7 @@
#include <asm/mpspec.h>
#include <linux/dmi.h>
#endif
+#include <linux/acpi_agdi.h>
#include <linux/acpi_iort.h>
#include <linux/acpi_viot.h>
#include <linux/pci.h>
@@ -283,6 +284,8 @@ EXPORT_SYMBOL_GPL(osc_pc_lpi_support_confirmed);
bool osc_sb_native_usb4_support_confirmed;
EXPORT_SYMBOL_GPL(osc_sb_native_usb4_support_confirmed);
+bool osc_sb_cppc_not_supported;
+
static u8 sb_uuid_str[] = "0811B06E-4A27-44F9-8D60-3CBBC22E7B48";
static void acpi_bus_osc_negotiate_platform_control(void)
{
@@ -332,21 +335,38 @@ static void acpi_bus_osc_negotiate_platform_control(void)
if (ACPI_FAILURE(acpi_run_osc(handle, &context)))
return;
- kfree(context.ret.pointer);
+ capbuf_ret = context.ret.pointer;
+ if (context.ret.length <= OSC_SUPPORT_DWORD) {
+ kfree(context.ret.pointer);
+ return;
+ }
+
+#ifdef CONFIG_X86
+ if (boot_cpu_has(X86_FEATURE_HWP))
+ osc_sb_cppc_not_supported = !(capbuf_ret[OSC_SUPPORT_DWORD] &
+ (OSC_SB_CPC_SUPPORT | OSC_SB_CPCV2_SUPPORT));
+#endif
- /* Now run _OSC again with query flag clear */
+ /*
+ * Now run _OSC again with query flag clear and with the caps
+ * supported by both the OS and the platform.
+ */
capbuf[OSC_QUERY_DWORD] = 0;
+ capbuf[OSC_SUPPORT_DWORD] = capbuf_ret[OSC_SUPPORT_DWORD];
+ kfree(context.ret.pointer);
if (ACPI_FAILURE(acpi_run_osc(handle, &context)))
return;
capbuf_ret = context.ret.pointer;
- osc_sb_apei_support_acked =
- capbuf_ret[OSC_SUPPORT_DWORD] & OSC_SB_APEI_SUPPORT;
- osc_pc_lpi_support_confirmed =
- capbuf_ret[OSC_SUPPORT_DWORD] & OSC_SB_PCLPI_SUPPORT;
- osc_sb_native_usb4_support_confirmed =
- capbuf_ret[OSC_SUPPORT_DWORD] & OSC_SB_NATIVE_USB4_SUPPORT;
+ if (context.ret.length > OSC_SUPPORT_DWORD) {
+ osc_sb_apei_support_acked =
+ capbuf_ret[OSC_SUPPORT_DWORD] & OSC_SB_APEI_SUPPORT;
+ osc_pc_lpi_support_confirmed =
+ capbuf_ret[OSC_SUPPORT_DWORD] & OSC_SB_PCLPI_SUPPORT;
+ osc_sb_native_usb4_support_confirmed =
+ capbuf_ret[OSC_SUPPORT_DWORD] & OSC_SB_NATIVE_USB4_SUPPORT;
+ }
kfree(context.ret.pointer);
}
@@ -1043,7 +1063,12 @@ struct bus_type acpi_bus_type = {
.remove = acpi_device_remove,
.uevent = acpi_device_uevent,
};
-EXPORT_SYMBOL_GPL(acpi_bus_type);
+
+int acpi_bus_for_each_dev(int (*fn)(struct device *, void *), void *data)
+{
+ return bus_for_each_dev(&acpi_bus_type, NULL, data, fn);
+}
+EXPORT_SYMBOL_GPL(acpi_bus_for_each_dev);
/* --------------------------------------------------------------------------
Initialization/Cleanup
@@ -1331,6 +1356,8 @@ static int __init acpi_init(void)
pci_mmcfg_late_init();
acpi_iort_init();
+ acpi_hest_init();
+ acpi_ghes_init();
acpi_scan_init();
acpi_ec_init();
acpi_debugfs_init();
@@ -1339,6 +1366,7 @@ static int __init acpi_init(void)
acpi_debugger_init();
acpi_setup_sb_notify_handler();
acpi_viot_init();
+ acpi_agdi_init();
return 0;
}
diff --git a/drivers/acpi/cppc_acpi.c b/drivers/acpi/cppc_acpi.c
index 866560cbb082..d418449194ee 100644
--- a/drivers/acpi/cppc_acpi.c
+++ b/drivers/acpi/cppc_acpi.c
@@ -633,8 +633,8 @@ static bool is_cppc_supported(int revision, int num_ent)
* )
*/
-#ifndef init_freq_invariance_cppc
-static inline void init_freq_invariance_cppc(void) { }
+#ifndef arch_init_invariance_cppc
+static inline void arch_init_invariance_cppc(void) { }
#endif
/**
@@ -656,6 +656,9 @@ int acpi_cppc_processor_probe(struct acpi_processor *pr)
acpi_status status;
int ret = -EFAULT;
+ if (osc_sb_cppc_not_supported)
+ return -ENODEV;
+
/* Parse the ACPI _CPC table for this CPU. */
status = acpi_evaluate_object_typed(handle, "_CPC", NULL, &output,
ACPI_TYPE_PACKAGE);
@@ -816,7 +819,7 @@ int acpi_cppc_processor_probe(struct acpi_processor *pr)
goto out_free;
}
- init_freq_invariance_cppc();
+ arch_init_invariance_cppc();
kfree(output.pointer);
return 0;
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
index 0077d2c85df8..a1b871a418f8 100644
--- a/drivers/acpi/ec.c
+++ b/drivers/acpi/ec.c
@@ -168,7 +168,7 @@ struct acpi_ec_query {
};
static int acpi_ec_submit_query(struct acpi_ec *ec);
-static bool advance_transaction(struct acpi_ec *ec, bool interrupt);
+static void advance_transaction(struct acpi_ec *ec, bool interrupt);
static void acpi_ec_event_handler(struct work_struct *work);
struct acpi_ec *first_ec;
@@ -441,36 +441,35 @@ static bool acpi_ec_submit_flushable_request(struct acpi_ec *ec)
return true;
}
-static bool acpi_ec_submit_event(struct acpi_ec *ec)
+static void acpi_ec_submit_event(struct acpi_ec *ec)
{
+ /*
+ * It is safe to mask the events here, because acpi_ec_close_event()
+ * will run at least once after this.
+ */
acpi_ec_mask_events(ec);
if (!acpi_ec_event_enabled(ec))
- return false;
+ return;
- if (ec->event_state == EC_EVENT_READY) {
- ec_dbg_evt("Command(%s) submitted/blocked",
- acpi_ec_cmd_string(ACPI_EC_COMMAND_QUERY));
+ if (ec->event_state != EC_EVENT_READY)
+ return;
- ec->event_state = EC_EVENT_IN_PROGRESS;
- /*
- * If events_to_process is greqter than 0 at this point, the
- * while () loop in acpi_ec_event_handler() is still running
- * and incrementing events_to_process will cause it to invoke
- * acpi_ec_submit_query() once more, so it is not necessary to
- * queue up the event work to start the same loop again.
- */
- if (ec->events_to_process++ > 0)
- return true;
-
- ec->events_in_progress++;
- return queue_work(ec_wq, &ec->work);
- }
+ ec_dbg_evt("Command(%s) submitted/blocked",
+ acpi_ec_cmd_string(ACPI_EC_COMMAND_QUERY));
+ ec->event_state = EC_EVENT_IN_PROGRESS;
/*
- * The event handling work has not been completed yet, so it needs to be
- * flushed.
+ * If events_to_process is greater than 0 at this point, the while ()
+ * loop in acpi_ec_event_handler() is still running and incrementing
+ * events_to_process will cause it to invoke acpi_ec_submit_query() once
+ * more, so it is not necessary to queue up the event work to start the
+ * same loop again.
*/
- return true;
+ if (ec->events_to_process++ > 0)
+ return;
+
+ ec->events_in_progress++;
+ queue_work(ec_wq, &ec->work);
}
static void acpi_ec_complete_event(struct acpi_ec *ec)
@@ -655,11 +654,10 @@ static void acpi_ec_spurious_interrupt(struct acpi_ec *ec, struct transaction *t
acpi_ec_mask_events(ec);
}
-static bool advance_transaction(struct acpi_ec *ec, bool interrupt)
+static void advance_transaction(struct acpi_ec *ec, bool interrupt)
{
struct transaction *t = ec->curr;
bool wakeup = false;
- bool ret = false;
u8 status;
ec_dbg_stm("%s (%d)", interrupt ? "IRQ" : "TASK", smp_processor_id());
@@ -724,12 +722,10 @@ static bool advance_transaction(struct acpi_ec *ec, bool interrupt)
out:
if (status & ACPI_EC_FLAG_SCI)
- ret = acpi_ec_submit_event(ec);
+ acpi_ec_submit_event(ec);
if (wakeup && interrupt)
wake_up(&ec->wait);
-
- return ret;
}
static void start_transaction(struct acpi_ec *ec)
@@ -1242,6 +1238,7 @@ static void acpi_ec_event_handler(struct work_struct *work)
acpi_ec_submit_query(ec);
spin_lock_irq(&ec->lock);
+
ec->events_to_process--;
}
@@ -1250,27 +1247,30 @@ static void acpi_ec_event_handler(struct work_struct *work)
* event handling work again regardless of whether or not the query
* queued up above is processed successfully.
*/
- if (ec_event_clearing == ACPI_EC_EVT_TIMING_EVENT)
+ if (ec_event_clearing == ACPI_EC_EVT_TIMING_EVENT) {
+ bool guard_timeout;
+
acpi_ec_complete_event(ec);
- else
- acpi_ec_close_event(ec);
- spin_unlock_irq(&ec->lock);
+ ec_dbg_evt("Event stopped");
- ec_dbg_evt("Event stopped");
+ spin_unlock_irq(&ec->lock);
+
+ guard_timeout = !!ec_guard(ec);
- if (ec_event_clearing == ACPI_EC_EVT_TIMING_EVENT && ec_guard(ec)) {
spin_lock_irq(&ec->lock);
/* Take care of SCI_EVT unless someone else is doing that. */
- if (!ec->curr)
+ if (guard_timeout && !ec->curr)
advance_transaction(ec, false);
+ } else {
+ acpi_ec_close_event(ec);
- spin_unlock_irq(&ec->lock);
+ ec_dbg_evt("Event stopped");
}
- spin_lock_irq(&ec->lock);
ec->events_in_progress--;
+
spin_unlock_irq(&ec->lock);
}
@@ -2051,6 +2051,11 @@ void acpi_ec_set_gpe_wake_mask(u8 action)
acpi_set_gpe_wake_mask(NULL, first_ec->gpe, action);
}
+static bool acpi_ec_work_in_progress(struct acpi_ec *ec)
+{
+ return ec->events_in_progress + ec->queries_in_progress > 0;
+}
+
bool acpi_ec_dispatch_gpe(void)
{
bool work_in_progress = false;
@@ -2066,13 +2071,27 @@ bool acpi_ec_dispatch_gpe(void)
return true;
/*
+ * Cancel the SCI wakeup and process all pending events in case there
+ * are any wakeup ones in there.
+ *
+ * Note that if any non-EC GPEs are active at this point, the SCI will
+ * retrigger after the rearming in acpi_s2idle_wake(), so no events
+ * should be missed by canceling the wakeup here.
+ */
+ pm_system_cancel_wakeup();
+
+ /*
* Dispatch the EC GPE in-band, but do not report wakeup in any case
* to allow the caller to process events properly after that.
*/
spin_lock_irq(&first_ec->lock);
- if (acpi_ec_gpe_status_set(first_ec))
- work_in_progress = advance_transaction(first_ec, false);
+ if (acpi_ec_gpe_status_set(first_ec)) {
+ pm_pr_dbg("ACPI EC GPE status set\n");
+
+ advance_transaction(first_ec, false);
+ work_in_progress = acpi_ec_work_in_progress(first_ec);
+ }
spin_unlock_irq(&first_ec->lock);
@@ -2089,8 +2108,7 @@ bool acpi_ec_dispatch_gpe(void)
spin_lock_irq(&first_ec->lock);
- work_in_progress = first_ec->events_in_progress +
- first_ec->queries_in_progress > 0;
+ work_in_progress = acpi_ec_work_in_progress(first_ec);
spin_unlock_irq(&first_ec->lock);
} while (work_in_progress && !pm_wakeup_pending());
diff --git a/drivers/acpi/fan.h b/drivers/acpi/fan.h
index dd9bb8ca2244..44728529a5b6 100644
--- a/drivers/acpi/fan.h
+++ b/drivers/acpi/fan.h
@@ -6,9 +6,53 @@
*
* Add new device IDs before the generic ACPI fan one.
*/
+
+#ifndef _ACPI_FAN_H_
+#define _ACPI_FAN_H_
+
#define ACPI_FAN_DEVICE_IDS \
{"INT3404", }, /* Fan */ \
{"INTC1044", }, /* Fan for Tiger Lake generation */ \
{"INTC1048", }, /* Fan for Alder Lake generation */ \
{"INTC10A2", }, /* Fan for Raptor Lake generation */ \
{"PNP0C0B", } /* Generic ACPI fan */
+
+#define ACPI_FPS_NAME_LEN 20
+
+struct acpi_fan_fps {
+ u64 control;
+ u64 trip_point;
+ u64 speed;
+ u64 noise_level;
+ u64 power;
+ char name[ACPI_FPS_NAME_LEN];
+ struct device_attribute dev_attr;
+};
+
+struct acpi_fan_fif {
+ u8 revision;
+ u8 fine_grain_ctrl;
+ u8 step_size;
+ u8 low_speed_notification;
+};
+
+struct acpi_fan_fst {
+ u64 revision;
+ u64 control;
+ u64 speed;
+};
+
+struct acpi_fan {
+ bool acpi4;
+ struct acpi_fan_fif fif;
+ struct acpi_fan_fps *fps;
+ int fps_count;
+ struct thermal_cooling_device *cdev;
+ struct device_attribute fst_speed;
+ struct device_attribute fine_grain_control;
+};
+
+int acpi_fan_get_fst(struct acpi_device *device, struct acpi_fan_fst *fst);
+int acpi_fan_create_attributes(struct acpi_device *device);
+void acpi_fan_delete_attributes(struct acpi_device *device);
+#endif
diff --git a/drivers/acpi/fan_attr.c b/drivers/acpi/fan_attr.c
new file mode 100644
index 000000000000..f15157d40713
--- /dev/null
+++ b/drivers/acpi/fan_attr.c
@@ -0,0 +1,137 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * fan_attr.c - Create extra attributes for ACPI Fan driver
+ *
+ * Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
+ * Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
+ * Copyright (C) 2022 Intel Corporation. All rights reserved.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/acpi.h>
+
+#include "fan.h"
+
+MODULE_LICENSE("GPL");
+
+static ssize_t show_state(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ struct acpi_fan_fps *fps = container_of(attr, struct acpi_fan_fps, dev_attr);
+ int count;
+
+ if (fps->control == 0xFFFFFFFF || fps->control > 100)
+ count = scnprintf(buf, PAGE_SIZE, "not-defined:");
+ else
+ count = scnprintf(buf, PAGE_SIZE, "%lld:", fps->control);
+
+ if (fps->trip_point == 0xFFFFFFFF || fps->trip_point > 9)
+ count += scnprintf(&buf[count], PAGE_SIZE - count, "not-defined:");
+ else
+ count += scnprintf(&buf[count], PAGE_SIZE - count, "%lld:", fps->trip_point);
+
+ if (fps->speed == 0xFFFFFFFF)
+ count += scnprintf(&buf[count], PAGE_SIZE - count, "not-defined:");
+ else
+ count += scnprintf(&buf[count], PAGE_SIZE - count, "%lld:", fps->speed);
+
+ if (fps->noise_level == 0xFFFFFFFF)
+ count += scnprintf(&buf[count], PAGE_SIZE - count, "not-defined:");
+ else
+ count += scnprintf(&buf[count], PAGE_SIZE - count, "%lld:", fps->noise_level * 100);
+
+ if (fps->power == 0xFFFFFFFF)
+ count += scnprintf(&buf[count], PAGE_SIZE - count, "not-defined\n");
+ else
+ count += scnprintf(&buf[count], PAGE_SIZE - count, "%lld\n", fps->power);
+
+ return count;
+}
+
+static ssize_t show_fan_speed(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ struct acpi_device *acpi_dev = container_of(dev, struct acpi_device, dev);
+ struct acpi_fan_fst fst;
+ int status;
+
+ status = acpi_fan_get_fst(acpi_dev, &fst);
+ if (status)
+ return status;
+
+ return sprintf(buf, "%lld\n", fst.speed);
+}
+
+static ssize_t show_fine_grain_control(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ struct acpi_device *acpi_dev = container_of(dev, struct acpi_device, dev);
+ struct acpi_fan *fan = acpi_driver_data(acpi_dev);
+
+ return sprintf(buf, "%d\n", fan->fif.fine_grain_ctrl);
+}
+
+int acpi_fan_create_attributes(struct acpi_device *device)
+{
+ struct acpi_fan *fan = acpi_driver_data(device);
+ int i, status;
+
+ sysfs_attr_init(&fan->fine_grain_control.attr);
+ fan->fine_grain_control.show = show_fine_grain_control;
+ fan->fine_grain_control.store = NULL;
+ fan->fine_grain_control.attr.name = "fine_grain_control";
+ fan->fine_grain_control.attr.mode = 0444;
+ status = sysfs_create_file(&device->dev.kobj, &fan->fine_grain_control.attr);
+ if (status)
+ return status;
+
+ /* _FST is present if we are here */
+ sysfs_attr_init(&fan->fst_speed.attr);
+ fan->fst_speed.show = show_fan_speed;
+ fan->fst_speed.store = NULL;
+ fan->fst_speed.attr.name = "fan_speed_rpm";
+ fan->fst_speed.attr.mode = 0444;
+ status = sysfs_create_file(&device->dev.kobj, &fan->fst_speed.attr);
+ if (status)
+ goto rem_fine_grain_attr;
+
+ for (i = 0; i < fan->fps_count; ++i) {
+ struct acpi_fan_fps *fps = &fan->fps[i];
+
+ snprintf(fps->name, ACPI_FPS_NAME_LEN, "state%d", i);
+ sysfs_attr_init(&fps->dev_attr.attr);
+ fps->dev_attr.show = show_state;
+ fps->dev_attr.store = NULL;
+ fps->dev_attr.attr.name = fps->name;
+ fps->dev_attr.attr.mode = 0444;
+ status = sysfs_create_file(&device->dev.kobj, &fps->dev_attr.attr);
+ if (status) {
+ int j;
+
+ for (j = 0; j < i; ++j)
+ sysfs_remove_file(&device->dev.kobj, &fan->fps[j].dev_attr.attr);
+ goto rem_fst_attr;
+ }
+ }
+
+ return 0;
+
+rem_fst_attr:
+ sysfs_remove_file(&device->dev.kobj, &fan->fst_speed.attr);
+
+rem_fine_grain_attr:
+ sysfs_remove_file(&device->dev.kobj, &fan->fine_grain_control.attr);
+
+ return status;
+}
+
+void acpi_fan_delete_attributes(struct acpi_device *device)
+{
+ struct acpi_fan *fan = acpi_driver_data(device);
+ int i;
+
+ for (i = 0; i < fan->fps_count; ++i)
+ sysfs_remove_file(&device->dev.kobj, &fan->fps[i].dev_attr.attr);
+
+ sysfs_remove_file(&device->dev.kobj, &fan->fst_speed.attr);
+ sysfs_remove_file(&device->dev.kobj, &fan->fine_grain_control.attr);
+}
diff --git a/drivers/acpi/fan.c b/drivers/acpi/fan_core.c
index 5cd0ceb50bc8..b9a9a59ddcc1 100644
--- a/drivers/acpi/fan.c
+++ b/drivers/acpi/fan_core.c
@@ -1,9 +1,10 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
- * acpi_fan.c - ACPI Fan Driver ($Revision: 29 $)
+ * fan_core.c - ACPI Fan core Driver
*
* Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
* Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
+ * Copyright (C) 2022 Intel Corporation. All rights reserved.
*/
#include <linux/kernel.h>
@@ -45,33 +46,6 @@ static const struct dev_pm_ops acpi_fan_pm = {
#define FAN_PM_OPS_PTR NULL
#endif
-#define ACPI_FPS_NAME_LEN 20
-
-struct acpi_fan_fps {
- u64 control;
- u64 trip_point;
- u64 speed;
- u64 noise_level;
- u64 power;
- char name[ACPI_FPS_NAME_LEN];
- struct device_attribute dev_attr;
-};
-
-struct acpi_fan_fif {
- u64 revision;
- u64 fine_grain_ctrl;
- u64 step_size;
- u64 low_speed_notification;
-};
-
-struct acpi_fan {
- bool acpi4;
- struct acpi_fan_fif fif;
- struct acpi_fan_fps *fps;
- int fps_count;
- struct thermal_cooling_device *cdev;
-};
-
static struct platform_driver acpi_fan_driver = {
.probe = acpi_fan_probe,
.remove = acpi_fan_remove,
@@ -89,25 +63,29 @@ static int fan_get_max_state(struct thermal_cooling_device *cdev, unsigned long
struct acpi_device *device = cdev->devdata;
struct acpi_fan *fan = acpi_driver_data(device);
- if (fan->acpi4)
- *state = fan->fps_count - 1;
- else
+ if (fan->acpi4) {
+ if (fan->fif.fine_grain_ctrl)
+ *state = 100 / fan->fif.step_size;
+ else
+ *state = fan->fps_count - 1;
+ } else {
*state = 1;
+ }
+
return 0;
}
-static int fan_get_state_acpi4(struct acpi_device *device, unsigned long *state)
+int acpi_fan_get_fst(struct acpi_device *device, struct acpi_fan_fst *fst)
{
struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
- struct acpi_fan *fan = acpi_driver_data(device);
union acpi_object *obj;
acpi_status status;
- int control, i;
+ int ret = 0;
status = acpi_evaluate_object(device->handle, "_FST", NULL, &buffer);
if (ACPI_FAILURE(status)) {
dev_err(&device->dev, "Get fan state failed\n");
- return status;
+ return -ENODEV;
}
obj = buffer.pointer;
@@ -115,35 +93,52 @@ static int fan_get_state_acpi4(struct acpi_device *device, unsigned long *state)
obj->package.count != 3 ||
obj->package.elements[1].type != ACPI_TYPE_INTEGER) {
dev_err(&device->dev, "Invalid _FST data\n");
- status = -EINVAL;
+ ret = -EINVAL;
goto err;
}
- control = obj->package.elements[1].integer.value;
+ fst->revision = obj->package.elements[0].integer.value;
+ fst->control = obj->package.elements[1].integer.value;
+ fst->speed = obj->package.elements[2].integer.value;
+
+err:
+ kfree(obj);
+ return ret;
+}
+
+static int fan_get_state_acpi4(struct acpi_device *device, unsigned long *state)
+{
+ struct acpi_fan *fan = acpi_driver_data(device);
+ struct acpi_fan_fst fst;
+ int status, i;
+
+ status = acpi_fan_get_fst(device, &fst);
+ if (status)
+ return status;
+
+ if (fan->fif.fine_grain_ctrl) {
+ /* This control should be same what we set using _FSL by spec */
+ if (fst.control > 100) {
+ dev_dbg(&device->dev, "Invalid control value returned\n");
+ goto match_fps;
+ }
+
+ *state = (int) fst.control / fan->fif.step_size;
+ return 0;
+ }
+
+match_fps:
for (i = 0; i < fan->fps_count; i++) {
- /*
- * When Fine Grain Control is set, return the state
- * corresponding to maximum fan->fps[i].control
- * value compared to the current speed. Here the
- * fan->fps[] is sorted array with increasing speed.
- */
- if (fan->fif.fine_grain_ctrl && control < fan->fps[i].control) {
- i = (i > 0) ? i - 1 : 0;
+ if (fst.control == fan->fps[i].control)
break;
- } else if (control == fan->fps[i].control) {
- break;
- }
}
if (i == fan->fps_count) {
dev_dbg(&device->dev, "Invalid control value returned\n");
- status = -EINVAL;
- goto err;
+ return -EINVAL;
}
*state = i;
-err:
- kfree(obj);
return status;
}
@@ -187,15 +182,30 @@ static int fan_set_state_acpi4(struct acpi_device *device, unsigned long state)
{
struct acpi_fan *fan = acpi_driver_data(device);
acpi_status status;
+ u64 value = state;
+ int max_state;
- if (state >= fan->fps_count)
+ if (fan->fif.fine_grain_ctrl)
+ max_state = 100 / fan->fif.step_size;
+ else
+ max_state = fan->fps_count - 1;
+
+ if (state > max_state)
return -EINVAL;
- status = acpi_execute_simple_method(device->handle, "_FSL",
- fan->fps[state].control);
+ if (fan->fif.fine_grain_ctrl) {
+ value *= fan->fif.step_size;
+ /* Spec allows compensate the last step only */
+ if (value + fan->fif.step_size > 100)
+ value = 100;
+ } else {
+ value = fan->fps[state].control;
+ }
+
+ status = acpi_execute_simple_method(device->handle, "_FSL", value);
if (ACPI_FAILURE(status)) {
dev_dbg(&device->dev, "Failed to set state by _FSL\n");
- return status;
+ return -ENODEV;
}
return 0;
@@ -237,7 +247,8 @@ static int acpi_fan_get_fif(struct acpi_device *device)
struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
struct acpi_fan *fan = acpi_driver_data(device);
struct acpi_buffer format = { sizeof("NNNN"), "NNNN" };
- struct acpi_buffer fif = { sizeof(fan->fif), &fan->fif };
+ u64 fields[4];
+ struct acpi_buffer fif = { sizeof(fields), fields };
union acpi_object *obj;
acpi_status status;
@@ -258,6 +269,17 @@ static int acpi_fan_get_fif(struct acpi_device *device)
status = -EINVAL;
}
+ fan->fif.revision = fields[0];
+ fan->fif.fine_grain_ctrl = fields[1];
+ fan->fif.step_size = fields[2];
+ fan->fif.low_speed_notification = fields[3];
+
+ /* If there is a bug in step size and set as 0, change to 1 */
+ if (!fan->fif.step_size)
+ fan->fif.step_size = 1;
+ /* If step size > 9, change to 9 (by spec valid values 1-9) */
+ else if (fan->fif.step_size > 9)
+ fan->fif.step_size = 9;
err:
kfree(obj);
return status;
@@ -270,39 +292,6 @@ static int acpi_fan_speed_cmp(const void *a, const void *b)
return fps1->speed - fps2->speed;
}
-static ssize_t show_state(struct device *dev, struct device_attribute *attr, char *buf)
-{
- struct acpi_fan_fps *fps = container_of(attr, struct acpi_fan_fps, dev_attr);
- int count;
-
- if (fps->control == 0xFFFFFFFF || fps->control > 100)
- count = scnprintf(buf, PAGE_SIZE, "not-defined:");
- else
- count = scnprintf(buf, PAGE_SIZE, "%lld:", fps->control);
-
- if (fps->trip_point == 0xFFFFFFFF || fps->trip_point > 9)
- count += scnprintf(&buf[count], PAGE_SIZE - count, "not-defined:");
- else
- count += scnprintf(&buf[count], PAGE_SIZE - count, "%lld:", fps->trip_point);
-
- if (fps->speed == 0xFFFFFFFF)
- count += scnprintf(&buf[count], PAGE_SIZE - count, "not-defined:");
- else
- count += scnprintf(&buf[count], PAGE_SIZE - count, "%lld:", fps->speed);
-
- if (fps->noise_level == 0xFFFFFFFF)
- count += scnprintf(&buf[count], PAGE_SIZE - count, "not-defined:");
- else
- count += scnprintf(&buf[count], PAGE_SIZE - count, "%lld:", fps->noise_level * 100);
-
- if (fps->power == 0xFFFFFFFF)
- count += scnprintf(&buf[count], PAGE_SIZE - count, "not-defined\n");
- else
- count += scnprintf(&buf[count], PAGE_SIZE - count, "%lld\n", fps->power);
-
- return count;
-}
-
static int acpi_fan_get_fps(struct acpi_device *device)
{
struct acpi_fan *fan = acpi_driver_data(device);
@@ -347,25 +336,6 @@ static int acpi_fan_get_fps(struct acpi_device *device)
sort(fan->fps, fan->fps_count, sizeof(*fan->fps),
acpi_fan_speed_cmp, NULL);
- for (i = 0; i < fan->fps_count; ++i) {
- struct acpi_fan_fps *fps = &fan->fps[i];
-
- snprintf(fps->name, ACPI_FPS_NAME_LEN, "state%d", i);
- sysfs_attr_init(&fps->dev_attr.attr);
- fps->dev_attr.show = show_state;
- fps->dev_attr.store = NULL;
- fps->dev_attr.attr.name = fps->name;
- fps->dev_attr.attr.mode = 0444;
- status = sysfs_create_file(&device->dev.kobj, &fps->dev_attr.attr);
- if (status) {
- int j;
-
- for (j = 0; j < i; ++j)
- sysfs_remove_file(&device->dev.kobj, &fan->fps[j].dev_attr.attr);
- break;
- }
- }
-
err:
kfree(obj);
return status;
@@ -396,6 +366,10 @@ static int acpi_fan_probe(struct platform_device *pdev)
if (result)
return result;
+ result = acpi_fan_create_attributes(device);
+ if (result)
+ return result;
+
fan->acpi4 = true;
} else {
result = acpi_device_update_power(device, NULL);
@@ -437,12 +411,8 @@ static int acpi_fan_probe(struct platform_device *pdev)
return 0;
err_end:
- if (fan->acpi4) {
- int i;
-
- for (i = 0; i < fan->fps_count; ++i)
- sysfs_remove_file(&device->dev.kobj, &fan->fps[i].dev_attr.attr);
- }
+ if (fan->acpi4)
+ acpi_fan_delete_attributes(device);
return result;
}
@@ -453,10 +423,8 @@ static int acpi_fan_remove(struct platform_device *pdev)
if (fan->acpi4) {
struct acpi_device *device = ACPI_COMPANION(&pdev->dev);
- int i;
- for (i = 0; i < fan->fps_count; ++i)
- sysfs_remove_file(&device->dev.kobj, &fan->fps[i].dev_attr.attr);
+ acpi_fan_delete_attributes(device);
}
sysfs_remove_link(&pdev->dev.kobj, "thermal_cooling");
sysfs_remove_link(&fan->cdev->device.kobj, "device");
diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h
index 457e11d851b8..628bf8f18130 100644
--- a/drivers/acpi/internal.h
+++ b/drivers/acpi/internal.h
@@ -96,8 +96,6 @@ void acpi_scan_table_notify(void);
extern struct list_head acpi_bus_id_list;
-#define ACPI_MAX_DEVICE_INSTANCES 4096
-
struct acpi_device_bus_id {
const char *bus_id;
struct ida instance_ida;
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
index 45c5c0e45e33..7a70c4bfc23c 100644
--- a/drivers/acpi/osl.c
+++ b/drivers/acpi/osl.c
@@ -642,22 +642,24 @@ u64 acpi_os_get_timer(void)
(ACPI_100NSEC_PER_SEC / HZ);
}
-acpi_status acpi_os_read_port(acpi_io_address port, u32 * value, u32 width)
+acpi_status acpi_os_read_port(acpi_io_address port, u32 *value, u32 width)
{
u32 dummy;
- if (!value)
+ if (value)
+ *value = 0;
+ else
value = &dummy;
- *value = 0;
if (width <= 8) {
- *(u8 *) value = inb(port);
+ *value = inb(port);
} else if (width <= 16) {
- *(u16 *) value = inw(port);
+ *value = inw(port);
} else if (width <= 32) {
- *(u32 *) value = inl(port);
+ *value = inl(port);
} else {
- BUG();
+ pr_debug("%s: Access width %d not supported\n", __func__, width);
+ return AE_BAD_PARAMETER;
}
return AE_OK;
@@ -674,7 +676,8 @@ acpi_status acpi_os_write_port(acpi_io_address port, u32 value, u32 width)
} else if (width <= 32) {
outl(value, port);
} else {
- BUG();
+ pr_debug("%s: Access width %d not supported\n", __func__, width);
+ return AE_BAD_PARAMETER;
}
return AE_OK;
diff --git a/drivers/acpi/pci_link.c b/drivers/acpi/pci_link.c
index d54fb8e54671..58647051c948 100644
--- a/drivers/acpi/pci_link.c
+++ b/drivers/acpi/pci_link.c
@@ -185,7 +185,7 @@ static acpi_status acpi_pci_link_check_current(struct acpi_resource *resource,
if (!p || !p->interrupt_count) {
/*
* IRQ descriptors may have no IRQ# bits set,
- * particularly those those w/ _STA disabled
+ * particularly those w/ _STA disabled
*/
pr_debug("Blank _CRS IRQ resource\n");
return AE_OK;
diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
index b76db99cced3..6f9e75d14808 100644
--- a/drivers/acpi/pci_root.c
+++ b/drivers/acpi/pci_root.c
@@ -22,8 +22,6 @@
#include <linux/slab.h>
#include <linux/dmi.h>
#include <linux/platform_data/x86/apple.h>
-#include <acpi/apei.h> /* for acpi_hest_init() */
-
#include "internal.h"
#define ACPI_PCI_ROOT_CLASS "pci_bridge"
@@ -943,7 +941,6 @@ out_release_info:
void __init acpi_pci_root_init(void)
{
- acpi_hest_init();
if (acpi_pci_disabled)
return;
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c
index 86560a28751b..32b20efff5f8 100644
--- a/drivers/acpi/processor_idle.c
+++ b/drivers/acpi/processor_idle.c
@@ -96,6 +96,11 @@ static const struct dmi_system_id processor_power_dmi_table[] = {
DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."),
DMI_MATCH(DMI_PRODUCT_NAME,"L8400B series Notebook PC")},
(void *)1},
+ /* T40 can not handle C3 idle state */
+ { set_max_cstate, "IBM ThinkPad T40", {
+ DMI_MATCH(DMI_SYS_VENDOR, "IBM"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "23737CU")},
+ (void *)2},
{},
};
@@ -1075,6 +1080,11 @@ static int flatten_lpi_states(struct acpi_processor *pr,
return 0;
}
+int __weak acpi_processor_ffh_lpi_probe(unsigned int cpu)
+{
+ return -EOPNOTSUPP;
+}
+
static int acpi_processor_get_lpi_info(struct acpi_processor *pr)
{
int ret, i;
@@ -1083,6 +1093,11 @@ static int acpi_processor_get_lpi_info(struct acpi_processor *pr)
struct acpi_device *d = NULL;
struct acpi_lpi_states_array info[2], *tmp, *prev, *curr;
+ /* make sure our architecture has support */
+ ret = acpi_processor_ffh_lpi_probe(pr->id);
+ if (ret == -EOPNOTSUPP)
+ return ret;
+
if (!osc_pc_lpi_support_confirmed)
return -EOPNOTSUPP;
@@ -1134,11 +1149,6 @@ static int acpi_processor_get_lpi_info(struct acpi_processor *pr)
return 0;
}
-int __weak acpi_processor_ffh_lpi_probe(unsigned int cpu)
-{
- return -ENODEV;
-}
-
int __weak acpi_processor_ffh_lpi_enter(struct acpi_lpi_state *lpi)
{
return -ENODEV;
diff --git a/drivers/acpi/property.c b/drivers/acpi/property.c
index d0986bda2964..12bbfe833609 100644
--- a/drivers/acpi/property.c
+++ b/drivers/acpi/property.c
@@ -541,7 +541,8 @@ acpi_device_data_of_node(const struct fwnode_handle *fwnode)
if (is_acpi_device_node(fwnode)) {
const struct acpi_device *adev = to_acpi_device_node(fwnode);
return &adev->data;
- } else if (is_acpi_data_node(fwnode)) {
+ }
+ if (is_acpi_data_node(fwnode)) {
const struct acpi_data_node *dn = to_acpi_data_node(fwnode);
return &dn->data;
}
@@ -685,7 +686,7 @@ int __acpi_node_get_property_reference(const struct fwnode_handle *fwnode,
*/
if (obj->type == ACPI_TYPE_LOCAL_REFERENCE) {
if (index)
- return -EINVAL;
+ return -ENOENT;
device = acpi_fetch_acpi_dev(obj->reference.handle);
if (!device)
@@ -739,14 +740,19 @@ int __acpi_node_get_property_reference(const struct fwnode_handle *fwnode,
return -EINVAL;
}
- /* assume following integer elements are all args */
+ /*
+ * Assume the following integer elements are all args.
+ * Stop counting on the first reference or end of the
+ * package arguments. In case of neither reference,
+ * nor integer, return an error, we can't parse it.
+ */
for (i = 0; element + i < end && i < num_args; i++) {
int type = element[i].type;
+ if (type == ACPI_TYPE_LOCAL_REFERENCE)
+ break;
if (type == ACPI_TYPE_INTEGER)
nargs++;
- else if (type == ACPI_TYPE_LOCAL_REFERENCE)
- break;
else
return -EINVAL;
}
@@ -950,7 +956,7 @@ static int acpi_data_prop_read(const struct acpi_device_data *data,
if (proptype != DEV_PROP_STRING && nval > obj->package.count)
return -EOVERFLOW;
- else if (nval <= 0)
+ if (nval == 0)
return -EINVAL;
items = obj->package.elements;
@@ -1012,14 +1018,10 @@ struct fwnode_handle *acpi_get_next_subnode(const struct fwnode_handle *fwnode,
const struct list_head *head;
struct list_head *next;
- if (!child || is_acpi_device_node(child)) {
+ if ((!child || is_acpi_device_node(child)) && adev) {
struct acpi_device *child_adev;
- if (adev)
- head = &adev->children;
- else
- goto nondev;
-
+ head = &adev->children;
if (list_empty(head))
goto nondev;
@@ -1089,7 +1091,8 @@ acpi_node_get_parent(const struct fwnode_handle *fwnode)
if (is_acpi_data_node(fwnode)) {
/* All data nodes have parent pointer so just return that */
return to_acpi_data_node(fwnode)->parent;
- } else if (is_acpi_device_node(fwnode)) {
+ }
+ if (is_acpi_device_node(fwnode)) {
struct device *dev = to_acpi_device_node(fwnode)->dev.parent;
if (dev)
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index 1331756d4cfc..c116e3a65ab4 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -477,7 +477,8 @@ static void acpi_device_del(struct acpi_device *device)
list_for_each_entry(acpi_device_bus_id, &acpi_bus_id_list, node)
if (!strcmp(acpi_device_bus_id->bus_id,
acpi_device_hid(device))) {
- ida_simple_remove(&acpi_device_bus_id->instance_ida, device->pnp.instance_no);
+ ida_free(&acpi_device_bus_id->instance_ida,
+ device->pnp.instance_no);
if (ida_is_empty(&acpi_device_bus_id->instance_ida)) {
list_del(&acpi_device_bus_id->node);
kfree_const(acpi_device_bus_id->bus_id);
@@ -642,7 +643,7 @@ static int acpi_device_set_name(struct acpi_device *device,
struct ida *instance_ida = &acpi_device_bus_id->instance_ida;
int result;
- result = ida_simple_get(instance_ida, 0, ACPI_MAX_DEVICE_INSTANCES, GFP_KERNEL);
+ result = ida_alloc(instance_ida, GFP_KERNEL);
if (result < 0)
return result;
@@ -1377,11 +1378,11 @@ static void acpi_set_pnp_ids(acpi_handle handle, struct acpi_device_pnp *pnp,
if (info->valid & ACPI_VALID_HID) {
acpi_add_id(pnp, info->hardware_id.string);
pnp->type.platform_id = 1;
- if (info->valid & ACPI_VALID_CID) {
- cid_list = &info->compatible_id_list;
- for (i = 0; i < cid_list->count; i++)
- acpi_add_id(pnp, cid_list->ids[i].string);
- }
+ }
+ if (info->valid & ACPI_VALID_CID) {
+ cid_list = &info->compatible_id_list;
+ for (i = 0; i < cid_list->count; i++)
+ acpi_add_id(pnp, cid_list->ids[i].string);
}
if (info->valid & ACPI_VALID_ADR) {
pnp->bus_address = info->address;
@@ -1734,17 +1735,21 @@ static bool acpi_device_enumeration_by_parent(struct acpi_device *device)
bool is_serial_bus_slave = false;
static const struct acpi_device_id ignore_serial_bus_ids[] = {
/*
- * These devices have multiple I2cSerialBus resources and an i2c-client
- * must be instantiated for each, each with its own i2c_device_id.
- * Normally we only instantiate an i2c-client for the first resource,
- * using the ACPI HID as id. These special cases are handled by the
- * drivers/platform/x86/i2c-multi-instantiate.c driver, which knows
- * which i2c_device_id to use for each resource.
+ * These devices have multiple SerialBus resources and a client
+ * device must be instantiated for each of them, each with
+ * its own device id.
+ * Normally we only instantiate one client device for the first
+ * resource, using the ACPI HID as id. These special cases are handled
+ * by the drivers/platform/x86/serial-multi-instantiate.c driver, which
+ * knows which client device id to use for each resource.
*/
{"BSG1160", },
{"BSG2150", },
+ {"CSC3551", },
{"INT33FE", },
{"INT3515", },
+ /* Non-conforming _HID for Cirrus Logic already released */
+ {"CLSA0100", },
/*
* HIDs of device with an UartSerialBusV2 resource for which userspace
* expects a regular tty cdev to be created (instead of the in kernel
diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c
index a60ff5dfed3a..c992e57b2c79 100644
--- a/drivers/acpi/sleep.c
+++ b/drivers/acpi/sleep.c
@@ -736,21 +736,15 @@ bool acpi_s2idle_wake(void)
return true;
}
- /* Check non-EC GPE wakeups and dispatch the EC GPE. */
+ /*
+ * Check non-EC GPE wakeups and if there are none, cancel the
+ * SCI-related wakeup and dispatch the EC GPE.
+ */
if (acpi_ec_dispatch_gpe()) {
pm_pr_dbg("ACPI non-EC GPE wakeup\n");
return true;
}
- /*
- * Cancel the SCI wakeup and process all pending events in case
- * there are any wakeup ones in there.
- *
- * Note that if any non-EC GPEs are active at this point, the
- * SCI will retrigger after the rearming below, so no events
- * should be missed by canceling the wakeup here.
- */
- pm_system_cancel_wakeup();
acpi_os_wait_events_complete();
/*
@@ -764,6 +758,9 @@ bool acpi_s2idle_wake(void)
return true;
}
+ pm_pr_dbg("Rearming ACPI SCI for wakeup\n");
+
+ pm_wakeup_clear(acpi_sci_irq);
rearm_wake_irq(acpi_sci_irq);
}
@@ -874,12 +871,7 @@ static inline void acpi_sleep_syscore_init(void) {}
#ifdef CONFIG_HIBERNATION
static unsigned long s4_hardware_signature;
static struct acpi_table_facs *facs;
-static int sigcheck = -1; /* Default behaviour is just to warn */
-
-void __init acpi_check_s4_hw_signature(int check)
-{
- sigcheck = check;
-}
+int acpi_check_s4_hw_signature = -1; /* Default behaviour is just to warn */
static int acpi_hibernation_begin(pm_message_t stage)
{
@@ -1004,7 +996,7 @@ static void acpi_sleep_hibernate_setup(void)
hibernation_set_ops(old_suspend_ordering ?
&acpi_hibernation_ops_old : &acpi_hibernation_ops);
sleep_states[ACPI_STATE_S4] = 1;
- if (!sigcheck)
+ if (!acpi_check_s4_hw_signature)
return;
acpi_get_table(ACPI_SIG_FACS, 1, (struct acpi_table_header **)&facs);
@@ -1016,7 +1008,7 @@ static void acpi_sleep_hibernate_setup(void)
*/
s4_hardware_signature = facs->hardware_signature;
- if (sigcheck > 0) {
+ if (acpi_check_s4_hw_signature > 0) {
/*
* If we're actually obeying the ACPI specification
* then the signature is written out as part of the
diff --git a/drivers/acpi/tables.c b/drivers/acpi/tables.c
index 0741a4933f62..ceee808f7f2a 100644
--- a/drivers/acpi/tables.c
+++ b/drivers/acpi/tables.c
@@ -400,7 +400,7 @@ int __init_or_acpilib acpi_table_parse_entries_array(
acpi_get_table(id, instance, &table_header);
if (!table_header) {
- pr_warn("%4.4s not present\n", id);
+ pr_debug("%4.4s not present\n", id);
return -ENODEV;
}
@@ -545,7 +545,7 @@ static const char table_sigs[][ACPI_NAMESEG_SIZE] __initconst = {
ACPI_SIG_WDDT, ACPI_SIG_WDRT, ACPI_SIG_DSDT, ACPI_SIG_FADT,
ACPI_SIG_PSDT, ACPI_SIG_RSDT, ACPI_SIG_XSDT, ACPI_SIG_SSDT,
ACPI_SIG_IORT, ACPI_SIG_NFIT, ACPI_SIG_HMAT, ACPI_SIG_PPTT,
- ACPI_SIG_NHLT, ACPI_SIG_AEST };
+ ACPI_SIG_NHLT, ACPI_SIG_AEST, ACPI_SIG_CEDT, ACPI_SIG_AGDI };
#define ACPI_HEADER_SIZE sizeof(struct acpi_table_header)
diff --git a/drivers/acpi/video_detect.c b/drivers/acpi/video_detect.c
index 4f64713e9917..becc198e4c22 100644
--- a/drivers/acpi/video_detect.c
+++ b/drivers/acpi/video_detect.c
@@ -415,6 +415,81 @@ static const struct dmi_system_id video_detect_dmi_table[] = {
DMI_MATCH(DMI_PRODUCT_NAME, "GA503"),
},
},
+ /*
+ * Clevo NL5xRU and NL5xNU/TUXEDO Aura 15 Gen1 and Gen2 have both a
+ * working native and video interface. However the default detection
+ * mechanism first registers the video interface before unregistering
+ * it again and switching to the native interface during boot. This
+ * results in a dangling SBIOS request for backlight change for some
+ * reason, causing the backlight to switch to ~2% once per boot on the
+ * first power cord connect or disconnect event. Setting the native
+ * interface explicitly circumvents this buggy behaviour, by avoiding
+ * the unregistering process.
+ */
+ {
+ .callback = video_detect_force_native,
+ .ident = "Clevo NL5xRU",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"),
+ DMI_MATCH(DMI_BOARD_NAME, "NL5xRU"),
+ },
+ },
+ {
+ .callback = video_detect_force_native,
+ .ident = "Clevo NL5xRU",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "SchenkerTechnologiesGmbH"),
+ DMI_MATCH(DMI_BOARD_NAME, "NL5xRU"),
+ },
+ },
+ {
+ .callback = video_detect_force_native,
+ .ident = "Clevo NL5xRU",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Notebook"),
+ DMI_MATCH(DMI_BOARD_NAME, "NL5xRU"),
+ },
+ },
+ {
+ .callback = video_detect_force_native,
+ .ident = "Clevo NL5xRU",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"),
+ DMI_MATCH(DMI_BOARD_NAME, "AURA1501"),
+ },
+ },
+ {
+ .callback = video_detect_force_native,
+ .ident = "Clevo NL5xRU",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"),
+ DMI_MATCH(DMI_BOARD_NAME, "EDUBOOK1502"),
+ },
+ },
+ {
+ .callback = video_detect_force_native,
+ .ident = "Clevo NL5xNU",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"),
+ DMI_MATCH(DMI_BOARD_NAME, "NL5xNU"),
+ },
+ },
+ {
+ .callback = video_detect_force_native,
+ .ident = "Clevo NL5xNU",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "SchenkerTechnologiesGmbH"),
+ DMI_MATCH(DMI_BOARD_NAME, "NL5xNU"),
+ },
+ },
+ {
+ .callback = video_detect_force_native,
+ .ident = "Clevo NL5xNU",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Notebook"),
+ DMI_MATCH(DMI_BOARD_NAME, "NL5xNU"),
+ },
+ },
/*
* Desktops which falsely report a backlight and which our heuristics
diff --git a/drivers/acpi/x86/s2idle.c b/drivers/acpi/x86/s2idle.c
index abc06e7f89d8..ed889f827f53 100644
--- a/drivers/acpi/x86/s2idle.c
+++ b/drivers/acpi/x86/s2idle.c
@@ -424,15 +424,11 @@ static int lps0_device_attach(struct acpi_device *adev,
mem_sleep_current = PM_SUSPEND_TO_IDLE;
/*
- * Some Intel based LPS0 systems, like ASUS Zenbook UX430UNR/i7-8550U don't
- * use intel-hid or intel-vbtn but require the EC GPE to be enabled while
- * suspended for certain wakeup devices to work, so mark it as wakeup-capable.
- *
- * Only enable on !AMD as enabling this universally causes problems for a number
- * of AMD based systems.
+ * Some LPS0 systems, like ASUS Zenbook UX430UNR/i7-8550U, require the
+ * EC GPE to be enabled while suspended for certain wakeup devices to
+ * work, so mark it as wakeup-capable.
*/
- if (!acpi_s2idle_vendor_amd())
- acpi_ec_mark_gpe_for_wake();
+ acpi_ec_mark_gpe_for_wake();
return 0;
}
diff --git a/drivers/acpi/x86/utils.c b/drivers/acpi/x86/utils.c
index ffdeed5334d6..664070fc8349 100644
--- a/drivers/acpi/x86/utils.c
+++ b/drivers/acpi/x86/utils.c
@@ -285,6 +285,27 @@ static const struct dmi_system_id acpi_quirk_skip_dmi_ids[] = {
ACPI_QUIRK_SKIP_ACPI_AC_AND_BATTERY),
},
{
+ /* Lenovo Yoga Tablet 1050F/L */
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Intel Corp."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "VALLEYVIEW C0 PLATFORM"),
+ DMI_MATCH(DMI_BOARD_NAME, "BYT-T FFD8"),
+ /* Partial match on beginning of BIOS version */
+ DMI_MATCH(DMI_BIOS_VERSION, "BLADE_21"),
+ },
+ .driver_data = (void *)(ACPI_QUIRK_SKIP_I2C_CLIENTS |
+ ACPI_QUIRK_SKIP_ACPI_AC_AND_BATTERY),
+ },
+ {
+ /* Nextbook Ares 8 */
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Insyde"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "M890BAP"),
+ },
+ .driver_data = (void *)(ACPI_QUIRK_SKIP_I2C_CLIENTS |
+ ACPI_QUIRK_SKIP_ACPI_AC_AND_BATTERY),
+ },
+ {
/* Whitelabel (sold as various brands) TM800A550L */
.matches = {
DMI_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"),
diff --git a/drivers/amba/bus.c b/drivers/amba/bus.c
index e1a5eca3ae3c..d3bd14aaabf6 100644
--- a/drivers/amba/bus.c
+++ b/drivers/amba/bus.c
@@ -370,6 +370,7 @@ int amba_driver_register(struct amba_driver *drv)
return driver_register(&drv->drv);
}
+EXPORT_SYMBOL(amba_driver_register);
/**
* amba_driver_unregister - remove an AMBA device driver
@@ -383,7 +384,7 @@ void amba_driver_unregister(struct amba_driver *drv)
{
driver_unregister(&drv->drv);
}
-
+EXPORT_SYMBOL(amba_driver_unregister);
static void amba_device_release(struct device *dev)
{
@@ -642,6 +643,7 @@ int amba_device_register(struct amba_device *dev, struct resource *parent)
return amba_device_add(dev, parent);
}
+EXPORT_SYMBOL(amba_device_register);
/**
* amba_device_put - put an AMBA device
@@ -668,66 +670,7 @@ void amba_device_unregister(struct amba_device *dev)
{
device_unregister(&dev->dev);
}
-
-
-struct find_data {
- struct amba_device *dev;
- struct device *parent;
- const char *busid;
- unsigned int id;
- unsigned int mask;
-};
-
-static int amba_find_match(struct device *dev, void *data)
-{
- struct find_data *d = data;
- struct amba_device *pcdev = to_amba_device(dev);
- int r;
-
- r = (pcdev->periphid & d->mask) == d->id;
- if (d->parent)
- r &= d->parent == dev->parent;
- if (d->busid)
- r &= strcmp(dev_name(dev), d->busid) == 0;
-
- if (r) {
- get_device(dev);
- d->dev = pcdev;
- }
-
- return r;
-}
-
-/**
- * amba_find_device - locate an AMBA device given a bus id
- * @busid: bus id for device (or NULL)
- * @parent: parent device (or NULL)
- * @id: peripheral ID (or 0)
- * @mask: peripheral ID mask (or 0)
- *
- * Return the AMBA device corresponding to the supplied parameters.
- * If no device matches, returns NULL.
- *
- * NOTE: When a valid device is found, its refcount is
- * incremented, and must be decremented before the returned
- * reference.
- */
-struct amba_device *
-amba_find_device(const char *busid, struct device *parent, unsigned int id,
- unsigned int mask)
-{
- struct find_data data;
-
- data.dev = NULL;
- data.parent = parent;
- data.busid = busid;
- data.id = id;
- data.mask = mask;
-
- bus_for_each_dev(&amba_bustype, NULL, &data, amba_find_match);
-
- return data.dev;
-}
+EXPORT_SYMBOL(amba_device_unregister);
/**
* amba_request_regions - request all mem regions associated with device
@@ -749,6 +692,7 @@ int amba_request_regions(struct amba_device *dev, const char *name)
return ret;
}
+EXPORT_SYMBOL(amba_request_regions);
/**
* amba_release_regions - release mem regions associated with device
@@ -763,11 +707,4 @@ void amba_release_regions(struct amba_device *dev)
size = resource_size(&dev->res);
release_mem_region(dev->res.start, size);
}
-
-EXPORT_SYMBOL(amba_driver_register);
-EXPORT_SYMBOL(amba_driver_unregister);
-EXPORT_SYMBOL(amba_device_register);
-EXPORT_SYMBOL(amba_device_unregister);
-EXPORT_SYMBOL(amba_find_device);
-EXPORT_SYMBOL(amba_request_regions);
EXPORT_SYMBOL(amba_release_regions);
diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig
index cb54631fd950..e5641e6c52ee 100644
--- a/drivers/ata/Kconfig
+++ b/drivers/ata/Kconfig
@@ -115,14 +115,14 @@ config SATA_AHCI
If unsure, say N.
-config SATA_MOBILE_LPM_POLICY
- int "Default SATA Link Power Management policy for mobile chipsets"
+config SATA_LPM_POLICY
+ int "Default SATA Link Power Management policy for low power chipsets"
range 0 4
default 0
depends on SATA_AHCI
help
Select the Default SATA Link Power Management (LPM) policy to use
- for mobile / laptop variants of chipsets / "South Bridges".
+ for chipsets / "South Bridges" designated as supporting low power.
The value set has the following meanings:
0 => Keep firmware settings
@@ -283,7 +283,7 @@ config SATA_FSL
config SATA_GEMINI
tristate "Gemini SATA bridge support"
- depends on ARCH_GEMINI || COMPILE_TEST
+ depends on ARCH_GEMINI || (OF && COMPILE_TEST)
select SATA_HOST
default ARCH_GEMINI
help
diff --git a/drivers/ata/acard-ahci.c b/drivers/ata/acard-ahci.c
index 536d4cb8f08b..7654a40c12b4 100644
--- a/drivers/ata/acard-ahci.c
+++ b/drivers/ata/acard-ahci.c
@@ -265,7 +265,7 @@ static bool acard_ahci_qc_fill_rtf(struct ata_queued_cmd *qc)
if (qc->tf.protocol == ATA_PROT_PIO && qc->dma_dir == DMA_FROM_DEVICE &&
!(qc->flags & ATA_QCFLAG_FAILED)) {
ata_tf_from_fis(rx_fis + RX_FIS_PIO_SETUP, &qc->result_tf);
- qc->result_tf.command = (rx_fis + RX_FIS_PIO_SETUP)[15];
+ qc->result_tf.status = (rx_fis + RX_FIS_PIO_SETUP)[15];
} else
ata_tf_from_fis(rx_fis + RX_FIS_D2H_REG, &qc->result_tf);
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c
index ab5811ef5a53..84456c05e845 100644
--- a/drivers/ata/ahci.c
+++ b/drivers/ata/ahci.c
@@ -50,7 +50,7 @@ enum board_ids {
/* board IDs by feature in alphabetical order */
board_ahci,
board_ahci_ign_iferr,
- board_ahci_mobile,
+ board_ahci_low_power,
board_ahci_no_debounce_delay,
board_ahci_nomsi,
board_ahci_noncq,
@@ -135,8 +135,8 @@ static const struct ata_port_info ahci_port_info[] = {
.udma_mask = ATA_UDMA6,
.port_ops = &ahci_ops,
},
- [board_ahci_mobile] = {
- AHCI_HFLAGS (AHCI_HFLAG_IS_MOBILE),
+ [board_ahci_low_power] = {
+ AHCI_HFLAGS (AHCI_HFLAG_USE_LPM_POLICY),
.flags = AHCI_FLAG_COMMON,
.pio_mask = ATA_PIO4,
.udma_mask = ATA_UDMA6,
@@ -275,13 +275,13 @@ static const struct pci_device_id ahci_pci_tbl[] = {
{ PCI_VDEVICE(INTEL, 0x2924), board_ahci }, /* ICH9 */
{ PCI_VDEVICE(INTEL, 0x2925), board_ahci }, /* ICH9 */
{ PCI_VDEVICE(INTEL, 0x2927), board_ahci }, /* ICH9 */
- { PCI_VDEVICE(INTEL, 0x2929), board_ahci_mobile }, /* ICH9M */
- { PCI_VDEVICE(INTEL, 0x292a), board_ahci_mobile }, /* ICH9M */
- { PCI_VDEVICE(INTEL, 0x292b), board_ahci_mobile }, /* ICH9M */
- { PCI_VDEVICE(INTEL, 0x292c), board_ahci_mobile }, /* ICH9M */
- { PCI_VDEVICE(INTEL, 0x292f), board_ahci_mobile }, /* ICH9M */
+ { PCI_VDEVICE(INTEL, 0x2929), board_ahci_low_power }, /* ICH9M */
+ { PCI_VDEVICE(INTEL, 0x292a), board_ahci_low_power }, /* ICH9M */
+ { PCI_VDEVICE(INTEL, 0x292b), board_ahci_low_power }, /* ICH9M */
+ { PCI_VDEVICE(INTEL, 0x292c), board_ahci_low_power }, /* ICH9M */
+ { PCI_VDEVICE(INTEL, 0x292f), board_ahci_low_power }, /* ICH9M */
{ PCI_VDEVICE(INTEL, 0x294d), board_ahci }, /* ICH9 */
- { PCI_VDEVICE(INTEL, 0x294e), board_ahci_mobile }, /* ICH9M */
+ { PCI_VDEVICE(INTEL, 0x294e), board_ahci_low_power }, /* ICH9M */
{ PCI_VDEVICE(INTEL, 0x502a), board_ahci }, /* Tolapai */
{ PCI_VDEVICE(INTEL, 0x502b), board_ahci }, /* Tolapai */
{ PCI_VDEVICE(INTEL, 0x3a05), board_ahci }, /* ICH10 */
@@ -291,9 +291,9 @@ static const struct pci_device_id ahci_pci_tbl[] = {
{ PCI_VDEVICE(INTEL, 0x3b23), board_ahci }, /* PCH AHCI */
{ PCI_VDEVICE(INTEL, 0x3b24), board_ahci }, /* PCH RAID */
{ PCI_VDEVICE(INTEL, 0x3b25), board_ahci }, /* PCH RAID */
- { PCI_VDEVICE(INTEL, 0x3b29), board_ahci_mobile }, /* PCH M AHCI */
+ { PCI_VDEVICE(INTEL, 0x3b29), board_ahci_low_power }, /* PCH M AHCI */
{ PCI_VDEVICE(INTEL, 0x3b2b), board_ahci }, /* PCH RAID */
- { PCI_VDEVICE(INTEL, 0x3b2c), board_ahci_mobile }, /* PCH M RAID */
+ { PCI_VDEVICE(INTEL, 0x3b2c), board_ahci_low_power }, /* PCH M RAID */
{ PCI_VDEVICE(INTEL, 0x3b2f), board_ahci }, /* PCH AHCI */
{ PCI_VDEVICE(INTEL, 0x19b0), board_ahci_pcs7 }, /* DNV AHCI */
{ PCI_VDEVICE(INTEL, 0x19b1), board_ahci_pcs7 }, /* DNV AHCI */
@@ -316,9 +316,9 @@ static const struct pci_device_id ahci_pci_tbl[] = {
{ PCI_VDEVICE(INTEL, 0x19cE), board_ahci_pcs7 }, /* DNV AHCI */
{ PCI_VDEVICE(INTEL, 0x19cF), board_ahci_pcs7 }, /* DNV AHCI */
{ PCI_VDEVICE(INTEL, 0x1c02), board_ahci }, /* CPT AHCI */
- { PCI_VDEVICE(INTEL, 0x1c03), board_ahci_mobile }, /* CPT M AHCI */
+ { PCI_VDEVICE(INTEL, 0x1c03), board_ahci_low_power }, /* CPT M AHCI */
{ PCI_VDEVICE(INTEL, 0x1c04), board_ahci }, /* CPT RAID */
- { PCI_VDEVICE(INTEL, 0x1c05), board_ahci_mobile }, /* CPT M RAID */
+ { PCI_VDEVICE(INTEL, 0x1c05), board_ahci_low_power }, /* CPT M RAID */
{ PCI_VDEVICE(INTEL, 0x1c06), board_ahci }, /* CPT RAID */
{ PCI_VDEVICE(INTEL, 0x1c07), board_ahci }, /* CPT RAID */
{ PCI_VDEVICE(INTEL, 0x1d02), board_ahci }, /* PBG AHCI */
@@ -327,29 +327,29 @@ static const struct pci_device_id ahci_pci_tbl[] = {
{ PCI_VDEVICE(INTEL, 0x2826), board_ahci }, /* PBG/Lewisburg RAID*/
{ PCI_VDEVICE(INTEL, 0x2323), board_ahci }, /* DH89xxCC AHCI */
{ PCI_VDEVICE(INTEL, 0x1e02), board_ahci }, /* Panther Point AHCI */
- { PCI_VDEVICE(INTEL, 0x1e03), board_ahci_mobile }, /* Panther M AHCI */
+ { PCI_VDEVICE(INTEL, 0x1e03), board_ahci_low_power }, /* Panther M AHCI */
{ PCI_VDEVICE(INTEL, 0x1e04), board_ahci }, /* Panther Point RAID */
{ PCI_VDEVICE(INTEL, 0x1e05), board_ahci }, /* Panther Point RAID */
{ PCI_VDEVICE(INTEL, 0x1e06), board_ahci }, /* Panther Point RAID */
- { PCI_VDEVICE(INTEL, 0x1e07), board_ahci_mobile }, /* Panther M RAID */
+ { PCI_VDEVICE(INTEL, 0x1e07), board_ahci_low_power }, /* Panther M RAID */
{ PCI_VDEVICE(INTEL, 0x1e0e), board_ahci }, /* Panther Point RAID */
{ PCI_VDEVICE(INTEL, 0x8c02), board_ahci }, /* Lynx Point AHCI */
- { PCI_VDEVICE(INTEL, 0x8c03), board_ahci_mobile }, /* Lynx M AHCI */
+ { PCI_VDEVICE(INTEL, 0x8c03), board_ahci_low_power }, /* Lynx M AHCI */
{ PCI_VDEVICE(INTEL, 0x8c04), board_ahci }, /* Lynx Point RAID */
- { PCI_VDEVICE(INTEL, 0x8c05), board_ahci_mobile }, /* Lynx M RAID */
+ { PCI_VDEVICE(INTEL, 0x8c05), board_ahci_low_power }, /* Lynx M RAID */
{ PCI_VDEVICE(INTEL, 0x8c06), board_ahci }, /* Lynx Point RAID */
- { PCI_VDEVICE(INTEL, 0x8c07), board_ahci_mobile }, /* Lynx M RAID */
+ { PCI_VDEVICE(INTEL, 0x8c07), board_ahci_low_power }, /* Lynx M RAID */
{ PCI_VDEVICE(INTEL, 0x8c0e), board_ahci }, /* Lynx Point RAID */
- { PCI_VDEVICE(INTEL, 0x8c0f), board_ahci_mobile }, /* Lynx M RAID */
- { PCI_VDEVICE(INTEL, 0x9c02), board_ahci_mobile }, /* Lynx LP AHCI */
- { PCI_VDEVICE(INTEL, 0x9c03), board_ahci_mobile }, /* Lynx LP AHCI */
- { PCI_VDEVICE(INTEL, 0x9c04), board_ahci_mobile }, /* Lynx LP RAID */
- { PCI_VDEVICE(INTEL, 0x9c05), board_ahci_mobile }, /* Lynx LP RAID */
- { PCI_VDEVICE(INTEL, 0x9c06), board_ahci_mobile }, /* Lynx LP RAID */
- { PCI_VDEVICE(INTEL, 0x9c07), board_ahci_mobile }, /* Lynx LP RAID */
- { PCI_VDEVICE(INTEL, 0x9c0e), board_ahci_mobile }, /* Lynx LP RAID */
- { PCI_VDEVICE(INTEL, 0x9c0f), board_ahci_mobile }, /* Lynx LP RAID */
- { PCI_VDEVICE(INTEL, 0x9dd3), board_ahci_mobile }, /* Cannon Lake PCH-LP AHCI */
+ { PCI_VDEVICE(INTEL, 0x8c0f), board_ahci_low_power }, /* Lynx M RAID */
+ { PCI_VDEVICE(INTEL, 0x9c02), board_ahci_low_power }, /* Lynx LP AHCI */
+ { PCI_VDEVICE(INTEL, 0x9c03), board_ahci_low_power }, /* Lynx LP AHCI */
+ { PCI_VDEVICE(INTEL, 0x9c04), board_ahci_low_power }, /* Lynx LP RAID */
+ { PCI_VDEVICE(INTEL, 0x9c05), board_ahci_low_power }, /* Lynx LP RAID */
+ { PCI_VDEVICE(INTEL, 0x9c06), board_ahci_low_power }, /* Lynx LP RAID */
+ { PCI_VDEVICE(INTEL, 0x9c07), board_ahci_low_power }, /* Lynx LP RAID */
+ { PCI_VDEVICE(INTEL, 0x9c0e), board_ahci_low_power }, /* Lynx LP RAID */
+ { PCI_VDEVICE(INTEL, 0x9c0f), board_ahci_low_power }, /* Lynx LP RAID */
+ { PCI_VDEVICE(INTEL, 0x9dd3), board_ahci_low_power }, /* Cannon Lake PCH-LP AHCI */
{ PCI_VDEVICE(INTEL, 0x1f22), board_ahci }, /* Avoton AHCI */
{ PCI_VDEVICE(INTEL, 0x1f23), board_ahci }, /* Avoton AHCI */
{ PCI_VDEVICE(INTEL, 0x1f24), board_ahci }, /* Avoton RAID */
@@ -381,26 +381,26 @@ static const struct pci_device_id ahci_pci_tbl[] = {
{ PCI_VDEVICE(INTEL, 0x8d66), board_ahci }, /* Wellsburg RAID */
{ PCI_VDEVICE(INTEL, 0x8d6e), board_ahci }, /* Wellsburg RAID */
{ PCI_VDEVICE(INTEL, 0x23a3), board_ahci }, /* Coleto Creek AHCI */
- { PCI_VDEVICE(INTEL, 0x9c83), board_ahci_mobile }, /* Wildcat LP AHCI */
- { PCI_VDEVICE(INTEL, 0x9c85), board_ahci_mobile }, /* Wildcat LP RAID */
- { PCI_VDEVICE(INTEL, 0x9c87), board_ahci_mobile }, /* Wildcat LP RAID */
- { PCI_VDEVICE(INTEL, 0x9c8f), board_ahci_mobile }, /* Wildcat LP RAID */
+ { PCI_VDEVICE(INTEL, 0x9c83), board_ahci_low_power }, /* Wildcat LP AHCI */
+ { PCI_VDEVICE(INTEL, 0x9c85), board_ahci_low_power }, /* Wildcat LP RAID */
+ { PCI_VDEVICE(INTEL, 0x9c87), board_ahci_low_power }, /* Wildcat LP RAID */
+ { PCI_VDEVICE(INTEL, 0x9c8f), board_ahci_low_power }, /* Wildcat LP RAID */
{ PCI_VDEVICE(INTEL, 0x8c82), board_ahci }, /* 9 Series AHCI */
- { PCI_VDEVICE(INTEL, 0x8c83), board_ahci_mobile }, /* 9 Series M AHCI */
+ { PCI_VDEVICE(INTEL, 0x8c83), board_ahci_low_power }, /* 9 Series M AHCI */
{ PCI_VDEVICE(INTEL, 0x8c84), board_ahci }, /* 9 Series RAID */
- { PCI_VDEVICE(INTEL, 0x8c85), board_ahci_mobile }, /* 9 Series M RAID */
+ { PCI_VDEVICE(INTEL, 0x8c85), board_ahci_low_power }, /* 9 Series M RAID */
{ PCI_VDEVICE(INTEL, 0x8c86), board_ahci }, /* 9 Series RAID */
- { PCI_VDEVICE(INTEL, 0x8c87), board_ahci_mobile }, /* 9 Series M RAID */
+ { PCI_VDEVICE(INTEL, 0x8c87), board_ahci_low_power }, /* 9 Series M RAID */
{ PCI_VDEVICE(INTEL, 0x8c8e), board_ahci }, /* 9 Series RAID */
- { PCI_VDEVICE(INTEL, 0x8c8f), board_ahci_mobile }, /* 9 Series M RAID */
- { PCI_VDEVICE(INTEL, 0x9d03), board_ahci_mobile }, /* Sunrise LP AHCI */
- { PCI_VDEVICE(INTEL, 0x9d05), board_ahci_mobile }, /* Sunrise LP RAID */
- { PCI_VDEVICE(INTEL, 0x9d07), board_ahci_mobile }, /* Sunrise LP RAID */
+ { PCI_VDEVICE(INTEL, 0x8c8f), board_ahci_low_power }, /* 9 Series M RAID */
+ { PCI_VDEVICE(INTEL, 0x9d03), board_ahci_low_power }, /* Sunrise LP AHCI */
+ { PCI_VDEVICE(INTEL, 0x9d05), board_ahci_low_power }, /* Sunrise LP RAID */
+ { PCI_VDEVICE(INTEL, 0x9d07), board_ahci_low_power }, /* Sunrise LP RAID */
{ PCI_VDEVICE(INTEL, 0xa102), board_ahci }, /* Sunrise Point-H AHCI */
- { PCI_VDEVICE(INTEL, 0xa103), board_ahci_mobile }, /* Sunrise M AHCI */
+ { PCI_VDEVICE(INTEL, 0xa103), board_ahci_low_power }, /* Sunrise M AHCI */
{ PCI_VDEVICE(INTEL, 0xa105), board_ahci }, /* Sunrise Point-H RAID */
{ PCI_VDEVICE(INTEL, 0xa106), board_ahci }, /* Sunrise Point-H RAID */
- { PCI_VDEVICE(INTEL, 0xa107), board_ahci_mobile }, /* Sunrise M RAID */
+ { PCI_VDEVICE(INTEL, 0xa107), board_ahci_low_power }, /* Sunrise M RAID */
{ PCI_VDEVICE(INTEL, 0xa10f), board_ahci }, /* Sunrise Point-H RAID */
{ PCI_VDEVICE(INTEL, 0xa182), board_ahci }, /* Lewisburg AHCI*/
{ PCI_VDEVICE(INTEL, 0xa186), board_ahci }, /* Lewisburg RAID*/
@@ -413,13 +413,13 @@ static const struct pci_device_id ahci_pci_tbl[] = {
{ PCI_VDEVICE(INTEL, 0xa356), board_ahci }, /* Cannon Lake PCH-H RAID */
{ PCI_VDEVICE(INTEL, 0x06d7), board_ahci }, /* Comet Lake-H RAID */
{ PCI_VDEVICE(INTEL, 0xa386), board_ahci }, /* Comet Lake PCH-V RAID */
- { PCI_VDEVICE(INTEL, 0x0f22), board_ahci_mobile }, /* Bay Trail AHCI */
- { PCI_VDEVICE(INTEL, 0x0f23), board_ahci_mobile }, /* Bay Trail AHCI */
- { PCI_VDEVICE(INTEL, 0x22a3), board_ahci_mobile }, /* Cherry Tr. AHCI */
- { PCI_VDEVICE(INTEL, 0x5ae3), board_ahci_mobile }, /* ApolloLake AHCI */
- { PCI_VDEVICE(INTEL, 0x34d3), board_ahci_mobile }, /* Ice Lake LP AHCI */
- { PCI_VDEVICE(INTEL, 0x02d3), board_ahci_mobile }, /* Comet Lake PCH-U AHCI */
- { PCI_VDEVICE(INTEL, 0x02d7), board_ahci_mobile }, /* Comet Lake PCH RAID */
+ { PCI_VDEVICE(INTEL, 0x0f22), board_ahci_low_power }, /* Bay Trail AHCI */
+ { PCI_VDEVICE(INTEL, 0x0f23), board_ahci_low_power }, /* Bay Trail AHCI */
+ { PCI_VDEVICE(INTEL, 0x22a3), board_ahci_low_power }, /* Cherry Tr. AHCI */
+ { PCI_VDEVICE(INTEL, 0x5ae3), board_ahci_low_power }, /* ApolloLake AHCI */
+ { PCI_VDEVICE(INTEL, 0x34d3), board_ahci_low_power }, /* Ice Lake LP AHCI */
+ { PCI_VDEVICE(INTEL, 0x02d3), board_ahci_low_power }, /* Comet Lake PCH-U AHCI */
+ { PCI_VDEVICE(INTEL, 0x02d7), board_ahci_low_power }, /* Comet Lake PCH RAID */
/* JMicron 360/1/3/5/6, match class to avoid IDE function */
{ PCI_VENDOR_ID_JMICRON, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
@@ -447,7 +447,7 @@ static const struct pci_device_id ahci_pci_tbl[] = {
{ PCI_VDEVICE(AMD, 0x7800), board_ahci }, /* AMD Hudson-2 */
{ PCI_VDEVICE(AMD, 0x7801), board_ahci_no_debounce_delay }, /* AMD Hudson-2 (AHCI mode) */
{ PCI_VDEVICE(AMD, 0x7900), board_ahci }, /* AMD CZ */
- { PCI_VDEVICE(AMD, 0x7901), board_ahci_mobile }, /* AMD Green Sardine */
+ { PCI_VDEVICE(AMD, 0x7901), board_ahci_low_power }, /* AMD Green Sardine */
/* AMD is using RAID class only for ahci controllers */
{ PCI_VENDOR_ID_AMD, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
PCI_CLASS_STORAGE_RAID << 8, 0xffffff, board_ahci },
@@ -582,6 +582,8 @@ static const struct pci_device_id ahci_pci_tbl[] = {
.driver_data = board_ahci_yes_fbs },
{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL_EXT, 0x9230),
.driver_data = board_ahci_yes_fbs },
+ { PCI_DEVICE(PCI_VENDOR_ID_MARVELL_EXT, 0x9235),
+ .driver_data = board_ahci_no_debounce_delay },
{ PCI_DEVICE(PCI_VENDOR_ID_TTI, 0x0642), /* highpoint rocketraid 642L */
.driver_data = board_ahci_yes_fbs },
{ PCI_DEVICE(PCI_VENDOR_ID_TTI, 0x0645), /* highpoint rocketraid 644L */
@@ -737,7 +739,7 @@ static int ahci_p5wdh_hardreset(struct ata_link *link, unsigned int *class,
/* clear D2H reception area to properly wait for D2H FIS */
ata_tf_init(link->device, &tf);
- tf.command = ATA_BUSY;
+ tf.status = ATA_BUSY;
ata_tf_to_fis(&tf, 0, 0, d2h_fis);
rc = sata_link_hardreset(link, sata_ehc_deb_timing(&link->eh_context),
@@ -806,7 +808,7 @@ static int ahci_avn_hardreset(struct ata_link *link, unsigned int *class,
/* clear D2H reception area to properly wait for D2H FIS */
ata_tf_init(link->device, &tf);
- tf.command = ATA_BUSY;
+ tf.status = ATA_BUSY;
ata_tf_to_fis(&tf, 0, 0, d2h_fis);
rc = sata_link_hardreset(link, timing, deadline, &online,
@@ -889,7 +891,8 @@ static int ahci_pci_device_suspend(struct device *dev)
}
ahci_pci_disable_interrupts(host);
- return ata_host_suspend(host, PMSG_SUSPEND);
+ ata_host_suspend(host, PMSG_SUSPEND);
+ return 0;
}
static int ahci_pci_device_resume(struct device *dev)
@@ -1592,11 +1595,11 @@ static int ahci_init_msi(struct pci_dev *pdev, unsigned int n_ports,
static void ahci_update_initial_lpm_policy(struct ata_port *ap,
struct ahci_host_priv *hpriv)
{
- int policy = CONFIG_SATA_MOBILE_LPM_POLICY;
+ int policy = CONFIG_SATA_LPM_POLICY;
- /* Ignore processing for non mobile platforms */
- if (!(hpriv->flags & AHCI_HFLAG_IS_MOBILE))
+ /* Ignore processing for chipsets that don't use policy */
+ if (!(hpriv->flags & AHCI_HFLAG_USE_LPM_POLICY))
return;
/* user modified policy via module param */
diff --git a/drivers/ata/ahci.h b/drivers/ata/ahci.h
index eeac5482f1d1..5badbaca05a0 100644
--- a/drivers/ata/ahci.h
+++ b/drivers/ata/ahci.h
@@ -235,8 +235,8 @@ enum {
AHCI_HFLAG_YES_ALPM = (1 << 23), /* force ALPM cap on */
AHCI_HFLAG_NO_WRITE_TO_RO = (1 << 24), /* don't write to read
only registers */
- AHCI_HFLAG_IS_MOBILE = (1 << 25), /* mobile chipset, use
- SATA_MOBILE_LPM_POLICY
+ AHCI_HFLAG_USE_LPM_POLICY = (1 << 25), /* chipset that should use
+ SATA_LPM_POLICY
as default lpm_policy */
AHCI_HFLAG_SUSPEND_PHYS = (1 << 26), /* handle PHYs during
suspend/resume */
diff --git a/drivers/ata/ahci_brcm.c b/drivers/ata/ahci_brcm.c
index 64dd8aa397d5..ab8552b1ff2a 100644
--- a/drivers/ata/ahci_brcm.c
+++ b/drivers/ata/ahci_brcm.c
@@ -427,7 +427,7 @@ static const struct of_device_id ahci_of_match[] = {
{.compatible = "brcm,bcm63138-ahci", .data = (void *)BRCM_SATA_BCM7445},
{.compatible = "brcm,bcm-nsp-ahci", .data = (void *)BRCM_SATA_NSP},
{.compatible = "brcm,bcm7216-ahci", .data = (void *)BRCM_SATA_BCM7216},
- {},
+ { /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, ahci_of_match);
diff --git a/drivers/ata/ahci_ceva.c b/drivers/ata/ahci_ceva.c
index acf59f51b356..cb24ecf36faf 100644
--- a/drivers/ata/ahci_ceva.c
+++ b/drivers/ata/ahci_ceva.c
@@ -363,7 +363,7 @@ static SIMPLE_DEV_PM_OPS(ahci_ceva_pm_ops, ceva_ahci_suspend, ceva_ahci_resume);
static const struct of_device_id ceva_ahci_of_match[] = {
{ .compatible = "ceva,ahci-1v84" },
- {},
+ { /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, ceva_ahci_of_match);
diff --git a/drivers/ata/ahci_da850.c b/drivers/ata/ahci_da850.c
index 0e8276600712..052c28e250aa 100644
--- a/drivers/ata/ahci_da850.c
+++ b/drivers/ata/ahci_da850.c
@@ -241,7 +241,7 @@ static SIMPLE_DEV_PM_OPS(ahci_da850_pm_ops, ahci_platform_suspend,
static const struct of_device_id ahci_da850_of_match[] = {
{ .compatible = "ti,da850-ahci", },
- { },
+ { /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, ahci_da850_of_match);
diff --git a/drivers/ata/ahci_dm816.c b/drivers/ata/ahci_dm816.c
index 8bec41041671..8a92112dcd59 100644
--- a/drivers/ata/ahci_dm816.c
+++ b/drivers/ata/ahci_dm816.c
@@ -176,7 +176,7 @@ static SIMPLE_DEV_PM_OPS(ahci_dm816_pm_ops,
static const struct of_device_id ahci_dm816_of_match[] = {
{ .compatible = "ti,dm816-ahci", },
- { },
+ { /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, ahci_dm816_of_match);
diff --git a/drivers/ata/ahci_imx.c b/drivers/ata/ahci_imx.c
index 388baf528fa8..79aa9f285312 100644
--- a/drivers/ata/ahci_imx.c
+++ b/drivers/ata/ahci_imx.c
@@ -811,7 +811,7 @@ static const struct of_device_id imx_ahci_of_match[] = {
{ .compatible = "fsl,imx6q-ahci", .data = (void *)AHCI_IMX6Q },
{ .compatible = "fsl,imx6qp-ahci", .data = (void *)AHCI_IMX6QP },
{ .compatible = "fsl,imx8qm-ahci", .data = (void *)AHCI_IMX8QM },
- {},
+ { /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, imx_ahci_of_match);
diff --git a/drivers/ata/ahci_mtk.c b/drivers/ata/ahci_mtk.c
index d9b08ae7c3b2..1f6c85fde983 100644
--- a/drivers/ata/ahci_mtk.c
+++ b/drivers/ata/ahci_mtk.c
@@ -169,7 +169,7 @@ static SIMPLE_DEV_PM_OPS(ahci_pm_ops, ahci_platform_suspend,
static const struct of_device_id ahci_of_match[] = {
{ .compatible = "mediatek,mtk-ahci", },
- {},
+ { /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, ahci_of_match);
diff --git a/drivers/ata/ahci_mvebu.c b/drivers/ata/ahci_mvebu.c
index 3ad46d26d9d5..991413a272e6 100644
--- a/drivers/ata/ahci_mvebu.c
+++ b/drivers/ata/ahci_mvebu.c
@@ -239,7 +239,7 @@ static const struct of_device_id ahci_mvebu_of_match[] = {
.compatible = "marvell,armada-3700-ahci",
.data = &ahci_mvebu_armada_3700_plat_data,
},
- { },
+ { /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, ahci_mvebu_of_match);
diff --git a/drivers/ata/ahci_octeon.c b/drivers/ata/ahci_octeon.c
index 5a44e089c6bb..b9460b91288f 100644
--- a/drivers/ata/ahci_octeon.c
+++ b/drivers/ata/ahci_octeon.c
@@ -80,7 +80,7 @@ static int ahci_octeon_remove(struct platform_device *pdev)
static const struct of_device_id octeon_ahci_match[] = {
{ .compatible = "cavium,octeon-7130-sata-uctl", },
- {},
+ { /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, octeon_ahci_match);
diff --git a/drivers/ata/ahci_platform.c b/drivers/ata/ahci_platform.c
index 3aab2e3d57f3..28a8de5b48b9 100644
--- a/drivers/ata/ahci_platform.c
+++ b/drivers/ata/ahci_platform.c
@@ -88,7 +88,7 @@ static const struct of_device_id ahci_of_match[] = {
{ .compatible = "snps,dwc-ahci", },
{ .compatible = "hisilicon,hisi-ahci", },
{ .compatible = "cavium,octeon-7130-ahci", },
- {},
+ { /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, ahci_of_match);
diff --git a/drivers/ata/ahci_qoriq.c b/drivers/ata/ahci_qoriq.c
index bf5b388bd4e0..6cd61842ad48 100644
--- a/drivers/ata/ahci_qoriq.c
+++ b/drivers/ata/ahci_qoriq.c
@@ -77,7 +77,7 @@ static const struct of_device_id ahci_qoriq_of_match[] = {
{ .compatible = "fsl,ls1088a-ahci", .data = (void *)AHCI_LS1088A},
{ .compatible = "fsl,ls2088a-ahci", .data = (void *)AHCI_LS2088A},
{ .compatible = "fsl,lx2160a-ahci", .data = (void *)AHCI_LX2160A},
- {},
+ { /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, ahci_qoriq_of_match);
@@ -123,7 +123,7 @@ static int ahci_qoriq_hardreset(struct ata_link *link, unsigned int *class,
/* clear D2H reception area to properly wait for D2H FIS */
ata_tf_init(link->device, &tf);
- tf.command = ATA_BUSY;
+ tf.status = ATA_BUSY;
ata_tf_to_fis(&tf, 0, 0, d2h_fis);
rc = sata_link_hardreset(link, timing, deadline, &online,
diff --git a/drivers/ata/ahci_st.c b/drivers/ata/ahci_st.c
index c268264c2129..7526653c843b 100644
--- a/drivers/ata/ahci_st.c
+++ b/drivers/ata/ahci_st.c
@@ -232,7 +232,7 @@ static SIMPLE_DEV_PM_OPS(st_ahci_pm_ops, st_ahci_suspend, st_ahci_resume);
static const struct of_device_id st_ahci_match[] = {
{ .compatible = "st,ahci", },
- {},
+ { /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, st_ahci_match);
diff --git a/drivers/ata/ahci_sunxi.c b/drivers/ata/ahci_sunxi.c
index 56b695136977..c7273c1cb0c7 100644
--- a/drivers/ata/ahci_sunxi.c
+++ b/drivers/ata/ahci_sunxi.c
@@ -286,7 +286,7 @@ static SIMPLE_DEV_PM_OPS(ahci_sunxi_pm_ops, ahci_platform_suspend,
static const struct of_device_id ahci_sunxi_of_match[] = {
{ .compatible = "allwinner,sun4i-a10-ahci", },
{ .compatible = "allwinner,sun8i-r40-ahci", },
- { },
+ { /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, ahci_sunxi_of_match);
diff --git a/drivers/ata/ahci_xgene.c b/drivers/ata/ahci_xgene.c
index 8e206379d699..7bb5db17f864 100644
--- a/drivers/ata/ahci_xgene.c
+++ b/drivers/ata/ahci_xgene.c
@@ -365,7 +365,7 @@ static int xgene_ahci_do_hardreset(struct ata_link *link,
do {
/* clear D2H reception area to properly wait for D2H FIS */
ata_tf_init(link->device, &tf);
- tf.command = ATA_BUSY;
+ tf.status = ATA_BUSY;
ata_tf_to_fis(&tf, 0, 0, d2h_fis);
rc = sata_link_hardreset(link, timing, deadline, online,
ahci_check_ready);
@@ -726,7 +726,7 @@ MODULE_DEVICE_TABLE(acpi, xgene_ahci_acpi_match);
static const struct of_device_id xgene_ahci_of_match[] = {
{.compatible = "apm,xgene-ahci", .data = (void *) XGENE_AHCI_V1},
{.compatible = "apm,xgene-ahci-v2", .data = (void *) XGENE_AHCI_V2},
- {},
+ { /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, xgene_ahci_of_match);
diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c
index 27b0d903f91f..ade5e894563b 100644
--- a/drivers/ata/ata_piix.c
+++ b/drivers/ata/ata_piix.c
@@ -993,11 +993,8 @@ static int piix_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg)
{
struct ata_host *host = pci_get_drvdata(pdev);
unsigned long flags;
- int rc = 0;
- rc = ata_host_suspend(host, mesg);
- if (rc)
- return rc;
+ ata_host_suspend(host, mesg);
/* Some braindamaged ACPI suspend implementations expect the
* controller to be awake on entry; otherwise, it burns cpu
diff --git a/drivers/ata/libahci.c b/drivers/ata/libahci.c
index 0ed484e04fd6..cf8c7fd59ada 100644
--- a/drivers/ata/libahci.c
+++ b/drivers/ata/libahci.c
@@ -1561,7 +1561,7 @@ int ahci_do_hardreset(struct ata_link *link, unsigned int *class,
/* clear D2H reception area to properly wait for D2H FIS */
ata_tf_init(link->device, &tf);
- tf.command = ATA_BUSY;
+ tf.status = ATA_BUSY;
ata_tf_to_fis(&tf, 0, 0, d2h_fis);
rc = sata_link_hardreset(link, timing, deadline, online,
@@ -2033,7 +2033,7 @@ static bool ahci_qc_fill_rtf(struct ata_queued_cmd *qc)
if (qc->tf.protocol == ATA_PROT_PIO && qc->dma_dir == DMA_FROM_DEVICE &&
!(qc->flags & ATA_QCFLAG_FAILED)) {
ata_tf_from_fis(rx_fis + RX_FIS_PIO_SETUP, &qc->result_tf);
- qc->result_tf.command = (rx_fis + RX_FIS_PIO_SETUP)[15];
+ qc->result_tf.status = (rx_fis + RX_FIS_PIO_SETUP)[15];
} else
ata_tf_from_fis(rx_fis + RX_FIS_D2H_REG, &qc->result_tf);
diff --git a/drivers/ata/libahci_platform.c b/drivers/ata/libahci_platform.c
index 18296443ccba..65227ef6b846 100644
--- a/drivers/ata/libahci_platform.c
+++ b/drivers/ata/libahci_platform.c
@@ -733,7 +733,8 @@ int ahci_platform_suspend_host(struct device *dev)
if (hpriv->flags & AHCI_HFLAG_SUSPEND_PHYS)
ahci_platform_disable_phys(hpriv);
- return ata_host_suspend(host, PMSG_SUSPEND);
+ ata_host_suspend(host, PMSG_SUSPEND);
+ return 0;
}
EXPORT_SYMBOL_GPL(ahci_platform_suspend_host);
diff --git a/drivers/ata/libata-acpi.c b/drivers/ata/libata-acpi.c
index 8cfa8c96bb13..3d345d173556 100644
--- a/drivers/ata/libata-acpi.c
+++ b/drivers/ata/libata-acpi.c
@@ -546,13 +546,13 @@ static void ata_acpi_gtf_to_tf(struct ata_device *dev,
tf->flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
tf->protocol = ATA_PROT_NODATA;
- tf->feature = gtf->tf[0]; /* 0x1f1 */
+ tf->error = gtf->tf[0]; /* 0x1f1 */
tf->nsect = gtf->tf[1]; /* 0x1f2 */
tf->lbal = gtf->tf[2]; /* 0x1f3 */
tf->lbam = gtf->tf[3]; /* 0x1f4 */
tf->lbah = gtf->tf[4]; /* 0x1f5 */
tf->device = gtf->tf[5]; /* 0x1f6 */
- tf->command = gtf->tf[6]; /* 0x1f7 */
+ tf->status = gtf->tf[6]; /* 0x1f7 */
}
static int ata_acpi_filter_tf(struct ata_device *dev,
@@ -679,7 +679,7 @@ static int ata_acpi_run_tf(struct ata_device *dev,
"(%s) rejected by device (Stat=0x%02x Err=0x%02x)",
tf.command, tf.feature, tf.nsect, tf.lbal,
tf.lbam, tf.lbah, tf.device, descr,
- rtf.command, rtf.feature);
+ rtf.status, rtf.error);
rc = 0;
break;
@@ -689,7 +689,7 @@ static int ata_acpi_run_tf(struct ata_device *dev,
"(%s) failed (Emask=0x%x Stat=0x%02x Err=0x%02x)",
tf.command, tf.feature, tf.nsect, tf.lbal,
tf.lbam, tf.lbah, tf.device, descr,
- err_mask, rtf.command, rtf.feature);
+ err_mask, rtf.status, rtf.error);
rc = -EIO;
break;
}
@@ -800,27 +800,6 @@ static int ata_acpi_push_id(struct ata_device *dev)
}
/**
- * ata_acpi_on_suspend - ATA ACPI hook called on suspend
- * @ap: target ATA port
- *
- * This function is called when @ap is about to be suspended. All
- * devices are already put to sleep but the port_suspend() callback
- * hasn't been executed yet. Error return from this function aborts
- * suspend.
- *
- * LOCKING:
- * EH context.
- *
- * RETURNS:
- * 0 on success, -errno on failure.
- */
-int ata_acpi_on_suspend(struct ata_port *ap)
-{
- /* nada */
- return 0;
-}
-
-/**
* ata_acpi_on_resume - ATA ACPI hook called on resume
* @ap: target ATA port
*
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index 67f88027680a..cceedde51126 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -1171,7 +1171,7 @@ static int ata_read_native_max_address(struct ata_device *dev, u64 *max_sectors)
ata_dev_warn(dev,
"failed to read native max address (err_mask=0x%x)\n",
err_mask);
- if (err_mask == AC_ERR_DEV && (tf.feature & ATA_ABORTED))
+ if (err_mask == AC_ERR_DEV && (tf.error & ATA_ABORTED))
return -EACCES;
return -EIO;
}
@@ -1235,7 +1235,7 @@ static int ata_set_max_sectors(struct ata_device *dev, u64 new_sectors)
"failed to set max address (err_mask=0x%x)\n",
err_mask);
if (err_mask == AC_ERR_DEV &&
- (tf.feature & (ATA_ABORTED | ATA_IDNF)))
+ (tf.error & (ATA_ABORTED | ATA_IDNF)))
return -EACCES;
return -EIO;
}
@@ -1584,7 +1584,7 @@ unsigned ata_exec_internal_sg(struct ata_device *dev,
/* perform minimal error analysis */
if (qc->flags & ATA_QCFLAG_FAILED) {
- if (qc->result_tf.command & (ATA_ERR | ATA_DF))
+ if (qc->result_tf.status & (ATA_ERR | ATA_DF))
qc->err_mask |= AC_ERR_DEV;
if (!qc->err_mask)
@@ -1593,7 +1593,7 @@ unsigned ata_exec_internal_sg(struct ata_device *dev,
if (qc->err_mask & ~AC_ERR_OTHER)
qc->err_mask &= ~AC_ERR_OTHER;
} else if (qc->tf.command == ATA_CMD_REQ_SENSE_DATA) {
- qc->result_tf.command |= ATA_SENSE;
+ qc->result_tf.status |= ATA_SENSE;
}
/* finish up */
@@ -1813,7 +1813,7 @@ retry:
return 0;
}
- if ((err_mask == AC_ERR_DEV) && (tf.feature & ATA_ABORTED)) {
+ if ((err_mask == AC_ERR_DEV) && (tf.error & ATA_ABORTED)) {
/* Device or controller might have reported
* the wrong device class. Give a shot at the
* other IDENTIFY if the current one is
@@ -2007,6 +2007,9 @@ static bool ata_log_supported(struct ata_device *dev, u8 log)
{
struct ata_port *ap = dev->link->ap;
+ if (dev->horkage & ATA_HORKAGE_NO_LOG_DIR)
+ return false;
+
if (ata_read_log_page(dev, ATA_LOG_DIRECTORY, 0, ap->sector_buf, 1))
return false;
return get_unaligned_le16(&ap->sector_buf[log * 2]) ? true : false;
@@ -2445,23 +2448,21 @@ static void ata_dev_config_cpr(struct ata_device *dev)
struct ata_cpr_log *cpr_log = NULL;
u8 *desc, *buf = NULL;
- if (!ata_identify_page_supported(dev,
- ATA_LOG_CONCURRENT_POSITIONING_RANGES))
+ if (ata_id_major_version(dev->id) < 11 ||
+ !ata_log_supported(dev, ATA_LOG_CONCURRENT_POSITIONING_RANGES))
goto out;
/*
- * Read IDENTIFY DEVICE data log, page 0x47
- * (concurrent positioning ranges). We can have at most 255 32B range
- * descriptors plus a 64B header.
+ * Read the concurrent positioning ranges log (0x47). We can have at
+ * most 255 32B range descriptors plus a 64B header.
*/
buf_len = (64 + 255 * 32 + 511) & ~511;
buf = kzalloc(buf_len, GFP_KERNEL);
if (!buf)
goto out;
- err_mask = ata_read_log_page(dev, ATA_LOG_IDENTIFY_DEVICE,
- ATA_LOG_CONCURRENT_POSITIONING_RANGES,
- buf, buf_len >> 9);
+ err_mask = ata_read_log_page(dev, ATA_LOG_CONCURRENT_POSITIONING_RANGES,
+ 0, buf, buf_len >> 9);
if (err_mask)
goto out;
@@ -3568,7 +3569,7 @@ EXPORT_SYMBOL_GPL(ata_wait_after_reset);
* Kernel thread context (may sleep)
*
* RETURNS:
- * 0 on success, -errno otherwise.
+ * Always 0.
*/
int ata_std_prereset(struct ata_link *link, unsigned long deadline)
{
@@ -4028,6 +4029,7 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = {
/* devices that don't properly handle TRIM commands */
{ "SuperSSpeed S238*", NULL, ATA_HORKAGE_NOTRIM, },
+ { "M88V29*", NULL, ATA_HORKAGE_NOTRIM, },
/*
* As defined, the DRAT (Deterministic Read After Trim) and RZAT
@@ -4073,6 +4075,13 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = {
{ "WDC WD3000JD-*", NULL, ATA_HORKAGE_WD_BROKEN_LPM },
{ "WDC WD3200JD-*", NULL, ATA_HORKAGE_WD_BROKEN_LPM },
+ /*
+ * This sata dom device goes on a walkabout when the ATA_LOG_DIRECTORY
+ * log page is accessed. Ensure we never ask for this log page with
+ * these devices.
+ */
+ { "SATADOM-ML 3ME", NULL, ATA_HORKAGE_NO_LOG_DIR },
+
/* End Marker */
{ }
};
@@ -4375,7 +4384,7 @@ static unsigned int ata_dev_init_params(struct ata_device *dev,
/* A clean abort indicates an original or just out of spec drive
and we should continue as we issue the setup based on the
drive reported working geometry */
- if (err_mask == AC_ERR_DEV && (tf.feature & ATA_ABORTED))
+ if (err_mask == AC_ERR_DEV && (tf.error & ATA_ABORTED))
err_mask = 0;
return err_mask;
@@ -5170,10 +5179,9 @@ EXPORT_SYMBOL_GPL(ata_sas_port_resume);
*
* Suspend @host. Actual operation is performed by port suspend.
*/
-int ata_host_suspend(struct ata_host *host, pm_message_t mesg)
+void ata_host_suspend(struct ata_host *host, pm_message_t mesg)
{
host->dev->power.power_state = mesg;
- return 0;
}
EXPORT_SYMBOL_GPL(ata_host_suspend);
@@ -6090,11 +6098,8 @@ EXPORT_SYMBOL_GPL(ata_pci_device_do_resume);
int ata_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg)
{
struct ata_host *host = pci_get_drvdata(pdev);
- int rc = 0;
- rc = ata_host_suspend(host, mesg);
- if (rc)
- return rc;
+ ata_host_suspend(host, mesg);
ata_pci_device_do_suspend(pdev, mesg);
diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c
index 7951fd946bf9..3307ed45fe4d 100644
--- a/drivers/ata/libata-eh.c
+++ b/drivers/ata/libata-eh.c
@@ -1386,7 +1386,7 @@ unsigned int atapi_eh_tur(struct ata_device *dev, u8 *r_sense_key)
err_mask = ata_exec_internal(dev, &tf, cdb, DMA_NONE, NULL, 0, 0);
if (err_mask == AC_ERR_DEV)
- *r_sense_key = tf.feature >> 4;
+ *r_sense_key = tf.error >> 4;
return err_mask;
}
@@ -1429,12 +1429,12 @@ static void ata_eh_request_sense(struct ata_queued_cmd *qc,
err_mask = ata_exec_internal(dev, &tf, NULL, DMA_NONE, NULL, 0, 0);
/* Ignore err_mask; ATA_ERR might be set */
- if (tf.command & ATA_SENSE) {
+ if (tf.status & ATA_SENSE) {
ata_scsi_set_sense(dev, cmd, tf.lbah, tf.lbam, tf.lbal);
qc->flags |= ATA_QCFLAG_SENSE_VALID;
} else {
ata_dev_warn(dev, "request sense failed stat %02x emask %x\n",
- tf.command, err_mask);
+ tf.status, err_mask);
}
}
@@ -1557,7 +1557,7 @@ static unsigned int ata_eh_analyze_tf(struct ata_queued_cmd *qc,
const struct ata_taskfile *tf)
{
unsigned int tmp, action = 0;
- u8 stat = tf->command, err = tf->feature;
+ u8 stat = tf->status, err = tf->error;
if ((stat & (ATA_BUSY | ATA_DRQ | ATA_DRDY)) != ATA_DRDY) {
qc->err_mask |= AC_ERR_HSM;
@@ -1594,7 +1594,7 @@ static unsigned int ata_eh_analyze_tf(struct ata_queued_cmd *qc,
if (!(qc->ap->pflags & ATA_PFLAG_FROZEN)) {
tmp = atapi_eh_request_sense(qc->dev,
qc->scsicmd->sense_buffer,
- qc->result_tf.feature >> 4);
+ qc->result_tf.error >> 4);
if (!tmp)
qc->flags |= ATA_QCFLAG_SENSE_VALID;
else
@@ -2360,7 +2360,7 @@ static void ata_eh_link_report(struct ata_link *link)
cmd->hob_feature, cmd->hob_nsect,
cmd->hob_lbal, cmd->hob_lbam, cmd->hob_lbah,
cmd->device, qc->tag, data_buf, cdb_buf,
- res->command, res->feature, res->nsect,
+ res->status, res->error, res->nsect,
res->lbal, res->lbam, res->lbah,
res->hob_feature, res->hob_nsect,
res->hob_lbal, res->hob_lbam, res->hob_lbah,
@@ -2368,28 +2368,28 @@ static void ata_eh_link_report(struct ata_link *link)
qc->err_mask & AC_ERR_NCQ ? " <F>" : "");
#ifdef CONFIG_ATA_VERBOSE_ERROR
- if (res->command & (ATA_BUSY | ATA_DRDY | ATA_DF | ATA_DRQ |
- ATA_SENSE | ATA_ERR)) {
- if (res->command & ATA_BUSY)
+ if (res->status & (ATA_BUSY | ATA_DRDY | ATA_DF | ATA_DRQ |
+ ATA_SENSE | ATA_ERR)) {
+ if (res->status & ATA_BUSY)
ata_dev_err(qc->dev, "status: { Busy }\n");
else
ata_dev_err(qc->dev, "status: { %s%s%s%s%s}\n",
- res->command & ATA_DRDY ? "DRDY " : "",
- res->command & ATA_DF ? "DF " : "",
- res->command & ATA_DRQ ? "DRQ " : "",
- res->command & ATA_SENSE ? "SENSE " : "",
- res->command & ATA_ERR ? "ERR " : "");
+ res->status & ATA_DRDY ? "DRDY " : "",
+ res->status & ATA_DF ? "DF " : "",
+ res->status & ATA_DRQ ? "DRQ " : "",
+ res->status & ATA_SENSE ? "SENSE " : "",
+ res->status & ATA_ERR ? "ERR " : "");
}
if (cmd->command != ATA_CMD_PACKET &&
- (res->feature & (ATA_ICRC | ATA_UNC | ATA_AMNF |
- ATA_IDNF | ATA_ABORTED)))
+ (res->error & (ATA_ICRC | ATA_UNC | ATA_AMNF | ATA_IDNF |
+ ATA_ABORTED)))
ata_dev_err(qc->dev, "error: { %s%s%s%s%s}\n",
- res->feature & ATA_ICRC ? "ICRC " : "",
- res->feature & ATA_UNC ? "UNC " : "",
- res->feature & ATA_AMNF ? "AMNF " : "",
- res->feature & ATA_IDNF ? "IDNF " : "",
- res->feature & ATA_ABORTED ? "ABRT " : "");
+ res->error & ATA_ICRC ? "ICRC " : "",
+ res->error & ATA_UNC ? "UNC " : "",
+ res->error & ATA_AMNF ? "AMNF " : "",
+ res->error & ATA_IDNF ? "IDNF " : "",
+ res->error & ATA_ABORTED ? "ABRT " : "");
#endif
}
}
@@ -3902,11 +3902,6 @@ static void ata_eh_handle_port_suspend(struct ata_port *ap)
}
}
- /* tell ACPI we're suspending */
- rc = ata_acpi_on_suspend(ap);
- if (rc)
- goto out;
-
/* suspend */
ata_eh_freeze_port(ap);
@@ -3914,7 +3909,7 @@ static void ata_eh_handle_port_suspend(struct ata_port *ap)
rc = ap->ops->port_suspend(ap, ap->pm_mesg);
ata_acpi_set_state(ap, ap->pm_mesg);
- out:
+
/* update the flags */
spin_lock_irqsave(ap->lock, flags);
diff --git a/drivers/ata/libata-sata.c b/drivers/ata/libata-sata.c
index 071158c0c44c..044a16daa2d4 100644
--- a/drivers/ata/libata-sata.c
+++ b/drivers/ata/libata-sata.c
@@ -191,8 +191,8 @@ EXPORT_SYMBOL_GPL(ata_tf_to_fis);
void ata_tf_from_fis(const u8 *fis, struct ata_taskfile *tf)
{
- tf->command = fis[2]; /* status */
- tf->feature = fis[3]; /* error */
+ tf->status = fis[2];
+ tf->error = fis[3];
tf->lbal = fis[4];
tf->lbam = fis[5];
@@ -1406,8 +1406,8 @@ static int ata_eh_read_log_10h(struct ata_device *dev,
*tag = buf[0] & 0x1f;
- tf->command = buf[2];
- tf->feature = buf[3];
+ tf->status = buf[2];
+ tf->error = buf[3];
tf->lbal = buf[4];
tf->lbam = buf[5];
tf->lbah = buf[6];
@@ -1482,7 +1482,7 @@ void ata_eh_analyze_ncq_error(struct ata_link *link)
qc->result_tf.flags = ATA_TFLAG_ISADDR | ATA_TFLAG_LBA | ATA_TFLAG_LBA48;
qc->err_mask |= AC_ERR_DEV | AC_ERR_NCQ;
if (dev->class == ATA_DEV_ZAC &&
- ((qc->result_tf.command & ATA_SENSE) || qc->result_tf.auxiliary)) {
+ ((qc->result_tf.status & ATA_SENSE) || qc->result_tf.auxiliary)) {
char sense_key, asc, ascq;
sense_key = (qc->result_tf.auxiliary >> 16) & 0xff;
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
index c8283bd4ffd1..06c9d90238d9 100644
--- a/drivers/ata/libata-scsi.c
+++ b/drivers/ata/libata-scsi.c
@@ -680,7 +680,7 @@ static void ata_qc_set_pc_nbytes(struct ata_queued_cmd *qc)
*/
static void ata_dump_status(struct ata_port *ap, struct ata_taskfile *tf)
{
- u8 stat = tf->command, err = tf->feature;
+ u8 stat = tf->status, err = tf->error;
if (stat & ATA_BUSY) {
ata_port_warn(ap, "status=0x%02x {Busy} ", stat);
@@ -871,8 +871,8 @@ static void ata_gen_passthru_sense(struct ata_queued_cmd *qc)
* onto sense key, asc & ascq.
*/
if (qc->err_mask ||
- tf->command & (ATA_BUSY | ATA_DF | ATA_ERR | ATA_DRQ)) {
- ata_to_sense_error(qc->ap->print_id, tf->command, tf->feature,
+ tf->status & (ATA_BUSY | ATA_DF | ATA_ERR | ATA_DRQ)) {
+ ata_to_sense_error(qc->ap->print_id, tf->status, tf->error,
&sense_key, &asc, &ascq, verbose);
ata_scsi_set_sense(qc->dev, cmd, sense_key, asc, ascq);
} else {
@@ -901,13 +901,13 @@ static void ata_gen_passthru_sense(struct ata_queued_cmd *qc)
* Copy registers into sense buffer.
*/
desc[2] = 0x00;
- desc[3] = tf->feature; /* == error reg */
+ desc[3] = tf->error;
desc[5] = tf->nsect;
desc[7] = tf->lbal;
desc[9] = tf->lbam;
desc[11] = tf->lbah;
desc[12] = tf->device;
- desc[13] = tf->command; /* == status reg */
+ desc[13] = tf->status;
/*
* Fill in Extend bit, and the high order bytes
@@ -922,8 +922,8 @@ static void ata_gen_passthru_sense(struct ata_queued_cmd *qc)
}
} else {
/* Fixed sense format */
- desc[0] = tf->feature;
- desc[1] = tf->command; /* status */
+ desc[0] = tf->error;
+ desc[1] = tf->status;
desc[2] = tf->device;
desc[3] = tf->nsect;
desc[7] = 0;
@@ -972,14 +972,14 @@ static void ata_gen_ata_sense(struct ata_queued_cmd *qc)
* onto sense key, asc & ascq.
*/
if (qc->err_mask ||
- tf->command & (ATA_BUSY | ATA_DF | ATA_ERR | ATA_DRQ)) {
- ata_to_sense_error(qc->ap->print_id, tf->command, tf->feature,
+ tf->status & (ATA_BUSY | ATA_DF | ATA_ERR | ATA_DRQ)) {
+ ata_to_sense_error(qc->ap->print_id, tf->status, tf->error,
&sense_key, &asc, &ascq, verbose);
ata_scsi_set_sense(dev, cmd, sense_key, asc, ascq);
} else {
/* Could not decode error */
ata_dev_warn(dev, "could not decode error status 0x%x err_mask 0x%x\n",
- tf->command, qc->err_mask);
+ tf->status, qc->err_mask);
ata_scsi_set_sense(dev, cmd, ABORTED_COMMAND, 0, 0);
return;
}
@@ -1316,21 +1316,10 @@ static void scsi_6_lba_len(const u8 *cdb, u64 *plba, u32 *plen)
* @plba: the LBA
* @plen: the transfer length
*/
-static void scsi_10_lba_len(const u8 *cdb, u64 *plba, u32 *plen)
+static inline void scsi_10_lba_len(const u8 *cdb, u64 *plba, u32 *plen)
{
- u64 lba = 0;
- u32 len = 0;
-
- lba |= ((u64)cdb[2]) << 24;
- lba |= ((u64)cdb[3]) << 16;
- lba |= ((u64)cdb[4]) << 8;
- lba |= ((u64)cdb[5]);
-
- len |= ((u32)cdb[7]) << 8;
- len |= ((u32)cdb[8]);
-
- *plba = lba;
- *plen = len;
+ *plba = get_unaligned_be32(&cdb[2]);
+ *plen = get_unaligned_be16(&cdb[7]);
}
/**
@@ -1343,27 +1332,10 @@ static void scsi_10_lba_len(const u8 *cdb, u64 *plba, u32 *plen)
* @plba: the LBA
* @plen: the transfer length
*/
-static void scsi_16_lba_len(const u8 *cdb, u64 *plba, u32 *plen)
+static inline void scsi_16_lba_len(const u8 *cdb, u64 *plba, u32 *plen)
{
- u64 lba = 0;
- u32 len = 0;
-
- lba |= ((u64)cdb[2]) << 56;
- lba |= ((u64)cdb[3]) << 48;
- lba |= ((u64)cdb[4]) << 40;
- lba |= ((u64)cdb[5]) << 32;
- lba |= ((u64)cdb[6]) << 24;
- lba |= ((u64)cdb[7]) << 16;
- lba |= ((u64)cdb[8]) << 8;
- lba |= ((u64)cdb[9]);
-
- len |= ((u32)cdb[10]) << 24;
- len |= ((u32)cdb[11]) << 16;
- len |= ((u32)cdb[12]) << 8;
- len |= ((u32)cdb[13]);
-
- *plba = lba;
- *plen = len;
+ *plba = get_unaligned_be64(&cdb[2]);
+ *plen = get_unaligned_be32(&cdb[10]);
}
/**
@@ -1392,19 +1364,22 @@ static unsigned int ata_scsi_verify_xlat(struct ata_queued_cmd *qc)
tf->flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
tf->protocol = ATA_PROT_NODATA;
- if (cdb[0] == VERIFY) {
+ switch (cdb[0]) {
+ case VERIFY:
if (scmd->cmd_len < 10) {
fp = 9;
goto invalid_fld;
}
scsi_10_lba_len(cdb, &block, &n_block);
- } else if (cdb[0] == VERIFY_16) {
+ break;
+ case VERIFY_16:
if (scmd->cmd_len < 16) {
fp = 15;
goto invalid_fld;
}
scsi_16_lba_len(cdb, &block, &n_block);
- } else {
+ break;
+ default:
fp = 0;
goto invalid_fld;
}
@@ -1536,8 +1511,13 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc)
int rc;
u16 fp = 0;
- if (cdb[0] == WRITE_10 || cdb[0] == WRITE_6 || cdb[0] == WRITE_16)
+ switch (cdb[0]) {
+ case WRITE_6:
+ case WRITE_10:
+ case WRITE_16:
tf_flags |= ATA_TFLAG_WRITE;
+ break;
+ }
/* Calculate the SCSI LBA, transfer length and FUA. */
switch (cdb[0]) {
@@ -2495,7 +2475,7 @@ static void atapi_request_sense(struct ata_queued_cmd *qc)
/* fill these in, for the case where they are -not- overwritten */
cmd->sense_buffer[0] = 0x70;
- cmd->sense_buffer[2] = qc->tf.feature >> 4;
+ cmd->sense_buffer[2] = qc->tf.error >> 4;
ata_qc_reinit(qc);
@@ -2847,7 +2827,8 @@ static unsigned int ata_scsi_pass_thru(struct ata_queued_cmd *qc)
* 12 and 16 byte CDBs use different offsets to
* provide the various register values.
*/
- if (cdb[0] == ATA_16) {
+ switch (cdb[0]) {
+ case ATA_16:
/*
* 16-byte CDB - may contain extended commands.
*
@@ -2873,7 +2854,8 @@ static unsigned int ata_scsi_pass_thru(struct ata_queued_cmd *qc)
tf->lbah = cdb[12];
tf->device = cdb[13];
tf->command = cdb[14];
- } else if (cdb[0] == ATA_12) {
+ break;
+ case ATA_12:
/*
* 12-byte CDB - incapable of extended commands.
*/
@@ -2886,7 +2868,8 @@ static unsigned int ata_scsi_pass_thru(struct ata_queued_cmd *qc)
tf->lbah = cdb[7];
tf->device = cdb[8];
tf->command = cdb[9];
- } else {
+ break;
+ default:
/*
* 32-byte CDB - may contain extended command fields.
*
@@ -2910,6 +2893,7 @@ static unsigned int ata_scsi_pass_thru(struct ata_queued_cmd *qc)
tf->device = cdb[24];
tf->command = cdb[25];
tf->auxiliary = get_unaligned_be32(&cdb[28]);
+ break;
}
/* For NCQ commands copy the tag value */
@@ -3674,7 +3658,7 @@ static unsigned int ata_scsi_mode_select_xlat(struct ata_queued_cmd *qc)
goto invalid_fld;
}
- len = (cdb[7] << 8) + cdb[8];
+ len = get_unaligned_be16(&cdb[7]);
hdr_len = 8;
}
@@ -3700,7 +3684,7 @@ static unsigned int ata_scsi_mode_select_xlat(struct ata_queued_cmd *qc)
if (six_byte)
bd_len = p[3];
else
- bd_len = (p[6] << 8) + p[7];
+ bd_len = get_unaligned_be16(&p[6]);
len -= hdr_len;
p += hdr_len;
@@ -3724,7 +3708,7 @@ static unsigned int ata_scsi_mode_select_xlat(struct ata_queued_cmd *qc)
goto invalid_param_len;
spg = p[1];
- pg_len = (p[2] << 8) | p[3];
+ pg_len = get_unaligned_be16(&p[2]);
p += 4;
len -= 4;
} else {
@@ -3935,7 +3919,6 @@ static inline ata_xlat_func_t ata_get_xlat_func(struct ata_device *dev, u8 cmd)
case MODE_SELECT:
case MODE_SELECT_10:
return ata_scsi_mode_select_xlat;
- break;
case ZBC_IN:
return ata_scsi_zbc_in_xlat;
diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c
index 75217828dfe3..b3be7a8f5bea 100644
--- a/drivers/ata/libata-sff.c
+++ b/drivers/ata/libata-sff.c
@@ -70,22 +70,35 @@ EXPORT_SYMBOL_GPL(ata_sff_check_status);
/**
* ata_sff_altstatus - Read device alternate status reg
* @ap: port where the device is
+ * @status: pointer to a status value
*
- * Reads ATA taskfile alternate status register for
- * currently-selected device and return its value.
+ * Reads ATA alternate status register for currently-selected device
+ * and return its value.
*
- * Note: may NOT be used as the check_altstatus() entry in
- * ata_port_operations.
+ * RETURN:
+ * true if the register exists, false if not.
*
* LOCKING:
* Inherited from caller.
*/
-static u8 ata_sff_altstatus(struct ata_port *ap)
+static bool ata_sff_altstatus(struct ata_port *ap, u8 *status)
{
- if (ap->ops->sff_check_altstatus)
- return ap->ops->sff_check_altstatus(ap);
+ u8 tmp;
+
+ if (ap->ops->sff_check_altstatus) {
+ tmp = ap->ops->sff_check_altstatus(ap);
+ goto read;
+ }
+ if (ap->ioaddr.altstatus_addr) {
+ tmp = ioread8(ap->ioaddr.altstatus_addr);
+ goto read;
+ }
+ return false;
- return ioread8(ap->ioaddr.altstatus_addr);
+read:
+ if (status)
+ *status = tmp;
+ return true;
}
/**
@@ -104,12 +117,9 @@ static u8 ata_sff_irq_status(struct ata_port *ap)
{
u8 status;
- if (ap->ops->sff_check_altstatus || ap->ioaddr.altstatus_addr) {
- status = ata_sff_altstatus(ap);
- /* Not us: We are busy */
- if (status & ATA_BUSY)
- return status;
- }
+ /* Not us: We are busy */
+ if (ata_sff_altstatus(ap, &status) && (status & ATA_BUSY))
+ return status;
/* Clear INTRQ latch */
status = ap->ops->sff_check_status(ap);
return status;
@@ -129,10 +139,7 @@ static u8 ata_sff_irq_status(struct ata_port *ap)
static void ata_sff_sync(struct ata_port *ap)
{
- if (ap->ops->sff_check_altstatus)
- ap->ops->sff_check_altstatus(ap);
- else if (ap->ioaddr.altstatus_addr)
- ioread8(ap->ioaddr.altstatus_addr);
+ ata_sff_altstatus(ap, NULL);
}
/**
@@ -164,12 +171,12 @@ EXPORT_SYMBOL_GPL(ata_sff_pause);
void ata_sff_dma_pause(struct ata_port *ap)
{
- if (ap->ops->sff_check_altstatus || ap->ioaddr.altstatus_addr) {
- /* An altstatus read will cause the needed delay without
- messing up the IRQ status */
- ata_sff_altstatus(ap);
+ /*
+ * An altstatus read will cause the needed delay without
+ * messing up the IRQ status
+ */
+ if (ata_sff_altstatus(ap, NULL))
return;
- }
/* There are no DMA controllers without ctl. BUG here to ensure
we never violate the HDMA1:0 transition timing and risk
corruption. */
@@ -265,20 +272,26 @@ EXPORT_SYMBOL_GPL(ata_sff_wait_ready);
* @ap: port where the device is
* @ctl: value to write
*
- * Writes ATA taskfile device control register.
+ * Writes ATA device control register.
*
- * Note: may NOT be used as the sff_set_devctl() entry in
- * ata_port_operations.
+ * RETURN:
+ * true if the register exists, false if not.
*
* LOCKING:
* Inherited from caller.
*/
-static void ata_sff_set_devctl(struct ata_port *ap, u8 ctl)
+static bool ata_sff_set_devctl(struct ata_port *ap, u8 ctl)
{
- if (ap->ops->sff_set_devctl)
+ if (ap->ops->sff_set_devctl) {
ap->ops->sff_set_devctl(ap, ctl);
- else
+ return true;
+ }
+ if (ap->ioaddr.ctl_addr) {
iowrite8(ctl, ap->ioaddr.ctl_addr);
+ return true;
+ }
+
+ return false;
}
/**
@@ -357,8 +370,6 @@ static void ata_dev_select(struct ata_port *ap, unsigned int device,
*/
void ata_sff_irq_on(struct ata_port *ap)
{
- struct ata_ioports *ioaddr = &ap->ioaddr;
-
if (ap->ops->sff_irq_on) {
ap->ops->sff_irq_on(ap);
return;
@@ -367,8 +378,7 @@ void ata_sff_irq_on(struct ata_port *ap)
ap->ctl &= ~ATA_NIEN;
ap->last_ctl = ap->ctl;
- if (ap->ops->sff_set_devctl || ioaddr->ctl_addr)
- ata_sff_set_devctl(ap, ap->ctl);
+ ata_sff_set_devctl(ap, ap->ctl);
ata_wait_idle(ap);
if (ap->ops->sff_irq_clear)
@@ -439,8 +449,8 @@ void ata_sff_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
{
struct ata_ioports *ioaddr = &ap->ioaddr;
- tf->command = ata_sff_check_status(ap);
- tf->feature = ioread8(ioaddr->error_addr);
+ tf->status = ata_sff_check_status(ap);
+ tf->error = ioread8(ioaddr->error_addr);
tf->nsect = ioread8(ioaddr->nsect_addr);
tf->lbal = ioread8(ioaddr->lbal_addr);
tf->lbam = ioread8(ioaddr->lbam_addr);
@@ -1634,14 +1644,14 @@ void ata_sff_lost_interrupt(struct ata_port *ap)
return;
/* See if the controller thinks it is still busy - if so the command
isn't a lost IRQ but is still in progress */
- status = ata_sff_altstatus(ap);
+ if (WARN_ON_ONCE(!ata_sff_altstatus(ap, &status)))
+ return;
if (status & ATA_BUSY)
return;
/* There was a command running, we are no longer busy and we have
no interrupt. */
- ata_port_warn(ap, "lost interrupt (Status 0x%x)\n",
- status);
+ ata_port_warn(ap, "lost interrupt (Status 0x%x)\n", status);
/* Run the host interrupt logic as if the interrupt had not been
lost */
ata_sff_port_intr(ap, qc);
@@ -1662,8 +1672,7 @@ void ata_sff_freeze(struct ata_port *ap)
ap->ctl |= ATA_NIEN;
ap->last_ctl = ap->ctl;
- if (ap->ops->sff_set_devctl || ap->ioaddr.ctl_addr)
- ata_sff_set_devctl(ap, ap->ctl);
+ ata_sff_set_devctl(ap, ap->ctl);
/* Under certain circumstances, some controllers raise IRQ on
* ATA_NIEN manipulation. Also, many controllers fail to mask
@@ -1708,16 +1717,15 @@ EXPORT_SYMBOL_GPL(ata_sff_thaw);
* Kernel thread context (may sleep)
*
* RETURNS:
- * 0 on success, -errno otherwise.
+ * Always 0.
*/
int ata_sff_prereset(struct ata_link *link, unsigned long deadline)
{
struct ata_eh_context *ehc = &link->eh_context;
int rc;
- rc = ata_std_prereset(link, deadline);
- if (rc)
- return rc;
+ /* The standard prereset is best-effort and always returns 0 */
+ ata_std_prereset(link, deadline);
/* if we're about to do hardreset, nothing more to do */
if (ehc->i.action & ATA_EH_HARDRESET)
@@ -1752,10 +1760,13 @@ EXPORT_SYMBOL_GPL(ata_sff_prereset);
* correctly storing and echoing back the
* ATA shadow register contents.
*
+ * RETURN:
+ * true if device is present, false if not.
+ *
* LOCKING:
* caller.
*/
-static unsigned int ata_devchk(struct ata_port *ap, unsigned int device)
+static bool ata_devchk(struct ata_port *ap, unsigned int device)
{
struct ata_ioports *ioaddr = &ap->ioaddr;
u8 nsect, lbal;
@@ -1775,9 +1786,9 @@ static unsigned int ata_devchk(struct ata_port *ap, unsigned int device)
lbal = ioread8(ioaddr->lbal_addr);
if ((nsect == 0x55) && (lbal == 0xaa))
- return 1; /* we found a device */
+ return true; /* we found a device */
- return 0; /* nothing found */
+ return false; /* nothing found */
}
/**
@@ -1814,7 +1825,7 @@ unsigned int ata_sff_dev_classify(struct ata_device *dev, int present,
memset(&tf, 0, sizeof(tf));
ap->ops->sff_tf_read(ap, &tf);
- err = tf.feature;
+ err = tf.error;
if (r_err)
*r_err = err;
@@ -1831,9 +1842,10 @@ unsigned int ata_sff_dev_classify(struct ata_device *dev, int present,
/* determine if device is ATA or ATAPI */
class = ata_port_classify(ap, &tf);
-
- if (class == ATA_DEV_UNKNOWN) {
- /* If the device failed diagnostic, it's likely to
+ switch (class) {
+ case ATA_DEV_UNKNOWN:
+ /*
+ * If the device failed diagnostic, it's likely to
* have reported incorrect device signature too.
* Assume ATA device if the device seems present but
* device signature is invalid with diagnostic
@@ -1843,10 +1855,12 @@ unsigned int ata_sff_dev_classify(struct ata_device *dev, int present,
class = ATA_DEV_ATA;
else
class = ATA_DEV_NONE;
- } else if ((class == ATA_DEV_ATA) &&
- (ap->ops->sff_check_status(ap) == 0))
- class = ATA_DEV_NONE;
-
+ break;
+ case ATA_DEV_ATA:
+ if (ap->ops->sff_check_status(ap) == 0)
+ class = ATA_DEV_NONE;
+ break;
+ }
return class;
}
EXPORT_SYMBOL_GPL(ata_sff_dev_classify);
@@ -2059,10 +2073,8 @@ void ata_sff_postreset(struct ata_link *link, unsigned int *classes)
return;
/* set up device control */
- if (ap->ops->sff_set_devctl || ap->ioaddr.ctl_addr) {
- ata_sff_set_devctl(ap, ap->ctl);
+ if (ata_sff_set_devctl(ap, ap->ctl))
ap->last_ctl = ap->ctl;
- }
}
EXPORT_SYMBOL_GPL(ata_sff_postreset);
@@ -2172,18 +2184,18 @@ EXPORT_SYMBOL_GPL(ata_sff_std_ports);
#ifdef CONFIG_PCI
-static int ata_resources_present(struct pci_dev *pdev, int port)
+static bool ata_resources_present(struct pci_dev *pdev, int port)
{
int i;
/* Check the PCI resources for this channel are enabled */
- port = port * 2;
+ port *= 2;
for (i = 0; i < 2; i++) {
if (pci_resource_start(pdev, port + i) == 0 ||
pci_resource_len(pdev, port + i) == 0)
- return 0;
+ return false;
}
- return 1;
+ return true;
}
/**
diff --git a/drivers/ata/libata.h b/drivers/ata/libata.h
index 51e01acdd241..c9c2496d91ea 100644
--- a/drivers/ata/libata.h
+++ b/drivers/ata/libata.h
@@ -107,7 +107,6 @@ static inline void ata_sas_free_tag(unsigned int tag, struct ata_port *ap) { }
#ifdef CONFIG_ATA_ACPI
extern unsigned int ata_acpi_gtf_filter;
extern void ata_acpi_dissociate(struct ata_host *host);
-extern int ata_acpi_on_suspend(struct ata_port *ap);
extern void ata_acpi_on_resume(struct ata_port *ap);
extern int ata_acpi_on_devcfg(struct ata_device *dev);
extern void ata_acpi_on_disable(struct ata_device *dev);
@@ -117,7 +116,6 @@ extern void ata_acpi_bind_dev(struct ata_device *dev);
extern acpi_handle ata_dev_acpi_handle(struct ata_device *dev);
#else
static inline void ata_acpi_dissociate(struct ata_host *host) { }
-static inline int ata_acpi_on_suspend(struct ata_port *ap) { return 0; }
static inline void ata_acpi_on_resume(struct ata_port *ap) { }
static inline int ata_acpi_on_devcfg(struct ata_device *dev) { return 0; }
static inline void ata_acpi_on_disable(struct ata_device *dev) { }
diff --git a/drivers/ata/pata_arasan_cf.c b/drivers/ata/pata_arasan_cf.c
index 24c3d5e1fca3..e89617ed9175 100644
--- a/drivers/ata/pata_arasan_cf.c
+++ b/drivers/ata/pata_arasan_cf.c
@@ -937,7 +937,8 @@ static int arasan_cf_suspend(struct device *dev)
dmaengine_terminate_all(acdev->dma_chan);
cf_exit(acdev);
- return ata_host_suspend(host, PMSG_SUSPEND);
+ ata_host_suspend(host, PMSG_SUSPEND);
+ return 0;
}
static int arasan_cf_resume(struct device *dev)
diff --git a/drivers/ata/pata_artop.c b/drivers/ata/pata_artop.c
index ad3c5808aaad..20a8f31a3f57 100644
--- a/drivers/ata/pata_artop.c
+++ b/drivers/ata/pata_artop.c
@@ -28,7 +28,7 @@
#include <linux/ata.h>
#define DRV_NAME "pata_artop"
-#define DRV_VERSION "0.4.6"
+#define DRV_VERSION "0.4.8"
/*
* The ARTOP has 33 Mhz and "over clocked" timing tables. Until we
@@ -315,12 +315,15 @@ static struct ata_port_operations artop6260_ops = {
static void atp8xx_fixup(struct pci_dev *pdev)
{
- if (pdev->device == 0x0005)
+ u8 reg;
+
+ switch (pdev->device) {
+ case 0x0005:
/* BIOS may have left us in UDMA, clear it before libata probe */
pci_write_config_byte(pdev, 0x54, 0);
- else if (pdev->device == 0x0008 || pdev->device == 0x0009) {
- u8 reg;
-
+ break;
+ case 0x0008:
+ case 0x0009:
/* Mac systems come up with some registers not set as we
will need them */
@@ -338,6 +341,7 @@ static void atp8xx_fixup(struct pci_dev *pdev)
/* Enable IRQ output and burst mode */
pci_read_config_byte(pdev, 0x4a, &reg);
pci_write_config_byte(pdev, 0x4a, (reg & ~0x01) | 0x80);
+ break;
}
}
@@ -394,16 +398,19 @@ static int artop_init_one (struct pci_dev *pdev, const struct pci_device_id *id)
if (rc)
return rc;
- if (id->driver_data == 0) /* 6210 variant */
+ switch (id->driver_data) {
+ case 0: /* 6210 variant */
ppi[0] = &info_6210;
- else if (id->driver_data == 1) /* 6260 */
+ break;
+ case 1: /* 6260 */
ppi[0] = &info_626x;
- else if (id->driver_data == 2) { /* 6280 or 6280 + fast */
- unsigned long io = pci_resource_start(pdev, 4);
-
- ppi[0] = &info_628x;
- if (inb(io) & 0x10)
+ break;
+ case 2: /* 6280 or 6280 + fast */
+ if (inb(pci_resource_start(pdev, 4)) & 0x10)
ppi[0] = &info_628x_fast;
+ else
+ ppi[0] = &info_628x;
+ break;
}
BUG_ON(ppi[0] == NULL);
diff --git a/drivers/ata/pata_atiixp.c b/drivers/ata/pata_atiixp.c
index c3a65ccd4b79..efdb94cff68b 100644
--- a/drivers/ata/pata_atiixp.c
+++ b/drivers/ata/pata_atiixp.c
@@ -102,7 +102,7 @@ static int atiixp_prereset(struct ata_link *link, unsigned long deadline)
static void atiixp_set_pio_timing(struct ata_port *ap, struct ata_device *adev, int pio)
{
- static u8 pio_timings[5] = { 0x5D, 0x47, 0x34, 0x22, 0x20 };
+ static const u8 pio_timings[5] = { 0x5D, 0x47, 0x34, 0x22, 0x20 };
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
int dn = 2 * ap->port_no + adev->devno;
@@ -149,7 +149,7 @@ static void atiixp_set_piomode(struct ata_port *ap, struct ata_device *adev)
static void atiixp_set_dmamode(struct ata_port *ap, struct ata_device *adev)
{
- static u8 mwdma_timings[5] = { 0x77, 0x21, 0x20 };
+ static const u8 mwdma_timings[5] = { 0x77, 0x21, 0x20 };
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
int dma = adev->dma_mode;
diff --git a/drivers/ata/pata_cs5520.c b/drivers/ata/pata_cs5520.c
index 24ce8665b1f9..f4289a532f87 100644
--- a/drivers/ata/pata_cs5520.c
+++ b/drivers/ata/pata_cs5520.c
@@ -259,11 +259,8 @@ static int cs5520_reinit_one(struct pci_dev *pdev)
static int cs5520_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg)
{
struct ata_host *host = pci_get_drvdata(pdev);
- int rc = 0;
- rc = ata_host_suspend(host, mesg);
- if (rc)
- return rc;
+ ata_host_suspend(host, mesg);
pci_save_state(pdev);
return 0;
diff --git a/drivers/ata/pata_ep93xx.c b/drivers/ata/pata_ep93xx.c
index b78f71c70f27..6c75a22db12b 100644
--- a/drivers/ata/pata_ep93xx.c
+++ b/drivers/ata/pata_ep93xx.c
@@ -416,8 +416,8 @@ static void ep93xx_pata_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
{
struct ep93xx_pata_data *drv_data = ap->host->private_data;
- tf->command = ep93xx_pata_check_status(ap);
- tf->feature = ep93xx_pata_read_reg(drv_data, IDECTRL_ADDR_FEATURE);
+ tf->status = ep93xx_pata_check_status(ap);
+ tf->error = ep93xx_pata_read_reg(drv_data, IDECTRL_ADDR_FEATURE);
tf->nsect = ep93xx_pata_read_reg(drv_data, IDECTRL_ADDR_NSECT);
tf->lbal = ep93xx_pata_read_reg(drv_data, IDECTRL_ADDR_LBAL);
tf->lbam = ep93xx_pata_read_reg(drv_data, IDECTRL_ADDR_LBAM);
diff --git a/drivers/ata/pata_ftide010.c b/drivers/ata/pata_ftide010.c
index 34cb104f6b43..2e35505b683c 100644
--- a/drivers/ata/pata_ftide010.c
+++ b/drivers/ata/pata_ftide010.c
@@ -554,10 +554,8 @@ static int pata_ftide010_remove(struct platform_device *pdev)
}
static const struct of_device_id pata_ftide010_of_match[] = {
- {
- .compatible = "faraday,ftide010",
- },
- {},
+ { .compatible = "faraday,ftide010", },
+ { /* sentinel */ }
};
static struct platform_driver pata_ftide010_driver = {
diff --git a/drivers/ata/pata_hpt366.c b/drivers/ata/pata_hpt366.c
index 778c893f276b..c99e8f0708b3 100644
--- a/drivers/ata/pata_hpt366.c
+++ b/drivers/ata/pata_hpt366.c
@@ -23,7 +23,7 @@
#include <linux/libata.h>
#define DRV_NAME "pata_hpt366"
-#define DRV_VERSION "0.6.11"
+#define DRV_VERSION "0.6.13"
struct hpt_clock {
u8 xfer_mode;
@@ -278,6 +278,40 @@ static void hpt366_set_dmamode(struct ata_port *ap, struct ata_device *adev)
hpt366_set_mode(ap, adev, adev->dma_mode);
}
+/**
+ * hpt366_prereset - reset the hpt36x bus
+ * @link: ATA link to reset
+ * @deadline: deadline jiffies for the operation
+ *
+ * Perform the initial reset handling for the 36x series controllers.
+ * Reset the hardware and state machine,
+ */
+
+static int hpt366_prereset(struct ata_link *link, unsigned long deadline)
+{
+ struct ata_port *ap = link->ap;
+ struct pci_dev *pdev = to_pci_dev(ap->host->dev);
+ /*
+ * HPT36x chips have one channel per function and have
+ * both channel enable bits located differently and visible
+ * to both functions -- really stupid design decision... :-(
+ * Bit 4 is for the primary channel, bit 5 for the secondary.
+ */
+ static const struct pci_bits hpt366_enable_bits = {
+ 0x50, 1, 0x30, 0x30
+ };
+ u8 mcr2;
+
+ if (!pci_test_config_bits(pdev, &hpt366_enable_bits))
+ return -ENOENT;
+
+ pci_read_config_byte(pdev, 0x51, &mcr2);
+ if (mcr2 & 0x80)
+ pci_write_config_byte(pdev, 0x51, mcr2 & ~0x80);
+
+ return ata_sff_prereset(link, deadline);
+}
+
static struct scsi_host_template hpt36x_sht = {
ATA_BMDMA_SHT(DRV_NAME),
};
@@ -288,6 +322,7 @@ static struct scsi_host_template hpt36x_sht = {
static struct ata_port_operations hpt366_port_ops = {
.inherits = &ata_bmdma_port_ops,
+ .prereset = hpt366_prereset,
.cable_detect = hpt36x_cable_detect,
.mode_filter = hpt366_filter,
.set_piomode = hpt366_set_piomode,
@@ -304,16 +339,20 @@ static struct ata_port_operations hpt366_port_ops = {
static void hpt36x_init_chipset(struct pci_dev *dev)
{
- u8 drive_fast;
+ u8 mcr1;
pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, (L1_CACHE_BYTES / 4));
pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x78);
pci_write_config_byte(dev, PCI_MIN_GNT, 0x08);
pci_write_config_byte(dev, PCI_MAX_LAT, 0x08);
- pci_read_config_byte(dev, 0x51, &drive_fast);
- if (drive_fast & 0x80)
- pci_write_config_byte(dev, 0x51, drive_fast & ~0x80);
+ /*
+ * Now we'll have to force both channels enabled if at least one
+ * of them has been enabled by BIOS...
+ */
+ pci_read_config_byte(dev, 0x50, &mcr1);
+ if (mcr1 & 0x30)
+ pci_write_config_byte(dev, 0x50, mcr1 | 0x30);
}
/**
diff --git a/drivers/ata/pata_hpt37x.c b/drivers/ata/pata_hpt37x.c
index 7abc7e04f656..156f304ef051 100644
--- a/drivers/ata/pata_hpt37x.c
+++ b/drivers/ata/pata_hpt37x.c
@@ -23,7 +23,7 @@
#include <linux/libata.h>
#define DRV_NAME "pata_hpt37x"
-#define DRV_VERSION "0.6.23"
+#define DRV_VERSION "0.6.25"
struct hpt_clock {
u8 xfer_speed;
@@ -394,6 +394,7 @@ static int hpt37x_pre_reset(struct ata_link *link, unsigned long deadline)
{ 0x50, 1, 0x04, 0x04 },
{ 0x54, 1, 0x04, 0x04 }
};
+ u8 mcr2;
if (!pci_test_config_bits(pdev, &hpt37x_enable_bits[ap->port_no]))
return -ENOENT;
@@ -402,25 +403,29 @@ static int hpt37x_pre_reset(struct ata_link *link, unsigned long deadline)
pci_write_config_byte(pdev, 0x50 + 4 * ap->port_no, 0x37);
udelay(100);
+ /*
+ * Disable the "fast interrupt" prediction. Don't hold off
+ * on interrupts. (== 0x01 despite what the docs say)
+ */
+ pci_read_config_byte(pdev, 0x51 + 4 * ap->port_no, &mcr2);
+ /* Is it HPT370/A? */
+ if (pdev->device == PCI_DEVICE_ID_TTI_HPT366 && pdev->revision < 5) {
+ mcr2 &= ~0x02;
+ mcr2 |= 0x01;
+ } else {
+ mcr2 &= ~0x07;
+ }
+ pci_write_config_byte(pdev, 0x51 + 4 * ap->port_no, mcr2);
+
return ata_sff_prereset(link, deadline);
}
-static void hpt370_set_mode(struct ata_port *ap, struct ata_device *adev,
+static void hpt37x_set_mode(struct ata_port *ap, struct ata_device *adev,
u8 mode)
{
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
- u32 addr1, addr2;
+ int addr = 0x40 + 4 * (adev->devno + 2 * ap->port_no);
u32 reg, timing, mask;
- u8 fast;
-
- addr1 = 0x40 + 4 * (adev->devno + 2 * ap->port_no);
- addr2 = 0x51 + 4 * ap->port_no;
-
- /* Fast interrupt prediction disable, hold off interrupt disable */
- pci_read_config_byte(pdev, addr2, &fast);
- fast &= ~0x02;
- fast |= 0x01;
- pci_write_config_byte(pdev, addr2, fast);
/* Determine timing mask and find matching mode entry */
if (mode < XFER_MW_DMA_0)
@@ -432,34 +437,34 @@ static void hpt370_set_mode(struct ata_port *ap, struct ata_device *adev,
timing = hpt37x_find_mode(ap, mode);
- pci_read_config_dword(pdev, addr1, &reg);
+ pci_read_config_dword(pdev, addr, &reg);
reg = (reg & ~mask) | (timing & mask);
- pci_write_config_dword(pdev, addr1, reg);
+ pci_write_config_dword(pdev, addr, reg);
}
/**
- * hpt370_set_piomode - PIO setup
+ * hpt37x_set_piomode - PIO setup
* @ap: ATA interface
* @adev: device on the interface
*
* Perform PIO mode setup.
*/
-static void hpt370_set_piomode(struct ata_port *ap, struct ata_device *adev)
+static void hpt37x_set_piomode(struct ata_port *ap, struct ata_device *adev)
{
- hpt370_set_mode(ap, adev, adev->pio_mode);
+ hpt37x_set_mode(ap, adev, adev->pio_mode);
}
/**
- * hpt370_set_dmamode - DMA timing setup
+ * hpt37x_set_dmamode - DMA timing setup
* @ap: ATA interface
* @adev: Device being configured
*
* Set up the channel for MWDMA or UDMA modes.
*/
-static void hpt370_set_dmamode(struct ata_port *ap, struct ata_device *adev)
+static void hpt37x_set_dmamode(struct ata_port *ap, struct ata_device *adev)
{
- hpt370_set_mode(ap, adev, adev->dma_mode);
+ hpt37x_set_mode(ap, adev, adev->dma_mode);
}
/**
@@ -499,63 +504,6 @@ static void hpt370_bmdma_stop(struct ata_queued_cmd *qc)
ata_bmdma_stop(qc);
}
-static void hpt372_set_mode(struct ata_port *ap, struct ata_device *adev,
- u8 mode)
-{
- struct pci_dev *pdev = to_pci_dev(ap->host->dev);
- u32 addr1, addr2;
- u32 reg, timing, mask;
- u8 fast;
-
- addr1 = 0x40 + 4 * (adev->devno + 2 * ap->port_no);
- addr2 = 0x51 + 4 * ap->port_no;
-
- /* Fast interrupt prediction disable, hold off interrupt disable */
- pci_read_config_byte(pdev, addr2, &fast);
- fast &= ~0x07;
- pci_write_config_byte(pdev, addr2, fast);
-
- /* Determine timing mask and find matching mode entry */
- if (mode < XFER_MW_DMA_0)
- mask = 0xcfc3ffff;
- else if (mode < XFER_UDMA_0)
- mask = 0x31c001ff;
- else
- mask = 0x303c0000;
-
- timing = hpt37x_find_mode(ap, mode);
-
- pci_read_config_dword(pdev, addr1, &reg);
- reg = (reg & ~mask) | (timing & mask);
- pci_write_config_dword(pdev, addr1, reg);
-}
-
-/**
- * hpt372_set_piomode - PIO setup
- * @ap: ATA interface
- * @adev: device on the interface
- *
- * Perform PIO mode setup.
- */
-
-static void hpt372_set_piomode(struct ata_port *ap, struct ata_device *adev)
-{
- hpt372_set_mode(ap, adev, adev->pio_mode);
-}
-
-/**
- * hpt372_set_dmamode - DMA timing setup
- * @ap: ATA interface
- * @adev: Device being configured
- *
- * Set up the channel for MWDMA or UDMA modes.
- */
-
-static void hpt372_set_dmamode(struct ata_port *ap, struct ata_device *adev)
-{
- hpt372_set_mode(ap, adev, adev->dma_mode);
-}
-
/**
* hpt37x_bmdma_stop - DMA engine stop
* @qc: ATA command
@@ -593,8 +541,8 @@ static struct ata_port_operations hpt370_port_ops = {
.mode_filter = hpt370_filter,
.cable_detect = hpt37x_cable_detect,
- .set_piomode = hpt370_set_piomode,
- .set_dmamode = hpt370_set_dmamode,
+ .set_piomode = hpt37x_set_piomode,
+ .set_dmamode = hpt37x_set_dmamode,
.prereset = hpt37x_pre_reset,
};
@@ -608,8 +556,7 @@ static struct ata_port_operations hpt370a_port_ops = {
};
/*
- * Configuration for HPT371 and HPT302. Slightly different PIO and DMA
- * mode setting functionality.
+ * Configuration for HPT371 and HPT302.
*/
static struct ata_port_operations hpt302_port_ops = {
@@ -618,8 +565,8 @@ static struct ata_port_operations hpt302_port_ops = {
.bmdma_stop = hpt37x_bmdma_stop,
.cable_detect = hpt37x_cable_detect,
- .set_piomode = hpt372_set_piomode,
- .set_dmamode = hpt372_set_dmamode,
+ .set_piomode = hpt37x_set_piomode,
+ .set_dmamode = hpt37x_set_dmamode,
.prereset = hpt37x_pre_reset,
};
@@ -920,6 +867,20 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
pci_write_config_byte(dev, 0x5a, irqmask);
/*
+ * HPT371 chips physically have only one channel, the secondary one,
+ * but the primary channel registers do exist! Go figure...
+ * So, we manually disable the non-existing channel here
+ * (if the BIOS hasn't done this already).
+ */
+ if (dev->device == PCI_DEVICE_ID_TTI_HPT371) {
+ u8 mcr1;
+
+ pci_read_config_byte(dev, 0x50, &mcr1);
+ mcr1 &= ~0x04;
+ pci_write_config_byte(dev, 0x50, mcr1);
+ }
+
+ /*
* default to pci clock. make sure MA15/16 are set to output
* to prevent drives having problems with 40-pin cables. Needed
* for some drives such as IBM-DTLA which will not enter ready
@@ -950,14 +911,14 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
if ((freq >> 12) != 0xABCDE) {
int i;
- u8 sr;
+ u16 sr;
u32 total = 0;
dev_warn(&dev->dev, "BIOS has not set timing clocks\n");
/* This is the process the HPT371 BIOS is reported to use */
for (i = 0; i < 128; i++) {
- pci_read_config_byte(dev, 0x78, &sr);
+ pci_read_config_word(dev, 0x78, &sr);
total += sr & 0x1FF;
udelay(15);
}
diff --git a/drivers/ata/pata_hpt3x2n.c b/drivers/ata/pata_hpt3x2n.c
index 1d9d4eec5b8a..1f6afd8ee29b 100644
--- a/drivers/ata/pata_hpt3x2n.c
+++ b/drivers/ata/pata_hpt3x2n.c
@@ -24,10 +24,9 @@
#include <linux/libata.h>
#define DRV_NAME "pata_hpt3x2n"
-#define DRV_VERSION "0.3.15"
+#define DRV_VERSION "0.3.18"
enum {
- HPT_PCI_FAST = (1 << 31),
PCI66 = (1 << 1),
USE_DPLL = (1 << 0)
};
@@ -37,11 +36,6 @@ struct hpt_clock {
u32 timing;
};
-struct hpt_chip {
- const char *name;
- struct hpt_clock *clocks[3];
-};
-
/* key for bus clock timings
* bit
* 0:3 data_high_time. Inactive time of DIOW_/DIOR_ for PIO and MW DMA.
@@ -168,11 +162,24 @@ static int hpt3x2n_pre_reset(struct ata_link *link, unsigned long deadline)
{
struct ata_port *ap = link->ap;
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
+ static const struct pci_bits hpt3x2n_enable_bits[] = {
+ { 0x50, 1, 0x04, 0x04 },
+ { 0x54, 1, 0x04, 0x04 }
+ };
+ u8 mcr2;
+
+ if (!pci_test_config_bits(pdev, &hpt3x2n_enable_bits[ap->port_no]))
+ return -ENOENT;
/* Reset the state machine */
pci_write_config_byte(pdev, 0x50 + 4 * ap->port_no, 0x37);
udelay(100);
+ /* Fast interrupt prediction disable, hold off interrupt disable */
+ pci_read_config_byte(pdev, 0x51 + 4 * ap->port_no, &mcr2);
+ mcr2 &= ~0x07;
+ pci_write_config_byte(pdev, 0x51 + 4 * ap->port_no, mcr2);
+
return ata_sff_prereset(link, deadline);
}
@@ -180,17 +187,8 @@ static void hpt3x2n_set_mode(struct ata_port *ap, struct ata_device *adev,
u8 mode)
{
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
- u32 addr1, addr2;
+ int addr = 0x40 + 4 * (adev->devno + 2 * ap->port_no);
u32 reg, timing, mask;
- u8 fast;
-
- addr1 = 0x40 + 4 * (adev->devno + 2 * ap->port_no);
- addr2 = 0x51 + 4 * ap->port_no;
-
- /* Fast interrupt prediction disable, hold off interrupt disable */
- pci_read_config_byte(pdev, addr2, &fast);
- fast &= ~0x07;
- pci_write_config_byte(pdev, addr2, fast);
/* Determine timing mask and find matching mode entry */
if (mode < XFER_MW_DMA_0)
@@ -202,9 +200,9 @@ static void hpt3x2n_set_mode(struct ata_port *ap, struct ata_device *adev,
timing = hpt3x2n_find_mode(ap, mode);
- pci_read_config_dword(pdev, addr1, &reg);
+ pci_read_config_dword(pdev, addr, &reg);
reg = (reg & ~mask) | (timing & mask);
- pci_write_config_dword(pdev, addr1, reg);
+ pci_write_config_dword(pdev, addr, reg);
}
/**
@@ -244,7 +242,7 @@ static void hpt3x2n_bmdma_stop(struct ata_queued_cmd *qc)
{
struct ata_port *ap = qc->ap;
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
- int mscreg = 0x50 + 2 * ap->port_no;
+ int mscreg = 0x50 + 4 * ap->port_no;
u8 bwsr_stat, msc_stat;
pci_read_config_byte(pdev, 0x6A, &bwsr_stat);
diff --git a/drivers/ata/pata_imx.c b/drivers/ata/pata_imx.c
index 2e538726802b..150939275b1b 100644
--- a/drivers/ata/pata_imx.c
+++ b/drivers/ata/pata_imx.c
@@ -223,17 +223,14 @@ static int pata_imx_suspend(struct device *dev)
{
struct ata_host *host = dev_get_drvdata(dev);
struct pata_imx_priv *priv = host->private_data;
- int ret;
- ret = ata_host_suspend(host, PMSG_SUSPEND);
- if (!ret) {
- __raw_writel(0, priv->host_regs + PATA_IMX_ATA_INT_EN);
- priv->ata_ctl =
- __raw_readl(priv->host_regs + PATA_IMX_ATA_CONTROL);
- clk_disable_unprepare(priv->clk);
- }
+ ata_host_suspend(host, PMSG_SUSPEND);
- return ret;
+ __raw_writel(0, priv->host_regs + PATA_IMX_ATA_INT_EN);
+ priv->ata_ctl = __raw_readl(priv->host_regs + PATA_IMX_ATA_CONTROL);
+ clk_disable_unprepare(priv->clk);
+
+ return 0;
}
static int pata_imx_resume(struct device *dev)
diff --git a/drivers/ata/pata_ixp4xx_cf.c b/drivers/ata/pata_ixp4xx_cf.c
index 17b557c91e1c..e225913a619d 100644
--- a/drivers/ata/pata_ixp4xx_cf.c
+++ b/drivers/ata/pata_ixp4xx_cf.c
@@ -293,7 +293,7 @@ static int ixp4xx_pata_probe(struct platform_device *pdev)
static const struct of_device_id ixp4xx_pata_of_match[] = {
{ .compatible = "intel,ixp4xx-compact-flash", },
- { },
+ { /* sentinel */ }
};
static struct platform_driver ixp4xx_pata_platform_driver = {
diff --git a/drivers/ata/pata_macio.c b/drivers/ata/pata_macio.c
index 16e8aa184a75..42798402cf63 100644
--- a/drivers/ata/pata_macio.c
+++ b/drivers/ata/pata_macio.c
@@ -853,12 +853,8 @@ static int pata_macio_slave_config(struct scsi_device *sdev)
#ifdef CONFIG_PM_SLEEP
static int pata_macio_do_suspend(struct pata_macio_priv *priv, pm_message_t mesg)
{
- int rc;
-
/* First, core libata suspend to do most of the work */
- rc = ata_host_suspend(priv->host, mesg);
- if (rc)
- return rc;
+ ata_host_suspend(priv->host, mesg);
/* Restore to default timings */
pata_macio_default_timings(priv);
@@ -1333,19 +1329,11 @@ static int pata_macio_pci_resume(struct pci_dev *pdev)
static const struct of_device_id pata_macio_match[] =
{
- {
- .name = "IDE",
- },
- {
- .name = "ATA",
- },
- {
- .type = "ide",
- },
- {
- .type = "ata",
- },
- {},
+ { .name = "IDE", },
+ { .name = "ATA", },
+ { .type = "ide", },
+ { .type = "ata", },
+ { /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, pata_macio_match);
diff --git a/drivers/ata/pata_mpc52xx.c b/drivers/ata/pata_mpc52xx.c
index f1d352d5f128..3250ef317df6 100644
--- a/drivers/ata/pata_mpc52xx.c
+++ b/drivers/ata/pata_mpc52xx.c
@@ -736,7 +736,7 @@ static int mpc52xx_ata_probe(struct platform_device *op)
}
/* Prepare our private structure */
- priv = devm_kzalloc(&op->dev, sizeof(*priv), GFP_ATOMIC);
+ priv = devm_kzalloc(&op->dev, sizeof(*priv), GFP_KERNEL);
if (!priv) {
rv = -ENOMEM;
goto err1;
@@ -824,7 +824,8 @@ mpc52xx_ata_suspend(struct platform_device *op, pm_message_t state)
{
struct ata_host *host = platform_get_drvdata(op);
- return ata_host_suspend(host, state);
+ ata_host_suspend(host, state);
+ return 0;
}
static int
@@ -849,7 +850,7 @@ mpc52xx_ata_resume(struct platform_device *op)
static const struct of_device_id mpc52xx_ata_of_match[] = {
{ .compatible = "fsl,mpc5200-ata", },
{ .compatible = "mpc5200-ata", },
- {},
+ { /* sentinel */ }
};
diff --git a/drivers/ata/pata_ns87415.c b/drivers/ata/pata_ns87415.c
index f4949e704356..9dd6bffefb48 100644
--- a/drivers/ata/pata_ns87415.c
+++ b/drivers/ata/pata_ns87415.c
@@ -264,8 +264,8 @@ void ns87560_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
{
struct ata_ioports *ioaddr = &ap->ioaddr;
- tf->command = ns87560_check_status(ap);
- tf->feature = ioread8(ioaddr->error_addr);
+ tf->status = ns87560_check_status(ap);
+ tf->error = ioread8(ioaddr->error_addr);
tf->nsect = ioread8(ioaddr->nsect_addr);
tf->lbal = ioread8(ioaddr->lbal_addr);
tf->lbam = ioread8(ioaddr->lbam_addr);
diff --git a/drivers/ata/pata_octeon_cf.c b/drivers/ata/pata_octeon_cf.c
index 05c2ab375756..6b5ed3046b44 100644
--- a/drivers/ata/pata_octeon_cf.c
+++ b/drivers/ata/pata_octeon_cf.c
@@ -382,7 +382,7 @@ static void octeon_cf_tf_read16(struct ata_port *ap, struct ata_taskfile *tf)
void __iomem *base = ap->ioaddr.data_addr;
blob = __raw_readw(base + 0xc);
- tf->feature = blob >> 8;
+ tf->error = blob >> 8;
blob = __raw_readw(base + 2);
tf->nsect = blob & 0xff;
@@ -394,7 +394,7 @@ static void octeon_cf_tf_read16(struct ata_port *ap, struct ata_taskfile *tf)
blob = __raw_readw(base + 6);
tf->device = blob & 0xff;
- tf->command = blob >> 8;
+ tf->status = blob >> 8;
if (tf->flags & ATA_TFLAG_LBA48) {
if (likely(ap->ioaddr.ctl_addr)) {
@@ -1006,10 +1006,8 @@ static void octeon_cf_shutdown(struct device *dev)
}
static const struct of_device_id octeon_cf_match[] = {
- {
- .compatible = "cavium,ebt3000-compact-flash",
- },
- {},
+ { .compatible = "cavium,ebt3000-compact-flash", },
+ { /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, octeon_cf_match);
diff --git a/drivers/ata/pata_of_platform.c b/drivers/ata/pata_of_platform.c
index c3a40b717dcd..ac5a633c00a5 100644
--- a/drivers/ata/pata_of_platform.c
+++ b/drivers/ata/pata_of_platform.c
@@ -79,7 +79,7 @@ static int pata_of_platform_probe(struct platform_device *ofdev)
static const struct of_device_id pata_of_platform_match[] = {
{ .compatible = "ata-generic", },
- { },
+ { /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, pata_of_platform_match);
diff --git a/drivers/ata/pata_pdc202xx_old.c b/drivers/ata/pata_pdc202xx_old.c
index b99849095853..f894ff2de0a9 100644
--- a/drivers/ata/pata_pdc202xx_old.c
+++ b/drivers/ata/pata_pdc202xx_old.c
@@ -78,7 +78,7 @@ static void pdc202xx_configure_piomode(struct ata_port *ap, struct ata_device *a
{
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
int port = 0x60 + 8 * ap->port_no + 4 * adev->devno;
- static u16 pio_timing[5] = {
+ static const u16 pio_timing[5] = {
0x0913, 0x050C , 0x0308, 0x0206, 0x0104
};
u8 r_ap, r_bp;
diff --git a/drivers/ata/pata_platform.c b/drivers/ata/pata_platform.c
index 028329428b75..21fb059859bd 100644
--- a/drivers/ata/pata_platform.c
+++ b/drivers/ata/pata_platform.c
@@ -128,6 +128,8 @@ int __pata_platform_probe(struct device *dev, struct resource *io_res,
ap = host->ports[0];
ap->ops = devm_kzalloc(dev, sizeof(*ap->ops), GFP_KERNEL);
+ if (!ap->ops)
+ return -ENOMEM;
ap->ops->inherits = &ata_sff_port_ops;
ap->ops->cable_detect = ata_cable_unknown;
ap->ops->set_mode = pata_platform_set_mode;
@@ -198,22 +200,16 @@ static int pata_platform_probe(struct platform_device *pdev)
/*
* Get the I/O base first
*/
- io_res = platform_get_resource(pdev, IORESOURCE_IO, 0);
- if (io_res == NULL) {
- io_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (unlikely(io_res == NULL))
- return -EINVAL;
- }
+ io_res = platform_get_mem_or_io(pdev, 0);
+ if (!io_res)
+ return -EINVAL;
/*
* Then the CTL base
*/
- ctl_res = platform_get_resource(pdev, IORESOURCE_IO, 1);
- if (ctl_res == NULL) {
- ctl_res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
- if (unlikely(ctl_res == NULL))
- return -EINVAL;
- }
+ ctl_res = platform_get_mem_or_io(pdev, 1);
+ if (!ctl_res)
+ return -EINVAL;
/*
* And the IRQ
diff --git a/drivers/ata/pata_pxa.c b/drivers/ata/pata_pxa.c
index 41430f79663c..985f42c4fd70 100644
--- a/drivers/ata/pata_pxa.c
+++ b/drivers/ata/pata_pxa.c
@@ -164,10 +164,10 @@ static int pxa_ata_probe(struct platform_device *pdev)
struct resource *cmd_res;
struct resource *ctl_res;
struct resource *dma_res;
- struct resource *irq_res;
struct pata_pxa_pdata *pdata = dev_get_platdata(&pdev->dev);
struct dma_slave_config config;
int ret = 0;
+ int irq;
/*
* Resource validation, three resources are needed:
@@ -205,9 +205,9 @@ static int pxa_ata_probe(struct platform_device *pdev)
/*
* IRQ pin
*/
- irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
- if (unlikely(irq_res == NULL))
- return -EINVAL;
+ irq = platform_get_irq(pdev, 0);
+ if (irq < 0)
+ return irq;
/*
* Allocate the host
@@ -287,7 +287,7 @@ static int pxa_ata_probe(struct platform_device *pdev)
/*
* Activate the ATA host
*/
- ret = ata_host_activate(host, irq_res->start, ata_sff_interrupt,
+ ret = ata_host_activate(host, irq, ata_sff_interrupt,
pdata->irq_flags, &pxa_ata_sht);
if (ret)
dma_release_channel(data->dma_chan);
diff --git a/drivers/ata/pata_samsung_cf.c b/drivers/ata/pata_samsung_cf.c
index 3da0e8e30286..aba1536ddd44 100644
--- a/drivers/ata/pata_samsung_cf.c
+++ b/drivers/ata/pata_samsung_cf.c
@@ -213,7 +213,7 @@ static void pata_s3c_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
{
struct ata_ioports *ioaddr = &ap->ioaddr;
- tf->feature = ata_inb(ap->host, ioaddr->error_addr);
+ tf->error = ata_inb(ap->host, ioaddr->error_addr);
tf->nsect = ata_inb(ap->host, ioaddr->nsect_addr);
tf->lbal = ata_inb(ap->host, ioaddr->lbal_addr);
tf->lbam = ata_inb(ap->host, ioaddr->lbam_addr);
@@ -308,8 +308,7 @@ static void pata_s3c_dev_select(struct ata_port *ap, unsigned int device)
/*
* pata_s3c_devchk - PATA device presence detection
*/
-static unsigned int pata_s3c_devchk(struct ata_port *ap,
- unsigned int device)
+static bool pata_s3c_devchk(struct ata_port *ap, unsigned int device)
{
struct ata_ioports *ioaddr = &ap->ioaddr;
u8 nsect, lbal;
@@ -329,9 +328,9 @@ static unsigned int pata_s3c_devchk(struct ata_port *ap,
lbal = ata_inb(ap->host, ioaddr->lbal_addr);
if ((nsect == 0x55) && (lbal == 0xaa))
- return 1; /* we found a device */
+ return true; /* we found a device */
- return 0; /* nothing found */
+ return false; /* nothing found */
}
/*
@@ -608,7 +607,8 @@ static int pata_s3c_suspend(struct device *dev)
{
struct ata_host *host = dev_get_drvdata(dev);
- return ata_host_suspend(host, PMSG_SUSPEND);
+ ata_host_suspend(host, PMSG_SUSPEND);
+ return 0;
}
static int pata_s3c_resume(struct device *dev)
diff --git a/drivers/ata/pata_triflex.c b/drivers/ata/pata_triflex.c
index 8a033598e7e1..782162d2f3f8 100644
--- a/drivers/ata/pata_triflex.c
+++ b/drivers/ata/pata_triflex.c
@@ -198,11 +198,8 @@ static const struct pci_device_id triflex[] = {
static int triflex_ata_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg)
{
struct ata_host *host = pci_get_drvdata(pdev);
- int rc = 0;
- rc = ata_host_suspend(host, mesg);
- if (rc)
- return rc;
+ ata_host_suspend(host, mesg);
/*
* We must not disable or powerdown the device.
diff --git a/drivers/ata/sata_fsl.c b/drivers/ata/sata_fsl.c
index da0152116d9f..b9a4f68b371d 100644
--- a/drivers/ata/sata_fsl.c
+++ b/drivers/ata/sata_fsl.c
@@ -322,7 +322,7 @@ static void fsl_sata_set_irq_coalescing(struct ata_host *host,
static ssize_t fsl_sata_intr_coalescing_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
- return sysfs_emit(buf, "%d %d\n",
+ return sysfs_emit(buf, "%u %u\n",
intr_coalescing_count, intr_coalescing_ticks);
}
@@ -332,10 +332,8 @@ static ssize_t fsl_sata_intr_coalescing_store(struct device *dev,
{
unsigned int coalescing_count, coalescing_ticks;
- if (sscanf(buf, "%d%d",
- &coalescing_count,
- &coalescing_ticks) != 2) {
- printk(KERN_ERR "fsl-sata: wrong parameter format.\n");
+ if (sscanf(buf, "%u%u", &coalescing_count, &coalescing_ticks) != 2) {
+ dev_err(dev, "fsl-sata: wrong parameter format.\n");
return -EINVAL;
}
@@ -359,7 +357,7 @@ static ssize_t fsl_sata_rx_watermark_show(struct device *dev,
rx_watermark &= 0x1f;
spin_unlock_irqrestore(&host->lock, flags);
- return sysfs_emit(buf, "%d\n", rx_watermark);
+ return sysfs_emit(buf, "%u\n", rx_watermark);
}
static ssize_t fsl_sata_rx_watermark_store(struct device *dev,
@@ -373,8 +371,8 @@ static ssize_t fsl_sata_rx_watermark_store(struct device *dev,
void __iomem *csr_base = host_priv->csr_base;
u32 temp;
- if (sscanf(buf, "%d", &rx_watermark) != 1) {
- printk(KERN_ERR "fsl-sata: wrong parameter format.\n");
+ if (kstrtouint(buf, 10, &rx_watermark) < 0) {
+ dev_err(dev, "fsl-sata: wrong parameter format.\n");
return -EINVAL;
}
@@ -382,8 +380,8 @@ static ssize_t fsl_sata_rx_watermark_store(struct device *dev,
temp = ioread32(csr_base + TRANSCFG);
temp &= 0xffffffe0;
iowrite32(temp | rx_watermark, csr_base + TRANSCFG);
-
spin_unlock_irqrestore(&host->lock, flags);
+
return strlen(buf);
}
@@ -1546,7 +1544,9 @@ static int sata_fsl_remove(struct platform_device *ofdev)
static int sata_fsl_suspend(struct platform_device *op, pm_message_t state)
{
struct ata_host *host = platform_get_drvdata(op);
- return ata_host_suspend(host, state);
+
+ ata_host_suspend(host, state);
+ return 0;
}
static int sata_fsl_resume(struct platform_device *op)
@@ -1579,13 +1579,9 @@ static int sata_fsl_resume(struct platform_device *op)
#endif
static const struct of_device_id fsl_sata_match[] = {
- {
- .compatible = "fsl,pq-sata",
- },
- {
- .compatible = "fsl,pq-sata-v2",
- },
- {},
+ { .compatible = "fsl,pq-sata", },
+ { .compatible = "fsl,pq-sata-v2", },
+ { /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, fsl_sata_match);
diff --git a/drivers/ata/sata_gemini.c b/drivers/ata/sata_gemini.c
index 440a63de20d0..00e1c7941d0e 100644
--- a/drivers/ata/sata_gemini.c
+++ b/drivers/ata/sata_gemini.c
@@ -419,10 +419,8 @@ static int gemini_sata_remove(struct platform_device *pdev)
}
static const struct of_device_id gemini_sata_of_match[] = {
- {
- .compatible = "cortina,gemini-sata-bridge",
- },
- {},
+ { .compatible = "cortina,gemini-sata-bridge", },
+ { /* sentinel */ }
};
static struct platform_driver gemini_sata_driver = {
diff --git a/drivers/ata/sata_highbank.c b/drivers/ata/sata_highbank.c
index b29d3f1d64b0..dfbf9493e451 100644
--- a/drivers/ata/sata_highbank.c
+++ b/drivers/ata/sata_highbank.c
@@ -400,7 +400,7 @@ static int ahci_highbank_hardreset(struct ata_link *link, unsigned int *class,
/* clear D2H reception area to properly wait for D2H FIS */
ata_tf_init(link->device, &tf);
- tf.command = ATA_BUSY;
+ tf.status = ATA_BUSY;
ata_tf_to_fis(&tf, 0, 0, d2h_fis);
do {
@@ -444,7 +444,7 @@ static struct scsi_host_template ahci_highbank_platform_sht = {
static const struct of_device_id ahci_of_match[] = {
{ .compatible = "calxeda,hb-ahci" },
- {},
+ { /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, ahci_of_match);
@@ -587,7 +587,8 @@ static int ahci_highbank_suspend(struct device *dev)
writel(ctl, mmio + HOST_CTL);
readl(mmio + HOST_CTL); /* flush */
- return ata_host_suspend(host, PMSG_SUSPEND);
+ ata_host_suspend(host, PMSG_SUSPEND);
+ return 0;
}
static int ahci_highbank_resume(struct device *dev)
diff --git a/drivers/ata/sata_inic162x.c b/drivers/ata/sata_inic162x.c
index 781901151d82..11e518f0111c 100644
--- a/drivers/ata/sata_inic162x.c
+++ b/drivers/ata/sata_inic162x.c
@@ -557,13 +557,13 @@ static void inic_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
{
void __iomem *port_base = inic_port_base(ap);
- tf->feature = readb(port_base + PORT_TF_FEATURE);
+ tf->error = readb(port_base + PORT_TF_FEATURE);
tf->nsect = readb(port_base + PORT_TF_NSECT);
tf->lbal = readb(port_base + PORT_TF_LBAL);
tf->lbam = readb(port_base + PORT_TF_LBAM);
tf->lbah = readb(port_base + PORT_TF_LBAH);
tf->device = readb(port_base + PORT_TF_DEVICE);
- tf->command = readb(port_base + PORT_TF_COMMAND);
+ tf->status = readb(port_base + PORT_TF_COMMAND);
}
static bool inic_qc_fill_rtf(struct ata_queued_cmd *qc)
@@ -580,11 +580,11 @@ static bool inic_qc_fill_rtf(struct ata_queued_cmd *qc)
*/
inic_tf_read(qc->ap, &tf);
- if (!(tf.command & ATA_ERR))
+ if (!(tf.status & ATA_ERR))
return false;
- rtf->command = tf.command;
- rtf->feature = tf.feature;
+ rtf->status = tf.status;
+ rtf->error = tf.error;
return true;
}
diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c
index 53446b997740..de5bd02cad44 100644
--- a/drivers/ata/sata_mv.c
+++ b/drivers/ata/sata_mv.c
@@ -4235,10 +4235,10 @@ static int mv_platform_remove(struct platform_device *pdev)
static int mv_platform_suspend(struct platform_device *pdev, pm_message_t state)
{
struct ata_host *host = platform_get_drvdata(pdev);
+
if (host)
- return ata_host_suspend(host, state);
- else
- return 0;
+ ata_host_suspend(host, state);
+ return 0;
}
static int mv_platform_resume(struct platform_device *pdev)
@@ -4277,7 +4277,7 @@ static int mv_platform_resume(struct platform_device *pdev)
static const struct of_device_id mv_sata_dt_ids[] = {
{ .compatible = "marvell,armada-370-sata", },
{ .compatible = "marvell,orion-sata", },
- {},
+ { /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, mv_sata_dt_ids);
#endif
diff --git a/drivers/ata/sata_rcar.c b/drivers/ata/sata_rcar.c
index 3d96b6faa3f0..590ebea99601 100644
--- a/drivers/ata/sata_rcar.c
+++ b/drivers/ata/sata_rcar.c
@@ -18,10 +18,6 @@
#define DRV_NAME "sata_rcar"
-/* SH-Navi2G/ATAPI-ATA compatible task registers */
-#define DATA_REG 0x100
-#define SDEVCON_REG 0x138
-
/* SH-Navi2G/ATAPI module compatible control registers */
#define ATAPI_CONTROL1_REG 0x180
#define ATAPI_STATUS_REG 0x184
@@ -283,8 +279,7 @@ static void sata_rcar_dev_select(struct ata_port *ap, unsigned int device)
ata_sff_pause(ap); /* needed; also flushes, for mmio */
}
-static unsigned int sata_rcar_ata_devchk(struct ata_port *ap,
- unsigned int device)
+static bool sata_rcar_ata_devchk(struct ata_port *ap, unsigned int device)
{
struct ata_ioports *ioaddr = &ap->ioaddr;
u8 nsect, lbal;
@@ -304,9 +299,9 @@ static unsigned int sata_rcar_ata_devchk(struct ata_port *ap,
lbal = ioread32(ioaddr->lbal_addr);
if (nsect == 0x55 && lbal == 0xaa)
- return 1; /* found a device */
+ return true; /* found a device */
- return 0; /* nothing found */
+ return false; /* nothing found */
}
static int sata_rcar_wait_after_reset(struct ata_link *link,
@@ -399,8 +394,8 @@ static void sata_rcar_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
{
struct ata_ioports *ioaddr = &ap->ioaddr;
- tf->command = sata_rcar_check_status(ap);
- tf->feature = ioread32(ioaddr->error_addr);
+ tf->status = sata_rcar_check_status(ap);
+ tf->error = ioread32(ioaddr->error_addr);
tf->nsect = ioread32(ioaddr->nsect_addr);
tf->lbal = ioread32(ioaddr->lbal_addr);
tf->lbam = ioread32(ioaddr->lbam_addr);
@@ -857,7 +852,7 @@ static const struct of_device_id sata_rcar_match[] = {
.compatible = "renesas,rcar-gen3-sata",
.data = (void *)RCAR_GEN3_SATA
},
- { },
+ { /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, sata_rcar_match);
@@ -945,19 +940,17 @@ static int sata_rcar_suspend(struct device *dev)
struct ata_host *host = dev_get_drvdata(dev);
struct sata_rcar_priv *priv = host->private_data;
void __iomem *base = priv->base;
- int ret;
- ret = ata_host_suspend(host, PMSG_SUSPEND);
- if (!ret) {
- /* disable interrupts */
- iowrite32(0, base + ATAPI_INT_ENABLE_REG);
- /* mask */
- iowrite32(priv->sataint_mask, base + SATAINTMASK_REG);
+ ata_host_suspend(host, PMSG_SUSPEND);
- pm_runtime_put(dev);
- }
+ /* disable interrupts */
+ iowrite32(0, base + ATAPI_INT_ENABLE_REG);
+ /* mask */
+ iowrite32(priv->sataint_mask, base + SATAINTMASK_REG);
- return ret;
+ pm_runtime_put(dev);
+
+ return 0;
}
static int sata_rcar_resume(struct device *dev)
diff --git a/drivers/ata/sata_svw.c b/drivers/ata/sata_svw.c
index f8552559db7f..2e3418a82b44 100644
--- a/drivers/ata/sata_svw.c
+++ b/drivers/ata/sata_svw.c
@@ -194,24 +194,24 @@ static void k2_sata_tf_load(struct ata_port *ap, const struct ata_taskfile *tf)
static void k2_sata_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
{
struct ata_ioports *ioaddr = &ap->ioaddr;
- u16 nsect, lbal, lbam, lbah, feature;
+ u16 nsect, lbal, lbam, lbah, error;
- tf->command = k2_stat_check_status(ap);
+ tf->status = k2_stat_check_status(ap);
tf->device = readw(ioaddr->device_addr);
- feature = readw(ioaddr->error_addr);
+ error = readw(ioaddr->error_addr);
nsect = readw(ioaddr->nsect_addr);
lbal = readw(ioaddr->lbal_addr);
lbam = readw(ioaddr->lbam_addr);
lbah = readw(ioaddr->lbah_addr);
- tf->feature = feature;
+ tf->error = error;
tf->nsect = nsect;
tf->lbal = lbal;
tf->lbam = lbam;
tf->lbah = lbah;
if (tf->flags & ATA_TFLAG_LBA48) {
- tf->hob_feature = feature >> 8;
+ tf->hob_feature = error >> 8;
tf->hob_nsect = nsect >> 8;
tf->hob_lbal = lbal >> 8;
tf->hob_lbam = lbam >> 8;
diff --git a/drivers/ata/sata_vsc.c b/drivers/ata/sata_vsc.c
index 8fa952cb9f7f..87e4ed66b306 100644
--- a/drivers/ata/sata_vsc.c
+++ b/drivers/ata/sata_vsc.c
@@ -183,24 +183,24 @@ static void vsc_sata_tf_load(struct ata_port *ap, const struct ata_taskfile *tf)
static void vsc_sata_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
{
struct ata_ioports *ioaddr = &ap->ioaddr;
- u16 nsect, lbal, lbam, lbah, feature;
+ u16 nsect, lbal, lbam, lbah, error;
- tf->command = ata_sff_check_status(ap);
+ tf->status = ata_sff_check_status(ap);
tf->device = readw(ioaddr->device_addr);
- feature = readw(ioaddr->error_addr);
+ error = readw(ioaddr->error_addr);
nsect = readw(ioaddr->nsect_addr);
lbal = readw(ioaddr->lbal_addr);
lbam = readw(ioaddr->lbam_addr);
lbah = readw(ioaddr->lbah_addr);
- tf->feature = feature;
+ tf->error = error;
tf->nsect = nsect;
tf->lbal = lbal;
tf->lbam = lbam;
tf->lbah = lbah;
if (tf->flags & ATA_TFLAG_LBA48) {
- tf->hob_feature = feature >> 8;
+ tf->hob_feature = error >> 8;
tf->hob_nsect = nsect >> 8;
tf->hob_lbal = lbal >> 8;
tf->hob_lbam = lbam >> 8;
diff --git a/drivers/atm/eni.c b/drivers/atm/eni.c
index 422753d52244..a31ffe16e626 100644
--- a/drivers/atm/eni.c
+++ b/drivers/atm/eni.c
@@ -1112,6 +1112,8 @@ DPRINTK("iovcnt = %d\n",skb_shinfo(skb)->nr_frags);
skb_data3 = skb->data[3];
paddr = dma_map_single(&eni_dev->pci_dev->dev,skb->data,skb->len,
DMA_TO_DEVICE);
+ if (dma_mapping_error(&eni_dev->pci_dev->dev, paddr))
+ return enq_next;
ENI_PRV_PADDR(skb) = paddr;
/* prepare DMA queue entries */
j = 0;
diff --git a/drivers/atm/firestream.c b/drivers/atm/firestream.c
index 3bc3c314a467..4f67404fe64c 100644
--- a/drivers/atm/firestream.c
+++ b/drivers/atm/firestream.c
@@ -1676,6 +1676,8 @@ static int fs_init(struct fs_dev *dev)
dev->hw_base = pci_resource_start(pci_dev, 0);
dev->base = ioremap(dev->hw_base, 0x1000);
+ if (!dev->base)
+ return 1;
reset_chip (dev);
diff --git a/drivers/atm/nicstar.c b/drivers/atm/nicstar.c
index bc5a6ab6fa4b..1a50de39f5b5 100644
--- a/drivers/atm/nicstar.c
+++ b/drivers/atm/nicstar.c
@@ -861,7 +861,6 @@ static void ns_init_card_error(ns_dev *card, int error)
static scq_info *get_scq(ns_dev *card, int size, u32 scd)
{
scq_info *scq;
- int i;
if (size != VBR_SCQSIZE && size != CBR_SCQSIZE)
return NULL;
@@ -875,9 +874,8 @@ static scq_info *get_scq(ns_dev *card, int size, u32 scd)
kfree(scq);
return NULL;
}
- scq->skb = kmalloc_array(size / NS_SCQE_SIZE,
- sizeof(*scq->skb),
- GFP_KERNEL);
+ scq->skb = kcalloc(size / NS_SCQE_SIZE, sizeof(*scq->skb),
+ GFP_KERNEL);
if (!scq->skb) {
dma_free_coherent(&card->pcidev->dev,
2 * size, scq->org, scq->dma);
@@ -890,15 +888,11 @@ static scq_info *get_scq(ns_dev *card, int size, u32 scd)
scq->last = scq->base + (scq->num_entries - 1);
scq->tail = scq->last;
scq->scd = scd;
- scq->num_entries = size / NS_SCQE_SIZE;
scq->tbd_count = 0;
init_waitqueue_head(&scq->scqfull_waitq);
scq->full = 0;
spin_lock_init(&scq->lock);
- for (i = 0; i < scq->num_entries; i++)
- scq->skb[i] = NULL;
-
return scq;
}
diff --git a/drivers/auxdisplay/lcd2s.c b/drivers/auxdisplay/lcd2s.c
index 38ba08628ccb..2578b2d45439 100644
--- a/drivers/auxdisplay/lcd2s.c
+++ b/drivers/auxdisplay/lcd2s.c
@@ -238,7 +238,7 @@ static int lcd2s_redefine_char(struct charlcd *lcd, char *esc)
if (buf[1] > 7)
return 1;
- i = 0;
+ i = 2;
shift = 0;
value = 0;
while (*esc && i < LCD2S_CHARACTER_SIZE + 2) {
@@ -298,6 +298,10 @@ static int lcd2s_i2c_probe(struct i2c_client *i2c,
I2C_FUNC_SMBUS_WRITE_BLOCK_DATA))
return -EIO;
+ lcd2s = devm_kzalloc(&i2c->dev, sizeof(*lcd2s), GFP_KERNEL);
+ if (!lcd2s)
+ return -ENOMEM;
+
/* Test, if the display is responding */
err = lcd2s_i2c_smbus_write_byte(i2c, LCD2S_CMD_DISPLAY_OFF);
if (err < 0)
@@ -307,12 +311,6 @@ static int lcd2s_i2c_probe(struct i2c_client *i2c,
if (!lcd)
return -ENOMEM;
- lcd2s = kzalloc(sizeof(struct lcd2s_data), GFP_KERNEL);
- if (!lcd2s) {
- err = -ENOMEM;
- goto fail1;
- }
-
lcd->drvdata = lcd2s;
lcd2s->i2c = i2c;
lcd2s->charlcd = lcd;
@@ -321,26 +319,24 @@ static int lcd2s_i2c_probe(struct i2c_client *i2c,
err = device_property_read_u32(&i2c->dev, "display-height-chars",
&lcd->height);
if (err)
- goto fail2;
+ goto fail1;
err = device_property_read_u32(&i2c->dev, "display-width-chars",
&lcd->width);
if (err)
- goto fail2;
+ goto fail1;
lcd->ops = &lcd2s_ops;
err = charlcd_register(lcd2s->charlcd);
if (err)
- goto fail2;
+ goto fail1;
i2c_set_clientdata(i2c, lcd2s);
return 0;
-fail2:
- kfree(lcd2s);
fail1:
- kfree(lcd);
+ charlcd_free(lcd2s->charlcd);
return err;
}
@@ -349,7 +345,7 @@ static int lcd2s_i2c_remove(struct i2c_client *i2c)
struct lcd2s_data *lcd2s = i2c_get_clientdata(i2c);
charlcd_unregister(lcd2s->charlcd);
- kfree(lcd2s->charlcd);
+ charlcd_free(lcd2s->charlcd);
return 0;
}
diff --git a/drivers/base/arch_topology.c b/drivers/base/arch_topology.c
index 976154140f0b..1d6636ebaac5 100644
--- a/drivers/base/arch_topology.c
+++ b/drivers/base/arch_topology.c
@@ -339,6 +339,46 @@ bool __init topology_parse_cpu_capacity(struct device_node *cpu_node, int cpu)
return !ret;
}
+#ifdef CONFIG_ACPI_CPPC_LIB
+#include <acpi/cppc_acpi.h>
+
+void topology_init_cpu_capacity_cppc(void)
+{
+ struct cppc_perf_caps perf_caps;
+ int cpu;
+
+ if (likely(acpi_disabled || !acpi_cpc_valid()))
+ return;
+
+ raw_capacity = kcalloc(num_possible_cpus(), sizeof(*raw_capacity),
+ GFP_KERNEL);
+ if (!raw_capacity)
+ return;
+
+ for_each_possible_cpu(cpu) {
+ if (!cppc_get_perf_caps(cpu, &perf_caps) &&
+ (perf_caps.highest_perf >= perf_caps.nominal_perf) &&
+ (perf_caps.highest_perf >= perf_caps.lowest_perf)) {
+ raw_capacity[cpu] = perf_caps.highest_perf;
+ pr_debug("cpu_capacity: CPU%d cpu_capacity=%u (raw).\n",
+ cpu, raw_capacity[cpu]);
+ continue;
+ }
+
+ pr_err("cpu_capacity: CPU%d missing/invalid highest performance.\n", cpu);
+ pr_err("cpu_capacity: partial information: fallback to 1024 for all CPUs\n");
+ goto exit;
+ }
+
+ topology_normalize_cpu_scale();
+ schedule_work(&update_topology_flags_work);
+ pr_debug("cpu_capacity: cpu_capacity initialization done\n");
+
+exit:
+ free_raw_capacity();
+}
+#endif
+
#ifdef CONFIG_CPU_FREQ
static cpumask_var_t cpus_to_visit;
static void parsing_done_workfn(struct work_struct *work);
@@ -387,9 +427,8 @@ static int __init register_cpufreq_notifier(void)
int ret;
/*
- * on ACPI-based systems we need to use the default cpu capacity
- * until we have the necessary code to parse the cpu capacity, so
- * skip registering cpufreq notifier.
+ * On ACPI-based systems skip registering cpufreq notifier as cpufreq
+ * information is not needed for cpu capacity initialization.
*/
if (!acpi_disabled || !raw_capacity)
return -EINVAL;
diff --git a/drivers/base/class.c b/drivers/base/class.c
index 7476f393df97..8feb85e186e3 100644
--- a/drivers/base/class.c
+++ b/drivers/base/class.c
@@ -16,7 +16,7 @@
#include <linux/kdev_t.h>
#include <linux/err.h>
#include <linux/slab.h>
-#include <linux/genhd.h>
+#include <linux/blkdev.h>
#include <linux/mutex.h>
#include "base.h"
diff --git a/drivers/base/core.c b/drivers/base/core.c
index 7bb957b11861..3d6430eb0c6a 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -21,7 +21,7 @@
#include <linux/notifier.h>
#include <linux/of.h>
#include <linux/of_device.h>
-#include <linux/genhd.h>
+#include <linux/blkdev.h>
#include <linux/mutex.h>
#include <linux/pm_runtime.h>
#include <linux/netdevice.h>
diff --git a/drivers/base/cpu.c b/drivers/base/cpu.c
index 5fc258073bc7..2ef23fce0860 100644
--- a/drivers/base/cpu.c
+++ b/drivers/base/cpu.c
@@ -275,7 +275,7 @@ static ssize_t print_cpus_isolated(struct device *dev,
return -ENOMEM;
cpumask_andnot(isolated, cpu_possible_mask,
- housekeeping_cpumask(HK_FLAG_DOMAIN));
+ housekeeping_cpumask(HK_TYPE_DOMAIN));
len = sysfs_emit(buf, "%*pbl\n", cpumask_pr_args(isolated));
free_cpumask_var(isolated);
diff --git a/drivers/base/dd.c b/drivers/base/dd.c
index 9eaaff2f556c..f47cab21430f 100644
--- a/drivers/base/dd.c
+++ b/drivers/base/dd.c
@@ -629,6 +629,9 @@ re_probe:
drv->remove(dev);
devres_release_all(dev);
+ arch_teardown_dma_ops(dev);
+ kfree(dev->dma_range_map);
+ dev->dma_range_map = NULL;
driver_sysfs_remove(dev);
dev->driver = NULL;
dev_set_drvdata(dev, NULL);
@@ -1209,6 +1212,8 @@ static void __device_release_driver(struct device *dev, struct device *parent)
devres_release_all(dev);
arch_teardown_dma_ops(dev);
+ kfree(dev->dma_range_map);
+ dev->dma_range_map = NULL;
dev->driver = NULL;
dev_set_drvdata(dev, NULL);
if (dev->pm_domain && dev->pm_domain->dismiss)
diff --git a/drivers/base/devtmpfs.c b/drivers/base/devtmpfs.c
index f41063ac1aee..db5a03a0618e 100644
--- a/drivers/base/devtmpfs.c
+++ b/drivers/base/devtmpfs.c
@@ -17,7 +17,7 @@
#include <linux/syscalls.h>
#include <linux/mount.h>
#include <linux/device.h>
-#include <linux/genhd.h>
+#include <linux/blkdev.h>
#include <linux/namei.h>
#include <linux/fs.h>
#include <linux/shmem_fs.h>
diff --git a/drivers/base/init.c b/drivers/base/init.c
index a9f57c22fb9e..d8d0fe687111 100644
--- a/drivers/base/init.c
+++ b/drivers/base/init.c
@@ -35,5 +35,6 @@ void __init driver_init(void)
auxiliary_bus_init();
cpu_dev_init();
memory_dev_init();
+ node_dev_init();
container_dev_init();
}
diff --git a/drivers/base/memory.c b/drivers/base/memory.c
index 365cd4a7f239..7222ff9b5e05 100644
--- a/drivers/base/memory.c
+++ b/drivers/base/memory.c
@@ -215,6 +215,7 @@ static int memory_block_online(struct memory_block *mem)
adjust_present_page_count(pfn_to_page(start_pfn), mem->group,
nr_vmemmap_pages);
+ mem->zone = zone;
return ret;
}
@@ -225,6 +226,9 @@ static int memory_block_offline(struct memory_block *mem)
unsigned long nr_vmemmap_pages = mem->nr_vmemmap_pages;
int ret;
+ if (!mem->zone)
+ return -EINVAL;
+
/*
* Unaccount before offlining, such that unpopulated zone and kthreads
* can properly be torn down in offline_pages().
@@ -234,7 +238,7 @@ static int memory_block_offline(struct memory_block *mem)
-nr_vmemmap_pages);
ret = offline_pages(start_pfn + nr_vmemmap_pages,
- nr_pages - nr_vmemmap_pages, mem->group);
+ nr_pages - nr_vmemmap_pages, mem->zone, mem->group);
if (ret) {
/* offline_pages() failed. Account back. */
if (nr_vmemmap_pages)
@@ -246,6 +250,7 @@ static int memory_block_offline(struct memory_block *mem)
if (nr_vmemmap_pages)
mhp_deinit_memmap_on_memory(start_pfn, nr_vmemmap_pages);
+ mem->zone = NULL;
return ret;
}
@@ -411,11 +416,10 @@ static ssize_t valid_zones_show(struct device *dev,
*/
if (mem->state == MEM_ONLINE) {
/*
- * The block contains more than one zone can not be offlined.
- * This can happen e.g. for ZONE_DMA and ZONE_DMA32
+ * If !mem->zone, the memory block spans multiple zones and
+ * cannot get offlined.
*/
- default_zone = test_pages_in_a_zone(start_pfn,
- start_pfn + nr_pages);
+ default_zone = mem->zone;
if (!default_zone)
return sysfs_emit(buf, "%s\n", "none");
len += sysfs_emit_at(buf, len, "%s", default_zone->name);
@@ -555,6 +559,8 @@ static ssize_t hard_offline_page_store(struct device *dev,
return -EINVAL;
pfn >>= PAGE_SHIFT;
ret = memory_failure(pfn, 0);
+ if (ret == -EOPNOTSUPP)
+ ret = 0;
return ret ? ret : count;
}
@@ -613,11 +619,7 @@ static const struct attribute_group *memory_memblk_attr_groups[] = {
NULL,
};
-/*
- * register_memory - Setup a sysfs device for a memory block
- */
-static
-int register_memory(struct memory_block *memory)
+static int __add_memory_block(struct memory_block *memory)
{
int ret;
@@ -641,9 +643,85 @@ int register_memory(struct memory_block *memory)
return ret;
}
-static int init_memory_block(unsigned long block_id, unsigned long state,
- unsigned long nr_vmemmap_pages,
- struct memory_group *group)
+static struct zone *early_node_zone_for_memory_block(struct memory_block *mem,
+ int nid)
+{
+ const unsigned long start_pfn = section_nr_to_pfn(mem->start_section_nr);
+ const unsigned long nr_pages = PAGES_PER_SECTION * sections_per_block;
+ struct zone *zone, *matching_zone = NULL;
+ pg_data_t *pgdat = NODE_DATA(nid);
+ int i;
+
+ /*
+ * This logic only works for early memory, when the applicable zones
+ * already span the memory block. We don't expect overlapping zones on
+ * a single node for early memory. So if we're told that some PFNs
+ * of a node fall into this memory block, we can assume that all node
+ * zones that intersect with the memory block are actually applicable.
+ * No need to look at the memmap.
+ */
+ for (i = 0; i < MAX_NR_ZONES; i++) {
+ zone = pgdat->node_zones + i;
+ if (!populated_zone(zone))
+ continue;
+ if (!zone_intersects(zone, start_pfn, nr_pages))
+ continue;
+ if (!matching_zone) {
+ matching_zone = zone;
+ continue;
+ }
+ /* Spans multiple zones ... */
+ matching_zone = NULL;
+ break;
+ }
+ return matching_zone;
+}
+
+#ifdef CONFIG_NUMA
+/**
+ * memory_block_add_nid() - Indicate that system RAM falling into this memory
+ * block device (partially) belongs to the given node.
+ * @mem: The memory block device.
+ * @nid: The node id.
+ * @context: The memory initialization context.
+ *
+ * Indicate that system RAM falling into this memory block (partially) belongs
+ * to the given node. If the context indicates ("early") that we are adding the
+ * node during node device subsystem initialization, this will also properly
+ * set/adjust mem->zone based on the zone ranges of the given node.
+ */
+void memory_block_add_nid(struct memory_block *mem, int nid,
+ enum meminit_context context)
+{
+ if (context == MEMINIT_EARLY && mem->nid != nid) {
+ /*
+ * For early memory we have to determine the zone when setting
+ * the node id and handle multiple nodes spanning a single
+ * memory block by indicate via zone == NULL that we're not
+ * dealing with a single zone. So if we're setting the node id
+ * the first time, determine if there is a single zone. If we're
+ * setting the node id a second time to a different node,
+ * invalidate the single detected zone.
+ */
+ if (mem->nid == NUMA_NO_NODE)
+ mem->zone = early_node_zone_for_memory_block(mem, nid);
+ else
+ mem->zone = NULL;
+ }
+
+ /*
+ * If this memory block spans multiple nodes, we only indicate
+ * the last processed node. If we span multiple nodes (not applicable
+ * to hotplugged memory), zone == NULL will prohibit memory offlining
+ * and consequently unplug.
+ */
+ mem->nid = nid;
+}
+#endif
+
+static int add_memory_block(unsigned long block_id, unsigned long state,
+ unsigned long nr_vmemmap_pages,
+ struct memory_group *group)
{
struct memory_block *mem;
int ret = 0;
@@ -663,17 +741,30 @@ static int init_memory_block(unsigned long block_id, unsigned long state,
mem->nr_vmemmap_pages = nr_vmemmap_pages;
INIT_LIST_HEAD(&mem->group_next);
+#ifndef CONFIG_NUMA
+ if (state == MEM_ONLINE)
+ /*
+ * MEM_ONLINE at this point implies early memory. With NUMA,
+ * we'll determine the zone when setting the node id via
+ * memory_block_add_nid(). Memory hotplug updated the zone
+ * manually when memory onlining/offlining succeeds.
+ */
+ mem->zone = early_node_zone_for_memory_block(mem, NUMA_NO_NODE);
+#endif /* CONFIG_NUMA */
+
+ ret = __add_memory_block(mem);
+ if (ret)
+ return ret;
+
if (group) {
mem->group = group;
list_add(&mem->group_next, &group->memory_blocks);
}
- ret = register_memory(mem);
-
- return ret;
+ return 0;
}
-static int add_memory_block(unsigned long base_section_nr)
+static int __init add_boot_memory_block(unsigned long base_section_nr)
{
int section_count = 0;
unsigned long nr;
@@ -685,11 +776,18 @@ static int add_memory_block(unsigned long base_section_nr)
if (section_count == 0)
return 0;
- return init_memory_block(memory_block_id(base_section_nr),
- MEM_ONLINE, 0, NULL);
+ return add_memory_block(memory_block_id(base_section_nr),
+ MEM_ONLINE, 0, NULL);
+}
+
+static int add_hotplug_memory_block(unsigned long block_id,
+ unsigned long nr_vmemmap_pages,
+ struct memory_group *group)
+{
+ return add_memory_block(block_id, MEM_OFFLINE, nr_vmemmap_pages, group);
}
-static void unregister_memory(struct memory_block *memory)
+static void remove_memory_block(struct memory_block *memory)
{
if (WARN_ON_ONCE(memory->dev.bus != &memory_subsys))
return;
@@ -728,8 +826,7 @@ int create_memory_block_devices(unsigned long start, unsigned long size,
return -EINVAL;
for (block_id = start_block_id; block_id != end_block_id; block_id++) {
- ret = init_memory_block(block_id, MEM_OFFLINE, vmemmap_pages,
- group);
+ ret = add_hotplug_memory_block(block_id, vmemmap_pages, group);
if (ret)
break;
}
@@ -740,7 +837,7 @@ int create_memory_block_devices(unsigned long start, unsigned long size,
mem = find_memory_block_by_id(block_id);
if (WARN_ON_ONCE(!mem))
continue;
- unregister_memory(mem);
+ remove_memory_block(mem);
}
}
return ret;
@@ -769,7 +866,7 @@ void remove_memory_block_devices(unsigned long start, unsigned long size)
if (WARN_ON_ONCE(!mem))
continue;
unregister_memory_block_under_nodes(mem);
- unregister_memory(mem);
+ remove_memory_block(mem);
}
}
@@ -829,7 +926,7 @@ void __init memory_dev_init(void)
*/
for (nr = 0; nr <= __highest_present_section_nr;
nr += sections_per_block) {
- ret = add_memory_block(nr);
+ ret = add_boot_memory_block(nr);
if (ret)
panic("%s() failed to add memory block: %d\n", __func__,
ret);
diff --git a/drivers/base/node.c b/drivers/base/node.c
index 87acc47e8951..ec8bb24a5a22 100644
--- a/drivers/base/node.c
+++ b/drivers/base/node.c
@@ -796,15 +796,12 @@ static int __ref get_nid_for_pfn(unsigned long pfn)
}
static void do_register_memory_block_under_node(int nid,
- struct memory_block *mem_blk)
+ struct memory_block *mem_blk,
+ enum meminit_context context)
{
int ret;
- /*
- * If this memory block spans multiple nodes, we only indicate
- * the last processed node.
- */
- mem_blk->nid = nid;
+ memory_block_add_nid(mem_blk, nid, context);
ret = sysfs_create_link_nowarn(&node_devices[nid]->dev.kobj,
&mem_blk->dev.kobj,
@@ -857,7 +854,7 @@ static int register_mem_block_under_node_early(struct memory_block *mem_blk,
if (page_nid != nid)
continue;
- do_register_memory_block_under_node(nid, mem_blk);
+ do_register_memory_block_under_node(nid, mem_blk, MEMINIT_EARLY);
return 0;
}
/* mem section does not span the specified node */
@@ -873,7 +870,7 @@ static int register_mem_block_under_node_hotplug(struct memory_block *mem_blk,
{
int nid = *(int *)arg;
- do_register_memory_block_under_node(nid, mem_blk);
+ do_register_memory_block_under_node(nid, mem_blk, MEMINIT_HOTPLUG);
return 0;
}
@@ -892,8 +889,9 @@ void unregister_memory_block_under_nodes(struct memory_block *mem_blk)
kobject_name(&node_devices[mem_blk->nid]->dev.kobj));
}
-void link_mem_sections(int nid, unsigned long start_pfn, unsigned long end_pfn,
- enum meminit_context context)
+void register_memory_blocks_under_node(int nid, unsigned long start_pfn,
+ unsigned long end_pfn,
+ enum meminit_context context)
{
walk_memory_blocks_func_t func;
@@ -1065,26 +1063,30 @@ static const struct attribute_group *cpu_root_attr_groups[] = {
};
#define NODE_CALLBACK_PRI 2 /* lower than SLAB */
-static int __init register_node_type(void)
+void __init node_dev_init(void)
{
- int ret;
+ static struct notifier_block node_memory_callback_nb = {
+ .notifier_call = node_memory_callback,
+ .priority = NODE_CALLBACK_PRI,
+ };
+ int ret, i;
BUILD_BUG_ON(ARRAY_SIZE(node_state_attr) != NR_NODE_STATES);
BUILD_BUG_ON(ARRAY_SIZE(node_state_attrs)-1 != NR_NODE_STATES);
ret = subsys_system_register(&node_subsys, cpu_root_attr_groups);
- if (!ret) {
- static struct notifier_block node_memory_callback_nb = {
- .notifier_call = node_memory_callback,
- .priority = NODE_CALLBACK_PRI,
- };
- register_hotmemory_notifier(&node_memory_callback_nb);
- }
+ if (ret)
+ panic("%s() failed to register subsystem: %d\n", __func__, ret);
+
+ register_hotmemory_notifier(&node_memory_callback_nb);
/*
- * Note: we're not going to unregister the node class if we fail
- * to register the node state class attribute files.
+ * Create all node devices, which will properly link the node
+ * to applicable memory block devices and already created cpu devices.
*/
- return ret;
+ for_each_online_node(i) {
+ ret = register_one_node(i);
+ if (ret)
+ panic("%s() failed to add node: %d\n", __func__, ret);
+ }
}
-postcore_initcall(register_node_type);
diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c
index 5db704f02e71..1ee878d126fd 100644
--- a/drivers/base/power/domain.c
+++ b/drivers/base/power/domain.c
@@ -636,6 +636,18 @@ static int genpd_power_off(struct generic_pm_domain *genpd, bool one_dev_on,
atomic_read(&genpd->sd_count) > 0)
return -EBUSY;
+ /*
+ * The children must be in their deepest (powered-off) states to allow
+ * the parent to be powered off. Note that, there's no need for
+ * additional locking, as powering on a child, requires the parent's
+ * lock to be acquired first.
+ */
+ list_for_each_entry(link, &genpd->parent_links, parent_node) {
+ struct generic_pm_domain *child = link->child;
+ if (child->state_idx < child->state_count - 1)
+ return -EBUSY;
+ }
+
list_for_each_entry(pdd, &genpd->dev_list, list_node) {
enum pm_qos_flags_status stat;
@@ -1073,6 +1085,13 @@ static void genpd_sync_power_off(struct generic_pm_domain *genpd, bool use_lock,
|| atomic_read(&genpd->sd_count) > 0)
return;
+ /* Check that the children are in their deepest (powered-off) state. */
+ list_for_each_entry(link, &genpd->parent_links, parent_node) {
+ struct generic_pm_domain *child = link->child;
+ if (child->state_idx < child->state_count - 1)
+ return;
+ }
+
/* Choose the deepest state when suspending */
genpd->state_idx = genpd->state_count - 1;
if (_genpd_power_off(genpd, false))
@@ -2058,9 +2077,9 @@ static int genpd_remove(struct generic_pm_domain *genpd)
kfree(link);
}
- genpd_debug_remove(genpd);
list_del(&genpd->gpd_list_node);
genpd_unlock(genpd);
+ genpd_debug_remove(genpd);
cancel_work_sync(&genpd->power_off_work);
if (genpd_is_cpu_domain(genpd))
free_cpumask_var(genpd->cpus);
@@ -2248,12 +2267,8 @@ int of_genpd_add_provider_simple(struct device_node *np,
/* Parse genpd OPP table */
if (genpd->set_performance_state) {
ret = dev_pm_opp_of_add_table(&genpd->dev);
- if (ret) {
- if (ret != -EPROBE_DEFER)
- dev_err(&genpd->dev, "Failed to add OPP table: %d\n",
- ret);
- return ret;
- }
+ if (ret)
+ return dev_err_probe(&genpd->dev, ret, "Failed to add OPP table\n");
/*
* Save table for faster processing while setting performance
@@ -2312,9 +2327,8 @@ int of_genpd_add_provider_onecell(struct device_node *np,
if (genpd->set_performance_state) {
ret = dev_pm_opp_of_add_table_indexed(&genpd->dev, i);
if (ret) {
- if (ret != -EPROBE_DEFER)
- dev_err(&genpd->dev, "Failed to add OPP table for index %d: %d\n",
- i, ret);
+ dev_err_probe(&genpd->dev, ret,
+ "Failed to add OPP table for index %d\n", i);
goto error;
}
@@ -2672,12 +2686,8 @@ static int __genpd_dev_pm_attach(struct device *dev, struct device *base_dev,
ret = genpd_add_device(pd, dev, base_dev);
mutex_unlock(&gpd_list_lock);
- if (ret < 0) {
- if (ret != -EPROBE_DEFER)
- dev_err(dev, "failed to add to PM domain %s: %d",
- pd->name, ret);
- return ret;
- }
+ if (ret < 0)
+ return dev_err_probe(dev, ret, "failed to add to PM domain %s\n", pd->name);
dev->pm_domain->detach = genpd_dev_pm_detach;
dev->pm_domain->sync = genpd_dev_pm_sync;
diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c
index 04ea92cbd9cf..c50139207794 100644
--- a/drivers/base/power/main.c
+++ b/drivers/base/power/main.c
@@ -485,7 +485,7 @@ static int dpm_run_callback(pm_callback_t cb, struct device *dev,
trace_device_pm_callback_start(dev, info, state.event);
error = cb(dev);
trace_device_pm_callback_end(dev, error);
- suspend_report_result(cb, error);
+ suspend_report_result(dev, cb, error);
initcall_debug_report(dev, calltime, cb, error);
@@ -1568,7 +1568,7 @@ static int legacy_suspend(struct device *dev, pm_message_t state,
trace_device_pm_callback_start(dev, info, state.event);
error = cb(dev, state);
trace_device_pm_callback_end(dev, error);
- suspend_report_result(cb, error);
+ suspend_report_result(dev, cb, error);
initcall_debug_report(dev, calltime, cb, error);
@@ -1855,7 +1855,7 @@ unlock:
device_unlock(dev);
if (ret < 0) {
- suspend_report_result(callback, ret);
+ suspend_report_result(dev, callback, ret);
pm_runtime_put(dev);
return ret;
}
@@ -1960,10 +1960,10 @@ int dpm_suspend_start(pm_message_t state)
}
EXPORT_SYMBOL_GPL(dpm_suspend_start);
-void __suspend_report_result(const char *function, void *fn, int ret)
+void __suspend_report_result(const char *function, struct device *dev, void *fn, int ret)
{
if (ret)
- pr_err("%s(): %pS returns %d\n", function, fn, ret);
+ dev_err(dev, "%s(): %pS returns %d\n", function, fn, ret);
}
EXPORT_SYMBOL_GPL(__suspend_report_result);
@@ -2018,7 +2018,9 @@ static bool pm_ops_is_empty(const struct dev_pm_ops *ops)
void device_pm_check_callbacks(struct device *dev)
{
- spin_lock_irq(&dev->power.lock);
+ unsigned long flags;
+
+ spin_lock_irqsave(&dev->power.lock, flags);
dev->power.no_pm_callbacks =
(!dev->bus || (pm_ops_is_empty(dev->bus->pm) &&
!dev->bus->suspend && !dev->bus->resume)) &&
@@ -2027,7 +2029,7 @@ void device_pm_check_callbacks(struct device *dev)
(!dev->pm_domain || pm_ops_is_empty(&dev->pm_domain->ops)) &&
(!dev->driver || (pm_ops_is_empty(dev->driver->pm) &&
!dev->driver->suspend && !dev->driver->resume));
- spin_unlock_irq(&dev->power.lock);
+ spin_unlock_irqrestore(&dev->power.lock, flags);
}
bool dev_pm_skip_suspend(struct device *dev)
diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c
index 2f3cce17219b..d4059e6ffeae 100644
--- a/drivers/base/power/runtime.c
+++ b/drivers/base/power/runtime.c
@@ -1476,11 +1476,16 @@ EXPORT_SYMBOL_GPL(pm_runtime_enable);
static void pm_runtime_disable_action(void *data)
{
+ pm_runtime_dont_use_autosuspend(data);
pm_runtime_disable(data);
}
/**
* devm_pm_runtime_enable - devres-enabled version of pm_runtime_enable.
+ *
+ * NOTE: this will also handle calling pm_runtime_dont_use_autosuspend() for
+ * you at driver exit time if needed.
+ *
* @dev: Device to handle.
*/
int devm_pm_runtime_enable(struct device *dev)
diff --git a/drivers/base/power/wakeirq.c b/drivers/base/power/wakeirq.c
index 0004db4a9d3b..d487a6bac630 100644
--- a/drivers/base/power/wakeirq.c
+++ b/drivers/base/power/wakeirq.c
@@ -289,7 +289,7 @@ EXPORT_SYMBOL_GPL(dev_pm_disable_wake_irq);
*
* Enables wakeirq conditionally. We need to enable wake-up interrupt
* lazily on the first rpm_suspend(). This is needed as the consumer device
- * starts in RPM_SUSPENDED state, and the the first pm_runtime_get() would
+ * starts in RPM_SUSPENDED state, and the first pm_runtime_get() would
* otherwise try to disable already disabled wakeirq. The wake-up interrupt
* starts disabled with IRQ_NOAUTOEN set.
*
diff --git a/drivers/base/power/wakeup.c b/drivers/base/power/wakeup.c
index 99bda0da23a8..a57d469676ca 100644
--- a/drivers/base/power/wakeup.c
+++ b/drivers/base/power/wakeup.c
@@ -34,7 +34,8 @@ suspend_state_t pm_suspend_target_state;
bool events_check_enabled __read_mostly;
/* First wakeup IRQ seen by the kernel in the last cycle. */
-unsigned int pm_wakeup_irq __read_mostly;
+static unsigned int wakeup_irq[2] __read_mostly;
+static DEFINE_RAW_SPINLOCK(wakeup_irq_lock);
/* If greater than 0 and the system is suspending, terminate the suspend. */
static atomic_t pm_abort_suspend __read_mostly;
@@ -586,7 +587,7 @@ static bool wakeup_source_not_registered(struct wakeup_source *ws)
* @ws: Wakeup source to handle.
*
* Update the @ws' statistics and, if @ws has just been activated, notify the PM
- * core of the event by incrementing the counter of of wakeup events being
+ * core of the event by incrementing the counter of the wakeup events being
* processed.
*/
static void wakeup_source_activate(struct wakeup_source *ws)
@@ -732,7 +733,7 @@ static void wakeup_source_deactivate(struct wakeup_source *ws)
/*
* Increment the counter of registered wakeup events and decrement the
- * couter of wakeup events in progress simultaneously.
+ * counter of wakeup events in progress simultaneously.
*/
cec = atomic_add_return(MAX_IN_PROGRESS, &combined_event_count);
trace_wakeup_source_deactivate(ws->name, cec);
@@ -942,19 +943,45 @@ void pm_system_cancel_wakeup(void)
atomic_dec_if_positive(&pm_abort_suspend);
}
-void pm_wakeup_clear(bool reset)
+void pm_wakeup_clear(unsigned int irq_number)
{
- pm_wakeup_irq = 0;
- if (reset)
+ raw_spin_lock_irq(&wakeup_irq_lock);
+
+ if (irq_number && wakeup_irq[0] == irq_number)
+ wakeup_irq[0] = wakeup_irq[1];
+ else
+ wakeup_irq[0] = 0;
+
+ wakeup_irq[1] = 0;
+
+ raw_spin_unlock_irq(&wakeup_irq_lock);
+
+ if (!irq_number)
atomic_set(&pm_abort_suspend, 0);
}
void pm_system_irq_wakeup(unsigned int irq_number)
{
- if (pm_wakeup_irq == 0) {
- pm_wakeup_irq = irq_number;
+ unsigned long flags;
+
+ raw_spin_lock_irqsave(&wakeup_irq_lock, flags);
+
+ if (wakeup_irq[0] == 0)
+ wakeup_irq[0] = irq_number;
+ else if (wakeup_irq[1] == 0)
+ wakeup_irq[1] = irq_number;
+ else
+ irq_number = 0;
+
+ raw_spin_unlock_irqrestore(&wakeup_irq_lock, flags);
+
+ if (irq_number)
pm_system_wakeup();
- }
+}
+
+unsigned int pm_wakeup_irq(void)
+{
+ return wakeup_irq[0];
}
/**
diff --git a/drivers/base/regmap/internal.h b/drivers/base/regmap/internal.h
index b1905916f7af..b4df36c7b17d 100644
--- a/drivers/base/regmap/internal.h
+++ b/drivers/base/regmap/internal.h
@@ -31,6 +31,7 @@ struct regmap_format {
size_t buf_size;
size_t reg_bytes;
size_t pad_bytes;
+ size_t reg_downshift;
size_t val_bytes;
void (*format_write)(struct regmap *map,
unsigned int reg, unsigned int val);
@@ -62,6 +63,7 @@ struct regmap {
regmap_unlock unlock;
void *lock_arg; /* This is passed to lock/unlock functions */
gfp_t alloc_flags;
+ unsigned int reg_base;
struct device *dev; /* Device we do I/O on */
void *work_buf; /* Scratch buffer used to format I/O */
diff --git a/drivers/base/regmap/regmap-irq.c b/drivers/base/regmap/regmap-irq.c
index d2656581a608..400c7412a7dc 100644
--- a/drivers/base/regmap/regmap-irq.c
+++ b/drivers/base/regmap/regmap-irq.c
@@ -189,11 +189,9 @@ static void regmap_irq_sync_unlock(struct irq_data *data)
ret = regmap_write(map, reg, d->mask_buf[i]);
if (d->chip->clear_ack) {
if (d->chip->ack_invert && !ret)
- ret = regmap_write(map, reg,
- d->mask_buf[i]);
+ ret = regmap_write(map, reg, UINT_MAX);
else if (!ret)
- ret = regmap_write(map, reg,
- ~d->mask_buf[i]);
+ ret = regmap_write(map, reg, 0);
}
if (ret != 0)
dev_err(d->map->dev, "Failed to ack 0x%x: %d\n",
@@ -537,7 +535,7 @@ static irqreturn_t regmap_irq_thread(int irq, void *d)
/*
* Ignore masked IRQs and ack if we need to; we ack early so
- * there is no race between handling and acknowleding the
+ * there is no race between handling and acknowledging the
* interrupt. We assume that typically few of the interrupts
* will fire simultaneously so don't worry about overhead from
* doing a write per register.
@@ -556,11 +554,9 @@ static irqreturn_t regmap_irq_thread(int irq, void *d)
data->status_buf[i]);
if (chip->clear_ack) {
if (chip->ack_invert && !ret)
- ret = regmap_write(map, reg,
- data->status_buf[i]);
+ ret = regmap_write(map, reg, UINT_MAX);
else if (!ret)
- ret = regmap_write(map, reg,
- ~data->status_buf[i]);
+ ret = regmap_write(map, reg, 0);
}
if (ret != 0)
dev_err(map->dev, "Failed to ack 0x%x: %d\n",
@@ -817,13 +813,9 @@ int regmap_add_irq_chip_fwnode(struct fwnode_handle *fwnode,
d->status_buf[i] & d->mask_buf[i]);
if (chip->clear_ack) {
if (chip->ack_invert && !ret)
- ret = regmap_write(map, reg,
- (d->status_buf[i] &
- d->mask_buf[i]));
+ ret = regmap_write(map, reg, UINT_MAX);
else if (!ret)
- ret = regmap_write(map, reg,
- ~(d->status_buf[i] &
- d->mask_buf[i]));
+ ret = regmap_write(map, reg, 0);
}
if (ret != 0) {
dev_err(map->dev, "Failed to ack 0x%x: %d\n",
@@ -1053,7 +1045,7 @@ int devm_regmap_add_irq_chip_fwnode(struct device *dev,
EXPORT_SYMBOL_GPL(devm_regmap_add_irq_chip_fwnode);
/**
- * devm_regmap_add_irq_chip() - Resource manager regmap_add_irq_chip()
+ * devm_regmap_add_irq_chip() - Resource managed regmap_add_irq_chip()
*
* @dev: The device pointer on which irq_chip belongs to.
* @map: The regmap for the device.
@@ -1082,7 +1074,7 @@ EXPORT_SYMBOL_GPL(devm_regmap_add_irq_chip);
/**
* devm_regmap_del_irq_chip() - Resource managed regmap_del_irq_chip()
*
- * @dev: Device for which which resource was allocated.
+ * @dev: Device for which the resource was allocated.
* @irq: Primary IRQ for the device.
* @data: &regmap_irq_chip_data allocated by regmap_add_irq_chip().
*
diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c
index 8f9fe5fd4707..5e12f7cb5147 100644
--- a/drivers/base/regmap/regmap.c
+++ b/drivers/base/regmap/regmap.c
@@ -821,8 +821,11 @@ struct regmap *__regmap_init(struct device *dev,
else
map->alloc_flags = GFP_KERNEL;
+ map->reg_base = config->reg_base;
+
map->format.reg_bytes = DIV_ROUND_UP(config->reg_bits, 8);
map->format.pad_bytes = config->pad_bits / 8;
+ map->format.reg_downshift = config->reg_downshift;
map->format.val_bytes = DIV_ROUND_UP(config->val_bits, 8);
map->format.buf_size = DIV_ROUND_UP(config->reg_bits +
config->val_bits + config->pad_bits, 8);
@@ -1735,6 +1738,8 @@ static int _regmap_raw_write_impl(struct regmap *map, unsigned int reg,
return ret;
}
+ reg += map->reg_base;
+ reg >>= map->format.reg_downshift;
map->format.format_reg(map->work_buf, reg, map->reg_shift);
regmap_set_work_buf_flag_mask(map, map->format.reg_bytes,
map->write_flag_mask);
@@ -1905,6 +1910,8 @@ static int _regmap_bus_formatted_write(void *context, unsigned int reg,
return ret;
}
+ reg += map->reg_base;
+ reg >>= map->format.reg_downshift;
map->format.format_write(map, reg, val);
trace_regmap_hw_write_start(map, reg, 1);
@@ -2346,6 +2353,8 @@ static int _regmap_raw_multi_reg_write(struct regmap *map,
unsigned int reg = regs[i].reg;
unsigned int val = regs[i].def;
trace_regmap_hw_write_start(map, reg, 1);
+ reg += map->reg_base;
+ reg >>= map->format.reg_downshift;
map->format.format_reg(u8, reg, map->reg_shift);
u8 += reg_bytes + pad_bytes;
map->format.format_val(u8, val, 0);
@@ -2673,6 +2682,8 @@ static int _regmap_raw_read(struct regmap *map, unsigned int reg, void *val,
return ret;
}
+ reg += map->reg_base;
+ reg >>= map->format.reg_downshift;
map->format.format_reg(map->work_buf, reg, map->reg_shift);
regmap_set_work_buf_flag_mask(map, map->format.reg_bytes,
map->read_flag_mask);
diff --git a/drivers/base/topology.c b/drivers/base/topology.c
index fc24e89f9592..e9d1efcda89b 100644
--- a/drivers/base/topology.c
+++ b/drivers/base/topology.c
@@ -14,11 +14,11 @@
#include <linux/hardirq.h>
#include <linux/topology.h>
-#define define_id_show_func(name) \
+#define define_id_show_func(name, fmt) \
static ssize_t name##_show(struct device *dev, \
struct device_attribute *attr, char *buf) \
{ \
- return sysfs_emit(buf, "%d\n", topology_##name(dev->id)); \
+ return sysfs_emit(buf, fmt "\n", topology_##name(dev->id)); \
}
#define define_siblings_read_func(name, mask) \
@@ -42,22 +42,25 @@ static ssize_t name##_list_read(struct file *file, struct kobject *kobj, \
off, count); \
}
-define_id_show_func(physical_package_id);
+define_id_show_func(physical_package_id, "%d");
static DEVICE_ATTR_RO(physical_package_id);
#ifdef TOPOLOGY_DIE_SYSFS
-define_id_show_func(die_id);
+define_id_show_func(die_id, "%d");
static DEVICE_ATTR_RO(die_id);
#endif
#ifdef TOPOLOGY_CLUSTER_SYSFS
-define_id_show_func(cluster_id);
+define_id_show_func(cluster_id, "%d");
static DEVICE_ATTR_RO(cluster_id);
#endif
-define_id_show_func(core_id);
+define_id_show_func(core_id, "%d");
static DEVICE_ATTR_RO(core_id);
+define_id_show_func(ppin, "0x%llx");
+static DEVICE_ATTR_ADMIN_RO(ppin);
+
define_siblings_read_func(thread_siblings, sibling_cpumask);
static BIN_ATTR_RO(thread_siblings, 0);
static BIN_ATTR_RO(thread_siblings_list, 0);
@@ -87,7 +90,7 @@ static BIN_ATTR_RO(package_cpus, 0);
static BIN_ATTR_RO(package_cpus_list, 0);
#ifdef TOPOLOGY_BOOK_SYSFS
-define_id_show_func(book_id);
+define_id_show_func(book_id, "%d");
static DEVICE_ATTR_RO(book_id);
define_siblings_read_func(book_siblings, book_cpumask);
static BIN_ATTR_RO(book_siblings, 0);
@@ -95,7 +98,7 @@ static BIN_ATTR_RO(book_siblings_list, 0);
#endif
#ifdef TOPOLOGY_DRAWER_SYSFS
-define_id_show_func(drawer_id);
+define_id_show_func(drawer_id, "%d");
static DEVICE_ATTR_RO(drawer_id);
define_siblings_read_func(drawer_siblings, drawer_cpumask);
static BIN_ATTR_RO(drawer_siblings, 0);
@@ -145,6 +148,7 @@ static struct attribute *default_attrs[] = {
#ifdef TOPOLOGY_DRAWER_SYSFS
&dev_attr_drawer_id.attr,
#endif
+ &dev_attr_ppin.attr,
NULL
};
diff --git a/drivers/bcma/driver_chipcommon.c b/drivers/bcma/driver_chipcommon.c
index 62f5bfa5065d..fd91a39f02c7 100644
--- a/drivers/bcma/driver_chipcommon.c
+++ b/drivers/bcma/driver_chipcommon.c
@@ -303,7 +303,7 @@ u32 bcma_chipco_gpio_outen(struct bcma_drv_cc *cc, u32 mask, u32 value)
EXPORT_SYMBOL_GPL(bcma_chipco_gpio_outen);
/*
- * If the bit is set to 0, chipcommon controlls this GPIO,
+ * If the bit is set to 0, chipcommon controls this GPIO,
* if the bit is set to 1, it is used by some part of the chip and not our code.
*/
u32 bcma_chipco_gpio_control(struct bcma_drv_cc *cc, u32 mask, u32 value)
diff --git a/drivers/bcma/driver_chipcommon_pmu.c b/drivers/bcma/driver_chipcommon_pmu.c
index 3056f81efca4..263ef6fa1d0f 100644
--- a/drivers/bcma/driver_chipcommon_pmu.c
+++ b/drivers/bcma/driver_chipcommon_pmu.c
@@ -206,7 +206,7 @@ static void bcma_pmu_resources_init(struct bcma_drv_cc *cc)
usleep_range(2000, 2500);
}
-/* Disable to allow reading SPROM. Don't know the adventages of enabling it. */
+/* Disable to allow reading SPROM. Don't know the advantages of enabling it. */
void bcma_chipco_bcm4331_ext_pa_lines_ctl(struct bcma_drv_cc *cc, bool enable)
{
struct bcma_bus *bus = cc->core->bus;
@@ -234,7 +234,7 @@ static void bcma_pmu_workarounds(struct bcma_drv_cc *cc)
switch (bus->chipinfo.id) {
case BCMA_CHIP_ID_BCM4313:
/*
- * enable 12 mA drive strenth for 4313 and set chipControl
+ * enable 12 mA drive strength for 4313 and set chipControl
* register bit 1
*/
bcma_chipco_chipctl_maskset(cc, 0,
@@ -249,7 +249,7 @@ static void bcma_pmu_workarounds(struct bcma_drv_cc *cc)
case BCMA_CHIP_ID_BCM43224:
case BCMA_CHIP_ID_BCM43421:
/*
- * enable 12 mA drive strenth for 43224 and set chipControl
+ * enable 12 mA drive strength for 43224 and set chipControl
* register bit 15
*/
if (bus->chipinfo.rev == 0) {
diff --git a/drivers/bcma/driver_gpio.c b/drivers/bcma/driver_gpio.c
index 8a1e4705bc87..1e74ec1c7f23 100644
--- a/drivers/bcma/driver_gpio.c
+++ b/drivers/bcma/driver_gpio.c
@@ -181,7 +181,6 @@ int bcma_gpio_init(struct bcma_drv_cc *cc)
chip->set = bcma_gpio_set_value;
chip->direction_input = bcma_gpio_direction_input;
chip->direction_output = bcma_gpio_direction_output;
- chip->owner = THIS_MODULE;
chip->parent = bus->dev;
#if IS_BUILTIN(CONFIG_OF)
chip->of_node = cc->core->dev.of_node;
diff --git a/drivers/bcma/driver_pci_host.c b/drivers/bcma/driver_pci_host.c
index 6f8fc5f587fe..aa0581cda718 100644
--- a/drivers/bcma/driver_pci_host.c
+++ b/drivers/bcma/driver_pci_host.c
@@ -61,7 +61,7 @@ static u32 bcma_get_cfgspace_addr(struct bcma_drv_pci *pc, unsigned int dev,
{
u32 addr = 0;
- /* Issue config commands only when the data link is up (atleast
+ /* Issue config commands only when the data link is up (at least
* one external pcie device is present).
*/
if (dev >= 2 || !(bcma_pcie_read(pc, BCMA_CORE_PCI_DLLP_LSREG)
@@ -295,7 +295,7 @@ static u8 bcma_find_pci_capability(struct bcma_drv_pci *pc, unsigned int dev,
if (cap_ptr == 0x00)
return cap_ptr;
- /* loop thr'u the capability list and see if the requested capabilty
+ /* loop through the capability list and see if the requested capability
* exists */
bcma_extpci_read_config(pc, dev, func, cap_ptr, &cap_id, sizeof(u8));
while (cap_id != req_cap_id) {
@@ -317,7 +317,7 @@ static u8 bcma_find_pci_capability(struct bcma_drv_pci *pc, unsigned int dev,
*buflen = 0;
- /* copy the cpability data excluding cap ID and next ptr */
+ /* copy the capability data excluding cap ID and next ptr */
cap_data = cap_ptr + 2;
if ((bufsize + cap_data) > PCI_CONFIG_SPACE_SIZE)
bufsize = PCI_CONFIG_SPACE_SIZE - cap_data;
diff --git a/drivers/bcma/main.c b/drivers/bcma/main.c
index 8e7ca3e4c8c4..44392b624b20 100644
--- a/drivers/bcma/main.c
+++ b/drivers/bcma/main.c
@@ -293,7 +293,7 @@ static int bcma_register_devices(struct bcma_bus *bus)
int err;
list_for_each_entry(core, &bus->cores, list) {
- /* We support that cores ourself */
+ /* We support that core ourselves */
switch (core->id.id) {
case BCMA_CORE_4706_CHIPCOMMON:
case BCMA_CORE_CHIPCOMMON:
@@ -369,7 +369,7 @@ void bcma_unregister_cores(struct bcma_bus *bus)
if (bus->hosttype == BCMA_HOSTTYPE_SOC)
platform_device_unregister(bus->drv_cc.watchdog);
- /* Now noone uses internally-handled cores, we can free them */
+ /* Now no one uses internally-handled cores, we can free them */
list_for_each_entry_safe(core, tmp, &bus->cores, list) {
list_del(&core->list);
put_device(&core->dev);
diff --git a/drivers/bcma/sprom.c b/drivers/bcma/sprom.c
index bd2c923a6586..3da01f173c63 100644
--- a/drivers/bcma/sprom.c
+++ b/drivers/bcma/sprom.c
@@ -28,7 +28,7 @@ static int(*get_fallback_sprom)(struct bcma_bus *dev, struct ssb_sprom *out);
* callback handler which fills the SPROM data structure. The fallback is
* used for PCI based BCMA devices, where no valid SPROM can be found
* in the shadow registers and to provide the SPROM for SoCs where BCMA is
- * to controll the system bus.
+ * to control the system bus.
*
* This function is useful for weird architectures that have a half-assed
* BCMA device hardwired to their PCI bus.
@@ -281,7 +281,7 @@ static void bcma_sprom_extract_r8(struct bcma_bus *bus, const u16 *sprom)
SPEX(alpha2[0], SSB_SPROM8_CCODE, 0xff00, 8);
SPEX(alpha2[1], SSB_SPROM8_CCODE, 0x00ff, 0);
- /* Extract cores power info info */
+ /* Extract core's power info */
for (i = 0; i < ARRAY_SIZE(pwr_info_offset); i++) {
o = pwr_info_offset[i];
SPEX(core_pwr_info[i].itssi_2g, o + SSB_SROM8_2G_MAXP_ITSSI,
diff --git a/drivers/block/aoe/aoeblk.c b/drivers/block/aoe/aoeblk.c
index 52484bcdedb9..8a91fcac6f82 100644
--- a/drivers/block/aoe/aoeblk.c
+++ b/drivers/block/aoe/aoeblk.c
@@ -12,7 +12,6 @@
#include <linux/ioctl.h>
#include <linux/slab.h>
#include <linux/ratelimit.h>
-#include <linux/genhd.h>
#include <linux/netdevice.h>
#include <linux/mutex.h>
#include <linux/export.h>
diff --git a/drivers/block/aoe/aoecmd.c b/drivers/block/aoe/aoecmd.c
index 6af111f568e4..384073ef2323 100644
--- a/drivers/block/aoe/aoecmd.c
+++ b/drivers/block/aoe/aoecmd.c
@@ -10,7 +10,6 @@
#include <linux/blk-mq.h>
#include <linux/skbuff.h>
#include <linux/netdevice.h>
-#include <linux/genhd.h>
#include <linux/moduleparam.h>
#include <linux/workqueue.h>
#include <linux/kthread.h>
@@ -1019,9 +1018,9 @@ bvcpy(struct sk_buff *skb, struct bio *bio, struct bvec_iter iter, long cnt)
iter.bi_size = cnt;
__bio_for_each_segment(bv, bio, iter, iter) {
- char *p = kmap_atomic(bv.bv_page) + bv.bv_offset;
+ char *p = bvec_kmap_local(&bv);
skb_copy_bits(skb, soff, p, bv.bv_len);
- kunmap_atomic(p);
+ kunmap_local(p);
soff += bv.bv_len;
}
}
diff --git a/drivers/block/drbd/drbd_actlog.c b/drivers/block/drbd/drbd_actlog.c
index 72cf7603d51f..f5bcded3640d 100644
--- a/drivers/block/drbd/drbd_actlog.c
+++ b/drivers/block/drbd/drbd_actlog.c
@@ -138,15 +138,14 @@ static int _drbd_md_sync_page_io(struct drbd_device *device,
op_flags |= REQ_FUA | REQ_PREFLUSH;
op_flags |= REQ_SYNC;
- bio = bio_alloc_bioset(GFP_NOIO, 1, &drbd_md_io_bio_set);
- bio_set_dev(bio, bdev->md_bdev);
+ bio = bio_alloc_bioset(bdev->md_bdev, 1, op | op_flags, GFP_NOIO,
+ &drbd_md_io_bio_set);
bio->bi_iter.bi_sector = sector;
err = -EIO;
if (bio_add_page(bio, device->md_io.page, size, 0) != size)
goto out;
bio->bi_private = device;
bio->bi_end_io = drbd_md_endio;
- bio_set_op_attrs(bio, op, op_flags);
if (op != REQ_OP_WRITE && device->state.disk == D_DISKLESS && device->ldev == NULL)
/* special case, drbd_md_read() during drbd_adm_attach(): no get_ldev */
diff --git a/drivers/block/drbd/drbd_bitmap.c b/drivers/block/drbd/drbd_bitmap.c
index c1f816f896a8..df25eecf80af 100644
--- a/drivers/block/drbd/drbd_bitmap.c
+++ b/drivers/block/drbd/drbd_bitmap.c
@@ -976,12 +976,13 @@ static void drbd_bm_endio(struct bio *bio)
static void bm_page_io_async(struct drbd_bm_aio_ctx *ctx, int page_nr) __must_hold(local)
{
- struct bio *bio = bio_alloc_bioset(GFP_NOIO, 1, &drbd_md_io_bio_set);
struct drbd_device *device = ctx->device;
+ unsigned int op = (ctx->flags & BM_AIO_READ) ? REQ_OP_READ : REQ_OP_WRITE;
+ struct bio *bio = bio_alloc_bioset(device->ldev->md_bdev, 1, op,
+ GFP_NOIO, &drbd_md_io_bio_set);
struct drbd_bitmap *b = device->bitmap;
struct page *page;
unsigned int len;
- unsigned int op = (ctx->flags & BM_AIO_READ) ? REQ_OP_READ : REQ_OP_WRITE;
sector_t on_disk_sector =
device->ldev->md.md_offset + device->ldev->md.bm_offset;
@@ -1006,14 +1007,12 @@ static void bm_page_io_async(struct drbd_bm_aio_ctx *ctx, int page_nr) __must_ho
bm_store_page_idx(page, page_nr);
} else
page = b->bm_pages[page_nr];
- bio_set_dev(bio, device->ldev->md_bdev);
bio->bi_iter.bi_sector = on_disk_sector;
/* bio_add_page of a single page to an empty bio will always succeed,
* according to api. Do we want to assert that? */
bio_add_page(bio, page, len, 0);
bio->bi_private = ctx;
bio->bi_end_io = drbd_bm_endio;
- bio_set_op_attrs(bio, op, 0);
if (drbd_insert_fault(device, (op == REQ_OP_WRITE) ? DRBD_FAULT_MD_WR : DRBD_FAULT_MD_RD)) {
bio_io_error(bio);
diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h
index f27d5b0f9a0b..4b55e864a0a3 100644
--- a/drivers/block/drbd/drbd_int.h
+++ b/drivers/block/drbd/drbd_int.h
@@ -27,7 +27,6 @@
#include <linux/major.h>
#include <linux/blkdev.h>
#include <linux/backing-dev.h>
-#include <linux/genhd.h>
#include <linux/idr.h>
#include <linux/dynamic_debug.h>
#include <net/tcp.h>
@@ -638,9 +637,6 @@ enum {
STATE_SENT, /* Do not change state/UUIDs while this is set */
CALLBACK_PENDING, /* Whether we have a call_usermodehelper(, UMH_WAIT_PROC)
* pending, from drbd worker context.
- * If set, bdi_write_congested() returns true,
- * so shrink_page_list() would not recurse into,
- * and potentially deadlock on, this drbd worker.
*/
DISCONNECT_SENT,
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
index 20b071443193..08da922f81d1 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -1279,16 +1279,16 @@ static void one_flush_endio(struct bio *bio)
static void submit_one_flush(struct drbd_device *device, struct issue_flush_context *ctx)
{
- struct bio *bio = bio_alloc(GFP_NOIO, 0);
+ struct bio *bio = bio_alloc(device->ldev->backing_bdev, 0,
+ REQ_OP_FLUSH | REQ_PREFLUSH, GFP_NOIO);
struct one_flush_context *octx = kmalloc(sizeof(*octx), GFP_NOIO);
- if (!bio || !octx) {
- drbd_warn(device, "Could not allocate a bio, CANNOT ISSUE FLUSH\n");
+
+ if (!octx) {
+ drbd_warn(device, "Could not allocate a octx, CANNOT ISSUE FLUSH\n");
/* FIXME: what else can I do now? disconnecting or detaching
* really does not help to improve the state of the world, either.
*/
- kfree(octx);
- if (bio)
- bio_put(bio);
+ bio_put(bio);
ctx->error = -ENOMEM;
put_ldev(device);
@@ -1298,10 +1298,8 @@ static void submit_one_flush(struct drbd_device *device, struct issue_flush_cont
octx->device = device;
octx->ctx = ctx;
- bio_set_dev(bio, device->ldev->backing_bdev);
bio->bi_private = octx;
bio->bi_end_io = one_flush_endio;
- bio->bi_opf = REQ_OP_FLUSH | REQ_PREFLUSH;
device->flush_jif = jiffies;
set_bit(FLUSH_PENDING, &device->flags);
@@ -1634,7 +1632,6 @@ int drbd_submit_peer_request(struct drbd_device *device,
unsigned data_size = peer_req->i.size;
unsigned n_bios = 0;
unsigned nr_pages = (data_size + PAGE_SIZE -1) >> PAGE_SHIFT;
- int err = -ENOMEM;
/* TRIM/DISCARD: for now, always use the helper function
* blkdev_issue_zeroout(..., discard=true).
@@ -1672,15 +1669,10 @@ int drbd_submit_peer_request(struct drbd_device *device,
* generated bio, but a bio allocated on behalf of the peer.
*/
next_bio:
- bio = bio_alloc(GFP_NOIO, nr_pages);
- if (!bio) {
- drbd_err(device, "submit_ee: Allocation of a bio failed (nr_pages=%u)\n", nr_pages);
- goto fail;
- }
+ bio = bio_alloc(device->ldev->backing_bdev, nr_pages, op | op_flags,
+ GFP_NOIO);
/* > peer_req->i.sector, unless this is the first bio */
bio->bi_iter.bi_sector = sector;
- bio_set_dev(bio, device->ldev->backing_bdev);
- bio_set_op_attrs(bio, op, op_flags);
bio->bi_private = peer_req;
bio->bi_end_io = drbd_peer_request_endio;
@@ -1711,14 +1703,6 @@ next_bio:
drbd_submit_bio_noacct(device, fault_type, bio);
} while (bios);
return 0;
-
-fail:
- while (bios) {
- bio = bios;
- bios = bios->bi_next;
- bio_put(bio);
- }
- return err;
}
static void drbd_remove_epoch_entry_interval(struct drbd_device *device,
@@ -2003,10 +1987,10 @@ static int recv_dless_read(struct drbd_peer_device *peer_device, struct drbd_req
D_ASSERT(peer_device->device, sector == bio->bi_iter.bi_sector);
bio_for_each_segment(bvec, bio, iter) {
- void *mapped = kmap(bvec.bv_page) + bvec.bv_offset;
+ void *mapped = bvec_kmap_local(&bvec);
expect = min_t(int, data_size, bvec.bv_len);
err = drbd_recv_all_warn(peer_device->connection, mapped, expect);
- kunmap(bvec.bv_page);
+ kunmap_local(mapped);
if (err)
return err;
data_size -= expect;
diff --git a/drivers/block/drbd/drbd_req.c b/drivers/block/drbd/drbd_req.c
index 84d61f7d1c35..c04394518b07 100644
--- a/drivers/block/drbd/drbd_req.c
+++ b/drivers/block/drbd/drbd_req.c
@@ -30,7 +30,8 @@ static struct drbd_request *drbd_req_new(struct drbd_device *device, struct bio
return NULL;
memset(req, 0, sizeof(*req));
- req->private_bio = bio_clone_fast(bio_src, GFP_NOIO, &drbd_io_bio_set);
+ req->private_bio = bio_alloc_clone(device->ldev->backing_bdev, bio_src,
+ GFP_NOIO, &drbd_io_bio_set);
req->private_bio->bi_private = req;
req->private_bio->bi_end_io = drbd_request_endio;
@@ -908,8 +909,7 @@ static bool remote_due_to_read_balancing(struct drbd_device *device, sector_t se
switch (rbm) {
case RB_CONGESTED_REMOTE:
- return bdi_read_congested(
- device->ldev->backing_bdev->bd_disk->bdi);
+ return 0;
case RB_LEAST_PENDING:
return atomic_read(&device->local_cnt) >
atomic_read(&device->ap_pending_cnt) + atomic_read(&device->rs_pending_cnt);
@@ -1150,8 +1150,6 @@ drbd_submit_req_private_bio(struct drbd_request *req)
else
type = DRBD_FAULT_DT_RD;
- bio_set_dev(bio, device->ldev->backing_bdev);
-
/* State may have changed since we grabbed our reference on the
* ->ldev member. Double check, and short-circuit to endio.
* In case the last activity log transaction failed to get on
diff --git a/drivers/block/drbd/drbd_worker.c b/drivers/block/drbd/drbd_worker.c
index 934bfb5d98d0..0f9956f4e9c4 100644
--- a/drivers/block/drbd/drbd_worker.c
+++ b/drivers/block/drbd/drbd_worker.c
@@ -326,9 +326,9 @@ void drbd_csum_bio(struct crypto_shash *tfm, struct bio *bio, void *digest)
bio_for_each_segment(bvec, bio, iter) {
u8 *src;
- src = kmap_atomic(bvec.bv_page);
- crypto_shash_update(desc, src + bvec.bv_offset, bvec.bv_len);
- kunmap_atomic(src);
+ src = bvec_kmap_local(&bvec);
+ crypto_shash_update(desc, src, bvec.bv_len);
+ kunmap_local(src);
}
crypto_shash_final(desc, digest);
shash_desc_zero(desc);
@@ -1518,9 +1518,9 @@ int w_restart_disk_io(struct drbd_work *w, int cancel)
if (bio_data_dir(req->master_bio) == WRITE && req->rq_state & RQ_IN_ACT_LOG)
drbd_al_begin_io(device, &req->i);
- req->private_bio = bio_clone_fast(req->master_bio, GFP_NOIO,
+ req->private_bio = bio_alloc_clone(device->ldev->backing_bdev,
+ req->master_bio, GFP_NOIO,
&drbd_io_bio_set);
- bio_set_dev(req->private_bio, device->ldev->backing_bdev);
req->private_bio->bi_private = req;
req->private_bio->bi_end_io = drbd_request_endio;
submit_bio_noacct(req->private_bio);
diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c
index e611411a934c..8c647532e3ce 100644
--- a/drivers/block/floppy.c
+++ b/drivers/block/floppy.c
@@ -2485,11 +2485,9 @@ static void copy_buffer(int ssize, int max_sector, int max_sector_2)
}
if (CT(raw_cmd->cmd[COMMAND]) == FD_READ)
- memcpy_to_page(bv.bv_page, bv.bv_offset, dma_buffer,
- size);
+ memcpy_to_bvec(&bv, dma_buffer);
else
- memcpy_from_page(dma_buffer, bv.bv_page, bv.bv_offset,
- size);
+ memcpy_from_bvec(dma_buffer, &bv);
remaining -= size;
dma_buffer += size;
@@ -4129,15 +4127,13 @@ static int __floppy_read_block_0(struct block_device *bdev, int drive)
cbdata.drive = drive;
- bio_init(&bio, &bio_vec, 1);
- bio_set_dev(&bio, bdev);
+ bio_init(&bio, bdev, &bio_vec, 1, REQ_OP_READ);
bio_add_page(&bio, page, block_size(bdev), 0);
bio.bi_iter.bi_sector = 0;
bio.bi_flags |= (1 << BIO_QUIET);
bio.bi_private = &cbdata;
bio.bi_end_io = floppy_rb0_cb;
- bio_set_op_attrs(&bio, REQ_OP_READ, 0);
init_completion(&cbdata.complete);
diff --git a/drivers/block/loop.c b/drivers/block/loop.c
index 01cbbfc4e9e2..3e636a75c83a 100644
--- a/drivers/block/loop.c
+++ b/drivers/block/loop.c
@@ -79,12 +79,14 @@
#include <linux/ioprio.h>
#include <linux/blk-cgroup.h>
#include <linux/sched/mm.h>
+#include <linux/statfs.h>
#include "loop.h"
#include <linux/uaccess.h>
#define LOOP_IDLE_WORKER_TIMEOUT (60 * HZ)
+#define LOOP_DEFAULT_HW_Q_DEPTH (128)
static DEFINE_IDR(loop_index_idr);
static DEFINE_MUTEX(loop_ctl_mutex);
@@ -308,12 +310,11 @@ static int lo_fallocate(struct loop_device *lo, struct request *rq, loff_t pos,
* a.k.a. discard/zerorange.
*/
struct file *file = lo->lo_backing_file;
- struct request_queue *q = lo->lo_queue;
int ret;
mode |= FALLOC_FL_KEEP_SIZE;
- if (!blk_queue_discard(q)) {
+ if (!blk_queue_discard(lo->lo_queue)) {
ret = -EOPNOTSUPP;
goto out;
}
@@ -327,8 +328,7 @@ static int lo_fallocate(struct loop_device *lo, struct request *rq, loff_t pos,
static int lo_req_flush(struct loop_device *lo, struct request *rq)
{
- struct file *file = lo->lo_backing_file;
- int ret = vfs_fsync(file, 0);
+ int ret = vfs_fsync(lo->lo_backing_file, 0);
if (unlikely(ret && ret != -EINVAL))
ret = -EIO;
@@ -680,33 +680,33 @@ static ssize_t loop_attr_backing_file_show(struct loop_device *lo, char *buf)
static ssize_t loop_attr_offset_show(struct loop_device *lo, char *buf)
{
- return sprintf(buf, "%llu\n", (unsigned long long)lo->lo_offset);
+ return sysfs_emit(buf, "%llu\n", (unsigned long long)lo->lo_offset);
}
static ssize_t loop_attr_sizelimit_show(struct loop_device *lo, char *buf)
{
- return sprintf(buf, "%llu\n", (unsigned long long)lo->lo_sizelimit);
+ return sysfs_emit(buf, "%llu\n", (unsigned long long)lo->lo_sizelimit);
}
static ssize_t loop_attr_autoclear_show(struct loop_device *lo, char *buf)
{
int autoclear = (lo->lo_flags & LO_FLAGS_AUTOCLEAR);
- return sprintf(buf, "%s\n", autoclear ? "1" : "0");
+ return sysfs_emit(buf, "%s\n", autoclear ? "1" : "0");
}
static ssize_t loop_attr_partscan_show(struct loop_device *lo, char *buf)
{
int partscan = (lo->lo_flags & LO_FLAGS_PARTSCAN);
- return sprintf(buf, "%s\n", partscan ? "1" : "0");
+ return sysfs_emit(buf, "%s\n", partscan ? "1" : "0");
}
static ssize_t loop_attr_dio_show(struct loop_device *lo, char *buf)
{
int dio = (lo->lo_flags & LO_FLAGS_DIRECT_IO);
- return sprintf(buf, "%s\n", dio ? "1" : "0");
+ return sysfs_emit(buf, "%s\n", dio ? "1" : "0");
}
LOOP_ATTR_RO(backing_file);
@@ -774,8 +774,13 @@ static void loop_config_discard(struct loop_device *lo)
granularity = 0;
} else {
+ struct kstatfs sbuf;
+
max_discard_sectors = UINT_MAX >> 9;
- granularity = inode->i_sb->s_blocksize;
+ if (!vfs_statfs(&file->f_path, &sbuf))
+ granularity = sbuf.f_bsize;
+ else
+ max_discard_sectors = 0;
}
if (max_discard_sectors) {
@@ -1082,7 +1087,7 @@ out_putf:
return error;
}
-static void __loop_clr_fd(struct loop_device *lo)
+static void __loop_clr_fd(struct loop_device *lo, bool release)
{
struct file *filp;
gfp_t gfp = lo->old_gfp_mask;
@@ -1144,6 +1149,8 @@ static void __loop_clr_fd(struct loop_device *lo)
/* let user-space know about this change */
kobject_uevent(&disk_to_dev(lo->lo_disk)->kobj, KOBJ_CHANGE);
mapping_set_gfp_mask(filp->f_mapping, gfp);
+ /* This is safe: open() is still holding a reference. */
+ module_put(THIS_MODULE);
blk_mq_unfreeze_queue(lo->lo_queue);
disk_force_media_change(lo->lo_disk, DISK_EVENT_MEDIA_CHANGE);
@@ -1151,52 +1158,44 @@ static void __loop_clr_fd(struct loop_device *lo)
if (lo->lo_flags & LO_FLAGS_PARTSCAN) {
int err;
- mutex_lock(&lo->lo_disk->open_mutex);
+ /*
+ * open_mutex has been held already in release path, so don't
+ * acquire it if this function is called in such case.
+ *
+ * If the reread partition isn't from release path, lo_refcnt
+ * must be at least one and it can only become zero when the
+ * current holder is released.
+ */
+ if (!release)
+ mutex_lock(&lo->lo_disk->open_mutex);
err = bdev_disk_changed(lo->lo_disk, false);
- mutex_unlock(&lo->lo_disk->open_mutex);
+ if (!release)
+ mutex_unlock(&lo->lo_disk->open_mutex);
if (err)
pr_warn("%s: partition scan of loop%d failed (rc=%d)\n",
__func__, lo->lo_number, err);
/* Device is gone, no point in returning error */
}
+ /*
+ * lo->lo_state is set to Lo_unbound here after above partscan has
+ * finished. There cannot be anybody else entering __loop_clr_fd() as
+ * Lo_rundown state protects us from all the other places trying to
+ * change the 'lo' device.
+ */
lo->lo_flags = 0;
if (!part_shift)
lo->lo_disk->flags |= GENHD_FL_NO_PART;
-
- fput(filp);
-}
-
-static void loop_rundown_completed(struct loop_device *lo)
-{
mutex_lock(&lo->lo_mutex);
lo->lo_state = Lo_unbound;
mutex_unlock(&lo->lo_mutex);
- module_put(THIS_MODULE);
-}
-static void loop_rundown_workfn(struct work_struct *work)
-{
- struct loop_device *lo = container_of(work, struct loop_device,
- rundown_work);
- struct block_device *bdev = lo->lo_device;
- struct gendisk *disk = lo->lo_disk;
-
- __loop_clr_fd(lo);
- kobject_put(&bdev->bd_device.kobj);
- module_put(disk->fops->owner);
- loop_rundown_completed(lo);
-}
-
-static void loop_schedule_rundown(struct loop_device *lo)
-{
- struct block_device *bdev = lo->lo_device;
- struct gendisk *disk = lo->lo_disk;
-
- __module_get(disk->fops->owner);
- kobject_get(&bdev->bd_device.kobj);
- INIT_WORK(&lo->rundown_work, loop_rundown_workfn);
- queue_work(system_long_wq, &lo->rundown_work);
+ /*
+ * Need not hold lo_mutex to fput backing file. Calling fput holding
+ * lo_mutex triggers a circular lock dependency possibility warning as
+ * fput can take open_mutex which is usually taken before lo_mutex.
+ */
+ fput(filp);
}
static int loop_clr_fd(struct loop_device *lo)
@@ -1228,8 +1227,7 @@ static int loop_clr_fd(struct loop_device *lo)
lo->lo_state = Lo_rundown;
mutex_unlock(&lo->lo_mutex);
- __loop_clr_fd(lo);
- loop_rundown_completed(lo);
+ __loop_clr_fd(lo, false);
return 0;
}
@@ -1262,7 +1260,7 @@ loop_set_status(struct loop_device *lo, const struct loop_info64 *info)
if (size_changed && lo->lo_device->bd_inode->i_mapping->nrpages) {
/* If any pages were dirtied after invalidate_bdev(), try again */
err = -EAGAIN;
- pr_warn("%s: loop%d (%s) has still dirty pages (nrpages=%lu)\n",
+ pr_warn("%s: loop%d (%s) still has dirty pages (nrpages=%lu)\n",
__func__, lo->lo_number, lo->lo_file_name,
lo->lo_device->bd_inode->i_mapping->nrpages);
goto out_unfreeze;
@@ -1482,7 +1480,7 @@ static int loop_set_block_size(struct loop_device *lo, unsigned long arg)
/* invalidate_bdev should have truncated all the pages */
if (lo->lo_device->bd_inode->i_mapping->nrpages) {
err = -EAGAIN;
- pr_warn("%s: loop%d (%s) has still dirty pages (nrpages=%lu)\n",
+ pr_warn("%s: loop%d (%s) still has dirty pages (nrpages=%lu)\n",
__func__, lo->lo_number, lo->lo_file_name,
lo->lo_device->bd_inode->i_mapping->nrpages);
goto out_unfreeze;
@@ -1754,7 +1752,7 @@ static void lo_release(struct gendisk *disk, fmode_t mode)
* In autoclear mode, stop the loop thread
* and remove configuration after last close.
*/
- loop_schedule_rundown(lo);
+ __loop_clr_fd(lo, true);
return;
} else if (lo->lo_state == Lo_bound) {
/*
@@ -1787,6 +1785,24 @@ module_param(max_loop, int, 0444);
MODULE_PARM_DESC(max_loop, "Maximum number of loop devices");
module_param(max_part, int, 0444);
MODULE_PARM_DESC(max_part, "Maximum number of partitions per loop device");
+
+static int hw_queue_depth = LOOP_DEFAULT_HW_Q_DEPTH;
+
+static int loop_set_hw_queue_depth(const char *s, const struct kernel_param *p)
+{
+ int ret = kstrtoint(s, 10, &hw_queue_depth);
+
+ return (ret || (hw_queue_depth < 1)) ? -EINVAL : 0;
+}
+
+static const struct kernel_param_ops loop_hw_qdepth_param_ops = {
+ .set = loop_set_hw_queue_depth,
+ .get = param_get_int,
+};
+
+device_param_cb(hw_queue_depth, &loop_hw_qdepth_param_ops, &hw_queue_depth, 0444);
+MODULE_PARM_DESC(hw_queue_depth, "Queue depth for each hardware queue. Default: 128");
+
MODULE_LICENSE("GPL");
MODULE_ALIAS_BLOCKDEV_MAJOR(LOOP_MAJOR);
@@ -1981,7 +1997,7 @@ static int loop_add(int i)
lo->tag_set.ops = &loop_mq_ops;
lo->tag_set.nr_hw_queues = 1;
- lo->tag_set.queue_depth = 128;
+ lo->tag_set.queue_depth = hw_queue_depth;
lo->tag_set.numa_node = NUMA_NO_NODE;
lo->tag_set.cmd_size = sizeof(struct loop_cmd);
lo->tag_set.flags = BLK_MQ_F_SHOULD_MERGE | BLK_MQ_F_STACKING |
@@ -2075,6 +2091,7 @@ static void loop_remove(struct loop_device *lo)
del_gendisk(lo->lo_disk);
blk_cleanup_disk(lo->lo_disk);
blk_mq_free_tag_set(&lo->tag_set);
+
mutex_lock(&loop_ctl_mutex);
idr_remove(&loop_index_idr, lo->lo_number);
mutex_unlock(&loop_ctl_mutex);
diff --git a/drivers/block/loop.h b/drivers/block/loop.h
index 918a7a2dc025..082d4b6bfc6a 100644
--- a/drivers/block/loop.h
+++ b/drivers/block/loop.h
@@ -56,7 +56,6 @@ struct loop_device {
struct gendisk *lo_disk;
struct mutex lo_mutex;
bool idr_visible;
- struct work_struct rundown_work;
};
struct loop_cmd {
diff --git a/drivers/block/mtip32xx/mtip32xx.c b/drivers/block/mtip32xx/mtip32xx.c
index e6005c232328..4fbaf0b4958b 100644
--- a/drivers/block/mtip32xx/mtip32xx.c
+++ b/drivers/block/mtip32xx/mtip32xx.c
@@ -19,7 +19,6 @@
#include <linux/compat.h>
#include <linux/fs.h>
#include <linux/module.h>
-#include <linux/genhd.h>
#include <linux/blkdev.h>
#include <linux/blk-mq.h>
#include <linux/bio.h>
@@ -161,9 +160,7 @@ static bool mtip_check_surprise_removal(struct driver_data *dd)
static struct mtip_cmd *mtip_cmd_from_tag(struct driver_data *dd,
unsigned int tag)
{
- struct blk_mq_hw_ctx *hctx = dd->queue->queue_hw_ctx[0];
-
- return blk_mq_rq_to_pdu(blk_mq_tag_to_rq(hctx->tags, tag));
+ return blk_mq_rq_to_pdu(blk_mq_tag_to_rq(dd->tags.tags[0], tag));
}
/*
@@ -4112,7 +4109,7 @@ static void mtip_pci_remove(struct pci_dev *pdev)
"Completion workers still active!\n");
}
- blk_set_queue_dying(dd->queue);
+ blk_mark_disk_dead(dd->disk);
set_bit(MTIP_DDF_REMOVE_PENDING_BIT, &dd->dd_flag);
/* Clean up the block layer. */
diff --git a/drivers/block/mtip32xx/mtip32xx.h b/drivers/block/mtip32xx/mtip32xx.h
index 88f4206310e4..6816beb45352 100644
--- a/drivers/block/mtip32xx/mtip32xx.h
+++ b/drivers/block/mtip32xx/mtip32xx.h
@@ -15,7 +15,6 @@
#include <linux/rwsem.h>
#include <linux/ata.h>
#include <linux/interrupt.h>
-#include <linux/genhd.h>
/* Offset of Subsystem Device ID in pci confoguration space */
#define PCI_SUBSYSTEM_DEVICEID 0x2E
diff --git a/drivers/block/null_blk/main.c b/drivers/block/null_blk/main.c
index 13004beb48ca..05b1120e6623 100644
--- a/drivers/block/null_blk/main.c
+++ b/drivers/block/null_blk/main.c
@@ -431,9 +431,10 @@ static ssize_t nullb_device_power_store(struct config_item *item,
if (!dev->power && newp) {
if (test_and_set_bit(NULLB_DEV_FL_UP, &dev->flags))
return count;
- if (null_add_dev(dev)) {
+ ret = null_add_dev(dev);
+ if (ret) {
clear_bit(NULLB_DEV_FL_UP, &dev->flags);
- return -ENOMEM;
+ return ret;
}
set_bit(NULLB_DEV_FL_CONFIGURED, &dev->flags);
@@ -719,26 +720,25 @@ static struct nullb_cmd *__alloc_cmd(struct nullb_queue *nq)
return NULL;
}
-static struct nullb_cmd *alloc_cmd(struct nullb_queue *nq, int can_wait)
+static struct nullb_cmd *alloc_cmd(struct nullb_queue *nq, struct bio *bio)
{
struct nullb_cmd *cmd;
DEFINE_WAIT(wait);
- cmd = __alloc_cmd(nq);
- if (cmd || !can_wait)
- return cmd;
-
do {
- prepare_to_wait(&nq->wait, &wait, TASK_UNINTERRUPTIBLE);
+ /*
+ * This avoids multiple return statements, multiple calls to
+ * __alloc_cmd() and a fast path call to prepare_to_wait().
+ */
cmd = __alloc_cmd(nq);
- if (cmd)
- break;
-
+ if (cmd) {
+ cmd->bio = bio;
+ return cmd;
+ }
+ prepare_to_wait(&nq->wait, &wait, TASK_UNINTERRUPTIBLE);
io_schedule();
+ finish_wait(&nq->wait, &wait);
} while (1);
-
- finish_wait(&nq->wait, &wait);
- return cmd;
}
static void end_cmd(struct nullb_cmd *cmd)
@@ -777,24 +777,22 @@ static void null_complete_rq(struct request *rq)
end_cmd(blk_mq_rq_to_pdu(rq));
}
-static struct nullb_page *null_alloc_page(gfp_t gfp_flags)
+static struct nullb_page *null_alloc_page(void)
{
struct nullb_page *t_page;
- t_page = kmalloc(sizeof(struct nullb_page), gfp_flags);
+ t_page = kmalloc(sizeof(struct nullb_page), GFP_NOIO);
if (!t_page)
- goto out;
+ return NULL;
- t_page->page = alloc_pages(gfp_flags, 0);
- if (!t_page->page)
- goto out_freepage;
+ t_page->page = alloc_pages(GFP_NOIO, 0);
+ if (!t_page->page) {
+ kfree(t_page);
+ return NULL;
+ }
memset(t_page->bitmap, 0, sizeof(t_page->bitmap));
return t_page;
-out_freepage:
- kfree(t_page);
-out:
- return NULL;
}
static void null_free_page(struct nullb_page *t_page)
@@ -932,7 +930,7 @@ static struct nullb_page *null_insert_page(struct nullb *nullb,
spin_unlock_irq(&nullb->lock);
- t_page = null_alloc_page(GFP_NOIO);
+ t_page = null_alloc_page();
if (!t_page)
goto out_lock;
@@ -1476,12 +1474,8 @@ static void null_submit_bio(struct bio *bio)
sector_t nr_sectors = bio_sectors(bio);
struct nullb *nullb = bio->bi_bdev->bd_disk->private_data;
struct nullb_queue *nq = nullb_to_queue(nullb);
- struct nullb_cmd *cmd;
-
- cmd = alloc_cmd(nq, 1);
- cmd->bio = bio;
- null_handle_cmd(cmd, sector, nr_sectors, bio_op(bio));
+ null_handle_cmd(alloc_cmd(nq, bio), sector, nr_sectors, bio_op(bio));
}
static bool should_timeout_request(struct request *rq)
diff --git a/drivers/block/pktcdvd.c b/drivers/block/pktcdvd.c
index aca94ebf4947..86c8794ede41 100644
--- a/drivers/block/pktcdvd.c
+++ b/drivers/block/pktcdvd.c
@@ -1022,9 +1022,8 @@ static void pkt_gather_data(struct pktcdvd_device *pd, struct packet_data *pkt)
continue;
bio = pkt->r_bios[f];
- bio_reset(bio);
+ bio_reset(bio, pd->bdev, REQ_OP_READ);
bio->bi_iter.bi_sector = pkt->sector + f * (CD_FRAMESIZE >> 9);
- bio_set_dev(bio, pd->bdev);
bio->bi_end_io = pkt_end_io_read;
bio->bi_private = pkt;
@@ -1036,7 +1035,6 @@ static void pkt_gather_data(struct pktcdvd_device *pd, struct packet_data *pkt)
BUG();
atomic_inc(&pkt->io_wait);
- bio_set_op_attrs(bio, REQ_OP_READ, 0);
pkt_queue_bio(pd, bio);
frames_read++;
}
@@ -1237,9 +1235,8 @@ static void pkt_start_write(struct pktcdvd_device *pd, struct packet_data *pkt)
{
int f;
- bio_reset(pkt->w_bio);
+ bio_reset(pkt->w_bio, pd->bdev, REQ_OP_WRITE);
pkt->w_bio->bi_iter.bi_sector = pkt->sector;
- bio_set_dev(pkt->w_bio, pd->bdev);
pkt->w_bio->bi_end_io = pkt_end_io_packet_write;
pkt->w_bio->bi_private = pkt;
@@ -1272,7 +1269,6 @@ static void pkt_start_write(struct pktcdvd_device *pd, struct packet_data *pkt)
/* Start the write request */
atomic_set(&pkt->io_wait, 1);
- bio_set_op_attrs(pkt->w_bio, REQ_OP_WRITE, 0);
pkt_queue_bio(pd, pkt->w_bio);
}
@@ -2300,12 +2296,12 @@ static void pkt_end_io_read_cloned(struct bio *bio)
static void pkt_make_request_read(struct pktcdvd_device *pd, struct bio *bio)
{
- struct bio *cloned_bio = bio_clone_fast(bio, GFP_NOIO, &pkt_bio_set);
+ struct bio *cloned_bio =
+ bio_alloc_clone(pd->bdev, bio, GFP_NOIO, &pkt_bio_set);
struct packet_stacked_data *psd = mempool_alloc(&psd_pool, GFP_NOIO);
psd->pd = pd;
psd->bio = bio;
- bio_set_dev(cloned_bio, pd->bdev);
cloned_bio->bi_private = psd;
cloned_bio->bi_end_io = pkt_end_io_read_cloned;
pd->stats.secs_r += bio_sectors(bio);
@@ -2406,18 +2402,11 @@ static void pkt_make_request_write(struct request_queue *q, struct bio *bio)
static void pkt_submit_bio(struct bio *bio)
{
- struct pktcdvd_device *pd;
- char b[BDEVNAME_SIZE];
+ struct pktcdvd_device *pd = bio->bi_bdev->bd_disk->queue->queuedata;
struct bio *split;
blk_queue_split(&bio);
- pd = bio->bi_bdev->bd_disk->queue->queuedata;
- if (!pd) {
- pr_err("%s incorrect request queue\n", bio_devname(bio, b));
- goto end_io;
- }
-
pkt_dbg(2, pd, "start = %6llx stop = %6llx\n",
(unsigned long long)bio->bi_iter.bi_sector,
(unsigned long long)bio_end_sector(bio));
diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c
index 4203cdab8abf..b844432bad20 100644
--- a/drivers/block/rbd.c
+++ b/drivers/block/rbd.c
@@ -7185,7 +7185,7 @@ static ssize_t do_rbd_remove(struct bus_type *bus,
* IO to complete/fail.
*/
blk_mq_freeze_queue(rbd_dev->disk->queue);
- blk_set_queue_dying(rbd_dev->disk->queue);
+ blk_mark_disk_dead(rbd_dev->disk);
}
del_gendisk(rbd_dev->disk);
diff --git a/drivers/block/rnbd/rnbd-clt.c b/drivers/block/rnbd/rnbd-clt.c
index dc192d273885..b66e8840b94b 100644
--- a/drivers/block/rnbd/rnbd-clt.c
+++ b/drivers/block/rnbd/rnbd-clt.c
@@ -23,7 +23,6 @@ MODULE_LICENSE("GPL");
static int rnbd_client_major;
static DEFINE_IDA(index_ida);
-static DEFINE_MUTEX(ida_lock);
static DEFINE_MUTEX(sess_lock);
static LIST_HEAD(sess_list);
@@ -55,9 +54,7 @@ static void rnbd_clt_put_dev(struct rnbd_clt_dev *dev)
if (!refcount_dec_and_test(&dev->refcount))
return;
- mutex_lock(&ida_lock);
- ida_simple_remove(&index_ida, dev->clt_device_id);
- mutex_unlock(&ida_lock);
+ ida_free(&index_ida, dev->clt_device_id);
kfree(dev->hw_queues);
kfree(dev->pathname);
rnbd_clt_put_sess(dev->sess);
@@ -86,7 +83,6 @@ static int rnbd_clt_set_dev_attr(struct rnbd_clt_dev *dev,
dev->discard_granularity = le32_to_cpu(rsp->discard_granularity);
dev->discard_alignment = le32_to_cpu(rsp->discard_alignment);
dev->secure_discard = le16_to_cpu(rsp->secure_discard);
- dev->rotational = rsp->rotational;
dev->wc = !!(rsp->cache_policy & RNBD_WRITEBACK);
dev->fua = !!(rsp->cache_policy & RNBD_FUA);
@@ -1261,9 +1257,9 @@ find_and_get_or_create_sess(const char *sessname,
struct rtrs_clt_ops rtrs_ops;
sess = find_or_create_sess(sessname, &first);
- if (sess == ERR_PTR(-ENOMEM))
+ if (sess == ERR_PTR(-ENOMEM)) {
return ERR_PTR(-ENOMEM);
- else if ((nr_poll_queues && !first) || (!nr_poll_queues && sess->nr_poll_queues)) {
+ } else if ((nr_poll_queues && !first) || (!nr_poll_queues && sess->nr_poll_queues)) {
/*
* A device MUST have its own session to use the polling-mode.
* It must fail to map new device with the same session.
@@ -1342,7 +1338,7 @@ static inline void rnbd_init_hw_queue(struct rnbd_clt_dev *dev,
static void rnbd_init_mq_hw_queues(struct rnbd_clt_dev *dev)
{
- int i;
+ unsigned long i;
struct blk_mq_hw_ctx *hctx;
struct rnbd_queue *q;
@@ -1407,8 +1403,10 @@ static int rnbd_clt_setup_gen_disk(struct rnbd_clt_dev *dev, int idx)
dev->read_only = false;
}
- if (!dev->rotational)
- blk_queue_flag_set(QUEUE_FLAG_NONROT, dev->queue);
+ /*
+ * Network device does not need rotational
+ */
+ blk_queue_flag_set(QUEUE_FLAG_NONROT, dev->queue);
err = add_disk(dev->gd);
if (err)
blk_cleanup_disk(dev->gd);
@@ -1456,10 +1454,8 @@ static struct rnbd_clt_dev *init_dev(struct rnbd_clt_session *sess,
goto out_alloc;
}
- mutex_lock(&ida_lock);
- ret = ida_simple_get(&index_ida, 0, 1 << (MINORBITS - RNBD_PART_BITS),
- GFP_KERNEL);
- mutex_unlock(&ida_lock);
+ ret = ida_alloc_max(&index_ida, 1 << (MINORBITS - RNBD_PART_BITS),
+ GFP_KERNEL);
if (ret < 0) {
pr_err("Failed to initialize device '%s' from session %s, allocating idr failed, err: %d\n",
pathname, sess->sessname, ret);
@@ -1607,13 +1603,13 @@ struct rnbd_clt_dev *rnbd_clt_map_device(const char *sessname,
}
rnbd_clt_info(dev,
- "map_device: Device mapped as %s (nsectors: %zu, logical_block_size: %d, physical_block_size: %d, max_discard_sectors: %d, discard_granularity: %d, discard_alignment: %d, secure_discard: %d, max_segments: %d, max_hw_sectors: %d, rotational: %d, wc: %d, fua: %d)\n",
+ "map_device: Device mapped as %s (nsectors: %zu, logical_block_size: %d, physical_block_size: %d, max_discard_sectors: %d, discard_granularity: %d, discard_alignment: %d, secure_discard: %d, max_segments: %d, max_hw_sectors: %d, wc: %d, fua: %d)\n",
dev->gd->disk_name, dev->nsectors,
dev->logical_block_size, dev->physical_block_size,
dev->max_discard_sectors,
dev->discard_granularity, dev->discard_alignment,
dev->secure_discard, dev->max_segments,
- dev->max_hw_sectors, dev->rotational, dev->wc, dev->fua);
+ dev->max_hw_sectors, dev->wc, dev->fua);
mutex_unlock(&dev->lock);
rnbd_clt_put_sess(sess);
diff --git a/drivers/block/rnbd/rnbd-clt.h b/drivers/block/rnbd/rnbd-clt.h
index 6946ba23d62e..2e2e8c4a85c1 100644
--- a/drivers/block/rnbd/rnbd-clt.h
+++ b/drivers/block/rnbd/rnbd-clt.h
@@ -118,7 +118,6 @@ struct rnbd_clt_dev {
enum rnbd_access_mode access_mode;
u32 nr_poll_queues;
bool read_only;
- bool rotational;
bool wc;
bool fua;
u32 max_hw_sectors;
diff --git a/drivers/block/rnbd/rnbd-proto.h b/drivers/block/rnbd/rnbd-proto.h
index 3eb8b34bd188..bfb08dd434d1 100644
--- a/drivers/block/rnbd/rnbd-proto.h
+++ b/drivers/block/rnbd/rnbd-proto.h
@@ -128,7 +128,7 @@ enum rnbd_cache_policy {
* @logical_block_size: logical block size device supports in bytes
* @max_segments: max segments hardware support in one transfer
* @secure_discard: supports secure discard
- * @rotation: is a rotational disc?
+ * @obsolete_rotational: obsolete, not in used.
* @cache_policy: support write-back caching or FUA?
*/
struct rnbd_msg_open_rsp {
@@ -144,7 +144,7 @@ struct rnbd_msg_open_rsp {
__le16 logical_block_size;
__le16 max_segments;
__le16 secure_discard;
- u8 rotational;
+ u8 obsolete_rotational;
u8 cache_policy;
u8 reserved[10];
};
diff --git a/drivers/block/rnbd/rnbd-srv-dev.c b/drivers/block/rnbd/rnbd-srv-dev.c
index b241a099aeae..c5d0a0391165 100644
--- a/drivers/block/rnbd/rnbd-srv-dev.c
+++ b/drivers/block/rnbd/rnbd-srv-dev.c
@@ -12,8 +12,7 @@
#include "rnbd-srv-dev.h"
#include "rnbd-log.h"
-struct rnbd_dev *rnbd_dev_open(const char *path, fmode_t flags,
- struct bio_set *bs)
+struct rnbd_dev *rnbd_dev_open(const char *path, fmode_t flags)
{
struct rnbd_dev *dev;
int ret;
@@ -30,7 +29,6 @@ struct rnbd_dev *rnbd_dev_open(const char *path, fmode_t flags,
dev->blk_open_flags = flags;
bdevname(dev->bdev, dev->name);
- dev->ibd_bio_set = bs;
return dev;
@@ -44,60 +42,3 @@ void rnbd_dev_close(struct rnbd_dev *dev)
blkdev_put(dev->bdev, dev->blk_open_flags);
kfree(dev);
}
-
-void rnbd_dev_bi_end_io(struct bio *bio)
-{
- struct rnbd_dev_blk_io *io = bio->bi_private;
-
- rnbd_endio(io->priv, blk_status_to_errno(bio->bi_status));
- bio_put(bio);
-}
-
-/**
- * rnbd_bio_map_kern - map kernel address into bio
- * @data: pointer to buffer to map
- * @bs: bio_set to use.
- * @len: length in bytes
- * @gfp_mask: allocation flags for bio allocation
- *
- * Map the kernel address into a bio suitable for io to a block
- * device. Returns an error pointer in case of error.
- */
-struct bio *rnbd_bio_map_kern(void *data, struct bio_set *bs,
- unsigned int len, gfp_t gfp_mask)
-{
- unsigned long kaddr = (unsigned long)data;
- unsigned long end = (kaddr + len + PAGE_SIZE - 1) >> PAGE_SHIFT;
- unsigned long start = kaddr >> PAGE_SHIFT;
- const int nr_pages = end - start;
- int offset, i;
- struct bio *bio;
-
- bio = bio_alloc_bioset(gfp_mask, nr_pages, bs);
- if (!bio)
- return ERR_PTR(-ENOMEM);
-
- offset = offset_in_page(kaddr);
- for (i = 0; i < nr_pages; i++) {
- unsigned int bytes = PAGE_SIZE - offset;
-
- if (len <= 0)
- break;
-
- if (bytes > len)
- bytes = len;
-
- if (bio_add_page(bio, virt_to_page(data), bytes,
- offset) < bytes) {
- /* we don't support partial mappings */
- bio_put(bio);
- return ERR_PTR(-EINVAL);
- }
-
- data += bytes;
- len -= bytes;
- offset = 0;
- }
-
- return bio;
-}
diff --git a/drivers/block/rnbd/rnbd-srv-dev.h b/drivers/block/rnbd/rnbd-srv-dev.h
index 0eb23850afb9..2c3df02b5e8e 100644
--- a/drivers/block/rnbd/rnbd-srv-dev.h
+++ b/drivers/block/rnbd/rnbd-srv-dev.h
@@ -14,25 +14,16 @@
struct rnbd_dev {
struct block_device *bdev;
- struct bio_set *ibd_bio_set;
fmode_t blk_open_flags;
char name[BDEVNAME_SIZE];
};
-struct rnbd_dev_blk_io {
- struct rnbd_dev *dev;
- void *priv;
- /* have to be last member for front_pad usage of bioset_init */
- struct bio bio;
-};
-
/**
* rnbd_dev_open() - Open a device
+ * @path: path to open
* @flags: open flags
- * @bs: bio_set to use during block io,
*/
-struct rnbd_dev *rnbd_dev_open(const char *path, fmode_t flags,
- struct bio_set *bs);
+struct rnbd_dev *rnbd_dev_open(const char *path, fmode_t flags);
/**
* rnbd_dev_close() - Close a device
@@ -41,11 +32,6 @@ void rnbd_dev_close(struct rnbd_dev *dev);
void rnbd_endio(void *priv, int error);
-void rnbd_dev_bi_end_io(struct bio *bio);
-
-struct bio *rnbd_bio_map_kern(void *data, struct bio_set *bs,
- unsigned int len, gfp_t gfp_mask);
-
static inline int rnbd_dev_get_max_segs(const struct rnbd_dev *dev)
{
return queue_max_segments(bdev_get_queue(dev->bdev));
diff --git a/drivers/block/rnbd/rnbd-srv-sysfs.c b/drivers/block/rnbd/rnbd-srv-sysfs.c
index 4db98e0e76f0..feaa76c5a342 100644
--- a/drivers/block/rnbd/rnbd-srv-sysfs.c
+++ b/drivers/block/rnbd/rnbd-srv-sysfs.c
@@ -13,7 +13,6 @@
#include <linux/kobject.h>
#include <linux/sysfs.h>
#include <linux/stat.h>
-#include <linux/genhd.h>
#include <linux/list.h>
#include <linux/moduleparam.h>
#include <linux/device.h>
diff --git a/drivers/block/rnbd/rnbd-srv.c b/drivers/block/rnbd/rnbd-srv.c
index ffcd937c2cf6..f04df6294650 100644
--- a/drivers/block/rnbd/rnbd-srv.c
+++ b/drivers/block/rnbd/rnbd-srv.c
@@ -114,6 +114,12 @@ rnbd_get_sess_dev(int dev_id, struct rnbd_srv_session *srv_sess)
return sess_dev;
}
+static void rnbd_dev_bi_end_io(struct bio *bio)
+{
+ rnbd_endio(bio->bi_private, blk_status_to_errno(bio->bi_status));
+ bio_put(bio);
+}
+
static int process_rdma(struct rnbd_srv_session *srv_sess,
struct rtrs_srv_op *id, void *data, u32 datalen,
const void *usr, size_t usrlen)
@@ -123,7 +129,6 @@ static int process_rdma(struct rnbd_srv_session *srv_sess,
struct rnbd_srv_sess_dev *sess_dev;
u32 dev_id;
int err;
- struct rnbd_dev_blk_io *io;
struct bio *bio;
short prio;
@@ -144,33 +149,29 @@ static int process_rdma(struct rnbd_srv_session *srv_sess,
priv->sess_dev = sess_dev;
priv->id = id;
- /* Generate bio with pages pointing to the rdma buffer */
- bio = rnbd_bio_map_kern(data, sess_dev->rnbd_dev->ibd_bio_set, datalen, GFP_KERNEL);
- if (IS_ERR(bio)) {
- err = PTR_ERR(bio);
- rnbd_srv_err(sess_dev, "Failed to generate bio, err: %d\n", err);
- goto sess_dev_put;
+ bio = bio_alloc(sess_dev->rnbd_dev->bdev, 1,
+ rnbd_to_bio_flags(le32_to_cpu(msg->rw)), GFP_KERNEL);
+ if (bio_add_page(bio, virt_to_page(data), datalen,
+ offset_in_page(data)) != datalen) {
+ rnbd_srv_err(sess_dev, "Failed to map data to bio\n");
+ err = -EINVAL;
+ goto bio_put;
}
- io = container_of(bio, struct rnbd_dev_blk_io, bio);
- io->dev = sess_dev->rnbd_dev;
- io->priv = priv;
-
bio->bi_end_io = rnbd_dev_bi_end_io;
- bio->bi_private = io;
- bio->bi_opf = rnbd_to_bio_flags(le32_to_cpu(msg->rw));
+ bio->bi_private = priv;
bio->bi_iter.bi_sector = le64_to_cpu(msg->sector);
bio->bi_iter.bi_size = le32_to_cpu(msg->bi_size);
prio = srv_sess->ver < RNBD_PROTO_VER_MAJOR ||
usrlen < sizeof(*msg) ? 0 : le16_to_cpu(msg->prio);
bio_set_prio(bio, prio);
- bio_set_dev(bio, sess_dev->rnbd_dev->bdev);
submit_bio(bio);
return 0;
-sess_dev_put:
+bio_put:
+ bio_put(bio);
rnbd_put_sess_dev(sess_dev);
err:
kfree(priv);
@@ -251,7 +252,6 @@ static void destroy_sess(struct rnbd_srv_session *srv_sess)
out:
xa_destroy(&srv_sess->index_idr);
- bioset_exit(&srv_sess->sess_bio_set);
pr_info("RTRS Session %s disconnected\n", srv_sess->sessname);
@@ -280,16 +280,6 @@ static int create_sess(struct rtrs_srv_sess *rtrs)
return -ENOMEM;
srv_sess->queue_depth = rtrs_srv_get_queue_depth(rtrs);
- err = bioset_init(&srv_sess->sess_bio_set, srv_sess->queue_depth,
- offsetof(struct rnbd_dev_blk_io, bio),
- BIOSET_NEED_BVECS);
- if (err) {
- pr_err("Allocating srv_session for path %s failed\n",
- pathname);
- kfree(srv_sess);
- return err;
- }
-
xa_init_flags(&srv_sess->index_idr, XA_FLAGS_ALLOC);
INIT_LIST_HEAD(&srv_sess->sess_dev_list);
mutex_init(&srv_sess->lock);
@@ -567,7 +557,6 @@ static void rnbd_srv_fill_msg_open_rsp(struct rnbd_msg_open_rsp *rsp,
cpu_to_le32(rnbd_dev_get_discard_alignment(rnbd_dev));
rsp->secure_discard =
cpu_to_le16(rnbd_dev_get_secure_discard(rnbd_dev));
- rsp->rotational = !blk_queue_nonrot(q);
rsp->cache_policy = 0;
if (test_bit(QUEUE_FLAG_WC, &q->queue_flags))
rsp->cache_policy |= RNBD_WRITEBACK;
@@ -737,8 +726,7 @@ static int process_msg_open(struct rnbd_srv_session *srv_sess,
goto reject;
}
- rnbd_dev = rnbd_dev_open(full_path, open_flags,
- &srv_sess->sess_bio_set);
+ rnbd_dev = rnbd_dev_open(full_path, open_flags);
if (IS_ERR(rnbd_dev)) {
pr_err("Opening device '%s' on session %s failed, failed to open the block device, err: %ld\n",
full_path, srv_sess->sessname, PTR_ERR(rnbd_dev));
diff --git a/drivers/block/rnbd/rnbd-srv.h b/drivers/block/rnbd/rnbd-srv.h
index e5604bce123a..be2ae486d407 100644
--- a/drivers/block/rnbd/rnbd-srv.h
+++ b/drivers/block/rnbd/rnbd-srv.h
@@ -23,7 +23,6 @@ struct rnbd_srv_session {
struct rtrs_srv_sess *rtrs;
char sessname[NAME_MAX];
int queue_depth;
- struct bio_set sess_bio_set;
struct xarray index_idr;
/* List of struct rnbd_srv_sess_dev */
diff --git a/drivers/block/sunvdc.c b/drivers/block/sunvdc.c
index 146d85d80e0e..dd0a1a6fed29 100644
--- a/drivers/block/sunvdc.c
+++ b/drivers/block/sunvdc.c
@@ -9,7 +9,6 @@
#include <linux/types.h>
#include <linux/blk-mq.h>
#include <linux/hdreg.h>
-#include <linux/genhd.h>
#include <linux/cdrom.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c
index c443cd64fc9b..a8bcf3f664af 100644
--- a/drivers/block/virtio_blk.c
+++ b/drivers/block/virtio_blk.c
@@ -69,16 +69,6 @@ struct virtio_blk {
/* Process context for config space updates */
struct work_struct config_work;
- /*
- * Tracks references from block_device_operations open/release and
- * virtio_driver probe/remove so this object can be freed once no
- * longer in use.
- */
- refcount_t refs;
-
- /* What host tells us, plus 2 for header & tailer. */
- unsigned int sg_elems;
-
/* Ida index - used to track minor number allocations. */
int index;
@@ -322,8 +312,6 @@ static blk_status_t virtio_queue_rq(struct blk_mq_hw_ctx *hctx,
blk_status_t status;
int err;
- BUG_ON(req->nr_phys_segments + 2 > vblk->sg_elems);
-
status = virtblk_setup_cmd(vblk->vdev, req, vbr);
if (unlikely(status))
return status;
@@ -391,43 +379,6 @@ out:
return err;
}
-static void virtblk_get(struct virtio_blk *vblk)
-{
- refcount_inc(&vblk->refs);
-}
-
-static void virtblk_put(struct virtio_blk *vblk)
-{
- if (refcount_dec_and_test(&vblk->refs)) {
- ida_simple_remove(&vd_index_ida, vblk->index);
- mutex_destroy(&vblk->vdev_mutex);
- kfree(vblk);
- }
-}
-
-static int virtblk_open(struct block_device *bd, fmode_t mode)
-{
- struct virtio_blk *vblk = bd->bd_disk->private_data;
- int ret = 0;
-
- mutex_lock(&vblk->vdev_mutex);
-
- if (vblk->vdev)
- virtblk_get(vblk);
- else
- ret = -ENXIO;
-
- mutex_unlock(&vblk->vdev_mutex);
- return ret;
-}
-
-static void virtblk_release(struct gendisk *disk, fmode_t mode)
-{
- struct virtio_blk *vblk = disk->private_data;
-
- virtblk_put(vblk);
-}
-
/* We provide getgeo only to please some old bootloader/partitioning tools */
static int virtblk_getgeo(struct block_device *bd, struct hd_geometry *geo)
{
@@ -460,11 +411,19 @@ out:
return ret;
}
+static void virtblk_free_disk(struct gendisk *disk)
+{
+ struct virtio_blk *vblk = disk->private_data;
+
+ ida_simple_remove(&vd_index_ida, vblk->index);
+ mutex_destroy(&vblk->vdev_mutex);
+ kfree(vblk);
+}
+
static const struct block_device_operations virtblk_fops = {
- .owner = THIS_MODULE,
- .open = virtblk_open,
- .release = virtblk_release,
- .getgeo = virtblk_getgeo,
+ .owner = THIS_MODULE,
+ .getgeo = virtblk_getgeo,
+ .free_disk = virtblk_free_disk,
};
static int index_to_minor(int index)
@@ -783,20 +742,15 @@ static int virtblk_probe(struct virtio_device *vdev)
/* Prevent integer overflows and honor max vq size */
sg_elems = min_t(u32, sg_elems, VIRTIO_BLK_MAX_SG_ELEMS - 2);
- /* We need extra sg elements at head and tail. */
- sg_elems += 2;
vdev->priv = vblk = kmalloc(sizeof(*vblk), GFP_KERNEL);
if (!vblk) {
err = -ENOMEM;
goto out_free_index;
}
- /* This reference is dropped in virtblk_remove(). */
- refcount_set(&vblk->refs, 1);
mutex_init(&vblk->vdev_mutex);
vblk->vdev = vdev;
- vblk->sg_elems = sg_elems;
INIT_WORK(&vblk->config_work, virtblk_config_changed_work);
@@ -853,7 +807,7 @@ static int virtblk_probe(struct virtio_device *vdev)
set_disk_ro(vblk->disk, 1);
/* We can handle whatever the host told us to handle. */
- blk_queue_max_segments(q, vblk->sg_elems-2);
+ blk_queue_max_segments(q, sg_elems);
/* No real sector limit. */
blk_queue_max_hw_sectors(q, -1U);
@@ -925,9 +879,15 @@ static int virtblk_probe(struct virtio_device *vdev)
virtio_cread(vdev, struct virtio_blk_config, max_discard_seg,
&v);
+
+ /*
+ * max_discard_seg == 0 is out of spec but we always
+ * handled it.
+ */
+ if (!v)
+ v = sg_elems;
blk_queue_max_discard_segments(q,
- min_not_zero(v,
- MAX_DISCARD_SEGMENTS));
+ min(v, MAX_DISCARD_SEGMENTS));
blk_queue_flag_set(QUEUE_FLAG_DISCARD, q);
}
@@ -970,7 +930,7 @@ static void virtblk_remove(struct virtio_device *vdev)
flush_work(&vblk->config_work);
del_gendisk(vblk->disk);
- blk_cleanup_disk(vblk->disk);
+ blk_cleanup_queue(vblk->disk->queue);
blk_mq_free_tag_set(&vblk->tag_set);
mutex_lock(&vblk->vdev_mutex);
@@ -986,7 +946,7 @@ static void virtblk_remove(struct virtio_device *vdev)
mutex_unlock(&vblk->vdev_mutex);
- virtblk_put(vblk);
+ put_disk(vblk->disk);
}
#ifdef CONFIG_PM_SLEEP
@@ -1060,7 +1020,7 @@ static struct virtio_driver virtio_blk = {
#endif
};
-static int __init init(void)
+static int __init virtio_blk_init(void)
{
int error;
@@ -1086,14 +1046,14 @@ out_destroy_workqueue:
return error;
}
-static void __exit fini(void)
+static void __exit virtio_blk_fini(void)
{
unregister_virtio_driver(&virtio_blk);
unregister_blkdev(major, "virtblk");
destroy_workqueue(virtblk_wq);
}
-module_init(init);
-module_exit(fini);
+module_init(virtio_blk_init);
+module_exit(virtio_blk_fini);
MODULE_DEVICE_TABLE(virtio, id_table);
MODULE_DESCRIPTION("Virtio block driver");
diff --git a/drivers/block/xen-blkback/blkback.c b/drivers/block/xen-blkback/blkback.c
index 14e452896d04..d1e26461a64e 100644
--- a/drivers/block/xen-blkback/blkback.c
+++ b/drivers/block/xen-blkback/blkback.c
@@ -1326,16 +1326,13 @@ static int dispatch_rw_block_io(struct xen_blkif_ring *ring,
pages[i]->page,
seg[i].nsec << 9,
seg[i].offset) == 0)) {
- bio = bio_alloc(GFP_KERNEL, bio_max_segs(nseg - i));
- if (unlikely(bio == NULL))
- goto fail_put_bio;
-
+ bio = bio_alloc(preq.bdev, bio_max_segs(nseg - i),
+ operation | operation_flags,
+ GFP_KERNEL);
biolist[nbio++] = bio;
- bio_set_dev(bio, preq.bdev);
bio->bi_private = pending_req;
bio->bi_end_io = end_block_io_op;
bio->bi_iter.bi_sector = preq.sector_number;
- bio_set_op_attrs(bio, operation, operation_flags);
}
preq.sector_number += seg[i].nsec;
@@ -1345,15 +1342,11 @@ static int dispatch_rw_block_io(struct xen_blkif_ring *ring,
if (!bio) {
BUG_ON(operation_flags != REQ_PREFLUSH);
- bio = bio_alloc(GFP_KERNEL, 0);
- if (unlikely(bio == NULL))
- goto fail_put_bio;
-
+ bio = bio_alloc(preq.bdev, 0, operation | operation_flags,
+ GFP_KERNEL);
biolist[nbio++] = bio;
- bio_set_dev(bio, preq.bdev);
bio->bi_private = pending_req;
bio->bi_end_io = end_block_io_op;
- bio_set_op_attrs(bio, operation, operation_flags);
}
atomic_set(&pending_req->pendcnt, nbio);
@@ -1381,14 +1374,6 @@ static int dispatch_rw_block_io(struct xen_blkif_ring *ring,
free_req(ring, pending_req);
msleep(1); /* back off a bit */
return -EIO;
-
- fail_put_bio:
- for (i = 0; i < nbio; i++)
- bio_put(biolist[i]);
- atomic_set(&pending_req->pendcnt, 1);
- __end_block_io_op(pending_req, BLK_STS_RESOURCE);
- msleep(1); /* back off a bit */
- return -EIO;
}
diff --git a/drivers/block/xen-blkback/xenbus.c b/drivers/block/xen-blkback/xenbus.c
index 62125fd4af4a..f09040435e2e 100644
--- a/drivers/block/xen-blkback/xenbus.c
+++ b/drivers/block/xen-blkback/xenbus.c
@@ -10,6 +10,7 @@
#include <linux/module.h>
#include <linux/kthread.h>
+#include <linux/pagemap.h>
#include <xen/events.h>
#include <xen/grant_table.h>
#include "common.h"
diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c
index ccd0dd0c6b83..85fc550508cc 100644
--- a/drivers/block/xen-blkfront.c
+++ b/drivers/block/xen-blkfront.c
@@ -1288,7 +1288,8 @@ free_shadow:
rinfo->ring_ref[i] = GRANT_INVALID_REF;
}
}
- free_pages((unsigned long)rinfo->ring.sring, get_order(info->nr_ring_pages * XEN_PAGE_SIZE));
+ free_pages_exact(rinfo->ring.sring,
+ info->nr_ring_pages * XEN_PAGE_SIZE);
rinfo->ring.sring = NULL;
if (rinfo->irq)
@@ -1372,9 +1373,15 @@ static int blkif_get_final_status(enum blk_req_status s1,
return BLKIF_RSP_OKAY;
}
-static bool blkif_completion(unsigned long *id,
- struct blkfront_ring_info *rinfo,
- struct blkif_response *bret)
+/*
+ * Return values:
+ * 1 response processed.
+ * 0 missing further responses.
+ * -1 error while processing.
+ */
+static int blkif_completion(unsigned long *id,
+ struct blkfront_ring_info *rinfo,
+ struct blkif_response *bret)
{
int i = 0;
struct scatterlist *sg;
@@ -1397,7 +1404,7 @@ static bool blkif_completion(unsigned long *id,
/* Wait the second response if not yet here. */
if (s2->status < REQ_DONE)
- return false;
+ return 0;
bret->status = blkif_get_final_status(s->status,
s2->status);
@@ -1448,42 +1455,43 @@ static bool blkif_completion(unsigned long *id,
}
/* Add the persistent grant into the list of free grants */
for (i = 0; i < num_grant; i++) {
- if (gnttab_query_foreign_access(s->grants_used[i]->gref)) {
+ if (!gnttab_try_end_foreign_access(s->grants_used[i]->gref)) {
/*
* If the grant is still mapped by the backend (the
* backend has chosen to make this grant persistent)
* we add it at the head of the list, so it will be
* reused first.
*/
- if (!info->feature_persistent)
- pr_alert_ratelimited("backed has not unmapped grant: %u\n",
- s->grants_used[i]->gref);
+ if (!info->feature_persistent) {
+ pr_alert("backed has not unmapped grant: %u\n",
+ s->grants_used[i]->gref);
+ return -1;
+ }
list_add(&s->grants_used[i]->node, &rinfo->grants);
rinfo->persistent_gnts_c++;
} else {
/*
- * If the grant is not mapped by the backend we end the
- * foreign access and add it to the tail of the list,
- * so it will not be picked again unless we run out of
- * persistent grants.
+ * If the grant is not mapped by the backend we add it
+ * to the tail of the list, so it will not be picked
+ * again unless we run out of persistent grants.
*/
- gnttab_end_foreign_access(s->grants_used[i]->gref, 0, 0UL);
s->grants_used[i]->gref = GRANT_INVALID_REF;
list_add_tail(&s->grants_used[i]->node, &rinfo->grants);
}
}
if (s->req.operation == BLKIF_OP_INDIRECT) {
for (i = 0; i < INDIRECT_GREFS(num_grant); i++) {
- if (gnttab_query_foreign_access(s->indirect_grants[i]->gref)) {
- if (!info->feature_persistent)
- pr_alert_ratelimited("backed has not unmapped grant: %u\n",
- s->indirect_grants[i]->gref);
+ if (!gnttab_try_end_foreign_access(s->indirect_grants[i]->gref)) {
+ if (!info->feature_persistent) {
+ pr_alert("backed has not unmapped grant: %u\n",
+ s->indirect_grants[i]->gref);
+ return -1;
+ }
list_add(&s->indirect_grants[i]->node, &rinfo->grants);
rinfo->persistent_gnts_c++;
} else {
struct page *indirect_page;
- gnttab_end_foreign_access(s->indirect_grants[i]->gref, 0, 0UL);
/*
* Add the used indirect page back to the list of
* available pages for indirect grefs.
@@ -1498,7 +1506,7 @@ static bool blkif_completion(unsigned long *id,
}
}
- return true;
+ return 1;
}
static irqreturn_t blkif_interrupt(int irq, void *dev_id)
@@ -1564,12 +1572,17 @@ static irqreturn_t blkif_interrupt(int irq, void *dev_id)
}
if (bret.operation != BLKIF_OP_DISCARD) {
+ int ret;
+
/*
* We may need to wait for an extra response if the
* I/O request is split in 2
*/
- if (!blkif_completion(&id, rinfo, &bret))
+ ret = blkif_completion(&id, rinfo, &bret);
+ if (!ret)
continue;
+ if (unlikely(ret < 0))
+ goto err;
}
if (add_id_to_freelist(rinfo, id)) {
@@ -1676,8 +1689,7 @@ static int setup_blkring(struct xenbus_device *dev,
for (i = 0; i < info->nr_ring_pages; i++)
rinfo->ring_ref[i] = GRANT_INVALID_REF;
- sring = (struct blkif_sring *)__get_free_pages(GFP_NOIO | __GFP_HIGH,
- get_order(ring_size));
+ sring = alloc_pages_exact(ring_size, GFP_NOIO);
if (!sring) {
xenbus_dev_fatal(dev, -ENOMEM, "allocating shared ring");
return -ENOMEM;
@@ -1687,7 +1699,7 @@ static int setup_blkring(struct xenbus_device *dev,
err = xenbus_grant_ring(dev, rinfo->ring.sring, info->nr_ring_pages, gref);
if (err < 0) {
- free_pages((unsigned long)sring, get_order(ring_size));
+ free_pages_exact(sring, ring_size);
rinfo->ring.sring = NULL;
goto fail;
}
@@ -2126,7 +2138,7 @@ static void blkfront_closing(struct blkfront_info *info)
/* No more blkif_request(). */
blk_mq_stop_hw_queues(info->rq);
- blk_set_queue_dying(info->rq);
+ blk_mark_disk_dead(info->gd);
set_capacity(info->gd, 0);
for_each_rinfo(info, rinfo, i) {
@@ -2521,6 +2533,7 @@ static void purge_persistent_grants(struct blkfront_info *info)
for_each_rinfo(info, rinfo, i) {
struct grant *gnt_list_entry, *tmp;
+ LIST_HEAD(grants);
spin_lock_irqsave(&rinfo->ring_lock, flags);
@@ -2532,16 +2545,17 @@ static void purge_persistent_grants(struct blkfront_info *info)
list_for_each_entry_safe(gnt_list_entry, tmp, &rinfo->grants,
node) {
if (gnt_list_entry->gref == GRANT_INVALID_REF ||
- gnttab_query_foreign_access(gnt_list_entry->gref))
+ !gnttab_try_end_foreign_access(gnt_list_entry->gref))
continue;
list_del(&gnt_list_entry->node);
- gnttab_end_foreign_access(gnt_list_entry->gref, 0, 0UL);
rinfo->persistent_gnts_c--;
gnt_list_entry->gref = GRANT_INVALID_REF;
- list_add_tail(&gnt_list_entry->node, &rinfo->grants);
+ list_add_tail(&gnt_list_entry->node, &grants);
}
+ list_splice_tail(&grants, &rinfo->grants);
+
spin_unlock_irqrestore(&rinfo->ring_lock, flags);
}
}
diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c
index cb253d80d72b..e9474b02012d 100644
--- a/drivers/block/zram/zram_drv.c
+++ b/drivers/block/zram/zram_drv.c
@@ -22,7 +22,6 @@
#include <linux/blkdev.h>
#include <linux/buffer_head.h>
#include <linux/device.h>
-#include <linux/genhd.h>
#include <linux/highmem.h>
#include <linux/slab.h>
#include <linux/backing-dev.h>
@@ -617,24 +616,21 @@ static int read_from_bdev_async(struct zram *zram, struct bio_vec *bvec,
{
struct bio *bio;
- bio = bio_alloc(GFP_NOIO, 1);
+ bio = bio_alloc(zram->bdev, 1, parent ? parent->bi_opf : REQ_OP_READ,
+ GFP_NOIO);
if (!bio)
return -ENOMEM;
bio->bi_iter.bi_sector = entry * (PAGE_SIZE >> 9);
- bio_set_dev(bio, zram->bdev);
if (!bio_add_page(bio, bvec->bv_page, bvec->bv_len, bvec->bv_offset)) {
bio_put(bio);
return -EIO;
}
- if (!parent) {
- bio->bi_opf = REQ_OP_READ;
+ if (!parent)
bio->bi_end_io = zram_page_end_io;
- } else {
- bio->bi_opf = parent->bi_opf;
+ else
bio_chain(bio, parent);
- }
submit_bio(bio);
return 1;
@@ -747,10 +743,9 @@ static ssize_t writeback_store(struct device *dev,
continue;
}
- bio_init(&bio, &bio_vec, 1);
- bio_set_dev(&bio, zram->bdev);
+ bio_init(&bio, zram->bdev, &bio_vec, 1,
+ REQ_OP_WRITE | REQ_SYNC);
bio.bi_iter.bi_sector = blk_idx * (PAGE_SIZE >> 9);
- bio.bi_opf = REQ_OP_WRITE | REQ_SYNC;
bio_add_page(&bio, bvec.bv_page, bvec.bv_len,
bvec.bv_offset);
@@ -1336,12 +1331,10 @@ static int zram_bvec_read(struct zram *zram, struct bio_vec *bvec,
goto out;
if (is_partial_io(bvec)) {
- void *dst = kmap_atomic(bvec->bv_page);
void *src = kmap_atomic(page);
- memcpy(dst + bvec->bv_offset, src + offset, bvec->bv_len);
+ memcpy_to_bvec(bvec, src + offset);
kunmap_atomic(src);
- kunmap_atomic(dst);
}
out:
if (is_partial_io(bvec))
@@ -1472,7 +1465,6 @@ static int zram_bvec_write(struct zram *zram, struct bio_vec *bvec,
{
int ret;
struct page *page = NULL;
- void *src;
struct bio_vec vec;
vec = *bvec;
@@ -1490,11 +1482,9 @@ static int zram_bvec_write(struct zram *zram, struct bio_vec *bvec,
if (ret)
goto out;
- src = kmap_atomic(bvec->bv_page);
dst = kmap_atomic(page);
- memcpy(dst + offset, src + bvec->bv_offset, bvec->bv_len);
+ memcpy_from_bvec(dst + offset, bvec);
kunmap_atomic(dst);
- kunmap_atomic(src);
vec.bv_page = page;
vec.bv_len = PAGE_SIZE;
diff --git a/drivers/bluetooth/Kconfig b/drivers/bluetooth/Kconfig
index 36380e618ba4..e30707405455 100644
--- a/drivers/bluetooth/Kconfig
+++ b/drivers/bluetooth/Kconfig
@@ -400,6 +400,7 @@ config BT_MTKSDIO
config BT_MTKUART
tristate "MediaTek HCI UART driver"
depends on SERIAL_DEV_BUS
+ select BT_MTK
help
MediaTek Bluetooth HCI UART driver.
This driver is required if you want to use MediaTek Bluetooth
diff --git a/drivers/bluetooth/ath3k.c b/drivers/bluetooth/ath3k.c
index 759d7828931d..88262d3a9392 100644
--- a/drivers/bluetooth/ath3k.c
+++ b/drivers/bluetooth/ath3k.c
@@ -10,7 +10,6 @@
#include <linux/slab.h>
#include <linux/types.h>
#include <linux/errno.h>
-#include <linux/device.h>
#include <linux/firmware.h>
#include <linux/usb.h>
#include <asm/unaligned.h>
diff --git a/drivers/bluetooth/bcm203x.c b/drivers/bluetooth/bcm203x.c
index e667933c3d70..c738ad0408cb 100644
--- a/drivers/bluetooth/bcm203x.c
+++ b/drivers/bluetooth/bcm203x.c
@@ -9,7 +9,6 @@
#include <linux/module.h>
-#include <linux/atomic.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/slab.h>
diff --git a/drivers/bluetooth/btintel.c b/drivers/bluetooth/btintel.c
index 1a4f8b227eac..06514ed66022 100644
--- a/drivers/bluetooth/btintel.c
+++ b/drivers/bluetooth/btintel.c
@@ -2428,10 +2428,15 @@ static int btintel_setup_combined(struct hci_dev *hdev)
/* Apply the device specific HCI quirks
*
- * WBS for SdP - SdP and Stp have a same hw_varaint but
- * different fw_variant
+ * WBS for SdP - For the Legacy ROM products, only SdP
+ * supports the WBS. But the version information is not
+ * enough to use here because the StP2 and SdP have same
+ * hw_variant and fw_variant. So, this flag is set by
+ * the transport driver (btusb) based on the HW info
+ * (idProduct)
*/
- if (ver.hw_variant == 0x08 && ver.fw_variant == 0x22)
+ if (!btintel_test_flag(hdev,
+ INTEL_ROM_LEGACY_NO_WBS_SUPPORT))
set_bit(HCI_QUIRK_WIDEBAND_SPEECH_SUPPORTED,
&hdev->quirks);
diff --git a/drivers/bluetooth/btintel.h b/drivers/bluetooth/btintel.h
index c9b24e9299e2..e0060e58573c 100644
--- a/drivers/bluetooth/btintel.h
+++ b/drivers/bluetooth/btintel.h
@@ -152,6 +152,7 @@ enum {
INTEL_BROKEN_INITIAL_NCMD,
INTEL_BROKEN_SHUTDOWN_LED,
INTEL_ROM_LEGACY,
+ INTEL_ROM_LEGACY_NO_WBS_SUPPORT,
__INTEL_NUM_FLAGS,
};
diff --git a/drivers/bluetooth/btmrvl_debugfs.c b/drivers/bluetooth/btmrvl_debugfs.c
index c4867576be00..db35b917aecf 100644
--- a/drivers/bluetooth/btmrvl_debugfs.c
+++ b/drivers/bluetooth/btmrvl_debugfs.c
@@ -1,4 +1,4 @@
-/**
+/*
* Marvell Bluetooth driver: debugfs related functions
*
* Copyright (C) 2009, Marvell International Ltd.
diff --git a/drivers/bluetooth/btmrvl_sdio.c b/drivers/bluetooth/btmrvl_sdio.c
index 68378b42ea7f..b8ef66f89fc1 100644
--- a/drivers/bluetooth/btmrvl_sdio.c
+++ b/drivers/bluetooth/btmrvl_sdio.c
@@ -1,4 +1,4 @@
-/**
+/*
* Marvell BT-over-SDIO driver: SDIO interface related functions.
*
* Copyright (C) 2009, Marvell International Ltd.
diff --git a/drivers/bluetooth/btmtk.c b/drivers/bluetooth/btmtk.c
index 526dfdf1fe01..809762d64fc6 100644
--- a/drivers/bluetooth/btmtk.c
+++ b/drivers/bluetooth/btmtk.c
@@ -285,6 +285,7 @@ MODULE_AUTHOR("Mark Chen <mark-yw.chen@mediatek.com>");
MODULE_DESCRIPTION("Bluetooth support for MediaTek devices ver " VERSION);
MODULE_VERSION(VERSION);
MODULE_LICENSE("GPL");
+MODULE_FIRMWARE(FIRMWARE_MT7622);
MODULE_FIRMWARE(FIRMWARE_MT7663);
MODULE_FIRMWARE(FIRMWARE_MT7668);
MODULE_FIRMWARE(FIRMWARE_MT7961);
diff --git a/drivers/bluetooth/btmtk.h b/drivers/bluetooth/btmtk.h
index 6e7b0c7567c0..2a88ea8e475e 100644
--- a/drivers/bluetooth/btmtk.h
+++ b/drivers/bluetooth/btmtk.h
@@ -1,14 +1,26 @@
/* SPDX-License-Identifier: ISC */
/* Copyright (C) 2021 MediaTek Inc. */
+#define FIRMWARE_MT7622 "mediatek/mt7622pr2h.bin"
#define FIRMWARE_MT7663 "mediatek/mt7663pr2h.bin"
#define FIRMWARE_MT7668 "mediatek/mt7668pr2h.bin"
#define FIRMWARE_MT7961 "mediatek/BT_RAM_CODE_MT7961_1_2_hdr.bin"
+#define HCI_EV_WMT 0xe4
#define HCI_WMT_MAX_EVENT_SIZE 64
+#define BTMTK_WMT_REG_WRITE 0x1
#define BTMTK_WMT_REG_READ 0x2
+#define MT7921_BTSYS_RST 0x70002610
+#define MT7921_BTSYS_RST_WITH_GPIO BIT(7)
+
+#define MT7921_PINMUX_0 0x70005050
+#define MT7921_PINMUX_1 0x70005054
+
+#define MT7921_DLSTATUS 0x7c053c10
+#define BT_DL_STATE BIT(1)
+
enum {
BTMTK_WMT_PATCH_DWNLD = 0x1,
BTMTK_WMT_TEST = 0x2,
@@ -68,6 +80,37 @@ struct btmtk_tci_sleep {
u8 time_compensation;
} __packed;
+struct btmtk_wakeon {
+ u8 mode;
+ u8 gpo;
+ u8 active_high;
+ __le16 enable_delay;
+ __le16 wakeup_delay;
+} __packed;
+
+struct btmtk_sco {
+ u8 clock_config;
+ u8 transmit_format_config;
+ u8 channel_format_config;
+ u8 channel_select_config;
+} __packed;
+
+struct reg_read_cmd {
+ u8 type;
+ u8 rsv;
+ u8 num;
+ __le32 addr;
+} __packed;
+
+struct reg_write_cmd {
+ u8 type;
+ u8 rsv;
+ u8 num;
+ __le32 addr;
+ __le32 data;
+ __le32 mask;
+} __packed;
+
struct btmtk_hci_wmt_params {
u8 op;
u8 flag;
diff --git a/drivers/bluetooth/btmtksdio.c b/drivers/bluetooth/btmtksdio.c
index b5ea8d3bffaa..f3dc5881fff7 100644
--- a/drivers/bluetooth/btmtksdio.c
+++ b/drivers/bluetooth/btmtksdio.c
@@ -12,10 +12,12 @@
#include <asm/unaligned.h>
#include <linux/atomic.h>
+#include <linux/gpio/consumer.h>
#include <linux/init.h>
#include <linux/iopoll.h>
#include <linux/kernel.h>
#include <linux/module.h>
+#include <linux/of.h>
#include <linux/pm_runtime.h>
#include <linux/skbuff.h>
@@ -31,28 +33,32 @@
#define VERSION "0.1"
-#define MTKBTSDIO_AUTOSUSPEND_DELAY 8000
+#define MTKBTSDIO_AUTOSUSPEND_DELAY 1000
-static bool enable_autosuspend;
+static bool enable_autosuspend = true;
struct btmtksdio_data {
const char *fwname;
u16 chipid;
+ bool lp_mbox_supported;
};
static const struct btmtksdio_data mt7663_data = {
.fwname = FIRMWARE_MT7663,
.chipid = 0x7663,
+ .lp_mbox_supported = false,
};
static const struct btmtksdio_data mt7668_data = {
.fwname = FIRMWARE_MT7668,
.chipid = 0x7668,
+ .lp_mbox_supported = false,
};
static const struct btmtksdio_data mt7921_data = {
.fwname = FIRMWARE_MT7961,
.chipid = 0x7921,
+ .lp_mbox_supported = true,
};
static const struct sdio_device_id btmtksdio_table[] = {
@@ -79,6 +85,7 @@ MODULE_DEVICE_TABLE(sdio, btmtksdio_table);
#define MTK_REG_CHCR 0xc
#define C_INT_CLR_CTRL BIT(1)
+#define BT_RST_DONE BIT(8)
/* CHISR have the same bits field definition with CHIER */
#define MTK_REG_CHISR 0x10
@@ -87,8 +94,17 @@ MODULE_DEVICE_TABLE(sdio, btmtksdio_table);
#define RX_DONE_INT BIT(1)
#define TX_EMPTY BIT(2)
#define TX_FIFO_OVERFLOW BIT(8)
+#define FW_MAILBOX_INT BIT(15)
+#define INT_MASK GENMASK(15, 0)
#define RX_PKT_LEN GENMASK(31, 16)
+#define MTK_REG_CSICR 0xc0
+#define CSICR_CLR_MBOX_ACK BIT(0)
+#define MTK_REG_PH2DSM0R 0xc4
+#define PH2DSM0R_DRIVER_OWN BIT(0)
+#define MTK_REG_PD2HRM0R 0xdc
+#define PD2HRM0R_DRV_OWN BIT(0)
+
#define MTK_REG_CTDR 0x18
#define MTK_REG_CRDR 0x1c
@@ -100,6 +116,8 @@ MODULE_DEVICE_TABLE(sdio, btmtksdio_table);
#define BTMTKSDIO_TX_WAIT_VND_EVT 1
#define BTMTKSDIO_HW_TX_READY 2
#define BTMTKSDIO_FUNC_ENABLED 3
+#define BTMTKSDIO_PATCH_ENABLED 4
+#define BTMTKSDIO_HW_RESET_ACTIVE 5
struct mtkbtsdio_hdr {
__le16 len;
@@ -119,6 +137,8 @@ struct btmtksdio_dev {
struct sk_buff *evt_skb;
const struct btmtksdio_data *data;
+
+ struct gpio_desc *reset;
};
static int mtk_hci_wmt_sync(struct hci_dev *hdev,
@@ -278,19 +298,89 @@ static u32 btmtksdio_drv_own_query(struct btmtksdio_dev *bdev)
return sdio_readl(bdev->func, MTK_REG_CHLPCR, NULL);
}
+static u32 btmtksdio_drv_own_query_79xx(struct btmtksdio_dev *bdev)
+{
+ return sdio_readl(bdev->func, MTK_REG_PD2HRM0R, NULL);
+}
+
+static u32 btmtksdio_chcr_query(struct btmtksdio_dev *bdev)
+{
+ return sdio_readl(bdev->func, MTK_REG_CHCR, NULL);
+}
+
+static int btmtksdio_fw_pmctrl(struct btmtksdio_dev *bdev)
+{
+ u32 status;
+ int err;
+
+ sdio_claim_host(bdev->func);
+
+ if (bdev->data->lp_mbox_supported &&
+ test_bit(BTMTKSDIO_PATCH_ENABLED, &bdev->tx_state)) {
+ sdio_writel(bdev->func, CSICR_CLR_MBOX_ACK, MTK_REG_CSICR,
+ &err);
+ err = readx_poll_timeout(btmtksdio_drv_own_query_79xx, bdev,
+ status, !(status & PD2HRM0R_DRV_OWN),
+ 2000, 1000000);
+ if (err < 0) {
+ bt_dev_err(bdev->hdev, "mailbox ACK not cleared");
+ goto out;
+ }
+ }
+
+ /* Return ownership to the device */
+ sdio_writel(bdev->func, C_FW_OWN_REQ_SET, MTK_REG_CHLPCR, &err);
+ if (err < 0)
+ goto out;
+
+ err = readx_poll_timeout(btmtksdio_drv_own_query, bdev, status,
+ !(status & C_COM_DRV_OWN), 2000, 1000000);
+
+out:
+ sdio_release_host(bdev->func);
+
+ if (err < 0)
+ bt_dev_err(bdev->hdev, "Cannot return ownership to device");
+
+ return err;
+}
+
+static int btmtksdio_drv_pmctrl(struct btmtksdio_dev *bdev)
+{
+ u32 status;
+ int err;
+
+ sdio_claim_host(bdev->func);
+
+ /* Get ownership from the device */
+ sdio_writel(bdev->func, C_FW_OWN_REQ_CLR, MTK_REG_CHLPCR, &err);
+ if (err < 0)
+ goto out;
+
+ err = readx_poll_timeout(btmtksdio_drv_own_query, bdev, status,
+ status & C_COM_DRV_OWN, 2000, 1000000);
+
+ if (!err && bdev->data->lp_mbox_supported &&
+ test_bit(BTMTKSDIO_PATCH_ENABLED, &bdev->tx_state))
+ err = readx_poll_timeout(btmtksdio_drv_own_query_79xx, bdev,
+ status, status & PD2HRM0R_DRV_OWN,
+ 2000, 1000000);
+
+out:
+ sdio_release_host(bdev->func);
+
+ if (err < 0)
+ bt_dev_err(bdev->hdev, "Cannot get ownership from device");
+
+ return err;
+}
+
static int btmtksdio_recv_event(struct hci_dev *hdev, struct sk_buff *skb)
{
struct btmtksdio_dev *bdev = hci_get_drvdata(hdev);
struct hci_event_hdr *hdr = (void *)skb->data;
int err;
- /* Fix up the vendor event id with 0xff for vendor specific instead
- * of 0xe4 so that event send via monitoring socket can be parsed
- * properly.
- */
- if (hdr->evt == 0xe4)
- hdr->evt = HCI_EV_VENDOR;
-
/* When someone waits for the WMT event, the skb is being cloned
* and being processed the events from there then.
*/
@@ -306,7 +396,7 @@ static int btmtksdio_recv_event(struct hci_dev *hdev, struct sk_buff *skb)
if (err < 0)
goto err_free_skb;
- if (hdr->evt == HCI_EV_VENDOR) {
+ if (hdr->evt == HCI_EV_WMT) {
if (test_and_clear_bit(BTMTKSDIO_TX_WAIT_VND_EVT,
&bdev->tx_state)) {
/* Barrier to sync with other CPUs */
@@ -480,6 +570,13 @@ static void btmtksdio_txrx_work(struct work_struct *work)
* FIFO.
*/
sdio_writel(bdev->func, int_status, MTK_REG_CHISR, NULL);
+ int_status &= INT_MASK;
+
+ if ((int_status & FW_MAILBOX_INT) &&
+ bdev->data->chipid == 0x7921) {
+ sdio_writel(bdev->func, PH2DSM0R_DRIVER_OWN,
+ MTK_REG_PH2DSM0R, 0);
+ }
if (int_status & FW_OWN_BACK_INT)
bt_dev_dbg(bdev->hdev, "Get fw own back");
@@ -531,7 +628,7 @@ static void btmtksdio_interrupt(struct sdio_func *func)
static int btmtksdio_open(struct hci_dev *hdev)
{
struct btmtksdio_dev *bdev = hci_get_drvdata(hdev);
- u32 status, val;
+ u32 val;
int err;
sdio_claim_host(bdev->func);
@@ -542,18 +639,10 @@ static int btmtksdio_open(struct hci_dev *hdev)
set_bit(BTMTKSDIO_FUNC_ENABLED, &bdev->tx_state);
- /* Get ownership from the device */
- sdio_writel(bdev->func, C_FW_OWN_REQ_CLR, MTK_REG_CHLPCR, &err);
+ err = btmtksdio_drv_pmctrl(bdev);
if (err < 0)
goto err_disable_func;
- err = readx_poll_timeout(btmtksdio_drv_own_query, bdev, status,
- status & C_COM_DRV_OWN, 2000, 1000000);
- if (err < 0) {
- bt_dev_err(bdev->hdev, "Cannot get ownership from device");
- goto err_disable_func;
- }
-
/* Disable interrupt & mask out all interrupt sources */
sdio_writel(bdev->func, C_INT_EN_CLR, MTK_REG_CHLPCR, &err);
if (err < 0)
@@ -623,8 +712,6 @@ err_release_host:
static int btmtksdio_close(struct hci_dev *hdev)
{
struct btmtksdio_dev *bdev = hci_get_drvdata(hdev);
- u32 status;
- int err;
sdio_claim_host(bdev->func);
@@ -635,13 +722,7 @@ static int btmtksdio_close(struct hci_dev *hdev)
cancel_work_sync(&bdev->txrx_work);
- /* Return ownership to the device */
- sdio_writel(bdev->func, C_FW_OWN_REQ_SET, MTK_REG_CHLPCR, NULL);
-
- err = readx_poll_timeout(btmtksdio_drv_own_query, bdev, status,
- !(status & C_COM_DRV_OWN), 2000, 1000000);
- if (err < 0)
- bt_dev_err(bdev->hdev, "Cannot return ownership to device");
+ btmtksdio_fw_pmctrl(bdev);
clear_bit(BTMTKSDIO_FUNC_ENABLED, &bdev->tx_state);
sdio_disable_func(bdev->func);
@@ -686,6 +767,7 @@ static int btmtksdio_func_query(struct hci_dev *hdev)
static int mt76xx_setup(struct hci_dev *hdev, const char *fwname)
{
+ struct btmtksdio_dev *bdev = hci_get_drvdata(hdev);
struct btmtk_hci_wmt_params wmt_params;
struct btmtk_tci_sleep tci_sleep;
struct sk_buff *skb;
@@ -746,6 +828,8 @@ ignore_setup_fw:
return err;
}
+ set_bit(BTMTKSDIO_PATCH_ENABLED, &bdev->tx_state);
+
ignore_func_on:
/* Apply the low power environment setup */
tci_sleep.mode = 0x5;
@@ -768,6 +852,7 @@ ignore_func_on:
static int mt79xx_setup(struct hci_dev *hdev, const char *fwname)
{
+ struct btmtksdio_dev *bdev = hci_get_drvdata(hdev);
struct btmtk_hci_wmt_params wmt_params;
u8 param = 0x1;
int err;
@@ -793,19 +878,15 @@ static int mt79xx_setup(struct hci_dev *hdev, const char *fwname)
hci_set_msft_opcode(hdev, 0xFD30);
hci_set_aosp_capable(hdev);
+ set_bit(BTMTKSDIO_PATCH_ENABLED, &bdev->tx_state);
return err;
}
-static int btsdio_mtk_reg_read(struct hci_dev *hdev, u32 reg, u32 *val)
+static int btmtksdio_mtk_reg_read(struct hci_dev *hdev, u32 reg, u32 *val)
{
struct btmtk_hci_wmt_params wmt_params;
- struct reg_read_cmd {
- u8 type;
- u8 rsv;
- u8 num;
- __le32 addr;
- } __packed reg_read = {
+ struct reg_read_cmd reg_read = {
.type = 1,
.num = 1,
};
@@ -821,7 +902,7 @@ static int btsdio_mtk_reg_read(struct hci_dev *hdev, u32 reg, u32 *val)
err = mtk_hci_wmt_sync(hdev, &wmt_params);
if (err < 0) {
- bt_dev_err(hdev, "Failed to read reg(%d)", err);
+ bt_dev_err(hdev, "Failed to read reg (%d)", err);
return err;
}
@@ -830,6 +911,151 @@ static int btsdio_mtk_reg_read(struct hci_dev *hdev, u32 reg, u32 *val)
return err;
}
+static int btmtksdio_mtk_reg_write(struct hci_dev *hdev, u32 reg, u32 val, u32 mask)
+{
+ struct btmtk_hci_wmt_params wmt_params;
+ const struct reg_write_cmd reg_write = {
+ .type = 1,
+ .num = 1,
+ .addr = cpu_to_le32(reg),
+ .data = cpu_to_le32(val),
+ .mask = cpu_to_le32(mask),
+ };
+ int err, status;
+
+ wmt_params.op = BTMTK_WMT_REGISTER;
+ wmt_params.flag = BTMTK_WMT_REG_WRITE;
+ wmt_params.dlen = sizeof(reg_write);
+ wmt_params.data = &reg_write;
+ wmt_params.status = &status;
+
+ err = mtk_hci_wmt_sync(hdev, &wmt_params);
+ if (err < 0)
+ bt_dev_err(hdev, "Failed to write reg (%d)", err);
+
+ return err;
+}
+
+static int btmtksdio_get_data_path_id(struct hci_dev *hdev, __u8 *data_path_id)
+{
+ /* uses 1 as data path id for all the usecases */
+ *data_path_id = 1;
+ return 0;
+}
+
+static int btmtksdio_get_codec_config_data(struct hci_dev *hdev,
+ __u8 link, struct bt_codec *codec,
+ __u8 *ven_len, __u8 **ven_data)
+{
+ int err = 0;
+
+ if (!ven_data || !ven_len)
+ return -EINVAL;
+
+ *ven_len = 0;
+ *ven_data = NULL;
+
+ if (link != ESCO_LINK) {
+ bt_dev_err(hdev, "Invalid link type(%u)", link);
+ return -EINVAL;
+ }
+
+ *ven_data = kmalloc(sizeof(__u8), GFP_KERNEL);
+ if (!ven_data) {
+ err = -ENOMEM;
+ goto error;
+ }
+
+ /* supports only CVSD and mSBC offload codecs */
+ switch (codec->id) {
+ case 0x02:
+ **ven_data = 0x00;
+ break;
+ case 0x05:
+ **ven_data = 0x01;
+ break;
+ default:
+ err = -EINVAL;
+ bt_dev_err(hdev, "Invalid codec id(%u)", codec->id);
+ goto error;
+ }
+ /* codec and its capabilities are pre-defined to ids
+ * preset id = 0x00 represents CVSD codec with sampling rate 8K
+ * preset id = 0x01 represents mSBC codec with sampling rate 16K
+ */
+ *ven_len = sizeof(__u8);
+ return err;
+
+error:
+ kfree(*ven_data);
+ *ven_data = NULL;
+ return err;
+}
+
+static int btmtksdio_sco_setting(struct hci_dev *hdev)
+{
+ const struct btmtk_sco sco_setting = {
+ .clock_config = 0x49,
+ .channel_format_config = 0x80,
+ };
+ struct sk_buff *skb;
+ u32 val;
+ int err;
+
+ /* Enable SCO over I2S/PCM for MediaTek chipset */
+ skb = __hci_cmd_sync(hdev, 0xfc72, sizeof(sco_setting),
+ &sco_setting, HCI_CMD_TIMEOUT);
+ if (IS_ERR(skb))
+ return PTR_ERR(skb);
+
+ kfree_skb(skb);
+
+ err = btmtksdio_mtk_reg_read(hdev, MT7921_PINMUX_0, &val);
+ if (err < 0)
+ return err;
+
+ val |= 0x11000000;
+ err = btmtksdio_mtk_reg_write(hdev, MT7921_PINMUX_0, val, ~0);
+ if (err < 0)
+ return err;
+
+ err = btmtksdio_mtk_reg_read(hdev, MT7921_PINMUX_1, &val);
+ if (err < 0)
+ return err;
+
+ val |= 0x00000101;
+ err = btmtksdio_mtk_reg_write(hdev, MT7921_PINMUX_1, val, ~0);
+ if (err < 0)
+ return err;
+
+ hdev->get_data_path_id = btmtksdio_get_data_path_id;
+ hdev->get_codec_config_data = btmtksdio_get_codec_config_data;
+
+ return err;
+}
+
+static int btmtksdio_reset_setting(struct hci_dev *hdev)
+{
+ int err;
+ u32 val;
+
+ err = btmtksdio_mtk_reg_read(hdev, MT7921_PINMUX_1, &val);
+ if (err < 0)
+ return err;
+
+ val |= 0x20; /* set the pin (bit field 11:8) work as GPIO mode */
+ err = btmtksdio_mtk_reg_write(hdev, MT7921_PINMUX_1, val, ~0);
+ if (err < 0)
+ return err;
+
+ err = btmtksdio_mtk_reg_read(hdev, MT7921_BTSYS_RST, &val);
+ if (err < 0)
+ return err;
+
+ val |= MT7921_BTSYS_RST_WITH_GPIO;
+ return btmtksdio_mtk_reg_write(hdev, MT7921_BTSYS_RST, val, ~0);
+}
+
static int btmtksdio_setup(struct hci_dev *hdev)
{
struct btmtksdio_dev *bdev = hci_get_drvdata(hdev);
@@ -837,20 +1063,39 @@ static int btmtksdio_setup(struct hci_dev *hdev)
unsigned long long duration;
char fwname[64];
int err, dev_id;
- u32 fw_version = 0;
+ u32 fw_version = 0, val;
calltime = ktime_get();
set_bit(BTMTKSDIO_HW_TX_READY, &bdev->tx_state);
switch (bdev->data->chipid) {
case 0x7921:
- err = btsdio_mtk_reg_read(hdev, 0x70010200, &dev_id);
+ if (test_bit(BTMTKSDIO_HW_RESET_ACTIVE, &bdev->tx_state)) {
+ err = btmtksdio_mtk_reg_read(hdev, MT7921_DLSTATUS,
+ &val);
+ if (err < 0)
+ return err;
+
+ val &= ~BT_DL_STATE;
+ err = btmtksdio_mtk_reg_write(hdev, MT7921_DLSTATUS,
+ val, ~0);
+ if (err < 0)
+ return err;
+
+ btmtksdio_fw_pmctrl(bdev);
+ msleep(20);
+ btmtksdio_drv_pmctrl(bdev);
+
+ clear_bit(BTMTKSDIO_HW_RESET_ACTIVE, &bdev->tx_state);
+ }
+
+ err = btmtksdio_mtk_reg_read(hdev, 0x70010200, &dev_id);
if (err < 0) {
bt_dev_err(hdev, "Failed to get device id (%d)", err);
return err;
}
- err = btsdio_mtk_reg_read(hdev, 0x80021004, &fw_version);
+ err = btmtksdio_mtk_reg_read(hdev, 0x80021004, &fw_version);
if (err < 0) {
bt_dev_err(hdev, "Failed to get fw version (%d)", err);
return err;
@@ -862,6 +1107,38 @@ static int btmtksdio_setup(struct hci_dev *hdev)
err = mt79xx_setup(hdev, fwname);
if (err < 0)
return err;
+
+ err = btmtksdio_fw_pmctrl(bdev);
+ if (err < 0)
+ return err;
+
+ err = btmtksdio_drv_pmctrl(bdev);
+ if (err < 0)
+ return err;
+
+ /* Enable SCO over I2S/PCM */
+ err = btmtksdio_sco_setting(hdev);
+ if (err < 0) {
+ bt_dev_err(hdev, "Failed to enable SCO setting (%d)", err);
+ return err;
+ }
+
+ /* Enable WBS with mSBC codec */
+ set_bit(HCI_QUIRK_WIDEBAND_SPEECH_SUPPORTED, &hdev->quirks);
+
+ /* Enable GPIO reset mechanism */
+ if (bdev->reset) {
+ err = btmtksdio_reset_setting(hdev);
+ if (err < 0) {
+ bt_dev_err(hdev, "Failed to enable Reset setting (%d)", err);
+ devm_gpiod_put(bdev->dev, bdev->reset);
+ bdev->reset = NULL;
+ }
+ }
+
+ /* Valid LE States quirk for MediaTek 7921 */
+ set_bit(HCI_QUIRK_VALID_LE_STATES, &hdev->quirks);
+
break;
case 0x7663:
case 0x7668:
@@ -958,6 +1235,73 @@ static int btmtksdio_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
return 0;
}
+static void btmtksdio_cmd_timeout(struct hci_dev *hdev)
+{
+ struct btmtksdio_dev *bdev = hci_get_drvdata(hdev);
+ u32 status;
+ int err;
+
+ if (!bdev->reset || bdev->data->chipid != 0x7921)
+ return;
+
+ pm_runtime_get_sync(bdev->dev);
+
+ if (test_and_set_bit(BTMTKSDIO_HW_RESET_ACTIVE, &bdev->tx_state))
+ return;
+
+ sdio_claim_host(bdev->func);
+
+ sdio_writel(bdev->func, C_INT_EN_CLR, MTK_REG_CHLPCR, NULL);
+ skb_queue_purge(&bdev->txq);
+ cancel_work_sync(&bdev->txrx_work);
+
+ gpiod_set_value_cansleep(bdev->reset, 1);
+ msleep(100);
+ gpiod_set_value_cansleep(bdev->reset, 0);
+
+ err = readx_poll_timeout(btmtksdio_chcr_query, bdev, status,
+ status & BT_RST_DONE, 100000, 2000000);
+ if (err < 0) {
+ bt_dev_err(hdev, "Failed to reset (%d)", err);
+ goto err;
+ }
+
+ clear_bit(BTMTKSDIO_PATCH_ENABLED, &bdev->tx_state);
+err:
+ sdio_release_host(bdev->func);
+
+ pm_runtime_put_noidle(bdev->dev);
+ pm_runtime_disable(bdev->dev);
+
+ hci_reset_dev(hdev);
+}
+
+static bool btmtksdio_sdio_wakeup(struct hci_dev *hdev)
+{
+ struct btmtksdio_dev *bdev = hci_get_drvdata(hdev);
+ bool may_wakeup = device_may_wakeup(bdev->dev);
+ const struct btmtk_wakeon bt_awake = {
+ .mode = 0x1,
+ .gpo = 0,
+ .active_high = 0x1,
+ .enable_delay = cpu_to_le16(0xc80),
+ .wakeup_delay = cpu_to_le16(0x20),
+ };
+
+ if (may_wakeup && bdev->data->chipid == 0x7921) {
+ struct sk_buff *skb;
+
+ skb = __hci_cmd_sync(hdev, 0xfc27, sizeof(bt_awake),
+ &bt_awake, HCI_CMD_TIMEOUT);
+ if (IS_ERR(skb))
+ may_wakeup = false;
+ else
+ kfree_skb(skb);
+ }
+
+ return may_wakeup;
+}
+
static int btmtksdio_probe(struct sdio_func *func,
const struct sdio_device_id *id)
{
@@ -993,10 +1337,12 @@ static int btmtksdio_probe(struct sdio_func *func,
hdev->open = btmtksdio_open;
hdev->close = btmtksdio_close;
+ hdev->cmd_timeout = btmtksdio_cmd_timeout;
hdev->flush = btmtksdio_flush;
hdev->setup = btmtksdio_setup;
hdev->shutdown = btmtksdio_shutdown;
hdev->send = btmtksdio_send_frame;
+ hdev->wakeup = btmtksdio_sdio_wakeup;
hdev->set_bdaddr = btmtk_set_bdaddr;
SET_HCIDEV_DEV(hdev, &func->dev);
@@ -1004,6 +1350,8 @@ static int btmtksdio_probe(struct sdio_func *func,
hdev->manufacturer = 70;
set_bit(HCI_QUIRK_NON_PERSISTENT_SETUP, &hdev->quirks);
+ sdio_set_drvdata(func, bdev);
+
err = hci_register_dev(hdev);
if (err < 0) {
dev_err(&func->dev, "Can't register HCI device\n");
@@ -1011,8 +1359,6 @@ static int btmtksdio_probe(struct sdio_func *func,
return err;
}
- sdio_set_drvdata(func, bdev);
-
/* pm_runtime_enable would be done after the firmware is being
* downloaded because the core layer probably already enables
* runtime PM for this func such as the case host->caps &
@@ -1032,7 +1378,18 @@ static int btmtksdio_probe(struct sdio_func *func,
*/
pm_runtime_put_noidle(bdev->dev);
- return 0;
+ err = device_init_wakeup(bdev->dev, true);
+ if (err)
+ bt_dev_err(hdev, "failed to initialize device wakeup");
+
+ bdev->dev->of_node = of_find_compatible_node(NULL, NULL,
+ "mediatek,mt7921s-bluetooth");
+ bdev->reset = devm_gpiod_get_optional(bdev->dev, "reset",
+ GPIOD_OUT_LOW);
+ if (IS_ERR(bdev->reset))
+ err = PTR_ERR(bdev->reset);
+
+ return err;
}
static void btmtksdio_remove(struct sdio_func *func)
@@ -1058,7 +1415,6 @@ static int btmtksdio_runtime_suspend(struct device *dev)
{
struct sdio_func *func = dev_to_sdio_func(dev);
struct btmtksdio_dev *bdev;
- u32 status;
int err;
bdev = sdio_get_drvdata(func);
@@ -1070,18 +1426,9 @@ static int btmtksdio_runtime_suspend(struct device *dev)
sdio_set_host_pm_flags(func, MMC_PM_KEEP_POWER);
- sdio_claim_host(bdev->func);
-
- sdio_writel(bdev->func, C_FW_OWN_REQ_SET, MTK_REG_CHLPCR, &err);
- if (err < 0)
- goto out;
-
- err = readx_poll_timeout(btmtksdio_drv_own_query, bdev, status,
- !(status & C_COM_DRV_OWN), 2000, 1000000);
-out:
- bt_dev_info(bdev->hdev, "status (%d) return ownership to device", err);
+ err = btmtksdio_fw_pmctrl(bdev);
- sdio_release_host(bdev->func);
+ bt_dev_dbg(bdev->hdev, "status (%d) return ownership to device", err);
return err;
}
@@ -1090,7 +1437,6 @@ static int btmtksdio_runtime_resume(struct device *dev)
{
struct sdio_func *func = dev_to_sdio_func(dev);
struct btmtksdio_dev *bdev;
- u32 status;
int err;
bdev = sdio_get_drvdata(func);
@@ -1100,18 +1446,9 @@ static int btmtksdio_runtime_resume(struct device *dev)
if (!test_bit(BTMTKSDIO_FUNC_ENABLED, &bdev->tx_state))
return 0;
- sdio_claim_host(bdev->func);
+ err = btmtksdio_drv_pmctrl(bdev);
- sdio_writel(bdev->func, C_FW_OWN_REQ_CLR, MTK_REG_CHLPCR, &err);
- if (err < 0)
- goto out;
-
- err = readx_poll_timeout(btmtksdio_drv_own_query, bdev, status,
- status & C_COM_DRV_OWN, 2000, 1000000);
-out:
- bt_dev_info(bdev->hdev, "status (%d) get ownership from device", err);
-
- sdio_release_host(bdev->func);
+ bt_dev_dbg(bdev->hdev, "status (%d) get ownership from device", err);
return err;
}
diff --git a/drivers/bluetooth/btmtkuart.c b/drivers/bluetooth/btmtkuart.c
index 9ba22b13b4fa..c98691cdbbd5 100644
--- a/drivers/bluetooth/btmtkuart.c
+++ b/drivers/bluetooth/btmtkuart.c
@@ -28,13 +28,10 @@
#include <net/bluetooth/hci_core.h>
#include "h4_recv.h"
+#include "btmtk.h"
#define VERSION "0.2"
-#define FIRMWARE_MT7622 "mediatek/mt7622pr2h.bin"
-#define FIRMWARE_MT7663 "mediatek/mt7663pr2h.bin"
-#define FIRMWARE_MT7668 "mediatek/mt7668pr2h.bin"
-
#define MTK_STP_TLR_SIZE 2
#define BTMTKUART_TX_STATE_ACTIVE 1
@@ -44,25 +41,6 @@
#define BTMTKUART_FLAG_STANDALONE_HW BIT(0)
-enum {
- MTK_WMT_PATCH_DWNLD = 0x1,
- MTK_WMT_TEST = 0x2,
- MTK_WMT_WAKEUP = 0x3,
- MTK_WMT_HIF = 0x4,
- MTK_WMT_FUNC_CTRL = 0x6,
- MTK_WMT_RST = 0x7,
- MTK_WMT_SEMAPHORE = 0x17,
-};
-
-enum {
- BTMTK_WMT_INVALID,
- BTMTK_WMT_PATCH_UNDONE,
- BTMTK_WMT_PATCH_DONE,
- BTMTK_WMT_ON_UNDONE,
- BTMTK_WMT_ON_DONE,
- BTMTK_WMT_ON_PROGRESS,
-};
-
struct mtk_stp_hdr {
u8 prefix;
__be16 dlen;
@@ -74,44 +52,6 @@ struct btmtkuart_data {
const char *fwname;
};
-struct mtk_wmt_hdr {
- u8 dir;
- u8 op;
- __le16 dlen;
- u8 flag;
-} __packed;
-
-struct mtk_hci_wmt_cmd {
- struct mtk_wmt_hdr hdr;
- u8 data[256];
-} __packed;
-
-struct btmtk_hci_wmt_evt {
- struct hci_event_hdr hhdr;
- struct mtk_wmt_hdr whdr;
-} __packed;
-
-struct btmtk_hci_wmt_evt_funcc {
- struct btmtk_hci_wmt_evt hwhdr;
- __be16 status;
-} __packed;
-
-struct btmtk_tci_sleep {
- u8 mode;
- __le16 duration;
- __le16 host_duration;
- u8 host_wakeup_pin;
- u8 time_compensation;
-} __packed;
-
-struct btmtk_hci_wmt_params {
- u8 op;
- u8 flag;
- u16 dlen;
- const void *data;
- u32 *status;
-};
-
struct btmtkuart_dev {
struct hci_dev *hdev;
struct serdev_device *serdev;
@@ -153,29 +93,36 @@ static int mtk_hci_wmt_sync(struct hci_dev *hdev,
struct btmtk_hci_wmt_evt_funcc *wmt_evt_funcc;
u32 hlen, status = BTMTK_WMT_INVALID;
struct btmtk_hci_wmt_evt *wmt_evt;
- struct mtk_hci_wmt_cmd wc;
- struct mtk_wmt_hdr *hdr;
+ struct btmtk_hci_wmt_cmd *wc;
+ struct btmtk_wmt_hdr *hdr;
int err;
+ /* Send the WMT command and wait until the WMT event returns */
hlen = sizeof(*hdr) + wmt_params->dlen;
if (hlen > 255) {
err = -EINVAL;
goto err_free_skb;
}
- hdr = (struct mtk_wmt_hdr *)&wc;
+ wc = kzalloc(hlen, GFP_KERNEL);
+ if (!wc) {
+ err = -ENOMEM;
+ goto err_free_skb;
+ }
+
+ hdr = &wc->hdr;
hdr->dir = 1;
hdr->op = wmt_params->op;
hdr->dlen = cpu_to_le16(wmt_params->dlen + 1);
hdr->flag = wmt_params->flag;
- memcpy(wc.data, wmt_params->data, wmt_params->dlen);
+ memcpy(wc->data, wmt_params->data, wmt_params->dlen);
set_bit(BTMTKUART_TX_WAIT_VND_EVT, &bdev->tx_state);
- err = __hci_cmd_send(hdev, 0xfc6f, hlen, &wc);
+ err = __hci_cmd_send(hdev, 0xfc6f, hlen, wc);
if (err < 0) {
clear_bit(BTMTKUART_TX_WAIT_VND_EVT, &bdev->tx_state);
- goto err_free_skb;
+ goto err_free_wc;
}
/* The vendor specific WMT commands are all answered by a vendor
@@ -192,14 +139,14 @@ static int mtk_hci_wmt_sync(struct hci_dev *hdev,
if (err == -EINTR) {
bt_dev_err(hdev, "Execution of wmt command interrupted");
clear_bit(BTMTKUART_TX_WAIT_VND_EVT, &bdev->tx_state);
- goto err_free_skb;
+ goto err_free_wc;
}
if (err) {
bt_dev_err(hdev, "Execution of wmt command timed out");
clear_bit(BTMTKUART_TX_WAIT_VND_EVT, &bdev->tx_state);
err = -ETIMEDOUT;
- goto err_free_skb;
+ goto err_free_wc;
}
/* Parse and handle the return WMT event */
@@ -208,17 +155,17 @@ static int mtk_hci_wmt_sync(struct hci_dev *hdev,
bt_dev_err(hdev, "Wrong op received %d expected %d",
wmt_evt->whdr.op, hdr->op);
err = -EIO;
- goto err_free_skb;
+ goto err_free_wc;
}
switch (wmt_evt->whdr.op) {
- case MTK_WMT_SEMAPHORE:
+ case BTMTK_WMT_SEMAPHORE:
if (wmt_evt->whdr.flag == 2)
status = BTMTK_WMT_PATCH_UNDONE;
else
status = BTMTK_WMT_PATCH_DONE;
break;
- case MTK_WMT_FUNC_CTRL:
+ case BTMTK_WMT_FUNC_CTRL:
wmt_evt_funcc = (struct btmtk_hci_wmt_evt_funcc *)wmt_evt;
if (be16_to_cpu(wmt_evt_funcc->status) == 0x404)
status = BTMTK_WMT_ON_DONE;
@@ -232,6 +179,8 @@ static int mtk_hci_wmt_sync(struct hci_dev *hdev,
if (wmt_params->status)
*wmt_params->status = status;
+err_free_wc:
+ kfree(wc);
err_free_skb:
kfree_skb(bdev->evt_skb);
bdev->evt_skb = NULL;
@@ -239,95 +188,12 @@ err_free_skb:
return err;
}
-static int mtk_setup_firmware(struct hci_dev *hdev, const char *fwname)
-{
- struct btmtk_hci_wmt_params wmt_params;
- const struct firmware *fw;
- const u8 *fw_ptr;
- size_t fw_size;
- int err, dlen;
- u8 flag;
-
- err = request_firmware(&fw, fwname, &hdev->dev);
- if (err < 0) {
- bt_dev_err(hdev, "Failed to load firmware file (%d)", err);
- return err;
- }
-
- fw_ptr = fw->data;
- fw_size = fw->size;
-
- /* The size of patch header is 30 bytes, should be skip */
- if (fw_size < 30) {
- err = -EINVAL;
- goto free_fw;
- }
-
- fw_size -= 30;
- fw_ptr += 30;
- flag = 1;
-
- wmt_params.op = MTK_WMT_PATCH_DWNLD;
- wmt_params.status = NULL;
-
- while (fw_size > 0) {
- dlen = min_t(int, 250, fw_size);
-
- /* Tell device the position in sequence */
- if (fw_size - dlen <= 0)
- flag = 3;
- else if (fw_size < fw->size - 30)
- flag = 2;
-
- wmt_params.flag = flag;
- wmt_params.dlen = dlen;
- wmt_params.data = fw_ptr;
-
- err = mtk_hci_wmt_sync(hdev, &wmt_params);
- if (err < 0) {
- bt_dev_err(hdev, "Failed to send wmt patch dwnld (%d)",
- err);
- goto free_fw;
- }
-
- fw_size -= dlen;
- fw_ptr += dlen;
- }
-
- wmt_params.op = MTK_WMT_RST;
- wmt_params.flag = 4;
- wmt_params.dlen = 0;
- wmt_params.data = NULL;
- wmt_params.status = NULL;
-
- /* Activate funciton the firmware providing to */
- err = mtk_hci_wmt_sync(hdev, &wmt_params);
- if (err < 0) {
- bt_dev_err(hdev, "Failed to send wmt rst (%d)", err);
- goto free_fw;
- }
-
- /* Wait a few moments for firmware activation done */
- usleep_range(10000, 12000);
-
-free_fw:
- release_firmware(fw);
- return err;
-}
-
static int btmtkuart_recv_event(struct hci_dev *hdev, struct sk_buff *skb)
{
struct btmtkuart_dev *bdev = hci_get_drvdata(hdev);
struct hci_event_hdr *hdr = (void *)skb->data;
int err;
- /* Fix up the vendor event id with 0xff for vendor specific instead
- * of 0xe4 so that event send via monitoring socket can be parsed
- * properly.
- */
- if (hdr->evt == 0xe4)
- hdr->evt = HCI_EV_VENDOR;
-
/* When someone waits for the WMT event, the skb is being cloned
* and being processed the events from there then.
*/
@@ -343,7 +209,7 @@ static int btmtkuart_recv_event(struct hci_dev *hdev, struct sk_buff *skb)
if (err < 0)
goto err_free_skb;
- if (hdr->evt == HCI_EV_VENDOR) {
+ if (hdr->evt == HCI_EV_WMT) {
if (test_and_clear_bit(BTMTKUART_TX_WAIT_VND_EVT,
&bdev->tx_state)) {
/* Barrier to sync with other CPUs */
@@ -645,7 +511,7 @@ static int btmtkuart_func_query(struct hci_dev *hdev)
u8 param = 0;
/* Query whether the function is enabled */
- wmt_params.op = MTK_WMT_FUNC_CTRL;
+ wmt_params.op = BTMTK_WMT_FUNC_CTRL;
wmt_params.flag = 4;
wmt_params.dlen = sizeof(param);
wmt_params.data = &param;
@@ -672,7 +538,7 @@ static int btmtkuart_change_baudrate(struct hci_dev *hdev)
* ready to change a new baudrate.
*/
baudrate = cpu_to_le32(bdev->desired_speed);
- wmt_params.op = MTK_WMT_HIF;
+ wmt_params.op = BTMTK_WMT_HIF;
wmt_params.flag = 1;
wmt_params.dlen = 4;
wmt_params.data = &baudrate;
@@ -706,7 +572,7 @@ static int btmtkuart_change_baudrate(struct hci_dev *hdev)
usleep_range(20000, 22000);
/* Test the new baudrate */
- wmt_params.op = MTK_WMT_TEST;
+ wmt_params.op = BTMTK_WMT_TEST;
wmt_params.flag = 7;
wmt_params.dlen = 0;
wmt_params.data = NULL;
@@ -741,7 +607,7 @@ static int btmtkuart_setup(struct hci_dev *hdev)
* do any setups.
*/
if (test_bit(BTMTKUART_REQUIRED_WAKEUP, &bdev->tx_state)) {
- wmt_params.op = MTK_WMT_WAKEUP;
+ wmt_params.op = BTMTK_WMT_WAKEUP;
wmt_params.flag = 3;
wmt_params.dlen = 0;
wmt_params.data = NULL;
@@ -760,7 +626,7 @@ static int btmtkuart_setup(struct hci_dev *hdev)
btmtkuart_change_baudrate(hdev);
/* Query whether the firmware is already download */
- wmt_params.op = MTK_WMT_SEMAPHORE;
+ wmt_params.op = BTMTK_WMT_SEMAPHORE;
wmt_params.flag = 1;
wmt_params.dlen = 0;
wmt_params.data = NULL;
@@ -778,7 +644,7 @@ static int btmtkuart_setup(struct hci_dev *hdev)
}
/* Setup a firmware which the device definitely requires */
- err = mtk_setup_firmware(hdev, bdev->data->fwname);
+ err = btmtk_setup_firmware(hdev, bdev->data->fwname, mtk_hci_wmt_sync);
if (err < 0)
return err;
@@ -801,7 +667,7 @@ ignore_setup_fw:
}
/* Enable Bluetooth protocol */
- wmt_params.op = MTK_WMT_FUNC_CTRL;
+ wmt_params.op = BTMTK_WMT_FUNC_CTRL;
wmt_params.flag = 0;
wmt_params.dlen = sizeof(param);
wmt_params.data = &param;
@@ -846,7 +712,7 @@ static int btmtkuart_shutdown(struct hci_dev *hdev)
int err;
/* Disable the device */
- wmt_params.op = MTK_WMT_FUNC_CTRL;
+ wmt_params.op = BTMTK_WMT_FUNC_CTRL;
wmt_params.flag = 0;
wmt_params.dlen = sizeof(param);
wmt_params.data = &param;
@@ -1007,6 +873,7 @@ static int btmtkuart_probe(struct serdev_device *serdev)
hdev->setup = btmtkuart_setup;
hdev->shutdown = btmtkuart_shutdown;
hdev->send = btmtkuart_send_frame;
+ hdev->set_bdaddr = btmtk_set_bdaddr;
SET_HCIDEV_DEV(hdev, &serdev->dev);
hdev->manufacturer = 70;
@@ -1131,6 +998,3 @@ MODULE_AUTHOR("Sean Wang <sean.wang@mediatek.com>");
MODULE_DESCRIPTION("MediaTek Bluetooth Serial driver ver " VERSION);
MODULE_VERSION(VERSION);
MODULE_LICENSE("GPL");
-MODULE_FIRMWARE(FIRMWARE_MT7622);
-MODULE_FIRMWARE(FIRMWARE_MT7663);
-MODULE_FIRMWARE(FIRMWARE_MT7668);
diff --git a/drivers/bluetooth/btrtl.c b/drivers/bluetooth/btrtl.c
index c2bdd1e6060e..481d488bca0f 100644
--- a/drivers/bluetooth/btrtl.c
+++ b/drivers/bluetooth/btrtl.c
@@ -49,6 +49,7 @@ enum btrtl_chip_id {
CHIP_ID_8822C = 13,
CHIP_ID_8761B,
CHIP_ID_8852A = 18,
+ CHIP_ID_8852B = 20,
};
struct id_table {
@@ -149,6 +150,14 @@ static const struct id_table ic_id_table[] = {
.cfg_name = "rtl_bt/rtl8761bu_config" },
/* 8822C with UART interface */
+ { IC_INFO(RTL_ROM_LMP_8822B, 0xc, 0x8, HCI_UART),
+ .config_needed = true,
+ .has_rom_version = true,
+ .has_msft_ext = true,
+ .fw_name = "rtl_bt/rtl8822cs_fw.bin",
+ .cfg_name = "rtl_bt/rtl8822cs_config" },
+
+ /* 8822C with UART interface */
{ IC_INFO(RTL_ROM_LMP_8822B, 0xc, 0xa, HCI_UART),
.config_needed = true,
.has_rom_version = true,
@@ -179,6 +188,14 @@ static const struct id_table ic_id_table[] = {
.has_msft_ext = true,
.fw_name = "rtl_bt/rtl8852au_fw.bin",
.cfg_name = "rtl_bt/rtl8852au_config" },
+
+ /* 8852B */
+ { IC_INFO(RTL_ROM_LMP_8852A, 0xb, 0xb, HCI_USB),
+ .config_needed = false,
+ .has_rom_version = true,
+ .has_msft_ext = true,
+ .fw_name = "rtl_bt/rtl8852bu_fw.bin",
+ .cfg_name = "rtl_bt/rtl8852bu_config" },
};
static const struct id_table *btrtl_match_ic(u16 lmp_subver, u16 hci_rev,
@@ -287,6 +304,7 @@ static int rtlbt_parse_firmware(struct hci_dev *hdev,
{ RTL_ROM_LMP_8822B, 13 }, /* 8822C */
{ RTL_ROM_LMP_8761A, 14 }, /* 8761B */
{ RTL_ROM_LMP_8852A, 18 }, /* 8852A */
+ { RTL_ROM_LMP_8852A, 20 }, /* 8852B */
};
min_size = sizeof(struct rtl_epatch_header) + sizeof(extension_sig) + 3;
@@ -749,6 +767,7 @@ void btrtl_set_quirks(struct hci_dev *hdev, struct btrtl_device_info *btrtl_dev)
switch (btrtl_dev->project_id) {
case CHIP_ID_8822C:
case CHIP_ID_8852A:
+ case CHIP_ID_8852B:
set_bit(HCI_QUIRK_VALID_LE_STATES, &hdev->quirks);
set_bit(HCI_QUIRK_WIDEBAND_SPEECH_SUPPORTED, &hdev->quirks);
hci_set_aosp_capable(hdev);
@@ -926,3 +945,5 @@ MODULE_FIRMWARE("rtl_bt/rtl8822b_fw.bin");
MODULE_FIRMWARE("rtl_bt/rtl8822b_config.bin");
MODULE_FIRMWARE("rtl_bt/rtl8852au_fw.bin");
MODULE_FIRMWARE("rtl_bt/rtl8852au_config.bin");
+MODULE_FIRMWARE("rtl_bt/rtl8852bu_fw.bin");
+MODULE_FIRMWARE("rtl_bt/rtl8852bu_config.bin");
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
index c30d131da784..50df417207af 100644
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@ -36,32 +36,33 @@ static bool reset = true;
static struct usb_driver btusb_driver;
-#define BTUSB_IGNORE 0x01
-#define BTUSB_DIGIANSWER 0x02
-#define BTUSB_CSR 0x04
-#define BTUSB_SNIFFER 0x08
-#define BTUSB_BCM92035 0x10
-#define BTUSB_BROKEN_ISOC 0x20
-#define BTUSB_WRONG_SCO_MTU 0x40
-#define BTUSB_ATH3012 0x80
-#define BTUSB_INTEL_COMBINED 0x100
-#define BTUSB_INTEL_BOOT 0x200
-#define BTUSB_BCM_PATCHRAM 0x400
-#define BTUSB_MARVELL 0x800
-#define BTUSB_SWAVE 0x1000
-#define BTUSB_AMP 0x4000
-#define BTUSB_QCA_ROME 0x8000
-#define BTUSB_BCM_APPLE 0x10000
-#define BTUSB_REALTEK 0x20000
-#define BTUSB_BCM2045 0x40000
-#define BTUSB_IFNUM_2 0x80000
-#define BTUSB_CW6622 0x100000
-#define BTUSB_MEDIATEK 0x200000
-#define BTUSB_WIDEBAND_SPEECH 0x400000
-#define BTUSB_VALID_LE_STATES 0x800000
-#define BTUSB_QCA_WCN6855 0x1000000
-#define BTUSB_INTEL_BROKEN_SHUTDOWN_LED 0x2000000
-#define BTUSB_INTEL_BROKEN_INITIAL_NCMD 0x4000000
+#define BTUSB_IGNORE BIT(0)
+#define BTUSB_DIGIANSWER BIT(1)
+#define BTUSB_CSR BIT(2)
+#define BTUSB_SNIFFER BIT(3)
+#define BTUSB_BCM92035 BIT(4)
+#define BTUSB_BROKEN_ISOC BIT(5)
+#define BTUSB_WRONG_SCO_MTU BIT(6)
+#define BTUSB_ATH3012 BIT(7)
+#define BTUSB_INTEL_COMBINED BIT(8)
+#define BTUSB_INTEL_BOOT BIT(9)
+#define BTUSB_BCM_PATCHRAM BIT(10)
+#define BTUSB_MARVELL BIT(11)
+#define BTUSB_SWAVE BIT(12)
+#define BTUSB_AMP BIT(13)
+#define BTUSB_QCA_ROME BIT(14)
+#define BTUSB_BCM_APPLE BIT(15)
+#define BTUSB_REALTEK BIT(16)
+#define BTUSB_BCM2045 BIT(17)
+#define BTUSB_IFNUM_2 BIT(18)
+#define BTUSB_CW6622 BIT(19)
+#define BTUSB_MEDIATEK BIT(20)
+#define BTUSB_WIDEBAND_SPEECH BIT(21)
+#define BTUSB_VALID_LE_STATES BIT(22)
+#define BTUSB_QCA_WCN6855 BIT(23)
+#define BTUSB_INTEL_BROKEN_SHUTDOWN_LED BIT(24)
+#define BTUSB_INTEL_BROKEN_INITIAL_NCMD BIT(25)
+#define BTUSB_INTEL_NO_WBS_SUPPORT BIT(26)
static const struct usb_device_id btusb_table[] = {
/* Generic Bluetooth USB device */
@@ -383,11 +384,14 @@ static const struct usb_device_id blacklist_table[] = {
{ USB_DEVICE(0x8087, 0x0029), .driver_info = BTUSB_INTEL_COMBINED },
{ USB_DEVICE(0x8087, 0x0032), .driver_info = BTUSB_INTEL_COMBINED },
{ USB_DEVICE(0x8087, 0x0033), .driver_info = BTUSB_INTEL_COMBINED },
+ { USB_DEVICE(0x8087, 0x0035), .driver_info = BTUSB_INTEL_COMBINED },
{ USB_DEVICE(0x8087, 0x07da), .driver_info = BTUSB_CSR },
{ USB_DEVICE(0x8087, 0x07dc), .driver_info = BTUSB_INTEL_COMBINED |
+ BTUSB_INTEL_NO_WBS_SUPPORT |
BTUSB_INTEL_BROKEN_INITIAL_NCMD |
BTUSB_INTEL_BROKEN_SHUTDOWN_LED },
{ USB_DEVICE(0x8087, 0x0a2a), .driver_info = BTUSB_INTEL_COMBINED |
+ BTUSB_INTEL_NO_WBS_SUPPORT |
BTUSB_INTEL_BROKEN_SHUTDOWN_LED },
{ USB_DEVICE(0x8087, 0x0a2b), .driver_info = BTUSB_INTEL_COMBINED },
{ USB_DEVICE(0x8087, 0x0aa7), .driver_info = BTUSB_INTEL_COMBINED |
@@ -405,6 +409,8 @@ static const struct usb_device_id blacklist_table[] = {
BTUSB_WIDEBAND_SPEECH },
/* Realtek 8852AE Bluetooth devices */
+ { USB_DEVICE(0x0bda, 0x2852), .driver_info = BTUSB_REALTEK |
+ BTUSB_WIDEBAND_SPEECH },
{ USB_DEVICE(0x0bda, 0xc852), .driver_info = BTUSB_REALTEK |
BTUSB_WIDEBAND_SPEECH },
{ USB_DEVICE(0x0bda, 0x385a), .driver_info = BTUSB_REALTEK |
@@ -429,6 +435,11 @@ static const struct usb_device_id blacklist_table[] = {
/* Additional MediaTek MT7615E Bluetooth devices */
{ USB_DEVICE(0x13d3, 0x3560), .driver_info = BTUSB_MEDIATEK},
+ /* Additional MediaTek MT7663 Bluetooth devices */
+ { USB_DEVICE(0x043e, 0x310c), .driver_info = BTUSB_MEDIATEK |
+ BTUSB_WIDEBAND_SPEECH |
+ BTUSB_VALID_LE_STATES },
+
/* Additional MediaTek MT7668 Bluetooth devices */
{ USB_DEVICE(0x043e, 0x3109), .driver_info = BTUSB_MEDIATEK |
BTUSB_WIDEBAND_SPEECH |
@@ -444,6 +455,9 @@ static const struct usb_device_id blacklist_table[] = {
{ USB_DEVICE(0x13d3, 0x3564), .driver_info = BTUSB_MEDIATEK |
BTUSB_WIDEBAND_SPEECH |
BTUSB_VALID_LE_STATES },
+ { USB_DEVICE(0x13d3, 0x3567), .driver_info = BTUSB_MEDIATEK |
+ BTUSB_WIDEBAND_SPEECH |
+ BTUSB_VALID_LE_STATES },
{ USB_DEVICE(0x0489, 0xe0cd), .driver_info = BTUSB_MEDIATEK |
BTUSB_WIDEBAND_SPEECH |
BTUSB_VALID_LE_STATES },
@@ -463,6 +477,7 @@ static const struct usb_device_id blacklist_table[] = {
/* Additional Realtek 8723BE Bluetooth devices */
{ USB_DEVICE(0x0489, 0xe085), .driver_info = BTUSB_REALTEK },
{ USB_DEVICE(0x0489, 0xe08b), .driver_info = BTUSB_REALTEK },
+ { USB_DEVICE(0x04f2, 0xb49f), .driver_info = BTUSB_REALTEK },
{ USB_DEVICE(0x13d3, 0x3410), .driver_info = BTUSB_REALTEK },
{ USB_DEVICE(0x13d3, 0x3416), .driver_info = BTUSB_REALTEK },
{ USB_DEVICE(0x13d3, 0x3459), .driver_info = BTUSB_REALTEK },
@@ -482,6 +497,8 @@ static const struct usb_device_id blacklist_table[] = {
/* Additional Realtek 8761BU Bluetooth devices */
{ USB_DEVICE(0x0b05, 0x190e), .driver_info = BTUSB_REALTEK |
BTUSB_WIDEBAND_SPEECH },
+ { USB_DEVICE(0x2550, 0x8761), .driver_info = BTUSB_REALTEK |
+ BTUSB_WIDEBAND_SPEECH },
/* Additional Realtek 8821AE Bluetooth devices */
{ USB_DEVICE(0x0b05, 0x17dc), .driver_info = BTUSB_REALTEK },
@@ -2041,6 +2058,8 @@ static int btusb_setup_csr(struct hci_dev *hdev)
*/
set_bit(HCI_QUIRK_BROKEN_STORED_LINK_KEY, &hdev->quirks);
set_bit(HCI_QUIRK_BROKEN_ERR_DATA_REPORTING, &hdev->quirks);
+ set_bit(HCI_QUIRK_BROKEN_FILTER_CLEAR_ALL, &hdev->quirks);
+ set_bit(HCI_QUIRK_NO_SUSPEND_NOTIFIER, &hdev->quirks);
/* Clear the reset quirk since this is not an actual
* early Bluetooth 1.1 device from CSR.
@@ -2051,16 +2070,16 @@ static int btusb_setup_csr(struct hci_dev *hdev)
/*
* Special workaround for these BT 4.0 chip clones, and potentially more:
*
- * - 0x0134: a Barrot 8041a02 (HCI rev: 0x1012 sub: 0x0810)
+ * - 0x0134: a Barrot 8041a02 (HCI rev: 0x0810 sub: 0x1012)
* - 0x7558: IC markings FR3191AHAL 749H15143 (HCI rev/sub-version: 0x0709)
*
* These controllers are really messed-up.
*
* 1. Their bulk RX endpoint will never report any data unless
- * the device was suspended at least once (yes, really).
+ * the device was suspended at least once (yes, really).
* 2. They will not wakeup when autosuspended and receiving data
- * on their bulk RX endpoint from e.g. a keyboard or mouse
- * (IOW remote-wakeup support is broken for the bulk endpoint).
+ * on their bulk RX endpoint from e.g. a keyboard or mouse
+ * (IOW remote-wakeup support is broken for the bulk endpoint).
*
* To fix 1. enable runtime-suspend, force-suspend the
* HCI and then wake-it up by disabling runtime-suspend.
@@ -2080,7 +2099,7 @@ static int btusb_setup_csr(struct hci_dev *hdev)
if (ret >= 0)
msleep(200);
else
- bt_dev_err(hdev, "CSR: Failed to suspend the device for our Barrot 8041a02 receive-issue workaround");
+ bt_dev_warn(hdev, "CSR: Couldn't suspend the device for our Barrot 8041a02 receive-issue workaround");
pm_runtime_forbid(&data->udev->dev);
@@ -2245,7 +2264,6 @@ static void btusb_mtk_wmt_recv(struct urb *urb)
{
struct hci_dev *hdev = urb->context;
struct btusb_data *data = hci_get_drvdata(hdev);
- struct hci_event_hdr *hdr;
struct sk_buff *skb;
int err;
@@ -2265,13 +2283,6 @@ static void btusb_mtk_wmt_recv(struct urb *urb)
hci_skb_pkt_type(skb) = HCI_EVENT_PKT;
skb_put_data(skb, urb->transfer_buffer, urb->actual_length);
- hdr = (void *)skb->data;
- /* Fix up the vendor event id with 0xff for vendor specific
- * instead of 0xe4 so that event send via monitoring socket can
- * be parsed properly.
- */
- hdr->evt = 0xff;
-
/* When someone waits for the WMT event, the skb is being cloned
* and being processed the events from there then.
*/
@@ -2988,6 +2999,7 @@ static int btusb_set_bdaddr_wcn6855(struct hci_dev *hdev,
#define QCA_PATCH_UPDATED 0x80
#define QCA_DFU_TIMEOUT 3000
#define QCA_FLAG_MULTI_NVM 0x80
+#define QCA_BT_RESET_WAIT_MS 100
#define WCN6855_2_0_RAM_VERSION_GF 0x400c1200
#define WCN6855_2_1_RAM_VERSION_GF 0x400c1211
@@ -3314,6 +3326,13 @@ static int btusb_setup_qca(struct hci_dev *hdev)
err = btusb_setup_qca_load_nvm(hdev, &ver, info);
if (err < 0)
return err;
+
+ /* WCN6855 2.1 will reset to apply firmware downloaded here, so
+ * wait ~100ms for reset Done then go ahead, otherwise, it maybe
+ * cause potential enable failure.
+ */
+ if (info->rom_version == 0x00130201)
+ msleep(QCA_BT_RESET_WAIT_MS);
}
return 0;
@@ -3737,6 +3756,9 @@ static int btusb_probe(struct usb_interface *intf,
hdev->send = btusb_send_frame_intel;
hdev->cmd_timeout = btusb_intel_cmd_timeout;
+ if (id->driver_info & BTUSB_INTEL_NO_WBS_SUPPORT)
+ btintel_set_flag(hdev, INTEL_ROM_LEGACY_NO_WBS_SUPPORT);
+
if (id->driver_info & BTUSB_INTEL_BROKEN_INITIAL_NCMD)
btintel_set_flag(hdev, INTEL_BROKEN_INITIAL_NCMD);
diff --git a/drivers/bluetooth/hci_bcm.c b/drivers/bluetooth/hci_bcm.c
index d634a27bc850..785f445dd60d 100644
--- a/drivers/bluetooth/hci_bcm.c
+++ b/drivers/bluetooth/hci_bcm.c
@@ -20,6 +20,7 @@
#include <linux/regulator/consumer.h>
#include <linux/clk.h>
#include <linux/gpio/consumer.h>
+#include <linux/gpio/machine.h>
#include <linux/tty.h>
#include <linux/interrupt.h>
#include <linux/dmi.h>
@@ -870,8 +871,24 @@ unlock:
#endif
/* Some firmware reports an IRQ which does not work (wrong pin in fw table?) */
+static struct gpiod_lookup_table asus_tf103c_irq_gpios = {
+ .dev_id = "serial0-0",
+ .table = {
+ GPIO_LOOKUP("INT33FC:02", 17, "host-wakeup-alt", GPIO_ACTIVE_HIGH),
+ { }
+ },
+};
+
static const struct dmi_system_id bcm_broken_irq_dmi_table[] = {
{
+ .ident = "Asus TF103C",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "TF103C"),
+ },
+ .driver_data = &asus_tf103c_irq_gpios,
+ },
+ {
.ident = "Meegopad T08",
.matches = {
DMI_EXACT_MATCH(DMI_BOARD_VENDOR,
@@ -1027,7 +1044,8 @@ static struct clk *bcm_get_txco(struct device *dev)
static int bcm_get_resources(struct bcm_device *dev)
{
- const struct dmi_system_id *dmi_id;
+ const struct dmi_system_id *broken_irq_dmi_id;
+ const char *irq_con_id = "host-wakeup";
int err;
dev->name = dev_name(dev->dev);
@@ -1083,23 +1101,33 @@ static int bcm_get_resources(struct bcm_device *dev)
if (err)
return err;
+ broken_irq_dmi_id = dmi_first_match(bcm_broken_irq_dmi_table);
+ if (broken_irq_dmi_id && broken_irq_dmi_id->driver_data) {
+ gpiod_add_lookup_table(broken_irq_dmi_id->driver_data);
+ irq_con_id = "host-wakeup-alt";
+ dev->irq_active_low = false;
+ dev->irq = 0;
+ }
+
/* IRQ can be declared in ACPI table as Interrupt or GpioInt */
if (dev->irq <= 0) {
struct gpio_desc *gpio;
- gpio = devm_gpiod_get_optional(dev->dev, "host-wakeup",
- GPIOD_IN);
+ gpio = devm_gpiod_get_optional(dev->dev, irq_con_id, GPIOD_IN);
if (IS_ERR(gpio))
return PTR_ERR(gpio);
dev->irq = gpiod_to_irq(gpio);
}
- dmi_id = dmi_first_match(bcm_broken_irq_dmi_table);
- if (dmi_id) {
- dev_info(dev->dev, "%s: Has a broken IRQ config, disabling IRQ support / runtime-pm\n",
- dmi_id->ident);
- dev->irq = 0;
+ if (broken_irq_dmi_id) {
+ if (broken_irq_dmi_id->driver_data) {
+ gpiod_remove_lookup_table(broken_irq_dmi_id->driver_data);
+ } else {
+ dev_info(dev->dev, "%s: Has a broken IRQ config, disabling IRQ support / runtime-pm\n",
+ broken_irq_dmi_id->ident);
+ dev->irq = 0;
+ }
}
dev_dbg(dev->dev, "BCM irq: %d\n", dev->irq);
@@ -1513,6 +1541,8 @@ static const struct of_device_id bcm_bluetooth_of_match[] = {
{ .compatible = "brcm,bcm4330-bt" },
{ .compatible = "brcm,bcm4334-bt" },
{ .compatible = "brcm,bcm4345c5" },
+ { .compatible = "brcm,bcm43430a0-bt" },
+ { .compatible = "brcm,bcm43430a1-bt" },
{ .compatible = "brcm,bcm43438-bt", .data = &bcm43438_device_data },
{ .compatible = "brcm,bcm43540-bt", .data = &bcm4354_device_data },
{ .compatible = "brcm,bcm4335a0" },
diff --git a/drivers/bluetooth/hci_h5.c b/drivers/bluetooth/hci_h5.c
index 34286ffe0568..c5a0409ef84f 100644
--- a/drivers/bluetooth/hci_h5.c
+++ b/drivers/bluetooth/hci_h5.c
@@ -629,9 +629,11 @@ static int h5_enqueue(struct hci_uart *hu, struct sk_buff *skb)
break;
}
- pm_runtime_get_sync(&hu->serdev->dev);
- pm_runtime_mark_last_busy(&hu->serdev->dev);
- pm_runtime_put_autosuspend(&hu->serdev->dev);
+ if (hu->serdev) {
+ pm_runtime_get_sync(&hu->serdev->dev);
+ pm_runtime_mark_last_busy(&hu->serdev->dev);
+ pm_runtime_put_autosuspend(&hu->serdev->dev);
+ }
return 0;
}
@@ -966,6 +968,11 @@ static void h5_btrtl_open(struct h5 *h5)
pm_runtime_enable(&h5->hu->serdev->dev);
}
+ /* The controller needs reset to startup */
+ gpiod_set_value_cansleep(h5->enable_gpio, 0);
+ gpiod_set_value_cansleep(h5->device_wake_gpio, 0);
+ msleep(100);
+
/* The controller needs up to 500ms to wakeup */
gpiod_set_value_cansleep(h5->enable_gpio, 1);
gpiod_set_value_cansleep(h5->device_wake_gpio, 1);
diff --git a/drivers/bluetooth/hci_ll.c b/drivers/bluetooth/hci_ll.c
index eb1e736efeeb..4eb420a9ed04 100644
--- a/drivers/bluetooth/hci_ll.c
+++ b/drivers/bluetooth/hci_ll.c
@@ -509,7 +509,7 @@ static int send_command_from_firmware(struct ll_device *lldev,
return 0;
}
-/**
+/*
* download_firmware -
* internal function which parses through the .bts firmware
* script file intreprets SEND, DELAY actions only as of now
diff --git a/drivers/bluetooth/hci_serdev.c b/drivers/bluetooth/hci_serdev.c
index 3b00d82d36cf..4cda890ce647 100644
--- a/drivers/bluetooth/hci_serdev.c
+++ b/drivers/bluetooth/hci_serdev.c
@@ -305,6 +305,8 @@ int hci_uart_register_device(struct hci_uart *hu,
if (err)
return err;
+ percpu_init_rwsem(&hu->proto_lock);
+
err = p->open(hu);
if (err)
goto err_open;
@@ -327,7 +329,6 @@ int hci_uart_register_device(struct hci_uart *hu,
INIT_WORK(&hu->init_ready, hci_uart_init_work);
INIT_WORK(&hu->write_work, hci_uart_write_work);
- percpu_init_rwsem(&hu->proto_lock);
/* Only when vendor specific setup callback is provided, consider
* the manufacturer information valid. This avoids filling in the
diff --git a/drivers/bus/imx-weim.c b/drivers/bus/imx-weim.c
index bccb275b65ba..60fbd42041dd 100644
--- a/drivers/bus/imx-weim.c
+++ b/drivers/bus/imx-weim.c
@@ -64,6 +64,11 @@ struct cs_timing_state {
struct cs_timing cs[MAX_CS_COUNT];
};
+struct weim_priv {
+ void __iomem *base;
+ struct cs_timing_state timing_state;
+};
+
static const struct of_device_id weim_id_table[] = {
/* i.MX1/21 */
{ .compatible = "fsl,imx1-weim", .data = &imx1_weim_devtype, },
@@ -128,21 +133,26 @@ err:
}
/* Parse and set the timing for this device. */
-static int weim_timing_setup(struct device *dev,
- struct device_node *np, void __iomem *base,
- const struct imx_weim_devtype *devtype,
- struct cs_timing_state *ts)
+static int weim_timing_setup(struct device *dev, struct device_node *np,
+ const struct imx_weim_devtype *devtype)
{
u32 cs_idx, value[MAX_CS_REGS_COUNT];
int i, ret;
int reg_idx, num_regs;
struct cs_timing *cst;
+ struct weim_priv *priv;
+ struct cs_timing_state *ts;
+ void __iomem *base;
if (WARN_ON(devtype->cs_regs_count > MAX_CS_REGS_COUNT))
return -EINVAL;
if (WARN_ON(devtype->cs_count > MAX_CS_COUNT))
return -EINVAL;
+ priv = dev_get_drvdata(dev);
+ base = priv->base;
+ ts = &priv->timing_state;
+
ret = of_property_read_u32_array(np, "fsl,weim-cs-timing",
value, devtype->cs_regs_count);
if (ret)
@@ -189,14 +199,15 @@ static int weim_timing_setup(struct device *dev,
return 0;
}
-static int weim_parse_dt(struct platform_device *pdev, void __iomem *base)
+static int weim_parse_dt(struct platform_device *pdev)
{
const struct of_device_id *of_id = of_match_device(weim_id_table,
&pdev->dev);
const struct imx_weim_devtype *devtype = of_id->data;
struct device_node *child;
int ret, have_child = 0;
- struct cs_timing_state ts = {};
+ struct weim_priv *priv;
+ void __iomem *base;
u32 reg;
if (devtype == &imx50_weim_devtype) {
@@ -205,6 +216,9 @@ static int weim_parse_dt(struct platform_device *pdev, void __iomem *base)
return ret;
}
+ priv = dev_get_drvdata(&pdev->dev);
+ base = priv->base;
+
if (of_property_read_bool(pdev->dev.of_node, "fsl,burst-clk-enable")) {
if (devtype->wcr_bcm) {
reg = readl(base + devtype->wcr_offset);
@@ -229,7 +243,7 @@ static int weim_parse_dt(struct platform_device *pdev, void __iomem *base)
}
for_each_available_child_of_node(pdev->dev.of_node, child) {
- ret = weim_timing_setup(&pdev->dev, child, base, devtype, &ts);
+ ret = weim_timing_setup(&pdev->dev, child, devtype);
if (ret)
dev_warn(&pdev->dev, "%pOF set timing failed.\n",
child);
@@ -248,17 +262,25 @@ static int weim_parse_dt(struct platform_device *pdev, void __iomem *base)
static int weim_probe(struct platform_device *pdev)
{
+ struct weim_priv *priv;
struct resource *res;
struct clk *clk;
void __iomem *base;
int ret;
+ priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+
/* get the resource */
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
base = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(base))
return PTR_ERR(base);
+ priv->base = base;
+ dev_set_drvdata(&pdev->dev, priv);
+
/* get the clock */
clk = devm_clk_get(&pdev->dev, NULL);
if (IS_ERR(clk))
@@ -269,7 +291,7 @@ static int weim_probe(struct platform_device *pdev)
return ret;
/* parse the device node */
- ret = weim_parse_dt(pdev, base);
+ ret = weim_parse_dt(pdev);
if (ret)
clk_disable_unprepare(clk);
else
@@ -278,6 +300,81 @@ static int weim_probe(struct platform_device *pdev)
return ret;
}
+#if IS_ENABLED(CONFIG_OF_DYNAMIC)
+static int of_weim_notify(struct notifier_block *nb, unsigned long action,
+ void *arg)
+{
+ const struct imx_weim_devtype *devtype;
+ struct of_reconfig_data *rd = arg;
+ const struct of_device_id *of_id;
+ struct platform_device *pdev;
+ int ret = NOTIFY_OK;
+
+ switch (of_reconfig_get_state_change(action, rd)) {
+ case OF_RECONFIG_CHANGE_ADD:
+ of_id = of_match_node(weim_id_table, rd->dn->parent);
+ if (!of_id)
+ return NOTIFY_OK; /* not for us */
+
+ devtype = of_id->data;
+
+ pdev = of_find_device_by_node(rd->dn->parent);
+ if (!pdev) {
+ pr_err("%s: could not find platform device for '%pOF'\n",
+ __func__, rd->dn->parent);
+
+ return notifier_from_errno(-EINVAL);
+ }
+
+ if (weim_timing_setup(&pdev->dev, rd->dn, devtype))
+ dev_warn(&pdev->dev,
+ "Failed to setup timing for '%pOF'\n", rd->dn);
+
+ if (!of_node_check_flag(rd->dn, OF_POPULATED)) {
+ if (!of_platform_device_create(rd->dn, NULL, &pdev->dev)) {
+ dev_err(&pdev->dev,
+ "Failed to create child device '%pOF'\n",
+ rd->dn);
+ ret = notifier_from_errno(-EINVAL);
+ }
+ }
+
+ platform_device_put(pdev);
+
+ break;
+ case OF_RECONFIG_CHANGE_REMOVE:
+ if (!of_node_check_flag(rd->dn, OF_POPULATED))
+ return NOTIFY_OK; /* device already destroyed */
+
+ of_id = of_match_node(weim_id_table, rd->dn->parent);
+ if (!of_id)
+ return NOTIFY_OK; /* not for us */
+
+ pdev = of_find_device_by_node(rd->dn);
+ if (!pdev) {
+ dev_err(&pdev->dev,
+ "Could not find platform device for '%pOF'\n",
+ rd->dn);
+
+ ret = notifier_from_errno(-EINVAL);
+ } else {
+ of_platform_device_destroy(&pdev->dev, NULL);
+ platform_device_put(pdev);
+ }
+
+ break;
+ default:
+ break;
+ }
+
+ return ret;
+}
+
+struct notifier_block weim_of_notifier = {
+ .notifier_call = of_weim_notify,
+};
+#endif /* IS_ENABLED(CONFIG_OF_DYNAMIC) */
+
static struct platform_driver weim_driver = {
.driver = {
.name = "imx-weim",
@@ -285,7 +382,27 @@ static struct platform_driver weim_driver = {
},
.probe = weim_probe,
};
-module_platform_driver(weim_driver);
+
+static int __init weim_init(void)
+{
+#if IS_ENABLED(CONFIG_OF_DYNAMIC)
+ WARN_ON(of_reconfig_notifier_register(&weim_of_notifier));
+#endif /* IS_ENABLED(CONFIG_OF_DYNAMIC) */
+
+ return platform_driver_register(&weim_driver);
+}
+module_init(weim_init);
+
+static void __exit weim_exit(void)
+{
+#if IS_ENABLED(CONFIG_OF_DYNAMIC)
+ of_reconfig_notifier_unregister(&weim_of_notifier);
+#endif /* IS_ENABLED(CONFIG_OF_DYNAMIC) */
+
+ return platform_driver_unregister(&weim_driver);
+
+}
+module_exit(weim_exit);
MODULE_AUTHOR("Freescale Semiconductor Inc.");
MODULE_DESCRIPTION("i.MX EIM Controller Driver");
diff --git a/drivers/bus/mhi/pci_generic.c b/drivers/bus/mhi/pci_generic.c
index 3a258a677df8..b79895810c52 100644
--- a/drivers/bus/mhi/pci_generic.c
+++ b/drivers/bus/mhi/pci_generic.c
@@ -366,6 +366,7 @@ static const struct mhi_pci_dev_info mhi_foxconn_sdx55_info = {
.config = &modem_foxconn_sdx55_config,
.bar_num = MHI_PCI_DEFAULT_BAR_NUM,
.dma_data_width = 32,
+ .mru_default = 32768,
.sideband_wake = false,
};
@@ -401,6 +402,7 @@ static const struct mhi_pci_dev_info mhi_mv31_info = {
.config = &modem_mv31_config,
.bar_num = MHI_PCI_DEFAULT_BAR_NUM,
.dma_data_width = 32,
+ .mru_default = 32768,
};
static const struct mhi_channel_config mhi_sierra_em919x_channels[] = {
diff --git a/drivers/bus/moxtet.c b/drivers/bus/moxtet.c
index fd87a59837fa..5eb0fe73ddc4 100644
--- a/drivers/bus/moxtet.c
+++ b/drivers/bus/moxtet.c
@@ -815,7 +815,7 @@ static int moxtet_probe(struct spi_device *spi)
return 0;
}
-static int moxtet_remove(struct spi_device *spi)
+static void moxtet_remove(struct spi_device *spi)
{
struct moxtet *moxtet = spi_get_drvdata(spi);
@@ -828,8 +828,6 @@ static int moxtet_remove(struct spi_device *spi)
device_for_each_child(moxtet->dev, NULL, __unregister);
mutex_destroy(&moxtet->lock);
-
- return 0;
}
static const struct of_device_id moxtet_dt_ids[] = {
diff --git a/drivers/cdrom/gdrom.c b/drivers/cdrom/gdrom.c
index faead41709bc..8e78b37d0f6a 100644
--- a/drivers/cdrom/gdrom.c
+++ b/drivers/cdrom/gdrom.c
@@ -15,7 +15,6 @@
#include <linux/slab.h>
#include <linux/dma-mapping.h>
#include <linux/cdrom.h>
-#include <linux/genhd.h>
#include <linux/bio.h>
#include <linux/blk-mq.h>
#include <linux/interrupt.h>
diff --git a/drivers/char/agp/ati-agp.c b/drivers/char/agp/ati-agp.c
index 20bf5f78a362..6f5530482d83 100644
--- a/drivers/char/agp/ati-agp.c
+++ b/drivers/char/agp/ati-agp.c
@@ -55,7 +55,7 @@ static struct _ati_generic_private {
static int ati_create_page_map(struct ati_page_map *page_map)
{
- int i, err = 0;
+ int i, err;
page_map->real = (unsigned long *) __get_free_page(GFP_KERNEL);
if (page_map->real == NULL)
@@ -63,6 +63,10 @@ static int ati_create_page_map(struct ati_page_map *page_map)
set_memory_uc((unsigned long)page_map->real, 1);
err = map_page_into_agp(virt_to_page(page_map->real));
+ if (err) {
+ free_page((unsigned long)page_map->real);
+ return err;
+ }
page_map->remapped = page_map->real;
for (i = 0; i < PAGE_SIZE / sizeof(unsigned long); i++) {
@@ -303,7 +307,7 @@ static int ati_insert_memory(struct agp_memory * mem,
for (i = 0, j = pg_start; i < mem->page_count; i++, j++) {
addr = (j * PAGE_SIZE) + agp_bridge->gart_bus_addr;
cur_gatt = GET_GATT(addr);
- writel(agp_bridge->driver->mask_memory(agp_bridge,
+ writel(agp_bridge->driver->mask_memory(agp_bridge,
page_to_phys(mem->pages[i]),
mem->type),
cur_gatt+GET_GATT_OFF(addr));
diff --git a/drivers/char/agp/backend.c b/drivers/char/agp/backend.c
index 004a3ce8ba72..0e19c600db53 100644
--- a/drivers/char/agp/backend.c
+++ b/drivers/char/agp/backend.c
@@ -62,6 +62,7 @@ EXPORT_SYMBOL(agp_find_bridge);
/**
* agp_backend_acquire - attempt to acquire an agp backend.
+ * @pdev: the PCI device
*
*/
struct agp_bridge_data *agp_backend_acquire(struct pci_dev *pdev)
@@ -83,6 +84,7 @@ EXPORT_SYMBOL(agp_backend_acquire);
/**
* agp_backend_release - release the lock on the agp backend.
+ * @bridge: the AGP backend to release
*
* The caller must insure that the graphics aperture translation table
* is read for use by another entity.
diff --git a/drivers/char/agp/frontend.c b/drivers/char/agp/frontend.c
index 00ff5fcb808a..321118a9cfa5 100644
--- a/drivers/char/agp/frontend.c
+++ b/drivers/char/agp/frontend.c
@@ -39,7 +39,9 @@
#include <linux/fs.h>
#include <linux/sched.h>
#include <linux/uaccess.h>
+
#include "agp.h"
+#include "compat_ioctl.h"
struct agp_front_data agp_fe;
@@ -1017,7 +1019,7 @@ static long agp_ioctl(struct file *file,
case AGPIOC_UNBIND:
ret_val = agpioc_unbind_wrap(curr_priv, (void __user *) arg);
break;
-
+
case AGPIOC_CHIPSET_FLUSH:
break;
}
diff --git a/drivers/char/agp/nvidia-agp.c b/drivers/char/agp/nvidia-agp.c
index f78e756157db..826dbd06f6bb 100644
--- a/drivers/char/agp/nvidia-agp.c
+++ b/drivers/char/agp/nvidia-agp.c
@@ -261,7 +261,8 @@ static int nvidia_remove_memory(struct agp_memory *mem, off_t pg_start, int type
static void nvidia_tlbflush(struct agp_memory *mem)
{
unsigned long end;
- u32 wbc_reg, temp;
+ u32 wbc_reg;
+ u32 __maybe_unused temp;
int i;
/* flush chipset */
diff --git a/drivers/char/agp/sworks-agp.c b/drivers/char/agp/sworks-agp.c
index f875970bda65..b91da5998dd7 100644
--- a/drivers/char/agp/sworks-agp.c
+++ b/drivers/char/agp/sworks-agp.c
@@ -262,13 +262,10 @@ static void serverworks_tlbflush(struct agp_memory *temp)
static int serverworks_configure(void)
{
- struct aper_size_info_lvl2 *current_size;
u32 temp;
u8 enable_reg;
u16 cap_reg;
- current_size = A_SIZE_LVL2(agp_bridge->current_size);
-
/* Get the memory mapped registers */
pci_read_config_dword(agp_bridge->dev, serverworks_private.mm_addr_ofs, &temp);
temp = (temp & PCI_BASE_ADDRESS_MEM_MASK);
@@ -350,7 +347,7 @@ static int serverworks_insert_memory(struct agp_memory *mem,
for (i = 0, j = pg_start; i < mem->page_count; i++, j++) {
addr = (j * PAGE_SIZE) + agp_bridge->gart_bus_addr;
cur_gatt = SVRWRKS_GET_GATT(addr);
- writel(agp_bridge->driver->mask_memory(agp_bridge,
+ writel(agp_bridge->driver->mask_memory(agp_bridge,
page_to_phys(mem->pages[i]), mem->type),
cur_gatt+GET_GATT_OFF(addr));
}
diff --git a/drivers/char/agp/via-agp.c b/drivers/char/agp/via-agp.c
index a460ae352772..b2f484f527fb 100644
--- a/drivers/char/agp/via-agp.c
+++ b/drivers/char/agp/via-agp.c
@@ -128,9 +128,6 @@ static int via_fetch_size_agp3(void)
static int via_configure_agp3(void)
{
u32 temp;
- struct aper_size_info_16 *current_size;
-
- current_size = A_SIZE_16(agp_bridge->current_size);
/* address to map to */
agp_bridge->gart_bus_addr = pci_bus_address(agp_bridge->dev,
diff --git a/drivers/char/hw_random/Kconfig b/drivers/char/hw_random/Kconfig
index 9704963f9d50..a087156a5818 100644
--- a/drivers/char/hw_random/Kconfig
+++ b/drivers/char/hw_random/Kconfig
@@ -401,7 +401,7 @@ config HW_RANDOM_MESON
config HW_RANDOM_CAVIUM
tristate "Cavium ThunderX Random Number Generator support"
- depends on HW_RANDOM && PCI && ARM64
+ depends on HW_RANDOM && PCI && ARCH_THUNDER
default HW_RANDOM
help
This driver provides kernel-side support for the Random Number
diff --git a/drivers/char/hw_random/atmel-rng.c b/drivers/char/hw_random/atmel-rng.c
index ecb71c4317a5..b8effe77d80f 100644
--- a/drivers/char/hw_random/atmel-rng.c
+++ b/drivers/char/hw_random/atmel-rng.c
@@ -13,13 +13,16 @@
#include <linux/err.h>
#include <linux/clk.h>
#include <linux/io.h>
+#include <linux/iopoll.h>
#include <linux/hw_random.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
#define TRNG_CR 0x00
#define TRNG_MR 0x04
#define TRNG_ISR 0x1c
+#define TRNG_ISR_DATRDY BIT(0)
#define TRNG_ODATA 0x50
#define TRNG_KEY 0x524e4700 /* RNG */
@@ -34,37 +37,79 @@ struct atmel_trng {
struct clk *clk;
void __iomem *base;
struct hwrng rng;
+ bool has_half_rate;
};
+static bool atmel_trng_wait_ready(struct atmel_trng *trng, bool wait)
+{
+ int ready;
+
+ ready = readl(trng->base + TRNG_ISR) & TRNG_ISR_DATRDY;
+ if (!ready && wait)
+ readl_poll_timeout(trng->base + TRNG_ISR, ready,
+ ready & TRNG_ISR_DATRDY, 1000, 20000);
+
+ return !!ready;
+}
+
static int atmel_trng_read(struct hwrng *rng, void *buf, size_t max,
bool wait)
{
struct atmel_trng *trng = container_of(rng, struct atmel_trng, rng);
u32 *data = buf;
+ int ret;
- /* data ready? */
- if (readl(trng->base + TRNG_ISR) & 1) {
- *data = readl(trng->base + TRNG_ODATA);
- /*
- ensure data ready is only set again AFTER the next data
- word is ready in case it got set between checking ISR
- and reading ODATA, so we don't risk re-reading the
- same word
- */
- readl(trng->base + TRNG_ISR);
- return 4;
- } else
- return 0;
+ ret = pm_runtime_get_sync((struct device *)trng->rng.priv);
+ if (ret < 0) {
+ pm_runtime_put_sync((struct device *)trng->rng.priv);
+ return ret;
+ }
+
+ ret = atmel_trng_wait_ready(trng, wait);
+ if (!ret)
+ goto out;
+
+ *data = readl(trng->base + TRNG_ODATA);
+ /*
+ * ensure data ready is only set again AFTER the next data word is ready
+ * in case it got set between checking ISR and reading ODATA, so we
+ * don't risk re-reading the same word
+ */
+ readl(trng->base + TRNG_ISR);
+ ret = 4;
+
+out:
+ pm_runtime_mark_last_busy((struct device *)trng->rng.priv);
+ pm_runtime_put_sync_autosuspend((struct device *)trng->rng.priv);
+ return ret;
}
-static void atmel_trng_enable(struct atmel_trng *trng)
+static int atmel_trng_init(struct atmel_trng *trng)
{
+ unsigned long rate;
+ int ret;
+
+ ret = clk_prepare_enable(trng->clk);
+ if (ret)
+ return ret;
+
+ if (trng->has_half_rate) {
+ rate = clk_get_rate(trng->clk);
+
+ /* if peripheral clk is above 100MHz, set HALFR */
+ if (rate > 100000000)
+ writel(TRNG_HALFR, trng->base + TRNG_MR);
+ }
+
writel(TRNG_KEY | 1, trng->base + TRNG_CR);
+
+ return 0;
}
-static void atmel_trng_disable(struct atmel_trng *trng)
+static void atmel_trng_cleanup(struct atmel_trng *trng)
{
writel(TRNG_KEY, trng->base + TRNG_CR);
+ clk_disable_unprepare(trng->clk);
}
static int atmel_trng_probe(struct platform_device *pdev)
@@ -88,32 +133,31 @@ static int atmel_trng_probe(struct platform_device *pdev)
if (!data)
return -ENODEV;
- if (data->has_half_rate) {
- unsigned long rate = clk_get_rate(trng->clk);
-
- /* if peripheral clk is above 100MHz, set HALFR */
- if (rate > 100000000)
- writel(TRNG_HALFR, trng->base + TRNG_MR);
- }
-
- ret = clk_prepare_enable(trng->clk);
- if (ret)
- return ret;
-
- atmel_trng_enable(trng);
+ trng->has_half_rate = data->has_half_rate;
trng->rng.name = pdev->name;
trng->rng.read = atmel_trng_read;
+ trng->rng.priv = (unsigned long)&pdev->dev;
+ platform_set_drvdata(pdev, trng);
- ret = devm_hwrng_register(&pdev->dev, &trng->rng);
+#ifndef CONFIG_PM
+ ret = atmel_trng_init(trng);
if (ret)
- goto err_register;
+ return ret;
+#endif
- platform_set_drvdata(pdev, trng);
+ pm_runtime_set_autosuspend_delay(&pdev->dev, 100);
+ pm_runtime_use_autosuspend(&pdev->dev);
+ pm_runtime_enable(&pdev->dev);
- return 0;
+ ret = devm_hwrng_register(&pdev->dev, &trng->rng);
+ if (ret) {
+ pm_runtime_disable(&pdev->dev);
+ pm_runtime_set_suspended(&pdev->dev);
+#ifndef CONFIG_PM
+ atmel_trng_cleanup(trng);
+#endif
+ }
-err_register:
- clk_disable_unprepare(trng->clk);
return ret;
}
@@ -121,43 +165,35 @@ static int atmel_trng_remove(struct platform_device *pdev)
{
struct atmel_trng *trng = platform_get_drvdata(pdev);
-
- atmel_trng_disable(trng);
- clk_disable_unprepare(trng->clk);
+ atmel_trng_cleanup(trng);
+ pm_runtime_disable(&pdev->dev);
+ pm_runtime_set_suspended(&pdev->dev);
return 0;
}
-#ifdef CONFIG_PM
-static int atmel_trng_suspend(struct device *dev)
+static int __maybe_unused atmel_trng_runtime_suspend(struct device *dev)
{
struct atmel_trng *trng = dev_get_drvdata(dev);
- atmel_trng_disable(trng);
- clk_disable_unprepare(trng->clk);
+ atmel_trng_cleanup(trng);
return 0;
}
-static int atmel_trng_resume(struct device *dev)
+static int __maybe_unused atmel_trng_runtime_resume(struct device *dev)
{
struct atmel_trng *trng = dev_get_drvdata(dev);
- int ret;
- ret = clk_prepare_enable(trng->clk);
- if (ret)
- return ret;
-
- atmel_trng_enable(trng);
-
- return 0;
+ return atmel_trng_init(trng);
}
-static const struct dev_pm_ops atmel_trng_pm_ops = {
- .suspend = atmel_trng_suspend,
- .resume = atmel_trng_resume,
+static const struct dev_pm_ops __maybe_unused atmel_trng_pm_ops = {
+ SET_RUNTIME_PM_OPS(atmel_trng_runtime_suspend,
+ atmel_trng_runtime_resume, NULL)
+ SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
+ pm_runtime_force_resume)
};
-#endif /* CONFIG_PM */
static const struct atmel_trng_data at91sam9g45_config = {
.has_half_rate = false,
@@ -185,9 +221,7 @@ static struct platform_driver atmel_trng_driver = {
.remove = atmel_trng_remove,
.driver = {
.name = "atmel-trng",
-#ifdef CONFIG_PM
- .pm = &atmel_trng_pm_ops,
-#endif /* CONFIG_PM */
+ .pm = pm_ptr(&atmel_trng_pm_ops),
.of_match_table = atmel_trng_dt_ids,
},
};
diff --git a/drivers/char/hw_random/cavium-rng-vf.c b/drivers/char/hw_random/cavium-rng-vf.c
index 6f66919652bf..7c55f4cf4a8b 100644
--- a/drivers/char/hw_random/cavium-rng-vf.c
+++ b/drivers/char/hw_random/cavium-rng-vf.c
@@ -179,7 +179,7 @@ static int cavium_map_pf_regs(struct cavium_rng *rng)
pdev = pci_get_device(PCI_VENDOR_ID_CAVIUM,
PCI_DEVID_CAVIUM_RNG_PF, NULL);
if (!pdev) {
- dev_err(&pdev->dev, "Cannot find RNG PF device\n");
+ pr_err("Cannot find RNG PF device\n");
return -EIO;
}
diff --git a/drivers/char/hw_random/core.c b/drivers/char/hw_random/core.c
index a3db27916256..16f227b995e8 100644
--- a/drivers/char/hw_random/core.c
+++ b/drivers/char/hw_random/core.c
@@ -15,6 +15,7 @@
#include <linux/err.h>
#include <linux/fs.h>
#include <linux/hw_random.h>
+#include <linux/random.h>
#include <linux/kernel.h>
#include <linux/kthread.h>
#include <linux/sched/signal.h>
@@ -31,7 +32,7 @@ static struct hwrng *current_rng;
/* the current rng has been explicitly chosen by user via sysfs */
static int cur_rng_set_by_user;
static struct task_struct *hwrng_fill;
-/* list of registered rngs, sorted decending by quality */
+/* list of registered rngs */
static LIST_HEAD(rng_list);
/* Protects rng_list and current_rng */
static DEFINE_MUTEX(rng_mutex);
@@ -44,14 +45,14 @@ static unsigned short default_quality; /* = 0; default to "off" */
module_param(current_quality, ushort, 0644);
MODULE_PARM_DESC(current_quality,
- "current hwrng entropy estimation per 1024 bits of input");
+ "current hwrng entropy estimation per 1024 bits of input -- obsolete, use rng_quality instead");
module_param(default_quality, ushort, 0644);
MODULE_PARM_DESC(default_quality,
"default entropy content of hwrng per 1024 bits of input");
static void drop_current_rng(void);
static int hwrng_init(struct hwrng *rng);
-static void start_khwrngd(void);
+static void hwrng_manage_rngd(struct hwrng *rng);
static inline int rng_get_data(struct hwrng *rng, u8 *buffer, size_t size,
int wait);
@@ -64,13 +65,12 @@ static size_t rng_buffer_size(void)
static void add_early_randomness(struct hwrng *rng)
{
int bytes_read;
- size_t size = min_t(size_t, 16, rng_buffer_size());
mutex_lock(&reading_mutex);
- bytes_read = rng_get_data(rng, rng_buffer, size, 0);
+ bytes_read = rng_get_data(rng, rng_fillbuf, 32, 0);
mutex_unlock(&reading_mutex);
if (bytes_read > 0)
- add_device_randomness(rng_buffer, bytes_read);
+ add_device_randomness(rng_fillbuf, bytes_read);
}
static inline void cleanup_rng(struct kref *kref)
@@ -161,14 +161,13 @@ static int hwrng_init(struct hwrng *rng)
reinit_completion(&rng->cleanup_done);
skip_init:
- current_quality = rng->quality ? : default_quality;
- if (current_quality > 1024)
- current_quality = 1024;
+ if (!rng->quality)
+ rng->quality = default_quality;
+ if (rng->quality > 1024)
+ rng->quality = 1024;
+ current_quality = rng->quality; /* obsolete */
- if (current_quality == 0 && hwrng_fill)
- kthread_stop(hwrng_fill);
- if (current_quality > 0 && !hwrng_fill)
- start_khwrngd();
+ hwrng_manage_rngd(rng);
return 0;
}
@@ -298,24 +297,28 @@ static struct miscdevice rng_miscdev = {
static int enable_best_rng(void)
{
+ struct hwrng *rng, *new_rng = NULL;
int ret = -ENODEV;
BUG_ON(!mutex_is_locked(&rng_mutex));
- /* rng_list is sorted by quality, use the best (=first) one */
- if (!list_empty(&rng_list)) {
- struct hwrng *new_rng;
-
- new_rng = list_entry(rng_list.next, struct hwrng, list);
- ret = ((new_rng == current_rng) ? 0 : set_current_rng(new_rng));
- if (!ret)
- cur_rng_set_by_user = 0;
- } else {
+ /* no rng to use? */
+ if (list_empty(&rng_list)) {
drop_current_rng();
cur_rng_set_by_user = 0;
- ret = 0;
+ return 0;
+ }
+
+ /* use the rng which offers the best quality */
+ list_for_each_entry(rng, &rng_list, list) {
+ if (!new_rng || rng->quality > new_rng->quality)
+ new_rng = rng;
}
+ ret = ((new_rng == current_rng) ? 0 : set_current_rng(new_rng));
+ if (!ret)
+ cur_rng_set_by_user = 0;
+
return ret;
}
@@ -336,8 +339,9 @@ static ssize_t rng_current_store(struct device *dev,
} else {
list_for_each_entry(rng, &rng_list, list) {
if (sysfs_streq(rng->name, buf)) {
- cur_rng_set_by_user = 1;
err = set_current_rng(rng);
+ if (!err)
+ cur_rng_set_by_user = 1;
break;
}
}
@@ -399,14 +403,76 @@ static ssize_t rng_selected_show(struct device *dev,
return sysfs_emit(buf, "%d\n", cur_rng_set_by_user);
}
+static ssize_t rng_quality_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ ssize_t ret;
+ struct hwrng *rng;
+
+ rng = get_current_rng();
+ if (IS_ERR(rng))
+ return PTR_ERR(rng);
+
+ if (!rng) /* no need to put_rng */
+ return -ENODEV;
+
+ ret = sysfs_emit(buf, "%hu\n", rng->quality);
+ put_rng(rng);
+
+ return ret;
+}
+
+static ssize_t rng_quality_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t len)
+{
+ u16 quality;
+ int ret = -EINVAL;
+
+ if (len < 2)
+ return -EINVAL;
+
+ ret = mutex_lock_interruptible(&rng_mutex);
+ if (ret)
+ return -ERESTARTSYS;
+
+ ret = kstrtou16(buf, 0, &quality);
+ if (ret || quality > 1024) {
+ ret = -EINVAL;
+ goto out;
+ }
+
+ if (!current_rng) {
+ ret = -ENODEV;
+ goto out;
+ }
+
+ current_rng->quality = quality;
+ current_quality = quality; /* obsolete */
+
+ /* the best available RNG may have changed */
+ ret = enable_best_rng();
+
+ /* start/stop rngd if necessary */
+ if (current_rng)
+ hwrng_manage_rngd(current_rng);
+
+out:
+ mutex_unlock(&rng_mutex);
+ return ret ? ret : len;
+}
+
static DEVICE_ATTR_RW(rng_current);
static DEVICE_ATTR_RO(rng_available);
static DEVICE_ATTR_RO(rng_selected);
+static DEVICE_ATTR_RW(rng_quality);
static struct attribute *rng_dev_attrs[] = {
&dev_attr_rng_current.attr,
&dev_attr_rng_available.attr,
&dev_attr_rng_selected.attr,
+ &dev_attr_rng_quality.attr,
NULL
};
@@ -424,9 +490,11 @@ static int __init register_miscdev(void)
static int hwrng_fillfn(void *unused)
{
+ size_t entropy, entropy_credit = 0; /* in 1/1024 of a bit */
long rc;
while (!kthread_should_stop()) {
+ unsigned short quality;
struct hwrng *rng;
rng = get_current_rng();
@@ -435,27 +503,49 @@ static int hwrng_fillfn(void *unused)
mutex_lock(&reading_mutex);
rc = rng_get_data(rng, rng_fillbuf,
rng_buffer_size(), 1);
+ if (current_quality != rng->quality)
+ rng->quality = current_quality; /* obsolete */
+ quality = rng->quality;
mutex_unlock(&reading_mutex);
put_rng(rng);
+
+ if (!quality)
+ break;
+
if (rc <= 0) {
pr_warn("hwrng: no data available\n");
msleep_interruptible(10000);
continue;
}
+
+ /* If we cannot credit at least one bit of entropy,
+ * keep track of the remainder for the next iteration
+ */
+ entropy = rc * quality * 8 + entropy_credit;
+ if ((entropy >> 10) == 0)
+ entropy_credit = entropy;
+
/* Outside lock, sure, but y'know: randomness. */
add_hwgenerator_randomness((void *)rng_fillbuf, rc,
- rc * current_quality * 8 >> 10);
+ entropy >> 10);
}
hwrng_fill = NULL;
return 0;
}
-static void start_khwrngd(void)
+static void hwrng_manage_rngd(struct hwrng *rng)
{
- hwrng_fill = kthread_run(hwrng_fillfn, NULL, "hwrng");
- if (IS_ERR(hwrng_fill)) {
- pr_err("hwrng_fill thread creation failed\n");
- hwrng_fill = NULL;
+ if (WARN_ON(!mutex_is_locked(&rng_mutex)))
+ return;
+
+ if (rng->quality == 0 && hwrng_fill)
+ kthread_stop(hwrng_fill);
+ if (rng->quality > 0 && !hwrng_fill) {
+ hwrng_fill = kthread_run(hwrng_fillfn, NULL, "hwrng");
+ if (IS_ERR(hwrng_fill)) {
+ pr_err("hwrng_fill thread creation failed\n");
+ hwrng_fill = NULL;
+ }
}
}
@@ -463,7 +553,6 @@ int hwrng_register(struct hwrng *rng)
{
int err = -EINVAL;
struct hwrng *tmp;
- struct list_head *rng_list_ptr;
bool is_new_current = false;
if (!rng->name || (!rng->data_read && !rng->read))
@@ -477,18 +566,11 @@ int hwrng_register(struct hwrng *rng)
if (strcmp(tmp->name, rng->name) == 0)
goto out_unlock;
}
+ list_add_tail(&rng->list, &rng_list);
init_completion(&rng->cleanup_done);
complete(&rng->cleanup_done);
- /* rng_list is sorted by decreasing quality */
- list_for_each(rng_list_ptr, &rng_list) {
- tmp = list_entry(rng_list_ptr, struct hwrng, list);
- if (tmp->quality < rng->quality)
- break;
- }
- list_add_tail(&rng->list, rng_list_ptr);
-
if (!current_rng ||
(!cur_rng_set_by_user && rng->quality > current_rng->quality)) {
/*
@@ -638,7 +720,7 @@ static void __exit hwrng_modexit(void)
unregister_miscdev();
}
-module_init(hwrng_modinit);
+fs_initcall(hwrng_modinit); /* depends on misc_register() */
module_exit(hwrng_modexit);
MODULE_DESCRIPTION("H/W Random Number Generator (RNG) driver");
diff --git a/drivers/char/hw_random/nomadik-rng.c b/drivers/char/hw_random/nomadik-rng.c
index 67947a19aa22..e8f9621e7954 100644
--- a/drivers/char/hw_random/nomadik-rng.c
+++ b/drivers/char/hw_random/nomadik-rng.c
@@ -65,14 +65,14 @@ static int nmk_rng_probe(struct amba_device *dev, const struct amba_id *id)
out_release:
amba_release_regions(dev);
out_clk:
- clk_disable(rng_clk);
+ clk_disable_unprepare(rng_clk);
return ret;
}
static void nmk_rng_remove(struct amba_device *dev)
{
amba_release_regions(dev);
- clk_disable(rng_clk);
+ clk_disable_unprepare(rng_clk);
}
static const struct amba_id nmk_rng_ids[] = {
diff --git a/drivers/char/hw_random/optee-rng.c b/drivers/char/hw_random/optee-rng.c
index 135a82590923..a948c0727b2b 100644
--- a/drivers/char/hw_random/optee-rng.c
+++ b/drivers/char/hw_random/optee-rng.c
@@ -145,10 +145,10 @@ static int optee_rng_init(struct hwrng *rng)
struct optee_rng_private *pvt_data = to_optee_rng_private(rng);
struct tee_shm *entropy_shm_pool = NULL;
- entropy_shm_pool = tee_shm_alloc(pvt_data->ctx, MAX_ENTROPY_REQ_SZ,
- TEE_SHM_MAPPED | TEE_SHM_DMA_BUF);
+ entropy_shm_pool = tee_shm_alloc_kernel_buf(pvt_data->ctx,
+ MAX_ENTROPY_REQ_SZ);
if (IS_ERR(entropy_shm_pool)) {
- dev_err(pvt_data->dev, "tee_shm_alloc failed\n");
+ dev_err(pvt_data->dev, "tee_shm_alloc_kernel_buf failed\n");
return PTR_ERR(entropy_shm_pool);
}
diff --git a/drivers/char/random.c b/drivers/char/random.c
index 68613f0b6887..66ce7c03a142 100644
--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -1,320 +1,28 @@
+// SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause)
/*
- * random.c -- A strong random number generator
- *
* Copyright (C) 2017-2022 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
- *
* Copyright Matt Mackall <mpm@selenic.com>, 2003, 2004, 2005
- *
- * Copyright Theodore Ts'o, 1994, 1995, 1996, 1997, 1998, 1999. 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, and the entire permission notice in its entirety,
- * including the disclaimer of warranties.
- * 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.
- * 3. The name of the author may not be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * ALTERNATIVELY, this product may be distributed under the terms of
- * the GNU General Public License, in which case the provisions of the GPL are
- * required INSTEAD OF the above restrictions. (This clause is
- * necessary due to a potential bad interaction between the GPL and
- * the restrictions contained in a BSD-style copyright.)
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF
- * WHICH ARE HEREBY DISCLAIMED. IN NO EVENT SHALL THE AUTHOR 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 NOT ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- */
-
-/*
- * (now, with legal B.S. out of the way.....)
- *
- * This routine gathers environmental noise from device drivers, etc.,
- * and returns good random numbers, suitable for cryptographic use.
- * Besides the obvious cryptographic uses, these numbers are also good
- * for seeding TCP sequence numbers, and other places where it is
- * desirable to have numbers which are not only random, but hard to
- * predict by an attacker.
- *
- * Theory of operation
- * ===================
- *
- * Computers are very predictable devices. Hence it is extremely hard
- * to produce truly random numbers on a computer --- as opposed to
- * pseudo-random numbers, which can easily generated by using a
- * algorithm. Unfortunately, it is very easy for attackers to guess
- * the sequence of pseudo-random number generators, and for some
- * applications this is not acceptable. So instead, we must try to
- * gather "environmental noise" from the computer's environment, which
- * must be hard for outside attackers to observe, and use that to
- * generate random numbers. In a Unix environment, this is best done
- * from inside the kernel.
- *
- * Sources of randomness from the environment include inter-keyboard
- * timings, inter-interrupt timings from some interrupts, and other
- * events which are both (a) non-deterministic and (b) hard for an
- * outside observer to measure. Randomness from these sources are
- * added to an "entropy pool", which is mixed using a CRC-like function.
- * This is not cryptographically strong, but it is adequate assuming
- * the randomness is not chosen maliciously, and it is fast enough that
- * the overhead of doing it on every interrupt is very reasonable.
- * As random bytes are mixed into the entropy pool, the routines keep
- * an *estimate* of how many bits of randomness have been stored into
- * the random number generator's internal state.
- *
- * When random bytes are desired, they are obtained by taking the BLAKE2s
- * hash of the contents of the "entropy pool". The BLAKE2s hash avoids
- * exposing the internal state of the entropy pool. It is believed to
- * be computationally infeasible to derive any useful information
- * about the input of BLAKE2s from its output. Even if it is possible to
- * analyze BLAKE2s in some clever way, as long as the amount of data
- * returned from the generator is less than the inherent entropy in
- * the pool, the output data is totally unpredictable. For this
- * reason, the routine decreases its internal estimate of how many
- * bits of "true randomness" are contained in the entropy pool as it
- * outputs random numbers.
- *
- * If this estimate goes to zero, the routine can still generate
- * random numbers; however, an attacker may (at least in theory) be
- * able to infer the future output of the generator from prior
- * outputs. This requires successful cryptanalysis of BLAKE2s, which is
- * not believed to be feasible, but there is a remote possibility.
- * Nonetheless, these numbers should be useful for the vast majority
- * of purposes.
- *
- * Exported interfaces ---- output
- * ===============================
- *
- * There are four exported interfaces; two for use within the kernel,
- * and two for use from userspace.
- *
- * Exported interfaces ---- userspace output
- * -----------------------------------------
- *
- * The userspace interfaces are two character devices /dev/random and
- * /dev/urandom. /dev/random is suitable for use when very high
- * quality randomness is desired (for example, for key generation or
- * one-time pads), as it will only return a maximum of the number of
- * bits of randomness (as estimated by the random number generator)
- * contained in the entropy pool.
- *
- * The /dev/urandom device does not have this limit, and will return
- * as many bytes as are requested. As more and more random bytes are
- * requested without giving time for the entropy pool to recharge,
- * this will result in random numbers that are merely cryptographically
- * strong. For many applications, however, this is acceptable.
- *
- * Exported interfaces ---- kernel output
- * --------------------------------------
- *
- * The primary kernel interface is
- *
- * void get_random_bytes(void *buf, int nbytes);
- *
- * This interface will return the requested number of random bytes,
- * and place it in the requested buffer. This is equivalent to a
- * read from /dev/urandom.
- *
- * For less critical applications, there are the functions:
- *
- * u32 get_random_u32()
- * u64 get_random_u64()
- * unsigned int get_random_int()
- * unsigned long get_random_long()
- *
- * These are produced by a cryptographic RNG seeded from get_random_bytes,
- * and so do not deplete the entropy pool as much. These are recommended
- * for most in-kernel operations *if the result is going to be stored in
- * the kernel*.
- *
- * Specifically, the get_random_int() family do not attempt to do
- * "anti-backtracking". If you capture the state of the kernel (e.g.
- * by snapshotting the VM), you can figure out previous get_random_int()
- * return values. But if the value is stored in the kernel anyway,
- * this is not a problem.
- *
- * It *is* safe to expose get_random_int() output to attackers (e.g. as
- * network cookies); given outputs 1..n, it's not feasible to predict
- * outputs 0 or n+1. The only concern is an attacker who breaks into
- * the kernel later; the get_random_int() engine is not reseeded as
- * often as the get_random_bytes() one.
- *
- * get_random_bytes() is needed for keys that need to stay secret after
- * they are erased from the kernel. For example, any key that will
- * be wrapped and stored encrypted. And session encryption keys: we'd
- * like to know that after the session is closed and the keys erased,
- * the plaintext is unrecoverable to someone who recorded the ciphertext.
- *
- * But for network ports/cookies, stack canaries, PRNG seeds, address
- * space layout randomization, session *authentication* keys, or other
- * applications where the sensitive data is stored in the kernel in
- * plaintext for as long as it's sensitive, the get_random_int() family
- * is just fine.
- *
- * Consider ASLR. We want to keep the address space secret from an
- * outside attacker while the process is running, but once the address
- * space is torn down, it's of no use to an attacker any more. And it's
- * stored in kernel data structures as long as it's alive, so worrying
- * about an attacker's ability to extrapolate it from the get_random_int()
- * CRNG is silly.
- *
- * Even some cryptographic keys are safe to generate with get_random_int().
- * In particular, keys for SipHash are generally fine. Here, knowledge
- * of the key authorizes you to do something to a kernel object (inject
- * packets to a network connection, or flood a hash table), and the
- * key is stored with the object being protected. Once it goes away,
- * we no longer care if anyone knows the key.
- *
- * prandom_u32()
- * -------------
- *
- * For even weaker applications, see the pseudorandom generator
- * prandom_u32(), prandom_max(), and prandom_bytes(). If the random
- * numbers aren't security-critical at all, these are *far* cheaper.
- * Useful for self-tests, random error simulation, randomized backoffs,
- * and any other application where you trust that nobody is trying to
- * maliciously mess with you by guessing the "random" numbers.
- *
- * Exported interfaces ---- input
- * ==============================
- *
- * The current exported interfaces for gathering environmental noise
- * from the devices are:
- *
- * void add_device_randomness(const void *buf, unsigned int size);
- * void add_input_randomness(unsigned int type, unsigned int code,
- * unsigned int value);
- * void add_interrupt_randomness(int irq);
- * void add_disk_randomness(struct gendisk *disk);
- * void add_hwgenerator_randomness(const char *buffer, size_t count,
- * size_t entropy);
- * void add_bootloader_randomness(const void *buf, unsigned int size);
- *
- * add_device_randomness() is for adding data to the random pool that
- * is likely to differ between two devices (or possibly even per boot).
- * This would be things like MAC addresses or serial numbers, or the
- * read-out of the RTC. This does *not* add any actual entropy to the
- * pool, but it initializes the pool to different values for devices
- * that might otherwise be identical and have very little entropy
- * available to them (particularly common in the embedded world).
- *
- * add_input_randomness() uses the input layer interrupt timing, as well as
- * the event type information from the hardware.
- *
- * add_interrupt_randomness() uses the interrupt timing as random
- * inputs to the entropy pool. Using the cycle counters and the irq source
- * as inputs, it feeds the randomness roughly once a second.
- *
- * add_disk_randomness() uses what amounts to the seek time of block
- * layer request events, on a per-disk_devt basis, as input to the
- * entropy pool. Note that high-speed solid state drives with very low
- * seek times do not make for good sources of entropy, as their seek
- * times are usually fairly consistent.
- *
- * All of these routines try to estimate how many bits of randomness a
- * particular randomness source. They do this by keeping track of the
- * first and second order deltas of the event timings.
- *
- * add_hwgenerator_randomness() is for true hardware RNGs, and will credit
- * entropy as specified by the caller. If the entropy pool is full it will
- * block until more entropy is needed.
- *
- * add_bootloader_randomness() is the same as add_hwgenerator_randomness() or
- * add_device_randomness(), depending on whether or not the configuration
- * option CONFIG_RANDOM_TRUST_BOOTLOADER is set.
- *
- * Ensuring unpredictability at system startup
- * ============================================
- *
- * When any operating system starts up, it will go through a sequence
- * of actions that are fairly predictable by an adversary, especially
- * if the start-up does not involve interaction with a human operator.
- * This reduces the actual number of bits of unpredictability in the
- * entropy pool below the value in entropy_count. In order to
- * counteract this effect, it helps to carry information in the
- * entropy pool across shut-downs and start-ups. To do this, put the
- * following lines an appropriate script which is run during the boot
- * sequence:
- *
- * echo "Initializing random number generator..."
- * random_seed=/var/run/random-seed
- * # Carry a random seed from start-up to start-up
- * # Load and then save the whole entropy pool
- * if [ -f $random_seed ]; then
- * cat $random_seed >/dev/urandom
- * else
- * touch $random_seed
- * fi
- * chmod 600 $random_seed
- * dd if=/dev/urandom of=$random_seed count=1 bs=512
- *
- * and the following lines in an appropriate script which is run as
- * the system is shutdown:
- *
- * # Carry a random seed from shut-down to start-up
- * # Save the whole entropy pool
- * echo "Saving random seed..."
- * random_seed=/var/run/random-seed
- * touch $random_seed
- * chmod 600 $random_seed
- * dd if=/dev/urandom of=$random_seed count=1 bs=512
- *
- * For example, on most modern systems using the System V init
- * scripts, such code fragments would be found in
- * /etc/rc.d/init.d/random. On older Linux systems, the correct script
- * location might be in /etc/rcb.d/rc.local or /etc/rc.d/rc.0.
- *
- * Effectively, these commands cause the contents of the entropy pool
- * to be saved at shut-down time and reloaded into the entropy pool at
- * start-up. (The 'dd' in the addition to the bootup script is to
- * make sure that /etc/random-seed is different for every start-up,
- * even if the system crashes without executing rc.0.) Even with
- * complete knowledge of the start-up activities, predicting the state
- * of the entropy pool requires knowledge of the previous history of
- * the system.
- *
- * Configuring the /dev/random driver under Linux
- * ==============================================
- *
- * The /dev/random driver under Linux uses minor numbers 8 and 9 of
- * the /dev/mem major number (#1). So if your system does not have
- * /dev/random and /dev/urandom created already, they can be created
- * by using the commands:
- *
- * mknod /dev/random c 1 8
- * mknod /dev/urandom c 1 9
- *
- * Acknowledgements:
- * =================
- *
- * Ideas for constructing this random number generator were derived
- * from Pretty Good Privacy's random number generator, and from private
- * discussions with Phil Karn. Colin Plumb provided a faster random
- * number generator, which speed up the mixing function of the entropy
- * pool, taken from PGPfone. Dale Worley has also contributed many
- * useful ideas and suggestions to improve this driver.
- *
- * Any flaws in the design are solely my responsibility, and should
- * not be attributed to the Phil, Colin, or any of authors of PGP.
- *
- * Further background information on this topic may be obtained from
- * RFC 1750, "Randomness Recommendations for Security", by Donald
- * Eastlake, Steve Crocker, and Jeff Schiller.
+ * Copyright Theodore Ts'o, 1994, 1995, 1996, 1997, 1998, 1999. All rights reserved.
+ *
+ * This driver produces cryptographically secure pseudorandom data. It is divided
+ * into roughly six sections, each with a section header:
+ *
+ * - Initialization and readiness waiting.
+ * - Fast key erasure RNG, the "crng".
+ * - Entropy accumulation and extraction routines.
+ * - Entropy collection routines.
+ * - Userspace reader/writer interfaces.
+ * - Sysctl interface.
+ *
+ * The high level overview is that there is one input pool, into which
+ * various pieces of data are hashed. Some of that data is then "credited" as
+ * having a certain number of bits of entropy. When enough bits of entropy are
+ * available, the hash is finalized and handed as a key to a stream cipher that
+ * expands it indefinitely for various consumers. This key is periodically
+ * refreshed as the various entropy collectors, described below, add data to the
+ * input pool and credit it. There is currently no Fortuna-like scheduler
+ * involved, which can lead to malicious entropy sources causing a premature
+ * reseed, and the entropy estimates are, at best, conservative guesses.
*/
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
@@ -330,7 +38,7 @@
#include <linux/poll.h>
#include <linux/init.h>
#include <linux/fs.h>
-#include <linux/genhd.h>
+#include <linux/blkdev.h>
#include <linux/interrupt.h>
#include <linux/mm.h>
#include <linux/nodemask.h>
@@ -344,744 +52,947 @@
#include <linux/syscalls.h>
#include <linux/completion.h>
#include <linux/uuid.h>
+#include <linux/uaccess.h>
#include <crypto/chacha.h>
#include <crypto/blake2s.h>
-
#include <asm/processor.h>
-#include <linux/uaccess.h>
#include <asm/irq.h>
#include <asm/irq_regs.h>
#include <asm/io.h>
-#define CREATE_TRACE_POINTS
-#include <trace/events/random.h>
-
-/* #define ADD_INTERRUPT_BENCH */
-
-/*
- * If the entropy count falls under this number of bits, then we
- * should wake up processes which are selecting or polling on write
- * access to /dev/random.
- */
-static int random_write_wakeup_bits = 28 * (1 << 5);
-
-/*
- * Originally, we used a primitive polynomial of degree .poolwords
- * over GF(2). The taps for various sizes are defined below. They
- * were chosen to be evenly spaced except for the last tap, which is 1
- * to get the twisting happening as fast as possible.
- *
- * For the purposes of better mixing, we use the CRC-32 polynomial as
- * well to make a (modified) twisted Generalized Feedback Shift
- * Register. (See M. Matsumoto & Y. Kurita, 1992. Twisted GFSR
- * generators. ACM Transactions on Modeling and Computer Simulation
- * 2(3):179-194. Also see M. Matsumoto & Y. Kurita, 1994. Twisted
- * GFSR generators II. ACM Transactions on Modeling and Computer
- * Simulation 4:254-266)
+/*********************************************************************
*
- * Thanks to Colin Plumb for suggesting this.
+ * Initialization and readiness waiting.
*
- * The mixing operation is much less sensitive than the output hash,
- * where we use BLAKE2s. All that we want of mixing operation is that
- * it be a good non-cryptographic hash; i.e. it not produce collisions
- * when fed "random" data of the sort we expect to see. As long as
- * the pool state differs for different inputs, we have preserved the
- * input entropy and done a good job. The fact that an intelligent
- * attacker can construct inputs that will produce controlled
- * alterations to the pool's state is not important because we don't
- * consider such inputs to contribute any randomness. The only
- * property we need with respect to them is that the attacker can't
- * increase his/her knowledge of the pool's state. Since all
- * additions are reversible (knowing the final state and the input,
- * you can reconstruct the initial state), if an attacker has any
- * uncertainty about the initial state, he/she can only shuffle that
- * uncertainty about, but never cause any collisions (which would
- * decrease the uncertainty).
+ * Much of the RNG infrastructure is devoted to various dependencies
+ * being able to wait until the RNG has collected enough entropy and
+ * is ready for safe consumption.
*
- * Our mixing functions were analyzed by Lacharme, Roeck, Strubel, and
- * Videau in their paper, "The Linux Pseudorandom Number Generator
- * Revisited" (see: http://eprint.iacr.org/2012/251.pdf). In their
- * paper, they point out that we are not using a true Twisted GFSR,
- * since Matsumoto & Kurita used a trinomial feedback polynomial (that
- * is, with only three taps, instead of the six that we are using).
- * As a result, the resulting polynomial is neither primitive nor
- * irreducible, and hence does not have a maximal period over
- * GF(2**32). They suggest a slight change to the generator
- * polynomial which improves the resulting TGFSR polynomial to be
- * irreducible, which we have made here.
- */
-enum poolinfo {
- POOL_WORDS = 128,
- POOL_WORDMASK = POOL_WORDS - 1,
- POOL_BYTES = POOL_WORDS * sizeof(u32),
- POOL_BITS = POOL_BYTES * 8,
- POOL_BITSHIFT = ilog2(POOL_BITS),
-
- /* To allow fractional bits to be tracked, the entropy_count field is
- * denominated in units of 1/8th bits. */
- POOL_ENTROPY_SHIFT = 3,
-#define POOL_ENTROPY_BITS() (input_pool.entropy_count >> POOL_ENTROPY_SHIFT)
- POOL_FRACBITS = POOL_BITS << POOL_ENTROPY_SHIFT,
-
- /* x^128 + x^104 + x^76 + x^51 +x^25 + x + 1 */
- POOL_TAP1 = 104,
- POOL_TAP2 = 76,
- POOL_TAP3 = 51,
- POOL_TAP4 = 25,
- POOL_TAP5 = 1,
-
- EXTRACT_SIZE = BLAKE2S_HASH_SIZE / 2
-};
-
-/*
- * Static global variables
- */
-static DECLARE_WAIT_QUEUE_HEAD(random_write_wait);
-static struct fasync_struct *fasync;
-
-static DEFINE_SPINLOCK(random_ready_list_lock);
-static LIST_HEAD(random_ready_list);
-
-struct crng_state {
- u32 state[16];
- unsigned long init_time;
- spinlock_t lock;
-};
-
-static struct crng_state primary_crng = {
- .lock = __SPIN_LOCK_UNLOCKED(primary_crng.lock),
- .state[0] = CHACHA_CONSTANT_EXPA,
- .state[1] = CHACHA_CONSTANT_ND_3,
- .state[2] = CHACHA_CONSTANT_2_BY,
- .state[3] = CHACHA_CONSTANT_TE_K,
-};
+ *********************************************************************/
/*
* crng_init = 0 --> Uninitialized
* 1 --> Initialized
* 2 --> Initialized from input_pool
*
- * crng_init is protected by primary_crng->lock, and only increases
+ * crng_init is protected by base_crng->lock, and only increases
* its value (from 0->1->2).
*/
static int crng_init = 0;
-static bool crng_need_final_init = false;
#define crng_ready() (likely(crng_init > 1))
-static int crng_init_cnt = 0;
-static unsigned long crng_global_init_time = 0;
-#define CRNG_INIT_CNT_THRESH (2 * CHACHA_KEY_SIZE)
-static void _extract_crng(struct crng_state *crng, u8 out[CHACHA_BLOCK_SIZE]);
-static void _crng_backtrack_protect(struct crng_state *crng,
- u8 tmp[CHACHA_BLOCK_SIZE], int used);
-static void process_random_ready_list(void);
-static void _get_random_bytes(void *buf, int nbytes);
+/* Various types of waiters for crng_init->2 transition. */
+static DECLARE_WAIT_QUEUE_HEAD(crng_init_wait);
+static struct fasync_struct *fasync;
+static DEFINE_SPINLOCK(random_ready_chain_lock);
+static RAW_NOTIFIER_HEAD(random_ready_chain);
+/* Control how we warn userspace. */
static struct ratelimit_state unseeded_warning =
RATELIMIT_STATE_INIT("warn_unseeded_randomness", HZ, 3);
static struct ratelimit_state urandom_warning =
RATELIMIT_STATE_INIT("warn_urandom_randomness", HZ, 3);
-
static int ratelimit_disable __read_mostly;
-
module_param_named(ratelimit_disable, ratelimit_disable, int, 0644);
MODULE_PARM_DESC(ratelimit_disable, "Disable random ratelimit suppression");
-/**********************************************************************
- *
- * OS independent entropy store. Here are the functions which handle
- * storing entropy in an entropy pool.
+/*
+ * Returns whether or not the input pool has been seeded and thus guaranteed
+ * to supply cryptographically secure random numbers. This applies to: the
+ * /dev/urandom device, the get_random_bytes function, and the get_random_{u32,
+ * ,u64,int,long} family of functions.
*
- **********************************************************************/
-
-static u32 input_pool_data[POOL_WORDS] __latent_entropy;
-
-static struct {
- spinlock_t lock;
- u16 add_ptr;
- u16 input_rotate;
- int entropy_count;
-} input_pool = {
- .lock = __SPIN_LOCK_UNLOCKED(input_pool.lock),
-};
+ * Returns: true if the input pool has been seeded.
+ * false if the input pool has not been seeded.
+ */
+bool rng_is_initialized(void)
+{
+ return crng_ready();
+}
+EXPORT_SYMBOL(rng_is_initialized);
-static ssize_t extract_entropy(void *buf, size_t nbytes, int min);
-static ssize_t _extract_entropy(void *buf, size_t nbytes);
+/* Used by wait_for_random_bytes(), and considered an entropy collector, below. */
+static void try_to_generate_entropy(void);
-static void crng_reseed(struct crng_state *crng, bool use_input_pool);
+/*
+ * Wait for the input pool to be seeded and thus guaranteed to supply
+ * cryptographically secure random numbers. This applies to: the /dev/urandom
+ * device, the get_random_bytes function, and the get_random_{u32,u64,int,long}
+ * family of functions. Using any of these functions without first calling
+ * this function forfeits the guarantee of security.
+ *
+ * Returns: 0 if the input pool has been seeded.
+ * -ERESTARTSYS if the function was interrupted by a signal.
+ */
+int wait_for_random_bytes(void)
+{
+ while (!crng_ready()) {
+ int ret;
-static const u32 twist_table[8] = {
- 0x00000000, 0x3b6e20c8, 0x76dc4190, 0x4db26158,
- 0xedb88320, 0xd6d6a3e8, 0x9b64c2b0, 0xa00ae278 };
+ try_to_generate_entropy();
+ ret = wait_event_interruptible_timeout(crng_init_wait, crng_ready(), HZ);
+ if (ret)
+ return ret > 0 ? 0 : ret;
+ }
+ return 0;
+}
+EXPORT_SYMBOL(wait_for_random_bytes);
/*
- * This function adds bytes into the entropy "pool". It does not
- * update the entropy estimate. The caller should call
- * credit_entropy_bits if this is appropriate.
+ * Add a callback function that will be invoked when the input
+ * pool is initialised.
*
- * The pool is stirred with a primitive polynomial of the appropriate
- * degree, and then twisted. We twist by three bits at a time because
- * it's cheap to do so and helps slightly in the expected case where
- * the entropy is concentrated in the low-order bits.
+ * returns: 0 if callback is successfully added
+ * -EALREADY if pool is already initialised (callback not called)
*/
-static void _mix_pool_bytes(const void *in, int nbytes)
+int register_random_ready_notifier(struct notifier_block *nb)
{
- unsigned long i;
- int input_rotate;
- const u8 *bytes = in;
- u32 w;
-
- input_rotate = input_pool.input_rotate;
- i = input_pool.add_ptr;
-
- /* mix one byte at a time to simplify size handling and churn faster */
- while (nbytes--) {
- w = rol32(*bytes++, input_rotate);
- i = (i - 1) & POOL_WORDMASK;
-
- /* XOR in the various taps */
- w ^= input_pool_data[i];
- w ^= input_pool_data[(i + POOL_TAP1) & POOL_WORDMASK];
- w ^= input_pool_data[(i + POOL_TAP2) & POOL_WORDMASK];
- w ^= input_pool_data[(i + POOL_TAP3) & POOL_WORDMASK];
- w ^= input_pool_data[(i + POOL_TAP4) & POOL_WORDMASK];
- w ^= input_pool_data[(i + POOL_TAP5) & POOL_WORDMASK];
-
- /* Mix the result back in with a twist */
- input_pool_data[i] = (w >> 3) ^ twist_table[w & 7];
+ unsigned long flags;
+ int ret = -EALREADY;
- /*
- * Normally, we add 7 bits of rotation to the pool.
- * At the beginning of the pool, add an extra 7 bits
- * rotation, so that successive passes spread the
- * input bits across the pool evenly.
- */
- input_rotate = (input_rotate + (i ? 7 : 14)) & 31;
- }
+ if (crng_ready())
+ return ret;
- input_pool.input_rotate = input_rotate;
- input_pool.add_ptr = i;
+ spin_lock_irqsave(&random_ready_chain_lock, flags);
+ if (!crng_ready())
+ ret = raw_notifier_chain_register(&random_ready_chain, nb);
+ spin_unlock_irqrestore(&random_ready_chain_lock, flags);
+ return ret;
}
-static void __mix_pool_bytes(const void *in, int nbytes)
+/*
+ * Delete a previously registered readiness callback function.
+ */
+int unregister_random_ready_notifier(struct notifier_block *nb)
{
- trace_mix_pool_bytes_nolock(nbytes, _RET_IP_);
- _mix_pool_bytes(in, nbytes);
+ unsigned long flags;
+ int ret;
+
+ spin_lock_irqsave(&random_ready_chain_lock, flags);
+ ret = raw_notifier_chain_unregister(&random_ready_chain, nb);
+ spin_unlock_irqrestore(&random_ready_chain_lock, flags);
+ return ret;
}
-static void mix_pool_bytes(const void *in, int nbytes)
+static void process_random_ready_list(void)
{
unsigned long flags;
- trace_mix_pool_bytes(nbytes, _RET_IP_);
- spin_lock_irqsave(&input_pool.lock, flags);
- _mix_pool_bytes(in, nbytes);
- spin_unlock_irqrestore(&input_pool.lock, flags);
+ spin_lock_irqsave(&random_ready_chain_lock, flags);
+ raw_notifier_call_chain(&random_ready_chain, 0, NULL);
+ spin_unlock_irqrestore(&random_ready_chain_lock, flags);
}
-struct fast_pool {
- u32 pool[4];
- unsigned long last;
- u16 reg_idx;
- u8 count;
-};
+#define warn_unseeded_randomness(previous) \
+ _warn_unseeded_randomness(__func__, (void *)_RET_IP_, (previous))
-/*
- * This is a fast mixing routine used by the interrupt randomness
- * collector. It's hardcoded for an 128 bit pool and assumes that any
- * locks that might be needed are taken by the caller.
- */
-static void fast_mix(struct fast_pool *f)
+static void _warn_unseeded_randomness(const char *func_name, void *caller, void **previous)
{
- u32 a = f->pool[0], b = f->pool[1];
- u32 c = f->pool[2], d = f->pool[3];
+#ifdef CONFIG_WARN_ALL_UNSEEDED_RANDOM
+ const bool print_once = false;
+#else
+ static bool print_once __read_mostly;
+#endif
- a += b; c += d;
- b = rol32(b, 6); d = rol32(d, 27);
- d ^= a; b ^= c;
+ if (print_once || crng_ready() ||
+ (previous && (caller == READ_ONCE(*previous))))
+ return;
+ WRITE_ONCE(*previous, caller);
+#ifndef CONFIG_WARN_ALL_UNSEEDED_RANDOM
+ print_once = true;
+#endif
+ if (__ratelimit(&unseeded_warning))
+ printk_deferred(KERN_NOTICE "random: %s called from %pS with crng_init=%d\n",
+ func_name, caller, crng_init);
+}
- a += b; c += d;
- b = rol32(b, 16); d = rol32(d, 14);
- d ^= a; b ^= c;
- a += b; c += d;
- b = rol32(b, 6); d = rol32(d, 27);
- d ^= a; b ^= c;
+/*********************************************************************
+ *
+ * Fast key erasure RNG, the "crng".
+ *
+ * These functions expand entropy from the entropy extractor into
+ * long streams for external consumption using the "fast key erasure"
+ * RNG described at <https://blog.cr.yp.to/20170723-random.html>.
+ *
+ * There are a few exported interfaces for use by other drivers:
+ *
+ * void get_random_bytes(void *buf, size_t nbytes)
+ * u32 get_random_u32()
+ * u64 get_random_u64()
+ * unsigned int get_random_int()
+ * unsigned long get_random_long()
+ *
+ * These interfaces will return the requested number of random bytes
+ * into the given buffer or as a return value. This is equivalent to
+ * a read from /dev/urandom. The integer family of functions may be
+ * higher performance for one-off random integers, because they do a
+ * bit of buffering.
+ *
+ *********************************************************************/
- a += b; c += d;
- b = rol32(b, 16); d = rol32(d, 14);
- d ^= a; b ^= c;
+enum {
+ CRNG_RESEED_INTERVAL = 300 * HZ,
+ CRNG_INIT_CNT_THRESH = 2 * CHACHA_KEY_SIZE
+};
- f->pool[0] = a; f->pool[1] = b;
- f->pool[2] = c; f->pool[3] = d;
- f->count++;
-}
+static struct {
+ u8 key[CHACHA_KEY_SIZE] __aligned(__alignof__(long));
+ unsigned long birth;
+ unsigned long generation;
+ spinlock_t lock;
+} base_crng = {
+ .lock = __SPIN_LOCK_UNLOCKED(base_crng.lock)
+};
-static void process_random_ready_list(void)
+struct crng {
+ u8 key[CHACHA_KEY_SIZE];
+ unsigned long generation;
+ local_lock_t lock;
+};
+
+static DEFINE_PER_CPU(struct crng, crngs) = {
+ .generation = ULONG_MAX,
+ .lock = INIT_LOCAL_LOCK(crngs.lock),
+};
+
+/* Used by crng_reseed() to extract a new seed from the input pool. */
+static bool drain_entropy(void *buf, size_t nbytes, bool force);
+
+/*
+ * This extracts a new crng key from the input pool, but only if there is a
+ * sufficient amount of entropy available or force is true, in order to
+ * mitigate bruteforcing of newly added bits.
+ */
+static void crng_reseed(bool force)
{
unsigned long flags;
- struct random_ready_callback *rdy, *tmp;
+ unsigned long next_gen;
+ u8 key[CHACHA_KEY_SIZE];
+ bool finalize_init = false;
- spin_lock_irqsave(&random_ready_list_lock, flags);
- list_for_each_entry_safe(rdy, tmp, &random_ready_list, list) {
- struct module *owner = rdy->owner;
+ /* Only reseed if we can, to prevent brute forcing a small amount of new bits. */
+ if (!drain_entropy(key, sizeof(key), force))
+ return;
- list_del_init(&rdy->list);
- rdy->func(rdy);
- module_put(owner);
+ /*
+ * We copy the new key into the base_crng, overwriting the old one,
+ * and update the generation counter. We avoid hitting ULONG_MAX,
+ * because the per-cpu crngs are initialized to ULONG_MAX, so this
+ * forces new CPUs that come online to always initialize.
+ */
+ spin_lock_irqsave(&base_crng.lock, flags);
+ memcpy(base_crng.key, key, sizeof(base_crng.key));
+ next_gen = base_crng.generation + 1;
+ if (next_gen == ULONG_MAX)
+ ++next_gen;
+ WRITE_ONCE(base_crng.generation, next_gen);
+ WRITE_ONCE(base_crng.birth, jiffies);
+ if (!crng_ready()) {
+ crng_init = 2;
+ finalize_init = true;
+ }
+ spin_unlock_irqrestore(&base_crng.lock, flags);
+ memzero_explicit(key, sizeof(key));
+ if (finalize_init) {
+ process_random_ready_list();
+ wake_up_interruptible(&crng_init_wait);
+ kill_fasync(&fasync, SIGIO, POLL_IN);
+ pr_notice("crng init done\n");
+ if (unseeded_warning.missed) {
+ pr_notice("%d get_random_xx warning(s) missed due to ratelimiting\n",
+ unseeded_warning.missed);
+ unseeded_warning.missed = 0;
+ }
+ if (urandom_warning.missed) {
+ pr_notice("%d urandom warning(s) missed due to ratelimiting\n",
+ urandom_warning.missed);
+ urandom_warning.missed = 0;
+ }
}
- spin_unlock_irqrestore(&random_ready_list_lock, flags);
}
/*
- * Credit (or debit) the entropy store with n bits of entropy.
- * Use credit_entropy_bits_safe() if the value comes from userspace
- * or otherwise should be checked for extreme values.
+ * This generates a ChaCha block using the provided key, and then
+ * immediately overwites that key with half the block. It returns
+ * the resultant ChaCha state to the user, along with the second
+ * half of the block containing 32 bytes of random data that may
+ * be used; random_data_len may not be greater than 32.
*/
-static void credit_entropy_bits(int nbits)
+static void crng_fast_key_erasure(u8 key[CHACHA_KEY_SIZE],
+ u32 chacha_state[CHACHA_STATE_WORDS],
+ u8 *random_data, size_t random_data_len)
{
- int entropy_count, entropy_bits, orig;
- int nfrac = nbits << POOL_ENTROPY_SHIFT;
-
- /* Ensure that the multiplication can avoid being 64 bits wide. */
- BUILD_BUG_ON(2 * (POOL_ENTROPY_SHIFT + POOL_BITSHIFT) > 31);
+ u8 first_block[CHACHA_BLOCK_SIZE];
- if (!nbits)
- return;
+ BUG_ON(random_data_len > 32);
-retry:
- entropy_count = orig = READ_ONCE(input_pool.entropy_count);
- if (nfrac < 0) {
- /* Debit */
- entropy_count += nfrac;
- } else {
- /*
- * Credit: we have to account for the possibility of
- * overwriting already present entropy. Even in the
- * ideal case of pure Shannon entropy, new contributions
- * approach the full value asymptotically:
- *
- * entropy <- entropy + (pool_size - entropy) *
- * (1 - exp(-add_entropy/pool_size))
- *
- * For add_entropy <= pool_size/2 then
- * (1 - exp(-add_entropy/pool_size)) >=
- * (add_entropy/pool_size)*0.7869...
- * so we can approximate the exponential with
- * 3/4*add_entropy/pool_size and still be on the
- * safe side by adding at most pool_size/2 at a time.
- *
- * The use of pool_size-2 in the while statement is to
- * prevent rounding artifacts from making the loop
- * arbitrarily long; this limits the loop to log2(pool_size)*2
- * turns no matter how large nbits is.
- */
- int pnfrac = nfrac;
- const int s = POOL_BITSHIFT + POOL_ENTROPY_SHIFT + 2;
- /* The +2 corresponds to the /4 in the denominator */
-
- do {
- unsigned int anfrac = min(pnfrac, POOL_FRACBITS / 2);
- unsigned int add =
- ((POOL_FRACBITS - entropy_count) * anfrac * 3) >> s;
-
- entropy_count += add;
- pnfrac -= anfrac;
- } while (unlikely(entropy_count < POOL_FRACBITS - 2 && pnfrac));
- }
+ chacha_init_consts(chacha_state);
+ memcpy(&chacha_state[4], key, CHACHA_KEY_SIZE);
+ memset(&chacha_state[12], 0, sizeof(u32) * 4);
+ chacha20_block(chacha_state, first_block);
- if (WARN_ON(entropy_count < 0)) {
- pr_warn("negative entropy/overflow: count %d\n", entropy_count);
- entropy_count = 0;
- } else if (entropy_count > POOL_FRACBITS)
- entropy_count = POOL_FRACBITS;
- if (cmpxchg(&input_pool.entropy_count, orig, entropy_count) != orig)
- goto retry;
-
- trace_credit_entropy_bits(nbits, entropy_count >> POOL_ENTROPY_SHIFT, _RET_IP_);
+ memcpy(key, first_block, CHACHA_KEY_SIZE);
+ memcpy(random_data, first_block + CHACHA_KEY_SIZE, random_data_len);
+ memzero_explicit(first_block, sizeof(first_block));
+}
- entropy_bits = entropy_count >> POOL_ENTROPY_SHIFT;
- if (crng_init < 2 && entropy_bits >= 128)
- crng_reseed(&primary_crng, true);
+/*
+ * Return whether the crng seed is considered to be sufficiently
+ * old that a reseeding might be attempted. This happens if the last
+ * reseeding was CRNG_RESEED_INTERVAL ago, or during early boot, at
+ * an interval proportional to the uptime.
+ */
+static bool crng_has_old_seed(void)
+{
+ static bool early_boot = true;
+ unsigned long interval = CRNG_RESEED_INTERVAL;
+
+ if (unlikely(READ_ONCE(early_boot))) {
+ time64_t uptime = ktime_get_seconds();
+ if (uptime >= CRNG_RESEED_INTERVAL / HZ * 2)
+ WRITE_ONCE(early_boot, false);
+ else
+ interval = max_t(unsigned int, 5 * HZ,
+ (unsigned int)uptime / 2 * HZ);
+ }
+ return time_after(jiffies, READ_ONCE(base_crng.birth) + interval);
}
-static int credit_entropy_bits_safe(int nbits)
+/*
+ * This function returns a ChaCha state that you may use for generating
+ * random data. It also returns up to 32 bytes on its own of random data
+ * that may be used; random_data_len may not be greater than 32.
+ */
+static void crng_make_state(u32 chacha_state[CHACHA_STATE_WORDS],
+ u8 *random_data, size_t random_data_len)
{
- if (nbits < 0)
- return -EINVAL;
+ unsigned long flags;
+ struct crng *crng;
- /* Cap the value to avoid overflows */
- nbits = min(nbits, POOL_BITS);
+ BUG_ON(random_data_len > 32);
- credit_entropy_bits(nbits);
- return 0;
-}
+ /*
+ * For the fast path, we check whether we're ready, unlocked first, and
+ * then re-check once locked later. In the case where we're really not
+ * ready, we do fast key erasure with the base_crng directly, because
+ * this is what crng_pre_init_inject() mutates during early init.
+ */
+ if (!crng_ready()) {
+ bool ready;
+
+ spin_lock_irqsave(&base_crng.lock, flags);
+ ready = crng_ready();
+ if (!ready)
+ crng_fast_key_erasure(base_crng.key, chacha_state,
+ random_data, random_data_len);
+ spin_unlock_irqrestore(&base_crng.lock, flags);
+ if (!ready)
+ return;
+ }
-/*********************************************************************
- *
- * CRNG using CHACHA20
- *
- *********************************************************************/
+ /*
+ * If the base_crng is old enough, we try to reseed, which in turn
+ * bumps the generation counter that we check below.
+ */
+ if (unlikely(crng_has_old_seed()))
+ crng_reseed(false);
-#define CRNG_RESEED_INTERVAL (300 * HZ)
+ local_lock_irqsave(&crngs.lock, flags);
+ crng = raw_cpu_ptr(&crngs);
-static DECLARE_WAIT_QUEUE_HEAD(crng_init_wait);
+ /*
+ * If our per-cpu crng is older than the base_crng, then it means
+ * somebody reseeded the base_crng. In that case, we do fast key
+ * erasure on the base_crng, and use its output as the new key
+ * for our per-cpu crng. This brings us up to date with base_crng.
+ */
+ if (unlikely(crng->generation != READ_ONCE(base_crng.generation))) {
+ spin_lock(&base_crng.lock);
+ crng_fast_key_erasure(base_crng.key, chacha_state,
+ crng->key, sizeof(crng->key));
+ crng->generation = base_crng.generation;
+ spin_unlock(&base_crng.lock);
+ }
+
+ /*
+ * Finally, when we've made it this far, our per-cpu crng has an up
+ * to date key, and we can do fast key erasure with it to produce
+ * some random data and a ChaCha state for the caller. All other
+ * branches of this function are "unlikely", so most of the time we
+ * should wind up here immediately.
+ */
+ crng_fast_key_erasure(crng->key, chacha_state, random_data, random_data_len);
+ local_unlock_irqrestore(&crngs.lock, flags);
+}
/*
- * Hack to deal with crazy userspace progams when they are all trying
- * to access /dev/urandom in parallel. The programs are almost
- * certainly doing something terribly wrong, but we'll work around
- * their brain damage.
+ * This function is for crng_init == 0 only. It loads entropy directly
+ * into the crng's key, without going through the input pool. It is,
+ * generally speaking, not very safe, but we use this only at early
+ * boot time when it's better to have something there rather than
+ * nothing.
+ *
+ * If account is set, then the crng_init_cnt counter is incremented.
+ * This shouldn't be set by functions like add_device_randomness(),
+ * where we can't trust the buffer passed to it is guaranteed to be
+ * unpredictable (so it might not have any entropy at all).
+ *
+ * Returns the number of bytes processed from input, which is bounded
+ * by CRNG_INIT_CNT_THRESH if account is true.
*/
-static struct crng_state **crng_node_pool __read_mostly;
+static size_t crng_pre_init_inject(const void *input, size_t len, bool account)
+{
+ static int crng_init_cnt = 0;
+ struct blake2s_state hash;
+ unsigned long flags;
-static void invalidate_batched_entropy(void);
-static void numa_crng_init(void);
+ blake2s_init(&hash, sizeof(base_crng.key));
-static bool trust_cpu __ro_after_init = IS_ENABLED(CONFIG_RANDOM_TRUST_CPU);
-static int __init parse_trust_cpu(char *arg)
-{
- return kstrtobool(arg, &trust_cpu);
-}
-early_param("random.trust_cpu", parse_trust_cpu);
+ spin_lock_irqsave(&base_crng.lock, flags);
+ if (crng_init != 0) {
+ spin_unlock_irqrestore(&base_crng.lock, flags);
+ return 0;
+ }
-static bool crng_init_try_arch(struct crng_state *crng)
-{
- int i;
- bool arch_init = true;
- unsigned long rv;
+ if (account)
+ len = min_t(size_t, len, CRNG_INIT_CNT_THRESH - crng_init_cnt);
- for (i = 4; i < 16; i++) {
- if (!arch_get_random_seed_long(&rv) &&
- !arch_get_random_long(&rv)) {
- rv = random_get_entropy();
- arch_init = false;
+ blake2s_update(&hash, base_crng.key, sizeof(base_crng.key));
+ blake2s_update(&hash, input, len);
+ blake2s_final(&hash, base_crng.key);
+
+ if (account) {
+ crng_init_cnt += len;
+ if (crng_init_cnt >= CRNG_INIT_CNT_THRESH) {
+ ++base_crng.generation;
+ crng_init = 1;
}
- crng->state[i] ^= rv;
}
- return arch_init;
+ spin_unlock_irqrestore(&base_crng.lock, flags);
+
+ if (crng_init == 1)
+ pr_notice("fast init done\n");
+
+ return len;
}
-static bool __init crng_init_try_arch_early(struct crng_state *crng)
+static void _get_random_bytes(void *buf, size_t nbytes)
{
- int i;
- bool arch_init = true;
- unsigned long rv;
+ u32 chacha_state[CHACHA_STATE_WORDS];
+ u8 tmp[CHACHA_BLOCK_SIZE];
+ size_t len;
- for (i = 4; i < 16; i++) {
- if (!arch_get_random_seed_long_early(&rv) &&
- !arch_get_random_long_early(&rv)) {
- rv = random_get_entropy();
- arch_init = false;
+ if (!nbytes)
+ return;
+
+ len = min_t(size_t, 32, nbytes);
+ crng_make_state(chacha_state, buf, len);
+ nbytes -= len;
+ buf += len;
+
+ while (nbytes) {
+ if (nbytes < CHACHA_BLOCK_SIZE) {
+ chacha20_block(chacha_state, tmp);
+ memcpy(buf, tmp, nbytes);
+ memzero_explicit(tmp, sizeof(tmp));
+ break;
}
- crng->state[i] ^= rv;
+
+ chacha20_block(chacha_state, buf);
+ if (unlikely(chacha_state[12] == 0))
+ ++chacha_state[13];
+ nbytes -= CHACHA_BLOCK_SIZE;
+ buf += CHACHA_BLOCK_SIZE;
}
- return arch_init;
+ memzero_explicit(chacha_state, sizeof(chacha_state));
}
-static void crng_initialize_secondary(struct crng_state *crng)
+/*
+ * This function is the exported kernel interface. It returns some
+ * number of good random numbers, suitable for key generation, seeding
+ * TCP sequence numbers, etc. It does not rely on the hardware random
+ * number generator. For random bytes direct from the hardware RNG
+ * (when available), use get_random_bytes_arch(). In order to ensure
+ * that the randomness provided by this function is okay, the function
+ * wait_for_random_bytes() should be called and return 0 at least once
+ * at any point prior.
+ */
+void get_random_bytes(void *buf, size_t nbytes)
{
- chacha_init_consts(crng->state);
- _get_random_bytes(&crng->state[4], sizeof(u32) * 12);
- crng_init_try_arch(crng);
- crng->init_time = jiffies - CRNG_RESEED_INTERVAL - 1;
-}
+ static void *previous;
-static void __init crng_initialize_primary(struct crng_state *crng)
-{
- _extract_entropy(&crng->state[4], sizeof(u32) * 12);
- if (crng_init_try_arch_early(crng) && trust_cpu && crng_init < 2) {
- invalidate_batched_entropy();
- numa_crng_init();
- crng_init = 2;
- pr_notice("crng init done (trusting CPU's manufacturer)\n");
- }
- crng->init_time = jiffies - CRNG_RESEED_INTERVAL - 1;
+ warn_unseeded_randomness(&previous);
+ _get_random_bytes(buf, nbytes);
}
+EXPORT_SYMBOL(get_random_bytes);
-static void crng_finalize_init(struct crng_state *crng)
+static ssize_t get_random_bytes_user(void __user *buf, size_t nbytes)
{
- if (crng != &primary_crng || crng_init >= 2)
- return;
- if (!system_wq) {
- /* We can't call numa_crng_init until we have workqueues,
- * so mark this for processing later. */
- crng_need_final_init = true;
- return;
- }
+ bool large_request = nbytes > 256;
+ ssize_t ret = 0;
+ size_t len;
+ u32 chacha_state[CHACHA_STATE_WORDS];
+ u8 output[CHACHA_BLOCK_SIZE];
- invalidate_batched_entropy();
- numa_crng_init();
- crng_init = 2;
- process_random_ready_list();
- wake_up_interruptible(&crng_init_wait);
- kill_fasync(&fasync, SIGIO, POLL_IN);
- pr_notice("crng init done\n");
- if (unseeded_warning.missed) {
- pr_notice("%d get_random_xx warning(s) missed due to ratelimiting\n",
- unseeded_warning.missed);
- unseeded_warning.missed = 0;
- }
- if (urandom_warning.missed) {
- pr_notice("%d urandom warning(s) missed due to ratelimiting\n",
- urandom_warning.missed);
- urandom_warning.missed = 0;
- }
-}
+ if (!nbytes)
+ return 0;
-static void do_numa_crng_init(struct work_struct *work)
-{
- int i;
- struct crng_state *crng;
- struct crng_state **pool;
-
- pool = kcalloc(nr_node_ids, sizeof(*pool), GFP_KERNEL | __GFP_NOFAIL);
- for_each_online_node(i) {
- crng = kmalloc_node(sizeof(struct crng_state),
- GFP_KERNEL | __GFP_NOFAIL, i);
- spin_lock_init(&crng->lock);
- crng_initialize_secondary(crng);
- pool[i] = crng;
- }
- /* pairs with READ_ONCE() in select_crng() */
- if (cmpxchg_release(&crng_node_pool, NULL, pool) != NULL) {
- for_each_node(i)
- kfree(pool[i]);
- kfree(pool);
- }
-}
+ len = min_t(size_t, 32, nbytes);
+ crng_make_state(chacha_state, output, len);
-static DECLARE_WORK(numa_crng_init_work, do_numa_crng_init);
+ if (copy_to_user(buf, output, len))
+ return -EFAULT;
+ nbytes -= len;
+ buf += len;
+ ret += len;
-static void numa_crng_init(void)
-{
- if (IS_ENABLED(CONFIG_NUMA))
- schedule_work(&numa_crng_init_work);
-}
+ while (nbytes) {
+ if (large_request && need_resched()) {
+ if (signal_pending(current))
+ break;
+ schedule();
+ }
-static struct crng_state *select_crng(void)
-{
- if (IS_ENABLED(CONFIG_NUMA)) {
- struct crng_state **pool;
- int nid = numa_node_id();
-
- /* pairs with cmpxchg_release() in do_numa_crng_init() */
- pool = READ_ONCE(crng_node_pool);
- if (pool && pool[nid])
- return pool[nid];
+ chacha20_block(chacha_state, output);
+ if (unlikely(chacha_state[12] == 0))
+ ++chacha_state[13];
+
+ len = min_t(size_t, nbytes, CHACHA_BLOCK_SIZE);
+ if (copy_to_user(buf, output, len)) {
+ ret = -EFAULT;
+ break;
+ }
+
+ nbytes -= len;
+ buf += len;
+ ret += len;
}
- return &primary_crng;
+ memzero_explicit(chacha_state, sizeof(chacha_state));
+ memzero_explicit(output, sizeof(output));
+ return ret;
}
/*
- * crng_fast_load() can be called by code in the interrupt service
- * path. So we can't afford to dilly-dally. Returns the number of
- * bytes processed from cp.
+ * Batched entropy returns random integers. The quality of the random
+ * number is good as /dev/urandom. In order to ensure that the randomness
+ * provided by this function is okay, the function wait_for_random_bytes()
+ * should be called and return 0 at least once at any point prior.
*/
-static size_t crng_fast_load(const u8 *cp, size_t len)
+struct batched_entropy {
+ union {
+ /*
+ * We make this 1.5x a ChaCha block, so that we get the
+ * remaining 32 bytes from fast key erasure, plus one full
+ * block from the detached ChaCha state. We can increase
+ * the size of this later if needed so long as we keep the
+ * formula of (integer_blocks + 0.5) * CHACHA_BLOCK_SIZE.
+ */
+ u64 entropy_u64[CHACHA_BLOCK_SIZE * 3 / (2 * sizeof(u64))];
+ u32 entropy_u32[CHACHA_BLOCK_SIZE * 3 / (2 * sizeof(u32))];
+ };
+ local_lock_t lock;
+ unsigned long generation;
+ unsigned int position;
+};
+
+
+static DEFINE_PER_CPU(struct batched_entropy, batched_entropy_u64) = {
+ .lock = INIT_LOCAL_LOCK(batched_entropy_u64.lock),
+ .position = UINT_MAX
+};
+
+u64 get_random_u64(void)
{
+ u64 ret;
unsigned long flags;
- u8 *p;
- size_t ret = 0;
+ struct batched_entropy *batch;
+ static void *previous;
+ unsigned long next_gen;
- if (!spin_trylock_irqsave(&primary_crng.lock, flags))
- return 0;
- if (crng_init != 0) {
- spin_unlock_irqrestore(&primary_crng.lock, flags);
- return 0;
- }
- p = (u8 *)&primary_crng.state[4];
- while (len > 0 && crng_init_cnt < CRNG_INIT_CNT_THRESH) {
- p[crng_init_cnt % CHACHA_KEY_SIZE] ^= *cp;
- cp++; crng_init_cnt++; len--; ret++;
- }
- spin_unlock_irqrestore(&primary_crng.lock, flags);
- if (crng_init_cnt >= CRNG_INIT_CNT_THRESH) {
- invalidate_batched_entropy();
- crng_init = 1;
- pr_notice("fast init done\n");
+ warn_unseeded_randomness(&previous);
+
+ local_lock_irqsave(&batched_entropy_u64.lock, flags);
+ batch = raw_cpu_ptr(&batched_entropy_u64);
+
+ next_gen = READ_ONCE(base_crng.generation);
+ if (batch->position >= ARRAY_SIZE(batch->entropy_u64) ||
+ next_gen != batch->generation) {
+ _get_random_bytes(batch->entropy_u64, sizeof(batch->entropy_u64));
+ batch->position = 0;
+ batch->generation = next_gen;
}
+
+ ret = batch->entropy_u64[batch->position];
+ batch->entropy_u64[batch->position] = 0;
+ ++batch->position;
+ local_unlock_irqrestore(&batched_entropy_u64.lock, flags);
return ret;
}
+EXPORT_SYMBOL(get_random_u64);
-/*
- * crng_slow_load() is called by add_device_randomness, which has two
- * attributes. (1) We can't trust the buffer passed to it is
- * guaranteed to be unpredictable (so it might not have any entropy at
- * all), and (2) it doesn't have the performance constraints of
- * crng_fast_load().
- *
- * So we do something more comprehensive which is guaranteed to touch
- * all of the primary_crng's state, and which uses a LFSR with a
- * period of 255 as part of the mixing algorithm. Finally, we do
- * *not* advance crng_init_cnt since buffer we may get may be something
- * like a fixed DMI table (for example), which might very well be
- * unique to the machine, but is otherwise unvarying.
- */
-static int crng_slow_load(const u8 *cp, size_t len)
+static DEFINE_PER_CPU(struct batched_entropy, batched_entropy_u32) = {
+ .lock = INIT_LOCAL_LOCK(batched_entropy_u32.lock),
+ .position = UINT_MAX
+};
+
+u32 get_random_u32(void)
{
+ u32 ret;
unsigned long flags;
- static u8 lfsr = 1;
- u8 tmp;
- unsigned int i, max = CHACHA_KEY_SIZE;
- const u8 *src_buf = cp;
- u8 *dest_buf = (u8 *)&primary_crng.state[4];
+ struct batched_entropy *batch;
+ static void *previous;
+ unsigned long next_gen;
- if (!spin_trylock_irqsave(&primary_crng.lock, flags))
- return 0;
- if (crng_init != 0) {
- spin_unlock_irqrestore(&primary_crng.lock, flags);
- return 0;
- }
- if (len > max)
- max = len;
-
- for (i = 0; i < max; i++) {
- tmp = lfsr;
- lfsr >>= 1;
- if (tmp & 1)
- lfsr ^= 0xE1;
- tmp = dest_buf[i % CHACHA_KEY_SIZE];
- dest_buf[i % CHACHA_KEY_SIZE] ^= src_buf[i % len] ^ lfsr;
- lfsr += (tmp << 3) | (tmp >> 5);
+ warn_unseeded_randomness(&previous);
+
+ local_lock_irqsave(&batched_entropy_u32.lock, flags);
+ batch = raw_cpu_ptr(&batched_entropy_u32);
+
+ next_gen = READ_ONCE(base_crng.generation);
+ if (batch->position >= ARRAY_SIZE(batch->entropy_u32) ||
+ next_gen != batch->generation) {
+ _get_random_bytes(batch->entropy_u32, sizeof(batch->entropy_u32));
+ batch->position = 0;
+ batch->generation = next_gen;
}
- spin_unlock_irqrestore(&primary_crng.lock, flags);
- return 1;
+
+ ret = batch->entropy_u32[batch->position];
+ batch->entropy_u32[batch->position] = 0;
+ ++batch->position;
+ local_unlock_irqrestore(&batched_entropy_u32.lock, flags);
+ return ret;
}
+EXPORT_SYMBOL(get_random_u32);
-static void crng_reseed(struct crng_state *crng, bool use_input_pool)
+#ifdef CONFIG_SMP
+/*
+ * This function is called when the CPU is coming up, with entry
+ * CPUHP_RANDOM_PREPARE, which comes before CPUHP_WORKQUEUE_PREP.
+ */
+int random_prepare_cpu(unsigned int cpu)
{
- unsigned long flags;
- int i, num;
- union {
- u8 block[CHACHA_BLOCK_SIZE];
- u32 key[8];
- } buf;
+ /*
+ * When the cpu comes back online, immediately invalidate both
+ * the per-cpu crng and all batches, so that we serve fresh
+ * randomness.
+ */
+ per_cpu_ptr(&crngs, cpu)->generation = ULONG_MAX;
+ per_cpu_ptr(&batched_entropy_u32, cpu)->position = UINT_MAX;
+ per_cpu_ptr(&batched_entropy_u64, cpu)->position = UINT_MAX;
+ return 0;
+}
+#endif
- if (use_input_pool) {
- num = extract_entropy(&buf, 32, 16);
- if (num == 0)
- return;
- } else {
- _extract_crng(&primary_crng, buf.block);
- _crng_backtrack_protect(&primary_crng, buf.block,
- CHACHA_KEY_SIZE);
- }
- spin_lock_irqsave(&crng->lock, flags);
- for (i = 0; i < 8; i++) {
- unsigned long rv;
- if (!arch_get_random_seed_long(&rv) &&
- !arch_get_random_long(&rv))
- rv = random_get_entropy();
- crng->state[i + 4] ^= buf.key[i] ^ rv;
+/**
+ * randomize_page - Generate a random, page aligned address
+ * @start: The smallest acceptable address the caller will take.
+ * @range: The size of the area, starting at @start, within which the
+ * random address must fall.
+ *
+ * If @start + @range would overflow, @range is capped.
+ *
+ * NOTE: Historical use of randomize_range, which this replaces, presumed that
+ * @start was already page aligned. We now align it regardless.
+ *
+ * Return: A page aligned address within [start, start + range). On error,
+ * @start is returned.
+ */
+unsigned long randomize_page(unsigned long start, unsigned long range)
+{
+ if (!PAGE_ALIGNED(start)) {
+ range -= PAGE_ALIGN(start) - start;
+ start = PAGE_ALIGN(start);
}
- memzero_explicit(&buf, sizeof(buf));
- WRITE_ONCE(crng->init_time, jiffies);
- spin_unlock_irqrestore(&crng->lock, flags);
- crng_finalize_init(crng);
+
+ if (start > ULONG_MAX - range)
+ range = ULONG_MAX - start;
+
+ range >>= PAGE_SHIFT;
+
+ if (range == 0)
+ return start;
+
+ return start + (get_random_long() % range << PAGE_SHIFT);
}
-static void _extract_crng(struct crng_state *crng, u8 out[CHACHA_BLOCK_SIZE])
+/*
+ * This function will use the architecture-specific hardware random
+ * number generator if it is available. It is not recommended for
+ * use. Use get_random_bytes() instead. It returns the number of
+ * bytes filled in.
+ */
+size_t __must_check get_random_bytes_arch(void *buf, size_t nbytes)
{
- unsigned long flags, init_time;
+ size_t left = nbytes;
+ u8 *p = buf;
- if (crng_ready()) {
- init_time = READ_ONCE(crng->init_time);
- if (time_after(READ_ONCE(crng_global_init_time), init_time) ||
- time_after(jiffies, init_time + CRNG_RESEED_INTERVAL))
- crng_reseed(crng, crng == &primary_crng);
+ while (left) {
+ unsigned long v;
+ size_t chunk = min_t(size_t, left, sizeof(unsigned long));
+
+ if (!arch_get_random_long(&v))
+ break;
+
+ memcpy(p, &v, chunk);
+ p += chunk;
+ left -= chunk;
}
- spin_lock_irqsave(&crng->lock, flags);
- chacha20_block(&crng->state[0], out);
- if (crng->state[12] == 0)
- crng->state[13]++;
- spin_unlock_irqrestore(&crng->lock, flags);
+
+ return nbytes - left;
}
+EXPORT_SYMBOL(get_random_bytes_arch);
-static void extract_crng(u8 out[CHACHA_BLOCK_SIZE])
+
+/**********************************************************************
+ *
+ * Entropy accumulation and extraction routines.
+ *
+ * Callers may add entropy via:
+ *
+ * static void mix_pool_bytes(const void *in, size_t nbytes)
+ *
+ * After which, if added entropy should be credited:
+ *
+ * static void credit_entropy_bits(size_t nbits)
+ *
+ * Finally, extract entropy via these two, with the latter one
+ * setting the entropy count to zero and extracting only if there
+ * is POOL_MIN_BITS entropy credited prior or force is true:
+ *
+ * static void extract_entropy(void *buf, size_t nbytes)
+ * static bool drain_entropy(void *buf, size_t nbytes, bool force)
+ *
+ **********************************************************************/
+
+enum {
+ POOL_BITS = BLAKE2S_HASH_SIZE * 8,
+ POOL_MIN_BITS = POOL_BITS /* No point in settling for less. */
+};
+
+/* For notifying userspace should write into /dev/random. */
+static DECLARE_WAIT_QUEUE_HEAD(random_write_wait);
+
+static struct {
+ struct blake2s_state hash;
+ spinlock_t lock;
+ unsigned int entropy_count;
+} input_pool = {
+ .hash.h = { BLAKE2S_IV0 ^ (0x01010000 | BLAKE2S_HASH_SIZE),
+ BLAKE2S_IV1, BLAKE2S_IV2, BLAKE2S_IV3, BLAKE2S_IV4,
+ BLAKE2S_IV5, BLAKE2S_IV6, BLAKE2S_IV7 },
+ .hash.outlen = BLAKE2S_HASH_SIZE,
+ .lock = __SPIN_LOCK_UNLOCKED(input_pool.lock),
+};
+
+static void _mix_pool_bytes(const void *in, size_t nbytes)
{
- _extract_crng(select_crng(), out);
+ blake2s_update(&input_pool.hash, in, nbytes);
}
/*
- * Use the leftover bytes from the CRNG block output (if there is
- * enough) to mutate the CRNG key to provide backtracking protection.
+ * This function adds bytes into the entropy "pool". It does not
+ * update the entropy estimate. The caller should call
+ * credit_entropy_bits if this is appropriate.
*/
-static void _crng_backtrack_protect(struct crng_state *crng,
- u8 tmp[CHACHA_BLOCK_SIZE], int used)
+static void mix_pool_bytes(const void *in, size_t nbytes)
{
unsigned long flags;
- u32 *s, *d;
- int i;
- used = round_up(used, sizeof(u32));
- if (used + CHACHA_KEY_SIZE > CHACHA_BLOCK_SIZE) {
- extract_crng(tmp);
- used = 0;
- }
- spin_lock_irqsave(&crng->lock, flags);
- s = (u32 *)&tmp[used];
- d = &crng->state[4];
- for (i = 0; i < 8; i++)
- *d++ ^= *s++;
- spin_unlock_irqrestore(&crng->lock, flags);
+ spin_lock_irqsave(&input_pool.lock, flags);
+ _mix_pool_bytes(in, nbytes);
+ spin_unlock_irqrestore(&input_pool.lock, flags);
}
-static void crng_backtrack_protect(u8 tmp[CHACHA_BLOCK_SIZE], int used)
+static void credit_entropy_bits(size_t nbits)
{
- _crng_backtrack_protect(select_crng(), tmp, used);
+ unsigned int entropy_count, orig, add;
+
+ if (!nbits)
+ return;
+
+ add = min_t(size_t, nbits, POOL_BITS);
+
+ do {
+ orig = READ_ONCE(input_pool.entropy_count);
+ entropy_count = min_t(unsigned int, POOL_BITS, orig + add);
+ } while (cmpxchg(&input_pool.entropy_count, orig, entropy_count) != orig);
+
+ if (!crng_ready() && entropy_count >= POOL_MIN_BITS)
+ crng_reseed(false);
}
-static ssize_t extract_crng_user(void __user *buf, size_t nbytes)
+/*
+ * This is an HKDF-like construction for using the hashed collected entropy
+ * as a PRF key, that's then expanded block-by-block.
+ */
+static void extract_entropy(void *buf, size_t nbytes)
{
- ssize_t ret = 0, i = CHACHA_BLOCK_SIZE;
- u8 tmp[CHACHA_BLOCK_SIZE] __aligned(4);
- int large_request = (nbytes > 256);
+ unsigned long flags;
+ u8 seed[BLAKE2S_HASH_SIZE], next_key[BLAKE2S_HASH_SIZE];
+ struct {
+ unsigned long rdseed[32 / sizeof(long)];
+ size_t counter;
+ } block;
+ size_t i;
+
+ for (i = 0; i < ARRAY_SIZE(block.rdseed); ++i) {
+ if (!arch_get_random_seed_long(&block.rdseed[i]) &&
+ !arch_get_random_long(&block.rdseed[i]))
+ block.rdseed[i] = random_get_entropy();
+ }
- while (nbytes) {
- if (large_request && need_resched()) {
- if (signal_pending(current)) {
- if (ret == 0)
- ret = -ERESTARTSYS;
- break;
- }
- schedule();
- }
+ spin_lock_irqsave(&input_pool.lock, flags);
- extract_crng(tmp);
- i = min_t(int, nbytes, CHACHA_BLOCK_SIZE);
- if (copy_to_user(buf, tmp, i)) {
- ret = -EFAULT;
- break;
- }
+ /* seed = HASHPRF(last_key, entropy_input) */
+ blake2s_final(&input_pool.hash, seed);
+
+ /* next_key = HASHPRF(seed, RDSEED || 0) */
+ block.counter = 0;
+ blake2s(next_key, (u8 *)&block, seed, sizeof(next_key), sizeof(block), sizeof(seed));
+ blake2s_init_key(&input_pool.hash, BLAKE2S_HASH_SIZE, next_key, sizeof(next_key));
+
+ spin_unlock_irqrestore(&input_pool.lock, flags);
+ memzero_explicit(next_key, sizeof(next_key));
+ while (nbytes) {
+ i = min_t(size_t, nbytes, BLAKE2S_HASH_SIZE);
+ /* output = HASHPRF(seed, RDSEED || ++counter) */
+ ++block.counter;
+ blake2s(buf, (u8 *)&block, seed, i, sizeof(block), sizeof(seed));
nbytes -= i;
buf += i;
- ret += i;
}
- crng_backtrack_protect(tmp, i);
- /* Wipe data just written to memory */
- memzero_explicit(tmp, sizeof(tmp));
+ memzero_explicit(seed, sizeof(seed));
+ memzero_explicit(&block, sizeof(block));
+}
- return ret;
+/*
+ * First we make sure we have POOL_MIN_BITS of entropy in the pool unless force
+ * is true, and then we set the entropy count to zero (but don't actually touch
+ * any data). Only then can we extract a new key with extract_entropy().
+ */
+static bool drain_entropy(void *buf, size_t nbytes, bool force)
+{
+ unsigned int entropy_count;
+ do {
+ entropy_count = READ_ONCE(input_pool.entropy_count);
+ if (!force && entropy_count < POOL_MIN_BITS)
+ return false;
+ } while (cmpxchg(&input_pool.entropy_count, entropy_count, 0) != entropy_count);
+ extract_entropy(buf, nbytes);
+ wake_up_interruptible(&random_write_wait);
+ kill_fasync(&fasync, SIGIO, POLL_OUT);
+ return true;
}
-/*********************************************************************
+
+/**********************************************************************
*
- * Entropy input management
+ * Entropy collection routines.
*
- *********************************************************************/
+ * The following exported functions are used for pushing entropy into
+ * the above entropy accumulation routines:
+ *
+ * void add_device_randomness(const void *buf, size_t size);
+ * void add_input_randomness(unsigned int type, unsigned int code,
+ * unsigned int value);
+ * void add_disk_randomness(struct gendisk *disk);
+ * void add_hwgenerator_randomness(const void *buffer, size_t count,
+ * size_t entropy);
+ * void add_bootloader_randomness(const void *buf, size_t size);
+ * void add_vmfork_randomness(const void *unique_vm_id, size_t size);
+ * void add_interrupt_randomness(int irq);
+ *
+ * add_device_randomness() adds data to the input pool that
+ * is likely to differ between two devices (or possibly even per boot).
+ * This would be things like MAC addresses or serial numbers, or the
+ * read-out of the RTC. This does *not* credit any actual entropy to
+ * the pool, but it initializes the pool to different values for devices
+ * that might otherwise be identical and have very little entropy
+ * available to them (particularly common in the embedded world).
+ *
+ * add_input_randomness() uses the input layer interrupt timing, as well
+ * as the event type information from the hardware.
+ *
+ * add_disk_randomness() uses what amounts to the seek time of block
+ * layer request events, on a per-disk_devt basis, as input to the
+ * entropy pool. Note that high-speed solid state drives with very low
+ * seek times do not make for good sources of entropy, as their seek
+ * times are usually fairly consistent.
+ *
+ * The above two routines try to estimate how many bits of entropy
+ * to credit. They do this by keeping track of the first and second
+ * order deltas of the event timings.
+ *
+ * add_hwgenerator_randomness() is for true hardware RNGs, and will credit
+ * entropy as specified by the caller. If the entropy pool is full it will
+ * block until more entropy is needed.
+ *
+ * add_bootloader_randomness() is the same as add_hwgenerator_randomness() or
+ * add_device_randomness(), depending on whether or not the configuration
+ * option CONFIG_RANDOM_TRUST_BOOTLOADER is set.
+ *
+ * add_vmfork_randomness() adds a unique (but not necessarily secret) ID
+ * representing the current instance of a VM to the pool, without crediting,
+ * and then force-reseeds the crng so that it takes effect immediately.
+ *
+ * add_interrupt_randomness() uses the interrupt timing as random
+ * inputs to the entropy pool. Using the cycle counters and the irq source
+ * as inputs, it feeds the input pool roughly once a second or after 64
+ * interrupts, crediting 1 bit of entropy for whichever comes first.
+ *
+ **********************************************************************/
-/* There is one of these per entropy source */
-struct timer_rand_state {
- cycles_t last_time;
- long last_delta, last_delta2;
-};
+static bool trust_cpu __ro_after_init = IS_ENABLED(CONFIG_RANDOM_TRUST_CPU);
+static int __init parse_trust_cpu(char *arg)
+{
+ return kstrtobool(arg, &trust_cpu);
+}
+early_param("random.trust_cpu", parse_trust_cpu);
-#define INIT_TIMER_RAND_STATE { INITIAL_JIFFIES, };
+/*
+ * The first collection of entropy occurs at system boot while interrupts
+ * are still turned off. Here we push in RDSEED, a timestamp, and utsname().
+ * Depending on the above configuration knob, RDSEED may be considered
+ * sufficient for initialization. Note that much earlier setup may already
+ * have pushed entropy into the input pool by the time we get here.
+ */
+int __init rand_initialize(void)
+{
+ size_t i;
+ ktime_t now = ktime_get_real();
+ bool arch_init = true;
+ unsigned long rv;
+
+ for (i = 0; i < BLAKE2S_BLOCK_SIZE; i += sizeof(rv)) {
+ if (!arch_get_random_seed_long_early(&rv) &&
+ !arch_get_random_long_early(&rv)) {
+ rv = random_get_entropy();
+ arch_init = false;
+ }
+ _mix_pool_bytes(&rv, sizeof(rv));
+ }
+ _mix_pool_bytes(&now, sizeof(now));
+ _mix_pool_bytes(utsname(), sizeof(*(utsname())));
+
+ extract_entropy(base_crng.key, sizeof(base_crng.key));
+ ++base_crng.generation;
+
+ if (arch_init && trust_cpu && !crng_ready()) {
+ crng_init = 2;
+ pr_notice("crng init done (trusting CPU's manufacturer)\n");
+ }
+
+ if (ratelimit_disable) {
+ urandom_warning.interval = 0;
+ unseeded_warning.interval = 0;
+ }
+ return 0;
+}
/*
* Add device- or boot-specific data to the input pool to help
@@ -1091,23 +1002,27 @@ struct timer_rand_state {
* the entropy pool having similar initial state across largely
* identical devices.
*/
-void add_device_randomness(const void *buf, unsigned int size)
+void add_device_randomness(const void *buf, size_t size)
{
- unsigned long time = random_get_entropy() ^ jiffies;
- unsigned long flags;
+ cycles_t cycles = random_get_entropy();
+ unsigned long flags, now = jiffies;
- if (!crng_ready() && size)
- crng_slow_load(buf, size);
+ if (crng_init == 0 && size)
+ crng_pre_init_inject(buf, size, false);
- trace_add_device_randomness(size, _RET_IP_);
spin_lock_irqsave(&input_pool.lock, flags);
+ _mix_pool_bytes(&cycles, sizeof(cycles));
+ _mix_pool_bytes(&now, sizeof(now));
_mix_pool_bytes(buf, size);
- _mix_pool_bytes(&time, sizeof(time));
spin_unlock_irqrestore(&input_pool.lock, flags);
}
EXPORT_SYMBOL(add_device_randomness);
-static struct timer_rand_state input_timer_state = INIT_TIMER_RAND_STATE;
+/* There is one of these per entropy source */
+struct timer_rand_state {
+ unsigned long last_time;
+ long last_delta, last_delta2;
+};
/*
* This function adds entropy to the entropy "pool" by using timing
@@ -1117,29 +1032,26 @@ static struct timer_rand_state input_timer_state = INIT_TIMER_RAND_STATE;
* The number "num" is also added to the pool - it should somehow describe
* the type of event which just happened. This is currently 0-255 for
* keyboard scan codes, and 256 upwards for interrupts.
- *
*/
-static void add_timer_randomness(struct timer_rand_state *state, unsigned num)
+static void add_timer_randomness(struct timer_rand_state *state, unsigned int num)
{
- struct {
- long jiffies;
- unsigned int cycles;
- unsigned int num;
- } sample;
+ cycles_t cycles = random_get_entropy();
+ unsigned long flags, now = jiffies;
long delta, delta2, delta3;
- sample.jiffies = jiffies;
- sample.cycles = random_get_entropy();
- sample.num = num;
- mix_pool_bytes(&sample, sizeof(sample));
+ spin_lock_irqsave(&input_pool.lock, flags);
+ _mix_pool_bytes(&cycles, sizeof(cycles));
+ _mix_pool_bytes(&now, sizeof(now));
+ _mix_pool_bytes(&num, sizeof(num));
+ spin_unlock_irqrestore(&input_pool.lock, flags);
/*
* Calculate number of bits of randomness we probably added.
* We take into account the first, second and third-order deltas
* in order to make our estimate.
*/
- delta = sample.jiffies - READ_ONCE(state->last_time);
- WRITE_ONCE(state->last_time, sample.jiffies);
+ delta = now - READ_ONCE(state->last_time);
+ WRITE_ONCE(state->last_time, now);
delta2 = delta - READ_ONCE(state->last_delta);
WRITE_ONCE(state->last_delta, delta);
@@ -1163,318 +1075,303 @@ static void add_timer_randomness(struct timer_rand_state *state, unsigned num)
* Round down by 1 bit on general principles,
* and limit entropy estimate to 12 bits.
*/
- credit_entropy_bits(min_t(int, fls(delta >> 1), 11));
+ credit_entropy_bits(min_t(unsigned int, fls(delta >> 1), 11));
}
void add_input_randomness(unsigned int type, unsigned int code,
unsigned int value)
{
static unsigned char last_value;
+ static struct timer_rand_state input_timer_state = { INITIAL_JIFFIES };
- /* ignore autorepeat and the like */
+ /* Ignore autorepeat and the like. */
if (value == last_value)
return;
last_value = value;
add_timer_randomness(&input_timer_state,
(type << 4) ^ code ^ (code >> 4) ^ value);
- trace_add_input_randomness(POOL_ENTROPY_BITS());
}
EXPORT_SYMBOL_GPL(add_input_randomness);
-static DEFINE_PER_CPU(struct fast_pool, irq_randomness);
-
-#ifdef ADD_INTERRUPT_BENCH
-static unsigned long avg_cycles, avg_deviation;
-
-#define AVG_SHIFT 8 /* Exponential average factor k=1/256 */
-#define FIXED_1_2 (1 << (AVG_SHIFT - 1))
-
-static void add_interrupt_bench(cycles_t start)
+#ifdef CONFIG_BLOCK
+void add_disk_randomness(struct gendisk *disk)
{
- long delta = random_get_entropy() - start;
-
- /* Use a weighted moving average */
- delta = delta - ((avg_cycles + FIXED_1_2) >> AVG_SHIFT);
- avg_cycles += delta;
- /* And average deviation */
- delta = abs(delta) - ((avg_deviation + FIXED_1_2) >> AVG_SHIFT);
- avg_deviation += delta;
+ if (!disk || !disk->random)
+ return;
+ /* First major is 1, so we get >= 0x200 here. */
+ add_timer_randomness(disk->random, 0x100 + disk_devt(disk));
}
-#else
-#define add_interrupt_bench(x)
-#endif
+EXPORT_SYMBOL_GPL(add_disk_randomness);
-static u32 get_reg(struct fast_pool *f, struct pt_regs *regs)
+void rand_initialize_disk(struct gendisk *disk)
{
- u32 *ptr = (u32 *)regs;
- unsigned int idx;
+ struct timer_rand_state *state;
- if (regs == NULL)
- return 0;
- idx = READ_ONCE(f->reg_idx);
- if (idx >= sizeof(struct pt_regs) / sizeof(u32))
- idx = 0;
- ptr += idx++;
- WRITE_ONCE(f->reg_idx, idx);
- return *ptr;
+ /*
+ * If kzalloc returns null, we just won't use that entropy
+ * source.
+ */
+ state = kzalloc(sizeof(struct timer_rand_state), GFP_KERNEL);
+ if (state) {
+ state->last_time = INITIAL_JIFFIES;
+ disk->random = state;
+ }
}
+#endif
-void add_interrupt_randomness(int irq)
+/*
+ * Interface for in-kernel drivers of true hardware RNGs.
+ * Those devices may produce endless random bits and will be throttled
+ * when our pool is full.
+ */
+void add_hwgenerator_randomness(const void *buffer, size_t count,
+ size_t entropy)
{
- struct fast_pool *fast_pool = this_cpu_ptr(&irq_randomness);
- struct pt_regs *regs = get_irq_regs();
- unsigned long now = jiffies;
- cycles_t cycles = random_get_entropy();
- u32 c_high, j_high;
- u64 ip;
-
- if (cycles == 0)
- cycles = get_reg(fast_pool, regs);
- c_high = (sizeof(cycles) > 4) ? cycles >> 32 : 0;
- j_high = (sizeof(now) > 4) ? now >> 32 : 0;
- fast_pool->pool[0] ^= cycles ^ j_high ^ irq;
- fast_pool->pool[1] ^= now ^ c_high;
- ip = regs ? instruction_pointer(regs) : _RET_IP_;
- fast_pool->pool[2] ^= ip;
- fast_pool->pool[3] ^=
- (sizeof(ip) > 4) ? ip >> 32 : get_reg(fast_pool, regs);
-
- fast_mix(fast_pool);
- add_interrupt_bench(cycles);
-
if (unlikely(crng_init == 0)) {
- if ((fast_pool->count >= 64) &&
- crng_fast_load((u8 *)fast_pool->pool, sizeof(fast_pool->pool)) > 0) {
- fast_pool->count = 0;
- fast_pool->last = now;
- }
- return;
+ size_t ret = crng_pre_init_inject(buffer, count, true);
+ mix_pool_bytes(buffer, ret);
+ count -= ret;
+ buffer += ret;
+ if (!count || crng_init == 0)
+ return;
}
- if ((fast_pool->count < 64) && !time_after(now, fast_pool->last + HZ))
- return;
+ /*
+ * Throttle writing if we're above the trickle threshold.
+ * We'll be woken up again once below POOL_MIN_BITS, when
+ * the calling thread is about to terminate, or once
+ * CRNG_RESEED_INTERVAL has elapsed.
+ */
+ wait_event_interruptible_timeout(random_write_wait,
+ !system_wq || kthread_should_stop() ||
+ input_pool.entropy_count < POOL_MIN_BITS,
+ CRNG_RESEED_INTERVAL);
+ mix_pool_bytes(buffer, count);
+ credit_entropy_bits(entropy);
+}
+EXPORT_SYMBOL_GPL(add_hwgenerator_randomness);
- if (!spin_trylock(&input_pool.lock))
- return;
+/*
+ * Handle random seed passed by bootloader.
+ * If the seed is trustworthy, it would be regarded as hardware RNGs. Otherwise
+ * it would be regarded as device data.
+ * The decision is controlled by CONFIG_RANDOM_TRUST_BOOTLOADER.
+ */
+void add_bootloader_randomness(const void *buf, size_t size)
+{
+ if (IS_ENABLED(CONFIG_RANDOM_TRUST_BOOTLOADER))
+ add_hwgenerator_randomness(buf, size, size * 8);
+ else
+ add_device_randomness(buf, size);
+}
+EXPORT_SYMBOL_GPL(add_bootloader_randomness);
- fast_pool->last = now;
- __mix_pool_bytes(&fast_pool->pool, sizeof(fast_pool->pool));
- spin_unlock(&input_pool.lock);
+#if IS_ENABLED(CONFIG_VMGENID)
+static BLOCKING_NOTIFIER_HEAD(vmfork_chain);
- fast_pool->count = 0;
+/*
+ * Handle a new unique VM ID, which is unique, not secret, so we
+ * don't credit it, but we do immediately force a reseed after so
+ * that it's used by the crng posthaste.
+ */
+void add_vmfork_randomness(const void *unique_vm_id, size_t size)
+{
+ add_device_randomness(unique_vm_id, size);
+ if (crng_ready()) {
+ crng_reseed(true);
+ pr_notice("crng reseeded due to virtual machine fork\n");
+ }
+ blocking_notifier_call_chain(&vmfork_chain, 0, NULL);
+}
+#if IS_MODULE(CONFIG_VMGENID)
+EXPORT_SYMBOL_GPL(add_vmfork_randomness);
+#endif
- /* award one bit for the contents of the fast pool */
- credit_entropy_bits(1);
+int register_random_vmfork_notifier(struct notifier_block *nb)
+{
+ return blocking_notifier_chain_register(&vmfork_chain, nb);
}
-EXPORT_SYMBOL_GPL(add_interrupt_randomness);
+EXPORT_SYMBOL_GPL(register_random_vmfork_notifier);
-#ifdef CONFIG_BLOCK
-void add_disk_randomness(struct gendisk *disk)
+int unregister_random_vmfork_notifier(struct notifier_block *nb)
{
- if (!disk || !disk->random)
- return;
- /* first major is 1, so we get >= 0x200 here */
- add_timer_randomness(disk->random, 0x100 + disk_devt(disk));
- trace_add_disk_randomness(disk_devt(disk), POOL_ENTROPY_BITS());
+ return blocking_notifier_chain_unregister(&vmfork_chain, nb);
}
-EXPORT_SYMBOL_GPL(add_disk_randomness);
+EXPORT_SYMBOL_GPL(unregister_random_vmfork_notifier);
#endif
-/*********************************************************************
- *
- * Entropy extraction routines
- *
- *********************************************************************/
+struct fast_pool {
+ struct work_struct mix;
+ unsigned long pool[4];
+ unsigned long last;
+ unsigned int count;
+ u16 reg_idx;
+};
+
+static DEFINE_PER_CPU(struct fast_pool, irq_randomness) = {
+#ifdef CONFIG_64BIT
+ /* SipHash constants */
+ .pool = { 0x736f6d6570736575UL, 0x646f72616e646f6dUL,
+ 0x6c7967656e657261UL, 0x7465646279746573UL }
+#else
+ /* HalfSipHash constants */
+ .pool = { 0, 0, 0x6c796765U, 0x74656462U }
+#endif
+};
/*
- * This function decides how many bytes to actually take from the
- * given pool, and also debits the entropy count accordingly.
+ * This is [Half]SipHash-1-x, starting from an empty key. Because
+ * the key is fixed, it assumes that its inputs are non-malicious,
+ * and therefore this has no security on its own. s represents the
+ * 128 or 256-bit SipHash state, while v represents a 128-bit input.
*/
-static size_t account(size_t nbytes, int min)
+static void fast_mix(unsigned long s[4], const unsigned long *v)
{
- int entropy_count, orig;
- size_t ibytes, nfrac;
-
- BUG_ON(input_pool.entropy_count > POOL_FRACBITS);
-
- /* Can we pull enough? */
-retry:
- entropy_count = orig = READ_ONCE(input_pool.entropy_count);
- if (WARN_ON(entropy_count < 0)) {
- pr_warn("negative entropy count: count %d\n", entropy_count);
- entropy_count = 0;
- }
-
- /* never pull more than available */
- ibytes = min_t(size_t, nbytes, entropy_count >> (POOL_ENTROPY_SHIFT + 3));
- if (ibytes < min)
- ibytes = 0;
- nfrac = ibytes << (POOL_ENTROPY_SHIFT + 3);
- if ((size_t)entropy_count > nfrac)
- entropy_count -= nfrac;
- else
- entropy_count = 0;
+ size_t i;
- if (cmpxchg(&input_pool.entropy_count, orig, entropy_count) != orig)
- goto retry;
-
- trace_debit_entropy(8 * ibytes);
- if (ibytes && POOL_ENTROPY_BITS() < random_write_wakeup_bits) {
- wake_up_interruptible(&random_write_wait);
- kill_fasync(&fasync, SIGIO, POLL_OUT);
+ for (i = 0; i < 16 / sizeof(long); ++i) {
+ s[3] ^= v[i];
+#ifdef CONFIG_64BIT
+ s[0] += s[1]; s[1] = rol64(s[1], 13); s[1] ^= s[0]; s[0] = rol64(s[0], 32);
+ s[2] += s[3]; s[3] = rol64(s[3], 16); s[3] ^= s[2];
+ s[0] += s[3]; s[3] = rol64(s[3], 21); s[3] ^= s[0];
+ s[2] += s[1]; s[1] = rol64(s[1], 17); s[1] ^= s[2]; s[2] = rol64(s[2], 32);
+#else
+ s[0] += s[1]; s[1] = rol32(s[1], 5); s[1] ^= s[0]; s[0] = rol32(s[0], 16);
+ s[2] += s[3]; s[3] = rol32(s[3], 8); s[3] ^= s[2];
+ s[0] += s[3]; s[3] = rol32(s[3], 7); s[3] ^= s[0];
+ s[2] += s[1]; s[1] = rol32(s[1], 13); s[1] ^= s[2]; s[2] = rol32(s[2], 16);
+#endif
+ s[0] ^= v[i];
}
-
- return ibytes;
}
+#ifdef CONFIG_SMP
/*
- * This function does the actual extraction for extract_entropy.
- *
- * Note: we assume that .poolwords is a multiple of 16 words.
+ * This function is called when the CPU has just come online, with
+ * entry CPUHP_AP_RANDOM_ONLINE, just after CPUHP_AP_WORKQUEUE_ONLINE.
*/
-static void extract_buf(u8 *out)
+int random_online_cpu(unsigned int cpu)
{
- struct blake2s_state state __aligned(__alignof__(unsigned long));
- u8 hash[BLAKE2S_HASH_SIZE];
- unsigned long *salt;
- unsigned long flags;
-
- blake2s_init(&state, sizeof(hash));
-
/*
- * If we have an architectural hardware random number
- * generator, use it for BLAKE2's salt & personal fields.
+ * During CPU shutdown and before CPU onlining, add_interrupt_
+ * randomness() may schedule mix_interrupt_randomness(), and
+ * set the MIX_INFLIGHT flag. However, because the worker can
+ * be scheduled on a different CPU during this period, that
+ * flag will never be cleared. For that reason, we zero out
+ * the flag here, which runs just after workqueues are onlined
+ * for the CPU again. This also has the effect of setting the
+ * irq randomness count to zero so that new accumulated irqs
+ * are fresh.
*/
- for (salt = (unsigned long *)&state.h[4];
- salt < (unsigned long *)&state.h[8]; ++salt) {
- unsigned long v;
- if (!arch_get_random_long(&v))
- break;
- *salt ^= v;
- }
-
- /* Generate a hash across the pool */
- spin_lock_irqsave(&input_pool.lock, flags);
- blake2s_update(&state, (const u8 *)input_pool_data, POOL_BYTES);
- blake2s_final(&state, hash); /* final zeros out state */
+ per_cpu_ptr(&irq_randomness, cpu)->count = 0;
+ return 0;
+}
+#endif
- /*
- * We mix the hash back into the pool to prevent backtracking
- * attacks (where the attacker knows the state of the pool
- * plus the current outputs, and attempts to find previous
- * outputs), unless the hash function can be inverted. By
- * mixing at least a hash worth of hash data back, we make
- * brute-forcing the feedback as hard as brute-forcing the
- * hash.
- */
- __mix_pool_bytes(hash, sizeof(hash));
- spin_unlock_irqrestore(&input_pool.lock, flags);
+static unsigned long get_reg(struct fast_pool *f, struct pt_regs *regs)
+{
+ unsigned long *ptr = (unsigned long *)regs;
+ unsigned int idx;
- /* Note that EXTRACT_SIZE is half of hash size here, because above
- * we've dumped the full length back into mixer. By reducing the
- * amount that we emit, we retain a level of forward secrecy.
- */
- memcpy(out, hash, EXTRACT_SIZE);
- memzero_explicit(hash, sizeof(hash));
+ if (regs == NULL)
+ return 0;
+ idx = READ_ONCE(f->reg_idx);
+ if (idx >= sizeof(struct pt_regs) / sizeof(unsigned long))
+ idx = 0;
+ ptr += idx++;
+ WRITE_ONCE(f->reg_idx, idx);
+ return *ptr;
}
-static ssize_t _extract_entropy(void *buf, size_t nbytes)
+static void mix_interrupt_randomness(struct work_struct *work)
{
- ssize_t ret = 0, i;
- u8 tmp[EXTRACT_SIZE];
+ struct fast_pool *fast_pool = container_of(work, struct fast_pool, mix);
+ /*
+ * The size of the copied stack pool is explicitly 16 bytes so that we
+ * tax mix_pool_byte()'s compression function the same amount on all
+ * platforms. This means on 64-bit we copy half the pool into this,
+ * while on 32-bit we copy all of it. The entropy is supposed to be
+ * sufficiently dispersed between bits that in the sponge-like
+ * half case, on average we don't wind up "losing" some.
+ */
+ u8 pool[16];
- while (nbytes) {
- extract_buf(tmp);
- i = min_t(int, nbytes, EXTRACT_SIZE);
- memcpy(buf, tmp, i);
- nbytes -= i;
- buf += i;
- ret += i;
+ /* Check to see if we're running on the wrong CPU due to hotplug. */
+ local_irq_disable();
+ if (fast_pool != this_cpu_ptr(&irq_randomness)) {
+ local_irq_enable();
+ return;
}
- /* Wipe data just returned from memory */
- memzero_explicit(tmp, sizeof(tmp));
+ /*
+ * Copy the pool to the stack so that the mixer always has a
+ * consistent view, before we reenable irqs again.
+ */
+ memcpy(pool, fast_pool->pool, sizeof(pool));
+ fast_pool->count = 0;
+ fast_pool->last = jiffies;
+ local_irq_enable();
- return ret;
-}
+ if (unlikely(crng_init == 0)) {
+ crng_pre_init_inject(pool, sizeof(pool), true);
+ mix_pool_bytes(pool, sizeof(pool));
+ } else {
+ mix_pool_bytes(pool, sizeof(pool));
+ credit_entropy_bits(1);
+ }
-/*
- * This function extracts randomness from the "entropy pool", and
- * returns it in a buffer.
- *
- * The min parameter specifies the minimum amount we can pull before
- * failing to avoid races that defeat catastrophic reseeding.
- */
-static ssize_t extract_entropy(void *buf, size_t nbytes, int min)
-{
- trace_extract_entropy(nbytes, POOL_ENTROPY_BITS(), _RET_IP_);
- nbytes = account(nbytes, min);
- return _extract_entropy(buf, nbytes);
+ memzero_explicit(pool, sizeof(pool));
}
-#define warn_unseeded_randomness(previous) \
- _warn_unseeded_randomness(__func__, (void *)_RET_IP_, (previous))
-
-static void _warn_unseeded_randomness(const char *func_name, void *caller, void **previous)
+void add_interrupt_randomness(int irq)
{
-#ifdef CONFIG_WARN_ALL_UNSEEDED_RANDOM
- const bool print_once = false;
-#else
- static bool print_once __read_mostly;
-#endif
-
- if (print_once || crng_ready() ||
- (previous && (caller == READ_ONCE(*previous))))
- return;
- WRITE_ONCE(*previous, caller);
-#ifndef CONFIG_WARN_ALL_UNSEEDED_RANDOM
- print_once = true;
-#endif
- if (__ratelimit(&unseeded_warning))
- printk_deferred(KERN_NOTICE "random: %s called from %pS with crng_init=%d\n",
- func_name, caller, crng_init);
-}
+ enum { MIX_INFLIGHT = 1U << 31 };
+ cycles_t cycles = random_get_entropy();
+ unsigned long now = jiffies;
+ struct fast_pool *fast_pool = this_cpu_ptr(&irq_randomness);
+ struct pt_regs *regs = get_irq_regs();
+ unsigned int new_count;
+ union {
+ u32 u32[4];
+ u64 u64[2];
+ unsigned long longs[16 / sizeof(long)];
+ } irq_data;
-/*
- * This function is the exported kernel interface. It returns some
- * number of good random numbers, suitable for key generation, seeding
- * TCP sequence numbers, etc. It does not rely on the hardware random
- * number generator. For random bytes direct from the hardware RNG
- * (when available), use get_random_bytes_arch(). In order to ensure
- * that the randomness provided by this function is okay, the function
- * wait_for_random_bytes() should be called and return 0 at least once
- * at any point prior.
- */
-static void _get_random_bytes(void *buf, int nbytes)
-{
- u8 tmp[CHACHA_BLOCK_SIZE] __aligned(4);
+ if (cycles == 0)
+ cycles = get_reg(fast_pool, regs);
- trace_get_random_bytes(nbytes, _RET_IP_);
+ if (sizeof(cycles) == 8)
+ irq_data.u64[0] = cycles ^ rol64(now, 32) ^ irq;
+ else {
+ irq_data.u32[0] = cycles ^ irq;
+ irq_data.u32[1] = now;
+ }
- while (nbytes >= CHACHA_BLOCK_SIZE) {
- extract_crng(buf);
- buf += CHACHA_BLOCK_SIZE;
- nbytes -= CHACHA_BLOCK_SIZE;
+ if (sizeof(unsigned long) == 8)
+ irq_data.u64[1] = regs ? instruction_pointer(regs) : _RET_IP_;
+ else {
+ irq_data.u32[2] = regs ? instruction_pointer(regs) : _RET_IP_;
+ irq_data.u32[3] = get_reg(fast_pool, regs);
}
- if (nbytes > 0) {
- extract_crng(tmp);
- memcpy(buf, tmp, nbytes);
- crng_backtrack_protect(tmp, nbytes);
- } else
- crng_backtrack_protect(tmp, CHACHA_BLOCK_SIZE);
- memzero_explicit(tmp, sizeof(tmp));
-}
+ fast_mix(fast_pool->pool, irq_data.longs);
+ new_count = ++fast_pool->count;
-void get_random_bytes(void *buf, int nbytes)
-{
- static void *previous;
+ if (new_count & MIX_INFLIGHT)
+ return;
- warn_unseeded_randomness(&previous);
- _get_random_bytes(buf, nbytes);
+ if (new_count < 64 && (!time_after(now, fast_pool->last + HZ) ||
+ unlikely(crng_init == 0)))
+ return;
+
+ if (unlikely(!fast_pool->mix.func))
+ INIT_WORK(&fast_pool->mix, mix_interrupt_randomness);
+ fast_pool->count |= MIX_INFLIGHT;
+ queue_work_on(raw_smp_processor_id(), system_highpri_wq, &fast_pool->mix);
}
-EXPORT_SYMBOL(get_random_bytes);
+EXPORT_SYMBOL_GPL(add_interrupt_randomness);
/*
* Each time the timer fires, we expect that we got an unpredictable
@@ -1501,238 +1398,134 @@ static void entropy_timer(struct timer_list *t)
static void try_to_generate_entropy(void)
{
struct {
- unsigned long now;
+ cycles_t cycles;
struct timer_list timer;
} stack;
- stack.now = random_get_entropy();
+ stack.cycles = random_get_entropy();
/* Slow counter - or none. Don't even bother */
- if (stack.now == random_get_entropy())
+ if (stack.cycles == random_get_entropy())
return;
timer_setup_on_stack(&stack.timer, entropy_timer, 0);
- while (!crng_ready()) {
+ while (!crng_ready() && !signal_pending(current)) {
if (!timer_pending(&stack.timer))
mod_timer(&stack.timer, jiffies + 1);
- mix_pool_bytes(&stack.now, sizeof(stack.now));
+ mix_pool_bytes(&stack.cycles, sizeof(stack.cycles));
schedule();
- stack.now = random_get_entropy();
+ stack.cycles = random_get_entropy();
}
del_timer_sync(&stack.timer);
destroy_timer_on_stack(&stack.timer);
- mix_pool_bytes(&stack.now, sizeof(stack.now));
+ mix_pool_bytes(&stack.cycles, sizeof(stack.cycles));
}
-/*
- * Wait for the urandom pool to be seeded and thus guaranteed to supply
- * cryptographically secure random numbers. This applies to: the /dev/urandom
- * device, the get_random_bytes function, and the get_random_{u32,u64,int,long}
- * family of functions. Using any of these functions without first calling
- * this function forfeits the guarantee of security.
- *
- * Returns: 0 if the urandom pool has been seeded.
- * -ERESTARTSYS if the function was interrupted by a signal.
- */
-int wait_for_random_bytes(void)
-{
- if (likely(crng_ready()))
- return 0;
-
- do {
- int ret;
- ret = wait_event_interruptible_timeout(crng_init_wait, crng_ready(), HZ);
- if (ret)
- return ret > 0 ? 0 : ret;
-
- try_to_generate_entropy();
- } while (!crng_ready());
- return 0;
-}
-EXPORT_SYMBOL(wait_for_random_bytes);
-
-/*
- * Returns whether or not the urandom pool has been seeded and thus guaranteed
- * to supply cryptographically secure random numbers. This applies to: the
- * /dev/urandom device, the get_random_bytes function, and the get_random_{u32,
- * ,u64,int,long} family of functions.
+/**********************************************************************
*
- * Returns: true if the urandom pool has been seeded.
- * false if the urandom pool has not been seeded.
- */
-bool rng_is_initialized(void)
-{
- return crng_ready();
-}
-EXPORT_SYMBOL(rng_is_initialized);
-
-/*
- * Add a callback function that will be invoked when the nonblocking
- * pool is initialised.
+ * Userspace reader/writer interfaces.
*
- * returns: 0 if callback is successfully added
- * -EALREADY if pool is already initialised (callback not called)
- * -ENOENT if module for callback is not alive
- */
-int add_random_ready_callback(struct random_ready_callback *rdy)
-{
- struct module *owner;
- unsigned long flags;
- int err = -EALREADY;
-
- if (crng_ready())
- return err;
-
- owner = rdy->owner;
- if (!try_module_get(owner))
- return -ENOENT;
-
- spin_lock_irqsave(&random_ready_list_lock, flags);
- if (crng_ready())
- goto out;
-
- owner = NULL;
-
- list_add(&rdy->list, &random_ready_list);
- err = 0;
-
-out:
- spin_unlock_irqrestore(&random_ready_list_lock, flags);
-
- module_put(owner);
-
- return err;
-}
-EXPORT_SYMBOL(add_random_ready_callback);
+ * getrandom(2) is the primary modern interface into the RNG and should
+ * be used in preference to anything else.
+ *
+ * Reading from /dev/random has the same functionality as calling
+ * getrandom(2) with flags=0. In earlier versions, however, it had
+ * vastly different semantics and should therefore be avoided, to
+ * prevent backwards compatibility issues.
+ *
+ * Reading from /dev/urandom has the same functionality as calling
+ * getrandom(2) with flags=GRND_INSECURE. Because it does not block
+ * waiting for the RNG to be ready, it should not be used.
+ *
+ * Writing to either /dev/random or /dev/urandom adds entropy to
+ * the input pool but does not credit it.
+ *
+ * Polling on /dev/random indicates when the RNG is initialized, on
+ * the read side, and when it wants new entropy, on the write side.
+ *
+ * Both /dev/random and /dev/urandom have the same set of ioctls for
+ * adding entropy, getting the entropy count, zeroing the count, and
+ * reseeding the crng.
+ *
+ **********************************************************************/
-/*
- * Delete a previously registered readiness callback function.
- */
-void del_random_ready_callback(struct random_ready_callback *rdy)
+SYSCALL_DEFINE3(getrandom, char __user *, buf, size_t, count, unsigned int,
+ flags)
{
- unsigned long flags;
- struct module *owner = NULL;
-
- spin_lock_irqsave(&random_ready_list_lock, flags);
- if (!list_empty(&rdy->list)) {
- list_del_init(&rdy->list);
- owner = rdy->owner;
- }
- spin_unlock_irqrestore(&random_ready_list_lock, flags);
-
- module_put(owner);
-}
-EXPORT_SYMBOL(del_random_ready_callback);
+ if (flags & ~(GRND_NONBLOCK | GRND_RANDOM | GRND_INSECURE))
+ return -EINVAL;
-/*
- * This function will use the architecture-specific hardware random
- * number generator if it is available. The arch-specific hw RNG will
- * almost certainly be faster than what we can do in software, but it
- * is impossible to verify that it is implemented securely (as
- * opposed, to, say, the AES encryption of a sequence number using a
- * key known by the NSA). So it's useful if we need the speed, but
- * only if we're willing to trust the hardware manufacturer not to
- * have put in a back door.
- *
- * Return number of bytes filled in.
- */
-int __must_check get_random_bytes_arch(void *buf, int nbytes)
-{
- int left = nbytes;
- u8 *p = buf;
+ /*
+ * Requesting insecure and blocking randomness at the same time makes
+ * no sense.
+ */
+ if ((flags & (GRND_INSECURE | GRND_RANDOM)) == (GRND_INSECURE | GRND_RANDOM))
+ return -EINVAL;
- trace_get_random_bytes_arch(left, _RET_IP_);
- while (left) {
- unsigned long v;
- int chunk = min_t(int, left, sizeof(unsigned long));
+ if (count > INT_MAX)
+ count = INT_MAX;
- if (!arch_get_random_long(&v))
- break;
+ if (!(flags & GRND_INSECURE) && !crng_ready()) {
+ int ret;
- memcpy(p, &v, chunk);
- p += chunk;
- left -= chunk;
+ if (flags & GRND_NONBLOCK)
+ return -EAGAIN;
+ ret = wait_for_random_bytes();
+ if (unlikely(ret))
+ return ret;
}
-
- return nbytes - left;
+ return get_random_bytes_user(buf, count);
}
-EXPORT_SYMBOL(get_random_bytes_arch);
-/*
- * init_std_data - initialize pool with system data
- *
- * This function clears the pool's entropy count and mixes some system
- * data into the pool to prepare it for use. The pool is not cleared
- * as that can only decrease the entropy in the pool.
- */
-static void __init init_std_data(void)
+static __poll_t random_poll(struct file *file, poll_table *wait)
{
- int i;
- ktime_t now = ktime_get_real();
- unsigned long rv;
-
- mix_pool_bytes(&now, sizeof(now));
- for (i = POOL_BYTES; i > 0; i -= sizeof(rv)) {
- if (!arch_get_random_seed_long(&rv) &&
- !arch_get_random_long(&rv))
- rv = random_get_entropy();
- mix_pool_bytes(&rv, sizeof(rv));
- }
- mix_pool_bytes(utsname(), sizeof(*(utsname())));
-}
+ __poll_t mask;
-/*
- * Note that setup_arch() may call add_device_randomness()
- * long before we get here. This allows seeding of the pools
- * with some platform dependent data very early in the boot
- * process. But it limits our options here. We must use
- * statically allocated structures that already have all
- * initializations complete at compile time. We should also
- * take care not to overwrite the precious per platform data
- * we were given.
- */
-int __init rand_initialize(void)
-{
- init_std_data();
- if (crng_need_final_init)
- crng_finalize_init(&primary_crng);
- crng_initialize_primary(&primary_crng);
- crng_global_init_time = jiffies;
- if (ratelimit_disable) {
- urandom_warning.interval = 0;
- unseeded_warning.interval = 0;
- }
- return 0;
+ poll_wait(file, &crng_init_wait, wait);
+ poll_wait(file, &random_write_wait, wait);
+ mask = 0;
+ if (crng_ready())
+ mask |= EPOLLIN | EPOLLRDNORM;
+ if (input_pool.entropy_count < POOL_MIN_BITS)
+ mask |= EPOLLOUT | EPOLLWRNORM;
+ return mask;
}
-#ifdef CONFIG_BLOCK
-void rand_initialize_disk(struct gendisk *disk)
+static int write_pool(const char __user *ubuf, size_t count)
{
- struct timer_rand_state *state;
+ size_t len;
+ int ret = 0;
+ u8 block[BLAKE2S_BLOCK_SIZE];
- /*
- * If kzalloc returns null, we just won't use that entropy
- * source.
- */
- state = kzalloc(sizeof(struct timer_rand_state), GFP_KERNEL);
- if (state) {
- state->last_time = INITIAL_JIFFIES;
- disk->random = state;
+ while (count) {
+ len = min(count, sizeof(block));
+ if (copy_from_user(block, ubuf, len)) {
+ ret = -EFAULT;
+ goto out;
+ }
+ count -= len;
+ ubuf += len;
+ mix_pool_bytes(block, len);
+ cond_resched();
}
+
+out:
+ memzero_explicit(block, sizeof(block));
+ return ret;
}
-#endif
-static ssize_t urandom_read_nowarn(struct file *file, char __user *buf,
- size_t nbytes, loff_t *ppos)
+static ssize_t random_write(struct file *file, const char __user *buffer,
+ size_t count, loff_t *ppos)
{
int ret;
- nbytes = min_t(size_t, nbytes, INT_MAX >> (POOL_ENTROPY_SHIFT + 3));
- ret = extract_crng_user(buf, nbytes);
- trace_urandom_read(8 * nbytes, 0, POOL_ENTROPY_BITS());
- return ret;
+ ret = write_pool(buffer, count);
+ if (ret)
+ return ret;
+
+ return (ssize_t)count;
}
static ssize_t urandom_read(struct file *file, char __user *buf, size_t nbytes,
@@ -1747,7 +1540,7 @@ static ssize_t urandom_read(struct file *file, char __user *buf, size_t nbytes,
current->comm, nbytes);
}
- return urandom_read_nowarn(file, buf, nbytes, ppos);
+ return get_random_bytes_user(buf, nbytes);
}
static ssize_t random_read(struct file *file, char __user *buf, size_t nbytes,
@@ -1758,62 +1551,7 @@ static ssize_t random_read(struct file *file, char __user *buf, size_t nbytes,
ret = wait_for_random_bytes();
if (ret != 0)
return ret;
- return urandom_read_nowarn(file, buf, nbytes, ppos);
-}
-
-static __poll_t random_poll(struct file *file, poll_table *wait)
-{
- __poll_t mask;
-
- poll_wait(file, &crng_init_wait, wait);
- poll_wait(file, &random_write_wait, wait);
- mask = 0;
- if (crng_ready())
- mask |= EPOLLIN | EPOLLRDNORM;
- if (POOL_ENTROPY_BITS() < random_write_wakeup_bits)
- mask |= EPOLLOUT | EPOLLWRNORM;
- return mask;
-}
-
-static int write_pool(const char __user *buffer, size_t count)
-{
- size_t bytes;
- u32 t, buf[16];
- const char __user *p = buffer;
-
- while (count > 0) {
- int b, i = 0;
-
- bytes = min(count, sizeof(buf));
- if (copy_from_user(&buf, p, bytes))
- return -EFAULT;
-
- for (b = bytes; b > 0; b -= sizeof(u32), i++) {
- if (!arch_get_random_int(&t))
- break;
- buf[i] ^= t;
- }
-
- count -= bytes;
- p += bytes;
-
- mix_pool_bytes(buf, bytes);
- cond_resched();
- }
-
- return 0;
-}
-
-static ssize_t random_write(struct file *file, const char __user *buffer,
- size_t count, loff_t *ppos)
-{
- size_t ret;
-
- ret = write_pool(buffer, count);
- if (ret)
- return ret;
-
- return (ssize_t)count;
+ return get_random_bytes_user(buf, nbytes);
}
static long random_ioctl(struct file *f, unsigned int cmd, unsigned long arg)
@@ -1824,9 +1562,8 @@ static long random_ioctl(struct file *f, unsigned int cmd, unsigned long arg)
switch (cmd) {
case RNDGETENTCNT:
- /* inherently racy, no point locking */
- ent_count = POOL_ENTROPY_BITS();
- if (put_user(ent_count, p))
+ /* Inherently racy, no point locking. */
+ if (put_user(input_pool.entropy_count, p))
return -EFAULT;
return 0;
case RNDADDTOENTCNT:
@@ -1834,7 +1571,10 @@ static long random_ioctl(struct file *f, unsigned int cmd, unsigned long arg)
return -EPERM;
if (get_user(ent_count, p))
return -EFAULT;
- return credit_entropy_bits_safe(ent_count);
+ if (ent_count < 0)
+ return -EINVAL;
+ credit_entropy_bits(ent_count);
+ return 0;
case RNDADDENTROPY:
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
@@ -1847,7 +1587,8 @@ static long random_ioctl(struct file *f, unsigned int cmd, unsigned long arg)
retval = write_pool((const char __user *)p, size);
if (retval < 0)
return retval;
- return credit_entropy_bits_safe(ent_count);
+ credit_entropy_bits(ent_count);
+ return 0;
case RNDZAPENTCNT:
case RNDCLEARPOOL:
/*
@@ -1856,15 +1597,17 @@ static long random_ioctl(struct file *f, unsigned int cmd, unsigned long arg)
*/
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
- input_pool.entropy_count = 0;
+ if (xchg(&input_pool.entropy_count, 0) >= POOL_MIN_BITS) {
+ wake_up_interruptible(&random_write_wait);
+ kill_fasync(&fasync, SIGIO, POLL_OUT);
+ }
return 0;
case RNDRESEEDCRNG:
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
- if (crng_init < 2)
+ if (!crng_ready())
return -ENODATA;
- crng_reseed(&primary_crng, true);
- WRITE_ONCE(crng_global_init_time, jiffies - 1);
+ crng_reseed(false);
return 0;
default:
return -EINVAL;
@@ -1895,37 +1638,34 @@ const struct file_operations urandom_fops = {
.llseek = noop_llseek,
};
-SYSCALL_DEFINE3(getrandom, char __user *, buf, size_t, count, unsigned int,
- flags)
-{
- int ret;
-
- if (flags & ~(GRND_NONBLOCK | GRND_RANDOM | GRND_INSECURE))
- return -EINVAL;
-
- /*
- * Requesting insecure and blocking randomness at the same time makes
- * no sense.
- */
- if ((flags & (GRND_INSECURE | GRND_RANDOM)) == (GRND_INSECURE | GRND_RANDOM))
- return -EINVAL;
-
- if (count > INT_MAX)
- count = INT_MAX;
-
- if (!(flags & GRND_INSECURE) && !crng_ready()) {
- if (flags & GRND_NONBLOCK)
- return -EAGAIN;
- ret = wait_for_random_bytes();
- if (unlikely(ret))
- return ret;
- }
- return urandom_read_nowarn(NULL, buf, count, NULL);
-}
/********************************************************************
*
- * Sysctl interface
+ * Sysctl interface.
+ *
+ * These are partly unused legacy knobs with dummy values to not break
+ * userspace and partly still useful things. They are usually accessible
+ * in /proc/sys/kernel/random/ and are as follows:
+ *
+ * - boot_id - a UUID representing the current boot.
+ *
+ * - uuid - a random UUID, different each time the file is read.
+ *
+ * - poolsize - the number of bits of entropy that the input pool can
+ * hold, tied to the POOL_BITS constant.
+ *
+ * - entropy_avail - the number of bits of entropy currently in the
+ * input pool. Always <= poolsize.
+ *
+ * - write_wakeup_threshold - the amount of entropy in the input pool
+ * below which write polls to /dev/random will unblock, requesting
+ * more entropy, tied to the POOL_MIN_BITS constant. It is writable
+ * to avoid breaking old userspaces, but writing to it does not
+ * change any behavior of the RNG.
+ *
+ * - urandom_min_reseed_secs - fixed to the value CRNG_RESEED_INTERVAL.
+ * It is writable to avoid breaking old userspaces, but writing
+ * to it does not change any behavior of the RNG.
*
********************************************************************/
@@ -1933,25 +1673,28 @@ SYSCALL_DEFINE3(getrandom, char __user *, buf, size_t, count, unsigned int,
#include <linux/sysctl.h>
-static int min_write_thresh;
-static int max_write_thresh = POOL_BITS;
-static int random_min_urandom_seed = 60;
-static char sysctl_bootid[16];
+static int sysctl_random_min_urandom_seed = CRNG_RESEED_INTERVAL / HZ;
+static int sysctl_random_write_wakeup_bits = POOL_MIN_BITS;
+static int sysctl_poolsize = POOL_BITS;
+static u8 sysctl_bootid[UUID_SIZE];
/*
* This function is used to return both the bootid UUID, and random
- * UUID. The difference is in whether table->data is NULL; if it is,
+ * UUID. The difference is in whether table->data is NULL; if it is,
* then a new UUID is generated and returned to the user.
- *
- * If the user accesses this via the proc interface, the UUID will be
- * returned as an ASCII string in the standard UUID format; if via the
- * sysctl system call, as 16 bytes of binary data.
*/
static int proc_do_uuid(struct ctl_table *table, int write, void *buffer,
size_t *lenp, loff_t *ppos)
{
- struct ctl_table fake_table;
- unsigned char buf[64], tmp_uuid[16], *uuid;
+ u8 tmp_uuid[UUID_SIZE], *uuid;
+ char uuid_string[UUID_STRING_LEN + 1];
+ struct ctl_table fake_table = {
+ .data = uuid_string,
+ .maxlen = UUID_STRING_LEN
+ };
+
+ if (write)
+ return -EPERM;
uuid = table->data;
if (!uuid) {
@@ -1966,32 +1709,17 @@ static int proc_do_uuid(struct ctl_table *table, int write, void *buffer,
spin_unlock(&bootid_spinlock);
}
- sprintf(buf, "%pU", uuid);
-
- fake_table.data = buf;
- fake_table.maxlen = sizeof(buf);
-
- return proc_dostring(&fake_table, write, buffer, lenp, ppos);
+ snprintf(uuid_string, sizeof(uuid_string), "%pU", uuid);
+ return proc_dostring(&fake_table, 0, buffer, lenp, ppos);
}
-/*
- * Return entropy available scaled to integral bits
- */
-static int proc_do_entropy(struct ctl_table *table, int write, void *buffer,
- size_t *lenp, loff_t *ppos)
+/* The same as proc_dointvec, but writes don't change anything. */
+static int proc_do_rointvec(struct ctl_table *table, int write, void *buffer,
+ size_t *lenp, loff_t *ppos)
{
- struct ctl_table fake_table;
- int entropy_count;
-
- entropy_count = *(int *)table->data >> POOL_ENTROPY_SHIFT;
-
- fake_table.data = &entropy_count;
- fake_table.maxlen = sizeof(entropy_count);
-
- return proc_dointvec(&fake_table, write, buffer, lenp, ppos);
+ return write ? 0 : proc_dointvec(table, 0, buffer, lenp, ppos);
}
-static int sysctl_poolsize = POOL_BITS;
static struct ctl_table random_table[] = {
{
.procname = "poolsize",
@@ -2002,56 +1730,36 @@ static struct ctl_table random_table[] = {
},
{
.procname = "entropy_avail",
+ .data = &input_pool.entropy_count,
.maxlen = sizeof(int),
.mode = 0444,
- .proc_handler = proc_do_entropy,
- .data = &input_pool.entropy_count,
+ .proc_handler = proc_dointvec,
},
{
.procname = "write_wakeup_threshold",
- .data = &random_write_wakeup_bits,
+ .data = &sysctl_random_write_wakeup_bits,
.maxlen = sizeof(int),
.mode = 0644,
- .proc_handler = proc_dointvec_minmax,
- .extra1 = &min_write_thresh,
- .extra2 = &max_write_thresh,
+ .proc_handler = proc_do_rointvec,
},
{
.procname = "urandom_min_reseed_secs",
- .data = &random_min_urandom_seed,
+ .data = &sysctl_random_min_urandom_seed,
.maxlen = sizeof(int),
.mode = 0644,
- .proc_handler = proc_dointvec,
+ .proc_handler = proc_do_rointvec,
},
{
.procname = "boot_id",
.data = &sysctl_bootid,
- .maxlen = 16,
.mode = 0444,
.proc_handler = proc_do_uuid,
},
{
.procname = "uuid",
- .maxlen = 16,
.mode = 0444,
.proc_handler = proc_do_uuid,
},
-#ifdef ADD_INTERRUPT_BENCH
- {
- .procname = "add_interrupt_avg_cycles",
- .data = &avg_cycles,
- .maxlen = sizeof(avg_cycles),
- .mode = 0444,
- .proc_handler = proc_doulongvec_minmax,
- },
- {
- .procname = "add_interrupt_avg_deviation",
- .data = &avg_deviation,
- .maxlen = sizeof(avg_deviation),
- .mode = 0444,
- .proc_handler = proc_doulongvec_minmax,
- },
-#endif
{ }
};
@@ -2065,168 +1773,4 @@ static int __init random_sysctls_init(void)
return 0;
}
device_initcall(random_sysctls_init);
-#endif /* CONFIG_SYSCTL */
-
-struct batched_entropy {
- union {
- u64 entropy_u64[CHACHA_BLOCK_SIZE / sizeof(u64)];
- u32 entropy_u32[CHACHA_BLOCK_SIZE / sizeof(u32)];
- };
- unsigned int position;
- spinlock_t batch_lock;
-};
-
-/*
- * Get a random word for internal kernel use only. The quality of the random
- * number is good as /dev/urandom, but there is no backtrack protection, with
- * the goal of being quite fast and not depleting entropy. In order to ensure
- * that the randomness provided by this function is okay, the function
- * wait_for_random_bytes() should be called and return 0 at least once at any
- * point prior.
- */
-static DEFINE_PER_CPU(struct batched_entropy, batched_entropy_u64) = {
- .batch_lock = __SPIN_LOCK_UNLOCKED(batched_entropy_u64.lock),
-};
-
-u64 get_random_u64(void)
-{
- u64 ret;
- unsigned long flags;
- struct batched_entropy *batch;
- static void *previous;
-
- warn_unseeded_randomness(&previous);
-
- batch = raw_cpu_ptr(&batched_entropy_u64);
- spin_lock_irqsave(&batch->batch_lock, flags);
- if (batch->position % ARRAY_SIZE(batch->entropy_u64) == 0) {
- extract_crng((u8 *)batch->entropy_u64);
- batch->position = 0;
- }
- ret = batch->entropy_u64[batch->position++];
- spin_unlock_irqrestore(&batch->batch_lock, flags);
- return ret;
-}
-EXPORT_SYMBOL(get_random_u64);
-
-static DEFINE_PER_CPU(struct batched_entropy, batched_entropy_u32) = {
- .batch_lock = __SPIN_LOCK_UNLOCKED(batched_entropy_u32.lock),
-};
-u32 get_random_u32(void)
-{
- u32 ret;
- unsigned long flags;
- struct batched_entropy *batch;
- static void *previous;
-
- warn_unseeded_randomness(&previous);
-
- batch = raw_cpu_ptr(&batched_entropy_u32);
- spin_lock_irqsave(&batch->batch_lock, flags);
- if (batch->position % ARRAY_SIZE(batch->entropy_u32) == 0) {
- extract_crng((u8 *)batch->entropy_u32);
- batch->position = 0;
- }
- ret = batch->entropy_u32[batch->position++];
- spin_unlock_irqrestore(&batch->batch_lock, flags);
- return ret;
-}
-EXPORT_SYMBOL(get_random_u32);
-
-/* It's important to invalidate all potential batched entropy that might
- * be stored before the crng is initialized, which we can do lazily by
- * simply resetting the counter to zero so that it's re-extracted on the
- * next usage. */
-static void invalidate_batched_entropy(void)
-{
- int cpu;
- unsigned long flags;
-
- for_each_possible_cpu(cpu) {
- struct batched_entropy *batched_entropy;
-
- batched_entropy = per_cpu_ptr(&batched_entropy_u32, cpu);
- spin_lock_irqsave(&batched_entropy->batch_lock, flags);
- batched_entropy->position = 0;
- spin_unlock(&batched_entropy->batch_lock);
-
- batched_entropy = per_cpu_ptr(&batched_entropy_u64, cpu);
- spin_lock(&batched_entropy->batch_lock);
- batched_entropy->position = 0;
- spin_unlock_irqrestore(&batched_entropy->batch_lock, flags);
- }
-}
-
-/**
- * randomize_page - Generate a random, page aligned address
- * @start: The smallest acceptable address the caller will take.
- * @range: The size of the area, starting at @start, within which the
- * random address must fall.
- *
- * If @start + @range would overflow, @range is capped.
- *
- * NOTE: Historical use of randomize_range, which this replaces, presumed that
- * @start was already page aligned. We now align it regardless.
- *
- * Return: A page aligned address within [start, start + range). On error,
- * @start is returned.
- */
-unsigned long randomize_page(unsigned long start, unsigned long range)
-{
- if (!PAGE_ALIGNED(start)) {
- range -= PAGE_ALIGN(start) - start;
- start = PAGE_ALIGN(start);
- }
-
- if (start > ULONG_MAX - range)
- range = ULONG_MAX - start;
-
- range >>= PAGE_SHIFT;
-
- if (range == 0)
- return start;
-
- return start + (get_random_long() % range << PAGE_SHIFT);
-}
-
-/* Interface for in-kernel drivers of true hardware RNGs.
- * Those devices may produce endless random bits and will be throttled
- * when our pool is full.
- */
-void add_hwgenerator_randomness(const char *buffer, size_t count,
- size_t entropy)
-{
- if (unlikely(crng_init == 0)) {
- size_t ret = crng_fast_load(buffer, count);
- mix_pool_bytes(buffer, ret);
- count -= ret;
- buffer += ret;
- if (!count || crng_init == 0)
- return;
- }
-
- /* Suspend writing if we're above the trickle threshold.
- * We'll be woken up again once below random_write_wakeup_thresh,
- * or when the calling thread is about to terminate.
- */
- wait_event_interruptible(random_write_wait,
- !system_wq || kthread_should_stop() ||
- POOL_ENTROPY_BITS() <= random_write_wakeup_bits);
- mix_pool_bytes(buffer, count);
- credit_entropy_bits(entropy);
-}
-EXPORT_SYMBOL_GPL(add_hwgenerator_randomness);
-
-/* Handle random seed passed by bootloader.
- * If the seed is trustworthy, it would be regarded as hardware RNGs. Otherwise
- * it would be regarded as device data.
- * The decision is controlled by CONFIG_RANDOM_TRUST_BOOTLOADER.
- */
-void add_bootloader_randomness(const void *buf, unsigned int size)
-{
- if (IS_ENABLED(CONFIG_RANDOM_TRUST_BOOTLOADER))
- add_hwgenerator_randomness(buf, size, size * 8);
- else
- add_device_randomness(buf, size);
-}
-EXPORT_SYMBOL_GPL(add_bootloader_randomness);
+#endif
diff --git a/drivers/char/tpm/st33zp24/i2c.c b/drivers/char/tpm/st33zp24/i2c.c
index 7c617edff4ca..3170d59d660c 100644
--- a/drivers/char/tpm/st33zp24/i2c.c
+++ b/drivers/char/tpm/st33zp24/i2c.c
@@ -267,11 +267,8 @@ static int st33zp24_i2c_probe(struct i2c_client *client,
static int st33zp24_i2c_remove(struct i2c_client *client)
{
struct tpm_chip *chip = i2c_get_clientdata(client);
- int ret;
- ret = st33zp24_remove(chip);
- if (ret)
- return ret;
+ st33zp24_remove(chip);
return 0;
}
diff --git a/drivers/char/tpm/st33zp24/spi.c b/drivers/char/tpm/st33zp24/spi.c
index a75dafd39445..22d184884694 100644
--- a/drivers/char/tpm/st33zp24/spi.c
+++ b/drivers/char/tpm/st33zp24/spi.c
@@ -381,16 +381,11 @@ static int st33zp24_spi_probe(struct spi_device *dev)
* @param: client, the spi_device description (TPM SPI description).
* @return: 0 in case of success.
*/
-static int st33zp24_spi_remove(struct spi_device *dev)
+static void st33zp24_spi_remove(struct spi_device *dev)
{
struct tpm_chip *chip = spi_get_drvdata(dev);
- int ret;
- ret = st33zp24_remove(chip);
- if (ret)
- return ret;
-
- return 0;
+ st33zp24_remove(chip);
}
static const struct spi_device_id st33zp24_spi_id[] = {
diff --git a/drivers/char/tpm/st33zp24/st33zp24.c b/drivers/char/tpm/st33zp24/st33zp24.c
index ce9efb73c144..15b393e92c8e 100644
--- a/drivers/char/tpm/st33zp24/st33zp24.c
+++ b/drivers/char/tpm/st33zp24/st33zp24.c
@@ -511,10 +511,9 @@ _tpm_clean_answer:
}
EXPORT_SYMBOL(st33zp24_probe);
-int st33zp24_remove(struct tpm_chip *chip)
+void st33zp24_remove(struct tpm_chip *chip)
{
tpm_chip_unregister(chip);
- return 0;
}
EXPORT_SYMBOL(st33zp24_remove);
diff --git a/drivers/char/tpm/st33zp24/st33zp24.h b/drivers/char/tpm/st33zp24/st33zp24.h
index 6747be1e2502..b387a476c555 100644
--- a/drivers/char/tpm/st33zp24/st33zp24.h
+++ b/drivers/char/tpm/st33zp24/st33zp24.h
@@ -34,5 +34,5 @@ int st33zp24_pm_resume(struct device *dev);
int st33zp24_probe(void *phy_id, const struct st33zp24_phy_ops *ops,
struct device *dev, int irq, int io_lpcpd);
-int st33zp24_remove(struct tpm_chip *chip);
+void st33zp24_remove(struct tpm_chip *chip);
#endif /* __LOCAL_ST33ZP24_H__ */
diff --git a/drivers/char/tpm/tpm-chip.c b/drivers/char/tpm/tpm-chip.c
index b009e7479b70..783d65fc71f0 100644
--- a/drivers/char/tpm/tpm-chip.c
+++ b/drivers/char/tpm/tpm-chip.c
@@ -274,14 +274,6 @@ static void tpm_dev_release(struct device *dev)
kfree(chip);
}
-static void tpm_devs_release(struct device *dev)
-{
- struct tpm_chip *chip = container_of(dev, struct tpm_chip, devs);
-
- /* release the master device reference */
- put_device(&chip->dev);
-}
-
/**
* tpm_class_shutdown() - prepare the TPM device for loss of power.
* @dev: device to which the chip is associated.
@@ -344,7 +336,6 @@ struct tpm_chip *tpm_chip_alloc(struct device *pdev,
chip->dev_num = rc;
device_initialize(&chip->dev);
- device_initialize(&chip->devs);
chip->dev.class = tpm_class;
chip->dev.class->shutdown_pre = tpm_class_shutdown;
@@ -352,39 +343,20 @@ struct tpm_chip *tpm_chip_alloc(struct device *pdev,
chip->dev.parent = pdev;
chip->dev.groups = chip->groups;
- chip->devs.parent = pdev;
- chip->devs.class = tpmrm_class;
- chip->devs.release = tpm_devs_release;
- /* get extra reference on main device to hold on
- * behalf of devs. This holds the chip structure
- * while cdevs is in use. The corresponding put
- * is in the tpm_devs_release (TPM2 only)
- */
- if (chip->flags & TPM_CHIP_FLAG_TPM2)
- get_device(&chip->dev);
-
if (chip->dev_num == 0)
chip->dev.devt = MKDEV(MISC_MAJOR, TPM_MINOR);
else
chip->dev.devt = MKDEV(MAJOR(tpm_devt), chip->dev_num);
- chip->devs.devt =
- MKDEV(MAJOR(tpm_devt), chip->dev_num + TPM_NUM_DEVICES);
-
rc = dev_set_name(&chip->dev, "tpm%d", chip->dev_num);
if (rc)
goto out;
- rc = dev_set_name(&chip->devs, "tpmrm%d", chip->dev_num);
- if (rc)
- goto out;
if (!pdev)
chip->flags |= TPM_CHIP_FLAG_VIRTUAL;
cdev_init(&chip->cdev, &tpm_fops);
- cdev_init(&chip->cdevs, &tpmrm_fops);
chip->cdev.owner = THIS_MODULE;
- chip->cdevs.owner = THIS_MODULE;
rc = tpm2_init_space(&chip->work_space, TPM2_SPACE_BUFFER_SIZE);
if (rc) {
@@ -396,7 +368,6 @@ struct tpm_chip *tpm_chip_alloc(struct device *pdev,
return chip;
out:
- put_device(&chip->devs);
put_device(&chip->dev);
return ERR_PTR(rc);
}
@@ -445,14 +416,9 @@ static int tpm_add_char_device(struct tpm_chip *chip)
}
if (chip->flags & TPM_CHIP_FLAG_TPM2 && !tpm_is_firmware_upgrade(chip)) {
- rc = cdev_device_add(&chip->cdevs, &chip->devs);
- if (rc) {
- dev_err(&chip->devs,
- "unable to cdev_device_add() %s, major %d, minor %d, err=%d\n",
- dev_name(&chip->devs), MAJOR(chip->devs.devt),
- MINOR(chip->devs.devt), rc);
- return rc;
- }
+ rc = tpm_devs_add(chip);
+ if (rc)
+ goto err_del_cdev;
}
/* Make the chip available. */
@@ -460,6 +426,10 @@ static int tpm_add_char_device(struct tpm_chip *chip)
idr_replace(&dev_nums_idr, chip, chip->dev_num);
mutex_unlock(&idr_lock);
+ return 0;
+
+err_del_cdev:
+ cdev_device_del(&chip->cdev, &chip->dev);
return rc;
}
@@ -654,7 +624,7 @@ void tpm_chip_unregister(struct tpm_chip *chip)
hwrng_unregister(&chip->hwrng);
tpm_bios_log_teardown(chip);
if (chip->flags & TPM_CHIP_FLAG_TPM2 && !tpm_is_firmware_upgrade(chip))
- cdev_device_del(&chip->cdevs, &chip->devs);
+ tpm_devs_remove(chip);
tpm_del_char_device(chip);
}
EXPORT_SYMBOL_GPL(tpm_chip_unregister);
diff --git a/drivers/char/tpm/tpm-dev-common.c b/drivers/char/tpm/tpm-dev-common.c
index c08cbb306636..dc4c0a0a5129 100644
--- a/drivers/char/tpm/tpm-dev-common.c
+++ b/drivers/char/tpm/tpm-dev-common.c
@@ -69,7 +69,13 @@ static void tpm_dev_async_work(struct work_struct *work)
ret = tpm_dev_transmit(priv->chip, priv->space, priv->data_buffer,
sizeof(priv->data_buffer));
tpm_put_ops(priv->chip);
- if (ret > 0) {
+
+ /*
+ * If ret is > 0 then tpm_dev_transmit returned the size of the
+ * response. If ret is < 0 then tpm_dev_transmit failed and
+ * returned an error code.
+ */
+ if (ret != 0) {
priv->response_length = ret;
mod_timer(&priv->user_read_timer, jiffies + (120 * HZ));
}
diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h
index 283f78211c3a..2163c6ee0d36 100644
--- a/drivers/char/tpm/tpm.h
+++ b/drivers/char/tpm/tpm.h
@@ -234,6 +234,8 @@ int tpm2_prepare_space(struct tpm_chip *chip, struct tpm_space *space, u8 *cmd,
size_t cmdsiz);
int tpm2_commit_space(struct tpm_chip *chip, struct tpm_space *space, void *buf,
size_t *bufsiz);
+int tpm_devs_add(struct tpm_chip *chip);
+void tpm_devs_remove(struct tpm_chip *chip);
void tpm_bios_log_setup(struct tpm_chip *chip);
void tpm_bios_log_teardown(struct tpm_chip *chip);
diff --git a/drivers/char/tpm/tpm2-space.c b/drivers/char/tpm/tpm2-space.c
index 97e916856cf3..ffb35f0154c1 100644
--- a/drivers/char/tpm/tpm2-space.c
+++ b/drivers/char/tpm/tpm2-space.c
@@ -58,12 +58,12 @@ int tpm2_init_space(struct tpm_space *space, unsigned int buf_size)
void tpm2_del_space(struct tpm_chip *chip, struct tpm_space *space)
{
- mutex_lock(&chip->tpm_mutex);
- if (!tpm_chip_start(chip)) {
+
+ if (tpm_try_get_ops(chip) == 0) {
tpm2_flush_sessions(chip, space);
- tpm_chip_stop(chip);
+ tpm_put_ops(chip);
}
- mutex_unlock(&chip->tpm_mutex);
+
kfree(space->context_buf);
kfree(space->session_buf);
}
@@ -574,3 +574,68 @@ out:
dev_err(&chip->dev, "%s: error %d\n", __func__, rc);
return rc;
}
+
+/*
+ * Put the reference to the main device.
+ */
+static void tpm_devs_release(struct device *dev)
+{
+ struct tpm_chip *chip = container_of(dev, struct tpm_chip, devs);
+
+ /* release the master device reference */
+ put_device(&chip->dev);
+}
+
+/*
+ * Remove the device file for exposed TPM spaces and release the device
+ * reference. This may also release the reference to the master device.
+ */
+void tpm_devs_remove(struct tpm_chip *chip)
+{
+ cdev_device_del(&chip->cdevs, &chip->devs);
+ put_device(&chip->devs);
+}
+
+/*
+ * Add a device file to expose TPM spaces. Also take a reference to the
+ * main device.
+ */
+int tpm_devs_add(struct tpm_chip *chip)
+{
+ int rc;
+
+ device_initialize(&chip->devs);
+ chip->devs.parent = chip->dev.parent;
+ chip->devs.class = tpmrm_class;
+
+ /*
+ * Get extra reference on main device to hold on behalf of devs.
+ * This holds the chip structure while cdevs is in use. The
+ * corresponding put is in the tpm_devs_release.
+ */
+ get_device(&chip->dev);
+ chip->devs.release = tpm_devs_release;
+ chip->devs.devt = MKDEV(MAJOR(tpm_devt), chip->dev_num + TPM_NUM_DEVICES);
+ cdev_init(&chip->cdevs, &tpmrm_fops);
+ chip->cdevs.owner = THIS_MODULE;
+
+ rc = dev_set_name(&chip->devs, "tpmrm%d", chip->dev_num);
+ if (rc)
+ goto err_put_devs;
+
+ rc = cdev_device_add(&chip->cdevs, &chip->devs);
+ if (rc) {
+ dev_err(&chip->devs,
+ "unable to cdev_device_add() %s, major %d, minor %d, err=%d\n",
+ dev_name(&chip->devs), MAJOR(chip->devs.devt),
+ MINOR(chip->devs.devt), rc);
+ goto err_put_devs;
+ }
+
+ return 0;
+
+err_put_devs:
+ put_device(&chip->devs);
+
+ return rc;
+}
diff --git a/drivers/char/tpm/tpm_tis_spi_main.c b/drivers/char/tpm/tpm_tis_spi_main.c
index aaa59a00eeae..184396b3af50 100644
--- a/drivers/char/tpm/tpm_tis_spi_main.c
+++ b/drivers/char/tpm/tpm_tis_spi_main.c
@@ -254,13 +254,12 @@ static int tpm_tis_spi_driver_probe(struct spi_device *spi)
static SIMPLE_DEV_PM_OPS(tpm_tis_pm, tpm_pm_suspend, tpm_tis_spi_resume);
-static int tpm_tis_spi_remove(struct spi_device *dev)
+static void tpm_tis_spi_remove(struct spi_device *dev)
{
struct tpm_chip *chip = spi_get_drvdata(dev);
tpm_chip_unregister(chip);
tpm_tis_remove(chip);
- return 0;
}
static const struct spi_device_id tpm_tis_spi_id[] = {
diff --git a/drivers/char/tpm/tpm_vtpm_proxy.c b/drivers/char/tpm/tpm_vtpm_proxy.c
index 91c772e38bb5..5c865987ba5c 100644
--- a/drivers/char/tpm/tpm_vtpm_proxy.c
+++ b/drivers/char/tpm/tpm_vtpm_proxy.c
@@ -91,7 +91,7 @@ static ssize_t vtpm_proxy_fops_read(struct file *filp, char __user *buf,
len = proxy_dev->req_len;
- if (count < len) {
+ if (count < len || len > sizeof(proxy_dev->buffer)) {
mutex_unlock(&proxy_dev->buf_lock);
pr_debug("Invalid size in recv: count=%zd, req_len=%zd\n",
count, len);
diff --git a/drivers/char/tpm/xen-tpmfront.c b/drivers/char/tpm/xen-tpmfront.c
index da5b30771418..f53e0cf1ec7e 100644
--- a/drivers/char/tpm/xen-tpmfront.c
+++ b/drivers/char/tpm/xen-tpmfront.c
@@ -126,16 +126,16 @@ static void vtpm_cancel(struct tpm_chip *chip)
notify_remote_via_evtchn(priv->evtchn);
}
-static unsigned int shr_data_offset(struct vtpm_shared_page *shr)
+static size_t shr_data_offset(struct vtpm_shared_page *shr)
{
- return sizeof(*shr) + sizeof(u32) * shr->nr_extra_pages;
+ return struct_size(shr, extra_pages, shr->nr_extra_pages);
}
static int vtpm_send(struct tpm_chip *chip, u8 *buf, size_t count)
{
struct tpm_private *priv = dev_get_drvdata(&chip->dev);
struct vtpm_shared_page *shr = priv->shr;
- unsigned int offset = shr_data_offset(shr);
+ size_t offset = shr_data_offset(shr);
u32 ordinal;
unsigned long duration;
@@ -177,7 +177,7 @@ static int vtpm_recv(struct tpm_chip *chip, u8 *buf, size_t count)
{
struct tpm_private *priv = dev_get_drvdata(&chip->dev);
struct vtpm_shared_page *shr = priv->shr;
- unsigned int offset = shr_data_offset(shr);
+ size_t offset = shr_data_offset(shr);
size_t length = shr->length;
if (shr->state == VTPM_STATE_IDLE)
diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c
index 2359889a35a0..e3c430539a17 100644
--- a/drivers/char/virtio_console.c
+++ b/drivers/char/virtio_console.c
@@ -1957,6 +1957,13 @@ static void virtcons_remove(struct virtio_device *vdev)
list_del(&portdev->list);
spin_unlock_irq(&pdrvdata_lock);
+ /* Device is going away, exit any polling for buffers */
+ virtio_break_device(vdev);
+ if (use_multiport(portdev))
+ flush_work(&portdev->control_work);
+ else
+ flush_work(&portdev->config_work);
+
/* Disable interrupts for vqs */
virtio_reset_device(vdev);
/* Finish up work that's lined up */
diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index ad4256d54361..d4d67fbae869 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -231,6 +231,8 @@ config COMMON_CLK_GEMINI
config COMMON_CLK_LAN966X
bool "Generic Clock Controller driver for LAN966X SoC"
+ depends on HAS_IOMEM
+ depends on OF
help
This driver provides support for Generic Clock Controller(GCK) on
LAN966X SoC. GCK generates and supplies clock to various peripherals
diff --git a/drivers/clk/clk-lmk04832.c b/drivers/clk/clk-lmk04832.c
index 8f02c0b88000..f416f8bc2898 100644
--- a/drivers/clk/clk-lmk04832.c
+++ b/drivers/clk/clk-lmk04832.c
@@ -1544,14 +1544,12 @@ err_disable_oscin:
return ret;
}
-static int lmk04832_remove(struct spi_device *spi)
+static void lmk04832_remove(struct spi_device *spi)
{
struct lmk04832 *lmk = spi_get_drvdata(spi);
clk_disable_unprepare(lmk->oscin);
of_clk_del_provider(spi->dev.of_node);
-
- return 0;
}
static const struct spi_device_id lmk04832_id[] = {
{ "lmk04832", LMK04832 },
diff --git a/drivers/clk/clk-scmi.c b/drivers/clk/clk-scmi.c
index 1e357d364ca2..2c7a830ce308 100644
--- a/drivers/clk/clk-scmi.c
+++ b/drivers/clk/clk-scmi.c
@@ -2,7 +2,7 @@
/*
* System Control and Power Interface (SCMI) Protocol based clock driver
*
- * Copyright (C) 2018-2021 ARM Ltd.
+ * Copyright (C) 2018-2022 ARM Ltd.
*/
#include <linux/clk-provider.h>
@@ -88,21 +88,51 @@ static void scmi_clk_disable(struct clk_hw *hw)
scmi_proto_clk_ops->disable(clk->ph, clk->id);
}
+static int scmi_clk_atomic_enable(struct clk_hw *hw)
+{
+ struct scmi_clk *clk = to_scmi_clk(hw);
+
+ return scmi_proto_clk_ops->enable_atomic(clk->ph, clk->id);
+}
+
+static void scmi_clk_atomic_disable(struct clk_hw *hw)
+{
+ struct scmi_clk *clk = to_scmi_clk(hw);
+
+ scmi_proto_clk_ops->disable_atomic(clk->ph, clk->id);
+}
+
+/*
+ * We can provide enable/disable atomic callbacks only if the underlying SCMI
+ * transport for an SCMI instance is configured to handle SCMI commands in an
+ * atomic manner.
+ *
+ * When no SCMI atomic transport support is available we instead provide only
+ * the prepare/unprepare API, as allowed by the clock framework when atomic
+ * calls are not available.
+ *
+ * Two distinct sets of clk_ops are provided since we could have multiple SCMI
+ * instances with different underlying transport quality, so they cannot be
+ * shared.
+ */
static const struct clk_ops scmi_clk_ops = {
.recalc_rate = scmi_clk_recalc_rate,
.round_rate = scmi_clk_round_rate,
.set_rate = scmi_clk_set_rate,
- /*
- * We can't provide enable/disable callback as we can't perform the same
- * in atomic context. Since the clock framework provides standard API
- * clk_prepare_enable that helps cases using clk_enable in non-atomic
- * context, it should be fine providing prepare/unprepare.
- */
.prepare = scmi_clk_enable,
.unprepare = scmi_clk_disable,
};
-static int scmi_clk_ops_init(struct device *dev, struct scmi_clk *sclk)
+static const struct clk_ops scmi_atomic_clk_ops = {
+ .recalc_rate = scmi_clk_recalc_rate,
+ .round_rate = scmi_clk_round_rate,
+ .set_rate = scmi_clk_set_rate,
+ .enable = scmi_clk_atomic_enable,
+ .disable = scmi_clk_atomic_disable,
+};
+
+static int scmi_clk_ops_init(struct device *dev, struct scmi_clk *sclk,
+ const struct clk_ops *scmi_ops)
{
int ret;
unsigned long min_rate, max_rate;
@@ -110,7 +140,7 @@ static int scmi_clk_ops_init(struct device *dev, struct scmi_clk *sclk)
struct clk_init_data init = {
.flags = CLK_GET_RATE_NOCACHE,
.num_parents = 0,
- .ops = &scmi_clk_ops,
+ .ops = scmi_ops,
.name = sclk->info->name,
};
@@ -139,6 +169,8 @@ static int scmi_clk_ops_init(struct device *dev, struct scmi_clk *sclk)
static int scmi_clocks_probe(struct scmi_device *sdev)
{
int idx, count, err;
+ unsigned int atomic_threshold;
+ bool is_atomic;
struct clk_hw **hws;
struct clk_hw_onecell_data *clk_data;
struct device *dev = &sdev->dev;
@@ -168,8 +200,11 @@ static int scmi_clocks_probe(struct scmi_device *sdev)
clk_data->num = count;
hws = clk_data->hws;
+ is_atomic = handle->is_transport_atomic(handle, &atomic_threshold);
+
for (idx = 0; idx < count; idx++) {
struct scmi_clk *sclk;
+ const struct clk_ops *scmi_ops;
sclk = devm_kzalloc(dev, sizeof(*sclk), GFP_KERNEL);
if (!sclk)
@@ -184,13 +219,27 @@ static int scmi_clocks_probe(struct scmi_device *sdev)
sclk->id = idx;
sclk->ph = ph;
- err = scmi_clk_ops_init(dev, sclk);
+ /*
+ * Note that when transport is atomic but SCMI protocol did not
+ * specify (or support) an enable_latency associated with a
+ * clock, we default to use atomic operations mode.
+ */
+ if (is_atomic &&
+ sclk->info->enable_latency <= atomic_threshold)
+ scmi_ops = &scmi_atomic_clk_ops;
+ else
+ scmi_ops = &scmi_clk_ops;
+
+ err = scmi_clk_ops_init(dev, sclk, scmi_ops);
if (err) {
dev_err(dev, "failed to register clock %d\n", idx);
devm_kfree(dev, sclk);
hws[idx] = NULL;
} else {
- dev_dbg(dev, "Registered clock:%s\n", sclk->info->name);
+ dev_dbg(dev, "Registered clock:%s%s\n",
+ sclk->info->name,
+ scmi_ops == &scmi_atomic_clk_ops ?
+ " (atomic ops)" : "");
hws[idx] = &sclk->hw;
}
}
diff --git a/drivers/clk/ingenic/jz4725b-cgu.c b/drivers/clk/ingenic/jz4725b-cgu.c
index 744d136b721b..15d61793f53b 100644
--- a/drivers/clk/ingenic/jz4725b-cgu.c
+++ b/drivers/clk/ingenic/jz4725b-cgu.c
@@ -139,11 +139,10 @@ static const struct ingenic_cgu_clk_info jz4725b_cgu_clocks[] = {
},
[JZ4725B_CLK_I2S] = {
- "i2s", CGU_CLK_MUX | CGU_CLK_DIV | CGU_CLK_GATE,
+ "i2s", CGU_CLK_MUX | CGU_CLK_DIV,
.parents = { JZ4725B_CLK_EXT, JZ4725B_CLK_PLL_HALF, -1, -1 },
.mux = { CGU_REG_CPCCR, 31, 1 },
.div = { CGU_REG_I2SCDR, 0, 1, 9, -1, -1, -1 },
- .gate = { CGU_REG_CLKGR, 6 },
},
[JZ4725B_CLK_SPI] = {
diff --git a/drivers/clk/qcom/dispcc-sc7180.c b/drivers/clk/qcom/dispcc-sc7180.c
index 538e4963c915..5d2ae297e741 100644
--- a/drivers/clk/qcom/dispcc-sc7180.c
+++ b/drivers/clk/qcom/dispcc-sc7180.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
- * Copyright (c) 2019, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2019, 2022, The Linux Foundation. All rights reserved.
*/
#include <linux/clk-provider.h>
@@ -625,6 +625,9 @@ static struct clk_branch disp_cc_mdss_vsync_clk = {
static struct gdsc mdss_gdsc = {
.gdscr = 0x3000,
+ .en_rest_wait_val = 0x2,
+ .en_few_wait_val = 0x2,
+ .clk_dis_wait_val = 0xf,
.pd = {
.name = "mdss_gdsc",
},
diff --git a/drivers/clk/qcom/dispcc-sc7280.c b/drivers/clk/qcom/dispcc-sc7280.c
index 4ef4ae231794..ad596d567f6a 100644
--- a/drivers/clk/qcom/dispcc-sc7280.c
+++ b/drivers/clk/qcom/dispcc-sc7280.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
- * Copyright (c) 2021, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2021-2022, The Linux Foundation. All rights reserved.
*/
#include <linux/clk-provider.h>
@@ -787,6 +787,9 @@ static struct clk_branch disp_cc_sleep_clk = {
static struct gdsc disp_cc_mdss_core_gdsc = {
.gdscr = 0x1004,
+ .en_rest_wait_val = 0x2,
+ .en_few_wait_val = 0x2,
+ .clk_dis_wait_val = 0xf,
.pd = {
.name = "disp_cc_mdss_core_gdsc",
},
diff --git a/drivers/clk/qcom/dispcc-sm8250.c b/drivers/clk/qcom/dispcc-sm8250.c
index 566fdfa0a15b..db9379634fb2 100644
--- a/drivers/clk/qcom/dispcc-sm8250.c
+++ b/drivers/clk/qcom/dispcc-sm8250.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0
/*
- * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2018-2020, 2022, The Linux Foundation. All rights reserved.
*/
#include <linux/clk-provider.h>
@@ -1126,6 +1126,9 @@ static struct clk_branch disp_cc_mdss_vsync_clk = {
static struct gdsc mdss_gdsc = {
.gdscr = 0x3000,
+ .en_rest_wait_val = 0x2,
+ .en_few_wait_val = 0x2,
+ .clk_dis_wait_val = 0xf,
.pd = {
.name = "mdss_gdsc",
},
diff --git a/drivers/clk/qcom/gcc-msm8994.c b/drivers/clk/qcom/gcc-msm8994.c
index 71aa630fa4bd..f09499999eb3 100644
--- a/drivers/clk/qcom/gcc-msm8994.c
+++ b/drivers/clk/qcom/gcc-msm8994.c
@@ -108,42 +108,6 @@ static const struct clk_parent_data gcc_xo_gpll0_gpll4[] = {
{ .hw = &gpll4.clkr.hw },
};
-static struct clk_rcg2 system_noc_clk_src = {
- .cmd_rcgr = 0x0120,
- .hid_width = 5,
- .parent_map = gcc_xo_gpll0_map,
- .clkr.hw.init = &(struct clk_init_data){
- .name = "system_noc_clk_src",
- .parent_data = gcc_xo_gpll0,
- .num_parents = ARRAY_SIZE(gcc_xo_gpll0),
- .ops = &clk_rcg2_ops,
- },
-};
-
-static struct clk_rcg2 config_noc_clk_src = {
- .cmd_rcgr = 0x0150,
- .hid_width = 5,
- .parent_map = gcc_xo_gpll0_map,
- .clkr.hw.init = &(struct clk_init_data){
- .name = "config_noc_clk_src",
- .parent_data = gcc_xo_gpll0,
- .num_parents = ARRAY_SIZE(gcc_xo_gpll0),
- .ops = &clk_rcg2_ops,
- },
-};
-
-static struct clk_rcg2 periph_noc_clk_src = {
- .cmd_rcgr = 0x0190,
- .hid_width = 5,
- .parent_map = gcc_xo_gpll0_map,
- .clkr.hw.init = &(struct clk_init_data){
- .name = "periph_noc_clk_src",
- .parent_data = gcc_xo_gpll0,
- .num_parents = ARRAY_SIZE(gcc_xo_gpll0),
- .ops = &clk_rcg2_ops,
- },
-};
-
static struct freq_tbl ftbl_ufs_axi_clk_src[] = {
F(50000000, P_GPLL0, 12, 0, 0),
F(100000000, P_GPLL0, 6, 0, 0),
@@ -1150,8 +1114,6 @@ static struct clk_branch gcc_blsp1_ahb_clk = {
.enable_mask = BIT(17),
.hw.init = &(struct clk_init_data){
.name = "gcc_blsp1_ahb_clk",
- .parent_hws = (const struct clk_hw *[]){ &periph_noc_clk_src.clkr.hw },
- .num_parents = 1,
.ops = &clk_branch2_ops,
},
},
@@ -1435,8 +1397,6 @@ static struct clk_branch gcc_blsp2_ahb_clk = {
.enable_mask = BIT(15),
.hw.init = &(struct clk_init_data){
.name = "gcc_blsp2_ahb_clk",
- .parent_hws = (const struct clk_hw *[]){ &periph_noc_clk_src.clkr.hw },
- .num_parents = 1,
.ops = &clk_branch2_ops,
},
},
@@ -1764,8 +1724,6 @@ static struct clk_branch gcc_lpass_q6_axi_clk = {
.enable_mask = BIT(0),
.hw.init = &(struct clk_init_data){
.name = "gcc_lpass_q6_axi_clk",
- .parent_hws = (const struct clk_hw *[]){ &system_noc_clk_src.clkr.hw },
- .num_parents = 1,
.ops = &clk_branch2_ops,
},
},
@@ -1778,8 +1736,6 @@ static struct clk_branch gcc_mss_q6_bimc_axi_clk = {
.enable_mask = BIT(0),
.hw.init = &(struct clk_init_data){
.name = "gcc_mss_q6_bimc_axi_clk",
- .parent_hws = (const struct clk_hw *[]){ &system_noc_clk_src.clkr.hw },
- .num_parents = 1,
.ops = &clk_branch2_ops,
},
},
@@ -1807,9 +1763,6 @@ static struct clk_branch gcc_pcie_0_cfg_ahb_clk = {
.enable_mask = BIT(0),
.hw.init = &(struct clk_init_data){
.name = "gcc_pcie_0_cfg_ahb_clk",
- .parent_hws = (const struct clk_hw *[]){ &config_noc_clk_src.clkr.hw },
- .num_parents = 1,
- .flags = CLK_SET_RATE_PARENT,
.ops = &clk_branch2_ops,
},
},
@@ -1822,9 +1775,6 @@ static struct clk_branch gcc_pcie_0_mstr_axi_clk = {
.enable_mask = BIT(0),
.hw.init = &(struct clk_init_data){
.name = "gcc_pcie_0_mstr_axi_clk",
- .parent_hws = (const struct clk_hw *[]){ &system_noc_clk_src.clkr.hw },
- .num_parents = 1,
- .flags = CLK_SET_RATE_PARENT,
.ops = &clk_branch2_ops,
},
},
@@ -1854,9 +1804,6 @@ static struct clk_branch gcc_pcie_0_slv_axi_clk = {
.enable_mask = BIT(0),
.hw.init = &(struct clk_init_data){
.name = "gcc_pcie_0_slv_axi_clk",
- .parent_hws = (const struct clk_hw *[]){ &system_noc_clk_src.clkr.hw },
- .num_parents = 1,
- .flags = CLK_SET_RATE_PARENT,
.ops = &clk_branch2_ops,
},
},
@@ -1884,9 +1831,6 @@ static struct clk_branch gcc_pcie_1_cfg_ahb_clk = {
.enable_mask = BIT(0),
.hw.init = &(struct clk_init_data){
.name = "gcc_pcie_1_cfg_ahb_clk",
- .parent_hws = (const struct clk_hw *[]){ &config_noc_clk_src.clkr.hw },
- .num_parents = 1,
- .flags = CLK_SET_RATE_PARENT,
.ops = &clk_branch2_ops,
},
},
@@ -1899,9 +1843,6 @@ static struct clk_branch gcc_pcie_1_mstr_axi_clk = {
.enable_mask = BIT(0),
.hw.init = &(struct clk_init_data){
.name = "gcc_pcie_1_mstr_axi_clk",
- .parent_hws = (const struct clk_hw *[]){ &system_noc_clk_src.clkr.hw },
- .num_parents = 1,
- .flags = CLK_SET_RATE_PARENT,
.ops = &clk_branch2_ops,
},
},
@@ -1930,9 +1871,6 @@ static struct clk_branch gcc_pcie_1_slv_axi_clk = {
.enable_mask = BIT(0),
.hw.init = &(struct clk_init_data){
.name = "gcc_pcie_1_slv_axi_clk",
- .parent_hws = (const struct clk_hw *[]){ &system_noc_clk_src.clkr.hw },
- .num_parents = 1,
- .flags = CLK_SET_RATE_PARENT,
.ops = &clk_branch2_ops,
},
},
@@ -1960,8 +1898,6 @@ static struct clk_branch gcc_pdm_ahb_clk = {
.enable_mask = BIT(0),
.hw.init = &(struct clk_init_data){
.name = "gcc_pdm_ahb_clk",
- .parent_hws = (const struct clk_hw *[]){ &periph_noc_clk_src.clkr.hw },
- .num_parents = 1,
.ops = &clk_branch2_ops,
},
},
@@ -1989,9 +1925,6 @@ static struct clk_branch gcc_sdcc1_ahb_clk = {
.enable_mask = BIT(0),
.hw.init = &(struct clk_init_data){
.name = "gcc_sdcc1_ahb_clk",
- .parent_hws = (const struct clk_hw *[]){ &periph_noc_clk_src.clkr.hw },
- .num_parents = 1,
- .flags = CLK_SET_RATE_PARENT,
.ops = &clk_branch2_ops,
},
},
@@ -2004,9 +1937,6 @@ static struct clk_branch gcc_sdcc2_ahb_clk = {
.enable_mask = BIT(0),
.hw.init = &(struct clk_init_data){
.name = "gcc_sdcc2_ahb_clk",
- .parent_hws = (const struct clk_hw *[]){ &periph_noc_clk_src.clkr.hw },
- .num_parents = 1,
- .flags = CLK_SET_RATE_PARENT,
.ops = &clk_branch2_ops,
},
},
@@ -2034,9 +1964,6 @@ static struct clk_branch gcc_sdcc3_ahb_clk = {
.enable_mask = BIT(0),
.hw.init = &(struct clk_init_data){
.name = "gcc_sdcc3_ahb_clk",
- .parent_hws = (const struct clk_hw *[]){ &periph_noc_clk_src.clkr.hw },
- .num_parents = 1,
- .flags = CLK_SET_RATE_PARENT,
.ops = &clk_branch2_ops,
},
},
@@ -2064,9 +1991,6 @@ static struct clk_branch gcc_sdcc4_ahb_clk = {
.enable_mask = BIT(0),
.hw.init = &(struct clk_init_data){
.name = "gcc_sdcc4_ahb_clk",
- .parent_hws = (const struct clk_hw *[]){ &periph_noc_clk_src.clkr.hw },
- .num_parents = 1,
- .flags = CLK_SET_RATE_PARENT,
.ops = &clk_branch2_ops,
},
},
@@ -2124,8 +2048,6 @@ static struct clk_branch gcc_tsif_ahb_clk = {
.enable_mask = BIT(0),
.hw.init = &(struct clk_init_data){
.name = "gcc_tsif_ahb_clk",
- .parent_hws = (const struct clk_hw *[]){ &periph_noc_clk_src.clkr.hw },
- .num_parents = 1,
.ops = &clk_branch2_ops,
},
},
@@ -2153,8 +2075,6 @@ static struct clk_branch gcc_ufs_ahb_clk = {
.enable_mask = BIT(0),
.hw.init = &(struct clk_init_data){
.name = "gcc_ufs_ahb_clk",
- .parent_hws = (const struct clk_hw *[]){ &config_noc_clk_src.clkr.hw },
- .num_parents = 1,
.ops = &clk_branch2_ops,
},
},
@@ -2198,8 +2118,6 @@ static struct clk_branch gcc_ufs_rx_symbol_0_clk = {
.enable_mask = BIT(0),
.hw.init = &(struct clk_init_data){
.name = "gcc_ufs_rx_symbol_0_clk",
- .parent_hws = (const struct clk_hw *[]){ &system_noc_clk_src.clkr.hw },
- .num_parents = 1,
.ops = &clk_branch2_ops,
},
},
@@ -2213,8 +2131,6 @@ static struct clk_branch gcc_ufs_rx_symbol_1_clk = {
.enable_mask = BIT(0),
.hw.init = &(struct clk_init_data){
.name = "gcc_ufs_rx_symbol_1_clk",
- .parent_hws = (const struct clk_hw *[]){ &system_noc_clk_src.clkr.hw },
- .num_parents = 1,
.ops = &clk_branch2_ops,
},
},
@@ -2243,8 +2159,6 @@ static struct clk_branch gcc_ufs_tx_symbol_0_clk = {
.enable_mask = BIT(0),
.hw.init = &(struct clk_init_data){
.name = "gcc_ufs_tx_symbol_0_clk",
- .parent_hws = (const struct clk_hw *[]){ &system_noc_clk_src.clkr.hw },
- .num_parents = 1,
.ops = &clk_branch2_ops,
},
},
@@ -2258,8 +2172,6 @@ static struct clk_branch gcc_ufs_tx_symbol_1_clk = {
.enable_mask = BIT(0),
.hw.init = &(struct clk_init_data){
.name = "gcc_ufs_tx_symbol_1_clk",
- .parent_hws = (const struct clk_hw *[]){ &system_noc_clk_src.clkr.hw },
- .num_parents = 1,
.ops = &clk_branch2_ops,
},
},
@@ -2364,8 +2276,6 @@ static struct clk_branch gcc_usb_hs_ahb_clk = {
.enable_mask = BIT(0),
.hw.init = &(struct clk_init_data){
.name = "gcc_usb_hs_ahb_clk",
- .parent_hws = (const struct clk_hw *[]){ &periph_noc_clk_src.clkr.hw },
- .num_parents = 1,
.ops = &clk_branch2_ops,
},
},
@@ -2488,8 +2398,6 @@ static struct clk_branch gcc_boot_rom_ahb_clk = {
.enable_mask = BIT(10),
.hw.init = &(struct clk_init_data){
.name = "gcc_boot_rom_ahb_clk",
- .parent_hws = (const struct clk_hw *[]){ &config_noc_clk_src.clkr.hw },
- .num_parents = 1,
.ops = &clk_branch2_ops,
},
},
@@ -2503,8 +2411,6 @@ static struct clk_branch gcc_prng_ahb_clk = {
.enable_mask = BIT(13),
.hw.init = &(struct clk_init_data){
.name = "gcc_prng_ahb_clk",
- .parent_hws = (const struct clk_hw *[]){ &periph_noc_clk_src.clkr.hw },
- .num_parents = 1,
.ops = &clk_branch2_ops,
},
},
@@ -2547,9 +2453,6 @@ static struct clk_regmap *gcc_msm8994_clocks[] = {
[GPLL0] = &gpll0.clkr,
[GPLL4_EARLY] = &gpll4_early.clkr,
[GPLL4] = &gpll4.clkr,
- [CONFIG_NOC_CLK_SRC] = &config_noc_clk_src.clkr,
- [PERIPH_NOC_CLK_SRC] = &periph_noc_clk_src.clkr,
- [SYSTEM_NOC_CLK_SRC] = &system_noc_clk_src.clkr,
[UFS_AXI_CLK_SRC] = &ufs_axi_clk_src.clkr,
[USB30_MASTER_CLK_SRC] = &usb30_master_clk_src.clkr,
[BLSP1_QUP1_I2C_APPS_CLK_SRC] = &blsp1_qup1_i2c_apps_clk_src.clkr,
@@ -2696,6 +2599,15 @@ static struct clk_regmap *gcc_msm8994_clocks[] = {
[USB_SS_PHY_LDO] = &usb_ss_phy_ldo.clkr,
[GCC_BOOT_ROM_AHB_CLK] = &gcc_boot_rom_ahb_clk.clkr,
[GCC_PRNG_AHB_CLK] = &gcc_prng_ahb_clk.clkr,
+
+ /*
+ * The following clocks should NOT be managed by this driver, but they once were
+ * mistakengly added. Now they are only here to indicate that they are not defined
+ * on purpose, even though the names will stay in the header file (for ABI sanity).
+ */
+ [CONFIG_NOC_CLK_SRC] = NULL,
+ [PERIPH_NOC_CLK_SRC] = NULL,
+ [SYSTEM_NOC_CLK_SRC] = NULL,
};
static struct gdsc *gcc_msm8994_gdscs[] = {
diff --git a/drivers/clk/qcom/gdsc.c b/drivers/clk/qcom/gdsc.c
index 7e1dd8ccfa38..44520efc6c72 100644
--- a/drivers/clk/qcom/gdsc.c
+++ b/drivers/clk/qcom/gdsc.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
- * Copyright (c) 2015, 2017-2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2015, 2017-2018, 2022, The Linux Foundation. All rights reserved.
*/
#include <linux/bitops.h>
@@ -35,9 +35,14 @@
#define CFG_GDSCR_OFFSET 0x4
/* Wait 2^n CXO cycles between all states. Here, n=2 (4 cycles). */
-#define EN_REST_WAIT_VAL (0x2 << 20)
-#define EN_FEW_WAIT_VAL (0x8 << 16)
-#define CLK_DIS_WAIT_VAL (0x2 << 12)
+#define EN_REST_WAIT_VAL 0x2
+#define EN_FEW_WAIT_VAL 0x8
+#define CLK_DIS_WAIT_VAL 0x2
+
+/* Transition delay shifts */
+#define EN_REST_WAIT_SHIFT 20
+#define EN_FEW_WAIT_SHIFT 16
+#define CLK_DIS_WAIT_SHIFT 12
#define RETAIN_MEM BIT(14)
#define RETAIN_PERIPH BIT(13)
@@ -380,7 +385,18 @@ static int gdsc_init(struct gdsc *sc)
*/
mask = HW_CONTROL_MASK | SW_OVERRIDE_MASK |
EN_REST_WAIT_MASK | EN_FEW_WAIT_MASK | CLK_DIS_WAIT_MASK;
- val = EN_REST_WAIT_VAL | EN_FEW_WAIT_VAL | CLK_DIS_WAIT_VAL;
+
+ if (!sc->en_rest_wait_val)
+ sc->en_rest_wait_val = EN_REST_WAIT_VAL;
+ if (!sc->en_few_wait_val)
+ sc->en_few_wait_val = EN_FEW_WAIT_VAL;
+ if (!sc->clk_dis_wait_val)
+ sc->clk_dis_wait_val = CLK_DIS_WAIT_VAL;
+
+ val = sc->en_rest_wait_val << EN_REST_WAIT_SHIFT |
+ sc->en_few_wait_val << EN_FEW_WAIT_SHIFT |
+ sc->clk_dis_wait_val << CLK_DIS_WAIT_SHIFT;
+
ret = regmap_update_bits(sc->regmap, sc->gdscr, mask, val);
if (ret)
return ret;
diff --git a/drivers/clk/qcom/gdsc.h b/drivers/clk/qcom/gdsc.h
index d7cc4c21a9d4..ad313d7210bd 100644
--- a/drivers/clk/qcom/gdsc.h
+++ b/drivers/clk/qcom/gdsc.h
@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
- * Copyright (c) 2015, 2017-2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2015, 2017-2018, 2022, The Linux Foundation. All rights reserved.
*/
#ifndef __QCOM_GDSC_H__
@@ -22,6 +22,9 @@ struct reset_controller_dev;
* @cxcs: offsets of branch registers to toggle mem/periph bits in
* @cxc_count: number of @cxcs
* @pwrsts: Possible powerdomain power states
+ * @en_rest_wait_val: transition delay value for receiving enr ack signal
+ * @en_few_wait_val: transition delay value for receiving enf ack signal
+ * @clk_dis_wait_val: transition delay value for halting clock
* @resets: ids of resets associated with this gdsc
* @reset_count: number of @resets
* @rcdev: reset controller
@@ -36,6 +39,9 @@ struct gdsc {
unsigned int clamp_io_ctrl;
unsigned int *cxcs;
unsigned int cxc_count;
+ unsigned int en_rest_wait_val;
+ unsigned int en_few_wait_val;
+ unsigned int clk_dis_wait_val;
const u8 pwrsts;
/* Powerdomain allowable state bitfields */
#define PWRSTS_OFF BIT(0)
diff --git a/drivers/clk/samsung/Kconfig b/drivers/clk/samsung/Kconfig
index 0e18d6ff2916..8e8245ab3fd1 100644
--- a/drivers/clk/samsung/Kconfig
+++ b/drivers/clk/samsung/Kconfig
@@ -11,6 +11,7 @@ config COMMON_CLK_SAMSUNG
select EXYNOS_5410_COMMON_CLK if ARM && SOC_EXYNOS5410
select EXYNOS_5420_COMMON_CLK if ARM && SOC_EXYNOS5420
select EXYNOS_ARM64_COMMON_CLK if ARM64 && ARCH_EXYNOS
+ select TESLA_FSD_COMMON_CLK if ARM64 && ARCH_TESLA_FSD
config S3C64XX_COMMON_CLK
bool "Samsung S3C64xx clock controller support" if COMPILE_TEST
@@ -124,3 +125,11 @@ config S3C2443_COMMON_CLK
help
Support for the clock controller present on the Samsung
S3C2416/S3C2443 SoCs. Choose Y here only if you build for this SoC.
+
+config TESLA_FSD_COMMON_CLK
+ bool "Tesla FSD clock controller support" if COMPILE_TEST
+ depends on COMMON_CLK_SAMSUNG
+ depends on EXYNOS_ARM64_COMMON_CLK
+ help
+ Support for the clock controller present on the Tesla FSD SoC.
+ Choose Y here only if you build for this SoC.
diff --git a/drivers/clk/samsung/Makefile b/drivers/clk/samsung/Makefile
index 0df74916a895..17e5d1cb9da2 100644
--- a/drivers/clk/samsung/Makefile
+++ b/drivers/clk/samsung/Makefile
@@ -26,3 +26,4 @@ obj-$(CONFIG_S3C2412_COMMON_CLK)+= clk-s3c2412.o
obj-$(CONFIG_S3C2443_COMMON_CLK)+= clk-s3c2443.o
obj-$(CONFIG_S3C64XX_COMMON_CLK) += clk-s3c64xx.o
obj-$(CONFIG_S5PV210_COMMON_CLK) += clk-s5pv210.o clk-s5pv210-audss.o
+obj-$(CONFIG_TESLA_FSD_COMMON_CLK) += clk-fsd.o
diff --git a/drivers/clk/samsung/clk-fsd.c b/drivers/clk/samsung/clk-fsd.c
new file mode 100644
index 000000000000..5d009c70e97d
--- /dev/null
+++ b/drivers/clk/samsung/clk-fsd.c
@@ -0,0 +1,1803 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2017-2022 Samsung Electronics Co., Ltd.
+ * https://www.samsung.com
+ * Copyright (c) 2017-2022 Tesla, Inc.
+ * https://www.tesla.com
+ *
+ * Common Clock Framework support for FSD SoC.
+ */
+
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+
+#include <dt-bindings/clock/fsd-clk.h>
+
+#include "clk.h"
+#include "clk-exynos-arm64.h"
+
+/* Register Offset definitions for CMU_CMU (0x11c10000) */
+#define PLL_LOCKTIME_PLL_SHARED0 0x0
+#define PLL_LOCKTIME_PLL_SHARED1 0x4
+#define PLL_LOCKTIME_PLL_SHARED2 0x8
+#define PLL_LOCKTIME_PLL_SHARED3 0xc
+#define PLL_CON0_PLL_SHARED0 0x100
+#define PLL_CON0_PLL_SHARED1 0x120
+#define PLL_CON0_PLL_SHARED2 0x140
+#define PLL_CON0_PLL_SHARED3 0x160
+#define MUX_CMU_CIS0_CLKMUX 0x1000
+#define MUX_CMU_CIS1_CLKMUX 0x1004
+#define MUX_CMU_CIS2_CLKMUX 0x1008
+#define MUX_CMU_CPUCL_SWITCHMUX 0x100c
+#define MUX_CMU_FSYS1_ACLK_MUX 0x1014
+#define MUX_PLL_SHARED0_MUX 0x1020
+#define MUX_PLL_SHARED1_MUX 0x1024
+#define DIV_CMU_CIS0_CLK 0x1800
+#define DIV_CMU_CIS1_CLK 0x1804
+#define DIV_CMU_CIS2_CLK 0x1808
+#define DIV_CMU_CMU_ACLK 0x180c
+#define DIV_CMU_CPUCL_SWITCH 0x1810
+#define DIV_CMU_FSYS0_SHARED0DIV4 0x181c
+#define DIV_CMU_FSYS0_SHARED1DIV3 0x1820
+#define DIV_CMU_FSYS0_SHARED1DIV4 0x1824
+#define DIV_CMU_FSYS1_SHARED0DIV4 0x1828
+#define DIV_CMU_FSYS1_SHARED0DIV8 0x182c
+#define DIV_CMU_IMEM_ACLK 0x1834
+#define DIV_CMU_IMEM_DMACLK 0x1838
+#define DIV_CMU_IMEM_TCUCLK 0x183c
+#define DIV_CMU_PERIC_SHARED0DIV20 0x1844
+#define DIV_CMU_PERIC_SHARED0DIV3_TBUCLK 0x1848
+#define DIV_CMU_PERIC_SHARED1DIV36 0x184c
+#define DIV_CMU_PERIC_SHARED1DIV4_DMACLK 0x1850
+#define DIV_PLL_SHARED0_DIV2 0x1858
+#define DIV_PLL_SHARED0_DIV3 0x185c
+#define DIV_PLL_SHARED0_DIV4 0x1860
+#define DIV_PLL_SHARED0_DIV6 0x1864
+#define DIV_PLL_SHARED1_DIV3 0x1868
+#define DIV_PLL_SHARED1_DIV36 0x186c
+#define DIV_PLL_SHARED1_DIV4 0x1870
+#define DIV_PLL_SHARED1_DIV9 0x1874
+#define GAT_CMU_CIS0_CLKGATE 0x2000
+#define GAT_CMU_CIS1_CLKGATE 0x2004
+#define GAT_CMU_CIS2_CLKGATE 0x2008
+#define GAT_CMU_CPUCL_SWITCH_GATE 0x200c
+#define GAT_CMU_FSYS0_SHARED0DIV4_GATE 0x2018
+#define GAT_CMU_FSYS0_SHARED1DIV4_CLK 0x201c
+#define GAT_CMU_FSYS0_SHARED1DIV4_GATE 0x2020
+#define GAT_CMU_FSYS1_SHARED0DIV4_GATE 0x2024
+#define GAT_CMU_FSYS1_SHARED1DIV4_GATE 0x2028
+#define GAT_CMU_IMEM_ACLK_GATE 0x2030
+#define GAT_CMU_IMEM_DMACLK_GATE 0x2034
+#define GAT_CMU_IMEM_TCUCLK_GATE 0x2038
+#define GAT_CMU_PERIC_SHARED0DIVE3_TBUCLK_GATE 0x2040
+#define GAT_CMU_PERIC_SHARED0DIVE4_GATE 0x2044
+#define GAT_CMU_PERIC_SHARED1DIV4_DMACLK_GATE 0x2048
+#define GAT_CMU_PERIC_SHARED1DIVE4_GATE 0x204c
+#define GAT_CMU_CMU_CMU_IPCLKPORT_PCLK 0x2054
+#define GAT_CMU_AXI2APB_CMU_IPCLKPORT_ACLK 0x2058
+#define GAT_CMU_NS_BRDG_CMU_IPCLKPORT_CLK__PSOC_CMU__CLK_CMU 0x205c
+#define GAT_CMU_SYSREG_CMU_IPCLKPORT_PCLK 0x2060
+
+static const unsigned long cmu_clk_regs[] __initconst = {
+ PLL_LOCKTIME_PLL_SHARED0,
+ PLL_LOCKTIME_PLL_SHARED1,
+ PLL_LOCKTIME_PLL_SHARED2,
+ PLL_LOCKTIME_PLL_SHARED3,
+ PLL_CON0_PLL_SHARED0,
+ PLL_CON0_PLL_SHARED1,
+ PLL_CON0_PLL_SHARED2,
+ PLL_CON0_PLL_SHARED3,
+ MUX_CMU_CIS0_CLKMUX,
+ MUX_CMU_CIS1_CLKMUX,
+ MUX_CMU_CIS2_CLKMUX,
+ MUX_CMU_CPUCL_SWITCHMUX,
+ MUX_CMU_FSYS1_ACLK_MUX,
+ MUX_PLL_SHARED0_MUX,
+ MUX_PLL_SHARED1_MUX,
+ DIV_CMU_CIS0_CLK,
+ DIV_CMU_CIS1_CLK,
+ DIV_CMU_CIS2_CLK,
+ DIV_CMU_CMU_ACLK,
+ DIV_CMU_CPUCL_SWITCH,
+ DIV_CMU_FSYS0_SHARED0DIV4,
+ DIV_CMU_FSYS0_SHARED1DIV3,
+ DIV_CMU_FSYS0_SHARED1DIV4,
+ DIV_CMU_FSYS1_SHARED0DIV4,
+ DIV_CMU_FSYS1_SHARED0DIV8,
+ DIV_CMU_IMEM_ACLK,
+ DIV_CMU_IMEM_DMACLK,
+ DIV_CMU_IMEM_TCUCLK,
+ DIV_CMU_PERIC_SHARED0DIV20,
+ DIV_CMU_PERIC_SHARED0DIV3_TBUCLK,
+ DIV_CMU_PERIC_SHARED1DIV36,
+ DIV_CMU_PERIC_SHARED1DIV4_DMACLK,
+ DIV_PLL_SHARED0_DIV2,
+ DIV_PLL_SHARED0_DIV3,
+ DIV_PLL_SHARED0_DIV4,
+ DIV_PLL_SHARED0_DIV6,
+ DIV_PLL_SHARED1_DIV3,
+ DIV_PLL_SHARED1_DIV36,
+ DIV_PLL_SHARED1_DIV4,
+ DIV_PLL_SHARED1_DIV9,
+ GAT_CMU_CIS0_CLKGATE,
+ GAT_CMU_CIS1_CLKGATE,
+ GAT_CMU_CIS2_CLKGATE,
+ GAT_CMU_CPUCL_SWITCH_GATE,
+ GAT_CMU_FSYS0_SHARED0DIV4_GATE,
+ GAT_CMU_FSYS0_SHARED1DIV4_CLK,
+ GAT_CMU_FSYS0_SHARED1DIV4_GATE,
+ GAT_CMU_FSYS1_SHARED0DIV4_GATE,
+ GAT_CMU_FSYS1_SHARED1DIV4_GATE,
+ GAT_CMU_IMEM_ACLK_GATE,
+ GAT_CMU_IMEM_DMACLK_GATE,
+ GAT_CMU_IMEM_TCUCLK_GATE,
+ GAT_CMU_PERIC_SHARED0DIVE3_TBUCLK_GATE,
+ GAT_CMU_PERIC_SHARED0DIVE4_GATE,
+ GAT_CMU_PERIC_SHARED1DIV4_DMACLK_GATE,
+ GAT_CMU_PERIC_SHARED1DIVE4_GATE,
+ GAT_CMU_CMU_CMU_IPCLKPORT_PCLK,
+ GAT_CMU_AXI2APB_CMU_IPCLKPORT_ACLK,
+ GAT_CMU_NS_BRDG_CMU_IPCLKPORT_CLK__PSOC_CMU__CLK_CMU,
+ GAT_CMU_SYSREG_CMU_IPCLKPORT_PCLK,
+};
+
+static const struct samsung_pll_rate_table pll_shared0_rate_table[] __initconst = {
+ PLL_35XX_RATE(24 * MHZ, 2000000000U, 250, 3, 0),
+};
+
+static const struct samsung_pll_rate_table pll_shared1_rate_table[] __initconst = {
+ PLL_35XX_RATE(24 * MHZ, 2400000000U, 200, 2, 0),
+};
+
+static const struct samsung_pll_rate_table pll_shared2_rate_table[] __initconst = {
+ PLL_35XX_RATE(24 * MHZ, 2400000000U, 200, 2, 0),
+};
+
+static const struct samsung_pll_rate_table pll_shared3_rate_table[] __initconst = {
+ PLL_35XX_RATE(24 * MHZ, 1800000000U, 150, 2, 0),
+};
+
+static const struct samsung_pll_clock cmu_pll_clks[] __initconst = {
+ PLL(pll_142xx, 0, "fout_pll_shared0", "fin_pll", PLL_LOCKTIME_PLL_SHARED0,
+ PLL_CON0_PLL_SHARED0, pll_shared0_rate_table),
+ PLL(pll_142xx, 0, "fout_pll_shared1", "fin_pll", PLL_LOCKTIME_PLL_SHARED1,
+ PLL_CON0_PLL_SHARED1, pll_shared1_rate_table),
+ PLL(pll_142xx, 0, "fout_pll_shared2", "fin_pll", PLL_LOCKTIME_PLL_SHARED2,
+ PLL_CON0_PLL_SHARED2, pll_shared2_rate_table),
+ PLL(pll_142xx, 0, "fout_pll_shared3", "fin_pll", PLL_LOCKTIME_PLL_SHARED3,
+ PLL_CON0_PLL_SHARED3, pll_shared3_rate_table),
+};
+
+/* List of parent clocks for Muxes in CMU_CMU */
+PNAME(mout_cmu_shared0_pll_p) = { "fin_pll", "fout_pll_shared0" };
+PNAME(mout_cmu_shared1_pll_p) = { "fin_pll", "fout_pll_shared1" };
+PNAME(mout_cmu_shared2_pll_p) = { "fin_pll", "fout_pll_shared2" };
+PNAME(mout_cmu_shared3_pll_p) = { "fin_pll", "fout_pll_shared3" };
+PNAME(mout_cmu_cis0_clkmux_p) = { "fin_pll", "dout_cmu_pll_shared0_div4" };
+PNAME(mout_cmu_cis1_clkmux_p) = { "fin_pll", "dout_cmu_pll_shared0_div4" };
+PNAME(mout_cmu_cis2_clkmux_p) = { "fin_pll", "dout_cmu_pll_shared0_div4" };
+PNAME(mout_cmu_cpucl_switchmux_p) = { "mout_cmu_pll_shared2", "mout_cmu_pll_shared0_mux" };
+PNAME(mout_cmu_fsys1_aclk_mux_p) = { "dout_cmu_pll_shared0_div4", "fin_pll" };
+PNAME(mout_cmu_pll_shared0_mux_p) = { "fin_pll", "mout_cmu_pll_shared0" };
+PNAME(mout_cmu_pll_shared1_mux_p) = { "fin_pll", "mout_cmu_pll_shared1" };
+
+static const struct samsung_mux_clock cmu_mux_clks[] __initconst = {
+ MUX(0, "mout_cmu_pll_shared0", mout_cmu_shared0_pll_p, PLL_CON0_PLL_SHARED0, 4, 1),
+ MUX(0, "mout_cmu_pll_shared1", mout_cmu_shared1_pll_p, PLL_CON0_PLL_SHARED1, 4, 1),
+ MUX(0, "mout_cmu_pll_shared2", mout_cmu_shared2_pll_p, PLL_CON0_PLL_SHARED2, 4, 1),
+ MUX(0, "mout_cmu_pll_shared3", mout_cmu_shared3_pll_p, PLL_CON0_PLL_SHARED3, 4, 1),
+ MUX(0, "mout_cmu_cis0_clkmux", mout_cmu_cis0_clkmux_p, MUX_CMU_CIS0_CLKMUX, 0, 1),
+ MUX(0, "mout_cmu_cis1_clkmux", mout_cmu_cis1_clkmux_p, MUX_CMU_CIS1_CLKMUX, 0, 1),
+ MUX(0, "mout_cmu_cis2_clkmux", mout_cmu_cis2_clkmux_p, MUX_CMU_CIS2_CLKMUX, 0, 1),
+ MUX(0, "mout_cmu_cpucl_switchmux", mout_cmu_cpucl_switchmux_p,
+ MUX_CMU_CPUCL_SWITCHMUX, 0, 1),
+ MUX(0, "mout_cmu_fsys1_aclk_mux", mout_cmu_fsys1_aclk_mux_p, MUX_CMU_FSYS1_ACLK_MUX, 0, 1),
+ MUX(0, "mout_cmu_pll_shared0_mux", mout_cmu_pll_shared0_mux_p, MUX_PLL_SHARED0_MUX, 0, 1),
+ MUX(0, "mout_cmu_pll_shared1_mux", mout_cmu_pll_shared1_mux_p, MUX_PLL_SHARED1_MUX, 0, 1),
+};
+
+static const struct samsung_div_clock cmu_div_clks[] __initconst = {
+ DIV(0, "dout_cmu_cis0_clk", "cmu_cis0_clkgate", DIV_CMU_CIS0_CLK, 0, 4),
+ DIV(0, "dout_cmu_cis1_clk", "cmu_cis1_clkgate", DIV_CMU_CIS1_CLK, 0, 4),
+ DIV(0, "dout_cmu_cis2_clk", "cmu_cis2_clkgate", DIV_CMU_CIS2_CLK, 0, 4),
+ DIV(0, "dout_cmu_cmu_aclk", "dout_cmu_pll_shared1_div9", DIV_CMU_CMU_ACLK, 0, 4),
+ DIV(0, "dout_cmu_cpucl_switch", "cmu_cpucl_switch_gate", DIV_CMU_CPUCL_SWITCH, 0, 4),
+ DIV(DOUT_CMU_FSYS0_SHARED0DIV4, "dout_cmu_fsys0_shared0div4", "cmu_fsys0_shared0div4_gate",
+ DIV_CMU_FSYS0_SHARED0DIV4, 0, 4),
+ DIV(0, "dout_cmu_fsys0_shared1div3", "cmu_fsys0_shared1div4_clk",
+ DIV_CMU_FSYS0_SHARED1DIV3, 0, 4),
+ DIV(DOUT_CMU_FSYS0_SHARED1DIV4, "dout_cmu_fsys0_shared1div4", "cmu_fsys0_shared1div4_gate",
+ DIV_CMU_FSYS0_SHARED1DIV4, 0, 4),
+ DIV(DOUT_CMU_FSYS1_SHARED0DIV4, "dout_cmu_fsys1_shared0div4", "cmu_fsys1_shared0div4_gate",
+ DIV_CMU_FSYS1_SHARED0DIV4, 0, 4),
+ DIV(DOUT_CMU_FSYS1_SHARED0DIV8, "dout_cmu_fsys1_shared0div8", "cmu_fsys1_shared1div4_gate",
+ DIV_CMU_FSYS1_SHARED0DIV8, 0, 4),
+ DIV(DOUT_CMU_IMEM_ACLK, "dout_cmu_imem_aclk", "cmu_imem_aclk_gate",
+ DIV_CMU_IMEM_ACLK, 0, 4),
+ DIV(DOUT_CMU_IMEM_DMACLK, "dout_cmu_imem_dmaclk", "cmu_imem_dmaclk_gate",
+ DIV_CMU_IMEM_DMACLK, 0, 4),
+ DIV(DOUT_CMU_IMEM_TCUCLK, "dout_cmu_imem_tcuclk", "cmu_imem_tcuclk_gate",
+ DIV_CMU_IMEM_TCUCLK, 0, 4),
+ DIV(DOUT_CMU_PERIC_SHARED0DIV20, "dout_cmu_peric_shared0div20",
+ "cmu_peric_shared0dive4_gate", DIV_CMU_PERIC_SHARED0DIV20, 0, 4),
+ DIV(DOUT_CMU_PERIC_SHARED0DIV3_TBUCLK, "dout_cmu_peric_shared0div3_tbuclk",
+ "cmu_peric_shared0dive3_tbuclk_gate", DIV_CMU_PERIC_SHARED0DIV3_TBUCLK, 0, 4),
+ DIV(DOUT_CMU_PERIC_SHARED1DIV36, "dout_cmu_peric_shared1div36",
+ "cmu_peric_shared1dive4_gate", DIV_CMU_PERIC_SHARED1DIV36, 0, 4),
+ DIV(DOUT_CMU_PERIC_SHARED1DIV4_DMACLK, "dout_cmu_peric_shared1div4_dmaclk",
+ "cmu_peric_shared1div4_dmaclk_gate", DIV_CMU_PERIC_SHARED1DIV4_DMACLK, 0, 4),
+ DIV(0, "dout_cmu_pll_shared0_div2", "mout_cmu_pll_shared0_mux",
+ DIV_PLL_SHARED0_DIV2, 0, 4),
+ DIV(0, "dout_cmu_pll_shared0_div3", "mout_cmu_pll_shared0_mux",
+ DIV_PLL_SHARED0_DIV3, 0, 4),
+ DIV(DOUT_CMU_PLL_SHARED0_DIV4, "dout_cmu_pll_shared0_div4", "dout_cmu_pll_shared0_div2",
+ DIV_PLL_SHARED0_DIV4, 0, 4),
+ DIV(DOUT_CMU_PLL_SHARED0_DIV6, "dout_cmu_pll_shared0_div6", "dout_cmu_pll_shared0_div3",
+ DIV_PLL_SHARED0_DIV6, 0, 4),
+ DIV(0, "dout_cmu_pll_shared1_div3", "mout_cmu_pll_shared1_mux",
+ DIV_PLL_SHARED1_DIV3, 0, 4),
+ DIV(0, "dout_cmu_pll_shared1_div36", "dout_cmu_pll_shared1_div9",
+ DIV_PLL_SHARED1_DIV36, 0, 4),
+ DIV(0, "dout_cmu_pll_shared1_div4", "mout_cmu_pll_shared1_mux",
+ DIV_PLL_SHARED1_DIV4, 0, 4),
+ DIV(0, "dout_cmu_pll_shared1_div9", "dout_cmu_pll_shared1_div3",
+ DIV_PLL_SHARED1_DIV9, 0, 4),
+};
+
+static const struct samsung_gate_clock cmu_gate_clks[] __initconst = {
+ GATE(0, "cmu_cis0_clkgate", "mout_cmu_cis0_clkmux", GAT_CMU_CIS0_CLKGATE, 21,
+ CLK_IGNORE_UNUSED, 0),
+ GATE(0, "cmu_cis1_clkgate", "mout_cmu_cis1_clkmux", GAT_CMU_CIS1_CLKGATE, 21,
+ CLK_IGNORE_UNUSED, 0),
+ GATE(0, "cmu_cis2_clkgate", "mout_cmu_cis2_clkmux", GAT_CMU_CIS2_CLKGATE, 21,
+ CLK_IGNORE_UNUSED, 0),
+ GATE(CMU_CPUCL_SWITCH_GATE, "cmu_cpucl_switch_gate", "mout_cmu_cpucl_switchmux",
+ GAT_CMU_CPUCL_SWITCH_GATE, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(GAT_CMU_FSYS0_SHARED0DIV4, "cmu_fsys0_shared0div4_gate", "dout_cmu_pll_shared0_div4",
+ GAT_CMU_FSYS0_SHARED0DIV4_GATE, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(0, "cmu_fsys0_shared1div4_clk", "dout_cmu_pll_shared1_div3",
+ GAT_CMU_FSYS0_SHARED1DIV4_CLK, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(0, "cmu_fsys0_shared1div4_gate", "dout_cmu_pll_shared1_div4",
+ GAT_CMU_FSYS0_SHARED1DIV4_GATE, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(0, "cmu_fsys1_shared0div4_gate", "mout_cmu_fsys1_aclk_mux",
+ GAT_CMU_FSYS1_SHARED0DIV4_GATE, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(0, "cmu_fsys1_shared1div4_gate", "dout_cmu_fsys1_shared0div4",
+ GAT_CMU_FSYS1_SHARED1DIV4_GATE, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(0, "cmu_imem_aclk_gate", "dout_cmu_pll_shared1_div9", GAT_CMU_IMEM_ACLK_GATE, 21,
+ CLK_IGNORE_UNUSED, 0),
+ GATE(0, "cmu_imem_dmaclk_gate", "mout_cmu_pll_shared1_mux", GAT_CMU_IMEM_DMACLK_GATE, 21,
+ CLK_IGNORE_UNUSED, 0),
+ GATE(0, "cmu_imem_tcuclk_gate", "dout_cmu_pll_shared0_div3", GAT_CMU_IMEM_TCUCLK_GATE, 21,
+ CLK_IGNORE_UNUSED, 0),
+ GATE(0, "cmu_peric_shared0dive3_tbuclk_gate", "dout_cmu_pll_shared0_div3",
+ GAT_CMU_PERIC_SHARED0DIVE3_TBUCLK_GATE, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(0, "cmu_peric_shared0dive4_gate", "dout_cmu_pll_shared0_div4",
+ GAT_CMU_PERIC_SHARED0DIVE4_GATE, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(0, "cmu_peric_shared1div4_dmaclk_gate", "dout_cmu_pll_shared1_div4",
+ GAT_CMU_PERIC_SHARED1DIV4_DMACLK_GATE, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(0, "cmu_peric_shared1dive4_gate", "dout_cmu_pll_shared1_div36",
+ GAT_CMU_PERIC_SHARED1DIVE4_GATE, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(0, "cmu_uid_cmu_cmu_cmu_ipclkport_pclk", "dout_cmu_cmu_aclk",
+ GAT_CMU_CMU_CMU_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(0, "cmu_uid_axi2apb_cmu_ipclkport_aclk", "dout_cmu_cmu_aclk",
+ GAT_CMU_AXI2APB_CMU_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(0, "cmu_uid_ns_brdg_cmu_ipclkport_clk__psoc_cmu__clk_cmu", "dout_cmu_cmu_aclk",
+ GAT_CMU_NS_BRDG_CMU_IPCLKPORT_CLK__PSOC_CMU__CLK_CMU, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(0, "cmu_uid_sysreg_cmu_ipclkport_pclk", "dout_cmu_cmu_aclk",
+ GAT_CMU_SYSREG_CMU_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+};
+
+static const struct samsung_cmu_info cmu_cmu_info __initconst = {
+ .pll_clks = cmu_pll_clks,
+ .nr_pll_clks = ARRAY_SIZE(cmu_pll_clks),
+ .mux_clks = cmu_mux_clks,
+ .nr_mux_clks = ARRAY_SIZE(cmu_mux_clks),
+ .div_clks = cmu_div_clks,
+ .nr_div_clks = ARRAY_SIZE(cmu_div_clks),
+ .gate_clks = cmu_gate_clks,
+ .nr_gate_clks = ARRAY_SIZE(cmu_gate_clks),
+ .nr_clk_ids = CMU_NR_CLK,
+ .clk_regs = cmu_clk_regs,
+ .nr_clk_regs = ARRAY_SIZE(cmu_clk_regs),
+};
+
+static void __init fsd_clk_cmu_init(struct device_node *np)
+{
+ samsung_cmu_register_one(np, &cmu_cmu_info);
+}
+
+CLK_OF_DECLARE(fsd_clk_cmu, "tesla,fsd-clock-cmu", fsd_clk_cmu_init);
+
+/* Register Offset definitions for CMU_PERIC (0x14010000) */
+#define PLL_CON0_PERIC_DMACLK_MUX 0x100
+#define PLL_CON0_PERIC_EQOS_BUSCLK_MUX 0x120
+#define PLL_CON0_PERIC_PCLK_MUX 0x140
+#define PLL_CON0_PERIC_TBUCLK_MUX 0x160
+#define PLL_CON0_SPI_CLK 0x180
+#define PLL_CON0_SPI_PCLK 0x1a0
+#define PLL_CON0_UART_CLK 0x1c0
+#define PLL_CON0_UART_PCLK 0x1e0
+#define MUX_PERIC_EQOS_PHYRXCLK 0x1000
+#define DIV_EQOS_BUSCLK 0x1800
+#define DIV_PERIC_MCAN_CLK 0x1804
+#define DIV_RGMII_CLK 0x1808
+#define DIV_RII_CLK 0x180c
+#define DIV_RMII_CLK 0x1810
+#define DIV_SPI_CLK 0x1814
+#define DIV_UART_CLK 0x1818
+#define GAT_EQOS_TOP_IPCLKPORT_CLK_PTP_REF_I 0x2000
+#define GAT_GPIO_PERIC_IPCLKPORT_OSCCLK 0x2004
+#define GAT_PERIC_ADC0_IPCLKPORT_I_OSCCLK 0x2008
+#define GAT_PERIC_CMU_PERIC_IPCLKPORT_PCLK 0x200c
+#define GAT_PERIC_PWM0_IPCLKPORT_I_OSCCLK 0x2010
+#define GAT_PERIC_PWM1_IPCLKPORT_I_OSCCLK 0x2014
+#define GAT_ASYNC_APB_DMA0_IPCLKPORT_PCLKM 0x2018
+#define GAT_ASYNC_APB_DMA0_IPCLKPORT_PCLKS 0x201c
+#define GAT_ASYNC_APB_DMA1_IPCLKPORT_PCLKM 0x2020
+#define GAT_ASYNC_APB_DMA1_IPCLKPORT_PCLKS 0x2024
+#define GAT_AXI2APB_PERIC0_IPCLKPORT_ACLK 0x2028
+#define GAT_AXI2APB_PERIC1_IPCLKPORT_ACLK 0x202c
+#define GAT_AXI2APB_PERIC2_IPCLKPORT_ACLK 0x2030
+#define GAT_BUS_D_PERIC_IPCLKPORT_DMACLK 0x2034
+#define GAT_BUS_D_PERIC_IPCLKPORT_EQOSCLK 0x2038
+#define GAT_BUS_D_PERIC_IPCLKPORT_MAINCLK 0x203c
+#define GAT_BUS_P_PERIC_IPCLKPORT_EQOSCLK 0x2040
+#define GAT_BUS_P_PERIC_IPCLKPORT_MAINCLK 0x2044
+#define GAT_BUS_P_PERIC_IPCLKPORT_SMMUCLK 0x2048
+#define GAT_EQOS_TOP_IPCLKPORT_ACLK_I 0x204c
+#define GAT_EQOS_TOP_IPCLKPORT_CLK_RX_I 0x2050
+#define GAT_EQOS_TOP_IPCLKPORT_HCLK_I 0x2054
+#define GAT_EQOS_TOP_IPCLKPORT_RGMII_CLK_I 0x2058
+#define GAT_EQOS_TOP_IPCLKPORT_RII_CLK_I 0x205c
+#define GAT_EQOS_TOP_IPCLKPORT_RMII_CLK_I 0x2060
+#define GAT_GPIO_PERIC_IPCLKPORT_PCLK 0x2064
+#define GAT_NS_BRDG_PERIC_IPCLKPORT_CLK__PSOC_PERIC__CLK_PERIC_D 0x2068
+#define GAT_NS_BRDG_PERIC_IPCLKPORT_CLK__PSOC_PERIC__CLK_PERIC_P 0x206c
+#define GAT_PERIC_ADC0_IPCLKPORT_PCLK_S0 0x2070
+#define GAT_PERIC_DMA0_IPCLKPORT_ACLK 0x2074
+#define GAT_PERIC_DMA1_IPCLKPORT_ACLK 0x2078
+#define GAT_PERIC_I2C0_IPCLKPORT_I_PCLK 0x207c
+#define GAT_PERIC_I2C1_IPCLKPORT_I_PCLK 0x2080
+#define GAT_PERIC_I2C2_IPCLKPORT_I_PCLK 0x2084
+#define GAT_PERIC_I2C3_IPCLKPORT_I_PCLK 0x2088
+#define GAT_PERIC_I2C4_IPCLKPORT_I_PCLK 0x208c
+#define GAT_PERIC_I2C5_IPCLKPORT_I_PCLK 0x2090
+#define GAT_PERIC_I2C6_IPCLKPORT_I_PCLK 0x2094
+#define GAT_PERIC_I2C7_IPCLKPORT_I_PCLK 0x2098
+#define GAT_PERIC_MCAN0_IPCLKPORT_CCLK 0x209c
+#define GAT_PERIC_MCAN0_IPCLKPORT_PCLK 0x20a0
+#define GAT_PERIC_MCAN1_IPCLKPORT_CCLK 0x20a4
+#define GAT_PERIC_MCAN1_IPCLKPORT_PCLK 0x20a8
+#define GAT_PERIC_MCAN2_IPCLKPORT_CCLK 0x20ac
+#define GAT_PERIC_MCAN2_IPCLKPORT_PCLK 0x20b0
+#define GAT_PERIC_MCAN3_IPCLKPORT_CCLK 0x20b4
+#define GAT_PERIC_MCAN3_IPCLKPORT_PCLK 0x20b8
+#define GAT_PERIC_PWM0_IPCLKPORT_I_PCLK_S0 0x20bc
+#define GAT_PERIC_PWM1_IPCLKPORT_I_PCLK_S0 0x20c0
+#define GAT_PERIC_SMMU_IPCLKPORT_CCLK 0x20c4
+#define GAT_PERIC_SMMU_IPCLKPORT_PERIC_BCLK 0x20c8
+#define GAT_PERIC_SPI0_IPCLKPORT_I_PCLK 0x20cc
+#define GAT_PERIC_SPI0_IPCLKPORT_I_SCLK_SPI 0x20d0
+#define GAT_PERIC_SPI1_IPCLKPORT_I_PCLK 0x20d4
+#define GAT_PERIC_SPI1_IPCLKPORT_I_SCLK_SPI 0x20d8
+#define GAT_PERIC_SPI2_IPCLKPORT_I_PCLK 0x20dc
+#define GAT_PERIC_SPI2_IPCLKPORT_I_SCLK_SPI 0x20e0
+#define GAT_PERIC_TDM0_IPCLKPORT_HCLK_M 0x20e4
+#define GAT_PERIC_TDM0_IPCLKPORT_PCLK 0x20e8
+#define GAT_PERIC_TDM1_IPCLKPORT_HCLK_M 0x20ec
+#define GAT_PERIC_TDM1_IPCLKPORT_PCLK 0x20f0
+#define GAT_PERIC_UART0_IPCLKPORT_I_SCLK_UART 0x20f4
+#define GAT_PERIC_UART0_IPCLKPORT_PCLK 0x20f8
+#define GAT_PERIC_UART1_IPCLKPORT_I_SCLK_UART 0x20fc
+#define GAT_PERIC_UART1_IPCLKPORT_PCLK 0x2100
+#define GAT_SYSREG_PERI_IPCLKPORT_PCLK 0x2104
+
+static const unsigned long peric_clk_regs[] __initconst = {
+ PLL_CON0_PERIC_DMACLK_MUX,
+ PLL_CON0_PERIC_EQOS_BUSCLK_MUX,
+ PLL_CON0_PERIC_PCLK_MUX,
+ PLL_CON0_PERIC_TBUCLK_MUX,
+ PLL_CON0_SPI_CLK,
+ PLL_CON0_SPI_PCLK,
+ PLL_CON0_UART_CLK,
+ PLL_CON0_UART_PCLK,
+ MUX_PERIC_EQOS_PHYRXCLK,
+ DIV_EQOS_BUSCLK,
+ DIV_PERIC_MCAN_CLK,
+ DIV_RGMII_CLK,
+ DIV_RII_CLK,
+ DIV_RMII_CLK,
+ DIV_SPI_CLK,
+ DIV_UART_CLK,
+ GAT_EQOS_TOP_IPCLKPORT_CLK_PTP_REF_I,
+ GAT_GPIO_PERIC_IPCLKPORT_OSCCLK,
+ GAT_PERIC_ADC0_IPCLKPORT_I_OSCCLK,
+ GAT_PERIC_CMU_PERIC_IPCLKPORT_PCLK,
+ GAT_PERIC_PWM0_IPCLKPORT_I_OSCCLK,
+ GAT_PERIC_PWM1_IPCLKPORT_I_OSCCLK,
+ GAT_ASYNC_APB_DMA0_IPCLKPORT_PCLKM,
+ GAT_ASYNC_APB_DMA0_IPCLKPORT_PCLKS,
+ GAT_ASYNC_APB_DMA1_IPCLKPORT_PCLKM,
+ GAT_ASYNC_APB_DMA1_IPCLKPORT_PCLKS,
+ GAT_AXI2APB_PERIC0_IPCLKPORT_ACLK,
+ GAT_AXI2APB_PERIC1_IPCLKPORT_ACLK,
+ GAT_AXI2APB_PERIC2_IPCLKPORT_ACLK,
+ GAT_BUS_D_PERIC_IPCLKPORT_DMACLK,
+ GAT_BUS_D_PERIC_IPCLKPORT_EQOSCLK,
+ GAT_BUS_D_PERIC_IPCLKPORT_MAINCLK,
+ GAT_BUS_P_PERIC_IPCLKPORT_EQOSCLK,
+ GAT_BUS_P_PERIC_IPCLKPORT_MAINCLK,
+ GAT_BUS_P_PERIC_IPCLKPORT_SMMUCLK,
+ GAT_EQOS_TOP_IPCLKPORT_ACLK_I,
+ GAT_EQOS_TOP_IPCLKPORT_CLK_RX_I,
+ GAT_EQOS_TOP_IPCLKPORT_HCLK_I,
+ GAT_EQOS_TOP_IPCLKPORT_RGMII_CLK_I,
+ GAT_EQOS_TOP_IPCLKPORT_RII_CLK_I,
+ GAT_EQOS_TOP_IPCLKPORT_RMII_CLK_I,
+ GAT_GPIO_PERIC_IPCLKPORT_PCLK,
+ GAT_NS_BRDG_PERIC_IPCLKPORT_CLK__PSOC_PERIC__CLK_PERIC_D,
+ GAT_NS_BRDG_PERIC_IPCLKPORT_CLK__PSOC_PERIC__CLK_PERIC_P,
+ GAT_PERIC_ADC0_IPCLKPORT_PCLK_S0,
+ GAT_PERIC_DMA0_IPCLKPORT_ACLK,
+ GAT_PERIC_DMA1_IPCLKPORT_ACLK,
+ GAT_PERIC_I2C0_IPCLKPORT_I_PCLK,
+ GAT_PERIC_I2C1_IPCLKPORT_I_PCLK,
+ GAT_PERIC_I2C2_IPCLKPORT_I_PCLK,
+ GAT_PERIC_I2C3_IPCLKPORT_I_PCLK,
+ GAT_PERIC_I2C4_IPCLKPORT_I_PCLK,
+ GAT_PERIC_I2C5_IPCLKPORT_I_PCLK,
+ GAT_PERIC_I2C6_IPCLKPORT_I_PCLK,
+ GAT_PERIC_I2C7_IPCLKPORT_I_PCLK,
+ GAT_PERIC_MCAN0_IPCLKPORT_CCLK,
+ GAT_PERIC_MCAN0_IPCLKPORT_PCLK,
+ GAT_PERIC_MCAN1_IPCLKPORT_CCLK,
+ GAT_PERIC_MCAN1_IPCLKPORT_PCLK,
+ GAT_PERIC_MCAN2_IPCLKPORT_CCLK,
+ GAT_PERIC_MCAN2_IPCLKPORT_PCLK,
+ GAT_PERIC_MCAN3_IPCLKPORT_CCLK,
+ GAT_PERIC_MCAN3_IPCLKPORT_PCLK,
+ GAT_PERIC_PWM0_IPCLKPORT_I_PCLK_S0,
+ GAT_PERIC_PWM1_IPCLKPORT_I_PCLK_S0,
+ GAT_PERIC_SMMU_IPCLKPORT_CCLK,
+ GAT_PERIC_SMMU_IPCLKPORT_PERIC_BCLK,
+ GAT_PERIC_SPI0_IPCLKPORT_I_PCLK,
+ GAT_PERIC_SPI0_IPCLKPORT_I_SCLK_SPI,
+ GAT_PERIC_SPI1_IPCLKPORT_I_PCLK,
+ GAT_PERIC_SPI1_IPCLKPORT_I_SCLK_SPI,
+ GAT_PERIC_SPI2_IPCLKPORT_I_PCLK,
+ GAT_PERIC_SPI2_IPCLKPORT_I_SCLK_SPI,
+ GAT_PERIC_TDM0_IPCLKPORT_HCLK_M,
+ GAT_PERIC_TDM0_IPCLKPORT_PCLK,
+ GAT_PERIC_TDM1_IPCLKPORT_HCLK_M,
+ GAT_PERIC_TDM1_IPCLKPORT_PCLK,
+ GAT_PERIC_UART0_IPCLKPORT_I_SCLK_UART,
+ GAT_PERIC_UART0_IPCLKPORT_PCLK,
+ GAT_PERIC_UART1_IPCLKPORT_I_SCLK_UART,
+ GAT_PERIC_UART1_IPCLKPORT_PCLK,
+ GAT_SYSREG_PERI_IPCLKPORT_PCLK,
+};
+
+static const struct samsung_fixed_rate_clock peric_fixed_clks[] __initconst = {
+ FRATE(PERIC_EQOS_PHYRXCLK, "eqos_phyrxclk", NULL, 0, 125000000),
+};
+
+/* List of parent clocks for Muxes in CMU_PERIC */
+PNAME(mout_peric_dmaclk_p) = { "fin_pll", "cmu_peric_shared1div4_dmaclk_gate" };
+PNAME(mout_peric_eqos_busclk_p) = { "fin_pll", "dout_cmu_pll_shared0_div4" };
+PNAME(mout_peric_pclk_p) = { "fin_pll", "dout_cmu_peric_shared1div36" };
+PNAME(mout_peric_tbuclk_p) = { "fin_pll", "dout_cmu_peric_shared0div3_tbuclk" };
+PNAME(mout_peric_spi_clk_p) = { "fin_pll", "dout_cmu_peric_shared0div20" };
+PNAME(mout_peric_spi_pclk_p) = { "fin_pll", "dout_cmu_peric_shared1div36" };
+PNAME(mout_peric_uart_clk_p) = { "fin_pll", "dout_cmu_peric_shared1div4_dmaclk" };
+PNAME(mout_peric_uart_pclk_p) = { "fin_pll", "dout_cmu_peric_shared1div36" };
+PNAME(mout_peric_eqos_phyrxclk_p) = { "dout_peric_rgmii_clk", "eqos_phyrxclk" };
+
+static const struct samsung_mux_clock peric_mux_clks[] __initconst = {
+ MUX(0, "mout_peric_dmaclk", mout_peric_dmaclk_p, PLL_CON0_PERIC_DMACLK_MUX, 4, 1),
+ MUX(0, "mout_peric_eqos_busclk", mout_peric_eqos_busclk_p,
+ PLL_CON0_PERIC_EQOS_BUSCLK_MUX, 4, 1),
+ MUX(0, "mout_peric_pclk", mout_peric_pclk_p, PLL_CON0_PERIC_PCLK_MUX, 4, 1),
+ MUX(0, "mout_peric_tbuclk", mout_peric_tbuclk_p, PLL_CON0_PERIC_TBUCLK_MUX, 4, 1),
+ MUX(0, "mout_peric_spi_clk", mout_peric_spi_clk_p, PLL_CON0_SPI_CLK, 4, 1),
+ MUX(0, "mout_peric_spi_pclk", mout_peric_spi_pclk_p, PLL_CON0_SPI_PCLK, 4, 1),
+ MUX(0, "mout_peric_uart_clk", mout_peric_uart_clk_p, PLL_CON0_UART_CLK, 4, 1),
+ MUX(0, "mout_peric_uart_pclk", mout_peric_uart_pclk_p, PLL_CON0_UART_PCLK, 4, 1),
+ MUX(PERIC_EQOS_PHYRXCLK_MUX, "mout_peric_eqos_phyrxclk", mout_peric_eqos_phyrxclk_p,
+ MUX_PERIC_EQOS_PHYRXCLK, 0, 1),
+};
+
+static const struct samsung_div_clock peric_div_clks[] __initconst = {
+ DIV(0, "dout_peric_eqos_busclk", "mout_peric_eqos_busclk", DIV_EQOS_BUSCLK, 0, 4),
+ DIV(0, "dout_peric_mcan_clk", "mout_peric_dmaclk", DIV_PERIC_MCAN_CLK, 0, 4),
+ DIV(PERIC_DOUT_RGMII_CLK, "dout_peric_rgmii_clk", "mout_peric_eqos_busclk",
+ DIV_RGMII_CLK, 0, 4),
+ DIV(0, "dout_peric_rii_clk", "dout_peric_rmii_clk", DIV_RII_CLK, 0, 4),
+ DIV(0, "dout_peric_rmii_clk", "dout_peric_rgmii_clk", DIV_RMII_CLK, 0, 4),
+ DIV(0, "dout_peric_spi_clk", "mout_peric_spi_clk", DIV_SPI_CLK, 0, 6),
+ DIV(0, "dout_peric_uart_clk", "mout_peric_uart_clk", DIV_UART_CLK, 0, 6),
+};
+
+static const struct samsung_gate_clock peric_gate_clks[] __initconst = {
+ GATE(PERIC_EQOS_TOP_IPCLKPORT_CLK_PTP_REF_I, "peric_eqos_top_ipclkport_clk_ptp_ref_i",
+ "fin_pll", GAT_EQOS_TOP_IPCLKPORT_CLK_PTP_REF_I, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(0, "peric_gpio_peric_ipclkport_oscclk", "fin_pll", GAT_GPIO_PERIC_IPCLKPORT_OSCCLK,
+ 21, CLK_IGNORE_UNUSED, 0),
+ GATE(PERIC_PCLK_ADCIF, "peric_adc0_ipclkport_i_oscclk", "fin_pll",
+ GAT_PERIC_ADC0_IPCLKPORT_I_OSCCLK, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(0, "peric_cmu_peric_ipclkport_pclk", "mout_peric_pclk",
+ GAT_PERIC_CMU_PERIC_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(0, "peric_pwm0_ipclkport_i_oscclk", "fin_pll", GAT_PERIC_PWM0_IPCLKPORT_I_OSCCLK, 21,
+ CLK_IGNORE_UNUSED, 0),
+ GATE(0, "peric_pwm1_ipclkport_i_oscclk", "fin_pll", GAT_PERIC_PWM1_IPCLKPORT_I_OSCCLK, 21,
+ CLK_IGNORE_UNUSED, 0),
+ GATE(0, "peric_async_apb_dma0_ipclkport_pclkm", "mout_peric_dmaclk",
+ GAT_ASYNC_APB_DMA0_IPCLKPORT_PCLKM, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(0, "peric_async_apb_dma0_ipclkport_pclks", "mout_peric_pclk",
+ GAT_ASYNC_APB_DMA0_IPCLKPORT_PCLKS, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(0, "peric_async_apb_dma1_ipclkport_pclkm", "mout_peric_dmaclk",
+ GAT_ASYNC_APB_DMA1_IPCLKPORT_PCLKM, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(0, "peric_async_apb_dma1_ipclkport_pclks", "mout_peric_pclk",
+ GAT_ASYNC_APB_DMA1_IPCLKPORT_PCLKS, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(0, "peric_axi2apb_peric0_ipclkport_aclk", "mout_peric_pclk",
+ GAT_AXI2APB_PERIC0_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(0, "peric_axi2apb_peric1_ipclkport_aclk", "mout_peric_pclk",
+ GAT_AXI2APB_PERIC1_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(0, "peric_axi2apb_peric2_ipclkport_aclk", "mout_peric_pclk",
+ GAT_AXI2APB_PERIC2_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(0, "peric_bus_d_peric_ipclkport_dmaclk", "mout_peric_dmaclk",
+ GAT_BUS_D_PERIC_IPCLKPORT_DMACLK, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(PERIC_BUS_D_PERIC_IPCLKPORT_EQOSCLK, "peric_bus_d_peric_ipclkport_eqosclk",
+ "dout_peric_eqos_busclk", GAT_BUS_D_PERIC_IPCLKPORT_EQOSCLK, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(0, "peric_bus_d_peric_ipclkport_mainclk", "mout_peric_tbuclk",
+ GAT_BUS_D_PERIC_IPCLKPORT_MAINCLK, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(PERIC_BUS_P_PERIC_IPCLKPORT_EQOSCLK, "peric_bus_p_peric_ipclkport_eqosclk",
+ "dout_peric_eqos_busclk", GAT_BUS_P_PERIC_IPCLKPORT_EQOSCLK, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(0, "peric_bus_p_peric_ipclkport_mainclk", "mout_peric_pclk",
+ GAT_BUS_P_PERIC_IPCLKPORT_MAINCLK, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(0, "peric_bus_p_peric_ipclkport_smmuclk", "mout_peric_tbuclk",
+ GAT_BUS_P_PERIC_IPCLKPORT_SMMUCLK, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(PERIC_EQOS_TOP_IPCLKPORT_ACLK_I, "peric_eqos_top_ipclkport_aclk_i",
+ "dout_peric_eqos_busclk", GAT_EQOS_TOP_IPCLKPORT_ACLK_I, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(PERIC_EQOS_TOP_IPCLKPORT_CLK_RX_I, "peric_eqos_top_ipclkport_clk_rx_i",
+ "mout_peric_eqos_phyrxclk", GAT_EQOS_TOP_IPCLKPORT_CLK_RX_I, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(PERIC_EQOS_TOP_IPCLKPORT_HCLK_I, "peric_eqos_top_ipclkport_hclk_i",
+ "dout_peric_eqos_busclk", GAT_EQOS_TOP_IPCLKPORT_HCLK_I, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(PERIC_EQOS_TOP_IPCLKPORT_RGMII_CLK_I, "peric_eqos_top_ipclkport_rgmii_clk_i",
+ "dout_peric_rgmii_clk", GAT_EQOS_TOP_IPCLKPORT_RGMII_CLK_I, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(0, "peric_eqos_top_ipclkport_rii_clk_i", "dout_peric_rii_clk",
+ GAT_EQOS_TOP_IPCLKPORT_RII_CLK_I, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(0, "peric_eqos_top_ipclkport_rmii_clk_i", "dout_peric_rmii_clk",
+ GAT_EQOS_TOP_IPCLKPORT_RMII_CLK_I, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(0, "peric_gpio_peric_ipclkport_pclk", "mout_peric_pclk",
+ GAT_GPIO_PERIC_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(0, "peric_ns_brdg_peric_ipclkport_clk__psoc_peric__clk_peric_d", "mout_peric_tbuclk",
+ GAT_NS_BRDG_PERIC_IPCLKPORT_CLK__PSOC_PERIC__CLK_PERIC_D, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(0, "peric_ns_brdg_peric_ipclkport_clk__psoc_peric__clk_peric_p", "mout_peric_pclk",
+ GAT_NS_BRDG_PERIC_IPCLKPORT_CLK__PSOC_PERIC__CLK_PERIC_P, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(0, "peric_adc0_ipclkport_pclk_s0", "mout_peric_pclk",
+ GAT_PERIC_ADC0_IPCLKPORT_PCLK_S0, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(PERIC_DMA0_IPCLKPORT_ACLK, "peric_dma0_ipclkport_aclk", "mout_peric_dmaclk",
+ GAT_PERIC_DMA0_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(PERIC_DMA1_IPCLKPORT_ACLK, "peric_dma1_ipclkport_aclk", "mout_peric_dmaclk",
+ GAT_PERIC_DMA1_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(PERIC_PCLK_HSI2C0, "peric_i2c0_ipclkport_i_pclk", "mout_peric_pclk",
+ GAT_PERIC_I2C0_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(PERIC_PCLK_HSI2C1, "peric_i2c1_ipclkport_i_pclk", "mout_peric_pclk",
+ GAT_PERIC_I2C1_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(PERIC_PCLK_HSI2C2, "peric_i2c2_ipclkport_i_pclk", "mout_peric_pclk",
+ GAT_PERIC_I2C2_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(PERIC_PCLK_HSI2C3, "peric_i2c3_ipclkport_i_pclk", "mout_peric_pclk",
+ GAT_PERIC_I2C3_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(PERIC_PCLK_HSI2C4, "peric_i2c4_ipclkport_i_pclk", "mout_peric_pclk",
+ GAT_PERIC_I2C4_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(PERIC_PCLK_HSI2C5, "peric_i2c5_ipclkport_i_pclk", "mout_peric_pclk",
+ GAT_PERIC_I2C5_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(PERIC_PCLK_HSI2C6, "peric_i2c6_ipclkport_i_pclk", "mout_peric_pclk",
+ GAT_PERIC_I2C6_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(PERIC_PCLK_HSI2C7, "peric_i2c7_ipclkport_i_pclk", "mout_peric_pclk",
+ GAT_PERIC_I2C7_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(PERIC_MCAN0_IPCLKPORT_CCLK, "peric_mcan0_ipclkport_cclk", "dout_peric_mcan_clk",
+ GAT_PERIC_MCAN0_IPCLKPORT_CCLK, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(PERIC_MCAN0_IPCLKPORT_PCLK, "peric_mcan0_ipclkport_pclk", "mout_peric_pclk",
+ GAT_PERIC_MCAN0_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(PERIC_MCAN1_IPCLKPORT_CCLK, "peric_mcan1_ipclkport_cclk", "dout_peric_mcan_clk",
+ GAT_PERIC_MCAN1_IPCLKPORT_CCLK, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(PERIC_MCAN1_IPCLKPORT_PCLK, "peric_mcan1_ipclkport_pclk", "mout_peric_pclk",
+ GAT_PERIC_MCAN1_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(PERIC_MCAN2_IPCLKPORT_CCLK, "peric_mcan2_ipclkport_cclk", "dout_peric_mcan_clk",
+ GAT_PERIC_MCAN2_IPCLKPORT_CCLK, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(PERIC_MCAN2_IPCLKPORT_PCLK, "peric_mcan2_ipclkport_pclk", "mout_peric_pclk",
+ GAT_PERIC_MCAN2_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(PERIC_MCAN3_IPCLKPORT_CCLK, "peric_mcan3_ipclkport_cclk", "dout_peric_mcan_clk",
+ GAT_PERIC_MCAN3_IPCLKPORT_CCLK, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(PERIC_MCAN3_IPCLKPORT_PCLK, "peric_mcan3_ipclkport_pclk", "mout_peric_pclk",
+ GAT_PERIC_MCAN3_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(PERIC_PWM0_IPCLKPORT_I_PCLK_S0, "peric_pwm0_ipclkport_i_pclk_s0", "mout_peric_pclk",
+ GAT_PERIC_PWM0_IPCLKPORT_I_PCLK_S0, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(PERIC_PWM1_IPCLKPORT_I_PCLK_S0, "peric_pwm1_ipclkport_i_pclk_s0", "mout_peric_pclk",
+ GAT_PERIC_PWM1_IPCLKPORT_I_PCLK_S0, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(0, "peric_smmu_ipclkport_cclk", "mout_peric_tbuclk",
+ GAT_PERIC_SMMU_IPCLKPORT_CCLK, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(0, "peric_smmu_ipclkport_peric_bclk", "mout_peric_tbuclk",
+ GAT_PERIC_SMMU_IPCLKPORT_PERIC_BCLK, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(PERIC_PCLK_SPI0, "peric_spi0_ipclkport_i_pclk", "mout_peric_spi_pclk",
+ GAT_PERIC_SPI0_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(PERIC_SCLK_SPI0, "peric_spi0_ipclkport_i_sclk_spi", "dout_peric_spi_clk",
+ GAT_PERIC_SPI0_IPCLKPORT_I_SCLK_SPI, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(PERIC_PCLK_SPI1, "peric_spi1_ipclkport_i_pclk", "mout_peric_spi_pclk",
+ GAT_PERIC_SPI1_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(PERIC_SCLK_SPI1, "peric_spi1_ipclkport_i_sclk_spi", "dout_peric_spi_clk",
+ GAT_PERIC_SPI1_IPCLKPORT_I_SCLK_SPI, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(PERIC_PCLK_SPI2, "peric_spi2_ipclkport_i_pclk", "mout_peric_spi_pclk",
+ GAT_PERIC_SPI2_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(PERIC_SCLK_SPI2, "peric_spi2_ipclkport_i_sclk_spi", "dout_peric_spi_clk",
+ GAT_PERIC_SPI2_IPCLKPORT_I_SCLK_SPI, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(PERIC_HCLK_TDM0, "peric_tdm0_ipclkport_hclk_m", "mout_peric_pclk",
+ GAT_PERIC_TDM0_IPCLKPORT_HCLK_M, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(PERIC_PCLK_TDM0, "peric_tdm0_ipclkport_pclk", "mout_peric_pclk",
+ GAT_PERIC_TDM0_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(PERIC_HCLK_TDM1, "peric_tdm1_ipclkport_hclk_m", "mout_peric_pclk",
+ GAT_PERIC_TDM1_IPCLKPORT_HCLK_M, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(PERIC_PCLK_TDM1, "peric_tdm1_ipclkport_pclk", "mout_peric_pclk",
+ GAT_PERIC_TDM1_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(PERIC_SCLK_UART0, "peric_uart0_ipclkport_i_sclk_uart", "dout_peric_uart_clk",
+ GAT_PERIC_UART0_IPCLKPORT_I_SCLK_UART, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(PERIC_PCLK_UART0, "peric_uart0_ipclkport_pclk", "mout_peric_uart_pclk",
+ GAT_PERIC_UART0_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(PERIC_SCLK_UART1, "peric_uart1_ipclkport_i_sclk_uart", "dout_peric_uart_clk",
+ GAT_PERIC_UART1_IPCLKPORT_I_SCLK_UART, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(PERIC_PCLK_UART1, "peric_uart1_ipclkport_pclk", "mout_peric_uart_pclk",
+ GAT_PERIC_UART1_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(0, "peric_sysreg_peri_ipclkport_pclk", "mout_peric_pclk",
+ GAT_SYSREG_PERI_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+};
+
+static const struct samsung_cmu_info peric_cmu_info __initconst = {
+ .mux_clks = peric_mux_clks,
+ .nr_mux_clks = ARRAY_SIZE(peric_mux_clks),
+ .div_clks = peric_div_clks,
+ .nr_div_clks = ARRAY_SIZE(peric_div_clks),
+ .gate_clks = peric_gate_clks,
+ .nr_gate_clks = ARRAY_SIZE(peric_gate_clks),
+ .fixed_clks = peric_fixed_clks,
+ .nr_fixed_clks = ARRAY_SIZE(peric_fixed_clks),
+ .nr_clk_ids = PERIC_NR_CLK,
+ .clk_regs = peric_clk_regs,
+ .nr_clk_regs = ARRAY_SIZE(peric_clk_regs),
+ .clk_name = "dout_cmu_pll_shared0_div4",
+};
+
+/* Register Offset definitions for CMU_FSYS0 (0x15010000) */
+#define PLL_CON0_CLKCMU_FSYS0_UNIPRO 0x100
+#define PLL_CON0_CLK_FSYS0_SLAVEBUSCLK 0x140
+#define PLL_CON0_EQOS_RGMII_125_MUX1 0x160
+#define DIV_CLK_UNIPRO 0x1800
+#define DIV_EQS_RGMII_CLK_125 0x1804
+#define DIV_PERIBUS_GRP 0x1808
+#define DIV_EQOS_RII_CLK2O5 0x180c
+#define DIV_EQOS_RMIICLK_25 0x1810
+#define DIV_PCIE_PHY_OSCCLK 0x1814
+#define GAT_FSYS0_EQOS_TOP0_IPCLKPORT_CLK_PTP_REF_I 0x2004
+#define GAT_FSYS0_EQOS_TOP0_IPCLKPORT_CLK_RX_I 0x2008
+#define GAT_FSYS0_FSYS0_CMU_FSYS0_IPCLKPORT_PCLK 0x200c
+#define GAT_FSYS0_GPIO_FSYS0_IPCLKPORT_OSCCLK 0x2010
+#define GAT_FSYS0_PCIE_TOP_IPCLKPORT_PCIEG3_PHY_X4_INST_0_PLL_REFCLK_FROM_XO 0x2014
+#define GAT_FSYS0_PCIE_TOP_IPCLKPORT_PIPE_PAL_INST_0_I_IMMORTAL_CLK 0x2018
+#define GAT_FSYS0_PCIE_TOP_IPCLKPORT_FSD_PCIE_SUB_CTRL_INST_0_AUX_CLK_SOC 0x201c
+#define GAT_FSYS0_UFS_TOP0_IPCLKPORT_I_MPHY_REFCLK_IXTAL24 0x2020
+#define GAT_FSYS0_UFS_TOP0_IPCLKPORT_I_MPHY_REFCLK_IXTAL26 0x2024
+#define GAT_FSYS0_UFS_TOP1_IPCLKPORT_I_MPHY_REFCLK_IXTAL24 0x2028
+#define GAT_FSYS0_UFS_TOP1_IPCLKPORT_I_MPHY_REFCLK_IXTAL26 0x202c
+#define GAT_FSYS0_AHBBR_FSYS0_IPCLKPORT_HCLK 0x2038
+#define GAT_FSYS0_AXI2APB_FSYS0_IPCLKPORT_ACLK 0x203c
+#define GAT_FSYS0_BUS_D_FSYS0_IPCLKPORT_MAINCLK 0x2040
+#define GAT_FSYS0_BUS_D_FSYS0_IPCLKPORT_PERICLK 0x2044
+#define GAT_FSYS0_BUS_P_FSYS0_IPCLKPORT_MAINCLK 0x2048
+#define GAT_FSYS0_BUS_P_FSYS0_IPCLKPORT_TCUCLK 0x204c
+#define GAT_FSYS0_CPE425_IPCLKPORT_ACLK 0x2050
+#define GAT_FSYS0_EQOS_TOP0_IPCLKPORT_ACLK_I 0x2054
+#define GAT_FSYS0_EQOS_TOP0_IPCLKPORT_HCLK_I 0x2058
+#define GAT_FSYS0_EQOS_TOP0_IPCLKPORT_RGMII_CLK_I 0x205c
+#define GAT_FSYS0_EQOS_TOP0_IPCLKPORT_RII_CLK_I 0x2060
+#define GAT_FSYS0_EQOS_TOP0_IPCLKPORT_RMII_CLK_I 0x2064
+#define GAT_FSYS0_GPIO_FSYS0_IPCLKPORT_PCLK 0x2068
+#define GAT_FSYS0_NS_BRDG_FSYS0_IPCLKPORT_CLK__PSOC_FSYS0__CLK_FSYS0_D 0x206c
+#define GAT_FSYS0_NS_BRDG_FSYS0_IPCLKPORT_CLK__PSOC_FSYS0__CLK_FSYS0_D1 0x2070
+#define GAT_FSYS0_NS_BRDG_FSYS0_IPCLKPORT_CLK__PSOC_FSYS0__CLK_FSYS0_P 0x2074
+#define GAT_FSYS0_NS_BRDG_FSYS0_IPCLKPORT_CLK__PSOC_FSYS0__CLK_FSYS0_S 0x2078
+#define GAT_FSYS0_PCIE_TOP_IPCLKPORT_PCIEG3_PHY_X4_INST_0_I_APB_PCLK 0x207c
+#define GAT_FSYS0_PCIE_TOP_IPCLKPORT_PCIEG3_PHY_X4_INST_0_PLL_REFCLK_FROM_SYSPLL 0x2080
+#define GAT_FSYS0_PCIE_TOP_IPCLKPORT_PIPE_PAL_INST_0_I_APB_PCLK_0 0x2084
+#define GAT_FSYS0_PCIE_TOP_IPCLKPORT_FSD_PCIE_SUB_CTRL_INST_0_DBI_ACLK_SOC 0x2088
+#define GAT_FSYS0_PCIE_TOP_IPCLKPORT_FSD_PCIE_SUB_CTRL_INST_0_I_DRIVER_APB_CLK 0x208c
+#define GAT_FSYS0_PCIE_TOP_IPCLKPORT_FSD_PCIE_SUB_CTRL_INST_0_MSTR_ACLK_SOC 0x2090
+#define GAT_FSYS0_PCIE_TOP_IPCLKPORT_FSD_PCIE_SUB_CTRL_INST_0_SLV_ACLK_SOC 0x2094
+#define GAT_FSYS0_SMMU_FSYS0_IPCLKPORT_CCLK 0x2098
+#define GAT_FSYS0_SMMU_FSYS0_IPCLKPORT_FSYS0_BCLK 0x209c
+#define GAT_FSYS0_SYSREG_FSYS0_IPCLKPORT_PCLK 0x20a0
+#define GAT_FSYS0_UFS_TOP0_IPCLKPORT_HCLK_BUS 0x20a4
+#define GAT_FSYS0_UFS_TOP0_IPCLKPORT_I_ACLK 0x20a8
+#define GAT_FSYS0_UFS_TOP0_IPCLKPORT_I_CLK_UNIPRO 0x20ac
+#define GAT_FSYS0_UFS_TOP0_IPCLKPORT_I_FMP_CLK 0x20b0
+#define GAT_FSYS0_UFS_TOP1_IPCLKPORT_HCLK_BUS 0x20b4
+#define GAT_FSYS0_UFS_TOP1_IPCLKPORT_I_ACLK 0x20b8
+#define GAT_FSYS0_UFS_TOP1_IPCLKPORT_I_CLK_UNIPRO 0x20bc
+#define GAT_FSYS0_UFS_TOP1_IPCLKPORT_I_FMP_CLK 0x20c0
+#define GAT_FSYS0_RII_CLK_DIVGATE 0x20d4
+
+static const unsigned long fsys0_clk_regs[] __initconst = {
+ PLL_CON0_CLKCMU_FSYS0_UNIPRO,
+ PLL_CON0_CLK_FSYS0_SLAVEBUSCLK,
+ PLL_CON0_EQOS_RGMII_125_MUX1,
+ DIV_CLK_UNIPRO,
+ DIV_EQS_RGMII_CLK_125,
+ DIV_PERIBUS_GRP,
+ DIV_EQOS_RII_CLK2O5,
+ DIV_EQOS_RMIICLK_25,
+ DIV_PCIE_PHY_OSCCLK,
+ GAT_FSYS0_EQOS_TOP0_IPCLKPORT_CLK_PTP_REF_I,
+ GAT_FSYS0_EQOS_TOP0_IPCLKPORT_CLK_RX_I,
+ GAT_FSYS0_FSYS0_CMU_FSYS0_IPCLKPORT_PCLK,
+ GAT_FSYS0_GPIO_FSYS0_IPCLKPORT_OSCCLK,
+ GAT_FSYS0_PCIE_TOP_IPCLKPORT_PCIEG3_PHY_X4_INST_0_PLL_REFCLK_FROM_XO,
+ GAT_FSYS0_PCIE_TOP_IPCLKPORT_PIPE_PAL_INST_0_I_IMMORTAL_CLK,
+ GAT_FSYS0_PCIE_TOP_IPCLKPORT_FSD_PCIE_SUB_CTRL_INST_0_AUX_CLK_SOC,
+ GAT_FSYS0_UFS_TOP0_IPCLKPORT_I_MPHY_REFCLK_IXTAL24,
+ GAT_FSYS0_UFS_TOP0_IPCLKPORT_I_MPHY_REFCLK_IXTAL26,
+ GAT_FSYS0_UFS_TOP1_IPCLKPORT_I_MPHY_REFCLK_IXTAL24,
+ GAT_FSYS0_UFS_TOP1_IPCLKPORT_I_MPHY_REFCLK_IXTAL26,
+ GAT_FSYS0_AHBBR_FSYS0_IPCLKPORT_HCLK,
+ GAT_FSYS0_AXI2APB_FSYS0_IPCLKPORT_ACLK,
+ GAT_FSYS0_BUS_D_FSYS0_IPCLKPORT_MAINCLK,
+ GAT_FSYS0_BUS_D_FSYS0_IPCLKPORT_PERICLK,
+ GAT_FSYS0_BUS_P_FSYS0_IPCLKPORT_MAINCLK,
+ GAT_FSYS0_BUS_P_FSYS0_IPCLKPORT_TCUCLK,
+ GAT_FSYS0_CPE425_IPCLKPORT_ACLK,
+ GAT_FSYS0_EQOS_TOP0_IPCLKPORT_ACLK_I,
+ GAT_FSYS0_EQOS_TOP0_IPCLKPORT_HCLK_I,
+ GAT_FSYS0_EQOS_TOP0_IPCLKPORT_RGMII_CLK_I,
+ GAT_FSYS0_EQOS_TOP0_IPCLKPORT_RII_CLK_I,
+ GAT_FSYS0_EQOS_TOP0_IPCLKPORT_RMII_CLK_I,
+ GAT_FSYS0_GPIO_FSYS0_IPCLKPORT_PCLK,
+ GAT_FSYS0_NS_BRDG_FSYS0_IPCLKPORT_CLK__PSOC_FSYS0__CLK_FSYS0_D,
+ GAT_FSYS0_NS_BRDG_FSYS0_IPCLKPORT_CLK__PSOC_FSYS0__CLK_FSYS0_D1,
+ GAT_FSYS0_NS_BRDG_FSYS0_IPCLKPORT_CLK__PSOC_FSYS0__CLK_FSYS0_P,
+ GAT_FSYS0_NS_BRDG_FSYS0_IPCLKPORT_CLK__PSOC_FSYS0__CLK_FSYS0_S,
+ GAT_FSYS0_PCIE_TOP_IPCLKPORT_PCIEG3_PHY_X4_INST_0_I_APB_PCLK,
+ GAT_FSYS0_PCIE_TOP_IPCLKPORT_PCIEG3_PHY_X4_INST_0_PLL_REFCLK_FROM_SYSPLL,
+ GAT_FSYS0_PCIE_TOP_IPCLKPORT_PIPE_PAL_INST_0_I_APB_PCLK_0,
+ GAT_FSYS0_PCIE_TOP_IPCLKPORT_FSD_PCIE_SUB_CTRL_INST_0_DBI_ACLK_SOC,
+ GAT_FSYS0_PCIE_TOP_IPCLKPORT_FSD_PCIE_SUB_CTRL_INST_0_I_DRIVER_APB_CLK,
+ GAT_FSYS0_PCIE_TOP_IPCLKPORT_FSD_PCIE_SUB_CTRL_INST_0_MSTR_ACLK_SOC,
+ GAT_FSYS0_PCIE_TOP_IPCLKPORT_FSD_PCIE_SUB_CTRL_INST_0_SLV_ACLK_SOC,
+ GAT_FSYS0_SMMU_FSYS0_IPCLKPORT_CCLK,
+ GAT_FSYS0_SMMU_FSYS0_IPCLKPORT_FSYS0_BCLK,
+ GAT_FSYS0_SYSREG_FSYS0_IPCLKPORT_PCLK,
+ GAT_FSYS0_UFS_TOP0_IPCLKPORT_HCLK_BUS,
+ GAT_FSYS0_UFS_TOP0_IPCLKPORT_I_ACLK,
+ GAT_FSYS0_UFS_TOP0_IPCLKPORT_I_CLK_UNIPRO,
+ GAT_FSYS0_UFS_TOP0_IPCLKPORT_I_FMP_CLK,
+ GAT_FSYS0_UFS_TOP1_IPCLKPORT_HCLK_BUS,
+ GAT_FSYS0_UFS_TOP1_IPCLKPORT_I_ACLK,
+ GAT_FSYS0_UFS_TOP1_IPCLKPORT_I_CLK_UNIPRO,
+ GAT_FSYS0_UFS_TOP1_IPCLKPORT_I_FMP_CLK,
+ GAT_FSYS0_RII_CLK_DIVGATE,
+};
+
+static const struct samsung_fixed_rate_clock fsys0_fixed_clks[] __initconst = {
+ FRATE(0, "pad_eqos0_phyrxclk", NULL, 0, 125000000),
+ FRATE(0, "i_mphy_refclk_ixtal26", NULL, 0, 26000000),
+ FRATE(0, "xtal_clk_pcie_phy", NULL, 0, 100000000),
+};
+
+/* List of parent clocks for Muxes in CMU_FSYS0 */
+PNAME(mout_fsys0_clkcmu_fsys0_unipro_p) = { "fin_pll", "dout_cmu_pll_shared0_div6" };
+PNAME(mout_fsys0_clk_fsys0_slavebusclk_p) = { "fin_pll", "dout_cmu_fsys0_shared1div4" };
+PNAME(mout_fsys0_eqos_rgmii_125_mux1_p) = { "fin_pll", "dout_cmu_fsys0_shared0div4" };
+
+static const struct samsung_mux_clock fsys0_mux_clks[] __initconst = {
+ MUX(0, "mout_fsys0_clkcmu_fsys0_unipro", mout_fsys0_clkcmu_fsys0_unipro_p,
+ PLL_CON0_CLKCMU_FSYS0_UNIPRO, 4, 1),
+ MUX(0, "mout_fsys0_clk_fsys0_slavebusclk", mout_fsys0_clk_fsys0_slavebusclk_p,
+ PLL_CON0_CLK_FSYS0_SLAVEBUSCLK, 4, 1),
+ MUX(0, "mout_fsys0_eqos_rgmii_125_mux1", mout_fsys0_eqos_rgmii_125_mux1_p,
+ PLL_CON0_EQOS_RGMII_125_MUX1, 4, 1),
+};
+
+static const struct samsung_div_clock fsys0_div_clks[] __initconst = {
+ DIV(0, "dout_fsys0_clk_unipro", "mout_fsys0_clkcmu_fsys0_unipro", DIV_CLK_UNIPRO, 0, 4),
+ DIV(0, "dout_fsys0_eqs_rgmii_clk_125", "mout_fsys0_eqos_rgmii_125_mux1",
+ DIV_EQS_RGMII_CLK_125, 0, 4),
+ DIV(FSYS0_DOUT_FSYS0_PERIBUS_GRP, "dout_fsys0_peribus_grp",
+ "mout_fsys0_clk_fsys0_slavebusclk", DIV_PERIBUS_GRP, 0, 4),
+ DIV(0, "dout_fsys0_eqos_rii_clk2o5", "fsys0_rii_clk_divgate", DIV_EQOS_RII_CLK2O5, 0, 4),
+ DIV(0, "dout_fsys0_eqos_rmiiclk_25", "mout_fsys0_eqos_rgmii_125_mux1",
+ DIV_EQOS_RMIICLK_25, 0, 5),
+ DIV(0, "dout_fsys0_pcie_phy_oscclk", "mout_fsys0_eqos_rgmii_125_mux1",
+ DIV_PCIE_PHY_OSCCLK, 0, 4),
+};
+
+static const struct samsung_gate_clock fsys0_gate_clks[] __initconst = {
+ GATE(FSYS0_EQOS_TOP0_IPCLKPORT_CLK_RX_I, "fsys0_eqos_top0_ipclkport_clk_rx_i",
+ "pad_eqos0_phyrxclk", GAT_FSYS0_EQOS_TOP0_IPCLKPORT_CLK_RX_I, 21,
+ CLK_IGNORE_UNUSED, 0),
+ GATE(PCIE_SUBCTRL_INST0_AUX_CLK_SOC,
+ "fsys0_pcie_top_ipclkport_fsd_pcie_sub_ctrl_inst_0_aux_clk_soc", "fin_pll",
+ GAT_FSYS0_PCIE_TOP_IPCLKPORT_FSD_PCIE_SUB_CTRL_INST_0_AUX_CLK_SOC, 21,
+ CLK_IGNORE_UNUSED, 0),
+ GATE(0, "fsys0_fsys0_cmu_fsys0_ipclkport_pclk", "dout_fsys0_peribus_grp",
+ GAT_FSYS0_FSYS0_CMU_FSYS0_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(0,
+ "fsys0_pcie_top_ipclkport_pcieg3_phy_x4_inst_0_pll_refclk_from_xo",
+ "xtal_clk_pcie_phy",
+ GAT_FSYS0_PCIE_TOP_IPCLKPORT_PCIEG3_PHY_X4_INST_0_PLL_REFCLK_FROM_XO, 21,
+ CLK_IGNORE_UNUSED, 0),
+ GATE(UFS0_MPHY_REFCLK_IXTAL24, "fsys0_ufs_top0_ipclkport_i_mphy_refclk_ixtal24",
+ "i_mphy_refclk_ixtal26", GAT_FSYS0_UFS_TOP0_IPCLKPORT_I_MPHY_REFCLK_IXTAL24, 21,
+ CLK_IGNORE_UNUSED, 0),
+ GATE(UFS0_MPHY_REFCLK_IXTAL26, "fsys0_ufs_top0_ipclkport_i_mphy_refclk_ixtal26",
+ "i_mphy_refclk_ixtal26", GAT_FSYS0_UFS_TOP0_IPCLKPORT_I_MPHY_REFCLK_IXTAL26, 21,
+ CLK_IGNORE_UNUSED, 0),
+ GATE(UFS1_MPHY_REFCLK_IXTAL24, "fsys0_ufs_top1_ipclkport_i_mphy_refclk_ixtal24",
+ "i_mphy_refclk_ixtal26", GAT_FSYS0_UFS_TOP1_IPCLKPORT_I_MPHY_REFCLK_IXTAL24, 21,
+ CLK_IGNORE_UNUSED, 0),
+ GATE(UFS1_MPHY_REFCLK_IXTAL26, "fsys0_ufs_top1_ipclkport_i_mphy_refclk_ixtal26",
+ "i_mphy_refclk_ixtal26", GAT_FSYS0_UFS_TOP1_IPCLKPORT_I_MPHY_REFCLK_IXTAL26, 21,
+ CLK_IGNORE_UNUSED, 0),
+ GATE(0, "fsys0_ahbbr_fsys0_ipclkport_hclk", "dout_fsys0_peribus_grp",
+ GAT_FSYS0_AHBBR_FSYS0_IPCLKPORT_HCLK, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(0, "fsys0_axi2apb_fsys0_ipclkport_aclk", "dout_fsys0_peribus_grp",
+ GAT_FSYS0_AXI2APB_FSYS0_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(0, "fsys0_bus_d_fsys0_ipclkport_mainclk", "mout_fsys0_clk_fsys0_slavebusclk",
+ GAT_FSYS0_BUS_D_FSYS0_IPCLKPORT_MAINCLK, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(0, "fsys0_bus_d_fsys0_ipclkport_periclk", "dout_fsys0_peribus_grp",
+ GAT_FSYS0_BUS_D_FSYS0_IPCLKPORT_PERICLK, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(0, "fsys0_bus_p_fsys0_ipclkport_mainclk", "dout_fsys0_peribus_grp",
+ GAT_FSYS0_BUS_P_FSYS0_IPCLKPORT_MAINCLK, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(0, "fsys0_bus_p_fsys0_ipclkport_tcuclk", "mout_fsys0_eqos_rgmii_125_mux1",
+ GAT_FSYS0_BUS_P_FSYS0_IPCLKPORT_TCUCLK, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(0, "fsys0_cpe425_ipclkport_aclk", "mout_fsys0_clk_fsys0_slavebusclk",
+ GAT_FSYS0_CPE425_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(FSYS0_EQOS_TOP0_IPCLKPORT_ACLK_I, "fsys0_eqos_top0_ipclkport_aclk_i",
+ "dout_fsys0_peribus_grp", GAT_FSYS0_EQOS_TOP0_IPCLKPORT_ACLK_I, 21,
+ CLK_IGNORE_UNUSED, 0),
+ GATE(FSYS0_EQOS_TOP0_IPCLKPORT_HCLK_I, "fsys0_eqos_top0_ipclkport_hclk_i",
+ "dout_fsys0_peribus_grp", GAT_FSYS0_EQOS_TOP0_IPCLKPORT_HCLK_I, 21,
+ CLK_IGNORE_UNUSED, 0),
+ GATE(FSYS0_EQOS_TOP0_IPCLKPORT_RGMII_CLK_I, "fsys0_eqos_top0_ipclkport_rgmii_clk_i",
+ "dout_fsys0_eqs_rgmii_clk_125", GAT_FSYS0_EQOS_TOP0_IPCLKPORT_RGMII_CLK_I, 21,
+ CLK_IGNORE_UNUSED, 0),
+ GATE(0, "fsys0_eqos_top0_ipclkport_rii_clk_i", "dout_fsys0_eqos_rii_clk2o5",
+ GAT_FSYS0_EQOS_TOP0_IPCLKPORT_RII_CLK_I, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(0, "fsys0_eqos_top0_ipclkport_rmii_clk_i", "dout_fsys0_eqos_rmiiclk_25",
+ GAT_FSYS0_EQOS_TOP0_IPCLKPORT_RMII_CLK_I, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(0, "fsys0_gpio_fsys0_ipclkport_pclk", "dout_fsys0_peribus_grp",
+ GAT_FSYS0_GPIO_FSYS0_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(0, "fsys0_gpio_fsys0_ipclkport_oscclk", "fin_pll",
+ GAT_FSYS0_GPIO_FSYS0_IPCLKPORT_OSCCLK, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(0, "fsys0_ns_brdg_fsys0_ipclkport_clk__psoc_fsys0__clk_fsys0_d",
+ "mout_fsys0_clk_fsys0_slavebusclk",
+ GAT_FSYS0_NS_BRDG_FSYS0_IPCLKPORT_CLK__PSOC_FSYS0__CLK_FSYS0_D, 21,
+ CLK_IGNORE_UNUSED, 0),
+ GATE(0, "fsys0_ns_brdg_fsys0_ipclkport_clk__psoc_fsys0__clk_fsys0_d1",
+ "mout_fsys0_eqos_rgmii_125_mux1",
+ GAT_FSYS0_NS_BRDG_FSYS0_IPCLKPORT_CLK__PSOC_FSYS0__CLK_FSYS0_D1, 21,
+ CLK_IGNORE_UNUSED, 0),
+ GATE(0, "fsys0_ns_brdg_fsys0_ipclkport_clk__psoc_fsys0__clk_fsys0_p",
+ "dout_fsys0_peribus_grp",
+ GAT_FSYS0_NS_BRDG_FSYS0_IPCLKPORT_CLK__PSOC_FSYS0__CLK_FSYS0_P, 21,
+ CLK_IGNORE_UNUSED, 0),
+ GATE(0, "fsys0_ns_brdg_fsys0_ipclkport_clk__psoc_fsys0__clk_fsys0_s",
+ "mout_fsys0_clk_fsys0_slavebusclk",
+ GAT_FSYS0_NS_BRDG_FSYS0_IPCLKPORT_CLK__PSOC_FSYS0__CLK_FSYS0_S, 21,
+ CLK_IGNORE_UNUSED, 0),
+ GATE(0, "fsys0_pcie_top_ipclkport_pcieg3_phy_x4_inst_0_i_apb_pclk",
+ "dout_fsys0_peribus_grp",
+ GAT_FSYS0_PCIE_TOP_IPCLKPORT_PCIEG3_PHY_X4_INST_0_I_APB_PCLK, 21,
+ CLK_IGNORE_UNUSED, 0),
+ GATE(0,
+ "fsys0_pcie_top_ipclkport_pcieg3_phy_x4_inst_0_pll_refclk_from_syspll",
+ "dout_fsys0_pcie_phy_oscclk",
+ GAT_FSYS0_PCIE_TOP_IPCLKPORT_PCIEG3_PHY_X4_INST_0_PLL_REFCLK_FROM_SYSPLL,
+ 21, CLK_IGNORE_UNUSED, 0),
+ GATE(0, "fsys0_pcie_top_ipclkport_pipe_pal_inst_0_i_apb_pclk_0", "dout_fsys0_peribus_grp",
+ GAT_FSYS0_PCIE_TOP_IPCLKPORT_PIPE_PAL_INST_0_I_APB_PCLK_0, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(0, "fsys0_pcie_top_ipclkport_pipe_pal_inst_0_i_immortal_clk", "fin_pll",
+ GAT_FSYS0_PCIE_TOP_IPCLKPORT_PIPE_PAL_INST_0_I_IMMORTAL_CLK, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(PCIE_SUBCTRL_INST0_DBI_ACLK_SOC,
+ "fsys0_pcie_top_ipclkport_fsd_pcie_sub_ctrl_inst_0_dbi_aclk_soc",
+ "dout_fsys0_peribus_grp",
+ GAT_FSYS0_PCIE_TOP_IPCLKPORT_FSD_PCIE_SUB_CTRL_INST_0_DBI_ACLK_SOC, 21,
+ CLK_IGNORE_UNUSED, 0),
+ GATE(0, "fsys0_pcie_top_ipclkport_fsd_pcie_sub_ctrl_inst_0_i_driver_apb_clk",
+ "dout_fsys0_peribus_grp",
+ GAT_FSYS0_PCIE_TOP_IPCLKPORT_FSD_PCIE_SUB_CTRL_INST_0_I_DRIVER_APB_CLK, 21,
+ CLK_IGNORE_UNUSED, 0),
+ GATE(PCIE_SUBCTRL_INST0_MSTR_ACLK_SOC,
+ "fsys0_pcie_top_ipclkport_fsd_pcie_sub_ctrl_inst_0_mstr_aclk_soc",
+ "mout_fsys0_clk_fsys0_slavebusclk",
+ GAT_FSYS0_PCIE_TOP_IPCLKPORT_FSD_PCIE_SUB_CTRL_INST_0_MSTR_ACLK_SOC, 21,
+ CLK_IGNORE_UNUSED, 0),
+ GATE(PCIE_SUBCTRL_INST0_SLV_ACLK_SOC,
+ "fsys0_pcie_top_ipclkport_fsd_pcie_sub_ctrl_inst_0_slv_aclk_soc",
+ "mout_fsys0_clk_fsys0_slavebusclk",
+ GAT_FSYS0_PCIE_TOP_IPCLKPORT_FSD_PCIE_SUB_CTRL_INST_0_SLV_ACLK_SOC, 21,
+ CLK_IGNORE_UNUSED, 0),
+ GATE(0, "fsys0_smmu_fsys0_ipclkport_cclk", "mout_fsys0_eqos_rgmii_125_mux1",
+ GAT_FSYS0_SMMU_FSYS0_IPCLKPORT_CCLK, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(0, "fsys0_smmu_fsys0_ipclkport_fsys0_bclk", "mout_fsys0_clk_fsys0_slavebusclk",
+ GAT_FSYS0_SMMU_FSYS0_IPCLKPORT_FSYS0_BCLK, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(0, "fsys0_sysreg_fsys0_ipclkport_pclk", "dout_fsys0_peribus_grp",
+ GAT_FSYS0_SYSREG_FSYS0_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(UFS0_TOP0_HCLK_BUS, "fsys0_ufs_top0_ipclkport_hclk_bus", "dout_fsys0_peribus_grp",
+ GAT_FSYS0_UFS_TOP0_IPCLKPORT_HCLK_BUS, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(UFS0_TOP0_ACLK, "fsys0_ufs_top0_ipclkport_i_aclk", "dout_fsys0_peribus_grp",
+ GAT_FSYS0_UFS_TOP0_IPCLKPORT_I_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(UFS0_TOP0_CLK_UNIPRO, "fsys0_ufs_top0_ipclkport_i_clk_unipro", "dout_fsys0_clk_unipro",
+ GAT_FSYS0_UFS_TOP0_IPCLKPORT_I_CLK_UNIPRO, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(UFS0_TOP0_FMP_CLK, "fsys0_ufs_top0_ipclkport_i_fmp_clk", "dout_fsys0_peribus_grp",
+ GAT_FSYS0_UFS_TOP0_IPCLKPORT_I_FMP_CLK, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(UFS1_TOP1_HCLK_BUS, "fsys0_ufs_top1_ipclkport_hclk_bus", "dout_fsys0_peribus_grp",
+ GAT_FSYS0_UFS_TOP1_IPCLKPORT_HCLK_BUS, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(UFS1_TOP1_ACLK, "fsys0_ufs_top1_ipclkport_i_aclk", "dout_fsys0_peribus_grp",
+ GAT_FSYS0_UFS_TOP1_IPCLKPORT_I_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(UFS1_TOP1_CLK_UNIPRO, "fsys0_ufs_top1_ipclkport_i_clk_unipro", "dout_fsys0_clk_unipro",
+ GAT_FSYS0_UFS_TOP1_IPCLKPORT_I_CLK_UNIPRO, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(UFS1_TOP1_FMP_CLK, "fsys0_ufs_top1_ipclkport_i_fmp_clk", "dout_fsys0_peribus_grp",
+ GAT_FSYS0_UFS_TOP1_IPCLKPORT_I_FMP_CLK, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(0, "fsys0_rii_clk_divgate", "dout_fsys0_eqos_rmiiclk_25", GAT_FSYS0_RII_CLK_DIVGATE,
+ 21, CLK_IGNORE_UNUSED, 0),
+ GATE(FSYS0_EQOS_TOP0_IPCLKPORT_CLK_PTP_REF_I, "fsys0_eqos_top0_ipclkport_clk_ptp_ref_i",
+ "fin_pll", GAT_FSYS0_EQOS_TOP0_IPCLKPORT_CLK_PTP_REF_I, 21, CLK_IGNORE_UNUSED, 0),
+};
+
+static const struct samsung_cmu_info fsys0_cmu_info __initconst = {
+ .mux_clks = fsys0_mux_clks,
+ .nr_mux_clks = ARRAY_SIZE(fsys0_mux_clks),
+ .div_clks = fsys0_div_clks,
+ .nr_div_clks = ARRAY_SIZE(fsys0_div_clks),
+ .gate_clks = fsys0_gate_clks,
+ .nr_gate_clks = ARRAY_SIZE(fsys0_gate_clks),
+ .fixed_clks = fsys0_fixed_clks,
+ .nr_fixed_clks = ARRAY_SIZE(fsys0_fixed_clks),
+ .nr_clk_ids = FSYS0_NR_CLK,
+ .clk_regs = fsys0_clk_regs,
+ .nr_clk_regs = ARRAY_SIZE(fsys0_clk_regs),
+ .clk_name = "dout_cmu_fsys0_shared1div4",
+};
+
+/* Register Offset definitions for CMU_FSYS1 (0x16810000) */
+#define PLL_CON0_ACLK_FSYS1_BUSP_MUX 0x100
+#define PLL_CON0_PCLKL_FSYS1_BUSP_MUX 0x180
+#define DIV_CLK_FSYS1_PHY0_OSCCLK 0x1800
+#define DIV_CLK_FSYS1_PHY1_OSCCLK 0x1804
+#define GAT_FSYS1_CMU_FSYS1_IPCLKPORT_PCLK 0x2000
+#define GAT_FSYS1_PCIE_LINK0_IPCLKPORT_AUXCLK 0x2004
+#define GAT_FSYS1_PCIE_LINK0_IPCLKPORT_I_SOC_REF_CLK 0x2008
+#define GAT_FSYS1_PCIE_LINK1_IPCLKPORT_AUXCLK 0x200c
+#define GAT_FSYS1_PCIE_PHY0_IPCLKPORT_I_REF_XTAL 0x202c
+#define GAT_FSYS1_PHY0_OSCCLLK 0x2034
+#define GAT_FSYS1_PHY1_OSCCLK 0x2038
+#define GAT_FSYS1_AXI2APB_FSYS1_IPCLKPORT_ACLK 0x203c
+#define GAT_FSYS1_BUS_D0_FSYS1_IPCLKPORT_MAINCLK 0x2040
+#define GAT_FSYS1_BUS_S0_FSYS1_IPCLKPORT_M250CLK 0x2048
+#define GAT_FSYS1_BUS_S0_FSYS1_IPCLKPORT_MAINCLK 0x204c
+#define GAT_FSYS1_CPE425_0_FSYS1_IPCLKPORT_ACLK 0x2054
+#define GAT_FSYS1_NS_BRDG_FSYS1_IPCLKPORT_CLK__PSOC_FSYS1__CLK_FSYS1_D0 0x205c
+#define GAT_FSYS1_NS_BRDG_FSYS1_IPCLKPORT_CLK__PSOC_FSYS1__CLK_FSYS1_S0 0x2064
+#define GAT_FSYS1_PCIE_LINK0_IPCLKPORT_DBI_ACLK 0x206c
+#define GAT_FSYS1_PCIE_LINK0_IPCLKPORT_I_APB_CLK 0x2070
+#define GAT_FSYS1_PCIE_LINK0_IPCLKPORT_I_DRIVER_APB_CLK 0x2074
+#define GAT_FSYS1_PCIE_LINK0_IPCLKPORT_MSTR_ACLK 0x2078
+#define GAT_FSYS1_PCIE_LINK0_IPCLKPORT_SLV_ACLK 0x207c
+#define GAT_FSYS1_PCIE_LINK1_IPCLKPORT_DBI_ACLK 0x2080
+#define GAT_FSYS1_PCIE_LINK1_IPCLKPORT_I_DRIVER_APB_CLK 0x2084
+#define GAT_FSYS1_PCIE_LINK1_IPCLKPORT_MSTR_ACLK 0x2088
+#define GAT_FSYS1_PCIE_LINK1_IPCLKPORT_SLV_ACLK 0x208c
+#define GAT_FSYS1_PCIE_PHY0_IPCLKPORT_I_APB_CLK 0x20a4
+#define GAT_FSYS1_PCIE_PHY0_IPCLKPORT_I_REF_SOC_PLL 0x20a8
+#define GAT_FSYS1_SYSREG_FSYS1_IPCLKPORT_PCLK 0x20b4
+#define GAT_FSYS1_TBU0_FSYS1_IPCLKPORT_ACLK 0x20b8
+
+static const unsigned long fsys1_clk_regs[] __initconst = {
+ PLL_CON0_ACLK_FSYS1_BUSP_MUX,
+ PLL_CON0_PCLKL_FSYS1_BUSP_MUX,
+ DIV_CLK_FSYS1_PHY0_OSCCLK,
+ DIV_CLK_FSYS1_PHY1_OSCCLK,
+ GAT_FSYS1_CMU_FSYS1_IPCLKPORT_PCLK,
+ GAT_FSYS1_PCIE_LINK0_IPCLKPORT_AUXCLK,
+ GAT_FSYS1_PCIE_LINK0_IPCLKPORT_I_SOC_REF_CLK,
+ GAT_FSYS1_PCIE_LINK1_IPCLKPORT_AUXCLK,
+ GAT_FSYS1_PCIE_PHY0_IPCLKPORT_I_REF_XTAL,
+ GAT_FSYS1_PHY0_OSCCLLK,
+ GAT_FSYS1_PHY1_OSCCLK,
+ GAT_FSYS1_AXI2APB_FSYS1_IPCLKPORT_ACLK,
+ GAT_FSYS1_BUS_D0_FSYS1_IPCLKPORT_MAINCLK,
+ GAT_FSYS1_BUS_S0_FSYS1_IPCLKPORT_M250CLK,
+ GAT_FSYS1_BUS_S0_FSYS1_IPCLKPORT_MAINCLK,
+ GAT_FSYS1_CPE425_0_FSYS1_IPCLKPORT_ACLK,
+ GAT_FSYS1_NS_BRDG_FSYS1_IPCLKPORT_CLK__PSOC_FSYS1__CLK_FSYS1_D0,
+ GAT_FSYS1_NS_BRDG_FSYS1_IPCLKPORT_CLK__PSOC_FSYS1__CLK_FSYS1_S0,
+ GAT_FSYS1_PCIE_LINK0_IPCLKPORT_DBI_ACLK,
+ GAT_FSYS1_PCIE_LINK0_IPCLKPORT_I_APB_CLK,
+ GAT_FSYS1_PCIE_LINK0_IPCLKPORT_I_DRIVER_APB_CLK,
+ GAT_FSYS1_PCIE_LINK0_IPCLKPORT_MSTR_ACLK,
+ GAT_FSYS1_PCIE_LINK0_IPCLKPORT_SLV_ACLK,
+ GAT_FSYS1_PCIE_LINK1_IPCLKPORT_DBI_ACLK,
+ GAT_FSYS1_PCIE_LINK1_IPCLKPORT_I_DRIVER_APB_CLK,
+ GAT_FSYS1_PCIE_LINK1_IPCLKPORT_MSTR_ACLK,
+ GAT_FSYS1_PCIE_LINK1_IPCLKPORT_SLV_ACLK,
+ GAT_FSYS1_PCIE_PHY0_IPCLKPORT_I_APB_CLK,
+ GAT_FSYS1_PCIE_PHY0_IPCLKPORT_I_REF_SOC_PLL,
+ GAT_FSYS1_SYSREG_FSYS1_IPCLKPORT_PCLK,
+ GAT_FSYS1_TBU0_FSYS1_IPCLKPORT_ACLK,
+};
+
+static const struct samsung_fixed_rate_clock fsys1_fixed_clks[] __initconst = {
+ FRATE(0, "clk_fsys1_phy0_ref", NULL, 0, 100000000),
+ FRATE(0, "clk_fsys1_phy1_ref", NULL, 0, 100000000),
+};
+
+/* List of parent clocks for Muxes in CMU_FSYS1 */
+PNAME(mout_fsys1_pclkl_fsys1_busp_mux_p) = { "fin_pll", "dout_cmu_fsys1_shared0div8" };
+PNAME(mout_fsys1_aclk_fsys1_busp_mux_p) = { "fin_pll", "dout_cmu_fsys1_shared0div4" };
+
+static const struct samsung_mux_clock fsys1_mux_clks[] __initconst = {
+ MUX(0, "mout_fsys1_pclkl_fsys1_busp_mux", mout_fsys1_pclkl_fsys1_busp_mux_p,
+ PLL_CON0_PCLKL_FSYS1_BUSP_MUX, 4, 1),
+ MUX(0, "mout_fsys1_aclk_fsys1_busp_mux", mout_fsys1_aclk_fsys1_busp_mux_p,
+ PLL_CON0_ACLK_FSYS1_BUSP_MUX, 4, 1),
+};
+
+static const struct samsung_div_clock fsys1_div_clks[] __initconst = {
+ DIV(0, "dout_fsys1_clk_fsys1_phy0_oscclk", "fsys1_phy0_osccllk",
+ DIV_CLK_FSYS1_PHY0_OSCCLK, 0, 4),
+ DIV(0, "dout_fsys1_clk_fsys1_phy1_oscclk", "fsys1_phy1_oscclk",
+ DIV_CLK_FSYS1_PHY1_OSCCLK, 0, 4),
+};
+
+static const struct samsung_gate_clock fsys1_gate_clks[] __initconst = {
+ GATE(0, "fsys1_cmu_fsys1_ipclkport_pclk", "mout_fsys1_pclkl_fsys1_busp_mux",
+ GAT_FSYS1_CMU_FSYS1_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(0, "fsys1_pcie_phy0_ipclkport_i_ref_xtal", "clk_fsys1_phy0_ref",
+ GAT_FSYS1_PCIE_PHY0_IPCLKPORT_I_REF_XTAL, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(0, "fsys1_phy0_osccllk", "mout_fsys1_aclk_fsys1_busp_mux",
+ GAT_FSYS1_PHY0_OSCCLLK, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(0, "fsys1_phy1_oscclk", "mout_fsys1_aclk_fsys1_busp_mux",
+ GAT_FSYS1_PHY1_OSCCLK, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(0, "fsys1_axi2apb_fsys1_ipclkport_aclk", "mout_fsys1_pclkl_fsys1_busp_mux",
+ GAT_FSYS1_AXI2APB_FSYS1_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(0, "fsys1_bus_d0_fsys1_ipclkport_mainclk", "mout_fsys1_aclk_fsys1_busp_mux",
+ GAT_FSYS1_BUS_D0_FSYS1_IPCLKPORT_MAINCLK, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(0, "fsys1_bus_s0_fsys1_ipclkport_m250clk", "mout_fsys1_pclkl_fsys1_busp_mux",
+ GAT_FSYS1_BUS_S0_FSYS1_IPCLKPORT_M250CLK, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(0, "fsys1_bus_s0_fsys1_ipclkport_mainclk", "mout_fsys1_aclk_fsys1_busp_mux",
+ GAT_FSYS1_BUS_S0_FSYS1_IPCLKPORT_MAINCLK, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(0, "fsys1_cpe425_0_fsys1_ipclkport_aclk", "mout_fsys1_aclk_fsys1_busp_mux",
+ GAT_FSYS1_CPE425_0_FSYS1_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(0, "fsys1_ns_brdg_fsys1_ipclkport_clk__psoc_fsys1__clk_fsys1_d0",
+ "mout_fsys1_aclk_fsys1_busp_mux",
+ GAT_FSYS1_NS_BRDG_FSYS1_IPCLKPORT_CLK__PSOC_FSYS1__CLK_FSYS1_D0, 21,
+ CLK_IGNORE_UNUSED, 0),
+ GATE(0, "fsys1_ns_brdg_fsys1_ipclkport_clk__psoc_fsys1__clk_fsys1_s0",
+ "mout_fsys1_aclk_fsys1_busp_mux",
+ GAT_FSYS1_NS_BRDG_FSYS1_IPCLKPORT_CLK__PSOC_FSYS1__CLK_FSYS1_S0, 21,
+ CLK_IGNORE_UNUSED, 0),
+ GATE(PCIE_LINK0_IPCLKPORT_DBI_ACLK, "fsys1_pcie_link0_ipclkport_dbi_aclk",
+ "mout_fsys1_aclk_fsys1_busp_mux", GAT_FSYS1_PCIE_LINK0_IPCLKPORT_DBI_ACLK, 21,
+ CLK_IGNORE_UNUSED, 0),
+ GATE(0, "fsys1_pcie_link0_ipclkport_i_apb_clk", "mout_fsys1_pclkl_fsys1_busp_mux",
+ GAT_FSYS1_PCIE_LINK0_IPCLKPORT_I_APB_CLK, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(0, "fsys1_pcie_link0_ipclkport_i_soc_ref_clk", "fin_pll",
+ GAT_FSYS1_PCIE_LINK0_IPCLKPORT_I_SOC_REF_CLK, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(0, "fsys1_pcie_link0_ipclkport_i_driver_apb_clk", "mout_fsys1_pclkl_fsys1_busp_mux",
+ GAT_FSYS1_PCIE_LINK0_IPCLKPORT_I_DRIVER_APB_CLK, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(PCIE_LINK0_IPCLKPORT_MSTR_ACLK, "fsys1_pcie_link0_ipclkport_mstr_aclk",
+ "mout_fsys1_aclk_fsys1_busp_mux", GAT_FSYS1_PCIE_LINK0_IPCLKPORT_MSTR_ACLK, 21,
+ CLK_IGNORE_UNUSED, 0),
+ GATE(PCIE_LINK0_IPCLKPORT_SLV_ACLK, "fsys1_pcie_link0_ipclkport_slv_aclk",
+ "mout_fsys1_aclk_fsys1_busp_mux", GAT_FSYS1_PCIE_LINK0_IPCLKPORT_SLV_ACLK, 21,
+ CLK_IGNORE_UNUSED, 0),
+ GATE(PCIE_LINK1_IPCLKPORT_DBI_ACLK, "fsys1_pcie_link1_ipclkport_dbi_aclk",
+ "mout_fsys1_aclk_fsys1_busp_mux", GAT_FSYS1_PCIE_LINK1_IPCLKPORT_DBI_ACLK, 21,
+ CLK_IGNORE_UNUSED, 0),
+ GATE(0, "fsys1_pcie_link1_ipclkport_i_driver_apb_clk", "mout_fsys1_pclkl_fsys1_busp_mux",
+ GAT_FSYS1_PCIE_LINK1_IPCLKPORT_I_DRIVER_APB_CLK, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(PCIE_LINK1_IPCLKPORT_MSTR_ACLK, "fsys1_pcie_link1_ipclkport_mstr_aclk",
+ "mout_fsys1_aclk_fsys1_busp_mux", GAT_FSYS1_PCIE_LINK1_IPCLKPORT_MSTR_ACLK, 21,
+ CLK_IGNORE_UNUSED, 0),
+ GATE(PCIE_LINK1_IPCLKPORT_SLV_ACLK, "fsys1_pcie_link1_ipclkport_slv_aclk",
+ "mout_fsys1_aclk_fsys1_busp_mux", GAT_FSYS1_PCIE_LINK1_IPCLKPORT_SLV_ACLK, 21,
+ CLK_IGNORE_UNUSED, 0),
+ GATE(0, "fsys1_pcie_phy0_ipclkport_i_apb_clk", "mout_fsys1_pclkl_fsys1_busp_mux",
+ GAT_FSYS1_PCIE_PHY0_IPCLKPORT_I_APB_CLK, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(PCIE_LINK0_IPCLKPORT_AUX_ACLK, "fsys1_pcie_link0_ipclkport_auxclk", "fin_pll",
+ GAT_FSYS1_PCIE_LINK0_IPCLKPORT_AUXCLK, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(PCIE_LINK1_IPCLKPORT_AUX_ACLK, "fsys1_pcie_link1_ipclkport_auxclk", "fin_pll",
+ GAT_FSYS1_PCIE_LINK1_IPCLKPORT_AUXCLK, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(0, "fsys1_pcie_phy0_ipclkport_i_ref_soc_pll", "dout_fsys1_clk_fsys1_phy0_oscclk",
+ GAT_FSYS1_PCIE_PHY0_IPCLKPORT_I_REF_SOC_PLL, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(0, "fsys1_sysreg_fsys1_ipclkport_pclk", "mout_fsys1_pclkl_fsys1_busp_mux",
+ GAT_FSYS1_SYSREG_FSYS1_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(0, "fsys1_tbu0_fsys1_ipclkport_aclk", "mout_fsys1_aclk_fsys1_busp_mux",
+ GAT_FSYS1_TBU0_FSYS1_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+};
+
+static const struct samsung_cmu_info fsys1_cmu_info __initconst = {
+ .mux_clks = fsys1_mux_clks,
+ .nr_mux_clks = ARRAY_SIZE(fsys1_mux_clks),
+ .div_clks = fsys1_div_clks,
+ .nr_div_clks = ARRAY_SIZE(fsys1_div_clks),
+ .gate_clks = fsys1_gate_clks,
+ .nr_gate_clks = ARRAY_SIZE(fsys1_gate_clks),
+ .fixed_clks = fsys1_fixed_clks,
+ .nr_fixed_clks = ARRAY_SIZE(fsys1_fixed_clks),
+ .nr_clk_ids = FSYS1_NR_CLK,
+ .clk_regs = fsys1_clk_regs,
+ .nr_clk_regs = ARRAY_SIZE(fsys1_clk_regs),
+ .clk_name = "dout_cmu_fsys1_shared0div4",
+};
+
+/* Register Offset definitions for CMU_IMEM (0x10010000) */
+#define PLL_CON0_CLK_IMEM_ACLK 0x100
+#define PLL_CON0_CLK_IMEM_INTMEMCLK 0x120
+#define PLL_CON0_CLK_IMEM_TCUCLK 0x140
+#define DIV_OSCCLK_IMEM_TMUTSCLK 0x1800
+#define GAT_IMEM_IMEM_CMU_IMEM_IPCLKPORT_PCLK 0x2000
+#define GAT_IMEM_MCT_IPCLKPORT_OSCCLK__ALO 0x2004
+#define GAT_IMEM_OTP_CON_TOP_IPCLKPORT_I_OSCCLK 0x2008
+#define GAT_IMEM_RSTNSYNC_OSCCLK_IPCLKPORT_CLK 0x200c
+#define GAT_IMEM_TMU_CPU0_IPCLKPORT_I_CLK 0x2010
+#define GAT_IMEM_TMU_CPU0_IPCLKPORT_I_CLK_TS 0x2014
+#define GAT_IMEM_TMU_CPU2_IPCLKPORT_I_CLK 0x2018
+#define GAT_IMEM_TMU_CPU2_IPCLKPORT_I_CLK_TS 0x201c
+#define GAT_IMEM_TMU_GPU_IPCLKPORT_I_CLK 0x2020
+#define GAT_IMEM_TMU_GPU_IPCLKPORT_I_CLK_TS 0x2024
+#define GAT_IMEM_TMU_GT_IPCLKPORT_I_CLK 0x2028
+#define GAT_IMEM_TMU_GT_IPCLKPORT_I_CLK_TS 0x202c
+#define GAT_IMEM_TMU_TOP_IPCLKPORT_I_CLK 0x2030
+#define GAT_IMEM_TMU_TOP_IPCLKPORT_I_CLK_TS 0x2034
+#define GAT_IMEM_WDT0_IPCLKPORT_CLK 0x2038
+#define GAT_IMEM_WDT1_IPCLKPORT_CLK 0x203c
+#define GAT_IMEM_WDT2_IPCLKPORT_CLK 0x2040
+#define GAT_IMEM_ADM_AXI4ST_I0_IMEM_IPCLKPORT_ACLKM 0x2044
+#define GAT_IMEM_ADM_AXI4ST_I1_IMEM_IPCLKPORT_ACLKM 0x2048
+#define GAT_IMEM_ADM_AXI4ST_I2_IMEM_IPCLKPORT_ACLKM 0x204c
+#define GAT_IMEM_ADS_AXI4ST_I0_IMEM_IPCLKPORT_ACLKS 0x2050
+#define GAT_IMEM_ADS_AXI4ST_I1_IMEM_IPCLKPORT_ACLKS 0x2054
+#define GAT_IMEM_ADS_AXI4ST_I2_IMEM_IPCLKPORT_ACLKS 0x2058
+#define GAT_IMEM_ASYNC_DMA0_IPCLKPORT_PCLKM 0x205c
+#define GAT_IMEM_ASYNC_DMA0_IPCLKPORT_PCLKS 0x2060
+#define GAT_IMEM_ASYNC_DMA1_IPCLKPORT_PCLKM 0x2064
+#define GAT_IMEM_ASYNC_DMA1_IPCLKPORT_PCLKS 0x2068
+#define GAT_IMEM_AXI2APB_IMEMP0_IPCLKPORT_ACLK 0x206c
+#define GAT_IMEM_AXI2APB_IMEMP1_IPCLKPORT_ACLK 0x2070
+#define GAT_IMEM_BUS_D_IMEM_IPCLKPORT_MAINCLK 0x2074
+#define GAT_IMEM_BUS_P_IMEM_IPCLKPORT_MAINCLK 0x2078
+#define GAT_IMEM_BUS_P_IMEM_IPCLKPORT_PERICLK 0x207c
+#define GAT_IMEM_BUS_P_IMEM_IPCLKPORT_TCUCLK 0x2080
+#define GAT_IMEM_DMA0_IPCLKPORT_ACLK 0x2084
+#define GAT_IMEM_DMA1_IPCLKPORT_ACLK 0x2088
+#define GAT_IMEM_GIC500_INPUT_SYNC_IPCLKPORT_CLK 0x208c
+#define GAT_IMEM_GIC_IPCLKPORT_CLK 0x2090
+#define GAT_IMEM_INTMEM_IPCLKPORT_ACLK 0x2094
+#define GAT_IMEM_MAILBOX_SCS_CA72_IPCLKPORT_PCLK 0x2098
+#define GAT_IMEM_MAILBOX_SMS_CA72_IPCLKPORT_PCLK 0x209c
+#define GAT_IMEM_MCT_IPCLKPORT_PCLK 0x20a0
+#define GAT_IMEM_NS_BRDG_IMEM_IPCLKPORT_CLK__PSCO_IMEM__CLK_IMEM_D 0x20a4
+#define GAT_IMEM_NS_BRDG_IMEM_IPCLKPORT_CLK__PSCO_IMEM__CLK_IMEM_TCU 0x20a8
+#define GAT_IMEM_NS_BRDG_IMEM_IPCLKPORT_CLK__PSOC_IMEM__CLK_IMEM_P 0x20ac
+#define GAT_IMEM_OTP_CON_TOP_IPCLKPORT_PCLK 0x20b0
+#define GAT_IMEM_RSTNSYNC_ACLK_IPCLKPORT_CLK 0x20b4
+#define GAT_IMEM_RSTNSYNC_INTMEMCLK_IPCLKPORT_CLK 0x20b8
+#define GAT_IMEM_RSTNSYNC_TCUCLK_IPCLKPORT_CLK 0x20bc
+#define GAT_IMEM_SFRIF_TMU0_IMEM_IPCLKPORT_PCLK 0x20c0
+#define GAT_IMEM_SFRIF_TMU1_IMEM_IPCLKPORT_PCLK 0x20c4
+#define GAT_IMEM_SYSREG_IMEM_IPCLKPORT_PCLK 0x20c8
+#define GAT_IMEM_TBU_IMEM_IPCLKPORT_ACLK 0x20cc
+#define GAT_IMEM_TCU_IPCLKPORT_ACLK 0x20d0
+#define GAT_IMEM_WDT0_IPCLKPORT_PCLK 0x20d4
+#define GAT_IMEM_WDT1_IPCLKPORT_PCLK 0x20d8
+#define GAT_IMEM_WDT2_IPCLKPORT_PCLK 0x20dc
+
+static const unsigned long imem_clk_regs[] __initconst = {
+ PLL_CON0_CLK_IMEM_ACLK,
+ PLL_CON0_CLK_IMEM_INTMEMCLK,
+ PLL_CON0_CLK_IMEM_TCUCLK,
+ DIV_OSCCLK_IMEM_TMUTSCLK,
+ GAT_IMEM_IMEM_CMU_IMEM_IPCLKPORT_PCLK,
+ GAT_IMEM_MCT_IPCLKPORT_OSCCLK__ALO,
+ GAT_IMEM_OTP_CON_TOP_IPCLKPORT_I_OSCCLK,
+ GAT_IMEM_RSTNSYNC_OSCCLK_IPCLKPORT_CLK,
+ GAT_IMEM_TMU_CPU0_IPCLKPORT_I_CLK,
+ GAT_IMEM_TMU_CPU0_IPCLKPORT_I_CLK_TS,
+ GAT_IMEM_TMU_CPU2_IPCLKPORT_I_CLK,
+ GAT_IMEM_TMU_CPU2_IPCLKPORT_I_CLK_TS,
+ GAT_IMEM_TMU_GPU_IPCLKPORT_I_CLK,
+ GAT_IMEM_TMU_GPU_IPCLKPORT_I_CLK_TS,
+ GAT_IMEM_TMU_GT_IPCLKPORT_I_CLK,
+ GAT_IMEM_TMU_GT_IPCLKPORT_I_CLK_TS,
+ GAT_IMEM_TMU_TOP_IPCLKPORT_I_CLK,
+ GAT_IMEM_TMU_TOP_IPCLKPORT_I_CLK_TS,
+ GAT_IMEM_WDT0_IPCLKPORT_CLK,
+ GAT_IMEM_WDT1_IPCLKPORT_CLK,
+ GAT_IMEM_WDT2_IPCLKPORT_CLK,
+ GAT_IMEM_ADM_AXI4ST_I0_IMEM_IPCLKPORT_ACLKM,
+ GAT_IMEM_ADM_AXI4ST_I1_IMEM_IPCLKPORT_ACLKM,
+ GAT_IMEM_ADM_AXI4ST_I2_IMEM_IPCLKPORT_ACLKM,
+ GAT_IMEM_ADS_AXI4ST_I0_IMEM_IPCLKPORT_ACLKS,
+ GAT_IMEM_ADS_AXI4ST_I1_IMEM_IPCLKPORT_ACLKS,
+ GAT_IMEM_ADS_AXI4ST_I2_IMEM_IPCLKPORT_ACLKS,
+ GAT_IMEM_ASYNC_DMA0_IPCLKPORT_PCLKM,
+ GAT_IMEM_ASYNC_DMA0_IPCLKPORT_PCLKS,
+ GAT_IMEM_ASYNC_DMA1_IPCLKPORT_PCLKM,
+ GAT_IMEM_ASYNC_DMA1_IPCLKPORT_PCLKS,
+ GAT_IMEM_AXI2APB_IMEMP0_IPCLKPORT_ACLK,
+ GAT_IMEM_AXI2APB_IMEMP1_IPCLKPORT_ACLK,
+ GAT_IMEM_BUS_D_IMEM_IPCLKPORT_MAINCLK,
+ GAT_IMEM_BUS_P_IMEM_IPCLKPORT_MAINCLK,
+ GAT_IMEM_BUS_P_IMEM_IPCLKPORT_PERICLK,
+ GAT_IMEM_BUS_P_IMEM_IPCLKPORT_TCUCLK,
+ GAT_IMEM_DMA0_IPCLKPORT_ACLK,
+ GAT_IMEM_DMA1_IPCLKPORT_ACLK,
+ GAT_IMEM_GIC500_INPUT_SYNC_IPCLKPORT_CLK,
+ GAT_IMEM_GIC_IPCLKPORT_CLK,
+ GAT_IMEM_INTMEM_IPCLKPORT_ACLK,
+ GAT_IMEM_MAILBOX_SCS_CA72_IPCLKPORT_PCLK,
+ GAT_IMEM_MAILBOX_SMS_CA72_IPCLKPORT_PCLK,
+ GAT_IMEM_MCT_IPCLKPORT_PCLK,
+ GAT_IMEM_NS_BRDG_IMEM_IPCLKPORT_CLK__PSCO_IMEM__CLK_IMEM_D,
+ GAT_IMEM_NS_BRDG_IMEM_IPCLKPORT_CLK__PSCO_IMEM__CLK_IMEM_TCU,
+ GAT_IMEM_NS_BRDG_IMEM_IPCLKPORT_CLK__PSOC_IMEM__CLK_IMEM_P,
+ GAT_IMEM_OTP_CON_TOP_IPCLKPORT_PCLK,
+ GAT_IMEM_RSTNSYNC_ACLK_IPCLKPORT_CLK,
+ GAT_IMEM_RSTNSYNC_INTMEMCLK_IPCLKPORT_CLK,
+ GAT_IMEM_RSTNSYNC_TCUCLK_IPCLKPORT_CLK,
+ GAT_IMEM_SFRIF_TMU0_IMEM_IPCLKPORT_PCLK,
+ GAT_IMEM_SFRIF_TMU1_IMEM_IPCLKPORT_PCLK,
+ GAT_IMEM_SYSREG_IMEM_IPCLKPORT_PCLK,
+ GAT_IMEM_TBU_IMEM_IPCLKPORT_ACLK,
+ GAT_IMEM_TCU_IPCLKPORT_ACLK,
+ GAT_IMEM_WDT0_IPCLKPORT_PCLK,
+ GAT_IMEM_WDT1_IPCLKPORT_PCLK,
+ GAT_IMEM_WDT2_IPCLKPORT_PCLK,
+};
+
+PNAME(mout_imem_clk_imem_tcuclk_p) = { "fin_pll", "dout_cmu_imem_tcuclk" };
+PNAME(mout_imem_clk_imem_aclk_p) = { "fin_pll", "dout_cmu_imem_aclk" };
+PNAME(mout_imem_clk_imem_intmemclk_p) = { "fin_pll", "dout_cmu_imem_dmaclk" };
+
+static const struct samsung_mux_clock imem_mux_clks[] __initconst = {
+ MUX(0, "mout_imem_clk_imem_tcuclk", mout_imem_clk_imem_tcuclk_p,
+ PLL_CON0_CLK_IMEM_TCUCLK, 4, 1),
+ MUX(0, "mout_imem_clk_imem_aclk", mout_imem_clk_imem_aclk_p, PLL_CON0_CLK_IMEM_ACLK, 4, 1),
+ MUX(0, "mout_imem_clk_imem_intmemclk", mout_imem_clk_imem_intmemclk_p,
+ PLL_CON0_CLK_IMEM_INTMEMCLK, 4, 1),
+};
+
+static const struct samsung_div_clock imem_div_clks[] __initconst = {
+ DIV(0, "dout_imem_oscclk_imem_tmutsclk", "fin_pll", DIV_OSCCLK_IMEM_TMUTSCLK, 0, 4),
+};
+
+static const struct samsung_gate_clock imem_gate_clks[] __initconst = {
+ GATE(0, "imem_imem_cmu_imem_ipclkport_pclk", "mout_imem_clk_imem_aclk",
+ GAT_IMEM_IMEM_CMU_IMEM_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(0, "imem_otp_con_top_ipclkport_i_oscclk", "fin_pll",
+ GAT_IMEM_OTP_CON_TOP_IPCLKPORT_I_OSCCLK, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(0, "imem_tmu_top_ipclkport_i_clk", "fin_pll",
+ GAT_IMEM_TMU_TOP_IPCLKPORT_I_CLK, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(0, "imem_tmu_gt_ipclkport_i_clk", "fin_pll",
+ GAT_IMEM_TMU_GT_IPCLKPORT_I_CLK, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(0, "imem_tmu_cpu0_ipclkport_i_clk", "fin_pll",
+ GAT_IMEM_TMU_CPU0_IPCLKPORT_I_CLK, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(0, "imem_tmu_gpu_ipclkport_i_clk", "fin_pll",
+ GAT_IMEM_TMU_GPU_IPCLKPORT_I_CLK, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(0, "imem_mct_ipclkport_oscclk__alo", "fin_pll",
+ GAT_IMEM_MCT_IPCLKPORT_OSCCLK__ALO, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(0, "imem_wdt0_ipclkport_clk", "fin_pll",
+ GAT_IMEM_WDT0_IPCLKPORT_CLK, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(0, "imem_wdt1_ipclkport_clk", "fin_pll",
+ GAT_IMEM_WDT1_IPCLKPORT_CLK, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(0, "imem_wdt2_ipclkport_clk", "fin_pll",
+ GAT_IMEM_WDT2_IPCLKPORT_CLK, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(IMEM_TMU_CPU0_IPCLKPORT_I_CLK_TS, "imem_tmu_cpu0_ipclkport_i_clk_ts",
+ "dout_imem_oscclk_imem_tmutsclk",
+ GAT_IMEM_TMU_CPU0_IPCLKPORT_I_CLK_TS, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(IMEM_TMU_CPU2_IPCLKPORT_I_CLK_TS, "imem_tmu_cpu2_ipclkport_i_clk_ts",
+ "dout_imem_oscclk_imem_tmutsclk",
+ GAT_IMEM_TMU_CPU2_IPCLKPORT_I_CLK_TS, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(IMEM_TMU_GPU_IPCLKPORT_I_CLK_TS, "imem_tmu_gpu_ipclkport_i_clk_ts",
+ "dout_imem_oscclk_imem_tmutsclk",
+ GAT_IMEM_TMU_GPU_IPCLKPORT_I_CLK_TS, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(IMEM_TMU_GT_IPCLKPORT_I_CLK_TS, "imem_tmu_gt_ipclkport_i_clk_ts",
+ "dout_imem_oscclk_imem_tmutsclk",
+ GAT_IMEM_TMU_GT_IPCLKPORT_I_CLK_TS, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(IMEM_TMU_TOP_IPCLKPORT_I_CLK_TS, "imem_tmu_top_ipclkport_i_clk_ts",
+ "dout_imem_oscclk_imem_tmutsclk",
+ GAT_IMEM_TMU_TOP_IPCLKPORT_I_CLK_TS, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(0, "imem_adm_axi4st_i0_imem_ipclkport_aclkm", "mout_imem_clk_imem_aclk",
+ GAT_IMEM_ADM_AXI4ST_I0_IMEM_IPCLKPORT_ACLKM, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(0, "imem_adm_axi4st_i1_imem_ipclkport_aclkm", "mout_imem_clk_imem_aclk",
+ GAT_IMEM_ADM_AXI4ST_I1_IMEM_IPCLKPORT_ACLKM, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(0, "imem_adm_axi4st_i2_imem_ipclkport_aclkm", "mout_imem_clk_imem_aclk",
+ GAT_IMEM_ADM_AXI4ST_I2_IMEM_IPCLKPORT_ACLKM, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(0, "imem_ads_axi4st_i0_imem_ipclkport_aclks", "mout_imem_clk_imem_aclk",
+ GAT_IMEM_ADS_AXI4ST_I0_IMEM_IPCLKPORT_ACLKS, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(0, "imem_ads_axi4st_i1_imem_ipclkport_aclks", "mout_imem_clk_imem_aclk",
+ GAT_IMEM_ADS_AXI4ST_I1_IMEM_IPCLKPORT_ACLKS, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(0, "imem_ads_axi4st_i2_imem_ipclkport_aclks", "mout_imem_clk_imem_aclk",
+ GAT_IMEM_ADS_AXI4ST_I2_IMEM_IPCLKPORT_ACLKS, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(0, "imem_async_dma0_ipclkport_pclkm", "mout_imem_clk_imem_tcuclk",
+ GAT_IMEM_ASYNC_DMA0_IPCLKPORT_PCLKM, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(0, "imem_async_dma0_ipclkport_pclks", "mout_imem_clk_imem_aclk",
+ GAT_IMEM_ASYNC_DMA0_IPCLKPORT_PCLKS, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(0, "imem_async_dma1_ipclkport_pclkm", "mout_imem_clk_imem_tcuclk",
+ GAT_IMEM_ASYNC_DMA1_IPCLKPORT_PCLKM, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(0, "imem_async_dma1_ipclkport_pclks", "mout_imem_clk_imem_aclk",
+ GAT_IMEM_ASYNC_DMA1_IPCLKPORT_PCLKS, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(0, "imem_axi2apb_imemp0_ipclkport_aclk", "mout_imem_clk_imem_aclk",
+ GAT_IMEM_AXI2APB_IMEMP0_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(0, "imem_axi2apb_imemp1_ipclkport_aclk", "mout_imem_clk_imem_aclk",
+ GAT_IMEM_AXI2APB_IMEMP1_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(0, "imem_bus_d_imem_ipclkport_mainclk", "mout_imem_clk_imem_tcuclk",
+ GAT_IMEM_BUS_D_IMEM_IPCLKPORT_MAINCLK, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(0, "imem_bus_p_imem_ipclkport_mainclk", "mout_imem_clk_imem_aclk",
+ GAT_IMEM_BUS_P_IMEM_IPCLKPORT_MAINCLK, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(0, "imem_bus_p_imem_ipclkport_pericclk", "mout_imem_clk_imem_aclk",
+ GAT_IMEM_BUS_P_IMEM_IPCLKPORT_PERICLK, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(0, "imem_bus_p_imem_ipclkport_tcuclk", "mout_imem_clk_imem_tcuclk",
+ GAT_IMEM_BUS_P_IMEM_IPCLKPORT_TCUCLK, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(IMEM_DMA0_IPCLKPORT_ACLK, "imem_dma0_ipclkport_aclk", "mout_imem_clk_imem_tcuclk",
+ GAT_IMEM_DMA0_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED | CLK_IS_CRITICAL, 0),
+ GATE(IMEM_DMA1_IPCLKPORT_ACLK, "imem_dma1_ipclkport_aclk", "mout_imem_clk_imem_tcuclk",
+ GAT_IMEM_DMA1_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED | CLK_IS_CRITICAL, 0),
+ GATE(0, "imem_gic500_input_sync_ipclkport_clk", "mout_imem_clk_imem_aclk",
+ GAT_IMEM_GIC500_INPUT_SYNC_IPCLKPORT_CLK, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(0, "imem_gic_ipclkport_clk", "mout_imem_clk_imem_aclk",
+ GAT_IMEM_GIC_IPCLKPORT_CLK, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(0, "imem_intmem_ipclkport_aclk", "mout_imem_clk_imem_intmemclk",
+ GAT_IMEM_INTMEM_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(0, "imem_mailbox_scs_ca72_ipclkport_pclk", "mout_imem_clk_imem_aclk",
+ GAT_IMEM_MAILBOX_SCS_CA72_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(0, "imem_mailbox_sms_ca72_ipclkport_pclk", "mout_imem_clk_imem_aclk",
+ GAT_IMEM_MAILBOX_SMS_CA72_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(IMEM_MCT_PCLK, "imem_mct_ipclkport_pclk", "mout_imem_clk_imem_aclk",
+ GAT_IMEM_MCT_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(0, "imem_ns_brdg_imem_ipclkport_clk__psco_imem__clk_imem_d",
+ "mout_imem_clk_imem_tcuclk",
+ GAT_IMEM_NS_BRDG_IMEM_IPCLKPORT_CLK__PSCO_IMEM__CLK_IMEM_D, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(0, "imem_ns_brdg_imem_ipclkport_clk__psco_imem__clk_imem_tcu",
+ "mout_imem_clk_imem_tcuclk",
+ GAT_IMEM_NS_BRDG_IMEM_IPCLKPORT_CLK__PSCO_IMEM__CLK_IMEM_TCU, 21,
+ CLK_IGNORE_UNUSED, 0),
+ GATE(0, "imem_ns_brdg_imem_ipclkport_clk__psoc_imem__clk_imem_p", "mout_imem_clk_imem_aclk",
+ GAT_IMEM_NS_BRDG_IMEM_IPCLKPORT_CLK__PSOC_IMEM__CLK_IMEM_P, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(0, "imem_otp_con_top_ipclkport_pclk", "mout_imem_clk_imem_aclk",
+ GAT_IMEM_OTP_CON_TOP_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(0, "imem_rstnsync_aclk_ipclkport_clk", "mout_imem_clk_imem_aclk",
+ GAT_IMEM_RSTNSYNC_ACLK_IPCLKPORT_CLK, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(0, "imem_rstnsync_oscclk_ipclkport_clk", "fin_pll",
+ GAT_IMEM_RSTNSYNC_OSCCLK_IPCLKPORT_CLK, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(0, "imem_rstnsync_intmemclk_ipclkport_clk", "mout_imem_clk_imem_intmemclk",
+ GAT_IMEM_RSTNSYNC_INTMEMCLK_IPCLKPORT_CLK, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(0, "imem_rstnsync_tcuclk_ipclkport_clk", "mout_imem_clk_imem_tcuclk",
+ GAT_IMEM_RSTNSYNC_TCUCLK_IPCLKPORT_CLK, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(0, "imem_sfrif_tmu0_imem_ipclkport_pclk", "mout_imem_clk_imem_aclk",
+ GAT_IMEM_SFRIF_TMU0_IMEM_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(0, "imem_sfrif_tmu1_imem_ipclkport_pclk", "mout_imem_clk_imem_aclk",
+ GAT_IMEM_SFRIF_TMU1_IMEM_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(0, "imem_tmu_cpu2_ipclkport_i_clk", "fin_pll",
+ GAT_IMEM_TMU_CPU2_IPCLKPORT_I_CLK, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(0, "imem_sysreg_imem_ipclkport_pclk", "mout_imem_clk_imem_aclk",
+ GAT_IMEM_SYSREG_IMEM_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(0, "imem_tbu_imem_ipclkport_aclk", "mout_imem_clk_imem_tcuclk",
+ GAT_IMEM_TBU_IMEM_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(0, "imem_tcu_ipclkport_aclk", "mout_imem_clk_imem_tcuclk",
+ GAT_IMEM_TCU_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(IMEM_WDT0_IPCLKPORT_PCLK, "imem_wdt0_ipclkport_pclk", "mout_imem_clk_imem_aclk",
+ GAT_IMEM_WDT0_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(IMEM_WDT1_IPCLKPORT_PCLK, "imem_wdt1_ipclkport_pclk", "mout_imem_clk_imem_aclk",
+ GAT_IMEM_WDT1_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(IMEM_WDT2_IPCLKPORT_PCLK, "imem_wdt2_ipclkport_pclk", "mout_imem_clk_imem_aclk",
+ GAT_IMEM_WDT2_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+};
+
+static const struct samsung_cmu_info imem_cmu_info __initconst = {
+ .mux_clks = imem_mux_clks,
+ .nr_mux_clks = ARRAY_SIZE(imem_mux_clks),
+ .div_clks = imem_div_clks,
+ .nr_div_clks = ARRAY_SIZE(imem_div_clks),
+ .gate_clks = imem_gate_clks,
+ .nr_gate_clks = ARRAY_SIZE(imem_gate_clks),
+ .nr_clk_ids = IMEM_NR_CLK,
+ .clk_regs = imem_clk_regs,
+ .nr_clk_regs = ARRAY_SIZE(imem_clk_regs),
+};
+
+static void __init fsd_clk_imem_init(struct device_node *np)
+{
+ samsung_cmu_register_one(np, &imem_cmu_info);
+}
+
+CLK_OF_DECLARE(fsd_clk_imem, "tesla,fsd-clock-imem", fsd_clk_imem_init);
+
+/* Register Offset definitions for CMU_MFC (0x12810000) */
+#define PLL_LOCKTIME_PLL_MFC 0x0
+#define PLL_CON0_PLL_MFC 0x100
+#define MUX_MFC_BUSD 0x1000
+#define MUX_MFC_BUSP 0x1008
+#define DIV_MFC_BUSD_DIV4 0x1800
+#define GAT_MFC_CMU_MFC_IPCLKPORT_PCLK 0x2000
+#define GAT_MFC_AS_P_MFC_IPCLKPORT_PCLKM 0x2004
+#define GAT_MFC_AS_P_MFC_IPCLKPORT_PCLKS 0x2008
+#define GAT_MFC_AXI2APB_MFC_IPCLKPORT_ACLK 0x200c
+#define GAT_MFC_MFC_IPCLKPORT_ACLK 0x2010
+#define GAT_MFC_NS_BRDG_MFC_IPCLKPORT_CLK__PMFC__CLK_MFC_D 0x2018
+#define GAT_MFC_NS_BRDG_MFC_IPCLKPORT_CLK__PMFC__CLK_MFC_P 0x201c
+#define GAT_MFC_PPMU_MFCD0_IPCLKPORT_ACLK 0x2028
+#define GAT_MFC_PPMU_MFCD0_IPCLKPORT_PCLK 0x202c
+#define GAT_MFC_PPMU_MFCD1_IPCLKPORT_ACLK 0x2030
+#define GAT_MFC_PPMU_MFCD1_IPCLKPORT_PCLK 0x2034
+#define GAT_MFC_SYSREG_MFC_IPCLKPORT_PCLK 0x2038
+#define GAT_MFC_TBU_MFCD0_IPCLKPORT_CLK 0x203c
+#define GAT_MFC_TBU_MFCD1_IPCLKPORT_CLK 0x2040
+#define GAT_MFC_BUSD_DIV4_GATE 0x2044
+#define GAT_MFC_BUSD_GATE 0x2048
+
+static const unsigned long mfc_clk_regs[] __initconst = {
+ PLL_LOCKTIME_PLL_MFC,
+ PLL_CON0_PLL_MFC,
+ MUX_MFC_BUSD,
+ MUX_MFC_BUSP,
+ DIV_MFC_BUSD_DIV4,
+ GAT_MFC_CMU_MFC_IPCLKPORT_PCLK,
+ GAT_MFC_AS_P_MFC_IPCLKPORT_PCLKM,
+ GAT_MFC_AS_P_MFC_IPCLKPORT_PCLKS,
+ GAT_MFC_AXI2APB_MFC_IPCLKPORT_ACLK,
+ GAT_MFC_MFC_IPCLKPORT_ACLK,
+ GAT_MFC_NS_BRDG_MFC_IPCLKPORT_CLK__PMFC__CLK_MFC_D,
+ GAT_MFC_NS_BRDG_MFC_IPCLKPORT_CLK__PMFC__CLK_MFC_P,
+ GAT_MFC_PPMU_MFCD0_IPCLKPORT_ACLK,
+ GAT_MFC_PPMU_MFCD0_IPCLKPORT_PCLK,
+ GAT_MFC_PPMU_MFCD1_IPCLKPORT_ACLK,
+ GAT_MFC_PPMU_MFCD1_IPCLKPORT_PCLK,
+ GAT_MFC_SYSREG_MFC_IPCLKPORT_PCLK,
+ GAT_MFC_TBU_MFCD0_IPCLKPORT_CLK,
+ GAT_MFC_TBU_MFCD1_IPCLKPORT_CLK,
+ GAT_MFC_BUSD_DIV4_GATE,
+ GAT_MFC_BUSD_GATE,
+};
+
+static const struct samsung_pll_rate_table pll_mfc_rate_table[] __initconst = {
+ PLL_35XX_RATE(24 * MHZ, 666000000U, 111, 4, 0),
+};
+
+static const struct samsung_pll_clock mfc_pll_clks[] __initconst = {
+ PLL(pll_142xx, 0, "fout_pll_mfc", "fin_pll",
+ PLL_LOCKTIME_PLL_MFC, PLL_CON0_PLL_MFC, pll_mfc_rate_table),
+};
+
+PNAME(mout_mfc_pll_p) = { "fin_pll", "fout_pll_mfc" };
+PNAME(mout_mfc_busp_p) = { "fin_pll", "dout_mfc_busd_div4" };
+PNAME(mout_mfc_busd_p) = { "fin_pll", "mfc_busd_gate" };
+
+static const struct samsung_mux_clock mfc_mux_clks[] __initconst = {
+ MUX(0, "mout_mfc_pll", mout_mfc_pll_p, PLL_CON0_PLL_MFC, 4, 1),
+ MUX(0, "mout_mfc_busp", mout_mfc_busp_p, MUX_MFC_BUSP, 0, 1),
+ MUX(0, "mout_mfc_busd", mout_mfc_busd_p, MUX_MFC_BUSD, 0, 1),
+};
+
+static const struct samsung_div_clock mfc_div_clks[] __initconst = {
+ DIV(0, "dout_mfc_busd_div4", "mfc_busd_div4_gate", DIV_MFC_BUSD_DIV4, 0, 4),
+};
+
+static const struct samsung_gate_clock mfc_gate_clks[] __initconst = {
+ GATE(0, "mfc_cmu_mfc_ipclkport_pclk", "mout_mfc_busp",
+ GAT_MFC_CMU_MFC_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(0, "mfc_as_p_mfc_ipclkport_pclkm", "mout_mfc_busd",
+ GAT_MFC_AS_P_MFC_IPCLKPORT_PCLKM, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(0, "mfc_as_p_mfc_ipclkport_pclks", "mout_mfc_busp",
+ GAT_MFC_AS_P_MFC_IPCLKPORT_PCLKS, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(0, "mfc_axi2apb_mfc_ipclkport_aclk", "mout_mfc_busp",
+ GAT_MFC_AXI2APB_MFC_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(MFC_MFC_IPCLKPORT_ACLK, "mfc_mfc_ipclkport_aclk", "mout_mfc_busd",
+ GAT_MFC_MFC_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(0, "mfc_ns_brdg_mfc_ipclkport_clk__pmfc__clk_mfc_d", "mout_mfc_busd",
+ GAT_MFC_NS_BRDG_MFC_IPCLKPORT_CLK__PMFC__CLK_MFC_D, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(0, "mfc_ns_brdg_mfc_ipclkport_clk__pmfc__clk_mfc_p", "mout_mfc_busp",
+ GAT_MFC_NS_BRDG_MFC_IPCLKPORT_CLK__PMFC__CLK_MFC_P, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(0, "mfc_ppmu_mfcd0_ipclkport_aclk", "mout_mfc_busd",
+ GAT_MFC_PPMU_MFCD0_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(0, "mfc_ppmu_mfcd0_ipclkport_pclk", "mout_mfc_busp",
+ GAT_MFC_PPMU_MFCD0_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(0, "mfc_ppmu_mfcd1_ipclkport_aclk", "mout_mfc_busd",
+ GAT_MFC_PPMU_MFCD1_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(0, "mfc_ppmu_mfcd1_ipclkport_pclk", "mout_mfc_busp",
+ GAT_MFC_PPMU_MFCD1_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(0, "mfc_sysreg_mfc_ipclkport_pclk", "mout_mfc_busp",
+ GAT_MFC_SYSREG_MFC_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(0, "mfc_tbu_mfcd0_ipclkport_clk", "mout_mfc_busd",
+ GAT_MFC_TBU_MFCD0_IPCLKPORT_CLK, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(0, "mfc_tbu_mfcd1_ipclkport_clk", "mout_mfc_busd",
+ GAT_MFC_TBU_MFCD1_IPCLKPORT_CLK, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(0, "mfc_busd_div4_gate", "mout_mfc_pll",
+ GAT_MFC_BUSD_DIV4_GATE, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(0, "mfc_busd_gate", "mout_mfc_pll", GAT_MFC_BUSD_GATE, 21, CLK_IS_CRITICAL, 0),
+};
+
+static const struct samsung_cmu_info mfc_cmu_info __initconst = {
+ .pll_clks = mfc_pll_clks,
+ .nr_pll_clks = ARRAY_SIZE(mfc_pll_clks),
+ .mux_clks = mfc_mux_clks,
+ .nr_mux_clks = ARRAY_SIZE(mfc_mux_clks),
+ .div_clks = mfc_div_clks,
+ .nr_div_clks = ARRAY_SIZE(mfc_div_clks),
+ .gate_clks = mfc_gate_clks,
+ .nr_gate_clks = ARRAY_SIZE(mfc_gate_clks),
+ .nr_clk_ids = MFC_NR_CLK,
+ .clk_regs = mfc_clk_regs,
+ .nr_clk_regs = ARRAY_SIZE(mfc_clk_regs),
+};
+
+/* Register Offset definitions for CMU_CAM_CSI (0x12610000) */
+#define PLL_LOCKTIME_PLL_CAM_CSI 0x0
+#define PLL_CON0_PLL_CAM_CSI 0x100
+#define DIV_CAM_CSI0_ACLK 0x1800
+#define DIV_CAM_CSI1_ACLK 0x1804
+#define DIV_CAM_CSI2_ACLK 0x1808
+#define DIV_CAM_CSI_BUSD 0x180c
+#define DIV_CAM_CSI_BUSP 0x1810
+#define GAT_CAM_CSI_CMU_CAM_CSI_IPCLKPORT_PCLK 0x2000
+#define GAT_CAM_AXI2APB_CAM_CSI_IPCLKPORT_ACLK 0x2004
+#define GAT_CAM_CSI_BUS_D_CAM_CSI_IPCLKPORT_CLK__SYSTEM__CLK_CSI0 0x2008
+#define GAT_CAM_CSI_BUS_D_CAM_CSI_IPCLKPORT_CLK__SYSTEM__CLK_CSI1 0x200c
+#define GAT_CAM_CSI_BUS_D_CAM_CSI_IPCLKPORT_CLK__SYSTEM__CLK_CSI2 0x2010
+#define GAT_CAM_CSI_BUS_D_CAM_CSI_IPCLKPORT_CLK__SYSTEM__CLK_SOC_NOC 0x2014
+#define GAT_CAM_CSI_BUS_D_CAM_CSI_IPCLKPORT_CLK__SYSTEM__NOC 0x2018
+#define GAT_CAM_CSI0_0_IPCLKPORT_I_ACLK 0x201c
+#define GAT_CAM_CSI0_0_IPCLKPORT_I_PCLK 0x2020
+#define GAT_CAM_CSI0_1_IPCLKPORT_I_ACLK 0x2024
+#define GAT_CAM_CSI0_1_IPCLKPORT_I_PCLK 0x2028
+#define GAT_CAM_CSI0_2_IPCLKPORT_I_ACLK 0x202c
+#define GAT_CAM_CSI0_2_IPCLKPORT_I_PCLK 0x2030
+#define GAT_CAM_CSI0_3_IPCLKPORT_I_ACLK 0x2034
+#define GAT_CAM_CSI0_3_IPCLKPORT_I_PCLK 0x2038
+#define GAT_CAM_CSI1_0_IPCLKPORT_I_ACLK 0x203c
+#define GAT_CAM_CSI1_0_IPCLKPORT_I_PCLK 0x2040
+#define GAT_CAM_CSI1_1_IPCLKPORT_I_ACLK 0x2044
+#define GAT_CAM_CSI1_1_IPCLKPORT_I_PCLK 0x2048
+#define GAT_CAM_CSI1_2_IPCLKPORT_I_ACLK 0x204c
+#define GAT_CAM_CSI1_2_IPCLKPORT_I_PCLK 0x2050
+#define GAT_CAM_CSI1_3_IPCLKPORT_I_ACLK 0x2054
+#define GAT_CAM_CSI1_3_IPCLKPORT_I_PCLK 0x2058
+#define GAT_CAM_CSI2_0_IPCLKPORT_I_ACLK 0x205c
+#define GAT_CAM_CSI2_0_IPCLKPORT_I_PCLK 0x2060
+#define GAT_CAM_CSI2_1_IPCLKPORT_I_ACLK 0x2064
+#define GAT_CAM_CSI2_1_IPCLKPORT_I_PCLK 0x2068
+#define GAT_CAM_CSI2_2_IPCLKPORT_I_ACLK 0x206c
+#define GAT_CAM_CSI2_2_IPCLKPORT_I_PCLK 0x2070
+#define GAT_CAM_CSI2_3_IPCLKPORT_I_ACLK 0x2074
+#define GAT_CAM_CSI2_3_IPCLKPORT_I_PCLK 0x2078
+#define GAT_CAM_NS_BRDG_CAM_CSI_IPCLKPORT_CLK__PSOC_CAM_CSI__CLK_CAM_CSI_D 0x207c
+#define GAT_CAM_NS_BRDG_CAM_CSI_IPCLKPORT_CLK__PSOC_CAM_CSI__CLK_CAM_CSI_P 0x2080
+#define GAT_CAM_SYSREG_CAM_CSI_IPCLKPORT_PCLK 0x2084
+#define GAT_CAM_TBU_CAM_CSI_IPCLKPORT_ACLK 0x2088
+
+static const unsigned long cam_csi_clk_regs[] __initconst = {
+ PLL_LOCKTIME_PLL_CAM_CSI,
+ PLL_CON0_PLL_CAM_CSI,
+ DIV_CAM_CSI0_ACLK,
+ DIV_CAM_CSI1_ACLK,
+ DIV_CAM_CSI2_ACLK,
+ DIV_CAM_CSI_BUSD,
+ DIV_CAM_CSI_BUSP,
+ GAT_CAM_CSI_CMU_CAM_CSI_IPCLKPORT_PCLK,
+ GAT_CAM_AXI2APB_CAM_CSI_IPCLKPORT_ACLK,
+ GAT_CAM_CSI_BUS_D_CAM_CSI_IPCLKPORT_CLK__SYSTEM__CLK_CSI0,
+ GAT_CAM_CSI_BUS_D_CAM_CSI_IPCLKPORT_CLK__SYSTEM__CLK_CSI1,
+ GAT_CAM_CSI_BUS_D_CAM_CSI_IPCLKPORT_CLK__SYSTEM__CLK_CSI2,
+ GAT_CAM_CSI_BUS_D_CAM_CSI_IPCLKPORT_CLK__SYSTEM__CLK_SOC_NOC,
+ GAT_CAM_CSI_BUS_D_CAM_CSI_IPCLKPORT_CLK__SYSTEM__NOC,
+ GAT_CAM_CSI0_0_IPCLKPORT_I_ACLK,
+ GAT_CAM_CSI0_0_IPCLKPORT_I_PCLK,
+ GAT_CAM_CSI0_1_IPCLKPORT_I_ACLK,
+ GAT_CAM_CSI0_1_IPCLKPORT_I_PCLK,
+ GAT_CAM_CSI0_2_IPCLKPORT_I_ACLK,
+ GAT_CAM_CSI0_2_IPCLKPORT_I_PCLK,
+ GAT_CAM_CSI0_3_IPCLKPORT_I_ACLK,
+ GAT_CAM_CSI0_3_IPCLKPORT_I_PCLK,
+ GAT_CAM_CSI1_0_IPCLKPORT_I_ACLK,
+ GAT_CAM_CSI1_0_IPCLKPORT_I_PCLK,
+ GAT_CAM_CSI1_1_IPCLKPORT_I_ACLK,
+ GAT_CAM_CSI1_1_IPCLKPORT_I_PCLK,
+ GAT_CAM_CSI1_2_IPCLKPORT_I_ACLK,
+ GAT_CAM_CSI1_2_IPCLKPORT_I_PCLK,
+ GAT_CAM_CSI1_3_IPCLKPORT_I_ACLK,
+ GAT_CAM_CSI1_3_IPCLKPORT_I_PCLK,
+ GAT_CAM_CSI2_0_IPCLKPORT_I_ACLK,
+ GAT_CAM_CSI2_0_IPCLKPORT_I_PCLK,
+ GAT_CAM_CSI2_1_IPCLKPORT_I_ACLK,
+ GAT_CAM_CSI2_1_IPCLKPORT_I_PCLK,
+ GAT_CAM_CSI2_2_IPCLKPORT_I_ACLK,
+ GAT_CAM_CSI2_2_IPCLKPORT_I_PCLK,
+ GAT_CAM_CSI2_3_IPCLKPORT_I_ACLK,
+ GAT_CAM_CSI2_3_IPCLKPORT_I_PCLK,
+ GAT_CAM_NS_BRDG_CAM_CSI_IPCLKPORT_CLK__PSOC_CAM_CSI__CLK_CAM_CSI_D,
+ GAT_CAM_NS_BRDG_CAM_CSI_IPCLKPORT_CLK__PSOC_CAM_CSI__CLK_CAM_CSI_P,
+ GAT_CAM_SYSREG_CAM_CSI_IPCLKPORT_PCLK,
+ GAT_CAM_TBU_CAM_CSI_IPCLKPORT_ACLK,
+};
+
+static const struct samsung_pll_rate_table pll_cam_csi_rate_table[] __initconst = {
+ PLL_35XX_RATE(24 * MHZ, 1066000000U, 533, 12, 0),
+};
+
+static const struct samsung_pll_clock cam_csi_pll_clks[] __initconst = {
+ PLL(pll_142xx, 0, "fout_pll_cam_csi", "fin_pll",
+ PLL_LOCKTIME_PLL_CAM_CSI, PLL_CON0_PLL_CAM_CSI, pll_cam_csi_rate_table),
+};
+
+PNAME(mout_cam_csi_pll_p) = { "fin_pll", "fout_pll_cam_csi" };
+
+static const struct samsung_mux_clock cam_csi_mux_clks[] __initconst = {
+ MUX(0, "mout_cam_csi_pll", mout_cam_csi_pll_p, PLL_CON0_PLL_CAM_CSI, 4, 1),
+};
+
+static const struct samsung_div_clock cam_csi_div_clks[] __initconst = {
+ DIV(0, "dout_cam_csi0_aclk", "mout_cam_csi_pll", DIV_CAM_CSI0_ACLK, 0, 4),
+ DIV(0, "dout_cam_csi1_aclk", "mout_cam_csi_pll", DIV_CAM_CSI1_ACLK, 0, 4),
+ DIV(0, "dout_cam_csi2_aclk", "mout_cam_csi_pll", DIV_CAM_CSI2_ACLK, 0, 4),
+ DIV(0, "dout_cam_csi_busd", "mout_cam_csi_pll", DIV_CAM_CSI_BUSD, 0, 4),
+ DIV(0, "dout_cam_csi_busp", "mout_cam_csi_pll", DIV_CAM_CSI_BUSP, 0, 4),
+};
+
+static const struct samsung_gate_clock cam_csi_gate_clks[] __initconst = {
+ GATE(0, "cam_csi_cmu_cam_csi_ipclkport_pclk", "dout_cam_csi_busp",
+ GAT_CAM_CSI_CMU_CAM_CSI_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(0, "cam_axi2apb_cam_csi_ipclkport_aclk", "dout_cam_csi_busp",
+ GAT_CAM_AXI2APB_CAM_CSI_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(0, "cam_csi_bus_d_cam_csi_ipclkport_clk__system__clk_csi0", "dout_cam_csi0_aclk",
+ GAT_CAM_CSI_BUS_D_CAM_CSI_IPCLKPORT_CLK__SYSTEM__CLK_CSI0, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(0, "cam_csi_bus_d_cam_csi_ipclkport_clk__system__clk_csi1", "dout_cam_csi1_aclk",
+ GAT_CAM_CSI_BUS_D_CAM_CSI_IPCLKPORT_CLK__SYSTEM__CLK_CSI1, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(0, "cam_csi_bus_d_cam_csi_ipclkport_clk__system__clk_csi2", "dout_cam_csi2_aclk",
+ GAT_CAM_CSI_BUS_D_CAM_CSI_IPCLKPORT_CLK__SYSTEM__CLK_CSI2, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(0, "cam_csi_bus_d_cam_csi_ipclkport_clk__system__clk_soc_noc", "dout_cam_csi_busd",
+ GAT_CAM_CSI_BUS_D_CAM_CSI_IPCLKPORT_CLK__SYSTEM__CLK_SOC_NOC, 21,
+ CLK_IGNORE_UNUSED, 0),
+ GATE(0, "cam_csi_bus_d_cam_csi_ipclkport_clk__system__noc", "dout_cam_csi_busd",
+ GAT_CAM_CSI_BUS_D_CAM_CSI_IPCLKPORT_CLK__SYSTEM__NOC, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(CAM_CSI0_0_IPCLKPORT_I_ACLK, "cam_csi0_0_ipclkport_i_aclk", "dout_cam_csi0_aclk",
+ GAT_CAM_CSI0_0_IPCLKPORT_I_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(0, "cam_csi0_0_ipclkport_i_pclk", "dout_cam_csi_busp",
+ GAT_CAM_CSI0_0_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(CAM_CSI0_1_IPCLKPORT_I_ACLK, "cam_csi0_1_ipclkport_i_aclk", "dout_cam_csi0_aclk",
+ GAT_CAM_CSI0_1_IPCLKPORT_I_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(0, "cam_csi0_1_ipclkport_i_pclk", "dout_cam_csi_busp",
+ GAT_CAM_CSI0_1_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(CAM_CSI0_2_IPCLKPORT_I_ACLK, "cam_csi0_2_ipclkport_i_aclk", "dout_cam_csi0_aclk",
+ GAT_CAM_CSI0_2_IPCLKPORT_I_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(0, "cam_csi0_2_ipclkport_i_pclk", "dout_cam_csi_busp",
+ GAT_CAM_CSI0_2_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(CAM_CSI0_3_IPCLKPORT_I_ACLK, "cam_csi0_3_ipclkport_i_aclk", "dout_cam_csi0_aclk",
+ GAT_CAM_CSI0_3_IPCLKPORT_I_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(0, "cam_csi0_3_ipclkport_i_pclk", "dout_cam_csi_busp",
+ GAT_CAM_CSI0_3_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(CAM_CSI1_0_IPCLKPORT_I_ACLK, "cam_csi1_0_ipclkport_i_aclk", "dout_cam_csi1_aclk",
+ GAT_CAM_CSI1_0_IPCLKPORT_I_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(0, "cam_csi1_0_ipclkport_i_pclk", "dout_cam_csi_busp",
+ GAT_CAM_CSI1_0_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(CAM_CSI1_1_IPCLKPORT_I_ACLK, "cam_csi1_1_ipclkport_i_aclk", "dout_cam_csi1_aclk",
+ GAT_CAM_CSI1_1_IPCLKPORT_I_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(0, "cam_csi1_1_ipclkport_i_pclk", "dout_cam_csi_busp",
+ GAT_CAM_CSI1_1_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(CAM_CSI1_2_IPCLKPORT_I_ACLK, "cam_csi1_2_ipclkport_i_aclk", "dout_cam_csi1_aclk",
+ GAT_CAM_CSI1_2_IPCLKPORT_I_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(0, "cam_csi1_2_ipclkport_i_pclk", "dout_cam_csi_busp",
+ GAT_CAM_CSI1_2_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(CAM_CSI1_3_IPCLKPORT_I_ACLK, "cam_csi1_3_ipclkport_i_aclk", "dout_cam_csi1_aclk",
+ GAT_CAM_CSI1_3_IPCLKPORT_I_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(0, "cam_csi1_3_ipclkport_i_pclk", "dout_cam_csi_busp",
+ GAT_CAM_CSI1_3_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(CAM_CSI2_0_IPCLKPORT_I_ACLK, "cam_csi2_0_ipclkport_i_aclk", "dout_cam_csi2_aclk",
+ GAT_CAM_CSI2_0_IPCLKPORT_I_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(0, "cam_csi2_0_ipclkport_i_pclk", "dout_cam_csi_busp",
+ GAT_CAM_CSI2_0_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(CAM_CSI2_1_IPCLKPORT_I_ACLK, "cam_csi2_1_ipclkport_i_aclk", "dout_cam_csi2_aclk",
+ GAT_CAM_CSI2_1_IPCLKPORT_I_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(0, "cam_csi2_1_ipclkport_i_pclk", "dout_cam_csi_busp",
+ GAT_CAM_CSI2_1_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(CAM_CSI2_2_IPCLKPORT_I_ACLK, "cam_csi2_2_ipclkport_i_aclk", "dout_cam_csi2_aclk",
+ GAT_CAM_CSI2_2_IPCLKPORT_I_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(0, "cam_csi2_2_ipclkport_i_pclk", "dout_cam_csi_busp",
+ GAT_CAM_CSI2_2_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(CAM_CSI2_3_IPCLKPORT_I_ACLK, "cam_csi2_3_ipclkport_i_aclk", "dout_cam_csi2_aclk",
+ GAT_CAM_CSI2_3_IPCLKPORT_I_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(0, "cam_csi2_3_ipclkport_i_pclk", "dout_cam_csi_busp",
+ GAT_CAM_CSI2_3_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(0, "cam_ns_brdg_cam_csi_ipclkport_clk__psoc_cam_csi__clk_cam_csi_d",
+ "dout_cam_csi_busd",
+ GAT_CAM_NS_BRDG_CAM_CSI_IPCLKPORT_CLK__PSOC_CAM_CSI__CLK_CAM_CSI_D, 21,
+ CLK_IGNORE_UNUSED, 0),
+ GATE(0, "cam_ns_brdg_cam_csi_ipclkport_clk__psoc_cam_csi__clk_cam_csi_p",
+ "dout_cam_csi_busp",
+ GAT_CAM_NS_BRDG_CAM_CSI_IPCLKPORT_CLK__PSOC_CAM_CSI__CLK_CAM_CSI_P, 21,
+ CLK_IGNORE_UNUSED, 0),
+ GATE(0, "cam_sysreg_cam_csi_ipclkport_pclk", "dout_cam_csi_busp",
+ GAT_CAM_SYSREG_CAM_CSI_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(0, "cam_tbu_cam_csi_ipclkport_aclk", "dout_cam_csi_busd",
+ GAT_CAM_TBU_CAM_CSI_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+};
+
+static const struct samsung_cmu_info cam_csi_cmu_info __initconst = {
+ .pll_clks = cam_csi_pll_clks,
+ .nr_pll_clks = ARRAY_SIZE(cam_csi_pll_clks),
+ .mux_clks = cam_csi_mux_clks,
+ .nr_mux_clks = ARRAY_SIZE(cam_csi_mux_clks),
+ .div_clks = cam_csi_div_clks,
+ .nr_div_clks = ARRAY_SIZE(cam_csi_div_clks),
+ .gate_clks = cam_csi_gate_clks,
+ .nr_gate_clks = ARRAY_SIZE(cam_csi_gate_clks),
+ .nr_clk_ids = CAM_CSI_NR_CLK,
+ .clk_regs = cam_csi_clk_regs,
+ .nr_clk_regs = ARRAY_SIZE(cam_csi_clk_regs),
+};
+
+/**
+ * fsd_cmu_probe - Probe function for FSD platform clocks
+ * @pdev: Pointer to platform device
+ *
+ * Configure clock hierarchy for clock domains of FSD platform
+ */
+static int __init fsd_cmu_probe(struct platform_device *pdev)
+{
+ const struct samsung_cmu_info *info;
+ struct device *dev = &pdev->dev;
+
+ info = of_device_get_match_data(dev);
+ exynos_arm64_register_cmu(dev, dev->of_node, info);
+
+ return 0;
+}
+
+/* CMUs which belong to Power Domains and need runtime PM to be implemented */
+static const struct of_device_id fsd_cmu_of_match[] = {
+ {
+ .compatible = "tesla,fsd-clock-peric",
+ .data = &peric_cmu_info,
+ }, {
+ .compatible = "tesla,fsd-clock-fsys0",
+ .data = &fsys0_cmu_info,
+ }, {
+ .compatible = "tesla,fsd-clock-fsys1",
+ .data = &fsys1_cmu_info,
+ }, {
+ .compatible = "tesla,fsd-clock-mfc",
+ .data = &mfc_cmu_info,
+ }, {
+ .compatible = "tesla,fsd-clock-cam_csi",
+ .data = &cam_csi_cmu_info,
+ }, {
+ },
+};
+
+static struct platform_driver fsd_cmu_driver __refdata = {
+ .driver = {
+ .name = "fsd-cmu",
+ .of_match_table = fsd_cmu_of_match,
+ .suppress_bind_attrs = true,
+ },
+ .probe = fsd_cmu_probe,
+};
+
+static int __init fsd_cmu_init(void)
+{
+ return platform_driver_register(&fsd_cmu_driver);
+}
+core_initcall(fsd_cmu_init);
diff --git a/drivers/clk/samsung/clk-pll.c b/drivers/clk/samsung/clk-pll.c
index 70cdc87f714e..fe383471c5f0 100644
--- a/drivers/clk/samsung/clk-pll.c
+++ b/drivers/clk/samsung/clk-pll.c
@@ -1469,6 +1469,7 @@ static void __init _samsung_clk_register_pll(struct samsung_clk_provider *ctx,
case pll_1450x:
case pll_1451x:
case pll_1452x:
+ case pll_142xx:
pll->enable_offs = PLL35XX_ENABLE_SHIFT;
pll->lock_offs = PLL35XX_LOCK_STAT_SHIFT;
if (!pll->rate_table)
diff --git a/drivers/clk/samsung/clk-pll.h b/drivers/clk/samsung/clk-pll.h
index c83a20195f6d..a9892c2d1f57 100644
--- a/drivers/clk/samsung/clk-pll.h
+++ b/drivers/clk/samsung/clk-pll.h
@@ -39,6 +39,7 @@ enum samsung_pll_type {
pll_1460x,
pll_0822x,
pll_0831x,
+ pll_142xx,
};
#define PLL_RATE(_fin, _m, _p, _s, _k, _ks) \
diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
index cfb8ea0df3b1..1589ae7d5abb 100644
--- a/drivers/clocksource/Kconfig
+++ b/drivers/clocksource/Kconfig
@@ -617,15 +617,6 @@ config CLKSRC_ST_LPC
Enable this option to use the Low Power controller timer
as clocksource.
-config ATCPIT100_TIMER
- bool "ATCPIT100 timer driver"
- depends on NDS32 || COMPILE_TEST
- depends on HAS_IOMEM
- select TIMER_OF
- default NDS32
- help
- This option enables support for the Andestech ATCPIT100 timers.
-
config RISCV_TIMER
bool "Timer for the RISC-V platform" if COMPILE_TEST
depends on GENERIC_SCHED_CLOCK && RISCV && RISCV_SBI
@@ -713,7 +704,6 @@ config INGENIC_OST
config MICROCHIP_PIT64B
bool "Microchip PIT64B support"
depends on OF || COMPILE_TEST
- select CLKSRC_MMIO
select TIMER_OF
help
This option enables Microchip PIT64B timer for Atmel
diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
index fa5f624eadb6..9c85ee2bb373 100644
--- a/drivers/clocksource/Makefile
+++ b/drivers/clocksource/Makefile
@@ -81,7 +81,6 @@ obj-$(CONFIG_INGENIC_SYSOST) += ingenic-sysost.o
obj-$(CONFIG_INGENIC_TIMER) += ingenic-timer.o
obj-$(CONFIG_CLKSRC_ST_LPC) += clksrc_st_lpc.o
obj-$(CONFIG_X86_NUMACHIP) += numachip.o
-obj-$(CONFIG_ATCPIT100_TIMER) += timer-atcpit100.o
obj-$(CONFIG_RISCV_TIMER) += timer-riscv.o
obj-$(CONFIG_CLINT_TIMER) += timer-clint.o
obj-$(CONFIG_CSKY_MP_TIMER) += timer-mp-csky.o
diff --git a/drivers/clocksource/acpi_pm.c b/drivers/clocksource/acpi_pm.c
index eb596ff9e7bb..279ddff81ab4 100644
--- a/drivers/clocksource/acpi_pm.c
+++ b/drivers/clocksource/acpi_pm.c
@@ -229,8 +229,10 @@ static int __init parse_pmtmr(char *arg)
int ret;
ret = kstrtouint(arg, 16, &base);
- if (ret)
- return ret;
+ if (ret) {
+ pr_warn("PMTMR: invalid 'pmtmr=' value: '%s'\n", arg);
+ return 1;
+ }
pr_info("PMTMR IOPort override: 0x%04x -> 0x%04x\n", pmtmr_ioport,
base);
diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
index 1ecd52f903b8..9ab8221ee3c6 100644
--- a/drivers/clocksource/arm_arch_timer.c
+++ b/drivers/clocksource/arm_arch_timer.c
@@ -880,10 +880,19 @@ static void __arch_timer_setup(unsigned type,
clockevents_config_and_register(clk, arch_timer_rate, 0xf, max_delta);
}
-static void arch_timer_evtstrm_enable(int divider)
+static void arch_timer_evtstrm_enable(unsigned int divider)
{
u32 cntkctl = arch_timer_get_cntkctl();
+#ifdef CONFIG_ARM64
+ /* ECV is likely to require a large divider. Use the EVNTIS flag. */
+ if (cpus_have_const_cap(ARM64_HAS_ECV) && divider > 15) {
+ cntkctl |= ARCH_TIMER_EVT_INTERVAL_SCALE;
+ divider -= 8;
+ }
+#endif
+
+ divider = min(divider, 15U);
cntkctl &= ~ARCH_TIMER_EVT_TRIGGER_MASK;
/* Set the divider and enable virtual event stream */
cntkctl |= (divider << ARCH_TIMER_EVT_TRIGGER_SHIFT)
@@ -912,7 +921,7 @@ static void arch_timer_configure_evtstream(void)
lsb++;
/* enable event stream */
- arch_timer_evtstrm_enable(max(0, min(lsb, 15)));
+ arch_timer_evtstrm_enable(max(0, lsb));
}
static void arch_counter_set_user_access(void)
diff --git a/drivers/clocksource/exynos_mct.c b/drivers/clocksource/exynos_mct.c
index 6db3d5511b0f..f29c812b70c9 100644
--- a/drivers/clocksource/exynos_mct.c
+++ b/drivers/clocksource/exynos_mct.c
@@ -60,27 +60,18 @@
#define MCT_CLKEVENTS_RATING 350
#endif
+/* There are four Global timers starting with 0 offset */
+#define MCT_G0_IRQ 0
+/* Local timers count starts after global timer count */
+#define MCT_L0_IRQ 4
+/* Max number of IRQ as per DT binding document */
+#define MCT_NR_IRQS 20
+
enum {
MCT_INT_SPI,
MCT_INT_PPI
};
-enum {
- MCT_G0_IRQ,
- MCT_G1_IRQ,
- MCT_G2_IRQ,
- MCT_G3_IRQ,
- MCT_L0_IRQ,
- MCT_L1_IRQ,
- MCT_L2_IRQ,
- MCT_L3_IRQ,
- MCT_L4_IRQ,
- MCT_L5_IRQ,
- MCT_L6_IRQ,
- MCT_L7_IRQ,
- MCT_NR_IRQS,
-};
-
static void __iomem *reg_base;
static unsigned long clk_rate;
static unsigned int mct_int_type;
@@ -89,7 +80,11 @@ static int mct_irqs[MCT_NR_IRQS];
struct mct_clock_event_device {
struct clock_event_device evt;
unsigned long base;
- char name[10];
+ /**
+ * The length of the name must be adjusted if number of
+ * local timer interrupts grow over two digits
+ */
+ char name[11];
};
static void exynos4_mct_write(unsigned int value, unsigned long offset)
@@ -541,6 +536,11 @@ static int __init exynos4_timer_interrupts(struct device_node *np,
* irqs are specified.
*/
nr_irqs = of_irq_count(np);
+ if (nr_irqs > ARRAY_SIZE(mct_irqs)) {
+ pr_err("exynos-mct: too many (%d) interrupts configured in DT\n",
+ nr_irqs);
+ nr_irqs = ARRAY_SIZE(mct_irqs);
+ }
for (i = MCT_L0_IRQ; i < nr_irqs; i++)
mct_irqs[i] = irq_of_parse_and_map(np, i);
@@ -553,11 +553,14 @@ static int __init exynos4_timer_interrupts(struct device_node *np,
mct_irqs[MCT_L0_IRQ], err);
} else {
for_each_possible_cpu(cpu) {
- int mct_irq = mct_irqs[MCT_L0_IRQ + cpu];
+ int mct_irq;
struct mct_clock_event_device *pcpu_mevt =
per_cpu_ptr(&percpu_mct_tick, cpu);
pcpu_mevt->evt.irq = -1;
+ if (MCT_L0_IRQ + cpu >= ARRAY_SIZE(mct_irqs))
+ break;
+ mct_irq = mct_irqs[MCT_L0_IRQ + cpu];
irq_set_status_flags(mct_irq, IRQ_NOAUTOEN);
if (request_irq(mct_irq,
diff --git a/drivers/clocksource/timer-atcpit100.c b/drivers/clocksource/timer-atcpit100.c
deleted file mode 100644
index b4bd2f5b801d..000000000000
--- a/drivers/clocksource/timer-atcpit100.c
+++ /dev/null
@@ -1,266 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-// Copyright (C) 2005-2017 Andes Technology Corporation
-/*
- * Andestech ATCPIT100 Timer Device Driver Implementation
- * Rick Chen, Andes Technology Corporation <rick@andestech.com>
- *
- */
-
-#include <linux/irq.h>
-#include <linux/clocksource.h>
-#include <linux/clockchips.h>
-#include <linux/interrupt.h>
-#include <linux/ioport.h>
-#include <linux/cpufreq.h>
-#include <linux/sched.h>
-#include <linux/sched_clock.h>
-#include <linux/of_address.h>
-#include <linux/of_irq.h>
-#include <linux/of_platform.h>
-#include "timer-of.h"
-#ifdef CONFIG_NDS32
-#include <asm/vdso_timer_info.h>
-#endif
-
-/*
- * Definition of register offsets
- */
-
-/* ID and Revision Register */
-#define ID_REV 0x0
-
-/* Configuration Register */
-#define CFG 0x10
-
-/* Interrupt Enable Register */
-#define INT_EN 0x14
-#define CH_INT_EN(c, i) ((1<<i)<<(4*c))
-#define CH0INT0EN 0x01
-
-/* Interrupt Status Register */
-#define INT_STA 0x18
-#define CH0INT0 0x01
-
-/* Channel Enable Register */
-#define CH_EN 0x1C
-#define CH0TMR0EN 0x1
-#define CH1TMR0EN 0x10
-
-/* Channel 0 , 1 Control Register */
-#define CH0_CTL (0x20)
-#define CH1_CTL (0x20 + 0x10)
-
-/* Channel clock source , bit 3 , 0:External clock , 1:APB clock */
-#define APB_CLK BIT(3)
-
-/* Channel mode , bit 0~2 */
-#define TMR_32 0x1
-#define TMR_16 0x2
-#define TMR_8 0x3
-
-/* Channel 0 , 1 Reload Register */
-#define CH0_REL (0x24)
-#define CH1_REL (0x24 + 0x10)
-
-/* Channel 0 , 1 Counter Register */
-#define CH0_CNT (0x28)
-#define CH1_CNT (0x28 + 0x10)
-
-#define TIMER_SYNC_TICKS 3
-
-static void atcpit100_ch1_tmr0_en(void __iomem *base)
-{
- writel(~0, base + CH1_REL);
- writel(APB_CLK|TMR_32, base + CH1_CTL);
-}
-
-static void atcpit100_ch0_tmr0_en(void __iomem *base)
-{
- writel(APB_CLK|TMR_32, base + CH0_CTL);
-}
-
-static void atcpit100_clkevt_time_setup(void __iomem *base, unsigned long delay)
-{
- writel(delay, base + CH0_CNT);
- writel(delay, base + CH0_REL);
-}
-
-static void atcpit100_timer_clear_interrupt(void __iomem *base)
-{
- u32 val;
-
- val = readl(base + INT_STA);
- writel(val | CH0INT0, base + INT_STA);
-}
-
-static void atcpit100_clocksource_start(void __iomem *base)
-{
- u32 val;
-
- val = readl(base + CH_EN);
- writel(val | CH1TMR0EN, base + CH_EN);
-}
-
-static void atcpit100_clkevt_time_start(void __iomem *base)
-{
- u32 val;
-
- val = readl(base + CH_EN);
- writel(val | CH0TMR0EN, base + CH_EN);
-}
-
-static void atcpit100_clkevt_time_stop(void __iomem *base)
-{
- u32 val;
-
- atcpit100_timer_clear_interrupt(base);
- val = readl(base + CH_EN);
- writel(val & ~CH0TMR0EN, base + CH_EN);
-}
-
-static int atcpit100_clkevt_next_event(unsigned long evt,
- struct clock_event_device *clkevt)
-{
- u32 val;
- struct timer_of *to = to_timer_of(clkevt);
-
- val = readl(timer_of_base(to) + CH_EN);
- writel(val & ~CH0TMR0EN, timer_of_base(to) + CH_EN);
- writel(evt, timer_of_base(to) + CH0_REL);
- writel(val | CH0TMR0EN, timer_of_base(to) + CH_EN);
-
- return 0;
-}
-
-static int atcpit100_clkevt_set_periodic(struct clock_event_device *evt)
-{
- struct timer_of *to = to_timer_of(evt);
-
- atcpit100_clkevt_time_setup(timer_of_base(to), timer_of_period(to));
- atcpit100_clkevt_time_start(timer_of_base(to));
-
- return 0;
-}
-static int atcpit100_clkevt_shutdown(struct clock_event_device *evt)
-{
- struct timer_of *to = to_timer_of(evt);
-
- atcpit100_clkevt_time_stop(timer_of_base(to));
-
- return 0;
-}
-static int atcpit100_clkevt_set_oneshot(struct clock_event_device *evt)
-{
- struct timer_of *to = to_timer_of(evt);
- u32 val;
-
- writel(~0x0, timer_of_base(to) + CH0_REL);
- val = readl(timer_of_base(to) + CH_EN);
- writel(val | CH0TMR0EN, timer_of_base(to) + CH_EN);
-
- return 0;
-}
-
-static irqreturn_t atcpit100_timer_interrupt(int irq, void *dev_id)
-{
- struct clock_event_device *evt = (struct clock_event_device *)dev_id;
- struct timer_of *to = to_timer_of(evt);
-
- atcpit100_timer_clear_interrupt(timer_of_base(to));
-
- evt->event_handler(evt);
-
- return IRQ_HANDLED;
-}
-
-static struct timer_of to = {
- .flags = TIMER_OF_IRQ | TIMER_OF_CLOCK | TIMER_OF_BASE,
-
- .clkevt = {
- .name = "atcpit100_tick",
- .rating = 300,
- .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
- .set_state_shutdown = atcpit100_clkevt_shutdown,
- .set_state_periodic = atcpit100_clkevt_set_periodic,
- .set_state_oneshot = atcpit100_clkevt_set_oneshot,
- .tick_resume = atcpit100_clkevt_shutdown,
- .set_next_event = atcpit100_clkevt_next_event,
- .cpumask = cpu_possible_mask,
- },
-
- .of_irq = {
- .handler = atcpit100_timer_interrupt,
- .flags = IRQF_TIMER | IRQF_IRQPOLL,
- },
-
- /*
- * FIXME: we currently only support clocking using PCLK
- * and using EXTCLK is not supported in the driver.
- */
- .of_clk = {
- .name = "PCLK",
- }
-};
-
-static u64 notrace atcpit100_timer_sched_read(void)
-{
- return ~readl(timer_of_base(&to) + CH1_CNT);
-}
-
-#ifdef CONFIG_NDS32
-static void fill_vdso_need_info(struct device_node *node)
-{
- struct resource timer_res;
- of_address_to_resource(node, 0, &timer_res);
- timer_info.mapping_base = (unsigned long)timer_res.start;
- timer_info.cycle_count_down = true;
- timer_info.cycle_count_reg_offset = CH1_CNT;
-}
-#endif
-
-static int __init atcpit100_timer_init(struct device_node *node)
-{
- int ret;
- u32 val;
- void __iomem *base;
-
- ret = timer_of_init(node, &to);
- if (ret)
- return ret;
-
- base = timer_of_base(&to);
-
- sched_clock_register(atcpit100_timer_sched_read, 32,
- timer_of_rate(&to));
-
- ret = clocksource_mmio_init(base + CH1_CNT,
- node->name, timer_of_rate(&to), 300, 32,
- clocksource_mmio_readl_down);
-
- if (ret) {
- pr_err("Failed to register clocksource\n");
- return ret;
- }
-
- /* clear channel 0 timer0 interrupt */
- atcpit100_timer_clear_interrupt(base);
-
- clockevents_config_and_register(&to.clkevt, timer_of_rate(&to),
- TIMER_SYNC_TICKS, 0xffffffff);
- atcpit100_ch0_tmr0_en(base);
- atcpit100_ch1_tmr0_en(base);
- atcpit100_clocksource_start(base);
- atcpit100_clkevt_time_start(base);
-
- /* Enable channel 0 timer0 interrupt */
- val = readl(base + INT_EN);
- writel(val | CH0INT0EN, base + INT_EN);
-
-#ifdef CONFIG_NDS32
- fill_vdso_need_info(node);
-#endif
-
- return ret;
-}
-
-TIMER_OF_DECLARE(atcpit100, "andestech,atcpit100", atcpit100_timer_init);
diff --git a/drivers/clocksource/timer-imx-sysctr.c b/drivers/clocksource/timer-imx-sysctr.c
index 55a8e198d2a1..523e37662a6e 100644
--- a/drivers/clocksource/timer-imx-sysctr.c
+++ b/drivers/clocksource/timer-imx-sysctr.c
@@ -110,7 +110,7 @@ static struct timer_of to_sysctr = {
},
.of_irq = {
.handler = sysctr_timer_interrupt,
- .flags = IRQF_TIMER | IRQF_IRQPOLL,
+ .flags = IRQF_TIMER,
},
.of_clk = {
.name = "per",
diff --git a/drivers/clocksource/timer-imx-tpm.c b/drivers/clocksource/timer-imx-tpm.c
index 2cdc077a39f5..bd64a8a8427f 100644
--- a/drivers/clocksource/timer-imx-tpm.c
+++ b/drivers/clocksource/timer-imx-tpm.c
@@ -32,8 +32,8 @@
#define TPM_C0SC_CHF_MASK (0x1 << 7)
#define TPM_C0V 0x24
-static int counter_width;
-static void __iomem *timer_base;
+static int counter_width __ro_after_init;
+static void __iomem *timer_base __ro_after_init;
static inline void tpm_timer_disable(void)
{
@@ -73,12 +73,12 @@ static unsigned long tpm_read_current_timer(void)
{
return tpm_read_counter();
}
-#endif
static u64 notrace tpm_read_sched_clock(void)
{
return tpm_read_counter();
}
+#endif
static int tpm_set_next_event(unsigned long delta,
struct clock_event_device *evt)
@@ -127,9 +127,9 @@ static irqreturn_t tpm_timer_interrupt(int irq, void *dev_id)
static struct timer_of to_tpm = {
.flags = TIMER_OF_IRQ | TIMER_OF_BASE | TIMER_OF_CLOCK,
.clkevt = {
- .name = "i.MX7ULP TPM Timer",
+ .name = "i.MX TPM Timer",
.rating = 200,
- .features = CLOCK_EVT_FEAT_ONESHOT,
+ .features = CLOCK_EVT_FEAT_ONESHOT | CLOCK_EVT_FEAT_DYNIRQ,
.set_state_shutdown = tpm_set_state_shutdown,
.set_state_oneshot = tpm_set_state_oneshot,
.set_next_event = tpm_set_next_event,
@@ -137,7 +137,7 @@ static struct timer_of to_tpm = {
},
.of_irq = {
.handler = tpm_timer_interrupt,
- .flags = IRQF_TIMER | IRQF_IRQPOLL,
+ .flags = IRQF_TIMER,
},
.of_clk = {
.name = "per",
@@ -150,10 +150,10 @@ static int __init tpm_clocksource_init(void)
tpm_delay_timer.read_current_timer = &tpm_read_current_timer;
tpm_delay_timer.freq = timer_of_rate(&to_tpm) >> 3;
register_current_timer_delay(&tpm_delay_timer);
-#endif
sched_clock_register(tpm_read_sched_clock, counter_width,
timer_of_rate(&to_tpm) >> 3);
+#endif
return clocksource_mmio_init(timer_base + TPM_CNT,
"imx-tpm",
diff --git a/drivers/clocksource/timer-microchip-pit64b.c b/drivers/clocksource/timer-microchip-pit64b.c
index cfa4ec7ef396..abce83d2f00b 100644
--- a/drivers/clocksource/timer-microchip-pit64b.c
+++ b/drivers/clocksource/timer-microchip-pit64b.c
@@ -42,8 +42,7 @@
#define MCHP_PIT64B_LSBMASK GENMASK_ULL(31, 0)
#define MCHP_PIT64B_PRES_TO_MODE(p) (MCHP_PIT64B_MR_PRES & ((p) << 8))
#define MCHP_PIT64B_MODE_TO_PRES(m) ((MCHP_PIT64B_MR_PRES & (m)) >> 8)
-#define MCHP_PIT64B_DEF_CS_FREQ 5000000UL /* 5 MHz */
-#define MCHP_PIT64B_DEF_CE_FREQ 32768 /* 32 KHz */
+#define MCHP_PIT64B_DEF_FREQ 5000000UL /* 5 MHz */
#define MCHP_PIT64B_NAME "pit64b"
@@ -165,7 +164,7 @@ static u64 mchp_pit64b_clksrc_read(struct clocksource *cs)
return mchp_pit64b_cnt_read(mchp_pit64b_cs_base);
}
-static u64 mchp_pit64b_sched_read_clk(void)
+static u64 notrace mchp_pit64b_sched_read_clk(void)
{
return mchp_pit64b_cnt_read(mchp_pit64b_cs_base);
}
@@ -418,7 +417,6 @@ static int __init mchp_pit64b_init_clkevt(struct mchp_pit64b_timer *timer,
static int __init mchp_pit64b_dt_init_timer(struct device_node *node,
bool clkevt)
{
- u32 freq = clkevt ? MCHP_PIT64B_DEF_CE_FREQ : MCHP_PIT64B_DEF_CS_FREQ;
struct mchp_pit64b_timer timer;
unsigned long clk_rate;
u32 irq = 0;
@@ -446,7 +444,7 @@ static int __init mchp_pit64b_dt_init_timer(struct device_node *node,
}
/* Initialize mode (prescaler + SGCK bit). To be used at runtime. */
- ret = mchp_pit64b_init_mode(&timer, freq);
+ ret = mchp_pit64b_init_mode(&timer, MCHP_PIT64B_DEF_FREQ);
if (ret)
goto irq_unmap;
diff --git a/drivers/clocksource/timer-of.c b/drivers/clocksource/timer-of.c
index 529cc6a51cdb..c3f54d9912be 100644
--- a/drivers/clocksource/timer-of.c
+++ b/drivers/clocksource/timer-of.c
@@ -157,9 +157,9 @@ static __init int timer_of_base_init(struct device_node *np,
of_base->base = of_base->name ?
of_io_request_and_map(np, of_base->index, of_base->name) :
of_iomap(np, of_base->index);
- if (IS_ERR(of_base->base)) {
- pr_err("Failed to iomap (%s)\n", of_base->name);
- return PTR_ERR(of_base->base);
+ if (IS_ERR_OR_NULL(of_base->base)) {
+ pr_err("Failed to iomap (%s:%s)\n", np->name, of_base->name);
+ return of_base->base ? PTR_ERR(of_base->base) : -ENOMEM;
}
return 0;
diff --git a/drivers/clocksource/timer-ti-dm-systimer.c b/drivers/clocksource/timer-ti-dm-systimer.c
index b6f97960d8ee..2737407ff069 100644
--- a/drivers/clocksource/timer-ti-dm-systimer.c
+++ b/drivers/clocksource/timer-ti-dm-systimer.c
@@ -241,8 +241,7 @@ static void __init dmtimer_systimer_assign_alwon(void)
bool quirk_unreliable_oscillator = false;
/* Quirk unreliable 32 KiHz oscillator with incomplete dts */
- if (of_machine_is_compatible("ti,omap3-beagle") ||
- of_machine_is_compatible("timll,omap3-devkit8000")) {
+ if (of_machine_is_compatible("ti,omap3-beagle-ab4")) {
quirk_unreliable_oscillator = true;
counter_32k = -ENODEV;
}
@@ -695,9 +694,9 @@ static int __init dmtimer_percpu_quirk_init(struct device_node *np, u32 pa)
return 0;
}
- if (pa == 0x48034000) /* dra7 dmtimer3 */
+ if (pa == 0x4882c000) /* dra7 dmtimer15 */
return dmtimer_percpu_timer_init(np, 0);
- else if (pa == 0x48036000) /* dra7 dmtimer4 */
+ else if (pa == 0x4882e000) /* dra7 dmtimer16 */
return dmtimer_percpu_timer_init(np, 1);
return 0;
diff --git a/drivers/connector/cn_proc.c b/drivers/connector/cn_proc.c
index 646ad385e490..ccac1c453080 100644
--- a/drivers/connector/cn_proc.c
+++ b/drivers/connector/cn_proc.c
@@ -358,7 +358,7 @@ static void cn_proc_mcast_ctl(struct cn_msg *msg,
* other namespaces.
*/
if ((current_user_ns() != &init_user_ns) ||
- (task_active_pid_ns(current) != &init_pid_ns))
+ !task_is_in_init_pid_ns(current))
return;
/* Can only change if privileged. */
diff --git a/drivers/counter/counter-core.c b/drivers/counter/counter-core.c
index 7e0957eea094..869894b74741 100644
--- a/drivers/counter/counter-core.c
+++ b/drivers/counter/counter-core.c
@@ -90,10 +90,8 @@ struct counter_device *counter_alloc(size_t sizeof_priv)
int err;
ch = kzalloc(sizeof(*ch) + sizeof_priv, GFP_KERNEL);
- if (!ch) {
- err = -ENOMEM;
- goto err_alloc_ch;
- }
+ if (!ch)
+ return NULL;
counter = &ch->counter;
dev = &counter->dev;
@@ -123,9 +121,8 @@ err_chrdev_add:
err_ida_alloc:
kfree(ch);
-err_alloc_ch:
- return ERR_PTR(err);
+ return NULL;
}
EXPORT_SYMBOL_GPL(counter_alloc);
@@ -208,12 +205,12 @@ struct counter_device *devm_counter_alloc(struct device *dev, size_t sizeof_priv
int err;
counter = counter_alloc(sizeof_priv);
- if (IS_ERR(counter))
- return counter;
+ if (!counter)
+ return NULL;
err = devm_add_action_or_reset(dev, devm_counter_put, counter);
if (err < 0)
- return ERR_PTR(err);
+ return NULL;
return counter;
}
diff --git a/drivers/counter/counter-sysfs.c b/drivers/counter/counter-sysfs.c
index 7cc4d1d523ea..04eac41dad33 100644
--- a/drivers/counter/counter-sysfs.c
+++ b/drivers/counter/counter-sysfs.c
@@ -19,6 +19,11 @@
#include "counter-sysfs.h"
+static inline struct counter_device *counter_from_dev(struct device *dev)
+{
+ return container_of(dev, struct counter_device, dev);
+}
+
/**
* struct counter_attribute - Counter sysfs attribute
* @dev_attr: device attribute for sysfs
@@ -90,7 +95,7 @@ static ssize_t counter_comp_u8_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
const struct counter_attribute *const a = to_counter_attribute(attr);
- struct counter_device *const counter = dev_get_drvdata(dev);
+ struct counter_device *const counter = counter_from_dev(dev);
int err;
u8 data = 0;
@@ -122,7 +127,7 @@ static ssize_t counter_comp_u8_store(struct device *dev,
const char *buf, size_t len)
{
const struct counter_attribute *const a = to_counter_attribute(attr);
- struct counter_device *const counter = dev_get_drvdata(dev);
+ struct counter_device *const counter = counter_from_dev(dev);
int err;
bool bool_data = 0;
u8 data = 0;
@@ -158,7 +163,7 @@ static ssize_t counter_comp_u32_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
const struct counter_attribute *const a = to_counter_attribute(attr);
- struct counter_device *const counter = dev_get_drvdata(dev);
+ struct counter_device *const counter = counter_from_dev(dev);
const struct counter_available *const avail = a->comp.priv;
int err;
u32 data = 0;
@@ -221,7 +226,7 @@ static ssize_t counter_comp_u32_store(struct device *dev,
const char *buf, size_t len)
{
const struct counter_attribute *const a = to_counter_attribute(attr);
- struct counter_device *const counter = dev_get_drvdata(dev);
+ struct counter_device *const counter = counter_from_dev(dev);
struct counter_count *const count = a->parent;
struct counter_synapse *const synapse = a->comp.priv;
const struct counter_available *const avail = a->comp.priv;
@@ -281,7 +286,7 @@ static ssize_t counter_comp_u64_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
const struct counter_attribute *const a = to_counter_attribute(attr);
- struct counter_device *const counter = dev_get_drvdata(dev);
+ struct counter_device *const counter = counter_from_dev(dev);
int err;
u64 data = 0;
@@ -309,7 +314,7 @@ static ssize_t counter_comp_u64_store(struct device *dev,
const char *buf, size_t len)
{
const struct counter_attribute *const a = to_counter_attribute(attr);
- struct counter_device *const counter = dev_get_drvdata(dev);
+ struct counter_device *const counter = counter_from_dev(dev);
int err;
u64 data = 0;
diff --git a/drivers/cpufreq/amd-pstate-trace.h b/drivers/cpufreq/amd-pstate-trace.h
index 647505957d4f..35f38ae67fb1 100644
--- a/drivers/cpufreq/amd-pstate-trace.h
+++ b/drivers/cpufreq/amd-pstate-trace.h
@@ -27,6 +27,10 @@ TRACE_EVENT(amd_pstate_perf,
TP_PROTO(unsigned long min_perf,
unsigned long target_perf,
unsigned long capacity,
+ u64 freq,
+ u64 mperf,
+ u64 aperf,
+ u64 tsc,
unsigned int cpu_id,
bool changed,
bool fast_switch
@@ -35,6 +39,10 @@ TRACE_EVENT(amd_pstate_perf,
TP_ARGS(min_perf,
target_perf,
capacity,
+ freq,
+ mperf,
+ aperf,
+ tsc,
cpu_id,
changed,
fast_switch
@@ -44,6 +52,10 @@ TRACE_EVENT(amd_pstate_perf,
__field(unsigned long, min_perf)
__field(unsigned long, target_perf)
__field(unsigned long, capacity)
+ __field(unsigned long long, freq)
+ __field(unsigned long long, mperf)
+ __field(unsigned long long, aperf)
+ __field(unsigned long long, tsc)
__field(unsigned int, cpu_id)
__field(bool, changed)
__field(bool, fast_switch)
@@ -53,15 +65,23 @@ TRACE_EVENT(amd_pstate_perf,
__entry->min_perf = min_perf;
__entry->target_perf = target_perf;
__entry->capacity = capacity;
+ __entry->freq = freq;
+ __entry->mperf = mperf;
+ __entry->aperf = aperf;
+ __entry->tsc = tsc;
__entry->cpu_id = cpu_id;
__entry->changed = changed;
__entry->fast_switch = fast_switch;
),
- TP_printk("amd_min_perf=%lu amd_des_perf=%lu amd_max_perf=%lu cpu_id=%u changed=%s fast_switch=%s",
+ TP_printk("amd_min_perf=%lu amd_des_perf=%lu amd_max_perf=%lu freq=%llu mperf=%llu aperf=%llu tsc=%llu cpu_id=%u changed=%s fast_switch=%s",
(unsigned long)__entry->min_perf,
(unsigned long)__entry->target_perf,
(unsigned long)__entry->capacity,
+ (unsigned long long)__entry->freq,
+ (unsigned long long)__entry->mperf,
+ (unsigned long long)__entry->aperf,
+ (unsigned long long)__entry->tsc,
(unsigned int)__entry->cpu_id,
(__entry->changed) ? "true" : "false",
(__entry->fast_switch) ? "true" : "false"
diff --git a/drivers/cpufreq/amd-pstate.c b/drivers/cpufreq/amd-pstate.c
index 9ce75ed11f8e..7be38bc6a673 100644
--- a/drivers/cpufreq/amd-pstate.c
+++ b/drivers/cpufreq/amd-pstate.c
@@ -66,6 +66,18 @@ MODULE_PARM_DESC(shared_mem,
static struct cpufreq_driver amd_pstate_driver;
/**
+ * struct amd_aperf_mperf
+ * @aperf: actual performance frequency clock count
+ * @mperf: maximum performance frequency clock count
+ * @tsc: time stamp counter
+ */
+struct amd_aperf_mperf {
+ u64 aperf;
+ u64 mperf;
+ u64 tsc;
+};
+
+/**
* struct amd_cpudata - private CPU data for AMD P-State
* @cpu: CPU number
* @req: constraint request to apply
@@ -81,6 +93,9 @@ static struct cpufreq_driver amd_pstate_driver;
* @min_freq: the frequency that mapped to lowest_perf
* @nominal_freq: the frequency that mapped to nominal_perf
* @lowest_nonlinear_freq: the frequency that mapped to lowest_nonlinear_perf
+ * @cur: Difference of Aperf/Mperf/tsc count between last and current sample
+ * @prev: Last Aperf/Mperf/tsc count value read from register
+ * @freq: current cpu frequency value
* @boost_supported: check whether the Processor or SBIOS supports boost mode
*
* The amd_cpudata is key private data for each CPU thread in AMD P-State, and
@@ -102,6 +117,10 @@ struct amd_cpudata {
u32 nominal_freq;
u32 lowest_nonlinear_freq;
+ struct amd_aperf_mperf cur;
+ struct amd_aperf_mperf prev;
+
+ u64 freq;
bool boost_supported;
};
@@ -211,6 +230,39 @@ static inline void amd_pstate_update_perf(struct amd_cpudata *cpudata,
max_perf, fast_switch);
}
+static inline bool amd_pstate_sample(struct amd_cpudata *cpudata)
+{
+ u64 aperf, mperf, tsc;
+ unsigned long flags;
+
+ local_irq_save(flags);
+ rdmsrl(MSR_IA32_APERF, aperf);
+ rdmsrl(MSR_IA32_MPERF, mperf);
+ tsc = rdtsc();
+
+ if (cpudata->prev.mperf == mperf || cpudata->prev.tsc == tsc) {
+ local_irq_restore(flags);
+ return false;
+ }
+
+ local_irq_restore(flags);
+
+ cpudata->cur.aperf = aperf;
+ cpudata->cur.mperf = mperf;
+ cpudata->cur.tsc = tsc;
+ cpudata->cur.aperf -= cpudata->prev.aperf;
+ cpudata->cur.mperf -= cpudata->prev.mperf;
+ cpudata->cur.tsc -= cpudata->prev.tsc;
+
+ cpudata->prev.aperf = aperf;
+ cpudata->prev.mperf = mperf;
+ cpudata->prev.tsc = tsc;
+
+ cpudata->freq = div64_u64((cpudata->cur.aperf * cpu_khz), cpudata->cur.mperf);
+
+ return true;
+}
+
static void amd_pstate_update(struct amd_cpudata *cpudata, u32 min_perf,
u32 des_perf, u32 max_perf, bool fast_switch)
{
@@ -226,8 +278,11 @@ static void amd_pstate_update(struct amd_cpudata *cpudata, u32 min_perf,
value &= ~AMD_CPPC_MAX_PERF(~0L);
value |= AMD_CPPC_MAX_PERF(max_perf);
- trace_amd_pstate_perf(min_perf, des_perf, max_perf,
- cpudata->cpu, (value != prev), fast_switch);
+ if (trace_amd_pstate_perf_enabled() && amd_pstate_sample(cpudata)) {
+ trace_amd_pstate_perf(min_perf, des_perf, max_perf, cpudata->freq,
+ cpudata->cur.mperf, cpudata->cur.aperf, cpudata->cur.tsc,
+ cpudata->cpu, (value != prev), fast_switch);
+ }
if (value == prev)
return;
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index b8d95536ee22..80f535cc8a75 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -1518,6 +1518,10 @@ static int cpufreq_online(unsigned int cpu)
kobject_uevent(&policy->kobj, KOBJ_ADD);
+ /* Callback for handling stuff after policy is ready */
+ if (cpufreq_driver->ready)
+ cpufreq_driver->ready(policy);
+
if (cpufreq_thermal_control_enabled(cpufreq_driver))
policy->cdev = of_cpufreq_cooling_register(policy);
diff --git a/drivers/cpufreq/cpufreq_conservative.c b/drivers/cpufreq/cpufreq_conservative.c
index 08515f7e515f..b6bd0ff35323 100644
--- a/drivers/cpufreq/cpufreq_conservative.c
+++ b/drivers/cpufreq/cpufreq_conservative.c
@@ -146,7 +146,7 @@ static unsigned int cs_dbs_update(struct cpufreq_policy *policy)
/************************** sysfs interface ************************/
-static ssize_t store_sampling_down_factor(struct gov_attr_set *attr_set,
+static ssize_t sampling_down_factor_store(struct gov_attr_set *attr_set,
const char *buf, size_t count)
{
struct dbs_data *dbs_data = to_dbs_data(attr_set);
@@ -161,7 +161,7 @@ static ssize_t store_sampling_down_factor(struct gov_attr_set *attr_set,
return count;
}
-static ssize_t store_up_threshold(struct gov_attr_set *attr_set,
+static ssize_t up_threshold_store(struct gov_attr_set *attr_set,
const char *buf, size_t count)
{
struct dbs_data *dbs_data = to_dbs_data(attr_set);
@@ -177,7 +177,7 @@ static ssize_t store_up_threshold(struct gov_attr_set *attr_set,
return count;
}
-static ssize_t store_down_threshold(struct gov_attr_set *attr_set,
+static ssize_t down_threshold_store(struct gov_attr_set *attr_set,
const char *buf, size_t count)
{
struct dbs_data *dbs_data = to_dbs_data(attr_set);
@@ -195,7 +195,7 @@ static ssize_t store_down_threshold(struct gov_attr_set *attr_set,
return count;
}
-static ssize_t store_ignore_nice_load(struct gov_attr_set *attr_set,
+static ssize_t ignore_nice_load_store(struct gov_attr_set *attr_set,
const char *buf, size_t count)
{
struct dbs_data *dbs_data = to_dbs_data(attr_set);
@@ -220,7 +220,7 @@ static ssize_t store_ignore_nice_load(struct gov_attr_set *attr_set,
return count;
}
-static ssize_t store_freq_step(struct gov_attr_set *attr_set, const char *buf,
+static ssize_t freq_step_store(struct gov_attr_set *attr_set, const char *buf,
size_t count)
{
struct dbs_data *dbs_data = to_dbs_data(attr_set);
diff --git a/drivers/cpufreq/cpufreq_governor.c b/drivers/cpufreq/cpufreq_governor.c
index 63f7c219062b..0d42cf8b88d8 100644
--- a/drivers/cpufreq/cpufreq_governor.c
+++ b/drivers/cpufreq/cpufreq_governor.c
@@ -27,7 +27,7 @@ static DEFINE_MUTEX(gov_dbs_data_mutex);
/* Common sysfs tunables */
/*
- * store_sampling_rate - update sampling rate effective immediately if needed.
+ * sampling_rate_store - update sampling rate effective immediately if needed.
*
* If new rate is smaller than the old, simply updating
* dbs.sampling_rate might not be appropriate. For example, if the
@@ -41,7 +41,7 @@ static DEFINE_MUTEX(gov_dbs_data_mutex);
* This must be called with dbs_data->mutex held, otherwise traversing
* policy_dbs_list isn't safe.
*/
-ssize_t store_sampling_rate(struct gov_attr_set *attr_set, const char *buf,
+ssize_t sampling_rate_store(struct gov_attr_set *attr_set, const char *buf,
size_t count)
{
struct dbs_data *dbs_data = to_dbs_data(attr_set);
@@ -80,7 +80,7 @@ ssize_t store_sampling_rate(struct gov_attr_set *attr_set, const char *buf,
return count;
}
-EXPORT_SYMBOL_GPL(store_sampling_rate);
+EXPORT_SYMBOL_GPL(sampling_rate_store);
/**
* gov_update_cpu_data - Update CPU load data.
diff --git a/drivers/cpufreq/cpufreq_governor.h b/drivers/cpufreq/cpufreq_governor.h
index bab8e6140377..a5a0bc3cc23e 100644
--- a/drivers/cpufreq/cpufreq_governor.h
+++ b/drivers/cpufreq/cpufreq_governor.h
@@ -51,7 +51,7 @@ static inline struct dbs_data *to_dbs_data(struct gov_attr_set *attr_set)
}
#define gov_show_one(_gov, file_name) \
-static ssize_t show_##file_name \
+static ssize_t file_name##_show \
(struct gov_attr_set *attr_set, char *buf) \
{ \
struct dbs_data *dbs_data = to_dbs_data(attr_set); \
@@ -60,7 +60,7 @@ static ssize_t show_##file_name \
}
#define gov_show_one_common(file_name) \
-static ssize_t show_##file_name \
+static ssize_t file_name##_show \
(struct gov_attr_set *attr_set, char *buf) \
{ \
struct dbs_data *dbs_data = to_dbs_data(attr_set); \
@@ -68,12 +68,10 @@ static ssize_t show_##file_name \
}
#define gov_attr_ro(_name) \
-static struct governor_attr _name = \
-__ATTR(_name, 0444, show_##_name, NULL)
+static struct governor_attr _name = __ATTR_RO(_name)
#define gov_attr_rw(_name) \
-static struct governor_attr _name = \
-__ATTR(_name, 0644, show_##_name, store_##_name)
+static struct governor_attr _name = __ATTR_RW(_name)
/* Common to all CPUs of a policy */
struct policy_dbs_info {
@@ -176,7 +174,7 @@ void od_register_powersave_bias_handler(unsigned int (*f)
(struct cpufreq_policy *, unsigned int, unsigned int),
unsigned int powersave_bias);
void od_unregister_powersave_bias_handler(void);
-ssize_t store_sampling_rate(struct gov_attr_set *attr_set, const char *buf,
+ssize_t sampling_rate_store(struct gov_attr_set *attr_set, const char *buf,
size_t count);
void gov_update_cpu_data(struct dbs_data *dbs_data);
#endif /* _CPUFREQ_GOVERNOR_H */
diff --git a/drivers/cpufreq/cpufreq_governor_attr_set.c b/drivers/cpufreq/cpufreq_governor_attr_set.c
index a6f365b9cc1a..771770ea0ed0 100644
--- a/drivers/cpufreq/cpufreq_governor_attr_set.c
+++ b/drivers/cpufreq/cpufreq_governor_attr_set.c
@@ -8,11 +8,6 @@
#include "cpufreq_governor.h"
-static inline struct gov_attr_set *to_gov_attr_set(struct kobject *kobj)
-{
- return container_of(kobj, struct gov_attr_set, kobj);
-}
-
static inline struct governor_attr *to_gov_attr(struct attribute *attr)
{
return container_of(attr, struct governor_attr, attr);
diff --git a/drivers/cpufreq/cpufreq_ondemand.c b/drivers/cpufreq/cpufreq_ondemand.c
index 6a41ea4729b8..e8fbf970ff07 100644
--- a/drivers/cpufreq/cpufreq_ondemand.c
+++ b/drivers/cpufreq/cpufreq_ondemand.c
@@ -202,7 +202,7 @@ static unsigned int od_dbs_update(struct cpufreq_policy *policy)
/************************** sysfs interface ************************/
static struct dbs_governor od_dbs_gov;
-static ssize_t store_io_is_busy(struct gov_attr_set *attr_set, const char *buf,
+static ssize_t io_is_busy_store(struct gov_attr_set *attr_set, const char *buf,
size_t count)
{
struct dbs_data *dbs_data = to_dbs_data(attr_set);
@@ -220,7 +220,7 @@ static ssize_t store_io_is_busy(struct gov_attr_set *attr_set, const char *buf,
return count;
}
-static ssize_t store_up_threshold(struct gov_attr_set *attr_set,
+static ssize_t up_threshold_store(struct gov_attr_set *attr_set,
const char *buf, size_t count)
{
struct dbs_data *dbs_data = to_dbs_data(attr_set);
@@ -237,7 +237,7 @@ static ssize_t store_up_threshold(struct gov_attr_set *attr_set,
return count;
}
-static ssize_t store_sampling_down_factor(struct gov_attr_set *attr_set,
+static ssize_t sampling_down_factor_store(struct gov_attr_set *attr_set,
const char *buf, size_t count)
{
struct dbs_data *dbs_data = to_dbs_data(attr_set);
@@ -265,7 +265,7 @@ static ssize_t store_sampling_down_factor(struct gov_attr_set *attr_set,
return count;
}
-static ssize_t store_ignore_nice_load(struct gov_attr_set *attr_set,
+static ssize_t ignore_nice_load_store(struct gov_attr_set *attr_set,
const char *buf, size_t count)
{
struct dbs_data *dbs_data = to_dbs_data(attr_set);
@@ -290,7 +290,7 @@ static ssize_t store_ignore_nice_load(struct gov_attr_set *attr_set,
return count;
}
-static ssize_t store_powersave_bias(struct gov_attr_set *attr_set,
+static ssize_t powersave_bias_store(struct gov_attr_set *attr_set,
const char *buf, size_t count)
{
struct dbs_data *dbs_data = to_dbs_data(attr_set);
diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c
index bc7f7e6759bd..846bb3a78788 100644
--- a/drivers/cpufreq/intel_pstate.c
+++ b/drivers/cpufreq/intel_pstate.c
@@ -1692,6 +1692,37 @@ static void intel_pstate_enable_hwp_interrupt(struct cpudata *cpudata)
}
}
+static void intel_pstate_update_epp_defaults(struct cpudata *cpudata)
+{
+ cpudata->epp_default = intel_pstate_get_epp(cpudata, 0);
+
+ /*
+ * If this CPU gen doesn't call for change in balance_perf
+ * EPP return.
+ */
+ if (epp_values[EPP_INDEX_BALANCE_PERFORMANCE] == HWP_EPP_BALANCE_PERFORMANCE)
+ return;
+
+ /*
+ * If powerup EPP is something other than chipset default 0x80 and
+ * - is more performance oriented than 0x80 (default balance_perf EPP)
+ * - But less performance oriented than performance EPP
+ * then use this as new balance_perf EPP.
+ */
+ if (cpudata->epp_default < HWP_EPP_BALANCE_PERFORMANCE &&
+ cpudata->epp_default > HWP_EPP_PERFORMANCE) {
+ epp_values[EPP_INDEX_BALANCE_PERFORMANCE] = cpudata->epp_default;
+ return;
+ }
+
+ /*
+ * Use hard coded value per gen to update the balance_perf
+ * and default EPP.
+ */
+ cpudata->epp_default = epp_values[EPP_INDEX_BALANCE_PERFORMANCE];
+ intel_pstate_set_epp(cpudata, cpudata->epp_default);
+}
+
static void intel_pstate_hwp_enable(struct cpudata *cpudata)
{
/* First disable HWP notification interrupt till we activate again */
@@ -1705,12 +1736,7 @@ static void intel_pstate_hwp_enable(struct cpudata *cpudata)
if (cpudata->epp_default >= 0)
return;
- if (epp_values[EPP_INDEX_BALANCE_PERFORMANCE] == HWP_EPP_BALANCE_PERFORMANCE) {
- cpudata->epp_default = intel_pstate_get_epp(cpudata, 0);
- } else {
- cpudata->epp_default = epp_values[EPP_INDEX_BALANCE_PERFORMANCE];
- intel_pstate_set_epp(cpudata, cpudata->epp_default);
- }
+ intel_pstate_update_epp_defaults(cpudata);
}
static int atom_get_min_pstate(void)
diff --git a/drivers/cpufreq/longhaul.c b/drivers/cpufreq/longhaul.c
index c538a153ee82..3e000e1a75c6 100644
--- a/drivers/cpufreq/longhaul.c
+++ b/drivers/cpufreq/longhaul.c
@@ -668,9 +668,9 @@ static acpi_status longhaul_walk_callback(acpi_handle obj_handle,
u32 nesting_level,
void *context, void **return_value)
{
- struct acpi_device *d;
+ struct acpi_device *d = acpi_fetch_acpi_dev(obj_handle);
- if (acpi_bus_get_device(obj_handle, &d))
+ if (!d)
return 0;
*return_value = acpi_driver_data(d);
diff --git a/drivers/cpufreq/powernow-k8.c b/drivers/cpufreq/powernow-k8.c
index 12ab4014af71..d289036beff2 100644
--- a/drivers/cpufreq/powernow-k8.c
+++ b/drivers/cpufreq/powernow-k8.c
@@ -1172,14 +1172,14 @@ static int powernowk8_init(void)
unsigned int i, supported_cpus = 0;
int ret;
+ if (!x86_match_cpu(powernow_k8_ids))
+ return -ENODEV;
+
if (boot_cpu_has(X86_FEATURE_HW_PSTATE)) {
__request_acpi_cpufreq();
return -ENODEV;
}
- if (!x86_match_cpu(powernow_k8_ids))
- return -ENODEV;
-
cpus_read_lock();
for_each_online_cpu(i) {
smp_call_function_single(i, check_supported_cpu, &ret, 1);
diff --git a/drivers/cpufreq/qcom-cpufreq-hw.c b/drivers/cpufreq/qcom-cpufreq-hw.c
index 05f3d7876e44..effbb680b453 100644
--- a/drivers/cpufreq/qcom-cpufreq-hw.c
+++ b/drivers/cpufreq/qcom-cpufreq-hw.c
@@ -388,7 +388,7 @@ static int qcom_cpufreq_hw_lmh_init(struct cpufreq_policy *policy, int index)
snprintf(data->irq_name, sizeof(data->irq_name), "dcvsh-irq-%u", policy->cpu);
ret = request_threaded_irq(data->throttle_irq, NULL, qcom_lmh_dcvs_handle_irq,
- IRQF_ONESHOT, data->irq_name, data);
+ IRQF_ONESHOT | IRQF_NO_AUTOEN, data->irq_name, data);
if (ret) {
dev_err(&pdev->dev, "Error registering %s: %d\n", data->irq_name, ret);
return 0;
@@ -542,6 +542,14 @@ static int qcom_cpufreq_hw_cpu_exit(struct cpufreq_policy *policy)
return 0;
}
+static void qcom_cpufreq_ready(struct cpufreq_policy *policy)
+{
+ struct qcom_cpufreq_data *data = policy->driver_data;
+
+ if (data->throttle_irq >= 0)
+ enable_irq(data->throttle_irq);
+}
+
static struct freq_attr *qcom_cpufreq_hw_attr[] = {
&cpufreq_freq_attr_scaling_available_freqs,
&cpufreq_freq_attr_scaling_boost_freqs,
@@ -561,6 +569,7 @@ static struct cpufreq_driver cpufreq_qcom_hw_driver = {
.fast_switch = qcom_cpufreq_hw_fast_switch,
.name = "qcom-cpufreq-hw",
.attr = qcom_cpufreq_hw_attr,
+ .ready = qcom_cpufreq_ready,
};
static int qcom_cpufreq_hw_driver_probe(struct platform_device *pdev)
diff --git a/drivers/cpuidle/cpuidle-haltpoll.c b/drivers/cpuidle/cpuidle-haltpoll.c
index fcc53215bac8..3a39a7f48b77 100644
--- a/drivers/cpuidle/cpuidle-haltpoll.c
+++ b/drivers/cpuidle/cpuidle-haltpoll.c
@@ -108,11 +108,11 @@ static int __init haltpoll_init(void)
if (boot_option_idle_override != IDLE_NO_OVERRIDE)
return -ENODEV;
- cpuidle_poll_state_init(drv);
-
if (!kvm_para_available() || !haltpoll_want())
return -ENODEV;
+ cpuidle_poll_state_init(drv);
+
ret = cpuidle_register_driver(drv);
if (ret < 0)
return ret;
diff --git a/drivers/cpuidle/cpuidle-qcom-spm.c b/drivers/cpuidle/cpuidle-qcom-spm.c
index 01e77913a414..beedf22cbe78 100644
--- a/drivers/cpuidle/cpuidle-qcom-spm.c
+++ b/drivers/cpuidle/cpuidle-qcom-spm.c
@@ -122,10 +122,6 @@ static int spm_cpuidle_register(struct device *cpuidle_dev, int cpu)
if (ret <= 0)
return ret ? : -ENODEV;
- ret = qcom_scm_set_warm_boot_addr(cpu_resume_arm, cpumask_of(cpu));
- if (ret)
- return ret;
-
return cpuidle_register(&data->cpuidle_driver, NULL);
}
@@ -136,6 +132,10 @@ static int spm_cpuidle_drv_probe(struct platform_device *pdev)
if (!qcom_scm_is_available())
return -EPROBE_DEFER;
+ ret = qcom_scm_set_warm_boot_addr(cpu_resume_arm);
+ if (ret)
+ return dev_err_probe(&pdev->dev, ret, "set warm boot addr failed");
+
for_each_possible_cpu(cpu) {
ret = spm_cpuidle_register(&pdev->dev, cpu);
if (ret && ret != -ENODEV) {
@@ -155,6 +155,22 @@ static struct platform_driver spm_cpuidle_driver = {
},
};
+static bool __init qcom_spm_find_any_cpu(void)
+{
+ struct device_node *cpu_node, *saw_node;
+
+ for_each_of_cpu_node(cpu_node) {
+ saw_node = of_parse_phandle(cpu_node, "qcom,saw", 0);
+ if (of_device_is_available(saw_node)) {
+ of_node_put(saw_node);
+ of_node_put(cpu_node);
+ return true;
+ }
+ of_node_put(saw_node);
+ }
+ return false;
+}
+
static int __init qcom_spm_cpuidle_init(void)
{
struct platform_device *pdev;
@@ -164,6 +180,10 @@ static int __init qcom_spm_cpuidle_init(void)
if (ret)
return ret;
+ /* Make sure there is actually any CPU managed by the SPM */
+ if (!qcom_spm_find_any_cpu())
+ return 0;
+
pdev = platform_device_register_simple("qcom-spm-cpuidle",
-1, NULL, 0);
if (IS_ERR(pdev)) {
diff --git a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig
index 4f705674f94f..7b2d138bc83e 100644
--- a/drivers/crypto/Kconfig
+++ b/drivers/crypto/Kconfig
@@ -808,6 +808,16 @@ config CRYPTO_DEV_ZYNQMP_AES
accelerator. Select this if you want to use the ZynqMP module
for AES algorithms.
+config CRYPTO_DEV_ZYNQMP_SHA3
+ tristate "Support for Xilinx ZynqMP SHA3 hardware accelerator"
+ depends on ZYNQMP_FIRMWARE || COMPILE_TEST
+ select CRYPTO_SHA3
+ help
+ Xilinx ZynqMP has SHA3 engine used for secure hash calculation.
+ This driver interfaces with SHA3 hardware engine.
+ Select this if you want to use the ZynqMP module
+ for SHA3 hash computation.
+
source "drivers/crypto/chelsio/Kconfig"
source "drivers/crypto/virtio/Kconfig"
diff --git a/drivers/crypto/Makefile b/drivers/crypto/Makefile
index 1fe5120eb966..0a4fff23d272 100644
--- a/drivers/crypto/Makefile
+++ b/drivers/crypto/Makefile
@@ -47,7 +47,7 @@ obj-$(CONFIG_CRYPTO_DEV_VMX) += vmx/
obj-$(CONFIG_CRYPTO_DEV_BCM_SPU) += bcm/
obj-$(CONFIG_CRYPTO_DEV_SAFEXCEL) += inside-secure/
obj-$(CONFIG_CRYPTO_DEV_ARTPEC6) += axis/
-obj-$(CONFIG_CRYPTO_DEV_ZYNQMP_AES) += xilinx/
+obj-y += xilinx/
obj-y += hisilicon/
obj-$(CONFIG_CRYPTO_DEV_AMLOGIC_GXL) += amlogic/
obj-y += keembay/
diff --git a/drivers/crypto/allwinner/sun8i-ce/sun8i-ce-cipher.c b/drivers/crypto/allwinner/sun8i-ce/sun8i-ce-cipher.c
index 54ae8d16e493..35e3cadccac2 100644
--- a/drivers/crypto/allwinner/sun8i-ce/sun8i-ce-cipher.c
+++ b/drivers/crypto/allwinner/sun8i-ce/sun8i-ce-cipher.c
@@ -11,6 +11,7 @@
* You could find a link for the datasheet in Documentation/arm/sunxi.rst
*/
+#include <linux/bottom_half.h>
#include <linux/crypto.h>
#include <linux/dma-mapping.h>
#include <linux/io.h>
@@ -283,7 +284,9 @@ static int sun8i_ce_cipher_run(struct crypto_engine *engine, void *areq)
flow = rctx->flow;
err = sun8i_ce_run_task(ce, flow, crypto_tfm_alg_name(breq->base.tfm));
+ local_bh_disable();
crypto_finalize_skcipher_request(engine, breq, err);
+ local_bh_enable();
return 0;
}
diff --git a/drivers/crypto/allwinner/sun8i-ce/sun8i-ce-hash.c b/drivers/crypto/allwinner/sun8i-ce/sun8i-ce-hash.c
index 88194718a806..859b7522faaa 100644
--- a/drivers/crypto/allwinner/sun8i-ce/sun8i-ce-hash.c
+++ b/drivers/crypto/allwinner/sun8i-ce/sun8i-ce-hash.c
@@ -9,6 +9,7 @@
*
* You could find the datasheet in Documentation/arm/sunxi.rst
*/
+#include <linux/bottom_half.h>
#include <linux/dma-mapping.h>
#include <linux/pm_runtime.h>
#include <linux/scatterlist.h>
@@ -414,6 +415,8 @@ int sun8i_ce_hash_run(struct crypto_engine *engine, void *breq)
theend:
kfree(buf);
kfree(result);
+ local_bh_disable();
crypto_finalize_hash_request(engine, breq, err);
+ local_bh_enable();
return 0;
}
diff --git a/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-cipher.c b/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-cipher.c
index 9ef1c85c4aaa..554e400d41ca 100644
--- a/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-cipher.c
+++ b/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-cipher.c
@@ -11,6 +11,7 @@
* You could find a link for the datasheet in Documentation/arm/sunxi.rst
*/
+#include <linux/bottom_half.h>
#include <linux/crypto.h>
#include <linux/dma-mapping.h>
#include <linux/io.h>
@@ -274,7 +275,9 @@ static int sun8i_ss_handle_cipher_request(struct crypto_engine *engine, void *ar
struct skcipher_request *breq = container_of(areq, struct skcipher_request, base);
err = sun8i_ss_cipher(breq);
+ local_bh_disable();
crypto_finalize_skcipher_request(engine, breq, err);
+ local_bh_enable();
return 0;
}
diff --git a/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-core.c b/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-core.c
index 80e89066dbd1..319fe3279a71 100644
--- a/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-core.c
+++ b/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-core.c
@@ -30,6 +30,8 @@
static const struct ss_variant ss_a80_variant = {
.alg_cipher = { SS_ALG_AES, SS_ALG_DES, SS_ALG_3DES,
},
+ .alg_hash = { SS_ID_NOTSUPP, SS_ID_NOTSUPP, SS_ID_NOTSUPP, SS_ID_NOTSUPP,
+ },
.op_mode = { SS_OP_ECB, SS_OP_CBC,
},
.ss_clks = {
diff --git a/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-hash.c b/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-hash.c
index 3c073eb3db03..1a71ed49d233 100644
--- a/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-hash.c
+++ b/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-hash.c
@@ -9,6 +9,7 @@
*
* You could find the datasheet in Documentation/arm/sunxi.rst
*/
+#include <linux/bottom_half.h>
#include <linux/dma-mapping.h>
#include <linux/pm_runtime.h>
#include <linux/scatterlist.h>
@@ -442,6 +443,8 @@ int sun8i_ss_hash_run(struct crypto_engine *engine, void *breq)
theend:
kfree(pad);
kfree(result);
+ local_bh_disable();
crypto_finalize_hash_request(engine, breq, err);
+ local_bh_enable();
return 0;
}
diff --git a/drivers/crypto/amlogic/amlogic-gxl-cipher.c b/drivers/crypto/amlogic/amlogic-gxl-cipher.c
index c6865cbd334b..e79514fce731 100644
--- a/drivers/crypto/amlogic/amlogic-gxl-cipher.c
+++ b/drivers/crypto/amlogic/amlogic-gxl-cipher.c
@@ -265,7 +265,9 @@ static int meson_handle_cipher_request(struct crypto_engine *engine,
struct skcipher_request *breq = container_of(areq, struct skcipher_request, base);
err = meson_cipher(breq);
+ local_bh_disable();
crypto_finalize_skcipher_request(engine, breq, err);
+ local_bh_enable();
return 0;
}
diff --git a/drivers/crypto/atmel-aes.c b/drivers/crypto/atmel-aes.c
index fe0558403191..f72c6b3e4ad8 100644
--- a/drivers/crypto/atmel-aes.c
+++ b/drivers/crypto/atmel-aes.c
@@ -2509,6 +2509,7 @@ static void atmel_aes_get_cap(struct atmel_aes_dev *dd)
/* keep only major version number */
switch (dd->hw_version & 0xff0) {
+ case 0x700:
case 0x500:
dd->caps.has_dualbuff = 1;
dd->caps.has_cfb64 = 1;
diff --git a/drivers/crypto/atmel-sha.c b/drivers/crypto/atmel-sha.c
index 1b13f601fd95..d1628112dacc 100644
--- a/drivers/crypto/atmel-sha.c
+++ b/drivers/crypto/atmel-sha.c
@@ -2508,6 +2508,7 @@ static void atmel_sha_get_cap(struct atmel_sha_dev *dd)
/* keep only major version number */
switch (dd->hw_version & 0xff0) {
+ case 0x700:
case 0x510:
dd->caps.has_dma = 1;
dd->caps.has_dualbuff = 1;
diff --git a/drivers/crypto/atmel-tdes.c b/drivers/crypto/atmel-tdes.c
index e30786ec9f2d..9fd7b8e439d2 100644
--- a/drivers/crypto/atmel-tdes.c
+++ b/drivers/crypto/atmel-tdes.c
@@ -1130,6 +1130,7 @@ static void atmel_tdes_get_cap(struct atmel_tdes_dev *dd)
/* keep only major version number */
switch (dd->hw_version & 0xf00) {
+ case 0x800:
case 0x700:
dd->caps.has_dma = 1;
dd->caps.has_cfb_3keys = 1;
diff --git a/drivers/crypto/caam/pdb.h b/drivers/crypto/caam/pdb.h
index 8ccc22075043..4b1bcf53f7ac 100644
--- a/drivers/crypto/caam/pdb.h
+++ b/drivers/crypto/caam/pdb.h
@@ -144,7 +144,7 @@ struct ipsec_encap_pdb {
};
u32 spi;
u32 ip_hdr_len;
- u32 ip_hdr[0];
+ u32 ip_hdr[];
};
/**
diff --git a/drivers/crypto/cavium/nitrox/nitrox_mbx.c b/drivers/crypto/cavium/nitrox/nitrox_mbx.c
index 2e9c0d214363..9e7308e39b30 100644
--- a/drivers/crypto/cavium/nitrox/nitrox_mbx.c
+++ b/drivers/crypto/cavium/nitrox/nitrox_mbx.c
@@ -1,4 +1,5 @@
// SPDX-License-Identifier: GPL-2.0
+#include <linux/bitmap.h>
#include <linux/workqueue.h>
#include "nitrox_csr.h"
@@ -120,6 +121,7 @@ static void pf2vf_resp_handler(struct work_struct *work)
void nitrox_pf2vf_mbox_handler(struct nitrox_device *ndev)
{
+ DECLARE_BITMAP(csr, BITS_PER_TYPE(u64));
struct nitrox_vfdev *vfdev;
struct pf2vf_work *pfwork;
u64 value, reg_addr;
@@ -129,7 +131,8 @@ void nitrox_pf2vf_mbox_handler(struct nitrox_device *ndev)
/* loop for VF(0..63) */
reg_addr = NPS_PKT_MBOX_INT_LO;
value = nitrox_read_csr(ndev, reg_addr);
- for_each_set_bit(i, (const unsigned long *)&value, BITS_PER_LONG) {
+ bitmap_from_u64(csr, value);
+ for_each_set_bit(i, csr, BITS_PER_TYPE(csr)) {
/* get the vfno from ring */
vfno = RING_TO_VFNO(i, ndev->iov.max_vf_queues);
vfdev = ndev->iov.vfdev + vfno;
@@ -151,7 +154,8 @@ void nitrox_pf2vf_mbox_handler(struct nitrox_device *ndev)
/* loop for VF(64..127) */
reg_addr = NPS_PKT_MBOX_INT_HI;
value = nitrox_read_csr(ndev, reg_addr);
- for_each_set_bit(i, (const unsigned long *)&value, BITS_PER_LONG) {
+ bitmap_from_u64(csr, value);
+ for_each_set_bit(i, csr, BITS_PER_TYPE(csr)) {
/* get the vfno from ring */
vfno = RING_TO_VFNO(i + 64, ndev->iov.max_vf_queues);
vfdev = ndev->iov.vfdev + vfno;
diff --git a/drivers/crypto/cavium/nitrox/nitrox_req.h b/drivers/crypto/cavium/nitrox/nitrox_req.h
index ed174883c8e3..6bf088bcdd11 100644
--- a/drivers/crypto/cavium/nitrox/nitrox_req.h
+++ b/drivers/crypto/cavium/nitrox/nitrox_req.h
@@ -440,7 +440,7 @@ struct aqmq_command_s {
/**
* struct ctx_hdr - Book keeping data about the crypto context
* @pool: Pool used to allocate crypto context
- * @dma: Base DMA address of the cypto context
+ * @dma: Base DMA address of the crypto context
* @ctx_dma: Actual usable crypto context for NITROX
*/
struct ctx_hdr {
diff --git a/drivers/crypto/cavium/zip/zip_main.c b/drivers/crypto/cavium/zip/zip_main.c
index 812b4ac9afd6..dc5b7bf7e1fd 100644
--- a/drivers/crypto/cavium/zip/zip_main.c
+++ b/drivers/crypto/cavium/zip/zip_main.c
@@ -55,6 +55,11 @@ static const struct pci_device_id zip_id_table[] = {
{ 0, }
};
+static void zip_debugfs_init(void);
+static void zip_debugfs_exit(void);
+static int zip_register_compression_device(void);
+static void zip_unregister_compression_device(void);
+
void zip_reg_write(u64 val, u64 __iomem *addr)
{
writeq(val, addr);
@@ -235,6 +240,15 @@ static int zip_init_hw(struct zip_device *zip)
return 0;
}
+static void zip_reset(struct zip_device *zip)
+{
+ union zip_cmd_ctl cmd_ctl;
+
+ cmd_ctl.u_reg64 = 0x0ull;
+ cmd_ctl.s.reset = 1; /* Forces ZIP cores to do reset */
+ zip_reg_write(cmd_ctl.u_reg64, (zip->reg_base + ZIP_CMD_CTL));
+}
+
static int zip_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
{
struct device *dev = &pdev->dev;
@@ -282,8 +296,21 @@ static int zip_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
if (err)
goto err_release_regions;
+ /* Register with the Kernel Crypto Interface */
+ err = zip_register_compression_device();
+ if (err < 0) {
+ zip_err("ZIP: Kernel Crypto Registration failed\n");
+ goto err_register;
+ }
+
+ /* comp-decomp statistics are handled with debugfs interface */
+ zip_debugfs_init();
+
return 0;
+err_register:
+ zip_reset(zip);
+
err_release_regions:
if (zip->reg_base)
iounmap(zip->reg_base);
@@ -305,16 +332,17 @@ err_free_device:
static void zip_remove(struct pci_dev *pdev)
{
struct zip_device *zip = pci_get_drvdata(pdev);
- union zip_cmd_ctl cmd_ctl;
int q = 0;
if (!zip)
return;
+ zip_debugfs_exit();
+
+ zip_unregister_compression_device();
+
if (zip->reg_base) {
- cmd_ctl.u_reg64 = 0x0ull;
- cmd_ctl.s.reset = 1; /* Forces ZIP cores to do reset */
- zip_reg_write(cmd_ctl.u_reg64, (zip->reg_base + ZIP_CMD_CTL));
+ zip_reset(zip);
iounmap(zip->reg_base);
}
@@ -585,7 +613,7 @@ DEFINE_SHOW_ATTRIBUTE(zip_regs);
/* Root directory for thunderx_zip debugfs entry */
static struct dentry *zip_debugfs_root;
-static void __init zip_debugfs_init(void)
+static void zip_debugfs_init(void)
{
if (!debugfs_initialized())
return;
@@ -604,7 +632,7 @@ static void __init zip_debugfs_init(void)
}
-static void __exit zip_debugfs_exit(void)
+static void zip_debugfs_exit(void)
{
debugfs_remove_recursive(zip_debugfs_root);
}
@@ -615,48 +643,7 @@ static void __exit zip_debugfs_exit(void) { }
#endif
/* debugfs - end */
-static int __init zip_init_module(void)
-{
- int ret;
-
- zip_msg("%s\n", DRV_NAME);
-
- ret = pci_register_driver(&zip_driver);
- if (ret < 0) {
- zip_err("ZIP: pci_register_driver() failed\n");
- return ret;
- }
-
- /* Register with the Kernel Crypto Interface */
- ret = zip_register_compression_device();
- if (ret < 0) {
- zip_err("ZIP: Kernel Crypto Registration failed\n");
- goto err_pci_unregister;
- }
-
- /* comp-decomp statistics are handled with debugfs interface */
- zip_debugfs_init();
-
- return ret;
-
-err_pci_unregister:
- pci_unregister_driver(&zip_driver);
- return ret;
-}
-
-static void __exit zip_cleanup_module(void)
-{
- zip_debugfs_exit();
-
- /* Unregister from the kernel crypto interface */
- zip_unregister_compression_device();
-
- /* Unregister this driver for pci zip devices */
- pci_unregister_driver(&zip_driver);
-}
-
-module_init(zip_init_module);
-module_exit(zip_cleanup_module);
+module_pci_driver(zip_driver);
MODULE_AUTHOR("Cavium Inc");
MODULE_DESCRIPTION("Cavium Inc ThunderX ZIP Driver");
diff --git a/drivers/crypto/ccp/ccp-crypto-aes.c b/drivers/crypto/ccp/ccp-crypto-aes.c
index e6dcd8cedd53..bed331953ff9 100644
--- a/drivers/crypto/ccp/ccp-crypto-aes.c
+++ b/drivers/crypto/ccp/ccp-crypto-aes.c
@@ -69,7 +69,6 @@ static int ccp_aes_crypt(struct skcipher_request *req, bool encrypt)
struct ccp_aes_req_ctx *rctx = skcipher_request_ctx(req);
struct scatterlist *iv_sg = NULL;
unsigned int iv_len = 0;
- int ret;
if (!ctx->u.aes.key_len)
return -EINVAL;
@@ -104,9 +103,7 @@ static int ccp_aes_crypt(struct skcipher_request *req, bool encrypt)
rctx->cmd.u.aes.src_len = req->cryptlen;
rctx->cmd.u.aes.dst = req->dst;
- ret = ccp_crypto_enqueue_request(&req->base, &rctx->cmd);
-
- return ret;
+ return ccp_crypto_enqueue_request(&req->base, &rctx->cmd);
}
static int ccp_aes_encrypt(struct skcipher_request *req)
diff --git a/drivers/crypto/ccp/ccp-dmaengine.c b/drivers/crypto/ccp/ccp-dmaengine.c
index d718db224be4..7d4b4ad1db1f 100644
--- a/drivers/crypto/ccp/ccp-dmaengine.c
+++ b/drivers/crypto/ccp/ccp-dmaengine.c
@@ -632,6 +632,20 @@ static int ccp_terminate_all(struct dma_chan *dma_chan)
return 0;
}
+static void ccp_dma_release(struct ccp_device *ccp)
+{
+ struct ccp_dma_chan *chan;
+ struct dma_chan *dma_chan;
+ unsigned int i;
+
+ for (i = 0; i < ccp->cmd_q_count; i++) {
+ chan = ccp->ccp_dma_chan + i;
+ dma_chan = &chan->dma_chan;
+ tasklet_kill(&chan->cleanup_tasklet);
+ list_del_rcu(&dma_chan->device_node);
+ }
+}
+
int ccp_dmaengine_register(struct ccp_device *ccp)
{
struct ccp_dma_chan *chan;
@@ -736,6 +750,7 @@ int ccp_dmaengine_register(struct ccp_device *ccp)
return 0;
err_reg:
+ ccp_dma_release(ccp);
kmem_cache_destroy(ccp->dma_desc_cache);
err_cache:
@@ -752,6 +767,7 @@ void ccp_dmaengine_unregister(struct ccp_device *ccp)
return;
dma_async_device_unregister(dma_dev);
+ ccp_dma_release(ccp);
kmem_cache_destroy(ccp->dma_desc_cache);
kmem_cache_destroy(ccp->dma_cmd_cache);
diff --git a/drivers/crypto/ccp/sev-dev.c b/drivers/crypto/ccp/sev-dev.c
index 8fd774a10edc..6ab93dfd478a 100644
--- a/drivers/crypto/ccp/sev-dev.c
+++ b/drivers/crypto/ccp/sev-dev.c
@@ -413,7 +413,7 @@ static int __sev_platform_init_locked(int *error)
{
struct psp_device *psp = psp_master;
struct sev_device *sev;
- int rc, psp_ret;
+ int rc, psp_ret = -1;
int (*init_function)(int *error);
if (!psp || !psp->sev_data)
diff --git a/drivers/crypto/ccree/cc_buffer_mgr.c b/drivers/crypto/ccree/cc_buffer_mgr.c
index a5e041d9d2cf..11e0278c8631 100644
--- a/drivers/crypto/ccree/cc_buffer_mgr.c
+++ b/drivers/crypto/ccree/cc_buffer_mgr.c
@@ -258,6 +258,13 @@ static int cc_map_sg(struct device *dev, struct scatterlist *sg,
{
int ret = 0;
+ if (!nbytes) {
+ *mapped_nents = 0;
+ *lbytes = 0;
+ *nents = 0;
+ return 0;
+ }
+
*nents = cc_get_sgl_nents(dev, sg, nbytes, lbytes);
if (*nents > max_sg_nents) {
*nents = 0;
diff --git a/drivers/crypto/ccree/cc_cipher.c b/drivers/crypto/ccree/cc_cipher.c
index 78833491f534..309da6334a0a 100644
--- a/drivers/crypto/ccree/cc_cipher.c
+++ b/drivers/crypto/ccree/cc_cipher.c
@@ -257,8 +257,8 @@ static void cc_cipher_exit(struct crypto_tfm *tfm)
&ctx_p->user.key_dma_addr);
/* Free key buffer in context */
- kfree_sensitive(ctx_p->user.key);
dev_dbg(dev, "Free key buffer in context. key=@%p\n", ctx_p->user.key);
+ kfree_sensitive(ctx_p->user.key);
}
struct tdes_keys {
diff --git a/drivers/crypto/gemini/sl3516-ce-cipher.c b/drivers/crypto/gemini/sl3516-ce-cipher.c
index c1c2b1d86663..14d0d83d388d 100644
--- a/drivers/crypto/gemini/sl3516-ce-cipher.c
+++ b/drivers/crypto/gemini/sl3516-ce-cipher.c
@@ -23,8 +23,8 @@ static bool sl3516_ce_need_fallback(struct skcipher_request *areq)
struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(areq);
struct sl3516_ce_cipher_tfm_ctx *op = crypto_skcipher_ctx(tfm);
struct sl3516_ce_dev *ce = op->ce;
- struct scatterlist *in_sg = areq->src;
- struct scatterlist *out_sg = areq->dst;
+ struct scatterlist *in_sg;
+ struct scatterlist *out_sg;
struct scatterlist *sg;
if (areq->cryptlen == 0 || areq->cryptlen % 16) {
@@ -264,7 +264,9 @@ static int sl3516_ce_handle_cipher_request(struct crypto_engine *engine, void *a
struct skcipher_request *breq = container_of(areq, struct skcipher_request, base);
err = sl3516_ce_cipher(breq);
+ local_bh_disable();
crypto_finalize_skcipher_request(engine, breq, err);
+ local_bh_enable();
return 0;
}
diff --git a/drivers/crypto/hisilicon/hpre/hpre.h b/drivers/crypto/hisilicon/hpre/hpre.h
index e0b4a1982ee9..9a0558ed82f9 100644
--- a/drivers/crypto/hisilicon/hpre/hpre.h
+++ b/drivers/crypto/hisilicon/hpre/hpre.h
@@ -4,7 +4,7 @@
#define __HISI_HPRE_H
#include <linux/list.h>
-#include "../qm.h"
+#include <linux/hisi_acc_qm.h>
#define HPRE_SQE_SIZE sizeof(struct hpre_sqe)
#define HPRE_PF_DEF_Q_NUM 64
diff --git a/drivers/crypto/hisilicon/hpre/hpre_main.c b/drivers/crypto/hisilicon/hpre/hpre_main.c
index ebfab3e14499..36ab30e9e654 100644
--- a/drivers/crypto/hisilicon/hpre/hpre_main.c
+++ b/drivers/crypto/hisilicon/hpre/hpre_main.c
@@ -68,8 +68,7 @@
#define HPRE_REG_RD_INTVRL_US 10
#define HPRE_REG_RD_TMOUT_US 1000
#define HPRE_DBGFS_VAL_MAX_LEN 20
-#define HPRE_PCI_DEVICE_ID 0xa258
-#define HPRE_PCI_VF_DEVICE_ID 0xa259
+#define PCI_DEVICE_ID_HUAWEI_HPRE_PF 0xa258
#define HPRE_QM_USR_CFG_MASK GENMASK(31, 1)
#define HPRE_QM_AXI_CFG_MASK GENMASK(15, 0)
#define HPRE_QM_VFG_AX_MASK GENMASK(7, 0)
@@ -111,8 +110,8 @@
static const char hpre_name[] = "hisi_hpre";
static struct dentry *hpre_debugfs_root;
static const struct pci_device_id hpre_dev_ids[] = {
- { PCI_DEVICE(PCI_VENDOR_ID_HUAWEI, HPRE_PCI_DEVICE_ID) },
- { PCI_DEVICE(PCI_VENDOR_ID_HUAWEI, HPRE_PCI_VF_DEVICE_ID) },
+ { PCI_DEVICE(PCI_VENDOR_ID_HUAWEI, PCI_DEVICE_ID_HUAWEI_HPRE_PF) },
+ { PCI_DEVICE(PCI_VENDOR_ID_HUAWEI, PCI_DEVICE_ID_HUAWEI_HPRE_VF) },
{ 0, }
};
@@ -242,7 +241,7 @@ MODULE_PARM_DESC(uacce_mode, UACCE_MODE_DESC);
static int pf_q_num_set(const char *val, const struct kernel_param *kp)
{
- return q_num_set(val, kp, HPRE_PCI_DEVICE_ID);
+ return q_num_set(val, kp, PCI_DEVICE_ID_HUAWEI_HPRE_PF);
}
static const struct kernel_param_ops hpre_pf_q_num_ops = {
@@ -921,7 +920,7 @@ static int hpre_debugfs_init(struct hisi_qm *qm)
qm->debug.sqe_mask_len = HPRE_SQE_MASK_LEN;
hisi_qm_debug_init(qm);
- if (qm->pdev->device == HPRE_PCI_DEVICE_ID) {
+ if (qm->pdev->device == PCI_DEVICE_ID_HUAWEI_HPRE_PF) {
ret = hpre_ctrl_debug_init(qm);
if (ret)
goto failed_to_create;
@@ -958,7 +957,7 @@ static int hpre_qm_init(struct hisi_qm *qm, struct pci_dev *pdev)
qm->sqe_size = HPRE_SQE_SIZE;
qm->dev_name = hpre_name;
- qm->fun_type = (pdev->device == HPRE_PCI_DEVICE_ID) ?
+ qm->fun_type = (pdev->device == PCI_DEVICE_ID_HUAWEI_HPRE_PF) ?
QM_HW_PF : QM_HW_VF;
if (qm->fun_type == QM_HW_PF) {
qm->qp_base = HPRE_PF_DEF_Q_BASE;
@@ -1191,6 +1190,12 @@ static struct pci_driver hpre_pci_driver = {
.driver.pm = &hpre_pm_ops,
};
+struct pci_driver *hisi_hpre_get_pf_driver(void)
+{
+ return &hpre_pci_driver;
+}
+EXPORT_SYMBOL_GPL(hisi_hpre_get_pf_driver);
+
static void hpre_register_debugfs(void)
{
if (!debugfs_initialized())
diff --git a/drivers/crypto/hisilicon/qm.c b/drivers/crypto/hisilicon/qm.c
index c5b84a5ea350..009132333d2b 100644
--- a/drivers/crypto/hisilicon/qm.c
+++ b/drivers/crypto/hisilicon/qm.c
@@ -15,7 +15,7 @@
#include <linux/uacce.h>
#include <linux/uaccess.h>
#include <uapi/misc/uacce/hisi_qm.h>
-#include "qm.h"
+#include <linux/hisi_acc_qm.h>
/* eq/aeq irq enable */
#define QM_VF_AEQ_INT_SOURCE 0x0
@@ -33,23 +33,6 @@
#define QM_ABNORMAL_EVENT_IRQ_VECTOR 3
/* mailbox */
-#define QM_MB_CMD_SQC 0x0
-#define QM_MB_CMD_CQC 0x1
-#define QM_MB_CMD_EQC 0x2
-#define QM_MB_CMD_AEQC 0x3
-#define QM_MB_CMD_SQC_BT 0x4
-#define QM_MB_CMD_CQC_BT 0x5
-#define QM_MB_CMD_SQC_VFT_V2 0x6
-#define QM_MB_CMD_STOP_QP 0x8
-#define QM_MB_CMD_SRC 0xc
-#define QM_MB_CMD_DST 0xd
-
-#define QM_MB_CMD_SEND_BASE 0x300
-#define QM_MB_EVENT_SHIFT 8
-#define QM_MB_BUSY_SHIFT 13
-#define QM_MB_OP_SHIFT 14
-#define QM_MB_CMD_DATA_ADDR_L 0x304
-#define QM_MB_CMD_DATA_ADDR_H 0x308
#define QM_MB_PING_ALL_VFS 0xffff
#define QM_MB_CMD_DATA_SHIFT 32
#define QM_MB_CMD_DATA_MASK GENMASK(31, 0)
@@ -103,19 +86,12 @@
#define QM_DB_CMD_SHIFT_V1 16
#define QM_DB_INDEX_SHIFT_V1 32
#define QM_DB_PRIORITY_SHIFT_V1 48
-#define QM_DOORBELL_SQ_CQ_BASE_V2 0x1000
-#define QM_DOORBELL_EQ_AEQ_BASE_V2 0x2000
#define QM_QUE_ISO_CFG_V 0x0030
#define QM_PAGE_SIZE 0x0034
#define QM_QUE_ISO_EN 0x100154
#define QM_CAPBILITY 0x100158
#define QM_QP_NUN_MASK GENMASK(10, 0)
#define QM_QP_DB_INTERVAL 0x10000
-#define QM_QP_MAX_NUM_SHIFT 11
-#define QM_DB_CMD_SHIFT_V2 12
-#define QM_DB_RAND_SHIFT_V2 16
-#define QM_DB_INDEX_SHIFT_V2 32
-#define QM_DB_PRIORITY_SHIFT_V2 48
#define QM_MEM_START_INIT 0x100040
#define QM_MEM_INIT_DONE 0x100044
@@ -693,7 +669,7 @@ static void qm_mb_pre_init(struct qm_mailbox *mailbox, u8 cmd,
}
/* return 0 mailbox ready, -ETIMEDOUT hardware timeout */
-static int qm_wait_mb_ready(struct hisi_qm *qm)
+int hisi_qm_wait_mb_ready(struct hisi_qm *qm)
{
u32 val;
@@ -701,6 +677,7 @@ static int qm_wait_mb_ready(struct hisi_qm *qm)
val, !((val >> QM_MB_BUSY_SHIFT) &
0x1), POLL_PERIOD, POLL_TIMEOUT);
}
+EXPORT_SYMBOL_GPL(hisi_qm_wait_mb_ready);
/* 128 bit should be written to hardware at one time to trigger a mailbox */
static void qm_mb_write(struct hisi_qm *qm, const void *src)
@@ -726,14 +703,14 @@ static void qm_mb_write(struct hisi_qm *qm, const void *src)
static int qm_mb_nolock(struct hisi_qm *qm, struct qm_mailbox *mailbox)
{
- if (unlikely(qm_wait_mb_ready(qm))) {
+ if (unlikely(hisi_qm_wait_mb_ready(qm))) {
dev_err(&qm->pdev->dev, "QM mailbox is busy to start!\n");
goto mb_busy;
}
qm_mb_write(qm, mailbox);
- if (unlikely(qm_wait_mb_ready(qm))) {
+ if (unlikely(hisi_qm_wait_mb_ready(qm))) {
dev_err(&qm->pdev->dev, "QM mailbox operation timeout!\n");
goto mb_busy;
}
@@ -745,8 +722,8 @@ mb_busy:
return -EBUSY;
}
-static int qm_mb(struct hisi_qm *qm, u8 cmd, dma_addr_t dma_addr, u16 queue,
- bool op)
+int hisi_qm_mb(struct hisi_qm *qm, u8 cmd, dma_addr_t dma_addr, u16 queue,
+ bool op)
{
struct qm_mailbox mailbox;
int ret;
@@ -762,6 +739,7 @@ static int qm_mb(struct hisi_qm *qm, u8 cmd, dma_addr_t dma_addr, u16 queue,
return ret;
}
+EXPORT_SYMBOL_GPL(hisi_qm_mb);
static void qm_db_v1(struct hisi_qm *qm, u16 qn, u8 cmd, u16 index, u8 priority)
{
@@ -1351,7 +1329,7 @@ static int qm_get_vft_v2(struct hisi_qm *qm, u32 *base, u32 *number)
u64 sqc_vft;
int ret;
- ret = qm_mb(qm, QM_MB_CMD_SQC_VFT_V2, 0, 0, 1);
+ ret = hisi_qm_mb(qm, QM_MB_CMD_SQC_VFT_V2, 0, 0, 1);
if (ret)
return ret;
@@ -1725,12 +1703,12 @@ static int dump_show(struct hisi_qm *qm, void *info,
static int qm_dump_sqc_raw(struct hisi_qm *qm, dma_addr_t dma_addr, u16 qp_id)
{
- return qm_mb(qm, QM_MB_CMD_SQC, dma_addr, qp_id, 1);
+ return hisi_qm_mb(qm, QM_MB_CMD_SQC, dma_addr, qp_id, 1);
}
static int qm_dump_cqc_raw(struct hisi_qm *qm, dma_addr_t dma_addr, u16 qp_id)
{
- return qm_mb(qm, QM_MB_CMD_CQC, dma_addr, qp_id, 1);
+ return hisi_qm_mb(qm, QM_MB_CMD_CQC, dma_addr, qp_id, 1);
}
static int qm_sqc_dump(struct hisi_qm *qm, const char *s)
@@ -1842,7 +1820,7 @@ static int qm_eqc_aeqc_dump(struct hisi_qm *qm, char *s, size_t size,
if (IS_ERR(xeqc))
return PTR_ERR(xeqc);
- ret = qm_mb(qm, cmd, xeqc_dma, 0, 1);
+ ret = hisi_qm_mb(qm, cmd, xeqc_dma, 0, 1);
if (ret)
goto err_free_ctx;
@@ -2495,7 +2473,7 @@ unlock:
static int qm_stop_qp(struct hisi_qp *qp)
{
- return qm_mb(qp->qm, QM_MB_CMD_STOP_QP, 0, qp->qp_id, 0);
+ return hisi_qm_mb(qp->qm, QM_MB_CMD_STOP_QP, 0, qp->qp_id, 0);
}
static int qm_set_msi(struct hisi_qm *qm, bool set)
@@ -2763,7 +2741,7 @@ static int qm_sq_ctx_cfg(struct hisi_qp *qp, int qp_id, u32 pasid)
return -ENOMEM;
}
- ret = qm_mb(qm, QM_MB_CMD_SQC, sqc_dma, qp_id, 0);
+ ret = hisi_qm_mb(qm, QM_MB_CMD_SQC, sqc_dma, qp_id, 0);
dma_unmap_single(dev, sqc_dma, sizeof(struct qm_sqc), DMA_TO_DEVICE);
kfree(sqc);
@@ -2804,7 +2782,7 @@ static int qm_cq_ctx_cfg(struct hisi_qp *qp, int qp_id, u32 pasid)
return -ENOMEM;
}
- ret = qm_mb(qm, QM_MB_CMD_CQC, cqc_dma, qp_id, 0);
+ ret = hisi_qm_mb(qm, QM_MB_CMD_CQC, cqc_dma, qp_id, 0);
dma_unmap_single(dev, cqc_dma, sizeof(struct qm_cqc), DMA_TO_DEVICE);
kfree(cqc);
@@ -3514,6 +3492,12 @@ static void hisi_qm_pci_uninit(struct hisi_qm *qm)
pci_disable_device(pdev);
}
+static void hisi_qm_set_state(struct hisi_qm *qm, u8 state)
+{
+ if (qm->ver > QM_HW_V2 && qm->fun_type == QM_HW_VF)
+ writel(state, qm->io_base + QM_VF_STATE);
+}
+
/**
* hisi_qm_uninit() - Uninitialize qm.
* @qm: The qm needed uninit.
@@ -3542,6 +3526,7 @@ void hisi_qm_uninit(struct hisi_qm *qm)
dma_free_coherent(dev, qm->qdma.size,
qm->qdma.va, qm->qdma.dma);
}
+ hisi_qm_set_state(qm, QM_NOT_READY);
up_write(&qm->qps_lock);
qm_irq_unregister(qm);
@@ -3655,7 +3640,7 @@ static int qm_eq_ctx_cfg(struct hisi_qm *qm)
return -ENOMEM;
}
- ret = qm_mb(qm, QM_MB_CMD_EQC, eqc_dma, 0, 0);
+ ret = hisi_qm_mb(qm, QM_MB_CMD_EQC, eqc_dma, 0, 0);
dma_unmap_single(dev, eqc_dma, sizeof(struct qm_eqc), DMA_TO_DEVICE);
kfree(eqc);
@@ -3684,7 +3669,7 @@ static int qm_aeq_ctx_cfg(struct hisi_qm *qm)
return -ENOMEM;
}
- ret = qm_mb(qm, QM_MB_CMD_AEQC, aeqc_dma, 0, 0);
+ ret = hisi_qm_mb(qm, QM_MB_CMD_AEQC, aeqc_dma, 0, 0);
dma_unmap_single(dev, aeqc_dma, sizeof(struct qm_aeqc), DMA_TO_DEVICE);
kfree(aeqc);
@@ -3723,11 +3708,11 @@ static int __hisi_qm_start(struct hisi_qm *qm)
if (ret)
return ret;
- ret = qm_mb(qm, QM_MB_CMD_SQC_BT, qm->sqc_dma, 0, 0);
+ ret = hisi_qm_mb(qm, QM_MB_CMD_SQC_BT, qm->sqc_dma, 0, 0);
if (ret)
return ret;
- ret = qm_mb(qm, QM_MB_CMD_CQC_BT, qm->cqc_dma, 0, 0);
+ ret = hisi_qm_mb(qm, QM_MB_CMD_CQC_BT, qm->cqc_dma, 0, 0);
if (ret)
return ret;
@@ -3767,6 +3752,7 @@ int hisi_qm_start(struct hisi_qm *qm)
if (!ret)
atomic_set(&qm->status.flags, QM_START);
+ hisi_qm_set_state(qm, QM_READY);
err_unlock:
up_write(&qm->qps_lock);
return ret;
@@ -3840,7 +3826,7 @@ static void qm_clear_queues(struct hisi_qm *qm)
for (i = 0; i < qm->qp_num; i++) {
qp = &qm->qp_array[i];
- if (qp->is_resetting)
+ if (qp->is_in_kernel && qp->is_resetting)
memset(qp->qdma.va, 0, qp->qdma.size);
}
@@ -4295,7 +4281,7 @@ static void qm_vf_get_qos(struct hisi_qm *qm, u32 fun_num)
static int qm_vf_read_qos(struct hisi_qm *qm)
{
int cnt = 0;
- int ret;
+ int ret = -EINVAL;
/* reset mailbox qos val */
qm->mb_qos = 0;
diff --git a/drivers/crypto/hisilicon/sec2/sec.h b/drivers/crypto/hisilicon/sec2/sec.h
index d97cf02b1df7..c2e9b01187a7 100644
--- a/drivers/crypto/hisilicon/sec2/sec.h
+++ b/drivers/crypto/hisilicon/sec2/sec.h
@@ -4,7 +4,7 @@
#ifndef __HISI_SEC_V2_H
#define __HISI_SEC_V2_H
-#include "../qm.h"
+#include <linux/hisi_acc_qm.h>
#include "sec_crypto.h"
/* Algorithm resource per hardware SEC queue */
diff --git a/drivers/crypto/hisilicon/sec2/sec_crypto.c b/drivers/crypto/hisilicon/sec2/sec_crypto.c
index 6a45bd23b363..a91635c348b5 100644
--- a/drivers/crypto/hisilicon/sec2/sec_crypto.c
+++ b/drivers/crypto/hisilicon/sec2/sec_crypto.c
@@ -42,6 +42,8 @@
#define SEC_DE_OFFSET_V3 9
#define SEC_SCENE_OFFSET_V3 5
#define SEC_CKEY_OFFSET_V3 13
+#define SEC_CTR_CNT_OFFSET 25
+#define SEC_CTR_CNT_ROLLOVER 2
#define SEC_SRC_SGL_OFFSET_V3 11
#define SEC_DST_SGL_OFFSET_V3 14
#define SEC_CALG_OFFSET_V3 4
@@ -63,6 +65,7 @@
#define SEC_AUTH_CIPHER 0x1
#define SEC_MAX_MAC_LEN 64
#define SEC_MAX_AAD_LEN 65535
+#define SEC_MAX_CCM_AAD_LEN 65279
#define SEC_TOTAL_MAC_SZ (SEC_MAX_MAC_LEN * QM_Q_DEPTH)
#define SEC_PBUF_SZ 512
@@ -237,7 +240,7 @@ static void sec_req_cb(struct hisi_qp *qp, void *resp)
if (unlikely(type != type_supported)) {
atomic64_inc(&dfx->err_bd_cnt);
- pr_err("err bd type [%d]\n", type);
+ pr_err("err bd type [%u]\n", type);
return;
}
@@ -641,13 +644,15 @@ static int sec_skcipher_fbtfm_init(struct crypto_skcipher *tfm)
struct sec_cipher_ctx *c_ctx = &ctx->c_ctx;
c_ctx->fallback = false;
+
+ /* Currently, only XTS mode need fallback tfm when using 192bit key */
if (likely(strncmp(alg, "xts", SEC_XTS_NAME_SZ)))
return 0;
c_ctx->fbtfm = crypto_alloc_sync_skcipher(alg, 0,
CRYPTO_ALG_NEED_FALLBACK);
if (IS_ERR(c_ctx->fbtfm)) {
- pr_err("failed to alloc fallback tfm!\n");
+ pr_err("failed to alloc xts mode fallback tfm!\n");
return PTR_ERR(c_ctx->fbtfm);
}
@@ -808,7 +813,7 @@ static int sec_skcipher_setkey(struct crypto_skcipher *tfm, const u8 *key,
}
memcpy(c_ctx->c_key, key, keylen);
- if (c_ctx->fallback) {
+ if (c_ctx->fallback && c_ctx->fbtfm) {
ret = crypto_sync_skcipher_setkey(c_ctx->fbtfm, key, keylen);
if (ret) {
dev_err(dev, "failed to set fallback skcipher key!\n");
@@ -1300,6 +1305,10 @@ static int sec_skcipher_bd_fill_v3(struct sec_ctx *ctx, struct sec_req *req)
cipher = SEC_CIPHER_DEC;
sec_sqe3->c_icv_key |= cpu_to_le16(cipher);
+ /* Set the CTR counter mode is 128bit rollover */
+ sec_sqe3->auth_mac_key = cpu_to_le32((u32)SEC_CTR_CNT_ROLLOVER <<
+ SEC_CTR_CNT_OFFSET);
+
if (req->use_pbuf) {
bd_param |= SEC_PBUF << SEC_SRC_SGL_OFFSET_V3;
bd_param |= SEC_PBUF << SEC_DST_SGL_OFFSET_V3;
@@ -1614,7 +1623,7 @@ static void sec_auth_bd_fill_ex_v3(struct sec_auth_ctx *ctx, int dir,
sqe3->auth_mac_key |= cpu_to_le32((u32)SEC_AUTH_TYPE1);
sqe3->huk_iv_seq &= SEC_CIPHER_AUTH_V3;
} else {
- sqe3->auth_mac_key |= cpu_to_le32((u32)SEC_AUTH_TYPE1);
+ sqe3->auth_mac_key |= cpu_to_le32((u32)SEC_AUTH_TYPE2);
sqe3->huk_iv_seq |= SEC_AUTH_CIPHER_V3;
}
sqe3->a_len_key = cpu_to_le32(c_req->c_len + aq->assoclen);
@@ -2032,13 +2041,12 @@ static int sec_skcipher_soft_crypto(struct sec_ctx *ctx,
struct skcipher_request *sreq, bool encrypt)
{
struct sec_cipher_ctx *c_ctx = &ctx->c_ctx;
+ SYNC_SKCIPHER_REQUEST_ON_STACK(subreq, c_ctx->fbtfm);
struct device *dev = ctx->dev;
int ret;
- SYNC_SKCIPHER_REQUEST_ON_STACK(subreq, c_ctx->fbtfm);
-
if (!c_ctx->fbtfm) {
- dev_err(dev, "failed to check fallback tfm\n");
+ dev_err_ratelimited(dev, "the soft tfm isn't supported in the current system.\n");
return -EINVAL;
}
@@ -2219,6 +2227,10 @@ static int sec_aead_spec_check(struct sec_ctx *ctx, struct sec_req *sreq)
}
if (c_mode == SEC_CMODE_CCM) {
+ if (unlikely(req->assoclen > SEC_MAX_CCM_AAD_LEN)) {
+ dev_err_ratelimited(dev, "CCM input aad parameter is too long!\n");
+ return -EINVAL;
+ }
ret = aead_iv_demension_check(req);
if (ret) {
dev_err(dev, "aead input iv param error!\n");
@@ -2256,7 +2268,6 @@ static int sec_aead_param_check(struct sec_ctx *ctx, struct sec_req *sreq)
if (ctx->sec->qm.ver == QM_HW_V2) {
if (unlikely(!req->cryptlen || (!sreq->c_req.encrypt &&
req->cryptlen <= authsize))) {
- dev_err(dev, "Kunpeng920 not support 0 length!\n");
ctx->a_ctx.fallback = true;
return -EINVAL;
}
@@ -2284,9 +2295,10 @@ static int sec_aead_soft_crypto(struct sec_ctx *ctx,
struct aead_request *aead_req,
bool encrypt)
{
- struct aead_request *subreq = aead_request_ctx(aead_req);
struct sec_auth_ctx *a_ctx = &ctx->a_ctx;
struct device *dev = ctx->dev;
+ struct aead_request *subreq;
+ int ret;
/* Kunpeng920 aead mode not support input 0 size */
if (!a_ctx->fallback_aead_tfm) {
@@ -2294,6 +2306,10 @@ static int sec_aead_soft_crypto(struct sec_ctx *ctx,
return -EINVAL;
}
+ subreq = aead_request_alloc(a_ctx->fallback_aead_tfm, GFP_KERNEL);
+ if (!subreq)
+ return -ENOMEM;
+
aead_request_set_tfm(subreq, a_ctx->fallback_aead_tfm);
aead_request_set_callback(subreq, aead_req->base.flags,
aead_req->base.complete, aead_req->base.data);
@@ -2301,8 +2317,13 @@ static int sec_aead_soft_crypto(struct sec_ctx *ctx,
aead_req->cryptlen, aead_req->iv);
aead_request_set_ad(subreq, aead_req->assoclen);
- return encrypt ? crypto_aead_encrypt(subreq) :
- crypto_aead_decrypt(subreq);
+ if (encrypt)
+ ret = crypto_aead_encrypt(subreq);
+ else
+ ret = crypto_aead_decrypt(subreq);
+ aead_request_free(subreq);
+
+ return ret;
}
static int sec_aead_crypto(struct aead_request *a_req, bool encrypt)
diff --git a/drivers/crypto/hisilicon/sec2/sec_crypto.h b/drivers/crypto/hisilicon/sec2/sec_crypto.h
index 9f71c358a6d3..5e039b50e9d4 100644
--- a/drivers/crypto/hisilicon/sec2/sec_crypto.h
+++ b/drivers/crypto/hisilicon/sec2/sec_crypto.h
@@ -354,8 +354,10 @@ struct sec_sqe3 {
* akey_len: 9~14 bits
* a_alg: 15~20 bits
* key_sel: 21~24 bits
- * updata_key: 25 bits
- * reserved: 26~31 bits
+ * ctr_count_mode/sm4_xts: 25~26 bits
+ * sva_prefetch: 27 bits
+ * key_wrap_num: 28~30 bits
+ * update_key: 31 bits
*/
__le32 auth_mac_key;
__le32 salt;
diff --git a/drivers/crypto/hisilicon/sec2/sec_main.c b/drivers/crypto/hisilicon/sec2/sec_main.c
index 26d3ab1d308b..92fae706bdb2 100644
--- a/drivers/crypto/hisilicon/sec2/sec_main.c
+++ b/drivers/crypto/hisilicon/sec2/sec_main.c
@@ -20,8 +20,7 @@
#define SEC_VF_NUM 63
#define SEC_QUEUE_NUM_V1 4096
-#define SEC_PF_PCI_DEVICE_ID 0xa255
-#define SEC_VF_PCI_DEVICE_ID 0xa256
+#define PCI_DEVICE_ID_HUAWEI_SEC_PF 0xa255
#define SEC_BD_ERR_CHK_EN0 0xEFFFFFFF
#define SEC_BD_ERR_CHK_EN1 0x7ffff7fd
@@ -90,6 +89,10 @@
SEC_USER1_WB_DATA_SSV)
#define SEC_USER1_SMMU_SVA (SEC_USER1_SMMU_NORMAL | SEC_USER1_SVA_SET)
#define SEC_USER1_SMMU_MASK (~SEC_USER1_SVA_SET)
+#define SEC_INTERFACE_USER_CTRL0_REG_V3 0x302220
+#define SEC_INTERFACE_USER_CTRL1_REG_V3 0x302224
+#define SEC_USER1_SMMU_NORMAL_V3 (BIT(23) | BIT(17) | BIT(11) | BIT(5))
+#define SEC_USER1_SMMU_MASK_V3 0xFF79E79E
#define SEC_CORE_INT_STATUS_M_ECC BIT(2)
#define SEC_PREFETCH_CFG 0x301130
@@ -225,7 +228,7 @@ static const struct debugfs_reg32 sec_dfx_regs[] = {
static int sec_pf_q_num_set(const char *val, const struct kernel_param *kp)
{
- return q_num_set(val, kp, SEC_PF_PCI_DEVICE_ID);
+ return q_num_set(val, kp, PCI_DEVICE_ID_HUAWEI_SEC_PF);
}
static const struct kernel_param_ops sec_pf_q_num_ops = {
@@ -313,8 +316,8 @@ module_param_cb(uacce_mode, &sec_uacce_mode_ops, &uacce_mode, 0444);
MODULE_PARM_DESC(uacce_mode, UACCE_MODE_DESC);
static const struct pci_device_id sec_dev_ids[] = {
- { PCI_DEVICE(PCI_VENDOR_ID_HUAWEI, SEC_PF_PCI_DEVICE_ID) },
- { PCI_DEVICE(PCI_VENDOR_ID_HUAWEI, SEC_VF_PCI_DEVICE_ID) },
+ { PCI_DEVICE(PCI_VENDOR_ID_HUAWEI, PCI_DEVICE_ID_HUAWEI_SEC_PF) },
+ { PCI_DEVICE(PCI_VENDOR_ID_HUAWEI, PCI_DEVICE_ID_HUAWEI_SEC_VF) },
{ 0, }
};
MODULE_DEVICE_TABLE(pci, sec_dev_ids);
@@ -335,6 +338,41 @@ static void sec_set_endian(struct hisi_qm *qm)
writel_relaxed(reg, qm->io_base + SEC_CONTROL_REG);
}
+static void sec_engine_sva_config(struct hisi_qm *qm)
+{
+ u32 reg;
+
+ if (qm->ver > QM_HW_V2) {
+ reg = readl_relaxed(qm->io_base +
+ SEC_INTERFACE_USER_CTRL0_REG_V3);
+ reg |= SEC_USER0_SMMU_NORMAL;
+ writel_relaxed(reg, qm->io_base +
+ SEC_INTERFACE_USER_CTRL0_REG_V3);
+
+ reg = readl_relaxed(qm->io_base +
+ SEC_INTERFACE_USER_CTRL1_REG_V3);
+ reg &= SEC_USER1_SMMU_MASK_V3;
+ reg |= SEC_USER1_SMMU_NORMAL_V3;
+ writel_relaxed(reg, qm->io_base +
+ SEC_INTERFACE_USER_CTRL1_REG_V3);
+ } else {
+ reg = readl_relaxed(qm->io_base +
+ SEC_INTERFACE_USER_CTRL0_REG);
+ reg |= SEC_USER0_SMMU_NORMAL;
+ writel_relaxed(reg, qm->io_base +
+ SEC_INTERFACE_USER_CTRL0_REG);
+ reg = readl_relaxed(qm->io_base +
+ SEC_INTERFACE_USER_CTRL1_REG);
+ reg &= SEC_USER1_SMMU_MASK;
+ if (qm->use_sva)
+ reg |= SEC_USER1_SMMU_SVA;
+ else
+ reg |= SEC_USER1_SMMU_NORMAL;
+ writel_relaxed(reg, qm->io_base +
+ SEC_INTERFACE_USER_CTRL1_REG);
+ }
+}
+
static void sec_open_sva_prefetch(struct hisi_qm *qm)
{
u32 val;
@@ -426,26 +464,18 @@ static int sec_engine_init(struct hisi_qm *qm)
reg |= (0x1 << SEC_TRNG_EN_SHIFT);
writel_relaxed(reg, qm->io_base + SEC_CONTROL_REG);
- reg = readl_relaxed(qm->io_base + SEC_INTERFACE_USER_CTRL0_REG);
- reg |= SEC_USER0_SMMU_NORMAL;
- writel_relaxed(reg, qm->io_base + SEC_INTERFACE_USER_CTRL0_REG);
-
- reg = readl_relaxed(qm->io_base + SEC_INTERFACE_USER_CTRL1_REG);
- reg &= SEC_USER1_SMMU_MASK;
- if (qm->use_sva && qm->ver == QM_HW_V2)
- reg |= SEC_USER1_SMMU_SVA;
- else
- reg |= SEC_USER1_SMMU_NORMAL;
- writel_relaxed(reg, qm->io_base + SEC_INTERFACE_USER_CTRL1_REG);
+ sec_engine_sva_config(qm);
writel(SEC_SINGLE_PORT_MAX_TRANS,
qm->io_base + AM_CFG_SINGLE_PORT_MAX_TRANS);
writel(SEC_SAA_ENABLE, qm->io_base + SEC_SAA_EN_REG);
- /* Enable sm4 extra mode, as ctr/ecb */
- writel_relaxed(SEC_BD_ERR_CHK_EN0,
- qm->io_base + SEC_BD_ERR_CHK_EN_REG0);
+ /* HW V2 enable sm4 extra mode, as ctr/ecb */
+ if (qm->ver < QM_HW_V3)
+ writel_relaxed(SEC_BD_ERR_CHK_EN0,
+ qm->io_base + SEC_BD_ERR_CHK_EN_REG0);
+
/* Enable sm4 xts mode multiple iv */
writel_relaxed(SEC_BD_ERR_CHK_EN1,
qm->io_base + SEC_BD_ERR_CHK_EN_REG1);
@@ -717,7 +747,7 @@ static int sec_core_debug_init(struct hisi_qm *qm)
regset->base = qm->io_base;
regset->dev = dev;
- if (qm->pdev->device == SEC_PF_PCI_DEVICE_ID)
+ if (qm->pdev->device == PCI_DEVICE_ID_HUAWEI_SEC_PF)
debugfs_create_file("regs", 0444, tmp_d, regset, &sec_regs_fops);
for (i = 0; i < ARRAY_SIZE(sec_dfx_labels); i++) {
@@ -735,7 +765,7 @@ static int sec_debug_init(struct hisi_qm *qm)
struct sec_dev *sec = container_of(qm, struct sec_dev, qm);
int i;
- if (qm->pdev->device == SEC_PF_PCI_DEVICE_ID) {
+ if (qm->pdev->device == PCI_DEVICE_ID_HUAWEI_SEC_PF) {
for (i = SEC_CLEAR_ENABLE; i < SEC_DEBUG_FILE_NUM; i++) {
spin_lock_init(&sec->debug.files[i].lock);
sec->debug.files[i].index = i;
@@ -877,7 +907,7 @@ static int sec_qm_init(struct hisi_qm *qm, struct pci_dev *pdev)
qm->sqe_size = SEC_SQE_SIZE;
qm->dev_name = sec_name;
- qm->fun_type = (pdev->device == SEC_PF_PCI_DEVICE_ID) ?
+ qm->fun_type = (pdev->device == PCI_DEVICE_ID_HUAWEI_SEC_PF) ?
QM_HW_PF : QM_HW_VF;
if (qm->fun_type == QM_HW_PF) {
qm->qp_base = SEC_PF_DEF_Q_BASE;
@@ -1089,6 +1119,12 @@ static struct pci_driver sec_pci_driver = {
.driver.pm = &sec_pm_ops,
};
+struct pci_driver *hisi_sec_get_pf_driver(void)
+{
+ return &sec_pci_driver;
+}
+EXPORT_SYMBOL_GPL(hisi_sec_get_pf_driver);
+
static void sec_register_debugfs(void)
{
if (!debugfs_initialized())
diff --git a/drivers/crypto/hisilicon/sgl.c b/drivers/crypto/hisilicon/sgl.c
index 057273769f26..f7efc02b065f 100644
--- a/drivers/crypto/hisilicon/sgl.c
+++ b/drivers/crypto/hisilicon/sgl.c
@@ -1,9 +1,9 @@
// SPDX-License-Identifier: GPL-2.0
/* Copyright (c) 2019 HiSilicon Limited. */
#include <linux/dma-mapping.h>
+#include <linux/hisi_acc_qm.h>
#include <linux/module.h>
#include <linux/slab.h>
-#include "qm.h"
#define HISI_ACC_SGL_SGE_NR_MIN 1
#define HISI_ACC_SGL_NR_MAX 256
diff --git a/drivers/crypto/hisilicon/zip/zip.h b/drivers/crypto/hisilicon/zip/zip.h
index 517fdbdff3ea..3dfd3bac5a33 100644
--- a/drivers/crypto/hisilicon/zip/zip.h
+++ b/drivers/crypto/hisilicon/zip/zip.h
@@ -7,7 +7,7 @@
#define pr_fmt(fmt) "hisi_zip: " fmt
#include <linux/list.h>
-#include "../qm.h"
+#include <linux/hisi_acc_qm.h>
enum hisi_zip_error_type {
/* negative compression */
diff --git a/drivers/crypto/hisilicon/zip/zip_main.c b/drivers/crypto/hisilicon/zip/zip_main.c
index 678f8b58ec42..4534e1e107d1 100644
--- a/drivers/crypto/hisilicon/zip/zip_main.c
+++ b/drivers/crypto/hisilicon/zip/zip_main.c
@@ -15,8 +15,7 @@
#include <linux/uacce.h>
#include "zip.h"
-#define PCI_DEVICE_ID_ZIP_PF 0xa250
-#define PCI_DEVICE_ID_ZIP_VF 0xa251
+#define PCI_DEVICE_ID_HUAWEI_ZIP_PF 0xa250
#define HZIP_QUEUE_NUM_V1 4096
@@ -246,7 +245,7 @@ MODULE_PARM_DESC(uacce_mode, UACCE_MODE_DESC);
static int pf_q_num_set(const char *val, const struct kernel_param *kp)
{
- return q_num_set(val, kp, PCI_DEVICE_ID_ZIP_PF);
+ return q_num_set(val, kp, PCI_DEVICE_ID_HUAWEI_ZIP_PF);
}
static const struct kernel_param_ops pf_q_num_ops = {
@@ -268,8 +267,8 @@ module_param_cb(vfs_num, &vfs_num_ops, &vfs_num, 0444);
MODULE_PARM_DESC(vfs_num, "Number of VFs to enable(1-63), 0(default)");
static const struct pci_device_id hisi_zip_dev_ids[] = {
- { PCI_DEVICE(PCI_VENDOR_ID_HUAWEI, PCI_DEVICE_ID_ZIP_PF) },
- { PCI_DEVICE(PCI_VENDOR_ID_HUAWEI, PCI_DEVICE_ID_ZIP_VF) },
+ { PCI_DEVICE(PCI_VENDOR_ID_HUAWEI, PCI_DEVICE_ID_HUAWEI_ZIP_PF) },
+ { PCI_DEVICE(PCI_VENDOR_ID_HUAWEI, PCI_DEVICE_ID_HUAWEI_ZIP_VF) },
{ 0, }
};
MODULE_DEVICE_TABLE(pci, hisi_zip_dev_ids);
@@ -838,7 +837,7 @@ static int hisi_zip_qm_init(struct hisi_qm *qm, struct pci_dev *pdev)
qm->sqe_size = HZIP_SQE_SIZE;
qm->dev_name = hisi_zip_name;
- qm->fun_type = (pdev->device == PCI_DEVICE_ID_ZIP_PF) ?
+ qm->fun_type = (pdev->device == PCI_DEVICE_ID_HUAWEI_ZIP_PF) ?
QM_HW_PF : QM_HW_VF;
if (qm->fun_type == QM_HW_PF) {
qm->qp_base = HZIP_PF_DEF_Q_BASE;
@@ -1013,6 +1012,12 @@ static struct pci_driver hisi_zip_pci_driver = {
.driver.pm = &hisi_zip_pm_ops,
};
+struct pci_driver *hisi_zip_get_pf_driver(void)
+{
+ return &hisi_zip_pci_driver;
+}
+EXPORT_SYMBOL_GPL(hisi_zip_get_pf_driver);
+
static void hisi_zip_register_debugfs(void)
{
if (!debugfs_initialized())
diff --git a/drivers/crypto/ixp4xx_crypto.c b/drivers/crypto/ixp4xx_crypto.c
index 98730aab287c..d39a386b31ac 100644
--- a/drivers/crypto/ixp4xx_crypto.c
+++ b/drivers/crypto/ixp4xx_crypto.c
@@ -33,7 +33,6 @@
/* Intermittent includes, delete this after v5.14-rc1 */
#include <linux/soc/ixp4xx/cpu.h>
-#include <mach/ixp4xx-regs.h>
#define MAX_KEYLEN 32
diff --git a/drivers/crypto/marvell/Kconfig b/drivers/crypto/marvell/Kconfig
index 9125199f1702..a48591af12d0 100644
--- a/drivers/crypto/marvell/Kconfig
+++ b/drivers/crypto/marvell/Kconfig
@@ -47,6 +47,7 @@ config CRYPTO_DEV_OCTEONTX2_CPT
select CRYPTO_SKCIPHER
select CRYPTO_HASH
select CRYPTO_AEAD
+ select NET_DEVLINK
help
This driver allows you to utilize the Marvell Cryptographic
Accelerator Unit(CPT) found in OcteonTX2 series of processors.
diff --git a/drivers/crypto/marvell/octeontx/otx_cptvf_algs.c b/drivers/crypto/marvell/octeontx/otx_cptvf_algs.c
index ccbef01888d4..01c48ddc4eeb 100644
--- a/drivers/crypto/marvell/octeontx/otx_cptvf_algs.c
+++ b/drivers/crypto/marvell/octeontx/otx_cptvf_algs.c
@@ -1639,11 +1639,8 @@ static void swap_func(void *lptr, void *rptr, int size)
{
struct cpt_device_desc *ldesc = (struct cpt_device_desc *) lptr;
struct cpt_device_desc *rdesc = (struct cpt_device_desc *) rptr;
- struct cpt_device_desc desc;
- desc = *ldesc;
- *ldesc = *rdesc;
- *rdesc = desc;
+ swap(*ldesc, *rdesc);
}
int otx_cpt_crypto_init(struct pci_dev *pdev, struct module *mod,
diff --git a/drivers/crypto/marvell/octeontx/otx_cptvf_main.c b/drivers/crypto/marvell/octeontx/otx_cptvf_main.c
index b681bd2dc6ad..36d72e35ebeb 100644
--- a/drivers/crypto/marvell/octeontx/otx_cptvf_main.c
+++ b/drivers/crypto/marvell/octeontx/otx_cptvf_main.c
@@ -204,7 +204,6 @@ static int alloc_command_queues(struct otx_cptvf *cptvf,
/* per queue initialization */
for (i = 0; i < cptvf->num_queues; i++) {
- c_size = 0;
rem_q_size = q_size;
first = NULL;
last = NULL;
diff --git a/drivers/crypto/marvell/octeontx2/otx2_cpt_common.h b/drivers/crypto/marvell/octeontx2/otx2_cpt_common.h
index fb56824cb0a6..5012b7e669f0 100644
--- a/drivers/crypto/marvell/octeontx2/otx2_cpt_common.h
+++ b/drivers/crypto/marvell/octeontx2/otx2_cpt_common.h
@@ -157,5 +157,6 @@ struct otx2_cptlfs_info;
int otx2_cpt_attach_rscrs_msg(struct otx2_cptlfs_info *lfs);
int otx2_cpt_detach_rsrcs_msg(struct otx2_cptlfs_info *lfs);
int otx2_cpt_msix_offset_msg(struct otx2_cptlfs_info *lfs);
+int otx2_cpt_sync_mbox_msg(struct otx2_mbox *mbox);
#endif /* __OTX2_CPT_COMMON_H */
diff --git a/drivers/crypto/marvell/octeontx2/otx2_cpt_mbox_common.c b/drivers/crypto/marvell/octeontx2/otx2_cpt_mbox_common.c
index 9074876d38e5..a317319696ef 100644
--- a/drivers/crypto/marvell/octeontx2/otx2_cpt_mbox_common.c
+++ b/drivers/crypto/marvell/octeontx2/otx2_cpt_mbox_common.c
@@ -202,3 +202,17 @@ int otx2_cpt_msix_offset_msg(struct otx2_cptlfs_info *lfs)
}
return ret;
}
+
+int otx2_cpt_sync_mbox_msg(struct otx2_mbox *mbox)
+{
+ int err;
+
+ if (!otx2_mbox_nonempty(mbox, 0))
+ return 0;
+ otx2_mbox_msg_send(mbox, 0);
+ err = otx2_mbox_wait_for_rsp(mbox, 0);
+ if (err)
+ return err;
+
+ return otx2_mbox_check_rsp_msgs(mbox, 0);
+}
diff --git a/drivers/crypto/marvell/octeontx2/otx2_cptlf.h b/drivers/crypto/marvell/octeontx2/otx2_cptlf.h
index b691b6c1d5c4..4fcaf61a70e3 100644
--- a/drivers/crypto/marvell/octeontx2/otx2_cptlf.h
+++ b/drivers/crypto/marvell/octeontx2/otx2_cptlf.h
@@ -26,12 +26,22 @@
*/
#define OTX2_CPT_INST_QLEN_MSGS ((OTX2_CPT_SIZE_DIV40 - 1) * 40)
+/*
+ * LDWB is getting incorrectly used when IQB_LDWB = 1 and CPT instruction
+ * queue has less than 320 free entries. So, increase HW instruction queue
+ * size by 320 and give 320 entries less for SW/NIX RX as a workaround.
+ */
+#define OTX2_CPT_INST_QLEN_EXTRA_BYTES (320 * OTX2_CPT_INST_SIZE)
+#define OTX2_CPT_EXTRA_SIZE_DIV40 (320/40)
+
/* CPT instruction queue length in bytes */
-#define OTX2_CPT_INST_QLEN_BYTES (OTX2_CPT_SIZE_DIV40 * 40 * \
- OTX2_CPT_INST_SIZE)
+#define OTX2_CPT_INST_QLEN_BYTES \
+ ((OTX2_CPT_SIZE_DIV40 * 40 * OTX2_CPT_INST_SIZE) + \
+ OTX2_CPT_INST_QLEN_EXTRA_BYTES)
/* CPT instruction group queue length in bytes */
-#define OTX2_CPT_INST_GRP_QLEN_BYTES (OTX2_CPT_SIZE_DIV40 * 16)
+#define OTX2_CPT_INST_GRP_QLEN_BYTES \
+ ((OTX2_CPT_SIZE_DIV40 + OTX2_CPT_EXTRA_SIZE_DIV40) * 16)
/* CPT FC length in bytes */
#define OTX2_CPT_Q_FC_LEN 128
@@ -179,7 +189,8 @@ static inline void otx2_cptlf_do_set_iqueue_size(struct otx2_cptlf_info *lf)
{
union otx2_cptx_lf_q_size lf_q_size = { .u = 0x0 };
- lf_q_size.s.size_div40 = OTX2_CPT_SIZE_DIV40;
+ lf_q_size.s.size_div40 = OTX2_CPT_SIZE_DIV40 +
+ OTX2_CPT_EXTRA_SIZE_DIV40;
otx2_cpt_write64(lf->lfs->reg_base, BLKADDR_CPT0, lf->slot,
OTX2_CPT_LF_Q_SIZE, lf_q_size.u);
}
diff --git a/drivers/crypto/marvell/octeontx2/otx2_cptpf.h b/drivers/crypto/marvell/octeontx2/otx2_cptpf.h
index 05b2d9c650e1..936174b012e8 100644
--- a/drivers/crypto/marvell/octeontx2/otx2_cptpf.h
+++ b/drivers/crypto/marvell/octeontx2/otx2_cptpf.h
@@ -46,6 +46,7 @@ struct otx2_cptpf_dev {
struct workqueue_struct *flr_wq;
struct cptpf_flr_work *flr_work;
+ struct mutex lock; /* serialize mailbox access */
unsigned long cap_flag;
u8 pf_id; /* RVU PF number */
diff --git a/drivers/crypto/marvell/octeontx2/otx2_cptpf_main.c b/drivers/crypto/marvell/octeontx2/otx2_cptpf_main.c
index 1720a5bb7016..a402ccfac557 100644
--- a/drivers/crypto/marvell/octeontx2/otx2_cptpf_main.c
+++ b/drivers/crypto/marvell/octeontx2/otx2_cptpf_main.c
@@ -140,10 +140,13 @@ static void cptpf_flr_wq_handler(struct work_struct *work)
vf = flr_work - pf->flr_work;
+ mutex_lock(&pf->lock);
req = otx2_mbox_alloc_msg_rsp(mbox, 0, sizeof(*req),
sizeof(struct msg_rsp));
- if (!req)
+ if (!req) {
+ mutex_unlock(&pf->lock);
return;
+ }
req->sig = OTX2_MBOX_REQ_SIG;
req->id = MBOX_MSG_VF_FLR;
@@ -151,16 +154,19 @@ static void cptpf_flr_wq_handler(struct work_struct *work)
req->pcifunc |= (vf + 1) & RVU_PFVF_FUNC_MASK;
otx2_cpt_send_mbox_msg(mbox, pf->pdev);
+ if (!otx2_cpt_sync_mbox_msg(&pf->afpf_mbox)) {
- if (vf >= 64) {
- reg = 1;
- vf = vf - 64;
+ if (vf >= 64) {
+ reg = 1;
+ vf = vf - 64;
+ }
+ /* Clear transaction pending register */
+ otx2_cpt_write64(pf->reg_base, BLKADDR_RVUM, 0,
+ RVU_PF_VFTRPENDX(reg), BIT_ULL(vf));
+ otx2_cpt_write64(pf->reg_base, BLKADDR_RVUM, 0,
+ RVU_PF_VFFLR_INT_ENA_W1SX(reg), BIT_ULL(vf));
}
- /* Clear transaction pending register */
- otx2_cpt_write64(pf->reg_base, BLKADDR_RVUM, 0,
- RVU_PF_VFTRPENDX(reg), BIT_ULL(vf));
- otx2_cpt_write64(pf->reg_base, BLKADDR_RVUM, 0,
- RVU_PF_VFFLR_INT_ENA_W1SX(reg), BIT_ULL(vf));
+ mutex_unlock(&pf->lock);
}
static irqreturn_t cptpf_vf_flr_intr(int __always_unused irq, void *arg)
@@ -468,6 +474,7 @@ static int cptpf_afpf_mbox_init(struct otx2_cptpf_dev *cptpf)
goto error;
INIT_WORK(&cptpf->afpf_mbox_work, otx2_cptpf_afpf_mbox_handler);
+ mutex_init(&cptpf->lock);
return 0;
error:
diff --git a/drivers/crypto/marvell/octeontx2/otx2_cptpf_mbox.c b/drivers/crypto/marvell/octeontx2/otx2_cptpf_mbox.c
index 186f1c1190c1..dee0aa60b698 100644
--- a/drivers/crypto/marvell/octeontx2/otx2_cptpf_mbox.c
+++ b/drivers/crypto/marvell/octeontx2/otx2_cptpf_mbox.c
@@ -18,9 +18,12 @@ static int forward_to_af(struct otx2_cptpf_dev *cptpf,
struct mbox_msghdr *msg;
int ret;
+ mutex_lock(&cptpf->lock);
msg = otx2_mbox_alloc_msg(&cptpf->afpf_mbox, 0, size);
- if (msg == NULL)
+ if (msg == NULL) {
+ mutex_unlock(&cptpf->lock);
return -ENOMEM;
+ }
memcpy((uint8_t *)msg + sizeof(struct mbox_msghdr),
(uint8_t *)req + sizeof(struct mbox_msghdr), size);
@@ -29,15 +32,19 @@ static int forward_to_af(struct otx2_cptpf_dev *cptpf,
msg->sig = req->sig;
msg->ver = req->ver;
- otx2_mbox_msg_send(&cptpf->afpf_mbox, 0);
- ret = otx2_mbox_wait_for_rsp(&cptpf->afpf_mbox, 0);
+ ret = otx2_cpt_sync_mbox_msg(&cptpf->afpf_mbox);
+ /* Error code -EIO indicate there is a communication failure
+ * to the AF. Rest of the error codes indicate that AF processed
+ * VF messages and set the error codes in response messages
+ * (if any) so simply forward responses to VF.
+ */
if (ret == -EIO) {
- dev_err(&cptpf->pdev->dev, "RVU MBOX timeout.\n");
+ dev_warn(&cptpf->pdev->dev,
+ "AF not responding to VF%d messages\n", vf->vf_id);
+ mutex_unlock(&cptpf->lock);
return ret;
- } else if (ret) {
- dev_err(&cptpf->pdev->dev, "RVU MBOX error: %d.\n", ret);
- return -EFAULT;
}
+ mutex_unlock(&cptpf->lock);
return 0;
}
@@ -204,6 +211,10 @@ void otx2_cptpf_vfpf_mbox_handler(struct work_struct *work)
if (err == -ENOMEM || err == -EIO)
break;
offset = msg->next_msgoff;
+ /* Write barrier required for VF responses which are handled by
+ * PF driver and not forwarded to AF.
+ */
+ smp_wmb();
}
/* Send mbox responses to VF */
if (mdev->num_msgs)
@@ -350,6 +361,8 @@ void otx2_cptpf_afpf_mbox_handler(struct work_struct *work)
process_afpf_mbox_msg(cptpf, msg);
offset = msg->next_msgoff;
+ /* Sync VF response ready to be sent */
+ smp_wmb();
mdev->msgs_acked++;
}
otx2_mbox_reset(afpf_mbox, 0);
diff --git a/drivers/crypto/marvell/octeontx2/otx2_cptpf_ucode.c b/drivers/crypto/marvell/octeontx2/otx2_cptpf_ucode.c
index 4c8ebdf671ca..9cba2f714c7e 100644
--- a/drivers/crypto/marvell/octeontx2/otx2_cptpf_ucode.c
+++ b/drivers/crypto/marvell/octeontx2/otx2_cptpf_ucode.c
@@ -1076,6 +1076,39 @@ static void delete_engine_grps(struct pci_dev *pdev,
delete_engine_group(&pdev->dev, &eng_grps->grp[i]);
}
+#define PCI_DEVID_CN10K_RNM 0xA098
+#define RNM_ENTROPY_STATUS 0x8
+
+static void rnm_to_cpt_errata_fixup(struct device *dev)
+{
+ struct pci_dev *pdev;
+ void __iomem *base;
+ int timeout = 5000;
+
+ pdev = pci_get_device(PCI_VENDOR_ID_CAVIUM, PCI_DEVID_CN10K_RNM, NULL);
+ if (!pdev)
+ return;
+
+ base = pci_ioremap_bar(pdev, 0);
+ if (!base)
+ goto put_pdev;
+
+ while ((readq(base + RNM_ENTROPY_STATUS) & 0x7F) != 0x40) {
+ cpu_relax();
+ udelay(1);
+ timeout--;
+ if (!timeout) {
+ dev_warn(dev, "RNM is not producing entropy\n");
+ break;
+ }
+ }
+
+ iounmap(base);
+
+put_pdev:
+ pci_dev_put(pdev);
+}
+
int otx2_cpt_get_eng_grp(struct otx2_cpt_eng_grps *eng_grps, int eng_type)
{
@@ -1111,6 +1144,7 @@ int otx2_cpt_create_eng_grps(struct otx2_cptpf_dev *cptpf,
struct otx2_cpt_engines engs[OTX2_CPT_MAX_ETYPES_PER_GRP] = { {0} };
struct pci_dev *pdev = cptpf->pdev;
struct fw_info_t fw_info;
+ u64 reg_val;
int ret = 0;
mutex_lock(&eng_grps->lock);
@@ -1189,9 +1223,17 @@ int otx2_cpt_create_eng_grps(struct otx2_cptpf_dev *cptpf,
if (is_dev_otx2(pdev))
goto unlock;
+
+ /*
+ * Ensure RNM_ENTROPY_STATUS[NORMAL_CNT] = 0x40 before writing
+ * CPT_AF_CTL[RNM_REQ_EN] = 1 as a workaround for HW errata.
+ */
+ rnm_to_cpt_errata_fixup(&pdev->dev);
+
/*
* Configure engine group mask to allow context prefetching
- * for the groups.
+ * for the groups and enable random number request, to enable
+ * CPT to request random numbers from RNM.
*/
otx2_cpt_write_af_reg(&cptpf->afpf_mbox, pdev, CPT_AF_CTL,
OTX2_CPT_ALL_ENG_GRPS_MASK << 3 | BIT_ULL(16),
@@ -1203,6 +1245,18 @@ int otx2_cpt_create_eng_grps(struct otx2_cptpf_dev *cptpf,
*/
otx2_cpt_write_af_reg(&cptpf->afpf_mbox, pdev, CPT_AF_CTX_FLUSH_TIMER,
CTX_FLUSH_TIMER_CNT, BLKADDR_CPT0);
+
+ /*
+ * Set CPT_AF_DIAG[FLT_DIS], as a workaround for HW errata, when
+ * CPT_AF_DIAG[FLT_DIS] = 0 and a CPT engine access to LLC/DRAM
+ * encounters a fault/poison, a rare case may result in
+ * unpredictable data being delivered to a CPT engine.
+ */
+ otx2_cpt_read_af_reg(&cptpf->afpf_mbox, pdev, CPT_AF_DIAG, &reg_val,
+ BLKADDR_CPT0);
+ otx2_cpt_write_af_reg(&cptpf->afpf_mbox, pdev, CPT_AF_DIAG,
+ reg_val | BIT_ULL(24), BLKADDR_CPT0);
+
mutex_unlock(&eng_grps->lock);
return 0;
@@ -1753,7 +1807,6 @@ void otx2_cpt_print_uc_dbg_info(struct otx2_cptpf_dev *cptpf)
char engs_info[2 * OTX2_CPT_NAME_LENGTH];
struct otx2_cpt_eng_grp_info *grp;
struct otx2_cpt_engs_rsvd *engs;
- u32 mask[4];
int i, j;
pr_debug("Engine groups global info");
@@ -1785,6 +1838,8 @@ void otx2_cpt_print_uc_dbg_info(struct otx2_cptpf_dev *cptpf)
for (j = 0; j < OTX2_CPT_MAX_ETYPES_PER_GRP; j++) {
engs = &grp->engs[j];
if (engs->type) {
+ u32 mask[5] = { };
+
get_engs_info(grp, engs_info,
2 * OTX2_CPT_NAME_LENGTH, j);
pr_debug("Slot%d: %s", j, engs_info);
diff --git a/drivers/crypto/marvell/octeontx2/otx2_cptvf_algs.c b/drivers/crypto/marvell/octeontx2/otx2_cptvf_algs.c
index 2748a3327e39..f8f8542ce3e4 100644
--- a/drivers/crypto/marvell/octeontx2/otx2_cptvf_algs.c
+++ b/drivers/crypto/marvell/octeontx2/otx2_cptvf_algs.c
@@ -1634,16 +1634,13 @@ static inline int cpt_register_algs(void)
{
int i, err = 0;
- if (!IS_ENABLED(CONFIG_DM_CRYPT)) {
- for (i = 0; i < ARRAY_SIZE(otx2_cpt_skciphers); i++)
- otx2_cpt_skciphers[i].base.cra_flags &=
- ~CRYPTO_ALG_DEAD;
-
- err = crypto_register_skciphers(otx2_cpt_skciphers,
- ARRAY_SIZE(otx2_cpt_skciphers));
- if (err)
- return err;
- }
+ for (i = 0; i < ARRAY_SIZE(otx2_cpt_skciphers); i++)
+ otx2_cpt_skciphers[i].base.cra_flags &= ~CRYPTO_ALG_DEAD;
+
+ err = crypto_register_skciphers(otx2_cpt_skciphers,
+ ARRAY_SIZE(otx2_cpt_skciphers));
+ if (err)
+ return err;
for (i = 0; i < ARRAY_SIZE(otx2_cpt_aeads); i++)
otx2_cpt_aeads[i].base.cra_flags &= ~CRYPTO_ALG_DEAD;
diff --git a/drivers/crypto/mxs-dcp.c b/drivers/crypto/mxs-dcp.c
index d19e5ffb5104..d6f9e2fe863d 100644
--- a/drivers/crypto/mxs-dcp.c
+++ b/drivers/crypto/mxs-dcp.c
@@ -331,7 +331,7 @@ static int mxs_dcp_aes_block_crypt(struct crypto_async_request *arq)
memset(key + AES_KEYSIZE_128, 0, AES_KEYSIZE_128);
}
- for_each_sg(req->src, src, sg_nents(src), i) {
+ for_each_sg(req->src, src, sg_nents(req->src), i) {
src_buf = sg_virt(src);
len = sg_dma_len(src);
tlen += len;
diff --git a/drivers/crypto/nx/nx-common-pseries.c b/drivers/crypto/nx/nx-common-pseries.c
index 4e304f6081e4..7584a34ba88c 100644
--- a/drivers/crypto/nx/nx-common-pseries.c
+++ b/drivers/crypto/nx/nx-common-pseries.c
@@ -962,7 +962,7 @@ static struct attribute *nx842_sysfs_entries[] = {
NULL,
};
-static struct attribute_group nx842_attribute_group = {
+static const struct attribute_group nx842_attribute_group = {
.name = NULL, /* put in device directory */
.attrs = nx842_sysfs_entries,
};
@@ -992,7 +992,7 @@ static struct attribute *nxcop_caps_sysfs_entries[] = {
NULL,
};
-static struct attribute_group nxcop_caps_attr_group = {
+static const struct attribute_group nxcop_caps_attr_group = {
.name = "nx_gzip_caps",
.attrs = nxcop_caps_sysfs_entries,
};
diff --git a/drivers/crypto/omap-aes.c b/drivers/crypto/omap-aes.c
index a196bb8b1701..581211a92628 100644
--- a/drivers/crypto/omap-aes.c
+++ b/drivers/crypto/omap-aes.c
@@ -1093,7 +1093,7 @@ static struct attribute *omap_aes_attrs[] = {
NULL,
};
-static struct attribute_group omap_aes_attr_group = {
+static const struct attribute_group omap_aes_attr_group = {
.attrs = omap_aes_attrs,
};
diff --git a/drivers/crypto/omap-sham.c b/drivers/crypto/omap-sham.c
index f6bf53c00b61..4b37dc69a50c 100644
--- a/drivers/crypto/omap-sham.c
+++ b/drivers/crypto/omap-sham.c
@@ -2045,7 +2045,7 @@ static struct attribute *omap_sham_attrs[] = {
NULL,
};
-static struct attribute_group omap_sham_attr_group = {
+static const struct attribute_group omap_sham_attr_group = {
.attrs = omap_sham_attrs,
};
diff --git a/drivers/crypto/qat/qat_4xxx/adf_4xxx_hw_data.c b/drivers/crypto/qat/qat_4xxx/adf_4xxx_hw_data.c
index 6d10edc40aca..fb5970a68484 100644
--- a/drivers/crypto/qat/qat_4xxx/adf_4xxx_hw_data.c
+++ b/drivers/crypto/qat/qat_4xxx/adf_4xxx_hw_data.c
@@ -6,6 +6,7 @@
#include <adf_common_drv.h>
#include <adf_gen4_hw_data.h>
#include <adf_gen4_pfvf.h>
+#include <adf_gen4_pm.h>
#include "adf_4xxx_hw_data.h"
#include "icp_qat_hw.h"
@@ -52,7 +53,7 @@ static const char *const dev_cfg_services[] = {
static int get_service_enabled(struct adf_accel_dev *accel_dev)
{
char services[ADF_CFG_MAX_VAL_LEN_IN_BYTES] = {0};
- u32 ret;
+ int ret;
ret = adf_cfg_get_param_value(accel_dev, ADF_GENERAL_SEC,
ADF_SERVICES_ENABLED, services);
@@ -229,7 +230,7 @@ static void adf_enable_error_correction(struct adf_accel_dev *accel_dev)
void __iomem *csr = misc_bar->virt_addr;
/* Enable all in errsou3 except VFLR notification on host */
- ADF_CSR_WR(csr, ADF_4XXX_ERRMSK3, ADF_4XXX_VFLNOTIFY);
+ ADF_CSR_WR(csr, ADF_GEN4_ERRMSK3, ADF_GEN4_VFLNOTIFY);
}
static void adf_enable_ints(struct adf_accel_dev *accel_dev)
@@ -256,19 +257,19 @@ static int adf_init_device(struct adf_accel_dev *accel_dev)
addr = (&GET_BARS(accel_dev)[ADF_4XXX_PMISC_BAR])->virt_addr;
/* Temporarily mask PM interrupt */
- csr = ADF_CSR_RD(addr, ADF_4XXX_ERRMSK2);
- csr |= ADF_4XXX_PM_SOU;
- ADF_CSR_WR(addr, ADF_4XXX_ERRMSK2, csr);
+ csr = ADF_CSR_RD(addr, ADF_GEN4_ERRMSK2);
+ csr |= ADF_GEN4_PM_SOU;
+ ADF_CSR_WR(addr, ADF_GEN4_ERRMSK2, csr);
/* Set DRV_ACTIVE bit to power up the device */
- ADF_CSR_WR(addr, ADF_4XXX_PM_INTERRUPT, ADF_4XXX_PM_DRV_ACTIVE);
+ ADF_CSR_WR(addr, ADF_GEN4_PM_INTERRUPT, ADF_GEN4_PM_DRV_ACTIVE);
/* Poll status register to make sure the device is powered up */
ret = read_poll_timeout(ADF_CSR_RD, status,
- status & ADF_4XXX_PM_INIT_STATE,
- ADF_4XXX_PM_POLL_DELAY_US,
- ADF_4XXX_PM_POLL_TIMEOUT_US, true, addr,
- ADF_4XXX_PM_STATUS);
+ status & ADF_GEN4_PM_INIT_STATE,
+ ADF_GEN4_PM_POLL_DELAY_US,
+ ADF_GEN4_PM_POLL_TIMEOUT_US, true, addr,
+ ADF_GEN4_PM_STATUS);
if (ret)
dev_err(&GET_DEV(accel_dev), "Failed to power up the device\n");
@@ -354,6 +355,8 @@ void adf_init_hw_data_4xxx(struct adf_hw_device_data *hw_data)
hw_data->set_ssm_wdtimer = adf_gen4_set_ssm_wdtimer;
hw_data->disable_iov = adf_disable_sriov;
hw_data->ring_pair_reset = adf_gen4_ring_pair_reset;
+ hw_data->enable_pm = adf_gen4_enable_pm;
+ hw_data->handle_pm_interrupt = adf_gen4_handle_pm_interrupt;
adf_gen4_init_hw_csr_ops(&hw_data->csr_ops);
adf_gen4_init_pf_pfvf_ops(&hw_data->pfvf_ops);
diff --git a/drivers/crypto/qat/qat_4xxx/adf_4xxx_hw_data.h b/drivers/crypto/qat/qat_4xxx/adf_4xxx_hw_data.h
index 12e4fb9b40ce..1034752845ca 100644
--- a/drivers/crypto/qat/qat_4xxx/adf_4xxx_hw_data.h
+++ b/drivers/crypto/qat/qat_4xxx/adf_4xxx_hw_data.h
@@ -39,20 +39,6 @@
#define ADF_4XXX_NUM_RINGS_PER_BANK 2
#define ADF_4XXX_NUM_BANKS_PER_VF 4
-/* Error source registers */
-#define ADF_4XXX_ERRSOU0 (0x41A200)
-#define ADF_4XXX_ERRSOU1 (0x41A204)
-#define ADF_4XXX_ERRSOU2 (0x41A208)
-#define ADF_4XXX_ERRSOU3 (0x41A20C)
-
-/* Error source mask registers */
-#define ADF_4XXX_ERRMSK0 (0x41A210)
-#define ADF_4XXX_ERRMSK1 (0x41A214)
-#define ADF_4XXX_ERRMSK2 (0x41A218)
-#define ADF_4XXX_ERRMSK3 (0x41A21C)
-
-#define ADF_4XXX_VFLNOTIFY BIT(7)
-
/* Arbiter configuration */
#define ADF_4XXX_ARB_CONFIG (BIT(31) | BIT(6) | BIT(0))
#define ADF_4XXX_ARB_OFFSET (0x0)
@@ -63,16 +49,6 @@
#define ADF_4XXX_ADMINMSGLR_OFFSET (0x500578)
#define ADF_4XXX_MAILBOX_BASE_OFFSET (0x600970)
-/* Power management */
-#define ADF_4XXX_PM_POLL_DELAY_US 20
-#define ADF_4XXX_PM_POLL_TIMEOUT_US USEC_PER_SEC
-#define ADF_4XXX_PM_STATUS (0x50A00C)
-#define ADF_4XXX_PM_INTERRUPT (0x50A028)
-#define ADF_4XXX_PM_DRV_ACTIVE BIT(20)
-#define ADF_4XXX_PM_INIT_STATE BIT(21)
-/* Power management source in ERRSOU2 and ERRMSK2 */
-#define ADF_4XXX_PM_SOU BIT(18)
-
/* Firmware Binaries */
#define ADF_4XXX_FW "qat_4xxx.bin"
#define ADF_4XXX_MMP "qat_4xxx_mmp.bin"
diff --git a/drivers/crypto/qat/qat_4xxx/adf_drv.c b/drivers/crypto/qat/qat_4xxx/adf_drv.c
index a6c78b9c730b..fa4c350c1bf9 100644
--- a/drivers/crypto/qat/qat_4xxx/adf_drv.c
+++ b/drivers/crypto/qat/qat_4xxx/adf_drv.c
@@ -75,6 +75,13 @@ static int adf_crypto_dev_config(struct adf_accel_dev *accel_dev)
if (ret)
goto err;
+ /* Temporarily set the number of crypto instances to zero to avoid
+ * registering the crypto algorithms.
+ * This will be removed when the algorithms will support the
+ * CRYPTO_TFM_REQ_MAY_BACKLOG flag
+ */
+ instances = 0;
+
for (i = 0; i < instances; i++) {
val = i;
bank = i * 2;
diff --git a/drivers/crypto/qat/qat_common/Makefile b/drivers/crypto/qat/qat_common/Makefile
index 7e191a42a5c7..f25a6c8edfc7 100644
--- a/drivers/crypto/qat/qat_common/Makefile
+++ b/drivers/crypto/qat/qat_common/Makefile
@@ -12,6 +12,7 @@ intel_qat-objs := adf_cfg.o \
adf_hw_arbiter.o \
adf_gen2_hw_data.o \
adf_gen4_hw_data.o \
+ adf_gen4_pm.o \
qat_crypto.o \
qat_algs.o \
qat_asym_algs.o \
diff --git a/drivers/crypto/qat/qat_common/adf_accel_devices.h b/drivers/crypto/qat/qat_common/adf_accel_devices.h
index 2d4cd7c7cf33..a03c6cf72331 100644
--- a/drivers/crypto/qat/qat_common/adf_accel_devices.h
+++ b/drivers/crypto/qat/qat_common/adf_accel_devices.h
@@ -184,6 +184,8 @@ struct adf_hw_device_data {
void (*exit_arb)(struct adf_accel_dev *accel_dev);
const u32 *(*get_arb_mapping)(void);
int (*init_device)(struct adf_accel_dev *accel_dev);
+ int (*enable_pm)(struct adf_accel_dev *accel_dev);
+ bool (*handle_pm_interrupt)(struct adf_accel_dev *accel_dev);
void (*disable_iov)(struct adf_accel_dev *accel_dev);
void (*configure_iov_threads)(struct adf_accel_dev *accel_dev,
bool enable);
diff --git a/drivers/crypto/qat/qat_common/adf_admin.c b/drivers/crypto/qat/qat_common/adf_admin.c
index 498eb6f690e3..3b6184c35081 100644
--- a/drivers/crypto/qat/qat_common/adf_admin.c
+++ b/drivers/crypto/qat/qat_common/adf_admin.c
@@ -251,6 +251,43 @@ int adf_send_admin_init(struct adf_accel_dev *accel_dev)
}
EXPORT_SYMBOL_GPL(adf_send_admin_init);
+/**
+ * adf_init_admin_pm() - Function sends PM init message to FW
+ * @accel_dev: Pointer to acceleration device.
+ * @idle_delay: QAT HW idle time before power gating is initiated.
+ * 000 - 64us
+ * 001 - 128us
+ * 010 - 256us
+ * 011 - 512us
+ * 100 - 1ms
+ * 101 - 2ms
+ * 110 - 4ms
+ * 111 - 8ms
+ *
+ * Function sends to the FW the admin init message for the PM state
+ * configuration.
+ *
+ * Return: 0 on success, error code otherwise.
+ */
+int adf_init_admin_pm(struct adf_accel_dev *accel_dev, u32 idle_delay)
+{
+ struct adf_hw_device_data *hw_data = accel_dev->hw_device;
+ struct icp_qat_fw_init_admin_resp resp = {0};
+ struct icp_qat_fw_init_admin_req req = {0};
+ u32 ae_mask = hw_data->admin_ae_mask;
+
+ if (!accel_dev->admin) {
+ dev_err(&GET_DEV(accel_dev), "adf_admin is not available\n");
+ return -EFAULT;
+ }
+
+ req.cmd_id = ICP_QAT_FW_PM_STATE_CONFIG;
+ req.idle_filter = idle_delay;
+
+ return adf_send_admin(accel_dev, &req, &resp, ae_mask);
+}
+EXPORT_SYMBOL_GPL(adf_init_admin_pm);
+
int adf_init_admin_comms(struct adf_accel_dev *accel_dev)
{
struct adf_admin_comms *admin;
diff --git a/drivers/crypto/qat/qat_common/adf_common_drv.h b/drivers/crypto/qat/qat_common/adf_common_drv.h
index 76f4f96ec5eb..e8c9b77c0d66 100644
--- a/drivers/crypto/qat/qat_common/adf_common_drv.h
+++ b/drivers/crypto/qat/qat_common/adf_common_drv.h
@@ -102,6 +102,7 @@ void adf_exit_aer(void);
int adf_init_admin_comms(struct adf_accel_dev *accel_dev);
void adf_exit_admin_comms(struct adf_accel_dev *accel_dev);
int adf_send_admin_init(struct adf_accel_dev *accel_dev);
+int adf_init_admin_pm(struct adf_accel_dev *accel_dev, u32 idle_delay);
int adf_init_arb(struct adf_accel_dev *accel_dev);
void adf_exit_arb(struct adf_accel_dev *accel_dev);
void adf_update_ring_arb(struct adf_etr_ring_data *ring);
@@ -188,6 +189,9 @@ int qat_uclo_map_obj(struct icp_qat_fw_loader_handle *handle,
void *addr_ptr, u32 mem_size, char *obj_name);
int qat_uclo_set_cfg_ae_mask(struct icp_qat_fw_loader_handle *handle,
unsigned int cfg_ae_mask);
+int adf_init_misc_wq(void);
+void adf_exit_misc_wq(void);
+bool adf_misc_wq_queue_work(struct work_struct *work);
#if defined(CONFIG_PCI_IOV)
int adf_sriov_configure(struct pci_dev *pdev, int numvfs);
void adf_disable_sriov(struct adf_accel_dev *accel_dev);
diff --git a/drivers/crypto/qat/qat_common/adf_ctl_drv.c b/drivers/crypto/qat/qat_common/adf_ctl_drv.c
index 6f64aa693146..e8ac932bbaab 100644
--- a/drivers/crypto/qat/qat_common/adf_ctl_drv.c
+++ b/drivers/crypto/qat/qat_common/adf_ctl_drv.c
@@ -419,6 +419,9 @@ static int __init adf_register_ctl_device_driver(void)
if (adf_chr_drv_create())
goto err_chr_dev;
+ if (adf_init_misc_wq())
+ goto err_misc_wq;
+
if (adf_init_aer())
goto err_aer;
@@ -440,6 +443,8 @@ err_vf_wq:
err_pf_wq:
adf_exit_aer();
err_aer:
+ adf_exit_misc_wq();
+err_misc_wq:
adf_chr_drv_destroy();
err_chr_dev:
mutex_destroy(&adf_ctl_lock);
@@ -449,6 +454,7 @@ err_chr_dev:
static void __exit adf_unregister_ctl_device_driver(void)
{
adf_chr_drv_destroy();
+ adf_exit_misc_wq();
adf_exit_aer();
adf_exit_vf_wq();
adf_exit_pf_wq();
diff --git a/drivers/crypto/qat/qat_common/adf_gen4_hw_data.h b/drivers/crypto/qat/qat_common/adf_gen4_hw_data.h
index f0f71ca44ca3..43b8f864806b 100644
--- a/drivers/crypto/qat/qat_common/adf_gen4_hw_data.h
+++ b/drivers/crypto/qat/qat_common/adf_gen4_hw_data.h
@@ -122,6 +122,20 @@ do { \
#define ADF_WQM_CSR_RPRESETSTS_STATUS BIT(0)
#define ADF_WQM_CSR_RPRESETSTS(bank) (ADF_WQM_CSR_RPRESETCTL(bank) + 4)
+/* Error source registers */
+#define ADF_GEN4_ERRSOU0 (0x41A200)
+#define ADF_GEN4_ERRSOU1 (0x41A204)
+#define ADF_GEN4_ERRSOU2 (0x41A208)
+#define ADF_GEN4_ERRSOU3 (0x41A20C)
+
+/* Error source mask registers */
+#define ADF_GEN4_ERRMSK0 (0x41A210)
+#define ADF_GEN4_ERRMSK1 (0x41A214)
+#define ADF_GEN4_ERRMSK2 (0x41A218)
+#define ADF_GEN4_ERRMSK3 (0x41A21C)
+
+#define ADF_GEN4_VFLNOTIFY BIT(7)
+
void adf_gen4_set_ssm_wdtimer(struct adf_accel_dev *accel_dev);
void adf_gen4_init_hw_csr_ops(struct adf_hw_csr_ops *csr_ops);
int adf_gen4_ring_pair_reset(struct adf_accel_dev *accel_dev, u32 bank_number);
diff --git a/drivers/crypto/qat/qat_common/adf_gen4_pfvf.c b/drivers/crypto/qat/qat_common/adf_gen4_pfvf.c
index 8efbedf63bc8..d80d493a7756 100644
--- a/drivers/crypto/qat/qat_common/adf_gen4_pfvf.c
+++ b/drivers/crypto/qat/qat_common/adf_gen4_pfvf.c
@@ -9,15 +9,12 @@
#include "adf_pfvf_pf_proto.h"
#include "adf_pfvf_utils.h"
-#define ADF_4XXX_MAX_NUM_VFS 16
-
#define ADF_4XXX_PF2VM_OFFSET(i) (0x40B010 + ((i) * 0x20))
#define ADF_4XXX_VM2PF_OFFSET(i) (0x40B014 + ((i) * 0x20))
/* VF2PF interrupt source registers */
-#define ADF_4XXX_VM2PF_SOU(i) (0x41A180 + ((i) * 4))
-#define ADF_4XXX_VM2PF_MSK(i) (0x41A1C0 + ((i) * 4))
-#define ADF_4XXX_VM2PF_INT_EN_MSK BIT(0)
+#define ADF_4XXX_VM2PF_SOU 0x41A180
+#define ADF_4XXX_VM2PF_MSK 0x41A1C0
#define ADF_PFVF_GEN4_MSGTYPE_SHIFT 2
#define ADF_PFVF_GEN4_MSGTYPE_MASK 0x3F
@@ -41,51 +38,30 @@ static u32 adf_gen4_pf_get_vf2pf_offset(u32 i)
static u32 adf_gen4_get_vf2pf_sources(void __iomem *pmisc_addr)
{
- int i;
u32 sou, mask;
- int num_csrs = ADF_4XXX_MAX_NUM_VFS;
- u32 vf_mask = 0;
- for (i = 0; i < num_csrs; i++) {
- sou = ADF_CSR_RD(pmisc_addr, ADF_4XXX_VM2PF_SOU(i));
- mask = ADF_CSR_RD(pmisc_addr, ADF_4XXX_VM2PF_MSK(i));
- sou &= ~mask;
- vf_mask |= sou << i;
- }
+ sou = ADF_CSR_RD(pmisc_addr, ADF_4XXX_VM2PF_SOU);
+ mask = ADF_CSR_RD(pmisc_addr, ADF_4XXX_VM2PF_MSK);
- return vf_mask;
+ return sou & ~mask;
}
static void adf_gen4_enable_vf2pf_interrupts(void __iomem *pmisc_addr,
u32 vf_mask)
{
- int num_csrs = ADF_4XXX_MAX_NUM_VFS;
- unsigned long mask = vf_mask;
unsigned int val;
- int i;
-
- for_each_set_bit(i, &mask, num_csrs) {
- unsigned int offset = ADF_4XXX_VM2PF_MSK(i);
- val = ADF_CSR_RD(pmisc_addr, offset) & ~ADF_4XXX_VM2PF_INT_EN_MSK;
- ADF_CSR_WR(pmisc_addr, offset, val);
- }
+ val = ADF_CSR_RD(pmisc_addr, ADF_4XXX_VM2PF_MSK) & ~vf_mask;
+ ADF_CSR_WR(pmisc_addr, ADF_4XXX_VM2PF_MSK, val);
}
static void adf_gen4_disable_vf2pf_interrupts(void __iomem *pmisc_addr,
u32 vf_mask)
{
- int num_csrs = ADF_4XXX_MAX_NUM_VFS;
- unsigned long mask = vf_mask;
unsigned int val;
- int i;
-
- for_each_set_bit(i, &mask, num_csrs) {
- unsigned int offset = ADF_4XXX_VM2PF_MSK(i);
- val = ADF_CSR_RD(pmisc_addr, offset) | ADF_4XXX_VM2PF_INT_EN_MSK;
- ADF_CSR_WR(pmisc_addr, offset, val);
- }
+ val = ADF_CSR_RD(pmisc_addr, ADF_4XXX_VM2PF_MSK) | vf_mask;
+ ADF_CSR_WR(pmisc_addr, ADF_4XXX_VM2PF_MSK, val);
}
static int adf_gen4_pfvf_send(struct adf_accel_dev *accel_dev,
diff --git a/drivers/crypto/qat/qat_common/adf_gen4_pm.c b/drivers/crypto/qat/qat_common/adf_gen4_pm.c
new file mode 100644
index 000000000000..7037c0892a8a
--- /dev/null
+++ b/drivers/crypto/qat/qat_common/adf_gen4_pm.c
@@ -0,0 +1,137 @@
+// SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0-only)
+/* Copyright(c) 2022 Intel Corporation */
+#include <linux/bitfield.h>
+#include <linux/iopoll.h>
+#include "adf_accel_devices.h"
+#include "adf_common_drv.h"
+#include "adf_gen4_pm.h"
+#include "adf_cfg_strings.h"
+#include "icp_qat_fw_init_admin.h"
+#include "adf_gen4_hw_data.h"
+#include "adf_cfg.h"
+
+enum qat_pm_host_msg {
+ PM_NO_CHANGE = 0,
+ PM_SET_MIN,
+};
+
+struct adf_gen4_pm_data {
+ struct work_struct pm_irq_work;
+ struct adf_accel_dev *accel_dev;
+ u32 pm_int_sts;
+};
+
+static int send_host_msg(struct adf_accel_dev *accel_dev)
+{
+ void __iomem *pmisc = adf_get_pmisc_base(accel_dev);
+ u32 msg;
+
+ msg = ADF_CSR_RD(pmisc, ADF_GEN4_PM_HOST_MSG);
+ if (msg & ADF_GEN4_PM_MSG_PENDING)
+ return -EBUSY;
+
+ /* Send HOST_MSG */
+ msg = FIELD_PREP(ADF_GEN4_PM_MSG_PAYLOAD_BIT_MASK, PM_SET_MIN);
+ msg |= ADF_GEN4_PM_MSG_PENDING;
+ ADF_CSR_WR(pmisc, ADF_GEN4_PM_HOST_MSG, msg);
+
+ /* Poll status register to make sure the HOST_MSG has been processed */
+ return read_poll_timeout(ADF_CSR_RD, msg,
+ !(msg & ADF_GEN4_PM_MSG_PENDING),
+ ADF_GEN4_PM_MSG_POLL_DELAY_US,
+ ADF_GEN4_PM_POLL_TIMEOUT_US, true, pmisc,
+ ADF_GEN4_PM_HOST_MSG);
+}
+
+static void pm_bh_handler(struct work_struct *work)
+{
+ struct adf_gen4_pm_data *pm_data =
+ container_of(work, struct adf_gen4_pm_data, pm_irq_work);
+ struct adf_accel_dev *accel_dev = pm_data->accel_dev;
+ void __iomem *pmisc = adf_get_pmisc_base(accel_dev);
+ u32 pm_int_sts = pm_data->pm_int_sts;
+ u32 val;
+
+ /* PM Idle interrupt */
+ if (pm_int_sts & ADF_GEN4_PM_IDLE_STS) {
+ /* Issue host message to FW */
+ if (send_host_msg(accel_dev))
+ dev_warn_ratelimited(&GET_DEV(accel_dev),
+ "Failed to send host msg to FW\n");
+ }
+
+ /* Clear interrupt status */
+ ADF_CSR_WR(pmisc, ADF_GEN4_PM_INTERRUPT, pm_int_sts);
+
+ /* Reenable PM interrupt */
+ val = ADF_CSR_RD(pmisc, ADF_GEN4_ERRMSK2);
+ val &= ~ADF_GEN4_PM_SOU;
+ ADF_CSR_WR(pmisc, ADF_GEN4_ERRMSK2, val);
+
+ kfree(pm_data);
+}
+
+bool adf_gen4_handle_pm_interrupt(struct adf_accel_dev *accel_dev)
+{
+ void __iomem *pmisc = adf_get_pmisc_base(accel_dev);
+ struct adf_gen4_pm_data *pm_data = NULL;
+ u32 errsou2;
+ u32 errmsk2;
+ u32 val;
+
+ /* Only handle the interrupt triggered by PM */
+ errmsk2 = ADF_CSR_RD(pmisc, ADF_GEN4_ERRMSK2);
+ if (errmsk2 & ADF_GEN4_PM_SOU)
+ return false;
+
+ errsou2 = ADF_CSR_RD(pmisc, ADF_GEN4_ERRSOU2);
+ if (!(errsou2 & ADF_GEN4_PM_SOU))
+ return false;
+
+ /* Disable interrupt */
+ val = ADF_CSR_RD(pmisc, ADF_GEN4_ERRMSK2);
+ val |= ADF_GEN4_PM_SOU;
+ ADF_CSR_WR(pmisc, ADF_GEN4_ERRMSK2, val);
+
+ val = ADF_CSR_RD(pmisc, ADF_GEN4_PM_INTERRUPT);
+
+ pm_data = kzalloc(sizeof(*pm_data), GFP_ATOMIC);
+ if (!pm_data)
+ return false;
+
+ pm_data->pm_int_sts = val;
+ pm_data->accel_dev = accel_dev;
+
+ INIT_WORK(&pm_data->pm_irq_work, pm_bh_handler);
+ adf_misc_wq_queue_work(&pm_data->pm_irq_work);
+
+ return true;
+}
+EXPORT_SYMBOL_GPL(adf_gen4_handle_pm_interrupt);
+
+int adf_gen4_enable_pm(struct adf_accel_dev *accel_dev)
+{
+ void __iomem *pmisc = adf_get_pmisc_base(accel_dev);
+ int ret;
+ u32 val;
+
+ ret = adf_init_admin_pm(accel_dev, ADF_GEN4_PM_DEFAULT_IDLE_FILTER);
+ if (ret)
+ return ret;
+
+ /* Enable default PM interrupts: IDLE, THROTTLE */
+ val = ADF_CSR_RD(pmisc, ADF_GEN4_PM_INTERRUPT);
+ val |= ADF_GEN4_PM_INT_EN_DEFAULT;
+
+ /* Clear interrupt status */
+ val |= ADF_GEN4_PM_INT_STS_MASK;
+ ADF_CSR_WR(pmisc, ADF_GEN4_PM_INTERRUPT, val);
+
+ /* Unmask PM Interrupt */
+ val = ADF_CSR_RD(pmisc, ADF_GEN4_ERRMSK2);
+ val &= ~ADF_GEN4_PM_SOU;
+ ADF_CSR_WR(pmisc, ADF_GEN4_ERRMSK2, val);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(adf_gen4_enable_pm);
diff --git a/drivers/crypto/qat/qat_common/adf_gen4_pm.h b/drivers/crypto/qat/qat_common/adf_gen4_pm.h
new file mode 100644
index 000000000000..f8f8a9ee29e5
--- /dev/null
+++ b/drivers/crypto/qat/qat_common/adf_gen4_pm.h
@@ -0,0 +1,44 @@
+/* SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0-only) */
+/* Copyright(c) 2022 Intel Corporation */
+#ifndef ADF_GEN4_PM_H
+#define ADF_GEN4_PM_H
+
+#include "adf_accel_devices.h"
+
+/* Power management registers */
+#define ADF_GEN4_PM_HOST_MSG (0x50A01C)
+
+/* Power management */
+#define ADF_GEN4_PM_POLL_DELAY_US 20
+#define ADF_GEN4_PM_POLL_TIMEOUT_US USEC_PER_SEC
+#define ADF_GEN4_PM_MSG_POLL_DELAY_US (10 * USEC_PER_MSEC)
+#define ADF_GEN4_PM_STATUS (0x50A00C)
+#define ADF_GEN4_PM_INTERRUPT (0x50A028)
+
+/* Power management source in ERRSOU2 and ERRMSK2 */
+#define ADF_GEN4_PM_SOU BIT(18)
+
+#define ADF_GEN4_PM_IDLE_INT_EN BIT(18)
+#define ADF_GEN4_PM_THROTTLE_INT_EN BIT(19)
+#define ADF_GEN4_PM_DRV_ACTIVE BIT(20)
+#define ADF_GEN4_PM_INIT_STATE BIT(21)
+#define ADF_GEN4_PM_INT_EN_DEFAULT (ADF_GEN4_PM_IDLE_INT_EN | \
+ ADF_GEN4_PM_THROTTLE_INT_EN)
+
+#define ADF_GEN4_PM_THR_STS BIT(0)
+#define ADF_GEN4_PM_IDLE_STS BIT(1)
+#define ADF_GEN4_PM_FW_INT_STS BIT(2)
+#define ADF_GEN4_PM_INT_STS_MASK (ADF_GEN4_PM_THR_STS | \
+ ADF_GEN4_PM_IDLE_STS | \
+ ADF_GEN4_PM_FW_INT_STS)
+
+#define ADF_GEN4_PM_MSG_PENDING BIT(0)
+#define ADF_GEN4_PM_MSG_PAYLOAD_BIT_MASK GENMASK(28, 1)
+
+#define ADF_GEN4_PM_DEFAULT_IDLE_FILTER (0x0)
+#define ADF_GEN4_PM_MAX_IDLE_FILTER (0x7)
+
+int adf_gen4_enable_pm(struct adf_accel_dev *accel_dev);
+bool adf_gen4_handle_pm_interrupt(struct adf_accel_dev *accel_dev);
+
+#endif
diff --git a/drivers/crypto/qat/qat_common/adf_init.c b/drivers/crypto/qat/qat_common/adf_init.c
index 2edc63c6b6ca..c2c718f1b489 100644
--- a/drivers/crypto/qat/qat_common/adf_init.c
+++ b/drivers/crypto/qat/qat_common/adf_init.c
@@ -181,6 +181,12 @@ int adf_dev_start(struct adf_accel_dev *accel_dev)
if (hw_data->set_ssm_wdtimer)
hw_data->set_ssm_wdtimer(accel_dev);
+ /* Enable Power Management */
+ if (hw_data->enable_pm && hw_data->enable_pm(accel_dev)) {
+ dev_err(&GET_DEV(accel_dev), "Failed to configure Power Management\n");
+ return -EFAULT;
+ }
+
list_for_each(list_itr, &service_table) {
service = list_entry(list_itr, struct service_hndl, list);
if (service->event_hld(accel_dev, ADF_EVENT_START)) {
diff --git a/drivers/crypto/qat/qat_common/adf_isr.c b/drivers/crypto/qat/qat_common/adf_isr.c
index 4ca482aa69f7..a35149f8bf1e 100644
--- a/drivers/crypto/qat/qat_common/adf_isr.c
+++ b/drivers/crypto/qat/qat_common/adf_isr.c
@@ -16,6 +16,7 @@
#include "adf_transport_internal.h"
#define ADF_MAX_NUM_VFS 32
+static struct workqueue_struct *adf_misc_wq;
static int adf_enable_msix(struct adf_accel_dev *accel_dev)
{
@@ -123,6 +124,17 @@ static bool adf_handle_vf2pf_int(struct adf_accel_dev *accel_dev)
}
#endif /* CONFIG_PCI_IOV */
+static bool adf_handle_pm_int(struct adf_accel_dev *accel_dev)
+{
+ struct adf_hw_device_data *hw_data = accel_dev->hw_device;
+
+ if (hw_data->handle_pm_interrupt &&
+ hw_data->handle_pm_interrupt(accel_dev))
+ return true;
+
+ return false;
+}
+
static irqreturn_t adf_msix_isr_ae(int irq, void *dev_ptr)
{
struct adf_accel_dev *accel_dev = dev_ptr;
@@ -133,6 +145,9 @@ static irqreturn_t adf_msix_isr_ae(int irq, void *dev_ptr)
return IRQ_HANDLED;
#endif /* CONFIG_PCI_IOV */
+ if (adf_handle_pm_int(accel_dev))
+ return IRQ_HANDLED;
+
dev_dbg(&GET_DEV(accel_dev), "qat_dev%d spurious AE interrupt\n",
accel_dev->accel_id);
@@ -341,3 +356,30 @@ err_out:
return ret;
}
EXPORT_SYMBOL_GPL(adf_isr_resource_alloc);
+
+/**
+ * adf_init_misc_wq() - Init misc workqueue
+ *
+ * Function init workqueue 'qat_misc_wq' for general purpose.
+ *
+ * Return: 0 on success, error code otherwise.
+ */
+int __init adf_init_misc_wq(void)
+{
+ adf_misc_wq = alloc_workqueue("qat_misc_wq", WQ_MEM_RECLAIM, 0);
+
+ return !adf_misc_wq ? -ENOMEM : 0;
+}
+
+void adf_exit_misc_wq(void)
+{
+ if (adf_misc_wq)
+ destroy_workqueue(adf_misc_wq);
+
+ adf_misc_wq = NULL;
+}
+
+bool adf_misc_wq_queue_work(struct work_struct *work)
+{
+ return queue_work(adf_misc_wq, work);
+}
diff --git a/drivers/crypto/qat/qat_common/adf_pfvf_vf_msg.c b/drivers/crypto/qat/qat_common/adf_pfvf_vf_msg.c
index 14b222691c9c..1141258db4b6 100644
--- a/drivers/crypto/qat/qat_common/adf_pfvf_vf_msg.c
+++ b/drivers/crypto/qat/qat_common/adf_pfvf_vf_msg.c
@@ -96,7 +96,7 @@ int adf_vf2pf_request_version(struct adf_accel_dev *accel_dev)
int adf_vf2pf_get_capabilities(struct adf_accel_dev *accel_dev)
{
struct adf_hw_device_data *hw_data = accel_dev->hw_device;
- struct capabilities_v3 cap_msg = { { 0 }, };
+ struct capabilities_v3 cap_msg = { 0 };
unsigned int len = sizeof(cap_msg);
if (accel_dev->vf.pf_compat_ver < ADF_PFVF_COMPAT_CAPABILITIES)
@@ -141,7 +141,7 @@ int adf_vf2pf_get_capabilities(struct adf_accel_dev *accel_dev)
int adf_vf2pf_get_ring_to_svc(struct adf_accel_dev *accel_dev)
{
- struct ring_to_svc_map_v1 rts_map_msg = { { 0 }, };
+ struct ring_to_svc_map_v1 rts_map_msg = { 0 };
unsigned int len = sizeof(rts_map_msg);
if (accel_dev->vf.pf_compat_ver < ADF_PFVF_COMPAT_RING_TO_SVC_MAP)
diff --git a/drivers/crypto/qat/qat_common/icp_qat_fw_init_admin.h b/drivers/crypto/qat/qat_common/icp_qat_fw_init_admin.h
index afe59a7684ac..56cb827f93ea 100644
--- a/drivers/crypto/qat/qat_common/icp_qat_fw_init_admin.h
+++ b/drivers/crypto/qat/qat_common/icp_qat_fw_init_admin.h
@@ -16,6 +16,7 @@ enum icp_qat_fw_init_admin_cmd_id {
ICP_QAT_FW_HEARTBEAT_SYNC = 7,
ICP_QAT_FW_HEARTBEAT_GET = 8,
ICP_QAT_FW_COMP_CAPABILITY_GET = 9,
+ ICP_QAT_FW_PM_STATE_CONFIG = 128,
};
enum icp_qat_fw_init_admin_resp_status {
diff --git a/drivers/crypto/qat/qat_common/qat_crypto.c b/drivers/crypto/qat/qat_common/qat_crypto.c
index 7234c4940fae..67c9588e89df 100644
--- a/drivers/crypto/qat/qat_common/qat_crypto.c
+++ b/drivers/crypto/qat/qat_common/qat_crypto.c
@@ -161,6 +161,13 @@ int qat_crypto_dev_config(struct adf_accel_dev *accel_dev)
if (ret)
goto err;
+ /* Temporarily set the number of crypto instances to zero to avoid
+ * registering the crypto algorithms.
+ * This will be removed when the algorithms will support the
+ * CRYPTO_TFM_REQ_MAY_BACKLOG flag
+ */
+ instances = 0;
+
for (i = 0; i < instances; i++) {
val = i;
snprintf(key, sizeof(key), ADF_CY "%d" ADF_RING_ASYM_BANK_NUM, i);
diff --git a/drivers/crypto/qat/qat_common/qat_uclo.c b/drivers/crypto/qat/qat_common/qat_uclo.c
index 2026cc6be8f0..6356402a2c9e 100644
--- a/drivers/crypto/qat/qat_common/qat_uclo.c
+++ b/drivers/crypto/qat/qat_common/qat_uclo.c
@@ -387,7 +387,9 @@ static int qat_uclo_init_ustore(struct icp_qat_fw_loader_handle *handle,
page = image->page;
for_each_set_bit(ae, &ae_mask, handle->hal_handle->ae_max_num) {
- if (!test_bit(ae, (unsigned long *)&uof_image->ae_assigned))
+ unsigned long ae_assigned = uof_image->ae_assigned;
+
+ if (!test_bit(ae, &ae_assigned))
continue;
if (!test_bit(ae, &cfg_ae_mask))
@@ -664,8 +666,9 @@ static int qat_uclo_map_ae(struct icp_qat_fw_loader_handle *handle, int max_ae)
continue;
for (i = 0; i < obj_handle->uimage_num; i++) {
- if (!test_bit(ae, (unsigned long *)
- &obj_handle->ae_uimage[i].img_ptr->ae_assigned))
+ unsigned long ae_assigned = obj_handle->ae_uimage[i].img_ptr->ae_assigned;
+
+ if (!test_bit(ae, &ae_assigned))
continue;
mflag = 1;
if (qat_uclo_init_ae_data(obj_handle, ae, i))
diff --git a/drivers/crypto/qcom-rng.c b/drivers/crypto/qcom-rng.c
index 99ba8d51d102..11f30fd48c14 100644
--- a/drivers/crypto/qcom-rng.c
+++ b/drivers/crypto/qcom-rng.c
@@ -8,6 +8,7 @@
#include <linux/clk.h>
#include <linux/crypto.h>
#include <linux/io.h>
+#include <linux/iopoll.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/platform_device.h>
@@ -43,16 +44,19 @@ static int qcom_rng_read(struct qcom_rng *rng, u8 *data, unsigned int max)
{
unsigned int currsize = 0;
u32 val;
+ int ret;
/* read random data from hardware */
do {
- val = readl_relaxed(rng->base + PRNG_STATUS);
- if (!(val & PRNG_STATUS_DATA_AVAIL))
- break;
+ ret = readl_poll_timeout(rng->base + PRNG_STATUS, val,
+ val & PRNG_STATUS_DATA_AVAIL,
+ 200, 10000);
+ if (ret)
+ return ret;
val = readl_relaxed(rng->base + PRNG_DATA_OUT);
if (!val)
- break;
+ return -EINVAL;
if ((max - currsize) >= WORD_SZ) {
memcpy(data, &val, WORD_SZ);
@@ -61,11 +65,10 @@ static int qcom_rng_read(struct qcom_rng *rng, u8 *data, unsigned int max)
} else {
/* copy only remaining bytes */
memcpy(data, &val, max - currsize);
- break;
}
} while (currsize < max);
- return currsize;
+ return 0;
}
static int qcom_rng_generate(struct crypto_rng *tfm,
@@ -87,7 +90,7 @@ static int qcom_rng_generate(struct crypto_rng *tfm,
mutex_unlock(&rng->lock);
clk_disable_unprepare(rng->clk);
- return 0;
+ return ret;
}
static int qcom_rng_seed(struct crypto_rng *tfm, const u8 *seed,
diff --git a/drivers/crypto/rockchip/rk3288_crypto_skcipher.c b/drivers/crypto/rockchip/rk3288_crypto_skcipher.c
index 1cece1a7d3f0..5bbf0d2722e1 100644
--- a/drivers/crypto/rockchip/rk3288_crypto_skcipher.c
+++ b/drivers/crypto/rockchip/rk3288_crypto_skcipher.c
@@ -506,7 +506,6 @@ struct rk_crypto_tmp rk_ecb_des3_ede_alg = {
.exit = rk_ablk_exit_tfm,
.min_keysize = DES3_EDE_KEY_SIZE,
.max_keysize = DES3_EDE_KEY_SIZE,
- .ivsize = DES_BLOCK_SIZE,
.setkey = rk_tdes_setkey,
.encrypt = rk_des3_ede_ecb_encrypt,
.decrypt = rk_des3_ede_ecb_decrypt,
diff --git a/drivers/crypto/ux500/cryp/cryp_core.c b/drivers/crypto/ux500/cryp/cryp_core.c
index 97277b7150cb..5a57c9afd8c8 100644
--- a/drivers/crypto/ux500/cryp/cryp_core.c
+++ b/drivers/crypto/ux500/cryp/cryp_core.c
@@ -1264,7 +1264,7 @@ static int ux500_cryp_probe(struct platform_device *pdev)
struct device *dev = &pdev->dev;
dev_dbg(dev, "[%s]", __func__);
- device_data = devm_kzalloc(dev, sizeof(*device_data), GFP_ATOMIC);
+ device_data = devm_kzalloc(dev, sizeof(*device_data), GFP_KERNEL);
if (!device_data) {
ret = -ENOMEM;
goto out;
diff --git a/drivers/crypto/ux500/hash/hash_core.c b/drivers/crypto/ux500/hash/hash_core.c
index 51a6e1a42434..5157c118d642 100644
--- a/drivers/crypto/ux500/hash/hash_core.c
+++ b/drivers/crypto/ux500/hash/hash_core.c
@@ -1658,7 +1658,7 @@ static int ux500_hash_probe(struct platform_device *pdev)
struct hash_device_data *device_data;
struct device *dev = &pdev->dev;
- device_data = devm_kzalloc(dev, sizeof(*device_data), GFP_ATOMIC);
+ device_data = devm_kzalloc(dev, sizeof(*device_data), GFP_KERNEL);
if (!device_data) {
ret = -ENOMEM;
goto out;
diff --git a/drivers/crypto/vmx/Kconfig b/drivers/crypto/vmx/Kconfig
index c85fab7ef0bd..b2c28b87f14b 100644
--- a/drivers/crypto/vmx/Kconfig
+++ b/drivers/crypto/vmx/Kconfig
@@ -2,7 +2,11 @@
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.
diff --git a/drivers/crypto/xilinx/Makefile b/drivers/crypto/xilinx/Makefile
index 534e32daf76a..730feff5b5f2 100644
--- a/drivers/crypto/xilinx/Makefile
+++ b/drivers/crypto/xilinx/Makefile
@@ -1,2 +1,3 @@
# SPDX-License-Identifier: GPL-2.0-only
obj-$(CONFIG_CRYPTO_DEV_ZYNQMP_AES) += zynqmp-aes-gcm.o
+obj-$(CONFIG_CRYPTO_DEV_ZYNQMP_SHA3) += zynqmp-sha.o
diff --git a/drivers/crypto/xilinx/zynqmp-sha.c b/drivers/crypto/xilinx/zynqmp-sha.c
new file mode 100644
index 000000000000..43ff170ff1c2
--- /dev/null
+++ b/drivers/crypto/xilinx/zynqmp-sha.c
@@ -0,0 +1,264 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Xilinx ZynqMP SHA Driver.
+ * Copyright (c) 2022 Xilinx Inc.
+ */
+#include <linux/cacheflush.h>
+#include <crypto/hash.h>
+#include <crypto/internal/hash.h>
+#include <crypto/sha3.h>
+#include <linux/crypto.h>
+#include <linux/device.h>
+#include <linux/dma-mapping.h>
+#include <linux/firmware/xlnx-zynqmp.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+
+#define ZYNQMP_DMA_BIT_MASK 32U
+#define ZYNQMP_DMA_ALLOC_FIXED_SIZE 0x1000U
+
+enum zynqmp_sha_op {
+ ZYNQMP_SHA3_INIT = 1,
+ ZYNQMP_SHA3_UPDATE = 2,
+ ZYNQMP_SHA3_FINAL = 4,
+};
+
+struct zynqmp_sha_drv_ctx {
+ struct shash_alg sha3_384;
+ struct device *dev;
+};
+
+struct zynqmp_sha_tfm_ctx {
+ struct device *dev;
+ struct crypto_shash *fbk_tfm;
+};
+
+struct zynqmp_sha_desc_ctx {
+ struct shash_desc fbk_req;
+};
+
+static dma_addr_t update_dma_addr, final_dma_addr;
+static char *ubuf, *fbuf;
+
+static int zynqmp_sha_init_tfm(struct crypto_shash *hash)
+{
+ const char *fallback_driver_name = crypto_shash_alg_name(hash);
+ struct zynqmp_sha_tfm_ctx *tfm_ctx = crypto_shash_ctx(hash);
+ struct shash_alg *alg = crypto_shash_alg(hash);
+ struct crypto_shash *fallback_tfm;
+ struct zynqmp_sha_drv_ctx *drv_ctx;
+
+ drv_ctx = container_of(alg, struct zynqmp_sha_drv_ctx, sha3_384);
+ tfm_ctx->dev = drv_ctx->dev;
+
+ /* Allocate a fallback and abort if it failed. */
+ fallback_tfm = crypto_alloc_shash(fallback_driver_name, 0,
+ CRYPTO_ALG_NEED_FALLBACK);
+ if (IS_ERR(fallback_tfm))
+ return PTR_ERR(fallback_tfm);
+
+ tfm_ctx->fbk_tfm = fallback_tfm;
+ hash->descsize += crypto_shash_descsize(tfm_ctx->fbk_tfm);
+
+ return 0;
+}
+
+static void zynqmp_sha_exit_tfm(struct crypto_shash *hash)
+{
+ struct zynqmp_sha_tfm_ctx *tfm_ctx = crypto_shash_ctx(hash);
+
+ if (tfm_ctx->fbk_tfm) {
+ crypto_free_shash(tfm_ctx->fbk_tfm);
+ tfm_ctx->fbk_tfm = NULL;
+ }
+
+ memzero_explicit(tfm_ctx, sizeof(struct zynqmp_sha_tfm_ctx));
+}
+
+static int zynqmp_sha_init(struct shash_desc *desc)
+{
+ struct zynqmp_sha_desc_ctx *dctx = shash_desc_ctx(desc);
+ struct zynqmp_sha_tfm_ctx *tctx = crypto_shash_ctx(desc->tfm);
+
+ dctx->fbk_req.tfm = tctx->fbk_tfm;
+ return crypto_shash_init(&dctx->fbk_req);
+}
+
+static int zynqmp_sha_update(struct shash_desc *desc, const u8 *data, unsigned int length)
+{
+ struct zynqmp_sha_desc_ctx *dctx = shash_desc_ctx(desc);
+
+ return crypto_shash_update(&dctx->fbk_req, data, length);
+}
+
+static int zynqmp_sha_final(struct shash_desc *desc, u8 *out)
+{
+ struct zynqmp_sha_desc_ctx *dctx = shash_desc_ctx(desc);
+
+ return crypto_shash_final(&dctx->fbk_req, out);
+}
+
+static int zynqmp_sha_finup(struct shash_desc *desc, const u8 *data, unsigned int length, u8 *out)
+{
+ struct zynqmp_sha_desc_ctx *dctx = shash_desc_ctx(desc);
+
+ return crypto_shash_finup(&dctx->fbk_req, data, length, out);
+}
+
+static int zynqmp_sha_import(struct shash_desc *desc, const void *in)
+{
+ struct zynqmp_sha_desc_ctx *dctx = shash_desc_ctx(desc);
+ struct zynqmp_sha_tfm_ctx *tctx = crypto_shash_ctx(desc->tfm);
+
+ dctx->fbk_req.tfm = tctx->fbk_tfm;
+ return crypto_shash_import(&dctx->fbk_req, in);
+}
+
+static int zynqmp_sha_export(struct shash_desc *desc, void *out)
+{
+ struct zynqmp_sha_desc_ctx *dctx = shash_desc_ctx(desc);
+
+ return crypto_shash_export(&dctx->fbk_req, out);
+}
+
+static int zynqmp_sha_digest(struct shash_desc *desc, const u8 *data, unsigned int len, u8 *out)
+{
+ unsigned int remaining_len = len;
+ int update_size;
+ int ret;
+
+ ret = zynqmp_pm_sha_hash(0, 0, ZYNQMP_SHA3_INIT);
+ if (ret)
+ return ret;
+
+ while (remaining_len != 0) {
+ memzero_explicit(ubuf, ZYNQMP_DMA_ALLOC_FIXED_SIZE);
+ if (remaining_len >= ZYNQMP_DMA_ALLOC_FIXED_SIZE) {
+ update_size = ZYNQMP_DMA_ALLOC_FIXED_SIZE;
+ remaining_len -= ZYNQMP_DMA_ALLOC_FIXED_SIZE;
+ } else {
+ update_size = remaining_len;
+ remaining_len = 0;
+ }
+ memcpy(ubuf, data, update_size);
+ flush_icache_range((unsigned long)ubuf, (unsigned long)ubuf + update_size);
+ ret = zynqmp_pm_sha_hash(update_dma_addr, update_size, ZYNQMP_SHA3_UPDATE);
+ if (ret)
+ return ret;
+
+ data += update_size;
+ }
+
+ ret = zynqmp_pm_sha_hash(final_dma_addr, SHA3_384_DIGEST_SIZE, ZYNQMP_SHA3_FINAL);
+ memcpy(out, fbuf, SHA3_384_DIGEST_SIZE);
+ memzero_explicit(fbuf, SHA3_384_DIGEST_SIZE);
+
+ return ret;
+}
+
+static struct zynqmp_sha_drv_ctx sha3_drv_ctx = {
+ .sha3_384 = {
+ .init = zynqmp_sha_init,
+ .update = zynqmp_sha_update,
+ .final = zynqmp_sha_final,
+ .finup = zynqmp_sha_finup,
+ .digest = zynqmp_sha_digest,
+ .export = zynqmp_sha_export,
+ .import = zynqmp_sha_import,
+ .init_tfm = zynqmp_sha_init_tfm,
+ .exit_tfm = zynqmp_sha_exit_tfm,
+ .descsize = sizeof(struct zynqmp_sha_desc_ctx),
+ .statesize = sizeof(struct sha3_state),
+ .digestsize = SHA3_384_DIGEST_SIZE,
+ .base = {
+ .cra_name = "sha3-384",
+ .cra_driver_name = "zynqmp-sha3-384",
+ .cra_priority = 300,
+ .cra_flags = CRYPTO_ALG_KERN_DRIVER_ONLY |
+ CRYPTO_ALG_ALLOCATES_MEMORY |
+ CRYPTO_ALG_NEED_FALLBACK,
+ .cra_blocksize = SHA3_384_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct zynqmp_sha_tfm_ctx),
+ .cra_alignmask = 3,
+ .cra_module = THIS_MODULE,
+ }
+ }
+};
+
+static int zynqmp_sha_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ int err;
+ u32 v;
+
+ /* Verify the hardware is present */
+ err = zynqmp_pm_get_api_version(&v);
+ if (err)
+ return err;
+
+
+ err = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(ZYNQMP_DMA_BIT_MASK));
+ if (err < 0) {
+ dev_err(dev, "No usable DMA configuration\n");
+ return err;
+ }
+
+ err = crypto_register_shash(&sha3_drv_ctx.sha3_384);
+ if (err < 0) {
+ dev_err(dev, "Failed to register shash alg.\n");
+ return err;
+ }
+
+ sha3_drv_ctx.dev = dev;
+ platform_set_drvdata(pdev, &sha3_drv_ctx);
+
+ ubuf = dma_alloc_coherent(dev, ZYNQMP_DMA_ALLOC_FIXED_SIZE, &update_dma_addr, GFP_KERNEL);
+ if (!ubuf) {
+ err = -ENOMEM;
+ goto err_shash;
+ }
+
+ fbuf = dma_alloc_coherent(dev, SHA3_384_DIGEST_SIZE, &final_dma_addr, GFP_KERNEL);
+ if (!fbuf) {
+ err = -ENOMEM;
+ goto err_mem;
+ }
+
+ return 0;
+
+err_mem:
+ dma_free_coherent(sha3_drv_ctx.dev, ZYNQMP_DMA_ALLOC_FIXED_SIZE, ubuf, update_dma_addr);
+
+err_shash:
+ crypto_unregister_shash(&sha3_drv_ctx.sha3_384);
+
+ return err;
+}
+
+static int zynqmp_sha_remove(struct platform_device *pdev)
+{
+ sha3_drv_ctx.dev = platform_get_drvdata(pdev);
+
+ dma_free_coherent(sha3_drv_ctx.dev, ZYNQMP_DMA_ALLOC_FIXED_SIZE, ubuf, update_dma_addr);
+ dma_free_coherent(sha3_drv_ctx.dev, SHA3_384_DIGEST_SIZE, fbuf, final_dma_addr);
+ crypto_unregister_shash(&sha3_drv_ctx.sha3_384);
+
+ return 0;
+}
+
+static struct platform_driver zynqmp_sha_driver = {
+ .probe = zynqmp_sha_probe,
+ .remove = zynqmp_sha_remove,
+ .driver = {
+ .name = "zynqmp-sha3-384",
+ },
+};
+
+module_platform_driver(zynqmp_sha_driver);
+MODULE_DESCRIPTION("ZynqMP SHA3 hardware acceleration support.");
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Harsha <harsha.harsha@xilinx.com>");
diff --git a/drivers/cxl/Kconfig b/drivers/cxl/Kconfig
index 67c91378f2dd..b88ab956bb7c 100644
--- a/drivers/cxl/Kconfig
+++ b/drivers/cxl/Kconfig
@@ -13,25 +13,26 @@ menuconfig CXL_BUS
if CXL_BUS
-config CXL_MEM
- tristate "CXL.mem: Memory Devices"
+config CXL_PCI
+ tristate "PCI manageability"
default CXL_BUS
help
- The CXL.mem protocol allows a device to act as a provider of
- "System RAM" and/or "Persistent Memory" that is fully coherent
- as if the memory was attached to the typical CPU memory
- controller.
+ The CXL specification defines a "CXL memory device" sub-class in the
+ PCI "memory controller" base class of devices. Device's identified by
+ this class code provide support for volatile and / or persistent
+ memory to be mapped into the system address map (Host-managed Device
+ Memory (HDM)).
- Say 'y/m' to enable a driver that will attach to CXL.mem devices for
- configuration and management primarily via the mailbox interface. See
- Chapter 2.3 Type 3 CXL Device in the CXL 2.0 specification for more
- details.
+ Say 'y/m' to enable a driver that will attach to CXL memory expander
+ devices enumerated by the memory device class code for configuration
+ and management primarily via the mailbox interface. See Chapter 2.3
+ Type 3 CXL Device in the CXL 2.0 specification for more details.
If unsure say 'm'.
config CXL_MEM_RAW_COMMANDS
bool "RAW Command Interface for Memory Devices"
- depends on CXL_MEM
+ depends on CXL_PCI
help
Enable CXL RAW command interface.
@@ -76,4 +77,25 @@ config CXL_PMEM
provisioning the persistent memory capacity of CXL memory expanders.
If unsure say 'm'.
+
+config CXL_MEM
+ tristate "CXL: Memory Expansion"
+ depends on CXL_PCI
+ default CXL_BUS
+ help
+ The CXL.mem protocol allows a device to act as a provider of "System
+ RAM" and/or "Persistent Memory" that is fully coherent as if the
+ memory were attached to the typical CPU memory controller. This is
+ known as HDM "Host-managed Device Memory".
+
+ Say 'y/m' to enable a driver that will attach to CXL.mem devices for
+ memory expansion and control of HDM. See Chapter 9.13 in the CXL 2.0
+ specification for a detailed description of HDM.
+
+ If unsure say 'm'.
+
+config CXL_PORT
+ default CXL_BUS
+ tristate
+
endif
diff --git a/drivers/cxl/Makefile b/drivers/cxl/Makefile
index d1aaabc940f3..ce267ef11d93 100644
--- a/drivers/cxl/Makefile
+++ b/drivers/cxl/Makefile
@@ -1,9 +1,13 @@
# SPDX-License-Identifier: GPL-2.0
obj-$(CONFIG_CXL_BUS) += core/
-obj-$(CONFIG_CXL_MEM) += cxl_pci.o
+obj-$(CONFIG_CXL_PCI) += cxl_pci.o
+obj-$(CONFIG_CXL_MEM) += cxl_mem.o
obj-$(CONFIG_CXL_ACPI) += cxl_acpi.o
obj-$(CONFIG_CXL_PMEM) += cxl_pmem.o
+obj-$(CONFIG_CXL_PORT) += cxl_port.o
+cxl_mem-y := mem.o
cxl_pci-y := pci.o
cxl_acpi-y := acpi.o
cxl_pmem-y := pmem.o
+cxl_port-y := port.o
diff --git a/drivers/cxl/acpi.c b/drivers/cxl/acpi.c
index 3163167ecc3a..d15a6aec0331 100644
--- a/drivers/cxl/acpi.c
+++ b/drivers/cxl/acpi.c
@@ -6,6 +6,7 @@
#include <linux/kernel.h>
#include <linux/acpi.h>
#include <linux/pci.h>
+#include "cxlpci.h"
#include "cxl.h"
/* Encode defined in CXL 2.0 8.2.5.12.7 HDM Decoder Control Register */
@@ -14,7 +15,7 @@
static unsigned long cfmws_to_decoder_flags(int restrictions)
{
- unsigned long flags = 0;
+ unsigned long flags = CXL_DECODER_F_ENABLE;
if (restrictions & ACPI_CEDT_CFMWS_RESTRICT_TYPE2)
flags |= CXL_DECODER_F_TYPE2;
@@ -101,16 +102,14 @@ static int cxl_parse_cfmws(union acpi_subtable_headers *header, void *arg,
for (i = 0; i < CFMWS_INTERLEAVE_WAYS(cfmws); i++)
target_map[i] = cfmws->interleave_targets[i];
- cxld = cxl_decoder_alloc(root_port, CFMWS_INTERLEAVE_WAYS(cfmws));
+ cxld = cxl_root_decoder_alloc(root_port, CFMWS_INTERLEAVE_WAYS(cfmws));
if (IS_ERR(cxld))
return 0;
cxld->flags = cfmws_to_decoder_flags(cfmws->restrictions);
cxld->target_type = CXL_DECODER_EXPANDER;
- cxld->range = (struct range){
- .start = cfmws->base_hpa,
- .end = cfmws->base_hpa + cfmws->window_size - 1,
- };
+ cxld->platform_res = (struct resource)DEFINE_RES_MEM(cfmws->base_hpa,
+ cfmws->window_size);
cxld->interleave_ways = CFMWS_INTERLEAVE_WAYS(cfmws);
cxld->interleave_granularity = CFMWS_INTERLEAVE_GRANULARITY(cfmws);
@@ -120,67 +119,17 @@ static int cxl_parse_cfmws(union acpi_subtable_headers *header, void *arg,
else
rc = cxl_decoder_autoremove(dev, cxld);
if (rc) {
- dev_err(dev, "Failed to add decoder for %#llx-%#llx\n",
- cfmws->base_hpa,
- cfmws->base_hpa + cfmws->window_size - 1);
+ dev_err(dev, "Failed to add decoder for %pr\n",
+ &cxld->platform_res);
return 0;
}
- dev_dbg(dev, "add: %s node: %d range %#llx-%#llx\n",
- dev_name(&cxld->dev), phys_to_target_node(cxld->range.start),
- cfmws->base_hpa, cfmws->base_hpa + cfmws->window_size - 1);
+ dev_dbg(dev, "add: %s node: %d range %pr\n", dev_name(&cxld->dev),
+ phys_to_target_node(cxld->platform_res.start),
+ &cxld->platform_res);
return 0;
}
-__mock int match_add_root_ports(struct pci_dev *pdev, void *data)
-{
- struct cxl_walk_context *ctx = data;
- struct pci_bus *root_bus = ctx->root;
- struct cxl_port *port = ctx->port;
- int type = pci_pcie_type(pdev);
- struct device *dev = ctx->dev;
- u32 lnkcap, port_num;
- int rc;
-
- if (pdev->bus != root_bus)
- return 0;
- if (!pci_is_pcie(pdev))
- return 0;
- if (type != PCI_EXP_TYPE_ROOT_PORT)
- return 0;
- if (pci_read_config_dword(pdev, pci_pcie_cap(pdev) + PCI_EXP_LNKCAP,
- &lnkcap) != PCIBIOS_SUCCESSFUL)
- return 0;
-
- /* TODO walk DVSEC to find component register base */
- port_num = FIELD_GET(PCI_EXP_LNKCAP_PN, lnkcap);
- rc = cxl_add_dport(port, &pdev->dev, port_num, CXL_RESOURCE_NONE);
- if (rc) {
- ctx->error = rc;
- return rc;
- }
- ctx->count++;
-
- dev_dbg(dev, "add dport%d: %s\n", port_num, dev_name(&pdev->dev));
-
- return 0;
-}
-
-static struct cxl_dport *find_dport_by_dev(struct cxl_port *port, struct device *dev)
-{
- struct cxl_dport *dport;
-
- device_lock(&port->dev);
- list_for_each_entry(dport, &port->dports, list)
- if (dport->dport == dev) {
- device_unlock(&port->dev);
- return dport;
- }
-
- device_unlock(&port->dev);
- return NULL;
-}
-
__mock struct acpi_device *to_cxl_host_bridge(struct device *host,
struct device *dev)
{
@@ -204,83 +153,35 @@ static int add_host_bridge_uport(struct device *match, void *arg)
struct device *host = root_port->dev.parent;
struct acpi_device *bridge = to_cxl_host_bridge(host, match);
struct acpi_pci_root *pci_root;
- struct cxl_walk_context ctx;
- int single_port_map[1], rc;
- struct cxl_decoder *cxld;
struct cxl_dport *dport;
struct cxl_port *port;
+ int rc;
if (!bridge)
return 0;
- dport = find_dport_by_dev(root_port, match);
+ dport = cxl_find_dport_by_dev(root_port, match);
if (!dport) {
dev_dbg(host, "host bridge expected and not found\n");
return 0;
}
- port = devm_cxl_add_port(host, match, dport->component_reg_phys,
- root_port);
- if (IS_ERR(port))
- return PTR_ERR(port);
- dev_dbg(host, "%s: add: %s\n", dev_name(match), dev_name(&port->dev));
-
/*
* Note that this lookup already succeeded in
* to_cxl_host_bridge(), so no need to check for failure here
*/
pci_root = acpi_pci_find_root(bridge->handle);
- ctx = (struct cxl_walk_context){
- .dev = host,
- .root = pci_root->bus,
- .port = port,
- };
- pci_walk_bus(pci_root->bus, match_add_root_ports, &ctx);
-
- if (ctx.count == 0)
- return -ENODEV;
- if (ctx.error)
- return ctx.error;
- if (ctx.count > 1)
- return 0;
-
- /* TODO: Scan CHBCR for HDM Decoder resources */
-
- /*
- * Per the CXL specification (8.2.5.12 CXL HDM Decoder Capability
- * Structure) single ported host-bridges need not publish a decoder
- * capability when a passthrough decode can be assumed, i.e. all
- * transactions that the uport sees are claimed and passed to the single
- * dport. Disable the range until the first CXL region is enumerated /
- * activated.
- */
- cxld = cxl_decoder_alloc(port, 1);
- if (IS_ERR(cxld))
- return PTR_ERR(cxld);
-
- cxld->interleave_ways = 1;
- cxld->interleave_granularity = PAGE_SIZE;
- cxld->target_type = CXL_DECODER_EXPANDER;
- cxld->range = (struct range) {
- .start = 0,
- .end = -1,
- };
-
- device_lock(&port->dev);
- dport = list_first_entry(&port->dports, typeof(*dport), list);
- device_unlock(&port->dev);
-
- single_port_map[0] = dport->port_id;
-
- rc = cxl_decoder_add(cxld, single_port_map);
+ rc = devm_cxl_register_pci_bus(host, match, pci_root->bus);
if (rc)
- put_device(&cxld->dev);
- else
- rc = cxl_decoder_autoremove(host, cxld);
+ return rc;
+
+ port = devm_cxl_add_port(host, match, dport->component_reg_phys,
+ root_port);
+ if (IS_ERR(port))
+ return PTR_ERR(port);
+ dev_dbg(host, "%s: add: %s\n", dev_name(match), dev_name(&port->dev));
- if (rc == 0)
- dev_dbg(host, "add: %s\n", dev_name(&cxld->dev));
- return rc;
+ return 0;
}
struct cxl_chbs_context {
@@ -309,9 +210,9 @@ static int cxl_get_chbcr(union acpi_subtable_headers *header, void *arg,
static int add_host_bridge_dport(struct device *match, void *arg)
{
- int rc;
acpi_status status;
unsigned long long uid;
+ struct cxl_dport *dport;
struct cxl_chbs_context ctx;
struct cxl_port *root_port = arg;
struct device *host = root_port->dev.parent;
@@ -340,11 +241,11 @@ static int add_host_bridge_dport(struct device *match, void *arg)
return 0;
}
- rc = cxl_add_dport(root_port, match, uid, ctx.chbcr);
- if (rc) {
+ dport = devm_cxl_add_dport(root_port, match, uid, ctx.chbcr);
+ if (IS_ERR(dport)) {
dev_err(host, "failed to add downstream port: %s\n",
dev_name(match));
- return rc;
+ return PTR_ERR(dport);
}
dev_dbg(host, "add dport%llu: %s\n", uid, dev_name(match));
return 0;
@@ -413,7 +314,8 @@ static int cxl_acpi_probe(struct platform_device *pdev)
if (rc < 0)
return rc;
- return 0;
+ /* In case PCI is scanned before ACPI re-trigger memdev attach */
+ return cxl_bus_rescan();
}
static const struct acpi_device_id cxl_acpi_ids[] = {
diff --git a/drivers/cxl/core/Makefile b/drivers/cxl/core/Makefile
index 40ab50318daf..6d37cd78b151 100644
--- a/drivers/cxl/core/Makefile
+++ b/drivers/cxl/core/Makefile
@@ -2,8 +2,10 @@
obj-$(CONFIG_CXL_BUS) += cxl_core.o
ccflags-y += -I$(srctree)/drivers/cxl
-cxl_core-y := bus.o
+cxl_core-y := port.o
cxl_core-y += pmem.o
cxl_core-y += regs.o
cxl_core-y += memdev.o
cxl_core-y += mbox.o
+cxl_core-y += pci.o
+cxl_core-y += hdm.o
diff --git a/drivers/cxl/core/bus.c b/drivers/cxl/core/bus.c
deleted file mode 100644
index 3f9b98ecd18b..000000000000
--- a/drivers/cxl/core/bus.c
+++ /dev/null
@@ -1,675 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/* Copyright(c) 2020 Intel Corporation. All rights reserved. */
-#include <linux/io-64-nonatomic-lo-hi.h>
-#include <linux/device.h>
-#include <linux/module.h>
-#include <linux/pci.h>
-#include <linux/slab.h>
-#include <linux/idr.h>
-#include <cxlmem.h>
-#include <cxl.h>
-#include "core.h"
-
-/**
- * DOC: cxl core
- *
- * The CXL core provides a set of interfaces that can be consumed by CXL aware
- * drivers. The interfaces allow for creation, modification, and destruction of
- * regions, memory devices, ports, and decoders. CXL aware drivers must register
- * with the CXL core via these interfaces in order to be able to participate in
- * cross-device interleave coordination. The CXL core also establishes and
- * maintains the bridge to the nvdimm subsystem.
- *
- * CXL core introduces sysfs hierarchy to control the devices that are
- * instantiated by the core.
- */
-
-static DEFINE_IDA(cxl_port_ida);
-
-static ssize_t devtype_show(struct device *dev, struct device_attribute *attr,
- char *buf)
-{
- return sysfs_emit(buf, "%s\n", dev->type->name);
-}
-static DEVICE_ATTR_RO(devtype);
-
-static struct attribute *cxl_base_attributes[] = {
- &dev_attr_devtype.attr,
- NULL,
-};
-
-struct attribute_group cxl_base_attribute_group = {
- .attrs = cxl_base_attributes,
-};
-
-static ssize_t start_show(struct device *dev, struct device_attribute *attr,
- char *buf)
-{
- struct cxl_decoder *cxld = to_cxl_decoder(dev);
-
- return sysfs_emit(buf, "%#llx\n", cxld->range.start);
-}
-static DEVICE_ATTR_RO(start);
-
-static ssize_t size_show(struct device *dev, struct device_attribute *attr,
- char *buf)
-{
- struct cxl_decoder *cxld = to_cxl_decoder(dev);
-
- return sysfs_emit(buf, "%#llx\n", range_len(&cxld->range));
-}
-static DEVICE_ATTR_RO(size);
-
-#define CXL_DECODER_FLAG_ATTR(name, flag) \
-static ssize_t name##_show(struct device *dev, \
- struct device_attribute *attr, char *buf) \
-{ \
- struct cxl_decoder *cxld = to_cxl_decoder(dev); \
- \
- return sysfs_emit(buf, "%s\n", \
- (cxld->flags & (flag)) ? "1" : "0"); \
-} \
-static DEVICE_ATTR_RO(name)
-
-CXL_DECODER_FLAG_ATTR(cap_pmem, CXL_DECODER_F_PMEM);
-CXL_DECODER_FLAG_ATTR(cap_ram, CXL_DECODER_F_RAM);
-CXL_DECODER_FLAG_ATTR(cap_type2, CXL_DECODER_F_TYPE2);
-CXL_DECODER_FLAG_ATTR(cap_type3, CXL_DECODER_F_TYPE3);
-CXL_DECODER_FLAG_ATTR(locked, CXL_DECODER_F_LOCK);
-
-static ssize_t target_type_show(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct cxl_decoder *cxld = to_cxl_decoder(dev);
-
- switch (cxld->target_type) {
- case CXL_DECODER_ACCELERATOR:
- return sysfs_emit(buf, "accelerator\n");
- case CXL_DECODER_EXPANDER:
- return sysfs_emit(buf, "expander\n");
- }
- return -ENXIO;
-}
-static DEVICE_ATTR_RO(target_type);
-
-static ssize_t target_list_show(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct cxl_decoder *cxld = to_cxl_decoder(dev);
- ssize_t offset = 0;
- int i, rc = 0;
-
- device_lock(dev);
- for (i = 0; i < cxld->interleave_ways; i++) {
- struct cxl_dport *dport = cxld->target[i];
- struct cxl_dport *next = NULL;
-
- if (!dport)
- break;
-
- if (i + 1 < cxld->interleave_ways)
- next = cxld->target[i + 1];
- rc = sysfs_emit_at(buf, offset, "%d%s", dport->port_id,
- next ? "," : "");
- if (rc < 0)
- break;
- offset += rc;
- }
- device_unlock(dev);
-
- if (rc < 0)
- return rc;
-
- rc = sysfs_emit_at(buf, offset, "\n");
- if (rc < 0)
- return rc;
-
- return offset + rc;
-}
-static DEVICE_ATTR_RO(target_list);
-
-static struct attribute *cxl_decoder_base_attrs[] = {
- &dev_attr_start.attr,
- &dev_attr_size.attr,
- &dev_attr_locked.attr,
- &dev_attr_target_list.attr,
- NULL,
-};
-
-static struct attribute_group cxl_decoder_base_attribute_group = {
- .attrs = cxl_decoder_base_attrs,
-};
-
-static struct attribute *cxl_decoder_root_attrs[] = {
- &dev_attr_cap_pmem.attr,
- &dev_attr_cap_ram.attr,
- &dev_attr_cap_type2.attr,
- &dev_attr_cap_type3.attr,
- NULL,
-};
-
-static struct attribute_group cxl_decoder_root_attribute_group = {
- .attrs = cxl_decoder_root_attrs,
-};
-
-static const struct attribute_group *cxl_decoder_root_attribute_groups[] = {
- &cxl_decoder_root_attribute_group,
- &cxl_decoder_base_attribute_group,
- &cxl_base_attribute_group,
- NULL,
-};
-
-static struct attribute *cxl_decoder_switch_attrs[] = {
- &dev_attr_target_type.attr,
- NULL,
-};
-
-static struct attribute_group cxl_decoder_switch_attribute_group = {
- .attrs = cxl_decoder_switch_attrs,
-};
-
-static const struct attribute_group *cxl_decoder_switch_attribute_groups[] = {
- &cxl_decoder_switch_attribute_group,
- &cxl_decoder_base_attribute_group,
- &cxl_base_attribute_group,
- NULL,
-};
-
-static void cxl_decoder_release(struct device *dev)
-{
- struct cxl_decoder *cxld = to_cxl_decoder(dev);
- struct cxl_port *port = to_cxl_port(dev->parent);
-
- ida_free(&port->decoder_ida, cxld->id);
- kfree(cxld);
-}
-
-static const struct device_type cxl_decoder_switch_type = {
- .name = "cxl_decoder_switch",
- .release = cxl_decoder_release,
- .groups = cxl_decoder_switch_attribute_groups,
-};
-
-static const struct device_type cxl_decoder_root_type = {
- .name = "cxl_decoder_root",
- .release = cxl_decoder_release,
- .groups = cxl_decoder_root_attribute_groups,
-};
-
-bool is_root_decoder(struct device *dev)
-{
- return dev->type == &cxl_decoder_root_type;
-}
-EXPORT_SYMBOL_NS_GPL(is_root_decoder, CXL);
-
-struct cxl_decoder *to_cxl_decoder(struct device *dev)
-{
- if (dev_WARN_ONCE(dev, dev->type->release != cxl_decoder_release,
- "not a cxl_decoder device\n"))
- return NULL;
- return container_of(dev, struct cxl_decoder, dev);
-}
-EXPORT_SYMBOL_NS_GPL(to_cxl_decoder, CXL);
-
-static void cxl_dport_release(struct cxl_dport *dport)
-{
- list_del(&dport->list);
- put_device(dport->dport);
- kfree(dport);
-}
-
-static void cxl_port_release(struct device *dev)
-{
- struct cxl_port *port = to_cxl_port(dev);
- struct cxl_dport *dport, *_d;
-
- device_lock(dev);
- list_for_each_entry_safe(dport, _d, &port->dports, list)
- cxl_dport_release(dport);
- device_unlock(dev);
- ida_free(&cxl_port_ida, port->id);
- kfree(port);
-}
-
-static const struct attribute_group *cxl_port_attribute_groups[] = {
- &cxl_base_attribute_group,
- NULL,
-};
-
-static const struct device_type cxl_port_type = {
- .name = "cxl_port",
- .release = cxl_port_release,
- .groups = cxl_port_attribute_groups,
-};
-
-struct cxl_port *to_cxl_port(struct device *dev)
-{
- if (dev_WARN_ONCE(dev, dev->type != &cxl_port_type,
- "not a cxl_port device\n"))
- return NULL;
- return container_of(dev, struct cxl_port, dev);
-}
-
-static void unregister_port(void *_port)
-{
- struct cxl_port *port = _port;
- struct cxl_dport *dport;
-
- device_lock(&port->dev);
- list_for_each_entry(dport, &port->dports, list) {
- char link_name[CXL_TARGET_STRLEN];
-
- if (snprintf(link_name, CXL_TARGET_STRLEN, "dport%d",
- dport->port_id) >= CXL_TARGET_STRLEN)
- continue;
- sysfs_remove_link(&port->dev.kobj, link_name);
- }
- device_unlock(&port->dev);
- device_unregister(&port->dev);
-}
-
-static void cxl_unlink_uport(void *_port)
-{
- struct cxl_port *port = _port;
-
- sysfs_remove_link(&port->dev.kobj, "uport");
-}
-
-static int devm_cxl_link_uport(struct device *host, struct cxl_port *port)
-{
- int rc;
-
- rc = sysfs_create_link(&port->dev.kobj, &port->uport->kobj, "uport");
- if (rc)
- return rc;
- return devm_add_action_or_reset(host, cxl_unlink_uport, port);
-}
-
-static struct cxl_port *cxl_port_alloc(struct device *uport,
- resource_size_t component_reg_phys,
- struct cxl_port *parent_port)
-{
- struct cxl_port *port;
- struct device *dev;
- int rc;
-
- port = kzalloc(sizeof(*port), GFP_KERNEL);
- if (!port)
- return ERR_PTR(-ENOMEM);
-
- rc = ida_alloc(&cxl_port_ida, GFP_KERNEL);
- if (rc < 0)
- goto err;
- port->id = rc;
-
- /*
- * The top-level cxl_port "cxl_root" does not have a cxl_port as
- * its parent and it does not have any corresponding component
- * registers as its decode is described by a fixed platform
- * description.
- */
- dev = &port->dev;
- if (parent_port)
- dev->parent = &parent_port->dev;
- else
- dev->parent = uport;
-
- port->uport = uport;
- port->component_reg_phys = component_reg_phys;
- ida_init(&port->decoder_ida);
- INIT_LIST_HEAD(&port->dports);
-
- device_initialize(dev);
- device_set_pm_not_required(dev);
- dev->bus = &cxl_bus_type;
- dev->type = &cxl_port_type;
-
- return port;
-
-err:
- kfree(port);
- return ERR_PTR(rc);
-}
-
-/**
- * devm_cxl_add_port - register a cxl_port in CXL memory decode hierarchy
- * @host: host device for devm operations
- * @uport: "physical" device implementing this upstream port
- * @component_reg_phys: (optional) for configurable cxl_port instances
- * @parent_port: next hop up in the CXL memory decode hierarchy
- */
-struct cxl_port *devm_cxl_add_port(struct device *host, struct device *uport,
- resource_size_t component_reg_phys,
- struct cxl_port *parent_port)
-{
- struct cxl_port *port;
- struct device *dev;
- int rc;
-
- port = cxl_port_alloc(uport, component_reg_phys, parent_port);
- if (IS_ERR(port))
- return port;
-
- dev = &port->dev;
- if (parent_port)
- rc = dev_set_name(dev, "port%d", port->id);
- else
- rc = dev_set_name(dev, "root%d", port->id);
- if (rc)
- goto err;
-
- rc = device_add(dev);
- if (rc)
- goto err;
-
- rc = devm_add_action_or_reset(host, unregister_port, port);
- if (rc)
- return ERR_PTR(rc);
-
- rc = devm_cxl_link_uport(host, port);
- if (rc)
- return ERR_PTR(rc);
-
- return port;
-
-err:
- put_device(dev);
- return ERR_PTR(rc);
-}
-EXPORT_SYMBOL_NS_GPL(devm_cxl_add_port, CXL);
-
-static struct cxl_dport *find_dport(struct cxl_port *port, int id)
-{
- struct cxl_dport *dport;
-
- device_lock_assert(&port->dev);
- list_for_each_entry (dport, &port->dports, list)
- if (dport->port_id == id)
- return dport;
- return NULL;
-}
-
-static int add_dport(struct cxl_port *port, struct cxl_dport *new)
-{
- struct cxl_dport *dup;
-
- device_lock(&port->dev);
- dup = find_dport(port, new->port_id);
- if (dup)
- dev_err(&port->dev,
- "unable to add dport%d-%s non-unique port id (%s)\n",
- new->port_id, dev_name(new->dport),
- dev_name(dup->dport));
- else
- list_add_tail(&new->list, &port->dports);
- device_unlock(&port->dev);
-
- return dup ? -EEXIST : 0;
-}
-
-/**
- * cxl_add_dport - append downstream port data to a cxl_port
- * @port: the cxl_port that references this dport
- * @dport_dev: firmware or PCI device representing the dport
- * @port_id: identifier for this dport in a decoder's target list
- * @component_reg_phys: optional location of CXL component registers
- *
- * Note that all allocations and links are undone by cxl_port deletion
- * and release.
- */
-int cxl_add_dport(struct cxl_port *port, struct device *dport_dev, int port_id,
- resource_size_t component_reg_phys)
-{
- char link_name[CXL_TARGET_STRLEN];
- struct cxl_dport *dport;
- int rc;
-
- if (snprintf(link_name, CXL_TARGET_STRLEN, "dport%d", port_id) >=
- CXL_TARGET_STRLEN)
- return -EINVAL;
-
- dport = kzalloc(sizeof(*dport), GFP_KERNEL);
- if (!dport)
- return -ENOMEM;
-
- INIT_LIST_HEAD(&dport->list);
- dport->dport = get_device(dport_dev);
- dport->port_id = port_id;
- dport->component_reg_phys = component_reg_phys;
- dport->port = port;
-
- rc = add_dport(port, dport);
- if (rc)
- goto err;
-
- rc = sysfs_create_link(&port->dev.kobj, &dport_dev->kobj, link_name);
- if (rc)
- goto err;
-
- return 0;
-err:
- cxl_dport_release(dport);
- return rc;
-}
-EXPORT_SYMBOL_NS_GPL(cxl_add_dport, CXL);
-
-static int decoder_populate_targets(struct cxl_decoder *cxld,
- struct cxl_port *port, int *target_map)
-{
- int rc = 0, i;
-
- if (!target_map)
- return 0;
-
- device_lock(&port->dev);
- if (list_empty(&port->dports)) {
- rc = -EINVAL;
- goto out_unlock;
- }
-
- for (i = 0; i < cxld->nr_targets; i++) {
- struct cxl_dport *dport = find_dport(port, target_map[i]);
-
- if (!dport) {
- rc = -ENXIO;
- goto out_unlock;
- }
- cxld->target[i] = dport;
- }
-
-out_unlock:
- device_unlock(&port->dev);
-
- return rc;
-}
-
-struct cxl_decoder *cxl_decoder_alloc(struct cxl_port *port, int nr_targets)
-{
- struct cxl_decoder *cxld;
- struct device *dev;
- int rc = 0;
-
- if (nr_targets > CXL_DECODER_MAX_INTERLEAVE || nr_targets < 1)
- return ERR_PTR(-EINVAL);
-
- cxld = kzalloc(struct_size(cxld, target, nr_targets), GFP_KERNEL);
- if (!cxld)
- return ERR_PTR(-ENOMEM);
-
- rc = ida_alloc(&port->decoder_ida, GFP_KERNEL);
- if (rc < 0)
- goto err;
-
- cxld->id = rc;
- cxld->nr_targets = nr_targets;
- dev = &cxld->dev;
- device_initialize(dev);
- device_set_pm_not_required(dev);
- dev->parent = &port->dev;
- dev->bus = &cxl_bus_type;
-
- /* root ports do not have a cxl_port_type parent */
- if (port->dev.parent->type == &cxl_port_type)
- dev->type = &cxl_decoder_switch_type;
- else
- dev->type = &cxl_decoder_root_type;
-
- return cxld;
-err:
- kfree(cxld);
- return ERR_PTR(rc);
-}
-EXPORT_SYMBOL_NS_GPL(cxl_decoder_alloc, CXL);
-
-int cxl_decoder_add(struct cxl_decoder *cxld, int *target_map)
-{
- struct cxl_port *port;
- struct device *dev;
- int rc;
-
- if (WARN_ON_ONCE(!cxld))
- return -EINVAL;
-
- if (WARN_ON_ONCE(IS_ERR(cxld)))
- return PTR_ERR(cxld);
-
- if (cxld->interleave_ways < 1)
- return -EINVAL;
-
- port = to_cxl_port(cxld->dev.parent);
- rc = decoder_populate_targets(cxld, port, target_map);
- if (rc)
- return rc;
-
- dev = &cxld->dev;
- rc = dev_set_name(dev, "decoder%d.%d", port->id, cxld->id);
- if (rc)
- return rc;
-
- return device_add(dev);
-}
-EXPORT_SYMBOL_NS_GPL(cxl_decoder_add, CXL);
-
-static void cxld_unregister(void *dev)
-{
- device_unregister(dev);
-}
-
-int cxl_decoder_autoremove(struct device *host, struct cxl_decoder *cxld)
-{
- return devm_add_action_or_reset(host, cxld_unregister, &cxld->dev);
-}
-EXPORT_SYMBOL_NS_GPL(cxl_decoder_autoremove, CXL);
-
-/**
- * __cxl_driver_register - register a driver for the cxl bus
- * @cxl_drv: cxl driver structure to attach
- * @owner: owning module/driver
- * @modname: KBUILD_MODNAME for parent driver
- */
-int __cxl_driver_register(struct cxl_driver *cxl_drv, struct module *owner,
- const char *modname)
-{
- if (!cxl_drv->probe) {
- pr_debug("%s ->probe() must be specified\n", modname);
- return -EINVAL;
- }
-
- if (!cxl_drv->name) {
- pr_debug("%s ->name must be specified\n", modname);
- return -EINVAL;
- }
-
- if (!cxl_drv->id) {
- pr_debug("%s ->id must be specified\n", modname);
- return -EINVAL;
- }
-
- cxl_drv->drv.bus = &cxl_bus_type;
- cxl_drv->drv.owner = owner;
- cxl_drv->drv.mod_name = modname;
- cxl_drv->drv.name = cxl_drv->name;
-
- return driver_register(&cxl_drv->drv);
-}
-EXPORT_SYMBOL_NS_GPL(__cxl_driver_register, CXL);
-
-void cxl_driver_unregister(struct cxl_driver *cxl_drv)
-{
- driver_unregister(&cxl_drv->drv);
-}
-EXPORT_SYMBOL_NS_GPL(cxl_driver_unregister, CXL);
-
-static int cxl_device_id(struct device *dev)
-{
- if (dev->type == &cxl_nvdimm_bridge_type)
- return CXL_DEVICE_NVDIMM_BRIDGE;
- if (dev->type == &cxl_nvdimm_type)
- return CXL_DEVICE_NVDIMM;
- return 0;
-}
-
-static int cxl_bus_uevent(struct device *dev, struct kobj_uevent_env *env)
-{
- return add_uevent_var(env, "MODALIAS=" CXL_MODALIAS_FMT,
- cxl_device_id(dev));
-}
-
-static int cxl_bus_match(struct device *dev, struct device_driver *drv)
-{
- return cxl_device_id(dev) == to_cxl_drv(drv)->id;
-}
-
-static int cxl_bus_probe(struct device *dev)
-{
- return to_cxl_drv(dev->driver)->probe(dev);
-}
-
-static void cxl_bus_remove(struct device *dev)
-{
- struct cxl_driver *cxl_drv = to_cxl_drv(dev->driver);
-
- if (cxl_drv->remove)
- cxl_drv->remove(dev);
-}
-
-struct bus_type cxl_bus_type = {
- .name = "cxl",
- .uevent = cxl_bus_uevent,
- .match = cxl_bus_match,
- .probe = cxl_bus_probe,
- .remove = cxl_bus_remove,
-};
-EXPORT_SYMBOL_NS_GPL(cxl_bus_type, CXL);
-
-static __init int cxl_core_init(void)
-{
- int rc;
-
- cxl_mbox_init();
-
- rc = cxl_memdev_init();
- if (rc)
- return rc;
-
- rc = bus_register(&cxl_bus_type);
- if (rc)
- goto err;
- return 0;
-
-err:
- cxl_memdev_exit();
- cxl_mbox_exit();
- return rc;
-}
-
-static void cxl_core_exit(void)
-{
- bus_unregister(&cxl_bus_type);
- cxl_memdev_exit();
- cxl_mbox_exit();
-}
-
-module_init(cxl_core_init);
-module_exit(cxl_core_exit);
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/cxl/core/core.h b/drivers/cxl/core/core.h
index e0c9aacc4e9c..1a50c0fc399c 100644
--- a/drivers/cxl/core/core.h
+++ b/drivers/cxl/core/core.h
@@ -14,6 +14,8 @@ struct cxl_mem_query_commands;
int cxl_query_cmd(struct cxl_memdev *cxlmd,
struct cxl_mem_query_commands __user *q);
int cxl_send_cmd(struct cxl_memdev *cxlmd, struct cxl_send_command __user *s);
+void __iomem *devm_cxl_iomap_block(struct device *dev, resource_size_t addr,
+ resource_size_t length);
int cxl_memdev_init(void);
void cxl_memdev_exit(void);
diff --git a/drivers/cxl/core/hdm.c b/drivers/cxl/core/hdm.c
new file mode 100644
index 000000000000..0e89a7a932d4
--- /dev/null
+++ b/drivers/cxl/core/hdm.c
@@ -0,0 +1,276 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/* Copyright(c) 2022 Intel Corporation. All rights reserved. */
+#include <linux/io-64-nonatomic-hi-lo.h>
+#include <linux/device.h>
+#include <linux/delay.h>
+
+#include "cxlmem.h"
+#include "core.h"
+
+/**
+ * DOC: cxl core hdm
+ *
+ * Compute Express Link Host Managed Device Memory, starting with the
+ * CXL 2.0 specification, is managed by an array of HDM Decoder register
+ * instances per CXL port and per CXL endpoint. Define common helpers
+ * for enumerating these registers and capabilities.
+ */
+
+static int add_hdm_decoder(struct cxl_port *port, struct cxl_decoder *cxld,
+ int *target_map)
+{
+ int rc;
+
+ rc = cxl_decoder_add_locked(cxld, target_map);
+ if (rc) {
+ put_device(&cxld->dev);
+ dev_err(&port->dev, "Failed to add decoder\n");
+ return rc;
+ }
+
+ rc = cxl_decoder_autoremove(&port->dev, cxld);
+ if (rc)
+ return rc;
+
+ dev_dbg(&cxld->dev, "Added to port %s\n", dev_name(&port->dev));
+
+ return 0;
+}
+
+/*
+ * Per the CXL specification (8.2.5.12 CXL HDM Decoder Capability Structure)
+ * single ported host-bridges need not publish a decoder capability when a
+ * passthrough decode can be assumed, i.e. all transactions that the uport sees
+ * are claimed and passed to the single dport. Disable the range until the first
+ * CXL region is enumerated / activated.
+ */
+int devm_cxl_add_passthrough_decoder(struct cxl_port *port)
+{
+ struct cxl_decoder *cxld;
+ struct cxl_dport *dport;
+ int single_port_map[1];
+
+ cxld = cxl_switch_decoder_alloc(port, 1);
+ if (IS_ERR(cxld))
+ return PTR_ERR(cxld);
+
+ device_lock_assert(&port->dev);
+
+ dport = list_first_entry(&port->dports, typeof(*dport), list);
+ single_port_map[0] = dport->port_id;
+
+ return add_hdm_decoder(port, cxld, single_port_map);
+}
+EXPORT_SYMBOL_NS_GPL(devm_cxl_add_passthrough_decoder, CXL);
+
+static void parse_hdm_decoder_caps(struct cxl_hdm *cxlhdm)
+{
+ u32 hdm_cap;
+
+ hdm_cap = readl(cxlhdm->regs.hdm_decoder + CXL_HDM_DECODER_CAP_OFFSET);
+ cxlhdm->decoder_count = cxl_hdm_decoder_count(hdm_cap);
+ cxlhdm->target_count =
+ FIELD_GET(CXL_HDM_DECODER_TARGET_COUNT_MASK, hdm_cap);
+ if (FIELD_GET(CXL_HDM_DECODER_INTERLEAVE_11_8, hdm_cap))
+ cxlhdm->interleave_mask |= GENMASK(11, 8);
+ if (FIELD_GET(CXL_HDM_DECODER_INTERLEAVE_14_12, hdm_cap))
+ cxlhdm->interleave_mask |= GENMASK(14, 12);
+}
+
+static void __iomem *map_hdm_decoder_regs(struct cxl_port *port,
+ void __iomem *crb)
+{
+ struct cxl_component_reg_map map;
+
+ cxl_probe_component_regs(&port->dev, crb, &map);
+ if (!map.hdm_decoder.valid) {
+ dev_err(&port->dev, "HDM decoder registers invalid\n");
+ return IOMEM_ERR_PTR(-ENXIO);
+ }
+
+ return crb + map.hdm_decoder.offset;
+}
+
+/**
+ * devm_cxl_setup_hdm - map HDM decoder component registers
+ * @port: cxl_port to map
+ */
+struct cxl_hdm *devm_cxl_setup_hdm(struct cxl_port *port)
+{
+ struct device *dev = &port->dev;
+ void __iomem *crb, *hdm;
+ struct cxl_hdm *cxlhdm;
+
+ cxlhdm = devm_kzalloc(dev, sizeof(*cxlhdm), GFP_KERNEL);
+ if (!cxlhdm)
+ return ERR_PTR(-ENOMEM);
+
+ cxlhdm->port = port;
+ crb = devm_cxl_iomap_block(dev, port->component_reg_phys,
+ CXL_COMPONENT_REG_BLOCK_SIZE);
+ if (!crb) {
+ dev_err(dev, "No component registers mapped\n");
+ return ERR_PTR(-ENXIO);
+ }
+
+ hdm = map_hdm_decoder_regs(port, crb);
+ if (IS_ERR(hdm))
+ return ERR_CAST(hdm);
+ cxlhdm->regs.hdm_decoder = hdm;
+
+ parse_hdm_decoder_caps(cxlhdm);
+ if (cxlhdm->decoder_count == 0) {
+ dev_err(dev, "Spec violation. Caps invalid\n");
+ return ERR_PTR(-ENXIO);
+ }
+
+ return cxlhdm;
+}
+EXPORT_SYMBOL_NS_GPL(devm_cxl_setup_hdm, CXL);
+
+static int to_interleave_granularity(u32 ctrl)
+{
+ int val = FIELD_GET(CXL_HDM_DECODER0_CTRL_IG_MASK, ctrl);
+
+ return 256 << val;
+}
+
+static int to_interleave_ways(u32 ctrl)
+{
+ int val = FIELD_GET(CXL_HDM_DECODER0_CTRL_IW_MASK, ctrl);
+
+ switch (val) {
+ case 0 ... 4:
+ return 1 << val;
+ case 8 ... 10:
+ return 3 << (val - 8);
+ default:
+ return 0;
+ }
+}
+
+static int init_hdm_decoder(struct cxl_port *port, struct cxl_decoder *cxld,
+ int *target_map, void __iomem *hdm, int which)
+{
+ u64 size, base;
+ u32 ctrl;
+ int i;
+ union {
+ u64 value;
+ unsigned char target_id[8];
+ } target_list;
+
+ ctrl = readl(hdm + CXL_HDM_DECODER0_CTRL_OFFSET(which));
+ base = ioread64_hi_lo(hdm + CXL_HDM_DECODER0_BASE_LOW_OFFSET(which));
+ size = ioread64_hi_lo(hdm + CXL_HDM_DECODER0_SIZE_LOW_OFFSET(which));
+
+ if (!(ctrl & CXL_HDM_DECODER0_CTRL_COMMITTED))
+ size = 0;
+ if (base == U64_MAX || size == U64_MAX) {
+ dev_warn(&port->dev, "decoder%d.%d: Invalid resource range\n",
+ port->id, cxld->id);
+ return -ENXIO;
+ }
+
+ cxld->decoder_range = (struct range) {
+ .start = base,
+ .end = base + size - 1,
+ };
+
+ /* switch decoders are always enabled if committed */
+ if (ctrl & CXL_HDM_DECODER0_CTRL_COMMITTED) {
+ cxld->flags |= CXL_DECODER_F_ENABLE;
+ if (ctrl & CXL_HDM_DECODER0_CTRL_LOCK)
+ cxld->flags |= CXL_DECODER_F_LOCK;
+ }
+ cxld->interleave_ways = to_interleave_ways(ctrl);
+ if (!cxld->interleave_ways) {
+ dev_warn(&port->dev,
+ "decoder%d.%d: Invalid interleave ways (ctrl: %#x)\n",
+ port->id, cxld->id, ctrl);
+ return -ENXIO;
+ }
+ cxld->interleave_granularity = to_interleave_granularity(ctrl);
+
+ if (FIELD_GET(CXL_HDM_DECODER0_CTRL_TYPE, ctrl))
+ cxld->target_type = CXL_DECODER_EXPANDER;
+ else
+ cxld->target_type = CXL_DECODER_ACCELERATOR;
+
+ if (is_cxl_endpoint(to_cxl_port(cxld->dev.parent)))
+ return 0;
+
+ target_list.value =
+ ioread64_hi_lo(hdm + CXL_HDM_DECODER0_TL_LOW(which));
+ for (i = 0; i < cxld->interleave_ways; i++)
+ target_map[i] = target_list.target_id[i];
+
+ return 0;
+}
+
+/**
+ * devm_cxl_enumerate_decoders - add decoder objects per HDM register set
+ * @cxlhdm: Structure to populate with HDM capabilities
+ */
+int devm_cxl_enumerate_decoders(struct cxl_hdm *cxlhdm)
+{
+ void __iomem *hdm = cxlhdm->regs.hdm_decoder;
+ struct cxl_port *port = cxlhdm->port;
+ int i, committed, failed;
+ u32 ctrl;
+
+ /*
+ * Since the register resource was recently claimed via request_region()
+ * be careful about trusting the "not-committed" status until the commit
+ * timeout has elapsed. The commit timeout is 10ms (CXL 2.0
+ * 8.2.5.12.20), but double it to be tolerant of any clock skew between
+ * host and target.
+ */
+ for (i = 0, committed = 0; i < cxlhdm->decoder_count; i++) {
+ ctrl = readl(hdm + CXL_HDM_DECODER0_CTRL_OFFSET(i));
+ if (ctrl & CXL_HDM_DECODER0_CTRL_COMMITTED)
+ committed++;
+ }
+
+ /* ensure that future checks of committed can be trusted */
+ if (committed != cxlhdm->decoder_count)
+ msleep(20);
+
+ for (i = 0, failed = 0; i < cxlhdm->decoder_count; i++) {
+ int target_map[CXL_DECODER_MAX_INTERLEAVE] = { 0 };
+ int rc, target_count = cxlhdm->target_count;
+ struct cxl_decoder *cxld;
+
+ if (is_cxl_endpoint(port))
+ cxld = cxl_endpoint_decoder_alloc(port);
+ else
+ cxld = cxl_switch_decoder_alloc(port, target_count);
+ if (IS_ERR(cxld)) {
+ dev_warn(&port->dev,
+ "Failed to allocate the decoder\n");
+ return PTR_ERR(cxld);
+ }
+
+ rc = init_hdm_decoder(port, cxld, target_map,
+ cxlhdm->regs.hdm_decoder, i);
+ if (rc) {
+ put_device(&cxld->dev);
+ failed++;
+ continue;
+ }
+ rc = add_hdm_decoder(port, cxld, target_map);
+ if (rc) {
+ dev_warn(&port->dev,
+ "Failed to add decoder to port\n");
+ return rc;
+ }
+ }
+
+ if (failed == cxlhdm->decoder_count) {
+ dev_err(&port->dev, "No valid decoders found\n");
+ return -ENXIO;
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL_NS_GPL(devm_cxl_enumerate_decoders, CXL);
diff --git a/drivers/cxl/core/memdev.c b/drivers/cxl/core/memdev.c
index 61029cb7ac62..1f76b28f9826 100644
--- a/drivers/cxl/core/memdev.c
+++ b/drivers/cxl/core/memdev.c
@@ -89,10 +89,29 @@ static ssize_t pmem_size_show(struct device *dev, struct device_attribute *attr,
static struct device_attribute dev_attr_pmem_size =
__ATTR(size, 0444, pmem_size_show, NULL);
+static ssize_t serial_show(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ struct cxl_memdev *cxlmd = to_cxl_memdev(dev);
+ struct cxl_dev_state *cxlds = cxlmd->cxlds;
+
+ return sysfs_emit(buf, "%#llx\n", cxlds->serial);
+}
+static DEVICE_ATTR_RO(serial);
+
+static ssize_t numa_node_show(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ return sprintf(buf, "%d\n", dev_to_node(dev));
+}
+static DEVICE_ATTR_RO(numa_node);
+
static struct attribute *cxl_memdev_attributes[] = {
+ &dev_attr_serial.attr,
&dev_attr_firmware_version.attr,
&dev_attr_payload_max.attr,
&dev_attr_label_storage_size.attr,
+ &dev_attr_numa_node.attr,
NULL,
};
@@ -106,8 +125,17 @@ static struct attribute *cxl_memdev_ram_attributes[] = {
NULL,
};
+static umode_t cxl_memdev_visible(struct kobject *kobj, struct attribute *a,
+ int n)
+{
+ if (!IS_ENABLED(CONFIG_NUMA) && a == &dev_attr_numa_node.attr)
+ return 0;
+ return a->mode;
+}
+
static struct attribute_group cxl_memdev_attribute_group = {
.attrs = cxl_memdev_attributes,
+ .is_visible = cxl_memdev_visible,
};
static struct attribute_group cxl_memdev_ram_attribute_group = {
@@ -134,6 +162,12 @@ static const struct device_type cxl_memdev_type = {
.groups = cxl_memdev_attribute_groups,
};
+bool is_cxl_memdev(struct device *dev)
+{
+ return dev->type == &cxl_memdev_type;
+}
+EXPORT_SYMBOL_NS_GPL(is_cxl_memdev, CXL);
+
/**
* set_exclusive_cxl_commands() - atomically disable user cxl commands
* @cxlds: The device state to operate on
@@ -185,6 +219,15 @@ static void cxl_memdev_unregister(void *_cxlmd)
put_device(dev);
}
+static void detach_memdev(struct work_struct *work)
+{
+ struct cxl_memdev *cxlmd;
+
+ cxlmd = container_of(work, typeof(*cxlmd), detach_work);
+ device_release_driver(&cxlmd->dev);
+ put_device(&cxlmd->dev);
+}
+
static struct cxl_memdev *cxl_memdev_alloc(struct cxl_dev_state *cxlds,
const struct file_operations *fops)
{
@@ -209,6 +252,7 @@ static struct cxl_memdev *cxl_memdev_alloc(struct cxl_dev_state *cxlds,
dev->devt = MKDEV(cxl_mem_major, cxlmd->id);
dev->type = &cxl_memdev_type;
device_set_pm_not_required(dev);
+ INIT_WORK(&cxlmd->detach_work, detach_memdev);
cdev = &cxlmd->cdev;
cdev_init(cdev, fops);
diff --git a/drivers/cxl/core/pci.c b/drivers/cxl/core/pci.c
new file mode 100644
index 000000000000..c9a494d6976a
--- /dev/null
+++ b/drivers/cxl/core/pci.c
@@ -0,0 +1,96 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/* Copyright(c) 2021 Intel Corporation. All rights reserved. */
+#include <linux/device.h>
+#include <linux/pci.h>
+#include <cxlpci.h>
+#include <cxl.h>
+#include "core.h"
+
+/**
+ * DOC: cxl core pci
+ *
+ * Compute Express Link protocols are layered on top of PCIe. CXL core provides
+ * a set of helpers for CXL interactions which occur via PCIe.
+ */
+
+struct cxl_walk_context {
+ struct pci_bus *bus;
+ struct cxl_port *port;
+ int type;
+ int error;
+ int count;
+};
+
+static int match_add_dports(struct pci_dev *pdev, void *data)
+{
+ struct cxl_walk_context *ctx = data;
+ struct cxl_port *port = ctx->port;
+ int type = pci_pcie_type(pdev);
+ struct cxl_register_map map;
+ struct cxl_dport *dport;
+ u32 lnkcap, port_num;
+ int rc;
+
+ if (pdev->bus != ctx->bus)
+ return 0;
+ if (!pci_is_pcie(pdev))
+ return 0;
+ if (type != ctx->type)
+ return 0;
+ if (pci_read_config_dword(pdev, pci_pcie_cap(pdev) + PCI_EXP_LNKCAP,
+ &lnkcap))
+ return 0;
+
+ rc = cxl_find_regblock(pdev, CXL_REGLOC_RBI_COMPONENT, &map);
+ if (rc)
+ dev_dbg(&port->dev, "failed to find component registers\n");
+
+ port_num = FIELD_GET(PCI_EXP_LNKCAP_PN, lnkcap);
+ dport = devm_cxl_add_dport(port, &pdev->dev, port_num,
+ cxl_regmap_to_base(pdev, &map));
+ if (IS_ERR(dport)) {
+ ctx->error = PTR_ERR(dport);
+ return PTR_ERR(dport);
+ }
+ ctx->count++;
+
+ dev_dbg(&port->dev, "add dport%d: %s\n", port_num, dev_name(&pdev->dev));
+
+ return 0;
+}
+
+/**
+ * devm_cxl_port_enumerate_dports - enumerate downstream ports of the upstream port
+ * @port: cxl_port whose ->uport is the upstream of dports to be enumerated
+ *
+ * Returns a positive number of dports enumerated or a negative error
+ * code.
+ */
+int devm_cxl_port_enumerate_dports(struct cxl_port *port)
+{
+ struct pci_bus *bus = cxl_port_to_pci_bus(port);
+ struct cxl_walk_context ctx;
+ int type;
+
+ if (!bus)
+ return -ENXIO;
+
+ if (pci_is_root_bus(bus))
+ type = PCI_EXP_TYPE_ROOT_PORT;
+ else
+ type = PCI_EXP_TYPE_DOWNSTREAM;
+
+ ctx = (struct cxl_walk_context) {
+ .port = port,
+ .bus = bus,
+ .type = type,
+ };
+ pci_walk_bus(bus, match_add_dports, &ctx);
+
+ if (ctx.count == 0)
+ return -ENODEV;
+ if (ctx.error)
+ return ctx.error;
+ return ctx.count;
+}
+EXPORT_SYMBOL_NS_GPL(devm_cxl_port_enumerate_dports, CXL);
diff --git a/drivers/cxl/core/pmem.c b/drivers/cxl/core/pmem.c
index b5fca97b0a07..8de240c4d96b 100644
--- a/drivers/cxl/core/pmem.c
+++ b/drivers/cxl/core/pmem.c
@@ -57,24 +57,30 @@ bool is_cxl_nvdimm_bridge(struct device *dev)
}
EXPORT_SYMBOL_NS_GPL(is_cxl_nvdimm_bridge, CXL);
-__mock int match_nvdimm_bridge(struct device *dev, const void *data)
+static int match_nvdimm_bridge(struct device *dev, void *data)
{
return is_cxl_nvdimm_bridge(dev);
}
struct cxl_nvdimm_bridge *cxl_find_nvdimm_bridge(struct cxl_nvdimm *cxl_nvd)
{
+ struct cxl_port *port = find_cxl_root(&cxl_nvd->dev);
struct device *dev;
- dev = bus_find_device(&cxl_bus_type, NULL, cxl_nvd, match_nvdimm_bridge);
+ if (!port)
+ return NULL;
+
+ dev = device_find_child(&port->dev, NULL, match_nvdimm_bridge);
+ put_device(&port->dev);
+
if (!dev)
return NULL;
+
return to_cxl_nvdimm_bridge(dev);
}
EXPORT_SYMBOL_NS_GPL(cxl_find_nvdimm_bridge, CXL);
-static struct cxl_nvdimm_bridge *
-cxl_nvdimm_bridge_alloc(struct cxl_port *port)
+static struct cxl_nvdimm_bridge *cxl_nvdimm_bridge_alloc(struct cxl_port *port)
{
struct cxl_nvdimm_bridge *cxl_nvb;
struct device *dev;
@@ -115,10 +121,10 @@ static void unregister_nvb(void *_cxl_nvb)
* work to flush. Once the state has been changed to 'dead' then no new
* work can be queued by user-triggered bind.
*/
- device_lock(&cxl_nvb->dev);
+ cxl_device_lock(&cxl_nvb->dev);
flush = cxl_nvb->state != CXL_NVB_NEW;
cxl_nvb->state = CXL_NVB_DEAD;
- device_unlock(&cxl_nvb->dev);
+ cxl_device_unlock(&cxl_nvb->dev);
/*
* Even though the device core will trigger device_release_driver()
diff --git a/drivers/cxl/core/port.c b/drivers/cxl/core/port.c
new file mode 100644
index 000000000000..2ab1ba4499b3
--- /dev/null
+++ b/drivers/cxl/core/port.c
@@ -0,0 +1,1568 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/* Copyright(c) 2020 Intel Corporation. All rights reserved. */
+#include <linux/io-64-nonatomic-lo-hi.h>
+#include <linux/workqueue.h>
+#include <linux/device.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/slab.h>
+#include <linux/idr.h>
+#include <cxlmem.h>
+#include <cxlpci.h>
+#include <cxl.h>
+#include "core.h"
+
+/**
+ * DOC: cxl core
+ *
+ * The CXL core provides a set of interfaces that can be consumed by CXL aware
+ * drivers. The interfaces allow for creation, modification, and destruction of
+ * regions, memory devices, ports, and decoders. CXL aware drivers must register
+ * with the CXL core via these interfaces in order to be able to participate in
+ * cross-device interleave coordination. The CXL core also establishes and
+ * maintains the bridge to the nvdimm subsystem.
+ *
+ * CXL core introduces sysfs hierarchy to control the devices that are
+ * instantiated by the core.
+ */
+
+static DEFINE_IDA(cxl_port_ida);
+static DEFINE_XARRAY(cxl_root_buses);
+
+static ssize_t devtype_show(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ return sysfs_emit(buf, "%s\n", dev->type->name);
+}
+static DEVICE_ATTR_RO(devtype);
+
+static int cxl_device_id(struct device *dev)
+{
+ if (dev->type == &cxl_nvdimm_bridge_type)
+ return CXL_DEVICE_NVDIMM_BRIDGE;
+ if (dev->type == &cxl_nvdimm_type)
+ return CXL_DEVICE_NVDIMM;
+ if (is_cxl_port(dev)) {
+ if (is_cxl_root(to_cxl_port(dev)))
+ return CXL_DEVICE_ROOT;
+ return CXL_DEVICE_PORT;
+ }
+ if (is_cxl_memdev(dev))
+ return CXL_DEVICE_MEMORY_EXPANDER;
+ return 0;
+}
+
+static ssize_t modalias_show(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ return sysfs_emit(buf, CXL_MODALIAS_FMT "\n", cxl_device_id(dev));
+}
+static DEVICE_ATTR_RO(modalias);
+
+static struct attribute *cxl_base_attributes[] = {
+ &dev_attr_devtype.attr,
+ &dev_attr_modalias.attr,
+ NULL,
+};
+
+struct attribute_group cxl_base_attribute_group = {
+ .attrs = cxl_base_attributes,
+};
+
+static ssize_t start_show(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ struct cxl_decoder *cxld = to_cxl_decoder(dev);
+ u64 start;
+
+ if (is_root_decoder(dev))
+ start = cxld->platform_res.start;
+ else
+ start = cxld->decoder_range.start;
+
+ return sysfs_emit(buf, "%#llx\n", start);
+}
+static DEVICE_ATTR_ADMIN_RO(start);
+
+static ssize_t size_show(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ struct cxl_decoder *cxld = to_cxl_decoder(dev);
+ u64 size;
+
+ if (is_root_decoder(dev))
+ size = resource_size(&cxld->platform_res);
+ else
+ size = range_len(&cxld->decoder_range);
+
+ return sysfs_emit(buf, "%#llx\n", size);
+}
+static DEVICE_ATTR_RO(size);
+
+#define CXL_DECODER_FLAG_ATTR(name, flag) \
+static ssize_t name##_show(struct device *dev, \
+ struct device_attribute *attr, char *buf) \
+{ \
+ struct cxl_decoder *cxld = to_cxl_decoder(dev); \
+ \
+ return sysfs_emit(buf, "%s\n", \
+ (cxld->flags & (flag)) ? "1" : "0"); \
+} \
+static DEVICE_ATTR_RO(name)
+
+CXL_DECODER_FLAG_ATTR(cap_pmem, CXL_DECODER_F_PMEM);
+CXL_DECODER_FLAG_ATTR(cap_ram, CXL_DECODER_F_RAM);
+CXL_DECODER_FLAG_ATTR(cap_type2, CXL_DECODER_F_TYPE2);
+CXL_DECODER_FLAG_ATTR(cap_type3, CXL_DECODER_F_TYPE3);
+CXL_DECODER_FLAG_ATTR(locked, CXL_DECODER_F_LOCK);
+
+static ssize_t target_type_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct cxl_decoder *cxld = to_cxl_decoder(dev);
+
+ switch (cxld->target_type) {
+ case CXL_DECODER_ACCELERATOR:
+ return sysfs_emit(buf, "accelerator\n");
+ case CXL_DECODER_EXPANDER:
+ return sysfs_emit(buf, "expander\n");
+ }
+ return -ENXIO;
+}
+static DEVICE_ATTR_RO(target_type);
+
+static ssize_t emit_target_list(struct cxl_decoder *cxld, char *buf)
+{
+ ssize_t offset = 0;
+ int i, rc = 0;
+
+ for (i = 0; i < cxld->interleave_ways; i++) {
+ struct cxl_dport *dport = cxld->target[i];
+ struct cxl_dport *next = NULL;
+
+ if (!dport)
+ break;
+
+ if (i + 1 < cxld->interleave_ways)
+ next = cxld->target[i + 1];
+ rc = sysfs_emit_at(buf, offset, "%d%s", dport->port_id,
+ next ? "," : "");
+ if (rc < 0)
+ return rc;
+ offset += rc;
+ }
+
+ return offset;
+}
+
+static ssize_t target_list_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct cxl_decoder *cxld = to_cxl_decoder(dev);
+ ssize_t offset;
+ unsigned int seq;
+ int rc;
+
+ do {
+ seq = read_seqbegin(&cxld->target_lock);
+ rc = emit_target_list(cxld, buf);
+ } while (read_seqretry(&cxld->target_lock, seq));
+
+ if (rc < 0)
+ return rc;
+ offset = rc;
+
+ rc = sysfs_emit_at(buf, offset, "\n");
+ if (rc < 0)
+ return rc;
+
+ return offset + rc;
+}
+static DEVICE_ATTR_RO(target_list);
+
+static struct attribute *cxl_decoder_base_attrs[] = {
+ &dev_attr_start.attr,
+ &dev_attr_size.attr,
+ &dev_attr_locked.attr,
+ NULL,
+};
+
+static struct attribute_group cxl_decoder_base_attribute_group = {
+ .attrs = cxl_decoder_base_attrs,
+};
+
+static struct attribute *cxl_decoder_root_attrs[] = {
+ &dev_attr_cap_pmem.attr,
+ &dev_attr_cap_ram.attr,
+ &dev_attr_cap_type2.attr,
+ &dev_attr_cap_type3.attr,
+ &dev_attr_target_list.attr,
+ NULL,
+};
+
+static struct attribute_group cxl_decoder_root_attribute_group = {
+ .attrs = cxl_decoder_root_attrs,
+};
+
+static const struct attribute_group *cxl_decoder_root_attribute_groups[] = {
+ &cxl_decoder_root_attribute_group,
+ &cxl_decoder_base_attribute_group,
+ &cxl_base_attribute_group,
+ NULL,
+};
+
+static struct attribute *cxl_decoder_switch_attrs[] = {
+ &dev_attr_target_type.attr,
+ &dev_attr_target_list.attr,
+ NULL,
+};
+
+static struct attribute_group cxl_decoder_switch_attribute_group = {
+ .attrs = cxl_decoder_switch_attrs,
+};
+
+static const struct attribute_group *cxl_decoder_switch_attribute_groups[] = {
+ &cxl_decoder_switch_attribute_group,
+ &cxl_decoder_base_attribute_group,
+ &cxl_base_attribute_group,
+ NULL,
+};
+
+static struct attribute *cxl_decoder_endpoint_attrs[] = {
+ &dev_attr_target_type.attr,
+ NULL,
+};
+
+static struct attribute_group cxl_decoder_endpoint_attribute_group = {
+ .attrs = cxl_decoder_endpoint_attrs,
+};
+
+static const struct attribute_group *cxl_decoder_endpoint_attribute_groups[] = {
+ &cxl_decoder_base_attribute_group,
+ &cxl_decoder_endpoint_attribute_group,
+ &cxl_base_attribute_group,
+ NULL,
+};
+
+static void cxl_decoder_release(struct device *dev)
+{
+ struct cxl_decoder *cxld = to_cxl_decoder(dev);
+ struct cxl_port *port = to_cxl_port(dev->parent);
+
+ ida_free(&port->decoder_ida, cxld->id);
+ kfree(cxld);
+ put_device(&port->dev);
+}
+
+static const struct device_type cxl_decoder_endpoint_type = {
+ .name = "cxl_decoder_endpoint",
+ .release = cxl_decoder_release,
+ .groups = cxl_decoder_endpoint_attribute_groups,
+};
+
+static const struct device_type cxl_decoder_switch_type = {
+ .name = "cxl_decoder_switch",
+ .release = cxl_decoder_release,
+ .groups = cxl_decoder_switch_attribute_groups,
+};
+
+static const struct device_type cxl_decoder_root_type = {
+ .name = "cxl_decoder_root",
+ .release = cxl_decoder_release,
+ .groups = cxl_decoder_root_attribute_groups,
+};
+
+static bool is_endpoint_decoder(struct device *dev)
+{
+ return dev->type == &cxl_decoder_endpoint_type;
+}
+
+bool is_root_decoder(struct device *dev)
+{
+ return dev->type == &cxl_decoder_root_type;
+}
+EXPORT_SYMBOL_NS_GPL(is_root_decoder, CXL);
+
+bool is_cxl_decoder(struct device *dev)
+{
+ return dev->type && dev->type->release == cxl_decoder_release;
+}
+EXPORT_SYMBOL_NS_GPL(is_cxl_decoder, CXL);
+
+struct cxl_decoder *to_cxl_decoder(struct device *dev)
+{
+ if (dev_WARN_ONCE(dev, dev->type->release != cxl_decoder_release,
+ "not a cxl_decoder device\n"))
+ return NULL;
+ return container_of(dev, struct cxl_decoder, dev);
+}
+EXPORT_SYMBOL_NS_GPL(to_cxl_decoder, CXL);
+
+static void cxl_ep_release(struct cxl_ep *ep)
+{
+ if (!ep)
+ return;
+ list_del(&ep->list);
+ put_device(ep->ep);
+ kfree(ep);
+}
+
+static void cxl_port_release(struct device *dev)
+{
+ struct cxl_port *port = to_cxl_port(dev);
+ struct cxl_ep *ep, *_e;
+
+ cxl_device_lock(dev);
+ list_for_each_entry_safe(ep, _e, &port->endpoints, list)
+ cxl_ep_release(ep);
+ cxl_device_unlock(dev);
+ ida_free(&cxl_port_ida, port->id);
+ kfree(port);
+}
+
+static const struct attribute_group *cxl_port_attribute_groups[] = {
+ &cxl_base_attribute_group,
+ NULL,
+};
+
+static const struct device_type cxl_port_type = {
+ .name = "cxl_port",
+ .release = cxl_port_release,
+ .groups = cxl_port_attribute_groups,
+};
+
+bool is_cxl_port(struct device *dev)
+{
+ return dev->type == &cxl_port_type;
+}
+EXPORT_SYMBOL_NS_GPL(is_cxl_port, CXL);
+
+struct cxl_port *to_cxl_port(struct device *dev)
+{
+ if (dev_WARN_ONCE(dev, dev->type != &cxl_port_type,
+ "not a cxl_port device\n"))
+ return NULL;
+ return container_of(dev, struct cxl_port, dev);
+}
+EXPORT_SYMBOL_NS_GPL(to_cxl_port, CXL);
+
+static void unregister_port(void *_port)
+{
+ struct cxl_port *port = _port;
+ struct cxl_port *parent;
+ struct device *lock_dev;
+
+ if (is_cxl_root(port))
+ parent = NULL;
+ else
+ parent = to_cxl_port(port->dev.parent);
+
+ /*
+ * CXL root port's and the first level of ports are unregistered
+ * under the platform firmware device lock, all other ports are
+ * unregistered while holding their parent port lock.
+ */
+ if (!parent)
+ lock_dev = port->uport;
+ else if (is_cxl_root(parent))
+ lock_dev = parent->uport;
+ else
+ lock_dev = &parent->dev;
+
+ device_lock_assert(lock_dev);
+ port->uport = NULL;
+ device_unregister(&port->dev);
+}
+
+static void cxl_unlink_uport(void *_port)
+{
+ struct cxl_port *port = _port;
+
+ sysfs_remove_link(&port->dev.kobj, "uport");
+}
+
+static int devm_cxl_link_uport(struct device *host, struct cxl_port *port)
+{
+ int rc;
+
+ rc = sysfs_create_link(&port->dev.kobj, &port->uport->kobj, "uport");
+ if (rc)
+ return rc;
+ return devm_add_action_or_reset(host, cxl_unlink_uport, port);
+}
+
+static struct cxl_port *cxl_port_alloc(struct device *uport,
+ resource_size_t component_reg_phys,
+ struct cxl_port *parent_port)
+{
+ struct cxl_port *port;
+ struct device *dev;
+ int rc;
+
+ port = kzalloc(sizeof(*port), GFP_KERNEL);
+ if (!port)
+ return ERR_PTR(-ENOMEM);
+
+ rc = ida_alloc(&cxl_port_ida, GFP_KERNEL);
+ if (rc < 0)
+ goto err;
+ port->id = rc;
+
+ /*
+ * The top-level cxl_port "cxl_root" does not have a cxl_port as
+ * its parent and it does not have any corresponding component
+ * registers as its decode is described by a fixed platform
+ * description.
+ */
+ dev = &port->dev;
+ if (parent_port)
+ dev->parent = &parent_port->dev;
+ else
+ dev->parent = uport;
+
+ port->uport = uport;
+ port->component_reg_phys = component_reg_phys;
+ ida_init(&port->decoder_ida);
+ INIT_LIST_HEAD(&port->dports);
+ INIT_LIST_HEAD(&port->endpoints);
+
+ device_initialize(dev);
+ device_set_pm_not_required(dev);
+ dev->bus = &cxl_bus_type;
+ dev->type = &cxl_port_type;
+
+ return port;
+
+err:
+ kfree(port);
+ return ERR_PTR(rc);
+}
+
+/**
+ * devm_cxl_add_port - register a cxl_port in CXL memory decode hierarchy
+ * @host: host device for devm operations
+ * @uport: "physical" device implementing this upstream port
+ * @component_reg_phys: (optional) for configurable cxl_port instances
+ * @parent_port: next hop up in the CXL memory decode hierarchy
+ */
+struct cxl_port *devm_cxl_add_port(struct device *host, struct device *uport,
+ resource_size_t component_reg_phys,
+ struct cxl_port *parent_port)
+{
+ struct cxl_port *port;
+ struct device *dev;
+ int rc;
+
+ port = cxl_port_alloc(uport, component_reg_phys, parent_port);
+ if (IS_ERR(port))
+ return port;
+
+ if (parent_port)
+ port->depth = parent_port->depth + 1;
+ dev = &port->dev;
+ if (is_cxl_memdev(uport))
+ rc = dev_set_name(dev, "endpoint%d", port->id);
+ else if (parent_port)
+ rc = dev_set_name(dev, "port%d", port->id);
+ else
+ rc = dev_set_name(dev, "root%d", port->id);
+ if (rc)
+ goto err;
+
+ rc = device_add(dev);
+ if (rc)
+ goto err;
+
+ rc = devm_add_action_or_reset(host, unregister_port, port);
+ if (rc)
+ return ERR_PTR(rc);
+
+ rc = devm_cxl_link_uport(host, port);
+ if (rc)
+ return ERR_PTR(rc);
+
+ return port;
+
+err:
+ put_device(dev);
+ return ERR_PTR(rc);
+}
+EXPORT_SYMBOL_NS_GPL(devm_cxl_add_port, CXL);
+
+struct pci_bus *cxl_port_to_pci_bus(struct cxl_port *port)
+{
+ /* There is no pci_bus associated with a CXL platform-root port */
+ if (is_cxl_root(port))
+ return NULL;
+
+ if (dev_is_pci(port->uport)) {
+ struct pci_dev *pdev = to_pci_dev(port->uport);
+
+ return pdev->subordinate;
+ }
+
+ return xa_load(&cxl_root_buses, (unsigned long)port->uport);
+}
+EXPORT_SYMBOL_NS_GPL(cxl_port_to_pci_bus, CXL);
+
+static void unregister_pci_bus(void *uport)
+{
+ xa_erase(&cxl_root_buses, (unsigned long)uport);
+}
+
+int devm_cxl_register_pci_bus(struct device *host, struct device *uport,
+ struct pci_bus *bus)
+{
+ int rc;
+
+ if (dev_is_pci(uport))
+ return -EINVAL;
+
+ rc = xa_insert(&cxl_root_buses, (unsigned long)uport, bus, GFP_KERNEL);
+ if (rc)
+ return rc;
+ return devm_add_action_or_reset(host, unregister_pci_bus, uport);
+}
+EXPORT_SYMBOL_NS_GPL(devm_cxl_register_pci_bus, CXL);
+
+static bool dev_is_cxl_root_child(struct device *dev)
+{
+ struct cxl_port *port, *parent;
+
+ if (!is_cxl_port(dev))
+ return false;
+
+ port = to_cxl_port(dev);
+ if (is_cxl_root(port))
+ return false;
+
+ parent = to_cxl_port(port->dev.parent);
+ if (is_cxl_root(parent))
+ return true;
+
+ return false;
+}
+
+/* Find a 2nd level CXL port that has a dport that is an ancestor of @match */
+static int match_root_child(struct device *dev, const void *match)
+{
+ const struct device *iter = NULL;
+ struct cxl_dport *dport;
+ struct cxl_port *port;
+
+ if (!dev_is_cxl_root_child(dev))
+ return 0;
+
+ port = to_cxl_port(dev);
+ cxl_device_lock(dev);
+ list_for_each_entry(dport, &port->dports, list) {
+ iter = match;
+ while (iter) {
+ if (iter == dport->dport)
+ goto out;
+ iter = iter->parent;
+ }
+ }
+out:
+ cxl_device_unlock(dev);
+
+ return !!iter;
+}
+
+struct cxl_port *find_cxl_root(struct device *dev)
+{
+ struct device *port_dev;
+ struct cxl_port *root;
+
+ port_dev = bus_find_device(&cxl_bus_type, NULL, dev, match_root_child);
+ if (!port_dev)
+ return NULL;
+
+ root = to_cxl_port(port_dev->parent);
+ get_device(&root->dev);
+ put_device(port_dev);
+ return root;
+}
+EXPORT_SYMBOL_NS_GPL(find_cxl_root, CXL);
+
+static struct cxl_dport *find_dport(struct cxl_port *port, int id)
+{
+ struct cxl_dport *dport;
+
+ device_lock_assert(&port->dev);
+ list_for_each_entry (dport, &port->dports, list)
+ if (dport->port_id == id)
+ return dport;
+ return NULL;
+}
+
+static int add_dport(struct cxl_port *port, struct cxl_dport *new)
+{
+ struct cxl_dport *dup;
+
+ device_lock_assert(&port->dev);
+ dup = find_dport(port, new->port_id);
+ if (dup)
+ dev_err(&port->dev,
+ "unable to add dport%d-%s non-unique port id (%s)\n",
+ new->port_id, dev_name(new->dport),
+ dev_name(dup->dport));
+ else
+ list_add_tail(&new->list, &port->dports);
+
+ return dup ? -EEXIST : 0;
+}
+
+/*
+ * Since root-level CXL dports cannot be enumerated by PCI they are not
+ * enumerated by the common port driver that acquires the port lock over
+ * dport add/remove. Instead, root dports are manually added by a
+ * platform driver and cond_cxl_root_lock() is used to take the missing
+ * port lock in that case.
+ */
+static void cond_cxl_root_lock(struct cxl_port *port)
+{
+ if (is_cxl_root(port))
+ cxl_device_lock(&port->dev);
+}
+
+static void cond_cxl_root_unlock(struct cxl_port *port)
+{
+ if (is_cxl_root(port))
+ cxl_device_unlock(&port->dev);
+}
+
+static void cxl_dport_remove(void *data)
+{
+ struct cxl_dport *dport = data;
+ struct cxl_port *port = dport->port;
+
+ put_device(dport->dport);
+ cond_cxl_root_lock(port);
+ list_del(&dport->list);
+ cond_cxl_root_unlock(port);
+}
+
+static void cxl_dport_unlink(void *data)
+{
+ struct cxl_dport *dport = data;
+ struct cxl_port *port = dport->port;
+ char link_name[CXL_TARGET_STRLEN];
+
+ sprintf(link_name, "dport%d", dport->port_id);
+ sysfs_remove_link(&port->dev.kobj, link_name);
+}
+
+/**
+ * devm_cxl_add_dport - append downstream port data to a cxl_port
+ * @port: the cxl_port that references this dport
+ * @dport_dev: firmware or PCI device representing the dport
+ * @port_id: identifier for this dport in a decoder's target list
+ * @component_reg_phys: optional location of CXL component registers
+ *
+ * Note that dports are appended to the devm release action's of the
+ * either the port's host (for root ports), or the port itself (for
+ * switch ports)
+ */
+struct cxl_dport *devm_cxl_add_dport(struct cxl_port *port,
+ struct device *dport_dev, int port_id,
+ resource_size_t component_reg_phys)
+{
+ char link_name[CXL_TARGET_STRLEN];
+ struct cxl_dport *dport;
+ struct device *host;
+ int rc;
+
+ if (is_cxl_root(port))
+ host = port->uport;
+ else
+ host = &port->dev;
+
+ if (!host->driver) {
+ dev_WARN_ONCE(&port->dev, 1, "dport:%s bad devm context\n",
+ dev_name(dport_dev));
+ return ERR_PTR(-ENXIO);
+ }
+
+ if (snprintf(link_name, CXL_TARGET_STRLEN, "dport%d", port_id) >=
+ CXL_TARGET_STRLEN)
+ return ERR_PTR(-EINVAL);
+
+ dport = devm_kzalloc(host, sizeof(*dport), GFP_KERNEL);
+ if (!dport)
+ return ERR_PTR(-ENOMEM);
+
+ INIT_LIST_HEAD(&dport->list);
+ dport->dport = dport_dev;
+ dport->port_id = port_id;
+ dport->component_reg_phys = component_reg_phys;
+ dport->port = port;
+
+ cond_cxl_root_lock(port);
+ rc = add_dport(port, dport);
+ cond_cxl_root_unlock(port);
+ if (rc)
+ return ERR_PTR(rc);
+
+ get_device(dport_dev);
+ rc = devm_add_action_or_reset(host, cxl_dport_remove, dport);
+ if (rc)
+ return ERR_PTR(rc);
+
+ rc = sysfs_create_link(&port->dev.kobj, &dport_dev->kobj, link_name);
+ if (rc)
+ return ERR_PTR(rc);
+
+ rc = devm_add_action_or_reset(host, cxl_dport_unlink, dport);
+ if (rc)
+ return ERR_PTR(rc);
+
+ return dport;
+}
+EXPORT_SYMBOL_NS_GPL(devm_cxl_add_dport, CXL);
+
+static struct cxl_ep *find_ep(struct cxl_port *port, struct device *ep_dev)
+{
+ struct cxl_ep *ep;
+
+ device_lock_assert(&port->dev);
+ list_for_each_entry(ep, &port->endpoints, list)
+ if (ep->ep == ep_dev)
+ return ep;
+ return NULL;
+}
+
+static int add_ep(struct cxl_port *port, struct cxl_ep *new)
+{
+ struct cxl_ep *dup;
+
+ cxl_device_lock(&port->dev);
+ if (port->dead) {
+ cxl_device_unlock(&port->dev);
+ return -ENXIO;
+ }
+ dup = find_ep(port, new->ep);
+ if (!dup)
+ list_add_tail(&new->list, &port->endpoints);
+ cxl_device_unlock(&port->dev);
+
+ return dup ? -EEXIST : 0;
+}
+
+/**
+ * cxl_add_ep - register an endpoint's interest in a port
+ * @port: a port in the endpoint's topology ancestry
+ * @ep_dev: device representing the endpoint
+ *
+ * Intermediate CXL ports are scanned based on the arrival of endpoints.
+ * When those endpoints depart the port can be destroyed once all
+ * endpoints that care about that port have been removed.
+ */
+static int cxl_add_ep(struct cxl_port *port, struct device *ep_dev)
+{
+ struct cxl_ep *ep;
+ int rc;
+
+ ep = kzalloc(sizeof(*ep), GFP_KERNEL);
+ if (!ep)
+ return -ENOMEM;
+
+ INIT_LIST_HEAD(&ep->list);
+ ep->ep = get_device(ep_dev);
+
+ rc = add_ep(port, ep);
+ if (rc)
+ cxl_ep_release(ep);
+ return rc;
+}
+
+struct cxl_find_port_ctx {
+ const struct device *dport_dev;
+ const struct cxl_port *parent_port;
+};
+
+static int match_port_by_dport(struct device *dev, const void *data)
+{
+ const struct cxl_find_port_ctx *ctx = data;
+ struct cxl_port *port;
+
+ if (!is_cxl_port(dev))
+ return 0;
+ if (ctx->parent_port && dev->parent != &ctx->parent_port->dev)
+ return 0;
+
+ port = to_cxl_port(dev);
+ return cxl_find_dport_by_dev(port, ctx->dport_dev) != NULL;
+}
+
+static struct cxl_port *__find_cxl_port(struct cxl_find_port_ctx *ctx)
+{
+ struct device *dev;
+
+ if (!ctx->dport_dev)
+ return NULL;
+
+ dev = bus_find_device(&cxl_bus_type, NULL, ctx, match_port_by_dport);
+ if (dev)
+ return to_cxl_port(dev);
+ return NULL;
+}
+
+static struct cxl_port *find_cxl_port(struct device *dport_dev)
+{
+ struct cxl_find_port_ctx ctx = {
+ .dport_dev = dport_dev,
+ };
+
+ return __find_cxl_port(&ctx);
+}
+
+static struct cxl_port *find_cxl_port_at(struct cxl_port *parent_port,
+ struct device *dport_dev)
+{
+ struct cxl_find_port_ctx ctx = {
+ .dport_dev = dport_dev,
+ .parent_port = parent_port,
+ };
+
+ return __find_cxl_port(&ctx);
+}
+
+/*
+ * All users of grandparent() are using it to walk PCIe-like swich port
+ * hierarchy. A PCIe switch is comprised of a bridge device representing the
+ * upstream switch port and N bridges representing downstream switch ports. When
+ * bridges stack the grand-parent of a downstream switch port is another
+ * downstream switch port in the immediate ancestor switch.
+ */
+static struct device *grandparent(struct device *dev)
+{
+ if (dev && dev->parent)
+ return dev->parent->parent;
+ return NULL;
+}
+
+static void delete_endpoint(void *data)
+{
+ struct cxl_memdev *cxlmd = data;
+ struct cxl_port *endpoint = dev_get_drvdata(&cxlmd->dev);
+ struct cxl_port *parent_port;
+ struct device *parent;
+
+ parent_port = cxl_mem_find_port(cxlmd);
+ if (!parent_port)
+ goto out;
+ parent = &parent_port->dev;
+
+ cxl_device_lock(parent);
+ if (parent->driver && endpoint->uport) {
+ devm_release_action(parent, cxl_unlink_uport, endpoint);
+ devm_release_action(parent, unregister_port, endpoint);
+ }
+ cxl_device_unlock(parent);
+ put_device(parent);
+out:
+ put_device(&endpoint->dev);
+}
+
+int cxl_endpoint_autoremove(struct cxl_memdev *cxlmd, struct cxl_port *endpoint)
+{
+ struct device *dev = &cxlmd->dev;
+
+ get_device(&endpoint->dev);
+ dev_set_drvdata(dev, endpoint);
+ return devm_add_action_or_reset(dev, delete_endpoint, cxlmd);
+}
+EXPORT_SYMBOL_NS_GPL(cxl_endpoint_autoremove, CXL);
+
+/*
+ * The natural end of life of a non-root 'cxl_port' is when its parent port goes
+ * through a ->remove() event ("top-down" unregistration). The unnatural trigger
+ * for a port to be unregistered is when all memdevs beneath that port have gone
+ * through ->remove(). This "bottom-up" removal selectively removes individual
+ * child ports manually. This depends on devm_cxl_add_port() to not change is
+ * devm action registration order.
+ */
+static void delete_switch_port(struct cxl_port *port, struct list_head *dports)
+{
+ struct cxl_dport *dport, *_d;
+
+ list_for_each_entry_safe(dport, _d, dports, list) {
+ devm_release_action(&port->dev, cxl_dport_unlink, dport);
+ devm_release_action(&port->dev, cxl_dport_remove, dport);
+ devm_kfree(&port->dev, dport);
+ }
+ devm_release_action(port->dev.parent, cxl_unlink_uport, port);
+ devm_release_action(port->dev.parent, unregister_port, port);
+}
+
+static void cxl_detach_ep(void *data)
+{
+ struct cxl_memdev *cxlmd = data;
+ struct device *iter;
+
+ for (iter = &cxlmd->dev; iter; iter = grandparent(iter)) {
+ struct device *dport_dev = grandparent(iter);
+ struct cxl_port *port, *parent_port;
+ LIST_HEAD(reap_dports);
+ struct cxl_ep *ep;
+
+ if (!dport_dev)
+ break;
+
+ port = find_cxl_port(dport_dev);
+ if (!port)
+ continue;
+
+ if (is_cxl_root(port)) {
+ put_device(&port->dev);
+ continue;
+ }
+
+ parent_port = to_cxl_port(port->dev.parent);
+ cxl_device_lock(&parent_port->dev);
+ if (!parent_port->dev.driver) {
+ /*
+ * The bottom-up race to delete the port lost to a
+ * top-down port disable, give up here, because the
+ * parent_port ->remove() will have cleaned up all
+ * descendants.
+ */
+ cxl_device_unlock(&parent_port->dev);
+ put_device(&port->dev);
+ continue;
+ }
+
+ cxl_device_lock(&port->dev);
+ ep = find_ep(port, &cxlmd->dev);
+ dev_dbg(&cxlmd->dev, "disconnect %s from %s\n",
+ ep ? dev_name(ep->ep) : "", dev_name(&port->dev));
+ cxl_ep_release(ep);
+ if (ep && !port->dead && list_empty(&port->endpoints) &&
+ !is_cxl_root(parent_port)) {
+ /*
+ * This was the last ep attached to a dynamically
+ * enumerated port. Block new cxl_add_ep() and garbage
+ * collect the port.
+ */
+ port->dead = true;
+ list_splice_init(&port->dports, &reap_dports);
+ }
+ cxl_device_unlock(&port->dev);
+
+ if (!list_empty(&reap_dports)) {
+ dev_dbg(&cxlmd->dev, "delete %s\n",
+ dev_name(&port->dev));
+ delete_switch_port(port, &reap_dports);
+ }
+ put_device(&port->dev);
+ cxl_device_unlock(&parent_port->dev);
+ }
+}
+
+static resource_size_t find_component_registers(struct device *dev)
+{
+ struct cxl_register_map map;
+ struct pci_dev *pdev;
+
+ /*
+ * Theoretically, CXL component registers can be hosted on a
+ * non-PCI device, in practice, only cxl_test hits this case.
+ */
+ if (!dev_is_pci(dev))
+ return CXL_RESOURCE_NONE;
+
+ pdev = to_pci_dev(dev);
+
+ cxl_find_regblock(pdev, CXL_REGLOC_RBI_COMPONENT, &map);
+ return cxl_regmap_to_base(pdev, &map);
+}
+
+static int add_port_attach_ep(struct cxl_memdev *cxlmd,
+ struct device *uport_dev,
+ struct device *dport_dev)
+{
+ struct device *dparent = grandparent(dport_dev);
+ struct cxl_port *port, *parent_port = NULL;
+ resource_size_t component_reg_phys;
+ int rc;
+
+ if (!dparent) {
+ /*
+ * The iteration reached the topology root without finding the
+ * CXL-root 'cxl_port' on a previous iteration, fail for now to
+ * be re-probed after platform driver attaches.
+ */
+ dev_dbg(&cxlmd->dev, "%s is a root dport\n",
+ dev_name(dport_dev));
+ return -ENXIO;
+ }
+
+ parent_port = find_cxl_port(dparent);
+ if (!parent_port) {
+ /* iterate to create this parent_port */
+ return -EAGAIN;
+ }
+
+ cxl_device_lock(&parent_port->dev);
+ if (!parent_port->dev.driver) {
+ dev_warn(&cxlmd->dev,
+ "port %s:%s disabled, failed to enumerate CXL.mem\n",
+ dev_name(&parent_port->dev), dev_name(uport_dev));
+ port = ERR_PTR(-ENXIO);
+ goto out;
+ }
+
+ port = find_cxl_port_at(parent_port, dport_dev);
+ if (!port) {
+ component_reg_phys = find_component_registers(uport_dev);
+ port = devm_cxl_add_port(&parent_port->dev, uport_dev,
+ component_reg_phys, parent_port);
+ if (!IS_ERR(port))
+ get_device(&port->dev);
+ }
+out:
+ cxl_device_unlock(&parent_port->dev);
+
+ if (IS_ERR(port))
+ rc = PTR_ERR(port);
+ else {
+ dev_dbg(&cxlmd->dev, "add to new port %s:%s\n",
+ dev_name(&port->dev), dev_name(port->uport));
+ rc = cxl_add_ep(port, &cxlmd->dev);
+ if (rc == -EEXIST) {
+ /*
+ * "can't" happen, but this error code means
+ * something to the caller, so translate it.
+ */
+ rc = -ENXIO;
+ }
+ put_device(&port->dev);
+ }
+
+ put_device(&parent_port->dev);
+ return rc;
+}
+
+int devm_cxl_enumerate_ports(struct cxl_memdev *cxlmd)
+{
+ struct device *dev = &cxlmd->dev;
+ struct device *iter;
+ int rc;
+
+ rc = devm_add_action_or_reset(&cxlmd->dev, cxl_detach_ep, cxlmd);
+ if (rc)
+ return rc;
+
+ /*
+ * Scan for and add all cxl_ports in this device's ancestry.
+ * Repeat until no more ports are added. Abort if a port add
+ * attempt fails.
+ */
+retry:
+ for (iter = dev; iter; iter = grandparent(iter)) {
+ struct device *dport_dev = grandparent(iter);
+ struct device *uport_dev;
+ struct cxl_port *port;
+
+ if (!dport_dev)
+ return 0;
+
+ uport_dev = dport_dev->parent;
+ if (!uport_dev) {
+ dev_warn(dev, "at %s no parent for dport: %s\n",
+ dev_name(iter), dev_name(dport_dev));
+ return -ENXIO;
+ }
+
+ dev_dbg(dev, "scan: iter: %s dport_dev: %s parent: %s\n",
+ dev_name(iter), dev_name(dport_dev),
+ dev_name(uport_dev));
+ port = find_cxl_port(dport_dev);
+ if (port) {
+ dev_dbg(&cxlmd->dev,
+ "found already registered port %s:%s\n",
+ dev_name(&port->dev), dev_name(port->uport));
+ rc = cxl_add_ep(port, &cxlmd->dev);
+
+ /*
+ * If the endpoint already exists in the port's list,
+ * that's ok, it was added on a previous pass.
+ * Otherwise, retry in add_port_attach_ep() after taking
+ * the parent_port lock as the current port may be being
+ * reaped.
+ */
+ if (rc && rc != -EEXIST) {
+ put_device(&port->dev);
+ return rc;
+ }
+
+ /* Any more ports to add between this one and the root? */
+ if (!dev_is_cxl_root_child(&port->dev)) {
+ put_device(&port->dev);
+ continue;
+ }
+
+ put_device(&port->dev);
+ return 0;
+ }
+
+ rc = add_port_attach_ep(cxlmd, uport_dev, dport_dev);
+ /* port missing, try to add parent */
+ if (rc == -EAGAIN)
+ continue;
+ /* failed to add ep or port */
+ if (rc)
+ return rc;
+ /* port added, new descendants possible, start over */
+ goto retry;
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL_NS_GPL(devm_cxl_enumerate_ports, CXL);
+
+struct cxl_port *cxl_mem_find_port(struct cxl_memdev *cxlmd)
+{
+ return find_cxl_port(grandparent(&cxlmd->dev));
+}
+EXPORT_SYMBOL_NS_GPL(cxl_mem_find_port, CXL);
+
+struct cxl_dport *cxl_find_dport_by_dev(struct cxl_port *port,
+ const struct device *dev)
+{
+ struct cxl_dport *dport;
+
+ cxl_device_lock(&port->dev);
+ list_for_each_entry(dport, &port->dports, list)
+ if (dport->dport == dev) {
+ cxl_device_unlock(&port->dev);
+ return dport;
+ }
+
+ cxl_device_unlock(&port->dev);
+ return NULL;
+}
+EXPORT_SYMBOL_NS_GPL(cxl_find_dport_by_dev, CXL);
+
+static int decoder_populate_targets(struct cxl_decoder *cxld,
+ struct cxl_port *port, int *target_map)
+{
+ int i, rc = 0;
+
+ if (!target_map)
+ return 0;
+
+ device_lock_assert(&port->dev);
+
+ if (list_empty(&port->dports))
+ return -EINVAL;
+
+ write_seqlock(&cxld->target_lock);
+ for (i = 0; i < cxld->nr_targets; i++) {
+ struct cxl_dport *dport = find_dport(port, target_map[i]);
+
+ if (!dport) {
+ rc = -ENXIO;
+ break;
+ }
+ cxld->target[i] = dport;
+ }
+ write_sequnlock(&cxld->target_lock);
+
+ return rc;
+}
+
+/**
+ * cxl_decoder_alloc - Allocate a new CXL decoder
+ * @port: owning port of this decoder
+ * @nr_targets: downstream targets accessible by this decoder. All upstream
+ * ports and root ports must have at least 1 target. Endpoint
+ * devices will have 0 targets. Callers wishing to register an
+ * endpoint device should specify 0.
+ *
+ * A port should contain one or more decoders. Each of those decoders enable
+ * some address space for CXL.mem utilization. A decoder is expected to be
+ * configured by the caller before registering.
+ *
+ * Return: A new cxl decoder to be registered by cxl_decoder_add(). The decoder
+ * is initialized to be a "passthrough" decoder.
+ */
+static struct cxl_decoder *cxl_decoder_alloc(struct cxl_port *port,
+ unsigned int nr_targets)
+{
+ struct cxl_decoder *cxld;
+ struct device *dev;
+ int rc = 0;
+
+ if (nr_targets > CXL_DECODER_MAX_INTERLEAVE)
+ return ERR_PTR(-EINVAL);
+
+ cxld = kzalloc(struct_size(cxld, target, nr_targets), GFP_KERNEL);
+ if (!cxld)
+ return ERR_PTR(-ENOMEM);
+
+ rc = ida_alloc(&port->decoder_ida, GFP_KERNEL);
+ if (rc < 0)
+ goto err;
+
+ /* need parent to stick around to release the id */
+ get_device(&port->dev);
+ cxld->id = rc;
+
+ cxld->nr_targets = nr_targets;
+ seqlock_init(&cxld->target_lock);
+ dev = &cxld->dev;
+ device_initialize(dev);
+ device_set_pm_not_required(dev);
+ dev->parent = &port->dev;
+ dev->bus = &cxl_bus_type;
+ if (is_cxl_root(port))
+ cxld->dev.type = &cxl_decoder_root_type;
+ else if (is_cxl_endpoint(port))
+ cxld->dev.type = &cxl_decoder_endpoint_type;
+ else
+ cxld->dev.type = &cxl_decoder_switch_type;
+
+ /* Pre initialize an "empty" decoder */
+ cxld->interleave_ways = 1;
+ cxld->interleave_granularity = PAGE_SIZE;
+ cxld->target_type = CXL_DECODER_EXPANDER;
+ cxld->platform_res = (struct resource)DEFINE_RES_MEM(0, 0);
+
+ return cxld;
+err:
+ kfree(cxld);
+ return ERR_PTR(rc);
+}
+
+/**
+ * cxl_root_decoder_alloc - Allocate a root level decoder
+ * @port: owning CXL root of this decoder
+ * @nr_targets: static number of downstream targets
+ *
+ * Return: A new cxl decoder to be registered by cxl_decoder_add(). A
+ * 'CXL root' decoder is one that decodes from a top-level / static platform
+ * firmware description of CXL resources into a CXL standard decode
+ * topology.
+ */
+struct cxl_decoder *cxl_root_decoder_alloc(struct cxl_port *port,
+ unsigned int nr_targets)
+{
+ if (!is_cxl_root(port))
+ return ERR_PTR(-EINVAL);
+
+ return cxl_decoder_alloc(port, nr_targets);
+}
+EXPORT_SYMBOL_NS_GPL(cxl_root_decoder_alloc, CXL);
+
+/**
+ * cxl_switch_decoder_alloc - Allocate a switch level decoder
+ * @port: owning CXL switch port of this decoder
+ * @nr_targets: max number of dynamically addressable downstream targets
+ *
+ * Return: A new cxl decoder to be registered by cxl_decoder_add(). A
+ * 'switch' decoder is any decoder that can be enumerated by PCIe
+ * topology and the HDM Decoder Capability. This includes the decoders
+ * that sit between Switch Upstream Ports / Switch Downstream Ports and
+ * Host Bridges / Root Ports.
+ */
+struct cxl_decoder *cxl_switch_decoder_alloc(struct cxl_port *port,
+ unsigned int nr_targets)
+{
+ if (is_cxl_root(port) || is_cxl_endpoint(port))
+ return ERR_PTR(-EINVAL);
+
+ return cxl_decoder_alloc(port, nr_targets);
+}
+EXPORT_SYMBOL_NS_GPL(cxl_switch_decoder_alloc, CXL);
+
+/**
+ * cxl_endpoint_decoder_alloc - Allocate an endpoint decoder
+ * @port: owning port of this decoder
+ *
+ * Return: A new cxl decoder to be registered by cxl_decoder_add()
+ */
+struct cxl_decoder *cxl_endpoint_decoder_alloc(struct cxl_port *port)
+{
+ if (!is_cxl_endpoint(port))
+ return ERR_PTR(-EINVAL);
+
+ return cxl_decoder_alloc(port, 0);
+}
+EXPORT_SYMBOL_NS_GPL(cxl_endpoint_decoder_alloc, CXL);
+
+/**
+ * cxl_decoder_add_locked - Add a decoder with targets
+ * @cxld: The cxl decoder allocated by cxl_decoder_alloc()
+ * @target_map: A list of downstream ports that this decoder can direct memory
+ * traffic to. These numbers should correspond with the port number
+ * in the PCIe Link Capabilities structure.
+ *
+ * Certain types of decoders may not have any targets. The main example of this
+ * is an endpoint device. A more awkward example is a hostbridge whose root
+ * ports get hot added (technically possible, though unlikely).
+ *
+ * This is the locked variant of cxl_decoder_add().
+ *
+ * Context: Process context. Expects the device lock of the port that owns the
+ * @cxld to be held.
+ *
+ * Return: Negative error code if the decoder wasn't properly configured; else
+ * returns 0.
+ */
+int cxl_decoder_add_locked(struct cxl_decoder *cxld, int *target_map)
+{
+ struct cxl_port *port;
+ struct device *dev;
+ int rc;
+
+ if (WARN_ON_ONCE(!cxld))
+ return -EINVAL;
+
+ if (WARN_ON_ONCE(IS_ERR(cxld)))
+ return PTR_ERR(cxld);
+
+ if (cxld->interleave_ways < 1)
+ return -EINVAL;
+
+ dev = &cxld->dev;
+
+ port = to_cxl_port(cxld->dev.parent);
+ if (!is_endpoint_decoder(dev)) {
+ rc = decoder_populate_targets(cxld, port, target_map);
+ if (rc && (cxld->flags & CXL_DECODER_F_ENABLE)) {
+ dev_err(&port->dev,
+ "Failed to populate active decoder targets\n");
+ return rc;
+ }
+ }
+
+ rc = dev_set_name(dev, "decoder%d.%d", port->id, cxld->id);
+ if (rc)
+ return rc;
+
+ /*
+ * Platform decoder resources should show up with a reasonable name. All
+ * other resources are just sub ranges within the main decoder resource.
+ */
+ if (is_root_decoder(dev))
+ cxld->platform_res.name = dev_name(dev);
+
+ return device_add(dev);
+}
+EXPORT_SYMBOL_NS_GPL(cxl_decoder_add_locked, CXL);
+
+/**
+ * cxl_decoder_add - Add a decoder with targets
+ * @cxld: The cxl decoder allocated by cxl_decoder_alloc()
+ * @target_map: A list of downstream ports that this decoder can direct memory
+ * traffic to. These numbers should correspond with the port number
+ * in the PCIe Link Capabilities structure.
+ *
+ * This is the unlocked variant of cxl_decoder_add_locked().
+ * See cxl_decoder_add_locked().
+ *
+ * Context: Process context. Takes and releases the device lock of the port that
+ * owns the @cxld.
+ */
+int cxl_decoder_add(struct cxl_decoder *cxld, int *target_map)
+{
+ struct cxl_port *port;
+ int rc;
+
+ if (WARN_ON_ONCE(!cxld))
+ return -EINVAL;
+
+ if (WARN_ON_ONCE(IS_ERR(cxld)))
+ return PTR_ERR(cxld);
+
+ port = to_cxl_port(cxld->dev.parent);
+
+ cxl_device_lock(&port->dev);
+ rc = cxl_decoder_add_locked(cxld, target_map);
+ cxl_device_unlock(&port->dev);
+
+ return rc;
+}
+EXPORT_SYMBOL_NS_GPL(cxl_decoder_add, CXL);
+
+static void cxld_unregister(void *dev)
+{
+ device_unregister(dev);
+}
+
+int cxl_decoder_autoremove(struct device *host, struct cxl_decoder *cxld)
+{
+ return devm_add_action_or_reset(host, cxld_unregister, &cxld->dev);
+}
+EXPORT_SYMBOL_NS_GPL(cxl_decoder_autoremove, CXL);
+
+/**
+ * __cxl_driver_register - register a driver for the cxl bus
+ * @cxl_drv: cxl driver structure to attach
+ * @owner: owning module/driver
+ * @modname: KBUILD_MODNAME for parent driver
+ */
+int __cxl_driver_register(struct cxl_driver *cxl_drv, struct module *owner,
+ const char *modname)
+{
+ if (!cxl_drv->probe) {
+ pr_debug("%s ->probe() must be specified\n", modname);
+ return -EINVAL;
+ }
+
+ if (!cxl_drv->name) {
+ pr_debug("%s ->name must be specified\n", modname);
+ return -EINVAL;
+ }
+
+ if (!cxl_drv->id) {
+ pr_debug("%s ->id must be specified\n", modname);
+ return -EINVAL;
+ }
+
+ cxl_drv->drv.bus = &cxl_bus_type;
+ cxl_drv->drv.owner = owner;
+ cxl_drv->drv.mod_name = modname;
+ cxl_drv->drv.name = cxl_drv->name;
+
+ return driver_register(&cxl_drv->drv);
+}
+EXPORT_SYMBOL_NS_GPL(__cxl_driver_register, CXL);
+
+void cxl_driver_unregister(struct cxl_driver *cxl_drv)
+{
+ driver_unregister(&cxl_drv->drv);
+}
+EXPORT_SYMBOL_NS_GPL(cxl_driver_unregister, CXL);
+
+static int cxl_bus_uevent(struct device *dev, struct kobj_uevent_env *env)
+{
+ return add_uevent_var(env, "MODALIAS=" CXL_MODALIAS_FMT,
+ cxl_device_id(dev));
+}
+
+static int cxl_bus_match(struct device *dev, struct device_driver *drv)
+{
+ return cxl_device_id(dev) == to_cxl_drv(drv)->id;
+}
+
+static int cxl_bus_probe(struct device *dev)
+{
+ int rc;
+
+ /*
+ * Take the CXL nested lock since the driver core only holds
+ * @dev->mutex and not @dev->lockdep_mutex.
+ */
+ cxl_nested_lock(dev);
+ rc = to_cxl_drv(dev->driver)->probe(dev);
+ cxl_nested_unlock(dev);
+
+ dev_dbg(dev, "probe: %d\n", rc);
+ return rc;
+}
+
+static void cxl_bus_remove(struct device *dev)
+{
+ struct cxl_driver *cxl_drv = to_cxl_drv(dev->driver);
+
+ cxl_nested_lock(dev);
+ if (cxl_drv->remove)
+ cxl_drv->remove(dev);
+ cxl_nested_unlock(dev);
+}
+
+static struct workqueue_struct *cxl_bus_wq;
+
+int cxl_bus_rescan(void)
+{
+ return bus_rescan_devices(&cxl_bus_type);
+}
+EXPORT_SYMBOL_NS_GPL(cxl_bus_rescan, CXL);
+
+bool schedule_cxl_memdev_detach(struct cxl_memdev *cxlmd)
+{
+ return queue_work(cxl_bus_wq, &cxlmd->detach_work);
+}
+EXPORT_SYMBOL_NS_GPL(schedule_cxl_memdev_detach, CXL);
+
+/* for user tooling to ensure port disable work has completed */
+static ssize_t flush_store(struct bus_type *bus, const char *buf, size_t count)
+{
+ if (sysfs_streq(buf, "1")) {
+ flush_workqueue(cxl_bus_wq);
+ return count;
+ }
+
+ return -EINVAL;
+}
+
+static BUS_ATTR_WO(flush);
+
+static struct attribute *cxl_bus_attributes[] = {
+ &bus_attr_flush.attr,
+ NULL,
+};
+
+static struct attribute_group cxl_bus_attribute_group = {
+ .attrs = cxl_bus_attributes,
+};
+
+static const struct attribute_group *cxl_bus_attribute_groups[] = {
+ &cxl_bus_attribute_group,
+ NULL,
+};
+
+struct bus_type cxl_bus_type = {
+ .name = "cxl",
+ .uevent = cxl_bus_uevent,
+ .match = cxl_bus_match,
+ .probe = cxl_bus_probe,
+ .remove = cxl_bus_remove,
+ .bus_groups = cxl_bus_attribute_groups,
+};
+EXPORT_SYMBOL_NS_GPL(cxl_bus_type, CXL);
+
+static __init int cxl_core_init(void)
+{
+ int rc;
+
+ cxl_mbox_init();
+
+ rc = cxl_memdev_init();
+ if (rc)
+ return rc;
+
+ cxl_bus_wq = alloc_ordered_workqueue("cxl_port", 0);
+ if (!cxl_bus_wq) {
+ rc = -ENOMEM;
+ goto err_wq;
+ }
+
+ rc = bus_register(&cxl_bus_type);
+ if (rc)
+ goto err_bus;
+
+ return 0;
+
+err_bus:
+ destroy_workqueue(cxl_bus_wq);
+err_wq:
+ cxl_memdev_exit();
+ cxl_mbox_exit();
+ return rc;
+}
+
+static void cxl_core_exit(void)
+{
+ bus_unregister(&cxl_bus_type);
+ destroy_workqueue(cxl_bus_wq);
+ cxl_memdev_exit();
+ cxl_mbox_exit();
+}
+
+module_init(cxl_core_init);
+module_exit(cxl_core_exit);
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/cxl/core/regs.c b/drivers/cxl/core/regs.c
index e37e23bf4355..39a129c57d40 100644
--- a/drivers/cxl/core/regs.c
+++ b/drivers/cxl/core/regs.c
@@ -5,6 +5,7 @@
#include <linux/slab.h>
#include <linux/pci.h>
#include <cxlmem.h>
+#include <cxlpci.h>
/**
* DOC: cxl registers
@@ -35,7 +36,7 @@ void cxl_probe_component_regs(struct device *dev, void __iomem *base,
struct cxl_component_reg_map *map)
{
int cap, cap_count;
- u64 cap_array;
+ u32 cap_array;
*map = (struct cxl_component_reg_map) { 0 };
@@ -45,11 +46,11 @@ void cxl_probe_component_regs(struct device *dev, void __iomem *base,
*/
base += CXL_CM_OFFSET;
- cap_array = readq(base + CXL_CM_CAP_HDR_OFFSET);
+ cap_array = readl(base + CXL_CM_CAP_HDR_OFFSET);
if (FIELD_GET(CXL_CM_CAP_HDR_ID_MASK, cap_array) != CM_CAP_HDR_CAP_ID) {
dev_err(dev,
- "Couldn't locate the CXL.cache and CXL.mem capability array header./n");
+ "Couldn't locate the CXL.cache and CXL.mem capability array header.\n");
return;
}
@@ -158,9 +159,8 @@ void cxl_probe_device_regs(struct device *dev, void __iomem *base,
}
EXPORT_SYMBOL_NS_GPL(cxl_probe_device_regs, CXL);
-static void __iomem *devm_cxl_iomap_block(struct device *dev,
- resource_size_t addr,
- resource_size_t length)
+void __iomem *devm_cxl_iomap_block(struct device *dev, resource_size_t addr,
+ resource_size_t length)
{
void __iomem *ret_val;
struct resource *res;
@@ -247,3 +247,58 @@ int cxl_map_device_regs(struct pci_dev *pdev,
return 0;
}
EXPORT_SYMBOL_NS_GPL(cxl_map_device_regs, CXL);
+
+static void cxl_decode_regblock(u32 reg_lo, u32 reg_hi,
+ struct cxl_register_map *map)
+{
+ map->block_offset = ((u64)reg_hi << 32) |
+ (reg_lo & CXL_DVSEC_REG_LOCATOR_BLOCK_OFF_LOW_MASK);
+ map->barno = FIELD_GET(CXL_DVSEC_REG_LOCATOR_BIR_MASK, reg_lo);
+ map->reg_type = FIELD_GET(CXL_DVSEC_REG_LOCATOR_BLOCK_ID_MASK, reg_lo);
+}
+
+/**
+ * cxl_find_regblock() - Locate register blocks by type
+ * @pdev: The CXL PCI device to enumerate.
+ * @type: Register Block Indicator id
+ * @map: Enumeration output, clobbered on error
+ *
+ * Return: 0 if register block enumerated, negative error code otherwise
+ *
+ * A CXL DVSEC may point to one or more register blocks, search for them
+ * by @type.
+ */
+int cxl_find_regblock(struct pci_dev *pdev, enum cxl_regloc_type type,
+ struct cxl_register_map *map)
+{
+ u32 regloc_size, regblocks;
+ int regloc, i;
+
+ map->block_offset = U64_MAX;
+ regloc = pci_find_dvsec_capability(pdev, PCI_DVSEC_VENDOR_ID_CXL,
+ CXL_DVSEC_REG_LOCATOR);
+ if (!regloc)
+ return -ENXIO;
+
+ pci_read_config_dword(pdev, regloc + PCI_DVSEC_HEADER1, &regloc_size);
+ regloc_size = FIELD_GET(PCI_DVSEC_HEADER1_LENGTH_MASK, regloc_size);
+
+ regloc += CXL_DVSEC_REG_LOCATOR_BLOCK1_OFFSET;
+ regblocks = (regloc_size - CXL_DVSEC_REG_LOCATOR_BLOCK1_OFFSET) / 8;
+
+ for (i = 0; i < regblocks; i++, regloc += 8) {
+ u32 reg_lo, reg_hi;
+
+ pci_read_config_dword(pdev, regloc, &reg_lo);
+ pci_read_config_dword(pdev, regloc + 4, &reg_hi);
+
+ cxl_decode_regblock(reg_lo, reg_hi, map);
+
+ if (map->reg_type == type)
+ return 0;
+ }
+
+ map->block_offset = U64_MAX;
+ return -ENODEV;
+}
+EXPORT_SYMBOL_NS_GPL(cxl_find_regblock, CXL);
diff --git a/drivers/cxl/cxl.h b/drivers/cxl/cxl.h
index a5a0be3f088b..990b6670222e 100644
--- a/drivers/cxl/cxl.h
+++ b/drivers/cxl/cxl.h
@@ -17,6 +17,9 @@
* (port-driver, region-driver, nvdimm object-drivers... etc).
*/
+/* CXL 2.0 8.2.4 CXL Component Register Layout and Definition */
+#define CXL_COMPONENT_REG_BLOCK_SIZE SZ_64K
+
/* CXL 2.0 8.2.5 CXL.cache and CXL.mem Registers*/
#define CXL_CM_OFFSET 0x1000
#define CXL_CM_CAP_HDR_OFFSET 0x0
@@ -36,11 +39,23 @@
#define CXL_HDM_DECODER_CAP_OFFSET 0x0
#define CXL_HDM_DECODER_COUNT_MASK GENMASK(3, 0)
#define CXL_HDM_DECODER_TARGET_COUNT_MASK GENMASK(7, 4)
-#define CXL_HDM_DECODER0_BASE_LOW_OFFSET 0x10
-#define CXL_HDM_DECODER0_BASE_HIGH_OFFSET 0x14
-#define CXL_HDM_DECODER0_SIZE_LOW_OFFSET 0x18
-#define CXL_HDM_DECODER0_SIZE_HIGH_OFFSET 0x1c
-#define CXL_HDM_DECODER0_CTRL_OFFSET 0x20
+#define CXL_HDM_DECODER_INTERLEAVE_11_8 BIT(8)
+#define CXL_HDM_DECODER_INTERLEAVE_14_12 BIT(9)
+#define CXL_HDM_DECODER_CTRL_OFFSET 0x4
+#define CXL_HDM_DECODER_ENABLE BIT(1)
+#define CXL_HDM_DECODER0_BASE_LOW_OFFSET(i) (0x20 * (i) + 0x10)
+#define CXL_HDM_DECODER0_BASE_HIGH_OFFSET(i) (0x20 * (i) + 0x14)
+#define CXL_HDM_DECODER0_SIZE_LOW_OFFSET(i) (0x20 * (i) + 0x18)
+#define CXL_HDM_DECODER0_SIZE_HIGH_OFFSET(i) (0x20 * (i) + 0x1c)
+#define CXL_HDM_DECODER0_CTRL_OFFSET(i) (0x20 * (i) + 0x20)
+#define CXL_HDM_DECODER0_CTRL_IG_MASK GENMASK(3, 0)
+#define CXL_HDM_DECODER0_CTRL_IW_MASK GENMASK(7, 4)
+#define CXL_HDM_DECODER0_CTRL_LOCK BIT(8)
+#define CXL_HDM_DECODER0_CTRL_COMMIT BIT(9)
+#define CXL_HDM_DECODER0_CTRL_COMMITTED BIT(10)
+#define CXL_HDM_DECODER0_CTRL_TYPE BIT(12)
+#define CXL_HDM_DECODER0_TL_LOW(i) (0x20 * (i) + 0x24)
+#define CXL_HDM_DECODER0_TL_HIGH(i) (0x20 * (i) + 0x28)
static inline int cxl_hdm_decoder_count(u32 cap_hdr)
{
@@ -145,6 +160,12 @@ int cxl_map_device_regs(struct pci_dev *pdev,
struct cxl_device_regs *regs,
struct cxl_register_map *map);
+enum cxl_regloc_type;
+int cxl_find_regblock(struct pci_dev *pdev, enum cxl_regloc_type type,
+ struct cxl_register_map *map);
+void __iomem *devm_cxl_iomap_block(struct device *dev, resource_size_t addr,
+ resource_size_t length);
+
#define CXL_RESOURCE_NONE ((resource_size_t) -1)
#define CXL_TARGET_STRLEN 20
@@ -158,7 +179,8 @@ int cxl_map_device_regs(struct pci_dev *pdev,
#define CXL_DECODER_F_TYPE2 BIT(2)
#define CXL_DECODER_F_TYPE3 BIT(3)
#define CXL_DECODER_F_LOCK BIT(4)
-#define CXL_DECODER_F_MASK GENMASK(4, 0)
+#define CXL_DECODER_F_ENABLE BIT(5)
+#define CXL_DECODER_F_MASK GENMASK(5, 0)
enum cxl_decoder_type {
CXL_DECODER_ACCELERATOR = 2,
@@ -175,22 +197,28 @@ enum cxl_decoder_type {
* struct cxl_decoder - CXL address range decode configuration
* @dev: this decoder's device
* @id: kernel device name id
- * @range: address range considered by this decoder
+ * @platform_res: address space resources considered by root decoder
+ * @decoder_range: address space resources considered by midlevel decoder
* @interleave_ways: number of cxl_dports in this decode
* @interleave_granularity: data stride per dport
* @target_type: accelerator vs expander (type2 vs type3) selector
* @flags: memory type capabilities and locking
+ * @target_lock: coordinate coherent reads of the target list
* @nr_targets: number of elements in @target
* @target: active ordered target list in current decoder configuration
*/
struct cxl_decoder {
struct device dev;
int id;
- struct range range;
+ union {
+ struct resource platform_res;
+ struct range decoder_range;
+ };
int interleave_ways;
int interleave_granularity;
enum cxl_decoder_type target_type;
unsigned long flags;
+ seqlock_t target_lock;
int nr_targets;
struct cxl_dport *target[];
};
@@ -226,14 +254,6 @@ struct cxl_nvdimm {
struct nvdimm *nvdimm;
};
-struct cxl_walk_context {
- struct device *dev;
- struct pci_bus *root;
- struct cxl_port *port;
- int error;
- int count;
-};
-
/**
* struct cxl_port - logical collection of upstream port devices and
* downstream port devices to construct a CXL memory
@@ -242,16 +262,22 @@ struct cxl_walk_context {
* @uport: PCI or platform device implementing the upstream port capability
* @id: id for port device-name
* @dports: cxl_dport instances referenced by decoders
+ * @endpoints: cxl_ep instances, endpoints that are a descendant of this port
* @decoder_ida: allocator for decoder ids
* @component_reg_phys: component register capability base address (optional)
+ * @dead: last ep has been removed, force port re-creation
+ * @depth: How deep this port is relative to the root. depth 0 is the root.
*/
struct cxl_port {
struct device dev;
struct device *uport;
int id;
struct list_head dports;
+ struct list_head endpoints;
struct ida decoder_ida;
resource_size_t component_reg_phys;
+ bool dead;
+ unsigned int depth;
};
/**
@@ -270,19 +296,65 @@ struct cxl_dport {
struct list_head list;
};
+/**
+ * struct cxl_ep - track an endpoint's interest in a port
+ * @ep: device that hosts a generic CXL endpoint (expander or accelerator)
+ * @list: node on port->endpoints list
+ */
+struct cxl_ep {
+ struct device *ep;
+ struct list_head list;
+};
+
+/*
+ * The platform firmware device hosting the root is also the top of the
+ * CXL port topology. All other CXL ports have another CXL port as their
+ * parent and their ->uport / host device is out-of-line of the port
+ * ancestry.
+ */
+static inline bool is_cxl_root(struct cxl_port *port)
+{
+ return port->uport == port->dev.parent;
+}
+
+bool is_cxl_port(struct device *dev);
struct cxl_port *to_cxl_port(struct device *dev);
+struct pci_bus;
+int devm_cxl_register_pci_bus(struct device *host, struct device *uport,
+ struct pci_bus *bus);
+struct pci_bus *cxl_port_to_pci_bus(struct cxl_port *port);
struct cxl_port *devm_cxl_add_port(struct device *host, struct device *uport,
resource_size_t component_reg_phys,
struct cxl_port *parent_port);
-
-int cxl_add_dport(struct cxl_port *port, struct device *dport, int port_id,
- resource_size_t component_reg_phys);
+struct cxl_port *find_cxl_root(struct device *dev);
+int devm_cxl_enumerate_ports(struct cxl_memdev *cxlmd);
+int cxl_bus_rescan(void);
+struct cxl_port *cxl_mem_find_port(struct cxl_memdev *cxlmd);
+bool schedule_cxl_memdev_detach(struct cxl_memdev *cxlmd);
+
+struct cxl_dport *devm_cxl_add_dport(struct cxl_port *port,
+ struct device *dport, int port_id,
+ resource_size_t component_reg_phys);
+struct cxl_dport *cxl_find_dport_by_dev(struct cxl_port *port,
+ const struct device *dev);
struct cxl_decoder *to_cxl_decoder(struct device *dev);
bool is_root_decoder(struct device *dev);
-struct cxl_decoder *cxl_decoder_alloc(struct cxl_port *port, int nr_targets);
+bool is_cxl_decoder(struct device *dev);
+struct cxl_decoder *cxl_root_decoder_alloc(struct cxl_port *port,
+ unsigned int nr_targets);
+struct cxl_decoder *cxl_switch_decoder_alloc(struct cxl_port *port,
+ unsigned int nr_targets);
int cxl_decoder_add(struct cxl_decoder *cxld, int *target_map);
+struct cxl_decoder *cxl_endpoint_decoder_alloc(struct cxl_port *port);
+int cxl_decoder_add_locked(struct cxl_decoder *cxld, int *target_map);
int cxl_decoder_autoremove(struct device *host, struct cxl_decoder *cxld);
+int cxl_endpoint_autoremove(struct cxl_memdev *cxlmd, struct cxl_port *endpoint);
+
+struct cxl_hdm;
+struct cxl_hdm *devm_cxl_setup_hdm(struct cxl_port *port);
+int devm_cxl_enumerate_decoders(struct cxl_hdm *cxlhdm);
+int devm_cxl_add_passthrough_decoder(struct cxl_port *port);
extern struct bus_type cxl_bus_type;
@@ -304,8 +376,14 @@ int __cxl_driver_register(struct cxl_driver *cxl_drv, struct module *owner,
#define cxl_driver_register(x) __cxl_driver_register(x, THIS_MODULE, KBUILD_MODNAME)
void cxl_driver_unregister(struct cxl_driver *cxl_drv);
+#define module_cxl_driver(__cxl_driver) \
+ module_driver(__cxl_driver, cxl_driver_register, cxl_driver_unregister)
+
#define CXL_DEVICE_NVDIMM_BRIDGE 1
#define CXL_DEVICE_NVDIMM 2
+#define CXL_DEVICE_PORT 3
+#define CXL_DEVICE_ROOT 4
+#define CXL_DEVICE_MEMORY_EXPANDER 5
#define MODULE_ALIAS_CXL(type) MODULE_ALIAS("cxl:t" __stringify(type) "*")
#define CXL_MODALIAS_FMT "cxl:t%d"
@@ -326,4 +404,83 @@ struct cxl_nvdimm_bridge *cxl_find_nvdimm_bridge(struct cxl_nvdimm *cxl_nvd);
#ifndef __mock
#define __mock static
#endif
+
+#ifdef CONFIG_PROVE_CXL_LOCKING
+enum cxl_lock_class {
+ CXL_ANON_LOCK,
+ CXL_NVDIMM_LOCK,
+ CXL_NVDIMM_BRIDGE_LOCK,
+ CXL_PORT_LOCK,
+ /*
+ * Be careful to add new lock classes here, CXL_PORT_LOCK is
+ * extended by the port depth, so a maximum CXL port topology
+ * depth would need to be defined first.
+ */
+};
+
+static inline void cxl_nested_lock(struct device *dev)
+{
+ if (is_cxl_port(dev)) {
+ struct cxl_port *port = to_cxl_port(dev);
+
+ mutex_lock_nested(&dev->lockdep_mutex,
+ CXL_PORT_LOCK + port->depth);
+ } else if (is_cxl_decoder(dev)) {
+ struct cxl_port *port = to_cxl_port(dev->parent);
+
+ /*
+ * A decoder is the immediate child of a port, so set
+ * its lock class equal to other child device siblings.
+ */
+ mutex_lock_nested(&dev->lockdep_mutex,
+ CXL_PORT_LOCK + port->depth + 1);
+ } else if (is_cxl_nvdimm_bridge(dev))
+ mutex_lock_nested(&dev->lockdep_mutex, CXL_NVDIMM_BRIDGE_LOCK);
+ else if (is_cxl_nvdimm(dev))
+ mutex_lock_nested(&dev->lockdep_mutex, CXL_NVDIMM_LOCK);
+ else
+ mutex_lock_nested(&dev->lockdep_mutex, CXL_ANON_LOCK);
+}
+
+static inline void cxl_nested_unlock(struct device *dev)
+{
+ mutex_unlock(&dev->lockdep_mutex);
+}
+
+static inline void cxl_device_lock(struct device *dev)
+{
+ /*
+ * For double lock errors the lockup will happen before lockdep
+ * warns at cxl_nested_lock(), so assert explicitly.
+ */
+ lockdep_assert_not_held(&dev->lockdep_mutex);
+
+ device_lock(dev);
+ cxl_nested_lock(dev);
+}
+
+static inline void cxl_device_unlock(struct device *dev)
+{
+ cxl_nested_unlock(dev);
+ device_unlock(dev);
+}
+#else
+static inline void cxl_nested_lock(struct device *dev)
+{
+}
+
+static inline void cxl_nested_unlock(struct device *dev)
+{
+}
+
+static inline void cxl_device_lock(struct device *dev)
+{
+ device_lock(dev);
+}
+
+static inline void cxl_device_unlock(struct device *dev)
+{
+ device_unlock(dev);
+}
+#endif
#endif /* __CXL_H__ */
diff --git a/drivers/cxl/cxlmem.h b/drivers/cxl/cxlmem.h
index 8d96d009ad90..5d33ce24fe09 100644
--- a/drivers/cxl/cxlmem.h
+++ b/drivers/cxl/cxlmem.h
@@ -34,12 +34,14 @@
* @dev: driver core device object
* @cdev: char dev core object for ioctl operations
* @cxlds: The device state backing this device
+ * @detach_work: active memdev lost a port in its ancestry
* @id: id number of this memdev instance.
*/
struct cxl_memdev {
struct device dev;
struct cdev cdev;
struct cxl_dev_state *cxlds;
+ struct work_struct detach_work;
int id;
};
@@ -48,6 +50,12 @@ static inline struct cxl_memdev *to_cxl_memdev(struct device *dev)
return container_of(dev, struct cxl_memdev, dev);
}
+bool is_cxl_memdev(struct device *dev);
+static inline bool is_cxl_endpoint(struct cxl_port *port)
+{
+ return is_cxl_memdev(port->uport);
+}
+
struct cxl_memdev *devm_cxl_add_memdev(struct cxl_dev_state *cxlds);
/**
@@ -90,6 +98,18 @@ struct cxl_mbox_cmd {
#define CXL_CAPACITY_MULTIPLIER SZ_256M
/**
+ * struct cxl_endpoint_dvsec_info - Cached DVSEC info
+ * @mem_enabled: cached value of mem_enabled in the DVSEC, PCIE_DEVICE
+ * @ranges: Number of active HDM ranges this device uses.
+ * @dvsec_range: cached attributes of the ranges in the DVSEC, PCIE_DEVICE
+ */
+struct cxl_endpoint_dvsec_info {
+ bool mem_enabled;
+ int ranges;
+ struct range dvsec_range[2];
+};
+
+/**
* struct cxl_dev_state - The driver device state
*
* cxl_dev_state represents the CXL driver/device state. It provides an
@@ -98,6 +118,7 @@ struct cxl_mbox_cmd {
*
* @dev: The device associated with this CXL state
* @regs: Parsed register blocks
+ * @cxl_dvsec: Offset to the PCIe device DVSEC
* @payload_size: Size of space for payload
* (CXL 2.0 8.2.8.4.3 Mailbox Capabilities Register)
* @lsa_size: Size of Label Storage Area
@@ -116,7 +137,11 @@ struct cxl_mbox_cmd {
* @active_persistent_bytes: sum of hard + soft persistent
* @next_volatile_bytes: volatile capacity change pending device reset
* @next_persistent_bytes: persistent capacity change pending device reset
+ * @component_reg_phys: register base of component registers
+ * @info: Cached DVSEC information about the device.
+ * @serial: PCIe Device Serial Number
* @mbox_send: @dev specific transport for transmitting mailbox commands
+ * @wait_media_ready: @dev specific method to await media ready
*
* See section 8.2.9.5.2 Capacity Configuration and Label Storage for
* details on capacity parameters.
@@ -125,6 +150,7 @@ struct cxl_dev_state {
struct device *dev;
struct cxl_regs regs;
+ int cxl_dvsec;
size_t payload_size;
size_t lsa_size;
@@ -145,7 +171,12 @@ struct cxl_dev_state {
u64 next_volatile_bytes;
u64 next_persistent_bytes;
+ resource_size_t component_reg_phys;
+ struct cxl_endpoint_dvsec_info info;
+ u64 serial;
+
int (*mbox_send)(struct cxl_dev_state *cxlds, struct cxl_mbox_cmd *cmd);
+ int (*wait_media_ready)(struct cxl_dev_state *cxlds);
};
enum cxl_opcode {
@@ -264,4 +295,12 @@ int cxl_mem_create_range_info(struct cxl_dev_state *cxlds);
struct cxl_dev_state *cxl_dev_state_create(struct device *dev);
void set_exclusive_cxl_commands(struct cxl_dev_state *cxlds, unsigned long *cmds);
void clear_exclusive_cxl_commands(struct cxl_dev_state *cxlds, unsigned long *cmds);
+
+struct cxl_hdm {
+ struct cxl_component_regs regs;
+ unsigned int decoder_count;
+ unsigned int target_count;
+ unsigned int interleave_mask;
+ struct cxl_port *port;
+};
#endif /* __CXL_MEM_H__ */
diff --git a/drivers/cxl/cxlpci.h b/drivers/cxl/cxlpci.h
new file mode 100644
index 000000000000..329e7ea3f36a
--- /dev/null
+++ b/drivers/cxl/cxlpci.h
@@ -0,0 +1,75 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/* Copyright(c) 2020 Intel Corporation. All rights reserved. */
+#ifndef __CXL_PCI_H__
+#define __CXL_PCI_H__
+#include <linux/pci.h>
+#include "cxl.h"
+
+#define CXL_MEMORY_PROGIF 0x10
+
+/*
+ * See section 8.1 Configuration Space Registers in the CXL 2.0
+ * Specification. Names are taken straight from the specification with "CXL" and
+ * "DVSEC" redundancies removed. When obvious, abbreviations may be used.
+ */
+#define PCI_DVSEC_HEADER1_LENGTH_MASK GENMASK(31, 20)
+#define PCI_DVSEC_VENDOR_ID_CXL 0x1E98
+
+/* CXL 2.0 8.1.3: PCIe DVSEC for CXL Device */
+#define CXL_DVSEC_PCIE_DEVICE 0
+#define CXL_DVSEC_CAP_OFFSET 0xA
+#define CXL_DVSEC_MEM_CAPABLE BIT(2)
+#define CXL_DVSEC_HDM_COUNT_MASK GENMASK(5, 4)
+#define CXL_DVSEC_CTRL_OFFSET 0xC
+#define CXL_DVSEC_MEM_ENABLE BIT(2)
+#define CXL_DVSEC_RANGE_SIZE_HIGH(i) (0x18 + (i * 0x10))
+#define CXL_DVSEC_RANGE_SIZE_LOW(i) (0x1C + (i * 0x10))
+#define CXL_DVSEC_MEM_INFO_VALID BIT(0)
+#define CXL_DVSEC_MEM_ACTIVE BIT(1)
+#define CXL_DVSEC_MEM_SIZE_LOW_MASK GENMASK(31, 28)
+#define CXL_DVSEC_RANGE_BASE_HIGH(i) (0x20 + (i * 0x10))
+#define CXL_DVSEC_RANGE_BASE_LOW(i) (0x24 + (i * 0x10))
+#define CXL_DVSEC_MEM_BASE_LOW_MASK GENMASK(31, 28)
+
+/* CXL 2.0 8.1.4: Non-CXL Function Map DVSEC */
+#define CXL_DVSEC_FUNCTION_MAP 2
+
+/* CXL 2.0 8.1.5: CXL 2.0 Extensions DVSEC for Ports */
+#define CXL_DVSEC_PORT_EXTENSIONS 3
+
+/* CXL 2.0 8.1.6: GPF DVSEC for CXL Port */
+#define CXL_DVSEC_PORT_GPF 4
+
+/* CXL 2.0 8.1.7: GPF DVSEC for CXL Device */
+#define CXL_DVSEC_DEVICE_GPF 5
+
+/* CXL 2.0 8.1.8: PCIe DVSEC for Flex Bus Port */
+#define CXL_DVSEC_PCIE_FLEXBUS_PORT 7
+
+/* CXL 2.0 8.1.9: Register Locator DVSEC */
+#define CXL_DVSEC_REG_LOCATOR 8
+#define CXL_DVSEC_REG_LOCATOR_BLOCK1_OFFSET 0xC
+#define CXL_DVSEC_REG_LOCATOR_BIR_MASK GENMASK(2, 0)
+#define CXL_DVSEC_REG_LOCATOR_BLOCK_ID_MASK GENMASK(15, 8)
+#define CXL_DVSEC_REG_LOCATOR_BLOCK_OFF_LOW_MASK GENMASK(31, 16)
+
+/* Register Block Identifier (RBI) */
+enum cxl_regloc_type {
+ CXL_REGLOC_RBI_EMPTY = 0,
+ CXL_REGLOC_RBI_COMPONENT,
+ CXL_REGLOC_RBI_VIRT,
+ CXL_REGLOC_RBI_MEMDEV,
+ CXL_REGLOC_RBI_TYPES
+};
+
+static inline resource_size_t cxl_regmap_to_base(struct pci_dev *pdev,
+ struct cxl_register_map *map)
+{
+ if (map->block_offset == U64_MAX)
+ return CXL_RESOURCE_NONE;
+
+ return pci_resource_start(pdev, map->barno) + map->block_offset;
+}
+
+int devm_cxl_port_enumerate_dports(struct cxl_port *port);
+#endif /* __CXL_PCI_H__ */
diff --git a/drivers/cxl/mem.c b/drivers/cxl/mem.c
new file mode 100644
index 000000000000..49a4b1c47299
--- /dev/null
+++ b/drivers/cxl/mem.c
@@ -0,0 +1,228 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/* Copyright(c) 2022 Intel Corporation. All rights reserved. */
+#include <linux/device.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+
+#include "cxlmem.h"
+#include "cxlpci.h"
+
+/**
+ * DOC: cxl mem
+ *
+ * CXL memory endpoint devices and switches are CXL capable devices that are
+ * participating in CXL.mem protocol. Their functionality builds on top of the
+ * CXL.io protocol that allows enumerating and configuring components via
+ * standard PCI mechanisms.
+ *
+ * The cxl_mem driver owns kicking off the enumeration of this CXL.mem
+ * capability. With the detection of a CXL capable endpoint, the driver will
+ * walk up to find the platform specific port it is connected to, and determine
+ * if there are intervening switches in the path. If there are switches, a
+ * secondary action is to enumerate those (implemented in cxl_core). Finally the
+ * cxl_mem driver adds the device it is bound to as a CXL endpoint-port for use
+ * in higher level operations.
+ */
+
+static int wait_for_media(struct cxl_memdev *cxlmd)
+{
+ struct cxl_dev_state *cxlds = cxlmd->cxlds;
+ struct cxl_endpoint_dvsec_info *info = &cxlds->info;
+ int rc;
+
+ if (!info->mem_enabled)
+ return -EBUSY;
+
+ rc = cxlds->wait_media_ready(cxlds);
+ if (rc)
+ return rc;
+
+ /*
+ * We know the device is active, and enabled, if any ranges are non-zero
+ * we'll need to check later before adding the port since that owns the
+ * HDM decoder registers.
+ */
+ return 0;
+}
+
+static int create_endpoint(struct cxl_memdev *cxlmd,
+ struct cxl_port *parent_port)
+{
+ struct cxl_dev_state *cxlds = cxlmd->cxlds;
+ struct cxl_port *endpoint;
+
+ endpoint = devm_cxl_add_port(&parent_port->dev, &cxlmd->dev,
+ cxlds->component_reg_phys, parent_port);
+ if (IS_ERR(endpoint))
+ return PTR_ERR(endpoint);
+
+ dev_dbg(&cxlmd->dev, "add: %s\n", dev_name(&endpoint->dev));
+
+ if (!endpoint->dev.driver) {
+ dev_err(&cxlmd->dev, "%s failed probe\n",
+ dev_name(&endpoint->dev));
+ return -ENXIO;
+ }
+
+ return cxl_endpoint_autoremove(cxlmd, endpoint);
+}
+
+/**
+ * cxl_dvsec_decode_init() - Setup HDM decoding for the endpoint
+ * @cxlds: Device state
+ *
+ * Additionally, enables global HDM decoding. Warning: don't call this outside
+ * of probe. Once probe is complete, the port driver owns all access to the HDM
+ * decoder registers.
+ *
+ * Returns: false if DVSEC Ranges are being used instead of HDM
+ * decoders, or if it can not be determined if DVSEC Ranges are in use.
+ * Otherwise, returns true.
+ */
+__mock bool cxl_dvsec_decode_init(struct cxl_dev_state *cxlds)
+{
+ struct cxl_endpoint_dvsec_info *info = &cxlds->info;
+ struct cxl_register_map map;
+ struct cxl_component_reg_map *cmap = &map.component_map;
+ bool global_enable, do_hdm_init = false;
+ void __iomem *crb;
+ u32 global_ctrl;
+
+ /* map hdm decoder */
+ crb = ioremap(cxlds->component_reg_phys, CXL_COMPONENT_REG_BLOCK_SIZE);
+ if (!crb) {
+ dev_dbg(cxlds->dev, "Failed to map component registers\n");
+ return false;
+ }
+
+ cxl_probe_component_regs(cxlds->dev, crb, cmap);
+ if (!cmap->hdm_decoder.valid) {
+ dev_dbg(cxlds->dev, "Invalid HDM decoder registers\n");
+ goto out;
+ }
+
+ global_ctrl = readl(crb + cmap->hdm_decoder.offset +
+ CXL_HDM_DECODER_CTRL_OFFSET);
+ global_enable = global_ctrl & CXL_HDM_DECODER_ENABLE;
+ if (!global_enable && info->ranges) {
+ dev_dbg(cxlds->dev,
+ "DVSEC ranges already programmed and HDM decoders not enabled.\n");
+ goto out;
+ }
+
+ do_hdm_init = true;
+
+ /*
+ * Permanently (for this boot at least) opt the device into HDM
+ * operation. Individual HDM decoders still need to be enabled after
+ * this point.
+ */
+ if (!global_enable) {
+ dev_dbg(cxlds->dev, "Enabling HDM decode\n");
+ writel(global_ctrl | CXL_HDM_DECODER_ENABLE,
+ crb + cmap->hdm_decoder.offset +
+ CXL_HDM_DECODER_CTRL_OFFSET);
+ }
+
+out:
+ iounmap(crb);
+ return do_hdm_init;
+}
+
+static int cxl_mem_probe(struct device *dev)
+{
+ struct cxl_memdev *cxlmd = to_cxl_memdev(dev);
+ struct cxl_dev_state *cxlds = cxlmd->cxlds;
+ struct cxl_port *parent_port;
+ int rc;
+
+ /*
+ * Someone is trying to reattach this device after it lost its port
+ * connection (an endpoint port previously registered by this memdev was
+ * disabled). This racy check is ok because if the port is still gone,
+ * no harm done, and if the port hierarchy comes back it will re-trigger
+ * this probe. Port rescan and memdev detach work share the same
+ * single-threaded workqueue.
+ */
+ if (work_pending(&cxlmd->detach_work))
+ return -EBUSY;
+
+ rc = wait_for_media(cxlmd);
+ if (rc) {
+ dev_err(dev, "Media not active (%d)\n", rc);
+ return rc;
+ }
+
+ /*
+ * If DVSEC ranges are being used instead of HDM decoder registers there
+ * is no use in trying to manage those.
+ */
+ if (!cxl_dvsec_decode_init(cxlds)) {
+ struct cxl_endpoint_dvsec_info *info = &cxlds->info;
+ int i;
+
+ /* */
+ for (i = 0; i < 2; i++) {
+ u64 base, size;
+
+ /*
+ * Give a nice warning to the user that BIOS has really
+ * botched things for them if it didn't place DVSEC
+ * ranges in the memory map.
+ */
+ base = info->dvsec_range[i].start;
+ size = range_len(&info->dvsec_range[i]);
+ if (size && !region_intersects(base, size,
+ IORESOURCE_SYSTEM_RAM,
+ IORES_DESC_NONE)) {
+ dev_err(dev,
+ "DVSEC range %#llx-%#llx must be reserved by BIOS, but isn't\n",
+ base, base + size - 1);
+ }
+ }
+ dev_err(dev,
+ "Active DVSEC range registers in use. Will not bind.\n");
+ return -EBUSY;
+ }
+
+ rc = devm_cxl_enumerate_ports(cxlmd);
+ if (rc)
+ return rc;
+
+ parent_port = cxl_mem_find_port(cxlmd);
+ if (!parent_port) {
+ dev_err(dev, "CXL port topology not found\n");
+ return -ENXIO;
+ }
+
+ cxl_device_lock(&parent_port->dev);
+ if (!parent_port->dev.driver) {
+ dev_err(dev, "CXL port topology %s not enabled\n",
+ dev_name(&parent_port->dev));
+ rc = -ENXIO;
+ goto out;
+ }
+
+ rc = create_endpoint(cxlmd, parent_port);
+out:
+ cxl_device_unlock(&parent_port->dev);
+ put_device(&parent_port->dev);
+ return rc;
+}
+
+static struct cxl_driver cxl_mem_driver = {
+ .name = "cxl_mem",
+ .probe = cxl_mem_probe,
+ .id = CXL_DEVICE_MEMORY_EXPANDER,
+};
+
+module_cxl_driver(cxl_mem_driver);
+
+MODULE_LICENSE("GPL v2");
+MODULE_IMPORT_NS(CXL);
+MODULE_ALIAS_CXL(CXL_DEVICE_MEMORY_EXPANDER);
+/*
+ * create_endpoint() wants to validate port driver attach immediately after
+ * endpoint registration.
+ */
+MODULE_SOFTDEP("pre: cxl_port");
diff --git a/drivers/cxl/pci.c b/drivers/cxl/pci.c
index 8dc91fd3396a..8a7267d116b7 100644
--- a/drivers/cxl/pci.c
+++ b/drivers/cxl/pci.c
@@ -1,14 +1,16 @@
// SPDX-License-Identifier: GPL-2.0-only
/* Copyright(c) 2020 Intel Corporation. All rights reserved. */
#include <linux/io-64-nonatomic-lo-hi.h>
+#include <linux/moduleparam.h>
#include <linux/module.h>
+#include <linux/delay.h>
#include <linux/sizes.h>
#include <linux/mutex.h>
#include <linux/list.h>
#include <linux/pci.h>
#include <linux/io.h>
#include "cxlmem.h"
-#include "pci.h"
+#include "cxlpci.h"
#include "cxl.h"
/**
@@ -35,6 +37,20 @@
/* CXL 2.0 - 8.2.8.4 */
#define CXL_MAILBOX_TIMEOUT_MS (2 * HZ)
+/*
+ * CXL 2.0 ECN "Add Mailbox Ready Time" defines a capability field to
+ * dictate how long to wait for the mailbox to become ready. The new
+ * field allows the device to tell software the amount of time to wait
+ * before mailbox ready. This field per the spec theoretically allows
+ * for up to 255 seconds. 255 seconds is unreasonably long, its longer
+ * than the maximum SATA port link recovery wait. Default to 60 seconds
+ * until someone builds a CXL device that needs more time in practice.
+ */
+static unsigned short mbox_ready_timeout = 60;
+module_param(mbox_ready_timeout, ushort, 0644);
+MODULE_PARM_DESC(mbox_ready_timeout,
+ "seconds to wait for mailbox ready / memory active status");
+
static int cxl_pci_mbox_wait_for_doorbell(struct cxl_dev_state *cxlds)
{
const unsigned long start = jiffies;
@@ -57,14 +73,16 @@ static int cxl_pci_mbox_wait_for_doorbell(struct cxl_dev_state *cxlds)
return 0;
}
-static void cxl_pci_mbox_timeout(struct cxl_dev_state *cxlds,
- struct cxl_mbox_cmd *mbox_cmd)
-{
- struct device *dev = cxlds->dev;
+#define cxl_err(dev, status, msg) \
+ dev_err_ratelimited(dev, msg ", device state %s%s\n", \
+ status & CXLMDEV_DEV_FATAL ? " fatal" : "", \
+ status & CXLMDEV_FW_HALT ? " firmware-halt" : "")
- dev_dbg(dev, "Mailbox command (opcode: %#x size: %zub) timed out\n",
- mbox_cmd->opcode, mbox_cmd->size_in);
-}
+#define cxl_cmd_err(dev, cmd, status, msg) \
+ dev_err_ratelimited(dev, msg " (opcode: %#x), device state %s%s\n", \
+ (cmd)->opcode, \
+ status & CXLMDEV_DEV_FATAL ? " fatal" : "", \
+ status & CXLMDEV_FW_HALT ? " firmware-halt" : "")
/**
* __cxl_pci_mbox_send_cmd() - Execute a mailbox command
@@ -118,7 +136,11 @@ static int __cxl_pci_mbox_send_cmd(struct cxl_dev_state *cxlds,
/* #1 */
if (cxl_doorbell_busy(cxlds)) {
- dev_err_ratelimited(dev, "Mailbox re-busy after acquiring\n");
+ u64 md_status =
+ readq(cxlds->regs.memdev + CXLMDEV_STATUS_OFFSET);
+
+ cxl_cmd_err(cxlds->dev, mbox_cmd, md_status,
+ "mailbox queue busy");
return -EBUSY;
}
@@ -144,7 +166,9 @@ static int __cxl_pci_mbox_send_cmd(struct cxl_dev_state *cxlds,
/* #5 */
rc = cxl_pci_mbox_wait_for_doorbell(cxlds);
if (rc == -ETIMEDOUT) {
- cxl_pci_mbox_timeout(cxlds, mbox_cmd);
+ u64 md_status = readq(cxlds->regs.memdev + CXLMDEV_STATUS_OFFSET);
+
+ cxl_cmd_err(cxlds->dev, mbox_cmd, md_status, "mailbox timeout");
return rc;
}
@@ -182,98 +206,13 @@ static int __cxl_pci_mbox_send_cmd(struct cxl_dev_state *cxlds,
return 0;
}
-/**
- * cxl_pci_mbox_get() - Acquire exclusive access to the mailbox.
- * @cxlds: The device state to gain access to.
- *
- * Context: Any context. Takes the mbox_mutex.
- * Return: 0 if exclusive access was acquired.
- */
-static int cxl_pci_mbox_get(struct cxl_dev_state *cxlds)
-{
- struct device *dev = cxlds->dev;
- u64 md_status;
- int rc;
-
- mutex_lock_io(&cxlds->mbox_mutex);
-
- /*
- * XXX: There is some amount of ambiguity in the 2.0 version of the spec
- * around the mailbox interface ready (8.2.8.5.1.1). The purpose of the
- * bit is to allow firmware running on the device to notify the driver
- * that it's ready to receive commands. It is unclear if the bit needs
- * to be read for each transaction mailbox, ie. the firmware can switch
- * it on and off as needed. Second, there is no defined timeout for
- * mailbox ready, like there is for the doorbell interface.
- *
- * Assumptions:
- * 1. The firmware might toggle the Mailbox Interface Ready bit, check
- * it for every command.
- *
- * 2. If the doorbell is clear, the firmware should have first set the
- * Mailbox Interface Ready bit. Therefore, waiting for the doorbell
- * to be ready is sufficient.
- */
- rc = cxl_pci_mbox_wait_for_doorbell(cxlds);
- if (rc) {
- dev_warn(dev, "Mailbox interface not ready\n");
- goto out;
- }
-
- md_status = readq(cxlds->regs.memdev + CXLMDEV_STATUS_OFFSET);
- if (!(md_status & CXLMDEV_MBOX_IF_READY && CXLMDEV_READY(md_status))) {
- dev_err(dev, "mbox: reported doorbell ready, but not mbox ready\n");
- rc = -EBUSY;
- goto out;
- }
-
- /*
- * Hardware shouldn't allow a ready status but also have failure bits
- * set. Spit out an error, this should be a bug report
- */
- rc = -EFAULT;
- if (md_status & CXLMDEV_DEV_FATAL) {
- dev_err(dev, "mbox: reported ready, but fatal\n");
- goto out;
- }
- if (md_status & CXLMDEV_FW_HALT) {
- dev_err(dev, "mbox: reported ready, but halted\n");
- goto out;
- }
- if (CXLMDEV_RESET_NEEDED(md_status)) {
- dev_err(dev, "mbox: reported ready, but reset needed\n");
- goto out;
- }
-
- /* with lock held */
- return 0;
-
-out:
- mutex_unlock(&cxlds->mbox_mutex);
- return rc;
-}
-
-/**
- * cxl_pci_mbox_put() - Release exclusive access to the mailbox.
- * @cxlds: The device state to communicate with.
- *
- * Context: Any context. Expects mbox_mutex to be held.
- */
-static void cxl_pci_mbox_put(struct cxl_dev_state *cxlds)
-{
- mutex_unlock(&cxlds->mbox_mutex);
-}
-
static int cxl_pci_mbox_send(struct cxl_dev_state *cxlds, struct cxl_mbox_cmd *cmd)
{
int rc;
- rc = cxl_pci_mbox_get(cxlds);
- if (rc)
- return rc;
-
+ mutex_lock_io(&cxlds->mbox_mutex);
rc = __cxl_pci_mbox_send_cmd(cxlds, cmd);
- cxl_pci_mbox_put(cxlds);
+ mutex_unlock(&cxlds->mbox_mutex);
return rc;
}
@@ -281,6 +220,34 @@ static int cxl_pci_mbox_send(struct cxl_dev_state *cxlds, struct cxl_mbox_cmd *c
static int cxl_pci_setup_mailbox(struct cxl_dev_state *cxlds)
{
const int cap = readl(cxlds->regs.mbox + CXLDEV_MBOX_CAPS_OFFSET);
+ unsigned long timeout;
+ u64 md_status;
+
+ timeout = jiffies + mbox_ready_timeout * HZ;
+ do {
+ md_status = readq(cxlds->regs.memdev + CXLMDEV_STATUS_OFFSET);
+ if (md_status & CXLMDEV_MBOX_IF_READY)
+ break;
+ if (msleep_interruptible(100))
+ break;
+ } while (!time_after(jiffies, timeout));
+
+ if (!(md_status & CXLMDEV_MBOX_IF_READY)) {
+ cxl_err(cxlds->dev, md_status,
+ "timeout awaiting mailbox ready");
+ return -ETIMEDOUT;
+ }
+
+ /*
+ * A command may be in flight from a previous driver instance,
+ * think kexec, do one doorbell wait so that
+ * __cxl_pci_mbox_send_cmd() can assume that it is the only
+ * source for future doorbell busy events.
+ */
+ if (cxl_pci_mbox_wait_for_doorbell(cxlds) != 0) {
+ cxl_err(cxlds->dev, md_status, "timeout awaiting mailbox idle");
+ return -ETIMEDOUT;
+ }
cxlds->mbox_send = cxl_pci_mbox_send;
cxlds->payload_size =
@@ -400,75 +367,182 @@ static int cxl_map_regs(struct cxl_dev_state *cxlds, struct cxl_register_map *ma
return 0;
}
-static void cxl_decode_regblock(u32 reg_lo, u32 reg_hi,
- struct cxl_register_map *map)
+static int cxl_setup_regs(struct pci_dev *pdev, enum cxl_regloc_type type,
+ struct cxl_register_map *map)
{
- map->block_offset =
- ((u64)reg_hi << 32) | (reg_lo & CXL_REGLOC_ADDR_MASK);
- map->barno = FIELD_GET(CXL_REGLOC_BIR_MASK, reg_lo);
- map->reg_type = FIELD_GET(CXL_REGLOC_RBI_MASK, reg_lo);
+ int rc;
+
+ rc = cxl_find_regblock(pdev, type, map);
+ if (rc)
+ return rc;
+
+ rc = cxl_map_regblock(pdev, map);
+ if (rc)
+ return rc;
+
+ rc = cxl_probe_regs(pdev, map);
+ cxl_unmap_regblock(pdev, map);
+
+ return rc;
}
-/**
- * cxl_find_regblock() - Locate register blocks by type
- * @pdev: The CXL PCI device to enumerate.
- * @type: Register Block Indicator id
- * @map: Enumeration output, clobbered on error
- *
- * Return: 0 if register block enumerated, negative error code otherwise
- *
- * A CXL DVSEC may point to one or more register blocks, search for them
- * by @type.
- */
-static int cxl_find_regblock(struct pci_dev *pdev, enum cxl_regloc_type type,
- struct cxl_register_map *map)
+static int wait_for_valid(struct cxl_dev_state *cxlds)
{
- u32 regloc_size, regblocks;
- int regloc, i;
+ struct pci_dev *pdev = to_pci_dev(cxlds->dev);
+ int d = cxlds->cxl_dvsec, rc;
+ u32 val;
- regloc = pci_find_dvsec_capability(pdev, PCI_DVSEC_VENDOR_ID_CXL,
- PCI_DVSEC_ID_CXL_REGLOC_DVSEC_ID);
- if (!regloc)
- return -ENXIO;
+ /*
+ * Memory_Info_Valid: When set, indicates that the CXL Range 1 Size high
+ * and Size Low registers are valid. Must be set within 1 second of
+ * deassertion of reset to CXL device. Likely it is already set by the
+ * time this runs, but otherwise give a 1.5 second timeout in case of
+ * clock skew.
+ */
+ rc = pci_read_config_dword(pdev, d + CXL_DVSEC_RANGE_SIZE_LOW(0), &val);
+ if (rc)
+ return rc;
+
+ if (val & CXL_DVSEC_MEM_INFO_VALID)
+ return 0;
+
+ msleep(1500);
+
+ rc = pci_read_config_dword(pdev, d + CXL_DVSEC_RANGE_SIZE_LOW(0), &val);
+ if (rc)
+ return rc;
- pci_read_config_dword(pdev, regloc + PCI_DVSEC_HEADER1, &regloc_size);
- regloc_size = FIELD_GET(PCI_DVSEC_HEADER1_LENGTH_MASK, regloc_size);
+ if (val & CXL_DVSEC_MEM_INFO_VALID)
+ return 0;
- regloc += PCI_DVSEC_ID_CXL_REGLOC_BLOCK1_OFFSET;
- regblocks = (regloc_size - PCI_DVSEC_ID_CXL_REGLOC_BLOCK1_OFFSET) / 8;
+ return -ETIMEDOUT;
+}
+
+/*
+ * Wait up to @mbox_ready_timeout for the device to report memory
+ * active.
+ */
+static int wait_for_media_ready(struct cxl_dev_state *cxlds)
+{
+ struct pci_dev *pdev = to_pci_dev(cxlds->dev);
+ int d = cxlds->cxl_dvsec;
+ bool active = false;
+ u64 md_status;
+ int rc, i;
+
+ rc = wait_for_valid(cxlds);
+ if (rc)
+ return rc;
- for (i = 0; i < regblocks; i++, regloc += 8) {
- u32 reg_lo, reg_hi;
+ for (i = mbox_ready_timeout; i; i--) {
+ u32 temp;
+ int rc;
- pci_read_config_dword(pdev, regloc, &reg_lo);
- pci_read_config_dword(pdev, regloc + 4, &reg_hi);
+ rc = pci_read_config_dword(
+ pdev, d + CXL_DVSEC_RANGE_SIZE_LOW(0), &temp);
+ if (rc)
+ return rc;
- cxl_decode_regblock(reg_lo, reg_hi, map);
+ active = FIELD_GET(CXL_DVSEC_MEM_ACTIVE, temp);
+ if (active)
+ break;
+ msleep(1000);
+ }
- if (map->reg_type == type)
- return 0;
+ if (!active) {
+ dev_err(&pdev->dev,
+ "timeout awaiting memory active after %d seconds\n",
+ mbox_ready_timeout);
+ return -ETIMEDOUT;
}
- return -ENODEV;
+ md_status = readq(cxlds->regs.memdev + CXLMDEV_STATUS_OFFSET);
+ if (!CXLMDEV_READY(md_status))
+ return -EIO;
+
+ return 0;
}
-static int cxl_setup_regs(struct pci_dev *pdev, enum cxl_regloc_type type,
- struct cxl_register_map *map)
+static int cxl_dvsec_ranges(struct cxl_dev_state *cxlds)
{
- int rc;
+ struct cxl_endpoint_dvsec_info *info = &cxlds->info;
+ struct pci_dev *pdev = to_pci_dev(cxlds->dev);
+ int d = cxlds->cxl_dvsec;
+ int hdm_count, rc, i;
+ u16 cap, ctrl;
- rc = cxl_find_regblock(pdev, type, map);
+ if (!d)
+ return -ENXIO;
+
+ rc = pci_read_config_word(pdev, d + CXL_DVSEC_CAP_OFFSET, &cap);
if (rc)
return rc;
- rc = cxl_map_regblock(pdev, map);
+ rc = pci_read_config_word(pdev, d + CXL_DVSEC_CTRL_OFFSET, &ctrl);
if (rc)
return rc;
- rc = cxl_probe_regs(pdev, map);
- cxl_unmap_regblock(pdev, map);
+ if (!(cap & CXL_DVSEC_MEM_CAPABLE))
+ return -ENXIO;
- return rc;
+ /*
+ * It is not allowed by spec for MEM.capable to be set and have 0 legacy
+ * HDM decoders (values > 2 are also undefined as of CXL 2.0). As this
+ * driver is for a spec defined class code which must be CXL.mem
+ * capable, there is no point in continuing to enable CXL.mem.
+ */
+ hdm_count = FIELD_GET(CXL_DVSEC_HDM_COUNT_MASK, cap);
+ if (!hdm_count || hdm_count > 2)
+ return -EINVAL;
+
+ rc = wait_for_valid(cxlds);
+ if (rc)
+ return rc;
+
+ info->mem_enabled = FIELD_GET(CXL_DVSEC_MEM_ENABLE, ctrl);
+
+ for (i = 0; i < hdm_count; i++) {
+ u64 base, size;
+ u32 temp;
+
+ rc = pci_read_config_dword(
+ pdev, d + CXL_DVSEC_RANGE_SIZE_HIGH(i), &temp);
+ if (rc)
+ return rc;
+
+ size = (u64)temp << 32;
+
+ rc = pci_read_config_dword(
+ pdev, d + CXL_DVSEC_RANGE_SIZE_LOW(i), &temp);
+ if (rc)
+ return rc;
+
+ size |= temp & CXL_DVSEC_MEM_SIZE_LOW_MASK;
+
+ rc = pci_read_config_dword(
+ pdev, d + CXL_DVSEC_RANGE_BASE_HIGH(i), &temp);
+ if (rc)
+ return rc;
+
+ base = (u64)temp << 32;
+
+ rc = pci_read_config_dword(
+ pdev, d + CXL_DVSEC_RANGE_BASE_LOW(i), &temp);
+ if (rc)
+ return rc;
+
+ base |= temp & CXL_DVSEC_MEM_BASE_LOW_MASK;
+
+ info->dvsec_range[i] = (struct range) {
+ .start = base,
+ .end = base + size - 1
+ };
+
+ if (size)
+ info->ranges++;
+ }
+
+ return 0;
}
static int cxl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
@@ -493,6 +567,15 @@ static int cxl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
if (IS_ERR(cxlds))
return PTR_ERR(cxlds);
+ cxlds->serial = pci_get_dsn(pdev);
+ cxlds->cxl_dvsec = pci_find_dvsec_capability(
+ pdev, PCI_DVSEC_VENDOR_ID_CXL, CXL_DVSEC_PCIE_DEVICE);
+ if (!cxlds->cxl_dvsec)
+ dev_warn(&pdev->dev,
+ "Device DVSEC not present, skip CXL.mem init\n");
+
+ cxlds->wait_media_ready = wait_for_media_ready;
+
rc = cxl_setup_regs(pdev, CXL_REGLOC_RBI_MEMDEV, &map);
if (rc)
return rc;
@@ -501,6 +584,17 @@ static int cxl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
if (rc)
return rc;
+ /*
+ * If the component registers can't be found, the cxl_pci driver may
+ * still be useful for management functions so don't return an error.
+ */
+ cxlds->component_reg_phys = CXL_RESOURCE_NONE;
+ rc = cxl_setup_regs(pdev, CXL_REGLOC_RBI_COMPONENT, &map);
+ if (rc)
+ dev_warn(&pdev->dev, "No component registers (%d)\n", rc);
+
+ cxlds->component_reg_phys = cxl_regmap_to_base(pdev, &map);
+
rc = cxl_pci_setup_mailbox(cxlds);
if (rc)
return rc;
@@ -517,6 +611,11 @@ static int cxl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
if (rc)
return rc;
+ rc = cxl_dvsec_ranges(cxlds);
+ if (rc)
+ dev_warn(&pdev->dev,
+ "Failed to get DVSEC range information (%d)\n", rc);
+
cxlmd = devm_cxl_add_memdev(cxlds);
if (IS_ERR(cxlmd))
return PTR_ERR(cxlmd);
diff --git a/drivers/cxl/pci.h b/drivers/cxl/pci.h
deleted file mode 100644
index 7d3e4bf06b45..000000000000
--- a/drivers/cxl/pci.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/* Copyright(c) 2020 Intel Corporation. All rights reserved. */
-#ifndef __CXL_PCI_H__
-#define __CXL_PCI_H__
-
-#define CXL_MEMORY_PROGIF 0x10
-
-/*
- * See section 8.1 Configuration Space Registers in the CXL 2.0
- * Specification
- */
-#define PCI_DVSEC_HEADER1_LENGTH_MASK GENMASK(31, 20)
-#define PCI_DVSEC_VENDOR_ID_CXL 0x1E98
-#define PCI_DVSEC_ID_CXL 0x0
-
-#define PCI_DVSEC_ID_CXL_REGLOC_DVSEC_ID 0x8
-#define PCI_DVSEC_ID_CXL_REGLOC_BLOCK1_OFFSET 0xC
-
-/* BAR Indicator Register (BIR) */
-#define CXL_REGLOC_BIR_MASK GENMASK(2, 0)
-
-/* Register Block Identifier (RBI) */
-enum cxl_regloc_type {
- CXL_REGLOC_RBI_EMPTY = 0,
- CXL_REGLOC_RBI_COMPONENT,
- CXL_REGLOC_RBI_VIRT,
- CXL_REGLOC_RBI_MEMDEV,
- CXL_REGLOC_RBI_TYPES
-};
-
-#define CXL_REGLOC_RBI_MASK GENMASK(15, 8)
-#define CXL_REGLOC_ADDR_MASK GENMASK(31, 16)
-
-#endif /* __CXL_PCI_H__ */
diff --git a/drivers/cxl/pmem.c b/drivers/cxl/pmem.c
index b65a272a2d6d..15ad666ab03e 100644
--- a/drivers/cxl/pmem.c
+++ b/drivers/cxl/pmem.c
@@ -43,7 +43,7 @@ static int cxl_nvdimm_probe(struct device *dev)
if (!cxl_nvb)
return -ENXIO;
- device_lock(&cxl_nvb->dev);
+ cxl_device_lock(&cxl_nvb->dev);
if (!cxl_nvb->nvdimm_bus) {
rc = -ENXIO;
goto out;
@@ -68,7 +68,7 @@ static int cxl_nvdimm_probe(struct device *dev)
dev_set_drvdata(dev, nvdimm);
rc = devm_add_action_or_reset(dev, unregister_nvdimm, nvdimm);
out:
- device_unlock(&cxl_nvb->dev);
+ cxl_device_unlock(&cxl_nvb->dev);
put_device(&cxl_nvb->dev);
return rc;
@@ -233,7 +233,7 @@ static void cxl_nvb_update_state(struct work_struct *work)
struct nvdimm_bus *victim_bus = NULL;
bool release = false, rescan = false;
- device_lock(&cxl_nvb->dev);
+ cxl_device_lock(&cxl_nvb->dev);
switch (cxl_nvb->state) {
case CXL_NVB_ONLINE:
if (!online_nvdimm_bus(cxl_nvb)) {
@@ -251,7 +251,7 @@ static void cxl_nvb_update_state(struct work_struct *work)
default:
break;
}
- device_unlock(&cxl_nvb->dev);
+ cxl_device_unlock(&cxl_nvb->dev);
if (release)
device_release_driver(&cxl_nvb->dev);
@@ -327,9 +327,9 @@ static int cxl_nvdimm_bridge_reset(struct device *dev, void *data)
return 0;
cxl_nvb = to_cxl_nvdimm_bridge(dev);
- device_lock(dev);
+ cxl_device_lock(dev);
cxl_nvb->state = CXL_NVB_NEW;
- device_unlock(dev);
+ cxl_device_unlock(dev);
return 0;
}
diff --git a/drivers/cxl/port.c b/drivers/cxl/port.c
new file mode 100644
index 000000000000..d420da5fc39c
--- /dev/null
+++ b/drivers/cxl/port.c
@@ -0,0 +1,76 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/* Copyright(c) 2022 Intel Corporation. All rights reserved. */
+#include <linux/device.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+
+#include "cxlmem.h"
+#include "cxlpci.h"
+
+/**
+ * DOC: cxl port
+ *
+ * The port driver enumerates dport via PCI and scans for HDM
+ * (Host-managed-Device-Memory) decoder resources via the
+ * @component_reg_phys value passed in by the agent that registered the
+ * port. All descendant ports of a CXL root port (described by platform
+ * firmware) are managed in this drivers context. Each driver instance
+ * is responsible for tearing down the driver context of immediate
+ * descendant ports. The locking for this is validated by
+ * CONFIG_PROVE_CXL_LOCKING.
+ *
+ * The primary service this driver provides is presenting APIs to other
+ * drivers to utilize the decoders, and indicating to userspace (via bind
+ * status) the connectivity of the CXL.mem protocol throughout the
+ * PCIe topology.
+ */
+
+static void schedule_detach(void *cxlmd)
+{
+ schedule_cxl_memdev_detach(cxlmd);
+}
+
+static int cxl_port_probe(struct device *dev)
+{
+ struct cxl_port *port = to_cxl_port(dev);
+ struct cxl_hdm *cxlhdm;
+ int rc;
+
+ if (is_cxl_endpoint(port)) {
+ struct cxl_memdev *cxlmd = to_cxl_memdev(port->uport);
+
+ get_device(&cxlmd->dev);
+ rc = devm_add_action_or_reset(dev, schedule_detach, cxlmd);
+ if (rc)
+ return rc;
+ } else {
+ rc = devm_cxl_port_enumerate_dports(port);
+ if (rc < 0)
+ return rc;
+ if (rc == 1)
+ return devm_cxl_add_passthrough_decoder(port);
+ }
+
+ cxlhdm = devm_cxl_setup_hdm(port);
+ if (IS_ERR(cxlhdm))
+ return PTR_ERR(cxlhdm);
+
+ rc = devm_cxl_enumerate_decoders(cxlhdm);
+ if (rc) {
+ dev_err(dev, "Couldn't enumerate decoders (%d)\n", rc);
+ return rc;
+ }
+
+ return 0;
+}
+
+static struct cxl_driver cxl_port_driver = {
+ .name = "cxl_port",
+ .probe = cxl_port_probe,
+ .id = CXL_DEVICE_PORT,
+};
+
+module_cxl_driver(cxl_port_driver);
+MODULE_LICENSE("GPL v2");
+MODULE_IMPORT_NS(CXL);
+MODULE_ALIAS_CXL(CXL_DEVICE_PORT);
diff --git a/drivers/dax/device.c b/drivers/dax/device.c
index d33a0613ed0c..5494d745ced5 100644
--- a/drivers/dax/device.c
+++ b/drivers/dax/device.c
@@ -346,8 +346,7 @@ static unsigned long dax_get_unmapped_area(struct file *filp,
}
static const struct address_space_operations dev_dax_aops = {
- .set_page_dirty = __set_page_dirty_no_writeback,
- .invalidatepage = noop_invalidatepage,
+ .dirty_folio = noop_dirty_folio,
};
static int dax_open(struct inode *inode, struct file *filp)
diff --git a/drivers/dax/super.c b/drivers/dax/super.c
index e3029389d809..0211e6f7b47a 100644
--- a/drivers/dax/super.c
+++ b/drivers/dax/super.c
@@ -21,6 +21,7 @@
* @cdev: optional character interface for "device dax"
* @private: dax driver private data
* @flags: state and boolean properties
+ * @ops: operations for this device
*/
struct dax_device {
struct inode inode;
@@ -282,7 +283,7 @@ static struct inode *dax_alloc_inode(struct super_block *sb)
struct dax_device *dax_dev;
struct inode *inode;
- dax_dev = kmem_cache_alloc(dax_cache, GFP_KERNEL);
+ dax_dev = alloc_inode_sb(sb, dax_cache, GFP_KERNEL);
if (!dax_dev)
return NULL;
@@ -476,6 +477,7 @@ static int dax_fs_init(void)
static void dax_fs_exit(void)
{
kern_unmount(dax_mnt);
+ rcu_barrier();
kmem_cache_destroy(dax_cache);
}
diff --git a/drivers/dma-buf/dma-buf.c b/drivers/dma-buf/dma-buf.c
index 602b12d7470d..df23239b04fc 100644
--- a/drivers/dma-buf/dma-buf.c
+++ b/drivers/dma-buf/dma-buf.c
@@ -1047,8 +1047,8 @@ EXPORT_SYMBOL_NS_GPL(dma_buf_move_notify, DMA_BUF);
*
* Interfaces::
*
- * void \*dma_buf_vmap(struct dma_buf \*dmabuf, struct dma_buf_map \*map)
- * void dma_buf_vunmap(struct dma_buf \*dmabuf, struct dma_buf_map \*map)
+ * void \*dma_buf_vmap(struct dma_buf \*dmabuf, struct iosys_map \*map)
+ * void dma_buf_vunmap(struct dma_buf \*dmabuf, struct iosys_map \*map)
*
* The vmap call can fail if there is no vmap support in the exporter, or if
* it runs out of vmalloc space. Note that the dma-buf layer keeps a reference
@@ -1260,12 +1260,12 @@ EXPORT_SYMBOL_NS_GPL(dma_buf_mmap, DMA_BUF);
*
* Returns 0 on success, or a negative errno code otherwise.
*/
-int dma_buf_vmap(struct dma_buf *dmabuf, struct dma_buf_map *map)
+int dma_buf_vmap(struct dma_buf *dmabuf, struct iosys_map *map)
{
- struct dma_buf_map ptr;
+ struct iosys_map ptr;
int ret = 0;
- dma_buf_map_clear(map);
+ iosys_map_clear(map);
if (WARN_ON(!dmabuf))
return -EINVAL;
@@ -1276,12 +1276,12 @@ int dma_buf_vmap(struct dma_buf *dmabuf, struct dma_buf_map *map)
mutex_lock(&dmabuf->lock);
if (dmabuf->vmapping_counter) {
dmabuf->vmapping_counter++;
- BUG_ON(dma_buf_map_is_null(&dmabuf->vmap_ptr));
+ BUG_ON(iosys_map_is_null(&dmabuf->vmap_ptr));
*map = dmabuf->vmap_ptr;
goto out_unlock;
}
- BUG_ON(dma_buf_map_is_set(&dmabuf->vmap_ptr));
+ BUG_ON(iosys_map_is_set(&dmabuf->vmap_ptr));
ret = dmabuf->ops->vmap(dmabuf, &ptr);
if (WARN_ON_ONCE(ret))
@@ -1303,20 +1303,20 @@ EXPORT_SYMBOL_NS_GPL(dma_buf_vmap, DMA_BUF);
* @dmabuf: [in] buffer to vunmap
* @map: [in] vmap pointer to vunmap
*/
-void dma_buf_vunmap(struct dma_buf *dmabuf, struct dma_buf_map *map)
+void dma_buf_vunmap(struct dma_buf *dmabuf, struct iosys_map *map)
{
if (WARN_ON(!dmabuf))
return;
- BUG_ON(dma_buf_map_is_null(&dmabuf->vmap_ptr));
+ BUG_ON(iosys_map_is_null(&dmabuf->vmap_ptr));
BUG_ON(dmabuf->vmapping_counter == 0);
- BUG_ON(!dma_buf_map_is_equal(&dmabuf->vmap_ptr, map));
+ BUG_ON(!iosys_map_is_equal(&dmabuf->vmap_ptr, map));
mutex_lock(&dmabuf->lock);
if (--dmabuf->vmapping_counter == 0) {
if (dmabuf->ops->vunmap)
dmabuf->ops->vunmap(dmabuf, map);
- dma_buf_map_clear(&dmabuf->vmap_ptr);
+ iosys_map_clear(&dmabuf->vmap_ptr);
}
mutex_unlock(&dmabuf->lock);
}
diff --git a/drivers/dma-buf/dma-fence-array.c b/drivers/dma-buf/dma-fence-array.c
index 3e07f961e2f3..cb1bacb5a42b 100644
--- a/drivers/dma-buf/dma-fence-array.c
+++ b/drivers/dma-buf/dma-fence-array.c
@@ -176,6 +176,20 @@ struct dma_fence_array *dma_fence_array_create(int num_fences,
array->base.error = PENDING_ERROR;
+ /*
+ * dma_fence_array objects should never contain any other fence
+ * containers or otherwise we run into recursion and potential kernel
+ * stack overflow on operations on the dma_fence_array.
+ *
+ * The correct way of handling this is to flatten out the array by the
+ * caller instead.
+ *
+ * Enforce this here by checking that we don't create a dma_fence_array
+ * with any container inside.
+ */
+ while (num_fences--)
+ WARN_ON(dma_fence_is_container(fences[num_fences]));
+
return array;
}
EXPORT_SYMBOL(dma_fence_array_create);
diff --git a/drivers/dma-buf/dma-fence-chain.c b/drivers/dma-buf/dma-fence-chain.c
index 1b4cb3e5cec9..06f8ef97c6e8 100644
--- a/drivers/dma-buf/dma-fence-chain.c
+++ b/drivers/dma-buf/dma-fence-chain.c
@@ -148,8 +148,7 @@ static bool dma_fence_chain_enable_signaling(struct dma_fence *fence)
dma_fence_get(&head->base);
dma_fence_chain_for_each(fence, &head->base) {
- struct dma_fence_chain *chain = to_dma_fence_chain(fence);
- struct dma_fence *f = chain ? chain->fence : fence;
+ struct dma_fence *f = dma_fence_chain_contained(fence);
dma_fence_get(f);
if (!dma_fence_add_callback(f, &head->cb, dma_fence_chain_cb)) {
@@ -165,8 +164,7 @@ static bool dma_fence_chain_enable_signaling(struct dma_fence *fence)
static bool dma_fence_chain_signaled(struct dma_fence *fence)
{
dma_fence_chain_for_each(fence, fence) {
- struct dma_fence_chain *chain = to_dma_fence_chain(fence);
- struct dma_fence *f = chain ? chain->fence : fence;
+ struct dma_fence *f = dma_fence_chain_contained(fence);
if (!dma_fence_is_signaled(f)) {
dma_fence_put(fence);
@@ -254,5 +252,14 @@ void dma_fence_chain_init(struct dma_fence_chain *chain,
dma_fence_init(&chain->base, &dma_fence_chain_ops,
&chain->lock, context, seqno);
+
+ /*
+ * Chaining dma_fence_chain container together is only allowed through
+ * the prev fence and not through the contained fence.
+ *
+ * The correct way of handling this is to flatten out the fence
+ * structure into a dma_fence_array by the caller instead.
+ */
+ WARN_ON(dma_fence_is_chain(fence));
}
EXPORT_SYMBOL(dma_fence_chain_init);
diff --git a/drivers/dma-buf/dma-heap.c b/drivers/dma-buf/dma-heap.c
index 56bf5ad01ad5..8f5848aa144f 100644
--- a/drivers/dma-buf/dma-heap.c
+++ b/drivers/dma-buf/dma-heap.c
@@ -14,6 +14,7 @@
#include <linux/xarray.h>
#include <linux/list.h>
#include <linux/slab.h>
+#include <linux/nospec.h>
#include <linux/uaccess.h>
#include <linux/syscalls.h>
#include <linux/dma-heap.h>
@@ -135,6 +136,7 @@ static long dma_heap_ioctl(struct file *file, unsigned int ucmd,
if (nr >= ARRAY_SIZE(dma_heap_ioctl_cmds))
return -EINVAL;
+ nr = array_index_nospec(nr, ARRAY_SIZE(dma_heap_ioctl_cmds));
/* Get the kernel ioctl cmd that matches */
kcmd = dma_heap_ioctl_cmds[nr];
diff --git a/drivers/dma-buf/dma-resv.c b/drivers/dma-buf/dma-resv.c
index 4deea75c0b9c..b51416405e86 100644
--- a/drivers/dma-buf/dma-resv.c
+++ b/drivers/dma-buf/dma-resv.c
@@ -256,6 +256,11 @@ void dma_resv_add_shared_fence(struct dma_resv *obj, struct dma_fence *fence)
dma_resv_assert_held(obj);
+ /* Drivers should not add containers here, instead add each fence
+ * individually.
+ */
+ WARN_ON(dma_fence_is_container(fence));
+
fobj = dma_resv_shared_list(obj);
count = fobj->shared_count;
@@ -323,12 +328,8 @@ void dma_resv_add_excl_fence(struct dma_resv *obj, struct dma_fence *fence)
}
EXPORT_SYMBOL(dma_resv_add_excl_fence);
-/**
- * dma_resv_iter_restart_unlocked - restart the unlocked iterator
- * @cursor: The dma_resv_iter object to restart
- *
- * Restart the unlocked iteration by initializing the cursor object.
- */
+/* Restart the iterator by initializing all the necessary fields, but not the
+ * relation to the dma_resv object. */
static void dma_resv_iter_restart_unlocked(struct dma_resv_iter *cursor)
{
cursor->seq = read_seqcount_begin(&cursor->obj->seq);
@@ -344,14 +345,7 @@ static void dma_resv_iter_restart_unlocked(struct dma_resv_iter *cursor)
cursor->is_restarted = true;
}
-/**
- * dma_resv_iter_walk_unlocked - walk over fences in a dma_resv obj
- * @cursor: cursor to record the current position
- *
- * Return all the fences in the dma_resv object which are not yet signaled.
- * The returned fence has an extra local reference so will stay alive.
- * If a concurrent modify is detected the whole iteration is started over again.
- */
+/* Walk to the next not signaled fence and grab a reference to it */
static void dma_resv_iter_walk_unlocked(struct dma_resv_iter *cursor)
{
struct dma_resv *obj = cursor->obj;
@@ -387,6 +381,12 @@ static void dma_resv_iter_walk_unlocked(struct dma_resv_iter *cursor)
* dma_resv_iter_first_unlocked - first fence in an unlocked dma_resv obj.
* @cursor: the cursor with the current position
*
+ * Subsequent fences are iterated with dma_resv_iter_next_unlocked().
+ *
+ * Beware that the iterator can be restarted. Code which accumulates statistics
+ * or similar needs to check for this with dma_resv_iter_is_restarted(). For
+ * this reason prefer the locked dma_resv_iter_first() whenver possible.
+ *
* Returns the first fence from an unlocked dma_resv obj.
*/
struct dma_fence *dma_resv_iter_first_unlocked(struct dma_resv_iter *cursor)
@@ -406,6 +406,10 @@ EXPORT_SYMBOL(dma_resv_iter_first_unlocked);
* dma_resv_iter_next_unlocked - next fence in an unlocked dma_resv obj.
* @cursor: the cursor with the current position
*
+ * Beware that the iterator can be restarted. Code which accumulates statistics
+ * or similar needs to check for this with dma_resv_iter_is_restarted(). For
+ * this reason prefer the locked dma_resv_iter_next() whenver possible.
+ *
* Returns the next fence from an unlocked dma_resv obj.
*/
struct dma_fence *dma_resv_iter_next_unlocked(struct dma_resv_iter *cursor)
@@ -431,6 +435,8 @@ EXPORT_SYMBOL(dma_resv_iter_next_unlocked);
* dma_resv_iter_first - first fence from a locked dma_resv object
* @cursor: cursor to record the current position
*
+ * Subsequent fences are iterated with dma_resv_iter_next_unlocked().
+ *
* Return the first fence in the dma_resv object while holding the
* &dma_resv.lock.
*/
@@ -542,57 +548,45 @@ EXPORT_SYMBOL(dma_resv_copy_fences);
* dma_resv_get_fences - Get an object's shared and exclusive
* fences without update side lock held
* @obj: the reservation object
- * @fence_excl: the returned exclusive fence (or NULL)
- * @shared_count: the number of shared fences returned
- * @shared: the array of shared fence ptrs returned (array is krealloc'd to
- * the required size, and must be freed by caller)
- *
- * Retrieve all fences from the reservation object. If the pointer for the
- * exclusive fence is not specified the fence is put into the array of the
- * shared fences as well. Returns either zero or -ENOMEM.
+ * @write: true if we should return all fences
+ * @num_fences: the number of fences returned
+ * @fences: the array of fence ptrs returned (array is krealloc'd to the
+ * required size, and must be freed by caller)
+ *
+ * Retrieve all fences from the reservation object.
+ * Returns either zero or -ENOMEM.
*/
-int dma_resv_get_fences(struct dma_resv *obj, struct dma_fence **fence_excl,
- unsigned int *shared_count, struct dma_fence ***shared)
+int dma_resv_get_fences(struct dma_resv *obj, bool write,
+ unsigned int *num_fences, struct dma_fence ***fences)
{
struct dma_resv_iter cursor;
struct dma_fence *fence;
- *shared_count = 0;
- *shared = NULL;
-
- if (fence_excl)
- *fence_excl = NULL;
+ *num_fences = 0;
+ *fences = NULL;
- dma_resv_iter_begin(&cursor, obj, true);
+ dma_resv_iter_begin(&cursor, obj, write);
dma_resv_for_each_fence_unlocked(&cursor, fence) {
if (dma_resv_iter_is_restarted(&cursor)) {
unsigned int count;
- while (*shared_count)
- dma_fence_put((*shared)[--(*shared_count)]);
+ while (*num_fences)
+ dma_fence_put((*fences)[--(*num_fences)]);
- if (fence_excl)
- dma_fence_put(*fence_excl);
-
- count = cursor.shared_count;
- count += fence_excl ? 0 : 1;
+ count = cursor.shared_count + 1;
/* Eventually re-allocate the array */
- *shared = krealloc_array(*shared, count,
+ *fences = krealloc_array(*fences, count,
sizeof(void *),
GFP_KERNEL);
- if (count && !*shared) {
+ if (count && !*fences) {
dma_resv_iter_end(&cursor);
return -ENOMEM;
}
}
- dma_fence_get(fence);
- if (dma_resv_iter_is_exclusive(&cursor) && fence_excl)
- *fence_excl = fence;
- else
- (*shared)[(*shared_count)++] = fence;
+ (*fences)[(*num_fences)++] = dma_fence_get(fence);
}
dma_resv_iter_end(&cursor);
diff --git a/drivers/dma-buf/heaps/cma_heap.c b/drivers/dma-buf/heaps/cma_heap.c
index 83f02bd51dda..28fb04eccdd0 100644
--- a/drivers/dma-buf/heaps/cma_heap.c
+++ b/drivers/dma-buf/heaps/cma_heap.c
@@ -202,7 +202,7 @@ static void *cma_heap_do_vmap(struct cma_heap_buffer *buffer)
return vaddr;
}
-static int cma_heap_vmap(struct dma_buf *dmabuf, struct dma_buf_map *map)
+static int cma_heap_vmap(struct dma_buf *dmabuf, struct iosys_map *map)
{
struct cma_heap_buffer *buffer = dmabuf->priv;
void *vaddr;
@@ -211,7 +211,7 @@ static int cma_heap_vmap(struct dma_buf *dmabuf, struct dma_buf_map *map)
mutex_lock(&buffer->lock);
if (buffer->vmap_cnt) {
buffer->vmap_cnt++;
- dma_buf_map_set_vaddr(map, buffer->vaddr);
+ iosys_map_set_vaddr(map, buffer->vaddr);
goto out;
}
@@ -222,14 +222,14 @@ static int cma_heap_vmap(struct dma_buf *dmabuf, struct dma_buf_map *map)
}
buffer->vaddr = vaddr;
buffer->vmap_cnt++;
- dma_buf_map_set_vaddr(map, buffer->vaddr);
+ iosys_map_set_vaddr(map, buffer->vaddr);
out:
mutex_unlock(&buffer->lock);
return ret;
}
-static void cma_heap_vunmap(struct dma_buf *dmabuf, struct dma_buf_map *map)
+static void cma_heap_vunmap(struct dma_buf *dmabuf, struct iosys_map *map)
{
struct cma_heap_buffer *buffer = dmabuf->priv;
@@ -239,7 +239,7 @@ static void cma_heap_vunmap(struct dma_buf *dmabuf, struct dma_buf_map *map)
buffer->vaddr = NULL;
}
mutex_unlock(&buffer->lock);
- dma_buf_map_clear(map);
+ iosys_map_clear(map);
}
static void cma_heap_dma_buf_release(struct dma_buf *dmabuf)
diff --git a/drivers/dma-buf/heaps/system_heap.c b/drivers/dma-buf/heaps/system_heap.c
index ab7fd896d2c4..fcf836ba9c1f 100644
--- a/drivers/dma-buf/heaps/system_heap.c
+++ b/drivers/dma-buf/heaps/system_heap.c
@@ -241,7 +241,7 @@ static void *system_heap_do_vmap(struct system_heap_buffer *buffer)
return vaddr;
}
-static int system_heap_vmap(struct dma_buf *dmabuf, struct dma_buf_map *map)
+static int system_heap_vmap(struct dma_buf *dmabuf, struct iosys_map *map)
{
struct system_heap_buffer *buffer = dmabuf->priv;
void *vaddr;
@@ -250,7 +250,7 @@ static int system_heap_vmap(struct dma_buf *dmabuf, struct dma_buf_map *map)
mutex_lock(&buffer->lock);
if (buffer->vmap_cnt) {
buffer->vmap_cnt++;
- dma_buf_map_set_vaddr(map, buffer->vaddr);
+ iosys_map_set_vaddr(map, buffer->vaddr);
goto out;
}
@@ -262,14 +262,14 @@ static int system_heap_vmap(struct dma_buf *dmabuf, struct dma_buf_map *map)
buffer->vaddr = vaddr;
buffer->vmap_cnt++;
- dma_buf_map_set_vaddr(map, buffer->vaddr);
+ iosys_map_set_vaddr(map, buffer->vaddr);
out:
mutex_unlock(&buffer->lock);
return ret;
}
-static void system_heap_vunmap(struct dma_buf *dmabuf, struct dma_buf_map *map)
+static void system_heap_vunmap(struct dma_buf *dmabuf, struct iosys_map *map)
{
struct system_heap_buffer *buffer = dmabuf->priv;
@@ -279,7 +279,7 @@ static void system_heap_vunmap(struct dma_buf *dmabuf, struct dma_buf_map *map)
buffer->vaddr = NULL;
}
mutex_unlock(&buffer->lock);
- dma_buf_map_clear(map);
+ iosys_map_clear(map);
}
static void system_heap_dma_buf_release(struct dma_buf *dmabuf)
diff --git a/drivers/dma-buf/st-dma-resv.c b/drivers/dma-buf/st-dma-resv.c
index bc32b3eedcb6..cbe999c6e7a6 100644
--- a/drivers/dma-buf/st-dma-resv.c
+++ b/drivers/dma-buf/st-dma-resv.c
@@ -275,7 +275,7 @@ static int test_shared_for_each_unlocked(void *arg)
static int test_get_fences(void *arg, bool shared)
{
- struct dma_fence *f, *excl = NULL, **fences = NULL;
+ struct dma_fence *f, **fences = NULL;
struct dma_resv resv;
int r, i;
@@ -304,35 +304,19 @@ static int test_get_fences(void *arg, bool shared)
}
dma_resv_unlock(&resv);
- r = dma_resv_get_fences(&resv, &excl, &i, &fences);
+ r = dma_resv_get_fences(&resv, shared, &i, &fences);
if (r) {
pr_err("get_fences failed\n");
goto err_free;
}
- if (shared) {
- if (excl != NULL) {
- pr_err("get_fences returned unexpected excl fence\n");
- goto err_free;
- }
- if (i != 1 || fences[0] != f) {
- pr_err("get_fences returned unexpected shared fence\n");
- goto err_free;
- }
- } else {
- if (excl != f) {
- pr_err("get_fences returned unexpected excl fence\n");
- goto err_free;
- }
- if (i != 0) {
- pr_err("get_fences returned unexpected shared fence\n");
- goto err_free;
- }
+ if (i != 1 || fences[0] != f) {
+ pr_err("get_fences returned unexpected fence\n");
+ goto err_free;
}
dma_fence_signal(f);
err_free:
- dma_fence_put(excl);
while (i--)
dma_fence_put(fences[i]);
kfree(fences);
diff --git a/drivers/dma-buf/udmabuf.c b/drivers/dma-buf/udmabuf.c
index c57a609db75b..e7330684d3b8 100644
--- a/drivers/dma-buf/udmabuf.c
+++ b/drivers/dma-buf/udmabuf.c
@@ -190,6 +190,10 @@ static long udmabuf_create(struct miscdevice *device,
if (ubuf->pagecount > pglimit)
goto err;
}
+
+ if (!ubuf->pagecount)
+ goto err;
+
ubuf->pages = kmalloc_array(ubuf->pagecount, sizeof(*ubuf->pages),
GFP_KERNEL);
if (!ubuf->pages) {
diff --git a/drivers/dma/at_xdmac.c b/drivers/dma/at_xdmac.c
index a1da2b4b6d73..1476156af74b 100644
--- a/drivers/dma/at_xdmac.c
+++ b/drivers/dma/at_xdmac.c
@@ -1681,8 +1681,10 @@ static void at_xdmac_tasklet(struct tasklet_struct *t)
__func__, atchan->irq_status);
if (!(atchan->irq_status & AT_XDMAC_CIS_LIS) &&
- !(atchan->irq_status & error_mask))
+ !(atchan->irq_status & error_mask)) {
+ spin_unlock_irq(&atchan->lock);
return;
+ }
if (atchan->irq_status & error_mask)
at_xdmac_handle_error(atchan);
diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c
index 110de8a60058..858400e42ec0 100644
--- a/drivers/dma/pl330.c
+++ b/drivers/dma/pl330.c
@@ -2968,7 +2968,7 @@ static int __maybe_unused pl330_suspend(struct device *dev)
struct amba_device *pcdev = to_amba_device(dev);
pm_runtime_force_suspend(dev);
- amba_pclk_unprepare(pcdev);
+ clk_unprepare(pcdev->pclk);
return 0;
}
@@ -2978,7 +2978,7 @@ static int __maybe_unused pl330_resume(struct device *dev)
struct amba_device *pcdev = to_amba_device(dev);
int ret;
- ret = amba_pclk_prepare(pcdev);
+ ret = clk_prepare(pcdev->pclk);
if (ret)
return ret;
diff --git a/drivers/dma/ptdma/ptdma-dev.c b/drivers/dma/ptdma/ptdma-dev.c
index 8a6bf291a73f..daafea5bc35d 100644
--- a/drivers/dma/ptdma/ptdma-dev.c
+++ b/drivers/dma/ptdma/ptdma-dev.c
@@ -207,7 +207,7 @@ int pt_core_init(struct pt_device *pt)
if (!cmd_q->qbase) {
dev_err(dev, "unable to allocate command queue\n");
ret = -ENOMEM;
- goto e_dma_alloc;
+ goto e_destroy_pool;
}
cmd_q->qidx = 0;
@@ -229,8 +229,10 @@ int pt_core_init(struct pt_device *pt)
/* Request an irq */
ret = request_irq(pt->pt_irq, pt_core_irq_handler, 0, dev_name(pt->dev), pt);
- if (ret)
- goto e_pool;
+ if (ret) {
+ dev_err(dev, "unable to allocate an IRQ\n");
+ goto e_free_dma;
+ }
/* Update the device registers with queue information. */
cmd_q->qcontrol &= ~CMD_Q_SIZE;
@@ -250,21 +252,20 @@ int pt_core_init(struct pt_device *pt)
/* Register the DMA engine support */
ret = pt_dmaengine_register(pt);
if (ret)
- goto e_dmaengine;
+ goto e_free_irq;
/* Set up debugfs entries */
ptdma_debugfs_setup(pt);
return 0;
-e_dmaengine:
+e_free_irq:
free_irq(pt->pt_irq, pt);
-e_dma_alloc:
+e_free_dma:
dma_free_coherent(dev, cmd_q->qsize, cmd_q->qbase, cmd_q->qbase_dma);
-e_pool:
- dev_err(dev, "unable to allocate an IRQ\n");
+e_destroy_pool:
dma_pool_destroy(pt->cmd_q.dma_pool);
return ret;
diff --git a/drivers/dma/sh/rcar-dmac.c b/drivers/dma/sh/rcar-dmac.c
index 481f45c77ce1..13d12d660cc2 100644
--- a/drivers/dma/sh/rcar-dmac.c
+++ b/drivers/dma/sh/rcar-dmac.c
@@ -1868,8 +1868,13 @@ static int rcar_dmac_probe(struct platform_device *pdev)
dmac->dev = &pdev->dev;
platform_set_drvdata(pdev, dmac);
- dma_set_max_seg_size(dmac->dev, RCAR_DMATCR_MASK);
- dma_set_mask_and_coherent(dmac->dev, DMA_BIT_MASK(40));
+ ret = dma_set_max_seg_size(dmac->dev, RCAR_DMATCR_MASK);
+ if (ret)
+ return ret;
+
+ ret = dma_set_mask_and_coherent(dmac->dev, DMA_BIT_MASK(40));
+ if (ret)
+ return ret;
ret = rcar_dmac_parse_of(&pdev->dev, dmac);
if (ret < 0)
diff --git a/drivers/dma/sh/shdma-base.c b/drivers/dma/sh/shdma-base.c
index 158e5e7defae..b26ed690f03c 100644
--- a/drivers/dma/sh/shdma-base.c
+++ b/drivers/dma/sh/shdma-base.c
@@ -115,8 +115,10 @@ static dma_cookie_t shdma_tx_submit(struct dma_async_tx_descriptor *tx)
ret = pm_runtime_get(schan->dev);
spin_unlock_irq(&schan->chan_lock);
- if (ret < 0)
+ if (ret < 0) {
dev_err(schan->dev, "%s(): GET = %d\n", __func__, ret);
+ pm_runtime_put(schan->dev);
+ }
pm_runtime_barrier(schan->dev);
diff --git a/drivers/dma/stm32-dmamux.c b/drivers/dma/stm32-dmamux.c
index a42164389ebc..d5d55732adba 100644
--- a/drivers/dma/stm32-dmamux.c
+++ b/drivers/dma/stm32-dmamux.c
@@ -292,10 +292,12 @@ static int stm32_dmamux_probe(struct platform_device *pdev)
ret = of_dma_router_register(node, stm32_dmamux_route_allocate,
&stm32_dmamux->dmarouter);
if (ret)
- goto err_clk;
+ goto pm_disable;
return 0;
+pm_disable:
+ pm_runtime_disable(&pdev->dev);
err_clk:
clk_disable_unprepare(stm32_dmamux->clk);
diff --git a/drivers/edac/altera_edac.c b/drivers/edac/altera_edac.c
index 3a6d2416cb0f..e7e8e624a436 100644
--- a/drivers/edac/altera_edac.c
+++ b/drivers/edac/altera_edac.c
@@ -350,7 +350,7 @@ static int altr_sdram_probe(struct platform_device *pdev)
if (irq < 0) {
edac_printk(KERN_ERR, EDAC_MC,
"No irq %d in DT\n", irq);
- return -ENODEV;
+ return irq;
}
/* Arria10 has a 2nd IRQ */
@@ -1083,8 +1083,46 @@ static int __init __maybe_unused altr_init_a10_ecc_device_type(char *compat)
#ifdef CONFIG_EDAC_ALTERA_SDRAM
+/*
+ * A legacy U-Boot bug only enabled memory mapped access to the ECC Enable
+ * register if ECC is enabled. Linux checks the ECC Enable register to
+ * determine ECC status.
+ * Use an SMC call (which always works) to determine ECC enablement.
+ */
+static int altr_s10_sdram_check_ecc_deps(struct altr_edac_device_dev *device)
+{
+ const struct edac_device_prv_data *prv = device->data;
+ unsigned long sdram_ecc_addr;
+ struct arm_smccc_res result;
+ struct device_node *np;
+ phys_addr_t sdram_addr;
+ u32 read_reg;
+ int ret;
+
+ np = of_find_compatible_node(NULL, NULL, "altr,sdr-ctl");
+ if (!np)
+ goto sdram_err;
+
+ sdram_addr = of_translate_address(np, of_get_address(np, 0,
+ NULL, NULL));
+ of_node_put(np);
+ sdram_ecc_addr = (unsigned long)sdram_addr + prv->ecc_en_ofst;
+ arm_smccc_smc(INTEL_SIP_SMC_REG_READ, sdram_ecc_addr,
+ 0, 0, 0, 0, 0, 0, &result);
+ read_reg = (unsigned int)result.a1;
+ ret = (int)result.a0;
+ if (!ret && (read_reg & prv->ecc_enable_mask))
+ return 0;
+
+sdram_err:
+ edac_printk(KERN_ERR, EDAC_DEVICE,
+ "%s: No ECC present or ECC disabled.\n",
+ device->edac_dev_name);
+ return -ENODEV;
+}
+
static const struct edac_device_prv_data s10_sdramecc_data = {
- .setup = altr_check_ecc_deps,
+ .setup = altr_s10_sdram_check_ecc_deps,
.ce_clear_mask = ALTR_S10_ECC_SERRPENA,
.ue_clear_mask = ALTR_S10_ECC_DERRPENA,
.ecc_enable_mask = ALTR_S10_ECC_EN,
diff --git a/drivers/edac/amd64_edac.c b/drivers/edac/amd64_edac.c
index fba609ada0e6..812baa48b290 100644
--- a/drivers/edac/amd64_edac.c
+++ b/drivers/edac/amd64_edac.c
@@ -15,6 +15,21 @@ static struct msr __percpu *msrs;
static struct amd64_family_type *fam_type;
+static inline u32 get_umc_reg(u32 reg)
+{
+ if (!fam_type->flags.zn_regs_v2)
+ return reg;
+
+ switch (reg) {
+ case UMCCH_ADDR_CFG: return UMCCH_ADDR_CFG_DDR5;
+ case UMCCH_ADDR_MASK_SEC: return UMCCH_ADDR_MASK_SEC_DDR5;
+ case UMCCH_DIMM_CFG: return UMCCH_DIMM_CFG_DDR5;
+ }
+
+ WARN_ONCE(1, "%s: unknown register 0x%x", __func__, reg);
+ return 0;
+}
+
/* Per-node stuff */
static struct ecc_settings **ecc_stngs;
@@ -1429,8 +1444,10 @@ static void __dump_misc_regs_df(struct amd64_pvt *pvt)
edac_dbg(1, "UMC%d x16 DIMMs present: %s\n",
i, (umc->dimm_cfg & BIT(7)) ? "yes" : "no");
- if (pvt->dram_type == MEM_LRDDR4) {
- amd_smn_read(pvt->mc_node_id, umc_base + UMCCH_ADDR_CFG, &tmp);
+ if (umc->dram_type == MEM_LRDDR4 || umc->dram_type == MEM_LRDDR5) {
+ amd_smn_read(pvt->mc_node_id,
+ umc_base + get_umc_reg(UMCCH_ADDR_CFG),
+ &tmp);
edac_dbg(1, "UMC%d LRDIMM %dx rank multiply\n",
i, 1 << ((tmp >> 4) & 0x3));
}
@@ -1505,7 +1522,7 @@ static void prep_chip_selects(struct amd64_pvt *pvt)
for_each_umc(umc) {
pvt->csels[umc].b_cnt = 4;
- pvt->csels[umc].m_cnt = 2;
+ pvt->csels[umc].m_cnt = fam_type->flags.zn_regs_v2 ? 4 : 2;
}
} else {
@@ -1545,7 +1562,7 @@ static void read_umc_base_mask(struct amd64_pvt *pvt)
}
umc_mask_reg = get_umc_base(umc) + UMCCH_ADDR_MASK;
- umc_mask_reg_sec = get_umc_base(umc) + UMCCH_ADDR_MASK_SEC;
+ umc_mask_reg_sec = get_umc_base(umc) + get_umc_reg(UMCCH_ADDR_MASK_SEC);
for_each_chip_select_mask(cs, umc, pvt) {
mask = &pvt->csels[umc].csmasks[cs];
@@ -1616,19 +1633,49 @@ static void read_dct_base_mask(struct amd64_pvt *pvt)
}
}
+static void determine_memory_type_df(struct amd64_pvt *pvt)
+{
+ struct amd64_umc *umc;
+ u32 i;
+
+ for_each_umc(i) {
+ umc = &pvt->umc[i];
+
+ if (!(umc->sdp_ctrl & UMC_SDP_INIT)) {
+ umc->dram_type = MEM_EMPTY;
+ continue;
+ }
+
+ /*
+ * Check if the system supports the "DDR Type" field in UMC Config
+ * and has DDR5 DIMMs in use.
+ */
+ if (fam_type->flags.zn_regs_v2 && ((umc->umc_cfg & GENMASK(2, 0)) == 0x1)) {
+ if (umc->dimm_cfg & BIT(5))
+ umc->dram_type = MEM_LRDDR5;
+ else if (umc->dimm_cfg & BIT(4))
+ umc->dram_type = MEM_RDDR5;
+ else
+ umc->dram_type = MEM_DDR5;
+ } else {
+ if (umc->dimm_cfg & BIT(5))
+ umc->dram_type = MEM_LRDDR4;
+ else if (umc->dimm_cfg & BIT(4))
+ umc->dram_type = MEM_RDDR4;
+ else
+ umc->dram_type = MEM_DDR4;
+ }
+
+ edac_dbg(1, " UMC%d DIMM type: %s\n", i, edac_mem_types[umc->dram_type]);
+ }
+}
+
static void determine_memory_type(struct amd64_pvt *pvt)
{
u32 dram_ctrl, dcsm;
- if (pvt->umc) {
- if ((pvt->umc[0].dimm_cfg | pvt->umc[1].dimm_cfg) & BIT(5))
- pvt->dram_type = MEM_LRDDR4;
- else if ((pvt->umc[0].dimm_cfg | pvt->umc[1].dimm_cfg) & BIT(4))
- pvt->dram_type = MEM_RDDR4;
- else
- pvt->dram_type = MEM_DDR4;
- return;
- }
+ if (pvt->umc)
+ return determine_memory_type_df(pvt);
switch (pvt->fam) {
case 0xf:
@@ -2149,6 +2196,7 @@ static int f17_addr_mask_to_cs_size(struct amd64_pvt *pvt, u8 umc,
{
u32 addr_mask_orig, addr_mask_deinterleaved;
u32 msb, weight, num_zero_bits;
+ int cs_mask_nr = csrow_nr;
int dimm, size = 0;
/* No Chip Selects are enabled. */
@@ -2164,17 +2212,33 @@ static int f17_addr_mask_to_cs_size(struct amd64_pvt *pvt, u8 umc,
return size;
/*
- * There is one mask per DIMM, and two Chip Selects per DIMM.
- * CS0 and CS1 -> DIMM0
- * CS2 and CS3 -> DIMM1
+ * Family 17h introduced systems with one mask per DIMM,
+ * and two Chip Selects per DIMM.
+ *
+ * CS0 and CS1 -> MASK0 / DIMM0
+ * CS2 and CS3 -> MASK1 / DIMM1
+ *
+ * Family 19h Model 10h introduced systems with one mask per Chip Select,
+ * and two Chip Selects per DIMM.
+ *
+ * CS0 -> MASK0 -> DIMM0
+ * CS1 -> MASK1 -> DIMM0
+ * CS2 -> MASK2 -> DIMM1
+ * CS3 -> MASK3 -> DIMM1
+ *
+ * Keep the mask number equal to the Chip Select number for newer systems,
+ * and shift the mask number for older systems.
*/
dimm = csrow_nr >> 1;
+ if (!fam_type->flags.zn_regs_v2)
+ cs_mask_nr >>= 1;
+
/* Asymmetric dual-rank DIMM support. */
if ((csrow_nr & 1) && (cs_mode & CS_ODD_SECONDARY))
- addr_mask_orig = pvt->csels[umc].csmasks_sec[dimm];
+ addr_mask_orig = pvt->csels[umc].csmasks_sec[cs_mask_nr];
else
- addr_mask_orig = pvt->csels[umc].csmasks[dimm];
+ addr_mask_orig = pvt->csels[umc].csmasks[cs_mask_nr];
/*
* The number of zero bits in the mask is equal to the number of bits
@@ -2930,6 +2994,7 @@ static struct amd64_family_type family_types[] = {
.f0_id = PCI_DEVICE_ID_AMD_19H_M10H_DF_F0,
.f6_id = PCI_DEVICE_ID_AMD_19H_M10H_DF_F6,
.max_mcs = 12,
+ .flags.zn_regs_v2 = 1,
.ops = {
.early_channel_count = f17_early_channel_count,
.dbam_to_cs = f17_addr_mask_to_cs_size,
@@ -3368,7 +3433,7 @@ static void __read_mc_regs_df(struct amd64_pvt *pvt)
umc_base = get_umc_base(i);
umc = &pvt->umc[i];
- amd_smn_read(nid, umc_base + UMCCH_DIMM_CFG, &umc->dimm_cfg);
+ amd_smn_read(nid, umc_base + get_umc_reg(UMCCH_DIMM_CFG), &umc->dimm_cfg);
amd_smn_read(nid, umc_base + UMCCH_UMC_CFG, &umc->umc_cfg);
amd_smn_read(nid, umc_base + UMCCH_SDP_CTRL, &umc->sdp_ctrl);
amd_smn_read(nid, umc_base + UMCCH_ECC_CTRL, &umc->ecc_ctrl);
@@ -3452,7 +3517,9 @@ skip:
read_dct_base_mask(pvt);
determine_memory_type(pvt);
- edac_dbg(1, " DIMM type: %s\n", edac_mem_types[pvt->dram_type]);
+
+ if (!pvt->umc)
+ edac_dbg(1, " DIMM type: %s\n", edac_mem_types[pvt->dram_type]);
determine_ecc_sym_sz(pvt);
}
@@ -3548,7 +3615,7 @@ static int init_csrows_df(struct mem_ctl_info *mci)
pvt->mc_node_id, cs);
dimm->nr_pages = get_csrow_nr_pages(pvt, umc, cs);
- dimm->mtype = pvt->dram_type;
+ dimm->mtype = pvt->umc[umc].dram_type;
dimm->edac_mode = edac_mode;
dimm->dtype = dev_type;
dimm->grain = 64;
diff --git a/drivers/edac/amd64_edac.h b/drivers/edac/amd64_edac.h
index 352bda9803f6..38e5ad95d010 100644
--- a/drivers/edac/amd64_edac.h
+++ b/drivers/edac/amd64_edac.h
@@ -273,8 +273,11 @@
#define UMCCH_BASE_ADDR_SEC 0x10
#define UMCCH_ADDR_MASK 0x20
#define UMCCH_ADDR_MASK_SEC 0x28
+#define UMCCH_ADDR_MASK_SEC_DDR5 0x30
#define UMCCH_ADDR_CFG 0x30
+#define UMCCH_ADDR_CFG_DDR5 0x40
#define UMCCH_DIMM_CFG 0x80
+#define UMCCH_DIMM_CFG_DDR5 0x90
#define UMCCH_UMC_CFG 0x100
#define UMCCH_SDP_CTRL 0x104
#define UMCCH_ECC_CTRL 0x14C
@@ -344,6 +347,9 @@ struct amd64_umc {
u32 sdp_ctrl; /* SDP Control reg */
u32 ecc_ctrl; /* DRAM ECC Control reg */
u32 umc_cap_hi; /* Capabilities High reg */
+
+ /* cache the dram_type */
+ enum mem_type dram_type;
};
struct amd64_pvt {
@@ -391,7 +397,12 @@ struct amd64_pvt {
/* place to store error injection parameters prior to issue */
struct error_injection injection;
- /* cache the dram_type */
+ /*
+ * cache the dram_type
+ *
+ * NOTE: Don't use this for Family 17h and later.
+ * Use dram_type in struct amd64_umc instead.
+ */
enum mem_type dram_type;
struct amd64_umc *umc; /* UMC registers */
@@ -480,11 +491,22 @@ struct low_ops {
unsigned cs_mode, int cs_mask_nr);
};
+struct amd64_family_flags {
+ /*
+ * Indicates that the system supports the new register offsets, etc.
+ * first introduced with Family 19h Model 10h.
+ */
+ __u64 zn_regs_v2 : 1,
+
+ __reserved : 63;
+};
+
struct amd64_family_type {
const char *ctl_name;
u16 f0_id, f1_id, f2_id, f6_id;
/* Maximum number of memory controllers per die/node. */
u8 max_mcs;
+ struct amd64_family_flags flags;
struct low_ops ops;
};
diff --git a/drivers/edac/edac_device_sysfs.c b/drivers/edac/edac_device_sysfs.c
index 5e7593753799..9a61d92bdf42 100644
--- a/drivers/edac/edac_device_sysfs.c
+++ b/drivers/edac/edac_device_sysfs.c
@@ -163,13 +163,14 @@ CTL_INFO_ATTR(poll_msec, S_IRUGO | S_IWUSR,
edac_device_ctl_poll_msec_show, edac_device_ctl_poll_msec_store);
/* Base Attributes of the EDAC_DEVICE ECC object */
-static struct ctl_info_attribute *device_ctrl_attr[] = {
- &attr_ctl_info_panic_on_ue,
- &attr_ctl_info_log_ue,
- &attr_ctl_info_log_ce,
- &attr_ctl_info_poll_msec,
+static struct attribute *device_ctrl_attrs[] = {
+ &attr_ctl_info_panic_on_ue.attr,
+ &attr_ctl_info_log_ue.attr,
+ &attr_ctl_info_log_ce.attr,
+ &attr_ctl_info_poll_msec.attr,
NULL,
};
+ATTRIBUTE_GROUPS(device_ctrl);
/*
* edac_device_ctrl_master_release
@@ -217,7 +218,7 @@ static void edac_device_ctrl_master_release(struct kobject *kobj)
static struct kobj_type ktype_device_ctrl = {
.release = edac_device_ctrl_master_release,
.sysfs_ops = &device_ctl_info_ops,
- .default_attrs = (struct attribute **)device_ctrl_attr,
+ .default_groups = device_ctrl_groups,
};
/*
@@ -389,17 +390,18 @@ INSTANCE_ATTR(ce_count, S_IRUGO, instance_ce_count_show, NULL);
INSTANCE_ATTR(ue_count, S_IRUGO, instance_ue_count_show, NULL);
/* list of edac_dev 'instance' attributes */
-static struct instance_attribute *device_instance_attr[] = {
- &attr_instance_ce_count,
- &attr_instance_ue_count,
+static struct attribute *device_instance_attrs[] = {
+ &attr_instance_ce_count.attr,
+ &attr_instance_ue_count.attr,
NULL,
};
+ATTRIBUTE_GROUPS(device_instance);
/* The 'ktype' for each edac_dev 'instance' */
static struct kobj_type ktype_instance_ctrl = {
.release = edac_device_ctrl_instance_release,
.sysfs_ops = &device_instance_ops,
- .default_attrs = (struct attribute **)device_instance_attr,
+ .default_groups = device_instance_groups,
};
/* edac_dev -> instance -> block information */
@@ -487,17 +489,18 @@ BLOCK_ATTR(ce_count, S_IRUGO, block_ce_count_show, NULL);
BLOCK_ATTR(ue_count, S_IRUGO, block_ue_count_show, NULL);
/* list of edac_dev 'block' attributes */
-static struct edac_dev_sysfs_block_attribute *device_block_attr[] = {
- &attr_block_ce_count,
- &attr_block_ue_count,
+static struct attribute *device_block_attrs[] = {
+ &attr_block_ce_count.attr,
+ &attr_block_ue_count.attr,
NULL,
};
+ATTRIBUTE_GROUPS(device_block);
/* The 'ktype' for each edac_dev 'block' */
static struct kobj_type ktype_block_ctrl = {
.release = edac_device_ctrl_block_release,
.sysfs_ops = &device_block_ops,
- .default_attrs = (struct attribute **)device_block_attr,
+ .default_groups = device_block_groups,
};
/* block ctor/dtor code */
diff --git a/drivers/edac/edac_mc.c b/drivers/edac/edac_mc.c
index 9d9aabdec96b..d2715774af6f 100644
--- a/drivers/edac/edac_mc.c
+++ b/drivers/edac/edac_mc.c
@@ -213,12 +213,12 @@ void *edac_align_ptr(void **p, unsigned int size, int n_elems)
else if (size > sizeof(char))
align = sizeof(short);
else
- return (char *)ptr;
+ return ptr;
- r = (unsigned long)p % align;
+ r = (unsigned long)ptr % align;
if (r == 0)
- return (char *)ptr;
+ return ptr;
*p += align - r;
diff --git a/drivers/edac/edac_pci_sysfs.c b/drivers/edac/edac_pci_sysfs.c
index 53042af7262e..888d5728ecef 100644
--- a/drivers/edac/edac_pci_sysfs.c
+++ b/drivers/edac/edac_pci_sysfs.c
@@ -135,17 +135,18 @@ INSTANCE_ATTR(pe_count, S_IRUGO, instance_pe_count_show, NULL);
INSTANCE_ATTR(npe_count, S_IRUGO, instance_npe_count_show, NULL);
/* pci instance attributes */
-static struct instance_attribute *pci_instance_attr[] = {
- &attr_instance_pe_count,
- &attr_instance_npe_count,
+static struct attribute *pci_instance_attrs[] = {
+ &attr_instance_pe_count.attr,
+ &attr_instance_npe_count.attr,
NULL
};
+ATTRIBUTE_GROUPS(pci_instance);
/* the ktype for a pci instance */
static struct kobj_type ktype_pci_instance = {
.release = edac_pci_instance_release,
.sysfs_ops = &pci_instance_ops,
- .default_attrs = (struct attribute **)pci_instance_attr,
+ .default_groups = pci_instance_groups,
};
/*
@@ -292,15 +293,16 @@ EDAC_PCI_ATTR(pci_parity_count, S_IRUGO, edac_pci_int_show, NULL);
EDAC_PCI_ATTR(pci_nonparity_count, S_IRUGO, edac_pci_int_show, NULL);
/* Base Attributes of the memory ECC object */
-static struct edac_pci_dev_attribute *edac_pci_attr[] = {
- &edac_pci_attr_check_pci_errors,
- &edac_pci_attr_edac_pci_log_pe,
- &edac_pci_attr_edac_pci_log_npe,
- &edac_pci_attr_edac_pci_panic_on_pe,
- &edac_pci_attr_pci_parity_count,
- &edac_pci_attr_pci_nonparity_count,
+static struct attribute *edac_pci_attrs[] = {
+ &edac_pci_attr_check_pci_errors.attr,
+ &edac_pci_attr_edac_pci_log_pe.attr,
+ &edac_pci_attr_edac_pci_log_npe.attr,
+ &edac_pci_attr_edac_pci_panic_on_pe.attr,
+ &edac_pci_attr_pci_parity_count.attr,
+ &edac_pci_attr_pci_nonparity_count.attr,
NULL,
};
+ATTRIBUTE_GROUPS(edac_pci);
/*
* edac_pci_release_main_kobj
@@ -327,7 +329,7 @@ static void edac_pci_release_main_kobj(struct kobject *kobj)
static struct kobj_type ktype_edac_pci_main_kobj = {
.release = edac_pci_release_main_kobj,
.sysfs_ops = &edac_pci_sysfs_ops,
- .default_attrs = (struct attribute **)edac_pci_attr,
+ .default_groups = edac_pci_groups,
};
/**
diff --git a/drivers/edac/xgene_edac.c b/drivers/edac/xgene_edac.c
index 2ccd1db5e98f..7197f9fa0245 100644
--- a/drivers/edac/xgene_edac.c
+++ b/drivers/edac/xgene_edac.c
@@ -1919,7 +1919,7 @@ static int xgene_edac_probe(struct platform_device *pdev)
irq = platform_get_irq_optional(pdev, i);
if (irq < 0) {
dev_err(&pdev->dev, "No IRQ resource\n");
- rc = -EINVAL;
+ rc = irq;
goto out_err;
}
rc = devm_request_irq(&pdev->dev, irq,
diff --git a/drivers/firmware/Kconfig b/drivers/firmware/Kconfig
index 75cb91055c17..e5cfb01353d8 100644
--- a/drivers/firmware/Kconfig
+++ b/drivers/firmware/Kconfig
@@ -40,6 +40,7 @@ config ARM_SCPI_POWER_DOMAIN
config ARM_SDE_INTERFACE
bool "ARM Software Delegated Exception Interface (SDEI)"
depends on ARM64
+ depends on ACPI_APEI_GHES
help
The Software Delegated Exception Interface (SDEI) is an ARM
standard for registering callbacks from the platform firmware
diff --git a/drivers/firmware/arm_scmi/Kconfig b/drivers/firmware/arm_scmi/Kconfig
index 3d7081e84853..7794bd41eaa0 100644
--- a/drivers/firmware/arm_scmi/Kconfig
+++ b/drivers/firmware/arm_scmi/Kconfig
@@ -54,6 +54,18 @@ config ARM_SCMI_TRANSPORT_MAILBOX
If you want the ARM SCMI PROTOCOL stack to include support for a
transport based on mailboxes, answer Y.
+config ARM_SCMI_TRANSPORT_OPTEE
+ bool "SCMI transport based on OP-TEE service"
+ depends on OPTEE=y || OPTEE=ARM_SCMI_PROTOCOL
+ select ARM_SCMI_HAVE_TRANSPORT
+ select ARM_SCMI_HAVE_SHMEM
+ default y
+ help
+ This enables the OP-TEE service based transport for SCMI.
+
+ If you want the ARM SCMI PROTOCOL stack to include support for a
+ transport based on OP-TEE SCMI service, answer Y.
+
config ARM_SCMI_TRANSPORT_SMC
bool "SCMI transport based on SMC"
depends on HAVE_ARM_SMCCC_DISCOVERY
@@ -66,6 +78,20 @@ config ARM_SCMI_TRANSPORT_SMC
If you want the ARM SCMI PROTOCOL stack to include support for a
transport based on SMC, answer Y.
+config ARM_SCMI_TRANSPORT_SMC_ATOMIC_ENABLE
+ bool "Enable atomic mode support for SCMI SMC transport"
+ depends on ARM_SCMI_TRANSPORT_SMC
+ help
+ Enable support of atomic operation for SCMI SMC based transport.
+
+ If you want the SCMI SMC based transport to operate in atomic
+ mode, avoiding any kind of sleeping behaviour for selected
+ transactions on the TX path, answer Y.
+ Enabling atomic mode operations allows any SCMI driver using this
+ transport to optionally ask for atomic SCMI transactions and operate
+ in atomic context too, at the price of using a number of busy-waiting
+ primitives all over instead. If unsure say N.
+
config ARM_SCMI_TRANSPORT_VIRTIO
bool "SCMI transport based on VirtIO"
depends on VIRTIO=y || VIRTIO=ARM_SCMI_PROTOCOL
@@ -77,6 +103,36 @@ config ARM_SCMI_TRANSPORT_VIRTIO
If you want the ARM SCMI PROTOCOL stack to include support for a
transport based on VirtIO, answer Y.
+config ARM_SCMI_TRANSPORT_VIRTIO_VERSION1_COMPLIANCE
+ bool "SCMI VirtIO transport Version 1 compliance"
+ depends on ARM_SCMI_TRANSPORT_VIRTIO
+ default y
+ help
+ This enforces strict compliance with VirtIO Version 1 specification.
+
+ If you want the ARM SCMI VirtIO transport layer to refuse to work
+ with Legacy VirtIO backends and instead support only VirtIO Version 1
+ devices (or above), answer Y.
+
+ If you want instead to support also old Legacy VirtIO backends (like
+ the ones implemented by kvmtool) and let the core Kernel VirtIO layer
+ take care of the needed conversions, say N.
+
+config ARM_SCMI_TRANSPORT_VIRTIO_ATOMIC_ENABLE
+ bool "Enable atomic mode for SCMI VirtIO transport"
+ depends on ARM_SCMI_TRANSPORT_VIRTIO
+ help
+ Enable support of atomic operation for SCMI VirtIO based transport.
+
+ If you want the SCMI VirtIO based transport to operate in atomic
+ mode, avoiding any kind of sleeping behaviour for selected
+ transactions on the TX path, answer Y.
+
+ Enabling atomic mode operations allows any SCMI driver using this
+ transport to optionally ask for atomic SCMI transactions and operate
+ in atomic context too, at the price of using a number of busy-waiting
+ primitives all over instead. If unsure say N.
+
endif #ARM_SCMI_PROTOCOL
config ARM_SCMI_POWER_DOMAIN
diff --git a/drivers/firmware/arm_scmi/Makefile b/drivers/firmware/arm_scmi/Makefile
index 1dcf123d64ab..8d4afadda38c 100644
--- a/drivers/firmware/arm_scmi/Makefile
+++ b/drivers/firmware/arm_scmi/Makefile
@@ -6,8 +6,16 @@ scmi-transport-$(CONFIG_ARM_SCMI_TRANSPORT_MAILBOX) += mailbox.o
scmi-transport-$(CONFIG_ARM_SCMI_TRANSPORT_SMC) += smc.o
scmi-transport-$(CONFIG_ARM_SCMI_HAVE_MSG) += msg.o
scmi-transport-$(CONFIG_ARM_SCMI_TRANSPORT_VIRTIO) += virtio.o
+scmi-transport-$(CONFIG_ARM_SCMI_TRANSPORT_OPTEE) += optee.o
scmi-protocols-y = base.o clock.o perf.o power.o reset.o sensors.o system.o voltage.o
scmi-module-objs := $(scmi-bus-y) $(scmi-driver-y) $(scmi-protocols-y) \
$(scmi-transport-y)
obj-$(CONFIG_ARM_SCMI_PROTOCOL) += scmi-module.o
obj-$(CONFIG_ARM_SCMI_POWER_DOMAIN) += scmi_pm_domain.o
+
+ifeq ($(CONFIG_THUMB2_KERNEL)$(CONFIG_CC_IS_CLANG),yy)
+# The use of R7 in the SMCCC conflicts with the compiler's use of R7 as a frame
+# pointer in Thumb2 mode, which is forcibly enabled by Clang when profiling
+# hooks are inserted via the -pg switch.
+CFLAGS_REMOVE_smc.o += $(CC_FLAGS_FTRACE)
+endif
diff --git a/drivers/firmware/arm_scmi/clock.c b/drivers/firmware/arm_scmi/clock.c
index 35b56c8ba0c0..cf6fed6dec77 100644
--- a/drivers/firmware/arm_scmi/clock.c
+++ b/drivers/firmware/arm_scmi/clock.c
@@ -27,7 +27,8 @@ struct scmi_msg_resp_clock_protocol_attributes {
struct scmi_msg_resp_clock_attributes {
__le32 attributes;
#define CLOCK_ENABLE BIT(0)
- u8 name[SCMI_MAX_STR_SIZE];
+ u8 name[SCMI_MAX_STR_SIZE];
+ __le32 clock_enable_latency;
};
struct scmi_clock_set_config {
@@ -116,10 +117,15 @@ static int scmi_clock_attributes_get(const struct scmi_protocol_handle *ph,
attr = t->rx.buf;
ret = ph->xops->do_xfer(ph, t);
- if (!ret)
+ if (!ret) {
strlcpy(clk->name, attr->name, SCMI_MAX_STR_SIZE);
- else
+ /* Is optional field clock_enable_latency provided ? */
+ if (t->rx.len == sizeof(*attr))
+ clk->enable_latency =
+ le32_to_cpu(attr->clock_enable_latency);
+ } else {
clk->name[0] = '\0';
+ }
ph->xops->xfer_put(ph, t);
return ret;
@@ -273,7 +279,7 @@ static int scmi_clock_rate_set(const struct scmi_protocol_handle *ph,
static int
scmi_clock_config_set(const struct scmi_protocol_handle *ph, u32 clk_id,
- u32 config)
+ u32 config, bool atomic)
{
int ret;
struct scmi_xfer *t;
@@ -284,6 +290,8 @@ scmi_clock_config_set(const struct scmi_protocol_handle *ph, u32 clk_id,
if (ret)
return ret;
+ t->hdr.poll_completion = atomic;
+
cfg = t->tx.buf;
cfg->id = cpu_to_le32(clk_id);
cfg->attributes = cpu_to_le32(config);
@@ -296,12 +304,24 @@ scmi_clock_config_set(const struct scmi_protocol_handle *ph, u32 clk_id,
static int scmi_clock_enable(const struct scmi_protocol_handle *ph, u32 clk_id)
{
- return scmi_clock_config_set(ph, clk_id, CLOCK_ENABLE);
+ return scmi_clock_config_set(ph, clk_id, CLOCK_ENABLE, false);
}
static int scmi_clock_disable(const struct scmi_protocol_handle *ph, u32 clk_id)
{
- return scmi_clock_config_set(ph, clk_id, 0);
+ return scmi_clock_config_set(ph, clk_id, 0, false);
+}
+
+static int scmi_clock_enable_atomic(const struct scmi_protocol_handle *ph,
+ u32 clk_id)
+{
+ return scmi_clock_config_set(ph, clk_id, CLOCK_ENABLE, true);
+}
+
+static int scmi_clock_disable_atomic(const struct scmi_protocol_handle *ph,
+ u32 clk_id)
+{
+ return scmi_clock_config_set(ph, clk_id, 0, true);
}
static int scmi_clock_count_get(const struct scmi_protocol_handle *ph)
@@ -330,6 +350,8 @@ static const struct scmi_clk_proto_ops clk_proto_ops = {
.rate_set = scmi_clock_rate_set,
.enable = scmi_clock_enable,
.disable = scmi_clock_disable,
+ .enable_atomic = scmi_clock_enable_atomic,
+ .disable_atomic = scmi_clock_disable_atomic,
};
static int scmi_clock_protocol_init(const struct scmi_protocol_handle *ph)
diff --git a/drivers/firmware/arm_scmi/common.h b/drivers/firmware/arm_scmi/common.h
index dea1bfbe1052..4fda84bfab42 100644
--- a/drivers/firmware/arm_scmi/common.h
+++ b/drivers/firmware/arm_scmi/common.h
@@ -339,11 +339,16 @@ void scmi_protocol_release(const struct scmi_handle *handle, u8 protocol_id);
* @dev: Reference to device in the SCMI hierarchy corresponding to this
* channel
* @handle: Pointer to SCMI entity handle
+ * @no_completion_irq: Flag to indicate that this channel has no completion
+ * interrupt mechanism for synchronous commands.
+ * This can be dynamically set by transports at run-time
+ * inside their provided .chan_setup().
* @transport_info: Transport layer related information
*/
struct scmi_chan_info {
struct device *dev;
struct scmi_handle *handle;
+ bool no_completion_irq;
void *transport_info;
};
@@ -373,7 +378,8 @@ struct scmi_transport_ops {
unsigned int (*get_max_msg)(struct scmi_chan_info *base_cinfo);
int (*send_message)(struct scmi_chan_info *cinfo,
struct scmi_xfer *xfer);
- void (*mark_txdone)(struct scmi_chan_info *cinfo, int ret);
+ void (*mark_txdone)(struct scmi_chan_info *cinfo, int ret,
+ struct scmi_xfer *xfer);
void (*fetch_response)(struct scmi_chan_info *cinfo,
struct scmi_xfer *xfer);
void (*fetch_notification)(struct scmi_chan_info *cinfo,
@@ -402,6 +408,18 @@ struct scmi_device *scmi_child_dev_find(struct device *parent,
* be pending simultaneously in the system. May be overridden by the
* get_max_msg op.
* @max_msg_size: Maximum size of data per message that can be handled.
+ * @force_polling: Flag to force this whole transport to use SCMI core polling
+ * mechanism instead of completion interrupts even if available.
+ * @sync_cmds_completed_on_ret: Flag to indicate that the transport assures
+ * synchronous-command messages are atomically
+ * completed on .send_message: no need to poll
+ * actively waiting for a response.
+ * Used by core internally only when polling is
+ * selected as a waiting for reply method: i.e.
+ * if a completion irq was found use that anyway.
+ * @atomic_enabled: Flag to indicate that this transport, which is assured not
+ * to sleep anywhere on the TX path, can be used in atomic mode
+ * when requested.
*/
struct scmi_desc {
int (*transport_init)(void);
@@ -410,6 +428,9 @@ struct scmi_desc {
int max_rx_timeout_ms;
int max_msg;
int max_msg_size;
+ const bool force_polling;
+ const bool sync_cmds_completed_on_ret;
+ const bool atomic_enabled;
};
#ifdef CONFIG_ARM_SCMI_TRANSPORT_MAILBOX
@@ -421,6 +442,9 @@ extern const struct scmi_desc scmi_smc_desc;
#ifdef CONFIG_ARM_SCMI_TRANSPORT_VIRTIO
extern const struct scmi_desc scmi_virtio_desc;
#endif
+#ifdef CONFIG_ARM_SCMI_TRANSPORT_OPTEE
+extern const struct scmi_desc scmi_optee_desc;
+#endif
void scmi_rx_callback(struct scmi_chan_info *cinfo, u32 msg_hdr, void *priv);
void scmi_free_channel(struct scmi_chan_info *cinfo, struct idr *idr, int id);
diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c
index b406b3f78f46..46118300a4d1 100644
--- a/drivers/firmware/arm_scmi/driver.c
+++ b/drivers/firmware/arm_scmi/driver.c
@@ -131,6 +131,12 @@ struct scmi_protocol_instance {
* MAX_PROTOCOLS_IMP elements allocated by the base protocol
* @active_protocols: IDR storing device_nodes for protocols actually defined
* in the DT and confirmed as implemented by fw.
+ * @atomic_threshold: Optional system wide DT-configured threshold, expressed
+ * in microseconds, for atomic operations.
+ * Only SCMI synchronous commands reported by the platform
+ * to have an execution latency lesser-equal to the threshold
+ * should be considered for atomic mode operation: such
+ * decision is finally left up to the SCMI drivers.
* @notify_priv: Pointer to private data structure specific to notifications.
* @node: List head
* @users: Number of users of this instance
@@ -149,6 +155,7 @@ struct scmi_info {
struct mutex protocols_mtx;
u8 *protocols_imp;
struct idr active_protocols;
+ unsigned int atomic_threshold;
void *notify_priv;
struct list_head node;
int users;
@@ -609,6 +616,25 @@ static inline void scmi_clear_channel(struct scmi_info *info,
info->desc->ops->clear_channel(cinfo);
}
+static inline bool is_polling_required(struct scmi_chan_info *cinfo,
+ struct scmi_info *info)
+{
+ return cinfo->no_completion_irq || info->desc->force_polling;
+}
+
+static inline bool is_transport_polling_capable(struct scmi_info *info)
+{
+ return info->desc->ops->poll_done ||
+ info->desc->sync_cmds_completed_on_ret;
+}
+
+static inline bool is_polling_enabled(struct scmi_chan_info *cinfo,
+ struct scmi_info *info)
+{
+ return is_polling_required(cinfo, info) &&
+ is_transport_polling_capable(info);
+}
+
static void scmi_handle_notification(struct scmi_chan_info *cinfo,
u32 msg_hdr, void *priv)
{
@@ -629,7 +655,8 @@ static void scmi_handle_notification(struct scmi_chan_info *cinfo,
unpack_scmi_header(msg_hdr, &xfer->hdr);
if (priv)
- xfer->priv = priv;
+ /* Ensure order between xfer->priv store and following ops */
+ smp_store_mb(xfer->priv, priv);
info->desc->ops->fetch_notification(cinfo, info->desc->max_msg_size,
xfer);
scmi_notify(cinfo->handle, xfer->hdr.protocol_id,
@@ -661,7 +688,8 @@ static void scmi_handle_response(struct scmi_chan_info *cinfo,
xfer->rx.len = info->desc->max_msg_size;
if (priv)
- xfer->priv = priv;
+ /* Ensure order between xfer->priv store and following ops */
+ smp_store_mb(xfer->priv, priv);
info->desc->ops->fetch_response(cinfo, xfer);
trace_scmi_rx_done(xfer->transfer_id, xfer->hdr.id,
@@ -724,8 +752,6 @@ static void xfer_put(const struct scmi_protocol_handle *ph,
__scmi_xfer_put(&info->tx_minfo, xfer);
}
-#define SCMI_MAX_POLL_TO_NS (100 * NSEC_PER_USEC)
-
static bool scmi_xfer_done_no_timeout(struct scmi_chan_info *cinfo,
struct scmi_xfer *xfer, ktime_t stop)
{
@@ -741,6 +767,79 @@ static bool scmi_xfer_done_no_timeout(struct scmi_chan_info *cinfo,
}
/**
+ * scmi_wait_for_message_response - An helper to group all the possible ways of
+ * waiting for a synchronous message response.
+ *
+ * @cinfo: SCMI channel info
+ * @xfer: Reference to the transfer being waited for.
+ *
+ * Chooses waiting strategy (sleep-waiting vs busy-waiting) depending on
+ * configuration flags like xfer->hdr.poll_completion.
+ *
+ * Return: 0 on Success, error otherwise.
+ */
+static int scmi_wait_for_message_response(struct scmi_chan_info *cinfo,
+ struct scmi_xfer *xfer)
+{
+ struct scmi_info *info = handle_to_scmi_info(cinfo->handle);
+ struct device *dev = info->dev;
+ int ret = 0, timeout_ms = info->desc->max_rx_timeout_ms;
+
+ trace_scmi_xfer_response_wait(xfer->transfer_id, xfer->hdr.id,
+ xfer->hdr.protocol_id, xfer->hdr.seq,
+ timeout_ms,
+ xfer->hdr.poll_completion);
+
+ if (xfer->hdr.poll_completion) {
+ /*
+ * Real polling is needed only if transport has NOT declared
+ * itself to support synchronous commands replies.
+ */
+ if (!info->desc->sync_cmds_completed_on_ret) {
+ /*
+ * Poll on xfer using transport provided .poll_done();
+ * assumes no completion interrupt was available.
+ */
+ ktime_t stop = ktime_add_ms(ktime_get(), timeout_ms);
+
+ spin_until_cond(scmi_xfer_done_no_timeout(cinfo,
+ xfer, stop));
+ if (ktime_after(ktime_get(), stop)) {
+ dev_err(dev,
+ "timed out in resp(caller: %pS) - polling\n",
+ (void *)_RET_IP_);
+ ret = -ETIMEDOUT;
+ }
+ }
+
+ if (!ret) {
+ unsigned long flags;
+
+ /*
+ * Do not fetch_response if an out-of-order delayed
+ * response is being processed.
+ */
+ spin_lock_irqsave(&xfer->lock, flags);
+ if (xfer->state == SCMI_XFER_SENT_OK) {
+ info->desc->ops->fetch_response(cinfo, xfer);
+ xfer->state = SCMI_XFER_RESP_OK;
+ }
+ spin_unlock_irqrestore(&xfer->lock, flags);
+ }
+ } else {
+ /* And we wait for the response. */
+ if (!wait_for_completion_timeout(&xfer->done,
+ msecs_to_jiffies(timeout_ms))) {
+ dev_err(dev, "timed out in resp(caller: %pS)\n",
+ (void *)_RET_IP_);
+ ret = -ETIMEDOUT;
+ }
+ }
+
+ return ret;
+}
+
+/**
* do_xfer() - Do one transfer
*
* @ph: Pointer to SCMI protocol handle
@@ -754,18 +853,26 @@ static int do_xfer(const struct scmi_protocol_handle *ph,
struct scmi_xfer *xfer)
{
int ret;
- int timeout;
const struct scmi_protocol_instance *pi = ph_to_pi(ph);
struct scmi_info *info = handle_to_scmi_info(pi->handle);
struct device *dev = info->dev;
struct scmi_chan_info *cinfo;
- if (xfer->hdr.poll_completion && !info->desc->ops->poll_done) {
+ /* Check for polling request on custom command xfers at first */
+ if (xfer->hdr.poll_completion && !is_transport_polling_capable(info)) {
dev_warn_once(dev,
"Polling mode is not supported by transport.\n");
return -EINVAL;
}
+ cinfo = idr_find(&info->tx_idr, pi->proto->id);
+ if (unlikely(!cinfo))
+ return -EINVAL;
+
+ /* True ONLY if also supported by transport. */
+ if (is_polling_enabled(cinfo, info))
+ xfer->hdr.poll_completion = true;
+
/*
* Initialise protocol id now from protocol handle to avoid it being
* overridden by mistake (or malice) by the protocol code mangling with
@@ -774,10 +881,6 @@ static int do_xfer(const struct scmi_protocol_handle *ph,
xfer->hdr.protocol_id = pi->proto->id;
reinit_completion(&xfer->done);
- cinfo = idr_find(&info->tx_idr, xfer->hdr.protocol_id);
- if (unlikely(!cinfo))
- return -EINVAL;
-
trace_scmi_xfer_begin(xfer->transfer_id, xfer->hdr.id,
xfer->hdr.protocol_id, xfer->hdr.seq,
xfer->hdr.poll_completion);
@@ -798,41 +901,12 @@ static int do_xfer(const struct scmi_protocol_handle *ph,
return ret;
}
- if (xfer->hdr.poll_completion) {
- ktime_t stop = ktime_add_ns(ktime_get(), SCMI_MAX_POLL_TO_NS);
-
- spin_until_cond(scmi_xfer_done_no_timeout(cinfo, xfer, stop));
- if (ktime_before(ktime_get(), stop)) {
- unsigned long flags;
-
- /*
- * Do not fetch_response if an out-of-order delayed
- * response is being processed.
- */
- spin_lock_irqsave(&xfer->lock, flags);
- if (xfer->state == SCMI_XFER_SENT_OK) {
- info->desc->ops->fetch_response(cinfo, xfer);
- xfer->state = SCMI_XFER_RESP_OK;
- }
- spin_unlock_irqrestore(&xfer->lock, flags);
- } else {
- ret = -ETIMEDOUT;
- }
- } else {
- /* And we wait for the response. */
- timeout = msecs_to_jiffies(info->desc->max_rx_timeout_ms);
- if (!wait_for_completion_timeout(&xfer->done, timeout)) {
- dev_err(dev, "timed out in resp(caller: %pS)\n",
- (void *)_RET_IP_);
- ret = -ETIMEDOUT;
- }
- }
-
+ ret = scmi_wait_for_message_response(cinfo, xfer);
if (!ret && xfer->hdr.status)
ret = scmi_to_linux_errno(xfer->hdr.status);
if (info->desc->ops->mark_txdone)
- info->desc->ops->mark_txdone(cinfo, ret);
+ info->desc->ops->mark_txdone(cinfo, ret, xfer);
trace_scmi_xfer_end(xfer->transfer_id, xfer->hdr.id,
xfer->hdr.protocol_id, xfer->hdr.seq, ret);
@@ -858,6 +932,20 @@ static void reset_rx_to_maxsz(const struct scmi_protocol_handle *ph,
* @ph: Pointer to SCMI protocol handle
* @xfer: Transfer to initiate and wait for response
*
+ * Using asynchronous commands in atomic/polling mode should be avoided since
+ * it could cause long busy-waiting here, so ignore polling for the delayed
+ * response and WARN if it was requested for this command transaction since
+ * upper layers should refrain from issuing such kind of requests.
+ *
+ * The only other option would have been to refrain from using any asynchronous
+ * command even if made available, when an atomic transport is detected, and
+ * instead forcibly use the synchronous version (thing that can be easily
+ * attained at the protocol layer), but this would also have led to longer
+ * stalls of the channel for synchronous commands and possibly timeouts.
+ * (in other words there is usually a good reason if a platform provides an
+ * asynchronous version of a command and we should prefer to use it...just not
+ * when using atomic/polling mode)
+ *
* Return: -ETIMEDOUT in case of no delayed response, if transmit error,
* return corresponding error, else if all goes well, return 0.
*/
@@ -869,12 +957,24 @@ static int do_xfer_with_response(const struct scmi_protocol_handle *ph,
xfer->async_done = &async_response;
+ /*
+ * Delayed responses should not be polled, so an async command should
+ * not have been used when requiring an atomic/poll context; WARN and
+ * perform instead a sleeping wait.
+ * (Note Async + IgnoreDelayedResponses are sent via do_xfer)
+ */
+ WARN_ON_ONCE(xfer->hdr.poll_completion);
+
ret = do_xfer(ph, xfer);
if (!ret) {
- if (!wait_for_completion_timeout(xfer->async_done, timeout))
+ if (!wait_for_completion_timeout(xfer->async_done, timeout)) {
+ dev_err(ph->dev,
+ "timed out in delayed resp(caller: %pS)\n",
+ (void *)_RET_IP_);
ret = -ETIMEDOUT;
- else if (xfer->hdr.status)
+ } else if (xfer->hdr.status) {
ret = scmi_to_linux_errno(xfer->hdr.status);
+ }
}
xfer->async_done = NULL;
@@ -1308,6 +1408,29 @@ static void scmi_devm_protocol_put(struct scmi_device *sdev, u8 protocol_id)
WARN_ON(ret);
}
+/**
+ * scmi_is_transport_atomic - Method to check if underlying transport for an
+ * SCMI instance is configured as atomic.
+ *
+ * @handle: A reference to the SCMI platform instance.
+ * @atomic_threshold: An optional return value for the system wide currently
+ * configured threshold for atomic operations.
+ *
+ * Return: True if transport is configured as atomic
+ */
+static bool scmi_is_transport_atomic(const struct scmi_handle *handle,
+ unsigned int *atomic_threshold)
+{
+ bool ret;
+ struct scmi_info *info = handle_to_scmi_info(handle);
+
+ ret = info->desc->atomic_enabled && is_transport_polling_capable(info);
+ if (ret && atomic_threshold)
+ *atomic_threshold = info->atomic_threshold;
+
+ return ret;
+}
+
static inline
struct scmi_handle *scmi_handle_get_from_info_unlocked(struct scmi_info *info)
{
@@ -1499,6 +1622,16 @@ static int scmi_chan_setup(struct scmi_info *info, struct device *dev,
if (ret)
return ret;
+ if (tx && is_polling_required(cinfo, info)) {
+ if (is_transport_polling_capable(info))
+ dev_info(dev,
+ "Enabled polling mode TX channel - prot_id:%d\n",
+ prot_id);
+ else
+ dev_warn(dev,
+ "Polling mode NOT supported by transport.\n");
+ }
+
idr_alloc:
ret = idr_alloc(idr, cinfo, prot_id, prot_id + 1, GFP_KERNEL);
if (ret != prot_id) {
@@ -1836,6 +1969,14 @@ static int scmi_probe(struct platform_device *pdev)
handle->devm_protocol_get = scmi_devm_protocol_get;
handle->devm_protocol_put = scmi_devm_protocol_put;
+ /* System wide atomic threshold for atomic ops .. if any */
+ if (!of_property_read_u32(np, "atomic-threshold-us",
+ &info->atomic_threshold))
+ dev_info(dev,
+ "SCMI System wide atomic threshold set to %d us\n",
+ info->atomic_threshold);
+ handle->is_transport_atomic = scmi_is_transport_atomic;
+
if (desc->ops->link_supplier) {
ret = desc->ops->link_supplier(dev);
if (ret)
@@ -1853,6 +1994,10 @@ static int scmi_probe(struct platform_device *pdev)
if (scmi_notification_init(handle))
dev_err(dev, "SCMI Notifications NOT available.\n");
+ if (info->desc->atomic_enabled && !is_transport_polling_capable(info))
+ dev_err(dev,
+ "Transport is not polling capable. Atomic mode not supported.\n");
+
/*
* Trigger SCMI Base protocol initialization.
* It's mandatory and won't be ever released/deinit until the
@@ -1994,6 +2139,9 @@ static const struct of_device_id scmi_of_match[] = {
#ifdef CONFIG_ARM_SCMI_TRANSPORT_MAILBOX
{ .compatible = "arm,scmi", .data = &scmi_mailbox_desc },
#endif
+#ifdef CONFIG_ARM_SCMI_TRANSPORT_OPTEE
+ { .compatible = "linaro,scmi-optee", .data = &scmi_optee_desc },
+#endif
#ifdef CONFIG_ARM_SCMI_TRANSPORT_SMC
{ .compatible = "arm,scmi-smc", .data = &scmi_smc_desc},
#endif
@@ -2112,7 +2260,7 @@ static void __exit scmi_driver_exit(void)
}
module_exit(scmi_driver_exit);
-MODULE_ALIAS("platform: arm-scmi");
+MODULE_ALIAS("platform:arm-scmi");
MODULE_AUTHOR("Sudeep Holla <sudeep.holla@arm.com>");
MODULE_DESCRIPTION("ARM SCMI protocol driver");
MODULE_LICENSE("GPL v2");
diff --git a/drivers/firmware/arm_scmi/mailbox.c b/drivers/firmware/arm_scmi/mailbox.c
index e09eb12bf421..08ff4d110beb 100644
--- a/drivers/firmware/arm_scmi/mailbox.c
+++ b/drivers/firmware/arm_scmi/mailbox.c
@@ -140,7 +140,8 @@ static int mailbox_send_message(struct scmi_chan_info *cinfo,
return ret;
}
-static void mailbox_mark_txdone(struct scmi_chan_info *cinfo, int ret)
+static void mailbox_mark_txdone(struct scmi_chan_info *cinfo, int ret,
+ struct scmi_xfer *__unused)
{
struct scmi_mailbox *smbox = cinfo->transport_info;
diff --git a/drivers/firmware/arm_scmi/optee.c b/drivers/firmware/arm_scmi/optee.c
new file mode 100644
index 000000000000..734f1eeee161
--- /dev/null
+++ b/drivers/firmware/arm_scmi/optee.c
@@ -0,0 +1,567 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2019-2021 Linaro Ltd.
+ */
+
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/slab.h>
+#include <linux/tee_drv.h>
+#include <linux/uuid.h>
+#include <uapi/linux/tee.h>
+
+#include "common.h"
+
+#define SCMI_OPTEE_MAX_MSG_SIZE 128
+
+enum scmi_optee_pta_cmd {
+ /*
+ * PTA_SCMI_CMD_CAPABILITIES - Get channel capabilities
+ *
+ * [out] value[0].a: Capability bit mask (enum pta_scmi_caps)
+ * [out] value[0].b: Extended capabilities or 0
+ */
+ PTA_SCMI_CMD_CAPABILITIES = 0,
+
+ /*
+ * PTA_SCMI_CMD_PROCESS_SMT_CHANNEL - Process SCMI message in SMT buffer
+ *
+ * [in] value[0].a: Channel handle
+ *
+ * Shared memory used for SCMI message/response exhange is expected
+ * already identified and bound to channel handle in both SCMI agent
+ * and SCMI server (OP-TEE) parts.
+ * The memory uses SMT header to carry SCMI meta-data (protocol ID and
+ * protocol message ID).
+ */
+ PTA_SCMI_CMD_PROCESS_SMT_CHANNEL = 1,
+
+ /*
+ * PTA_SCMI_CMD_PROCESS_SMT_CHANNEL_MESSAGE - Process SMT/SCMI message
+ *
+ * [in] value[0].a: Channel handle
+ * [in/out] memref[1]: Message/response buffer (SMT and SCMI payload)
+ *
+ * Shared memory used for SCMI message/response is a SMT buffer
+ * referenced by param[1]. It shall be 128 bytes large to fit response
+ * payload whatever message playload size.
+ * The memory uses SMT header to carry SCMI meta-data (protocol ID and
+ * protocol message ID).
+ */
+ PTA_SCMI_CMD_PROCESS_SMT_CHANNEL_MESSAGE = 2,
+
+ /*
+ * PTA_SCMI_CMD_GET_CHANNEL - Get channel handle
+ *
+ * SCMI shm information are 0 if agent expects to use OP-TEE regular SHM
+ *
+ * [in] value[0].a: Channel identifier
+ * [out] value[0].a: Returned channel handle
+ * [in] value[0].b: Requested capabilities mask (enum pta_scmi_caps)
+ */
+ PTA_SCMI_CMD_GET_CHANNEL = 3,
+};
+
+/*
+ * OP-TEE SCMI service capabilities bit flags (32bit)
+ *
+ * PTA_SCMI_CAPS_SMT_HEADER
+ * When set, OP-TEE supports command using SMT header protocol (SCMI shmem) in
+ * shared memory buffers to carry SCMI protocol synchronisation information.
+ */
+#define PTA_SCMI_CAPS_NONE 0
+#define PTA_SCMI_CAPS_SMT_HEADER BIT(0)
+
+/**
+ * struct scmi_optee_channel - Description of an OP-TEE SCMI channel
+ *
+ * @channel_id: OP-TEE channel ID used for this transport
+ * @tee_session: TEE session identifier
+ * @caps: OP-TEE SCMI channel capabilities
+ * @mu: Mutex protection on channel access
+ * @cinfo: SCMI channel information
+ * @shmem: Virtual base address of the shared memory
+ * @tee_shm: Reference to TEE shared memory or NULL if using static shmem
+ * @link: Reference in agent's channel list
+ */
+struct scmi_optee_channel {
+ u32 channel_id;
+ u32 tee_session;
+ u32 caps;
+ struct mutex mu;
+ struct scmi_chan_info *cinfo;
+ struct scmi_shared_mem __iomem *shmem;
+ struct tee_shm *tee_shm;
+ struct list_head link;
+};
+
+/**
+ * struct scmi_optee_agent - OP-TEE transport private data
+ *
+ * @dev: Device used for communication with TEE
+ * @tee_ctx: TEE context used for communication
+ * @caps: Supported channel capabilities
+ * @mu: Mutex for protection of @channel_list
+ * @channel_list: List of all created channels for the agent
+ */
+struct scmi_optee_agent {
+ struct device *dev;
+ struct tee_context *tee_ctx;
+ u32 caps;
+ struct mutex mu;
+ struct list_head channel_list;
+};
+
+/* There can be only 1 SCMI service in OP-TEE we connect to */
+static struct scmi_optee_agent *scmi_optee_private;
+
+/* Forward reference to scmi_optee transport initialization */
+static int scmi_optee_init(void);
+
+/* Open a session toward SCMI OP-TEE service with REE_KERNEL identity */
+static int open_session(struct scmi_optee_agent *agent, u32 *tee_session)
+{
+ struct device *dev = agent->dev;
+ struct tee_client_device *scmi_pta = to_tee_client_device(dev);
+ struct tee_ioctl_open_session_arg arg = { };
+ int ret;
+
+ memcpy(arg.uuid, scmi_pta->id.uuid.b, TEE_IOCTL_UUID_LEN);
+ arg.clnt_login = TEE_IOCTL_LOGIN_REE_KERNEL;
+
+ ret = tee_client_open_session(agent->tee_ctx, &arg, NULL);
+ if (ret < 0 || arg.ret) {
+ dev_err(dev, "Can't open tee session: %d / %#x\n", ret, arg.ret);
+ return -EOPNOTSUPP;
+ }
+
+ *tee_session = arg.session;
+
+ return 0;
+}
+
+static void close_session(struct scmi_optee_agent *agent, u32 tee_session)
+{
+ tee_client_close_session(agent->tee_ctx, tee_session);
+}
+
+static int get_capabilities(struct scmi_optee_agent *agent)
+{
+ struct tee_ioctl_invoke_arg arg = { };
+ struct tee_param param[1] = { };
+ u32 caps;
+ u32 tee_session;
+ int ret;
+
+ ret = open_session(agent, &tee_session);
+ if (ret)
+ return ret;
+
+ arg.func = PTA_SCMI_CMD_CAPABILITIES;
+ arg.session = tee_session;
+ arg.num_params = 1;
+
+ param[0].attr = TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_OUTPUT;
+
+ ret = tee_client_invoke_func(agent->tee_ctx, &arg, param);
+
+ close_session(agent, tee_session);
+
+ if (ret < 0 || arg.ret) {
+ dev_err(agent->dev, "Can't get capabilities: %d / %#x\n", ret, arg.ret);
+ return -EOPNOTSUPP;
+ }
+
+ caps = param[0].u.value.a;
+
+ if (!(caps & PTA_SCMI_CAPS_SMT_HEADER)) {
+ dev_err(agent->dev, "OP-TEE SCMI PTA doesn't support SMT\n");
+ return -EOPNOTSUPP;
+ }
+
+ agent->caps = caps;
+
+ return 0;
+}
+
+static int get_channel(struct scmi_optee_channel *channel)
+{
+ struct device *dev = scmi_optee_private->dev;
+ struct tee_ioctl_invoke_arg arg = { };
+ struct tee_param param[1] = { };
+ unsigned int caps = PTA_SCMI_CAPS_SMT_HEADER;
+ int ret;
+
+ arg.func = PTA_SCMI_CMD_GET_CHANNEL;
+ arg.session = channel->tee_session;
+ arg.num_params = 1;
+
+ param[0].attr = TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INOUT;
+ param[0].u.value.a = channel->channel_id;
+ param[0].u.value.b = caps;
+
+ ret = tee_client_invoke_func(scmi_optee_private->tee_ctx, &arg, param);
+
+ if (ret || arg.ret) {
+ dev_err(dev, "Can't get channel with caps %#x: %d / %#x\n", caps, ret, arg.ret);
+ return -EOPNOTSUPP;
+ }
+
+ /* From now on use channel identifer provided by OP-TEE SCMI service */
+ channel->channel_id = param[0].u.value.a;
+ channel->caps = caps;
+
+ return 0;
+}
+
+static int invoke_process_smt_channel(struct scmi_optee_channel *channel)
+{
+ struct tee_ioctl_invoke_arg arg = { };
+ struct tee_param param[2] = { };
+ int ret;
+
+ arg.session = channel->tee_session;
+ param[0].attr = TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT;
+ param[0].u.value.a = channel->channel_id;
+
+ if (channel->tee_shm) {
+ param[1].attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INOUT;
+ param[1].u.memref.shm = channel->tee_shm;
+ param[1].u.memref.size = SCMI_OPTEE_MAX_MSG_SIZE;
+ arg.num_params = 2;
+ arg.func = PTA_SCMI_CMD_PROCESS_SMT_CHANNEL_MESSAGE;
+ } else {
+ arg.num_params = 1;
+ arg.func = PTA_SCMI_CMD_PROCESS_SMT_CHANNEL;
+ }
+
+ ret = tee_client_invoke_func(scmi_optee_private->tee_ctx, &arg, param);
+ if (ret < 0 || arg.ret) {
+ dev_err(scmi_optee_private->dev, "Can't invoke channel %u: %d / %#x\n",
+ channel->channel_id, ret, arg.ret);
+ return -EIO;
+ }
+
+ return 0;
+}
+
+static int scmi_optee_link_supplier(struct device *dev)
+{
+ if (!scmi_optee_private) {
+ if (scmi_optee_init())
+ dev_dbg(dev, "Optee bus not yet ready\n");
+
+ /* Wait for optee bus */
+ return -EPROBE_DEFER;
+ }
+
+ if (!device_link_add(dev, scmi_optee_private->dev, DL_FLAG_AUTOREMOVE_CONSUMER)) {
+ dev_err(dev, "Adding link to supplier optee device failed\n");
+ return -ECANCELED;
+ }
+
+ return 0;
+}
+
+static bool scmi_optee_chan_available(struct device *dev, int idx)
+{
+ u32 channel_id;
+
+ return !of_property_read_u32_index(dev->of_node, "linaro,optee-channel-id",
+ idx, &channel_id);
+}
+
+static void scmi_optee_clear_channel(struct scmi_chan_info *cinfo)
+{
+ struct scmi_optee_channel *channel = cinfo->transport_info;
+
+ shmem_clear_channel(channel->shmem);
+}
+
+static int setup_static_shmem(struct device *dev, struct scmi_chan_info *cinfo,
+ struct scmi_optee_channel *channel)
+{
+ struct device_node *np;
+ resource_size_t size;
+ struct resource res;
+ int ret;
+
+ np = of_parse_phandle(cinfo->dev->of_node, "shmem", 0);
+ if (!of_device_is_compatible(np, "arm,scmi-shmem")) {
+ ret = -ENXIO;
+ goto out;
+ }
+
+ ret = of_address_to_resource(np, 0, &res);
+ if (ret) {
+ dev_err(dev, "Failed to get SCMI Tx shared memory\n");
+ goto out;
+ }
+
+ size = resource_size(&res);
+
+ channel->shmem = devm_ioremap(dev, res.start, size);
+ if (!channel->shmem) {
+ dev_err(dev, "Failed to ioremap SCMI Tx shared memory\n");
+ ret = -EADDRNOTAVAIL;
+ goto out;
+ }
+
+ ret = 0;
+
+out:
+ of_node_put(np);
+
+ return ret;
+}
+
+static int setup_shmem(struct device *dev, struct scmi_chan_info *cinfo,
+ struct scmi_optee_channel *channel)
+{
+ if (of_find_property(cinfo->dev->of_node, "shmem", NULL))
+ return setup_static_shmem(dev, cinfo, channel);
+ else
+ return -ENOMEM;
+}
+
+static int scmi_optee_chan_setup(struct scmi_chan_info *cinfo, struct device *dev, bool tx)
+{
+ struct scmi_optee_channel *channel;
+ uint32_t channel_id;
+ int ret;
+
+ if (!tx)
+ return -ENODEV;
+
+ channel = devm_kzalloc(dev, sizeof(*channel), GFP_KERNEL);
+ if (!channel)
+ return -ENOMEM;
+
+ ret = of_property_read_u32_index(cinfo->dev->of_node, "linaro,optee-channel-id",
+ 0, &channel_id);
+ if (ret)
+ return ret;
+
+ cinfo->transport_info = channel;
+ channel->cinfo = cinfo;
+ channel->channel_id = channel_id;
+ mutex_init(&channel->mu);
+
+ ret = setup_shmem(dev, cinfo, channel);
+ if (ret)
+ return ret;
+
+ ret = open_session(scmi_optee_private, &channel->tee_session);
+ if (ret)
+ goto err_free_shm;
+
+ ret = get_channel(channel);
+ if (ret)
+ goto err_close_sess;
+
+ /* Enable polling */
+ cinfo->no_completion_irq = true;
+
+ mutex_lock(&scmi_optee_private->mu);
+ list_add(&channel->link, &scmi_optee_private->channel_list);
+ mutex_unlock(&scmi_optee_private->mu);
+
+ return 0;
+
+err_close_sess:
+ close_session(scmi_optee_private, channel->tee_session);
+err_free_shm:
+ if (channel->tee_shm)
+ tee_shm_free(channel->tee_shm);
+
+ return ret;
+}
+
+static int scmi_optee_chan_free(int id, void *p, void *data)
+{
+ struct scmi_chan_info *cinfo = p;
+ struct scmi_optee_channel *channel = cinfo->transport_info;
+
+ mutex_lock(&scmi_optee_private->mu);
+ list_del(&channel->link);
+ mutex_unlock(&scmi_optee_private->mu);
+
+ close_session(scmi_optee_private, channel->tee_session);
+
+ if (channel->tee_shm) {
+ tee_shm_free(channel->tee_shm);
+ channel->tee_shm = NULL;
+ }
+
+ cinfo->transport_info = NULL;
+ channel->cinfo = NULL;
+
+ scmi_free_channel(cinfo, data, id);
+
+ return 0;
+}
+
+static struct scmi_shared_mem *get_channel_shm(struct scmi_optee_channel *chan,
+ struct scmi_xfer *xfer)
+{
+ if (!chan)
+ return NULL;
+
+ return chan->shmem;
+}
+
+
+static int scmi_optee_send_message(struct scmi_chan_info *cinfo,
+ struct scmi_xfer *xfer)
+{
+ struct scmi_optee_channel *channel = cinfo->transport_info;
+ struct scmi_shared_mem *shmem = get_channel_shm(channel, xfer);
+ int ret;
+
+ mutex_lock(&channel->mu);
+ shmem_tx_prepare(shmem, xfer);
+
+ ret = invoke_process_smt_channel(channel);
+ if (ret)
+ mutex_unlock(&channel->mu);
+
+ return ret;
+}
+
+static void scmi_optee_fetch_response(struct scmi_chan_info *cinfo,
+ struct scmi_xfer *xfer)
+{
+ struct scmi_optee_channel *channel = cinfo->transport_info;
+ struct scmi_shared_mem *shmem = get_channel_shm(channel, xfer);
+
+ shmem_fetch_response(shmem, xfer);
+}
+
+static void scmi_optee_mark_txdone(struct scmi_chan_info *cinfo, int ret,
+ struct scmi_xfer *__unused)
+{
+ struct scmi_optee_channel *channel = cinfo->transport_info;
+
+ mutex_unlock(&channel->mu);
+}
+
+static struct scmi_transport_ops scmi_optee_ops = {
+ .link_supplier = scmi_optee_link_supplier,
+ .chan_available = scmi_optee_chan_available,
+ .chan_setup = scmi_optee_chan_setup,
+ .chan_free = scmi_optee_chan_free,
+ .send_message = scmi_optee_send_message,
+ .mark_txdone = scmi_optee_mark_txdone,
+ .fetch_response = scmi_optee_fetch_response,
+ .clear_channel = scmi_optee_clear_channel,
+};
+
+static int scmi_optee_ctx_match(struct tee_ioctl_version_data *ver, const void *data)
+{
+ return ver->impl_id == TEE_IMPL_ID_OPTEE;
+}
+
+static int scmi_optee_service_probe(struct device *dev)
+{
+ struct scmi_optee_agent *agent;
+ struct tee_context *tee_ctx;
+ int ret;
+
+ /* Only one SCMI OP-TEE device allowed */
+ if (scmi_optee_private) {
+ dev_err(dev, "An SCMI OP-TEE device was already initialized: only one allowed\n");
+ return -EBUSY;
+ }
+
+ tee_ctx = tee_client_open_context(NULL, scmi_optee_ctx_match, NULL, NULL);
+ if (IS_ERR(tee_ctx))
+ return -ENODEV;
+
+ agent = devm_kzalloc(dev, sizeof(*agent), GFP_KERNEL);
+ if (!agent) {
+ ret = -ENOMEM;
+ goto err;
+ }
+
+ agent->dev = dev;
+ agent->tee_ctx = tee_ctx;
+ INIT_LIST_HEAD(&agent->channel_list);
+ mutex_init(&agent->mu);
+
+ ret = get_capabilities(agent);
+ if (ret)
+ goto err;
+
+ /* Ensure agent resources are all visible before scmi_optee_private is */
+ smp_mb();
+ scmi_optee_private = agent;
+
+ return 0;
+
+err:
+ tee_client_close_context(tee_ctx);
+
+ return ret;
+}
+
+static int scmi_optee_service_remove(struct device *dev)
+{
+ struct scmi_optee_agent *agent = scmi_optee_private;
+
+ if (!scmi_optee_private)
+ return -EINVAL;
+
+ if (!list_empty(&scmi_optee_private->channel_list))
+ return -EBUSY;
+
+ /* Ensure cleared reference is visible before resources are released */
+ smp_store_mb(scmi_optee_private, NULL);
+
+ tee_client_close_context(agent->tee_ctx);
+
+ return 0;
+}
+
+static const struct tee_client_device_id scmi_optee_service_id[] = {
+ {
+ UUID_INIT(0xa8cfe406, 0xd4f5, 0x4a2e,
+ 0x9f, 0x8d, 0xa2, 0x5d, 0xc7, 0x54, 0xc0, 0x99)
+ },
+ { }
+};
+
+MODULE_DEVICE_TABLE(tee, scmi_optee_service_id);
+
+static struct tee_client_driver scmi_optee_driver = {
+ .id_table = scmi_optee_service_id,
+ .driver = {
+ .name = "scmi-optee",
+ .bus = &tee_bus_type,
+ .probe = scmi_optee_service_probe,
+ .remove = scmi_optee_service_remove,
+ },
+};
+
+static int scmi_optee_init(void)
+{
+ return driver_register(&scmi_optee_driver.driver);
+}
+
+static void scmi_optee_exit(void)
+{
+ if (scmi_optee_private)
+ driver_unregister(&scmi_optee_driver.driver);
+}
+
+const struct scmi_desc scmi_optee_desc = {
+ .transport_exit = scmi_optee_exit,
+ .ops = &scmi_optee_ops,
+ .max_rx_timeout_ms = 30,
+ .max_msg = 20,
+ .max_msg_size = SCMI_OPTEE_MAX_MSG_SIZE,
+ .sync_cmds_completed_on_ret = true,
+};
diff --git a/drivers/firmware/arm_scmi/smc.c b/drivers/firmware/arm_scmi/smc.c
index 4effecc3bb46..745acfdd0b3d 100644
--- a/drivers/firmware/arm_scmi/smc.c
+++ b/drivers/firmware/arm_scmi/smc.c
@@ -7,6 +7,7 @@
*/
#include <linux/arm-smccc.h>
+#include <linux/atomic.h>
#include <linux/device.h>
#include <linux/err.h>
#include <linux/interrupt.h>
@@ -14,6 +15,7 @@
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_irq.h>
+#include <linux/processor.h>
#include <linux/slab.h>
#include "common.h"
@@ -23,26 +25,29 @@
*
* @cinfo: SCMI channel info
* @shmem: Transmit/Receive shared memory area
- * @shmem_lock: Lock to protect access to Tx/Rx shared memory area
+ * @shmem_lock: Lock to protect access to Tx/Rx shared memory area.
+ * Used when NOT operating in atomic mode.
+ * @inflight: Atomic flag to protect access to Tx/Rx shared memory area.
+ * Used when operating in atomic mode.
* @func_id: smc/hvc call function id
- * @irq: Optional; employed when platforms indicates msg completion by intr.
- * @tx_complete: Optional, employed only when irq is valid.
*/
struct scmi_smc {
struct scmi_chan_info *cinfo;
struct scmi_shared_mem __iomem *shmem;
+ /* Protect access to shmem area */
struct mutex shmem_lock;
+#define INFLIGHT_NONE MSG_TOKEN_MAX
+ atomic_t inflight;
u32 func_id;
- int irq;
- struct completion tx_complete;
};
static irqreturn_t smc_msg_done_isr(int irq, void *data)
{
struct scmi_smc *scmi_info = data;
- complete(&scmi_info->tx_complete);
+ scmi_rx_callback(scmi_info->cinfo,
+ shmem_read_header(scmi_info->shmem), NULL);
return IRQ_HANDLED;
}
@@ -57,6 +62,41 @@ static bool smc_chan_available(struct device *dev, int idx)
return true;
}
+static inline void smc_channel_lock_init(struct scmi_smc *scmi_info)
+{
+ if (IS_ENABLED(CONFIG_ARM_SCMI_TRANSPORT_SMC_ATOMIC_ENABLE))
+ atomic_set(&scmi_info->inflight, INFLIGHT_NONE);
+ else
+ mutex_init(&scmi_info->shmem_lock);
+}
+
+static bool smc_xfer_inflight(struct scmi_xfer *xfer, atomic_t *inflight)
+{
+ int ret;
+
+ ret = atomic_cmpxchg(inflight, INFLIGHT_NONE, xfer->hdr.seq);
+
+ return ret == INFLIGHT_NONE;
+}
+
+static inline void
+smc_channel_lock_acquire(struct scmi_smc *scmi_info,
+ struct scmi_xfer *xfer __maybe_unused)
+{
+ if (IS_ENABLED(CONFIG_ARM_SCMI_TRANSPORT_SMC_ATOMIC_ENABLE))
+ spin_until_cond(smc_xfer_inflight(xfer, &scmi_info->inflight));
+ else
+ mutex_lock(&scmi_info->shmem_lock);
+}
+
+static inline void smc_channel_lock_release(struct scmi_smc *scmi_info)
+{
+ if (IS_ENABLED(CONFIG_ARM_SCMI_TRANSPORT_SMC_ATOMIC_ENABLE))
+ atomic_set(&scmi_info->inflight, INFLIGHT_NONE);
+ else
+ mutex_unlock(&scmi_info->shmem_lock);
+}
+
static int smc_chan_setup(struct scmi_chan_info *cinfo, struct device *dev,
bool tx)
{
@@ -111,13 +151,13 @@ static int smc_chan_setup(struct scmi_chan_info *cinfo, struct device *dev,
dev_err(dev, "failed to setup SCMI smc irq\n");
return ret;
}
- init_completion(&scmi_info->tx_complete);
- scmi_info->irq = irq;
+ } else {
+ cinfo->no_completion_irq = true;
}
scmi_info->func_id = func_id;
scmi_info->cinfo = cinfo;
- mutex_init(&scmi_info->shmem_lock);
+ smc_channel_lock_init(scmi_info);
cinfo->transport_info = scmi_info;
return 0;
@@ -142,26 +182,22 @@ static int smc_send_message(struct scmi_chan_info *cinfo,
struct scmi_smc *scmi_info = cinfo->transport_info;
struct arm_smccc_res res;
- mutex_lock(&scmi_info->shmem_lock);
+ /*
+ * Channel will be released only once response has been
+ * surely fully retrieved, so after .mark_txdone()
+ */
+ smc_channel_lock_acquire(scmi_info, xfer);
shmem_tx_prepare(scmi_info->shmem, xfer);
- if (scmi_info->irq)
- reinit_completion(&scmi_info->tx_complete);
-
arm_smccc_1_1_invoke(scmi_info->func_id, 0, 0, 0, 0, 0, 0, 0, &res);
- if (scmi_info->irq)
- wait_for_completion(&scmi_info->tx_complete);
-
- scmi_rx_callback(scmi_info->cinfo,
- shmem_read_header(scmi_info->shmem), NULL);
-
- mutex_unlock(&scmi_info->shmem_lock);
-
/* Only SMCCC_RET_NOT_SUPPORTED is valid error code */
- if (res.a0)
+ if (res.a0) {
+ smc_channel_lock_release(scmi_info);
return -EOPNOTSUPP;
+ }
+
return 0;
}
@@ -173,12 +209,12 @@ static void smc_fetch_response(struct scmi_chan_info *cinfo,
shmem_fetch_response(scmi_info->shmem, xfer);
}
-static bool
-smc_poll_done(struct scmi_chan_info *cinfo, struct scmi_xfer *xfer)
+static void smc_mark_txdone(struct scmi_chan_info *cinfo, int ret,
+ struct scmi_xfer *__unused)
{
struct scmi_smc *scmi_info = cinfo->transport_info;
- return shmem_poll_done(scmi_info->shmem, xfer);
+ smc_channel_lock_release(scmi_info);
}
static const struct scmi_transport_ops scmi_smc_ops = {
@@ -186,8 +222,8 @@ static const struct scmi_transport_ops scmi_smc_ops = {
.chan_setup = smc_chan_setup,
.chan_free = smc_chan_free,
.send_message = smc_send_message,
+ .mark_txdone = smc_mark_txdone,
.fetch_response = smc_fetch_response,
- .poll_done = smc_poll_done,
};
const struct scmi_desc scmi_smc_desc = {
@@ -195,4 +231,14 @@ const struct scmi_desc scmi_smc_desc = {
.max_rx_timeout_ms = 30,
.max_msg = 20,
.max_msg_size = 128,
+ /*
+ * Setting .sync_cmds_atomic_replies to true for SMC assumes that,
+ * once the SMC instruction has completed successfully, the issued
+ * SCMI command would have been already fully processed by the SCMI
+ * platform firmware and so any possible response value expected
+ * for the issued command will be immmediately ready to be fetched
+ * from the shared memory area.
+ */
+ .sync_cmds_completed_on_ret = true,
+ .atomic_enabled = IS_ENABLED(CONFIG_ARM_SCMI_TRANSPORT_SMC_ATOMIC_ENABLE),
};
diff --git a/drivers/firmware/arm_scmi/virtio.c b/drivers/firmware/arm_scmi/virtio.c
index eefcc4146749..14709dbc96a1 100644
--- a/drivers/firmware/arm_scmi/virtio.c
+++ b/drivers/firmware/arm_scmi/virtio.c
@@ -3,8 +3,8 @@
* Virtio Transport driver for Arm System Control and Management Interface
* (SCMI).
*
- * Copyright (C) 2020-2021 OpenSynergy.
- * Copyright (C) 2021 ARM Ltd.
+ * Copyright (C) 2020-2022 OpenSynergy.
+ * Copyright (C) 2021-2022 ARM Ltd.
*/
/**
@@ -17,7 +17,9 @@
* virtqueue. Access to each virtqueue is protected by spinlocks.
*/
+#include <linux/completion.h>
#include <linux/errno.h>
+#include <linux/refcount.h>
#include <linux/slab.h>
#include <linux/virtio.h>
#include <linux/virtio_config.h>
@@ -27,6 +29,7 @@
#include "common.h"
+#define VIRTIO_MAX_RX_TIMEOUT_MS 60000
#define VIRTIO_SCMI_MAX_MSG_SIZE 128 /* Value may be increased. */
#define VIRTIO_SCMI_MAX_PDU_SIZE \
(VIRTIO_SCMI_MAX_MSG_SIZE + SCMI_MSG_MAX_PROT_OVERHEAD)
@@ -37,25 +40,46 @@
*
* @vqueue: Associated virtqueue
* @cinfo: SCMI Tx or Rx channel
+ * @free_lock: Protects access to the @free_list.
* @free_list: List of unused scmi_vio_msg, maintained for Tx channels only
+ * @deferred_tx_work: Worker for TX deferred replies processing
+ * @deferred_tx_wq: Workqueue for TX deferred replies
+ * @pending_lock: Protects access to the @pending_cmds_list.
+ * @pending_cmds_list: List of pre-fetched commands queueud for later processing
* @is_rx: Whether channel is an Rx channel
- * @ready: Whether transport user is ready to hear about channel
* @max_msg: Maximum number of pending messages for this channel.
- * @lock: Protects access to all members except ready.
- * @ready_lock: Protects access to ready. If required, it must be taken before
- * lock.
+ * @lock: Protects access to all members except users, free_list and
+ * pending_cmds_list.
+ * @shutdown_done: A reference to a completion used when freeing this channel.
+ * @users: A reference count to currently active users of this channel.
*/
struct scmi_vio_channel {
struct virtqueue *vqueue;
struct scmi_chan_info *cinfo;
+ /* lock to protect access to the free list. */
+ spinlock_t free_lock;
struct list_head free_list;
+ /* lock to protect access to the pending list. */
+ spinlock_t pending_lock;
+ struct list_head pending_cmds_list;
+ struct work_struct deferred_tx_work;
+ struct workqueue_struct *deferred_tx_wq;
bool is_rx;
- bool ready;
unsigned int max_msg;
- /* lock to protect access to all members except ready. */
+ /*
+ * Lock to protect access to all members except users, free_list and
+ * pending_cmds_list
+ */
spinlock_t lock;
- /* lock to rotects access to ready flag. */
- spinlock_t ready_lock;
+ struct completion *shutdown_done;
+ refcount_t users;
+};
+
+enum poll_states {
+ VIO_MSG_NOT_POLLED,
+ VIO_MSG_POLL_TIMEOUT,
+ VIO_MSG_POLLING,
+ VIO_MSG_POLL_DONE,
};
/**
@@ -65,29 +89,154 @@ struct scmi_vio_channel {
* @input: SDU used for (delayed) responses and notifications
* @list: List which scmi_vio_msg may be part of
* @rx_len: Input SDU size in bytes, once input has been received
+ * @poll_idx: Last used index registered for polling purposes if this message
+ * transaction reply was configured for polling.
+ * @poll_status: Polling state for this message.
+ * @poll_lock: A lock to protect @poll_status
+ * @users: A reference count to track this message users and avoid premature
+ * freeing (and reuse) when polling and IRQ execution paths interleave.
*/
struct scmi_vio_msg {
struct scmi_msg_payld *request;
struct scmi_msg_payld *input;
struct list_head list;
unsigned int rx_len;
+ unsigned int poll_idx;
+ enum poll_states poll_status;
+ /* Lock to protect access to poll_status */
+ spinlock_t poll_lock;
+ refcount_t users;
};
/* Only one SCMI VirtIO device can possibly exist */
static struct virtio_device *scmi_vdev;
+static void scmi_vio_channel_ready(struct scmi_vio_channel *vioch,
+ struct scmi_chan_info *cinfo)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&vioch->lock, flags);
+ cinfo->transport_info = vioch;
+ /* Indirectly setting channel not available any more */
+ vioch->cinfo = cinfo;
+ spin_unlock_irqrestore(&vioch->lock, flags);
+
+ refcount_set(&vioch->users, 1);
+}
+
+static inline bool scmi_vio_channel_acquire(struct scmi_vio_channel *vioch)
+{
+ return refcount_inc_not_zero(&vioch->users);
+}
+
+static inline void scmi_vio_channel_release(struct scmi_vio_channel *vioch)
+{
+ if (refcount_dec_and_test(&vioch->users)) {
+ unsigned long flags;
+
+ spin_lock_irqsave(&vioch->lock, flags);
+ if (vioch->shutdown_done) {
+ vioch->cinfo = NULL;
+ complete(vioch->shutdown_done);
+ }
+ spin_unlock_irqrestore(&vioch->lock, flags);
+ }
+}
+
+static void scmi_vio_channel_cleanup_sync(struct scmi_vio_channel *vioch)
+{
+ unsigned long flags;
+ DECLARE_COMPLETION_ONSTACK(vioch_shutdown_done);
+ void *deferred_wq = NULL;
+
+ /*
+ * Prepare to wait for the last release if not already released
+ * or in progress.
+ */
+ spin_lock_irqsave(&vioch->lock, flags);
+ if (!vioch->cinfo || vioch->shutdown_done) {
+ spin_unlock_irqrestore(&vioch->lock, flags);
+ return;
+ }
+
+ vioch->shutdown_done = &vioch_shutdown_done;
+ virtio_break_device(vioch->vqueue->vdev);
+ if (!vioch->is_rx && vioch->deferred_tx_wq) {
+ deferred_wq = vioch->deferred_tx_wq;
+ /* Cannot be kicked anymore after this...*/
+ vioch->deferred_tx_wq = NULL;
+ }
+ spin_unlock_irqrestore(&vioch->lock, flags);
+
+ if (deferred_wq)
+ destroy_workqueue(deferred_wq);
+
+ scmi_vio_channel_release(vioch);
+
+ /* Let any possibly concurrent RX path release the channel */
+ wait_for_completion(vioch->shutdown_done);
+}
+
+/* Assumes to be called with vio channel acquired already */
+static struct scmi_vio_msg *
+scmi_virtio_get_free_msg(struct scmi_vio_channel *vioch)
+{
+ unsigned long flags;
+ struct scmi_vio_msg *msg;
+
+ spin_lock_irqsave(&vioch->free_lock, flags);
+ if (list_empty(&vioch->free_list)) {
+ spin_unlock_irqrestore(&vioch->free_lock, flags);
+ return NULL;
+ }
+
+ msg = list_first_entry(&vioch->free_list, typeof(*msg), list);
+ list_del_init(&msg->list);
+ spin_unlock_irqrestore(&vioch->free_lock, flags);
+
+ /* Still no users, no need to acquire poll_lock */
+ msg->poll_status = VIO_MSG_NOT_POLLED;
+ refcount_set(&msg->users, 1);
+
+ return msg;
+}
+
+static inline bool scmi_vio_msg_acquire(struct scmi_vio_msg *msg)
+{
+ return refcount_inc_not_zero(&msg->users);
+}
+
+/* Assumes to be called with vio channel acquired already */
+static inline bool scmi_vio_msg_release(struct scmi_vio_channel *vioch,
+ struct scmi_vio_msg *msg)
+{
+ bool ret;
+
+ ret = refcount_dec_and_test(&msg->users);
+ if (ret) {
+ unsigned long flags;
+
+ spin_lock_irqsave(&vioch->free_lock, flags);
+ list_add_tail(&msg->list, &vioch->free_list);
+ spin_unlock_irqrestore(&vioch->free_lock, flags);
+ }
+
+ return ret;
+}
+
static bool scmi_vio_have_vq_rx(struct virtio_device *vdev)
{
return virtio_has_feature(vdev, VIRTIO_SCMI_F_P2A_CHANNELS);
}
static int scmi_vio_feed_vq_rx(struct scmi_vio_channel *vioch,
- struct scmi_vio_msg *msg,
- struct device *dev)
+ struct scmi_vio_msg *msg)
{
struct scatterlist sg_in;
int rc;
unsigned long flags;
+ struct device *dev = &vioch->vqueue->vdev->dev;
sg_init_one(&sg_in, msg->input, VIRTIO_SCMI_MAX_PDU_SIZE);
@@ -95,7 +244,7 @@ static int scmi_vio_feed_vq_rx(struct scmi_vio_channel *vioch,
rc = virtqueue_add_inbuf(vioch->vqueue, &sg_in, 1, msg, GFP_ATOMIC);
if (rc)
- dev_err_once(dev, "failed to add to virtqueue (%d)\n", rc);
+ dev_err(dev, "failed to add to RX virtqueue (%d)\n", rc);
else
virtqueue_kick(vioch->vqueue);
@@ -104,22 +253,22 @@ static int scmi_vio_feed_vq_rx(struct scmi_vio_channel *vioch,
return rc;
}
+/*
+ * Assume to be called with channel already acquired or not ready at all;
+ * vioch->lock MUST NOT have been already acquired.
+ */
static void scmi_finalize_message(struct scmi_vio_channel *vioch,
struct scmi_vio_msg *msg)
{
- if (vioch->is_rx) {
- scmi_vio_feed_vq_rx(vioch, msg, vioch->cinfo->dev);
- } else {
- /* Here IRQs are assumed to be already disabled by the caller */
- spin_lock(&vioch->lock);
- list_add(&msg->list, &vioch->free_list);
- spin_unlock(&vioch->lock);
- }
+ if (vioch->is_rx)
+ scmi_vio_feed_vq_rx(vioch, msg);
+ else
+ scmi_vio_msg_release(vioch, msg);
}
static void scmi_vio_complete_cb(struct virtqueue *vqueue)
{
- unsigned long ready_flags;
+ unsigned long flags;
unsigned int length;
struct scmi_vio_channel *vioch;
struct scmi_vio_msg *msg;
@@ -130,27 +279,25 @@ static void scmi_vio_complete_cb(struct virtqueue *vqueue)
vioch = &((struct scmi_vio_channel *)vqueue->vdev->priv)[vqueue->index];
for (;;) {
- spin_lock_irqsave(&vioch->ready_lock, ready_flags);
+ if (!scmi_vio_channel_acquire(vioch))
+ return;
- if (!vioch->ready) {
- if (!cb_enabled)
- (void)virtqueue_enable_cb(vqueue);
- goto unlock_ready_out;
- }
-
- /* IRQs already disabled here no need to irqsave */
- spin_lock(&vioch->lock);
+ spin_lock_irqsave(&vioch->lock, flags);
if (cb_enabled) {
virtqueue_disable_cb(vqueue);
cb_enabled = false;
}
+
msg = virtqueue_get_buf(vqueue, &length);
if (!msg) {
- if (virtqueue_enable_cb(vqueue))
- goto unlock_out;
+ if (virtqueue_enable_cb(vqueue)) {
+ spin_unlock_irqrestore(&vioch->lock, flags);
+ scmi_vio_channel_release(vioch);
+ return;
+ }
cb_enabled = true;
}
- spin_unlock(&vioch->lock);
+ spin_unlock_irqrestore(&vioch->lock, flags);
if (msg) {
msg->rx_len = length;
@@ -161,19 +308,57 @@ static void scmi_vio_complete_cb(struct virtqueue *vqueue)
}
/*
- * Release ready_lock and re-enable IRQs between loop iterations
- * to allow virtio_chan_free() to possibly kick in and set the
- * flag vioch->ready to false even in between processing of
- * messages, so as to force outstanding messages to be ignored
- * when system is shutting down.
+ * Release vio channel between loop iterations to allow
+ * virtio_chan_free() to eventually fully release it when
+ * shutting down; in such a case, any outstanding message will
+ * be ignored since this loop will bail out at the next
+ * iteration.
+ */
+ scmi_vio_channel_release(vioch);
+ }
+}
+
+static void scmi_vio_deferred_tx_worker(struct work_struct *work)
+{
+ unsigned long flags;
+ struct scmi_vio_channel *vioch;
+ struct scmi_vio_msg *msg, *tmp;
+
+ vioch = container_of(work, struct scmi_vio_channel, deferred_tx_work);
+
+ if (!scmi_vio_channel_acquire(vioch))
+ return;
+
+ /*
+ * Process pre-fetched messages: these could be non-polled messages or
+ * late timed-out replies to polled messages dequeued by chance while
+ * polling for some other messages: this worker is in charge to process
+ * the valid non-expired messages and anyway finally free all of them.
+ */
+ spin_lock_irqsave(&vioch->pending_lock, flags);
+
+ /* Scan the list of possibly pre-fetched messages during polling. */
+ list_for_each_entry_safe(msg, tmp, &vioch->pending_cmds_list, list) {
+ list_del(&msg->list);
+
+ /*
+ * Channel is acquired here (cannot vanish) and this message
+ * is no more processed elsewhere so no poll_lock needed.
*/
- spin_unlock_irqrestore(&vioch->ready_lock, ready_flags);
+ if (msg->poll_status == VIO_MSG_NOT_POLLED)
+ scmi_rx_callback(vioch->cinfo,
+ msg_read_header(msg->input), msg);
+
+ /* Free the processed message once done */
+ scmi_vio_msg_release(vioch, msg);
}
-unlock_out:
- spin_unlock(&vioch->lock);
-unlock_ready_out:
- spin_unlock_irqrestore(&vioch->ready_lock, ready_flags);
+ spin_unlock_irqrestore(&vioch->pending_lock, flags);
+
+ /* Process possibly still pending messages */
+ scmi_vio_complete_cb(vioch->vqueue);
+
+ scmi_vio_channel_release(vioch);
}
static const char *const scmi_vio_vqueue_names[] = { "tx", "rx" };
@@ -193,8 +378,8 @@ static unsigned int virtio_get_max_msg(struct scmi_chan_info *base_cinfo)
static int virtio_link_supplier(struct device *dev)
{
if (!scmi_vdev) {
- dev_notice_once(dev,
- "Deferring probe after not finding a bound scmi-virtio device\n");
+ dev_notice(dev,
+ "Deferring probe after not finding a bound scmi-virtio device\n");
return -EPROBE_DEFER;
}
@@ -234,7 +419,6 @@ static bool virtio_chan_available(struct device *dev, int idx)
static int virtio_chan_setup(struct scmi_chan_info *cinfo, struct device *dev,
bool tx)
{
- unsigned long flags;
struct scmi_vio_channel *vioch;
int index = tx ? VIRTIO_SCMI_VQ_TX : VIRTIO_SCMI_VQ_RX;
int i;
@@ -244,6 +428,19 @@ static int virtio_chan_setup(struct scmi_chan_info *cinfo, struct device *dev,
vioch = &((struct scmi_vio_channel *)scmi_vdev->priv)[index];
+ /* Setup a deferred worker for polling. */
+ if (tx && !vioch->deferred_tx_wq) {
+ vioch->deferred_tx_wq =
+ alloc_workqueue(dev_name(&scmi_vdev->dev),
+ WQ_UNBOUND | WQ_FREEZABLE | WQ_SYSFS,
+ 0);
+ if (!vioch->deferred_tx_wq)
+ return -ENOMEM;
+
+ INIT_WORK(&vioch->deferred_tx_work,
+ scmi_vio_deferred_tx_worker);
+ }
+
for (i = 0; i < vioch->max_msg; i++) {
struct scmi_vio_msg *msg;
@@ -257,6 +454,8 @@ static int virtio_chan_setup(struct scmi_chan_info *cinfo, struct device *dev,
GFP_KERNEL);
if (!msg->request)
return -ENOMEM;
+ spin_lock_init(&msg->poll_lock);
+ refcount_set(&msg->users, 1);
}
msg->input = devm_kzalloc(cinfo->dev, VIRTIO_SCMI_MAX_PDU_SIZE,
@@ -264,44 +463,23 @@ static int virtio_chan_setup(struct scmi_chan_info *cinfo, struct device *dev,
if (!msg->input)
return -ENOMEM;
- if (tx) {
- spin_lock_irqsave(&vioch->lock, flags);
- list_add_tail(&msg->list, &vioch->free_list);
- spin_unlock_irqrestore(&vioch->lock, flags);
- } else {
- scmi_vio_feed_vq_rx(vioch, msg, cinfo->dev);
- }
+ scmi_finalize_message(vioch, msg);
}
- spin_lock_irqsave(&vioch->lock, flags);
- cinfo->transport_info = vioch;
- /* Indirectly setting channel not available any more */
- vioch->cinfo = cinfo;
- spin_unlock_irqrestore(&vioch->lock, flags);
-
- spin_lock_irqsave(&vioch->ready_lock, flags);
- vioch->ready = true;
- spin_unlock_irqrestore(&vioch->ready_lock, flags);
+ scmi_vio_channel_ready(vioch, cinfo);
return 0;
}
static int virtio_chan_free(int id, void *p, void *data)
{
- unsigned long flags;
struct scmi_chan_info *cinfo = p;
struct scmi_vio_channel *vioch = cinfo->transport_info;
- spin_lock_irqsave(&vioch->ready_lock, flags);
- vioch->ready = false;
- spin_unlock_irqrestore(&vioch->ready_lock, flags);
+ scmi_vio_channel_cleanup_sync(vioch);
scmi_free_channel(cinfo, data, id);
- spin_lock_irqsave(&vioch->lock, flags);
- vioch->cinfo = NULL;
- spin_unlock_irqrestore(&vioch->lock, flags);
-
return 0;
}
@@ -316,33 +494,56 @@ static int virtio_send_message(struct scmi_chan_info *cinfo,
int rc;
struct scmi_vio_msg *msg;
- spin_lock_irqsave(&vioch->lock, flags);
+ if (!scmi_vio_channel_acquire(vioch))
+ return -EINVAL;
- if (list_empty(&vioch->free_list)) {
- spin_unlock_irqrestore(&vioch->lock, flags);
+ msg = scmi_virtio_get_free_msg(vioch);
+ if (!msg) {
+ scmi_vio_channel_release(vioch);
return -EBUSY;
}
- msg = list_first_entry(&vioch->free_list, typeof(*msg), list);
- list_del(&msg->list);
-
msg_tx_prepare(msg->request, xfer);
sg_init_one(&sg_out, msg->request, msg_command_size(xfer));
sg_init_one(&sg_in, msg->input, msg_response_size(xfer));
+ spin_lock_irqsave(&vioch->lock, flags);
+
+ /*
+ * If polling was requested for this transaction:
+ * - retrieve last used index (will be used as polling reference)
+ * - bind the polled message to the xfer via .priv
+ * - grab an additional msg refcount for the poll-path
+ */
+ if (xfer->hdr.poll_completion) {
+ msg->poll_idx = virtqueue_enable_cb_prepare(vioch->vqueue);
+ /* Still no users, no need to acquire poll_lock */
+ msg->poll_status = VIO_MSG_POLLING;
+ scmi_vio_msg_acquire(msg);
+ /* Ensure initialized msg is visibly bound to xfer */
+ smp_store_mb(xfer->priv, msg);
+ }
+
rc = virtqueue_add_sgs(vioch->vqueue, sgs, 1, 1, msg, GFP_ATOMIC);
- if (rc) {
- list_add(&msg->list, &vioch->free_list);
- dev_err_once(vioch->cinfo->dev,
- "%s() failed to add to virtqueue (%d)\n", __func__,
- rc);
- } else {
+ if (rc)
+ dev_err(vioch->cinfo->dev,
+ "failed to add to TX virtqueue (%d)\n", rc);
+ else
virtqueue_kick(vioch->vqueue);
- }
spin_unlock_irqrestore(&vioch->lock, flags);
+ if (rc) {
+ /* Ensure order between xfer->priv clear and vq feeding */
+ smp_store_mb(xfer->priv, NULL);
+ if (xfer->hdr.poll_completion)
+ scmi_vio_msg_release(vioch, msg);
+ scmi_vio_msg_release(vioch, msg);
+ }
+
+ scmi_vio_channel_release(vioch);
+
return rc;
}
@@ -351,10 +552,8 @@ static void virtio_fetch_response(struct scmi_chan_info *cinfo,
{
struct scmi_vio_msg *msg = xfer->priv;
- if (msg) {
+ if (msg)
msg_fetch_response(msg->input, msg->rx_len, xfer);
- xfer->priv = NULL;
- }
}
static void virtio_fetch_notification(struct scmi_chan_info *cinfo,
@@ -362,10 +561,225 @@ static void virtio_fetch_notification(struct scmi_chan_info *cinfo,
{
struct scmi_vio_msg *msg = xfer->priv;
- if (msg) {
+ if (msg)
msg_fetch_notification(msg->input, msg->rx_len, max_len, xfer);
- xfer->priv = NULL;
+}
+
+/**
+ * virtio_mark_txdone - Mark transmission done
+ *
+ * Free only completed polling transfer messages.
+ *
+ * Note that in the SCMI VirtIO transport we never explicitly release still
+ * outstanding but timed-out messages by forcibly re-adding them to the
+ * free-list inside the TX code path; we instead let IRQ/RX callbacks, or the
+ * TX deferred worker, eventually clean up such messages once, finally, a late
+ * reply is received and discarded (if ever).
+ *
+ * This approach was deemed preferable since those pending timed-out buffers are
+ * still effectively owned by the SCMI platform VirtIO device even after timeout
+ * expiration: forcibly freeing and reusing them before they had been returned
+ * explicitly by the SCMI platform could lead to subtle bugs due to message
+ * corruption.
+ * An SCMI platform VirtIO device which never returns message buffers is
+ * anyway broken and it will quickly lead to exhaustion of available messages.
+ *
+ * For this same reason, here, we take care to free only the polled messages
+ * that had been somehow replied (only if not by chance already processed on the
+ * IRQ path - the initial scmi_vio_msg_release() takes care of this) and also
+ * any timed-out polled message if that indeed appears to have been at least
+ * dequeued from the virtqueues (VIO_MSG_POLL_DONE): this is needed since such
+ * messages won't be freed elsewhere. Any other polled message is marked as
+ * VIO_MSG_POLL_TIMEOUT.
+ *
+ * Possible late replies to timed-out polled messages will be eventually freed
+ * by RX callbacks if delivered on the IRQ path or by the deferred TX worker if
+ * dequeued on some other polling path.
+ *
+ * @cinfo: SCMI channel info
+ * @ret: Transmission return code
+ * @xfer: Transfer descriptor
+ */
+static void virtio_mark_txdone(struct scmi_chan_info *cinfo, int ret,
+ struct scmi_xfer *xfer)
+{
+ unsigned long flags;
+ struct scmi_vio_channel *vioch = cinfo->transport_info;
+ struct scmi_vio_msg *msg = xfer->priv;
+
+ if (!msg || !scmi_vio_channel_acquire(vioch))
+ return;
+
+ /* Ensure msg is unbound from xfer anyway at this point */
+ smp_store_mb(xfer->priv, NULL);
+
+ /* Must be a polled xfer and not already freed on the IRQ path */
+ if (!xfer->hdr.poll_completion || scmi_vio_msg_release(vioch, msg)) {
+ scmi_vio_channel_release(vioch);
+ return;
}
+
+ spin_lock_irqsave(&msg->poll_lock, flags);
+ /* Do not free timedout polled messages only if still inflight */
+ if (ret != -ETIMEDOUT || msg->poll_status == VIO_MSG_POLL_DONE)
+ scmi_vio_msg_release(vioch, msg);
+ else if (msg->poll_status == VIO_MSG_POLLING)
+ msg->poll_status = VIO_MSG_POLL_TIMEOUT;
+ spin_unlock_irqrestore(&msg->poll_lock, flags);
+
+ scmi_vio_channel_release(vioch);
+}
+
+/**
+ * virtio_poll_done - Provide polling support for VirtIO transport
+ *
+ * @cinfo: SCMI channel info
+ * @xfer: Reference to the transfer being poll for.
+ *
+ * VirtIO core provides a polling mechanism based only on last used indexes:
+ * this means that it is possible to poll the virtqueues waiting for something
+ * new to arrive from the host side, but the only way to check if the freshly
+ * arrived buffer was indeed what we were waiting for is to compare the newly
+ * arrived message descriptor with the one we are polling on.
+ *
+ * As a consequence it can happen to dequeue something different from the buffer
+ * we were poll-waiting for: if that is the case such early fetched buffers are
+ * then added to a the @pending_cmds_list list for later processing by a
+ * dedicated deferred worker.
+ *
+ * So, basically, once something new is spotted we proceed to de-queue all the
+ * freshly received used buffers until we found the one we were polling on, or,
+ * we have 'seemingly' emptied the virtqueue; if some buffers are still pending
+ * in the vqueue at the end of the polling loop (possible due to inherent races
+ * in virtqueues handling mechanisms), we similarly kick the deferred worker
+ * and let it process those, to avoid indefinitely looping in the .poll_done
+ * busy-waiting helper.
+ *
+ * Finally, we delegate to the deferred worker also the final free of any timed
+ * out reply to a polled message that we should dequeue.
+ *
+ * Note that, since we do NOT have per-message suppress notification mechanism,
+ * the message we are polling for could be alternatively delivered via usual
+ * IRQs callbacks on another core which happened to have IRQs enabled while we
+ * are actively polling for it here: in such a case it will be handled as such
+ * by scmi_rx_callback() and the polling loop in the SCMI Core TX path will be
+ * transparently terminated anyway.
+ *
+ * Return: True once polling has successfully completed.
+ */
+static bool virtio_poll_done(struct scmi_chan_info *cinfo,
+ struct scmi_xfer *xfer)
+{
+ bool pending, found = false;
+ unsigned int length, any_prefetched = 0;
+ unsigned long flags;
+ struct scmi_vio_msg *next_msg, *msg = xfer->priv;
+ struct scmi_vio_channel *vioch = cinfo->transport_info;
+
+ if (!msg)
+ return true;
+
+ /*
+ * Processed already by other polling loop on another CPU ?
+ *
+ * Note that this message is acquired on the poll path so cannot vanish
+ * while inside this loop iteration even if concurrently processed on
+ * the IRQ path.
+ *
+ * Avoid to acquire poll_lock since polled_status can be changed
+ * in a relevant manner only later in this same thread of execution:
+ * any other possible changes made concurrently by other polling loops
+ * or by a reply delivered on the IRQ path have no meaningful impact on
+ * this loop iteration: in other words it is harmless to allow this
+ * possible race but let has avoid spinlocking with irqs off in this
+ * initial part of the polling loop.
+ */
+ if (msg->poll_status == VIO_MSG_POLL_DONE)
+ return true;
+
+ if (!scmi_vio_channel_acquire(vioch))
+ return true;
+
+ /* Has cmdq index moved at all ? */
+ pending = virtqueue_poll(vioch->vqueue, msg->poll_idx);
+ if (!pending) {
+ scmi_vio_channel_release(vioch);
+ return false;
+ }
+
+ spin_lock_irqsave(&vioch->lock, flags);
+ virtqueue_disable_cb(vioch->vqueue);
+
+ /*
+ * Process all new messages till the polled-for message is found OR
+ * the vqueue is empty.
+ */
+ while ((next_msg = virtqueue_get_buf(vioch->vqueue, &length))) {
+ bool next_msg_done = false;
+
+ /*
+ * Mark any dequeued buffer message as VIO_MSG_POLL_DONE so
+ * that can be properly freed even on timeout in mark_txdone.
+ */
+ spin_lock(&next_msg->poll_lock);
+ if (next_msg->poll_status == VIO_MSG_POLLING) {
+ next_msg->poll_status = VIO_MSG_POLL_DONE;
+ next_msg_done = true;
+ }
+ spin_unlock(&next_msg->poll_lock);
+
+ next_msg->rx_len = length;
+ /* Is the message we were polling for ? */
+ if (next_msg == msg) {
+ found = true;
+ break;
+ } else if (next_msg_done) {
+ /* Skip the rest if this was another polled msg */
+ continue;
+ }
+
+ /*
+ * Enqueue for later processing any non-polled message and any
+ * timed-out polled one that we happen to have dequeued.
+ */
+ spin_lock(&next_msg->poll_lock);
+ if (next_msg->poll_status == VIO_MSG_NOT_POLLED ||
+ next_msg->poll_status == VIO_MSG_POLL_TIMEOUT) {
+ spin_unlock(&next_msg->poll_lock);
+
+ any_prefetched++;
+ spin_lock(&vioch->pending_lock);
+ list_add_tail(&next_msg->list,
+ &vioch->pending_cmds_list);
+ spin_unlock(&vioch->pending_lock);
+ } else {
+ spin_unlock(&next_msg->poll_lock);
+ }
+ }
+
+ /*
+ * When the polling loop has successfully terminated if something
+ * else was queued in the meantime, it will be served by a deferred
+ * worker OR by the normal IRQ/callback OR by other poll loops.
+ *
+ * If we are still looking for the polled reply, the polling index has
+ * to be updated to the current vqueue last used index.
+ */
+ if (found) {
+ pending = !virtqueue_enable_cb(vioch->vqueue);
+ } else {
+ msg->poll_idx = virtqueue_enable_cb_prepare(vioch->vqueue);
+ pending = virtqueue_poll(vioch->vqueue, msg->poll_idx);
+ }
+
+ if (vioch->deferred_tx_wq && (any_prefetched || pending))
+ queue_work(vioch->deferred_tx_wq, &vioch->deferred_tx_work);
+
+ spin_unlock_irqrestore(&vioch->lock, flags);
+
+ scmi_vio_channel_release(vioch);
+
+ return found;
}
static const struct scmi_transport_ops scmi_virtio_ops = {
@@ -377,6 +791,8 @@ static const struct scmi_transport_ops scmi_virtio_ops = {
.send_message = virtio_send_message,
.fetch_response = virtio_fetch_response,
.fetch_notification = virtio_fetch_notification,
+ .mark_txdone = virtio_mark_txdone,
+ .poll_done = virtio_poll_done,
};
static int scmi_vio_probe(struct virtio_device *vdev)
@@ -417,8 +833,10 @@ static int scmi_vio_probe(struct virtio_device *vdev)
unsigned int sz;
spin_lock_init(&channels[i].lock);
- spin_lock_init(&channels[i].ready_lock);
+ spin_lock_init(&channels[i].free_lock);
INIT_LIST_HEAD(&channels[i].free_list);
+ spin_lock_init(&channels[i].pending_lock);
+ INIT_LIST_HEAD(&channels[i].pending_cmds_list);
channels[i].vqueue = vqs[i];
sz = virtqueue_get_vring_size(channels[i].vqueue);
@@ -427,10 +845,10 @@ static int scmi_vio_probe(struct virtio_device *vdev)
sz /= DESCRIPTORS_PER_TX_MSG;
if (sz > MSG_TOKEN_MAX) {
- dev_info_once(dev,
- "%s virtqueue could hold %d messages. Only %ld allowed to be pending.\n",
- channels[i].is_rx ? "rx" : "tx",
- sz, MSG_TOKEN_MAX);
+ dev_info(dev,
+ "%s virtqueue could hold %d messages. Only %ld allowed to be pending.\n",
+ channels[i].is_rx ? "rx" : "tx",
+ sz, MSG_TOKEN_MAX);
sz = MSG_TOKEN_MAX;
}
channels[i].max_msg = sz;
@@ -460,12 +878,13 @@ static void scmi_vio_remove(struct virtio_device *vdev)
static int scmi_vio_validate(struct virtio_device *vdev)
{
+#ifdef CONFIG_ARM_SCMI_TRANSPORT_VIRTIO_VERSION1_COMPLIANCE
if (!virtio_has_feature(vdev, VIRTIO_F_VERSION_1)) {
dev_err(&vdev->dev,
"device does not comply with spec version 1.x\n");
return -EINVAL;
}
-
+#endif
return 0;
}
@@ -503,7 +922,9 @@ const struct scmi_desc scmi_virtio_desc = {
.transport_init = virtio_scmi_init,
.transport_exit = virtio_scmi_exit,
.ops = &scmi_virtio_ops,
- .max_rx_timeout_ms = 60000, /* for non-realtime virtio devices */
+ /* for non-realtime virtio devices */
+ .max_rx_timeout_ms = VIRTIO_MAX_RX_TIMEOUT_MS,
.max_msg = 0, /* overridden by virtio_get_max_msg() */
.max_msg_size = VIRTIO_SCMI_MAX_MSG_SIZE,
+ .atomic_enabled = IS_ENABLED(CONFIG_ARM_SCMI_TRANSPORT_VIRTIO_ATOMIC_ENABLE),
};
diff --git a/drivers/firmware/arm_sdei.c b/drivers/firmware/arm_sdei.c
index a7e762c352f9..1e1a51510e83 100644
--- a/drivers/firmware/arm_sdei.c
+++ b/drivers/firmware/arm_sdei.c
@@ -1059,14 +1059,14 @@ static bool __init sdei_present_acpi(void)
return true;
}
-static int __init sdei_init(void)
+void __init sdei_init(void)
{
struct platform_device *pdev;
int ret;
ret = platform_driver_register(&sdei_driver);
if (ret || !sdei_present_acpi())
- return ret;
+ return;
pdev = platform_device_register_simple(sdei_driver.driver.name,
0, NULL, 0);
@@ -1076,17 +1076,8 @@ static int __init sdei_init(void)
pr_info("Failed to register ACPI:SDEI platform device %d\n",
ret);
}
-
- return ret;
}
-/*
- * On an ACPI system SDEI needs to be ready before HEST:GHES tries to register
- * its events. ACPI is initialised from a subsys_initcall(), GHES is initialised
- * by device_initcall(). We want to be called in the middle.
- */
-subsys_initcall_sync(sdei_init);
-
int sdei_event_handler(struct pt_regs *regs,
struct sdei_registered_event *arg)
{
diff --git a/drivers/firmware/efi/apple-properties.c b/drivers/firmware/efi/apple-properties.c
index 4c3201e290e2..ea84108035eb 100644
--- a/drivers/firmware/efi/apple-properties.c
+++ b/drivers/firmware/efi/apple-properties.c
@@ -24,7 +24,7 @@ static bool dump_properties __initdata;
static int __init dump_properties_enable(char *arg)
{
dump_properties = true;
- return 0;
+ return 1;
}
__setup("dump_apple_properties", dump_properties_enable);
diff --git a/drivers/firmware/efi/efi-pstore.c b/drivers/firmware/efi/efi-pstore.c
index 0ef086e43090..7e771c56c13c 100644
--- a/drivers/firmware/efi/efi-pstore.c
+++ b/drivers/firmware/efi/efi-pstore.c
@@ -266,7 +266,7 @@ static int efi_pstore_write(struct pstore_record *record)
efi_name[i] = name[i];
ret = efivar_entry_set_safe(efi_name, vendor, PSTORE_EFI_ATTRIBUTES,
- preemptible(), record->size, record->psi->buf);
+ false, record->size, record->psi->buf);
if (record->reason == KMSG_DUMP_OOPS && try_module_get(THIS_MODULE))
if (!schedule_work(&efivar_work))
diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c
index ae79c3300129..5502e176d51b 100644
--- a/drivers/firmware/efi/efi.c
+++ b/drivers/firmware/efi/efi.c
@@ -212,7 +212,7 @@ static int __init efivar_ssdt_setup(char *str)
memcpy(efivar_ssdt, str, strlen(str));
else
pr_warn("efivar_ssdt: name too long: %s\n", str);
- return 0;
+ return 1;
}
__setup("efivar_ssdt=", efivar_ssdt_setup);
@@ -722,6 +722,13 @@ void __init efi_systab_report_header(const efi_table_hdr_t *systab_hdr,
systab_hdr->revision >> 16,
systab_hdr->revision & 0xffff,
vendor);
+
+ if (IS_ENABLED(CONFIG_X86_64) &&
+ systab_hdr->revision > EFI_1_10_SYSTEM_TABLE_REVISION &&
+ !strcmp(vendor, "Apple")) {
+ pr_info("Apple Mac detected, using EFI v1.10 runtime services only\n");
+ efi.runtime_version = EFI_1_10_SYSTEM_TABLE_REVISION;
+ }
}
static __initdata char memory_type_name[][13] = {
diff --git a/drivers/firmware/efi/libstub/arm64-stub.c b/drivers/firmware/efi/libstub/arm64-stub.c
index 2363fee9211c..9cc556013d08 100644
--- a/drivers/firmware/efi/libstub/arm64-stub.c
+++ b/drivers/firmware/efi/libstub/arm64-stub.c
@@ -119,9 +119,9 @@ efi_status_t handle_kernel_image(unsigned long *image_addr,
if (image->image_base != _text)
efi_err("FIRMWARE BUG: efi_loaded_image_t::image_base has bogus value\n");
- if (!IS_ALIGNED((u64)_text, EFI_KIMG_ALIGN))
- efi_err("FIRMWARE BUG: kernel image not aligned on %ldk boundary\n",
- EFI_KIMG_ALIGN >> 10);
+ if (!IS_ALIGNED((u64)_text, SEGMENT_ALIGN))
+ efi_err("FIRMWARE BUG: kernel image not aligned on %dk boundary\n",
+ SEGMENT_ALIGN >> 10);
kernel_size = _edata - _text;
kernel_memsize = kernel_size + (_end - _edata);
diff --git a/drivers/firmware/efi/libstub/riscv-stub.c b/drivers/firmware/efi/libstub/riscv-stub.c
index 380e4e251399..9c460843442f 100644
--- a/drivers/firmware/efi/libstub/riscv-stub.c
+++ b/drivers/firmware/efi/libstub/riscv-stub.c
@@ -25,7 +25,7 @@ typedef void __noreturn (*jump_kernel_func)(unsigned int, unsigned long);
static u32 hartid;
-static u32 get_boot_hartid_from_fdt(void)
+static int get_boot_hartid_from_fdt(void)
{
const void *fdt;
int chosen_node, len;
@@ -33,23 +33,26 @@ static u32 get_boot_hartid_from_fdt(void)
fdt = get_efi_config_table(DEVICE_TREE_GUID);
if (!fdt)
- return U32_MAX;
+ return -EINVAL;
chosen_node = fdt_path_offset(fdt, "/chosen");
if (chosen_node < 0)
- return U32_MAX;
+ return -EINVAL;
prop = fdt_getprop((void *)fdt, chosen_node, "boot-hartid", &len);
if (!prop || len != sizeof(u32))
- return U32_MAX;
+ return -EINVAL;
- return fdt32_to_cpu(*prop);
+ hartid = fdt32_to_cpu(*prop);
+ return 0;
}
efi_status_t check_platform_features(void)
{
- hartid = get_boot_hartid_from_fdt();
- if (hartid == U32_MAX) {
+ int ret;
+
+ ret = get_boot_hartid_from_fdt();
+ if (ret) {
efi_err("/chosen/boot-hartid missing or invalid!\n");
return EFI_UNSUPPORTED;
}
diff --git a/drivers/firmware/efi/mokvar-table.c b/drivers/firmware/efi/mokvar-table.c
index 38722d2009e2..5ed0602c2f75 100644
--- a/drivers/firmware/efi/mokvar-table.c
+++ b/drivers/firmware/efi/mokvar-table.c
@@ -359,4 +359,4 @@ static int __init efi_mokvar_sysfs_init(void)
}
return err;
}
-device_initcall(efi_mokvar_sysfs_init);
+fs_initcall(efi_mokvar_sysfs_init);
diff --git a/drivers/firmware/efi/vars.c b/drivers/firmware/efi/vars.c
index abdc8a6a3963..cae590bd08f2 100644
--- a/drivers/firmware/efi/vars.c
+++ b/drivers/firmware/efi/vars.c
@@ -742,6 +742,7 @@ int efivar_entry_set_safe(efi_char16_t *name, efi_guid_t vendor, u32 attributes,
{
const struct efivar_operations *ops;
efi_status_t status;
+ unsigned long varsize;
if (!__efivars)
return -EINVAL;
@@ -764,15 +765,17 @@ int efivar_entry_set_safe(efi_char16_t *name, efi_guid_t vendor, u32 attributes,
return efivar_entry_set_nonblocking(name, vendor, attributes,
size, data);
+ varsize = size + ucs2_strsize(name, 1024);
if (!block) {
if (down_trylock(&efivars_lock))
return -EBUSY;
+ status = check_var_size_nonblocking(attributes, varsize);
} else {
if (down_interruptible(&efivars_lock))
return -EINTR;
+ status = check_var_size(attributes, varsize);
}
- status = check_var_size(attributes, size + ucs2_strsize(name, 1024));
if (status != EFI_SUCCESS) {
up(&efivars_lock);
return -ENOSPC;
diff --git a/drivers/firmware/imx/rm.c b/drivers/firmware/imx/rm.c
index a12db6ff323b..d492b99e1c6c 100644
--- a/drivers/firmware/imx/rm.c
+++ b/drivers/firmware/imx/rm.c
@@ -43,3 +43,48 @@ bool imx_sc_rm_is_resource_owned(struct imx_sc_ipc *ipc, u16 resource)
return hdr->func;
}
EXPORT_SYMBOL(imx_sc_rm_is_resource_owned);
+
+struct imx_sc_msg_rm_get_resource_owner {
+ struct imx_sc_rpc_msg hdr;
+ union {
+ struct {
+ u16 resource;
+ } req;
+ struct {
+ u8 val;
+ } resp;
+ } data;
+} __packed __aligned(4);
+
+/*
+ * This function get @resource partition number
+ *
+ * @param[in] ipc IPC handle
+ * @param[in] resource resource the control is associated with
+ * @param[out] pt pointer to return the partition number
+ *
+ * @return Returns 0 for success and < 0 for errors.
+ */
+int imx_sc_rm_get_resource_owner(struct imx_sc_ipc *ipc, u16 resource, u8 *pt)
+{
+ struct imx_sc_msg_rm_get_resource_owner msg;
+ struct imx_sc_rpc_msg *hdr = &msg.hdr;
+ int ret;
+
+ hdr->ver = IMX_SC_RPC_VERSION;
+ hdr->svc = IMX_SC_RPC_SVC_RM;
+ hdr->func = IMX_SC_RM_FUNC_GET_RESOURCE_OWNER;
+ hdr->size = 2;
+
+ msg.data.req.resource = resource;
+
+ ret = imx_scu_call_rpc(ipc, &msg, true);
+ if (ret)
+ return ret;
+
+ if (pt)
+ *pt = msg.data.resp.val;
+
+ return 0;
+}
+EXPORT_SYMBOL(imx_sc_rm_get_resource_owner);
diff --git a/drivers/firmware/imx/scu-pd.c b/drivers/firmware/imx/scu-pd.c
index ff6569c4a53b..af3d057e6421 100644
--- a/drivers/firmware/imx/scu-pd.c
+++ b/drivers/firmware/imx/scu-pd.c
@@ -155,6 +155,10 @@ static const struct imx_sc_pd_range imx8qxp_scu_pd_ranges[] = {
{ "vpu-pid", IMX_SC_R_VPU_PID0, 8, true, 0 },
{ "vpu-dec0", IMX_SC_R_VPU_DEC_0, 1, false, 0 },
{ "vpu-enc0", IMX_SC_R_VPU_ENC_0, 1, false, 0 },
+ { "vpu-enc1", IMX_SC_R_VPU_ENC_1, 1, false, 0 },
+ { "vpu-mu0", IMX_SC_R_VPU_MU_0, 1, false, 0 },
+ { "vpu-mu1", IMX_SC_R_VPU_MU_1, 1, false, 0 },
+ { "vpu-mu2", IMX_SC_R_VPU_MU_2, 1, false, 0 },
/* GPU SS */
{ "gpu0-pid", IMX_SC_R_GPU_0_PID0, 4, true, 0 },
diff --git a/drivers/firmware/qcom_scm.c b/drivers/firmware/qcom_scm.c
index 7db8066b19fd..491bbf70c94a 100644
--- a/drivers/firmware/qcom_scm.c
+++ b/drivers/firmware/qcom_scm.c
@@ -49,26 +49,12 @@ struct qcom_scm_mem_map_info {
__le64 mem_size;
};
-#define QCOM_SCM_FLAG_COLDBOOT_CPU0 0x00
-#define QCOM_SCM_FLAG_COLDBOOT_CPU1 0x01
-#define QCOM_SCM_FLAG_COLDBOOT_CPU2 0x08
-#define QCOM_SCM_FLAG_COLDBOOT_CPU3 0x20
-
-#define QCOM_SCM_FLAG_WARMBOOT_CPU0 0x04
-#define QCOM_SCM_FLAG_WARMBOOT_CPU1 0x02
-#define QCOM_SCM_FLAG_WARMBOOT_CPU2 0x10
-#define QCOM_SCM_FLAG_WARMBOOT_CPU3 0x40
-
-struct qcom_scm_wb_entry {
- int flag;
- void *entry;
+/* Each bit configures cold/warm boot address for one of the 4 CPUs */
+static const u8 qcom_scm_cpu_cold_bits[QCOM_SCM_BOOT_MAX_CPUS] = {
+ 0, BIT(0), BIT(3), BIT(5)
};
-
-static struct qcom_scm_wb_entry qcom_scm_wb[] = {
- { .flag = QCOM_SCM_FLAG_WARMBOOT_CPU0 },
- { .flag = QCOM_SCM_FLAG_WARMBOOT_CPU1 },
- { .flag = QCOM_SCM_FLAG_WARMBOOT_CPU2 },
- { .flag = QCOM_SCM_FLAG_WARMBOOT_CPU3 },
+static const u8 qcom_scm_cpu_warm_bits[QCOM_SCM_BOOT_MAX_CPUS] = {
+ BIT(2), BIT(1), BIT(4), BIT(6)
};
static const char * const qcom_scm_convention_names[] = {
@@ -179,9 +165,8 @@ found:
/**
* qcom_scm_call() - Invoke a syscall in the secure world
* @dev: device
- * @svc_id: service identifier
- * @cmd_id: command identifier
* @desc: Descriptor structure containing arguments and return values
+ * @res: Structure containing results from SMC/HVC call
*
* Sends a command to the SCM and waits for the command to finish processing.
* This should *only* be called in pre-emptible context.
@@ -205,8 +190,6 @@ static int qcom_scm_call(struct device *dev, const struct qcom_scm_desc *desc,
/**
* qcom_scm_call_atomic() - atomic variation of qcom_scm_call()
* @dev: device
- * @svc_id: service identifier
- * @cmd_id: command identifier
* @desc: Descriptor structure containing arguments and return values
* @res: Structure containing results from SMC/HVC call
*
@@ -260,97 +243,83 @@ static bool __qcom_scm_is_call_available(struct device *dev, u32 svc_id,
return ret ? false : !!res.result[0];
}
-/**
- * qcom_scm_set_warm_boot_addr() - Set the warm boot address for cpus
- * @entry: Entry point function for the cpus
- * @cpus: The cpumask of cpus that will use the entry point
- *
- * Set the Linux entry point for the SCM to transfer control to when coming
- * out of a power down. CPU power down may be executed on cpuidle or hotplug.
- */
-int qcom_scm_set_warm_boot_addr(void *entry, const cpumask_t *cpus)
+static int qcom_scm_set_boot_addr(void *entry, const u8 *cpu_bits)
{
- int ret;
- int flags = 0;
int cpu;
+ unsigned int flags = 0;
struct qcom_scm_desc desc = {
.svc = QCOM_SCM_SVC_BOOT,
.cmd = QCOM_SCM_BOOT_SET_ADDR,
.arginfo = QCOM_SCM_ARGS(2),
+ .owner = ARM_SMCCC_OWNER_SIP,
};
- /*
- * Reassign only if we are switching from hotplug entry point
- * to cpuidle entry point or vice versa.
- */
- for_each_cpu(cpu, cpus) {
- if (entry == qcom_scm_wb[cpu].entry)
- continue;
- flags |= qcom_scm_wb[cpu].flag;
+ for_each_present_cpu(cpu) {
+ if (cpu >= QCOM_SCM_BOOT_MAX_CPUS)
+ return -EINVAL;
+ flags |= cpu_bits[cpu];
}
- /* No change in entry function */
- if (!flags)
- return 0;
-
desc.args[0] = flags;
desc.args[1] = virt_to_phys(entry);
- ret = qcom_scm_call(__scm->dev, &desc, NULL);
- if (!ret) {
- for_each_cpu(cpu, cpus)
- qcom_scm_wb[cpu].entry = entry;
- }
-
- return ret;
+ return qcom_scm_call_atomic(__scm ? __scm->dev : NULL, &desc, NULL);
}
-EXPORT_SYMBOL(qcom_scm_set_warm_boot_addr);
-/**
- * qcom_scm_set_cold_boot_addr() - Set the cold boot address for cpus
- * @entry: Entry point function for the cpus
- * @cpus: The cpumask of cpus that will use the entry point
- *
- * Set the cold boot address of the cpus. Any cpu outside the supported
- * range would be removed from the cpu present mask.
- */
-int qcom_scm_set_cold_boot_addr(void *entry, const cpumask_t *cpus)
+static int qcom_scm_set_boot_addr_mc(void *entry, unsigned int flags)
{
- int flags = 0;
- int cpu;
- int scm_cb_flags[] = {
- QCOM_SCM_FLAG_COLDBOOT_CPU0,
- QCOM_SCM_FLAG_COLDBOOT_CPU1,
- QCOM_SCM_FLAG_COLDBOOT_CPU2,
- QCOM_SCM_FLAG_COLDBOOT_CPU3,
- };
struct qcom_scm_desc desc = {
.svc = QCOM_SCM_SVC_BOOT,
- .cmd = QCOM_SCM_BOOT_SET_ADDR,
- .arginfo = QCOM_SCM_ARGS(2),
+ .cmd = QCOM_SCM_BOOT_SET_ADDR_MC,
.owner = ARM_SMCCC_OWNER_SIP,
+ .arginfo = QCOM_SCM_ARGS(6),
+ .args = {
+ virt_to_phys(entry),
+ /* Apply to all CPUs in all affinity levels */
+ ~0ULL, ~0ULL, ~0ULL, ~0ULL,
+ flags,
+ },
};
- if (!cpus || cpumask_empty(cpus))
- return -EINVAL;
+ /* Need a device for DMA of the additional arguments */
+ if (!__scm || __get_convention() == SMC_CONVENTION_LEGACY)
+ return -EOPNOTSUPP;
- for_each_cpu(cpu, cpus) {
- if (cpu < ARRAY_SIZE(scm_cb_flags))
- flags |= scm_cb_flags[cpu];
- else
- set_cpu_present(cpu, false);
- }
+ return qcom_scm_call(__scm->dev, &desc, NULL);
+}
- desc.args[0] = flags;
- desc.args[1] = virt_to_phys(entry);
+/**
+ * qcom_scm_set_warm_boot_addr() - Set the warm boot address for all cpus
+ * @entry: Entry point function for the cpus
+ *
+ * Set the Linux entry point for the SCM to transfer control to when coming
+ * out of a power down. CPU power down may be executed on cpuidle or hotplug.
+ */
+int qcom_scm_set_warm_boot_addr(void *entry)
+{
+ if (qcom_scm_set_boot_addr_mc(entry, QCOM_SCM_BOOT_MC_FLAG_WARMBOOT))
+ /* Fallback to old SCM call */
+ return qcom_scm_set_boot_addr(entry, qcom_scm_cpu_warm_bits);
+ return 0;
+}
+EXPORT_SYMBOL(qcom_scm_set_warm_boot_addr);
- return qcom_scm_call_atomic(__scm ? __scm->dev : NULL, &desc, NULL);
+/**
+ * qcom_scm_set_cold_boot_addr() - Set the cold boot address for all cpus
+ * @entry: Entry point function for the cpus
+ */
+int qcom_scm_set_cold_boot_addr(void *entry)
+{
+ if (qcom_scm_set_boot_addr_mc(entry, QCOM_SCM_BOOT_MC_FLAG_COLDBOOT))
+ /* Fallback to old SCM call */
+ return qcom_scm_set_boot_addr(entry, qcom_scm_cpu_cold_bits);
+ return 0;
}
EXPORT_SYMBOL(qcom_scm_set_cold_boot_addr);
/**
* qcom_scm_cpu_power_down() - Power down the cpu
- * @flags - Flags to flush cache
+ * @flags: Flags to flush cache
*
* This is an end point to power down cpu. If there was a pending interrupt,
* the control would return from this function, otherwise, the cpu jumps to the
@@ -435,10 +404,16 @@ static void qcom_scm_set_download_mode(bool enable)
* and optional blob of data used for authenticating the metadata
* and the rest of the firmware
* @size: size of the metadata
+ * @ctx: optional metadata context
*
- * Returns 0 on success.
+ * Return: 0 on success.
+ *
+ * Upon successful return, the PAS metadata context (@ctx) will be used to
+ * track the metadata allocation, this needs to be released by invoking
+ * qcom_scm_pas_metadata_release() by the caller.
*/
-int qcom_scm_pas_init_image(u32 peripheral, const void *metadata, size_t size)
+int qcom_scm_pas_init_image(u32 peripheral, const void *metadata, size_t size,
+ struct qcom_scm_pas_metadata *ctx)
{
dma_addr_t mdata_phys;
void *mdata_buf;
@@ -467,7 +442,7 @@ int qcom_scm_pas_init_image(u32 peripheral, const void *metadata, size_t size)
ret = qcom_scm_clk_enable();
if (ret)
- goto free_metadata;
+ goto out;
desc.args[1] = mdata_phys;
@@ -475,14 +450,37 @@ int qcom_scm_pas_init_image(u32 peripheral, const void *metadata, size_t size)
qcom_scm_clk_disable();
-free_metadata:
- dma_free_coherent(__scm->dev, size, mdata_buf, mdata_phys);
+out:
+ if (ret < 0 || !ctx) {
+ dma_free_coherent(__scm->dev, size, mdata_buf, mdata_phys);
+ } else if (ctx) {
+ ctx->ptr = mdata_buf;
+ ctx->phys = mdata_phys;
+ ctx->size = size;
+ }
return ret ? : res.result[0];
}
EXPORT_SYMBOL(qcom_scm_pas_init_image);
/**
+ * qcom_scm_pas_metadata_release() - release metadata context
+ * @ctx: metadata context
+ */
+void qcom_scm_pas_metadata_release(struct qcom_scm_pas_metadata *ctx)
+{
+ if (!ctx->ptr)
+ return;
+
+ dma_free_coherent(__scm->dev, ctx->size, ctx->ptr, ctx->phys);
+
+ ctx->ptr = NULL;
+ ctx->phys = 0;
+ ctx->size = 0;
+}
+EXPORT_SYMBOL(qcom_scm_pas_metadata_release);
+
+/**
* qcom_scm_pas_mem_setup() - Prepare the memory related to a given peripheral
* for firmware loading
* @peripheral: peripheral id
@@ -749,12 +747,6 @@ int qcom_scm_iommu_secure_ptbl_init(u64 addr, u32 size, u32 spare)
};
int ret;
- desc.args[0] = addr;
- desc.args[1] = size;
- desc.args[2] = spare;
- desc.arginfo = QCOM_SCM_ARGS(3, QCOM_SCM_RW, QCOM_SCM_VAL,
- QCOM_SCM_VAL);
-
ret = qcom_scm_call(__scm->dev, &desc, NULL);
/* the pg table has been initialized already, ignore the error */
@@ -765,6 +757,21 @@ int qcom_scm_iommu_secure_ptbl_init(u64 addr, u32 size, u32 spare)
}
EXPORT_SYMBOL(qcom_scm_iommu_secure_ptbl_init);
+int qcom_scm_iommu_set_cp_pool_size(u32 spare, u32 size)
+{
+ struct qcom_scm_desc desc = {
+ .svc = QCOM_SCM_SVC_MP,
+ .cmd = QCOM_SCM_MP_IOMMU_SET_CP_POOL_SIZE,
+ .arginfo = QCOM_SCM_ARGS(2),
+ .args[0] = size,
+ .args[1] = spare,
+ .owner = ARM_SMCCC_OWNER_SIP,
+ };
+
+ return qcom_scm_call(__scm->dev, &desc, NULL);
+}
+EXPORT_SYMBOL(qcom_scm_iommu_set_cp_pool_size);
+
int qcom_scm_mem_protect_video_var(u32 cp_start, u32 cp_size,
u32 cp_nonpixel_start,
u32 cp_nonpixel_size)
@@ -1131,6 +1138,22 @@ int qcom_scm_hdcp_req(struct qcom_scm_hdcp_req *req, u32 req_cnt, u32 *resp)
}
EXPORT_SYMBOL(qcom_scm_hdcp_req);
+int qcom_scm_iommu_set_pt_format(u32 sec_id, u32 ctx_num, u32 pt_fmt)
+{
+ struct qcom_scm_desc desc = {
+ .svc = QCOM_SCM_SVC_SMMU_PROGRAM,
+ .cmd = QCOM_SCM_SMMU_PT_FORMAT,
+ .arginfo = QCOM_SCM_ARGS(3),
+ .args[0] = sec_id,
+ .args[1] = ctx_num,
+ .args[2] = pt_fmt, /* 0: LPAE AArch32 - 1: AArch64 */
+ .owner = ARM_SMCCC_OWNER_SIP,
+ };
+
+ return qcom_scm_call(__scm->dev, &desc, NULL);
+}
+EXPORT_SYMBOL(qcom_scm_iommu_set_pt_format);
+
int qcom_scm_qsmmu500_wait_safe_toggle(bool en)
{
struct qcom_scm_desc desc = {
diff --git a/drivers/firmware/qcom_scm.h b/drivers/firmware/qcom_scm.h
index d92156ceb3ac..0d51eef2472f 100644
--- a/drivers/firmware/qcom_scm.h
+++ b/drivers/firmware/qcom_scm.h
@@ -78,8 +78,13 @@ extern int scm_legacy_call(struct device *dev, const struct qcom_scm_desc *desc,
#define QCOM_SCM_BOOT_SET_ADDR 0x01
#define QCOM_SCM_BOOT_TERMINATE_PC 0x02
#define QCOM_SCM_BOOT_SET_DLOAD_MODE 0x10
+#define QCOM_SCM_BOOT_SET_ADDR_MC 0x11
#define QCOM_SCM_BOOT_SET_REMOTE_STATE 0x0a
#define QCOM_SCM_FLUSH_FLAG_MASK 0x3
+#define QCOM_SCM_BOOT_MAX_CPUS 4
+#define QCOM_SCM_BOOT_MC_FLAG_AARCH64 BIT(0)
+#define QCOM_SCM_BOOT_MC_FLAG_COLDBOOT BIT(1)
+#define QCOM_SCM_BOOT_MC_FLAG_WARMBOOT BIT(2)
#define QCOM_SCM_SVC_PIL 0x02
#define QCOM_SCM_PIL_PAS_INIT_IMAGE 0x01
@@ -100,6 +105,7 @@ extern int scm_legacy_call(struct device *dev, const struct qcom_scm_desc *desc,
#define QCOM_SCM_MP_RESTORE_SEC_CFG 0x02
#define QCOM_SCM_MP_IOMMU_SECURE_PTBL_SIZE 0x03
#define QCOM_SCM_MP_IOMMU_SECURE_PTBL_INIT 0x04
+#define QCOM_SCM_MP_IOMMU_SET_CP_POOL_SIZE 0x05
#define QCOM_SCM_MP_VIDEO_VAR 0x08
#define QCOM_SCM_MP_ASSIGN 0x16
@@ -119,6 +125,7 @@ extern int scm_legacy_call(struct device *dev, const struct qcom_scm_desc *desc,
#define QCOM_SCM_LMH_LIMIT_DCVSH 0x10
#define QCOM_SCM_SVC_SMMU_PROGRAM 0x15
+#define QCOM_SCM_SMMU_PT_FORMAT 0x01
#define QCOM_SCM_SMMU_CONFIG_ERRATA1 0x03
#define QCOM_SCM_SMMU_CONFIG_ERRATA1_CLIENT_ALL 0x02
diff --git a/drivers/firmware/sysfb_simplefb.c b/drivers/firmware/sysfb_simplefb.c
index 303a491e520d..76c4abc42a30 100644
--- a/drivers/firmware/sysfb_simplefb.c
+++ b/drivers/firmware/sysfb_simplefb.c
@@ -99,7 +99,7 @@ __init int sysfb_create_simplefb(const struct screen_info *si,
/* setup IORESOURCE_MEM as framebuffer memory */
memset(&res, 0, sizeof(res));
- res.flags = IORESOURCE_MEM | IORESOURCE_BUSY;
+ res.flags = IORESOURCE_MEM;
res.name = simplefb_resname;
res.start = base;
res.end = res.start + length - 1;
diff --git a/drivers/firmware/ti_sci.c b/drivers/firmware/ti_sci.c
index 5ae2040b8b02..4697edc125b1 100644
--- a/drivers/firmware/ti_sci.c
+++ b/drivers/firmware/ti_sci.c
@@ -3412,7 +3412,7 @@ static int ti_sci_probe(struct platform_device *pdev)
ret = register_restart_handler(&info->nb);
if (ret) {
dev_err(dev, "reboot registration fail(%d)\n", ret);
- return ret;
+ goto out;
}
}
diff --git a/drivers/firmware/xilinx/zynqmp.c b/drivers/firmware/xilinx/zynqmp.c
index 450c5f6a1cbf..5e5b0bb2e4e0 100644
--- a/drivers/firmware/xilinx/zynqmp.c
+++ b/drivers/firmware/xilinx/zynqmp.c
@@ -1121,6 +1121,32 @@ int zynqmp_pm_aes_engine(const u64 address, u32 *out)
EXPORT_SYMBOL_GPL(zynqmp_pm_aes_engine);
/**
+ * zynqmp_pm_sha_hash - Access the SHA engine to calculate the hash
+ * @address: Address of the data/ Address of output buffer where
+ * hash should be stored.
+ * @size: Size of the data.
+ * @flags:
+ * BIT(0) - for initializing csudma driver and SHA3(Here address
+ * and size inputs can be NULL).
+ * BIT(1) - to call Sha3_Update API which can be called multiple
+ * times when data is not contiguous.
+ * BIT(2) - to get final hash of the whole updated data.
+ * Hash will be overwritten at provided address with
+ * 48 bytes.
+ *
+ * Return: Returns status, either success or error code.
+ */
+int zynqmp_pm_sha_hash(const u64 address, const u32 size, const u32 flags)
+{
+ u32 lower_addr = lower_32_bits(address);
+ u32 upper_addr = upper_32_bits(address);
+
+ return zynqmp_pm_invoke_fn(PM_SECURE_SHA, upper_addr, lower_addr,
+ size, flags, NULL);
+}
+EXPORT_SYMBOL_GPL(zynqmp_pm_sha_hash);
+
+/**
* zynqmp_pm_register_notifier() - PM API for register a subsystem
* to be notified about specific
* event/error.
diff --git a/drivers/gpio/gpio-74x164.c b/drivers/gpio/gpio-74x164.c
index 4a55cdf089d6..e00c33310517 100644
--- a/drivers/gpio/gpio-74x164.c
+++ b/drivers/gpio/gpio-74x164.c
@@ -163,15 +163,13 @@ exit_destroy:
return ret;
}
-static int gen_74x164_remove(struct spi_device *spi)
+static void gen_74x164_remove(struct spi_device *spi)
{
struct gen_74x164_chip *chip = spi_get_drvdata(spi);
gpiod_set_value_cansleep(chip->gpiod_oe, 0);
gpiochip_remove(&chip->gpio_chip);
mutex_destroy(&chip->lock);
-
- return 0;
}
static const struct spi_device_id gen_74x164_spi_ids[] = {
diff --git a/drivers/gpio/gpio-aggregator.c b/drivers/gpio/gpio-aggregator.c
index 869dc952cf45..0cb2664085cf 100644
--- a/drivers/gpio/gpio-aggregator.c
+++ b/drivers/gpio/gpio-aggregator.c
@@ -278,7 +278,8 @@ static int gpio_fwd_get(struct gpio_chip *chip, unsigned int offset)
{
struct gpiochip_fwd *fwd = gpiochip_get_data(chip);
- return gpiod_get_value(fwd->descs[offset]);
+ return chip->can_sleep ? gpiod_get_value_cansleep(fwd->descs[offset])
+ : gpiod_get_value(fwd->descs[offset]);
}
static int gpio_fwd_get_multiple(struct gpiochip_fwd *fwd, unsigned long *mask,
@@ -293,7 +294,10 @@ static int gpio_fwd_get_multiple(struct gpiochip_fwd *fwd, unsigned long *mask,
for_each_set_bit(i, mask, fwd->chip.ngpio)
descs[j++] = fwd->descs[i];
- error = gpiod_get_array_value(j, descs, NULL, values);
+ if (fwd->chip.can_sleep)
+ error = gpiod_get_array_value_cansleep(j, descs, NULL, values);
+ else
+ error = gpiod_get_array_value(j, descs, NULL, values);
if (error)
return error;
@@ -328,7 +332,10 @@ static void gpio_fwd_set(struct gpio_chip *chip, unsigned int offset, int value)
{
struct gpiochip_fwd *fwd = gpiochip_get_data(chip);
- gpiod_set_value(fwd->descs[offset], value);
+ if (chip->can_sleep)
+ gpiod_set_value_cansleep(fwd->descs[offset], value);
+ else
+ gpiod_set_value(fwd->descs[offset], value);
}
static void gpio_fwd_set_multiple(struct gpiochip_fwd *fwd, unsigned long *mask,
@@ -343,7 +350,10 @@ static void gpio_fwd_set_multiple(struct gpiochip_fwd *fwd, unsigned long *mask,
descs[j++] = fwd->descs[i];
}
- gpiod_set_array_value(j, descs, NULL, values);
+ if (fwd->chip.can_sleep)
+ gpiod_set_array_value_cansleep(j, descs, NULL, values);
+ else
+ gpiod_set_array_value(j, descs, NULL, values);
}
static void gpio_fwd_set_multiple_locked(struct gpio_chip *chip,
diff --git a/drivers/gpio/gpio-max3191x.c b/drivers/gpio/gpio-max3191x.c
index 51cd6f98d1c7..161c4751c5f7 100644
--- a/drivers/gpio/gpio-max3191x.c
+++ b/drivers/gpio/gpio-max3191x.c
@@ -443,14 +443,12 @@ static int max3191x_probe(struct spi_device *spi)
return 0;
}
-static int max3191x_remove(struct spi_device *spi)
+static void max3191x_remove(struct spi_device *spi)
{
struct max3191x_chip *max3191x = spi_get_drvdata(spi);
gpiochip_remove(&max3191x->gpio);
mutex_destroy(&max3191x->lock);
-
- return 0;
}
static int __init max3191x_register_driver(struct spi_driver *sdrv)
diff --git a/drivers/gpio/gpio-max7301.c b/drivers/gpio/gpio-max7301.c
index 5862d73bf325..11813f41d460 100644
--- a/drivers/gpio/gpio-max7301.c
+++ b/drivers/gpio/gpio-max7301.c
@@ -64,11 +64,9 @@ static int max7301_probe(struct spi_device *spi)
return ret;
}
-static int max7301_remove(struct spi_device *spi)
+static void max7301_remove(struct spi_device *spi)
{
__max730x_remove(&spi->dev);
-
- return 0;
}
static const struct spi_device_id max7301_id[] = {
diff --git a/drivers/gpio/gpio-mc33880.c b/drivers/gpio/gpio-mc33880.c
index 31d2be1bebc8..cd9b16dbe1a9 100644
--- a/drivers/gpio/gpio-mc33880.c
+++ b/drivers/gpio/gpio-mc33880.c
@@ -134,7 +134,7 @@ exit_destroy:
return ret;
}
-static int mc33880_remove(struct spi_device *spi)
+static void mc33880_remove(struct spi_device *spi)
{
struct mc33880 *mc;
@@ -142,8 +142,6 @@ static int mc33880_remove(struct spi_device *spi)
gpiochip_remove(&mc->chip);
mutex_destroy(&mc->lock);
-
- return 0;
}
static struct spi_driver mc33880_driver = {
diff --git a/drivers/gpio/gpio-mt7621.c b/drivers/gpio/gpio-mt7621.c
index ccaad1cb3c2e..d8a26e503ca5 100644
--- a/drivers/gpio/gpio-mt7621.c
+++ b/drivers/gpio/gpio-mt7621.c
@@ -239,7 +239,6 @@ mediatek_gpio_bank_probe(struct device *dev, int bank)
rg->chip.offset = bank * MTK_BANK_WIDTH;
rg->irq_chip.name = dev_name(dev);
- rg->irq_chip.parent_device = dev;
rg->irq_chip.irq_unmask = mediatek_gpio_irq_unmask;
rg->irq_chip.irq_mask = mediatek_gpio_irq_mask;
rg->irq_chip.irq_mask_ack = mediatek_gpio_irq_mask;
diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c
index e099c39e0355..80ddc43fd875 100644
--- a/drivers/gpio/gpio-omap.c
+++ b/drivers/gpio/gpio-omap.c
@@ -986,7 +986,8 @@ static void omap_gpio_mod_init(struct gpio_bank *bank)
writel_relaxed(0, base + bank->regs->ctrl);
}
-static int omap_gpio_chip_init(struct gpio_bank *bank, struct irq_chip *irqc)
+static int omap_gpio_chip_init(struct gpio_bank *bank, struct irq_chip *irqc,
+ struct device *pm_dev)
{
struct gpio_irq_chip *irq;
static int gpio;
@@ -1052,6 +1053,7 @@ static int omap_gpio_chip_init(struct gpio_bank *bank, struct irq_chip *irqc)
if (ret)
return dev_err_probe(bank->chip.parent, ret, "Could not register gpio chip\n");
+ irq_domain_set_pm_device(bank->chip.irq.domain, pm_dev);
ret = devm_request_irq(bank->chip.parent, bank->irq,
omap_gpio_irq_handler,
0, dev_name(bank->chip.parent), bank);
@@ -1402,7 +1404,6 @@ static int omap_gpio_probe(struct platform_device *pdev)
irqc->irq_bus_sync_unlock = gpio_irq_bus_sync_unlock,
irqc->name = dev_name(&pdev->dev);
irqc->flags = IRQCHIP_MASK_ON_SUSPEND;
- irqc->parent_device = dev;
bank->irq = platform_get_irq(pdev, 0);
if (bank->irq <= 0) {
@@ -1466,7 +1467,7 @@ static int omap_gpio_probe(struct platform_device *pdev)
omap_gpio_mod_init(bank);
- ret = omap_gpio_chip_init(bank, irqc);
+ ret = omap_gpio_chip_init(bank, irqc, dev);
if (ret) {
pm_runtime_put_sync(dev);
pm_runtime_disable(dev);
diff --git a/drivers/gpio/gpio-pisosr.c b/drivers/gpio/gpio-pisosr.c
index 8e04054cf07e..81a47ae09ff8 100644
--- a/drivers/gpio/gpio-pisosr.c
+++ b/drivers/gpio/gpio-pisosr.c
@@ -163,15 +163,13 @@ static int pisosr_gpio_probe(struct spi_device *spi)
return 0;
}
-static int pisosr_gpio_remove(struct spi_device *spi)
+static void pisosr_gpio_remove(struct spi_device *spi)
{
struct pisosr_gpio *gpio = spi_get_drvdata(spi);
gpiochip_remove(&gpio->chip);
mutex_destroy(&gpio->lock);
-
- return 0;
}
static const struct spi_device_id pisosr_gpio_id_table[] = {
diff --git a/drivers/gpio/gpio-rcar.c b/drivers/gpio/gpio-rcar.c
index bd2e16d6e21c..3a76538f27fa 100644
--- a/drivers/gpio/gpio-rcar.c
+++ b/drivers/gpio/gpio-rcar.c
@@ -530,7 +530,6 @@ static int gpio_rcar_probe(struct platform_device *pdev)
irq_chip = &p->irq_chip;
irq_chip->name = "gpio-rcar";
- irq_chip->parent_device = dev;
irq_chip->irq_mask = gpio_rcar_irq_disable;
irq_chip->irq_unmask = gpio_rcar_irq_enable;
irq_chip->irq_set_type = gpio_rcar_irq_set_type;
@@ -552,6 +551,7 @@ static int gpio_rcar_probe(struct platform_device *pdev)
goto err0;
}
+ irq_domain_set_pm_device(gpio_chip->irq.domain, dev);
ret = devm_request_irq(dev, p->irq_parent, gpio_rcar_irq_handler,
IRQF_SHARED, name, p);
if (ret) {
diff --git a/drivers/gpio/gpio-rockchip.c b/drivers/gpio/gpio-rockchip.c
index a4c4e4584f5b..099e358d2491 100644
--- a/drivers/gpio/gpio-rockchip.c
+++ b/drivers/gpio/gpio-rockchip.c
@@ -410,10 +410,8 @@ static int rockchip_irq_set_type(struct irq_data *d, unsigned int type)
level = rockchip_gpio_readl(bank, bank->gpio_regs->int_type);
polarity = rockchip_gpio_readl(bank, bank->gpio_regs->int_polarity);
- switch (type) {
- case IRQ_TYPE_EDGE_BOTH:
+ if (type == IRQ_TYPE_EDGE_BOTH) {
if (bank->gpio_type == GPIO_TYPE_V2) {
- bank->toggle_edge_mode &= ~mask;
rockchip_gpio_writel_bit(bank, d->hwirq, 1,
bank->gpio_regs->int_bothedge);
goto out;
@@ -431,30 +429,34 @@ static int rockchip_irq_set_type(struct irq_data *d, unsigned int type)
else
polarity |= mask;
}
- break;
- case IRQ_TYPE_EDGE_RISING:
- bank->toggle_edge_mode &= ~mask;
- level |= mask;
- polarity |= mask;
- break;
- case IRQ_TYPE_EDGE_FALLING:
- bank->toggle_edge_mode &= ~mask;
- level |= mask;
- polarity &= ~mask;
- break;
- case IRQ_TYPE_LEVEL_HIGH:
- bank->toggle_edge_mode &= ~mask;
- level &= ~mask;
- polarity |= mask;
- break;
- case IRQ_TYPE_LEVEL_LOW:
- bank->toggle_edge_mode &= ~mask;
- level &= ~mask;
- polarity &= ~mask;
- break;
- default:
- ret = -EINVAL;
- goto out;
+ } else {
+ if (bank->gpio_type == GPIO_TYPE_V2) {
+ rockchip_gpio_writel_bit(bank, d->hwirq, 0,
+ bank->gpio_regs->int_bothedge);
+ } else {
+ bank->toggle_edge_mode &= ~mask;
+ }
+ switch (type) {
+ case IRQ_TYPE_EDGE_RISING:
+ level |= mask;
+ polarity |= mask;
+ break;
+ case IRQ_TYPE_EDGE_FALLING:
+ level |= mask;
+ polarity &= ~mask;
+ break;
+ case IRQ_TYPE_LEVEL_HIGH:
+ level &= ~mask;
+ polarity |= mask;
+ break;
+ case IRQ_TYPE_LEVEL_LOW:
+ level &= ~mask;
+ polarity &= ~mask;
+ break;
+ default:
+ ret = -EINVAL;
+ goto out;
+ }
}
rockchip_gpio_writel(bank, level, bank->gpio_regs->int_type);
diff --git a/drivers/gpio/gpio-sifive.c b/drivers/gpio/gpio-sifive.c
index 403f9e833d6a..7d82388b4ab7 100644
--- a/drivers/gpio/gpio-sifive.c
+++ b/drivers/gpio/gpio-sifive.c
@@ -223,7 +223,7 @@ static int sifive_gpio_probe(struct platform_device *pdev)
NULL,
chip->base + SIFIVE_GPIO_OUTPUT_EN,
chip->base + SIFIVE_GPIO_INPUT_EN,
- 0);
+ BGPIOF_READ_OUTPUT_REG_SET);
if (ret) {
dev_err(dev, "unable to init generic GPIO\n");
return ret;
diff --git a/drivers/gpio/gpio-sim.c b/drivers/gpio/gpio-sim.c
index 838bbfed11d3..8e5d87984a48 100644
--- a/drivers/gpio/gpio-sim.c
+++ b/drivers/gpio/gpio-sim.c
@@ -547,7 +547,7 @@ struct gpio_sim_bank {
*
* So we need to store the pointer to the parent struct here. We can
* dereference it anywhere we need with no checks and no locking as
- * it's guaranteed to survive the childred and protected by configfs
+ * it's guaranteed to survive the children and protected by configfs
* locks.
*
* Same for other structures.
@@ -570,6 +570,11 @@ static struct gpio_sim_bank *to_gpio_sim_bank(struct config_item *item)
return container_of(group, struct gpio_sim_bank, group);
}
+static bool gpio_sim_bank_has_label(struct gpio_sim_bank *bank)
+{
+ return bank->label && *bank->label;
+}
+
static struct gpio_sim_device *
gpio_sim_bank_get_device(struct gpio_sim_bank *bank)
{
@@ -770,9 +775,15 @@ static int gpio_sim_add_hogs(struct gpio_sim_device *dev)
* point the device doesn't exist yet and so dev_name()
* is not available.
*/
- hog->chip_label = kasprintf(GFP_KERNEL,
- "gpio-sim.%u-%s", dev->id,
- fwnode_get_name(bank->swnode));
+ if (gpio_sim_bank_has_label(bank))
+ hog->chip_label = kstrdup(bank->label,
+ GFP_KERNEL);
+ else
+ hog->chip_label = kasprintf(GFP_KERNEL,
+ "gpio-sim.%u-%s",
+ dev->id,
+ fwnode_get_name(
+ bank->swnode));
if (!hog->chip_label) {
gpio_sim_remove_hogs(dev);
return -ENOMEM;
@@ -816,7 +827,7 @@ gpio_sim_make_bank_swnode(struct gpio_sim_bank *bank,
properties[prop_idx++] = PROPERTY_ENTRY_U32("ngpios", bank->num_lines);
- if (bank->label)
+ if (gpio_sim_bank_has_label(bank))
properties[prop_idx++] = PROPERTY_ENTRY_STRING("gpio-sim,label",
bank->label);
@@ -1311,7 +1322,7 @@ static void gpio_sim_hog_config_item_release(struct config_item *item)
kfree(hog);
}
-struct configfs_item_operations gpio_sim_hog_config_item_ops = {
+static struct configfs_item_operations gpio_sim_hog_config_item_ops = {
.release = gpio_sim_hog_config_item_release,
};
diff --git a/drivers/gpio/gpio-tegra186.c b/drivers/gpio/gpio-tegra186.c
index 34b36a8c035f..031fe105b58e 100644
--- a/drivers/gpio/gpio-tegra186.c
+++ b/drivers/gpio/gpio-tegra186.c
@@ -343,9 +343,12 @@ static int tegra186_gpio_of_xlate(struct gpio_chip *chip,
return offset + pin;
}
+#define to_tegra_gpio(x) container_of((x), struct tegra_gpio, gpio)
+
static void tegra186_irq_ack(struct irq_data *data)
{
- struct tegra_gpio *gpio = irq_data_get_irq_chip_data(data);
+ struct gpio_chip *gc = irq_data_get_irq_chip_data(data);
+ struct tegra_gpio *gpio = to_tegra_gpio(gc);
void __iomem *base;
base = tegra186_gpio_get_base(gpio, data->hwirq);
@@ -357,7 +360,8 @@ static void tegra186_irq_ack(struct irq_data *data)
static void tegra186_irq_mask(struct irq_data *data)
{
- struct tegra_gpio *gpio = irq_data_get_irq_chip_data(data);
+ struct gpio_chip *gc = irq_data_get_irq_chip_data(data);
+ struct tegra_gpio *gpio = to_tegra_gpio(gc);
void __iomem *base;
u32 value;
@@ -372,7 +376,8 @@ static void tegra186_irq_mask(struct irq_data *data)
static void tegra186_irq_unmask(struct irq_data *data)
{
- struct tegra_gpio *gpio = irq_data_get_irq_chip_data(data);
+ struct gpio_chip *gc = irq_data_get_irq_chip_data(data);
+ struct tegra_gpio *gpio = to_tegra_gpio(gc);
void __iomem *base;
u32 value;
@@ -387,7 +392,8 @@ static void tegra186_irq_unmask(struct irq_data *data)
static int tegra186_irq_set_type(struct irq_data *data, unsigned int type)
{
- struct tegra_gpio *gpio = irq_data_get_irq_chip_data(data);
+ struct gpio_chip *gc = irq_data_get_irq_chip_data(data);
+ struct tegra_gpio *gpio = to_tegra_gpio(gc);
void __iomem *base;
u32 value;
@@ -1069,6 +1075,7 @@ static const struct tegra_gpio_soc tegra241_main_soc = {
.ports = tegra241_main_ports,
.name = "tegra241-gpio",
.instance = 0,
+ .num_irqs_per_bank = 8,
};
#define TEGRA241_AON_GPIO_PORT(_name, _bank, _port, _pins) \
@@ -1089,6 +1096,7 @@ static const struct tegra_gpio_soc tegra241_aon_soc = {
.ports = tegra241_aon_ports,
.name = "tegra241-gpio-aon",
.instance = 1,
+ .num_irqs_per_bank = 8,
};
static const struct of_device_id tegra186_gpio_of_match[] = {
diff --git a/drivers/gpio/gpio-tqmx86.c b/drivers/gpio/gpio-tqmx86.c
index 5b103221b58d..fa4bc7481f9a 100644
--- a/drivers/gpio/gpio-tqmx86.c
+++ b/drivers/gpio/gpio-tqmx86.c
@@ -281,7 +281,6 @@ static int tqmx86_gpio_probe(struct platform_device *pdev)
u8 irq_status;
irq_chip->name = chip->label;
- irq_chip->parent_device = &pdev->dev;
irq_chip->irq_mask = tqmx86_gpio_irq_mask;
irq_chip->irq_unmask = tqmx86_gpio_irq_unmask;
irq_chip->irq_set_type = tqmx86_gpio_irq_set_type;
@@ -316,6 +315,8 @@ static int tqmx86_gpio_probe(struct platform_device *pdev)
goto out_pm_dis;
}
+ irq_domain_set_pm_device(girq->domain, dev);
+
dev_info(dev, "GPIO functionality initialized with %d pins\n",
chip->ngpio);
diff --git a/drivers/gpio/gpio-ts4900.c b/drivers/gpio/gpio-ts4900.c
index d885032cf814..d918d2df4de2 100644
--- a/drivers/gpio/gpio-ts4900.c
+++ b/drivers/gpio/gpio-ts4900.c
@@ -1,7 +1,7 @@
/*
* Digital I/O driver for Technologic Systems I2C FPGA Core
*
- * Copyright (C) 2015 Technologic Systems
+ * Copyright (C) 2015, 2018 Technologic Systems
* Copyright (C) 2016 Savoir-Faire Linux
*
* This program is free software; you can redistribute it and/or
@@ -55,19 +55,33 @@ static int ts4900_gpio_direction_input(struct gpio_chip *chip,
{
struct ts4900_gpio_priv *priv = gpiochip_get_data(chip);
- /*
- * This will clear the output enable bit, the other bits are
- * dontcare when this is cleared
+ /* Only clear the OE bit here, requires a RMW. Prevents potential issue
+ * with OE and data getting to the physical pin at different times.
*/
- return regmap_write(priv->regmap, offset, 0);
+ return regmap_update_bits(priv->regmap, offset, TS4900_GPIO_OE, 0);
}
static int ts4900_gpio_direction_output(struct gpio_chip *chip,
unsigned int offset, int value)
{
struct ts4900_gpio_priv *priv = gpiochip_get_data(chip);
+ unsigned int reg;
int ret;
+ /* If changing from an input to an output, we need to first set the
+ * proper data bit to what is requested and then set OE bit. This
+ * prevents a glitch that can occur on the IO line
+ */
+ regmap_read(priv->regmap, offset, &reg);
+ if (!(reg & TS4900_GPIO_OE)) {
+ if (value)
+ reg = TS4900_GPIO_OUT;
+ else
+ reg &= ~TS4900_GPIO_OUT;
+
+ regmap_write(priv->regmap, offset, reg);
+ }
+
if (value)
ret = regmap_write(priv->regmap, offset, TS4900_GPIO_OE |
TS4900_GPIO_OUT);
diff --git a/drivers/gpio/gpiolib-acpi.c b/drivers/gpio/gpiolib-acpi.c
index c0f6a25c3279..a5495ad31c9c 100644
--- a/drivers/gpio/gpiolib-acpi.c
+++ b/drivers/gpio/gpiolib-acpi.c
@@ -307,7 +307,8 @@ static struct gpio_desc *acpi_request_own_gpiod(struct gpio_chip *chip,
if (IS_ERR(desc))
return desc;
- ret = gpio_set_debounce_timeout(desc, agpio->debounce_timeout);
+ /* ACPI uses hundredths of milliseconds units */
+ ret = gpio_set_debounce_timeout(desc, agpio->debounce_timeout * 10);
if (ret)
dev_warn(chip->parent,
"Failed to set debounce-timeout for pin 0x%04X, err %d\n",
@@ -1035,7 +1036,8 @@ int acpi_dev_gpio_irq_get_by(struct acpi_device *adev, const char *name, int ind
if (ret < 0)
return ret;
- ret = gpio_set_debounce_timeout(desc, info.debounce);
+ /* ACPI uses hundredths of milliseconds units */
+ ret = gpio_set_debounce_timeout(desc, info.debounce * 10);
if (ret)
return ret;
diff --git a/drivers/gpio/gpiolib-cdev.c b/drivers/gpio/gpiolib-cdev.c
index c7b5446d01fd..ffa0256cad5a 100644
--- a/drivers/gpio/gpiolib-cdev.c
+++ b/drivers/gpio/gpiolib-cdev.c
@@ -330,7 +330,7 @@ static int linehandle_create(struct gpio_device *gdev, void __user *ip)
goto out_free_lh;
}
- ret = gpiod_request(desc, lh->label);
+ ret = gpiod_request_user(desc, lh->label);
if (ret)
goto out_free_lh;
lh->descs[i] = desc;
@@ -1378,7 +1378,7 @@ static int linereq_create(struct gpio_device *gdev, void __user *ip)
goto out_free_linereq;
}
- ret = gpiod_request(desc, lr->label);
+ ret = gpiod_request_user(desc, lr->label);
if (ret)
goto out_free_linereq;
@@ -1764,7 +1764,7 @@ static int lineevent_create(struct gpio_device *gdev, void __user *ip)
}
}
- ret = gpiod_request(desc, le->label);
+ ret = gpiod_request_user(desc, le->label);
if (ret)
goto out_free_le;
le->desc = desc;
diff --git a/drivers/gpio/gpiolib-sysfs.c b/drivers/gpio/gpiolib-sysfs.c
index 4098bc7f88b7..44c1ad51b3fe 100644
--- a/drivers/gpio/gpiolib-sysfs.c
+++ b/drivers/gpio/gpiolib-sysfs.c
@@ -475,12 +475,9 @@ static ssize_t export_store(struct class *class,
* they may be undone on its behalf too.
*/
- status = gpiod_request(desc, "sysfs");
- if (status) {
- if (status == -EPROBE_DEFER)
- status = -ENODEV;
+ status = gpiod_request_user(desc, "sysfs");
+ if (status)
goto done;
- }
status = gpiod_set_transitory(desc, false);
if (!status) {
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index 3859911b61e9..6630d92e30ad 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -2227,6 +2227,16 @@ static int gpio_set_bias(struct gpio_desc *desc)
return gpio_set_config_with_argument_optional(desc, bias, arg);
}
+/**
+ * gpio_set_debounce_timeout() - Set debounce timeout
+ * @desc: GPIO descriptor to set the debounce timeout
+ * @debounce: Debounce timeout in microseconds
+ *
+ * The function calls the certain GPIO driver to set debounce timeout
+ * in the hardware.
+ *
+ * Returns 0 on success, or negative error code otherwise.
+ */
int gpio_set_debounce_timeout(struct gpio_desc *desc, unsigned int debounce)
{
return gpio_set_config_with_argument_optional(desc,
@@ -3147,6 +3157,16 @@ int gpiod_to_irq(const struct gpio_desc *desc)
return retirq;
}
+#ifdef CONFIG_GPIOLIB_IRQCHIP
+ if (gc->irq.chip) {
+ /*
+ * Avoid race condition with other code, which tries to lookup
+ * an IRQ before the irqchip has been properly registered,
+ * i.e. while gpiochip is still being brought up.
+ */
+ return -EPROBE_DEFER;
+ }
+#endif
return -ENXIO;
}
EXPORT_SYMBOL_GPL(gpiod_to_irq);
diff --git a/drivers/gpio/gpiolib.h b/drivers/gpio/gpiolib.h
index 30bc3f80f83e..c31f4626915d 100644
--- a/drivers/gpio/gpiolib.h
+++ b/drivers/gpio/gpiolib.h
@@ -135,6 +135,18 @@ struct gpio_desc {
int gpiod_request(struct gpio_desc *desc, const char *label);
void gpiod_free(struct gpio_desc *desc);
+
+static inline int gpiod_request_user(struct gpio_desc *desc, const char *label)
+{
+ int ret;
+
+ ret = gpiod_request(desc, label);
+ if (ret == -EPROBE_DEFER)
+ ret = -ENODEV;
+
+ return ret;
+}
+
int gpiod_configure_flags(struct gpio_desc *desc, const char *con_id,
unsigned long lflags, enum gpiod_flags dflags);
int gpio_set_debounce_timeout(struct gpio_desc *desc, unsigned int debounce);
diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
index b1f22e457fd0..f1422bee3dcc 100644
--- a/drivers/gpu/drm/Kconfig
+++ b/drivers/gpu/drm/Kconfig
@@ -68,8 +68,10 @@ config DRM_DEBUG_SELFTEST
depends on DRM
depends on DEBUG_KERNEL
select PRIME_NUMBERS
+ select DRM_DP_HELPER
select DRM_LIB_RANDOM
select DRM_KMS_HELPER
+ select DRM_BUDDY
select DRM_EXPORT_FOR_TESTS if m
default n
help
@@ -80,6 +82,12 @@ config DRM_DEBUG_SELFTEST
If in doubt, say "N".
+config DRM_DP_HELPER
+ tristate
+ depends on DRM
+ help
+ DRM helpers for DisplayPort.
+
config DRM_KMS_HELPER
tristate
depends on DRM
@@ -198,6 +206,12 @@ config DRM_TTM
GPU memory types. Will be enabled automatically if a device driver
uses it.
+config DRM_BUDDY
+ tristate
+ depends on DRM
+ help
+ A page based buddy allocator
+
config DRM_VRAM_HELPER
tristate
depends on DRM
@@ -236,6 +250,7 @@ config DRM_RADEON
depends on DRM && PCI && MMU
depends on AGP || !AGP
select FW_LOADER
+ select DRM_DP_HELPER
select DRM_KMS_HELPER
select DRM_TTM
select DRM_TTM_HELPER
@@ -256,6 +271,7 @@ config DRM_AMDGPU
tristate "AMD GPU"
depends on DRM && PCI && MMU
select FW_LOADER
+ select DRM_DP_HELPER
select DRM_KMS_HELPER
select DRM_SCHED
select DRM_TTM
@@ -388,6 +404,8 @@ source "drivers/gpu/drm/xlnx/Kconfig"
source "drivers/gpu/drm/gud/Kconfig"
+source "drivers/gpu/drm/solomon/Kconfig"
+
source "drivers/gpu/drm/sprd/Kconfig"
config DRM_HYPERV
diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
index 301a44dc18e3..c2ef5f9fce54 100644
--- a/drivers/gpu/drm/Makefile
+++ b/drivers/gpu/drm/Makefile
@@ -31,8 +31,6 @@ drm-$(CONFIG_DEBUG_FS) += drm_debugfs.o drm_debugfs_crc.o
drm-$(CONFIG_DRM_LOAD_EDID_FIRMWARE) += drm_edid_load.o
drm-$(CONFIG_DRM_PRIVACY_SCREEN) += drm_privacy_screen.o drm_privacy_screen_x86.o
-obj-$(CONFIG_DRM_DP_AUX_BUS) += drm_dp_aux_bus.o
-
obj-$(CONFIG_DRM_NOMODESET) += drm_nomodeset.o
drm_cma_helper-y := drm_gem_cma_helper.o
@@ -42,27 +40,26 @@ obj-$(CONFIG_DRM_GEM_CMA_HELPER) += drm_cma_helper.o
drm_shmem_helper-y := drm_gem_shmem_helper.o
obj-$(CONFIG_DRM_GEM_SHMEM_HELPER) += drm_shmem_helper.o
+obj-$(CONFIG_DRM_BUDDY) += drm_buddy.o
+
drm_vram_helper-y := drm_gem_vram_helper.o
obj-$(CONFIG_DRM_VRAM_HELPER) += drm_vram_helper.o
drm_ttm_helper-y := drm_gem_ttm_helper.o
obj-$(CONFIG_DRM_TTM_HELPER) += drm_ttm_helper.o
-drm_kms_helper-y := drm_bridge_connector.o drm_crtc_helper.o drm_dp_helper.o \
+drm_kms_helper-y := drm_bridge_connector.o drm_crtc_helper.o \
drm_dsc.o drm_encoder_slave.o drm_flip_work.o drm_hdcp.o \
drm_probe_helper.o \
- drm_plane_helper.o drm_dp_mst_topology.o drm_atomic_helper.o \
- drm_kms_helper_common.o drm_dp_dual_mode_helper.o \
+ drm_plane_helper.o drm_atomic_helper.o \
+ drm_kms_helper_common.o \
drm_simple_kms_helper.o drm_modeset_helper.o \
drm_scdc_helper.o drm_gem_atomic_helper.o \
drm_gem_framebuffer_helper.o \
drm_atomic_state_helper.o drm_damage_helper.o \
drm_format_helper.o drm_self_refresh_helper.o drm_rect.o
-
drm_kms_helper-$(CONFIG_DRM_PANEL_BRIDGE) += bridge/panel.o
drm_kms_helper-$(CONFIG_DRM_FBDEV_EMULATION) += drm_fb_helper.o
-drm_kms_helper-$(CONFIG_DRM_DP_AUX_CHARDEV) += drm_dp_aux_dev.o
-drm_kms_helper-$(CONFIG_DRM_DP_CEC) += drm_dp_cec.o
obj-$(CONFIG_DRM_KMS_HELPER) += drm_kms_helper.o
obj-$(CONFIG_DRM_DEBUG_SELFTEST) += selftests/
@@ -72,6 +69,7 @@ obj-$(CONFIG_DRM_MIPI_DBI) += drm_mipi_dbi.o
obj-$(CONFIG_DRM_MIPI_DSI) += drm_mipi_dsi.o
obj-$(CONFIG_DRM_PANEL_ORIENTATION_QUIRKS) += drm_panel_orientation_quirks.o
obj-y += arm/
+obj-y += dp/
obj-$(CONFIG_DRM_TTM) += ttm/
obj-$(CONFIG_DRM_SCHED) += scheduler/
obj-$(CONFIG_DRM_TDFX) += tdfx/
@@ -134,4 +132,5 @@ obj-$(CONFIG_DRM_TIDSS) += tidss/
obj-y += xlnx/
obj-y += gud/
obj-$(CONFIG_DRM_HYPERV) += hyperv/
+obj-y += solomon/
obj-$(CONFIG_DRM_SPRD) += sprd/
diff --git a/drivers/gpu/drm/amd/amdgpu/Makefile b/drivers/gpu/drm/amd/amdgpu/Makefile
index 7fedbb725e17..40e2c6e2df79 100644
--- a/drivers/gpu/drm/amd/amdgpu/Makefile
+++ b/drivers/gpu/drm/amd/amdgpu/Makefile
@@ -46,18 +46,18 @@ amdgpu-y += amdgpu_device.o amdgpu_kms.o \
atom.o amdgpu_fence.o amdgpu_ttm.o amdgpu_object.o amdgpu_gart.o \
amdgpu_encoders.o amdgpu_display.o amdgpu_i2c.o \
amdgpu_gem.o amdgpu_ring.o \
- amdgpu_cs.o amdgpu_bios.o amdgpu_benchmark.o amdgpu_test.o \
+ amdgpu_cs.o amdgpu_bios.o amdgpu_benchmark.o \
atombios_dp.o amdgpu_afmt.o amdgpu_trace_points.o \
atombios_encoders.o amdgpu_sa.o atombios_i2c.o \
amdgpu_dma_buf.o amdgpu_vm.o amdgpu_ib.o amdgpu_pll.o \
amdgpu_ucode.o amdgpu_bo_list.o amdgpu_ctx.o amdgpu_sync.o \
amdgpu_gtt_mgr.o amdgpu_preempt_mgr.o amdgpu_vram_mgr.o amdgpu_virt.o \
amdgpu_atomfirmware.o amdgpu_vf_error.o amdgpu_sched.o \
- amdgpu_debugfs.o amdgpu_ids.o amdgpu_gmc.o amdgpu_mmhub.o \
+ amdgpu_debugfs.o amdgpu_ids.o amdgpu_gmc.o \
amdgpu_xgmi.o amdgpu_csa.o amdgpu_ras.o amdgpu_vm_cpu.o \
amdgpu_vm_sdma.o amdgpu_discovery.o amdgpu_ras_eeprom.o amdgpu_nbio.o \
amdgpu_umc.o smu_v11_0_i2c.o amdgpu_fru_eeprom.o amdgpu_rap.o \
- amdgpu_fw_attestation.o amdgpu_securedisplay.o amdgpu_hdp.o \
+ amdgpu_fw_attestation.o amdgpu_securedisplay.o \
amdgpu_eeprom.o amdgpu_mca.o
amdgpu-$(CONFIG_PROC_FS) += amdgpu_fdinfo.o
diff --git a/drivers/gpu/drm/amd/amdgpu/aldebaran.c b/drivers/gpu/drm/amd/amdgpu/aldebaran.c
index bcfdb63b1d42..c6cc493a5486 100644
--- a/drivers/gpu/drm/amd/amdgpu/aldebaran.c
+++ b/drivers/gpu/drm/amd/amdgpu/aldebaran.c
@@ -31,6 +31,17 @@
#include "amdgpu_psp.h"
#include "amdgpu_xgmi.h"
+static bool aldebaran_is_mode2_default(struct amdgpu_reset_control *reset_ctl)
+{
+ struct amdgpu_device *adev = (struct amdgpu_device *)reset_ctl->handle;
+
+ if ((adev->ip_versions[MP1_HWIP][0] == IP_VERSION(13, 0, 2) &&
+ adev->gmc.xgmi.connected_to_cpu))
+ return true;
+
+ return false;
+}
+
static struct amdgpu_reset_handler *
aldebaran_get_reset_handler(struct amdgpu_reset_control *reset_ctl,
struct amdgpu_reset_context *reset_context)
@@ -48,7 +59,7 @@ aldebaran_get_reset_handler(struct amdgpu_reset_control *reset_ctl,
}
}
- if (adev->gmc.xgmi.connected_to_cpu) {
+ if (aldebaran_is_mode2_default(reset_ctl)) {
list_for_each_entry(handler, &reset_ctl->reset_handlers,
handler_list) {
if (handler->reset_method == AMD_RESET_METHOD_MODE2) {
@@ -136,18 +147,31 @@ static int
aldebaran_mode2_perform_reset(struct amdgpu_reset_control *reset_ctl,
struct amdgpu_reset_context *reset_context)
{
- struct amdgpu_device *tmp_adev = NULL;
struct amdgpu_device *adev = (struct amdgpu_device *)reset_ctl->handle;
+ struct amdgpu_device *tmp_adev = NULL;
+ struct list_head reset_device_list;
int r = 0;
dev_dbg(adev->dev, "aldebaran perform hw reset\n");
- if (reset_context->hive == NULL) {
+ if (adev->ip_versions[MP1_HWIP][0] == IP_VERSION(13, 0, 2) &&
+ reset_context->hive == NULL) {
/* Wrong context, return error */
return -EINVAL;
}
- list_for_each_entry(tmp_adev, &reset_context->hive->device_list,
- gmc.xgmi.head) {
+ INIT_LIST_HEAD(&reset_device_list);
+ if (reset_context->hive) {
+ list_for_each_entry (tmp_adev,
+ &reset_context->hive->device_list,
+ gmc.xgmi.head)
+ list_add_tail(&tmp_adev->reset_list,
+ &reset_device_list);
+ } else {
+ list_add_tail(&reset_context->reset_req_dev->reset_list,
+ &reset_device_list);
+ }
+
+ list_for_each_entry (tmp_adev, &reset_device_list, reset_list) {
mutex_lock(&tmp_adev->reset_cntl->reset_lock);
tmp_adev->reset_cntl->active_reset = AMD_RESET_METHOD_MODE2;
}
@@ -155,8 +179,7 @@ aldebaran_mode2_perform_reset(struct amdgpu_reset_control *reset_ctl,
* Mode2 reset doesn't need any sync between nodes in XGMI hive, instead launch
* them together so that they can be completed asynchronously on multiple nodes
*/
- list_for_each_entry(tmp_adev, &reset_context->hive->device_list,
- gmc.xgmi.head) {
+ list_for_each_entry (tmp_adev, &reset_device_list, reset_list) {
/* For XGMI run all resets in parallel to speed up the process */
if (tmp_adev->gmc.xgmi.num_physical_nodes > 1) {
if (!queue_work(system_unbound_wq,
@@ -174,9 +197,7 @@ aldebaran_mode2_perform_reset(struct amdgpu_reset_control *reset_ctl,
/* For XGMI wait for all resets to complete before proceed */
if (!r) {
- list_for_each_entry(tmp_adev,
- &reset_context->hive->device_list,
- gmc.xgmi.head) {
+ list_for_each_entry (tmp_adev, &reset_device_list, reset_list) {
if (tmp_adev->gmc.xgmi.num_physical_nodes > 1) {
flush_work(&tmp_adev->reset_cntl->reset_work);
r = tmp_adev->asic_reset_res;
@@ -186,8 +207,7 @@ aldebaran_mode2_perform_reset(struct amdgpu_reset_control *reset_ctl,
}
}
- list_for_each_entry(tmp_adev, &reset_context->hive->device_list,
- gmc.xgmi.head) {
+ list_for_each_entry (tmp_adev, &reset_device_list, reset_list) {
mutex_unlock(&tmp_adev->reset_cntl->reset_lock);
tmp_adev->reset_cntl->active_reset = AMD_RESET_METHOD_NONE;
}
@@ -260,7 +280,7 @@ static int aldebaran_mode2_restore_ip(struct amdgpu_device *adev)
adev->gfx.rlc.funcs->resume(adev);
/* Wait for FW reset event complete */
- r = smu_wait_for_event(adev, SMU_EVENT_RESET_COMPLETE, 0);
+ r = amdgpu_dpm_wait_for_event(adev, SMU_EVENT_RESET_COMPLETE, 0);
if (r) {
dev_err(adev->dev,
"Failed to get response from firmware after reset\n");
@@ -319,16 +339,30 @@ static int
aldebaran_mode2_restore_hwcontext(struct amdgpu_reset_control *reset_ctl,
struct amdgpu_reset_context *reset_context)
{
- int r;
struct amdgpu_device *tmp_adev = NULL;
+ struct list_head reset_device_list;
+ int r;
- if (reset_context->hive == NULL) {
+ if (reset_context->reset_req_dev->ip_versions[MP1_HWIP][0] ==
+ IP_VERSION(13, 0, 2) &&
+ reset_context->hive == NULL) {
/* Wrong context, return error */
return -EINVAL;
}
- list_for_each_entry(tmp_adev, &reset_context->hive->device_list,
- gmc.xgmi.head) {
+ INIT_LIST_HEAD(&reset_device_list);
+ if (reset_context->hive) {
+ list_for_each_entry (tmp_adev,
+ &reset_context->hive->device_list,
+ gmc.xgmi.head)
+ list_add_tail(&tmp_adev->reset_list,
+ &reset_device_list);
+ } else {
+ list_add_tail(&reset_context->reset_req_dev->reset_list,
+ &reset_device_list);
+ }
+
+ list_for_each_entry (tmp_adev, &reset_device_list, reset_list) {
dev_info(tmp_adev->dev,
"GPU reset succeeded, trying to resume\n");
r = aldebaran_mode2_restore_ip(tmp_adev);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
index d8b854fcbffa..cdf0818088b3 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
@@ -60,7 +60,6 @@
#include <drm/amdgpu_drm.h>
#include <drm/drm_gem.h>
#include <drm/drm_ioctl.h>
-#include <drm/gpu_scheduler.h>
#include <kgd_kfd_interface.h>
#include "dm_pp_interface.h"
@@ -99,7 +98,6 @@
#include "amdgpu_gem.h"
#include "amdgpu_doorbell.h"
#include "amdgpu_amdkfd.h"
-#include "amdgpu_smu.h"
#include "amdgpu_discovery.h"
#include "amdgpu_mes.h"
#include "amdgpu_umc.h"
@@ -109,6 +107,7 @@
#include "amdgpu_smuio.h"
#include "amdgpu_fdinfo.h"
#include "amdgpu_mca.h"
+#include "amdgpu_ras.h"
#define MAX_GPU_INSTANCE 16
@@ -155,8 +154,6 @@ extern int amdgpu_vis_vram_limit;
extern int amdgpu_gart_size;
extern int amdgpu_gtt_size;
extern int amdgpu_moverate;
-extern int amdgpu_benchmarking;
-extern int amdgpu_testing;
extern int amdgpu_audio;
extern int amdgpu_disp_priority;
extern int amdgpu_hw_i2c;
@@ -197,7 +194,6 @@ extern int amdgpu_emu_mode;
extern uint amdgpu_smu_memory_pool_size;
extern int amdgpu_smu_pptable_id;
extern uint amdgpu_dc_feature_mask;
-extern uint amdgpu_freesync_vid_mode;
extern uint amdgpu_dc_debug_mask;
extern uint amdgpu_dm_abm_level;
extern int amdgpu_backlight;
@@ -214,6 +210,7 @@ extern int amdgpu_mes;
extern int amdgpu_noretry;
extern int amdgpu_force_asic_type;
extern int amdgpu_smartshift_bias;
+extern int amdgpu_use_xgmi_p2p;
#ifdef CONFIG_HSA_AMD
extern int sched_policy;
extern bool debug_evictions;
@@ -235,6 +232,9 @@ extern int amdgpu_cik_support;
#endif
extern int amdgpu_num_kcq;
+#define AMDGPU_VCNFW_LOG_SIZE (32 * 1024)
+extern int amdgpu_vcnfw_log;
+
#define AMDGPU_VM_MAX_NUM_CTX 4096
#define AMDGPU_SG_THRESHOLD (256*1024*1024)
#define AMDGPU_DEFAULT_GTT_SIZE_MB 3072ULL /* 3GB by default */
@@ -276,9 +276,6 @@ extern int amdgpu_num_kcq;
#define AMDGPU_SMARTSHIFT_MIN_BIAS (-100)
struct amdgpu_device;
-struct amdgpu_ib;
-struct amdgpu_cs_parser;
-struct amdgpu_job;
struct amdgpu_irq_src;
struct amdgpu_fpriv;
struct amdgpu_bo_va_mapping;
@@ -373,7 +370,8 @@ int amdgpu_device_ip_block_add(struct amdgpu_device *adev,
*/
bool amdgpu_get_bios(struct amdgpu_device *adev);
bool amdgpu_read_bios(struct amdgpu_device *adev);
-
+bool amdgpu_soc15_read_bios_from_rom(struct amdgpu_device *adev,
+ u8 *bios, u32 length_bytes);
/*
* Clocks
*/
@@ -466,20 +464,6 @@ struct amdgpu_flip_work {
/*
- * CP & rings.
- */
-
-struct amdgpu_ib {
- struct amdgpu_sa_bo *sa_bo;
- uint32_t length_dw;
- uint64_t gpu_addr;
- uint32_t *ptr;
- uint32_t flags;
-};
-
-extern const struct drm_sched_backend_ops amdgpu_sched_ops;
-
-/*
* file private structure
*/
@@ -494,79 +478,6 @@ struct amdgpu_fpriv {
int amdgpu_file_to_fpriv(struct file *filp, struct amdgpu_fpriv **fpriv);
-int amdgpu_ib_get(struct amdgpu_device *adev, struct amdgpu_vm *vm,
- unsigned size,
- enum amdgpu_ib_pool_type pool,
- struct amdgpu_ib *ib);
-void amdgpu_ib_free(struct amdgpu_device *adev, struct amdgpu_ib *ib,
- struct dma_fence *f);
-int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs,
- struct amdgpu_ib *ibs, struct amdgpu_job *job,
- struct dma_fence **f);
-int amdgpu_ib_pool_init(struct amdgpu_device *adev);
-void amdgpu_ib_pool_fini(struct amdgpu_device *adev);
-int amdgpu_ib_ring_tests(struct amdgpu_device *adev);
-
-/*
- * CS.
- */
-struct amdgpu_cs_chunk {
- uint32_t chunk_id;
- uint32_t length_dw;
- void *kdata;
-};
-
-struct amdgpu_cs_post_dep {
- struct drm_syncobj *syncobj;
- struct dma_fence_chain *chain;
- u64 point;
-};
-
-struct amdgpu_cs_parser {
- struct amdgpu_device *adev;
- struct drm_file *filp;
- struct amdgpu_ctx *ctx;
-
- /* chunks */
- unsigned nchunks;
- struct amdgpu_cs_chunk *chunks;
-
- /* scheduler job object */
- struct amdgpu_job *job;
- struct drm_sched_entity *entity;
-
- /* buffer objects */
- struct ww_acquire_ctx ticket;
- struct amdgpu_bo_list *bo_list;
- struct amdgpu_mn *mn;
- struct amdgpu_bo_list_entry vm_pd;
- struct list_head validated;
- struct dma_fence *fence;
- uint64_t bytes_moved_threshold;
- uint64_t bytes_moved_vis_threshold;
- uint64_t bytes_moved;
- uint64_t bytes_moved_vis;
-
- /* user fence */
- struct amdgpu_bo_list_entry uf_entry;
-
- unsigned num_post_deps;
- struct amdgpu_cs_post_dep *post_deps;
-};
-
-static inline u32 amdgpu_get_ib_value(struct amdgpu_cs_parser *p,
- uint32_t ib_idx, int idx)
-{
- return p->job->ibs[ib_idx].ptr[idx];
-}
-
-static inline void amdgpu_set_ib_value(struct amdgpu_cs_parser *p,
- uint32_t ib_idx, int idx,
- uint32_t value)
-{
- p->job->ibs[ib_idx].ptr[idx] = value;
-}
-
/*
* Writeback
*/
@@ -586,13 +497,7 @@ void amdgpu_device_wb_free(struct amdgpu_device *adev, u32 wb);
/*
* Benchmarking
*/
-void amdgpu_benchmark(struct amdgpu_device *adev, int test_number);
-
-
-/*
- * Testing
- */
-void amdgpu_test_moves(struct amdgpu_device *adev);
+int amdgpu_benchmark(struct amdgpu_device *adev, int test_number);
/*
* ASIC specific register table accessible by UMD
@@ -771,6 +676,8 @@ struct amd_powerplay {
const struct amd_pm_funcs *pp_funcs;
};
+struct ip_discovery_top;
+
/* polaris10 kickers */
#define ASICID_IS_P20(did, rid) (((did == 0x67DF) && \
((rid == 0xE3) || \
@@ -813,6 +720,8 @@ struct amd_powerplay {
#define AMDGPU_RESET_MAGIC_NUM 64
#define AMDGPU_MAX_DF_PERFMONS 4
#define AMDGPU_PRODUCT_NAME_LEN 64
+struct amdgpu_reset_domain;
+
struct amdgpu_device {
struct device *dev;
struct pci_dev *pdev;
@@ -950,12 +859,6 @@ struct amdgpu_device {
/* powerplay */
struct amd_powerplay powerplay;
- bool pp_force_state_enabled;
-
- /* smu */
- struct smu_context smu;
-
- /* dpm */
struct amdgpu_pm pm;
u32 cg_flags;
u32 pg_flags;
@@ -1054,9 +957,7 @@ struct amdgpu_device {
bool in_s4;
bool in_s0ix;
- atomic_t in_gpu_reset;
enum pp_mp1_state mp1_state;
- struct rw_semaphore reset_sem;
struct amdgpu_doorbell_index doorbell_index;
struct mutex notifier_lock;
@@ -1100,6 +1001,18 @@ struct amdgpu_device {
uint32_t ip_versions[MAX_HWIP][HWIP_MAX_INSTANCE];
bool ram_is_direct_mapped;
+
+ struct list_head ras_list;
+
+ struct ip_discovery_top *ip_top;
+
+ struct amdgpu_reset_domain *reset_domain;
+
+ struct mutex benchmark_mutex;
+
+ /* reset dump register */
+ uint32_t *reset_dump_reg_list;
+ int num_regs;
};
static inline struct amdgpu_device *drm_to_adev(struct drm_device *ddev)
@@ -1293,9 +1206,12 @@ bool amdgpu_device_has_job_running(struct amdgpu_device *adev);
bool amdgpu_device_should_recover_gpu(struct amdgpu_device *adev);
int amdgpu_device_gpu_recover(struct amdgpu_device *adev,
struct amdgpu_job* job);
+int amdgpu_device_gpu_recover_imp(struct amdgpu_device *adev,
+ struct amdgpu_job *job);
void amdgpu_device_pci_config_reset(struct amdgpu_device *adev);
int amdgpu_device_pci_reset(struct amdgpu_device *adev);
bool amdgpu_device_need_post(struct amdgpu_device *adev);
+bool amdgpu_device_should_use_aspm(struct amdgpu_device *adev);
void amdgpu_cs_report_moved_bytes(struct amdgpu_device *adev, u64 num_bytes,
u64 num_vis_bytes);
@@ -1321,6 +1237,10 @@ void amdgpu_device_invalidate_hdp(struct amdgpu_device *adev,
struct amdgpu_ring *ring);
void amdgpu_device_halt(struct amdgpu_device *adev);
+u32 amdgpu_device_pcie_port_rreg(struct amdgpu_device *adev,
+ u32 reg);
+void amdgpu_device_pcie_port_wreg(struct amdgpu_device *adev,
+ u32 reg, u32 v);
/* atpx handler */
#if defined(CONFIG_VGA_SWITCHEROO)
@@ -1408,12 +1328,10 @@ int amdgpu_acpi_smart_shift_update(struct drm_device *dev, enum amdgpu_ss ss_sta
int amdgpu_acpi_pcie_notify_device_ready(struct amdgpu_device *adev);
void amdgpu_acpi_get_backlight_caps(struct amdgpu_dm_backlight_caps *caps);
-bool amdgpu_acpi_is_s0ix_active(struct amdgpu_device *adev);
void amdgpu_acpi_detect(void);
#else
static inline int amdgpu_acpi_init(struct amdgpu_device *adev) { return 0; }
static inline void amdgpu_acpi_fini(struct amdgpu_device *adev) { }
-static inline bool amdgpu_acpi_is_s0ix_active(struct amdgpu_device *adev) { return false; }
static inline void amdgpu_acpi_detect(void) { }
static inline bool amdgpu_acpi_is_power_shift_control_supported(void) { return false; }
static inline int amdgpu_acpi_power_shift_control(struct amdgpu_device *adev,
@@ -1422,9 +1340,13 @@ static inline int amdgpu_acpi_smart_shift_update(struct drm_device *dev,
enum amdgpu_ss ss_state) { return 0; }
#endif
-int amdgpu_cs_find_mapping(struct amdgpu_cs_parser *parser,
- uint64_t addr, struct amdgpu_bo **bo,
- struct amdgpu_bo_va_mapping **mapping);
+#if defined(CONFIG_ACPI) && defined(CONFIG_SUSPEND)
+bool amdgpu_acpi_is_s3_active(struct amdgpu_device *adev);
+bool amdgpu_acpi_is_s0ix_active(struct amdgpu_device *adev);
+#else
+static inline bool amdgpu_acpi_is_s0ix_active(struct amdgpu_device *adev) { return false; }
+static inline bool amdgpu_acpi_is_s3_active(struct amdgpu_device *adev) { return false; }
+#endif
#if defined(CONFIG_DRM_AMD_DC)
int amdgpu_dm_display_resume(struct amdgpu_device *adev );
@@ -1452,6 +1374,15 @@ int amdgpu_device_set_cg_state(struct amdgpu_device *adev,
int amdgpu_device_set_pg_state(struct amdgpu_device *adev,
enum amd_powergating_state state);
+static inline bool amdgpu_device_has_timeouts_enabled(struct amdgpu_device *adev)
+{
+ return amdgpu_gpu_recovery != 0 &&
+ adev->gfx_timeout != MAX_SCHEDULE_TIMEOUT &&
+ adev->compute_timeout != MAX_SCHEDULE_TIMEOUT &&
+ adev->sdma_timeout != MAX_SCHEDULE_TIMEOUT &&
+ adev->video_timeout != MAX_SCHEDULE_TIMEOUT;
+}
+
#include "amdgpu_object.h"
static inline bool amdgpu_is_tmz(struct amdgpu_device *adev)
@@ -1459,8 +1390,6 @@ static inline bool amdgpu_is_tmz(struct amdgpu_device *adev)
return adev->gmc.tmz_enabled;
}
-static inline int amdgpu_in_reset(struct amdgpu_device *adev)
-{
- return atomic_read(&adev->in_gpu_reset);
-}
+int amdgpu_in_reset(struct amdgpu_device *adev);
+
#endif
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c
index 4811b0faafd9..0e12315fa0cb 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c
@@ -1031,6 +1031,20 @@ void amdgpu_acpi_detect(void)
}
}
+#if IS_ENABLED(CONFIG_SUSPEND)
+/**
+ * amdgpu_acpi_is_s3_active
+ *
+ * @adev: amdgpu_device_pointer
+ *
+ * returns true if supported, false if not.
+ */
+bool amdgpu_acpi_is_s3_active(struct amdgpu_device *adev)
+{
+ return !(adev->flags & AMD_IS_APU) ||
+ (pm_suspend_target_state == PM_SUSPEND_MEM);
+}
+
/**
* amdgpu_acpi_is_s0ix_active
*
@@ -1040,11 +1054,24 @@ void amdgpu_acpi_detect(void)
*/
bool amdgpu_acpi_is_s0ix_active(struct amdgpu_device *adev)
{
-#if IS_ENABLED(CONFIG_AMD_PMC) && IS_ENABLED(CONFIG_SUSPEND)
- if (acpi_gbl_FADT.flags & ACPI_FADT_LOW_POWER_S0) {
- if (adev->flags & AMD_IS_APU)
- return pm_suspend_target_state == PM_SUSPEND_TO_IDLE;
+ if (!(adev->flags & AMD_IS_APU) ||
+ (pm_suspend_target_state != PM_SUSPEND_TO_IDLE))
+ return false;
+
+ if (!(acpi_gbl_FADT.flags & ACPI_FADT_LOW_POWER_S0)) {
+ dev_warn_once(adev->dev,
+ "Power consumption will be higher as BIOS has not been configured for suspend-to-idle.\n"
+ "To use suspend-to-idle change the sleep mode in BIOS setup.\n");
+ return false;
}
-#endif
+
+#if !IS_ENABLED(CONFIG_AMD_PMC)
+ dev_warn_once(adev->dev,
+ "Power consumption will be higher as the kernel has not been compiled with CONFIG_AMD_PMC.\n");
return false;
+#else
+ return true;
+#endif /* CONFIG_AMD_PMC */
}
+
+#endif /* CONFIG_SUSPEND */
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h
index ac841ae8f5cc..4cb14c2fe53f 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h
@@ -131,6 +131,7 @@ struct amdkfd_process_info {
atomic_t evicted_bos;
struct delayed_work restore_userptr_work;
struct pid *pid;
+ bool block_mmu_notifications;
};
int amdgpu_amdkfd_init(void);
@@ -268,7 +269,7 @@ uint64_t amdgpu_amdkfd_gpuvm_get_process_page_dir(void *drm_priv);
int amdgpu_amdkfd_gpuvm_alloc_memory_of_gpu(
struct amdgpu_device *adev, uint64_t va, uint64_t size,
void *drm_priv, struct kgd_mem **mem,
- uint64_t *offset, uint32_t flags);
+ uint64_t *offset, uint32_t flags, bool criu_resume);
int amdgpu_amdkfd_gpuvm_free_memory_of_gpu(
struct amdgpu_device *adev, struct kgd_mem *mem, void *drm_priv,
uint64_t *size);
@@ -297,6 +298,10 @@ int amdgpu_amdkfd_get_tile_config(struct amdgpu_device *adev,
struct tile_config *config);
void amdgpu_amdkfd_ras_poison_consumption_handler(struct amdgpu_device *adev,
bool reset);
+bool amdgpu_amdkfd_bo_mapped_to_dev(struct amdgpu_device *adev, struct kgd_mem *mem);
+void amdgpu_amdkfd_block_mmu_notifications(void *p);
+int amdgpu_amdkfd_criu_resume(void *p);
+
#if IS_ENABLED(CONFIG_HSA_AMD)
void amdgpu_amdkfd_gpuvm_init_mem_limits(void);
void amdgpu_amdkfd_gpuvm_destroy_cb(struct amdgpu_device *adev,
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_aldebaran.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_aldebaran.c
index 46cd4ee6bafb..c8935d718207 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_aldebaran.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_aldebaran.c
@@ -37,10 +37,7 @@ const struct kfd2kgd_calls aldebaran_kfd2kgd = {
.hqd_sdma_is_occupied = kgd_arcturus_hqd_sdma_is_occupied,
.hqd_destroy = kgd_gfx_v9_hqd_destroy,
.hqd_sdma_destroy = kgd_arcturus_hqd_sdma_destroy,
- .address_watch_disable = kgd_gfx_v9_address_watch_disable,
- .address_watch_execute = kgd_gfx_v9_address_watch_execute,
.wave_control_execute = kgd_gfx_v9_wave_control_execute,
- .address_watch_get_offset = kgd_gfx_v9_address_watch_get_offset,
.get_atc_vmid_pasid_mapping_info =
kgd_gfx_v9_get_atc_vmid_pasid_mapping_info,
.set_vm_context_page_table_base = kgd_gfx_v9_set_vm_context_page_table_base,
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_arcturus.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_arcturus.c
index abe93b3ff765..4191af5a3f13 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_arcturus.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_arcturus.c
@@ -289,10 +289,7 @@ const struct kfd2kgd_calls arcturus_kfd2kgd = {
.hqd_sdma_is_occupied = kgd_arcturus_hqd_sdma_is_occupied,
.hqd_destroy = kgd_gfx_v9_hqd_destroy,
.hqd_sdma_destroy = kgd_arcturus_hqd_sdma_destroy,
- .address_watch_disable = kgd_gfx_v9_address_watch_disable,
- .address_watch_execute = kgd_gfx_v9_address_watch_execute,
.wave_control_execute = kgd_gfx_v9_wave_control_execute,
- .address_watch_get_offset = kgd_gfx_v9_address_watch_get_offset,
.get_atc_vmid_pasid_mapping_info =
kgd_gfx_v9_get_atc_vmid_pasid_mapping_info,
.set_vm_context_page_table_base =
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v10.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v10.c
index 7b7f4b2764c1..9378fc79e9ea 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v10.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v10.c
@@ -671,20 +671,6 @@ static bool get_atc_vmid_pasid_mapping_info(struct amdgpu_device *adev,
return !!(value & ATC_VMID0_PASID_MAPPING__VALID_MASK);
}
-static int kgd_address_watch_disable(struct amdgpu_device *adev)
-{
- return 0;
-}
-
-static int kgd_address_watch_execute(struct amdgpu_device *adev,
- unsigned int watch_point_id,
- uint32_t cntl_val,
- uint32_t addr_hi,
- uint32_t addr_lo)
-{
- return 0;
-}
-
static int kgd_wave_control_execute(struct amdgpu_device *adev,
uint32_t gfx_index_val,
uint32_t sq_cmd)
@@ -709,13 +695,6 @@ static int kgd_wave_control_execute(struct amdgpu_device *adev,
return 0;
}
-static uint32_t kgd_address_watch_get_offset(struct amdgpu_device *adev,
- unsigned int watch_point_id,
- unsigned int reg_offset)
-{
- return 0;
-}
-
static void set_vm_context_page_table_base(struct amdgpu_device *adev,
uint32_t vmid, uint64_t page_table_base)
{
@@ -767,10 +746,7 @@ const struct kfd2kgd_calls gfx_v10_kfd2kgd = {
.hqd_sdma_is_occupied = kgd_hqd_sdma_is_occupied,
.hqd_destroy = kgd_hqd_destroy,
.hqd_sdma_destroy = kgd_hqd_sdma_destroy,
- .address_watch_disable = kgd_address_watch_disable,
- .address_watch_execute = kgd_address_watch_execute,
.wave_control_execute = kgd_wave_control_execute,
- .address_watch_get_offset = kgd_address_watch_get_offset,
.get_atc_vmid_pasid_mapping_info =
get_atc_vmid_pasid_mapping_info,
.set_vm_context_page_table_base = set_vm_context_page_table_base,
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v10_3.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v10_3.c
index 1f37d3574001..ba21ec6b35e0 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v10_3.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v10_3.c
@@ -26,6 +26,8 @@
#include "gc/gc_10_3_0_sh_mask.h"
#include "oss/osssys_5_0_0_offset.h"
#include "oss/osssys_5_0_0_sh_mask.h"
+#include "athub/athub_2_1_0_offset.h"
+#include "athub/athub_2_1_0_sh_mask.h"
#include "soc15_common.h"
#include "v10_structs.h"
#include "nv.h"
@@ -582,21 +584,6 @@ static int hqd_sdma_destroy_v10_3(struct amdgpu_device *adev, void *mqd,
return 0;
}
-
-static int address_watch_disable_v10_3(struct amdgpu_device *adev)
-{
- return 0;
-}
-
-static int address_watch_execute_v10_3(struct amdgpu_device *adev,
- unsigned int watch_point_id,
- uint32_t cntl_val,
- uint32_t addr_hi,
- uint32_t addr_lo)
-{
- return 0;
-}
-
static int wave_control_execute_v10_3(struct amdgpu_device *adev,
uint32_t gfx_index_val,
uint32_t sq_cmd)
@@ -621,11 +608,16 @@ static int wave_control_execute_v10_3(struct amdgpu_device *adev,
return 0;
}
-static uint32_t address_watch_get_offset_v10_3(struct amdgpu_device *adev,
- unsigned int watch_point_id,
- unsigned int reg_offset)
+static bool get_atc_vmid_pasid_mapping_info_v10_3(struct amdgpu_device *adev,
+ uint8_t vmid, uint16_t *p_pasid)
{
- return 0;
+ uint32_t value;
+
+ value = RREG32(SOC15_REG_OFFSET(ATHUB, 0, mmATC_VMID0_PASID_MAPPING)
+ + vmid);
+ *p_pasid = value & ATC_VMID0_PASID_MAPPING__PASID_MASK;
+
+ return !!(value & ATC_VMID0_PASID_MAPPING__VALID_MASK);
}
static void set_vm_context_page_table_base_v10_3(struct amdgpu_device *adev,
@@ -809,11 +801,8 @@ const struct kfd2kgd_calls gfx_v10_3_kfd2kgd = {
.hqd_sdma_is_occupied = hqd_sdma_is_occupied_v10_3,
.hqd_destroy = hqd_destroy_v10_3,
.hqd_sdma_destroy = hqd_sdma_destroy_v10_3,
- .address_watch_disable = address_watch_disable_v10_3,
- .address_watch_execute = address_watch_execute_v10_3,
.wave_control_execute = wave_control_execute_v10_3,
- .address_watch_get_offset = address_watch_get_offset_v10_3,
- .get_atc_vmid_pasid_mapping_info = NULL,
+ .get_atc_vmid_pasid_mapping_info = get_atc_vmid_pasid_mapping_info_v10_3,
.set_vm_context_page_table_base = set_vm_context_page_table_base_v10_3,
.program_trap_handler_settings = program_trap_handler_settings_v10_3,
#if 0
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v7.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v7.c
index 36528dad7684..65552bb7d2f2 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v7.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v7.c
@@ -45,43 +45,6 @@ enum {
MAX_WATCH_ADDRESSES = 4
};
-enum {
- ADDRESS_WATCH_REG_ADDR_HI = 0,
- ADDRESS_WATCH_REG_ADDR_LO,
- ADDRESS_WATCH_REG_CNTL,
- ADDRESS_WATCH_REG_MAX
-};
-
-/* not defined in the CI/KV reg file */
-enum {
- ADDRESS_WATCH_REG_CNTL_ATC_BIT = 0x10000000UL,
- ADDRESS_WATCH_REG_CNTL_DEFAULT_MASK = 0x00FFFFFF,
- ADDRESS_WATCH_REG_ADDLOW_MASK_EXTENSION = 0x03000000,
- /* extend the mask to 26 bits to match the low address field */
- ADDRESS_WATCH_REG_ADDLOW_SHIFT = 6,
- ADDRESS_WATCH_REG_ADDHIGH_MASK = 0xFFFF
-};
-
-static const uint32_t watchRegs[MAX_WATCH_ADDRESSES * ADDRESS_WATCH_REG_MAX] = {
- mmTCP_WATCH0_ADDR_H, mmTCP_WATCH0_ADDR_L, mmTCP_WATCH0_CNTL,
- mmTCP_WATCH1_ADDR_H, mmTCP_WATCH1_ADDR_L, mmTCP_WATCH1_CNTL,
- mmTCP_WATCH2_ADDR_H, mmTCP_WATCH2_ADDR_L, mmTCP_WATCH2_CNTL,
- mmTCP_WATCH3_ADDR_H, mmTCP_WATCH3_ADDR_L, mmTCP_WATCH3_CNTL
-};
-
-union TCP_WATCH_CNTL_BITS {
- struct {
- uint32_t mask:24;
- uint32_t vmid:4;
- uint32_t atc:1;
- uint32_t mode:2;
- uint32_t valid:1;
- } bitfields, bits;
- uint32_t u32All;
- signed int i32All;
- float f32All;
-};
-
static void lock_srbm(struct amdgpu_device *adev, uint32_t mec, uint32_t pipe,
uint32_t queue, uint32_t vmid)
{
@@ -529,55 +492,6 @@ static int kgd_hqd_sdma_destroy(struct amdgpu_device *adev, void *mqd,
return 0;
}
-static int kgd_address_watch_disable(struct amdgpu_device *adev)
-{
- union TCP_WATCH_CNTL_BITS cntl;
- unsigned int i;
-
- cntl.u32All = 0;
-
- cntl.bitfields.valid = 0;
- cntl.bitfields.mask = ADDRESS_WATCH_REG_CNTL_DEFAULT_MASK;
- cntl.bitfields.atc = 1;
-
- /* Turning off this address until we set all the registers */
- for (i = 0; i < MAX_WATCH_ADDRESSES; i++)
- WREG32(watchRegs[i * ADDRESS_WATCH_REG_MAX +
- ADDRESS_WATCH_REG_CNTL], cntl.u32All);
-
- return 0;
-}
-
-static int kgd_address_watch_execute(struct amdgpu_device *adev,
- unsigned int watch_point_id,
- uint32_t cntl_val,
- uint32_t addr_hi,
- uint32_t addr_lo)
-{
- union TCP_WATCH_CNTL_BITS cntl;
-
- cntl.u32All = cntl_val;
-
- /* Turning off this watch point until we set all the registers */
- cntl.bitfields.valid = 0;
- WREG32(watchRegs[watch_point_id * ADDRESS_WATCH_REG_MAX +
- ADDRESS_WATCH_REG_CNTL], cntl.u32All);
-
- WREG32(watchRegs[watch_point_id * ADDRESS_WATCH_REG_MAX +
- ADDRESS_WATCH_REG_ADDR_HI], addr_hi);
-
- WREG32(watchRegs[watch_point_id * ADDRESS_WATCH_REG_MAX +
- ADDRESS_WATCH_REG_ADDR_LO], addr_lo);
-
- /* Enable the watch point */
- cntl.bitfields.valid = 1;
-
- WREG32(watchRegs[watch_point_id * ADDRESS_WATCH_REG_MAX +
- ADDRESS_WATCH_REG_CNTL], cntl.u32All);
-
- return 0;
-}
-
static int kgd_wave_control_execute(struct amdgpu_device *adev,
uint32_t gfx_index_val,
uint32_t sq_cmd)
@@ -602,13 +516,6 @@ static int kgd_wave_control_execute(struct amdgpu_device *adev,
return 0;
}
-static uint32_t kgd_address_watch_get_offset(struct amdgpu_device *adev,
- unsigned int watch_point_id,
- unsigned int reg_offset)
-{
- return watchRegs[watch_point_id * ADDRESS_WATCH_REG_MAX + reg_offset];
-}
-
static bool get_atc_vmid_pasid_mapping_info(struct amdgpu_device *adev,
uint8_t vmid, uint16_t *p_pasid)
{
@@ -665,10 +572,7 @@ const struct kfd2kgd_calls gfx_v7_kfd2kgd = {
.hqd_sdma_is_occupied = kgd_hqd_sdma_is_occupied,
.hqd_destroy = kgd_hqd_destroy,
.hqd_sdma_destroy = kgd_hqd_sdma_destroy,
- .address_watch_disable = kgd_address_watch_disable,
- .address_watch_execute = kgd_address_watch_execute,
.wave_control_execute = kgd_wave_control_execute,
- .address_watch_get_offset = kgd_address_watch_get_offset,
.get_atc_vmid_pasid_mapping_info = get_atc_vmid_pasid_mapping_info,
.set_scratch_backing_va = set_scratch_backing_va,
.set_vm_context_page_table_base = set_vm_context_page_table_base,
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v8.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v8.c
index 52832cd69a93..9dc5f2a0cc07 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v8.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v8.c
@@ -538,20 +538,6 @@ static bool get_atc_vmid_pasid_mapping_info(struct amdgpu_device *adev,
return !!(value & ATC_VMID0_PASID_MAPPING__VALID_MASK);
}
-static int kgd_address_watch_disable(struct amdgpu_device *adev)
-{
- return 0;
-}
-
-static int kgd_address_watch_execute(struct amdgpu_device *adev,
- unsigned int watch_point_id,
- uint32_t cntl_val,
- uint32_t addr_hi,
- uint32_t addr_lo)
-{
- return 0;
-}
-
static int kgd_wave_control_execute(struct amdgpu_device *adev,
uint32_t gfx_index_val,
uint32_t sq_cmd)
@@ -576,13 +562,6 @@ static int kgd_wave_control_execute(struct amdgpu_device *adev,
return 0;
}
-static uint32_t kgd_address_watch_get_offset(struct amdgpu_device *adev,
- unsigned int watch_point_id,
- unsigned int reg_offset)
-{
- return 0;
-}
-
static void set_scratch_backing_va(struct amdgpu_device *adev,
uint64_t va, uint32_t vmid)
{
@@ -614,10 +593,7 @@ const struct kfd2kgd_calls gfx_v8_kfd2kgd = {
.hqd_sdma_is_occupied = kgd_hqd_sdma_is_occupied,
.hqd_destroy = kgd_hqd_destroy,
.hqd_sdma_destroy = kgd_hqd_sdma_destroy,
- .address_watch_disable = kgd_address_watch_disable,
- .address_watch_execute = kgd_address_watch_execute,
.wave_control_execute = kgd_wave_control_execute,
- .address_watch_get_offset = kgd_address_watch_get_offset,
.get_atc_vmid_pasid_mapping_info =
get_atc_vmid_pasid_mapping_info,
.set_scratch_backing_va = set_scratch_backing_va,
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v9.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v9.c
index 1abf662a0e91..81e3b528bbc9 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v9.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v9.c
@@ -622,20 +622,6 @@ bool kgd_gfx_v9_get_atc_vmid_pasid_mapping_info(struct amdgpu_device *adev,
return !!(value & ATC_VMID0_PASID_MAPPING__VALID_MASK);
}
-int kgd_gfx_v9_address_watch_disable(struct amdgpu_device *adev)
-{
- return 0;
-}
-
-int kgd_gfx_v9_address_watch_execute(struct amdgpu_device *adev,
- unsigned int watch_point_id,
- uint32_t cntl_val,
- uint32_t addr_hi,
- uint32_t addr_lo)
-{
- return 0;
-}
-
int kgd_gfx_v9_wave_control_execute(struct amdgpu_device *adev,
uint32_t gfx_index_val,
uint32_t sq_cmd)
@@ -660,13 +646,6 @@ int kgd_gfx_v9_wave_control_execute(struct amdgpu_device *adev,
return 0;
}
-uint32_t kgd_gfx_v9_address_watch_get_offset(struct amdgpu_device *adev,
- unsigned int watch_point_id,
- unsigned int reg_offset)
-{
- return 0;
-}
-
void kgd_gfx_v9_set_vm_context_page_table_base(struct amdgpu_device *adev,
uint32_t vmid, uint64_t page_table_base)
{
@@ -736,7 +715,7 @@ static void get_wave_count(struct amdgpu_device *adev, int queue_idx,
* process whose pasid is provided as a parameter. The process could have ZERO
* or more queues running and submitting waves to compute units.
*
- * @kgd: Handle of device from which to get number of waves in flight
+ * @adev: Handle of device from which to get number of waves in flight
* @pasid: Identifies the process for which this query call is invoked
* @pasid_wave_cnt: Output parameter updated with number of waves in flight that
* belong to process with given pasid
@@ -745,7 +724,7 @@ static void get_wave_count(struct amdgpu_device *adev, int queue_idx,
*
* Note: It's possible that the device has too many queues (oversubscription)
* in which case a VMID could be remapped to a different PASID. This could lead
- * to an iaccurate wave count. Following is a high-level sequence:
+ * to an inaccurate wave count. Following is a high-level sequence:
* Time T1: vmid = getVmid(); vmid is associated with Pasid P1
* Time T2: passId = getPasId(vmid); vmid is associated with Pasid P2
* In the sequence above wave count obtained from time T1 will be incorrectly
@@ -888,10 +867,7 @@ const struct kfd2kgd_calls gfx_v9_kfd2kgd = {
.hqd_sdma_is_occupied = kgd_hqd_sdma_is_occupied,
.hqd_destroy = kgd_gfx_v9_hqd_destroy,
.hqd_sdma_destroy = kgd_hqd_sdma_destroy,
- .address_watch_disable = kgd_gfx_v9_address_watch_disable,
- .address_watch_execute = kgd_gfx_v9_address_watch_execute,
.wave_control_execute = kgd_gfx_v9_wave_control_execute,
- .address_watch_get_offset = kgd_gfx_v9_address_watch_get_offset,
.get_atc_vmid_pasid_mapping_info =
kgd_gfx_v9_get_atc_vmid_pasid_mapping_info,
.set_vm_context_page_table_base = kgd_gfx_v9_set_vm_context_page_table_base,
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v9.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v9.h
index 24be49df26fd..c7ed3bc9053c 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v9.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v9.h
@@ -46,19 +46,9 @@ int kgd_gfx_v9_hqd_destroy(struct amdgpu_device *adev, void *mqd,
enum kfd_preempt_type reset_type,
unsigned int utimeout, uint32_t pipe_id,
uint32_t queue_id);
-int kgd_gfx_v9_address_watch_disable(struct amdgpu_device *adev);
-int kgd_gfx_v9_address_watch_execute(struct amdgpu_device *adev,
- unsigned int watch_point_id,
- uint32_t cntl_val,
- uint32_t addr_hi,
- uint32_t addr_lo);
int kgd_gfx_v9_wave_control_execute(struct amdgpu_device *adev,
uint32_t gfx_index_val,
uint32_t sq_cmd);
-uint32_t kgd_gfx_v9_address_watch_get_offset(struct amdgpu_device *adev,
- unsigned int watch_point_id,
- unsigned int reg_offset);
-
bool kgd_gfx_v9_get_atc_vmid_pasid_mapping_info(struct amdgpu_device *adev,
uint8_t vmid, uint16_t *p_pasid);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
index f9bab963a948..cd89d2e46852 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
@@ -121,7 +121,7 @@ static size_t amdgpu_amdkfd_acc_size(uint64_t size)
}
/**
- * @amdgpu_amdkfd_reserve_mem_limit() - Decrease available memory by size
+ * amdgpu_amdkfd_reserve_mem_limit() - Decrease available memory by size
* of buffer including any reserved for control structures
*
* @adev: Device to which allocated BO belongs to
@@ -778,7 +778,7 @@ unwind:
continue;
if (attachment[i]->bo_va) {
amdgpu_bo_reserve(bo[i], true);
- amdgpu_vm_bo_rmv(adev, attachment[i]->bo_va);
+ amdgpu_vm_bo_del(adev, attachment[i]->bo_va);
amdgpu_bo_unreserve(bo[i]);
list_del(&attachment[i]->list);
}
@@ -795,7 +795,7 @@ static void kfd_mem_detach(struct kfd_mem_attachment *attachment)
pr_debug("\t remove VA 0x%llx in entry %p\n",
attachment->va, attachment);
- amdgpu_vm_bo_rmv(attachment->adev, attachment->bo_va);
+ amdgpu_vm_bo_del(attachment->adev, attachment->bo_va);
drm_gem_object_put(&bo->tbo.base);
list_del(&attachment->list);
kfree(attachment);
@@ -842,7 +842,8 @@ static void remove_kgd_mem_from_kfd_bo_list(struct kgd_mem *mem,
*
* Returns 0 for success, negative errno for errors.
*/
-static int init_user_pages(struct kgd_mem *mem, uint64_t user_addr)
+static int init_user_pages(struct kgd_mem *mem, uint64_t user_addr,
+ bool criu_resume)
{
struct amdkfd_process_info *process_info = mem->process_info;
struct amdgpu_bo *bo = mem->bo;
@@ -864,6 +865,18 @@ static int init_user_pages(struct kgd_mem *mem, uint64_t user_addr)
goto out;
}
+ if (criu_resume) {
+ /*
+ * During a CRIU restore operation, the userptr buffer objects
+ * will be validated in the restore_userptr_work worker at a
+ * later stage when it is scheduled by another ioctl called by
+ * CRIU master process for the target pid for restore.
+ */
+ atomic_inc(&mem->invalid);
+ mutex_unlock(&process_info->lock);
+ return 0;
+ }
+
ret = amdgpu_ttm_tt_get_user_pages(bo, bo->tbo.ttm->pages);
if (ret) {
pr_err("%s: Failed to get user pages: %d\n", __func__, ret);
@@ -1452,10 +1465,39 @@ uint64_t amdgpu_amdkfd_gpuvm_get_process_page_dir(void *drm_priv)
return avm->pd_phys_addr;
}
+void amdgpu_amdkfd_block_mmu_notifications(void *p)
+{
+ struct amdkfd_process_info *pinfo = (struct amdkfd_process_info *)p;
+
+ mutex_lock(&pinfo->lock);
+ WRITE_ONCE(pinfo->block_mmu_notifications, true);
+ mutex_unlock(&pinfo->lock);
+}
+
+int amdgpu_amdkfd_criu_resume(void *p)
+{
+ int ret = 0;
+ struct amdkfd_process_info *pinfo = (struct amdkfd_process_info *)p;
+
+ mutex_lock(&pinfo->lock);
+ pr_debug("scheduling work\n");
+ atomic_inc(&pinfo->evicted_bos);
+ if (!READ_ONCE(pinfo->block_mmu_notifications)) {
+ ret = -EINVAL;
+ goto out_unlock;
+ }
+ WRITE_ONCE(pinfo->block_mmu_notifications, false);
+ schedule_delayed_work(&pinfo->restore_userptr_work, 0);
+
+out_unlock:
+ mutex_unlock(&pinfo->lock);
+ return ret;
+}
+
int amdgpu_amdkfd_gpuvm_alloc_memory_of_gpu(
struct amdgpu_device *adev, uint64_t va, uint64_t size,
void *drm_priv, struct kgd_mem **mem,
- uint64_t *offset, uint32_t flags)
+ uint64_t *offset, uint32_t flags, bool criu_resume)
{
struct amdgpu_vm *avm = drm_priv_to_vm(drm_priv);
enum ttm_bo_type bo_type = ttm_bo_type_device;
@@ -1558,7 +1600,8 @@ int amdgpu_amdkfd_gpuvm_alloc_memory_of_gpu(
add_kgd_mem_to_kfd_bo_list(*mem, avm->process_info, user_addr);
if (user_addr) {
- ret = init_user_pages(*mem, user_addr);
+ pr_debug("creating userptr BO for user_addr = %llu\n", user_addr);
+ ret = init_user_pages(*mem, user_addr, criu_resume);
if (ret)
goto allocate_init_user_pages_failed;
} else if (flags & (KFD_IOC_ALLOC_MEM_FLAGS_DOORBELL |
@@ -1813,12 +1856,6 @@ int amdgpu_amdkfd_gpuvm_map_memory_to_gpu(
true);
ret = unreserve_bo_and_vms(&ctx, false, false);
- /* Only apply no TLB flush on Aldebaran to
- * workaround regressions on other Asics.
- */
- if (table_freed && (adev->asic_type != CHIP_ALDEBARAN))
- *table_freed = true;
-
goto out;
out_unreserve:
@@ -2068,6 +2105,10 @@ int amdgpu_amdkfd_evict_userptr(struct kgd_mem *mem,
int evicted_bos;
int r = 0;
+ /* Do not process MMU notifications until stage-4 IOCTL is received */
+ if (READ_ONCE(process_info->block_mmu_notifications))
+ return 0;
+
atomic_inc(&mem->invalid);
evicted_bos = atomic_inc_return(&process_info->evicted_bos);
if (evicted_bos == 1) {
@@ -2635,3 +2676,14 @@ int amdgpu_amdkfd_get_tile_config(struct amdgpu_device *adev,
return 0;
}
+
+bool amdgpu_amdkfd_bo_mapped_to_dev(struct amdgpu_device *adev, struct kgd_mem *mem)
+{
+ struct kfd_mem_attachment *entry;
+
+ list_for_each_entry(entry, &mem->attachments, list) {
+ if (entry->is_mapped && entry->adev == adev)
+ return true;
+ }
+ return false;
+}
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c
index 12a6b1c99c93..9ba4817a9148 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c
@@ -1083,6 +1083,7 @@ int amdgpu_atombios_get_clock_dividers(struct amdgpu_device *adev,
return 0;
}
+#ifdef CONFIG_DRM_AMDGPU_SI
int amdgpu_atombios_get_memory_pll_dividers(struct amdgpu_device *adev,
u32 clock,
bool strobe_mode,
@@ -1503,6 +1504,7 @@ int amdgpu_atombios_init_mc_reg_table(struct amdgpu_device *adev,
}
return -EINVAL;
}
+#endif
bool amdgpu_atombios_has_gpu_virtualization_table(struct amdgpu_device *adev)
{
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.h
index 27e74b1fc260..4153d520e2a3 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.h
@@ -160,6 +160,7 @@ int amdgpu_atombios_get_clock_dividers(struct amdgpu_device *adev,
bool strobe_mode,
struct atom_clock_dividers *dividers);
+#ifdef CONFIG_DRM_AMDGPU_SI
int amdgpu_atombios_get_memory_pll_dividers(struct amdgpu_device *adev,
u32 clock,
bool strobe_mode,
@@ -179,6 +180,17 @@ int amdgpu_atombios_get_voltage_table(struct amdgpu_device *adev,
int amdgpu_atombios_init_mc_reg_table(struct amdgpu_device *adev,
u8 module_index,
struct atom_mc_reg_table *reg_table);
+int amdgpu_atombios_get_max_vddc(struct amdgpu_device *adev, u8 voltage_type,
+ u16 voltage_id, u16 *voltage);
+int amdgpu_atombios_get_leakage_vddc_based_on_leakage_idx(struct amdgpu_device *adev,
+ u16 *voltage,
+ u16 leakage_idx);
+void amdgpu_atombios_get_default_voltages(struct amdgpu_device *adev,
+ u16 *vddc, u16 *vddci, u16 *mvdd);
+int amdgpu_atombios_get_svi2_info(struct amdgpu_device *adev,
+ u8 voltage_type,
+ u8 *svd_gpio_id, u8 *svc_gpio_id);
+#endif
bool amdgpu_atombios_has_gpu_virtualization_table(struct amdgpu_device *adev);
@@ -190,21 +202,11 @@ void amdgpu_atombios_scratch_regs_set_backlight_level(struct amdgpu_device *adev
bool amdgpu_atombios_scratch_need_asic_init(struct amdgpu_device *adev);
void amdgpu_atombios_copy_swap(u8 *dst, u8 *src, u8 num_bytes, bool to_le);
-int amdgpu_atombios_get_max_vddc(struct amdgpu_device *adev, u8 voltage_type,
- u16 voltage_id, u16 *voltage);
-int amdgpu_atombios_get_leakage_vddc_based_on_leakage_idx(struct amdgpu_device *adev,
- u16 *voltage,
- u16 leakage_idx);
-void amdgpu_atombios_get_default_voltages(struct amdgpu_device *adev,
- u16 *vddc, u16 *vddci, u16 *mvdd);
int amdgpu_atombios_get_clock_dividers(struct amdgpu_device *adev,
u8 clock_type,
u32 clock,
bool strobe_mode,
struct atom_clock_dividers *dividers);
-int amdgpu_atombios_get_svi2_info(struct amdgpu_device *adev,
- u8 voltage_type,
- u8 *svd_gpio_id, u8 *svc_gpio_id);
int amdgpu_atombios_get_data_table(struct amdgpu_device *adev,
uint32_t table,
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_benchmark.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_benchmark.c
index 313517f7cf10..edc6377ec5ff 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_benchmark.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_benchmark.c
@@ -29,14 +29,13 @@
#define AMDGPU_BENCHMARK_COMMON_MODES_N 17
static int amdgpu_benchmark_do_move(struct amdgpu_device *adev, unsigned size,
- uint64_t saddr, uint64_t daddr, int n)
+ uint64_t saddr, uint64_t daddr, int n, s64 *time_ms)
{
- unsigned long start_jiffies;
- unsigned long end_jiffies;
+ ktime_t stime, etime;
struct dma_fence *fence;
int i, r;
- start_jiffies = jiffies;
+ stime = ktime_get();
for (i = 0; i < n; i++) {
struct amdgpu_ring *ring = adev->mman.buffer_funcs_ring;
r = amdgpu_copy_buffer(ring, saddr, daddr, size, NULL, &fence,
@@ -48,120 +47,81 @@ static int amdgpu_benchmark_do_move(struct amdgpu_device *adev, unsigned size,
if (r)
goto exit_do_move;
}
- end_jiffies = jiffies;
- r = jiffies_to_msecs(end_jiffies - start_jiffies);
exit_do_move:
+ etime = ktime_get();
+ *time_ms = ktime_ms_delta(etime, stime);
+
return r;
}
-static void amdgpu_benchmark_log_results(int n, unsigned size,
- unsigned int time,
+static void amdgpu_benchmark_log_results(struct amdgpu_device *adev,
+ int n, unsigned size,
+ s64 time_ms,
unsigned sdomain, unsigned ddomain,
char *kind)
{
- unsigned int throughput = (n * (size >> 10)) / time;
- DRM_INFO("amdgpu: %s %u bo moves of %u kB from"
- " %d to %d in %u ms, throughput: %u Mb/s or %u MB/s\n",
- kind, n, size >> 10, sdomain, ddomain, time,
+ s64 throughput = (n * (size >> 10));
+
+ throughput = div64_s64(throughput, time_ms);
+
+ dev_info(adev->dev, "amdgpu: %s %u bo moves of %u kB from"
+ " %d to %d in %lld ms, throughput: %lld Mb/s or %lld MB/s\n",
+ kind, n, size >> 10, sdomain, ddomain, time_ms,
throughput * 8, throughput);
}
-static void amdgpu_benchmark_move(struct amdgpu_device *adev, unsigned size,
- unsigned sdomain, unsigned ddomain)
+static int amdgpu_benchmark_move(struct amdgpu_device *adev, unsigned size,
+ unsigned sdomain, unsigned ddomain)
{
struct amdgpu_bo *dobj = NULL;
struct amdgpu_bo *sobj = NULL;
- struct amdgpu_bo_param bp;
uint64_t saddr, daddr;
+ s64 time_ms;
int r, n;
- int time;
-
- memset(&bp, 0, sizeof(bp));
- bp.size = size;
- bp.byte_align = PAGE_SIZE;
- bp.domain = sdomain;
- bp.flags = 0;
- bp.type = ttm_bo_type_kernel;
- bp.resv = NULL;
- bp.bo_ptr_size = sizeof(struct amdgpu_bo);
n = AMDGPU_BENCHMARK_ITERATIONS;
- r = amdgpu_bo_create(adev, &bp, &sobj);
- if (r) {
- goto out_cleanup;
- }
- r = amdgpu_bo_reserve(sobj, false);
- if (unlikely(r != 0))
- goto out_cleanup;
- r = amdgpu_bo_pin(sobj, sdomain);
- if (r) {
- amdgpu_bo_unreserve(sobj);
- goto out_cleanup;
- }
- r = amdgpu_ttm_alloc_gart(&sobj->tbo);
- amdgpu_bo_unreserve(sobj);
- if (r) {
- goto out_cleanup;
- }
- saddr = amdgpu_bo_gpu_offset(sobj);
- bp.domain = ddomain;
- r = amdgpu_bo_create(adev, &bp, &dobj);
- if (r) {
- goto out_cleanup;
- }
- r = amdgpu_bo_reserve(dobj, false);
- if (unlikely(r != 0))
- goto out_cleanup;
- r = amdgpu_bo_pin(dobj, ddomain);
- if (r) {
- amdgpu_bo_unreserve(sobj);
+
+ r = amdgpu_bo_create_kernel(adev, size,
+ PAGE_SIZE, sdomain,
+ &sobj,
+ &saddr,
+ NULL);
+ if (r)
goto out_cleanup;
- }
- r = amdgpu_ttm_alloc_gart(&dobj->tbo);
- amdgpu_bo_unreserve(dobj);
- if (r) {
+ r = amdgpu_bo_create_kernel(adev, size,
+ PAGE_SIZE, ddomain,
+ &dobj,
+ &daddr,
+ NULL);
+ if (r)
goto out_cleanup;
- }
- daddr = amdgpu_bo_gpu_offset(dobj);
if (adev->mman.buffer_funcs) {
- time = amdgpu_benchmark_do_move(adev, size, saddr, daddr, n);
- if (time < 0)
+ r = amdgpu_benchmark_do_move(adev, size, saddr, daddr, n, &time_ms);
+ if (r)
goto out_cleanup;
- if (time > 0)
- amdgpu_benchmark_log_results(n, size, time,
+ else
+ amdgpu_benchmark_log_results(adev, n, size, time_ms,
sdomain, ddomain, "dma");
}
out_cleanup:
/* Check error value now. The value can be overwritten when clean up.*/
- if (r) {
- DRM_ERROR("Error while benchmarking BO move.\n");
- }
+ if (r < 0)
+ dev_info(adev->dev, "Error while benchmarking BO move.\n");
- if (sobj) {
- r = amdgpu_bo_reserve(sobj, true);
- if (likely(r == 0)) {
- amdgpu_bo_unpin(sobj);
- amdgpu_bo_unreserve(sobj);
- }
- amdgpu_bo_unref(&sobj);
- }
- if (dobj) {
- r = amdgpu_bo_reserve(dobj, true);
- if (likely(r == 0)) {
- amdgpu_bo_unpin(dobj);
- amdgpu_bo_unreserve(dobj);
- }
- amdgpu_bo_unref(&dobj);
- }
+ if (sobj)
+ amdgpu_bo_free_kernel(&sobj, &saddr, NULL);
+ if (dobj)
+ amdgpu_bo_free_kernel(&dobj, &daddr, NULL);
+ return r;
}
-void amdgpu_benchmark(struct amdgpu_device *adev, int test_number)
+int amdgpu_benchmark(struct amdgpu_device *adev, int test_number)
{
- int i;
+ int i, r;
static const int common_modes[AMDGPU_BENCHMARK_COMMON_MODES_N] = {
640 * 480 * 4,
720 * 480 * 4,
@@ -182,63 +142,119 @@ void amdgpu_benchmark(struct amdgpu_device *adev, int test_number)
1920 * 1200 * 4
};
+ mutex_lock(&adev->benchmark_mutex);
switch (test_number) {
case 1:
+ dev_info(adev->dev,
+ "benchmark test: %d (simple test, VRAM to GTT and GTT to VRAM)\n",
+ test_number);
/* simple test, VRAM to GTT and GTT to VRAM */
- amdgpu_benchmark_move(adev, 1024*1024, AMDGPU_GEM_DOMAIN_GTT,
- AMDGPU_GEM_DOMAIN_VRAM);
- amdgpu_benchmark_move(adev, 1024*1024, AMDGPU_GEM_DOMAIN_VRAM,
- AMDGPU_GEM_DOMAIN_GTT);
+ r = amdgpu_benchmark_move(adev, 1024*1024, AMDGPU_GEM_DOMAIN_GTT,
+ AMDGPU_GEM_DOMAIN_VRAM);
+ if (r)
+ goto done;
+ r = amdgpu_benchmark_move(adev, 1024*1024, AMDGPU_GEM_DOMAIN_VRAM,
+ AMDGPU_GEM_DOMAIN_GTT);
+ if (r)
+ goto done;
break;
case 2:
+ dev_info(adev->dev,
+ "benchmark test: %d (simple test, VRAM to VRAM)\n",
+ test_number);
/* simple test, VRAM to VRAM */
- amdgpu_benchmark_move(adev, 1024*1024, AMDGPU_GEM_DOMAIN_VRAM,
- AMDGPU_GEM_DOMAIN_VRAM);
+ r = amdgpu_benchmark_move(adev, 1024*1024, AMDGPU_GEM_DOMAIN_VRAM,
+ AMDGPU_GEM_DOMAIN_VRAM);
+ if (r)
+ goto done;
break;
case 3:
+ dev_info(adev->dev,
+ "benchmark test: %d (GTT to VRAM, buffer size sweep, powers of 2)\n",
+ test_number);
/* GTT to VRAM, buffer size sweep, powers of 2 */
- for (i = 1; i <= 16384; i <<= 1)
- amdgpu_benchmark_move(adev, i * AMDGPU_GPU_PAGE_SIZE,
- AMDGPU_GEM_DOMAIN_GTT,
- AMDGPU_GEM_DOMAIN_VRAM);
+ for (i = 1; i <= 16384; i <<= 1) {
+ r = amdgpu_benchmark_move(adev, i * AMDGPU_GPU_PAGE_SIZE,
+ AMDGPU_GEM_DOMAIN_GTT,
+ AMDGPU_GEM_DOMAIN_VRAM);
+ if (r)
+ goto done;
+ }
break;
case 4:
+ dev_info(adev->dev,
+ "benchmark test: %d (VRAM to GTT, buffer size sweep, powers of 2)\n",
+ test_number);
/* VRAM to GTT, buffer size sweep, powers of 2 */
- for (i = 1; i <= 16384; i <<= 1)
- amdgpu_benchmark_move(adev, i * AMDGPU_GPU_PAGE_SIZE,
- AMDGPU_GEM_DOMAIN_VRAM,
- AMDGPU_GEM_DOMAIN_GTT);
+ for (i = 1; i <= 16384; i <<= 1) {
+ r = amdgpu_benchmark_move(adev, i * AMDGPU_GPU_PAGE_SIZE,
+ AMDGPU_GEM_DOMAIN_VRAM,
+ AMDGPU_GEM_DOMAIN_GTT);
+ if (r)
+ goto done;
+ }
break;
case 5:
+ dev_info(adev->dev,
+ "benchmark test: %d (VRAM to VRAM, buffer size sweep, powers of 2)\n",
+ test_number);
/* VRAM to VRAM, buffer size sweep, powers of 2 */
- for (i = 1; i <= 16384; i <<= 1)
- amdgpu_benchmark_move(adev, i * AMDGPU_GPU_PAGE_SIZE,
- AMDGPU_GEM_DOMAIN_VRAM,
- AMDGPU_GEM_DOMAIN_VRAM);
+ for (i = 1; i <= 16384; i <<= 1) {
+ r = amdgpu_benchmark_move(adev, i * AMDGPU_GPU_PAGE_SIZE,
+ AMDGPU_GEM_DOMAIN_VRAM,
+ AMDGPU_GEM_DOMAIN_VRAM);
+ if (r)
+ goto done;
+ }
break;
case 6:
+ dev_info(adev->dev,
+ "benchmark test: %d (GTT to VRAM, buffer size sweep, common modes)\n",
+ test_number);
/* GTT to VRAM, buffer size sweep, common modes */
- for (i = 0; i < AMDGPU_BENCHMARK_COMMON_MODES_N; i++)
- amdgpu_benchmark_move(adev, common_modes[i],
- AMDGPU_GEM_DOMAIN_GTT,
- AMDGPU_GEM_DOMAIN_VRAM);
+ for (i = 0; i < AMDGPU_BENCHMARK_COMMON_MODES_N; i++) {
+ r = amdgpu_benchmark_move(adev, common_modes[i],
+ AMDGPU_GEM_DOMAIN_GTT,
+ AMDGPU_GEM_DOMAIN_VRAM);
+ if (r)
+ goto done;
+ }
break;
case 7:
+ dev_info(adev->dev,
+ "benchmark test: %d (VRAM to GTT, buffer size sweep, common modes)\n",
+ test_number);
/* VRAM to GTT, buffer size sweep, common modes */
- for (i = 0; i < AMDGPU_BENCHMARK_COMMON_MODES_N; i++)
- amdgpu_benchmark_move(adev, common_modes[i],
- AMDGPU_GEM_DOMAIN_VRAM,
- AMDGPU_GEM_DOMAIN_GTT);
+ for (i = 0; i < AMDGPU_BENCHMARK_COMMON_MODES_N; i++) {
+ r = amdgpu_benchmark_move(adev, common_modes[i],
+ AMDGPU_GEM_DOMAIN_VRAM,
+ AMDGPU_GEM_DOMAIN_GTT);
+ if (r)
+ goto done;
+ }
break;
case 8:
+ dev_info(adev->dev,
+ "benchmark test: %d (VRAM to VRAM, buffer size sweep, common modes)\n",
+ test_number);
/* VRAM to VRAM, buffer size sweep, common modes */
- for (i = 0; i < AMDGPU_BENCHMARK_COMMON_MODES_N; i++)
- amdgpu_benchmark_move(adev, common_modes[i],
+ for (i = 0; i < AMDGPU_BENCHMARK_COMMON_MODES_N; i++) {
+ r = amdgpu_benchmark_move(adev, common_modes[i],
AMDGPU_GEM_DOMAIN_VRAM,
AMDGPU_GEM_DOMAIN_VRAM);
+ if (r)
+ goto done;
+ }
break;
default:
- DRM_ERROR("Unknown benchmark\n");
+ dev_info(adev->dev, "Unknown benchmark %d\n", test_number);
+ r = -EINVAL;
+ break;
}
+
+done:
+ mutex_unlock(&adev->benchmark_mutex);
+
+ return r;
}
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_bios.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_bios.c
index 27b19503773b..0eddca795e96 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_bios.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_bios.c
@@ -464,3 +464,41 @@ success:
adev->is_atom_fw = (adev->asic_type >= CHIP_VEGA10) ? true : false;
return true;
}
+
+/* helper function for soc15 and onwards to read bios from rom */
+bool amdgpu_soc15_read_bios_from_rom(struct amdgpu_device *adev,
+ u8 *bios, u32 length_bytes)
+{
+ u32 *dw_ptr;
+ u32 i, length_dw;
+ u32 rom_index_offset;
+ u32 rom_data_offset;
+
+ if (bios == NULL)
+ return false;
+ if (length_bytes == 0)
+ return false;
+ /* APU vbios image is part of sbios image */
+ if (adev->flags & AMD_IS_APU)
+ return false;
+ if (!adev->smuio.funcs ||
+ !adev->smuio.funcs->get_rom_index_offset ||
+ !adev->smuio.funcs->get_rom_data_offset)
+ return false;
+
+ dw_ptr = (u32 *)bios;
+ length_dw = ALIGN(length_bytes, 4) / 4;
+
+ rom_index_offset =
+ adev->smuio.funcs->get_rom_index_offset(adev);
+ rom_data_offset =
+ adev->smuio.funcs->get_rom_data_offset(adev);
+
+ /* set rom index to 0 */
+ WREG32(rom_index_offset, 0);
+ /* read out the rom data */
+ for (i = 0; i < length_dw; i++)
+ dw_ptr[i] = RREG32(rom_data_offset);
+
+ return true;
+}
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c
index c16a2704ced6..673078faa27a 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c
@@ -26,7 +26,7 @@
#include <drm/drm_edid.h>
#include <drm/drm_fb_helper.h>
-#include <drm/drm_dp_helper.h>
+#include <drm/dp/drm_dp_helper.h>
#include <drm/drm_probe_helper.h>
#include <drm/amdgpu_drm.h>
#include "amdgpu.h"
@@ -175,7 +175,7 @@ int amdgpu_connector_get_monitor_bpc(struct drm_connector *connector)
/* Check if bpc is within clock limit. Try to degrade gracefully otherwise */
if ((bpc == 12) && (mode_clock * 3/2 > max_tmds_clock)) {
- if ((connector->display_info.edid_hdmi_dc_modes & DRM_EDID_HDMI_DC_30) &&
+ if ((connector->display_info.edid_hdmi_rgb444_dc_modes & DRM_EDID_HDMI_DC_30) &&
(mode_clock * 5/4 <= max_tmds_clock))
bpc = 10;
else
@@ -626,7 +626,7 @@ amdgpu_connector_fixup_lcd_native_mode(struct drm_encoder *encoder,
if (mode->type & DRM_MODE_TYPE_PREFERRED) {
if (mode->hdisplay != native_mode->hdisplay ||
mode->vdisplay != native_mode->vdisplay)
- memcpy(native_mode, mode, sizeof(*mode));
+ drm_mode_copy(native_mode, mode);
}
}
@@ -635,7 +635,7 @@ amdgpu_connector_fixup_lcd_native_mode(struct drm_encoder *encoder,
list_for_each_entry_safe(mode, t, &connector->probed_modes, head) {
if (mode->hdisplay == native_mode->hdisplay &&
mode->vdisplay == native_mode->vdisplay) {
- *native_mode = *mode;
+ drm_mode_copy(native_mode, mode);
drm_mode_set_crtcinfo(native_mode, CRTC_INTERLACE_HALVE_V);
DRM_DEBUG_KMS("Determined LVDS native mode details from EDID\n");
break;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
index 06d07502a1f6..970b065e9a6b 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
@@ -32,6 +32,7 @@
#include <drm/amdgpu_drm.h>
#include <drm/drm_syncobj.h>
+#include "amdgpu_cs.h"
#include "amdgpu.h"
#include "amdgpu_trace.h"
#include "amdgpu_gmc.h"
@@ -127,8 +128,6 @@ static int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p, union drm_amdgpu_cs
goto free_chunk;
}
- mutex_lock(&p->ctx->lock);
-
/* skip guilty context job */
if (atomic_read(&p->ctx->guilty) == 1) {
ret = -ECANCELED;
@@ -314,7 +313,7 @@ static void amdgpu_cs_get_threshold_for_moves(struct amdgpu_device *adev,
}
total_vram = adev->gmc.real_vram_size - atomic64_read(&adev->vram_pin_size);
- used_vram = amdgpu_vram_mgr_usage(&adev->mman.vram_mgr);
+ used_vram = ttm_resource_manager_usage(&adev->mman.vram_mgr.manager);
free_vram = used_vram >= total_vram ? 0 : total_vram - used_vram;
spin_lock(&adev->mm_stats.lock);
@@ -341,7 +340,7 @@ static void amdgpu_cs_get_threshold_for_moves(struct amdgpu_device *adev,
if (free_vram >= 128 * 1024 * 1024 || free_vram >= total_vram / 8) {
s64 min_us;
- /* Be more aggresive on dGPUs. Try to fill a portion of free
+ /* Be more aggressive on dGPUs. Try to fill a portion of free
* VRAM now.
*/
if (!(adev->flags & AMD_IS_APU))
@@ -585,6 +584,16 @@ static int amdgpu_cs_parser_bos(struct amdgpu_cs_parser *p,
}
}
+ /* Move fence waiting after getting reservation lock of
+ * PD root. Then there is no need on a ctx mutex lock.
+ */
+ r = amdgpu_ctx_wait_prev_fence(p->ctx, p->entity);
+ if (unlikely(r != 0)) {
+ if (r != -ERESTARTSYS)
+ DRM_ERROR("amdgpu_ctx_wait_prev_fence failed.\n");
+ goto error_validate;
+ }
+
amdgpu_cs_get_threshold_for_moves(p->adev, &p->bytes_moved_threshold,
&p->bytes_moved_vis_threshold);
p->bytes_moved = 0;
@@ -700,7 +709,6 @@ static void amdgpu_cs_parser_fini(struct amdgpu_cs_parser *parser, int error,
dma_fence_put(parser->fence);
if (parser->ctx) {
- mutex_unlock(&parser->ctx->lock);
amdgpu_ctx_put(parser->ctx);
}
if (parser->bo_list)
@@ -775,12 +783,12 @@ static int amdgpu_cs_vm_handling(struct amdgpu_cs_parser *p)
memcpy(ib->ptr, kptr, chunk_ib->ib_bytes);
amdgpu_bo_kunmap(aobj);
- r = amdgpu_ring_parse_cs(ring, p, j);
+ r = amdgpu_ring_parse_cs(ring, p, p->job, ib);
if (r)
return r;
} else {
ib->ptr = (uint32_t *)kptr;
- r = amdgpu_ring_patch_cs_in_place(ring, p, j);
+ r = amdgpu_ring_patch_cs_in_place(ring, p, p->job, ib);
amdgpu_bo_kunmap(aobj);
if (r)
return r;
@@ -944,7 +952,7 @@ static int amdgpu_cs_ib_fill(struct amdgpu_device *adev,
if (parser->job->uf_addr && ring->funcs->no_user_fence)
return -EINVAL;
- return amdgpu_ctx_wait_prev_fence(parser->ctx, parser->entity);
+ return 0;
}
static int amdgpu_cs_process_fence_dep(struct amdgpu_cs_parser *p,
@@ -1272,16 +1280,13 @@ static int amdgpu_cs_submit(struct amdgpu_cs_parser *p,
continue;
/*
- * Work around dma_resv shortcommings by wrapping up the
+ * Work around dma_resv shortcomings by wrapping up the
* submission in a dma_fence_chain and add it as exclusive
- * fence, but first add the submission as shared fence to make
- * sure that shared fences never signal before the exclusive
- * one.
+ * fence.
*/
dma_fence_chain_init(chain, dma_resv_excl_fence(resv),
dma_fence_get(p->fence), 1);
- dma_resv_add_shared_fence(resv, p->fence);
rcu_assign_pointer(resv->fence_excl, &chain->base);
e->chain = NULL;
}
@@ -1363,7 +1368,6 @@ int amdgpu_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
goto out;
r = amdgpu_cs_submit(&parser, cs);
-
out:
amdgpu_cs_parser_fini(&parser, r, reserved_buffers);
@@ -1509,6 +1513,7 @@ int amdgpu_cs_fence_to_handle_ioctl(struct drm_device *dev, void *data,
return 0;
default:
+ dma_fence_put(fence);
return -EINVAL;
}
}
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.h
new file mode 100644
index 000000000000..30ecc4917f81
--- /dev/null
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright 2022 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+#ifndef __AMDGPU_CS_H__
+#define __AMDGPU_CS_H__
+
+#include "amdgpu_job.h"
+#include "amdgpu_bo_list.h"
+#include "amdgpu_ring.h"
+
+struct amdgpu_bo_va_mapping;
+
+struct amdgpu_cs_chunk {
+ uint32_t chunk_id;
+ uint32_t length_dw;
+ void *kdata;
+};
+
+struct amdgpu_cs_post_dep {
+ struct drm_syncobj *syncobj;
+ struct dma_fence_chain *chain;
+ u64 point;
+};
+
+struct amdgpu_cs_parser {
+ struct amdgpu_device *adev;
+ struct drm_file *filp;
+ struct amdgpu_ctx *ctx;
+
+ /* chunks */
+ unsigned nchunks;
+ struct amdgpu_cs_chunk *chunks;
+
+ /* scheduler job object */
+ struct amdgpu_job *job;
+ struct drm_sched_entity *entity;
+
+ /* buffer objects */
+ struct ww_acquire_ctx ticket;
+ struct amdgpu_bo_list *bo_list;
+ struct amdgpu_mn *mn;
+ struct amdgpu_bo_list_entry vm_pd;
+ struct list_head validated;
+ struct dma_fence *fence;
+ uint64_t bytes_moved_threshold;
+ uint64_t bytes_moved_vis_threshold;
+ uint64_t bytes_moved;
+ uint64_t bytes_moved_vis;
+
+ /* user fence */
+ struct amdgpu_bo_list_entry uf_entry;
+
+ unsigned num_post_deps;
+ struct amdgpu_cs_post_dep *post_deps;
+};
+
+int amdgpu_cs_find_mapping(struct amdgpu_cs_parser *parser,
+ uint64_t addr, struct amdgpu_bo **bo,
+ struct amdgpu_bo_va_mapping **mapping);
+
+#endif
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_csa.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_csa.c
index da21e60bb827..c6d4d41c4393 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_csa.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_csa.c
@@ -98,7 +98,7 @@ int amdgpu_map_static_csa(struct amdgpu_device *adev, struct amdgpu_vm *vm,
if (r) {
DRM_ERROR("failed to do bo_map on static CSA, err=%d\n", r);
- amdgpu_vm_bo_rmv(adev, *bo_va);
+ amdgpu_vm_bo_del(adev, *bo_va);
ttm_eu_backoff_reservation(&ticket, &list);
return r;
}
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c
index 468003583b2a..5981c7d9bd48 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c
@@ -23,6 +23,7 @@
*/
#include <drm/drm_auth.h>
+#include <drm/drm_drv.h>
#include "amdgpu.h"
#include "amdgpu_sched.h"
#include "amdgpu_ras.h"
@@ -204,9 +205,15 @@ static int amdgpu_ctx_init_entity(struct amdgpu_ctx *ctx, u32 hw_ip,
if (r)
goto error_free_entity;
- ctx->entities[hw_ip][ring] = entity;
+ /* It's not an error if we fail to install the new entity */
+ if (cmpxchg(&ctx->entities[hw_ip][ring], NULL, entity))
+ goto cleanup_entity;
+
return 0;
+cleanup_entity:
+ drm_sched_entity_fini(&entity->entity);
+
error_free_entity:
kfree(entity);
@@ -230,13 +237,13 @@ static int amdgpu_ctx_init(struct amdgpu_device *adev,
kref_init(&ctx->refcount);
spin_lock_init(&ctx->ring_lock);
- mutex_init(&ctx->lock);
ctx->reset_counter = atomic_read(&adev->gpu_reset_counter);
ctx->reset_counter_query = ctx->reset_counter;
ctx->vram_lost_counter = atomic_read(&adev->vram_lost_counter);
ctx->init_priority = priority;
ctx->override_priority = AMDGPU_CTX_PRIORITY_UNSET;
+ ctx->stable_pstate = AMDGPU_CTX_STABLE_PSTATE_NONE;
return 0;
}
@@ -255,11 +262,85 @@ static void amdgpu_ctx_fini_entity(struct amdgpu_ctx_entity *entity)
kfree(entity);
}
+static int amdgpu_ctx_get_stable_pstate(struct amdgpu_ctx *ctx,
+ u32 *stable_pstate)
+{
+ struct amdgpu_device *adev = ctx->adev;
+ enum amd_dpm_forced_level current_level;
+
+ current_level = amdgpu_dpm_get_performance_level(adev);
+
+ switch (current_level) {
+ case AMD_DPM_FORCED_LEVEL_PROFILE_STANDARD:
+ *stable_pstate = AMDGPU_CTX_STABLE_PSTATE_STANDARD;
+ break;
+ case AMD_DPM_FORCED_LEVEL_PROFILE_MIN_SCLK:
+ *stable_pstate = AMDGPU_CTX_STABLE_PSTATE_MIN_SCLK;
+ break;
+ case AMD_DPM_FORCED_LEVEL_PROFILE_MIN_MCLK:
+ *stable_pstate = AMDGPU_CTX_STABLE_PSTATE_MIN_MCLK;
+ break;
+ case AMD_DPM_FORCED_LEVEL_PROFILE_PEAK:
+ *stable_pstate = AMDGPU_CTX_STABLE_PSTATE_PEAK;
+ break;
+ default:
+ *stable_pstate = AMDGPU_CTX_STABLE_PSTATE_NONE;
+ break;
+ }
+ return 0;
+}
+
+static int amdgpu_ctx_set_stable_pstate(struct amdgpu_ctx *ctx,
+ u32 stable_pstate)
+{
+ struct amdgpu_device *adev = ctx->adev;
+ enum amd_dpm_forced_level level;
+ int r;
+
+ mutex_lock(&adev->pm.stable_pstate_ctx_lock);
+ if (adev->pm.stable_pstate_ctx && adev->pm.stable_pstate_ctx != ctx) {
+ r = -EBUSY;
+ goto done;
+ }
+
+ switch (stable_pstate) {
+ case AMDGPU_CTX_STABLE_PSTATE_NONE:
+ level = AMD_DPM_FORCED_LEVEL_AUTO;
+ break;
+ case AMDGPU_CTX_STABLE_PSTATE_STANDARD:
+ level = AMD_DPM_FORCED_LEVEL_PROFILE_STANDARD;
+ break;
+ case AMDGPU_CTX_STABLE_PSTATE_MIN_SCLK:
+ level = AMD_DPM_FORCED_LEVEL_PROFILE_MIN_SCLK;
+ break;
+ case AMDGPU_CTX_STABLE_PSTATE_MIN_MCLK:
+ level = AMD_DPM_FORCED_LEVEL_PROFILE_MIN_MCLK;
+ break;
+ case AMDGPU_CTX_STABLE_PSTATE_PEAK:
+ level = AMD_DPM_FORCED_LEVEL_PROFILE_PEAK;
+ break;
+ default:
+ r = -EINVAL;
+ goto done;
+ }
+
+ r = amdgpu_dpm_force_performance_level(adev, level);
+
+ if (level == AMD_DPM_FORCED_LEVEL_AUTO)
+ adev->pm.stable_pstate_ctx = NULL;
+ else
+ adev->pm.stable_pstate_ctx = ctx;
+done:
+ mutex_unlock(&adev->pm.stable_pstate_ctx_lock);
+
+ return r;
+}
+
static void amdgpu_ctx_fini(struct kref *ref)
{
struct amdgpu_ctx *ctx = container_of(ref, struct amdgpu_ctx, refcount);
struct amdgpu_device *adev = ctx->adev;
- unsigned i, j;
+ unsigned i, j, idx;
if (!adev)
return;
@@ -271,7 +352,11 @@ static void amdgpu_ctx_fini(struct kref *ref)
}
}
- mutex_destroy(&ctx->lock);
+ if (drm_dev_enter(&adev->ddev, &idx)) {
+ amdgpu_ctx_set_stable_pstate(ctx, AMDGPU_CTX_STABLE_PSTATE_NONE);
+ drm_dev_exit(idx);
+ }
+
kfree(ctx);
}
@@ -467,11 +552,41 @@ static int amdgpu_ctx_query2(struct amdgpu_device *adev,
return 0;
}
+
+
+static int amdgpu_ctx_stable_pstate(struct amdgpu_device *adev,
+ struct amdgpu_fpriv *fpriv, uint32_t id,
+ bool set, u32 *stable_pstate)
+{
+ struct amdgpu_ctx *ctx;
+ struct amdgpu_ctx_mgr *mgr;
+ int r;
+
+ if (!fpriv)
+ return -EINVAL;
+
+ mgr = &fpriv->ctx_mgr;
+ mutex_lock(&mgr->lock);
+ ctx = idr_find(&mgr->ctx_handles, id);
+ if (!ctx) {
+ mutex_unlock(&mgr->lock);
+ return -EINVAL;
+ }
+
+ if (set)
+ r = amdgpu_ctx_set_stable_pstate(ctx, *stable_pstate);
+ else
+ r = amdgpu_ctx_get_stable_pstate(ctx, stable_pstate);
+
+ mutex_unlock(&mgr->lock);
+ return r;
+}
+
int amdgpu_ctx_ioctl(struct drm_device *dev, void *data,
struct drm_file *filp)
{
int r;
- uint32_t id;
+ uint32_t id, stable_pstate;
int32_t priority;
union drm_amdgpu_ctx *args = data;
@@ -500,6 +615,21 @@ int amdgpu_ctx_ioctl(struct drm_device *dev, void *data,
case AMDGPU_CTX_OP_QUERY_STATE2:
r = amdgpu_ctx_query2(adev, fpriv, id, &args->out);
break;
+ case AMDGPU_CTX_OP_GET_STABLE_PSTATE:
+ if (args->in.flags)
+ return -EINVAL;
+ r = amdgpu_ctx_stable_pstate(adev, fpriv, id, false, &stable_pstate);
+ if (!r)
+ args->out.pstate.flags = stable_pstate;
+ break;
+ case AMDGPU_CTX_OP_SET_STABLE_PSTATE:
+ if (args->in.flags & ~AMDGPU_CTX_STABLE_PSTATE_FLAGS_MASK)
+ return -EINVAL;
+ stable_pstate = args->in.flags & AMDGPU_CTX_STABLE_PSTATE_FLAGS_MASK;
+ if (stable_pstate > AMDGPU_CTX_STABLE_PSTATE_PEAK)
+ return -EINVAL;
+ r = amdgpu_ctx_stable_pstate(adev, fpriv, id, true, &stable_pstate);
+ break;
default:
return -EINVAL;
}
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.h
index a44b8b8ed39c..d0cbfcea90f7 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.h
@@ -49,10 +49,10 @@ struct amdgpu_ctx {
bool preamble_presented;
int32_t init_priority;
int32_t override_priority;
- struct mutex lock;
atomic_t guilty;
unsigned long ras_counter_ce;
unsigned long ras_counter_ue;
+ uint32_t stable_pstate;
};
struct amdgpu_ctx_mgr {
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c
index 25e2e5bf90eb..5d04d24a0d5f 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c
@@ -37,6 +37,8 @@
#include "amdgpu_fw_attestation.h"
#include "amdgpu_umr.h"
+#include "amdgpu_reset.h"
+
#if defined(CONFIG_DEBUG_FS)
/**
@@ -728,7 +730,7 @@ static ssize_t amdgpu_debugfs_gca_config_read(struct file *f, char __user *buf,
return -ENOMEM;
/* version, increment each time something is added */
- config[no_regs++] = 3;
+ config[no_regs++] = 4;
config[no_regs++] = adev->gfx.config.max_shader_engines;
config[no_regs++] = adev->gfx.config.max_tile_pipes;
config[no_regs++] = adev->gfx.config.max_cu_per_sh;
@@ -768,6 +770,9 @@ static ssize_t amdgpu_debugfs_gca_config_read(struct file *f, char __user *buf,
config[no_regs++] = adev->pdev->subsystem_device;
config[no_regs++] = adev->pdev->subsystem_vendor;
+ /* rev==4 APU flag */
+ config[no_regs++] = adev->flags & AMD_IS_APU ? 1 : 0;
+
while (size && (*pos < no_regs * 4)) {
uint32_t value;
@@ -1120,8 +1125,10 @@ static ssize_t amdgpu_debugfs_gfxoff_read(struct file *f, char __user *buf,
return -EINVAL;
r = pm_runtime_get_sync(adev_to_drm(adev)->dev);
- if (r < 0)
+ if (r < 0) {
+ pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
return r;
+ }
while (size) {
uint32_t value;
@@ -1279,7 +1286,7 @@ static int amdgpu_debugfs_test_ib_show(struct seq_file *m, void *unused)
}
/* Avoid accidently unparking the sched thread during GPU reset */
- r = down_write_killable(&adev->reset_sem);
+ r = down_write_killable(&adev->reset_domain->sem);
if (r)
return r;
@@ -1308,7 +1315,7 @@ static int amdgpu_debugfs_test_ib_show(struct seq_file *m, void *unused)
kthread_unpark(ring->sched.thread);
}
- up_write(&adev->reset_sem);
+ up_write(&adev->reset_domain->sem);
pm_runtime_mark_last_busy(dev->dev);
pm_runtime_put_autosuspend(dev->dev);
@@ -1357,6 +1364,25 @@ static int amdgpu_debugfs_evict_gtt(void *data, u64 *val)
return 0;
}
+static int amdgpu_debugfs_benchmark(void *data, u64 val)
+{
+ struct amdgpu_device *adev = (struct amdgpu_device *)data;
+ struct drm_device *dev = adev_to_drm(adev);
+ int r;
+
+ r = pm_runtime_get_sync(dev->dev);
+ if (r < 0) {
+ pm_runtime_put_autosuspend(dev->dev);
+ return r;
+ }
+
+ r = amdgpu_benchmark(adev, val);
+
+ pm_runtime_mark_last_busy(dev->dev);
+ pm_runtime_put_autosuspend(dev->dev);
+
+ return r;
+}
static int amdgpu_debugfs_vm_info_show(struct seq_file *m, void *unused)
{
@@ -1393,6 +1419,8 @@ DEFINE_DEBUGFS_ATTRIBUTE(amdgpu_evict_vram_fops, amdgpu_debugfs_evict_vram,
NULL, "%lld\n");
DEFINE_DEBUGFS_ATTRIBUTE(amdgpu_evict_gtt_fops, amdgpu_debugfs_evict_gtt,
NULL, "%lld\n");
+DEFINE_DEBUGFS_ATTRIBUTE(amdgpu_benchmark_fops, NULL, amdgpu_debugfs_benchmark,
+ "%lld\n");
static void amdgpu_ib_preempt_fences_swap(struct amdgpu_ring *ring,
struct dma_fence **fences)
@@ -1517,7 +1545,7 @@ static int amdgpu_debugfs_ib_preempt(void *data, u64 val)
return -ENOMEM;
/* Avoid accidently unparking the sched thread during GPU reset */
- r = down_read_killable(&adev->reset_sem);
+ r = down_read_killable(&adev->reset_domain->sem);
if (r)
goto pro_end;
@@ -1560,7 +1588,7 @@ failure:
/* restart the scheduler */
kthread_unpark(ring->sched.thread);
- up_read(&adev->reset_sem);
+ up_read(&adev->reset_domain->sem);
ttm_bo_unlock_delayed_workqueue(&adev->mman.bdev, resched);
@@ -1585,22 +1613,25 @@ static int amdgpu_debugfs_sclk_set(void *data, u64 val)
return ret;
}
- if (is_support_sw_smu(adev)) {
- ret = smu_get_dpm_freq_range(&adev->smu, SMU_SCLK, &min_freq, &max_freq);
- if (ret || val > max_freq || val < min_freq)
- return -EINVAL;
- ret = smu_set_soft_freq_range(&adev->smu, SMU_SCLK, (uint32_t)val, (uint32_t)val);
- } else {
- return 0;
+ ret = amdgpu_dpm_get_dpm_freq_range(adev, PP_SCLK, &min_freq, &max_freq);
+ if (ret == -EOPNOTSUPP) {
+ ret = 0;
+ goto out;
+ }
+ if (ret || val > max_freq || val < min_freq) {
+ ret = -EINVAL;
+ goto out;
}
+ ret = amdgpu_dpm_set_soft_freq_range(adev, PP_SCLK, (uint32_t)val, (uint32_t)val);
+ if (ret)
+ ret = -EINVAL;
+
+out:
pm_runtime_mark_last_busy(adev_to_drm(adev)->dev);
pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
- if (ret)
- return -EINVAL;
-
- return 0;
+ return ret;
}
DEFINE_DEBUGFS_ATTRIBUTE(fops_ib_preempt, NULL,
@@ -1609,6 +1640,91 @@ DEFINE_DEBUGFS_ATTRIBUTE(fops_ib_preempt, NULL,
DEFINE_DEBUGFS_ATTRIBUTE(fops_sclk_set, NULL,
amdgpu_debugfs_sclk_set, "%llu\n");
+static ssize_t amdgpu_reset_dump_register_list_read(struct file *f,
+ char __user *buf, size_t size, loff_t *pos)
+{
+ struct amdgpu_device *adev = (struct amdgpu_device *)file_inode(f)->i_private;
+ char reg_offset[12];
+ int i, ret, len = 0;
+
+ if (*pos)
+ return 0;
+
+ memset(reg_offset, 0, 12);
+ ret = down_read_killable(&adev->reset_domain->sem);
+ if (ret)
+ return ret;
+
+ for (i = 0; i < adev->num_regs; i++) {
+ sprintf(reg_offset, "0x%x\n", adev->reset_dump_reg_list[i]);
+ up_read(&adev->reset_domain->sem);
+ if (copy_to_user(buf + len, reg_offset, strlen(reg_offset)))
+ return -EFAULT;
+
+ len += strlen(reg_offset);
+ ret = down_read_killable(&adev->reset_domain->sem);
+ if (ret)
+ return ret;
+ }
+
+ up_read(&adev->reset_domain->sem);
+ *pos += len;
+
+ return len;
+}
+
+static ssize_t amdgpu_reset_dump_register_list_write(struct file *f,
+ const char __user *buf, size_t size, loff_t *pos)
+{
+ struct amdgpu_device *adev = (struct amdgpu_device *)file_inode(f)->i_private;
+ char reg_offset[11];
+ uint32_t *new, *tmp = NULL;
+ int ret, i = 0, len = 0;
+
+ do {
+ memset(reg_offset, 0, 11);
+ if (copy_from_user(reg_offset, buf + len,
+ min(10, ((int)size-len)))) {
+ ret = -EFAULT;
+ goto error_free;
+ }
+
+ new = krealloc_array(tmp, i + 1, sizeof(uint32_t), GFP_KERNEL);
+ if (!new) {
+ ret = -ENOMEM;
+ goto error_free;
+ }
+ tmp = new;
+ if (sscanf(reg_offset, "%X %n", &tmp[i], &ret) != 1) {
+ ret = -EINVAL;
+ goto error_free;
+ }
+
+ len += ret;
+ i++;
+ } while (len < size);
+
+ ret = down_write_killable(&adev->reset_domain->sem);
+ if (ret)
+ goto error_free;
+
+ swap(adev->reset_dump_reg_list, tmp);
+ adev->num_regs = i;
+ up_write(&adev->reset_domain->sem);
+ ret = size;
+
+error_free:
+ kfree(tmp);
+ return ret;
+}
+
+static const struct file_operations amdgpu_reset_dump_register_list = {
+ .owner = THIS_MODULE,
+ .read = amdgpu_reset_dump_register_list_read,
+ .write = amdgpu_reset_dump_register_list_write,
+ .llseek = default_llseek
+};
+
int amdgpu_debugfs_init(struct amdgpu_device *adev)
{
struct dentry *root = adev_to_drm(adev)->primary->debugfs_root;
@@ -1662,6 +1778,16 @@ int amdgpu_debugfs_init(struct amdgpu_device *adev)
amdgpu_debugfs_ring_init(adev, ring);
}
+ for ( i = 0; i < adev->vcn.num_vcn_inst; i++) {
+ if (!amdgpu_vcnfw_log)
+ break;
+
+ if (adev->vcn.harvest_config & (1 << i))
+ continue;
+
+ amdgpu_debugfs_vcn_fwlog_init(adev, i, &adev->vcn.inst[i]);
+ }
+
amdgpu_ras_debugfs_create_all(adev);
amdgpu_rap_debugfs_init(adev);
amdgpu_securedisplay_debugfs_init(adev);
@@ -1675,6 +1801,10 @@ int amdgpu_debugfs_init(struct amdgpu_device *adev)
&amdgpu_debugfs_test_ib_fops);
debugfs_create_file("amdgpu_vm_info", 0444, root, adev,
&amdgpu_debugfs_vm_info_fops);
+ debugfs_create_file("amdgpu_benchmark", 0200, root, adev,
+ &amdgpu_benchmark_fops);
+ debugfs_create_file("amdgpu_reset_dump_register_list", 0644, root, adev,
+ &amdgpu_reset_dump_register_list);
adev->debugfs_vbios_blob.data = adev->bios;
adev->debugfs_vbios_blob.size = adev->bios_size;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
index ed077de426d9..3987ecb24ef4 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
@@ -31,6 +31,7 @@
#include <linux/console.h>
#include <linux/slab.h>
#include <linux/iommu.h>
+#include <linux/pci.h>
#include <drm/drm_atomic_helper.h>
#include <drm/drm_probe_helper.h>
@@ -55,7 +56,6 @@
#include "soc15.h"
#include "nv.h"
#include "bif/bif_4_1_d.h"
-#include <linux/pci.h>
#include <linux/firmware.h>
#include "amdgpu_vf_error.h"
@@ -80,14 +80,11 @@ MODULE_FIRMWARE("amdgpu/raven_gpu_info.bin");
MODULE_FIRMWARE("amdgpu/picasso_gpu_info.bin");
MODULE_FIRMWARE("amdgpu/raven2_gpu_info.bin");
MODULE_FIRMWARE("amdgpu/arcturus_gpu_info.bin");
-MODULE_FIRMWARE("amdgpu/renoir_gpu_info.bin");
-MODULE_FIRMWARE("amdgpu/navi10_gpu_info.bin");
-MODULE_FIRMWARE("amdgpu/navi14_gpu_info.bin");
MODULE_FIRMWARE("amdgpu/navi12_gpu_info.bin");
-MODULE_FIRMWARE("amdgpu/vangogh_gpu_info.bin");
-MODULE_FIRMWARE("amdgpu/yellow_carp_gpu_info.bin");
#define AMDGPU_RESUME_MS 2000
+#define AMDGPU_MAX_RETRY_LIMIT 2
+#define AMDGPU_RETRY_SRIOV_RESET(r) ((r) == -EBUSY || (r) == -ETIMEDOUT || (r) == -EINVAL)
const char *amdgpu_asic_name[] = {
"TAHITI",
@@ -424,10 +421,10 @@ bool amdgpu_device_skip_hw_access(struct amdgpu_device *adev)
* the lock.
*/
if (in_task()) {
- if (down_read_trylock(&adev->reset_sem))
- up_read(&adev->reset_sem);
+ if (down_read_trylock(&adev->reset_domain->sem))
+ up_read(&adev->reset_domain->sem);
else
- lockdep_assert_held(&adev->reset_sem);
+ lockdep_assert_held(&adev->reset_domain->sem);
}
#endif
return false;
@@ -453,9 +450,9 @@ uint32_t amdgpu_device_rreg(struct amdgpu_device *adev,
if ((reg * 4) < adev->rmmio_size) {
if (!(acc_flags & AMDGPU_REGS_NO_KIQ) &&
amdgpu_sriov_runtime(adev) &&
- down_read_trylock(&adev->reset_sem)) {
+ down_read_trylock(&adev->reset_domain->sem)) {
ret = amdgpu_kiq_rreg(adev, reg);
- up_read(&adev->reset_sem);
+ up_read(&adev->reset_domain->sem);
} else {
ret = readl(((void __iomem *)adev->rmmio) + (reg * 4));
}
@@ -538,9 +535,9 @@ void amdgpu_device_wreg(struct amdgpu_device *adev,
if ((reg * 4) < adev->rmmio_size) {
if (!(acc_flags & AMDGPU_REGS_NO_KIQ) &&
amdgpu_sriov_runtime(adev) &&
- down_read_trylock(&adev->reset_sem)) {
+ down_read_trylock(&adev->reset_domain->sem)) {
amdgpu_kiq_wreg(adev, reg, v);
- up_read(&adev->reset_sem);
+ up_read(&adev->reset_domain->sem);
} else {
writel(v, ((void __iomem *)adev->rmmio) + (reg * 4));
}
@@ -554,7 +551,11 @@ void amdgpu_device_wreg(struct amdgpu_device *adev,
/**
* amdgpu_mm_wreg_mmio_rlc - write register either with direct/indirect mmio or with RLC path if in range
*
- * this function is invoked only the debugfs register access
+ * @adev: amdgpu_device pointer
+ * @reg: mmio/rlc register
+ * @v: value to write
+ *
+ * this function is invoked only for the debugfs register access
*/
void amdgpu_mm_wreg_mmio_rlc(struct amdgpu_device *adev,
uint32_t reg, uint32_t v)
@@ -566,7 +567,7 @@ void amdgpu_mm_wreg_mmio_rlc(struct amdgpu_device *adev,
adev->gfx.rlc.funcs &&
adev->gfx.rlc.funcs->is_rlcg_access_range) {
if (adev->gfx.rlc.funcs->is_rlcg_access_range(adev, reg))
- return adev->gfx.rlc.funcs->sriov_wreg(adev, reg, v, 0, 0);
+ return amdgpu_sriov_wreg(adev, reg, v, 0, 0);
} else if ((reg * 4) >= adev->rmmio_size) {
adev->pcie_wreg(adev, reg * 4, v);
} else {
@@ -1312,6 +1313,31 @@ bool amdgpu_device_need_post(struct amdgpu_device *adev)
return true;
}
+/**
+ * amdgpu_device_should_use_aspm - check if the device should program ASPM
+ *
+ * @adev: amdgpu_device pointer
+ *
+ * Confirm whether the module parameter and pcie bridge agree that ASPM should
+ * be set for this device.
+ *
+ * Returns true if it should be used or false if not.
+ */
+bool amdgpu_device_should_use_aspm(struct amdgpu_device *adev)
+{
+ switch (amdgpu_aspm) {
+ case -1:
+ break;
+ case 0:
+ return false;
+ case 1:
+ return true;
+ default:
+ return false;
+ }
+ return pcie_aspm_enabled(adev->pdev);
+}
+
/* if we get transitioned to only one device, take VGA back */
/**
* amdgpu_device_vga_set_decode - enable/disable vga decode
@@ -1446,7 +1472,8 @@ static int amdgpu_device_init_apu_flags(struct amdgpu_device *adev)
case CHIP_YELLOW_CARP:
break;
case CHIP_CYAN_SKILLFISH:
- if (adev->pdev->device == 0x13FE)
+ if ((adev->pdev->device == 0x13FE) ||
+ (adev->pdev->device == 0x143F))
adev->apu_flags |= AMD_APU_IS_CYAN_SKILLFISH2;
break;
default:
@@ -1507,6 +1534,11 @@ static int amdgpu_device_check_arguments(struct amdgpu_device *adev)
amdgpu_sched_hw_submission = roundup_pow_of_two(amdgpu_sched_hw_submission);
}
+ if (amdgpu_reset_method < -1 || amdgpu_reset_method > 4) {
+ dev_warn(adev->dev, "invalid option for reset method, reverting to default\n");
+ amdgpu_reset_method = -1;
+ }
+
amdgpu_device_check_smu_prv_buffer_size(adev);
amdgpu_device_check_vm_size(adev);
@@ -1517,7 +1549,6 @@ static int amdgpu_device_check_arguments(struct amdgpu_device *adev)
amdgpu_gmc_tmz_set(adev);
- amdgpu_gmc_noretry_set(adev);
return 0;
}
@@ -1955,27 +1986,9 @@ static int amdgpu_device_parse_gpu_info_fw(struct amdgpu_device *adev)
case CHIP_ARCTURUS:
chip_name = "arcturus";
break;
- case CHIP_RENOIR:
- if (adev->apu_flags & AMD_APU_IS_RENOIR)
- chip_name = "renoir";
- else
- chip_name = "green_sardine";
- break;
- case CHIP_NAVI10:
- chip_name = "navi10";
- break;
- case CHIP_NAVI14:
- chip_name = "navi14";
- break;
case CHIP_NAVI12:
chip_name = "navi12";
break;
- case CHIP_VANGOGH:
- chip_name = "vangogh";
- break;
- case CHIP_YELLOW_CARP:
- chip_name = "yellow_carp";
- break;
}
snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_gpu_info.bin", chip_name);
@@ -2073,6 +2086,8 @@ out:
*/
static int amdgpu_device_ip_early_init(struct amdgpu_device *adev)
{
+ struct drm_device *dev = adev_to_drm(adev);
+ struct pci_dev *parent;
int i, r;
amdgpu_device_enable_virtual_display(adev);
@@ -2137,6 +2152,18 @@ static int amdgpu_device_ip_early_init(struct amdgpu_device *adev)
break;
}
+ if (amdgpu_has_atpx() &&
+ (amdgpu_is_atpx_hybrid() ||
+ amdgpu_has_atpx_dgpu_power_cntl()) &&
+ ((adev->flags & AMD_IS_APU) == 0) &&
+ !pci_is_thunderbolt_attached(to_pci_dev(dev->dev)))
+ adev->flags |= AMD_IS_PX;
+
+ if (!(adev->flags & AMD_IS_APU)) {
+ parent = pci_upstream_bridge(adev->pdev);
+ adev->has_pr3 = parent ? pci_pr3_present(parent) : false;
+ }
+
amdgpu_amdkfd_device_probe(adev);
adev->pm.pp_feature = amdgpu_pp_feature_mask;
@@ -2287,6 +2314,49 @@ static int amdgpu_device_fw_loading(struct amdgpu_device *adev)
return r;
}
+static int amdgpu_device_init_schedulers(struct amdgpu_device *adev)
+{
+ long timeout;
+ int r, i;
+
+ for (i = 0; i < AMDGPU_MAX_RINGS; ++i) {
+ struct amdgpu_ring *ring = adev->rings[i];
+
+ /* No need to setup the GPU scheduler for rings that don't need it */
+ if (!ring || ring->no_scheduler)
+ continue;
+
+ switch (ring->funcs->type) {
+ case AMDGPU_RING_TYPE_GFX:
+ timeout = adev->gfx_timeout;
+ break;
+ case AMDGPU_RING_TYPE_COMPUTE:
+ timeout = adev->compute_timeout;
+ break;
+ case AMDGPU_RING_TYPE_SDMA:
+ timeout = adev->sdma_timeout;
+ break;
+ default:
+ timeout = adev->video_timeout;
+ break;
+ }
+
+ r = drm_sched_init(&ring->sched, &amdgpu_sched_ops,
+ ring->num_hw_submission, amdgpu_job_hang_limit,
+ timeout, adev->reset_domain->wq,
+ ring->sched_score, ring->name,
+ adev->dev);
+ if (r) {
+ DRM_ERROR("Failed to create scheduler on ring %s.\n",
+ ring->name);
+ return r;
+ }
+ }
+
+ return 0;
+}
+
+
/**
* amdgpu_device_ip_init - run init for hardware IPs
*
@@ -2398,8 +2468,28 @@ static int amdgpu_device_ip_init(struct amdgpu_device *adev)
if (r)
goto init_failed;
- if (adev->gmc.xgmi.num_physical_nodes > 1)
- amdgpu_xgmi_add_device(adev);
+ /**
+ * In case of XGMI grab extra reference for reset domain for this device
+ */
+ if (adev->gmc.xgmi.num_physical_nodes > 1) {
+ if (amdgpu_xgmi_add_device(adev) == 0) {
+ struct amdgpu_hive_info *hive = amdgpu_get_xgmi_hive(adev);
+
+ if (!hive->reset_domain ||
+ !amdgpu_reset_get_reset_domain(hive->reset_domain)) {
+ r = -ENOENT;
+ goto init_failed;
+ }
+
+ /* Drop the early temporary reset domain we created for device */
+ amdgpu_reset_put_reset_domain(adev->reset_domain);
+ adev->reset_domain = hive->reset_domain;
+ }
+ }
+
+ r = amdgpu_device_init_schedulers(adev);
+ if (r)
+ goto init_failed;
/* Don't init kfd if whole hive need to be reset during init */
if (!adev->gmc.xgmi.pending_reset)
@@ -2610,6 +2700,12 @@ static int amdgpu_device_ip_late_init(struct amdgpu_device *adev)
adev->ip_blocks[i].status.late_initialized = true;
}
+ r = amdgpu_ras_late_init(adev);
+ if (r) {
+ DRM_ERROR("amdgpu_ras_late_init failed %d", r);
+ return r;
+ }
+
amdgpu_ras_set_error_query_ready(adev, true);
amdgpu_device_set_cg_state(adev, AMD_CG_STATE_GATE);
@@ -2624,7 +2720,7 @@ static int amdgpu_device_ip_late_init(struct amdgpu_device *adev)
/* For passthrough configuration on arcturus and aldebaran, enable special handling SBR */
if (amdgpu_passthrough(adev) && ((adev->asic_type == CHIP_ARCTURUS && adev->gmc.xgmi.num_physical_nodes > 1)||
adev->asic_type == CHIP_ALDEBARAN ))
- smu_handle_passthrough_sbr(&adev->smu, true);
+ amdgpu_dpm_handle_passthrough_sbr(adev, true);
if (adev->gmc.xgmi.num_physical_nodes > 1) {
mutex_lock(&mgpu_info.mutex);
@@ -2708,11 +2804,11 @@ static int amdgpu_device_ip_fini_early(struct amdgpu_device *adev)
}
}
- amdgpu_amdkfd_suspend(adev, false);
-
amdgpu_device_set_pg_state(adev, AMD_PG_STATE_UNGATE);
amdgpu_device_set_cg_state(adev, AMD_CG_STATE_UNGATE);
+ amdgpu_amdkfd_suspend(adev, false);
+
/* Workaroud for ASICs need to disable SMC first */
amdgpu_device_smu_fini_early(adev);
@@ -2881,7 +2977,7 @@ static int amdgpu_device_ip_suspend_phase2(struct amdgpu_device *adev)
int i, r;
if (adev->in_s0ix)
- amdgpu_gfx_state_change_set(adev, sGpuChangeState_D3Entry);
+ amdgpu_dpm_gfx_state_change(adev, sGpuChangeState_D3Entry);
for (i = adev->num_ip_blocks - 1; i >= 0; i--) {
if (!adev->ip_blocks[i].status.valid)
@@ -3307,9 +3403,9 @@ static void amdgpu_device_xgmi_reset_func(struct work_struct *__work)
if (adev->asic_reset_res)
goto fail;
- if (adev->mmhub.ras_funcs &&
- adev->mmhub.ras_funcs->reset_ras_error_count)
- adev->mmhub.ras_funcs->reset_ras_error_count(adev);
+ if (adev->mmhub.ras && adev->mmhub.ras->ras_block.hw_ops &&
+ adev->mmhub.ras->ras_block.hw_ops->reset_ras_error_count)
+ adev->mmhub.ras->ras_block.hw_ops->reset_ras_error_count(adev);
} else {
task_barrier_full(&hive->tb);
@@ -3493,12 +3589,12 @@ int amdgpu_device_init(struct amdgpu_device *adev,
mutex_init(&adev->mn_lock);
mutex_init(&adev->virt.vf_errors.lock);
hash_init(adev->mn_hash);
- atomic_set(&adev->in_gpu_reset, 0);
- init_rwsem(&adev->reset_sem);
mutex_init(&adev->psp.mutex);
mutex_init(&adev->notifier_lock);
+ mutex_init(&adev->pm.stable_pstate_ctx_lock);
+ mutex_init(&adev->benchmark_mutex);
- amdgpu_device_init_apu_flags(adev);
+ amdgpu_device_init_apu_flags(adev);
r = amdgpu_device_check_arguments(adev);
if (r)
@@ -3519,6 +3615,8 @@ int amdgpu_device_init(struct amdgpu_device *adev,
INIT_LIST_HEAD(&adev->reset_list);
+ INIT_LIST_HEAD(&adev->ras_list);
+
INIT_DELAYED_WORK(&adev->delayed_init_work,
amdgpu_device_delayed_init_work_handler);
INIT_DELAYED_WORK(&adev->gfx.gfx_off_delay_work,
@@ -3568,6 +3666,15 @@ int amdgpu_device_init(struct amdgpu_device *adev,
if (amdgpu_mes && adev->asic_type >= CHIP_NAVI10)
adev->enable_mes = true;
+ /*
+ * Reset domain needs to be present early, before XGMI hive discovered
+ * (if any) and intitialized to use reset sem and in_gpu reset flag
+ * early on during init and before calling to RREG32.
+ */
+ adev->reset_domain = amdgpu_reset_create_reset_domain(SINGLE_DEVICE, "amdgpu-reset-dev");
+ if (!adev->reset_domain)
+ return -ENOMEM;
+
/* detect hw virtualization here */
amdgpu_detect_virtualization(adev);
@@ -3582,6 +3689,7 @@ int amdgpu_device_init(struct amdgpu_device *adev,
if (r)
return r;
+ amdgpu_gmc_noretry_set(adev);
/* Need to get xgmi info early to decide the reset behavior*/
if (adev->gmc.xgmi.supported) {
r = adev->gfxhub.funcs->get_xgmi_info(adev);
@@ -3749,19 +3857,6 @@ fence_driver_init:
} else
adev->ucode_sysfs_en = true;
- if ((amdgpu_testing & 1)) {
- if (adev->accel_working)
- amdgpu_test_moves(adev);
- else
- DRM_INFO("amdgpu: acceleration disabled, skipping move tests\n");
- }
- if (amdgpu_benchmarking) {
- if (adev->accel_working)
- amdgpu_benchmark(adev, amdgpu_benchmarking);
- else
- DRM_INFO("amdgpu: acceleration disabled, skipping benchmarks\n");
- }
-
/*
* Register gpu instance before amdgpu_device_enable_mgpu_fan_boost.
* Otherwise the mgpu fan boost feature will be skipped due to the
@@ -3953,6 +4048,9 @@ void amdgpu_device_fini_sw(struct amdgpu_device *adev)
if (adev->mman.discovery_bin)
amdgpu_discovery_fini(adev);
+ amdgpu_reset_put_reset_domain(adev->reset_domain);
+ adev->reset_domain = NULL;
+
kfree(adev->pci_state);
}
@@ -4044,7 +4142,7 @@ int amdgpu_device_resume(struct drm_device *dev, bool fbcon)
return 0;
if (adev->in_s0ix)
- amdgpu_gfx_state_change_set(adev, sGpuChangeState_D0Entry);
+ amdgpu_dpm_gfx_state_change(adev, sGpuChangeState_D0Entry);
/* post card */
if (amdgpu_device_need_post(adev)) {
@@ -4347,7 +4445,9 @@ static int amdgpu_device_reset_sriov(struct amdgpu_device *adev,
{
int r;
struct amdgpu_hive_info *hive = NULL;
+ int retry_limit = 0;
+retry:
amdgpu_amdkfd_pre_reset(adev);
amdgpu_amdkfd_pre_reset(adev);
@@ -4396,6 +4496,14 @@ error:
}
amdgpu_virt_release_full_gpu(adev, true);
+ if (AMDGPU_RETRY_SRIOV_RESET(r)) {
+ if (retry_limit < AMDGPU_MAX_RETRY_LIMIT) {
+ retry_limit++;
+ goto retry;
+ } else
+ DRM_ERROR("GPU reset retry is beyond the retry limit\n");
+ }
+
return r;
}
@@ -4587,6 +4695,22 @@ int amdgpu_device_pre_asic_reset(struct amdgpu_device *adev,
return r;
}
+static int amdgpu_reset_reg_dumps(struct amdgpu_device *adev)
+{
+ uint32_t reg_value;
+ int i;
+
+ lockdep_assert_held(&adev->reset_domain->sem);
+ dump_stack();
+
+ for (i = 0; i < adev->num_regs; i++) {
+ reg_value = RREG32(adev->reset_dump_reg_list[i]);
+ trace_amdgpu_reset_reg_dumps(adev->reset_dump_reg_list[i], reg_value);
+ }
+
+ return 0;
+}
+
int amdgpu_do_asic_reset(struct list_head *device_list_handle,
struct amdgpu_reset_context *reset_context)
{
@@ -4597,6 +4721,7 @@ int amdgpu_do_asic_reset(struct list_head *device_list_handle,
/* Try reset handler method first */
tmp_adev = list_first_entry(device_list_handle, struct amdgpu_device,
reset_list);
+ amdgpu_reset_reg_dumps(tmp_adev);
r = amdgpu_reset_perform_reset(tmp_adev, reset_context);
/* If reset handler not implemented, continue; otherwise return */
if (r == -ENOSYS)
@@ -4645,9 +4770,9 @@ int amdgpu_do_asic_reset(struct list_head *device_list_handle,
if (!r && amdgpu_ras_intr_triggered()) {
list_for_each_entry(tmp_adev, device_list_handle, reset_list) {
- if (tmp_adev->mmhub.ras_funcs &&
- tmp_adev->mmhub.ras_funcs->reset_ras_error_count)
- tmp_adev->mmhub.ras_funcs->reset_ras_error_count(tmp_adev);
+ if (tmp_adev->mmhub.ras && tmp_adev->mmhub.ras->ras_block.hw_ops &&
+ tmp_adev->mmhub.ras->ras_block.hw_ops->reset_ras_error_count)
+ tmp_adev->mmhub.ras->ras_block.hw_ops->reset_ras_error_count(tmp_adev);
}
amdgpu_ras_intr_cleared();
@@ -4754,17 +4879,8 @@ end:
return r;
}
-static bool amdgpu_device_lock_adev(struct amdgpu_device *adev,
- struct amdgpu_hive_info *hive)
+static void amdgpu_device_set_mp1_state(struct amdgpu_device *adev)
{
- if (atomic_cmpxchg(&adev->in_gpu_reset, 0, 1) != 0)
- return false;
-
- if (hive) {
- down_write_nest_lock(&adev->reset_sem, &hive->hive_lock);
- } else {
- down_write(&adev->reset_sem);
- }
switch (amdgpu_asic_reset_method(adev)) {
case AMD_RESET_METHOD_MODE1:
@@ -4777,56 +4893,12 @@ static bool amdgpu_device_lock_adev(struct amdgpu_device *adev,
adev->mp1_state = PP_MP1_STATE_NONE;
break;
}
-
- return true;
}
-static void amdgpu_device_unlock_adev(struct amdgpu_device *adev)
+static void amdgpu_device_unset_mp1_state(struct amdgpu_device *adev)
{
amdgpu_vf_error_trans_all(adev);
adev->mp1_state = PP_MP1_STATE_NONE;
- atomic_set(&adev->in_gpu_reset, 0);
- up_write(&adev->reset_sem);
-}
-
-/*
- * to lockup a list of amdgpu devices in a hive safely, if not a hive
- * with multiple nodes, it will be similar as amdgpu_device_lock_adev.
- *
- * unlock won't require roll back.
- */
-static int amdgpu_device_lock_hive_adev(struct amdgpu_device *adev, struct amdgpu_hive_info *hive)
-{
- struct amdgpu_device *tmp_adev = NULL;
-
- if (!amdgpu_sriov_vf(adev) && (adev->gmc.xgmi.num_physical_nodes > 1)) {
- if (!hive) {
- dev_err(adev->dev, "Hive is NULL while device has multiple xgmi nodes");
- return -ENODEV;
- }
- list_for_each_entry(tmp_adev, &hive->device_list, gmc.xgmi.head) {
- if (!amdgpu_device_lock_adev(tmp_adev, hive))
- goto roll_back;
- }
- } else if (!amdgpu_device_lock_adev(adev, hive))
- return -EAGAIN;
-
- return 0;
-roll_back:
- if (!list_is_first(&tmp_adev->gmc.xgmi.head, &hive->device_list)) {
- /*
- * if the lockup iteration break in the middle of a hive,
- * it may means there may has a race issue,
- * or a hive device locked up independently.
- * we may be in trouble and may not, so will try to roll back
- * the lock and give out a warnning.
- */
- dev_warn(tmp_adev->dev, "Hive lock iteration broke in the middle. Rolling back to unlock");
- list_for_each_entry_continue_reverse(tmp_adev, &hive->device_list, gmc.xgmi.head) {
- amdgpu_device_unlock_adev(tmp_adev);
- }
- }
- return -EAGAIN;
}
static void amdgpu_device_resume_display_audio(struct amdgpu_device *adev)
@@ -4960,7 +5032,7 @@ retry:
}
/**
- * amdgpu_device_gpu_recover - reset the asic and recover scheduler
+ * amdgpu_device_gpu_recover_imp - reset the asic and recover scheduler
*
* @adev: amdgpu_device pointer
* @job: which job trigger hang
@@ -4970,7 +5042,7 @@ retry:
* Returns 0 for success or an error on failure.
*/
-int amdgpu_device_gpu_recover(struct amdgpu_device *adev,
+int amdgpu_device_gpu_recover_imp(struct amdgpu_device *adev,
struct amdgpu_job *job)
{
struct list_head device_list, *device_list_handle = NULL;
@@ -5004,26 +5076,10 @@ int amdgpu_device_gpu_recover(struct amdgpu_device *adev,
dev_info(adev->dev, "GPU %s begin!\n",
need_emergency_restart ? "jobs stop":"reset");
- /*
- * Here we trylock to avoid chain of resets executing from
- * either trigger by jobs on different adevs in XGMI hive or jobs on
- * different schedulers for same device while this TO handler is running.
- * We always reset all schedulers for device and all devices for XGMI
- * hive so that should take care of them too.
- */
if (!amdgpu_sriov_vf(adev))
hive = amdgpu_get_xgmi_hive(adev);
- if (hive) {
- if (atomic_cmpxchg(&hive->in_reset, 0, 1) != 0) {
- DRM_INFO("Bailing on TDR for s_job:%llx, hive: %llx as another already in progress",
- job ? job->base.id : -1, hive->hive_id);
- amdgpu_put_xgmi_hive(hive);
- if (job && job->vm)
- drm_sched_increase_karma(&job->base);
- return 0;
- }
+ if (hive)
mutex_lock(&hive->hive_lock);
- }
reset_context.method = AMD_RESET_METHOD_NONE;
reset_context.reset_req_dev = adev;
@@ -5032,22 +5088,6 @@ int amdgpu_device_gpu_recover(struct amdgpu_device *adev,
clear_bit(AMDGPU_NEED_FULL_RESET, &reset_context.flags);
/*
- * lock the device before we try to operate the linked list
- * if didn't get the device lock, don't touch the linked list since
- * others may iterating it.
- */
- r = amdgpu_device_lock_hive_adev(adev, hive);
- if (r) {
- dev_info(adev->dev, "Bailing on TDR for s_job:%llx, as another already in progress",
- job ? job->base.id : -1);
-
- /* even we skipped this reset, still need to set the job to guilty */
- if (job && job->vm)
- drm_sched_increase_karma(&job->base);
- goto skip_recovery;
- }
-
- /*
* Build list of devices to reset.
* In case we are in XGMI hive mode, resort the device list
* to put adev in the 1st position.
@@ -5064,8 +5104,16 @@ int amdgpu_device_gpu_recover(struct amdgpu_device *adev,
device_list_handle = &device_list;
}
+ /* We need to lock reset domain only once both for XGMI and single device */
+ tmp_adev = list_first_entry(device_list_handle, struct amdgpu_device,
+ reset_list);
+ amdgpu_device_lock_reset_domain(tmp_adev->reset_domain);
+
/* block all schedulers and reset given job's ring */
list_for_each_entry(tmp_adev, device_list_handle, reset_list) {
+
+ amdgpu_device_set_mp1_state(tmp_adev);
+
/*
* Try to put the audio codec into suspend state
* before gpu reset started.
@@ -5187,6 +5235,9 @@ skip_hw_reset:
drm_helper_resume_force_mode(adev_to_drm(tmp_adev));
}
+ if (tmp_adev->asic_reset_res)
+ r = tmp_adev->asic_reset_res;
+
tmp_adev->asic_reset_res = 0;
if (r) {
@@ -5214,21 +5265,55 @@ skip_sched_resume:
if (audio_suspended)
amdgpu_device_resume_display_audio(tmp_adev);
- amdgpu_device_unlock_adev(tmp_adev);
+
+ amdgpu_device_unset_mp1_state(tmp_adev);
}
-skip_recovery:
+ tmp_adev = list_first_entry(device_list_handle, struct amdgpu_device,
+ reset_list);
+ amdgpu_device_unlock_reset_domain(tmp_adev->reset_domain);
+
if (hive) {
- atomic_set(&hive->in_reset, 0);
mutex_unlock(&hive->hive_lock);
amdgpu_put_xgmi_hive(hive);
}
- if (r && r != -EAGAIN)
+ if (r)
dev_info(adev->dev, "GPU reset end with ret = %d\n", r);
return r;
}
+struct amdgpu_recover_work_struct {
+ struct work_struct base;
+ struct amdgpu_device *adev;
+ struct amdgpu_job *job;
+ int ret;
+};
+
+static void amdgpu_device_queue_gpu_recover_work(struct work_struct *work)
+{
+ struct amdgpu_recover_work_struct *recover_work = container_of(work, struct amdgpu_recover_work_struct, base);
+
+ recover_work->ret = amdgpu_device_gpu_recover_imp(recover_work->adev, recover_work->job);
+}
+/*
+ * Serialize gpu recover into reset domain single threaded wq
+ */
+int amdgpu_device_gpu_recover(struct amdgpu_device *adev,
+ struct amdgpu_job *job)
+{
+ struct amdgpu_recover_work_struct work = {.adev = adev, .job = job};
+
+ INIT_WORK(&work.base, amdgpu_device_queue_gpu_recover_work);
+
+ if (!amdgpu_reset_domain_schedule(adev->reset_domain, &work.base))
+ return -EAGAIN;
+
+ flush_work(&work.base);
+
+ return work.ret;
+}
+
/**
* amdgpu_device_get_pcie_info - fence pcie info about the PCIE slot
*
@@ -5416,20 +5501,6 @@ int amdgpu_device_baco_exit(struct drm_device *dev)
return 0;
}
-static void amdgpu_cancel_all_tdr(struct amdgpu_device *adev)
-{
- int i;
-
- for (i = 0; i < AMDGPU_MAX_RINGS; ++i) {
- struct amdgpu_ring *ring = adev->rings[i];
-
- if (!ring || !ring->sched.thread)
- continue;
-
- cancel_delayed_work_sync(&ring->sched.work_tdr);
- }
-}
-
/**
* amdgpu_pci_error_detected - Called when a PCI error is detected.
* @pdev: PCI device struct
@@ -5460,14 +5531,11 @@ pci_ers_result_t amdgpu_pci_error_detected(struct pci_dev *pdev, pci_channel_sta
/* Fatal error, prepare for slot reset */
case pci_channel_io_frozen:
/*
- * Cancel and wait for all TDRs in progress if failing to
- * set adev->in_gpu_reset in amdgpu_device_lock_adev
- *
- * Locking adev->reset_sem will prevent any external access
+ * Locking adev->reset_domain->sem will prevent any external access
* to GPU during PCI error recovery
*/
- while (!amdgpu_device_lock_adev(adev, NULL))
- amdgpu_cancel_all_tdr(adev);
+ amdgpu_device_lock_reset_domain(adev->reset_domain);
+ amdgpu_device_set_mp1_state(adev);
/*
* Block any work scheduling as we do for regular GPU reset
@@ -5574,7 +5642,8 @@ out:
DRM_INFO("PCIe error recovery succeeded\n");
} else {
DRM_ERROR("PCIe error recovery failed, err:%d", r);
- amdgpu_device_unlock_adev(adev);
+ amdgpu_device_unset_mp1_state(adev);
+ amdgpu_device_unlock_reset_domain(adev->reset_domain);
}
return r ? PCI_ERS_RESULT_DISCONNECT : PCI_ERS_RESULT_RECOVERED;
@@ -5611,7 +5680,8 @@ void amdgpu_pci_resume(struct pci_dev *pdev)
drm_sched_start(&ring->sched, true);
}
- amdgpu_device_unlock_adev(adev);
+ amdgpu_device_unset_mp1_state(adev);
+ amdgpu_device_unlock_reset_domain(adev->reset_domain);
}
bool amdgpu_device_cache_pci_state(struct pci_dev *pdev)
@@ -5688,6 +5758,11 @@ void amdgpu_device_invalidate_hdp(struct amdgpu_device *adev,
amdgpu_asic_invalidate_hdp(adev, ring);
}
+int amdgpu_in_reset(struct amdgpu_device *adev)
+{
+ return atomic_read(&adev->reset_domain->in_gpu_reset);
+ }
+
/**
* amdgpu_device_halt() - bring hardware to some kind of halt state
*
@@ -5726,3 +5801,36 @@ void amdgpu_device_halt(struct amdgpu_device *adev)
pci_disable_device(pdev);
pci_wait_for_pending_transaction(pdev);
}
+
+u32 amdgpu_device_pcie_port_rreg(struct amdgpu_device *adev,
+ u32 reg)
+{
+ unsigned long flags, address, data;
+ u32 r;
+
+ address = adev->nbio.funcs->get_pcie_port_index_offset(adev);
+ data = adev->nbio.funcs->get_pcie_port_data_offset(adev);
+
+ spin_lock_irqsave(&adev->pcie_idx_lock, flags);
+ WREG32(address, reg * 4);
+ (void)RREG32(address);
+ r = RREG32(data);
+ spin_unlock_irqrestore(&adev->pcie_idx_lock, flags);
+ return r;
+}
+
+void amdgpu_device_pcie_port_wreg(struct amdgpu_device *adev,
+ u32 reg, u32 v)
+{
+ unsigned long flags, address, data;
+
+ address = adev->nbio.funcs->get_pcie_port_index_offset(adev);
+ data = adev->nbio.funcs->get_pcie_port_data_offset(adev);
+
+ spin_lock_irqsave(&adev->pcie_idx_lock, flags);
+ WREG32(address, reg * 4);
+ (void)RREG32(address);
+ WREG32(data, v);
+ (void)RREG32(data);
+ spin_unlock_irqrestore(&adev->pcie_idx_lock, flags);
+}
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c
index 81bfee978b74..e4fcbb385a62 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c
@@ -360,8 +360,11 @@ out:
return r;
}
+static void amdgpu_discovery_sysfs_fini(struct amdgpu_device *adev);
+
void amdgpu_discovery_fini(struct amdgpu_device *adev)
{
+ amdgpu_discovery_sysfs_fini(adev);
kfree(adev->mman.discovery_bin);
adev->mman.discovery_bin = NULL;
}
@@ -382,6 +385,578 @@ static int amdgpu_discovery_validate_ip(const struct ip *ip)
return 0;
}
+static void amdgpu_discovery_read_harvest_bit_per_ip(struct amdgpu_device *adev,
+ uint32_t *vcn_harvest_count)
+{
+ struct binary_header *bhdr;
+ struct ip_discovery_header *ihdr;
+ struct die_header *dhdr;
+ struct ip *ip;
+ uint16_t die_offset, ip_offset, num_dies, num_ips;
+ int i, j;
+
+ bhdr = (struct binary_header *)adev->mman.discovery_bin;
+ ihdr = (struct ip_discovery_header *)(adev->mman.discovery_bin +
+ le16_to_cpu(bhdr->table_list[IP_DISCOVERY].offset));
+ num_dies = le16_to_cpu(ihdr->num_dies);
+
+ /* scan harvest bit of all IP data structures */
+ for (i = 0; i < num_dies; i++) {
+ die_offset = le16_to_cpu(ihdr->die_info[i].die_offset);
+ dhdr = (struct die_header *)(adev->mman.discovery_bin + die_offset);
+ num_ips = le16_to_cpu(dhdr->num_ips);
+ ip_offset = die_offset + sizeof(*dhdr);
+
+ for (j = 0; j < num_ips; j++) {
+ ip = (struct ip *)(adev->mman.discovery_bin + ip_offset);
+
+ if (amdgpu_discovery_validate_ip(ip))
+ goto next_ip;
+
+ if (le16_to_cpu(ip->harvest) == 1) {
+ switch (le16_to_cpu(ip->hw_id)) {
+ case VCN_HWID:
+ (*vcn_harvest_count)++;
+ if (ip->number_instance == 0)
+ adev->vcn.harvest_config |= AMDGPU_VCN_HARVEST_VCN0;
+ else
+ adev->vcn.harvest_config |= AMDGPU_VCN_HARVEST_VCN1;
+ break;
+ case DMU_HWID:
+ adev->harvest_ip_mask |= AMD_HARVEST_IP_DMU_MASK;
+ break;
+ default:
+ break;
+ }
+ }
+next_ip:
+ ip_offset += sizeof(*ip) + 4 * (ip->num_base_address - 1);
+ }
+ }
+}
+
+static void amdgpu_discovery_read_from_harvest_table(struct amdgpu_device *adev,
+ uint32_t *vcn_harvest_count)
+{
+ struct binary_header *bhdr;
+ struct harvest_table *harvest_info;
+ int i;
+
+ bhdr = (struct binary_header *)adev->mman.discovery_bin;
+ harvest_info = (struct harvest_table *)(adev->mman.discovery_bin +
+ le16_to_cpu(bhdr->table_list[HARVEST_INFO].offset));
+ for (i = 0; i < 32; i++) {
+ if (le16_to_cpu(harvest_info->list[i].hw_id) == 0)
+ break;
+
+ switch (le16_to_cpu(harvest_info->list[i].hw_id)) {
+ case VCN_HWID:
+ (*vcn_harvest_count)++;
+ if (harvest_info->list[i].number_instance == 0)
+ adev->vcn.harvest_config |= AMDGPU_VCN_HARVEST_VCN0;
+ else
+ adev->vcn.harvest_config |= AMDGPU_VCN_HARVEST_VCN1;
+ break;
+ case DMU_HWID:
+ adev->harvest_ip_mask |= AMD_HARVEST_IP_DMU_MASK;
+ break;
+ default:
+ break;
+ }
+ }
+}
+
+/* ================================================== */
+
+struct ip_hw_instance {
+ struct kobject kobj; /* ip_discovery/die/#die/#hw_id/#instance/<attrs...> */
+
+ int hw_id;
+ u8 num_instance;
+ u8 major, minor, revision;
+ u8 harvest;
+
+ int num_base_addresses;
+ u32 base_addr[];
+};
+
+struct ip_hw_id {
+ struct kset hw_id_kset; /* ip_discovery/die/#die/#hw_id/, contains ip_hw_instance */
+ int hw_id;
+};
+
+struct ip_die_entry {
+ struct kset ip_kset; /* ip_discovery/die/#die/, contains ip_hw_id */
+ u16 num_ips;
+};
+
+/* -------------------------------------------------- */
+
+struct ip_hw_instance_attr {
+ struct attribute attr;
+ ssize_t (*show)(struct ip_hw_instance *ip_hw_instance, char *buf);
+};
+
+static ssize_t hw_id_show(struct ip_hw_instance *ip_hw_instance, char *buf)
+{
+ return sysfs_emit(buf, "%d\n", ip_hw_instance->hw_id);
+}
+
+static ssize_t num_instance_show(struct ip_hw_instance *ip_hw_instance, char *buf)
+{
+ return sysfs_emit(buf, "%d\n", ip_hw_instance->num_instance);
+}
+
+static ssize_t major_show(struct ip_hw_instance *ip_hw_instance, char *buf)
+{
+ return sysfs_emit(buf, "%d\n", ip_hw_instance->major);
+}
+
+static ssize_t minor_show(struct ip_hw_instance *ip_hw_instance, char *buf)
+{
+ return sysfs_emit(buf, "%d\n", ip_hw_instance->minor);
+}
+
+static ssize_t revision_show(struct ip_hw_instance *ip_hw_instance, char *buf)
+{
+ return sysfs_emit(buf, "%d\n", ip_hw_instance->revision);
+}
+
+static ssize_t harvest_show(struct ip_hw_instance *ip_hw_instance, char *buf)
+{
+ return sysfs_emit(buf, "0x%01X\n", ip_hw_instance->harvest);
+}
+
+static ssize_t num_base_addresses_show(struct ip_hw_instance *ip_hw_instance, char *buf)
+{
+ return sysfs_emit(buf, "%d\n", ip_hw_instance->num_base_addresses);
+}
+
+static ssize_t base_addr_show(struct ip_hw_instance *ip_hw_instance, char *buf)
+{
+ ssize_t res, at;
+ int ii;
+
+ for (res = at = ii = 0; ii < ip_hw_instance->num_base_addresses; ii++) {
+ /* Here we satisfy the condition that, at + size <= PAGE_SIZE.
+ */
+ if (at + 12 > PAGE_SIZE)
+ break;
+ res = sysfs_emit_at(buf, at, "0x%08X\n",
+ ip_hw_instance->base_addr[ii]);
+ if (res <= 0)
+ break;
+ at += res;
+ }
+
+ return res < 0 ? res : at;
+}
+
+static struct ip_hw_instance_attr ip_hw_attr[] = {
+ __ATTR_RO(hw_id),
+ __ATTR_RO(num_instance),
+ __ATTR_RO(major),
+ __ATTR_RO(minor),
+ __ATTR_RO(revision),
+ __ATTR_RO(harvest),
+ __ATTR_RO(num_base_addresses),
+ __ATTR_RO(base_addr),
+};
+
+static struct attribute *ip_hw_instance_attrs[ARRAY_SIZE(ip_hw_attr) + 1];
+ATTRIBUTE_GROUPS(ip_hw_instance);
+
+#define to_ip_hw_instance(x) container_of(x, struct ip_hw_instance, kobj)
+#define to_ip_hw_instance_attr(x) container_of(x, struct ip_hw_instance_attr, attr)
+
+static ssize_t ip_hw_instance_attr_show(struct kobject *kobj,
+ struct attribute *attr,
+ char *buf)
+{
+ struct ip_hw_instance *ip_hw_instance = to_ip_hw_instance(kobj);
+ struct ip_hw_instance_attr *ip_hw_attr = to_ip_hw_instance_attr(attr);
+
+ if (!ip_hw_attr->show)
+ return -EIO;
+
+ return ip_hw_attr->show(ip_hw_instance, buf);
+}
+
+static const struct sysfs_ops ip_hw_instance_sysfs_ops = {
+ .show = ip_hw_instance_attr_show,
+};
+
+static void ip_hw_instance_release(struct kobject *kobj)
+{
+ struct ip_hw_instance *ip_hw_instance = to_ip_hw_instance(kobj);
+
+ kfree(ip_hw_instance);
+}
+
+static struct kobj_type ip_hw_instance_ktype = {
+ .release = ip_hw_instance_release,
+ .sysfs_ops = &ip_hw_instance_sysfs_ops,
+ .default_groups = ip_hw_instance_groups,
+};
+
+/* -------------------------------------------------- */
+
+#define to_ip_hw_id(x) container_of(to_kset(x), struct ip_hw_id, hw_id_kset)
+
+static void ip_hw_id_release(struct kobject *kobj)
+{
+ struct ip_hw_id *ip_hw_id = to_ip_hw_id(kobj);
+
+ if (!list_empty(&ip_hw_id->hw_id_kset.list))
+ DRM_ERROR("ip_hw_id->hw_id_kset is not empty");
+ kfree(ip_hw_id);
+}
+
+static struct kobj_type ip_hw_id_ktype = {
+ .release = ip_hw_id_release,
+ .sysfs_ops = &kobj_sysfs_ops,
+};
+
+/* -------------------------------------------------- */
+
+static void die_kobj_release(struct kobject *kobj);
+static void ip_disc_release(struct kobject *kobj);
+
+struct ip_die_entry_attribute {
+ struct attribute attr;
+ ssize_t (*show)(struct ip_die_entry *ip_die_entry, char *buf);
+};
+
+#define to_ip_die_entry_attr(x) container_of(x, struct ip_die_entry_attribute, attr)
+
+static ssize_t num_ips_show(struct ip_die_entry *ip_die_entry, char *buf)
+{
+ return sysfs_emit(buf, "%d\n", ip_die_entry->num_ips);
+}
+
+/* If there are more ip_die_entry attrs, other than the number of IPs,
+ * we can make this intro an array of attrs, and then initialize
+ * ip_die_entry_attrs in a loop.
+ */
+static struct ip_die_entry_attribute num_ips_attr =
+ __ATTR_RO(num_ips);
+
+static struct attribute *ip_die_entry_attrs[] = {
+ &num_ips_attr.attr,
+ NULL,
+};
+ATTRIBUTE_GROUPS(ip_die_entry); /* ip_die_entry_groups */
+
+#define to_ip_die_entry(x) container_of(to_kset(x), struct ip_die_entry, ip_kset)
+
+static ssize_t ip_die_entry_attr_show(struct kobject *kobj,
+ struct attribute *attr,
+ char *buf)
+{
+ struct ip_die_entry_attribute *ip_die_entry_attr = to_ip_die_entry_attr(attr);
+ struct ip_die_entry *ip_die_entry = to_ip_die_entry(kobj);
+
+ if (!ip_die_entry_attr->show)
+ return -EIO;
+
+ return ip_die_entry_attr->show(ip_die_entry, buf);
+}
+
+static void ip_die_entry_release(struct kobject *kobj)
+{
+ struct ip_die_entry *ip_die_entry = to_ip_die_entry(kobj);
+
+ if (!list_empty(&ip_die_entry->ip_kset.list))
+ DRM_ERROR("ip_die_entry->ip_kset is not empty");
+ kfree(ip_die_entry);
+}
+
+static const struct sysfs_ops ip_die_entry_sysfs_ops = {
+ .show = ip_die_entry_attr_show,
+};
+
+static struct kobj_type ip_die_entry_ktype = {
+ .release = ip_die_entry_release,
+ .sysfs_ops = &ip_die_entry_sysfs_ops,
+ .default_groups = ip_die_entry_groups,
+};
+
+static struct kobj_type die_kobj_ktype = {
+ .release = die_kobj_release,
+ .sysfs_ops = &kobj_sysfs_ops,
+};
+
+static struct kobj_type ip_discovery_ktype = {
+ .release = ip_disc_release,
+ .sysfs_ops = &kobj_sysfs_ops,
+};
+
+struct ip_discovery_top {
+ struct kobject kobj; /* ip_discovery/ */
+ struct kset die_kset; /* ip_discovery/die/, contains ip_die_entry */
+ struct amdgpu_device *adev;
+};
+
+static void die_kobj_release(struct kobject *kobj)
+{
+ struct ip_discovery_top *ip_top = container_of(to_kset(kobj),
+ struct ip_discovery_top,
+ die_kset);
+ if (!list_empty(&ip_top->die_kset.list))
+ DRM_ERROR("ip_top->die_kset is not empty");
+}
+
+static void ip_disc_release(struct kobject *kobj)
+{
+ struct ip_discovery_top *ip_top = container_of(kobj, struct ip_discovery_top,
+ kobj);
+ struct amdgpu_device *adev = ip_top->adev;
+
+ adev->ip_top = NULL;
+ kfree(ip_top);
+}
+
+static int amdgpu_discovery_sysfs_ips(struct amdgpu_device *adev,
+ struct ip_die_entry *ip_die_entry,
+ const size_t _ip_offset, const int num_ips)
+{
+ int ii, jj, kk, res;
+
+ DRM_DEBUG("num_ips:%d", num_ips);
+
+ /* Find all IPs of a given HW ID, and add their instance to
+ * #die/#hw_id/#instance/<attributes>
+ */
+ for (ii = 0; ii < HW_ID_MAX; ii++) {
+ struct ip_hw_id *ip_hw_id = NULL;
+ size_t ip_offset = _ip_offset;
+
+ for (jj = 0; jj < num_ips; jj++) {
+ struct ip *ip;
+ struct ip_hw_instance *ip_hw_instance;
+
+ ip = (struct ip *)(adev->mman.discovery_bin + ip_offset);
+ if (amdgpu_discovery_validate_ip(ip) ||
+ le16_to_cpu(ip->hw_id) != ii)
+ goto next_ip;
+
+ DRM_DEBUG("match:%d @ ip_offset:%zu", ii, ip_offset);
+
+ /* We have a hw_id match; register the hw
+ * block if not yet registered.
+ */
+ if (!ip_hw_id) {
+ ip_hw_id = kzalloc(sizeof(*ip_hw_id), GFP_KERNEL);
+ if (!ip_hw_id)
+ return -ENOMEM;
+ ip_hw_id->hw_id = ii;
+
+ kobject_set_name(&ip_hw_id->hw_id_kset.kobj, "%d", ii);
+ ip_hw_id->hw_id_kset.kobj.kset = &ip_die_entry->ip_kset;
+ ip_hw_id->hw_id_kset.kobj.ktype = &ip_hw_id_ktype;
+ res = kset_register(&ip_hw_id->hw_id_kset);
+ if (res) {
+ DRM_ERROR("Couldn't register ip_hw_id kset");
+ kfree(ip_hw_id);
+ return res;
+ }
+ if (hw_id_names[ii]) {
+ res = sysfs_create_link(&ip_die_entry->ip_kset.kobj,
+ &ip_hw_id->hw_id_kset.kobj,
+ hw_id_names[ii]);
+ if (res) {
+ DRM_ERROR("Couldn't create IP link %s in IP Die:%s\n",
+ hw_id_names[ii],
+ kobject_name(&ip_die_entry->ip_kset.kobj));
+ }
+ }
+ }
+
+ /* Now register its instance.
+ */
+ ip_hw_instance = kzalloc(struct_size(ip_hw_instance,
+ base_addr,
+ ip->num_base_address),
+ GFP_KERNEL);
+ if (!ip_hw_instance) {
+ DRM_ERROR("no memory for ip_hw_instance");
+ return -ENOMEM;
+ }
+ ip_hw_instance->hw_id = le16_to_cpu(ip->hw_id); /* == ii */
+ ip_hw_instance->num_instance = ip->number_instance;
+ ip_hw_instance->major = ip->major;
+ ip_hw_instance->minor = ip->minor;
+ ip_hw_instance->revision = ip->revision;
+ ip_hw_instance->harvest = ip->harvest;
+ ip_hw_instance->num_base_addresses = ip->num_base_address;
+
+ for (kk = 0; kk < ip_hw_instance->num_base_addresses; kk++)
+ ip_hw_instance->base_addr[kk] = ip->base_address[kk];
+
+ kobject_init(&ip_hw_instance->kobj, &ip_hw_instance_ktype);
+ ip_hw_instance->kobj.kset = &ip_hw_id->hw_id_kset;
+ res = kobject_add(&ip_hw_instance->kobj, NULL,
+ "%d", ip_hw_instance->num_instance);
+next_ip:
+ ip_offset += sizeof(*ip) + 4 * (ip->num_base_address - 1);
+ }
+ }
+
+ return 0;
+}
+
+static int amdgpu_discovery_sysfs_recurse(struct amdgpu_device *adev)
+{
+ struct binary_header *bhdr;
+ struct ip_discovery_header *ihdr;
+ struct die_header *dhdr;
+ struct kset *die_kset = &adev->ip_top->die_kset;
+ u16 num_dies, die_offset, num_ips;
+ size_t ip_offset;
+ int ii, res;
+
+ bhdr = (struct binary_header *)adev->mman.discovery_bin;
+ ihdr = (struct ip_discovery_header *)(adev->mman.discovery_bin +
+ le16_to_cpu(bhdr->table_list[IP_DISCOVERY].offset));
+ num_dies = le16_to_cpu(ihdr->num_dies);
+
+ DRM_DEBUG("number of dies: %d\n", num_dies);
+
+ for (ii = 0; ii < num_dies; ii++) {
+ struct ip_die_entry *ip_die_entry;
+
+ die_offset = le16_to_cpu(ihdr->die_info[ii].die_offset);
+ dhdr = (struct die_header *)(adev->mman.discovery_bin + die_offset);
+ num_ips = le16_to_cpu(dhdr->num_ips);
+ ip_offset = die_offset + sizeof(*dhdr);
+
+ /* Add the die to the kset.
+ *
+ * dhdr->die_id == ii, which was checked in
+ * amdgpu_discovery_reg_base_init().
+ */
+
+ ip_die_entry = kzalloc(sizeof(*ip_die_entry), GFP_KERNEL);
+ if (!ip_die_entry)
+ return -ENOMEM;
+
+ ip_die_entry->num_ips = num_ips;
+
+ kobject_set_name(&ip_die_entry->ip_kset.kobj, "%d", le16_to_cpu(dhdr->die_id));
+ ip_die_entry->ip_kset.kobj.kset = die_kset;
+ ip_die_entry->ip_kset.kobj.ktype = &ip_die_entry_ktype;
+ res = kset_register(&ip_die_entry->ip_kset);
+ if (res) {
+ DRM_ERROR("Couldn't register ip_die_entry kset");
+ kfree(ip_die_entry);
+ return res;
+ }
+
+ amdgpu_discovery_sysfs_ips(adev, ip_die_entry, ip_offset, num_ips);
+ }
+
+ return 0;
+}
+
+static int amdgpu_discovery_sysfs_init(struct amdgpu_device *adev)
+{
+ struct kset *die_kset;
+ int res, ii;
+
+ adev->ip_top = kzalloc(sizeof(*adev->ip_top), GFP_KERNEL);
+ if (!adev->ip_top)
+ return -ENOMEM;
+
+ adev->ip_top->adev = adev;
+
+ res = kobject_init_and_add(&adev->ip_top->kobj, &ip_discovery_ktype,
+ &adev->dev->kobj, "ip_discovery");
+ if (res) {
+ DRM_ERROR("Couldn't init and add ip_discovery/");
+ goto Err;
+ }
+
+ die_kset = &adev->ip_top->die_kset;
+ kobject_set_name(&die_kset->kobj, "%s", "die");
+ die_kset->kobj.parent = &adev->ip_top->kobj;
+ die_kset->kobj.ktype = &die_kobj_ktype;
+ res = kset_register(&adev->ip_top->die_kset);
+ if (res) {
+ DRM_ERROR("Couldn't register die_kset");
+ goto Err;
+ }
+
+ for (ii = 0; ii < ARRAY_SIZE(ip_hw_attr); ii++)
+ ip_hw_instance_attrs[ii] = &ip_hw_attr[ii].attr;
+ ip_hw_instance_attrs[ii] = NULL;
+
+ res = amdgpu_discovery_sysfs_recurse(adev);
+
+ return res;
+Err:
+ kobject_put(&adev->ip_top->kobj);
+ return res;
+}
+
+/* -------------------------------------------------- */
+
+#define list_to_kobj(el) container_of(el, struct kobject, entry)
+
+static void amdgpu_discovery_sysfs_ip_hw_free(struct ip_hw_id *ip_hw_id)
+{
+ struct list_head *el, *tmp;
+ struct kset *hw_id_kset;
+
+ hw_id_kset = &ip_hw_id->hw_id_kset;
+ spin_lock(&hw_id_kset->list_lock);
+ list_for_each_prev_safe(el, tmp, &hw_id_kset->list) {
+ list_del_init(el);
+ spin_unlock(&hw_id_kset->list_lock);
+ /* kobject is embedded in ip_hw_instance */
+ kobject_put(list_to_kobj(el));
+ spin_lock(&hw_id_kset->list_lock);
+ }
+ spin_unlock(&hw_id_kset->list_lock);
+ kobject_put(&ip_hw_id->hw_id_kset.kobj);
+}
+
+static void amdgpu_discovery_sysfs_die_free(struct ip_die_entry *ip_die_entry)
+{
+ struct list_head *el, *tmp;
+ struct kset *ip_kset;
+
+ ip_kset = &ip_die_entry->ip_kset;
+ spin_lock(&ip_kset->list_lock);
+ list_for_each_prev_safe(el, tmp, &ip_kset->list) {
+ list_del_init(el);
+ spin_unlock(&ip_kset->list_lock);
+ amdgpu_discovery_sysfs_ip_hw_free(to_ip_hw_id(list_to_kobj(el)));
+ spin_lock(&ip_kset->list_lock);
+ }
+ spin_unlock(&ip_kset->list_lock);
+ kobject_put(&ip_die_entry->ip_kset.kobj);
+}
+
+static void amdgpu_discovery_sysfs_fini(struct amdgpu_device *adev)
+{
+ struct list_head *el, *tmp;
+ struct kset *die_kset;
+
+ die_kset = &adev->ip_top->die_kset;
+ spin_lock(&die_kset->list_lock);
+ list_for_each_prev_safe(el, tmp, &die_kset->list) {
+ list_del_init(el);
+ spin_unlock(&die_kset->list_lock);
+ amdgpu_discovery_sysfs_die_free(to_ip_die_entry(list_to_kobj(el)));
+ spin_lock(&die_kset->list_lock);
+ }
+ spin_unlock(&die_kset->list_lock);
+ kobject_put(&adev->ip_top->die_kset.kobj);
+ kobject_put(&adev->ip_top->kobj);
+}
+
+/* ================================================== */
+
int amdgpu_discovery_reg_base_init(struct amdgpu_device *adev)
{
struct binary_header *bhdr;
@@ -492,6 +1067,8 @@ next_ip:
}
}
+ amdgpu_discovery_sysfs_init(adev);
+
return 0;
}
@@ -545,32 +1122,26 @@ int amdgpu_discovery_get_ip_version(struct amdgpu_device *adev, int hw_id, int n
void amdgpu_discovery_harvest_ip(struct amdgpu_device *adev)
{
- struct binary_header *bhdr;
- struct harvest_table *harvest_info;
- int i, vcn_harvest_count = 0;
-
- bhdr = (struct binary_header *)adev->mman.discovery_bin;
- harvest_info = (struct harvest_table *)(adev->mman.discovery_bin +
- le16_to_cpu(bhdr->table_list[HARVEST_INFO].offset));
-
- for (i = 0; i < 32; i++) {
- if (le16_to_cpu(harvest_info->list[i].hw_id) == 0)
- break;
+ int vcn_harvest_count = 0;
- switch (le16_to_cpu(harvest_info->list[i].hw_id)) {
- case VCN_HWID:
- vcn_harvest_count++;
- if (harvest_info->list[i].number_instance == 0)
- adev->vcn.harvest_config |= AMDGPU_VCN_HARVEST_VCN0;
- else
- adev->vcn.harvest_config |= AMDGPU_VCN_HARVEST_VCN1;
- break;
- case DMU_HWID:
- adev->harvest_ip_mask |= AMD_HARVEST_IP_DMU_MASK;
- break;
- default:
- break;
- }
+ /*
+ * Harvest table does not fit Navi1x and legacy GPUs,
+ * so read harvest bit per IP data structure to set
+ * harvest configuration.
+ */
+ if (adev->ip_versions[GC_HWIP][0] < IP_VERSION(10, 2, 0)) {
+ if ((adev->pdev->device == 0x731E &&
+ (adev->pdev->revision == 0xC6 ||
+ adev->pdev->revision == 0xC7)) ||
+ (adev->pdev->device == 0x7340 &&
+ adev->pdev->revision == 0xC9) ||
+ (adev->pdev->device == 0x7360 &&
+ adev->pdev->revision == 0xC7))
+ amdgpu_discovery_read_harvest_bit_per_ip(adev,
+ &vcn_harvest_count);
+ } else {
+ amdgpu_discovery_read_from_harvest_table(adev,
+ &vcn_harvest_count);
}
amdgpu_discovery_harvest_config_quirk(adev);
@@ -674,12 +1245,15 @@ static int amdgpu_discovery_set_common_ip_blocks(struct amdgpu_device *adev)
case IP_VERSION(10, 1, 1):
case IP_VERSION(10, 1, 2):
case IP_VERSION(10, 1, 3):
+ case IP_VERSION(10, 1, 4):
case IP_VERSION(10, 3, 0):
case IP_VERSION(10, 3, 1):
case IP_VERSION(10, 3, 2):
case IP_VERSION(10, 3, 3):
case IP_VERSION(10, 3, 4):
case IP_VERSION(10, 3, 5):
+ case IP_VERSION(10, 3, 6):
+ case IP_VERSION(10, 3, 7):
amdgpu_device_ip_block_add(adev, &nv_common_ip_block);
break;
default:
@@ -709,12 +1283,15 @@ static int amdgpu_discovery_set_gmc_ip_blocks(struct amdgpu_device *adev)
case IP_VERSION(10, 1, 1):
case IP_VERSION(10, 1, 2):
case IP_VERSION(10, 1, 3):
+ case IP_VERSION(10, 1, 4):
case IP_VERSION(10, 3, 0):
case IP_VERSION(10, 3, 1):
case IP_VERSION(10, 3, 2):
case IP_VERSION(10, 3, 3):
case IP_VERSION(10, 3, 4):
case IP_VERSION(10, 3, 5):
+ case IP_VERSION(10, 3, 6):
+ case IP_VERSION(10, 3, 7):
amdgpu_device_ip_block_add(adev, &gmc_v10_0_ip_block);
break;
default:
@@ -790,6 +1367,8 @@ static int amdgpu_discovery_set_psp_ip_blocks(struct amdgpu_device *adev)
case IP_VERSION(13, 0, 1):
case IP_VERSION(13, 0, 2):
case IP_VERSION(13, 0, 3):
+ case IP_VERSION(13, 0, 5):
+ case IP_VERSION(13, 0, 8):
amdgpu_device_ip_block_add(adev, &psp_v13_0_ip_block);
break;
default:
@@ -831,6 +1410,8 @@ static int amdgpu_discovery_set_smu_ip_blocks(struct amdgpu_device *adev)
case IP_VERSION(13, 0, 1):
case IP_VERSION(13, 0, 2):
case IP_VERSION(13, 0, 3):
+ case IP_VERSION(13, 0, 5):
+ case IP_VERSION(13, 0, 8):
amdgpu_device_ip_block_add(adev, &smu_v13_0_ip_block);
break;
default:
@@ -846,8 +1427,14 @@ static int amdgpu_discovery_set_display_ip_blocks(struct amdgpu_device *adev)
{
if (adev->enable_virtual_display || amdgpu_sriov_vf(adev)) {
amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block);
+ return 0;
+ }
+
+ if (!amdgpu_device_has_dc_support(adev))
+ return 0;
+
#if defined(CONFIG_DRM_AMD_DC)
- } else if (adev->ip_versions[DCE_HWIP][0]) {
+ if (adev->ip_versions[DCE_HWIP][0]) {
switch (adev->ip_versions[DCE_HWIP][0]) {
case IP_VERSION(1, 0, 0):
case IP_VERSION(1, 0, 1):
@@ -861,6 +1448,8 @@ static int amdgpu_discovery_set_display_ip_blocks(struct amdgpu_device *adev)
case IP_VERSION(3, 0, 1):
case IP_VERSION(3, 1, 2):
case IP_VERSION(3, 1, 3):
+ case IP_VERSION(3, 1, 5):
+ case IP_VERSION(3, 1, 6):
amdgpu_device_ip_block_add(adev, &dm_ip_block);
break;
default:
@@ -882,8 +1471,8 @@ static int amdgpu_discovery_set_display_ip_blocks(struct amdgpu_device *adev)
adev->ip_versions[DCI_HWIP][0]);
return -EINVAL;
}
-#endif
}
+#endif
return 0;
}
@@ -904,12 +1493,15 @@ static int amdgpu_discovery_set_gc_ip_blocks(struct amdgpu_device *adev)
case IP_VERSION(10, 1, 2):
case IP_VERSION(10, 1, 1):
case IP_VERSION(10, 1, 3):
+ case IP_VERSION(10, 1, 4):
case IP_VERSION(10, 3, 0):
case IP_VERSION(10, 3, 2):
case IP_VERSION(10, 3, 1):
case IP_VERSION(10, 3, 4):
case IP_VERSION(10, 3, 5):
+ case IP_VERSION(10, 3, 6):
case IP_VERSION(10, 3, 3):
+ case IP_VERSION(10, 3, 7):
amdgpu_device_ip_block_add(adev, &gfx_v10_0_ip_block);
break;
default:
@@ -944,8 +1536,10 @@ static int amdgpu_discovery_set_sdma_ip_blocks(struct amdgpu_device *adev)
case IP_VERSION(5, 2, 2):
case IP_VERSION(5, 2, 4):
case IP_VERSION(5, 2, 5):
+ case IP_VERSION(5, 2, 6):
case IP_VERSION(5, 2, 3):
case IP_VERSION(5, 2, 1):
+ case IP_VERSION(5, 2, 7):
amdgpu_device_ip_block_add(adev, &sdma_v5_2_ip_block);
break;
default:
@@ -1012,6 +1606,7 @@ static int amdgpu_discovery_set_mm_ip_blocks(struct amdgpu_device *adev)
case IP_VERSION(3, 0, 0):
case IP_VERSION(3, 0, 16):
case IP_VERSION(3, 1, 1):
+ case IP_VERSION(3, 1, 2):
case IP_VERSION(3, 0, 2):
case IP_VERSION(3, 0, 192):
amdgpu_device_ip_block_add(adev, &vcn_v3_0_ip_block);
@@ -1038,12 +1633,14 @@ static int amdgpu_discovery_set_mes_ip_blocks(struct amdgpu_device *adev)
case IP_VERSION(10, 1, 1):
case IP_VERSION(10, 1, 2):
case IP_VERSION(10, 1, 3):
+ case IP_VERSION(10, 1, 4):
case IP_VERSION(10, 3, 0):
case IP_VERSION(10, 3, 1):
case IP_VERSION(10, 3, 2):
case IP_VERSION(10, 3, 3):
case IP_VERSION(10, 3, 4):
case IP_VERSION(10, 3, 5):
+ case IP_VERSION(10, 3, 6):
amdgpu_device_ip_block_add(adev, &mes_v10_1_ip_block);
break;
default:
@@ -1217,11 +1814,6 @@ int amdgpu_discovery_set_ip_blocks(struct amdgpu_device *adev)
return -EINVAL;
amdgpu_discovery_harvest_ip(adev);
-
- if (!adev->mman.discovery_bin) {
- DRM_ERROR("ip discovery uninitialized\n");
- return -EINVAL;
- }
break;
}
@@ -1242,6 +1834,7 @@ int amdgpu_discovery_set_ip_blocks(struct amdgpu_device *adev)
case IP_VERSION(10, 1, 1):
case IP_VERSION(10, 1, 2):
case IP_VERSION(10, 1, 3):
+ case IP_VERSION(10, 1, 4):
case IP_VERSION(10, 3, 0):
case IP_VERSION(10, 3, 2):
case IP_VERSION(10, 3, 4):
@@ -1254,10 +1847,32 @@ int amdgpu_discovery_set_ip_blocks(struct amdgpu_device *adev)
case IP_VERSION(10, 3, 3):
adev->family = AMDGPU_FAMILY_YC;
break;
+ case IP_VERSION(10, 3, 6):
+ adev->family = AMDGPU_FAMILY_GC_10_3_6;
+ break;
+ case IP_VERSION(10, 3, 7):
+ adev->family = AMDGPU_FAMILY_GC_10_3_7;
+ break;
default:
return -EINVAL;
}
+ switch (adev->ip_versions[GC_HWIP][0]) {
+ case IP_VERSION(9, 1, 0):
+ case IP_VERSION(9, 2, 2):
+ case IP_VERSION(9, 3, 0):
+ case IP_VERSION(10, 1, 3):
+ case IP_VERSION(10, 1, 4):
+ case IP_VERSION(10, 3, 1):
+ case IP_VERSION(10, 3, 3):
+ case IP_VERSION(10, 3, 6):
+ case IP_VERSION(10, 3, 7):
+ adev->flags |= AMD_IS_APU;
+ break;
+ default:
+ break;
+ }
+
if (adev->ip_versions[XGMI_HWIP][0] == IP_VERSION(4, 8, 0))
adev->gmc.xgmi.supported = true;
@@ -1285,7 +1900,9 @@ int amdgpu_discovery_set_ip_blocks(struct amdgpu_device *adev)
break;
case IP_VERSION(7, 2, 0):
case IP_VERSION(7, 2, 1):
+ case IP_VERSION(7, 3, 0):
case IP_VERSION(7, 5, 0):
+ case IP_VERSION(7, 5, 1):
adev->nbio.funcs = &nbio_v7_2_funcs;
adev->nbio.hdp_flush_reg = &nbio_v7_2_hdp_flush_reg;
break;
@@ -1368,6 +1985,8 @@ int amdgpu_discovery_set_ip_blocks(struct amdgpu_device *adev)
case IP_VERSION(11, 0, 11):
case IP_VERSION(11, 5, 0):
case IP_VERSION(13, 0, 1):
+ case IP_VERSION(13, 0, 9):
+ case IP_VERSION(13, 0, 10):
adev->smuio.funcs = &smuio_v11_0_6_funcs;
break;
case IP_VERSION(13, 0, 2):
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
index 82011e75ed85..fae5c1debfad 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
@@ -200,8 +200,10 @@ int amdgpu_display_crtc_page_flip_target(struct drm_crtc *crtc,
goto unpin;
}
- r = dma_resv_get_fences(new_abo->tbo.base.resv, NULL,
- &work->shared_count, &work->shared);
+ /* TODO: Unify this with other drivers */
+ r = dma_resv_get_fences(new_abo->tbo.base.resv, true,
+ &work->shared_count,
+ &work->shared);
if (unlikely(r != 0)) {
DRM_ERROR("failed to get fences for buffer\n");
goto unpin;
@@ -504,28 +506,9 @@ uint32_t amdgpu_display_supported_domains(struct amdgpu_device *adev,
*/
if ((bo_flags & AMDGPU_GEM_CREATE_CPU_GTT_USWC) &&
amdgpu_bo_support_uswc(bo_flags) &&
- amdgpu_device_asic_has_dc_support(adev->asic_type)) {
- switch (adev->asic_type) {
- case CHIP_CARRIZO:
- case CHIP_STONEY:
- domain |= AMDGPU_GEM_DOMAIN_GTT;
- break;
- case CHIP_RAVEN:
- /* enable S/G on PCO and RV2 */
- if ((adev->apu_flags & AMD_APU_IS_RAVEN2) ||
- (adev->apu_flags & AMD_APU_IS_PICASSO))
- domain |= AMDGPU_GEM_DOMAIN_GTT;
- break;
- case CHIP_RENOIR:
- case CHIP_VANGOGH:
- case CHIP_YELLOW_CARP:
- domain |= AMDGPU_GEM_DOMAIN_GTT;
- break;
-
- default:
- break;
- }
- }
+ amdgpu_device_asic_has_dc_support(adev->asic_type) &&
+ adev->mode_info.gpu_vm_support)
+ domain |= AMDGPU_GEM_DOMAIN_GTT;
#endif
return domain;
@@ -708,9 +691,9 @@ static int convert_tiling_flags_to_modifier(struct amdgpu_framebuffer *afb)
return -EINVAL;
}
- if (adev->asic_type >= CHIP_SIENNA_CICHLID)
+ if (adev->ip_versions[GC_HWIP][0] >= IP_VERSION(10, 3, 0))
version = AMD_FMT_MOD_TILE_VER_GFX10_RBPLUS;
- else if (adev->family == AMDGPU_FAMILY_NV)
+ else if (adev->ip_versions[GC_HWIP][0] >= IP_VERSION(10, 0, 0))
version = AMD_FMT_MOD_TILE_VER_GFX10;
else
version = AMD_FMT_MOD_TILE_VER_GFX9;
@@ -804,7 +787,7 @@ static int convert_tiling_flags_to_modifier(struct amdgpu_framebuffer *afb)
if (adev->family >= AMDGPU_FAMILY_NV) {
int extra_pipe = 0;
- if (adev->asic_type >= CHIP_SIENNA_CICHLID &&
+ if ((adev->ip_versions[GC_HWIP][0] >= IP_VERSION(10, 3, 0)) &&
pipes == packers && pipes > 1)
extra_pipe = 1;
@@ -954,7 +937,7 @@ static int amdgpu_display_verify_sizes(struct amdgpu_framebuffer *rfb)
int ret;
unsigned int i, block_width, block_height, block_size_log2;
- if (!rfb->base.dev->mode_config.allow_fb_modifiers)
+ if (rfb->base.dev->mode_config.fb_modifiers_not_supported)
return 0;
for (i = 0; i < format_info->num_planes; ++i) {
@@ -1141,7 +1124,7 @@ int amdgpu_display_framebuffer_init(struct drm_device *dev,
if (ret)
return ret;
- if (!dev->mode_config.allow_fb_modifiers) {
+ if (dev->mode_config.fb_modifiers_not_supported && !adev->enable_virtual_display) {
drm_WARN_ONCE(dev, adev->family >= AMDGPU_FAMILY_AI,
"GFX9+ requires FB check based on format modifier\n");
ret = check_tiling_flags_gfx6(rfb);
@@ -1149,7 +1132,7 @@ int amdgpu_display_framebuffer_init(struct drm_device *dev,
return ret;
}
- if (dev->mode_config.allow_fb_modifiers &&
+ if (!dev->mode_config.fb_modifiers_not_supported &&
!(rfb->base.flags & DRM_MODE_FB_MODIFIERS)) {
ret = convert_tiling_flags_to_modifier(rfb);
if (ret) {
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
index b21bcdc97460..bb1c025d9001 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
@@ -99,9 +99,11 @@
* - 3.42.0 - Add 16bpc fixed point display support
* - 3.43.0 - Add device hot plug/unplug support
* - 3.44.0 - DCN3 supports DCC independent block settings: !64B && 128B, 64B && 128B
+ * - 3.45.0 - Add context ioctl stable pstate interface
+ * * 3.46.0 - To enable hot plug amdgpu tests in libdrm
*/
#define KMS_DRIVER_MAJOR 3
-#define KMS_DRIVER_MINOR 44
+#define KMS_DRIVER_MINOR 46
#define KMS_DRIVER_PATCHLEVEL 0
int amdgpu_vram_limit;
@@ -109,8 +111,6 @@ int amdgpu_vis_vram_limit;
int amdgpu_gart_size = -1; /* auto */
int amdgpu_gtt_size = -1; /* auto */
int amdgpu_moverate = -1; /* auto */
-int amdgpu_benchmarking;
-int amdgpu_testing;
int amdgpu_audio = -1;
int amdgpu_disp_priority;
int amdgpu_hw_i2c;
@@ -174,10 +174,11 @@ int amdgpu_mes;
int amdgpu_noretry = -1;
int amdgpu_force_asic_type = -1;
int amdgpu_tmz = -1; /* auto */
-uint amdgpu_freesync_vid_mode;
int amdgpu_reset_method = -1; /* auto */
int amdgpu_num_kcq = -1;
int amdgpu_smartshift_bias;
+int amdgpu_use_xgmi_p2p = 1;
+int amdgpu_vcnfw_log;
static void amdgpu_drv_delayed_reset_work_handler(struct work_struct *work);
@@ -232,20 +233,6 @@ MODULE_PARM_DESC(moverate, "Maximum buffer migration rate in MB/s. (32, 64, etc.
module_param_named(moverate, amdgpu_moverate, int, 0600);
/**
- * DOC: benchmark (int)
- * Run benchmarks. The default is 0 (Skip benchmarks).
- */
-MODULE_PARM_DESC(benchmark, "Run benchmark");
-module_param_named(benchmark, amdgpu_benchmarking, int, 0444);
-
-/**
- * DOC: test (int)
- * Test BO GTT->VRAM and VRAM->GTT GPU copies. The default is 0 (Skip test, only set 1 to run test).
- */
-MODULE_PARM_DESC(test, "Run tests");
-module_param_named(test, amdgpu_testing, int, 0444);
-
-/**
* DOC: audio (int)
* Set HDMI/DPAudio. Only affects non-DC display handling. The default is -1 (Enabled), set 0 to disabled it.
*/
@@ -667,6 +654,13 @@ MODULE_PARM_DESC(force_asic_type,
"A non negative value used to specify the asic type for all supported GPUs");
module_param_named(force_asic_type, amdgpu_force_asic_type, int, 0444);
+/**
+ * DOC: use_xgmi_p2p (int)
+ * Enables/disables XGMI P2P interface (0 = disable, 1 = enable).
+ */
+MODULE_PARM_DESC(use_xgmi_p2p,
+ "Enable XGMI P2P interface (0 = disable; 1 = enable (default))");
+module_param_named(use_xgmi_p2p, amdgpu_use_xgmi_p2p, int, 0444);
#ifdef CONFIG_HSA_AMD
@@ -740,7 +734,7 @@ MODULE_PARM_DESC(debug_largebar,
* systems with a broken CRAT table.
*
* Default is auto (according to asic type, iommu_v2, and crat table, to decide
- * whehter use CRAT)
+ * whether use CRAT)
*/
int ignore_crat;
module_param(ignore_crat, int, 0444);
@@ -844,36 +838,10 @@ MODULE_PARM_DESC(tmz, "Enable TMZ feature (-1 = auto (default), 0 = off, 1 = on)
module_param_named(tmz, amdgpu_tmz, int, 0444);
/**
- * DOC: freesync_video (uint)
- * Enable the optimization to adjust front porch timing to achieve seamless
- * mode change experience when setting a freesync supported mode for which full
- * modeset is not needed.
- *
- * The Display Core will add a set of modes derived from the base FreeSync
- * video mode into the corresponding connector's mode list based on commonly
- * used refresh rates and VRR range of the connected display, when users enable
- * this feature. From the userspace perspective, they can see a seamless mode
- * change experience when the change between different refresh rates under the
- * same resolution. Additionally, userspace applications such as Video playback
- * can read this modeset list and change the refresh rate based on the video
- * frame rate. Finally, the userspace can also derive an appropriate mode for a
- * particular refresh rate based on the FreeSync Mode and add it to the
- * connector's mode list.
- *
- * Note: This is an experimental feature.
- *
- * The default value: 0 (off).
- */
-MODULE_PARM_DESC(
- freesync_video,
- "Enable freesync modesetting optimization feature (0 = off (default), 1 = on)");
-module_param_named(freesync_video, amdgpu_freesync_vid_mode, uint, 0444);
-
-/**
* DOC: reset_method (int)
- * GPU reset method (-1 = auto (default), 0 = legacy, 1 = mode0, 2 = mode1, 3 = mode2, 4 = baco, 5 = pci)
+ * GPU reset method (-1 = auto (default), 0 = legacy, 1 = mode0, 2 = mode1, 3 = mode2, 4 = baco)
*/
-MODULE_PARM_DESC(reset_method, "GPU reset method (-1 = auto (default), 0 = legacy, 1 = mode0, 2 = mode1, 3 = mode2, 4 = baco/bamaco, 5 = pci)");
+MODULE_PARM_DESC(reset_method, "GPU reset method (-1 = auto (default), 0 = legacy, 1 = mode0, 2 = mode1, 3 = mode2, 4 = baco/bamaco)");
module_param_named(reset_method, amdgpu_reset_method, int, 0444);
/**
@@ -889,6 +857,13 @@ MODULE_PARM_DESC(num_kcq, "number of kernel compute queue user want to setup (8
module_param_named(num_kcq, amdgpu_num_kcq, int, 0444);
/**
+ * DOC: vcnfw_log (int)
+ * Enable vcnfw log output for debugging, the default is disabled.
+ */
+MODULE_PARM_DESC(vcnfw_log, "Enable vcnfw log(0 = disable (default value), 1 = enable)");
+module_param_named(vcnfw_log, amdgpu_vcnfw_log, int, 0444);
+
+/**
* DOC: smu_pptable_id (int)
* Used to override pptable id. id = 0 use VBIOS pptable.
* id > 0 use the soft pptable with specicfied id.
@@ -1525,6 +1500,87 @@ static const u16 amdgpu_unsupported_pciidlist[] = {
0x99A0,
0x99A2,
0x99A4,
+ /* radeon secondary ids */
+ 0x3171,
+ 0x3e70,
+ 0x4164,
+ 0x4165,
+ 0x4166,
+ 0x4168,
+ 0x4170,
+ 0x4171,
+ 0x4172,
+ 0x4173,
+ 0x496e,
+ 0x4a69,
+ 0x4a6a,
+ 0x4a6b,
+ 0x4a70,
+ 0x4a74,
+ 0x4b69,
+ 0x4b6b,
+ 0x4b6c,
+ 0x4c6e,
+ 0x4e64,
+ 0x4e65,
+ 0x4e66,
+ 0x4e67,
+ 0x4e68,
+ 0x4e69,
+ 0x4e6a,
+ 0x4e71,
+ 0x4f73,
+ 0x5569,
+ 0x556b,
+ 0x556d,
+ 0x556f,
+ 0x5571,
+ 0x5854,
+ 0x5874,
+ 0x5940,
+ 0x5941,
+ 0x5b72,
+ 0x5b73,
+ 0x5b74,
+ 0x5b75,
+ 0x5d44,
+ 0x5d45,
+ 0x5d6d,
+ 0x5d6f,
+ 0x5d72,
+ 0x5d77,
+ 0x5e6b,
+ 0x5e6d,
+ 0x7120,
+ 0x7124,
+ 0x7129,
+ 0x712e,
+ 0x712f,
+ 0x7162,
+ 0x7163,
+ 0x7166,
+ 0x7167,
+ 0x7172,
+ 0x7173,
+ 0x71a0,
+ 0x71a1,
+ 0x71a3,
+ 0x71a7,
+ 0x71bb,
+ 0x71e0,
+ 0x71e1,
+ 0x71e2,
+ 0x71e6,
+ 0x71e7,
+ 0x71f2,
+ 0x7269,
+ 0x726b,
+ 0x726e,
+ 0x72a0,
+ 0x72a8,
+ 0x72b1,
+ 0x72b3,
+ 0x793f,
};
static const struct pci_device_id pciidlist[] = {
@@ -1861,13 +1917,14 @@ static const struct pci_device_id pciidlist[] = {
{0x1002, 0x73FF, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_DIMGREY_CAVEFISH},
/* Aldebaran */
- {0x1002, 0x7408, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_ALDEBARAN|AMD_EXP_HW_SUPPORT},
- {0x1002, 0x740C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_ALDEBARAN|AMD_EXP_HW_SUPPORT},
- {0x1002, 0x740F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_ALDEBARAN|AMD_EXP_HW_SUPPORT},
- {0x1002, 0x7410, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_ALDEBARAN|AMD_EXP_HW_SUPPORT},
+ {0x1002, 0x7408, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_ALDEBARAN},
+ {0x1002, 0x740C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_ALDEBARAN},
+ {0x1002, 0x740F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_ALDEBARAN},
+ {0x1002, 0x7410, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_ALDEBARAN},
/* CYAN_SKILLFISH */
{0x1002, 0x13FE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CYAN_SKILLFISH|AMD_IS_APU},
+ {0x1002, 0x143F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CYAN_SKILLFISH|AMD_IS_APU},
/* BEIGE_GOBY */
{0x1002, 0x7420, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_BEIGE_GOBY},
@@ -1913,6 +1970,28 @@ static bool amdgpu_is_fw_framebuffer(resource_size_t base,
return found;
}
+static void amdgpu_get_secondary_funcs(struct amdgpu_device *adev)
+{
+ struct pci_dev *p = NULL;
+ int i;
+
+ /* 0 - GPU
+ * 1 - audio
+ * 2 - USB
+ * 3 - UCSI
+ */
+ for (i = 1; i < 4; i++) {
+ p = pci_get_domain_bus_and_slot(pci_domain_nr(adev->pdev->bus),
+ adev->pdev->bus->number, i);
+ if (p) {
+ pm_runtime_get_sync(&p->dev);
+ pm_runtime_mark_last_busy(&p->dev);
+ pm_runtime_put_autosuspend(&p->dev);
+ pci_dev_put(p);
+ }
+ }
+}
+
static int amdgpu_pci_probe(struct pci_dev *pdev,
const struct pci_device_id *ent)
{
@@ -1930,6 +2009,9 @@ static int amdgpu_pci_probe(struct pci_dev *pdev,
return -ENODEV;
}
+ if (amdgpu_aspm == -1 && !pcie_aspm_enabled(pdev))
+ amdgpu_aspm = 0;
+
if (amdgpu_virtual_display ||
amdgpu_device_asic_has_dc_support(flags & AMD_ASIC_MASK))
supports_atomic = true;
@@ -2045,6 +2127,48 @@ retry_init:
if (ret)
DRM_ERROR("Creating debugfs files failed (%d).\n", ret);
+ if (adev->runpm) {
+ /* only need to skip on ATPX */
+ if (amdgpu_device_supports_px(ddev))
+ dev_pm_set_driver_flags(ddev->dev, DPM_FLAG_NO_DIRECT_COMPLETE);
+ /* we want direct complete for BOCO */
+ if (amdgpu_device_supports_boco(ddev))
+ dev_pm_set_driver_flags(ddev->dev, DPM_FLAG_SMART_PREPARE |
+ DPM_FLAG_SMART_SUSPEND |
+ DPM_FLAG_MAY_SKIP_RESUME);
+ pm_runtime_use_autosuspend(ddev->dev);
+ pm_runtime_set_autosuspend_delay(ddev->dev, 5000);
+
+ pm_runtime_allow(ddev->dev);
+
+ pm_runtime_mark_last_busy(ddev->dev);
+ pm_runtime_put_autosuspend(ddev->dev);
+
+ /*
+ * For runpm implemented via BACO, PMFW will handle the
+ * timing for BACO in and out:
+ * - put ASIC into BACO state only when both video and
+ * audio functions are in D3 state.
+ * - pull ASIC out of BACO state when either video or
+ * audio function is in D0 state.
+ * Also, at startup, PMFW assumes both functions are in
+ * D0 state.
+ *
+ * So if snd driver was loaded prior to amdgpu driver
+ * and audio function was put into D3 state, there will
+ * be no PMFW-aware D-state transition(D0->D3) on runpm
+ * suspend. Thus the BACO will be not correctly kicked in.
+ *
+ * Via amdgpu_get_secondary_funcs(), the audio dev is put
+ * into D0 state. Then there will be a PMFW-aware D-state
+ * transition(D0->D3) on runpm suspend.
+ */
+ if (amdgpu_device_supports_baco(ddev) &&
+ !(adev->flags & AMD_IS_APU) &&
+ (adev->asic_type >= CHIP_NAVI10))
+ amdgpu_get_secondary_funcs(adev);
+ }
+
return 0;
err_pci:
@@ -2056,8 +2180,15 @@ static void
amdgpu_pci_remove(struct pci_dev *pdev)
{
struct drm_device *dev = pci_get_drvdata(pdev);
+ struct amdgpu_device *adev = drm_to_adev(dev);
drm_dev_unplug(dev);
+
+ if (adev->runpm) {
+ pm_runtime_get_sync(dev->dev);
+ pm_runtime_forbid(dev->dev);
+ }
+
amdgpu_driver_unload_kms(dev);
/*
@@ -2165,13 +2296,20 @@ static void amdgpu_drv_delayed_reset_work_handler(struct work_struct *work)
static int amdgpu_pmops_prepare(struct device *dev)
{
struct drm_device *drm_dev = dev_get_drvdata(dev);
+ struct amdgpu_device *adev = drm_to_adev(drm_dev);
/* Return a positive number here so
* DPM_FLAG_SMART_SUSPEND works properly
*/
if (amdgpu_device_supports_boco(drm_dev))
- return pm_runtime_suspended(dev) &&
- pm_suspend_via_firmware();
+ return pm_runtime_suspended(dev);
+
+ /* if we will not support s3 or s2i for the device
+ * then skip suspend
+ */
+ if (!amdgpu_acpi_is_s0ix_active(adev) &&
+ !amdgpu_acpi_is_s3_active(adev))
+ return 1;
return 0;
}
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c
index 45977a72b5dd..5d13ed376ab4 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c
@@ -446,24 +446,18 @@ int amdgpu_fence_driver_start_ring(struct amdgpu_ring *ring,
* for the requested ring.
*
* @ring: ring to init the fence driver on
- * @num_hw_submission: number of entries on the hardware queue
- * @sched_score: optional score atomic shared with other schedulers
*
* Init the fence driver for the requested ring (all asics).
* Helper function for amdgpu_fence_driver_init().
*/
-int amdgpu_fence_driver_init_ring(struct amdgpu_ring *ring,
- unsigned num_hw_submission,
- atomic_t *sched_score)
+int amdgpu_fence_driver_init_ring(struct amdgpu_ring *ring)
{
struct amdgpu_device *adev = ring->adev;
- long timeout;
- int r;
if (!adev)
return -EINVAL;
- if (!is_power_of_2(num_hw_submission))
+ if (!is_power_of_2(ring->num_hw_submission))
return -EINVAL;
ring->fence_drv.cpu_addr = NULL;
@@ -474,41 +468,14 @@ int amdgpu_fence_driver_init_ring(struct amdgpu_ring *ring,
timer_setup(&ring->fence_drv.fallback_timer, amdgpu_fence_fallback, 0);
- ring->fence_drv.num_fences_mask = num_hw_submission * 2 - 1;
+ ring->fence_drv.num_fences_mask = ring->num_hw_submission * 2 - 1;
spin_lock_init(&ring->fence_drv.lock);
- ring->fence_drv.fences = kcalloc(num_hw_submission * 2, sizeof(void *),
+ ring->fence_drv.fences = kcalloc(ring->num_hw_submission * 2, sizeof(void *),
GFP_KERNEL);
+
if (!ring->fence_drv.fences)
return -ENOMEM;
- /* No need to setup the GPU scheduler for rings that don't need it */
- if (ring->no_scheduler)
- return 0;
-
- switch (ring->funcs->type) {
- case AMDGPU_RING_TYPE_GFX:
- timeout = adev->gfx_timeout;
- break;
- case AMDGPU_RING_TYPE_COMPUTE:
- timeout = adev->compute_timeout;
- break;
- case AMDGPU_RING_TYPE_SDMA:
- timeout = adev->sdma_timeout;
- break;
- default:
- timeout = adev->video_timeout;
- break;
- }
-
- r = drm_sched_init(&ring->sched, &amdgpu_sched_ops,
- num_hw_submission, amdgpu_job_hang_limit,
- timeout, NULL, sched_score, ring->name);
- if (r) {
- DRM_ERROR("Failed to create scheduler on ring %s.\n",
- ring->name);
- return r;
- }
-
return 0;
}
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_fru_eeprom.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_fru_eeprom.c
index 2a786e788627..ecada5eadfe3 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_fru_eeprom.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_fru_eeprom.c
@@ -30,7 +30,6 @@
#include "amdgpu_eeprom.h"
#define FRU_EEPROM_MADDR 0x60000
-#define I2C_PRODUCT_INFO_OFFSET 0xC0
static bool is_fru_eeprom_supported(struct amdgpu_device *adev)
{
@@ -40,7 +39,13 @@ static bool is_fru_eeprom_supported(struct amdgpu_device *adev)
*/
struct atom_context *atom_ctx = adev->mode_info.atom_context;
- /* VBIOS is of the format ###-DXXXYY-##. For SKU identification,
+ /* The i2c access is blocked on VF
+ * TODO: Need other way to get the info
+ */
+ if (amdgpu_sriov_vf(adev))
+ return false;
+
+ /* VBIOS is of the format ###-DXXXYYYY-##. For SKU identification,
* we can use just the "DXXX" portion. If there were more models, we
* could convert the 3 characters to a hex integer and use a switch
* for ease/speed/readability. For now, 2 string comparisons are
@@ -59,17 +64,24 @@ static bool is_fru_eeprom_supported(struct amdgpu_device *adev)
case CHIP_ALDEBARAN:
/* All Aldebaran SKUs have the FRU */
return true;
+ case CHIP_SIENNA_CICHLID:
+ if (strnstr(atom_ctx->vbios_version, "D603",
+ sizeof(atom_ctx->vbios_version)))
+ return true;
+ else
+ return false;
default:
return false;
}
}
static int amdgpu_fru_read_eeprom(struct amdgpu_device *adev, uint32_t addrptr,
- unsigned char *buff)
+ unsigned char *buf, size_t buf_size)
{
- int ret, size;
+ int ret;
+ u8 size;
- ret = amdgpu_eeprom_read(&adev->pm.smu_i2c, addrptr, buff, 1);
+ ret = amdgpu_eeprom_read(adev->pm.fru_eeprom_i2c_bus, addrptr, buf, 1);
if (ret < 1) {
DRM_WARN("FRU: Failed to get size field");
return ret;
@@ -78,9 +90,11 @@ static int amdgpu_fru_read_eeprom(struct amdgpu_device *adev, uint32_t addrptr,
/* The size returned by the i2c requires subtraction of 0xC0 since the
* size apparently always reports as 0xC0+actual size.
*/
- size = buff[0] - I2C_PRODUCT_INFO_OFFSET;
+ size = buf[0] & 0x3F;
+ size = min_t(size_t, size, buf_size);
- ret = amdgpu_eeprom_read(&adev->pm.smu_i2c, addrptr + 1, buff, size);
+ ret = amdgpu_eeprom_read(adev->pm.fru_eeprom_i2c_bus, addrptr + 1,
+ buf, size);
if (ret < 1) {
DRM_WARN("FRU: Failed to get data field");
return ret;
@@ -91,19 +105,15 @@ static int amdgpu_fru_read_eeprom(struct amdgpu_device *adev, uint32_t addrptr,
int amdgpu_fru_get_product_info(struct amdgpu_device *adev)
{
- unsigned char buff[AMDGPU_PRODUCT_NAME_LEN+2];
+ unsigned char buf[AMDGPU_PRODUCT_NAME_LEN];
u32 addrptr;
int size, len;
- int offset = 2;
if (!is_fru_eeprom_supported(adev))
return 0;
- if (adev->asic_type == CHIP_ALDEBARAN)
- offset = 0;
-
/* If algo exists, it means that the i2c_adapter's initialized */
- if (!adev->pm.smu_i2c.algo) {
+ if (!adev->pm.fru_eeprom_i2c_bus || !adev->pm.fru_eeprom_i2c_bus->algo) {
DRM_WARN("Cannot access FRU, EEPROM accessor not initialized");
return -ENODEV;
}
@@ -121,7 +131,7 @@ int amdgpu_fru_get_product_info(struct amdgpu_device *adev)
* and the language field, so just start from 0xb, manufacturer size
*/
addrptr = FRU_EEPROM_MADDR + 0xb;
- size = amdgpu_fru_read_eeprom(adev, addrptr, buff);
+ size = amdgpu_fru_read_eeprom(adev, addrptr, buf, sizeof(buf));
if (size < 1) {
DRM_ERROR("Failed to read FRU Manufacturer, ret:%d", size);
return -EINVAL;
@@ -131,7 +141,7 @@ int amdgpu_fru_get_product_info(struct amdgpu_device *adev)
* size field being 1 byte. This pattern continues below.
*/
addrptr += size + 1;
- size = amdgpu_fru_read_eeprom(adev, addrptr, buff);
+ size = amdgpu_fru_read_eeprom(adev, addrptr, buf, sizeof(buf));
if (size < 1) {
DRM_ERROR("Failed to read FRU product name, ret:%d", size);
return -EINVAL;
@@ -143,12 +153,11 @@ int amdgpu_fru_get_product_info(struct amdgpu_device *adev)
AMDGPU_PRODUCT_NAME_LEN);
len = AMDGPU_PRODUCT_NAME_LEN - 1;
}
- /* Start at 2 due to buff using fields 0 and 1 for the address */
- memcpy(adev->product_name, &buff[offset], len);
+ memcpy(adev->product_name, buf, len);
adev->product_name[len] = '\0';
addrptr += size + 1;
- size = amdgpu_fru_read_eeprom(adev, addrptr, buff);
+ size = amdgpu_fru_read_eeprom(adev, addrptr, buf, sizeof(buf));
if (size < 1) {
DRM_ERROR("Failed to read FRU product number, ret:%d", size);
return -EINVAL;
@@ -162,11 +171,11 @@ int amdgpu_fru_get_product_info(struct amdgpu_device *adev)
DRM_WARN("FRU Product Number is larger than 16 characters. This is likely a mistake");
len = sizeof(adev->product_number) - 1;
}
- memcpy(adev->product_number, &buff[offset], len);
+ memcpy(adev->product_number, buf, len);
adev->product_number[len] = '\0';
addrptr += size + 1;
- size = amdgpu_fru_read_eeprom(adev, addrptr, buff);
+ size = amdgpu_fru_read_eeprom(adev, addrptr, buf, sizeof(buf));
if (size < 1) {
DRM_ERROR("Failed to read FRU product version, ret:%d", size);
@@ -174,7 +183,7 @@ int amdgpu_fru_get_product_info(struct amdgpu_device *adev)
}
addrptr += size + 1;
- size = amdgpu_fru_read_eeprom(adev, addrptr, buff);
+ size = amdgpu_fru_read_eeprom(adev, addrptr, buf, sizeof(buf));
if (size < 1) {
DRM_ERROR("Failed to read FRU serial number, ret:%d", size);
@@ -189,7 +198,7 @@ int amdgpu_fru_get_product_info(struct amdgpu_device *adev)
DRM_WARN("FRU Serial Number is larger than 16 characters. This is likely a mistake");
len = sizeof(adev->serial) - 1;
}
- memcpy(adev->serial, &buff[offset], len);
+ memcpy(adev->serial, buf, len);
adev->serial[len] = '\0';
return 0;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c
index 645950a653a0..01cb89ffbd56 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c
@@ -150,7 +150,7 @@ void amdgpu_gart_table_vram_free(struct amdgpu_device *adev)
* replaces them with the dummy page (all asics).
* Returns 0 for success, -EINVAL for failure.
*/
-int amdgpu_gart_unbind(struct amdgpu_device *adev, uint64_t offset,
+void amdgpu_gart_unbind(struct amdgpu_device *adev, uint64_t offset,
int pages)
{
unsigned t;
@@ -161,13 +161,11 @@ int amdgpu_gart_unbind(struct amdgpu_device *adev, uint64_t offset,
uint64_t flags = 0;
int idx;
- if (!adev->gart.ready) {
- WARN(1, "trying to unbind memory from uninitialized GART !\n");
- return -EINVAL;
- }
+ if (!adev->gart.ptr)
+ return;
if (!drm_dev_enter(adev_to_drm(adev), &idx))
- return 0;
+ return;
t = offset / AMDGPU_GPU_PAGE_SIZE;
p = t / AMDGPU_GPU_PAGES_IN_CPU_PAGE;
@@ -188,7 +186,6 @@ int amdgpu_gart_unbind(struct amdgpu_device *adev, uint64_t offset,
amdgpu_gmc_flush_gpu_tlb(adev, 0, i, 0);
drm_dev_exit(idx);
- return 0;
}
/**
@@ -204,7 +201,7 @@ int amdgpu_gart_unbind(struct amdgpu_device *adev, uint64_t offset,
* Map the dma_addresses into GART entries (all asics).
* Returns 0 for success, -EINVAL for failure.
*/
-int amdgpu_gart_map(struct amdgpu_device *adev, uint64_t offset,
+void amdgpu_gart_map(struct amdgpu_device *adev, uint64_t offset,
int pages, dma_addr_t *dma_addr, uint64_t flags,
void *dst)
{
@@ -212,13 +209,8 @@ int amdgpu_gart_map(struct amdgpu_device *adev, uint64_t offset,
unsigned i, j, t;
int idx;
- if (!adev->gart.ready) {
- WARN(1, "trying to bind memory to uninitialized GART !\n");
- return -EINVAL;
- }
-
if (!drm_dev_enter(adev_to_drm(adev), &idx))
- return 0;
+ return;
t = offset / AMDGPU_GPU_PAGE_SIZE;
@@ -230,7 +222,6 @@ int amdgpu_gart_map(struct amdgpu_device *adev, uint64_t offset,
}
}
drm_dev_exit(idx);
- return 0;
}
/**
@@ -246,20 +237,14 @@ int amdgpu_gart_map(struct amdgpu_device *adev, uint64_t offset,
* (all asics).
* Returns 0 for success, -EINVAL for failure.
*/
-int amdgpu_gart_bind(struct amdgpu_device *adev, uint64_t offset,
+void amdgpu_gart_bind(struct amdgpu_device *adev, uint64_t offset,
int pages, dma_addr_t *dma_addr,
uint64_t flags)
{
- if (!adev->gart.ready) {
- WARN(1, "trying to bind memory to uninitialized GART !\n");
- return -EINVAL;
- }
-
if (!adev->gart.ptr)
- return 0;
+ return;
- return amdgpu_gart_map(adev, offset, pages, dma_addr, flags,
- adev->gart.ptr);
+ amdgpu_gart_map(adev, offset, pages, dma_addr, flags, adev->gart.ptr);
}
/**
@@ -274,6 +259,9 @@ void amdgpu_gart_invalidate_tlb(struct amdgpu_device *adev)
{
int i;
+ if (!adev->gart.ptr)
+ return;
+
mb();
amdgpu_device_flush_hdp(adev, NULL);
for (i = 0; i < adev->num_vmhubs; i++)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.h
index 78895413cf9f..8fea3e04e411 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.h
@@ -46,7 +46,6 @@ struct amdgpu_gart {
unsigned num_gpu_pages;
unsigned num_cpu_pages;
unsigned table_size;
- bool ready;
/* Asic default pte flags */
uint64_t gart_pte_flags;
@@ -58,12 +57,12 @@ int amdgpu_gart_table_vram_pin(struct amdgpu_device *adev);
void amdgpu_gart_table_vram_unpin(struct amdgpu_device *adev);
int amdgpu_gart_init(struct amdgpu_device *adev);
void amdgpu_gart_dummy_page_fini(struct amdgpu_device *adev);
-int amdgpu_gart_unbind(struct amdgpu_device *adev, uint64_t offset,
- int pages);
-int amdgpu_gart_map(struct amdgpu_device *adev, uint64_t offset,
- int pages, dma_addr_t *dma_addr, uint64_t flags,
- void *dst);
-int amdgpu_gart_bind(struct amdgpu_device *adev, uint64_t offset,
- int pages, dma_addr_t *dma_addr, uint64_t flags);
+void amdgpu_gart_unbind(struct amdgpu_device *adev, uint64_t offset,
+ int pages);
+void amdgpu_gart_map(struct amdgpu_device *adev, uint64_t offset,
+ int pages, dma_addr_t *dma_addr, uint64_t flags,
+ void *dst);
+void amdgpu_gart_bind(struct amdgpu_device *adev, uint64_t offset,
+ int pages, dma_addr_t *dma_addr, uint64_t flags);
void amdgpu_gart_invalidate_tlb(struct amdgpu_device *adev);
#endif
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
index c0d8f40a5b45..57b74d35052f 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
@@ -222,16 +222,10 @@ static void amdgpu_gem_object_close(struct drm_gem_object *obj,
if (!bo_va || --bo_va->ref_count)
goto out_unlock;
- amdgpu_vm_bo_rmv(adev, bo_va);
+ amdgpu_vm_bo_del(adev, bo_va);
if (!amdgpu_vm_ready(vm))
goto out_unlock;
- fence = dma_resv_excl_fence(bo->tbo.base.resv);
- if (fence) {
- amdgpu_bo_fence(bo, fence, true);
- fence = NULL;
- }
-
r = amdgpu_vm_clear_freed(adev, vm, &fence);
if (r || !fence)
goto out_unlock;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c
index 1916ec84dd71..8fe939976224 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c
@@ -615,74 +615,35 @@ int amdgpu_get_gfx_off_status(struct amdgpu_device *adev, uint32_t *value)
mutex_lock(&adev->gfx.gfx_off_mutex);
- r = smu_get_status_gfxoff(adev, value);
+ r = amdgpu_dpm_get_status_gfxoff(adev, value);
mutex_unlock(&adev->gfx.gfx_off_mutex);
return r;
}
-int amdgpu_gfx_ras_late_init(struct amdgpu_device *adev)
+int amdgpu_gfx_ras_late_init(struct amdgpu_device *adev, struct ras_common_if *ras_block)
{
int r;
- struct ras_fs_if fs_info = {
- .sysfs_name = "gfx_err_count",
- };
- struct ras_ih_if ih_info = {
- .cb = amdgpu_gfx_process_ras_data_cb,
- };
-
- if (!adev->gfx.ras_if) {
- adev->gfx.ras_if = kmalloc(sizeof(struct ras_common_if), GFP_KERNEL);
- if (!adev->gfx.ras_if)
- return -ENOMEM;
- adev->gfx.ras_if->block = AMDGPU_RAS_BLOCK__GFX;
- adev->gfx.ras_if->type = AMDGPU_RAS_ERROR__MULTI_UNCORRECTABLE;
- adev->gfx.ras_if->sub_block_index = 0;
- }
- fs_info.head = ih_info.head = *adev->gfx.ras_if;
- r = amdgpu_ras_late_init(adev, adev->gfx.ras_if,
- &fs_info, &ih_info);
+ r = amdgpu_ras_block_late_init(adev, ras_block);
if (r)
- goto free;
+ return r;
- if (amdgpu_ras_is_supported(adev, adev->gfx.ras_if->block)) {
+ if (amdgpu_ras_is_supported(adev, ras_block->block)) {
if (!amdgpu_persistent_edc_harvesting_supported(adev))
amdgpu_ras_reset_error_status(adev, AMDGPU_RAS_BLOCK__GFX);
r = amdgpu_irq_get(adev, &adev->gfx.cp_ecc_error_irq, 0);
if (r)
goto late_fini;
- } else {
- /* free gfx ras_if if ras is not supported */
- r = 0;
- goto free;
}
return 0;
late_fini:
- amdgpu_ras_late_fini(adev, adev->gfx.ras_if, &ih_info);
-free:
- kfree(adev->gfx.ras_if);
- adev->gfx.ras_if = NULL;
+ amdgpu_ras_block_late_fini(adev, ras_block);
return r;
}
-void amdgpu_gfx_ras_fini(struct amdgpu_device *adev)
-{
- if (amdgpu_ras_is_supported(adev, AMDGPU_RAS_BLOCK__GFX) &&
- adev->gfx.ras_if) {
- struct ras_common_if *ras_if = adev->gfx.ras_if;
- struct ras_ih_if ih_info = {
- .head = *ras_if,
- .cb = amdgpu_gfx_process_ras_data_cb,
- };
-
- amdgpu_ras_late_fini(adev, ras_if, &ih_info);
- kfree(ras_if);
- }
-}
-
int amdgpu_gfx_process_ras_data_cb(struct amdgpu_device *adev,
void *err_data,
struct amdgpu_iv_entry *entry)
@@ -695,9 +656,9 @@ int amdgpu_gfx_process_ras_data_cb(struct amdgpu_device *adev,
*/
if (!amdgpu_ras_is_supported(adev, AMDGPU_RAS_BLOCK__GFX)) {
kgd2kfd_set_sram_ecc_flag(adev->kfd.dev);
- if (adev->gfx.ras_funcs &&
- adev->gfx.ras_funcs->query_ras_error_count)
- adev->gfx.ras_funcs->query_ras_error_count(adev, err_data);
+ if (adev->gfx.ras && adev->gfx.ras->ras_block.hw_ops &&
+ adev->gfx.ras->ras_block.hw_ops->query_ras_error_count)
+ adev->gfx.ras->ras_block.hw_ops->query_ras_error_count(adev, err_data);
amdgpu_ras_reset_gpu(adev);
}
return AMDGPU_RAS_SUCCESS;
@@ -852,19 +813,3 @@ int amdgpu_gfx_get_num_kcq(struct amdgpu_device *adev)
}
return amdgpu_num_kcq;
}
-
-/* amdgpu_gfx_state_change_set - Handle gfx power state change set
- * @adev: amdgpu_device pointer
- * @state: gfx power state(1 -sGpuChangeState_D0Entry and 2 -sGpuChangeState_D3Entry)
- *
- */
-
-void amdgpu_gfx_state_change_set(struct amdgpu_device *adev, enum gfx_change_state state)
-{
- mutex_lock(&adev->pm.mutex);
- if (adev->powerplay.pp_funcs &&
- adev->powerplay.pp_funcs->gfx_state_change_set)
- ((adev)->powerplay.pp_funcs->gfx_state_change_set(
- (adev)->powerplay.pp_handle, state));
- mutex_unlock(&adev->pm.mutex);
-}
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.h
index f851196c83a5..dcb3c7871c73 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.h
@@ -31,6 +31,7 @@
#include "amdgpu_ring.h"
#include "amdgpu_rlc.h"
#include "soc15.h"
+#include "amdgpu_ras.h"
/* GFX current status */
#define AMDGPU_GFX_NORMAL_MODE 0x00000000L
@@ -47,12 +48,6 @@ enum amdgpu_gfx_pipe_priority {
AMDGPU_GFX_PIPE_PRIO_HIGH = AMDGPU_RING_PRIO_2
};
-/* Argument for PPSMC_MSG_GpuChangeState */
-enum gfx_change_state {
- sGpuChangeState_D0Entry = 1,
- sGpuChangeState_D3Entry,
-};
-
#define AMDGPU_GFX_QUEUE_PRIORITY_MINIMUM 0
#define AMDGPU_GFX_QUEUE_PRIORITY_MAXIMUM 15
@@ -204,16 +199,8 @@ struct amdgpu_cu_info {
uint32_t bitmap[4][4];
};
-struct amdgpu_gfx_ras_funcs {
- int (*ras_late_init)(struct amdgpu_device *adev);
- void (*ras_fini)(struct amdgpu_device *adev);
- int (*ras_error_inject)(struct amdgpu_device *adev,
- void *inject_if);
- int (*query_ras_error_count)(struct amdgpu_device *adev,
- void *ras_error_status);
- void (*reset_ras_error_count)(struct amdgpu_device *adev);
- void (*query_ras_error_status)(struct amdgpu_device *adev);
- void (*reset_ras_error_status)(struct amdgpu_device *adev);
+struct amdgpu_gfx_ras {
+ struct amdgpu_ras_block_object ras_block;
void (*enable_watchdog_timer)(struct amdgpu_device *adev);
};
@@ -337,7 +324,7 @@ struct amdgpu_gfx {
/*ras */
struct ras_common_if *ras_if;
- const struct amdgpu_gfx_ras_funcs *ras_funcs;
+ struct amdgpu_gfx_ras *ras;
};
#define amdgpu_gfx_get_gpu_clock_counter(adev) (adev)->gfx.funcs->get_gpu_clock_counter((adev))
@@ -399,8 +386,7 @@ bool amdgpu_gfx_is_me_queue_enabled(struct amdgpu_device *adev, int me,
int pipe, int queue);
void amdgpu_gfx_off_ctrl(struct amdgpu_device *adev, bool enable);
int amdgpu_get_gfx_off_status(struct amdgpu_device *adev, uint32_t *value);
-int amdgpu_gfx_ras_late_init(struct amdgpu_device *adev);
-void amdgpu_gfx_ras_fini(struct amdgpu_device *adev);
+int amdgpu_gfx_ras_late_init(struct amdgpu_device *adev, struct ras_common_if *ras_block);
int amdgpu_gfx_process_ras_data_cb(struct amdgpu_device *adev,
void *err_data,
struct amdgpu_iv_entry *entry);
@@ -410,5 +396,4 @@ int amdgpu_gfx_cp_ecc_error_irq(struct amdgpu_device *adev,
uint32_t amdgpu_kiq_rreg(struct amdgpu_device *adev, uint32_t reg);
void amdgpu_kiq_wreg(struct amdgpu_device *adev, uint32_t reg, uint32_t v);
int amdgpu_gfx_get_num_kcq(struct amdgpu_device *adev);
-void amdgpu_gfx_state_change_set(struct amdgpu_device *adev, enum gfx_change_state state);
#endif
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
index 2430d6223c2d..ca2cfb65f976 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
@@ -436,82 +436,25 @@ void amdgpu_gmc_filter_faults_remove(struct amdgpu_device *adev, uint64_t addr,
} while (fault->timestamp < tmp);
}
-int amdgpu_gmc_ras_late_init(struct amdgpu_device *adev)
+int amdgpu_gmc_ras_early_init(struct amdgpu_device *adev)
{
- int r;
-
- if (adev->umc.ras_funcs &&
- adev->umc.ras_funcs->ras_late_init) {
- r = adev->umc.ras_funcs->ras_late_init(adev);
- if (r)
- return r;
- }
-
- if (adev->mmhub.ras_funcs &&
- adev->mmhub.ras_funcs->ras_late_init) {
- r = adev->mmhub.ras_funcs->ras_late_init(adev);
- if (r)
- return r;
- }
-
- if (!adev->gmc.xgmi.connected_to_cpu)
- adev->gmc.xgmi.ras_funcs = &xgmi_ras_funcs;
-
- if (adev->gmc.xgmi.ras_funcs &&
- adev->gmc.xgmi.ras_funcs->ras_late_init) {
- r = adev->gmc.xgmi.ras_funcs->ras_late_init(adev);
- if (r)
- return r;
+ if (!adev->gmc.xgmi.connected_to_cpu) {
+ adev->gmc.xgmi.ras = &xgmi_ras;
+ amdgpu_ras_register_ras_block(adev, &adev->gmc.xgmi.ras->ras_block);
+ adev->gmc.xgmi.ras_if = &adev->gmc.xgmi.ras->ras_block.ras_comm;
}
- if (adev->hdp.ras_funcs &&
- adev->hdp.ras_funcs->ras_late_init) {
- r = adev->hdp.ras_funcs->ras_late_init(adev);
- if (r)
- return r;
- }
-
- if (adev->mca.mp0.ras_funcs &&
- adev->mca.mp0.ras_funcs->ras_late_init) {
- r = adev->mca.mp0.ras_funcs->ras_late_init(adev);
- if (r)
- return r;
- }
-
- if (adev->mca.mp1.ras_funcs &&
- adev->mca.mp1.ras_funcs->ras_late_init) {
- r = adev->mca.mp1.ras_funcs->ras_late_init(adev);
- if (r)
- return r;
- }
-
- if (adev->mca.mpio.ras_funcs &&
- adev->mca.mpio.ras_funcs->ras_late_init) {
- r = adev->mca.mpio.ras_funcs->ras_late_init(adev);
- if (r)
- return r;
- }
+ return 0;
+}
+int amdgpu_gmc_ras_late_init(struct amdgpu_device *adev)
+{
return 0;
}
void amdgpu_gmc_ras_fini(struct amdgpu_device *adev)
{
- if (adev->umc.ras_funcs &&
- adev->umc.ras_funcs->ras_fini)
- adev->umc.ras_funcs->ras_fini(adev);
- if (adev->mmhub.ras_funcs &&
- adev->mmhub.ras_funcs->ras_fini)
- adev->mmhub.ras_funcs->ras_fini(adev);
-
- if (adev->gmc.xgmi.ras_funcs &&
- adev->gmc.xgmi.ras_funcs->ras_fini)
- adev->gmc.xgmi.ras_funcs->ras_fini(adev);
-
- if (adev->hdp.ras_funcs &&
- adev->hdp.ras_funcs->ras_fini)
- adev->hdp.ras_funcs->ras_fini(adev);
}
/*
@@ -584,6 +527,7 @@ void amdgpu_gmc_tmz_set(struct amdgpu_device *adev)
case CHIP_NAVI12:
case CHIP_VANGOGH:
case CHIP_YELLOW_CARP:
+ case CHIP_IP_DISCOVERY:
/* Don't enable it by default yet.
*/
if (amdgpu_tmz < 1) {
@@ -615,11 +559,11 @@ void amdgpu_gmc_noretry_set(struct amdgpu_device *adev)
{
struct amdgpu_gmc *gmc = &adev->gmc;
- switch (adev->asic_type) {
- case CHIP_VEGA10:
- case CHIP_VEGA20:
- case CHIP_ARCTURUS:
- case CHIP_ALDEBARAN:
+ switch (adev->ip_versions[GC_HWIP][0]) {
+ case IP_VERSION(9, 0, 1):
+ case IP_VERSION(9, 4, 0):
+ case IP_VERSION(9, 4, 1):
+ case IP_VERSION(9, 4, 2):
/*
* noretry = 0 will cause kfd page fault tests fail
* for some ASICs, so set default to 1 for these ASICs.
@@ -629,7 +573,6 @@ void amdgpu_gmc_noretry_set(struct amdgpu_device *adev)
else
gmc->noretry = amdgpu_noretry;
break;
- case CHIP_RAVEN:
default:
/* Raven currently has issues with noretry
* regardless of what we decide for other
@@ -680,6 +623,13 @@ void amdgpu_gmc_get_vbios_allocations(struct amdgpu_device *adev)
unsigned size;
/*
+ * Some ASICs need to reserve a region of video memory to avoid access
+ * from driver
+ */
+ adev->mman.stolen_reserved_offset = 0;
+ adev->mman.stolen_reserved_size = 0;
+
+ /*
* TODO:
* Currently there is a bug where some memory client outside
* of the driver writes to first 8M of VRAM on S3 resume,
@@ -689,10 +639,25 @@ void amdgpu_gmc_get_vbios_allocations(struct amdgpu_device *adev)
*/
switch (adev->asic_type) {
case CHIP_VEGA10:
+ adev->mman.keep_stolen_vga_memory = true;
+ /*
+ * VEGA10 SRIOV VF needs some firmware reserved area.
+ */
+ if (amdgpu_sriov_vf(adev)) {
+ adev->mman.stolen_reserved_offset = 0x100000;
+ adev->mman.stolen_reserved_size = 0x600000;
+ }
+ break;
case CHIP_RAVEN:
case CHIP_RENOIR:
adev->mman.keep_stolen_vga_memory = true;
break;
+ case CHIP_YELLOW_CARP:
+ if (amdgpu_discovery == 0) {
+ adev->mman.stolen_reserved_offset = 0x1ffb0000;
+ adev->mman.stolen_reserved_size = 64 * PAGE_SIZE;
+ }
+ break;
default:
adev->mman.keep_stolen_vga_memory = false;
break;
@@ -813,21 +778,48 @@ uint64_t amdgpu_gmc_vram_cpu_pa(struct amdgpu_device *adev, struct amdgpu_bo *bo
return amdgpu_bo_gpu_offset(bo) - adev->gmc.vram_start + adev->gmc.aper_base;
}
-void amdgpu_gmc_get_reserved_allocation(struct amdgpu_device *adev)
+int amdgpu_gmc_vram_checking(struct amdgpu_device *adev)
{
- /* Some ASICs need to reserve a region of video memory to avoid access
- * from driver */
- adev->mman.stolen_reserved_offset = 0;
- adev->mman.stolen_reserved_size = 0;
+ struct amdgpu_bo *vram_bo = NULL;
+ uint64_t vram_gpu = 0;
+ void *vram_ptr = NULL;
+
+ int ret, size = 0x100000;
+ uint8_t cptr[10];
+
+ ret = amdgpu_bo_create_kernel(adev, size, PAGE_SIZE,
+ AMDGPU_GEM_DOMAIN_VRAM,
+ &vram_bo,
+ &vram_gpu,
+ &vram_ptr);
+ if (ret)
+ return ret;
+
+ memset(vram_ptr, 0x86, size);
+ memset(cptr, 0x86, 10);
+
+ /**
+ * Check the start, the mid, and the end of the memory if the content of
+ * each byte is the pattern "0x86". If yes, we suppose the vram bo is
+ * workable.
+ *
+ * Note: If check the each byte of whole 1M bo, it will cost too many
+ * seconds, so here, we just pick up three parts for emulation.
+ */
+ ret = memcmp(vram_ptr, cptr, 10);
+ if (ret)
+ return ret;
- switch (adev->asic_type) {
- case CHIP_YELLOW_CARP:
- if (amdgpu_discovery == 0) {
- adev->mman.stolen_reserved_offset = 0x1ffb0000;
- adev->mman.stolen_reserved_size = 64 * PAGE_SIZE;
- }
- break;
- default:
- break;
- }
+ ret = memcmp(vram_ptr + (size / 2), cptr, 10);
+ if (ret)
+ return ret;
+
+ ret = memcmp(vram_ptr + size - 10, cptr, 10);
+ if (ret)
+ return ret;
+
+ amdgpu_bo_free_kernel(&vram_bo, &vram_gpu,
+ &vram_ptr);
+
+ return 0;
}
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h
index 8458cebc6d5b..032b0313f277 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h
@@ -29,6 +29,7 @@
#include <linux/types.h>
#include "amdgpu_irq.h"
+#include "amdgpu_ras.h"
/* VA hole for 48bit addresses on Vega10 */
#define AMDGPU_GMC_HOLE_START 0x0000800000000000ULL
@@ -135,12 +136,8 @@ struct amdgpu_gmc_funcs {
unsigned int (*get_vbios_fb_size)(struct amdgpu_device *adev);
};
-struct amdgpu_xgmi_ras_funcs {
- int (*ras_late_init)(struct amdgpu_device *adev);
- void (*ras_fini)(struct amdgpu_device *adev);
- int (*query_ras_error_count)(struct amdgpu_device *adev,
- void *ras_error_status);
- void (*reset_ras_error_count)(struct amdgpu_device *adev);
+struct amdgpu_xgmi_ras {
+ struct amdgpu_ras_block_object ras_block;
};
struct amdgpu_xgmi {
@@ -159,7 +156,7 @@ struct amdgpu_xgmi {
struct ras_common_if *ras_if;
bool connected_to_cpu;
bool pending_reset;
- const struct amdgpu_xgmi_ras_funcs *ras_funcs;
+ struct amdgpu_xgmi_ras *ras;
};
struct amdgpu_gmc {
@@ -321,6 +318,7 @@ bool amdgpu_gmc_filter_faults(struct amdgpu_device *adev,
uint16_t pasid, uint64_t timestamp);
void amdgpu_gmc_filter_faults_remove(struct amdgpu_device *adev, uint64_t addr,
uint16_t pasid);
+int amdgpu_gmc_ras_early_init(struct amdgpu_device *adev);
int amdgpu_gmc_ras_late_init(struct amdgpu_device *adev);
void amdgpu_gmc_ras_fini(struct amdgpu_device *adev);
int amdgpu_gmc_allocate_vm_inv_eng(struct amdgpu_device *adev);
@@ -333,10 +331,10 @@ amdgpu_gmc_set_vm_fault_masks(struct amdgpu_device *adev, int hub_type,
bool enable);
void amdgpu_gmc_get_vbios_allocations(struct amdgpu_device *adev);
-void amdgpu_gmc_get_reserved_allocation(struct amdgpu_device *adev);
void amdgpu_gmc_init_pdb0(struct amdgpu_device *adev);
uint64_t amdgpu_gmc_vram_mc2pa(struct amdgpu_device *adev, uint64_t mc_addr);
uint64_t amdgpu_gmc_vram_pa(struct amdgpu_device *adev, struct amdgpu_bo *bo);
uint64_t amdgpu_gmc_vram_cpu_pa(struct amdgpu_device *adev, struct amdgpu_bo *bo);
+int amdgpu_gmc_vram_checking(struct amdgpu_device *adev);
#endif
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gtt_mgr.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gtt_mgr.c
index 72022df264f6..dd78402e3cb0 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gtt_mgr.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gtt_mgr.c
@@ -60,7 +60,7 @@ static ssize_t amdgpu_mem_info_gtt_total_show(struct device *dev,
struct ttm_resource_manager *man;
man = ttm_manager_type(&adev->mman.bdev, TTM_PL_TT);
- return sysfs_emit(buf, "%llu\n", man->size * PAGE_SIZE);
+ return sysfs_emit(buf, "%llu\n", man->size);
}
/**
@@ -77,8 +77,9 @@ static ssize_t amdgpu_mem_info_gtt_used_show(struct device *dev,
{
struct drm_device *ddev = dev_get_drvdata(dev);
struct amdgpu_device *adev = drm_to_adev(ddev);
+ struct ttm_resource_manager *man = &adev->mman.gtt_mgr.manager;
- return sysfs_emit(buf, "%llu\n", amdgpu_gtt_mgr_usage(&adev->mman.gtt_mgr));
+ return sysfs_emit(buf, "%llu\n", ttm_resource_manager_usage(man));
}
static DEVICE_ATTR(mem_info_gtt_total, S_IRUGO,
@@ -130,20 +131,17 @@ static int amdgpu_gtt_mgr_new(struct ttm_resource_manager *man,
struct amdgpu_gtt_node *node;
int r;
- if (!(place->flags & TTM_PL_FLAG_TEMPORARY) &&
- atomic64_add_return(num_pages, &mgr->used) > man->size) {
- atomic64_sub(num_pages, &mgr->used);
- return -ENOSPC;
- }
-
node = kzalloc(struct_size(node, base.mm_nodes, 1), GFP_KERNEL);
- if (!node) {
- r = -ENOMEM;
- goto err_out;
- }
+ if (!node)
+ return -ENOMEM;
node->tbo = tbo;
ttm_resource_init(tbo, place, &node->base.base);
+ if (!(place->flags & TTM_PL_FLAG_TEMPORARY) &&
+ ttm_resource_manager_usage(man) > man->size) {
+ r = -ENOSPC;
+ goto err_free;
+ }
if (place->lpfn) {
spin_lock(&mgr->lock);
@@ -167,12 +165,8 @@ static int amdgpu_gtt_mgr_new(struct ttm_resource_manager *man,
return 0;
err_free:
+ ttm_resource_fini(man, &node->base.base);
kfree(node);
-
-err_out:
- if (!(place->flags & TTM_PL_FLAG_TEMPORARY))
- atomic64_sub(num_pages, &mgr->used);
-
return r;
}
@@ -195,51 +189,32 @@ static void amdgpu_gtt_mgr_del(struct ttm_resource_manager *man,
drm_mm_remove_node(&node->base.mm_nodes[0]);
spin_unlock(&mgr->lock);
- if (!(res->placement & TTM_PL_FLAG_TEMPORARY))
- atomic64_sub(res->num_pages, &mgr->used);
-
+ ttm_resource_fini(man, res);
kfree(node);
}
/**
- * amdgpu_gtt_mgr_usage - return usage of GTT domain
- *
- * @mgr: amdgpu_gtt_mgr pointer
- *
- * Return how many bytes are used in the GTT domain
- */
-uint64_t amdgpu_gtt_mgr_usage(struct amdgpu_gtt_mgr *mgr)
-{
- return atomic64_read(&mgr->used) * PAGE_SIZE;
-}
-
-/**
* amdgpu_gtt_mgr_recover - re-init gart
*
* @mgr: amdgpu_gtt_mgr pointer
*
* Re-init the gart for each known BO in the GTT.
*/
-int amdgpu_gtt_mgr_recover(struct amdgpu_gtt_mgr *mgr)
+void amdgpu_gtt_mgr_recover(struct amdgpu_gtt_mgr *mgr)
{
struct amdgpu_gtt_node *node;
struct drm_mm_node *mm_node;
struct amdgpu_device *adev;
- int r = 0;
adev = container_of(mgr, typeof(*adev), mman.gtt_mgr);
spin_lock(&mgr->lock);
drm_mm_for_each_node(mm_node, &mgr->mm) {
node = container_of(mm_node, typeof(*node), base.mm_nodes[0]);
- r = amdgpu_ttm_recover_gart(node->tbo);
- if (r)
- break;
+ amdgpu_ttm_recover_gart(node->tbo);
}
spin_unlock(&mgr->lock);
amdgpu_gart_invalidate_tlb(adev);
-
- return r;
}
/**
@@ -258,9 +233,6 @@ static void amdgpu_gtt_mgr_debug(struct ttm_resource_manager *man,
spin_lock(&mgr->lock);
drm_mm_print(&mgr->mm, printer);
spin_unlock(&mgr->lock);
-
- drm_printf(printer, "man size:%llu pages, gtt used:%llu pages\n",
- man->size, atomic64_read(&mgr->used));
}
static const struct ttm_resource_manager_func amdgpu_gtt_mgr_func = {
@@ -286,13 +258,12 @@ int amdgpu_gtt_mgr_init(struct amdgpu_device *adev, uint64_t gtt_size)
man->use_tt = true;
man->func = &amdgpu_gtt_mgr_func;
- ttm_resource_manager_init(man, gtt_size >> PAGE_SHIFT);
+ ttm_resource_manager_init(man, &adev->mman.bdev, gtt_size);
start = AMDGPU_GTT_MAX_TRANSFER_SIZE * AMDGPU_GTT_NUM_TRANSFER_WINDOWS;
size = (adev->gmc.gart_size >> PAGE_SHIFT) - start;
drm_mm_init(&mgr->mm, start, size);
spin_lock_init(&mgr->lock);
- atomic64_set(&mgr->used, 0);
ttm_set_driver_manager(&adev->mman.bdev, TTM_PL_TT, &mgr->manager);
ttm_resource_manager_set_used(man, true);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_hdp.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_hdp.h
index 7ec99d591584..9181c7bef7c6 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_hdp.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_hdp.h
@@ -22,13 +22,10 @@
*/
#ifndef __AMDGPU_HDP_H__
#define __AMDGPU_HDP_H__
+#include "amdgpu_ras.h"
-struct amdgpu_hdp_ras_funcs {
- int (*ras_late_init)(struct amdgpu_device *adev);
- void (*ras_fini)(struct amdgpu_device *adev);
- void (*query_ras_error_count)(struct amdgpu_device *adev,
- void *ras_error_status);
- void (*reset_ras_error_count)(struct amdgpu_device *adev);
+struct amdgpu_hdp_ras {
+ struct amdgpu_ras_block_object ras_block;
};
struct amdgpu_hdp_funcs {
@@ -43,9 +40,8 @@ struct amdgpu_hdp_funcs {
struct amdgpu_hdp {
struct ras_common_if *ras_if;
const struct amdgpu_hdp_funcs *funcs;
- const struct amdgpu_hdp_ras_funcs *ras_funcs;
+ struct amdgpu_hdp_ras *ras;
};
-int amdgpu_hdp_ras_late_init(struct amdgpu_device *adev);
-void amdgpu_hdp_ras_fini(struct amdgpu_device *adev);
+int amdgpu_hdp_ras_late_init(struct amdgpu_device *adev, struct ras_common_if *ras_block);
#endif /* __AMDGPU_HDP_H__ */
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c
index bc1297dcdf97..d583766ea392 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c
@@ -166,8 +166,8 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs,
}
if ((ib->flags & AMDGPU_IB_FLAGS_SECURE) &&
- (ring->funcs->type == AMDGPU_RING_TYPE_COMPUTE)) {
- dev_err(adev->dev, "secure submissions not supported on compute rings\n");
+ (!ring->funcs->secure_submission_supported)) {
+ dev_err(adev->dev, "secure submissions not supported on ring <%s>\n", ring->name);
return -EINVAL;
}
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ids.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ids.c
index b7fb72bff2c1..92a70fb57fa3 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ids.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ids.c
@@ -112,7 +112,7 @@ void amdgpu_pasid_free_delayed(struct dma_resv *resv,
unsigned count;
int r;
- r = dma_resv_get_fences(resv, NULL, &count, &fences);
+ r = dma_resv_get_fences(resv, true, &count, &fences);
if (r)
goto fallback;
@@ -204,7 +204,7 @@ static int amdgpu_vmid_grab_idle(struct amdgpu_vm *vm,
unsigned i;
int r;
- if (ring->vmid_wait && !dma_fence_is_signaled(ring->vmid_wait))
+ if (!dma_fence_is_signaled(ring->vmid_wait))
return amdgpu_sync_fence(sync, ring->vmid_wait);
fences = kmalloc_array(id_mgr->num_ids, sizeof(void *), GFP_KERNEL);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c
index f5cbc2747ac6..ea3e8c66211f 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c
@@ -199,13 +199,13 @@ static irqreturn_t amdgpu_irq_handler(int irq, void *arg)
* ack the interrupt if it is there
*/
if (amdgpu_ras_is_supported(adev, AMDGPU_RAS_BLOCK__PCIE_BIF)) {
- if (adev->nbio.ras_funcs &&
- adev->nbio.ras_funcs->handle_ras_controller_intr_no_bifring)
- adev->nbio.ras_funcs->handle_ras_controller_intr_no_bifring(adev);
+ if (adev->nbio.ras &&
+ adev->nbio.ras->handle_ras_controller_intr_no_bifring)
+ adev->nbio.ras->handle_ras_controller_intr_no_bifring(adev);
- if (adev->nbio.ras_funcs &&
- adev->nbio.ras_funcs->handle_ras_err_event_athub_intr_no_bifring)
- adev->nbio.ras_funcs->handle_ras_err_event_athub_intr_no_bifring(adev);
+ if (adev->nbio.ras &&
+ adev->nbio.ras->handle_ras_err_event_athub_intr_no_bifring)
+ adev->nbio.ras->handle_ras_err_event_athub_intr_no_bifring(adev);
}
return ret;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c
index bfc47bea23db..67f66f2f1809 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c
@@ -37,6 +37,7 @@ static enum drm_gpu_sched_stat amdgpu_job_timedout(struct drm_sched_job *s_job)
struct amdgpu_task_info ti;
struct amdgpu_device *adev = ring->adev;
int idx;
+ int r;
if (!drm_dev_enter(adev_to_drm(adev), &idx)) {
DRM_INFO("%s - device unplugged skipping recovery on scheduler:%s",
@@ -63,7 +64,9 @@ static enum drm_gpu_sched_stat amdgpu_job_timedout(struct drm_sched_job *s_job)
ti.process_name, ti.tgid, ti.task_name, ti.pid);
if (amdgpu_device_should_recover_gpu(ring->adev)) {
- amdgpu_device_gpu_recover(ring->adev, job);
+ r = amdgpu_device_gpu_recover_imp(ring->adev, job);
+ if (r)
+ DRM_ERROR("GPU Recovery Failed: %d\n", r);
} else {
drm_sched_suspend_timeout(&ring->sched);
if (amdgpu_sriov_vf(adev))
@@ -78,14 +81,10 @@ exit:
int amdgpu_job_alloc(struct amdgpu_device *adev, unsigned num_ibs,
struct amdgpu_job **job, struct amdgpu_vm *vm)
{
- size_t size = sizeof(struct amdgpu_job);
-
if (num_ibs == 0)
return -EINVAL;
- size += sizeof(struct amdgpu_ib) * num_ibs;
-
- *job = kzalloc(size, GFP_KERNEL);
+ *job = kzalloc(struct_size(*job, ibs, num_ibs), GFP_KERNEL);
if (!*job)
return -ENOMEM;
@@ -95,7 +94,6 @@ int amdgpu_job_alloc(struct amdgpu_device *adev, unsigned num_ibs,
*/
(*job)->base.sched = &adev->rings[0]->sched;
(*job)->vm = vm;
- (*job)->ibs = (void *)&(*job)[1];
(*job)->num_ibs = num_ibs;
amdgpu_sync_create(&(*job)->sync);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.h
index 9e65730193b8..d599c0540b46 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.h
@@ -23,6 +23,10 @@
#ifndef __AMDGPU_JOB_H__
#define __AMDGPU_JOB_H__
+#include <drm/gpu_scheduler.h>
+#include "amdgpu_sync.h"
+#include "amdgpu_ring.h"
+
/* bit set means command submit involves a preamble IB */
#define AMDGPU_PREAMBLE_IB_PRESENT (1 << 0)
/* bit set means preamble IB is first presented in belonging context */
@@ -45,12 +49,10 @@ struct amdgpu_job {
struct amdgpu_vm *vm;
struct amdgpu_sync sync;
struct amdgpu_sync sched_sync;
- struct amdgpu_ib *ibs;
struct dma_fence hw_fence;
struct dma_fence *external_hw_fence;
uint32_t preamble_status;
uint32_t preemption_status;
- uint32_t num_ibs;
bool vm_needs_flush;
uint64_t vm_pd_addr;
unsigned vmid;
@@ -66,6 +68,9 @@ struct amdgpu_job {
/* job_run_counter >= 1 means a resubmit job */
uint32_t job_run_counter;
+
+ uint32_t num_ibs;
+ struct amdgpu_ib ibs[];
};
int amdgpu_job_alloc(struct amdgpu_device *adev, unsigned num_ibs,
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
index 1ebb91db2274..6b626c293e72 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
@@ -87,11 +87,6 @@ void amdgpu_driver_unload_kms(struct drm_device *dev)
if (adev->rmmio == NULL)
return;
- if (adev->runpm) {
- pm_runtime_get_sync(dev->dev);
- pm_runtime_forbid(dev->dev);
- }
-
if (amdgpu_acpi_smart_shift_update(dev, AMDGPU_SS_DRV_UNLOAD))
DRM_WARN("smart shift update failed\n");
@@ -124,22 +119,6 @@ void amdgpu_register_gpu_instance(struct amdgpu_device *adev)
mutex_unlock(&mgpu_info.mutex);
}
-static void amdgpu_get_audio_func(struct amdgpu_device *adev)
-{
- struct pci_dev *p = NULL;
-
- p = pci_get_domain_bus_and_slot(pci_domain_nr(adev->pdev->bus),
- adev->pdev->bus->number, 1);
- if (p) {
- pm_runtime_get_sync(&p->dev);
-
- pm_runtime_mark_last_busy(&p->dev);
- pm_runtime_put_autosuspend(&p->dev);
-
- pci_dev_put(p);
- }
-}
-
/**
* amdgpu_driver_load_kms - Main load function for KMS.
*
@@ -152,21 +131,10 @@ static void amdgpu_get_audio_func(struct amdgpu_device *adev)
int amdgpu_driver_load_kms(struct amdgpu_device *adev, unsigned long flags)
{
struct drm_device *dev;
- struct pci_dev *parent;
int r, acpi_status;
dev = adev_to_drm(adev);
- if (amdgpu_has_atpx() &&
- (amdgpu_is_atpx_hybrid() ||
- amdgpu_has_atpx_dgpu_power_cntl()) &&
- ((flags & AMD_IS_APU) == 0) &&
- !pci_is_thunderbolt_attached(to_pci_dev(dev->dev)))
- flags |= AMD_IS_PX;
-
- parent = pci_upstream_bridge(adev->pdev);
- adev->has_pr3 = parent ? pci_pr3_present(parent) : false;
-
/* amdgpu_device_init should report only fatal error
* like memory allocation failure or iomapping failure,
* or memory manager initialization failure, it must
@@ -224,58 +192,12 @@ int amdgpu_driver_load_kms(struct amdgpu_device *adev, unsigned long flags)
if (acpi_status)
dev_dbg(dev->dev, "Error during ACPI methods call\n");
- if (adev->runpm) {
- /* only need to skip on ATPX */
- if (amdgpu_device_supports_px(dev))
- dev_pm_set_driver_flags(dev->dev, DPM_FLAG_NO_DIRECT_COMPLETE);
- /* we want direct complete for BOCO */
- if (amdgpu_device_supports_boco(dev))
- dev_pm_set_driver_flags(dev->dev, DPM_FLAG_SMART_PREPARE |
- DPM_FLAG_SMART_SUSPEND |
- DPM_FLAG_MAY_SKIP_RESUME);
- pm_runtime_use_autosuspend(dev->dev);
- pm_runtime_set_autosuspend_delay(dev->dev, 5000);
-
- pm_runtime_allow(dev->dev);
-
- pm_runtime_mark_last_busy(dev->dev);
- pm_runtime_put_autosuspend(dev->dev);
-
- /*
- * For runpm implemented via BACO, PMFW will handle the
- * timing for BACO in and out:
- * - put ASIC into BACO state only when both video and
- * audio functions are in D3 state.
- * - pull ASIC out of BACO state when either video or
- * audio function is in D0 state.
- * Also, at startup, PMFW assumes both functions are in
- * D0 state.
- *
- * So if snd driver was loaded prior to amdgpu driver
- * and audio function was put into D3 state, there will
- * be no PMFW-aware D-state transition(D0->D3) on runpm
- * suspend. Thus the BACO will be not correctly kicked in.
- *
- * Via amdgpu_get_audio_func(), the audio dev is put
- * into D0 state. Then there will be a PMFW-aware D-state
- * transition(D0->D3) on runpm suspend.
- */
- if (amdgpu_device_supports_baco(dev) &&
- !(adev->flags & AMD_IS_APU) &&
- (adev->asic_type >= CHIP_NAVI10))
- amdgpu_get_audio_func(adev);
- }
-
if (amdgpu_acpi_smart_shift_update(dev, AMDGPU_SS_DRV_LOAD))
DRM_WARN("smart shift update failed\n");
out:
- if (r) {
- /* balance pm_runtime_get_sync in amdgpu_driver_unload_kms */
- if (adev->rmmio && adev->runpm)
- pm_runtime_put_noidle(dev->dev);
+ if (r)
amdgpu_driver_unload_kms(dev);
- }
return r;
}
@@ -406,6 +328,10 @@ static int amdgpu_firmware_info(struct drm_amdgpu_info_firmware *fw_info,
fw_info->ver = adev->psp.toc.fw_version;
fw_info->feature = adev->psp.toc.feature_version;
break;
+ case AMDGPU_INFO_FW_CAP:
+ fw_info->ver = adev->psp.cap_fw_version;
+ fw_info->feature = adev->psp.cap_feature_version;
+ break;
default:
return -EINVAL;
}
@@ -678,13 +604,13 @@ int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
ui64 = atomic64_read(&adev->num_vram_cpu_page_faults);
return copy_to_user(out, &ui64, min(size, 8u)) ? -EFAULT : 0;
case AMDGPU_INFO_VRAM_USAGE:
- ui64 = amdgpu_vram_mgr_usage(&adev->mman.vram_mgr);
+ ui64 = ttm_resource_manager_usage(&adev->mman.vram_mgr.manager);
return copy_to_user(out, &ui64, min(size, 8u)) ? -EFAULT : 0;
case AMDGPU_INFO_VIS_VRAM_USAGE:
ui64 = amdgpu_vram_mgr_vis_usage(&adev->mman.vram_mgr);
return copy_to_user(out, &ui64, min(size, 8u)) ? -EFAULT : 0;
case AMDGPU_INFO_GTT_USAGE:
- ui64 = amdgpu_gtt_mgr_usage(&adev->mman.gtt_mgr);
+ ui64 = ttm_resource_manager_usage(&adev->mman.gtt_mgr.manager);
return copy_to_user(out, &ui64, min(size, 8u)) ? -EFAULT : 0;
case AMDGPU_INFO_GDS_CONFIG: {
struct drm_amdgpu_info_gds gds_info;
@@ -716,14 +642,17 @@ int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
case AMDGPU_INFO_MEMORY: {
struct drm_amdgpu_memory_info mem;
struct ttm_resource_manager *gtt_man =
- ttm_manager_type(&adev->mman.bdev, TTM_PL_TT);
+ &adev->mman.gtt_mgr.manager;
+ struct ttm_resource_manager *vram_man =
+ &adev->mman.vram_mgr.manager;
+
memset(&mem, 0, sizeof(mem));
mem.vram.total_heap_size = adev->gmc.real_vram_size;
mem.vram.usable_heap_size = adev->gmc.real_vram_size -
atomic64_read(&adev->vram_pin_size) -
AMDGPU_VM_RESERVED_VRAM;
mem.vram.heap_usage =
- amdgpu_vram_mgr_usage(&adev->mman.vram_mgr);
+ ttm_resource_manager_usage(vram_man);
mem.vram.max_allocation = mem.vram.usable_heap_size * 3 / 4;
mem.cpu_accessible_vram.total_heap_size =
@@ -741,8 +670,7 @@ int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
mem.gtt.total_heap_size *= PAGE_SIZE;
mem.gtt.usable_heap_size = mem.gtt.total_heap_size -
atomic64_read(&adev->gart_pin_size);
- mem.gtt.heap_usage =
- amdgpu_gtt_mgr_usage(&adev->mman.gtt_mgr);
+ mem.gtt.heap_usage = ttm_resource_manager_usage(gtt_man);
mem.gtt.max_allocation = mem.gtt.usable_heap_size * 3 / 4;
return copy_to_user(out, &mem,
@@ -1268,18 +1196,20 @@ void amdgpu_driver_postclose_kms(struct drm_device *dev,
if (amdgpu_device_ip_get_ip_block(adev, AMD_IP_BLOCK_TYPE_VCE) != NULL)
amdgpu_vce_free_handles(adev, file_priv);
- amdgpu_vm_bo_rmv(adev, fpriv->prt_va);
-
if (amdgpu_mcbp || amdgpu_sriov_vf(adev)) {
/* TODO: how to handle reserve failure */
BUG_ON(amdgpu_bo_reserve(adev->virt.csa_obj, true));
- amdgpu_vm_bo_rmv(adev, fpriv->csa_va);
+ amdgpu_vm_bo_del(adev, fpriv->csa_va);
fpriv->csa_va = NULL;
amdgpu_bo_unreserve(adev->virt.csa_obj);
}
pasid = fpriv->vm.pasid;
pd = amdgpu_bo_ref(fpriv->vm.root.bo);
+ if (!WARN_ON(amdgpu_bo_reserve(pd, true))) {
+ amdgpu_vm_bo_del(adev, fpriv->prt_va);
+ amdgpu_bo_unreserve(pd);
+ }
amdgpu_ctx_mgr_fini(&fpriv->ctx_mgr);
amdgpu_vm_fini(adev, &fpriv->vm);
@@ -1427,8 +1357,7 @@ static int amdgpu_debugfs_firmware_info_show(struct seq_file *m, void *unused)
struct drm_amdgpu_info_firmware fw_info;
struct drm_amdgpu_query_fw query_fw;
struct atom_context *ctx = adev->mode_info.atom_context;
- uint8_t smu_minor, smu_debug;
- uint16_t smu_major;
+ uint8_t smu_program, smu_major, smu_minor, smu_debug;
int ret, i;
static const char *ta_fw_name[TA_FW_TYPE_MAX_INDEX] = {
@@ -1574,11 +1503,12 @@ static int amdgpu_debugfs_firmware_info_show(struct seq_file *m, void *unused)
ret = amdgpu_firmware_info(&fw_info, &query_fw, adev);
if (ret)
return ret;
- smu_major = (fw_info.ver >> 16) & 0xffff;
+ smu_program = (fw_info.ver >> 24) & 0xff;
+ smu_major = (fw_info.ver >> 16) & 0xff;
smu_minor = (fw_info.ver >> 8) & 0xff;
smu_debug = (fw_info.ver >> 0) & 0xff;
- seq_printf(m, "SMC feature version: %u, firmware version: 0x%08x (%d.%d.%d)\n",
- fw_info.feature, fw_info.ver, smu_major, smu_minor, smu_debug);
+ seq_printf(m, "SMC feature version: %u, program: %d, firmware version: 0x%08x (%d.%d.%d)\n",
+ fw_info.feature, smu_program, fw_info.ver, smu_major, smu_minor, smu_debug);
/* SDMA */
query_fw.fw_type = AMDGPU_INFO_FW_SDMA;
@@ -1623,6 +1553,16 @@ static int amdgpu_debugfs_firmware_info_show(struct seq_file *m, void *unused)
seq_printf(m, "TOC feature version: %u, firmware version: 0x%08x\n",
fw_info.feature, fw_info.ver);
+ /* CAP */
+ if (adev->psp.cap_fw) {
+ query_fw.fw_type = AMDGPU_INFO_FW_CAP;
+ ret = amdgpu_firmware_info(&fw_info, &query_fw, adev);
+ if (ret)
+ return ret;
+ seq_printf(m, "CAP feature version: %u, firmware version: 0x%08x\n",
+ fw_info.feature, fw_info.ver);
+ }
+
seq_printf(m, "VBIOS version: %s\n", ctx->vbios_version);
return 0;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mca.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_mca.c
index ce538f4819f9..51c2a82e2fa4 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mca.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mca.c
@@ -70,48 +70,3 @@ void amdgpu_mca_query_ras_error_count(struct amdgpu_device *adev,
amdgpu_mca_reset_error_count(adev, mc_status_addr);
}
-
-int amdgpu_mca_ras_late_init(struct amdgpu_device *adev,
- struct amdgpu_mca_ras *mca_dev)
-{
- int r;
- struct ras_ih_if ih_info = {
- .cb = NULL,
- };
- struct ras_fs_if fs_info = {
- .sysfs_name = mca_dev->ras_funcs->sysfs_name,
- };
-
- if (!mca_dev->ras_if) {
- mca_dev->ras_if = kmalloc(sizeof(struct ras_common_if), GFP_KERNEL);
- if (!mca_dev->ras_if)
- return -ENOMEM;
- mca_dev->ras_if->block = mca_dev->ras_funcs->ras_block;
- mca_dev->ras_if->sub_block_index = mca_dev->ras_funcs->ras_sub_block;
- mca_dev->ras_if->type = AMDGPU_RAS_ERROR__MULTI_UNCORRECTABLE;
- }
- ih_info.head = fs_info.head = *mca_dev->ras_if;
- r = amdgpu_ras_late_init(adev, mca_dev->ras_if,
- &fs_info, &ih_info);
- if (r || !amdgpu_ras_is_supported(adev, mca_dev->ras_if->block)) {
- kfree(mca_dev->ras_if);
- mca_dev->ras_if = NULL;
- }
-
- return r;
-}
-
-void amdgpu_mca_ras_fini(struct amdgpu_device *adev,
- struct amdgpu_mca_ras *mca_dev)
-{
- struct ras_ih_if ih_info = {
- .cb = NULL,
- };
-
- if (!mca_dev->ras_if)
- return;
-
- amdgpu_ras_late_fini(adev, mca_dev->ras_if, &ih_info);
- kfree(mca_dev->ras_if);
- mca_dev->ras_if = NULL;
-} \ No newline at end of file
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mca.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_mca.h
index c74bc7177066..7ce16d16e34b 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mca.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mca.h
@@ -21,21 +21,13 @@
#ifndef __AMDGPU_MCA_H__
#define __AMDGPU_MCA_H__
-struct amdgpu_mca_ras_funcs {
- int (*ras_late_init)(struct amdgpu_device *adev);
- void (*ras_fini)(struct amdgpu_device *adev);
- void (*query_ras_error_count)(struct amdgpu_device *adev,
- void *ras_error_status);
- void (*query_ras_error_address)(struct amdgpu_device *adev,
- void *ras_error_status);
- uint32_t ras_block;
- uint32_t ras_sub_block;
- const char* sysfs_name;
+struct amdgpu_mca_ras_block {
+ struct amdgpu_ras_block_object ras_block;
};
struct amdgpu_mca_ras {
struct ras_common_if *ras_if;
- const struct amdgpu_mca_ras_funcs *ras_funcs;
+ struct amdgpu_mca_ras_block *ras;
};
struct amdgpu_mca_funcs {
@@ -64,10 +56,4 @@ void amdgpu_mca_query_ras_error_count(struct amdgpu_device *adev,
uint64_t mc_status_addr,
void *ras_error_status);
-int amdgpu_mca_ras_late_init(struct amdgpu_device *adev,
- struct amdgpu_mca_ras *mca_dev);
-
-void amdgpu_mca_ras_fini(struct amdgpu_device *adev,
- struct amdgpu_mca_ras *mca_dev);
-
#endif
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mmhub.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_mmhub.c
deleted file mode 100644
index 24297dc51434..000000000000
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mmhub.c
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright 2019 Advanced Micro Devices, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- */
-
-#include "amdgpu.h"
-#include "amdgpu_ras.h"
-
-int amdgpu_mmhub_ras_late_init(struct amdgpu_device *adev)
-{
- int r;
- struct ras_ih_if ih_info = {
- .cb = NULL,
- };
- struct ras_fs_if fs_info = {
- .sysfs_name = "mmhub_err_count",
- };
-
- if (!adev->mmhub.ras_if) {
- adev->mmhub.ras_if = kmalloc(sizeof(struct ras_common_if), GFP_KERNEL);
- if (!adev->mmhub.ras_if)
- return -ENOMEM;
- adev->mmhub.ras_if->block = AMDGPU_RAS_BLOCK__MMHUB;
- adev->mmhub.ras_if->type = AMDGPU_RAS_ERROR__MULTI_UNCORRECTABLE;
- adev->mmhub.ras_if->sub_block_index = 0;
- }
- ih_info.head = fs_info.head = *adev->mmhub.ras_if;
- r = amdgpu_ras_late_init(adev, adev->mmhub.ras_if,
- &fs_info, &ih_info);
- if (r || !amdgpu_ras_is_supported(adev, adev->mmhub.ras_if->block)) {
- kfree(adev->mmhub.ras_if);
- adev->mmhub.ras_if = NULL;
- }
-
- return r;
-}
-
-void amdgpu_mmhub_ras_fini(struct amdgpu_device *adev)
-{
- if (amdgpu_ras_is_supported(adev, AMDGPU_RAS_BLOCK__MMHUB) &&
- adev->mmhub.ras_if) {
- struct ras_common_if *ras_if = adev->mmhub.ras_if;
- struct ras_ih_if ih_info = {
- .cb = NULL,
- };
-
- amdgpu_ras_late_fini(adev, ras_if, &ih_info);
- kfree(ras_if);
- }
-}
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mmhub.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_mmhub.h
index b27fcbccce2b..9f1540f0ebf9 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mmhub.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mmhub.h
@@ -21,14 +21,8 @@
#ifndef __AMDGPU_MMHUB_H__
#define __AMDGPU_MMHUB_H__
-struct amdgpu_mmhub_ras_funcs {
- int (*ras_late_init)(struct amdgpu_device *adev);
- void (*ras_fini)(struct amdgpu_device *adev);
- void (*query_ras_error_count)(struct amdgpu_device *adev,
- void *ras_error_status);
- void (*query_ras_error_status)(struct amdgpu_device *adev);
- void (*reset_ras_error_count)(struct amdgpu_device *adev);
- void (*reset_ras_error_status)(struct amdgpu_device *adev);
+struct amdgpu_mmhub_ras {
+ struct amdgpu_ras_block_object ras_block;
};
struct amdgpu_mmhub_funcs {
@@ -50,10 +44,8 @@ struct amdgpu_mmhub_funcs {
struct amdgpu_mmhub {
struct ras_common_if *ras_if;
const struct amdgpu_mmhub_funcs *funcs;
- const struct amdgpu_mmhub_ras_funcs *ras_funcs;
+ struct amdgpu_mmhub_ras *ras;
};
-int amdgpu_mmhub_ras_late_init(struct amdgpu_device *adev);
-void amdgpu_mmhub_ras_fini(struct amdgpu_device *adev);
#endif
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
index 6043bf6fd414..a546cb3cfa18 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
@@ -33,7 +33,7 @@
#include <drm/drm_crtc.h>
#include <drm/drm_edid.h>
#include <drm/drm_encoder.h>
-#include <drm/drm_dp_helper.h>
+#include <drm/dp/drm_dp_helper.h>
#include <drm/drm_fixed.h>
#include <drm/drm_crtc_helper.h>
#include <drm/drm_fb_helper.h>
@@ -44,7 +44,7 @@
#include <linux/hrtimer.h>
#include "amdgpu_irq.h"
-#include <drm/drm_dp_mst_helper.h>
+#include <drm/dp/drm_dp_mst_helper.h>
#include "modules/inc/mod_freesync.h"
#include "amdgpu_dm_irq_params.h"
@@ -341,6 +341,7 @@ struct amdgpu_mode_info {
int num_crtc; /* number of crtcs */
int num_hpd; /* number of hpd pins */
int num_dig; /* number of dig blocks */
+ bool gpu_vm_support; /* supports display from GTT */
int disp_priority;
const struct amdgpu_display_funcs *funcs;
const enum drm_plane_type *plane_type;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_nbio.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_nbio.c
index 6afb02fef8cf..37d779b8e4a6 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_nbio.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_nbio.c
@@ -22,61 +22,24 @@
#include "amdgpu.h"
#include "amdgpu_ras.h"
-int amdgpu_nbio_ras_late_init(struct amdgpu_device *adev)
+int amdgpu_nbio_ras_late_init(struct amdgpu_device *adev, struct ras_common_if *ras_block)
{
int r;
- struct ras_ih_if ih_info = {
- .cb = NULL,
- };
- struct ras_fs_if fs_info = {
- .sysfs_name = "pcie_bif_err_count",
- };
-
- if (!adev->nbio.ras_if) {
- adev->nbio.ras_if = kmalloc(sizeof(struct ras_common_if), GFP_KERNEL);
- if (!adev->nbio.ras_if)
- return -ENOMEM;
- adev->nbio.ras_if->block = AMDGPU_RAS_BLOCK__PCIE_BIF;
- adev->nbio.ras_if->type = AMDGPU_RAS_ERROR__MULTI_UNCORRECTABLE;
- adev->nbio.ras_if->sub_block_index = 0;
- }
- ih_info.head = fs_info.head = *adev->nbio.ras_if;
- r = amdgpu_ras_late_init(adev, adev->nbio.ras_if,
- &fs_info, &ih_info);
+ r = amdgpu_ras_block_late_init(adev, ras_block);
if (r)
- goto free;
+ return r;
- if (amdgpu_ras_is_supported(adev, adev->nbio.ras_if->block)) {
+ if (amdgpu_ras_is_supported(adev, ras_block->block)) {
r = amdgpu_irq_get(adev, &adev->nbio.ras_controller_irq, 0);
if (r)
goto late_fini;
r = amdgpu_irq_get(adev, &adev->nbio.ras_err_event_athub_irq, 0);
if (r)
goto late_fini;
- } else {
- r = 0;
- goto free;
}
return 0;
late_fini:
- amdgpu_ras_late_fini(adev, adev->nbio.ras_if, &ih_info);
-free:
- kfree(adev->nbio.ras_if);
- adev->nbio.ras_if = NULL;
+ amdgpu_ras_block_late_fini(adev, ras_block);
return r;
}
-
-void amdgpu_nbio_ras_fini(struct amdgpu_device *adev)
-{
- if (amdgpu_ras_is_supported(adev, AMDGPU_RAS_BLOCK__PCIE_BIF) &&
- adev->nbio.ras_if) {
- struct ras_common_if *ras_if = adev->nbio.ras_if;
- struct ras_ih_if ih_info = {
- .cb = NULL,
- };
-
- amdgpu_ras_late_fini(adev, ras_if, &ih_info);
- kfree(ras_if);
- }
-}
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_nbio.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_nbio.h
index 843052205bd5..3d13e601fc35 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_nbio.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_nbio.h
@@ -47,15 +47,12 @@ struct nbio_hdp_flush_reg {
u32 ref_and_mask_sdma7;
};
-struct amdgpu_nbio_ras_funcs {
+struct amdgpu_nbio_ras {
+ struct amdgpu_ras_block_object ras_block;
void (*handle_ras_controller_intr_no_bifring)(struct amdgpu_device *adev);
void (*handle_ras_err_event_athub_intr_no_bifring)(struct amdgpu_device *adev);
int (*init_ras_controller_interrupt)(struct amdgpu_device *adev);
int (*init_ras_err_event_athub_interrupt)(struct amdgpu_device *adev);
- void (*query_ras_error_count)(struct amdgpu_device *adev,
- void *ras_error_status);
- int (*ras_late_init)(struct amdgpu_device *adev);
- void (*ras_fini)(struct amdgpu_device *adev);
};
struct amdgpu_nbio_funcs {
@@ -104,9 +101,8 @@ struct amdgpu_nbio {
struct amdgpu_irq_src ras_err_event_athub_irq;
struct ras_common_if *ras_if;
const struct amdgpu_nbio_funcs *funcs;
- const struct amdgpu_nbio_ras_funcs *ras_funcs;
+ struct amdgpu_nbio_ras *ras;
};
-int amdgpu_nbio_ras_late_init(struct amdgpu_device *adev);
-void amdgpu_nbio_ras_fini(struct amdgpu_device *adev);
+int amdgpu_nbio_ras_late_init(struct amdgpu_device *adev, struct ras_common_if *ras_block);
#endif
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
index 5661b82d84d4..25731719c627 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
@@ -451,7 +451,7 @@ static bool amdgpu_bo_validate_size(struct amdgpu_device *adev,
if (domain & AMDGPU_GEM_DOMAIN_GTT) {
man = ttm_manager_type(&adev->mman.bdev, TTM_PL_TT);
- if (size < (man->size << PAGE_SHIFT))
+ if (size < man->size)
return true;
else
goto fail;
@@ -460,7 +460,7 @@ static bool amdgpu_bo_validate_size(struct amdgpu_device *adev,
if (domain & AMDGPU_GEM_DOMAIN_VRAM) {
man = ttm_manager_type(&adev->mman.bdev, TTM_PL_VRAM);
- if (size < (man->size << PAGE_SHIFT))
+ if (size < man->size)
return true;
else
goto fail;
@@ -575,6 +575,9 @@ int amdgpu_bo_create(struct amdgpu_device *adev,
if (!amdgpu_bo_support_uswc(bo->flags))
bo->flags &= ~AMDGPU_GEM_CREATE_CPU_GTT_USWC;
+ if (adev->ras_enabled)
+ bo->flags |= AMDGPU_GEM_CREATE_VRAM_WIPE_ON_RELEASE;
+
bo->tbo.bdev = &adev->mman.bdev;
if (bp->domain & (AMDGPU_GEM_DOMAIN_GWS | AMDGPU_GEM_DOMAIN_OA |
AMDGPU_GEM_DOMAIN_GDS))
@@ -1303,7 +1306,8 @@ void amdgpu_bo_release_notify(struct ttm_buffer_object *bo)
!(abo->flags & AMDGPU_GEM_CREATE_VRAM_WIPE_ON_RELEASE))
return;
- dma_resv_lock(bo->base.resv, NULL);
+ if (WARN_ON_ONCE(!dma_resv_trylock(bo->base.resv)))
+ return;
r = amdgpu_fill_buffer(abo, AMDGPU_POISON, bo->base.resv, &fence);
if (!WARN_ON(r)) {
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_preempt_mgr.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_preempt_mgr.c
index 786afe4f58f9..e8adfd0a570a 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_preempt_mgr.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_preempt_mgr.c
@@ -25,12 +25,6 @@
#include "amdgpu.h"
-static inline struct amdgpu_preempt_mgr *
-to_preempt_mgr(struct ttm_resource_manager *man)
-{
- return container_of(man, struct amdgpu_preempt_mgr, manager);
-}
-
/**
* DOC: mem_info_preempt_used
*
@@ -45,10 +39,9 @@ static ssize_t mem_info_preempt_used_show(struct device *dev,
{
struct drm_device *ddev = dev_get_drvdata(dev);
struct amdgpu_device *adev = drm_to_adev(ddev);
- struct ttm_resource_manager *man;
+ struct ttm_resource_manager *man = &adev->mman.preempt_mgr;
- man = ttm_manager_type(&adev->mman.bdev, AMDGPU_PL_PREEMPT);
- return sysfs_emit(buf, "%llu\n", amdgpu_preempt_mgr_usage(man));
+ return sysfs_emit(buf, "%llu\n", ttm_resource_manager_usage(man));
}
static DEVICE_ATTR_RO(mem_info_preempt_used);
@@ -68,16 +61,12 @@ static int amdgpu_preempt_mgr_new(struct ttm_resource_manager *man,
const struct ttm_place *place,
struct ttm_resource **res)
{
- struct amdgpu_preempt_mgr *mgr = to_preempt_mgr(man);
-
*res = kzalloc(sizeof(**res), GFP_KERNEL);
if (!*res)
return -ENOMEM;
ttm_resource_init(tbo, place, *res);
(*res)->start = AMDGPU_BO_INVALID_OFFSET;
-
- atomic64_add((*res)->num_pages, &mgr->used);
return 0;
}
@@ -92,48 +81,13 @@ static int amdgpu_preempt_mgr_new(struct ttm_resource_manager *man,
static void amdgpu_preempt_mgr_del(struct ttm_resource_manager *man,
struct ttm_resource *res)
{
- struct amdgpu_preempt_mgr *mgr = to_preempt_mgr(man);
-
- atomic64_sub(res->num_pages, &mgr->used);
+ ttm_resource_fini(man, res);
kfree(res);
}
-/**
- * amdgpu_preempt_mgr_usage - return usage of PREEMPT domain
- *
- * @man: TTM memory type manager
- *
- * Return how many bytes are used in the GTT domain
- */
-uint64_t amdgpu_preempt_mgr_usage(struct ttm_resource_manager *man)
-{
- struct amdgpu_preempt_mgr *mgr = to_preempt_mgr(man);
- s64 result = atomic64_read(&mgr->used);
-
- return (result > 0 ? result : 0) * PAGE_SIZE;
-}
-
-/**
- * amdgpu_preempt_mgr_debug - dump VRAM table
- *
- * @man: TTM memory type manager
- * @printer: DRM printer to use
- *
- * Dump the table content using printk.
- */
-static void amdgpu_preempt_mgr_debug(struct ttm_resource_manager *man,
- struct drm_printer *printer)
-{
- struct amdgpu_preempt_mgr *mgr = to_preempt_mgr(man);
-
- drm_printf(printer, "man size:%llu pages, preempt used:%lld pages\n",
- man->size, (u64)atomic64_read(&mgr->used));
-}
-
static const struct ttm_resource_manager_func amdgpu_preempt_mgr_func = {
.alloc = amdgpu_preempt_mgr_new,
.free = amdgpu_preempt_mgr_del,
- .debug = amdgpu_preempt_mgr_debug
};
/**
@@ -145,16 +99,13 @@ static const struct ttm_resource_manager_func amdgpu_preempt_mgr_func = {
*/
int amdgpu_preempt_mgr_init(struct amdgpu_device *adev)
{
- struct amdgpu_preempt_mgr *mgr = &adev->mman.preempt_mgr;
- struct ttm_resource_manager *man = &mgr->manager;
+ struct ttm_resource_manager *man = &adev->mman.preempt_mgr;
int ret;
man->use_tt = true;
man->func = &amdgpu_preempt_mgr_func;
- ttm_resource_manager_init(man, (1 << 30));
-
- atomic64_set(&mgr->used, 0);
+ ttm_resource_manager_init(man, &adev->mman.bdev, (1 << 30));
ret = device_create_file(adev->dev, &dev_attr_mem_info_preempt_used);
if (ret) {
@@ -162,8 +113,7 @@ int amdgpu_preempt_mgr_init(struct amdgpu_device *adev)
return ret;
}
- ttm_set_driver_manager(&adev->mman.bdev, AMDGPU_PL_PREEMPT,
- &mgr->manager);
+ ttm_set_driver_manager(&adev->mman.bdev, AMDGPU_PL_PREEMPT, man);
ttm_resource_manager_set_used(man, true);
return 0;
}
@@ -178,8 +128,7 @@ int amdgpu_preempt_mgr_init(struct amdgpu_device *adev)
*/
void amdgpu_preempt_mgr_fini(struct amdgpu_device *adev)
{
- struct amdgpu_preempt_mgr *mgr = &adev->mman.preempt_mgr;
- struct ttm_resource_manager *man = &mgr->manager;
+ struct ttm_resource_manager *man = &adev->mman.preempt_mgr;
int ret;
ttm_resource_manager_set_used(man, false);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c
index dee17a0e1187..a6acec1a6155 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c
@@ -133,6 +133,8 @@ static int psp_early_init(void *handle)
break;
case IP_VERSION(13, 0, 1):
case IP_VERSION(13, 0, 3):
+ case IP_VERSION(13, 0, 5):
+ case IP_VERSION(13, 0, 8):
psp_v13_0_set_psp_funcs(psp);
psp->autoload_supported = true;
break;
@@ -259,6 +261,32 @@ static bool psp_get_runtime_db_entry(struct amdgpu_device *adev,
return ret;
}
+static int psp_init_sriov_microcode(struct psp_context *psp)
+{
+ struct amdgpu_device *adev = psp->adev;
+ int ret = 0;
+
+ switch (adev->ip_versions[MP0_HWIP][0]) {
+ case IP_VERSION(9, 0, 0):
+ ret = psp_init_cap_microcode(psp, "vega10");
+ break;
+ case IP_VERSION(11, 0, 9):
+ ret = psp_init_cap_microcode(psp, "navi12");
+ break;
+ case IP_VERSION(11, 0, 7):
+ ret = psp_init_cap_microcode(psp, "sienna_cichlid");
+ break;
+ case IP_VERSION(13, 0, 2):
+ ret = psp_init_cap_microcode(psp, "aldebaran");
+ break;
+ default:
+ BUG();
+ break;
+ }
+
+ return ret;
+}
+
static int psp_sw_init(void *handle)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
@@ -273,21 +301,19 @@ static int psp_sw_init(void *handle)
ret = -ENOMEM;
}
- if (!amdgpu_sriov_vf(adev)) {
+ if (amdgpu_sriov_vf(adev))
+ ret = psp_init_sriov_microcode(psp);
+ else
ret = psp_init_microcode(psp);
- if (ret) {
- DRM_ERROR("Failed to load psp firmware!\n");
- return ret;
- }
- } else if (amdgpu_sriov_vf(adev) &&
- adev->ip_versions[MP0_HWIP][0] == IP_VERSION(13, 0, 2)) {
- ret = psp_init_ta_microcode(psp, "aldebaran");
- if (ret) {
- DRM_ERROR("Failed to initialize ta microcode!\n");
- return ret;
- }
+ if (ret) {
+ DRM_ERROR("Failed to load psp firmware!\n");
+ return ret;
}
+ adev->psp.xgmi_context.supports_extended_data =
+ !adev->gmc.xgmi.connected_to_cpu &&
+ adev->ip_versions[MP0_HWIP][0] == IP_VERSION(13, 0, 2);
+
memset(&boot_cfg_entry, 0, sizeof(boot_cfg_entry));
if (psp_get_runtime_db_entry(adev,
PSP_RUNTIME_ENTRY_TYPE_BOOT_CONFIG,
@@ -353,6 +379,10 @@ static int psp_sw_fini(void *handle)
release_firmware(psp->ta_fw);
psp->ta_fw = NULL;
}
+ if (adev->psp.cap_fw) {
+ release_firmware(psp->cap_fw);
+ psp->cap_fw = NULL;
+ }
if (adev->ip_versions[MP0_HWIP][0] == IP_VERSION(11, 0, 0) ||
adev->ip_versions[MP0_HWIP][0] == IP_VERSION(11, 0, 7))
@@ -491,7 +521,10 @@ psp_cmd_submit_buf(struct psp_context *psp,
DRM_WARN("psp gfx command %s(0x%X) failed and response status is (0x%X)\n",
psp_gfx_cmd_name(psp->cmd_buf_mem->cmd_id), psp->cmd_buf_mem->cmd_id,
psp->cmd_buf_mem->resp.status);
- if (!timeout) {
+ /* If we load CAP FW, PSP must return 0 under SRIOV
+ * also return failure in case of timeout
+ */
+ if ((ucode && (ucode->ucode_id == AMDGPU_UCODE_ID_CAP)) || !timeout) {
ret = -EINVAL;
goto exit;
}
@@ -914,19 +947,15 @@ static void psp_prep_ta_load_cmd_buf(struct psp_gfx_cmd_resp *cmd,
static int psp_ta_init_shared_buf(struct psp_context *psp,
struct ta_mem_context *mem_ctx)
{
- int ret;
-
/*
* Allocate 16k memory aligned to 4k from Frame Buffer (local
* physical) for ta to host memory
*/
- ret = amdgpu_bo_create_kernel(psp->adev, mem_ctx->shared_mem_size,
+ return amdgpu_bo_create_kernel(psp->adev, mem_ctx->shared_mem_size,
PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM,
&mem_ctx->shared_bo,
&mem_ctx->shared_mc_addr,
&mem_ctx->shared_buf);
-
- return ret;
}
static void psp_ta_free_shared_buf(struct ta_mem_context *mem_ctx)
@@ -1308,6 +1337,11 @@ static void psp_ras_ta_check_status(struct psp_context *psp)
break;
case TA_RAS_STATUS__SUCCESS:
break;
+ case TA_RAS_STATUS__TEE_ERROR_ACCESS_DENIED:
+ if (ras_cmd->cmd_id == TA_RAS_COMMAND__TRIGGER_ERROR)
+ dev_warn(psp->adev->dev,
+ "RAS WARNING: Inject error to critical region is not allowed\n");
+ break;
default:
dev_warn(psp->adev->dev,
"RAS WARNING: ras status = 0x%X\n", ras_cmd->ras_status);
@@ -1520,7 +1554,9 @@ int psp_ras_trigger_error(struct psp_context *psp,
if (amdgpu_ras_intr_triggered())
return 0;
- if (ras_cmd->ras_status)
+ if (ras_cmd->ras_status == TA_RAS_STATUS__TEE_ERROR_ACCESS_DENIED)
+ return -EACCES;
+ else if (ras_cmd->ras_status)
return -EINVAL;
return 0;
@@ -2051,6 +2087,9 @@ static int psp_get_fw_type(struct amdgpu_firmware_info *ucode,
enum psp_gfx_fw_type *type)
{
switch (ucode->ucode_id) {
+ case AMDGPU_UCODE_ID_CAP:
+ *type = GFX_FW_TYPE_CAP;
+ break;
case AMDGPU_UCODE_ID_SDMA0:
*type = GFX_FW_TYPE_SDMA0;
break;
@@ -2973,7 +3012,6 @@ static int psp_init_sos_base_fw(struct amdgpu_device *adev)
adev->psp.sos.size_bytes = le32_to_cpu(sos_hdr->sos.size_bytes);
adev->psp.sos.start_addr = ucode_array_start_addr +
le32_to_cpu(sos_hdr->sos.offset_bytes);
- adev->psp.xgmi_context.supports_extended_data = false;
} else {
/* Load alternate PSP SOS FW */
sos_hdr_v1_3 = (const struct psp_firmware_header_v1_3 *)adev->psp.sos_fw->data;
@@ -2988,7 +3026,6 @@ static int psp_init_sos_base_fw(struct amdgpu_device *adev)
adev->psp.sos.size_bytes = le32_to_cpu(sos_hdr_v1_3->sos_aux.size_bytes);
adev->psp.sos.start_addr = ucode_array_start_addr +
le32_to_cpu(sos_hdr_v1_3->sos_aux.offset_bytes);
- adev->psp.xgmi_context.supports_extended_data = true;
}
if ((adev->psp.sys.size_bytes == 0) || (adev->psp.sos.size_bytes == 0)) {
@@ -3217,6 +3254,58 @@ out:
return err;
}
+int psp_init_cap_microcode(struct psp_context *psp,
+ const char *chip_name)
+{
+ struct amdgpu_device *adev = psp->adev;
+ char fw_name[PSP_FW_NAME_LEN];
+ const struct psp_firmware_header_v1_0 *cap_hdr_v1_0;
+ struct amdgpu_firmware_info *info = NULL;
+ int err = 0;
+
+ if (!chip_name) {
+ dev_err(adev->dev, "invalid chip name for cap microcode\n");
+ return -EINVAL;
+ }
+
+ if (!amdgpu_sriov_vf(adev)) {
+ dev_err(adev->dev, "cap microcode should only be loaded under SRIOV\n");
+ return -EINVAL;
+ }
+
+ snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_cap.bin", chip_name);
+ err = request_firmware(&adev->psp.cap_fw, fw_name, adev->dev);
+ if (err) {
+ dev_warn(adev->dev, "cap microcode does not exist, skip\n");
+ err = 0;
+ goto out;
+ }
+
+ err = amdgpu_ucode_validate(adev->psp.cap_fw);
+ if (err) {
+ dev_err(adev->dev, "fail to initialize cap microcode\n");
+ goto out;
+ }
+
+ info = &adev->firmware.ucode[AMDGPU_UCODE_ID_CAP];
+ info->ucode_id = AMDGPU_UCODE_ID_CAP;
+ info->fw = adev->psp.cap_fw;
+ cap_hdr_v1_0 = (const struct psp_firmware_header_v1_0 *)
+ adev->psp.cap_fw->data;
+ adev->firmware.fw_size += ALIGN(
+ le32_to_cpu(cap_hdr_v1_0->header.ucode_size_bytes), PAGE_SIZE);
+ adev->psp.cap_fw_version = le32_to_cpu(cap_hdr_v1_0->header.ucode_version);
+ adev->psp.cap_feature_version = le32_to_cpu(cap_hdr_v1_0->sos.fw_version);
+ adev->psp.cap_ucode_size = le32_to_cpu(cap_hdr_v1_0->header.ucode_size_bytes);
+
+ return 0;
+
+out:
+ release_firmware(adev->psp.cap_fw);
+ adev->psp.cap_fw = NULL;
+ return err;
+}
+
static int psp_set_clockgating_state(void *handle,
enum amd_clockgating_state state)
{
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h
index f29afabbff1f..ff7d533eb746 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h
@@ -306,6 +306,9 @@ struct psp_context
/* toc firmware */
const struct firmware *toc_fw;
+ /* cap firmware */
+ const struct firmware *cap_fw;
+
/* fence buffer */
struct amdgpu_bo *fence_buf_bo;
uint64_t fence_buf_mc_addr;
@@ -327,6 +330,10 @@ struct psp_context
const struct firmware *ta_fw;
uint32_t ta_fw_version;
+ uint32_t cap_fw_version;
+ uint32_t cap_feature_version;
+ uint32_t cap_ucode_size;
+
struct ta_context asd_context;
struct psp_xgmi_context xgmi_context;
struct psp_ras_context ras_context;
@@ -440,6 +447,8 @@ int psp_init_sos_microcode(struct psp_context *psp,
const char *chip_name);
int psp_init_ta_microcode(struct psp_context *psp,
const char *chip_name);
+int psp_init_cap_microcode(struct psp_context *psp,
+ const char *chip_name);
int psp_get_fw_attestation_records_addr(struct psp_context *psp,
uint64_t *output_ptr);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c
index 8f47c14ecbc7..424c22a841f4 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c
@@ -75,6 +75,13 @@ const char *ras_mca_block_string[] = {
"mca_iohc",
};
+struct amdgpu_ras_block_list {
+ /* ras block link */
+ struct list_head node;
+
+ struct amdgpu_ras_block_object *ras_obj;
+};
+
const char *get_ras_block_str(struct ras_common_if *ras_block)
{
if (!ras_block)
@@ -89,6 +96,9 @@ const char *get_ras_block_str(struct ras_common_if *ras_block)
return ras_block_string[ras_block->block];
}
+#define ras_block_str(_BLOCK_) \
+ (((_BLOCK_) < ARRAY_SIZE(ras_block_string)) ? ras_block_string[_BLOCK_] : "Out Of Range")
+
#define ras_err_str(i) (ras_error_string[ffs(i)])
#define RAS_DEFAULT_FLAGS (AMDGPU_RAS_FLAG_INIT_BY_VBIOS)
@@ -155,14 +165,9 @@ static int amdgpu_reserve_page_direct(struct amdgpu_device *adev, uint64_t addre
}
memset(&err_rec, 0x0, sizeof(struct eeprom_table_record));
-
- err_rec.address = address;
- err_rec.retired_page = address >> AMDGPU_GPU_PAGE_SHIFT;
- err_rec.ts = (uint64_t)ktime_get_real_seconds();
- err_rec.err_type = AMDGPU_RAS_EEPROM_ERR_NON_RECOVERABLE;
-
err_data.err_addr = &err_rec;
- err_data.err_addr_cnt = 1;
+ amdgpu_umc_fill_error_record(&err_data, address,
+ (address >> AMDGPU_GPU_PAGE_SHIFT), 0, 0);
if (amdgpu_bad_page_threshold != 0) {
amdgpu_ras_add_bad_pages(adev, err_data.err_addr,
@@ -452,7 +457,7 @@ static ssize_t amdgpu_ras_debugfs_ctrl_write(struct file *f,
}
if (ret)
- return -EINVAL;
+ return ret;
return size;
}
@@ -866,30 +871,47 @@ static int amdgpu_ras_enable_all_features(struct amdgpu_device *adev,
}
/* feature ctl end */
+static int amdgpu_ras_block_match_default(struct amdgpu_ras_block_object *block_obj,
+ enum amdgpu_ras_block block)
+{
+ if (!block_obj)
+ return -EINVAL;
-static void amdgpu_ras_mca_query_error_status(struct amdgpu_device *adev,
- struct ras_common_if *ras_block,
- struct ras_err_data *err_data)
+ if (block_obj->ras_comm.block == block)
+ return 0;
+
+ return -EINVAL;
+}
+
+static struct amdgpu_ras_block_object *amdgpu_ras_get_ras_block(struct amdgpu_device *adev,
+ enum amdgpu_ras_block block, uint32_t sub_block_index)
{
- switch (ras_block->sub_block_index) {
- case AMDGPU_RAS_MCA_BLOCK__MP0:
- if (adev->mca.mp0.ras_funcs &&
- adev->mca.mp0.ras_funcs->query_ras_error_count)
- adev->mca.mp0.ras_funcs->query_ras_error_count(adev, &err_data);
- break;
- case AMDGPU_RAS_MCA_BLOCK__MP1:
- if (adev->mca.mp1.ras_funcs &&
- adev->mca.mp1.ras_funcs->query_ras_error_count)
- adev->mca.mp1.ras_funcs->query_ras_error_count(adev, &err_data);
- break;
- case AMDGPU_RAS_MCA_BLOCK__MPIO:
- if (adev->mca.mpio.ras_funcs &&
- adev->mca.mpio.ras_funcs->query_ras_error_count)
- adev->mca.mpio.ras_funcs->query_ras_error_count(adev, &err_data);
- break;
- default:
- break;
+ struct amdgpu_ras_block_list *node, *tmp;
+ struct amdgpu_ras_block_object *obj;
+
+ if (block >= AMDGPU_RAS_BLOCK__LAST)
+ return NULL;
+
+ if (!amdgpu_ras_is_supported(adev, block))
+ return NULL;
+
+ list_for_each_entry_safe(node, tmp, &adev->ras_list, node) {
+ if (!node->ras_obj) {
+ dev_warn(adev->dev, "Warning: abnormal ras list node.\n");
+ continue;
+ }
+
+ obj = node->ras_obj;
+ if (obj->ras_block_match) {
+ if (obj->ras_block_match(obj, block, sub_block_index) == 0)
+ return obj;
+ } else {
+ if (amdgpu_ras_block_match_default(obj, block) == 0)
+ return obj;
+ }
}
+
+ return NULL;
}
static void amdgpu_ras_get_ecc_info(struct amdgpu_device *adev, struct ras_err_data *err_data)
@@ -901,26 +923,26 @@ static void amdgpu_ras_get_ecc_info(struct amdgpu_device *adev, struct ras_err_d
* choosing right query method according to
* whether smu support query error information
*/
- ret = smu_get_ecc_info(&adev->smu, (void *)&(ras->umc_ecc));
+ ret = amdgpu_dpm_get_ecc_info(adev, (void *)&(ras->umc_ecc));
if (ret == -EOPNOTSUPP) {
- if (adev->umc.ras_funcs &&
- adev->umc.ras_funcs->query_ras_error_count)
- adev->umc.ras_funcs->query_ras_error_count(adev, err_data);
+ if (adev->umc.ras && adev->umc.ras->ras_block.hw_ops &&
+ adev->umc.ras->ras_block.hw_ops->query_ras_error_count)
+ adev->umc.ras->ras_block.hw_ops->query_ras_error_count(adev, err_data);
/* umc query_ras_error_address is also responsible for clearing
* error status
*/
- if (adev->umc.ras_funcs &&
- adev->umc.ras_funcs->query_ras_error_address)
- adev->umc.ras_funcs->query_ras_error_address(adev, err_data);
+ if (adev->umc.ras && adev->umc.ras->ras_block.hw_ops &&
+ adev->umc.ras->ras_block.hw_ops->query_ras_error_address)
+ adev->umc.ras->ras_block.hw_ops->query_ras_error_address(adev, err_data);
} else if (!ret) {
- if (adev->umc.ras_funcs &&
- adev->umc.ras_funcs->ecc_info_query_ras_error_count)
- adev->umc.ras_funcs->ecc_info_query_ras_error_count(adev, err_data);
+ if (adev->umc.ras &&
+ adev->umc.ras->ecc_info_query_ras_error_count)
+ adev->umc.ras->ecc_info_query_ras_error_count(adev, err_data);
- if (adev->umc.ras_funcs &&
- adev->umc.ras_funcs->ecc_info_query_ras_error_address)
- adev->umc.ras_funcs->ecc_info_query_ras_error_address(adev, err_data);
+ if (adev->umc.ras &&
+ adev->umc.ras->ecc_info_query_ras_error_address)
+ adev->umc.ras->ecc_info_query_ras_error_address(adev, err_data);
}
}
@@ -928,62 +950,32 @@ static void amdgpu_ras_get_ecc_info(struct amdgpu_device *adev, struct ras_err_d
int amdgpu_ras_query_error_status(struct amdgpu_device *adev,
struct ras_query_if *info)
{
+ struct amdgpu_ras_block_object *block_obj = NULL;
struct ras_manager *obj = amdgpu_ras_find_obj(adev, &info->head);
struct ras_err_data err_data = {0, 0, 0, NULL};
- int i;
if (!obj)
return -EINVAL;
- switch (info->head.block) {
- case AMDGPU_RAS_BLOCK__UMC:
+ if (info->head.block == AMDGPU_RAS_BLOCK__UMC) {
amdgpu_ras_get_ecc_info(adev, &err_data);
- break;
- case AMDGPU_RAS_BLOCK__SDMA:
- if (adev->sdma.funcs->query_ras_error_count) {
- for (i = 0; i < adev->sdma.num_instances; i++)
- adev->sdma.funcs->query_ras_error_count(adev, i,
- &err_data);
+ } else {
+ block_obj = amdgpu_ras_get_ras_block(adev, info->head.block, 0);
+ if (!block_obj || !block_obj->hw_ops) {
+ dev_dbg_once(adev->dev, "%s doesn't config RAS function\n",
+ get_ras_block_str(&info->head));
+ return -EINVAL;
}
- break;
- case AMDGPU_RAS_BLOCK__GFX:
- if (adev->gfx.ras_funcs &&
- adev->gfx.ras_funcs->query_ras_error_count)
- adev->gfx.ras_funcs->query_ras_error_count(adev, &err_data);
-
- if (adev->gfx.ras_funcs &&
- adev->gfx.ras_funcs->query_ras_error_status)
- adev->gfx.ras_funcs->query_ras_error_status(adev);
- break;
- case AMDGPU_RAS_BLOCK__MMHUB:
- if (adev->mmhub.ras_funcs &&
- adev->mmhub.ras_funcs->query_ras_error_count)
- adev->mmhub.ras_funcs->query_ras_error_count(adev, &err_data);
-
- if (adev->mmhub.ras_funcs &&
- adev->mmhub.ras_funcs->query_ras_error_status)
- adev->mmhub.ras_funcs->query_ras_error_status(adev);
- break;
- case AMDGPU_RAS_BLOCK__PCIE_BIF:
- if (adev->nbio.ras_funcs &&
- adev->nbio.ras_funcs->query_ras_error_count)
- adev->nbio.ras_funcs->query_ras_error_count(adev, &err_data);
- break;
- case AMDGPU_RAS_BLOCK__XGMI_WAFL:
- if (adev->gmc.xgmi.ras_funcs &&
- adev->gmc.xgmi.ras_funcs->query_ras_error_count)
- adev->gmc.xgmi.ras_funcs->query_ras_error_count(adev, &err_data);
- break;
- case AMDGPU_RAS_BLOCK__HDP:
- if (adev->hdp.ras_funcs &&
- adev->hdp.ras_funcs->query_ras_error_count)
- adev->hdp.ras_funcs->query_ras_error_count(adev, &err_data);
- break;
- case AMDGPU_RAS_BLOCK__MCA:
- amdgpu_ras_mca_query_error_status(adev, &info->head, &err_data);
- break;
- default:
- break;
+
+ if (block_obj->hw_ops->query_ras_error_count)
+ block_obj->hw_ops->query_ras_error_count(adev, &err_data);
+
+ if ((info->head.block == AMDGPU_RAS_BLOCK__SDMA) ||
+ (info->head.block == AMDGPU_RAS_BLOCK__GFX) ||
+ (info->head.block == AMDGPU_RAS_BLOCK__MMHUB)) {
+ if (block_obj->hw_ops->query_ras_error_status)
+ block_obj->hw_ops->query_ras_error_status(adev);
+ }
}
obj->err_data.ue_count += err_data.ue_count;
@@ -1040,68 +1032,27 @@ int amdgpu_ras_query_error_status(struct amdgpu_device *adev,
int amdgpu_ras_reset_error_status(struct amdgpu_device *adev,
enum amdgpu_ras_block block)
{
+ struct amdgpu_ras_block_object *block_obj = amdgpu_ras_get_ras_block(adev, block, 0);
+
if (!amdgpu_ras_is_supported(adev, block))
return -EINVAL;
- switch (block) {
- case AMDGPU_RAS_BLOCK__GFX:
- if (adev->gfx.ras_funcs &&
- adev->gfx.ras_funcs->reset_ras_error_count)
- adev->gfx.ras_funcs->reset_ras_error_count(adev);
-
- if (adev->gfx.ras_funcs &&
- adev->gfx.ras_funcs->reset_ras_error_status)
- adev->gfx.ras_funcs->reset_ras_error_status(adev);
- break;
- case AMDGPU_RAS_BLOCK__MMHUB:
- if (adev->mmhub.ras_funcs &&
- adev->mmhub.ras_funcs->reset_ras_error_count)
- adev->mmhub.ras_funcs->reset_ras_error_count(adev);
-
- if (adev->mmhub.ras_funcs &&
- adev->mmhub.ras_funcs->reset_ras_error_status)
- adev->mmhub.ras_funcs->reset_ras_error_status(adev);
- break;
- case AMDGPU_RAS_BLOCK__SDMA:
- if (adev->sdma.funcs->reset_ras_error_count)
- adev->sdma.funcs->reset_ras_error_count(adev);
- break;
- case AMDGPU_RAS_BLOCK__HDP:
- if (adev->hdp.ras_funcs &&
- adev->hdp.ras_funcs->reset_ras_error_count)
- adev->hdp.ras_funcs->reset_ras_error_count(adev);
- break;
- default:
- break;
+ if (!block_obj || !block_obj->hw_ops) {
+ dev_dbg_once(adev->dev, "%s doesn't config RAS function\n",
+ ras_block_str(block));
+ return -EINVAL;
}
- return 0;
-}
-
-/* Trigger XGMI/WAFL error */
-static int amdgpu_ras_error_inject_xgmi(struct amdgpu_device *adev,
- struct ta_ras_trigger_error_input *block_info)
-{
- int ret;
-
- if (amdgpu_dpm_set_df_cstate(adev, DF_CSTATE_DISALLOW))
- dev_warn(adev->dev, "Failed to disallow df cstate");
-
- if (amdgpu_dpm_allow_xgmi_power_down(adev, false))
- dev_warn(adev->dev, "Failed to disallow XGMI power down");
-
- ret = psp_ras_trigger_error(&adev->psp, block_info);
+ if (block_obj->hw_ops->reset_ras_error_count)
+ block_obj->hw_ops->reset_ras_error_count(adev);
- if (amdgpu_ras_intr_triggered())
- return ret;
-
- if (amdgpu_dpm_allow_xgmi_power_down(adev, true))
- dev_warn(adev->dev, "Failed to allow XGMI power down");
-
- if (amdgpu_dpm_set_df_cstate(adev, DF_CSTATE_ALLOW))
- dev_warn(adev->dev, "Failed to allow df cstate");
+ if ((block == AMDGPU_RAS_BLOCK__GFX) ||
+ (block == AMDGPU_RAS_BLOCK__MMHUB)) {
+ if (block_obj->hw_ops->reset_ras_error_status)
+ block_obj->hw_ops->reset_ras_error_status(adev);
+ }
- return ret;
+ return 0;
}
/* wrapper of psp_ras_trigger_error */
@@ -1116,11 +1067,20 @@ int amdgpu_ras_error_inject(struct amdgpu_device *adev,
.address = info->address,
.value = info->value,
};
- int ret = 0;
+ int ret = -EINVAL;
+ struct amdgpu_ras_block_object *block_obj = amdgpu_ras_get_ras_block(adev,
+ info->head.block,
+ info->head.sub_block_index);
if (!obj)
return -EINVAL;
+ if (!block_obj || !block_obj->hw_ops) {
+ dev_dbg_once(adev->dev, "%s doesn't config RAS function\n",
+ get_ras_block_str(&info->head));
+ return -EINVAL;
+ }
+
/* Calculate XGMI relative offset */
if (adev->gmc.xgmi.num_physical_nodes > 1) {
block_info.address =
@@ -1128,28 +1088,15 @@ int amdgpu_ras_error_inject(struct amdgpu_device *adev,
block_info.address);
}
- switch (info->head.block) {
- case AMDGPU_RAS_BLOCK__GFX:
- if (adev->gfx.ras_funcs &&
- adev->gfx.ras_funcs->ras_error_inject)
- ret = adev->gfx.ras_funcs->ras_error_inject(adev, info);
- else
- ret = -EINVAL;
- break;
- case AMDGPU_RAS_BLOCK__UMC:
- case AMDGPU_RAS_BLOCK__SDMA:
- case AMDGPU_RAS_BLOCK__MMHUB:
- case AMDGPU_RAS_BLOCK__PCIE_BIF:
- case AMDGPU_RAS_BLOCK__MCA:
- ret = psp_ras_trigger_error(&adev->psp, &block_info);
- break;
- case AMDGPU_RAS_BLOCK__XGMI_WAFL:
- ret = amdgpu_ras_error_inject_xgmi(adev, &block_info);
- break;
- default:
- dev_info(adev->dev, "%s error injection is not supported yet\n",
- get_ras_block_str(&info->head));
- ret = -EINVAL;
+ if (info->head.block == AMDGPU_RAS_BLOCK__GFX) {
+ if (block_obj->hw_ops->ras_error_inject)
+ ret = block_obj->hw_ops->ras_error_inject(adev, info);
+ } else {
+ /* If defined special ras_error_inject(e.g: xgmi), implement special ras_error_inject */
+ if (block_obj->hw_ops->ras_error_inject)
+ ret = block_obj->hw_ops->ras_error_inject(adev, &block_info);
+ else /*If not defined .ras_error_inject, use default ras_error_inject*/
+ ret = psp_ras_trigger_error(&adev->psp, &block_info);
}
if (ret)
@@ -1329,18 +1276,17 @@ static int amdgpu_ras_sysfs_remove_feature_node(struct amdgpu_device *adev)
}
int amdgpu_ras_sysfs_create(struct amdgpu_device *adev,
- struct ras_fs_if *head)
+ struct ras_common_if *head)
{
- struct ras_manager *obj = amdgpu_ras_find_obj(adev, &head->head);
+ struct ras_manager *obj = amdgpu_ras_find_obj(adev, head);
if (!obj || obj->attr_inuse)
return -EINVAL;
get_obj(obj);
- memcpy(obj->fs_data.sysfs_name,
- head->sysfs_name,
- sizeof(obj->fs_data.sysfs_name));
+ snprintf(obj->fs_data.sysfs_name, sizeof(obj->fs_data.sysfs_name),
+ "%s_err_count", head->name);
obj->sysfs_attr = (struct device_attribute){
.attr = {
@@ -1647,9 +1593,9 @@ int amdgpu_ras_interrupt_dispatch(struct amdgpu_device *adev,
}
int amdgpu_ras_interrupt_remove_handler(struct amdgpu_device *adev,
- struct ras_ih_if *info)
+ struct ras_common_if *head)
{
- struct ras_manager *obj = amdgpu_ras_find_obj(adev, &info->head);
+ struct ras_manager *obj = amdgpu_ras_find_obj(adev, head);
struct ras_ih_data *data;
if (!obj)
@@ -1669,24 +1615,27 @@ int amdgpu_ras_interrupt_remove_handler(struct amdgpu_device *adev,
}
int amdgpu_ras_interrupt_add_handler(struct amdgpu_device *adev,
- struct ras_ih_if *info)
+ struct ras_common_if *head)
{
- struct ras_manager *obj = amdgpu_ras_find_obj(adev, &info->head);
+ struct ras_manager *obj = amdgpu_ras_find_obj(adev, head);
struct ras_ih_data *data;
+ struct amdgpu_ras_block_object *ras_obj;
if (!obj) {
/* in case we registe the IH before enable ras feature */
- obj = amdgpu_ras_create_obj(adev, &info->head);
+ obj = amdgpu_ras_create_obj(adev, head);
if (!obj)
return -EINVAL;
} else
get_obj(obj);
+ ras_obj = container_of(head, struct amdgpu_ras_block_object, ras_comm);
+
data = &obj->ih_data;
/* add the callback.etc */
*data = (struct ras_ih_data) {
.inuse = 0,
- .cb = info->cb,
+ .cb = ras_obj->ras_cb,
.element_size = sizeof(struct amdgpu_iv_entry),
.rptr = 0,
.wptr = 0,
@@ -1715,10 +1664,7 @@ static int amdgpu_ras_interrupt_remove_all(struct amdgpu_device *adev)
struct ras_manager *obj, *tmp;
list_for_each_entry_safe(obj, tmp, &con->head, node) {
- struct ras_ih_if info = {
- .head = obj->head,
- };
- amdgpu_ras_interrupt_remove_handler(adev, &info);
+ amdgpu_ras_interrupt_remove_handler(adev, &obj->head);
}
return 0;
@@ -1766,24 +1712,28 @@ static void amdgpu_ras_log_on_err_counter(struct amdgpu_device *adev)
static void amdgpu_ras_error_status_query(struct amdgpu_device *adev,
struct ras_query_if *info)
{
+ struct amdgpu_ras_block_object *block_obj;
/*
* Only two block need to query read/write
* RspStatus at current state
*/
- switch (info->head.block) {
- case AMDGPU_RAS_BLOCK__GFX:
- if (adev->gfx.ras_funcs &&
- adev->gfx.ras_funcs->query_ras_error_status)
- adev->gfx.ras_funcs->query_ras_error_status(adev);
- break;
- case AMDGPU_RAS_BLOCK__MMHUB:
- if (adev->mmhub.ras_funcs &&
- adev->mmhub.ras_funcs->query_ras_error_status)
- adev->mmhub.ras_funcs->query_ras_error_status(adev);
- break;
- default:
- break;
+ if ((info->head.block != AMDGPU_RAS_BLOCK__GFX) &&
+ (info->head.block != AMDGPU_RAS_BLOCK__MMHUB))
+ return;
+
+ block_obj = amdgpu_ras_get_ras_block(adev,
+ info->head.block,
+ info->head.sub_block_index);
+
+ if (!block_obj || !block_obj->hw_ops) {
+ dev_dbg_once(adev->dev, "%s doesn't config RAS function\n",
+ get_ras_block_str(&info->head));
+ return;
}
+
+ if (block_obj->hw_ops->query_ras_error_status)
+ block_obj->hw_ops->query_ras_error_status(adev);
+
}
static void amdgpu_ras_query_err_status(struct amdgpu_device *adev)
@@ -2118,6 +2068,7 @@ int amdgpu_ras_recovery_init(struct amdgpu_device *adev)
mutex_init(&con->recovery_lock);
INIT_WORK(&con->recovery_work, amdgpu_ras_do_recovery);
atomic_set(&con->in_recovery, 0);
+ con->eeprom_control.bad_channel_bitmap = 0;
max_eeprom_records_count = amdgpu_ras_eeprom_max_record_count();
amdgpu_ras_validate_threshold(adev, max_eeprom_records_count);
@@ -2141,8 +2092,12 @@ int amdgpu_ras_recovery_init(struct amdgpu_device *adev)
if (ret)
goto free;
- if (adev->smu.ppt_funcs && adev->smu.ppt_funcs->send_hbm_bad_pages_num)
- adev->smu.ppt_funcs->send_hbm_bad_pages_num(&adev->smu, con->eeprom_control.ras_num_recs);
+ amdgpu_dpm_send_hbm_bad_pages_num(adev, con->eeprom_control.ras_num_recs);
+
+ if (con->update_channel_flag == true) {
+ amdgpu_dpm_send_hbm_bad_channel_flag(adev, con->eeprom_control.bad_channel_bitmap);
+ con->update_channel_flag = false;
+ }
}
#ifdef CONFIG_X86_MCE_AMD
@@ -2336,6 +2291,7 @@ int amdgpu_ras_init(struct amdgpu_device *adev)
goto release_con;
}
+ con->update_channel_flag = false;
con->features = 0;
INIT_LIST_HEAD(&con->head);
/* Might need get this flag from vbios. */
@@ -2348,24 +2304,27 @@ int amdgpu_ras_init(struct amdgpu_device *adev)
case CHIP_VEGA20:
case CHIP_ARCTURUS:
case CHIP_ALDEBARAN:
- if (!adev->gmc.xgmi.connected_to_cpu)
- adev->nbio.ras_funcs = &nbio_v7_4_ras_funcs;
+ if (!adev->gmc.xgmi.connected_to_cpu) {
+ adev->nbio.ras = &nbio_v7_4_ras;
+ amdgpu_ras_register_ras_block(adev, &adev->nbio.ras->ras_block);
+ adev->nbio.ras_if = &adev->nbio.ras->ras_block.ras_comm;
+ }
break;
default:
/* nbio ras is not available */
break;
}
- if (adev->nbio.ras_funcs &&
- adev->nbio.ras_funcs->init_ras_controller_interrupt) {
- r = adev->nbio.ras_funcs->init_ras_controller_interrupt(adev);
+ if (adev->nbio.ras &&
+ adev->nbio.ras->init_ras_controller_interrupt) {
+ r = adev->nbio.ras->init_ras_controller_interrupt(adev);
if (r)
goto release_con;
}
- if (adev->nbio.ras_funcs &&
- adev->nbio.ras_funcs->init_ras_err_event_athub_interrupt) {
- r = adev->nbio.ras_funcs->init_ras_err_event_athub_interrupt(adev);
+ if (adev->nbio.ras &&
+ adev->nbio.ras->init_ras_err_event_athub_interrupt) {
+ r = adev->nbio.ras->init_ras_err_event_athub_interrupt(adev);
if (r)
goto release_con;
}
@@ -2377,12 +2336,12 @@ int amdgpu_ras_init(struct amdgpu_device *adev)
}
else if (adev->df.funcs &&
adev->df.funcs->query_ras_poison_mode &&
- adev->umc.ras_funcs &&
- adev->umc.ras_funcs->query_ras_poison_mode) {
+ adev->umc.ras &&
+ adev->umc.ras->query_ras_poison_mode) {
df_poison =
adev->df.funcs->query_ras_poison_mode(adev);
umc_poison =
- adev->umc.ras_funcs->query_ras_poison_mode(adev);
+ adev->umc.ras->query_ras_poison_mode(adev);
/* Only poison is set in both DF and UMC, we can support it */
if (df_poison && umc_poison)
con->poison_supported = true;
@@ -2445,11 +2404,10 @@ bool amdgpu_ras_is_poison_mode_supported(struct amdgpu_device *adev)
}
/* helper function to handle common stuff in ip late init phase */
-int amdgpu_ras_late_init(struct amdgpu_device *adev,
- struct ras_common_if *ras_block,
- struct ras_fs_if *fs_info,
- struct ras_ih_if *ih_info)
+int amdgpu_ras_block_late_init(struct amdgpu_device *adev,
+ struct ras_common_if *ras_block)
{
+ struct amdgpu_ras_block_object *ras_obj = NULL;
struct amdgpu_ras *con = amdgpu_ras_get_context(adev);
unsigned long ue_count, ce_count;
int r;
@@ -2477,15 +2435,16 @@ int amdgpu_ras_late_init(struct amdgpu_device *adev,
if (adev->in_suspend || amdgpu_in_reset(adev))
return 0;
- if (ih_info->cb) {
- r = amdgpu_ras_interrupt_add_handler(adev, ih_info);
+ ras_obj = container_of(ras_block, struct amdgpu_ras_block_object, ras_comm);
+ if (ras_obj->ras_cb) {
+ r = amdgpu_ras_interrupt_add_handler(adev, ras_block);
if (r)
- goto interrupt;
+ goto cleanup;
}
- r = amdgpu_ras_sysfs_create(adev, fs_info);
+ r = amdgpu_ras_sysfs_create(adev, ras_block);
if (r)
- goto sysfs;
+ goto interrupt;
/* Those are the cached values at init.
*/
@@ -2495,27 +2454,40 @@ int amdgpu_ras_late_init(struct amdgpu_device *adev,
}
return 0;
-cleanup:
- amdgpu_ras_sysfs_remove(adev, ras_block);
-sysfs:
- if (ih_info->cb)
- amdgpu_ras_interrupt_remove_handler(adev, ih_info);
+
interrupt:
+ if (ras_obj->ras_cb)
+ amdgpu_ras_interrupt_remove_handler(adev, ras_block);
+cleanup:
amdgpu_ras_feature_enable(adev, ras_block, 0);
return r;
}
+static int amdgpu_ras_block_late_init_default(struct amdgpu_device *adev,
+ struct ras_common_if *ras_block)
+{
+ return amdgpu_ras_block_late_init(adev, ras_block);
+}
+
/* helper function to remove ras fs node and interrupt handler */
-void amdgpu_ras_late_fini(struct amdgpu_device *adev,
- struct ras_common_if *ras_block,
- struct ras_ih_if *ih_info)
+void amdgpu_ras_block_late_fini(struct amdgpu_device *adev,
+ struct ras_common_if *ras_block)
{
- if (!ras_block || !ih_info)
+ struct amdgpu_ras_block_object *ras_obj;
+ if (!ras_block)
return;
amdgpu_ras_sysfs_remove(adev, ras_block);
- if (ih_info->cb)
- amdgpu_ras_interrupt_remove_handler(adev, ih_info);
+
+ ras_obj = container_of(ras_block, struct amdgpu_ras_block_object, ras_comm);
+ if (ras_obj->ras_cb)
+ amdgpu_ras_interrupt_remove_handler(adev, ras_block);
+}
+
+static void amdgpu_ras_block_late_fini_default(struct amdgpu_device *adev,
+ struct ras_common_if *ras_block)
+{
+ return amdgpu_ras_block_late_fini(adev, ras_block);
}
/* do some init work after IP late init as dependence.
@@ -2568,6 +2540,33 @@ void amdgpu_ras_suspend(struct amdgpu_device *adev)
amdgpu_ras_disable_all_features(adev, 1);
}
+int amdgpu_ras_late_init(struct amdgpu_device *adev)
+{
+ struct amdgpu_ras_block_list *node, *tmp;
+ struct amdgpu_ras_block_object *obj;
+ int r;
+
+ list_for_each_entry_safe(node, tmp, &adev->ras_list, node) {
+ if (!node->ras_obj) {
+ dev_warn(adev->dev, "Warning: abnormal ras list node.\n");
+ continue;
+ }
+
+ obj = node->ras_obj;
+ if (obj->ras_late_init) {
+ r = obj->ras_late_init(adev, &obj->ras_comm);
+ if (r) {
+ dev_err(adev->dev, "%s failed to execute ras_late_init! ret:%d\n",
+ obj->ras_comm.name, r);
+ return r;
+ }
+ } else
+ amdgpu_ras_block_late_init_default(adev, &obj->ras_comm);
+ }
+
+ return 0;
+}
+
/* do some fini work before IP fini as dependence */
int amdgpu_ras_pre_fini(struct amdgpu_device *adev)
{
@@ -2585,11 +2584,28 @@ int amdgpu_ras_pre_fini(struct amdgpu_device *adev)
int amdgpu_ras_fini(struct amdgpu_device *adev)
{
+ struct amdgpu_ras_block_list *ras_node, *tmp;
+ struct amdgpu_ras_block_object *obj = NULL;
struct amdgpu_ras *con = amdgpu_ras_get_context(adev);
if (!adev->ras_enabled || !con)
return 0;
+ list_for_each_entry_safe(ras_node, tmp, &adev->ras_list, node) {
+ if (ras_node->ras_obj) {
+ obj = ras_node->ras_obj;
+ if (amdgpu_ras_is_supported(adev, obj->ras_comm.block) &&
+ obj->ras_fini)
+ obj->ras_fini(adev, &obj->ras_comm);
+ else
+ amdgpu_ras_block_late_fini_default(adev, &obj->ras_comm);
+ }
+
+ /* Clear ras blocks from ras_list and free ras block list node */
+ list_del(&ras_node->node);
+ kfree(ras_node);
+ }
+
amdgpu_ras_fs_fini(adev);
amdgpu_ras_interrupt_remove_all(adev);
@@ -2717,8 +2733,6 @@ static int amdgpu_bad_page_notifier(struct notifier_block *nb,
dev_info(adev->dev, "Uncorrectable error detected in UMC inst: %d, chan_idx: %d",
umc_inst, ch_inst);
- memset(&err_rec, 0x0, sizeof(struct eeprom_table_record));
-
/*
* Translate UMC channel address to Physical address
*/
@@ -2730,16 +2744,10 @@ static int amdgpu_bad_page_notifier(struct notifier_block *nb,
ADDR_OF_256B_BLOCK(channel_index) |
OFFSET_IN_256B_BLOCK(m->addr);
- err_rec.address = m->addr;
- err_rec.retired_page = retired_page >> AMDGPU_GPU_PAGE_SHIFT;
- err_rec.ts = (uint64_t)ktime_get_real_seconds();
- err_rec.err_type = AMDGPU_RAS_EEPROM_ERR_NON_RECOVERABLE;
- err_rec.cu = 0;
- err_rec.mem_channel = channel_index;
- err_rec.mcumc_id = umc_inst;
-
+ memset(&err_rec, 0x0, sizeof(struct eeprom_table_record));
err_data.err_addr = &err_rec;
- err_data.err_addr_cnt = 1;
+ amdgpu_umc_fill_error_record(&err_data, m->addr,
+ retired_page, channel_index, umc_inst);
if (amdgpu_bad_page_threshold != 0) {
amdgpu_ras_add_bad_pages(adev, err_data.err_addr,
@@ -2777,3 +2785,63 @@ static void amdgpu_register_bad_pages_mca_notifier(struct amdgpu_device *adev)
}
}
#endif
+
+struct amdgpu_ras *amdgpu_ras_get_context(struct amdgpu_device *adev)
+{
+ if (!adev)
+ return NULL;
+
+ return adev->psp.ras_context.ras;
+}
+
+int amdgpu_ras_set_context(struct amdgpu_device *adev, struct amdgpu_ras *ras_con)
+{
+ if (!adev)
+ return -EINVAL;
+
+ adev->psp.ras_context.ras = ras_con;
+ return 0;
+}
+
+/* check if ras is supported on block, say, sdma, gfx */
+int amdgpu_ras_is_supported(struct amdgpu_device *adev,
+ unsigned int block)
+{
+ struct amdgpu_ras *ras = amdgpu_ras_get_context(adev);
+
+ if (block >= AMDGPU_RAS_BLOCK_COUNT)
+ return 0;
+ return ras && (adev->ras_enabled & (1 << block));
+}
+
+int amdgpu_ras_reset_gpu(struct amdgpu_device *adev)
+{
+ struct amdgpu_ras *ras = amdgpu_ras_get_context(adev);
+
+ if (atomic_cmpxchg(&ras->in_recovery, 0, 1) == 0)
+ schedule_work(&ras->recovery_work);
+ return 0;
+}
+
+
+/* Register each ip ras block into amdgpu ras */
+int amdgpu_ras_register_ras_block(struct amdgpu_device *adev,
+ struct amdgpu_ras_block_object *ras_block_obj)
+{
+ struct amdgpu_ras_block_list *ras_node;
+ if (!adev || !ras_block_obj)
+ return -EINVAL;
+
+ if (!amdgpu_ras_asic_supported(adev))
+ return 0;
+
+ ras_node = kzalloc(sizeof(*ras_node), GFP_KERNEL);
+ if (!ras_node)
+ return -ENOMEM;
+
+ INIT_LIST_HEAD(&ras_node->node);
+ ras_node->ras_obj = ras_block_obj;
+ list_add_tail(&ras_node->node, &adev->ras_list);
+
+ return 0;
+}
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.h
index 1c708122d492..9314fde81e68 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.h
@@ -26,11 +26,11 @@
#include <linux/debugfs.h>
#include <linux/list.h>
-#include "amdgpu.h"
-#include "amdgpu_psp.h"
#include "ta_ras_if.h"
#include "amdgpu_ras_eeprom.h"
+struct amdgpu_iv_entry;
+
#define AMDGPU_RAS_FLAG_INIT_BY_VBIOS (0x1 << 0)
enum amdgpu_ras_block {
@@ -374,6 +374,9 @@ struct amdgpu_ras {
/* record umc error info queried from smu */
struct umc_ecc_info umc_ecc;
+
+ /* Indicates smu whether need update bad channel info */
+ bool update_channel_flag;
};
struct ras_fs_data {
@@ -484,6 +487,27 @@ struct ras_debug_if {
};
int op;
};
+
+struct amdgpu_ras_block_object {
+ struct ras_common_if ras_comm;
+
+ int (*ras_block_match)(struct amdgpu_ras_block_object *block_obj,
+ enum amdgpu_ras_block block, uint32_t sub_block_index);
+ int (*ras_late_init)(struct amdgpu_device *adev, struct ras_common_if *ras_block);
+ void (*ras_fini)(struct amdgpu_device *adev, struct ras_common_if *ras_block);
+ ras_ih_cb ras_cb;
+ const struct amdgpu_ras_block_hw_ops *hw_ops;
+};
+
+struct amdgpu_ras_block_hw_ops {
+ int (*ras_error_inject)(struct amdgpu_device *adev, void *inject_if);
+ void (*query_ras_error_count)(struct amdgpu_device *adev, void *ras_error_status);
+ void (*query_ras_error_status)(struct amdgpu_device *adev);
+ void (*query_ras_error_address)(struct amdgpu_device *adev, void *ras_error_status);
+ void (*reset_ras_error_count)(struct amdgpu_device *adev);
+ void (*reset_ras_error_status)(struct amdgpu_device *adev);
+};
+
/* work flow
* vbios
* 1: ras feature enable (enabled by default)
@@ -498,19 +522,6 @@ struct ras_debug_if {
* 8: feature disable
*/
-#define amdgpu_ras_get_context(adev) ((adev)->psp.ras_context.ras)
-#define amdgpu_ras_set_context(adev, ras_con) ((adev)->psp.ras_context.ras = (ras_con))
-
-/* check if ras is supported on block, say, sdma, gfx */
-static inline int amdgpu_ras_is_supported(struct amdgpu_device *adev,
- unsigned int block)
-{
- struct amdgpu_ras *ras = amdgpu_ras_get_context(adev);
-
- if (block >= AMDGPU_RAS_BLOCK_COUNT)
- return 0;
- return ras && (adev->ras_enabled & (1 << block));
-}
int amdgpu_ras_recovery_init(struct amdgpu_device *adev);
@@ -527,15 +538,6 @@ int amdgpu_ras_add_bad_pages(struct amdgpu_device *adev,
int amdgpu_ras_save_bad_pages(struct amdgpu_device *adev);
-static inline int amdgpu_ras_reset_gpu(struct amdgpu_device *adev)
-{
- struct amdgpu_ras *ras = amdgpu_ras_get_context(adev);
-
- if (atomic_cmpxchg(&ras->in_recovery, 0, 1) == 0)
- schedule_work(&ras->recovery_work);
- return 0;
-}
-
static inline enum ta_ras_block
amdgpu_ras_block_to_ta(enum amdgpu_ras_block block) {
switch (block) {
@@ -596,15 +598,15 @@ amdgpu_ras_error_to_ta(enum amdgpu_ras_error_type error) {
/* called in ip_init and ip_fini */
int amdgpu_ras_init(struct amdgpu_device *adev);
+int amdgpu_ras_late_init(struct amdgpu_device *adev);
int amdgpu_ras_fini(struct amdgpu_device *adev);
int amdgpu_ras_pre_fini(struct amdgpu_device *adev);
-int amdgpu_ras_late_init(struct amdgpu_device *adev,
- struct ras_common_if *ras_block,
- struct ras_fs_if *fs_info,
- struct ras_ih_if *ih_info);
-void amdgpu_ras_late_fini(struct amdgpu_device *adev,
- struct ras_common_if *ras_block,
- struct ras_ih_if *ih_info);
+
+int amdgpu_ras_block_late_init(struct amdgpu_device *adev,
+ struct ras_common_if *ras_block);
+
+void amdgpu_ras_block_late_fini(struct amdgpu_device *adev,
+ struct ras_common_if *ras_block);
int amdgpu_ras_feature_enable(struct amdgpu_device *adev,
struct ras_common_if *head, bool enable);
@@ -613,7 +615,7 @@ int amdgpu_ras_feature_enable_on_boot(struct amdgpu_device *adev,
struct ras_common_if *head, bool enable);
int amdgpu_ras_sysfs_create(struct amdgpu_device *adev,
- struct ras_fs_if *head);
+ struct ras_common_if *head);
int amdgpu_ras_sysfs_remove(struct amdgpu_device *adev,
struct ras_common_if *head);
@@ -630,10 +632,10 @@ int amdgpu_ras_error_inject(struct amdgpu_device *adev,
struct ras_inject_if *info);
int amdgpu_ras_interrupt_add_handler(struct amdgpu_device *adev,
- struct ras_ih_if *info);
+ struct ras_common_if *head);
int amdgpu_ras_interrupt_remove_handler(struct amdgpu_device *adev,
- struct ras_ih_if *info);
+ struct ras_common_if *head);
int amdgpu_ras_interrupt_dispatch(struct amdgpu_device *adev,
struct ras_dispatch_if *info);
@@ -667,4 +669,14 @@ const char *get_ras_block_str(struct ras_common_if *ras_block);
bool amdgpu_ras_is_poison_mode_supported(struct amdgpu_device *adev);
+int amdgpu_ras_is_supported(struct amdgpu_device *adev, unsigned int block);
+
+int amdgpu_ras_reset_gpu(struct amdgpu_device *adev);
+
+struct amdgpu_ras* amdgpu_ras_get_context(struct amdgpu_device *adev);
+
+int amdgpu_ras_set_context(struct amdgpu_device *adev, struct amdgpu_ras *ras_con);
+
+int amdgpu_ras_register_ras_block(struct amdgpu_device *adev,
+ struct amdgpu_ras_block_object *ras_block_obj);
#endif
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras_eeprom.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras_eeprom.c
index 05117eda105b..c4283987bb1e 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras_eeprom.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras_eeprom.c
@@ -31,6 +31,8 @@
#include <linux/debugfs.h>
#include <linux/uaccess.h>
+#include "amdgpu_reset.h"
+
#define EEPROM_I2C_MADDR_VEGA20 0x0
#define EEPROM_I2C_MADDR_ARCTURUS 0x40000
#define EEPROM_I2C_MADDR_ARCTURUS_D342 0x0
@@ -193,12 +195,12 @@ static int __write_table_header(struct amdgpu_ras_eeprom_control *control)
__encode_table_header_to_buf(&control->tbl_hdr, buf);
/* i2c may be unstable in gpu reset */
- down_read(&adev->reset_sem);
- res = amdgpu_eeprom_write(&adev->pm.smu_i2c,
+ down_read(&adev->reset_domain->sem);
+ res = amdgpu_eeprom_write(adev->pm.ras_eeprom_i2c_bus,
control->i2c_address +
control->ras_header_offset,
buf, RAS_TABLE_HEADER_SIZE);
- up_read(&adev->reset_sem);
+ up_read(&adev->reset_domain->sem);
if (res < 0) {
DRM_ERROR("Failed to write EEPROM table header:%d", res);
@@ -263,7 +265,9 @@ static int amdgpu_ras_eeprom_correct_header_tag(
*/
int amdgpu_ras_eeprom_reset_table(struct amdgpu_ras_eeprom_control *control)
{
+ struct amdgpu_device *adev = to_amdgpu_device(control);
struct amdgpu_ras_eeprom_table_header *hdr = &control->tbl_hdr;
+ struct amdgpu_ras *con = amdgpu_ras_get_context(adev);
u8 csum;
int res;
@@ -282,6 +286,12 @@ int amdgpu_ras_eeprom_reset_table(struct amdgpu_ras_eeprom_control *control)
control->ras_num_recs = 0;
control->ras_fri = 0;
+ amdgpu_dpm_send_hbm_bad_pages_num(adev, control->ras_num_recs);
+
+ control->bad_channel_bitmap = 0;
+ amdgpu_dpm_send_hbm_bad_channel_flag(adev, control->bad_channel_bitmap);
+ con->update_channel_flag = false;
+
amdgpu_ras_debugfs_set_ret_size(control);
mutex_unlock(&control->ras_tbl_mutex);
@@ -387,13 +397,13 @@ static int __amdgpu_ras_eeprom_write(struct amdgpu_ras_eeprom_control *control,
int res;
/* i2c may be unstable in gpu reset */
- down_read(&adev->reset_sem);
+ down_read(&adev->reset_domain->sem);
buf_size = num * RAS_TABLE_RECORD_SIZE;
- res = amdgpu_eeprom_write(&adev->pm.smu_i2c,
+ res = amdgpu_eeprom_write(adev->pm.ras_eeprom_i2c_bus,
control->i2c_address +
RAS_INDEX_TO_OFFSET(control, fri),
buf, buf_size);
- up_read(&adev->reset_sem);
+ up_read(&adev->reset_domain->sem);
if (res < 0) {
DRM_ERROR("Writing %d EEPROM table records error:%d",
num, res);
@@ -415,6 +425,7 @@ amdgpu_ras_eeprom_append_table(struct amdgpu_ras_eeprom_control *control,
struct eeprom_table_record *record,
const u32 num)
{
+ struct amdgpu_ras *con = amdgpu_ras_get_context(to_amdgpu_device(control));
u32 a, b, i;
u8 *buf, *pp;
int res;
@@ -426,9 +437,16 @@ amdgpu_ras_eeprom_append_table(struct amdgpu_ras_eeprom_control *control,
/* Encode all of them in one go.
*/
pp = buf;
- for (i = 0; i < num; i++, pp += RAS_TABLE_RECORD_SIZE)
+ for (i = 0; i < num; i++, pp += RAS_TABLE_RECORD_SIZE) {
__encode_table_record_to_buf(control, &record[i], pp);
+ /* update bad channel bitmap */
+ if (!(control->bad_channel_bitmap & (1 << record[i].mem_channel))) {
+ control->bad_channel_bitmap |= 1 << record[i].mem_channel;
+ con->update_channel_flag = true;
+ }
+ }
+
/* a, first record index to write into.
* b, last record index to write into.
* a = first index to read (fri) + number of records in the table,
@@ -547,12 +565,12 @@ amdgpu_ras_eeprom_update_header(struct amdgpu_ras_eeprom_control *control)
goto Out;
}
- down_read(&adev->reset_sem);
- res = amdgpu_eeprom_read(&adev->pm.smu_i2c,
+ down_read(&adev->reset_domain->sem);
+ res = amdgpu_eeprom_read(adev->pm.ras_eeprom_i2c_bus,
control->i2c_address +
control->ras_record_offset,
buf, buf_size);
- up_read(&adev->reset_sem);
+ up_read(&adev->reset_domain->sem);
if (res < 0) {
DRM_ERROR("EEPROM failed reading records:%d\n",
res);
@@ -642,13 +660,13 @@ static int __amdgpu_ras_eeprom_read(struct amdgpu_ras_eeprom_control *control,
int res;
/* i2c may be unstable in gpu reset */
- down_read(&adev->reset_sem);
+ down_read(&adev->reset_domain->sem);
buf_size = num * RAS_TABLE_RECORD_SIZE;
- res = amdgpu_eeprom_read(&adev->pm.smu_i2c,
+ res = amdgpu_eeprom_read(adev->pm.ras_eeprom_i2c_bus,
control->i2c_address +
RAS_INDEX_TO_OFFSET(control, fri),
buf, buf_size);
- up_read(&adev->reset_sem);
+ up_read(&adev->reset_domain->sem);
if (res < 0) {
DRM_ERROR("Reading %d EEPROM table records error:%d",
num, res);
@@ -681,6 +699,7 @@ int amdgpu_ras_eeprom_read(struct amdgpu_ras_eeprom_control *control,
const u32 num)
{
struct amdgpu_device *adev = to_amdgpu_device(control);
+ struct amdgpu_ras *con = amdgpu_ras_get_context(adev);
int i, res;
u8 *buf, *pp;
u32 g0, g1;
@@ -748,8 +767,15 @@ int amdgpu_ras_eeprom_read(struct amdgpu_ras_eeprom_control *control,
/* Read up everything? Then transform.
*/
pp = buf;
- for (i = 0; i < num; i++, pp += RAS_TABLE_RECORD_SIZE)
+ for (i = 0; i < num; i++, pp += RAS_TABLE_RECORD_SIZE) {
__decode_table_record_from_buf(control, &record[i], pp);
+
+ /* update bad channel bitmap */
+ if (!(control->bad_channel_bitmap & (1 << record[i].mem_channel))) {
+ control->bad_channel_bitmap |= 1 << record[i].mem_channel;
+ con->update_channel_flag = true;
+ }
+ }
Out:
kfree(buf);
mutex_unlock(&control->ras_tbl_mutex);
@@ -1009,7 +1035,7 @@ static int __verify_ras_table_checksum(struct amdgpu_ras_eeprom_control *control
return -ENOMEM;
}
- res = amdgpu_eeprom_read(&adev->pm.smu_i2c,
+ res = amdgpu_eeprom_read(adev->pm.ras_eeprom_i2c_bus,
control->i2c_address +
control->ras_header_offset,
buf, buf_size);
@@ -1045,7 +1071,7 @@ int amdgpu_ras_eeprom_init(struct amdgpu_ras_eeprom_control *control,
return 0;
/* Verify i2c adapter is initialized */
- if (!adev->pm.smu_i2c.algo)
+ if (!adev->pm.ras_eeprom_i2c_bus || !adev->pm.ras_eeprom_i2c_bus->algo)
return -ENOENT;
if (!__get_eeprom_i2c_addr(adev, control))
@@ -1057,7 +1083,7 @@ int amdgpu_ras_eeprom_init(struct amdgpu_ras_eeprom_control *control,
mutex_init(&control->ras_tbl_mutex);
/* Read the table header from EEPROM address */
- res = amdgpu_eeprom_read(&adev->pm.smu_i2c,
+ res = amdgpu_eeprom_read(adev->pm.ras_eeprom_i2c_bus,
control->i2c_address + control->ras_header_offset,
buf, RAS_TABLE_HEADER_SIZE);
if (res < RAS_TABLE_HEADER_SIZE) {
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras_eeprom.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras_eeprom.h
index 6bb00578bfbb..54d9bfe0881d 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras_eeprom.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras_eeprom.h
@@ -80,6 +80,10 @@ struct amdgpu_ras_eeprom_control {
/* Protect table access via this mutex.
*/
struct mutex ras_tbl_mutex;
+
+ /* Record channel info which occurred bad pages
+ */
+ u32 bad_channel_bitmap;
};
/*
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_reset.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_reset.c
index 02afd4115675..c80af0889773 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_reset.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_reset.c
@@ -36,8 +36,8 @@ int amdgpu_reset_init(struct amdgpu_device *adev)
{
int ret = 0;
- switch (adev->asic_type) {
- case CHIP_ALDEBARAN:
+ switch (adev->ip_versions[MP1_HWIP][0]) {
+ case IP_VERSION(13, 0, 2):
ret = aldebaran_reset_init(adev);
break;
default:
@@ -51,8 +51,8 @@ int amdgpu_reset_fini(struct amdgpu_device *adev)
{
int ret = 0;
- switch (adev->asic_type) {
- case CHIP_ALDEBARAN:
+ switch (adev->ip_versions[MP1_HWIP][0]) {
+ case IP_VERSION(13, 0, 2):
ret = aldebaran_reset_fini(adev);
break;
default:
@@ -96,3 +96,59 @@ int amdgpu_reset_perform_reset(struct amdgpu_device *adev,
return reset_handler->restore_hwcontext(adev->reset_cntl,
reset_context);
}
+
+
+void amdgpu_reset_destroy_reset_domain(struct kref *ref)
+{
+ struct amdgpu_reset_domain *reset_domain = container_of(ref,
+ struct amdgpu_reset_domain,
+ refcount);
+ if (reset_domain->wq)
+ destroy_workqueue(reset_domain->wq);
+
+ kvfree(reset_domain);
+}
+
+struct amdgpu_reset_domain *amdgpu_reset_create_reset_domain(enum amdgpu_reset_domain_type type,
+ char *wq_name)
+{
+ struct amdgpu_reset_domain *reset_domain;
+
+ reset_domain = kvzalloc(sizeof(struct amdgpu_reset_domain), GFP_KERNEL);
+ if (!reset_domain) {
+ DRM_ERROR("Failed to allocate amdgpu_reset_domain!");
+ return NULL;
+ }
+
+ reset_domain->type = type;
+ kref_init(&reset_domain->refcount);
+
+ reset_domain->wq = create_singlethread_workqueue(wq_name);
+ if (!reset_domain->wq) {
+ DRM_ERROR("Failed to allocate wq for amdgpu_reset_domain!");
+ amdgpu_reset_put_reset_domain(reset_domain);
+ return NULL;
+
+ }
+
+ atomic_set(&reset_domain->in_gpu_reset, 0);
+ init_rwsem(&reset_domain->sem);
+
+ return reset_domain;
+}
+
+void amdgpu_device_lock_reset_domain(struct amdgpu_reset_domain *reset_domain)
+{
+ atomic_set(&reset_domain->in_gpu_reset, 1);
+ down_write(&reset_domain->sem);
+}
+
+
+void amdgpu_device_unlock_reset_domain(struct amdgpu_reset_domain *reset_domain)
+{
+ atomic_set(&reset_domain->in_gpu_reset, 0);
+ up_write(&reset_domain->sem);
+}
+
+
+
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_reset.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_reset.h
index e00d38d9160a..1949dbe28a86 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_reset.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_reset.h
@@ -70,6 +70,21 @@ struct amdgpu_reset_control {
void (*async_reset)(struct work_struct *work);
};
+
+enum amdgpu_reset_domain_type {
+ SINGLE_DEVICE,
+ XGMI_HIVE
+};
+
+struct amdgpu_reset_domain {
+ struct kref refcount;
+ struct workqueue_struct *wq;
+ enum amdgpu_reset_domain_type type;
+ struct rw_semaphore sem;
+ atomic_t in_gpu_reset;
+};
+
+
int amdgpu_reset_init(struct amdgpu_device *adev);
int amdgpu_reset_fini(struct amdgpu_device *adev);
@@ -82,4 +97,29 @@ int amdgpu_reset_perform_reset(struct amdgpu_device *adev,
int amdgpu_reset_add_handler(struct amdgpu_reset_control *reset_ctl,
struct amdgpu_reset_handler *handler);
+struct amdgpu_reset_domain *amdgpu_reset_create_reset_domain(enum amdgpu_reset_domain_type type,
+ char *wq_name);
+
+void amdgpu_reset_destroy_reset_domain(struct kref *ref);
+
+static inline bool amdgpu_reset_get_reset_domain(struct amdgpu_reset_domain *domain)
+{
+ return kref_get_unless_zero(&domain->refcount) != 0;
+}
+
+static inline void amdgpu_reset_put_reset_domain(struct amdgpu_reset_domain *domain)
+{
+ kref_put(&domain->refcount, amdgpu_reset_destroy_reset_domain);
+}
+
+static inline bool amdgpu_reset_domain_schedule(struct amdgpu_reset_domain *domain,
+ struct work_struct *work)
+{
+ return queue_work(domain->wq, work);
+}
+
+void amdgpu_device_lock_reset_domain(struct amdgpu_reset_domain *reset_domain);
+
+void amdgpu_device_unlock_reset_domain(struct amdgpu_reset_domain *reset_domain);
+
#endif
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c
index ab2351ba9574..7f33ae87cb41 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c
@@ -191,8 +191,10 @@ int amdgpu_ring_init(struct amdgpu_device *adev, struct amdgpu_ring *ring,
ring->adev = adev;
ring->idx = adev->num_rings++;
adev->rings[ring->idx] = ring;
- r = amdgpu_fence_driver_init_ring(ring, sched_hw_submission,
- sched_score);
+ ring->num_hw_submission = sched_hw_submission;
+ ring->sched_score = sched_score;
+ ring->vmid_wait = dma_fence_get_stub();
+ r = amdgpu_fence_driver_init_ring(ring);
if (r)
return r;
}
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h
index fae7d185ad0d..5320bb0883d8 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h
@@ -28,6 +28,13 @@
#include <drm/gpu_scheduler.h>
#include <drm/drm_print.h>
+struct amdgpu_device;
+struct amdgpu_ring;
+struct amdgpu_ib;
+struct amdgpu_cs_parser;
+struct amdgpu_job;
+struct amdgpu_vm;
+
/* max number of rings */
#define AMDGPU_MAX_RINGS 28
#define AMDGPU_MAX_HWIP_RINGS 8
@@ -82,11 +89,13 @@ enum amdgpu_ib_pool_type {
AMDGPU_IB_POOL_MAX
};
-struct amdgpu_device;
-struct amdgpu_ring;
-struct amdgpu_ib;
-struct amdgpu_cs_parser;
-struct amdgpu_job;
+struct amdgpu_ib {
+ struct amdgpu_sa_bo *sa_bo;
+ uint32_t length_dw;
+ uint64_t gpu_addr;
+ uint32_t *ptr;
+ uint32_t flags;
+};
struct amdgpu_sched {
u32 num_scheds;
@@ -111,12 +120,12 @@ struct amdgpu_fence_driver {
struct dma_fence **fences;
};
+extern const struct drm_sched_backend_ops amdgpu_sched_ops;
+
void amdgpu_fence_driver_clear_job_fences(struct amdgpu_ring *ring);
void amdgpu_fence_driver_force_completion(struct amdgpu_ring *ring);
-int amdgpu_fence_driver_init_ring(struct amdgpu_ring *ring,
- unsigned num_hw_submission,
- atomic_t *sched_score);
+int amdgpu_fence_driver_init_ring(struct amdgpu_ring *ring);
int amdgpu_fence_driver_start_ring(struct amdgpu_ring *ring,
struct amdgpu_irq_src *irq_src,
unsigned irq_type);
@@ -146,6 +155,7 @@ struct amdgpu_ring_funcs {
u32 nop;
bool support_64bit_ptrs;
bool no_user_fence;
+ bool secure_submission_supported;
unsigned vmhub;
unsigned extra_dw;
@@ -154,8 +164,12 @@ struct amdgpu_ring_funcs {
u64 (*get_wptr)(struct amdgpu_ring *ring);
void (*set_wptr)(struct amdgpu_ring *ring);
/* validating and patching of IBs */
- int (*parse_cs)(struct amdgpu_cs_parser *p, uint32_t ib_idx);
- int (*patch_cs_in_place)(struct amdgpu_cs_parser *p, uint32_t ib_idx);
+ int (*parse_cs)(struct amdgpu_cs_parser *p,
+ struct amdgpu_job *job,
+ struct amdgpu_ib *ib);
+ int (*patch_cs_in_place)(struct amdgpu_cs_parser *p,
+ struct amdgpu_job *job,
+ struct amdgpu_ib *ib);
/* constants to calculate how many DW are needed for an emit */
unsigned emit_frame_size;
unsigned emit_ib_size;
@@ -251,10 +265,12 @@ struct amdgpu_ring {
bool has_compute_vm_bug;
bool no_scheduler;
int hw_prio;
+ unsigned num_hw_submission;
+ atomic_t *sched_score;
};
-#define amdgpu_ring_parse_cs(r, p, ib) ((r)->funcs->parse_cs((p), (ib)))
-#define amdgpu_ring_patch_cs_in_place(r, p, ib) ((r)->funcs->patch_cs_in_place((p), (ib)))
+#define amdgpu_ring_parse_cs(r, p, job, ib) ((r)->funcs->parse_cs((p), (job), (ib)))
+#define amdgpu_ring_patch_cs_in_place(r, p, job, ib) ((r)->funcs->patch_cs_in_place((p), (job), (ib)))
#define amdgpu_ring_test_ring(r) (r)->funcs->test_ring((r))
#define amdgpu_ring_test_ib(r, t) (r)->funcs->test_ib((r), (t))
#define amdgpu_ring_get_rptr(r) (r)->funcs->get_rptr((r))
@@ -352,4 +368,29 @@ int amdgpu_ring_test_helper(struct amdgpu_ring *ring);
void amdgpu_debugfs_ring_init(struct amdgpu_device *adev,
struct amdgpu_ring *ring);
+
+static inline u32 amdgpu_ib_get_value(struct amdgpu_ib *ib, int idx)
+{
+ return ib->ptr[idx];
+}
+
+static inline void amdgpu_ib_set_value(struct amdgpu_ib *ib, int idx,
+ uint32_t value)
+{
+ ib->ptr[idx] = value;
+}
+
+int amdgpu_ib_get(struct amdgpu_device *adev, struct amdgpu_vm *vm,
+ unsigned size,
+ enum amdgpu_ib_pool_type pool,
+ struct amdgpu_ib *ib);
+void amdgpu_ib_free(struct amdgpu_device *adev, struct amdgpu_ib *ib,
+ struct dma_fence *f);
+int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs,
+ struct amdgpu_ib *ibs, struct amdgpu_job *job,
+ struct dma_fence **f);
+int amdgpu_ib_pool_init(struct amdgpu_device *adev);
+void amdgpu_ib_pool_fini(struct amdgpu_device *adev);
+int amdgpu_ib_ring_tests(struct amdgpu_device *adev);
+
#endif
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_rlc.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_rlc.h
index 00afd0dcae86..3f671a62b009 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_rlc.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_rlc.h
@@ -127,11 +127,19 @@ struct amdgpu_rlc_funcs {
void (*reset)(struct amdgpu_device *adev);
void (*start)(struct amdgpu_device *adev);
void (*update_spm_vmid)(struct amdgpu_device *adev, unsigned vmid);
- void (*sriov_wreg)(struct amdgpu_device *adev, u32 offset, u32 v, u32 acc_flags, u32 hwip);
- u32 (*sriov_rreg)(struct amdgpu_device *adev, u32 offset, u32 acc_flags, u32 hwip);
bool (*is_rlcg_access_range)(struct amdgpu_device *adev, uint32_t reg);
};
+struct amdgpu_rlcg_reg_access_ctrl {
+ uint32_t scratch_reg0;
+ uint32_t scratch_reg1;
+ uint32_t scratch_reg2;
+ uint32_t scratch_reg3;
+ uint32_t grbm_cntl;
+ uint32_t grbm_idx;
+ uint32_t spare_int;
+};
+
struct amdgpu_rlc {
/* for power gating */
struct amdgpu_bo *save_restore_obj;
@@ -191,6 +199,10 @@ struct amdgpu_rlc {
struct amdgpu_bo *rlc_toc_bo;
uint64_t rlc_toc_gpu_addr;
void *rlc_toc_buf;
+
+ bool rlcg_reg_access_supported;
+ /* registers for rlcg indirect reg access */
+ struct amdgpu_rlcg_reg_access_ctrl reg_access_ctrl;
};
void amdgpu_gfx_rlc_enter_safe_mode(struct amdgpu_device *adev);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.c
index 65debb65a5df..e1835fd4b237 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.c
@@ -87,73 +87,30 @@ uint64_t amdgpu_sdma_get_csa_mc_addr(struct amdgpu_ring *ring,
}
int amdgpu_sdma_ras_late_init(struct amdgpu_device *adev,
- void *ras_ih_info)
+ struct ras_common_if *ras_block)
{
int r, i;
- struct ras_ih_if *ih_info = (struct ras_ih_if *)ras_ih_info;
- struct ras_fs_if fs_info = {
- .sysfs_name = "sdma_err_count",
- };
-
- if (!ih_info)
- return -EINVAL;
-
- if (!adev->sdma.ras_if) {
- adev->sdma.ras_if = kmalloc(sizeof(struct ras_common_if), GFP_KERNEL);
- if (!adev->sdma.ras_if)
- return -ENOMEM;
- adev->sdma.ras_if->block = AMDGPU_RAS_BLOCK__SDMA;
- adev->sdma.ras_if->type = AMDGPU_RAS_ERROR__MULTI_UNCORRECTABLE;
- adev->sdma.ras_if->sub_block_index = 0;
- }
- fs_info.head = ih_info->head = *adev->sdma.ras_if;
- r = amdgpu_ras_late_init(adev, adev->sdma.ras_if,
- &fs_info, ih_info);
+ r = amdgpu_ras_block_late_init(adev, ras_block);
if (r)
- goto free;
+ return r;
- if (amdgpu_ras_is_supported(adev, adev->sdma.ras_if->block)) {
+ if (amdgpu_ras_is_supported(adev, ras_block->block)) {
for (i = 0; i < adev->sdma.num_instances; i++) {
r = amdgpu_irq_get(adev, &adev->sdma.ecc_irq,
AMDGPU_SDMA_IRQ_INSTANCE0 + i);
if (r)
goto late_fini;
}
- } else {
- r = 0;
- goto free;
}
return 0;
late_fini:
- amdgpu_ras_late_fini(adev, adev->sdma.ras_if, ih_info);
-free:
- kfree(adev->sdma.ras_if);
- adev->sdma.ras_if = NULL;
+ amdgpu_ras_block_late_fini(adev, ras_block);
return r;
}
-void amdgpu_sdma_ras_fini(struct amdgpu_device *adev)
-{
- if (amdgpu_ras_is_supported(adev, AMDGPU_RAS_BLOCK__SDMA) &&
- adev->sdma.ras_if) {
- struct ras_common_if *ras_if = adev->sdma.ras_if;
- struct ras_ih_if ih_info = {
- .head = *ras_if,
- /* the cb member will not be used by
- * amdgpu_ras_interrupt_remove_handler, init it only
- * to cheat the check in ras_late_fini
- */
- .cb = amdgpu_sdma_process_ras_data_cb,
- };
-
- amdgpu_ras_late_fini(adev, ras_if, &ih_info);
- kfree(ras_if);
- }
-}
-
int amdgpu_sdma_process_ras_data_cb(struct amdgpu_device *adev,
void *err_data,
struct amdgpu_iv_entry *entry)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.h
index f8fb755e3aa6..53ac3ebae8d6 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.h
@@ -23,6 +23,7 @@
#ifndef __AMDGPU_SDMA_H__
#define __AMDGPU_SDMA_H__
+#include "amdgpu_ras.h"
/* max number of IP instances */
#define AMDGPU_MAX_SDMA_INSTANCES 8
@@ -50,13 +51,8 @@ struct amdgpu_sdma_instance {
bool burst_nop;
};
-struct amdgpu_sdma_ras_funcs {
- int (*ras_late_init)(struct amdgpu_device *adev,
- void *ras_ih_info);
- void (*ras_fini)(struct amdgpu_device *adev);
- int (*query_ras_error_count)(struct amdgpu_device *adev,
- uint32_t instance, void *ras_error_status);
- void (*reset_ras_error_count)(struct amdgpu_device *adev);
+struct amdgpu_sdma_ras {
+ struct amdgpu_ras_block_object ras_block;
};
struct amdgpu_sdma {
@@ -73,7 +69,7 @@ struct amdgpu_sdma {
uint32_t srbm_soft_reset;
bool has_page_queue;
struct ras_common_if *ras_if;
- const struct amdgpu_sdma_ras_funcs *funcs;
+ struct amdgpu_sdma_ras *ras;
};
/*
@@ -121,8 +117,7 @@ amdgpu_sdma_get_instance_from_ring(struct amdgpu_ring *ring);
int amdgpu_sdma_get_index_from_ring(struct amdgpu_ring *ring, uint32_t *index);
uint64_t amdgpu_sdma_get_csa_mc_addr(struct amdgpu_ring *ring, unsigned vmid);
int amdgpu_sdma_ras_late_init(struct amdgpu_device *adev,
- void *ras_ih_info);
-void amdgpu_sdma_ras_fini(struct amdgpu_device *adev);
+ struct ras_common_if *ras_block);
int amdgpu_sdma_process_ras_data_cb(struct amdgpu_device *adev,
void *err_data,
struct amdgpu_iv_entry *entry);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c
index f7d8487799b2..40e06745fae9 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c
@@ -261,10 +261,9 @@ int amdgpu_sync_resv(struct amdgpu_device *adev, struct amdgpu_sync *sync,
dma_resv_for_each_fence(&cursor, resv, true, f) {
dma_fence_chain_for_each(f, f) {
- struct dma_fence_chain *chain = to_dma_fence_chain(f);
+ struct dma_fence *tmp = dma_fence_chain_contained(f);
- if (amdgpu_sync_test_fence(adev, mode, owner, chain ?
- chain->fence : f)) {
+ if (amdgpu_sync_test_fence(adev, mode, owner, tmp)) {
r = amdgpu_sync_fence(sync, f);
dma_fence_put(f);
if (r)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_test.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_test.c
deleted file mode 100644
index 909d830b513e..000000000000
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_test.c
+++ /dev/null
@@ -1,250 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0 OR MIT
-/*
- * Copyright 2009 VMware, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Authors: Michel Dänzer
- */
-
-#include <drm/amdgpu_drm.h>
-#include "amdgpu.h"
-#include "amdgpu_uvd.h"
-#include "amdgpu_vce.h"
-
-/* Test BO GTT->VRAM and VRAM->GTT GPU copies across the whole GTT aperture */
-static void amdgpu_do_test_moves(struct amdgpu_device *adev)
-{
- struct amdgpu_ring *ring = adev->mman.buffer_funcs_ring;
- struct amdgpu_bo *vram_obj = NULL;
- struct amdgpu_bo **gtt_obj = NULL;
- struct amdgpu_bo_param bp;
- uint64_t gart_addr, vram_addr;
- unsigned n, size;
- int i, r;
-
- size = 1024 * 1024;
-
- /* Number of tests =
- * (Total GTT - gart_pin_size - (2 transfer windows for buffer moves)) / test size
- */
- n = adev->gmc.gart_size - atomic64_read(&adev->gart_pin_size);
- n -= AMDGPU_GTT_MAX_TRANSFER_SIZE * AMDGPU_GTT_NUM_TRANSFER_WINDOWS *
- AMDGPU_GPU_PAGE_SIZE;
- n /= size;
-
- gtt_obj = kcalloc(n, sizeof(*gtt_obj), GFP_KERNEL);
- if (!gtt_obj) {
- DRM_ERROR("Failed to allocate %d pointers\n", n);
- r = 1;
- goto out_cleanup;
- }
- memset(&bp, 0, sizeof(bp));
- bp.size = size;
- bp.byte_align = PAGE_SIZE;
- bp.domain = AMDGPU_GEM_DOMAIN_VRAM;
- bp.flags = 0;
- bp.type = ttm_bo_type_kernel;
- bp.resv = NULL;
- bp.bo_ptr_size = sizeof(struct amdgpu_bo);
-
- r = amdgpu_bo_create(adev, &bp, &vram_obj);
- if (r) {
- DRM_ERROR("Failed to create VRAM object\n");
- goto out_cleanup;
- }
- r = amdgpu_bo_reserve(vram_obj, false);
- if (unlikely(r != 0))
- goto out_unref;
- r = amdgpu_bo_pin(vram_obj, AMDGPU_GEM_DOMAIN_VRAM);
- if (r) {
- DRM_ERROR("Failed to pin VRAM object\n");
- goto out_unres;
- }
- vram_addr = amdgpu_bo_gpu_offset(vram_obj);
- for (i = 0; i < n; i++) {
- void *gtt_map, *vram_map;
- void **gart_start, **gart_end;
- void **vram_start, **vram_end;
- struct dma_fence *fence = NULL;
-
- bp.domain = AMDGPU_GEM_DOMAIN_GTT;
- r = amdgpu_bo_create(adev, &bp, gtt_obj + i);
- if (r) {
- DRM_ERROR("Failed to create GTT object %d\n", i);
- goto out_lclean;
- }
-
- r = amdgpu_bo_reserve(gtt_obj[i], false);
- if (unlikely(r != 0))
- goto out_lclean_unref;
- r = amdgpu_bo_pin(gtt_obj[i], AMDGPU_GEM_DOMAIN_GTT);
- if (r) {
- DRM_ERROR("Failed to pin GTT object %d\n", i);
- goto out_lclean_unres;
- }
- r = amdgpu_ttm_alloc_gart(&gtt_obj[i]->tbo);
- if (r) {
- DRM_ERROR("%p bind failed\n", gtt_obj[i]);
- goto out_lclean_unpin;
- }
- gart_addr = amdgpu_bo_gpu_offset(gtt_obj[i]);
-
- r = amdgpu_bo_kmap(gtt_obj[i], &gtt_map);
- if (r) {
- DRM_ERROR("Failed to map GTT object %d\n", i);
- goto out_lclean_unpin;
- }
-
- for (gart_start = gtt_map, gart_end = gtt_map + size;
- gart_start < gart_end;
- gart_start++)
- *gart_start = gart_start;
-
- amdgpu_bo_kunmap(gtt_obj[i]);
-
- r = amdgpu_copy_buffer(ring, gart_addr, vram_addr,
- size, NULL, &fence, false, false, false);
-
- if (r) {
- DRM_ERROR("Failed GTT->VRAM copy %d\n", i);
- goto out_lclean_unpin;
- }
-
- r = dma_fence_wait(fence, false);
- if (r) {
- DRM_ERROR("Failed to wait for GTT->VRAM fence %d\n", i);
- goto out_lclean_unpin;
- }
-
- dma_fence_put(fence);
- fence = NULL;
-
- r = amdgpu_bo_kmap(vram_obj, &vram_map);
- if (r) {
- DRM_ERROR("Failed to map VRAM object after copy %d\n", i);
- goto out_lclean_unpin;
- }
-
- for (gart_start = gtt_map, gart_end = gtt_map + size,
- vram_start = vram_map, vram_end = vram_map + size;
- vram_start < vram_end;
- gart_start++, vram_start++) {
- if (*vram_start != gart_start) {
- DRM_ERROR("Incorrect GTT->VRAM copy %d: Got 0x%p, "
- "expected 0x%p (GTT/VRAM offset "
- "0x%16llx/0x%16llx)\n",
- i, *vram_start, gart_start,
- (unsigned long long)
- (gart_addr - adev->gmc.gart_start +
- (void *)gart_start - gtt_map),
- (unsigned long long)
- (vram_addr - adev->gmc.vram_start +
- (void *)gart_start - gtt_map));
- amdgpu_bo_kunmap(vram_obj);
- goto out_lclean_unpin;
- }
- *vram_start = vram_start;
- }
-
- amdgpu_bo_kunmap(vram_obj);
-
- r = amdgpu_copy_buffer(ring, vram_addr, gart_addr,
- size, NULL, &fence, false, false, false);
-
- if (r) {
- DRM_ERROR("Failed VRAM->GTT copy %d\n", i);
- goto out_lclean_unpin;
- }
-
- r = dma_fence_wait(fence, false);
- if (r) {
- DRM_ERROR("Failed to wait for VRAM->GTT fence %d\n", i);
- goto out_lclean_unpin;
- }
-
- dma_fence_put(fence);
- fence = NULL;
-
- r = amdgpu_bo_kmap(gtt_obj[i], &gtt_map);
- if (r) {
- DRM_ERROR("Failed to map GTT object after copy %d\n", i);
- goto out_lclean_unpin;
- }
-
- for (gart_start = gtt_map, gart_end = gtt_map + size,
- vram_start = vram_map, vram_end = vram_map + size;
- gart_start < gart_end;
- gart_start++, vram_start++) {
- if (*gart_start != vram_start) {
- DRM_ERROR("Incorrect VRAM->GTT copy %d: Got 0x%p, "
- "expected 0x%p (VRAM/GTT offset "
- "0x%16llx/0x%16llx)\n",
- i, *gart_start, vram_start,
- (unsigned long long)
- (vram_addr - adev->gmc.vram_start +
- (void *)vram_start - vram_map),
- (unsigned long long)
- (gart_addr - adev->gmc.gart_start +
- (void *)vram_start - vram_map));
- amdgpu_bo_kunmap(gtt_obj[i]);
- goto out_lclean_unpin;
- }
- }
-
- amdgpu_bo_kunmap(gtt_obj[i]);
-
- DRM_INFO("Tested GTT->VRAM and VRAM->GTT copy for GTT offset 0x%llx\n",
- gart_addr - adev->gmc.gart_start);
- continue;
-
-out_lclean_unpin:
- amdgpu_bo_unpin(gtt_obj[i]);
-out_lclean_unres:
- amdgpu_bo_unreserve(gtt_obj[i]);
-out_lclean_unref:
- amdgpu_bo_unref(&gtt_obj[i]);
-out_lclean:
- for (--i; i >= 0; --i) {
- amdgpu_bo_unpin(gtt_obj[i]);
- amdgpu_bo_unreserve(gtt_obj[i]);
- amdgpu_bo_unref(&gtt_obj[i]);
- }
- if (fence)
- dma_fence_put(fence);
- break;
- }
-
- amdgpu_bo_unpin(vram_obj);
-out_unres:
- amdgpu_bo_unreserve(vram_obj);
-out_unref:
- amdgpu_bo_unref(&vram_obj);
-out_cleanup:
- kfree(gtt_obj);
- if (r) {
- pr_warn("Error while testing BO move\n");
- }
-}
-
-void amdgpu_test_moves(struct amdgpu_device *adev)
-{
- if (adev->mman.buffer_funcs)
- amdgpu_do_test_moves(adev);
-}
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_trace.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_trace.h
index d855cb53c7e0..06dfcf297a8d 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_trace.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_trace.h
@@ -358,11 +358,10 @@ TRACE_EVENT(amdgpu_vm_update_ptes,
}
),
TP_printk("pid:%u vm_ctx:0x%llx start:0x%010llx end:0x%010llx,"
- " flags:0x%llx, incr:%llu, dst:\n%s%s", __entry->pid,
+ " flags:0x%llx, incr:%llu, dst:\n%s", __entry->pid,
__entry->vm_ctx, __entry->start, __entry->end,
__entry->flags, __entry->incr, __print_array(
- __get_dynamic_array(dst), min(__entry->nptes, 32u), 8),
- __entry->nptes > 32 ? "..." : "")
+ __get_dynamic_array(dst), __entry->nptes, 8))
);
TRACE_EVENT(amdgpu_vm_set_ptes,
@@ -537,6 +536,22 @@ TRACE_EVENT(amdgpu_ib_pipe_sync,
__entry->seqno)
);
+TRACE_EVENT(amdgpu_reset_reg_dumps,
+ TP_PROTO(uint32_t address, uint32_t value),
+ TP_ARGS(address, value),
+ TP_STRUCT__entry(
+ __field(uint32_t, address)
+ __field(uint32_t, value)
+ ),
+ TP_fast_assign(
+ __entry->address = address;
+ __entry->value = value;
+ ),
+ TP_printk("amdgpu register dump 0x%x: 0x%x",
+ __entry->address,
+ __entry->value)
+);
+
#undef AMDGPU_JOB_GET_TIMELINE_NAME
#endif
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_trace_points.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_trace_points.c
index 57c6c39ba064..b96d885f6e33 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_trace_points.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_trace_points.c
@@ -23,6 +23,7 @@
*/
#include <drm/amdgpu_drm.h>
+#include "amdgpu_cs.h"
#include "amdgpu.h"
#define CREATE_TRACE_POINTS
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
index 5c3f24069f2a..4b9ee6e27f74 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
@@ -50,6 +50,7 @@
#include <drm/ttm/ttm_range_manager.h>
#include <drm/amdgpu_drm.h>
+#include <drm/drm_drv.h>
#include "amdgpu.h"
#include "amdgpu_object.h"
@@ -170,10 +171,10 @@ static void amdgpu_evict_flags(struct ttm_buffer_object *bo,
* @bo: buffer object to map
* @mem: memory object to map
* @mm_cur: range to map
- * @num_pages: number of pages to map
* @window: which GART window to use
* @ring: DMA ring to use for the copy
* @tmz: if we should setup a TMZ enabled mapping
+ * @size: in number of bytes to map, out number of bytes mapped
* @addr: resulting address inside the MC address space
*
* Setup one of the GART windows to access a specific piece of memory or return
@@ -182,15 +183,14 @@ static void amdgpu_evict_flags(struct ttm_buffer_object *bo,
static int amdgpu_ttm_map_buffer(struct ttm_buffer_object *bo,
struct ttm_resource *mem,
struct amdgpu_res_cursor *mm_cur,
- unsigned num_pages, unsigned window,
- struct amdgpu_ring *ring, bool tmz,
- uint64_t *addr)
+ unsigned window, struct amdgpu_ring *ring,
+ bool tmz, uint64_t *size, uint64_t *addr)
{
struct amdgpu_device *adev = ring->adev;
- struct amdgpu_job *job;
- unsigned num_dw, num_bytes;
- struct dma_fence *fence;
+ unsigned offset, num_pages, num_dw, num_bytes;
uint64_t src_addr, dst_addr;
+ struct dma_fence *fence;
+ struct amdgpu_job *job;
void *cpu_addr;
uint64_t flags;
unsigned int i;
@@ -198,7 +198,9 @@ static int amdgpu_ttm_map_buffer(struct ttm_buffer_object *bo,
BUG_ON(adev->mman.buffer_funcs->copy_max_bytes <
AMDGPU_GTT_MAX_TRANSFER_SIZE * 8);
- BUG_ON(mem->mem_type == AMDGPU_PL_PREEMPT);
+
+ if (WARN_ON(mem->mem_type == AMDGPU_PL_PREEMPT))
+ return -EINVAL;
/* Map only what can't be accessed directly */
if (!tmz && mem->start != AMDGPU_BO_INVALID_OFFSET) {
@@ -207,10 +209,22 @@ static int amdgpu_ttm_map_buffer(struct ttm_buffer_object *bo,
return 0;
}
+
+ /*
+ * If start begins at an offset inside the page, then adjust the size
+ * and addr accordingly
+ */
+ offset = mm_cur->start & ~PAGE_MASK;
+
+ num_pages = PFN_UP(*size + offset);
+ num_pages = min_t(uint32_t, num_pages, AMDGPU_GTT_MAX_TRANSFER_SIZE);
+
+ *size = min(*size, (uint64_t)num_pages * PAGE_SIZE - offset);
+
*addr = adev->gmc.gart_start;
*addr += (u64)window * AMDGPU_GTT_MAX_TRANSFER_SIZE *
AMDGPU_GPU_PAGE_SIZE;
- *addr += mm_cur->start & ~PAGE_MASK;
+ *addr += offset;
num_dw = ALIGN(adev->mman.buffer_funcs->copy_num_dw, 8);
num_bytes = num_pages * 8 * AMDGPU_GPU_PAGES_IN_CPU_PAGE;
@@ -241,10 +255,7 @@ static int amdgpu_ttm_map_buffer(struct ttm_buffer_object *bo,
dma_addr_t *dma_addr;
dma_addr = &bo->ttm->dma_address[mm_cur->start >> PAGE_SHIFT];
- r = amdgpu_gart_map(adev, 0, num_pages, dma_addr, flags,
- cpu_addr);
- if (r)
- goto error_free;
+ amdgpu_gart_map(adev, 0, num_pages, dma_addr, flags, cpu_addr);
} else {
dma_addr_t dma_address;
@@ -252,11 +263,8 @@ static int amdgpu_ttm_map_buffer(struct ttm_buffer_object *bo,
dma_address += adev->vm_manager.vram_base_offset;
for (i = 0; i < num_pages; ++i) {
- r = amdgpu_gart_map(adev, i << PAGE_SHIFT, 1,
- &dma_address, flags, cpu_addr);
- if (r)
- goto error_free;
-
+ amdgpu_gart_map(adev, i << PAGE_SHIFT, 1, &dma_address,
+ flags, cpu_addr);
dma_address += PAGE_SIZE;
}
}
@@ -297,9 +305,6 @@ int amdgpu_ttm_copy_mem_to_mem(struct amdgpu_device *adev,
struct dma_resv *resv,
struct dma_fence **f)
{
- const uint32_t GTT_MAX_BYTES = (AMDGPU_GTT_MAX_TRANSFER_SIZE *
- AMDGPU_GPU_PAGE_SIZE);
-
struct amdgpu_ring *ring = adev->mman.buffer_funcs_ring;
struct amdgpu_res_cursor src_mm, dst_mm;
struct dma_fence *fence = NULL;
@@ -315,29 +320,20 @@ int amdgpu_ttm_copy_mem_to_mem(struct amdgpu_device *adev,
mutex_lock(&adev->mman.gtt_window_lock);
while (src_mm.remaining) {
- uint32_t src_page_offset = src_mm.start & ~PAGE_MASK;
- uint32_t dst_page_offset = dst_mm.start & ~PAGE_MASK;
+ uint64_t from, to, cur_size;
struct dma_fence *next;
- uint32_t cur_size;
- uint64_t from, to;
- /* Copy size cannot exceed GTT_MAX_BYTES. So if src or dst
- * begins at an offset, then adjust the size accordingly
- */
- cur_size = max(src_page_offset, dst_page_offset);
- cur_size = min(min3(src_mm.size, dst_mm.size, size),
- (uint64_t)(GTT_MAX_BYTES - cur_size));
+ /* Never copy more than 256MiB at once to avoid a timeout */
+ cur_size = min3(src_mm.size, dst_mm.size, 256ULL << 20);
/* Map src to window 0 and dst to window 1. */
r = amdgpu_ttm_map_buffer(src->bo, src->mem, &src_mm,
- PFN_UP(cur_size + src_page_offset),
- 0, ring, tmz, &from);
+ 0, ring, tmz, &cur_size, &from);
if (r)
goto error;
r = amdgpu_ttm_map_buffer(dst->bo, dst->mem, &dst_mm,
- PFN_UP(cur_size + dst_page_offset),
- 1, ring, tmz, &to);
+ 1, ring, tmz, &cur_size, &to);
if (r)
goto error;
@@ -396,8 +392,7 @@ static int amdgpu_move_blit(struct ttm_buffer_object *bo,
(abo->flags & AMDGPU_GEM_CREATE_VRAM_WIPE_ON_RELEASE)) {
struct dma_fence *wipe_fence = NULL;
- r = amdgpu_fill_buffer(ttm_to_amdgpu_bo(bo), AMDGPU_POISON,
- NULL, &wipe_fence);
+ r = amdgpu_fill_buffer(abo, AMDGPU_POISON, NULL, &wipe_fence);
if (r) {
goto error;
} else if (wipe_fence) {
@@ -821,14 +816,13 @@ static void amdgpu_ttm_tt_unpin_userptr(struct ttm_device *bdev,
#endif
}
-static int amdgpu_ttm_gart_bind(struct amdgpu_device *adev,
- struct ttm_buffer_object *tbo,
- uint64_t flags)
+static void amdgpu_ttm_gart_bind(struct amdgpu_device *adev,
+ struct ttm_buffer_object *tbo,
+ uint64_t flags)
{
struct amdgpu_bo *abo = ttm_to_amdgpu_bo(tbo);
struct ttm_tt *ttm = tbo->ttm;
struct amdgpu_ttm_tt *gtt = (void *)ttm;
- int r;
if (amdgpu_bo_encrypted(abo))
flags |= AMDGPU_PTE_TMZ;
@@ -836,10 +830,8 @@ static int amdgpu_ttm_gart_bind(struct amdgpu_device *adev,
if (abo->flags & AMDGPU_GEM_CREATE_CP_MQD_GFX9) {
uint64_t page_idx = 1;
- r = amdgpu_gart_bind(adev, gtt->offset, page_idx,
- gtt->ttm.dma_address, flags);
- if (r)
- goto gart_bind_fail;
+ amdgpu_gart_bind(adev, gtt->offset, page_idx,
+ gtt->ttm.dma_address, flags);
/* The memory type of the first page defaults to UC. Now
* modify the memory type to NC from the second page of
@@ -848,21 +840,13 @@ static int amdgpu_ttm_gart_bind(struct amdgpu_device *adev,
flags &= ~AMDGPU_PTE_MTYPE_VG10_MASK;
flags |= AMDGPU_PTE_MTYPE_VG10(AMDGPU_MTYPE_NC);
- r = amdgpu_gart_bind(adev,
- gtt->offset + (page_idx << PAGE_SHIFT),
- ttm->num_pages - page_idx,
- &(gtt->ttm.dma_address[page_idx]), flags);
+ amdgpu_gart_bind(adev, gtt->offset + (page_idx << PAGE_SHIFT),
+ ttm->num_pages - page_idx,
+ &(gtt->ttm.dma_address[page_idx]), flags);
} else {
- r = amdgpu_gart_bind(adev, gtt->offset, ttm->num_pages,
- gtt->ttm.dma_address, flags);
+ amdgpu_gart_bind(adev, gtt->offset, ttm->num_pages,
+ gtt->ttm.dma_address, flags);
}
-
-gart_bind_fail:
- if (r)
- DRM_ERROR("failed to bind %u pages at 0x%08llX\n",
- ttm->num_pages, gtt->offset);
-
- return r;
}
/*
@@ -878,7 +862,7 @@ static int amdgpu_ttm_backend_bind(struct ttm_device *bdev,
struct amdgpu_device *adev = amdgpu_ttm_adev(bdev);
struct amdgpu_ttm_tt *gtt = (void*)ttm;
uint64_t flags;
- int r = 0;
+ int r;
if (!bo_mem)
return -EINVAL;
@@ -925,14 +909,10 @@ static int amdgpu_ttm_backend_bind(struct ttm_device *bdev,
/* bind pages into GART page tables */
gtt->offset = (u64)bo_mem->start << PAGE_SHIFT;
- r = amdgpu_gart_bind(adev, gtt->offset, ttm->num_pages,
- gtt->ttm.dma_address, flags);
-
- if (r)
- DRM_ERROR("failed to bind %u pages at 0x%08llX\n",
- ttm->num_pages, gtt->offset);
+ amdgpu_gart_bind(adev, gtt->offset, ttm->num_pages,
+ gtt->ttm.dma_address, flags);
gtt->bound = true;
- return r;
+ return 0;
}
/*
@@ -982,12 +962,7 @@ int amdgpu_ttm_alloc_gart(struct ttm_buffer_object *bo)
/* Bind pages */
gtt->offset = (u64)tmp->start << PAGE_SHIFT;
- r = amdgpu_ttm_gart_bind(adev, bo, flags);
- if (unlikely(r)) {
- ttm_resource_free(bo, &tmp);
- return r;
- }
-
+ amdgpu_ttm_gart_bind(adev, bo, flags);
amdgpu_gart_invalidate_tlb(adev);
ttm_resource_free(bo, &bo->resource);
ttm_bo_assign_mem(bo, tmp);
@@ -1001,19 +976,16 @@ int amdgpu_ttm_alloc_gart(struct ttm_buffer_object *bo)
* Called by amdgpu_gtt_mgr_recover() from amdgpu_device_reset() to
* rebind GTT pages during a GPU reset.
*/
-int amdgpu_ttm_recover_gart(struct ttm_buffer_object *tbo)
+void amdgpu_ttm_recover_gart(struct ttm_buffer_object *tbo)
{
struct amdgpu_device *adev = amdgpu_ttm_adev(tbo->bdev);
uint64_t flags;
- int r;
if (!tbo->ttm)
- return 0;
+ return;
flags = amdgpu_ttm_tt_pte_flags(adev, tbo->ttm, tbo->resource);
- r = amdgpu_ttm_gart_bind(adev, tbo, flags);
-
- return r;
+ amdgpu_ttm_gart_bind(adev, tbo, flags);
}
/*
@@ -1027,7 +999,6 @@ static void amdgpu_ttm_backend_unbind(struct ttm_device *bdev,
{
struct amdgpu_device *adev = amdgpu_ttm_adev(bdev);
struct amdgpu_ttm_tt *gtt = (void *)ttm;
- int r;
/* if the pages have userptr pinning then clear that first */
if (gtt->userptr) {
@@ -1047,10 +1018,7 @@ static void amdgpu_ttm_backend_unbind(struct ttm_device *bdev,
return;
/* unbind shouldn't be done for GDS/GWS/OA in ttm_bo_clean_mm */
- r = amdgpu_gart_unbind(adev, gtt->offset, ttm->num_pages);
- if (r)
- DRM_ERROR("failed to unbind %u pages at 0x%08llX\n",
- gtt->ttm.num_pages, gtt->offset);
+ amdgpu_gart_unbind(adev, gtt->offset, ttm->num_pages);
gtt->bound = false;
}
@@ -1169,6 +1137,26 @@ static void amdgpu_ttm_tt_unpopulate(struct ttm_device *bdev,
}
/**
+ * amdgpu_ttm_tt_get_userptr - Return the userptr GTT ttm_tt for the current
+ * task
+ *
+ * @tbo: The ttm_buffer_object that contains the userptr
+ * @user_addr: The returned value
+ */
+int amdgpu_ttm_tt_get_userptr(const struct ttm_buffer_object *tbo,
+ uint64_t *user_addr)
+{
+ struct amdgpu_ttm_tt *gtt;
+
+ if (!tbo->ttm)
+ return -EINVAL;
+
+ gtt = (void *)tbo->ttm;
+ *user_addr = gtt->userptr;
+ return 0;
+}
+
+/**
* amdgpu_ttm_tt_set_userptr - Initialize userptr GTT ttm_tt for the current
* task
*
@@ -1433,6 +1421,63 @@ static void amdgpu_ttm_vram_mm_access(struct amdgpu_device *adev, loff_t pos,
}
}
+static int amdgpu_ttm_access_memory_sdma(struct ttm_buffer_object *bo,
+ unsigned long offset, void *buf, int len, int write)
+{
+ struct amdgpu_bo *abo = ttm_to_amdgpu_bo(bo);
+ struct amdgpu_device *adev = amdgpu_ttm_adev(abo->tbo.bdev);
+ struct amdgpu_res_cursor src_mm;
+ struct amdgpu_job *job;
+ struct dma_fence *fence;
+ uint64_t src_addr, dst_addr;
+ unsigned int num_dw;
+ int r, idx;
+
+ if (len != PAGE_SIZE)
+ return -EINVAL;
+
+ if (!adev->mman.sdma_access_ptr)
+ return -EACCES;
+
+ if (!drm_dev_enter(adev_to_drm(adev), &idx))
+ return -ENODEV;
+
+ if (write)
+ memcpy(adev->mman.sdma_access_ptr, buf, len);
+
+ num_dw = ALIGN(adev->mman.buffer_funcs->copy_num_dw, 8);
+ r = amdgpu_job_alloc_with_ib(adev, num_dw * 4, AMDGPU_IB_POOL_DELAYED, &job);
+ if (r)
+ goto out;
+
+ amdgpu_res_first(abo->tbo.resource, offset, len, &src_mm);
+ src_addr = amdgpu_ttm_domain_start(adev, bo->resource->mem_type) + src_mm.start;
+ dst_addr = amdgpu_bo_gpu_offset(adev->mman.sdma_access_bo);
+ if (write)
+ swap(src_addr, dst_addr);
+
+ amdgpu_emit_copy_buffer(adev, &job->ibs[0], src_addr, dst_addr, PAGE_SIZE, false);
+
+ amdgpu_ring_pad_ib(adev->mman.buffer_funcs_ring, &job->ibs[0]);
+ WARN_ON(job->ibs[0].length_dw > num_dw);
+
+ r = amdgpu_job_submit(job, &adev->mman.entity, AMDGPU_FENCE_OWNER_UNDEFINED, &fence);
+ if (r) {
+ amdgpu_job_free(job);
+ goto out;
+ }
+
+ if (!dma_fence_wait_timeout(fence, false, adev->sdma_timeout))
+ r = -ETIMEDOUT;
+ dma_fence_put(fence);
+
+ if (!(r || write))
+ memcpy(buf, adev->mman.sdma_access_ptr, len);
+out:
+ drm_dev_exit(idx);
+ return r;
+}
+
/**
* amdgpu_ttm_access_memory - Read or Write memory that backs a buffer object.
*
@@ -1457,6 +1502,10 @@ static int amdgpu_ttm_access_memory(struct ttm_buffer_object *bo,
if (bo->resource->mem_type != TTM_PL_VRAM)
return -EIO;
+ if (amdgpu_device_has_timeouts_enabled(adev) &&
+ !amdgpu_ttm_access_memory_sdma(bo, offset, buf, len, write))
+ return len;
+
amdgpu_res_first(bo->resource, offset, len, &cursor);
while (cursor.remaining) {
size_t count, size = cursor.size;
@@ -1797,6 +1846,12 @@ int amdgpu_ttm_init(struct amdgpu_device *adev)
return r;
}
+ if (amdgpu_bo_create_kernel(adev, PAGE_SIZE, PAGE_SIZE,
+ AMDGPU_GEM_DOMAIN_GTT,
+ &adev->mman.sdma_access_bo, NULL,
+ &adev->mman.sdma_access_ptr))
+ DRM_WARN("Debug VRAM access will use slowpath MM access\n");
+
return 0;
}
@@ -1818,6 +1873,8 @@ void amdgpu_ttm_fini(struct amdgpu_device *adev)
if (adev->mman.stolen_reserved_size)
amdgpu_bo_free_kernel(&adev->mman.stolen_reserved_memory,
NULL, NULL);
+ amdgpu_bo_free_kernel(&adev->mman.sdma_access_bo, NULL,
+ &adev->mman.sdma_access_ptr);
amdgpu_ttm_fw_reserve_vram_fini(adev);
if (drm_dev_enter(adev_to_drm(adev), &idx)) {
@@ -1884,27 +1941,59 @@ void amdgpu_ttm_set_buffer_funcs_status(struct amdgpu_device *adev, bool enable)
size = adev->gmc.real_vram_size;
else
size = adev->gmc.visible_vram_size;
- man->size = size >> PAGE_SHIFT;
+ man->size = size;
adev->mman.buffer_funcs_enabled = enable;
}
+static int amdgpu_ttm_prepare_job(struct amdgpu_device *adev,
+ bool direct_submit,
+ unsigned int num_dw,
+ struct dma_resv *resv,
+ bool vm_needs_flush,
+ struct amdgpu_job **job)
+{
+ enum amdgpu_ib_pool_type pool = direct_submit ?
+ AMDGPU_IB_POOL_DIRECT :
+ AMDGPU_IB_POOL_DELAYED;
+ int r;
+
+ r = amdgpu_job_alloc_with_ib(adev, num_dw * 4, pool, job);
+ if (r)
+ return r;
+
+ if (vm_needs_flush) {
+ (*job)->vm_pd_addr = amdgpu_gmc_pd_addr(adev->gmc.pdb0_bo ?
+ adev->gmc.pdb0_bo :
+ adev->gart.bo);
+ (*job)->vm_needs_flush = true;
+ }
+ if (resv) {
+ r = amdgpu_sync_resv(adev, &(*job)->sync, resv,
+ AMDGPU_SYNC_ALWAYS,
+ AMDGPU_FENCE_OWNER_UNDEFINED);
+ if (r) {
+ DRM_ERROR("sync failed (%d).\n", r);
+ amdgpu_job_free(*job);
+ return r;
+ }
+ }
+ return 0;
+}
+
int amdgpu_copy_buffer(struct amdgpu_ring *ring, uint64_t src_offset,
uint64_t dst_offset, uint32_t byte_count,
struct dma_resv *resv,
struct dma_fence **fence, bool direct_submit,
bool vm_needs_flush, bool tmz)
{
- enum amdgpu_ib_pool_type pool = direct_submit ? AMDGPU_IB_POOL_DIRECT :
- AMDGPU_IB_POOL_DELAYED;
struct amdgpu_device *adev = ring->adev;
+ unsigned num_loops, num_dw;
struct amdgpu_job *job;
-
uint32_t max_bytes;
- unsigned num_loops, num_dw;
unsigned i;
int r;
- if (direct_submit && !ring->sched.ready) {
+ if (!direct_submit && !ring->sched.ready) {
DRM_ERROR("Trying to move memory with ring turned off.\n");
return -EINVAL;
}
@@ -1912,26 +2001,11 @@ int amdgpu_copy_buffer(struct amdgpu_ring *ring, uint64_t src_offset,
max_bytes = adev->mman.buffer_funcs->copy_max_bytes;
num_loops = DIV_ROUND_UP(byte_count, max_bytes);
num_dw = ALIGN(num_loops * adev->mman.buffer_funcs->copy_num_dw, 8);
-
- r = amdgpu_job_alloc_with_ib(adev, num_dw * 4, pool, &job);
+ r = amdgpu_ttm_prepare_job(adev, direct_submit, num_dw,
+ resv, vm_needs_flush, &job);
if (r)
return r;
- if (vm_needs_flush) {
- job->vm_pd_addr = amdgpu_gmc_pd_addr(adev->gmc.pdb0_bo ?
- adev->gmc.pdb0_bo : adev->gart.bo);
- job->vm_needs_flush = true;
- }
- if (resv) {
- r = amdgpu_sync_resv(adev, &job->sync, resv,
- AMDGPU_SYNC_ALWAYS,
- AMDGPU_FENCE_OWNER_UNDEFINED);
- if (r) {
- DRM_ERROR("sync failed (%d).\n", r);
- goto error_free;
- }
- }
-
for (i = 0; i < num_loops; i++) {
uint32_t cur_size_in_bytes = min(byte_count, max_bytes);
@@ -1961,77 +2035,35 @@ error_free:
return r;
}
-int amdgpu_fill_buffer(struct amdgpu_bo *bo,
- uint32_t src_data,
- struct dma_resv *resv,
- struct dma_fence **fence)
+static int amdgpu_ttm_fill_mem(struct amdgpu_ring *ring, uint32_t src_data,
+ uint64_t dst_addr, uint32_t byte_count,
+ struct dma_resv *resv,
+ struct dma_fence **fence,
+ bool vm_needs_flush)
{
- struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev);
- uint32_t max_bytes = adev->mman.buffer_funcs->fill_max_bytes;
- struct amdgpu_ring *ring = adev->mman.buffer_funcs_ring;
-
- struct amdgpu_res_cursor cursor;
+ struct amdgpu_device *adev = ring->adev;
unsigned int num_loops, num_dw;
- uint64_t num_bytes;
-
struct amdgpu_job *job;
+ uint32_t max_bytes;
+ unsigned int i;
int r;
- if (!adev->mman.buffer_funcs_enabled) {
- DRM_ERROR("Trying to clear memory with ring turned off.\n");
- return -EINVAL;
- }
-
- if (bo->tbo.resource->mem_type == AMDGPU_PL_PREEMPT) {
- DRM_ERROR("Trying to clear preemptible memory.\n");
- return -EINVAL;
- }
-
- if (bo->tbo.resource->mem_type == TTM_PL_TT) {
- r = amdgpu_ttm_alloc_gart(&bo->tbo);
- if (r)
- return r;
- }
-
- num_bytes = bo->tbo.resource->num_pages << PAGE_SHIFT;
- num_loops = 0;
-
- amdgpu_res_first(bo->tbo.resource, 0, num_bytes, &cursor);
- while (cursor.remaining) {
- num_loops += DIV_ROUND_UP_ULL(cursor.size, max_bytes);
- amdgpu_res_next(&cursor, cursor.size);
- }
- num_dw = num_loops * adev->mman.buffer_funcs->fill_num_dw;
-
- /* for IB padding */
- num_dw += 64;
-
- r = amdgpu_job_alloc_with_ib(adev, num_dw * 4, AMDGPU_IB_POOL_DELAYED,
- &job);
+ max_bytes = adev->mman.buffer_funcs->fill_max_bytes;
+ num_loops = DIV_ROUND_UP_ULL(byte_count, max_bytes);
+ num_dw = ALIGN(num_loops * adev->mman.buffer_funcs->fill_num_dw, 8);
+ r = amdgpu_ttm_prepare_job(adev, false, num_dw, resv, vm_needs_flush,
+ &job);
if (r)
return r;
- if (resv) {
- r = amdgpu_sync_resv(adev, &job->sync, resv,
- AMDGPU_SYNC_ALWAYS,
- AMDGPU_FENCE_OWNER_UNDEFINED);
- if (r) {
- DRM_ERROR("sync failed (%d).\n", r);
- goto error_free;
- }
- }
-
- amdgpu_res_first(bo->tbo.resource, 0, num_bytes, &cursor);
- while (cursor.remaining) {
- uint32_t cur_size = min_t(uint64_t, cursor.size, max_bytes);
- uint64_t dst_addr = cursor.start;
+ for (i = 0; i < num_loops; i++) {
+ uint32_t cur_size = min(byte_count, max_bytes);
- dst_addr += amdgpu_ttm_domain_start(adev,
- bo->tbo.resource->mem_type);
amdgpu_emit_fill_buffer(adev, &job->ibs[0], src_data, dst_addr,
cur_size);
- amdgpu_res_next(&cursor, cur_size);
+ dst_addr += cur_size;
+ byte_count -= cur_size;
}
amdgpu_ring_pad_ib(ring, &job->ibs[0]);
@@ -2048,6 +2080,55 @@ error_free:
return r;
}
+int amdgpu_fill_buffer(struct amdgpu_bo *bo,
+ uint32_t src_data,
+ struct dma_resv *resv,
+ struct dma_fence **f)
+{
+ struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev);
+ struct amdgpu_ring *ring = adev->mman.buffer_funcs_ring;
+ struct dma_fence *fence = NULL;
+ struct amdgpu_res_cursor dst;
+ int r;
+
+ if (!adev->mman.buffer_funcs_enabled) {
+ DRM_ERROR("Trying to clear memory with ring turned off.\n");
+ return -EINVAL;
+ }
+
+ amdgpu_res_first(bo->tbo.resource, 0, amdgpu_bo_size(bo), &dst);
+
+ mutex_lock(&adev->mman.gtt_window_lock);
+ while (dst.remaining) {
+ struct dma_fence *next;
+ uint64_t cur_size, to;
+
+ /* Never fill more than 256MiB at once to avoid timeouts */
+ cur_size = min(dst.size, 256ULL << 20);
+
+ r = amdgpu_ttm_map_buffer(&bo->tbo, bo->tbo.resource, &dst,
+ 1, ring, false, &cur_size, &to);
+ if (r)
+ goto error;
+
+ r = amdgpu_ttm_fill_mem(ring, src_data, to, cur_size, resv,
+ &next, true);
+ if (r)
+ goto error;
+
+ dma_fence_put(fence);
+ fence = next;
+
+ amdgpu_res_next(&dst, cur_size);
+ }
+error:
+ mutex_unlock(&adev->mman.gtt_window_lock);
+ if (f)
+ *f = dma_fence_get(fence);
+ dma_fence_put(fence);
+ return r;
+}
+
/**
* amdgpu_ttm_evict_resources - evict memory buffers
* @adev: amdgpu device object
@@ -2087,7 +2168,7 @@ static int amdgpu_mm_vram_table_show(struct seq_file *m, void *unused)
TTM_PL_VRAM);
struct drm_printer p = drm_seq_file_printer(m);
- man->func->debug(man, &p);
+ ttm_resource_manager_debug(man, &p);
return 0;
}
@@ -2105,7 +2186,7 @@ static int amdgpu_mm_tt_table_show(struct seq_file *m, void *unused)
TTM_PL_TT);
struct drm_printer p = drm_seq_file_printer(m);
- man->func->debug(man, &p);
+ ttm_resource_manager_debug(man, &p);
return 0;
}
@@ -2116,7 +2197,7 @@ static int amdgpu_mm_gds_table_show(struct seq_file *m, void *unused)
AMDGPU_PL_GDS);
struct drm_printer p = drm_seq_file_printer(m);
- man->func->debug(man, &p);
+ ttm_resource_manager_debug(man, &p);
return 0;
}
@@ -2127,7 +2208,7 @@ static int amdgpu_mm_gws_table_show(struct seq_file *m, void *unused)
AMDGPU_PL_GWS);
struct drm_printer p = drm_seq_file_printer(m);
- man->func->debug(man, &p);
+ ttm_resource_manager_debug(man, &p);
return 0;
}
@@ -2138,7 +2219,7 @@ static int amdgpu_mm_oa_table_show(struct seq_file *m, void *unused)
AMDGPU_PL_OA);
struct drm_printer p = drm_seq_file_printer(m);
- man->func->debug(man, &p);
+ ttm_resource_manager_debug(man, &p);
return 0;
}
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h
index f8f48be16d80..9120ae80ef52 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h
@@ -44,7 +44,6 @@ struct amdgpu_vram_mgr {
spinlock_t lock;
struct list_head reservations_pending;
struct list_head reserved_pages;
- atomic64_t usage;
atomic64_t vis_usage;
};
@@ -52,12 +51,6 @@ struct amdgpu_gtt_mgr {
struct ttm_resource_manager manager;
struct drm_mm mm;
spinlock_t lock;
- atomic64_t used;
-};
-
-struct amdgpu_preempt_mgr {
- struct ttm_resource_manager manager;
- atomic64_t used;
};
struct amdgpu_mman {
@@ -76,7 +69,7 @@ struct amdgpu_mman {
struct amdgpu_vram_mgr vram_mgr;
struct amdgpu_gtt_mgr gtt_mgr;
- struct amdgpu_preempt_mgr preempt_mgr;
+ struct ttm_resource_manager preempt_mgr;
uint64_t stolen_vga_size;
struct amdgpu_bo *stolen_vga_memory;
@@ -98,6 +91,10 @@ struct amdgpu_mman {
u64 fw_vram_usage_size;
struct amdgpu_bo *fw_vram_usage_reserved_bo;
void *fw_vram_usage_va;
+
+ /* PAGE_SIZE'd BO for process memory r/w over SDMA. */
+ struct amdgpu_bo *sdma_access_bo;
+ void *sdma_access_ptr;
};
struct amdgpu_copy_mem {
@@ -114,8 +111,7 @@ int amdgpu_vram_mgr_init(struct amdgpu_device *adev);
void amdgpu_vram_mgr_fini(struct amdgpu_device *adev);
bool amdgpu_gtt_mgr_has_gart_addr(struct ttm_resource *mem);
-uint64_t amdgpu_gtt_mgr_usage(struct amdgpu_gtt_mgr *mgr);
-int amdgpu_gtt_mgr_recover(struct amdgpu_gtt_mgr *mgr);
+void amdgpu_gtt_mgr_recover(struct amdgpu_gtt_mgr *mgr);
uint64_t amdgpu_preempt_mgr_usage(struct ttm_resource_manager *man);
@@ -129,7 +125,6 @@ int amdgpu_vram_mgr_alloc_sgt(struct amdgpu_device *adev,
void amdgpu_vram_mgr_free_sgt(struct device *dev,
enum dma_data_direction dir,
struct sg_table *sgt);
-uint64_t amdgpu_vram_mgr_usage(struct amdgpu_vram_mgr *mgr);
uint64_t amdgpu_vram_mgr_vis_usage(struct amdgpu_vram_mgr *mgr);
int amdgpu_vram_mgr_reserve_range(struct amdgpu_vram_mgr *mgr,
uint64_t start, uint64_t size);
@@ -158,7 +153,7 @@ int amdgpu_fill_buffer(struct amdgpu_bo *bo,
struct dma_fence **fence);
int amdgpu_ttm_alloc_gart(struct ttm_buffer_object *bo);
-int amdgpu_ttm_recover_gart(struct ttm_buffer_object *tbo);
+void amdgpu_ttm_recover_gart(struct ttm_buffer_object *tbo);
uint64_t amdgpu_ttm_domain_start(struct amdgpu_device *adev, uint32_t type);
#if IS_ENABLED(CONFIG_DRM_AMDGPU_USERPTR)
@@ -177,6 +172,8 @@ static inline bool amdgpu_ttm_tt_get_user_pages_done(struct ttm_tt *ttm)
#endif
void amdgpu_ttm_tt_set_user_pages(struct ttm_tt *ttm, struct page **pages);
+int amdgpu_ttm_tt_get_userptr(const struct ttm_buffer_object *tbo,
+ uint64_t *user_addr);
int amdgpu_ttm_tt_set_userptr(struct ttm_buffer_object *bo,
uint64_t addr, uint32_t flags);
bool amdgpu_ttm_tt_has_userptr(struct ttm_tt *ttm);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.h
index 7c2538db3cd5..40dffbac85a0 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.h
@@ -343,7 +343,8 @@ union amdgpu_firmware_header {
* fw loading support
*/
enum AMDGPU_UCODE_ID {
- AMDGPU_UCODE_ID_SDMA0 = 0,
+ AMDGPU_UCODE_ID_CAP = 0,
+ AMDGPU_UCODE_ID_SDMA0,
AMDGPU_UCODE_ID_SDMA1,
AMDGPU_UCODE_ID_SDMA2,
AMDGPU_UCODE_ID_SDMA3,
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_umc.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_umc.c
index 46264a4002f7..aad3c8b4c810 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_umc.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_umc.c
@@ -21,7 +21,7 @@
*
*/
-#include "amdgpu_ras.h"
+#include "amdgpu.h"
static int amdgpu_umc_do_page_retirement(struct amdgpu_device *adev,
void *ras_error_status,
@@ -33,14 +33,14 @@ static int amdgpu_umc_do_page_retirement(struct amdgpu_device *adev,
int ret = 0;
kgd2kfd_set_sram_ecc_flag(adev->kfd.dev);
- ret = smu_get_ecc_info(&adev->smu, (void *)&(con->umc_ecc));
+ ret = amdgpu_dpm_get_ecc_info(adev, (void *)&(con->umc_ecc));
if (ret == -EOPNOTSUPP) {
- if (adev->umc.ras_funcs &&
- adev->umc.ras_funcs->query_ras_error_count)
- adev->umc.ras_funcs->query_ras_error_count(adev, ras_error_status);
+ if (adev->umc.ras && adev->umc.ras->ras_block.hw_ops &&
+ adev->umc.ras->ras_block.hw_ops->query_ras_error_count)
+ adev->umc.ras->ras_block.hw_ops->query_ras_error_count(adev, ras_error_status);
- if (adev->umc.ras_funcs &&
- adev->umc.ras_funcs->query_ras_error_address &&
+ if (adev->umc.ras && adev->umc.ras->ras_block.hw_ops &&
+ adev->umc.ras->ras_block.hw_ops->query_ras_error_address &&
adev->umc.max_ras_err_cnt_per_query) {
err_data->err_addr =
kcalloc(adev->umc.max_ras_err_cnt_per_query,
@@ -56,15 +56,15 @@ static int amdgpu_umc_do_page_retirement(struct amdgpu_device *adev,
/* umc query_ras_error_address is also responsible for clearing
* error status
*/
- adev->umc.ras_funcs->query_ras_error_address(adev, ras_error_status);
+ adev->umc.ras->ras_block.hw_ops->query_ras_error_address(adev, ras_error_status);
}
} else if (!ret) {
- if (adev->umc.ras_funcs &&
- adev->umc.ras_funcs->ecc_info_query_ras_error_count)
- adev->umc.ras_funcs->ecc_info_query_ras_error_count(adev, ras_error_status);
+ if (adev->umc.ras &&
+ adev->umc.ras->ecc_info_query_ras_error_count)
+ adev->umc.ras->ecc_info_query_ras_error_count(adev, ras_error_status);
- if (adev->umc.ras_funcs &&
- adev->umc.ras_funcs->ecc_info_query_ras_error_address &&
+ if (adev->umc.ras &&
+ adev->umc.ras->ecc_info_query_ras_error_address &&
adev->umc.max_ras_err_cnt_per_query) {
err_data->err_addr =
kcalloc(adev->umc.max_ras_err_cnt_per_query,
@@ -80,7 +80,7 @@ static int amdgpu_umc_do_page_retirement(struct amdgpu_device *adev,
/* umc query_ras_error_address is also responsible for clearing
* error status
*/
- adev->umc.ras_funcs->ecc_info_query_ras_error_address(adev, ras_error_status);
+ adev->umc.ras->ecc_info_query_ras_error_address(adev, ras_error_status);
}
}
@@ -96,8 +96,12 @@ static int amdgpu_umc_do_page_retirement(struct amdgpu_device *adev,
err_data->err_addr_cnt);
amdgpu_ras_save_bad_pages(adev);
- if (adev->smu.ppt_funcs && adev->smu.ppt_funcs->send_hbm_bad_pages_num)
- adev->smu.ppt_funcs->send_hbm_bad_pages_num(&adev->smu, con->eeprom_control.ras_num_recs);
+ amdgpu_dpm_send_hbm_bad_pages_num(adev, con->eeprom_control.ras_num_recs);
+
+ if (con->update_channel_flag == true) {
+ amdgpu_dpm_send_hbm_bad_channel_flag(adev, con->eeprom_control.bad_channel_bitmap);
+ con->update_channel_flag = false;
+ }
}
if (reset)
@@ -130,78 +134,39 @@ int amdgpu_umc_poison_handler(struct amdgpu_device *adev,
return ret;
}
-static int amdgpu_umc_process_ras_data_cb(struct amdgpu_device *adev,
+int amdgpu_umc_process_ras_data_cb(struct amdgpu_device *adev,
void *ras_error_status,
struct amdgpu_iv_entry *entry)
{
return amdgpu_umc_do_page_retirement(adev, ras_error_status, entry, true);
}
-int amdgpu_umc_ras_late_init(struct amdgpu_device *adev)
+int amdgpu_umc_ras_late_init(struct amdgpu_device *adev, struct ras_common_if *ras_block)
{
int r;
- struct ras_fs_if fs_info = {
- .sysfs_name = "umc_err_count",
- };
- struct ras_ih_if ih_info = {
- .cb = amdgpu_umc_process_ras_data_cb,
- };
- if (!adev->umc.ras_if) {
- adev->umc.ras_if =
- kmalloc(sizeof(struct ras_common_if), GFP_KERNEL);
- if (!adev->umc.ras_if)
- return -ENOMEM;
- adev->umc.ras_if->block = AMDGPU_RAS_BLOCK__UMC;
- adev->umc.ras_if->type = AMDGPU_RAS_ERROR__MULTI_UNCORRECTABLE;
- adev->umc.ras_if->sub_block_index = 0;
- }
- ih_info.head = fs_info.head = *adev->umc.ras_if;
-
- r = amdgpu_ras_late_init(adev, adev->umc.ras_if,
- &fs_info, &ih_info);
+ r = amdgpu_ras_block_late_init(adev, ras_block);
if (r)
- goto free;
+ return r;
- if (amdgpu_ras_is_supported(adev, adev->umc.ras_if->block)) {
+ if (amdgpu_ras_is_supported(adev, ras_block->block)) {
r = amdgpu_irq_get(adev, &adev->gmc.ecc_irq, 0);
if (r)
goto late_fini;
- } else {
- r = 0;
- goto free;
}
/* ras init of specific umc version */
- if (adev->umc.ras_funcs &&
- adev->umc.ras_funcs->err_cnt_init)
- adev->umc.ras_funcs->err_cnt_init(adev);
+ if (adev->umc.ras &&
+ adev->umc.ras->err_cnt_init)
+ adev->umc.ras->err_cnt_init(adev);
return 0;
late_fini:
- amdgpu_ras_late_fini(adev, adev->umc.ras_if, &ih_info);
-free:
- kfree(adev->umc.ras_if);
- adev->umc.ras_if = NULL;
+ amdgpu_ras_block_late_fini(adev, ras_block);
return r;
}
-void amdgpu_umc_ras_fini(struct amdgpu_device *adev)
-{
- if (amdgpu_ras_is_supported(adev, AMDGPU_RAS_BLOCK__UMC) &&
- adev->umc.ras_if) {
- struct ras_common_if *ras_if = adev->umc.ras_if;
- struct ras_ih_if ih_info = {
- .head = *ras_if,
- .cb = amdgpu_umc_process_ras_data_cb,
- };
-
- amdgpu_ras_late_fini(adev, ras_if, &ih_info);
- kfree(ras_if);
- }
-}
-
int amdgpu_umc_process_ecc_irq(struct amdgpu_device *adev,
struct amdgpu_irq_src *source,
struct amdgpu_iv_entry *entry)
@@ -219,3 +184,24 @@ int amdgpu_umc_process_ecc_irq(struct amdgpu_device *adev,
amdgpu_ras_interrupt_dispatch(adev, &ih_data);
return 0;
}
+
+void amdgpu_umc_fill_error_record(struct ras_err_data *err_data,
+ uint64_t err_addr,
+ uint64_t retired_page,
+ uint32_t channel_index,
+ uint32_t umc_inst)
+{
+ struct eeprom_table_record *err_rec =
+ &err_data->err_addr[err_data->err_addr_cnt];
+
+ err_rec->address = err_addr;
+ /* page frame address is saved */
+ err_rec->retired_page = retired_page >> AMDGPU_GPU_PAGE_SHIFT;
+ err_rec->ts = (uint64_t)ktime_get_real_seconds();
+ err_rec->err_type = AMDGPU_RAS_EEPROM_ERR_NON_RECOVERABLE;
+ err_rec->cu = 0;
+ err_rec->mem_channel = channel_index;
+ err_rec->mcumc_id = umc_inst;
+
+ err_data->err_addr_cnt++;
+}
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_umc.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_umc.h
index b72194e8bfe5..2ec6698aa1fe 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_umc.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_umc.h
@@ -20,6 +20,7 @@
*/
#ifndef __AMDGPU_UMC_H__
#define __AMDGPU_UMC_H__
+#include "amdgpu_ras.h"
/*
* (addr / 256) * 4096, the higher 26 bits in ErrorAddr
@@ -40,14 +41,9 @@
#define LOOP_UMC_CH_INST(ch_inst) for ((ch_inst) = 0; (ch_inst) < adev->umc.channel_inst_num; (ch_inst)++)
#define LOOP_UMC_INST_AND_CH(umc_inst, ch_inst) LOOP_UMC_INST((umc_inst)) LOOP_UMC_CH_INST((ch_inst))
-struct amdgpu_umc_ras_funcs {
+struct amdgpu_umc_ras {
+ struct amdgpu_ras_block_object ras_block;
void (*err_cnt_init)(struct amdgpu_device *adev);
- int (*ras_late_init)(struct amdgpu_device *adev);
- void (*ras_fini)(struct amdgpu_device *adev);
- void (*query_ras_error_count)(struct amdgpu_device *adev,
- void *ras_error_status);
- void (*query_ras_error_address)(struct amdgpu_device *adev,
- void *ras_error_status);
bool (*query_ras_poison_mode)(struct amdgpu_device *adev);
void (*ecc_info_query_ras_error_count)(struct amdgpu_device *adev,
void *ras_error_status);
@@ -73,15 +69,23 @@ struct amdgpu_umc {
struct ras_common_if *ras_if;
const struct amdgpu_umc_funcs *funcs;
- const struct amdgpu_umc_ras_funcs *ras_funcs;
+ struct amdgpu_umc_ras *ras;
};
-int amdgpu_umc_ras_late_init(struct amdgpu_device *adev);
-void amdgpu_umc_ras_fini(struct amdgpu_device *adev);
+int amdgpu_umc_ras_late_init(struct amdgpu_device *adev, struct ras_common_if *ras_block);
int amdgpu_umc_poison_handler(struct amdgpu_device *adev,
void *ras_error_status,
bool reset);
int amdgpu_umc_process_ecc_irq(struct amdgpu_device *adev,
struct amdgpu_irq_src *source,
struct amdgpu_iv_entry *entry);
+void amdgpu_umc_fill_error_record(struct ras_err_data *err_data,
+ uint64_t err_addr,
+ uint64_t retired_page,
+ uint32_t channel_index,
+ uint32_t umc_inst);
+
+int amdgpu_umc_process_ras_data_cb(struct amdgpu_device *adev,
+ void *ras_error_status,
+ struct amdgpu_iv_entry *entry);
#endif
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c
index 6f8de11a17f1..39c74d9fa7cc 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c
@@ -37,6 +37,7 @@
#include "amdgpu.h"
#include "amdgpu_pm.h"
#include "amdgpu_uvd.h"
+#include "amdgpu_cs.h"
#include "cikd.h"
#include "uvd/uvd_4_2_d.h"
@@ -98,7 +99,7 @@ struct amdgpu_uvd_cs_ctx {
unsigned reg, count;
unsigned data0, data1;
unsigned idx;
- unsigned ib_idx;
+ struct amdgpu_ib *ib;
/* does the IB has a msg command */
bool has_msg_cmd;
@@ -557,8 +558,8 @@ static u64 amdgpu_uvd_get_addr_from_ctx(struct amdgpu_uvd_cs_ctx *ctx)
uint32_t lo, hi;
uint64_t addr;
- lo = amdgpu_get_ib_value(ctx->parser, ctx->ib_idx, ctx->data0);
- hi = amdgpu_get_ib_value(ctx->parser, ctx->ib_idx, ctx->data1);
+ lo = amdgpu_ib_get_value(ctx->ib, ctx->data0);
+ hi = amdgpu_ib_get_value(ctx->ib, ctx->data1);
addr = ((uint64_t)lo) | (((uint64_t)hi) << 32);
return addr;
@@ -589,7 +590,7 @@ static int amdgpu_uvd_cs_pass1(struct amdgpu_uvd_cs_ctx *ctx)
if (!ctx->parser->adev->uvd.address_64_bit) {
/* check if it's a message or feedback command */
- cmd = amdgpu_get_ib_value(ctx->parser, ctx->ib_idx, ctx->idx) >> 1;
+ cmd = amdgpu_ib_get_value(ctx->ib, ctx->idx) >> 1;
if (cmd == 0x0 || cmd == 0x3) {
/* yes, force it into VRAM */
uint32_t domain = AMDGPU_GEM_DOMAIN_VRAM;
@@ -834,6 +835,7 @@ static int amdgpu_uvd_cs_msg(struct amdgpu_uvd_cs_ctx *ctx,
handle = msg[2];
if (handle == 0) {
+ amdgpu_bo_kunmap(bo);
DRM_ERROR("Invalid UVD handle!\n");
return -EINVAL;
}
@@ -892,6 +894,7 @@ static int amdgpu_uvd_cs_msg(struct amdgpu_uvd_cs_ctx *ctx,
DRM_ERROR("Illegal UVD message type (%d)!\n", msg_type);
}
+ amdgpu_bo_kunmap(bo);
return -EINVAL;
}
@@ -925,12 +928,10 @@ static int amdgpu_uvd_cs_pass2(struct amdgpu_uvd_cs_ctx *ctx)
addr -= mapping->start * AMDGPU_GPU_PAGE_SIZE;
start += addr;
- amdgpu_set_ib_value(ctx->parser, ctx->ib_idx, ctx->data0,
- lower_32_bits(start));
- amdgpu_set_ib_value(ctx->parser, ctx->ib_idx, ctx->data1,
- upper_32_bits(start));
+ amdgpu_ib_set_value(ctx->ib, ctx->data0, lower_32_bits(start));
+ amdgpu_ib_set_value(ctx->ib, ctx->data1, upper_32_bits(start));
- cmd = amdgpu_get_ib_value(ctx->parser, ctx->ib_idx, ctx->idx) >> 1;
+ cmd = amdgpu_ib_get_value(ctx->ib, ctx->idx) >> 1;
if (cmd < 0x4) {
if ((end - start) < ctx->buf_sizes[cmd]) {
DRM_ERROR("buffer (%d) to small (%d / %d)!\n", cmd,
@@ -990,14 +991,13 @@ static int amdgpu_uvd_cs_pass2(struct amdgpu_uvd_cs_ctx *ctx)
static int amdgpu_uvd_cs_reg(struct amdgpu_uvd_cs_ctx *ctx,
int (*cb)(struct amdgpu_uvd_cs_ctx *ctx))
{
- struct amdgpu_ib *ib = &ctx->parser->job->ibs[ctx->ib_idx];
int i, r;
ctx->idx++;
for (i = 0; i <= ctx->count; ++i) {
unsigned reg = ctx->reg + i;
- if (ctx->idx >= ib->length_dw) {
+ if (ctx->idx >= ctx->ib->length_dw) {
DRM_ERROR("Register command after end of CS!\n");
return -EINVAL;
}
@@ -1037,11 +1037,10 @@ static int amdgpu_uvd_cs_reg(struct amdgpu_uvd_cs_ctx *ctx,
static int amdgpu_uvd_cs_packets(struct amdgpu_uvd_cs_ctx *ctx,
int (*cb)(struct amdgpu_uvd_cs_ctx *ctx))
{
- struct amdgpu_ib *ib = &ctx->parser->job->ibs[ctx->ib_idx];
int r;
- for (ctx->idx = 0 ; ctx->idx < ib->length_dw; ) {
- uint32_t cmd = amdgpu_get_ib_value(ctx->parser, ctx->ib_idx, ctx->idx);
+ for (ctx->idx = 0 ; ctx->idx < ctx->ib->length_dw; ) {
+ uint32_t cmd = amdgpu_ib_get_value(ctx->ib, ctx->idx);
unsigned type = CP_PACKET_GET_TYPE(cmd);
switch (type) {
case PACKET_TYPE0:
@@ -1066,11 +1065,14 @@ static int amdgpu_uvd_cs_packets(struct amdgpu_uvd_cs_ctx *ctx,
* amdgpu_uvd_ring_parse_cs - UVD command submission parser
*
* @parser: Command submission parser context
- * @ib_idx: Which indirect buffer to use
+ * @job: the job to parse
+ * @ib: the IB to patch
*
* Parse the command stream, patch in addresses as necessary.
*/
-int amdgpu_uvd_ring_parse_cs(struct amdgpu_cs_parser *parser, uint32_t ib_idx)
+int amdgpu_uvd_ring_parse_cs(struct amdgpu_cs_parser *parser,
+ struct amdgpu_job *job,
+ struct amdgpu_ib *ib)
{
struct amdgpu_uvd_cs_ctx ctx = {};
unsigned buf_sizes[] = {
@@ -1080,10 +1082,9 @@ int amdgpu_uvd_ring_parse_cs(struct amdgpu_cs_parser *parser, uint32_t ib_idx)
[0x00000003] = 2048,
[0x00000004] = 0xFFFFFFFF,
};
- struct amdgpu_ib *ib = &parser->job->ibs[ib_idx];
int r;
- parser->job->vm = NULL;
+ job->vm = NULL;
ib->gpu_addr = amdgpu_sa_bo_gpu_addr(ib->sa_bo);
if (ib->length_dw % 16) {
@@ -1094,7 +1095,7 @@ int amdgpu_uvd_ring_parse_cs(struct amdgpu_cs_parser *parser, uint32_t ib_idx)
ctx.parser = parser;
ctx.buf_sizes = buf_sizes;
- ctx.ib_idx = ib_idx;
+ ctx.ib = ib;
/* first round only required on chips without UVD 64 bit address support */
if (!parser->adev->uvd.address_64_bit) {
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.h
index 76ac9699885d..9f89bb7cd60b 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.h
@@ -82,7 +82,9 @@ int amdgpu_uvd_get_destroy_msg(struct amdgpu_ring *ring, uint32_t handle,
bool direct, struct dma_fence **fence);
void amdgpu_uvd_free_handles(struct amdgpu_device *adev,
struct drm_file *filp);
-int amdgpu_uvd_ring_parse_cs(struct amdgpu_cs_parser *parser, uint32_t ib_idx);
+int amdgpu_uvd_ring_parse_cs(struct amdgpu_cs_parser *parser,
+ struct amdgpu_job *job,
+ struct amdgpu_ib *ib);
void amdgpu_uvd_ring_begin_use(struct amdgpu_ring *ring);
void amdgpu_uvd_ring_end_use(struct amdgpu_ring *ring);
int amdgpu_uvd_ring_test_ib(struct amdgpu_ring *ring, long timeout);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c
index 344f711ad144..02cb3a12dd76 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c
@@ -34,6 +34,7 @@
#include "amdgpu.h"
#include "amdgpu_pm.h"
#include "amdgpu_vce.h"
+#include "amdgpu_cs.h"
#include "cikd.h"
/* 1 second timeout */
@@ -587,8 +588,7 @@ err:
/**
* amdgpu_vce_validate_bo - make sure not to cross 4GB boundary
*
- * @p: parser context
- * @ib_idx: indirect buffer to use
+ * @ib: indirect buffer to use
* @lo: address of lower dword
* @hi: address of higher dword
* @size: minimum size
@@ -596,8 +596,9 @@ err:
*
* Make sure that no BO cross a 4GB boundary.
*/
-static int amdgpu_vce_validate_bo(struct amdgpu_cs_parser *p, uint32_t ib_idx,
- int lo, int hi, unsigned size, int32_t index)
+static int amdgpu_vce_validate_bo(struct amdgpu_cs_parser *p,
+ struct amdgpu_ib *ib, int lo, int hi,
+ unsigned size, int32_t index)
{
int64_t offset = ((uint64_t)size) * ((int64_t)index);
struct ttm_operation_ctx ctx = { false, false };
@@ -607,8 +608,8 @@ static int amdgpu_vce_validate_bo(struct amdgpu_cs_parser *p, uint32_t ib_idx,
uint64_t addr;
int r;
- addr = ((uint64_t)amdgpu_get_ib_value(p, ib_idx, lo)) |
- ((uint64_t)amdgpu_get_ib_value(p, ib_idx, hi)) << 32;
+ addr = ((uint64_t)amdgpu_ib_get_value(ib, lo)) |
+ ((uint64_t)amdgpu_ib_get_value(ib, hi)) << 32;
if (index >= 0) {
addr += offset;
fpfn = PAGE_ALIGN(offset) >> PAGE_SHIFT;
@@ -638,7 +639,7 @@ static int amdgpu_vce_validate_bo(struct amdgpu_cs_parser *p, uint32_t ib_idx,
* amdgpu_vce_cs_reloc - command submission relocation
*
* @p: parser context
- * @ib_idx: indirect buffer to use
+ * @ib: indirect buffer to use
* @lo: address of lower dword
* @hi: address of higher dword
* @size: minimum size
@@ -646,7 +647,7 @@ static int amdgpu_vce_validate_bo(struct amdgpu_cs_parser *p, uint32_t ib_idx,
*
* Patch relocation inside command stream with real buffer address
*/
-static int amdgpu_vce_cs_reloc(struct amdgpu_cs_parser *p, uint32_t ib_idx,
+static int amdgpu_vce_cs_reloc(struct amdgpu_cs_parser *p, struct amdgpu_ib *ib,
int lo, int hi, unsigned size, uint32_t index)
{
struct amdgpu_bo_va_mapping *mapping;
@@ -657,8 +658,8 @@ static int amdgpu_vce_cs_reloc(struct amdgpu_cs_parser *p, uint32_t ib_idx,
if (index == 0xffffffff)
index = 0;
- addr = ((uint64_t)amdgpu_get_ib_value(p, ib_idx, lo)) |
- ((uint64_t)amdgpu_get_ib_value(p, ib_idx, hi)) << 32;
+ addr = ((uint64_t)amdgpu_ib_get_value(ib, lo)) |
+ ((uint64_t)amdgpu_ib_get_value(ib, hi)) << 32;
addr += ((uint64_t)size) * ((uint64_t)index);
r = amdgpu_cs_find_mapping(p, addr, &bo, &mapping);
@@ -679,8 +680,8 @@ static int amdgpu_vce_cs_reloc(struct amdgpu_cs_parser *p, uint32_t ib_idx,
addr += amdgpu_bo_gpu_offset(bo);
addr -= ((uint64_t)size) * ((uint64_t)index);
- amdgpu_set_ib_value(p, ib_idx, lo, lower_32_bits(addr));
- amdgpu_set_ib_value(p, ib_idx, hi, upper_32_bits(addr));
+ amdgpu_ib_set_value(ib, lo, lower_32_bits(addr));
+ amdgpu_ib_set_value(ib, hi, upper_32_bits(addr));
return 0;
}
@@ -729,11 +730,13 @@ static int amdgpu_vce_validate_handle(struct amdgpu_cs_parser *p,
* amdgpu_vce_ring_parse_cs - parse and validate the command stream
*
* @p: parser context
- * @ib_idx: indirect buffer to use
+ * @job: the job to parse
+ * @ib: the IB to patch
*/
-int amdgpu_vce_ring_parse_cs(struct amdgpu_cs_parser *p, uint32_t ib_idx)
+int amdgpu_vce_ring_parse_cs(struct amdgpu_cs_parser *p,
+ struct amdgpu_job *job,
+ struct amdgpu_ib *ib)
{
- struct amdgpu_ib *ib = &p->job->ibs[ib_idx];
unsigned fb_idx = 0, bs_idx = 0;
int session_idx = -1;
uint32_t destroyed = 0;
@@ -744,12 +747,12 @@ int amdgpu_vce_ring_parse_cs(struct amdgpu_cs_parser *p, uint32_t ib_idx)
unsigned idx;
int i, r = 0;
- p->job->vm = NULL;
+ job->vm = NULL;
ib->gpu_addr = amdgpu_sa_bo_gpu_addr(ib->sa_bo);
for (idx = 0; idx < ib->length_dw;) {
- uint32_t len = amdgpu_get_ib_value(p, ib_idx, idx);
- uint32_t cmd = amdgpu_get_ib_value(p, ib_idx, idx + 1);
+ uint32_t len = amdgpu_ib_get_value(ib, idx);
+ uint32_t cmd = amdgpu_ib_get_value(ib, idx + 1);
if ((len < 8) || (len & 3)) {
DRM_ERROR("invalid VCE command length (%d)!\n", len);
@@ -759,52 +762,52 @@ int amdgpu_vce_ring_parse_cs(struct amdgpu_cs_parser *p, uint32_t ib_idx)
switch (cmd) {
case 0x00000002: /* task info */
- fb_idx = amdgpu_get_ib_value(p, ib_idx, idx + 6);
- bs_idx = amdgpu_get_ib_value(p, ib_idx, idx + 7);
+ fb_idx = amdgpu_ib_get_value(ib, idx + 6);
+ bs_idx = amdgpu_ib_get_value(ib, idx + 7);
break;
case 0x03000001: /* encode */
- r = amdgpu_vce_validate_bo(p, ib_idx, idx + 10,
- idx + 9, 0, 0);
+ r = amdgpu_vce_validate_bo(p, ib, idx + 10, idx + 9,
+ 0, 0);
if (r)
goto out;
- r = amdgpu_vce_validate_bo(p, ib_idx, idx + 12,
- idx + 11, 0, 0);
+ r = amdgpu_vce_validate_bo(p, ib, idx + 12, idx + 11,
+ 0, 0);
if (r)
goto out;
break;
case 0x05000001: /* context buffer */
- r = amdgpu_vce_validate_bo(p, ib_idx, idx + 3,
- idx + 2, 0, 0);
+ r = amdgpu_vce_validate_bo(p, ib, idx + 3, idx + 2,
+ 0, 0);
if (r)
goto out;
break;
case 0x05000004: /* video bitstream buffer */
- tmp = amdgpu_get_ib_value(p, ib_idx, idx + 4);
- r = amdgpu_vce_validate_bo(p, ib_idx, idx + 3, idx + 2,
+ tmp = amdgpu_ib_get_value(ib, idx + 4);
+ r = amdgpu_vce_validate_bo(p, ib, idx + 3, idx + 2,
tmp, bs_idx);
if (r)
goto out;
break;
case 0x05000005: /* feedback buffer */
- r = amdgpu_vce_validate_bo(p, ib_idx, idx + 3, idx + 2,
+ r = amdgpu_vce_validate_bo(p, ib, idx + 3, idx + 2,
4096, fb_idx);
if (r)
goto out;
break;
case 0x0500000d: /* MV buffer */
- r = amdgpu_vce_validate_bo(p, ib_idx, idx + 3,
- idx + 2, 0, 0);
+ r = amdgpu_vce_validate_bo(p, ib, idx + 3, idx + 2,
+ 0, 0);
if (r)
goto out;
- r = amdgpu_vce_validate_bo(p, ib_idx, idx + 8,
- idx + 7, 0, 0);
+ r = amdgpu_vce_validate_bo(p, ib, idx + 8, idx + 7,
+ 0, 0);
if (r)
goto out;
break;
@@ -814,12 +817,12 @@ int amdgpu_vce_ring_parse_cs(struct amdgpu_cs_parser *p, uint32_t ib_idx)
}
for (idx = 0; idx < ib->length_dw;) {
- uint32_t len = amdgpu_get_ib_value(p, ib_idx, idx);
- uint32_t cmd = amdgpu_get_ib_value(p, ib_idx, idx + 1);
+ uint32_t len = amdgpu_ib_get_value(ib, idx);
+ uint32_t cmd = amdgpu_ib_get_value(ib, idx + 1);
switch (cmd) {
case 0x00000001: /* session */
- handle = amdgpu_get_ib_value(p, ib_idx, idx + 2);
+ handle = amdgpu_ib_get_value(ib, idx + 2);
session_idx = amdgpu_vce_validate_handle(p, handle,
&allocated);
if (session_idx < 0) {
@@ -830,8 +833,8 @@ int amdgpu_vce_ring_parse_cs(struct amdgpu_cs_parser *p, uint32_t ib_idx)
break;
case 0x00000002: /* task info */
- fb_idx = amdgpu_get_ib_value(p, ib_idx, idx + 6);
- bs_idx = amdgpu_get_ib_value(p, ib_idx, idx + 7);
+ fb_idx = amdgpu_ib_get_value(ib, idx + 6);
+ bs_idx = amdgpu_ib_get_value(ib, idx + 7);
break;
case 0x01000001: /* create */
@@ -846,8 +849,8 @@ int amdgpu_vce_ring_parse_cs(struct amdgpu_cs_parser *p, uint32_t ib_idx)
goto out;
}
- *size = amdgpu_get_ib_value(p, ib_idx, idx + 8) *
- amdgpu_get_ib_value(p, ib_idx, idx + 10) *
+ *size = amdgpu_ib_get_value(ib, idx + 8) *
+ amdgpu_ib_get_value(ib, idx + 10) *
8 * 3 / 2;
break;
@@ -876,12 +879,12 @@ int amdgpu_vce_ring_parse_cs(struct amdgpu_cs_parser *p, uint32_t ib_idx)
break;
case 0x03000001: /* encode */
- r = amdgpu_vce_cs_reloc(p, ib_idx, idx + 10, idx + 9,
+ r = amdgpu_vce_cs_reloc(p, ib, idx + 10, idx + 9,
*size, 0);
if (r)
goto out;
- r = amdgpu_vce_cs_reloc(p, ib_idx, idx + 12, idx + 11,
+ r = amdgpu_vce_cs_reloc(p, ib, idx + 12, idx + 11,
*size / 3, 0);
if (r)
goto out;
@@ -892,35 +895,35 @@ int amdgpu_vce_ring_parse_cs(struct amdgpu_cs_parser *p, uint32_t ib_idx)
break;
case 0x05000001: /* context buffer */
- r = amdgpu_vce_cs_reloc(p, ib_idx, idx + 3, idx + 2,
+ r = amdgpu_vce_cs_reloc(p, ib, idx + 3, idx + 2,
*size * 2, 0);
if (r)
goto out;
break;
case 0x05000004: /* video bitstream buffer */
- tmp = amdgpu_get_ib_value(p, ib_idx, idx + 4);
- r = amdgpu_vce_cs_reloc(p, ib_idx, idx + 3, idx + 2,
+ tmp = amdgpu_ib_get_value(ib, idx + 4);
+ r = amdgpu_vce_cs_reloc(p, ib, idx + 3, idx + 2,
tmp, bs_idx);
if (r)
goto out;
break;
case 0x05000005: /* feedback buffer */
- r = amdgpu_vce_cs_reloc(p, ib_idx, idx + 3, idx + 2,
+ r = amdgpu_vce_cs_reloc(p, ib, idx + 3, idx + 2,
4096, fb_idx);
if (r)
goto out;
break;
case 0x0500000d: /* MV buffer */
- r = amdgpu_vce_cs_reloc(p, ib_idx, idx + 3,
- idx + 2, *size, 0);
+ r = amdgpu_vce_cs_reloc(p, ib, idx + 3,
+ idx + 2, *size, 0);
if (r)
goto out;
- r = amdgpu_vce_cs_reloc(p, ib_idx, idx + 8,
- idx + 7, *size / 12, 0);
+ r = amdgpu_vce_cs_reloc(p, ib, idx + 8,
+ idx + 7, *size / 12, 0);
if (r)
goto out;
break;
@@ -965,11 +968,13 @@ out:
* amdgpu_vce_ring_parse_cs_vm - parse the command stream in VM mode
*
* @p: parser context
- * @ib_idx: indirect buffer to use
+ * @job: the job to parse
+ * @ib: the IB to patch
*/
-int amdgpu_vce_ring_parse_cs_vm(struct amdgpu_cs_parser *p, uint32_t ib_idx)
+int amdgpu_vce_ring_parse_cs_vm(struct amdgpu_cs_parser *p,
+ struct amdgpu_job *job,
+ struct amdgpu_ib *ib)
{
- struct amdgpu_ib *ib = &p->job->ibs[ib_idx];
int session_idx = -1;
uint32_t destroyed = 0;
uint32_t created = 0;
@@ -978,8 +983,8 @@ int amdgpu_vce_ring_parse_cs_vm(struct amdgpu_cs_parser *p, uint32_t ib_idx)
int i, r = 0, idx = 0;
while (idx < ib->length_dw) {
- uint32_t len = amdgpu_get_ib_value(p, ib_idx, idx);
- uint32_t cmd = amdgpu_get_ib_value(p, ib_idx, idx + 1);
+ uint32_t len = amdgpu_ib_get_value(ib, idx);
+ uint32_t cmd = amdgpu_ib_get_value(ib, idx + 1);
if ((len < 8) || (len & 3)) {
DRM_ERROR("invalid VCE command length (%d)!\n", len);
@@ -989,7 +994,7 @@ int amdgpu_vce_ring_parse_cs_vm(struct amdgpu_cs_parser *p, uint32_t ib_idx)
switch (cmd) {
case 0x00000001: /* session */
- handle = amdgpu_get_ib_value(p, ib_idx, idx + 2);
+ handle = amdgpu_ib_get_value(ib, idx + 2);
session_idx = amdgpu_vce_validate_handle(p, handle,
&allocated);
if (session_idx < 0) {
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.h
index be4a6e773c5b..ea680fc9a6c3 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.h
@@ -59,8 +59,11 @@ int amdgpu_vce_entity_init(struct amdgpu_device *adev);
int amdgpu_vce_suspend(struct amdgpu_device *adev);
int amdgpu_vce_resume(struct amdgpu_device *adev);
void amdgpu_vce_free_handles(struct amdgpu_device *adev, struct drm_file *filp);
-int amdgpu_vce_ring_parse_cs(struct amdgpu_cs_parser *p, uint32_t ib_idx);
-int amdgpu_vce_ring_parse_cs_vm(struct amdgpu_cs_parser *p, uint32_t ib_idx);
+int amdgpu_vce_ring_parse_cs(struct amdgpu_cs_parser *p, struct amdgpu_job *job,
+ struct amdgpu_ib *ib);
+int amdgpu_vce_ring_parse_cs_vm(struct amdgpu_cs_parser *p,
+ struct amdgpu_job *job,
+ struct amdgpu_ib *ib);
void amdgpu_vce_ring_emit_ib(struct amdgpu_ring *ring, struct amdgpu_job *job,
struct amdgpu_ib *ib, uint32_t flags);
void amdgpu_vce_ring_emit_fence(struct amdgpu_ring *ring, u64 addr, u64 seq,
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c
index 9a19a6a57b23..f99093f2ebc7 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c
@@ -27,6 +27,7 @@
#include <linux/firmware.h>
#include <linux/module.h>
#include <linux/pci.h>
+#include <linux/debugfs.h>
#include <drm/drm_drv.h>
#include "amdgpu.h"
@@ -51,6 +52,7 @@
#define FIRMWARE_ALDEBARAN "amdgpu/aldebaran_vcn.bin"
#define FIRMWARE_BEIGE_GOBY "amdgpu/beige_goby_vcn.bin"
#define FIRMWARE_YELLOW_CARP "amdgpu/yellow_carp_vcn.bin"
+#define FIRMWARE_VCN_3_1_2 "amdgpu/vcn_3_1_2_vcn.bin"
MODULE_FIRMWARE(FIRMWARE_RAVEN);
MODULE_FIRMWARE(FIRMWARE_PICASSO);
@@ -68,6 +70,7 @@ MODULE_FIRMWARE(FIRMWARE_VANGOGH);
MODULE_FIRMWARE(FIRMWARE_DIMGREY_CAVEFISH);
MODULE_FIRMWARE(FIRMWARE_BEIGE_GOBY);
MODULE_FIRMWARE(FIRMWARE_YELLOW_CARP);
+MODULE_FIRMWARE(FIRMWARE_VCN_3_1_2);
static void amdgpu_vcn_idle_work_handler(struct work_struct *work);
@@ -77,6 +80,7 @@ int amdgpu_vcn_sw_init(struct amdgpu_device *adev)
const char *fw_name;
const struct common_firmware_header *hdr;
unsigned char fw_check;
+ unsigned int fw_shared_size, log_offset;
int i, r;
INIT_DELAYED_WORK(&adev->vcn.idle_work, amdgpu_vcn_idle_work_handler);
@@ -165,6 +169,12 @@ int amdgpu_vcn_sw_init(struct amdgpu_device *adev)
(adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG))
adev->vcn.indirect_sram = true;
break;
+ case IP_VERSION(3, 1, 2):
+ fw_name = FIRMWARE_VCN_3_1_2;
+ if ((adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) &&
+ (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG))
+ adev->vcn.indirect_sram = true;
+ break;
default:
return -EINVAL;
}
@@ -218,7 +228,12 @@ int amdgpu_vcn_sw_init(struct amdgpu_device *adev)
bo_size = AMDGPU_VCN_STACK_SIZE + AMDGPU_VCN_CONTEXT_SIZE;
if (adev->firmware.load_type != AMDGPU_FW_LOAD_PSP)
bo_size += AMDGPU_GPU_PAGE_ALIGN(le32_to_cpu(hdr->ucode_size_bytes) + 8);
- bo_size += AMDGPU_GPU_PAGE_ALIGN(sizeof(struct amdgpu_fw_shared));
+ fw_shared_size = AMDGPU_GPU_PAGE_ALIGN(sizeof(struct amdgpu_fw_shared));
+ log_offset = offsetof(struct amdgpu_fw_shared, fw_log);
+ bo_size += fw_shared_size;
+
+ if (amdgpu_vcnfw_log)
+ bo_size += AMDGPU_VCNFW_LOG_SIZE;
for (i = 0; i < adev->vcn.num_vcn_inst; i++) {
if (adev->vcn.harvest_config & (1 << i))
@@ -232,10 +247,18 @@ int amdgpu_vcn_sw_init(struct amdgpu_device *adev)
return r;
}
- adev->vcn.inst[i].fw_shared_cpu_addr = adev->vcn.inst[i].cpu_addr +
- bo_size - AMDGPU_GPU_PAGE_ALIGN(sizeof(struct amdgpu_fw_shared));
- adev->vcn.inst[i].fw_shared_gpu_addr = adev->vcn.inst[i].gpu_addr +
- bo_size - AMDGPU_GPU_PAGE_ALIGN(sizeof(struct amdgpu_fw_shared));
+ adev->vcn.inst[i].fw_shared.cpu_addr = adev->vcn.inst[i].cpu_addr +
+ bo_size - fw_shared_size;
+ adev->vcn.inst[i].fw_shared.gpu_addr = adev->vcn.inst[i].gpu_addr +
+ bo_size - fw_shared_size;
+
+ adev->vcn.inst[i].fw_shared.mem_size = fw_shared_size;
+
+ if (amdgpu_vcnfw_log) {
+ adev->vcn.inst[i].fw_shared.cpu_addr -= AMDGPU_VCNFW_LOG_SIZE;
+ adev->vcn.inst[i].fw_shared.gpu_addr -= AMDGPU_VCNFW_LOG_SIZE;
+ adev->vcn.inst[i].fw_shared.log_offset = log_offset;
+ }
if (adev->vcn.indirect_sram) {
r = amdgpu_bo_create_kernel(adev, 64 * 2 * 4, PAGE_SIZE,
@@ -971,3 +994,112 @@ void amdgpu_vcn_setup_ucode(struct amdgpu_device *adev)
dev_info(adev->dev, "Will use PSP to load VCN firmware\n");
}
}
+
+/*
+ * debugfs for mapping vcn firmware log buffer.
+ */
+#if defined(CONFIG_DEBUG_FS)
+static ssize_t amdgpu_debugfs_vcn_fwlog_read(struct file *f, char __user *buf,
+ size_t size, loff_t *pos)
+{
+ struct amdgpu_vcn_inst *vcn;
+ void *log_buf;
+ volatile struct amdgpu_vcn_fwlog *plog;
+ unsigned int read_pos, write_pos, available, i, read_bytes = 0;
+ unsigned int read_num[2] = {0};
+
+ vcn = file_inode(f)->i_private;
+ if (!vcn)
+ return -ENODEV;
+
+ if (!vcn->fw_shared.cpu_addr || !amdgpu_vcnfw_log)
+ return -EFAULT;
+
+ log_buf = vcn->fw_shared.cpu_addr + vcn->fw_shared.mem_size;
+
+ plog = (volatile struct amdgpu_vcn_fwlog *)log_buf;
+ read_pos = plog->rptr;
+ write_pos = plog->wptr;
+
+ if (read_pos > AMDGPU_VCNFW_LOG_SIZE || write_pos > AMDGPU_VCNFW_LOG_SIZE)
+ return -EFAULT;
+
+ if (!size || (read_pos == write_pos))
+ return 0;
+
+ if (write_pos > read_pos) {
+ available = write_pos - read_pos;
+ read_num[0] = min(size, (size_t)available);
+ } else {
+ read_num[0] = AMDGPU_VCNFW_LOG_SIZE - read_pos;
+ available = read_num[0] + write_pos - plog->header_size;
+ if (size > available)
+ read_num[1] = write_pos - plog->header_size;
+ else if (size > read_num[0])
+ read_num[1] = size - read_num[0];
+ else
+ read_num[0] = size;
+ }
+
+ for (i = 0; i < 2; i++) {
+ if (read_num[i]) {
+ if (read_pos == AMDGPU_VCNFW_LOG_SIZE)
+ read_pos = plog->header_size;
+ if (read_num[i] == copy_to_user((buf + read_bytes),
+ (log_buf + read_pos), read_num[i]))
+ return -EFAULT;
+
+ read_bytes += read_num[i];
+ read_pos += read_num[i];
+ }
+ }
+
+ plog->rptr = read_pos;
+ *pos += read_bytes;
+ return read_bytes;
+}
+
+static const struct file_operations amdgpu_debugfs_vcnfwlog_fops = {
+ .owner = THIS_MODULE,
+ .read = amdgpu_debugfs_vcn_fwlog_read,
+ .llseek = default_llseek
+};
+#endif
+
+void amdgpu_debugfs_vcn_fwlog_init(struct amdgpu_device *adev, uint8_t i,
+ struct amdgpu_vcn_inst *vcn)
+{
+#if defined(CONFIG_DEBUG_FS)
+ struct drm_minor *minor = adev_to_drm(adev)->primary;
+ struct dentry *root = minor->debugfs_root;
+ char name[32];
+
+ sprintf(name, "amdgpu_vcn_%d_fwlog", i);
+ debugfs_create_file_size(name, S_IFREG | S_IRUGO, root, vcn,
+ &amdgpu_debugfs_vcnfwlog_fops,
+ AMDGPU_VCNFW_LOG_SIZE);
+#endif
+}
+
+void amdgpu_vcn_fwlog_init(struct amdgpu_vcn_inst *vcn)
+{
+#if defined(CONFIG_DEBUG_FS)
+ volatile uint32_t *flag = vcn->fw_shared.cpu_addr;
+ void *fw_log_cpu_addr = vcn->fw_shared.cpu_addr + vcn->fw_shared.mem_size;
+ uint64_t fw_log_gpu_addr = vcn->fw_shared.gpu_addr + vcn->fw_shared.mem_size;
+ volatile struct amdgpu_vcn_fwlog *log_buf = fw_log_cpu_addr;
+ volatile struct amdgpu_fw_shared_fw_logging *fw_log = vcn->fw_shared.cpu_addr
+ + vcn->fw_shared.log_offset;
+ *flag |= cpu_to_le32(AMDGPU_VCN_FW_LOGGING_FLAG);
+ fw_log->is_enabled = 1;
+ fw_log->addr_lo = cpu_to_le32(fw_log_gpu_addr & 0xFFFFFFFF);
+ fw_log->addr_hi = cpu_to_le32(fw_log_gpu_addr >> 32);
+ fw_log->size = cpu_to_le32(AMDGPU_VCNFW_LOG_SIZE);
+
+ log_buf->header_size = sizeof(struct amdgpu_vcn_fwlog);
+ log_buf->buffer_size = AMDGPU_VCNFW_LOG_SIZE;
+ log_buf->rptr = log_buf->header_size;
+ log_buf->wptr = log_buf->header_size;
+ log_buf->wrapped = 0;
+#endif
+}
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.h
index 5d3728b027d3..e2fde88aaf5e 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.h
@@ -158,6 +158,7 @@
#define AMDGPU_VCN_FW_SHARED_FLAG_0_RB (1 << 6)
#define AMDGPU_VCN_MULTI_QUEUE_FLAG (1 << 8)
#define AMDGPU_VCN_SW_RING_FLAG (1 << 9)
+#define AMDGPU_VCN_FW_LOGGING_FLAG (1 << 10)
#define AMDGPU_VCN_IB_FLAG_DECODE_BUFFER 0x00000001
#define AMDGPU_VCN_CMD_FLAG_MSG_BUFFER 0x00000001
@@ -205,6 +206,13 @@ struct amdgpu_vcn_reg{
unsigned scratch9;
};
+struct amdgpu_vcn_fw_shared {
+ void *cpu_addr;
+ uint64_t gpu_addr;
+ uint32_t mem_size;
+ uint32_t log_offset;
+};
+
struct amdgpu_vcn_inst {
struct amdgpu_bo *vcpu_bo;
void *cpu_addr;
@@ -221,8 +229,7 @@ struct amdgpu_vcn_inst {
uint64_t dpg_sram_gpu_addr;
uint32_t *dpg_sram_curr_addr;
atomic_t dpg_enc_submission_cnt;
- void *fw_shared_cpu_addr;
- uint64_t fw_shared_gpu_addr;
+ struct amdgpu_vcn_fw_shared fw_shared;
};
struct amdgpu_vcn {
@@ -265,6 +272,13 @@ struct amdgpu_fw_shared_sw_ring {
uint8_t padding[3];
};
+struct amdgpu_fw_shared_fw_logging {
+ uint8_t is_enabled;
+ uint32_t addr_lo;
+ uint32_t addr_hi;
+ uint32_t size;
+};
+
struct amdgpu_fw_shared {
uint32_t present_flag_0;
uint8_t pad[44];
@@ -272,6 +286,15 @@ struct amdgpu_fw_shared {
uint8_t pad1[1];
struct amdgpu_fw_shared_multi_queue multi_queue;
struct amdgpu_fw_shared_sw_ring sw_ring;
+ struct amdgpu_fw_shared_fw_logging fw_log;
+};
+
+struct amdgpu_vcn_fwlog {
+ uint32_t rptr;
+ uint32_t wptr;
+ uint32_t buffer_size;
+ uint32_t header_size;
+ uint8_t wrapped;
};
struct amdgpu_vcn_decode_buffer {
@@ -313,4 +336,7 @@ enum amdgpu_ring_priority_level amdgpu_vcn_get_enc_ring_prio(int ring);
void amdgpu_vcn_setup_ucode(struct amdgpu_device *adev);
+void amdgpu_vcn_fwlog_init(struct amdgpu_vcn_inst *vcn);
+void amdgpu_debugfs_vcn_fwlog_init(struct amdgpu_device *adev,
+ uint8_t i, struct amdgpu_vcn_inst *vcn);
#endif
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c
index 07bc0f504713..a025f080aa6a 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c
@@ -575,8 +575,10 @@ static int amdgpu_virt_write_vf2pf_data(struct amdgpu_device *adev)
vf2pf_info->driver_cert = 0;
vf2pf_info->os_info.all = 0;
- vf2pf_info->fb_usage = amdgpu_vram_mgr_usage(&adev->mman.vram_mgr) >> 20;
- vf2pf_info->fb_vis_usage = amdgpu_vram_mgr_vis_usage(&adev->mman.vram_mgr) >> 20;
+ vf2pf_info->fb_usage =
+ ttm_resource_manager_usage(&adev->mman.vram_mgr.manager) >> 20;
+ vf2pf_info->fb_vis_usage =
+ amdgpu_vram_mgr_vis_usage(&adev->mman.vram_mgr) >> 20;
vf2pf_info->fb_size = adev->gmc.real_vram_size >> 20;
vf2pf_info->fb_vis_size = adev->gmc.visible_vram_size >> 20;
@@ -820,3 +822,148 @@ void amdgpu_virt_update_sriov_video_codec(struct amdgpu_device *adev,
}
}
}
+
+static bool amdgpu_virt_get_rlcg_reg_access_flag(struct amdgpu_device *adev,
+ u32 acc_flags, u32 hwip,
+ bool write, u32 *rlcg_flag)
+{
+ bool ret = false;
+
+ switch (hwip) {
+ case GC_HWIP:
+ if (amdgpu_sriov_reg_indirect_gc(adev)) {
+ *rlcg_flag =
+ write ? AMDGPU_RLCG_GC_WRITE : AMDGPU_RLCG_GC_READ;
+ ret = true;
+ /* only in new version, AMDGPU_REGS_NO_KIQ and
+ * AMDGPU_REGS_RLC are enabled simultaneously */
+ } else if ((acc_flags & AMDGPU_REGS_RLC) &&
+ !(acc_flags & AMDGPU_REGS_NO_KIQ) && write) {
+ *rlcg_flag = AMDGPU_RLCG_GC_WRITE_LEGACY;
+ ret = true;
+ }
+ break;
+ case MMHUB_HWIP:
+ if (amdgpu_sriov_reg_indirect_mmhub(adev) &&
+ (acc_flags & AMDGPU_REGS_RLC) && write) {
+ *rlcg_flag = AMDGPU_RLCG_MMHUB_WRITE;
+ ret = true;
+ }
+ break;
+ default:
+ break;
+ }
+ return ret;
+}
+
+static u32 amdgpu_virt_rlcg_reg_rw(struct amdgpu_device *adev, u32 offset, u32 v, u32 flag)
+{
+ struct amdgpu_rlcg_reg_access_ctrl *reg_access_ctrl;
+ uint32_t timeout = 50000;
+ uint32_t i, tmp;
+ uint32_t ret = 0;
+ static void *scratch_reg0;
+ static void *scratch_reg1;
+ static void *scratch_reg2;
+ static void *scratch_reg3;
+ static void *spare_int;
+
+ if (!adev->gfx.rlc.rlcg_reg_access_supported) {
+ dev_err(adev->dev,
+ "indirect registers access through rlcg is not available\n");
+ return 0;
+ }
+
+ reg_access_ctrl = &adev->gfx.rlc.reg_access_ctrl;
+ scratch_reg0 = (void __iomem *)adev->rmmio + 4 * reg_access_ctrl->scratch_reg0;
+ scratch_reg1 = (void __iomem *)adev->rmmio + 4 * reg_access_ctrl->scratch_reg1;
+ scratch_reg2 = (void __iomem *)adev->rmmio + 4 * reg_access_ctrl->scratch_reg2;
+ scratch_reg3 = (void __iomem *)adev->rmmio + 4 * reg_access_ctrl->scratch_reg3;
+ if (reg_access_ctrl->spare_int)
+ spare_int = (void __iomem *)adev->rmmio + 4 * reg_access_ctrl->spare_int;
+
+ if (offset == reg_access_ctrl->grbm_cntl) {
+ /* if the target reg offset is grbm_cntl, write to scratch_reg2 */
+ writel(v, scratch_reg2);
+ writel(v, ((void __iomem *)adev->rmmio) + (offset * 4));
+ } else if (offset == reg_access_ctrl->grbm_idx) {
+ /* if the target reg offset is grbm_idx, write to scratch_reg3 */
+ writel(v, scratch_reg3);
+ writel(v, ((void __iomem *)adev->rmmio) + (offset * 4));
+ } else {
+ /*
+ * SCRATCH_REG0 = read/write value
+ * SCRATCH_REG1[30:28] = command
+ * SCRATCH_REG1[19:0] = address in dword
+ * SCRATCH_REG1[26:24] = Error reporting
+ */
+ writel(v, scratch_reg0);
+ writel((offset | flag), scratch_reg1);
+ if (reg_access_ctrl->spare_int)
+ writel(1, spare_int);
+
+ for (i = 0; i < timeout; i++) {
+ tmp = readl(scratch_reg1);
+ if (!(tmp & AMDGPU_RLCG_SCRATCH1_ADDRESS_MASK))
+ break;
+ udelay(10);
+ }
+
+ if (i >= timeout) {
+ if (amdgpu_sriov_rlcg_error_report_enabled(adev)) {
+ if (tmp & AMDGPU_RLCG_VFGATE_DISABLED) {
+ dev_err(adev->dev,
+ "vfgate is disabled, rlcg failed to program reg: 0x%05x\n", offset);
+ } else if (tmp & AMDGPU_RLCG_WRONG_OPERATION_TYPE) {
+ dev_err(adev->dev,
+ "wrong operation type, rlcg failed to program reg: 0x%05x\n", offset);
+ } else if (tmp & AMDGPU_RLCG_REG_NOT_IN_RANGE) {
+ dev_err(adev->dev,
+ "regiser is not in range, rlcg failed to program reg: 0x%05x\n", offset);
+ } else {
+ dev_err(adev->dev,
+ "unknown error type, rlcg failed to program reg: 0x%05x\n", offset);
+ }
+ } else {
+ dev_err(adev->dev,
+ "timeout: rlcg faled to program reg: 0x%05x\n", offset);
+ }
+ }
+ }
+
+ ret = readl(scratch_reg0);
+ return ret;
+}
+
+void amdgpu_sriov_wreg(struct amdgpu_device *adev,
+ u32 offset, u32 value,
+ u32 acc_flags, u32 hwip)
+{
+ u32 rlcg_flag;
+
+ if (!amdgpu_sriov_runtime(adev) &&
+ amdgpu_virt_get_rlcg_reg_access_flag(adev, acc_flags, hwip, true, &rlcg_flag)) {
+ amdgpu_virt_rlcg_reg_rw(adev, offset, value, rlcg_flag);
+ return;
+ }
+
+ if (acc_flags & AMDGPU_REGS_NO_KIQ)
+ WREG32_NO_KIQ(offset, value);
+ else
+ WREG32(offset, value);
+}
+
+u32 amdgpu_sriov_rreg(struct amdgpu_device *adev,
+ u32 offset, u32 acc_flags, u32 hwip)
+{
+ u32 rlcg_flag;
+
+ if (!amdgpu_sriov_runtime(adev) &&
+ amdgpu_virt_get_rlcg_reg_access_flag(adev, acc_flags, hwip, false, &rlcg_flag))
+ return amdgpu_virt_rlcg_reg_rw(adev, offset, 0, rlcg_flag);
+
+ if (acc_flags & AMDGPU_REGS_NO_KIQ)
+ return RREG32_NO_KIQ(offset);
+ else
+ return RREG32(offset);
+}
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h
index 9adfb8d63280..239f232f9c02 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h
@@ -32,6 +32,19 @@
#define AMDGPU_PASSTHROUGH_MODE (1 << 3) /* thw whole GPU is pass through for VM */
#define AMDGPU_SRIOV_CAPS_RUNTIME (1 << 4) /* is out of full access mode */
+/* flags for indirect register access path supported by rlcg for sriov */
+#define AMDGPU_RLCG_GC_WRITE_LEGACY (0x8 << 28)
+#define AMDGPU_RLCG_GC_WRITE (0x0 << 28)
+#define AMDGPU_RLCG_GC_READ (0x1 << 28)
+#define AMDGPU_RLCG_MMHUB_WRITE (0x2 << 28)
+
+/* error code for indirect register access path supported by rlcg for sriov */
+#define AMDGPU_RLCG_VFGATE_DISABLED 0x4000000
+#define AMDGPU_RLCG_WRONG_OPERATION_TYPE 0x2000000
+#define AMDGPU_RLCG_REG_NOT_IN_RANGE 0x1000000
+
+#define AMDGPU_RLCG_SCRATCH1_ADDRESS_MASK 0xFFFFF
+
/* all asic after AI use this offset */
#define mmRCC_IOV_FUNC_IDENTIFIER 0xDE5
/* tonga/fiji use this offset */
@@ -275,13 +288,18 @@ struct amdgpu_video_codec_info;
(amdgpu_sriov_vf((adev)) && \
((adev)->virt.reg_access & (AMDGIM_FEATURE_GC_REG_RLC_EN)))
+#define amdgpu_sriov_rlcg_error_report_enabled(adev) \
+ (amdgpu_sriov_reg_indirect_mmhub(adev) || amdgpu_sriov_reg_indirect_gc(adev))
+
#define amdgpu_passthrough(adev) \
((adev)->virt.caps & AMDGPU_PASSTHROUGH_MODE)
static inline bool is_virtual_machine(void)
{
-#ifdef CONFIG_X86
+#if defined(CONFIG_X86)
return boot_cpu_has(X86_FEATURE_HYPERVISOR);
+#elif defined(CONFIG_ARM64)
+ return !is_kernel_in_hyp_mode();
#else
return false;
#endif
@@ -293,7 +311,6 @@ static inline bool is_virtual_machine(void)
((!amdgpu_in_reset(adev)) && adev->virt.tdr_debug)
#define amdgpu_sriov_is_normal(adev) \
((!amdgpu_in_reset(adev)) && (!adev->virt.tdr_debug))
-
bool amdgpu_virt_mmio_blocked(struct amdgpu_device *adev);
void amdgpu_virt_init_setting(struct amdgpu_device *adev);
void amdgpu_virt_kiq_reg_write_reg_wait(struct amdgpu_device *adev,
@@ -321,4 +338,9 @@ enum amdgpu_sriov_vf_mode amdgpu_virt_get_sriov_vf_mode(struct amdgpu_device *ad
void amdgpu_virt_update_sriov_video_codec(struct amdgpu_device *adev,
struct amdgpu_video_codec_info *encode, uint32_t encode_array_size,
struct amdgpu_video_codec_info *decode, uint32_t decode_array_size);
+void amdgpu_sriov_wreg(struct amdgpu_device *adev,
+ u32 offset, u32 value,
+ u32 acc_flags, u32 hwip);
+u32 amdgpu_sriov_rreg(struct amdgpu_device *adev,
+ u32 offset, u32 acc_flags, u32 hwip);
#endif
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c
index d99c8779b51e..5224d9a39737 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c
@@ -391,7 +391,6 @@ static struct drm_plane *amdgpu_vkms_plane_init(struct drm_device *dev,
int index)
{
struct drm_plane *plane;
- uint64_t modifiers[] = {DRM_FORMAT_MOD_LINEAR, DRM_FORMAT_MOD_INVALID};
int ret;
plane = kzalloc(sizeof(*plane), GFP_KERNEL);
@@ -402,7 +401,7 @@ static struct drm_plane *amdgpu_vkms_plane_init(struct drm_device *dev,
&amdgpu_vkms_plane_funcs,
amdgpu_vkms_formats,
ARRAY_SIZE(amdgpu_vkms_formats),
- modifiers, type, NULL);
+ NULL, type, NULL);
if (ret) {
kfree(plane);
return ERR_PTR(ret);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
index b37fc7d7d2c7..fc4563cf2828 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
@@ -375,6 +375,8 @@ static void amdgpu_vm_bo_base_init(struct amdgpu_vm_bo_base *base,
if (bo->tbo.base.resv != vm->root.bo->tbo.base.resv)
return;
+ dma_resv_assert_held(vm->root.bo->tbo.base.resv);
+
vm->bulk_moveable = false;
if (bo->tbo.type == ttm_bo_type_kernel && bo->parent)
amdgpu_vm_bo_relocated(base);
@@ -768,11 +770,17 @@ int amdgpu_vm_validate_pt_bos(struct amdgpu_device *adev, struct amdgpu_vm *vm,
* Check if all VM PDs/PTs are ready for updates
*
* Returns:
- * True if eviction list is empty.
+ * True if VM is not evicting.
*/
bool amdgpu_vm_ready(struct amdgpu_vm *vm)
{
- return list_empty(&vm->evicted);
+ bool ret;
+
+ amdgpu_vm_eviction_lock(vm);
+ ret = !vm->evicting;
+ amdgpu_vm_eviction_unlock(vm);
+
+ return ret && list_empty(&vm->evicted);
}
/**
@@ -1634,7 +1642,7 @@ static int amdgpu_vm_update_ptes(struct amdgpu_vm_update_params *params,
nptes = max(nptes, 1u);
trace_amdgpu_vm_update_ptes(params, frag_start, upd_end,
- nptes, dst, incr, upd_flags,
+ min(nptes, 32u), dst, incr, upd_flags,
vm->task_info.pid,
vm->immediate.fence_context);
amdgpu_vm_update_flags(params, to_amdgpu_bo_vm(pt),
@@ -2257,6 +2265,7 @@ struct amdgpu_bo_va *amdgpu_vm_bo_add(struct amdgpu_device *adev,
if (!bo)
return bo_va;
+ dma_resv_assert_held(bo->tbo.base.resv);
if (amdgpu_dmabuf_is_xgmi_accessible(adev, bo)) {
bo_va->is_xgmi = true;
/* Power up XGMI if it can be potentially used */
@@ -2634,7 +2643,7 @@ void amdgpu_vm_bo_trace_cs(struct amdgpu_vm *vm, struct ww_acquire_ctx *ticket)
}
/**
- * amdgpu_vm_bo_rmv - remove a bo to a specific vm
+ * amdgpu_vm_bo_del - remove a bo from a specific vm
*
* @adev: amdgpu_device pointer
* @bo_va: requested bo_va
@@ -2643,7 +2652,7 @@ void amdgpu_vm_bo_trace_cs(struct amdgpu_vm *vm, struct ww_acquire_ctx *ticket)
*
* Object have to be reserved!
*/
-void amdgpu_vm_bo_rmv(struct amdgpu_device *adev,
+void amdgpu_vm_bo_del(struct amdgpu_device *adev,
struct amdgpu_bo_va *bo_va)
{
struct amdgpu_bo_va_mapping *mapping, *next;
@@ -2651,7 +2660,10 @@ void amdgpu_vm_bo_rmv(struct amdgpu_device *adev,
struct amdgpu_vm *vm = bo_va->base.vm;
struct amdgpu_vm_bo_base **base;
+ dma_resv_assert_held(vm->root.bo->tbo.base.resv);
+
if (bo) {
+ dma_resv_assert_held(bo->tbo.base.resv);
if (bo->tbo.base.resv == vm->root.bo->tbo.base.resv)
vm->bulk_moveable = false;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h
index 85fcfb8c5efd..a40a6a993bb0 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h
@@ -435,7 +435,7 @@ int amdgpu_vm_bo_clear_mappings(struct amdgpu_device *adev,
struct amdgpu_bo_va_mapping *amdgpu_vm_bo_lookup_mapping(struct amdgpu_vm *vm,
uint64_t addr);
void amdgpu_vm_bo_trace_cs(struct amdgpu_vm *vm, struct ww_acquire_ctx *ticket);
-void amdgpu_vm_bo_rmv(struct amdgpu_device *adev,
+void amdgpu_vm_bo_del(struct amdgpu_device *adev,
struct amdgpu_bo_va *bo_va);
void amdgpu_vm_adjust_size(struct amdgpu_device *adev, uint32_t min_vm_size,
uint32_t fragment_size_default, unsigned max_level,
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c
index 7a2b487db57c..0a7611648573 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c
@@ -96,9 +96,9 @@ static ssize_t amdgpu_mem_info_vram_used_show(struct device *dev,
{
struct drm_device *ddev = dev_get_drvdata(dev);
struct amdgpu_device *adev = drm_to_adev(ddev);
+ struct ttm_resource_manager *man = &adev->mman.vram_mgr.manager;
- return sysfs_emit(buf, "%llu\n",
- amdgpu_vram_mgr_usage(&adev->mman.vram_mgr));
+ return sysfs_emit(buf, "%llu\n", ttm_resource_manager_usage(man));
}
/**
@@ -253,7 +253,9 @@ static void amdgpu_vram_mgr_do_reserve(struct ttm_resource_manager *man)
vis_usage = amdgpu_vram_mgr_vis_size(adev, &rsv->mm_node);
atomic64_add(vis_usage, &mgr->vis_usage);
- atomic64_add(rsv->mm_node.size << PAGE_SHIFT, &mgr->usage);
+ spin_lock(&man->bdev->lru_lock);
+ man->usage += rsv->mm_node.size << PAGE_SHIFT;
+ spin_unlock(&man->bdev->lru_lock);
list_move(&rsv->node, &mgr->reserved_pages);
}
}
@@ -281,7 +283,7 @@ int amdgpu_vram_mgr_reserve_range(struct amdgpu_vram_mgr *mgr,
rsv->mm_node.size = size >> PAGE_SHIFT;
spin_lock(&mgr->lock);
- list_add_tail(&mgr->reservations_pending, &rsv->node);
+ list_add_tail(&rsv->node, &mgr->reservations_pending);
amdgpu_vram_mgr_do_reserve(&mgr->manager);
spin_unlock(&mgr->lock);
@@ -378,19 +380,13 @@ static int amdgpu_vram_mgr_new(struct ttm_resource_manager *man,
lpfn = place->lpfn;
if (!lpfn)
- lpfn = man->size;
+ lpfn = man->size >> PAGE_SHIFT;
max_bytes = adev->gmc.mc_vram_size;
if (tbo->type != ttm_bo_type_kernel)
max_bytes -= AMDGPU_VM_RESERVED_VRAM;
- /* bail out quickly if there's likely not enough VRAM for this BO */
mem_bytes = tbo->base.size;
- if (atomic64_add_return(mem_bytes, &mgr->usage) > max_bytes) {
- r = -ENOSPC;
- goto error_sub;
- }
-
if (place->flags & TTM_PL_FLAG_CONTIGUOUS) {
pages_per_node = ~0ul;
num_nodes = 1;
@@ -408,13 +404,17 @@ static int amdgpu_vram_mgr_new(struct ttm_resource_manager *man,
node = kvmalloc(struct_size(node, mm_nodes, num_nodes),
GFP_KERNEL | __GFP_ZERO);
- if (!node) {
- r = -ENOMEM;
- goto error_sub;
- }
+ if (!node)
+ return -ENOMEM;
ttm_resource_init(tbo, place, &node->base);
+ /* bail out quickly if there's likely not enough VRAM for this BO */
+ if (ttm_resource_manager_usage(man) > max_bytes) {
+ r = -ENOSPC;
+ goto error_fini;
+ }
+
mode = DRM_MM_INSERT_BEST;
if (place->flags & TTM_PL_FLAG_TOPDOWN)
mode = DRM_MM_INSERT_HIGH;
@@ -472,10 +472,10 @@ error_free:
while (i--)
drm_mm_remove_node(&node->mm_nodes[i]);
spin_unlock(&mgr->lock);
+error_fini:
+ ttm_resource_fini(man, &node->base);
kvfree(node);
-error_sub:
- atomic64_sub(mem_bytes, &mgr->usage);
return r;
}
@@ -493,7 +493,7 @@ static void amdgpu_vram_mgr_del(struct ttm_resource_manager *man,
struct ttm_range_mgr_node *node = to_ttm_range_mgr_node(res);
struct amdgpu_vram_mgr *mgr = to_vram_mgr(man);
struct amdgpu_device *adev = to_amdgpu_device(mgr);
- uint64_t usage = 0, vis_usage = 0;
+ uint64_t vis_usage = 0;
unsigned i, pages;
spin_lock(&mgr->lock);
@@ -502,15 +502,14 @@ static void amdgpu_vram_mgr_del(struct ttm_resource_manager *man,
struct drm_mm_node *mm = &node->mm_nodes[i];
drm_mm_remove_node(mm);
- usage += mm->size << PAGE_SHIFT;
vis_usage += amdgpu_vram_mgr_vis_size(adev, mm);
}
amdgpu_vram_mgr_do_reserve(man);
spin_unlock(&mgr->lock);
- atomic64_sub(usage, &mgr->usage);
atomic64_sub(vis_usage, &mgr->vis_usage);
+ ttm_resource_fini(man, res);
kvfree(node);
}
@@ -626,18 +625,6 @@ void amdgpu_vram_mgr_free_sgt(struct device *dev,
}
/**
- * amdgpu_vram_mgr_usage - how many bytes are used in this domain
- *
- * @mgr: amdgpu_vram_mgr pointer
- *
- * Returns how many bytes are used in this domain.
- */
-uint64_t amdgpu_vram_mgr_usage(struct amdgpu_vram_mgr *mgr)
-{
- return atomic64_read(&mgr->usage);
-}
-
-/**
* amdgpu_vram_mgr_vis_usage - how many bytes are used in the visible part
*
* @mgr: amdgpu_vram_mgr pointer
@@ -662,13 +649,12 @@ static void amdgpu_vram_mgr_debug(struct ttm_resource_manager *man,
{
struct amdgpu_vram_mgr *mgr = to_vram_mgr(man);
+ drm_printf(printer, " vis usage:%llu\n",
+ amdgpu_vram_mgr_vis_usage(mgr));
+
spin_lock(&mgr->lock);
drm_mm_print(&mgr->mm, printer);
spin_unlock(&mgr->lock);
-
- drm_printf(printer, "man size:%llu pages, ram usage:%lluMB, vis usage:%lluMB\n",
- man->size, amdgpu_vram_mgr_usage(mgr) >> 20,
- amdgpu_vram_mgr_vis_usage(mgr) >> 20);
}
static const struct ttm_resource_manager_func amdgpu_vram_mgr_func = {
@@ -689,11 +675,12 @@ int amdgpu_vram_mgr_init(struct amdgpu_device *adev)
struct amdgpu_vram_mgr *mgr = &adev->mman.vram_mgr;
struct ttm_resource_manager *man = &mgr->manager;
- ttm_resource_manager_init(man, adev->gmc.real_vram_size >> PAGE_SHIFT);
+ ttm_resource_manager_init(man, &adev->mman.bdev,
+ adev->gmc.real_vram_size);
man->func = &amdgpu_vram_mgr_func;
- drm_mm_init(&mgr->mm, 0, man->size);
+ drm_mm_init(&mgr->mm, 0, man->size >> PAGE_SHIFT);
spin_lock_init(&mgr->lock);
INIT_LIST_HEAD(&mgr->reservations_pending);
INIT_LIST_HEAD(&mgr->reserved_pages);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.c
index e8b8f28c2f72..1b108d03e785 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.c
@@ -32,7 +32,8 @@
#include "wafl/wafl2_4_0_0_smn.h"
#include "wafl/wafl2_4_0_0_sh_mask.h"
-#define smnPCS_XGMI23_PCS_ERROR_STATUS 0x11a01210
+#include "amdgpu_reset.h"
+
#define smnPCS_XGMI3X16_PCS_ERROR_STATUS 0x11a0020c
#define smnPCS_GOPX1_PCS_ERROR_STATUS 0x12200210
@@ -67,17 +68,6 @@ static const int wafl_pcs_err_status_reg_arct[] = {
smnPCS_GOPX1_0_PCS_GOPX1_PCS_ERROR_STATUS + 0x100000,
};
-static const int xgmi23_pcs_err_status_reg_aldebaran[] = {
- smnPCS_XGMI23_PCS_ERROR_STATUS,
- smnPCS_XGMI23_PCS_ERROR_STATUS + 0x100000,
- smnPCS_XGMI23_PCS_ERROR_STATUS + 0x200000,
- smnPCS_XGMI23_PCS_ERROR_STATUS + 0x300000,
- smnPCS_XGMI23_PCS_ERROR_STATUS + 0x400000,
- smnPCS_XGMI23_PCS_ERROR_STATUS + 0x500000,
- smnPCS_XGMI23_PCS_ERROR_STATUS + 0x600000,
- smnPCS_XGMI23_PCS_ERROR_STATUS + 0x700000
-};
-
static const int xgmi3x16_pcs_err_status_reg_aldebaran[] = {
smnPCS_XGMI3X16_PCS_ERROR_STATUS,
smnPCS_XGMI3X16_PCS_ERROR_STATUS + 0x100000,
@@ -227,6 +217,9 @@ static void amdgpu_xgmi_hive_release(struct kobject *kobj)
struct amdgpu_hive_info *hive = container_of(
kobj, struct amdgpu_hive_info, kobj);
+ amdgpu_reset_put_reset_domain(hive->reset_domain);
+ hive->reset_domain = NULL;
+
mutex_destroy(&hive->hive_lock);
kfree(hive);
}
@@ -398,15 +391,35 @@ struct amdgpu_hive_info *amdgpu_get_xgmi_hive(struct amdgpu_device *adev)
goto pro_end;
}
+ /**
+ * Avoid recreating reset domain when hive is reconstructed for the case
+ * of reset the devices in the XGMI hive during probe for SRIOV
+ * See https://www.spinics.net/lists/amd-gfx/msg58836.html
+ */
+ if (adev->reset_domain->type != XGMI_HIVE) {
+ hive->reset_domain = amdgpu_reset_create_reset_domain(XGMI_HIVE, "amdgpu-reset-hive");
+ if (!hive->reset_domain) {
+ dev_err(adev->dev, "XGMI: failed initializing reset domain for xgmi hive\n");
+ ret = -ENOMEM;
+ kobject_put(&hive->kobj);
+ kfree(hive);
+ hive = NULL;
+ goto pro_end;
+ }
+ } else {
+ amdgpu_reset_get_reset_domain(adev->reset_domain);
+ hive->reset_domain = adev->reset_domain;
+ }
+
hive->hive_id = adev->gmc.xgmi.hive_id;
INIT_LIST_HEAD(&hive->device_list);
INIT_LIST_HEAD(&hive->node);
mutex_init(&hive->hive_lock);
- atomic_set(&hive->in_reset, 0);
atomic_set(&hive->number_devices, 0);
task_barrier_init(&hive->tb);
hive->pstate = AMDGPU_XGMI_PSTATE_UNKNOWN;
hive->hi_req_gpu = NULL;
+
/*
* hive pstate on boot is high in vega20 so we have to go to low
* pstate on after boot.
@@ -732,53 +745,15 @@ int amdgpu_xgmi_remove_device(struct amdgpu_device *adev)
return psp_xgmi_terminate(&adev->psp);
}
-static int amdgpu_xgmi_ras_late_init(struct amdgpu_device *adev)
+static int amdgpu_xgmi_ras_late_init(struct amdgpu_device *adev, struct ras_common_if *ras_block)
{
- int r;
- struct ras_ih_if ih_info = {
- .cb = NULL,
- };
- struct ras_fs_if fs_info = {
- .sysfs_name = "xgmi_wafl_err_count",
- };
-
if (!adev->gmc.xgmi.supported ||
adev->gmc.xgmi.num_physical_nodes == 0)
return 0;
- adev->gmc.xgmi.ras_funcs->reset_ras_error_count(adev);
-
- if (!adev->gmc.xgmi.ras_if) {
- adev->gmc.xgmi.ras_if = kmalloc(sizeof(struct ras_common_if), GFP_KERNEL);
- if (!adev->gmc.xgmi.ras_if)
- return -ENOMEM;
- adev->gmc.xgmi.ras_if->block = AMDGPU_RAS_BLOCK__XGMI_WAFL;
- adev->gmc.xgmi.ras_if->type = AMDGPU_RAS_ERROR__MULTI_UNCORRECTABLE;
- adev->gmc.xgmi.ras_if->sub_block_index = 0;
- }
- ih_info.head = fs_info.head = *adev->gmc.xgmi.ras_if;
- r = amdgpu_ras_late_init(adev, adev->gmc.xgmi.ras_if,
- &fs_info, &ih_info);
- if (r || !amdgpu_ras_is_supported(adev, adev->gmc.xgmi.ras_if->block)) {
- kfree(adev->gmc.xgmi.ras_if);
- adev->gmc.xgmi.ras_if = NULL;
- }
-
- return r;
-}
+ adev->gmc.xgmi.ras->ras_block.hw_ops->reset_ras_error_count(adev);
-static void amdgpu_xgmi_ras_fini(struct amdgpu_device *adev)
-{
- if (amdgpu_ras_is_supported(adev, AMDGPU_RAS_BLOCK__XGMI_WAFL) &&
- adev->gmc.xgmi.ras_if) {
- struct ras_common_if *ras_if = adev->gmc.xgmi.ras_if;
- struct ras_ih_if ih_info = {
- .cb = NULL,
- };
-
- amdgpu_ras_late_fini(adev, ras_if, &ih_info);
- kfree(ras_if);
- }
+ return amdgpu_ras_block_late_init(adev, ras_block);
}
uint64_t amdgpu_xgmi_get_relative_phy_addr(struct amdgpu_device *adev,
@@ -810,9 +785,6 @@ static void amdgpu_xgmi_reset_ras_error_count(struct amdgpu_device *adev)
xgmi_pcs_err_status_reg_vg20[i]);
break;
case CHIP_ALDEBARAN:
- for (i = 0; i < ARRAY_SIZE(xgmi23_pcs_err_status_reg_aldebaran); i++)
- pcs_clear_status(adev,
- xgmi23_pcs_err_status_reg_aldebaran[i]);
for (i = 0; i < ARRAY_SIZE(xgmi3x16_pcs_err_status_reg_aldebaran); i++)
pcs_clear_status(adev,
xgmi3x16_pcs_err_status_reg_aldebaran[i]);
@@ -865,7 +837,7 @@ static int amdgpu_xgmi_query_pcs_error_status(struct amdgpu_device *adev,
return 0;
}
-static int amdgpu_xgmi_query_ras_error_count(struct amdgpu_device *adev,
+static void amdgpu_xgmi_query_ras_error_count(struct amdgpu_device *adev,
void *ras_error_status)
{
struct ras_err_data *err_data = (struct ras_err_data *)ras_error_status;
@@ -874,7 +846,7 @@ static int amdgpu_xgmi_query_ras_error_count(struct amdgpu_device *adev,
uint32_t ue_cnt = 0, ce_cnt = 0;
if (!amdgpu_ras_is_supported(adev, AMDGPU_RAS_BLOCK__XGMI_WAFL))
- return -EINVAL;
+ return ;
err_data->ue_count = 0;
err_data->ce_count = 0;
@@ -913,13 +885,6 @@ static int amdgpu_xgmi_query_ras_error_count(struct amdgpu_device *adev,
}
break;
case CHIP_ALDEBARAN:
- /* check xgmi23 pcs error */
- for (i = 0; i < ARRAY_SIZE(xgmi23_pcs_err_status_reg_aldebaran); i++) {
- data = RREG32_PCIE(xgmi23_pcs_err_status_reg_aldebaran[i]);
- if (data)
- amdgpu_xgmi_query_pcs_error_status(adev,
- data, &ue_cnt, &ce_cnt, true);
- }
/* check xgmi3x16 pcs error */
for (i = 0; i < ARRAY_SIZE(xgmi3x16_pcs_err_status_reg_aldebaran); i++) {
data = RREG32_PCIE(xgmi3x16_pcs_err_status_reg_aldebaran[i]);
@@ -940,17 +905,53 @@ static int amdgpu_xgmi_query_ras_error_count(struct amdgpu_device *adev,
break;
}
- adev->gmc.xgmi.ras_funcs->reset_ras_error_count(adev);
+ adev->gmc.xgmi.ras->ras_block.hw_ops->reset_ras_error_count(adev);
err_data->ue_count += ue_cnt;
err_data->ce_count += ce_cnt;
+}
- return 0;
+/* Trigger XGMI/WAFL error */
+static int amdgpu_ras_error_inject_xgmi(struct amdgpu_device *adev, void *inject_if)
+{
+ int ret = 0;
+ struct ta_ras_trigger_error_input *block_info =
+ (struct ta_ras_trigger_error_input *)inject_if;
+
+ if (amdgpu_dpm_set_df_cstate(adev, DF_CSTATE_DISALLOW))
+ dev_warn(adev->dev, "Failed to disallow df cstate");
+
+ if (amdgpu_dpm_allow_xgmi_power_down(adev, false))
+ dev_warn(adev->dev, "Failed to disallow XGMI power down");
+
+ ret = psp_ras_trigger_error(&adev->psp, block_info);
+
+ if (amdgpu_ras_intr_triggered())
+ return ret;
+
+ if (amdgpu_dpm_allow_xgmi_power_down(adev, true))
+ dev_warn(adev->dev, "Failed to allow XGMI power down");
+
+ if (amdgpu_dpm_set_df_cstate(adev, DF_CSTATE_ALLOW))
+ dev_warn(adev->dev, "Failed to allow df cstate");
+
+ return ret;
}
-const struct amdgpu_xgmi_ras_funcs xgmi_ras_funcs = {
- .ras_late_init = amdgpu_xgmi_ras_late_init,
- .ras_fini = amdgpu_xgmi_ras_fini,
+struct amdgpu_ras_block_hw_ops xgmi_ras_hw_ops = {
.query_ras_error_count = amdgpu_xgmi_query_ras_error_count,
.reset_ras_error_count = amdgpu_xgmi_reset_ras_error_count,
+ .ras_error_inject = amdgpu_ras_error_inject_xgmi,
+};
+
+struct amdgpu_xgmi_ras xgmi_ras = {
+ .ras_block = {
+ .ras_comm = {
+ .name = "xgmi_wafl",
+ .block = AMDGPU_RAS_BLOCK__XGMI_WAFL,
+ .type = AMDGPU_RAS_ERROR__MULTI_UNCORRECTABLE,
+ },
+ .hw_ops = &xgmi_ras_hw_ops,
+ .ras_late_init = amdgpu_xgmi_ras_late_init,
+ },
};
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.h
index d2189bf7d428..552e6fb55aa8 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.h
@@ -24,7 +24,7 @@
#include <drm/task_barrier.h>
#include "amdgpu_psp.h"
-
+#include "amdgpu_ras.h"
struct amdgpu_hive_info {
struct kobject kobj;
@@ -33,7 +33,6 @@ struct amdgpu_hive_info {
struct list_head node;
atomic_t number_devices;
struct mutex hive_lock;
- atomic_t in_reset;
int hi_req_count;
struct amdgpu_device *hi_req_gpu;
struct task_barrier tb;
@@ -42,6 +41,8 @@ struct amdgpu_hive_info {
AMDGPU_XGMI_PSTATE_MAX_VEGA20,
AMDGPU_XGMI_PSTATE_UNKNOWN
} pstate;
+
+ struct amdgpu_reset_domain *reset_domain;
};
struct amdgpu_pcs_ras_field {
@@ -50,7 +51,7 @@ struct amdgpu_pcs_ras_field {
uint32_t pcs_err_shift;
};
-extern const struct amdgpu_xgmi_ras_funcs xgmi_ras_funcs;
+extern struct amdgpu_xgmi_ras xgmi_ras;
struct amdgpu_hive_info *amdgpu_get_xgmi_hive(struct amdgpu_device *adev);
void amdgpu_put_xgmi_hive(struct amdgpu_hive_info *hive);
int amdgpu_xgmi_update_topology(struct amdgpu_hive_info *hive, struct amdgpu_device *adev);
@@ -66,7 +67,8 @@ uint64_t amdgpu_xgmi_get_relative_phy_addr(struct amdgpu_device *adev,
static inline bool amdgpu_xgmi_same_hive(struct amdgpu_device *adev,
struct amdgpu_device *bo_adev)
{
- return (adev != bo_adev &&
+ return (amdgpu_use_xgmi_p2p &&
+ adev != bo_adev &&
adev->gmc.xgmi.hive_id &&
adev->gmc.xgmi.hive_id == bo_adev->gmc.xgmi.hive_id);
}
diff --git a/drivers/gpu/drm/amd/amdgpu/athub_v1_0.c b/drivers/gpu/drm/amd/amdgpu/athub_v1_0.c
index 3ea557864320..88642e7ecdf4 100644
--- a/drivers/gpu/drm/amd/amdgpu/athub_v1_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/athub_v1_0.c
@@ -68,12 +68,13 @@ int athub_v1_0_set_clockgating(struct amdgpu_device *adev,
if (amdgpu_sriov_vf(adev))
return 0;
- switch (adev->asic_type) {
- case CHIP_VEGA10:
- case CHIP_VEGA12:
- case CHIP_VEGA20:
- case CHIP_RAVEN:
- case CHIP_RENOIR:
+ switch (adev->ip_versions[ATHUB_HWIP][0]) {
+ case IP_VERSION(9, 0, 0):
+ case IP_VERSION(9, 1, 0):
+ case IP_VERSION(9, 2, 0):
+ case IP_VERSION(9, 3, 0):
+ case IP_VERSION(9, 4, 0):
+ case IP_VERSION(1, 5, 0):
athub_update_medium_grain_clock_gating(adev,
state == AMD_CG_STATE_GATE);
athub_update_medium_grain_light_sleep(adev,
diff --git a/drivers/gpu/drm/amd/amdgpu/athub_v2_0.c b/drivers/gpu/drm/amd/amdgpu/athub_v2_0.c
index ab6a07e5e8c4..a720436857b4 100644
--- a/drivers/gpu/drm/amd/amdgpu/athub_v2_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/athub_v2_0.c
@@ -78,6 +78,7 @@ int athub_v2_0_set_clockgating(struct amdgpu_device *adev,
return 0;
switch (adev->ip_versions[ATHUB_HWIP][0]) {
+ case IP_VERSION(1, 3, 1):
case IP_VERSION(2, 0, 0):
case IP_VERSION(2, 0, 2):
athub_v2_0_update_medium_grain_clock_gating(adev,
diff --git a/drivers/gpu/drm/amd/amdgpu/athub_v2_1.c b/drivers/gpu/drm/amd/amdgpu/athub_v2_1.c
index 2edefd10e56c..ad8e87d3d2cb 100644
--- a/drivers/gpu/drm/amd/amdgpu/athub_v2_1.c
+++ b/drivers/gpu/drm/amd/amdgpu/athub_v2_1.c
@@ -74,6 +74,7 @@ int athub_v2_1_set_clockgating(struct amdgpu_device *adev,
case IP_VERSION(2, 1, 0):
case IP_VERSION(2, 1, 1):
case IP_VERSION(2, 1, 2):
+ case IP_VERSION(2, 4, 0):
athub_v2_1_update_medium_grain_clock_gating(adev, state == AMD_CG_STATE_GATE);
athub_v2_1_update_medium_grain_light_sleep(adev, state == AMD_CG_STATE_GATE);
break;
diff --git a/drivers/gpu/drm/amd/amdgpu/atom.c b/drivers/gpu/drm/amd/amdgpu/atom.c
index 6fa2229b7229..1c5d9388ad0b 100644
--- a/drivers/gpu/drm/amd/amdgpu/atom.c
+++ b/drivers/gpu/drm/amd/amdgpu/atom.c
@@ -25,6 +25,8 @@
#include <linux/module.h>
#include <linux/sched.h>
#include <linux/slab.h>
+#include <linux/string_helpers.h>
+
#include <asm/unaligned.h>
#include <drm/drm_util.h>
@@ -740,7 +742,7 @@ static void atom_op_jump(atom_exec_context *ctx, int *ptr, int arg)
break;
}
if (arg != ATOM_COND_ALWAYS)
- SDEBUG(" taken: %s\n", execute ? "yes" : "no");
+ SDEBUG(" taken: %s\n", str_yes_no(execute));
SDEBUG(" target: 0x%04X\n", target);
if (execute) {
if (ctx->last_jump == (ctx->start + target)) {
diff --git a/drivers/gpu/drm/amd/amdgpu/atombios_dp.c b/drivers/gpu/drm/amd/amdgpu/atombios_dp.c
index f327becb022f..49a2f594fb2c 100644
--- a/drivers/gpu/drm/amd/amdgpu/atombios_dp.c
+++ b/drivers/gpu/drm/amd/amdgpu/atombios_dp.c
@@ -34,7 +34,7 @@
#include "atombios_dp.h"
#include "amdgpu_connectors.h"
#include "amdgpu_atombios.h"
-#include <drm/drm_dp_helper.h>
+#include <drm/dp/drm_dp_helper.h>
/* move these to drm_dp_helper.c/h */
#define DP_LINK_CONFIGURATION_SIZE 9
diff --git a/drivers/gpu/drm/amd/amdgpu/cik.c b/drivers/gpu/drm/amd/amdgpu/cik.c
index f10ce740a29c..de6d10390ab2 100644
--- a/drivers/gpu/drm/amd/amdgpu/cik.c
+++ b/drivers/gpu/drm/amd/amdgpu/cik.c
@@ -1719,7 +1719,7 @@ static void cik_program_aspm(struct amdgpu_device *adev)
bool disable_l0s = false, disable_l1 = false, disable_plloff_in_l1 = false;
bool disable_clkreq = false;
- if (amdgpu_aspm == 0)
+ if (!amdgpu_device_should_use_aspm(adev))
return;
if (pci_is_root_bus(adev->pdev->bus))
diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c
index d1570a462a51..288fce7dc0ed 100644
--- a/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c
@@ -2532,7 +2532,7 @@ static void dce_v10_0_crtc_dpms(struct drm_crtc *crtc, int mode)
break;
}
/* adjust pm to dpms */
- amdgpu_pm_compute_clocks(adev);
+ amdgpu_dpm_compute_clocks(adev);
}
static void dce_v10_0_crtc_prepare(struct drm_crtc *crtc)
@@ -2798,6 +2798,8 @@ static int dce_v10_0_sw_init(void *handle)
adev_to_drm(adev)->mode_config.preferred_depth = 24;
adev_to_drm(adev)->mode_config.prefer_shadow = 1;
+ adev_to_drm(adev)->mode_config.fb_modifiers_not_supported = true;
+
adev_to_drm(adev)->mode_config.fb_base = adev->gmc.aper_base;
r = amdgpu_display_modeset_create_props(adev);
diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c
index 18a7b3bd633b..cbe5250b31cb 100644
--- a/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c
@@ -2608,7 +2608,7 @@ static void dce_v11_0_crtc_dpms(struct drm_crtc *crtc, int mode)
break;
}
/* adjust pm to dpms */
- amdgpu_pm_compute_clocks(adev);
+ amdgpu_dpm_compute_clocks(adev);
}
static void dce_v11_0_crtc_prepare(struct drm_crtc *crtc)
@@ -2916,6 +2916,8 @@ static int dce_v11_0_sw_init(void *handle)
adev_to_drm(adev)->mode_config.preferred_depth = 24;
adev_to_drm(adev)->mode_config.prefer_shadow = 1;
+ adev_to_drm(adev)->mode_config.fb_modifiers_not_supported = true;
+
adev_to_drm(adev)->mode_config.fb_base = adev->gmc.aper_base;
r = amdgpu_display_modeset_create_props(adev);
diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v6_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v6_0.c
index c7803dc2b2d5..982855e6cf52 100644
--- a/drivers/gpu/drm/amd/amdgpu/dce_v6_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/dce_v6_0.c
@@ -2424,7 +2424,7 @@ static void dce_v6_0_crtc_dpms(struct drm_crtc *crtc, int mode)
break;
}
/* adjust pm to dpms */
- amdgpu_pm_compute_clocks(adev);
+ amdgpu_dpm_compute_clocks(adev);
}
static void dce_v6_0_crtc_prepare(struct drm_crtc *crtc)
@@ -2674,6 +2674,7 @@ static int dce_v6_0_sw_init(void *handle)
adev_to_drm(adev)->mode_config.max_height = 16384;
adev_to_drm(adev)->mode_config.preferred_depth = 24;
adev_to_drm(adev)->mode_config.prefer_shadow = 1;
+ adev_to_drm(adev)->mode_config.fb_modifiers_not_supported = true;
adev_to_drm(adev)->mode_config.fb_base = adev->gmc.aper_base;
r = amdgpu_display_modeset_create_props(adev);
diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c
index 8318ee8339f1..84440741c60b 100644
--- a/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c
@@ -2433,7 +2433,7 @@ static void dce_v8_0_crtc_dpms(struct drm_crtc *crtc, int mode)
break;
}
/* adjust pm to dpms */
- amdgpu_pm_compute_clocks(adev);
+ amdgpu_dpm_compute_clocks(adev);
}
static void dce_v8_0_crtc_prepare(struct drm_crtc *crtc)
@@ -2695,6 +2695,8 @@ static int dce_v8_0_sw_init(void *handle)
adev_to_drm(adev)->mode_config.preferred_depth = 24;
adev_to_drm(adev)->mode_config.prefer_shadow = 1;
+ adev_to_drm(adev)->mode_config.fb_modifiers_not_supported = true;
+
adev_to_drm(adev)->mode_config.fb_base = adev->gmc.aper_base;
r = amdgpu_display_modeset_create_props(adev);
diff --git a/drivers/gpu/drm/amd/amdgpu/df_v3_6.c b/drivers/gpu/drm/amd/amdgpu/df_v3_6.c
index 43c5e3ec9a39..f4dfca013ec5 100644
--- a/drivers/gpu/drm/amd/amdgpu/df_v3_6.c
+++ b/drivers/gpu/drm/amd/amdgpu/df_v3_6.c
@@ -458,7 +458,7 @@ static int df_v3_6_pmc_add_cntr(struct amdgpu_device *adev,
#define DEFERRED_ARM_MASK (1 << 31)
static int df_v3_6_pmc_set_deferred(struct amdgpu_device *adev,
- int counter_idx, uint64_t config,
+ uint64_t config, int counter_idx,
bool is_deferred)
{
@@ -476,8 +476,8 @@ static int df_v3_6_pmc_set_deferred(struct amdgpu_device *adev,
}
static bool df_v3_6_pmc_is_deferred(struct amdgpu_device *adev,
- int counter_idx,
- uint64_t config)
+ uint64_t config,
+ int counter_idx)
{
return (df_v3_6_pmc_has_counter(adev, config, counter_idx) &&
(adev->df_perfmon_config_assign_mask[counter_idx]
diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c
index dbe7442fb25c..f4c6accd3226 100644
--- a/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c
@@ -56,10 +56,6 @@
#define GFX10_NUM_GFX_RINGS_Sienna_Cichlid 1
#define GFX10_MEC_HPD_SIZE 2048
-#define RLCG_VFGATE_DISABLED 0x4000000
-#define RLCG_WRONG_OPERATION_TYPE 0x2000000
-#define RLCG_NOT_IN_RANGE 0x1000000
-
#define F32_CE_PROGRAM_RAM_SIZE 65536
#define RLCG_UCODE_LOADING_START_ADDRESS 0x00002000L
@@ -110,6 +106,12 @@
#define mmGOLDEN_TSC_COUNT_UPPER_Vangogh_BASE_IDX 1
#define mmGOLDEN_TSC_COUNT_LOWER_Vangogh 0x0026
#define mmGOLDEN_TSC_COUNT_LOWER_Vangogh_BASE_IDX 1
+
+#define mmGOLDEN_TSC_COUNT_UPPER_GC_10_3_6 0x002d
+#define mmGOLDEN_TSC_COUNT_UPPER_GC_10_3_6_BASE_IDX 1
+#define mmGOLDEN_TSC_COUNT_LOWER_GC_10_3_6 0x002e
+#define mmGOLDEN_TSC_COUNT_LOWER_GC_10_3_6_BASE_IDX 1
+
#define mmSPI_CONFIG_CNTL_1_Vangogh 0x2441
#define mmSPI_CONFIG_CNTL_1_Vangogh_BASE_IDX 1
#define mmVGT_TF_MEMORY_BASE_HI_Vangogh 0x2261
@@ -180,14 +182,6 @@
#define mmRLC_SPARE_INT_0_Sienna_Cichlid 0x4ca5
#define mmRLC_SPARE_INT_0_Sienna_Cichlid_BASE_IDX 1
-#define GFX_RLCG_GC_WRITE_OLD (0x8 << 28)
-#define GFX_RLCG_GC_WRITE (0x0 << 28)
-#define GFX_RLCG_GC_READ (0x1 << 28)
-#define GFX_RLCG_MMHUB_WRITE (0x2 << 28)
-
-#define RLCG_ERROR_REPORT_ENABLED(adev) \
- (amdgpu_sriov_reg_indirect_mmhub(adev) || amdgpu_sriov_reg_indirect_gc(adev))
-
MODULE_FIRMWARE("amdgpu/navi10_ce.bin");
MODULE_FIRMWARE("amdgpu/navi10_pfp.bin");
MODULE_FIRMWARE("amdgpu/navi10_me.bin");
@@ -256,13 +250,6 @@ MODULE_FIRMWARE("amdgpu/yellow_carp_mec.bin");
MODULE_FIRMWARE("amdgpu/yellow_carp_mec2.bin");
MODULE_FIRMWARE("amdgpu/yellow_carp_rlc.bin");
-MODULE_FIRMWARE("amdgpu/cyan_skillfish_ce.bin");
-MODULE_FIRMWARE("amdgpu/cyan_skillfish_pfp.bin");
-MODULE_FIRMWARE("amdgpu/cyan_skillfish_me.bin");
-MODULE_FIRMWARE("amdgpu/cyan_skillfish_mec.bin");
-MODULE_FIRMWARE("amdgpu/cyan_skillfish_mec2.bin");
-MODULE_FIRMWARE("amdgpu/cyan_skillfish_rlc.bin");
-
MODULE_FIRMWARE("amdgpu/cyan_skillfish2_ce.bin");
MODULE_FIRMWARE("amdgpu/cyan_skillfish2_pfp.bin");
MODULE_FIRMWARE("amdgpu/cyan_skillfish2_me.bin");
@@ -270,6 +257,20 @@ MODULE_FIRMWARE("amdgpu/cyan_skillfish2_mec.bin");
MODULE_FIRMWARE("amdgpu/cyan_skillfish2_mec2.bin");
MODULE_FIRMWARE("amdgpu/cyan_skillfish2_rlc.bin");
+MODULE_FIRMWARE("amdgpu/gc_10_3_6_ce.bin");
+MODULE_FIRMWARE("amdgpu/gc_10_3_6_pfp.bin");
+MODULE_FIRMWARE("amdgpu/gc_10_3_6_me.bin");
+MODULE_FIRMWARE("amdgpu/gc_10_3_6_mec.bin");
+MODULE_FIRMWARE("amdgpu/gc_10_3_6_mec2.bin");
+MODULE_FIRMWARE("amdgpu/gc_10_3_6_rlc.bin");
+
+MODULE_FIRMWARE("amdgpu/gc_10_3_7_ce.bin");
+MODULE_FIRMWARE("amdgpu/gc_10_3_7_pfp.bin");
+MODULE_FIRMWARE("amdgpu/gc_10_3_7_me.bin");
+MODULE_FIRMWARE("amdgpu/gc_10_3_7_mec.bin");
+MODULE_FIRMWARE("amdgpu/gc_10_3_7_mec2.bin");
+MODULE_FIRMWARE("amdgpu/gc_10_3_7_rlc.bin");
+
static const struct soc15_reg_golden golden_settings_gc_10_1[] =
{
SOC15_REG_GOLDEN_VALUE(GC, 0, mmCB_HW_CONTROL_4, 0xffffffff, 0x00400014),
@@ -1463,143 +1464,6 @@ static const struct soc15_reg_golden golden_settings_gc_10_1_2[] =
SOC15_REG_GOLDEN_VALUE(GC, 0, mmUTCL1_CTRL, 0xffffffff, 0x00c00000)
};
-static bool gfx_v10_get_rlcg_flag(struct amdgpu_device *adev, u32 acc_flags, u32 hwip,
- int write, u32 *rlcg_flag)
-{
- switch (hwip) {
- case GC_HWIP:
- if (amdgpu_sriov_reg_indirect_gc(adev)) {
- *rlcg_flag = write ? GFX_RLCG_GC_WRITE : GFX_RLCG_GC_READ;
-
- return true;
- /* only in new version, AMDGPU_REGS_NO_KIQ and AMDGPU_REGS_RLC enabled simultaneously */
- } else if ((acc_flags & AMDGPU_REGS_RLC) && !(acc_flags & AMDGPU_REGS_NO_KIQ)) {
- *rlcg_flag = GFX_RLCG_GC_WRITE_OLD;
-
- return true;
- }
-
- break;
- case MMHUB_HWIP:
- if (amdgpu_sriov_reg_indirect_mmhub(adev) &&
- (acc_flags & AMDGPU_REGS_RLC) && write) {
- *rlcg_flag = GFX_RLCG_MMHUB_WRITE;
- return true;
- }
-
- break;
- default:
- DRM_DEBUG("Not program register by RLCG\n");
- }
-
- return false;
-}
-
-static u32 gfx_v10_rlcg_rw(struct amdgpu_device *adev, u32 offset, u32 v, uint32_t flag)
-{
- static void *scratch_reg0;
- static void *scratch_reg1;
- static void *scratch_reg2;
- static void *scratch_reg3;
- static void *spare_int;
- static uint32_t grbm_cntl;
- static uint32_t grbm_idx;
- uint32_t i = 0;
- uint32_t retries = 50000;
- u32 ret = 0;
- u32 tmp;
-
- scratch_reg0 = adev->rmmio +
- (adev->reg_offset[GC_HWIP][0][mmSCRATCH_REG0_BASE_IDX] + mmSCRATCH_REG0) * 4;
- scratch_reg1 = adev->rmmio +
- (adev->reg_offset[GC_HWIP][0][mmSCRATCH_REG1_BASE_IDX] + mmSCRATCH_REG1) * 4;
- scratch_reg2 = adev->rmmio +
- (adev->reg_offset[GC_HWIP][0][mmSCRATCH_REG0_BASE_IDX] + mmSCRATCH_REG2) * 4;
- scratch_reg3 = adev->rmmio +
- (adev->reg_offset[GC_HWIP][0][mmSCRATCH_REG1_BASE_IDX] + mmSCRATCH_REG3) * 4;
-
- if (adev->ip_versions[GC_HWIP][0] >= IP_VERSION(10, 3, 0)) {
- spare_int = adev->rmmio +
- (adev->reg_offset[GC_HWIP][0][mmRLC_SPARE_INT_0_Sienna_Cichlid_BASE_IDX]
- + mmRLC_SPARE_INT_0_Sienna_Cichlid) * 4;
- } else {
- spare_int = adev->rmmio +
- (adev->reg_offset[GC_HWIP][0][mmRLC_SPARE_INT_BASE_IDX] + mmRLC_SPARE_INT) * 4;
- }
-
- grbm_cntl = adev->reg_offset[GC_HWIP][0][mmGRBM_GFX_CNTL_BASE_IDX] + mmGRBM_GFX_CNTL;
- grbm_idx = adev->reg_offset[GC_HWIP][0][mmGRBM_GFX_INDEX_BASE_IDX] + mmGRBM_GFX_INDEX;
-
- if (offset == grbm_cntl || offset == grbm_idx) {
- if (offset == grbm_cntl)
- writel(v, scratch_reg2);
- else if (offset == grbm_idx)
- writel(v, scratch_reg3);
-
- writel(v, ((void __iomem *)adev->rmmio) + (offset * 4));
- } else {
- writel(v, scratch_reg0);
- writel(offset | flag, scratch_reg1);
- writel(1, spare_int);
-
- for (i = 0; i < retries; i++) {
- tmp = readl(scratch_reg1);
- if (!(tmp & flag))
- break;
-
- udelay(10);
- }
-
- if (i >= retries) {
- if (RLCG_ERROR_REPORT_ENABLED(adev)) {
- if (tmp & RLCG_VFGATE_DISABLED)
- pr_err("The vfgate is disabled, program reg:0x%05x failed!\n", offset);
- else if (tmp & RLCG_WRONG_OPERATION_TYPE)
- pr_err("Wrong operation type, program reg:0x%05x failed!\n", offset);
- else if (tmp & RLCG_NOT_IN_RANGE)
- pr_err("The register is not in range, program reg:0x%05x failed!\n", offset);
- else
- pr_err("Unknown error type, program reg:0x%05x failed!\n", offset);
- } else
- pr_err("timeout: rlcg program reg:0x%05x failed!\n", offset);
- }
- }
-
- ret = readl(scratch_reg0);
-
- return ret;
-}
-
-static void gfx_v10_sriov_wreg(struct amdgpu_device *adev, u32 offset, u32 value, u32 acc_flags, u32 hwip)
-{
- u32 rlcg_flag;
-
- if (!amdgpu_sriov_runtime(adev) &&
- gfx_v10_get_rlcg_flag(adev, acc_flags, hwip, 1, &rlcg_flag)) {
- gfx_v10_rlcg_rw(adev, offset, value, rlcg_flag);
- return;
- }
-
- if (acc_flags & AMDGPU_REGS_NO_KIQ)
- WREG32_NO_KIQ(offset, value);
- else
- WREG32(offset, value);
-}
-
-static u32 gfx_v10_sriov_rreg(struct amdgpu_device *adev, u32 offset, u32 acc_flags, u32 hwip)
-{
- u32 rlcg_flag;
-
- if (!amdgpu_sriov_runtime(adev) &&
- gfx_v10_get_rlcg_flag(adev, acc_flags, hwip, 0, &rlcg_flag))
- return gfx_v10_rlcg_rw(adev, offset, 0, rlcg_flag);
-
- if (acc_flags & AMDGPU_REGS_NO_KIQ)
- return RREG32_NO_KIQ(offset);
- else
- return RREG32(offset);
-}
-
static const struct soc15_reg_golden golden_settings_gc_10_1_nv14[] =
{
/* Pending on emulation bring up */
@@ -3557,6 +3421,57 @@ static const struct soc15_reg_golden golden_settings_gc_10_0_cyan_skillfish[] =
SOC15_REG_GOLDEN_VALUE(GC, 0, mmUTCL1_CTRL, 0x00800000, 0x00800000)
};
+static const struct soc15_reg_golden golden_settings_gc_10_3_6[] =
+{
+ SOC15_REG_GOLDEN_VALUE(GC, 0, mmCGTT_SPI_CS_CLK_CTRL, 0xff7f0fff, 0x78000100),
+ SOC15_REG_GOLDEN_VALUE(GC, 0, mmCH_PIPE_STEER, 0x000000ff, 0x00000044),
+ SOC15_REG_GOLDEN_VALUE(GC, 0, mmCPF_GCR_CNTL, 0x0007ffff, 0x0000c200),
+ SOC15_REG_GOLDEN_VALUE(GC, 0, mmDB_DEBUG3, 0xffffffff, 0x00000280),
+ SOC15_REG_GOLDEN_VALUE(GC, 0, mmDB_DEBUG4, 0xffffffff, 0x00800000),
+ SOC15_REG_GOLDEN_VALUE(GC, 0, mmGB_ADDR_CONFIG, 0x0c1807ff, 0x00000042),
+ SOC15_REG_GOLDEN_VALUE(GC, 0, mmGCR_GENERAL_CNTL, 0x1ff1ffff, 0x00000500),
+ SOC15_REG_GOLDEN_VALUE(GC, 0, mmGL1_PIPE_STEER, 0x000000ff, 0x00000044),
+ SOC15_REG_GOLDEN_VALUE(GC, 0, mmGL2_PIPE_STEER_0, 0x77777777, 0x32103210),
+ SOC15_REG_GOLDEN_VALUE(GC, 0, mmGL2_PIPE_STEER_1, 0x77777777, 0x32103210),
+ SOC15_REG_GOLDEN_VALUE(GC, 0, mmGL2A_ADDR_MATCH_MASK, 0xffffffff, 0xfffffff3),
+ SOC15_REG_GOLDEN_VALUE(GC, 0, mmGL2C_ADDR_MATCH_MASK, 0xffffffff, 0xfffffff3),
+ SOC15_REG_GOLDEN_VALUE(GC, 0, mmGL2C_CM_CTRL1, 0xff8fff0f, 0x580f1008),
+ SOC15_REG_GOLDEN_VALUE(GC, 0, mmGL2C_CTRL3, 0xf7ffffff, 0x00f80988),
+ SOC15_REG_GOLDEN_VALUE(GC, 0, mmLDS_CONFIG, 0x000001ff, 0x00000020),
+ SOC15_REG_GOLDEN_VALUE(GC, 0, mmPA_CL_ENHANCE, 0xf17fffff, 0x01200007),
+ SOC15_REG_GOLDEN_VALUE(GC, 0, mmPA_SC_BINNER_TIMEOUT_COUNTER, 0xffffffff, 0x00000800),
+ SOC15_REG_GOLDEN_VALUE(GC, 0, mmPA_SC_ENHANCE_2, 0xffffffbf, 0x00000820),
+ SOC15_REG_GOLDEN_VALUE(GC, 0, mmSQG_CONFIG, 0x000017ff, 0x00001000),
+ SOC15_REG_GOLDEN_VALUE(GC, 0, mmSX_DEBUG_1, 0xffffff7f, 0x00010020),
+ SOC15_REG_GOLDEN_VALUE(GC, 0, mmTA_CNTL_AUX, 0xfff7ffff, 0x01030000),
+ SOC15_REG_GOLDEN_VALUE(GC, 0, mmUTCL1_CTRL, 0xffffffff, 0x00100000)
+};
+
+static const struct soc15_reg_golden golden_settings_gc_10_3_7[] = {
+ SOC15_REG_GOLDEN_VALUE(GC, 0, mmCGTT_SPI_CS_CLK_CTRL, 0xff7f0fff, 0x78000100),
+ SOC15_REG_GOLDEN_VALUE(GC, 0, mmCH_PIPE_STEER, 0x000000ff, 0x000000e4),
+ SOC15_REG_GOLDEN_VALUE(GC, 0, mmCPF_GCR_CNTL, 0x0007ffff, 0x0000c200),
+ SOC15_REG_GOLDEN_VALUE(GC, 0, mmDB_DEBUG3, 0xffffffff, 0x00000280),
+ SOC15_REG_GOLDEN_VALUE(GC, 0, mmDB_DEBUG4, 0xffffffff, 0x00800000),
+ SOC15_REG_GOLDEN_VALUE(GC, 0, mmGB_ADDR_CONFIG, 0x0c1807ff, 0x00000041),
+ SOC15_REG_GOLDEN_VALUE(GC, 0, mmGCR_GENERAL_CNTL, 0x1ff1ffff, 0x00000500),
+ SOC15_REG_GOLDEN_VALUE(GC, 0, mmGL1_PIPE_STEER, 0x000000ff, 0x000000e4),
+ SOC15_REG_GOLDEN_VALUE(GC, 0, mmGL2_PIPE_STEER_0, 0x77777777, 0x32103210),
+ SOC15_REG_GOLDEN_VALUE(GC, 0, mmGL2_PIPE_STEER_1, 0x77777777, 0x32103210),
+ SOC15_REG_GOLDEN_VALUE(GC, 0, mmGL2A_ADDR_MATCH_MASK, 0xffffffff, 0xffffffff),
+ SOC15_REG_GOLDEN_VALUE(GC, 0, mmGL2C_ADDR_MATCH_MASK, 0xffffffff, 0xffffffff),
+ SOC15_REG_GOLDEN_VALUE(GC, 0, mmGL2C_CM_CTRL1, 0xff8fff0f, 0x580f1008),
+ SOC15_REG_GOLDEN_VALUE(GC, 0, mmGL2C_CTRL3, 0xf7ffffff, 0x00f80988),
+ SOC15_REG_GOLDEN_VALUE(GC, 0, mmLDS_CONFIG, 0x000001ff, 0x00000020),
+ SOC15_REG_GOLDEN_VALUE(GC, 0, mmPA_CL_ENHANCE, 0xf000003f, 0x01200007),
+ SOC15_REG_GOLDEN_VALUE(GC, 0, mmPA_SC_BINNER_TIMEOUT_COUNTER, 0xffffffff, 0x00000800),
+ SOC15_REG_GOLDEN_VALUE(GC, 0, mmPA_SC_ENHANCE_2, 0xffffffbf, 0x00000820),
+ SOC15_REG_GOLDEN_VALUE(GC, 0, mmSQG_CONFIG, 0x000017ff, 0x00001000),
+ SOC15_REG_GOLDEN_VALUE(GC, 0, mmSX_DEBUG_1, 0xffffff7f, 0x00010020),
+ SOC15_REG_GOLDEN_VALUE(GC, 0, mmTA_CNTL_AUX, 0xfff7ffff, 0x01030000),
+ SOC15_REG_GOLDEN_VALUE(GC, 0, mmUTCL1_CTRL, 0xffffffff, 0x00100000)
+};
+
#define DEFAULT_SH_MEM_CONFIG \
((SH_MEM_ADDRESS_MODE_64 << SH_MEM_CONFIG__ADDRESS_MODE__SHIFT) | \
(SH_MEM_ALIGNMENT_MODE_UNALIGNED << SH_MEM_CONFIG__ALIGNMENT_MODE__SHIFT) | \
@@ -3790,10 +3705,21 @@ static void gfx_v10_0_init_golden_registers(struct amdgpu_device *adev)
(const u32)ARRAY_SIZE(golden_settings_gc_10_3_5));
break;
case IP_VERSION(10, 1, 3):
+ case IP_VERSION(10, 1, 4):
soc15_program_register_sequence(adev,
golden_settings_gc_10_0_cyan_skillfish,
(const u32)ARRAY_SIZE(golden_settings_gc_10_0_cyan_skillfish));
break;
+ case IP_VERSION(10, 3, 6):
+ soc15_program_register_sequence(adev,
+ golden_settings_gc_10_3_6,
+ (const u32)ARRAY_SIZE(golden_settings_gc_10_3_6));
+ break;
+ case IP_VERSION(10, 3, 7):
+ soc15_program_register_sequence(adev,
+ golden_settings_gc_10_3_7,
+ (const u32)ARRAY_SIZE(golden_settings_gc_10_3_7));
+ break;
default:
break;
}
@@ -3968,6 +3894,7 @@ static void gfx_v10_0_check_fw_write_wait(struct amdgpu_device *adev)
case IP_VERSION(10, 1, 2):
case IP_VERSION(10, 1, 1):
case IP_VERSION(10, 1, 3):
+ case IP_VERSION(10, 1, 4):
if ((adev->gfx.me_fw_version >= 0x00000046) &&
(adev->gfx.me_feature_version >= 27) &&
(adev->gfx.pfp_fw_version >= 0x00000068) &&
@@ -3981,7 +3908,9 @@ static void gfx_v10_0_check_fw_write_wait(struct amdgpu_device *adev)
case IP_VERSION(10, 3, 1):
case IP_VERSION(10, 3, 4):
case IP_VERSION(10, 3, 5):
+ case IP_VERSION(10, 3, 6):
case IP_VERSION(10, 3, 3):
+ case IP_VERSION(10, 3, 7):
adev->gfx.cp_fw_write_wait = true;
break;
default:
@@ -4102,11 +4031,15 @@ static int gfx_v10_0_init_microcode(struct amdgpu_device *adev)
case IP_VERSION(10, 3, 3):
chip_name = "yellow_carp";
break;
+ case IP_VERSION(10, 3, 6):
+ chip_name = "gc_10_3_6";
+ break;
case IP_VERSION(10, 1, 3):
- if (adev->apu_flags & AMD_APU_IS_CYAN_SKILLFISH2)
- chip_name = "cyan_skillfish2";
- else
- chip_name = "cyan_skillfish";
+ case IP_VERSION(10, 1, 4):
+ chip_name = "cyan_skillfish2";
+ break;
+ case IP_VERSION(10, 3, 7):
+ chip_name = "gc_10_3_7";
break;
default:
BUG();
@@ -4448,6 +4381,30 @@ static void gfx_v10_0_rlc_fini(struct amdgpu_device *adev)
(void **)&adev->gfx.rlc.cp_table_ptr);
}
+static void gfx_v10_0_init_rlcg_reg_access_ctrl(struct amdgpu_device *adev)
+{
+ struct amdgpu_rlcg_reg_access_ctrl *reg_access_ctrl;
+
+ reg_access_ctrl = &adev->gfx.rlc.reg_access_ctrl;
+ reg_access_ctrl->scratch_reg0 = SOC15_REG_OFFSET(GC, 0, mmSCRATCH_REG0);
+ reg_access_ctrl->scratch_reg1 = SOC15_REG_OFFSET(GC, 0, mmSCRATCH_REG1);
+ reg_access_ctrl->scratch_reg2 = SOC15_REG_OFFSET(GC, 0, mmSCRATCH_REG2);
+ reg_access_ctrl->scratch_reg3 = SOC15_REG_OFFSET(GC, 0, mmSCRATCH_REG3);
+ reg_access_ctrl->grbm_cntl = SOC15_REG_OFFSET(GC, 0, mmGRBM_GFX_CNTL);
+ reg_access_ctrl->grbm_idx = SOC15_REG_OFFSET(GC, 0, mmGRBM_GFX_INDEX);
+ switch (adev->ip_versions[GC_HWIP][0]) {
+ case IP_VERSION(10, 3, 0):
+ reg_access_ctrl->spare_int =
+ SOC15_REG_OFFSET(GC, 0, mmRLC_SPARE_INT_0_Sienna_Cichlid);
+ break;
+ default:
+ reg_access_ctrl->spare_int =
+ SOC15_REG_OFFSET(GC, 0, mmRLC_SPARE_INT);
+ break;
+ }
+ adev->gfx.rlc.rlcg_reg_access_supported = true;
+}
+
static int gfx_v10_0_rlc_init(struct amdgpu_device *adev)
{
const struct cs_section_def *cs_data;
@@ -4468,6 +4425,7 @@ static int gfx_v10_0_rlc_init(struct amdgpu_device *adev)
if (adev->gfx.rlc.funcs->update_spm_vmid)
adev->gfx.rlc.funcs->update_spm_vmid(adev, 0xf);
+
return 0;
}
@@ -4678,7 +4636,9 @@ static void gfx_v10_0_gpu_early_init(struct amdgpu_device *adev)
case IP_VERSION(10, 3, 1):
case IP_VERSION(10, 3, 4):
case IP_VERSION(10, 3, 5):
+ case IP_VERSION(10, 3, 6):
case IP_VERSION(10, 3, 3):
+ case IP_VERSION(10, 3, 7):
adev->gfx.config.max_hw_contexts = 8;
adev->gfx.config.sc_prim_fifo_size_frontend = 0x20;
adev->gfx.config.sc_prim_fifo_size_backend = 0x100;
@@ -4689,6 +4649,7 @@ static void gfx_v10_0_gpu_early_init(struct amdgpu_device *adev)
1 << REG_GET_FIELD(gb_addr_config, GB_ADDR_CONFIG, NUM_PKRS);
break;
case IP_VERSION(10, 1, 3):
+ case IP_VERSION(10, 1, 4):
adev->gfx.config.max_hw_contexts = 8;
adev->gfx.config.sc_prim_fifo_size_frontend = 0x20;
adev->gfx.config.sc_prim_fifo_size_backend = 0x100;
@@ -4801,6 +4762,7 @@ static int gfx_v10_0_sw_init(void *handle)
case IP_VERSION(10, 1, 1):
case IP_VERSION(10, 1, 2):
case IP_VERSION(10, 1, 3):
+ case IP_VERSION(10, 1, 4):
adev->gfx.me.num_me = 1;
adev->gfx.me.num_pipe_per_me = 1;
adev->gfx.me.num_queue_per_pipe = 1;
@@ -4813,7 +4775,9 @@ static int gfx_v10_0_sw_init(void *handle)
case IP_VERSION(10, 3, 1):
case IP_VERSION(10, 3, 4):
case IP_VERSION(10, 3, 5):
+ case IP_VERSION(10, 3, 6):
case IP_VERSION(10, 3, 3):
+ case IP_VERSION(10, 3, 7):
adev->gfx.me.num_me = 1;
adev->gfx.me.num_pipe_per_me = 1;
adev->gfx.me.num_queue_per_pipe = 1;
@@ -4865,10 +4829,14 @@ static int gfx_v10_0_sw_init(void *handle)
if (r)
return r;
- r = gfx_v10_0_rlc_init(adev);
- if (r) {
- DRM_ERROR("Failed to init rlc BOs!\n");
- return r;
+ if (adev->gfx.rlc.funcs) {
+ if (adev->gfx.rlc.funcs->init) {
+ r = adev->gfx.rlc.funcs->init(adev);
+ if (r) {
+ dev_err(adev->dev, "Failed to init rlc BOs!\n");
+ return r;
+ }
+ }
}
r = gfx_v10_0_mec_init(adev);
@@ -5047,7 +5015,8 @@ static void gfx_v10_0_setup_rb(struct amdgpu_device *adev)
for (j = 0; j < adev->gfx.config.max_sh_per_se; j++) {
bitmap = i * adev->gfx.config.max_sh_per_se + j;
if (((adev->ip_versions[GC_HWIP][0] == IP_VERSION(10, 3, 0)) ||
- (adev->ip_versions[GC_HWIP][0] == IP_VERSION(10, 3, 3))) &&
+ (adev->ip_versions[GC_HWIP][0] == IP_VERSION(10, 3, 3)) ||
+ (adev->ip_versions[GC_HWIP][0] == IP_VERSION(10, 3, 6))) &&
((gfx_v10_3_get_disabled_sa(adev) >> bitmap) & 1))
continue;
gfx_v10_0_select_se_sh(adev, i, j, 0xffffffff);
@@ -6321,7 +6290,9 @@ static void gfx_v10_0_cp_gfx_set_doorbell(struct amdgpu_device *adev,
case IP_VERSION(10, 3, 1):
case IP_VERSION(10, 3, 4):
case IP_VERSION(10, 3, 5):
+ case IP_VERSION(10, 3, 6):
case IP_VERSION(10, 3, 3):
+ case IP_VERSION(10, 3, 7):
tmp = REG_SET_FIELD(0, CP_RB_DOORBELL_RANGE_LOWER,
DOORBELL_RANGE_LOWER_Sienna_Cichlid, ring->doorbell_index);
WREG32_SOC15(GC, 0, mmCP_RB_DOORBELL_RANGE_LOWER, tmp);
@@ -6458,7 +6429,9 @@ static void gfx_v10_0_cp_compute_enable(struct amdgpu_device *adev, bool enable)
case IP_VERSION(10, 3, 1):
case IP_VERSION(10, 3, 4):
case IP_VERSION(10, 3, 5):
+ case IP_VERSION(10, 3, 6):
case IP_VERSION(10, 3, 3):
+ case IP_VERSION(10, 3, 7):
WREG32_SOC15(GC, 0, mmCP_MEC_CNTL_Sienna_Cichlid, 0);
break;
default:
@@ -6472,7 +6445,9 @@ static void gfx_v10_0_cp_compute_enable(struct amdgpu_device *adev, bool enable)
case IP_VERSION(10, 3, 1):
case IP_VERSION(10, 3, 4):
case IP_VERSION(10, 3, 5):
+ case IP_VERSION(10, 3, 6):
case IP_VERSION(10, 3, 3):
+ case IP_VERSION(10, 3, 7):
WREG32_SOC15(GC, 0, mmCP_MEC_CNTL_Sienna_Cichlid,
(CP_MEC_CNTL__MEC_ME1_HALT_MASK |
CP_MEC_CNTL__MEC_ME2_HALT_MASK));
@@ -6570,7 +6545,9 @@ static void gfx_v10_0_kiq_setting(struct amdgpu_ring *ring)
case IP_VERSION(10, 3, 1):
case IP_VERSION(10, 3, 4):
case IP_VERSION(10, 3, 5):
+ case IP_VERSION(10, 3, 6):
case IP_VERSION(10, 3, 3):
+ case IP_VERSION(10, 3, 7):
tmp = RREG32_SOC15(GC, 0, mmRLC_CP_SCHEDULERS_Sienna_Cichlid);
tmp &= 0xffffff00;
tmp |= (ring->me << 5) | (ring->pipe << 3) | (ring->queue);
@@ -7300,6 +7277,8 @@ static bool gfx_v10_0_check_grbm_cam_remapping(struct amdgpu_device *adev)
break;
case IP_VERSION(10, 3, 1):
case IP_VERSION(10, 3, 3):
+ case IP_VERSION(10, 3, 6):
+ case IP_VERSION(10, 3, 7):
return true;
default:
data = RREG32_SOC15(GC, 0, mmVGT_ESGS_RING_SIZE);
@@ -7334,7 +7313,9 @@ static void gfx_v10_0_setup_grbm_cam_remapping(struct amdgpu_device *adev)
case IP_VERSION(10, 3, 1):
case IP_VERSION(10, 3, 4):
case IP_VERSION(10, 3, 5):
+ case IP_VERSION(10, 3, 6):
case IP_VERSION(10, 3, 3):
+ case IP_VERSION(10, 3, 7):
/* mmVGT_TF_RING_SIZE_UMD -> mmVGT_TF_RING_SIZE */
data = (SOC15_REG_OFFSET(GC, 0, mmVGT_TF_RING_SIZE_UMD) <<
GRBM_CAM_DATA__CAM_ADDR__SHIFT) |
@@ -7654,6 +7635,7 @@ static int gfx_v10_0_soft_reset(void *handle)
case IP_VERSION(10, 3, 1):
case IP_VERSION(10, 3, 4):
case IP_VERSION(10, 3, 5):
+ case IP_VERSION(10, 3, 6):
case IP_VERSION(10, 3, 3):
if (REG_GET_FIELD(tmp, GRBM_STATUS2, RLC_BUSY_Sienna_Cichlid))
grbm_soft_reset = REG_SET_FIELD(grbm_soft_reset,
@@ -7721,6 +7703,21 @@ static uint64_t gfx_v10_0_get_gpu_clock_counter(struct amdgpu_device *adev)
preempt_enable();
clock = clock_lo | (clock_hi << 32ULL);
break;
+ case IP_VERSION(10, 3, 6):
+ preempt_disable();
+ clock_hi = RREG32_SOC15_NO_KIQ(SMUIO, 0, mmGOLDEN_TSC_COUNT_UPPER_GC_10_3_6);
+ clock_lo = RREG32_SOC15_NO_KIQ(SMUIO, 0, mmGOLDEN_TSC_COUNT_LOWER_GC_10_3_6);
+ hi_check = RREG32_SOC15_NO_KIQ(SMUIO, 0, mmGOLDEN_TSC_COUNT_UPPER_GC_10_3_6);
+ /* The SMUIO TSC clock frequency is 100MHz, which sets 32-bit carry over
+ * roughly every 42 seconds.
+ */
+ if (hi_check != clock_hi) {
+ clock_lo = RREG32_SOC15_NO_KIQ(SMUIO, 0, mmGOLDEN_TSC_COUNT_LOWER_GC_10_3_6);
+ clock_hi = hi_check;
+ }
+ preempt_enable();
+ clock = clock_lo | (clock_hi << 32ULL);
+ break;
default:
preempt_disable();
clock_hi = RREG32_SOC15_NO_KIQ(SMUIO, 0, mmGOLDEN_TSC_COUNT_UPPER);
@@ -7778,6 +7775,7 @@ static int gfx_v10_0_early_init(void *handle)
case IP_VERSION(10, 1, 1):
case IP_VERSION(10, 1, 2):
case IP_VERSION(10, 1, 3):
+ case IP_VERSION(10, 1, 4):
adev->gfx.num_gfx_rings = GFX10_NUM_GFX_RINGS_NV1X;
break;
case IP_VERSION(10, 3, 0):
@@ -7785,7 +7783,9 @@ static int gfx_v10_0_early_init(void *handle)
case IP_VERSION(10, 3, 1):
case IP_VERSION(10, 3, 4):
case IP_VERSION(10, 3, 5):
+ case IP_VERSION(10, 3, 6):
case IP_VERSION(10, 3, 3):
+ case IP_VERSION(10, 3, 7):
adev->gfx.num_gfx_rings = GFX10_NUM_GFX_RINGS_Sienna_Cichlid;
break;
default:
@@ -7801,6 +7801,9 @@ static int gfx_v10_0_early_init(void *handle)
gfx_v10_0_set_gds_init(adev);
gfx_v10_0_set_rlc_funcs(adev);
+ /* init rlcg reg access ctrl */
+ gfx_v10_0_init_rlcg_reg_access_ctrl(adev);
+
return 0;
}
@@ -7843,7 +7846,9 @@ static void gfx_v10_0_set_safe_mode(struct amdgpu_device *adev)
case IP_VERSION(10, 3, 1):
case IP_VERSION(10, 3, 4):
case IP_VERSION(10, 3, 5):
+ case IP_VERSION(10, 3, 6):
case IP_VERSION(10, 3, 3):
+ case IP_VERSION(10, 3, 7):
WREG32_SOC15(GC, 0, mmRLC_SAFE_MODE_Sienna_Cichlid, data);
/* wait for RLC_SAFE_MODE */
@@ -7879,7 +7884,9 @@ static void gfx_v10_0_unset_safe_mode(struct amdgpu_device *adev)
case IP_VERSION(10, 3, 1):
case IP_VERSION(10, 3, 4):
case IP_VERSION(10, 3, 5):
+ case IP_VERSION(10, 3, 6):
case IP_VERSION(10, 3, 3):
+ case IP_VERSION(10, 3, 7):
WREG32_SOC15(GC, 0, mmRLC_SAFE_MODE_Sienna_Cichlid, data);
break;
default:
@@ -8333,6 +8340,8 @@ static void gfx_v10_cntl_power_gating(struct amdgpu_device *adev, bool enable)
switch (adev->ip_versions[GC_HWIP][0]) {
case IP_VERSION(10, 3, 1):
case IP_VERSION(10, 3, 3):
+ case IP_VERSION(10, 3, 6):
+ case IP_VERSION(10, 3, 7):
data = 0x4E20 & RLC_PG_DELAY_3__CGCG_ACTIVE_BEFORE_CGPG_MASK_Vangogh;
WREG32_SOC15(GC, 0, mmRLC_PG_DELAY_3, data);
break;
@@ -8377,8 +8386,6 @@ static const struct amdgpu_rlc_funcs gfx_v10_0_rlc_funcs_sriov = {
.reset = gfx_v10_0_rlc_reset,
.start = gfx_v10_0_rlc_start,
.update_spm_vmid = gfx_v10_0_update_spm_vmid,
- .sriov_wreg = gfx_v10_sriov_wreg,
- .sriov_rreg = gfx_v10_sriov_rreg,
.is_rlcg_access_range = gfx_v10_0_is_rlcg_access_range,
};
@@ -8403,6 +8410,8 @@ static int gfx_v10_0_set_powergating_state(void *handle,
break;
case IP_VERSION(10, 3, 1):
case IP_VERSION(10, 3, 3):
+ case IP_VERSION(10, 3, 6):
+ case IP_VERSION(10, 3, 7):
gfx_v10_cntl_pg(adev, enable);
amdgpu_gfx_off_ctrl(adev, enable);
break;
@@ -8429,7 +8438,9 @@ static int gfx_v10_0_set_clockgating_state(void *handle,
case IP_VERSION(10, 3, 1):
case IP_VERSION(10, 3, 4):
case IP_VERSION(10, 3, 5):
+ case IP_VERSION(10, 3, 6):
case IP_VERSION(10, 3, 3):
+ case IP_VERSION(10, 3, 7):
gfx_v10_0_update_gfx_clock_gating(adev,
state == AMD_CG_STATE_GATE);
break;
@@ -9366,6 +9377,7 @@ static const struct amdgpu_ring_funcs gfx_v10_0_ring_funcs_gfx = {
.align_mask = 0xff,
.nop = PACKET3(PACKET3_NOP, 0x3FFF),
.support_64bit_ptrs = true,
+ .secure_submission_supported = true,
.vmhub = AMDGPU_GFXHUB_0,
.get_rptr = gfx_v10_0_ring_get_rptr_gfx,
.get_wptr = gfx_v10_0_ring_get_wptr_gfx,
@@ -9537,11 +9549,14 @@ static void gfx_v10_0_set_rlc_funcs(struct amdgpu_device *adev)
case IP_VERSION(10, 1, 10):
case IP_VERSION(10, 1, 1):
case IP_VERSION(10, 1, 3):
+ case IP_VERSION(10, 1, 4):
case IP_VERSION(10, 3, 2):
case IP_VERSION(10, 3, 1):
case IP_VERSION(10, 3, 4):
case IP_VERSION(10, 3, 5):
+ case IP_VERSION(10, 3, 6):
case IP_VERSION(10, 3, 3):
+ case IP_VERSION(10, 3, 7):
adev->gfx.rlc.funcs = &gfx_v10_0_rlc_funcs;
break;
case IP_VERSION(10, 1, 2):
@@ -9634,7 +9649,9 @@ static int gfx_v10_0_get_cu_info(struct amdgpu_device *adev,
for (j = 0; j < adev->gfx.config.max_sh_per_se; j++) {
bitmap = i * adev->gfx.config.max_sh_per_se + j;
if (((adev->ip_versions[GC_HWIP][0] == IP_VERSION(10, 3, 0)) ||
- (adev->ip_versions[GC_HWIP][0] == IP_VERSION(10, 3, 3))) &&
+ (adev->ip_versions[GC_HWIP][0] == IP_VERSION(10, 3, 3)) ||
+ (adev->ip_versions[GC_HWIP][0] == IP_VERSION(10, 3, 6)) ||
+ (adev->ip_versions[GC_HWIP][0] == IP_VERSION(10, 3, 7))) &&
((gfx_v10_3_get_disabled_sa(adev) >> bitmap) & 1))
continue;
mask = 1;
diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c
index 9189fb85a4dd..46d4bf27ebbb 100644
--- a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c
@@ -63,13 +63,6 @@
#define mmGCEA_PROBE_MAP 0x070c
#define mmGCEA_PROBE_MAP_BASE_IDX 0
-#define GFX9_RLCG_GC_WRITE_OLD (0x8 << 28)
-#define GFX9_RLCG_GC_WRITE (0x0 << 28)
-#define GFX9_RLCG_GC_READ (0x1 << 28)
-#define GFX9_RLCG_VFGATE_DISABLED 0x4000000
-#define GFX9_RLCG_WRONG_OPERATION_TYPE 0x2000000
-#define GFX9_RLCG_NOT_IN_RANGE 0x1000000
-
MODULE_FIRMWARE("amdgpu/vega10_ce.bin");
MODULE_FIRMWARE("amdgpu/vega10_pfp.bin");
MODULE_FIRMWARE("amdgpu/vega10_me.bin");
@@ -746,128 +739,6 @@ static const u32 GFX_RLC_SRM_INDEX_CNTL_DATA_OFFSETS[] =
mmRLC_SRM_INDEX_CNTL_DATA_7 - mmRLC_SRM_INDEX_CNTL_DATA_0,
};
-static u32 gfx_v9_0_rlcg_rw(struct amdgpu_device *adev, u32 offset, u32 v, uint32_t flag)
-{
- static void *scratch_reg0;
- static void *scratch_reg1;
- static void *scratch_reg2;
- static void *scratch_reg3;
- static void *spare_int;
- static uint32_t grbm_cntl;
- static uint32_t grbm_idx;
- uint32_t i = 0;
- uint32_t retries = 50000;
- u32 ret = 0;
- u32 tmp;
-
- scratch_reg0 = adev->rmmio + (adev->reg_offset[GC_HWIP][0][mmSCRATCH_REG0_BASE_IDX] + mmSCRATCH_REG0)*4;
- scratch_reg1 = adev->rmmio + (adev->reg_offset[GC_HWIP][0][mmSCRATCH_REG1_BASE_IDX] + mmSCRATCH_REG1)*4;
- scratch_reg2 = adev->rmmio + (adev->reg_offset[GC_HWIP][0][mmSCRATCH_REG2_BASE_IDX] + mmSCRATCH_REG2)*4;
- scratch_reg3 = adev->rmmio + (adev->reg_offset[GC_HWIP][0][mmSCRATCH_REG3_BASE_IDX] + mmSCRATCH_REG3)*4;
- spare_int = adev->rmmio + (adev->reg_offset[GC_HWIP][0][mmRLC_SPARE_INT_BASE_IDX] + mmRLC_SPARE_INT)*4;
-
- grbm_cntl = adev->reg_offset[GC_HWIP][0][mmGRBM_GFX_CNTL_BASE_IDX] + mmGRBM_GFX_CNTL;
- grbm_idx = adev->reg_offset[GC_HWIP][0][mmGRBM_GFX_INDEX_BASE_IDX] + mmGRBM_GFX_INDEX;
-
- if (offset == grbm_cntl || offset == grbm_idx) {
- if (offset == grbm_cntl)
- writel(v, scratch_reg2);
- else if (offset == grbm_idx)
- writel(v, scratch_reg3);
-
- writel(v, ((void __iomem *)adev->rmmio) + (offset * 4));
- } else {
- /*
- * SCRATCH_REG0 = read/write value
- * SCRATCH_REG1[30:28] = command
- * SCRATCH_REG1[19:0] = address in dword
- * SCRATCH_REG1[26:24] = Error reporting
- */
- writel(v, scratch_reg0);
- writel(offset | flag, scratch_reg1);
- writel(1, spare_int);
-
- for (i = 0; i < retries; i++) {
- tmp = readl(scratch_reg1);
- if (!(tmp & flag))
- break;
-
- udelay(10);
- }
-
- if (i >= retries) {
- if (amdgpu_sriov_reg_indirect_gc(adev)) {
- if (tmp & GFX9_RLCG_VFGATE_DISABLED)
- pr_err("The vfgate is disabled, program reg:0x%05x failed!\n", offset);
- else if (tmp & GFX9_RLCG_WRONG_OPERATION_TYPE)
- pr_err("Wrong operation type, program reg:0x%05x failed!\n", offset);
- else if (tmp & GFX9_RLCG_NOT_IN_RANGE)
- pr_err("The register is not in range, program reg:0x%05x failed!\n", offset);
- else
- pr_err("Unknown error type, program reg:0x%05x failed!\n", offset);
- } else
- pr_err("timeout: rlcg program reg:0x%05x failed!\n", offset);
- }
- }
-
- ret = readl(scratch_reg0);
-
- return ret;
-}
-
-static bool gfx_v9_0_get_rlcg_flag(struct amdgpu_device *adev, u32 acc_flags, u32 hwip,
- int write, u32 *rlcg_flag)
-{
-
- switch (hwip) {
- case GC_HWIP:
- if (amdgpu_sriov_reg_indirect_gc(adev)) {
- *rlcg_flag = write ? GFX9_RLCG_GC_WRITE : GFX9_RLCG_GC_READ;
-
- return true;
- /* only in new version, AMDGPU_REGS_NO_KIQ and AMDGPU_REGS_RLC enabled simultaneously */
- } else if ((acc_flags & AMDGPU_REGS_RLC) && !(acc_flags & AMDGPU_REGS_NO_KIQ) && write) {
- *rlcg_flag = GFX9_RLCG_GC_WRITE_OLD;
- return true;
- }
-
- break;
- default:
- return false;
- }
-
- return false;
-}
-
-static u32 gfx_v9_0_sriov_rreg(struct amdgpu_device *adev, u32 offset, u32 acc_flags, u32 hwip)
-{
- u32 rlcg_flag;
-
- if (!amdgpu_sriov_runtime(adev) && gfx_v9_0_get_rlcg_flag(adev, acc_flags, hwip, 0, &rlcg_flag))
- return gfx_v9_0_rlcg_rw(adev, offset, 0, rlcg_flag);
-
- if (acc_flags & AMDGPU_REGS_NO_KIQ)
- return RREG32_NO_KIQ(offset);
- else
- return RREG32(offset);
-}
-
-static void gfx_v9_0_sriov_wreg(struct amdgpu_device *adev, u32 offset,
- u32 value, u32 acc_flags, u32 hwip)
-{
- u32 rlcg_flag;
-
- if (!amdgpu_sriov_runtime(adev) && gfx_v9_0_get_rlcg_flag(adev, acc_flags, hwip, 1, &rlcg_flag)) {
- gfx_v9_0_rlcg_rw(adev, offset, value, rlcg_flag);
- return;
- }
-
- if (acc_flags & AMDGPU_REGS_NO_KIQ)
- WREG32_NO_KIQ(offset, value);
- else
- WREG32(offset, value);
-}
-
#define VEGA10_GB_ADDR_CONFIG_GOLDEN 0x2a114042
#define VEGA12_GB_ADDR_CONFIG_GOLDEN 0x24104041
#define RAVEN_GB_ADDR_CONFIG_GOLDEN 0x24000042
@@ -882,7 +753,7 @@ static int gfx_v9_0_get_cu_info(struct amdgpu_device *adev,
static uint64_t gfx_v9_0_get_gpu_clock_counter(struct amdgpu_device *adev);
static void gfx_v9_0_ring_emit_de_meta(struct amdgpu_ring *ring);
static u64 gfx_v9_0_ring_get_rptr_compute(struct amdgpu_ring *ring);
-static int gfx_v9_0_query_ras_error_count(struct amdgpu_device *adev,
+static void gfx_v9_0_query_ras_error_count(struct amdgpu_device *adev,
void *ras_error_status);
static int gfx_v9_0_ras_error_inject(struct amdgpu_device *adev,
void *inject_if);
@@ -2008,6 +1879,21 @@ static int gfx_v9_0_cp_jump_table_num(struct amdgpu_device *adev)
return 4;
}
+static void gfx_v9_0_init_rlcg_reg_access_ctrl(struct amdgpu_device *adev)
+{
+ struct amdgpu_rlcg_reg_access_ctrl *reg_access_ctrl;
+
+ reg_access_ctrl = &adev->gfx.rlc.reg_access_ctrl;
+ reg_access_ctrl->scratch_reg0 = SOC15_REG_OFFSET(GC, 0, mmSCRATCH_REG0);
+ reg_access_ctrl->scratch_reg1 = SOC15_REG_OFFSET(GC, 0, mmSCRATCH_REG1);
+ reg_access_ctrl->scratch_reg2 = SOC15_REG_OFFSET(GC, 0, mmSCRATCH_REG2);
+ reg_access_ctrl->scratch_reg3 = SOC15_REG_OFFSET(GC, 0, mmSCRATCH_REG3);
+ reg_access_ctrl->grbm_cntl = SOC15_REG_OFFSET(GC, 0, mmGRBM_GFX_CNTL);
+ reg_access_ctrl->grbm_idx = SOC15_REG_OFFSET(GC, 0, mmGRBM_GFX_INDEX);
+ reg_access_ctrl->spare_int = SOC15_REG_OFFSET(GC, 0, mmRLC_SPARE_INT);
+ adev->gfx.rlc.rlcg_reg_access_supported = true;
+}
+
static int gfx_v9_0_rlc_init(struct amdgpu_device *adev)
{
const struct cs_section_def *cs_data;
@@ -2197,12 +2083,16 @@ static const struct amdgpu_gfx_funcs gfx_v9_0_gfx_funcs = {
.select_me_pipe_q = &gfx_v9_0_select_me_pipe_q,
};
-static const struct amdgpu_gfx_ras_funcs gfx_v9_0_ras_funcs = {
- .ras_late_init = amdgpu_gfx_ras_late_init,
- .ras_fini = amdgpu_gfx_ras_fini,
- .ras_error_inject = &gfx_v9_0_ras_error_inject,
- .query_ras_error_count = &gfx_v9_0_query_ras_error_count,
- .reset_ras_error_count = &gfx_v9_0_reset_ras_error_count,
+const struct amdgpu_ras_block_hw_ops gfx_v9_0_ras_ops = {
+ .ras_error_inject = &gfx_v9_0_ras_error_inject,
+ .query_ras_error_count = &gfx_v9_0_query_ras_error_count,
+ .reset_ras_error_count = &gfx_v9_0_reset_ras_error_count,
+};
+
+static struct amdgpu_gfx_ras gfx_v9_0_ras = {
+ .ras_block = {
+ .hw_ops = &gfx_v9_0_ras_ops,
+ },
};
static int gfx_v9_0_gpu_early_init(struct amdgpu_device *adev)
@@ -2231,7 +2121,7 @@ static int gfx_v9_0_gpu_early_init(struct amdgpu_device *adev)
DRM_INFO("fix gfx.config for vega12\n");
break;
case IP_VERSION(9, 4, 0):
- adev->gfx.ras_funcs = &gfx_v9_0_ras_funcs;
+ adev->gfx.ras = &gfx_v9_0_ras;
adev->gfx.config.max_hw_contexts = 8;
adev->gfx.config.sc_prim_fifo_size_frontend = 0x20;
adev->gfx.config.sc_prim_fifo_size_backend = 0x100;
@@ -2258,7 +2148,7 @@ static int gfx_v9_0_gpu_early_init(struct amdgpu_device *adev)
gb_addr_config = RAVEN_GB_ADDR_CONFIG_GOLDEN;
break;
case IP_VERSION(9, 4, 1):
- adev->gfx.ras_funcs = &gfx_v9_4_ras_funcs;
+ adev->gfx.ras = &gfx_v9_4_ras;
adev->gfx.config.max_hw_contexts = 8;
adev->gfx.config.sc_prim_fifo_size_frontend = 0x20;
adev->gfx.config.sc_prim_fifo_size_backend = 0x100;
@@ -2279,7 +2169,7 @@ static int gfx_v9_0_gpu_early_init(struct amdgpu_device *adev)
gb_addr_config |= 0x22010042;
break;
case IP_VERSION(9, 4, 2):
- adev->gfx.ras_funcs = &gfx_v9_4_2_ras_funcs;
+ adev->gfx.ras = &gfx_v9_4_2_ras;
adev->gfx.config.max_hw_contexts = 8;
adev->gfx.config.sc_prim_fifo_size_frontend = 0x20;
adev->gfx.config.sc_prim_fifo_size_backend = 0x100;
@@ -2298,6 +2188,27 @@ static int gfx_v9_0_gpu_early_init(struct amdgpu_device *adev)
break;
}
+ if (adev->gfx.ras) {
+ err = amdgpu_ras_register_ras_block(adev, &adev->gfx.ras->ras_block);
+ if (err) {
+ DRM_ERROR("Failed to register gfx ras block!\n");
+ return err;
+ }
+
+ strcpy(adev->gfx.ras->ras_block.ras_comm.name, "gfx");
+ adev->gfx.ras->ras_block.ras_comm.block = AMDGPU_RAS_BLOCK__GFX;
+ adev->gfx.ras->ras_block.ras_comm.type = AMDGPU_RAS_ERROR__MULTI_UNCORRECTABLE;
+ adev->gfx.ras_if = &adev->gfx.ras->ras_block.ras_comm;
+
+ /* If not define special ras_late_init function, use gfx default ras_late_init */
+ if (!adev->gfx.ras->ras_block.ras_late_init)
+ adev->gfx.ras->ras_block.ras_late_init = amdgpu_gfx_ras_late_init;
+
+ /* If not defined special ras_cb function, use default ras_cb */
+ if (!adev->gfx.ras->ras_block.ras_cb)
+ adev->gfx.ras->ras_block.ras_cb = amdgpu_gfx_process_ras_data_cb;
+ }
+
adev->gfx.config.gb_addr_config = gb_addr_config;
adev->gfx.config.gb_addr_config_fields.num_pipes = 1 <<
@@ -2434,10 +2345,14 @@ static int gfx_v9_0_sw_init(void *handle)
return r;
}
- r = adev->gfx.rlc.funcs->init(adev);
- if (r) {
- DRM_ERROR("Failed to init rlc BOs!\n");
- return r;
+ if (adev->gfx.rlc.funcs) {
+ if (adev->gfx.rlc.funcs->init) {
+ r = adev->gfx.rlc.funcs->init(adev);
+ if (r) {
+ dev_err(adev->dev, "Failed to init rlc BOs!\n");
+ return r;
+ }
+ }
}
r = gfx_v9_0_mec_init(adev);
@@ -2513,10 +2428,6 @@ static int gfx_v9_0_sw_fini(void *handle)
int i;
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
- if (adev->gfx.ras_funcs &&
- adev->gfx.ras_funcs->ras_fini)
- adev->gfx.ras_funcs->ras_fini(adev);
-
for (i = 0; i < adev->gfx.num_gfx_rings; i++)
amdgpu_ring_fini(&adev->gfx.gfx_ring[i]);
for (i = 0; i < adev->gfx.num_compute_rings; i++)
@@ -4840,6 +4751,9 @@ static int gfx_v9_0_early_init(void *handle)
gfx_v9_0_set_gds_init(adev);
gfx_v9_0_set_rlc_funcs(adev);
+ /* init rlcg reg access ctrl */
+ gfx_v9_0_init_rlcg_reg_access_ctrl(adev);
+
return 0;
}
@@ -4870,16 +4784,9 @@ static int gfx_v9_0_ecc_late_init(void *handle)
if (r)
return r;
- if (adev->gfx.ras_funcs &&
- adev->gfx.ras_funcs->ras_late_init) {
- r = adev->gfx.ras_funcs->ras_late_init(adev);
- if (r)
- return r;
- }
-
- if (adev->gfx.ras_funcs &&
- adev->gfx.ras_funcs->enable_watchdog_timer)
- adev->gfx.ras_funcs->enable_watchdog_timer(adev);
+ if (adev->gfx.ras &&
+ adev->gfx.ras->enable_watchdog_timer)
+ adev->gfx.ras->enable_watchdog_timer(adev);
return 0;
}
@@ -5250,8 +5157,6 @@ static const struct amdgpu_rlc_funcs gfx_v9_0_rlc_funcs = {
.reset = gfx_v9_0_rlc_reset,
.start = gfx_v9_0_rlc_start,
.update_spm_vmid = gfx_v9_0_update_spm_vmid,
- .sriov_wreg = gfx_v9_0_sriov_wreg,
- .sriov_rreg = gfx_v9_0_sriov_rreg,
.is_rlcg_access_range = gfx_v9_0_is_rlcg_access_range,
};
@@ -6819,7 +6724,7 @@ static void gfx_v9_0_reset_ras_error_count(struct amdgpu_device *adev)
WREG32_SOC15(GC, 0, mmATC_L2_CACHE_4K_EDC_INDEX, 255);
}
-static int gfx_v9_0_query_ras_error_count(struct amdgpu_device *adev,
+static void gfx_v9_0_query_ras_error_count(struct amdgpu_device *adev,
void *ras_error_status)
{
struct ras_err_data *err_data = (struct ras_err_data *)ras_error_status;
@@ -6828,7 +6733,7 @@ static int gfx_v9_0_query_ras_error_count(struct amdgpu_device *adev,
uint32_t reg_value;
if (!amdgpu_ras_is_supported(adev, AMDGPU_RAS_BLOCK__GFX))
- return -EINVAL;
+ return;
err_data->ue_count = 0;
err_data->ce_count = 0;
@@ -6857,8 +6762,6 @@ static int gfx_v9_0_query_ras_error_count(struct amdgpu_device *adev,
mutex_unlock(&adev->grbm_idx_mutex);
gfx_v9_0_query_utc_edc_status(adev, err_data);
-
- return 0;
}
static void gfx_v9_0_emit_mem_sync(struct amdgpu_ring *ring)
@@ -6962,6 +6865,7 @@ static const struct amdgpu_ring_funcs gfx_v9_0_ring_funcs_gfx = {
.align_mask = 0xff,
.nop = PACKET3(PACKET3_NOP, 0x3FFF),
.support_64bit_ptrs = true,
+ .secure_submission_supported = true,
.vmhub = AMDGPU_GFXHUB_0,
.get_rptr = gfx_v9_0_ring_get_rptr_gfx,
.get_wptr = gfx_v9_0_ring_get_wptr_gfx,
diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v9_4.c b/drivers/gpu/drm/amd/amdgpu/gfx_v9_4.c
index b4789dfc2bb9..c67e387a97f5 100644
--- a/drivers/gpu/drm/amd/amdgpu/gfx_v9_4.c
+++ b/drivers/gpu/drm/amd/amdgpu/gfx_v9_4.c
@@ -863,7 +863,7 @@ static int gfx_v9_4_ras_error_count(struct amdgpu_device *adev,
return 0;
}
-static int gfx_v9_4_query_ras_error_count(struct amdgpu_device *adev,
+static void gfx_v9_4_query_ras_error_count(struct amdgpu_device *adev,
void *ras_error_status)
{
struct ras_err_data *err_data = (struct ras_err_data *)ras_error_status;
@@ -872,7 +872,7 @@ static int gfx_v9_4_query_ras_error_count(struct amdgpu_device *adev,
uint32_t reg_value;
if (!amdgpu_ras_is_supported(adev, AMDGPU_RAS_BLOCK__GFX))
- return -EINVAL;
+ return;
err_data->ue_count = 0;
err_data->ce_count = 0;
@@ -903,7 +903,6 @@ static int gfx_v9_4_query_ras_error_count(struct amdgpu_device *adev,
gfx_v9_4_query_utc_edc_status(adev, err_data);
- return 0;
}
static void gfx_v9_4_reset_ras_error_count(struct amdgpu_device *adev)
@@ -1029,11 +1028,16 @@ static void gfx_v9_4_query_ras_error_status(struct amdgpu_device *adev)
mutex_unlock(&adev->grbm_idx_mutex);
}
-const struct amdgpu_gfx_ras_funcs gfx_v9_4_ras_funcs = {
- .ras_late_init = amdgpu_gfx_ras_late_init,
- .ras_fini = amdgpu_gfx_ras_fini,
- .ras_error_inject = &gfx_v9_4_ras_error_inject,
- .query_ras_error_count = &gfx_v9_4_query_ras_error_count,
- .reset_ras_error_count = &gfx_v9_4_reset_ras_error_count,
- .query_ras_error_status = &gfx_v9_4_query_ras_error_status,
+
+const struct amdgpu_ras_block_hw_ops gfx_v9_4_ras_ops = {
+ .ras_error_inject = &gfx_v9_4_ras_error_inject,
+ .query_ras_error_count = &gfx_v9_4_query_ras_error_count,
+ .reset_ras_error_count = &gfx_v9_4_reset_ras_error_count,
+ .query_ras_error_status = &gfx_v9_4_query_ras_error_status,
+};
+
+struct amdgpu_gfx_ras gfx_v9_4_ras = {
+ .ras_block = {
+ .hw_ops = &gfx_v9_4_ras_ops,
+ },
};
diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v9_4.h b/drivers/gpu/drm/amd/amdgpu/gfx_v9_4.h
index bdd16b568021..ca520a767267 100644
--- a/drivers/gpu/drm/amd/amdgpu/gfx_v9_4.h
+++ b/drivers/gpu/drm/amd/amdgpu/gfx_v9_4.h
@@ -24,6 +24,6 @@
#ifndef __GFX_V9_4_H__
#define __GFX_V9_4_H__
-extern const struct amdgpu_gfx_ras_funcs gfx_v9_4_ras_funcs;
+extern struct amdgpu_gfx_ras gfx_v9_4_ras;
#endif /* __GFX_V9_4_H__ */
diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v9_4_2.c b/drivers/gpu/drm/amd/amdgpu/gfx_v9_4_2.c
index c4f37a161875..7653ebd0e67b 100644
--- a/drivers/gpu/drm/amd/amdgpu/gfx_v9_4_2.c
+++ b/drivers/gpu/drm/amd/amdgpu/gfx_v9_4_2.c
@@ -1641,14 +1641,14 @@ static int gfx_v9_4_2_query_utc_edc_count(struct amdgpu_device *adev,
return 0;
}
-static int gfx_v9_4_2_query_ras_error_count(struct amdgpu_device *adev,
+static void gfx_v9_4_2_query_ras_error_count(struct amdgpu_device *adev,
void *ras_error_status)
{
struct ras_err_data *err_data = (struct ras_err_data *)ras_error_status;
uint32_t sec_count = 0, ded_count = 0;
if (!amdgpu_ras_is_supported(adev, AMDGPU_RAS_BLOCK__GFX))
- return -EINVAL;
+ return;
err_data->ue_count = 0;
err_data->ce_count = 0;
@@ -1661,7 +1661,6 @@ static int gfx_v9_4_2_query_ras_error_count(struct amdgpu_device *adev,
err_data->ce_count += sec_count;
err_data->ue_count += ded_count;
- return 0;
}
static void gfx_v9_4_2_reset_utc_err_status(struct amdgpu_device *adev)
@@ -1931,13 +1930,17 @@ static void gfx_v9_4_2_reset_sq_timeout_status(struct amdgpu_device *adev)
mutex_unlock(&adev->grbm_idx_mutex);
}
-const struct amdgpu_gfx_ras_funcs gfx_v9_4_2_ras_funcs = {
- .ras_late_init = amdgpu_gfx_ras_late_init,
- .ras_fini = amdgpu_gfx_ras_fini,
- .ras_error_inject = &gfx_v9_4_2_ras_error_inject,
- .query_ras_error_count = &gfx_v9_4_2_query_ras_error_count,
- .reset_ras_error_count = &gfx_v9_4_2_reset_ras_error_count,
- .query_ras_error_status = &gfx_v9_4_2_query_ras_error_status,
- .reset_ras_error_status = &gfx_v9_4_2_reset_ras_error_status,
+struct amdgpu_ras_block_hw_ops gfx_v9_4_2_ras_ops = {
+ .ras_error_inject = &gfx_v9_4_2_ras_error_inject,
+ .query_ras_error_count = &gfx_v9_4_2_query_ras_error_count,
+ .reset_ras_error_count = &gfx_v9_4_2_reset_ras_error_count,
+ .query_ras_error_status = &gfx_v9_4_2_query_ras_error_status,
+ .reset_ras_error_status = &gfx_v9_4_2_reset_ras_error_status,
+};
+
+struct amdgpu_gfx_ras gfx_v9_4_2_ras = {
+ .ras_block = {
+ .hw_ops = &gfx_v9_4_2_ras_ops,
+ },
.enable_watchdog_timer = &gfx_v9_4_2_enable_watchdog_timer,
};
diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v9_4_2.h b/drivers/gpu/drm/amd/amdgpu/gfx_v9_4_2.h
index 6db1f88509af..7584624b641c 100644
--- a/drivers/gpu/drm/amd/amdgpu/gfx_v9_4_2.h
+++ b/drivers/gpu/drm/amd/amdgpu/gfx_v9_4_2.h
@@ -31,6 +31,6 @@ void gfx_v9_4_2_init_golden_registers(struct amdgpu_device *adev,
void gfx_v9_4_2_set_power_brake_sequence(struct amdgpu_device *adev);
int gfx_v9_4_2_do_edc_gpr_workarounds(struct amdgpu_device *adev);
-extern const struct amdgpu_gfx_ras_funcs gfx_v9_4_2_ras_funcs;
+extern struct amdgpu_gfx_ras gfx_v9_4_2_ras;
#endif /* __GFX_V9_4_2_H__ */
diff --git a/drivers/gpu/drm/amd/amdgpu/gfxhub_v2_1.c b/drivers/gpu/drm/amd/amdgpu/gfxhub_v2_1.c
index b4eddf6e98a6..ff738e9725ee 100644
--- a/drivers/gpu/drm/amd/amdgpu/gfxhub_v2_1.c
+++ b/drivers/gpu/drm/amd/amdgpu/gfxhub_v2_1.c
@@ -543,7 +543,9 @@ static void gfxhub_v2_1_utcl2_harvest(struct amdgpu_device *adev)
adev->gfx.config.max_sh_per_se *
adev->gfx.config.max_shader_engines);
- if (adev->ip_versions[GC_HWIP][0] == IP_VERSION(10, 3, 3)) {
+ switch (adev->ip_versions[GC_HWIP][0]) {
+ case IP_VERSION(10, 3, 1):
+ case IP_VERSION(10, 3, 3):
/* Get SA disabled bitmap from eFuse setting */
efuse_setting = RREG32_SOC15(GC, 0, mmCC_GC_SA_UNIT_DISABLE);
efuse_setting &= CC_GC_SA_UNIT_DISABLE__SA_DISABLE_MASK;
@@ -566,6 +568,9 @@ static void gfxhub_v2_1_utcl2_harvest(struct amdgpu_device *adev)
disabled_sa = tmp;
WREG32_SOC15(GC, 0, mmGCUTCL2_HARVEST_BYPASS_GROUPS_YELLOW_CARP, disabled_sa);
+ break;
+ default:
+ break;
}
}
diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c
index 38bb42727715..3c1d440824a7 100644
--- a/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c
@@ -48,6 +48,8 @@
#include "athub_v2_0.h"
#include "athub_v2_1.h"
+#include "amdgpu_reset.h"
+
#if 0
static const struct soc15_reg_golden golden_settings_navi10_hdp[] =
{
@@ -328,7 +330,7 @@ static void gmc_v10_0_flush_gpu_tlb(struct amdgpu_device *adev, uint32_t vmid,
*/
if (adev->gfx.kiq.ring.sched.ready &&
(amdgpu_sriov_runtime(adev) || !amdgpu_sriov_vf(adev)) &&
- down_read_trylock(&adev->reset_sem)) {
+ down_read_trylock(&adev->reset_domain->sem)) {
struct amdgpu_vmhub *hub = &adev->vmhub[vmhub];
const unsigned eng = 17;
u32 inv_req = hub->vmhub_funcs->get_invalidate_req(vmid, flush_type);
@@ -338,7 +340,7 @@ static void gmc_v10_0_flush_gpu_tlb(struct amdgpu_device *adev, uint32_t vmid,
amdgpu_virt_kiq_reg_write_reg_wait(adev, req, ack, inv_req,
1 << vmid);
- up_read(&adev->reset_sem);
+ up_read(&adev->reset_domain->sem);
return;
}
@@ -664,11 +666,27 @@ static void gmc_v10_0_set_umc_funcs(struct amdgpu_device *adev)
adev->umc.umc_inst_num = UMC_V8_7_UMC_INSTANCE_NUM;
adev->umc.channel_offs = UMC_V8_7_PER_CHANNEL_OFFSET_SIENNA;
adev->umc.channel_idx_tbl = &umc_v8_7_channel_idx_tbl[0][0];
- adev->umc.ras_funcs = &umc_v8_7_ras_funcs;
+ adev->umc.ras = &umc_v8_7_ras;
break;
default:
break;
}
+ if (adev->umc.ras) {
+ amdgpu_ras_register_ras_block(adev, &adev->umc.ras->ras_block);
+
+ strcpy(adev->umc.ras->ras_block.ras_comm.name, "umc");
+ adev->umc.ras->ras_block.ras_comm.block = AMDGPU_RAS_BLOCK__UMC;
+ adev->umc.ras->ras_block.ras_comm.type = AMDGPU_RAS_ERROR__MULTI_UNCORRECTABLE;
+ adev->umc.ras_if = &adev->umc.ras->ras_block.ras_comm;
+
+ /* If don't define special ras_late_init function, use default ras_late_init */
+ if (!adev->umc.ras->ras_block.ras_late_init)
+ adev->umc.ras->ras_block.ras_late_init = amdgpu_umc_ras_late_init;
+
+ /* If not defined special ras_cb function, use default ras_cb */
+ if (!adev->umc.ras->ras_block.ras_cb)
+ adev->umc.ras->ras_block.ras_cb = amdgpu_umc_process_ras_data_cb;
+ }
}
@@ -677,6 +695,7 @@ static void gmc_v10_0_set_mmhub_funcs(struct amdgpu_device *adev)
switch (adev->ip_versions[MMHUB_HWIP][0]) {
case IP_VERSION(2, 3, 0):
case IP_VERSION(2, 4, 0):
+ case IP_VERSION(2, 4, 1):
adev->mmhub.funcs = &mmhub_v2_3_funcs;
break;
default:
@@ -693,7 +712,9 @@ static void gmc_v10_0_set_gfxhub_funcs(struct amdgpu_device *adev)
case IP_VERSION(10, 3, 1):
case IP_VERSION(10, 3, 4):
case IP_VERSION(10, 3, 5):
+ case IP_VERSION(10, 3, 6):
case IP_VERSION(10, 3, 3):
+ case IP_VERSION(10, 3, 7):
adev->gfxhub.funcs = &gfxhub_v2_1_funcs;
break;
default:
@@ -705,6 +726,7 @@ static void gmc_v10_0_set_gfxhub_funcs(struct amdgpu_device *adev)
static int gmc_v10_0_early_init(void *handle)
{
+ int r;
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
gmc_v10_0_set_mmhub_funcs(adev);
@@ -720,6 +742,10 @@ static int gmc_v10_0_early_init(void *handle)
adev->gmc.private_aperture_end =
adev->gmc.private_aperture_start + (4ULL << 30) - 1;
+ r = amdgpu_gmc_ras_early_init(adev);
+ if (r)
+ return r;
+
return 0;
}
@@ -862,12 +888,15 @@ static int gmc_v10_0_sw_init(void *handle)
case IP_VERSION(10, 1, 1):
case IP_VERSION(10, 1, 2):
case IP_VERSION(10, 1, 3):
+ case IP_VERSION(10, 1, 4):
case IP_VERSION(10, 3, 0):
case IP_VERSION(10, 3, 2):
case IP_VERSION(10, 3, 1):
case IP_VERSION(10, 3, 4):
case IP_VERSION(10, 3, 5):
+ case IP_VERSION(10, 3, 6):
case IP_VERSION(10, 3, 3):
+ case IP_VERSION(10, 3, 7):
adev->num_vmhubs = 2;
/*
* To fulfill 4-level page support,
@@ -919,7 +948,6 @@ static int gmc_v10_0_sw_init(void *handle)
return r;
amdgpu_gmc_get_vbios_allocations(adev);
- amdgpu_gmc_get_reserved_allocation(adev);
/* Memory manager */
r = amdgpu_bo_init(adev);
@@ -986,14 +1014,7 @@ static int gmc_v10_0_gart_enable(struct amdgpu_device *adev)
return -EINVAL;
}
- if (amdgpu_sriov_vf(adev) && amdgpu_in_reset(adev))
- goto skip_pin_bo;
-
- r = amdgpu_gtt_mgr_recover(&adev->mman.gtt_mgr);
- if (r)
- return r;
-
-skip_pin_bo:
+ amdgpu_gtt_mgr_recover(&adev->mman.gtt_mgr);
r = adev->gfxhub.funcs->gart_enable(adev);
if (r)
return r;
@@ -1019,8 +1040,6 @@ skip_pin_bo:
(unsigned)(adev->gmc.gart_size >> 20),
(unsigned long long)amdgpu_bo_gpu_offset(adev->gart.bo));
- adev->gart.ready = true;
-
return 0;
}
@@ -1043,6 +1062,12 @@ static int gmc_v10_0_hw_init(void *handle)
if (r)
return r;
+ if (amdgpu_emu_mode == 1) {
+ r = amdgpu_gmc_vram_checking(adev);
+ if (r)
+ return r;
+ }
+
if (adev->umc.funcs && adev->umc.funcs->init_registers)
adev->umc.funcs->init_registers(adev);
@@ -1140,6 +1165,10 @@ static void gmc_v10_0_get_clockgating_state(void *handle, u32 *flags)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
+ if (adev->ip_versions[GC_HWIP][0] == IP_VERSION(10, 1, 3) ||
+ adev->ip_versions[GC_HWIP][0] == IP_VERSION(10, 1, 4))
+ return;
+
adev->mmhub.funcs->get_clockgating(adev, flags);
if (adev->ip_versions[ATHUB_HWIP][0] >= IP_VERSION(2, 1, 0))
diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v6_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v6_0.c
index cd6c38e083d0..ec291d28edff 100644
--- a/drivers/gpu/drm/amd/amdgpu/gmc_v6_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gmc_v6_0.c
@@ -469,16 +469,14 @@ static void gmc_v6_0_set_prt(struct amdgpu_device *adev, bool enable)
static int gmc_v6_0_gart_enable(struct amdgpu_device *adev)
{
uint64_t table_addr;
- int r, i;
u32 field;
+ int i;
if (adev->gart.bo == NULL) {
dev_err(adev->dev, "No VRAM object for PCIE GART.\n");
return -EINVAL;
}
- r = amdgpu_gtt_mgr_recover(&adev->mman.gtt_mgr);
- if (r)
- return r;
+ amdgpu_gtt_mgr_recover(&adev->mman.gtt_mgr);
table_addr = amdgpu_bo_gpu_offset(adev->gart.bo);
@@ -558,7 +556,6 @@ static int gmc_v6_0_gart_enable(struct amdgpu_device *adev)
dev_info(adev->dev, "PCIE GART of %uM enabled (table at 0x%016llX).\n",
(unsigned)(adev->gmc.gart_size >> 20),
(unsigned long long)table_addr);
- adev->gart.ready = true;
return 0;
}
@@ -922,7 +919,10 @@ static int gmc_v6_0_hw_init(void *handle)
if (r)
return r;
- return r;
+ if (amdgpu_emu_mode == 1)
+ return amdgpu_gmc_vram_checking(adev);
+ else
+ return r;
}
static int gmc_v6_0_hw_fini(void *handle)
diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c
index ab8adbff9e2d..344d819b4c1b 100644
--- a/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c
@@ -613,17 +613,14 @@ static void gmc_v7_0_set_prt(struct amdgpu_device *adev, bool enable)
static int gmc_v7_0_gart_enable(struct amdgpu_device *adev)
{
uint64_t table_addr;
- int r, i;
u32 tmp, field;
+ int i;
if (adev->gart.bo == NULL) {
dev_err(adev->dev, "No VRAM object for PCIE GART.\n");
return -EINVAL;
}
- r = amdgpu_gtt_mgr_recover(&adev->mman.gtt_mgr);
- if (r)
- return r;
-
+ amdgpu_gtt_mgr_recover(&adev->mman.gtt_mgr);
table_addr = amdgpu_bo_gpu_offset(adev->gart.bo);
/* Setup TLB control */
@@ -712,7 +709,6 @@ static int gmc_v7_0_gart_enable(struct amdgpu_device *adev)
DRM_INFO("PCIE GART of %uM enabled (table at 0x%016llX).\n",
(unsigned)(adev->gmc.gart_size >> 20),
(unsigned long long)table_addr);
- adev->gart.ready = true;
return 0;
}
@@ -1111,7 +1107,10 @@ static int gmc_v7_0_hw_init(void *handle)
if (r)
return r;
- return r;
+ if (amdgpu_emu_mode == 1)
+ return amdgpu_gmc_vram_checking(adev);
+ else
+ return r;
}
static int gmc_v7_0_hw_fini(void *handle)
diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c
index 054733838292..ca9841d5669f 100644
--- a/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c
@@ -837,17 +837,14 @@ static void gmc_v8_0_set_prt(struct amdgpu_device *adev, bool enable)
static int gmc_v8_0_gart_enable(struct amdgpu_device *adev)
{
uint64_t table_addr;
- int r, i;
u32 tmp, field;
+ int i;
if (adev->gart.bo == NULL) {
dev_err(adev->dev, "No VRAM object for PCIE GART.\n");
return -EINVAL;
}
- r = amdgpu_gtt_mgr_recover(&adev->mman.gtt_mgr);
- if (r)
- return r;
-
+ amdgpu_gtt_mgr_recover(&adev->mman.gtt_mgr);
table_addr = amdgpu_bo_gpu_offset(adev->gart.bo);
/* Setup TLB control */
@@ -953,7 +950,6 @@ static int gmc_v8_0_gart_enable(struct amdgpu_device *adev)
DRM_INFO("PCIE GART of %uM enabled (table at 0x%016llX).\n",
(unsigned)(adev->gmc.gart_size >> 20),
(unsigned long long)table_addr);
- adev->gart.ready = true;
return 0;
}
@@ -1242,7 +1238,10 @@ static int gmc_v8_0_hw_init(void *handle)
if (r)
return r;
- return r;
+ if (amdgpu_emu_mode == 1)
+ return amdgpu_gmc_vram_checking(adev);
+ else
+ return r;
}
static int gmc_v8_0_hw_fini(void *handle)
diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c
index 88c1eb9ad068..431742eb7811 100644
--- a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c
@@ -62,6 +62,8 @@
#include "amdgpu_ras.h"
#include "amdgpu_xgmi.h"
+#include "amdgpu_reset.h"
+
/* add these here since we already include dce12 headers and these are for DCN */
#define mmHUBP0_DCSURF_PRI_VIEWPORT_DIMENSION 0x055d
#define mmHUBP0_DCSURF_PRI_VIEWPORT_DIMENSION_BASE_IDX 2
@@ -787,13 +789,13 @@ static void gmc_v9_0_flush_gpu_tlb(struct amdgpu_device *adev, uint32_t vmid,
*/
if (adev->gfx.kiq.ring.sched.ready &&
(amdgpu_sriov_runtime(adev) || !amdgpu_sriov_vf(adev)) &&
- down_read_trylock(&adev->reset_sem)) {
+ down_read_trylock(&adev->reset_domain->sem)) {
uint32_t req = hub->vm_inv_eng0_req + hub->eng_distance * eng;
uint32_t ack = hub->vm_inv_eng0_ack + hub->eng_distance * eng;
amdgpu_virt_kiq_reg_write_reg_wait(adev, req, ack, inv_req,
1 << vmid);
- up_read(&adev->reset_sem);
+ up_read(&adev->reset_domain->sem);
return;
}
@@ -900,7 +902,7 @@ static int gmc_v9_0_flush_gpu_tlb_pasid(struct amdgpu_device *adev,
if (amdgpu_in_reset(adev))
return -EIO;
- if (ring->sched.ready && down_read_trylock(&adev->reset_sem)) {
+ if (ring->sched.ready && down_read_trylock(&adev->reset_domain->sem)) {
/* Vega20+XGMI caches PTEs in TC and TLB. Add a
* heavy-weight TLB flush (type 2), which flushes
* both. Due to a race condition with concurrent
@@ -927,7 +929,7 @@ static int gmc_v9_0_flush_gpu_tlb_pasid(struct amdgpu_device *adev,
if (r) {
amdgpu_ring_undo(ring);
spin_unlock(&adev->gfx.kiq.ring_lock);
- up_read(&adev->reset_sem);
+ up_read(&adev->reset_domain->sem);
return -ETIME;
}
@@ -936,10 +938,10 @@ static int gmc_v9_0_flush_gpu_tlb_pasid(struct amdgpu_device *adev,
r = amdgpu_fence_wait_polling(ring, seq, adev->usec_timeout);
if (r < 1) {
dev_err(adev->dev, "wait for kiq fence error: %ld.\n", r);
- up_read(&adev->reset_sem);
+ up_read(&adev->reset_domain->sem);
return -ETIME;
}
- up_read(&adev->reset_sem);
+ up_read(&adev->reset_domain->sem);
return 0;
}
@@ -1202,7 +1204,7 @@ static void gmc_v9_0_set_umc_funcs(struct amdgpu_device *adev)
adev->umc.umc_inst_num = UMC_V6_1_UMC_INSTANCE_NUM;
adev->umc.channel_offs = UMC_V6_1_PER_CHANNEL_OFFSET_VG20;
adev->umc.channel_idx_tbl = &umc_v6_1_channel_idx_tbl[0][0];
- adev->umc.ras_funcs = &umc_v6_1_ras_funcs;
+ adev->umc.ras = &umc_v6_1_ras;
break;
case IP_VERSION(6, 1, 2):
adev->umc.max_ras_err_cnt_per_query = UMC_V6_1_TOTAL_CHANNEL_NUM;
@@ -1210,15 +1212,16 @@ static void gmc_v9_0_set_umc_funcs(struct amdgpu_device *adev)
adev->umc.umc_inst_num = UMC_V6_1_UMC_INSTANCE_NUM;
adev->umc.channel_offs = UMC_V6_1_PER_CHANNEL_OFFSET_ARCT;
adev->umc.channel_idx_tbl = &umc_v6_1_channel_idx_tbl[0][0];
- adev->umc.ras_funcs = &umc_v6_1_ras_funcs;
+ adev->umc.ras = &umc_v6_1_ras;
break;
case IP_VERSION(6, 7, 0):
- adev->umc.max_ras_err_cnt_per_query = UMC_V6_7_TOTAL_CHANNEL_NUM;
+ adev->umc.max_ras_err_cnt_per_query =
+ UMC_V6_7_TOTAL_CHANNEL_NUM * UMC_V6_7_BAD_PAGE_NUM_PER_CHANNEL;
adev->umc.channel_inst_num = UMC_V6_7_CHANNEL_INSTANCE_NUM;
adev->umc.umc_inst_num = UMC_V6_7_UMC_INSTANCE_NUM;
adev->umc.channel_offs = UMC_V6_7_PER_CHANNEL_OFFSET;
if (!adev->gmc.xgmi.connected_to_cpu)
- adev->umc.ras_funcs = &umc_v6_7_ras_funcs;
+ adev->umc.ras = &umc_v6_7_ras;
if (1 & adev->smuio.funcs->get_die_id(adev))
adev->umc.channel_idx_tbl = &umc_v6_7_channel_idx_tbl_first[0][0];
else
@@ -1227,6 +1230,23 @@ static void gmc_v9_0_set_umc_funcs(struct amdgpu_device *adev)
default:
break;
}
+
+ if (adev->umc.ras) {
+ amdgpu_ras_register_ras_block(adev, &adev->umc.ras->ras_block);
+
+ strcpy(adev->umc.ras->ras_block.ras_comm.name, "umc");
+ adev->umc.ras->ras_block.ras_comm.block = AMDGPU_RAS_BLOCK__UMC;
+ adev->umc.ras->ras_block.ras_comm.type = AMDGPU_RAS_ERROR__MULTI_UNCORRECTABLE;
+ adev->umc.ras_if = &adev->umc.ras->ras_block.ras_comm;
+
+ /* If don't define special ras_late_init function, use default ras_late_init */
+ if (!adev->umc.ras->ras_block.ras_late_init)
+ adev->umc.ras->ras_block.ras_late_init = amdgpu_umc_ras_late_init;
+
+ /* If not defined special ras_cb function, use default ras_cb */
+ if (!adev->umc.ras->ras_block.ras_cb)
+ adev->umc.ras->ras_block.ras_cb = amdgpu_umc_process_ras_data_cb;
+ }
}
static void gmc_v9_0_set_mmhub_funcs(struct amdgpu_device *adev)
@@ -1248,18 +1268,27 @@ static void gmc_v9_0_set_mmhub_ras_funcs(struct amdgpu_device *adev)
{
switch (adev->ip_versions[MMHUB_HWIP][0]) {
case IP_VERSION(9, 4, 0):
- adev->mmhub.ras_funcs = &mmhub_v1_0_ras_funcs;
+ adev->mmhub.ras = &mmhub_v1_0_ras;
break;
case IP_VERSION(9, 4, 1):
- adev->mmhub.ras_funcs = &mmhub_v9_4_ras_funcs;
+ adev->mmhub.ras = &mmhub_v9_4_ras;
break;
case IP_VERSION(9, 4, 2):
- adev->mmhub.ras_funcs = &mmhub_v1_7_ras_funcs;
+ adev->mmhub.ras = &mmhub_v1_7_ras;
break;
default:
/* mmhub ras is not available */
break;
}
+
+ if (adev->mmhub.ras) {
+ amdgpu_ras_register_ras_block(adev, &adev->mmhub.ras->ras_block);
+
+ strcpy(adev->mmhub.ras->ras_block.ras_comm.name, "mmhub");
+ adev->mmhub.ras->ras_block.ras_comm.block = AMDGPU_RAS_BLOCK__MMHUB;
+ adev->mmhub.ras->ras_block.ras_comm.type = AMDGPU_RAS_ERROR__MULTI_UNCORRECTABLE;
+ adev->mmhub.ras_if = &adev->mmhub.ras->ras_block.ras_comm;
+ }
}
static void gmc_v9_0_set_gfxhub_funcs(struct amdgpu_device *adev)
@@ -1269,7 +1298,9 @@ static void gmc_v9_0_set_gfxhub_funcs(struct amdgpu_device *adev)
static void gmc_v9_0_set_hdp_ras_funcs(struct amdgpu_device *adev)
{
- adev->hdp.ras_funcs = &hdp_v4_0_ras_funcs;
+ adev->hdp.ras = &hdp_v4_0_ras;
+ amdgpu_ras_register_ras_block(adev, &adev->hdp.ras->ras_block);
+ adev->hdp.ras_if = &adev->hdp.ras->ras_block.ras_comm;
}
static void gmc_v9_0_set_mca_funcs(struct amdgpu_device *adev)
@@ -1287,6 +1318,7 @@ static void gmc_v9_0_set_mca_funcs(struct amdgpu_device *adev)
static int gmc_v9_0_early_init(void *handle)
{
+ int r;
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
/* ARCT and VEGA20 don't have XGMI defined in their IP discovery tables */
@@ -1316,6 +1348,10 @@ static int gmc_v9_0_early_init(void *handle)
adev->gmc.private_aperture_end =
adev->gmc.private_aperture_start + (4ULL << 30) - 1;
+ r = amdgpu_gmc_ras_early_init(adev);
+ if (r)
+ return r;
+
return 0;
}
@@ -1342,13 +1378,13 @@ static int gmc_v9_0_late_init(void *handle)
}
if (!amdgpu_persistent_edc_harvesting_supported(adev)) {
- if (adev->mmhub.ras_funcs &&
- adev->mmhub.ras_funcs->reset_ras_error_count)
- adev->mmhub.ras_funcs->reset_ras_error_count(adev);
+ if (adev->mmhub.ras && adev->mmhub.ras->ras_block.hw_ops &&
+ adev->mmhub.ras->ras_block.hw_ops->reset_ras_error_count)
+ adev->mmhub.ras->ras_block.hw_ops->reset_ras_error_count(adev);
- if (adev->hdp.ras_funcs &&
- adev->hdp.ras_funcs->reset_ras_error_count)
- adev->hdp.ras_funcs->reset_ras_error_count(adev);
+ if (adev->hdp.ras && adev->hdp.ras->ras_block.hw_ops &&
+ adev->hdp.ras->ras_block.hw_ops->reset_ras_error_count)
+ adev->hdp.ras->ras_block.hw_ops->reset_ras_error_count(adev);
}
r = amdgpu_gmc_ras_late_init(adev);
@@ -1517,7 +1553,7 @@ static void gmc_v9_0_save_registers(struct amdgpu_device *adev)
static int gmc_v9_0_sw_init(void *handle)
{
- int r, vram_width = 0, vram_type = 0, vram_vendor = 0;
+ int r, vram_width = 0, vram_type = 0, vram_vendor = 0, dma_addr_bits;
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
adev->gfxhub.funcs->init(adev);
@@ -1633,12 +1669,13 @@ static int gmc_v9_0_sw_init(void *handle)
*/
adev->gmc.mc_mask = 0xffffffffffffULL; /* 48 bit MC */
- r = dma_set_mask_and_coherent(adev->dev, DMA_BIT_MASK(44));
+ dma_addr_bits = adev->ip_versions[GC_HWIP][0] == IP_VERSION(9, 4, 2) ? 48:44;
+ r = dma_set_mask_and_coherent(adev->dev, DMA_BIT_MASK(dma_addr_bits));
if (r) {
printk(KERN_WARNING "amdgpu: No suitable DMA available.\n");
return r;
}
- adev->need_swiotlb = drm_need_swiotlb(44);
+ adev->need_swiotlb = drm_need_swiotlb(dma_addr_bits);
r = gmc_v9_0_mc_init(adev);
if (r)
@@ -1752,14 +1789,7 @@ static int gmc_v9_0_gart_enable(struct amdgpu_device *adev)
return -EINVAL;
}
- if (amdgpu_sriov_vf(adev) && amdgpu_in_reset(adev))
- goto skip_pin_bo;
-
- r = amdgpu_gtt_mgr_recover(&adev->mman.gtt_mgr);
- if (r)
- return r;
-
-skip_pin_bo:
+ amdgpu_gtt_mgr_recover(&adev->mman.gtt_mgr);
r = adev->gfxhub.funcs->gart_enable(adev);
if (r)
return r;
@@ -1776,7 +1806,6 @@ skip_pin_bo:
DRM_INFO("PTB located at 0x%016llX\n",
(unsigned long long)amdgpu_bo_gpu_offset(adev->gart.bo));
- adev->gart.ready = true;
return 0;
}
@@ -1784,7 +1813,7 @@ static int gmc_v9_0_hw_init(void *handle)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
bool value;
- int i;
+ int i, r;
/* The sequence of these two function calls matters.*/
gmc_v9_0_init_golden_registers(adev);
@@ -1819,7 +1848,14 @@ static int gmc_v9_0_hw_init(void *handle)
if (adev->umc.funcs && adev->umc.funcs->init_registers)
adev->umc.funcs->init_registers(adev);
- return gmc_v9_0_gart_enable(adev);
+ r = gmc_v9_0_gart_enable(adev);
+ if (r)
+ return r;
+
+ if (amdgpu_emu_mode == 1)
+ return amdgpu_gmc_vram_checking(adev);
+ else
+ return r;
}
/**
diff --git a/drivers/gpu/drm/amd/amdgpu/hdp_v4_0.c b/drivers/gpu/drm/amd/amdgpu/hdp_v4_0.c
index eecfb1545c1e..046216635262 100644
--- a/drivers/gpu/drm/amd/amdgpu/hdp_v4_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/hdp_v4_0.c
@@ -146,17 +146,29 @@ static void hdp_v4_0_init_registers(struct amdgpu_device *adev)
WREG32_FIELD15(HDP, 0, HDP_MISC_CNTL, FLUSH_INVALIDATE_CACHE, 1);
+ if (adev->ip_versions[HDP_HWIP][0] == IP_VERSION(4, 4, 0))
+ WREG32_FIELD15(HDP, 0, HDP_MISC_CNTL, READ_BUFFER_WATERMARK, 2);
+
WREG32_SOC15(HDP, 0, mmHDP_NONSURFACE_BASE, (adev->gmc.vram_start >> 8));
WREG32_SOC15(HDP, 0, mmHDP_NONSURFACE_BASE_HI, (adev->gmc.vram_start >> 40));
}
-const struct amdgpu_hdp_ras_funcs hdp_v4_0_ras_funcs = {
- .ras_late_init = amdgpu_hdp_ras_late_init,
- .ras_fini = amdgpu_hdp_ras_fini,
+struct amdgpu_ras_block_hw_ops hdp_v4_0_ras_hw_ops = {
.query_ras_error_count = hdp_v4_0_query_ras_error_count,
.reset_ras_error_count = hdp_v4_0_reset_ras_error_count,
};
+struct amdgpu_hdp_ras hdp_v4_0_ras = {
+ .ras_block = {
+ .ras_comm = {
+ .name = "hdp",
+ .block = AMDGPU_RAS_BLOCK__HDP,
+ .type = AMDGPU_RAS_ERROR__MULTI_UNCORRECTABLE,
+ },
+ .hw_ops = &hdp_v4_0_ras_hw_ops,
+ },
+};
+
const struct amdgpu_hdp_funcs hdp_v4_0_funcs = {
.flush_hdp = hdp_v4_0_flush_hdp,
.invalidate_hdp = hdp_v4_0_invalidate_hdp,
diff --git a/drivers/gpu/drm/amd/amdgpu/hdp_v4_0.h b/drivers/gpu/drm/amd/amdgpu/hdp_v4_0.h
index dc3a1b81dd62..c44eee9282ab 100644
--- a/drivers/gpu/drm/amd/amdgpu/hdp_v4_0.h
+++ b/drivers/gpu/drm/amd/amdgpu/hdp_v4_0.h
@@ -27,6 +27,6 @@
#include "soc15_common.h"
extern const struct amdgpu_hdp_funcs hdp_v4_0_funcs;
-extern const struct amdgpu_hdp_ras_funcs hdp_v4_0_ras_funcs;
+extern struct amdgpu_hdp_ras hdp_v4_0_ras;
#endif
diff --git a/drivers/gpu/drm/amd/amdgpu/jpeg_v3_0.c b/drivers/gpu/drm/amd/amdgpu/jpeg_v3_0.c
index 01c242c5abc3..41a00851b6c5 100644
--- a/drivers/gpu/drm/amd/amdgpu/jpeg_v3_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/jpeg_v3_0.c
@@ -50,11 +50,16 @@ static int jpeg_v3_0_early_init(void *handle)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
- if (adev->asic_type != CHIP_YELLOW_CARP) {
- u32 harvest = RREG32_SOC15(JPEG, 0, mmCC_UVD_HARVESTING);
+ u32 harvest;
+ switch (adev->ip_versions[UVD_HWIP][0]) {
+ case IP_VERSION(3, 1, 1):
+ break;
+ default:
+ harvest = RREG32_SOC15(JPEG, 0, mmCC_UVD_HARVESTING);
if (harvest & CC_UVD_HARVESTING__UVD_DISABLE_MASK)
return -ENOENT;
+ break;
}
adev->jpeg.num_jpeg_inst = 1;
diff --git a/drivers/gpu/drm/amd/amdgpu/mca_v3_0.c b/drivers/gpu/drm/amd/amdgpu/mca_v3_0.c
index 8f7107d392af..d4bd7d1d2649 100644
--- a/drivers/gpu/drm/amd/amdgpu/mca_v3_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/mca_v3_0.c
@@ -37,24 +37,36 @@ static void mca_v3_0_mp0_query_ras_error_count(struct amdgpu_device *adev,
ras_error_status);
}
-static int mca_v3_0_mp0_ras_late_init(struct amdgpu_device *adev)
+static int mca_v3_0_ras_block_match(struct amdgpu_ras_block_object *block_obj,
+ enum amdgpu_ras_block block, uint32_t sub_block_index)
{
- return amdgpu_mca_ras_late_init(adev, &adev->mca.mp0);
-}
+ if (!block_obj)
+ return -EINVAL;
-static void mca_v3_0_mp0_ras_fini(struct amdgpu_device *adev)
-{
- amdgpu_mca_ras_fini(adev, &adev->mca.mp0);
+ if ((block_obj->ras_comm.block == block) &&
+ (block_obj->ras_comm.sub_block_index == sub_block_index)) {
+ return 0;
+ }
+
+ return -EINVAL;
}
-const struct amdgpu_mca_ras_funcs mca_v3_0_mp0_ras_funcs = {
- .ras_late_init = mca_v3_0_mp0_ras_late_init,
- .ras_fini = mca_v3_0_mp0_ras_fini,
+const struct amdgpu_ras_block_hw_ops mca_v3_0_mp0_hw_ops = {
.query_ras_error_count = mca_v3_0_mp0_query_ras_error_count,
.query_ras_error_address = NULL,
- .ras_block = AMDGPU_RAS_BLOCK__MCA,
- .ras_sub_block = AMDGPU_RAS_MCA_BLOCK__MP0,
- .sysfs_name = "mp0_err_count",
+};
+
+struct amdgpu_mca_ras_block mca_v3_0_mp0_ras = {
+ .ras_block = {
+ .ras_comm = {
+ .block = AMDGPU_RAS_BLOCK__MCA,
+ .sub_block_index = AMDGPU_RAS_MCA_BLOCK__MP0,
+ .type = AMDGPU_RAS_ERROR__MULTI_UNCORRECTABLE,
+ .name = "mp0",
+ },
+ .hw_ops = &mca_v3_0_mp0_hw_ops,
+ .ras_block_match = mca_v3_0_ras_block_match,
+ },
};
static void mca_v3_0_mp1_query_ras_error_count(struct amdgpu_device *adev,
@@ -65,24 +77,22 @@ static void mca_v3_0_mp1_query_ras_error_count(struct amdgpu_device *adev,
ras_error_status);
}
-static int mca_v3_0_mp1_ras_late_init(struct amdgpu_device *adev)
-{
- return amdgpu_mca_ras_late_init(adev, &adev->mca.mp1);
-}
-
-static void mca_v3_0_mp1_ras_fini(struct amdgpu_device *adev)
-{
- amdgpu_mca_ras_fini(adev, &adev->mca.mp1);
-}
-
-const struct amdgpu_mca_ras_funcs mca_v3_0_mp1_ras_funcs = {
- .ras_late_init = mca_v3_0_mp1_ras_late_init,
- .ras_fini = mca_v3_0_mp1_ras_fini,
+const struct amdgpu_ras_block_hw_ops mca_v3_0_mp1_hw_ops = {
.query_ras_error_count = mca_v3_0_mp1_query_ras_error_count,
.query_ras_error_address = NULL,
- .ras_block = AMDGPU_RAS_BLOCK__MCA,
- .ras_sub_block = AMDGPU_RAS_MCA_BLOCK__MP1,
- .sysfs_name = "mp1_err_count",
+};
+
+struct amdgpu_mca_ras_block mca_v3_0_mp1_ras = {
+ .ras_block = {
+ .ras_comm = {
+ .block = AMDGPU_RAS_BLOCK__MCA,
+ .sub_block_index = AMDGPU_RAS_MCA_BLOCK__MP1,
+ .type = AMDGPU_RAS_ERROR__MULTI_UNCORRECTABLE,
+ .name = "mp1",
+ },
+ .hw_ops = &mca_v3_0_mp1_hw_ops,
+ .ras_block_match = mca_v3_0_ras_block_match,
+ },
};
static void mca_v3_0_mpio_query_ras_error_count(struct amdgpu_device *adev,
@@ -93,24 +103,22 @@ static void mca_v3_0_mpio_query_ras_error_count(struct amdgpu_device *adev,
ras_error_status);
}
-static int mca_v3_0_mpio_ras_late_init(struct amdgpu_device *adev)
-{
- return amdgpu_mca_ras_late_init(adev, &adev->mca.mpio);
-}
-
-static void mca_v3_0_mpio_ras_fini(struct amdgpu_device *adev)
-{
- amdgpu_mca_ras_fini(adev, &adev->mca.mpio);
-}
-
-const struct amdgpu_mca_ras_funcs mca_v3_0_mpio_ras_funcs = {
- .ras_late_init = mca_v3_0_mpio_ras_late_init,
- .ras_fini = mca_v3_0_mpio_ras_fini,
+const struct amdgpu_ras_block_hw_ops mca_v3_0_mpio_hw_ops = {
.query_ras_error_count = mca_v3_0_mpio_query_ras_error_count,
.query_ras_error_address = NULL,
- .ras_block = AMDGPU_RAS_BLOCK__MCA,
- .ras_sub_block = AMDGPU_RAS_MCA_BLOCK__MPIO,
- .sysfs_name = "mpio_err_count",
+};
+
+struct amdgpu_mca_ras_block mca_v3_0_mpio_ras = {
+ .ras_block = {
+ .ras_comm = {
+ .block = AMDGPU_RAS_BLOCK__MCA,
+ .sub_block_index = AMDGPU_RAS_MCA_BLOCK__MPIO,
+ .type = AMDGPU_RAS_ERROR__MULTI_UNCORRECTABLE,
+ .name = "mpio",
+ },
+ .hw_ops = &mca_v3_0_mpio_hw_ops,
+ .ras_block_match = mca_v3_0_ras_block_match,
+ },
};
@@ -118,9 +126,15 @@ static void mca_v3_0_init(struct amdgpu_device *adev)
{
struct amdgpu_mca *mca = &adev->mca;
- mca->mp0.ras_funcs = &mca_v3_0_mp0_ras_funcs;
- mca->mp1.ras_funcs = &mca_v3_0_mp1_ras_funcs;
- mca->mpio.ras_funcs = &mca_v3_0_mpio_ras_funcs;
+ mca->mp0.ras = &mca_v3_0_mp0_ras;
+ mca->mp1.ras = &mca_v3_0_mp1_ras;
+ mca->mpio.ras = &mca_v3_0_mpio_ras;
+ amdgpu_ras_register_ras_block(adev, &mca->mp0.ras->ras_block);
+ amdgpu_ras_register_ras_block(adev, &mca->mp1.ras->ras_block);
+ amdgpu_ras_register_ras_block(adev, &mca->mpio.ras->ras_block);
+ mca->mp0.ras_if = &mca->mp0.ras->ras_block.ras_comm;
+ mca->mp1.ras_if = &mca->mp1.ras->ras_block.ras_comm;
+ mca->mpio.ras_if = &mca->mpio.ras->ras_block.ras_comm;
}
const struct amdgpu_mca_funcs mca_v3_0_funcs = {
diff --git a/drivers/gpu/drm/amd/amdgpu/mmhub_v1_0.c b/drivers/gpu/drm/amd/amdgpu/mmhub_v1_0.c
index 1da2ec692057..4c9f0c0f3116 100644
--- a/drivers/gpu/drm/amd/amdgpu/mmhub_v1_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/mmhub_v1_0.c
@@ -774,13 +774,17 @@ static void mmhub_v1_0_reset_ras_error_count(struct amdgpu_device *adev)
}
}
-const struct amdgpu_mmhub_ras_funcs mmhub_v1_0_ras_funcs = {
- .ras_late_init = amdgpu_mmhub_ras_late_init,
- .ras_fini = amdgpu_mmhub_ras_fini,
+struct amdgpu_ras_block_hw_ops mmhub_v1_0_ras_hw_ops = {
.query_ras_error_count = mmhub_v1_0_query_ras_error_count,
.reset_ras_error_count = mmhub_v1_0_reset_ras_error_count,
};
+struct amdgpu_mmhub_ras mmhub_v1_0_ras = {
+ .ras_block = {
+ .hw_ops = &mmhub_v1_0_ras_hw_ops,
+ },
+};
+
const struct amdgpu_mmhub_funcs mmhub_v1_0_funcs = {
.get_fb_location = mmhub_v1_0_get_fb_location,
.init = mmhub_v1_0_init,
diff --git a/drivers/gpu/drm/amd/amdgpu/mmhub_v1_0.h b/drivers/gpu/drm/amd/amdgpu/mmhub_v1_0.h
index 4661b094e007..dae7ca48bd8b 100644
--- a/drivers/gpu/drm/amd/amdgpu/mmhub_v1_0.h
+++ b/drivers/gpu/drm/amd/amdgpu/mmhub_v1_0.h
@@ -24,6 +24,6 @@
#define __MMHUB_V1_0_H__
extern const struct amdgpu_mmhub_funcs mmhub_v1_0_funcs;
-extern const struct amdgpu_mmhub_ras_funcs mmhub_v1_0_ras_funcs;
+extern struct amdgpu_mmhub_ras mmhub_v1_0_ras;
#endif
diff --git a/drivers/gpu/drm/amd/amdgpu/mmhub_v1_7.c b/drivers/gpu/drm/amd/amdgpu/mmhub_v1_7.c
index f5f7181f9af5..3b901f941627 100644
--- a/drivers/gpu/drm/amd/amdgpu/mmhub_v1_7.c
+++ b/drivers/gpu/drm/amd/amdgpu/mmhub_v1_7.c
@@ -1321,15 +1321,19 @@ static void mmhub_v1_7_reset_ras_error_status(struct amdgpu_device *adev)
}
}
-const struct amdgpu_mmhub_ras_funcs mmhub_v1_7_ras_funcs = {
- .ras_late_init = amdgpu_mmhub_ras_late_init,
- .ras_fini = amdgpu_mmhub_ras_fini,
+struct amdgpu_ras_block_hw_ops mmhub_v1_7_ras_hw_ops = {
.query_ras_error_count = mmhub_v1_7_query_ras_error_count,
.reset_ras_error_count = mmhub_v1_7_reset_ras_error_count,
.query_ras_error_status = mmhub_v1_7_query_ras_error_status,
.reset_ras_error_status = mmhub_v1_7_reset_ras_error_status,
};
+struct amdgpu_mmhub_ras mmhub_v1_7_ras = {
+ .ras_block = {
+ .hw_ops = &mmhub_v1_7_ras_hw_ops,
+ },
+};
+
const struct amdgpu_mmhub_funcs mmhub_v1_7_funcs = {
.get_fb_location = mmhub_v1_7_get_fb_location,
.init = mmhub_v1_7_init,
diff --git a/drivers/gpu/drm/amd/amdgpu/mmhub_v1_7.h b/drivers/gpu/drm/amd/amdgpu/mmhub_v1_7.h
index a7f9dfc24697..629f49052137 100644
--- a/drivers/gpu/drm/amd/amdgpu/mmhub_v1_7.h
+++ b/drivers/gpu/drm/amd/amdgpu/mmhub_v1_7.h
@@ -24,6 +24,6 @@
#define __MMHUB_V1_7_H__
extern const struct amdgpu_mmhub_funcs mmhub_v1_7_funcs;
-extern const struct amdgpu_mmhub_ras_funcs mmhub_v1_7_ras_funcs;
+extern struct amdgpu_mmhub_ras mmhub_v1_7_ras;
#endif
diff --git a/drivers/gpu/drm/amd/amdgpu/mmhub_v2_3.c b/drivers/gpu/drm/amd/amdgpu/mmhub_v2_3.c
index 9e16da28505a..1957fb098c4d 100644
--- a/drivers/gpu/drm/amd/amdgpu/mmhub_v2_3.c
+++ b/drivers/gpu/drm/amd/amdgpu/mmhub_v2_3.c
@@ -93,6 +93,7 @@ mmhub_v2_3_print_l2_protection_fault_status(struct amdgpu_device *adev,
switch (adev->ip_versions[MMHUB_HWIP][0]) {
case IP_VERSION(2, 3, 0):
case IP_VERSION(2, 4, 0):
+ case IP_VERSION(2, 4, 1):
mmhub_cid = mmhub_client_ids_vangogh[cid][rw];
break;
default:
diff --git a/drivers/gpu/drm/amd/amdgpu/mmhub_v9_4.c b/drivers/gpu/drm/amd/amdgpu/mmhub_v9_4.c
index ff49eeaf7882..619106f7d23d 100644
--- a/drivers/gpu/drm/amd/amdgpu/mmhub_v9_4.c
+++ b/drivers/gpu/drm/amd/amdgpu/mmhub_v9_4.c
@@ -1655,14 +1655,18 @@ static void mmhub_v9_4_query_ras_error_status(struct amdgpu_device *adev)
}
}
-const struct amdgpu_mmhub_ras_funcs mmhub_v9_4_ras_funcs = {
- .ras_late_init = amdgpu_mmhub_ras_late_init,
- .ras_fini = amdgpu_mmhub_ras_fini,
+const struct amdgpu_ras_block_hw_ops mmhub_v9_4_ras_hw_ops = {
.query_ras_error_count = mmhub_v9_4_query_ras_error_count,
.reset_ras_error_count = mmhub_v9_4_reset_ras_error_count,
.query_ras_error_status = mmhub_v9_4_query_ras_error_status,
};
+struct amdgpu_mmhub_ras mmhub_v9_4_ras = {
+ .ras_block = {
+ .hw_ops = &mmhub_v9_4_ras_hw_ops,
+ },
+};
+
const struct amdgpu_mmhub_funcs mmhub_v9_4_funcs = {
.get_fb_location = mmhub_v9_4_get_fb_location,
.init = mmhub_v9_4_init,
diff --git a/drivers/gpu/drm/amd/amdgpu/mmhub_v9_4.h b/drivers/gpu/drm/amd/amdgpu/mmhub_v9_4.h
index 90436efa92ef..a48329d95f71 100644
--- a/drivers/gpu/drm/amd/amdgpu/mmhub_v9_4.h
+++ b/drivers/gpu/drm/amd/amdgpu/mmhub_v9_4.h
@@ -24,6 +24,6 @@
#define __MMHUB_V9_4_H__
extern const struct amdgpu_mmhub_funcs mmhub_v9_4_funcs;
-extern const struct amdgpu_mmhub_ras_funcs mmhub_v9_4_ras_funcs;
+extern struct amdgpu_mmhub_ras mmhub_v9_4_ras;
#endif
diff --git a/drivers/gpu/drm/amd/amdgpu/mxgpu_ai.c b/drivers/gpu/drm/amd/amdgpu/mxgpu_ai.c
index 56da5ab82987..b81acf59870c 100644
--- a/drivers/gpu/drm/amd/amdgpu/mxgpu_ai.c
+++ b/drivers/gpu/drm/amd/amdgpu/mxgpu_ai.c
@@ -32,6 +32,8 @@
#include "soc15_common.h"
#include "mxgpu_ai.h"
+#include "amdgpu_reset.h"
+
static void xgpu_ai_mailbox_send_ack(struct amdgpu_device *adev)
{
WREG8(AI_MAIBOX_CONTROL_RCV_OFFSET_BYTE, 2);
@@ -257,10 +259,10 @@ static void xgpu_ai_mailbox_flr_work(struct work_struct *work)
* otherwise the mailbox msg will be ruined/reseted by
* the VF FLR.
*/
- if (atomic_cmpxchg(&adev->in_gpu_reset, 0, 1) != 0)
+ if (atomic_cmpxchg(&adev->reset_domain->in_gpu_reset, 0, 1) != 0)
return;
- down_write(&adev->reset_sem);
+ down_write(&adev->reset_domain->sem);
amdgpu_virt_fini_data_exchange(adev);
@@ -275,14 +277,14 @@ static void xgpu_ai_mailbox_flr_work(struct work_struct *work)
} while (timeout > 1);
flr_done:
- atomic_set(&adev->in_gpu_reset, 0);
- up_write(&adev->reset_sem);
+ atomic_set(&adev->reset_domain->in_gpu_reset, 0);
+ up_write(&adev->reset_domain->sem);
/* Trigger recovery for world switch failure if no TDR */
if (amdgpu_device_should_recover_gpu(adev)
&& (!amdgpu_device_has_job_running(adev) ||
adev->sdma_timeout == MAX_SCHEDULE_TIMEOUT))
- amdgpu_device_gpu_recover(adev, NULL);
+ amdgpu_device_gpu_recover_imp(adev, NULL);
}
static int xgpu_ai_set_mailbox_rcv_irq(struct amdgpu_device *adev,
@@ -307,8 +309,11 @@ static int xgpu_ai_mailbox_rcv_irq(struct amdgpu_device *adev,
switch (event) {
case IDH_FLR_NOTIFICATION:
- if (amdgpu_sriov_runtime(adev))
- schedule_work(&adev->virt.flr_work);
+ if (amdgpu_sriov_runtime(adev) && !amdgpu_in_reset(adev))
+ WARN_ONCE(!amdgpu_reset_domain_schedule(adev->reset_domain,
+ &adev->virt.flr_work),
+ "Failed to queue work! at %s",
+ __func__);
break;
case IDH_QUERY_ALIVE:
xgpu_ai_mailbox_send_ack(adev);
diff --git a/drivers/gpu/drm/amd/amdgpu/mxgpu_nv.c b/drivers/gpu/drm/amd/amdgpu/mxgpu_nv.c
index 477d0dde19c5..22c10b97ea81 100644
--- a/drivers/gpu/drm/amd/amdgpu/mxgpu_nv.c
+++ b/drivers/gpu/drm/amd/amdgpu/mxgpu_nv.c
@@ -31,6 +31,8 @@
#include "soc15_common.h"
#include "mxgpu_nv.h"
+#include "amdgpu_reset.h"
+
static void xgpu_nv_mailbox_send_ack(struct amdgpu_device *adev)
{
WREG8(NV_MAIBOX_CONTROL_RCV_OFFSET_BYTE, 2);
@@ -281,10 +283,10 @@ static void xgpu_nv_mailbox_flr_work(struct work_struct *work)
* otherwise the mailbox msg will be ruined/reseted by
* the VF FLR.
*/
- if (atomic_cmpxchg(&adev->in_gpu_reset, 0, 1) != 0)
+ if (atomic_cmpxchg(&adev->reset_domain->in_gpu_reset, 0, 1) != 0)
return;
- down_write(&adev->reset_sem);
+ down_write(&adev->reset_domain->sem);
amdgpu_virt_fini_data_exchange(adev);
@@ -299,8 +301,8 @@ static void xgpu_nv_mailbox_flr_work(struct work_struct *work)
} while (timeout > 1);
flr_done:
- atomic_set(&adev->in_gpu_reset, 0);
- up_write(&adev->reset_sem);
+ atomic_set(&adev->reset_domain->in_gpu_reset, 0);
+ up_write(&adev->reset_domain->sem);
/* Trigger recovery for world switch failure if no TDR */
if (amdgpu_device_should_recover_gpu(adev)
@@ -309,7 +311,7 @@ flr_done:
adev->gfx_timeout == MAX_SCHEDULE_TIMEOUT ||
adev->compute_timeout == MAX_SCHEDULE_TIMEOUT ||
adev->video_timeout == MAX_SCHEDULE_TIMEOUT))
- amdgpu_device_gpu_recover(adev, NULL);
+ amdgpu_device_gpu_recover_imp(adev, NULL);
}
static int xgpu_nv_set_mailbox_rcv_irq(struct amdgpu_device *adev,
@@ -337,8 +339,11 @@ static int xgpu_nv_mailbox_rcv_irq(struct amdgpu_device *adev,
switch (event) {
case IDH_FLR_NOTIFICATION:
- if (amdgpu_sriov_runtime(adev))
- schedule_work(&adev->virt.flr_work);
+ if (amdgpu_sriov_runtime(adev) && !amdgpu_in_reset(adev))
+ WARN_ONCE(!amdgpu_reset_domain_schedule(adev->reset_domain,
+ &adev->virt.flr_work),
+ "Failed to queue work! at %s",
+ __func__);
break;
/* READY_TO_ACCESS_GPU is fetched by kernel polling, IRQ can ignore
* it byfar since that polling thread will handle it,
diff --git a/drivers/gpu/drm/amd/amdgpu/mxgpu_vi.c b/drivers/gpu/drm/amd/amdgpu/mxgpu_vi.c
index aef9d059ae52..7b63d30b9b79 100644
--- a/drivers/gpu/drm/amd/amdgpu/mxgpu_vi.c
+++ b/drivers/gpu/drm/amd/amdgpu/mxgpu_vi.c
@@ -42,6 +42,8 @@
#include "smu/smu_7_1_3_d.h"
#include "mxgpu_vi.h"
+#include "amdgpu_reset.h"
+
/* VI golden setting */
static const u32 xgpu_fiji_mgcg_cgcg_init[] = {
mmRLC_CGTT_MGCG_OVERRIDE, 0xffffffff, 0xffffffff,
@@ -521,7 +523,7 @@ static void xgpu_vi_mailbox_flr_work(struct work_struct *work)
/* Trigger recovery due to world switch failure */
if (amdgpu_device_should_recover_gpu(adev))
- amdgpu_device_gpu_recover(adev, NULL);
+ amdgpu_device_gpu_recover_imp(adev, NULL);
}
static int xgpu_vi_set_mailbox_rcv_irq(struct amdgpu_device *adev,
@@ -544,14 +546,17 @@ static int xgpu_vi_mailbox_rcv_irq(struct amdgpu_device *adev,
{
int r;
- /* trigger gpu-reset by hypervisor only if TDR disbaled */
+ /* trigger gpu-reset by hypervisor only if TDR disabled */
if (!amdgpu_gpu_recovery) {
/* see what event we get */
r = xgpu_vi_mailbox_rcv_msg(adev, IDH_FLR_NOTIFICATION);
/* only handle FLR_NOTIFY now */
- if (!r)
- schedule_work(&adev->virt.flr_work);
+ if (!r && !amdgpu_in_reset(adev))
+ WARN_ONCE(!amdgpu_reset_domain_schedule(adev->reset_domain,
+ &adev->virt.flr_work),
+ "Failed to queue work! at %s",
+ __func__);
}
return 0;
diff --git a/drivers/gpu/drm/amd/amdgpu/nbio_v7_2.c b/drivers/gpu/drm/amd/amdgpu/nbio_v7_2.c
index 3444332ea110..6f81de6f3cc4 100644
--- a/drivers/gpu/drm/amd/amdgpu/nbio_v7_2.c
+++ b/drivers/gpu/drm/amd/amdgpu/nbio_v7_2.c
@@ -59,10 +59,16 @@ static u32 nbio_v7_2_get_rev_id(struct amdgpu_device *adev)
{
u32 tmp;
- if (adev->asic_type == CHIP_YELLOW_CARP)
+ switch (adev->ip_versions[NBIO_HWIP][0]) {
+ case IP_VERSION(7, 2, 1):
+ case IP_VERSION(7, 3, 0):
+ case IP_VERSION(7, 5, 0):
tmp = RREG32_SOC15(NBIO, 0, regRCC_STRAP0_RCC_DEV0_EPF0_STRAP0_YC);
- else
+ break;
+ default:
tmp = RREG32_SOC15(NBIO, 0, regRCC_STRAP0_RCC_DEV0_EPF0_STRAP0);
+ break;
+ }
tmp &= RCC_STRAP0_RCC_DEV0_EPF0_STRAP0__STRAP_ATI_REV_ID_DEV0_F0_MASK;
tmp >>= RCC_STRAP0_RCC_DEV0_EPF0_STRAP0__STRAP_ATI_REV_ID_DEV0_F0__SHIFT;
@@ -72,20 +78,26 @@ static u32 nbio_v7_2_get_rev_id(struct amdgpu_device *adev)
static void nbio_v7_2_mc_access_enable(struct amdgpu_device *adev, bool enable)
{
- if (enable)
- if (adev->asic_type == CHIP_YELLOW_CARP)
+ switch (adev->ip_versions[NBIO_HWIP][0]) {
+ case IP_VERSION(7, 2, 1):
+ case IP_VERSION(7, 3, 0):
+ case IP_VERSION(7, 5, 0):
+ if (enable)
WREG32_SOC15(NBIO, 0, regBIF_BX0_BIF_FB_EN_YC,
BIF_BX0_BIF_FB_EN__FB_READ_EN_MASK |
BIF_BX0_BIF_FB_EN__FB_WRITE_EN_MASK);
else
+ WREG32_SOC15(NBIO, 0, regBIF_BX0_BIF_FB_EN_YC, 0);
+ break;
+ default:
+ if (enable)
WREG32_SOC15(NBIO, 0, regBIF_BX0_BIF_FB_EN,
BIF_BX0_BIF_FB_EN__FB_READ_EN_MASK |
BIF_BX0_BIF_FB_EN__FB_WRITE_EN_MASK);
- else
- if (adev->asic_type == CHIP_YELLOW_CARP)
- WREG32_SOC15(NBIO, 0, regBIF_BX0_BIF_FB_EN_YC, 0);
else
WREG32_SOC15(NBIO, 0, regBIF_BX0_BIF_FB_EN, 0);
+ break;
+ }
}
static u32 nbio_v7_2_get_memsize(struct amdgpu_device *adev)
@@ -250,7 +262,10 @@ static void nbio_v7_2_update_medium_grain_light_sleep(struct amdgpu_device *adev
{
uint32_t def, data;
- if (adev->asic_type == CHIP_YELLOW_CARP) {
+ switch (adev->ip_versions[NBIO_HWIP][0]) {
+ case IP_VERSION(7, 2, 1):
+ case IP_VERSION(7, 3, 0):
+ case IP_VERSION(7, 5, 0):
def = data = RREG32_PCIE_PORT(SOC15_REG_OFFSET(NBIO, 0, regPCIE_CNTL2));
if (enable && (adev->cg_flags & AMD_CG_SUPPORT_BIF_LS))
data |= PCIE_CNTL2__SLV_MEM_LS_EN_MASK;
@@ -260,8 +275,8 @@ static void nbio_v7_2_update_medium_grain_light_sleep(struct amdgpu_device *adev
if (def != data)
WREG32_PCIE_PORT(SOC15_REG_OFFSET(NBIO, 0, regPCIE_CNTL2), data);
- data = RREG32_PCIE_PORT(SOC15_REG_OFFSET(NBIO, 0, regBIF1_PCIE_TX_POWER_CTRL_1));
- def = data;
+ def = data = RREG32_PCIE_PORT(SOC15_REG_OFFSET(NBIO, 0,
+ regBIF1_PCIE_TX_POWER_CTRL_1));
if (enable && (adev->cg_flags & AMD_CG_SUPPORT_BIF_LS))
data |= (BIF1_PCIE_TX_POWER_CTRL_1__MST_MEM_LS_EN_MASK |
BIF1_PCIE_TX_POWER_CTRL_1__REPLAY_MEM_LS_EN_MASK);
@@ -272,7 +287,8 @@ static void nbio_v7_2_update_medium_grain_light_sleep(struct amdgpu_device *adev
if (def != data)
WREG32_PCIE_PORT(SOC15_REG_OFFSET(NBIO, 0, regBIF1_PCIE_TX_POWER_CTRL_1),
data);
- } else {
+ break;
+ default:
def = data = RREG32_PCIE_PORT(SOC15_REG_OFFSET(NBIO, 0, regPCIE_CNTL2));
if (enable && (adev->cg_flags & AMD_CG_SUPPORT_BIF_LS))
data |= (PCIE_CNTL2__SLV_MEM_LS_EN_MASK |
@@ -285,6 +301,7 @@ static void nbio_v7_2_update_medium_grain_light_sleep(struct amdgpu_device *adev
if (def != data)
WREG32_PCIE_PORT(SOC15_REG_OFFSET(NBIO, 0, regPCIE_CNTL2), data);
+ break;
}
}
@@ -352,7 +369,10 @@ const struct nbio_hdp_flush_reg nbio_v7_2_hdp_flush_reg = {
static void nbio_v7_2_init_registers(struct amdgpu_device *adev)
{
uint32_t def, data;
- if (adev->asic_type == CHIP_YELLOW_CARP) {
+ switch (adev->ip_versions[NBIO_HWIP][0]) {
+ case IP_VERSION(7, 2, 1):
+ case IP_VERSION(7, 3, 0):
+ case IP_VERSION(7, 5, 0):
def = data = RREG32_PCIE_PORT(SOC15_REG_OFFSET(NBIO, 0, regBIF1_PCIE_MST_CTRL_3));
data = REG_SET_FIELD(data, BIF1_PCIE_MST_CTRL_3,
CI_SWUS_MAX_READ_REQUEST_SIZE_MODE, 1);
@@ -361,7 +381,8 @@ static void nbio_v7_2_init_registers(struct amdgpu_device *adev)
if (def != data)
WREG32_PCIE_PORT(SOC15_REG_OFFSET(NBIO, 0, regBIF1_PCIE_MST_CTRL_3), data);
- } else {
+ break;
+ default:
def = data = RREG32_PCIE_PORT(SOC15_REG_OFFSET(NBIO, 0, regPCIE_CONFIG_CNTL));
data = REG_SET_FIELD(data, PCIE_CONFIG_CNTL,
CI_SWUS_MAX_READ_REQUEST_SIZE_MODE, 1);
@@ -370,6 +391,7 @@ static void nbio_v7_2_init_registers(struct amdgpu_device *adev)
if (def != data)
WREG32_PCIE_PORT(SOC15_REG_OFFSET(NBIO, 0, regPCIE_CONFIG_CNTL), data);
+ break;
}
if (amdgpu_sriov_vf(adev))
diff --git a/drivers/gpu/drm/amd/amdgpu/nbio_v7_4.c b/drivers/gpu/drm/amd/amdgpu/nbio_v7_4.c
index dc5e93756fea..c2357e83a8c4 100644
--- a/drivers/gpu/drm/amd/amdgpu/nbio_v7_4.c
+++ b/drivers/gpu/drm/amd/amdgpu/nbio_v7_4.c
@@ -362,9 +362,24 @@ const struct nbio_hdp_flush_reg nbio_v7_4_hdp_flush_reg_ald = {
static void nbio_v7_4_init_registers(struct amdgpu_device *adev)
{
+ uint32_t baco_cntl;
+
if (amdgpu_sriov_vf(adev))
adev->rmmio_remap.reg_offset = SOC15_REG_OFFSET(NBIO, 0,
mmBIF_BX_DEV0_EPF0_VF0_HDP_MEM_COHERENCY_FLUSH_CNTL) << 2;
+
+ if (adev->ip_versions[NBIO_HWIP][0] == IP_VERSION(7, 4, 4) &&
+ !amdgpu_sriov_vf(adev)) {
+ baco_cntl = RREG32_SOC15(NBIO, 0, mmBACO_CNTL);
+ if (baco_cntl &
+ (BACO_CNTL__BACO_DUMMY_EN_MASK | BACO_CNTL__BACO_EN_MASK)) {
+ baco_cntl &= ~(BACO_CNTL__BACO_DUMMY_EN_MASK |
+ BACO_CNTL__BACO_EN_MASK);
+ dev_dbg(adev->dev, "Unsetting baco dummy mode %x",
+ baco_cntl);
+ WREG32_SOC15(NBIO, 0, mmBACO_CNTL, baco_cntl);
+ }
+ }
}
static void nbio_v7_4_handle_ras_controller_intr_no_bifring(struct amdgpu_device *adev)
@@ -658,16 +673,27 @@ static void nbio_v7_4_enable_doorbell_interrupt(struct amdgpu_device *adev,
DOORBELL_INTERRUPT_DISABLE, enable ? 0 : 1);
}
-const struct amdgpu_nbio_ras_funcs nbio_v7_4_ras_funcs = {
+const struct amdgpu_ras_block_hw_ops nbio_v7_4_ras_hw_ops = {
+ .query_ras_error_count = nbio_v7_4_query_ras_error_count,
+};
+
+struct amdgpu_nbio_ras nbio_v7_4_ras = {
+ .ras_block = {
+ .ras_comm = {
+ .name = "pcie_bif",
+ .block = AMDGPU_RAS_BLOCK__PCIE_BIF,
+ .type = AMDGPU_RAS_ERROR__MULTI_UNCORRECTABLE,
+ },
+ .hw_ops = &nbio_v7_4_ras_hw_ops,
+ .ras_late_init = amdgpu_nbio_ras_late_init,
+ },
.handle_ras_controller_intr_no_bifring = nbio_v7_4_handle_ras_controller_intr_no_bifring,
.handle_ras_err_event_athub_intr_no_bifring = nbio_v7_4_handle_ras_err_event_athub_intr_no_bifring,
.init_ras_controller_interrupt = nbio_v7_4_init_ras_controller_interrupt,
.init_ras_err_event_athub_interrupt = nbio_v7_4_init_ras_err_event_athub_interrupt,
- .query_ras_error_count = nbio_v7_4_query_ras_error_count,
- .ras_late_init = amdgpu_nbio_ras_late_init,
- .ras_fini = amdgpu_nbio_ras_fini,
};
+
static void nbio_v7_4_program_ltr(struct amdgpu_device *adev)
{
uint32_t def, data;
diff --git a/drivers/gpu/drm/amd/amdgpu/nbio_v7_4.h b/drivers/gpu/drm/amd/amdgpu/nbio_v7_4.h
index cc5692db6f98..7490022d79d4 100644
--- a/drivers/gpu/drm/amd/amdgpu/nbio_v7_4.h
+++ b/drivers/gpu/drm/amd/amdgpu/nbio_v7_4.h
@@ -29,6 +29,6 @@
extern const struct nbio_hdp_flush_reg nbio_v7_4_hdp_flush_reg;
extern const struct nbio_hdp_flush_reg nbio_v7_4_hdp_flush_reg_ald;
extern const struct amdgpu_nbio_funcs nbio_v7_4_funcs;
-extern const struct amdgpu_nbio_ras_funcs nbio_v7_4_ras_funcs;
+extern struct amdgpu_nbio_ras nbio_v7_4_ras;
#endif
diff --git a/drivers/gpu/drm/amd/amdgpu/nv.c b/drivers/gpu/drm/amd/amdgpu/nv.c
index 2ec1ffb36b1f..e19f14c3ef59 100644
--- a/drivers/gpu/drm/amd/amdgpu/nv.c
+++ b/drivers/gpu/drm/amd/amdgpu/nv.c
@@ -204,6 +204,7 @@ static int nv_query_video_codecs(struct amdgpu_device *adev, bool encode,
*codecs = &sc_video_codecs_decode;
return 0;
case IP_VERSION(3, 1, 1):
+ case IP_VERSION(3, 1, 2):
if (encode)
*codecs = &nv_video_codecs_encode;
else
@@ -258,21 +259,6 @@ static u64 nv_pcie_rreg64(struct amdgpu_device *adev, u32 reg)
return amdgpu_device_indirect_rreg64(adev, address, data, reg);
}
-static u32 nv_pcie_port_rreg(struct amdgpu_device *adev, u32 reg)
-{
- unsigned long flags, address, data;
- u32 r;
- address = adev->nbio.funcs->get_pcie_port_index_offset(adev);
- data = adev->nbio.funcs->get_pcie_port_data_offset(adev);
-
- spin_lock_irqsave(&adev->pcie_idx_lock, flags);
- WREG32(address, reg * 4);
- (void)RREG32(address);
- r = RREG32(data);
- spin_unlock_irqrestore(&adev->pcie_idx_lock, flags);
- return r;
-}
-
static void nv_pcie_wreg64(struct amdgpu_device *adev, u32 reg, u64 v)
{
unsigned long address, data;
@@ -283,21 +269,6 @@ static void nv_pcie_wreg64(struct amdgpu_device *adev, u32 reg, u64 v)
amdgpu_device_indirect_wreg64(adev, address, data, reg, v);
}
-static void nv_pcie_port_wreg(struct amdgpu_device *adev, u32 reg, u32 v)
-{
- unsigned long flags, address, data;
-
- address = adev->nbio.funcs->get_pcie_port_index_offset(adev);
- data = adev->nbio.funcs->get_pcie_port_data_offset(adev);
-
- spin_lock_irqsave(&adev->pcie_idx_lock, flags);
- WREG32(address, reg * 4);
- (void)RREG32(address);
- WREG32(data, v);
- (void)RREG32(data);
- spin_unlock_irqrestore(&adev->pcie_idx_lock, flags);
-}
-
static u32 nv_didt_rreg(struct amdgpu_device *adev, u32 reg)
{
unsigned long flags, address, data;
@@ -360,38 +331,6 @@ static bool nv_read_disabled_bios(struct amdgpu_device *adev)
return false;
}
-static bool nv_read_bios_from_rom(struct amdgpu_device *adev,
- u8 *bios, u32 length_bytes)
-{
- u32 *dw_ptr;
- u32 i, length_dw;
- u32 rom_index_offset, rom_data_offset;
-
- if (bios == NULL)
- return false;
- if (length_bytes == 0)
- return false;
- /* APU vbios image is part of sbios image */
- if (adev->flags & AMD_IS_APU)
- return false;
-
- dw_ptr = (u32 *)bios;
- length_dw = ALIGN(length_bytes, 4) / 4;
-
- rom_index_offset =
- adev->smuio.funcs->get_rom_index_offset(adev);
- rom_data_offset =
- adev->smuio.funcs->get_rom_data_offset(adev);
-
- /* set rom index to 0 */
- WREG32(rom_index_offset, 0);
- /* read out the rom data */
- for (i = 0; i < length_dw; i++)
- dw_ptr[i] = RREG32(rom_data_offset);
-
- return true;
-}
-
static struct soc15_allowed_register_entry nv_allowed_read_registers[] = {
{ SOC15_REG_ENTRY(GC, 0, mmGRBM_STATUS)},
{ SOC15_REG_ENTRY(GC, 0, mmGRBM_STATUS2)},
@@ -515,6 +454,8 @@ nv_asic_reset_method(struct amdgpu_device *adev)
case IP_VERSION(11, 5, 0):
case IP_VERSION(13, 0, 1):
case IP_VERSION(13, 0, 3):
+ case IP_VERSION(13, 0, 5):
+ case IP_VERSION(13, 0, 8):
return AMD_RESET_METHOD_MODE2;
case IP_VERSION(11, 0, 7):
case IP_VERSION(11, 0, 11):
@@ -584,7 +525,7 @@ static void nv_pcie_gen3_enable(struct amdgpu_device *adev)
static void nv_program_aspm(struct amdgpu_device *adev)
{
- if (!amdgpu_aspm)
+ if (!amdgpu_device_should_use_aspm(adev))
return;
if (!(adev->flags & AMD_IS_APU) &&
@@ -699,7 +640,8 @@ static int nv_update_umd_stable_pstate(struct amdgpu_device *adev,
adev->gfx.funcs->update_perfmon_mgcg(adev, !enter);
if (!(adev->flags & AMD_IS_APU) &&
- (adev->nbio.funcs->enable_aspm))
+ (adev->nbio.funcs->enable_aspm) &&
+ amdgpu_device_should_use_aspm(adev))
adev->nbio.funcs->enable_aspm(adev, !enter);
return 0;
@@ -708,7 +650,7 @@ static int nv_update_umd_stable_pstate(struct amdgpu_device *adev,
static const struct amdgpu_asic_funcs nv_asic_funcs =
{
.read_disabled_bios = &nv_read_disabled_bios,
- .read_bios_from_rom = &nv_read_bios_from_rom,
+ .read_bios_from_rom = &amdgpu_soc15_read_bios_from_rom,
.read_register = &nv_read_register,
.reset = &nv_asic_reset,
.reset_method = &nv_asic_reset_method,
@@ -742,8 +684,8 @@ static int nv_common_early_init(void *handle)
adev->pcie_wreg = &nv_pcie_wreg;
adev->pcie_rreg64 = &nv_pcie_rreg64;
adev->pcie_wreg64 = &nv_pcie_wreg64;
- adev->pciep_rreg = &nv_pcie_port_rreg;
- adev->pciep_wreg = &nv_pcie_port_wreg;
+ adev->pciep_rreg = amdgpu_device_pcie_port_rreg;
+ adev->pciep_wreg = amdgpu_device_pcie_port_wreg;
/* TODO: will add them during VCN v2 implementation */
adev->uvd_ctx_rreg = NULL;
@@ -964,10 +906,63 @@ static int nv_common_early_init(void *handle)
adev->external_rev_id = adev->rev_id + 0x01;
break;
case IP_VERSION(10, 1, 3):
+ case IP_VERSION(10, 1, 4):
adev->cg_flags = 0;
adev->pg_flags = 0;
adev->external_rev_id = adev->rev_id + 0x82;
break;
+ case IP_VERSION(10, 3, 6):
+ adev->cg_flags = AMD_CG_SUPPORT_GFX_MGCG |
+ AMD_CG_SUPPORT_GFX_MGLS |
+ AMD_CG_SUPPORT_GFX_CGCG |
+ AMD_CG_SUPPORT_GFX_CGLS |
+ AMD_CG_SUPPORT_GFX_3D_CGCG |
+ AMD_CG_SUPPORT_GFX_3D_CGLS |
+ AMD_CG_SUPPORT_GFX_RLC_LS |
+ AMD_CG_SUPPORT_GFX_CP_LS |
+ AMD_CG_SUPPORT_GFX_FGCG |
+ AMD_CG_SUPPORT_MC_MGCG |
+ AMD_CG_SUPPORT_MC_LS |
+ AMD_CG_SUPPORT_SDMA_LS |
+ AMD_CG_SUPPORT_HDP_MGCG |
+ AMD_CG_SUPPORT_HDP_LS |
+ AMD_CG_SUPPORT_ATHUB_MGCG |
+ AMD_CG_SUPPORT_ATHUB_LS |
+ AMD_CG_SUPPORT_IH_CG |
+ AMD_CG_SUPPORT_VCN_MGCG |
+ AMD_CG_SUPPORT_JPEG_MGCG;
+ adev->pg_flags = AMD_PG_SUPPORT_GFX_PG |
+ AMD_PG_SUPPORT_VCN |
+ AMD_PG_SUPPORT_VCN_DPG |
+ AMD_PG_SUPPORT_JPEG;
+ adev->external_rev_id = adev->rev_id + 0x01;
+ break;
+ case IP_VERSION(10, 3, 7):
+ adev->cg_flags = AMD_CG_SUPPORT_GFX_MGCG |
+ AMD_CG_SUPPORT_GFX_MGLS |
+ AMD_CG_SUPPORT_GFX_CGCG |
+ AMD_CG_SUPPORT_GFX_CGLS |
+ AMD_CG_SUPPORT_GFX_3D_CGCG |
+ AMD_CG_SUPPORT_GFX_3D_CGLS |
+ AMD_CG_SUPPORT_GFX_RLC_LS |
+ AMD_CG_SUPPORT_GFX_CP_LS |
+ AMD_CG_SUPPORT_GFX_FGCG |
+ AMD_CG_SUPPORT_MC_MGCG |
+ AMD_CG_SUPPORT_MC_LS |
+ AMD_CG_SUPPORT_SDMA_LS |
+ AMD_CG_SUPPORT_HDP_MGCG |
+ AMD_CG_SUPPORT_HDP_LS |
+ AMD_CG_SUPPORT_ATHUB_MGCG |
+ AMD_CG_SUPPORT_ATHUB_LS |
+ AMD_CG_SUPPORT_IH_CG |
+ AMD_CG_SUPPORT_VCN_MGCG |
+ AMD_CG_SUPPORT_JPEG_MGCG;
+ adev->pg_flags = AMD_PG_SUPPORT_VCN |
+ AMD_PG_SUPPORT_VCN_DPG |
+ AMD_PG_SUPPORT_JPEG |
+ AMD_PG_SUPPORT_GFX_PG;
+ adev->external_rev_id = adev->rev_id + 0x01;
+ break;
default:
/* FIXME: not supported yet */
return -EINVAL;
diff --git a/drivers/gpu/drm/amd/amdgpu/psp_gfx_if.h b/drivers/gpu/drm/amd/amdgpu/psp_gfx_if.h
index dd0dce254901..1f276ddd26e9 100644
--- a/drivers/gpu/drm/amd/amdgpu/psp_gfx_if.h
+++ b/drivers/gpu/drm/amd/amdgpu/psp_gfx_if.h
@@ -258,6 +258,7 @@ enum psp_gfx_fw_type {
GFX_FW_TYPE_SDMA6 = 56, /* SDMA6 MI */
GFX_FW_TYPE_SDMA7 = 57, /* SDMA7 MI */
GFX_FW_TYPE_VCN1 = 58, /* VCN1 MI */
+ GFX_FW_TYPE_CAP = 62, /* CAP_FW */
GFX_FW_TYPE_REG_LIST = 67, /* REG_LIST MI */
GFX_FW_TYPE_MAX
};
diff --git a/drivers/gpu/drm/amd/amdgpu/psp_v11_0.c b/drivers/gpu/drm/amd/amdgpu/psp_v11_0.c
index d0e76b36d4ab..9518b4394a6e 100644
--- a/drivers/gpu/drm/amd/amdgpu/psp_v11_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/psp_v11_0.c
@@ -53,11 +53,13 @@ MODULE_FIRMWARE("amdgpu/navi14_ta.bin");
MODULE_FIRMWARE("amdgpu/navi12_sos.bin");
MODULE_FIRMWARE("amdgpu/navi12_asd.bin");
MODULE_FIRMWARE("amdgpu/navi12_ta.bin");
+MODULE_FIRMWARE("amdgpu/navi12_cap.bin");
MODULE_FIRMWARE("amdgpu/arcturus_sos.bin");
MODULE_FIRMWARE("amdgpu/arcturus_asd.bin");
MODULE_FIRMWARE("amdgpu/arcturus_ta.bin");
MODULE_FIRMWARE("amdgpu/sienna_cichlid_sos.bin");
MODULE_FIRMWARE("amdgpu/sienna_cichlid_ta.bin");
+MODULE_FIRMWARE("amdgpu/sienna_cichlid_cap.bin");
MODULE_FIRMWARE("amdgpu/navy_flounder_sos.bin");
MODULE_FIRMWARE("amdgpu/navy_flounder_ta.bin");
MODULE_FIRMWARE("amdgpu/vangogh_asd.bin");
@@ -177,8 +179,6 @@ static int psp_v11_0_init_microcode(struct psp_context *psp)
err = psp_init_asd_microcode(psp, chip_name);
if (err)
return err;
- if (amdgpu_sriov_vf(adev))
- break;
snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_ta.bin", chip_name);
err = request_firmware(&adev->psp.ta_fw, fw_name, adev->dev);
if (err) {
diff --git a/drivers/gpu/drm/amd/amdgpu/psp_v13_0.c b/drivers/gpu/drm/amd/amdgpu/psp_v13_0.c
index 17655bc6d2f1..024f60631faf 100644
--- a/drivers/gpu/drm/amd/amdgpu/psp_v13_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/psp_v13_0.c
@@ -31,9 +31,16 @@
MODULE_FIRMWARE("amdgpu/aldebaran_sos.bin");
MODULE_FIRMWARE("amdgpu/aldebaran_ta.bin");
+MODULE_FIRMWARE("amdgpu/aldebaran_cap.bin");
MODULE_FIRMWARE("amdgpu/yellow_carp_asd.bin");
MODULE_FIRMWARE("amdgpu/yellow_carp_toc.bin");
MODULE_FIRMWARE("amdgpu/yellow_carp_ta.bin");
+MODULE_FIRMWARE("amdgpu/psp_13_0_5_asd.bin");
+MODULE_FIRMWARE("amdgpu/psp_13_0_5_toc.bin");
+MODULE_FIRMWARE("amdgpu/psp_13_0_5_ta.bin");
+MODULE_FIRMWARE("amdgpu/psp_13_0_8_asd.bin");
+MODULE_FIRMWARE("amdgpu/psp_13_0_8_toc.bin");
+MODULE_FIRMWARE("amdgpu/psp_13_0_8_ta.bin");
/* For large FW files the time to complete can be very long */
#define USBC_PD_POLLING_LIMIT_S 240
@@ -55,6 +62,12 @@ static int psp_v13_0_init_microcode(struct psp_context *psp)
case IP_VERSION(13, 0, 3):
chip_name = "yellow_carp";
break;
+ case IP_VERSION(13, 0, 5):
+ chip_name = "psp_13_0_5";
+ break;
+ case IP_VERSION(13, 0, 8):
+ chip_name = "psp_13_0_8";
+ break;
default:
BUG();
}
@@ -69,6 +82,8 @@ static int psp_v13_0_init_microcode(struct psp_context *psp)
break;
case IP_VERSION(13, 0, 1):
case IP_VERSION(13, 0, 3):
+ case IP_VERSION(13, 0, 5):
+ case IP_VERSION(13, 0, 8):
err = psp_init_asd_microcode(psp, chip_name);
if (err)
return err;
diff --git a/drivers/gpu/drm/amd/amdgpu/psp_v3_1.c b/drivers/gpu/drm/amd/amdgpu/psp_v3_1.c
index 1ed357cb0f49..01f3bcc62a6c 100644
--- a/drivers/gpu/drm/amd/amdgpu/psp_v3_1.c
+++ b/drivers/gpu/drm/amd/amdgpu/psp_v3_1.c
@@ -44,6 +44,7 @@
MODULE_FIRMWARE("amdgpu/vega10_sos.bin");
MODULE_FIRMWARE("amdgpu/vega10_asd.bin");
+MODULE_FIRMWARE("amdgpu/vega10_cap.bin");
MODULE_FIRMWARE("amdgpu/vega12_sos.bin");
MODULE_FIRMWARE("amdgpu/vega12_asd.bin");
diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c b/drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c
index 4509bd4cce2d..1d8bbcbd7a37 100644
--- a/drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c
+++ b/drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c
@@ -1142,6 +1142,7 @@ static const struct amdgpu_ring_funcs sdma_v2_4_ring_funcs = {
.align_mask = 0xf,
.nop = SDMA_PKT_NOP_HEADER_OP(SDMA_OP_NOP),
.support_64bit_ptrs = false,
+ .secure_submission_supported = true,
.get_rptr = sdma_v2_4_ring_get_rptr,
.get_wptr = sdma_v2_4_ring_get_wptr,
.set_wptr = sdma_v2_4_ring_set_wptr,
diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c
index 135727b59c41..4ef4feff5649 100644
--- a/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c
@@ -1580,6 +1580,7 @@ static const struct amdgpu_ring_funcs sdma_v3_0_ring_funcs = {
.align_mask = 0xf,
.nop = SDMA_PKT_NOP_HEADER_OP(SDMA_OP_NOP),
.support_64bit_ptrs = false,
+ .secure_submission_supported = true,
.get_rptr = sdma_v3_0_ring_get_rptr,
.get_wptr = sdma_v3_0_ring_get_wptr,
.set_wptr = sdma_v3_0_ring_set_wptr,
diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c
index e8e4749e9c79..d7e8f7232364 100644
--- a/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c
@@ -1885,22 +1885,16 @@ static int sdma_v4_0_process_ras_data_cb(struct amdgpu_device *adev,
static int sdma_v4_0_late_init(void *handle)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
- struct ras_ih_if ih_info = {
- .cb = sdma_v4_0_process_ras_data_cb,
- };
sdma_v4_0_setup_ulv(adev);
if (!amdgpu_persistent_edc_harvesting_supported(adev)) {
- if (adev->sdma.funcs &&
- adev->sdma.funcs->reset_ras_error_count)
- adev->sdma.funcs->reset_ras_error_count(adev);
+ if (adev->sdma.ras && adev->sdma.ras->ras_block.hw_ops &&
+ adev->sdma.ras->ras_block.hw_ops->reset_ras_error_count)
+ adev->sdma.ras->ras_block.hw_ops->reset_ras_error_count(adev);
}
- if (adev->sdma.funcs && adev->sdma.funcs->ras_late_init)
- return adev->sdma.funcs->ras_late_init(adev, &ih_info);
- else
- return 0;
+ return 0;
}
static int sdma_v4_0_sw_init(void *handle)
@@ -2001,9 +1995,6 @@ static int sdma_v4_0_sw_fini(void *handle)
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
int i;
- if (adev->sdma.funcs && adev->sdma.funcs->ras_fini)
- adev->sdma.funcs->ras_fini(adev);
-
for (i = 0; i < adev->sdma.num_instances; i++) {
amdgpu_ring_fini(&adev->sdma.instance[i].ring);
if (adev->sdma.has_page_queue)
@@ -2057,6 +2048,10 @@ static int sdma_v4_0_suspend(void *handle)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
+ /* SMU saves SDMA state for us */
+ if (adev->in_s0ix)
+ return 0;
+
return sdma_v4_0_hw_fini(adev);
}
@@ -2064,6 +2059,10 @@ static int sdma_v4_0_resume(void *handle)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
+ /* SMU restores SDMA state for us */
+ if (adev->in_s0ix)
+ return 0;
+
return sdma_v4_0_hw_init(adev);
}
@@ -2415,6 +2414,7 @@ static const struct amdgpu_ring_funcs sdma_v4_0_ring_funcs = {
.align_mask = 0xf,
.nop = SDMA_PKT_NOP_HEADER_OP(SDMA_OP_NOP),
.support_64bit_ptrs = true,
+ .secure_submission_supported = true,
.vmhub = AMDGPU_MMHUB_0,
.get_rptr = sdma_v4_0_ring_get_rptr,
.get_wptr = sdma_v4_0_ring_get_wptr,
@@ -2451,6 +2451,7 @@ static const struct amdgpu_ring_funcs sdma_v4_0_ring_funcs_2nd_mmhub = {
.align_mask = 0xf,
.nop = SDMA_PKT_NOP_HEADER_OP(SDMA_OP_NOP),
.support_64bit_ptrs = true,
+ .secure_submission_supported = true,
.vmhub = AMDGPU_MMHUB_1,
.get_rptr = sdma_v4_0_ring_get_rptr,
.get_wptr = sdma_v4_0_ring_get_wptr,
@@ -2483,6 +2484,7 @@ static const struct amdgpu_ring_funcs sdma_v4_0_page_ring_funcs = {
.align_mask = 0xf,
.nop = SDMA_PKT_NOP_HEADER_OP(SDMA_OP_NOP),
.support_64bit_ptrs = true,
+ .secure_submission_supported = true,
.vmhub = AMDGPU_MMHUB_0,
.get_rptr = sdma_v4_0_ring_get_rptr,
.get_wptr = sdma_v4_0_page_ring_get_wptr,
@@ -2515,6 +2517,7 @@ static const struct amdgpu_ring_funcs sdma_v4_0_page_ring_funcs_2nd_mmhub = {
.align_mask = 0xf,
.nop = SDMA_PKT_NOP_HEADER_OP(SDMA_OP_NOP),
.support_64bit_ptrs = true,
+ .secure_submission_supported = true,
.vmhub = AMDGPU_MMHUB_1,
.get_rptr = sdma_v4_0_ring_get_rptr,
.get_wptr = sdma_v4_0_page_ring_get_wptr,
@@ -2740,7 +2743,7 @@ static void sdma_v4_0_get_ras_error_count(uint32_t value,
}
}
-static int sdma_v4_0_query_ras_error_count(struct amdgpu_device *adev,
+static int sdma_v4_0_query_ras_error_count_by_instance(struct amdgpu_device *adev,
uint32_t instance, void *ras_error_status)
{
struct ras_err_data *err_data = (struct ras_err_data *)ras_error_status;
@@ -2762,6 +2765,18 @@ static int sdma_v4_0_query_ras_error_count(struct amdgpu_device *adev,
return 0;
};
+static void sdma_v4_0_query_ras_error_count(struct amdgpu_device *adev, void *ras_error_status)
+{
+ int i = 0;
+
+ for (i = 0; i < adev->sdma.num_instances; i++) {
+ if (sdma_v4_0_query_ras_error_count_by_instance(adev, i, ras_error_status)) {
+ dev_err(adev->dev, "Query ras error count failed in SDMA%d\n", i);
+ return;
+ }
+ }
+}
+
static void sdma_v4_0_reset_ras_error_count(struct amdgpu_device *adev)
{
int i;
@@ -2773,26 +2788,48 @@ static void sdma_v4_0_reset_ras_error_count(struct amdgpu_device *adev)
}
}
-static const struct amdgpu_sdma_ras_funcs sdma_v4_0_ras_funcs = {
- .ras_late_init = amdgpu_sdma_ras_late_init,
- .ras_fini = amdgpu_sdma_ras_fini,
+const struct amdgpu_ras_block_hw_ops sdma_v4_0_ras_hw_ops = {
.query_ras_error_count = sdma_v4_0_query_ras_error_count,
.reset_ras_error_count = sdma_v4_0_reset_ras_error_count,
};
+static struct amdgpu_sdma_ras sdma_v4_0_ras = {
+ .ras_block = {
+ .hw_ops = &sdma_v4_0_ras_hw_ops,
+ .ras_cb = sdma_v4_0_process_ras_data_cb,
+ },
+};
+
static void sdma_v4_0_set_ras_funcs(struct amdgpu_device *adev)
{
switch (adev->ip_versions[SDMA0_HWIP][0]) {
case IP_VERSION(4, 2, 0):
case IP_VERSION(4, 2, 2):
- adev->sdma.funcs = &sdma_v4_0_ras_funcs;
+ adev->sdma.ras = &sdma_v4_0_ras;
break;
case IP_VERSION(4, 4, 0):
- adev->sdma.funcs = &sdma_v4_4_ras_funcs;
+ adev->sdma.ras = &sdma_v4_4_ras;
break;
default:
break;
}
+
+ if (adev->sdma.ras) {
+ amdgpu_ras_register_ras_block(adev, &adev->sdma.ras->ras_block);
+
+ strcpy(adev->sdma.ras->ras_block.ras_comm.name, "sdma");
+ adev->sdma.ras->ras_block.ras_comm.block = AMDGPU_RAS_BLOCK__SDMA;
+ adev->sdma.ras->ras_block.ras_comm.type = AMDGPU_RAS_ERROR__MULTI_UNCORRECTABLE;
+ adev->sdma.ras_if = &adev->sdma.ras->ras_block.ras_comm;
+
+ /* If don't define special ras_late_init function, use default ras_late_init */
+ if (!adev->sdma.ras->ras_block.ras_late_init)
+ adev->sdma.ras->ras_block.ras_late_init = amdgpu_sdma_ras_late_init;
+
+ /* If not defined special ras_cb function, use default ras_cb */
+ if (!adev->sdma.ras->ras_block.ras_cb)
+ adev->sdma.ras->ras_block.ras_cb = amdgpu_sdma_process_ras_data_cb;
+ }
}
const struct amdgpu_ip_block_version sdma_v4_0_ip_block = {
diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v4_4.c b/drivers/gpu/drm/amd/amdgpu/sdma_v4_4.c
index bf95007f0843..6f9895cdddb1 100644
--- a/drivers/gpu/drm/amd/amdgpu/sdma_v4_4.c
+++ b/drivers/gpu/drm/amd/amdgpu/sdma_v4_4.c
@@ -188,7 +188,7 @@ static void sdma_v4_4_get_ras_error_count(struct amdgpu_device *adev,
}
}
-static int sdma_v4_4_query_ras_error_count(struct amdgpu_device *adev,
+static int sdma_v4_4_query_ras_error_count_by_instance(struct amdgpu_device *adev,
uint32_t instance,
void *ras_error_status)
{
@@ -245,9 +245,26 @@ static void sdma_v4_4_reset_ras_error_count(struct amdgpu_device *adev)
}
}
-const struct amdgpu_sdma_ras_funcs sdma_v4_4_ras_funcs = {
- .ras_late_init = amdgpu_sdma_ras_late_init,
- .ras_fini = amdgpu_sdma_ras_fini,
+static void sdma_v4_4_query_ras_error_count(struct amdgpu_device *adev, void *ras_error_status)
+{
+ int i = 0;
+
+ for (i = 0; i < adev->sdma.num_instances; i++) {
+ if (sdma_v4_4_query_ras_error_count_by_instance(adev, i, ras_error_status)) {
+ dev_err(adev->dev, "Query ras error count failed in SDMA%d\n", i);
+ return;
+ }
+ }
+
+}
+
+const struct amdgpu_ras_block_hw_ops sdma_v4_4_ras_hw_ops = {
.query_ras_error_count = sdma_v4_4_query_ras_error_count,
.reset_ras_error_count = sdma_v4_4_reset_ras_error_count,
};
+
+struct amdgpu_sdma_ras sdma_v4_4_ras = {
+ .ras_block = {
+ .hw_ops = &sdma_v4_4_ras_hw_ops,
+ },
+};
diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v4_4.h b/drivers/gpu/drm/amd/amdgpu/sdma_v4_4.h
index 74a6e5b5e949..a9f0c68359e0 100644
--- a/drivers/gpu/drm/amd/amdgpu/sdma_v4_4.h
+++ b/drivers/gpu/drm/amd/amdgpu/sdma_v4_4.h
@@ -23,6 +23,6 @@
#ifndef __SDMA_V4_4_H__
#define __SDMA_V4_4_H__
-extern const struct amdgpu_sdma_ras_funcs sdma_v4_4_ras_funcs;
+extern struct amdgpu_sdma_ras sdma_v4_4_ras;
#endif
diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c
index 81e033549dda..a8d49c005f73 100644
--- a/drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c
@@ -51,9 +51,6 @@ MODULE_FIRMWARE("amdgpu/navi14_sdma1.bin");
MODULE_FIRMWARE("amdgpu/navi12_sdma.bin");
MODULE_FIRMWARE("amdgpu/navi12_sdma1.bin");
-MODULE_FIRMWARE("amdgpu/cyan_skillfish_sdma.bin");
-MODULE_FIRMWARE("amdgpu/cyan_skillfish_sdma1.bin");
-
MODULE_FIRMWARE("amdgpu/cyan_skillfish2_sdma.bin");
MODULE_FIRMWARE("amdgpu/cyan_skillfish2_sdma1.bin");
@@ -264,10 +261,7 @@ static int sdma_v5_0_init_microcode(struct amdgpu_device *adev)
chip_name = "navi12";
break;
case IP_VERSION(5, 0, 1):
- if (adev->apu_flags & AMD_APU_IS_CYAN_SKILLFISH2)
- chip_name = "cyan_skillfish2";
- else
- chip_name = "cyan_skillfish";
+ chip_name = "cyan_skillfish2";
break;
default:
BUG();
@@ -1696,6 +1690,7 @@ static const struct amdgpu_ring_funcs sdma_v5_0_ring_funcs = {
.align_mask = 0xf,
.nop = SDMA_PKT_NOP_HEADER_OP(SDMA_OP_NOP),
.support_64bit_ptrs = true,
+ .secure_submission_supported = true,
.vmhub = AMDGPU_GFXHUB_0,
.get_rptr = sdma_v5_0_ring_get_rptr,
.get_wptr = sdma_v5_0_ring_get_wptr,
diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c b/drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c
index d3d6d5b045b8..824eace69884 100644
--- a/drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c
+++ b/drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c
@@ -51,6 +51,8 @@ MODULE_FIRMWARE("amdgpu/beige_goby_sdma.bin");
MODULE_FIRMWARE("amdgpu/vangogh_sdma.bin");
MODULE_FIRMWARE("amdgpu/yellow_carp_sdma.bin");
+MODULE_FIRMWARE("amdgpu/sdma_5_2_6.bin");
+MODULE_FIRMWARE("amdgpu/sdma_5_2_7.bin");
#define SDMA1_REG_OFFSET 0x600
#define SDMA3_REG_OFFSET 0x400
@@ -138,28 +140,34 @@ static int sdma_v5_2_init_microcode(struct amdgpu_device *adev)
switch (adev->ip_versions[SDMA0_HWIP][0]) {
case IP_VERSION(5, 2, 0):
- chip_name = "sienna_cichlid";
+ chip_name = "sienna_cichlid_sdma";
break;
case IP_VERSION(5, 2, 2):
- chip_name = "navy_flounder";
+ chip_name = "navy_flounder_sdma";
break;
case IP_VERSION(5, 2, 1):
- chip_name = "vangogh";
+ chip_name = "vangogh_sdma";
break;
case IP_VERSION(5, 2, 4):
- chip_name = "dimgrey_cavefish";
+ chip_name = "dimgrey_cavefish_sdma";
break;
case IP_VERSION(5, 2, 5):
- chip_name = "beige_goby";
+ chip_name = "beige_goby_sdma";
break;
case IP_VERSION(5, 2, 3):
- chip_name = "yellow_carp";
+ chip_name = "yellow_carp_sdma";
+ break;
+ case IP_VERSION(5, 2, 6):
+ chip_name = "sdma_5_2_6";
+ break;
+ case IP_VERSION(5, 2, 7):
+ chip_name = "sdma_5_2_7";
break;
default:
BUG();
}
- snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_sdma.bin", chip_name);
+ snprintf(fw_name, sizeof(fw_name), "amdgpu/%s.bin", chip_name);
err = request_firmware(&adev->sdma.instance[0].fw, fw_name, adev->dev);
if (err)
@@ -1617,6 +1625,7 @@ static int sdma_v5_2_set_clockgating_state(void *handle,
case IP_VERSION(5, 2, 1):
case IP_VERSION(5, 2, 4):
case IP_VERSION(5, 2, 5):
+ case IP_VERSION(5, 2, 6):
case IP_VERSION(5, 2, 3):
sdma_v5_2_update_medium_grain_clock_gating(adev,
state == AMD_CG_STATE_GATE);
@@ -1644,6 +1653,11 @@ static void sdma_v5_2_get_clockgating_state(void *handle, u32 *flags)
if (amdgpu_sriov_vf(adev))
*flags = 0;
+ /* AMD_CG_SUPPORT_SDMA_MGCG */
+ data = RREG32(sdma_v5_2_get_reg_offset(adev, 0, mmSDMA0_CLK_CTRL));
+ if (!(data & SDMA0_CLK_CTRL__CGCG_EN_OVERRIDE_MASK))
+ *flags |= AMD_CG_SUPPORT_SDMA_MGCG;
+
/* AMD_CG_SUPPORT_SDMA_LS */
data = RREG32_KIQ(sdma_v5_2_get_reg_offset(adev, 0, mmSDMA0_POWER_CNTL));
if (data & SDMA0_POWER_CNTL__MEM_POWER_OVERRIDE_MASK)
@@ -1673,6 +1687,7 @@ static const struct amdgpu_ring_funcs sdma_v5_2_ring_funcs = {
.align_mask = 0xf,
.nop = SDMA_PKT_NOP_HEADER_OP(SDMA_OP_NOP),
.support_64bit_ptrs = true,
+ .secure_submission_supported = true,
.vmhub = AMDGPU_GFXHUB_0,
.get_rptr = sdma_v5_2_ring_get_rptr,
.get_wptr = sdma_v5_2_ring_get_wptr,
diff --git a/drivers/gpu/drm/amd/amdgpu/si.c b/drivers/gpu/drm/amd/amdgpu/si.c
index e6d2f74a7976..7f99e130acd0 100644
--- a/drivers/gpu/drm/amd/amdgpu/si.c
+++ b/drivers/gpu/drm/amd/amdgpu/si.c
@@ -2453,7 +2453,7 @@ static void si_program_aspm(struct amdgpu_device *adev)
bool disable_l0s = false, disable_l1 = false, disable_plloff_in_l1 = false;
bool disable_clkreq = false;
- if (amdgpu_aspm == 0)
+ if (!amdgpu_device_should_use_aspm(adev))
return;
if (adev->flags & AMD_IS_APU)
diff --git a/drivers/gpu/drm/amd/amdgpu/smu_v11_0_i2c.c b/drivers/gpu/drm/amd/amdgpu/smu_v11_0_i2c.c
index 73ffa8fde3df..dd2d66090d23 100644
--- a/drivers/gpu/drm/amd/amdgpu/smu_v11_0_i2c.c
+++ b/drivers/gpu/drm/amd/amdgpu/smu_v11_0_i2c.c
@@ -26,6 +26,7 @@
#include "smu_v11_0_i2c.h"
#include "amdgpu.h"
+#include "amdgpu_dpm.h"
#include "soc15_common.h"
#include <drm/drm_fixed.h>
#include <drm/drm_drv.h>
@@ -43,11 +44,10 @@
#define I2C_X_RESTART BIT(31)
-#define to_amdgpu_device(x) (container_of(x, struct amdgpu_device, pm.smu_i2c))
-
static void smu_v11_0_i2c_set_clock_gating(struct i2c_adapter *control, bool en)
{
- struct amdgpu_device *adev = to_amdgpu_device(control);
+ struct amdgpu_smu_i2c_bus *smu_i2c = i2c_get_adapdata(control);
+ struct amdgpu_device *adev = smu_i2c->adev;
uint32_t reg = RREG32_SOC15(SMUIO, 0, mmSMUIO_PWRMGT);
reg = REG_SET_FIELD(reg, SMUIO_PWRMGT, i2c_clk_gate_en, en ? 1 : 0);
@@ -75,7 +75,8 @@ static void smu_v11_0_i2c_set_clock_gating(struct i2c_adapter *control, bool en)
static int smu_v11_0_i2c_enable(struct i2c_adapter *control, bool enable)
{
- struct amdgpu_device *adev = to_amdgpu_device(control);
+ struct amdgpu_smu_i2c_bus *smu_i2c = i2c_get_adapdata(control);
+ struct amdgpu_device *adev = smu_i2c->adev;
WREG32_SOC15(SMUIO, 0, mmCKSVII2C_IC_ENABLE, enable ? 1 : 0);
@@ -100,7 +101,8 @@ static int smu_v11_0_i2c_enable(struct i2c_adapter *control, bool enable)
static void smu_v11_0_i2c_clear_status(struct i2c_adapter *control)
{
- struct amdgpu_device *adev = to_amdgpu_device(control);
+ struct amdgpu_smu_i2c_bus *smu_i2c = i2c_get_adapdata(control);
+ struct amdgpu_device *adev = smu_i2c->adev;
/* do */
{
RREG32_SOC15(SMUIO, 0, mmCKSVII2C_IC_CLR_INTR);
@@ -110,7 +112,8 @@ static void smu_v11_0_i2c_clear_status(struct i2c_adapter *control)
static void smu_v11_0_i2c_configure(struct i2c_adapter *control)
{
- struct amdgpu_device *adev = to_amdgpu_device(control);
+ struct amdgpu_smu_i2c_bus *smu_i2c = i2c_get_adapdata(control);
+ struct amdgpu_device *adev = smu_i2c->adev;
uint32_t reg = 0;
reg = REG_SET_FIELD(reg, CKSVII2C_IC_CON, IC_SLAVE_DISABLE, 1);
@@ -131,7 +134,8 @@ static void smu_v11_0_i2c_configure(struct i2c_adapter *control)
static void smu_v11_0_i2c_set_clock(struct i2c_adapter *control)
{
- struct amdgpu_device *adev = to_amdgpu_device(control);
+ struct amdgpu_smu_i2c_bus *smu_i2c = i2c_get_adapdata(control);
+ struct amdgpu_device *adev = smu_i2c->adev;
/*
* Standard mode speed, These values are taken from SMUIO MAS,
@@ -154,7 +158,8 @@ static void smu_v11_0_i2c_set_clock(struct i2c_adapter *control)
static void smu_v11_0_i2c_set_address(struct i2c_adapter *control, u16 address)
{
- struct amdgpu_device *adev = to_amdgpu_device(control);
+ struct amdgpu_smu_i2c_bus *smu_i2c = i2c_get_adapdata(control);
+ struct amdgpu_device *adev = smu_i2c->adev;
/* The IC_TAR::IC_TAR field is 10-bits wide.
* It takes a 7-bit or 10-bit addresses as an address,
@@ -165,7 +170,8 @@ static void smu_v11_0_i2c_set_address(struct i2c_adapter *control, u16 address)
static uint32_t smu_v11_0_i2c_poll_tx_status(struct i2c_adapter *control)
{
- struct amdgpu_device *adev = to_amdgpu_device(control);
+ struct amdgpu_smu_i2c_bus *smu_i2c = i2c_get_adapdata(control);
+ struct amdgpu_device *adev = smu_i2c->adev;
uint32_t ret = I2C_OK;
uint32_t reg, reg_c_tx_abrt_source;
@@ -216,7 +222,8 @@ static uint32_t smu_v11_0_i2c_poll_tx_status(struct i2c_adapter *control)
static uint32_t smu_v11_0_i2c_poll_rx_status(struct i2c_adapter *control)
{
- struct amdgpu_device *adev = to_amdgpu_device(control);
+ struct amdgpu_smu_i2c_bus *smu_i2c = i2c_get_adapdata(control);
+ struct amdgpu_device *adev = smu_i2c->adev;
uint32_t ret = I2C_OK;
uint32_t reg_ic_status, reg_c_tx_abrt_source;
@@ -262,7 +269,8 @@ static uint32_t smu_v11_0_i2c_transmit(struct i2c_adapter *control,
u16 address, u8 *data,
u32 numbytes, u32 i2c_flag)
{
- struct amdgpu_device *adev = to_amdgpu_device(control);
+ struct amdgpu_smu_i2c_bus *smu_i2c = i2c_get_adapdata(control);
+ struct amdgpu_device *adev = smu_i2c->adev;
u32 bytes_sent, reg, ret = I2C_OK;
unsigned long timeout_counter;
@@ -360,7 +368,8 @@ static uint32_t smu_v11_0_i2c_receive(struct i2c_adapter *control,
u16 address, u8 *data,
u32 numbytes, u32 i2c_flag)
{
- struct amdgpu_device *adev = to_amdgpu_device(control);
+ struct amdgpu_smu_i2c_bus *smu_i2c = i2c_get_adapdata(control);
+ struct amdgpu_device *adev = smu_i2c->adev;
uint32_t bytes_received, ret = I2C_OK;
bytes_received = 0;
@@ -431,7 +440,8 @@ static uint32_t smu_v11_0_i2c_receive(struct i2c_adapter *control,
static void smu_v11_0_i2c_abort(struct i2c_adapter *control)
{
- struct amdgpu_device *adev = to_amdgpu_device(control);
+ struct amdgpu_smu_i2c_bus *smu_i2c = i2c_get_adapdata(control);
+ struct amdgpu_device *adev = smu_i2c->adev;
uint32_t reg = 0;
/* Enable I2C engine; */
@@ -447,7 +457,8 @@ static void smu_v11_0_i2c_abort(struct i2c_adapter *control)
static bool smu_v11_0_i2c_activity_done(struct i2c_adapter *control)
{
- struct amdgpu_device *adev = to_amdgpu_device(control);
+ struct amdgpu_smu_i2c_bus *smu_i2c = i2c_get_adapdata(control);
+ struct amdgpu_device *adev = smu_i2c->adev;
const uint32_t IDLE_TIMEOUT = 1024;
uint32_t timeout_count = 0;
@@ -508,7 +519,8 @@ static void smu_v11_0_i2c_init(struct i2c_adapter *control)
static void smu_v11_0_i2c_fini(struct i2c_adapter *control)
{
- struct amdgpu_device *adev = to_amdgpu_device(control);
+ struct amdgpu_smu_i2c_bus *smu_i2c = i2c_get_adapdata(control);
+ struct amdgpu_device *adev = smu_i2c->adev;
u32 status, enable, en_stat;
int res;
@@ -543,7 +555,8 @@ static void smu_v11_0_i2c_fini(struct i2c_adapter *control)
static bool smu_v11_0_i2c_bus_lock(struct i2c_adapter *control)
{
- struct amdgpu_device *adev = to_amdgpu_device(control);
+ struct amdgpu_smu_i2c_bus *smu_i2c = i2c_get_adapdata(control);
+ struct amdgpu_device *adev = smu_i2c->adev;
/* Send PPSMC_MSG_RequestI2CBus */
if (!amdgpu_dpm_smu_i2c_bus_access(adev, true))
@@ -554,7 +567,8 @@ static bool smu_v11_0_i2c_bus_lock(struct i2c_adapter *control)
static bool smu_v11_0_i2c_bus_unlock(struct i2c_adapter *control)
{
- struct amdgpu_device *adev = to_amdgpu_device(control);
+ struct amdgpu_smu_i2c_bus *smu_i2c = i2c_get_adapdata(control);
+ struct amdgpu_device *adev = smu_i2c->adev;
/* Send PPSMC_MSG_ReleaseI2CBus */
if (!amdgpu_dpm_smu_i2c_bus_access(adev, false))
@@ -587,16 +601,17 @@ static uint32_t smu_v11_0_i2c_write_data(struct i2c_adapter *control,
if (ret != I2C_OK)
DRM_ERROR("WriteI2CData() - I2C error occurred :%x", ret);
-
+
return ret;
}
static void lock_bus(struct i2c_adapter *i2c, unsigned int flags)
{
- struct amdgpu_device *adev = to_amdgpu_device(i2c);
+ struct amdgpu_smu_i2c_bus *smu_i2c = i2c_get_adapdata(i2c);
+ struct amdgpu_device *adev = smu_i2c->adev;
- mutex_lock(&adev->pm.smu_i2c_mutex);
+ mutex_lock(&smu_i2c->mutex);
if (!smu_v11_0_i2c_bus_lock(i2c))
DRM_ERROR("Failed to lock the bus from SMU");
else
@@ -611,13 +626,14 @@ static int trylock_bus(struct i2c_adapter *i2c, unsigned int flags)
static void unlock_bus(struct i2c_adapter *i2c, unsigned int flags)
{
- struct amdgpu_device *adev = to_amdgpu_device(i2c);
+ struct amdgpu_smu_i2c_bus *smu_i2c = i2c_get_adapdata(i2c);
+ struct amdgpu_device *adev = smu_i2c->adev;
if (!smu_v11_0_i2c_bus_unlock(i2c))
DRM_ERROR("Failed to unlock the bus from SMU");
else
adev->pm.bus_locked = false;
- mutex_unlock(&adev->pm.smu_i2c_mutex);
+ mutex_unlock(&smu_i2c->mutex);
}
static const struct i2c_lock_operations smu_v11_0_i2c_i2c_lock_ops = {
@@ -706,19 +722,26 @@ static const struct i2c_adapter_quirks smu_v11_0_i2c_control_quirks = {
.flags = I2C_AQ_NO_ZERO_LEN,
};
-int smu_v11_0_i2c_control_init(struct i2c_adapter *control)
+int smu_v11_0_i2c_control_init(struct amdgpu_device *adev)
{
- struct amdgpu_device *adev = to_amdgpu_device(control);
+ struct amdgpu_smu_i2c_bus *smu_i2c = &adev->pm.smu_i2c[0];
+ struct i2c_adapter *control = &smu_i2c->adapter;
int res;
- mutex_init(&adev->pm.smu_i2c_mutex);
+ smu_i2c->adev = adev;
+ smu_i2c->port = 0;
+ mutex_init(&smu_i2c->mutex);
control->owner = THIS_MODULE;
control->class = I2C_CLASS_HWMON;
control->dev.parent = &adev->pdev->dev;
control->algo = &smu_v11_0_i2c_algo;
- snprintf(control->name, sizeof(control->name), "AMDGPU SMU");
+ snprintf(control->name, sizeof(control->name), "AMDGPU SMU 0");
control->lock_ops = &smu_v11_0_i2c_i2c_lock_ops;
control->quirks = &smu_v11_0_i2c_control_quirks;
+ i2c_set_adapdata(control, smu_i2c);
+
+ adev->pm.ras_eeprom_i2c_bus = &adev->pm.smu_i2c[0].adapter;
+ adev->pm.fru_eeprom_i2c_bus = &adev->pm.smu_i2c[0].adapter;
res = i2c_add_adapter(control);
if (res)
@@ -727,9 +750,13 @@ int smu_v11_0_i2c_control_init(struct i2c_adapter *control)
return res;
}
-void smu_v11_0_i2c_control_fini(struct i2c_adapter *control)
+void smu_v11_0_i2c_control_fini(struct amdgpu_device *adev)
{
+ struct i2c_adapter *control = adev->pm.ras_eeprom_i2c_bus;
+
i2c_del_adapter(control);
+ adev->pm.ras_eeprom_i2c_bus = NULL;
+ adev->pm.fru_eeprom_i2c_bus = NULL;
}
/*
diff --git a/drivers/gpu/drm/amd/amdgpu/smu_v11_0_i2c.h b/drivers/gpu/drm/amd/amdgpu/smu_v11_0_i2c.h
index 44467c05f642..96ad14288a0c 100644
--- a/drivers/gpu/drm/amd/amdgpu/smu_v11_0_i2c.h
+++ b/drivers/gpu/drm/amd/amdgpu/smu_v11_0_i2c.h
@@ -26,9 +26,9 @@
#include <linux/types.h>
-struct i2c_adapter;
+struct amdgpu_device;
-int smu_v11_0_i2c_control_init(struct i2c_adapter *control);
-void smu_v11_0_i2c_control_fini(struct i2c_adapter *control);
+int smu_v11_0_i2c_control_init(struct amdgpu_device *adev);
+void smu_v11_0_i2c_control_fini(struct amdgpu_device *adev);
#endif
diff --git a/drivers/gpu/drm/amd/amdgpu/soc15.c b/drivers/gpu/drm/amd/amdgpu/soc15.c
index 0fc1747e4a70..3d0251ef8d79 100644
--- a/drivers/gpu/drm/amd/amdgpu/soc15.c
+++ b/drivers/gpu/drm/amd/amdgpu/soc15.c
@@ -375,39 +375,6 @@ static bool soc15_read_disabled_bios(struct amdgpu_device *adev)
return false;
}
-static bool soc15_read_bios_from_rom(struct amdgpu_device *adev,
- u8 *bios, u32 length_bytes)
-{
- u32 *dw_ptr;
- u32 i, length_dw;
- uint32_t rom_index_offset;
- uint32_t rom_data_offset;
-
- if (bios == NULL)
- return false;
- if (length_bytes == 0)
- return false;
- /* APU vbios image is part of sbios image */
- if (adev->flags & AMD_IS_APU)
- return false;
-
- dw_ptr = (u32 *)bios;
- length_dw = ALIGN(length_bytes, 4) / 4;
-
- rom_index_offset =
- adev->smuio.funcs->get_rom_index_offset(adev);
- rom_data_offset =
- adev->smuio.funcs->get_rom_data_offset(adev);
-
- /* set rom index to 0 */
- WREG32(rom_index_offset, 0);
- /* read out the rom data */
- for (i = 0; i < length_dw; i++)
- dw_ptr[i] = RREG32(rom_data_offset);
-
- return true;
-}
-
static struct soc15_allowed_register_entry soc15_allowed_read_registers[] = {
{ SOC15_REG_ENTRY(GC, 0, mmGRBM_STATUS)},
{ SOC15_REG_ENTRY(GC, 0, mmGRBM_STATUS2)},
@@ -619,8 +586,8 @@ soc15_asic_reset_method(struct amdgpu_device *adev)
static int soc15_asic_reset(struct amdgpu_device *adev)
{
/* original raven doesn't have full asic reset */
- if ((adev->apu_flags & AMD_APU_IS_RAVEN) &&
- !(adev->apu_flags & AMD_APU_IS_RAVEN2))
+ if ((adev->apu_flags & AMD_APU_IS_RAVEN) ||
+ (adev->apu_flags & AMD_APU_IS_RAVEN2))
return 0;
switch (soc15_asic_reset_method(adev)) {
@@ -703,7 +670,7 @@ static void soc15_pcie_gen3_enable(struct amdgpu_device *adev)
static void soc15_program_aspm(struct amdgpu_device *adev)
{
- if (!amdgpu_aspm)
+ if (!amdgpu_device_should_use_aspm(adev))
return;
if (!(adev->flags & AMD_IS_APU) &&
@@ -886,6 +853,10 @@ static bool soc15_need_reset_on_init(struct amdgpu_device *adev)
{
u32 sol_reg;
+ /* CP hangs in IGT reloading test on RN, reset to WA */
+ if (adev->asic_type == CHIP_RENOIR)
+ return true;
+
/* Just return false for soc15 GPUs. Reset does not seem to
* be necessary.
*/
@@ -925,7 +896,7 @@ static void soc15_pre_asic_init(struct amdgpu_device *adev)
static const struct amdgpu_asic_funcs soc15_asic_funcs =
{
.read_disabled_bios = &soc15_read_disabled_bios,
- .read_bios_from_rom = &soc15_read_bios_from_rom,
+ .read_bios_from_rom = &amdgpu_soc15_read_bios_from_rom,
.read_register = &soc15_read_register,
.reset = &soc15_asic_reset,
.reset_method = &soc15_asic_reset_method,
@@ -947,7 +918,7 @@ static const struct amdgpu_asic_funcs soc15_asic_funcs =
static const struct amdgpu_asic_funcs vega20_asic_funcs =
{
.read_disabled_bios = &soc15_read_disabled_bios,
- .read_bios_from_rom = &soc15_read_bios_from_rom,
+ .read_bios_from_rom = &amdgpu_soc15_read_bios_from_rom,
.read_register = &soc15_read_register,
.reset = &soc15_asic_reset,
.reset_method = &soc15_asic_reset_method,
@@ -1114,8 +1085,11 @@ static int soc15_common_early_init(void *handle)
AMD_CG_SUPPORT_SDMA_LS |
AMD_CG_SUPPORT_VCN_MGCG;
+ /*
+ * MMHUB PG needs to be disabled for Picasso for
+ * stability reasons.
+ */
adev->pg_flags = AMD_PG_SUPPORT_SDMA |
- AMD_PG_SUPPORT_MMHUB |
AMD_PG_SUPPORT_VCN;
} else {
adev->cg_flags = AMD_CG_SUPPORT_GFX_MGCG |
@@ -1219,16 +1193,11 @@ static int soc15_common_early_init(void *handle)
static int soc15_common_late_init(void *handle)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
- int r = 0;
if (amdgpu_sriov_vf(adev))
xgpu_ai_mailbox_get_irq(adev);
- if (adev->nbio.ras_funcs &&
- adev->nbio.ras_funcs->ras_late_init)
- r = adev->nbio.ras_funcs->ras_late_init(adev);
-
- return r;
+ return 0;
}
static int soc15_common_sw_init(void *handle)
@@ -1249,10 +1218,6 @@ static int soc15_common_sw_fini(void *handle)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
- if (adev->nbio.ras_funcs &&
- adev->nbio.ras_funcs->ras_fini)
- adev->nbio.ras_funcs->ras_fini(adev);
-
if (adev->df.funcs &&
adev->df.funcs->sw_fini)
adev->df.funcs->sw_fini(adev);
@@ -1318,11 +1283,11 @@ static int soc15_common_hw_fini(void *handle)
if (adev->nbio.ras_if &&
amdgpu_ras_is_supported(adev, adev->nbio.ras_if->block)) {
- if (adev->nbio.ras_funcs &&
- adev->nbio.ras_funcs->init_ras_controller_interrupt)
+ if (adev->nbio.ras &&
+ adev->nbio.ras->init_ras_controller_interrupt)
amdgpu_irq_put(adev, &adev->nbio.ras_controller_irq, 0);
- if (adev->nbio.ras_funcs &&
- adev->nbio.ras_funcs->init_ras_err_event_athub_interrupt)
+ if (adev->nbio.ras &&
+ adev->nbio.ras->init_ras_err_event_athub_interrupt)
amdgpu_irq_put(adev, &adev->nbio.ras_err_event_athub_irq, 0);
}
diff --git a/drivers/gpu/drm/amd/amdgpu/soc15_common.h b/drivers/gpu/drm/amd/amdgpu/soc15_common.h
index 473767e03676..acce8c2e0328 100644
--- a/drivers/gpu/drm/amd/amdgpu/soc15_common.h
+++ b/drivers/gpu/drm/amd/amdgpu/soc15_common.h
@@ -28,13 +28,13 @@
#define SOC15_REG_OFFSET(ip, inst, reg) (adev->reg_offset[ip##_HWIP][inst][reg##_BASE_IDX] + reg)
#define __WREG32_SOC15_RLC__(reg, value, flag, hwip) \
- ((amdgpu_sriov_vf(adev) && adev->gfx.rlc.funcs && adev->gfx.rlc.funcs->sriov_wreg) ? \
- adev->gfx.rlc.funcs->sriov_wreg(adev, reg, value, flag, hwip) : \
+ ((amdgpu_sriov_vf(adev) && adev->gfx.rlc.funcs && adev->gfx.rlc.rlcg_reg_access_supported) ? \
+ amdgpu_sriov_wreg(adev, reg, value, flag, hwip) : \
WREG32(reg, value))
#define __RREG32_SOC15_RLC__(reg, flag, hwip) \
- ((amdgpu_sriov_vf(adev) && adev->gfx.rlc.funcs && adev->gfx.rlc.funcs->sriov_rreg) ? \
- adev->gfx.rlc.funcs->sriov_rreg(adev, reg, flag, hwip) : \
+ ((amdgpu_sriov_vf(adev) && adev->gfx.rlc.funcs && adev->gfx.rlc.rlcg_reg_access_supported) ? \
+ amdgpu_sriov_rreg(adev, reg, flag, hwip) : \
RREG32(reg))
#define WREG32_FIELD15(ip, idx, reg, field, val) \
diff --git a/drivers/gpu/drm/amd/amdgpu/ta_ras_if.h b/drivers/gpu/drm/amd/amdgpu/ta_ras_if.h
index 5093826a43d1..509d8a1945eb 100644
--- a/drivers/gpu/drm/amd/amdgpu/ta_ras_if.h
+++ b/drivers/gpu/drm/amd/amdgpu/ta_ras_if.h
@@ -64,7 +64,8 @@ enum ta_ras_status {
TA_RAS_STATUS__ERROR_PCS_STATE_ERROR = 0xA016,
TA_RAS_STATUS__ERROR_PCS_STATE_HANG = 0xA017,
TA_RAS_STATUS__ERROR_PCS_STATE_UNKNOWN = 0xA018,
- TA_RAS_STATUS__ERROR_UNSUPPORTED_ERROR_INJ = 0xA019
+ TA_RAS_STATUS__ERROR_UNSUPPORTED_ERROR_INJ = 0xA019,
+ TA_RAS_STATUS__TEE_ERROR_ACCESS_DENIED = 0xA01A
};
enum ta_ras_block {
diff --git a/drivers/gpu/drm/amd/amdgpu/umc_v6_1.c b/drivers/gpu/drm/amd/amdgpu/umc_v6_1.c
index 20b44983ac94..939cb203f7ad 100644
--- a/drivers/gpu/drm/amd/amdgpu/umc_v6_1.c
+++ b/drivers/gpu/drm/amd/amdgpu/umc_v6_1.c
@@ -300,7 +300,6 @@ static void umc_v6_1_query_error_address(struct amdgpu_device *adev,
{
uint32_t lsb, mc_umc_status_addr;
uint64_t mc_umc_status, err_addr, retired_page, mc_umc_addrt0;
- struct eeprom_table_record *err_rec;
uint32_t channel_index = adev->umc.channel_idx_tbl[umc_inst * adev->umc.channel_inst_num + ch_inst];
if (adev->asic_type == CHIP_ARCTURUS) {
@@ -328,8 +327,6 @@ static void umc_v6_1_query_error_address(struct amdgpu_device *adev,
return;
}
- err_rec = &err_data->err_addr[err_data->err_addr_cnt];
-
/* calculate error address if ue/ce error is detected */
if (REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, Val) == 1 &&
(REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, UECC) == 1 ||
@@ -348,18 +345,9 @@ static void umc_v6_1_query_error_address(struct amdgpu_device *adev,
/* we only save ue error information currently, ce is skipped */
if (REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, UECC)
- == 1) {
- err_rec->address = err_addr;
- /* page frame address is saved */
- err_rec->retired_page = retired_page >> AMDGPU_GPU_PAGE_SHIFT;
- err_rec->ts = (uint64_t)ktime_get_real_seconds();
- err_rec->err_type = AMDGPU_RAS_EEPROM_ERR_NON_RECOVERABLE;
- err_rec->cu = 0;
- err_rec->mem_channel = channel_index;
- err_rec->mcumc_id = umc_inst;
-
- err_data->err_addr_cnt++;
- }
+ == 1)
+ amdgpu_umc_fill_error_record(err_data, err_addr,
+ retired_page, channel_index, umc_inst);
}
/* clear umc status */
@@ -465,10 +453,14 @@ static void umc_v6_1_err_cnt_init(struct amdgpu_device *adev)
umc_v6_1_enable_umc_index_mode(adev);
}
-const struct amdgpu_umc_ras_funcs umc_v6_1_ras_funcs = {
- .err_cnt_init = umc_v6_1_err_cnt_init,
- .ras_late_init = amdgpu_umc_ras_late_init,
- .ras_fini = amdgpu_umc_ras_fini,
+const struct amdgpu_ras_block_hw_ops umc_v6_1_ras_hw_ops = {
.query_ras_error_count = umc_v6_1_query_ras_error_count,
.query_ras_error_address = umc_v6_1_query_ras_error_address,
};
+
+struct amdgpu_umc_ras umc_v6_1_ras = {
+ .ras_block = {
+ .hw_ops = &umc_v6_1_ras_hw_ops,
+ },
+ .err_cnt_init = umc_v6_1_err_cnt_init,
+}; \ No newline at end of file
diff --git a/drivers/gpu/drm/amd/amdgpu/umc_v6_1.h b/drivers/gpu/drm/amd/amdgpu/umc_v6_1.h
index 5dc36c730bb2..50c632eb4cc6 100644
--- a/drivers/gpu/drm/amd/amdgpu/umc_v6_1.h
+++ b/drivers/gpu/drm/amd/amdgpu/umc_v6_1.h
@@ -45,7 +45,7 @@
/* umc ce count initial value */
#define UMC_V6_1_CE_CNT_INIT (UMC_V6_1_CE_CNT_MAX - UMC_V6_1_CE_INT_THRESHOLD)
-extern const struct amdgpu_umc_ras_funcs umc_v6_1_ras_funcs;
+extern struct amdgpu_umc_ras umc_v6_1_ras;
extern const uint32_t
umc_v6_1_channel_idx_tbl[UMC_V6_1_UMC_INSTANCE_NUM][UMC_V6_1_CHANNEL_INSTANCE_NUM];
diff --git a/drivers/gpu/drm/amd/amdgpu/umc_v6_7.c b/drivers/gpu/drm/amd/amdgpu/umc_v6_7.c
index 6dd1e19e8d43..c45d9c14ecbc 100644
--- a/drivers/gpu/drm/amd/amdgpu/umc_v6_7.c
+++ b/drivers/gpu/drm/amd/amdgpu/umc_v6_7.c
@@ -47,6 +47,13 @@ static inline uint32_t get_umc_v6_7_reg_offset(struct amdgpu_device *adev,
uint32_t umc_inst,
uint32_t ch_inst)
{
+ uint32_t index = umc_inst * adev->umc.channel_inst_num + ch_inst;
+
+ /* adjust umc and channel index offset,
+ * the register address is not linear on each umc instace */
+ umc_inst = index / 4;
+ ch_inst = index % 4;
+
return adev->umc.channel_offs * ch_inst + UMC_V6_7_INST_DIST * umc_inst;
}
@@ -58,49 +65,74 @@ static inline uint32_t get_umc_v6_7_channel_index(struct amdgpu_device *adev,
}
static void umc_v6_7_ecc_info_query_correctable_error_count(struct amdgpu_device *adev,
- uint32_t channel_index,
+ uint32_t umc_inst, uint32_t ch_inst,
unsigned long *error_count)
{
- uint32_t ecc_err_cnt;
uint64_t mc_umc_status;
+ uint32_t eccinfo_table_idx;
struct amdgpu_ras *ras = amdgpu_ras_get_context(adev);
- /*
- * select the lower chip and check the error count
- * skip add error count, calc error counter only from mca_umc_status
- */
- ecc_err_cnt = ras->umc_ecc.ecc[channel_index].ce_count_lo_chip;
-
- /*
- * select the higher chip and check the err counter
- * skip add error count, calc error counter only from mca_umc_status
- */
- ecc_err_cnt = ras->umc_ecc.ecc[channel_index].ce_count_hi_chip;
-
+ eccinfo_table_idx = umc_inst * adev->umc.channel_inst_num + ch_inst;
/* check for SRAM correctable error
MCUMC_STATUS is a 64 bit register */
- mc_umc_status = ras->umc_ecc.ecc[channel_index].mca_umc_status;
+ mc_umc_status = ras->umc_ecc.ecc[eccinfo_table_idx].mca_umc_status;
if (REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, Val) == 1 &&
REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, CECC) == 1)
*error_count += 1;
}
static void umc_v6_7_ecc_info_querry_uncorrectable_error_count(struct amdgpu_device *adev,
- uint32_t channel_index,
+ uint32_t umc_inst, uint32_t ch_inst,
unsigned long *error_count)
{
uint64_t mc_umc_status;
+ uint32_t eccinfo_table_idx;
+ uint32_t umc_reg_offset;
+ uint32_t mc_umc_addr;
+ uint64_t reg_value;
struct amdgpu_ras *ras = amdgpu_ras_get_context(adev);
+ umc_reg_offset = get_umc_v6_7_reg_offset(adev,
+ umc_inst, ch_inst);
+
+ eccinfo_table_idx = umc_inst * adev->umc.channel_inst_num + ch_inst;
/* check the MCUMC_STATUS */
- mc_umc_status = ras->umc_ecc.ecc[channel_index].mca_umc_status;
+ mc_umc_status = ras->umc_ecc.ecc[eccinfo_table_idx].mca_umc_status;
if ((REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, Val) == 1) &&
(REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, Deferred) == 1 ||
REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, UECC) == 1 ||
REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, PCC) == 1 ||
REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, UC) == 1 ||
- REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, TCC) == 1))
+ REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, TCC) == 1)) {
*error_count += 1;
+
+ if (REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, Deferred) == 1)
+ dev_info(adev->dev, "Deferred error, no user action is needed.\n");
+
+ if (mc_umc_status)
+ dev_info(adev->dev, "MCA STATUS 0x%llx, umc_reg_offset 0x%x\n", mc_umc_status, umc_reg_offset);
+
+ /* print IPID registers value */
+ mc_umc_addr =
+ SOC15_REG_OFFSET(UMC, 0, regMCA_UMC_UMC0_MCUMC_IPIDT0);
+ reg_value = RREG64_PCIE((mc_umc_addr + umc_reg_offset) * 4);
+ if (reg_value)
+ dev_info(adev->dev, "MCA IPID 0x%llx, umc_reg_offset 0x%x\n", reg_value, umc_reg_offset);
+
+ /* print SYND registers value */
+ mc_umc_addr =
+ SOC15_REG_OFFSET(UMC, 0, regMCA_UMC_UMC0_MCUMC_SYNDT0);
+ reg_value = RREG64_PCIE((mc_umc_addr + umc_reg_offset) * 4);
+ if (reg_value)
+ dev_info(adev->dev, "MCA SYND 0x%llx, umc_reg_offset 0x%x\n", reg_value, umc_reg_offset);
+
+ /* print MISC0 registers value */
+ mc_umc_addr =
+ SOC15_REG_OFFSET(UMC, 0, regMCA_UMC_UMC0_MCUMC_MISC0T0);
+ reg_value = RREG64_PCIE((mc_umc_addr + umc_reg_offset) * 4);
+ if (reg_value)
+ dev_info(adev->dev, "MCA MISC0 0x%llx, umc_reg_offset 0x%x\n", reg_value, umc_reg_offset);
+ }
}
static void umc_v6_7_ecc_info_query_ras_error_count(struct amdgpu_device *adev,
@@ -110,42 +142,34 @@ static void umc_v6_7_ecc_info_query_ras_error_count(struct amdgpu_device *adev,
uint32_t umc_inst = 0;
uint32_t ch_inst = 0;
- uint32_t umc_reg_offset = 0;
- uint32_t channel_index = 0;
/*TODO: driver needs to toggle DF Cstate to ensure
* safe access of UMC registers. Will add the protection */
LOOP_UMC_INST_AND_CH(umc_inst, ch_inst) {
- umc_reg_offset = get_umc_v6_7_reg_offset(adev,
- umc_inst,
- ch_inst);
- channel_index = get_umc_v6_7_channel_index(adev,
- umc_inst,
- ch_inst);
umc_v6_7_ecc_info_query_correctable_error_count(adev,
- channel_index,
+ umc_inst, ch_inst,
&(err_data->ce_count));
umc_v6_7_ecc_info_querry_uncorrectable_error_count(adev,
- channel_index,
+ umc_inst, ch_inst,
&(err_data->ue_count));
}
}
static void umc_v6_7_ecc_info_query_error_address(struct amdgpu_device *adev,
struct ras_err_data *err_data,
- uint32_t umc_reg_offset,
uint32_t ch_inst,
uint32_t umc_inst)
{
- uint64_t mc_umc_status, err_addr, retired_page;
- struct eeprom_table_record *err_rec;
+ uint64_t mc_umc_status, err_addr, soc_pa, retired_page, column;
uint32_t channel_index;
+ uint32_t eccinfo_table_idx;
struct amdgpu_ras *ras = amdgpu_ras_get_context(adev);
+ eccinfo_table_idx = umc_inst * adev->umc.channel_inst_num + ch_inst;
channel_index =
adev->umc.channel_idx_tbl[umc_inst * adev->umc.channel_inst_num + ch_inst];
- mc_umc_status = ras->umc_ecc.ecc[channel_index].mca_umc_status;
+ mc_umc_status = ras->umc_ecc.ecc[eccinfo_table_idx].mca_umc_status;
if (mc_umc_status == 0)
return;
@@ -153,34 +177,41 @@ static void umc_v6_7_ecc_info_query_error_address(struct amdgpu_device *adev,
if (!err_data->err_addr)
return;
- err_rec = &err_data->err_addr[err_data->err_addr_cnt];
-
/* calculate error address if ue/ce error is detected */
if (REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, Val) == 1 &&
(REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, UECC) == 1 ||
REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, CECC) == 1)) {
- err_addr = ras->umc_ecc.ecc[channel_index].mca_umc_addr;
+ err_addr = ras->umc_ecc.ecc[eccinfo_table_idx].mca_umc_addr;
err_addr = REG_GET_FIELD(err_addr, MCA_UMC_UMC0_MCUMC_ADDRT0, ErrorAddr);
/* translate umc channel address to soc pa, 3 parts are included */
- retired_page = ADDR_OF_8KB_BLOCK(err_addr) |
+ soc_pa = ADDR_OF_8KB_BLOCK(err_addr) |
ADDR_OF_256B_BLOCK(channel_index) |
OFFSET_IN_256B_BLOCK(err_addr);
+ /* The umc channel bits are not original values, they are hashed */
+ SET_CHANNEL_HASH(channel_index, soc_pa);
+
+ /* clear [C4 C3 C2] in soc physical address */
+ soc_pa &= ~(0x7ULL << UMC_V6_7_PA_C2_BIT);
+
/* we only save ue error information currently, ce is skipped */
if (REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, UECC)
== 1) {
- err_rec->address = err_addr;
- /* page frame address is saved */
- err_rec->retired_page = retired_page >> AMDGPU_GPU_PAGE_SHIFT;
- err_rec->ts = (uint64_t)ktime_get_real_seconds();
- err_rec->err_type = AMDGPU_RAS_EEPROM_ERR_NON_RECOVERABLE;
- err_rec->cu = 0;
- err_rec->mem_channel = channel_index;
- err_rec->mcumc_id = umc_inst;
-
- err_data->err_addr_cnt++;
+ /* loop for all possibilities of [C4 C3 C2] */
+ for (column = 0; column < UMC_V6_7_NA_MAP_PA_NUM; column++) {
+ retired_page = soc_pa | (column << UMC_V6_7_PA_C2_BIT);
+ dev_info(adev->dev, "Error Address(PA): 0x%llx\n", retired_page);
+ amdgpu_umc_fill_error_record(err_data, err_addr,
+ retired_page, channel_index, umc_inst);
+
+ /* shift R14 bit */
+ retired_page ^= (0x1ULL << UMC_V6_7_PA_R14_BIT);
+ dev_info(adev->dev, "Error Address(PA): 0x%llx\n", retired_page);
+ amdgpu_umc_fill_error_record(err_data, err_addr,
+ retired_page, channel_index, umc_inst);
+ }
}
}
}
@@ -192,18 +223,13 @@ static void umc_v6_7_ecc_info_query_ras_error_address(struct amdgpu_device *adev
uint32_t umc_inst = 0;
uint32_t ch_inst = 0;
- uint32_t umc_reg_offset = 0;
/*TODO: driver needs to toggle DF Cstate to ensure
* safe access of UMC resgisters. Will add the protection
* when firmware interface is ready */
LOOP_UMC_INST_AND_CH(umc_inst, ch_inst) {
- umc_reg_offset = get_umc_v6_7_reg_offset(adev,
- umc_inst,
- ch_inst);
umc_v6_7_ecc_info_query_error_address(adev,
err_data,
- umc_reg_offset,
ch_inst,
umc_inst);
}
@@ -261,6 +287,8 @@ static void umc_v6_7_querry_uncorrectable_error_count(struct amdgpu_device *adev
{
uint64_t mc_umc_status;
uint32_t mc_umc_status_addr;
+ uint32_t mc_umc_addr;
+ uint64_t reg_value;
mc_umc_status_addr =
SOC15_REG_OFFSET(UMC, 0, regMCA_UMC_UMC0_MCUMC_STATUST0);
@@ -272,8 +300,36 @@ static void umc_v6_7_querry_uncorrectable_error_count(struct amdgpu_device *adev
REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, UECC) == 1 ||
REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, PCC) == 1 ||
REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, UC) == 1 ||
- REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, TCC) == 1))
+ REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, TCC) == 1)) {
*error_count += 1;
+
+ if (REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, Deferred) == 1)
+ dev_info(adev->dev, "Deferred error, no user action is needed.\n");
+
+ if (mc_umc_status)
+ dev_info(adev->dev, "MCA STATUS 0x%llx, umc_reg_offset 0x%x\n", mc_umc_status, umc_reg_offset);
+
+ /* print IPID registers value */
+ mc_umc_addr =
+ SOC15_REG_OFFSET(UMC, 0, regMCA_UMC_UMC0_MCUMC_IPIDT0);
+ reg_value = RREG64_PCIE((mc_umc_addr + umc_reg_offset) * 4);
+ if (reg_value)
+ dev_info(adev->dev, "MCA IPID 0x%llx, umc_reg_offset 0x%x\n", reg_value, umc_reg_offset);
+
+ /* print SYND registers value */
+ mc_umc_addr =
+ SOC15_REG_OFFSET(UMC, 0, regMCA_UMC_UMC0_MCUMC_SYNDT0);
+ reg_value = RREG64_PCIE((mc_umc_addr + umc_reg_offset) * 4);
+ if (reg_value)
+ dev_info(adev->dev, "MCA SYND 0x%llx, umc_reg_offset 0x%x\n", reg_value, umc_reg_offset);
+
+ /* print MISC0 registers value */
+ mc_umc_addr =
+ SOC15_REG_OFFSET(UMC, 0, regMCA_UMC_UMC0_MCUMC_MISC0T0);
+ reg_value = RREG64_PCIE((mc_umc_addr + umc_reg_offset) * 4);
+ if (reg_value)
+ dev_info(adev->dev, "MCA MISC0 0x%llx, umc_reg_offset 0x%x\n", reg_value, umc_reg_offset);
+ }
}
static void umc_v6_7_reset_error_count_per_channel(struct amdgpu_device *adev,
@@ -365,9 +421,9 @@ static void umc_v6_7_query_error_address(struct amdgpu_device *adev,
uint32_t umc_inst)
{
uint32_t mc_umc_status_addr;
- uint64_t mc_umc_status, err_addr, retired_page, mc_umc_addrt0;
- struct eeprom_table_record *err_rec;
uint32_t channel_index;
+ uint64_t mc_umc_status, mc_umc_addrt0;
+ uint64_t err_addr, soc_pa, retired_page, column;
mc_umc_status_addr =
SOC15_REG_OFFSET(UMC, 0, regMCA_UMC_UMC0_MCUMC_STATUST0);
@@ -385,8 +441,6 @@ static void umc_v6_7_query_error_address(struct amdgpu_device *adev,
return;
}
- err_rec = &err_data->err_addr[err_data->err_addr_cnt];
-
channel_index =
adev->umc.channel_idx_tbl[umc_inst * adev->umc.channel_inst_num + ch_inst];
@@ -399,23 +453,32 @@ static void umc_v6_7_query_error_address(struct amdgpu_device *adev,
err_addr = REG_GET_FIELD(err_addr, MCA_UMC_UMC0_MCUMC_ADDRT0, ErrorAddr);
/* translate umc channel address to soc pa, 3 parts are included */
- retired_page = ADDR_OF_8KB_BLOCK(err_addr) |
+ soc_pa = ADDR_OF_8KB_BLOCK(err_addr) |
ADDR_OF_256B_BLOCK(channel_index) |
OFFSET_IN_256B_BLOCK(err_addr);
+ /* The umc channel bits are not original values, they are hashed */
+ SET_CHANNEL_HASH(channel_index, soc_pa);
+
+ /* clear [C4 C3 C2] in soc physical address */
+ soc_pa &= ~(0x7ULL << UMC_V6_7_PA_C2_BIT);
+
/* we only save ue error information currently, ce is skipped */
if (REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, UECC)
== 1) {
- err_rec->address = err_addr;
- /* page frame address is saved */
- err_rec->retired_page = retired_page >> AMDGPU_GPU_PAGE_SHIFT;
- err_rec->ts = (uint64_t)ktime_get_real_seconds();
- err_rec->err_type = AMDGPU_RAS_EEPROM_ERR_NON_RECOVERABLE;
- err_rec->cu = 0;
- err_rec->mem_channel = channel_index;
- err_rec->mcumc_id = umc_inst;
-
- err_data->err_addr_cnt++;
+ /* loop for all possibilities of [C4 C3 C2] */
+ for (column = 0; column < UMC_V6_7_NA_MAP_PA_NUM; column++) {
+ retired_page = soc_pa | (column << UMC_V6_7_PA_C2_BIT);
+ dev_info(adev->dev, "Error Address(PA): 0x%llx\n", retired_page);
+ amdgpu_umc_fill_error_record(err_data, err_addr,
+ retired_page, channel_index, umc_inst);
+
+ /* shift R14 bit */
+ retired_page ^= (0x1ULL << UMC_V6_7_PA_R14_BIT);
+ dev_info(adev->dev, "Error Address(PA): 0x%llx\n", retired_page);
+ amdgpu_umc_fill_error_record(err_data, err_addr,
+ retired_page, channel_index, umc_inst);
+ }
}
}
@@ -463,28 +526,24 @@ static uint32_t umc_v6_7_query_ras_poison_mode_per_channel(
static bool umc_v6_7_query_ras_poison_mode(struct amdgpu_device *adev)
{
- uint32_t umc_inst = 0;
- uint32_t ch_inst = 0;
uint32_t umc_reg_offset = 0;
- LOOP_UMC_INST_AND_CH(umc_inst, ch_inst) {
- umc_reg_offset = get_umc_v6_7_reg_offset(adev,
- umc_inst,
- ch_inst);
- /* Enabling fatal error in one channel will be considered
- as fatal error mode */
- if (umc_v6_7_query_ras_poison_mode_per_channel(adev, umc_reg_offset))
- return false;
- }
-
- return true;
+ /* Enabling fatal error in umc instance0 channel0 will be
+ * considered as fatal error mode
+ */
+ umc_reg_offset = get_umc_v6_7_reg_offset(adev, 0, 0);
+ return !umc_v6_7_query_ras_poison_mode_per_channel(adev, umc_reg_offset);
}
-const struct amdgpu_umc_ras_funcs umc_v6_7_ras_funcs = {
- .ras_late_init = amdgpu_umc_ras_late_init,
- .ras_fini = amdgpu_umc_ras_fini,
+const struct amdgpu_ras_block_hw_ops umc_v6_7_ras_hw_ops = {
.query_ras_error_count = umc_v6_7_query_ras_error_count,
.query_ras_error_address = umc_v6_7_query_ras_error_address,
+};
+
+struct amdgpu_umc_ras umc_v6_7_ras = {
+ .ras_block = {
+ .hw_ops = &umc_v6_7_ras_hw_ops,
+ },
.query_ras_poison_mode = umc_v6_7_query_ras_poison_mode,
.ecc_info_query_ras_error_count = umc_v6_7_ecc_info_query_ras_error_count,
.ecc_info_query_ras_error_address = umc_v6_7_ecc_info_query_ras_error_address,
diff --git a/drivers/gpu/drm/amd/amdgpu/umc_v6_7.h b/drivers/gpu/drm/amd/amdgpu/umc_v6_7.h
index 57f2557e7aca..fe41ed2f5945 100644
--- a/drivers/gpu/drm/amd/amdgpu/umc_v6_7.h
+++ b/drivers/gpu/drm/amd/amdgpu/umc_v6_7.h
@@ -41,9 +41,32 @@
#define UMC_V6_7_CHANNEL_INSTANCE_NUM 8
/* total channel instances in one umc block */
#define UMC_V6_7_TOTAL_CHANNEL_NUM (UMC_V6_7_CHANNEL_INSTANCE_NUM * UMC_V6_7_UMC_INSTANCE_NUM)
+/* one piece of normalizing address is mapped to 8 pieces of physical address */
+#define UMC_V6_7_NA_MAP_PA_NUM 8
+/* R14 bit shift should be considered, double the number */
+#define UMC_V6_7_BAD_PAGE_NUM_PER_CHANNEL (UMC_V6_7_NA_MAP_PA_NUM * 2)
+/* The CH4 bit in SOC physical address */
+#define UMC_V6_7_PA_CH4_BIT 12
+/* The C2 bit in SOC physical address */
+#define UMC_V6_7_PA_C2_BIT 17
+/* The R14 bit in SOC physical address */
+#define UMC_V6_7_PA_R14_BIT 34
/* UMC regiser per channel offset */
#define UMC_V6_7_PER_CHANNEL_OFFSET 0x400
-extern const struct amdgpu_umc_ras_funcs umc_v6_7_ras_funcs;
+
+/* XOR bit 20, 25, 34 of PA into CH4 bit (bit 12 of PA),
+ * hash bit is only effective when related setting is enabled
+ */
+#define CHANNEL_HASH(channel_idx, pa) (((channel_idx) >> 4) ^ \
+ (((pa) >> 20) & 0x1ULL & adev->df.hash_status.hash_64k) ^ \
+ (((pa) >> 25) & 0x1ULL & adev->df.hash_status.hash_2m) ^ \
+ (((pa) >> 34) & 0x1ULL & adev->df.hash_status.hash_1g))
+#define SET_CHANNEL_HASH(channel_idx, pa) do { \
+ (pa) &= ~(0x1ULL << UMC_V6_7_PA_CH4_BIT); \
+ (pa) |= (CHANNEL_HASH(channel_idx, pa) << UMC_V6_7_PA_CH4_BIT); \
+ } while (0)
+
+extern struct amdgpu_umc_ras umc_v6_7_ras;
extern const uint32_t
umc_v6_7_channel_idx_tbl_second[UMC_V6_7_UMC_INSTANCE_NUM][UMC_V6_7_CHANNEL_INSTANCE_NUM];
extern const uint32_t
diff --git a/drivers/gpu/drm/amd/amdgpu/umc_v8_7.c b/drivers/gpu/drm/amd/amdgpu/umc_v8_7.c
index af59a35788e3..f35253e0eaa6 100644
--- a/drivers/gpu/drm/amd/amdgpu/umc_v8_7.c
+++ b/drivers/gpu/drm/amd/amdgpu/umc_v8_7.c
@@ -40,13 +40,137 @@ const uint32_t
{9, 0}, {15, 6}
};
-static inline uint32_t get_umc_8_reg_offset(struct amdgpu_device *adev,
+static inline uint32_t get_umc_v8_7_reg_offset(struct amdgpu_device *adev,
uint32_t umc_inst,
uint32_t ch_inst)
{
return adev->umc.channel_offs*ch_inst + UMC_8_INST_DIST*umc_inst;
}
+static void umc_v8_7_ecc_info_query_correctable_error_count(struct amdgpu_device *adev,
+ uint32_t umc_inst, uint32_t ch_inst,
+ unsigned long *error_count)
+{
+ uint64_t mc_umc_status;
+ uint32_t eccinfo_table_idx;
+ struct amdgpu_ras *ras = amdgpu_ras_get_context(adev);
+
+ eccinfo_table_idx = umc_inst * adev->umc.channel_inst_num + ch_inst;
+
+ /* check for SRAM correctable error
+ * MCUMC_STATUS is a 64 bit register
+ */
+ mc_umc_status = ras->umc_ecc.ecc[eccinfo_table_idx].mca_umc_status;
+ if (REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, Val) == 1 &&
+ REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, CECC) == 1)
+ *error_count += 1;
+}
+
+static void umc_v8_7_ecc_info_querry_uncorrectable_error_count(struct amdgpu_device *adev,
+ uint32_t umc_inst, uint32_t ch_inst,
+ unsigned long *error_count)
+{
+ uint64_t mc_umc_status;
+ uint32_t eccinfo_table_idx;
+ struct amdgpu_ras *ras = amdgpu_ras_get_context(adev);
+
+ eccinfo_table_idx = umc_inst * adev->umc.channel_inst_num + ch_inst;
+
+ /* check the MCUMC_STATUS */
+ mc_umc_status = ras->umc_ecc.ecc[eccinfo_table_idx].mca_umc_status;
+ if ((REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, Val) == 1) &&
+ (REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, Deferred) == 1 ||
+ REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, UECC) == 1 ||
+ REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, PCC) == 1 ||
+ REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, UC) == 1 ||
+ REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, TCC) == 1))
+ *error_count += 1;
+}
+
+static void umc_v8_7_ecc_info_query_ras_error_count(struct amdgpu_device *adev,
+ void *ras_error_status)
+{
+ struct ras_err_data *err_data = (struct ras_err_data *)ras_error_status;
+
+ uint32_t umc_inst = 0;
+ uint32_t ch_inst = 0;
+
+ /* TODO: driver needs to toggle DF Cstate to ensure
+ * safe access of UMC registers. Will add the protection
+ */
+ LOOP_UMC_INST_AND_CH(umc_inst, ch_inst) {
+ umc_v8_7_ecc_info_query_correctable_error_count(adev,
+ umc_inst, ch_inst,
+ &(err_data->ce_count));
+ umc_v8_7_ecc_info_querry_uncorrectable_error_count(adev,
+ umc_inst, ch_inst,
+ &(err_data->ue_count));
+ }
+}
+
+static void umc_v8_7_ecc_info_query_error_address(struct amdgpu_device *adev,
+ struct ras_err_data *err_data,
+ uint32_t ch_inst,
+ uint32_t umc_inst)
+{
+ uint64_t mc_umc_status, err_addr, retired_page;
+ uint32_t channel_index;
+ uint32_t eccinfo_table_idx;
+ struct amdgpu_ras *ras = amdgpu_ras_get_context(adev);
+
+ eccinfo_table_idx = umc_inst * adev->umc.channel_inst_num + ch_inst;
+ channel_index =
+ adev->umc.channel_idx_tbl[umc_inst * adev->umc.channel_inst_num + ch_inst];
+
+ mc_umc_status = ras->umc_ecc.ecc[eccinfo_table_idx].mca_umc_status;
+
+ if (mc_umc_status == 0)
+ return;
+
+ if (!err_data->err_addr)
+ return;
+
+ /* calculate error address if ue/ce error is detected */
+ if (REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, Val) == 1 &&
+ (REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, UECC) == 1 ||
+ REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, CECC) == 1)) {
+
+ err_addr = ras->umc_ecc.ecc[eccinfo_table_idx].mca_umc_addr;
+ err_addr = REG_GET_FIELD(err_addr, MCA_UMC_UMC0_MCUMC_ADDRT0, ErrorAddr);
+
+ /* translate umc channel address to soc pa, 3 parts are included */
+ retired_page = ADDR_OF_4KB_BLOCK(err_addr) |
+ ADDR_OF_256B_BLOCK(channel_index) |
+ OFFSET_IN_256B_BLOCK(err_addr);
+
+ /* we only save ue error information currently, ce is skipped */
+ if (REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, UECC)
+ == 1)
+ amdgpu_umc_fill_error_record(err_data, err_addr,
+ retired_page, channel_index, umc_inst);
+ }
+}
+
+static void umc_v8_7_ecc_info_query_ras_error_address(struct amdgpu_device *adev,
+ void *ras_error_status)
+{
+ struct ras_err_data *err_data = (struct ras_err_data *)ras_error_status;
+
+ uint32_t umc_inst = 0;
+ uint32_t ch_inst = 0;
+
+ /* TODO: driver needs to toggle DF Cstate to ensure
+ * safe access of UMC resgisters. Will add the protection
+ * when firmware interface is ready
+ */
+ LOOP_UMC_INST_AND_CH(umc_inst, ch_inst) {
+ umc_v8_7_ecc_info_query_error_address(adev,
+ err_data,
+ ch_inst,
+ umc_inst);
+ }
+}
+
static void umc_v8_7_clear_error_count_per_channel(struct amdgpu_device *adev,
uint32_t umc_reg_offset)
{
@@ -92,7 +216,7 @@ static void umc_v8_7_clear_error_count(struct amdgpu_device *adev)
uint32_t umc_reg_offset = 0;
LOOP_UMC_INST_AND_CH(umc_inst, ch_inst) {
- umc_reg_offset = get_umc_8_reg_offset(adev,
+ umc_reg_offset = get_umc_v8_7_reg_offset(adev,
umc_inst,
ch_inst);
@@ -178,7 +302,7 @@ static void umc_v8_7_query_ras_error_count(struct amdgpu_device *adev,
uint32_t umc_reg_offset = 0;
LOOP_UMC_INST_AND_CH(umc_inst, ch_inst) {
- umc_reg_offset = get_umc_8_reg_offset(adev,
+ umc_reg_offset = get_umc_v8_7_reg_offset(adev,
umc_inst,
ch_inst);
@@ -201,7 +325,6 @@ static void umc_v8_7_query_error_address(struct amdgpu_device *adev,
{
uint32_t lsb, mc_umc_status_addr;
uint64_t mc_umc_status, err_addr, retired_page, mc_umc_addrt0;
- struct eeprom_table_record *err_rec;
uint32_t channel_index = adev->umc.channel_idx_tbl[umc_inst * adev->umc.channel_inst_num + ch_inst];
mc_umc_status_addr =
@@ -220,8 +343,6 @@ static void umc_v8_7_query_error_address(struct amdgpu_device *adev,
return;
}
- err_rec = &err_data->err_addr[err_data->err_addr_cnt];
-
/* calculate error address if ue/ce error is detected */
if (REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, Val) == 1 &&
(REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, UECC) == 1 ||
@@ -240,18 +361,9 @@ static void umc_v8_7_query_error_address(struct amdgpu_device *adev,
/* we only save ue error information currently, ce is skipped */
if (REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, UECC)
- == 1) {
- err_rec->address = err_addr;
- /* page frame address is saved */
- err_rec->retired_page = retired_page >> AMDGPU_GPU_PAGE_SHIFT;
- err_rec->ts = (uint64_t)ktime_get_real_seconds();
- err_rec->err_type = AMDGPU_RAS_EEPROM_ERR_NON_RECOVERABLE;
- err_rec->cu = 0;
- err_rec->mem_channel = channel_index;
- err_rec->mcumc_id = umc_inst;
-
- err_data->err_addr_cnt++;
- }
+ == 1)
+ amdgpu_umc_fill_error_record(err_data, err_addr,
+ retired_page, channel_index, umc_inst);
}
/* clear umc status */
@@ -268,7 +380,7 @@ static void umc_v8_7_query_ras_error_address(struct amdgpu_device *adev,
uint32_t umc_reg_offset = 0;
LOOP_UMC_INST_AND_CH(umc_inst, ch_inst) {
- umc_reg_offset = get_umc_8_reg_offset(adev,
+ umc_reg_offset = get_umc_v8_7_reg_offset(adev,
umc_inst,
ch_inst);
@@ -316,7 +428,7 @@ static void umc_v8_7_err_cnt_init(struct amdgpu_device *adev)
uint32_t umc_reg_offset = 0;
LOOP_UMC_INST_AND_CH(umc_inst, ch_inst) {
- umc_reg_offset = get_umc_8_reg_offset(adev,
+ umc_reg_offset = get_umc_v8_7_reg_offset(adev,
umc_inst,
ch_inst);
@@ -324,10 +436,16 @@ static void umc_v8_7_err_cnt_init(struct amdgpu_device *adev)
}
}
-const struct amdgpu_umc_ras_funcs umc_v8_7_ras_funcs = {
- .err_cnt_init = umc_v8_7_err_cnt_init,
- .ras_late_init = amdgpu_umc_ras_late_init,
- .ras_fini = amdgpu_umc_ras_fini,
+const struct amdgpu_ras_block_hw_ops umc_v8_7_ras_hw_ops = {
.query_ras_error_count = umc_v8_7_query_ras_error_count,
.query_ras_error_address = umc_v8_7_query_ras_error_address,
};
+
+struct amdgpu_umc_ras umc_v8_7_ras = {
+ .ras_block = {
+ .hw_ops = &umc_v8_7_ras_hw_ops,
+ },
+ .err_cnt_init = umc_v8_7_err_cnt_init,
+ .ecc_info_query_ras_error_count = umc_v8_7_ecc_info_query_ras_error_count,
+ .ecc_info_query_ras_error_address = umc_v8_7_ecc_info_query_ras_error_address,
+};
diff --git a/drivers/gpu/drm/amd/amdgpu/umc_v8_7.h b/drivers/gpu/drm/amd/amdgpu/umc_v8_7.h
index 37e6dc7c28e0..dd4993f5f78f 100644
--- a/drivers/gpu/drm/amd/amdgpu/umc_v8_7.h
+++ b/drivers/gpu/drm/amd/amdgpu/umc_v8_7.h
@@ -44,7 +44,7 @@
/* umc ce count initial value */
#define UMC_V8_7_CE_CNT_INIT (UMC_V8_7_CE_CNT_MAX - UMC_V8_7_CE_INT_THRESHOLD)
-extern const struct amdgpu_umc_ras_funcs umc_v8_7_ras_funcs;
+extern struct amdgpu_umc_ras umc_v8_7_ras;
extern const uint32_t
umc_v8_7_channel_idx_tbl[UMC_V8_7_UMC_INSTANCE_NUM][UMC_V8_7_CHANNEL_INSTANCE_NUM];
diff --git a/drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c b/drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c
index b483f03b4591..2f15b8e0f7d7 100644
--- a/drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c
@@ -25,6 +25,7 @@
#include "amdgpu.h"
#include "amdgpu_uvd.h"
+#include "amdgpu_cs.h"
#include "soc15.h"
#include "soc15d.h"
#include "soc15_common.h"
@@ -1275,14 +1276,15 @@ static int uvd_v7_0_ring_test_ring(struct amdgpu_ring *ring)
* uvd_v7_0_ring_patch_cs_in_place - Patch the IB for command submission.
*
* @p: the CS parser with the IBs
- * @ib_idx: which IB to patch
+ * @job: which job this ib is in
+ * @ib: which IB to patch
*
*/
static int uvd_v7_0_ring_patch_cs_in_place(struct amdgpu_cs_parser *p,
- uint32_t ib_idx)
+ struct amdgpu_job *job,
+ struct amdgpu_ib *ib)
{
- struct amdgpu_ring *ring = to_amdgpu_ring(p->entity->rq->sched);
- struct amdgpu_ib *ib = &p->job->ibs[ib_idx];
+ struct amdgpu_ring *ring = to_amdgpu_ring(job->base.sched);
unsigned i;
/* No patching necessary for the first instance */
@@ -1290,12 +1292,12 @@ static int uvd_v7_0_ring_patch_cs_in_place(struct amdgpu_cs_parser *p,
return 0;
for (i = 0; i < ib->length_dw; i += 2) {
- uint32_t reg = amdgpu_get_ib_value(p, ib_idx, i);
+ uint32_t reg = amdgpu_ib_get_value(ib, i);
reg -= p->adev->reg_offset[UVD_HWIP][0][1];
reg += p->adev->reg_offset[UVD_HWIP][1][1];
- amdgpu_set_ib_value(p, ib_idx, i, reg);
+ amdgpu_ib_set_value(ib, i, reg);
}
return 0;
}
diff --git a/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c b/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c
index 3799226defc0..dff54190b96c 100644
--- a/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c
@@ -148,6 +148,13 @@ static int vcn_v1_0_sw_init(void *handle)
adev->vcn.pause_dpg_mode = vcn_v1_0_pause_dpg_mode;
+ if (amdgpu_vcnfw_log) {
+ volatile struct amdgpu_fw_shared *fw_shared = adev->vcn.inst->fw_shared.cpu_addr;
+
+ fw_shared->present_flag_0 = 0;
+ amdgpu_vcn_fwlog_init(adev->vcn.inst);
+ }
+
r = jpeg_v1_0_sw_init(handle);
return r;
@@ -1095,13 +1102,8 @@ static int vcn_v1_0_start_dpg_mode(struct amdgpu_device *adev)
static int vcn_v1_0_start(struct amdgpu_device *adev)
{
- int r;
-
- if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG)
- r = vcn_v1_0_start_dpg_mode(adev);
- else
- r = vcn_v1_0_start_spg_mode(adev);
- return r;
+ return (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG) ?
+ vcn_v1_0_start_dpg_mode(adev) : vcn_v1_0_start_spg_mode(adev);
}
/**
@@ -1903,6 +1905,7 @@ static const struct amdgpu_ring_funcs vcn_v1_0_dec_ring_vm_funcs = {
.align_mask = 0xf,
.support_64bit_ptrs = false,
.no_user_fence = true,
+ .secure_submission_supported = true,
.vmhub = AMDGPU_MMHUB_0,
.get_rptr = vcn_v1_0_dec_ring_get_rptr,
.get_wptr = vcn_v1_0_dec_ring_get_wptr,
diff --git a/drivers/gpu/drm/amd/amdgpu/vcn_v2_0.c b/drivers/gpu/drm/amd/amdgpu/vcn_v2_0.c
index 313fc1b53999..7a7f35e83dd5 100644
--- a/drivers/gpu/drm/amd/amdgpu/vcn_v2_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/vcn_v2_0.c
@@ -172,8 +172,12 @@ static int vcn_v2_0_sw_init(void *handle)
if (r)
return r;
- fw_shared = adev->vcn.inst->fw_shared_cpu_addr;
+ fw_shared = adev->vcn.inst->fw_shared.cpu_addr;
fw_shared->present_flag_0 = cpu_to_le32(AMDGPU_VCN_MULTI_QUEUE_FLAG);
+
+ if (amdgpu_vcnfw_log)
+ amdgpu_vcn_fwlog_init(adev->vcn.inst);
+
return 0;
}
@@ -188,7 +192,7 @@ static int vcn_v2_0_sw_fini(void *handle)
{
int r, idx;
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
- volatile struct amdgpu_fw_shared *fw_shared = adev->vcn.inst->fw_shared_cpu_addr;
+ volatile struct amdgpu_fw_shared *fw_shared = adev->vcn.inst->fw_shared.cpu_addr;
if (drm_dev_enter(adev_to_drm(adev), &idx)) {
fw_shared->present_flag_0 = 0;
@@ -364,9 +368,9 @@ static void vcn_v2_0_mc_resume(struct amdgpu_device *adev)
/* non-cache window */
WREG32_SOC15(UVD, 0, mmUVD_LMI_VCPU_NC0_64BIT_BAR_LOW,
- lower_32_bits(adev->vcn.inst->fw_shared_gpu_addr));
+ lower_32_bits(adev->vcn.inst->fw_shared.gpu_addr));
WREG32_SOC15(UVD, 0, mmUVD_LMI_VCPU_NC0_64BIT_BAR_HIGH,
- upper_32_bits(adev->vcn.inst->fw_shared_gpu_addr));
+ upper_32_bits(adev->vcn.inst->fw_shared.gpu_addr));
WREG32_SOC15(UVD, 0, mmUVD_VCPU_NONCACHE_OFFSET0, 0);
WREG32_SOC15(UVD, 0, mmUVD_VCPU_NONCACHE_SIZE0,
AMDGPU_GPU_PAGE_ALIGN(sizeof(struct amdgpu_fw_shared)));
@@ -455,10 +459,10 @@ static void vcn_v2_0_mc_resume_dpg_mode(struct amdgpu_device *adev, bool indirec
/* non-cache window */
WREG32_SOC15_DPG_MODE(0, SOC15_DPG_MODE_OFFSET(
UVD, 0, mmUVD_LMI_VCPU_NC0_64BIT_BAR_LOW),
- lower_32_bits(adev->vcn.inst->fw_shared_gpu_addr), 0, indirect);
+ lower_32_bits(adev->vcn.inst->fw_shared.gpu_addr), 0, indirect);
WREG32_SOC15_DPG_MODE(0, SOC15_DPG_MODE_OFFSET(
UVD, 0, mmUVD_LMI_VCPU_NC0_64BIT_BAR_HIGH),
- upper_32_bits(adev->vcn.inst->fw_shared_gpu_addr), 0, indirect);
+ upper_32_bits(adev->vcn.inst->fw_shared.gpu_addr), 0, indirect);
WREG32_SOC15_DPG_MODE(0, SOC15_DPG_MODE_OFFSET(
UVD, 0, mmUVD_VCPU_NONCACHE_OFFSET0), 0, 0, indirect);
WREG32_SOC15_DPG_MODE(0, SOC15_DPG_MODE_OFFSET(
@@ -784,7 +788,7 @@ static void vcn_v2_0_enable_static_power_gating(struct amdgpu_device *adev)
static int vcn_v2_0_start_dpg_mode(struct amdgpu_device *adev, bool indirect)
{
- volatile struct amdgpu_fw_shared *fw_shared = adev->vcn.inst->fw_shared_cpu_addr;
+ volatile struct amdgpu_fw_shared *fw_shared = adev->vcn.inst->fw_shared.cpu_addr;
struct amdgpu_ring *ring = &adev->vcn.inst->ring_dec;
uint32_t rb_bufsz, tmp;
@@ -921,7 +925,7 @@ static int vcn_v2_0_start_dpg_mode(struct amdgpu_device *adev, bool indirect)
static int vcn_v2_0_start(struct amdgpu_device *adev)
{
- volatile struct amdgpu_fw_shared *fw_shared = adev->vcn.inst->fw_shared_cpu_addr;
+ volatile struct amdgpu_fw_shared *fw_shared = adev->vcn.inst->fw_shared.cpu_addr;
struct amdgpu_ring *ring = &adev->vcn.inst->ring_dec;
uint32_t rb_bufsz, tmp;
uint32_t lmi_swap_cntl;
@@ -1094,8 +1098,10 @@ static int vcn_v2_0_start(struct amdgpu_device *adev)
static int vcn_v2_0_stop_dpg_mode(struct amdgpu_device *adev)
{
+ struct dpg_pause_state state = {.fw_based = VCN_DPG_STATE__UNPAUSE};
uint32_t tmp;
+ vcn_v2_0_pause_dpg_mode(adev, 0, &state);
/* Wait for power status to be 1 */
SOC15_WAIT_ON_RREG(UVD, 0, mmUVD_POWER_STATUS, 1,
UVD_POWER_STATUS__UVD_POWER_STATUS_MASK);
@@ -1207,7 +1213,7 @@ static int vcn_v2_0_pause_dpg_mode(struct amdgpu_device *adev,
UVD_POWER_STATUS__UVD_POWER_STATUS_MASK);
if (!ret_code) {
- volatile struct amdgpu_fw_shared *fw_shared = adev->vcn.inst->fw_shared_cpu_addr;
+ volatile struct amdgpu_fw_shared *fw_shared = adev->vcn.inst->fw_shared.cpu_addr;
/* pause DPG */
reg_data |= UVD_DPG_PAUSE__NJ_PAUSE_DPG_REQ_MASK;
WREG32_SOC15(UVD, 0, mmUVD_DPG_PAUSE, reg_data);
@@ -2003,6 +2009,7 @@ static const struct amd_ip_funcs vcn_v2_0_ip_funcs = {
static const struct amdgpu_ring_funcs vcn_v2_0_dec_ring_vm_funcs = {
.type = AMDGPU_RING_TYPE_VCN_DEC,
.align_mask = 0xf,
+ .secure_submission_supported = true,
.vmhub = AMDGPU_MMHUB_0,
.get_rptr = vcn_v2_0_dec_ring_get_rptr,
.get_wptr = vcn_v2_0_dec_ring_get_wptr,
diff --git a/drivers/gpu/drm/amd/amdgpu/vcn_v2_5.c b/drivers/gpu/drm/amd/amdgpu/vcn_v2_5.c
index 44fc4c218433..1bf672966a62 100644
--- a/drivers/gpu/drm/amd/amdgpu/vcn_v2_5.c
+++ b/drivers/gpu/drm/amd/amdgpu/vcn_v2_5.c
@@ -196,8 +196,11 @@ static int vcn_v2_5_sw_init(void *handle)
return r;
}
- fw_shared = adev->vcn.inst[j].fw_shared_cpu_addr;
+ fw_shared = adev->vcn.inst[j].fw_shared.cpu_addr;
fw_shared->present_flag_0 = cpu_to_le32(AMDGPU_VCN_MULTI_QUEUE_FLAG);
+
+ if (amdgpu_vcnfw_log)
+ amdgpu_vcn_fwlog_init(&adev->vcn.inst[i]);
}
if (amdgpu_sriov_vf(adev)) {
@@ -229,7 +232,7 @@ static int vcn_v2_5_sw_fini(void *handle)
for (i = 0; i < adev->vcn.num_vcn_inst; i++) {
if (adev->vcn.harvest_config & (1 << i))
continue;
- fw_shared = adev->vcn.inst[i].fw_shared_cpu_addr;
+ fw_shared = adev->vcn.inst[i].fw_shared.cpu_addr;
fw_shared->present_flag_0 = 0;
}
drm_dev_exit(idx);
@@ -423,9 +426,9 @@ static void vcn_v2_5_mc_resume(struct amdgpu_device *adev)
/* non-cache window */
WREG32_SOC15(VCN, i, mmUVD_LMI_VCPU_NC0_64BIT_BAR_LOW,
- lower_32_bits(adev->vcn.inst[i].fw_shared_gpu_addr));
+ lower_32_bits(adev->vcn.inst[i].fw_shared.gpu_addr));
WREG32_SOC15(VCN, i, mmUVD_LMI_VCPU_NC0_64BIT_BAR_HIGH,
- upper_32_bits(adev->vcn.inst[i].fw_shared_gpu_addr));
+ upper_32_bits(adev->vcn.inst[i].fw_shared.gpu_addr));
WREG32_SOC15(VCN, i, mmUVD_VCPU_NONCACHE_OFFSET0, 0);
WREG32_SOC15(VCN, i, mmUVD_VCPU_NONCACHE_SIZE0,
AMDGPU_GPU_PAGE_ALIGN(sizeof(struct amdgpu_fw_shared)));
@@ -513,10 +516,10 @@ static void vcn_v2_5_mc_resume_dpg_mode(struct amdgpu_device *adev, int inst_idx
/* non-cache window */
WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
VCN, 0, mmUVD_LMI_VCPU_NC0_64BIT_BAR_LOW),
- lower_32_bits(adev->vcn.inst[inst_idx].fw_shared_gpu_addr), 0, indirect);
+ lower_32_bits(adev->vcn.inst[inst_idx].fw_shared.gpu_addr), 0, indirect);
WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
VCN, 0, mmUVD_LMI_VCPU_NC0_64BIT_BAR_HIGH),
- upper_32_bits(adev->vcn.inst[inst_idx].fw_shared_gpu_addr), 0, indirect);
+ upper_32_bits(adev->vcn.inst[inst_idx].fw_shared.gpu_addr), 0, indirect);
WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
VCN, 0, mmUVD_VCPU_NONCACHE_OFFSET0), 0, 0, indirect);
WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
@@ -757,7 +760,7 @@ static void vcn_v2_5_enable_clock_gating(struct amdgpu_device *adev)
static int vcn_v2_5_start_dpg_mode(struct amdgpu_device *adev, int inst_idx, bool indirect)
{
- volatile struct amdgpu_fw_shared *fw_shared = adev->vcn.inst[inst_idx].fw_shared_cpu_addr;
+ volatile struct amdgpu_fw_shared *fw_shared = adev->vcn.inst[inst_idx].fw_shared.cpu_addr;
struct amdgpu_ring *ring;
uint32_t rb_bufsz, tmp;
@@ -981,7 +984,7 @@ static int vcn_v2_5_start(struct amdgpu_device *adev)
vcn_v2_5_mc_resume(adev);
for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
- volatile struct amdgpu_fw_shared *fw_shared = adev->vcn.inst[i].fw_shared_cpu_addr;
+ volatile struct amdgpu_fw_shared *fw_shared = adev->vcn.inst[i].fw_shared.cpu_addr;
if (adev->vcn.harvest_config & (1 << i))
continue;
/* VCN global tiling registers */
@@ -1403,7 +1406,7 @@ static int vcn_v2_5_pause_dpg_mode(struct amdgpu_device *adev,
UVD_POWER_STATUS__UVD_POWER_STATUS_MASK);
if (!ret_code) {
- volatile struct amdgpu_fw_shared *fw_shared = adev->vcn.inst[inst_idx].fw_shared_cpu_addr;
+ volatile struct amdgpu_fw_shared *fw_shared = adev->vcn.inst[inst_idx].fw_shared.cpu_addr;
/* pause DPG */
reg_data |= UVD_DPG_PAUSE__NJ_PAUSE_DPG_REQ_MASK;
@@ -1512,6 +1515,7 @@ static void vcn_v2_5_dec_ring_set_wptr(struct amdgpu_ring *ring)
static const struct amdgpu_ring_funcs vcn_v2_5_dec_ring_vm_funcs = {
.type = AMDGPU_RING_TYPE_VCN_DEC,
.align_mask = 0xf,
+ .secure_submission_supported = true,
.vmhub = AMDGPU_MMHUB_1,
.get_rptr = vcn_v2_5_dec_ring_get_rptr,
.get_wptr = vcn_v2_5_dec_ring_get_wptr,
@@ -1542,6 +1546,7 @@ static const struct amdgpu_ring_funcs vcn_v2_5_dec_ring_vm_funcs = {
static const struct amdgpu_ring_funcs vcn_v2_6_dec_ring_vm_funcs = {
.type = AMDGPU_RING_TYPE_VCN_DEC,
.align_mask = 0xf,
+ .secure_submission_supported = true,
.vmhub = AMDGPU_MMHUB_0,
.get_rptr = vcn_v2_5_dec_ring_get_rptr,
.get_wptr = vcn_v2_5_dec_ring_get_wptr,
diff --git a/drivers/gpu/drm/amd/amdgpu/vcn_v3_0.c b/drivers/gpu/drm/amd/amdgpu/vcn_v3_0.c
index da11ceba0698..c87263ed20ec 100644
--- a/drivers/gpu/drm/amd/amdgpu/vcn_v3_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/vcn_v3_0.c
@@ -25,6 +25,7 @@
#include "amdgpu.h"
#include "amdgpu_vcn.h"
#include "amdgpu_pm.h"
+#include "amdgpu_cs.h"
#include "soc15.h"
#include "soc15d.h"
#include "vcn_v2_0.h"
@@ -213,11 +214,14 @@ static int vcn_v3_0_sw_init(void *handle)
return r;
}
- fw_shared = adev->vcn.inst[i].fw_shared_cpu_addr;
+ fw_shared = adev->vcn.inst[i].fw_shared.cpu_addr;
fw_shared->present_flag_0 |= cpu_to_le32(AMDGPU_VCN_SW_RING_FLAG) |
cpu_to_le32(AMDGPU_VCN_MULTI_QUEUE_FLAG) |
cpu_to_le32(AMDGPU_VCN_FW_SHARED_FLAG_0_RB);
fw_shared->sw_ring.is_enabled = cpu_to_le32(DEC_SW_RING_ENABLED);
+
+ if (amdgpu_vcnfw_log)
+ amdgpu_vcn_fwlog_init(&adev->vcn.inst[i]);
}
if (amdgpu_sriov_vf(adev)) {
@@ -249,7 +253,7 @@ static int vcn_v3_0_sw_fini(void *handle)
if (adev->vcn.harvest_config & (1 << i))
continue;
- fw_shared = adev->vcn.inst[i].fw_shared_cpu_addr;
+ fw_shared = adev->vcn.inst[i].fw_shared.cpu_addr;
fw_shared->present_flag_0 = 0;
fw_shared->sw_ring.is_enabled = false;
}
@@ -295,6 +299,7 @@ static int vcn_v3_0_hw_init(void *handle)
ring = &adev->vcn.inst[i].ring_dec;
if (amdgpu_vcn_is_disabled_vcn(adev, VCN_DECODE_RING, i)) {
ring->sched.ready = false;
+ ring->no_scheduler = true;
dev_info(adev->dev, "ring %s is disabled by hypervisor\n", ring->name);
} else {
ring->wptr = 0;
@@ -307,6 +312,7 @@ static int vcn_v3_0_hw_init(void *handle)
ring = &adev->vcn.inst[i].ring_enc[j];
if (amdgpu_vcn_is_disabled_vcn(adev, VCN_ENCODE_RING, i)) {
ring->sched.ready = false;
+ ring->no_scheduler = true;
dev_info(adev->dev, "ring %s is disabled by hypervisor\n", ring->name);
} else {
ring->wptr = 0;
@@ -469,9 +475,9 @@ static void vcn_v3_0_mc_resume(struct amdgpu_device *adev, int inst)
/* non-cache window */
WREG32_SOC15(VCN, inst, mmUVD_LMI_VCPU_NC0_64BIT_BAR_LOW,
- lower_32_bits(adev->vcn.inst[inst].fw_shared_gpu_addr));
+ lower_32_bits(adev->vcn.inst[inst].fw_shared.gpu_addr));
WREG32_SOC15(VCN, inst, mmUVD_LMI_VCPU_NC0_64BIT_BAR_HIGH,
- upper_32_bits(adev->vcn.inst[inst].fw_shared_gpu_addr));
+ upper_32_bits(adev->vcn.inst[inst].fw_shared.gpu_addr));
WREG32_SOC15(VCN, inst, mmUVD_VCPU_NONCACHE_OFFSET0, 0);
WREG32_SOC15(VCN, inst, mmUVD_VCPU_NONCACHE_SIZE0,
AMDGPU_GPU_PAGE_ALIGN(sizeof(struct amdgpu_fw_shared)));
@@ -558,10 +564,10 @@ static void vcn_v3_0_mc_resume_dpg_mode(struct amdgpu_device *adev, int inst_idx
/* non-cache window */
WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
VCN, inst_idx, mmUVD_LMI_VCPU_NC0_64BIT_BAR_LOW),
- lower_32_bits(adev->vcn.inst[inst_idx].fw_shared_gpu_addr), 0, indirect);
+ lower_32_bits(adev->vcn.inst[inst_idx].fw_shared.gpu_addr), 0, indirect);
WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
VCN, inst_idx, mmUVD_LMI_VCPU_NC0_64BIT_BAR_HIGH),
- upper_32_bits(adev->vcn.inst[inst_idx].fw_shared_gpu_addr), 0, indirect);
+ upper_32_bits(adev->vcn.inst[inst_idx].fw_shared.gpu_addr), 0, indirect);
WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
VCN, inst_idx, mmUVD_VCPU_NONCACHE_OFFSET0), 0, 0, indirect);
WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
@@ -923,7 +929,7 @@ static void vcn_v3_0_enable_clock_gating(struct amdgpu_device *adev, int inst)
static int vcn_v3_0_start_dpg_mode(struct amdgpu_device *adev, int inst_idx, bool indirect)
{
- volatile struct amdgpu_fw_shared *fw_shared = adev->vcn.inst[inst_idx].fw_shared_cpu_addr;
+ volatile struct amdgpu_fw_shared *fw_shared = adev->vcn.inst[inst_idx].fw_shared.cpu_addr;
struct amdgpu_ring *ring;
uint32_t rb_bufsz, tmp;
@@ -1220,7 +1226,7 @@ static int vcn_v3_0_start(struct amdgpu_device *adev)
tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_RPTR_WR_EN, 1);
WREG32_SOC15(VCN, i, mmUVD_RBC_RB_CNTL, tmp);
- fw_shared = adev->vcn.inst[i].fw_shared_cpu_addr;
+ fw_shared = adev->vcn.inst[i].fw_shared.cpu_addr;
fw_shared->multi_queue.decode_queue_mode |= cpu_to_le32(FW_QUEUE_RING_RESET);
/* programm the RB_BASE for ring buffer */
@@ -1611,7 +1617,7 @@ static int vcn_v3_0_pause_dpg_mode(struct amdgpu_device *adev,
if (adev->ip_versions[UVD_HWIP][0] != IP_VERSION(3, 0, 33)) {
/* Restore */
- fw_shared = adev->vcn.inst[inst_idx].fw_shared_cpu_addr;
+ fw_shared = adev->vcn.inst[inst_idx].fw_shared.cpu_addr;
fw_shared->multi_queue.encode_generalpurpose_queue_mode |= cpu_to_le32(FW_QUEUE_RING_RESET);
ring = &adev->vcn.inst[inst_idx].ring_enc[0];
ring->wptr = 0;
@@ -1700,7 +1706,7 @@ static void vcn_v3_0_dec_ring_set_wptr(struct amdgpu_ring *ring)
if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG) {
/*whenever update RBC_RB_WPTR, we save the wptr in shared rb.wptr and scratch2 */
- fw_shared = adev->vcn.inst[ring->me].fw_shared_cpu_addr;
+ fw_shared = adev->vcn.inst[ring->me].fw_shared.cpu_addr;
fw_shared->rb.wptr = lower_32_bits(ring->wptr);
WREG32_SOC15(VCN, ring->me, mmUVD_SCRATCH2,
lower_32_bits(ring->wptr));
@@ -1780,6 +1786,7 @@ static const struct amdgpu_ring_funcs vcn_v3_0_dec_sw_ring_vm_funcs = {
.type = AMDGPU_RING_TYPE_VCN_DEC,
.align_mask = 0x3f,
.nop = VCN_DEC_SW_CMD_NO_OP,
+ .secure_submission_supported = true,
.vmhub = AMDGPU_MMHUB_0,
.get_rptr = vcn_v3_0_dec_ring_get_rptr,
.get_wptr = vcn_v3_0_dec_ring_get_wptr,
@@ -1806,21 +1813,23 @@ static const struct amdgpu_ring_funcs vcn_v3_0_dec_sw_ring_vm_funcs = {
.emit_reg_write_reg_wait = amdgpu_ring_emit_reg_write_reg_wait_helper,
};
-static int vcn_v3_0_limit_sched(struct amdgpu_cs_parser *p)
+static int vcn_v3_0_limit_sched(struct amdgpu_cs_parser *p,
+ struct amdgpu_job *job)
{
struct drm_gpu_scheduler **scheds;
/* The create msg must be in the first IB submitted */
- if (atomic_read(&p->entity->fence_seq))
+ if (atomic_read(&job->base.entity->fence_seq))
return -EINVAL;
scheds = p->adev->gpu_sched[AMDGPU_HW_IP_VCN_DEC]
[AMDGPU_RING_PRIO_DEFAULT].sched;
- drm_sched_entity_modify_sched(p->entity, scheds, 1);
+ drm_sched_entity_modify_sched(job->base.entity, scheds, 1);
return 0;
}
-static int vcn_v3_0_dec_msg(struct amdgpu_cs_parser *p, uint64_t addr)
+static int vcn_v3_0_dec_msg(struct amdgpu_cs_parser *p, struct amdgpu_job *job,
+ uint64_t addr)
{
struct ttm_operation_ctx ctx = { false, false };
struct amdgpu_bo_va_mapping *map;
@@ -1891,7 +1900,7 @@ static int vcn_v3_0_dec_msg(struct amdgpu_cs_parser *p, uint64_t addr)
if (create[0] == 0x7 || create[0] == 0x10 || create[0] == 0x11)
continue;
- r = vcn_v3_0_limit_sched(p);
+ r = vcn_v3_0_limit_sched(p, job);
if (r)
goto out;
}
@@ -1902,10 +1911,10 @@ out:
}
static int vcn_v3_0_ring_patch_cs_in_place(struct amdgpu_cs_parser *p,
- uint32_t ib_idx)
+ struct amdgpu_job *job,
+ struct amdgpu_ib *ib)
{
- struct amdgpu_ring *ring = to_amdgpu_ring(p->entity->rq->sched);
- struct amdgpu_ib *ib = &p->job->ibs[ib_idx];
+ struct amdgpu_ring *ring = to_amdgpu_ring(job->base.sched);
uint32_t msg_lo = 0, msg_hi = 0;
unsigned i;
int r;
@@ -1915,8 +1924,8 @@ static int vcn_v3_0_ring_patch_cs_in_place(struct amdgpu_cs_parser *p,
return 0;
for (i = 0; i < ib->length_dw; i += 2) {
- uint32_t reg = amdgpu_get_ib_value(p, ib_idx, i);
- uint32_t val = amdgpu_get_ib_value(p, ib_idx, i + 1);
+ uint32_t reg = amdgpu_ib_get_value(ib, i);
+ uint32_t val = amdgpu_ib_get_value(ib, i + 1);
if (reg == PACKET0(p->adev->vcn.internal.data0, 0)) {
msg_lo = val;
@@ -1924,7 +1933,8 @@ static int vcn_v3_0_ring_patch_cs_in_place(struct amdgpu_cs_parser *p,
msg_hi = val;
} else if (reg == PACKET0(p->adev->vcn.internal.cmd, 0) &&
val == 0) {
- r = vcn_v3_0_dec_msg(p, ((u64)msg_hi) << 32 | msg_lo);
+ r = vcn_v3_0_dec_msg(p, job,
+ ((u64)msg_hi) << 32 | msg_lo);
if (r)
return r;
}
@@ -1935,6 +1945,7 @@ static int vcn_v3_0_ring_patch_cs_in_place(struct amdgpu_cs_parser *p,
static const struct amdgpu_ring_funcs vcn_v3_0_dec_ring_vm_funcs = {
.type = AMDGPU_RING_TYPE_VCN_DEC,
.align_mask = 0xf,
+ .secure_submission_supported = true,
.vmhub = AMDGPU_MMHUB_0,
.get_rptr = vcn_v3_0_dec_ring_get_rptr,
.get_wptr = vcn_v3_0_dec_ring_get_wptr,
diff --git a/drivers/gpu/drm/amd/amdgpu/vi.c b/drivers/gpu/drm/amd/amdgpu/vi.c
index 6645ebbd2696..039b90cdc3bc 100644
--- a/drivers/gpu/drm/amd/amdgpu/vi.c
+++ b/drivers/gpu/drm/amd/amdgpu/vi.c
@@ -1140,7 +1140,7 @@ static void vi_program_aspm(struct amdgpu_device *adev)
bool bL1SS = false;
bool bClkReqSupport = true;
- if (!amdgpu_aspm)
+ if (!amdgpu_device_should_use_aspm(adev))
return;
if (adev->flags & AMD_IS_APU ||
diff --git a/drivers/gpu/drm/amd/amdkfd/Makefile b/drivers/gpu/drm/amd/amdkfd/Makefile
index c4f3aff11072..19cfbf9577b4 100644
--- a/drivers/gpu/drm/amd/amdkfd/Makefile
+++ b/drivers/gpu/drm/amd/amdkfd/Makefile
@@ -51,8 +51,6 @@ AMDKFD_FILES := $(AMDKFD_PATH)/kfd_module.o \
$(AMDKFD_PATH)/kfd_events.o \
$(AMDKFD_PATH)/cik_event_interrupt.o \
$(AMDKFD_PATH)/kfd_int_process_v9.o \
- $(AMDKFD_PATH)/kfd_dbgdev.o \
- $(AMDKFD_PATH)/kfd_dbgmgr.o \
$(AMDKFD_PATH)/kfd_smi_events.o \
$(AMDKFD_PATH)/kfd_crat.o
diff --git a/drivers/gpu/drm/amd/amdkfd/cik_event_interrupt.c b/drivers/gpu/drm/amd/amdkfd/cik_event_interrupt.c
index d60576ce10cd..5c8023cba196 100644
--- a/drivers/gpu/drm/amd/amdkfd/cik_event_interrupt.c
+++ b/drivers/gpu/drm/amd/amdkfd/cik_event_interrupt.c
@@ -110,7 +110,7 @@ static void cik_event_interrupt_wq(struct kfd_dev *dev,
struct kfd_vm_fault_info info;
kfd_smi_event_update_vmfault(dev, pasid);
- kfd_process_vm_fault(dev->dqm, pasid);
+ kfd_dqm_evict_pasid(dev->dqm, pasid);
memset(&info, 0, sizeof(info));
amdgpu_amdkfd_gpuvm_get_vm_fault_info(dev->adev, &info);
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
index 4bfc0c8ab764..607f65ab39ac 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
@@ -1,5 +1,6 @@
+// SPDX-License-Identifier: GPL-2.0 OR MIT
/*
- * Copyright 2014 Advanced Micro Devices, Inc.
+ * Copyright 2014-2022 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@@ -33,14 +34,16 @@
#include <linux/time.h>
#include <linux/mm.h>
#include <linux/mman.h>
+#include <linux/ptrace.h>
#include <linux/dma-buf.h>
-#include <asm/processor.h>
+#include <linux/fdtable.h>
+#include <linux/processor.h>
#include "kfd_priv.h"
#include "kfd_device_queue_manager.h"
-#include "kfd_dbgmgr.h"
#include "kfd_svm.h"
#include "amdgpu_amdkfd.h"
#include "kfd_smi_events.h"
+#include "amdgpu_dma_buf.h"
static long kfd_ioctl(struct file *, unsigned int, unsigned long);
static int kfd_open(struct inode *, struct file *);
@@ -101,11 +104,6 @@ void kfd_chardev_exit(void)
kfd_device = NULL;
}
-struct device *kfd_chardev(void)
-{
- return kfd_device;
-}
-
static int kfd_open(struct inode *inode, struct file *filep)
{
@@ -292,14 +290,17 @@ static int kfd_ioctl_create_queue(struct file *filep, struct kfd_process *p,
return err;
pr_debug("Looking for gpu id 0x%x\n", args->gpu_id);
- dev = kfd_device_by_id(args->gpu_id);
- if (!dev) {
- pr_debug("Could not find gpu id 0x%x\n", args->gpu_id);
- return -EINVAL;
- }
mutex_lock(&p->mutex);
+ pdd = kfd_process_device_data_by_id(p, args->gpu_id);
+ if (!pdd) {
+ pr_debug("Could not find gpu id 0x%x\n", args->gpu_id);
+ err = -EINVAL;
+ goto err_pdd;
+ }
+ dev = pdd->dev;
+
pdd = kfd_bind_process_to_device(dev, p);
if (IS_ERR(pdd)) {
err = -ESRCH;
@@ -310,7 +311,7 @@ static int kfd_ioctl_create_queue(struct file *filep, struct kfd_process *p,
p->pasid,
dev->id);
- err = pqm_create_queue(&p->pqm, dev, filep, &q_properties, &queue_id,
+ err = pqm_create_queue(&p->pqm, dev, filep, &q_properties, &queue_id, NULL, NULL, NULL,
&doorbell_offset_in_process);
if (err != 0)
goto err_create_queue;
@@ -344,6 +345,7 @@ static int kfd_ioctl_create_queue(struct file *filep, struct kfd_process *p,
err_create_queue:
err_bind_process:
+err_pdd:
mutex_unlock(&p->mutex);
return err;
}
@@ -490,7 +492,6 @@ static int kfd_ioctl_set_memory_policy(struct file *filep,
struct kfd_process *p, void *data)
{
struct kfd_ioctl_set_memory_policy_args *args = data;
- struct kfd_dev *dev;
int err = 0;
struct kfd_process_device *pdd;
enum cache_policy default_policy, alternate_policy;
@@ -505,13 +506,15 @@ static int kfd_ioctl_set_memory_policy(struct file *filep,
return -EINVAL;
}
- dev = kfd_device_by_id(args->gpu_id);
- if (!dev)
- return -EINVAL;
-
mutex_lock(&p->mutex);
+ pdd = kfd_process_device_data_by_id(p, args->gpu_id);
+ if (!pdd) {
+ pr_debug("Could not find gpu id 0x%x\n", args->gpu_id);
+ err = -EINVAL;
+ goto err_pdd;
+ }
- pdd = kfd_bind_process_to_device(dev, p);
+ pdd = kfd_bind_process_to_device(pdd->dev, p);
if (IS_ERR(pdd)) {
err = -ESRCH;
goto out;
@@ -524,7 +527,7 @@ static int kfd_ioctl_set_memory_policy(struct file *filep,
(args->alternate_policy == KFD_IOC_CACHE_POLICY_COHERENT)
? cache_policy_coherent : cache_policy_noncoherent;
- if (!dev->dqm->ops.set_cache_memory_policy(dev->dqm,
+ if (!pdd->dev->dqm->ops.set_cache_memory_policy(pdd->dev->dqm,
&pdd->qpd,
default_policy,
alternate_policy,
@@ -533,6 +536,7 @@ static int kfd_ioctl_set_memory_policy(struct file *filep,
err = -EINVAL;
out:
+err_pdd:
mutex_unlock(&p->mutex);
return err;
@@ -542,17 +546,18 @@ static int kfd_ioctl_set_trap_handler(struct file *filep,
struct kfd_process *p, void *data)
{
struct kfd_ioctl_set_trap_handler_args *args = data;
- struct kfd_dev *dev;
int err = 0;
struct kfd_process_device *pdd;
- dev = kfd_device_by_id(args->gpu_id);
- if (!dev)
- return -EINVAL;
-
mutex_lock(&p->mutex);
- pdd = kfd_bind_process_to_device(dev, p);
+ pdd = kfd_process_device_data_by_id(p, args->gpu_id);
+ if (!pdd) {
+ err = -EINVAL;
+ goto err_pdd;
+ }
+
+ pdd = kfd_bind_process_to_device(pdd->dev, p);
if (IS_ERR(pdd)) {
err = -ESRCH;
goto out;
@@ -561,6 +566,7 @@ static int kfd_ioctl_set_trap_handler(struct file *filep,
kfd_process_set_trap_handler(&pdd->qpd, args->tba_addr, args->tma_addr);
out:
+err_pdd:
mutex_unlock(&p->mutex);
return err;
@@ -569,289 +575,40 @@ out:
static int kfd_ioctl_dbg_register(struct file *filep,
struct kfd_process *p, void *data)
{
- struct kfd_ioctl_dbg_register_args *args = data;
- struct kfd_dev *dev;
- struct kfd_dbgmgr *dbgmgr_ptr;
- struct kfd_process_device *pdd;
- bool create_ok;
- long status = 0;
-
- dev = kfd_device_by_id(args->gpu_id);
- if (!dev)
- return -EINVAL;
-
- if (dev->adev->asic_type == CHIP_CARRIZO) {
- pr_debug("kfd_ioctl_dbg_register not supported on CZ\n");
- return -EINVAL;
- }
-
- mutex_lock(&p->mutex);
- mutex_lock(kfd_get_dbgmgr_mutex());
-
- /*
- * make sure that we have pdd, if this the first queue created for
- * this process
- */
- pdd = kfd_bind_process_to_device(dev, p);
- if (IS_ERR(pdd)) {
- status = PTR_ERR(pdd);
- goto out;
- }
-
- if (!dev->dbgmgr) {
- /* In case of a legal call, we have no dbgmgr yet */
- create_ok = kfd_dbgmgr_create(&dbgmgr_ptr, dev);
- if (create_ok) {
- status = kfd_dbgmgr_register(dbgmgr_ptr, p);
- if (status != 0)
- kfd_dbgmgr_destroy(dbgmgr_ptr);
- else
- dev->dbgmgr = dbgmgr_ptr;
- }
- } else {
- pr_debug("debugger already registered\n");
- status = -EINVAL;
- }
-
-out:
- mutex_unlock(kfd_get_dbgmgr_mutex());
- mutex_unlock(&p->mutex);
-
- return status;
+ return -EPERM;
}
static int kfd_ioctl_dbg_unregister(struct file *filep,
struct kfd_process *p, void *data)
{
- struct kfd_ioctl_dbg_unregister_args *args = data;
- struct kfd_dev *dev;
- long status;
-
- dev = kfd_device_by_id(args->gpu_id);
- if (!dev || !dev->dbgmgr)
- return -EINVAL;
-
- if (dev->adev->asic_type == CHIP_CARRIZO) {
- pr_debug("kfd_ioctl_dbg_unregister not supported on CZ\n");
- return -EINVAL;
- }
-
- mutex_lock(kfd_get_dbgmgr_mutex());
-
- status = kfd_dbgmgr_unregister(dev->dbgmgr, p);
- if (!status) {
- kfd_dbgmgr_destroy(dev->dbgmgr);
- dev->dbgmgr = NULL;
- }
-
- mutex_unlock(kfd_get_dbgmgr_mutex());
-
- return status;
+ return -EPERM;
}
-/*
- * Parse and generate variable size data structure for address watch.
- * Total size of the buffer and # watch points is limited in order
- * to prevent kernel abuse. (no bearing to the much smaller HW limitation
- * which is enforced by dbgdev module)
- * please also note that the watch address itself are not "copied from user",
- * since it be set into the HW in user mode values.
- *
- */
static int kfd_ioctl_dbg_address_watch(struct file *filep,
struct kfd_process *p, void *data)
{
- struct kfd_ioctl_dbg_address_watch_args *args = data;
- struct kfd_dev *dev;
- struct dbg_address_watch_info aw_info;
- unsigned char *args_buff;
- long status;
- void __user *cmd_from_user;
- uint64_t watch_mask_value = 0;
- unsigned int args_idx = 0;
-
- memset((void *) &aw_info, 0, sizeof(struct dbg_address_watch_info));
-
- dev = kfd_device_by_id(args->gpu_id);
- if (!dev)
- return -EINVAL;
-
- if (dev->adev->asic_type == CHIP_CARRIZO) {
- pr_debug("kfd_ioctl_dbg_wave_control not supported on CZ\n");
- return -EINVAL;
- }
-
- cmd_from_user = (void __user *) args->content_ptr;
-
- /* Validate arguments */
-
- if ((args->buf_size_in_bytes > MAX_ALLOWED_AW_BUFF_SIZE) ||
- (args->buf_size_in_bytes <= sizeof(*args) + sizeof(int) * 2) ||
- (cmd_from_user == NULL))
- return -EINVAL;
-
- /* this is the actual buffer to work with */
- args_buff = memdup_user(cmd_from_user,
- args->buf_size_in_bytes - sizeof(*args));
- if (IS_ERR(args_buff))
- return PTR_ERR(args_buff);
-
- aw_info.process = p;
-
- aw_info.num_watch_points = *((uint32_t *)(&args_buff[args_idx]));
- args_idx += sizeof(aw_info.num_watch_points);
-
- aw_info.watch_mode = (enum HSA_DBG_WATCH_MODE *) &args_buff[args_idx];
- args_idx += sizeof(enum HSA_DBG_WATCH_MODE) * aw_info.num_watch_points;
-
- /*
- * set watch address base pointer to point on the array base
- * within args_buff
- */
- aw_info.watch_address = (uint64_t *) &args_buff[args_idx];
-
- /* skip over the addresses buffer */
- args_idx += sizeof(aw_info.watch_address) * aw_info.num_watch_points;
-
- if (args_idx >= args->buf_size_in_bytes - sizeof(*args)) {
- status = -EINVAL;
- goto out;
- }
-
- watch_mask_value = (uint64_t) args_buff[args_idx];
-
- if (watch_mask_value > 0) {
- /*
- * There is an array of masks.
- * set watch mask base pointer to point on the array base
- * within args_buff
- */
- aw_info.watch_mask = (uint64_t *) &args_buff[args_idx];
-
- /* skip over the masks buffer */
- args_idx += sizeof(aw_info.watch_mask) *
- aw_info.num_watch_points;
- } else {
- /* just the NULL mask, set to NULL and skip over it */
- aw_info.watch_mask = NULL;
- args_idx += sizeof(aw_info.watch_mask);
- }
-
- if (args_idx >= args->buf_size_in_bytes - sizeof(args)) {
- status = -EINVAL;
- goto out;
- }
-
- /* Currently HSA Event is not supported for DBG */
- aw_info.watch_event = NULL;
-
- mutex_lock(kfd_get_dbgmgr_mutex());
-
- status = kfd_dbgmgr_address_watch(dev->dbgmgr, &aw_info);
-
- mutex_unlock(kfd_get_dbgmgr_mutex());
-
-out:
- kfree(args_buff);
-
- return status;
+ return -EPERM;
}
/* Parse and generate fixed size data structure for wave control */
static int kfd_ioctl_dbg_wave_control(struct file *filep,
struct kfd_process *p, void *data)
{
- struct kfd_ioctl_dbg_wave_control_args *args = data;
- struct kfd_dev *dev;
- struct dbg_wave_control_info wac_info;
- unsigned char *args_buff;
- uint32_t computed_buff_size;
- long status;
- void __user *cmd_from_user;
- unsigned int args_idx = 0;
-
- memset((void *) &wac_info, 0, sizeof(struct dbg_wave_control_info));
-
- /* we use compact form, independent of the packing attribute value */
- computed_buff_size = sizeof(*args) +
- sizeof(wac_info.mode) +
- sizeof(wac_info.operand) +
- sizeof(wac_info.dbgWave_msg.DbgWaveMsg) +
- sizeof(wac_info.dbgWave_msg.MemoryVA) +
- sizeof(wac_info.trapId);
-
- dev = kfd_device_by_id(args->gpu_id);
- if (!dev)
- return -EINVAL;
-
- if (dev->adev->asic_type == CHIP_CARRIZO) {
- pr_debug("kfd_ioctl_dbg_wave_control not supported on CZ\n");
- return -EINVAL;
- }
-
- /* input size must match the computed "compact" size */
- if (args->buf_size_in_bytes != computed_buff_size) {
- pr_debug("size mismatch, computed : actual %u : %u\n",
- args->buf_size_in_bytes, computed_buff_size);
- return -EINVAL;
- }
-
- cmd_from_user = (void __user *) args->content_ptr;
-
- if (cmd_from_user == NULL)
- return -EINVAL;
-
- /* copy the entire buffer from user */
-
- args_buff = memdup_user(cmd_from_user,
- args->buf_size_in_bytes - sizeof(*args));
- if (IS_ERR(args_buff))
- return PTR_ERR(args_buff);
-
- /* move ptr to the start of the "pay-load" area */
- wac_info.process = p;
-
- wac_info.operand = *((enum HSA_DBG_WAVEOP *)(&args_buff[args_idx]));
- args_idx += sizeof(wac_info.operand);
-
- wac_info.mode = *((enum HSA_DBG_WAVEMODE *)(&args_buff[args_idx]));
- args_idx += sizeof(wac_info.mode);
-
- wac_info.trapId = *((uint32_t *)(&args_buff[args_idx]));
- args_idx += sizeof(wac_info.trapId);
-
- wac_info.dbgWave_msg.DbgWaveMsg.WaveMsgInfoGen2.Value =
- *((uint32_t *)(&args_buff[args_idx]));
- wac_info.dbgWave_msg.MemoryVA = NULL;
-
- mutex_lock(kfd_get_dbgmgr_mutex());
-
- pr_debug("Calling dbg manager process %p, operand %u, mode %u, trapId %u, message %u\n",
- wac_info.process, wac_info.operand,
- wac_info.mode, wac_info.trapId,
- wac_info.dbgWave_msg.DbgWaveMsg.WaveMsgInfoGen2.Value);
-
- status = kfd_dbgmgr_wave_control(dev->dbgmgr, &wac_info);
-
- pr_debug("Returned status of dbg manager is %ld\n", status);
-
- mutex_unlock(kfd_get_dbgmgr_mutex());
-
- kfree(args_buff);
-
- return status;
+ return -EPERM;
}
static int kfd_ioctl_get_clock_counters(struct file *filep,
struct kfd_process *p, void *data)
{
struct kfd_ioctl_get_clock_counters_args *args = data;
- struct kfd_dev *dev;
+ struct kfd_process_device *pdd;
- dev = kfd_device_by_id(args->gpu_id);
- if (dev)
+ mutex_lock(&p->mutex);
+ pdd = kfd_process_device_data_by_id(p, args->gpu_id);
+ mutex_unlock(&p->mutex);
+ if (pdd)
/* Reading GPU clock counter from KGD */
- args->gpu_clock_counter = amdgpu_amdkfd_get_gpu_clock_counter(dev->adev);
+ args->gpu_clock_counter = amdgpu_amdkfd_get_gpu_clock_counter(pdd->dev->adev);
else
/* Node without GPU resource */
args->gpu_clock_counter = 0;
@@ -1007,57 +764,11 @@ static int kfd_ioctl_create_event(struct file *filp, struct kfd_process *p,
* through the event_page_offset field.
*/
if (args->event_page_offset) {
- struct kfd_dev *kfd;
- struct kfd_process_device *pdd;
- void *mem, *kern_addr;
- uint64_t size;
-
- kfd = kfd_device_by_id(GET_GPU_ID(args->event_page_offset));
- if (!kfd) {
- pr_err("Getting device by id failed in %s\n", __func__);
- return -EINVAL;
- }
-
mutex_lock(&p->mutex);
-
- if (p->signal_page) {
- pr_err("Event page is already set\n");
- err = -EINVAL;
- goto out_unlock;
- }
-
- pdd = kfd_bind_process_to_device(kfd, p);
- if (IS_ERR(pdd)) {
- err = PTR_ERR(pdd);
- goto out_unlock;
- }
-
- mem = kfd_process_device_translate_handle(pdd,
- GET_IDR_HANDLE(args->event_page_offset));
- if (!mem) {
- pr_err("Can't find BO, offset is 0x%llx\n",
- args->event_page_offset);
- err = -EINVAL;
- goto out_unlock;
- }
-
- err = amdgpu_amdkfd_gpuvm_map_gtt_bo_to_kernel(kfd->adev,
- mem, &kern_addr, &size);
- if (err) {
- pr_err("Failed to map event page to kernel\n");
- goto out_unlock;
- }
-
- err = kfd_event_page_set(p, kern_addr, size);
- if (err) {
- pr_err("Failed to set event page\n");
- amdgpu_amdkfd_gpuvm_unmap_gtt_bo_from_kernel(kfd->adev, mem);
- goto out_unlock;
- }
-
- p->signal_handle = args->event_page_offset;
-
+ err = kfd_kmap_event_page(p, args->event_page_offset);
mutex_unlock(&p->mutex);
+ if (err)
+ return err;
}
err = kfd_event_create(filp, p, args->event_type,
@@ -1066,10 +777,7 @@ static int kfd_ioctl_create_event(struct file *filp, struct kfd_process *p,
&args->event_page_offset,
&args->event_slot_index);
- return err;
-
-out_unlock:
- mutex_unlock(&p->mutex);
+ pr_debug("Created event (id:0x%08x) (%s)\n", args->event_id, __func__);
return err;
}
@@ -1118,11 +826,13 @@ static int kfd_ioctl_set_scratch_backing_va(struct file *filep,
struct kfd_dev *dev;
long err;
- dev = kfd_device_by_id(args->gpu_id);
- if (!dev)
- return -EINVAL;
-
mutex_lock(&p->mutex);
+ pdd = kfd_process_device_data_by_id(p, args->gpu_id);
+ if (!pdd) {
+ err = -EINVAL;
+ goto err_pdd;
+ }
+ dev = pdd->dev;
pdd = kfd_bind_process_to_device(dev, p);
if (IS_ERR(pdd)) {
@@ -1142,6 +852,7 @@ static int kfd_ioctl_set_scratch_backing_va(struct file *filep,
return 0;
bind_process_to_device_fail:
+err_pdd:
mutex_unlock(&p->mutex);
return err;
}
@@ -1150,15 +861,17 @@ static int kfd_ioctl_get_tile_config(struct file *filep,
struct kfd_process *p, void *data)
{
struct kfd_ioctl_get_tile_config_args *args = data;
- struct kfd_dev *dev;
+ struct kfd_process_device *pdd;
struct tile_config config;
int err = 0;
- dev = kfd_device_by_id(args->gpu_id);
- if (!dev)
+ mutex_lock(&p->mutex);
+ pdd = kfd_process_device_data_by_id(p, args->gpu_id);
+ mutex_unlock(&p->mutex);
+ if (!pdd)
return -EINVAL;
- amdgpu_amdkfd_get_tile_config(dev->adev, &config);
+ amdgpu_amdkfd_get_tile_config(pdd->dev->adev, &config);
args->gb_addr_config = config.gb_addr_config;
args->num_banks = config.num_banks;
@@ -1193,40 +906,37 @@ static int kfd_ioctl_acquire_vm(struct file *filep, struct kfd_process *p,
{
struct kfd_ioctl_acquire_vm_args *args = data;
struct kfd_process_device *pdd;
- struct kfd_dev *dev;
struct file *drm_file;
int ret;
- dev = kfd_device_by_id(args->gpu_id);
- if (!dev)
- return -EINVAL;
-
drm_file = fget(args->drm_fd);
if (!drm_file)
return -EINVAL;
mutex_lock(&p->mutex);
-
- pdd = kfd_get_process_device_data(dev, p);
+ pdd = kfd_process_device_data_by_id(p, args->gpu_id);
if (!pdd) {
ret = -EINVAL;
- goto err_unlock;
+ goto err_pdd;
}
if (pdd->drm_file) {
ret = pdd->drm_file == drm_file ? 0 : -EBUSY;
- goto err_unlock;
+ goto err_drm_file;
}
ret = kfd_process_device_init_vm(pdd, drm_file);
if (ret)
goto err_unlock;
+
/* On success, the PDD keeps the drm_file reference */
mutex_unlock(&p->mutex);
return 0;
err_unlock:
+err_pdd:
+err_drm_file:
mutex_unlock(&p->mutex);
fput(drm_file);
return ret;
@@ -1283,19 +993,23 @@ static int kfd_ioctl_alloc_memory_of_gpu(struct file *filep,
}
mutex_unlock(&p->svms.lock);
#endif
- dev = kfd_device_by_id(args->gpu_id);
- if (!dev)
- return -EINVAL;
+ mutex_lock(&p->mutex);
+ pdd = kfd_process_device_data_by_id(p, args->gpu_id);
+ if (!pdd) {
+ err = -EINVAL;
+ goto err_pdd;
+ }
+
+ dev = pdd->dev;
if ((flags & KFD_IOC_ALLOC_MEM_FLAGS_PUBLIC) &&
(flags & KFD_IOC_ALLOC_MEM_FLAGS_VRAM) &&
!kfd_dev_is_large_bar(dev)) {
pr_err("Alloc host visible vram on small bar is not allowed\n");
- return -EINVAL;
+ err = -EINVAL;
+ goto err_large_bar;
}
- mutex_lock(&p->mutex);
-
pdd = kfd_bind_process_to_device(dev, p);
if (IS_ERR(pdd)) {
err = PTR_ERR(pdd);
@@ -1323,7 +1037,7 @@ static int kfd_ioctl_alloc_memory_of_gpu(struct file *filep,
err = amdgpu_amdkfd_gpuvm_alloc_memory_of_gpu(
dev->adev, args->va_addr, args->size,
pdd->drm_priv, (struct kgd_mem **) &mem, &offset,
- flags);
+ flags, false);
if (err)
goto err_unlock;
@@ -1356,6 +1070,8 @@ err_free:
amdgpu_amdkfd_gpuvm_free_memory_of_gpu(dev->adev, (struct kgd_mem *)mem,
pdd->drm_priv, NULL);
err_unlock:
+err_pdd:
+err_large_bar:
mutex_unlock(&p->mutex);
return err;
}
@@ -1366,14 +1082,9 @@ static int kfd_ioctl_free_memory_of_gpu(struct file *filep,
struct kfd_ioctl_free_memory_of_gpu_args *args = data;
struct kfd_process_device *pdd;
void *mem;
- struct kfd_dev *dev;
int ret;
uint64_t size = 0;
- dev = kfd_device_by_id(GET_GPU_ID(args->handle));
- if (!dev)
- return -EINVAL;
-
mutex_lock(&p->mutex);
/*
* Safeguard to prevent user space from freeing signal BO.
@@ -1385,11 +1096,11 @@ static int kfd_ioctl_free_memory_of_gpu(struct file *filep,
goto err_unlock;
}
- pdd = kfd_get_process_device_data(dev, p);
+ pdd = kfd_process_device_data_by_id(p, GET_GPU_ID(args->handle));
if (!pdd) {
pr_err("Process device data doesn't exist\n");
ret = -EINVAL;
- goto err_unlock;
+ goto err_pdd;
}
mem = kfd_process_device_translate_handle(
@@ -1399,7 +1110,7 @@ static int kfd_ioctl_free_memory_of_gpu(struct file *filep,
goto err_unlock;
}
- ret = amdgpu_amdkfd_gpuvm_free_memory_of_gpu(dev->adev,
+ ret = amdgpu_amdkfd_gpuvm_free_memory_of_gpu(pdd->dev->adev,
(struct kgd_mem *)mem, pdd->drm_priv, &size);
/* If freeing the buffer failed, leave the handle in place for
@@ -1412,26 +1123,31 @@ static int kfd_ioctl_free_memory_of_gpu(struct file *filep,
WRITE_ONCE(pdd->vram_usage, pdd->vram_usage - size);
err_unlock:
+err_pdd:
mutex_unlock(&p->mutex);
return ret;
}
+static bool kfd_flush_tlb_after_unmap(struct kfd_dev *dev)
+{
+ return KFD_GC_VERSION(dev) == IP_VERSION(9, 4, 2) ||
+ (KFD_GC_VERSION(dev) == IP_VERSION(9, 4, 1) &&
+ dev->adev->sdma.instance[0].fw_version >= 18) ||
+ KFD_GC_VERSION(dev) == IP_VERSION(9, 4, 0);
+}
+
static int kfd_ioctl_map_memory_to_gpu(struct file *filep,
struct kfd_process *p, void *data)
{
struct kfd_ioctl_map_memory_to_gpu_args *args = data;
struct kfd_process_device *pdd, *peer_pdd;
void *mem;
- struct kfd_dev *dev, *peer;
+ struct kfd_dev *dev;
long err = 0;
int i;
uint32_t *devices_arr = NULL;
bool table_freed = false;
- dev = kfd_device_by_id(GET_GPU_ID(args->handle));
- if (!dev)
- return -EINVAL;
-
if (!args->n_devices) {
pr_debug("Device IDs array empty\n");
return -EINVAL;
@@ -1455,6 +1171,12 @@ static int kfd_ioctl_map_memory_to_gpu(struct file *filep,
}
mutex_lock(&p->mutex);
+ pdd = kfd_process_device_data_by_id(p, GET_GPU_ID(args->handle));
+ if (!pdd) {
+ err = -EINVAL;
+ goto get_process_device_data_failed;
+ }
+ dev = pdd->dev;
pdd = kfd_bind_process_to_device(dev, p);
if (IS_ERR(pdd)) {
@@ -1470,25 +1192,33 @@ static int kfd_ioctl_map_memory_to_gpu(struct file *filep,
}
for (i = args->n_success; i < args->n_devices; i++) {
- peer = kfd_device_by_id(devices_arr[i]);
- if (!peer) {
+ peer_pdd = kfd_process_device_data_by_id(p, devices_arr[i]);
+ if (!peer_pdd) {
pr_debug("Getting device by id failed for 0x%x\n",
devices_arr[i]);
err = -EINVAL;
goto get_mem_obj_from_handle_failed;
}
- peer_pdd = kfd_bind_process_to_device(peer, p);
+ peer_pdd = kfd_bind_process_to_device(peer_pdd->dev, p);
if (IS_ERR(peer_pdd)) {
err = PTR_ERR(peer_pdd);
goto get_mem_obj_from_handle_failed;
}
+
err = amdgpu_amdkfd_gpuvm_map_memory_to_gpu(
- peer->adev, (struct kgd_mem *)mem,
+ peer_pdd->dev->adev, (struct kgd_mem *)mem,
peer_pdd->drm_priv, &table_freed);
if (err) {
- pr_err("Failed to map to gpu %d/%d\n",
- i, args->n_devices);
+ struct pci_dev *pdev = peer_pdd->dev->adev->pdev;
+
+ dev_err(dev->adev->dev,
+ "Failed to map peer:%04x:%02x:%02x.%d mem_domain:%d\n",
+ pci_domain_nr(pdev->bus),
+ pdev->bus->number,
+ PCI_SLOT(pdev->devfn),
+ PCI_FUNC(pdev->devfn),
+ ((struct kgd_mem *)mem)->domain);
goto map_memory_to_gpu_failed;
}
args->n_success = i+1;
@@ -1503,12 +1233,9 @@ static int kfd_ioctl_map_memory_to_gpu(struct file *filep,
}
/* Flush TLBs after waiting for the page table updates to complete */
- if (table_freed) {
+ if (table_freed || !kfd_flush_tlb_after_unmap(dev)) {
for (i = 0; i < args->n_devices; i++) {
- peer = kfd_device_by_id(devices_arr[i]);
- if (WARN_ON_ONCE(!peer))
- continue;
- peer_pdd = kfd_get_process_device_data(peer, p);
+ peer_pdd = kfd_process_device_data_by_id(p, devices_arr[i]);
if (WARN_ON_ONCE(!peer_pdd))
continue;
kfd_flush_tlb(peer_pdd, TLB_FLUSH_LEGACY);
@@ -1518,6 +1245,7 @@ static int kfd_ioctl_map_memory_to_gpu(struct file *filep,
return err;
+get_process_device_data_failed:
bind_process_to_device_failed:
get_mem_obj_from_handle_failed:
map_memory_to_gpu_failed:
@@ -1535,14 +1263,9 @@ static int kfd_ioctl_unmap_memory_from_gpu(struct file *filep,
struct kfd_ioctl_unmap_memory_from_gpu_args *args = data;
struct kfd_process_device *pdd, *peer_pdd;
void *mem;
- struct kfd_dev *dev, *peer;
long err = 0;
uint32_t *devices_arr = NULL, i;
- dev = kfd_device_by_id(GET_GPU_ID(args->handle));
- if (!dev)
- return -EINVAL;
-
if (!args->n_devices) {
pr_debug("Device IDs array empty\n");
return -EINVAL;
@@ -1566,8 +1289,7 @@ static int kfd_ioctl_unmap_memory_from_gpu(struct file *filep,
}
mutex_lock(&p->mutex);
-
- pdd = kfd_get_process_device_data(dev, p);
+ pdd = kfd_process_device_data_by_id(p, GET_GPU_ID(args->handle));
if (!pdd) {
err = -EINVAL;
goto bind_process_to_device_failed;
@@ -1581,19 +1303,13 @@ static int kfd_ioctl_unmap_memory_from_gpu(struct file *filep,
}
for (i = args->n_success; i < args->n_devices; i++) {
- peer = kfd_device_by_id(devices_arr[i]);
- if (!peer) {
- err = -EINVAL;
- goto get_mem_obj_from_handle_failed;
- }
-
- peer_pdd = kfd_get_process_device_data(peer, p);
+ peer_pdd = kfd_process_device_data_by_id(p, devices_arr[i]);
if (!peer_pdd) {
- err = -ENODEV;
+ err = -EINVAL;
goto get_mem_obj_from_handle_failed;
}
err = amdgpu_amdkfd_gpuvm_unmap_memory_from_gpu(
- peer->adev, (struct kgd_mem *)mem, peer_pdd->drm_priv);
+ peer_pdd->dev->adev, (struct kgd_mem *)mem, peer_pdd->drm_priv);
if (err) {
pr_err("Failed to unmap from gpu %d/%d\n",
i, args->n_devices);
@@ -1603,8 +1319,8 @@ static int kfd_ioctl_unmap_memory_from_gpu(struct file *filep,
}
mutex_unlock(&p->mutex);
- if (KFD_GC_VERSION(dev) == IP_VERSION(9, 4, 2)) {
- err = amdgpu_amdkfd_gpuvm_sync_memory(dev->adev,
+ if (kfd_flush_tlb_after_unmap(pdd->dev)) {
+ err = amdgpu_amdkfd_gpuvm_sync_memory(pdd->dev->adev,
(struct kgd_mem *) mem, true);
if (err) {
pr_debug("Sync memory failed, wait interrupted by user signal\n");
@@ -1613,10 +1329,7 @@ static int kfd_ioctl_unmap_memory_from_gpu(struct file *filep,
/* Flush TLBs after waiting for the page table updates to complete */
for (i = 0; i < args->n_devices; i++) {
- peer = kfd_device_by_id(devices_arr[i]);
- if (WARN_ON_ONCE(!peer))
- continue;
- peer_pdd = kfd_get_process_device_data(peer, p);
+ peer_pdd = kfd_process_device_data_by_id(p, devices_arr[i]);
if (WARN_ON_ONCE(!peer_pdd))
continue;
kfd_flush_tlb(peer_pdd, TLB_FLUSH_HEAVYWEIGHT);
@@ -1736,29 +1449,29 @@ static int kfd_ioctl_import_dmabuf(struct file *filep,
struct kfd_ioctl_import_dmabuf_args *args = data;
struct kfd_process_device *pdd;
struct dma_buf *dmabuf;
- struct kfd_dev *dev;
int idr_handle;
uint64_t size;
void *mem;
int r;
- dev = kfd_device_by_id(args->gpu_id);
- if (!dev)
- return -EINVAL;
-
dmabuf = dma_buf_get(args->dmabuf_fd);
if (IS_ERR(dmabuf))
return PTR_ERR(dmabuf);
mutex_lock(&p->mutex);
+ pdd = kfd_process_device_data_by_id(p, args->gpu_id);
+ if (!pdd) {
+ r = -EINVAL;
+ goto err_unlock;
+ }
- pdd = kfd_bind_process_to_device(dev, p);
+ pdd = kfd_bind_process_to_device(pdd->dev, p);
if (IS_ERR(pdd)) {
r = PTR_ERR(pdd);
goto err_unlock;
}
- r = amdgpu_amdkfd_gpuvm_import_dmabuf(dev->adev, dmabuf,
+ r = amdgpu_amdkfd_gpuvm_import_dmabuf(pdd->dev->adev, dmabuf,
args->va_addr, pdd->drm_priv,
(struct kgd_mem **)&mem, &size,
NULL);
@@ -1779,7 +1492,7 @@ static int kfd_ioctl_import_dmabuf(struct file *filep,
return 0;
err_free:
- amdgpu_amdkfd_gpuvm_free_memory_of_gpu(dev->adev, (struct kgd_mem *)mem,
+ amdgpu_amdkfd_gpuvm_free_memory_of_gpu(pdd->dev->adev, (struct kgd_mem *)mem,
pdd->drm_priv, NULL);
err_unlock:
mutex_unlock(&p->mutex);
@@ -1792,13 +1505,16 @@ static int kfd_ioctl_smi_events(struct file *filep,
struct kfd_process *p, void *data)
{
struct kfd_ioctl_smi_events_args *args = data;
- struct kfd_dev *dev;
+ struct kfd_process_device *pdd;
- dev = kfd_device_by_id(args->gpuid);
- if (!dev)
+ mutex_lock(&p->mutex);
+
+ pdd = kfd_process_device_data_by_id(p, args->gpuid);
+ mutex_unlock(&p->mutex);
+ if (!pdd)
return -EINVAL;
- return kfd_smi_event_open(dev, &args->anon_fd);
+ return kfd_smi_event_open(pdd->dev, &args->anon_fd);
}
static int kfd_ioctl_set_xnack_mode(struct file *filep,
@@ -1840,13 +1556,9 @@ static int kfd_ioctl_svm(struct file *filep, struct kfd_process *p, void *data)
if (!args->start_addr || !args->size)
return -EINVAL;
- mutex_lock(&p->mutex);
-
r = svm_ioctl(p, args->op, args->start_addr, args->size, args->nattr,
args->attrs);
- mutex_unlock(&p->mutex);
-
return r;
}
#else
@@ -1856,6 +1568,993 @@ static int kfd_ioctl_svm(struct file *filep, struct kfd_process *p, void *data)
}
#endif
+static int criu_checkpoint_process(struct kfd_process *p,
+ uint8_t __user *user_priv_data,
+ uint64_t *priv_offset)
+{
+ struct kfd_criu_process_priv_data process_priv;
+ int ret;
+
+ memset(&process_priv, 0, sizeof(process_priv));
+
+ process_priv.version = KFD_CRIU_PRIV_VERSION;
+ /* For CR, we don't consider negative xnack mode which is used for
+ * querying without changing it, here 0 simply means disabled and 1
+ * means enabled so retry for finding a valid PTE.
+ */
+ process_priv.xnack_mode = p->xnack_enabled ? 1 : 0;
+
+ ret = copy_to_user(user_priv_data + *priv_offset,
+ &process_priv, sizeof(process_priv));
+
+ if (ret) {
+ pr_err("Failed to copy process information to user\n");
+ ret = -EFAULT;
+ }
+
+ *priv_offset += sizeof(process_priv);
+ return ret;
+}
+
+static int criu_checkpoint_devices(struct kfd_process *p,
+ uint32_t num_devices,
+ uint8_t __user *user_addr,
+ uint8_t __user *user_priv_data,
+ uint64_t *priv_offset)
+{
+ struct kfd_criu_device_priv_data *device_priv = NULL;
+ struct kfd_criu_device_bucket *device_buckets = NULL;
+ int ret = 0, i;
+
+ device_buckets = kvzalloc(num_devices * sizeof(*device_buckets), GFP_KERNEL);
+ if (!device_buckets) {
+ ret = -ENOMEM;
+ goto exit;
+ }
+
+ device_priv = kvzalloc(num_devices * sizeof(*device_priv), GFP_KERNEL);
+ if (!device_priv) {
+ ret = -ENOMEM;
+ goto exit;
+ }
+
+ for (i = 0; i < num_devices; i++) {
+ struct kfd_process_device *pdd = p->pdds[i];
+
+ device_buckets[i].user_gpu_id = pdd->user_gpu_id;
+ device_buckets[i].actual_gpu_id = pdd->dev->id;
+
+ /*
+ * priv_data does not contain useful information for now and is reserved for
+ * future use, so we do not set its contents.
+ */
+ }
+
+ ret = copy_to_user(user_addr, device_buckets, num_devices * sizeof(*device_buckets));
+ if (ret) {
+ pr_err("Failed to copy device information to user\n");
+ ret = -EFAULT;
+ goto exit;
+ }
+
+ ret = copy_to_user(user_priv_data + *priv_offset,
+ device_priv,
+ num_devices * sizeof(*device_priv));
+ if (ret) {
+ pr_err("Failed to copy device information to user\n");
+ ret = -EFAULT;
+ }
+ *priv_offset += num_devices * sizeof(*device_priv);
+
+exit:
+ kvfree(device_buckets);
+ kvfree(device_priv);
+ return ret;
+}
+
+static uint32_t get_process_num_bos(struct kfd_process *p)
+{
+ uint32_t num_of_bos = 0;
+ int i;
+
+ /* Run over all PDDs of the process */
+ for (i = 0; i < p->n_pdds; i++) {
+ struct kfd_process_device *pdd = p->pdds[i];
+ void *mem;
+ int id;
+
+ idr_for_each_entry(&pdd->alloc_idr, mem, id) {
+ struct kgd_mem *kgd_mem = (struct kgd_mem *)mem;
+
+ if ((uint64_t)kgd_mem->va > pdd->gpuvm_base)
+ num_of_bos++;
+ }
+ }
+ return num_of_bos;
+}
+
+static int criu_get_prime_handle(struct drm_gem_object *gobj, int flags,
+ u32 *shared_fd)
+{
+ struct dma_buf *dmabuf;
+ int ret;
+
+ dmabuf = amdgpu_gem_prime_export(gobj, flags);
+ if (IS_ERR(dmabuf)) {
+ ret = PTR_ERR(dmabuf);
+ pr_err("dmabuf export failed for the BO\n");
+ return ret;
+ }
+
+ ret = dma_buf_fd(dmabuf, flags);
+ if (ret < 0) {
+ pr_err("dmabuf create fd failed, ret:%d\n", ret);
+ goto out_free_dmabuf;
+ }
+
+ *shared_fd = ret;
+ return 0;
+
+out_free_dmabuf:
+ dma_buf_put(dmabuf);
+ return ret;
+}
+
+static int criu_checkpoint_bos(struct kfd_process *p,
+ uint32_t num_bos,
+ uint8_t __user *user_bos,
+ uint8_t __user *user_priv_data,
+ uint64_t *priv_offset)
+{
+ struct kfd_criu_bo_bucket *bo_buckets;
+ struct kfd_criu_bo_priv_data *bo_privs;
+ int ret = 0, pdd_index, bo_index = 0, id;
+ void *mem;
+
+ bo_buckets = kvzalloc(num_bos * sizeof(*bo_buckets), GFP_KERNEL);
+ if (!bo_buckets)
+ return -ENOMEM;
+
+ bo_privs = kvzalloc(num_bos * sizeof(*bo_privs), GFP_KERNEL);
+ if (!bo_privs) {
+ ret = -ENOMEM;
+ goto exit;
+ }
+
+ for (pdd_index = 0; pdd_index < p->n_pdds; pdd_index++) {
+ struct kfd_process_device *pdd = p->pdds[pdd_index];
+ struct amdgpu_bo *dumper_bo;
+ struct kgd_mem *kgd_mem;
+
+ idr_for_each_entry(&pdd->alloc_idr, mem, id) {
+ struct kfd_criu_bo_bucket *bo_bucket;
+ struct kfd_criu_bo_priv_data *bo_priv;
+ int i, dev_idx = 0;
+
+ if (!mem) {
+ ret = -ENOMEM;
+ goto exit;
+ }
+
+ kgd_mem = (struct kgd_mem *)mem;
+ dumper_bo = kgd_mem->bo;
+
+ if ((uint64_t)kgd_mem->va <= pdd->gpuvm_base)
+ continue;
+
+ bo_bucket = &bo_buckets[bo_index];
+ bo_priv = &bo_privs[bo_index];
+
+ bo_bucket->gpu_id = pdd->user_gpu_id;
+ bo_bucket->addr = (uint64_t)kgd_mem->va;
+ bo_bucket->size = amdgpu_bo_size(dumper_bo);
+ bo_bucket->alloc_flags = (uint32_t)kgd_mem->alloc_flags;
+ bo_priv->idr_handle = id;
+
+ if (bo_bucket->alloc_flags & KFD_IOC_ALLOC_MEM_FLAGS_USERPTR) {
+ ret = amdgpu_ttm_tt_get_userptr(&dumper_bo->tbo,
+ &bo_priv->user_addr);
+ if (ret) {
+ pr_err("Failed to obtain user address for user-pointer bo\n");
+ goto exit;
+ }
+ }
+ if (bo_bucket->alloc_flags
+ & (KFD_IOC_ALLOC_MEM_FLAGS_VRAM | KFD_IOC_ALLOC_MEM_FLAGS_GTT)) {
+ ret = criu_get_prime_handle(&dumper_bo->tbo.base,
+ bo_bucket->alloc_flags &
+ KFD_IOC_ALLOC_MEM_FLAGS_WRITABLE ? DRM_RDWR : 0,
+ &bo_bucket->dmabuf_fd);
+ if (ret)
+ goto exit;
+ } else {
+ bo_bucket->dmabuf_fd = KFD_INVALID_FD;
+ }
+
+ if (bo_bucket->alloc_flags & KFD_IOC_ALLOC_MEM_FLAGS_DOORBELL)
+ bo_bucket->offset = KFD_MMAP_TYPE_DOORBELL |
+ KFD_MMAP_GPU_ID(pdd->dev->id);
+ else if (bo_bucket->alloc_flags &
+ KFD_IOC_ALLOC_MEM_FLAGS_MMIO_REMAP)
+ bo_bucket->offset = KFD_MMAP_TYPE_MMIO |
+ KFD_MMAP_GPU_ID(pdd->dev->id);
+ else
+ bo_bucket->offset = amdgpu_bo_mmap_offset(dumper_bo);
+
+ for (i = 0; i < p->n_pdds; i++) {
+ if (amdgpu_amdkfd_bo_mapped_to_dev(p->pdds[i]->dev->adev, kgd_mem))
+ bo_priv->mapped_gpuids[dev_idx++] = p->pdds[i]->user_gpu_id;
+ }
+
+ pr_debug("bo_size = 0x%llx, bo_addr = 0x%llx bo_offset = 0x%llx\n"
+ "gpu_id = 0x%x alloc_flags = 0x%x idr_handle = 0x%x",
+ bo_bucket->size,
+ bo_bucket->addr,
+ bo_bucket->offset,
+ bo_bucket->gpu_id,
+ bo_bucket->alloc_flags,
+ bo_priv->idr_handle);
+ bo_index++;
+ }
+ }
+
+ ret = copy_to_user(user_bos, bo_buckets, num_bos * sizeof(*bo_buckets));
+ if (ret) {
+ pr_err("Failed to copy BO information to user\n");
+ ret = -EFAULT;
+ goto exit;
+ }
+
+ ret = copy_to_user(user_priv_data + *priv_offset, bo_privs, num_bos * sizeof(*bo_privs));
+ if (ret) {
+ pr_err("Failed to copy BO priv information to user\n");
+ ret = -EFAULT;
+ goto exit;
+ }
+
+ *priv_offset += num_bos * sizeof(*bo_privs);
+
+exit:
+ while (ret && bo_index--) {
+ if (bo_buckets[bo_index].alloc_flags
+ & (KFD_IOC_ALLOC_MEM_FLAGS_VRAM | KFD_IOC_ALLOC_MEM_FLAGS_GTT))
+ close_fd(bo_buckets[bo_index].dmabuf_fd);
+ }
+
+ kvfree(bo_buckets);
+ kvfree(bo_privs);
+ return ret;
+}
+
+static int criu_get_process_object_info(struct kfd_process *p,
+ uint32_t *num_devices,
+ uint32_t *num_bos,
+ uint32_t *num_objects,
+ uint64_t *objs_priv_size)
+{
+ uint64_t queues_priv_data_size, svm_priv_data_size, priv_size;
+ uint32_t num_queues, num_events, num_svm_ranges;
+ int ret;
+
+ *num_devices = p->n_pdds;
+ *num_bos = get_process_num_bos(p);
+
+ ret = kfd_process_get_queue_info(p, &num_queues, &queues_priv_data_size);
+ if (ret)
+ return ret;
+
+ num_events = kfd_get_num_events(p);
+
+ ret = svm_range_get_info(p, &num_svm_ranges, &svm_priv_data_size);
+ if (ret)
+ return ret;
+
+ *num_objects = num_queues + num_events + num_svm_ranges;
+
+ if (objs_priv_size) {
+ priv_size = sizeof(struct kfd_criu_process_priv_data);
+ priv_size += *num_devices * sizeof(struct kfd_criu_device_priv_data);
+ priv_size += *num_bos * sizeof(struct kfd_criu_bo_priv_data);
+ priv_size += queues_priv_data_size;
+ priv_size += num_events * sizeof(struct kfd_criu_event_priv_data);
+ priv_size += svm_priv_data_size;
+ *objs_priv_size = priv_size;
+ }
+ return 0;
+}
+
+static int criu_checkpoint(struct file *filep,
+ struct kfd_process *p,
+ struct kfd_ioctl_criu_args *args)
+{
+ int ret;
+ uint32_t num_devices, num_bos, num_objects;
+ uint64_t priv_size, priv_offset = 0;
+
+ if (!args->devices || !args->bos || !args->priv_data)
+ return -EINVAL;
+
+ mutex_lock(&p->mutex);
+
+ if (!p->n_pdds) {
+ pr_err("No pdd for given process\n");
+ ret = -ENODEV;
+ goto exit_unlock;
+ }
+
+ /* Confirm all process queues are evicted */
+ if (!p->queues_paused) {
+ pr_err("Cannot dump process when queues are not in evicted state\n");
+ /* CRIU plugin did not call op PROCESS_INFO before checkpointing */
+ ret = -EINVAL;
+ goto exit_unlock;
+ }
+
+ ret = criu_get_process_object_info(p, &num_devices, &num_bos, &num_objects, &priv_size);
+ if (ret)
+ goto exit_unlock;
+
+ if (num_devices != args->num_devices ||
+ num_bos != args->num_bos ||
+ num_objects != args->num_objects ||
+ priv_size != args->priv_data_size) {
+
+ ret = -EINVAL;
+ goto exit_unlock;
+ }
+
+ /* each function will store private data inside priv_data and adjust priv_offset */
+ ret = criu_checkpoint_process(p, (uint8_t __user *)args->priv_data, &priv_offset);
+ if (ret)
+ goto exit_unlock;
+
+ ret = criu_checkpoint_devices(p, num_devices, (uint8_t __user *)args->devices,
+ (uint8_t __user *)args->priv_data, &priv_offset);
+ if (ret)
+ goto exit_unlock;
+
+ ret = criu_checkpoint_bos(p, num_bos, (uint8_t __user *)args->bos,
+ (uint8_t __user *)args->priv_data, &priv_offset);
+ if (ret)
+ goto exit_unlock;
+
+ if (num_objects) {
+ ret = kfd_criu_checkpoint_queues(p, (uint8_t __user *)args->priv_data,
+ &priv_offset);
+ if (ret)
+ goto close_bo_fds;
+
+ ret = kfd_criu_checkpoint_events(p, (uint8_t __user *)args->priv_data,
+ &priv_offset);
+ if (ret)
+ goto close_bo_fds;
+
+ ret = kfd_criu_checkpoint_svm(p, (uint8_t __user *)args->priv_data, &priv_offset);
+ if (ret)
+ goto close_bo_fds;
+ }
+
+close_bo_fds:
+ if (ret) {
+ /* If IOCTL returns err, user assumes all FDs opened in criu_dump_bos are closed */
+ uint32_t i;
+ struct kfd_criu_bo_bucket *bo_buckets = (struct kfd_criu_bo_bucket *) args->bos;
+
+ for (i = 0; i < num_bos; i++) {
+ if (bo_buckets[i].alloc_flags & KFD_IOC_ALLOC_MEM_FLAGS_VRAM)
+ close_fd(bo_buckets[i].dmabuf_fd);
+ }
+ }
+
+exit_unlock:
+ mutex_unlock(&p->mutex);
+ if (ret)
+ pr_err("Failed to dump CRIU ret:%d\n", ret);
+ else
+ pr_debug("CRIU dump ret:%d\n", ret);
+
+ return ret;
+}
+
+static int criu_restore_process(struct kfd_process *p,
+ struct kfd_ioctl_criu_args *args,
+ uint64_t *priv_offset,
+ uint64_t max_priv_data_size)
+{
+ int ret = 0;
+ struct kfd_criu_process_priv_data process_priv;
+
+ if (*priv_offset + sizeof(process_priv) > max_priv_data_size)
+ return -EINVAL;
+
+ ret = copy_from_user(&process_priv,
+ (void __user *)(args->priv_data + *priv_offset),
+ sizeof(process_priv));
+ if (ret) {
+ pr_err("Failed to copy process private information from user\n");
+ ret = -EFAULT;
+ goto exit;
+ }
+ *priv_offset += sizeof(process_priv);
+
+ if (process_priv.version != KFD_CRIU_PRIV_VERSION) {
+ pr_err("Invalid CRIU API version (checkpointed:%d current:%d)\n",
+ process_priv.version, KFD_CRIU_PRIV_VERSION);
+ return -EINVAL;
+ }
+
+ pr_debug("Setting XNACK mode\n");
+ if (process_priv.xnack_mode && !kfd_process_xnack_mode(p, true)) {
+ pr_err("xnack mode cannot be set\n");
+ ret = -EPERM;
+ goto exit;
+ } else {
+ pr_debug("set xnack mode: %d\n", process_priv.xnack_mode);
+ p->xnack_enabled = process_priv.xnack_mode;
+ }
+
+exit:
+ return ret;
+}
+
+static int criu_restore_devices(struct kfd_process *p,
+ struct kfd_ioctl_criu_args *args,
+ uint64_t *priv_offset,
+ uint64_t max_priv_data_size)
+{
+ struct kfd_criu_device_bucket *device_buckets;
+ struct kfd_criu_device_priv_data *device_privs;
+ int ret = 0;
+ uint32_t i;
+
+ if (args->num_devices != p->n_pdds)
+ return -EINVAL;
+
+ if (*priv_offset + (args->num_devices * sizeof(*device_privs)) > max_priv_data_size)
+ return -EINVAL;
+
+ device_buckets = kmalloc_array(args->num_devices, sizeof(*device_buckets), GFP_KERNEL);
+ if (!device_buckets)
+ return -ENOMEM;
+
+ ret = copy_from_user(device_buckets, (void __user *)args->devices,
+ args->num_devices * sizeof(*device_buckets));
+ if (ret) {
+ pr_err("Failed to copy devices buckets from user\n");
+ ret = -EFAULT;
+ goto exit;
+ }
+
+ for (i = 0; i < args->num_devices; i++) {
+ struct kfd_dev *dev;
+ struct kfd_process_device *pdd;
+ struct file *drm_file;
+
+ /* device private data is not currently used */
+
+ if (!device_buckets[i].user_gpu_id) {
+ pr_err("Invalid user gpu_id\n");
+ ret = -EINVAL;
+ goto exit;
+ }
+
+ dev = kfd_device_by_id(device_buckets[i].actual_gpu_id);
+ if (!dev) {
+ pr_err("Failed to find device with gpu_id = %x\n",
+ device_buckets[i].actual_gpu_id);
+ ret = -EINVAL;
+ goto exit;
+ }
+
+ pdd = kfd_get_process_device_data(dev, p);
+ if (!pdd) {
+ pr_err("Failed to get pdd for gpu_id = %x\n",
+ device_buckets[i].actual_gpu_id);
+ ret = -EINVAL;
+ goto exit;
+ }
+ pdd->user_gpu_id = device_buckets[i].user_gpu_id;
+
+ drm_file = fget(device_buckets[i].drm_fd);
+ if (!drm_file) {
+ pr_err("Invalid render node file descriptor sent from plugin (%d)\n",
+ device_buckets[i].drm_fd);
+ ret = -EINVAL;
+ goto exit;
+ }
+
+ if (pdd->drm_file) {
+ ret = -EINVAL;
+ goto exit;
+ }
+
+ /* create the vm using render nodes for kfd pdd */
+ if (kfd_process_device_init_vm(pdd, drm_file)) {
+ pr_err("could not init vm for given pdd\n");
+ /* On success, the PDD keeps the drm_file reference */
+ fput(drm_file);
+ ret = -EINVAL;
+ goto exit;
+ }
+ /*
+ * pdd now already has the vm bound to render node so below api won't create a new
+ * exclusive kfd mapping but use existing one with renderDXXX but is still needed
+ * for iommu v2 binding and runtime pm.
+ */
+ pdd = kfd_bind_process_to_device(dev, p);
+ if (IS_ERR(pdd)) {
+ ret = PTR_ERR(pdd);
+ goto exit;
+ }
+ }
+
+ /*
+ * We are not copying device private data from user as we are not using the data for now,
+ * but we still adjust for its private data.
+ */
+ *priv_offset += args->num_devices * sizeof(*device_privs);
+
+exit:
+ kfree(device_buckets);
+ return ret;
+}
+
+static int criu_restore_memory_of_gpu(struct kfd_process_device *pdd,
+ struct kfd_criu_bo_bucket *bo_bucket,
+ struct kfd_criu_bo_priv_data *bo_priv,
+ struct kgd_mem **kgd_mem)
+{
+ int idr_handle;
+ int ret;
+ const bool criu_resume = true;
+ u64 offset;
+
+ if (bo_bucket->alloc_flags & KFD_IOC_ALLOC_MEM_FLAGS_DOORBELL) {
+ if (bo_bucket->size != kfd_doorbell_process_slice(pdd->dev))
+ return -EINVAL;
+
+ offset = kfd_get_process_doorbells(pdd);
+ } else if (bo_bucket->alloc_flags & KFD_IOC_ALLOC_MEM_FLAGS_MMIO_REMAP) {
+ /* MMIO BOs need remapped bus address */
+ if (bo_bucket->size != PAGE_SIZE) {
+ pr_err("Invalid page size\n");
+ return -EINVAL;
+ }
+ offset = pdd->dev->adev->rmmio_remap.bus_addr;
+ if (!offset) {
+ pr_err("amdgpu_amdkfd_get_mmio_remap_phys_addr failed\n");
+ return -ENOMEM;
+ }
+ } else if (bo_bucket->alloc_flags & KFD_IOC_ALLOC_MEM_FLAGS_USERPTR) {
+ offset = bo_priv->user_addr;
+ }
+ /* Create the BO */
+ ret = amdgpu_amdkfd_gpuvm_alloc_memory_of_gpu(pdd->dev->adev, bo_bucket->addr,
+ bo_bucket->size, pdd->drm_priv, kgd_mem,
+ &offset, bo_bucket->alloc_flags, criu_resume);
+ if (ret) {
+ pr_err("Could not create the BO\n");
+ return ret;
+ }
+ pr_debug("New BO created: size:0x%llx addr:0x%llx offset:0x%llx\n",
+ bo_bucket->size, bo_bucket->addr, offset);
+
+ /* Restore previous IDR handle */
+ pr_debug("Restoring old IDR handle for the BO");
+ idr_handle = idr_alloc(&pdd->alloc_idr, *kgd_mem, bo_priv->idr_handle,
+ bo_priv->idr_handle + 1, GFP_KERNEL);
+
+ if (idr_handle < 0) {
+ pr_err("Could not allocate idr\n");
+ amdgpu_amdkfd_gpuvm_free_memory_of_gpu(pdd->dev->adev, *kgd_mem, pdd->drm_priv,
+ NULL);
+ return -ENOMEM;
+ }
+
+ if (bo_bucket->alloc_flags & KFD_IOC_ALLOC_MEM_FLAGS_DOORBELL)
+ bo_bucket->restored_offset = KFD_MMAP_TYPE_DOORBELL | KFD_MMAP_GPU_ID(pdd->dev->id);
+ if (bo_bucket->alloc_flags & KFD_IOC_ALLOC_MEM_FLAGS_MMIO_REMAP) {
+ bo_bucket->restored_offset = KFD_MMAP_TYPE_MMIO | KFD_MMAP_GPU_ID(pdd->dev->id);
+ } else if (bo_bucket->alloc_flags & KFD_IOC_ALLOC_MEM_FLAGS_GTT) {
+ bo_bucket->restored_offset = offset;
+ } else if (bo_bucket->alloc_flags & KFD_IOC_ALLOC_MEM_FLAGS_VRAM) {
+ bo_bucket->restored_offset = offset;
+ /* Update the VRAM usage count */
+ WRITE_ONCE(pdd->vram_usage, pdd->vram_usage + bo_bucket->size);
+ }
+ return 0;
+}
+
+static int criu_restore_bo(struct kfd_process *p,
+ struct kfd_criu_bo_bucket *bo_bucket,
+ struct kfd_criu_bo_priv_data *bo_priv)
+{
+ struct kfd_process_device *pdd;
+ struct kgd_mem *kgd_mem;
+ int ret;
+ int j;
+
+ pr_debug("Restoring BO size:0x%llx addr:0x%llx gpu_id:0x%x flags:0x%x idr_handle:0x%x\n",
+ bo_bucket->size, bo_bucket->addr, bo_bucket->gpu_id, bo_bucket->alloc_flags,
+ bo_priv->idr_handle);
+
+ pdd = kfd_process_device_data_by_id(p, bo_bucket->gpu_id);
+ if (!pdd) {
+ pr_err("Failed to get pdd\n");
+ return -ENODEV;
+ }
+
+ ret = criu_restore_memory_of_gpu(pdd, bo_bucket, bo_priv, &kgd_mem);
+ if (ret)
+ return ret;
+
+ /* now map these BOs to GPU/s */
+ for (j = 0; j < p->n_pdds; j++) {
+ struct kfd_dev *peer;
+ struct kfd_process_device *peer_pdd;
+
+ if (!bo_priv->mapped_gpuids[j])
+ break;
+
+ peer_pdd = kfd_process_device_data_by_id(p, bo_priv->mapped_gpuids[j]);
+ if (!peer_pdd)
+ return -EINVAL;
+
+ peer = peer_pdd->dev;
+
+ peer_pdd = kfd_bind_process_to_device(peer, p);
+ if (IS_ERR(peer_pdd))
+ return PTR_ERR(peer_pdd);
+
+ ret = amdgpu_amdkfd_gpuvm_map_memory_to_gpu(peer->adev, kgd_mem, peer_pdd->drm_priv,
+ NULL);
+ if (ret) {
+ pr_err("Failed to map to gpu %d/%d\n", j, p->n_pdds);
+ return ret;
+ }
+ }
+
+ pr_debug("map memory was successful for the BO\n");
+ /* create the dmabuf object and export the bo */
+ if (bo_bucket->alloc_flags
+ & (KFD_IOC_ALLOC_MEM_FLAGS_VRAM | KFD_IOC_ALLOC_MEM_FLAGS_GTT)) {
+ ret = criu_get_prime_handle(&kgd_mem->bo->tbo.base, DRM_RDWR,
+ &bo_bucket->dmabuf_fd);
+ if (ret)
+ return ret;
+ } else {
+ bo_bucket->dmabuf_fd = KFD_INVALID_FD;
+ }
+
+ return 0;
+}
+
+static int criu_restore_bos(struct kfd_process *p,
+ struct kfd_ioctl_criu_args *args,
+ uint64_t *priv_offset,
+ uint64_t max_priv_data_size)
+{
+ struct kfd_criu_bo_bucket *bo_buckets = NULL;
+ struct kfd_criu_bo_priv_data *bo_privs = NULL;
+ int ret = 0;
+ uint32_t i = 0;
+
+ if (*priv_offset + (args->num_bos * sizeof(*bo_privs)) > max_priv_data_size)
+ return -EINVAL;
+
+ /* Prevent MMU notifications until stage-4 IOCTL (CRIU_RESUME) is received */
+ amdgpu_amdkfd_block_mmu_notifications(p->kgd_process_info);
+
+ bo_buckets = kvmalloc_array(args->num_bos, sizeof(*bo_buckets), GFP_KERNEL);
+ if (!bo_buckets)
+ return -ENOMEM;
+
+ ret = copy_from_user(bo_buckets, (void __user *)args->bos,
+ args->num_bos * sizeof(*bo_buckets));
+ if (ret) {
+ pr_err("Failed to copy BOs information from user\n");
+ ret = -EFAULT;
+ goto exit;
+ }
+
+ bo_privs = kvmalloc_array(args->num_bos, sizeof(*bo_privs), GFP_KERNEL);
+ if (!bo_privs) {
+ ret = -ENOMEM;
+ goto exit;
+ }
+
+ ret = copy_from_user(bo_privs, (void __user *)args->priv_data + *priv_offset,
+ args->num_bos * sizeof(*bo_privs));
+ if (ret) {
+ pr_err("Failed to copy BOs information from user\n");
+ ret = -EFAULT;
+ goto exit;
+ }
+ *priv_offset += args->num_bos * sizeof(*bo_privs);
+
+ /* Create and map new BOs */
+ for (; i < args->num_bos; i++) {
+ ret = criu_restore_bo(p, &bo_buckets[i], &bo_privs[i]);
+ if (ret) {
+ pr_debug("Failed to restore BO[%d] ret%d\n", i, ret);
+ goto exit;
+ }
+ } /* done */
+
+ /* Copy only the buckets back so user can read bo_buckets[N].restored_offset */
+ ret = copy_to_user((void __user *)args->bos,
+ bo_buckets,
+ (args->num_bos * sizeof(*bo_buckets)));
+ if (ret)
+ ret = -EFAULT;
+
+exit:
+ while (ret && i--) {
+ if (bo_buckets[i].alloc_flags
+ & (KFD_IOC_ALLOC_MEM_FLAGS_VRAM | KFD_IOC_ALLOC_MEM_FLAGS_GTT))
+ close_fd(bo_buckets[i].dmabuf_fd);
+ }
+ kvfree(bo_buckets);
+ kvfree(bo_privs);
+ return ret;
+}
+
+static int criu_restore_objects(struct file *filep,
+ struct kfd_process *p,
+ struct kfd_ioctl_criu_args *args,
+ uint64_t *priv_offset,
+ uint64_t max_priv_data_size)
+{
+ int ret = 0;
+ uint32_t i;
+
+ BUILD_BUG_ON(offsetof(struct kfd_criu_queue_priv_data, object_type));
+ BUILD_BUG_ON(offsetof(struct kfd_criu_event_priv_data, object_type));
+ BUILD_BUG_ON(offsetof(struct kfd_criu_svm_range_priv_data, object_type));
+
+ for (i = 0; i < args->num_objects; i++) {
+ uint32_t object_type;
+
+ if (*priv_offset + sizeof(object_type) > max_priv_data_size) {
+ pr_err("Invalid private data size\n");
+ return -EINVAL;
+ }
+
+ ret = get_user(object_type, (uint32_t __user *)(args->priv_data + *priv_offset));
+ if (ret) {
+ pr_err("Failed to copy private information from user\n");
+ goto exit;
+ }
+
+ switch (object_type) {
+ case KFD_CRIU_OBJECT_TYPE_QUEUE:
+ ret = kfd_criu_restore_queue(p, (uint8_t __user *)args->priv_data,
+ priv_offset, max_priv_data_size);
+ if (ret)
+ goto exit;
+ break;
+ case KFD_CRIU_OBJECT_TYPE_EVENT:
+ ret = kfd_criu_restore_event(filep, p, (uint8_t __user *)args->priv_data,
+ priv_offset, max_priv_data_size);
+ if (ret)
+ goto exit;
+ break;
+ case KFD_CRIU_OBJECT_TYPE_SVM_RANGE:
+ ret = kfd_criu_restore_svm(p, (uint8_t __user *)args->priv_data,
+ priv_offset, max_priv_data_size);
+ if (ret)
+ goto exit;
+ break;
+ default:
+ pr_err("Invalid object type:%u at index:%d\n", object_type, i);
+ ret = -EINVAL;
+ goto exit;
+ }
+ }
+exit:
+ return ret;
+}
+
+static int criu_restore(struct file *filep,
+ struct kfd_process *p,
+ struct kfd_ioctl_criu_args *args)
+{
+ uint64_t priv_offset = 0;
+ int ret = 0;
+
+ pr_debug("CRIU restore (num_devices:%u num_bos:%u num_objects:%u priv_data_size:%llu)\n",
+ args->num_devices, args->num_bos, args->num_objects, args->priv_data_size);
+
+ if (!args->bos || !args->devices || !args->priv_data || !args->priv_data_size ||
+ !args->num_devices || !args->num_bos)
+ return -EINVAL;
+
+ mutex_lock(&p->mutex);
+
+ /*
+ * Set the process to evicted state to avoid running any new queues before all the memory
+ * mappings are ready.
+ */
+ ret = kfd_process_evict_queues(p);
+ if (ret)
+ goto exit_unlock;
+
+ /* Each function will adjust priv_offset based on how many bytes they consumed */
+ ret = criu_restore_process(p, args, &priv_offset, args->priv_data_size);
+ if (ret)
+ goto exit_unlock;
+
+ ret = criu_restore_devices(p, args, &priv_offset, args->priv_data_size);
+ if (ret)
+ goto exit_unlock;
+
+ ret = criu_restore_bos(p, args, &priv_offset, args->priv_data_size);
+ if (ret)
+ goto exit_unlock;
+
+ ret = criu_restore_objects(filep, p, args, &priv_offset, args->priv_data_size);
+ if (ret)
+ goto exit_unlock;
+
+ if (priv_offset != args->priv_data_size) {
+ pr_err("Invalid private data size\n");
+ ret = -EINVAL;
+ }
+
+exit_unlock:
+ mutex_unlock(&p->mutex);
+ if (ret)
+ pr_err("Failed to restore CRIU ret:%d\n", ret);
+ else
+ pr_debug("CRIU restore successful\n");
+
+ return ret;
+}
+
+static int criu_unpause(struct file *filep,
+ struct kfd_process *p,
+ struct kfd_ioctl_criu_args *args)
+{
+ int ret;
+
+ mutex_lock(&p->mutex);
+
+ if (!p->queues_paused) {
+ mutex_unlock(&p->mutex);
+ return -EINVAL;
+ }
+
+ ret = kfd_process_restore_queues(p);
+ if (ret)
+ pr_err("Failed to unpause queues ret:%d\n", ret);
+ else
+ p->queues_paused = false;
+
+ mutex_unlock(&p->mutex);
+
+ return ret;
+}
+
+static int criu_resume(struct file *filep,
+ struct kfd_process *p,
+ struct kfd_ioctl_criu_args *args)
+{
+ struct kfd_process *target = NULL;
+ struct pid *pid = NULL;
+ int ret = 0;
+
+ pr_debug("Inside %s, target pid for criu restore: %d\n", __func__,
+ args->pid);
+
+ pid = find_get_pid(args->pid);
+ if (!pid) {
+ pr_err("Cannot find pid info for %i\n", args->pid);
+ return -ESRCH;
+ }
+
+ pr_debug("calling kfd_lookup_process_by_pid\n");
+ target = kfd_lookup_process_by_pid(pid);
+
+ put_pid(pid);
+
+ if (!target) {
+ pr_debug("Cannot find process info for %i\n", args->pid);
+ return -ESRCH;
+ }
+
+ mutex_lock(&target->mutex);
+ ret = kfd_criu_resume_svm(target);
+ if (ret) {
+ pr_err("kfd_criu_resume_svm failed for %i\n", args->pid);
+ goto exit;
+ }
+
+ ret = amdgpu_amdkfd_criu_resume(target->kgd_process_info);
+ if (ret)
+ pr_err("amdgpu_amdkfd_criu_resume failed for %i\n", args->pid);
+
+exit:
+ mutex_unlock(&target->mutex);
+
+ kfd_unref_process(target);
+ return ret;
+}
+
+static int criu_process_info(struct file *filep,
+ struct kfd_process *p,
+ struct kfd_ioctl_criu_args *args)
+{
+ int ret = 0;
+
+ mutex_lock(&p->mutex);
+
+ if (!p->n_pdds) {
+ pr_err("No pdd for given process\n");
+ ret = -ENODEV;
+ goto err_unlock;
+ }
+
+ ret = kfd_process_evict_queues(p);
+ if (ret)
+ goto err_unlock;
+
+ p->queues_paused = true;
+
+ args->pid = task_pid_nr_ns(p->lead_thread,
+ task_active_pid_ns(p->lead_thread));
+
+ ret = criu_get_process_object_info(p, &args->num_devices, &args->num_bos,
+ &args->num_objects, &args->priv_data_size);
+ if (ret)
+ goto err_unlock;
+
+ dev_dbg(kfd_device, "Num of devices:%u bos:%u objects:%u priv_data_size:%lld\n",
+ args->num_devices, args->num_bos, args->num_objects,
+ args->priv_data_size);
+
+err_unlock:
+ if (ret) {
+ kfd_process_restore_queues(p);
+ p->queues_paused = false;
+ }
+ mutex_unlock(&p->mutex);
+ return ret;
+}
+
+static int kfd_ioctl_criu(struct file *filep, struct kfd_process *p, void *data)
+{
+ struct kfd_ioctl_criu_args *args = data;
+ int ret;
+
+ dev_dbg(kfd_device, "CRIU operation: %d\n", args->op);
+ switch (args->op) {
+ case KFD_CRIU_OP_PROCESS_INFO:
+ ret = criu_process_info(filep, p, args);
+ break;
+ case KFD_CRIU_OP_CHECKPOINT:
+ ret = criu_checkpoint(filep, p, args);
+ break;
+ case KFD_CRIU_OP_UNPAUSE:
+ ret = criu_unpause(filep, p, args);
+ break;
+ case KFD_CRIU_OP_RESTORE:
+ ret = criu_restore(filep, p, args);
+ break;
+ case KFD_CRIU_OP_RESUME:
+ ret = criu_resume(filep, p, args);
+ break;
+ default:
+ dev_dbg(kfd_device, "Unsupported CRIU operation:%d\n", args->op);
+ ret = -EINVAL;
+ break;
+ }
+
+ if (ret)
+ dev_dbg(kfd_device, "CRIU operation:%d err:%d\n", args->op, ret);
+
+ return ret;
+}
+
#define AMDKFD_IOCTL_DEF(ioctl, _func, _flags) \
[_IOC_NR(ioctl)] = {.cmd = ioctl, .func = _func, .flags = _flags, \
.cmd_drv = 0, .name = #ioctl}
@@ -1898,16 +2597,16 @@ static const struct amdkfd_ioctl_desc amdkfd_ioctls[] = {
AMDKFD_IOCTL_DEF(AMDKFD_IOC_WAIT_EVENTS,
kfd_ioctl_wait_events, 0),
- AMDKFD_IOCTL_DEF(AMDKFD_IOC_DBG_REGISTER,
+ AMDKFD_IOCTL_DEF(AMDKFD_IOC_DBG_REGISTER_DEPRECATED,
kfd_ioctl_dbg_register, 0),
- AMDKFD_IOCTL_DEF(AMDKFD_IOC_DBG_UNREGISTER,
+ AMDKFD_IOCTL_DEF(AMDKFD_IOC_DBG_UNREGISTER_DEPRECATED,
kfd_ioctl_dbg_unregister, 0),
- AMDKFD_IOCTL_DEF(AMDKFD_IOC_DBG_ADDRESS_WATCH,
+ AMDKFD_IOCTL_DEF(AMDKFD_IOC_DBG_ADDRESS_WATCH_DEPRECATED,
kfd_ioctl_dbg_address_watch, 0),
- AMDKFD_IOCTL_DEF(AMDKFD_IOC_DBG_WAVE_CONTROL,
+ AMDKFD_IOCTL_DEF(AMDKFD_IOC_DBG_WAVE_CONTROL_DEPRECATED,
kfd_ioctl_dbg_wave_control, 0),
AMDKFD_IOCTL_DEF(AMDKFD_IOC_SET_SCRATCH_BACKING_VA,
@@ -1959,6 +2658,10 @@ static const struct amdkfd_ioctl_desc amdkfd_ioctls[] = {
AMDKFD_IOCTL_DEF(AMDKFD_IOC_SET_XNACK_MODE,
kfd_ioctl_set_xnack_mode, 0),
+
+ AMDKFD_IOCTL_DEF(AMDKFD_IOC_CRIU_OP,
+ kfd_ioctl_criu, KFD_IOC_FLAG_CHECKPOINT_RESTORE),
+
};
#define AMDKFD_CORE_IOCTL_COUNT ARRAY_SIZE(amdkfd_ioctls)
@@ -1973,6 +2676,7 @@ static long kfd_ioctl(struct file *filep, unsigned int cmd, unsigned long arg)
char *kdata = NULL;
unsigned int usize, asize;
int retcode = -EINVAL;
+ bool ptrace_attached = false;
if (nr >= AMDKFD_CORE_IOCTL_COUNT)
goto err_i1;
@@ -1998,7 +2702,15 @@ static long kfd_ioctl(struct file *filep, unsigned int cmd, unsigned long arg)
* processes need to create their own KFD device context.
*/
process = filep->private_data;
- if (process->lead_thread != current->group_leader) {
+
+ rcu_read_lock();
+ if ((ioctl->flags & KFD_IOC_FLAG_CHECKPOINT_RESTORE) &&
+ ptrace_parent(process->lead_thread) == current)
+ ptrace_attached = true;
+ rcu_read_unlock();
+
+ if (process->lead_thread != current->group_leader
+ && !ptrace_attached) {
dev_dbg(kfd_device, "Using KFD FD in wrong process\n");
retcode = -EBADF;
goto err_i1;
@@ -2013,6 +2725,19 @@ static long kfd_ioctl(struct file *filep, unsigned int cmd, unsigned long arg)
goto err_i1;
}
+ /*
+ * Versions of docker shipped in Ubuntu 18.xx and 20.xx do not support
+ * CAP_CHECKPOINT_RESTORE, so we also allow access if CAP_SYS_ADMIN as CAP_SYS_ADMIN is a
+ * more priviledged access.
+ */
+ if (unlikely(ioctl->flags & KFD_IOC_FLAG_CHECKPOINT_RESTORE)) {
+ if (!capable(CAP_CHECKPOINT_RESTORE) &&
+ !capable(CAP_SYS_ADMIN)) {
+ retcode = -EACCES;
+ goto err_i1;
+ }
+ }
+
if (cmd & (IOC_IN | IOC_OUT)) {
if (asize <= sizeof(stack_kdata)) {
kdata = stack_kdata;
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_crat.c b/drivers/gpu/drm/amd/amdkfd/kfd_crat.c
index 9624bbe8b501..1eaabd2cb41b 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_crat.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_crat.c
@@ -1,5 +1,6 @@
+// SPDX-License-Identifier: GPL-2.0 OR MIT
/*
- * Copyright 2015-2017 Advanced Micro Devices, Inc.
+ * Copyright 2015-2022 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@@ -1381,7 +1382,7 @@ static int kfd_fill_gpu_cache_info(struct kfd_dev *kdev,
num_of_cache_types = ARRAY_SIZE(vegam_cache_info);
break;
default:
- switch(KFD_GC_VERSION(kdev)) {
+ switch (KFD_GC_VERSION(kdev)) {
case IP_VERSION(9, 0, 1):
pcache_info = vega10_cache_info;
num_of_cache_types = ARRAY_SIZE(vega10_cache_info);
@@ -1411,6 +1412,7 @@ static int kfd_fill_gpu_cache_info(struct kfd_dev *kdev,
case IP_VERSION(10, 1, 10):
case IP_VERSION(10, 1, 2):
case IP_VERSION(10, 1, 3):
+ case IP_VERSION(10, 1, 4):
pcache_info = navi10_cache_info;
num_of_cache_types = ARRAY_SIZE(navi10_cache_info);
break;
@@ -1567,7 +1569,7 @@ int kfd_create_crat_image_acpi(void **crat_image, size_t *size)
/* Fetch the CRAT table from ACPI */
status = acpi_get_table(CRAT_SIGNATURE, 0, &crat_table);
if (status == AE_NOT_FOUND) {
- pr_warn("CRAT table not found\n");
+ pr_info("CRAT table not found\n");
return -ENODATA;
} else if (ACPI_FAILURE(status)) {
const char *err = acpi_format_exception(status);
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_crat.h b/drivers/gpu/drm/amd/amdkfd/kfd_crat.h
index d54ceebd346b..482ba84a728d 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_crat.h
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_crat.h
@@ -1,5 +1,6 @@
+/* SPDX-License-Identifier: GPL-2.0 OR MIT */
/*
- * Copyright 2014 Advanced Micro Devices, Inc.
+ * Copyright 2014-2022 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@@ -232,7 +233,7 @@ struct crat_subtype_ccompute {
#define CRAT_IOLINK_FLAGS_NO_ATOMICS_32_BIT (1 << 2)
#define CRAT_IOLINK_FLAGS_NO_ATOMICS_64_BIT (1 << 3)
#define CRAT_IOLINK_FLAGS_NO_PEER_TO_PEER_DMA (1 << 4)
-#define CRAT_IOLINK_FLAGS_BI_DIRECTIONAL (1 << 31)
+#define CRAT_IOLINK_FLAGS_BI_DIRECTIONAL (1 << 31)
#define CRAT_IOLINK_FLAGS_RESERVED_MASK 0x7fffffe0
/*
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_dbgdev.c b/drivers/gpu/drm/amd/amdkfd/kfd_dbgdev.c
deleted file mode 100644
index 1e30717b5253..000000000000
--- a/drivers/gpu/drm/amd/amdkfd/kfd_dbgdev.c
+++ /dev/null
@@ -1,845 +0,0 @@
-/*
- * Copyright 2014 Advanced Micro Devices, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- */
-
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/log2.h>
-#include <linux/sched.h>
-#include <linux/slab.h>
-#include <linux/mutex.h>
-#include <linux/device.h>
-
-#include "kfd_pm4_headers.h"
-#include "kfd_pm4_headers_diq.h"
-#include "kfd_kernel_queue.h"
-#include "kfd_priv.h"
-#include "kfd_pm4_opcodes.h"
-#include "cik_regs.h"
-#include "kfd_dbgmgr.h"
-#include "kfd_dbgdev.h"
-#include "kfd_device_queue_manager.h"
-
-static void dbgdev_address_watch_disable_nodiq(struct kfd_dev *dev)
-{
- dev->kfd2kgd->address_watch_disable(dev->adev);
-}
-
-static int dbgdev_diq_submit_ib(struct kfd_dbgdev *dbgdev,
- u32 pasid, uint64_t vmid0_address,
- uint32_t *packet_buff, size_t size_in_bytes)
-{
- struct pm4__release_mem *rm_packet;
- struct pm4__indirect_buffer_pasid *ib_packet;
- struct kfd_mem_obj *mem_obj;
- size_t pq_packets_size_in_bytes;
- union ULARGE_INTEGER *largep;
- union ULARGE_INTEGER addr;
- struct kernel_queue *kq;
- uint64_t *rm_state;
- unsigned int *ib_packet_buff;
- int status;
-
- if (WARN_ON(!size_in_bytes))
- return -EINVAL;
-
- kq = dbgdev->kq;
-
- pq_packets_size_in_bytes = sizeof(struct pm4__release_mem) +
- sizeof(struct pm4__indirect_buffer_pasid);
-
- /*
- * We acquire a buffer from DIQ
- * The receive packet buff will be sitting on the Indirect Buffer
- * and in the PQ we put the IB packet + sync packet(s).
- */
- status = kq_acquire_packet_buffer(kq,
- pq_packets_size_in_bytes / sizeof(uint32_t),
- &ib_packet_buff);
- if (status) {
- pr_err("kq_acquire_packet_buffer failed\n");
- return status;
- }
-
- memset(ib_packet_buff, 0, pq_packets_size_in_bytes);
-
- ib_packet = (struct pm4__indirect_buffer_pasid *) (ib_packet_buff);
-
- ib_packet->header.count = 3;
- ib_packet->header.opcode = IT_INDIRECT_BUFFER_PASID;
- ib_packet->header.type = PM4_TYPE_3;
-
- largep = (union ULARGE_INTEGER *) &vmid0_address;
-
- ib_packet->bitfields2.ib_base_lo = largep->u.low_part >> 2;
- ib_packet->bitfields3.ib_base_hi = largep->u.high_part;
-
- ib_packet->control = (1 << 23) | (1 << 31) |
- ((size_in_bytes / 4) & 0xfffff);
-
- ib_packet->bitfields5.pasid = pasid;
-
- /*
- * for now we use release mem for GPU-CPU synchronization
- * Consider WaitRegMem + WriteData as a better alternative
- * we get a GART allocations ( gpu/cpu mapping),
- * for the sync variable, and wait until:
- * (a) Sync with HW
- * (b) Sync var is written by CP to mem.
- */
- rm_packet = (struct pm4__release_mem *) (ib_packet_buff +
- (sizeof(struct pm4__indirect_buffer_pasid) /
- sizeof(unsigned int)));
-
- status = kfd_gtt_sa_allocate(dbgdev->dev, sizeof(uint64_t),
- &mem_obj);
-
- if (status) {
- pr_err("Failed to allocate GART memory\n");
- kq_rollback_packet(kq);
- return status;
- }
-
- rm_state = (uint64_t *) mem_obj->cpu_ptr;
-
- *rm_state = QUEUESTATE__ACTIVE_COMPLETION_PENDING;
-
- rm_packet->header.opcode = IT_RELEASE_MEM;
- rm_packet->header.type = PM4_TYPE_3;
- rm_packet->header.count = sizeof(struct pm4__release_mem) / 4 - 2;
-
- rm_packet->bitfields2.event_type = CACHE_FLUSH_AND_INV_TS_EVENT;
- rm_packet->bitfields2.event_index =
- event_index___release_mem__end_of_pipe;
-
- rm_packet->bitfields2.cache_policy = cache_policy___release_mem__lru;
- rm_packet->bitfields2.atc = 0;
- rm_packet->bitfields2.tc_wb_action_ena = 1;
-
- addr.quad_part = mem_obj->gpu_addr;
-
- rm_packet->bitfields4.address_lo_32b = addr.u.low_part >> 2;
- rm_packet->address_hi = addr.u.high_part;
-
- rm_packet->bitfields3.data_sel =
- data_sel___release_mem__send_64_bit_data;
-
- rm_packet->bitfields3.int_sel =
- int_sel___release_mem__send_data_after_write_confirm;
-
- rm_packet->bitfields3.dst_sel =
- dst_sel___release_mem__memory_controller;
-
- rm_packet->data_lo = QUEUESTATE__ACTIVE;
-
- kq_submit_packet(kq);
-
- /* Wait till CP writes sync code: */
- status = amdkfd_fence_wait_timeout(
- rm_state,
- QUEUESTATE__ACTIVE, 1500);
-
- kfd_gtt_sa_free(dbgdev->dev, mem_obj);
-
- return status;
-}
-
-static int dbgdev_register_nodiq(struct kfd_dbgdev *dbgdev)
-{
- /*
- * no action is needed in this case,
- * just make sure diq will not be used
- */
-
- dbgdev->kq = NULL;
-
- return 0;
-}
-
-static int dbgdev_register_diq(struct kfd_dbgdev *dbgdev)
-{
- struct queue_properties properties;
- unsigned int qid;
- struct kernel_queue *kq = NULL;
- int status;
-
- properties.type = KFD_QUEUE_TYPE_DIQ;
-
- status = pqm_create_queue(dbgdev->pqm, dbgdev->dev, NULL,
- &properties, &qid, NULL);
-
- if (status) {
- pr_err("Failed to create DIQ\n");
- return status;
- }
-
- pr_debug("DIQ Created with queue id: %d\n", qid);
-
- kq = pqm_get_kernel_queue(dbgdev->pqm, qid);
-
- if (!kq) {
- pr_err("Error getting DIQ\n");
- pqm_destroy_queue(dbgdev->pqm, qid);
- return -EFAULT;
- }
-
- dbgdev->kq = kq;
-
- return status;
-}
-
-static int dbgdev_unregister_nodiq(struct kfd_dbgdev *dbgdev)
-{
- /* disable watch address */
- dbgdev_address_watch_disable_nodiq(dbgdev->dev);
- return 0;
-}
-
-static int dbgdev_unregister_diq(struct kfd_dbgdev *dbgdev)
-{
- /* todo - disable address watch */
- int status;
-
- status = pqm_destroy_queue(dbgdev->pqm,
- dbgdev->kq->queue->properties.queue_id);
- dbgdev->kq = NULL;
-
- return status;
-}
-
-static void dbgdev_address_watch_set_registers(
- const struct dbg_address_watch_info *adw_info,
- union TCP_WATCH_ADDR_H_BITS *addrHi,
- union TCP_WATCH_ADDR_L_BITS *addrLo,
- union TCP_WATCH_CNTL_BITS *cntl,
- unsigned int index, unsigned int vmid)
-{
- union ULARGE_INTEGER addr;
-
- addr.quad_part = 0;
- addrHi->u32All = 0;
- addrLo->u32All = 0;
- cntl->u32All = 0;
-
- if (adw_info->watch_mask)
- cntl->bitfields.mask =
- (uint32_t) (adw_info->watch_mask[index] &
- ADDRESS_WATCH_REG_CNTL_DEFAULT_MASK);
- else
- cntl->bitfields.mask = ADDRESS_WATCH_REG_CNTL_DEFAULT_MASK;
-
- addr.quad_part = (unsigned long long) adw_info->watch_address[index];
-
- addrHi->bitfields.addr = addr.u.high_part &
- ADDRESS_WATCH_REG_ADDHIGH_MASK;
- addrLo->bitfields.addr =
- (addr.u.low_part >> ADDRESS_WATCH_REG_ADDLOW_SHIFT);
-
- cntl->bitfields.mode = adw_info->watch_mode[index];
- cntl->bitfields.vmid = (uint32_t) vmid;
- /* for now assume it is an ATC address */
- cntl->u32All |= ADDRESS_WATCH_REG_CNTL_ATC_BIT;
-
- pr_debug("\t\t%20s %08x\n", "set reg mask :", cntl->bitfields.mask);
- pr_debug("\t\t%20s %08x\n", "set reg add high :",
- addrHi->bitfields.addr);
- pr_debug("\t\t%20s %08x\n", "set reg add low :",
- addrLo->bitfields.addr);
-}
-
-static int dbgdev_address_watch_nodiq(struct kfd_dbgdev *dbgdev,
- struct dbg_address_watch_info *adw_info)
-{
- union TCP_WATCH_ADDR_H_BITS addrHi;
- union TCP_WATCH_ADDR_L_BITS addrLo;
- union TCP_WATCH_CNTL_BITS cntl;
- struct kfd_process_device *pdd;
- unsigned int i;
-
- /* taking the vmid for that process on the safe way using pdd */
- pdd = kfd_get_process_device_data(dbgdev->dev,
- adw_info->process);
- if (!pdd) {
- pr_err("Failed to get pdd for wave control no DIQ\n");
- return -EFAULT;
- }
-
- addrHi.u32All = 0;
- addrLo.u32All = 0;
- cntl.u32All = 0;
-
- if ((adw_info->num_watch_points > MAX_WATCH_ADDRESSES) ||
- (adw_info->num_watch_points == 0)) {
- pr_err("num_watch_points is invalid\n");
- return -EINVAL;
- }
-
- if (!adw_info->watch_mode || !adw_info->watch_address) {
- pr_err("adw_info fields are not valid\n");
- return -EINVAL;
- }
-
- for (i = 0; i < adw_info->num_watch_points; i++) {
- dbgdev_address_watch_set_registers(adw_info, &addrHi, &addrLo,
- &cntl, i, pdd->qpd.vmid);
-
- pr_debug("\t\t%30s\n", "* * * * * * * * * * * * * * * * * *");
- pr_debug("\t\t%20s %08x\n", "register index :", i);
- pr_debug("\t\t%20s %08x\n", "vmid is :", pdd->qpd.vmid);
- pr_debug("\t\t%20s %08x\n", "Address Low is :",
- addrLo.bitfields.addr);
- pr_debug("\t\t%20s %08x\n", "Address high is :",
- addrHi.bitfields.addr);
- pr_debug("\t\t%20s %08x\n", "Address high is :",
- addrHi.bitfields.addr);
- pr_debug("\t\t%20s %08x\n", "Control Mask is :",
- cntl.bitfields.mask);
- pr_debug("\t\t%20s %08x\n", "Control Mode is :",
- cntl.bitfields.mode);
- pr_debug("\t\t%20s %08x\n", "Control Vmid is :",
- cntl.bitfields.vmid);
- pr_debug("\t\t%20s %08x\n", "Control atc is :",
- cntl.bitfields.atc);
- pr_debug("\t\t%30s\n", "* * * * * * * * * * * * * * * * * *");
-
- pdd->dev->kfd2kgd->address_watch_execute(
- dbgdev->dev->adev,
- i,
- cntl.u32All,
- addrHi.u32All,
- addrLo.u32All);
- }
-
- return 0;
-}
-
-static int dbgdev_address_watch_diq(struct kfd_dbgdev *dbgdev,
- struct dbg_address_watch_info *adw_info)
-{
- struct pm4__set_config_reg *packets_vec;
- union TCP_WATCH_ADDR_H_BITS addrHi;
- union TCP_WATCH_ADDR_L_BITS addrLo;
- union TCP_WATCH_CNTL_BITS cntl;
- struct kfd_mem_obj *mem_obj;
- unsigned int aw_reg_add_dword;
- uint32_t *packet_buff_uint;
- unsigned int i;
- int status;
- size_t ib_size = sizeof(struct pm4__set_config_reg) * 4;
- /* we do not control the vmid in DIQ mode, just a place holder */
- unsigned int vmid = 0;
-
- addrHi.u32All = 0;
- addrLo.u32All = 0;
- cntl.u32All = 0;
-
- if ((adw_info->num_watch_points > MAX_WATCH_ADDRESSES) ||
- (adw_info->num_watch_points == 0)) {
- pr_err("num_watch_points is invalid\n");
- return -EINVAL;
- }
-
- if (!adw_info->watch_mode || !adw_info->watch_address) {
- pr_err("adw_info fields are not valid\n");
- return -EINVAL;
- }
-
- status = kfd_gtt_sa_allocate(dbgdev->dev, ib_size, &mem_obj);
-
- if (status) {
- pr_err("Failed to allocate GART memory\n");
- return status;
- }
-
- packet_buff_uint = mem_obj->cpu_ptr;
-
- memset(packet_buff_uint, 0, ib_size);
-
- packets_vec = (struct pm4__set_config_reg *) (packet_buff_uint);
-
- packets_vec[0].header.count = 1;
- packets_vec[0].header.opcode = IT_SET_CONFIG_REG;
- packets_vec[0].header.type = PM4_TYPE_3;
- packets_vec[0].bitfields2.vmid_shift = ADDRESS_WATCH_CNTL_OFFSET;
- packets_vec[0].bitfields2.insert_vmid = 1;
- packets_vec[1].ordinal1 = packets_vec[0].ordinal1;
- packets_vec[1].bitfields2.insert_vmid = 0;
- packets_vec[2].ordinal1 = packets_vec[0].ordinal1;
- packets_vec[2].bitfields2.insert_vmid = 0;
- packets_vec[3].ordinal1 = packets_vec[0].ordinal1;
- packets_vec[3].bitfields2.vmid_shift = ADDRESS_WATCH_CNTL_OFFSET;
- packets_vec[3].bitfields2.insert_vmid = 1;
-
- for (i = 0; i < adw_info->num_watch_points; i++) {
- dbgdev_address_watch_set_registers(adw_info,
- &addrHi,
- &addrLo,
- &cntl,
- i,
- vmid);
-
- pr_debug("\t\t%30s\n", "* * * * * * * * * * * * * * * * * *");
- pr_debug("\t\t%20s %08x\n", "register index :", i);
- pr_debug("\t\t%20s %08x\n", "vmid is :", vmid);
- pr_debug("\t\t%20s %p\n", "Add ptr is :",
- adw_info->watch_address);
- pr_debug("\t\t%20s %08llx\n", "Add is :",
- adw_info->watch_address[i]);
- pr_debug("\t\t%20s %08x\n", "Address Low is :",
- addrLo.bitfields.addr);
- pr_debug("\t\t%20s %08x\n", "Address high is :",
- addrHi.bitfields.addr);
- pr_debug("\t\t%20s %08x\n", "Control Mask is :",
- cntl.bitfields.mask);
- pr_debug("\t\t%20s %08x\n", "Control Mode is :",
- cntl.bitfields.mode);
- pr_debug("\t\t%20s %08x\n", "Control Vmid is :",
- cntl.bitfields.vmid);
- pr_debug("\t\t%20s %08x\n", "Control atc is :",
- cntl.bitfields.atc);
- pr_debug("\t\t%30s\n", "* * * * * * * * * * * * * * * * * *");
-
- aw_reg_add_dword =
- dbgdev->dev->kfd2kgd->address_watch_get_offset(
- dbgdev->dev->adev,
- i,
- ADDRESS_WATCH_REG_CNTL);
-
- packets_vec[0].bitfields2.reg_offset =
- aw_reg_add_dword - AMD_CONFIG_REG_BASE;
-
- packets_vec[0].reg_data[0] = cntl.u32All;
-
- aw_reg_add_dword =
- dbgdev->dev->kfd2kgd->address_watch_get_offset(
- dbgdev->dev->adev,
- i,
- ADDRESS_WATCH_REG_ADDR_HI);
-
- packets_vec[1].bitfields2.reg_offset =
- aw_reg_add_dword - AMD_CONFIG_REG_BASE;
- packets_vec[1].reg_data[0] = addrHi.u32All;
-
- aw_reg_add_dword =
- dbgdev->dev->kfd2kgd->address_watch_get_offset(
- dbgdev->dev->adev,
- i,
- ADDRESS_WATCH_REG_ADDR_LO);
-
- packets_vec[2].bitfields2.reg_offset =
- aw_reg_add_dword - AMD_CONFIG_REG_BASE;
- packets_vec[2].reg_data[0] = addrLo.u32All;
-
- /* enable watch flag if address is not zero*/
- if (adw_info->watch_address[i] > 0)
- cntl.bitfields.valid = 1;
- else
- cntl.bitfields.valid = 0;
-
- aw_reg_add_dword =
- dbgdev->dev->kfd2kgd->address_watch_get_offset(
- dbgdev->dev->adev,
- i,
- ADDRESS_WATCH_REG_CNTL);
-
- packets_vec[3].bitfields2.reg_offset =
- aw_reg_add_dword - AMD_CONFIG_REG_BASE;
- packets_vec[3].reg_data[0] = cntl.u32All;
-
- status = dbgdev_diq_submit_ib(
- dbgdev,
- adw_info->process->pasid,
- mem_obj->gpu_addr,
- packet_buff_uint,
- ib_size);
-
- if (status) {
- pr_err("Failed to submit IB to DIQ\n");
- break;
- }
- }
-
- kfd_gtt_sa_free(dbgdev->dev, mem_obj);
- return status;
-}
-
-static int dbgdev_wave_control_set_registers(
- struct dbg_wave_control_info *wac_info,
- union SQ_CMD_BITS *in_reg_sq_cmd,
- union GRBM_GFX_INDEX_BITS *in_reg_gfx_index)
-{
- int status = 0;
- union SQ_CMD_BITS reg_sq_cmd;
- union GRBM_GFX_INDEX_BITS reg_gfx_index;
- struct HsaDbgWaveMsgAMDGen2 *pMsg;
-
- reg_sq_cmd.u32All = 0;
- reg_gfx_index.u32All = 0;
- pMsg = &wac_info->dbgWave_msg.DbgWaveMsg.WaveMsgInfoGen2;
-
- switch (wac_info->mode) {
- /* Send command to single wave */
- case HSA_DBG_WAVEMODE_SINGLE:
- /*
- * Limit access to the process waves only,
- * by setting vmid check
- */
- reg_sq_cmd.bits.check_vmid = 1;
- reg_sq_cmd.bits.simd_id = pMsg->ui32.SIMD;
- reg_sq_cmd.bits.wave_id = pMsg->ui32.WaveId;
- reg_sq_cmd.bits.mode = SQ_IND_CMD_MODE_SINGLE;
-
- reg_gfx_index.bits.sh_index = pMsg->ui32.ShaderArray;
- reg_gfx_index.bits.se_index = pMsg->ui32.ShaderEngine;
- reg_gfx_index.bits.instance_index = pMsg->ui32.HSACU;
-
- break;
-
- /* Send command to all waves with matching VMID */
- case HSA_DBG_WAVEMODE_BROADCAST_PROCESS:
-
- reg_gfx_index.bits.sh_broadcast_writes = 1;
- reg_gfx_index.bits.se_broadcast_writes = 1;
- reg_gfx_index.bits.instance_broadcast_writes = 1;
-
- reg_sq_cmd.bits.mode = SQ_IND_CMD_MODE_BROADCAST;
-
- break;
-
- /* Send command to all CU waves with matching VMID */
- case HSA_DBG_WAVEMODE_BROADCAST_PROCESS_CU:
-
- reg_sq_cmd.bits.check_vmid = 1;
- reg_sq_cmd.bits.mode = SQ_IND_CMD_MODE_BROADCAST;
-
- reg_gfx_index.bits.sh_index = pMsg->ui32.ShaderArray;
- reg_gfx_index.bits.se_index = pMsg->ui32.ShaderEngine;
- reg_gfx_index.bits.instance_index = pMsg->ui32.HSACU;
-
- break;
-
- default:
- return -EINVAL;
- }
-
- switch (wac_info->operand) {
- case HSA_DBG_WAVEOP_HALT:
- reg_sq_cmd.bits.cmd = SQ_IND_CMD_CMD_HALT;
- break;
-
- case HSA_DBG_WAVEOP_RESUME:
- reg_sq_cmd.bits.cmd = SQ_IND_CMD_CMD_RESUME;
- break;
-
- case HSA_DBG_WAVEOP_KILL:
- reg_sq_cmd.bits.cmd = SQ_IND_CMD_CMD_KILL;
- break;
-
- case HSA_DBG_WAVEOP_DEBUG:
- reg_sq_cmd.bits.cmd = SQ_IND_CMD_CMD_DEBUG;
- break;
-
- case HSA_DBG_WAVEOP_TRAP:
- if (wac_info->trapId < MAX_TRAPID) {
- reg_sq_cmd.bits.cmd = SQ_IND_CMD_CMD_TRAP;
- reg_sq_cmd.bits.trap_id = wac_info->trapId;
- } else {
- status = -EINVAL;
- }
- break;
-
- default:
- status = -EINVAL;
- break;
- }
-
- if (status == 0) {
- *in_reg_sq_cmd = reg_sq_cmd;
- *in_reg_gfx_index = reg_gfx_index;
- }
-
- return status;
-}
-
-static int dbgdev_wave_control_diq(struct kfd_dbgdev *dbgdev,
- struct dbg_wave_control_info *wac_info)
-{
-
- int status;
- union SQ_CMD_BITS reg_sq_cmd;
- union GRBM_GFX_INDEX_BITS reg_gfx_index;
- struct kfd_mem_obj *mem_obj;
- uint32_t *packet_buff_uint;
- struct pm4__set_config_reg *packets_vec;
- size_t ib_size = sizeof(struct pm4__set_config_reg) * 3;
-
- reg_sq_cmd.u32All = 0;
-
- status = dbgdev_wave_control_set_registers(wac_info, &reg_sq_cmd,
- &reg_gfx_index);
- if (status) {
- pr_err("Failed to set wave control registers\n");
- return status;
- }
-
- /* we do not control the VMID in DIQ, so reset it to a known value */
- reg_sq_cmd.bits.vm_id = 0;
-
- pr_debug("\t\t %30s\n", "* * * * * * * * * * * * * * * * * *");
-
- pr_debug("\t\t mode is: %u\n", wac_info->mode);
- pr_debug("\t\t operand is: %u\n", wac_info->operand);
- pr_debug("\t\t trap id is: %u\n", wac_info->trapId);
- pr_debug("\t\t msg value is: %u\n",
- wac_info->dbgWave_msg.DbgWaveMsg.WaveMsgInfoGen2.Value);
- pr_debug("\t\t vmid is: N/A\n");
-
- pr_debug("\t\t chk_vmid is : %u\n", reg_sq_cmd.bitfields.check_vmid);
- pr_debug("\t\t command is : %u\n", reg_sq_cmd.bitfields.cmd);
- pr_debug("\t\t queue id is : %u\n", reg_sq_cmd.bitfields.queue_id);
- pr_debug("\t\t simd id is : %u\n", reg_sq_cmd.bitfields.simd_id);
- pr_debug("\t\t mode is : %u\n", reg_sq_cmd.bitfields.mode);
- pr_debug("\t\t vm_id is : %u\n", reg_sq_cmd.bitfields.vm_id);
- pr_debug("\t\t wave_id is : %u\n", reg_sq_cmd.bitfields.wave_id);
-
- pr_debug("\t\t ibw is : %u\n",
- reg_gfx_index.bitfields.instance_broadcast_writes);
- pr_debug("\t\t ii is : %u\n",
- reg_gfx_index.bitfields.instance_index);
- pr_debug("\t\t sebw is : %u\n",
- reg_gfx_index.bitfields.se_broadcast_writes);
- pr_debug("\t\t se_ind is : %u\n", reg_gfx_index.bitfields.se_index);
- pr_debug("\t\t sh_ind is : %u\n", reg_gfx_index.bitfields.sh_index);
- pr_debug("\t\t sbw is : %u\n",
- reg_gfx_index.bitfields.sh_broadcast_writes);
-
- pr_debug("\t\t %30s\n", "* * * * * * * * * * * * * * * * * *");
-
- status = kfd_gtt_sa_allocate(dbgdev->dev, ib_size, &mem_obj);
-
- if (status != 0) {
- pr_err("Failed to allocate GART memory\n");
- return status;
- }
-
- packet_buff_uint = mem_obj->cpu_ptr;
-
- memset(packet_buff_uint, 0, ib_size);
-
- packets_vec = (struct pm4__set_config_reg *) packet_buff_uint;
- packets_vec[0].header.count = 1;
- packets_vec[0].header.opcode = IT_SET_UCONFIG_REG;
- packets_vec[0].header.type = PM4_TYPE_3;
- packets_vec[0].bitfields2.reg_offset =
- GRBM_GFX_INDEX / 4 - USERCONFIG_REG_BASE;
-
- packets_vec[0].bitfields2.insert_vmid = 0;
- packets_vec[0].reg_data[0] = reg_gfx_index.u32All;
-
- packets_vec[1].header.count = 1;
- packets_vec[1].header.opcode = IT_SET_CONFIG_REG;
- packets_vec[1].header.type = PM4_TYPE_3;
- packets_vec[1].bitfields2.reg_offset = SQ_CMD / 4 - AMD_CONFIG_REG_BASE;
-
- packets_vec[1].bitfields2.vmid_shift = SQ_CMD_VMID_OFFSET;
- packets_vec[1].bitfields2.insert_vmid = 1;
- packets_vec[1].reg_data[0] = reg_sq_cmd.u32All;
-
- /* Restore the GRBM_GFX_INDEX register */
-
- reg_gfx_index.u32All = 0;
- reg_gfx_index.bits.sh_broadcast_writes = 1;
- reg_gfx_index.bits.instance_broadcast_writes = 1;
- reg_gfx_index.bits.se_broadcast_writes = 1;
-
-
- packets_vec[2].ordinal1 = packets_vec[0].ordinal1;
- packets_vec[2].bitfields2.reg_offset =
- GRBM_GFX_INDEX / 4 - USERCONFIG_REG_BASE;
-
- packets_vec[2].bitfields2.insert_vmid = 0;
- packets_vec[2].reg_data[0] = reg_gfx_index.u32All;
-
- status = dbgdev_diq_submit_ib(
- dbgdev,
- wac_info->process->pasid,
- mem_obj->gpu_addr,
- packet_buff_uint,
- ib_size);
-
- if (status)
- pr_err("Failed to submit IB to DIQ\n");
-
- kfd_gtt_sa_free(dbgdev->dev, mem_obj);
-
- return status;
-}
-
-static int dbgdev_wave_control_nodiq(struct kfd_dbgdev *dbgdev,
- struct dbg_wave_control_info *wac_info)
-{
- int status;
- union SQ_CMD_BITS reg_sq_cmd;
- union GRBM_GFX_INDEX_BITS reg_gfx_index;
- struct kfd_process_device *pdd;
-
- reg_sq_cmd.u32All = 0;
-
- /* taking the VMID for that process on the safe way using PDD */
- pdd = kfd_get_process_device_data(dbgdev->dev, wac_info->process);
-
- if (!pdd) {
- pr_err("Failed to get pdd for wave control no DIQ\n");
- return -EFAULT;
- }
- status = dbgdev_wave_control_set_registers(wac_info, &reg_sq_cmd,
- &reg_gfx_index);
- if (status) {
- pr_err("Failed to set wave control registers\n");
- return status;
- }
-
- /* for non DIQ we need to patch the VMID: */
-
- reg_sq_cmd.bits.vm_id = pdd->qpd.vmid;
-
- pr_debug("\t\t %30s\n", "* * * * * * * * * * * * * * * * * *");
-
- pr_debug("\t\t mode is: %u\n", wac_info->mode);
- pr_debug("\t\t operand is: %u\n", wac_info->operand);
- pr_debug("\t\t trap id is: %u\n", wac_info->trapId);
- pr_debug("\t\t msg value is: %u\n",
- wac_info->dbgWave_msg.DbgWaveMsg.WaveMsgInfoGen2.Value);
- pr_debug("\t\t vmid is: %u\n", pdd->qpd.vmid);
-
- pr_debug("\t\t chk_vmid is : %u\n", reg_sq_cmd.bitfields.check_vmid);
- pr_debug("\t\t command is : %u\n", reg_sq_cmd.bitfields.cmd);
- pr_debug("\t\t queue id is : %u\n", reg_sq_cmd.bitfields.queue_id);
- pr_debug("\t\t simd id is : %u\n", reg_sq_cmd.bitfields.simd_id);
- pr_debug("\t\t mode is : %u\n", reg_sq_cmd.bitfields.mode);
- pr_debug("\t\t vm_id is : %u\n", reg_sq_cmd.bitfields.vm_id);
- pr_debug("\t\t wave_id is : %u\n", reg_sq_cmd.bitfields.wave_id);
-
- pr_debug("\t\t ibw is : %u\n",
- reg_gfx_index.bitfields.instance_broadcast_writes);
- pr_debug("\t\t ii is : %u\n",
- reg_gfx_index.bitfields.instance_index);
- pr_debug("\t\t sebw is : %u\n",
- reg_gfx_index.bitfields.se_broadcast_writes);
- pr_debug("\t\t se_ind is : %u\n", reg_gfx_index.bitfields.se_index);
- pr_debug("\t\t sh_ind is : %u\n", reg_gfx_index.bitfields.sh_index);
- pr_debug("\t\t sbw is : %u\n",
- reg_gfx_index.bitfields.sh_broadcast_writes);
-
- pr_debug("\t\t %30s\n", "* * * * * * * * * * * * * * * * * *");
-
- return dbgdev->dev->kfd2kgd->wave_control_execute(dbgdev->dev->adev,
- reg_gfx_index.u32All,
- reg_sq_cmd.u32All);
-}
-
-int dbgdev_wave_reset_wavefronts(struct kfd_dev *dev, struct kfd_process *p)
-{
- int status = 0;
- unsigned int vmid;
- uint16_t queried_pasid;
- union SQ_CMD_BITS reg_sq_cmd;
- union GRBM_GFX_INDEX_BITS reg_gfx_index;
- struct kfd_process_device *pdd;
- struct dbg_wave_control_info wac_info;
- int first_vmid_to_scan = dev->vm_info.first_vmid_kfd;
- int last_vmid_to_scan = dev->vm_info.last_vmid_kfd;
-
- reg_sq_cmd.u32All = 0;
- status = 0;
-
- wac_info.mode = HSA_DBG_WAVEMODE_BROADCAST_PROCESS;
- wac_info.operand = HSA_DBG_WAVEOP_KILL;
-
- pr_debug("Killing all process wavefronts\n");
-
- /* Scan all registers in the range ATC_VMID8_PASID_MAPPING ..
- * ATC_VMID15_PASID_MAPPING
- * to check which VMID the current process is mapped to.
- */
-
- for (vmid = first_vmid_to_scan; vmid <= last_vmid_to_scan; vmid++) {
- status = dev->kfd2kgd->get_atc_vmid_pasid_mapping_info
- (dev->adev, vmid, &queried_pasid);
-
- if (status && queried_pasid == p->pasid) {
- pr_debug("Killing wave fronts of vmid %d and pasid 0x%x\n",
- vmid, p->pasid);
- break;
- }
- }
-
- if (vmid > last_vmid_to_scan) {
- pr_err("Didn't find vmid for pasid 0x%x\n", p->pasid);
- return -EFAULT;
- }
-
- /* taking the VMID for that process on the safe way using PDD */
- pdd = kfd_get_process_device_data(dev, p);
- if (!pdd)
- return -EFAULT;
-
- status = dbgdev_wave_control_set_registers(&wac_info, &reg_sq_cmd,
- &reg_gfx_index);
- if (status != 0)
- return -EINVAL;
-
- /* for non DIQ we need to patch the VMID: */
- reg_sq_cmd.bits.vm_id = vmid;
-
- dev->kfd2kgd->wave_control_execute(dev->adev,
- reg_gfx_index.u32All,
- reg_sq_cmd.u32All);
-
- return 0;
-}
-
-void kfd_dbgdev_init(struct kfd_dbgdev *pdbgdev, struct kfd_dev *pdev,
- enum DBGDEV_TYPE type)
-{
- pdbgdev->dev = pdev;
- pdbgdev->kq = NULL;
- pdbgdev->type = type;
- pdbgdev->pqm = NULL;
-
- switch (type) {
- case DBGDEV_TYPE_NODIQ:
- pdbgdev->dbgdev_register = dbgdev_register_nodiq;
- pdbgdev->dbgdev_unregister = dbgdev_unregister_nodiq;
- pdbgdev->dbgdev_wave_control = dbgdev_wave_control_nodiq;
- pdbgdev->dbgdev_address_watch = dbgdev_address_watch_nodiq;
- break;
- case DBGDEV_TYPE_DIQ:
- default:
- pdbgdev->dbgdev_register = dbgdev_register_diq;
- pdbgdev->dbgdev_unregister = dbgdev_unregister_diq;
- pdbgdev->dbgdev_wave_control = dbgdev_wave_control_diq;
- pdbgdev->dbgdev_address_watch = dbgdev_address_watch_diq;
- break;
- }
-
-}
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_dbgdev.h b/drivers/gpu/drm/amd/amdkfd/kfd_dbgdev.h
deleted file mode 100644
index 0619c777b47e..000000000000
--- a/drivers/gpu/drm/amd/amdkfd/kfd_dbgdev.h
+++ /dev/null
@@ -1,230 +0,0 @@
-/*
- * Copyright 2014 Advanced Micro Devices, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- */
-
-#ifndef KFD_DBGDEV_H_
-#define KFD_DBGDEV_H_
-
-enum {
- SQ_CMD_VMID_OFFSET = 28,
- ADDRESS_WATCH_CNTL_OFFSET = 24
-};
-
-enum {
- PRIV_QUEUE_SYNC_TIME_MS = 200
-};
-
-/* CONTEXT reg space definition */
-enum {
- CONTEXT_REG_BASE = 0xA000,
- CONTEXT_REG_END = 0xA400,
- CONTEXT_REG_SIZE = CONTEXT_REG_END - CONTEXT_REG_BASE
-};
-
-/* USER CONFIG reg space definition */
-enum {
- USERCONFIG_REG_BASE = 0xC000,
- USERCONFIG_REG_END = 0x10000,
- USERCONFIG_REG_SIZE = USERCONFIG_REG_END - USERCONFIG_REG_BASE
-};
-
-/* CONFIG reg space definition */
-enum {
- AMD_CONFIG_REG_BASE = 0x2000, /* in dwords */
- AMD_CONFIG_REG_END = 0x2B00,
- AMD_CONFIG_REG_SIZE = AMD_CONFIG_REG_END - AMD_CONFIG_REG_BASE
-};
-
-/* SH reg space definition */
-enum {
- SH_REG_BASE = 0x2C00,
- SH_REG_END = 0x3000,
- SH_REG_SIZE = SH_REG_END - SH_REG_BASE
-};
-
-/* SQ_CMD definitions */
-#define SQ_CMD 0x8DEC
-
-enum SQ_IND_CMD_CMD {
- SQ_IND_CMD_CMD_NULL = 0x00000000,
- SQ_IND_CMD_CMD_HALT = 0x00000001,
- SQ_IND_CMD_CMD_RESUME = 0x00000002,
- SQ_IND_CMD_CMD_KILL = 0x00000003,
- SQ_IND_CMD_CMD_DEBUG = 0x00000004,
- SQ_IND_CMD_CMD_TRAP = 0x00000005,
-};
-
-enum SQ_IND_CMD_MODE {
- SQ_IND_CMD_MODE_SINGLE = 0x00000000,
- SQ_IND_CMD_MODE_BROADCAST = 0x00000001,
- SQ_IND_CMD_MODE_BROADCAST_QUEUE = 0x00000002,
- SQ_IND_CMD_MODE_BROADCAST_PIPE = 0x00000003,
- SQ_IND_CMD_MODE_BROADCAST_ME = 0x00000004,
-};
-
-union SQ_IND_INDEX_BITS {
- struct {
- uint32_t wave_id:4;
- uint32_t simd_id:2;
- uint32_t thread_id:6;
- uint32_t:1;
- uint32_t force_read:1;
- uint32_t read_timeout:1;
- uint32_t unindexed:1;
- uint32_t index:16;
-
- } bitfields, bits;
- uint32_t u32All;
- signed int i32All;
- float f32All;
-};
-
-union SQ_IND_CMD_BITS {
- struct {
- uint32_t data:32;
- } bitfields, bits;
- uint32_t u32All;
- signed int i32All;
- float f32All;
-};
-
-union SQ_CMD_BITS {
- struct {
- uint32_t cmd:3;
- uint32_t:1;
- uint32_t mode:3;
- uint32_t check_vmid:1;
- uint32_t trap_id:3;
- uint32_t:5;
- uint32_t wave_id:4;
- uint32_t simd_id:2;
- uint32_t:2;
- uint32_t queue_id:3;
- uint32_t:1;
- uint32_t vm_id:4;
- } bitfields, bits;
- uint32_t u32All;
- signed int i32All;
- float f32All;
-};
-
-union SQ_IND_DATA_BITS {
- struct {
- uint32_t data:32;
- } bitfields, bits;
- uint32_t u32All;
- signed int i32All;
- float f32All;
-};
-
-union GRBM_GFX_INDEX_BITS {
- struct {
- uint32_t instance_index:8;
- uint32_t sh_index:8;
- uint32_t se_index:8;
- uint32_t:5;
- uint32_t sh_broadcast_writes:1;
- uint32_t instance_broadcast_writes:1;
- uint32_t se_broadcast_writes:1;
- } bitfields, bits;
- uint32_t u32All;
- signed int i32All;
- float f32All;
-};
-
-union TCP_WATCH_ADDR_H_BITS {
- struct {
- uint32_t addr:16;
- uint32_t:16;
-
- } bitfields, bits;
- uint32_t u32All;
- signed int i32All;
- float f32All;
-};
-
-union TCP_WATCH_ADDR_L_BITS {
- struct {
- uint32_t:6;
- uint32_t addr:26;
- } bitfields, bits;
- uint32_t u32All;
- signed int i32All;
- float f32All;
-};
-
-enum {
- QUEUESTATE__INVALID = 0, /* so by default we'll get invalid state */
- QUEUESTATE__ACTIVE_COMPLETION_PENDING,
- QUEUESTATE__ACTIVE
-};
-
-union ULARGE_INTEGER {
- struct {
- uint32_t low_part;
- uint32_t high_part;
- } u;
- unsigned long long quad_part;
-};
-
-
-#define KFD_CIK_VMID_START_OFFSET (8)
-#define KFD_CIK_VMID_END_OFFSET (KFD_CIK_VMID_START_OFFSET + (8))
-
-
-void kfd_dbgdev_init(struct kfd_dbgdev *pdbgdev, struct kfd_dev *pdev,
- enum DBGDEV_TYPE type);
-
-union TCP_WATCH_CNTL_BITS {
- struct {
- uint32_t mask:24;
- uint32_t vmid:4;
- uint32_t atc:1;
- uint32_t mode:2;
- uint32_t valid:1;
- } bitfields, bits;
- uint32_t u32All;
- signed int i32All;
- float f32All;
-};
-
-enum {
- ADDRESS_WATCH_REG_CNTL_ATC_BIT = 0x10000000UL,
- ADDRESS_WATCH_REG_CNTL_DEFAULT_MASK = 0x00FFFFFF,
- ADDRESS_WATCH_REG_ADDLOW_MASK_EXTENSION = 0x03000000,
- /* extend the mask to 26 bits in order to match the low address field */
- ADDRESS_WATCH_REG_ADDLOW_SHIFT = 6,
- ADDRESS_WATCH_REG_ADDHIGH_MASK = 0xFFFF
-};
-
-enum {
- MAX_TRAPID = 8, /* 3 bits in the bitfield. */
- MAX_WATCH_ADDRESSES = 4
-};
-
-enum {
- ADDRESS_WATCH_REG_ADDR_HI = 0,
- ADDRESS_WATCH_REG_ADDR_LO,
- ADDRESS_WATCH_REG_CNTL,
- ADDRESS_WATCH_REG_MAX
-};
-
-#endif /* KFD_DBGDEV_H_ */
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_dbgmgr.c b/drivers/gpu/drm/amd/amdkfd/kfd_dbgmgr.c
deleted file mode 100644
index 9bfa50633654..000000000000
--- a/drivers/gpu/drm/amd/amdkfd/kfd_dbgmgr.c
+++ /dev/null
@@ -1,158 +0,0 @@
-/*
- * Copyright 2014 Advanced Micro Devices, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- */
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/log2.h>
-#include <linux/sched.h>
-#include <linux/slab.h>
-#include <linux/device.h>
-
-#include "kfd_priv.h"
-#include "cik_regs.h"
-#include "kfd_pm4_headers.h"
-#include "kfd_pm4_headers_diq.h"
-#include "kfd_dbgmgr.h"
-#include "kfd_dbgdev.h"
-#include "kfd_device_queue_manager.h"
-
-static DEFINE_MUTEX(kfd_dbgmgr_mutex);
-
-struct mutex *kfd_get_dbgmgr_mutex(void)
-{
- return &kfd_dbgmgr_mutex;
-}
-
-
-static void kfd_dbgmgr_uninitialize(struct kfd_dbgmgr *pmgr)
-{
- kfree(pmgr->dbgdev);
-
- pmgr->dbgdev = NULL;
- pmgr->pasid = 0;
- pmgr->dev = NULL;
-}
-
-void kfd_dbgmgr_destroy(struct kfd_dbgmgr *pmgr)
-{
- if (pmgr) {
- kfd_dbgmgr_uninitialize(pmgr);
- kfree(pmgr);
- }
-}
-
-bool kfd_dbgmgr_create(struct kfd_dbgmgr **ppmgr, struct kfd_dev *pdev)
-{
- enum DBGDEV_TYPE type = DBGDEV_TYPE_DIQ;
- struct kfd_dbgmgr *new_buff;
-
- if (WARN_ON(!pdev->init_complete))
- return false;
-
- new_buff = kfd_alloc_struct(new_buff);
- if (!new_buff) {
- pr_err("Failed to allocate dbgmgr instance\n");
- return false;
- }
-
- new_buff->pasid = 0;
- new_buff->dev = pdev;
- new_buff->dbgdev = kfd_alloc_struct(new_buff->dbgdev);
- if (!new_buff->dbgdev) {
- pr_err("Failed to allocate dbgdev instance\n");
- kfree(new_buff);
- return false;
- }
-
- /* get actual type of DBGDevice cpsch or not */
- if (pdev->dqm->sched_policy == KFD_SCHED_POLICY_NO_HWS)
- type = DBGDEV_TYPE_NODIQ;
-
- kfd_dbgdev_init(new_buff->dbgdev, pdev, type);
- *ppmgr = new_buff;
-
- return true;
-}
-
-long kfd_dbgmgr_register(struct kfd_dbgmgr *pmgr, struct kfd_process *p)
-{
- if (pmgr->pasid != 0) {
- pr_debug("H/W debugger is already active using pasid 0x%x\n",
- pmgr->pasid);
- return -EBUSY;
- }
-
- /* remember pasid */
- pmgr->pasid = p->pasid;
-
- /* provide the pqm for diq generation */
- pmgr->dbgdev->pqm = &p->pqm;
-
- /* activate the actual registering */
- pmgr->dbgdev->dbgdev_register(pmgr->dbgdev);
-
- return 0;
-}
-
-long kfd_dbgmgr_unregister(struct kfd_dbgmgr *pmgr, struct kfd_process *p)
-{
- /* Is the requests coming from the already registered process? */
- if (pmgr->pasid != p->pasid) {
- pr_debug("H/W debugger is not registered by calling pasid 0x%x\n",
- p->pasid);
- return -EINVAL;
- }
-
- pmgr->dbgdev->dbgdev_unregister(pmgr->dbgdev);
-
- pmgr->pasid = 0;
-
- return 0;
-}
-
-long kfd_dbgmgr_wave_control(struct kfd_dbgmgr *pmgr,
- struct dbg_wave_control_info *wac_info)
-{
- /* Is the requests coming from the already registered process? */
- if (pmgr->pasid != wac_info->process->pasid) {
- pr_debug("H/W debugger support was not registered for requester pasid 0x%x\n",
- wac_info->process->pasid);
- return -EINVAL;
- }
-
- return (long) pmgr->dbgdev->dbgdev_wave_control(pmgr->dbgdev, wac_info);
-}
-
-long kfd_dbgmgr_address_watch(struct kfd_dbgmgr *pmgr,
- struct dbg_address_watch_info *adw_info)
-{
- /* Is the requests coming from the already registered process? */
- if (pmgr->pasid != adw_info->process->pasid) {
- pr_debug("H/W debugger support was not registered for requester pasid 0x%x\n",
- adw_info->process->pasid);
- return -EINVAL;
- }
-
- return (long) pmgr->dbgdev->dbgdev_address_watch(pmgr->dbgdev,
- adw_info);
-}
-
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_dbgmgr.h b/drivers/gpu/drm/amd/amdkfd/kfd_dbgmgr.h
deleted file mode 100644
index f9c6df1fdc5c..000000000000
--- a/drivers/gpu/drm/amd/amdkfd/kfd_dbgmgr.h
+++ /dev/null
@@ -1,293 +0,0 @@
-/*
- * Copyright 2014 Advanced Micro Devices, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- */
-
-#ifndef KFD_DBGMGR_H_
-#define KFD_DBGMGR_H_
-
-#include "kfd_priv.h"
-
-/* must align with hsakmttypes definition */
-#pragma pack(push, 4)
-
-enum HSA_DBG_WAVEOP {
- HSA_DBG_WAVEOP_HALT = 1, /* Halts a wavefront */
- HSA_DBG_WAVEOP_RESUME = 2, /* Resumes a wavefront */
- HSA_DBG_WAVEOP_KILL = 3, /* Kills a wavefront */
- HSA_DBG_WAVEOP_DEBUG = 4, /* Causes wavefront to enter dbg mode */
- HSA_DBG_WAVEOP_TRAP = 5, /* Causes wavefront to take a trap */
- HSA_DBG_NUM_WAVEOP = 5,
- HSA_DBG_MAX_WAVEOP = 0xFFFFFFFF
-};
-
-enum HSA_DBG_WAVEMODE {
- /* send command to a single wave */
- HSA_DBG_WAVEMODE_SINGLE = 0,
- /*
- * Broadcast to all wavefronts of all processes is not
- * supported for HSA user mode
- */
-
- /* send to waves within current process */
- HSA_DBG_WAVEMODE_BROADCAST_PROCESS = 2,
- /* send to waves within current process on CU */
- HSA_DBG_WAVEMODE_BROADCAST_PROCESS_CU = 3,
- HSA_DBG_NUM_WAVEMODE = 3,
- HSA_DBG_MAX_WAVEMODE = 0xFFFFFFFF
-};
-
-enum HSA_DBG_WAVEMSG_TYPE {
- HSA_DBG_WAVEMSG_AUTO = 0,
- HSA_DBG_WAVEMSG_USER = 1,
- HSA_DBG_WAVEMSG_ERROR = 2,
- HSA_DBG_NUM_WAVEMSG,
- HSA_DBG_MAX_WAVEMSG = 0xFFFFFFFF
-};
-
-enum HSA_DBG_WATCH_MODE {
- HSA_DBG_WATCH_READ = 0, /* Read operations only */
- HSA_DBG_WATCH_NONREAD = 1, /* Write or Atomic operations only */
- HSA_DBG_WATCH_ATOMIC = 2, /* Atomic Operations only */
- HSA_DBG_WATCH_ALL = 3, /* Read, Write or Atomic operations */
- HSA_DBG_WATCH_NUM,
- HSA_DBG_WATCH_SIZE = 0xFFFFFFFF
-};
-
-/* This structure is hardware specific and may change in the future */
-struct HsaDbgWaveMsgAMDGen2 {
- union {
- struct ui32 {
- uint32_t UserData:8; /* user data */
- uint32_t ShaderArray:1; /* Shader array */
- uint32_t Priv:1; /* Privileged */
- uint32_t Reserved0:4; /* Reserved, should be 0 */
- uint32_t WaveId:4; /* wave id */
- uint32_t SIMD:2; /* SIMD id */
- uint32_t HSACU:4; /* Compute unit */
- uint32_t ShaderEngine:2;/* Shader engine */
- uint32_t MessageType:2; /* see HSA_DBG_WAVEMSG_TYPE */
- uint32_t Reserved1:4; /* Reserved, should be 0 */
- } ui32;
- uint32_t Value;
- };
- uint32_t Reserved2;
-};
-
-union HsaDbgWaveMessageAMD {
- struct HsaDbgWaveMsgAMDGen2 WaveMsgInfoGen2;
- /* for future HsaDbgWaveMsgAMDGen3; */
-};
-
-struct HsaDbgWaveMessage {
- void *MemoryVA; /* ptr to associated host-accessible data */
- union HsaDbgWaveMessageAMD DbgWaveMsg;
-};
-
-/*
- * TODO: This definitions to be MOVED to kfd_event, once it is implemented.
- *
- * HSA sync primitive, Event and HW Exception notification API definitions.
- * The API functions allow the runtime to define a so-called sync-primitive,
- * a SW object combining a user-mode provided "syncvar" and a scheduler event
- * that can be signaled through a defined GPU interrupt. A syncvar is
- * a process virtual memory location of a certain size that can be accessed
- * by CPU and GPU shader code within the process to set and query the content
- * within that memory. The definition of the content is determined by the HSA
- * runtime and potentially GPU shader code interfacing with the HSA runtime.
- * The syncvar values may be commonly written through an PM4 WRITE_DATA packet
- * in the user mode instruction stream. The OS scheduler event is typically
- * associated and signaled by an interrupt issued by the GPU, but other HSA
- * system interrupt conditions from other HW (e.g. IOMMUv2) may be surfaced
- * by the KFD by this mechanism, too.
- */
-
-/* these are the new definitions for events */
-enum HSA_EVENTTYPE {
- HSA_EVENTTYPE_SIGNAL = 0, /* user-mode generated GPU signal */
- HSA_EVENTTYPE_NODECHANGE = 1, /* HSA node change (attach/detach) */
- HSA_EVENTTYPE_DEVICESTATECHANGE = 2, /* HSA device state change
- * (start/stop)
- */
- HSA_EVENTTYPE_HW_EXCEPTION = 3, /* GPU shader exception event */
- HSA_EVENTTYPE_SYSTEM_EVENT = 4, /* GPU SYSCALL with parameter info */
- HSA_EVENTTYPE_DEBUG_EVENT = 5, /* GPU signal for debugging */
- HSA_EVENTTYPE_PROFILE_EVENT = 6,/* GPU signal for profiling */
- HSA_EVENTTYPE_QUEUE_EVENT = 7, /* GPU signal queue idle state
- * (EOP pm4)
- */
- /* ... */
- HSA_EVENTTYPE_MAXID,
- HSA_EVENTTYPE_TYPE_SIZE = 0xFFFFFFFF
-};
-
-/* Sub-definitions for various event types: Syncvar */
-struct HsaSyncVar {
- union SyncVar {
- void *UserData; /* pointer to user mode data */
- uint64_t UserDataPtrValue; /* 64bit compatibility of value */
- } SyncVar;
- uint64_t SyncVarSize;
-};
-
-/* Sub-definitions for various event types: NodeChange */
-
-enum HSA_EVENTTYPE_NODECHANGE_FLAGS {
- HSA_EVENTTYPE_NODECHANGE_ADD = 0,
- HSA_EVENTTYPE_NODECHANGE_REMOVE = 1,
- HSA_EVENTTYPE_NODECHANGE_SIZE = 0xFFFFFFFF
-};
-
-struct HsaNodeChange {
- /* HSA node added/removed on the platform */
- enum HSA_EVENTTYPE_NODECHANGE_FLAGS Flags;
-};
-
-/* Sub-definitions for various event types: DeviceStateChange */
-enum HSA_EVENTTYPE_DEVICESTATECHANGE_FLAGS {
- /* device started (and available) */
- HSA_EVENTTYPE_DEVICESTATUSCHANGE_START = 0,
- /* device stopped (i.e. unavailable) */
- HSA_EVENTTYPE_DEVICESTATUSCHANGE_STOP = 1,
- HSA_EVENTTYPE_DEVICESTATUSCHANGE_SIZE = 0xFFFFFFFF
-};
-
-enum HSA_DEVICE {
- HSA_DEVICE_CPU = 0,
- HSA_DEVICE_GPU = 1,
- MAX_HSA_DEVICE = 2
-};
-
-struct HsaDeviceStateChange {
- uint32_t NodeId; /* F-NUMA node that contains the device */
- enum HSA_DEVICE Device; /* device type: GPU or CPU */
- enum HSA_EVENTTYPE_DEVICESTATECHANGE_FLAGS Flags; /* event flags */
-};
-
-struct HsaEventData {
- enum HSA_EVENTTYPE EventType; /* event type */
- union EventData {
- /*
- * return data associated with HSA_EVENTTYPE_SIGNAL
- * and other events
- */
- struct HsaSyncVar SyncVar;
-
- /* data associated with HSA_EVENTTYPE_NODE_CHANGE */
- struct HsaNodeChange NodeChangeState;
-
- /* data associated with HSA_EVENTTYPE_DEVICE_STATE_CHANGE */
- struct HsaDeviceStateChange DeviceState;
- } EventData;
-
- /* the following data entries are internal to the KFD & thunk itself */
-
- /* internal thunk store for Event data (OsEventHandle) */
- uint64_t HWData1;
- /* internal thunk store for Event data (HWAddress) */
- uint64_t HWData2;
- /* internal thunk store for Event data (HWData) */
- uint32_t HWData3;
-};
-
-struct HsaEventDescriptor {
- /* event type to allocate */
- enum HSA_EVENTTYPE EventType;
- /* H-NUMA node containing GPU device that is event source */
- uint32_t NodeId;
- /* pointer to user mode syncvar data, syncvar->UserDataPtrValue
- * may be NULL
- */
- struct HsaSyncVar SyncVar;
-};
-
-struct HsaEvent {
- uint32_t EventId;
- struct HsaEventData EventData;
-};
-
-#pragma pack(pop)
-
-enum DBGDEV_TYPE {
- DBGDEV_TYPE_ILLEGAL = 0,
- DBGDEV_TYPE_NODIQ = 1,
- DBGDEV_TYPE_DIQ = 2,
- DBGDEV_TYPE_TEST = 3
-};
-
-struct dbg_address_watch_info {
- struct kfd_process *process;
- enum HSA_DBG_WATCH_MODE *watch_mode;
- uint64_t *watch_address;
- uint64_t *watch_mask;
- struct HsaEvent *watch_event;
- uint32_t num_watch_points;
-};
-
-struct dbg_wave_control_info {
- struct kfd_process *process;
- uint32_t trapId;
- enum HSA_DBG_WAVEOP operand;
- enum HSA_DBG_WAVEMODE mode;
- struct HsaDbgWaveMessage dbgWave_msg;
-};
-
-struct kfd_dbgdev {
-
- /* The device that owns this data. */
- struct kfd_dev *dev;
-
- /* kernel queue for DIQ */
- struct kernel_queue *kq;
-
- /* a pointer to the pqm of the calling process */
- struct process_queue_manager *pqm;
-
- /* type of debug device ( DIQ, non DIQ, etc. ) */
- enum DBGDEV_TYPE type;
-
- /* virtualized function pointers to device dbg */
- int (*dbgdev_register)(struct kfd_dbgdev *dbgdev);
- int (*dbgdev_unregister)(struct kfd_dbgdev *dbgdev);
- int (*dbgdev_address_watch)(struct kfd_dbgdev *dbgdev,
- struct dbg_address_watch_info *adw_info);
- int (*dbgdev_wave_control)(struct kfd_dbgdev *dbgdev,
- struct dbg_wave_control_info *wac_info);
-
-};
-
-struct kfd_dbgmgr {
- u32 pasid;
- struct kfd_dev *dev;
- struct kfd_dbgdev *dbgdev;
-};
-
-/* prototypes for debug manager functions */
-struct mutex *kfd_get_dbgmgr_mutex(void);
-void kfd_dbgmgr_destroy(struct kfd_dbgmgr *pmgr);
-bool kfd_dbgmgr_create(struct kfd_dbgmgr **ppmgr, struct kfd_dev *pdev);
-long kfd_dbgmgr_register(struct kfd_dbgmgr *pmgr, struct kfd_process *p);
-long kfd_dbgmgr_unregister(struct kfd_dbgmgr *pmgr, struct kfd_process *p);
-long kfd_dbgmgr_wave_control(struct kfd_dbgmgr *pmgr,
- struct dbg_wave_control_info *wac_info);
-long kfd_dbgmgr_address_watch(struct kfd_dbgmgr *pmgr,
- struct dbg_address_watch_info *adw_info);
-#endif /* KFD_DBGMGR_H_ */
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_debugfs.c b/drivers/gpu/drm/amd/amdkfd/kfd_debugfs.c
index 673d5e34f213..581c3a30fee1 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_debugfs.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_debugfs.c
@@ -1,5 +1,6 @@
+// SPDX-License-Identifier: GPL-2.0 OR MIT
/*
- * Copyright 2016-2017 Advanced Micro Devices, Inc.
+ * Copyright 2016-2022 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@@ -35,7 +36,7 @@ static int kfd_debugfs_open(struct inode *inode, struct file *file)
}
static int kfd_debugfs_hang_hws_read(struct seq_file *m, void *data)
{
- seq_printf(m, "echo gpu_id > hang_hws\n");
+ seq_puts(m, "echo gpu_id > hang_hws\n");
return 0;
}
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device.c b/drivers/gpu/drm/amd/amdkfd/kfd_device.c
index 2b65d0acae2c..339e12c94cff 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_device.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_device.c
@@ -1,5 +1,6 @@
+// SPDX-License-Identifier: GPL-2.0 OR MIT
/*
- * Copyright 2014 Advanced Micro Devices, Inc.
+ * Copyright 2014-2022 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@@ -64,34 +65,33 @@ static void kfd_device_info_set_sdma_queue_num(struct kfd_dev *kfd)
uint32_t sdma_version = kfd->adev->ip_versions[SDMA0_HWIP][0];
switch (sdma_version) {
- case IP_VERSION(4, 0, 0):/* VEGA10 */
- case IP_VERSION(4, 0, 1):/* VEGA12 */
- case IP_VERSION(4, 1, 0):/* RAVEN */
- case IP_VERSION(4, 1, 1):/* RAVEN */
- case IP_VERSION(4, 1, 2):/* RENOIR */
- case IP_VERSION(5, 2, 1):/* VANGOGH */
- case IP_VERSION(5, 2, 3):/* YELLOW_CARP */
- kfd->device_info.num_sdma_queues_per_engine = 2;
- break;
- case IP_VERSION(4, 2, 0):/* VEGA20 */
- case IP_VERSION(4, 2, 2):/* ARCTURUS */
- case IP_VERSION(4, 4, 0):/* ALDEBARAN */
- case IP_VERSION(5, 0, 0):/* NAVI10 */
- case IP_VERSION(5, 0, 1):/* CYAN_SKILLFISH */
- case IP_VERSION(5, 0, 2):/* NAVI14 */
- case IP_VERSION(5, 0, 5):/* NAVI12 */
- case IP_VERSION(5, 2, 0):/* SIENNA_CICHLID */
- case IP_VERSION(5, 2, 2):/* NAVY_FLOUNDER */
- case IP_VERSION(5, 2, 4):/* DIMGREY_CAVEFISH */
- case IP_VERSION(5, 2, 5):/* BEIGE_GOBY */
- kfd->device_info.num_sdma_queues_per_engine = 8;
- break;
- default:
- dev_warn(kfd_device,
- "Default sdma queue per engine(8) is set due to "
- "mismatch of sdma ip block(SDMA_HWIP:0x%x).\n",
- sdma_version);
- kfd->device_info.num_sdma_queues_per_engine = 8;
+ case IP_VERSION(4, 0, 0):/* VEGA10 */
+ case IP_VERSION(4, 0, 1):/* VEGA12 */
+ case IP_VERSION(4, 1, 0):/* RAVEN */
+ case IP_VERSION(4, 1, 1):/* RAVEN */
+ case IP_VERSION(4, 1, 2):/* RENOIR */
+ case IP_VERSION(5, 2, 1):/* VANGOGH */
+ case IP_VERSION(5, 2, 3):/* YELLOW_CARP */
+ kfd->device_info.num_sdma_queues_per_engine = 2;
+ break;
+ case IP_VERSION(4, 2, 0):/* VEGA20 */
+ case IP_VERSION(4, 2, 2):/* ARCTURUS */
+ case IP_VERSION(4, 4, 0):/* ALDEBARAN */
+ case IP_VERSION(5, 0, 0):/* NAVI10 */
+ case IP_VERSION(5, 0, 1):/* CYAN_SKILLFISH */
+ case IP_VERSION(5, 0, 2):/* NAVI14 */
+ case IP_VERSION(5, 0, 5):/* NAVI12 */
+ case IP_VERSION(5, 2, 0):/* SIENNA_CICHLID */
+ case IP_VERSION(5, 2, 2):/* NAVY_FLOUNDER */
+ case IP_VERSION(5, 2, 4):/* DIMGREY_CAVEFISH */
+ case IP_VERSION(5, 2, 5):/* BEIGE_GOBY */
+ kfd->device_info.num_sdma_queues_per_engine = 8;
+ break;
+ default:
+ dev_warn(kfd_device,
+ "Default sdma queue per engine(8) is set due to mismatch of sdma ip block(SDMA_HWIP:0x%x).\n",
+ sdma_version);
+ kfd->device_info.num_sdma_queues_per_engine = 8;
}
}
@@ -111,6 +111,7 @@ static void kfd_device_info_set_event_interrupt_class(struct kfd_dev *kfd)
case IP_VERSION(10, 3, 1): /* VANGOGH */
case IP_VERSION(10, 3, 3): /* YELLOW_CARP */
case IP_VERSION(10, 1, 3): /* CYAN_SKILLFISH */
+ case IP_VERSION(10, 1, 4):
case IP_VERSION(10, 1, 10): /* NAVI10 */
case IP_VERSION(10, 1, 2): /* NAVI12 */
case IP_VERSION(10, 1, 1): /* NAVI14 */
@@ -308,6 +309,7 @@ struct kfd_dev *kgd2kfd_probe(struct amdgpu_device *adev, bool vf)
break;
/* Cyan Skillfish */
case IP_VERSION(10, 1, 3):
+ case IP_VERSION(10, 1, 4):
gfx_target_version = 100103;
if (!vf)
f2g = &gfx_v10_kfd2kgd;
@@ -437,7 +439,8 @@ static int kfd_gws_init(struct kfd_dev *kfd)
return ret;
}
-static void kfd_smi_init(struct kfd_dev *dev) {
+static void kfd_smi_init(struct kfd_dev *dev)
+{
INIT_LIST_HEAD(&dev->smi_clients);
spin_lock_init(&dev->smi_lock);
}
@@ -570,14 +573,12 @@ bool kgd2kfd_device_init(struct kfd_dev *kfd,
svm_migrate_init(kfd->adev);
- if(kgd2kfd_resume_iommu(kfd))
+ if (kgd2kfd_resume_iommu(kfd))
goto device_iommu_error;
if (kfd_resume(kfd))
goto kfd_resume_error;
- kfd->dbgmgr = NULL;
-
if (kfd_topology_add_device(kfd)) {
dev_err(kfd_device, "Error adding device to topology\n");
goto kfd_topology_add_device_error;
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
index 4b6814949aad..acf4f7975850 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
@@ -1,5 +1,6 @@
+// SPDX-License-Identifier: GPL-2.0 OR MIT
/*
- * Copyright 2014 Advanced Micro Devices, Inc.
+ * Copyright 2014-2022 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@@ -58,7 +59,7 @@ static inline void deallocate_hqd(struct device_queue_manager *dqm,
struct queue *q);
static int allocate_hqd(struct device_queue_manager *dqm, struct queue *q);
static int allocate_sdma_queue(struct device_queue_manager *dqm,
- struct queue *q);
+ struct queue *q, const uint32_t *restore_sdma_id);
static void kfd_process_hw_exception(struct work_struct *work);
static inline
@@ -144,7 +145,13 @@ static void decrement_queue_count(struct device_queue_manager *dqm,
dqm->active_cp_queue_count--;
}
-static int allocate_doorbell(struct qcm_process_device *qpd, struct queue *q)
+/*
+ * Allocate a doorbell ID to this queue.
+ * If doorbell_id is passed in, make sure requested ID is valid then allocate it.
+ */
+static int allocate_doorbell(struct qcm_process_device *qpd,
+ struct queue *q,
+ uint32_t const *restore_id)
{
struct kfd_dev *dev = qpd->dqm->dev;
@@ -152,6 +159,10 @@ static int allocate_doorbell(struct qcm_process_device *qpd, struct queue *q)
/* On pre-SOC15 chips we need to use the queue ID to
* preserve the user mode ABI.
*/
+
+ if (restore_id && *restore_id != q->properties.queue_id)
+ return -EINVAL;
+
q->doorbell_id = q->properties.queue_id;
} else if (q->properties.type == KFD_QUEUE_TYPE_SDMA ||
q->properties.type == KFD_QUEUE_TYPE_SDMA_XGMI) {
@@ -160,25 +171,37 @@ static int allocate_doorbell(struct qcm_process_device *qpd, struct queue *q)
* The doobell index distance between RLC (2*i) and (2*i+1)
* for a SDMA engine is 512.
*/
- uint32_t *idx_offset =
- dev->shared_resources.sdma_doorbell_idx;
- q->doorbell_id = idx_offset[q->properties.sdma_engine_id]
- + (q->properties.sdma_queue_id & 1)
- * KFD_QUEUE_DOORBELL_MIRROR_OFFSET
- + (q->properties.sdma_queue_id >> 1);
+ uint32_t *idx_offset = dev->shared_resources.sdma_doorbell_idx;
+ uint32_t valid_id = idx_offset[q->properties.sdma_engine_id]
+ + (q->properties.sdma_queue_id & 1)
+ * KFD_QUEUE_DOORBELL_MIRROR_OFFSET
+ + (q->properties.sdma_queue_id >> 1);
+
+ if (restore_id && *restore_id != valid_id)
+ return -EINVAL;
+ q->doorbell_id = valid_id;
} else {
- /* For CP queues on SOC15 reserve a free doorbell ID */
- unsigned int found;
-
- found = find_first_zero_bit(qpd->doorbell_bitmap,
- KFD_MAX_NUM_OF_QUEUES_PER_PROCESS);
- if (found >= KFD_MAX_NUM_OF_QUEUES_PER_PROCESS) {
- pr_debug("No doorbells available");
- return -EBUSY;
+ /* For CP queues on SOC15 */
+ if (restore_id) {
+ /* make sure that ID is free */
+ if (__test_and_set_bit(*restore_id, qpd->doorbell_bitmap))
+ return -EINVAL;
+
+ q->doorbell_id = *restore_id;
+ } else {
+ /* or reserve a free doorbell ID */
+ unsigned int found;
+
+ found = find_first_zero_bit(qpd->doorbell_bitmap,
+ KFD_MAX_NUM_OF_QUEUES_PER_PROCESS);
+ if (found >= KFD_MAX_NUM_OF_QUEUES_PER_PROCESS) {
+ pr_debug("No doorbells available");
+ return -EBUSY;
+ }
+ set_bit(found, qpd->doorbell_bitmap);
+ q->doorbell_id = found;
}
- set_bit(found, qpd->doorbell_bitmap);
- q->doorbell_id = found;
}
q->properties.doorbell_off =
@@ -299,7 +322,9 @@ static void deallocate_vmid(struct device_queue_manager *dqm,
static int create_queue_nocpsch(struct device_queue_manager *dqm,
struct queue *q,
- struct qcm_process_device *qpd)
+ struct qcm_process_device *qpd,
+ const struct kfd_criu_queue_priv_data *qd,
+ const void *restore_mqd, const void *restore_ctl_stack)
{
struct mqd_manager *mqd_mgr;
int retval;
@@ -339,13 +364,13 @@ static int create_queue_nocpsch(struct device_queue_manager *dqm,
q->pipe, q->queue);
} else if (q->properties.type == KFD_QUEUE_TYPE_SDMA ||
q->properties.type == KFD_QUEUE_TYPE_SDMA_XGMI) {
- retval = allocate_sdma_queue(dqm, q);
+ retval = allocate_sdma_queue(dqm, q, qd ? &qd->sdma_id : NULL);
if (retval)
goto deallocate_vmid;
dqm->asic_ops.init_sdma_vm(dqm, q, qpd);
}
- retval = allocate_doorbell(qpd, q);
+ retval = allocate_doorbell(qpd, q, qd ? &qd->doorbell_id : NULL);
if (retval)
goto out_deallocate_hqd;
@@ -358,8 +383,15 @@ static int create_queue_nocpsch(struct device_queue_manager *dqm,
retval = -ENOMEM;
goto out_deallocate_doorbell;
}
- mqd_mgr->init_mqd(mqd_mgr, &q->mqd, q->mqd_mem_obj,
- &q->gart_mqd_addr, &q->properties);
+
+ if (qd)
+ mqd_mgr->restore_mqd(mqd_mgr, &q->mqd, q->mqd_mem_obj, &q->gart_mqd_addr,
+ &q->properties, restore_mqd, restore_ctl_stack,
+ qd->ctl_stack_size);
+ else
+ mqd_mgr->init_mqd(mqd_mgr, &q->mqd, q->mqd_mem_obj,
+ &q->gart_mqd_addr, &q->properties);
+
if (q->properties.is_active) {
if (!dqm->sched_running) {
WARN_ONCE(1, "Load non-HWS mqd while stopped\n");
@@ -449,6 +481,70 @@ static inline void deallocate_hqd(struct device_queue_manager *dqm,
dqm->allocated_queues[q->pipe] |= (1 << q->queue);
}
+#define SQ_IND_CMD_CMD_KILL 0x00000003
+#define SQ_IND_CMD_MODE_BROADCAST 0x00000001
+
+static int dbgdev_wave_reset_wavefronts(struct kfd_dev *dev, struct kfd_process *p)
+{
+ int status = 0;
+ unsigned int vmid;
+ uint16_t queried_pasid;
+ union SQ_CMD_BITS reg_sq_cmd;
+ union GRBM_GFX_INDEX_BITS reg_gfx_index;
+ struct kfd_process_device *pdd;
+ int first_vmid_to_scan = dev->vm_info.first_vmid_kfd;
+ int last_vmid_to_scan = dev->vm_info.last_vmid_kfd;
+
+ reg_sq_cmd.u32All = 0;
+ reg_gfx_index.u32All = 0;
+
+ pr_debug("Killing all process wavefronts\n");
+
+ if (!dev->kfd2kgd->get_atc_vmid_pasid_mapping_info) {
+ pr_err("no vmid pasid mapping supported \n");
+ return -EOPNOTSUPP;
+ }
+
+ /* Scan all registers in the range ATC_VMID8_PASID_MAPPING ..
+ * ATC_VMID15_PASID_MAPPING
+ * to check which VMID the current process is mapped to.
+ */
+
+ for (vmid = first_vmid_to_scan; vmid <= last_vmid_to_scan; vmid++) {
+ status = dev->kfd2kgd->get_atc_vmid_pasid_mapping_info
+ (dev->adev, vmid, &queried_pasid);
+
+ if (status && queried_pasid == p->pasid) {
+ pr_debug("Killing wave fronts of vmid %d and pasid 0x%x\n",
+ vmid, p->pasid);
+ break;
+ }
+ }
+
+ if (vmid > last_vmid_to_scan) {
+ pr_err("Didn't find vmid for pasid 0x%x\n", p->pasid);
+ return -EFAULT;
+ }
+
+ /* taking the VMID for that process on the safe way using PDD */
+ pdd = kfd_get_process_device_data(dev, p);
+ if (!pdd)
+ return -EFAULT;
+
+ reg_gfx_index.bits.sh_broadcast_writes = 1;
+ reg_gfx_index.bits.se_broadcast_writes = 1;
+ reg_gfx_index.bits.instance_broadcast_writes = 1;
+ reg_sq_cmd.bits.mode = SQ_IND_CMD_MODE_BROADCAST;
+ reg_sq_cmd.bits.cmd = SQ_IND_CMD_CMD_KILL;
+ reg_sq_cmd.bits.vm_id = vmid;
+
+ dev->kfd2kgd->wave_control_execute(dev->adev,
+ reg_gfx_index.u32All,
+ reg_sq_cmd.u32All);
+
+ return 0;
+}
+
/* Access to DQM has to be locked before calling destroy_queue_nocpsch_locked
* to avoid asynchronized access
*/
@@ -586,9 +682,9 @@ static int update_queue(struct device_queue_manager *dqm, struct queue *q,
}
retval = mqd_mgr->destroy_mqd(mqd_mgr, q->mqd,
- (dqm->dev->cwsr_enabled?
- KFD_PREEMPT_TYPE_WAVEFRONT_SAVE:
- KFD_PREEMPT_TYPE_WAVEFRONT_DRAIN),
+ (dqm->dev->cwsr_enabled ?
+ KFD_PREEMPT_TYPE_WAVEFRONT_SAVE :
+ KFD_PREEMPT_TYPE_WAVEFRONT_DRAIN),
KFD_UNMAP_LATENCY_MS, q->pipe, q->queue);
if (retval) {
pr_err("destroy mqd failed\n");
@@ -681,9 +777,9 @@ static int evict_process_queues_nocpsch(struct device_queue_manager *dqm,
continue;
retval = mqd_mgr->destroy_mqd(mqd_mgr, q->mqd,
- (dqm->dev->cwsr_enabled?
- KFD_PREEMPT_TYPE_WAVEFRONT_SAVE:
- KFD_PREEMPT_TYPE_WAVEFRONT_DRAIN),
+ (dqm->dev->cwsr_enabled ?
+ KFD_PREEMPT_TYPE_WAVEFRONT_SAVE :
+ KFD_PREEMPT_TYPE_WAVEFRONT_DRAIN),
KFD_UNMAP_LATENCY_MS, q->pipe, q->queue);
if (retval && !ret)
/* Return the first error, but keep going to
@@ -1008,7 +1104,7 @@ static int start_nocpsch(struct device_queue_manager *dqm)
pr_info("SW scheduler is used");
init_interrupts(dqm);
-
+
if (dqm->dev->adev->asic_type == CHIP_HAWAII)
r = pm_init(&dqm->packet_mgr, dqm);
if (!r)
@@ -1034,7 +1130,7 @@ static void pre_reset(struct device_queue_manager *dqm)
}
static int allocate_sdma_queue(struct device_queue_manager *dqm,
- struct queue *q)
+ struct queue *q, const uint32_t *restore_sdma_id)
{
int bit;
@@ -1044,9 +1140,21 @@ static int allocate_sdma_queue(struct device_queue_manager *dqm,
return -ENOMEM;
}
- bit = __ffs64(dqm->sdma_bitmap);
- dqm->sdma_bitmap &= ~(1ULL << bit);
- q->sdma_id = bit;
+ if (restore_sdma_id) {
+ /* Re-use existing sdma_id */
+ if (!(dqm->sdma_bitmap & (1ULL << *restore_sdma_id))) {
+ pr_err("SDMA queue already in use\n");
+ return -EBUSY;
+ }
+ dqm->sdma_bitmap &= ~(1ULL << *restore_sdma_id);
+ q->sdma_id = *restore_sdma_id;
+ } else {
+ /* Find first available sdma_id */
+ bit = __ffs64(dqm->sdma_bitmap);
+ dqm->sdma_bitmap &= ~(1ULL << bit);
+ q->sdma_id = bit;
+ }
+
q->properties.sdma_engine_id = q->sdma_id %
kfd_get_num_sdma_engines(dqm->dev);
q->properties.sdma_queue_id = q->sdma_id /
@@ -1056,9 +1164,19 @@ static int allocate_sdma_queue(struct device_queue_manager *dqm,
pr_err("No more XGMI SDMA queue to allocate\n");
return -ENOMEM;
}
- bit = __ffs64(dqm->xgmi_sdma_bitmap);
- dqm->xgmi_sdma_bitmap &= ~(1ULL << bit);
- q->sdma_id = bit;
+ if (restore_sdma_id) {
+ /* Re-use existing sdma_id */
+ if (!(dqm->xgmi_sdma_bitmap & (1ULL << *restore_sdma_id))) {
+ pr_err("SDMA queue already in use\n");
+ return -EBUSY;
+ }
+ dqm->xgmi_sdma_bitmap &= ~(1ULL << *restore_sdma_id);
+ q->sdma_id = *restore_sdma_id;
+ } else {
+ bit = __ffs64(dqm->xgmi_sdma_bitmap);
+ dqm->xgmi_sdma_bitmap &= ~(1ULL << bit);
+ q->sdma_id = bit;
+ }
/* sdma_engine_id is sdma id including
* both PCIe-optimized SDMAs and XGMI-
* optimized SDMAs. The calculation below
@@ -1288,7 +1406,9 @@ static void destroy_kernel_queue_cpsch(struct device_queue_manager *dqm,
}
static int create_queue_cpsch(struct device_queue_manager *dqm, struct queue *q,
- struct qcm_process_device *qpd)
+ struct qcm_process_device *qpd,
+ const struct kfd_criu_queue_priv_data *qd,
+ const void *restore_mqd, const void *restore_ctl_stack)
{
int retval;
struct mqd_manager *mqd_mgr;
@@ -1303,13 +1423,13 @@ static int create_queue_cpsch(struct device_queue_manager *dqm, struct queue *q,
if (q->properties.type == KFD_QUEUE_TYPE_SDMA ||
q->properties.type == KFD_QUEUE_TYPE_SDMA_XGMI) {
dqm_lock(dqm);
- retval = allocate_sdma_queue(dqm, q);
+ retval = allocate_sdma_queue(dqm, q, qd ? &qd->sdma_id : NULL);
dqm_unlock(dqm);
if (retval)
goto out;
}
- retval = allocate_doorbell(qpd, q);
+ retval = allocate_doorbell(qpd, q, qd ? &qd->doorbell_id : NULL);
if (retval)
goto out_deallocate_sdma_queue;
@@ -1334,8 +1454,14 @@ static int create_queue_cpsch(struct device_queue_manager *dqm, struct queue *q,
* updates the is_evicted flag but is a no-op otherwise.
*/
q->properties.is_evicted = !!qpd->evicted;
- mqd_mgr->init_mqd(mqd_mgr, &q->mqd, q->mqd_mem_obj,
- &q->gart_mqd_addr, &q->properties);
+
+ if (qd)
+ mqd_mgr->restore_mqd(mqd_mgr, &q->mqd, q->mqd_mem_obj, &q->gart_mqd_addr,
+ &q->properties, restore_mqd, restore_ctl_stack,
+ qd->ctl_stack_size);
+ else
+ mqd_mgr->init_mqd(mqd_mgr, &q->mqd, q->mqd_mem_obj,
+ &q->gart_mqd_addr, &q->properties);
list_add(&q->list, &qpd->queues_list);
qpd->queue_count++;
@@ -1434,8 +1560,7 @@ static int unmap_queues_cpsch(struct device_queue_manager *dqm,
if (!dqm->active_runlist)
return retval;
- retval = pm_send_unmap_queue(&dqm->packet_mgr, KFD_QUEUE_TYPE_COMPUTE,
- filter, filter_param, reset, 0);
+ retval = pm_send_unmap_queue(&dqm->packet_mgr, filter, filter_param, reset);
if (retval)
return retval;
@@ -1738,6 +1863,56 @@ static int get_wave_state(struct device_queue_manager *dqm,
ctl_stack_used_size, save_area_used_size);
}
+static void get_queue_checkpoint_info(struct device_queue_manager *dqm,
+ const struct queue *q,
+ u32 *mqd_size,
+ u32 *ctl_stack_size)
+{
+ struct mqd_manager *mqd_mgr;
+ enum KFD_MQD_TYPE mqd_type =
+ get_mqd_type_from_queue_type(q->properties.type);
+
+ dqm_lock(dqm);
+ mqd_mgr = dqm->mqd_mgrs[mqd_type];
+ *mqd_size = mqd_mgr->mqd_size;
+ *ctl_stack_size = 0;
+
+ if (q->properties.type == KFD_QUEUE_TYPE_COMPUTE && mqd_mgr->get_checkpoint_info)
+ mqd_mgr->get_checkpoint_info(mqd_mgr, q->mqd, ctl_stack_size);
+
+ dqm_unlock(dqm);
+}
+
+static int checkpoint_mqd(struct device_queue_manager *dqm,
+ const struct queue *q,
+ void *mqd,
+ void *ctl_stack)
+{
+ struct mqd_manager *mqd_mgr;
+ int r = 0;
+ enum KFD_MQD_TYPE mqd_type =
+ get_mqd_type_from_queue_type(q->properties.type);
+
+ dqm_lock(dqm);
+
+ if (q->properties.is_active || !q->device->cwsr_enabled) {
+ r = -EINVAL;
+ goto dqm_unlock;
+ }
+
+ mqd_mgr = dqm->mqd_mgrs[mqd_type];
+ if (!mqd_mgr->checkpoint_mqd) {
+ r = -EOPNOTSUPP;
+ goto dqm_unlock;
+ }
+
+ mqd_mgr->checkpoint_mqd(mqd_mgr, q->mqd, mqd, ctl_stack);
+
+dqm_unlock:
+ dqm_unlock(dqm);
+ return r;
+}
+
static int process_termination_cpsch(struct device_queue_manager *dqm,
struct qcm_process_device *qpd)
{
@@ -1915,6 +2090,8 @@ struct device_queue_manager *device_queue_manager_init(struct kfd_dev *dev)
dqm->ops.restore_process_queues = restore_process_queues_cpsch;
dqm->ops.get_wave_state = get_wave_state;
dqm->ops.reset_queues = reset_queues_cpsch;
+ dqm->ops.get_queue_checkpoint_info = get_queue_checkpoint_info;
+ dqm->ops.checkpoint_mqd = checkpoint_mqd;
break;
case KFD_SCHED_POLICY_NO_HWS:
/* initialize dqm for no cp scheduling */
@@ -1934,6 +2111,8 @@ struct device_queue_manager *device_queue_manager_init(struct kfd_dev *dev)
dqm->ops.restore_process_queues =
restore_process_queues_nocpsch;
dqm->ops.get_wave_state = get_wave_state;
+ dqm->ops.get_queue_checkpoint_info = get_queue_checkpoint_info;
+ dqm->ops.checkpoint_mqd = checkpoint_mqd;
break;
default:
pr_err("Invalid scheduling policy %d\n", dqm->sched_policy);
@@ -2005,7 +2184,7 @@ void device_queue_manager_uninit(struct device_queue_manager *dqm)
kfree(dqm);
}
-int kfd_process_vm_fault(struct device_queue_manager *dqm, u32 pasid)
+int kfd_dqm_evict_pasid(struct device_queue_manager *dqm, u32 pasid)
{
struct kfd_process_device *pdd;
struct kfd_process *p = kfd_lookup_process_by_pasid(pasid);
@@ -2060,8 +2239,7 @@ int dqm_debugfs_hqds(struct seq_file *m, void *data)
int r = 0;
if (!dqm->sched_running) {
- seq_printf(m, " Device is stopped\n");
-
+ seq_puts(m, " Device is stopped\n");
return 0;
}
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.h b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.h
index e145e4deb53a..3d539d6483e0 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.h
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.h
@@ -1,5 +1,6 @@
+/* SPDX-License-Identifier: GPL-2.0 OR MIT */
/*
- * Copyright 2014 Advanced Micro Devices, Inc.
+ * Copyright 2014-2022 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@@ -39,6 +40,41 @@ struct device_process_node {
struct list_head list;
};
+union SQ_CMD_BITS {
+ struct {
+ uint32_t cmd:3;
+ uint32_t:1;
+ uint32_t mode:3;
+ uint32_t check_vmid:1;
+ uint32_t trap_id:3;
+ uint32_t:5;
+ uint32_t wave_id:4;
+ uint32_t simd_id:2;
+ uint32_t:2;
+ uint32_t queue_id:3;
+ uint32_t:1;
+ uint32_t vm_id:4;
+ } bitfields, bits;
+ uint32_t u32All;
+ signed int i32All;
+ float f32All;
+};
+
+union GRBM_GFX_INDEX_BITS {
+ struct {
+ uint32_t instance_index:8;
+ uint32_t sh_index:8;
+ uint32_t se_index:8;
+ uint32_t:5;
+ uint32_t sh_broadcast_writes:1;
+ uint32_t instance_broadcast_writes:1;
+ uint32_t se_broadcast_writes:1;
+ } bitfields, bits;
+ uint32_t u32All;
+ signed int i32All;
+ float f32All;
+};
+
/**
* struct device_queue_manager_ops
*
@@ -56,7 +92,7 @@ struct device_process_node {
*
* @initialize: Initializes the pipelines and memory module for that device.
*
- * @start: Initializes the resources/modules the the device needs for queues
+ * @start: Initializes the resources/modules the device needs for queues
* execution. This function is called on device initialization and after the
* system woke up after suspension.
*
@@ -77,18 +113,24 @@ struct device_process_node {
*
* @evict_process_queues: Evict all active queues of a process
*
- * @restore_process_queues: Restore all evicted queues queues of a process
+ * @restore_process_queues: Restore all evicted queues of a process
*
* @get_wave_state: Retrieves context save state and optionally copies the
* control stack, if kept in the MQD, to the given userspace address.
*
* @reset_queues: reset queues which consume RAS poison
+ * @get_queue_checkpoint_info: Retrieves queue size information for CRIU checkpoint.
+ *
+ * @checkpoint_mqd: checkpoint queue MQD contents for CRIU.
*/
struct device_queue_manager_ops {
int (*create_queue)(struct device_queue_manager *dqm,
struct queue *q,
- struct qcm_process_device *qpd);
+ struct qcm_process_device *qpd,
+ const struct kfd_criu_queue_priv_data *qd,
+ const void *restore_mqd,
+ const void *restore_ctl_stack);
int (*destroy_queue)(struct device_queue_manager *dqm,
struct qcm_process_device *qpd,
@@ -139,6 +181,14 @@ struct device_queue_manager_ops {
int (*reset_queues)(struct device_queue_manager *dqm,
uint16_t pasid);
+ void (*get_queue_checkpoint_info)(struct device_queue_manager *dqm,
+ const struct queue *q, u32 *mqd_size,
+ u32 *ctl_stack_size);
+
+ int (*checkpoint_mqd)(struct device_queue_manager *dqm,
+ const struct queue *q,
+ void *mqd,
+ void *ctl_stack);
};
struct device_queue_manager_asic_ops {
@@ -253,9 +303,7 @@ static inline void dqm_unlock(struct device_queue_manager *dqm)
static inline int read_sdma_queue_counter(uint64_t __user *q_rptr, uint64_t *val)
{
- /*
- * SDMA activity counter is stored at queue's RPTR + 0x8 location.
- */
+ /* SDMA activity counter is stored at queue's RPTR + 0x8 location. */
return get_user(*val, q_rptr + 1);
}
#endif /* KFD_DEVICE_QUEUE_MANAGER_H_ */
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager_cik.c b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager_cik.c
index 0d26506798cf..b1ab5b0775e1 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager_cik.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager_cik.c
@@ -1,5 +1,6 @@
+// SPDX-License-Identifier: GPL-2.0 OR MIT
/*
- * Copyright 2014 Advanced Micro Devices, Inc.
+ * Copyright 2014-2022 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager_v10.c b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager_v10.c
index ad0593342333..f1a1f5753e65 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager_v10.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager_v10.c
@@ -1,5 +1,6 @@
+// SPDX-License-Identifier: GPL-2.0 OR MIT
/*
- * Copyright 2018 Advanced Micro Devices, Inc.
+ * Copyright 2018-2022 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@@ -61,15 +62,6 @@ static int update_qpd_v10(struct device_queue_manager *dqm,
(SH_MEM_ALIGNMENT_MODE_UNALIGNED <<
SH_MEM_CONFIG__ALIGNMENT_MODE__SHIFT) |
(3 << SH_MEM_CONFIG__INITIAL_INST_PREFETCH__SHIFT);
-#if 0
- /* TODO:
- * This shouldn't be an issue with Navi10. Verify.
- */
- if (vega10_noretry)
- qpd->sh_mem_config |=
- 1 << SH_MEM_CONFIG__RETRY_DISABLE__SHIFT;
-#endif
-
qpd->sh_mem_ape1_limit = 0;
qpd->sh_mem_ape1_base = 0;
}
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager_v9.c b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager_v9.c
index f20434d9980e..d119070956fb 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager_v9.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager_v9.c
@@ -1,5 +1,6 @@
+// SPDX-License-Identifier: GPL-2.0 OR MIT
/*
- * Copyright 2016-2018 Advanced Micro Devices, Inc.
+ * Copyright 2016-2022 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager_vi.c b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager_vi.c
index 3a7cb2f88366..d7d45832df0f 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager_vi.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager_vi.c
@@ -1,5 +1,6 @@
+// SPDX-License-Identifier: GPL-2.0 OR MIT
/*
- * Copyright 2014 Advanced Micro Devices, Inc.
+ * Copyright 2014-2022 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_doorbell.c b/drivers/gpu/drm/amd/amdkfd/kfd_doorbell.c
index 0dbcf54657ed..5401b6317f25 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_doorbell.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_doorbell.c
@@ -1,5 +1,6 @@
+// SPDX-License-Identifier: GPL-2.0 OR MIT
/*
- * Copyright 2014 Advanced Micro Devices, Inc.
+ * Copyright 2014-2022 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_events.c b/drivers/gpu/drm/amd/amdkfd/kfd_events.c
index afe72dd11325..deecccebe5b6 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_events.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_events.c
@@ -1,5 +1,6 @@
+// SPDX-License-Identifier: GPL-2.0 OR MIT
/*
- * Copyright 2014 Advanced Micro Devices, Inc.
+ * Copyright 2014-2022 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@@ -55,7 +56,6 @@ struct kfd_signal_page {
bool need_to_free_pages;
};
-
static uint64_t *page_slots(struct kfd_signal_page *page)
{
return page->kernel_address;
@@ -92,7 +92,8 @@ fail_alloc_signal_store:
}
static int allocate_event_notification_slot(struct kfd_process *p,
- struct kfd_event *ev)
+ struct kfd_event *ev,
+ const int *restore_id)
{
int id;
@@ -104,14 +105,19 @@ static int allocate_event_notification_slot(struct kfd_process *p,
p->signal_mapped_size = 256*8;
}
- /*
- * Compatibility with old user mode: Only use signal slots
- * user mode has mapped, may be less than
- * KFD_SIGNAL_EVENT_LIMIT. This also allows future increase
- * of the event limit without breaking user mode.
- */
- id = idr_alloc(&p->event_idr, ev, 0, p->signal_mapped_size / 8,
- GFP_KERNEL);
+ if (restore_id) {
+ id = idr_alloc(&p->event_idr, ev, *restore_id, *restore_id + 1,
+ GFP_KERNEL);
+ } else {
+ /*
+ * Compatibility with old user mode: Only use signal slots
+ * user mode has mapped, may be less than
+ * KFD_SIGNAL_EVENT_LIMIT. This also allows future increase
+ * of the event limit without breaking user mode.
+ */
+ id = idr_alloc(&p->event_idr, ev, 0, p->signal_mapped_size / 8,
+ GFP_KERNEL);
+ }
if (id < 0)
return id;
@@ -178,9 +184,8 @@ static struct kfd_event *lookup_signaled_event_by_partial_id(
return ev;
}
-static int create_signal_event(struct file *devkfd,
- struct kfd_process *p,
- struct kfd_event *ev)
+static int create_signal_event(struct file *devkfd, struct kfd_process *p,
+ struct kfd_event *ev, const int *restore_id)
{
int ret;
@@ -193,7 +198,7 @@ static int create_signal_event(struct file *devkfd,
return -ENOSPC;
}
- ret = allocate_event_notification_slot(p, ev);
+ ret = allocate_event_notification_slot(p, ev, restore_id);
if (ret) {
pr_warn("Signal event wasn't created because out of kernel memory\n");
return ret;
@@ -209,16 +214,22 @@ static int create_signal_event(struct file *devkfd,
return 0;
}
-static int create_other_event(struct kfd_process *p, struct kfd_event *ev)
+static int create_other_event(struct kfd_process *p, struct kfd_event *ev, const int *restore_id)
{
- /* Cast KFD_LAST_NONSIGNAL_EVENT to uint32_t. This allows an
- * intentional integer overflow to -1 without a compiler
- * warning. idr_alloc treats a negative value as "maximum
- * signed integer".
- */
- int id = idr_alloc(&p->event_idr, ev, KFD_FIRST_NONSIGNAL_EVENT_ID,
- (uint32_t)KFD_LAST_NONSIGNAL_EVENT_ID + 1,
- GFP_KERNEL);
+ int id;
+
+ if (restore_id)
+ id = idr_alloc(&p->event_idr, ev, *restore_id, *restore_id + 1,
+ GFP_KERNEL);
+ else
+ /* Cast KFD_LAST_NONSIGNAL_EVENT to uint32_t. This allows an
+ * intentional integer overflow to -1 without a compiler
+ * warning. idr_alloc treats a negative value as "maximum
+ * signed integer".
+ */
+ id = idr_alloc(&p->event_idr, ev, KFD_FIRST_NONSIGNAL_EVENT_ID,
+ (uint32_t)KFD_LAST_NONSIGNAL_EVENT_ID + 1,
+ GFP_KERNEL);
if (id < 0)
return id;
@@ -295,8 +306,8 @@ static bool event_can_be_cpu_signaled(const struct kfd_event *ev)
return ev->type == KFD_EVENT_TYPE_SIGNAL;
}
-int kfd_event_page_set(struct kfd_process *p, void *kernel_address,
- uint64_t size)
+static int kfd_event_page_set(struct kfd_process *p, void *kernel_address,
+ uint64_t size, uint64_t user_handle)
{
struct kfd_signal_page *page;
@@ -315,10 +326,57 @@ int kfd_event_page_set(struct kfd_process *p, void *kernel_address,
p->signal_page = page;
p->signal_mapped_size = size;
-
+ p->signal_handle = user_handle;
return 0;
}
+int kfd_kmap_event_page(struct kfd_process *p, uint64_t event_page_offset)
+{
+ struct kfd_dev *kfd;
+ struct kfd_process_device *pdd;
+ void *mem, *kern_addr;
+ uint64_t size;
+ int err = 0;
+
+ if (p->signal_page) {
+ pr_err("Event page is already set\n");
+ return -EINVAL;
+ }
+
+ pdd = kfd_process_device_data_by_id(p, GET_GPU_ID(event_page_offset));
+ if (!pdd) {
+ pr_err("Getting device by id failed in %s\n", __func__);
+ return -EINVAL;
+ }
+ kfd = pdd->dev;
+
+ pdd = kfd_bind_process_to_device(kfd, p);
+ if (IS_ERR(pdd))
+ return PTR_ERR(pdd);
+
+ mem = kfd_process_device_translate_handle(pdd,
+ GET_IDR_HANDLE(event_page_offset));
+ if (!mem) {
+ pr_err("Can't find BO, offset is 0x%llx\n", event_page_offset);
+ return -EINVAL;
+ }
+
+ err = amdgpu_amdkfd_gpuvm_map_gtt_bo_to_kernel(kfd->adev,
+ mem, &kern_addr, &size);
+ if (err) {
+ pr_err("Failed to map event page to kernel\n");
+ return err;
+ }
+
+ err = kfd_event_page_set(p, kern_addr, size, event_page_offset);
+ if (err) {
+ pr_err("Failed to set event page\n");
+ amdgpu_amdkfd_gpuvm_unmap_gtt_bo_from_kernel(kfd->adev, mem);
+ return err;
+ }
+ return err;
+}
+
int kfd_event_create(struct file *devkfd, struct kfd_process *p,
uint32_t event_type, bool auto_reset, uint32_t node_id,
uint32_t *event_id, uint32_t *event_trigger_data,
@@ -343,14 +401,14 @@ int kfd_event_create(struct file *devkfd, struct kfd_process *p,
switch (event_type) {
case KFD_EVENT_TYPE_SIGNAL:
case KFD_EVENT_TYPE_DEBUG:
- ret = create_signal_event(devkfd, p, ev);
+ ret = create_signal_event(devkfd, p, ev, NULL);
if (!ret) {
*event_page_offset = KFD_MMAP_TYPE_EVENTS;
*event_slot_index = ev->event_id;
}
break;
default:
- ret = create_other_event(p, ev);
+ ret = create_other_event(p, ev, NULL);
break;
}
@@ -366,6 +424,166 @@ int kfd_event_create(struct file *devkfd, struct kfd_process *p,
return ret;
}
+int kfd_criu_restore_event(struct file *devkfd,
+ struct kfd_process *p,
+ uint8_t __user *user_priv_ptr,
+ uint64_t *priv_data_offset,
+ uint64_t max_priv_data_size)
+{
+ struct kfd_criu_event_priv_data *ev_priv;
+ struct kfd_event *ev = NULL;
+ int ret = 0;
+
+ ev_priv = kmalloc(sizeof(*ev_priv), GFP_KERNEL);
+ if (!ev_priv)
+ return -ENOMEM;
+
+ ev = kzalloc(sizeof(*ev), GFP_KERNEL);
+ if (!ev) {
+ ret = -ENOMEM;
+ goto exit;
+ }
+
+ if (*priv_data_offset + sizeof(*ev_priv) > max_priv_data_size) {
+ ret = -EINVAL;
+ goto exit;
+ }
+
+ ret = copy_from_user(ev_priv, user_priv_ptr + *priv_data_offset, sizeof(*ev_priv));
+ if (ret) {
+ ret = -EFAULT;
+ goto exit;
+ }
+ *priv_data_offset += sizeof(*ev_priv);
+
+ if (ev_priv->user_handle) {
+ ret = kfd_kmap_event_page(p, ev_priv->user_handle);
+ if (ret)
+ goto exit;
+ }
+
+ ev->type = ev_priv->type;
+ ev->auto_reset = ev_priv->auto_reset;
+ ev->signaled = ev_priv->signaled;
+
+ init_waitqueue_head(&ev->wq);
+
+ mutex_lock(&p->event_mutex);
+ switch (ev->type) {
+ case KFD_EVENT_TYPE_SIGNAL:
+ case KFD_EVENT_TYPE_DEBUG:
+ ret = create_signal_event(devkfd, p, ev, &ev_priv->event_id);
+ break;
+ case KFD_EVENT_TYPE_MEMORY:
+ memcpy(&ev->memory_exception_data,
+ &ev_priv->memory_exception_data,
+ sizeof(struct kfd_hsa_memory_exception_data));
+
+ ret = create_other_event(p, ev, &ev_priv->event_id);
+ break;
+ case KFD_EVENT_TYPE_HW_EXCEPTION:
+ memcpy(&ev->hw_exception_data,
+ &ev_priv->hw_exception_data,
+ sizeof(struct kfd_hsa_hw_exception_data));
+
+ ret = create_other_event(p, ev, &ev_priv->event_id);
+ break;
+ }
+
+exit:
+ if (ret)
+ kfree(ev);
+
+ kfree(ev_priv);
+
+ mutex_unlock(&p->event_mutex);
+
+ return ret;
+}
+
+int kfd_criu_checkpoint_events(struct kfd_process *p,
+ uint8_t __user *user_priv_data,
+ uint64_t *priv_data_offset)
+{
+ struct kfd_criu_event_priv_data *ev_privs;
+ int i = 0;
+ int ret = 0;
+ struct kfd_event *ev;
+ uint32_t ev_id;
+
+ uint32_t num_events = kfd_get_num_events(p);
+
+ if (!num_events)
+ return 0;
+
+ ev_privs = kvzalloc(num_events * sizeof(*ev_privs), GFP_KERNEL);
+ if (!ev_privs)
+ return -ENOMEM;
+
+
+ idr_for_each_entry(&p->event_idr, ev, ev_id) {
+ struct kfd_criu_event_priv_data *ev_priv;
+
+ /*
+ * Currently, all events have same size of private_data, but the current ioctl's
+ * and CRIU plugin supports private_data of variable sizes
+ */
+ ev_priv = &ev_privs[i];
+
+ ev_priv->object_type = KFD_CRIU_OBJECT_TYPE_EVENT;
+
+ /* We store the user_handle with the first event */
+ if (i == 0 && p->signal_page)
+ ev_priv->user_handle = p->signal_handle;
+
+ ev_priv->event_id = ev->event_id;
+ ev_priv->auto_reset = ev->auto_reset;
+ ev_priv->type = ev->type;
+ ev_priv->signaled = ev->signaled;
+
+ if (ev_priv->type == KFD_EVENT_TYPE_MEMORY)
+ memcpy(&ev_priv->memory_exception_data,
+ &ev->memory_exception_data,
+ sizeof(struct kfd_hsa_memory_exception_data));
+ else if (ev_priv->type == KFD_EVENT_TYPE_HW_EXCEPTION)
+ memcpy(&ev_priv->hw_exception_data,
+ &ev->hw_exception_data,
+ sizeof(struct kfd_hsa_hw_exception_data));
+
+ pr_debug("Checkpointed event[%d] id = 0x%08x auto_reset = %x type = %x signaled = %x\n",
+ i,
+ ev_priv->event_id,
+ ev_priv->auto_reset,
+ ev_priv->type,
+ ev_priv->signaled);
+ i++;
+ }
+
+ ret = copy_to_user(user_priv_data + *priv_data_offset,
+ ev_privs, num_events * sizeof(*ev_privs));
+ if (ret) {
+ pr_err("Failed to copy events priv to user\n");
+ ret = -EFAULT;
+ }
+
+ *priv_data_offset += num_events * sizeof(*ev_privs);
+
+ kvfree(ev_privs);
+ return ret;
+}
+
+int kfd_get_num_events(struct kfd_process *p)
+{
+ struct kfd_event *ev;
+ uint32_t id;
+ u32 num_events = 0;
+
+ idr_for_each_entry(&p->event_idr, ev, id)
+ num_events++;
+
+ return num_events;
+}
+
/* Assumes that p is current. */
int kfd_event_destroy(struct kfd_process *p, uint32_t event_id)
{
@@ -878,6 +1096,7 @@ void kfd_signal_iommu_event(struct kfd_dev *dev, u32 pasid,
{
struct kfd_hsa_memory_exception_data memory_exception_data;
struct vm_area_struct *vma;
+ int user_gpu_id;
/*
* Because we are called from arbitrary context (workqueue) as opposed
@@ -899,12 +1118,17 @@ void kfd_signal_iommu_event(struct kfd_dev *dev, u32 pasid,
return; /* Process is exiting */
}
+ user_gpu_id = kfd_process_get_user_gpu_id(p, dev->id);
+ if (unlikely(user_gpu_id == -EINVAL)) {
+ WARN_ONCE(1, "Could not get user_gpu_id from dev->id:%x\n", dev->id);
+ return;
+ }
memset(&memory_exception_data, 0, sizeof(memory_exception_data));
mmap_read_lock(mm);
vma = find_vma(mm, address);
- memory_exception_data.gpu_id = dev->id;
+ memory_exception_data.gpu_id = user_gpu_id;
memory_exception_data.va = address;
/* Set failure reason */
memory_exception_data.failure.NotPresent = 1;
@@ -980,11 +1204,19 @@ void kfd_signal_vm_fault_event(struct kfd_dev *dev, u32 pasid,
uint32_t id;
struct kfd_process *p = kfd_lookup_process_by_pasid(pasid);
struct kfd_hsa_memory_exception_data memory_exception_data;
+ int user_gpu_id;
if (!p)
return; /* Presumably process exited. */
+
+ user_gpu_id = kfd_process_get_user_gpu_id(p, dev->id);
+ if (unlikely(user_gpu_id == -EINVAL)) {
+ WARN_ONCE(1, "Could not get user_gpu_id from dev->id:%x\n", dev->id);
+ return;
+ }
+
memset(&memory_exception_data, 0, sizeof(memory_exception_data));
- memory_exception_data.gpu_id = dev->id;
+ memory_exception_data.gpu_id = user_gpu_id;
memory_exception_data.failure.imprecise = true;
/* Set failure reason */
if (info) {
@@ -1024,27 +1256,34 @@ void kfd_signal_reset_event(struct kfd_dev *dev)
/* Whole gpu reset caused by GPU hang and memory is lost */
memset(&hw_exception_data, 0, sizeof(hw_exception_data));
- hw_exception_data.gpu_id = dev->id;
hw_exception_data.memory_lost = 1;
hw_exception_data.reset_cause = reset_cause;
memset(&memory_exception_data, 0, sizeof(memory_exception_data));
memory_exception_data.ErrorType = KFD_MEM_ERR_SRAM_ECC;
- memory_exception_data.gpu_id = dev->id;
memory_exception_data.failure.imprecise = true;
idx = srcu_read_lock(&kfd_processes_srcu);
hash_for_each_rcu(kfd_processes_table, temp, p, kfd_processes) {
+ int user_gpu_id = kfd_process_get_user_gpu_id(p, dev->id);
+
+ if (unlikely(user_gpu_id == -EINVAL)) {
+ WARN_ONCE(1, "Could not get user_gpu_id from dev->id:%x\n", dev->id);
+ continue;
+ }
+
mutex_lock(&p->event_mutex);
id = KFD_FIRST_NONSIGNAL_EVENT_ID;
idr_for_each_entry_continue(&p->event_idr, ev, id) {
if (ev->type == KFD_EVENT_TYPE_HW_EXCEPTION) {
ev->hw_exception_data = hw_exception_data;
+ ev->hw_exception_data.gpu_id = user_gpu_id;
set_event(ev);
}
if (ev->type == KFD_EVENT_TYPE_MEMORY &&
reset_cause == KFD_HW_EXCEPTION_ECC) {
ev->memory_exception_data = memory_exception_data;
+ ev->memory_exception_data.gpu_id = user_gpu_id;
set_event(ev);
}
}
@@ -1060,18 +1299,25 @@ void kfd_signal_poison_consumed_event(struct kfd_dev *dev, u32 pasid)
struct kfd_hsa_hw_exception_data hw_exception_data;
struct kfd_event *ev;
uint32_t id = KFD_FIRST_NONSIGNAL_EVENT_ID;
+ int user_gpu_id;
if (!p)
return; /* Presumably process exited. */
+ user_gpu_id = kfd_process_get_user_gpu_id(p, dev->id);
+ if (unlikely(user_gpu_id == -EINVAL)) {
+ WARN_ONCE(1, "Could not get user_gpu_id from dev->id:%x\n", dev->id);
+ return;
+ }
+
memset(&hw_exception_data, 0, sizeof(hw_exception_data));
- hw_exception_data.gpu_id = dev->id;
+ hw_exception_data.gpu_id = user_gpu_id;
hw_exception_data.memory_lost = 1;
hw_exception_data.reset_cause = KFD_HW_EXCEPTION_ECC;
memset(&memory_exception_data, 0, sizeof(memory_exception_data));
memory_exception_data.ErrorType = KFD_MEM_ERR_POISON_CONSUMED;
- memory_exception_data.gpu_id = dev->id;
+ memory_exception_data.gpu_id = user_gpu_id;
memory_exception_data.failure.imprecise = true;
mutex_lock(&p->event_mutex);
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_events.h b/drivers/gpu/drm/amd/amdkfd/kfd_events.h
index c8fe5dbdad55..1238af11916e 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_events.h
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_events.h
@@ -1,5 +1,6 @@
+/* SPDX-License-Identifier: GPL-2.0 OR MIT */
/*
- * Copyright 2014 Advanced Micro Devices, Inc.
+ * Copyright 2014-2022 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_flat_memory.c b/drivers/gpu/drm/amd/amdkfd/kfd_flat_memory.c
index 2e2b7ceb71db..8aebe408c544 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_flat_memory.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_flat_memory.c
@@ -1,5 +1,6 @@
+// SPDX-License-Identifier: GPL-2.0 OR MIT
/*
- * Copyright 2014 Advanced Micro Devices, Inc.
+ * Copyright 2014-2022 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@@ -34,7 +35,7 @@
#include "kfd_priv.h"
#include <linux/mm.h>
#include <linux/mman.h>
-#include <asm/processor.h>
+#include <linux/processor.h>
/*
* The primary memory I/O features being added for revisions of gfxip
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_int_process_v9.c b/drivers/gpu/drm/amd/amdkfd/kfd_int_process_v9.c
index e8bc28009c22..7eedbcd14828 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_int_process_v9.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_int_process_v9.c
@@ -1,5 +1,6 @@
+// SPDX-License-Identifier: GPL-2.0 OR MIT
/*
- * Copyright 2016-2018 Advanced Micro Devices, Inc.
+ * Copyright 2016-2022 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@@ -109,8 +110,7 @@ static void event_interrupt_poison_consumption(struct kfd_dev *dev,
switch (source_id) {
case SOC15_INTSRC_SQ_INTERRUPT_MSG:
- if (dev->dqm->ops.reset_queues)
- ret = dev->dqm->ops.reset_queues(dev->dqm, pasid);
+ ret = kfd_dqm_evict_pasid(dev->dqm, pasid);
break;
case SOC15_INTSRC_SDMA_ECC:
default:
@@ -120,7 +120,8 @@ static void event_interrupt_poison_consumption(struct kfd_dev *dev,
kfd_signal_poison_consumed_event(dev, pasid);
/* resetting queue passes, do page retirement without gpu reset
- resetting queue fails, fallback to gpu reset solution */
+ * resetting queue fails, fallback to gpu reset solution
+ */
if (!ret)
amdgpu_amdkfd_ras_poison_consumption_handler(dev->adev, false);
else
@@ -308,7 +309,7 @@ static void event_interrupt_wq_v9(struct kfd_dev *dev,
info.prot_write = ring_id & 0x20;
kfd_smi_event_update_vmfault(dev, pasid);
- kfd_process_vm_fault(dev->dqm, pasid);
+ kfd_dqm_evict_pasid(dev->dqm, pasid);
kfd_signal_vm_fault_event(dev, pasid, &info);
}
}
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_interrupt.c b/drivers/gpu/drm/amd/amdkfd/kfd_interrupt.c
index 81887c2013c9..9178cfe34f20 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_interrupt.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_interrupt.c
@@ -1,5 +1,6 @@
+// SPDX-License-Identifier: GPL-2.0 OR MIT
/*
- * Copyright 2014 Advanced Micro Devices, Inc.
+ * Copyright 2014-2022 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@@ -57,14 +58,14 @@ int kfd_interrupt_init(struct kfd_dev *kfd)
KFD_IH_NUM_ENTRIES * kfd->device_info.ih_ring_entry_size,
GFP_KERNEL);
if (r) {
- dev_err(kfd_chardev(), "Failed to allocate IH fifo\n");
+ dev_err(kfd->adev->dev, "Failed to allocate IH fifo\n");
return r;
}
kfd->ih_wq = alloc_workqueue("KFD IH", WQ_HIGHPRI, 1);
if (unlikely(!kfd->ih_wq)) {
kfifo_free(&kfd->ih_fifo);
- dev_err(kfd_chardev(), "Failed to allocate KFD IH workqueue\n");
+ dev_err(kfd->adev->dev, "Failed to allocate KFD IH workqueue\n");
return -ENOMEM;
}
spin_lock_init(&kfd->interrupt_lock);
@@ -116,7 +117,7 @@ bool enqueue_ih_ring_entry(struct kfd_dev *kfd, const void *ih_ring_entry)
count = kfifo_in(&kfd->ih_fifo, ih_ring_entry,
kfd->device_info.ih_ring_entry_size);
if (count != kfd->device_info.ih_ring_entry_size) {
- dev_err_ratelimited(kfd_chardev(),
+ dev_dbg_ratelimited(kfd->adev->dev,
"Interrupt ring overflow, dropping interrupt %d\n",
count);
return false;
@@ -147,7 +148,7 @@ static void interrupt_wq(struct work_struct *work)
uint32_t ih_ring_entry[KFD_MAX_RING_ENTRY_SIZE];
if (dev->device_info.ih_ring_entry_size > sizeof(ih_ring_entry)) {
- dev_err_once(kfd_chardev(), "Ring entry too small\n");
+ dev_err_once(dev->adev->dev, "Ring entry too small\n");
return;
}
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_iommu.c b/drivers/gpu/drm/amd/amdkfd/kfd_iommu.c
index 66ad8d0b8f7f..fbd0afe4da42 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_iommu.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_iommu.c
@@ -1,5 +1,6 @@
+// SPDX-License-Identifier: GPL-2.0 OR MIT
/*
- * Copyright 2018 Advanced Micro Devices, Inc.
+ * Copyright 2018-2022 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@@ -30,7 +31,6 @@
#include <linux/pci.h>
#include <linux/amd-iommu.h>
#include "kfd_priv.h"
-#include "kfd_dbgmgr.h"
#include "kfd_topology.h"
#include "kfd_iommu.h"
@@ -163,17 +163,6 @@ static void iommu_pasid_shutdown_callback(struct pci_dev *pdev, u32 pasid)
pr_debug("Unbinding process 0x%x from IOMMU\n", pasid);
- mutex_lock(kfd_get_dbgmgr_mutex());
-
- if (dev->dbgmgr && dev->dbgmgr->pasid == p->pasid) {
- if (!kfd_dbgmgr_unregister(dev->dbgmgr, p)) {
- kfd_dbgmgr_destroy(dev->dbgmgr);
- dev->dbgmgr = NULL;
- }
- }
-
- mutex_unlock(kfd_get_dbgmgr_mutex());
-
mutex_lock(&p->mutex);
pdd = kfd_get_process_device_data(dev, p);
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_iommu.h b/drivers/gpu/drm/amd/amdkfd/kfd_iommu.h
index afd420b01a0c..8cf0fcbe87c2 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_iommu.h
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_iommu.h
@@ -1,5 +1,6 @@
+/* SPDX-License-Identifier: GPL-2.0 OR MIT */
/*
- * Copyright 2018 Advanced Micro Devices, Inc.
+ * Copyright 2018-2022 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue.c b/drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue.c
index 16f8bc4ca7f6..bcf7bc3302c9 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue.c
@@ -1,5 +1,6 @@
+// SPDX-License-Identifier: GPL-2.0 OR MIT
/*
- * Copyright 2014 Advanced Micro Devices, Inc.
+ * Copyright 2014-2022 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue.h b/drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue.h
index f4cfe9f1871c..383202fd1ea2 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue.h
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue.h
@@ -1,5 +1,6 @@
+/* SPDX-License-Identifier: GPL-2.0 OR MIT */
/*
- * Copyright 2014 Advanced Micro Devices, Inc.
+ * Copyright 2014-2022 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_migrate.c b/drivers/gpu/drm/amd/amdkfd/kfd_migrate.c
index ed5385137f48..7e3a7fcb9fe6 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_migrate.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_migrate.c
@@ -24,6 +24,7 @@
#include <linux/hmm.h>
#include <linux/dma-direction.h>
#include <linux/dma-mapping.h>
+#include <linux/migrate.h>
#include "amdgpu_sync.h"
#include "amdgpu_object.h"
#include "amdgpu_vm.h"
@@ -36,7 +37,7 @@
#ifdef dev_fmt
#undef dev_fmt
#endif
-#define dev_fmt(fmt) "kfd_migrate: %s: " fmt, __func__
+#define dev_fmt(fmt) "kfd_migrate: " fmt
static uint64_t
svm_migrate_direct_mapping_addr(struct amdgpu_device *adev, uint64_t addr)
@@ -86,10 +87,7 @@ svm_migrate_gart_map(struct amdgpu_ring *ring, uint64_t npages,
cpu_addr = &job->ibs[0].ptr[num_dw];
- r = amdgpu_gart_map(adev, 0, npages, addr, pte_flags, cpu_addr);
- if (r)
- goto error_free;
-
+ amdgpu_gart_map(adev, 0, npages, addr, pte_flags, cpu_addr);
r = amdgpu_job_submit(job, &adev->mman.entity,
AMDGPU_FENCE_OWNER_UNDEFINED, &fence);
if (r)
@@ -224,7 +222,6 @@ svm_migrate_get_vram_page(struct svm_range *prange, unsigned long pfn)
page = pfn_to_page(pfn);
svm_range_bo_ref(prange->svm_bo);
page->zone_device_data = prange->svm_bo;
- get_page(page);
lock_page(page);
}
@@ -315,7 +312,7 @@ svm_migrate_copy_to_vram(struct amdgpu_device *adev, struct svm_range *prange,
r = svm_range_vram_node_new(adev, prange, true);
if (r) {
- dev_err(adev->dev, "fail %d to alloc vram\n", r);
+ dev_dbg(adev->dev, "fail %d to alloc vram\n", r);
goto out;
}
@@ -334,7 +331,8 @@ svm_migrate_copy_to_vram(struct amdgpu_device *adev, struct svm_range *prange,
DMA_TO_DEVICE);
r = dma_mapping_error(dev, src[i]);
if (r) {
- dev_err(adev->dev, "fail %d dma_map_page\n", r);
+ dev_err(adev->dev, "%s: fail %d dma_map_page\n",
+ __func__, r);
goto out_free_vram_pages;
}
} else {
@@ -365,7 +363,7 @@ svm_migrate_copy_to_vram(struct amdgpu_device *adev, struct svm_range *prange,
if (r)
goto out_free_vram_pages;
amdgpu_res_next(&cursor, (j + 1) * PAGE_SIZE);
- j= 0;
+ j = 0;
} else {
j++;
}
@@ -435,8 +433,8 @@ svm_migrate_vma_to_vram(struct amdgpu_device *adev, struct svm_range *prange,
r = migrate_vma_setup(&migrate);
if (r) {
- dev_err(adev->dev, "vma setup fail %d range [0x%lx 0x%lx]\n", r,
- prange->start, prange->last);
+ dev_err(adev->dev, "%s: vma setup fail %d range [0x%lx 0x%lx]\n",
+ __func__, r, prange->start, prange->last);
goto out_free;
}
@@ -614,7 +612,7 @@ svm_migrate_copy_to_ram(struct amdgpu_device *adev, struct svm_range *prange,
dst[i] = dma_map_page(dev, dpage, 0, PAGE_SIZE, DMA_FROM_DEVICE);
r = dma_mapping_error(dev, dst[i]);
if (r) {
- dev_err(adev->dev, "fail %d dma_map_page\n", r);
+ dev_err(adev->dev, "%s: fail %d dma_map_page\n", __func__, r);
goto out_oom;
}
@@ -640,6 +638,22 @@ out_oom:
return r;
}
+/**
+ * svm_migrate_vma_to_ram - migrate range inside one vma from device to system
+ *
+ * @adev: amdgpu device to migrate from
+ * @prange: svm range structure
+ * @vma: vm_area_struct that range [start, end] belongs to
+ * @start: range start virtual address in pages
+ * @end: range end virtual address in pages
+ *
+ * Context: Process context, caller hold mmap read lock, prange->migrate_mutex
+ *
+ * Return:
+ * 0 - success with all pages migrated
+ * negative values - indicate error
+ * positive values - partial migration, number of pages not migrated
+ */
static long
svm_migrate_vma_to_ram(struct amdgpu_device *adev, struct svm_range *prange,
struct vm_area_struct *vma, uint64_t start, uint64_t end)
@@ -674,8 +688,8 @@ svm_migrate_vma_to_ram(struct amdgpu_device *adev, struct svm_range *prange,
r = migrate_vma_setup(&migrate);
if (r) {
- dev_err(adev->dev, "vma setup fail %d range [0x%lx 0x%lx]\n", r,
- prange->start, prange->last);
+ dev_err(adev->dev, "%s: vma setup fail %d range [0x%lx 0x%lx]\n",
+ __func__, r, prange->start, prange->last);
goto out_free;
}
@@ -711,8 +725,6 @@ out:
pdd = svm_range_get_pdd_by_adev(prange, adev);
if (pdd)
WRITE_ONCE(pdd->page_out, pdd->page_out + cpages);
-
- return upages;
}
return r ? r : upages;
}
@@ -722,7 +734,7 @@ out:
* @prange: range structure
* @mm: process mm, use current->mm if NULL
*
- * Context: Process context, caller hold mmap read lock, svms lock, prange lock
+ * Context: Process context, caller hold mmap read lock, prange->migrate_mutex
*
* Return:
* 0 - OK, otherwise error code
@@ -761,13 +773,16 @@ int svm_migrate_vram_to_ram(struct svm_range *prange, struct mm_struct *mm)
unsigned long next;
vma = find_vma(mm, addr);
- if (!vma || addr < vma->vm_start)
+ if (!vma || addr < vma->vm_start) {
+ pr_debug("failed to find vma for prange %p\n", prange);
+ r = -EFAULT;
break;
+ }
next = min(vma->vm_end, end);
r = svm_migrate_vma_to_ram(adev, prange, vma, addr, next);
if (r < 0) {
- pr_debug("failed %ld to migrate\n", r);
+ pr_debug("failed %ld to migrate prange %p\n", r, prange);
break;
} else {
upages += r;
@@ -775,7 +790,7 @@ int svm_migrate_vram_to_ram(struct svm_range *prange, struct mm_struct *mm)
addr = next;
}
- if (!upages) {
+ if (r >= 0 && !upages) {
svm_range_vram_node_free(prange);
prange->actual_loc = 0;
}
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_module.c b/drivers/gpu/drm/amd/amdkfd/kfd_module.c
index 5e90fe642192..09b966dc3768 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_module.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_module.c
@@ -1,5 +1,6 @@
+// SPDX-License-Identifier: GPL-2.0 OR MIT
/*
- * Copyright 2014 Advanced Micro Devices, Inc.
+ * Copyright 2014-2022 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.c
index e2825ad4d699..5ac209209613 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.c
@@ -1,5 +1,6 @@
+// SPDX-License-Identifier: GPL-2.0 OR MIT
/*
- * Copyright 2014 Advanced Micro Devices, Inc.
+ * Copyright 2014-2022 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@@ -100,6 +101,7 @@ void mqd_symmetrically_map_cu_mask(struct mqd_manager *mm,
struct kfd_cu_info cu_info;
uint32_t cu_per_sh[KFD_MAX_NUM_SE][KFD_MAX_NUM_SH_PER_SE] = {0};
int i, se, sh, cu;
+
amdgpu_amdkfd_get_cu_info(mm->dev->adev, &cu_info);
if (cu_mask_count > cu_info.cu_active_number)
@@ -173,3 +175,66 @@ void mqd_symmetrically_map_cu_mask(struct mqd_manager *mm,
}
}
}
+
+int kfd_hiq_load_mqd_kiq(struct mqd_manager *mm, void *mqd,
+ uint32_t pipe_id, uint32_t queue_id,
+ struct queue_properties *p, struct mm_struct *mms)
+{
+ return mm->dev->kfd2kgd->hiq_mqd_load(mm->dev->adev, mqd, pipe_id,
+ queue_id, p->doorbell_off);
+}
+
+int kfd_destroy_mqd_cp(struct mqd_manager *mm, void *mqd,
+ enum kfd_preempt_type type, unsigned int timeout,
+ uint32_t pipe_id, uint32_t queue_id)
+{
+ return mm->dev->kfd2kgd->hqd_destroy(mm->dev->adev, mqd, type, timeout,
+ pipe_id, queue_id);
+}
+
+void kfd_free_mqd_cp(struct mqd_manager *mm, void *mqd,
+ struct kfd_mem_obj *mqd_mem_obj)
+{
+ if (mqd_mem_obj->gtt_mem) {
+ amdgpu_amdkfd_free_gtt_mem(mm->dev->adev, mqd_mem_obj->gtt_mem);
+ kfree(mqd_mem_obj);
+ } else {
+ kfd_gtt_sa_free(mm->dev, mqd_mem_obj);
+ }
+}
+
+bool kfd_is_occupied_cp(struct mqd_manager *mm, void *mqd,
+ uint64_t queue_address, uint32_t pipe_id,
+ uint32_t queue_id)
+{
+ return mm->dev->kfd2kgd->hqd_is_occupied(mm->dev->adev, queue_address,
+ pipe_id, queue_id);
+}
+
+int kfd_load_mqd_sdma(struct mqd_manager *mm, void *mqd,
+ uint32_t pipe_id, uint32_t queue_id,
+ struct queue_properties *p, struct mm_struct *mms)
+{
+ return mm->dev->kfd2kgd->hqd_sdma_load(mm->dev->adev, mqd,
+ (uint32_t __user *)p->write_ptr,
+ mms);
+}
+
+/*
+ * preempt type here is ignored because there is only one way
+ * to preempt sdma queue
+ */
+int kfd_destroy_mqd_sdma(struct mqd_manager *mm, void *mqd,
+ enum kfd_preempt_type type,
+ unsigned int timeout, uint32_t pipe_id,
+ uint32_t queue_id)
+{
+ return mm->dev->kfd2kgd->hqd_sdma_destroy(mm->dev->adev, mqd, timeout);
+}
+
+bool kfd_is_occupied_sdma(struct mqd_manager *mm, void *mqd,
+ uint64_t queue_address, uint32_t pipe_id,
+ uint32_t queue_id)
+{
+ return mm->dev->kfd2kgd->hqd_sdma_is_occupied(mm->dev->adev, mqd);
+}
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.h b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.h
index 965e17c5dbb4..57f900ccaa10 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.h
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.h
@@ -1,5 +1,6 @@
+/* SPDX-License-Identifier: GPL-2.0 OR MIT */
/*
- * Copyright 2014 Advanced Micro Devices, Inc.
+ * Copyright 2014-2022 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@@ -100,6 +101,20 @@ struct mqd_manager {
u32 *ctl_stack_used_size,
u32 *save_area_used_size);
+ void (*get_checkpoint_info)(struct mqd_manager *mm, void *mqd, uint32_t *ctl_stack_size);
+
+ void (*checkpoint_mqd)(struct mqd_manager *mm,
+ void *mqd,
+ void *mqd_dst,
+ void *ctl_stack_dst);
+
+ void (*restore_mqd)(struct mqd_manager *mm, void **mqd,
+ struct kfd_mem_obj *mqd_mem_obj, uint64_t *gart_addr,
+ struct queue_properties *p,
+ const void *mqd_src,
+ const void *ctl_stack_src,
+ const u32 ctl_stack_size);
+
#if defined(CONFIG_DEBUG_FS)
int (*debugfs_show_mqd)(struct seq_file *m, void *data);
#endif
@@ -122,4 +137,31 @@ void mqd_symmetrically_map_cu_mask(struct mqd_manager *mm,
const uint32_t *cu_mask, uint32_t cu_mask_count,
uint32_t *se_mask);
+int kfd_hiq_load_mqd_kiq(struct mqd_manager *mm, void *mqd,
+ uint32_t pipe_id, uint32_t queue_id,
+ struct queue_properties *p, struct mm_struct *mms);
+
+int kfd_destroy_mqd_cp(struct mqd_manager *mm, void *mqd,
+ enum kfd_preempt_type type, unsigned int timeout,
+ uint32_t pipe_id, uint32_t queue_id);
+
+void kfd_free_mqd_cp(struct mqd_manager *mm, void *mqd,
+ struct kfd_mem_obj *mqd_mem_obj);
+
+bool kfd_is_occupied_cp(struct mqd_manager *mm, void *mqd,
+ uint64_t queue_address, uint32_t pipe_id,
+ uint32_t queue_id);
+
+int kfd_load_mqd_sdma(struct mqd_manager *mm, void *mqd,
+ uint32_t pipe_id, uint32_t queue_id,
+ struct queue_properties *p, struct mm_struct *mms);
+
+int kfd_destroy_mqd_sdma(struct mqd_manager *mm, void *mqd,
+ enum kfd_preempt_type type, unsigned int timeout,
+ uint32_t pipe_id, uint32_t queue_id);
+
+bool kfd_is_occupied_sdma(struct mqd_manager *mm, void *mqd,
+ uint64_t queue_address, uint32_t pipe_id,
+ uint32_t queue_id);
+
#endif /* KFD_MQD_MANAGER_H_ */
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_cik.c b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_cik.c
index e9a8e21e144e..4889865c725c 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_cik.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_cik.c
@@ -1,5 +1,6 @@
+// SPDX-License-Identifier: GPL-2.0 OR MIT
/*
- * Copyright 2014 Advanced Micro Devices, Inc.
+ * Copyright 2014-2022 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@@ -156,13 +157,6 @@ static void init_mqd_sdma(struct mqd_manager *mm, void **mqd,
mm->update_mqd(mm, m, q, NULL);
}
-static void free_mqd(struct mqd_manager *mm, void *mqd,
- struct kfd_mem_obj *mqd_mem_obj)
-{
- kfd_gtt_sa_free(mm->dev, mqd_mem_obj);
-}
-
-
static int load_mqd(struct mqd_manager *mm, void *mqd, uint32_t pipe_id,
uint32_t queue_id, struct queue_properties *p,
struct mm_struct *mms)
@@ -176,15 +170,6 @@ static int load_mqd(struct mqd_manager *mm, void *mqd, uint32_t pipe_id,
wptr_shift, wptr_mask, mms);
}
-static int load_mqd_sdma(struct mqd_manager *mm, void *mqd,
- uint32_t pipe_id, uint32_t queue_id,
- struct queue_properties *p, struct mm_struct *mms)
-{
- return mm->dev->kfd2kgd->hqd_sdma_load(mm->dev->adev, mqd,
- (uint32_t __user *)p->write_ptr,
- mms);
-}
-
static void __update_mqd(struct mqd_manager *mm, void *mqd,
struct queue_properties *q, struct mqd_update_info *minfo,
unsigned int atc_bit)
@@ -271,42 +256,75 @@ static void update_mqd_sdma(struct mqd_manager *mm, void *mqd,
q->is_active = QUEUE_IS_ACTIVE(*q);
}
-static int destroy_mqd(struct mqd_manager *mm, void *mqd,
- enum kfd_preempt_type type,
- unsigned int timeout, uint32_t pipe_id,
- uint32_t queue_id)
+static void checkpoint_mqd(struct mqd_manager *mm, void *mqd, void *mqd_dst, void *ctl_stack_dst)
{
- return mm->dev->kfd2kgd->hqd_destroy(mm->dev->adev, mqd, type, timeout,
- pipe_id, queue_id);
+ struct cik_mqd *m;
+
+ m = get_mqd(mqd);
+
+ memcpy(mqd_dst, m, sizeof(struct cik_mqd));
}
-/*
- * preempt type here is ignored because there is only one way
- * to preempt sdma queue
- */
-static int destroy_mqd_sdma(struct mqd_manager *mm, void *mqd,
- enum kfd_preempt_type type,
- unsigned int timeout, uint32_t pipe_id,
- uint32_t queue_id)
+static void restore_mqd(struct mqd_manager *mm, void **mqd,
+ struct kfd_mem_obj *mqd_mem_obj, uint64_t *gart_addr,
+ struct queue_properties *qp,
+ const void *mqd_src,
+ const void *ctl_stack_src, const u32 ctl_stack_size)
{
- return mm->dev->kfd2kgd->hqd_sdma_destroy(mm->dev->adev, mqd, timeout);
+ uint64_t addr;
+ struct cik_mqd *m;
+
+ m = (struct cik_mqd *) mqd_mem_obj->cpu_ptr;
+ addr = mqd_mem_obj->gpu_addr;
+
+ memcpy(m, mqd_src, sizeof(*m));
+
+ *mqd = m;
+ if (gart_addr)
+ *gart_addr = addr;
+
+ m->cp_hqd_pq_doorbell_control = DOORBELL_OFFSET(qp->doorbell_off);
+
+ pr_debug("cp_hqd_pq_doorbell_control 0x%x\n",
+ m->cp_hqd_pq_doorbell_control);
+
+ qp->is_active = 0;
}
-static bool is_occupied(struct mqd_manager *mm, void *mqd,
- uint64_t queue_address, uint32_t pipe_id,
- uint32_t queue_id)
+static void checkpoint_mqd_sdma(struct mqd_manager *mm,
+ void *mqd,
+ void *mqd_dst,
+ void *ctl_stack_dst)
{
+ struct cik_sdma_rlc_registers *m;
- return mm->dev->kfd2kgd->hqd_is_occupied(mm->dev->adev, queue_address,
- pipe_id, queue_id);
+ m = get_sdma_mqd(mqd);
+ memcpy(mqd_dst, m, sizeof(struct cik_sdma_rlc_registers));
}
-static bool is_occupied_sdma(struct mqd_manager *mm, void *mqd,
- uint64_t queue_address, uint32_t pipe_id,
- uint32_t queue_id)
+static void restore_mqd_sdma(struct mqd_manager *mm, void **mqd,
+ struct kfd_mem_obj *mqd_mem_obj, uint64_t *gart_addr,
+ struct queue_properties *qp,
+ const void *mqd_src,
+ const void *ctl_stack_src, const u32 ctl_stack_size)
{
- return mm->dev->kfd2kgd->hqd_sdma_is_occupied(mm->dev->adev, mqd);
+ uint64_t addr;
+ struct cik_sdma_rlc_registers *m;
+
+ m = (struct cik_sdma_rlc_registers *) mqd_mem_obj->cpu_ptr;
+ addr = mqd_mem_obj->gpu_addr;
+
+ memcpy(m, mqd_src, sizeof(*m));
+
+ m->sdma_rlc_doorbell =
+ qp->doorbell_off << SDMA0_RLC0_DOORBELL__OFFSET__SHIFT;
+
+ *mqd = m;
+ if (gart_addr)
+ *gart_addr = addr;
+
+ qp->is_active = 0;
}
/*
@@ -389,11 +407,13 @@ struct mqd_manager *mqd_manager_init_cik(enum KFD_MQD_TYPE type,
case KFD_MQD_TYPE_CP:
mqd->allocate_mqd = allocate_mqd;
mqd->init_mqd = init_mqd;
- mqd->free_mqd = free_mqd;
+ mqd->free_mqd = kfd_free_mqd_cp;
mqd->load_mqd = load_mqd;
mqd->update_mqd = update_mqd;
- mqd->destroy_mqd = destroy_mqd;
- mqd->is_occupied = is_occupied;
+ mqd->destroy_mqd = kfd_destroy_mqd_cp;
+ mqd->is_occupied = kfd_is_occupied_cp;
+ mqd->checkpoint_mqd = checkpoint_mqd;
+ mqd->restore_mqd = restore_mqd;
mqd->mqd_size = sizeof(struct cik_mqd);
#if defined(CONFIG_DEBUG_FS)
mqd->debugfs_show_mqd = debugfs_show_mqd;
@@ -405,8 +425,8 @@ struct mqd_manager *mqd_manager_init_cik(enum KFD_MQD_TYPE type,
mqd->free_mqd = free_mqd_hiq_sdma;
mqd->load_mqd = load_mqd;
mqd->update_mqd = update_mqd_hiq;
- mqd->destroy_mqd = destroy_mqd;
- mqd->is_occupied = is_occupied;
+ mqd->destroy_mqd = kfd_destroy_mqd_cp;
+ mqd->is_occupied = kfd_is_occupied_cp;
mqd->mqd_size = sizeof(struct cik_mqd);
#if defined(CONFIG_DEBUG_FS)
mqd->debugfs_show_mqd = debugfs_show_mqd;
@@ -416,11 +436,11 @@ struct mqd_manager *mqd_manager_init_cik(enum KFD_MQD_TYPE type,
case KFD_MQD_TYPE_DIQ:
mqd->allocate_mqd = allocate_mqd;
mqd->init_mqd = init_mqd_hiq;
- mqd->free_mqd = free_mqd;
+ mqd->free_mqd = kfd_free_mqd_cp;
mqd->load_mqd = load_mqd;
mqd->update_mqd = update_mqd_hiq;
- mqd->destroy_mqd = destroy_mqd;
- mqd->is_occupied = is_occupied;
+ mqd->destroy_mqd = kfd_destroy_mqd_cp;
+ mqd->is_occupied = kfd_is_occupied_cp;
mqd->mqd_size = sizeof(struct cik_mqd);
#if defined(CONFIG_DEBUG_FS)
mqd->debugfs_show_mqd = debugfs_show_mqd;
@@ -430,10 +450,12 @@ struct mqd_manager *mqd_manager_init_cik(enum KFD_MQD_TYPE type,
mqd->allocate_mqd = allocate_sdma_mqd;
mqd->init_mqd = init_mqd_sdma;
mqd->free_mqd = free_mqd_hiq_sdma;
- mqd->load_mqd = load_mqd_sdma;
+ mqd->load_mqd = kfd_load_mqd_sdma;
mqd->update_mqd = update_mqd_sdma;
- mqd->destroy_mqd = destroy_mqd_sdma;
- mqd->is_occupied = is_occupied_sdma;
+ mqd->destroy_mqd = kfd_destroy_mqd_sdma;
+ mqd->is_occupied = kfd_is_occupied_sdma;
+ mqd->checkpoint_mqd = checkpoint_mqd_sdma;
+ mqd->restore_mqd = restore_mqd_sdma;
mqd->mqd_size = sizeof(struct cik_sdma_rlc_registers);
#if defined(CONFIG_DEBUG_FS)
mqd->debugfs_show_mqd = debugfs_show_mqd_sdma;
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v10.c b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v10.c
index d74d8a6ac27a..d3e2b6a599a4 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v10.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v10.c
@@ -1,5 +1,6 @@
+// SPDX-License-Identifier: GPL-2.0 OR MIT
/*
- * Copyright 2018 Advanced Micro Devices, Inc.
+ * Copyright 2018-2022 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@@ -154,14 +155,6 @@ static int load_mqd(struct mqd_manager *mm, void *mqd,
return r;
}
-static int hiq_load_mqd_kiq(struct mqd_manager *mm, void *mqd,
- uint32_t pipe_id, uint32_t queue_id,
- struct queue_properties *p, struct mm_struct *mms)
-{
- return mm->dev->kfd2kgd->hiq_mqd_load(mm->dev->adev, mqd, pipe_id,
- queue_id, p->doorbell_off);
-}
-
static void update_mqd(struct mqd_manager *mm, void *mqd,
struct queue_properties *q,
struct mqd_update_info *minfo)
@@ -213,7 +206,7 @@ static void update_mqd(struct mqd_manager *mm, void *mqd,
/* GC 10 removed WPP_CLAMP from PQ Control */
m->cp_hqd_pq_control |= CP_HQD_PQ_CONTROL__NO_UPDATE_RPTR_MASK |
2 << CP_HQD_PQ_CONTROL__SLOT_BASED_WPTR__SHIFT |
- 1 << CP_HQD_PQ_CONTROL__QUEUE_FULL_EN__SHIFT ;
+ 1 << CP_HQD_PQ_CONTROL__QUEUE_FULL_EN__SHIFT;
m->cp_hqd_pq_doorbell_control |=
1 << CP_HQD_PQ_DOORBELL_CONTROL__DOORBELL_BIF_DROP__SHIFT;
}
@@ -233,31 +226,6 @@ static uint32_t read_doorbell_id(void *mqd)
return m->queue_doorbell_id0;
}
-static int destroy_mqd(struct mqd_manager *mm, void *mqd,
- enum kfd_preempt_type type,
- unsigned int timeout, uint32_t pipe_id,
- uint32_t queue_id)
-{
- return mm->dev->kfd2kgd->hqd_destroy
- (mm->dev->adev, mqd, type, timeout,
- pipe_id, queue_id);
-}
-
-static void free_mqd(struct mqd_manager *mm, void *mqd,
- struct kfd_mem_obj *mqd_mem_obj)
-{
- kfd_gtt_sa_free(mm->dev, mqd_mem_obj);
-}
-
-static bool is_occupied(struct mqd_manager *mm, void *mqd,
- uint64_t queue_address, uint32_t pipe_id,
- uint32_t queue_id)
-{
- return mm->dev->kfd2kgd->hqd_is_occupied(
- mm->dev->adev, queue_address,
- pipe_id, queue_id);
-}
-
static int get_wave_state(struct mqd_manager *mm, void *mqd,
void __user *ctl_stack,
u32 *ctl_stack_used_size,
@@ -285,6 +253,42 @@ static int get_wave_state(struct mqd_manager *mm, void *mqd,
return 0;
}
+static void checkpoint_mqd(struct mqd_manager *mm, void *mqd, void *mqd_dst, void *ctl_stack_dst)
+{
+ struct v10_compute_mqd *m;
+
+ m = get_mqd(mqd);
+
+ memcpy(mqd_dst, m, sizeof(struct v10_compute_mqd));
+}
+
+static void restore_mqd(struct mqd_manager *mm, void **mqd,
+ struct kfd_mem_obj *mqd_mem_obj, uint64_t *gart_addr,
+ struct queue_properties *qp,
+ const void *mqd_src,
+ const void *ctl_stack_src, const u32 ctl_stack_size)
+{
+ uint64_t addr;
+ struct v10_compute_mqd *m;
+
+ m = (struct v10_compute_mqd *) mqd_mem_obj->cpu_ptr;
+ addr = mqd_mem_obj->gpu_addr;
+
+ memcpy(m, mqd_src, sizeof(*m));
+
+ *mqd = m;
+ if (gart_addr)
+ *gart_addr = addr;
+
+ m->cp_hqd_pq_doorbell_control =
+ qp->doorbell_off <<
+ CP_HQD_PQ_DOORBELL_CONTROL__DOORBELL_OFFSET__SHIFT;
+ pr_debug("cp_hqd_pq_doorbell_control 0x%x\n",
+ m->cp_hqd_pq_doorbell_control);
+
+ qp->is_active = 0;
+}
+
static void init_mqd_hiq(struct mqd_manager *mm, void **mqd,
struct kfd_mem_obj *mqd_mem_obj, uint64_t *gart_addr,
struct queue_properties *q)
@@ -316,15 +320,6 @@ static void init_mqd_sdma(struct mqd_manager *mm, void **mqd,
mm->update_mqd(mm, m, q, NULL);
}
-static int load_mqd_sdma(struct mqd_manager *mm, void *mqd,
- uint32_t pipe_id, uint32_t queue_id,
- struct queue_properties *p, struct mm_struct *mms)
-{
- return mm->dev->kfd2kgd->hqd_sdma_load(mm->dev->adev, mqd,
- (uint32_t __user *)p->write_ptr,
- mms);
-}
-
#define SDMA_RLC_DUMMY_DEFAULT 0xf
static void update_mqd_sdma(struct mqd_manager *mm, void *mqd,
@@ -354,23 +349,41 @@ static void update_mqd_sdma(struct mqd_manager *mm, void *mqd,
q->is_active = QUEUE_IS_ACTIVE(*q);
}
-/*
- * * preempt type here is ignored because there is only one way
- * * to preempt sdma queue
- */
-static int destroy_mqd_sdma(struct mqd_manager *mm, void *mqd,
- enum kfd_preempt_type type,
- unsigned int timeout, uint32_t pipe_id,
- uint32_t queue_id)
+static void checkpoint_mqd_sdma(struct mqd_manager *mm,
+ void *mqd,
+ void *mqd_dst,
+ void *ctl_stack_dst)
{
- return mm->dev->kfd2kgd->hqd_sdma_destroy(mm->dev->adev, mqd, timeout);
+ struct v10_sdma_mqd *m;
+
+ m = get_sdma_mqd(mqd);
+
+ memcpy(mqd_dst, m, sizeof(struct v10_sdma_mqd));
}
-static bool is_occupied_sdma(struct mqd_manager *mm, void *mqd,
- uint64_t queue_address, uint32_t pipe_id,
- uint32_t queue_id)
+static void restore_mqd_sdma(struct mqd_manager *mm, void **mqd,
+ struct kfd_mem_obj *mqd_mem_obj, uint64_t *gart_addr,
+ struct queue_properties *qp,
+ const void *mqd_src,
+ const void *ctl_stack_src,
+ const u32 ctl_stack_size)
{
- return mm->dev->kfd2kgd->hqd_sdma_is_occupied(mm->dev->adev, mqd);
+ uint64_t addr;
+ struct v10_sdma_mqd *m;
+
+ m = (struct v10_sdma_mqd *) mqd_mem_obj->cpu_ptr;
+ addr = mqd_mem_obj->gpu_addr;
+
+ memcpy(m, mqd_src, sizeof(*m));
+
+ m->sdmax_rlcx_doorbell_offset =
+ qp->doorbell_off << SDMA0_RLC0_DOORBELL_OFFSET__OFFSET__SHIFT;
+
+ *mqd = m;
+ if (gart_addr)
+ *gart_addr = addr;
+
+ qp->is_active = 0;
}
#if defined(CONFIG_DEBUG_FS)
@@ -410,13 +423,15 @@ struct mqd_manager *mqd_manager_init_v10(enum KFD_MQD_TYPE type,
pr_debug("%s@%i\n", __func__, __LINE__);
mqd->allocate_mqd = allocate_mqd;
mqd->init_mqd = init_mqd;
- mqd->free_mqd = free_mqd;
+ mqd->free_mqd = kfd_free_mqd_cp;
mqd->load_mqd = load_mqd;
mqd->update_mqd = update_mqd;
- mqd->destroy_mqd = destroy_mqd;
- mqd->is_occupied = is_occupied;
+ mqd->destroy_mqd = kfd_destroy_mqd_cp;
+ mqd->is_occupied = kfd_is_occupied_cp;
mqd->mqd_size = sizeof(struct v10_compute_mqd);
mqd->get_wave_state = get_wave_state;
+ mqd->checkpoint_mqd = checkpoint_mqd;
+ mqd->restore_mqd = restore_mqd;
#if defined(CONFIG_DEBUG_FS)
mqd->debugfs_show_mqd = debugfs_show_mqd;
#endif
@@ -427,10 +442,10 @@ struct mqd_manager *mqd_manager_init_v10(enum KFD_MQD_TYPE type,
mqd->allocate_mqd = allocate_hiq_mqd;
mqd->init_mqd = init_mqd_hiq;
mqd->free_mqd = free_mqd_hiq_sdma;
- mqd->load_mqd = hiq_load_mqd_kiq;
+ mqd->load_mqd = kfd_hiq_load_mqd_kiq;
mqd->update_mqd = update_mqd;
- mqd->destroy_mqd = destroy_mqd;
- mqd->is_occupied = is_occupied;
+ mqd->destroy_mqd = kfd_destroy_mqd_cp;
+ mqd->is_occupied = kfd_is_occupied_cp;
mqd->mqd_size = sizeof(struct v10_compute_mqd);
#if defined(CONFIG_DEBUG_FS)
mqd->debugfs_show_mqd = debugfs_show_mqd;
@@ -441,11 +456,11 @@ struct mqd_manager *mqd_manager_init_v10(enum KFD_MQD_TYPE type,
case KFD_MQD_TYPE_DIQ:
mqd->allocate_mqd = allocate_mqd;
mqd->init_mqd = init_mqd_hiq;
- mqd->free_mqd = free_mqd;
+ mqd->free_mqd = kfd_free_mqd_cp;
mqd->load_mqd = load_mqd;
mqd->update_mqd = update_mqd;
- mqd->destroy_mqd = destroy_mqd;
- mqd->is_occupied = is_occupied;
+ mqd->destroy_mqd = kfd_destroy_mqd_cp;
+ mqd->is_occupied = kfd_is_occupied_cp;
mqd->mqd_size = sizeof(struct v10_compute_mqd);
#if defined(CONFIG_DEBUG_FS)
mqd->debugfs_show_mqd = debugfs_show_mqd;
@@ -456,10 +471,12 @@ struct mqd_manager *mqd_manager_init_v10(enum KFD_MQD_TYPE type,
mqd->allocate_mqd = allocate_sdma_mqd;
mqd->init_mqd = init_mqd_sdma;
mqd->free_mqd = free_mqd_hiq_sdma;
- mqd->load_mqd = load_mqd_sdma;
+ mqd->load_mqd = kfd_load_mqd_sdma;
mqd->update_mqd = update_mqd_sdma;
- mqd->destroy_mqd = destroy_mqd_sdma;
- mqd->is_occupied = is_occupied_sdma;
+ mqd->destroy_mqd = kfd_destroy_mqd_sdma;
+ mqd->is_occupied = kfd_is_occupied_sdma;
+ mqd->checkpoint_mqd = checkpoint_mqd_sdma;
+ mqd->restore_mqd = restore_mqd_sdma;
mqd->mqd_size = sizeof(struct v10_sdma_mqd);
#if defined(CONFIG_DEBUG_FS)
mqd->debugfs_show_mqd = debugfs_show_mqd_sdma;
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v9.c b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v9.c
index 326eb2285029..0778e587a2d6 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v9.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v9.c
@@ -1,5 +1,6 @@
+// SPDX-License-Identifier: GPL-2.0 OR MIT
/*
- * Copyright 2016-2018 Advanced Micro Devices, Inc.
+ * Copyright 2016-2022 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@@ -204,14 +205,6 @@ static int load_mqd(struct mqd_manager *mm, void *mqd,
wptr_shift, 0, mms);
}
-static int hiq_load_mqd_kiq(struct mqd_manager *mm, void *mqd,
- uint32_t pipe_id, uint32_t queue_id,
- struct queue_properties *p, struct mm_struct *mms)
-{
- return mm->dev->kfd2kgd->hiq_mqd_load(mm->dev->adev, mqd, pipe_id,
- queue_id, p->doorbell_off);
-}
-
static void update_mqd(struct mqd_manager *mm, void *mqd,
struct queue_properties *q,
struct mqd_update_info *minfo)
@@ -285,38 +278,6 @@ static uint32_t read_doorbell_id(void *mqd)
return m->queue_doorbell_id0;
}
-static int destroy_mqd(struct mqd_manager *mm, void *mqd,
- enum kfd_preempt_type type,
- unsigned int timeout, uint32_t pipe_id,
- uint32_t queue_id)
-{
- return mm->dev->kfd2kgd->hqd_destroy
- (mm->dev->adev, mqd, type, timeout,
- pipe_id, queue_id);
-}
-
-static void free_mqd(struct mqd_manager *mm, void *mqd,
- struct kfd_mem_obj *mqd_mem_obj)
-{
- struct kfd_dev *kfd = mm->dev;
-
- if (mqd_mem_obj->gtt_mem) {
- amdgpu_amdkfd_free_gtt_mem(kfd->adev, mqd_mem_obj->gtt_mem);
- kfree(mqd_mem_obj);
- } else {
- kfd_gtt_sa_free(mm->dev, mqd_mem_obj);
- }
-}
-
-static bool is_occupied(struct mqd_manager *mm, void *mqd,
- uint64_t queue_address, uint32_t pipe_id,
- uint32_t queue_id)
-{
- return mm->dev->kfd2kgd->hqd_is_occupied(
- mm->dev->adev, queue_address,
- pipe_id, queue_id);
-}
-
static int get_wave_state(struct mqd_manager *mm, void *mqd,
void __user *ctl_stack,
u32 *ctl_stack_used_size,
@@ -340,6 +301,57 @@ static int get_wave_state(struct mqd_manager *mm, void *mqd,
return 0;
}
+static void get_checkpoint_info(struct mqd_manager *mm, void *mqd, u32 *ctl_stack_size)
+{
+ struct v9_mqd *m = get_mqd(mqd);
+
+ *ctl_stack_size = m->cp_hqd_cntl_stack_size;
+}
+
+static void checkpoint_mqd(struct mqd_manager *mm, void *mqd, void *mqd_dst, void *ctl_stack_dst)
+{
+ struct v9_mqd *m;
+ /* Control stack is located one page after MQD. */
+ void *ctl_stack = (void *)((uintptr_t)mqd + PAGE_SIZE);
+
+ m = get_mqd(mqd);
+
+ memcpy(mqd_dst, m, sizeof(struct v9_mqd));
+ memcpy(ctl_stack_dst, ctl_stack, m->cp_hqd_cntl_stack_size);
+}
+
+static void restore_mqd(struct mqd_manager *mm, void **mqd,
+ struct kfd_mem_obj *mqd_mem_obj, uint64_t *gart_addr,
+ struct queue_properties *qp,
+ const void *mqd_src,
+ const void *ctl_stack_src, u32 ctl_stack_size)
+{
+ uint64_t addr;
+ struct v9_mqd *m;
+ void *ctl_stack;
+
+ m = (struct v9_mqd *) mqd_mem_obj->cpu_ptr;
+ addr = mqd_mem_obj->gpu_addr;
+
+ memcpy(m, mqd_src, sizeof(*m));
+
+ *mqd = m;
+ if (gart_addr)
+ *gart_addr = addr;
+
+ /* Control stack is located one page after MQD. */
+ ctl_stack = (void *)((uintptr_t)*mqd + PAGE_SIZE);
+ memcpy(ctl_stack, ctl_stack_src, ctl_stack_size);
+
+ m->cp_hqd_pq_doorbell_control =
+ qp->doorbell_off <<
+ CP_HQD_PQ_DOORBELL_CONTROL__DOORBELL_OFFSET__SHIFT;
+ pr_debug("cp_hqd_pq_doorbell_control 0x%x\n",
+ m->cp_hqd_pq_doorbell_control);
+
+ qp->is_active = 0;
+}
+
static void init_mqd_hiq(struct mqd_manager *mm, void **mqd,
struct kfd_mem_obj *mqd_mem_obj, uint64_t *gart_addr,
struct queue_properties *q)
@@ -371,15 +383,6 @@ static void init_mqd_sdma(struct mqd_manager *mm, void **mqd,
mm->update_mqd(mm, m, q, NULL);
}
-static int load_mqd_sdma(struct mqd_manager *mm, void *mqd,
- uint32_t pipe_id, uint32_t queue_id,
- struct queue_properties *p, struct mm_struct *mms)
-{
- return mm->dev->kfd2kgd->hqd_sdma_load(mm->dev->adev, mqd,
- (uint32_t __user *)p->write_ptr,
- mms);
-}
-
#define SDMA_RLC_DUMMY_DEFAULT 0xf
static void update_mqd_sdma(struct mqd_manager *mm, void *mqd,
@@ -409,23 +412,40 @@ static void update_mqd_sdma(struct mqd_manager *mm, void *mqd,
q->is_active = QUEUE_IS_ACTIVE(*q);
}
-/*
- * * preempt type here is ignored because there is only one way
- * * to preempt sdma queue
- */
-static int destroy_mqd_sdma(struct mqd_manager *mm, void *mqd,
- enum kfd_preempt_type type,
- unsigned int timeout, uint32_t pipe_id,
- uint32_t queue_id)
+static void checkpoint_mqd_sdma(struct mqd_manager *mm,
+ void *mqd,
+ void *mqd_dst,
+ void *ctl_stack_dst)
{
- return mm->dev->kfd2kgd->hqd_sdma_destroy(mm->dev->adev, mqd, timeout);
+ struct v9_sdma_mqd *m;
+
+ m = get_sdma_mqd(mqd);
+
+ memcpy(mqd_dst, m, sizeof(struct v9_sdma_mqd));
}
-static bool is_occupied_sdma(struct mqd_manager *mm, void *mqd,
- uint64_t queue_address, uint32_t pipe_id,
- uint32_t queue_id)
+static void restore_mqd_sdma(struct mqd_manager *mm, void **mqd,
+ struct kfd_mem_obj *mqd_mem_obj, uint64_t *gart_addr,
+ struct queue_properties *qp,
+ const void *mqd_src,
+ const void *ctl_stack_src, const u32 ctl_stack_size)
{
- return mm->dev->kfd2kgd->hqd_sdma_is_occupied(mm->dev->adev, mqd);
+ uint64_t addr;
+ struct v9_sdma_mqd *m;
+
+ m = (struct v9_sdma_mqd *) mqd_mem_obj->cpu_ptr;
+ addr = mqd_mem_obj->gpu_addr;
+
+ memcpy(m, mqd_src, sizeof(*m));
+
+ m->sdmax_rlcx_doorbell_offset =
+ qp->doorbell_off << SDMA0_RLC0_DOORBELL_OFFSET__OFFSET__SHIFT;
+
+ *mqd = m;
+ if (gart_addr)
+ *gart_addr = addr;
+
+ qp->is_active = 0;
}
#if defined(CONFIG_DEBUG_FS)
@@ -464,12 +484,15 @@ struct mqd_manager *mqd_manager_init_v9(enum KFD_MQD_TYPE type,
case KFD_MQD_TYPE_CP:
mqd->allocate_mqd = allocate_mqd;
mqd->init_mqd = init_mqd;
- mqd->free_mqd = free_mqd;
+ mqd->free_mqd = kfd_free_mqd_cp;
mqd->load_mqd = load_mqd;
mqd->update_mqd = update_mqd;
- mqd->destroy_mqd = destroy_mqd;
- mqd->is_occupied = is_occupied;
+ mqd->destroy_mqd = kfd_destroy_mqd_cp;
+ mqd->is_occupied = kfd_is_occupied_cp;
mqd->get_wave_state = get_wave_state;
+ mqd->get_checkpoint_info = get_checkpoint_info;
+ mqd->checkpoint_mqd = checkpoint_mqd;
+ mqd->restore_mqd = restore_mqd;
mqd->mqd_size = sizeof(struct v9_mqd);
#if defined(CONFIG_DEBUG_FS)
mqd->debugfs_show_mqd = debugfs_show_mqd;
@@ -479,10 +502,10 @@ struct mqd_manager *mqd_manager_init_v9(enum KFD_MQD_TYPE type,
mqd->allocate_mqd = allocate_hiq_mqd;
mqd->init_mqd = init_mqd_hiq;
mqd->free_mqd = free_mqd_hiq_sdma;
- mqd->load_mqd = hiq_load_mqd_kiq;
+ mqd->load_mqd = kfd_hiq_load_mqd_kiq;
mqd->update_mqd = update_mqd;
- mqd->destroy_mqd = destroy_mqd;
- mqd->is_occupied = is_occupied;
+ mqd->destroy_mqd = kfd_destroy_mqd_cp;
+ mqd->is_occupied = kfd_is_occupied_cp;
mqd->mqd_size = sizeof(struct v9_mqd);
#if defined(CONFIG_DEBUG_FS)
mqd->debugfs_show_mqd = debugfs_show_mqd;
@@ -492,11 +515,11 @@ struct mqd_manager *mqd_manager_init_v9(enum KFD_MQD_TYPE type,
case KFD_MQD_TYPE_DIQ:
mqd->allocate_mqd = allocate_mqd;
mqd->init_mqd = init_mqd_hiq;
- mqd->free_mqd = free_mqd;
+ mqd->free_mqd = kfd_free_mqd_cp;
mqd->load_mqd = load_mqd;
mqd->update_mqd = update_mqd;
- mqd->destroy_mqd = destroy_mqd;
- mqd->is_occupied = is_occupied;
+ mqd->destroy_mqd = kfd_destroy_mqd_cp;
+ mqd->is_occupied = kfd_is_occupied_cp;
mqd->mqd_size = sizeof(struct v9_mqd);
#if defined(CONFIG_DEBUG_FS)
mqd->debugfs_show_mqd = debugfs_show_mqd;
@@ -506,10 +529,12 @@ struct mqd_manager *mqd_manager_init_v9(enum KFD_MQD_TYPE type,
mqd->allocate_mqd = allocate_sdma_mqd;
mqd->init_mqd = init_mqd_sdma;
mqd->free_mqd = free_mqd_hiq_sdma;
- mqd->load_mqd = load_mqd_sdma;
+ mqd->load_mqd = kfd_load_mqd_sdma;
mqd->update_mqd = update_mqd_sdma;
- mqd->destroy_mqd = destroy_mqd_sdma;
- mqd->is_occupied = is_occupied_sdma;
+ mqd->destroy_mqd = kfd_destroy_mqd_sdma;
+ mqd->is_occupied = kfd_is_occupied_sdma;
+ mqd->checkpoint_mqd = checkpoint_mqd_sdma;
+ mqd->restore_mqd = restore_mqd_sdma;
mqd->mqd_size = sizeof(struct v9_sdma_mqd);
#if defined(CONFIG_DEBUG_FS)
mqd->debugfs_show_mqd = debugfs_show_mqd_sdma;
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_vi.c b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_vi.c
index d456e950ce1d..530ba6f5b57e 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_vi.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_vi.c
@@ -1,5 +1,6 @@
+// SPDX-License-Identifier: GPL-2.0 OR MIT
/*
- * Copyright 2014 Advanced Micro Devices, Inc.
+ * Copyright 2014-2022 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@@ -259,31 +260,6 @@ static void update_mqd_tonga(struct mqd_manager *mm, void *mqd,
__update_mqd(mm, mqd, q, minfo, MTYPE_UC, 0);
}
-static int destroy_mqd(struct mqd_manager *mm, void *mqd,
- enum kfd_preempt_type type,
- unsigned int timeout, uint32_t pipe_id,
- uint32_t queue_id)
-{
- return mm->dev->kfd2kgd->hqd_destroy
- (mm->dev->adev, mqd, type, timeout,
- pipe_id, queue_id);
-}
-
-static void free_mqd(struct mqd_manager *mm, void *mqd,
- struct kfd_mem_obj *mqd_mem_obj)
-{
- kfd_gtt_sa_free(mm->dev, mqd_mem_obj);
-}
-
-static bool is_occupied(struct mqd_manager *mm, void *mqd,
- uint64_t queue_address, uint32_t pipe_id,
- uint32_t queue_id)
-{
- return mm->dev->kfd2kgd->hqd_is_occupied(
- mm->dev->adev, queue_address,
- pipe_id, queue_id);
-}
-
static int get_wave_state(struct mqd_manager *mm, void *mqd,
void __user *ctl_stack,
u32 *ctl_stack_used_size,
@@ -306,11 +282,54 @@ static int get_wave_state(struct mqd_manager *mm, void *mqd,
return 0;
}
+static void get_checkpoint_info(struct mqd_manager *mm, void *mqd, u32 *ctl_stack_size)
+{
+ /* Control stack is stored in user mode */
+ *ctl_stack_size = 0;
+}
+
+static void checkpoint_mqd(struct mqd_manager *mm, void *mqd, void *mqd_dst, void *ctl_stack_dst)
+{
+ struct vi_mqd *m;
+
+ m = get_mqd(mqd);
+
+ memcpy(mqd_dst, m, sizeof(struct vi_mqd));
+}
+
+static void restore_mqd(struct mqd_manager *mm, void **mqd,
+ struct kfd_mem_obj *mqd_mem_obj, uint64_t *gart_addr,
+ struct queue_properties *qp,
+ const void *mqd_src,
+ const void *ctl_stack_src, const u32 ctl_stack_size)
+{
+ uint64_t addr;
+ struct vi_mqd *m;
+
+ m = (struct vi_mqd *) mqd_mem_obj->cpu_ptr;
+ addr = mqd_mem_obj->gpu_addr;
+
+ memcpy(m, mqd_src, sizeof(*m));
+
+ *mqd = m;
+ if (gart_addr)
+ *gart_addr = addr;
+
+ m->cp_hqd_pq_doorbell_control =
+ qp->doorbell_off <<
+ CP_HQD_PQ_DOORBELL_CONTROL__DOORBELL_OFFSET__SHIFT;
+ pr_debug("cp_hqd_pq_doorbell_control 0x%x\n",
+ m->cp_hqd_pq_doorbell_control);
+
+ qp->is_active = 0;
+}
+
static void init_mqd_hiq(struct mqd_manager *mm, void **mqd,
struct kfd_mem_obj *mqd_mem_obj, uint64_t *gart_addr,
struct queue_properties *q)
{
struct vi_mqd *m;
+
init_mqd(mm, mqd, mqd_mem_obj, gart_addr, q);
m = get_mqd(*mqd);
@@ -343,15 +362,6 @@ static void init_mqd_sdma(struct mqd_manager *mm, void **mqd,
mm->update_mqd(mm, m, q, NULL);
}
-static int load_mqd_sdma(struct mqd_manager *mm, void *mqd,
- uint32_t pipe_id, uint32_t queue_id,
- struct queue_properties *p, struct mm_struct *mms)
-{
- return mm->dev->kfd2kgd->hqd_sdma_load(mm->dev->adev, mqd,
- (uint32_t __user *)p->write_ptr,
- mms);
-}
-
static void update_mqd_sdma(struct mqd_manager *mm, void *mqd,
struct queue_properties *q,
struct mqd_update_info *minfo)
@@ -380,27 +390,45 @@ static void update_mqd_sdma(struct mqd_manager *mm, void *mqd,
q->is_active = QUEUE_IS_ACTIVE(*q);
}
-/*
- * * preempt type here is ignored because there is only one way
- * * to preempt sdma queue
- */
-static int destroy_mqd_sdma(struct mqd_manager *mm, void *mqd,
- enum kfd_preempt_type type,
- unsigned int timeout, uint32_t pipe_id,
- uint32_t queue_id)
+static void checkpoint_mqd_sdma(struct mqd_manager *mm,
+ void *mqd,
+ void *mqd_dst,
+ void *ctl_stack_dst)
{
- return mm->dev->kfd2kgd->hqd_sdma_destroy(mm->dev->adev, mqd, timeout);
+ struct vi_sdma_mqd *m;
+
+ m = get_sdma_mqd(mqd);
+
+ memcpy(mqd_dst, m, sizeof(struct vi_sdma_mqd));
}
-static bool is_occupied_sdma(struct mqd_manager *mm, void *mqd,
- uint64_t queue_address, uint32_t pipe_id,
- uint32_t queue_id)
+static void restore_mqd_sdma(struct mqd_manager *mm, void **mqd,
+ struct kfd_mem_obj *mqd_mem_obj, uint64_t *gart_addr,
+ struct queue_properties *qp,
+ const void *mqd_src,
+ const void *ctl_stack_src, const u32 ctl_stack_size)
{
- return mm->dev->kfd2kgd->hqd_sdma_is_occupied(mm->dev->adev, mqd);
+ uint64_t addr;
+ struct vi_sdma_mqd *m;
+
+ m = (struct vi_sdma_mqd *) mqd_mem_obj->cpu_ptr;
+ addr = mqd_mem_obj->gpu_addr;
+
+ memcpy(m, mqd_src, sizeof(*m));
+
+ m->sdmax_rlcx_doorbell =
+ qp->doorbell_off << SDMA0_RLC0_DOORBELL__OFFSET__SHIFT;
+
+ *mqd = m;
+ if (gart_addr)
+ *gart_addr = addr;
+
+ qp->is_active = 0;
}
#if defined(CONFIG_DEBUG_FS)
+
static int debugfs_show_mqd(struct seq_file *m, void *data)
{
seq_hex_dump(m, " ", DUMP_PREFIX_OFFSET, 32, 4,
@@ -435,12 +463,15 @@ struct mqd_manager *mqd_manager_init_vi(enum KFD_MQD_TYPE type,
case KFD_MQD_TYPE_CP:
mqd->allocate_mqd = allocate_mqd;
mqd->init_mqd = init_mqd;
- mqd->free_mqd = free_mqd;
+ mqd->free_mqd = kfd_free_mqd_cp;
mqd->load_mqd = load_mqd;
mqd->update_mqd = update_mqd;
- mqd->destroy_mqd = destroy_mqd;
- mqd->is_occupied = is_occupied;
+ mqd->destroy_mqd = kfd_destroy_mqd_cp;
+ mqd->is_occupied = kfd_is_occupied_cp;
mqd->get_wave_state = get_wave_state;
+ mqd->get_checkpoint_info = get_checkpoint_info;
+ mqd->checkpoint_mqd = checkpoint_mqd;
+ mqd->restore_mqd = restore_mqd;
mqd->mqd_size = sizeof(struct vi_mqd);
#if defined(CONFIG_DEBUG_FS)
mqd->debugfs_show_mqd = debugfs_show_mqd;
@@ -452,8 +483,8 @@ struct mqd_manager *mqd_manager_init_vi(enum KFD_MQD_TYPE type,
mqd->free_mqd = free_mqd_hiq_sdma;
mqd->load_mqd = load_mqd;
mqd->update_mqd = update_mqd_hiq;
- mqd->destroy_mqd = destroy_mqd;
- mqd->is_occupied = is_occupied;
+ mqd->destroy_mqd = kfd_destroy_mqd_cp;
+ mqd->is_occupied = kfd_is_occupied_cp;
mqd->mqd_size = sizeof(struct vi_mqd);
#if defined(CONFIG_DEBUG_FS)
mqd->debugfs_show_mqd = debugfs_show_mqd;
@@ -463,11 +494,11 @@ struct mqd_manager *mqd_manager_init_vi(enum KFD_MQD_TYPE type,
case KFD_MQD_TYPE_DIQ:
mqd->allocate_mqd = allocate_mqd;
mqd->init_mqd = init_mqd_hiq;
- mqd->free_mqd = free_mqd;
+ mqd->free_mqd = kfd_free_mqd_cp;
mqd->load_mqd = load_mqd;
mqd->update_mqd = update_mqd_hiq;
- mqd->destroy_mqd = destroy_mqd;
- mqd->is_occupied = is_occupied;
+ mqd->destroy_mqd = kfd_destroy_mqd_cp;
+ mqd->is_occupied = kfd_is_occupied_cp;
mqd->mqd_size = sizeof(struct vi_mqd);
#if defined(CONFIG_DEBUG_FS)
mqd->debugfs_show_mqd = debugfs_show_mqd;
@@ -477,10 +508,12 @@ struct mqd_manager *mqd_manager_init_vi(enum KFD_MQD_TYPE type,
mqd->allocate_mqd = allocate_sdma_mqd;
mqd->init_mqd = init_mqd_sdma;
mqd->free_mqd = free_mqd_hiq_sdma;
- mqd->load_mqd = load_mqd_sdma;
+ mqd->load_mqd = kfd_load_mqd_sdma;
mqd->update_mqd = update_mqd_sdma;
- mqd->destroy_mqd = destroy_mqd_sdma;
- mqd->is_occupied = is_occupied_sdma;
+ mqd->destroy_mqd = kfd_destroy_mqd_sdma;
+ mqd->is_occupied = kfd_is_occupied_sdma;
+ mqd->checkpoint_mqd = checkpoint_mqd_sdma;
+ mqd->restore_mqd = restore_mqd_sdma;
mqd->mqd_size = sizeof(struct vi_sdma_mqd);
#if defined(CONFIG_DEBUG_FS)
mqd->debugfs_show_mqd = debugfs_show_mqd_sdma;
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_packet_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_packet_manager.c
index 1439420925a0..ed02b6d8bf63 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_packet_manager.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_packet_manager.c
@@ -1,5 +1,6 @@
+// SPDX-License-Identifier: GPL-2.0 OR MIT
/*
- * Copyright 2014 Advanced Micro Devices, Inc.
+ * Copyright 2014-2022 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@@ -368,10 +369,9 @@ out:
return retval;
}
-int pm_send_unmap_queue(struct packet_manager *pm, enum kfd_queue_type type,
+int pm_send_unmap_queue(struct packet_manager *pm,
enum kfd_unmap_queues_filter filter,
- uint32_t filter_param, bool reset,
- unsigned int sdma_engine)
+ uint32_t filter_param, bool reset)
{
uint32_t *buffer, size;
int retval = 0;
@@ -386,8 +386,7 @@ int pm_send_unmap_queue(struct packet_manager *pm, enum kfd_queue_type type,
goto out;
}
- retval = pm->pmf->unmap_queues(pm, buffer, type, filter, filter_param,
- reset, sdma_engine);
+ retval = pm->pmf->unmap_queues(pm, buffer, filter, filter_param, reset);
if (!retval)
kq_submit_packet(pm->priv_queue);
else
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_packet_manager_v9.c b/drivers/gpu/drm/amd/amdkfd/kfd_packet_manager_v9.c
index 7ea3f671b325..18250845a989 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_packet_manager_v9.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_packet_manager_v9.c
@@ -1,5 +1,6 @@
+// SPDX-License-Identifier: GPL-2.0 OR MIT
/*
- * Copyright 2016-2018 Advanced Micro Devices, Inc.
+ * Copyright 2016-2022 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@@ -178,6 +179,11 @@ static int pm_set_resources_v9(struct packet_manager *pm, uint32_t *buffer,
return 0;
}
+static inline bool pm_use_ext_eng(struct kfd_dev *dev)
+{
+ return dev->adev->ip_versions[SDMA0_HWIP][0] >= IP_VERSION(5, 2, 0);
+}
+
static int pm_map_queues_v9(struct packet_manager *pm, uint32_t *buffer,
struct queue *q, bool is_static)
{
@@ -214,7 +220,7 @@ static int pm_map_queues_v9(struct packet_manager *pm, uint32_t *buffer,
case KFD_QUEUE_TYPE_SDMA:
case KFD_QUEUE_TYPE_SDMA_XGMI:
use_static = false; /* no static queues under SDMA */
- if (q->properties.sdma_engine_id < 2)
+ if (q->properties.sdma_engine_id < 2 && !pm_use_ext_eng(q->device))
packet->bitfields2.engine_sel = q->properties.sdma_engine_id +
engine_sel__mes_map_queues__sdma0_vi;
else {
@@ -246,10 +252,8 @@ static int pm_map_queues_v9(struct packet_manager *pm, uint32_t *buffer,
}
static int pm_unmap_queues_v9(struct packet_manager *pm, uint32_t *buffer,
- enum kfd_queue_type type,
enum kfd_unmap_queues_filter filter,
- uint32_t filter_param, bool reset,
- unsigned int sdma_engine)
+ uint32_t filter_param, bool reset)
{
struct pm4_mes_unmap_queues *packet;
@@ -258,31 +262,13 @@ static int pm_unmap_queues_v9(struct packet_manager *pm, uint32_t *buffer,
packet->header.u32All = pm_build_pm4_header(IT_UNMAP_QUEUES,
sizeof(struct pm4_mes_unmap_queues));
- switch (type) {
- case KFD_QUEUE_TYPE_COMPUTE:
- case KFD_QUEUE_TYPE_DIQ:
- packet->bitfields2.extended_engine_sel =
- extended_engine_sel__mes_unmap_queues__legacy_engine_sel;
- packet->bitfields2.engine_sel =
- engine_sel__mes_unmap_queues__compute;
- break;
- case KFD_QUEUE_TYPE_SDMA:
- case KFD_QUEUE_TYPE_SDMA_XGMI:
- if (sdma_engine < 2) {
- packet->bitfields2.extended_engine_sel =
- extended_engine_sel__mes_unmap_queues__legacy_engine_sel;
- packet->bitfields2.engine_sel =
- engine_sel__mes_unmap_queues__sdma0 + sdma_engine;
- } else {
- packet->bitfields2.extended_engine_sel =
- extended_engine_sel__mes_unmap_queues__sdma0_to_7_sel;
- packet->bitfields2.engine_sel = sdma_engine;
- }
- break;
- default:
- WARN(1, "queue type %d", type);
- return -EINVAL;
- }
+
+ packet->bitfields2.extended_engine_sel = pm_use_ext_eng(pm->dqm->dev) ?
+ extended_engine_sel__mes_unmap_queues__sdma0_to_7_sel :
+ extended_engine_sel__mes_unmap_queues__legacy_engine_sel;
+
+ packet->bitfields2.engine_sel =
+ engine_sel__mes_unmap_queues__compute;
if (reset)
packet->bitfields2.action =
@@ -292,12 +278,6 @@ static int pm_unmap_queues_v9(struct packet_manager *pm, uint32_t *buffer,
action__mes_unmap_queues__preempt_queues;
switch (filter) {
- case KFD_UNMAP_QUEUES_FILTER_SINGLE_QUEUE:
- packet->bitfields2.queue_sel =
- queue_sel__mes_unmap_queues__perform_request_on_specified_queues;
- packet->bitfields2.num_queues = 1;
- packet->bitfields3b.doorbell_offset0 = filter_param;
- break;
case KFD_UNMAP_QUEUES_FILTER_BY_PASID:
packet->bitfields2.queue_sel =
queue_sel__mes_unmap_queues__perform_request_on_pasid_queues;
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_packet_manager_vi.c b/drivers/gpu/drm/amd/amdkfd/kfd_packet_manager_vi.c
index 3c0658e32e93..4f951eaa6ee8 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_packet_manager_vi.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_packet_manager_vi.c
@@ -1,5 +1,6 @@
+// SPDX-License-Identifier: GPL-2.0 OR MIT
/*
- * Copyright 2014 Advanced Micro Devices, Inc.
+ * Copyright 2014-2022 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@@ -197,10 +198,8 @@ static int pm_map_queues_vi(struct packet_manager *pm, uint32_t *buffer,
}
static int pm_unmap_queues_vi(struct packet_manager *pm, uint32_t *buffer,
- enum kfd_queue_type type,
enum kfd_unmap_queues_filter filter,
- uint32_t filter_param, bool reset,
- unsigned int sdma_engine)
+ uint32_t filter_param, bool reset)
{
struct pm4_mes_unmap_queues *packet;
@@ -209,21 +208,9 @@ static int pm_unmap_queues_vi(struct packet_manager *pm, uint32_t *buffer,
packet->header.u32All = pm_build_pm4_header(IT_UNMAP_QUEUES,
sizeof(struct pm4_mes_unmap_queues));
- switch (type) {
- case KFD_QUEUE_TYPE_COMPUTE:
- case KFD_QUEUE_TYPE_DIQ:
- packet->bitfields2.engine_sel =
+
+ packet->bitfields2.engine_sel =
engine_sel__mes_unmap_queues__compute;
- break;
- case KFD_QUEUE_TYPE_SDMA:
- case KFD_QUEUE_TYPE_SDMA_XGMI:
- packet->bitfields2.engine_sel =
- engine_sel__mes_unmap_queues__sdma0 + sdma_engine;
- break;
- default:
- WARN(1, "queue type %d", type);
- return -EINVAL;
- }
if (reset)
packet->bitfields2.action =
@@ -233,12 +220,6 @@ static int pm_unmap_queues_vi(struct packet_manager *pm, uint32_t *buffer,
action__mes_unmap_queues__preempt_queues;
switch (filter) {
- case KFD_UNMAP_QUEUES_FILTER_SINGLE_QUEUE:
- packet->bitfields2.queue_sel =
- queue_sel__mes_unmap_queues__perform_request_on_specified_queues;
- packet->bitfields2.num_queues = 1;
- packet->bitfields3b.doorbell_offset0 = filter_param;
- break;
case KFD_UNMAP_QUEUES_FILTER_BY_PASID:
packet->bitfields2.queue_sel =
queue_sel__mes_unmap_queues__perform_request_on_pasid_queues;
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_pasid.c b/drivers/gpu/drm/amd/amdkfd/kfd_pasid.c
index af5816f51e55..e3b250918f39 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_pasid.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_pasid.c
@@ -1,5 +1,6 @@
+// SPDX-License-Identifier: GPL-2.0 OR MIT
/*
- * Copyright 2014 Advanced Micro Devices, Inc.
+ * Copyright 2014-2022 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_pm4_headers.h b/drivers/gpu/drm/amd/amdkfd/kfd_pm4_headers.h
index e50f73d25de6..7274edfd3f38 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_pm4_headers.h
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_pm4_headers.h
@@ -1,5 +1,6 @@
+/* SPDX-License-Identifier: GPL-2.0 OR MIT */
/*
- * Copyright 2014 Advanced Micro Devices, Inc.
+ * Copyright 2014-2022 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_pm4_headers_ai.h b/drivers/gpu/drm/amd/amdkfd/kfd_pm4_headers_ai.h
index 4d7add843746..a666710ed403 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_pm4_headers_ai.h
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_pm4_headers_ai.h
@@ -1,5 +1,6 @@
+/* SPDX-License-Identifier: GPL-2.0 OR MIT */
/*
- * Copyright 2016 Advanced Micro Devices, Inc.
+ * Copyright 2016-2022 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_pm4_headers_aldebaran.h b/drivers/gpu/drm/amd/amdkfd/kfd_pm4_headers_aldebaran.h
index f795ec815e2a..38f5cb6a222a 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_pm4_headers_aldebaran.h
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_pm4_headers_aldebaran.h
@@ -1,5 +1,6 @@
+/* SPDX-License-Identifier: GPL-2.0 OR MIT */
/*
- * Copyright 2020 Advanced Micro Devices, Inc.
+ * Copyright 2020-2022 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_pm4_headers_diq.h b/drivers/gpu/drm/amd/amdkfd/kfd_pm4_headers_diq.h
index a0ff34878163..f9cd28690151 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_pm4_headers_diq.h
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_pm4_headers_diq.h
@@ -1,5 +1,6 @@
+/* SPDX-License-Identifier: GPL-2.0 OR MIT */
/*
- * Copyright 2014 Advanced Micro Devices, Inc.
+ * Copyright 2014-2022 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_pm4_headers_vi.h b/drivers/gpu/drm/amd/amdkfd/kfd_pm4_headers_vi.h
index 5466cfe1c3cc..8147395c083b 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_pm4_headers_vi.h
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_pm4_headers_vi.h
@@ -1,5 +1,6 @@
+/* SPDX-License-Identifier: GPL-2.0 OR MIT */
/*
- * Copyright 2014 Advanced Micro Devices, Inc.
+ * Copyright 2014-2022 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@@ -101,8 +102,8 @@ struct pm4_mes_set_resources {
struct pm4_mes_runlist {
union {
- union PM4_MES_TYPE_3_HEADER header; /* header */
- uint32_t ordinal1;
+ union PM4_MES_TYPE_3_HEADER header; /* header */
+ uint32_t ordinal1;
};
union {
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_pm4_opcodes.h b/drivers/gpu/drm/amd/amdkfd/kfd_pm4_opcodes.h
index b72fa3b8c2d4..5bfd0f9cbe23 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_pm4_opcodes.h
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_pm4_opcodes.h
@@ -1,5 +1,6 @@
+/* SPDX-License-Identifier: GPL-2.0 OR MIT */
/*
- * Copyright 2014 Advanced Micro Devices, Inc.
+ * Copyright 2014-2022 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h
index ea68f3b3a4e9..9967a73d5b0f 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h
@@ -1,5 +1,6 @@
+/* SPDX-License-Identifier: GPL-2.0 OR MIT */
/*
- * Copyright 2014 Advanced Micro Devices, Inc.
+ * Copyright 2014-2022 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@@ -25,6 +26,7 @@
#include <linux/hashtable.h>
#include <linux/mmu_notifier.h>
+#include <linux/memremap.h>
#include <linux/mutex.h>
#include <linux/types.h>
#include <linux/atomic.h>
@@ -121,7 +123,26 @@
*/
#define KFD_QUEUE_DOORBELL_MIRROR_OFFSET 512
-
+/**
+ * enum kfd_ioctl_flags - KFD ioctl flags
+ * Various flags that can be set in &amdkfd_ioctl_desc.flags to control how
+ * userspace can use a given ioctl.
+ */
+enum kfd_ioctl_flags {
+ /*
+ * @KFD_IOC_FLAG_CHECKPOINT_RESTORE:
+ * Certain KFD ioctls such as AMDKFD_IOC_CRIU_OP can potentially
+ * perform privileged operations and load arbitrary data into MQDs and
+ * eventually HQD registers when the queue is mapped by HWS. In order to
+ * prevent this we should perform additional security checks.
+ *
+ * This is equivalent to callers with the CHECKPOINT_RESTORE capability.
+ *
+ * Note: Since earlier versions of docker do not support CHECKPOINT_RESTORE,
+ * we also allow ioctls with SYS_ADMIN capability.
+ */
+ KFD_IOC_FLAG_CHECKPOINT_RESTORE = BIT(0),
+};
/*
* Kernel module parameter to specify maximum number of supported queues per
* device
@@ -281,9 +302,6 @@ struct kfd_dev {
*/
bool interrupts_active;
- /* Debug manager */
- struct kfd_dbgmgr *dbgmgr;
-
/* Firmware versions */
uint16_t mec_fw_version;
uint16_t mec2_fw_version;
@@ -338,25 +356,24 @@ enum kfd_mempool {
/* Character device interface */
int kfd_chardev_init(void);
void kfd_chardev_exit(void);
-struct device *kfd_chardev(void);
/**
* enum kfd_unmap_queues_filter - Enum for queue filters.
*
- * @KFD_UNMAP_QUEUES_FILTER_SINGLE_QUEUE: Preempts single queue.
- *
* @KFD_UNMAP_QUEUES_FILTER_ALL_QUEUES: Preempts all queues in the
* running queues list.
*
+ * @KFD_UNMAP_QUEUES_FILTER_DYNAMIC_QUEUES: Preempts all non-static queues
+ * in the run list.
+ *
* @KFD_UNMAP_QUEUES_FILTER_BY_PASID: Preempts queues that belongs to
* specific process.
*
*/
enum kfd_unmap_queues_filter {
- KFD_UNMAP_QUEUES_FILTER_SINGLE_QUEUE,
- KFD_UNMAP_QUEUES_FILTER_ALL_QUEUES,
- KFD_UNMAP_QUEUES_FILTER_DYNAMIC_QUEUES,
- KFD_UNMAP_QUEUES_FILTER_BY_PASID
+ KFD_UNMAP_QUEUES_FILTER_ALL_QUEUES = 1,
+ KFD_UNMAP_QUEUES_FILTER_DYNAMIC_QUEUES = 2,
+ KFD_UNMAP_QUEUES_FILTER_BY_PASID = 3
};
/**
@@ -442,6 +459,7 @@ enum KFD_QUEUE_PRIORITY {
* it's user mode or kernel mode queue.
*
*/
+
struct queue_properties {
enum kfd_queue_type type;
enum kfd_queue_format format;
@@ -754,6 +772,12 @@ struct kfd_process_device {
uint64_t faults;
uint64_t page_in;
uint64_t page_out;
+ /*
+ * If this process has been checkpointed before, then the user
+ * application will use the original gpu_id on the
+ * checkpointed node to refer to this device.
+ */
+ uint32_t user_gpu_id;
};
#define qpd_to_pdd(x) container_of(x, struct kfd_process_device, qpd)
@@ -764,12 +788,13 @@ struct svm_range_list {
struct list_head list;
struct work_struct deferred_list_work;
struct list_head deferred_range_list;
+ struct list_head criu_svm_metadata_list;
spinlock_t deferred_list_lock;
atomic_t evicted_ranges;
atomic_t drain_pagefaults;
struct delayed_work restore_work;
DECLARE_BITMAP(bitmap_supported, MAX_GPU_INSTANCE);
- struct task_struct *faulting_task;
+ struct task_struct *faulting_task;
};
/* Process data */
@@ -858,6 +883,8 @@ struct kfd_process {
bool xnack_enabled;
atomic_t poison;
+ /* Queues are in paused stated because we are in the process of doing a CRIU checkpoint */
+ bool queues_paused;
};
#define KFD_PROCESS_TABLE_SIZE 5 /* bits: 32 entries */
@@ -888,7 +915,7 @@ bool kfd_dev_is_large_bar(struct kfd_dev *dev);
int kfd_process_create_wq(void);
void kfd_process_destroy_wq(void);
struct kfd_process *kfd_create_process(struct file *filep);
-struct kfd_process *kfd_get_process(const struct task_struct *);
+struct kfd_process *kfd_get_process(const struct task_struct *task);
struct kfd_process *kfd_lookup_process_by_pasid(u32 pasid);
struct kfd_process *kfd_lookup_process_by_mm(const struct mm_struct *mm);
@@ -911,6 +938,11 @@ int kfd_process_restore_queues(struct kfd_process *p);
void kfd_suspend_all_processes(void);
int kfd_resume_all_processes(void);
+struct kfd_process_device *kfd_process_device_data_by_id(struct kfd_process *process,
+ uint32_t gpu_id);
+
+int kfd_process_get_user_gpu_id(struct kfd_process *p, uint32_t actual_gpu_id);
+
int kfd_process_device_init_vm(struct kfd_process_device *pdd,
struct file *drm_file);
struct kfd_process_device *kfd_bind_process_to_device(struct kfd_dev *dev,
@@ -932,6 +964,7 @@ void *kfd_process_device_translate_handle(struct kfd_process_device *p,
int handle);
void kfd_process_device_remove_obj_handle(struct kfd_process_device *pdd,
int handle);
+struct kfd_process *kfd_lookup_process_by_pid(struct pid *pid);
/* PASIDs */
int kfd_pasid_init(void);
@@ -1006,6 +1039,116 @@ void kfd_process_set_trap_handler(struct qcm_process_device *qpd,
uint64_t tba_addr,
uint64_t tma_addr);
+/* CRIU */
+/*
+ * Need to increment KFD_CRIU_PRIV_VERSION each time a change is made to any of the CRIU private
+ * structures:
+ * kfd_criu_process_priv_data
+ * kfd_criu_device_priv_data
+ * kfd_criu_bo_priv_data
+ * kfd_criu_queue_priv_data
+ * kfd_criu_event_priv_data
+ * kfd_criu_svm_range_priv_data
+ */
+
+#define KFD_CRIU_PRIV_VERSION 1
+
+struct kfd_criu_process_priv_data {
+ uint32_t version;
+ uint32_t xnack_mode;
+};
+
+struct kfd_criu_device_priv_data {
+ /* For future use */
+ uint64_t reserved;
+};
+
+struct kfd_criu_bo_priv_data {
+ uint64_t user_addr;
+ uint32_t idr_handle;
+ uint32_t mapped_gpuids[MAX_GPU_INSTANCE];
+};
+
+/*
+ * The first 4 bytes of kfd_criu_queue_priv_data, kfd_criu_event_priv_data,
+ * kfd_criu_svm_range_priv_data is the object type
+ */
+enum kfd_criu_object_type {
+ KFD_CRIU_OBJECT_TYPE_QUEUE,
+ KFD_CRIU_OBJECT_TYPE_EVENT,
+ KFD_CRIU_OBJECT_TYPE_SVM_RANGE,
+};
+
+struct kfd_criu_svm_range_priv_data {
+ uint32_t object_type;
+ uint64_t start_addr;
+ uint64_t size;
+ /* Variable length array of attributes */
+ struct kfd_ioctl_svm_attribute attrs[];
+};
+
+struct kfd_criu_queue_priv_data {
+ uint32_t object_type;
+ uint64_t q_address;
+ uint64_t q_size;
+ uint64_t read_ptr_addr;
+ uint64_t write_ptr_addr;
+ uint64_t doorbell_off;
+ uint64_t eop_ring_buffer_address;
+ uint64_t ctx_save_restore_area_address;
+ uint32_t gpu_id;
+ uint32_t type;
+ uint32_t format;
+ uint32_t q_id;
+ uint32_t priority;
+ uint32_t q_percent;
+ uint32_t doorbell_id;
+ uint32_t is_gws;
+ uint32_t sdma_id;
+ uint32_t eop_ring_buffer_size;
+ uint32_t ctx_save_restore_area_size;
+ uint32_t ctl_stack_size;
+ uint32_t mqd_size;
+};
+
+struct kfd_criu_event_priv_data {
+ uint32_t object_type;
+ uint64_t user_handle;
+ uint32_t event_id;
+ uint32_t auto_reset;
+ uint32_t type;
+ uint32_t signaled;
+
+ union {
+ struct kfd_hsa_memory_exception_data memory_exception_data;
+ struct kfd_hsa_hw_exception_data hw_exception_data;
+ };
+};
+
+int kfd_process_get_queue_info(struct kfd_process *p,
+ uint32_t *num_queues,
+ uint64_t *priv_data_sizes);
+
+int kfd_criu_checkpoint_queues(struct kfd_process *p,
+ uint8_t __user *user_priv_data,
+ uint64_t *priv_data_offset);
+
+int kfd_criu_restore_queue(struct kfd_process *p,
+ uint8_t __user *user_priv_data,
+ uint64_t *priv_data_offset,
+ uint64_t max_priv_data_size);
+
+int kfd_criu_checkpoint_events(struct kfd_process *p,
+ uint8_t __user *user_priv_data,
+ uint64_t *priv_data_offset);
+
+int kfd_criu_restore_event(struct file *devkfd,
+ struct kfd_process *p,
+ uint8_t __user *user_priv_data,
+ uint64_t *priv_data_offset,
+ uint64_t max_priv_data_size);
+/* CRIU - End */
+
/* Queue Context Management */
int init_queue(struct queue **q, const struct queue_properties *properties);
void uninit_queue(struct queue *q);
@@ -1029,7 +1172,7 @@ void device_queue_manager_uninit(struct device_queue_manager *dqm);
struct kernel_queue *kernel_queue_init(struct kfd_dev *dev,
enum kfd_queue_type type);
void kernel_queue_uninit(struct kernel_queue *kq, bool hanging);
-int kfd_process_vm_fault(struct device_queue_manager *dqm, u32 pasid);
+int kfd_dqm_evict_pasid(struct device_queue_manager *dqm, u32 pasid);
/* Process Queue Manager */
struct process_queue_node {
@@ -1047,6 +1190,9 @@ int pqm_create_queue(struct process_queue_manager *pqm,
struct file *f,
struct queue_properties *properties,
unsigned int *qid,
+ const struct kfd_criu_queue_priv_data *q_data,
+ const void *restore_mqd,
+ const void *restore_ctl_stack,
uint32_t *p_doorbell_offset_in_process);
int pqm_destroy_queue(struct process_queue_manager *pqm, unsigned int qid);
int pqm_update_queue_properties(struct process_queue_manager *pqm, unsigned int qid,
@@ -1069,6 +1215,10 @@ int amdkfd_fence_wait_timeout(uint64_t *fence_addr,
uint64_t fence_value,
unsigned int timeout_ms);
+int pqm_get_queue_checkpoint_info(struct process_queue_manager *pqm,
+ unsigned int qid,
+ u32 *mqd_size,
+ u32 *ctl_stack_size);
/* Packet Manager */
#define KFD_FENCE_COMPLETED (100)
@@ -1097,10 +1247,8 @@ struct packet_manager_funcs {
int (*map_queues)(struct packet_manager *pm, uint32_t *buffer,
struct queue *q, bool is_static);
int (*unmap_queues)(struct packet_manager *pm, uint32_t *buffer,
- enum kfd_queue_type type,
enum kfd_unmap_queues_filter mode,
- uint32_t filter_param, bool reset,
- unsigned int sdma_engine);
+ uint32_t filter_param, bool reset);
int (*query_status)(struct packet_manager *pm, uint32_t *buffer,
uint64_t fence_address, uint64_t fence_value);
int (*release_mem)(uint64_t gpu_addr, uint32_t *buffer);
@@ -1127,10 +1275,9 @@ int pm_send_runlist(struct packet_manager *pm, struct list_head *dqm_queues);
int pm_send_query_status(struct packet_manager *pm, uint64_t fence_address,
uint64_t fence_value);
-int pm_send_unmap_queue(struct packet_manager *pm, enum kfd_queue_type type,
+int pm_send_unmap_queue(struct packet_manager *pm,
enum kfd_unmap_queues_filter mode,
- uint32_t filter_param, bool reset,
- unsigned int sdma_engine);
+ uint32_t filter_param, bool reset);
void pm_release_ib(struct packet_manager *pm);
@@ -1160,12 +1307,14 @@ void kfd_signal_iommu_event(struct kfd_dev *dev,
void kfd_signal_hw_exception_event(u32 pasid);
int kfd_set_event(struct kfd_process *p, uint32_t event_id);
int kfd_reset_event(struct kfd_process *p, uint32_t event_id);
-int kfd_event_page_set(struct kfd_process *p, void *kernel_address,
- uint64_t size);
+int kfd_kmap_event_page(struct kfd_process *p, uint64_t event_page_offset);
+
int kfd_event_create(struct file *devkfd, struct kfd_process *p,
uint32_t event_type, bool auto_reset, uint32_t node_id,
uint32_t *event_id, uint32_t *event_trigger_data,
uint64_t *event_page_offset, uint32_t *event_slot_index);
+
+int kfd_get_num_events(struct kfd_process *p);
int kfd_event_destroy(struct kfd_process *p, uint32_t event_id);
void kfd_signal_vm_fault_event(struct kfd_dev *dev, u32 pasid,
@@ -1177,8 +1326,6 @@ void kfd_signal_poison_consumed_event(struct kfd_dev *dev, u32 pasid);
void kfd_flush_tlb(struct kfd_process_device *pdd, enum TLB_FLUSH_TYPE type);
-int dbgdev_wave_reset_wavefronts(struct kfd_dev *dev, struct kfd_process *p);
-
bool kfd_is_locked(void);
/* Compute profile */
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_process.c b/drivers/gpu/drm/amd/amdkfd/kfd_process.c
index d1145da5348f..59c04b2d383b 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_process.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_process.c
@@ -1,5 +1,6 @@
+// SPDX-License-Identifier: GPL-2.0 OR MIT
/*
- * Copyright 2014 Advanced Micro Devices, Inc.
+ * Copyright 2014-2022 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@@ -40,7 +41,6 @@ struct mm_struct;
#include "kfd_priv.h"
#include "kfd_device_queue_manager.h"
-#include "kfd_dbgmgr.h"
#include "kfd_iommu.h"
#include "kfd_svm.h"
@@ -64,7 +64,8 @@ static struct workqueue_struct *kfd_process_wq;
*/
static struct workqueue_struct *kfd_restore_wq;
-static struct kfd_process *find_process(const struct task_struct *thread);
+static struct kfd_process *find_process(const struct task_struct *thread,
+ bool ref);
static void kfd_process_ref_release(struct kref *ref);
static struct kfd_process *create_process(const struct task_struct *thread);
static int kfd_process_init_cwsr_apu(struct kfd_process *p, struct file *filep);
@@ -715,7 +716,8 @@ static int kfd_process_alloc_gpuvm(struct kfd_process_device *pdd,
int err;
err = amdgpu_amdkfd_gpuvm_alloc_memory_of_gpu(kdev->adev, gpu_va, size,
- pdd->drm_priv, mem, NULL, flags);
+ pdd->drm_priv, mem, NULL,
+ flags, false);
if (err)
goto err_alloc_mem;
@@ -816,7 +818,7 @@ struct kfd_process *kfd_create_process(struct file *filep)
mutex_lock(&kfd_processes_mutex);
/* A prior open of /dev/kfd could have already created the process. */
- process = find_process(thread);
+ process = find_process(thread, false);
if (process) {
pr_debug("Process already found\n");
} else {
@@ -884,7 +886,7 @@ struct kfd_process *kfd_get_process(const struct task_struct *thread)
if (thread->group_leader->mm != thread->mm)
return ERR_PTR(-EINVAL);
- process = find_process(thread);
+ process = find_process(thread, false);
if (!process)
return ERR_PTR(-EINVAL);
@@ -903,13 +905,16 @@ static struct kfd_process *find_process_by_mm(const struct mm_struct *mm)
return NULL;
}
-static struct kfd_process *find_process(const struct task_struct *thread)
+static struct kfd_process *find_process(const struct task_struct *thread,
+ bool ref)
{
struct kfd_process *p;
int idx;
idx = srcu_read_lock(&kfd_processes_srcu);
p = find_process_by_mm(thread->mm);
+ if (p && ref)
+ kref_get(&p->ref);
srcu_read_unlock(&kfd_processes_srcu, idx);
return p;
@@ -920,6 +925,26 @@ void kfd_unref_process(struct kfd_process *p)
kref_put(&p->ref, kfd_process_ref_release);
}
+/* This increments the process->ref counter. */
+struct kfd_process *kfd_lookup_process_by_pid(struct pid *pid)
+{
+ struct task_struct *task = NULL;
+ struct kfd_process *p = NULL;
+
+ if (!pid) {
+ task = current;
+ get_task_struct(task);
+ } else {
+ task = get_pid_task(pid, PIDTYPE_PID);
+ }
+
+ if (task) {
+ p = find_process(task, true);
+ put_task_struct(task);
+ }
+
+ return p;
+}
static void kfd_process_device_free_bos(struct kfd_process_device *pdd)
{
@@ -1133,7 +1158,6 @@ static void kfd_process_notifier_release(struct mmu_notifier *mn,
struct mm_struct *mm)
{
struct kfd_process *p;
- int i;
/*
* The kfd_process structure can not be free because the
@@ -1150,27 +1174,9 @@ static void kfd_process_notifier_release(struct mmu_notifier *mn,
cancel_delayed_work_sync(&p->eviction_work);
cancel_delayed_work_sync(&p->restore_work);
- cancel_delayed_work_sync(&p->svms.restore_work);
mutex_lock(&p->mutex);
- /* Iterate over all process device data structures and if the
- * pdd is in debug mode, we should first force unregistration,
- * then we will be able to destroy the queues
- */
- for (i = 0; i < p->n_pdds; i++) {
- struct kfd_dev *dev = p->pdds[i]->dev;
-
- mutex_lock(kfd_get_dbgmgr_mutex());
- if (dev && dev->dbgmgr && dev->dbgmgr->pasid == p->pasid) {
- if (!kfd_dbgmgr_unregister(dev->dbgmgr, p)) {
- kfd_dbgmgr_destroy(dev->dbgmgr);
- dev->dbgmgr = NULL;
- }
- }
- mutex_unlock(kfd_get_dbgmgr_mutex());
- }
-
kfd_process_dequeue_from_all_devices(p);
pqm_uninit(&p->pqm);
@@ -1360,6 +1366,7 @@ static struct kfd_process *create_process(const struct task_struct *thread)
process->mm = thread->mm;
process->lead_thread = thread->group_leader;
process->n_pdds = 0;
+ process->queues_paused = false;
INIT_DELAYED_WORK(&process->eviction_work, evict_process_worker);
INIT_DELAYED_WORK(&process->restore_work, restore_process_worker);
process->last_restore_timestamp = get_jiffies_64();
@@ -1501,6 +1508,7 @@ struct kfd_process_device *kfd_create_process_device_data(struct kfd_dev *dev,
pdd->runtime_inuse = false;
pdd->vram_usage = 0;
pdd->sdma_past_activity_counter = 0;
+ pdd->user_gpu_id = dev->id;
atomic64_set(&pdd->evict_duration_counter, 0);
p->pdds[p->n_pdds++] = pdd;
@@ -1771,7 +1779,7 @@ int kfd_process_gpuidx_from_gpuid(struct kfd_process *p, uint32_t gpu_id)
int i;
for (i = 0; i < p->n_pdds; i++)
- if (p->pdds[i] && gpu_id == p->pdds[i]->dev->id)
+ if (p->pdds[i] && gpu_id == p->pdds[i]->user_gpu_id)
return i;
return -EINVAL;
}
@@ -1784,7 +1792,7 @@ kfd_process_gpuid_from_adev(struct kfd_process *p, struct amdgpu_device *adev,
for (i = 0; i < p->n_pdds; i++)
if (p->pdds[i] && p->pdds[i]->dev->adev == adev) {
- *gpuid = p->pdds[i]->dev->id;
+ *gpuid = p->pdds[i]->user_gpu_id;
*gpuidx = i;
return 0;
}
@@ -1956,6 +1964,37 @@ void kfd_flush_tlb(struct kfd_process_device *pdd, enum TLB_FLUSH_TYPE type)
}
}
+struct kfd_process_device *kfd_process_device_data_by_id(struct kfd_process *p, uint32_t gpu_id)
+{
+ int i;
+
+ if (gpu_id) {
+ for (i = 0; i < p->n_pdds; i++) {
+ struct kfd_process_device *pdd = p->pdds[i];
+
+ if (pdd->user_gpu_id == gpu_id)
+ return pdd;
+ }
+ }
+ return NULL;
+}
+
+int kfd_process_get_user_gpu_id(struct kfd_process *p, uint32_t actual_gpu_id)
+{
+ int i;
+
+ if (!actual_gpu_id)
+ return 0;
+
+ for (i = 0; i < p->n_pdds; i++) {
+ struct kfd_process_device *pdd = p->pdds[i];
+
+ if (pdd->dev->id == actual_gpu_id)
+ return pdd->user_gpu_id;
+ }
+ return -EINVAL;
+}
+
#if defined(CONFIG_DEBUG_FS)
int kfd_debugfs_mqds_by_process(struct seq_file *m, void *data)
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c
index 5e5c84a8e1ef..6eca9509f2e3 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c
@@ -1,5 +1,6 @@
+// SPDX-License-Identifier: GPL-2.0 OR MIT
/*
- * Copyright 2014 Advanced Micro Devices, Inc.
+ * Copyright 2014-2022 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@@ -42,6 +43,20 @@ static inline struct process_queue_node *get_queue_by_qid(
return NULL;
}
+static int assign_queue_slot_by_qid(struct process_queue_manager *pqm,
+ unsigned int qid)
+{
+ if (qid >= KFD_MAX_NUM_OF_QUEUES_PER_PROCESS)
+ return -EINVAL;
+
+ if (__test_and_set_bit(qid, pqm->queue_slot_bitmap)) {
+ pr_err("Cannot create new queue because requested qid(%u) is in use\n", qid);
+ return -ENOSPC;
+ }
+
+ return 0;
+}
+
static int find_available_queue_slot(struct process_queue_manager *pqm,
unsigned int *qid)
{
@@ -193,6 +208,9 @@ int pqm_create_queue(struct process_queue_manager *pqm,
struct file *f,
struct queue_properties *properties,
unsigned int *qid,
+ const struct kfd_criu_queue_priv_data *q_data,
+ const void *restore_mqd,
+ const void *restore_ctl_stack,
uint32_t *p_doorbell_offset_in_process)
{
int retval;
@@ -224,7 +242,12 @@ int pqm_create_queue(struct process_queue_manager *pqm,
if (pdd->qpd.queue_count >= max_queues)
return -ENOSPC;
- retval = find_available_queue_slot(pqm, qid);
+ if (q_data) {
+ retval = assign_queue_slot_by_qid(pqm, q_data->q_id);
+ *qid = q_data->q_id;
+ } else
+ retval = find_available_queue_slot(pqm, qid);
+
if (retval != 0)
return retval;
@@ -252,7 +275,8 @@ int pqm_create_queue(struct process_queue_manager *pqm,
goto err_create_queue;
pqn->q = q;
pqn->kq = NULL;
- retval = dev->dqm->ops.create_queue(dev->dqm, q, &pdd->qpd);
+ retval = dev->dqm->ops.create_queue(dev->dqm, q, &pdd->qpd, q_data,
+ restore_mqd, restore_ctl_stack);
print_queue(q);
break;
@@ -272,7 +296,8 @@ int pqm_create_queue(struct process_queue_manager *pqm,
goto err_create_queue;
pqn->q = q;
pqn->kq = NULL;
- retval = dev->dqm->ops.create_queue(dev->dqm, q, &pdd->qpd);
+ retval = dev->dqm->ops.create_queue(dev->dqm, q, &pdd->qpd, q_data,
+ restore_mqd, restore_ctl_stack);
print_queue(q);
break;
case KFD_QUEUE_TYPE_DIQ:
@@ -497,6 +522,348 @@ int pqm_get_wave_state(struct process_queue_manager *pqm,
save_area_used_size);
}
+static int get_queue_data_sizes(struct kfd_process_device *pdd,
+ struct queue *q,
+ uint32_t *mqd_size,
+ uint32_t *ctl_stack_size)
+{
+ int ret;
+
+ ret = pqm_get_queue_checkpoint_info(&pdd->process->pqm,
+ q->properties.queue_id,
+ mqd_size,
+ ctl_stack_size);
+ if (ret)
+ pr_err("Failed to get queue dump info (%d)\n", ret);
+
+ return ret;
+}
+
+int kfd_process_get_queue_info(struct kfd_process *p,
+ uint32_t *num_queues,
+ uint64_t *priv_data_sizes)
+{
+ uint32_t extra_data_sizes = 0;
+ struct queue *q;
+ int i;
+ int ret;
+
+ *num_queues = 0;
+
+ /* Run over all PDDs of the process */
+ for (i = 0; i < p->n_pdds; i++) {
+ struct kfd_process_device *pdd = p->pdds[i];
+
+ list_for_each_entry(q, &pdd->qpd.queues_list, list) {
+ if (q->properties.type == KFD_QUEUE_TYPE_COMPUTE ||
+ q->properties.type == KFD_QUEUE_TYPE_SDMA ||
+ q->properties.type == KFD_QUEUE_TYPE_SDMA_XGMI) {
+ uint32_t mqd_size, ctl_stack_size;
+
+ *num_queues = *num_queues + 1;
+
+ ret = get_queue_data_sizes(pdd, q, &mqd_size, &ctl_stack_size);
+ if (ret)
+ return ret;
+
+ extra_data_sizes += mqd_size + ctl_stack_size;
+ } else {
+ pr_err("Unsupported queue type (%d)\n", q->properties.type);
+ return -EOPNOTSUPP;
+ }
+ }
+ }
+ *priv_data_sizes = extra_data_sizes +
+ (*num_queues * sizeof(struct kfd_criu_queue_priv_data));
+
+ return 0;
+}
+
+static int pqm_checkpoint_mqd(struct process_queue_manager *pqm,
+ unsigned int qid,
+ void *mqd,
+ void *ctl_stack)
+{
+ struct process_queue_node *pqn;
+
+ pqn = get_queue_by_qid(pqm, qid);
+ if (!pqn) {
+ pr_debug("amdkfd: No queue %d exists for operation\n", qid);
+ return -EFAULT;
+ }
+
+ if (!pqn->q->device->dqm->ops.checkpoint_mqd) {
+ pr_err("amdkfd: queue dumping not supported on this device\n");
+ return -EOPNOTSUPP;
+ }
+
+ return pqn->q->device->dqm->ops.checkpoint_mqd(pqn->q->device->dqm,
+ pqn->q, mqd, ctl_stack);
+}
+
+static int criu_checkpoint_queue(struct kfd_process_device *pdd,
+ struct queue *q,
+ struct kfd_criu_queue_priv_data *q_data)
+{
+ uint8_t *mqd, *ctl_stack;
+ int ret;
+
+ mqd = (void *)(q_data + 1);
+ ctl_stack = mqd + q_data->mqd_size;
+
+ q_data->gpu_id = pdd->user_gpu_id;
+ q_data->type = q->properties.type;
+ q_data->format = q->properties.format;
+ q_data->q_id = q->properties.queue_id;
+ q_data->q_address = q->properties.queue_address;
+ q_data->q_size = q->properties.queue_size;
+ q_data->priority = q->properties.priority;
+ q_data->q_percent = q->properties.queue_percent;
+ q_data->read_ptr_addr = (uint64_t)q->properties.read_ptr;
+ q_data->write_ptr_addr = (uint64_t)q->properties.write_ptr;
+ q_data->doorbell_id = q->doorbell_id;
+
+ q_data->sdma_id = q->sdma_id;
+
+ q_data->eop_ring_buffer_address =
+ q->properties.eop_ring_buffer_address;
+
+ q_data->eop_ring_buffer_size = q->properties.eop_ring_buffer_size;
+
+ q_data->ctx_save_restore_area_address =
+ q->properties.ctx_save_restore_area_address;
+
+ q_data->ctx_save_restore_area_size =
+ q->properties.ctx_save_restore_area_size;
+
+ ret = pqm_checkpoint_mqd(&pdd->process->pqm, q->properties.queue_id, mqd, ctl_stack);
+ if (ret) {
+ pr_err("Failed checkpoint queue_mqd (%d)\n", ret);
+ return ret;
+ }
+
+ pr_debug("Dumping Queue: gpu_id:%x queue_id:%u\n", q_data->gpu_id, q_data->q_id);
+ return ret;
+}
+
+static int criu_checkpoint_queues_device(struct kfd_process_device *pdd,
+ uint8_t __user *user_priv,
+ unsigned int *q_index,
+ uint64_t *queues_priv_data_offset)
+{
+ unsigned int q_private_data_size = 0;
+ uint8_t *q_private_data = NULL; /* Local buffer to store individual queue private data */
+ struct queue *q;
+ int ret = 0;
+
+ list_for_each_entry(q, &pdd->qpd.queues_list, list) {
+ struct kfd_criu_queue_priv_data *q_data;
+ uint64_t q_data_size;
+ uint32_t mqd_size;
+ uint32_t ctl_stack_size;
+
+ if (q->properties.type != KFD_QUEUE_TYPE_COMPUTE &&
+ q->properties.type != KFD_QUEUE_TYPE_SDMA &&
+ q->properties.type != KFD_QUEUE_TYPE_SDMA_XGMI) {
+
+ pr_err("Unsupported queue type (%d)\n", q->properties.type);
+ ret = -EOPNOTSUPP;
+ break;
+ }
+
+ ret = get_queue_data_sizes(pdd, q, &mqd_size, &ctl_stack_size);
+ if (ret)
+ break;
+
+ q_data_size = sizeof(*q_data) + mqd_size + ctl_stack_size;
+
+ /* Increase local buffer space if needed */
+ if (q_private_data_size < q_data_size) {
+ kfree(q_private_data);
+
+ q_private_data = kzalloc(q_data_size, GFP_KERNEL);
+ if (!q_private_data) {
+ ret = -ENOMEM;
+ break;
+ }
+ q_private_data_size = q_data_size;
+ }
+
+ q_data = (struct kfd_criu_queue_priv_data *)q_private_data;
+
+ /* data stored in this order: priv_data, mqd, ctl_stack */
+ q_data->mqd_size = mqd_size;
+ q_data->ctl_stack_size = ctl_stack_size;
+
+ ret = criu_checkpoint_queue(pdd, q, q_data);
+ if (ret)
+ break;
+
+ q_data->object_type = KFD_CRIU_OBJECT_TYPE_QUEUE;
+
+ ret = copy_to_user(user_priv + *queues_priv_data_offset,
+ q_data, q_data_size);
+ if (ret) {
+ ret = -EFAULT;
+ break;
+ }
+ *queues_priv_data_offset += q_data_size;
+ *q_index = *q_index + 1;
+ }
+
+ kfree(q_private_data);
+
+ return ret;
+}
+
+int kfd_criu_checkpoint_queues(struct kfd_process *p,
+ uint8_t __user *user_priv_data,
+ uint64_t *priv_data_offset)
+{
+ int ret = 0, pdd_index, q_index = 0;
+
+ for (pdd_index = 0; pdd_index < p->n_pdds; pdd_index++) {
+ struct kfd_process_device *pdd = p->pdds[pdd_index];
+
+ /*
+ * criu_checkpoint_queues_device will copy data to user and update q_index and
+ * queues_priv_data_offset
+ */
+ ret = criu_checkpoint_queues_device(pdd, user_priv_data, &q_index,
+ priv_data_offset);
+
+ if (ret)
+ break;
+ }
+
+ return ret;
+}
+
+static void set_queue_properties_from_criu(struct queue_properties *qp,
+ struct kfd_criu_queue_priv_data *q_data)
+{
+ qp->is_interop = false;
+ qp->is_gws = q_data->is_gws;
+ qp->queue_percent = q_data->q_percent;
+ qp->priority = q_data->priority;
+ qp->queue_address = q_data->q_address;
+ qp->queue_size = q_data->q_size;
+ qp->read_ptr = (uint32_t *) q_data->read_ptr_addr;
+ qp->write_ptr = (uint32_t *) q_data->write_ptr_addr;
+ qp->eop_ring_buffer_address = q_data->eop_ring_buffer_address;
+ qp->eop_ring_buffer_size = q_data->eop_ring_buffer_size;
+ qp->ctx_save_restore_area_address = q_data->ctx_save_restore_area_address;
+ qp->ctx_save_restore_area_size = q_data->ctx_save_restore_area_size;
+ qp->ctl_stack_size = q_data->ctl_stack_size;
+ qp->type = q_data->type;
+ qp->format = q_data->format;
+}
+
+int kfd_criu_restore_queue(struct kfd_process *p,
+ uint8_t __user *user_priv_ptr,
+ uint64_t *priv_data_offset,
+ uint64_t max_priv_data_size)
+{
+ uint8_t *mqd, *ctl_stack, *q_extra_data = NULL;
+ struct kfd_criu_queue_priv_data *q_data;
+ struct kfd_process_device *pdd;
+ uint64_t q_extra_data_size;
+ struct queue_properties qp;
+ unsigned int queue_id;
+ int ret = 0;
+
+ if (*priv_data_offset + sizeof(*q_data) > max_priv_data_size)
+ return -EINVAL;
+
+ q_data = kmalloc(sizeof(*q_data), GFP_KERNEL);
+ if (!q_data)
+ return -ENOMEM;
+
+ ret = copy_from_user(q_data, user_priv_ptr + *priv_data_offset, sizeof(*q_data));
+ if (ret) {
+ ret = -EFAULT;
+ goto exit;
+ }
+
+ *priv_data_offset += sizeof(*q_data);
+ q_extra_data_size = (uint64_t)q_data->ctl_stack_size + q_data->mqd_size;
+
+ if (*priv_data_offset + q_extra_data_size > max_priv_data_size) {
+ ret = -EINVAL;
+ goto exit;
+ }
+
+ q_extra_data = kmalloc(q_extra_data_size, GFP_KERNEL);
+ if (!q_extra_data) {
+ ret = -ENOMEM;
+ goto exit;
+ }
+
+ ret = copy_from_user(q_extra_data, user_priv_ptr + *priv_data_offset, q_extra_data_size);
+ if (ret) {
+ ret = -EFAULT;
+ goto exit;
+ }
+
+ *priv_data_offset += q_extra_data_size;
+
+ pdd = kfd_process_device_data_by_id(p, q_data->gpu_id);
+ if (!pdd) {
+ pr_err("Failed to get pdd\n");
+ ret = -EINVAL;
+ goto exit;
+ }
+ /* data stored in this order: mqd, ctl_stack */
+ mqd = q_extra_data;
+ ctl_stack = mqd + q_data->mqd_size;
+
+ memset(&qp, 0, sizeof(qp));
+ set_queue_properties_from_criu(&qp, q_data);
+
+ print_queue_properties(&qp);
+
+ ret = pqm_create_queue(&p->pqm, pdd->dev, NULL, &qp, &queue_id, q_data, mqd, ctl_stack,
+ NULL);
+ if (ret) {
+ pr_err("Failed to create new queue err:%d\n", ret);
+ ret = -EINVAL;
+ }
+
+exit:
+ if (ret)
+ pr_err("Failed to create queue (%d)\n", ret);
+ else
+ pr_debug("Queue id %d was restored successfully\n", queue_id);
+
+ kfree(q_data);
+
+ return ret;
+}
+
+int pqm_get_queue_checkpoint_info(struct process_queue_manager *pqm,
+ unsigned int qid,
+ uint32_t *mqd_size,
+ uint32_t *ctl_stack_size)
+{
+ struct process_queue_node *pqn;
+
+ pqn = get_queue_by_qid(pqm, qid);
+ if (!pqn) {
+ pr_debug("amdkfd: No queue %d exists for operation\n", qid);
+ return -EFAULT;
+ }
+
+ if (!pqn->q->device->dqm->ops.get_queue_checkpoint_info) {
+ pr_err("amdkfd: queue dumping not supported on this device\n");
+ return -EOPNOTSUPP;
+ }
+
+ pqn->q->device->dqm->ops.get_queue_checkpoint_info(pqn->q->device->dqm,
+ pqn->q, mqd_size,
+ ctl_stack_size);
+ return 0;
+}
+
#if defined(CONFIG_DEBUG_FS)
int pqm_debugfs_mqds(struct seq_file *m, void *data)
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_queue.c b/drivers/gpu/drm/amd/amdkfd/kfd_queue.c
index 6dcd621e5b71..0f6992b1895c 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_queue.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_queue.c
@@ -1,5 +1,6 @@
+// SPDX-License-Identifier: GPL-2.0 OR MIT
/*
- * Copyright 2014 Advanced Micro Devices, Inc.
+ * Copyright 2014-2022 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_smi_events.c b/drivers/gpu/drm/amd/amdkfd/kfd_smi_events.c
index deae12dc777d..e4beebb1c80a 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_smi_events.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_smi_events.c
@@ -1,5 +1,6 @@
+// SPDX-License-Identifier: GPL-2.0 OR MIT
/*
- * Copyright 2020 Advanced Micro Devices, Inc.
+ * Copyright 2020-2022 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@@ -81,7 +82,8 @@ static ssize_t kfd_smi_ev_read(struct file *filep, char __user *user,
struct kfd_smi_client *client = filep->private_data;
unsigned char *buf;
- buf = kmalloc_array(MAX_KFIFO_SIZE, sizeof(*buf), GFP_KERNEL);
+ size = min_t(size_t, size, MAX_KFIFO_SIZE);
+ buf = kmalloc(size, GFP_KERNEL);
if (!buf)
return -ENOMEM;
@@ -95,7 +97,7 @@ static ssize_t kfd_smi_ev_read(struct file *filep, char __user *user,
ret = -EAGAIN;
goto ret_err;
}
- to_copy = min3(size, sizeof(buf), to_copy);
+ to_copy = min(size, to_copy);
ret = kfifo_out(&client->fifo, buf, to_copy);
spin_unlock(&client->lock);
if (ret <= 0) {
@@ -174,22 +176,29 @@ static void add_event_to_kfifo(struct kfd_dev *dev, unsigned int smi_event,
rcu_read_unlock();
}
-void kfd_smi_event_update_gpu_reset(struct kfd_dev *dev, bool post_reset)
+__printf(3, 4)
+static void kfd_smi_event_add(struct kfd_dev *dev, unsigned int event,
+ char *fmt, ...)
{
- /*
- * GpuReset msg = Reset seq number (incremented for
- * every reset message sent before GPU reset).
- * 1 byte event + 1 byte space + 8 bytes seq num +
- * 1 byte \n + 1 byte \0 = 12
- */
- char fifo_in[12];
+ char fifo_in[KFD_SMI_EVENT_MSG_SIZE];
int len;
- unsigned int event;
+ va_list args;
if (list_empty(&dev->smi_clients))
return;
- memset(fifo_in, 0x0, sizeof(fifo_in));
+ len = snprintf(fifo_in, sizeof(fifo_in), "%x ", event);
+
+ va_start(args, fmt);
+ len += vsnprintf(fifo_in + len, sizeof(fifo_in) - len, fmt, args);
+ va_end(args);
+
+ add_event_to_kfifo(dev, event, fifo_in, len);
+}
+
+void kfd_smi_event_update_gpu_reset(struct kfd_dev *dev, bool post_reset)
+{
+ unsigned int event;
if (post_reset) {
event = KFD_SMI_EVENT_GPU_POST_RESET;
@@ -197,48 +206,20 @@ void kfd_smi_event_update_gpu_reset(struct kfd_dev *dev, bool post_reset)
event = KFD_SMI_EVENT_GPU_PRE_RESET;
++(dev->reset_seq_num);
}
-
- len = snprintf(fifo_in, sizeof(fifo_in), "%x %x\n", event,
- dev->reset_seq_num);
-
- add_event_to_kfifo(dev, event, fifo_in, len);
+ kfd_smi_event_add(dev, event, "%x\n", dev->reset_seq_num);
}
void kfd_smi_event_update_thermal_throttling(struct kfd_dev *dev,
uint64_t throttle_bitmask)
{
- /*
- * ThermalThrottle msg = throttle_bitmask(8):
- * thermal_interrupt_count(16):
- * 1 byte event + 1 byte space + 16 byte throttle_bitmask +
- * 1 byte : + 16 byte thermal_interupt_counter + 1 byte \n +
- * 1 byte \0 = 37
- */
- char fifo_in[37];
- int len;
-
- if (list_empty(&dev->smi_clients))
- return;
-
- len = snprintf(fifo_in, sizeof(fifo_in), "%x %llx:%llx\n",
- KFD_SMI_EVENT_THERMAL_THROTTLE, throttle_bitmask,
- atomic64_read(&dev->adev->smu.throttle_int_counter));
-
- add_event_to_kfifo(dev, KFD_SMI_EVENT_THERMAL_THROTTLE, fifo_in, len);
+ kfd_smi_event_add(dev, KFD_SMI_EVENT_THERMAL_THROTTLE, "%llx:%llx\n",
+ throttle_bitmask,
+ amdgpu_dpm_get_thermal_throttling_counter(dev->adev));
}
void kfd_smi_event_update_vmfault(struct kfd_dev *dev, uint16_t pasid)
{
struct amdgpu_task_info task_info;
- /* VmFault msg = (hex)uint32_pid(8) + :(1) + task name(16) = 25 */
- /* 1 byte event + 1 byte space + 25 bytes msg + 1 byte \n +
- * 1 byte \0 = 29
- */
- char fifo_in[29];
- int len;
-
- if (list_empty(&dev->smi_clients))
- return;
memset(&task_info, 0, sizeof(struct amdgpu_task_info));
amdgpu_vm_get_task_info(dev->adev, pasid, &task_info);
@@ -246,10 +227,8 @@ void kfd_smi_event_update_vmfault(struct kfd_dev *dev, uint16_t pasid)
if (!task_info.pid)
return;
- len = snprintf(fifo_in, sizeof(fifo_in), "%x %x:%s\n", KFD_SMI_EVENT_VMFAULT,
- task_info.pid, task_info.task_name);
-
- add_event_to_kfifo(dev, KFD_SMI_EVENT_VMFAULT, fifo_in, len);
+ kfd_smi_event_add(dev, KFD_SMI_EVENT_VMFAULT, "%x:%s\n",
+ task_info.pid, task_info.task_name);
}
int kfd_smi_event_open(struct kfd_dev *dev, uint32_t *fd)
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_smi_events.h b/drivers/gpu/drm/amd/amdkfd/kfd_smi_events.h
index bffd0c32b060..dfe101c21166 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_smi_events.h
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_smi_events.h
@@ -1,5 +1,6 @@
+/* SPDX-License-Identifier: GPL-2.0 OR MIT */
/*
- * Copyright 2020 Advanced Micro Devices, Inc.
+ * Copyright 2020-2022 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_svm.c b/drivers/gpu/drm/amd/amdkfd/kfd_svm.c
index f2805ba74c80..3b8856b4cece 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_svm.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_svm.c
@@ -45,6 +45,11 @@
*/
#define AMDGPU_SVM_RANGE_RETRY_FAULT_PENDING 2000
+struct criu_svm_metadata {
+ struct list_head list;
+ struct kfd_criu_svm_range_priv_data data;
+};
+
static void svm_range_evict_svm_bo_worker(struct work_struct *work);
static bool
svm_range_cpu_invalidate_pagetables(struct mmu_interval_notifier *mni,
@@ -1224,19 +1229,20 @@ svm_range_unmap_from_gpus(struct svm_range *prange, unsigned long start,
if (r)
break;
}
- amdgpu_amdkfd_flush_gpu_tlb_pasid(pdd->dev->adev,
- p->pasid, TLB_FLUSH_HEAVYWEIGHT);
+ kfd_flush_tlb(pdd, TLB_FLUSH_HEAVYWEIGHT);
}
return r;
}
static int
-svm_range_map_to_gpu(struct amdgpu_device *adev, struct amdgpu_vm *vm,
- struct svm_range *prange, unsigned long offset,
- unsigned long npages, bool readonly, dma_addr_t *dma_addr,
- struct amdgpu_device *bo_adev, struct dma_fence **fence)
+svm_range_map_to_gpu(struct kfd_process_device *pdd, struct svm_range *prange,
+ unsigned long offset, unsigned long npages, bool readonly,
+ dma_addr_t *dma_addr, struct amdgpu_device *bo_adev,
+ struct dma_fence **fence)
{
+ struct amdgpu_device *adev = pdd->dev->adev;
+ struct amdgpu_vm *vm = drm_priv_to_vm(pdd->drm_priv);
bool table_freed = false;
uint64_t pte_flags;
unsigned long last_start;
@@ -1300,12 +1306,8 @@ svm_range_map_to_gpu(struct amdgpu_device *adev, struct amdgpu_vm *vm,
if (fence)
*fence = dma_fence_get(vm->last_update);
- if (table_freed) {
- struct kfd_process *p;
-
- p = container_of(prange->svms, struct kfd_process, svms);
- amdgpu_amdkfd_flush_gpu_tlb_pasid(adev, p->pasid, TLB_FLUSH_LEGACY);
- }
+ if (table_freed)
+ kfd_flush_tlb(pdd, TLB_FLUSH_LEGACY);
out:
return r;
}
@@ -1346,8 +1348,7 @@ svm_range_map_to_gpus(struct svm_range *prange, unsigned long offset,
continue;
}
- r = svm_range_map_to_gpu(pdd->dev->adev, drm_priv_to_vm(pdd->drm_priv),
- prange, offset, npages, readonly,
+ r = svm_range_map_to_gpu(pdd, prange, offset, npages, readonly,
prange->dma_addr[gpuidx],
bo_adev, wait ? &fence : NULL);
if (r)
@@ -1628,6 +1629,7 @@ retry_flush_work:
static void svm_range_restore_work(struct work_struct *work)
{
struct delayed_work *dwork = to_delayed_work(work);
+ struct amdkfd_process_info *process_info;
struct svm_range_list *svms;
struct svm_range *prange;
struct kfd_process *p;
@@ -1643,14 +1645,17 @@ static void svm_range_restore_work(struct work_struct *work)
pr_debug("restore svm ranges\n");
- /* kfd_process_notifier_release destroys this worker thread. So during
- * the lifetime of this thread, kfd_process and mm will be valid.
- */
p = container_of(svms, struct kfd_process, svms);
- mm = p->mm;
- if (!mm)
+ process_info = p->kgd_process_info;
+
+ /* Keep mm reference when svm_range_validate_and_map ranges */
+ mm = get_task_mm(p->lead_thread);
+ if (!mm) {
+ pr_debug("svms 0x%p process mm gone\n", svms);
return;
+ }
+ mutex_lock(&process_info->lock);
svm_range_list_lock_and_flush_work(svms, mm);
mutex_lock(&svms->lock);
@@ -1703,6 +1708,8 @@ static void svm_range_restore_work(struct work_struct *work)
out_reschedule:
mutex_unlock(&svms->lock);
mmap_write_unlock(mm);
+ mutex_unlock(&process_info->lock);
+ mmput(mm);
/* If validation failed, reschedule another attempt */
if (evicted_ranges) {
@@ -1985,10 +1992,9 @@ svm_range_update_notifier_and_interval_tree(struct mm_struct *mm,
}
static void
-svm_range_handle_list_op(struct svm_range_list *svms, struct svm_range *prange)
+svm_range_handle_list_op(struct svm_range_list *svms, struct svm_range *prange,
+ struct mm_struct *mm)
{
- struct mm_struct *mm = prange->work_item.mm;
-
switch (prange->work_item.op) {
case SVM_OP_NULL:
pr_debug("NULL OP 0x%p prange 0x%p [0x%lx 0x%lx]\n",
@@ -2065,40 +2071,44 @@ static void svm_range_deferred_list_work(struct work_struct *work)
struct svm_range_list *svms;
struct svm_range *prange;
struct mm_struct *mm;
- struct kfd_process *p;
svms = container_of(work, struct svm_range_list, deferred_list_work);
pr_debug("enter svms 0x%p\n", svms);
- p = container_of(svms, struct kfd_process, svms);
- /* Avoid mm is gone when inserting mmu notifier */
- mm = get_task_mm(p->lead_thread);
- if (!mm) {
- pr_debug("svms 0x%p process mm gone\n", svms);
- return;
- }
-retry:
- mmap_write_lock(mm);
-
- /* Checking for the need to drain retry faults must be inside
- * mmap write lock to serialize with munmap notifiers.
- */
- if (unlikely(atomic_read(&svms->drain_pagefaults))) {
- mmap_write_unlock(mm);
- svm_range_drain_retry_fault(svms);
- goto retry;
- }
-
spin_lock(&svms->deferred_list_lock);
while (!list_empty(&svms->deferred_range_list)) {
prange = list_first_entry(&svms->deferred_range_list,
struct svm_range, deferred_list);
- list_del_init(&prange->deferred_list);
spin_unlock(&svms->deferred_list_lock);
pr_debug("prange 0x%p [0x%lx 0x%lx] op %d\n", prange,
prange->start, prange->last, prange->work_item.op);
+ mm = prange->work_item.mm;
+retry:
+ mmap_write_lock(mm);
+
+ /* Checking for the need to drain retry faults must be inside
+ * mmap write lock to serialize with munmap notifiers.
+ */
+ if (unlikely(atomic_read(&svms->drain_pagefaults))) {
+ mmap_write_unlock(mm);
+ svm_range_drain_retry_fault(svms);
+ goto retry;
+ }
+
+ /* Remove from deferred_list must be inside mmap write lock, for
+ * two race cases:
+ * 1. unmap_from_cpu may change work_item.op and add the range
+ * to deferred_list again, cause use after free bug.
+ * 2. svm_range_list_lock_and_flush_work may hold mmap write
+ * lock and continue because deferred_list is empty, but
+ * deferred_list work is actually waiting for mmap lock.
+ */
+ spin_lock(&svms->deferred_list_lock);
+ list_del_init(&prange->deferred_list);
+ spin_unlock(&svms->deferred_list_lock);
+
mutex_lock(&svms->lock);
mutex_lock(&prange->migrate_mutex);
while (!list_empty(&prange->child_list)) {
@@ -2109,19 +2119,20 @@ retry:
pr_debug("child prange 0x%p op %d\n", pchild,
pchild->work_item.op);
list_del_init(&pchild->child_list);
- svm_range_handle_list_op(svms, pchild);
+ svm_range_handle_list_op(svms, pchild, mm);
}
mutex_unlock(&prange->migrate_mutex);
- svm_range_handle_list_op(svms, prange);
+ svm_range_handle_list_op(svms, prange, mm);
mutex_unlock(&svms->lock);
+ mmap_write_unlock(mm);
+
+ /* Pairs with mmget in svm_range_add_list_work */
+ mmput(mm);
spin_lock(&svms->deferred_list_lock);
}
spin_unlock(&svms->deferred_list_lock);
-
- mmap_write_unlock(mm);
- mmput(mm);
pr_debug("exit svms 0x%p\n", svms);
}
@@ -2139,6 +2150,9 @@ svm_range_add_list_work(struct svm_range_list *svms, struct svm_range *prange,
prange->work_item.op = op;
} else {
prange->work_item.op = op;
+
+ /* Pairs with mmput in deferred_list_work */
+ mmget(mm);
prange->work_item.mm = mm;
list_add_tail(&prange->deferred_list,
&prange->svms->deferred_range_list);
@@ -2830,6 +2844,8 @@ void svm_range_list_fini(struct kfd_process *p)
pr_debug("pasid 0x%x svms 0x%p\n", p->pasid, &p->svms);
+ cancel_delayed_work_sync(&p->svms.restore_work);
+
/* Ensure list work is finished before process is destroyed */
flush_work(&p->svms.deferred_list_work);
@@ -2840,7 +2856,6 @@ void svm_range_list_fini(struct kfd_process *p)
atomic_inc(&p->svms.drain_pagefaults);
svm_range_drain_retry_fault(&p->svms);
-
list_for_each_entry_safe(prange, next, &p->svms.list, list) {
svm_range_unlink(prange);
svm_range_remove_notifier(prange);
@@ -2865,6 +2880,7 @@ int svm_range_list_init(struct kfd_process *p)
INIT_DELAYED_WORK(&svms->restore_work, svm_range_restore_work);
INIT_WORK(&svms->deferred_list_work, svm_range_deferred_list_work);
INIT_LIST_HEAD(&svms->deferred_range_list);
+ INIT_LIST_HEAD(&svms->criu_svm_metadata_list);
spin_lock_init(&svms->deferred_list_lock);
for (i = 0; i < p->n_pdds; i++)
@@ -3139,6 +3155,7 @@ static void svm_range_evict_svm_bo_worker(struct work_struct *work)
struct svm_range_bo *svm_bo;
struct kfd_process *p;
struct mm_struct *mm;
+ int r = 0;
svm_bo = container_of(work, struct svm_range_bo, eviction_work);
if (!svm_bo_ref_unless_zero(svm_bo))
@@ -3154,7 +3171,7 @@ static void svm_range_evict_svm_bo_worker(struct work_struct *work)
mmap_read_lock(mm);
spin_lock(&svm_bo->list_lock);
- while (!list_empty(&svm_bo->range_list)) {
+ while (!list_empty(&svm_bo->range_list) && !r) {
struct svm_range *prange =
list_first_entry(&svm_bo->range_list,
struct svm_range, svm_bo_list);
@@ -3168,15 +3185,18 @@ static void svm_range_evict_svm_bo_worker(struct work_struct *work)
mutex_lock(&prange->migrate_mutex);
do {
- svm_migrate_vram_to_ram(prange,
+ r = svm_migrate_vram_to_ram(prange,
svm_bo->eviction_fence->mm);
- } while (prange->actual_loc && --retries);
- WARN(prange->actual_loc, "Migration failed during eviction");
+ } while (!r && prange->actual_loc && --retries);
- mutex_lock(&prange->lock);
- prange->svm_bo = NULL;
- mutex_unlock(&prange->lock);
+ if (!r && prange->actual_loc)
+ pr_info_once("Migration failed during eviction");
+ if (!prange->actual_loc) {
+ mutex_lock(&prange->lock);
+ prange->svm_bo = NULL;
+ mutex_unlock(&prange->lock);
+ }
mutex_unlock(&prange->migrate_mutex);
spin_lock(&svm_bo->list_lock);
@@ -3185,18 +3205,20 @@ static void svm_range_evict_svm_bo_worker(struct work_struct *work)
mmap_read_unlock(mm);
dma_fence_signal(&svm_bo->eviction_fence->base);
+
/* This is the last reference to svm_bo, after svm_range_vram_node_free
* has been called in svm_migrate_vram_to_ram
*/
- WARN_ONCE(kref_read(&svm_bo->kref) != 1, "This was not the last reference\n");
+ WARN_ONCE(!r && kref_read(&svm_bo->kref) != 1, "This was not the last reference\n");
svm_range_bo_unref(svm_bo);
}
static int
-svm_range_set_attr(struct kfd_process *p, uint64_t start, uint64_t size,
- uint32_t nattr, struct kfd_ioctl_svm_attribute *attrs)
+svm_range_set_attr(struct kfd_process *p, struct mm_struct *mm,
+ uint64_t start, uint64_t size, uint32_t nattr,
+ struct kfd_ioctl_svm_attribute *attrs)
{
- struct mm_struct *mm = current->mm;
+ struct amdkfd_process_info *process_info = p->kgd_process_info;
struct list_head update_list;
struct list_head insert_list;
struct list_head remove_list;
@@ -3214,6 +3236,8 @@ svm_range_set_attr(struct kfd_process *p, uint64_t start, uint64_t size,
svms = &p->svms;
+ mutex_lock(&process_info->lock);
+
svm_range_list_lock_and_flush_work(svms, mm);
r = svm_range_is_valid(p, start, size);
@@ -3288,6 +3312,8 @@ out_unlock_range:
mutex_unlock(&svms->lock);
mmap_read_unlock(mm);
out:
+ mutex_unlock(&process_info->lock);
+
pr_debug("pasid 0x%x svms 0x%p [0x%llx 0x%llx] done, r=%d\n", p->pasid,
&p->svms, start, start + size - 1, r);
@@ -3295,8 +3321,9 @@ out:
}
static int
-svm_range_get_attr(struct kfd_process *p, uint64_t start, uint64_t size,
- uint32_t nattr, struct kfd_ioctl_svm_attribute *attrs)
+svm_range_get_attr(struct kfd_process *p, struct mm_struct *mm,
+ uint64_t start, uint64_t size, uint32_t nattr,
+ struct kfd_ioctl_svm_attribute *attrs)
{
DECLARE_BITMAP(bitmap_access, MAX_GPU_INSTANCE);
DECLARE_BITMAP(bitmap_aip, MAX_GPU_INSTANCE);
@@ -3306,7 +3333,6 @@ svm_range_get_attr(struct kfd_process *p, uint64_t start, uint64_t size,
bool get_accessible = false;
bool get_flags = false;
uint64_t last = start + size - 1UL;
- struct mm_struct *mm = current->mm;
uint8_t granularity = 0xff;
struct interval_tree_node *node;
struct svm_range_list *svms;
@@ -3471,10 +3497,321 @@ fill_values:
return 0;
}
+int kfd_criu_resume_svm(struct kfd_process *p)
+{
+ struct kfd_ioctl_svm_attribute *set_attr_new, *set_attr = NULL;
+ int nattr_common = 4, nattr_accessibility = 1;
+ struct criu_svm_metadata *criu_svm_md = NULL;
+ struct svm_range_list *svms = &p->svms;
+ struct criu_svm_metadata *next = NULL;
+ uint32_t set_flags = 0xffffffff;
+ int i, j, num_attrs, ret = 0;
+ uint64_t set_attr_size;
+ struct mm_struct *mm;
+
+ if (list_empty(&svms->criu_svm_metadata_list)) {
+ pr_debug("No SVM data from CRIU restore stage 2\n");
+ return ret;
+ }
+
+ mm = get_task_mm(p->lead_thread);
+ if (!mm) {
+ pr_err("failed to get mm for the target process\n");
+ return -ESRCH;
+ }
+
+ num_attrs = nattr_common + (nattr_accessibility * p->n_pdds);
+
+ i = j = 0;
+ list_for_each_entry(criu_svm_md, &svms->criu_svm_metadata_list, list) {
+ pr_debug("criu_svm_md[%d]\n\tstart: 0x%llx size: 0x%llx (npages)\n",
+ i, criu_svm_md->data.start_addr, criu_svm_md->data.size);
+
+ for (j = 0; j < num_attrs; j++) {
+ pr_debug("\ncriu_svm_md[%d]->attrs[%d].type : 0x%x\ncriu_svm_md[%d]->attrs[%d].value : 0x%x\n",
+ i, j, criu_svm_md->data.attrs[j].type,
+ i, j, criu_svm_md->data.attrs[j].value);
+ switch (criu_svm_md->data.attrs[j].type) {
+ /* During Checkpoint operation, the query for
+ * KFD_IOCTL_SVM_ATTR_PREFETCH_LOC attribute might
+ * return KFD_IOCTL_SVM_LOCATION_UNDEFINED if they were
+ * not used by the range which was checkpointed. Care
+ * must be taken to not restore with an invalid value
+ * otherwise the gpuidx value will be invalid and
+ * set_attr would eventually fail so just replace those
+ * with another dummy attribute such as
+ * KFD_IOCTL_SVM_ATTR_SET_FLAGS.
+ */
+ case KFD_IOCTL_SVM_ATTR_PREFETCH_LOC:
+ if (criu_svm_md->data.attrs[j].value ==
+ KFD_IOCTL_SVM_LOCATION_UNDEFINED) {
+ criu_svm_md->data.attrs[j].type =
+ KFD_IOCTL_SVM_ATTR_SET_FLAGS;
+ criu_svm_md->data.attrs[j].value = 0;
+ }
+ break;
+ case KFD_IOCTL_SVM_ATTR_SET_FLAGS:
+ set_flags = criu_svm_md->data.attrs[j].value;
+ break;
+ default:
+ break;
+ }
+ }
+
+ /* CLR_FLAGS is not available via get_attr during checkpoint but
+ * it needs to be inserted before restoring the ranges so
+ * allocate extra space for it before calling set_attr
+ */
+ set_attr_size = sizeof(struct kfd_ioctl_svm_attribute) *
+ (num_attrs + 1);
+ set_attr_new = krealloc(set_attr, set_attr_size,
+ GFP_KERNEL);
+ if (!set_attr_new) {
+ ret = -ENOMEM;
+ goto exit;
+ }
+ set_attr = set_attr_new;
+
+ memcpy(set_attr, criu_svm_md->data.attrs, num_attrs *
+ sizeof(struct kfd_ioctl_svm_attribute));
+ set_attr[num_attrs].type = KFD_IOCTL_SVM_ATTR_CLR_FLAGS;
+ set_attr[num_attrs].value = ~set_flags;
+
+ ret = svm_range_set_attr(p, mm, criu_svm_md->data.start_addr,
+ criu_svm_md->data.size, num_attrs + 1,
+ set_attr);
+ if (ret) {
+ pr_err("CRIU: failed to set range attributes\n");
+ goto exit;
+ }
+
+ i++;
+ }
+exit:
+ kfree(set_attr);
+ list_for_each_entry_safe(criu_svm_md, next, &svms->criu_svm_metadata_list, list) {
+ pr_debug("freeing criu_svm_md[]\n\tstart: 0x%llx\n",
+ criu_svm_md->data.start_addr);
+ kfree(criu_svm_md);
+ }
+
+ mmput(mm);
+ return ret;
+
+}
+
+int kfd_criu_restore_svm(struct kfd_process *p,
+ uint8_t __user *user_priv_ptr,
+ uint64_t *priv_data_offset,
+ uint64_t max_priv_data_size)
+{
+ uint64_t svm_priv_data_size, svm_object_md_size, svm_attrs_size;
+ int nattr_common = 4, nattr_accessibility = 1;
+ struct criu_svm_metadata *criu_svm_md = NULL;
+ struct svm_range_list *svms = &p->svms;
+ uint32_t num_devices;
+ int ret = 0;
+
+ num_devices = p->n_pdds;
+ /* Handle one SVM range object at a time, also the number of gpus are
+ * assumed to be same on the restore node, checking must be done while
+ * evaluating the topology earlier
+ */
+
+ svm_attrs_size = sizeof(struct kfd_ioctl_svm_attribute) *
+ (nattr_common + nattr_accessibility * num_devices);
+ svm_object_md_size = sizeof(struct criu_svm_metadata) + svm_attrs_size;
+
+ svm_priv_data_size = sizeof(struct kfd_criu_svm_range_priv_data) +
+ svm_attrs_size;
+
+ criu_svm_md = kzalloc(svm_object_md_size, GFP_KERNEL);
+ if (!criu_svm_md) {
+ pr_err("failed to allocate memory to store svm metadata\n");
+ return -ENOMEM;
+ }
+ if (*priv_data_offset + svm_priv_data_size > max_priv_data_size) {
+ ret = -EINVAL;
+ goto exit;
+ }
+
+ ret = copy_from_user(&criu_svm_md->data, user_priv_ptr + *priv_data_offset,
+ svm_priv_data_size);
+ if (ret) {
+ ret = -EFAULT;
+ goto exit;
+ }
+ *priv_data_offset += svm_priv_data_size;
+
+ list_add_tail(&criu_svm_md->list, &svms->criu_svm_metadata_list);
+
+ return 0;
+
+
+exit:
+ kfree(criu_svm_md);
+ return ret;
+}
+
+int svm_range_get_info(struct kfd_process *p, uint32_t *num_svm_ranges,
+ uint64_t *svm_priv_data_size)
+{
+ uint64_t total_size, accessibility_size, common_attr_size;
+ int nattr_common = 4, nattr_accessibility = 1;
+ int num_devices = p->n_pdds;
+ struct svm_range_list *svms;
+ struct svm_range *prange;
+ uint32_t count = 0;
+
+ *svm_priv_data_size = 0;
+
+ svms = &p->svms;
+ if (!svms)
+ return -EINVAL;
+
+ mutex_lock(&svms->lock);
+ list_for_each_entry(prange, &svms->list, list) {
+ pr_debug("prange: 0x%p start: 0x%lx\t npages: 0x%llx\t end: 0x%llx\n",
+ prange, prange->start, prange->npages,
+ prange->start + prange->npages - 1);
+ count++;
+ }
+ mutex_unlock(&svms->lock);
+
+ *num_svm_ranges = count;
+ /* Only the accessbility attributes need to be queried for all the gpus
+ * individually, remaining ones are spanned across the entire process
+ * regardless of the various gpu nodes. Of the remaining attributes,
+ * KFD_IOCTL_SVM_ATTR_CLR_FLAGS need not be saved.
+ *
+ * KFD_IOCTL_SVM_ATTR_PREFERRED_LOC
+ * KFD_IOCTL_SVM_ATTR_PREFETCH_LOC
+ * KFD_IOCTL_SVM_ATTR_SET_FLAGS
+ * KFD_IOCTL_SVM_ATTR_GRANULARITY
+ *
+ * ** ACCESSBILITY ATTRIBUTES **
+ * (Considered as one, type is altered during query, value is gpuid)
+ * KFD_IOCTL_SVM_ATTR_ACCESS
+ * KFD_IOCTL_SVM_ATTR_ACCESS_IN_PLACE
+ * KFD_IOCTL_SVM_ATTR_NO_ACCESS
+ */
+ if (*num_svm_ranges > 0) {
+ common_attr_size = sizeof(struct kfd_ioctl_svm_attribute) *
+ nattr_common;
+ accessibility_size = sizeof(struct kfd_ioctl_svm_attribute) *
+ nattr_accessibility * num_devices;
+
+ total_size = sizeof(struct kfd_criu_svm_range_priv_data) +
+ common_attr_size + accessibility_size;
+
+ *svm_priv_data_size = *num_svm_ranges * total_size;
+ }
+
+ pr_debug("num_svm_ranges %u total_priv_size %llu\n", *num_svm_ranges,
+ *svm_priv_data_size);
+ return 0;
+}
+
+int kfd_criu_checkpoint_svm(struct kfd_process *p,
+ uint8_t __user *user_priv_data,
+ uint64_t *priv_data_offset)
+{
+ struct kfd_criu_svm_range_priv_data *svm_priv = NULL;
+ struct kfd_ioctl_svm_attribute *query_attr = NULL;
+ uint64_t svm_priv_data_size, query_attr_size = 0;
+ int index, nattr_common = 4, ret = 0;
+ struct svm_range_list *svms;
+ int num_devices = p->n_pdds;
+ struct svm_range *prange;
+ struct mm_struct *mm;
+
+ svms = &p->svms;
+ if (!svms)
+ return -EINVAL;
+
+ mm = get_task_mm(p->lead_thread);
+ if (!mm) {
+ pr_err("failed to get mm for the target process\n");
+ return -ESRCH;
+ }
+
+ query_attr_size = sizeof(struct kfd_ioctl_svm_attribute) *
+ (nattr_common + num_devices);
+
+ query_attr = kzalloc(query_attr_size, GFP_KERNEL);
+ if (!query_attr) {
+ ret = -ENOMEM;
+ goto exit;
+ }
+
+ query_attr[0].type = KFD_IOCTL_SVM_ATTR_PREFERRED_LOC;
+ query_attr[1].type = KFD_IOCTL_SVM_ATTR_PREFETCH_LOC;
+ query_attr[2].type = KFD_IOCTL_SVM_ATTR_SET_FLAGS;
+ query_attr[3].type = KFD_IOCTL_SVM_ATTR_GRANULARITY;
+
+ for (index = 0; index < num_devices; index++) {
+ struct kfd_process_device *pdd = p->pdds[index];
+
+ query_attr[index + nattr_common].type =
+ KFD_IOCTL_SVM_ATTR_ACCESS;
+ query_attr[index + nattr_common].value = pdd->user_gpu_id;
+ }
+
+ svm_priv_data_size = sizeof(*svm_priv) + query_attr_size;
+
+ svm_priv = kzalloc(svm_priv_data_size, GFP_KERNEL);
+ if (!svm_priv) {
+ ret = -ENOMEM;
+ goto exit_query;
+ }
+
+ index = 0;
+ list_for_each_entry(prange, &svms->list, list) {
+
+ svm_priv->object_type = KFD_CRIU_OBJECT_TYPE_SVM_RANGE;
+ svm_priv->start_addr = prange->start;
+ svm_priv->size = prange->npages;
+ memcpy(&svm_priv->attrs, query_attr, query_attr_size);
+ pr_debug("CRIU: prange: 0x%p start: 0x%lx\t npages: 0x%llx end: 0x%llx\t size: 0x%llx\n",
+ prange, prange->start, prange->npages,
+ prange->start + prange->npages - 1,
+ prange->npages * PAGE_SIZE);
+
+ ret = svm_range_get_attr(p, mm, svm_priv->start_addr,
+ svm_priv->size,
+ (nattr_common + num_devices),
+ svm_priv->attrs);
+ if (ret) {
+ pr_err("CRIU: failed to obtain range attributes\n");
+ goto exit_priv;
+ }
+
+ if (copy_to_user(user_priv_data + *priv_data_offset, svm_priv,
+ svm_priv_data_size)) {
+ pr_err("Failed to copy svm priv to user\n");
+ ret = -EFAULT;
+ goto exit_priv;
+ }
+
+ *priv_data_offset += svm_priv_data_size;
+
+ }
+
+
+exit_priv:
+ kfree(svm_priv);
+exit_query:
+ kfree(query_attr);
+exit:
+ mmput(mm);
+ return ret;
+}
+
int
svm_ioctl(struct kfd_process *p, enum kfd_ioctl_svm_op op, uint64_t start,
uint64_t size, uint32_t nattrs, struct kfd_ioctl_svm_attribute *attrs)
{
+ struct mm_struct *mm = current->mm;
int r;
start >>= PAGE_SHIFT;
@@ -3482,10 +3819,10 @@ svm_ioctl(struct kfd_process *p, enum kfd_ioctl_svm_op op, uint64_t start,
switch (op) {
case KFD_IOCTL_SVM_OP_SET_ATTR:
- r = svm_range_set_attr(p, start, size, nattrs, attrs);
+ r = svm_range_set_attr(p, mm, start, size, nattrs, attrs);
break;
case KFD_IOCTL_SVM_OP_GET_ATTR:
- r = svm_range_get_attr(p, start, size, nattrs, attrs);
+ r = svm_range_get_attr(p, mm, start, size, nattrs, attrs);
break;
default:
r = EINVAL;
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_svm.h b/drivers/gpu/drm/amd/amdkfd/kfd_svm.h
index 949b477e2f4c..66c77f00ac3e 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_svm.h
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_svm.h
@@ -183,6 +183,16 @@ void svm_range_dma_unmap(struct device *dev, dma_addr_t *dma_addr,
void svm_range_free_dma_mappings(struct svm_range *prange);
void svm_range_prefault(struct svm_range *prange, struct mm_struct *mm,
void *owner);
+int svm_range_get_info(struct kfd_process *p, uint32_t *num_svm_ranges,
+ uint64_t *svm_priv_data_size);
+int kfd_criu_checkpoint_svm(struct kfd_process *p,
+ uint8_t __user *user_priv_data,
+ uint64_t *priv_offset);
+int kfd_criu_restore_svm(struct kfd_process *p,
+ uint8_t __user *user_priv_ptr,
+ uint64_t *priv_data_offset,
+ uint64_t max_priv_data_size);
+int kfd_criu_resume_svm(struct kfd_process *p);
struct kfd_process_device *
svm_range_get_pdd_by_adev(struct svm_range *prange, struct amdgpu_device *adev);
void svm_range_list_lock_and_flush_work(struct svm_range_list *svms, struct mm_struct *mm);
@@ -220,6 +230,35 @@ static inline int svm_range_schedule_evict_svm_bo(
return -EINVAL;
}
+static inline int svm_range_get_info(struct kfd_process *p,
+ uint32_t *num_svm_ranges,
+ uint64_t *svm_priv_data_size)
+{
+ *num_svm_ranges = 0;
+ *svm_priv_data_size = 0;
+ return 0;
+}
+
+static inline int kfd_criu_checkpoint_svm(struct kfd_process *p,
+ uint8_t __user *user_priv_data,
+ uint64_t *priv_offset)
+{
+ return 0;
+}
+
+static inline int kfd_criu_restore_svm(struct kfd_process *p,
+ uint8_t __user *user_priv_ptr,
+ uint64_t *priv_data_offset,
+ uint64_t max_priv_data_size)
+{
+ return -EINVAL;
+}
+
+static inline int kfd_criu_resume_svm(struct kfd_process *p)
+{
+ return 0;
+}
+
#define KFD_IS_SVM_API_SUPPORTED(dev) false
#endif /* IS_ENABLED(CONFIG_HSA_AMD_SVM) */
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_topology.c b/drivers/gpu/drm/amd/amdkfd/kfd_topology.c
index 948fbb39336e..3bdcae239bc0 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_topology.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_topology.c
@@ -1,5 +1,6 @@
+// SPDX-License-Identifier: GPL-2.0 OR MIT
/*
- * Copyright 2014 Advanced Micro Devices, Inc.
+ * Copyright 2014-2022 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@@ -1441,9 +1442,9 @@ int kfd_topology_add_device(struct kfd_dev *gpu)
}
/*
- * Overwrite ATS capability according to needs_iommu_device to fix
- * potential missing corresponding bit in CRAT of BIOS.
- */
+ * Overwrite ATS capability according to needs_iommu_device to fix
+ * potential missing corresponding bit in CRAT of BIOS.
+ */
if (dev->gpu->use_iommu_v2)
dev->node_props.capability |= HSA_CAP_ATS_PRESENT;
else
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_topology.h b/drivers/gpu/drm/amd/amdkfd/kfd_topology.h
index f0cc59d2fd5d..4f80d2ea1000 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_topology.h
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_topology.h
@@ -1,5 +1,6 @@
+/* SPDX-License-Identifier: GPL-2.0 OR MIT */
/*
- * Copyright 2014 Advanced Micro Devices, Inc.
+ * Copyright 2014-2022 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index 7f9773f8dab6..b30656959fd8 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -76,7 +76,7 @@
#include <drm/drm_atomic.h>
#include <drm/drm_atomic_uapi.h>
#include <drm/drm_atomic_helper.h>
-#include <drm/drm_dp_mst_helper.h>
+#include <drm/dp/drm_dp_mst_helper.h>
#include <drm/drm_fb_helper.h>
#include <drm/drm_fourcc.h>
#include <drm/drm_edid.h>
@@ -114,6 +114,10 @@ MODULE_FIRMWARE(FIRMWARE_DIMGREY_CAVEFISH_DMUB);
MODULE_FIRMWARE(FIRMWARE_BEIGE_GOBY_DMUB);
#define FIRMWARE_YELLOW_CARP_DMUB "amdgpu/yellow_carp_dmcub.bin"
MODULE_FIRMWARE(FIRMWARE_YELLOW_CARP_DMUB);
+#define FIRMWARE_DCN_315_DMUB "amdgpu/dcn_3_1_5_dmcub.bin"
+MODULE_FIRMWARE(FIRMWARE_DCN_315_DMUB);
+#define FIRMWARE_DCN316_DMUB "amdgpu/dcn_3_1_6_dmcub.bin"
+MODULE_FIRMWARE(FIRMWARE_DCN316_DMUB);
#define FIRMWARE_RAVEN_DMCU "amdgpu/raven_dmcu.bin"
MODULE_FIRMWARE(FIRMWARE_RAVEN_DMCU);
@@ -1027,7 +1031,6 @@ static int dm_dmub_hw_init(struct amdgpu_device *adev)
const unsigned char *fw_inst_const, *fw_bss_data;
uint32_t i, fw_inst_const_size, fw_bss_data_size;
bool has_hw_support;
- struct dc *dc = adev->dm.dc;
if (!dmub_srv)
/* DMUB isn't supported on the ASIC. */
@@ -1119,14 +1122,12 @@ static int dm_dmub_hw_init(struct amdgpu_device *adev)
for (i = 0; i < fb_info->num_fb; ++i)
hw_params.fb[i] = &fb_info->fb[i];
- switch (adev->asic_type) {
- case CHIP_YELLOW_CARP:
- if (dc->ctx->asic_id.hw_internal_rev != YELLOW_CARP_A0) {
- hw_params.dpia_supported = true;
+ switch (adev->ip_versions[DCE_HWIP][0]) {
+ case IP_VERSION(3, 1, 3): /* Only for this asic hw internal rev B0 */
+ hw_params.dpia_supported = true;
#if defined(CONFIG_DRM_AMD_DC_DCN)
- hw_params.disable_dpia = dc->debug.dpia_debug.bits.disable_dpia;
+ hw_params.disable_dpia = adev->dm.dc->debug.dpia_debug.bits.disable_dpia;
#endif
- }
break;
default:
break;
@@ -1442,6 +1443,25 @@ static int amdgpu_dm_init(struct amdgpu_device *adev)
init_data.dce_environment = DCE_ENV_PRODUCTION_DRV;
+ switch (adev->ip_versions[DCE_HWIP][0]) {
+ case IP_VERSION(2, 1, 0):
+ switch (adev->dm.dmcub_fw_version) {
+ case 0: /* development */
+ case 0x1: /* linux-firmware.git hash 6d9f399 */
+ case 0x01000000: /* linux-firmware.git hash 9a0b0f4 */
+ init_data.flags.disable_dmcu = false;
+ break;
+ default:
+ init_data.flags.disable_dmcu = true;
+ }
+ break;
+ case IP_VERSION(2, 0, 3):
+ init_data.flags.disable_dmcu = true;
+ break;
+ default:
+ break;
+ }
+
switch (adev->asic_type) {
case CHIP_CARRIZO:
case CHIP_STONEY:
@@ -1449,34 +1469,30 @@ static int amdgpu_dm_init(struct amdgpu_device *adev)
break;
default:
switch (adev->ip_versions[DCE_HWIP][0]) {
- case IP_VERSION(2, 1, 0):
- init_data.flags.gpu_vm_support = true;
- switch (adev->dm.dmcub_fw_version) {
- case 0: /* development */
- case 0x1: /* linux-firmware.git hash 6d9f399 */
- case 0x01000000: /* linux-firmware.git hash 9a0b0f4 */
- init_data.flags.disable_dmcu = false;
- break;
- default:
- init_data.flags.disable_dmcu = true;
- }
- break;
case IP_VERSION(1, 0, 0):
case IP_VERSION(1, 0, 1):
+ /* enable S/G on PCO and RV2 */
+ if ((adev->apu_flags & AMD_APU_IS_RAVEN2) ||
+ (adev->apu_flags & AMD_APU_IS_PICASSO))
+ init_data.flags.gpu_vm_support = true;
+ break;
+ case IP_VERSION(2, 1, 0):
case IP_VERSION(3, 0, 1):
case IP_VERSION(3, 1, 2):
case IP_VERSION(3, 1, 3):
+ case IP_VERSION(3, 1, 5):
+ case IP_VERSION(3, 1, 6):
init_data.flags.gpu_vm_support = true;
break;
- case IP_VERSION(2, 0, 3):
- init_data.flags.disable_dmcu = true;
- break;
default:
break;
}
break;
}
+ if (init_data.flags.gpu_vm_support)
+ adev->mode_info.gpu_vm_support = true;
+
if (amdgpu_dc_feature_mask & DC_FBC_MASK)
init_data.flags.fbc_support = true;
@@ -1496,10 +1512,10 @@ static int amdgpu_dm_init(struct amdgpu_device *adev)
init_data.flags.allow_lttpr_non_transparent_mode.bits.DP2_0 = true;
#endif
- init_data.flags.power_down_display_on_boot = true;
+ init_data.flags.seamless_boot_edp_requested = false;
if (check_seamless_boot_capability(adev)) {
- init_data.flags.power_down_display_on_boot = false;
+ init_data.flags.seamless_boot_edp_requested = true;
init_data.flags.allow_seamless_boot_optimization = true;
DRM_INFO("Seamless boot condition check passed\n");
}
@@ -1804,6 +1820,8 @@ static int load_dmcu_fw(struct amdgpu_device *adev)
case IP_VERSION(3, 0, 1):
case IP_VERSION(3, 1, 2):
case IP_VERSION(3, 1, 3):
+ case IP_VERSION(3, 1, 5):
+ case IP_VERSION(3, 1, 6):
return 0;
default:
break;
@@ -1919,7 +1937,14 @@ static int dm_dmub_sw_init(struct amdgpu_device *adev)
dmub_asic = (adev->external_rev_id == YELLOW_CARP_B0) ? DMUB_ASIC_DCN31B : DMUB_ASIC_DCN31;
fw_name_dmub = FIRMWARE_YELLOW_CARP_DMUB;
break;
-
+ case IP_VERSION(3, 1, 5):
+ dmub_asic = DMUB_ASIC_DCN315;
+ fw_name_dmub = FIRMWARE_DCN_315_DMUB;
+ break;
+ case IP_VERSION(3, 1, 6):
+ dmub_asic = DMUB_ASIC_DCN316;
+ fw_name_dmub = FIRMWARE_DCN316_DMUB;
+ break;
default:
/* ASIC doesn't support DMUB. */
return 0;
@@ -2179,12 +2204,8 @@ static void s3_handle_mst(struct drm_device *dev, bool suspend)
static int amdgpu_dm_smu_write_watermarks_table(struct amdgpu_device *adev)
{
- struct smu_context *smu = &adev->smu;
int ret = 0;
- if (!is_support_sw_smu(adev))
- return 0;
-
/* This interface is for dGPU Navi1x.Linux dc-pplib interface depends
* on window driver dc implementation.
* For Navi1x, clock settings of dcn watermarks are fixed. the settings
@@ -2223,7 +2244,7 @@ static int amdgpu_dm_smu_write_watermarks_table(struct amdgpu_device *adev)
return 0;
}
- ret = smu_write_watermarks_table(smu);
+ ret = amdgpu_dpm_write_watermarks_table(adev);
if (ret) {
DRM_ERROR("Failed to update WMTABLE!\n");
return ret;
@@ -2413,7 +2434,7 @@ static int dm_suspend(void *handle)
return 0;
}
-static struct amdgpu_dm_connector *
+struct amdgpu_dm_connector *
amdgpu_dm_find_first_crtc_matching_connector(struct drm_atomic_state *state,
struct drm_crtc *crtc)
{
@@ -2613,10 +2634,13 @@ static int dm_resume(void *handle)
* before the 0 streams commit.
*
* DC expects that link encoder assignments are *not* valid
- * when committing a state, so as a workaround it needs to be
- * cleared here.
+ * when committing a state, so as a workaround we can copy
+ * off of the current state.
+ *
+ * We lose the previous assignments, but we had already
+ * commit 0 streams anyway.
*/
- link_enc_cfg_init(dm->dc, dc_state);
+ link_enc_cfg_copy(adev->dm.dc->current_state, dc_state);
if (dc_enable_dmub_notifications(adev->dm.dc))
amdgpu_dm_outbox_init(adev);
@@ -3653,7 +3677,7 @@ static int dcn10_register_irq_handlers(struct amdgpu_device *adev)
/* Use GRPH_PFLIP interrupt */
for (i = DCN_1_0__SRCID__HUBP0_FLIP_INTERRUPT;
- i <= DCN_1_0__SRCID__HUBP0_FLIP_INTERRUPT + adev->mode_info.num_crtc - 1;
+ i <= DCN_1_0__SRCID__HUBP0_FLIP_INTERRUPT + dc->caps.max_otg_num - 1;
i++) {
r = amdgpu_irq_add_id(adev, SOC15_IH_CLIENTID_DCE, i, &adev->pageflip_irq);
if (r) {
@@ -3730,8 +3754,8 @@ static int register_outbox_irq_handlers(struct amdgpu_device *adev)
*
* This should only be called during atomic check.
*/
-static int dm_atomic_get_state(struct drm_atomic_state *state,
- struct dm_atomic_state **dm_state)
+int dm_atomic_get_state(struct drm_atomic_state *state,
+ struct dm_atomic_state **dm_state)
{
struct drm_device *dev = state->dev;
struct amdgpu_device *adev = drm_to_adev(dev);
@@ -4231,6 +4255,8 @@ static int amdgpu_dm_initialize_drm_device(struct amdgpu_device *adev)
case IP_VERSION(3, 0, 0):
case IP_VERSION(3, 1, 2):
case IP_VERSION(3, 1, 3):
+ case IP_VERSION(3, 1, 5):
+ case IP_VERSION(3, 1, 6):
case IP_VERSION(2, 1, 0):
if (register_outbox_irq_handlers(dm->adev)) {
DRM_ERROR("DM: Failed to initialize IRQ\n");
@@ -4247,6 +4273,8 @@ static int amdgpu_dm_initialize_drm_device(struct amdgpu_device *adev)
switch (adev->ip_versions[DCE_HWIP][0]) {
case IP_VERSION(3, 1, 2):
case IP_VERSION(3, 1, 3):
+ case IP_VERSION(3, 1, 5):
+ case IP_VERSION(3, 1, 6):
psr_feature_enabled = true;
break;
default:
@@ -4256,6 +4284,9 @@ static int amdgpu_dm_initialize_drm_device(struct amdgpu_device *adev)
}
#endif
+ /* Disable vblank IRQs aggressively for power-saving. */
+ adev_to_drm(adev)->vblank_disable_immediate = true;
+
/* loops over all connectors on the board */
for (i = 0; i < link_cnt; i++) {
struct dc_link *link = NULL;
@@ -4301,19 +4332,17 @@ static int amdgpu_dm_initialize_drm_device(struct amdgpu_device *adev)
update_connector_ext_caps(aconnector);
if (psr_feature_enabled)
amdgpu_dm_set_psr_caps(link);
+
+ /* TODO: Fix vblank control helpers to delay PSR entry to allow this when
+ * PSR is also supported.
+ */
+ if (link->psr_settings.psr_feature_enabled)
+ adev_to_drm(adev)->vblank_disable_immediate = false;
}
}
- /*
- * Disable vblank IRQs aggressively for power-saving.
- *
- * TODO: Fix vblank control helpers to delay PSR entry to allow this when PSR
- * is also supported.
- */
- adev_to_drm(adev)->vblank_disable_immediate = !psr_feature_enabled;
-
/* Software is initialized. Now we can register interrupt handlers. */
switch (adev->asic_type) {
#if defined(CONFIG_DRM_AMD_DC_SI)
@@ -4363,6 +4392,8 @@ static int amdgpu_dm_initialize_drm_device(struct amdgpu_device *adev)
case IP_VERSION(3, 0, 1):
case IP_VERSION(3, 1, 2):
case IP_VERSION(3, 1, 3):
+ case IP_VERSION(3, 1, 5):
+ case IP_VERSION(3, 1, 6):
if (dcn10_register_irq_handlers(dm->adev)) {
DRM_ERROR("DM: Failed to initialize IRQ\n");
goto fail;
@@ -4548,6 +4579,8 @@ static int dm_early_init(void *handle)
case IP_VERSION(2, 1, 0):
case IP_VERSION(3, 1, 2):
case IP_VERSION(3, 1, 3):
+ case IP_VERSION(3, 1, 5):
+ case IP_VERSION(3, 1, 6):
adev->mode_info.num_crtc = 4;
adev->mode_info.num_hpd = 4;
adev->mode_info.num_dig = 4;
@@ -5220,6 +5253,8 @@ get_plane_modifiers(const struct amdgpu_device *adev, unsigned int plane_type, u
case AMDGPU_FAMILY_NV:
case AMDGPU_FAMILY_VGH:
case AMDGPU_FAMILY_YC:
+ case AMDGPU_FAMILY_GC_10_3_6:
+ case AMDGPU_FAMILY_GC_10_3_7:
if (adev->ip_versions[GC_HWIP][0] >= IP_VERSION(10, 3, 0))
add_gfx10_3_modifiers(adev, mods, &size, &capacity);
else
@@ -5856,7 +5891,7 @@ static void fill_stream_properties_from_drm_display_mode(
else if (drm_mode_is_420_also(info, mode_in)
&& aconnector->force_yuv420_output)
timing_out->pixel_encoding = PIXEL_ENCODING_YCBCR420;
- else if ((connector->display_info.color_formats & DRM_COLOR_FORMAT_YCRCB444)
+ else if ((connector->display_info.color_formats & DRM_COLOR_FORMAT_YCBCR444)
&& stream->signal == SIGNAL_TYPE_HDMI_TYPE_A)
timing_out->pixel_encoding = PIXEL_ENCODING_YCBCR444;
else
@@ -6186,7 +6221,7 @@ static void apply_dsc_policy_for_stream(struct amdgpu_dm_connector *aconnector,
if (stream->link && stream->link->local_sink)
max_dsc_target_bpp_limit_override =
stream->link->local_sink->edid_caps.panel_patch.max_dsc_target_bpp_limit;
-
+
/* Set DSC policy according to dsc_clock_en */
dc_dsc_policy_set_enable_dsc_when_not_needed(
aconnector->dsc_settings.dsc_force_enable == DSC_CLK_FORCE_ENABLE);
@@ -6325,7 +6360,7 @@ get_highest_refresh_rate_mode(struct amdgpu_dm_connector *aconnector,
}
}
- aconnector->freesync_vid_base = *m_pref;
+ drm_mode_copy(&aconnector->freesync_vid_base, m_pref);
return m_pref;
}
@@ -6435,12 +6470,11 @@ create_stream_for_sink(struct amdgpu_dm_connector *aconnector,
*/
DRM_DEBUG_DRIVER("No preferred mode found\n");
} else {
- recalculate_timing = amdgpu_freesync_vid_mode &&
- is_freesync_video_mode(&mode, aconnector);
+ recalculate_timing = is_freesync_video_mode(&mode, aconnector);
if (recalculate_timing) {
freesync_mode = get_highest_refresh_rate_mode(aconnector, false);
- saved_mode = mode;
- mode = *freesync_mode;
+ drm_mode_copy(&saved_mode, &mode);
+ drm_mode_copy(&mode, freesync_mode);
} else {
decide_crtc_timing_for_drm_display_mode(
&mode, preferred_mode, scale);
@@ -6499,7 +6533,7 @@ create_stream_for_sink(struct amdgpu_dm_connector *aconnector,
if (stream->link->dpcd_caps.dprx_feature.bits.VSC_SDP_COLORIMETRY_SUPPORTED)
stream->use_vsc_sdp_for_colorimetry = true;
}
- mod_build_vsc_infopacket(stream, &stream->vsc_infopacket);
+ mod_build_vsc_infopacket(stream, &stream->vsc_infopacket, stream->output_color_space);
aconnector->psr_skip_count = AMDGPU_DM_PSR_ENTRY_DELAY;
}
@@ -7010,7 +7044,7 @@ static void handle_edid_mgmt(struct amdgpu_dm_connector *aconnector)
create_eml_sink(aconnector);
}
-static struct dc_stream_state *
+struct dc_stream_state *
create_validate_stream_for_sink(struct amdgpu_dm_connector *aconnector,
const struct drm_display_mode *drm_mode,
const struct dm_connector_state *dm_state,
@@ -7894,6 +7928,9 @@ static int amdgpu_dm_plane_init(struct amdgpu_display_manager *dm,
if (res)
return res;
+ if (modifiers == NULL)
+ adev_to_drm(dm->adev)->mode_config.fb_modifiers_not_supported = true;
+
res = drm_universal_plane_init(adev_to_drm(dm->adev), plane, possible_crtcs,
&dm_plane_funcs, formats, num_formats,
modifiers, plane->type, NULL);
@@ -8143,6 +8180,9 @@ static void amdgpu_dm_connector_add_common_modes(struct drm_encoder *encoder,
mode = amdgpu_dm_create_common_mode(encoder,
common_modes[i].name, common_modes[i].w,
common_modes[i].h);
+ if (!mode)
+ continue;
+
drm_mode_probed_add(connector, mode);
amdgpu_dm_connector->num_modes++;
}
@@ -8304,7 +8344,7 @@ static void amdgpu_dm_connector_add_freesync_modes(struct drm_connector *connect
struct amdgpu_dm_connector *amdgpu_dm_connector =
to_amdgpu_dm_connector(connector);
- if (!(amdgpu_freesync_vid_mode && edid))
+ if (!edid)
return;
if (amdgpu_dm_connector->max_vfreq - amdgpu_dm_connector->min_vfreq > 10)
@@ -8371,7 +8411,7 @@ void amdgpu_dm_connector_init_helper(struct amdgpu_display_manager *dm,
break;
case DRM_MODE_CONNECTOR_DisplayPort:
aconnector->base.polled = DRM_CONNECTOR_POLL_HPD;
- link->link_enc = dp_get_link_enc(link);
+ link->link_enc = link_enc_cfg_get_link_enc(link);
ASSERT(link->link_enc);
if (link->link_enc)
aconnector->base.ycbcr_420_allowed =
@@ -10141,27 +10181,27 @@ static bool
is_timing_unchanged_for_freesync(struct drm_crtc_state *old_crtc_state,
struct drm_crtc_state *new_crtc_state)
{
- struct drm_display_mode old_mode, new_mode;
+ const struct drm_display_mode *old_mode, *new_mode;
if (!old_crtc_state || !new_crtc_state)
return false;
- old_mode = old_crtc_state->mode;
- new_mode = new_crtc_state->mode;
-
- if (old_mode.clock == new_mode.clock &&
- old_mode.hdisplay == new_mode.hdisplay &&
- old_mode.vdisplay == new_mode.vdisplay &&
- old_mode.htotal == new_mode.htotal &&
- old_mode.vtotal != new_mode.vtotal &&
- old_mode.hsync_start == new_mode.hsync_start &&
- old_mode.vsync_start != new_mode.vsync_start &&
- old_mode.hsync_end == new_mode.hsync_end &&
- old_mode.vsync_end != new_mode.vsync_end &&
- old_mode.hskew == new_mode.hskew &&
- old_mode.vscan == new_mode.vscan &&
- (old_mode.vsync_end - old_mode.vsync_start) ==
- (new_mode.vsync_end - new_mode.vsync_start))
+ old_mode = &old_crtc_state->mode;
+ new_mode = &new_crtc_state->mode;
+
+ if (old_mode->clock == new_mode->clock &&
+ old_mode->hdisplay == new_mode->hdisplay &&
+ old_mode->vdisplay == new_mode->vdisplay &&
+ old_mode->htotal == new_mode->htotal &&
+ old_mode->vtotal != new_mode->vtotal &&
+ old_mode->hsync_start == new_mode->hsync_start &&
+ old_mode->vsync_start != new_mode->vsync_start &&
+ old_mode->hsync_end == new_mode->hsync_end &&
+ old_mode->vsync_end != new_mode->vsync_end &&
+ old_mode->hskew == new_mode->hskew &&
+ old_mode->vscan == new_mode->vscan &&
+ (old_mode->vsync_end - old_mode->vsync_start) ==
+ (new_mode->vsync_end - new_mode->vsync_start))
return true;
return false;
@@ -10182,12 +10222,12 @@ static void set_freesync_fixed_config(struct dm_crtc_state *dm_new_crtc_state) {
}
static int dm_update_crtc_state(struct amdgpu_display_manager *dm,
- struct drm_atomic_state *state,
- struct drm_crtc *crtc,
- struct drm_crtc_state *old_crtc_state,
- struct drm_crtc_state *new_crtc_state,
- bool enable,
- bool *lock_and_validation_needed)
+ struct drm_atomic_state *state,
+ struct drm_crtc *crtc,
+ struct drm_crtc_state *old_crtc_state,
+ struct drm_crtc_state *new_crtc_state,
+ bool enable,
+ bool *lock_and_validation_needed)
{
struct dm_atomic_state *dm_state = NULL;
struct dm_crtc_state *dm_old_crtc_state, *dm_new_crtc_state;
@@ -10271,8 +10311,7 @@ static int dm_update_crtc_state(struct amdgpu_display_manager *dm,
* TODO: Refactor this function to allow this check to work
* in all conditions.
*/
- if (amdgpu_freesync_vid_mode &&
- dm_new_crtc_state->stream &&
+ if (dm_new_crtc_state->stream &&
is_timing_unchanged_for_freesync(new_crtc_state, old_crtc_state))
goto skip_modeset;
@@ -10307,7 +10346,7 @@ static int dm_update_crtc_state(struct amdgpu_display_manager *dm,
if (!dm_old_crtc_state->stream)
goto skip_modeset;
- if (amdgpu_freesync_vid_mode && dm_new_crtc_state->stream &&
+ if (dm_new_crtc_state->stream &&
is_timing_unchanged_for_freesync(new_crtc_state,
old_crtc_state)) {
new_crtc_state->mode_changed = false;
@@ -10319,7 +10358,7 @@ static int dm_update_crtc_state(struct amdgpu_display_manager *dm,
set_freesync_fixed_config(dm_new_crtc_state);
goto skip_modeset;
- } else if (amdgpu_freesync_vid_mode && aconnector &&
+ } else if (aconnector &&
is_freesync_video_mode(&new_crtc_state->mode,
aconnector)) {
struct drm_display_mode *high_mode;
@@ -10857,10 +10896,13 @@ static int dm_check_crtc_cursor(struct drm_atomic_state *state,
static int add_affected_mst_dsc_crtcs(struct drm_atomic_state *state, struct drm_crtc *crtc)
{
struct drm_connector *connector;
- struct drm_connector_state *conn_state;
+ struct drm_connector_state *conn_state, *old_conn_state;
struct amdgpu_dm_connector *aconnector = NULL;
int i;
- for_each_new_connector_in_state(state, connector, conn_state, i) {
+ for_each_oldnew_connector_in_state(state, connector, old_conn_state, conn_state, i) {
+ if (!conn_state->crtc)
+ conn_state = old_conn_state;
+
if (conn_state->crtc != crtc)
continue;
@@ -10967,6 +11009,7 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
}
}
}
+ pre_validate_dsc(state, &dm_state, vars);
}
#endif
for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) {
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
index b9a69b0cef23..6a908d736d6a 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
@@ -29,7 +29,7 @@
#include <drm/drm_atomic.h>
#include <drm/drm_connector.h>
#include <drm/drm_crtc.h>
-#include <drm/drm_dp_mst_helper.h>
+#include <drm/dp/drm_dp_mst_helper.h>
#include <drm/drm_plane.h>
/*
@@ -604,6 +604,7 @@ struct amdgpu_dm_connector {
#endif
bool force_yuv420_output;
struct dsc_preferred_settings dsc_settings;
+ union dp_downstream_port_present mst_downstream_port_present;
/* Cached display modes */
struct drm_display_mode freesync_vid_base;
@@ -736,4 +737,16 @@ int amdgpu_dm_process_dmub_aux_transfer_sync(bool is_cmd_aux,
bool check_seamless_boot_capability(struct amdgpu_device *adev);
+struct dc_stream_state *
+ create_validate_stream_for_sink(struct amdgpu_dm_connector *aconnector,
+ const struct drm_display_mode *drm_mode,
+ const struct dm_connector_state *dm_state,
+ const struct dc_stream_state *old_stream);
+
+int dm_atomic_get_state(struct drm_atomic_state *state,
+ struct dm_atomic_state **dm_state);
+
+struct amdgpu_dm_connector *
+amdgpu_dm_find_first_crtc_matching_connector(struct drm_atomic_state *state,
+ struct drm_crtc *crtc);
#endif /* __AMDGPU_DM_H__ */
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c
index 26719efa5396..da17ece1a2c5 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c
@@ -23,6 +23,7 @@
*
*/
+#include <linux/string_helpers.h>
#include <linux/uaccess.h>
#include "dc.h"
@@ -49,11 +50,6 @@ struct dmub_debugfs_trace_entry {
uint32_t param1;
};
-static inline const char *yesno(bool v)
-{
- return v ? "yes" : "no";
-}
-
/* parse_write_buffer_into_params - Helper function to parse debugfs write buffer into an array
*
* Function takes in attributes passed to debugfs write entry
@@ -227,8 +223,10 @@ static ssize_t dp_link_settings_read(struct file *f, char __user *buf,
break;
r = put_user(*(rd_buf + result), buf);
- if (r)
+ if (r) {
+ kfree(rd_buf);
return r; /* r = -EFAULT */
+ }
buf += 1;
size -= 1;
@@ -245,6 +243,7 @@ static ssize_t dp_link_settings_write(struct file *f, const char __user *buf,
{
struct amdgpu_dm_connector *connector = file_inode(f)->i_private;
struct dc_link *link = connector->dc_link;
+ struct amdgpu_device *adev = drm_to_adev(connector->base.dev);
struct dc *dc = (struct dc *)link->dc;
struct dc_link_settings prefer_link_settings;
char *wr_buf = NULL;
@@ -304,6 +303,9 @@ static ssize_t dp_link_settings_write(struct file *f, const char __user *buf,
if (!valid_input) {
kfree(wr_buf);
DRM_DEBUG_DRIVER("Invalid Input value No HW will be programmed\n");
+ mutex_lock(&adev->dm.dc_lock);
+ dc_link_set_preferred_training_settings(dc, NULL, NULL, link, false);
+ mutex_unlock(&adev->dm.dc_lock);
return size;
}
@@ -315,7 +317,9 @@ static ssize_t dp_link_settings_write(struct file *f, const char __user *buf,
prefer_link_settings.lane_count = param[0];
prefer_link_settings.link_rate = param[1];
- dc_link_set_preferred_training_settings(dc, &prefer_link_settings, NULL, link, true);
+ mutex_lock(&adev->dm.dc_lock);
+ dc_link_set_preferred_training_settings(dc, &prefer_link_settings, NULL, link, false);
+ mutex_unlock(&adev->dm.dc_lock);
kfree(wr_buf);
return size;
@@ -389,8 +393,10 @@ static ssize_t dp_phy_settings_read(struct file *f, char __user *buf,
break;
r = put_user((*(rd_buf + result)), buf);
- if (r)
+ if (r) {
+ kfree(rd_buf);
return r; /* r = -EFAULT */
+ }
buf += 1;
size -= 1;
@@ -853,12 +859,12 @@ static int psr_capability_show(struct seq_file *m, void *data)
if (!(link->connector_signal & SIGNAL_TYPE_EDP))
return -ENODEV;
- seq_printf(m, "Sink support: %s", yesno(link->dpcd_caps.psr_caps.psr_version != 0));
- if (link->dpcd_caps.psr_caps.psr_version)
- seq_printf(m, " [0x%02x]", link->dpcd_caps.psr_caps.psr_version);
+ seq_printf(m, "Sink support: %s", str_yes_no(link->dpcd_caps.psr_info.psr_version != 0));
+ if (link->dpcd_caps.psr_info.psr_version)
+ seq_printf(m, " [0x%02x]", link->dpcd_caps.psr_info.psr_version);
seq_puts(m, "\n");
- seq_printf(m, "Driver support: %s", yesno(link->psr_settings.psr_feature_enabled));
+ seq_printf(m, "Driver support: %s", str_yes_no(link->psr_settings.psr_feature_enabled));
if (link->psr_settings.psr_version)
seq_printf(m, " [0x%02x]", link->psr_settings.psr_version);
seq_puts(m, "\n");
@@ -1207,8 +1213,8 @@ static int dp_dsc_fec_support_show(struct seq_file *m, void *data)
drm_modeset_drop_locks(&ctx);
drm_modeset_acquire_fini(&ctx);
- seq_printf(m, "FEC_Sink_Support: %s\n", yesno(is_fec_supported));
- seq_printf(m, "DSC_Sink_Support: %s\n", yesno(is_dsc_supported));
+ seq_printf(m, "FEC_Sink_Support: %s\n", str_yes_no(is_fec_supported));
+ seq_printf(m, "DSC_Sink_Support: %s\n", str_yes_no(is_dsc_supported));
return ret;
}
@@ -1359,8 +1365,10 @@ static ssize_t dp_dsc_clock_en_read(struct file *f, char __user *buf,
break;
}
- if (!pipe_ctx)
+ if (!pipe_ctx) {
+ kfree(rd_buf);
return -ENXIO;
+ }
dsc = pipe_ctx->stream_res.dsc;
if (dsc)
@@ -1376,8 +1384,10 @@ static ssize_t dp_dsc_clock_en_read(struct file *f, char __user *buf,
break;
r = put_user(*(rd_buf + result), buf);
- if (r)
+ if (r) {
+ kfree(rd_buf);
return r; /* r = -EFAULT */
+ }
buf += 1;
size -= 1;
@@ -1546,8 +1556,10 @@ static ssize_t dp_dsc_slice_width_read(struct file *f, char __user *buf,
break;
}
- if (!pipe_ctx)
+ if (!pipe_ctx) {
+ kfree(rd_buf);
return -ENXIO;
+ }
dsc = pipe_ctx->stream_res.dsc;
if (dsc)
@@ -1563,8 +1575,10 @@ static ssize_t dp_dsc_slice_width_read(struct file *f, char __user *buf,
break;
r = put_user(*(rd_buf + result), buf);
- if (r)
+ if (r) {
+ kfree(rd_buf);
return r; /* r = -EFAULT */
+ }
buf += 1;
size -= 1;
@@ -1731,8 +1745,10 @@ static ssize_t dp_dsc_slice_height_read(struct file *f, char __user *buf,
break;
}
- if (!pipe_ctx)
+ if (!pipe_ctx) {
+ kfree(rd_buf);
return -ENXIO;
+ }
dsc = pipe_ctx->stream_res.dsc;
if (dsc)
@@ -1748,8 +1764,10 @@ static ssize_t dp_dsc_slice_height_read(struct file *f, char __user *buf,
break;
r = put_user(*(rd_buf + result), buf);
- if (r)
+ if (r) {
+ kfree(rd_buf);
return r; /* r = -EFAULT */
+ }
buf += 1;
size -= 1;
@@ -1912,8 +1930,10 @@ static ssize_t dp_dsc_bits_per_pixel_read(struct file *f, char __user *buf,
break;
}
- if (!pipe_ctx)
+ if (!pipe_ctx) {
+ kfree(rd_buf);
return -ENXIO;
+ }
dsc = pipe_ctx->stream_res.dsc;
if (dsc)
@@ -1929,8 +1949,10 @@ static ssize_t dp_dsc_bits_per_pixel_read(struct file *f, char __user *buf,
break;
r = put_user(*(rd_buf + result), buf);
- if (r)
+ if (r) {
+ kfree(rd_buf);
return r; /* r = -EFAULT */
+ }
buf += 1;
size -= 1;
@@ -2088,8 +2110,10 @@ static ssize_t dp_dsc_pic_width_read(struct file *f, char __user *buf,
break;
}
- if (!pipe_ctx)
+ if (!pipe_ctx) {
+ kfree(rd_buf);
return -ENXIO;
+ }
dsc = pipe_ctx->stream_res.dsc;
if (dsc)
@@ -2105,8 +2129,10 @@ static ssize_t dp_dsc_pic_width_read(struct file *f, char __user *buf,
break;
r = put_user(*(rd_buf + result), buf);
- if (r)
+ if (r) {
+ kfree(rd_buf);
return r; /* r = -EFAULT */
+ }
buf += 1;
size -= 1;
@@ -2145,8 +2171,10 @@ static ssize_t dp_dsc_pic_height_read(struct file *f, char __user *buf,
break;
}
- if (!pipe_ctx)
+ if (!pipe_ctx) {
+ kfree(rd_buf);
return -ENXIO;
+ }
dsc = pipe_ctx->stream_res.dsc;
if (dsc)
@@ -2162,8 +2190,10 @@ static ssize_t dp_dsc_pic_height_read(struct file *f, char __user *buf,
break;
r = put_user(*(rd_buf + result), buf);
- if (r)
+ if (r) {
+ kfree(rd_buf);
return r; /* r = -EFAULT */
+ }
buf += 1;
size -= 1;
@@ -2217,8 +2247,10 @@ static ssize_t dp_dsc_chunk_size_read(struct file *f, char __user *buf,
break;
}
- if (!pipe_ctx)
+ if (!pipe_ctx) {
+ kfree(rd_buf);
return -ENXIO;
+ }
dsc = pipe_ctx->stream_res.dsc;
if (dsc)
@@ -2234,8 +2266,10 @@ static ssize_t dp_dsc_chunk_size_read(struct file *f, char __user *buf,
break;
r = put_user(*(rd_buf + result), buf);
- if (r)
+ if (r) {
+ kfree(rd_buf);
return r; /* r = -EFAULT */
+ }
buf += 1;
size -= 1;
@@ -2289,8 +2323,10 @@ static ssize_t dp_dsc_slice_bpg_offset_read(struct file *f, char __user *buf,
break;
}
- if (!pipe_ctx)
+ if (!pipe_ctx) {
+ kfree(rd_buf);
return -ENXIO;
+ }
dsc = pipe_ctx->stream_res.dsc;
if (dsc)
@@ -2306,8 +2342,10 @@ static ssize_t dp_dsc_slice_bpg_offset_read(struct file *f, char __user *buf,
break;
r = put_user(*(rd_buf + result), buf);
- if (r)
+ if (r) {
+ kfree(rd_buf);
return r; /* r = -EFAULT */
+ }
buf += 1;
size -= 1;
@@ -2851,7 +2889,9 @@ static ssize_t edp_ilr_write(struct file *f, const char __user *buf,
kfree(wr_buf);
DRM_DEBUG_DRIVER("Invalid Input value. No HW will be programmed\n");
prefer_link_settings.use_link_rate_set = false;
- dc_link_set_preferred_training_settings(dc, NULL, NULL, link, true);
+ mutex_lock(&adev->dm.dc_lock);
+ dc_link_set_preferred_training_settings(dc, NULL, NULL, link, false);
+ mutex_unlock(&adev->dm.dc_lock);
return size;
}
@@ -3395,6 +3435,30 @@ static int dp_force_sst_get(void *data, u64 *val)
}
DEFINE_DEBUGFS_ATTRIBUTE(dp_set_mst_en_for_sst_ops, dp_force_sst_get,
dp_force_sst_set, "%llu\n");
+
+/*
+ * Force DP2 sequence without VESA certified cable.
+ * Example usage: echo 1 > /sys/kernel/debug/dri/0/amdgpu_dm_dp_ignore_cable_id
+ */
+static int dp_ignore_cable_id_set(void *data, u64 val)
+{
+ struct amdgpu_device *adev = data;
+
+ adev->dm.dc->debug.ignore_cable_id = val;
+
+ return 0;
+}
+
+static int dp_ignore_cable_id_get(void *data, u64 *val)
+{
+ struct amdgpu_device *adev = data;
+
+ *val = adev->dm.dc->debug.ignore_cable_id;
+
+ return 0;
+}
+DEFINE_DEBUGFS_ATTRIBUTE(dp_ignore_cable_id_ops, dp_ignore_cable_id_get,
+ dp_ignore_cable_id_set, "%llu\n");
#endif
/*
@@ -3459,8 +3523,10 @@ static ssize_t dcc_en_bits_read(
dc->hwss.get_dcc_en_bits(dc, dcc_en_bits);
rd_buf = kcalloc(rd_buf_size, sizeof(char), GFP_KERNEL);
- if (!rd_buf)
+ if (!rd_buf) {
+ kfree(dcc_en_bits);
return -ENOMEM;
+ }
for (i = 0; i < num_pipes; i++)
offset += snprintf(rd_buf + offset, rd_buf_size - offset,
@@ -3473,8 +3539,10 @@ static ssize_t dcc_en_bits_read(
if (*pos >= rd_buf_size)
break;
r = put_user(*(rd_buf + result), buf);
- if (r)
+ if (r) {
+ kfree(rd_buf);
return r; /* r = -EFAULT */
+ }
buf += 1;
size -= 1;
*pos += 1;
@@ -3509,6 +3577,8 @@ void dtn_debugfs_init(struct amdgpu_device *adev)
#if defined(CONFIG_DRM_AMD_DC_DCN)
debugfs_create_file("amdgpu_dm_dp_set_mst_en_for_sst", 0644, root, adev,
&dp_set_mst_en_for_sst_ops);
+ debugfs_create_file("amdgpu_dm_dp_ignore_cable_id", 0644, root, adev,
+ &dp_ignore_cable_id_ops);
#endif
debugfs_create_file_unsafe("amdgpu_dm_visual_confirm", 0644, root, adev,
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.c
index 5bfdc66b5867..bf0d50277f8f 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.c
@@ -663,7 +663,9 @@ struct hdcp_workqueue *hdcp_create_workqueue(struct amdgpu_device *adev, struct
INIT_DELAYED_WORK(&hdcp_work[i].property_validate_dwork, event_property_validate);
hdcp_work[i].hdcp.config.psp.handle = &adev->psp;
- if (dc->ctx->dce_version == DCN_VERSION_3_1)
+ if (dc->ctx->dce_version == DCN_VERSION_3_1 ||
+ dc->ctx->dce_version == DCN_VERSION_3_15 ||
+ dc->ctx->dce_version == DCN_VERSION_3_16)
hdcp_work[i].hdcp.config.psp.caps.dtm_v3_supported = 1;
hdcp_work[i].hdcp.config.ddc.handle = dc_get_link_at_index(dc, i);
hdcp_work[i].hdcp.config.ddc.funcs.write_i2c = lp_write_i2c;
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
index 29f07c26d080..f5f39984702f 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
@@ -39,6 +39,7 @@
#include "amdgpu_dm_mst_types.h"
#include "dm_helpers.h"
+#include "ddc_service_types.h"
struct monitor_patch_info {
unsigned int manufacturer_id;
@@ -445,7 +446,7 @@ bool dm_helpers_dp_mst_start_top_mgr(
return (drm_dp_mst_topology_mgr_set_mst(&aconnector->mst_mgr, true) == 0);
}
-void dm_helpers_dp_mst_stop_top_mgr(
+bool dm_helpers_dp_mst_stop_top_mgr(
struct dc_context *ctx,
struct dc_link *link)
{
@@ -454,7 +455,7 @@ void dm_helpers_dp_mst_stop_top_mgr(
if (!aconnector) {
DRM_ERROR("Failed to find connector for link!");
- return;
+ return false;
}
DRM_INFO("DM_MST: stopping TM on aconnector: %p [id: %d]\n",
@@ -479,6 +480,8 @@ void dm_helpers_dp_mst_stop_top_mgr(
}
}
}
+
+ return false;
}
bool dm_helpers_dp_read_dpcd(
@@ -552,6 +555,177 @@ bool dm_helpers_submit_i2c(
return result;
}
+
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+static bool execute_synaptics_rc_command(struct drm_dp_aux *aux,
+ bool is_write_cmd,
+ unsigned char cmd,
+ unsigned int length,
+ unsigned int offset,
+ unsigned char *data)
+{
+ bool success = false;
+ unsigned char rc_data[16] = {0};
+ unsigned char rc_offset[4] = {0};
+ unsigned char rc_length[2] = {0};
+ unsigned char rc_cmd = 0;
+ unsigned char rc_result = 0xFF;
+ unsigned char i = 0;
+ uint8_t ret = 0;
+
+ if (is_write_cmd) {
+ // write rc data
+ memmove(rc_data, data, length);
+ ret = drm_dp_dpcd_write(aux, SYNAPTICS_RC_DATA, rc_data, sizeof(rc_data));
+ }
+
+ // write rc offset
+ rc_offset[0] = (unsigned char) offset & 0xFF;
+ rc_offset[1] = (unsigned char) (offset >> 8) & 0xFF;
+ rc_offset[2] = (unsigned char) (offset >> 16) & 0xFF;
+ rc_offset[3] = (unsigned char) (offset >> 24) & 0xFF;
+ ret = drm_dp_dpcd_write(aux, SYNAPTICS_RC_OFFSET, rc_offset, sizeof(rc_offset));
+
+ // write rc length
+ rc_length[0] = (unsigned char) length & 0xFF;
+ rc_length[1] = (unsigned char) (length >> 8) & 0xFF;
+ ret = drm_dp_dpcd_write(aux, SYNAPTICS_RC_LENGTH, rc_length, sizeof(rc_length));
+
+ // write rc cmd
+ rc_cmd = cmd | 0x80;
+ ret = drm_dp_dpcd_write(aux, SYNAPTICS_RC_COMMAND, &rc_cmd, sizeof(rc_cmd));
+
+ if (ret < 0) {
+ DRM_ERROR(" execute_synaptics_rc_command - write cmd ..., err = %d\n", ret);
+ return false;
+ }
+
+ // poll until active is 0
+ for (i = 0; i < 10; i++) {
+ drm_dp_dpcd_read(aux, SYNAPTICS_RC_COMMAND, &rc_cmd, sizeof(rc_cmd));
+ if (rc_cmd == cmd)
+ // active is 0
+ break;
+ msleep(10);
+ }
+
+ // read rc result
+ drm_dp_dpcd_read(aux, SYNAPTICS_RC_RESULT, &rc_result, sizeof(rc_result));
+ success = (rc_result == 0);
+
+ if (success && !is_write_cmd) {
+ // read rc data
+ drm_dp_dpcd_read(aux, SYNAPTICS_RC_DATA, data, length);
+ }
+
+ DC_LOG_DC(" execute_synaptics_rc_command - success = %d\n", success);
+
+ return success;
+}
+
+static void apply_synaptics_fifo_reset_wa(struct drm_dp_aux *aux)
+{
+ unsigned char data[16] = {0};
+
+ DC_LOG_DC("Start apply_synaptics_fifo_reset_wa\n");
+
+ // Step 2
+ data[0] = 'P';
+ data[1] = 'R';
+ data[2] = 'I';
+ data[3] = 'U';
+ data[4] = 'S';
+
+ if (!execute_synaptics_rc_command(aux, true, 0x01, 5, 0, data))
+ return;
+
+ // Step 3 and 4
+ if (!execute_synaptics_rc_command(aux, false, 0x31, 4, 0x220998, data))
+ return;
+
+ data[0] &= (~(1 << 1)); // set bit 1 to 0
+ if (!execute_synaptics_rc_command(aux, true, 0x21, 4, 0x220998, data))
+ return;
+
+ if (!execute_synaptics_rc_command(aux, false, 0x31, 4, 0x220D98, data))
+ return;
+
+ data[0] &= (~(1 << 1)); // set bit 1 to 0
+ if (!execute_synaptics_rc_command(aux, true, 0x21, 4, 0x220D98, data))
+ return;
+
+ if (!execute_synaptics_rc_command(aux, false, 0x31, 4, 0x221198, data))
+ return;
+
+ data[0] &= (~(1 << 1)); // set bit 1 to 0
+ if (!execute_synaptics_rc_command(aux, true, 0x21, 4, 0x221198, data))
+ return;
+
+ // Step 3 and 5
+ if (!execute_synaptics_rc_command(aux, false, 0x31, 4, 0x220998, data))
+ return;
+
+ data[0] |= (1 << 1); // set bit 1 to 1
+ if (!execute_synaptics_rc_command(aux, true, 0x21, 4, 0x220998, data))
+ return;
+
+ if (!execute_synaptics_rc_command(aux, false, 0x31, 4, 0x220D98, data))
+ return;
+
+ data[0] |= (1 << 1); // set bit 1 to 1
+ return;
+
+ if (!execute_synaptics_rc_command(aux, false, 0x31, 4, 0x221198, data))
+ return;
+
+ data[0] |= (1 << 1); // set bit 1 to 1
+ if (!execute_synaptics_rc_command(aux, true, 0x21, 4, 0x221198, data))
+ return;
+
+ // Step 6
+ if (!execute_synaptics_rc_command(aux, true, 0x02, 0, 0, NULL))
+ return;
+
+ DC_LOG_DC("Done apply_synaptics_fifo_reset_wa\n");
+}
+
+static uint8_t write_dsc_enable_synaptics_non_virtual_dpcd_mst(
+ struct drm_dp_aux *aux,
+ const struct dc_stream_state *stream,
+ bool enable)
+{
+ uint8_t ret = 0;
+
+ DC_LOG_DC("Configure DSC to non-virtual dpcd synaptics\n");
+
+ if (enable) {
+ /* When DSC is enabled on previous boot and reboot with the hub,
+ * there is a chance that Synaptics hub gets stuck during reboot sequence.
+ * Applying a workaround to reset Synaptics SDP fifo before enabling the first stream
+ */
+ if (!stream->link->link_status.link_active &&
+ memcmp(stream->link->dpcd_caps.branch_dev_name,
+ (int8_t *)SYNAPTICS_DEVICE_ID, 4) == 0)
+ apply_synaptics_fifo_reset_wa(aux);
+
+ ret = drm_dp_dpcd_write(aux, DP_DSC_ENABLE, &enable, 1);
+ DRM_INFO("Send DSC enable to synaptics\n");
+
+ } else {
+ /* Synaptics hub not support virtual dpcd,
+ * external monitor occur garbage while disable DSC,
+ * Disable DSC only when entire link status turn to false,
+ */
+ if (!stream->link->link_status.link_active) {
+ ret = drm_dp_dpcd_write(aux, DP_DSC_ENABLE, &enable, 1);
+ DRM_INFO("Send DSC disable to synaptics\n");
+ }
+ }
+
+ return ret;
+}
+#endif
+
bool dm_helpers_dp_write_dsc_enable(
struct dc_context *ctx,
const struct dc_stream_state *stream,
@@ -570,7 +744,16 @@ bool dm_helpers_dp_write_dsc_enable(
if (!aconnector->dsc_aux)
return false;
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+ // apply w/a to synaptics
+ if (needs_dsc_aux_workaround(aconnector->dc_link) &&
+ (aconnector->mst_downstream_port_present.byte & 0x7) != 0x3)
+ return write_dsc_enable_synaptics_non_virtual_dpcd_mst(
+ aconnector->dsc_aux, stream, enable_dsc);
+#endif
+
ret = drm_dp_dpcd_write(aconnector->dsc_aux, DP_DSC_ENABLE, &enable_dsc, 1);
+ DC_LOG_DC("Send DSC %s to MST RX\n", enable_dsc ? "enable" : "disable");
}
if (stream->signal == SIGNAL_TYPE_DISPLAY_PORT || stream->signal == SIGNAL_TYPE_EDP) {
@@ -648,14 +831,6 @@ enum dc_edid_status dm_helpers_read_local_edid(
/* We don't need the original edid anymore */
kfree(edid);
- /* connector->display_info is parsed from EDID and saved
- * into drm_connector->display_info
- *
- * drm_connector->display_info will be used by amdgpu_dm funcs,
- * like fill_stream_properties_from_drm_display_mode
- */
- amdgpu_dm_update_connector_after_detect(aconnector);
-
edid_status = dm_helpers_parse_edid_caps(
link,
&sink->dc_edid,
@@ -797,16 +972,14 @@ void dm_helpers_mst_enable_stream_features(const struct dc_stream_state *stream)
sizeof(new_downspread));
}
-#if defined(CONFIG_DRM_AMD_DC_DCN)
void dm_set_phyd32clk(struct dc_context *ctx, int freq_khz)
{
- // FPGA programming for this clock in diags framework that
- // needs to go through dm layer, therefore leave dummy interace here
+ // TODO
}
-
+#if defined(CONFIG_DRM_AMD_DC_DCN)
void dm_helpers_enable_periodic_detection(struct dc_context *ctx, bool enable)
{
- /* TODO: add peridic detection implementation */
+ /* TODO: add periodic detection implementation */
}
#endif
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
index cc34a35d0bcb..31ac1fce36f8 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
@@ -25,8 +25,8 @@
#include <drm/drm_atomic.h>
#include <drm/drm_atomic_helper.h>
-#include <drm/drm_dp_mst_helper.h>
-#include <drm/drm_dp_helper.h>
+#include <drm/dp/drm_dp_mst_helper.h>
+#include <drm/dp/drm_dp_helper.h>
#include "dm_services.h"
#include "amdgpu.h"
#include "amdgpu_dm.h"
@@ -47,6 +47,9 @@
#if defined(CONFIG_DRM_AMD_DC_DCN)
#include "dc/dcn20/dcn20_resource.h"
+bool is_timing_changed(struct dc_stream_state *cur_stream,
+ struct dc_stream_state *new_stream);
+
#endif
static ssize_t dm_dp_aux_transfer(struct drm_dp_aux *aux,
@@ -159,7 +162,7 @@ static const struct drm_connector_funcs dm_dp_mst_connector_funcs = {
};
#if defined(CONFIG_DRM_AMD_DC_DCN)
-static bool needs_dsc_aux_workaround(struct dc_link *link)
+bool needs_dsc_aux_workaround(struct dc_link *link)
{
if (link->dpcd_caps.branch_dev_id == DP_BRANCH_DEVICE_ID_90CC24 &&
(link->dpcd_caps.dpcd_rev.raw == DPCD_REV_14 || link->dpcd_caps.dpcd_rev.raw == DPCD_REV_12) &&
@@ -209,6 +212,25 @@ static bool validate_dsc_caps_on_connector(struct amdgpu_dm_connector *aconnecto
return true;
}
+
+static bool retrieve_downstream_port_device(struct amdgpu_dm_connector *aconnector)
+{
+ union dp_downstream_port_present ds_port_present;
+
+ if (!aconnector->dsc_aux)
+ return false;
+
+ if (drm_dp_dpcd_read(aconnector->dsc_aux, DP_DOWNSTREAMPORT_PRESENT, &ds_port_present, 1) < 0) {
+ DRM_INFO("Failed to read downstream_port_present 0x05 from DFP of branch device\n");
+ return false;
+ }
+
+ aconnector->mst_downstream_port_present = ds_port_present;
+ DRM_INFO("Downstream port present %d, type %d\n",
+ ds_port_present.fields.PORT_PRESENT, ds_port_present.fields.PORT_TYPE);
+
+ return true;
+}
#endif
static int dm_dp_mst_get_modes(struct drm_connector *connector)
@@ -289,6 +311,10 @@ static int dm_dp_mst_get_modes(struct drm_connector *connector)
if (!validate_dsc_caps_on_connector(aconnector))
memset(&aconnector->dc_sink->dsc_caps,
0, sizeof(aconnector->dc_sink->dsc_caps));
+
+ if (!retrieve_downstream_port_device(aconnector))
+ memset(&aconnector->mst_downstream_port_present,
+ 0, sizeof(aconnector->mst_downstream_port_present));
#endif
}
}
@@ -576,6 +602,21 @@ static void set_dsc_configs_from_fairness_vars(struct dsc_mst_fairness_params *p
} else {
params[i].timing->flags.DSC = 0;
}
+ params[i].timing->dsc_cfg.mst_pbn = vars[i + k].pbn;
+ }
+
+ for (i = 0; i < count; i++) {
+ if (params[i].sink) {
+ if (params[i].sink->sink_signal != SIGNAL_TYPE_VIRTUAL &&
+ params[i].sink->sink_signal != SIGNAL_TYPE_NONE)
+ DRM_DEBUG_DRIVER("%s i=%d dispname=%s\n", __func__, i,
+ params[i].sink->edid_caps.display_name);
+ }
+
+ DRM_DEBUG_DRIVER("dsc=%d bits_per_pixel=%d pbn=%d\n",
+ params[i].timing->flags.DSC,
+ params[i].timing->dsc_cfg.bits_per_pixel,
+ vars[i + k].pbn);
}
}
@@ -888,22 +929,31 @@ static bool is_dsc_need_re_compute(
struct dc_state *dc_state,
struct dc_link *dc_link)
{
- int i;
+ int i, j;
bool is_dsc_need_re_compute = false;
+ struct amdgpu_dm_connector *stream_on_link[MAX_PIPES];
+ int new_stream_on_link_num = 0;
+ struct amdgpu_dm_connector *aconnector;
+ struct dc_stream_state *stream;
+ const struct dc *dc = dc_link->dc;
- /* only check phy used by mst branch */
+ /* only check phy used by dsc mst branch */
if (dc_link->type != dc_connection_mst_branch)
return false;
+ if (!(dc_link->dpcd_caps.dsc_caps.dsc_basic_caps.fields.dsc_support.DSC_SUPPORT ||
+ dc_link->dpcd_caps.dsc_caps.dsc_basic_caps.fields.dsc_support.DSC_PASSTHROUGH_SUPPORT))
+ return false;
+
+ for (i = 0; i < MAX_PIPES; i++)
+ stream_on_link[i] = NULL;
+
/* check if there is mode change in new request */
for (i = 0; i < dc_state->stream_count; i++) {
- struct amdgpu_dm_connector *aconnector;
- struct dc_stream_state *stream;
struct drm_crtc_state *new_crtc_state;
struct drm_connector_state *new_conn_state;
stream = dc_state->streams[i];
-
if (!stream)
continue;
@@ -915,8 +965,10 @@ static bool is_dsc_need_re_compute(
if (!aconnector)
continue;
- new_conn_state = drm_atomic_get_new_connector_state(state, &aconnector->base);
+ stream_on_link[new_stream_on_link_num] = aconnector;
+ new_stream_on_link_num++;
+ new_conn_state = drm_atomic_get_new_connector_state(state, &aconnector->base);
if (!new_conn_state)
continue;
@@ -927,7 +979,6 @@ static bool is_dsc_need_re_compute(
continue;
new_crtc_state = drm_atomic_get_new_crtc_state(state, new_conn_state->crtc);
-
if (!new_crtc_state)
continue;
@@ -937,7 +988,34 @@ static bool is_dsc_need_re_compute(
if (new_crtc_state->enable && new_crtc_state->active) {
if (new_crtc_state->mode_changed || new_crtc_state->active_changed ||
new_crtc_state->connectors_changed)
- is_dsc_need_re_compute = true;
+ return true;
+ }
+ }
+
+ /* check current_state if there stream on link but it is not in
+ * new request state
+ */
+ for (i = 0; i < dc->current_state->stream_count; i++) {
+ stream = dc->current_state->streams[i];
+ /* only check stream on the mst hub */
+ if (stream->link != dc_link)
+ continue;
+
+ aconnector = (struct amdgpu_dm_connector *)stream->dm_stream_context;
+ if (!aconnector)
+ continue;
+
+ for (j = 0; j < new_stream_on_link_num; j++) {
+ if (stream_on_link[j]) {
+ if (aconnector == stream_on_link[j])
+ break;
+ }
+ }
+
+ if (j == new_stream_on_link_num) {
+ /* not in new state */
+ is_dsc_need_re_compute = true;
+ break;
}
}
@@ -1005,4 +1083,197 @@ bool compute_mst_dsc_configs_for_state(struct drm_atomic_state *state,
return true;
}
+static bool
+ pre_compute_mst_dsc_configs_for_state(struct drm_atomic_state *state,
+ struct dc_state *dc_state,
+ struct dsc_mst_fairness_vars *vars)
+{
+ int i, j;
+ struct dc_stream_state *stream;
+ bool computed_streams[MAX_PIPES];
+ struct amdgpu_dm_connector *aconnector;
+ int link_vars_start_index = 0;
+
+ for (i = 0; i < dc_state->stream_count; i++)
+ computed_streams[i] = false;
+
+ for (i = 0; i < dc_state->stream_count; i++) {
+ stream = dc_state->streams[i];
+
+ if (stream->signal != SIGNAL_TYPE_DISPLAY_PORT_MST)
+ continue;
+
+ aconnector = (struct amdgpu_dm_connector *)stream->dm_stream_context;
+
+ if (!aconnector || !aconnector->dc_sink)
+ continue;
+
+ if (!aconnector->dc_sink->dsc_caps.dsc_dec_caps.is_dsc_supported)
+ continue;
+
+ if (computed_streams[i])
+ continue;
+
+ if (!is_dsc_need_re_compute(state, dc_state, stream->link))
+ continue;
+
+ mutex_lock(&aconnector->mst_mgr.lock);
+ if (!compute_mst_dsc_configs_for_link(state,
+ dc_state,
+ stream->link,
+ vars,
+ &link_vars_start_index)) {
+ mutex_unlock(&aconnector->mst_mgr.lock);
+ return false;
+ }
+ mutex_unlock(&aconnector->mst_mgr.lock);
+
+ for (j = 0; j < dc_state->stream_count; j++) {
+ if (dc_state->streams[j]->link == stream->link)
+ computed_streams[j] = true;
+ }
+ }
+
+ return true;
+}
+
+static int find_crtc_index_in_state_by_stream(struct drm_atomic_state *state,
+ struct dc_stream_state *stream)
+{
+ int i;
+ struct drm_crtc *crtc;
+ struct drm_crtc_state *new_state, *old_state;
+
+ for_each_oldnew_crtc_in_state(state, crtc, old_state, new_state, i) {
+ struct dm_crtc_state *dm_state = to_dm_crtc_state(new_state);
+
+ if (dm_state->stream == stream)
+ return i;
+ }
+ return -1;
+}
+
+static bool is_link_to_dschub(struct dc_link *dc_link)
+{
+ union dpcd_dsc_basic_capabilities *dsc_caps =
+ &dc_link->dpcd_caps.dsc_caps.dsc_basic_caps;
+
+ /* only check phy used by dsc mst branch */
+ if (dc_link->type != dc_connection_mst_branch)
+ return false;
+
+ if (!(dsc_caps->fields.dsc_support.DSC_SUPPORT ||
+ dsc_caps->fields.dsc_support.DSC_PASSTHROUGH_SUPPORT))
+ return false;
+ return true;
+}
+
+static bool is_dsc_precompute_needed(struct drm_atomic_state *state)
+{
+ int i;
+ struct drm_crtc *crtc;
+ struct drm_crtc_state *old_crtc_state, *new_crtc_state;
+ bool ret = false;
+
+ for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) {
+ struct dm_crtc_state *dm_crtc_state = to_dm_crtc_state(new_crtc_state);
+
+ if (!amdgpu_dm_find_first_crtc_matching_connector(state, crtc)) {
+ ret = false;
+ break;
+ }
+ if (dm_crtc_state->stream && dm_crtc_state->stream->link)
+ if (is_link_to_dschub(dm_crtc_state->stream->link))
+ ret = true;
+ }
+ return ret;
+}
+
+void pre_validate_dsc(struct drm_atomic_state *state,
+ struct dm_atomic_state **dm_state_ptr,
+ struct dsc_mst_fairness_vars *vars)
+{
+ int i;
+ struct dm_atomic_state *dm_state;
+ struct dc_state *local_dc_state = NULL;
+
+ if (!is_dsc_precompute_needed(state)) {
+ DRM_INFO_ONCE("DSC precompute is not needed.\n");
+ return;
+ }
+ if (dm_atomic_get_state(state, dm_state_ptr)) {
+ DRM_INFO_ONCE("dm_atomic_get_state() failed\n");
+ return;
+ }
+ dm_state = *dm_state_ptr;
+
+ /*
+ * create local vailable for dc_state. copy content of streams of dm_state->context
+ * to local variable. make sure stream pointer of local variable not the same as stream
+ * from dm_state->context.
+ */
+
+ local_dc_state = kmemdup(dm_state->context, sizeof(struct dc_state), GFP_KERNEL);
+ if (!local_dc_state)
+ return;
+
+ for (i = 0; i < local_dc_state->stream_count; i++) {
+ struct dc_stream_state *stream = dm_state->context->streams[i];
+ int ind = find_crtc_index_in_state_by_stream(state, stream);
+
+ if (ind >= 0) {
+ struct amdgpu_dm_connector *aconnector;
+ struct drm_connector_state *drm_new_conn_state;
+ struct dm_connector_state *dm_new_conn_state;
+ struct dm_crtc_state *dm_old_crtc_state;
+
+ aconnector =
+ amdgpu_dm_find_first_crtc_matching_connector(state,
+ state->crtcs[ind].ptr);
+ drm_new_conn_state =
+ drm_atomic_get_new_connector_state(state,
+ &aconnector->base);
+ dm_new_conn_state = to_dm_connector_state(drm_new_conn_state);
+ dm_old_crtc_state = to_dm_crtc_state(state->crtcs[ind].old_state);
+
+ local_dc_state->streams[i] =
+ create_validate_stream_for_sink(aconnector,
+ &state->crtcs[ind].new_state->mode,
+ dm_new_conn_state,
+ dm_old_crtc_state->stream);
+ }
+ }
+
+ if (!pre_compute_mst_dsc_configs_for_state(state, local_dc_state, vars)) {
+ DRM_INFO_ONCE("pre_compute_mst_dsc_configs_for_state() failed\n");
+ goto clean_exit;
+ }
+
+ /*
+ * compare local_streams -> timing with dm_state->context,
+ * if the same set crtc_state->mode-change = 0;
+ */
+ for (i = 0; i < local_dc_state->stream_count; i++) {
+ struct dc_stream_state *stream = dm_state->context->streams[i];
+
+ if (local_dc_state->streams[i] &&
+ is_timing_changed(stream, local_dc_state->streams[i])) {
+ DRM_INFO_ONCE("crtc[%d] needs mode_changed\n", i);
+ } else {
+ int ind = find_crtc_index_in_state_by_stream(state, stream);
+
+ if (ind >= 0)
+ state->crtcs[ind].new_state->mode_changed = 0;
+ }
+ }
+clean_exit:
+ for (i = 0; i < local_dc_state->stream_count; i++) {
+ struct dc_stream_state *stream = dm_state->context->streams[i];
+
+ if (local_dc_state->streams[i] != stream)
+ dc_stream_release(local_dc_state->streams[i]);
+ }
+
+ kfree(local_dc_state);
+}
#endif
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.h b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.h
index 900d3f7a8498..c561e0d872d6 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.h
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.h
@@ -26,6 +26,14 @@
#ifndef __DAL_AMDGPU_DM_MST_TYPES_H__
#define __DAL_AMDGPU_DM_MST_TYPES_H__
+#define DP_BRANCH_DEVICE_ID_90CC24 0x90CC24
+
+#define SYNAPTICS_RC_COMMAND 0x4B2
+#define SYNAPTICS_RC_RESULT 0x4B3
+#define SYNAPTICS_RC_LENGTH 0x4B8
+#define SYNAPTICS_RC_OFFSET 0x4BC
+#define SYNAPTICS_RC_DATA 0x4C0
+
struct amdgpu_display_manager;
struct amdgpu_dm_connector;
@@ -50,6 +58,12 @@ struct dsc_mst_fairness_vars {
bool compute_mst_dsc_configs_for_state(struct drm_atomic_state *state,
struct dc_state *dc_state,
struct dsc_mst_fairness_vars *vars);
+
+bool needs_dsc_aux_workaround(struct dc_link *link);
+
+void pre_validate_dsc(struct drm_atomic_state *state,
+ struct dm_atomic_state **dm_state_ptr,
+ struct dsc_mst_fairness_vars *vars);
#endif
#endif
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_pp_smu.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_pp_smu.c
index eba270121698..75284e2cec74 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_pp_smu.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_pp_smu.c
@@ -99,12 +99,9 @@ bool dm_pp_apply_display_requirements(
adev->pm.pm_display_cfg.displays[i].controller_id = dc_cfg->pipe_idx + 1;
}
- if (adev->powerplay.pp_funcs && adev->powerplay.pp_funcs->display_configuration_change)
- adev->powerplay.pp_funcs->display_configuration_change(
- adev->powerplay.pp_handle,
- &adev->pm.pm_display_cfg);
+ amdgpu_dpm_display_configuration_change(adev, &adev->pm.pm_display_cfg);
- amdgpu_pm_compute_clocks(adev);
+ amdgpu_dpm_compute_clocks(adev);
}
return true;
@@ -298,31 +295,25 @@ bool dm_pp_get_clock_levels_by_type(
struct dm_pp_clock_levels *dc_clks)
{
struct amdgpu_device *adev = ctx->driver_context;
- void *pp_handle = adev->powerplay.pp_handle;
struct amd_pp_clocks pp_clks = { 0 };
struct amd_pp_simple_clock_info validation_clks = { 0 };
uint32_t i;
- if (adev->powerplay.pp_funcs && adev->powerplay.pp_funcs->get_clock_by_type) {
- if (adev->powerplay.pp_funcs->get_clock_by_type(pp_handle,
- dc_to_pp_clock_type(clk_type), &pp_clks)) {
- /* Error in pplib. Provide default values. */
- get_default_clock_levels(clk_type, dc_clks);
- return true;
- }
+ if (amdgpu_dpm_get_clock_by_type(adev,
+ dc_to_pp_clock_type(clk_type), &pp_clks)) {
+ /* Error in pplib. Provide default values. */
+ get_default_clock_levels(clk_type, dc_clks);
+ return true;
}
pp_to_dc_clock_levels(&pp_clks, dc_clks, clk_type);
- if (adev->powerplay.pp_funcs && adev->powerplay.pp_funcs->get_display_mode_validation_clocks) {
- if (adev->powerplay.pp_funcs->get_display_mode_validation_clocks(
- pp_handle, &validation_clks)) {
- /* Error in pplib. Provide default values. */
- DRM_INFO("DM_PPLIB: Warning: using default validation clocks!\n");
- validation_clks.engine_max_clock = 72000;
- validation_clks.memory_max_clock = 80000;
- validation_clks.level = 0;
- }
+ if (amdgpu_dpm_get_display_mode_validation_clks(adev, &validation_clks)) {
+ /* Error in pplib. Provide default values. */
+ DRM_INFO("DM_PPLIB: Warning: using default validation clocks!\n");
+ validation_clks.engine_max_clock = 72000;
+ validation_clks.memory_max_clock = 80000;
+ validation_clks.level = 0;
}
DRM_INFO("DM_PPLIB: Validation clocks:\n");
@@ -370,18 +361,14 @@ bool dm_pp_get_clock_levels_by_type_with_latency(
struct dm_pp_clock_levels_with_latency *clk_level_info)
{
struct amdgpu_device *adev = ctx->driver_context;
- void *pp_handle = adev->powerplay.pp_handle;
struct pp_clock_levels_with_latency pp_clks = { 0 };
- const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
int ret;
- if (pp_funcs && pp_funcs->get_clock_by_type_with_latency) {
- ret = pp_funcs->get_clock_by_type_with_latency(pp_handle,
- dc_to_pp_clock_type(clk_type),
- &pp_clks);
- if (ret)
- return false;
- }
+ ret = amdgpu_dpm_get_clock_by_type_with_latency(adev,
+ dc_to_pp_clock_type(clk_type),
+ &pp_clks);
+ if (ret)
+ return false;
pp_to_dc_clock_levels_with_latency(&pp_clks, clk_level_info, clk_type);
@@ -394,18 +381,14 @@ bool dm_pp_get_clock_levels_by_type_with_voltage(
struct dm_pp_clock_levels_with_voltage *clk_level_info)
{
struct amdgpu_device *adev = ctx->driver_context;
- void *pp_handle = adev->powerplay.pp_handle;
struct pp_clock_levels_with_voltage pp_clk_info = {0};
- const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
int ret;
- if (pp_funcs && pp_funcs->get_clock_by_type_with_voltage) {
- ret = pp_funcs->get_clock_by_type_with_voltage(pp_handle,
- dc_to_pp_clock_type(clk_type),
- &pp_clk_info);
- if (ret)
- return false;
- }
+ ret = amdgpu_dpm_get_clock_by_type_with_voltage(adev,
+ dc_to_pp_clock_type(clk_type),
+ &pp_clk_info);
+ if (ret)
+ return false;
pp_to_dc_clock_levels_with_voltage(&pp_clk_info, clk_level_info, clk_type);
@@ -417,19 +400,16 @@ bool dm_pp_notify_wm_clock_changes(
struct dm_pp_wm_sets_with_clock_ranges *wm_with_clock_ranges)
{
struct amdgpu_device *adev = ctx->driver_context;
- void *pp_handle = adev->powerplay.pp_handle;
- const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
/*
* Limit this watermark setting for Polaris for now
* TODO: expand this to other ASICs
*/
- if ((adev->asic_type >= CHIP_POLARIS10) && (adev->asic_type <= CHIP_VEGAM)
- && pp_funcs && pp_funcs->set_watermarks_for_clocks_ranges) {
- if (!pp_funcs->set_watermarks_for_clocks_ranges(pp_handle,
+ if ((adev->asic_type >= CHIP_POLARIS10) &&
+ (adev->asic_type <= CHIP_VEGAM) &&
+ !amdgpu_dpm_set_watermarks_for_clocks_ranges(adev,
(void *)wm_with_clock_ranges))
return true;
- }
return false;
}
@@ -456,12 +436,10 @@ bool dm_pp_apply_clock_for_voltage_request(
if (!pp_clock_request.clock_type)
return false;
- if (adev->powerplay.pp_funcs && adev->powerplay.pp_funcs->display_clock_voltage_request)
- ret = adev->powerplay.pp_funcs->display_clock_voltage_request(
- adev->powerplay.pp_handle,
- &pp_clock_request);
- if (ret)
+ ret = amdgpu_dpm_display_clock_voltage_request(adev, &pp_clock_request);
+ if (ret && (ret != -EOPNOTSUPP))
return false;
+
return true;
}
@@ -471,15 +449,8 @@ bool dm_pp_get_static_clocks(
{
struct amdgpu_device *adev = ctx->driver_context;
struct amd_pp_clock_info pp_clk_info = {0};
- int ret = 0;
- if (adev->powerplay.pp_funcs && adev->powerplay.pp_funcs->get_current_clocks)
- ret = adev->powerplay.pp_funcs->get_current_clocks(
- adev->powerplay.pp_handle,
- &pp_clk_info);
- else
- return false;
- if (ret)
+ if (amdgpu_dpm_get_current_clocks(adev, &pp_clk_info))
return false;
static_clk_info->max_clocks_state = pp_to_dc_powerlevel_state(pp_clk_info.max_clocks_state);
@@ -494,8 +465,6 @@ static void pp_rv_set_wm_ranges(struct pp_smu *pp,
{
const struct dc_context *ctx = pp->dm;
struct amdgpu_device *adev = ctx->driver_context;
- void *pp_handle = adev->powerplay.pp_handle;
- const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
struct dm_pp_wm_sets_with_clock_ranges_soc15 wm_with_clock_ranges;
struct dm_pp_clock_range_for_dmif_wm_set_soc15 *wm_dce_clocks = wm_with_clock_ranges.wm_dmif_clocks_ranges;
struct dm_pp_clock_range_for_mcif_wm_set_soc15 *wm_soc_clocks = wm_with_clock_ranges.wm_mcif_clocks_ranges;
@@ -536,72 +505,48 @@ static void pp_rv_set_wm_ranges(struct pp_smu *pp,
ranges->writer_wm_sets[i].min_drain_clk_mhz * 1000;
}
- if (pp_funcs && pp_funcs->set_watermarks_for_clocks_ranges)
- pp_funcs->set_watermarks_for_clocks_ranges(pp_handle,
- &wm_with_clock_ranges);
+ amdgpu_dpm_set_watermarks_for_clocks_ranges(adev,
+ &wm_with_clock_ranges);
}
static void pp_rv_set_pme_wa_enable(struct pp_smu *pp)
{
const struct dc_context *ctx = pp->dm;
struct amdgpu_device *adev = ctx->driver_context;
- void *pp_handle = adev->powerplay.pp_handle;
- const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
- if (pp_funcs && pp_funcs->notify_smu_enable_pwe)
- pp_funcs->notify_smu_enable_pwe(pp_handle);
+ amdgpu_dpm_notify_smu_enable_pwe(adev);
}
static void pp_rv_set_active_display_count(struct pp_smu *pp, int count)
{
const struct dc_context *ctx = pp->dm;
struct amdgpu_device *adev = ctx->driver_context;
- void *pp_handle = adev->powerplay.pp_handle;
- const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
- if (!pp_funcs || !pp_funcs->set_active_display_count)
- return;
-
- pp_funcs->set_active_display_count(pp_handle, count);
+ amdgpu_dpm_set_active_display_count(adev, count);
}
static void pp_rv_set_min_deep_sleep_dcfclk(struct pp_smu *pp, int clock)
{
const struct dc_context *ctx = pp->dm;
struct amdgpu_device *adev = ctx->driver_context;
- void *pp_handle = adev->powerplay.pp_handle;
- const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
-
- if (!pp_funcs || !pp_funcs->set_min_deep_sleep_dcefclk)
- return;
- pp_funcs->set_min_deep_sleep_dcefclk(pp_handle, clock);
+ amdgpu_dpm_set_min_deep_sleep_dcefclk(adev, clock);
}
static void pp_rv_set_hard_min_dcefclk_by_freq(struct pp_smu *pp, int clock)
{
const struct dc_context *ctx = pp->dm;
struct amdgpu_device *adev = ctx->driver_context;
- void *pp_handle = adev->powerplay.pp_handle;
- const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
- if (!pp_funcs || !pp_funcs->set_hard_min_dcefclk_by_freq)
- return;
-
- pp_funcs->set_hard_min_dcefclk_by_freq(pp_handle, clock);
+ amdgpu_dpm_set_hard_min_dcefclk_by_freq(adev, clock);
}
static void pp_rv_set_hard_min_fclk_by_freq(struct pp_smu *pp, int mhz)
{
const struct dc_context *ctx = pp->dm;
struct amdgpu_device *adev = ctx->driver_context;
- void *pp_handle = adev->powerplay.pp_handle;
- const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
-
- if (!pp_funcs || !pp_funcs->set_hard_min_fclk_by_freq)
- return;
- pp_funcs->set_hard_min_fclk_by_freq(pp_handle, mhz);
+ amdgpu_dpm_set_hard_min_fclk_by_freq(adev, mhz);
}
static enum pp_smu_status pp_nv_set_wm_ranges(struct pp_smu *pp,
@@ -609,11 +554,8 @@ static enum pp_smu_status pp_nv_set_wm_ranges(struct pp_smu *pp,
{
const struct dc_context *ctx = pp->dm;
struct amdgpu_device *adev = ctx->driver_context;
- void *pp_handle = adev->powerplay.pp_handle;
- const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
- if (pp_funcs && pp_funcs->set_watermarks_for_clocks_ranges)
- pp_funcs->set_watermarks_for_clocks_ranges(pp_handle, ranges);
+ amdgpu_dpm_set_watermarks_for_clocks_ranges(adev, ranges);
return PP_SMU_RESULT_OK;
}
@@ -622,14 +564,13 @@ static enum pp_smu_status pp_nv_set_display_count(struct pp_smu *pp, int count)
{
const struct dc_context *ctx = pp->dm;
struct amdgpu_device *adev = ctx->driver_context;
- void *pp_handle = adev->powerplay.pp_handle;
- const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
+ int ret = 0;
- if (!pp_funcs || !pp_funcs->set_active_display_count)
+ ret = amdgpu_dpm_set_active_display_count(adev, count);
+ if (ret == -EOPNOTSUPP)
return PP_SMU_RESULT_UNSUPPORTED;
-
- /* 0: successful or smu.ppt_funcs->set_display_count = NULL; 1: fail */
- if (pp_funcs->set_active_display_count(pp_handle, count))
+ else if (ret)
+ /* 0: successful or smu.ppt_funcs->set_display_count = NULL; 1: fail */
return PP_SMU_RESULT_FAIL;
return PP_SMU_RESULT_OK;
@@ -640,14 +581,13 @@ pp_nv_set_min_deep_sleep_dcfclk(struct pp_smu *pp, int mhz)
{
const struct dc_context *ctx = pp->dm;
struct amdgpu_device *adev = ctx->driver_context;
- void *pp_handle = adev->powerplay.pp_handle;
- const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
-
- if (!pp_funcs || !pp_funcs->set_min_deep_sleep_dcefclk)
- return PP_SMU_RESULT_UNSUPPORTED;
+ int ret = 0;
/* 0: successful or smu.ppt_funcs->set_deep_sleep_dcefclk = NULL;1: fail */
- if (pp_funcs->set_min_deep_sleep_dcefclk(pp_handle, mhz))
+ ret = amdgpu_dpm_set_min_deep_sleep_dcefclk(adev, mhz);
+ if (ret == -EOPNOTSUPP)
+ return PP_SMU_RESULT_UNSUPPORTED;
+ else if (ret)
return PP_SMU_RESULT_FAIL;
return PP_SMU_RESULT_OK;
@@ -658,12 +598,8 @@ static enum pp_smu_status pp_nv_set_hard_min_dcefclk_by_freq(
{
const struct dc_context *ctx = pp->dm;
struct amdgpu_device *adev = ctx->driver_context;
- void *pp_handle = adev->powerplay.pp_handle;
- const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
struct pp_display_clock_request clock_req;
-
- if (!pp_funcs || !pp_funcs->display_clock_voltage_request)
- return PP_SMU_RESULT_UNSUPPORTED;
+ int ret = 0;
clock_req.clock_type = amd_pp_dcef_clock;
clock_req.clock_freq_in_khz = mhz * 1000;
@@ -671,7 +607,10 @@ static enum pp_smu_status pp_nv_set_hard_min_dcefclk_by_freq(
/* 0: successful or smu.ppt_funcs->display_clock_voltage_request = NULL
* 1: fail
*/
- if (pp_funcs->display_clock_voltage_request(pp_handle, &clock_req))
+ ret = amdgpu_dpm_display_clock_voltage_request(adev, &clock_req);
+ if (ret == -EOPNOTSUPP)
+ return PP_SMU_RESULT_UNSUPPORTED;
+ else if (ret)
return PP_SMU_RESULT_FAIL;
return PP_SMU_RESULT_OK;
@@ -682,12 +621,8 @@ pp_nv_set_hard_min_uclk_by_freq(struct pp_smu *pp, int mhz)
{
const struct dc_context *ctx = pp->dm;
struct amdgpu_device *adev = ctx->driver_context;
- void *pp_handle = adev->powerplay.pp_handle;
- const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
struct pp_display_clock_request clock_req;
-
- if (!pp_funcs || !pp_funcs->display_clock_voltage_request)
- return PP_SMU_RESULT_UNSUPPORTED;
+ int ret = 0;
clock_req.clock_type = amd_pp_mem_clock;
clock_req.clock_freq_in_khz = mhz * 1000;
@@ -695,7 +630,10 @@ pp_nv_set_hard_min_uclk_by_freq(struct pp_smu *pp, int mhz)
/* 0: successful or smu.ppt_funcs->display_clock_voltage_request = NULL
* 1: fail
*/
- if (pp_funcs->display_clock_voltage_request(pp_handle, &clock_req))
+ ret = amdgpu_dpm_display_clock_voltage_request(adev, &clock_req);
+ if (ret == -EOPNOTSUPP)
+ return PP_SMU_RESULT_UNSUPPORTED;
+ else if (ret)
return PP_SMU_RESULT_FAIL;
return PP_SMU_RESULT_OK;
@@ -706,14 +644,10 @@ static enum pp_smu_status pp_nv_set_pstate_handshake_support(
{
const struct dc_context *ctx = pp->dm;
struct amdgpu_device *adev = ctx->driver_context;
- void *pp_handle = adev->powerplay.pp_handle;
- const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
- if (pp_funcs && pp_funcs->display_disable_memory_clock_switch) {
- if (pp_funcs->display_disable_memory_clock_switch(pp_handle,
- !pstate_handshake_supported))
- return PP_SMU_RESULT_FAIL;
- }
+ if (amdgpu_dpm_display_disable_memory_clock_switch(adev,
+ !pstate_handshake_supported))
+ return PP_SMU_RESULT_FAIL;
return PP_SMU_RESULT_OK;
}
@@ -723,12 +657,8 @@ static enum pp_smu_status pp_nv_set_voltage_by_freq(struct pp_smu *pp,
{
const struct dc_context *ctx = pp->dm;
struct amdgpu_device *adev = ctx->driver_context;
- void *pp_handle = adev->powerplay.pp_handle;
- const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
struct pp_display_clock_request clock_req;
-
- if (!pp_funcs || !pp_funcs->display_clock_voltage_request)
- return PP_SMU_RESULT_UNSUPPORTED;
+ int ret = 0;
switch (clock_id) {
case PP_SMU_NV_DISPCLK:
@@ -748,7 +678,10 @@ static enum pp_smu_status pp_nv_set_voltage_by_freq(struct pp_smu *pp,
/* 0: successful or smu.ppt_funcs->display_clock_voltage_request = NULL
* 1: fail
*/
- if (pp_funcs->display_clock_voltage_request(pp_handle, &clock_req))
+ ret = amdgpu_dpm_display_clock_voltage_request(adev, &clock_req);
+ if (ret == -EOPNOTSUPP)
+ return PP_SMU_RESULT_UNSUPPORTED;
+ else if (ret)
return PP_SMU_RESULT_FAIL;
return PP_SMU_RESULT_OK;
@@ -759,16 +692,16 @@ static enum pp_smu_status pp_nv_get_maximum_sustainable_clocks(
{
const struct dc_context *ctx = pp->dm;
struct amdgpu_device *adev = ctx->driver_context;
- void *pp_handle = adev->powerplay.pp_handle;
- const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
+ int ret = 0;
- if (!pp_funcs || !pp_funcs->get_max_sustainable_clocks_by_dc)
+ ret = amdgpu_dpm_get_max_sustainable_clocks_by_dc(adev,
+ max_clocks);
+ if (ret == -EOPNOTSUPP)
return PP_SMU_RESULT_UNSUPPORTED;
+ else if (ret)
+ return PP_SMU_RESULT_FAIL;
- if (!pp_funcs->get_max_sustainable_clocks_by_dc(pp_handle, max_clocks))
- return PP_SMU_RESULT_OK;
-
- return PP_SMU_RESULT_FAIL;
+ return PP_SMU_RESULT_OK;
}
static enum pp_smu_status pp_nv_get_uclk_dpm_states(struct pp_smu *pp,
@@ -776,18 +709,17 @@ static enum pp_smu_status pp_nv_get_uclk_dpm_states(struct pp_smu *pp,
{
const struct dc_context *ctx = pp->dm;
struct amdgpu_device *adev = ctx->driver_context;
- void *pp_handle = adev->powerplay.pp_handle;
- const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
+ int ret = 0;
- if (!pp_funcs || !pp_funcs->get_uclk_dpm_states)
+ ret = amdgpu_dpm_get_uclk_dpm_states(adev,
+ clock_values_in_khz,
+ num_states);
+ if (ret == -EOPNOTSUPP)
return PP_SMU_RESULT_UNSUPPORTED;
+ else if (ret)
+ return PP_SMU_RESULT_FAIL;
- if (!pp_funcs->get_uclk_dpm_states(pp_handle,
- clock_values_in_khz,
- num_states))
- return PP_SMU_RESULT_OK;
-
- return PP_SMU_RESULT_FAIL;
+ return PP_SMU_RESULT_OK;
}
static enum pp_smu_status pp_rn_get_dpm_clock_table(
@@ -795,16 +727,15 @@ static enum pp_smu_status pp_rn_get_dpm_clock_table(
{
const struct dc_context *ctx = pp->dm;
struct amdgpu_device *adev = ctx->driver_context;
- void *pp_handle = adev->powerplay.pp_handle;
- const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
+ int ret = 0;
- if (!pp_funcs || !pp_funcs->get_dpm_clock_table)
+ ret = amdgpu_dpm_get_dpm_clock_table(adev, clock_table);
+ if (ret == -EOPNOTSUPP)
return PP_SMU_RESULT_UNSUPPORTED;
+ else if (ret)
+ return PP_SMU_RESULT_FAIL;
- if (!pp_funcs->get_dpm_clock_table(pp_handle, clock_table))
- return PP_SMU_RESULT_OK;
-
- return PP_SMU_RESULT_FAIL;
+ return PP_SMU_RESULT_OK;
}
static enum pp_smu_status pp_rn_set_wm_ranges(struct pp_smu *pp,
@@ -812,11 +743,8 @@ static enum pp_smu_status pp_rn_set_wm_ranges(struct pp_smu *pp,
{
const struct dc_context *ctx = pp->dm;
struct amdgpu_device *adev = ctx->driver_context;
- void *pp_handle = adev->powerplay.pp_handle;
- const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
- if (pp_funcs && pp_funcs->set_watermarks_for_clocks_ranges)
- pp_funcs->set_watermarks_for_clocks_ranges(pp_handle, ranges);
+ amdgpu_dpm_set_watermarks_for_clocks_ranges(adev, ranges);
return PP_SMU_RESULT_OK;
}
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_psr.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_psr.c
index c510638b4f99..0c923a90615c 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_psr.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_psr.c
@@ -28,49 +28,6 @@
#include "dm_helpers.h"
#include "amdgpu_dm.h"
-static bool link_get_psr_caps(struct dc_link *link)
-{
- uint8_t psr_dpcd_data[EDP_PSR_RECEIVER_CAP_SIZE];
- uint8_t edp_rev_dpcd_data;
-
-
-
- if (!dm_helpers_dp_read_dpcd(NULL, link, DP_PSR_SUPPORT,
- psr_dpcd_data, sizeof(psr_dpcd_data)))
- return false;
-
- if (!dm_helpers_dp_read_dpcd(NULL, link, DP_EDP_DPCD_REV,
- &edp_rev_dpcd_data, sizeof(edp_rev_dpcd_data)))
- return false;
-
- link->dpcd_caps.psr_caps.psr_version = psr_dpcd_data[0];
- link->dpcd_caps.psr_caps.edp_revision = edp_rev_dpcd_data;
-
-#ifdef CONFIG_DRM_AMD_DC_DCN
- if (link->dpcd_caps.psr_caps.psr_version > 0x1) {
- uint8_t alpm_dpcd_data;
- uint8_t su_granularity_dpcd_data;
-
- if (!dm_helpers_dp_read_dpcd(NULL, link, DP_RECEIVER_ALPM_CAP,
- &alpm_dpcd_data, sizeof(alpm_dpcd_data)))
- return false;
-
- if (!dm_helpers_dp_read_dpcd(NULL, link, DP_PSR2_SU_Y_GRANULARITY,
- &su_granularity_dpcd_data, sizeof(su_granularity_dpcd_data)))
- return false;
-
- link->dpcd_caps.psr_caps.y_coordinate_required = psr_dpcd_data[1] & DP_PSR2_SU_Y_COORDINATE_REQUIRED;
- link->dpcd_caps.psr_caps.su_granularity_required = psr_dpcd_data[1] & DP_PSR2_SU_GRANULARITY_REQUIRED;
-
- link->dpcd_caps.psr_caps.alpm_cap = alpm_dpcd_data & DP_ALPM_CAP;
- link->dpcd_caps.psr_caps.standby_support = alpm_dpcd_data & (1 << 1);
-
- link->dpcd_caps.psr_caps.su_y_granularity = su_granularity_dpcd_data;
- }
-#endif
- return true;
-}
-
#ifdef CONFIG_DRM_AMD_DC_DCN
static bool link_supports_psrsu(struct dc_link *link)
{
@@ -82,12 +39,12 @@ static bool link_supports_psrsu(struct dc_link *link)
if (dc->ctx->dce_version < DCN_VERSION_3_1)
return false;
- if (!link->dpcd_caps.psr_caps.alpm_cap ||
- !link->dpcd_caps.psr_caps.y_coordinate_required)
+ if (!link->dpcd_caps.alpm_caps.bits.AUX_WAKE_ALPM_CAP ||
+ !link->dpcd_caps.psr_info.psr_dpcd_caps.bits.Y_COORDINATE_REQUIRED)
return false;
- if (link->dpcd_caps.psr_caps.su_granularity_required &&
- !link->dpcd_caps.psr_caps.su_y_granularity)
+ if (link->dpcd_caps.psr_info.psr_dpcd_caps.bits.SU_GRANULARITY_REQUIRED &&
+ !link->dpcd_caps.psr_info.psr2_su_y_granularity_cap)
return false;
return true;
@@ -107,12 +64,7 @@ void amdgpu_dm_set_psr_caps(struct dc_link *link)
if (link->type == dc_connection_none)
return;
- if (!link_get_psr_caps(link)) {
- DRM_ERROR("amdgpu: Failed to read PSR Caps!\n");
- return;
- }
-
- if (link->dpcd_caps.psr_caps.psr_version == 0) {
+ if (link->dpcd_caps.psr_info.psr_version == 0) {
link->psr_settings.psr_version = DC_PSR_VERSION_UNSUPPORTED;
link->psr_settings.psr_feature_enabled = false;
@@ -149,10 +101,8 @@ bool amdgpu_dm_link_setup_psr(struct dc_stream_state *stream)
link = stream->link;
- psr_config.psr_version = link->dpcd_caps.psr_caps.psr_version;
-
- if (psr_config.psr_version > 0) {
- psr_config.psr_exit_link_training_required = 0x1;
+ if (link->psr_settings.psr_version != DC_PSR_VERSION_UNSUPPORTED) {
+ psr_config.psr_version = link->psr_settings.psr_version;
psr_config.psr_frame_capture_indication_req = 0;
psr_config.psr_rfb_setup_time = 0x37;
psr_config.psr_sdp_transmit_line_num_deadline = 0x20;
diff --git a/drivers/gpu/drm/amd/display/dc/Makefile b/drivers/gpu/drm/amd/display/dc/Makefile
index b1f0d6260226..f05ab2bf20c5 100644
--- a/drivers/gpu/drm/amd/display/dc/Makefile
+++ b/drivers/gpu/drm/amd/display/dc/Makefile
@@ -23,12 +23,12 @@
# Makefile for Display Core (dc) component.
#
-DC_LIBS = basics bios calcs clk_mgr dce gpio irq virtual
+DC_LIBS = basics bios dml clk_mgr dce gpio irq link virtual
ifdef CONFIG_DRM_AMD_DC_DCN
DC_LIBS += dcn20
DC_LIBS += dsc
-DC_LIBS += dcn10 dml
+DC_LIBS += dcn10
DC_LIBS += dcn21
DC_LIBS += dcn201
DC_LIBS += dcn30
@@ -36,6 +36,8 @@ DC_LIBS += dcn301
DC_LIBS += dcn302
DC_LIBS += dcn303
DC_LIBS += dcn31
+DC_LIBS += dcn315
+DC_LIBS += dcn316
endif
DC_LIBS += dce120
@@ -58,7 +60,7 @@ AMD_DC = $(addsuffix /Makefile, $(addprefix $(FULL_AMD_DISPLAY_PATH)/dc/,$(DC_LI
include $(AMD_DC)
DISPLAY_CORE = dc.o dc_stat.o dc_link.o dc_resource.o dc_hw_sequencer.o dc_sink.o \
-dc_surface.o dc_link_hwss.o dc_link_dp.o dc_link_ddc.o dc_debug.o dc_stream.o \
+dc_surface.o dc_link_dp.o dc_link_ddc.o dc_debug.o dc_stream.o \
dc_link_enc_cfg.o dc_link_dpia.o dc_link_dpcd.o
ifdef CONFIG_DRM_AMD_DC_DCN
diff --git a/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c b/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c
index 1e385d55e7fb..23a3b640f0ee 100644
--- a/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c
+++ b/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c
@@ -1692,7 +1692,6 @@ static enum bp_result bios_parser_get_encoder_cap_info(
ATOM_ENCODER_CAP_RECORD_HBR3_EN) ? 1 : 0;
info->HDMI_6GB_EN = (record->encodercaps &
ATOM_ENCODER_CAP_RECORD_HDMI6Gbps_EN) ? 1 : 0;
-#if defined(CONFIG_DRM_AMD_DC_DCN)
info->IS_DP2_CAPABLE = (record->encodercaps &
ATOM_ENCODER_CAP_RECORD_DP2) ? 1 : 0;
info->DP_UHBR10_EN = (record->encodercaps &
@@ -1701,7 +1700,6 @@ static enum bp_result bios_parser_get_encoder_cap_info(
ATOM_ENCODER_CAP_RECORD_UHBR13_5_EN) ? 1 : 0;
info->DP_UHBR20_EN = (record->encodercaps &
ATOM_ENCODER_CAP_RECORD_UHBR20_EN) ? 1 : 0;
-#endif
info->DP_IS_USB_C = (record->encodercaps &
ATOM_ENCODER_CAP_RECORD_USB_C_TYPE) ? 1 : 0;
diff --git a/drivers/gpu/drm/amd/display/dc/bios/command_table.c b/drivers/gpu/drm/amd/display/dc/bios/command_table.c
index ad13e4e36d77..0e36cd800fc9 100644
--- a/drivers/gpu/drm/amd/display/dc/bios/command_table.c
+++ b/drivers/gpu/drm/amd/display/dc/bios/command_table.c
@@ -456,7 +456,7 @@ static enum bp_result transmitter_control_v2(
if ((CONNECTOR_ID_DUAL_LINK_DVII == connector_id) ||
(CONNECTOR_ID_DUAL_LINK_DVID == connector_id))
/* on INIT this bit should be set according to the
- * phisycal connector
+ * physical connector
* Bit0: dual link connector flag
* =0 connector is single link connector
* =1 connector is dual link connector
@@ -468,7 +468,7 @@ static enum bp_result transmitter_control_v2(
cpu_to_le16((uint8_t)cntl->connector_obj_id.id);
break;
case TRANSMITTER_CONTROL_SET_VOLTAGE_AND_PREEMPASIS:
- /* votage swing and pre-emphsis */
+ /* voltage swing and pre-emphsis */
params.asMode.ucLaneSel = (uint8_t)cntl->lane_select;
params.asMode.ucLaneSet = (uint8_t)cntl->lane_settings;
break;
@@ -2120,7 +2120,7 @@ static enum bp_result program_clock_v5(
memset(&params, 0, sizeof(params));
if (!bp->cmd_helper->clock_source_id_to_atom(
bp_params->pll_id, &atom_pll_id)) {
- BREAK_TO_DEBUGGER(); /* Invalid Inpute!! */
+ BREAK_TO_DEBUGGER(); /* Invalid Input!! */
return BP_RESULT_BADINPUT;
}
diff --git a/drivers/gpu/drm/amd/display/dc/bios/command_table2.c b/drivers/gpu/drm/amd/display/dc/bios/command_table2.c
index 9afa5eb2e6d3..f52f7ff7ead4 100644
--- a/drivers/gpu/drm/amd/display/dc/bios/command_table2.c
+++ b/drivers/gpu/drm/amd/display/dc/bios/command_table2.c
@@ -338,12 +338,10 @@ static enum bp_result transmitter_control_v1_7(
const struct command_table_helper *cmd = bp->cmd_helper;
struct dmub_dig_transmitter_control_data_v1_7 dig_v1_7 = {0};
-#if defined(CONFIG_DRM_AMD_DC_DCN)
uint8_t hpo_instance = (uint8_t)cntl->hpo_engine_id - ENGINE_ID_HPO_0;
if (dc_is_dp_signal(cntl->signal))
hpo_instance = (uint8_t)cntl->hpo_engine_id - ENGINE_ID_HPO_DP_0;
-#endif
dig_v1_7.phyid = cmd->phy_id_to_atom(cntl->transmitter);
dig_v1_7.action = (uint8_t)cntl->action;
@@ -358,9 +356,7 @@ static enum bp_result transmitter_control_v1_7(
dig_v1_7.hpdsel = cmd->hpd_sel_to_atom(cntl->hpd_sel);
dig_v1_7.digfe_sel = cmd->dig_encoder_sel_to_atom(cntl->engine_id);
dig_v1_7.connobj_id = (uint8_t)cntl->connector_obj_id.id;
-#if defined(CONFIG_DRM_AMD_DC_DCN)
dig_v1_7.HPO_instance = hpo_instance;
-#endif
dig_v1_7.symclk_units.symclk_10khz = cntl->pixel_clock/10;
if (cntl->action == TRANSMITTER_CONTROL_ENABLE ||
diff --git a/drivers/gpu/drm/amd/display/dc/bios/command_table_helper2.c b/drivers/gpu/drm/amd/display/dc/bios/command_table_helper2.c
index eedc553f340e..dd9704ef4ccc 100644
--- a/drivers/gpu/drm/amd/display/dc/bios/command_table_helper2.c
+++ b/drivers/gpu/drm/amd/display/dc/bios/command_table_helper2.c
@@ -76,6 +76,8 @@ bool dal_bios_parser_init_cmd_tbl_helper2(
case DCN_VERSION_3_02:
case DCN_VERSION_3_03:
case DCN_VERSION_3_1:
+ case DCN_VERSION_3_15:
+ case DCN_VERSION_3_16:
*h = dal_cmd_tbl_helper_dce112_get_table2();
return true;
#endif
diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/Makefile b/drivers/gpu/drm/amd/display/dc/clk_mgr/Makefile
index 6bd73e49a6d2..817871917632 100644
--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/Makefile
+++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/Makefile
@@ -153,4 +153,23 @@ CLK_MGR_DCN31 = dcn31_smu.o dcn31_clk_mgr.o
AMD_DAL_CLK_MGR_DCN31 = $(addprefix $(AMDDALPATH)/dc/clk_mgr/dcn31/,$(CLK_MGR_DCN31))
AMD_DISPLAY_FILES += $(AMD_DAL_CLK_MGR_DCN31)
+
+###############################################################################
+# DCN315
+###############################################################################
+CLK_MGR_DCN315 = dcn315_smu.o dcn315_clk_mgr.o
+
+AMD_DAL_CLK_MGR_DCN315 = $(addprefix $(AMDDALPATH)/dc/clk_mgr/dcn315/,$(CLK_MGR_DCN315))
+
+AMD_DISPLAY_FILES += $(AMD_DAL_CLK_MGR_DCN315)
+
+###############################################################################
+# DCN316
+###############################################################################
+CLK_MGR_DCN316 = dcn316_smu.o dcn316_clk_mgr.o
+
+AMD_DAL_CLK_MGR_DCN316 = $(addprefix $(AMDDALPATH)/dc/clk_mgr/dcn316/,$(CLK_MGR_DCN316))
+
+AMD_DISPLAY_FILES += $(AMD_DAL_CLK_MGR_DCN316)
+
endif
diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/clk_mgr.c
index 9200c8ce02ba..772bffda68cc 100644
--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/clk_mgr.c
+++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/clk_mgr.c
@@ -43,6 +43,8 @@
#include "dcn30/dcn30_clk_mgr.h"
#include "dcn301/vg_clk_mgr.h"
#include "dcn31/dcn31_clk_mgr.h"
+#include "dcn315/dcn315_clk_mgr.h"
+#include "dcn316/dcn316_clk_mgr.h"
int clk_mgr_helper_get_active_display_cnt(
@@ -289,6 +291,31 @@ struct clk_mgr *dc_clk_mgr_create(struct dc_context *ctx, struct pp_smu_funcs *p
dcn31_clk_mgr_construct(ctx, clk_mgr, pp_smu, dccg);
return &clk_mgr->base.base;
}
+ break;
+ case AMDGPU_FAMILY_GC_10_3_6: {
+ struct clk_mgr_dcn315 *clk_mgr = kzalloc(sizeof(*clk_mgr), GFP_KERNEL);
+
+ if (clk_mgr == NULL) {
+ BREAK_TO_DEBUGGER();
+ return NULL;
+ }
+
+ dcn315_clk_mgr_construct(ctx, clk_mgr, pp_smu, dccg);
+ return &clk_mgr->base.base;
+ }
+ break;
+ case AMDGPU_FAMILY_GC_10_3_7: {
+ struct clk_mgr_dcn316 *clk_mgr = kzalloc(sizeof(*clk_mgr), GFP_KERNEL);
+
+ if (clk_mgr == NULL) {
+ BREAK_TO_DEBUGGER();
+ return NULL;
+ }
+
+ dcn316_clk_mgr_construct(ctx, clk_mgr, pp_smu, dccg);
+ return &clk_mgr->base.base;
+ }
+ break;
#endif
default:
@@ -322,7 +349,15 @@ void dc_destroy_clk_mgr(struct clk_mgr *clk_mgr_base)
break;
case FAMILY_YELLOW_CARP:
- dcn31_clk_mgr_destroy(clk_mgr);
+ dcn31_clk_mgr_destroy(clk_mgr);
+ break;
+
+ case AMDGPU_FAMILY_GC_10_3_6:
+ dcn315_clk_mgr_destroy(clk_mgr);
+ break;
+
+ case AMDGPU_FAMILY_GC_10_3_7:
+ dcn316_clk_mgr_destroy(clk_mgr);
break;
default:
diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dce100/dce_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dce100/dce_clk_mgr.c
index b210f8e9d592..dfba6138f538 100644
--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dce100/dce_clk_mgr.c
+++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dce100/dce_clk_mgr.c
@@ -374,6 +374,8 @@ void dce_clock_read_ss_info(struct clk_mgr_internal *clk_mgr_dce)
clk_mgr_dce->dprefclk_ss_percentage =
info.spread_spectrum_percentage;
}
+ if (clk_mgr_dce->base.ctx->dc->debug.ignore_dpref_ss)
+ clk_mgr_dce->dprefclk_ss_percentage = 0;
}
}
}
diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn10/rv1_clk_mgr_vbios_smu.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn10/rv1_clk_mgr_vbios_smu.c
index 06bab24d8e27..450eaead4f20 100644
--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn10/rv1_clk_mgr_vbios_smu.c
+++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn10/rv1_clk_mgr_vbios_smu.c
@@ -101,7 +101,8 @@ static uint32_t rv1_smu_wait_for_response(struct clk_mgr_internal *clk_mgr, unsi
return res_val;
}
-int rv1_vbios_smu_send_msg_with_param(struct clk_mgr_internal *clk_mgr, unsigned int msg_id, unsigned int param)
+static int rv1_vbios_smu_send_msg_with_param(struct clk_mgr_internal *clk_mgr,
+ unsigned int msg_id, unsigned int param)
{
uint32_t result;
diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn30/dcn30_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn30/dcn30_clk_mgr.c
index f977f29907df..5ed6a93d1708 100644
--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn30/dcn30_clk_mgr.c
+++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn30/dcn30_clk_mgr.c
@@ -25,30 +25,23 @@
#include "dccg.h"
#include "clk_mgr_internal.h"
-
#include "dcn30_clk_mgr_smu_msg.h"
#include "dcn20/dcn20_clk_mgr.h"
#include "dce100/dce_clk_mgr.h"
+#include "dcn30/dcn30_clk_mgr.h"
#include "reg_helper.h"
#include "core_types.h"
#include "dm_helpers.h"
-
#include "atomfirmware.h"
-
-
#include "sienna_cichlid_ip_offset.h"
#include "dcn/dcn_3_0_0_offset.h"
#include "dcn/dcn_3_0_0_sh_mask.h"
-
#include "nbio/nbio_7_4_offset.h"
-
-#include "dcn/dpcs_3_0_0_offset.h"
-#include "dcn/dpcs_3_0_0_sh_mask.h"
-
+#include "dpcs/dpcs_3_0_0_offset.h"
+#include "dpcs/dpcs_3_0_0_sh_mask.h"
#include "mmhub/mmhub_2_0_0_offset.h"
#include "mmhub/mmhub_2_0_0_sh_mask.h"
-/*we don't have clk folder yet*/
-#include "dcn30/dcn30_clk_mgr.h"
+#include "dcn30_smu11_driver_if.h"
#undef FN
#define FN(reg_name, field_name) \
@@ -83,7 +76,7 @@ static const struct clk_mgr_mask clk_mgr_mask = {
/* Query SMU for all clock states for a particular clock */
-static void dcn3_init_single_clock(struct clk_mgr_internal *clk_mgr, PPCLK_e clk, unsigned int *entry_0, unsigned int *num_levels)
+static void dcn3_init_single_clock(struct clk_mgr_internal *clk_mgr, uint32_t clk, unsigned int *entry_0, unsigned int *num_levels)
{
unsigned int i;
char *entry_i = (char *)entry_0;
@@ -184,6 +177,7 @@ void dcn3_init_clocks(struct clk_mgr *clk_mgr_base)
dcn3_init_single_clock(clk_mgr, PPCLK_DCEFCLK,
&clk_mgr_base->bw_params->clk_table.entries[0].dcfclk_mhz,
&num_levels);
+ dcn30_smu_set_min_deep_sleep_dcef_clk(clk_mgr, 0);
/* DTBCLK */
dcn3_init_single_clock(clk_mgr, PPCLK_DTBCLK,
@@ -473,8 +467,10 @@ static void dcn3_get_memclk_states_from_smu(struct clk_mgr *clk_mgr_base)
clk_mgr_base->bw_params->dc_mode_softmax_memclk = dcn30_smu_get_dc_mode_max_dpm_freq(clk_mgr, PPCLK_UCLK);
/* Refresh bounding box */
+ DC_FP_START();
clk_mgr_base->ctx->dc->res_pool->funcs->update_bw_bounding_box(
clk_mgr->base.ctx->dc, clk_mgr_base->bw_params);
+ DC_FP_END();
}
static bool dcn3_is_smu_present(struct clk_mgr *clk_mgr_base)
diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn30/dcn30_clk_mgr_smu_msg.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn30/dcn30_clk_mgr_smu_msg.c
index 8ecc708bcd9e..bfc960579760 100644
--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn30/dcn30_clk_mgr_smu_msg.c
+++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn30/dcn30_clk_mgr_smu_msg.c
@@ -29,6 +29,7 @@
#include "clk_mgr_internal.h"
#include "reg_helper.h"
#include "dalsmc.h"
+#include "dcn30_smu11_driver_if.h"
#define mmDAL_MSG_REG 0x1628A
#define mmDAL_ARG_REG 0x16273
@@ -197,7 +198,7 @@ void dcn30_smu_transfer_wm_table_dram_2_smu(struct clk_mgr_internal *clk_mgr)
}
/* Returns the actual frequency that was set in MHz, 0 on failure */
-unsigned int dcn30_smu_set_hard_min_by_freq(struct clk_mgr_internal *clk_mgr, PPCLK_e clk, uint16_t freq_mhz)
+unsigned int dcn30_smu_set_hard_min_by_freq(struct clk_mgr_internal *clk_mgr, uint32_t clk, uint16_t freq_mhz)
{
uint32_t response = 0;
@@ -215,7 +216,7 @@ unsigned int dcn30_smu_set_hard_min_by_freq(struct clk_mgr_internal *clk_mgr, PP
}
/* Returns the actual frequency that was set in MHz, 0 on failure */
-unsigned int dcn30_smu_set_hard_max_by_freq(struct clk_mgr_internal *clk_mgr, PPCLK_e clk, uint16_t freq_mhz)
+unsigned int dcn30_smu_set_hard_max_by_freq(struct clk_mgr_internal *clk_mgr, uint32_t clk, uint16_t freq_mhz)
{
uint32_t response = 0;
@@ -246,7 +247,7 @@ unsigned int dcn30_smu_set_hard_max_by_freq(struct clk_mgr_internal *clk_mgr, PP
*
* Returns 0 on failure
*/
-unsigned int dcn30_smu_get_dpm_freq_by_index(struct clk_mgr_internal *clk_mgr, PPCLK_e clk, uint8_t dpm_level)
+unsigned int dcn30_smu_get_dpm_freq_by_index(struct clk_mgr_internal *clk_mgr, uint32_t clk, uint8_t dpm_level)
{
uint32_t response = 0;
@@ -264,7 +265,7 @@ unsigned int dcn30_smu_get_dpm_freq_by_index(struct clk_mgr_internal *clk_mgr, P
}
/* Returns the max DPM frequency in DC mode in MHz, 0 on failure */
-unsigned int dcn30_smu_get_dc_mode_max_dpm_freq(struct clk_mgr_internal *clk_mgr, PPCLK_e clk)
+unsigned int dcn30_smu_get_dc_mode_max_dpm_freq(struct clk_mgr_internal *clk_mgr, uint32_t clk)
{
uint32_t response = 0;
diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn30/dcn30_clk_mgr_smu_msg.h b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn30/dcn30_clk_mgr_smu_msg.h
index dd2640a3ce5d..ca9f5296be94 100644
--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn30/dcn30_clk_mgr_smu_msg.h
+++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn30/dcn30_clk_mgr_smu_msg.h
@@ -28,65 +28,6 @@
#include "core_types.h"
-#define SMU11_DRIVER_IF_VERSION 0x1F
-
-typedef enum {
- PPCLK_GFXCLK = 0,
- PPCLK_SOCCLK,
- PPCLK_UCLK,
- PPCLK_FCLK,
- PPCLK_DCLK_0,
- PPCLK_VCLK_0,
- PPCLK_DCLK_1,
- PPCLK_VCLK_1,
- PPCLK_DCEFCLK,
- PPCLK_DISPCLK,
- PPCLK_PIXCLK,
- PPCLK_PHYCLK,
- PPCLK_DTBCLK,
- PPCLK_COUNT,
-} PPCLK_e;
-
-typedef struct {
- uint16_t MinClock; // This is either DCEFCLK or SOCCLK (in MHz)
- uint16_t MaxClock; // This is either DCEFCLK or SOCCLK (in MHz)
- uint16_t MinUclk;
- uint16_t MaxUclk;
-
- uint8_t WmSetting;
- uint8_t Flags;
- uint8_t Padding[2];
-
-} WatermarkRowGeneric_t;
-
-#define NUM_WM_RANGES 4
-
-typedef enum {
- WM_SOCCLK = 0,
- WM_DCEFCLK,
- WM_COUNT,
-} WM_CLOCK_e;
-
-typedef enum {
- WATERMARKS_CLOCK_RANGE = 0,
- WATERMARKS_DUMMY_PSTATE,
- WATERMARKS_MALL,
- WATERMARKS_COUNT,
-} WATERMARKS_FLAGS_e;
-
-typedef struct {
- // Watermarks
- WatermarkRowGeneric_t WatermarkRow[WM_COUNT][NUM_WM_RANGES];
-} Watermarks_t;
-
-typedef struct {
- Watermarks_t Watermarks;
-
- uint32_t MmHubPadding[8]; // SMU internal use
-} WatermarksExternal_t;
-
-#define TABLE_WATERMARKS 1
-
struct clk_mgr_internal;
bool dcn30_smu_test_message(struct clk_mgr_internal *clk_mgr, uint32_t input);
@@ -97,10 +38,10 @@ void dcn30_smu_set_dram_addr_high(struct clk_mgr_internal *clk_mgr, uint
void dcn30_smu_set_dram_addr_low(struct clk_mgr_internal *clk_mgr, uint32_t addr_low);
void dcn30_smu_transfer_wm_table_smu_2_dram(struct clk_mgr_internal *clk_mgr);
void dcn30_smu_transfer_wm_table_dram_2_smu(struct clk_mgr_internal *clk_mgr);
-unsigned int dcn30_smu_set_hard_min_by_freq(struct clk_mgr_internal *clk_mgr, PPCLK_e clk, uint16_t freq_mhz);
-unsigned int dcn30_smu_set_hard_max_by_freq(struct clk_mgr_internal *clk_mgr, PPCLK_e clk, uint16_t freq_mhz);
-unsigned int dcn30_smu_get_dpm_freq_by_index(struct clk_mgr_internal *clk_mgr, PPCLK_e clk, uint8_t dpm_level);
-unsigned int dcn30_smu_get_dc_mode_max_dpm_freq(struct clk_mgr_internal *clk_mgr, PPCLK_e clk);
+unsigned int dcn30_smu_set_hard_min_by_freq(struct clk_mgr_internal *clk_mgr, uint32_t clk, uint16_t freq_mhz);
+unsigned int dcn30_smu_set_hard_max_by_freq(struct clk_mgr_internal *clk_mgr, uint32_t clk, uint16_t freq_mhz);
+unsigned int dcn30_smu_get_dpm_freq_by_index(struct clk_mgr_internal *clk_mgr, uint32_t clk, uint8_t dpm_level);
+unsigned int dcn30_smu_get_dc_mode_max_dpm_freq(struct clk_mgr_internal *clk_mgr, uint32_t clk);
void dcn30_smu_set_min_deep_sleep_dcef_clk(struct clk_mgr_internal *clk_mgr, uint32_t freq_mhz);
void dcn30_smu_set_num_of_displays(struct clk_mgr_internal *clk_mgr, uint32_t num_displays);
void dcn30_smu_set_display_refresh_from_mall(struct clk_mgr_internal *clk_mgr, bool enable, uint8_t cache_timer_delay, uint8_t cache_timer_scale);
diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn30/dcn30_smu11_driver_if.h b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn30/dcn30_smu11_driver_if.h
new file mode 100644
index 000000000000..8ea8ee57b39f
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn30/dcn30_smu11_driver_if.h
@@ -0,0 +1,74 @@
+// This is a stripped-down version of the smu11_driver_if.h file for the relevant DAL interfaces.
+
+#define SMU11_DRIVER_IF_VERSION 0x40
+
+//Only Clks that have DPM descriptors are listed here
+typedef enum {
+ PPCLK_GFXCLK = 0,
+ PPCLK_SOCCLK,
+ PPCLK_UCLK,
+ PPCLK_FCLK,
+ PPCLK_DCLK_0,
+ PPCLK_VCLK_0,
+ PPCLK_DCLK_1,
+ PPCLK_VCLK_1,
+ PPCLK_DCEFCLK,
+ PPCLK_DISPCLK,
+ PPCLK_PIXCLK,
+ PPCLK_PHYCLK,
+ PPCLK_DTBCLK,
+ PPCLK_COUNT,
+} PPCLK_e;
+
+typedef struct {
+ uint16_t MinClock; // This is either DCEFCLK or SOCCLK (in MHz)
+ uint16_t MaxClock; // This is either DCEFCLK or SOCCLK (in MHz)
+ uint16_t MinUclk;
+ uint16_t MaxUclk;
+
+ uint8_t WmSetting;
+ uint8_t Flags;
+ uint8_t Padding[2];
+
+} WatermarkRowGeneric_t;
+
+#define NUM_WM_RANGES 4
+
+typedef enum {
+ WM_SOCCLK = 0,
+ WM_DCEFCLK,
+ WM_COUNT,
+} WM_CLOCK_e;
+
+typedef enum {
+ WATERMARKS_CLOCK_RANGE = 0,
+ WATERMARKS_DUMMY_PSTATE,
+ WATERMARKS_MALL,
+ WATERMARKS_COUNT,
+} WATERMARKS_FLAGS_e;
+
+typedef struct {
+ // Watermarks
+ WatermarkRowGeneric_t WatermarkRow[WM_COUNT][NUM_WM_RANGES];
+} Watermarks_t;
+
+typedef struct {
+ Watermarks_t Watermarks;
+
+ uint32_t MmHubPadding[8]; // SMU internal use
+} WatermarksExternal_t;
+
+// Table types
+#define TABLE_PPTABLE 0
+#define TABLE_WATERMARKS 1
+#define TABLE_AVFS_PSM_DEBUG 2
+#define TABLE_AVFS_FUSE_OVERRIDE 3
+#define TABLE_PMSTATUSLOG 4
+#define TABLE_SMU_METRICS 5
+#define TABLE_DRIVER_SMU_CONFIG 6
+#define TABLE_ACTIVITY_MONITOR_COEFF 7
+#define TABLE_OVERDRIVE 8
+#define TABLE_I2C_COMMANDS 9
+#define TABLE_PACE 10
+#define TABLE_ECCINFO 11
+#define TABLE_COUNT 12
diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn301/vg_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn301/vg_clk_mgr.c
index 48005def1164..bc4ddc36fe58 100644
--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn301/vg_clk_mgr.c
+++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn301/vg_clk_mgr.c
@@ -570,32 +570,32 @@ static struct wm_table lpddr5_wm_table = {
.wm_inst = WM_A,
.wm_type = WM_TYPE_PSTATE_CHG,
.pstate_latency_us = 11.65333,
- .sr_exit_time_us = 7.95,
- .sr_enter_plus_exit_time_us = 9,
+ .sr_exit_time_us = 13.5,
+ .sr_enter_plus_exit_time_us = 16.5,
.valid = true,
},
{
.wm_inst = WM_B,
.wm_type = WM_TYPE_PSTATE_CHG,
.pstate_latency_us = 11.65333,
- .sr_exit_time_us = 9.82,
- .sr_enter_plus_exit_time_us = 11.196,
+ .sr_exit_time_us = 13.5,
+ .sr_enter_plus_exit_time_us = 16.5,
.valid = true,
},
{
.wm_inst = WM_C,
.wm_type = WM_TYPE_PSTATE_CHG,
.pstate_latency_us = 11.65333,
- .sr_exit_time_us = 9.89,
- .sr_enter_plus_exit_time_us = 11.24,
+ .sr_exit_time_us = 13.5,
+ .sr_enter_plus_exit_time_us = 16.5,
.valid = true,
},
{
.wm_inst = WM_D,
.wm_type = WM_TYPE_PSTATE_CHG,
.pstate_latency_us = 11.65333,
- .sr_exit_time_us = 9.748,
- .sr_enter_plus_exit_time_us = 11.102,
+ .sr_exit_time_us = 13.5,
+ .sr_enter_plus_exit_time_us = 16.5,
.valid = true,
},
}
diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn31/dcn31_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn31/dcn31_clk_mgr.c
index 4162ce40089b..59fdd7f0d609 100644
--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn31/dcn31_clk_mgr.c
+++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn31/dcn31_clk_mgr.c
@@ -139,9 +139,9 @@ void dcn31_update_clocks(struct clk_mgr *clk_mgr_base,
* also if safe to lower is false, we just go in the higher state
*/
if (safe_to_lower) {
- if (new_clocks->zstate_support == DCN_ZSTATE_SUPPORT_ALLOW &&
+ if (new_clocks->zstate_support != DCN_ZSTATE_SUPPORT_DISALLOW &&
new_clocks->zstate_support != clk_mgr_base->clks.zstate_support) {
- dcn31_smu_set_Z9_support(clk_mgr, true);
+ dcn31_smu_set_zstate_support(clk_mgr, new_clocks->zstate_support);
dm_helpers_enable_periodic_detection(clk_mgr_base->ctx, true);
clk_mgr_base->clks.zstate_support = new_clocks->zstate_support;
}
@@ -167,7 +167,7 @@ void dcn31_update_clocks(struct clk_mgr *clk_mgr_base,
} else {
if (new_clocks->zstate_support == DCN_ZSTATE_SUPPORT_DISALLOW &&
new_clocks->zstate_support != clk_mgr_base->clks.zstate_support) {
- dcn31_smu_set_Z9_support(clk_mgr, false);
+ dcn31_smu_set_zstate_support(clk_mgr, DCN_ZSTATE_SUPPORT_DISALLOW);
dm_helpers_enable_periodic_detection(clk_mgr_base->ctx, false);
clk_mgr_base->clks.zstate_support = new_clocks->zstate_support;
}
@@ -329,38 +329,38 @@ static struct clk_bw_params dcn31_bw_params = {
};
-static struct wm_table ddr4_wm_table = {
+static struct wm_table ddr5_wm_table = {
.entries = {
{
.wm_inst = WM_A,
.wm_type = WM_TYPE_PSTATE_CHG,
.pstate_latency_us = 11.72,
- .sr_exit_time_us = 6.09,
- .sr_enter_plus_exit_time_us = 7.14,
+ .sr_exit_time_us = 9,
+ .sr_enter_plus_exit_time_us = 11,
.valid = true,
},
{
.wm_inst = WM_B,
.wm_type = WM_TYPE_PSTATE_CHG,
.pstate_latency_us = 11.72,
- .sr_exit_time_us = 10.12,
- .sr_enter_plus_exit_time_us = 11.48,
+ .sr_exit_time_us = 9,
+ .sr_enter_plus_exit_time_us = 11,
.valid = true,
},
{
.wm_inst = WM_C,
.wm_type = WM_TYPE_PSTATE_CHG,
.pstate_latency_us = 11.72,
- .sr_exit_time_us = 10.12,
- .sr_enter_plus_exit_time_us = 11.48,
+ .sr_exit_time_us = 9,
+ .sr_enter_plus_exit_time_us = 11,
.valid = true,
},
{
.wm_inst = WM_D,
.wm_type = WM_TYPE_PSTATE_CHG,
.pstate_latency_us = 11.72,
- .sr_exit_time_us = 10.12,
- .sr_enter_plus_exit_time_us = 11.48,
+ .sr_exit_time_us = 9,
+ .sr_enter_plus_exit_time_us = 11,
.valid = true,
},
}
@@ -687,7 +687,7 @@ void dcn31_clk_mgr_construct(
if (ctx->dc_bios->integrated_info->memory_type == LpDdr5MemType) {
dcn31_bw_params.wm_table = lpddr5_wm_table;
} else {
- dcn31_bw_params.wm_table = ddr4_wm_table;
+ dcn31_bw_params.wm_table = ddr5_wm_table;
}
/* Saved clocks configured at boot for debug purposes */
dcn31_dump_clk_registers(&clk_mgr->base.base.boot_snapshot, &clk_mgr->base.base, &log_info);
@@ -697,6 +697,8 @@ void dcn31_clk_mgr_construct(
clk_mgr->base.base.dprefclk_khz = 600000;
clk_mgr->base.dccg->ref_dtbclk_khz = 600000;
dce_clock_read_ss_info(&clk_mgr->base);
+ /*if bios enabled SS, driver needs to adjust dtb clock, only enable with correct bios*/
+ //clk_mgr->base.dccg->ref_dtbclk_khz = dce_adjust_dp_ref_freq_for_ss(clk_mgr_internal, clk_mgr->base.base.dprefclk_khz);
clk_mgr->base.base.bw_params = &dcn31_bw_params;
diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn31/dcn31_smu.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn31/dcn31_smu.c
index a1011f3273f3..c5d7d075026f 100644
--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn31/dcn31_smu.c
+++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn31/dcn31_smu.c
@@ -120,7 +120,11 @@ static int dcn31_smu_send_msg_with_param(struct clk_mgr_internal *clk_mgr,
result = dcn31_smu_wait_for_response(clk_mgr, 10, 200000);
if (result == VBIOSSMC_Result_Failed) {
- ASSERT(0);
+ if (msg_id == VBIOSSMC_MSG_TransferTableDram2Smu &&
+ param == TABLE_WATERMARKS)
+ DC_LOG_WARNING("Watermarks table not configured properly by SMU");
+ else
+ ASSERT(0);
REG_WRITE(MP1_SMN_C2PMSG_91, VBIOSSMC_Result_OK);
return -1;
}
@@ -306,23 +310,32 @@ void dcn31_smu_transfer_wm_table_dram_2_smu(struct clk_mgr_internal *clk_mgr)
VBIOSSMC_MSG_TransferTableDram2Smu, TABLE_WATERMARKS);
}
-void dcn31_smu_set_Z9_support(struct clk_mgr_internal *clk_mgr, bool support)
+void dcn31_smu_set_zstate_support(struct clk_mgr_internal *clk_mgr, enum dcn_zstate_support_state support)
{
- //TODO: Work with smu team to define optimization options.
- unsigned int msg_id;
+ unsigned int msg_id, param;
if (!clk_mgr->smu_present)
return;
- if (support)
- msg_id = VBIOSSMC_MSG_AllowZstatesEntry;
+ if (!clk_mgr->base.ctx->dc->debug.enable_z9_disable_interface &&
+ (support == DCN_ZSTATE_SUPPORT_ALLOW_Z10_ONLY))
+ support = DCN_ZSTATE_SUPPORT_DISALLOW;
+
+
+ if (support == DCN_ZSTATE_SUPPORT_ALLOW_Z10_ONLY)
+ param = 1;
else
+ param = 0;
+
+ if (support == DCN_ZSTATE_SUPPORT_DISALLOW)
msg_id = VBIOSSMC_MSG_DisallowZstatesEntry;
+ else
+ msg_id = VBIOSSMC_MSG_AllowZstatesEntry;
dcn31_smu_send_msg_with_param(
clk_mgr,
msg_id,
- 0);
+ param);
}
diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn31/dcn31_smu.h b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn31/dcn31_smu.h
index cd0b7e1e685f..dfa25a76a6d1 100644
--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn31/dcn31_smu.h
+++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn31/dcn31_smu.h
@@ -265,7 +265,7 @@ void dcn31_smu_set_dram_addr_low(struct clk_mgr_internal *clk_mgr, uint32_t addr
void dcn31_smu_transfer_dpm_table_smu_2_dram(struct clk_mgr_internal *clk_mgr);
void dcn31_smu_transfer_wm_table_dram_2_smu(struct clk_mgr_internal *clk_mgr);
-void dcn31_smu_set_Z9_support(struct clk_mgr_internal *clk_mgr, bool support);
+void dcn31_smu_set_zstate_support(struct clk_mgr_internal *clk_mgr, enum dcn_zstate_support_state support);
void dcn31_smu_set_dtbclk(struct clk_mgr_internal *clk_mgr, bool enable);
#endif /* DAL_DC_31_SMU_H_ */
diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn315/dcn315_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn315/dcn315_clk_mgr.c
new file mode 100644
index 000000000000..edda572dc570
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn315/dcn315_clk_mgr.c
@@ -0,0 +1,620 @@
+/*
+ * Copyright 2021 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: AMD
+ *
+ */
+
+
+
+#include "dccg.h"
+#include "clk_mgr_internal.h"
+
+// For dce12_get_dp_ref_freq_khz
+#include "dce100/dce_clk_mgr.h"
+// For dcn20_update_clocks_update_dpp_dto
+#include "dcn20/dcn20_clk_mgr.h"
+#include "dcn31/dcn31_clk_mgr.h"
+#include "dcn315_clk_mgr.h"
+
+#include "core_types.h"
+#include "dcn315_smu.h"
+#include "dm_helpers.h"
+
+#include "dc_dmub_srv.h"
+
+#if defined (CONFIG_DRM_AMD_DC_DP2_0)
+#include "dc_link_dp.h"
+#endif
+
+#define TO_CLK_MGR_DCN315(clk_mgr)\
+ container_of(clk_mgr, struct clk_mgr_dcn315, base)
+
+static int dcn315_get_active_display_cnt_wa(
+ struct dc *dc,
+ struct dc_state *context)
+{
+ int i, display_count;
+ bool tmds_present = false;
+
+ display_count = 0;
+ for (i = 0; i < context->stream_count; i++) {
+ const struct dc_stream_state *stream = context->streams[i];
+
+ if (stream->signal == SIGNAL_TYPE_HDMI_TYPE_A ||
+ stream->signal == SIGNAL_TYPE_DVI_SINGLE_LINK ||
+ stream->signal == SIGNAL_TYPE_DVI_DUAL_LINK)
+ tmds_present = true;
+ }
+
+ for (i = 0; i < dc->link_count; i++) {
+ const struct dc_link *link = dc->links[i];
+
+ /* abusing the fact that the dig and phy are coupled to see if the phy is enabled */
+ if (link->link_enc && link->link_enc->funcs->is_dig_enabled &&
+ link->link_enc->funcs->is_dig_enabled(link->link_enc))
+ display_count++;
+ }
+
+ /* WA for hang on HDMI after display off back back on*/
+ if (display_count == 0 && tmds_present)
+ display_count = 1;
+
+ return display_count;
+}
+
+static void dcn315_disable_otg_wa(struct clk_mgr *clk_mgr_base, bool disable)
+{
+ struct dc *dc = clk_mgr_base->ctx->dc;
+ int i;
+
+ for (i = 0; i < dc->res_pool->pipe_count; ++i) {
+ struct pipe_ctx *pipe = &dc->current_state->res_ctx.pipe_ctx[i];
+
+ if (pipe->top_pipe || pipe->prev_odm_pipe)
+ continue;
+ if (pipe->stream && (pipe->stream->dpms_off || dc_is_virtual_signal(pipe->stream->signal))) {
+ if (disable)
+ pipe->stream_res.tg->funcs->immediate_disable_crtc(pipe->stream_res.tg);
+ else
+ pipe->stream_res.tg->funcs->enable_crtc(pipe->stream_res.tg);
+ }
+ }
+}
+
+static void dcn315_update_clocks(struct clk_mgr *clk_mgr_base,
+ struct dc_state *context,
+ bool safe_to_lower)
+{
+ union dmub_rb_cmd cmd;
+ struct clk_mgr_internal *clk_mgr = TO_CLK_MGR_INTERNAL(clk_mgr_base);
+ struct dc_clocks *new_clocks = &context->bw_ctx.bw.dcn.clk;
+ struct dc *dc = clk_mgr_base->ctx->dc;
+ int display_count;
+ bool update_dppclk = false;
+ bool update_dispclk = false;
+ bool dpp_clock_lowered = false;
+
+ if (dc->work_arounds.skip_clock_update)
+ return;
+
+ clk_mgr_base->clks.zstate_support = new_clocks->zstate_support;
+ /*
+ * if it is safe to lower, but we are already in the lower state, we don't have to do anything
+ * also if safe to lower is false, we just go in the higher state
+ */
+ clk_mgr_base->clks.zstate_support = new_clocks->zstate_support;
+ if (safe_to_lower) {
+ /* check that we're not already in lower */
+ if (clk_mgr_base->clks.pwr_state != DCN_PWR_STATE_LOW_POWER) {
+ display_count = dcn315_get_active_display_cnt_wa(dc, context);
+ /* if we can go lower, go lower */
+ if (display_count == 0) {
+ union display_idle_optimization_u idle_info = { 0 };
+ idle_info.idle_info.df_request_disabled = 1;
+ idle_info.idle_info.phy_ref_clk_off = 1;
+ idle_info.idle_info.s0i2_rdy = 1;
+ dcn315_smu_set_display_idle_optimization(clk_mgr, idle_info.data);
+ /* update power state */
+ clk_mgr_base->clks.pwr_state = DCN_PWR_STATE_LOW_POWER;
+ }
+ }
+ } else {
+ /* check that we're not already in D0 */
+ if (clk_mgr_base->clks.pwr_state != DCN_PWR_STATE_MISSION_MODE) {
+ union display_idle_optimization_u idle_info = { 0 };
+ dcn315_smu_set_display_idle_optimization(clk_mgr, idle_info.data);
+ /* update power state */
+ clk_mgr_base->clks.pwr_state = DCN_PWR_STATE_MISSION_MODE;
+ }
+ }
+
+ if (should_set_clock(safe_to_lower, new_clocks->dcfclk_khz, clk_mgr_base->clks.dcfclk_khz)) {
+ clk_mgr_base->clks.dcfclk_khz = new_clocks->dcfclk_khz;
+ dcn315_smu_set_hard_min_dcfclk(clk_mgr, clk_mgr_base->clks.dcfclk_khz);
+ }
+
+ if (should_set_clock(safe_to_lower,
+ new_clocks->dcfclk_deep_sleep_khz, clk_mgr_base->clks.dcfclk_deep_sleep_khz)) {
+ clk_mgr_base->clks.dcfclk_deep_sleep_khz = new_clocks->dcfclk_deep_sleep_khz;
+ dcn315_smu_set_min_deep_sleep_dcfclk(clk_mgr, clk_mgr_base->clks.dcfclk_deep_sleep_khz);
+ }
+
+ // workaround: Limit dppclk to 100Mhz to avoid lower eDP panel switch to plus 4K monitor underflow.
+ if (!IS_DIAG_DC(dc->ctx->dce_environment)) {
+ if (new_clocks->dppclk_khz < 100000)
+ new_clocks->dppclk_khz = 100000;
+ if (new_clocks->dispclk_khz < 100000)
+ new_clocks->dispclk_khz = 100000;
+ }
+
+ if (should_set_clock(safe_to_lower, new_clocks->dppclk_khz, clk_mgr->base.clks.dppclk_khz)) {
+ if (clk_mgr->base.clks.dppclk_khz > new_clocks->dppclk_khz)
+ dpp_clock_lowered = true;
+ clk_mgr_base->clks.dppclk_khz = new_clocks->dppclk_khz;
+ update_dppclk = true;
+ }
+
+ if (should_set_clock(safe_to_lower, new_clocks->dispclk_khz, clk_mgr_base->clks.dispclk_khz)) {
+ dcn315_disable_otg_wa(clk_mgr_base, true);
+
+ clk_mgr_base->clks.dispclk_khz = new_clocks->dispclk_khz;
+ dcn315_smu_set_dispclk(clk_mgr, clk_mgr_base->clks.dispclk_khz);
+ dcn315_disable_otg_wa(clk_mgr_base, false);
+
+ update_dispclk = true;
+ }
+
+ if (dpp_clock_lowered) {
+ // increase per DPP DTO before lowering global dppclk
+ dcn20_update_clocks_update_dpp_dto(clk_mgr, context, safe_to_lower);
+ dcn315_smu_set_dppclk(clk_mgr, clk_mgr_base->clks.dppclk_khz);
+ } else {
+ // increase global DPPCLK before lowering per DPP DTO
+ if (update_dppclk || update_dispclk)
+ dcn315_smu_set_dppclk(clk_mgr, clk_mgr_base->clks.dppclk_khz);
+ // always update dtos unless clock is lowered and not safe to lower
+ if (new_clocks->dppclk_khz >= dc->current_state->bw_ctx.bw.dcn.clk.dppclk_khz)
+ dcn20_update_clocks_update_dpp_dto(clk_mgr, context, safe_to_lower);
+ }
+
+ // notify DMCUB of latest clocks
+ memset(&cmd, 0, sizeof(cmd));
+ cmd.notify_clocks.header.type = DMUB_CMD__CLK_MGR;
+ cmd.notify_clocks.header.sub_type = DMUB_CMD__CLK_MGR_NOTIFY_CLOCKS;
+ cmd.notify_clocks.clocks.dcfclk_khz = clk_mgr_base->clks.dcfclk_khz;
+ cmd.notify_clocks.clocks.dcfclk_deep_sleep_khz =
+ clk_mgr_base->clks.dcfclk_deep_sleep_khz;
+ cmd.notify_clocks.clocks.dispclk_khz = clk_mgr_base->clks.dispclk_khz;
+ cmd.notify_clocks.clocks.dppclk_khz = clk_mgr_base->clks.dppclk_khz;
+
+ dc_dmub_srv_cmd_queue(dc->ctx->dmub_srv, &cmd);
+ dc_dmub_srv_cmd_execute(dc->ctx->dmub_srv);
+ dc_dmub_srv_wait_idle(dc->ctx->dmub_srv);
+}
+
+static void dcn315_dump_clk_registers(struct clk_state_registers_and_bypass *regs_and_bypass,
+ struct clk_mgr *clk_mgr_base, struct clk_log_info *log_info)
+{
+ return;
+}
+
+static struct clk_bw_params dcn315_bw_params = {
+ .vram_type = Ddr4MemType,
+ .num_channels = 1,
+ .clk_table = {
+ .num_entries = 5,
+ },
+
+};
+
+static struct wm_table ddr5_wm_table = {
+ .entries = {
+ {
+ .wm_inst = WM_A,
+ .wm_type = WM_TYPE_PSTATE_CHG,
+ .pstate_latency_us = 64.0,
+ .sr_exit_time_us = 11.5,
+ .sr_enter_plus_exit_time_us = 14.5,
+ .valid = true,
+ },
+ {
+ .wm_inst = WM_B,
+ .wm_type = WM_TYPE_PSTATE_CHG,
+ .pstate_latency_us = 64.0,
+ .sr_exit_time_us = 11.5,
+ .sr_enter_plus_exit_time_us = 14.5,
+ .valid = true,
+ },
+ {
+ .wm_inst = WM_C,
+ .wm_type = WM_TYPE_PSTATE_CHG,
+ .pstate_latency_us = 64.0,
+ .sr_exit_time_us = 11.5,
+ .sr_enter_plus_exit_time_us = 14.5,
+ .valid = true,
+ },
+ {
+ .wm_inst = WM_D,
+ .wm_type = WM_TYPE_PSTATE_CHG,
+ .pstate_latency_us = 64.0,
+ .sr_exit_time_us = 11.5,
+ .sr_enter_plus_exit_time_us = 14.5,
+ .valid = true,
+ },
+ }
+};
+
+static struct wm_table lpddr5_wm_table = {
+ .entries = {
+ {
+ .wm_inst = WM_A,
+ .wm_type = WM_TYPE_PSTATE_CHG,
+ .pstate_latency_us = 11.65333,
+ .sr_exit_time_us = 11.5,
+ .sr_enter_plus_exit_time_us = 14.5,
+ .valid = true,
+ },
+ {
+ .wm_inst = WM_B,
+ .wm_type = WM_TYPE_PSTATE_CHG,
+ .pstate_latency_us = 11.65333,
+ .sr_exit_time_us = 11.5,
+ .sr_enter_plus_exit_time_us = 14.5,
+ .valid = true,
+ },
+ {
+ .wm_inst = WM_C,
+ .wm_type = WM_TYPE_PSTATE_CHG,
+ .pstate_latency_us = 11.65333,
+ .sr_exit_time_us = 11.5,
+ .sr_enter_plus_exit_time_us = 14.5,
+ .valid = true,
+ },
+ {
+ .wm_inst = WM_D,
+ .wm_type = WM_TYPE_PSTATE_CHG,
+ .pstate_latency_us = 11.65333,
+ .sr_exit_time_us = 11.5,
+ .sr_enter_plus_exit_time_us = 14.5,
+ .valid = true,
+ },
+ }
+};
+
+static DpmClocks_315_t dummy_clocks;
+
+static struct dcn315_watermarks dummy_wms = { 0 };
+
+static void dcn315_build_watermark_ranges(struct clk_bw_params *bw_params, struct dcn315_watermarks *table)
+{
+ int i, num_valid_sets;
+
+ num_valid_sets = 0;
+
+ for (i = 0; i < WM_SET_COUNT; i++) {
+ /* skip empty entries, the smu array has no holes*/
+ if (!bw_params->wm_table.entries[i].valid)
+ continue;
+
+ table->WatermarkRow[WM_DCFCLK][num_valid_sets].WmSetting = bw_params->wm_table.entries[i].wm_inst;
+ table->WatermarkRow[WM_DCFCLK][num_valid_sets].WmType = bw_params->wm_table.entries[i].wm_type;
+ /* We will not select WM based on fclk, so leave it as unconstrained */
+ table->WatermarkRow[WM_DCFCLK][num_valid_sets].MinClock = 0;
+ table->WatermarkRow[WM_DCFCLK][num_valid_sets].MaxClock = 0xFFFF;
+
+ if (table->WatermarkRow[WM_DCFCLK][num_valid_sets].WmType == WM_TYPE_PSTATE_CHG) {
+ if (i == 0)
+ table->WatermarkRow[WM_DCFCLK][num_valid_sets].MinMclk = 0;
+ else {
+ /* add 1 to make it non-overlapping with next lvl */
+ table->WatermarkRow[WM_DCFCLK][num_valid_sets].MinMclk =
+ bw_params->clk_table.entries[i - 1].dcfclk_mhz + 1;
+ }
+ table->WatermarkRow[WM_DCFCLK][num_valid_sets].MaxMclk =
+ bw_params->clk_table.entries[i].dcfclk_mhz;
+
+ } else {
+ /* unconstrained for memory retraining */
+ table->WatermarkRow[WM_DCFCLK][num_valid_sets].MinClock = 0;
+ table->WatermarkRow[WM_DCFCLK][num_valid_sets].MaxClock = 0xFFFF;
+
+ /* Modify previous watermark range to cover up to max */
+ table->WatermarkRow[WM_DCFCLK][num_valid_sets - 1].MaxClock = 0xFFFF;
+ }
+ num_valid_sets++;
+ }
+
+ ASSERT(num_valid_sets != 0); /* Must have at least one set of valid watermarks */
+
+ /* modify the min and max to make sure we cover the whole range*/
+ table->WatermarkRow[WM_DCFCLK][0].MinMclk = 0;
+ table->WatermarkRow[WM_DCFCLK][0].MinClock = 0;
+ table->WatermarkRow[WM_DCFCLK][num_valid_sets - 1].MaxMclk = 0xFFFF;
+ table->WatermarkRow[WM_DCFCLK][num_valid_sets - 1].MaxClock = 0xFFFF;
+
+ /* This is for writeback only, does not matter currently as no writeback support*/
+ table->WatermarkRow[WM_SOCCLK][0].WmSetting = WM_A;
+ table->WatermarkRow[WM_SOCCLK][0].MinClock = 0;
+ table->WatermarkRow[WM_SOCCLK][0].MaxClock = 0xFFFF;
+ table->WatermarkRow[WM_SOCCLK][0].MinMclk = 0;
+ table->WatermarkRow[WM_SOCCLK][0].MaxMclk = 0xFFFF;
+}
+
+static void dcn315_notify_wm_ranges(struct clk_mgr *clk_mgr_base)
+{
+ struct clk_mgr_internal *clk_mgr = TO_CLK_MGR_INTERNAL(clk_mgr_base);
+ struct clk_mgr_dcn315 *clk_mgr_dcn315 = TO_CLK_MGR_DCN315(clk_mgr);
+ struct dcn315_watermarks *table = clk_mgr_dcn315->smu_wm_set.wm_set;
+
+ if (!clk_mgr->smu_ver)
+ return;
+
+ if (!table || clk_mgr_dcn315->smu_wm_set.mc_address.quad_part == 0)
+ return;
+
+ memset(table, 0, sizeof(*table));
+
+ dcn315_build_watermark_ranges(clk_mgr_base->bw_params, table);
+
+ dcn315_smu_set_dram_addr_high(clk_mgr,
+ clk_mgr_dcn315->smu_wm_set.mc_address.high_part);
+ dcn315_smu_set_dram_addr_low(clk_mgr,
+ clk_mgr_dcn315->smu_wm_set.mc_address.low_part);
+ dcn315_smu_transfer_wm_table_dram_2_smu(clk_mgr);
+}
+
+static void dcn315_get_dpm_table_from_smu(struct clk_mgr_internal *clk_mgr,
+ struct dcn315_smu_dpm_clks *smu_dpm_clks)
+{
+ DpmClocks_315_t *table = smu_dpm_clks->dpm_clks;
+
+ if (!clk_mgr->smu_ver)
+ return;
+
+ if (!table || smu_dpm_clks->mc_address.quad_part == 0)
+ return;
+
+ memset(table, 0, sizeof(*table));
+
+ dcn315_smu_set_dram_addr_high(clk_mgr,
+ smu_dpm_clks->mc_address.high_part);
+ dcn315_smu_set_dram_addr_low(clk_mgr,
+ smu_dpm_clks->mc_address.low_part);
+ dcn315_smu_transfer_dpm_table_smu_2_dram(clk_mgr);
+}
+
+static uint32_t find_max_clk_value(const uint32_t clocks[], uint32_t num_clocks)
+{
+ uint32_t max = 0;
+ int i;
+
+ for (i = 0; i < num_clocks; ++i) {
+ if (clocks[i] > max)
+ max = clocks[i];
+ }
+
+ return max;
+}
+
+static unsigned int find_clk_for_voltage(
+ const DpmClocks_315_t *clock_table,
+ const uint32_t clocks[],
+ unsigned int voltage)
+{
+ int i;
+
+ for (i = 0; i < NUM_SOC_VOLTAGE_LEVELS; i++) {
+ if (clock_table->SocVoltage[i] == voltage)
+ return clocks[i];
+ }
+
+ ASSERT(0);
+ return 0;
+}
+
+static void dcn315_clk_mgr_helper_populate_bw_params(
+ struct clk_mgr_internal *clk_mgr,
+ struct integrated_info *bios_info,
+ const DpmClocks_315_t *clock_table)
+{
+ int i, j;
+ struct clk_bw_params *bw_params = clk_mgr->base.bw_params;
+ uint32_t max_dispclk = 0, max_dppclk = 0;
+
+ j = -1;
+
+ ASSERT(NUM_DF_PSTATE_LEVELS <= MAX_NUM_DPM_LVL);
+
+ /* Find lowest DPM, FCLK is filled in reverse order*/
+
+ for (i = NUM_DF_PSTATE_LEVELS - 1; i >= 0; i--) {
+ if (clock_table->DfPstateTable[i].FClk != 0) {
+ j = i;
+ break;
+ }
+ }
+
+ if (j == -1) {
+ /* clock table is all 0s, just use our own hardcode */
+ ASSERT(0);
+ return;
+ }
+
+ bw_params->clk_table.num_entries = j + 1;
+
+ /* dispclk and dppclk can be max at any voltage, same number of levels for both */
+ if (clock_table->NumDispClkLevelsEnabled <= NUM_DISPCLK_DPM_LEVELS &&
+ clock_table->NumDispClkLevelsEnabled <= NUM_DPPCLK_DPM_LEVELS) {
+ max_dispclk = find_max_clk_value(clock_table->DispClocks, clock_table->NumDispClkLevelsEnabled);
+ max_dppclk = find_max_clk_value(clock_table->DppClocks, clock_table->NumDispClkLevelsEnabled);
+ } else {
+ ASSERT(0);
+ }
+
+ for (i = 0; i < bw_params->clk_table.num_entries; i++, j--) {
+ int temp;
+
+ bw_params->clk_table.entries[i].fclk_mhz = clock_table->DfPstateTable[j].FClk;
+ bw_params->clk_table.entries[i].memclk_mhz = clock_table->DfPstateTable[j].MemClk;
+ bw_params->clk_table.entries[i].voltage = clock_table->DfPstateTable[j].Voltage;
+ bw_params->clk_table.entries[i].wck_ratio = 1;
+ temp = find_clk_for_voltage(clock_table, clock_table->DcfClocks, clock_table->DfPstateTable[j].Voltage);
+ if (temp)
+ bw_params->clk_table.entries[i].dcfclk_mhz = temp;
+ temp = find_clk_for_voltage(clock_table, clock_table->SocClocks, clock_table->DfPstateTable[j].Voltage);
+ if (temp)
+ bw_params->clk_table.entries[i].socclk_mhz = temp;
+ bw_params->clk_table.entries[i].dispclk_mhz = max_dispclk;
+ bw_params->clk_table.entries[i].dppclk_mhz = max_dppclk;
+ }
+
+ bw_params->vram_type = bios_info->memory_type;
+ bw_params->num_channels = bios_info->ma_channel_number;
+
+ for (i = 0; i < WM_SET_COUNT; i++) {
+ bw_params->wm_table.entries[i].wm_inst = i;
+
+ if (i >= bw_params->clk_table.num_entries) {
+ bw_params->wm_table.entries[i].valid = false;
+ continue;
+ }
+
+ bw_params->wm_table.entries[i].wm_type = WM_TYPE_PSTATE_CHG;
+ bw_params->wm_table.entries[i].valid = true;
+ }
+}
+
+static void dcn315_enable_pme_wa(struct clk_mgr *clk_mgr_base)
+{
+ struct clk_mgr_internal *clk_mgr = TO_CLK_MGR_INTERNAL(clk_mgr_base);
+
+ dcn315_smu_enable_pme_wa(clk_mgr);
+}
+
+static struct clk_mgr_funcs dcn315_funcs = {
+ .get_dp_ref_clk_frequency = dce12_get_dp_ref_freq_khz,
+ .update_clocks = dcn315_update_clocks,
+ .init_clocks = dcn31_init_clocks,
+ .enable_pme_wa = dcn315_enable_pme_wa,
+ .are_clock_states_equal = dcn31_are_clock_states_equal,
+ .notify_wm_ranges = dcn315_notify_wm_ranges
+};
+extern struct clk_mgr_funcs dcn3_fpga_funcs;
+
+void dcn315_clk_mgr_construct(
+ struct dc_context *ctx,
+ struct clk_mgr_dcn315 *clk_mgr,
+ struct pp_smu_funcs *pp_smu,
+ struct dccg *dccg)
+{
+ struct dcn315_smu_dpm_clks smu_dpm_clks = { 0 };
+
+ clk_mgr->base.base.ctx = ctx;
+ clk_mgr->base.base.funcs = &dcn315_funcs;
+
+ clk_mgr->base.pp_smu = pp_smu;
+
+ clk_mgr->base.dccg = dccg;
+ clk_mgr->base.dfs_bypass_disp_clk = 0;
+
+ clk_mgr->base.dprefclk_ss_percentage = 0;
+ clk_mgr->base.dprefclk_ss_divider = 1000;
+ clk_mgr->base.ss_on_dprefclk = false;
+ clk_mgr->base.dfs_ref_freq_khz = 48000;
+
+ clk_mgr->smu_wm_set.wm_set = (struct dcn315_watermarks *)dm_helpers_allocate_gpu_mem(
+ clk_mgr->base.base.ctx,
+ DC_MEM_ALLOC_TYPE_FRAME_BUFFER,
+ sizeof(struct dcn315_watermarks),
+ &clk_mgr->smu_wm_set.mc_address.quad_part);
+
+ if (!clk_mgr->smu_wm_set.wm_set) {
+ clk_mgr->smu_wm_set.wm_set = &dummy_wms;
+ clk_mgr->smu_wm_set.mc_address.quad_part = 0;
+ }
+ ASSERT(clk_mgr->smu_wm_set.wm_set);
+
+ smu_dpm_clks.dpm_clks = (DpmClocks_315_t *)dm_helpers_allocate_gpu_mem(
+ clk_mgr->base.base.ctx,
+ DC_MEM_ALLOC_TYPE_FRAME_BUFFER,
+ sizeof(DpmClocks_315_t),
+ &smu_dpm_clks.mc_address.quad_part);
+
+ if (smu_dpm_clks.dpm_clks == NULL) {
+ smu_dpm_clks.dpm_clks = &dummy_clocks;
+ smu_dpm_clks.mc_address.quad_part = 0;
+ }
+
+ ASSERT(smu_dpm_clks.dpm_clks);
+
+ if (IS_FPGA_MAXIMUS_DC(ctx->dce_environment)) {
+ clk_mgr->base.base.funcs = &dcn3_fpga_funcs;
+ } else {
+ struct clk_log_info log_info = {0};
+
+ clk_mgr->base.smu_ver = dcn315_smu_get_smu_version(&clk_mgr->base);
+
+ if (clk_mgr->base.smu_ver > 0)
+ clk_mgr->base.smu_present = true;
+
+ if (ctx->dc_bios->integrated_info->memory_type == LpDdr5MemType) {
+ dcn315_bw_params.wm_table = lpddr5_wm_table;
+ } else {
+ dcn315_bw_params.wm_table = ddr5_wm_table;
+ }
+ /* Saved clocks configured at boot for debug purposes */
+ dcn315_dump_clk_registers(&clk_mgr->base.base.boot_snapshot, &clk_mgr->base.base, &log_info);
+
+ }
+
+ clk_mgr->base.base.dprefclk_khz = 600000;
+ clk_mgr->base.base.dprefclk_khz = dcn315_smu_get_dpref_clk(&clk_mgr->base);
+ clk_mgr->base.dccg->ref_dtbclk_khz = clk_mgr->base.base.dprefclk_khz;
+ dce_clock_read_ss_info(&clk_mgr->base);
+ clk_mgr->base.dccg->ref_dtbclk_khz = dce_adjust_dp_ref_freq_for_ss(&clk_mgr->base, clk_mgr->base.base.dprefclk_khz);
+
+ clk_mgr->base.base.bw_params = &dcn315_bw_params;
+
+ if (clk_mgr->base.base.ctx->dc->debug.pstate_enabled) {
+ dcn315_get_dpm_table_from_smu(&clk_mgr->base, &smu_dpm_clks);
+
+ if (ctx->dc_bios && ctx->dc_bios->integrated_info) {
+ dcn315_clk_mgr_helper_populate_bw_params(
+ &clk_mgr->base,
+ ctx->dc_bios->integrated_info,
+ smu_dpm_clks.dpm_clks);
+ }
+ }
+
+ if (smu_dpm_clks.dpm_clks && smu_dpm_clks.mc_address.quad_part != 0)
+ dm_helpers_free_gpu_mem(clk_mgr->base.base.ctx, DC_MEM_ALLOC_TYPE_FRAME_BUFFER,
+ smu_dpm_clks.dpm_clks);
+}
+
+void dcn315_clk_mgr_destroy(struct clk_mgr_internal *clk_mgr_int)
+{
+ struct clk_mgr_dcn315 *clk_mgr = TO_CLK_MGR_DCN315(clk_mgr_int);
+
+ if (clk_mgr->smu_wm_set.wm_set && clk_mgr->smu_wm_set.mc_address.quad_part != 0)
+ dm_helpers_free_gpu_mem(clk_mgr_int->base.ctx, DC_MEM_ALLOC_TYPE_FRAME_BUFFER,
+ clk_mgr->smu_wm_set.wm_set);
+}
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_hdp.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn315/dcn315_clk_mgr.h
index a766e1aad2b9..ac36ddf5dd1a 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_hdp.c
+++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn315/dcn315_clk_mgr.h
@@ -19,50 +19,31 @@
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
+ * Authors: AMD
+ *
*/
-#include "amdgpu.h"
-#include "amdgpu_ras.h"
+#ifndef __DCN315_CLK_MGR_H__
+#define __DCN315_CLK_MGR_H__
+#include "clk_mgr_internal.h"
+
+struct dcn315_watermarks;
-int amdgpu_hdp_ras_late_init(struct amdgpu_device *adev)
-{
- int r;
- struct ras_ih_if ih_info = {
- .cb = NULL,
- };
- struct ras_fs_if fs_info = {
- .sysfs_name = "hdp_err_count",
- };
+struct dcn315_smu_watermark_set {
+ struct dcn315_watermarks *wm_set;
+ union large_integer mc_address;
+};
- if (!adev->hdp.ras_if) {
- adev->hdp.ras_if = kmalloc(sizeof(struct ras_common_if), GFP_KERNEL);
- if (!adev->hdp.ras_if)
- return -ENOMEM;
- adev->hdp.ras_if->block = AMDGPU_RAS_BLOCK__HDP;
- adev->hdp.ras_if->type = AMDGPU_RAS_ERROR__MULTI_UNCORRECTABLE;
- adev->hdp.ras_if->sub_block_index = 0;
- }
- ih_info.head = fs_info.head = *adev->hdp.ras_if;
- r = amdgpu_ras_late_init(adev, adev->hdp.ras_if,
- &fs_info, &ih_info);
- if (r || !amdgpu_ras_is_supported(adev, adev->hdp.ras_if->block)) {
- kfree(adev->hdp.ras_if);
- adev->hdp.ras_if = NULL;
- }
+struct clk_mgr_dcn315 {
+ struct clk_mgr_internal base;
+ struct dcn315_smu_watermark_set smu_wm_set;
+};
- return r;
-}
+void dcn315_clk_mgr_construct(struct dc_context *ctx,
+ struct clk_mgr_dcn315 *clk_mgr,
+ struct pp_smu_funcs *pp_smu,
+ struct dccg *dccg);
-void amdgpu_hdp_ras_fini(struct amdgpu_device *adev)
-{
- if (amdgpu_ras_is_supported(adev, AMDGPU_RAS_BLOCK__HDP) &&
- adev->hdp.ras_if) {
- struct ras_common_if *ras_if = adev->hdp.ras_if;
- struct ras_ih_if ih_info = {
- .cb = NULL,
- };
+void dcn315_clk_mgr_destroy(struct clk_mgr_internal *clk_mgr_int);
- amdgpu_ras_late_fini(adev, ras_if, &ih_info);
- kfree(ras_if);
- }
-}
+#endif //__DCN315_CLK_MGR_H__
diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn315/dcn315_smu.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn315/dcn315_smu.c
new file mode 100644
index 000000000000..880ffea2afc6
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn315/dcn315_smu.c
@@ -0,0 +1,338 @@
+/*
+ * Copyright 2021 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: AMD
+ *
+ */
+
+#include "core_types.h"
+#include "clk_mgr_internal.h"
+#include "reg_helper.h"
+#include "dm_helpers.h"
+#include "dcn315_smu.h"
+#include "mp/mp_13_0_5_offset.h"
+
+#define MAX_INSTANCE 6
+#define MAX_SEGMENT 6
+
+struct IP_BASE_INSTANCE
+{
+ unsigned int segment[MAX_SEGMENT];
+};
+
+struct IP_BASE
+{
+ struct IP_BASE_INSTANCE instance[MAX_INSTANCE];
+};
+
+static const struct IP_BASE MP0_BASE = { { { { 0x00016000, 0x00DC0000, 0x00E00000, 0x00E40000, 0x0243FC00, 0 } },
+ { { 0, 0, 0, 0, 0, 0 } },
+ { { 0, 0, 0, 0, 0, 0 } },
+ { { 0, 0, 0, 0, 0, 0 } },
+ { { 0, 0, 0, 0, 0, 0 } },
+ { { 0, 0, 0, 0, 0, 0 } } } };
+static const struct IP_BASE NBIO_BASE = { { { { 0x00000000, 0x00000014, 0x00000D20, 0x00010400, 0x0241B000, 0x04040000 } },
+ { { 0, 0, 0, 0, 0, 0 } },
+ { { 0, 0, 0, 0, 0, 0 } },
+ { { 0, 0, 0, 0, 0, 0 } },
+ { { 0, 0, 0, 0, 0, 0 } },
+ { { 0, 0, 0, 0, 0, 0 } } } };
+
+#define regBIF_BX_PF2_RSMU_INDEX 0x0000
+#define regBIF_BX_PF2_RSMU_INDEX_BASE_IDX 1
+#define regBIF_BX_PF2_RSMU_DATA 0x0001
+#define regBIF_BX_PF2_RSMU_DATA_BASE_IDX 1
+
+#define REG(reg_name) \
+ (MP0_BASE.instance[0].segment[reg ## reg_name ## _BASE_IDX] + reg ## reg_name)
+
+#define FN(reg_name, field) \
+ FD(reg_name##__##field)
+
+#define REG_NBIO(reg_name) \
+ (NBIO_BASE.instance[0].segment[regBIF_BX_PF2_ ## reg_name ## _BASE_IDX] + regBIF_BX_PF2_ ## reg_name)
+
+#define mmMP1_C2PMSG_3 0x3B1050C
+
+#define VBIOSSMC_MSG_TestMessage 0x01 ///< To check if PMFW is alive and responding. Requirement specified by PMFW team
+#define VBIOSSMC_MSG_GetPmfwVersion 0x02 ///< Get PMFW version
+#define VBIOSSMC_MSG_Spare0 0x03 ///< Spare0
+#define VBIOSSMC_MSG_SetDispclkFreq 0x04 ///< Set display clock frequency in MHZ
+#define VBIOSSMC_MSG_Spare1 0x05 ///< Spare1
+#define VBIOSSMC_MSG_SetDppclkFreq 0x06 ///< Set DPP clock frequency in MHZ
+#define VBIOSSMC_MSG_SetHardMinDcfclkByFreq 0x07 ///< Set DCF clock frequency hard min in MHZ
+#define VBIOSSMC_MSG_SetMinDeepSleepDcfclk 0x08 ///< Set DCF clock minimum frequency in deep sleep in MHZ
+#define VBIOSSMC_MSG_SetPhyclkVoltageByFreq 0x09 ///< Set display phy clock frequency in MHZ in case VMIN does not support phy frequency
+#define VBIOSSMC_MSG_GetFclkFrequency 0x0A ///< Get FCLK frequency, return frequemcy in MHZ
+#define VBIOSSMC_MSG_SetDisplayCount 0x0B ///< Inform PMFW of number of display connected
+#define VBIOSSMC_MSG_EnableTmdp48MHzRefclkPwrDown 0x0C ///< To ask PMFW turn off TMDP 48MHz refclk during display off to save power
+#define VBIOSSMC_MSG_UpdatePmeRestore 0x0D ///< To ask PMFW to write into Azalia for PME wake up event
+#define VBIOSSMC_MSG_SetVbiosDramAddrHigh 0x0E ///< Set DRAM address high 32 bits for WM table transfer
+#define VBIOSSMC_MSG_SetVbiosDramAddrLow 0x0F ///< Set DRAM address low 32 bits for WM table transfer
+#define VBIOSSMC_MSG_TransferTableSmu2Dram 0x10 ///< Transfer table from PMFW SRAM to system DRAM
+#define VBIOSSMC_MSG_TransferTableDram2Smu 0x11 ///< Transfer table from system DRAM to PMFW
+#define VBIOSSMC_MSG_SetDisplayIdleOptimizations 0x12 ///< Set Idle state optimization for display off
+#define VBIOSSMC_MSG_GetDprefclkFreq 0x13 ///< Get DPREF clock frequency. Return in MHZ
+#define VBIOSSMC_Message_Count 0x14 ///< Total number of VBIS and DAL messages
+
+#define VBIOSSMC_Status_BUSY 0x0
+#define VBIOSSMC_Result_OK 0x01 ///< Message Response OK
+#define VBIOSSMC_Result_Failed 0xFF ///< Message Response Failed
+#define VBIOSSMC_Result_UnknownCmd 0xFE ///< Message Response Unknown Command
+#define VBIOSSMC_Result_CmdRejectedPrereq 0xFD ///< Message Response Command Failed Prerequisite
+#define VBIOSSMC_Result_CmdRejectedBusy 0xFC ///< Message Response Command Rejected due to PMFW is busy. Sender should retry sending this message
+
+/*
+ * Function to be used instead of REG_WAIT macro because the wait ends when
+ * the register is NOT EQUAL to zero, and because the translation in msg_if.h
+ * won't work with REG_WAIT.
+ */
+static uint32_t dcn315_smu_wait_for_response(struct clk_mgr_internal *clk_mgr, unsigned int delay_us, unsigned int max_retries)
+{
+ uint32_t res_val = VBIOSSMC_Status_BUSY;
+
+ do {
+ res_val = REG_READ(MP1_SMN_C2PMSG_38);
+ if (res_val != VBIOSSMC_Status_BUSY)
+ break;
+
+ if (delay_us >= 1000)
+ msleep(delay_us/1000);
+ else if (delay_us > 0)
+ udelay(delay_us);
+ } while (max_retries--);
+
+ return res_val;
+}
+
+static int dcn315_smu_send_msg_with_param(
+ struct clk_mgr_internal *clk_mgr,
+ unsigned int msg_id, unsigned int param)
+{
+ uint32_t result;
+
+ result = dcn315_smu_wait_for_response(clk_mgr, 10, 200000);
+ ASSERT(result == VBIOSSMC_Result_OK);
+
+ if (result == VBIOSSMC_Status_BUSY) {
+ return -1;
+ }
+
+ /* First clear response register */
+ REG_WRITE(MP1_SMN_C2PMSG_38, VBIOSSMC_Status_BUSY);
+
+ /* Set the parameter register for the SMU message, unit is Mhz */
+ REG_WRITE(MP1_SMN_C2PMSG_37, param);
+
+ /* Trigger the message transaction by writing the message ID */
+ generic_write_indirect_reg(CTX,
+ REG_NBIO(RSMU_INDEX), REG_NBIO(RSMU_DATA),
+ mmMP1_C2PMSG_3, msg_id);
+
+ result = dcn315_smu_wait_for_response(clk_mgr, 10, 200000);
+
+ if (result == VBIOSSMC_Status_BUSY) {
+ ASSERT(0);
+ dm_helpers_smu_timeout(CTX, msg_id, param, 10 * 200000);
+ }
+
+ return REG_READ(MP1_SMN_C2PMSG_37);
+}
+
+int dcn315_smu_get_smu_version(struct clk_mgr_internal *clk_mgr)
+{
+ return dcn315_smu_send_msg_with_param(
+ clk_mgr,
+ VBIOSSMC_MSG_GetPmfwVersion,
+ 0);
+}
+
+
+int dcn315_smu_set_dispclk(struct clk_mgr_internal *clk_mgr, int requested_dispclk_khz)
+{
+ int actual_dispclk_set_mhz = -1;
+
+ if (!clk_mgr->smu_present)
+ return requested_dispclk_khz;
+
+ /* Unit of SMU msg parameter is Mhz */
+ actual_dispclk_set_mhz = dcn315_smu_send_msg_with_param(
+ clk_mgr,
+ VBIOSSMC_MSG_SetDispclkFreq,
+ khz_to_mhz_ceil(requested_dispclk_khz));
+
+ return actual_dispclk_set_mhz * 1000;
+}
+
+int dcn315_smu_set_hard_min_dcfclk(struct clk_mgr_internal *clk_mgr, int requested_dcfclk_khz)
+{
+ int actual_dcfclk_set_mhz = -1;
+
+ if (!clk_mgr->base.ctx->dc->debug.pstate_enabled)
+ return -1;
+
+ if (!clk_mgr->smu_present)
+ return requested_dcfclk_khz;
+
+ actual_dcfclk_set_mhz = dcn315_smu_send_msg_with_param(
+ clk_mgr,
+ VBIOSSMC_MSG_SetHardMinDcfclkByFreq,
+ khz_to_mhz_ceil(requested_dcfclk_khz));
+
+ return actual_dcfclk_set_mhz * 1000;
+}
+
+int dcn315_smu_set_min_deep_sleep_dcfclk(struct clk_mgr_internal *clk_mgr, int requested_min_ds_dcfclk_khz)
+{
+ int actual_min_ds_dcfclk_mhz = -1;
+
+ if (!clk_mgr->base.ctx->dc->debug.pstate_enabled)
+ return -1;
+
+ if (!clk_mgr->smu_present)
+ return requested_min_ds_dcfclk_khz;
+
+ actual_min_ds_dcfclk_mhz = dcn315_smu_send_msg_with_param(
+ clk_mgr,
+ VBIOSSMC_MSG_SetMinDeepSleepDcfclk,
+ khz_to_mhz_ceil(requested_min_ds_dcfclk_khz));
+
+ return actual_min_ds_dcfclk_mhz * 1000;
+}
+
+int dcn315_smu_set_dppclk(struct clk_mgr_internal *clk_mgr, int requested_dpp_khz)
+{
+ int actual_dppclk_set_mhz = -1;
+
+ if (!clk_mgr->smu_present)
+ return requested_dpp_khz;
+
+ actual_dppclk_set_mhz = dcn315_smu_send_msg_with_param(
+ clk_mgr,
+ VBIOSSMC_MSG_SetDppclkFreq,
+ khz_to_mhz_ceil(requested_dpp_khz));
+
+ return actual_dppclk_set_mhz * 1000;
+}
+
+void dcn315_smu_set_display_idle_optimization(struct clk_mgr_internal *clk_mgr, uint32_t idle_info)
+{
+ if (!clk_mgr->base.ctx->dc->debug.pstate_enabled)
+ return;
+
+ if (!clk_mgr->smu_present)
+ return;
+
+ //TODO: Work with smu team to define optimization options.
+ dcn315_smu_send_msg_with_param(
+ clk_mgr,
+ VBIOSSMC_MSG_SetDisplayIdleOptimizations,
+ idle_info);
+}
+
+void dcn315_smu_enable_phy_refclk_pwrdwn(struct clk_mgr_internal *clk_mgr, bool enable)
+{
+ union display_idle_optimization_u idle_info = { 0 };
+
+ if (!clk_mgr->smu_present)
+ return;
+
+ if (enable) {
+ idle_info.idle_info.df_request_disabled = 1;
+ idle_info.idle_info.phy_ref_clk_off = 1;
+ }
+
+ dcn315_smu_send_msg_with_param(
+ clk_mgr,
+ VBIOSSMC_MSG_SetDisplayIdleOptimizations,
+ idle_info.data);
+}
+
+void dcn315_smu_enable_pme_wa(struct clk_mgr_internal *clk_mgr)
+{
+ if (!clk_mgr->smu_present)
+ return;
+
+ dcn315_smu_send_msg_with_param(
+ clk_mgr,
+ VBIOSSMC_MSG_UpdatePmeRestore,
+ 0);
+}
+void dcn315_smu_set_dram_addr_high(struct clk_mgr_internal *clk_mgr, uint32_t addr_high)
+{
+ if (!clk_mgr->smu_present)
+ return;
+
+ dcn315_smu_send_msg_with_param(clk_mgr,
+ VBIOSSMC_MSG_SetVbiosDramAddrHigh, addr_high);
+}
+
+void dcn315_smu_set_dram_addr_low(struct clk_mgr_internal *clk_mgr, uint32_t addr_low)
+{
+ if (!clk_mgr->smu_present)
+ return;
+
+ dcn315_smu_send_msg_with_param(clk_mgr,
+ VBIOSSMC_MSG_SetVbiosDramAddrLow, addr_low);
+}
+
+void dcn315_smu_transfer_dpm_table_smu_2_dram(struct clk_mgr_internal *clk_mgr)
+{
+ if (!clk_mgr->smu_present)
+ return;
+
+ dcn315_smu_send_msg_with_param(clk_mgr,
+ VBIOSSMC_MSG_TransferTableSmu2Dram, TABLE_DPMCLOCKS);
+}
+
+void dcn315_smu_transfer_wm_table_dram_2_smu(struct clk_mgr_internal *clk_mgr)
+{
+ if (!clk_mgr->smu_present)
+ return;
+
+ dcn315_smu_send_msg_with_param(clk_mgr,
+ VBIOSSMC_MSG_TransferTableDram2Smu, TABLE_WATERMARKS);
+}
+
+int dcn315_smu_get_dpref_clk(struct clk_mgr_internal *clk_mgr)
+{
+ int dprefclk_get_mhz = -1;
+ if (clk_mgr->smu_present) {
+ dprefclk_get_mhz = dcn315_smu_send_msg_with_param(
+ clk_mgr,
+ VBIOSSMC_MSG_GetDprefclkFreq,
+ 0);
+ }
+ return (dprefclk_get_mhz * 1000);
+}
+
+int dcn315_smu_get_smu_fclk(struct clk_mgr_internal *clk_mgr)
+{
+ int fclk_get_mhz = -1;
+
+ if (clk_mgr->smu_present) {
+ fclk_get_mhz = dcn315_smu_send_msg_with_param(
+ clk_mgr,
+ VBIOSSMC_MSG_GetFclkFrequency,
+ 0);
+ }
+ return (fclk_get_mhz * 1000);
+}
diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn315/dcn315_smu.h b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn315/dcn315_smu.h
new file mode 100644
index 000000000000..66fa42f8dd18
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn315/dcn315_smu.h
@@ -0,0 +1,128 @@
+/*
+ * Copyright 2021 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: AMD
+ *
+ */
+
+#ifndef DAL_DC_315_SMU_H_
+#define DAL_DC_315_SMU_H_
+#include "os_types.h"
+
+#define PMFW_DRIVER_IF_VERSION 4
+
+#define NUM_DCFCLK_DPM_LEVELS 4
+#define NUM_DISPCLK_DPM_LEVELS 4
+#define NUM_DPPCLK_DPM_LEVELS 4
+#define NUM_SOCCLK_DPM_LEVELS 4
+#define NUM_VCN_DPM_LEVELS 4
+#define NUM_SOC_VOLTAGE_LEVELS 4
+#define NUM_DF_PSTATE_LEVELS 4
+
+typedef struct {
+ uint16_t MinClock; // This is either DCFCLK or SOCCLK (in MHz)
+ uint16_t MaxClock; // This is either DCFCLK or SOCCLK (in MHz)
+ uint16_t MinMclk;
+ uint16_t MaxMclk;
+ uint8_t WmSetting;
+ uint8_t WmType; // Used for normal pstate change or memory retraining
+ uint8_t Padding[2];
+} WatermarkRowGeneric_t;
+
+#define NUM_WM_RANGES 4
+#define WM_PSTATE_CHG 0
+#define WM_RETRAINING 1
+
+typedef enum {
+ WM_SOCCLK = 0,
+ WM_DCFCLK,
+ WM_COUNT,
+} WM_CLOCK_e;
+
+typedef struct {
+ uint32_t FClk;
+ uint32_t MemClk;
+ uint32_t Voltage;
+} DfPstateTable_t;
+
+//Freq in MHz
+//Voltage in milli volts with 2 fractional bits
+typedef struct {
+ uint32_t DcfClocks[NUM_DCFCLK_DPM_LEVELS];
+ uint32_t DispClocks[NUM_DISPCLK_DPM_LEVELS];
+ uint32_t DppClocks[NUM_DPPCLK_DPM_LEVELS];
+ uint32_t SocClocks[NUM_SOCCLK_DPM_LEVELS];
+ uint32_t VClocks[NUM_VCN_DPM_LEVELS];
+ uint32_t DClocks[NUM_VCN_DPM_LEVELS];
+ uint32_t SocVoltage[NUM_SOC_VOLTAGE_LEVELS];
+ DfPstateTable_t DfPstateTable[NUM_DF_PSTATE_LEVELS];
+ uint8_t NumDcfClkLevelsEnabled;
+ uint8_t NumDispClkLevelsEnabled; //Applies to both Dispclk and Dppclk
+ uint8_t NumSocClkLevelsEnabled;
+ uint8_t VcnClkLevelsEnabled; //Applies to both Vclk and Dclk
+ uint8_t NumDfPstatesEnabled;
+ uint8_t spare[3];
+ uint32_t MinGfxClk;
+ uint32_t MaxGfxClk;
+} DpmClocks_315_t;
+
+struct dcn315_watermarks {
+ // Watermarks
+ WatermarkRowGeneric_t WatermarkRow[WM_COUNT][NUM_WM_RANGES];
+ uint32_t MmHubPadding[7]; // SMU internal use
+};
+
+struct dcn315_smu_dpm_clks {
+ DpmClocks_315_t *dpm_clks;
+ union large_integer mc_address;
+};
+
+#define TABLE_WATERMARKS 1 // Called by DAL through VBIOS
+#define TABLE_DPMCLOCKS 4 // Called by Driver and VBIOS
+
+struct display_idle_optimization {
+ unsigned int df_request_disabled : 1;
+ unsigned int phy_ref_clk_off : 1;
+ unsigned int s0i2_rdy : 1;
+ unsigned int reserved : 29;
+};
+
+union display_idle_optimization_u {
+ struct display_idle_optimization idle_info;
+ uint32_t data;
+};
+
+int dcn315_smu_get_smu_version(struct clk_mgr_internal *clk_mgr);
+int dcn315_smu_set_dispclk(struct clk_mgr_internal *clk_mgr, int requested_dispclk_khz);
+int dcn315_smu_set_hard_min_dcfclk(struct clk_mgr_internal *clk_mgr, int requested_dcfclk_khz);
+int dcn315_smu_set_min_deep_sleep_dcfclk(struct clk_mgr_internal *clk_mgr, int requested_min_ds_dcfclk_khz);
+int dcn315_smu_set_dppclk(struct clk_mgr_internal *clk_mgr, int requested_dpp_khz);
+void dcn315_smu_set_display_idle_optimization(struct clk_mgr_internal *clk_mgr, uint32_t idle_info);
+void dcn315_smu_enable_phy_refclk_pwrdwn(struct clk_mgr_internal *clk_mgr, bool enable);
+void dcn315_smu_set_dram_addr_high(struct clk_mgr_internal *clk_mgr, uint32_t addr_high);
+void dcn315_smu_set_dram_addr_low(struct clk_mgr_internal *clk_mgr, uint32_t addr_low);
+void dcn315_smu_transfer_dpm_table_smu_2_dram(struct clk_mgr_internal *clk_mgr);
+void dcn315_smu_transfer_wm_table_dram_2_smu(struct clk_mgr_internal *clk_mgr);
+void dcn315_smu_request_voltage_via_phyclk(struct clk_mgr_internal *clk_mgr, int requested_phyclk_khz);
+void dcn315_smu_enable_pme_wa(struct clk_mgr_internal *clk_mgr);
+int dcn315_smu_get_dpref_clk(struct clk_mgr_internal *clk_mgr);
+int dcn315_smu_get_smu_fclk(struct clk_mgr_internal *clk_mgr);
+#endif /* DAL_DC_315_SMU_H_ */
diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn316/dcn316_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn316/dcn316_clk_mgr.c
new file mode 100644
index 000000000000..702d00ce7da4
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn316/dcn316_clk_mgr.c
@@ -0,0 +1,717 @@
+/*
+ * Copyright 2021 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: AMD
+ *
+ */
+
+
+
+#include "dccg.h"
+#include "clk_mgr_internal.h"
+
+// For dce12_get_dp_ref_freq_khz
+#include "dce100/dce_clk_mgr.h"
+// For dcn20_update_clocks_update_dpp_dto
+#include "dcn20/dcn20_clk_mgr.h"
+#include "dcn31/dcn31_clk_mgr.h"
+#include "dcn316_clk_mgr.h"
+#include "reg_helper.h"
+#include "core_types.h"
+#include "dcn316_smu.h"
+#include "dm_helpers.h"
+#include "dc_dmub_srv.h"
+#include "dc_link_dp.h"
+
+// DCN316 this is CLK1 instance
+#define MAX_INSTANCE 7
+#define MAX_SEGMENT 6
+
+struct IP_BASE_INSTANCE
+{
+ unsigned int segment[MAX_SEGMENT];
+};
+
+struct IP_BASE
+{
+ struct IP_BASE_INSTANCE instance[MAX_INSTANCE];
+};
+
+static const struct IP_BASE CLK_BASE = { { { { 0x00016C00, 0x02401800, 0, 0, 0, 0 } },
+ { { 0x00016E00, 0x02401C00, 0, 0, 0, 0 } },
+ { { 0x00017000, 0x02402000, 0, 0, 0, 0 } },
+ { { 0x00017200, 0x02402400, 0, 0, 0, 0 } },
+ { { 0x0001B000, 0x0242D800, 0, 0, 0, 0 } },
+ { { 0x0001B200, 0x0242DC00, 0, 0, 0, 0 } },
+ { { 0x0001B400, 0x0242E000, 0, 0, 0, 0 } } } };
+
+#define regCLK1_CLK_PLL_REQ 0x0237
+#define regCLK1_CLK_PLL_REQ_BASE_IDX 0
+
+#define CLK1_CLK_PLL_REQ__FbMult_int__SHIFT 0x0
+#define CLK1_CLK_PLL_REQ__PllSpineDiv__SHIFT 0xc
+#define CLK1_CLK_PLL_REQ__FbMult_frac__SHIFT 0x10
+#define CLK1_CLK_PLL_REQ__FbMult_int_MASK 0x000001FFL
+#define CLK1_CLK_PLL_REQ__PllSpineDiv_MASK 0x0000F000L
+#define CLK1_CLK_PLL_REQ__FbMult_frac_MASK 0xFFFF0000L
+
+#define REG(reg_name) \
+ (CLK_BASE.instance[0].segment[reg ## reg_name ## _BASE_IDX] + reg ## reg_name)
+
+#define TO_CLK_MGR_DCN316(clk_mgr)\
+ container_of(clk_mgr, struct clk_mgr_dcn316, base)
+
+static int dcn316_get_active_display_cnt_wa(
+ struct dc *dc,
+ struct dc_state *context)
+{
+ int i, display_count;
+ bool tmds_present = false;
+
+ display_count = 0;
+ for (i = 0; i < context->stream_count; i++) {
+ const struct dc_stream_state *stream = context->streams[i];
+
+ if (stream->signal == SIGNAL_TYPE_HDMI_TYPE_A ||
+ stream->signal == SIGNAL_TYPE_DVI_SINGLE_LINK ||
+ stream->signal == SIGNAL_TYPE_DVI_DUAL_LINK)
+ tmds_present = true;
+ }
+
+ for (i = 0; i < dc->link_count; i++) {
+ const struct dc_link *link = dc->links[i];
+
+ /* abusing the fact that the dig and phy are coupled to see if the phy is enabled */
+ if (link->link_enc && link->link_enc->funcs->is_dig_enabled &&
+ link->link_enc->funcs->is_dig_enabled(link->link_enc))
+ display_count++;
+ }
+
+ /* WA for hang on HDMI after display off back back on*/
+ if (display_count == 0 && tmds_present)
+ display_count = 1;
+
+ return display_count;
+}
+
+static void dcn316_disable_otg_wa(struct clk_mgr *clk_mgr_base, bool disable)
+{
+ struct dc *dc = clk_mgr_base->ctx->dc;
+ int i;
+
+ for (i = 0; i < dc->res_pool->pipe_count; ++i) {
+ struct pipe_ctx *pipe = &dc->current_state->res_ctx.pipe_ctx[i];
+
+ if (pipe->top_pipe || pipe->prev_odm_pipe)
+ continue;
+ if (pipe->stream && (pipe->stream->dpms_off || dc_is_virtual_signal(pipe->stream->signal))) {
+ if (disable)
+ pipe->stream_res.tg->funcs->immediate_disable_crtc(pipe->stream_res.tg);
+ else
+ pipe->stream_res.tg->funcs->enable_crtc(pipe->stream_res.tg);
+ }
+ }
+}
+
+static void dcn316_enable_pme_wa(struct clk_mgr *clk_mgr_base)
+{
+ struct clk_mgr_internal *clk_mgr = TO_CLK_MGR_INTERNAL(clk_mgr_base);
+
+ dcn316_smu_enable_pme_wa(clk_mgr);
+}
+
+static void dcn316_update_clocks(struct clk_mgr *clk_mgr_base,
+ struct dc_state *context,
+ bool safe_to_lower)
+{
+ union dmub_rb_cmd cmd;
+ struct clk_mgr_internal *clk_mgr = TO_CLK_MGR_INTERNAL(clk_mgr_base);
+ struct dc_clocks *new_clocks = &context->bw_ctx.bw.dcn.clk;
+ struct dc *dc = clk_mgr_base->ctx->dc;
+ int display_count;
+ bool update_dppclk = false;
+ bool update_dispclk = false;
+ bool dpp_clock_lowered = false;
+
+ if (dc->work_arounds.skip_clock_update)
+ return;
+
+ /*
+ * if it is safe to lower, but we are already in the lower state, we don't have to do anything
+ * also if safe to lower is false, we just go in the higher state
+ */
+ clk_mgr_base->clks.zstate_support = new_clocks->zstate_support;
+ if (safe_to_lower) {
+ if (clk_mgr_base->clks.dtbclk_en && !new_clocks->dtbclk_en) {
+ dcn316_smu_set_dtbclk(clk_mgr, false);
+ clk_mgr_base->clks.dtbclk_en = new_clocks->dtbclk_en;
+ }
+ /* check that we're not already in lower */
+ if (clk_mgr_base->clks.pwr_state != DCN_PWR_STATE_LOW_POWER) {
+ display_count = dcn316_get_active_display_cnt_wa(dc, context);
+ /* if we can go lower, go lower */
+ if (display_count == 0) {
+ union display_idle_optimization_u idle_info = { 0 };
+ idle_info.idle_info.df_request_disabled = 1;
+ idle_info.idle_info.phy_ref_clk_off = 1;
+ idle_info.idle_info.s0i2_rdy = 1;
+ dcn316_smu_set_display_idle_optimization(clk_mgr, idle_info.data);
+ /* update power state */
+ clk_mgr_base->clks.pwr_state = DCN_PWR_STATE_LOW_POWER;
+ }
+ }
+ } else {
+ if (!clk_mgr_base->clks.dtbclk_en && new_clocks->dtbclk_en) {
+ dcn316_smu_set_dtbclk(clk_mgr, true);
+ clk_mgr_base->clks.dtbclk_en = new_clocks->dtbclk_en;
+ }
+
+ /* check that we're not already in D0 */
+ if (clk_mgr_base->clks.pwr_state != DCN_PWR_STATE_MISSION_MODE) {
+ union display_idle_optimization_u idle_info = { 0 };
+ dcn316_smu_set_display_idle_optimization(clk_mgr, idle_info.data);
+ /* update power state */
+ clk_mgr_base->clks.pwr_state = DCN_PWR_STATE_MISSION_MODE;
+ }
+ }
+
+ if (should_set_clock(safe_to_lower, new_clocks->dcfclk_khz, clk_mgr_base->clks.dcfclk_khz)) {
+ clk_mgr_base->clks.dcfclk_khz = new_clocks->dcfclk_khz;
+ dcn316_smu_set_hard_min_dcfclk(clk_mgr, clk_mgr_base->clks.dcfclk_khz);
+ }
+
+ if (should_set_clock(safe_to_lower,
+ new_clocks->dcfclk_deep_sleep_khz, clk_mgr_base->clks.dcfclk_deep_sleep_khz)) {
+ clk_mgr_base->clks.dcfclk_deep_sleep_khz = new_clocks->dcfclk_deep_sleep_khz;
+ dcn316_smu_set_min_deep_sleep_dcfclk(clk_mgr, clk_mgr_base->clks.dcfclk_deep_sleep_khz);
+ }
+
+ // workaround: Limit dppclk to 100Mhz to avoid lower eDP panel switch to plus 4K monitor underflow.
+ if (!IS_DIAG_DC(dc->ctx->dce_environment)) {
+ if (new_clocks->dppclk_khz < 100000)
+ new_clocks->dppclk_khz = 100000;
+ if (new_clocks->dispclk_khz < 100000)
+ new_clocks->dispclk_khz = 100000;
+ }
+
+ if (should_set_clock(safe_to_lower, new_clocks->dppclk_khz, clk_mgr->base.clks.dppclk_khz)) {
+ if (clk_mgr->base.clks.dppclk_khz > new_clocks->dppclk_khz)
+ dpp_clock_lowered = true;
+ clk_mgr_base->clks.dppclk_khz = new_clocks->dppclk_khz;
+ update_dppclk = true;
+ }
+
+ if (should_set_clock(safe_to_lower, new_clocks->dispclk_khz, clk_mgr_base->clks.dispclk_khz)) {
+ dcn316_disable_otg_wa(clk_mgr_base, true);
+
+ clk_mgr_base->clks.dispclk_khz = new_clocks->dispclk_khz;
+ dcn316_smu_set_dispclk(clk_mgr, clk_mgr_base->clks.dispclk_khz);
+ dcn316_disable_otg_wa(clk_mgr_base, false);
+
+ update_dispclk = true;
+ }
+
+ if (dpp_clock_lowered) {
+ // increase per DPP DTO before lowering global dppclk
+ dcn20_update_clocks_update_dpp_dto(clk_mgr, context, safe_to_lower);
+ dcn316_smu_set_dppclk(clk_mgr, clk_mgr_base->clks.dppclk_khz);
+ } else {
+ // increase global DPPCLK before lowering per DPP DTO
+ if (update_dppclk || update_dispclk)
+ dcn316_smu_set_dppclk(clk_mgr, clk_mgr_base->clks.dppclk_khz);
+ // always update dtos unless clock is lowered and not safe to lower
+ if (new_clocks->dppclk_khz >= dc->current_state->bw_ctx.bw.dcn.clk.dppclk_khz)
+ dcn20_update_clocks_update_dpp_dto(clk_mgr, context, safe_to_lower);
+ }
+
+ // notify DMCUB of latest clocks
+ memset(&cmd, 0, sizeof(cmd));
+ cmd.notify_clocks.header.type = DMUB_CMD__CLK_MGR;
+ cmd.notify_clocks.header.sub_type = DMUB_CMD__CLK_MGR_NOTIFY_CLOCKS;
+ cmd.notify_clocks.clocks.dcfclk_khz = clk_mgr_base->clks.dcfclk_khz;
+ cmd.notify_clocks.clocks.dcfclk_deep_sleep_khz =
+ clk_mgr_base->clks.dcfclk_deep_sleep_khz;
+ cmd.notify_clocks.clocks.dispclk_khz = clk_mgr_base->clks.dispclk_khz;
+ cmd.notify_clocks.clocks.dppclk_khz = clk_mgr_base->clks.dppclk_khz;
+
+ dc_dmub_srv_cmd_queue(dc->ctx->dmub_srv, &cmd);
+ dc_dmub_srv_cmd_execute(dc->ctx->dmub_srv);
+ dc_dmub_srv_wait_idle(dc->ctx->dmub_srv);
+}
+
+static void dcn316_dump_clk_registers(struct clk_state_registers_and_bypass *regs_and_bypass,
+ struct clk_mgr *clk_mgr_base, struct clk_log_info *log_info)
+{
+ return;
+}
+
+static struct clk_bw_params dcn316_bw_params = {
+ .vram_type = Ddr4MemType,
+ .num_channels = 1,
+ .clk_table = {
+ .num_entries = 5,
+ },
+
+};
+
+static struct wm_table ddr4_wm_table = {
+ .entries = {
+ {
+ .wm_inst = WM_A,
+ .wm_type = WM_TYPE_PSTATE_CHG,
+ .pstate_latency_us = 11.72,
+ .sr_exit_time_us = 6.09,
+ .sr_enter_plus_exit_time_us = 7.14,
+ .valid = true,
+ },
+ {
+ .wm_inst = WM_B,
+ .wm_type = WM_TYPE_PSTATE_CHG,
+ .pstate_latency_us = 11.72,
+ .sr_exit_time_us = 10.12,
+ .sr_enter_plus_exit_time_us = 11.48,
+ .valid = true,
+ },
+ {
+ .wm_inst = WM_C,
+ .wm_type = WM_TYPE_PSTATE_CHG,
+ .pstate_latency_us = 11.72,
+ .sr_exit_time_us = 10.12,
+ .sr_enter_plus_exit_time_us = 11.48,
+ .valid = true,
+ },
+ {
+ .wm_inst = WM_D,
+ .wm_type = WM_TYPE_PSTATE_CHG,
+ .pstate_latency_us = 11.72,
+ .sr_exit_time_us = 10.12,
+ .sr_enter_plus_exit_time_us = 11.48,
+ .valid = true,
+ },
+ }
+};
+
+static struct wm_table lpddr5_wm_table = {
+ .entries = {
+ {
+ .wm_inst = WM_A,
+ .wm_type = WM_TYPE_PSTATE_CHG,
+ .pstate_latency_us = 11.65333,
+ .sr_exit_time_us = 11.5,
+ .sr_enter_plus_exit_time_us = 14.5,
+ .valid = true,
+ },
+ {
+ .wm_inst = WM_B,
+ .wm_type = WM_TYPE_PSTATE_CHG,
+ .pstate_latency_us = 11.65333,
+ .sr_exit_time_us = 11.5,
+ .sr_enter_plus_exit_time_us = 14.5,
+ .valid = true,
+ },
+ {
+ .wm_inst = WM_C,
+ .wm_type = WM_TYPE_PSTATE_CHG,
+ .pstate_latency_us = 11.65333,
+ .sr_exit_time_us = 11.5,
+ .sr_enter_plus_exit_time_us = 14.5,
+ .valid = true,
+ },
+ {
+ .wm_inst = WM_D,
+ .wm_type = WM_TYPE_PSTATE_CHG,
+ .pstate_latency_us = 11.65333,
+ .sr_exit_time_us = 11.5,
+ .sr_enter_plus_exit_time_us = 14.5,
+ .valid = true,
+ },
+ }
+};
+
+static DpmClocks_316_t dummy_clocks;
+
+static struct dcn316_watermarks dummy_wms = { 0 };
+
+static void dcn316_build_watermark_ranges(struct clk_bw_params *bw_params, struct dcn316_watermarks *table)
+{
+ int i, num_valid_sets;
+
+ num_valid_sets = 0;
+
+ for (i = 0; i < WM_SET_COUNT; i++) {
+ /* skip empty entries, the smu array has no holes*/
+ if (!bw_params->wm_table.entries[i].valid)
+ continue;
+
+ table->WatermarkRow[WM_DCFCLK][num_valid_sets].WmSetting = bw_params->wm_table.entries[i].wm_inst;
+ table->WatermarkRow[WM_DCFCLK][num_valid_sets].WmType = bw_params->wm_table.entries[i].wm_type;
+ /* We will not select WM based on fclk, so leave it as unconstrained */
+ table->WatermarkRow[WM_DCFCLK][num_valid_sets].MinClock = 0;
+ table->WatermarkRow[WM_DCFCLK][num_valid_sets].MaxClock = 0xFFFF;
+
+ if (table->WatermarkRow[WM_DCFCLK][num_valid_sets].WmType == WM_TYPE_PSTATE_CHG) {
+ if (i == 0)
+ table->WatermarkRow[WM_DCFCLK][num_valid_sets].MinMclk = 0;
+ else {
+ /* add 1 to make it non-overlapping with next lvl */
+ table->WatermarkRow[WM_DCFCLK][num_valid_sets].MinMclk =
+ bw_params->clk_table.entries[i - 1].dcfclk_mhz + 1;
+ }
+ table->WatermarkRow[WM_DCFCLK][num_valid_sets].MaxMclk =
+ bw_params->clk_table.entries[i].dcfclk_mhz;
+
+ } else {
+ /* unconstrained for memory retraining */
+ table->WatermarkRow[WM_DCFCLK][num_valid_sets].MinClock = 0;
+ table->WatermarkRow[WM_DCFCLK][num_valid_sets].MaxClock = 0xFFFF;
+
+ /* Modify previous watermark range to cover up to max */
+ table->WatermarkRow[WM_DCFCLK][num_valid_sets - 1].MaxClock = 0xFFFF;
+ }
+ num_valid_sets++;
+ }
+
+ ASSERT(num_valid_sets != 0); /* Must have at least one set of valid watermarks */
+
+ /* modify the min and max to make sure we cover the whole range*/
+ table->WatermarkRow[WM_DCFCLK][0].MinMclk = 0;
+ table->WatermarkRow[WM_DCFCLK][0].MinClock = 0;
+ table->WatermarkRow[WM_DCFCLK][num_valid_sets - 1].MaxMclk = 0xFFFF;
+ table->WatermarkRow[WM_DCFCLK][num_valid_sets - 1].MaxClock = 0xFFFF;
+
+ /* This is for writeback only, does not matter currently as no writeback support*/
+ table->WatermarkRow[WM_SOCCLK][0].WmSetting = WM_A;
+ table->WatermarkRow[WM_SOCCLK][0].MinClock = 0;
+ table->WatermarkRow[WM_SOCCLK][0].MaxClock = 0xFFFF;
+ table->WatermarkRow[WM_SOCCLK][0].MinMclk = 0;
+ table->WatermarkRow[WM_SOCCLK][0].MaxMclk = 0xFFFF;
+}
+
+static void dcn316_notify_wm_ranges(struct clk_mgr *clk_mgr_base)
+{
+ struct clk_mgr_internal *clk_mgr = TO_CLK_MGR_INTERNAL(clk_mgr_base);
+ struct clk_mgr_dcn316 *clk_mgr_dcn316 = TO_CLK_MGR_DCN316(clk_mgr);
+ struct dcn316_watermarks *table = clk_mgr_dcn316->smu_wm_set.wm_set;
+
+ if (!clk_mgr->smu_ver)
+ return;
+
+ if (!table || clk_mgr_dcn316->smu_wm_set.mc_address.quad_part == 0)
+ return;
+
+ memset(table, 0, sizeof(*table));
+
+ dcn316_build_watermark_ranges(clk_mgr_base->bw_params, table);
+
+ dcn316_smu_set_dram_addr_high(clk_mgr,
+ clk_mgr_dcn316->smu_wm_set.mc_address.high_part);
+ dcn316_smu_set_dram_addr_low(clk_mgr,
+ clk_mgr_dcn316->smu_wm_set.mc_address.low_part);
+ dcn316_smu_transfer_wm_table_dram_2_smu(clk_mgr);
+}
+
+static void dcn316_get_dpm_table_from_smu(struct clk_mgr_internal *clk_mgr,
+ struct dcn316_smu_dpm_clks *smu_dpm_clks)
+{
+ DpmClocks_316_t *table = smu_dpm_clks->dpm_clks;
+
+ if (!clk_mgr->smu_ver)
+ return;
+
+ if (!table || smu_dpm_clks->mc_address.quad_part == 0)
+ return;
+
+ memset(table, 0, sizeof(*table));
+
+ dcn316_smu_set_dram_addr_high(clk_mgr,
+ smu_dpm_clks->mc_address.high_part);
+ dcn316_smu_set_dram_addr_low(clk_mgr,
+ smu_dpm_clks->mc_address.low_part);
+ dcn316_smu_transfer_dpm_table_smu_2_dram(clk_mgr);
+}
+
+static uint32_t find_max_clk_value(const uint32_t clocks[], uint32_t num_clocks)
+{
+ uint32_t max = 0;
+ int i;
+
+ for (i = 0; i < num_clocks; ++i) {
+ if (clocks[i] > max)
+ max = clocks[i];
+ }
+
+ return max;
+}
+
+static unsigned int find_clk_for_voltage(
+ const DpmClocks_316_t *clock_table,
+ const uint32_t clocks[],
+ unsigned int voltage)
+{
+ int i;
+ int max_voltage = 0;
+ int clock = 0;
+
+ for (i = 0; i < NUM_SOC_VOLTAGE_LEVELS; i++) {
+ if (clock_table->SocVoltage[i] == voltage) {
+ return clocks[i];
+ } else if (clock_table->SocVoltage[i] >= max_voltage &&
+ clock_table->SocVoltage[i] < voltage) {
+ max_voltage = clock_table->SocVoltage[i];
+ clock = clocks[i];
+ }
+ }
+
+ ASSERT(clock);
+ return clock;
+}
+
+static void dcn316_clk_mgr_helper_populate_bw_params(
+ struct clk_mgr_internal *clk_mgr,
+ struct integrated_info *bios_info,
+ const DpmClocks_316_t *clock_table)
+{
+ int i, j;
+ struct clk_bw_params *bw_params = clk_mgr->base.bw_params;
+ uint32_t max_dispclk = 0, max_dppclk = 0;
+
+ j = -1;
+
+ ASSERT(NUM_DF_PSTATE_LEVELS <= MAX_NUM_DPM_LVL);
+
+ /* Find lowest DPM, FCLK is filled in reverse order*/
+
+ for (i = NUM_DF_PSTATE_LEVELS - 1; i >= 0; i--) {
+ if (clock_table->DfPstateTable[i].FClk != 0) {
+ j = i;
+ break;
+ }
+ }
+
+ if (j == -1) {
+ /* clock table is all 0s, just use our own hardcode */
+ ASSERT(0);
+ return;
+ }
+
+ bw_params->clk_table.num_entries = j + 1;
+
+ /* dispclk and dppclk can be max at any voltage, same number of levels for both */
+ if (clock_table->NumDispClkLevelsEnabled <= NUM_DISPCLK_DPM_LEVELS &&
+ clock_table->NumDispClkLevelsEnabled <= NUM_DPPCLK_DPM_LEVELS) {
+ max_dispclk = find_max_clk_value(clock_table->DispClocks, clock_table->NumDispClkLevelsEnabled);
+ max_dppclk = find_max_clk_value(clock_table->DppClocks, clock_table->NumDispClkLevelsEnabled);
+ } else {
+ ASSERT(0);
+ }
+
+ for (i = 0; i < bw_params->clk_table.num_entries; i++, j--) {
+ int temp;
+
+ bw_params->clk_table.entries[i].fclk_mhz = clock_table->DfPstateTable[j].FClk;
+ bw_params->clk_table.entries[i].memclk_mhz = clock_table->DfPstateTable[j].MemClk;
+ bw_params->clk_table.entries[i].voltage = clock_table->DfPstateTable[j].Voltage;
+ switch (clock_table->DfPstateTable[j].WckRatio) {
+ case WCK_RATIO_1_2:
+ bw_params->clk_table.entries[i].wck_ratio = 2;
+ break;
+ case WCK_RATIO_1_4:
+ bw_params->clk_table.entries[i].wck_ratio = 4;
+ break;
+ default:
+ bw_params->clk_table.entries[i].wck_ratio = 1;
+ }
+ temp = find_clk_for_voltage(clock_table, clock_table->DcfClocks, clock_table->DfPstateTable[j].Voltage);
+ if (temp)
+ bw_params->clk_table.entries[i].dcfclk_mhz = temp;
+ temp = find_clk_for_voltage(clock_table, clock_table->SocClocks, clock_table->DfPstateTable[j].Voltage);
+ if (temp)
+ bw_params->clk_table.entries[i].socclk_mhz = temp;
+ bw_params->clk_table.entries[i].dispclk_mhz = max_dispclk;
+ bw_params->clk_table.entries[i].dppclk_mhz = max_dppclk;
+ }
+
+ bw_params->vram_type = bios_info->memory_type;
+ bw_params->num_channels = bios_info->ma_channel_number;
+
+ for (i = 0; i < WM_SET_COUNT; i++) {
+ bw_params->wm_table.entries[i].wm_inst = i;
+
+ if (i >= bw_params->clk_table.num_entries) {
+ bw_params->wm_table.entries[i].valid = false;
+ continue;
+ }
+
+ bw_params->wm_table.entries[i].wm_type = WM_TYPE_PSTATE_CHG;
+ bw_params->wm_table.entries[i].valid = true;
+ }
+}
+
+
+
+static struct clk_mgr_funcs dcn316_funcs = {
+ .enable_pme_wa = dcn316_enable_pme_wa,
+ .get_dp_ref_clk_frequency = dce12_get_dp_ref_freq_khz,
+ .update_clocks = dcn316_update_clocks,
+ .init_clocks = dcn31_init_clocks,
+ .are_clock_states_equal = dcn31_are_clock_states_equal,
+ .notify_wm_ranges = dcn316_notify_wm_ranges
+};
+extern struct clk_mgr_funcs dcn3_fpga_funcs;
+
+static int get_vco_frequency_from_reg(struct clk_mgr_internal *clk_mgr)
+{
+ /* get FbMult value */
+ struct fixed31_32 pll_req;
+ unsigned int fbmult_frac_val = 0;
+ unsigned int fbmult_int_val = 0;
+
+ /*
+ * Register value of fbmult is in 8.16 format, we are converting to 31.32
+ * to leverage the fix point operations available in driver
+ */
+
+ REG_GET(CLK1_CLK_PLL_REQ, FbMult_frac, &fbmult_frac_val); /* 16 bit fractional part*/
+ REG_GET(CLK1_CLK_PLL_REQ, FbMult_int, &fbmult_int_val); /* 8 bit integer part */
+
+ pll_req = dc_fixpt_from_int(fbmult_int_val);
+
+ /*
+ * since fractional part is only 16 bit in register definition but is 32 bit
+ * in our fix point definiton, need to shift left by 16 to obtain correct value
+ */
+ pll_req.value |= fbmult_frac_val << 16;
+
+ /* multiply by REFCLK period */
+ pll_req = dc_fixpt_mul_int(pll_req, clk_mgr->dfs_ref_freq_khz);
+
+ /* integer part is now VCO frequency in kHz */
+ return dc_fixpt_floor(pll_req);
+}
+
+void dcn316_clk_mgr_construct(
+ struct dc_context *ctx,
+ struct clk_mgr_dcn316 *clk_mgr,
+ struct pp_smu_funcs *pp_smu,
+ struct dccg *dccg)
+{
+ struct dcn316_smu_dpm_clks smu_dpm_clks = { 0 };
+
+ clk_mgr->base.base.ctx = ctx;
+ clk_mgr->base.base.funcs = &dcn316_funcs;
+
+ clk_mgr->base.pp_smu = pp_smu;
+
+ clk_mgr->base.dccg = dccg;
+ clk_mgr->base.dfs_bypass_disp_clk = 0;
+
+ clk_mgr->base.dprefclk_ss_percentage = 0;
+ clk_mgr->base.dprefclk_ss_divider = 1000;
+ clk_mgr->base.ss_on_dprefclk = false;
+ clk_mgr->base.dfs_ref_freq_khz = 48000;
+
+ clk_mgr->smu_wm_set.wm_set = (struct dcn316_watermarks *)dm_helpers_allocate_gpu_mem(
+ clk_mgr->base.base.ctx,
+ DC_MEM_ALLOC_TYPE_FRAME_BUFFER,
+ sizeof(struct dcn316_watermarks),
+ &clk_mgr->smu_wm_set.mc_address.quad_part);
+
+ if (!clk_mgr->smu_wm_set.wm_set) {
+ clk_mgr->smu_wm_set.wm_set = &dummy_wms;
+ clk_mgr->smu_wm_set.mc_address.quad_part = 0;
+ }
+ ASSERT(clk_mgr->smu_wm_set.wm_set);
+
+ smu_dpm_clks.dpm_clks = (DpmClocks_316_t *)dm_helpers_allocate_gpu_mem(
+ clk_mgr->base.base.ctx,
+ DC_MEM_ALLOC_TYPE_FRAME_BUFFER,
+ sizeof(DpmClocks_316_t),
+ &smu_dpm_clks.mc_address.quad_part);
+
+ if (smu_dpm_clks.dpm_clks == NULL) {
+ smu_dpm_clks.dpm_clks = &dummy_clocks;
+ smu_dpm_clks.mc_address.quad_part = 0;
+ }
+
+ ASSERT(smu_dpm_clks.dpm_clks);
+
+ if (IS_FPGA_MAXIMUS_DC(ctx->dce_environment)) {
+ clk_mgr->base.base.funcs = &dcn3_fpga_funcs;
+ clk_mgr->base.base.dentist_vco_freq_khz = 2500000;
+ } else {
+ struct clk_log_info log_info = {0};
+
+ clk_mgr->base.smu_ver = dcn316_smu_get_smu_version(&clk_mgr->base);
+
+ if (clk_mgr->base.smu_ver > 0)
+ clk_mgr->base.smu_present = true;
+
+ // Skip this for now as it did not work on DCN315, renable during bring up
+ clk_mgr->base.base.dentist_vco_freq_khz = get_vco_frequency_from_reg(&clk_mgr->base);
+
+ /* in case we don't get a value from the register, use default */
+ if (clk_mgr->base.base.dentist_vco_freq_khz == 0)
+ clk_mgr->base.base.dentist_vco_freq_khz = 2500000; /* 2400MHz */
+
+
+ if (ctx->dc_bios->integrated_info->memory_type == LpDdr5MemType) {
+ dcn316_bw_params.wm_table = lpddr5_wm_table;
+ } else {
+ dcn316_bw_params.wm_table = ddr4_wm_table;
+ }
+ /* Saved clocks configured at boot for debug purposes */
+ dcn316_dump_clk_registers(&clk_mgr->base.base.boot_snapshot, &clk_mgr->base.base, &log_info);
+
+ }
+
+ clk_mgr->base.base.dprefclk_khz = 600000;
+ clk_mgr->base.base.dprefclk_khz = dcn316_smu_get_dpref_clk(&clk_mgr->base);
+ clk_mgr->base.dccg->ref_dtbclk_khz = clk_mgr->base.base.dprefclk_khz;
+ dce_clock_read_ss_info(&clk_mgr->base);
+ clk_mgr->base.dccg->ref_dtbclk_khz =
+ dce_adjust_dp_ref_freq_for_ss(&clk_mgr->base, clk_mgr->base.base.dprefclk_khz);
+
+ clk_mgr->base.base.bw_params = &dcn316_bw_params;
+
+ if (clk_mgr->base.base.ctx->dc->debug.pstate_enabled) {
+ dcn316_get_dpm_table_from_smu(&clk_mgr->base, &smu_dpm_clks);
+
+ if (ctx->dc_bios && ctx->dc_bios->integrated_info) {
+ dcn316_clk_mgr_helper_populate_bw_params(
+ &clk_mgr->base,
+ ctx->dc_bios->integrated_info,
+ smu_dpm_clks.dpm_clks);
+ }
+ }
+
+ if (smu_dpm_clks.dpm_clks && smu_dpm_clks.mc_address.quad_part != 0)
+ dm_helpers_free_gpu_mem(clk_mgr->base.base.ctx, DC_MEM_ALLOC_TYPE_FRAME_BUFFER,
+ smu_dpm_clks.dpm_clks);
+}
+
+void dcn316_clk_mgr_destroy(struct clk_mgr_internal *clk_mgr_int)
+{
+ struct clk_mgr_dcn316 *clk_mgr = TO_CLK_MGR_DCN316(clk_mgr_int);
+
+ if (clk_mgr->smu_wm_set.wm_set && clk_mgr->smu_wm_set.mc_address.quad_part != 0)
+ dm_helpers_free_gpu_mem(clk_mgr_int->base.ctx, DC_MEM_ALLOC_TYPE_FRAME_BUFFER,
+ clk_mgr->smu_wm_set.wm_set);
+}
diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn316/dcn316_clk_mgr.h b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn316/dcn316_clk_mgr.h
new file mode 100644
index 000000000000..864d1f6cef26
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn316/dcn316_clk_mgr.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2021 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: AMD
+ *
+ */
+
+#ifndef __DCN316_CLK_MGR_H__
+#define __DCN316_CLK_MGR_H__
+#include "clk_mgr_internal.h"
+
+struct dcn316_watermarks;
+
+struct dcn316_smu_watermark_set {
+ struct dcn316_watermarks *wm_set;
+ union large_integer mc_address;
+};
+
+struct clk_mgr_dcn316 {
+ struct clk_mgr_internal base;
+ struct dcn316_smu_watermark_set smu_wm_set;
+};
+
+void dcn316_clk_mgr_construct(struct dc_context *ctx,
+ struct clk_mgr_dcn316 *clk_mgr,
+ struct pp_smu_funcs *pp_smu,
+ struct dccg *dccg);
+
+void dcn316_clk_mgr_destroy(struct clk_mgr_internal *clk_mgr_int);
+
+#endif //__DCN316_CLK_MGR_H__
diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn316/dcn316_smu.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn316/dcn316_smu.c
new file mode 100644
index 000000000000..dceec4b96052
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn316/dcn316_smu.c
@@ -0,0 +1,338 @@
+/*
+ * Copyright 2021 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: AMD
+ *
+ */
+
+#include "core_types.h"
+#include "clk_mgr_internal.h"
+#include "reg_helper.h"
+#include "dm_helpers.h"
+#include "dcn316_smu.h"
+#include "mp/mp_13_0_8_offset.h"
+#include "mp/mp_13_0_8_sh_mask.h"
+
+#define MAX_INSTANCE 7
+#define MAX_SEGMENT 6
+
+struct IP_BASE_INSTANCE
+{
+ unsigned int segment[MAX_SEGMENT];
+};
+
+struct IP_BASE
+{
+ struct IP_BASE_INSTANCE instance[MAX_INSTANCE];
+};
+
+static const struct IP_BASE MP0_BASE = { { { { 0x00016000, 0x00DC0000, 0x00E00000, 0x00E40000, 0x0243FC00, 0 } },
+ { { 0, 0, 0, 0, 0, 0 } },
+ { { 0, 0, 0, 0, 0, 0 } },
+ { { 0, 0, 0, 0, 0, 0 } },
+ { { 0, 0, 0, 0, 0, 0 } },
+ { { 0, 0, 0, 0, 0, 0 } },
+ { { 0, 0, 0, 0, 0, 0 } } } };
+
+#define REG(reg_name) \
+ (MP0_BASE.instance[0].segment[reg ## reg_name ## _BASE_IDX] + reg ## reg_name)
+
+#define FN(reg_name, field) \
+ FD(reg_name##__##field)
+
+#define VBIOSSMC_MSG_TestMessage 0x01 ///< To check if PMFW is alive and responding. Requirement specified by PMFW team
+#define VBIOSSMC_MSG_GetPmfwVersion 0x02 ///< Get PMFW version
+#define VBIOSSMC_MSG_Spare0 0x03 ///< Spare0
+#define VBIOSSMC_MSG_SetDispclkFreq 0x04 ///< Set display clock frequency in MHZ
+#define VBIOSSMC_MSG_Spare1 0x05 ///< Spare1
+#define VBIOSSMC_MSG_SetDppclkFreq 0x06 ///< Set DPP clock frequency in MHZ
+#define VBIOSSMC_MSG_SetHardMinDcfclkByFreq 0x07 ///< Set DCF clock frequency hard min in MHZ
+#define VBIOSSMC_MSG_SetMinDeepSleepDcfclk 0x08 ///< Set DCF clock minimum frequency in deep sleep in MHZ
+#define VBIOSSMC_MSG_SetPhyclkVoltageByFreq 0x09 ///< Set display phy clock frequency in MHZ in case VMIN does not support phy frequency
+#define VBIOSSMC_MSG_GetFclkFrequency 0x0A ///< Get FCLK frequency, return frequemcy in MHZ
+#define VBIOSSMC_MSG_SetDisplayCount 0x0B ///< Inform PMFW of number of display connected
+#define VBIOSSMC_MSG_SPARE 0x0C ///< SPARE
+#define VBIOSSMC_MSG_UpdatePmeRestore 0x0D ///< To ask PMFW to write into Azalia for PME wake up event
+#define VBIOSSMC_MSG_SetVbiosDramAddrHigh 0x0E ///< Set DRAM address high 32 bits for WM table transfer
+#define VBIOSSMC_MSG_SetVbiosDramAddrLow 0x0F ///< Set DRAM address low 32 bits for WM table transfer
+#define VBIOSSMC_MSG_TransferTableSmu2Dram 0x10 ///< Transfer table from PMFW SRAM to system DRAM
+#define VBIOSSMC_MSG_TransferTableDram2Smu 0x11 ///< Transfer table from system DRAM to PMFW
+#define VBIOSSMC_MSG_SetDisplayIdleOptimizations 0x12 ///< Set Idle state optimization for display off
+#define VBIOSSMC_MSG_GetDprefclkFreq 0x13 ///< Get DPREF clock frequency. Return in MHZ
+#define VBIOSSMC_MSG_GetDtbclkFreq 0x14 ///< Get DPREF clock frequency. Return in MHZ
+#define VBIOSSMC_MSG_SetDtbclkFreq 0x15 ///< Inform PMFW to turn on/off DTB clock arg = 1, turn DTB clock on 600MHz/ arg = 0 turn DTB clock off
+#define VBIOSSMC_Message_Count 0x16 ///< Total number of VBIS and DAL messages
+
+#define VBIOSSMC_Status_BUSY 0x0
+#define VBIOSSMC_Result_OK 0x01 ///< Message Response OK
+#define VBIOSSMC_Result_Failed 0xFF ///< Message Response Failed
+#define VBIOSSMC_Result_UnknownCmd 0xFE ///< Message Response Unknown Command
+#define VBIOSSMC_Result_CmdRejectedPrereq 0xFD ///< Message Response Command Failed Prerequisite
+#define VBIOSSMC_Result_CmdRejectedBusy 0xFC ///< Message Response Command Rejected due to PMFW is busy. Sender should retry sending this message
+
+/*
+ * Function to be used instead of REG_WAIT macro because the wait ends when
+ * the register is NOT EQUAL to zero, and because the translation in msg_if.h
+ * won't work with REG_WAIT.
+ */
+static uint32_t dcn316_smu_wait_for_response(struct clk_mgr_internal *clk_mgr, unsigned int delay_us, unsigned int max_retries)
+{
+ uint32_t res_val = VBIOSSMC_Status_BUSY;
+
+ do {
+ res_val = REG_READ(MP1_SMN_C2PMSG_91);
+ if (res_val != VBIOSSMC_Status_BUSY)
+ break;
+
+ if (delay_us >= 1000)
+ msleep(delay_us/1000);
+ else if (delay_us > 0)
+ udelay(delay_us);
+ } while (max_retries--);
+
+ return res_val;
+}
+
+static int dcn316_smu_send_msg_with_param(
+ struct clk_mgr_internal *clk_mgr,
+ unsigned int msg_id, unsigned int param)
+{
+ uint32_t result;
+
+ result = dcn316_smu_wait_for_response(clk_mgr, 10, 200000);
+ ASSERT(result == VBIOSSMC_Result_OK);
+
+ if (result == VBIOSSMC_Status_BUSY) {
+ return -1;
+ }
+
+ /* First clear response register */
+ REG_WRITE(MP1_SMN_C2PMSG_91, VBIOSSMC_Status_BUSY);
+
+ /* Set the parameter register for the SMU message, unit is Mhz */
+ REG_WRITE(MP1_SMN_C2PMSG_83, param);
+
+ /* Trigger the message transaction by writing the message ID */
+ REG_WRITE(MP1_SMN_C2PMSG_67, msg_id);
+
+ result = dcn316_smu_wait_for_response(clk_mgr, 10, 200000);
+
+ if (result == VBIOSSMC_Status_BUSY) {
+ ASSERT(0);
+ dm_helpers_smu_timeout(CTX, msg_id, param, 10 * 200000);
+ }
+
+ return REG_READ(MP1_SMN_C2PMSG_83);
+}
+
+int dcn316_smu_get_smu_version(struct clk_mgr_internal *clk_mgr)
+{
+ return dcn316_smu_send_msg_with_param(
+ clk_mgr,
+ VBIOSSMC_MSG_GetPmfwVersion,
+ 0);
+}
+
+
+int dcn316_smu_set_dispclk(struct clk_mgr_internal *clk_mgr, int requested_dispclk_khz)
+{
+ int actual_dispclk_set_mhz = -1;
+
+ if (!clk_mgr->smu_present)
+ return requested_dispclk_khz;
+
+ /* Unit of SMU msg parameter is Mhz */
+ actual_dispclk_set_mhz = dcn316_smu_send_msg_with_param(
+ clk_mgr,
+ VBIOSSMC_MSG_SetDispclkFreq,
+ khz_to_mhz_ceil(requested_dispclk_khz));
+
+ return actual_dispclk_set_mhz * 1000;
+}
+
+int dcn316_smu_set_hard_min_dcfclk(struct clk_mgr_internal *clk_mgr, int requested_dcfclk_khz)
+{
+ int actual_dcfclk_set_mhz = -1;
+
+ if (!clk_mgr->base.ctx->dc->debug.pstate_enabled)
+ return -1;
+
+ if (!clk_mgr->smu_present)
+ return requested_dcfclk_khz;
+
+ actual_dcfclk_set_mhz = dcn316_smu_send_msg_with_param(
+ clk_mgr,
+ VBIOSSMC_MSG_SetHardMinDcfclkByFreq,
+ khz_to_mhz_ceil(requested_dcfclk_khz));
+
+ return actual_dcfclk_set_mhz * 1000;
+}
+
+int dcn316_smu_set_min_deep_sleep_dcfclk(struct clk_mgr_internal *clk_mgr, int requested_min_ds_dcfclk_khz)
+{
+ int actual_min_ds_dcfclk_mhz = -1;
+
+ if (!clk_mgr->base.ctx->dc->debug.pstate_enabled)
+ return -1;
+
+ if (!clk_mgr->smu_present)
+ return requested_min_ds_dcfclk_khz;
+
+ actual_min_ds_dcfclk_mhz = dcn316_smu_send_msg_with_param(
+ clk_mgr,
+ VBIOSSMC_MSG_SetMinDeepSleepDcfclk,
+ khz_to_mhz_ceil(requested_min_ds_dcfclk_khz));
+
+ return actual_min_ds_dcfclk_mhz * 1000;
+}
+
+int dcn316_smu_set_dppclk(struct clk_mgr_internal *clk_mgr, int requested_dpp_khz)
+{
+ int actual_dppclk_set_mhz = -1;
+
+ if (!clk_mgr->smu_present)
+ return requested_dpp_khz;
+
+ actual_dppclk_set_mhz = dcn316_smu_send_msg_with_param(
+ clk_mgr,
+ VBIOSSMC_MSG_SetDppclkFreq,
+ khz_to_mhz_ceil(requested_dpp_khz));
+
+ return actual_dppclk_set_mhz * 1000;
+}
+
+void dcn316_smu_set_display_idle_optimization(struct clk_mgr_internal *clk_mgr, uint32_t idle_info)
+{
+ if (!clk_mgr->base.ctx->dc->debug.pstate_enabled)
+ return;
+
+ if (!clk_mgr->smu_present)
+ return;
+
+ //TODO: Work with smu team to define optimization options.
+ dcn316_smu_send_msg_with_param(
+ clk_mgr,
+ VBIOSSMC_MSG_SetDisplayIdleOptimizations,
+ idle_info);
+}
+
+void dcn316_smu_enable_phy_refclk_pwrdwn(struct clk_mgr_internal *clk_mgr, bool enable)
+{
+ union display_idle_optimization_u idle_info = { 0 };
+
+ if (!clk_mgr->smu_present)
+ return;
+
+ if (enable) {
+ idle_info.idle_info.df_request_disabled = 1;
+ idle_info.idle_info.phy_ref_clk_off = 1;
+ }
+
+ dcn316_smu_send_msg_with_param(
+ clk_mgr,
+ VBIOSSMC_MSG_SetDisplayIdleOptimizations,
+ idle_info.data);
+}
+
+void dcn316_smu_set_dram_addr_high(struct clk_mgr_internal *clk_mgr, uint32_t addr_high)
+{
+ if (!clk_mgr->smu_present)
+ return;
+
+ dcn316_smu_send_msg_with_param(clk_mgr,
+ VBIOSSMC_MSG_SetVbiosDramAddrHigh, addr_high);
+}
+
+void dcn316_smu_set_dram_addr_low(struct clk_mgr_internal *clk_mgr, uint32_t addr_low)
+{
+ if (!clk_mgr->smu_present)
+ return;
+
+ dcn316_smu_send_msg_with_param(clk_mgr,
+ VBIOSSMC_MSG_SetVbiosDramAddrLow, addr_low);
+}
+
+void dcn316_smu_transfer_dpm_table_smu_2_dram(struct clk_mgr_internal *clk_mgr)
+{
+ if (!clk_mgr->smu_present)
+ return;
+
+ dcn316_smu_send_msg_with_param(clk_mgr,
+ VBIOSSMC_MSG_TransferTableSmu2Dram, TABLE_DPMCLOCKS);
+}
+
+void dcn316_smu_transfer_wm_table_dram_2_smu(struct clk_mgr_internal *clk_mgr)
+{
+ if (!clk_mgr->smu_present)
+ return;
+
+ dcn316_smu_send_msg_with_param(clk_mgr,
+ VBIOSSMC_MSG_TransferTableDram2Smu, TABLE_WATERMARKS);
+}
+
+void dcn316_smu_enable_pme_wa(struct clk_mgr_internal *clk_mgr)
+{
+ if (!clk_mgr->smu_present)
+ return;
+
+ dcn316_smu_send_msg_with_param(
+ clk_mgr,
+ VBIOSSMC_MSG_UpdatePmeRestore,
+ 0);
+}
+
+/* Arg = 1: Turn DTB on; 0: Turn DTB CLK OFF. when it is on, it is 600MHZ */
+void dcn316_smu_set_dtbclk(struct clk_mgr_internal *clk_mgr, bool enable)
+{
+ if (!clk_mgr->smu_present)
+ return;
+
+ dcn316_smu_send_msg_with_param(
+ clk_mgr,
+ VBIOSSMC_MSG_SetDtbclkFreq,
+ enable);
+}
+
+int dcn316_smu_get_dpref_clk(struct clk_mgr_internal *clk_mgr)
+{
+ int dprefclk_get_mhz = -1;
+
+ if (clk_mgr->smu_present) {
+ dprefclk_get_mhz = dcn316_smu_send_msg_with_param(
+ clk_mgr,
+ VBIOSSMC_MSG_GetDprefclkFreq,
+ 0);
+ }
+ return (dprefclk_get_mhz * 1000);
+}
+
+int dcn316_smu_get_smu_fclk(struct clk_mgr_internal *clk_mgr)
+{
+ int fclk_get_mhz = -1;
+
+ if (clk_mgr->smu_present) {
+ fclk_get_mhz = dcn316_smu_send_msg_with_param(
+ clk_mgr,
+ VBIOSSMC_MSG_GetFclkFrequency,
+ 0);
+ }
+ return (fclk_get_mhz * 1000);
+}
diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn316/dcn316_smu.h b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn316/dcn316_smu.h
new file mode 100644
index 000000000000..2a7293f66515
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn316/dcn316_smu.h
@@ -0,0 +1,139 @@
+/*
+ * Copyright 2021 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: AMD
+ *
+ */
+
+#ifndef DAL_DC_316_SMU_H_
+#define DAL_DC_316_SMU_H_
+#include "os_types.h"
+
+#define PMFW_DRIVER_IF_VERSION 4
+
+#define NUM_DCFCLK_DPM_LEVELS 8
+#define NUM_DISPCLK_DPM_LEVELS 8
+#define NUM_DPPCLK_DPM_LEVELS 8
+#define NUM_SOCCLK_DPM_LEVELS 8
+#define NUM_VCN_DPM_LEVELS 8
+#define NUM_SOC_VOLTAGE_LEVELS 8
+#define NUM_DF_PSTATE_LEVELS 4
+
+typedef struct {
+ uint16_t MinClock; // This is either DCFCLK or SOCCLK (in MHz)
+ uint16_t MaxClock; // This is either DCFCLK or SOCCLK (in MHz)
+ uint16_t MinMclk;
+ uint16_t MaxMclk;
+ uint8_t WmSetting;
+ uint8_t WmType; // Used for normal pstate change or memory retraining
+ uint8_t Padding[2];
+} WatermarkRowGeneric_t;
+
+#define NUM_WM_RANGES 4
+#define WM_PSTATE_CHG 0
+#define WM_RETRAINING 1
+
+typedef enum {
+ WM_SOCCLK = 0,
+ WM_DCFCLK,
+ WM_COUNT,
+} WM_CLOCK_e;
+
+typedef enum{
+ WCK_RATIO_1_1 = 0, // DDR5, Wck:ck is always 1:1;
+ WCK_RATIO_1_2,
+ WCK_RATIO_1_4,
+ WCK_RATIO_MAX
+} WCK_RATIO_e;
+
+typedef struct {
+ uint32_t FClk;
+ uint32_t MemClk;
+ uint32_t Voltage;
+ uint8_t WckRatio;
+ uint8_t Spare[3];
+} DfPstateTable_t;
+
+//Freq in MHz
+//Voltage in milli volts with 2 fractional bits
+typedef struct {
+ uint32_t DcfClocks[NUM_DCFCLK_DPM_LEVELS];
+ uint32_t DispClocks[NUM_DISPCLK_DPM_LEVELS];
+ uint32_t DppClocks[NUM_DPPCLK_DPM_LEVELS];
+ uint32_t SocClocks[NUM_SOCCLK_DPM_LEVELS];
+ uint32_t VClocks[NUM_VCN_DPM_LEVELS];
+ uint32_t DClocks[NUM_VCN_DPM_LEVELS];
+ uint32_t SocVoltage[NUM_SOC_VOLTAGE_LEVELS];
+ DfPstateTable_t DfPstateTable[NUM_DF_PSTATE_LEVELS];
+ uint8_t NumDcfClkLevelsEnabled;
+ uint8_t NumDispClkLevelsEnabled; //Applies to both Dispclk and Dppclk
+ uint8_t NumSocClkLevelsEnabled;
+ uint8_t VcnClkLevelsEnabled; //Applies to both Vclk and Dclk
+ uint8_t NumDfPstatesEnabled;
+ uint8_t spare[3];
+ uint32_t MinGfxClk;
+ uint32_t MaxGfxClk;
+} DpmClocks_316_t;
+
+struct dcn316_watermarks {
+ // Watermarks
+ WatermarkRowGeneric_t WatermarkRow[WM_COUNT][NUM_WM_RANGES];
+ uint32_t MmHubPadding[7]; // SMU internal use
+};
+
+struct dcn316_smu_dpm_clks {
+ DpmClocks_316_t *dpm_clks;
+ union large_integer mc_address;
+};
+
+#define TABLE_WATERMARKS 1 // Called by DAL through VBIOS
+#define TABLE_DPMCLOCKS 4 // Called by Driver and VBIOS
+
+struct display_idle_optimization {
+ unsigned int df_request_disabled : 1;
+ unsigned int phy_ref_clk_off : 1;
+ unsigned int s0i2_rdy : 1;
+ unsigned int reserved : 29;
+};
+
+union display_idle_optimization_u {
+ struct display_idle_optimization idle_info;
+ uint32_t data;
+};
+
+int dcn316_smu_get_smu_version(struct clk_mgr_internal *clk_mgr);
+int dcn316_smu_set_dispclk(struct clk_mgr_internal *clk_mgr, int requested_dispclk_khz);
+int dcn316_smu_set_hard_min_dcfclk(struct clk_mgr_internal *clk_mgr, int requested_dcfclk_khz);
+int dcn316_smu_set_min_deep_sleep_dcfclk(struct clk_mgr_internal *clk_mgr, int requested_min_ds_dcfclk_khz);
+int dcn316_smu_set_dppclk(struct clk_mgr_internal *clk_mgr, int requested_dpp_khz);
+void dcn316_smu_set_display_idle_optimization(struct clk_mgr_internal *clk_mgr, uint32_t idle_info);
+void dcn316_smu_enable_phy_refclk_pwrdwn(struct clk_mgr_internal *clk_mgr, bool enable);
+void dcn316_smu_set_dram_addr_high(struct clk_mgr_internal *clk_mgr, uint32_t addr_high);
+void dcn316_smu_set_dram_addr_low(struct clk_mgr_internal *clk_mgr, uint32_t addr_low);
+void dcn316_smu_transfer_dpm_table_smu_2_dram(struct clk_mgr_internal *clk_mgr);
+void dcn316_smu_transfer_wm_table_dram_2_smu(struct clk_mgr_internal *clk_mgr);
+void dcn316_smu_request_voltage_via_phyclk(struct clk_mgr_internal *clk_mgr, int requested_phyclk_khz);
+void dcn316_smu_enable_pme_wa(struct clk_mgr_internal *clk_mgr);
+void dcn316_smu_set_dtbclk(struct clk_mgr_internal *clk_mgr, bool enable);
+int dcn316_smu_get_dpref_clk(struct clk_mgr_internal *clk_mgr);
+int dcn316_smu_get_smu_fclk(struct clk_mgr_internal *clk_mgr);
+
+#endif /* DAL_DC_316_SMU_H_ */
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c
index 01c8849b9db2..f6e19efea756 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
@@ -76,6 +76,8 @@
#include "dc_trace.h"
+#include "dce/dmub_outbox.h"
+
#define CTX \
dc->ctx
@@ -985,10 +987,13 @@ static bool dc_construct(struct dc *dc,
goto fail;
#ifdef CONFIG_DRM_AMD_DC_DCN
dc->clk_mgr->force_smu_not_present = init_params->force_smu_not_present;
-#endif
- if (dc->res_pool->funcs->update_bw_bounding_box)
+ if (dc->res_pool->funcs->update_bw_bounding_box) {
+ DC_FP_START();
dc->res_pool->funcs->update_bw_bounding_box(dc, dc->clk_mgr->bw_params);
+ DC_FP_END();
+ }
+#endif
/* Creation of current_state must occur after dc->dml
* is initialized in dc_create_resource_pool because
@@ -1077,7 +1082,8 @@ static void disable_dangling_plane(struct dc *dc, struct dc_state *context)
break;
}
}
- if (!should_disable && pipe_split_change)
+ if (!should_disable && pipe_split_change &&
+ dc->current_state->stream_count != context->stream_count)
should_disable = true;
if (should_disable && old_stream) {
@@ -1220,6 +1226,8 @@ struct dc *dc_create(const struct dc_init_data *init_params)
dc->caps.max_dp_protocol_version = DP_VERSION_1_4;
+ dc->caps.max_otg_num = dc->res_pool->res_cap->num_timing_generator;
+
if (dc->res_pool->dmcu != NULL)
dc->versions.dmcu_version = dc->res_pool->dmcu->dmcu_version;
}
@@ -1404,20 +1412,34 @@ static void program_timing_sync(
status->timing_sync_info.master = false;
}
- /* remove any other unblanked pipes as they have already been synced */
- for (j = j + 1; j < group_size; j++) {
- bool is_blanked;
- if (pipe_set[j]->stream_res.opp->funcs->dpg_is_blanked)
- is_blanked =
- pipe_set[j]->stream_res.opp->funcs->dpg_is_blanked(pipe_set[j]->stream_res.opp);
- else
- is_blanked =
- pipe_set[j]->stream_res.tg->funcs->is_blanked(pipe_set[j]->stream_res.tg);
- if (!is_blanked) {
- group_size--;
- pipe_set[j] = pipe_set[group_size];
- j--;
+ /* remove any other pipes that are already been synced */
+ if (dc->config.use_pipe_ctx_sync_logic) {
+ /* check pipe's syncd to decide which pipe to be removed */
+ for (j = 1; j < group_size; j++) {
+ if (pipe_set[j]->pipe_idx_syncd == pipe_set[0]->pipe_idx_syncd) {
+ group_size--;
+ pipe_set[j] = pipe_set[group_size];
+ j--;
+ } else
+ /* link slave pipe's syncd with master pipe */
+ pipe_set[j]->pipe_idx_syncd = pipe_set[0]->pipe_idx_syncd;
+ }
+ } else {
+ for (j = j + 1; j < group_size; j++) {
+ bool is_blanked;
+
+ if (pipe_set[j]->stream_res.opp->funcs->dpg_is_blanked)
+ is_blanked =
+ pipe_set[j]->stream_res.opp->funcs->dpg_is_blanked(pipe_set[j]->stream_res.opp);
+ else
+ is_blanked =
+ pipe_set[j]->stream_res.tg->funcs->is_blanked(pipe_set[j]->stream_res.tg);
+ if (!is_blanked) {
+ group_size--;
+ pipe_set[j] = pipe_set[group_size];
+ j--;
+ }
}
}
@@ -1453,7 +1475,7 @@ static bool context_changed(
return false;
}
-bool dc_validate_seamless_boot_timing(const struct dc *dc,
+bool dc_validate_boot_timing(const struct dc *dc,
const struct dc_sink *sink,
struct dc_crtc_timing *crtc_timing)
{
@@ -1669,6 +1691,7 @@ static enum dc_status dc_commit_state_no_check(struct dc *dc, struct dc_state *c
struct pipe_ctx *pipe;
int i, k, l;
struct dc_stream_state *dc_streams[MAX_STREAMS] = {0};
+ struct dc_state *old_state;
#if defined(CONFIG_DRM_AMD_DC_DCN)
dc_z10_restore(dc);
@@ -1787,10 +1810,11 @@ static enum dc_status dc_commit_state_no_check(struct dc *dc, struct dc_state *c
for (i = 0; i < context->stream_count; i++)
context->streams[i]->mode_changed = false;
- dc_release_state(dc->current_state);
-
+ old_state = dc->current_state;
dc->current_state = context;
+ dc_release_state(old_state);
+
dc_retain_state(dc->current_state);
return result;
@@ -2363,10 +2387,8 @@ static enum surface_update_type check_update_surfaces_for_stream(
if (stream_update->dsc_config)
su_flags->bits.dsc_changed = 1;
-#if defined(CONFIG_DRM_AMD_DC_DCN)
if (stream_update->mst_bw_update)
su_flags->bits.mst_bw = 1;
-#endif
if (su_flags->raw != 0)
overall_type = UPDATE_TYPE_FULL;
@@ -2708,6 +2730,9 @@ static void commit_planes_do_stream_update(struct dc *dc,
stream_update->vsp_infopacket) {
resource_build_info_frame(pipe_ctx);
dc->hwss.update_info_frame(pipe_ctx);
+
+ if (dc_is_dp_signal(pipe_ctx->stream->signal))
+ dp_source_sequence_trace(pipe_ctx->stream->link, DPCD_SOURCE_SEQ_AFTER_UPDATE_INFO_FRAME);
}
if (stream_update->hdr_static_metadata &&
@@ -2745,14 +2770,12 @@ static void commit_planes_do_stream_update(struct dc *dc,
if (stream_update->dsc_config)
dp_update_dsc_config(pipe_ctx);
-#if defined(CONFIG_DRM_AMD_DC_DCN)
if (stream_update->mst_bw_update) {
if (stream_update->mst_bw_update->is_increase)
dc_link_increase_mst_payload(pipe_ctx, stream_update->mst_bw_update->mst_stream_bw);
else
dc_link_reduce_mst_payload(pipe_ctx, stream_update->mst_bw_update->mst_stream_bw);
}
-#endif
if (stream_update->pending_test_pattern) {
dc_link_dp_set_test_pattern(stream->link,
@@ -3340,6 +3363,19 @@ bool dc_is_dmcu_initialized(struct dc *dc)
return false;
}
+bool dc_is_oem_i2c_device_present(
+ struct dc *dc,
+ size_t slave_address)
+{
+ if (dc->res_pool->oem_device)
+ return dce_i2c_oem_device_present(
+ dc->res_pool,
+ dc->res_pool->oem_device,
+ slave_address);
+
+ return false;
+}
+
bool dc_submit_i2c(
struct dc *dc,
uint32_t link_index,
@@ -3688,13 +3724,23 @@ void dc_hardware_release(struct dc *dc)
}
#endif
-/**
- * dc_enable_dmub_notifications - Returns whether dmub notification can be enabled
- * @dc: dc structure
+/*
+ *****************************************************************************
+ * Function: dc_is_dmub_outbox_supported -
+ *
+ * @brief
+ * Checks whether DMUB FW supports outbox notifications, if supported
+ * DM should register outbox interrupt prior to actually enabling interrupts
+ * via dc_enable_dmub_outbox
*
- * Returns: True to enable dmub notifications, False otherwise
+ * @param
+ * [in] dc: dc structure
+ *
+ * @return
+ * True if DMUB FW supports outbox notifications, False otherwise
+ *****************************************************************************
*/
-bool dc_enable_dmub_notifications(struct dc *dc)
+bool dc_is_dmub_outbox_supported(struct dc *dc)
{
#if defined(CONFIG_DRM_AMD_DC_DCN)
/* YELLOW_CARP B0 USB4 DPIA needs dmub notifications for interrupts */
@@ -3707,6 +3753,48 @@ bool dc_enable_dmub_notifications(struct dc *dc)
return dc->debug.enable_dmub_aux_for_legacy_ddc;
}
+/*
+ *****************************************************************************
+ * Function: dc_enable_dmub_notifications
+ *
+ * @brief
+ * Calls dc_is_dmub_outbox_supported to check if dmub fw supports outbox
+ * notifications. All DMs shall switch to dc_is_dmub_outbox_supported.
+ * This API shall be removed after switching.
+ *
+ * @param
+ * [in] dc: dc structure
+ *
+ * @return
+ * True if DMUB FW supports outbox notifications, False otherwise
+ *****************************************************************************
+ */
+bool dc_enable_dmub_notifications(struct dc *dc)
+{
+ return dc_is_dmub_outbox_supported(dc);
+}
+
+/**
+ *****************************************************************************
+ * Function: dc_enable_dmub_outbox
+ *
+ * @brief
+ * Enables DMUB unsolicited notifications to x86 via outbox
+ *
+ * @param
+ * [in] dc: dc structure
+ *
+ * @return
+ * None
+ *****************************************************************************
+ */
+void dc_enable_dmub_outbox(struct dc *dc)
+{
+ struct dc_context *dc_ctx = dc->ctx;
+
+ dmub_enable_outbox_notification(dc_ctx->dmub_srv);
+}
+
/**
* dc_process_dmub_aux_transfer_async - Submits aux command to dmub via inbox message
* Sets port index appropriately for legacy DDC
@@ -3810,7 +3898,7 @@ uint8_t get_link_index_from_dpia_port_index(const struct dc *dc,
* [in] payload: aux payload
* [out] notify: set_config immediate reply
*
- * @return
+ * @return
* True if successful, False if failure
*****************************************************************************
*/
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link.c b/drivers/gpu/drm/amd/display/dc/core/dc_link.c
index b5e570d33ca9..cb87dd643180 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c
@@ -50,6 +50,7 @@
#include "inc/hw/panel_cntl.h"
#include "inc/link_enc_cfg.h"
#include "inc/link_dpcd.h"
+#include "link/link_dp_trace.h"
#include "dc/dcn30/dcn30_vpg.h"
@@ -720,35 +721,8 @@ static bool detect_dp(struct dc_link *link,
sink_caps->signal = SIGNAL_TYPE_DISPLAY_PORT;
if (!detect_dp_sink_caps(link))
return false;
- if (is_mst_supported(link)) {
- sink_caps->signal = SIGNAL_TYPE_DISPLAY_PORT_MST;
- link->type = dc_connection_mst_branch;
- dal_ddc_service_set_transaction_type(link->ddc,
- sink_caps->transaction_type);
-
-#if defined(CONFIG_DRM_AMD_DC_DCN)
- /* Apply work around for tunneled MST on certain USB4 docks. Always use DSC if dock
- * reports DSC support.
- */
- if (link->ep_type == DISPLAY_ENDPOINT_USB4_DPIA &&
- link->type == dc_connection_mst_branch &&
- link->dpcd_caps.branch_dev_id == DP_BRANCH_DEVICE_ID_90CC24 &&
- link->dpcd_caps.dsc_caps.dsc_basic_caps.fields.dsc_support.DSC_SUPPORT &&
- !link->dc->debug.dpia_debug.bits.disable_mst_dsc_work_around)
- link->wa_flags.dpia_mst_dsc_always_on = true;
-#endif
-
-#if defined(CONFIG_DRM_AMD_DC_HDCP)
- /* In case of fallback to SST when topology discovery below fails
- * HDCP caps will be querried again later by the upper layer (caller
- * of this function). */
- query_hdcp_capability(SIGNAL_TYPE_DISPLAY_PORT_MST, link);
-#endif
- }
-
- if (link->type != dc_connection_mst_branch &&
- is_dp_branch_device(link))
+ if (is_dp_branch_device(link))
/* DP SST branch */
link->type = dc_connection_sst_branch;
} else {
@@ -757,6 +731,7 @@ static bool detect_dp(struct dc_link *link,
sink_caps,
audio_support);
link->dpcd_caps.dongle_type = sink_caps->dongle_type;
+ link->dpcd_caps.is_dongle_type_one = sink_caps->is_dongle_type_one;
link->dpcd_caps.dpcd_rev.raw = 0;
}
@@ -824,15 +799,214 @@ static bool wait_for_entering_dp_alt_mode(struct dc_link *link)
return false;
}
-/*
- * dc_link_detect() - Detect if a sink is attached to a given link
+static void apply_dpia_mst_dsc_always_on_wa(struct dc_link *link)
+{
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+ /* Apply work around for tunneled MST on certain USB4 docks. Always use DSC if dock
+ * reports DSC support.
+ */
+ if (link->ep_type == DISPLAY_ENDPOINT_USB4_DPIA &&
+ link->type == dc_connection_mst_branch &&
+ link->dpcd_caps.branch_dev_id == DP_BRANCH_DEVICE_ID_90CC24 &&
+ link->dpcd_caps.branch_hw_revision == DP_BRANCH_HW_REV_20 &&
+ link->dpcd_caps.dsc_caps.dsc_basic_caps.fields.dsc_support.DSC_SUPPORT &&
+ !link->dc->debug.dpia_debug.bits.disable_mst_dsc_work_around)
+ link->wa_flags.dpia_mst_dsc_always_on = true;
+#endif
+}
+
+static void revert_dpia_mst_dsc_always_on_wa(struct dc_link *link)
+{
+ /* Disable work around which keeps DSC on for tunneled MST on certain USB4 docks. */
+ if (link->ep_type == DISPLAY_ENDPOINT_USB4_DPIA)
+ link->wa_flags.dpia_mst_dsc_always_on = false;
+}
+
+static bool discover_dp_mst_topology(struct dc_link *link, enum dc_detect_reason reason)
+{
+ DC_LOGGER_INIT(link->ctx->logger);
+
+ LINK_INFO("link=%d, mst branch is now Connected\n",
+ link->link_index);
+
+ apply_dpia_mst_dsc_always_on_wa(link);
+ link->type = dc_connection_mst_branch;
+ dm_helpers_dp_update_branch_info(link->ctx, link);
+ if (dm_helpers_dp_mst_start_top_mgr(link->ctx,
+ link, (reason == DETECT_REASON_BOOT || reason == DETECT_REASON_RESUMEFROMS3S4))) {
+ link_disconnect_sink(link);
+ } else {
+ link->type = dc_connection_sst_branch;
+ }
+
+ return link->type == dc_connection_mst_branch;
+}
+
+static bool reset_cur_dp_mst_topology(struct dc_link *link)
+{
+ bool result = false;
+ DC_LOGGER_INIT(link->ctx->logger);
+
+ LINK_INFO("link=%d, mst branch is now Disconnected\n",
+ link->link_index);
+
+ revert_dpia_mst_dsc_always_on_wa(link);
+ result = dm_helpers_dp_mst_stop_top_mgr(link->ctx, link);
+
+ link->mst_stream_alloc_table.stream_count = 0;
+ memset(link->mst_stream_alloc_table.stream_allocations,
+ 0,
+ sizeof(link->mst_stream_alloc_table.stream_allocations));
+ return result;
+}
+
+static bool should_prepare_phy_clocks_for_link_verification(const struct dc *dc,
+ enum dc_detect_reason reason)
+{
+ int i;
+ bool can_apply_seamless_boot = false;
+
+ for (i = 0; i < dc->current_state->stream_count; i++) {
+ if (dc->current_state->streams[i]->apply_seamless_boot_optimization) {
+ can_apply_seamless_boot = true;
+ break;
+ }
+ }
+
+ return !can_apply_seamless_boot && reason != DETECT_REASON_BOOT;
+}
+
+static void prepare_phy_clocks_for_destructive_link_verification(const struct dc *dc)
+{
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+ dc_z10_restore(dc);
+#endif
+ clk_mgr_exit_optimized_pwr_state(dc, dc->clk_mgr);
+}
+
+static void restore_phy_clocks_for_destructive_link_verification(const struct dc *dc)
+{
+ clk_mgr_optimize_pwr_state(dc, dc->clk_mgr);
+}
+
+static void set_all_streams_dpms_off_for_link(struct dc_link *link)
+{
+ int i;
+ struct pipe_ctx *pipe_ctx;
+ struct dc_stream_update stream_update;
+ bool dpms_off = true;
+ struct link_resource link_res = {0};
+
+ memset(&stream_update, 0, sizeof(stream_update));
+ stream_update.dpms_off = &dpms_off;
+
+ for (i = 0; i < MAX_PIPES; i++) {
+ pipe_ctx = &link->dc->current_state->res_ctx.pipe_ctx[i];
+ if (pipe_ctx && pipe_ctx->stream && !pipe_ctx->stream->dpms_off &&
+ pipe_ctx->stream->link == link && !pipe_ctx->prev_odm_pipe) {
+ stream_update.stream = pipe_ctx->stream;
+ dc_commit_updates_for_stream(link->ctx->dc, NULL, 0,
+ pipe_ctx->stream, &stream_update,
+ link->ctx->dc->current_state);
+ }
+ }
+
+ /* link can be also enabled by vbios. In this case it is not recorded
+ * in pipe_ctx. Disable link phy here to make sure it is completely off
+ */
+ dp_disable_link_phy(link, &link_res, link->connector_signal);
+}
+
+static void verify_link_capability_destructive(struct dc_link *link,
+ struct dc_sink *sink,
+ enum dc_detect_reason reason)
+{
+ bool should_prepare_phy_clocks =
+ should_prepare_phy_clocks_for_link_verification(link->dc, reason);
+
+ if (should_prepare_phy_clocks)
+ prepare_phy_clocks_for_destructive_link_verification(link->dc);
+
+ if (dc_is_dp_signal(link->local_sink->sink_signal)) {
+ struct dc_link_settings known_limit_link_setting =
+ dp_get_max_link_cap(link);
+ set_all_streams_dpms_off_for_link(link);
+ dp_verify_link_cap_with_retries(
+ link, &known_limit_link_setting,
+ LINK_TRAINING_MAX_VERIFY_RETRY);
+ } else {
+ ASSERT(0);
+ }
+
+ if (should_prepare_phy_clocks)
+ restore_phy_clocks_for_destructive_link_verification(link->dc);
+}
+
+static void verify_link_capability_non_destructive(struct dc_link *link)
+{
+ if (dc_is_dp_signal(link->local_sink->sink_signal)) {
+ if (dc_is_embedded_signal(link->local_sink->sink_signal) ||
+ link->ep_type == DISPLAY_ENDPOINT_USB4_DPIA)
+ /* TODO - should we check link encoder's max link caps here?
+ * How do we know which link encoder to check from?
+ */
+ link->verified_link_cap = link->reported_link_cap;
+ else
+ link->verified_link_cap = dp_get_max_link_cap(link);
+ }
+}
+
+static bool should_verify_link_capability_destructively(struct dc_link *link,
+ enum dc_detect_reason reason)
+{
+ bool destrictive = false;
+ struct dc_link_settings max_link_cap;
+ bool is_link_enc_unavailable = link->link_enc &&
+ link->dc->res_pool->funcs->link_encs_assign &&
+ !link_enc_cfg_is_link_enc_avail(
+ link->ctx->dc,
+ link->link_enc->preferred_engine,
+ link);
+
+ if (dc_is_dp_signal(link->local_sink->sink_signal)) {
+ max_link_cap = dp_get_max_link_cap(link);
+ destrictive = true;
+
+ if (link->dc->debug.skip_detection_link_training ||
+ dc_is_embedded_signal(link->local_sink->sink_signal) ||
+ link->ep_type == DISPLAY_ENDPOINT_USB4_DPIA) {
+ destrictive = false;
+ } else if (dp_get_link_encoding_format(&max_link_cap) ==
+ DP_8b_10b_ENCODING) {
+ if (link->dpcd_caps.is_mst_capable ||
+ is_link_enc_unavailable) {
+ destrictive = false;
+ }
+ }
+ } else if (dc_is_hdmi_signal(link->local_sink->sink_signal))
+ destrictive = true;
+
+ return destrictive;
+}
+
+static void verify_link_capability(struct dc_link *link, struct dc_sink *sink,
+ enum dc_detect_reason reason)
+{
+ if (should_verify_link_capability_destructively(link, reason))
+ verify_link_capability_destructive(link, sink, reason);
+ else
+ verify_link_capability_non_destructive(link);
+}
+
+
+/**
+ * detect_link_and_local_sink() - Detect if a sink is attached to a given link
*
* link->local_sink is created or destroyed as needed.
*
- * This does not create remote sinks but will trigger DM
- * to start MST detection if a branch is detected.
+ * This does not create remote sinks.
*/
-static bool dc_link_detect_helper(struct dc_link *link,
+static bool detect_link_and_local_sink(struct dc_link *link,
enum dc_detect_reason reason)
{
struct dc_sink_init_data sink_init_data = { 0 };
@@ -848,9 +1022,7 @@ static bool dc_link_detect_helper(struct dc_link *link,
struct dpcd_caps prev_dpcd_caps;
enum dc_connection_type new_connection_type = dc_connection_none;
enum dc_connection_type pre_connection_type = dc_connection_none;
- bool perform_dp_seamless_boot = false;
const uint32_t post_oui_delay = 30; // 30ms
- struct link_resource link_res = { 0 };
DC_LOGGER_INIT(link->ctx->logger);
@@ -862,7 +1034,8 @@ static bool dc_link_detect_helper(struct dc_link *link,
(!link->dc->config.allow_edp_hotplug_detection)) &&
link->local_sink) {
// need to re-write OUI and brightness in resume case
- if (link->connector_signal == SIGNAL_TYPE_EDP) {
+ if (link->connector_signal == SIGNAL_TYPE_EDP &&
+ (link->dpcd_sink_ext_caps.bits.oled == 1)) {
dpcd_set_source_specific_data(link);
msleep(post_oui_delay);
dc_link_set_default_brightness_aux(link);
@@ -943,61 +1116,6 @@ static bool dc_link_detect_helper(struct dc_link *link,
return false;
}
-#if defined(CONFIG_DRM_AMD_DC_DCN)
- if (dp_get_link_encoding_format(&link->reported_link_cap) == DP_128b_132b_ENCODING)
- link_res.hpo_dp_link_enc = resource_get_hpo_dp_link_enc_for_det_lt(
- &link->dc->current_state->res_ctx,
- link->dc->res_pool,
- link);
-#endif
-
- if (link->type == dc_connection_mst_branch) {
- LINK_INFO("link=%d, mst branch is now Connected\n",
- link->link_index);
- /* Need to setup mst link_cap struct here
- * otherwise dc_link_detect() will leave mst link_cap
- * empty which leads to allocate_mst_payload() has "0"
- * pbn_per_slot value leading to exception on dc_fixpt_div()
- */
- dp_verify_mst_link_cap(link, &link_res);
-
- /*
- * This call will initiate MST topology discovery. Which
- * will detect MST ports and add new DRM connector DRM
- * framework. Then read EDID via remote i2c over aux. In
- * the end, will notify DRM detect result and save EDID
- * into DRM framework.
- *
- * .detect is called by .fill_modes.
- * .fill_modes is called by user mode ioctl
- * DRM_IOCTL_MODE_GETCONNECTOR.
- *
- * .get_modes is called by .fill_modes.
- *
- * call .get_modes, AMDGPU DM implementation will create
- * new dc_sink and add to dc_link. For long HPD plug
- * in/out, MST has its own handle.
- *
- * Therefore, just after dc_create, link->sink is not
- * created for MST until user mode app calls
- * DRM_IOCTL_MODE_GETCONNECTOR.
- *
- * Need check ->sink usages in case ->sink = NULL
- * TODO: s3 resume check
- */
-
- dm_helpers_dp_update_branch_info(link->ctx, link);
- if (dm_helpers_dp_mst_start_top_mgr(link->ctx,
- link, reason == DETECT_REASON_BOOT)) {
- if (prev_sink)
- dc_sink_release(prev_sink);
- return false;
- } else {
- link->type = dc_connection_sst_branch;
- sink_caps.signal = SIGNAL_TYPE_DISPLAY_PORT;
- }
- }
-
/* Active SST downstream branch device unplug*/
if (link->type == dc_connection_sst_branch &&
link->dpcd_caps.sink_count.bits.SINK_COUNT == 0) {
@@ -1018,19 +1136,6 @@ static bool dc_link_detect_helper(struct dc_link *link,
if (pre_connection_type == dc_connection_mst_branch &&
link->type != dc_connection_mst_branch)
dm_helpers_dp_mst_stop_top_mgr(link->ctx, link);
-
-
- // For seamless boot, to skip verify link cap, we read UEFI settings and set them as verified.
- if (reason == DETECT_REASON_BOOT &&
- !dc_ctx->dc->config.power_down_display_on_boot &&
- link->link_status.link_active)
- perform_dp_seamless_boot = true;
-
- if (perform_dp_seamless_boot) {
- read_current_link_settings_on_detect(link);
- link->verified_link_cap = link->reported_link_cap;
- }
-
break;
}
@@ -1078,6 +1183,9 @@ static bool dc_link_detect_helper(struct dc_link *link,
case EDID_BAD_CHECKSUM:
DC_LOG_ERROR("EDID checksum invalid.\n");
break;
+ case EDID_PARTIAL_VALID:
+ DC_LOG_ERROR("Partial EDID valid, abandon invalid blocks.\n");
+ break;
case EDID_NO_RESPONSE:
DC_LOG_ERROR("No EDID read.\n");
/*
@@ -1095,6 +1203,22 @@ static bool dc_link_detect_helper(struct dc_link *link,
return false;
}
+
+ if (link->type == dc_connection_sst_branch &&
+ link->dpcd_caps.dongle_type ==
+ DISPLAY_DONGLE_DP_VGA_CONVERTER &&
+ reason == DETECT_REASON_HPDRX) {
+ /* Abort detection for DP-VGA adapters when EDID
+ * can't be read and detection reason is VGA-side
+ * hotplug
+ */
+ if (prev_sink)
+ dc_sink_release(prev_sink);
+ link_disconnect_sink(link);
+
+ return true;
+ }
+
break;
default:
break;
@@ -1119,13 +1243,6 @@ static bool dc_link_detect_helper(struct dc_link *link,
#if defined(CONFIG_DRM_AMD_DC_HDCP)
query_hdcp_capability(sink->sink_signal, link);
#endif
-
- // verify link cap for SST non-seamless boot
- if (!perform_dp_seamless_boot)
- dp_verify_link_cap_with_retries(link,
- &link_res,
- &link->reported_link_cap,
- LINK_TRAINING_MAX_VERIFY_RETRY);
} else {
// If edid is the same, then discard new sink and revert back to original sink
if (same_edid) {
@@ -1143,6 +1260,9 @@ static bool dc_link_detect_helper(struct dc_link *link,
!sink->edid_caps.edid_hdmi)
sink->sink_signal = SIGNAL_TYPE_DVI_SINGLE_LINK;
+ if (link->local_sink && dc_is_dp_signal(sink_caps.signal))
+ dp_trace_init(link);
+
/* Connectivity log: detection */
for (i = 0; i < sink->dc_edid.length / DC_EDID_BLOCK_SIZE; i++) {
CONN_DATA_DETECT(link,
@@ -1185,27 +1305,6 @@ static bool dc_link_detect_helper(struct dc_link *link,
}
} else {
/* From Connected-to-Disconnected. */
- if (link->type == dc_connection_mst_branch) {
- LINK_INFO("link=%d, mst branch is now Disconnected\n",
- link->link_index);
-
- /* Disable work around which keeps DSC on for tunneled MST on certain USB4 docks. */
- if (link->ep_type == DISPLAY_ENDPOINT_USB4_DPIA)
- link->wa_flags.dpia_mst_dsc_always_on = false;
-
- dm_helpers_dp_mst_stop_top_mgr(link->ctx, link);
-
- link->mst_stream_alloc_table.stream_count = 0;
- memset(link->mst_stream_alloc_table.stream_allocations,
- 0,
- sizeof(link->mst_stream_alloc_table.stream_allocations));
- }
-
-#if defined(CONFIG_DRM_AMD_DC_DCN)
- if (dp_get_link_encoding_format(&link->cur_link_settings) == DP_128b_132b_ENCODING)
- reset_dp_hpo_stream_encoders_for_link(link);
-#endif
-
link->type = dc_connection_none;
sink_caps.signal = SIGNAL_TYPE_NONE;
/* When we unplug a passive DP-HDMI dongle connection, dongle_max_pix_clk
@@ -1214,6 +1313,9 @@ static bool dc_link_detect_helper(struct dc_link *link,
* Clear dongle_max_pix_clk on disconnect to fix this
*/
link->dongle_max_pix_clk = 0;
+
+ dc_link_clear_dprx_states(link);
+ dp_trace_reset(link);
}
LINK_INFO("link=%d, dc_sink_in=%p is now %s prev_sink=%p edid same=%d\n",
@@ -1230,33 +1332,26 @@ static bool dc_link_detect_helper(struct dc_link *link,
bool dc_link_detect(struct dc_link *link, enum dc_detect_reason reason)
{
- const struct dc *dc = link->dc;
- bool ret;
- bool can_apply_seamless_boot = false;
- int i;
+ bool is_local_sink_detect_success;
+ bool is_delegated_to_mst_top_mgr = false;
+ enum dc_connection_type pre_link_type = link->type;
- for (i = 0; i < dc->current_state->stream_count; i++) {
- if (dc->current_state->streams[i]->apply_seamless_boot_optimization) {
- can_apply_seamless_boot = true;
- break;
- }
- }
+ is_local_sink_detect_success = detect_link_and_local_sink(link, reason);
-#if defined(CONFIG_DRM_AMD_DC_DCN)
- dc_z10_restore(dc);
-#endif
+ if (is_local_sink_detect_success && link->local_sink)
+ verify_link_capability(link, link->local_sink, reason);
- /* get out of low power state */
- if (!can_apply_seamless_boot && reason != DETECT_REASON_BOOT)
- clk_mgr_exit_optimized_pwr_state(dc, dc->clk_mgr);
+ if (is_local_sink_detect_success && link->local_sink &&
+ dc_is_dp_signal(link->local_sink->sink_signal) &&
+ link->dpcd_caps.is_mst_capable)
+ is_delegated_to_mst_top_mgr = discover_dp_mst_topology(link, reason);
- ret = dc_link_detect_helper(link, reason);
+ if (is_local_sink_detect_success &&
+ pre_link_type == dc_connection_mst_branch &&
+ link->type != dc_connection_mst_branch)
+ is_delegated_to_mst_top_mgr = reset_cur_dp_mst_topology(link);
- /* Go back to power optimized state */
- if (!can_apply_seamless_boot && reason != DETECT_REASON_BOOT)
- clk_mgr_optimize_pwr_state(dc, dc->clk_mgr);
-
- return ret;
+ return is_local_sink_detect_success && !is_delegated_to_mst_top_mgr;
}
bool dc_link_get_hpd_state(struct dc_link *dc_link)
@@ -1586,9 +1681,7 @@ static bool dc_link_construct_legacy(struct dc_link *link,
}
DC_LOG_DC("BIOS object table - DP_IS_USB_C: %d", link->link_enc->features.flags.bits.DP_IS_USB_C);
-#if defined(CONFIG_DRM_AMD_DC_DCN)
DC_LOG_DC("BIOS object table - IS_DP2_CAPABLE: %d", link->link_enc->features.flags.bits.IS_DP2_CAPABLE);
-#endif
/* Update link encoder tracking variables. These are used for the dynamic
* assignment of link encoders to streams.
@@ -1871,7 +1964,6 @@ static enum dc_status enable_link_dp(struct dc_state *state,
if (link->ep_type == DISPLAY_ENDPOINT_USB4_DPIA)
do_fallback = true;
-#if defined(CONFIG_DRM_AMD_DC_DCN)
/*
* Temporary w/a to get DP2.0 link rates to work with SST.
* TODO DP2.0 - Workaround: Remove w/a if and when the issue is resolved.
@@ -1881,7 +1973,6 @@ static enum dc_status enable_link_dp(struct dc_state *state,
link->dc->debug.set_mst_en_for_sst) {
dp_enable_mst_on_sink(link, true);
}
-#endif
if (pipe_ctx->stream->signal == SIGNAL_TYPE_EDP) {
/*in case it is not on*/
@@ -1889,7 +1980,6 @@ static enum dc_status enable_link_dp(struct dc_state *state,
link->dc->hwss.edp_wait_for_hpd_ready(link, true);
}
-#if defined(CONFIG_DRM_AMD_DC_DCN)
if (dp_get_link_encoding_format(&link_settings) == DP_128b_132b_ENCODING) {
/* TODO - DP2.0 HW: calculate 32 symbol clock for HPO encoder */
} else {
@@ -1899,19 +1989,15 @@ static enum dc_status enable_link_dp(struct dc_state *state,
state->clk_mgr->funcs->update_clocks(state->clk_mgr,
state, false);
}
-#else
- pipe_ctx->stream_res.pix_clk_params.requested_sym_clk =
- link_settings.link_rate * LINK_RATE_REF_FREQ_IN_KHZ;
- if (state->clk_mgr && !apply_seamless_boot_optimization)
- state->clk_mgr->funcs->update_clocks(state->clk_mgr,
- state, false);
-#endif
// during mode switch we do DP_SET_POWER off then on, and OUI is lost
dpcd_set_source_specific_data(link);
if (link->dpcd_sink_ext_caps.raw != 0)
msleep(post_oui_delay);
+ // similarly, mode switch can cause loss of cable ID
+ dpcd_write_cable_id_to_dprx(link);
+
skip_video_pattern = true;
if (link_settings.link_rate == LINK_RATE_LOW)
@@ -1934,12 +2020,8 @@ static enum dc_status enable_link_dp(struct dc_state *state,
else
fec_enable = true;
-#if defined(CONFIG_DRM_AMD_DC_DCN)
if (dp_get_link_encoding_format(&link_settings) == DP_8b_10b_ENCODING)
dp_set_fec_enable(link, fec_enable);
-#else
- dp_set_fec_enable(link, fec_enable);
-#endif
// during mode set we do DP_SET_POWER off then on, aux writes are lost
if (link->dpcd_sink_ext_caps.bits.oled == 1 ||
@@ -2495,9 +2577,7 @@ static void disable_link(struct dc_link *link, const struct link_resource *link_
if (dc_is_dp_signal(signal)) {
/* SST DP, eDP */
-#if defined(CONFIG_DRM_AMD_DC_DCN)
struct dc_link_settings link_settings = link->cur_link_settings;
-#endif
if (dc_is_dp_sst_signal(signal))
dp_disable_link_phy(link, link_res, signal);
else
@@ -2505,15 +2585,10 @@ static void disable_link(struct dc_link *link, const struct link_resource *link_
if (dc_is_dp_sst_signal(signal) ||
link->mst_stream_alloc_table.stream_count == 0) {
-#if defined(CONFIG_DRM_AMD_DC_DCN)
if (dp_get_link_encoding_format(&link_settings) == DP_8b_10b_ENCODING) {
dp_set_fec_enable(link, false);
dp_set_fec_ready(link, link_res, false);
}
-#else
- dp_set_fec_enable(link, false);
- dp_set_fec_ready(link, link_res, false);
-#endif
}
} else {
if (signal != SIGNAL_TYPE_VIRTUAL)
@@ -2696,72 +2771,74 @@ static bool dp_active_dongle_validate_timing(
break;
}
-#if defined(CONFIG_DRM_AMD_DC_DCN)
if (dpcd_caps->dongle_type == DISPLAY_DONGLE_DP_HDMI_CONVERTER &&
dongle_caps->extendedCapValid == true) {
-#else
- if (dpcd_caps->dongle_type != DISPLAY_DONGLE_DP_HDMI_CONVERTER ||
- dongle_caps->extendedCapValid == false)
- return true;
-#endif
-
- /* Check Pixel Encoding */
- switch (timing->pixel_encoding) {
- case PIXEL_ENCODING_RGB:
- case PIXEL_ENCODING_YCBCR444:
- break;
- case PIXEL_ENCODING_YCBCR422:
- if (!dongle_caps->is_dp_hdmi_ycbcr422_pass_through)
- return false;
- break;
- case PIXEL_ENCODING_YCBCR420:
- if (!dongle_caps->is_dp_hdmi_ycbcr420_pass_through)
+ /* Check Pixel Encoding */
+ switch (timing->pixel_encoding) {
+ case PIXEL_ENCODING_RGB:
+ case PIXEL_ENCODING_YCBCR444:
+ break;
+ case PIXEL_ENCODING_YCBCR422:
+ if (!dongle_caps->is_dp_hdmi_ycbcr422_pass_through)
+ return false;
+ break;
+ case PIXEL_ENCODING_YCBCR420:
+ if (!dongle_caps->is_dp_hdmi_ycbcr420_pass_through)
+ return false;
+ break;
+ default:
+ /* Invalid Pixel Encoding*/
return false;
- break;
- default:
- /* Invalid Pixel Encoding*/
- return false;
- }
+ }
- switch (timing->display_color_depth) {
- case COLOR_DEPTH_666:
- case COLOR_DEPTH_888:
- /*888 and 666 should always be supported*/
- break;
- case COLOR_DEPTH_101010:
- if (dongle_caps->dp_hdmi_max_bpc < 10)
+ switch (timing->display_color_depth) {
+ case COLOR_DEPTH_666:
+ case COLOR_DEPTH_888:
+ /*888 and 666 should always be supported*/
+ break;
+ case COLOR_DEPTH_101010:
+ if (dongle_caps->dp_hdmi_max_bpc < 10)
+ return false;
+ break;
+ case COLOR_DEPTH_121212:
+ if (dongle_caps->dp_hdmi_max_bpc < 12)
+ return false;
+ break;
+ case COLOR_DEPTH_141414:
+ case COLOR_DEPTH_161616:
+ default:
+ /* These color depths are currently not supported */
return false;
- break;
- case COLOR_DEPTH_121212:
- if (dongle_caps->dp_hdmi_max_bpc < 12)
+ }
+
+ /* Check 3D format */
+ switch (timing->timing_3d_format) {
+ case TIMING_3D_FORMAT_NONE:
+ case TIMING_3D_FORMAT_FRAME_ALTERNATE:
+ /*Only frame alternate 3D is supported on active dongle*/
+ break;
+ default:
+ /*other 3D formats are not supported due to bad infoframe translation */
return false;
- break;
- case COLOR_DEPTH_141414:
- case COLOR_DEPTH_161616:
- default:
- /* These color depths are currently not supported */
- return false;
- }
+ }
#if defined(CONFIG_DRM_AMD_DC_DCN)
- if (dongle_caps->dp_hdmi_frl_max_link_bw_in_kbps > 0) { // DP to HDMI FRL converter
- struct dc_crtc_timing outputTiming = *timing;
+ if (dongle_caps->dp_hdmi_frl_max_link_bw_in_kbps > 0) { // DP to HDMI FRL converter
+ struct dc_crtc_timing outputTiming = *timing;
- if (timing->flags.DSC && !timing->dsc_cfg.is_frl)
- /* DP input has DSC, HDMI FRL output doesn't have DSC, remove DSC from output timing */
- outputTiming.flags.DSC = 0;
- if (dc_bandwidth_in_kbps_from_timing(&outputTiming) > dongle_caps->dp_hdmi_frl_max_link_bw_in_kbps)
- return false;
- } else { // DP to HDMI TMDS converter
+ if (timing->flags.DSC && !timing->dsc_cfg.is_frl)
+ /* DP input has DSC, HDMI FRL output doesn't have DSC, remove DSC from output timing */
+ outputTiming.flags.DSC = 0;
+ if (dc_bandwidth_in_kbps_from_timing(&outputTiming) > dongle_caps->dp_hdmi_frl_max_link_bw_in_kbps)
+ return false;
+ } else { // DP to HDMI TMDS converter
+ if (get_timing_pixel_clock_100hz(timing) > (dongle_caps->dp_hdmi_max_pixel_clk_in_khz * 10))
+ return false;
+ }
+#else
if (get_timing_pixel_clock_100hz(timing) > (dongle_caps->dp_hdmi_max_pixel_clk_in_khz * 10))
return false;
- }
-#else
- if (get_timing_pixel_clock_100hz(timing) > (dongle_caps->dp_hdmi_max_pixel_clk_in_khz * 10))
- return false;
#endif
-
-#if defined(CONFIG_DRM_AMD_DC_DCN)
}
if (dpcd_caps->channel_coding_cap.bits.DP_128b_132b_SUPPORTED == 0 &&
@@ -2842,7 +2919,6 @@ static bool dp_active_dongle_validate_timing(
return false;
}
}
-#endif
return true;
}
@@ -3197,9 +3273,16 @@ bool dc_link_setup_psr(struct dc_link *link,
/*skip power down the single pipe since it blocks the cstate*/
#if defined(CONFIG_DRM_AMD_DC_DCN)
if (link->ctx->asic_id.chip_family >= FAMILY_RV) {
- psr_context->psr_level.bits.SKIP_CRTC_DISABLE = true;
- if (link->ctx->asic_id.chip_family == FAMILY_YELLOW_CARP && !dc->debug.disable_z10)
- psr_context->psr_level.bits.SKIP_CRTC_DISABLE = false;
+ switch(link->ctx->asic_id.chip_family) {
+ case FAMILY_YELLOW_CARP:
+ case AMDGPU_FAMILY_GC_10_3_6:
+ if(!dc->debug.disable_z10)
+ psr_context->psr_level.bits.SKIP_CRTC_DISABLE = false;
+ break;
+ default:
+ psr_context->psr_level.bits.SKIP_CRTC_DISABLE = true;
+ break;
+ }
}
#else
if (link->ctx->asic_id.chip_family >= FAMILY_RV)
@@ -3315,9 +3398,7 @@ static struct fixed31_32 get_pbn_from_timing(struct pipe_ctx *pipe_ctx)
static void update_mst_stream_alloc_table(
struct dc_link *link,
struct stream_encoder *stream_enc,
-#if defined(CONFIG_DRM_AMD_DC_DCN)
struct hpo_dp_stream_encoder *hpo_dp_stream_enc, // TODO: Rename stream_enc to dio_stream_enc?
-#endif
const struct dp_mst_stream_allocation_table *proposed_table)
{
struct link_mst_stream_allocation work_table[MAX_CONTROLLER_NUM] = { 0 };
@@ -3353,9 +3434,7 @@ static void update_mst_stream_alloc_table(
work_table[i].slot_count =
proposed_table->stream_allocations[i].slot_count;
work_table[i].stream_enc = stream_enc;
-#if defined(CONFIG_DRM_AMD_DC_DCN)
work_table[i].hpo_dp_stream_enc = hpo_dp_stream_enc;
-#endif
}
}
@@ -3366,7 +3445,7 @@ static void update_mst_stream_alloc_table(
link->mst_stream_alloc_table.stream_allocations[i] =
work_table[i];
}
-#if defined(CONFIG_DRM_AMD_DC_DCN)
+
static void dc_log_vcp_x_y(const struct dc_link *link, struct fixed31_32 avg_time_slots_per_mtp)
{
const uint32_t VCP_Y_PRECISION = 1000;
@@ -3402,6 +3481,8 @@ static enum dc_status dc_link_update_sst_payload(struct pipe_ctx *pipe_ctx,
struct hpo_dp_stream_encoder *hpo_dp_stream_encoder = pipe_ctx->stream_res.hpo_dp_stream_enc;
struct link_mst_stream_allocation_table proposed_table = {0};
struct fixed31_32 avg_time_slots_per_mtp;
+ const struct dc_link_settings empty_link_settings = {0};
+ const struct link_hwss *link_hwss = get_link_hwss(link, &pipe_ctx->link_res);
DC_LOGGER_INIT(link->ctx->logger);
/* slot X.Y for SST payload deallocate */
@@ -3410,10 +3491,13 @@ static enum dc_status dc_link_update_sst_payload(struct pipe_ctx *pipe_ctx,
dc_log_vcp_x_y(link, avg_time_slots_per_mtp);
- hpo_dp_link_encoder->funcs->set_throttled_vcp_size(
- hpo_dp_link_encoder,
- hpo_dp_stream_encoder->inst,
- avg_time_slots_per_mtp);
+ if (link_hwss->ext.set_throttled_vcp_size)
+ link_hwss->ext.set_throttled_vcp_size(pipe_ctx,
+ avg_time_slots_per_mtp);
+ if (link_hwss->ext.set_hblank_min_symbol_width)
+ link_hwss->ext.set_hblank_min_symbol_width(pipe_ctx,
+ &empty_link_settings,
+ avg_time_slots_per_mtp);
}
/* calculate VC payload and update branch with new payload allocation table*/
@@ -3457,10 +3541,13 @@ static enum dc_status dc_link_update_sst_payload(struct pipe_ctx *pipe_ctx,
dc_log_vcp_x_y(link, avg_time_slots_per_mtp);
- hpo_dp_link_encoder->funcs->set_throttled_vcp_size(
- hpo_dp_link_encoder,
- hpo_dp_stream_encoder->inst,
- avg_time_slots_per_mtp);
+ if (link_hwss->ext.set_throttled_vcp_size)
+ link_hwss->ext.set_throttled_vcp_size(pipe_ctx,
+ avg_time_slots_per_mtp);
+ if (link_hwss->ext.set_hblank_min_symbol_width)
+ link_hwss->ext.set_hblank_min_symbol_width(pipe_ctx,
+ &link->cur_link_settings,
+ avg_time_slots_per_mtp);
}
/* Always return DC_OK.
@@ -3468,7 +3555,6 @@ static enum dc_status dc_link_update_sst_payload(struct pipe_ctx *pipe_ctx,
*/
return DC_OK;
}
-#endif
/* convert link_mst_stream_alloc_table to dm dp_mst_stream_alloc_table
* because stream_encoder is not exposed to dm
@@ -3478,24 +3564,17 @@ enum dc_status dc_link_allocate_mst_payload(struct pipe_ctx *pipe_ctx)
struct dc_stream_state *stream = pipe_ctx->stream;
struct dc_link *link = stream->link;
struct link_encoder *link_encoder = NULL;
- struct stream_encoder *stream_encoder = pipe_ctx->stream_res.stream_enc;
-#if defined(CONFIG_DRM_AMD_DC_DCN)
struct hpo_dp_link_encoder *hpo_dp_link_encoder = pipe_ctx->link_res.hpo_dp_link_enc;
- struct hpo_dp_stream_encoder *hpo_dp_stream_encoder = pipe_ctx->stream_res.hpo_dp_stream_enc;
-#endif
struct dp_mst_stream_allocation_table proposed_table = {0};
struct fixed31_32 avg_time_slots_per_mtp;
struct fixed31_32 pbn;
struct fixed31_32 pbn_per_slot;
int i;
enum act_return_status ret;
+ const struct link_hwss *link_hwss = get_link_hwss(link, &pipe_ctx->link_res);
DC_LOGGER_INIT(link->ctx->logger);
- /* Link encoder may have been dynamically assigned to non-physical display endpoint. */
- if (link->ep_type == DISPLAY_ENDPOINT_PHY)
- link_encoder = link->link_enc;
- else if (link->dc->res_pool->funcs->link_encs_assign)
- link_encoder = link_enc_cfg_get_link_enc_used_by_stream(pipe_ctx->stream->ctx->dc, stream);
+ link_encoder = link_enc_cfg_get_link_enc(link);
ASSERT(link_encoder);
/* enable_link_dp_mst already check link->enabled_stream_count
@@ -3508,17 +3587,12 @@ enum dc_status dc_link_allocate_mst_payload(struct pipe_ctx *pipe_ctx)
stream->ctx,
stream,
&proposed_table,
- true)) {
+ true))
update_mst_stream_alloc_table(
-#if defined(CONFIG_DRM_AMD_DC_DCN)
link,
pipe_ctx->stream_res.stream_enc,
pipe_ctx->stream_res.hpo_dp_stream_enc,
&proposed_table);
-#else
- link, pipe_ctx->stream_res.stream_enc, &proposed_table);
-#endif
- }
else
DC_LOG_WARNING("Failed to update"
"MST allocation table for"
@@ -3531,7 +3605,6 @@ enum dc_status dc_link_allocate_mst_payload(struct pipe_ctx *pipe_ctx)
link->mst_stream_alloc_table.stream_count);
for (i = 0; i < MAX_CONTROLLER_NUM; i++) {
-#if defined(CONFIG_DRM_AMD_DC_DCN)
DC_LOG_MST("stream_enc[%d]: %p "
"stream[%d].hpo_dp_stream_enc: %p "
"stream[%d].vcp_id: %d "
@@ -3544,17 +3617,6 @@ enum dc_status dc_link_allocate_mst_payload(struct pipe_ctx *pipe_ctx)
link->mst_stream_alloc_table.stream_allocations[i].vcp_id,
i,
link->mst_stream_alloc_table.stream_allocations[i].slot_count);
-#else
- DC_LOG_MST("stream_enc[%d]: %p "
- "stream[%d].vcp_id: %d "
- "stream[%d].slot_count: %d\n",
- i,
- (void *) link->mst_stream_alloc_table.stream_allocations[i].stream_enc,
- i,
- link->mst_stream_alloc_table.stream_allocations[i].vcp_id,
- i,
- link->mst_stream_alloc_table.stream_allocations[i].slot_count);
-#endif
}
ASSERT(proposed_table.stream_count > 0);
@@ -3574,7 +3636,6 @@ enum dc_status dc_link_allocate_mst_payload(struct pipe_ctx *pipe_ctx)
}
/* program DP source TX for payload */
-#if defined(CONFIG_DRM_AMD_DC_DCN)
switch (dp_get_link_encoding_format(&link->cur_link_settings)) {
case DP_8b_10b_ENCODING:
link_encoder->funcs->update_mst_stream_allocation_table(
@@ -3590,11 +3651,6 @@ enum dc_status dc_link_allocate_mst_payload(struct pipe_ctx *pipe_ctx)
DC_LOG_ERROR("Failure: unknown encoding format\n");
return DC_ERROR_UNEXPECTED;
}
-#else
- link_encoder->funcs->update_mst_stream_allocation_table(
- link_encoder,
- &link->mst_stream_alloc_table);
-#endif
/* send down message */
ret = dm_helpers_dp_mst_poll_for_allocation_change_trigger(
@@ -3617,34 +3673,19 @@ enum dc_status dc_link_allocate_mst_payload(struct pipe_ctx *pipe_ctx)
pbn = get_pbn_from_timing(pipe_ctx);
avg_time_slots_per_mtp = dc_fixpt_div(pbn, pbn_per_slot);
-#if defined(CONFIG_DRM_AMD_DC_DCN)
- switch (dp_get_link_encoding_format(&link->cur_link_settings)) {
- case DP_8b_10b_ENCODING:
- stream_encoder->funcs->set_throttled_vcp_size(
- stream_encoder,
- avg_time_slots_per_mtp);
- break;
- case DP_128b_132b_ENCODING:
- hpo_dp_link_encoder->funcs->set_throttled_vcp_size(
- hpo_dp_link_encoder,
- hpo_dp_stream_encoder->inst,
+ dc_log_vcp_x_y(link, avg_time_slots_per_mtp);
+
+ if (link_hwss->ext.set_throttled_vcp_size)
+ link_hwss->ext.set_throttled_vcp_size(pipe_ctx, avg_time_slots_per_mtp);
+ if (link_hwss->ext.set_hblank_min_symbol_width)
+ link_hwss->ext.set_hblank_min_symbol_width(pipe_ctx,
+ &link->cur_link_settings,
avg_time_slots_per_mtp);
- break;
- case DP_UNKNOWN_ENCODING:
- DC_LOG_ERROR("Failure: unknown encoding format\n");
- return DC_ERROR_UNEXPECTED;
- }
-#else
- stream_encoder->funcs->set_throttled_vcp_size(
- stream_encoder,
- avg_time_slots_per_mtp);
-#endif
return DC_OK;
}
-#if defined(CONFIG_DRM_AMD_DC_DCN)
enum dc_status dc_link_reduce_mst_payload(struct pipe_ctx *pipe_ctx, uint32_t bw_in_kbps)
{
struct dc_stream_state *stream = pipe_ctx->stream;
@@ -3653,10 +3694,10 @@ enum dc_status dc_link_reduce_mst_payload(struct pipe_ctx *pipe_ctx, uint32_t bw
struct fixed31_32 pbn;
struct fixed31_32 pbn_per_slot;
struct link_encoder *link_encoder = link->link_enc;
- struct stream_encoder *stream_encoder = pipe_ctx->stream_res.stream_enc;
struct dp_mst_stream_allocation_table proposed_table = {0};
uint8_t i;
enum act_return_status ret;
+ const struct link_hwss *link_hwss = get_link_hwss(link, &pipe_ctx->link_res);
DC_LOGGER_INIT(link->ctx->logger);
/* decrease throttled vcp size */
@@ -3664,8 +3705,11 @@ enum dc_status dc_link_reduce_mst_payload(struct pipe_ctx *pipe_ctx, uint32_t bw
pbn = get_pbn_from_bw_in_kbps(bw_in_kbps);
avg_time_slots_per_mtp = dc_fixpt_div(pbn, pbn_per_slot);
- stream_encoder->funcs->set_throttled_vcp_size(
- stream_encoder,
+ if (link_hwss->ext.set_throttled_vcp_size)
+ link_hwss->ext.set_throttled_vcp_size(pipe_ctx, avg_time_slots_per_mtp);
+ if (link_hwss->ext.set_hblank_min_symbol_width)
+ link_hwss->ext.set_hblank_min_symbol_width(pipe_ctx,
+ &link->cur_link_settings,
avg_time_slots_per_mtp);
/* send ALLOCATE_PAYLOAD sideband message with updated pbn */
@@ -3733,10 +3777,10 @@ enum dc_status dc_link_increase_mst_payload(struct pipe_ctx *pipe_ctx, uint32_t
struct fixed31_32 pbn;
struct fixed31_32 pbn_per_slot;
struct link_encoder *link_encoder = link->link_enc;
- struct stream_encoder *stream_encoder = pipe_ctx->stream_res.stream_enc;
struct dp_mst_stream_allocation_table proposed_table = {0};
uint8_t i;
enum act_return_status ret;
+ const struct link_hwss *link_hwss = get_link_hwss(link, &pipe_ctx->link_res);
DC_LOGGER_INIT(link->ctx->logger);
/* notify immediate branch device table update */
@@ -3795,35 +3839,31 @@ enum dc_status dc_link_increase_mst_payload(struct pipe_ctx *pipe_ctx, uint32_t
pbn_per_slot = get_pbn_per_slot(stream);
avg_time_slots_per_mtp = dc_fixpt_div(pbn, pbn_per_slot);
- stream_encoder->funcs->set_throttled_vcp_size(
- stream_encoder,
+ if (link_hwss->ext.set_throttled_vcp_size)
+ link_hwss->ext.set_throttled_vcp_size(pipe_ctx, avg_time_slots_per_mtp);
+ if (link_hwss->ext.set_hblank_min_symbol_width)
+ link_hwss->ext.set_hblank_min_symbol_width(pipe_ctx,
+ &link->cur_link_settings,
avg_time_slots_per_mtp);
return DC_OK;
}
-#endif
static enum dc_status deallocate_mst_payload(struct pipe_ctx *pipe_ctx)
{
struct dc_stream_state *stream = pipe_ctx->stream;
struct dc_link *link = stream->link;
struct link_encoder *link_encoder = NULL;
- struct stream_encoder *stream_encoder = pipe_ctx->stream_res.stream_enc;
-#if defined(CONFIG_DRM_AMD_DC_DCN)
struct hpo_dp_link_encoder *hpo_dp_link_encoder = pipe_ctx->link_res.hpo_dp_link_enc;
- struct hpo_dp_stream_encoder *hpo_dp_stream_encoder = pipe_ctx->stream_res.hpo_dp_stream_enc;
-#endif
struct dp_mst_stream_allocation_table proposed_table = {0};
struct fixed31_32 avg_time_slots_per_mtp = dc_fixpt_from_int(0);
int i;
bool mst_mode = (link->type == dc_connection_mst_branch);
+ const struct link_hwss *link_hwss = get_link_hwss(link, &pipe_ctx->link_res);
+ const struct dc_link_settings empty_link_settings = {0};
DC_LOGGER_INIT(link->ctx->logger);
- /* Link encoder may have been dynamically assigned to non-physical display endpoint. */
- if (link->ep_type == DISPLAY_ENDPOINT_PHY)
- link_encoder = link->link_enc;
- else if (link->dc->res_pool->funcs->link_encs_assign)
- link_encoder = link_enc_cfg_get_link_enc_used_by_stream(pipe_ctx->stream->ctx->dc, stream);
+ link_encoder = link_enc_cfg_get_link_enc(link);
ASSERT(link_encoder);
/* deallocate_mst_payload is called before disable link. When mode or
@@ -3834,28 +3874,12 @@ static enum dc_status deallocate_mst_payload(struct pipe_ctx *pipe_ctx)
*/
/* slot X.Y */
-#if defined(CONFIG_DRM_AMD_DC_DCN)
- switch (dp_get_link_encoding_format(&link->cur_link_settings)) {
- case DP_8b_10b_ENCODING:
- stream_encoder->funcs->set_throttled_vcp_size(
- stream_encoder,
- avg_time_slots_per_mtp);
- break;
- case DP_128b_132b_ENCODING:
- hpo_dp_link_encoder->funcs->set_throttled_vcp_size(
- hpo_dp_link_encoder,
- hpo_dp_stream_encoder->inst,
+ if (link_hwss->ext.set_throttled_vcp_size)
+ link_hwss->ext.set_throttled_vcp_size(pipe_ctx, avg_time_slots_per_mtp);
+ if (link_hwss->ext.set_hblank_min_symbol_width)
+ link_hwss->ext.set_hblank_min_symbol_width(pipe_ctx,
+ &empty_link_settings,
avg_time_slots_per_mtp);
- break;
- case DP_UNKNOWN_ENCODING:
- DC_LOG_ERROR("Failure: unknown encoding format\n");
- return DC_ERROR_UNEXPECTED;
- }
-#else
- stream_encoder->funcs->set_throttled_vcp_size(
- stream_encoder,
- avg_time_slots_per_mtp);
-#endif
/* TODO: which component is responsible for remove payload table? */
if (mst_mode) {
@@ -3865,16 +3889,11 @@ static enum dc_status deallocate_mst_payload(struct pipe_ctx *pipe_ctx)
&proposed_table,
false)) {
-#if defined(CONFIG_DRM_AMD_DC_DCN)
update_mst_stream_alloc_table(
link,
pipe_ctx->stream_res.stream_enc,
pipe_ctx->stream_res.hpo_dp_stream_enc,
&proposed_table);
-#else
- update_mst_stream_alloc_table(
- link, pipe_ctx->stream_res.stream_enc, &proposed_table);
-#endif
}
else {
DC_LOG_WARNING("Failed to update"
@@ -3890,7 +3909,6 @@ static enum dc_status deallocate_mst_payload(struct pipe_ctx *pipe_ctx)
link->mst_stream_alloc_table.stream_count);
for (i = 0; i < MAX_CONTROLLER_NUM; i++) {
-#if defined(CONFIG_DRM_AMD_DC_DCN)
DC_LOG_MST("stream_enc[%d]: %p "
"stream[%d].hpo_dp_stream_enc: %p "
"stream[%d].vcp_id: %d "
@@ -3903,17 +3921,6 @@ static enum dc_status deallocate_mst_payload(struct pipe_ctx *pipe_ctx)
link->mst_stream_alloc_table.stream_allocations[i].vcp_id,
i,
link->mst_stream_alloc_table.stream_allocations[i].slot_count);
-#else
- DC_LOG_MST("stream_enc[%d]: %p "
- "stream[%d].vcp_id: %d "
- "stream[%d].slot_count: %d\n",
- i,
- (void *) link->mst_stream_alloc_table.stream_allocations[i].stream_enc,
- i,
- link->mst_stream_alloc_table.stream_allocations[i].vcp_id,
- i,
- link->mst_stream_alloc_table.stream_allocations[i].slot_count);
-#endif
}
if (link->ep_type == DISPLAY_ENDPOINT_USB4_DPIA) {
@@ -3930,7 +3937,6 @@ static enum dc_status deallocate_mst_payload(struct pipe_ctx *pipe_ctx)
status, mst_alloc_slots, prev_mst_slots_in_use);
}
-#if defined(CONFIG_DRM_AMD_DC_DCN)
switch (dp_get_link_encoding_format(&link->cur_link_settings)) {
case DP_8b_10b_ENCODING:
link_encoder->funcs->update_mst_stream_allocation_table(
@@ -3943,14 +3949,9 @@ static enum dc_status deallocate_mst_payload(struct pipe_ctx *pipe_ctx)
&link->mst_stream_alloc_table);
break;
case DP_UNKNOWN_ENCODING:
- DC_LOG_ERROR("Failure: unknown encoding format\n");
+ DC_LOG_DEBUG("Unknown encoding format\n");
return DC_ERROR_UNEXPECTED;
}
-#else
- link_encoder->funcs->update_mst_stream_allocation_table(
- link_encoder,
- &link->mst_stream_alloc_table);
-#endif
if (mst_mode) {
dm_helpers_dp_mst_poll_for_allocation_change_trigger(
@@ -3979,13 +3980,7 @@ static void update_psp_stream_config(struct pipe_ctx *pipe_ctx, bool dpms_off)
if (cp_psp == NULL || cp_psp->funcs.update_stream_config == NULL)
return;
- if (pipe_ctx->stream->link->ep_type == DISPLAY_ENDPOINT_PHY)
- link_enc = pipe_ctx->stream->link->link_enc;
- else if (pipe_ctx->stream->link->ep_type == DISPLAY_ENDPOINT_USB4_DPIA &&
- pipe_ctx->stream->link->dc->res_pool->funcs->link_encs_assign)
- link_enc = link_enc_cfg_get_link_enc_used_by_stream(
- pipe_ctx->stream->ctx->dc,
- pipe_ctx->stream);
+ link_enc = link_enc_cfg_get_link_enc(pipe_ctx->stream->link);
ASSERT(link_enc);
if (link_enc == NULL)
return;
@@ -3998,21 +3993,18 @@ static void update_psp_stream_config(struct pipe_ctx *pipe_ctx, bool dpms_off)
/* stream encoder index */
config.stream_enc_idx = pipe_ctx->stream_res.stream_enc->id - ENGINE_ID_DIGA;
-#if defined(CONFIG_DRM_AMD_DC_DCN)
if (is_dp_128b_132b_signal(pipe_ctx))
config.stream_enc_idx =
pipe_ctx->stream_res.hpo_dp_stream_enc->id - ENGINE_ID_HPO_DP_0;
-#endif
/* dig back end */
config.dig_be = pipe_ctx->stream->link->link_enc_hw_inst;
/* link encoder index */
config.link_enc_idx = link_enc->transmitter - TRANSMITTER_UNIPHY_A;
-#if defined(CONFIG_DRM_AMD_DC_DCN)
if (is_dp_128b_132b_signal(pipe_ctx))
config.link_enc_idx = pipe_ctx->link_res.hpo_dp_link_enc->inst;
-#endif
+
/* dio output index */
config.dio_output_idx = link_enc->transmitter - TRANSMITTER_UNIPHY_A;
@@ -4027,9 +4019,7 @@ static void update_psp_stream_config(struct pipe_ctx *pipe_ctx, bool dpms_off)
config.assr_enabled = (panel_mode == DP_PANEL_MODE_EDP) ? 1 : 0;
config.mst_enabled = (pipe_ctx->stream->signal ==
SIGNAL_TYPE_DISPLAY_PORT_MST) ? 1 : 0;
-#if defined(CONFIG_DRM_AMD_DC_DCN)
config.dp2_enabled = is_dp_128b_132b_signal(pipe_ctx) ? 1 : 0;
-#endif
config.usb4_enabled = (pipe_ctx->stream->link->ep_type == DISPLAY_ENDPOINT_USB4_DPIA) ?
1 : 0;
config.dpms_off = dpms_off;
@@ -4041,7 +4031,6 @@ static void update_psp_stream_config(struct pipe_ctx *pipe_ctx, bool dpms_off)
}
#endif
-#if defined(CONFIG_DRM_AMD_DC_DCN)
static void fpga_dp_hpo_enable_link_and_stream(struct dc_state *state, struct pipe_ctx *pipe_ctx)
{
struct dc *dc = pipe_ctx->stream->ctx->dc;
@@ -4050,15 +4039,17 @@ static void fpga_dp_hpo_enable_link_and_stream(struct dc_state *state, struct pi
struct fixed31_32 avg_time_slots_per_mtp;
uint8_t req_slot_count = 0;
uint8_t vc_id = 1; /// VC ID always 1 for SST
-
struct dc_link_settings link_settings = {0};
+ const struct link_hwss *link_hwss = get_link_hwss(stream->link, &pipe_ctx->link_res);
DC_LOGGER_INIT(pipe_ctx->stream->ctx->logger);
decide_link_settings(stream, &link_settings);
stream->link->cur_link_settings = link_settings;
- /* Enable clock, Configure lane count, and Enable Link Encoder*/
- enable_dp_hpo_output(stream->link, &pipe_ctx->link_res, &stream->link->cur_link_settings);
+ if (link_hwss->ext.enable_dp_link_output)
+ link_hwss->ext.enable_dp_link_output(stream->link, &pipe_ctx->link_res,
+ stream->signal, pipe_ctx->clock_source->id,
+ &link_settings);
#ifdef DIAGS_BUILD
/* Workaround for FPGA HPO capture DP link data:
@@ -4112,16 +4103,11 @@ static void fpga_dp_hpo_enable_link_and_stream(struct dc_state *state, struct pi
pipe_ctx->link_res.hpo_dp_link_enc,
&proposed_table);
- pipe_ctx->link_res.hpo_dp_link_enc->funcs->set_throttled_vcp_size(
- pipe_ctx->link_res.hpo_dp_link_enc,
- pipe_ctx->stream_res.hpo_dp_stream_enc->inst,
- avg_time_slots_per_mtp);
-
-
+ if (link_hwss->ext.set_throttled_vcp_size)
+ link_hwss->ext.set_throttled_vcp_size(pipe_ctx, avg_time_slots_per_mtp);
dc->hwss.unblank_stream(pipe_ctx, &stream->link->cur_link_settings);
}
-#endif
void core_link_enable_stream(
struct dc_state *state,
@@ -4132,31 +4118,32 @@ void core_link_enable_stream(
struct dc_link *link = stream->sink->link;
enum dc_status status;
struct link_encoder *link_enc;
-#if defined(CONFIG_DRM_AMD_DC_DCN)
enum otg_out_mux_dest otg_out_dest = OUT_MUX_DIO;
struct vpg *vpg = pipe_ctx->stream_res.stream_enc->vpg;
if (is_dp_128b_132b_signal(pipe_ctx))
vpg = pipe_ctx->stream_res.hpo_dp_stream_enc->vpg;
-#endif
+
DC_LOGGER_INIT(pipe_ctx->stream->ctx->logger);
+ if (pipe_ctx->stream->sink) {
+ if (pipe_ctx->stream->sink->sink_signal != SIGNAL_TYPE_VIRTUAL &&
+ pipe_ctx->stream->sink->sink_signal != SIGNAL_TYPE_NONE) {
+ DC_LOG_DC("%s pipe_ctx dispname=%s signal=%x\n", __func__,
+ pipe_ctx->stream->sink->edid_caps.display_name,
+ pipe_ctx->stream->signal);
+ }
+ }
+
if (!IS_DIAG_DC(dc->ctx->dce_environment) &&
dc_is_virtual_signal(pipe_ctx->stream->signal))
return;
- if (dc->res_pool->funcs->link_encs_assign && stream->link->ep_type != DISPLAY_ENDPOINT_PHY)
- link_enc = link_enc_cfg_get_link_enc_used_by_stream(dc, stream);
- else
- link_enc = stream->link->link_enc;
+ link_enc = link_enc_cfg_get_link_enc(link);
ASSERT(link_enc);
-#if defined(CONFIG_DRM_AMD_DC_DCN)
if (!dc_is_virtual_signal(pipe_ctx->stream->signal)
&& !is_dp_128b_132b_signal(pipe_ctx)) {
-#else
- if (!dc_is_virtual_signal(pipe_ctx->stream->signal)) {
-#endif
if (link_enc)
link_enc->funcs->setup(
link_enc,
@@ -4167,7 +4154,6 @@ void core_link_enable_stream(
stream->timing.timing_3d_format != TIMING_3D_FORMAT_NONE);
}
-#if defined(CONFIG_DRM_AMD_DC_DCN)
if (is_dp_128b_132b_signal(pipe_ctx)) {
pipe_ctx->stream_res.hpo_dp_stream_enc->funcs->set_stream_attribute(
pipe_ctx->stream_res.hpo_dp_stream_enc,
@@ -4185,14 +4171,6 @@ void core_link_enable_stream(
stream->use_vsc_sdp_for_colorimetry,
stream->link->dpcd_caps.dprx_feature.bits.SST_SPLIT_SDP_CAP);
}
-#else
- pipe_ctx->stream_res.stream_enc->funcs->dp_set_stream_attribute(
- pipe_ctx->stream_res.stream_enc,
- &stream->timing,
- stream->output_color_space,
- stream->use_vsc_sdp_for_colorimetry,
- stream->link->dpcd_caps.dprx_feature.bits.SST_SPLIT_SDP_CAP);
-#endif
if (dc_is_dp_signal(pipe_ctx->stream->signal))
dp_source_sequence_trace(link, DPCD_SOURCE_SEQ_AFTER_DP_STREAM_ATTR);
@@ -4206,10 +4184,8 @@ void core_link_enable_stream(
pipe_ctx->stream->link->link_state_valid = true;
-#if defined(CONFIG_DRM_AMD_DC_DCN)
if (pipe_ctx->stream_res.tg->funcs->set_out_mux)
pipe_ctx->stream_res.tg->funcs->set_out_mux(pipe_ctx->stream_res.tg, otg_out_dest);
-#endif
if (dc_is_dvi_signal(pipe_ctx->stream->signal))
pipe_ctx->stream_res.stream_enc->funcs->dvi_set_stream_attribute(
@@ -4229,11 +4205,9 @@ void core_link_enable_stream(
pipe_ctx->stream->apply_edp_fast_boot_optimization = false;
-#if defined(CONFIG_DRM_AMD_DC_DCN)
// Enable VPG before building infoframe
if (vpg && vpg->funcs->vpg_poweron)
vpg->funcs->vpg_poweron(vpg);
-#endif
resource_build_info_frame(pipe_ctx);
dc->hwss.update_info_frame(pipe_ctx);
@@ -4319,12 +4293,8 @@ void core_link_enable_stream(
* as a workaround for the incorrect value being applied
* from transmitter control.
*/
-#if defined(CONFIG_DRM_AMD_DC_DCN)
if (!(dc_is_virtual_signal(pipe_ctx->stream->signal) ||
is_dp_128b_132b_signal(pipe_ctx)))
-#else
- if (!dc_is_virtual_signal(pipe_ctx->stream->signal))
-#endif
if (link_enc)
link_enc->funcs->setup(
link_enc,
@@ -4343,11 +4313,9 @@ void core_link_enable_stream(
if (pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST)
dc_link_allocate_mst_payload(pipe_ctx);
-#if defined(CONFIG_DRM_AMD_DC_DCN)
else if (pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT &&
is_dp_128b_132b_signal(pipe_ctx))
dc_link_update_sst_payload(pipe_ctx, true);
-#endif
dc->hwss.unblank_stream(pipe_ctx,
&pipe_ctx->stream->link->cur_link_settings);
@@ -4364,11 +4332,9 @@ void core_link_enable_stream(
dc->hwss.enable_audio_stream(pipe_ctx);
} else { // if (IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment))
-#if defined(CONFIG_DRM_AMD_DC_DCN)
if (is_dp_128b_132b_signal(pipe_ctx)) {
fpga_dp_hpo_enable_link_and_stream(state, pipe_ctx);
}
-#endif
if (dc_is_dp_signal(pipe_ctx->stream->signal) ||
dc_is_virtual_signal(pipe_ctx->stream->signal))
dp_set_dsc_enable(pipe_ctx, true);
@@ -4385,12 +4351,21 @@ void core_link_disable_stream(struct pipe_ctx *pipe_ctx)
struct dc *dc = pipe_ctx->stream->ctx->dc;
struct dc_stream_state *stream = pipe_ctx->stream;
struct dc_link *link = stream->sink->link;
-#if defined(CONFIG_DRM_AMD_DC_DCN)
struct vpg *vpg = pipe_ctx->stream_res.stream_enc->vpg;
if (is_dp_128b_132b_signal(pipe_ctx))
vpg = pipe_ctx->stream_res.hpo_dp_stream_enc->vpg;
-#endif
+
+ DC_LOGGER_INIT(pipe_ctx->stream->ctx->logger);
+
+ if (pipe_ctx->stream->sink) {
+ if (pipe_ctx->stream->sink->sink_signal != SIGNAL_TYPE_VIRTUAL &&
+ pipe_ctx->stream->sink->sink_signal != SIGNAL_TYPE_NONE) {
+ DC_LOG_DC("%s pipe_ctx dispname=%s signal=%x\n", __func__,
+ pipe_ctx->stream->sink->edid_caps.display_name,
+ pipe_ctx->stream->signal);
+ }
+ }
if (!IS_DIAG_DC(dc->ctx->dce_environment) &&
dc_is_virtual_signal(pipe_ctx->stream->signal))
@@ -4410,11 +4385,9 @@ void core_link_disable_stream(struct pipe_ctx *pipe_ctx)
if (pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST)
deallocate_mst_payload(pipe_ctx);
-#if defined(CONFIG_DRM_AMD_DC_DCN)
else if (pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT &&
is_dp_128b_132b_signal(pipe_ctx))
dc_link_update_sst_payload(pipe_ctx, false);
-#endif
if (dc_is_hdmi_signal(pipe_ctx->stream->signal)) {
struct ext_hdmi_settings settings = {0};
@@ -4441,7 +4414,6 @@ void core_link_disable_stream(struct pipe_ctx *pipe_ctx)
}
}
-#if defined(CONFIG_DRM_AMD_DC_DCN)
if (pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT &&
!is_dp_128b_132b_signal(pipe_ctx)) {
@@ -4458,27 +4430,18 @@ void core_link_disable_stream(struct pipe_ctx *pipe_ctx)
dc->hwss.disable_stream(pipe_ctx);
disable_link(pipe_ctx->stream->link, &pipe_ctx->link_res, pipe_ctx->stream->signal);
}
-#else
- disable_link(pipe_ctx->stream->link, &pipe_ctx->link_res, pipe_ctx->stream->signal);
-
- dc->hwss.disable_stream(pipe_ctx);
-#endif
if (pipe_ctx->stream->timing.flags.DSC) {
if (dc_is_dp_signal(pipe_ctx->stream->signal))
dp_set_dsc_enable(pipe_ctx, false);
}
-#if defined(CONFIG_DRM_AMD_DC_DCN)
if (is_dp_128b_132b_signal(pipe_ctx)) {
if (pipe_ctx->stream_res.tg->funcs->set_out_mux)
pipe_ctx->stream_res.tg->funcs->set_out_mux(pipe_ctx->stream_res.tg, OUT_MUX_DIO);
}
-#endif
-#if defined(CONFIG_DRM_AMD_DC_DCN)
if (vpg && vpg->funcs->vpg_powerdown)
vpg->funcs->vpg_powerdown(vpg);
-#endif
}
void core_link_set_avmute(struct pipe_ctx *pipe_ctx, bool enable)
@@ -4542,22 +4505,17 @@ void dc_link_set_drive_settings(struct dc *dc,
{
int i;
- struct pipe_ctx *pipe = NULL;
- const struct link_resource *link_res;
+ struct link_resource link_res;
- link_res = dc_link_get_cur_link_res(link);
+ for (i = 0; i < dc->link_count; i++)
+ if (dc->links[i] == link)
+ break;
- for (i = 0; i < MAX_PIPES; i++) {
- pipe = &dc->current_state->res_ctx.pipe_ctx[i];
- if (pipe->stream && pipe->stream->link) {
- if (pipe->stream->link == link)
- break;
- }
- }
- if (pipe && link_res)
- dc_link_dp_set_drive_settings(pipe->stream->link, link_res, lt_settings);
- else
+ if (i >= dc->link_count)
ASSERT_CRITICAL(false);
+
+ dc_link_get_cur_link_res(link, &link_res);
+ dc_link_dp_set_drive_settings(dc->links[i], &link_res, lt_settings);
}
void dc_link_set_preferred_link_settings(struct dc *dc,
@@ -4617,11 +4575,9 @@ void dc_link_set_preferred_training_settings(struct dc *dc,
if (link_setting != NULL) {
link->preferred_link_setting = *link_setting;
-#if defined(CONFIG_DRM_AMD_DC_DCN)
if (dp_get_link_encoding_format(link_setting) == DP_128b_132b_ENCODING)
/* TODO: add dc update for acquiring link res */
skip_immediate_retrain = true;
-#endif
} else {
link->preferred_link_setting.lane_count = LANE_COUNT_UNKNOWN;
link->preferred_link_setting.link_rate = LINK_RATE_UNKNOWN;
@@ -4663,7 +4619,6 @@ uint32_t dc_link_bandwidth_kbps(
const struct dc_link *link,
const struct dc_link_settings *link_setting)
{
-#if defined(CONFIG_DRM_AMD_DC_DCN)
uint32_t total_data_bw_efficiency_x10000 = 0;
uint32_t link_rate_per_lane_kbps = 0;
@@ -4694,40 +4649,6 @@ uint32_t dc_link_bandwidth_kbps(
/* overall effective link bandwidth = link rate per lane * lane count * total data bandwidth efficiency */
return link_rate_per_lane_kbps * link_setting->lane_count / 10000 * total_data_bw_efficiency_x10000;
-#else
- uint32_t link_bw_kbps =
- link_setting->link_rate * LINK_RATE_REF_FREQ_IN_KHZ; /* bytes per sec */
-
- link_bw_kbps *= 8; /* 8 bits per byte*/
- link_bw_kbps *= link_setting->lane_count;
-
- if (dc_link_should_enable_fec(link)) {
- /* Account for FEC overhead.
- * We have to do it based on caps,
- * and not based on FEC being set ready,
- * because FEC is set ready too late in
- * the process to correctly be picked up
- * by mode enumeration.
- *
- * There's enough zeros at the end of 'kbps'
- * that make the below operation 100% precise
- * for our purposes.
- * 'long long' makes it work even for HDMI 2.1
- * max bandwidth (and much, much bigger bandwidths
- * than that, actually).
- *
- * NOTE: Reducing link BW by 3% may not be precise
- * because it may be a stream BT that increases by 3%, and so
- * 1/1.03 = 0.970873 factor should have been used instead,
- * but the difference is minimal and is in a safe direction,
- * which all works well around potential ambiguity of DP 1.4a spec.
- */
- long long fec_link_bw_kbps = link_bw_kbps * 970LL;
- link_bw_kbps = (uint32_t)(div64_s64(fec_link_bw_kbps, 1000LL));
- }
- return link_bw_kbps;
-
-#endif
}
const struct dc_link_settings *dc_link_get_link_cap(
@@ -4752,16 +4673,7 @@ bool dc_link_is_fec_supported(const struct dc_link *link)
*/
struct link_encoder *link_enc = NULL;
- /* Links supporting dynamically assigned link encoder will be assigned next
- * available encoder if one not already assigned.
- */
- if (link->is_dig_mapping_flexible &&
- link->dc->res_pool->funcs->link_encs_assign) {
- link_enc = link_enc_cfg_get_link_enc_used_by_link(link->ctx->dc, link);
- if (link_enc == NULL)
- link_enc = link_enc_cfg_get_next_avail_link_enc(link->ctx->dc);
- } else
- link_enc = link->link_enc;
+ link_enc = link_enc_cfg_get_link_enc(link);
ASSERT(link_enc);
return (dc_is_dp_signal(link->connector_signal) && link_enc &&
@@ -4845,23 +4757,24 @@ uint32_t dc_bandwidth_in_kbps_from_timing(
}
-const struct link_resource *dc_link_get_cur_link_res(const struct dc_link *link)
+void dc_link_get_cur_link_res(const struct dc_link *link,
+ struct link_resource *link_res)
{
int i;
struct pipe_ctx *pipe = NULL;
- const struct link_resource *link_res = NULL;
+
+ memset(link_res, 0, sizeof(*link_res));
for (i = 0; i < MAX_PIPES; i++) {
pipe = &link->dc->current_state->res_ctx.pipe_ctx[i];
if (pipe->stream && pipe->stream->link && pipe->top_pipe == NULL) {
if (pipe->stream->link == link) {
- link_res = &pipe->link_res;
+ *link_res = pipe->link_res;
break;
}
}
}
- return link_res;
}
/**
@@ -4883,9 +4796,8 @@ const struct link_resource *dc_link_get_cur_link_res(const struct dc_link *link)
*/
void dc_get_cur_link_res_map(const struct dc *dc, uint32_t *map)
{
-#if defined(CONFIG_DRM_AMD_DC_DCN)
struct dc_link *link;
- uint8_t i;
+ uint32_t i;
uint32_t hpo_dp_recycle_map = 0;
*map = 0;
@@ -4903,7 +4815,6 @@ void dc_get_cur_link_res_map(const struct dc *dc, uint32_t *map)
}
*map |= (hpo_dp_recycle_map << LINK_RES_HPO_DP_REC_MAP__SHIFT);
}
-#endif
}
/**
@@ -4926,9 +4837,8 @@ void dc_get_cur_link_res_map(const struct dc *dc, uint32_t *map)
*/
void dc_restore_link_res_map(const struct dc *dc, uint32_t *map)
{
-#if defined(CONFIG_DRM_AMD_DC_DCN)
struct dc_link *link;
- uint8_t i;
+ uint32_t i;
unsigned int available_hpo_dp_count;
uint32_t hpo_dp_recycle_map = (*map & LINK_RES_HPO_DP_REC_MAP__MASK)
>> LINK_RES_HPO_DP_REC_MAP__SHIFT;
@@ -4964,5 +4874,4 @@ void dc_restore_link_res_map(const struct dc *dc, uint32_t *map)
}
}
}
-#endif
}
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_ddc.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_ddc.c
index 24dc662ec3e4..1d4863763df9 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link_ddc.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_ddc.c
@@ -298,6 +298,9 @@ static uint32_t defer_delay_converter_wa(
if (link->dpcd_caps.dongle_type == DISPLAY_DONGLE_DP_VGA_CONVERTER &&
link->dpcd_caps.branch_dev_id == DP_BRANCH_DEVICE_ID_0080E1 &&
+ (link->dpcd_caps.branch_fw_revision[0] < 0x01 ||
+ (link->dpcd_caps.branch_fw_revision[0] == 0x01 &&
+ link->dpcd_caps.branch_fw_revision[1] < 0x40)) &&
!memcmp(link->dpcd_caps.branch_dev_name,
DP_VGA_DONGLE_BRANCH_DEV_NAME,
sizeof(link->dpcd_caps.branch_dev_name)))
@@ -490,6 +493,7 @@ void dal_ddc_service_i2c_query_dp_dual_mode_adaptor(
sink_cap->max_hdmi_pixel_clock =
max_tmds_clk * 1000;
}
+ sink_cap->is_dongle_type_one = false;
} else {
if (is_valid_hdmi_signature == true) {
@@ -507,6 +511,7 @@ void dal_ddc_service_i2c_query_dp_dual_mode_adaptor(
"Type 1 DP-HDMI passive dongle (no signature) %dMhz: ",
sink_cap->max_hdmi_pixel_clock / 1000);
}
+ sink_cap->is_dongle_type_one = true;
}
return;
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
index 05e216524370..351081f574cb 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
@@ -27,6 +27,7 @@
#include "dm_helpers.h"
#include "opp.h"
#include "dsc.h"
+#include "clk_mgr.h"
#include "resource.h"
#include "inc/core_types.h"
@@ -38,6 +39,7 @@
#include "dce/dmub_hw_lock_mgr.h"
#include "inc/dc_link_dpia.h"
#include "inc/link_enc_cfg.h"
+#include "link/link_dp_trace.h"
/*Travis*/
static const uint8_t DP_VGA_LVDS_CONVERTER_ID_2[] = "sivarT";
@@ -50,6 +52,13 @@ static const uint8_t DP_VGA_LVDS_CONVERTER_ID_3[] = "dnomlA";
#include "link_dpcd.h"
+#ifndef MAX
+#define MAX(X, Y) ((X) > (Y) ? (X) : (Y))
+#endif
+#ifndef MIN
+#define MIN(X, Y) ((X) < (Y) ? (X) : (Y))
+#endif
+
/* maximum pre emphasis level allowed for each voltage swing level*/
static const enum dc_pre_emphasis
voltage_swing_to_pre_emphasis[] = { PRE_EMPHASIS_LEVEL3,
@@ -62,7 +71,6 @@ enum {
POST_LT_ADJ_REQ_TIMEOUT = 200
};
-#if defined(CONFIG_DRM_AMD_DC_DCN)
struct dp_lt_fallback_entry {
enum dc_lane_count lane_count;
enum dc_link_rate link_rate;
@@ -97,16 +105,18 @@ static const struct dp_lt_fallback_entry dp_lt_fallbacks[] = {
{LANE_COUNT_ONE, LINK_RATE_HIGH},
{LANE_COUNT_ONE, LINK_RATE_LOW},
};
-#endif
+
+static const struct dc_link_settings fail_safe_link_settings = {
+ .lane_count = LANE_COUNT_ONE,
+ .link_rate = LINK_RATE_LOW,
+ .link_spread = LINK_SPREAD_DISABLED,
+};
static bool decide_fallback_link_setting(
struct dc_link *link,
struct dc_link_settings initial_link_settings,
struct dc_link_settings *current_link_setting,
enum link_training_result training_result);
-static struct dc_link_settings get_common_supported_link_settings(
- struct dc_link_settings link_setting_a,
- struct dc_link_settings link_setting_b);
static void maximize_lane_settings(const struct link_training_settings *lt_settings,
struct dc_lane_settings lane_settings[LANE_COUNT_DP_MAX]);
static void override_lane_settings(const struct link_training_settings *lt_settings,
@@ -117,7 +127,7 @@ static uint32_t get_cr_training_aux_rd_interval(struct dc_link *link,
{
union training_aux_rd_interval training_rd_interval;
uint32_t wait_in_micro_secs = 100;
-#if defined(CONFIG_DRM_AMD_DC_DCN)
+
memset(&training_rd_interval, 0, sizeof(training_rd_interval));
if (dp_get_link_encoding_format(link_settings) == DP_8b_10b_ENCODING &&
link->dpcd_caps.dpcd_rev.raw >= DPCD_REV_12) {
@@ -129,15 +139,7 @@ static uint32_t get_cr_training_aux_rd_interval(struct dc_link *link,
if (training_rd_interval.bits.TRAINIG_AUX_RD_INTERVAL)
wait_in_micro_secs = training_rd_interval.bits.TRAINIG_AUX_RD_INTERVAL * 4000;
}
-#else
- core_link_read_dpcd(
- link,
- DP_TRAINING_AUX_RD_INTERVAL,
- (uint8_t *)&training_rd_interval,
- sizeof(training_rd_interval));
- if (training_rd_interval.bits.TRAINIG_AUX_RD_INTERVAL)
- wait_in_micro_secs = training_rd_interval.bits.TRAINIG_AUX_RD_INTERVAL * 4000;
-#endif
+
return wait_in_micro_secs;
}
@@ -145,7 +147,6 @@ static uint32_t get_eq_training_aux_rd_interval(
struct dc_link *link,
const struct dc_link_settings *link_settings)
{
-#if defined(CONFIG_DRM_AMD_DC_DCN)
union training_aux_rd_interval training_rd_interval;
memset(&training_rd_interval, 0, sizeof(training_rd_interval));
@@ -174,41 +175,16 @@ static uint32_t get_eq_training_aux_rd_interval(
case 6: return 64000;
default: return 400;
}
-#else
- union training_aux_rd_interval training_rd_interval;
- uint32_t wait_in_micro_secs = 400;
-
- memset(&training_rd_interval, 0, sizeof(training_rd_interval));
- /* overwrite the delay if rev > 1.1*/
- if (link->dpcd_caps.dpcd_rev.raw >= DPCD_REV_12) {
- /* DP 1.2 or later - retrieve delay through
- * "DPCD_ADDR_TRAINING_AUX_RD_INTERVAL" register */
- core_link_read_dpcd(
- link,
- DP_TRAINING_AUX_RD_INTERVAL,
- (uint8_t *)&training_rd_interval,
- sizeof(training_rd_interval));
-
- if (training_rd_interval.bits.TRAINIG_AUX_RD_INTERVAL)
- wait_in_micro_secs = training_rd_interval.bits.TRAINIG_AUX_RD_INTERVAL * 4000;
- }
-
- return wait_in_micro_secs;
-#endif
}
void dp_wait_for_training_aux_rd_interval(
struct dc_link *link,
uint32_t wait_in_micro_secs)
{
-#if defined(CONFIG_DRM_AMD_DC_DCN)
- if (wait_in_micro_secs > 16000)
+ if (wait_in_micro_secs > 1000)
msleep(wait_in_micro_secs/1000);
else
udelay(wait_in_micro_secs);
-#else
- udelay(wait_in_micro_secs);
-#endif
DC_LOG_HW_LINK_TRAINING("%s:\n wait = %d\n",
__func__,
@@ -236,7 +212,6 @@ enum dpcd_training_patterns
case DP_TRAINING_PATTERN_SEQUENCE_4:
dpcd_tr_pattern = DPCD_TRAINING_PATTERN_4;
break;
-#if defined(CONFIG_DRM_AMD_DC_DCN)
case DP_128b_132b_TPS1:
dpcd_tr_pattern = DPCD_128b_132b_TPS1;
break;
@@ -246,7 +221,6 @@ enum dpcd_training_patterns
case DP_128b_132b_TPS2_CDS:
dpcd_tr_pattern = DPCD_128b_132b_TPS2_CDS;
break;
-#endif
case DP_TRAINING_PATTERN_VIDEOIDLE:
dpcd_tr_pattern = DPCD_TRAINING_PATTERN_VIDEOIDLE;
break;
@@ -289,10 +263,8 @@ static enum dc_dp_training_pattern decide_cr_training_pattern(
case DP_8b_10b_ENCODING:
default:
return DP_TRAINING_PATTERN_SEQUENCE_1;
-#if defined(CONFIG_DRM_AMD_DC_DCN)
case DP_128b_132b_ENCODING:
return DP_128b_132b_TPS1;
-#endif
}
}
@@ -300,19 +272,11 @@ static enum dc_dp_training_pattern decide_eq_training_pattern(struct dc_link *li
const struct dc_link_settings *link_settings)
{
struct link_encoder *link_enc;
-#if defined(CONFIG_DRM_AMD_DC_DCN)
struct encoder_feature_support *enc_caps;
struct dpcd_caps *rx_caps = &link->dpcd_caps;
enum dc_dp_training_pattern pattern = DP_TRAINING_PATTERN_SEQUENCE_2;
- /* Access link encoder capability based on whether it is statically
- * or dynamically assigned to a link.
- */
- if (link->is_dig_mapping_flexible &&
- link->dc->res_pool->funcs->link_encs_assign)
- link_enc = link_enc_cfg_get_link_enc_used_by_link(link->ctx->dc, link);
- else
- link_enc = link->link_enc;
+ link_enc = link_enc_cfg_get_link_enc(link);
ASSERT(link_enc);
enc_caps = &link_enc->features;
@@ -335,41 +299,8 @@ static enum dc_dp_training_pattern decide_eq_training_pattern(struct dc_link *li
break;
}
return pattern;
-#else
- enum dc_dp_training_pattern highest_tp = DP_TRAINING_PATTERN_SEQUENCE_2;
- struct encoder_feature_support *features;
- struct dpcd_caps *dpcd_caps = &link->dpcd_caps;
-
- /* Access link encoder capability based on whether it is statically
- * or dynamically assigned to a link.
- */
- if (link->is_dig_mapping_flexible &&
- link->dc->res_pool->funcs->link_encs_assign)
- link_enc = link_enc_cfg_get_link_enc_used_by_link(link->ctx->dc, link);
- else
- link_enc = link->link_enc;
- ASSERT(link_enc);
- features = &link_enc->features;
-
- if (features->flags.bits.IS_TPS3_CAPABLE)
- highest_tp = DP_TRAINING_PATTERN_SEQUENCE_3;
-
- if (features->flags.bits.IS_TPS4_CAPABLE)
- highest_tp = DP_TRAINING_PATTERN_SEQUENCE_4;
-
- if (dpcd_caps->max_down_spread.bits.TPS4_SUPPORTED &&
- highest_tp >= DP_TRAINING_PATTERN_SEQUENCE_4)
- return DP_TRAINING_PATTERN_SEQUENCE_4;
-
- if (dpcd_caps->max_ln_count.bits.TPS3_SUPPORTED &&
- highest_tp >= DP_TRAINING_PATTERN_SEQUENCE_3)
- return DP_TRAINING_PATTERN_SEQUENCE_3;
-
- return DP_TRAINING_PATTERN_SEQUENCE_2;
-#endif
}
-#if defined(CONFIG_DRM_AMD_DC_DCN)
static uint8_t get_dpcd_link_rate(const struct dc_link_settings *link_settings)
{
uint8_t link_rate = 0;
@@ -397,7 +328,6 @@ static uint8_t get_dpcd_link_rate(const struct dc_link_settings *link_settings)
return link_rate;
}
-#endif
static void vendor_specific_lttpr_wa_one_start(struct dc_link *link)
{
@@ -418,29 +348,6 @@ static void vendor_specific_lttpr_wa_one_start(struct dc_link *link)
sizeof(vendor_lttpr_write_data));
}
-static void vendor_specific_lttpr_wa_one_end(
- struct dc_link *link,
- uint8_t retry_count)
-{
- const uint8_t vendor_lttpr_write_data[4] = {0x1, 0x50, 0x63, 0x0};
- const uint8_t offset = dp_convert_to_count(
- link->dpcd_caps.lttpr_caps.phy_repeater_cnt);
- uint32_t vendor_lttpr_write_address = 0xF004F;
-
- if (!retry_count) {
- if (offset != 0xFF)
- vendor_lttpr_write_address +=
- ((DP_REPEATER_CONFIGURATION_AND_STATUS_SIZE) * (offset - 1));
-
- /* W/A for certain LTTPR to reset their lane settings, part two of two */
- core_link_write_dpcd(
- link,
- vendor_lttpr_write_address,
- &vendor_lttpr_write_data[0],
- sizeof(vendor_lttpr_write_data));
- }
-}
-
static void vendor_specific_lttpr_wa_one_two(
struct dc_link *link,
const uint8_t rate)
@@ -467,9 +374,9 @@ static void vendor_specific_lttpr_wa_one_two(
}
}
-static void vendor_specific_lttpr_wa_three(
+static void dp_fixed_vs_pe_read_lane_adjust(
struct dc_link *link,
- union lane_adjust dpcd_lane_adjust[LANE_COUNT_DP_MAX])
+ union dpcd_training_lane dpcd_lane_adjust[LANE_COUNT_DP_MAX])
{
const uint8_t vendor_lttpr_write_data_vs[3] = {0x0, 0x53, 0x63};
const uint8_t vendor_lttpr_write_data_pe[3] = {0x0, 0x54, 0x63};
@@ -511,23 +418,8 @@ static void vendor_specific_lttpr_wa_three(
1);
for (lane = 0; lane < LANE_COUNT_DP_MAX; lane++) {
- dpcd_lane_adjust[lane].bits.VOLTAGE_SWING_LANE = (dprx_vs >> (2 * lane)) & 0x3;
- dpcd_lane_adjust[lane].bits.PRE_EMPHASIS_LANE = (dprx_pe >> (2 * lane)) & 0x3;
- }
-}
-
-static void vendor_specific_lttpr_wa_three_dpcd(
- struct dc_link *link,
- union dpcd_training_lane dpcd_lane_adjust[LANE_COUNT_DP_MAX])
-{
- union lane_adjust lane_adjust[LANE_COUNT_DP_MAX];
- uint8_t lane = 0;
-
- vendor_specific_lttpr_wa_three(link, lane_adjust);
-
- for (lane = 0; lane < LANE_COUNT_DP_MAX; lane++) {
- dpcd_lane_adjust[lane].bits.VOLTAGE_SWING_SET = lane_adjust[lane].bits.VOLTAGE_SWING_LANE;
- dpcd_lane_adjust[lane].bits.PRE_EMPHASIS_SET = lane_adjust[lane].bits.PRE_EMPHASIS_LANE;
+ dpcd_lane_adjust[lane].bits.VOLTAGE_SWING_SET = (dprx_vs >> (2 * lane)) & 0x3;
+ dpcd_lane_adjust[lane].bits.PRE_EMPHASIS_SET = (dprx_pe >> (2 * lane)) & 0x3;
}
}
@@ -540,10 +432,8 @@ static void vendor_specific_lttpr_wa_four(
const uint8_t offset = dp_convert_to_count(
link->dpcd_caps.lttpr_caps.phy_repeater_cnt);
uint32_t vendor_lttpr_write_address = 0xF004F;
-#if defined(CONFIG_DRM_AMD_DC_DP2_0)
uint8_t sink_status = 0;
uint8_t i;
-#endif
if (offset != 0xFF)
vendor_lttpr_write_address +=
@@ -569,7 +459,6 @@ static void vendor_specific_lttpr_wa_four(
sizeof(vendor_lttpr_write_data_two));
}
-#if defined(CONFIG_DRM_AMD_DC_DP2_0)
/* poll for intra-hop disable */
for (i = 0; i < 10; i++) {
if ((core_link_read_dpcd(link, DP_SINK_STATUS, &sink_status, 1) == DC_OK) &&
@@ -577,20 +466,26 @@ static void vendor_specific_lttpr_wa_four(
break;
udelay(1000);
}
-#endif
}
-static void vendor_specific_lttpr_wa_five(
+static void dp_fixed_vs_pe_set_retimer_lane_settings(
struct dc_link *link,
const union dpcd_training_lane dpcd_lane_adjust[LANE_COUNT_DP_MAX],
uint8_t lane_count)
{
- const uint32_t vendor_lttpr_write_address = 0xF004F;
+ const uint8_t offset = dp_convert_to_count(
+ link->dpcd_caps.lttpr_caps.phy_repeater_cnt);
const uint8_t vendor_lttpr_write_data_reset[4] = {0x1, 0x50, 0x63, 0xFF};
+ uint32_t vendor_lttpr_write_address = 0xF004F;
uint8_t vendor_lttpr_write_data_vs[4] = {0x1, 0x51, 0x63, 0x0};
uint8_t vendor_lttpr_write_data_pe[4] = {0x1, 0x52, 0x63, 0x0};
uint8_t lane = 0;
+ if (offset != 0xFF) {
+ vendor_lttpr_write_address +=
+ ((DP_REPEATER_CONFIGURATION_AND_STATUS_SIZE) * (offset - 1));
+ }
+
for (lane = 0; lane < lane_count; lane++) {
vendor_lttpr_write_data_vs[3] |=
dpcd_lane_adjust[lane].bits.VOLTAGE_SWING_SET << (2 * lane);
@@ -665,11 +560,7 @@ enum dc_status dpcd_set_link_settings(
status = core_link_write_dpcd(link, DP_LINK_RATE_SET,
&lt_settings->link_settings.link_rate_set, 1);
} else {
-#if defined(CONFIG_DRM_AMD_DC_DCN)
rate = get_dpcd_link_rate(&lt_settings->link_settings);
-#else
- rate = (uint8_t) (lt_settings->link_settings.link_rate);
-#endif
if (link->dc->debug.apply_vendor_specific_lttpr_wa &&
(link->chip_caps & EXT_DISPLAY_PATH_CAPS__DP_FIXED_VS_EN) &&
link->lttpr_mode == LTTPR_MODE_TRANSPARENT)
@@ -720,10 +611,8 @@ uint8_t dc_dp_initialize_scrambling_data_symbols(
disable_scrabled_data_symbols = 1;
break;
case DP_TRAINING_PATTERN_SEQUENCE_4:
-#if defined(CONFIG_DRM_AMD_DC_DCN)
case DP_128b_132b_TPS1:
case DP_128b_132b_TPS2:
-#endif
disable_scrabled_data_symbols = 0;
break;
default:
@@ -794,7 +683,6 @@ static void dpcd_set_lt_pattern_and_lane_settings(
size_in_bytes);
if (is_repeater(link, offset)) {
-#if defined(CONFIG_DRM_AMD_DC_DCN)
if (dp_get_link_encoding_format(&lt_settings->link_settings) ==
DP_128b_132b_ENCODING)
DC_LOG_HW_LINK_TRAINING("%s:\n LTTPR Repeater ID: %d\n"
@@ -805,7 +693,6 @@ static void dpcd_set_lt_pattern_and_lane_settings(
lt_settings->dpcd_lane_settings[0].tx_ffe.PRESET_VALUE);
else if (dp_get_link_encoding_format(&lt_settings->link_settings) ==
DP_8b_10b_ENCODING)
-#endif
DC_LOG_HW_LINK_TRAINING("%s:\n LTTPR Repeater ID: %d\n"
" 0x%X VS set = %x PE set = %x max VS Reached = %x max PE Reached = %x\n",
__func__,
@@ -816,7 +703,6 @@ static void dpcd_set_lt_pattern_and_lane_settings(
lt_settings->dpcd_lane_settings[0].bits.MAX_SWING_REACHED,
lt_settings->dpcd_lane_settings[0].bits.MAX_PRE_EMPHASIS_REACHED);
} else {
-#if defined(CONFIG_DRM_AMD_DC_DCN)
if (dp_get_link_encoding_format(&lt_settings->link_settings) ==
DP_128b_132b_ENCODING)
DC_LOG_HW_LINK_TRAINING("%s:\n 0x%X TX_FFE_PRESET_VALUE = %x\n",
@@ -825,14 +711,13 @@ static void dpcd_set_lt_pattern_and_lane_settings(
lt_settings->dpcd_lane_settings[0].tx_ffe.PRESET_VALUE);
else if (dp_get_link_encoding_format(&lt_settings->link_settings) ==
DP_8b_10b_ENCODING)
-#endif
- DC_LOG_HW_LINK_TRAINING("%s:\n 0x%X VS set = %x PE set = %x max VS Reached = %x max PE Reached = %x\n",
- __func__,
- dpcd_base_lt_offset,
- lt_settings->dpcd_lane_settings[0].bits.VOLTAGE_SWING_SET,
- lt_settings->dpcd_lane_settings[0].bits.PRE_EMPHASIS_SET,
- lt_settings->dpcd_lane_settings[0].bits.MAX_SWING_REACHED,
- lt_settings->dpcd_lane_settings[0].bits.MAX_PRE_EMPHASIS_REACHED);
+ DC_LOG_HW_LINK_TRAINING("%s:\n 0x%X VS set = %x PE set = %x max VS Reached = %x max PE Reached = %x\n",
+ __func__,
+ dpcd_base_lt_offset,
+ lt_settings->dpcd_lane_settings[0].bits.VOLTAGE_SWING_SET,
+ lt_settings->dpcd_lane_settings[0].bits.PRE_EMPHASIS_SET,
+ lt_settings->dpcd_lane_settings[0].bits.MAX_SWING_REACHED,
+ lt_settings->dpcd_lane_settings[0].bits.MAX_PRE_EMPHASIS_REACHED);
}
if (edp_workaround) {
/* for eDP write in 2 parts because the 5-byte burst is
@@ -850,7 +735,6 @@ static void dpcd_set_lt_pattern_and_lane_settings(
(uint8_t *)(lt_settings->dpcd_lane_settings),
size_in_bytes);
-#if defined(CONFIG_DRM_AMD_DC_DCN)
} else if (dp_get_link_encoding_format(&lt_settings->link_settings) ==
DP_128b_132b_ENCODING) {
core_link_write_dpcd(
@@ -858,10 +742,9 @@ static void dpcd_set_lt_pattern_and_lane_settings(
dpcd_base_lt_offset,
dpcd_lt_buffer,
sizeof(dpcd_lt_buffer));
-#endif
- } else
+ } else
/* write it all in (1 + number-of-lanes)-byte burst*/
- core_link_write_dpcd(
+ core_link_write_dpcd(
link,
dpcd_base_lt_offset,
dpcd_lt_buffer,
@@ -928,13 +811,11 @@ void dp_hw_to_dpcd_lane_settings(
(hw_lane_settings[lane].PRE_EMPHASIS ==
PRE_EMPHASIS_MAX_LEVEL ? 1 : 0);
}
-#if defined(CONFIG_DRM_AMD_DC_DCN)
else if (dp_get_link_encoding_format(&lt_settings->link_settings) ==
DP_128b_132b_ENCODING) {
dpcd_lane_settings[lane].tx_ffe.PRESET_VALUE =
hw_lane_settings[lane].FFE_PRESET.settings.level;
}
-#endif
}
}
@@ -956,13 +837,11 @@ void dp_decide_lane_settings(
(enum dc_pre_emphasis)(ln_adjust[lane].bits.
PRE_EMPHASIS_LANE);
}
-#if defined(CONFIG_DRM_AMD_DC_DCN)
else if (dp_get_link_encoding_format(&lt_settings->link_settings) ==
DP_128b_132b_ENCODING) {
hw_lane_settings[lane].FFE_PRESET.raw =
ln_adjust[lane].tx_ffe.PRESET_VALUE;
}
-#endif
}
dp_hw_to_dpcd_lane_settings(lt_settings, hw_lane_settings, dpcd_lane_settings);
@@ -1013,9 +892,7 @@ static void maximize_lane_settings(const struct link_training_settings *lt_setti
max_requested.VOLTAGE_SWING = lane_settings[0].VOLTAGE_SWING;
max_requested.PRE_EMPHASIS = lane_settings[0].PRE_EMPHASIS;
-#if defined(CONFIG_DRM_AMD_DC_DCN)
max_requested.FFE_PRESET = lane_settings[0].FFE_PRESET;
-#endif
/* Determine what the maximum of the requested settings are*/
for (lane = 1; lane < lt_settings->link_settings.lane_count; lane++) {
@@ -1024,12 +901,10 @@ static void maximize_lane_settings(const struct link_training_settings *lt_setti
if (lane_settings[lane].PRE_EMPHASIS > max_requested.PRE_EMPHASIS)
max_requested.PRE_EMPHASIS = lane_settings[lane].PRE_EMPHASIS;
-#if defined(CONFIG_DRM_AMD_DC_DCN)
if (lane_settings[lane].FFE_PRESET.settings.level >
max_requested.FFE_PRESET.settings.level)
max_requested.FFE_PRESET.settings.level =
lane_settings[lane].FFE_PRESET.settings.level;
-#endif
}
/* make sure the requested settings are
@@ -1039,10 +914,8 @@ static void maximize_lane_settings(const struct link_training_settings *lt_setti
if (max_requested.PRE_EMPHASIS > PRE_EMPHASIS_MAX_LEVEL)
max_requested.PRE_EMPHASIS = PRE_EMPHASIS_MAX_LEVEL;
-#if defined(CONFIG_DRM_AMD_DC_DCN)
if (max_requested.FFE_PRESET.settings.level > DP_FFE_PRESET_MAX_LEVEL)
max_requested.FFE_PRESET.settings.level = DP_FFE_PRESET_MAX_LEVEL;
-#endif
/* make sure the pre-emphasis matches the voltage swing*/
if (max_requested.PRE_EMPHASIS >
@@ -1055,9 +928,7 @@ static void maximize_lane_settings(const struct link_training_settings *lt_setti
for (lane = 0; lane < LANE_COUNT_DP_MAX; lane++) {
lane_settings[lane].VOLTAGE_SWING = max_requested.VOLTAGE_SWING;
lane_settings[lane].PRE_EMPHASIS = max_requested.PRE_EMPHASIS;
-#if defined(CONFIG_DRM_AMD_DC_DCN)
lane_settings[lane].FFE_PRESET = max_requested.FFE_PRESET;
-#endif
}
}
@@ -1068,9 +939,7 @@ static void override_lane_settings(const struct link_training_settings *lt_setti
if (lt_settings->voltage_swing == NULL &&
lt_settings->pre_emphasis == NULL &&
-#if defined(CONFIG_DRM_AMD_DC_DCN)
lt_settings->ffe_preset == NULL &&
-#endif
lt_settings->post_cursor2 == NULL)
return;
@@ -1082,10 +951,8 @@ static void override_lane_settings(const struct link_training_settings *lt_setti
lane_settings[lane].PRE_EMPHASIS = *lt_settings->pre_emphasis;
if (lt_settings->post_cursor2)
lane_settings[lane].POST_CURSOR2 = *lt_settings->post_cursor2;
-#if defined(CONFIG_DRM_AMD_DC_DCN)
if (lt_settings->ffe_preset)
lane_settings[lane].FFE_PRESET = *lt_settings->ffe_preset;
-#endif
}
}
@@ -1117,6 +984,14 @@ enum dc_status dp_get_lane_status_and_lane_adjust(
(uint8_t *)(dpcd_buf),
sizeof(dpcd_buf));
+ if (status != DC_OK) {
+ DC_LOG_HW_LINK_TRAINING("%s:\n Failed to read from address 0x%X,"
+ " keep current lane status and lane adjust unchanged",
+ __func__,
+ lane01_status_address);
+ return status;
+ }
+
for (lane = 0; lane <
(uint32_t)(link_training_setting->link_settings.lane_count);
lane++) {
@@ -1189,7 +1064,6 @@ enum dc_status dpcd_set_lane_settings(
link_training_setting->link_settings.lane_count);
if (is_repeater(link, offset)) {
-#if defined(CONFIG_DRM_AMD_DC_DCN)
if (dp_get_link_encoding_format(&link_training_setting->link_settings) ==
DP_128b_132b_ENCODING)
DC_LOG_HW_LINK_TRAINING("%s:\n LTTPR Repeater ID: %d\n"
@@ -1200,7 +1074,6 @@ enum dc_status dpcd_set_lane_settings(
link_training_setting->dpcd_lane_settings[0].tx_ffe.PRESET_VALUE);
else if (dp_get_link_encoding_format(&link_training_setting->link_settings) ==
DP_8b_10b_ENCODING)
-#endif
DC_LOG_HW_LINK_TRAINING("%s\n LTTPR Repeater ID: %d\n"
" 0x%X VS set = %x PE set = %x max VS Reached = %x max PE Reached = %x\n",
__func__,
@@ -1212,7 +1085,6 @@ enum dc_status dpcd_set_lane_settings(
link_training_setting->dpcd_lane_settings[0].bits.MAX_PRE_EMPHASIS_REACHED);
} else {
-#if defined(CONFIG_DRM_AMD_DC_DCN)
if (dp_get_link_encoding_format(&link_training_setting->link_settings) ==
DP_128b_132b_ENCODING)
DC_LOG_HW_LINK_TRAINING("%s:\n 0x%X TX_FFE_PRESET_VALUE = %x\n",
@@ -1221,7 +1093,6 @@ enum dc_status dpcd_set_lane_settings(
link_training_setting->dpcd_lane_settings[0].tx_ffe.PRESET_VALUE);
else if (dp_get_link_encoding_format(&link_training_setting->link_settings) ==
DP_8b_10b_ENCODING)
-#endif
DC_LOG_HW_LINK_TRAINING("%s\n 0x%X VS set = %x PE set = %x max VS Reached = %x max PE Reached = %x\n",
__func__,
lane0_set_address,
@@ -1261,6 +1132,9 @@ static bool perform_post_lt_adj_req_sequence(
uint32_t adj_req_timer;
bool req_drv_setting_changed;
uint32_t lane;
+ union lane_status dpcd_lane_status[LANE_COUNT_DP_MAX] = {0};
+ union lane_align_status_updated dpcd_lane_status_updated = {0};
+ union lane_adjust dpcd_lane_adjust[LANE_COUNT_DP_MAX] = {0};
req_drv_setting_changed = false;
for (adj_req_count = 0; adj_req_count < POST_LT_ADJ_REQ_LIMIT;
@@ -1272,11 +1146,6 @@ static bool perform_post_lt_adj_req_sequence(
adj_req_timer < POST_LT_ADJ_REQ_TIMEOUT;
adj_req_timer++) {
- union lane_status dpcd_lane_status[LANE_COUNT_DP_MAX];
- union lane_align_status_updated
- dpcd_lane_status_updated;
- union lane_adjust dpcd_lane_adjust[LANE_COUNT_DP_MAX] = { { {0} } };
-
dp_get_lane_status_and_lane_adjust(
link,
lt_settings,
@@ -1357,14 +1226,12 @@ uint32_t dp_translate_training_aux_read_interval(uint32_t dpcd_aux_read_interval
case 0x04:
aux_rd_interval_us = 16000;
break;
-#if defined(CONFIG_DRM_AMD_DC_DCN)
case 0x05:
aux_rd_interval_us = 32000;
break;
case 0x06:
aux_rd_interval_us = 64000;
break;
-#endif
default:
break;
}
@@ -1405,13 +1272,8 @@ static enum link_training_result perform_channel_equalization_sequence(
/* Note: also check that TPS4 is a supported feature*/
tr_pattern = lt_settings->pattern_for_eq;
-#if defined(CONFIG_DRM_AMD_DC_DCN)
if (is_repeater(link, offset) && dp_get_link_encoding_format(&lt_settings->link_settings) == DP_8b_10b_ENCODING)
tr_pattern = DP_TRAINING_PATTERN_SEQUENCE_4;
-#else
- if (is_repeater(link, offset))
- tr_pattern = DP_TRAINING_PATTERN_SEQUENCE_4;
-#endif
dp_set_hw_training_pattern(link, link_res, tr_pattern, offset);
@@ -1510,6 +1372,10 @@ static enum link_training_result perform_clock_recovery_sequence(
retries_cr = 0;
retry_count = 0;
+ memset(&dpcd_lane_status, '\0', sizeof(dpcd_lane_status));
+ memset(&dpcd_lane_status_updated, '\0',
+ sizeof(dpcd_lane_status_updated));
+
if (!link->ctx->dc->work_arounds.lt_early_cr_pattern)
dp_set_hw_training_pattern(link, link_res, lt_settings->pattern_for_cr, offset);
@@ -1521,9 +1387,6 @@ static enum link_training_result perform_clock_recovery_sequence(
while ((retries_cr < LINK_TRAINING_MAX_RETRY_COUNT) &&
(retry_count < LINK_TRAINING_MAX_CR_RETRY)) {
- memset(&dpcd_lane_status, '\0', sizeof(dpcd_lane_status));
- memset(&dpcd_lane_status_updated, '\0',
- sizeof(dpcd_lane_status_updated));
/* 1. call HWSS to set lane settings*/
dp_set_hw_lane_settings(
@@ -1570,27 +1433,15 @@ static enum link_training_result perform_clock_recovery_sequence(
dpcd_lane_adjust,
offset);
- if (link->dc->debug.apply_vendor_specific_lttpr_wa &&
- (link->chip_caps & EXT_DISPLAY_PATH_CAPS__DP_FIXED_VS_EN) &&
- link->lttpr_mode == LTTPR_MODE_TRANSPARENT) {
- vendor_specific_lttpr_wa_one_end(link, retry_count);
- vendor_specific_lttpr_wa_three(link, dpcd_lane_adjust);
- }
-
/* 5. check CR done*/
if (dp_is_cr_done(lane_count, dpcd_lane_status))
return LINK_TRAINING_SUCCESS;
/* 6. max VS reached*/
-#if defined(CONFIG_DRM_AMD_DC_DCN)
if ((dp_get_link_encoding_format(&lt_settings->link_settings) ==
DP_8b_10b_ENCODING) &&
dp_is_max_vs_reached(lt_settings))
break;
-#else
- if (dp_is_max_vs_reached(lt_settings))
- break;
-#endif
/* 7. same lane settings*/
/* Note: settings are the same for all lanes,
@@ -1599,12 +1450,10 @@ static enum link_training_result perform_clock_recovery_sequence(
lt_settings->dpcd_lane_settings[0].bits.VOLTAGE_SWING_SET ==
dpcd_lane_adjust[0].bits.VOLTAGE_SWING_LANE)
retries_cr++;
-#if defined(CONFIG_DRM_AMD_DC_DCN)
else if ((dp_get_link_encoding_format(&lt_settings->link_settings) == DP_128b_132b_ENCODING) &&
lt_settings->dpcd_lane_settings[0].tx_ffe.PRESET_VALUE ==
dpcd_lane_adjust[0].tx_ffe.PRESET_VALUE)
retries_cr++;
-#endif
else
retries_cr = 0;
@@ -1642,11 +1491,7 @@ static inline enum link_training_result dp_transition_to_video_idle(
* TPS4 must be used instead of POST_LT_ADJ_REQ.
*/
if (link->dpcd_caps.max_ln_count.bits.POST_LT_ADJ_REQ_SUPPORTED != 1 ||
-#if defined(CONFIG_DRM_AMD_DC_DCN)
lt_settings->pattern_for_eq >= DP_TRAINING_PATTERN_SEQUENCE_4) {
-#else
- lt_settings->pattern_for_eq == DP_TRAINING_PATTERN_SEQUENCE_4) {
-#endif
/* delay 5ms after Main Link output idle pattern and then check
* DPCD 0202h.
*/
@@ -1745,7 +1590,6 @@ static inline void decide_8b_10b_training_settings(
dp_hw_to_dpcd_lane_settings(lt_settings, lt_settings->hw_lane_settings, lt_settings->dpcd_lane_settings);
}
-#if defined(CONFIG_DRM_AMD_DC_DCN)
static inline void decide_128b_132b_training_settings(struct dc_link *link,
const struct dc_link_settings *link_settings,
struct link_training_settings *lt_settings)
@@ -1772,7 +1616,6 @@ static inline void decide_128b_132b_training_settings(struct dc_link *link,
dp_hw_to_dpcd_lane_settings(lt_settings,
lt_settings->hw_lane_settings, lt_settings->dpcd_lane_settings);
}
-#endif
void dp_decide_training_settings(
struct dc_link *link,
@@ -1781,10 +1624,8 @@ void dp_decide_training_settings(
{
if (dp_get_link_encoding_format(link_settings) == DP_8b_10b_ENCODING)
decide_8b_10b_training_settings(link, link_settings, lt_settings);
-#if defined(CONFIG_DRM_AMD_DC_DCN)
else if (dp_get_link_encoding_format(link_settings) == DP_128b_132b_ENCODING)
decide_128b_132b_training_settings(link, link_settings, lt_settings);
-#endif
}
static void override_training_settings(
@@ -1807,10 +1648,8 @@ static void override_training_settings(
lt_settings->pre_emphasis = overrides->pre_emphasis;
if (overrides->post_cursor2 != NULL)
lt_settings->post_cursor2 = overrides->post_cursor2;
-#if defined(CONFIG_DRM_AMD_DC_DCN)
if (overrides->ffe_preset != NULL)
lt_settings->ffe_preset = overrides->ffe_preset;
-#endif
/* Override HW lane settings with BIOS forced values if present */
if (link->chip_caps & EXT_DISPLAY_PATH_CAPS__DP_FIXED_VS_EN &&
link->lttpr_mode == LTTPR_MODE_TRANSPARENT) {
@@ -2014,7 +1853,6 @@ static void print_status_message(
case LINK_RATE_HIGH3:
link_rate = "HBR3";
break;
-#if defined(CONFIG_DRM_AMD_DC_DCN)
case LINK_RATE_UHBR10:
link_rate = "UHBR10";
break;
@@ -2024,7 +1862,6 @@ static void print_status_message(
case LINK_RATE_UHBR20:
link_rate = "UHBR20";
break;
-#endif
default:
break;
}
@@ -2054,7 +1891,6 @@ static void print_status_message(
case LINK_TRAINING_LINK_LOSS:
lt_result = "Link loss";
break;
-#if defined(CONFIG_DRM_AMD_DC_DCN)
case DP_128b_132b_LT_FAILED:
lt_result = "LT_FAILED received";
break;
@@ -2067,7 +1903,6 @@ static void print_status_message(
case DP_128b_132b_CDS_DONE_TIMEOUT:
lt_result = "CDS timeout";
break;
-#endif
default:
break;
}
@@ -2087,9 +1922,9 @@ static void print_status_message(
}
/* Connectivity log: link training */
-#if defined(CONFIG_DRM_AMD_DC_DCN)
+
/* TODO - DP2.0 Log: add connectivity log for FFE PRESET */
-#endif
+
CONN_MSG_LT(link, "%sx%d %s VS=%d, PE=%d, DS=%s",
link_rate,
lt_settings->link_settings.lane_count,
@@ -2177,15 +2012,12 @@ enum dc_status dpcd_configure_lttpr_mode(struct dc_link *link, struct link_train
static void dpcd_exit_training_mode(struct dc_link *link)
{
-#if defined(CONFIG_DRM_AMD_DC_DCN)
uint8_t sink_status = 0;
uint8_t i;
-#endif
/* clear training pattern set */
dpcd_set_training_pattern(link, DP_TRAINING_PATTERN_VIDEOIDLE);
-#if defined(CONFIG_DRM_AMD_DC_DCN)
/* poll for intra-hop disable */
for (i = 0; i < 10; i++) {
if ((core_link_read_dpcd(link, DP_SINK_STATUS, &sink_status, 1) == DC_OK) &&
@@ -2193,7 +2025,6 @@ static void dpcd_exit_training_mode(struct dc_link *link)
break;
udelay(1000);
}
-#endif
}
enum dc_status dpcd_configure_channel_coding(struct dc_link *link,
@@ -2217,7 +2048,6 @@ enum dc_status dpcd_configure_channel_coding(struct dc_link *link,
return status;
}
-#if defined(CONFIG_DRM_AMD_DC_DCN)
static void dpcd_128b_132b_get_aux_rd_interval(struct dc_link *link,
uint32_t *interval_in_us)
{
@@ -2348,7 +2178,6 @@ static enum link_training_result dp_perform_128b_132b_cds_done_sequence(
return status;
}
-#endif
static enum link_training_result dp_perform_8b_10b_link_training(
struct dc_link *link,
@@ -2378,38 +2207,42 @@ static enum link_training_result dp_perform_8b_10b_link_training(
repeater_id--) {
status = perform_clock_recovery_sequence(link, link_res, lt_settings, repeater_id);
- if (status != LINK_TRAINING_SUCCESS)
+ if (status != LINK_TRAINING_SUCCESS) {
+ repeater_training_done(link, repeater_id);
break;
+ }
status = perform_channel_equalization_sequence(link,
link_res,
lt_settings,
repeater_id);
+ repeater_training_done(link, repeater_id);
+
if (status != LINK_TRAINING_SUCCESS)
break;
- repeater_training_done(link, repeater_id);
+ for (lane = 0; lane < LANE_COUNT_DP_MAX; lane++) {
+ lt_settings->dpcd_lane_settings[lane].raw = 0;
+ lt_settings->hw_lane_settings[lane].VOLTAGE_SWING = 0;
+ lt_settings->hw_lane_settings[lane].PRE_EMPHASIS = 0;
+ }
}
-
- for (lane = 0; lane < (uint8_t)lt_settings->link_settings.lane_count; lane++)
- lt_settings->dpcd_lane_settings[lane].raw = 0;
}
if (status == LINK_TRAINING_SUCCESS) {
status = perform_clock_recovery_sequence(link, link_res, lt_settings, DPRX);
- if (status == LINK_TRAINING_SUCCESS) {
- status = perform_channel_equalization_sequence(link,
- link_res,
- lt_settings,
- DPRX);
+ if (status == LINK_TRAINING_SUCCESS) {
+ status = perform_channel_equalization_sequence(link,
+ link_res,
+ lt_settings,
+ DPRX);
}
}
return status;
}
-#if defined(CONFIG_DRM_AMD_DC_DCN)
static enum link_training_result dp_perform_128b_132b_link_training(
struct dc_link *link,
const struct link_resource *link_res,
@@ -2437,9 +2270,97 @@ static enum link_training_result dp_perform_128b_132b_link_training(
return result;
}
-#endif
-static enum link_training_result dc_link_dp_perform_fixed_vs_pe_training_sequence(
+static enum link_training_result perform_fixed_vs_pe_nontransparent_training_sequence(
+ struct dc_link *link,
+ const struct link_resource *link_res,
+ struct link_training_settings *lt_settings)
+{
+ enum link_training_result status = LINK_TRAINING_SUCCESS;
+ uint8_t lane = 0;
+ uint8_t toggle_rate = 0x6;
+ uint8_t target_rate = 0x6;
+ bool apply_toggle_rate_wa = false;
+ uint8_t repeater_cnt;
+ uint8_t repeater_id;
+
+ /* Fixed VS/PE specific: Force CR AUX RD Interval to at least 16ms */
+ if (lt_settings->cr_pattern_time < 16000)
+ lt_settings->cr_pattern_time = 16000;
+
+ /* Fixed VS/PE specific: Toggle link rate */
+ apply_toggle_rate_wa = (link->vendor_specific_lttpr_link_rate_wa == target_rate);
+ target_rate = get_dpcd_link_rate(&lt_settings->link_settings);
+ toggle_rate = (target_rate == 0x6) ? 0xA : 0x6;
+
+ if (apply_toggle_rate_wa)
+ lt_settings->link_settings.link_rate = toggle_rate;
+
+ if (link->ctx->dc->work_arounds.lt_early_cr_pattern)
+ start_clock_recovery_pattern_early(link, link_res, lt_settings, DPRX);
+
+ /* 1. set link rate, lane count and spread. */
+ dpcd_set_link_settings(link, lt_settings);
+
+ /* Fixed VS/PE specific: Toggle link rate back*/
+ if (apply_toggle_rate_wa) {
+ core_link_write_dpcd(
+ link,
+ DP_LINK_BW_SET,
+ &target_rate,
+ 1);
+ }
+
+ link->vendor_specific_lttpr_link_rate_wa = target_rate;
+
+ if (link->lttpr_mode == LTTPR_MODE_NON_TRANSPARENT) {
+
+ /* 2. perform link training (set link training done
+ * to false is done as well)
+ */
+ repeater_cnt = dp_convert_to_count(link->dpcd_caps.lttpr_caps.phy_repeater_cnt);
+
+ for (repeater_id = repeater_cnt; (repeater_id > 0 && status == LINK_TRAINING_SUCCESS);
+ repeater_id--) {
+ status = perform_clock_recovery_sequence(link, link_res, lt_settings, repeater_id);
+
+ if (status != LINK_TRAINING_SUCCESS) {
+ repeater_training_done(link, repeater_id);
+ break;
+ }
+
+ status = perform_channel_equalization_sequence(link,
+ link_res,
+ lt_settings,
+ repeater_id);
+
+ repeater_training_done(link, repeater_id);
+
+ if (status != LINK_TRAINING_SUCCESS)
+ break;
+
+ for (lane = 0; lane < LANE_COUNT_DP_MAX; lane++) {
+ lt_settings->dpcd_lane_settings[lane].raw = 0;
+ lt_settings->hw_lane_settings[lane].VOLTAGE_SWING = 0;
+ lt_settings->hw_lane_settings[lane].PRE_EMPHASIS = 0;
+ }
+ }
+ }
+
+ if (status == LINK_TRAINING_SUCCESS) {
+ status = perform_clock_recovery_sequence(link, link_res, lt_settings, DPRX);
+ if (status == LINK_TRAINING_SUCCESS) {
+ status = perform_channel_equalization_sequence(link,
+ link_res,
+ lt_settings,
+ DPRX);
+ }
+ }
+
+ return status;
+}
+
+static enum link_training_result dp_perform_fixed_vs_pe_training_sequence(
struct dc_link *link,
const struct link_resource *link_res,
struct link_training_settings *lt_settings)
@@ -2463,6 +2384,11 @@ static enum link_training_result dc_link_dp_perform_fixed_vs_pe_training_sequenc
ASSERT(dp_get_link_encoding_format(&lt_settings->link_settings) ==
DP_8b_10b_ENCODING);
+ if (link->lttpr_mode == LTTPR_MODE_NON_TRANSPARENT) {
+ status = perform_fixed_vs_pe_nontransparent_training_sequence(link, link_res, lt_settings);
+ return status;
+ }
+
if (offset != 0xFF) {
vendor_lttpr_write_address +=
((DP_REPEATER_CONFIGURATION_AND_STATUS_SIZE) * (offset - 1));
@@ -2514,11 +2440,7 @@ static enum link_training_result dc_link_dp_perform_fixed_vs_pe_training_sequenc
core_link_write_dpcd(link, DP_LANE_COUNT_SET,
&lane_count_set.raw, 1);
-#if defined(CONFIG_DRM_AMD_DC_DCN)
rate = get_dpcd_link_rate(&lt_settings->link_settings);
-#else
- rate = (uint8_t) (lt_settings->link_settings.link_rate);
-#endif
/* Vendor specific: Toggle link rate */
toggle_rate = (rate == 0x6) ? 0xA : 0x6;
@@ -2560,12 +2482,13 @@ static enum link_training_result dc_link_dp_perform_fixed_vs_pe_training_sequenc
retries_cr = 0;
retry_count = 0;
+ memset(&dpcd_lane_status, '\0', sizeof(dpcd_lane_status));
+ memset(&dpcd_lane_status_updated, '\0',
+ sizeof(dpcd_lane_status_updated));
+
while ((retries_cr < LINK_TRAINING_MAX_RETRY_COUNT) &&
(retry_count < LINK_TRAINING_MAX_CR_RETRY)) {
- memset(&dpcd_lane_status, '\0', sizeof(dpcd_lane_status));
- memset(&dpcd_lane_status_updated, '\0',
- sizeof(dpcd_lane_status_updated));
/* 1. call HWSS to set lane settings */
dp_set_hw_lane_settings(
@@ -2813,16 +2736,12 @@ enum link_training_result dc_link_dp_perform_link_training(
* Per DP specs starting from here, DPTX device shall not issue
* Non-LT AUX transactions inside training mode.
*/
- if (!link->dc->debug.apply_vendor_specific_lttpr_wa &&
- (link->chip_caps & EXT_DISPLAY_PATH_CAPS__DP_FIXED_VS_EN) &&
- link->lttpr_mode == LTTPR_MODE_TRANSPARENT)
- status = dc_link_dp_perform_fixed_vs_pe_training_sequence(link, link_res, &lt_settings);
+ if (link->chip_caps & EXT_DISPLAY_PATH_CAPS__DP_FIXED_VS_EN)
+ status = dp_perform_fixed_vs_pe_training_sequence(link, link_res, &lt_settings);
else if (encoding == DP_8b_10b_ENCODING)
status = dp_perform_8b_10b_link_training(link, link_res, &lt_settings);
-#if defined(CONFIG_DRM_AMD_DC_DCN)
else if (encoding == DP_128b_132b_ENCODING)
status = dp_perform_128b_132b_link_training(link, link_res, &lt_settings);
-#endif
else
ASSERT(0);
@@ -2863,27 +2782,21 @@ bool perform_link_training_with_retries(
struct dc_stream_state *stream = pipe_ctx->stream;
struct dc_link *link = stream->link;
enum dp_panel_mode panel_mode = dp_get_panel_mode(link);
- struct link_encoder *link_enc;
enum link_training_result status = LINK_TRAINING_CR_FAIL_LANE0;
struct dc_link_settings current_setting = *link_setting;
+ const struct link_hwss *link_hwss = get_link_hwss(link, &pipe_ctx->link_res);
+ int fail_count = 0;
- /* Dynamically assigned link encoders associated with stream rather than
- * link.
- */
- if (link->is_dig_mapping_flexible && link->dc->res_pool->funcs->link_encs_assign)
- link_enc = link_enc_cfg_get_link_enc_used_by_stream(link->ctx->dc, pipe_ctx->stream);
- else
- link_enc = link->link_enc;
+ dp_trace_commit_lt_init(link);
- /* We need to do this before the link training to ensure the idle pattern in SST
- * mode will be sent right after the link training
- */
- if (dp_get_link_encoding_format(&current_setting) == DP_8b_10b_ENCODING) {
- link_enc->funcs->connect_dig_be_to_fe(link_enc,
- pipe_ctx->stream_res.stream_enc->id, true);
- dp_source_sequence_trace(link, DPCD_SOURCE_SEQ_AFTER_CONNECT_DIG_FE_BE);
- }
+ if (dp_get_link_encoding_format(&current_setting) == DP_8b_10b_ENCODING)
+ /* We need to do this before the link training to ensure the idle
+ * pattern in SST mode will be sent right after the link training
+ */
+ link_hwss->setup_stream_encoder(pipe_ctx);
+
+ dp_trace_set_lt_start_timestamp(link, false);
for (j = 0; j < attempts; ++j) {
DC_LOG_HW_LINK_TRAINING("%s: Beginning link training attempt %u of %d\n",
@@ -2939,10 +2852,15 @@ bool perform_link_training_with_retries(
skip_video_pattern);
}
+ dp_trace_lt_total_count_increment(link, false);
+ dp_trace_lt_result_update(link, status, false);
+ dp_trace_set_lt_end_timestamp(link, false);
if (status == LINK_TRAINING_SUCCESS)
return true;
}
+ fail_count++;
+ dp_trace_lt_fail_count_update(link, fail_count, false);
/* latest link training still fail, skip delay and keep PHY on
*/
if (j == (attempts - 1) && link->ep_type == DISPLAY_ENDPOINT_PHY)
@@ -3074,14 +2992,10 @@ enum link_training_result dc_link_dp_sync_lt_attempt(
dp_cs_id, link_settings);
/* Set FEC enable */
-#if defined(CONFIG_DRM_AMD_DC_DCN)
if (dp_get_link_encoding_format(link_settings) == DP_8b_10b_ENCODING) {
-#endif
fec_enable = lt_overrides->fec_enable && *lt_overrides->fec_enable;
dp_set_fec_ready(link, NULL, fec_enable);
-#if defined(CONFIG_DRM_AMD_DC_DCN)
}
-#endif
if (lt_overrides->alternate_scrambler_reset) {
if (*lt_overrides->alternate_scrambler_reset)
@@ -3124,13 +3038,9 @@ bool dc_link_dp_sync_lt_end(struct dc_link *link, bool link_down)
* Still shouldn't turn off dp_receiver (DPCD:600h)
*/
if (link_down == true) {
-#if defined(CONFIG_DRM_AMD_DC_DCN)
struct dc_link_settings link_settings = link->cur_link_settings;
-#endif
dp_disable_link_phy(link, NULL, link->connector_signal);
-#if defined(CONFIG_DRM_AMD_DC_DCN)
if (dp_get_link_encoding_format(&link_settings) == DP_8b_10b_ENCODING)
-#endif
dp_set_fec_ready(link, NULL, false);
}
@@ -3138,7 +3048,6 @@ bool dc_link_dp_sync_lt_end(struct dc_link *link, bool link_down)
return true;
}
-#if defined(CONFIG_DRM_AMD_DC_DCN)
static enum dc_link_rate get_lttpr_max_link_rate(struct dc_link *link)
{
enum dc_link_rate lttpr_max_link_rate = link->dpcd_caps.lttpr_caps.max_link_rate;
@@ -3152,7 +3061,20 @@ static enum dc_link_rate get_lttpr_max_link_rate(struct dc_link *link)
return lttpr_max_link_rate;
}
-#endif
+
+static enum dc_link_rate get_cable_max_link_rate(struct dc_link *link)
+{
+ enum dc_link_rate cable_max_link_rate = LINK_RATE_HIGH3;
+
+ if (link->dpcd_caps.cable_id.bits.UHBR10_20_CAPABILITY & DP_UHBR20)
+ cable_max_link_rate = LINK_RATE_UHBR20;
+ else if (link->dpcd_caps.cable_id.bits.UHBR13_5_CAPABILITY)
+ cable_max_link_rate = LINK_RATE_UHBR13_5;
+ else if (link->dpcd_caps.cable_id.bits.UHBR10_20_CAPABILITY & DP_UHBR10)
+ cable_max_link_rate = LINK_RATE_UHBR10;
+
+ return cable_max_link_rate;
+}
bool dc_link_dp_get_max_link_enc_cap(const struct dc_link *link, struct dc_link_settings *max_link_enc_cap)
{
@@ -3163,16 +3085,7 @@ bool dc_link_dp_get_max_link_enc_cap(const struct dc_link *link, struct dc_link_
return false;
}
- /* Links supporting dynamically assigned link encoder will be assigned next
- * available encoder if one not already assigned.
- */
- if (link->is_dig_mapping_flexible &&
- link->dc->res_pool->funcs->link_encs_assign) {
- link_enc = link_enc_cfg_get_link_enc_used_by_link(link->ctx->dc, link);
- if (link_enc == NULL)
- link_enc = link_enc_cfg_get_next_avail_link_enc(link->ctx->dc);
- } else
- link_enc = link->link_enc;
+ link_enc = link_enc_cfg_get_link_enc(link);
ASSERT(link_enc);
if (link_enc && link_enc->funcs->get_max_link_cap) {
@@ -3186,37 +3099,21 @@ bool dc_link_dp_get_max_link_enc_cap(const struct dc_link *link, struct dc_link_
return false;
}
-static struct dc_link_settings get_max_link_cap(struct dc_link *link,
- const struct link_resource *link_res)
+
+struct dc_link_settings dp_get_max_link_cap(struct dc_link *link)
{
struct dc_link_settings max_link_cap = {0};
-#if defined(CONFIG_DRM_AMD_DC_DCN)
enum dc_link_rate lttpr_max_link_rate;
-#endif
+ enum dc_link_rate cable_max_link_rate;
struct link_encoder *link_enc = NULL;
- /* Links supporting dynamically assigned link encoder will be assigned next
- * available encoder if one not already assigned.
- */
- if (link->is_dig_mapping_flexible &&
- link->dc->res_pool->funcs->link_encs_assign) {
- link_enc = link_enc_cfg_get_link_enc_used_by_link(link->ctx->dc, link);
- if (link_enc == NULL)
- link_enc = link_enc_cfg_get_next_avail_link_enc(link->ctx->dc);
- } else
- link_enc = link->link_enc;
+
+ link_enc = link_enc_cfg_get_link_enc(link);
ASSERT(link_enc);
/* get max link encoder capability */
if (link_enc)
link_enc->funcs->get_max_link_cap(link_enc, &max_link_cap);
-#if defined(CONFIG_DRM_AMD_DC_DCN)
- if (max_link_cap.link_rate >= LINK_RATE_UHBR10) {
- if (!link_res->hpo_dp_link_enc ||
- link->dc->debug.disable_uhbr)
- max_link_cap.link_rate = LINK_RATE_HIGH3;
- }
-#endif
/* Lower link settings based on sink's link cap */
if (link->reported_link_cap.lane_count < max_link_cap.lane_count)
@@ -3229,6 +3126,14 @@ static struct dc_link_settings get_max_link_cap(struct dc_link *link,
max_link_cap.link_spread)
max_link_cap.link_spread =
link->reported_link_cap.link_spread;
+
+ /* Lower link settings based on cable attributes */
+ cable_max_link_rate = get_cable_max_link_rate(link);
+
+ if (!link->dc->debug.ignore_cable_id &&
+ cable_max_link_rate < max_link_cap.link_rate)
+ max_link_cap.link_rate = cable_max_link_rate;
+
/*
* account for lttpr repeaters cap
* notes: repeaters do not snoop in the DPRX Capabilities addresses (3.6.3).
@@ -3236,22 +3141,21 @@ static struct dc_link_settings get_max_link_cap(struct dc_link *link,
if (link->lttpr_mode != LTTPR_MODE_NON_LTTPR) {
if (link->dpcd_caps.lttpr_caps.max_lane_count < max_link_cap.lane_count)
max_link_cap.lane_count = link->dpcd_caps.lttpr_caps.max_lane_count;
-
-#if defined(CONFIG_DRM_AMD_DC_DCN)
lttpr_max_link_rate = get_lttpr_max_link_rate(link);
if (lttpr_max_link_rate < max_link_cap.link_rate)
max_link_cap.link_rate = lttpr_max_link_rate;
-#else
- if (link->dpcd_caps.lttpr_caps.max_link_rate < max_link_cap.link_rate)
- max_link_cap.link_rate = link->dpcd_caps.lttpr_caps.max_link_rate;
-#endif
DC_LOG_HW_LINK_TRAINING("%s\n Training with LTTPR, max_lane count %d max_link rate %d \n",
__func__,
max_link_cap.lane_count,
max_link_cap.link_rate);
}
+
+ if (dp_get_link_encoding_format(&max_link_cap) == DP_128b_132b_ENCODING &&
+ link->dc->debug.disable_uhbr)
+ max_link_cap.link_rate = LINK_RATE_HIGH3;
+
return max_link_cap;
}
@@ -3370,48 +3274,22 @@ bool hpd_rx_irq_check_link_loss_status(
return return_code;
}
-bool dp_verify_link_cap(
+static bool dp_verify_link_cap(
struct dc_link *link,
- const struct link_resource *link_res,
struct dc_link_settings *known_limit_link_setting,
int *fail_count)
{
- struct dc_link_settings max_link_cap = {0};
- struct dc_link_settings cur_link_setting = {0};
- struct dc_link_settings *cur = &cur_link_setting;
- struct dc_link_settings initial_link_settings = {0};
- bool success;
- bool skip_link_training;
+ struct dc_link_settings cur_link_settings = {0};
+ struct dc_link_settings initial_link_settings = *known_limit_link_setting;
+ bool success = false;
bool skip_video_pattern;
- enum clock_source_id dp_cs_id = CLOCK_SOURCE_ID_EXTERNAL;
- enum link_training_result status;
+ enum clock_source_id dp_cs_id = get_clock_source_id(link);
+ enum link_training_result status = LINK_TRAINING_SUCCESS;
union hpd_irq_data irq_data;
-
- /* link training starts with the maximum common settings
- * supported by both sink and ASIC.
- */
- max_link_cap = get_max_link_cap(link, link_res);
- initial_link_settings = get_common_supported_link_settings(
- *known_limit_link_setting,
- max_link_cap);
-
- /* Accept reported capabilities if link supports flexible encoder mapping or encoder already in use. */
- if (link->dc->debug.skip_detection_link_training ||
- link->is_dig_mapping_flexible) {
- /* TODO - should we check link encoder's max link caps here?
- * How do we know which link encoder to check from?
- */
- link->verified_link_cap = *known_limit_link_setting;
- return true;
- } else if (link->link_enc && link->dc->res_pool->funcs->link_encs_assign &&
- !link_enc_cfg_is_link_enc_avail(link->ctx->dc, link->link_enc->preferred_engine, link)) {
- link->verified_link_cap = initial_link_settings;
- return true;
- }
+ struct link_resource link_res;
memset(&irq_data, 0, sizeof(irq_data));
- success = false;
- skip_link_training = false;
+ cur_link_settings = initial_link_settings;
/* Grant extended timeout request */
if ((link->lttpr_mode == LTTPR_MODE_NON_TRANSPARENT) && (link->dpcd_caps.lttpr_caps.max_ext_timeout > 0)) {
@@ -3420,199 +3298,126 @@ bool dp_verify_link_cap(
core_link_write_dpcd(link, DP_PHY_REPEATER_EXTENDED_WAIT_TIMEOUT, &grant, sizeof(grant));
}
-#if defined(CONFIG_DRM_AMD_DC_DCN)
- if (dp_get_link_encoding_format(&link->cur_link_settings) == DP_128b_132b_ENCODING)
- reset_dp_hpo_stream_encoders_for_link(link);
-#endif
- /* TODO implement override and monitor patch later */
-
- /* try to train the link from high to low to
- * find the physical link capability
- */
- /* disable PHY done possible by BIOS, will be done by driver itself */
- dp_disable_link_phy(link, link_res, link->connector_signal);
-
- dp_cs_id = get_clock_source_id(link);
-
- cur_link_setting = initial_link_settings;
-
- /* Temporary Renoir-specific workaround for SWDEV-215184;
- * PHY will sometimes be in bad state on hotplugging display from certain USB-C dongle,
- * so add extra cycle of enabling and disabling the PHY before first link training.
- */
- if (link->link_enc && link->link_enc->features.flags.bits.DP_IS_USB_C &&
- link->dc->debug.usbc_combo_phy_reset_wa) {
- dp_enable_link_phy(link, link_res, link->connector_signal, dp_cs_id, cur);
- dp_disable_link_phy(link, link_res, link->connector_signal);
- }
-
do {
- skip_video_pattern = true;
-
- if (cur->link_rate == LINK_RATE_LOW)
- skip_video_pattern = false;
+ if (!get_temp_dp_link_res(link, &link_res, &cur_link_settings))
+ continue;
+ skip_video_pattern = cur_link_settings.link_rate != LINK_RATE_LOW;
dp_enable_link_phy(
link,
- link_res,
+ &link_res,
link->connector_signal,
dp_cs_id,
- cur);
+ &cur_link_settings);
+ status = dc_link_dp_perform_link_training(
+ link,
+ &link_res,
+ &cur_link_settings,
+ skip_video_pattern);
- if (skip_link_training)
+ if (status == LINK_TRAINING_SUCCESS) {
success = true;
- else {
- status = dc_link_dp_perform_link_training(
+ udelay(1000);
+ if (read_hpd_rx_irq_data(link, &irq_data) == DC_OK &&
+ hpd_rx_irq_check_link_loss_status(
link,
- link_res,
- cur,
- skip_video_pattern);
- if (status == LINK_TRAINING_SUCCESS)
- success = true;
- else
+ &irq_data))
(*fail_count)++;
- }
- if (success) {
- link->verified_link_cap = *cur;
- udelay(1000);
- if (read_hpd_rx_irq_data(link, &irq_data) == DC_OK)
- if (hpd_rx_irq_check_link_loss_status(
- link,
- &irq_data))
- (*fail_count)++;
+ } else {
+ (*fail_count)++;
}
- /* always disable the link before trying another
- * setting or before returning we'll enable it later
- * based on the actual mode we're driving
- */
- dp_disable_link_phy(link, link_res, link->connector_signal);
+ dp_trace_lt_total_count_increment(link, true);
+ dp_trace_lt_result_update(link, status, true);
+ dp_disable_link_phy(link, &link_res, link->connector_signal);
} while (!success && decide_fallback_link_setting(link,
- initial_link_settings, cur, status));
-
- /* Link Training failed for all Link Settings
- * (Lane Count is still unknown)
- */
- if (!success) {
- /* If all LT fails for all settings,
- * set verified = failed safe (1 lane low)
- */
- link->verified_link_cap.lane_count = LANE_COUNT_ONE;
- link->verified_link_cap.link_rate = LINK_RATE_LOW;
+ initial_link_settings, &cur_link_settings, status));
- link->verified_link_cap.link_spread =
- LINK_SPREAD_DISABLED;
- }
+ link->verified_link_cap = success ?
+ cur_link_settings : fail_safe_link_settings;
+ return success;
+}
+static void apply_usbc_combo_phy_reset_wa(struct dc_link *link,
+ struct dc_link_settings *link_settings)
+{
+ /* Temporary Renoir-specific workaround PHY will sometimes be in bad
+ * state on hotplugging display from certain USB-C dongle, so add extra
+ * cycle of enabling and disabling the PHY before first link training.
+ */
+ struct link_resource link_res = {0};
+ enum clock_source_id dp_cs_id = get_clock_source_id(link);
- return success;
+ dp_enable_link_phy(link, &link_res, link->connector_signal,
+ dp_cs_id, link_settings);
+ dp_disable_link_phy(link, &link_res, link->connector_signal);
}
bool dp_verify_link_cap_with_retries(
struct dc_link *link,
- const struct link_resource *link_res,
struct dc_link_settings *known_limit_link_setting,
int attempts)
{
int i = 0;
bool success = false;
+ int fail_count = 0;
+ dp_trace_detect_lt_init(link);
+
+ if (link->link_enc && link->link_enc->features.flags.bits.DP_IS_USB_C &&
+ link->dc->debug.usbc_combo_phy_reset_wa)
+ apply_usbc_combo_phy_reset_wa(link, known_limit_link_setting);
+
+ dp_trace_set_lt_start_timestamp(link, false);
for (i = 0; i < attempts; i++) {
- int fail_count = 0;
enum dc_connection_type type = dc_connection_none;
memset(&link->verified_link_cap, 0,
sizeof(struct dc_link_settings));
if (!dc_link_detect_sink(link, &type) || type == dc_connection_none) {
- link->verified_link_cap.lane_count = LANE_COUNT_ONE;
- link->verified_link_cap.link_rate = LINK_RATE_LOW;
- link->verified_link_cap.link_spread = LINK_SPREAD_DISABLED;
+ link->verified_link_cap = fail_safe_link_settings;
break;
- } else if (dp_verify_link_cap(link, link_res,
- known_limit_link_setting,
+ } else if (dp_verify_link_cap(link, known_limit_link_setting,
&fail_count) && fail_count == 0) {
success = true;
break;
}
msleep(10);
}
- return success;
-}
-bool dp_verify_mst_link_cap(
- struct dc_link *link, const struct link_resource *link_res)
-{
- struct dc_link_settings max_link_cap = {0};
+ dp_trace_lt_fail_count_update(link, fail_count, true);
+ dp_trace_set_lt_end_timestamp(link, true);
- if (dp_get_link_encoding_format(&link->reported_link_cap) ==
- DP_8b_10b_ENCODING) {
- max_link_cap = get_max_link_cap(link, link_res);
- link->verified_link_cap = get_common_supported_link_settings(
- link->reported_link_cap,
- max_link_cap);
- }
-#if defined(CONFIG_DRM_AMD_DC_DCN)
- else if (dp_get_link_encoding_format(&link->reported_link_cap) ==
- DP_128b_132b_ENCODING) {
- dp_verify_link_cap_with_retries(link,
- link_res,
- &link->reported_link_cap,
- LINK_TRAINING_MAX_VERIFY_RETRY);
- }
-#endif
- return true;
+ return success;
}
-static struct dc_link_settings get_common_supported_link_settings(
- struct dc_link_settings link_setting_a,
- struct dc_link_settings link_setting_b)
+/* in DP compliance test, DPR-120 may have
+ * a random value in its MAX_LINK_BW dpcd field.
+ * We map it to the maximum supported link rate that
+ * is smaller than MAX_LINK_BW in this case.
+ */
+static enum dc_link_rate get_link_rate_from_max_link_bw(
+ uint8_t max_link_bw)
{
- struct dc_link_settings link_settings = {0};
+ enum dc_link_rate link_rate;
- link_settings.lane_count =
- (link_setting_a.lane_count <=
- link_setting_b.lane_count) ?
- link_setting_a.lane_count :
- link_setting_b.lane_count;
- link_settings.link_rate =
- (link_setting_a.link_rate <=
- link_setting_b.link_rate) ?
- link_setting_a.link_rate :
- link_setting_b.link_rate;
- link_settings.link_spread = LINK_SPREAD_DISABLED;
-
- /* in DP compliance test, DPR-120 may have
- * a random value in its MAX_LINK_BW dpcd field.
- * We map it to the maximum supported link rate that
- * is smaller than MAX_LINK_BW in this case.
- */
-#if defined(CONFIG_DRM_AMD_DC_DCN)
- if (link_settings.link_rate > LINK_RATE_UHBR20) {
- link_settings.link_rate = LINK_RATE_UHBR20;
- } else if (link_settings.link_rate < LINK_RATE_UHBR20 &&
- link_settings.link_rate > LINK_RATE_UHBR13_5) {
- link_settings.link_rate = LINK_RATE_UHBR13_5;
- } else if (link_settings.link_rate < LINK_RATE_UHBR10 &&
- link_settings.link_rate > LINK_RATE_HIGH3) {
-#else
- if (link_settings.link_rate > LINK_RATE_HIGH3) {
-#endif
- link_settings.link_rate = LINK_RATE_HIGH3;
- } else if (link_settings.link_rate < LINK_RATE_HIGH3
- && link_settings.link_rate > LINK_RATE_HIGH2) {
- link_settings.link_rate = LINK_RATE_HIGH2;
- } else if (link_settings.link_rate < LINK_RATE_HIGH2
- && link_settings.link_rate > LINK_RATE_HIGH) {
- link_settings.link_rate = LINK_RATE_HIGH;
- } else if (link_settings.link_rate < LINK_RATE_HIGH
- && link_settings.link_rate > LINK_RATE_LOW) {
- link_settings.link_rate = LINK_RATE_LOW;
- } else if (link_settings.link_rate < LINK_RATE_LOW) {
- link_settings.link_rate = LINK_RATE_UNKNOWN;
+ if (max_link_bw >= LINK_RATE_HIGH3) {
+ link_rate = LINK_RATE_HIGH3;
+ } else if (max_link_bw < LINK_RATE_HIGH3
+ && max_link_bw >= LINK_RATE_HIGH2) {
+ link_rate = LINK_RATE_HIGH2;
+ } else if (max_link_bw < LINK_RATE_HIGH2
+ && max_link_bw >= LINK_RATE_HIGH) {
+ link_rate = LINK_RATE_HIGH;
+ } else if (max_link_bw < LINK_RATE_HIGH
+ && max_link_bw >= LINK_RATE_LOW) {
+ link_rate = LINK_RATE_LOW;
+ } else {
+ link_rate = LINK_RATE_UNKNOWN;
}
- return link_settings;
+ return link_rate;
}
static inline bool reached_minimum_lane_count(enum dc_lane_count lane_count)
@@ -3642,14 +3447,12 @@ static enum dc_lane_count reduce_lane_count(enum dc_lane_count lane_count)
static enum dc_link_rate reduce_link_rate(enum dc_link_rate link_rate)
{
switch (link_rate) {
-#if defined(CONFIG_DRM_AMD_DC_DCN)
case LINK_RATE_UHBR20:
return LINK_RATE_UHBR13_5;
case LINK_RATE_UHBR13_5:
return LINK_RATE_UHBR10;
case LINK_RATE_UHBR10:
return LINK_RATE_HIGH3;
-#endif
case LINK_RATE_HIGH3:
return LINK_RATE_HIGH2;
case LINK_RATE_HIGH2:
@@ -3675,7 +3478,8 @@ static enum dc_lane_count increase_lane_count(enum dc_lane_count lane_count)
}
}
-static enum dc_link_rate increase_link_rate(enum dc_link_rate link_rate)
+static enum dc_link_rate increase_link_rate(struct dc_link *link,
+ enum dc_link_rate link_rate)
{
switch (link_rate) {
case LINK_RATE_LOW:
@@ -3684,27 +3488,37 @@ static enum dc_link_rate increase_link_rate(enum dc_link_rate link_rate)
return LINK_RATE_HIGH2;
case LINK_RATE_HIGH2:
return LINK_RATE_HIGH3;
-#if defined(CONFIG_DRM_AMD_DC_DCN)
case LINK_RATE_HIGH3:
return LINK_RATE_UHBR10;
case LINK_RATE_UHBR10:
- return LINK_RATE_UHBR13_5;
+ /* upto DP2.x specs UHBR13.5 is the only link rate that could be
+ * not supported by DPRX when higher link rate is supported.
+ * so we treat it as a special case for code simplicity. When we
+ * have new specs with more link rates like this, we should
+ * consider a more generic solution to handle discrete link
+ * rate capabilities.
+ */
+ return link->dpcd_caps.dp_128b_132b_supported_link_rates.bits.UHBR13_5 ?
+ LINK_RATE_UHBR13_5 : LINK_RATE_UHBR20;
case LINK_RATE_UHBR13_5:
return LINK_RATE_UHBR20;
-#endif
default:
return LINK_RATE_UNKNOWN;
}
}
-#if defined(CONFIG_DRM_AMD_DC_DCN)
static bool decide_fallback_link_setting_max_bw_policy(
+ struct dc_link *link,
const struct dc_link_settings *max,
- struct dc_link_settings *cur)
+ struct dc_link_settings *cur,
+ enum link_training_result training_result)
{
uint8_t cur_idx = 0, next_idx;
bool found = false;
+ if (training_result == LINK_TRAINING_ABORT)
+ return false;
+
while (cur_idx < ARRAY_SIZE(dp_lt_fallbacks))
/* find current index */
if (dp_lt_fallbacks[cur_idx].lane_count == cur->lane_count &&
@@ -3717,11 +3531,22 @@ static bool decide_fallback_link_setting_max_bw_policy(
while (next_idx < ARRAY_SIZE(dp_lt_fallbacks))
/* find next index */
- if (dp_lt_fallbacks[next_idx].lane_count <= max->lane_count &&
- dp_lt_fallbacks[next_idx].link_rate <= max->link_rate)
- break;
- else
+ if (dp_lt_fallbacks[next_idx].lane_count > max->lane_count ||
+ dp_lt_fallbacks[next_idx].link_rate > max->link_rate)
next_idx++;
+ else if (dp_lt_fallbacks[next_idx].link_rate == LINK_RATE_UHBR13_5 &&
+ link->dpcd_caps.dp_128b_132b_supported_link_rates.bits.UHBR13_5 == 0)
+ /* upto DP2.x specs UHBR13.5 is the only link rate that
+ * could be not supported by DPRX when higher link rate
+ * is supported. so we treat it as a special case for
+ * code simplicity. When we have new specs with more
+ * link rates like this, we should consider a more
+ * generic solution to handle discrete link rate
+ * capabilities.
+ */
+ next_idx++;
+ else
+ break;
if (next_idx < ARRAY_SIZE(dp_lt_fallbacks)) {
cur->lane_count = dp_lt_fallbacks[next_idx].lane_count;
@@ -3731,7 +3556,6 @@ static bool decide_fallback_link_setting_max_bw_policy(
return found;
}
-#endif
/*
* function: set link rate and lane count fallback based
@@ -3749,12 +3573,10 @@ static bool decide_fallback_link_setting(
{
if (!current_link_setting)
return false;
-#if defined(CONFIG_DRM_AMD_DC_DCN)
if (dp_get_link_encoding_format(&initial_link_settings) == DP_128b_132b_ENCODING ||
link->dc->debug.force_dp2_lt_fallback_method)
- return decide_fallback_link_setting_max_bw_policy(&initial_link_settings,
- current_link_setting);
-#endif
+ return decide_fallback_link_setting_max_bw_policy(link, &initial_link_settings,
+ current_link_setting, training_result);
switch (training_result) {
case LINK_TRAINING_CR_FAIL_LANE0:
@@ -3801,6 +3623,7 @@ static bool decide_fallback_link_setting(
current_link_setting->link_rate =
reduce_link_rate(
current_link_setting->link_rate);
+ current_link_setting->lane_count = initial_link_settings.lane_count;
} else {
return false;
}
@@ -3813,6 +3636,7 @@ static bool decide_fallback_link_setting(
current_link_setting->link_rate =
reduce_link_rate(
current_link_setting->link_rate);
+ current_link_setting->lane_count = initial_link_settings.lane_count;
} else {
return false;
}
@@ -3907,7 +3731,7 @@ static bool decide_dp_link_settings(struct dc_link *link, struct dc_link_setting
current_link_setting.lane_count);
} else {
current_link_setting.link_rate =
- increase_link_rate(
+ increase_link_rate(link,
current_link_setting.link_rate);
current_link_setting.lane_count =
initial_link_setting.lane_count;
@@ -4022,7 +3846,7 @@ static bool decide_edp_link_settings_with_dsc(struct dc_link *link,
/* minimize lane */
if (current_link_setting.link_rate < max_link_rate) {
current_link_setting.link_rate =
- increase_link_rate(
+ increase_link_rate(link,
current_link_setting.link_rate);
} else {
if (current_link_setting.lane_count <
@@ -4043,7 +3867,7 @@ static bool decide_edp_link_settings_with_dsc(struct dc_link *link,
current_link_setting.lane_count);
} else {
current_link_setting.link_rate =
- increase_link_rate(
+ increase_link_rate(link,
current_link_setting.link_rate);
current_link_setting.lane_count =
initial_link_setting.lane_count;
@@ -4292,15 +4116,9 @@ static void dp_test_send_phy_test_pattern(struct dc_link *link)
union phy_test_pattern dpcd_test_pattern;
union lane_adjust dpcd_lane_adjustment[2];
unsigned char dpcd_post_cursor_2_adjustment = 0;
-#if defined(CONFIG_DRM_AMD_DC_DCN)
unsigned char test_pattern_buffer[
(DP_TEST_264BIT_CUSTOM_PATTERN_263_256 -
DP_TEST_264BIT_CUSTOM_PATTERN_7_0)+1] = {0};
-#else
- unsigned char test_pattern_buffer[
- (DP_TEST_80BIT_CUSTOM_PATTERN_79_72 -
- DP_TEST_80BIT_CUSTOM_PATTERN_7_0)+1] = {0};
-#endif
unsigned int test_pattern_size = 0;
enum dp_test_pattern test_pattern;
union lane_adjust dpcd_lane_adjust;
@@ -4326,7 +4144,7 @@ static void dp_test_send_phy_test_pattern(struct dc_link *link)
if (link->dc->debug.apply_vendor_specific_lttpr_wa &&
(link->chip_caps & EXT_DISPLAY_PATH_CAPS__DP_FIXED_VS_EN) &&
link->lttpr_mode == LTTPR_MODE_TRANSPARENT)
- vendor_specific_lttpr_wa_three_dpcd(
+ dp_fixed_vs_pe_read_lane_adjust(
link,
link_training_settings.dpcd_lane_settings);
@@ -4371,7 +4189,6 @@ static void dp_test_send_phy_test_pattern(struct dc_link *link)
case PHY_TEST_PATTERN_CP2520_3:
test_pattern = DP_TEST_PATTERN_TRAINING_PATTERN4;
break;
-#if defined(CONFIG_DRM_AMD_DC_DCN)
case PHY_TEST_PATTERN_128b_132b_TPS1:
test_pattern = DP_TEST_PATTERN_128b_132b_TPS1;
break;
@@ -4399,7 +4216,6 @@ static void dp_test_send_phy_test_pattern(struct dc_link *link)
case PHY_TEST_PATTERN_SQUARE_PULSE:
test_pattern = DP_TEST_PATTERN_SQUARE_PULSE;
break;
-#endif
default:
test_pattern = DP_TEST_PATTERN_VIDEO_MODE;
break;
@@ -4415,7 +4231,6 @@ static void dp_test_send_phy_test_pattern(struct dc_link *link)
test_pattern_size);
}
-#if defined(CONFIG_DRM_AMD_DC_DCN)
if (test_pattern == DP_TEST_PATTERN_SQUARE_PULSE) {
test_pattern_size = 1; // Square pattern data is 1 byte (DP spec)
core_link_read_dpcd(
@@ -4434,7 +4249,6 @@ static void dp_test_send_phy_test_pattern(struct dc_link *link)
test_pattern_buffer,
test_pattern_size);
}
-#endif
/* prepare link training settings */
link_training_settings.link_settings = link->cur_link_settings;
@@ -4455,14 +4269,11 @@ static void dp_test_send_phy_test_pattern(struct dc_link *link)
link_training_settings.hw_lane_settings[lane].POST_CURSOR2 =
(enum dc_post_cursor2)
((dpcd_post_cursor_2_adjustment >> (lane * 2)) & 0x03);
- }
-#if defined(CONFIG_DRM_AMD_DC_DCN)
- else if (dp_get_link_encoding_format(&link->cur_link_settings) ==
+ } else if (dp_get_link_encoding_format(&link->cur_link_settings) ==
DP_128b_132b_ENCODING) {
link_training_settings.hw_lane_settings[lane].FFE_PRESET.raw =
dpcd_lane_adjust.tx_ffe.PRESET_VALUE;
}
-#endif
}
dp_hw_to_dpcd_lane_settings(&link_training_settings,
@@ -4869,6 +4680,8 @@ bool dc_link_handle_hpd_rx_irq(struct dc_link *link, union hpd_irq_data *out_hpd
status = false;
if (out_link_loss)
*out_link_loss = true;
+
+ dp_trace_link_loss_increment(link);
}
if (link->type == dc_connection_sst_branch &&
@@ -4970,7 +4783,7 @@ uint32_t dc_link_bw_kbps_from_raw_frl_link_rate_data(uint8_t bw)
return 0;
}
-/**
+/*
* Return PCON's post FRL link training supported BW if its non-zero, otherwise return max_supported_frl_bw.
*/
static uint32_t intersect_frl_link_bw_support(
@@ -5159,7 +4972,6 @@ static void get_active_converter_info(
dp_hw_fw_revision.ieee_fw_rev,
sizeof(dp_hw_fw_revision.ieee_fw_rev));
}
-#if defined(CONFIG_DRM_AMD_DC_DCN)
if (link->dpcd_caps.dpcd_rev.raw >= DPCD_REV_14 &&
link->dpcd_caps.dongle_type != DISPLAY_DONGLE_NONE) {
union dp_dfp_cap_ext dfp_cap_ext;
@@ -5195,7 +5007,6 @@ static void get_active_converter_info(
DC_LOG_DP2("\tdfp_cap_ext.max_video_h_active_width = %d", link->dpcd_caps.dongle_caps.dfp_cap_ext.max_video_h_active_width);
DC_LOG_DP2("\tdfp_cap_ext.max_video_v_active_height = %d", link->dpcd_caps.dongle_caps.dfp_cap_ext.max_video_v_active_height);
}
-#endif
}
static void dp_wa_power_up_0010FA(struct dc_link *link, uint8_t *dpcd_data,
@@ -5255,12 +5066,8 @@ static bool dpcd_read_sink_ext_caps(struct dc_link *link)
bool dp_retrieve_lttpr_cap(struct dc_link *link)
{
-#if defined(CONFIG_DRM_AMD_DC_DCN)
uint8_t lttpr_dpcd_data[8];
bool allow_lttpr_non_transparent_mode = 0;
-#else
- uint8_t lttpr_dpcd_data[6];
-#endif
bool vbios_lttpr_enable = link->dc->caps.vbios_lttpr_enable;
bool vbios_lttpr_interop = link->dc->caps.vbios_lttpr_aware;
enum dc_status status = DC_ERROR_UNEXPECTED;
@@ -5268,7 +5075,6 @@ bool dp_retrieve_lttpr_cap(struct dc_link *link)
memset(lttpr_dpcd_data, '\0', sizeof(lttpr_dpcd_data));
-#if defined(CONFIG_DRM_AMD_DC_DCN)
if ((link->dc->config.allow_lttpr_non_transparent_mode.bits.DP2_0 &&
link->dpcd_caps.channel_coding_cap.bits.DP_128b_132b_SUPPORTED)) {
allow_lttpr_non_transparent_mode = 1;
@@ -5276,7 +5082,6 @@ bool dp_retrieve_lttpr_cap(struct dc_link *link)
!link->dpcd_caps.channel_coding_cap.bits.DP_128b_132b_SUPPORTED) {
allow_lttpr_non_transparent_mode = 1;
}
-#endif
/*
* Logic to determine LTTPR mode
@@ -5285,21 +5090,12 @@ bool dp_retrieve_lttpr_cap(struct dc_link *link)
if (vbios_lttpr_enable && vbios_lttpr_interop)
link->lttpr_mode = LTTPR_MODE_NON_TRANSPARENT;
else if (!vbios_lttpr_enable && vbios_lttpr_interop) {
-#if defined(CONFIG_DRM_AMD_DC_DCN)
if (allow_lttpr_non_transparent_mode)
-#else
- if (link->dc->config.allow_lttpr_non_transparent_mode)
-#endif
link->lttpr_mode = LTTPR_MODE_NON_TRANSPARENT;
else
link->lttpr_mode = LTTPR_MODE_TRANSPARENT;
} else if (!vbios_lttpr_enable && !vbios_lttpr_interop) {
-#if defined(CONFIG_DRM_AMD_DC_DCN)
if (!allow_lttpr_non_transparent_mode || !link->dc->caps.extended_aux_timeout_support)
-#else
- if (!link->dc->config.allow_lttpr_non_transparent_mode
- || !link->dc->caps.extended_aux_timeout_support)
-#endif
link->lttpr_mode = LTTPR_MODE_NON_LTTPR;
else
link->lttpr_mode = LTTPR_MODE_NON_TRANSPARENT;
@@ -5322,6 +5118,7 @@ bool dp_retrieve_lttpr_cap(struct dc_link *link)
sizeof(lttpr_dpcd_data));
if (status != DC_OK) {
DC_LOG_DP2("%s: Read LTTPR caps data failed.\n", __func__);
+ link->lttpr_mode = LTTPR_MODE_NON_LTTPR;
return false;
}
@@ -5349,7 +5146,6 @@ bool dp_retrieve_lttpr_cap(struct dc_link *link)
lttpr_dpcd_data[DP_PHY_REPEATER_EXTENDED_WAIT_TIMEOUT -
DP_LT_TUNABLE_PHY_REPEATER_FIELD_DATA_STRUCTURE_REV];
-#if defined(CONFIG_DRM_AMD_DC_DCN)
link->dpcd_caps.lttpr_caps.main_link_channel_coding.raw =
lttpr_dpcd_data[DP_MAIN_LINK_CHANNEL_CODING_PHY_REPEATER -
DP_LT_TUNABLE_PHY_REPEATER_FIELD_DATA_STRUCTURE_REV];
@@ -5357,12 +5153,10 @@ bool dp_retrieve_lttpr_cap(struct dc_link *link)
link->dpcd_caps.lttpr_caps.supported_128b_132b_rates.raw =
lttpr_dpcd_data[DP_PHY_REPEATER_128b_132b_RATES -
DP_LT_TUNABLE_PHY_REPEATER_FIELD_DATA_STRUCTURE_REV];
-#endif
/* Attempt to train in LTTPR transparent mode if repeater count exceeds 8. */
- is_lttpr_present = (dp_convert_to_count(link->dpcd_caps.lttpr_caps.phy_repeater_cnt) != 0 &&
+ is_lttpr_present = (link->dpcd_caps.lttpr_caps.max_lane_count > 0 &&
link->dpcd_caps.lttpr_caps.phy_repeater_cnt < 0xff &&
- link->dpcd_caps.lttpr_caps.max_lane_count > 0 &&
link->dpcd_caps.lttpr_caps.max_lane_count <= 4 &&
link->dpcd_caps.lttpr_caps.revision.raw >= 0x14);
if (is_lttpr_present) {
@@ -5374,6 +5168,54 @@ bool dp_retrieve_lttpr_cap(struct dc_link *link)
return is_lttpr_present;
}
+static bool get_usbc_cable_id(struct dc_link *link, union dp_cable_id *cable_id)
+{
+ union dmub_rb_cmd cmd;
+
+ if (!link->ctx->dmub_srv ||
+ link->ep_type != DISPLAY_ENDPOINT_PHY ||
+ link->link_enc->features.flags.bits.DP_IS_USB_C == 0)
+ return false;
+
+ memset(&cmd, 0, sizeof(cmd));
+ cmd.cable_id.header.type = DMUB_CMD_GET_USBC_CABLE_ID;
+ cmd.cable_id.header.payload_bytes = sizeof(cmd.cable_id.data);
+ cmd.cable_id.data.input.phy_inst = resource_transmitter_to_phy_idx(
+ link->dc, link->link_enc->transmitter);
+ if (dc_dmub_srv_cmd_with_reply_data(link->ctx->dmub_srv, &cmd) &&
+ cmd.cable_id.header.ret_status == 1)
+ cable_id->raw = cmd.cable_id.data.output_raw;
+
+ return cmd.cable_id.header.ret_status == 1;
+}
+
+static union dp_cable_id intersect_cable_id(
+ union dp_cable_id *a, union dp_cable_id *b)
+{
+ union dp_cable_id out;
+
+ out.bits.UHBR10_20_CAPABILITY = MIN(a->bits.UHBR10_20_CAPABILITY,
+ b->bits.UHBR10_20_CAPABILITY);
+ out.bits.UHBR13_5_CAPABILITY = MIN(a->bits.UHBR13_5_CAPABILITY,
+ b->bits.UHBR13_5_CAPABILITY);
+ out.bits.CABLE_TYPE = MAX(a->bits.CABLE_TYPE, b->bits.CABLE_TYPE);
+
+ return out;
+}
+
+static void retrieve_cable_id(struct dc_link *link)
+{
+ union dp_cable_id usbc_cable_id;
+
+ link->dpcd_caps.cable_id.raw = 0;
+ core_link_read_dpcd(link, DP_CABLE_ATTRIBUTES_UPDATED_BY_DPRX,
+ &link->dpcd_caps.cable_id.raw, sizeof(uint8_t));
+
+ if (get_usbc_cable_id(link, &usbc_cable_id))
+ link->dpcd_caps.cable_id = intersect_cable_id(
+ &link->dpcd_caps.cable_id, &usbc_cable_id);
+}
+
static bool retrieve_link_cap(struct dc_link *link)
{
/* DP_ADAPTER_CAP - DP_DPCD_REV + 1 == 16 and also DP_DSC_BITS_PER_PIXEL_INC - DP_DSC_SUPPORT + 1 == 16,
@@ -5516,6 +5358,9 @@ static bool retrieve_link_cap(struct dc_link *link)
read_dp_device_vendor_id(link);
+ /* TODO - decouple raw mst capability from policy decision */
+ link->dpcd_caps.is_mst_capable = is_mst_supported(link);
+
get_active_converter_info(ds_port.byte, link);
dp_wa_power_up_0010FA(link, dpcd_data, sizeof(dpcd_data));
@@ -5534,8 +5379,8 @@ static bool retrieve_link_cap(struct dc_link *link)
link->reported_link_cap.lane_count =
link->dpcd_caps.max_ln_count.bits.MAX_LANE_COUNT;
- link->reported_link_cap.link_rate = dpcd_data[
- DP_MAX_LINK_RATE - DP_DPCD_REV];
+ link->reported_link_cap.link_rate = get_link_rate_from_max_link_bw(
+ dpcd_data[DP_MAX_LINK_RATE - DP_DPCD_REV]);
link->reported_link_cap.link_spread =
link->dpcd_caps.max_down_spread.bits.MAX_DOWN_SPREAD ?
LINK_SPREAD_05_DOWNSPREAD_30KHZ : LINK_SPREAD_DISABLED;
@@ -5546,7 +5391,8 @@ static bool retrieve_link_cap(struct dc_link *link)
edp_config_cap.bits.ALT_SCRAMBLER_RESET;
link->dpcd_caps.dpcd_display_control_capable =
edp_config_cap.bits.DPCD_DISPLAY_CONTROL_CAPABLE;
-
+ link->dpcd_caps.channel_coding_cap.raw =
+ dpcd_data[DP_MAIN_LINK_CHANNEL_CODING - DP_DPCD_REV];
link->test_pattern_enabled = false;
link->compliance_test_state.raw = 0;
@@ -5597,6 +5443,26 @@ static bool retrieve_link_cap(struct dc_link *link)
dp_hw_fw_revision.ieee_fw_rev,
sizeof(dp_hw_fw_revision.ieee_fw_rev));
+ /* Quirk for Apple MBP 2018 15" Retina panels: wrong DP_MAX_LINK_RATE */
+ {
+ uint8_t str_mbp_2018[] = { 101, 68, 21, 103, 98, 97 };
+ uint8_t fwrev_mbp_2018[] = { 7, 4 };
+ uint8_t fwrev_mbp_2018_vega[] = { 8, 4 };
+
+ /* We also check for the firmware revision as 16,1 models have an
+ * identical device id and are incorrectly quirked otherwise.
+ */
+ if ((link->dpcd_caps.sink_dev_id == 0x0010fa) &&
+ !memcmp(link->dpcd_caps.sink_dev_id_str, str_mbp_2018,
+ sizeof(str_mbp_2018)) &&
+ (!memcmp(link->dpcd_caps.sink_fw_revision, fwrev_mbp_2018,
+ sizeof(fwrev_mbp_2018)) ||
+ !memcmp(link->dpcd_caps.sink_fw_revision, fwrev_mbp_2018_vega,
+ sizeof(fwrev_mbp_2018_vega)))) {
+ link->reported_link_cap.link_rate = LINK_RATE_RBR2;
+ }
+ }
+
memset(&link->dpcd_caps.dsc_caps, '\0',
sizeof(link->dpcd_caps.dsc_caps));
memset(&link->dpcd_caps.fec_cap, '\0', sizeof(link->dpcd_caps.fec_cap));
@@ -5612,7 +5478,6 @@ static bool retrieve_link_cap(struct dc_link *link)
DP_DSC_SUPPORT,
link->dpcd_caps.dsc_caps.dsc_basic_caps.raw,
sizeof(link->dpcd_caps.dsc_caps.dsc_basic_caps.raw));
-#if defined(CONFIG_DRM_AMD_DC_DCN)
if (link->dpcd_caps.dongle_type != DISPLAY_DONGLE_NONE) {
status = core_link_read_dpcd(
link,
@@ -5627,21 +5492,33 @@ static bool retrieve_link_cap(struct dc_link *link)
DC_LOG_DSC("\tBRANCH_MAX_LINE_WIDTH 0x%02x",
link->dpcd_caps.dsc_caps.dsc_branch_decoder_caps.fields.BRANCH_MAX_LINE_WIDTH);
}
-#else
- status = core_link_read_dpcd(
- link,
- DP_DSC_BRANCH_OVERALL_THROUGHPUT_0,
- link->dpcd_caps.dsc_caps.dsc_branch_decoder_caps.raw,
- sizeof(link->dpcd_caps.dsc_caps.dsc_branch_decoder_caps.raw));
+
+ /* Apply work around to disable FEC and DSC for USB4 tunneling in TBT3 compatibility mode
+ * only if required.
+ */
+ if (link->ep_type == DISPLAY_ENDPOINT_USB4_DPIA &&
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+ !link->dc->debug.dpia_debug.bits.disable_force_tbt3_work_around &&
#endif
+ link->dpcd_caps.is_branch_dev &&
+ link->dpcd_caps.branch_dev_id == DP_BRANCH_DEVICE_ID_90CC24 &&
+ link->dpcd_caps.branch_hw_revision == DP_BRANCH_HW_REV_10 &&
+ (link->dpcd_caps.fec_cap.bits.FEC_CAPABLE ||
+ link->dpcd_caps.dsc_caps.dsc_basic_caps.fields.dsc_support.DSC_SUPPORT)) {
+ /* A TBT3 device is expected to report no support for FEC or DSC to a USB4 DPIA.
+ * Clear FEC and DSC capabilities as a work around if that is not the case.
+ */
+ link->wa_flags.dpia_forced_tbt3_mode = true;
+ memset(&link->dpcd_caps.dsc_caps, '\0', sizeof(link->dpcd_caps.dsc_caps));
+ memset(&link->dpcd_caps.fec_cap, '\0', sizeof(link->dpcd_caps.fec_cap));
+ DC_LOG_DSC("Clear DSC SUPPORT for USB4 link(%d) in TBT3 compatibility mode", link->link_index);
+ } else
+ link->wa_flags.dpia_forced_tbt3_mode = false;
}
if (!dpcd_read_sink_ext_caps(link))
link->dpcd_sink_ext_caps.raw = 0;
-#if defined(CONFIG_DRM_AMD_DC_DCN)
- link->dpcd_caps.channel_coding_cap.raw = dpcd_data[DP_MAIN_LINK_CHANNEL_CODING_CAP - DP_DPCD_REV];
-
if (link->dpcd_caps.channel_coding_cap.bits.DP_128b_132b_SUPPORTED) {
DC_LOG_DP2("128b/132b encoding is supported at link %d", link->link_index);
@@ -5686,7 +5563,9 @@ static bool retrieve_link_cap(struct dc_link *link)
if (link->dpcd_caps.fec_cap1.bits.AGGREGATED_ERROR_COUNTERS_CAPABLE)
DC_LOG_DP2("\tFEC aggregated error counters are supported");
}
-#endif
+
+ retrieve_cable_id(link);
+ dpcd_write_cable_id_to_dprx(link);
/* Connectivity log: detection */
CONN_DATA_DETECT(link, dpcd_data, sizeof(dpcd_data), "Rx Caps: ");
@@ -5759,14 +5638,6 @@ bool dp_overwrite_extended_receiver_cap(struct dc_link *link)
bool detect_dp_sink_caps(struct dc_link *link)
{
return retrieve_link_cap(link);
-
- /* dc init_hw has power encoder using default
- * signal for connector. For native DP, no
- * need to power up encoder again. If not native
- * DP, hw_init may need check signal or power up
- * encoder here.
- */
- /* TODO save sink caps in link->sink */
}
static enum dc_link_rate linkRateInKHzToLinkRateMultiplier(uint32_t link_rate_in_khz)
@@ -5844,8 +5715,6 @@ void detect_edp_sink_caps(struct dc_link *link)
}
}
}
- link->verified_link_cap = link->reported_link_cap;
-
core_link_read_dpcd(link, DP_EDP_BACKLIGHT_ADJUSTMENT_CAP,
&backlight_adj_cap, sizeof(backlight_adj_cap));
@@ -5853,6 +5722,34 @@ void detect_edp_sink_caps(struct dc_link *link)
(backlight_adj_cap & DP_EDP_DYNAMIC_BACKLIGHT_CAP) ? true:false;
dc_link_set_default_brightness_aux(link);
+
+ core_link_read_dpcd(link, DP_EDP_DPCD_REV,
+ &link->dpcd_caps.edp_rev,
+ sizeof(link->dpcd_caps.edp_rev));
+ /*
+ * PSR is only valid for eDP v1.3 or higher.
+ */
+ if (link->dpcd_caps.edp_rev >= DP_EDP_13) {
+ core_link_read_dpcd(link, DP_PSR_SUPPORT,
+ &link->dpcd_caps.psr_info.psr_version,
+ sizeof(link->dpcd_caps.psr_info.psr_version));
+ core_link_read_dpcd(link, DP_PSR_CAPS,
+ &link->dpcd_caps.psr_info.psr_dpcd_caps.raw,
+ sizeof(link->dpcd_caps.psr_info.psr_dpcd_caps.raw));
+ if (link->dpcd_caps.psr_info.psr_dpcd_caps.bits.Y_COORDINATE_REQUIRED) {
+ core_link_read_dpcd(link, DP_PSR2_SU_Y_GRANULARITY,
+ &link->dpcd_caps.psr_info.psr2_su_y_granularity_cap,
+ sizeof(link->dpcd_caps.psr_info.psr2_su_y_granularity_cap));
+ }
+ }
+
+ /*
+ * ALPM is only valid for eDP v1.4 or higher.
+ */
+ if (link->dpcd_caps.dpcd_rev.raw >= DP_EDP_14)
+ core_link_read_dpcd(link, DP_RECEIVER_ALPM_CAP,
+ &link->dpcd_caps.alpm_caps.raw,
+ sizeof(link->dpcd_caps.alpm_caps.raw));
}
void dc_link_dp_enable_hpd(const struct dc_link *link)
@@ -6011,7 +5908,7 @@ static void set_crtc_test_pattern(struct dc_link *link,
else if (link->dc->hwss.set_disp_pattern_generator) {
struct pipe_ctx *odm_pipe;
int opp_cnt = 1;
- int dpg_width = width;
+ int dpg_width;
for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe)
opp_cnt++;
@@ -6110,15 +6007,14 @@ bool dc_link_dp_set_test_pattern(
if (link->dc->debug.apply_vendor_specific_lttpr_wa &&
(link->chip_caps & EXT_DISPLAY_PATH_CAPS__DP_FIXED_VS_EN) &&
link->lttpr_mode == LTTPR_MODE_TRANSPARENT) {
- dpcd_set_lane_settings(link, p_link_settings, DPRX);
- vendor_specific_lttpr_wa_five(
+ dp_fixed_vs_pe_set_retimer_lane_settings(
link,
p_link_settings->dpcd_lane_settings,
p_link_settings->link_settings.lane_count);
} else {
dp_set_hw_lane_settings(link, &pipe_ctx->link_res, p_link_settings, DPRX);
- dpcd_set_lane_settings(link, p_link_settings, DPRX);
}
+ dpcd_set_lane_settings(link, p_link_settings, DPRX);
}
/* Blank stream if running test pattern */
@@ -6168,7 +6064,6 @@ bool dc_link_dp_set_test_pattern(
case DP_TEST_PATTERN_CP2520_3:
pattern = PHY_TEST_PATTERN_CP2520_3;
break;
-#if defined(CONFIG_DRM_AMD_DC_DCN)
case DP_TEST_PATTERN_128b_132b_TPS1:
pattern = PHY_TEST_PATTERN_128b_132b_TPS1;
break;
@@ -6196,7 +6091,6 @@ bool dc_link_dp_set_test_pattern(
case DP_TEST_PATTERN_SQUARE_PULSE:
pattern = PHY_TEST_PATTERN_SQUARE_PULSE;
break;
-#endif
default:
return false;
}
@@ -6462,14 +6356,7 @@ enum dc_status dp_set_fec_ready(struct dc_link *link, const struct link_resource
enum dc_status status = DC_OK;
uint8_t fec_config = 0;
- /* Access link encoder based on whether it is statically
- * or dynamically assigned to a link.
- */
- if (link->is_dig_mapping_flexible &&
- link->dc->res_pool->funcs->link_encs_assign)
- link_enc = link_enc_cfg_get_link_enc_used_by_link(link->ctx->dc, link);
- else
- link_enc = link->link_enc;
+ link_enc = link_enc_cfg_get_link_enc(link);
ASSERT(link_enc);
if (!dc_link_should_enable_fec(link))
@@ -6509,14 +6396,7 @@ void dp_set_fec_enable(struct dc_link *link, bool enable)
{
struct link_encoder *link_enc = NULL;
- /* Access link encoder based on whether it is statically
- * or dynamically assigned to a link.
- */
- if (link->is_dig_mapping_flexible &&
- link->dc->res_pool->funcs->link_encs_assign)
- link_enc = link_enc_cfg_get_link_enc_used_by_link(link->ctx->dc, link);
- else
- link_enc = link->link_enc;
+ link_enc = link_enc_cfg_get_link_enc(link);
ASSERT(link_enc);
if (!dc_link_should_enable_fec(link))
@@ -6542,23 +6422,6 @@ void dp_set_fec_enable(struct dc_link *link, bool enable)
}
}
-struct link_encoder *dp_get_link_enc(struct dc_link *link)
-{
- struct link_encoder *link_enc;
-
- link_enc = link->link_enc;
- if (link->is_dig_mapping_flexible &&
- link->dc->res_pool->funcs->link_encs_assign) {
- link_enc = link_enc_cfg_get_link_enc_used_by_link(link->ctx->dc,
- link);
- if (!link->link_enc)
- link_enc = link_enc_cfg_get_next_avail_link_enc(
- link->ctx->dc);
- }
-
- return link_enc;
-}
-
void dpcd_set_source_specific_data(struct dc_link *link)
{
if (!link->dc->vendor_signature.is_valid) {
@@ -6635,6 +6498,20 @@ void dpcd_set_source_specific_data(struct dc_link *link)
}
}
+void dpcd_write_cable_id_to_dprx(struct dc_link *link)
+{
+ if (!link->dpcd_caps.channel_coding_cap.bits.DP_128b_132b_SUPPORTED ||
+ link->dpcd_caps.cable_id.raw == 0 ||
+ link->dprx_states.cable_id_written)
+ return;
+
+ core_link_write_dpcd(link, DP_CABLE_ATTRIBUTES_UPDATED_BY_DPTX,
+ &link->dpcd_caps.cable_id.raw,
+ sizeof(link->dpcd_caps.cable_id.raw));
+
+ link->dprx_states.cable_id_written = 1;
+}
+
bool dc_link_set_backlight_level_nits(struct dc_link *link,
bool isHDR,
uint32_t backlight_millinits,
@@ -6799,15 +6676,12 @@ enum dp_link_encoding dp_get_link_encoding_format(const struct dc_link_settings
if ((link_settings->link_rate >= LINK_RATE_LOW) &&
(link_settings->link_rate <= LINK_RATE_HIGH3))
return DP_8b_10b_ENCODING;
-#if defined(CONFIG_DRM_AMD_DC_DCN)
else if ((link_settings->link_rate >= LINK_RATE_UHBR10) &&
(link_settings->link_rate <= LINK_RATE_UHBR20))
return DP_128b_132b_ENCODING;
-#endif
return DP_UNKNOWN_ENCODING;
}
-#if defined(CONFIG_DRM_AMD_DC_DCN)
enum dp_link_encoding dc_link_dp_mst_decide_link_encoding_format(const struct dc_link *link)
{
struct dc_link_settings link_settings = {0};
@@ -6935,7 +6809,7 @@ bool dpcd_write_128b_132b_sst_payload_allocation_table(
}
}
retries++;
- udelay(5000);
+ msleep(5);
}
if (!result && retries == max_retries) {
@@ -6987,7 +6861,7 @@ bool dpcd_poll_for_allocation_change_trigger(struct dc_link *link)
break;
}
- udelay(5000);
+ msleep(5);
}
if (result == ACT_FAILED) {
@@ -7024,7 +6898,6 @@ bool is_dp_128b_132b_signal(struct pipe_ctx *pipe_ctx)
pipe_ctx->link_res.hpo_dp_link_enc &&
dc_is_dp_signal(pipe_ctx->stream->signal));
}
-#endif
void edp_panel_backlight_power_on(struct dc_link *link)
{
@@ -7036,3 +6909,621 @@ void edp_panel_backlight_power_on(struct dc_link *link)
if (link->dc->hwss.edp_backlight_control)
link->dc->hwss.edp_backlight_control(link, true);
}
+
+void dc_link_clear_dprx_states(struct dc_link *link)
+{
+ memset(&link->dprx_states, 0, sizeof(link->dprx_states));
+}
+
+void dp_receiver_power_ctrl(struct dc_link *link, bool on)
+{
+ uint8_t state;
+
+ state = on ? DP_POWER_STATE_D0 : DP_POWER_STATE_D3;
+
+ if (link->sync_lt_in_progress)
+ return;
+
+ core_link_write_dpcd(link, DP_SET_POWER, &state,
+ sizeof(state));
+
+}
+
+void dp_source_sequence_trace(struct dc_link *link, uint8_t dp_test_mode)
+{
+ if (link != NULL && link->dc->debug.enable_driver_sequence_debug)
+ core_link_write_dpcd(link, DP_SOURCE_SEQUENCE,
+ &dp_test_mode, sizeof(dp_test_mode));
+}
+
+
+static uint8_t convert_to_count(uint8_t lttpr_repeater_count)
+{
+ switch (lttpr_repeater_count) {
+ case 0x80: // 1 lttpr repeater
+ return 1;
+ case 0x40: // 2 lttpr repeaters
+ return 2;
+ case 0x20: // 3 lttpr repeaters
+ return 3;
+ case 0x10: // 4 lttpr repeaters
+ return 4;
+ case 0x08: // 5 lttpr repeaters
+ return 5;
+ case 0x04: // 6 lttpr repeaters
+ return 6;
+ case 0x02: // 7 lttpr repeaters
+ return 7;
+ case 0x01: // 8 lttpr repeaters
+ return 8;
+ default:
+ break;
+ }
+ return 0; // invalid value
+}
+
+static inline bool is_immediate_downstream(struct dc_link *link, uint32_t offset)
+{
+ return (convert_to_count(link->dpcd_caps.lttpr_caps.phy_repeater_cnt) == offset);
+}
+
+void dp_enable_link_phy(
+ struct dc_link *link,
+ const struct link_resource *link_res,
+ enum signal_type signal,
+ enum clock_source_id clock_source,
+ const struct dc_link_settings *link_settings)
+{
+ struct dc *dc = link->ctx->dc;
+ struct dmcu *dmcu = dc->res_pool->dmcu;
+ struct pipe_ctx *pipes =
+ link->dc->current_state->res_ctx.pipe_ctx;
+ struct clock_source *dp_cs =
+ link->dc->res_pool->dp_clock_source;
+ const struct link_hwss *link_hwss = get_link_hwss(link, link_res);
+ unsigned int i;
+
+ if (link->connector_signal == SIGNAL_TYPE_EDP) {
+ link->dc->hwss.edp_power_control(link, true);
+ link->dc->hwss.edp_wait_for_hpd_ready(link, true);
+ }
+
+ /* If the current pixel clock source is not DTO(happens after
+ * switching from HDMI passive dongle to DP on the same connector),
+ * switch the pixel clock source to DTO.
+ */
+ for (i = 0; i < MAX_PIPES; i++) {
+ if (pipes[i].stream != NULL &&
+ pipes[i].stream->link == link) {
+ if (pipes[i].clock_source != NULL &&
+ pipes[i].clock_source->id != CLOCK_SOURCE_ID_DP_DTO) {
+ pipes[i].clock_source = dp_cs;
+ pipes[i].stream_res.pix_clk_params.requested_pix_clk_100hz =
+ pipes[i].stream->timing.pix_clk_100hz;
+ pipes[i].clock_source->funcs->program_pix_clk(
+ pipes[i].clock_source,
+ &pipes[i].stream_res.pix_clk_params,
+ &pipes[i].pll_settings);
+ }
+ }
+ }
+
+ link->cur_link_settings = *link_settings;
+
+ if (dp_get_link_encoding_format(link_settings) == DP_8b_10b_ENCODING) {
+ if (dc->clk_mgr->funcs->notify_link_rate_change)
+ dc->clk_mgr->funcs->notify_link_rate_change(dc->clk_mgr, link);
+ }
+
+ if (dmcu != NULL && dmcu->funcs->lock_phy)
+ dmcu->funcs->lock_phy(dmcu);
+
+ if (link_hwss->ext.enable_dp_link_output)
+ link_hwss->ext.enable_dp_link_output(link, link_res, signal,
+ clock_source, link_settings);
+
+ if (dmcu != NULL && dmcu->funcs->unlock_phy)
+ dmcu->funcs->unlock_phy(dmcu);
+
+ dp_source_sequence_trace(link, DPCD_SOURCE_SEQ_AFTER_ENABLE_LINK_PHY);
+ dp_receiver_power_ctrl(link, true);
+}
+
+void edp_add_delay_for_T9(struct dc_link *link)
+{
+ if (link->local_sink &&
+ link->local_sink->edid_caps.panel_patch.extra_delay_backlight_off > 0)
+ udelay(link->local_sink->edid_caps.panel_patch.extra_delay_backlight_off * 1000);
+}
+
+bool edp_receiver_ready_T9(struct dc_link *link)
+{
+ unsigned int tries = 0;
+ unsigned char sinkstatus = 0;
+ unsigned char edpRev = 0;
+ enum dc_status result = DC_OK;
+
+ result = core_link_read_dpcd(link, DP_EDP_DPCD_REV, &edpRev, sizeof(edpRev));
+
+ /* start from eDP version 1.2, SINK_STAUS indicate the sink is ready.*/
+ if (result == DC_OK && edpRev >= DP_EDP_12) {
+ do {
+ sinkstatus = 1;
+ result = core_link_read_dpcd(link, DP_SINK_STATUS, &sinkstatus, sizeof(sinkstatus));
+ if (sinkstatus == 0)
+ break;
+ if (result != DC_OK)
+ break;
+ udelay(100); //MAx T9
+ } while (++tries < 50);
+ }
+
+ return result;
+}
+bool edp_receiver_ready_T7(struct dc_link *link)
+{
+ unsigned char sinkstatus = 0;
+ unsigned char edpRev = 0;
+ enum dc_status result = DC_OK;
+
+ /* use absolute time stamp to constrain max T7*/
+ unsigned long long enter_timestamp = 0;
+ unsigned long long finish_timestamp = 0;
+ unsigned long long time_taken_in_ns = 0;
+
+ result = core_link_read_dpcd(link, DP_EDP_DPCD_REV, &edpRev, sizeof(edpRev));
+
+ if (result == DC_OK && edpRev >= DP_EDP_12) {
+ /* start from eDP version 1.2, SINK_STAUS indicate the sink is ready.*/
+ enter_timestamp = dm_get_timestamp(link->ctx);
+ do {
+ sinkstatus = 0;
+ result = core_link_read_dpcd(link, DP_SINK_STATUS, &sinkstatus, sizeof(sinkstatus));
+ if (sinkstatus == 1)
+ break;
+ if (result != DC_OK)
+ break;
+ udelay(25);
+ finish_timestamp = dm_get_timestamp(link->ctx);
+ time_taken_in_ns = dm_get_elapse_time_in_ns(link->ctx, finish_timestamp, enter_timestamp);
+ } while (time_taken_in_ns < 50 * 1000000); //MAx T7 is 50ms
+ }
+
+ if (link->local_sink &&
+ link->local_sink->edid_caps.panel_patch.extra_t7_ms > 0)
+ udelay(link->local_sink->edid_caps.panel_patch.extra_t7_ms * 1000);
+
+ return result;
+}
+
+void dp_disable_link_phy(struct dc_link *link, const struct link_resource *link_res,
+ enum signal_type signal)
+{
+ struct dc *dc = link->ctx->dc;
+ struct dmcu *dmcu = dc->res_pool->dmcu;
+ const struct link_hwss *link_hwss = get_link_hwss(link, link_res);
+
+ if (!link->wa_flags.dp_keep_receiver_powered)
+ dp_receiver_power_ctrl(link, false);
+
+ if (signal == SIGNAL_TYPE_EDP) {
+ if (link->dc->hwss.edp_backlight_control)
+ link->dc->hwss.edp_backlight_control(link, false);
+ if (link_hwss->ext.disable_dp_link_output)
+ link_hwss->ext.disable_dp_link_output(link, link_res, signal);
+ link->dc->hwss.edp_power_control(link, false);
+ } else {
+ if (dmcu != NULL && dmcu->funcs->lock_phy)
+ dmcu->funcs->lock_phy(dmcu);
+ if (link_hwss->ext.disable_dp_link_output)
+ link_hwss->ext.disable_dp_link_output(link, link_res, signal);
+ if (dmcu != NULL && dmcu->funcs->unlock_phy)
+ dmcu->funcs->unlock_phy(dmcu);
+ }
+
+ dp_source_sequence_trace(link, DPCD_SOURCE_SEQ_AFTER_DISABLE_LINK_PHY);
+
+ /* Clear current link setting.*/
+ memset(&link->cur_link_settings, 0,
+ sizeof(link->cur_link_settings));
+
+ if (dc->clk_mgr->funcs->notify_link_rate_change)
+ dc->clk_mgr->funcs->notify_link_rate_change(dc->clk_mgr, link);
+}
+
+void dp_disable_link_phy_mst(struct dc_link *link, const struct link_resource *link_res,
+ enum signal_type signal)
+{
+ /* MST disable link only when no stream use the link */
+ if (link->mst_stream_alloc_table.stream_count > 0)
+ return;
+
+ dp_disable_link_phy(link, link_res, signal);
+
+ /* set the sink to SST mode after disabling the link */
+ dp_enable_mst_on_sink(link, false);
+}
+
+bool dp_set_hw_training_pattern(
+ struct dc_link *link,
+ const struct link_resource *link_res,
+ enum dc_dp_training_pattern pattern,
+ uint32_t offset)
+{
+ enum dp_test_pattern test_pattern = DP_TEST_PATTERN_UNSUPPORTED;
+
+ switch (pattern) {
+ case DP_TRAINING_PATTERN_SEQUENCE_1:
+ test_pattern = DP_TEST_PATTERN_TRAINING_PATTERN1;
+ break;
+ case DP_TRAINING_PATTERN_SEQUENCE_2:
+ test_pattern = DP_TEST_PATTERN_TRAINING_PATTERN2;
+ break;
+ case DP_TRAINING_PATTERN_SEQUENCE_3:
+ test_pattern = DP_TEST_PATTERN_TRAINING_PATTERN3;
+ break;
+ case DP_TRAINING_PATTERN_SEQUENCE_4:
+ test_pattern = DP_TEST_PATTERN_TRAINING_PATTERN4;
+ break;
+ case DP_128b_132b_TPS1:
+ test_pattern = DP_TEST_PATTERN_128b_132b_TPS1_TRAINING_MODE;
+ break;
+ case DP_128b_132b_TPS2:
+ test_pattern = DP_TEST_PATTERN_128b_132b_TPS2_TRAINING_MODE;
+ break;
+ default:
+ break;
+ }
+
+ dp_set_hw_test_pattern(link, link_res, test_pattern, NULL, 0);
+
+ return true;
+}
+
+void dp_set_hw_lane_settings(
+ struct dc_link *link,
+ const struct link_resource *link_res,
+ const struct link_training_settings *link_settings,
+ uint32_t offset)
+{
+ const struct link_hwss *link_hwss = get_link_hwss(link, link_res);
+
+ if ((link->lttpr_mode == LTTPR_MODE_NON_TRANSPARENT) && !is_immediate_downstream(link, offset))
+ return;
+
+ if (link_hwss->ext.set_dp_lane_settings)
+ link_hwss->ext.set_dp_lane_settings(link, link_res,
+ &link_settings->link_settings,
+ link_settings->hw_lane_settings);
+
+ memmove(link->cur_lane_setting,
+ link_settings->hw_lane_settings,
+ sizeof(link->cur_lane_setting));
+}
+
+void dp_set_hw_test_pattern(
+ struct dc_link *link,
+ const struct link_resource *link_res,
+ enum dp_test_pattern test_pattern,
+ uint8_t *custom_pattern,
+ uint32_t custom_pattern_size)
+{
+ const struct link_hwss *link_hwss = get_link_hwss(link, link_res);
+ struct encoder_set_dp_phy_pattern_param pattern_param = {0};
+
+ pattern_param.dp_phy_pattern = test_pattern;
+ pattern_param.custom_pattern = custom_pattern;
+ pattern_param.custom_pattern_size = custom_pattern_size;
+ pattern_param.dp_panel_mode = dp_get_panel_mode(link);
+
+ if (link_hwss->ext.set_dp_link_test_pattern)
+ link_hwss->ext.set_dp_link_test_pattern(link, link_res, &pattern_param);
+}
+
+void dp_retrain_link_dp_test(struct dc_link *link,
+ struct dc_link_settings *link_setting,
+ bool skip_video_pattern)
+{
+ struct pipe_ctx *pipes =
+ &link->dc->current_state->res_ctx.pipe_ctx[0];
+ unsigned int i;
+
+
+ for (i = 0; i < MAX_PIPES; i++) {
+ if (pipes[i].stream != NULL &&
+ !pipes[i].top_pipe && !pipes[i].prev_odm_pipe &&
+ pipes[i].stream->link != NULL &&
+ pipes[i].stream_res.stream_enc != NULL &&
+ pipes[i].stream->link == link) {
+ udelay(100);
+
+ pipes[i].stream_res.stream_enc->funcs->dp_blank(link,
+ pipes[i].stream_res.stream_enc);
+
+ /* disable any test pattern that might be active */
+ dp_set_hw_test_pattern(link, &pipes[i].link_res,
+ DP_TEST_PATTERN_VIDEO_MODE, NULL, 0);
+
+ dp_receiver_power_ctrl(link, false);
+
+ link->dc->hwss.disable_stream(&pipes[i]);
+ if ((&pipes[i])->stream_res.audio && !link->dc->debug.az_endpoint_mute_only)
+ (&pipes[i])->stream_res.audio->funcs->az_disable((&pipes[i])->stream_res.audio);
+
+ if (link->link_enc)
+ link->link_enc->funcs->disable_output(
+ link->link_enc,
+ SIGNAL_TYPE_DISPLAY_PORT);
+
+ /* Clear current link setting. */
+ memset(&link->cur_link_settings, 0,
+ sizeof(link->cur_link_settings));
+
+ perform_link_training_with_retries(
+ link_setting,
+ skip_video_pattern,
+ LINK_TRAINING_ATTEMPTS,
+ &pipes[i],
+ SIGNAL_TYPE_DISPLAY_PORT,
+ false);
+
+ link->dc->hwss.enable_stream(&pipes[i]);
+
+ link->dc->hwss.unblank_stream(&pipes[i],
+ link_setting);
+
+ if (pipes[i].stream_res.audio) {
+ /* notify audio driver for
+ * audio modes of monitor */
+ pipes[i].stream_res.audio->funcs->az_enable(
+ pipes[i].stream_res.audio);
+
+ /* un-mute audio */
+ /* TODO: audio should be per stream rather than
+ * per link */
+ pipes[i].stream_res.stream_enc->funcs->
+ audio_mute_control(
+ pipes[i].stream_res.stream_enc, false);
+ }
+ }
+ }
+}
+
+#undef DC_LOGGER
+#define DC_LOGGER \
+ dsc->ctx->logger
+static void dsc_optc_config_log(struct display_stream_compressor *dsc,
+ struct dsc_optc_config *config)
+{
+ uint32_t precision = 1 << 28;
+ uint32_t bytes_per_pixel_int = config->bytes_per_pixel / precision;
+ uint32_t bytes_per_pixel_mod = config->bytes_per_pixel % precision;
+ uint64_t ll_bytes_per_pix_fraq = bytes_per_pixel_mod;
+
+ /* 7 fractional digits decimal precision for bytes per pixel is enough because DSC
+ * bits per pixel precision is 1/16th of a pixel, which means bytes per pixel precision is
+ * 1/16/8 = 1/128 of a byte, or 0.0078125 decimal
+ */
+ ll_bytes_per_pix_fraq *= 10000000;
+ ll_bytes_per_pix_fraq /= precision;
+
+ DC_LOG_DSC("\tbytes_per_pixel 0x%08x (%d.%07d)",
+ config->bytes_per_pixel, bytes_per_pixel_int, (uint32_t)ll_bytes_per_pix_fraq);
+ DC_LOG_DSC("\tis_pixel_format_444 %d", config->is_pixel_format_444);
+ DC_LOG_DSC("\tslice_width %d", config->slice_width);
+}
+
+bool dp_set_dsc_on_rx(struct pipe_ctx *pipe_ctx, bool enable)
+{
+ struct dc *dc = pipe_ctx->stream->ctx->dc;
+ struct dc_stream_state *stream = pipe_ctx->stream;
+ bool result = false;
+
+ if (dc_is_virtual_signal(stream->signal) || IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment))
+ result = true;
+ else
+ result = dm_helpers_dp_write_dsc_enable(dc->ctx, stream, enable);
+ return result;
+}
+
+/* The stream with these settings can be sent (unblanked) only after DSC was enabled on RX first,
+ * i.e. after dp_enable_dsc_on_rx() had been called
+ */
+void dp_set_dsc_on_stream(struct pipe_ctx *pipe_ctx, bool enable)
+{
+ struct display_stream_compressor *dsc = pipe_ctx->stream_res.dsc;
+ struct dc *dc = pipe_ctx->stream->ctx->dc;
+ struct dc_stream_state *stream = pipe_ctx->stream;
+ struct pipe_ctx *odm_pipe;
+ int opp_cnt = 1;
+
+ for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe)
+ opp_cnt++;
+
+ if (enable) {
+ struct dsc_config dsc_cfg;
+ struct dsc_optc_config dsc_optc_cfg;
+ enum optc_dsc_mode optc_dsc_mode;
+
+ /* Enable DSC hw block */
+ dsc_cfg.pic_width = (stream->timing.h_addressable + stream->timing.h_border_left + stream->timing.h_border_right) / opp_cnt;
+ dsc_cfg.pic_height = stream->timing.v_addressable + stream->timing.v_border_top + stream->timing.v_border_bottom;
+ dsc_cfg.pixel_encoding = stream->timing.pixel_encoding;
+ dsc_cfg.color_depth = stream->timing.display_color_depth;
+ dsc_cfg.is_odm = pipe_ctx->next_odm_pipe ? true : false;
+ dsc_cfg.dc_dsc_cfg = stream->timing.dsc_cfg;
+ ASSERT(dsc_cfg.dc_dsc_cfg.num_slices_h % opp_cnt == 0);
+ dsc_cfg.dc_dsc_cfg.num_slices_h /= opp_cnt;
+
+ dsc->funcs->dsc_set_config(dsc, &dsc_cfg, &dsc_optc_cfg);
+ dsc->funcs->dsc_enable(dsc, pipe_ctx->stream_res.opp->inst);
+ for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe) {
+ struct display_stream_compressor *odm_dsc = odm_pipe->stream_res.dsc;
+
+ odm_dsc->funcs->dsc_set_config(odm_dsc, &dsc_cfg, &dsc_optc_cfg);
+ odm_dsc->funcs->dsc_enable(odm_dsc, odm_pipe->stream_res.opp->inst);
+ }
+ dsc_cfg.dc_dsc_cfg.num_slices_h *= opp_cnt;
+ dsc_cfg.pic_width *= opp_cnt;
+
+ optc_dsc_mode = dsc_optc_cfg.is_pixel_format_444 ? OPTC_DSC_ENABLED_444 : OPTC_DSC_ENABLED_NATIVE_SUBSAMPLED;
+
+ /* Enable DSC in encoder */
+ if (dc_is_dp_signal(stream->signal) && !IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment)
+ && !is_dp_128b_132b_signal(pipe_ctx)) {
+ DC_LOG_DSC("Setting stream encoder DSC config for engine %d:", (int)pipe_ctx->stream_res.stream_enc->id);
+ dsc_optc_config_log(dsc, &dsc_optc_cfg);
+ pipe_ctx->stream_res.stream_enc->funcs->dp_set_dsc_config(pipe_ctx->stream_res.stream_enc,
+ optc_dsc_mode,
+ dsc_optc_cfg.bytes_per_pixel,
+ dsc_optc_cfg.slice_width);
+
+ /* PPS SDP is set elsewhere because it has to be done after DIG FE is connected to DIG BE */
+ }
+
+ /* Enable DSC in OPTC */
+ DC_LOG_DSC("Setting optc DSC config for tg instance %d:", pipe_ctx->stream_res.tg->inst);
+ dsc_optc_config_log(dsc, &dsc_optc_cfg);
+ pipe_ctx->stream_res.tg->funcs->set_dsc_config(pipe_ctx->stream_res.tg,
+ optc_dsc_mode,
+ dsc_optc_cfg.bytes_per_pixel,
+ dsc_optc_cfg.slice_width);
+ } else {
+ /* disable DSC in OPTC */
+ pipe_ctx->stream_res.tg->funcs->set_dsc_config(
+ pipe_ctx->stream_res.tg,
+ OPTC_DSC_DISABLED, 0, 0);
+
+ /* disable DSC in stream encoder */
+ if (dc_is_dp_signal(stream->signal)) {
+ if (is_dp_128b_132b_signal(pipe_ctx))
+ pipe_ctx->stream_res.hpo_dp_stream_enc->funcs->dp_set_dsc_pps_info_packet(
+ pipe_ctx->stream_res.hpo_dp_stream_enc,
+ false,
+ NULL,
+ true);
+ else if (!IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment)) {
+ pipe_ctx->stream_res.stream_enc->funcs->dp_set_dsc_config(
+ pipe_ctx->stream_res.stream_enc,
+ OPTC_DSC_DISABLED, 0, 0);
+ pipe_ctx->stream_res.stream_enc->funcs->dp_set_dsc_pps_info_packet(
+ pipe_ctx->stream_res.stream_enc, false, NULL, true);
+ }
+ }
+
+ /* disable DSC block */
+ pipe_ctx->stream_res.dsc->funcs->dsc_disable(pipe_ctx->stream_res.dsc);
+ for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe)
+ odm_pipe->stream_res.dsc->funcs->dsc_disable(odm_pipe->stream_res.dsc);
+ }
+}
+
+bool dp_set_dsc_enable(struct pipe_ctx *pipe_ctx, bool enable)
+{
+ struct display_stream_compressor *dsc = pipe_ctx->stream_res.dsc;
+ bool result = false;
+
+ if (!pipe_ctx->stream->timing.flags.DSC)
+ goto out;
+ if (!dsc)
+ goto out;
+
+ if (enable) {
+ {
+ dp_set_dsc_on_stream(pipe_ctx, true);
+ result = true;
+ }
+ } else {
+ dp_set_dsc_on_rx(pipe_ctx, false);
+ dp_set_dsc_on_stream(pipe_ctx, false);
+ result = true;
+ }
+out:
+ return result;
+}
+
+/*
+ * For dynamic bpp change case, dsc is programmed with MASTER_UPDATE_LOCK enabled;
+ * hence PPS info packet update need to use frame update instead of immediate update.
+ * Added parameter immediate_update for this purpose.
+ * The decision to use frame update is hard-coded in function dp_update_dsc_config(),
+ * which is the only place where a "false" would be passed in for param immediate_update.
+ *
+ * immediate_update is only applicable when DSC is enabled.
+ */
+bool dp_set_dsc_pps_sdp(struct pipe_ctx *pipe_ctx, bool enable, bool immediate_update)
+{
+ struct display_stream_compressor *dsc = pipe_ctx->stream_res.dsc;
+ struct dc_stream_state *stream = pipe_ctx->stream;
+
+ if (!pipe_ctx->stream->timing.flags.DSC || !dsc)
+ return false;
+
+ if (enable) {
+ struct dsc_config dsc_cfg;
+ uint8_t dsc_packed_pps[128];
+
+ memset(&dsc_cfg, 0, sizeof(dsc_cfg));
+ memset(dsc_packed_pps, 0, 128);
+
+ /* Enable DSC hw block */
+ dsc_cfg.pic_width = stream->timing.h_addressable + stream->timing.h_border_left + stream->timing.h_border_right;
+ dsc_cfg.pic_height = stream->timing.v_addressable + stream->timing.v_border_top + stream->timing.v_border_bottom;
+ dsc_cfg.pixel_encoding = stream->timing.pixel_encoding;
+ dsc_cfg.color_depth = stream->timing.display_color_depth;
+ dsc_cfg.is_odm = pipe_ctx->next_odm_pipe ? true : false;
+ dsc_cfg.dc_dsc_cfg = stream->timing.dsc_cfg;
+
+ DC_LOG_DSC(" ");
+ dsc->funcs->dsc_get_packed_pps(dsc, &dsc_cfg, &dsc_packed_pps[0]);
+ if (dc_is_dp_signal(stream->signal)) {
+ DC_LOG_DSC("Setting stream encoder DSC PPS SDP for engine %d\n", (int)pipe_ctx->stream_res.stream_enc->id);
+ if (is_dp_128b_132b_signal(pipe_ctx))
+ pipe_ctx->stream_res.hpo_dp_stream_enc->funcs->dp_set_dsc_pps_info_packet(
+ pipe_ctx->stream_res.hpo_dp_stream_enc,
+ true,
+ &dsc_packed_pps[0],
+ immediate_update);
+ else
+ pipe_ctx->stream_res.stream_enc->funcs->dp_set_dsc_pps_info_packet(
+ pipe_ctx->stream_res.stream_enc,
+ true,
+ &dsc_packed_pps[0],
+ immediate_update);
+ }
+ } else {
+ /* disable DSC PPS in stream encoder */
+ if (dc_is_dp_signal(stream->signal)) {
+ if (is_dp_128b_132b_signal(pipe_ctx))
+ pipe_ctx->stream_res.hpo_dp_stream_enc->funcs->dp_set_dsc_pps_info_packet(
+ pipe_ctx->stream_res.hpo_dp_stream_enc,
+ false,
+ NULL,
+ true);
+ else
+ pipe_ctx->stream_res.stream_enc->funcs->dp_set_dsc_pps_info_packet(
+ pipe_ctx->stream_res.stream_enc, false, NULL, true);
+ }
+ }
+
+ return true;
+}
+
+
+bool dp_update_dsc_config(struct pipe_ctx *pipe_ctx)
+{
+ struct display_stream_compressor *dsc = pipe_ctx->stream_res.dsc;
+
+ if (!pipe_ctx->stream->timing.flags.DSC)
+ return false;
+ if (!dsc)
+ return false;
+
+ dp_set_dsc_on_stream(pipe_ctx, true);
+ dp_set_dsc_pps_sdp(pipe_ctx, true, false);
+ return true;
+}
+
+#undef DC_LOGGER
+#define DC_LOGGER \
+ link->ctx->logger
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_dpcd.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_dpcd.c
index 7f25c11f4248..48a18766f002 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link_dpcd.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_dpcd.c
@@ -27,7 +27,7 @@
#include <dc_link.h>
#include <inc/link_hwss.h>
#include <inc/link_dpcd.h>
-#include "drm/drm_dp_helper.h"
+#include <drm/dp/drm_dp_helper.h>
#include <dc_dp_types.h>
#include "dm_helpers.h"
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_enc_cfg.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_enc_cfg.c
index a55944da8d53..42da7f430113 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link_enc_cfg.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_enc_cfg.c
@@ -122,6 +122,7 @@ static void remove_link_enc_assignment(
stream->link_enc = NULL;
state->res_ctx.link_enc_cfg_ctx.link_enc_assignments[i].eng_id = ENGINE_ID_UNKNOWN;
state->res_ctx.link_enc_cfg_ctx.link_enc_assignments[i].stream = NULL;
+ dc_stream_release(stream);
break;
}
}
@@ -271,6 +272,13 @@ void link_enc_cfg_init(
state->res_ctx.link_enc_cfg_ctx.mode = LINK_ENC_CFG_STEADY;
}
+void link_enc_cfg_copy(const struct dc_state *src_ctx, struct dc_state *dst_ctx)
+{
+ memcpy(&dst_ctx->res_ctx.link_enc_cfg_ctx,
+ &src_ctx->res_ctx.link_enc_cfg_ctx,
+ sizeof(dst_ctx->res_ctx.link_enc_cfg_ctx));
+}
+
void link_enc_cfg_link_encs_assign(
struct dc *dc,
struct dc_state *state,
@@ -486,7 +494,8 @@ struct link_encoder *link_enc_cfg_get_next_avail_link_enc(struct dc *dc)
}
for (i = 0; i < dc->res_pool->res_cap->num_dig_link_enc; i++) {
- if (encs_assigned[i] == ENGINE_ID_UNKNOWN) {
+ if (encs_assigned[i] == ENGINE_ID_UNKNOWN &&
+ dc->res_pool->link_encoders[i] != NULL) {
link_enc = dc->res_pool->link_encoders[i];
break;
}
@@ -506,6 +515,26 @@ struct link_encoder *link_enc_cfg_get_link_enc_used_by_stream(
return link_enc;
}
+struct link_encoder *link_enc_cfg_get_link_enc(
+ const struct dc_link *link)
+{
+ struct link_encoder *link_enc = NULL;
+
+ /* Links supporting dynamically assigned link encoder will be assigned next
+ * available encoder if one not already assigned.
+ */
+ if (link->is_dig_mapping_flexible &&
+ link->dc->res_pool->funcs->link_encs_assign) {
+ link_enc = link_enc_cfg_get_link_enc_used_by_link(link->ctx->dc, link);
+ if (link_enc == NULL)
+ link_enc = link_enc_cfg_get_next_avail_link_enc(
+ link->ctx->dc);
+ } else
+ link_enc = link->link_enc;
+
+ return link_enc;
+}
+
bool link_enc_cfg_is_link_enc_avail(struct dc *dc, enum engine_id eng_id, struct dc_link *link)
{
bool is_avail = true;
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_hwss.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_hwss.c
deleted file mode 100644
index 45d03d3a95c3..000000000000
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link_hwss.c
+++ /dev/null
@@ -1,917 +0,0 @@
-/* Copyright 2015 Advanced Micro Devices, Inc. */
-
-
-#include "dm_services.h"
-#include "dc.h"
-#include "inc/core_types.h"
-#include "include/ddc_service_types.h"
-#include "include/i2caux_interface.h"
-#include "link_hwss.h"
-#include "hw_sequencer.h"
-#include "dc_link_dp.h"
-#include "dc_link_ddc.h"
-#include "dm_helpers.h"
-#include "dpcd_defs.h"
-#include "dsc.h"
-#include "resource.h"
-#include "link_enc_cfg.h"
-#include "clk_mgr.h"
-#include "inc/link_dpcd.h"
-#include "dccg.h"
-
-static uint8_t convert_to_count(uint8_t lttpr_repeater_count)
-{
- switch (lttpr_repeater_count) {
- case 0x80: // 1 lttpr repeater
- return 1;
- case 0x40: // 2 lttpr repeaters
- return 2;
- case 0x20: // 3 lttpr repeaters
- return 3;
- case 0x10: // 4 lttpr repeaters
- return 4;
- case 0x08: // 5 lttpr repeaters
- return 5;
- case 0x04: // 6 lttpr repeaters
- return 6;
- case 0x02: // 7 lttpr repeaters
- return 7;
- case 0x01: // 8 lttpr repeaters
- return 8;
- default:
- break;
- }
- return 0; // invalid value
-}
-
-static inline bool is_immediate_downstream(struct dc_link *link, uint32_t offset)
-{
- return (convert_to_count(link->dpcd_caps.lttpr_caps.phy_repeater_cnt) == offset);
-}
-
-void dp_receiver_power_ctrl(struct dc_link *link, bool on)
-{
- uint8_t state;
-
- state = on ? DP_POWER_STATE_D0 : DP_POWER_STATE_D3;
-
- if (link->sync_lt_in_progress)
- return;
-
- core_link_write_dpcd(link, DP_SET_POWER, &state,
- sizeof(state));
-}
-
-void dp_source_sequence_trace(struct dc_link *link, uint8_t dp_test_mode)
-{
- if (link != NULL && link->dc->debug.enable_driver_sequence_debug)
- core_link_write_dpcd(link, DP_SOURCE_SEQUENCE,
- &dp_test_mode, sizeof(dp_test_mode));
-}
-
-void dp_enable_link_phy(
- struct dc_link *link,
- const struct link_resource *link_res,
- enum signal_type signal,
- enum clock_source_id clock_source,
- const struct dc_link_settings *link_settings)
-{
- struct link_encoder *link_enc;
- struct dc *dc = link->ctx->dc;
- struct dmcu *dmcu = dc->res_pool->dmcu;
-
- struct pipe_ctx *pipes =
- link->dc->current_state->res_ctx.pipe_ctx;
- struct clock_source *dp_cs =
- link->dc->res_pool->dp_clock_source;
- unsigned int i;
-
- /* Link should always be assigned encoder when en-/disabling. */
- if (link->is_dig_mapping_flexible && dc->res_pool->funcs->link_encs_assign)
- link_enc = link_enc_cfg_get_link_enc_used_by_link(dc, link);
- else
- link_enc = link->link_enc;
- ASSERT(link_enc);
-
- if (link->connector_signal == SIGNAL_TYPE_EDP) {
- link->dc->hwss.edp_power_control(link, true);
- link->dc->hwss.edp_wait_for_hpd_ready(link, true);
- }
-
- /* If the current pixel clock source is not DTO(happens after
- * switching from HDMI passive dongle to DP on the same connector),
- * switch the pixel clock source to DTO.
- */
- for (i = 0; i < MAX_PIPES; i++) {
- if (pipes[i].stream != NULL &&
- pipes[i].stream->link == link) {
- if (pipes[i].clock_source != NULL &&
- pipes[i].clock_source->id != CLOCK_SOURCE_ID_DP_DTO) {
- pipes[i].clock_source = dp_cs;
- pipes[i].stream_res.pix_clk_params.requested_pix_clk_100hz =
- pipes[i].stream->timing.pix_clk_100hz;
- pipes[i].clock_source->funcs->program_pix_clk(
- pipes[i].clock_source,
- &pipes[i].stream_res.pix_clk_params,
- &pipes[i].pll_settings);
- }
- }
- }
-
- link->cur_link_settings = *link_settings;
-
-#if defined(CONFIG_DRM_AMD_DC_DCN)
- if (dp_get_link_encoding_format(link_settings) == DP_128b_132b_ENCODING) {
- /* TODO - DP2.0 HW: notify link rate change here */
- } else if (dp_get_link_encoding_format(link_settings) == DP_8b_10b_ENCODING) {
- if (dc->clk_mgr->funcs->notify_link_rate_change)
- dc->clk_mgr->funcs->notify_link_rate_change(dc->clk_mgr, link);
- }
-#else
- if (dc->clk_mgr->funcs->notify_link_rate_change)
- dc->clk_mgr->funcs->notify_link_rate_change(dc->clk_mgr, link);
-#endif
- if (dmcu != NULL && dmcu->funcs->lock_phy)
- dmcu->funcs->lock_phy(dmcu);
-
-#if defined(CONFIG_DRM_AMD_DC_DCN)
- if (dp_get_link_encoding_format(link_settings) == DP_128b_132b_ENCODING) {
- enable_dp_hpo_output(link, link_res, link_settings);
- } else if (dp_get_link_encoding_format(link_settings) == DP_8b_10b_ENCODING) {
- if (dc_is_dp_sst_signal(signal)) {
- link_enc->funcs->enable_dp_output(
- link_enc,
- link_settings,
- clock_source);
- } else {
- link_enc->funcs->enable_dp_mst_output(
- link_enc,
- link_settings,
- clock_source);
- }
- }
-#else
- if (dc_is_dp_sst_signal(signal)) {
- link_enc->funcs->enable_dp_output(
- link_enc,
- link_settings,
- clock_source);
- } else {
- link_enc->funcs->enable_dp_mst_output(
- link_enc,
- link_settings,
- clock_source);
- }
-#endif
- if (dmcu != NULL && dmcu->funcs->unlock_phy)
- dmcu->funcs->unlock_phy(dmcu);
-
- dp_source_sequence_trace(link, DPCD_SOURCE_SEQ_AFTER_ENABLE_LINK_PHY);
- dp_receiver_power_ctrl(link, true);
-}
-
-void edp_add_delay_for_T9(struct dc_link *link)
-{
- if (link->local_sink &&
- link->local_sink->edid_caps.panel_patch.extra_delay_backlight_off > 0)
- udelay(link->local_sink->edid_caps.panel_patch.extra_delay_backlight_off * 1000);
-}
-
-bool edp_receiver_ready_T9(struct dc_link *link)
-{
- unsigned int tries = 0;
- unsigned char sinkstatus = 0;
- unsigned char edpRev = 0;
- enum dc_status result;
-
- result = core_link_read_dpcd(link, DP_EDP_DPCD_REV, &edpRev, sizeof(edpRev));
-
- /* start from eDP version 1.2, SINK_STAUS indicate the sink is ready.*/
- if (result == DC_OK && edpRev >= DP_EDP_12) {
- do {
- sinkstatus = 1;
- result = core_link_read_dpcd(link, DP_SINK_STATUS, &sinkstatus, sizeof(sinkstatus));
- if (sinkstatus == 0)
- break;
- if (result != DC_OK)
- break;
- udelay(100); //MAx T9
- } while (++tries < 50);
- }
-
- return result;
-}
-bool edp_receiver_ready_T7(struct dc_link *link)
-{
- unsigned char sinkstatus = 0;
- unsigned char edpRev = 0;
- enum dc_status result;
-
- /* use absolute time stamp to constrain max T7*/
- unsigned long long enter_timestamp = 0;
- unsigned long long finish_timestamp = 0;
- unsigned long long time_taken_in_ns = 0;
-
- result = core_link_read_dpcd(link, DP_EDP_DPCD_REV, &edpRev, sizeof(edpRev));
-
- if (result == DC_OK && edpRev >= DP_EDP_12) {
- /* start from eDP version 1.2, SINK_STAUS indicate the sink is ready.*/
- enter_timestamp = dm_get_timestamp(link->ctx);
- do {
- sinkstatus = 0;
- result = core_link_read_dpcd(link, DP_SINK_STATUS, &sinkstatus, sizeof(sinkstatus));
- if (sinkstatus == 1)
- break;
- if (result != DC_OK)
- break;
- udelay(25);
- finish_timestamp = dm_get_timestamp(link->ctx);
- time_taken_in_ns = dm_get_elapse_time_in_ns(link->ctx, finish_timestamp, enter_timestamp);
- } while (time_taken_in_ns < 50 * 1000000); //MAx T7 is 50ms
- }
-
- if (link->local_sink &&
- link->local_sink->edid_caps.panel_patch.extra_t7_ms > 0)
- udelay(link->local_sink->edid_caps.panel_patch.extra_t7_ms * 1000);
-
- return result;
-}
-
-void dp_disable_link_phy(struct dc_link *link, const struct link_resource *link_res,
- enum signal_type signal)
-{
- struct dc *dc = link->ctx->dc;
- struct dmcu *dmcu = dc->res_pool->dmcu;
-#if defined(CONFIG_DRM_AMD_DC_DCN)
- struct hpo_dp_link_encoder *hpo_link_enc = link_res->hpo_dp_link_enc;
-#endif
- struct link_encoder *link_enc;
-
- /* Link should always be assigned encoder when en-/disabling. */
- if (link->is_dig_mapping_flexible && dc->res_pool->funcs->link_encs_assign)
- link_enc = link_enc_cfg_get_link_enc_used_by_link(dc, link);
- else
- link_enc = link->link_enc;
- ASSERT(link_enc);
-
- if (!link->wa_flags.dp_keep_receiver_powered)
- dp_receiver_power_ctrl(link, false);
-
- if (signal == SIGNAL_TYPE_EDP) {
- if (link->dc->hwss.edp_backlight_control)
- link->dc->hwss.edp_backlight_control(link, false);
-#if defined(CONFIG_DRM_AMD_DC_DCN)
- if (dp_get_link_encoding_format(&link->cur_link_settings) == DP_128b_132b_ENCODING)
- disable_dp_hpo_output(link, link_res, signal);
- else
- link_enc->funcs->disable_output(link_enc, signal);
-#else
- link_enc->funcs->disable_output(link_enc, signal);
-#endif
- link->dc->hwss.edp_power_control(link, false);
- } else {
- if (dmcu != NULL && dmcu->funcs->lock_phy)
- dmcu->funcs->lock_phy(dmcu);
-
-#if defined(CONFIG_DRM_AMD_DC_DCN)
- if (dp_get_link_encoding_format(&link->cur_link_settings) == DP_128b_132b_ENCODING &&
- hpo_link_enc)
- disable_dp_hpo_output(link, link_res, signal);
- else
- link_enc->funcs->disable_output(link_enc, signal);
-#else
- link_enc->funcs->disable_output(link_enc, signal);
-#endif
- if (dmcu != NULL && dmcu->funcs->unlock_phy)
- dmcu->funcs->unlock_phy(dmcu);
- }
-
- dp_source_sequence_trace(link, DPCD_SOURCE_SEQ_AFTER_DISABLE_LINK_PHY);
-
- /* Clear current link setting.*/
- memset(&link->cur_link_settings, 0,
- sizeof(link->cur_link_settings));
-
- if (dc->clk_mgr->funcs->notify_link_rate_change)
- dc->clk_mgr->funcs->notify_link_rate_change(dc->clk_mgr, link);
-}
-
-void dp_disable_link_phy_mst(struct dc_link *link, const struct link_resource *link_res,
- enum signal_type signal)
-{
- /* MST disable link only when no stream use the link */
- if (link->mst_stream_alloc_table.stream_count > 0)
- return;
-
- dp_disable_link_phy(link, link_res, signal);
-
- /* set the sink to SST mode after disabling the link */
- dp_enable_mst_on_sink(link, false);
-}
-
-bool dp_set_hw_training_pattern(
- struct dc_link *link,
- const struct link_resource *link_res,
- enum dc_dp_training_pattern pattern,
- uint32_t offset)
-{
- enum dp_test_pattern test_pattern = DP_TEST_PATTERN_UNSUPPORTED;
-
- switch (pattern) {
- case DP_TRAINING_PATTERN_SEQUENCE_1:
- test_pattern = DP_TEST_PATTERN_TRAINING_PATTERN1;
- break;
- case DP_TRAINING_PATTERN_SEQUENCE_2:
- test_pattern = DP_TEST_PATTERN_TRAINING_PATTERN2;
- break;
- case DP_TRAINING_PATTERN_SEQUENCE_3:
- test_pattern = DP_TEST_PATTERN_TRAINING_PATTERN3;
- break;
- case DP_TRAINING_PATTERN_SEQUENCE_4:
- test_pattern = DP_TEST_PATTERN_TRAINING_PATTERN4;
- break;
-#if defined(CONFIG_DRM_AMD_DC_DCN)
- case DP_128b_132b_TPS1:
- test_pattern = DP_TEST_PATTERN_128b_132b_TPS1_TRAINING_MODE;
- break;
- case DP_128b_132b_TPS2:
- test_pattern = DP_TEST_PATTERN_128b_132b_TPS2_TRAINING_MODE;
- break;
-#endif
- default:
- break;
- }
-
- dp_set_hw_test_pattern(link, link_res, test_pattern, NULL, 0);
-
- return true;
-}
-
-#if defined(CONFIG_DRM_AMD_DC_DCN)
-#define DC_LOGGER \
- link->ctx->logger
-#endif
-void dp_set_hw_lane_settings(
- struct dc_link *link,
- const struct link_resource *link_res,
- const struct link_training_settings *link_settings,
- uint32_t offset)
-{
- struct link_encoder *encoder = link->link_enc;
-
- if ((link->lttpr_mode == LTTPR_MODE_NON_TRANSPARENT) && !is_immediate_downstream(link, offset))
- return;
-
- /* call Encoder to set lane settings */
-#if defined(CONFIG_DRM_AMD_DC_DCN)
- if (dp_get_link_encoding_format(&link_settings->link_settings) ==
- DP_128b_132b_ENCODING) {
- link_res->hpo_dp_link_enc->funcs->set_ffe(
- link_res->hpo_dp_link_enc,
- &link_settings->link_settings,
- link_settings->lane_settings[0].FFE_PRESET.raw);
- } else if (dp_get_link_encoding_format(&link_settings->link_settings)
- == DP_8b_10b_ENCODING) {
- encoder->funcs->dp_set_lane_settings(encoder, link_settings);
- }
-#else
- encoder->funcs->dp_set_lane_settings(encoder, link_settings);
-#endif
- memmove(link->cur_lane_setting,
- link_settings->lane_settings,
- sizeof(link->cur_lane_setting));
-}
-
-void dp_set_hw_test_pattern(
- struct dc_link *link,
- const struct link_resource *link_res,
- enum dp_test_pattern test_pattern,
- uint8_t *custom_pattern,
- uint32_t custom_pattern_size)
-{
- struct encoder_set_dp_phy_pattern_param pattern_param = {0};
- struct link_encoder *encoder;
-#if defined(CONFIG_DRM_AMD_DC_DCN)
- enum dp_link_encoding link_encoding_format = dp_get_link_encoding_format(&link->cur_link_settings);
-#endif
-
- /* Access link encoder based on whether it is statically
- * or dynamically assigned to a link.
- */
- if (link->is_dig_mapping_flexible &&
- link->dc->res_pool->funcs->link_encs_assign)
- encoder = link_enc_cfg_get_link_enc_used_by_link(link->ctx->dc, link);
- else
- encoder = link->link_enc;
-
- pattern_param.dp_phy_pattern = test_pattern;
- pattern_param.custom_pattern = custom_pattern;
- pattern_param.custom_pattern_size = custom_pattern_size;
- pattern_param.dp_panel_mode = dp_get_panel_mode(link);
-
-#if defined(CONFIG_DRM_AMD_DC_DCN)
- switch (link_encoding_format) {
- case DP_128b_132b_ENCODING:
- link_res->hpo_dp_link_enc->funcs->set_link_test_pattern(
- link_res->hpo_dp_link_enc, &pattern_param);
- break;
- case DP_8b_10b_ENCODING:
- ASSERT(encoder);
- encoder->funcs->dp_set_phy_pattern(encoder, &pattern_param);
- break;
- default:
- DC_LOG_ERROR("%s: Unknown link encoding format.", __func__);
- break;
- }
-#else
- encoder->funcs->dp_set_phy_pattern(encoder, &pattern_param);
-#endif
- dp_source_sequence_trace(link, DPCD_SOURCE_SEQ_AFTER_SET_SOURCE_PATTERN);
-}
-#if defined(CONFIG_DRM_AMD_DC_DCN)
-#undef DC_LOGGER
-#endif
-
-void dp_retrain_link_dp_test(struct dc_link *link,
- struct dc_link_settings *link_setting,
- bool skip_video_pattern)
-{
- struct pipe_ctx *pipes =
- &link->dc->current_state->res_ctx.pipe_ctx[0];
- unsigned int i;
-
- for (i = 0; i < MAX_PIPES; i++) {
- if (pipes[i].stream != NULL &&
- !pipes[i].top_pipe && !pipes[i].prev_odm_pipe &&
- pipes[i].stream->link != NULL &&
- pipes[i].stream_res.stream_enc != NULL &&
- pipes[i].stream->link == link) {
- udelay(100);
-
- pipes[i].stream_res.stream_enc->funcs->dp_blank(link,
- pipes[i].stream_res.stream_enc);
-
- /* disable any test pattern that might be active */
- dp_set_hw_test_pattern(link, &pipes[i].link_res,
- DP_TEST_PATTERN_VIDEO_MODE, NULL, 0);
-
- dp_receiver_power_ctrl(link, false);
-
- link->dc->hwss.disable_stream(&pipes[i]);
- if ((&pipes[i])->stream_res.audio && !link->dc->debug.az_endpoint_mute_only)
- (&pipes[i])->stream_res.audio->funcs->az_disable((&pipes[i])->stream_res.audio);
-
- if (link->link_enc)
- link->link_enc->funcs->disable_output(
- link->link_enc,
- SIGNAL_TYPE_DISPLAY_PORT);
-
- /* Clear current link setting. */
- memset(&link->cur_link_settings, 0,
- sizeof(link->cur_link_settings));
-
- perform_link_training_with_retries(
- link_setting,
- skip_video_pattern,
- LINK_TRAINING_ATTEMPTS,
- &pipes[i],
- SIGNAL_TYPE_DISPLAY_PORT,
- false);
-
- link->dc->hwss.enable_stream(&pipes[i]);
-
- link->dc->hwss.unblank_stream(&pipes[i],
- link_setting);
-
- if (pipes[i].stream_res.audio) {
- /* notify audio driver for
- * audio modes of monitor */
- pipes[i].stream_res.audio->funcs->az_enable(
- pipes[i].stream_res.audio);
-
- /* un-mute audio */
- /* TODO: audio should be per stream rather than
- * per link */
- pipes[i].stream_res.stream_enc->funcs->
- audio_mute_control(
- pipes[i].stream_res.stream_enc, false);
- }
- }
- }
-}
-
-#define DC_LOGGER \
- dsc->ctx->logger
-static void dsc_optc_config_log(struct display_stream_compressor *dsc,
- struct dsc_optc_config *config)
-{
- uint32_t precision = 1 << 28;
- uint32_t bytes_per_pixel_int = config->bytes_per_pixel / precision;
- uint32_t bytes_per_pixel_mod = config->bytes_per_pixel % precision;
- uint64_t ll_bytes_per_pix_fraq = bytes_per_pixel_mod;
-
- /* 7 fractional digits decimal precision for bytes per pixel is enough because DSC
- * bits per pixel precision is 1/16th of a pixel, which means bytes per pixel precision is
- * 1/16/8 = 1/128 of a byte, or 0.0078125 decimal
- */
- ll_bytes_per_pix_fraq *= 10000000;
- ll_bytes_per_pix_fraq /= precision;
-
- DC_LOG_DSC("\tbytes_per_pixel 0x%08x (%d.%07d)",
- config->bytes_per_pixel, bytes_per_pixel_int, (uint32_t)ll_bytes_per_pix_fraq);
- DC_LOG_DSC("\tis_pixel_format_444 %d", config->is_pixel_format_444);
- DC_LOG_DSC("\tslice_width %d", config->slice_width);
-}
-
-bool dp_set_dsc_on_rx(struct pipe_ctx *pipe_ctx, bool enable)
-{
- struct dc *dc = pipe_ctx->stream->ctx->dc;
- struct dc_stream_state *stream = pipe_ctx->stream;
- bool result = false;
-
- if (dc_is_virtual_signal(stream->signal) || IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment))
- result = true;
- else
- result = dm_helpers_dp_write_dsc_enable(dc->ctx, stream, enable);
- return result;
-}
-
-/* The stream with these settings can be sent (unblanked) only after DSC was enabled on RX first,
- * i.e. after dp_enable_dsc_on_rx() had been called
- */
-void dp_set_dsc_on_stream(struct pipe_ctx *pipe_ctx, bool enable)
-{
- struct display_stream_compressor *dsc = pipe_ctx->stream_res.dsc;
- struct dc *dc = pipe_ctx->stream->ctx->dc;
- struct dc_stream_state *stream = pipe_ctx->stream;
- struct pipe_ctx *odm_pipe;
- int opp_cnt = 1;
-
- for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe)
- opp_cnt++;
-
- if (enable) {
- struct dsc_config dsc_cfg;
- struct dsc_optc_config dsc_optc_cfg;
- enum optc_dsc_mode optc_dsc_mode;
-
- /* Enable DSC hw block */
- dsc_cfg.pic_width = (stream->timing.h_addressable + stream->timing.h_border_left + stream->timing.h_border_right) / opp_cnt;
- dsc_cfg.pic_height = stream->timing.v_addressable + stream->timing.v_border_top + stream->timing.v_border_bottom;
- dsc_cfg.pixel_encoding = stream->timing.pixel_encoding;
- dsc_cfg.color_depth = stream->timing.display_color_depth;
- dsc_cfg.is_odm = pipe_ctx->next_odm_pipe ? true : false;
- dsc_cfg.dc_dsc_cfg = stream->timing.dsc_cfg;
- ASSERT(dsc_cfg.dc_dsc_cfg.num_slices_h % opp_cnt == 0);
- dsc_cfg.dc_dsc_cfg.num_slices_h /= opp_cnt;
-
- dsc->funcs->dsc_set_config(dsc, &dsc_cfg, &dsc_optc_cfg);
- dsc->funcs->dsc_enable(dsc, pipe_ctx->stream_res.opp->inst);
- for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe) {
- struct display_stream_compressor *odm_dsc = odm_pipe->stream_res.dsc;
-
- odm_dsc->funcs->dsc_set_config(odm_dsc, &dsc_cfg, &dsc_optc_cfg);
- odm_dsc->funcs->dsc_enable(odm_dsc, odm_pipe->stream_res.opp->inst);
- }
- dsc_cfg.dc_dsc_cfg.num_slices_h *= opp_cnt;
- dsc_cfg.pic_width *= opp_cnt;
-
- optc_dsc_mode = dsc_optc_cfg.is_pixel_format_444 ? OPTC_DSC_ENABLED_444 : OPTC_DSC_ENABLED_NATIVE_SUBSAMPLED;
-
- /* Enable DSC in encoder */
-#if defined(CONFIG_DRM_AMD_DC_DCN)
- if (dc_is_dp_signal(stream->signal) && !IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment)
- && !is_dp_128b_132b_signal(pipe_ctx)) {
-#else
- if (dc_is_dp_signal(stream->signal) && !IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment)) {
-#endif
- DC_LOG_DSC("Setting stream encoder DSC config for engine %d:", (int)pipe_ctx->stream_res.stream_enc->id);
- dsc_optc_config_log(dsc, &dsc_optc_cfg);
- pipe_ctx->stream_res.stream_enc->funcs->dp_set_dsc_config(pipe_ctx->stream_res.stream_enc,
- optc_dsc_mode,
- dsc_optc_cfg.bytes_per_pixel,
- dsc_optc_cfg.slice_width);
-
- /* PPS SDP is set elsewhere because it has to be done after DIG FE is connected to DIG BE */
- }
-
- /* Enable DSC in OPTC */
- DC_LOG_DSC("Setting optc DSC config for tg instance %d:", pipe_ctx->stream_res.tg->inst);
- dsc_optc_config_log(dsc, &dsc_optc_cfg);
- pipe_ctx->stream_res.tg->funcs->set_dsc_config(pipe_ctx->stream_res.tg,
- optc_dsc_mode,
- dsc_optc_cfg.bytes_per_pixel,
- dsc_optc_cfg.slice_width);
- } else {
- /* disable DSC in OPTC */
- pipe_ctx->stream_res.tg->funcs->set_dsc_config(
- pipe_ctx->stream_res.tg,
- OPTC_DSC_DISABLED, 0, 0);
-
- /* disable DSC in stream encoder */
- if (dc_is_dp_signal(stream->signal)) {
-
-#if defined(CONFIG_DRM_AMD_DC_DCN)
- if (is_dp_128b_132b_signal(pipe_ctx))
- pipe_ctx->stream_res.hpo_dp_stream_enc->funcs->dp_set_dsc_pps_info_packet(
- pipe_ctx->stream_res.hpo_dp_stream_enc,
- false,
- NULL,
- true);
- else
-#endif
- if (!IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment)) {
- pipe_ctx->stream_res.stream_enc->funcs->dp_set_dsc_config(
- pipe_ctx->stream_res.stream_enc,
- OPTC_DSC_DISABLED, 0, 0);
- pipe_ctx->stream_res.stream_enc->funcs->dp_set_dsc_pps_info_packet(
- pipe_ctx->stream_res.stream_enc, false, NULL, true);
- }
- }
-
- /* disable DSC block */
- pipe_ctx->stream_res.dsc->funcs->dsc_disable(pipe_ctx->stream_res.dsc);
- for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe)
- odm_pipe->stream_res.dsc->funcs->dsc_disable(odm_pipe->stream_res.dsc);
- }
-}
-
-bool dp_set_dsc_enable(struct pipe_ctx *pipe_ctx, bool enable)
-{
- struct display_stream_compressor *dsc = pipe_ctx->stream_res.dsc;
- bool result = false;
-
- if (!pipe_ctx->stream->timing.flags.DSC)
- goto out;
- if (!dsc)
- goto out;
-
- if (enable) {
- {
- dp_set_dsc_on_stream(pipe_ctx, true);
- result = true;
- }
- } else {
- dp_set_dsc_on_rx(pipe_ctx, false);
- dp_set_dsc_on_stream(pipe_ctx, false);
- result = true;
- }
-out:
- return result;
-}
-
-/*
- * For dynamic bpp change case, dsc is programmed with MASTER_UPDATE_LOCK enabled;
- * hence PPS info packet update need to use frame update instead of immediate update.
- * Added parameter immediate_update for this purpose.
- * The decision to use frame update is hard-coded in function dp_update_dsc_config(),
- * which is the only place where a "false" would be passed in for param immediate_update.
- *
- * immediate_update is only applicable when DSC is enabled.
- */
-bool dp_set_dsc_pps_sdp(struct pipe_ctx *pipe_ctx, bool enable, bool immediate_update)
-{
- struct display_stream_compressor *dsc = pipe_ctx->stream_res.dsc;
- struct dc_stream_state *stream = pipe_ctx->stream;
-
- if (!pipe_ctx->stream->timing.flags.DSC || !dsc)
- return false;
-
- if (enable) {
- struct dsc_config dsc_cfg;
- uint8_t dsc_packed_pps[128];
-
- memset(&dsc_cfg, 0, sizeof(dsc_cfg));
- memset(dsc_packed_pps, 0, 128);
-
- /* Enable DSC hw block */
- dsc_cfg.pic_width = stream->timing.h_addressable + stream->timing.h_border_left + stream->timing.h_border_right;
- dsc_cfg.pic_height = stream->timing.v_addressable + stream->timing.v_border_top + stream->timing.v_border_bottom;
- dsc_cfg.pixel_encoding = stream->timing.pixel_encoding;
- dsc_cfg.color_depth = stream->timing.display_color_depth;
- dsc_cfg.is_odm = pipe_ctx->next_odm_pipe ? true : false;
- dsc_cfg.dc_dsc_cfg = stream->timing.dsc_cfg;
-
- DC_LOG_DSC(" ");
- dsc->funcs->dsc_get_packed_pps(dsc, &dsc_cfg, &dsc_packed_pps[0]);
- if (dc_is_dp_signal(stream->signal)) {
- DC_LOG_DSC("Setting stream encoder DSC PPS SDP for engine %d\n", (int)pipe_ctx->stream_res.stream_enc->id);
-#if defined(CONFIG_DRM_AMD_DC_DCN)
- if (is_dp_128b_132b_signal(pipe_ctx))
- pipe_ctx->stream_res.hpo_dp_stream_enc->funcs->dp_set_dsc_pps_info_packet(
- pipe_ctx->stream_res.hpo_dp_stream_enc,
- true,
- &dsc_packed_pps[0],
- immediate_update);
- else
-#endif
- pipe_ctx->stream_res.stream_enc->funcs->dp_set_dsc_pps_info_packet(
- pipe_ctx->stream_res.stream_enc,
- true,
- &dsc_packed_pps[0],
- immediate_update);
- }
- } else {
- /* disable DSC PPS in stream encoder */
- if (dc_is_dp_signal(stream->signal)) {
-#if defined(CONFIG_DRM_AMD_DC_DCN)
- if (is_dp_128b_132b_signal(pipe_ctx))
- pipe_ctx->stream_res.hpo_dp_stream_enc->funcs->dp_set_dsc_pps_info_packet(
- pipe_ctx->stream_res.hpo_dp_stream_enc,
- false,
- NULL,
- true);
- else
-#endif
- pipe_ctx->stream_res.stream_enc->funcs->dp_set_dsc_pps_info_packet(
- pipe_ctx->stream_res.stream_enc, false, NULL, true);
- }
- }
-
- return true;
-}
-
-
-bool dp_update_dsc_config(struct pipe_ctx *pipe_ctx)
-{
- struct display_stream_compressor *dsc = pipe_ctx->stream_res.dsc;
-
- if (!pipe_ctx->stream->timing.flags.DSC)
- return false;
- if (!dsc)
- return false;
-
- dp_set_dsc_on_stream(pipe_ctx, true);
- dp_set_dsc_pps_sdp(pipe_ctx, true, false);
- return true;
-}
-
-#if defined(CONFIG_DRM_AMD_DC_DCN)
-#undef DC_LOGGER
-#define DC_LOGGER \
- link->ctx->logger
-
-static enum phyd32clk_clock_source get_phyd32clk_src(struct dc_link *link)
-{
- switch (link->link_enc->transmitter) {
- case TRANSMITTER_UNIPHY_A:
- return PHYD32CLKA;
- case TRANSMITTER_UNIPHY_B:
- return PHYD32CLKB;
- case TRANSMITTER_UNIPHY_C:
- return PHYD32CLKC;
- case TRANSMITTER_UNIPHY_D:
- return PHYD32CLKD;
- case TRANSMITTER_UNIPHY_E:
- return PHYD32CLKE;
- default:
- return PHYD32CLKA;
- }
-}
-
-void enable_dp_hpo_output(struct dc_link *link,
- const struct link_resource *link_res,
- const struct dc_link_settings *link_settings)
-{
- const struct dc *dc = link->dc;
- enum phyd32clk_clock_source phyd32clk;
-
- /* Enable PHY PLL at target bit rate
- * UHBR10 = 10Gbps (SYMCLK32 = 312.5MHz)
- * UBR13.5 = 13.5Gbps (SYMCLK32 = 421.875MHz)
- * UHBR20 = 20Gbps (SYMCLK32 = 625MHz)
- */
- if (IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment)) {
- switch (link_settings->link_rate) {
- case LINK_RATE_UHBR10:
- dm_set_phyd32clk(dc->ctx, 312500);
- break;
- case LINK_RATE_UHBR13_5:
- dm_set_phyd32clk(dc->ctx, 412875);
- break;
- case LINK_RATE_UHBR20:
- dm_set_phyd32clk(dc->ctx, 625000);
- break;
- default:
- return;
- }
- } else {
- /* DP2.0 HW: call transmitter control to enable PHY */
- link_res->hpo_dp_link_enc->funcs->enable_link_phy(
- link_res->hpo_dp_link_enc,
- link_settings,
- link->link_enc->transmitter,
- link->link_enc->hpd_source);
- }
-
- /* DCCG muxing and DTBCLK DTO */
- if (IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment)) {
- dc->res_pool->dccg->funcs->set_physymclk(
- dc->res_pool->dccg,
- link->link_enc_hw_inst,
- PHYSYMCLK_FORCE_SRC_PHYD32CLK,
- true);
-
- phyd32clk = get_phyd32clk_src(link);
- dc->res_pool->dccg->funcs->enable_symclk32_le(
- dc->res_pool->dccg,
- link_res->hpo_dp_link_enc->inst,
- phyd32clk);
- link_res->hpo_dp_link_enc->funcs->link_enable(
- link_res->hpo_dp_link_enc,
- link_settings->lane_count);
- }
-}
-
-void disable_dp_hpo_output(struct dc_link *link,
- const struct link_resource *link_res,
- enum signal_type signal)
-{
- const struct dc *dc = link->dc;
-
- link_res->hpo_dp_link_enc->funcs->link_disable(link_res->hpo_dp_link_enc);
-
- if (IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment)) {
- dc->res_pool->dccg->funcs->disable_symclk32_le(
- dc->res_pool->dccg,
- link_res->hpo_dp_link_enc->inst);
-
- dc->res_pool->dccg->funcs->set_physymclk(
- dc->res_pool->dccg,
- link->link_enc_hw_inst,
- PHYSYMCLK_FORCE_SRC_SYMCLK,
- false);
-
- dm_set_phyd32clk(dc->ctx, 0);
- } else {
- /* DP2.0 HW: call transmitter control to disable PHY */
- link_res->hpo_dp_link_enc->funcs->disable_link_phy(
- link_res->hpo_dp_link_enc,
- signal);
- }
-}
-
-void setup_dp_hpo_stream(struct pipe_ctx *pipe_ctx, bool enable)
-{
- struct dc_stream_state *stream = pipe_ctx->stream;
- struct dc *dc = pipe_ctx->stream->ctx->dc;
- struct pipe_ctx *odm_pipe;
- int odm_combine_num_segments = 1;
- enum phyd32clk_clock_source phyd32clk;
-
- if (enable) {
- for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe)
- odm_combine_num_segments++;
-
- dc->res_pool->dccg->funcs->set_dpstreamclk(
- dc->res_pool->dccg,
- DTBCLK0,
- pipe_ctx->stream_res.tg->inst);
-
- phyd32clk = get_phyd32clk_src(stream->link);
- dc->res_pool->dccg->funcs->enable_symclk32_se(
- dc->res_pool->dccg,
- pipe_ctx->stream_res.hpo_dp_stream_enc->inst,
- phyd32clk);
-
- dc->res_pool->dccg->funcs->set_dtbclk_dto(
- dc->res_pool->dccg,
- pipe_ctx->stream_res.tg->inst,
- stream->phy_pix_clk,
- odm_combine_num_segments,
- &stream->timing);
- } else {
- dc->res_pool->dccg->funcs->set_dtbclk_dto(
- dc->res_pool->dccg,
- pipe_ctx->stream_res.tg->inst,
- 0,
- 0,
- &stream->timing);
- dc->res_pool->dccg->funcs->disable_symclk32_se(
- dc->res_pool->dccg,
- pipe_ctx->stream_res.hpo_dp_stream_enc->inst);
- dc->res_pool->dccg->funcs->set_dpstreamclk(
- dc->res_pool->dccg,
- REFCLK,
- pipe_ctx->stream_res.tg->inst);
- }
-}
-
-void reset_dp_hpo_stream_encoders_for_link(struct dc_link *link)
-{
- const struct dc *dc = link->dc;
- struct dc_state *state = dc->current_state;
- uint8_t i;
-
- for (i = 0; i < MAX_PIPES; i++) {
- if (state->res_ctx.pipe_ctx[i].stream_res.hpo_dp_stream_enc &&
- state->res_ctx.pipe_ctx[i].stream &&
- state->res_ctx.pipe_ctx[i].stream->link == link &&
- !state->res_ctx.pipe_ctx[i].stream->dpms_off) {
- setup_dp_hpo_stream(&state->res_ctx.pipe_ctx[i], false);
- }
- }
-}
-
-#undef DC_LOGGER
-#endif
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
index d4ff6cc6b8d9..7af153434e9e 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
@@ -43,6 +43,10 @@
#include "dpcd_defs.h"
#include "link_enc_cfg.h"
#include "dc_link_dp.h"
+#include "virtual/virtual_link_hwss.h"
+#include "link/link_hwss_dio.h"
+#include "link/link_hwss_dpia.h"
+#include "link/link_hwss_hpo_dp.h"
#if defined(CONFIG_DRM_AMD_DC_SI)
#include "dce60/dce60_resource.h"
@@ -62,6 +66,8 @@
#include "dcn302/dcn302_resource.h"
#include "dcn303/dcn303_resource.h"
#include "dcn31/dcn31_resource.h"
+#include "dcn315/dcn315_resource.h"
+#include "dcn316/dcn316_resource.h"
#endif
#define DC_LOGGER_INIT(logger)
@@ -131,7 +137,7 @@ enum dce_version resource_parse_asic_id(struct hw_asic_id asic_id)
case FAMILY_NV:
dc_version = DCN_VERSION_2_0;
- if (asic_id.chip_id == DEVICE_ID_NV_13FE) {
+ if (asic_id.chip_id == DEVICE_ID_NV_13FE || asic_id.chip_id == DEVICE_ID_NV_143F) {
dc_version = DCN_VERSION_2_01;
break;
}
@@ -151,6 +157,14 @@ enum dce_version resource_parse_asic_id(struct hw_asic_id asic_id)
if (ASICREV_IS_YELLOW_CARP(asic_id.hw_internal_rev))
dc_version = DCN_VERSION_3_1;
break;
+ case AMDGPU_FAMILY_GC_10_3_6:
+ if (ASICREV_IS_GC_10_3_6(asic_id.hw_internal_rev))
+ dc_version = DCN_VERSION_3_15;
+ break;
+ case AMDGPU_FAMILY_GC_10_3_7:
+ if (ASICREV_IS_GC_10_3_7(asic_id.hw_internal_rev))
+ dc_version = DCN_VERSION_3_16;
+ break;
#endif
default:
@@ -242,6 +256,12 @@ struct resource_pool *dc_create_resource_pool(struct dc *dc,
case DCN_VERSION_3_1:
res_pool = dcn31_create_resource_pool(init_data, dc);
break;
+ case DCN_VERSION_3_15:
+ res_pool = dcn315_create_resource_pool(init_data, dc);
+ break;
+ case DCN_VERSION_3_16:
+ res_pool = dcn316_create_resource_pool(init_data, dc);
+ break;
#endif
default:
break;
@@ -356,7 +376,6 @@ bool resource_construct(
}
}
-#if defined(CONFIG_DRM_AMD_DC_DCN)
pool->hpo_dp_stream_enc_count = 0;
if (create_funcs->create_hpo_dp_stream_encoder) {
for (i = 0; i < caps->num_hpo_dp_stream_encoder; i++) {
@@ -377,7 +396,6 @@ bool resource_construct(
pool->hpo_dp_link_enc_count++;
}
}
-#endif
#if defined(CONFIG_DRM_AMD_DC_DCN)
for (i = 0; i < caps->num_mpc_3dlut; i++) {
@@ -1612,8 +1630,8 @@ bool dc_add_all_planes_for_stream(
return add_all_planes_for_stream(dc, stream, &set, 1, context);
}
-static bool is_timing_changed(struct dc_stream_state *cur_stream,
- struct dc_stream_state *new_stream)
+bool is_timing_changed(struct dc_stream_state *cur_stream,
+ struct dc_stream_state *new_stream)
{
if (cur_stream == NULL)
return true;
@@ -1640,6 +1658,9 @@ static bool are_stream_backends_same(
if (is_timing_changed(stream_a, stream_b))
return false;
+ if (stream_a->signal != stream_b->signal)
+ return false;
+
if (stream_a->dpms_off != stream_b->dpms_off)
return false;
@@ -1674,8 +1695,8 @@ bool dc_is_stream_unchanged(
/*
* dc_is_stream_scaling_unchanged() - Compare scaling rectangles of two streams.
*/
-bool dc_is_stream_scaling_unchanged(
- struct dc_stream_state *old_stream, struct dc_stream_state *stream)
+bool dc_is_stream_scaling_unchanged(struct dc_stream_state *old_stream,
+ struct dc_stream_state *stream)
{
if (old_stream == stream)
return true;
@@ -1710,7 +1731,6 @@ static void update_stream_engine_usage(
}
}
-#if defined(CONFIG_DRM_AMD_DC_DCN)
static void update_hpo_dp_stream_engine_usage(
struct resource_context *res_ctx,
const struct resource_pool *pool,
@@ -1812,7 +1832,6 @@ static void remove_hpo_dp_link_enc_from_ctx(struct resource_context *res_ctx,
pipe_ctx->link_res.hpo_dp_link_enc = NULL;
}
}
-#endif
/* TODO: release audio object */
void update_audio_usage(
@@ -1858,7 +1877,6 @@ static int acquire_first_free_pipe(
return -1;
}
-#if defined(CONFIG_DRM_AMD_DC_DCN)
static struct hpo_dp_stream_encoder *find_first_free_match_hpo_dp_stream_enc_for_link(
struct resource_context *res_ctx,
const struct resource_pool *pool,
@@ -1876,7 +1894,6 @@ static struct hpo_dp_stream_encoder *find_first_free_match_hpo_dp_stream_enc_for
return NULL;
}
-#endif
static struct audio *find_first_free_audio(
struct resource_context *res_ctx,
@@ -1907,7 +1924,7 @@ static struct audio *find_first_free_audio(
return pool->audios[i];
}
}
- return 0;
+ return NULL;
}
/*
@@ -1964,11 +1981,6 @@ enum dc_status dc_remove_stream_from_ctx(
dc->res_pool,
del_pipe->stream_res.stream_enc,
false);
- /* Release link encoder from stream in new dc_state. */
- if (dc->res_pool->funcs->link_enc_unassign)
- dc->res_pool->funcs->link_enc_unassign(new_ctx, del_pipe->stream);
-
-#if defined(CONFIG_DRM_AMD_DC_DCN)
if (is_dp_128b_132b_signal(del_pipe)) {
update_hpo_dp_stream_engine_usage(
&new_ctx->res_ctx, dc->res_pool,
@@ -1976,7 +1988,6 @@ enum dc_status dc_remove_stream_from_ctx(
false);
remove_hpo_dp_link_enc_from_ctx(&new_ctx->res_ctx, del_pipe, del_pipe->stream);
}
-#endif
if (del_pipe->stream_res.audio)
update_audio_usage(
@@ -2173,7 +2184,7 @@ static void mark_seamless_boot_stream(
if (dc->config.allow_seamless_boot_optimization &&
!dcb->funcs->is_accelerated_mode(dcb)) {
- if (dc_validate_seamless_boot_timing(dc, stream->sink, &stream->timing))
+ if (dc_validate_boot_timing(dc, stream->sink, &stream->timing))
stream->apply_seamless_boot_optimization = true;
}
}
@@ -2229,7 +2240,6 @@ enum dc_status resource_map_pool_resources(
pipe_ctx->stream_res.stream_enc,
true);
-#if defined(CONFIG_DRM_AMD_DC_DCN)
/* Allocate DP HPO Stream Encoder based on signal, hw capabilities
* and link settings
*/
@@ -2254,7 +2264,6 @@ enum dc_status resource_map_pool_resources(
return DC_NO_LINK_ENC_RESOURCE;
}
}
-#endif
/* TODO: Add check if ASIC support and EDID audio */
if (!stream->converter_disable_audio &&
@@ -2326,6 +2335,9 @@ void dc_resource_state_construct(
bool dc_resource_is_dsc_encoding_supported(const struct dc *dc)
{
+ if (dc->res_pool == NULL)
+ return false;
+
return dc->res_pool->res_cap->num_dsc > 0;
}
@@ -2606,6 +2618,8 @@ static void set_avi_info_frame(
hdmi_info.bits.YQ0_YQ1 = YYC_QUANTIZATION_LIMITED_RANGE;
///VIC
+ if (pipe_ctx->stream->timing.hdmi_vic != 0)
+ vic = 0;
format = stream->timing.timing_3d_format;
/*todo, add 3DStereo support*/
if (format != TIMING_3D_FORMAT_NONE) {
@@ -2924,12 +2938,10 @@ bool pipe_need_reprogram(
if (pipe_ctx_old->stream_res.dsc != pipe_ctx->stream_res.dsc)
return true;
-#if defined(CONFIG_DRM_AMD_DC_DCN)
if (pipe_ctx_old->stream_res.hpo_dp_stream_enc != pipe_ctx->stream_res.hpo_dp_stream_enc)
return true;
if (pipe_ctx_old->link_res.hpo_dp_link_enc != pipe_ctx->link_res.hpo_dp_link_enc)
return true;
-#endif
/* DIG link encoder resource assignment for stream changed. */
if (pipe_ctx_old->stream->ctx->dc->res_pool->funcs->link_encs_assign) {
@@ -3196,10 +3208,9 @@ void get_audio_check(struct audio_info *aud_modes,
}
}
-#if defined(CONFIG_DRM_AMD_DC_DCN)
-struct hpo_dp_link_encoder *resource_get_hpo_dp_link_enc_for_det_lt(
+static struct hpo_dp_link_encoder *get_temp_hpo_dp_link_enc(
const struct resource_context *res_ctx,
- const struct resource_pool *pool,
+ const struct resource_pool *const pool,
const struct dc_link *link)
{
struct hpo_dp_link_encoder *hpo_dp_link_enc = NULL;
@@ -3215,7 +3226,78 @@ struct hpo_dp_link_encoder *resource_get_hpo_dp_link_enc_for_det_lt(
return hpo_dp_link_enc;
}
-#endif
+
+bool get_temp_dp_link_res(struct dc_link *link,
+ struct link_resource *link_res,
+ struct dc_link_settings *link_settings)
+{
+ const struct dc *dc = link->dc;
+ const struct resource_context *res_ctx = &dc->current_state->res_ctx;
+
+ memset(link_res, 0, sizeof(*link_res));
+
+ if (dp_get_link_encoding_format(link_settings) == DP_128b_132b_ENCODING) {
+ link_res->hpo_dp_link_enc = get_temp_hpo_dp_link_enc(res_ctx,
+ dc->res_pool, link);
+ if (!link_res->hpo_dp_link_enc)
+ return false;
+ }
+ return true;
+}
+
+void reset_syncd_pipes_from_disabled_pipes(struct dc *dc,
+ struct dc_state *context)
+{
+ int i, j;
+ struct pipe_ctx *pipe_ctx_old, *pipe_ctx, *pipe_ctx_syncd;
+
+ /* If pipe backend is reset, need to reset pipe syncd status */
+ for (i = 0; i < dc->res_pool->pipe_count; i++) {
+ pipe_ctx_old = &dc->current_state->res_ctx.pipe_ctx[i];
+ pipe_ctx = &context->res_ctx.pipe_ctx[i];
+
+ if (!pipe_ctx_old->stream)
+ continue;
+
+ if (pipe_ctx_old->top_pipe || pipe_ctx_old->prev_odm_pipe)
+ continue;
+
+ if (!pipe_ctx->stream ||
+ pipe_need_reprogram(pipe_ctx_old, pipe_ctx)) {
+
+ /* Reset all the syncd pipes from the disabled pipe */
+ for (j = 0; j < dc->res_pool->pipe_count; j++) {
+ pipe_ctx_syncd = &context->res_ctx.pipe_ctx[j];
+ if ((GET_PIPE_SYNCD_FROM_PIPE(pipe_ctx_syncd) == pipe_ctx_old->pipe_idx) ||
+ !IS_PIPE_SYNCD_VALID(pipe_ctx_syncd))
+ SET_PIPE_SYNCD_TO_PIPE(pipe_ctx_syncd, j);
+ }
+ }
+ }
+}
+
+void check_syncd_pipes_for_disabled_master_pipe(struct dc *dc,
+ struct dc_state *context,
+ uint8_t disabled_master_pipe_idx)
+{
+ int i;
+ struct pipe_ctx *pipe_ctx, *pipe_ctx_check;
+
+ pipe_ctx = &context->res_ctx.pipe_ctx[disabled_master_pipe_idx];
+ if ((GET_PIPE_SYNCD_FROM_PIPE(pipe_ctx) != disabled_master_pipe_idx) ||
+ !IS_PIPE_SYNCD_VALID(pipe_ctx))
+ SET_PIPE_SYNCD_TO_PIPE(pipe_ctx, disabled_master_pipe_idx);
+
+ /* for the pipe disabled, check if any slave pipe exists and assert */
+ for (i = 0; i < dc->res_pool->pipe_count; i++) {
+ pipe_ctx_check = &context->res_ctx.pipe_ctx[i];
+
+ if ((GET_PIPE_SYNCD_FROM_PIPE(pipe_ctx_check) == disabled_master_pipe_idx) &&
+ IS_PIPE_SYNCD_VALID(pipe_ctx_check) && (i != disabled_master_pipe_idx))
+ DC_ERR("DC: Failure: pipe_idx[%d] syncd with disabled master pipe_idx[%d]\n",
+ i, disabled_master_pipe_idx);
+ }
+}
uint8_t resource_transmitter_to_phy_idx(const struct dc *dc, enum transmitter transmitter)
{
@@ -3249,3 +3331,36 @@ uint8_t resource_transmitter_to_phy_idx(const struct dc *dc, enum transmitter tr
#endif
return phy_idx;
}
+
+const struct link_hwss *get_link_hwss(const struct dc_link *link,
+ const struct link_resource *link_res)
+{
+ /* Link_hwss is only accessible by getter function instead of accessing
+ * by pointers in dc with the intent to protect against breaking polymorphism.
+ */
+ if (can_use_hpo_dp_link_hwss(link, link_res))
+ /* TODO: some assumes that if decided link settings is 128b/132b
+ * channel coding format hpo_dp_link_enc should be used.
+ * Others believe that if hpo_dp_link_enc is available in link
+ * resource then hpo_dp_link_enc must be used. This bound between
+ * hpo_dp_link_enc != NULL and decided link settings is loosely coupled
+ * with a premise that both hpo_dp_link_enc pointer and decided link
+ * settings are determined based on single policy function like
+ * "decide_link_settings" from upper layer. This "convention"
+ * cannot be maintained and enforced at current level.
+ * Therefore a refactor is due so we can enforce a strong bound
+ * between those two parameters at this level.
+ *
+ * To put it simple, we want to make enforcement at low level so that
+ * we will not return link hwss if caller plans to do 8b/10b
+ * with an hpo encoder. Or we can return a very dummy one that doesn't
+ * do work for all functions
+ */
+ return get_hpo_dp_link_hwss();
+ else if (can_use_dpia_link_hwss(link, link_res))
+ return get_dpia_link_hwss();
+ else if (can_use_dio_link_hwss(link, link_res))
+ return get_dio_link_hwss();
+ else
+ return get_virtual_link_hwss();
+}
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_stream.c b/drivers/gpu/drm/amd/display/dc/core/dc_stream.c
index 57cf4cb82370..c4e871f358ab 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_stream.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_stream.c
@@ -273,6 +273,8 @@ static void program_cursor_attributes(
if (!pipe_to_program) {
pipe_to_program = pipe_ctx;
dc->hwss.cursor_lock(dc, pipe_to_program, true);
+ if (pipe_to_program->next_odm_pipe)
+ dc->hwss.cursor_lock(dc, pipe_to_program->next_odm_pipe, true);
}
dc->hwss.set_cursor_attribute(pipe_ctx);
@@ -280,8 +282,11 @@ static void program_cursor_attributes(
dc->hwss.set_cursor_sdr_white_level(pipe_ctx);
}
- if (pipe_to_program)
+ if (pipe_to_program) {
dc->hwss.cursor_lock(dc, pipe_to_program, false);
+ if (pipe_to_program->next_odm_pipe)
+ dc->hwss.cursor_lock(dc, pipe_to_program->next_odm_pipe, false);
+ }
}
#ifndef TRIM_FSFT
@@ -713,6 +718,20 @@ enum dc_status dc_stream_add_dsc_to_resource(struct dc *dc,
}
}
+struct pipe_ctx *dc_stream_get_pipe_ctx(struct dc_stream_state *stream)
+{
+ int i = 0;
+
+ for (i = 0; i < MAX_PIPES; i++) {
+ struct pipe_ctx *pipe = &stream->ctx->dc->current_state->res_ctx.pipe_ctx[i];
+
+ if (pipe->stream == stream)
+ return pipe;
+ }
+
+ return NULL;
+}
+
void dc_stream_log(const struct dc *dc, const struct dc_stream_state *stream)
{
DC_LOG_DC(
@@ -737,5 +756,21 @@ void dc_stream_log(const struct dc *dc, const struct dc_stream_state *stream)
DC_LOG_DC(
"\tlink: %d\n",
stream->link->link_index);
+
+ DC_LOG_DC(
+ "\tdsc: %d, mst_pbn: %d\n",
+ stream->timing.flags.DSC,
+ stream->timing.dsc_cfg.mst_pbn);
+
+ if (stream->sink) {
+ if (stream->sink->sink_signal != SIGNAL_TYPE_VIRTUAL &&
+ stream->sink->sink_signal != SIGNAL_TYPE_NONE) {
+
+ DC_LOG_DC(
+ "\tdispname: %s signal: %x\n",
+ stream->sink->edid_caps.display_name,
+ stream->signal);
+ }
+ }
}
diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h
index da2c78ce14d6..4ffab7bb1098 100644
--- a/drivers/gpu/drm/amd/display/dc/dc.h
+++ b/drivers/gpu/drm/amd/display/dc/dc.h
@@ -47,7 +47,7 @@ struct aux_payload;
struct set_config_cmd_payload;
struct dmub_notification;
-#define DC_VER "3.2.167"
+#define DC_VER "3.2.177"
#define MAX_SURFACES 3
#define MAX_PLANES 6
@@ -195,13 +195,12 @@ struct dc_caps {
unsigned int cursor_cache_size;
struct dc_plane_cap planes[MAX_PLANES];
struct dc_color_caps color;
-#if defined(CONFIG_DRM_AMD_DC_DCN)
bool dp_hpo;
bool hdmi_frl_pcon_support;
-#endif
bool edp_dsc_support;
bool vbios_lttpr_aware;
bool vbios_lttpr_enable;
+ uint32_t max_otg_num;
};
struct dc_bug_wa {
@@ -306,7 +305,6 @@ struct dc_cap_funcs {
struct link_training_settings;
-#if defined(CONFIG_DRM_AMD_DC_DCN)
union allow_lttpr_non_transparent_mode {
struct {
bool DP1_4A : 1;
@@ -314,7 +312,7 @@ union allow_lttpr_non_transparent_mode {
} bits;
unsigned char raw;
};
-#endif
+
/* Structure to hold configuration flags set by dm at dc creation. */
struct dc_config {
bool gpu_vm_support;
@@ -322,16 +320,12 @@ struct dc_config {
bool fbc_support;
bool disable_fractional_pwm;
bool allow_seamless_boot_optimization;
- bool power_down_display_on_boot;
+ bool seamless_boot_edp_requested;
bool edp_not_connected;
bool edp_no_power_sequencing;
bool force_enum_edp;
bool forced_clocks;
-#if defined(CONFIG_DRM_AMD_DC_DCN)
union allow_lttpr_non_transparent_mode allow_lttpr_non_transparent_mode;
-#else
- bool allow_lttpr_non_transparent_mode;
-#endif
bool multi_mon_pp_mclk_switch;
bool disable_dmcu;
bool enable_4to1MPC;
@@ -344,6 +338,7 @@ struct dc_config {
uint8_t vblank_alignment_max_frame_time_diff;
bool is_asymmetric_memory;
bool is_single_rank_dimm;
+ bool use_pipe_ctx_sync_logic;
};
enum visual_confirm {
@@ -359,6 +354,7 @@ enum dc_psr_power_opts {
psr_power_opt_invalid = 0x0,
psr_power_opt_smu_opt_static_screen = 0x1,
psr_power_opt_z10_static_screen = 0x10,
+ psr_power_opt_ds_disable_allow = 0x100,
};
enum dcc_option {
@@ -395,6 +391,7 @@ enum dcn_pwr_state {
enum dcn_zstate_support_state {
DCN_ZSTATE_SUPPORT_UNKNOWN,
DCN_ZSTATE_SUPPORT_ALLOW,
+ DCN_ZSTATE_SUPPORT_ALLOW_Z10_ONLY,
DCN_ZSTATE_SUPPORT_DISALLOW,
};
#endif
@@ -517,12 +514,13 @@ union root_clock_optimization_options {
union dpia_debug_options {
struct {
- uint32_t disable_dpia:1;
- uint32_t force_non_lttpr:1;
- uint32_t extend_aux_rd_interval:1;
- uint32_t disable_mst_dsc_work_around:1;
- uint32_t hpd_delay_in_ms:12;
- uint32_t reserved:16;
+ uint32_t disable_dpia:1; /* bit 0 */
+ uint32_t force_non_lttpr:1; /* bit 1 */
+ uint32_t extend_aux_rd_interval:1; /* bit 2 */
+ uint32_t disable_mst_dsc_work_around:1; /* bit 3 */
+ uint32_t hpd_delay_in_ms:12; /* bits 4-15 */
+ uint32_t disable_force_tbt3_work_around:1; /* bit 16 */
+ uint32_t reserved:15;
} bits;
uint32_t raw;
};
@@ -686,13 +684,12 @@ struct dc_debug_options {
bool disable_dsc_edp;
unsigned int force_dsc_edp_policy;
bool enable_dram_clock_change_one_display_vactive;
-#if defined(CONFIG_DRM_AMD_DC_DCN)
/* TODO - remove once tested */
bool legacy_dp2_lt;
bool set_mst_en_for_sst;
bool disable_uhbr;
bool force_dp2_lt_fallback_method;
-#endif
+ bool ignore_cable_id;
union mem_low_power_enable_options enable_mem_low_power;
union root_clock_optimization_options root_clock_optimization;
bool hpo_optimization;
@@ -708,10 +705,13 @@ struct dc_debug_options {
int crb_alloc_policy_min_disp_count;
#if defined(CONFIG_DRM_AMD_DC_DCN)
bool disable_z10;
+ bool enable_z9_disable_interface;
bool enable_sw_cntl_psr;
union dpia_debug_options dpia_debug;
#endif
bool apply_vendor_specific_lttpr_wa;
+ bool ignore_dpref_ss;
+ uint8_t psr_power_use_phy_fsm;
};
struct gpu_info_soc_bounding_box_v1_0;
@@ -1129,7 +1129,7 @@ struct dc_validation_set {
uint8_t plane_count;
};
-bool dc_validate_seamless_boot_timing(const struct dc *dc,
+bool dc_validate_boot_timing(const struct dc *dc,
const struct dc_sink *sink,
struct dc_crtc_timing *crtc_timing);
@@ -1206,10 +1206,12 @@ struct dpcd_caps {
/* dongle type (DP converter, CV smart dongle) */
enum display_dongle_type dongle_type;
+ bool is_dongle_type_one;
/* branch device or sink device */
bool is_branch_dev;
/* Dongle's downstream count. */
union sink_count sink_count;
+ bool is_mst_capable;
/* If dongle_type == DISPLAY_DONGLE_DP_HDMI_CONVERTER,
indicates 'Frame Sequential-to-lllFrame Pack' conversion capability.*/
struct dc_dongle_caps dongle_caps;
@@ -1232,15 +1234,16 @@ struct dpcd_caps {
union dpcd_fec_capability fec_cap;
struct dpcd_dsc_capabilities dsc_caps;
struct dc_lttpr_caps lttpr_caps;
- struct psr_caps psr_caps;
struct dpcd_usb4_dp_tunneling_info usb4_dp_tun_info;
-#if defined(CONFIG_DRM_AMD_DC_DCN)
union dp_128b_132b_supported_link_rates dp_128b_132b_supported_link_rates;
union dp_main_line_channel_coding_cap channel_coding_cap;
union dp_sink_video_fallback_formats fallback_formats;
union dp_fec_capability1 fec_cap1;
-#endif
+ union dp_cable_id cable_id;
+ uint8_t edp_rev;
+ union edp_alpm_caps alpm_caps;
+ struct edp_psr_info psr_info;
};
union dpcd_sink_ext_caps {
@@ -1446,8 +1449,11 @@ void dc_z10_restore(const struct dc *dc);
void dc_z10_save_init(struct dc *dc);
#endif
+bool dc_is_dmub_outbox_supported(struct dc *dc);
bool dc_enable_dmub_notifications(struct dc *dc);
+void dc_enable_dmub_outbox(struct dc *dc);
+
bool dc_process_dmub_aux_transfer_async(struct dc *dc,
uint32_t link_index,
struct aux_payload *payload);
diff --git a/drivers/gpu/drm/amd/display/dc/dc_dp_types.h b/drivers/gpu/drm/amd/display/dc/dc_dp_types.h
index 353dac420f34..36ac2a8746bd 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_dp_types.h
+++ b/drivers/gpu/drm/amd/display/dc/dc_dp_types.h
@@ -53,7 +53,6 @@ enum dc_link_rate {
LINK_RATE_RBR2 = 0x0C, // Rate_5 (RBR2)- 3.24 Gbps/Lane
LINK_RATE_RATE_6 = 0x10, // Rate_6 - 4.32 Gbps/Lane
LINK_RATE_HIGH2 = 0x14, // Rate_7 (HBR2)- 5.40 Gbps/Lane
-#if defined(CONFIG_DRM_AMD_DC_DCN)
LINK_RATE_HIGH3 = 0x1E, // Rate_8 (HBR3)- 8.10 Gbps/Lane
/* Starting from DP2.0 link rate enum directly represents actual
* link rate value in unit of 10 mbps
@@ -61,9 +60,6 @@ enum dc_link_rate {
LINK_RATE_UHBR10 = 1000, // UHBR10 - 10.0 Gbps/Lane
LINK_RATE_UHBR13_5 = 1350, // UHBR13.5 - 13.5 Gbps/Lane
LINK_RATE_UHBR20 = 2000, // UHBR10 - 20.0 Gbps/Lane
-#else
- LINK_RATE_HIGH3 = 0x1E // Rate_8 (HBR3)- 8.10 Gbps/Lane
-#endif
};
enum dc_link_spread {
@@ -100,7 +96,6 @@ enum dc_post_cursor2 {
POST_CURSOR2_MAX_LEVEL = POST_CURSOR2_LEVEL3,
};
-#if defined(CONFIG_DRM_AMD_DC_DCN)
enum dc_dp_ffe_preset_level {
DP_FFE_PRESET_LEVEL0 = 0,
DP_FFE_PRESET_LEVEL1,
@@ -120,7 +115,6 @@ enum dc_dp_ffe_preset_level {
DP_FFE_PRESET_LEVEL15,
DP_FFE_PRESET_MAX_LEVEL = DP_FFE_PRESET_LEVEL15,
};
-#endif
enum dc_dp_training_pattern {
DP_TRAINING_PATTERN_SEQUENCE_1 = 0,
@@ -128,19 +122,15 @@ enum dc_dp_training_pattern {
DP_TRAINING_PATTERN_SEQUENCE_3,
DP_TRAINING_PATTERN_SEQUENCE_4,
DP_TRAINING_PATTERN_VIDEOIDLE,
-#if defined(CONFIG_DRM_AMD_DC_DCN)
DP_128b_132b_TPS1,
DP_128b_132b_TPS2,
DP_128b_132b_TPS2_CDS,
-#endif
};
enum dp_link_encoding {
DP_UNKNOWN_ENCODING = 0,
DP_8b_10b_ENCODING = 1,
-#if defined(CONFIG_DRM_AMD_DC_DCN)
DP_128b_132b_ENCODING = 2,
-#endif
};
struct dc_link_settings {
@@ -152,7 +142,6 @@ struct dc_link_settings {
bool dpcd_source_device_specific_field_support;
};
-#if defined(CONFIG_DRM_AMD_DC_DCN)
union dc_dp_ffe_preset {
struct {
uint8_t level : 4;
@@ -163,24 +152,19 @@ union dc_dp_ffe_preset {
} settings;
uint8_t raw;
};
-#endif
struct dc_lane_settings {
enum dc_voltage_swing VOLTAGE_SWING;
enum dc_pre_emphasis PRE_EMPHASIS;
enum dc_post_cursor2 POST_CURSOR2;
-#if defined(CONFIG_DRM_AMD_DC_DCN)
union dc_dp_ffe_preset FFE_PRESET;
-#endif
};
struct dc_link_training_overrides {
enum dc_voltage_swing *voltage_swing;
enum dc_pre_emphasis *pre_emphasis;
enum dc_post_cursor2 *post_cursor2;
-#if defined(CONFIG_DRM_AMD_DC_DCN)
union dc_dp_ffe_preset *ffe_preset;
-#endif
uint16_t *cr_pattern_time;
uint16_t *eq_pattern_time;
@@ -194,7 +178,6 @@ struct dc_link_training_overrides {
bool *fec_enable;
};
-#if defined(CONFIG_DRM_AMD_DC_DCN)
union payload_table_update_status {
struct {
uint8_t VC_PAYLOAD_TABLE_UPDATED:1;
@@ -202,7 +185,6 @@ union payload_table_update_status {
} bits;
uint8_t raw;
};
-#endif
union dpcd_rev {
struct {
@@ -291,14 +273,10 @@ union lane_align_status_updated {
struct {
uint8_t INTERLANE_ALIGN_DONE:1;
uint8_t POST_LT_ADJ_REQ_IN_PROGRESS:1;
-#if defined(CONFIG_DRM_AMD_DC_DCN)
uint8_t EQ_INTERLANE_ALIGN_DONE_128b_132b:1;
uint8_t CDS_INTERLANE_ALIGN_DONE_128b_132b:1;
uint8_t LT_FAILED_128b_132b:1;
uint8_t RESERVED:1;
-#else
- uint8_t RESERVED:4;
-#endif
uint8_t DOWNSTREAM_PORT_STATUS_CHANGED:1;
uint8_t LINK_STATUS_UPDATED:1;
} bits;
@@ -311,12 +289,10 @@ union lane_adjust {
uint8_t PRE_EMPHASIS_LANE:2;
uint8_t RESERVED:4;
} bits;
-#if defined(CONFIG_DRM_AMD_DC_DCN)
struct {
uint8_t PRESET_VALUE :4;
uint8_t RESERVED :4;
} tx_ffe;
-#endif
uint8_t raw;
};
@@ -346,12 +322,10 @@ union dpcd_training_lane {
uint8_t MAX_PRE_EMPHASIS_REACHED:1;
uint8_t RESERVED:2;
} bits;
-#if defined(CONFIG_DRM_AMD_DC_DCN)
struct {
uint8_t PRESET_VALUE :4;
uint8_t RESERVED :4;
} tx_ffe;
-#endif
uint8_t raw;
};
@@ -665,18 +639,9 @@ union test_response {
union phy_test_pattern {
struct {
-#if defined(CONFIG_DRM_AMD_DC_DCN)
/* This field is 7 bits for DP2.0 */
uint8_t PATTERN :7;
uint8_t RESERVED :1;
-#else
- /* DpcdPhyTestPatterns. This field is 2 bits for DP1.1
- * and 3 bits for DP1.2.
- */
- uint8_t PATTERN :3;
- /* BY speci, bit7:2 is 0 for DP1.1. */
- uint8_t RESERVED :5;
-#endif
} bits;
uint8_t raw;
};
@@ -754,14 +719,10 @@ union dpcd_fec_capability {
uint8_t UNCORRECTED_BLOCK_ERROR_COUNT_CAPABLE:1;
uint8_t CORRECTED_BLOCK_ERROR_COUNT_CAPABLE:1;
uint8_t BIT_ERROR_COUNT_CAPABLE:1;
-#if defined(CONFIG_DRM_AMD_DC_DCN)
uint8_t PARITY_BLOCK_ERROR_COUNT_CAPABLE:1;
uint8_t ARITY_BIT_ERROR_COUNT_CAPABLE:1;
uint8_t FEC_RUNNING_INDICATOR_SUPPORTED:1;
uint8_t FEC_ERROR_REPORTING_POLICY_SUPPORTED:1;
-#else
- uint8_t RESERVED:4;
-#endif
} bits;
uint8_t raw;
};
@@ -925,7 +886,6 @@ struct dpcd_usb4_dp_tunneling_info {
uint8_t usb4_topology_id[DPCD_USB4_TOPOLOGY_ID_LEN];
};
-#if defined(CONFIG_DRM_AMD_DC_DCN)
#ifndef DP_MAIN_LINK_CHANNEL_CODING_CAP
#define DP_MAIN_LINK_CHANNEL_CODING_CAP 0x006
#endif
@@ -941,6 +901,9 @@ struct dpcd_usb4_dp_tunneling_info {
#ifndef DP_LINK_SQUARE_PATTERN
#define DP_LINK_SQUARE_PATTERN 0x10F
#endif
+#ifndef DP_CABLE_ATTRIBUTES_UPDATED_BY_DPTX
+#define DP_CABLE_ATTRIBUTES_UPDATED_BY_DPTX 0x110
+#endif
#ifndef DP_DSC_CONFIGURATION
#define DP_DSC_CONFIGURATION 0x161
#endif
@@ -953,6 +916,9 @@ struct dpcd_usb4_dp_tunneling_info {
#ifndef DP_128b_132b_TRAINING_AUX_RD_INTERVAL
#define DP_128b_132b_TRAINING_AUX_RD_INTERVAL 0x2216
#endif
+#ifndef DP_CABLE_ATTRIBUTES_UPDATED_BY_DPRX
+#define DP_CABLE_ATTRIBUTES_UPDATED_BY_DPRX 0x2217
+#endif
#ifndef DP_TEST_264BIT_CUSTOM_PATTERN_7_0
#define DP_TEST_264BIT_CUSTOM_PATTERN_7_0 0X2230
#endif
@@ -994,8 +960,8 @@ struct dpcd_usb4_dp_tunneling_info {
#endif
#ifndef DP_INTRA_HOP_AUX_REPLY_INDICATION
#define DP_INTRA_HOP_AUX_REPLY_INDICATION (1 << 3)
-#endif
/* TODO - Use DRM header to replace above once available */
+#endif // DP_INTRA_HOP_AUX_REPLY_INDICATION
union dp_main_line_channel_coding_cap {
struct {
@@ -1052,6 +1018,16 @@ union dp_fec_capability1 {
uint8_t raw;
};
+union dp_cable_id {
+ struct {
+ uint8_t UHBR10_20_CAPABILITY :2;
+ uint8_t UHBR13_5_CAPABILITY :1;
+ uint8_t CABLE_TYPE :3;
+ uint8_t RESERVED :2;
+ } bits;
+ uint8_t raw;
+};
+
struct dp_color_depth_caps {
uint8_t support_6bpc :1;
uint8_t support_8bpc :1;
@@ -1091,6 +1067,34 @@ union dp_128b_132b_training_aux_rd_interval {
} bits;
uint8_t raw;
};
-#endif
+
+union edp_alpm_caps {
+ struct {
+ uint8_t AUX_WAKE_ALPM_CAP :1;
+ uint8_t PM_STATE_2A_SUPPORT :1;
+ uint8_t AUX_LESS_ALPM_CAP :1;
+ uint8_t RESERVED :5;
+ } bits;
+ uint8_t raw;
+};
+
+union edp_psr_dpcd_caps {
+ struct {
+ uint8_t LINK_TRAINING_ON_EXIT_NOT_REQUIRED :1;
+ uint8_t PSR_SETUP_TIME :3;
+ uint8_t Y_COORDINATE_REQUIRED :1;
+ uint8_t SU_GRANULARITY_REQUIRED :1;
+ uint8_t FRAME_SYNC_IS_NOT_NEEDED_FOR_SU :1;
+ uint8_t RESERVED :1;
+ } bits;
+ uint8_t raw;
+};
+
+struct edp_psr_info {
+ uint8_t psr_version;
+ union edp_psr_dpcd_caps psr_dpcd_caps;
+ uint8_t psr2_su_y_granularity_cap;
+ uint8_t force_psrsu_cap;
+};
#endif /* DC_DP_TYPES_H */
diff --git a/drivers/gpu/drm/amd/display/dc/dc_helper.c b/drivers/gpu/drm/amd/display/dc/dc_helper.c
index ab6bc5d79012..f43cce16bb6c 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_helper.c
+++ b/drivers/gpu/drm/amd/display/dc/dc_helper.c
@@ -588,6 +588,66 @@ uint32_t generic_indirect_reg_update_ex(const struct dc_context *ctx,
return reg_val;
}
+
+uint32_t generic_indirect_reg_update_ex_sync(const struct dc_context *ctx,
+ uint32_t index, uint32_t reg_val, int n,
+ uint8_t shift1, uint32_t mask1, uint32_t field_value1,
+ ...)
+{
+ uint32_t shift, mask, field_value;
+ int i = 1;
+
+ va_list ap;
+
+ va_start(ap, field_value1);
+
+ reg_val = set_reg_field_value_ex(reg_val, field_value1, mask1, shift1);
+
+ while (i < n) {
+ shift = va_arg(ap, uint32_t);
+ mask = va_arg(ap, uint32_t);
+ field_value = va_arg(ap, uint32_t);
+
+ reg_val = set_reg_field_value_ex(reg_val, field_value, mask, shift);
+ i++;
+ }
+
+ dm_write_index_reg(ctx, CGS_IND_REG__PCIE, index, reg_val);
+ va_end(ap);
+
+ return reg_val;
+}
+
+uint32_t generic_indirect_reg_get_sync(const struct dc_context *ctx,
+ uint32_t index, int n,
+ uint8_t shift1, uint32_t mask1, uint32_t *field_value1,
+ ...)
+{
+ uint32_t shift, mask, *field_value;
+ uint32_t value = 0;
+ int i = 1;
+
+ va_list ap;
+
+ va_start(ap, field_value1);
+
+ value = dm_read_index_reg(ctx, CGS_IND_REG__PCIE, index);
+ *field_value1 = get_reg_field_value_ex(value, mask1, shift1);
+
+ while (i < n) {
+ shift = va_arg(ap, uint32_t);
+ mask = va_arg(ap, uint32_t);
+ field_value = va_arg(ap, uint32_t *);
+
+ *field_value = get_reg_field_value_ex(value, mask, shift);
+ i++;
+ }
+
+ va_end(ap);
+
+ return value;
+}
+
void reg_sequence_start_gather(const struct dc_context *ctx)
{
/* if reg sequence is supported and enabled, set flag to
diff --git a/drivers/gpu/drm/amd/display/dc/dc_hw_types.h b/drivers/gpu/drm/amd/display/dc/dc_hw_types.h
index eac34f591a3f..c964f598755a 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_hw_types.h
+++ b/drivers/gpu/drm/amd/display/dc/dc_hw_types.h
@@ -745,6 +745,7 @@ struct dc_dsc_config {
bool is_frl; /* indicate if DSC is applied based on HDMI FRL sink's capability */
#endif
bool is_dp; /* indicate if DSC is applied based on DP's capability */
+ uint32_t mst_pbn; /* pbn of display on dsc mst hub */
};
struct dc_crtc_timing {
uint32_t h_total;
diff --git a/drivers/gpu/drm/amd/display/dc/dc_link.h b/drivers/gpu/drm/amd/display/dc/dc_link.h
index c0e37ad0e26c..aa818bf840eb 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_link.h
+++ b/drivers/gpu/drm/amd/display/dc/dc_link.h
@@ -43,14 +43,16 @@ struct dc_link_status {
struct dpcd_caps *dpcd_caps;
};
+struct dprx_states {
+ bool cable_id_written;
+};
+
/* DP MST stream allocation (payload bandwidth number) */
struct link_mst_stream_allocation {
/* DIG front */
const struct stream_encoder *stream_enc;
-#if defined(CONFIG_DRM_AMD_DC_DCN)
/* HPO DP Stream Encoder */
const struct hpo_dp_stream_encoder *hpo_dp_stream_enc;
-#endif
/* associate DRM payload table with DC stream encoder */
uint8_t vcp_id;
/* number of slots required for the DP stream in transport packet */
@@ -74,6 +76,28 @@ struct link_trace {
struct time_stamp time_stamp;
};
+struct dp_trace_lt_counts {
+ unsigned int total;
+ unsigned int fail;
+};
+
+struct dp_trace_lt {
+ struct dp_trace_lt_counts counts;
+ struct dp_trace_timestamps {
+ unsigned long long start;
+ unsigned long long end;
+ } timestamps;
+ enum link_training_result result;
+ bool is_logged;
+};
+
+struct dp_trace {
+ struct dp_trace_lt detect_lt_trace;
+ struct dp_trace_lt commit_lt_trace;
+ unsigned int link_loss_count;
+ bool is_initialized;
+};
+
/* PSR feature flags */
struct psr_settings {
bool psr_feature_enabled; // PSR is supported by sink
@@ -119,6 +143,8 @@ struct dc_link {
bool edp_sink_present;
+ struct dp_trace dp_trace;
+
/* caps is the same as reported_link_cap. link_traing use
* reported_link_cap. Will clean up. TODO
*/
@@ -197,10 +223,13 @@ struct dc_link {
bool dp_mot_reset_segment;
/* Some USB4 docks do not handle turning off MST DSC once it has been enabled. */
bool dpia_mst_dsc_always_on;
+ /* Forced DPIA into TBT3 compatibility mode. */
+ bool dpia_forced_tbt3_mode;
} wa_flags;
struct link_mst_stream_allocation_table mst_stream_alloc_table;
struct dc_link_status link_status;
+ struct dprx_states dprx_states;
struct link_trace link_trace;
struct gpio *hpd_gpio;
@@ -307,6 +336,7 @@ void dc_link_blank_dp_stream(struct dc_link *link, bool hw_init);
*/
enum dc_detect_reason {
DETECT_REASON_BOOT,
+ DETECT_REASON_RESUMEFROMS3S4,
DETECT_REASON_HPD,
DETECT_REASON_HPDRX,
DETECT_REASON_FALLBACK,
@@ -316,10 +346,8 @@ enum dc_detect_reason {
bool dc_link_detect(struct dc_link *dc_link, enum dc_detect_reason reason);
bool dc_link_get_hpd_state(struct dc_link *dc_link);
enum dc_status dc_link_allocate_mst_payload(struct pipe_ctx *pipe_ctx);
-#if defined(CONFIG_DRM_AMD_DC_DCN)
enum dc_status dc_link_reduce_mst_payload(struct pipe_ctx *pipe_ctx, uint32_t req_pbn);
enum dc_status dc_link_increase_mst_payload(struct pipe_ctx *pipe_ctx, uint32_t req_pbn);
-#endif
/* Notify DC about DP RX Interrupt (aka Short Pulse Interrupt).
* Return:
@@ -438,6 +466,11 @@ const struct dc_link_settings *dc_link_get_link_cap(
void dc_link_overwrite_extended_receiver_cap(
struct dc_link *link);
+bool dc_is_oem_i2c_device_present(
+ struct dc *dc,
+ size_t slave_address
+);
+
bool dc_submit_i2c(
struct dc *dc,
uint32_t link_index,
@@ -453,14 +486,29 @@ uint32_t dc_bandwidth_in_kbps_from_timing(
bool dc_link_is_fec_supported(const struct dc_link *link);
bool dc_link_should_enable_fec(const struct dc_link *link);
-#if defined(CONFIG_DRM_AMD_DC_DCN)
uint32_t dc_link_bw_kbps_from_raw_frl_link_rate_data(uint8_t bw);
enum dp_link_encoding dc_link_dp_mst_decide_link_encoding_format(const struct dc_link *link);
-#endif
-const struct link_resource *dc_link_get_cur_link_res(const struct dc_link *link);
+void dc_link_get_cur_link_res(const struct dc_link *link,
+ struct link_resource *link_res);
/* take a snapshot of current link resource allocation state */
void dc_get_cur_link_res_map(const struct dc *dc, uint32_t *map);
/* restore link resource allocation state from a snapshot */
void dc_restore_link_res_map(const struct dc *dc, uint32_t *map);
+void dc_link_clear_dprx_states(struct dc_link *link);
+struct gpio *get_hpd_gpio(struct dc_bios *dcb,
+ struct graphics_object_id link_id,
+ struct gpio_service *gpio_service);
+void dp_trace_reset(struct dc_link *link);
+bool dc_dp_trace_is_initialized(struct dc_link *link);
+unsigned long long dc_dp_trace_get_lt_end_timestamp(struct dc_link *link,
+ bool in_detection);
+void dc_dp_trace_set_is_logged_flag(struct dc_link *link,
+ bool in_detection,
+ bool is_logged);
+bool dc_dp_trace_is_logged(struct dc_link *link,
+ bool in_detection);
+struct dp_trace_lt_counts *dc_dp_trace_get_lt_counts(struct dc_link *link,
+ bool in_detection);
+unsigned int dc_dp_trace_get_link_loss_count(struct dc_link *link);
#endif /* DC_LINK_H_ */
diff --git a/drivers/gpu/drm/amd/display/dc/dc_stream.h b/drivers/gpu/drm/amd/display/dc/dc_stream.h
index e37c4a10bfd5..99a750f561f8 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_stream.h
+++ b/drivers/gpu/drm/amd/display/dc/dc_stream.h
@@ -115,12 +115,10 @@ struct periodic_interrupt_config {
int lines_offset;
};
-#if defined(CONFIG_DRM_AMD_DC_DCN)
struct dc_mst_stream_bw_update {
bool is_increase; // is bandwidth reduced or increased
uint32_t mst_stream_bw; // new mst bandwidth in kbps
};
-#endif
union stream_update_flags {
struct {
@@ -132,9 +130,7 @@ union stream_update_flags {
uint32_t gamut_remap:1;
uint32_t wb_update:1;
uint32_t dsc_changed : 1;
-#if defined(CONFIG_DRM_AMD_DC_DCN)
uint32_t mst_bw : 1;
-#endif
} bits;
uint32_t raw;
@@ -288,9 +284,7 @@ struct dc_stream_update {
struct dc_writeback_update *wb_update;
struct dc_dsc_config *dsc_config;
-#if defined(CONFIG_DRM_AMD_DC_DCN)
struct dc_mst_stream_bw_update *mst_bw_update;
-#endif
struct dc_transfer_func *func_shaper;
struct dc_3dlut *lut3d_func;
@@ -530,4 +524,6 @@ bool dc_stream_get_crtc_position(struct dc *dc,
unsigned int *v_pos,
unsigned int *nom_v_pos);
+struct pipe_ctx *dc_stream_get_pipe_ctx(struct dc_stream_state *stream);
+
#endif /* DC_STREAM_H_ */
diff --git a/drivers/gpu/drm/amd/display/dc/dc_types.h b/drivers/gpu/drm/amd/display/dc/dc_types.h
index 0285a4b38d05..2ba9f528c0fe 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_types.h
+++ b/drivers/gpu/drm/amd/display/dc/dc_types.h
@@ -138,6 +138,7 @@ enum dc_edid_status {
EDID_BAD_CHECKSUM,
EDID_THE_SAME,
EDID_FALL_BACK,
+ EDID_PARTIAL_VALID,
};
enum act_return_status {
@@ -395,14 +396,11 @@ struct dc_lttpr_caps {
uint8_t max_link_rate;
uint8_t phy_repeater_cnt;
uint8_t max_ext_timeout;
-#if defined(CONFIG_DRM_AMD_DC_DCN)
union dp_main_link_channel_coding_lttpr_cap main_link_channel_coding;
union dp_128b_132b_supported_lttpr_link_rates supported_128b_132b_rates;
-#endif
uint8_t aux_rd_interval[MAX_REPEATER_CNT - 1];
};
-#if defined(CONFIG_DRM_AMD_DC_DCN)
struct dc_dongle_dfp_cap_ext {
bool supported;
uint16_t max_pixel_rate_in_mps;
@@ -414,7 +412,6 @@ struct dc_dongle_dfp_cap_ext {
struct dp_color_depth_caps ycbcr422_color_depth_caps;
struct dp_color_depth_caps ycbcr420_color_depth_caps;
};
-#endif
struct dc_dongle_caps {
/* dongle type (DP converter, CV smart dongle) */
@@ -429,10 +426,8 @@ struct dc_dongle_caps {
bool is_dp_hdmi_ycbcr420_converter;
uint32_t dp_hdmi_max_bpc;
uint32_t dp_hdmi_max_pixel_clk_in_khz;
-#if defined(CONFIG_DRM_AMD_DC_DCN)
uint32_t dp_hdmi_frl_max_link_bw_in_kbps;
struct dc_dongle_dfp_cap_ext dfp_cap_ext;
-#endif
};
/* Scaling format */
enum scaling_transformation {
diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_aux.c b/drivers/gpu/drm/amd/display/dc/dce/dce_aux.c
index 6d42a9cc9916..8e814000db62 100644
--- a/drivers/gpu/drm/amd/display/dc/dce/dce_aux.c
+++ b/drivers/gpu/drm/amd/display/dc/dce/dce_aux.c
@@ -413,7 +413,8 @@ static bool acquire(
return false;
if (!acquire_engine(engine)) {
- dal_ddc_close(ddc);
+ engine->ddc = ddc;
+ release_engine(engine);
return false;
}
@@ -878,7 +879,7 @@ bool dce_aux_transfer_with_retries(struct ddc_service *ddc,
default:
DC_TRACE_LEVEL_MESSAGE(DAL_TRACE_LEVEL_ERROR,
LOG_FLAG_Error_I2cAux,
- "dce_aux_transfer_with_retries: AUX_RET_SUCCESS: FAILURE: AUX_TRANSACTION_REPLY_* unknown, default case.");
+ "dce_aux_transfer_with_retries: AUX_RET_SUCCESS: FAILURE: AUX_TRANSACTION_REPLY_* unknown, default case. Reply: %d", *payload->reply);
goto fail;
}
break;
diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/dce/dce_clk_mgr.c
index 1435d7bc1f21..07359eb89efc 100644
--- a/drivers/gpu/drm/amd/display/dc/dce/dce_clk_mgr.c
+++ b/drivers/gpu/drm/amd/display/dc/dce/dce_clk_mgr.c
@@ -450,6 +450,8 @@ void dce_clock_read_ss_info(struct dce_clk_mgr *clk_mgr_dce)
clk_mgr_dce->dprefclk_ss_percentage =
info.spread_spectrum_percentage;
}
+ if (clk_mgr_dce->base.ctx->dc->debug.ignore_dpref_ss)
+ clk_mgr_dce->dprefclk_ss_percentage = 0;
}
}
}
diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_clock_source.c b/drivers/gpu/drm/amd/display/dc/dce/dce_clock_source.c
index 2c7eb982eabc..cc5128e67daf 100644
--- a/drivers/gpu/drm/amd/display/dc/dce/dce_clock_source.c
+++ b/drivers/gpu/drm/amd/display/dc/dce/dce_clock_source.c
@@ -971,6 +971,98 @@ static bool dce112_program_pix_clk(
return true;
}
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+static bool dcn31_program_pix_clk(
+ struct clock_source *clock_source,
+ struct pixel_clk_params *pix_clk_params,
+ struct pll_settings *pll_settings)
+{
+ struct dce110_clk_src *clk_src = TO_DCE110_CLK_SRC(clock_source);
+ unsigned int inst = pix_clk_params->controller_id - CONTROLLER_ID_D0;
+ unsigned int dp_dto_ref_khz = clock_source->ctx->dc->clk_mgr->dprefclk_khz;
+ const struct pixel_rate_range_table_entry *e =
+ look_up_in_video_optimized_rate_tlb(pix_clk_params->requested_pix_clk_100hz / 10);
+ struct bp_pixel_clock_parameters bp_pc_params = {0};
+ enum transmitter_color_depth bp_pc_colour_depth = TRANSMITTER_COLOR_DEPTH_24;
+ // For these signal types Driver to program DP_DTO without calling VBIOS Command table
+ if (dc_is_dp_signal(pix_clk_params->signal_type)) {
+ if (e) {
+ /* Set DTO values: phase = target clock, modulo = reference clock*/
+ REG_WRITE(PHASE[inst], e->target_pixel_rate_khz * e->mult_factor);
+ REG_WRITE(MODULO[inst], dp_dto_ref_khz * e->div_factor);
+ } else {
+ /* Set DTO values: phase = target clock, modulo = reference clock*/
+ REG_WRITE(PHASE[inst], pll_settings->actual_pix_clk_100hz * 100);
+ REG_WRITE(MODULO[inst], dp_dto_ref_khz * 1000);
+ }
+ REG_UPDATE(PIXEL_RATE_CNTL[inst], DP_DTO0_ENABLE, 1);
+ } else {
+ if (IS_FPGA_MAXIMUS_DC(clock_source->ctx->dce_environment)) {
+ unsigned int inst = pix_clk_params->controller_id - CONTROLLER_ID_D0;
+ unsigned dp_dto_ref_100hz = 7000000;
+ unsigned clock_100hz = pll_settings->actual_pix_clk_100hz;
+
+ /* Set DTO values: phase = target clock, modulo = reference clock */
+ REG_WRITE(PHASE[inst], clock_100hz);
+ REG_WRITE(MODULO[inst], dp_dto_ref_100hz);
+
+ /* Enable DTO */
+ REG_UPDATE(PIXEL_RATE_CNTL[inst], DP_DTO0_ENABLE, 1);
+ return true;
+ }
+
+ /*ATOMBIOS expects pixel rate adjusted by deep color ratio)*/
+ bp_pc_params.controller_id = pix_clk_params->controller_id;
+ bp_pc_params.pll_id = clock_source->id;
+ bp_pc_params.target_pixel_clock_100hz = pll_settings->actual_pix_clk_100hz;
+ bp_pc_params.encoder_object_id = pix_clk_params->encoder_object_id;
+ bp_pc_params.signal_type = pix_clk_params->signal_type;
+
+ // Make sure we send the correct color depth to DMUB for HDMI
+ if (pix_clk_params->signal_type == SIGNAL_TYPE_HDMI_TYPE_A) {
+ switch (pix_clk_params->color_depth) {
+ case COLOR_DEPTH_888:
+ bp_pc_colour_depth = TRANSMITTER_COLOR_DEPTH_24;
+ break;
+ case COLOR_DEPTH_101010:
+ bp_pc_colour_depth = TRANSMITTER_COLOR_DEPTH_30;
+ break;
+ case COLOR_DEPTH_121212:
+ bp_pc_colour_depth = TRANSMITTER_COLOR_DEPTH_36;
+ break;
+ case COLOR_DEPTH_161616:
+ bp_pc_colour_depth = TRANSMITTER_COLOR_DEPTH_48;
+ break;
+ default:
+ bp_pc_colour_depth = TRANSMITTER_COLOR_DEPTH_24;
+ break;
+ }
+ bp_pc_params.color_depth = bp_pc_colour_depth;
+ }
+
+ if (clock_source->id != CLOCK_SOURCE_ID_DP_DTO) {
+ bp_pc_params.flags.SET_GENLOCK_REF_DIV_SRC =
+ pll_settings->use_external_clk;
+ bp_pc_params.flags.SET_XTALIN_REF_SRC =
+ !pll_settings->use_external_clk;
+ if (pix_clk_params->flags.SUPPORT_YCBCR420) {
+ bp_pc_params.flags.SUPPORT_YUV_420 = 1;
+ }
+ }
+ if (clk_src->bios->funcs->set_pixel_clock(
+ clk_src->bios, &bp_pc_params) != BP_RESULT_OK)
+ return false;
+ /* Resync deep color DTO */
+ if (clock_source->id != CLOCK_SOURCE_ID_DP_DTO)
+ dce112_program_pixel_clk_resync(clk_src,
+ pix_clk_params->signal_type,
+ pix_clk_params->color_depth,
+ pix_clk_params->flags.SUPPORT_YCBCR420);
+ }
+
+ return true;
+}
+#endif
static bool dce110_clock_source_power_down(
struct clock_source *clk_src)
@@ -1205,6 +1297,13 @@ static const struct clock_source_funcs dcn3_clk_src_funcs = {
.get_pix_clk_dividers = dcn3_get_pix_clk_dividers,
.get_pixel_clk_frequency_100hz = get_pixel_clk_frequency_100hz
};
+
+static const struct clock_source_funcs dcn31_clk_src_funcs = {
+ .cs_power_down = dce110_clock_source_power_down,
+ .program_pix_clk = dcn31_program_pix_clk,
+ .get_pix_clk_dividers = dcn3_get_pix_clk_dividers,
+ .get_pixel_clk_frequency_100hz = get_pixel_clk_frequency_100hz
+};
#endif
/*****************************************/
/* Constructor */
@@ -1610,6 +1709,24 @@ bool dcn3_clk_src_construct(
#endif
#if defined(CONFIG_DRM_AMD_DC_DCN)
+bool dcn31_clk_src_construct(
+ struct dce110_clk_src *clk_src,
+ struct dc_context *ctx,
+ struct dc_bios *bios,
+ enum clock_source_id id,
+ const struct dce110_clk_src_regs *regs,
+ const struct dce110_clk_src_shift *cs_shift,
+ const struct dce110_clk_src_mask *cs_mask)
+{
+ bool ret = dce112_clk_src_construct(clk_src, ctx, bios, id, regs, cs_shift, cs_mask);
+
+ clk_src->base.funcs = &dcn31_clk_src_funcs;
+
+ return ret;
+}
+#endif
+
+#if defined(CONFIG_DRM_AMD_DC_DCN)
bool dcn301_clk_src_construct(
struct dce110_clk_src *clk_src,
struct dc_context *ctx,
diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_clock_source.h b/drivers/gpu/drm/amd/display/dc/dce/dce_clock_source.h
index 692fa23ca02b..069de7649c8c 100644
--- a/drivers/gpu/drm/amd/display/dc/dce/dce_clock_source.h
+++ b/drivers/gpu/drm/amd/display/dc/dce/dce_clock_source.h
@@ -292,6 +292,15 @@ bool dcn301_clk_src_construct(
const struct dce110_clk_src_regs *regs,
const struct dce110_clk_src_shift *cs_shift,
const struct dce110_clk_src_mask *cs_mask);
+
+bool dcn31_clk_src_construct(
+ struct dce110_clk_src *clk_src,
+ struct dc_context *ctx,
+ struct dc_bios *bios,
+ enum clock_source_id id,
+ const struct dce110_clk_src_regs *regs,
+ const struct dce110_clk_src_shift *cs_shift,
+ const struct dce110_clk_src_mask *cs_mask);
#endif
/* this table is use to find *1.001 and /1.001 pixel rates from non-precise pixel rate */
diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_i2c.c b/drivers/gpu/drm/amd/display/dc/dce/dce_i2c.c
index dd41736bb5c4..f5cd2392fc5f 100644
--- a/drivers/gpu/drm/amd/display/dc/dce/dce_i2c.c
+++ b/drivers/gpu/drm/amd/display/dc/dce/dce_i2c.c
@@ -25,6 +25,32 @@
#include "dce_i2c.h"
#include "reg_helper.h"
+bool dce_i2c_oem_device_present(
+ struct resource_pool *pool,
+ struct ddc_service *ddc,
+ size_t slave_address
+)
+{
+ struct dc *dc = ddc->ctx->dc;
+ struct dc_bios *dcb = dc->ctx->dc_bios;
+ struct graphics_object_id id = {0};
+ struct graphics_object_i2c_info i2c_info;
+
+ if (!dc->ctx->dc_bios->fw_info.oem_i2c_present)
+ return false;
+
+ id.id = dc->ctx->dc_bios->fw_info.oem_i2c_obj_id;
+ id.enum_id = 0;
+ id.type = OBJECT_TYPE_GENERIC;
+ if (dcb->funcs->get_i2c_info(dcb, id, &i2c_info) != BP_RESULT_OK)
+ return false;
+
+ if (i2c_info.i2c_slave_address != slave_address)
+ return false;
+
+ return true;
+}
+
bool dce_i2c_submit_command(
struct resource_pool *pool,
struct ddc *ddc,
diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_i2c.h b/drivers/gpu/drm/amd/display/dc/dce/dce_i2c.h
index a171c5cd8439..535fd58de450 100644
--- a/drivers/gpu/drm/amd/display/dc/dce/dce_i2c.h
+++ b/drivers/gpu/drm/amd/display/dc/dce/dce_i2c.h
@@ -30,6 +30,12 @@
#include "dce_i2c_hw.h"
#include "dce_i2c_sw.h"
+bool dce_i2c_oem_device_present(
+ struct resource_pool *pool,
+ struct ddc_service *ddc,
+ size_t slave_address
+);
+
bool dce_i2c_submit_command(
struct resource_pool *pool,
struct ddc *ddc,
diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c b/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c
index f1c61d5aee6c..0bc41414481e 100644
--- a/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c
+++ b/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c
@@ -1325,7 +1325,8 @@ void dce110_link_encoder_disable_output(
void dce110_link_encoder_dp_set_lane_settings(
struct link_encoder *enc,
- const struct link_training_settings *link_settings)
+ const struct dc_link_settings *link_settings,
+ const struct dc_lane_settings lane_settings[LANE_COUNT_DP_MAX])
{
struct dce110_link_encoder *enc110 = TO_DCE110_LINK_ENC(enc);
union dpcd_training_lane_set training_lane_set = { { 0 } };
@@ -1340,26 +1341,26 @@ void dce110_link_encoder_dp_set_lane_settings(
cntl.action = TRANSMITTER_CONTROL_SET_VOLTAGE_AND_PREEMPASIS;
cntl.transmitter = enc110->base.transmitter;
cntl.connector_obj_id = enc110->base.connector;
- cntl.lanes_number = link_settings->link_settings.lane_count;
+ cntl.lanes_number = link_settings->lane_count;
cntl.hpd_sel = enc110->base.hpd_source;
- cntl.pixel_clock = link_settings->link_settings.link_rate *
+ cntl.pixel_clock = link_settings->link_rate *
LINK_RATE_REF_FREQ_IN_KHZ;
- for (lane = 0; lane < link_settings->link_settings.lane_count; lane++) {
+ for (lane = 0; lane < link_settings->lane_count; lane++) {
/* translate lane settings */
training_lane_set.bits.VOLTAGE_SWING_SET =
- link_settings->lane_settings[lane].VOLTAGE_SWING;
+ lane_settings[lane].VOLTAGE_SWING;
training_lane_set.bits.PRE_EMPHASIS_SET =
- link_settings->lane_settings[lane].PRE_EMPHASIS;
+ lane_settings[lane].PRE_EMPHASIS;
/* post cursor 2 setting only applies to HBR2 link rate */
- if (link_settings->link_settings.link_rate == LINK_RATE_HIGH2) {
+ if (link_settings->link_rate == LINK_RATE_HIGH2) {
/* this is passed to VBIOS
* to program post cursor 2 level */
training_lane_set.bits.POST_CURSOR2_SET =
- link_settings->lane_settings[lane].POST_CURSOR2;
+ lane_settings[lane].POST_CURSOR2;
}
cntl.lane_select = lane;
diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.h b/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.h
index fc6ade824c23..261c70e01e33 100644
--- a/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.h
+++ b/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.h
@@ -279,7 +279,8 @@ void dce110_link_encoder_disable_output(
/* set DP lane settings */
void dce110_link_encoder_dp_set_lane_settings(
struct link_encoder *enc,
- const struct link_training_settings *link_settings);
+ const struct dc_link_settings *link_settings,
+ const struct dc_lane_settings lane_settings[LANE_COUNT_DP_MAX]);
void dce110_link_encoder_dp_set_phy_pattern(
struct link_encoder *enc,
diff --git a/drivers/gpu/drm/amd/display/dc/dce/dmub_outbox.c b/drivers/gpu/drm/amd/display/dc/dce/dmub_outbox.c
index faad8555ddbb..fff1d07d865d 100644
--- a/drivers/gpu/drm/amd/display/dc/dce/dmub_outbox.c
+++ b/drivers/gpu/drm/amd/display/dc/dce/dmub_outbox.c
@@ -22,20 +22,23 @@
* Authors: AMD
*/
-#include "dmub_outbox.h"
+#include "dc.h"
#include "dc_dmub_srv.h"
+#include "dmub_outbox.h"
#include "dmub/inc/dmub_cmd.h"
-/**
- * dmub_enable_outbox_notification - Sends inbox cmd to dmub to enable outbox1
- * messages with interrupt. Dmub sends outbox1
- * message and triggers outbox1 interrupt.
- * @dc: dc structure
+/*
+ * Function: dmub_enable_outbox_notification
+ *
+ * @brief
+ * Sends inbox cmd to dmub for enabling outbox notifications to x86.
+ *
+ * @param
+ * [in] dmub_srv: dmub_srv structure
*/
-void dmub_enable_outbox_notification(struct dc *dc)
+void dmub_enable_outbox_notification(struct dc_dmub_srv *dmub_srv)
{
union dmub_rb_cmd cmd;
- struct dc_context *dc_ctx = dc->ctx;
memset(&cmd, 0x0, sizeof(cmd));
cmd.outbox1_enable.header.type = DMUB_CMD__OUTBOX1_ENABLE;
@@ -45,7 +48,7 @@ void dmub_enable_outbox_notification(struct dc *dc)
sizeof(cmd.outbox1_enable.header);
cmd.outbox1_enable.enable = true;
- dc_dmub_srv_cmd_queue(dc_ctx->dmub_srv, &cmd);
- dc_dmub_srv_cmd_execute(dc_ctx->dmub_srv);
- dc_dmub_srv_wait_idle(dc_ctx->dmub_srv);
+ dc_dmub_srv_cmd_queue(dmub_srv, &cmd);
+ dc_dmub_srv_cmd_execute(dmub_srv);
+ dc_dmub_srv_wait_idle(dmub_srv);
}
diff --git a/drivers/gpu/drm/amd/display/dc/dce/dmub_outbox.h b/drivers/gpu/drm/amd/display/dc/dce/dmub_outbox.h
index 4e0aa0d1a2d5..58ceabb9d497 100644
--- a/drivers/gpu/drm/amd/display/dc/dce/dmub_outbox.h
+++ b/drivers/gpu/drm/amd/display/dc/dce/dmub_outbox.h
@@ -26,8 +26,8 @@
#ifndef _DMUB_OUTBOX_H_
#define _DMUB_OUTBOX_H_
-#include "dc.h"
+struct dc_dmub_srv;
-void dmub_enable_outbox_notification(struct dc *dc);
+void dmub_enable_outbox_notification(struct dc_dmub_srv *dmub_srv);
#endif /* _DMUB_OUTBOX_H_ */
diff --git a/drivers/gpu/drm/amd/display/dc/dce/dmub_psr.c b/drivers/gpu/drm/amd/display/dc/dce/dmub_psr.c
index 87ed48d5530d..312c68172689 100644
--- a/drivers/gpu/drm/amd/display/dc/dce/dmub_psr.c
+++ b/drivers/gpu/drm/amd/display/dc/dce/dmub_psr.c
@@ -138,6 +138,10 @@ static bool dmub_psr_set_version(struct dmub_psr *dmub, struct dc_stream_state *
cmd.psr_set_version.psr_set_version_data.version = PSR_VERSION_UNSUPPORTED;
break;
}
+
+ if (cmd.psr_set_version.psr_set_version_data.version == PSR_VERSION_UNSUPPORTED)
+ return false;
+
cmd.psr_set_version.psr_set_version_data.cmd_version = DMUB_CMD_PSR_CONTROL_VERSION_1;
cmd.psr_set_version.psr_set_version_data.panel_inst = panel_inst;
cmd.psr_set_version.header.payload_bytes = sizeof(struct dmub_cmd_psr_set_version_data);
@@ -316,6 +320,7 @@ static bool dmub_psr_copy_settings(struct dmub_psr *dmub,
copy_settings_data->otg_inst = 0;
// Misc
+ copy_settings_data->use_phy_fsm = link->ctx->dc->debug.psr_power_use_phy_fsm;
copy_settings_data->psr_level = psr_context->psr_level.u32all;
copy_settings_data->smu_optimizations_en = psr_context->allow_smu_optimizations;
copy_settings_data->multi_disp_optimizations_en = psr_context->allow_multi_disp_optimizations;
diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c
index 78192ecba102..248602c15f3a 100644
--- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c
+++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c
@@ -49,9 +49,7 @@
#include "link_enc_cfg.h"
#include "link_hwss.h"
#include "dc_link_dp.h"
-#if defined(CONFIG_DRM_AMD_DC_DCN)
#include "dccg.h"
-#endif
#include "clock_source.h"
#include "clk_mgr.h"
#include "abm.h"
@@ -669,17 +667,12 @@ void dce110_enable_stream(struct pipe_ctx *pipe_ctx)
struct dc_crtc_timing *timing = &pipe_ctx->stream->timing;
struct dc_link *link = pipe_ctx->stream->link;
const struct dc *dc = link->dc;
-
+ const struct link_hwss *link_hwss = get_link_hwss(link, &pipe_ctx->link_res);
uint32_t active_total_with_borders;
uint32_t early_control = 0;
struct timing_generator *tg = pipe_ctx->stream_res.tg;
- /* For MST, there are multiply stream go to only one link.
- * connect DIG back_end to front_end while enable_stream and
- * disconnect them during disable_stream
- * BY this, it is logic clean to separate stream and link */
- link->link_enc->funcs->connect_dig_be_to_fe(link->link_enc,
- pipe_ctx->stream_res.stream_enc->id, true);
+ link_hwss->setup_stream_encoder(pipe_ctx);
dc->hwss.update_info_frame(pipe_ctx);
@@ -795,7 +788,7 @@ void dce110_edp_wait_for_hpd_ready(
dal_gpio_destroy_irq(&hpd);
if (false == edp_hpd_high) {
- DC_LOG_ERROR(
+ DC_LOG_WARNING(
"%s: wait timed out!\n", __func__);
}
}
@@ -1112,17 +1105,12 @@ void dce110_enable_audio_stream(struct pipe_ctx *pipe_ctx)
clk_mgr->funcs->enable_pme_wa(clk_mgr);
/* un-mute audio */
/* TODO: audio should be per stream rather than per link */
-#if defined(CONFIG_DRM_AMD_DC_DCN)
if (is_dp_128b_132b_signal(pipe_ctx))
pipe_ctx->stream_res.hpo_dp_stream_enc->funcs->audio_mute_control(
pipe_ctx->stream_res.hpo_dp_stream_enc, false);
else
pipe_ctx->stream_res.stream_enc->funcs->audio_mute_control(
pipe_ctx->stream_res.stream_enc, false);
-#else
- pipe_ctx->stream_res.stream_enc->funcs->audio_mute_control(
- pipe_ctx->stream_res.stream_enc, false);
-#endif
if (pipe_ctx->stream_res.audio)
pipe_ctx->stream_res.audio->enabled = true;
}
@@ -1145,32 +1133,22 @@ void dce110_disable_audio_stream(struct pipe_ctx *pipe_ctx)
if (pipe_ctx->stream_res.audio && pipe_ctx->stream_res.audio->enabled == false)
return;
-#if defined(CONFIG_DRM_AMD_DC_DCN)
if (is_dp_128b_132b_signal(pipe_ctx))
pipe_ctx->stream_res.hpo_dp_stream_enc->funcs->audio_mute_control(
pipe_ctx->stream_res.hpo_dp_stream_enc, true);
else
pipe_ctx->stream_res.stream_enc->funcs->audio_mute_control(
pipe_ctx->stream_res.stream_enc, true);
-#else
- pipe_ctx->stream_res.stream_enc->funcs->audio_mute_control(
- pipe_ctx->stream_res.stream_enc, true);
-#endif
if (pipe_ctx->stream_res.audio) {
pipe_ctx->stream_res.audio->enabled = false;
if (dc_is_dp_signal(pipe_ctx->stream->signal))
-#if defined(CONFIG_DRM_AMD_DC_DCN)
if (is_dp_128b_132b_signal(pipe_ctx))
pipe_ctx->stream_res.hpo_dp_stream_enc->funcs->dp_audio_disable(
pipe_ctx->stream_res.hpo_dp_stream_enc);
else
pipe_ctx->stream_res.stream_enc->funcs->dp_audio_disable(
pipe_ctx->stream_res.stream_enc);
-#else
- pipe_ctx->stream_res.stream_enc->funcs->dp_audio_disable(
- pipe_ctx->stream_res.stream_enc);
-#endif
else
pipe_ctx->stream_res.stream_enc->funcs->hdmi_audio_disable(
pipe_ctx->stream_res.stream_enc);
@@ -1195,7 +1173,7 @@ void dce110_disable_stream(struct pipe_ctx *pipe_ctx)
struct dc_stream_state *stream = pipe_ctx->stream;
struct dc_link *link = stream->link;
struct dc *dc = pipe_ctx->stream->ctx->dc;
- struct link_encoder *link_enc = NULL;
+ const struct link_hwss *link_hwss = get_link_hwss(link, &pipe_ctx->link_res);
if (dc_is_hdmi_tmds_signal(pipe_ctx->stream->signal)) {
pipe_ctx->stream_res.stream_enc->funcs->stop_hdmi_info_packets(
@@ -1204,54 +1182,26 @@ void dce110_disable_stream(struct pipe_ctx *pipe_ctx)
pipe_ctx->stream_res.stream_enc);
}
-#if defined(CONFIG_DRM_AMD_DC_DCN)
if (is_dp_128b_132b_signal(pipe_ctx)) {
pipe_ctx->stream_res.hpo_dp_stream_enc->funcs->stop_dp_info_packets(
pipe_ctx->stream_res.hpo_dp_stream_enc);
} else if (dc_is_dp_signal(pipe_ctx->stream->signal))
-#else
- if (dc_is_dp_signal(pipe_ctx->stream->signal))
-#endif
pipe_ctx->stream_res.stream_enc->funcs->stop_dp_info_packets(
pipe_ctx->stream_res.stream_enc);
dc->hwss.disable_audio_stream(pipe_ctx);
- /* Link encoder may have been dynamically assigned to non-physical display endpoint. */
- if (link->ep_type == DISPLAY_ENDPOINT_PHY)
- link_enc = link->link_enc;
- else if (dc->res_pool->funcs->link_encs_assign)
- link_enc = link_enc_cfg_get_link_enc_used_by_link(link->ctx->dc, link);
- ASSERT(link_enc);
+ link_hwss->reset_stream_encoder(pipe_ctx);
-#if defined(CONFIG_DRM_AMD_DC_DCN)
if (is_dp_128b_132b_signal(pipe_ctx)) {
- pipe_ctx->stream_res.hpo_dp_stream_enc->funcs->disable(
- pipe_ctx->stream_res.hpo_dp_stream_enc);
- setup_dp_hpo_stream(pipe_ctx, false);
- /* TODO - DP2.0 HW: unmap stream from link encoder here */
- } else {
- if (link_enc)
- link_enc->funcs->connect_dig_be_to_fe(
- link_enc,
- pipe_ctx->stream_res.stream_enc->id,
- false);
- }
-#else
- if (link_enc)
- link_enc->funcs->connect_dig_be_to_fe(
- link->link_enc,
- pipe_ctx->stream_res.stream_enc->id,
- false);
-#endif
- if (dc_is_dp_signal(pipe_ctx->stream->signal))
- dp_source_sequence_trace(link, DPCD_SOURCE_SEQ_AFTER_DISCONNECT_DIG_FE_BE);
-
-#if defined(CONFIG_DRM_AMD_DC_DCN)
- if (dc->hwseq->funcs.setup_hpo_hw_control && is_dp_128b_132b_signal(pipe_ctx))
- dc->hwseq->funcs.setup_hpo_hw_control(dc->hwseq, false);
-#endif
-
+ /* TODO: This looks like a bug to me as we are disabling HPO IO when
+ * we are just disabling a single HPO stream. Shouldn't we disable HPO
+ * HW control only when HPOs for all streams are disabled?
+ */
+ if (pipe_ctx->stream->ctx->dc->hwseq->funcs.setup_hpo_hw_control)
+ pipe_ctx->stream->ctx->dc->hwseq->funcs.setup_hpo_hw_control(
+ pipe_ctx->stream->ctx->dc->hwseq, false);
+ }
}
void dce110_unblank_stream(struct pipe_ctx *pipe_ctx,
@@ -1285,15 +1235,11 @@ void dce110_blank_stream(struct pipe_ctx *pipe_ctx)
link->dc->hwss.set_abm_immediate_disable(pipe_ctx);
}
-#if defined(CONFIG_DRM_AMD_DC_DCN)
if (is_dp_128b_132b_signal(pipe_ctx)) {
/* TODO - DP2.0 HW: Set ODM mode in dp hpo encoder here */
pipe_ctx->stream_res.hpo_dp_stream_enc->funcs->dp_blank(
pipe_ctx->stream_res.hpo_dp_stream_enc);
} else if (dc_is_dp_signal(pipe_ctx->stream->signal)) {
-#else
- if (dc_is_dp_signal(pipe_ctx->stream->signal)) {
-#endif
pipe_ctx->stream_res.stream_enc->funcs->dp_blank(link, pipe_ctx->stream_res.stream_enc);
if (!dc_is_embedded_signal(pipe_ctx->stream->signal)) {
@@ -1535,7 +1481,6 @@ static enum dc_status apply_single_controller_ctx_to_hw(
build_audio_output(context, pipe_ctx, &audio_output);
if (dc_is_dp_signal(pipe_ctx->stream->signal))
-#if defined(CONFIG_DRM_AMD_DC_DCN)
if (is_dp_128b_132b_signal(pipe_ctx))
pipe_ctx->stream_res.hpo_dp_stream_enc->funcs->dp_audio_setup(
pipe_ctx->stream_res.hpo_dp_stream_enc,
@@ -1546,12 +1491,6 @@ static enum dc_status apply_single_controller_ctx_to_hw(
pipe_ctx->stream_res.stream_enc,
pipe_ctx->stream_res.audio->inst,
&pipe_ctx->stream->audio_info);
-#else
- pipe_ctx->stream_res.stream_enc->funcs->dp_audio_setup(
- pipe_ctx->stream_res.stream_enc,
- pipe_ctx->stream_res.audio->inst,
- &pipe_ctx->stream->audio_info);
-#endif
else
pipe_ctx->stream_res.stream_enc->funcs->hdmi_audio_setup(
pipe_ctx->stream_res.stream_enc,
@@ -1566,14 +1505,41 @@ static enum dc_status apply_single_controller_ctx_to_hw(
&pipe_ctx->stream->audio_info);
}
-#if defined(CONFIG_DRM_AMD_DC_DCN)
+ /* make sure no pipes syncd to the pipe being enabled */
+ if (!pipe_ctx->stream->apply_seamless_boot_optimization && dc->config.use_pipe_ctx_sync_logic)
+ check_syncd_pipes_for_disabled_master_pipe(dc, context, pipe_ctx->pipe_idx);
+
+ pipe_ctx->stream_res.opp->funcs->opp_program_fmt(
+ pipe_ctx->stream_res.opp,
+ &stream->bit_depth_params,
+ &stream->clamping);
+
+ pipe_ctx->stream_res.opp->funcs->opp_set_dyn_expansion(
+ pipe_ctx->stream_res.opp,
+ COLOR_SPACE_YCBCR601,
+ stream->timing.display_color_depth,
+ stream->signal);
+
+ while (odm_pipe) {
+ odm_pipe->stream_res.opp->funcs->opp_set_dyn_expansion(
+ odm_pipe->stream_res.opp,
+ COLOR_SPACE_YCBCR601,
+ stream->timing.display_color_depth,
+ stream->signal);
+
+ odm_pipe->stream_res.opp->funcs->opp_program_fmt(
+ odm_pipe->stream_res.opp,
+ &stream->bit_depth_params,
+ &stream->clamping);
+ odm_pipe = odm_pipe->next_odm_pipe;
+ }
+
/* DCN3.1 FPGA Workaround
* Need to enable HPO DP Stream Encoder before setting OTG master enable.
* To do so, move calling function enable_stream_timing to only be done AFTER calling
* function core_link_enable_stream
*/
if (!(hws->wa.dp_hpo_and_otg_sequence && is_dp_128b_132b_signal(pipe_ctx)))
-#endif
/* */
/* Do not touch stream timing on seamless boot optimization. */
if (!pipe_ctx->stream->apply_seamless_boot_optimization)
@@ -1604,42 +1570,12 @@ static enum dc_status apply_single_controller_ctx_to_hw(
pipe_ctx->stream_res.stream_enc,
pipe_ctx->stream_res.tg->inst);
- if (dc_is_dp_signal(pipe_ctx->stream->signal) &&
- pipe_ctx->stream_res.stream_enc->funcs->reset_fifo)
- pipe_ctx->stream_res.stream_enc->funcs->reset_fifo(
- pipe_ctx->stream_res.stream_enc);
-
if (dc_is_dp_signal(pipe_ctx->stream->signal))
dp_source_sequence_trace(link, DPCD_SOURCE_SEQ_AFTER_CONNECT_DIG_FE_OTG);
- pipe_ctx->stream_res.opp->funcs->opp_set_dyn_expansion(
- pipe_ctx->stream_res.opp,
- COLOR_SPACE_YCBCR601,
- stream->timing.display_color_depth,
- stream->signal);
-
- pipe_ctx->stream_res.opp->funcs->opp_program_fmt(
- pipe_ctx->stream_res.opp,
- &stream->bit_depth_params,
- &stream->clamping);
- while (odm_pipe) {
- odm_pipe->stream_res.opp->funcs->opp_set_dyn_expansion(
- odm_pipe->stream_res.opp,
- COLOR_SPACE_YCBCR601,
- stream->timing.display_color_depth,
- stream->signal);
-
- odm_pipe->stream_res.opp->funcs->opp_program_fmt(
- odm_pipe->stream_res.opp,
- &stream->bit_depth_params,
- &stream->clamping);
- odm_pipe = odm_pipe->next_odm_pipe;
- }
-
if (!stream->dpms_off)
core_link_enable_stream(context, pipe_ctx);
-#if defined(CONFIG_DRM_AMD_DC_DCN)
/* DCN3.1 FPGA Workaround
* Need to enable HPO DP Stream Encoder before setting OTG master enable.
* To do so, move calling function enable_stream_timing to only be done AFTER calling
@@ -1649,9 +1585,8 @@ static enum dc_status apply_single_controller_ctx_to_hw(
if (!pipe_ctx->stream->apply_seamless_boot_optimization)
hws->funcs.enable_stream_timing(pipe_ctx, context, dc);
}
-#endif
- pipe_ctx->plane_res.scl_data.lb_params.alpha_en = pipe_ctx->bottom_pipe != 0;
+ pipe_ctx->plane_res.scl_data.lb_params.alpha_en = pipe_ctx->bottom_pipe != NULL;
pipe_ctx->stream->link->psr_settings.psr_feature_enabled = false;
@@ -1827,7 +1762,8 @@ void dce110_enable_accelerated_mode(struct dc *dc, struct dc_state *context)
edp_link->link_status.link_active) {
struct dc_stream_state *edp_stream = edp_streams[0];
- can_apply_edp_fast_boot = !is_edp_ilr_optimization_required(edp_stream->link, &edp_stream->timing);
+ can_apply_edp_fast_boot = dc_validate_boot_timing(dc,
+ edp_stream->sink, &edp_stream->timing);
edp_stream->apply_edp_fast_boot_optimization = can_apply_edp_fast_boot;
if (can_apply_edp_fast_boot)
DC_LOG_EVENT_LINK_TRAINING("eDP fast boot disabled to optimize link rate\n");
@@ -1835,9 +1771,29 @@ void dce110_enable_accelerated_mode(struct dc *dc, struct dc_state *context)
break;
}
}
- // We are trying to enable eDP, don't power down VDD
- if (can_apply_edp_fast_boot)
+
+ /*
+ * TO-DO: So far the code logic below only addresses single eDP case.
+ * For dual eDP case, there are a few things that need to be
+ * implemented first:
+ *
+ * 1. Change the fastboot logic above, so eDP link[0 or 1]'s
+ * stream[0 or 1] will all be checked.
+ *
+ * 2. Change keep_edp_vdd_on to an array, and maintain keep_edp_vdd_on
+ * for each eDP.
+ *
+ * Once above 2 things are completed, we can then change the logic below
+ * correspondingly, so dual eDP case will be fully covered.
+ */
+
+ // We are trying to enable eDP, don't power down VDD if eDP stream is existing
+ if ((edp_stream_num == 1 && edp_streams[0] != NULL) || can_apply_edp_fast_boot) {
keep_edp_vdd_on = true;
+ DC_LOG_EVENT_LINK_TRAINING("Keep eDP Vdd on\n");
+ } else {
+ DC_LOG_EVENT_LINK_TRAINING("No eDP stream enabled, turn eDP Vdd off\n");
+ }
}
// Check seamless boot support
@@ -2229,8 +2185,6 @@ static void dce110_setup_audio_dto(
build_audio_output(context, pipe_ctx, &audio_output);
-#if defined(CONFIG_DRM_AMD_DC_DCN)
- /* For DCN3.1, audio to HPO FRL encoder is using audio DTBCLK DTO */
if (dc->res_pool->dccg && dc->res_pool->dccg->funcs->set_audio_dtbclk_dto) {
/* disable audio DTBCLK DTO */
dc->res_pool->dccg->funcs->set_audio_dtbclk_dto(
@@ -2247,13 +2201,6 @@ static void dce110_setup_audio_dto(
pipe_ctx->stream->signal,
&audio_output.crtc_info,
&audio_output.pll_info);
-#else
- pipe_ctx->stream_res.audio->funcs->wall_dto_setup(
- pipe_ctx->stream_res.audio,
- pipe_ctx->stream->signal,
- &audio_output.crtc_info,
- &audio_output.pll_info);
-#endif
break;
}
}
@@ -2297,6 +2244,10 @@ enum dc_status dce110_apply_ctx_to_hw(
enum dc_status status;
int i;
+ /* reset syncd pipes from disabled pipes */
+ if (dc->config.use_pipe_ctx_sync_logic)
+ reset_syncd_pipes_from_disabled_pipes(dc, context);
+
/* Reset old context */
/* look up the targets that have been removed since last commit */
hws->funcs.reset_hw_ctx_wrap(dc, context);
@@ -2772,7 +2723,7 @@ static void dce110_program_front_end_for_pipe(
pipe_ctx->plane_res.xfm->funcs->transform_set_gamut_remap(pipe_ctx->plane_res.xfm, &adjust);
- pipe_ctx->plane_res.scl_data.lb_params.alpha_en = pipe_ctx->bottom_pipe != 0;
+ pipe_ctx->plane_res.scl_data.lb_params.alpha_en = pipe_ctx->bottom_pipe != NULL;
program_scaler(dc, pipe_ctx);
diff --git a/drivers/gpu/drm/amd/display/dc/dce112/dce112_resource.c b/drivers/gpu/drm/amd/display/dc/dce112/dce112_resource.c
index ee55cda854bf..560da6cbcaa3 100644
--- a/drivers/gpu/drm/amd/display/dc/dce112/dce112_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/dce112/dce112_resource.c
@@ -862,7 +862,7 @@ static struct clock_source *find_matching_pll(
return NULL;
}
- return 0;
+ return NULL;
}
static enum dc_status build_mapped_resource(
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.c
index f4f423d0b8c3..80595d7f060c 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.c
@@ -940,6 +940,7 @@ static const struct hubbub_funcs hubbub1_funcs = {
.program_watermarks = hubbub1_program_watermarks,
.is_allow_self_refresh_enabled = hubbub1_is_allow_self_refresh_enabled,
.allow_self_refresh_control = hubbub1_allow_self_refresh_control,
+ .verify_allow_pstate_change_high = hubbub1_verify_allow_pstate_change_high,
};
void hubbub1_construct(struct hubbub *hubbub,
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.c
index ea185c877323..fbff6beb78be 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.c
@@ -1311,6 +1311,20 @@ void hubp1_set_flip_int(struct hubp *hubp)
return;
}
+/**
+ * hubp1_wait_pipe_read_start - wait for hubp ret path starting read.
+ *
+ * @hubp: hubp struct reference.
+ */
+void hubp1_wait_pipe_read_start(struct hubp *hubp)
+{
+ struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
+
+ REG_WAIT(HUBPRET_READ_LINE_STATUS,
+ PIPE_READ_VBLANK, 0,
+ 1, 1000);
+}
+
void hubp1_init(struct hubp *hubp)
{
//do nothing
@@ -1345,6 +1359,7 @@ static const struct hubp_funcs dcn10_hubp_funcs = {
.hubp_soft_reset = hubp1_soft_reset,
.hubp_in_blank = hubp1_in_blank,
.hubp_set_flip_int = hubp1_set_flip_int,
+ .hubp_wait_pipe_read_start = hubp1_wait_pipe_read_start,
};
/*****************************************/
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.h b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.h
index 9cb8c383d673..0b17c2993ca5 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.h
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.h
@@ -76,6 +76,7 @@
SRI(DCSURF_SURFACE_CONTROL, HUBPREQ, id),\
SRI(DCSURF_SURFACE_FLIP_INTERRUPT, HUBPREQ, id),\
SRI(HUBPRET_CONTROL, HUBPRET, id),\
+ SRI(HUBPRET_READ_LINE_STATUS, HUBPRET, id),\
SRI(DCN_EXPANSION_MODE, HUBPREQ, id),\
SRI(DCHUBP_REQ_SIZE_CONFIG, HUBP, id),\
SRI(DCHUBP_REQ_SIZE_CONFIG_C, HUBP, id),\
@@ -186,6 +187,7 @@
uint32_t DCSURF_SURFACE_CONTROL; \
uint32_t DCSURF_SURFACE_FLIP_INTERRUPT; \
uint32_t HUBPRET_CONTROL; \
+ uint32_t HUBPRET_READ_LINE_STATUS; \
uint32_t DCN_EXPANSION_MODE; \
uint32_t DCHUBP_REQ_SIZE_CONFIG; \
uint32_t DCHUBP_REQ_SIZE_CONFIG_C; \
@@ -338,6 +340,7 @@
HUBP_SF(HUBPRET0_HUBPRET_CONTROL, DET_BUF_PLANE1_BASE_ADDRESS, mask_sh),\
HUBP_SF(HUBPRET0_HUBPRET_CONTROL, CROSSBAR_SRC_CB_B, mask_sh),\
HUBP_SF(HUBPRET0_HUBPRET_CONTROL, CROSSBAR_SRC_CR_R, mask_sh),\
+ HUBP_SF(HUBPRET0_HUBPRET_READ_LINE_STATUS, PIPE_READ_VBLANK, mask_sh),\
HUBP_SF(HUBPREQ0_DCN_EXPANSION_MODE, DRQ_EXPANSION_MODE, mask_sh),\
HUBP_SF(HUBPREQ0_DCN_EXPANSION_MODE, PRQ_EXPANSION_MODE, mask_sh),\
HUBP_SF(HUBPREQ0_DCN_EXPANSION_MODE, MRQ_EXPANSION_MODE, mask_sh),\
@@ -538,6 +541,7 @@
type DET_BUF_PLANE1_BASE_ADDRESS;\
type CROSSBAR_SRC_CB_B;\
type CROSSBAR_SRC_CR_R;\
+ type PIPE_READ_VBLANK;\
type DRQ_EXPANSION_MODE;\
type PRQ_EXPANSION_MODE;\
type MRQ_EXPANSION_MODE;\
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
index 530a72e3eefe..c3e141c19a77 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
@@ -107,7 +107,7 @@ void dcn10_lock_all_pipes(struct dc *dc,
* (un)locking. Also skip if pipe is disabled.
*/
if (pipe_ctx->top_pipe ||
- !pipe_ctx->stream || !pipe_ctx->plane_state ||
+ !pipe_ctx->stream ||
!tg->funcs->is_tg_enabled(tg))
continue;
@@ -1112,9 +1112,13 @@ static bool dcn10_hw_wa_force_recovery(struct dc *dc)
void dcn10_verify_allow_pstate_change_high(struct dc *dc)
{
+ struct hubbub *hubbub = dc->res_pool->hubbub;
static bool should_log_hw_state; /* prevent hw state log by default */
- if (!hubbub1_verify_allow_pstate_change_high(dc->res_pool->hubbub)) {
+ if (!hubbub->funcs->verify_allow_pstate_change_high)
+ return;
+
+ if (!hubbub->funcs->verify_allow_pstate_change_high(hubbub)) {
int i = 0;
if (should_log_hw_state)
@@ -1123,8 +1127,8 @@ void dcn10_verify_allow_pstate_change_high(struct dc *dc)
TRACE_DC_PIPE_STATE(pipe_ctx, i, MAX_PIPES);
BREAK_TO_DEBUGGER();
if (dcn10_hw_wa_force_recovery(dc)) {
- /*check again*/
- if (!hubbub1_verify_allow_pstate_change_high(dc->res_pool->hubbub))
+ /*check again*/
+ if (!hubbub->funcs->verify_allow_pstate_change_high(hubbub))
BREAK_TO_DEBUGGER();
}
}
@@ -1500,13 +1504,8 @@ void dcn10_init_hw(struct dc *dc)
hws->funcs.dsc_pg_control(hws, res_pool->dscs[i]->inst, false);
}
- /* Enable outbox notification feature of dmub */
- if (dc->debug.enable_dmub_aux_for_legacy_ddc)
- dmub_enable_outbox_notification(dc);
-
/* we want to turn off all dp displays before doing detection */
- if (dc->config.power_down_display_on_boot)
- dc_link_blank_all_dp_displays(dc);
+ dc_link_blank_all_dp_displays(dc);
/* If taking control over from VBIOS, we may want to optimize our first
* mode set, so we need to skip powering down pipes until we know which
@@ -1514,7 +1513,7 @@ void dcn10_init_hw(struct dc *dc)
* Otherwise, if taking control is not possible, we need to power
* everything down.
*/
- if (dcb->funcs->is_accelerated_mode(dcb) || dc->config.power_down_display_on_boot) {
+ if (dcb->funcs->is_accelerated_mode(dcb) || !dc->config.seamless_boot_edp_requested) {
if (!is_optimized_init_done) {
hws->funcs.init_pipes(dc, dc->current_state);
if (dc->res_pool->hubbub->funcs->allow_self_refresh_control)
@@ -2065,14 +2064,11 @@ static int dcn10_align_pixel_clocks(struct dc *dc, int group_size,
uint32_t embedded_pix_clk_100hz;
uint16_t embedded_h_total;
uint16_t embedded_v_total;
- bool clamshell_closed = false;
uint32_t dp_ref_clk_100hz =
dc->res_pool->dp_clock_source->ctx->dc->clk_mgr->dprefclk_khz*10;
if (dc->config.vblank_alignment_dto_params &&
dc->res_pool->dp_clock_source->funcs->override_dp_pix_clk) {
- clamshell_closed =
- (dc->config.vblank_alignment_dto_params >> 63);
embedded_h_total =
(dc->config.vblank_alignment_dto_params >> 32) & 0x7FFF;
embedded_v_total =
@@ -3101,7 +3097,8 @@ static void dcn10_config_stereo_parameters(
flags->PROGRAM_STEREO = 1;
flags->PROGRAM_POLARITY = 1;
- if (timing_3d_format == TIMING_3D_FORMAT_INBAND_FA ||
+ if (timing_3d_format == TIMING_3D_FORMAT_FRAME_ALTERNATE ||
+ timing_3d_format == TIMING_3D_FORMAT_INBAND_FA ||
timing_3d_format == TIMING_3D_FORMAT_DP_HDMI_INBAND_FA ||
timing_3d_format == TIMING_3D_FORMAT_SIDEBAND_FA) {
enum display_dongle_type dongle = \
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_link_encoder.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_link_encoder.c
index f4b34c110eae..ca39361f71c8 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_link_encoder.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_link_encoder.c
@@ -1101,7 +1101,8 @@ void dcn10_link_encoder_disable_output(
void dcn10_link_encoder_dp_set_lane_settings(
struct link_encoder *enc,
- const struct link_training_settings *link_settings)
+ const struct dc_link_settings *link_settings,
+ const struct dc_lane_settings lane_settings[LANE_COUNT_DP_MAX])
{
struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
union dpcd_training_lane_set training_lane_set = { { 0 } };
@@ -1116,26 +1117,25 @@ void dcn10_link_encoder_dp_set_lane_settings(
cntl.action = TRANSMITTER_CONTROL_SET_VOLTAGE_AND_PREEMPASIS;
cntl.transmitter = enc10->base.transmitter;
cntl.connector_obj_id = enc10->base.connector;
- cntl.lanes_number = link_settings->link_settings.lane_count;
+ cntl.lanes_number = link_settings->lane_count;
cntl.hpd_sel = enc10->base.hpd_source;
- cntl.pixel_clock = link_settings->link_settings.link_rate *
- LINK_RATE_REF_FREQ_IN_KHZ;
+ cntl.pixel_clock = link_settings->link_rate * LINK_RATE_REF_FREQ_IN_KHZ;
- for (lane = 0; lane < link_settings->link_settings.lane_count; lane++) {
+ for (lane = 0; lane < link_settings->lane_count; lane++) {
/* translate lane settings */
training_lane_set.bits.VOLTAGE_SWING_SET =
- link_settings->lane_settings[lane].VOLTAGE_SWING;
+ lane_settings[lane].VOLTAGE_SWING;
training_lane_set.bits.PRE_EMPHASIS_SET =
- link_settings->lane_settings[lane].PRE_EMPHASIS;
+ lane_settings[lane].PRE_EMPHASIS;
/* post cursor 2 setting only applies to HBR2 link rate */
- if (link_settings->link_settings.link_rate == LINK_RATE_HIGH2) {
+ if (link_settings->link_rate == LINK_RATE_HIGH2) {
/* this is passed to VBIOS
* to program post cursor 2 level
*/
training_lane_set.bits.POST_CURSOR2_SET =
- link_settings->lane_settings[lane].POST_CURSOR2;
+ lane_settings[lane].POST_CURSOR2;
}
cntl.lane_select = lane;
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_link_encoder.h b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_link_encoder.h
index c337588231ff..663aac0a164a 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_link_encoder.h
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_link_encoder.h
@@ -581,7 +581,8 @@ void dcn10_link_encoder_disable_output(
/* set DP lane settings */
void dcn10_link_encoder_dp_set_lane_settings(
struct link_encoder *enc,
- const struct link_training_settings *link_settings);
+ const struct dc_link_settings *link_settings,
+ const struct dc_lane_settings lane_settings[LANE_COUNT_DP_MAX]);
void dcn10_link_encoder_dp_set_phy_pattern(
struct link_encoder *enc,
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c
index 858b72149897..4048908dd265 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c
@@ -70,68 +70,6 @@
#include "dce/dce_aux.h"
#include "dce/dce_i2c.h"
-const struct _vcs_dpi_ip_params_st dcn1_0_ip = {
- .rob_buffer_size_kbytes = 64,
- .det_buffer_size_kbytes = 164,
- .dpte_buffer_size_in_pte_reqs_luma = 42,
- .dpp_output_buffer_pixels = 2560,
- .opp_output_buffer_lines = 1,
- .pixel_chunk_size_kbytes = 8,
- .pte_enable = 1,
- .pte_chunk_size_kbytes = 2,
- .meta_chunk_size_kbytes = 2,
- .writeback_chunk_size_kbytes = 2,
- .line_buffer_size_bits = 589824,
- .max_line_buffer_lines = 12,
- .IsLineBufferBppFixed = 0,
- .LineBufferFixedBpp = -1,
- .writeback_luma_buffer_size_kbytes = 12,
- .writeback_chroma_buffer_size_kbytes = 8,
- .max_num_dpp = 4,
- .max_num_wb = 2,
- .max_dchub_pscl_bw_pix_per_clk = 4,
- .max_pscl_lb_bw_pix_per_clk = 2,
- .max_lb_vscl_bw_pix_per_clk = 4,
- .max_vscl_hscl_bw_pix_per_clk = 4,
- .max_hscl_ratio = 4,
- .max_vscl_ratio = 4,
- .hscl_mults = 4,
- .vscl_mults = 4,
- .max_hscl_taps = 8,
- .max_vscl_taps = 8,
- .dispclk_ramp_margin_percent = 1,
- .underscan_factor = 1.10,
- .min_vblank_lines = 14,
- .dppclk_delay_subtotal = 90,
- .dispclk_delay_subtotal = 42,
- .dcfclk_cstate_latency = 10,
- .max_inter_dcn_tile_repeaters = 8,
- .can_vstartup_lines_exceed_vsync_plus_back_porch_lines_minus_one = 0,
- .bug_forcing_LC_req_same_size_fixed = 0,
-};
-
-const struct _vcs_dpi_soc_bounding_box_st dcn1_0_soc = {
- .sr_exit_time_us = 9.0,
- .sr_enter_plus_exit_time_us = 11.0,
- .urgent_latency_us = 4.0,
- .writeback_latency_us = 12.0,
- .ideal_dram_bw_after_urgent_percent = 80.0,
- .max_request_size_bytes = 256,
- .downspread_percent = 0.5,
- .dram_page_open_time_ns = 50.0,
- .dram_rw_turnaround_time_ns = 17.5,
- .dram_return_buffer_per_channel_bytes = 8192,
- .round_trip_ping_latency_dcfclk_cycles = 128,
- .urgent_out_of_order_return_per_channel_bytes = 256,
- .channel_interleave_bytes = 256,
- .num_banks = 8,
- .num_chans = 2,
- .vmm_page_size_bytes = 4096,
- .dram_clock_change_latency_us = 17.0,
- .writeback_dram_clock_change_latency_us = 23.0,
- .return_bus_width_bytes = 64,
-};
-
#ifndef mmDP0_DP_DPHY_INTERNAL_CTRL
#define mmDP0_DP_DPHY_INTERNAL_CTRL 0x210f
#define mmDP0_DP_DPHY_INTERNAL_CTRL_BASE_IDX 2
@@ -925,6 +863,21 @@ static struct dce_hwseq *dcn10_hwseq_create(
hws->wa.DEGVIDCN10_253 = true;
hws->wa.false_optc_underflow = true;
hws->wa.DEGVIDCN10_254 = true;
+
+ if ((ctx->asic_id.chip_family == FAMILY_RV) &&
+ ASICREV_IS_RAVEN2(ctx->asic_id.hw_internal_rev))
+ switch (ctx->asic_id.pci_revision_id) {
+ case PRID_POLLOCK_94:
+ case PRID_POLLOCK_95:
+ case PRID_POLLOCK_E9:
+ case PRID_POLLOCK_EA:
+ case PRID_POLLOCK_EB:
+ hws->wa.wait_hubpret_read_start_during_mpo_transition = true;
+ break;
+ default:
+ hws->wa.wait_hubpret_read_start_during_mpo_transition = false;
+ break;
+ }
}
return hws;
}
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.h b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.h
index 633025ccb870..bf8e33cd8147 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.h
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.h
@@ -27,6 +27,7 @@
#define __DC_RESOURCE_DCN10_H__
#include "core_types.h"
+#include "dml/dcn10/dcn10_fpu.h"
#define TO_DCN10_RES_POOL(pool)\
container_of(pool, struct dcn10_resource_pool, base)
@@ -35,6 +36,9 @@ struct dc;
struct resource_pool;
struct _vcs_dpi_display_pipe_params_st;
+extern struct _vcs_dpi_ip_params_st dcn1_0_ip;
+extern struct _vcs_dpi_soc_bounding_box_st dcn1_0_soc;
+
struct dcn10_resource_pool {
struct resource_pool base;
};
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_stream_encoder.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_stream_encoder.c
index bf4436d7aaab..b0c08ee6bc2c 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_stream_encoder.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_stream_encoder.c
@@ -902,19 +902,6 @@ void enc1_stream_encoder_stop_dp_info_packets(
}
-void enc1_stream_encoder_reset_fifo(
- struct stream_encoder *enc)
-{
- struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc);
-
- /* set DIG_START to 0x1 to reset FIFO */
- REG_UPDATE(DIG_FE_CNTL, DIG_START, 1);
- udelay(100);
-
- /* write 0 to take the FIFO out of reset */
- REG_UPDATE(DIG_FE_CNTL, DIG_START, 0);
-}
-
void enc1_stream_encoder_dp_blank(
struct dc_link *link,
struct stream_encoder *enc)
@@ -1600,8 +1587,6 @@ static const struct stream_encoder_funcs dcn10_str_enc_funcs = {
enc1_stream_encoder_send_immediate_sdp_message,
.stop_dp_info_packets =
enc1_stream_encoder_stop_dp_info_packets,
- .reset_fifo =
- enc1_stream_encoder_reset_fifo,
.dp_blank =
enc1_stream_encoder_dp_blank,
.dp_unblank =
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_stream_encoder.h b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_stream_encoder.h
index a146a41f68e9..687d7e4bf7ca 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_stream_encoder.h
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_stream_encoder.h
@@ -626,9 +626,6 @@ void enc1_stream_encoder_send_immediate_sdp_message(
void enc1_stream_encoder_stop_dp_info_packets(
struct stream_encoder *enc);
-void enc1_stream_encoder_reset_fifo(
- struct stream_encoder *enc);
-
void enc1_stream_encoder_dp_blank(
struct dc_link *link,
struct stream_encoder *enc);
diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/Makefile b/drivers/gpu/drm/amd/display/dc/dcn20/Makefile
index 5fcaf78334ff..abaed2121feb 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn20/Makefile
+++ b/drivers/gpu/drm/amd/display/dc/dcn20/Makefile
@@ -9,31 +9,6 @@ DCN20 = dcn20_resource.o dcn20_init.o dcn20_hwseq.o dcn20_dpp.o dcn20_dpp_cm.o d
DCN20 += dcn20_dsc.o
-ifdef CONFIG_X86
-CFLAGS_$(AMDDALPATH)/dc/dcn20/dcn20_resource.o := -mhard-float -msse
-endif
-
-ifdef CONFIG_PPC64
-CFLAGS_$(AMDDALPATH)/dc/dcn20/dcn20_resource.o := -mhard-float -maltivec
-endif
-
-ifdef CONFIG_CC_IS_GCC
-ifeq ($(call cc-ifversion, -lt, 0701, y), y)
-IS_OLD_GCC = 1
-endif
-endif
-
-ifdef CONFIG_X86
-ifdef IS_OLD_GCC
-# Stack alignment mismatch, proceed with caution.
-# GCC < 7.1 cannot compile code using `double` and -mpreferred-stack-boundary=3
-# (8B stack alignment).
-CFLAGS_$(AMDDALPATH)/dc/dcn20/dcn20_resource.o += -mpreferred-stack-boundary=4
-else
-CFLAGS_$(AMDDALPATH)/dc/dcn20/dcn20_resource.o += -msse2
-endif
-endif
-
AMD_DAL_DCN20 = $(addprefix $(AMDDALPATH)/dc/dcn20/,$(DCN20))
AMD_DISPLAY_FILES += $(AMD_DAL_DCN20)
diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dccg.h b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dccg.h
index f98aba308028..b3c9a9724efd 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dccg.h
+++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dccg.h
@@ -183,15 +183,25 @@
type SYMCLK32_ROOT_SE1_GATE_DISABLE;\
type SYMCLK32_ROOT_SE2_GATE_DISABLE;\
type SYMCLK32_ROOT_SE3_GATE_DISABLE;\
+ type SYMCLK32_SE0_GATE_DISABLE;\
+ type SYMCLK32_SE1_GATE_DISABLE;\
+ type SYMCLK32_SE2_GATE_DISABLE;\
+ type SYMCLK32_SE3_GATE_DISABLE;\
type SYMCLK32_ROOT_LE0_GATE_DISABLE;\
type SYMCLK32_ROOT_LE1_GATE_DISABLE;\
+ type SYMCLK32_LE0_GATE_DISABLE;\
+ type SYMCLK32_LE1_GATE_DISABLE;\
type DPSTREAMCLK_ROOT_GATE_DISABLE;\
type DPSTREAMCLK_GATE_DISABLE;\
type HDMISTREAMCLK0_DTO_PHASE;\
type HDMISTREAMCLK0_DTO_MODULO;\
type HDMICHARCLK0_GATE_DISABLE;\
- type HDMICHARCLK0_ROOT_GATE_DISABLE;
-
+ type HDMICHARCLK0_ROOT_GATE_DISABLE; \
+ type PHYASYMCLK_GATE_DISABLE; \
+ type PHYBSYMCLK_GATE_DISABLE; \
+ type PHYCSYMCLK_GATE_DISABLE; \
+ type PHYDSYMCLK_GATE_DISABLE; \
+ type PHYESYMCLK_GATE_DISABLE;
struct dccg_shift {
DCCG_REG_FIELD_LIST(uint8_t)
@@ -233,6 +243,7 @@ struct dccg_registers {
uint32_t DSCCLK2_DTO_PARAM;
uint32_t DPSTREAMCLK_ROOT_GATE_DISABLE;
uint32_t DPSTREAMCLK_GATE_DISABLE;
+ uint32_t DCCG_GATE_DISABLE_CNTL2;
uint32_t DCCG_GATE_DISABLE_CNTL3;
uint32_t HDMISTREAMCLK0_DTO_PARAM;
uint32_t DCCG_GATE_DISABLE_CNTL4;
diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hubp.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hubp.c
index dc1752e9f461..a665af19f201 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hubp.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hubp.c
@@ -707,17 +707,6 @@ bool hubp2_program_surface_flip_and_addr(
REG_UPDATE(VMID_SETTINGS_0,
VMID, address->vmid);
- if (address->type == PLN_ADDR_TYPE_GRPH_STEREO) {
- REG_UPDATE(DCSURF_FLIP_CONTROL, SURFACE_FLIP_MODE_FOR_STEREOSYNC, 0x1);
- REG_UPDATE(DCSURF_FLIP_CONTROL, SURFACE_FLIP_IN_STEREOSYNC, 0x1);
-
- } else {
- // turn off stereo if not in stereo
- REG_UPDATE(DCSURF_FLIP_CONTROL, SURFACE_FLIP_MODE_FOR_STEREOSYNC, 0x0);
- REG_UPDATE(DCSURF_FLIP_CONTROL, SURFACE_FLIP_IN_STEREOSYNC, 0x0);
- }
-
-
/* HW automatically latch rest of address register on write to
* DCSURF_PRIMARY_SURFACE_ADDRESS if SURFACE_UPDATE_LOCK is not used
@@ -942,10 +931,6 @@ void hubp2_set_blank_regs(struct hubp *hubp, bool blank)
struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp);
uint32_t blank_en = blank ? 1 : 0;
- REG_UPDATE_2(DCHUBP_CNTL,
- HUBP_BLANK_EN, blank_en,
- HUBP_TTU_DISABLE, blank_en);
-
if (blank) {
uint32_t reg_val = REG_READ(DCHUBP_CNTL);
@@ -958,9 +943,13 @@ void hubp2_set_blank_regs(struct hubp *hubp, bool blank)
*/
REG_WAIT(DCHUBP_CNTL,
HUBP_NO_OUTSTANDING_REQ, 1,
- 1, 200);
+ 1, 100000);
}
}
+
+ REG_UPDATE_2(DCHUBP_CNTL,
+ HUBP_BLANK_EN, blank_en,
+ HUBP_TTU_DISABLE, 0);
}
void hubp2_cursor_set_position(
diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
index 4991e93e5308..ab910deed481 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
@@ -55,6 +55,7 @@
#include "inc/link_dpcd.h"
#include "dpcd_defs.h"
#include "inc/link_enc_cfg.h"
+#include "link_hwss.h"
#define DC_LOGGER_INIT(logger)
@@ -1738,6 +1739,16 @@ void dcn20_program_front_end_for_ctx(
|| pipe->stream->update_flags.raw)
&& hws->funcs.program_all_writeback_pipes_in_tree)
hws->funcs.program_all_writeback_pipes_in_tree(dc, pipe->stream, context);
+
+ /* Avoid underflow by check of pipe line read when adding 2nd plane. */
+ if (hws->wa.wait_hubpret_read_start_during_mpo_transition &&
+ !pipe->top_pipe &&
+ pipe->stream &&
+ pipe->plane_res.hubp->funcs->hubp_wait_pipe_read_start &&
+ dc->current_state->stream_status[0].plane_count == 1 &&
+ context->stream_status[0].plane_count > 1) {
+ pipe->plane_res.hubp->funcs->hubp_wait_pipe_read_start(pipe->plane_res.hubp);
+ }
}
}
@@ -1817,6 +1828,7 @@ void dcn20_prepare_bandwidth(
struct dc_state *context)
{
struct hubbub *hubbub = dc->res_pool->hubbub;
+ unsigned int compbuf_size_kb = 0;
dc->clk_mgr->funcs->update_clocks(
dc->clk_mgr,
@@ -1828,9 +1840,16 @@ void dcn20_prepare_bandwidth(
&context->bw_ctx.bw.dcn.watermarks,
dc->res_pool->ref_clocks.dchub_ref_clock_inKhz / 1000,
false);
+
/* decrease compbuf size */
- if (hubbub->funcs->program_compbuf_size)
- hubbub->funcs->program_compbuf_size(hubbub, context->bw_ctx.bw.dcn.compbuf_size_kb, false);
+ if (hubbub->funcs->program_compbuf_size) {
+ if (context->bw_ctx.dml.ip.min_comp_buffer_size_kbytes)
+ compbuf_size_kb = context->bw_ctx.dml.ip.min_comp_buffer_size_kbytes;
+ else
+ compbuf_size_kb = context->bw_ctx.bw.dcn.compbuf_size_kb;
+
+ hubbub->funcs->program_compbuf_size(hubbub, compbuf_size_kb, false);
+ }
}
void dcn20_optimize_bandwidth(
@@ -2390,46 +2409,22 @@ void dcn20_enable_stream(struct pipe_ctx *pipe_ctx)
uint32_t active_total_with_borders;
uint32_t early_control = 0;
struct timing_generator *tg = pipe_ctx->stream_res.tg;
- struct link_encoder *link_enc;
+ const struct link_hwss *link_hwss = get_link_hwss(link, &pipe_ctx->link_res);
+ struct dc *dc = pipe_ctx->stream->ctx->dc;
- if (link->is_dig_mapping_flexible &&
- link->dc->res_pool->funcs->link_encs_assign)
- link_enc = link_enc_cfg_get_link_enc_used_by_stream(link->ctx->dc, pipe_ctx->stream);
- else
- link_enc = link->link_enc;
- ASSERT(link_enc);
-
- /* For MST, there are multiply stream go to only one link.
- * connect DIG back_end to front_end while enable_stream and
- * disconnect them during disable_stream
- * BY this, it is logic clean to separate stream and link
- */
if (is_dp_128b_132b_signal(pipe_ctx)) {
- if (pipe_ctx->stream->ctx->dc->hwseq->funcs.setup_hpo_hw_control)
- pipe_ctx->stream->ctx->dc->hwseq->funcs.setup_hpo_hw_control(
- pipe_ctx->stream->ctx->dc->hwseq, true);
- setup_dp_hpo_stream(pipe_ctx, true);
- pipe_ctx->stream_res.hpo_dp_stream_enc->funcs->enable_stream(
- pipe_ctx->stream_res.hpo_dp_stream_enc);
- pipe_ctx->stream_res.hpo_dp_stream_enc->funcs->map_stream_to_link(
- pipe_ctx->stream_res.hpo_dp_stream_enc,
- pipe_ctx->stream_res.hpo_dp_stream_enc->inst,
- pipe_ctx->link_res.hpo_dp_link_enc->inst);
+ if (dc->hwseq->funcs.setup_hpo_hw_control)
+ dc->hwseq->funcs.setup_hpo_hw_control(dc->hwseq, true);
}
- if (!is_dp_128b_132b_signal(pipe_ctx) && link_enc)
- link_enc->funcs->connect_dig_be_to_fe(
- link_enc, pipe_ctx->stream_res.stream_enc->id, true);
-
- if (dc_is_dp_signal(pipe_ctx->stream->signal))
- dp_source_sequence_trace(link, DPCD_SOURCE_SEQ_AFTER_CONNECT_DIG_FE_BE);
+ link_hwss->setup_stream_encoder(pipe_ctx);
if (pipe_ctx->plane_state && pipe_ctx->plane_state->flip_immediate != 1) {
- if (link->dc->hwss.program_dmdata_engine)
- link->dc->hwss.program_dmdata_engine(pipe_ctx);
+ if (dc->hwss.program_dmdata_engine)
+ dc->hwss.program_dmdata_engine(pipe_ctx);
}
- link->dc->hwss.update_info_frame(pipe_ctx);
+ dc->hwss.update_info_frame(pipe_ctx);
if (dc_is_dp_signal(pipe_ctx->stream->signal))
dp_source_sequence_trace(link, DPCD_SOURCE_SEQ_AFTER_UPDATE_INFO_FRAME);
diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c
index 2bc93df023ad..d473708d5399 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c
@@ -63,7 +63,6 @@
#include "dcn20_dccg.h"
#include "dcn20_vmid.h"
#include "dc_link_ddc.h"
-#include "dc_link_dp.h"
#include "dce/dce_panel_cntl.h"
#include "navi10_ip_offset.h"
@@ -93,367 +92,6 @@
#define DC_LOGGER_INIT(logger)
-struct _vcs_dpi_ip_params_st dcn2_0_ip = {
- .odm_capable = 1,
- .gpuvm_enable = 0,
- .hostvm_enable = 0,
- .gpuvm_max_page_table_levels = 4,
- .hostvm_max_page_table_levels = 4,
- .hostvm_cached_page_table_levels = 0,
- .pte_group_size_bytes = 2048,
- .num_dsc = 6,
- .rob_buffer_size_kbytes = 168,
- .det_buffer_size_kbytes = 164,
- .dpte_buffer_size_in_pte_reqs_luma = 84,
- .pde_proc_buffer_size_64k_reqs = 48,
- .dpp_output_buffer_pixels = 2560,
- .opp_output_buffer_lines = 1,
- .pixel_chunk_size_kbytes = 8,
- .pte_chunk_size_kbytes = 2,
- .meta_chunk_size_kbytes = 2,
- .writeback_chunk_size_kbytes = 2,
- .line_buffer_size_bits = 789504,
- .is_line_buffer_bpp_fixed = 0,
- .line_buffer_fixed_bpp = 0,
- .dcc_supported = true,
- .max_line_buffer_lines = 12,
- .writeback_luma_buffer_size_kbytes = 12,
- .writeback_chroma_buffer_size_kbytes = 8,
- .writeback_chroma_line_buffer_width_pixels = 4,
- .writeback_max_hscl_ratio = 1,
- .writeback_max_vscl_ratio = 1,
- .writeback_min_hscl_ratio = 1,
- .writeback_min_vscl_ratio = 1,
- .writeback_max_hscl_taps = 12,
- .writeback_max_vscl_taps = 12,
- .writeback_line_buffer_luma_buffer_size = 0,
- .writeback_line_buffer_chroma_buffer_size = 14643,
- .cursor_buffer_size = 8,
- .cursor_chunk_size = 2,
- .max_num_otg = 6,
- .max_num_dpp = 6,
- .max_num_wb = 1,
- .max_dchub_pscl_bw_pix_per_clk = 4,
- .max_pscl_lb_bw_pix_per_clk = 2,
- .max_lb_vscl_bw_pix_per_clk = 4,
- .max_vscl_hscl_bw_pix_per_clk = 4,
- .max_hscl_ratio = 8,
- .max_vscl_ratio = 8,
- .hscl_mults = 4,
- .vscl_mults = 4,
- .max_hscl_taps = 8,
- .max_vscl_taps = 8,
- .dispclk_ramp_margin_percent = 1,
- .underscan_factor = 1.10,
- .min_vblank_lines = 32, //
- .dppclk_delay_subtotal = 77, //
- .dppclk_delay_scl_lb_only = 16,
- .dppclk_delay_scl = 50,
- .dppclk_delay_cnvc_formatter = 8,
- .dppclk_delay_cnvc_cursor = 6,
- .dispclk_delay_subtotal = 87, //
- .dcfclk_cstate_latency = 10, // SRExitTime
- .max_inter_dcn_tile_repeaters = 8,
- .xfc_supported = true,
- .xfc_fill_bw_overhead_percent = 10.0,
- .xfc_fill_constant_bytes = 0,
- .number_of_cursors = 1,
-};
-
-static struct _vcs_dpi_ip_params_st dcn2_0_nv14_ip = {
- .odm_capable = 1,
- .gpuvm_enable = 0,
- .hostvm_enable = 0,
- .gpuvm_max_page_table_levels = 4,
- .hostvm_max_page_table_levels = 4,
- .hostvm_cached_page_table_levels = 0,
- .num_dsc = 5,
- .rob_buffer_size_kbytes = 168,
- .det_buffer_size_kbytes = 164,
- .dpte_buffer_size_in_pte_reqs_luma = 84,
- .dpte_buffer_size_in_pte_reqs_chroma = 42,//todo
- .dpp_output_buffer_pixels = 2560,
- .opp_output_buffer_lines = 1,
- .pixel_chunk_size_kbytes = 8,
- .pte_enable = 1,
- .max_page_table_levels = 4,
- .pte_chunk_size_kbytes = 2,
- .meta_chunk_size_kbytes = 2,
- .writeback_chunk_size_kbytes = 2,
- .line_buffer_size_bits = 789504,
- .is_line_buffer_bpp_fixed = 0,
- .line_buffer_fixed_bpp = 0,
- .dcc_supported = true,
- .max_line_buffer_lines = 12,
- .writeback_luma_buffer_size_kbytes = 12,
- .writeback_chroma_buffer_size_kbytes = 8,
- .writeback_chroma_line_buffer_width_pixels = 4,
- .writeback_max_hscl_ratio = 1,
- .writeback_max_vscl_ratio = 1,
- .writeback_min_hscl_ratio = 1,
- .writeback_min_vscl_ratio = 1,
- .writeback_max_hscl_taps = 12,
- .writeback_max_vscl_taps = 12,
- .writeback_line_buffer_luma_buffer_size = 0,
- .writeback_line_buffer_chroma_buffer_size = 14643,
- .cursor_buffer_size = 8,
- .cursor_chunk_size = 2,
- .max_num_otg = 5,
- .max_num_dpp = 5,
- .max_num_wb = 1,
- .max_dchub_pscl_bw_pix_per_clk = 4,
- .max_pscl_lb_bw_pix_per_clk = 2,
- .max_lb_vscl_bw_pix_per_clk = 4,
- .max_vscl_hscl_bw_pix_per_clk = 4,
- .max_hscl_ratio = 8,
- .max_vscl_ratio = 8,
- .hscl_mults = 4,
- .vscl_mults = 4,
- .max_hscl_taps = 8,
- .max_vscl_taps = 8,
- .dispclk_ramp_margin_percent = 1,
- .underscan_factor = 1.10,
- .min_vblank_lines = 32, //
- .dppclk_delay_subtotal = 77, //
- .dppclk_delay_scl_lb_only = 16,
- .dppclk_delay_scl = 50,
- .dppclk_delay_cnvc_formatter = 8,
- .dppclk_delay_cnvc_cursor = 6,
- .dispclk_delay_subtotal = 87, //
- .dcfclk_cstate_latency = 10, // SRExitTime
- .max_inter_dcn_tile_repeaters = 8,
- .xfc_supported = true,
- .xfc_fill_bw_overhead_percent = 10.0,
- .xfc_fill_constant_bytes = 0,
- .ptoi_supported = 0,
- .number_of_cursors = 1,
-};
-
-static struct _vcs_dpi_soc_bounding_box_st dcn2_0_soc = {
- /* Defaults that get patched on driver load from firmware. */
- .clock_limits = {
- {
- .state = 0,
- .dcfclk_mhz = 560.0,
- .fabricclk_mhz = 560.0,
- .dispclk_mhz = 513.0,
- .dppclk_mhz = 513.0,
- .phyclk_mhz = 540.0,
- .socclk_mhz = 560.0,
- .dscclk_mhz = 171.0,
- .dram_speed_mts = 8960.0,
- },
- {
- .state = 1,
- .dcfclk_mhz = 694.0,
- .fabricclk_mhz = 694.0,
- .dispclk_mhz = 642.0,
- .dppclk_mhz = 642.0,
- .phyclk_mhz = 600.0,
- .socclk_mhz = 694.0,
- .dscclk_mhz = 214.0,
- .dram_speed_mts = 11104.0,
- },
- {
- .state = 2,
- .dcfclk_mhz = 875.0,
- .fabricclk_mhz = 875.0,
- .dispclk_mhz = 734.0,
- .dppclk_mhz = 734.0,
- .phyclk_mhz = 810.0,
- .socclk_mhz = 875.0,
- .dscclk_mhz = 245.0,
- .dram_speed_mts = 14000.0,
- },
- {
- .state = 3,
- .dcfclk_mhz = 1000.0,
- .fabricclk_mhz = 1000.0,
- .dispclk_mhz = 1100.0,
- .dppclk_mhz = 1100.0,
- .phyclk_mhz = 810.0,
- .socclk_mhz = 1000.0,
- .dscclk_mhz = 367.0,
- .dram_speed_mts = 16000.0,
- },
- {
- .state = 4,
- .dcfclk_mhz = 1200.0,
- .fabricclk_mhz = 1200.0,
- .dispclk_mhz = 1284.0,
- .dppclk_mhz = 1284.0,
- .phyclk_mhz = 810.0,
- .socclk_mhz = 1200.0,
- .dscclk_mhz = 428.0,
- .dram_speed_mts = 16000.0,
- },
- /*Extra state, no dispclk ramping*/
- {
- .state = 5,
- .dcfclk_mhz = 1200.0,
- .fabricclk_mhz = 1200.0,
- .dispclk_mhz = 1284.0,
- .dppclk_mhz = 1284.0,
- .phyclk_mhz = 810.0,
- .socclk_mhz = 1200.0,
- .dscclk_mhz = 428.0,
- .dram_speed_mts = 16000.0,
- },
- },
- .num_states = 5,
- .sr_exit_time_us = 8.6,
- .sr_enter_plus_exit_time_us = 10.9,
- .urgent_latency_us = 4.0,
- .urgent_latency_pixel_data_only_us = 4.0,
- .urgent_latency_pixel_mixed_with_vm_data_us = 4.0,
- .urgent_latency_vm_data_only_us = 4.0,
- .urgent_out_of_order_return_per_channel_pixel_only_bytes = 4096,
- .urgent_out_of_order_return_per_channel_pixel_and_vm_bytes = 4096,
- .urgent_out_of_order_return_per_channel_vm_only_bytes = 4096,
- .pct_ideal_dram_sdp_bw_after_urgent_pixel_only = 40.0,
- .pct_ideal_dram_sdp_bw_after_urgent_pixel_and_vm = 40.0,
- .pct_ideal_dram_sdp_bw_after_urgent_vm_only = 40.0,
- .max_avg_sdp_bw_use_normal_percent = 40.0,
- .max_avg_dram_bw_use_normal_percent = 40.0,
- .writeback_latency_us = 12.0,
- .ideal_dram_bw_after_urgent_percent = 40.0,
- .max_request_size_bytes = 256,
- .dram_channel_width_bytes = 2,
- .fabric_datapath_to_dcn_data_return_bytes = 64,
- .dcn_downspread_percent = 0.5,
- .downspread_percent = 0.38,
- .dram_page_open_time_ns = 50.0,
- .dram_rw_turnaround_time_ns = 17.5,
- .dram_return_buffer_per_channel_bytes = 8192,
- .round_trip_ping_latency_dcfclk_cycles = 131,
- .urgent_out_of_order_return_per_channel_bytes = 256,
- .channel_interleave_bytes = 256,
- .num_banks = 8,
- .num_chans = 16,
- .vmm_page_size_bytes = 4096,
- .dram_clock_change_latency_us = 404.0,
- .dummy_pstate_latency_us = 5.0,
- .writeback_dram_clock_change_latency_us = 23.0,
- .return_bus_width_bytes = 64,
- .dispclk_dppclk_vco_speed_mhz = 3850,
- .xfc_bus_transport_time_us = 20,
- .xfc_xbuf_latency_tolerance_us = 4,
- .use_urgent_burst_bw = 0
-};
-
-static struct _vcs_dpi_soc_bounding_box_st dcn2_0_nv14_soc = {
- .clock_limits = {
- {
- .state = 0,
- .dcfclk_mhz = 560.0,
- .fabricclk_mhz = 560.0,
- .dispclk_mhz = 513.0,
- .dppclk_mhz = 513.0,
- .phyclk_mhz = 540.0,
- .socclk_mhz = 560.0,
- .dscclk_mhz = 171.0,
- .dram_speed_mts = 8960.0,
- },
- {
- .state = 1,
- .dcfclk_mhz = 694.0,
- .fabricclk_mhz = 694.0,
- .dispclk_mhz = 642.0,
- .dppclk_mhz = 642.0,
- .phyclk_mhz = 600.0,
- .socclk_mhz = 694.0,
- .dscclk_mhz = 214.0,
- .dram_speed_mts = 11104.0,
- },
- {
- .state = 2,
- .dcfclk_mhz = 875.0,
- .fabricclk_mhz = 875.0,
- .dispclk_mhz = 734.0,
- .dppclk_mhz = 734.0,
- .phyclk_mhz = 810.0,
- .socclk_mhz = 875.0,
- .dscclk_mhz = 245.0,
- .dram_speed_mts = 14000.0,
- },
- {
- .state = 3,
- .dcfclk_mhz = 1000.0,
- .fabricclk_mhz = 1000.0,
- .dispclk_mhz = 1100.0,
- .dppclk_mhz = 1100.0,
- .phyclk_mhz = 810.0,
- .socclk_mhz = 1000.0,
- .dscclk_mhz = 367.0,
- .dram_speed_mts = 16000.0,
- },
- {
- .state = 4,
- .dcfclk_mhz = 1200.0,
- .fabricclk_mhz = 1200.0,
- .dispclk_mhz = 1284.0,
- .dppclk_mhz = 1284.0,
- .phyclk_mhz = 810.0,
- .socclk_mhz = 1200.0,
- .dscclk_mhz = 428.0,
- .dram_speed_mts = 16000.0,
- },
- /*Extra state, no dispclk ramping*/
- {
- .state = 5,
- .dcfclk_mhz = 1200.0,
- .fabricclk_mhz = 1200.0,
- .dispclk_mhz = 1284.0,
- .dppclk_mhz = 1284.0,
- .phyclk_mhz = 810.0,
- .socclk_mhz = 1200.0,
- .dscclk_mhz = 428.0,
- .dram_speed_mts = 16000.0,
- },
- },
- .num_states = 5,
- .sr_exit_time_us = 11.6,
- .sr_enter_plus_exit_time_us = 13.9,
- .urgent_latency_us = 4.0,
- .urgent_latency_pixel_data_only_us = 4.0,
- .urgent_latency_pixel_mixed_with_vm_data_us = 4.0,
- .urgent_latency_vm_data_only_us = 4.0,
- .urgent_out_of_order_return_per_channel_pixel_only_bytes = 4096,
- .urgent_out_of_order_return_per_channel_pixel_and_vm_bytes = 4096,
- .urgent_out_of_order_return_per_channel_vm_only_bytes = 4096,
- .pct_ideal_dram_sdp_bw_after_urgent_pixel_only = 40.0,
- .pct_ideal_dram_sdp_bw_after_urgent_pixel_and_vm = 40.0,
- .pct_ideal_dram_sdp_bw_after_urgent_vm_only = 40.0,
- .max_avg_sdp_bw_use_normal_percent = 40.0,
- .max_avg_dram_bw_use_normal_percent = 40.0,
- .writeback_latency_us = 12.0,
- .ideal_dram_bw_after_urgent_percent = 40.0,
- .max_request_size_bytes = 256,
- .dram_channel_width_bytes = 2,
- .fabric_datapath_to_dcn_data_return_bytes = 64,
- .dcn_downspread_percent = 0.5,
- .downspread_percent = 0.38,
- .dram_page_open_time_ns = 50.0,
- .dram_rw_turnaround_time_ns = 17.5,
- .dram_return_buffer_per_channel_bytes = 8192,
- .round_trip_ping_latency_dcfclk_cycles = 131,
- .urgent_out_of_order_return_per_channel_bytes = 256,
- .channel_interleave_bytes = 256,
- .num_banks = 8,
- .num_chans = 8,
- .vmm_page_size_bytes = 4096,
- .dram_clock_change_latency_us = 404.0,
- .dummy_pstate_latency_us = 5.0,
- .writeback_dram_clock_change_latency_us = 23.0,
- .return_bus_width_bytes = 64,
- .dispclk_dppclk_vco_speed_mhz = 3850,
- .xfc_bus_transport_time_us = 20,
- .xfc_xbuf_latency_tolerance_us = 4,
- .use_urgent_burst_bw = 0
-};
-
-static struct _vcs_dpi_soc_bounding_box_st dcn2_0_nv12_soc = { 0 };
-
#ifndef mmDP0_DP_DPHY_INTERNAL_CTRL
#define mmDP0_DP_DPHY_INTERNAL_CTRL 0x210f
#define mmDP0_DP_DPHY_INTERNAL_CTRL_BASE_IDX 2
@@ -1069,7 +707,7 @@ static const struct dc_debug_options debug_defaults_drv = {
.timing_trace = false,
.clock_trace = true,
.disable_pplib_clock_request = true,
- .pipe_split_policy = MPC_SPLIT_DYNAMIC,
+ .pipe_split_policy = MPC_SPLIT_AVOID_MULT_DISP,
.force_single_disp_pipe_split = false,
.disable_dcc = DCC_ENABLE,
.vsr_support = true,
@@ -1605,16 +1243,7 @@ static void get_pixel_clock_parameters(
pixel_clk_params->requested_pix_clk_100hz = stream->timing.pix_clk_100hz;
- /* Links supporting dynamically assigned link encoder will be assigned next
- * available encoder if one not already assigned.
- */
- if (link->is_dig_mapping_flexible &&
- link->dc->res_pool->funcs->link_encs_assign) {
- link_enc = link_enc_cfg_get_link_enc_used_by_stream(stream->ctx->dc, stream);
- if (link_enc == NULL)
- link_enc = link_enc_cfg_get_next_avail_link_enc(stream->ctx->dc);
- } else
- link_enc = stream->link->link_enc;
+ link_enc = link_enc_cfg_get_link_enc(link);
ASSERT(link_enc);
if (link_enc)
@@ -1819,69 +1448,6 @@ enum dc_status dcn20_remove_stream_from_ctx(struct dc *dc, struct dc_state *new_
return result;
}
-
-static void swizzle_to_dml_params(
- enum swizzle_mode_values swizzle,
- unsigned int *sw_mode)
-{
- switch (swizzle) {
- case DC_SW_LINEAR:
- *sw_mode = dm_sw_linear;
- break;
- case DC_SW_4KB_S:
- *sw_mode = dm_sw_4kb_s;
- break;
- case DC_SW_4KB_S_X:
- *sw_mode = dm_sw_4kb_s_x;
- break;
- case DC_SW_4KB_D:
- *sw_mode = dm_sw_4kb_d;
- break;
- case DC_SW_4KB_D_X:
- *sw_mode = dm_sw_4kb_d_x;
- break;
- case DC_SW_64KB_S:
- *sw_mode = dm_sw_64kb_s;
- break;
- case DC_SW_64KB_S_X:
- *sw_mode = dm_sw_64kb_s_x;
- break;
- case DC_SW_64KB_S_T:
- *sw_mode = dm_sw_64kb_s_t;
- break;
- case DC_SW_64KB_D:
- *sw_mode = dm_sw_64kb_d;
- break;
- case DC_SW_64KB_D_X:
- *sw_mode = dm_sw_64kb_d_x;
- break;
- case DC_SW_64KB_D_T:
- *sw_mode = dm_sw_64kb_d_t;
- break;
- case DC_SW_64KB_R_X:
- *sw_mode = dm_sw_64kb_r_x;
- break;
- case DC_SW_VAR_S:
- *sw_mode = dm_sw_var_s;
- break;
- case DC_SW_VAR_S_X:
- *sw_mode = dm_sw_var_s_x;
- break;
- case DC_SW_VAR_D:
- *sw_mode = dm_sw_var_d;
- break;
- case DC_SW_VAR_D_X:
- *sw_mode = dm_sw_var_d_x;
- break;
- case DC_SW_VAR_R_X:
- *sw_mode = dm_sw_var_r_x;
- break;
- default:
- ASSERT(0); /* Not supported */
- break;
- }
-}
-
bool dcn20_split_stream_for_odm(
const struct dc *dc,
struct resource_context *res_ctx,
@@ -1997,394 +1563,6 @@ void dcn20_split_stream_for_mpc(
ASSERT(primary_pipe->plane_state);
}
-int dcn20_populate_dml_pipes_from_context(
- struct dc *dc,
- struct dc_state *context,
- display_e2e_pipe_params_st *pipes,
- bool fast_validate)
-{
- int pipe_cnt, i;
- bool synchronized_vblank = true;
- struct resource_context *res_ctx = &context->res_ctx;
-
- for (i = 0, pipe_cnt = -1; i < dc->res_pool->pipe_count; i++) {
- if (!res_ctx->pipe_ctx[i].stream)
- continue;
-
- if (pipe_cnt < 0) {
- pipe_cnt = i;
- continue;
- }
-
- if (res_ctx->pipe_ctx[pipe_cnt].stream == res_ctx->pipe_ctx[i].stream)
- continue;
-
- if (dc->debug.disable_timing_sync ||
- (!resource_are_streams_timing_synchronizable(
- res_ctx->pipe_ctx[pipe_cnt].stream,
- res_ctx->pipe_ctx[i].stream) &&
- !resource_are_vblanks_synchronizable(
- res_ctx->pipe_ctx[pipe_cnt].stream,
- res_ctx->pipe_ctx[i].stream))) {
- synchronized_vblank = false;
- break;
- }
- }
-
- for (i = 0, pipe_cnt = 0; i < dc->res_pool->pipe_count; i++) {
- struct dc_crtc_timing *timing = &res_ctx->pipe_ctx[i].stream->timing;
- unsigned int v_total;
- unsigned int front_porch;
- int output_bpc;
- struct audio_check aud_check = {0};
-
- if (!res_ctx->pipe_ctx[i].stream)
- continue;
-
- v_total = timing->v_total;
- front_porch = timing->v_front_porch;
-
- /* todo:
- pipes[pipe_cnt].pipe.src.dynamic_metadata_enable = 0;
- pipes[pipe_cnt].pipe.src.dcc = 0;
- pipes[pipe_cnt].pipe.src.vm = 0;*/
-
- pipes[pipe_cnt].clks_cfg.refclk_mhz = dc->res_pool->ref_clocks.dchub_ref_clock_inKhz / 1000.0;
-
- pipes[pipe_cnt].dout.dsc_enable = res_ctx->pipe_ctx[i].stream->timing.flags.DSC;
- /* todo: rotation?*/
- pipes[pipe_cnt].dout.dsc_slices = res_ctx->pipe_ctx[i].stream->timing.dsc_cfg.num_slices_h;
- if (res_ctx->pipe_ctx[i].stream->use_dynamic_meta) {
- pipes[pipe_cnt].pipe.src.dynamic_metadata_enable = true;
- /* 1/2 vblank */
- pipes[pipe_cnt].pipe.src.dynamic_metadata_lines_before_active =
- (v_total - timing->v_addressable
- - timing->v_border_top - timing->v_border_bottom) / 2;
- /* 36 bytes dp, 32 hdmi */
- pipes[pipe_cnt].pipe.src.dynamic_metadata_xmit_bytes =
- dc_is_dp_signal(res_ctx->pipe_ctx[i].stream->signal) ? 36 : 32;
- }
- pipes[pipe_cnt].pipe.src.dcc = false;
- pipes[pipe_cnt].pipe.src.dcc_rate = 1;
- pipes[pipe_cnt].pipe.dest.synchronized_vblank_all_planes = synchronized_vblank;
- pipes[pipe_cnt].pipe.dest.hblank_start = timing->h_total - timing->h_front_porch;
- pipes[pipe_cnt].pipe.dest.hblank_end = pipes[pipe_cnt].pipe.dest.hblank_start
- - timing->h_addressable
- - timing->h_border_left
- - timing->h_border_right;
- pipes[pipe_cnt].pipe.dest.vblank_start = v_total - front_porch;
- pipes[pipe_cnt].pipe.dest.vblank_end = pipes[pipe_cnt].pipe.dest.vblank_start
- - timing->v_addressable
- - timing->v_border_top
- - timing->v_border_bottom;
- pipes[pipe_cnt].pipe.dest.htotal = timing->h_total;
- pipes[pipe_cnt].pipe.dest.vtotal = v_total;
- pipes[pipe_cnt].pipe.dest.hactive =
- timing->h_addressable + timing->h_border_left + timing->h_border_right;
- pipes[pipe_cnt].pipe.dest.vactive =
- timing->v_addressable + timing->v_border_top + timing->v_border_bottom;
- pipes[pipe_cnt].pipe.dest.interlaced = timing->flags.INTERLACE;
- pipes[pipe_cnt].pipe.dest.pixel_rate_mhz = timing->pix_clk_100hz/10000.0;
- if (timing->timing_3d_format == TIMING_3D_FORMAT_HW_FRAME_PACKING)
- pipes[pipe_cnt].pipe.dest.pixel_rate_mhz *= 2;
- pipes[pipe_cnt].pipe.dest.otg_inst = res_ctx->pipe_ctx[i].stream_res.tg->inst;
- pipes[pipe_cnt].dout.dp_lanes = 4;
- pipes[pipe_cnt].dout.is_virtual = 0;
- pipes[pipe_cnt].pipe.dest.vtotal_min = res_ctx->pipe_ctx[i].stream->adjust.v_total_min;
- pipes[pipe_cnt].pipe.dest.vtotal_max = res_ctx->pipe_ctx[i].stream->adjust.v_total_max;
- switch (get_num_odm_splits(&res_ctx->pipe_ctx[i])) {
- case 1:
- pipes[pipe_cnt].pipe.dest.odm_combine = dm_odm_combine_mode_2to1;
- break;
- case 3:
- pipes[pipe_cnt].pipe.dest.odm_combine = dm_odm_combine_mode_4to1;
- break;
- default:
- pipes[pipe_cnt].pipe.dest.odm_combine = dm_odm_combine_mode_disabled;
- }
- pipes[pipe_cnt].pipe.src.hsplit_grp = res_ctx->pipe_ctx[i].pipe_idx;
- if (res_ctx->pipe_ctx[i].top_pipe && res_ctx->pipe_ctx[i].top_pipe->plane_state
- == res_ctx->pipe_ctx[i].plane_state) {
- struct pipe_ctx *first_pipe = res_ctx->pipe_ctx[i].top_pipe;
- int split_idx = 0;
-
- while (first_pipe->top_pipe && first_pipe->top_pipe->plane_state
- == res_ctx->pipe_ctx[i].plane_state) {
- first_pipe = first_pipe->top_pipe;
- split_idx++;
- }
- /* Treat 4to1 mpc combine as an mpo of 2 2-to-1 combines */
- if (split_idx == 0)
- pipes[pipe_cnt].pipe.src.hsplit_grp = first_pipe->pipe_idx;
- else if (split_idx == 1)
- pipes[pipe_cnt].pipe.src.hsplit_grp = res_ctx->pipe_ctx[i].pipe_idx;
- else if (split_idx == 2)
- pipes[pipe_cnt].pipe.src.hsplit_grp = res_ctx->pipe_ctx[i].top_pipe->pipe_idx;
- } else if (res_ctx->pipe_ctx[i].prev_odm_pipe) {
- struct pipe_ctx *first_pipe = res_ctx->pipe_ctx[i].prev_odm_pipe;
-
- while (first_pipe->prev_odm_pipe)
- first_pipe = first_pipe->prev_odm_pipe;
- pipes[pipe_cnt].pipe.src.hsplit_grp = first_pipe->pipe_idx;
- }
-
- switch (res_ctx->pipe_ctx[i].stream->signal) {
- case SIGNAL_TYPE_DISPLAY_PORT_MST:
- case SIGNAL_TYPE_DISPLAY_PORT:
- pipes[pipe_cnt].dout.output_type = dm_dp;
- break;
- case SIGNAL_TYPE_EDP:
- pipes[pipe_cnt].dout.output_type = dm_edp;
- break;
- case SIGNAL_TYPE_HDMI_TYPE_A:
- case SIGNAL_TYPE_DVI_SINGLE_LINK:
- case SIGNAL_TYPE_DVI_DUAL_LINK:
- pipes[pipe_cnt].dout.output_type = dm_hdmi;
- break;
- default:
- /* In case there is no signal, set dp with 4 lanes to allow max config */
- pipes[pipe_cnt].dout.is_virtual = 1;
- pipes[pipe_cnt].dout.output_type = dm_dp;
- pipes[pipe_cnt].dout.dp_lanes = 4;
- }
-
- switch (res_ctx->pipe_ctx[i].stream->timing.display_color_depth) {
- case COLOR_DEPTH_666:
- output_bpc = 6;
- break;
- case COLOR_DEPTH_888:
- output_bpc = 8;
- break;
- case COLOR_DEPTH_101010:
- output_bpc = 10;
- break;
- case COLOR_DEPTH_121212:
- output_bpc = 12;
- break;
- case COLOR_DEPTH_141414:
- output_bpc = 14;
- break;
- case COLOR_DEPTH_161616:
- output_bpc = 16;
- break;
- case COLOR_DEPTH_999:
- output_bpc = 9;
- break;
- case COLOR_DEPTH_111111:
- output_bpc = 11;
- break;
- default:
- output_bpc = 8;
- break;
- }
-
- switch (res_ctx->pipe_ctx[i].stream->timing.pixel_encoding) {
- case PIXEL_ENCODING_RGB:
- case PIXEL_ENCODING_YCBCR444:
- pipes[pipe_cnt].dout.output_format = dm_444;
- pipes[pipe_cnt].dout.output_bpp = output_bpc * 3;
- break;
- case PIXEL_ENCODING_YCBCR420:
- pipes[pipe_cnt].dout.output_format = dm_420;
- pipes[pipe_cnt].dout.output_bpp = (output_bpc * 3.0) / 2;
- break;
- case PIXEL_ENCODING_YCBCR422:
- if (res_ctx->pipe_ctx[i].stream->timing.flags.DSC &&
- !res_ctx->pipe_ctx[i].stream->timing.dsc_cfg.ycbcr422_simple)
- pipes[pipe_cnt].dout.output_format = dm_n422;
- else
- pipes[pipe_cnt].dout.output_format = dm_s422;
- pipes[pipe_cnt].dout.output_bpp = output_bpc * 2;
- break;
- default:
- pipes[pipe_cnt].dout.output_format = dm_444;
- pipes[pipe_cnt].dout.output_bpp = output_bpc * 3;
- }
-
- if (res_ctx->pipe_ctx[i].stream->timing.flags.DSC)
- pipes[pipe_cnt].dout.output_bpp = res_ctx->pipe_ctx[i].stream->timing.dsc_cfg.bits_per_pixel / 16.0;
-
- /* todo: default max for now, until there is logic reflecting this in dc*/
- pipes[pipe_cnt].dout.dsc_input_bpc = 12;
- /*fill up the audio sample rate (unit in kHz)*/
- get_audio_check(&res_ctx->pipe_ctx[i].stream->audio_info, &aud_check);
- pipes[pipe_cnt].dout.max_audio_sample_rate = aud_check.max_audiosample_rate / 1000;
- /*
- * For graphic plane, cursor number is 1, nv12 is 0
- * bw calculations due to cursor on/off
- */
- if (res_ctx->pipe_ctx[i].plane_state &&
- res_ctx->pipe_ctx[i].plane_state->address.type == PLN_ADDR_TYPE_VIDEO_PROGRESSIVE)
- pipes[pipe_cnt].pipe.src.num_cursors = 0;
- else
- pipes[pipe_cnt].pipe.src.num_cursors = dc->dml.ip.number_of_cursors;
-
- pipes[pipe_cnt].pipe.src.cur0_src_width = 256;
- pipes[pipe_cnt].pipe.src.cur0_bpp = dm_cur_32bit;
-
- if (!res_ctx->pipe_ctx[i].plane_state) {
- pipes[pipe_cnt].pipe.src.is_hsplit = pipes[pipe_cnt].pipe.dest.odm_combine != dm_odm_combine_mode_disabled;
- pipes[pipe_cnt].pipe.src.source_scan = dm_horz;
- pipes[pipe_cnt].pipe.src.sw_mode = dm_sw_4kb_s;
- pipes[pipe_cnt].pipe.src.macro_tile_size = dm_64k_tile;
- pipes[pipe_cnt].pipe.src.viewport_width = timing->h_addressable;
- if (pipes[pipe_cnt].pipe.src.viewport_width > 1920)
- pipes[pipe_cnt].pipe.src.viewport_width = 1920;
- pipes[pipe_cnt].pipe.src.viewport_height = timing->v_addressable;
- if (pipes[pipe_cnt].pipe.src.viewport_height > 1080)
- pipes[pipe_cnt].pipe.src.viewport_height = 1080;
- pipes[pipe_cnt].pipe.src.surface_height_y = pipes[pipe_cnt].pipe.src.viewport_height;
- pipes[pipe_cnt].pipe.src.surface_width_y = pipes[pipe_cnt].pipe.src.viewport_width;
- pipes[pipe_cnt].pipe.src.surface_height_c = pipes[pipe_cnt].pipe.src.viewport_height;
- pipes[pipe_cnt].pipe.src.surface_width_c = pipes[pipe_cnt].pipe.src.viewport_width;
- pipes[pipe_cnt].pipe.src.data_pitch = ((pipes[pipe_cnt].pipe.src.viewport_width + 255) / 256) * 256;
- pipes[pipe_cnt].pipe.src.source_format = dm_444_32;
- pipes[pipe_cnt].pipe.dest.recout_width = pipes[pipe_cnt].pipe.src.viewport_width; /*vp_width/hratio*/
- pipes[pipe_cnt].pipe.dest.recout_height = pipes[pipe_cnt].pipe.src.viewport_height; /*vp_height/vratio*/
- pipes[pipe_cnt].pipe.dest.full_recout_width = pipes[pipe_cnt].pipe.dest.recout_width; /*when is_hsplit != 1*/
- pipes[pipe_cnt].pipe.dest.full_recout_height = pipes[pipe_cnt].pipe.dest.recout_height; /*when is_hsplit != 1*/
- pipes[pipe_cnt].pipe.scale_ratio_depth.lb_depth = dm_lb_16;
- pipes[pipe_cnt].pipe.scale_ratio_depth.hscl_ratio = 1.0;
- pipes[pipe_cnt].pipe.scale_ratio_depth.vscl_ratio = 1.0;
- pipes[pipe_cnt].pipe.scale_ratio_depth.scl_enable = 0; /*Lb only or Full scl*/
- pipes[pipe_cnt].pipe.scale_taps.htaps = 1;
- pipes[pipe_cnt].pipe.scale_taps.vtaps = 1;
- pipes[pipe_cnt].pipe.dest.vtotal_min = v_total;
- pipes[pipe_cnt].pipe.dest.vtotal_max = v_total;
-
- if (pipes[pipe_cnt].pipe.dest.odm_combine == dm_odm_combine_mode_2to1) {
- pipes[pipe_cnt].pipe.src.viewport_width /= 2;
- pipes[pipe_cnt].pipe.dest.recout_width /= 2;
- } else if (pipes[pipe_cnt].pipe.dest.odm_combine == dm_odm_combine_mode_4to1) {
- pipes[pipe_cnt].pipe.src.viewport_width /= 4;
- pipes[pipe_cnt].pipe.dest.recout_width /= 4;
- }
- } else {
- struct dc_plane_state *pln = res_ctx->pipe_ctx[i].plane_state;
- struct scaler_data *scl = &res_ctx->pipe_ctx[i].plane_res.scl_data;
-
- pipes[pipe_cnt].pipe.src.immediate_flip = pln->flip_immediate;
- pipes[pipe_cnt].pipe.src.is_hsplit = (res_ctx->pipe_ctx[i].bottom_pipe && res_ctx->pipe_ctx[i].bottom_pipe->plane_state == pln)
- || (res_ctx->pipe_ctx[i].top_pipe && res_ctx->pipe_ctx[i].top_pipe->plane_state == pln)
- || pipes[pipe_cnt].pipe.dest.odm_combine != dm_odm_combine_mode_disabled;
-
- /* stereo is not split */
- if (pln->stereo_format == PLANE_STEREO_FORMAT_SIDE_BY_SIDE ||
- pln->stereo_format == PLANE_STEREO_FORMAT_TOP_AND_BOTTOM) {
- pipes[pipe_cnt].pipe.src.is_hsplit = false;
- pipes[pipe_cnt].pipe.src.hsplit_grp = res_ctx->pipe_ctx[i].pipe_idx;
- }
-
- pipes[pipe_cnt].pipe.src.source_scan = pln->rotation == ROTATION_ANGLE_90
- || pln->rotation == ROTATION_ANGLE_270 ? dm_vert : dm_horz;
- pipes[pipe_cnt].pipe.src.viewport_y_y = scl->viewport.y;
- pipes[pipe_cnt].pipe.src.viewport_y_c = scl->viewport_c.y;
- pipes[pipe_cnt].pipe.src.viewport_width = scl->viewport.width;
- pipes[pipe_cnt].pipe.src.viewport_width_c = scl->viewport_c.width;
- pipes[pipe_cnt].pipe.src.viewport_height = scl->viewport.height;
- pipes[pipe_cnt].pipe.src.viewport_height_c = scl->viewport_c.height;
- pipes[pipe_cnt].pipe.src.viewport_width_max = pln->src_rect.width;
- pipes[pipe_cnt].pipe.src.viewport_height_max = pln->src_rect.height;
- pipes[pipe_cnt].pipe.src.surface_width_y = pln->plane_size.surface_size.width;
- pipes[pipe_cnt].pipe.src.surface_height_y = pln->plane_size.surface_size.height;
- pipes[pipe_cnt].pipe.src.surface_width_c = pln->plane_size.chroma_size.width;
- pipes[pipe_cnt].pipe.src.surface_height_c = pln->plane_size.chroma_size.height;
- if (pln->format == SURFACE_PIXEL_FORMAT_GRPH_RGBE_ALPHA
- || pln->format >= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN) {
- pipes[pipe_cnt].pipe.src.data_pitch = pln->plane_size.surface_pitch;
- pipes[pipe_cnt].pipe.src.data_pitch_c = pln->plane_size.chroma_pitch;
- pipes[pipe_cnt].pipe.src.meta_pitch = pln->dcc.meta_pitch;
- pipes[pipe_cnt].pipe.src.meta_pitch_c = pln->dcc.meta_pitch_c;
- } else {
- pipes[pipe_cnt].pipe.src.data_pitch = pln->plane_size.surface_pitch;
- pipes[pipe_cnt].pipe.src.meta_pitch = pln->dcc.meta_pitch;
- }
- pipes[pipe_cnt].pipe.src.dcc = pln->dcc.enable;
- pipes[pipe_cnt].pipe.dest.recout_width = scl->recout.width;
- pipes[pipe_cnt].pipe.dest.recout_height = scl->recout.height;
- pipes[pipe_cnt].pipe.dest.full_recout_height = scl->recout.height;
- pipes[pipe_cnt].pipe.dest.full_recout_width = scl->recout.width;
- if (pipes[pipe_cnt].pipe.dest.odm_combine == dm_odm_combine_mode_2to1)
- pipes[pipe_cnt].pipe.dest.full_recout_width *= 2;
- else if (pipes[pipe_cnt].pipe.dest.odm_combine == dm_odm_combine_mode_4to1)
- pipes[pipe_cnt].pipe.dest.full_recout_width *= 4;
- else {
- struct pipe_ctx *split_pipe = res_ctx->pipe_ctx[i].bottom_pipe;
-
- while (split_pipe && split_pipe->plane_state == pln) {
- pipes[pipe_cnt].pipe.dest.full_recout_width += split_pipe->plane_res.scl_data.recout.width;
- split_pipe = split_pipe->bottom_pipe;
- }
- split_pipe = res_ctx->pipe_ctx[i].top_pipe;
- while (split_pipe && split_pipe->plane_state == pln) {
- pipes[pipe_cnt].pipe.dest.full_recout_width += split_pipe->plane_res.scl_data.recout.width;
- split_pipe = split_pipe->top_pipe;
- }
- }
-
- pipes[pipe_cnt].pipe.scale_ratio_depth.lb_depth = dm_lb_16;
- pipes[pipe_cnt].pipe.scale_ratio_depth.hscl_ratio = (double) scl->ratios.horz.value / (1ULL<<32);
- pipes[pipe_cnt].pipe.scale_ratio_depth.hscl_ratio_c = (double) scl->ratios.horz_c.value / (1ULL<<32);
- pipes[pipe_cnt].pipe.scale_ratio_depth.vscl_ratio = (double) scl->ratios.vert.value / (1ULL<<32);
- pipes[pipe_cnt].pipe.scale_ratio_depth.vscl_ratio_c = (double) scl->ratios.vert_c.value / (1ULL<<32);
- pipes[pipe_cnt].pipe.scale_ratio_depth.scl_enable =
- scl->ratios.vert.value != dc_fixpt_one.value
- || scl->ratios.horz.value != dc_fixpt_one.value
- || scl->ratios.vert_c.value != dc_fixpt_one.value
- || scl->ratios.horz_c.value != dc_fixpt_one.value /*Lb only or Full scl*/
- || dc->debug.always_scale; /*support always scale*/
- pipes[pipe_cnt].pipe.scale_taps.htaps = scl->taps.h_taps;
- pipes[pipe_cnt].pipe.scale_taps.htaps_c = scl->taps.h_taps_c;
- pipes[pipe_cnt].pipe.scale_taps.vtaps = scl->taps.v_taps;
- pipes[pipe_cnt].pipe.scale_taps.vtaps_c = scl->taps.v_taps_c;
-
- pipes[pipe_cnt].pipe.src.macro_tile_size =
- swizzle_mode_to_macro_tile_size(pln->tiling_info.gfx9.swizzle);
- swizzle_to_dml_params(pln->tiling_info.gfx9.swizzle,
- &pipes[pipe_cnt].pipe.src.sw_mode);
-
- switch (pln->format) {
- case SURFACE_PIXEL_FORMAT_VIDEO_420_YCbCr:
- case SURFACE_PIXEL_FORMAT_VIDEO_420_YCrCb:
- pipes[pipe_cnt].pipe.src.source_format = dm_420_8;
- break;
- case SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCbCr:
- case SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCrCb:
- pipes[pipe_cnt].pipe.src.source_format = dm_420_10;
- break;
- case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616:
- case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616:
- case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616F:
- case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F:
- pipes[pipe_cnt].pipe.src.source_format = dm_444_64;
- break;
- case SURFACE_PIXEL_FORMAT_GRPH_ARGB1555:
- case SURFACE_PIXEL_FORMAT_GRPH_RGB565:
- pipes[pipe_cnt].pipe.src.source_format = dm_444_16;
- break;
- case SURFACE_PIXEL_FORMAT_GRPH_PALETA_256_COLORS:
- pipes[pipe_cnt].pipe.src.source_format = dm_444_8;
- break;
- case SURFACE_PIXEL_FORMAT_GRPH_RGBE_ALPHA:
- pipes[pipe_cnt].pipe.src.source_format = dm_rgbe_alpha;
- break;
- default:
- pipes[pipe_cnt].pipe.src.source_format = dm_444_32;
- break;
- }
- }
-
- pipe_cnt++;
- }
-
- /* populate writeback information */
- DC_FP_START();
- dc->res_pool->funcs->populate_dml_writeback_from_context(dc, res_ctx, pipes);
- DC_FP_END();
-
- return pipe_cnt;
-}
-
unsigned int dcn20_calc_max_scaled_time(
unsigned int time_per_pixel,
enum mmhubbub_wbif_mode mode,
@@ -2422,7 +1600,7 @@ void dcn20_set_mcif_arb_params(
{
enum mmhubbub_wbif_mode wbif_mode;
struct mcif_arb_params *wb_arb_params;
- int i, j, k, dwb_pipe;
+ int i, j, dwb_pipe;
/* Writeback MCIF_WB arbitration parameters */
dwb_pipe = 0;
@@ -2446,11 +1624,10 @@ void dcn20_set_mcif_arb_params(
} else
wbif_mode = PACKED_444;
- for (k = 0; k < sizeof(wb_arb_params->cli_watermark)/sizeof(wb_arb_params->cli_watermark[0]); k++) {
- wb_arb_params->cli_watermark[k] = get_wm_writeback_urgent(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
- wb_arb_params->pstate_watermark[k] = get_wm_writeback_dram_clock_change(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
- }
- wb_arb_params->time_per_pixel = 16.0 * 1000 / (context->res_ctx.pipe_ctx[i].stream->phy_pix_clk / 1000); /* 4 bit fraction, ms */
+ DC_FP_START();
+ dcn20_fpu_set_wb_arb_params(wb_arb_params, context, pipes, pipe_cnt, i);
+ DC_FP_END();
+
wb_arb_params->slice_lines = 32;
wb_arb_params->arbitration_slice = 2;
wb_arb_params->max_scaled_time = dcn20_calc_max_scaled_time(wb_arb_params->time_per_pixel,
@@ -2817,8 +1994,11 @@ int dcn20_validate_apply_pipe_split_flags(
}
/* Adjust dppclk when split is forced, do not bother with dispclk */
- if (split[i] != 0 && v->NoOfDPP[vlevel][max_mpc_comb][pipe_idx] == 1)
- v->RequiredDPPCLK[vlevel][max_mpc_comb][pipe_idx] /= 2;
+ if (split[i] != 0 && v->NoOfDPP[vlevel][max_mpc_comb][pipe_idx] == 1) {
+ DC_FP_START();
+ dcn20_fpu_adjust_dppclk(v, vlevel, max_mpc_comb, pipe_idx, false);
+ DC_FP_END();
+ }
pipe_idx++;
}
@@ -2844,7 +2024,9 @@ bool dcn20_fast_validate_bw(
dcn20_merge_pipes_for_validate(dc, context);
+ DC_FP_START();
pipe_cnt = dc->res_pool->funcs->populate_dml_pipes(dc, context, pipes, fast_validate);
+ DC_FP_END();
*pipe_cnt_out = pipe_cnt;
@@ -2901,7 +2083,9 @@ bool dcn20_fast_validate_bw(
hsplit_pipe = dcn20_find_secondary_pipe(dc, &context->res_ctx, dc->res_pool, pipe);
ASSERT(hsplit_pipe);
if (!hsplit_pipe) {
- context->bw_ctx.dml.vba.RequiredDPPCLK[vlevel][context->bw_ctx.dml.vba.maxMpcComb][pipe_idx] *= 2;
+ DC_FP_START();
+ dcn20_fpu_adjust_dppclk(&context->bw_ctx.dml.vba, vlevel, context->bw_ctx.dml.vba.maxMpcComb, pipe_idx, true);
+ DC_FP_END();
continue;
}
if (context->bw_ctx.dml.vba.ODMCombineEnabled[pipe_idx]) {
@@ -2943,363 +2127,6 @@ validate_out:
return out;
}
-static void dcn20_calculate_wm(
- struct dc *dc, struct dc_state *context,
- display_e2e_pipe_params_st *pipes,
- int *out_pipe_cnt,
- int *pipe_split_from,
- int vlevel,
- bool fast_validate)
-{
- int pipe_cnt, i, pipe_idx;
-
- for (i = 0, pipe_idx = 0, pipe_cnt = 0; i < dc->res_pool->pipe_count; i++) {
- if (!context->res_ctx.pipe_ctx[i].stream)
- continue;
-
- pipes[pipe_cnt].clks_cfg.refclk_mhz = dc->res_pool->ref_clocks.dchub_ref_clock_inKhz / 1000.0;
- pipes[pipe_cnt].clks_cfg.dispclk_mhz = context->bw_ctx.dml.vba.RequiredDISPCLK[vlevel][context->bw_ctx.dml.vba.maxMpcComb];
-
- if (pipe_split_from[i] < 0) {
- pipes[pipe_cnt].clks_cfg.dppclk_mhz =
- context->bw_ctx.dml.vba.RequiredDPPCLK[vlevel][context->bw_ctx.dml.vba.maxMpcComb][pipe_idx];
- if (context->bw_ctx.dml.vba.BlendingAndTiming[pipe_idx] == pipe_idx)
- pipes[pipe_cnt].pipe.dest.odm_combine =
- context->bw_ctx.dml.vba.ODMCombineEnabled[pipe_idx];
- else
- pipes[pipe_cnt].pipe.dest.odm_combine = 0;
- pipe_idx++;
- } else {
- pipes[pipe_cnt].clks_cfg.dppclk_mhz =
- context->bw_ctx.dml.vba.RequiredDPPCLK[vlevel][context->bw_ctx.dml.vba.maxMpcComb][pipe_split_from[i]];
- if (context->bw_ctx.dml.vba.BlendingAndTiming[pipe_split_from[i]] == pipe_split_from[i])
- pipes[pipe_cnt].pipe.dest.odm_combine =
- context->bw_ctx.dml.vba.ODMCombineEnabled[pipe_split_from[i]];
- else
- pipes[pipe_cnt].pipe.dest.odm_combine = 0;
- }
-
- if (dc->config.forced_clocks) {
- pipes[pipe_cnt].clks_cfg.dispclk_mhz = context->bw_ctx.dml.soc.clock_limits[0].dispclk_mhz;
- pipes[pipe_cnt].clks_cfg.dppclk_mhz = context->bw_ctx.dml.soc.clock_limits[0].dppclk_mhz;
- }
- if (dc->debug.min_disp_clk_khz > pipes[pipe_cnt].clks_cfg.dispclk_mhz * 1000)
- pipes[pipe_cnt].clks_cfg.dispclk_mhz = dc->debug.min_disp_clk_khz / 1000.0;
- if (dc->debug.min_dpp_clk_khz > pipes[pipe_cnt].clks_cfg.dppclk_mhz * 1000)
- pipes[pipe_cnt].clks_cfg.dppclk_mhz = dc->debug.min_dpp_clk_khz / 1000.0;
-
- pipe_cnt++;
- }
-
- if (pipe_cnt != pipe_idx) {
- if (dc->res_pool->funcs->populate_dml_pipes)
- pipe_cnt = dc->res_pool->funcs->populate_dml_pipes(dc,
- context, pipes, fast_validate);
- else
- pipe_cnt = dcn20_populate_dml_pipes_from_context(dc,
- context, pipes, fast_validate);
- }
-
- *out_pipe_cnt = pipe_cnt;
-
- pipes[0].clks_cfg.voltage = vlevel;
- pipes[0].clks_cfg.dcfclk_mhz = context->bw_ctx.dml.soc.clock_limits[vlevel].dcfclk_mhz;
- pipes[0].clks_cfg.socclk_mhz = context->bw_ctx.dml.soc.clock_limits[vlevel].socclk_mhz;
-
- /* only pipe 0 is read for voltage and dcf/soc clocks */
- if (vlevel < 1) {
- pipes[0].clks_cfg.voltage = 1;
- pipes[0].clks_cfg.dcfclk_mhz = context->bw_ctx.dml.soc.clock_limits[1].dcfclk_mhz;
- pipes[0].clks_cfg.socclk_mhz = context->bw_ctx.dml.soc.clock_limits[1].socclk_mhz;
- }
- context->bw_ctx.bw.dcn.watermarks.b.urgent_ns = get_wm_urgent(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
- context->bw_ctx.bw.dcn.watermarks.b.cstate_pstate.cstate_enter_plus_exit_ns = get_wm_stutter_enter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
- context->bw_ctx.bw.dcn.watermarks.b.cstate_pstate.cstate_exit_ns = get_wm_stutter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
- context->bw_ctx.bw.dcn.watermarks.b.cstate_pstate.pstate_change_ns = get_wm_dram_clock_change(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
- context->bw_ctx.bw.dcn.watermarks.b.pte_meta_urgent_ns = get_wm_memory_trip(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
- context->bw_ctx.bw.dcn.watermarks.b.frac_urg_bw_nom = get_fraction_of_urgent_bandwidth(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
- context->bw_ctx.bw.dcn.watermarks.b.frac_urg_bw_flip = get_fraction_of_urgent_bandwidth_imm_flip(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
- context->bw_ctx.bw.dcn.watermarks.b.urgent_latency_ns = get_urgent_latency(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
-
- if (vlevel < 2) {
- pipes[0].clks_cfg.voltage = 2;
- pipes[0].clks_cfg.dcfclk_mhz = context->bw_ctx.dml.soc.clock_limits[2].dcfclk_mhz;
- pipes[0].clks_cfg.socclk_mhz = context->bw_ctx.dml.soc.clock_limits[2].socclk_mhz;
- }
- context->bw_ctx.bw.dcn.watermarks.c.urgent_ns = get_wm_urgent(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
- context->bw_ctx.bw.dcn.watermarks.c.cstate_pstate.cstate_enter_plus_exit_ns = get_wm_stutter_enter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
- context->bw_ctx.bw.dcn.watermarks.c.cstate_pstate.cstate_exit_ns = get_wm_stutter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
- context->bw_ctx.bw.dcn.watermarks.c.cstate_pstate.pstate_change_ns = get_wm_dram_clock_change(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
- context->bw_ctx.bw.dcn.watermarks.c.pte_meta_urgent_ns = get_wm_memory_trip(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
- context->bw_ctx.bw.dcn.watermarks.c.frac_urg_bw_nom = get_fraction_of_urgent_bandwidth(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
- context->bw_ctx.bw.dcn.watermarks.c.frac_urg_bw_flip = get_fraction_of_urgent_bandwidth_imm_flip(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
-
- if (vlevel < 3) {
- pipes[0].clks_cfg.voltage = 3;
- pipes[0].clks_cfg.dcfclk_mhz = context->bw_ctx.dml.soc.clock_limits[2].dcfclk_mhz;
- pipes[0].clks_cfg.socclk_mhz = context->bw_ctx.dml.soc.clock_limits[2].socclk_mhz;
- }
- context->bw_ctx.bw.dcn.watermarks.d.urgent_ns = get_wm_urgent(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
- context->bw_ctx.bw.dcn.watermarks.d.cstate_pstate.cstate_enter_plus_exit_ns = get_wm_stutter_enter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
- context->bw_ctx.bw.dcn.watermarks.d.cstate_pstate.cstate_exit_ns = get_wm_stutter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
- context->bw_ctx.bw.dcn.watermarks.d.cstate_pstate.pstate_change_ns = get_wm_dram_clock_change(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
- context->bw_ctx.bw.dcn.watermarks.d.pte_meta_urgent_ns = get_wm_memory_trip(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
- context->bw_ctx.bw.dcn.watermarks.d.frac_urg_bw_nom = get_fraction_of_urgent_bandwidth(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
- context->bw_ctx.bw.dcn.watermarks.d.frac_urg_bw_flip = get_fraction_of_urgent_bandwidth_imm_flip(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
-
- pipes[0].clks_cfg.voltage = vlevel;
- pipes[0].clks_cfg.dcfclk_mhz = context->bw_ctx.dml.soc.clock_limits[vlevel].dcfclk_mhz;
- pipes[0].clks_cfg.socclk_mhz = context->bw_ctx.dml.soc.clock_limits[vlevel].socclk_mhz;
- context->bw_ctx.bw.dcn.watermarks.a.urgent_ns = get_wm_urgent(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
- context->bw_ctx.bw.dcn.watermarks.a.cstate_pstate.cstate_enter_plus_exit_ns = get_wm_stutter_enter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
- context->bw_ctx.bw.dcn.watermarks.a.cstate_pstate.cstate_exit_ns = get_wm_stutter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
- context->bw_ctx.bw.dcn.watermarks.a.cstate_pstate.pstate_change_ns = get_wm_dram_clock_change(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
- context->bw_ctx.bw.dcn.watermarks.a.pte_meta_urgent_ns = get_wm_memory_trip(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
- context->bw_ctx.bw.dcn.watermarks.a.frac_urg_bw_nom = get_fraction_of_urgent_bandwidth(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
- context->bw_ctx.bw.dcn.watermarks.a.frac_urg_bw_flip = get_fraction_of_urgent_bandwidth_imm_flip(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
-}
-
-static bool is_dtbclk_required(struct dc *dc, struct dc_state *context)
-{
- int i;
- for (i = 0; i < dc->res_pool->pipe_count; i++) {
- if (!context->res_ctx.pipe_ctx[i].stream)
- continue;
- if (is_dp_128b_132b_signal(&context->res_ctx.pipe_ctx[i]))
- return true;
- }
- return false;
-}
-
-static enum dcn_zstate_support_state decide_zstate_support(struct dc *dc, struct dc_state *context)
-{
- int plane_count;
- int i;
-
- plane_count = 0;
- for (i = 0; i < dc->res_pool->pipe_count; i++) {
- if (context->res_ctx.pipe_ctx[i].plane_state)
- plane_count++;
- }
-
- /*
- * Zstate is allowed in following scenarios:
- * 1. Single eDP with PSR enabled
- * 2. 0 planes (No memory requests)
- * 3. Single eDP without PSR but > 5ms stutter period
- */
- if (plane_count == 0)
- return DCN_ZSTATE_SUPPORT_ALLOW;
- else if (context->stream_count == 1 && context->streams[0]->signal == SIGNAL_TYPE_EDP) {
- struct dc_link *link = context->streams[0]->sink->link;
-
- if (link->link_index == 0 && context->bw_ctx.dml.vba.StutterPeriod > 5000.0)
- return DCN_ZSTATE_SUPPORT_ALLOW;
- else
- return DCN_ZSTATE_SUPPORT_DISALLOW;
- } else
- return DCN_ZSTATE_SUPPORT_DISALLOW;
-}
-
-void dcn20_calculate_dlg_params(
- struct dc *dc, struct dc_state *context,
- display_e2e_pipe_params_st *pipes,
- int pipe_cnt,
- int vlevel)
-{
- int i, pipe_idx;
-
- /* Writeback MCIF_WB arbitration parameters */
- dc->res_pool->funcs->set_mcif_arb_params(dc, context, pipes, pipe_cnt);
-
- context->bw_ctx.bw.dcn.clk.dispclk_khz = context->bw_ctx.dml.vba.DISPCLK * 1000;
- context->bw_ctx.bw.dcn.clk.dcfclk_khz = context->bw_ctx.dml.vba.DCFCLK * 1000;
- context->bw_ctx.bw.dcn.clk.socclk_khz = context->bw_ctx.dml.vba.SOCCLK * 1000;
- context->bw_ctx.bw.dcn.clk.dramclk_khz = context->bw_ctx.dml.vba.DRAMSpeed * 1000 / 16;
-
- if (dc->debug.min_dram_clk_khz > context->bw_ctx.bw.dcn.clk.dramclk_khz)
- context->bw_ctx.bw.dcn.clk.dramclk_khz = dc->debug.min_dram_clk_khz;
-
- context->bw_ctx.bw.dcn.clk.dcfclk_deep_sleep_khz = context->bw_ctx.dml.vba.DCFCLKDeepSleep * 1000;
- context->bw_ctx.bw.dcn.clk.fclk_khz = context->bw_ctx.dml.vba.FabricClock * 1000;
- context->bw_ctx.bw.dcn.clk.p_state_change_support =
- context->bw_ctx.dml.vba.DRAMClockChangeSupport[vlevel][context->bw_ctx.dml.vba.maxMpcComb]
- != dm_dram_clock_change_unsupported;
- context->bw_ctx.bw.dcn.clk.dppclk_khz = 0;
-
- context->bw_ctx.bw.dcn.clk.zstate_support = decide_zstate_support(dc, context);
-
- context->bw_ctx.bw.dcn.clk.dtbclk_en = is_dtbclk_required(dc, context);
-
- if (context->bw_ctx.bw.dcn.clk.dispclk_khz < dc->debug.min_disp_clk_khz)
- context->bw_ctx.bw.dcn.clk.dispclk_khz = dc->debug.min_disp_clk_khz;
-
- for (i = 0, pipe_idx = 0; i < dc->res_pool->pipe_count; i++) {
- if (!context->res_ctx.pipe_ctx[i].stream)
- continue;
- pipes[pipe_idx].pipe.dest.vstartup_start = get_vstartup(&context->bw_ctx.dml, pipes, pipe_cnt, pipe_idx);
- pipes[pipe_idx].pipe.dest.vupdate_offset = get_vupdate_offset(&context->bw_ctx.dml, pipes, pipe_cnt, pipe_idx);
- pipes[pipe_idx].pipe.dest.vupdate_width = get_vupdate_width(&context->bw_ctx.dml, pipes, pipe_cnt, pipe_idx);
- pipes[pipe_idx].pipe.dest.vready_offset = get_vready_offset(&context->bw_ctx.dml, pipes, pipe_cnt, pipe_idx);
- context->res_ctx.pipe_ctx[i].det_buffer_size_kb = context->bw_ctx.dml.ip.det_buffer_size_kbytes;
- context->res_ctx.pipe_ctx[i].unbounded_req = pipes[pipe_idx].pipe.src.unbounded_req_mode;
-
- if (context->bw_ctx.bw.dcn.clk.dppclk_khz < pipes[pipe_idx].clks_cfg.dppclk_mhz * 1000)
- context->bw_ctx.bw.dcn.clk.dppclk_khz = pipes[pipe_idx].clks_cfg.dppclk_mhz * 1000;
- context->res_ctx.pipe_ctx[i].plane_res.bw.dppclk_khz =
- pipes[pipe_idx].clks_cfg.dppclk_mhz * 1000;
- context->res_ctx.pipe_ctx[i].pipe_dlg_param = pipes[pipe_idx].pipe.dest;
- pipe_idx++;
- }
- /*save a original dppclock copy*/
- context->bw_ctx.bw.dcn.clk.bw_dppclk_khz = context->bw_ctx.bw.dcn.clk.dppclk_khz;
- context->bw_ctx.bw.dcn.clk.bw_dispclk_khz = context->bw_ctx.bw.dcn.clk.dispclk_khz;
- context->bw_ctx.bw.dcn.clk.max_supported_dppclk_khz = context->bw_ctx.dml.soc.clock_limits[vlevel].dppclk_mhz * 1000;
- context->bw_ctx.bw.dcn.clk.max_supported_dispclk_khz = context->bw_ctx.dml.soc.clock_limits[vlevel].dispclk_mhz * 1000;
-
- context->bw_ctx.bw.dcn.compbuf_size_kb = context->bw_ctx.dml.ip.config_return_buffer_size_in_kbytes
- - context->bw_ctx.dml.ip.det_buffer_size_kbytes * pipe_idx;
-
- for (i = 0, pipe_idx = 0; i < dc->res_pool->pipe_count; i++) {
- bool cstate_en = context->bw_ctx.dml.vba.PrefetchMode[vlevel][context->bw_ctx.dml.vba.maxMpcComb] != 2;
-
- if (!context->res_ctx.pipe_ctx[i].stream)
- continue;
-
- if (dc->ctx->dce_version == DCN_VERSION_2_01)
- cstate_en = false;
-
- context->bw_ctx.dml.funcs.rq_dlg_get_dlg_reg(&context->bw_ctx.dml,
- &context->res_ctx.pipe_ctx[i].dlg_regs,
- &context->res_ctx.pipe_ctx[i].ttu_regs,
- pipes,
- pipe_cnt,
- pipe_idx,
- cstate_en,
- context->bw_ctx.bw.dcn.clk.p_state_change_support,
- false, false, true);
-
- context->bw_ctx.dml.funcs.rq_dlg_get_rq_reg(&context->bw_ctx.dml,
- &context->res_ctx.pipe_ctx[i].rq_regs,
- &pipes[pipe_idx].pipe);
- pipe_idx++;
- }
-}
-
-static bool dcn20_validate_bandwidth_internal(struct dc *dc, struct dc_state *context,
- bool fast_validate)
-{
- bool out = false;
-
- BW_VAL_TRACE_SETUP();
-
- int vlevel = 0;
- int pipe_split_from[MAX_PIPES];
- int pipe_cnt = 0;
- display_e2e_pipe_params_st *pipes = kzalloc(dc->res_pool->pipe_count * sizeof(display_e2e_pipe_params_st), GFP_ATOMIC);
- DC_LOGGER_INIT(dc->ctx->logger);
-
- BW_VAL_TRACE_COUNT();
-
- out = dcn20_fast_validate_bw(dc, context, pipes, &pipe_cnt, pipe_split_from, &vlevel, fast_validate);
-
- if (pipe_cnt == 0)
- goto validate_out;
-
- if (!out)
- goto validate_fail;
-
- BW_VAL_TRACE_END_VOLTAGE_LEVEL();
-
- if (fast_validate) {
- BW_VAL_TRACE_SKIP(fast);
- goto validate_out;
- }
-
- dcn20_calculate_wm(dc, context, pipes, &pipe_cnt, pipe_split_from, vlevel, fast_validate);
- dcn20_calculate_dlg_params(dc, context, pipes, pipe_cnt, vlevel);
-
- BW_VAL_TRACE_END_WATERMARKS();
-
- goto validate_out;
-
-validate_fail:
- DC_LOG_WARNING("Mode Validation Warning: %s failed validation.\n",
- dml_get_status_message(context->bw_ctx.dml.vba.ValidationStatus[context->bw_ctx.dml.vba.soc.num_states]));
-
- BW_VAL_TRACE_SKIP(fail);
- out = false;
-
-validate_out:
- kfree(pipes);
-
- BW_VAL_TRACE_FINISH();
-
- return out;
-}
-
-/*
- * This must be noinline to ensure anything that deals with FP registers
- * is contained within this call; previously our compiling with hard-float
- * would result in fp instructions being emitted outside of the boundaries
- * of the DC_FP_START/END macros, which makes sense as the compiler has no
- * idea about what is wrapped and what is not
- *
- * This is largely just a workaround to avoid breakage introduced with 5.6,
- * ideally all fp-using code should be moved into its own file, only that
- * should be compiled with hard-float, and all code exported from there
- * should be strictly wrapped with DC_FP_START/END
- */
-static noinline bool dcn20_validate_bandwidth_fp(struct dc *dc,
- struct dc_state *context, bool fast_validate)
-{
- bool voltage_supported = false;
- bool full_pstate_supported = false;
- bool dummy_pstate_supported = false;
- double p_state_latency_us;
-
- p_state_latency_us = context->bw_ctx.dml.soc.dram_clock_change_latency_us;
- context->bw_ctx.dml.soc.disable_dram_clock_change_vactive_support =
- dc->debug.disable_dram_clock_change_vactive_support;
- context->bw_ctx.dml.soc.allow_dram_clock_one_display_vactive =
- dc->debug.enable_dram_clock_change_one_display_vactive;
-
- /*Unsafe due to current pipe merge and split logic*/
- ASSERT(context != dc->current_state);
-
- if (fast_validate) {
- return dcn20_validate_bandwidth_internal(dc, context, true);
- }
-
- // Best case, we support full UCLK switch latency
- voltage_supported = dcn20_validate_bandwidth_internal(dc, context, false);
- full_pstate_supported = context->bw_ctx.bw.dcn.clk.p_state_change_support;
-
- if (context->bw_ctx.dml.soc.dummy_pstate_latency_us == 0 ||
- (voltage_supported && full_pstate_supported)) {
- context->bw_ctx.bw.dcn.clk.p_state_change_support = full_pstate_supported;
- goto restore_dml_state;
- }
-
- // Fallback: Try to only support G6 temperature read latency
- context->bw_ctx.dml.soc.dram_clock_change_latency_us = context->bw_ctx.dml.soc.dummy_pstate_latency_us;
-
- voltage_supported = dcn20_validate_bandwidth_internal(dc, context, false);
- dummy_pstate_supported = context->bw_ctx.bw.dcn.clk.p_state_change_support;
-
- if (voltage_supported && (dummy_pstate_supported || !(context->stream_count))) {
- context->bw_ctx.bw.dcn.clk.p_state_change_support = false;
- goto restore_dml_state;
- }
-
- // ERROR: fallback is supposed to always work.
- ASSERT(false);
-
-restore_dml_state:
- context->bw_ctx.dml.soc.dram_clock_change_latency_us = p_state_latency_us;
- return voltage_supported;
-}
-
bool dcn20_validate_bandwidth(struct dc *dc, struct dc_state *context,
bool fast_validate)
{
@@ -3467,170 +2294,6 @@ static void dcn20_pp_smu_destroy(struct pp_smu_funcs **pp_smu)
}
}
-void dcn20_cap_soc_clocks(
- struct _vcs_dpi_soc_bounding_box_st *bb,
- struct pp_smu_nv_clock_table max_clocks)
-{
- int i;
-
- // First pass - cap all clocks higher than the reported max
- for (i = 0; i < bb->num_states; i++) {
- if ((bb->clock_limits[i].dcfclk_mhz > (max_clocks.dcfClockInKhz / 1000))
- && max_clocks.dcfClockInKhz != 0)
- bb->clock_limits[i].dcfclk_mhz = (max_clocks.dcfClockInKhz / 1000);
-
- if ((bb->clock_limits[i].dram_speed_mts > (max_clocks.uClockInKhz / 1000) * 16)
- && max_clocks.uClockInKhz != 0)
- bb->clock_limits[i].dram_speed_mts = (max_clocks.uClockInKhz / 1000) * 16;
-
- if ((bb->clock_limits[i].fabricclk_mhz > (max_clocks.fabricClockInKhz / 1000))
- && max_clocks.fabricClockInKhz != 0)
- bb->clock_limits[i].fabricclk_mhz = (max_clocks.fabricClockInKhz / 1000);
-
- if ((bb->clock_limits[i].dispclk_mhz > (max_clocks.displayClockInKhz / 1000))
- && max_clocks.displayClockInKhz != 0)
- bb->clock_limits[i].dispclk_mhz = (max_clocks.displayClockInKhz / 1000);
-
- if ((bb->clock_limits[i].dppclk_mhz > (max_clocks.dppClockInKhz / 1000))
- && max_clocks.dppClockInKhz != 0)
- bb->clock_limits[i].dppclk_mhz = (max_clocks.dppClockInKhz / 1000);
-
- if ((bb->clock_limits[i].phyclk_mhz > (max_clocks.phyClockInKhz / 1000))
- && max_clocks.phyClockInKhz != 0)
- bb->clock_limits[i].phyclk_mhz = (max_clocks.phyClockInKhz / 1000);
-
- if ((bb->clock_limits[i].socclk_mhz > (max_clocks.socClockInKhz / 1000))
- && max_clocks.socClockInKhz != 0)
- bb->clock_limits[i].socclk_mhz = (max_clocks.socClockInKhz / 1000);
-
- if ((bb->clock_limits[i].dscclk_mhz > (max_clocks.dscClockInKhz / 1000))
- && max_clocks.dscClockInKhz != 0)
- bb->clock_limits[i].dscclk_mhz = (max_clocks.dscClockInKhz / 1000);
- }
-
- // Second pass - remove all duplicate clock states
- for (i = bb->num_states - 1; i > 1; i--) {
- bool duplicate = true;
-
- if (bb->clock_limits[i-1].dcfclk_mhz != bb->clock_limits[i].dcfclk_mhz)
- duplicate = false;
- if (bb->clock_limits[i-1].dispclk_mhz != bb->clock_limits[i].dispclk_mhz)
- duplicate = false;
- if (bb->clock_limits[i-1].dppclk_mhz != bb->clock_limits[i].dppclk_mhz)
- duplicate = false;
- if (bb->clock_limits[i-1].dram_speed_mts != bb->clock_limits[i].dram_speed_mts)
- duplicate = false;
- if (bb->clock_limits[i-1].dscclk_mhz != bb->clock_limits[i].dscclk_mhz)
- duplicate = false;
- if (bb->clock_limits[i-1].fabricclk_mhz != bb->clock_limits[i].fabricclk_mhz)
- duplicate = false;
- if (bb->clock_limits[i-1].phyclk_mhz != bb->clock_limits[i].phyclk_mhz)
- duplicate = false;
- if (bb->clock_limits[i-1].socclk_mhz != bb->clock_limits[i].socclk_mhz)
- duplicate = false;
-
- if (duplicate)
- bb->num_states--;
- }
-}
-
-void dcn20_update_bounding_box(struct dc *dc, struct _vcs_dpi_soc_bounding_box_st *bb,
- struct pp_smu_nv_clock_table *max_clocks, unsigned int *uclk_states, unsigned int num_states)
-{
- struct _vcs_dpi_voltage_scaling_st calculated_states[DC__VOLTAGE_STATES];
- int i;
- int num_calculated_states = 0;
- int min_dcfclk = 0;
-
- if (num_states == 0)
- return;
-
- memset(calculated_states, 0, sizeof(calculated_states));
-
- if (dc->bb_overrides.min_dcfclk_mhz > 0)
- min_dcfclk = dc->bb_overrides.min_dcfclk_mhz;
- else {
- if (ASICREV_IS_NAVI12_P(dc->ctx->asic_id.hw_internal_rev))
- min_dcfclk = 310;
- else
- // Accounting for SOC/DCF relationship, we can go as high as
- // 506Mhz in Vmin.
- min_dcfclk = 506;
- }
-
- for (i = 0; i < num_states; i++) {
- int min_fclk_required_by_uclk;
- calculated_states[i].state = i;
- calculated_states[i].dram_speed_mts = uclk_states[i] * 16 / 1000;
-
- // FCLK:UCLK ratio is 1.08
- min_fclk_required_by_uclk = div_u64(((unsigned long long)uclk_states[i]) * 1080,
- 1000000);
-
- calculated_states[i].fabricclk_mhz = (min_fclk_required_by_uclk < min_dcfclk) ?
- min_dcfclk : min_fclk_required_by_uclk;
-
- calculated_states[i].socclk_mhz = (calculated_states[i].fabricclk_mhz > max_clocks->socClockInKhz / 1000) ?
- max_clocks->socClockInKhz / 1000 : calculated_states[i].fabricclk_mhz;
-
- calculated_states[i].dcfclk_mhz = (calculated_states[i].fabricclk_mhz > max_clocks->dcfClockInKhz / 1000) ?
- max_clocks->dcfClockInKhz / 1000 : calculated_states[i].fabricclk_mhz;
-
- calculated_states[i].dispclk_mhz = max_clocks->displayClockInKhz / 1000;
- calculated_states[i].dppclk_mhz = max_clocks->displayClockInKhz / 1000;
- calculated_states[i].dscclk_mhz = max_clocks->displayClockInKhz / (1000 * 3);
-
- calculated_states[i].phyclk_mhz = max_clocks->phyClockInKhz / 1000;
-
- num_calculated_states++;
- }
-
- calculated_states[num_calculated_states - 1].socclk_mhz = max_clocks->socClockInKhz / 1000;
- calculated_states[num_calculated_states - 1].fabricclk_mhz = max_clocks->socClockInKhz / 1000;
- calculated_states[num_calculated_states - 1].dcfclk_mhz = max_clocks->dcfClockInKhz / 1000;
-
- memcpy(bb->clock_limits, calculated_states, sizeof(bb->clock_limits));
- bb->num_states = num_calculated_states;
-
- // Duplicate the last state, DML always an extra state identical to max state to work
- memcpy(&bb->clock_limits[num_calculated_states], &bb->clock_limits[num_calculated_states - 1], sizeof(struct _vcs_dpi_voltage_scaling_st));
- bb->clock_limits[num_calculated_states].state = bb->num_states;
-}
-
-void dcn20_patch_bounding_box(struct dc *dc, struct _vcs_dpi_soc_bounding_box_st *bb)
-{
- if ((int)(bb->sr_exit_time_us * 1000) != dc->bb_overrides.sr_exit_time_ns
- && dc->bb_overrides.sr_exit_time_ns) {
- bb->sr_exit_time_us = dc->bb_overrides.sr_exit_time_ns / 1000.0;
- }
-
- if ((int)(bb->sr_enter_plus_exit_time_us * 1000)
- != dc->bb_overrides.sr_enter_plus_exit_time_ns
- && dc->bb_overrides.sr_enter_plus_exit_time_ns) {
- bb->sr_enter_plus_exit_time_us =
- dc->bb_overrides.sr_enter_plus_exit_time_ns / 1000.0;
- }
-
- if ((int)(bb->urgent_latency_us * 1000) != dc->bb_overrides.urgent_latency_ns
- && dc->bb_overrides.urgent_latency_ns) {
- bb->urgent_latency_us = dc->bb_overrides.urgent_latency_ns / 1000.0;
- }
-
- if ((int)(bb->dram_clock_change_latency_us * 1000)
- != dc->bb_overrides.dram_clock_change_latency_ns
- && dc->bb_overrides.dram_clock_change_latency_ns) {
- bb->dram_clock_change_latency_us =
- dc->bb_overrides.dram_clock_change_latency_ns / 1000.0;
- }
-
- if ((int)(bb->dummy_pstate_latency_us * 1000)
- != dc->bb_overrides.dummy_clock_change_latency_ns
- && dc->bb_overrides.dummy_clock_change_latency_ns) {
- bb->dummy_pstate_latency_us =
- dc->bb_overrides.dummy_clock_change_latency_ns / 1000.0;
- }
-}
-
static struct _vcs_dpi_soc_bounding_box_st *get_asic_rev_soc_bb(
uint32_t hw_internal_rev)
{
@@ -3913,8 +2576,9 @@ static bool dcn20_resource_construct(
ranges.reader_wm_sets[i].wm_inst = i;
ranges.reader_wm_sets[i].min_drain_clk_mhz = PP_SMU_WM_SET_RANGE_CLK_UNCONSTRAINED_MIN;
ranges.reader_wm_sets[i].max_drain_clk_mhz = PP_SMU_WM_SET_RANGE_CLK_UNCONSTRAINED_MAX;
- ranges.reader_wm_sets[i].min_fill_clk_mhz = (i > 0) ? (loaded_bb->clock_limits[i - 1].dram_speed_mts / 16) + 1 : 0;
- ranges.reader_wm_sets[i].max_fill_clk_mhz = loaded_bb->clock_limits[i].dram_speed_mts / 16;
+ DC_FP_START();
+ dcn20_fpu_set_wm_ranges(i, &ranges, loaded_bb);
+ DC_FP_END();
ranges.num_reader_wm_sets = i + 1;
}
diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.h b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.h
index 6ec8ff45f0f7..7cbe1e9daa36 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.h
+++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.h
@@ -27,6 +27,7 @@
#define __DC_RESOURCE_DCN20_H__
#include "core_types.h"
+#include "dml/dcn20/dcn20_fpu.h"
#define TO_DCN20_RES_POOL(pool)\
container_of(pool, struct dcn20_resource_pool, base)
@@ -35,6 +36,12 @@ struct dc;
struct resource_pool;
struct _vcs_dpi_display_pipe_params_st;
+extern struct _vcs_dpi_ip_params_st dcn2_0_ip;
+extern struct _vcs_dpi_ip_params_st dcn2_0_nv14_ip;
+extern struct _vcs_dpi_soc_bounding_box_st dcn2_0_soc;
+extern struct _vcs_dpi_soc_bounding_box_st dcn2_0_nv14_soc;
+extern struct _vcs_dpi_soc_bounding_box_st dcn2_0_nv12_soc;
+
struct dcn20_resource_pool {
struct resource_pool base;
};
@@ -49,11 +56,7 @@ unsigned int dcn20_calc_max_scaled_time(
unsigned int time_per_pixel,
enum mmhubbub_wbif_mode mode,
unsigned int urgent_watermark);
-int dcn20_populate_dml_pipes_from_context(
- struct dc *dc,
- struct dc_state *context,
- display_e2e_pipe_params_st *pipes,
- bool fast_validate);
+
struct pipe_ctx *dcn20_acquire_idle_pipe_for_layer(
struct dc_state *state,
const struct resource_pool *pool,
@@ -79,7 +82,6 @@ struct dpp *dcn20_dpp_create(
struct input_pixel_processor *dcn20_ipp_create(
struct dc_context *ctx, uint32_t inst);
-
struct output_pixel_processor *dcn20_opp_create(
struct dc_context *ctx, uint32_t inst);
@@ -96,11 +98,6 @@ struct display_stream_compressor *dcn20_dsc_create(
struct dc_context *ctx, uint32_t inst);
void dcn20_dsc_destroy(struct display_stream_compressor **dsc);
-void dcn20_cap_soc_clocks(
- struct _vcs_dpi_soc_bounding_box_st *bb,
- struct pp_smu_nv_clock_table max_clocks);
-void dcn20_update_bounding_box(struct dc *dc, struct _vcs_dpi_soc_bounding_box_st *bb,
- struct pp_smu_nv_clock_table *max_clocks, unsigned int *uclk_states, unsigned int num_states);
struct hubp *dcn20_hubp_create(
struct dc_context *ctx,
uint32_t inst);
@@ -158,11 +155,6 @@ bool dcn20_fast_validate_bw(
int *pipe_split_from,
int *vlevel_out,
bool fast_validate);
-void dcn20_calculate_dlg_params(
- struct dc *dc, struct dc_state *context,
- display_e2e_pipe_params_st *pipes,
- int pipe_cnt,
- int vlevel);
enum dc_status dcn20_build_mapped_resource(const struct dc *dc, struct dc_state *context, struct dc_stream_state *stream);
enum dc_status dcn20_add_stream_to_ctx(struct dc *dc, struct dc_state *new_ctx, struct dc_stream_state *dc_stream);
@@ -170,12 +162,5 @@ enum dc_status dcn20_add_dsc_to_stream_resource(struct dc *dc, struct dc_state *
enum dc_status dcn20_remove_stream_from_ctx(struct dc *dc, struct dc_state *new_ctx, struct dc_stream_state *dc_stream);
enum dc_status dcn20_patch_unknown_plane_state(struct dc_plane_state *plane_state);
-void dcn20_patch_bounding_box(
- struct dc *dc,
- struct _vcs_dpi_soc_bounding_box_st *bb);
-void dcn20_cap_soc_clocks(
- struct _vcs_dpi_soc_bounding_box_st *bb,
- struct pp_smu_nv_clock_table max_clocks);
-
#endif /* __DC_RESOURCE_DCN20_H__ */
diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_stream_encoder.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_stream_encoder.c
index 8a70f92795c2..aab25ca8343a 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_stream_encoder.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_stream_encoder.c
@@ -593,8 +593,6 @@ static const struct stream_encoder_funcs dcn20_str_enc_funcs = {
enc1_stream_encoder_send_immediate_sdp_message,
.stop_dp_info_packets =
enc1_stream_encoder_stop_dp_info_packets,
- .reset_fifo =
- enc1_stream_encoder_reset_fifo,
.dp_blank =
enc1_stream_encoder_dp_blank,
.dp_unblank =
diff --git a/drivers/gpu/drm/amd/display/dc/dcn201/dcn201_init.c b/drivers/gpu/drm/amd/display/dc/dcn201/dcn201_init.c
index f1f89f93603f..1826dd7f3da1 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn201/dcn201_init.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn201/dcn201_init.c
@@ -27,6 +27,7 @@
#include "dcn10/dcn10_hw_sequencer.h"
#include "dcn20/dcn20_hwseq.h"
#include "dcn201_hwseq.h"
+#include "dcn201_init.h"
static const struct hw_sequencer_funcs dcn201_funcs = {
.program_gamut_remap = dcn10_program_gamut_remap,
diff --git a/drivers/gpu/drm/amd/display/dc/dcn21/Makefile b/drivers/gpu/drm/amd/display/dc/dcn21/Makefile
index bb8c95141082..0dc06e428999 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn21/Makefile
+++ b/drivers/gpu/drm/amd/display/dc/dcn21/Makefile
@@ -5,31 +5,6 @@
DCN21 = dcn21_init.o dcn21_hubp.o dcn21_hubbub.o dcn21_resource.o \
dcn21_hwseq.o dcn21_link_encoder.o dcn21_dccg.o
-ifdef CONFIG_X86
-CFLAGS_$(AMDDALPATH)/dc/dcn21/dcn21_resource.o := -mhard-float -msse
-endif
-
-ifdef CONFIG_PPC64
-CFLAGS_$(AMDDALPATH)/dc/dcn21/dcn21_resource.o := -mhard-float -maltivec
-endif
-
-ifdef CONFIG_CC_IS_GCC
-ifeq ($(call cc-ifversion, -lt, 0701, y), y)
-IS_OLD_GCC = 1
-endif
-endif
-
-ifdef CONFIG_X86
-ifdef IS_OLD_GCC
-# Stack alignment mismatch, proceed with caution.
-# GCC < 7.1 cannot compile code using `double` and -mpreferred-stack-boundary=3
-# (8B stack alignment).
-CFLAGS_$(AMDDALPATH)/dc/dcn21/dcn21_resource.o += -mpreferred-stack-boundary=4
-else
-CFLAGS_$(AMDDALPATH)/dc/dcn21/dcn21_resource.o += -msse2
-endif
-endif
-
AMD_DAL_DCN21 = $(addprefix $(AMDDALPATH)/dc/dcn21/,$(DCN21))
AMD_DISPLAY_FILES += $(AMD_DAL_DCN21)
diff --git a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c
index e5cc6bf45743..612732656772 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c
@@ -34,6 +34,7 @@
#include "resource.h"
#include "include/irq_service_interface.h"
#include "dcn20/dcn20_resource.h"
+#include "dcn21/dcn21_resource.h"
#include "dml/dcn20/dcn20_fpu.h"
@@ -89,230 +90,6 @@
#include "dce/dmub_psr.h"
#include "dce/dmub_abm.h"
-#define DC_LOGGER_INIT(logger)
-
-
-struct _vcs_dpi_ip_params_st dcn2_1_ip = {
- .odm_capable = 1,
- .gpuvm_enable = 1,
- .hostvm_enable = 1,
- .gpuvm_max_page_table_levels = 1,
- .hostvm_max_page_table_levels = 4,
- .hostvm_cached_page_table_levels = 2,
- .num_dsc = 3,
- .rob_buffer_size_kbytes = 168,
- .det_buffer_size_kbytes = 164,
- .dpte_buffer_size_in_pte_reqs_luma = 44,
- .dpte_buffer_size_in_pte_reqs_chroma = 42,//todo
- .dpp_output_buffer_pixels = 2560,
- .opp_output_buffer_lines = 1,
- .pixel_chunk_size_kbytes = 8,
- .pte_enable = 1,
- .max_page_table_levels = 4,
- .pte_chunk_size_kbytes = 2,
- .meta_chunk_size_kbytes = 2,
- .min_meta_chunk_size_bytes = 256,
- .writeback_chunk_size_kbytes = 2,
- .line_buffer_size_bits = 789504,
- .is_line_buffer_bpp_fixed = 0,
- .line_buffer_fixed_bpp = 0,
- .dcc_supported = true,
- .max_line_buffer_lines = 12,
- .writeback_luma_buffer_size_kbytes = 12,
- .writeback_chroma_buffer_size_kbytes = 8,
- .writeback_chroma_line_buffer_width_pixels = 4,
- .writeback_max_hscl_ratio = 1,
- .writeback_max_vscl_ratio = 1,
- .writeback_min_hscl_ratio = 1,
- .writeback_min_vscl_ratio = 1,
- .writeback_max_hscl_taps = 12,
- .writeback_max_vscl_taps = 12,
- .writeback_line_buffer_luma_buffer_size = 0,
- .writeback_line_buffer_chroma_buffer_size = 14643,
- .cursor_buffer_size = 8,
- .cursor_chunk_size = 2,
- .max_num_otg = 4,
- .max_num_dpp = 4,
- .max_num_wb = 1,
- .max_dchub_pscl_bw_pix_per_clk = 4,
- .max_pscl_lb_bw_pix_per_clk = 2,
- .max_lb_vscl_bw_pix_per_clk = 4,
- .max_vscl_hscl_bw_pix_per_clk = 4,
- .max_hscl_ratio = 4,
- .max_vscl_ratio = 4,
- .hscl_mults = 4,
- .vscl_mults = 4,
- .max_hscl_taps = 8,
- .max_vscl_taps = 8,
- .dispclk_ramp_margin_percent = 1,
- .underscan_factor = 1.10,
- .min_vblank_lines = 32, //
- .dppclk_delay_subtotal = 77, //
- .dppclk_delay_scl_lb_only = 16,
- .dppclk_delay_scl = 50,
- .dppclk_delay_cnvc_formatter = 8,
- .dppclk_delay_cnvc_cursor = 6,
- .dispclk_delay_subtotal = 87, //
- .dcfclk_cstate_latency = 10, // SRExitTime
- .max_inter_dcn_tile_repeaters = 8,
-
- .xfc_supported = false,
- .xfc_fill_bw_overhead_percent = 10.0,
- .xfc_fill_constant_bytes = 0,
- .ptoi_supported = 0,
- .number_of_cursors = 1,
-};
-
-struct _vcs_dpi_soc_bounding_box_st dcn2_1_soc = {
- .clock_limits = {
- {
- .state = 0,
- .dcfclk_mhz = 400.0,
- .fabricclk_mhz = 400.0,
- .dispclk_mhz = 600.0,
- .dppclk_mhz = 400.00,
- .phyclk_mhz = 600.0,
- .socclk_mhz = 278.0,
- .dscclk_mhz = 205.67,
- .dram_speed_mts = 1600.0,
- },
- {
- .state = 1,
- .dcfclk_mhz = 464.52,
- .fabricclk_mhz = 800.0,
- .dispclk_mhz = 654.55,
- .dppclk_mhz = 626.09,
- .phyclk_mhz = 600.0,
- .socclk_mhz = 278.0,
- .dscclk_mhz = 205.67,
- .dram_speed_mts = 1600.0,
- },
- {
- .state = 2,
- .dcfclk_mhz = 514.29,
- .fabricclk_mhz = 933.0,
- .dispclk_mhz = 757.89,
- .dppclk_mhz = 685.71,
- .phyclk_mhz = 600.0,
- .socclk_mhz = 278.0,
- .dscclk_mhz = 287.67,
- .dram_speed_mts = 1866.0,
- },
- {
- .state = 3,
- .dcfclk_mhz = 576.00,
- .fabricclk_mhz = 1067.0,
- .dispclk_mhz = 847.06,
- .dppclk_mhz = 757.89,
- .phyclk_mhz = 600.0,
- .socclk_mhz = 715.0,
- .dscclk_mhz = 318.334,
- .dram_speed_mts = 2134.0,
- },
- {
- .state = 4,
- .dcfclk_mhz = 626.09,
- .fabricclk_mhz = 1200.0,
- .dispclk_mhz = 900.00,
- .dppclk_mhz = 847.06,
- .phyclk_mhz = 810.0,
- .socclk_mhz = 953.0,
- .dscclk_mhz = 489.0,
- .dram_speed_mts = 2400.0,
- },
- {
- .state = 5,
- .dcfclk_mhz = 685.71,
- .fabricclk_mhz = 1333.0,
- .dispclk_mhz = 1028.57,
- .dppclk_mhz = 960.00,
- .phyclk_mhz = 810.0,
- .socclk_mhz = 278.0,
- .dscclk_mhz = 287.67,
- .dram_speed_mts = 2666.0,
- },
- {
- .state = 6,
- .dcfclk_mhz = 757.89,
- .fabricclk_mhz = 1467.0,
- .dispclk_mhz = 1107.69,
- .dppclk_mhz = 1028.57,
- .phyclk_mhz = 810.0,
- .socclk_mhz = 715.0,
- .dscclk_mhz = 318.334,
- .dram_speed_mts = 3200.0,
- },
- {
- .state = 7,
- .dcfclk_mhz = 847.06,
- .fabricclk_mhz = 1600.0,
- .dispclk_mhz = 1395.0,
- .dppclk_mhz = 1285.00,
- .phyclk_mhz = 1325.0,
- .socclk_mhz = 953.0,
- .dscclk_mhz = 489.0,
- .dram_speed_mts = 4266.0,
- },
- /*Extra state, no dispclk ramping*/
- {
- .state = 8,
- .dcfclk_mhz = 847.06,
- .fabricclk_mhz = 1600.0,
- .dispclk_mhz = 1395.0,
- .dppclk_mhz = 1285.0,
- .phyclk_mhz = 1325.0,
- .socclk_mhz = 953.0,
- .dscclk_mhz = 489.0,
- .dram_speed_mts = 4266.0,
- },
-
- },
-
- .sr_exit_time_us = 12.5,
- .sr_enter_plus_exit_time_us = 17.0,
- .urgent_latency_us = 4.0,
- .urgent_latency_pixel_data_only_us = 4.0,
- .urgent_latency_pixel_mixed_with_vm_data_us = 4.0,
- .urgent_latency_vm_data_only_us = 4.0,
- .urgent_out_of_order_return_per_channel_pixel_only_bytes = 4096,
- .urgent_out_of_order_return_per_channel_pixel_and_vm_bytes = 4096,
- .urgent_out_of_order_return_per_channel_vm_only_bytes = 4096,
- .pct_ideal_dram_sdp_bw_after_urgent_pixel_only = 80.0,
- .pct_ideal_dram_sdp_bw_after_urgent_pixel_and_vm = 75.0,
- .pct_ideal_dram_sdp_bw_after_urgent_vm_only = 40.0,
- .max_avg_sdp_bw_use_normal_percent = 60.0,
- .max_avg_dram_bw_use_normal_percent = 100.0,
- .writeback_latency_us = 12.0,
- .max_request_size_bytes = 256,
- .dram_channel_width_bytes = 4,
- .fabric_datapath_to_dcn_data_return_bytes = 32,
- .dcn_downspread_percent = 0.5,
- .downspread_percent = 0.38,
- .dram_page_open_time_ns = 50.0,
- .dram_rw_turnaround_time_ns = 17.5,
- .dram_return_buffer_per_channel_bytes = 8192,
- .round_trip_ping_latency_dcfclk_cycles = 128,
- .urgent_out_of_order_return_per_channel_bytes = 4096,
- .channel_interleave_bytes = 256,
- .num_banks = 8,
- .num_chans = 4,
- .vmm_page_size_bytes = 4096,
- .dram_clock_change_latency_us = 23.84,
- .return_bus_width_bytes = 64,
- .dispclk_dppclk_vco_speed_mhz = 3600,
- .xfc_bus_transport_time_us = 4,
- .xfc_xbuf_latency_tolerance_us = 4,
- .use_urgent_burst_bw = 1,
- .num_states = 8
-};
-
-#ifndef MAX
-#define MAX(X, Y) ((X) > (Y) ? (X) : (Y))
-#endif
-#ifndef MIN
-#define MIN(X, Y) ((X) < (Y) ? (X) : (Y))
-#endif
-
/* begin *********************
* macros to expend register list macro defined in HW object header file */
@@ -705,12 +482,6 @@ static const struct dcn10_stream_encoder_mask se_mask = {
static void dcn21_pp_smu_destroy(struct pp_smu_funcs **pp_smu);
-static int dcn21_populate_dml_pipes_from_context(
- struct dc *dc,
- struct dc_state *context,
- display_e2e_pipe_params_st *pipes,
- bool fast_validate);
-
static struct input_pixel_processor *dcn21_ipp_create(
struct dc_context *ctx, uint32_t inst)
{
@@ -1029,163 +800,13 @@ static void dcn21_resource_destruct(struct dcn21_resource_pool *pool)
dcn21_pp_smu_destroy(&pool->base.pp_smu);
}
-
-static void calculate_wm_set_for_vlevel(
- int vlevel,
- struct wm_range_table_entry *table_entry,
- struct dcn_watermarks *wm_set,
- struct display_mode_lib *dml,
- display_e2e_pipe_params_st *pipes,
- int pipe_cnt)
-{
- double dram_clock_change_latency_cached = dml->soc.dram_clock_change_latency_us;
-
- ASSERT(vlevel < dml->soc.num_states);
- /* only pipe 0 is read for voltage and dcf/soc clocks */
- pipes[0].clks_cfg.voltage = vlevel;
- pipes[0].clks_cfg.dcfclk_mhz = dml->soc.clock_limits[vlevel].dcfclk_mhz;
- pipes[0].clks_cfg.socclk_mhz = dml->soc.clock_limits[vlevel].socclk_mhz;
-
- dml->soc.dram_clock_change_latency_us = table_entry->pstate_latency_us;
- dml->soc.sr_exit_time_us = table_entry->sr_exit_time_us;
- dml->soc.sr_enter_plus_exit_time_us = table_entry->sr_enter_plus_exit_time_us;
-
- wm_set->urgent_ns = get_wm_urgent(dml, pipes, pipe_cnt) * 1000;
- wm_set->cstate_pstate.cstate_enter_plus_exit_ns = get_wm_stutter_enter_exit(dml, pipes, pipe_cnt) * 1000;
- wm_set->cstate_pstate.cstate_exit_ns = get_wm_stutter_exit(dml, pipes, pipe_cnt) * 1000;
- wm_set->cstate_pstate.pstate_change_ns = get_wm_dram_clock_change(dml, pipes, pipe_cnt) * 1000;
- wm_set->pte_meta_urgent_ns = get_wm_memory_trip(dml, pipes, pipe_cnt) * 1000;
- wm_set->frac_urg_bw_nom = get_fraction_of_urgent_bandwidth(dml, pipes, pipe_cnt) * 1000;
- wm_set->frac_urg_bw_flip = get_fraction_of_urgent_bandwidth_imm_flip(dml, pipes, pipe_cnt) * 1000;
- wm_set->urgent_latency_ns = get_urgent_latency(dml, pipes, pipe_cnt) * 1000;
- dml->soc.dram_clock_change_latency_us = dram_clock_change_latency_cached;
-
-}
-
-static void patch_bounding_box(struct dc *dc, struct _vcs_dpi_soc_bounding_box_st *bb)
-{
- int i;
-
- if (dc->bb_overrides.sr_exit_time_ns) {
- for (i = 0; i < WM_SET_COUNT; i++) {
- dc->clk_mgr->bw_params->wm_table.entries[i].sr_exit_time_us =
- dc->bb_overrides.sr_exit_time_ns / 1000.0;
- }
- }
-
- if (dc->bb_overrides.sr_enter_plus_exit_time_ns) {
- for (i = 0; i < WM_SET_COUNT; i++) {
- dc->clk_mgr->bw_params->wm_table.entries[i].sr_enter_plus_exit_time_us =
- dc->bb_overrides.sr_enter_plus_exit_time_ns / 1000.0;
- }
- }
-
- if (dc->bb_overrides.urgent_latency_ns) {
- bb->urgent_latency_us = dc->bb_overrides.urgent_latency_ns / 1000.0;
- }
-
- if (dc->bb_overrides.dram_clock_change_latency_ns) {
- for (i = 0; i < WM_SET_COUNT; i++) {
- dc->clk_mgr->bw_params->wm_table.entries[i].pstate_latency_us =
- dc->bb_overrides.dram_clock_change_latency_ns / 1000.0;
- }
- }
-}
-
-static void dcn21_calculate_wm(
- struct dc *dc, struct dc_state *context,
- display_e2e_pipe_params_st *pipes,
- int *out_pipe_cnt,
- int *pipe_split_from,
- int vlevel_req,
- bool fast_validate)
-{
- int pipe_cnt, i, pipe_idx;
- int vlevel, vlevel_max;
- struct wm_range_table_entry *table_entry;
- struct clk_bw_params *bw_params = dc->clk_mgr->bw_params;
-
- ASSERT(bw_params);
-
- patch_bounding_box(dc, &context->bw_ctx.dml.soc);
-
- for (i = 0, pipe_idx = 0, pipe_cnt = 0; i < dc->res_pool->pipe_count; i++) {
- if (!context->res_ctx.pipe_ctx[i].stream)
- continue;
-
- pipes[pipe_cnt].clks_cfg.refclk_mhz = dc->res_pool->ref_clocks.dchub_ref_clock_inKhz / 1000.0;
- pipes[pipe_cnt].clks_cfg.dispclk_mhz = context->bw_ctx.dml.vba.RequiredDISPCLK[vlevel_req][context->bw_ctx.dml.vba.maxMpcComb];
-
- if (pipe_split_from[i] < 0) {
- pipes[pipe_cnt].clks_cfg.dppclk_mhz =
- context->bw_ctx.dml.vba.RequiredDPPCLK[vlevel_req][context->bw_ctx.dml.vba.maxMpcComb][pipe_idx];
- if (context->bw_ctx.dml.vba.BlendingAndTiming[pipe_idx] == pipe_idx)
- pipes[pipe_cnt].pipe.dest.odm_combine =
- context->bw_ctx.dml.vba.ODMCombineEnablePerState[vlevel_req][pipe_idx];
- else
- pipes[pipe_cnt].pipe.dest.odm_combine = 0;
- pipe_idx++;
- } else {
- pipes[pipe_cnt].clks_cfg.dppclk_mhz =
- context->bw_ctx.dml.vba.RequiredDPPCLK[vlevel_req][context->bw_ctx.dml.vba.maxMpcComb][pipe_split_from[i]];
- if (context->bw_ctx.dml.vba.BlendingAndTiming[pipe_split_from[i]] == pipe_split_from[i])
- pipes[pipe_cnt].pipe.dest.odm_combine =
- context->bw_ctx.dml.vba.ODMCombineEnablePerState[vlevel_req][pipe_split_from[i]];
- else
- pipes[pipe_cnt].pipe.dest.odm_combine = 0;
- }
- pipe_cnt++;
- }
-
- if (pipe_cnt != pipe_idx) {
- if (dc->res_pool->funcs->populate_dml_pipes)
- pipe_cnt = dc->res_pool->funcs->populate_dml_pipes(dc,
- context, pipes, fast_validate);
- else
- pipe_cnt = dcn21_populate_dml_pipes_from_context(dc,
- context, pipes, fast_validate);
- }
-
- *out_pipe_cnt = pipe_cnt;
-
- vlevel_max = bw_params->clk_table.num_entries - 1;
-
-
- /* WM Set D */
- table_entry = &bw_params->wm_table.entries[WM_D];
- if (table_entry->wm_type == WM_TYPE_RETRAINING)
- vlevel = 0;
- else
- vlevel = vlevel_max;
- calculate_wm_set_for_vlevel(vlevel, table_entry, &context->bw_ctx.bw.dcn.watermarks.d,
- &context->bw_ctx.dml, pipes, pipe_cnt);
- /* WM Set C */
- table_entry = &bw_params->wm_table.entries[WM_C];
- vlevel = MIN(MAX(vlevel_req, 3), vlevel_max);
- calculate_wm_set_for_vlevel(vlevel, table_entry, &context->bw_ctx.bw.dcn.watermarks.c,
- &context->bw_ctx.dml, pipes, pipe_cnt);
- /* WM Set B */
- table_entry = &bw_params->wm_table.entries[WM_B];
- vlevel = MIN(MAX(vlevel_req, 2), vlevel_max);
- calculate_wm_set_for_vlevel(vlevel, table_entry, &context->bw_ctx.bw.dcn.watermarks.b,
- &context->bw_ctx.dml, pipes, pipe_cnt);
-
- /* WM Set A */
- table_entry = &bw_params->wm_table.entries[WM_A];
- vlevel = MIN(vlevel_req, vlevel_max);
- calculate_wm_set_for_vlevel(vlevel, table_entry, &context->bw_ctx.bw.dcn.watermarks.a,
- &context->bw_ctx.dml, pipes, pipe_cnt);
-}
-
-
-static bool dcn21_fast_validate_bw(
- struct dc *dc,
- struct dc_state *context,
- display_e2e_pipe_params_st *pipes,
- int *pipe_cnt_out,
- int *pipe_split_from,
- int *vlevel_out,
- bool fast_validate)
+bool dcn21_fast_validate_bw(struct dc *dc,
+ struct dc_state *context,
+ display_e2e_pipe_params_st *pipes,
+ int *pipe_cnt_out,
+ int *pipe_split_from,
+ int *vlevel_out,
+ bool fast_validate)
{
bool out = false;
int split[MAX_PIPES] = { 0 };
@@ -1197,7 +818,9 @@ static bool dcn21_fast_validate_bw(
dcn20_merge_pipes_for_validate(dc, context);
+ DC_FP_START();
pipe_cnt = dc->res_pool->funcs->populate_dml_pipes(dc, context, pipes, fast_validate);
+ DC_FP_END();
*pipe_cnt_out = pipe_cnt;
@@ -1287,7 +910,9 @@ static bool dcn21_fast_validate_bw(
hsplit_pipe = dcn20_find_secondary_pipe(dc, &context->res_ctx, dc->res_pool, pipe);
ASSERT(hsplit_pipe);
if (!hsplit_pipe) {
- context->bw_ctx.dml.vba.RequiredDPPCLK[vlevel][context->bw_ctx.dml.vba.maxMpcComb][pipe_idx] *= 2;
+ DC_FP_START();
+ dcn20_fpu_adjust_dppclk(&context->bw_ctx.dml.vba, vlevel, context->bw_ctx.dml.vba.maxMpcComb, pipe_idx, true);
+ DC_FP_END();
continue;
}
if (context->bw_ctx.dml.vba.ODMCombineEnabled[pipe_idx]) {
@@ -1329,61 +954,6 @@ validate_out:
return out;
}
-static noinline bool dcn21_validate_bandwidth_fp(struct dc *dc,
- struct dc_state *context, bool fast_validate)
-{
- bool out = false;
-
- BW_VAL_TRACE_SETUP();
-
- int vlevel = 0;
- int pipe_split_from[MAX_PIPES];
- int pipe_cnt = 0;
- display_e2e_pipe_params_st *pipes = kzalloc(dc->res_pool->pipe_count * sizeof(display_e2e_pipe_params_st), GFP_ATOMIC);
- DC_LOGGER_INIT(dc->ctx->logger);
-
- BW_VAL_TRACE_COUNT();
-
- /*Unsafe due to current pipe merge and split logic*/
- ASSERT(context != dc->current_state);
-
- out = dcn21_fast_validate_bw(dc, context, pipes, &pipe_cnt, pipe_split_from, &vlevel, fast_validate);
-
- if (pipe_cnt == 0)
- goto validate_out;
-
- if (!out)
- goto validate_fail;
-
- BW_VAL_TRACE_END_VOLTAGE_LEVEL();
-
- if (fast_validate) {
- BW_VAL_TRACE_SKIP(fast);
- goto validate_out;
- }
-
- dcn21_calculate_wm(dc, context, pipes, &pipe_cnt, pipe_split_from, vlevel, fast_validate);
- dcn20_calculate_dlg_params(dc, context, pipes, pipe_cnt, vlevel);
-
- BW_VAL_TRACE_END_WATERMARKS();
-
- goto validate_out;
-
-validate_fail:
- DC_LOG_WARNING("Mode Validation Warning: %s failed validation.\n",
- dml_get_status_message(context->bw_ctx.dml.vba.ValidationStatus[context->bw_ctx.dml.vba.soc.num_states]));
-
- BW_VAL_TRACE_SKIP(fail);
- out = false;
-
-validate_out:
- kfree(pipes);
-
- BW_VAL_TRACE_FINISH();
-
- return out;
-}
-
/*
* Some of the functions further below use the FPU, so we need to wrap this
* with DC_FP_START()/DC_FP_END(). Use the same approach as for
@@ -1558,94 +1128,6 @@ static struct display_stream_compressor *dcn21_dsc_create(struct dc_context *ctx
return &dsc->base;
}
-static struct _vcs_dpi_voltage_scaling_st construct_low_pstate_lvl(struct clk_limit_table *clk_table, unsigned int high_voltage_lvl)
-{
- struct _vcs_dpi_voltage_scaling_st low_pstate_lvl;
- int i;
-
- low_pstate_lvl.state = 1;
- low_pstate_lvl.dcfclk_mhz = clk_table->entries[0].dcfclk_mhz;
- low_pstate_lvl.fabricclk_mhz = clk_table->entries[0].fclk_mhz;
- low_pstate_lvl.socclk_mhz = clk_table->entries[0].socclk_mhz;
- low_pstate_lvl.dram_speed_mts = clk_table->entries[0].memclk_mhz * 2;
-
- low_pstate_lvl.dispclk_mhz = dcn2_1_soc.clock_limits[high_voltage_lvl].dispclk_mhz;
- low_pstate_lvl.dppclk_mhz = dcn2_1_soc.clock_limits[high_voltage_lvl].dppclk_mhz;
- low_pstate_lvl.dram_bw_per_chan_gbps = dcn2_1_soc.clock_limits[high_voltage_lvl].dram_bw_per_chan_gbps;
- low_pstate_lvl.dscclk_mhz = dcn2_1_soc.clock_limits[high_voltage_lvl].dscclk_mhz;
- low_pstate_lvl.dtbclk_mhz = dcn2_1_soc.clock_limits[high_voltage_lvl].dtbclk_mhz;
- low_pstate_lvl.phyclk_d18_mhz = dcn2_1_soc.clock_limits[high_voltage_lvl].phyclk_d18_mhz;
- low_pstate_lvl.phyclk_mhz = dcn2_1_soc.clock_limits[high_voltage_lvl].phyclk_mhz;
-
- for (i = clk_table->num_entries; i > 1; i--)
- clk_table->entries[i] = clk_table->entries[i-1];
- clk_table->entries[1] = clk_table->entries[0];
- clk_table->num_entries++;
-
- return low_pstate_lvl;
-}
-
-static void update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_params)
-{
- struct dcn21_resource_pool *pool = TO_DCN21_RES_POOL(dc->res_pool);
- struct clk_limit_table *clk_table = &bw_params->clk_table;
- struct _vcs_dpi_voltage_scaling_st clock_limits[DC__VOLTAGE_STATES];
- unsigned int i, closest_clk_lvl = 0, k = 0;
- int j;
-
- dcn2_1_ip.max_num_otg = pool->base.res_cap->num_timing_generator;
- dcn2_1_ip.max_num_dpp = pool->base.pipe_count;
- dcn2_1_soc.num_chans = bw_params->num_channels;
-
- ASSERT(clk_table->num_entries);
- /* Copy dcn2_1_soc.clock_limits to clock_limits to avoid copying over null states later */
- for (i = 0; i < dcn2_1_soc.num_states + 1; i++) {
- clock_limits[i] = dcn2_1_soc.clock_limits[i];
- }
-
- for (i = 0; i < clk_table->num_entries; i++) {
- /* loop backwards*/
- for (closest_clk_lvl = 0, j = dcn2_1_soc.num_states - 1; j >= 0; j--) {
- if ((unsigned int) dcn2_1_soc.clock_limits[j].dcfclk_mhz <= clk_table->entries[i].dcfclk_mhz) {
- closest_clk_lvl = j;
- break;
- }
- }
-
- /* clk_table[1] is reserved for min DF PState. skip here to fill in later. */
- if (i == 1)
- k++;
-
- clock_limits[k].state = k;
- clock_limits[k].dcfclk_mhz = clk_table->entries[i].dcfclk_mhz;
- clock_limits[k].fabricclk_mhz = clk_table->entries[i].fclk_mhz;
- clock_limits[k].socclk_mhz = clk_table->entries[i].socclk_mhz;
- clock_limits[k].dram_speed_mts = clk_table->entries[i].memclk_mhz * 2;
-
- clock_limits[k].dispclk_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].dispclk_mhz;
- clock_limits[k].dppclk_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].dppclk_mhz;
- clock_limits[k].dram_bw_per_chan_gbps = dcn2_1_soc.clock_limits[closest_clk_lvl].dram_bw_per_chan_gbps;
- clock_limits[k].dscclk_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].dscclk_mhz;
- clock_limits[k].dtbclk_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].dtbclk_mhz;
- clock_limits[k].phyclk_d18_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].phyclk_d18_mhz;
- clock_limits[k].phyclk_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].phyclk_mhz;
-
- k++;
- }
- for (i = 0; i < clk_table->num_entries + 1; i++)
- dcn2_1_soc.clock_limits[i] = clock_limits[i];
- if (clk_table->num_entries) {
- dcn2_1_soc.num_states = clk_table->num_entries + 1;
- /* fill in min DF PState */
- dcn2_1_soc.clock_limits[1] = construct_low_pstate_lvl(clk_table, closest_clk_lvl);
- /* duplicate last level */
- dcn2_1_soc.clock_limits[dcn2_1_soc.num_states] = dcn2_1_soc.clock_limits[dcn2_1_soc.num_states - 1];
- dcn2_1_soc.clock_limits[dcn2_1_soc.num_states].state = dcn2_1_soc.num_states;
- }
-
- dml_init_instance(&dc->dml, &dcn2_1_soc, &dcn2_1_ip, DML_PROJECT_DCN21);
-}
-
static struct pp_smu_funcs *dcn21_pp_smu_create(struct dc_context *ctx)
{
struct pp_smu_funcs *pp_smu = kzalloc(sizeof(*pp_smu), GFP_KERNEL);
@@ -1896,24 +1378,6 @@ static uint32_t read_pipe_fuses(struct dc_context *ctx)
return value;
}
-static int dcn21_populate_dml_pipes_from_context(
- struct dc *dc,
- struct dc_state *context,
- display_e2e_pipe_params_st *pipes,
- bool fast_validate)
-{
- uint32_t pipe_cnt = dcn20_populate_dml_pipes_from_context(dc, context, pipes, fast_validate);
- int i;
-
- for (i = 0; i < pipe_cnt; i++) {
-
- pipes[i].pipe.src.hostvm = dc->res_pool->hubbub->riommu_active;
- pipes[i].pipe.src.gpuvm = 1;
- }
-
- return pipe_cnt;
-}
-
static enum dc_status dcn21_patch_unknown_plane_state(struct dc_plane_state *plane_state)
{
enum dc_status result = DC_OK;
@@ -1941,7 +1405,7 @@ static const struct resource_funcs dcn21_res_pool_funcs = {
.patch_unknown_plane_state = dcn21_patch_unknown_plane_state,
.set_mcif_arb_params = dcn20_set_mcif_arb_params,
.find_first_free_match_stream_enc_for_link = dcn10_find_first_free_match_stream_enc_for_link,
- .update_bw_bounding_box = update_bw_bounding_box
+ .update_bw_bounding_box = dcn21_update_bw_bounding_box,
};
static bool dcn21_resource_construct(
diff --git a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.h b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.h
index a27355171bca..f7ecc002c2f7 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.h
+++ b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.h
@@ -35,11 +35,22 @@ struct dc;
struct resource_pool;
struct _vcs_dpi_display_pipe_params_st;
+extern struct _vcs_dpi_ip_params_st dcn2_1_ip;
+extern struct _vcs_dpi_soc_bounding_box_st dcn2_1_soc;
+
struct dcn21_resource_pool {
struct resource_pool base;
};
struct resource_pool *dcn21_create_resource_pool(
const struct dc_init_data *init_data,
struct dc *dc);
+bool dcn21_fast_validate_bw(
+ struct dc *dc,
+ struct dc_state *context,
+ display_e2e_pipe_params_st *pipes,
+ int *pipe_cnt_out,
+ int *pipe_split_from,
+ int *vlevel_out,
+ bool fast_validate);
#endif /* _DCN21_RESOURCE_H_ */
diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dio_stream_encoder.c b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dio_stream_encoder.c
index 8daa12730bc1..a04ca4a98392 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dio_stream_encoder.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dio_stream_encoder.c
@@ -789,8 +789,6 @@ static const struct stream_encoder_funcs dcn30_str_enc_funcs = {
enc3_stream_encoder_update_dp_info_packets,
.stop_dp_info_packets =
enc1_stream_encoder_stop_dp_info_packets,
- .reset_fifo =
- enc1_stream_encoder_reset_fifo,
.dp_blank =
enc1_stream_encoder_dp_blank,
.dp_unblank =
diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dpp_cm.c b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dpp_cm.c
index 387eec616162..87dbeca18984 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dpp_cm.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dpp_cm.c
@@ -408,6 +408,6 @@ void dpp3_cm_set_gamut_remap(
gamut_mode = 1;
//follow dcn2 approach for now - using only coefficient set A
- program_gamut_remap(dpp, arr_reg_val, GAMUT_REMAP_COEFF);
+ program_gamut_remap(dpp, arr_reg_val, gamut_mode);
}
}
diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hubbub.c b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hubbub.c
index f4414de96acc..152c9c5733f1 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hubbub.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hubbub.c
@@ -448,6 +448,7 @@ static const struct hubbub_funcs hubbub30_funcs = {
.program_watermarks = hubbub3_program_watermarks,
.allow_self_refresh_control = hubbub1_allow_self_refresh_control,
.is_allow_self_refresh_enabled = hubbub1_is_allow_self_refresh_enabled,
+ .verify_allow_pstate_change_high = hubbub1_verify_allow_pstate_change_high,
.force_wm_propagate_to_pipes = hubbub3_force_wm_propagate_to_pipes,
.force_pstate_change_control = hubbub3_force_pstate_change_control,
.init_watermarks = hubbub3_init_watermarks,
diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c
index 1db1ca19411d..ed0a0e5fd805 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c
@@ -545,8 +545,7 @@ void dcn30_init_hw(struct dc *dc)
hws->funcs.dsc_pg_control(hws, res_pool->dscs[i]->inst, false);
/* we want to turn off all dp displays before doing detection */
- if (dc->config.power_down_display_on_boot)
- dc_link_blank_all_dp_displays(dc);
+ dc_link_blank_all_dp_displays(dc);
/* If taking control over from VBIOS, we may want to optimize our first
* mode set, so we need to skip powering down pipes until we know which
@@ -554,7 +553,7 @@ void dcn30_init_hw(struct dc *dc)
* Otherwise, if taking control is not possible, we need to power
* everything down.
*/
- if (dcb->funcs->is_accelerated_mode(dcb) || dc->config.power_down_display_on_boot) {
+ if (dcb->funcs->is_accelerated_mode(dcb) || !dc->config.seamless_boot_edp_requested) {
hws->funcs.init_pipes(dc, dc->current_state);
if (dc->res_pool->hubbub->funcs->allow_self_refresh_control)
dc->res_pool->hubbub->funcs->allow_self_refresh_control(dc->res_pool->hubbub,
@@ -566,7 +565,7 @@ void dcn30_init_hw(struct dc *dc)
* To avoid this, power down hardware on boot
* if DIG is turned on and seamless boot not enabled
*/
- if (dc->config.power_down_display_on_boot) {
+ if (!dc->config.seamless_boot_edp_requested) {
struct dc_link *edp_links[MAX_NUM_EDP];
struct dc_link *edp_link = NULL;
diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c
index 602ec9a08549..e6a62cc75139 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c
@@ -72,8 +72,8 @@
#include "nbio/nbio_7_4_offset.h"
-#include "dcn/dpcs_3_0_0_offset.h"
-#include "dcn/dpcs_3_0_0_sh_mask.h"
+#include "dpcs/dpcs_3_0_0_offset.h"
+#include "dpcs/dpcs_3_0_0_sh_mask.h"
#include "mmhub/mmhub_2_0_0_offset.h"
#include "mmhub/mmhub_2_0_0_sh_mask.h"
@@ -1462,7 +1462,9 @@ int dcn30_populate_dml_pipes_from_context(
int i, pipe_cnt;
struct resource_context *res_ctx = &context->res_ctx;
+ DC_FP_START();
dcn20_populate_dml_pipes_from_context(dc, context, pipes, fast_validate);
+ DC_FP_END();
for (i = 0, pipe_cnt = 0; i < dc->res_pool->pipe_count; i++) {
if (!res_ctx->pipe_ctx[i].stream)
@@ -1731,7 +1733,10 @@ static bool init_soc_bounding_box(struct dc *dc,
loaded_ip->max_num_otg = pool->base.res_cap->num_timing_generator;
loaded_ip->max_num_dpp = pool->base.pipe_count;
loaded_ip->clamp_min_dcfclk = dc->config.clamp_min_dcfclk;
+
+ DC_FP_START();
dcn20_patch_bounding_box(dc, loaded_bb);
+ DC_FP_END();
if (dc->ctx->dc_bios->funcs->get_soc_bb_info) {
struct bp_soc_bb_info bb_info = {0};
@@ -1878,7 +1883,6 @@ noinline bool dcn30_internal_validate_bw(
dc->res_pool->funcs->update_soc_for_wm_a(dc, context);
pipe_cnt = dc->res_pool->funcs->populate_dml_pipes(dc, context, pipes, fast_validate);
- DC_FP_START();
if (!pipe_cnt) {
out = true;
goto validate_out;
@@ -2104,7 +2108,6 @@ validate_fail:
out = false;
validate_out:
- DC_FP_END();
return out;
}
@@ -2263,7 +2266,9 @@ static noinline void dcn30_calculate_wm_and_dlg_fp(
pipe_idx++;
}
+ DC_FP_START();
dcn20_calculate_dlg_params(dc, context, pipes, pipe_cnt, vlevel);
+ DC_FP_END();
if (!pstate_en)
/* Restore full p-state latency */
@@ -2306,7 +2311,9 @@ bool dcn30_validate_bandwidth(struct dc *dc,
BW_VAL_TRACE_COUNT();
+ DC_FP_START();
out = dcn30_internal_validate_bw(dc, context, pipes, &pipe_cnt, &vlevel, fast_validate);
+ DC_FP_END();
if (pipe_cnt == 0)
goto validate_out;
diff --git a/drivers/gpu/drm/amd/display/dc/dcn301/dcn301_hubbub.c b/drivers/gpu/drm/amd/display/dc/dcn301/dcn301_hubbub.c
index 1e3bd2e9cdcc..a046664e2031 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn301/dcn301_hubbub.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn301/dcn301_hubbub.c
@@ -60,6 +60,7 @@ static const struct hubbub_funcs hubbub301_funcs = {
.program_watermarks = hubbub3_program_watermarks,
.allow_self_refresh_control = hubbub1_allow_self_refresh_control,
.is_allow_self_refresh_enabled = hubbub1_is_allow_self_refresh_enabled,
+ .verify_allow_pstate_change_high = hubbub1_verify_allow_pstate_change_high,
.force_wm_propagate_to_pipes = hubbub3_force_wm_propagate_to_pipes,
.force_pstate_change_control = hubbub3_force_pstate_change_control,
.hubbub_read_state = hubbub2_read_state,
diff --git a/drivers/gpu/drm/amd/display/dc/dcn301/dcn301_resource.c b/drivers/gpu/drm/amd/display/dc/dcn301/dcn301_resource.c
index c1c6e602b06c..4daf8931aa7c 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn301/dcn301_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn301/dcn301_resource.c
@@ -73,8 +73,8 @@
#include "nbio/nbio_7_2_0_offset.h"
-#include "dcn/dpcs_3_0_0_offset.h"
-#include "dcn/dpcs_3_0_0_sh_mask.h"
+#include "dpcs/dpcs_3_0_0_offset.h"
+#include "dpcs/dpcs_3_0_0_sh_mask.h"
#include "reg_helper.h"
#include "dce/dmub_abm.h"
@@ -686,7 +686,7 @@ static const struct dc_debug_options debug_defaults_drv = {
.disable_clock_gate = true,
.disable_pplib_clock_request = true,
.disable_pplib_wm_range = true,
- .pipe_split_policy = MPC_SPLIT_DYNAMIC,
+ .pipe_split_policy = MPC_SPLIT_AVOID,
.force_single_disp_pipe_split = false,
.disable_dcc = DCC_ENABLE,
.vsr_support = true,
@@ -1380,6 +1380,17 @@ static void set_wm_ranges(
pp_smu->nv_funcs.set_wm_ranges(&pp_smu->nv_funcs.pp_smu, &ranges);
}
+static void dcn301_calculate_wm_and_dlg(
+ struct dc *dc, struct dc_state *context,
+ display_e2e_pipe_params_st *pipes,
+ int pipe_cnt,
+ int vlevel)
+{
+ DC_FP_START();
+ dcn301_calculate_wm_and_dlg_fp(dc, context, pipes, pipe_cnt, vlevel);
+ DC_FP_END();
+}
+
static struct resource_funcs dcn301_res_pool_funcs = {
.destroy = dcn301_destroy_resource_pool,
.link_enc_create = dcn301_link_encoder_create,
diff --git a/drivers/gpu/drm/amd/display/dc/dcn302/Makefile b/drivers/gpu/drm/amd/display/dc/dcn302/Makefile
index 101620a8867a..f9561d7f97a1 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn302/Makefile
+++ b/drivers/gpu/drm/amd/display/dc/dcn302/Makefile
@@ -1,11 +1,6 @@
#
# (c) Copyright 2020 Advanced Micro Devices, Inc. All the rights reserved
#
-# All rights reserved. This notice is intended as a precaution against
-# inadvertent publication and does not imply publication or any waiver
-# of confidentiality. The year included in the foregoing notice is the
-# year of creation of the work.
-#
# Authors: AMD
#
# Makefile for dcn302.
@@ -20,13 +15,6 @@ ifdef CONFIG_PPC64
CFLAGS_$(AMDDALPATH)/dc/dcn302/dcn302_resource.o := -mhard-float -maltivec
endif
-ifdef CONFIG_CC_IS_GCC
-ifeq ($(call cc-ifversion, -lt, 0701, y), y)
-IS_OLD_GCC = 1
-endif
-CFLAGS_$(AMDDALPATH)/dc/dcn302/dcn302_resource.o += -mhard-float
-endif
-
ifdef CONFIG_X86
ifdef IS_OLD_GCC
# Stack alignment mismatch, proceed with caution.
diff --git a/drivers/gpu/drm/amd/display/dc/dcn302/dcn302_resource.c b/drivers/gpu/drm/amd/display/dc/dcn302/dcn302_resource.c
index 2e9cbfa7663b..88318e8ffca8 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn302/dcn302_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn302/dcn302_resource.c
@@ -61,150 +61,18 @@
#include "resource.h"
#include "vm_helper.h"
+#include "dml/dcn302/dcn302_fpu.h"
+
#include "dimgrey_cavefish_ip_offset.h"
#include "dcn/dcn_3_0_2_offset.h"
#include "dcn/dcn_3_0_2_sh_mask.h"
-#include "dcn/dpcs_3_0_0_offset.h"
-#include "dcn/dpcs_3_0_0_sh_mask.h"
+#include "dpcs/dpcs_3_0_0_offset.h"
+#include "dpcs/dpcs_3_0_0_sh_mask.h"
#include "nbio/nbio_7_4_offset.h"
#include "amdgpu_socbb.h"
#define DC_LOGGER_INIT(logger)
-struct _vcs_dpi_ip_params_st dcn3_02_ip = {
- .use_min_dcfclk = 0,
- .clamp_min_dcfclk = 0,
- .odm_capable = 1,
- .gpuvm_enable = 1,
- .hostvm_enable = 0,
- .gpuvm_max_page_table_levels = 4,
- .hostvm_max_page_table_levels = 4,
- .hostvm_cached_page_table_levels = 0,
- .pte_group_size_bytes = 2048,
- .num_dsc = 5,
- .rob_buffer_size_kbytes = 184,
- .det_buffer_size_kbytes = 184,
- .dpte_buffer_size_in_pte_reqs_luma = 64,
- .dpte_buffer_size_in_pte_reqs_chroma = 34,
- .pde_proc_buffer_size_64k_reqs = 48,
- .dpp_output_buffer_pixels = 2560,
- .opp_output_buffer_lines = 1,
- .pixel_chunk_size_kbytes = 8,
- .pte_enable = 1,
- .max_page_table_levels = 2,
- .pte_chunk_size_kbytes = 2, // ?
- .meta_chunk_size_kbytes = 2,
- .writeback_chunk_size_kbytes = 8,
- .line_buffer_size_bits = 789504,
- .is_line_buffer_bpp_fixed = 0, // ?
- .line_buffer_fixed_bpp = 0, // ?
- .dcc_supported = true,
- .writeback_interface_buffer_size_kbytes = 90,
- .writeback_line_buffer_buffer_size = 0,
- .max_line_buffer_lines = 12,
- .writeback_luma_buffer_size_kbytes = 12, // writeback_line_buffer_buffer_size = 656640
- .writeback_chroma_buffer_size_kbytes = 8,
- .writeback_chroma_line_buffer_width_pixels = 4,
- .writeback_max_hscl_ratio = 1,
- .writeback_max_vscl_ratio = 1,
- .writeback_min_hscl_ratio = 1,
- .writeback_min_vscl_ratio = 1,
- .writeback_max_hscl_taps = 1,
- .writeback_max_vscl_taps = 1,
- .writeback_line_buffer_luma_buffer_size = 0,
- .writeback_line_buffer_chroma_buffer_size = 14643,
- .cursor_buffer_size = 8,
- .cursor_chunk_size = 2,
- .max_num_otg = 5,
- .max_num_dpp = 5,
- .max_num_wb = 1,
- .max_dchub_pscl_bw_pix_per_clk = 4,
- .max_pscl_lb_bw_pix_per_clk = 2,
- .max_lb_vscl_bw_pix_per_clk = 4,
- .max_vscl_hscl_bw_pix_per_clk = 4,
- .max_hscl_ratio = 6,
- .max_vscl_ratio = 6,
- .hscl_mults = 4,
- .vscl_mults = 4,
- .max_hscl_taps = 8,
- .max_vscl_taps = 8,
- .dispclk_ramp_margin_percent = 1,
- .underscan_factor = 1.11,
- .min_vblank_lines = 32,
- .dppclk_delay_subtotal = 46,
- .dynamic_metadata_vm_enabled = true,
- .dppclk_delay_scl_lb_only = 16,
- .dppclk_delay_scl = 50,
- .dppclk_delay_cnvc_formatter = 27,
- .dppclk_delay_cnvc_cursor = 6,
- .dispclk_delay_subtotal = 119,
- .dcfclk_cstate_latency = 5.2, // SRExitTime
- .max_inter_dcn_tile_repeaters = 8,
- .max_num_hdmi_frl_outputs = 1,
- .odm_combine_4to1_supported = true,
-
- .xfc_supported = false,
- .xfc_fill_bw_overhead_percent = 10.0,
- .xfc_fill_constant_bytes = 0,
- .gfx7_compat_tiling_supported = 0,
- .number_of_cursors = 1,
-};
-
-struct _vcs_dpi_soc_bounding_box_st dcn3_02_soc = {
- .clock_limits = {
- {
- .state = 0,
- .dispclk_mhz = 562.0,
- .dppclk_mhz = 300.0,
- .phyclk_mhz = 300.0,
- .phyclk_d18_mhz = 667.0,
- .dscclk_mhz = 405.6,
- },
- },
-
- .min_dcfclk = 500.0, /* TODO: set this to actual min DCFCLK */
- .num_states = 1,
- .sr_exit_time_us = 26.5,
- .sr_enter_plus_exit_time_us = 31,
- .urgent_latency_us = 4.0,
- .urgent_latency_pixel_data_only_us = 4.0,
- .urgent_latency_pixel_mixed_with_vm_data_us = 4.0,
- .urgent_latency_vm_data_only_us = 4.0,
- .urgent_out_of_order_return_per_channel_pixel_only_bytes = 4096,
- .urgent_out_of_order_return_per_channel_pixel_and_vm_bytes = 4096,
- .urgent_out_of_order_return_per_channel_vm_only_bytes = 4096,
- .pct_ideal_dram_sdp_bw_after_urgent_pixel_only = 80.0,
- .pct_ideal_dram_sdp_bw_after_urgent_pixel_and_vm = 60.0,
- .pct_ideal_dram_sdp_bw_after_urgent_vm_only = 40.0,
- .max_avg_sdp_bw_use_normal_percent = 60.0,
- .max_avg_dram_bw_use_normal_percent = 40.0,
- .writeback_latency_us = 12.0,
- .max_request_size_bytes = 256,
- .fabric_datapath_to_dcn_data_return_bytes = 64,
- .dcn_downspread_percent = 0.5,
- .downspread_percent = 0.38,
- .dram_page_open_time_ns = 50.0,
- .dram_rw_turnaround_time_ns = 17.5,
- .dram_return_buffer_per_channel_bytes = 8192,
- .round_trip_ping_latency_dcfclk_cycles = 156,
- .urgent_out_of_order_return_per_channel_bytes = 4096,
- .channel_interleave_bytes = 256,
- .num_banks = 8,
- .gpuvm_min_page_size_bytes = 4096,
- .hostvm_min_page_size_bytes = 4096,
- .dram_clock_change_latency_us = 404,
- .dummy_pstate_latency_us = 5,
- .writeback_dram_clock_change_latency_us = 23.0,
- .return_bus_width_bytes = 64,
- .dispclk_dppclk_vco_speed_mhz = 3650,
- .xfc_bus_transport_time_us = 20, // ?
- .xfc_xbuf_latency_tolerance_us = 4, // ?
- .use_urgent_burst_bw = 1, // ?
- .do_urgent_latency_adjustment = true,
- .urgent_latency_adjustment_fabric_clock_component_us = 1.0,
- .urgent_latency_adjustment_fabric_clock_reference_mhz = 1000,
-};
-
static const struct dc_debug_options debug_defaults_drv = {
.disable_dmcu = true,
.force_abm_enable = false,
@@ -1105,24 +973,19 @@ static bool init_soc_bounding_box(struct dc *dc, struct resource_pool *pool)
loaded_ip->max_num_otg = pool->pipe_count;
loaded_ip->max_num_dpp = pool->pipe_count;
loaded_ip->clamp_min_dcfclk = dc->config.clamp_min_dcfclk;
+ DC_FP_START();
dcn20_patch_bounding_box(dc, loaded_bb);
+ DC_FP_END();
if (dc->ctx->dc_bios->funcs->get_soc_bb_info) {
struct bp_soc_bb_info bb_info = { 0 };
if (dc->ctx->dc_bios->funcs->get_soc_bb_info(
dc->ctx->dc_bios, &bb_info) == BP_RESULT_OK) {
- if (bb_info.dram_clock_change_latency_100ns > 0)
- dcn3_02_soc.dram_clock_change_latency_us =
- bb_info.dram_clock_change_latency_100ns * 10;
- if (bb_info.dram_sr_enter_exit_latency_100ns > 0)
- dcn3_02_soc.sr_enter_plus_exit_time_us =
- bb_info.dram_sr_enter_exit_latency_100ns * 10;
-
- if (bb_info.dram_sr_exit_latency_100ns > 0)
- dcn3_02_soc.sr_exit_time_us =
- bb_info.dram_sr_exit_latency_100ns * 10;
+ DC_FP_START();
+ dcn302_fpu_init_soc_bounding_box(bb_info);
+ DC_FP_END();
}
}
@@ -1257,170 +1120,11 @@ static void dcn302_destroy_resource_pool(struct resource_pool **pool)
*pool = NULL;
}
-static void dcn302_get_optimal_dcfclk_fclk_for_uclk(unsigned int uclk_mts,
- unsigned int *optimal_dcfclk,
- unsigned int *optimal_fclk)
-{
- double bw_from_dram, bw_from_dram1, bw_from_dram2;
-
- bw_from_dram1 = uclk_mts * dcn3_02_soc.num_chans *
- dcn3_02_soc.dram_channel_width_bytes * (dcn3_02_soc.max_avg_dram_bw_use_normal_percent / 100);
- bw_from_dram2 = uclk_mts * dcn3_02_soc.num_chans *
- dcn3_02_soc.dram_channel_width_bytes * (dcn3_02_soc.max_avg_sdp_bw_use_normal_percent / 100);
-
- bw_from_dram = (bw_from_dram1 < bw_from_dram2) ? bw_from_dram1 : bw_from_dram2;
-
- if (optimal_fclk)
- *optimal_fclk = bw_from_dram /
- (dcn3_02_soc.fabric_datapath_to_dcn_data_return_bytes * (dcn3_02_soc.max_avg_sdp_bw_use_normal_percent / 100));
-
- if (optimal_dcfclk)
- *optimal_dcfclk = bw_from_dram /
- (dcn3_02_soc.return_bus_width_bytes * (dcn3_02_soc.max_avg_sdp_bw_use_normal_percent / 100));
-}
-
void dcn302_update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_params)
{
- unsigned int i, j;
- unsigned int num_states = 0;
-
- unsigned int dcfclk_mhz[DC__VOLTAGE_STATES] = {0};
- unsigned int dram_speed_mts[DC__VOLTAGE_STATES] = {0};
- unsigned int optimal_uclk_for_dcfclk_sta_targets[DC__VOLTAGE_STATES] = {0};
- unsigned int optimal_dcfclk_for_uclk[DC__VOLTAGE_STATES] = {0};
-
- unsigned int dcfclk_sta_targets[DC__VOLTAGE_STATES] = {694, 875, 1000, 1200};
- unsigned int num_dcfclk_sta_targets = 4;
- unsigned int num_uclk_states;
-
-
- if (dc->ctx->dc_bios->vram_info.num_chans)
- dcn3_02_soc.num_chans = dc->ctx->dc_bios->vram_info.num_chans;
-
- if (dc->ctx->dc_bios->vram_info.dram_channel_width_bytes)
- dcn3_02_soc.dram_channel_width_bytes = dc->ctx->dc_bios->vram_info.dram_channel_width_bytes;
-
- dcn3_02_soc.dispclk_dppclk_vco_speed_mhz = dc->clk_mgr->dentist_vco_freq_khz / 1000.0;
- dc->dml.soc.dispclk_dppclk_vco_speed_mhz = dc->clk_mgr->dentist_vco_freq_khz / 1000.0;
-
- if (bw_params->clk_table.entries[0].memclk_mhz) {
- int max_dcfclk_mhz = 0, max_dispclk_mhz = 0, max_dppclk_mhz = 0, max_phyclk_mhz = 0;
-
- for (i = 0; i < MAX_NUM_DPM_LVL; i++) {
- if (bw_params->clk_table.entries[i].dcfclk_mhz > max_dcfclk_mhz)
- max_dcfclk_mhz = bw_params->clk_table.entries[i].dcfclk_mhz;
- if (bw_params->clk_table.entries[i].dispclk_mhz > max_dispclk_mhz)
- max_dispclk_mhz = bw_params->clk_table.entries[i].dispclk_mhz;
- if (bw_params->clk_table.entries[i].dppclk_mhz > max_dppclk_mhz)
- max_dppclk_mhz = bw_params->clk_table.entries[i].dppclk_mhz;
- if (bw_params->clk_table.entries[i].phyclk_mhz > max_phyclk_mhz)
- max_phyclk_mhz = bw_params->clk_table.entries[i].phyclk_mhz;
- }
- if (!max_dcfclk_mhz)
- max_dcfclk_mhz = dcn3_02_soc.clock_limits[0].dcfclk_mhz;
- if (!max_dispclk_mhz)
- max_dispclk_mhz = dcn3_02_soc.clock_limits[0].dispclk_mhz;
- if (!max_dppclk_mhz)
- max_dppclk_mhz = dcn3_02_soc.clock_limits[0].dppclk_mhz;
- if (!max_phyclk_mhz)
- max_phyclk_mhz = dcn3_02_soc.clock_limits[0].phyclk_mhz;
-
- if (max_dcfclk_mhz > dcfclk_sta_targets[num_dcfclk_sta_targets-1]) {
- /* If max DCFCLK is greater than the max DCFCLK STA target, insert into the DCFCLK STA target array */
- dcfclk_sta_targets[num_dcfclk_sta_targets] = max_dcfclk_mhz;
- num_dcfclk_sta_targets++;
- } else if (max_dcfclk_mhz < dcfclk_sta_targets[num_dcfclk_sta_targets-1]) {
- /* If max DCFCLK is less than the max DCFCLK STA target, cap values and remove duplicates */
- for (i = 0; i < num_dcfclk_sta_targets; i++) {
- if (dcfclk_sta_targets[i] > max_dcfclk_mhz) {
- dcfclk_sta_targets[i] = max_dcfclk_mhz;
- break;
- }
- }
- /* Update size of array since we "removed" duplicates */
- num_dcfclk_sta_targets = i + 1;
- }
-
- num_uclk_states = bw_params->clk_table.num_entries;
-
- /* Calculate optimal dcfclk for each uclk */
- for (i = 0; i < num_uclk_states; i++) {
- dcn302_get_optimal_dcfclk_fclk_for_uclk(bw_params->clk_table.entries[i].memclk_mhz * 16,
- &optimal_dcfclk_for_uclk[i], NULL);
- if (optimal_dcfclk_for_uclk[i] < bw_params->clk_table.entries[0].dcfclk_mhz) {
- optimal_dcfclk_for_uclk[i] = bw_params->clk_table.entries[0].dcfclk_mhz;
- }
- }
-
- /* Calculate optimal uclk for each dcfclk sta target */
- for (i = 0; i < num_dcfclk_sta_targets; i++) {
- for (j = 0; j < num_uclk_states; j++) {
- if (dcfclk_sta_targets[i] < optimal_dcfclk_for_uclk[j]) {
- optimal_uclk_for_dcfclk_sta_targets[i] =
- bw_params->clk_table.entries[j].memclk_mhz * 16;
- break;
- }
- }
- }
-
- i = 0;
- j = 0;
- /* create the final dcfclk and uclk table */
- while (i < num_dcfclk_sta_targets && j < num_uclk_states && num_states < DC__VOLTAGE_STATES) {
- if (dcfclk_sta_targets[i] < optimal_dcfclk_for_uclk[j] && i < num_dcfclk_sta_targets) {
- dcfclk_mhz[num_states] = dcfclk_sta_targets[i];
- dram_speed_mts[num_states++] = optimal_uclk_for_dcfclk_sta_targets[i++];
- } else {
- if (j < num_uclk_states && optimal_dcfclk_for_uclk[j] <= max_dcfclk_mhz) {
- dcfclk_mhz[num_states] = optimal_dcfclk_for_uclk[j];
- dram_speed_mts[num_states++] = bw_params->clk_table.entries[j++].memclk_mhz * 16;
- } else {
- j = num_uclk_states;
- }
- }
- }
-
- while (i < num_dcfclk_sta_targets && num_states < DC__VOLTAGE_STATES) {
- dcfclk_mhz[num_states] = dcfclk_sta_targets[i];
- dram_speed_mts[num_states++] = optimal_uclk_for_dcfclk_sta_targets[i++];
- }
-
- while (j < num_uclk_states && num_states < DC__VOLTAGE_STATES &&
- optimal_dcfclk_for_uclk[j] <= max_dcfclk_mhz) {
- dcfclk_mhz[num_states] = optimal_dcfclk_for_uclk[j];
- dram_speed_mts[num_states++] = bw_params->clk_table.entries[j++].memclk_mhz * 16;
- }
-
- dcn3_02_soc.num_states = num_states;
- for (i = 0; i < dcn3_02_soc.num_states; i++) {
- dcn3_02_soc.clock_limits[i].state = i;
- dcn3_02_soc.clock_limits[i].dcfclk_mhz = dcfclk_mhz[i];
- dcn3_02_soc.clock_limits[i].fabricclk_mhz = dcfclk_mhz[i];
- dcn3_02_soc.clock_limits[i].dram_speed_mts = dram_speed_mts[i];
-
- /* Fill all states with max values of all other clocks */
- dcn3_02_soc.clock_limits[i].dispclk_mhz = max_dispclk_mhz;
- dcn3_02_soc.clock_limits[i].dppclk_mhz = max_dppclk_mhz;
- dcn3_02_soc.clock_limits[i].phyclk_mhz = max_phyclk_mhz;
- /* Populate from bw_params for DTBCLK, SOCCLK */
- if (!bw_params->clk_table.entries[i].dtbclk_mhz && i > 0)
- dcn3_02_soc.clock_limits[i].dtbclk_mhz = dcn3_02_soc.clock_limits[i-1].dtbclk_mhz;
- else
- dcn3_02_soc.clock_limits[i].dtbclk_mhz = bw_params->clk_table.entries[i].dtbclk_mhz;
- if (!bw_params->clk_table.entries[i].socclk_mhz && i > 0)
- dcn3_02_soc.clock_limits[i].socclk_mhz = dcn3_02_soc.clock_limits[i-1].socclk_mhz;
- else
- dcn3_02_soc.clock_limits[i].socclk_mhz = bw_params->clk_table.entries[i].socclk_mhz;
- /* These clocks cannot come from bw_params, always fill from dcn3_02_soc[1] */
- /* FCLK, PHYCLK_D18, DSCCLK */
- dcn3_02_soc.clock_limits[i].phyclk_d18_mhz = dcn3_02_soc.clock_limits[0].phyclk_d18_mhz;
- dcn3_02_soc.clock_limits[i].dscclk_mhz = dcn3_02_soc.clock_limits[0].dscclk_mhz;
- }
- /* re-init DML with updated bb */
- dml_init_instance(&dc->dml, &dcn3_02_soc, &dcn3_02_ip, DML_PROJECT_DCN30);
- if (dc->current_state)
- dml_init_instance(&dc->current_state->bw_ctx.dml, &dcn3_02_soc, &dcn3_02_ip, DML_PROJECT_DCN30);
- }
+ DC_FP_START();
+ dcn302_fpu_update_bw_bounding_box(dc, bw_params);
+ DC_FP_END();
}
static struct resource_funcs dcn302_res_pool_funcs = {
diff --git a/drivers/gpu/drm/amd/display/dc/dcn302/dcn302_resource.h b/drivers/gpu/drm/amd/display/dc/dcn302/dcn302_resource.h
index 42d2c73e30bc..9f24e73b92b3 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn302/dcn302_resource.h
+++ b/drivers/gpu/drm/amd/display/dc/dcn302/dcn302_resource.h
@@ -28,6 +28,9 @@
#include "core_types.h"
+extern struct _vcs_dpi_ip_params_st dcn3_02_ip;
+extern struct _vcs_dpi_soc_bounding_box_st dcn3_02_soc;
+
struct resource_pool *dcn302_create_resource_pool(const struct dc_init_data *init_data, struct dc *dc);
void dcn302_update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_params);
diff --git a/drivers/gpu/drm/amd/display/dc/dcn303/Makefile b/drivers/gpu/drm/amd/display/dc/dcn303/Makefile
index 6f7a1f2b49f0..8702e0b7fda3 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn303/Makefile
+++ b/drivers/gpu/drm/amd/display/dc/dcn303/Makefile
@@ -8,32 +8,6 @@
DCN3_03 = dcn303_init.o dcn303_hwseq.o dcn303_resource.o
-ifdef CONFIG_X86
-CFLAGS_$(AMDDALPATH)/dc/dcn303/dcn303_resource.o := -msse
-endif
-
-ifdef CONFIG_PPC64
-CFLAGS_$(AMDDALPATH)/dc/dcn303/dcn303_resource.o := -mhard-float -maltivec
-endif
-
-ifdef CONFIG_CC_IS_GCC
-ifeq ($(call cc-ifversion, -lt, 0701, y), y)
-IS_OLD_GCC = 1
-endif
-CFLAGS_$(AMDDALPATH)/dc/dcn303/dcn303_resource.o += -mhard-float
-endif
-
-ifdef CONFIG_X86
-ifdef IS_OLD_GCC
-# Stack alignment mismatch, proceed with caution.
-# GCC < 7.1 cannot compile code using `double` and -mpreferred-stack-boundary=3
-# (8B stack alignment).
-CFLAGS_$(AMDDALPATH)/dc/dcn303/dcn303_resource.o += -mpreferred-stack-boundary=4
-else
-CFLAGS_$(AMDDALPATH)/dc/dcn303/dcn303_resource.o += -msse2
-endif
-endif
-
AMD_DAL_DCN3_03 = $(addprefix $(AMDDALPATH)/dc/dcn303/,$(DCN3_03))
AMD_DISPLAY_FILES += $(AMD_DAL_DCN3_03)
diff --git a/drivers/gpu/drm/amd/display/dc/dcn303/dcn303_resource.c b/drivers/gpu/drm/amd/display/dc/dcn303/dcn303_resource.c
index 2de687f64cf6..4fcbc0502808 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn303/dcn303_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn303/dcn303_resource.c
@@ -48,144 +48,14 @@
#include "sienna_cichlid_ip_offset.h"
#include "dcn/dcn_3_0_3_offset.h"
#include "dcn/dcn_3_0_3_sh_mask.h"
-#include "dcn/dpcs_3_0_3_offset.h"
-#include "dcn/dpcs_3_0_3_sh_mask.h"
+#include "dpcs/dpcs_3_0_3_offset.h"
+#include "dpcs/dpcs_3_0_3_sh_mask.h"
#include "nbio/nbio_2_3_offset.h"
-#define DC_LOGGER_INIT(logger)
+#include "dml/dcn303/dcn303_fpu.h"
-struct _vcs_dpi_ip_params_st dcn3_03_ip = {
- .use_min_dcfclk = 0,
- .clamp_min_dcfclk = 0,
- .odm_capable = 1,
- .gpuvm_enable = 1,
- .hostvm_enable = 0,
- .gpuvm_max_page_table_levels = 4,
- .hostvm_max_page_table_levels = 4,
- .hostvm_cached_page_table_levels = 0,
- .pte_group_size_bytes = 2048,
- .num_dsc = 2,
- .rob_buffer_size_kbytes = 184,
- .det_buffer_size_kbytes = 184,
- .dpte_buffer_size_in_pte_reqs_luma = 64,
- .dpte_buffer_size_in_pte_reqs_chroma = 34,
- .pde_proc_buffer_size_64k_reqs = 48,
- .dpp_output_buffer_pixels = 2560,
- .opp_output_buffer_lines = 1,
- .pixel_chunk_size_kbytes = 8,
- .pte_enable = 1,
- .max_page_table_levels = 2,
- .pte_chunk_size_kbytes = 2, // ?
- .meta_chunk_size_kbytes = 2,
- .writeback_chunk_size_kbytes = 8,
- .line_buffer_size_bits = 789504,
- .is_line_buffer_bpp_fixed = 0, // ?
- .line_buffer_fixed_bpp = 0, // ?
- .dcc_supported = true,
- .writeback_interface_buffer_size_kbytes = 90,
- .writeback_line_buffer_buffer_size = 0,
- .max_line_buffer_lines = 12,
- .writeback_luma_buffer_size_kbytes = 12, // writeback_line_buffer_buffer_size = 656640
- .writeback_chroma_buffer_size_kbytes = 8,
- .writeback_chroma_line_buffer_width_pixels = 4,
- .writeback_max_hscl_ratio = 1,
- .writeback_max_vscl_ratio = 1,
- .writeback_min_hscl_ratio = 1,
- .writeback_min_vscl_ratio = 1,
- .writeback_max_hscl_taps = 1,
- .writeback_max_vscl_taps = 1,
- .writeback_line_buffer_luma_buffer_size = 0,
- .writeback_line_buffer_chroma_buffer_size = 14643,
- .cursor_buffer_size = 8,
- .cursor_chunk_size = 2,
- .max_num_otg = 2,
- .max_num_dpp = 2,
- .max_num_wb = 1,
- .max_dchub_pscl_bw_pix_per_clk = 4,
- .max_pscl_lb_bw_pix_per_clk = 2,
- .max_lb_vscl_bw_pix_per_clk = 4,
- .max_vscl_hscl_bw_pix_per_clk = 4,
- .max_hscl_ratio = 6,
- .max_vscl_ratio = 6,
- .hscl_mults = 4,
- .vscl_mults = 4,
- .max_hscl_taps = 8,
- .max_vscl_taps = 8,
- .dispclk_ramp_margin_percent = 1,
- .underscan_factor = 1.11,
- .min_vblank_lines = 32,
- .dppclk_delay_subtotal = 46,
- .dynamic_metadata_vm_enabled = true,
- .dppclk_delay_scl_lb_only = 16,
- .dppclk_delay_scl = 50,
- .dppclk_delay_cnvc_formatter = 27,
- .dppclk_delay_cnvc_cursor = 6,
- .dispclk_delay_subtotal = 119,
- .dcfclk_cstate_latency = 5.2, // SRExitTime
- .max_inter_dcn_tile_repeaters = 8,
- .max_num_hdmi_frl_outputs = 1,
- .odm_combine_4to1_supported = false,
- .xfc_supported = false,
- .xfc_fill_bw_overhead_percent = 10.0,
- .xfc_fill_constant_bytes = 0,
- .gfx7_compat_tiling_supported = 0,
- .number_of_cursors = 1,
-};
-
-struct _vcs_dpi_soc_bounding_box_st dcn3_03_soc = {
- .clock_limits = {
- {
- .state = 0,
- .dispclk_mhz = 1217.0,
- .dppclk_mhz = 1217.0,
- .phyclk_mhz = 810.0,
- .phyclk_d18_mhz = 667.0,
- .dscclk_mhz = 405.6,
- },
- },
+#define DC_LOGGER_INIT(logger)
- .min_dcfclk = 500.0, /* TODO: set this to actual min DCFCLK */
- .num_states = 1,
- .sr_exit_time_us = 35.5,
- .sr_enter_plus_exit_time_us = 40,
- .urgent_latency_us = 4.0,
- .urgent_latency_pixel_data_only_us = 4.0,
- .urgent_latency_pixel_mixed_with_vm_data_us = 4.0,
- .urgent_latency_vm_data_only_us = 4.0,
- .urgent_out_of_order_return_per_channel_pixel_only_bytes = 4096,
- .urgent_out_of_order_return_per_channel_pixel_and_vm_bytes = 4096,
- .urgent_out_of_order_return_per_channel_vm_only_bytes = 4096,
- .pct_ideal_dram_sdp_bw_after_urgent_pixel_only = 80.0,
- .pct_ideal_dram_sdp_bw_after_urgent_pixel_and_vm = 60.0,
- .pct_ideal_dram_sdp_bw_after_urgent_vm_only = 40.0,
- .max_avg_sdp_bw_use_normal_percent = 60.0,
- .max_avg_dram_bw_use_normal_percent = 40.0,
- .writeback_latency_us = 12.0,
- .max_request_size_bytes = 256,
- .fabric_datapath_to_dcn_data_return_bytes = 64,
- .dcn_downspread_percent = 0.5,
- .downspread_percent = 0.38,
- .dram_page_open_time_ns = 50.0,
- .dram_rw_turnaround_time_ns = 17.5,
- .dram_return_buffer_per_channel_bytes = 8192,
- .round_trip_ping_latency_dcfclk_cycles = 156,
- .urgent_out_of_order_return_per_channel_bytes = 4096,
- .channel_interleave_bytes = 256,
- .num_banks = 8,
- .gpuvm_min_page_size_bytes = 4096,
- .hostvm_min_page_size_bytes = 4096,
- .dram_clock_change_latency_us = 404,
- .dummy_pstate_latency_us = 5,
- .writeback_dram_clock_change_latency_us = 23.0,
- .return_bus_width_bytes = 64,
- .dispclk_dppclk_vco_speed_mhz = 3650,
- .xfc_bus_transport_time_us = 20, // ?
- .xfc_xbuf_latency_tolerance_us = 4, // ?
- .use_urgent_burst_bw = 1, // ?
- .do_urgent_latency_adjustment = true,
- .urgent_latency_adjustment_fabric_clock_component_us = 1.0,
- .urgent_latency_adjustment_fabric_clock_reference_mhz = 1000,
-};
static const struct dc_debug_options debug_defaults_drv = {
.disable_dmcu = true,
@@ -1031,24 +901,18 @@ static bool init_soc_bounding_box(struct dc *dc, struct resource_pool *pool)
loaded_ip->max_num_otg = pool->pipe_count;
loaded_ip->max_num_dpp = pool->pipe_count;
loaded_ip->clamp_min_dcfclk = dc->config.clamp_min_dcfclk;
+ DC_FP_START();
dcn20_patch_bounding_box(dc, loaded_bb);
+ DC_FP_END();
if (dc->ctx->dc_bios->funcs->get_soc_bb_info) {
struct bp_soc_bb_info bb_info = { 0 };
if (dc->ctx->dc_bios->funcs->get_soc_bb_info(
dc->ctx->dc_bios, &bb_info) == BP_RESULT_OK) {
- if (bb_info.dram_clock_change_latency_100ns > 0)
- dcn3_03_soc.dram_clock_change_latency_us =
- bb_info.dram_clock_change_latency_100ns * 10;
-
- if (bb_info.dram_sr_enter_exit_latency_100ns > 0)
- dcn3_03_soc.sr_enter_plus_exit_time_us =
- bb_info.dram_sr_enter_exit_latency_100ns * 10;
-
- if (bb_info.dram_sr_exit_latency_100ns > 0)
- dcn3_03_soc.sr_exit_time_us =
- bb_info.dram_sr_exit_latency_100ns * 10;
+ DC_FP_START();
+ dcn303_fpu_init_soc_bounding_box(bb_info);
+ DC_FP_END();
}
}
@@ -1186,183 +1050,12 @@ static void dcn303_destroy_resource_pool(struct resource_pool **pool)
*pool = NULL;
}
-static void dcn303_get_optimal_dcfclk_fclk_for_uclk(unsigned int uclk_mts,
- unsigned int *optimal_dcfclk,
- unsigned int *optimal_fclk)
-{
- double bw_from_dram, bw_from_dram1, bw_from_dram2;
-
- bw_from_dram1 = uclk_mts * dcn3_03_soc.num_chans *
- dcn3_03_soc.dram_channel_width_bytes * (dcn3_03_soc.max_avg_dram_bw_use_normal_percent / 100);
- bw_from_dram2 = uclk_mts * dcn3_03_soc.num_chans *
- dcn3_03_soc.dram_channel_width_bytes * (dcn3_03_soc.max_avg_sdp_bw_use_normal_percent / 100);
-
- bw_from_dram = (bw_from_dram1 < bw_from_dram2) ? bw_from_dram1 : bw_from_dram2;
-
- if (optimal_fclk)
- *optimal_fclk = bw_from_dram /
- (dcn3_03_soc.fabric_datapath_to_dcn_data_return_bytes *
- (dcn3_03_soc.max_avg_sdp_bw_use_normal_percent / 100));
-
- if (optimal_dcfclk)
- *optimal_dcfclk = bw_from_dram /
- (dcn3_03_soc.return_bus_width_bytes * (dcn3_03_soc.max_avg_sdp_bw_use_normal_percent / 100));
-}
void dcn303_update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_params)
{
- unsigned int i, j;
- unsigned int num_states = 0;
-
- unsigned int dcfclk_mhz[DC__VOLTAGE_STATES] = {0};
- unsigned int dram_speed_mts[DC__VOLTAGE_STATES] = {0};
- unsigned int optimal_uclk_for_dcfclk_sta_targets[DC__VOLTAGE_STATES] = {0};
- unsigned int optimal_dcfclk_for_uclk[DC__VOLTAGE_STATES] = {0};
-
- unsigned int dcfclk_sta_targets[DC__VOLTAGE_STATES] = {694, 875, 1000, 1200};
- unsigned int num_dcfclk_sta_targets = 4;
- unsigned int num_uclk_states;
-
-
- if (dc->ctx->dc_bios->vram_info.num_chans)
- dcn3_03_soc.num_chans = dc->ctx->dc_bios->vram_info.num_chans;
-
- if (dc->ctx->dc_bios->vram_info.dram_channel_width_bytes)
- dcn3_03_soc.dram_channel_width_bytes = dc->ctx->dc_bios->vram_info.dram_channel_width_bytes;
-
- dcn3_03_soc.dispclk_dppclk_vco_speed_mhz = dc->clk_mgr->dentist_vco_freq_khz / 1000.0;
- dc->dml.soc.dispclk_dppclk_vco_speed_mhz = dc->clk_mgr->dentist_vco_freq_khz / 1000.0;
-
- if (bw_params->clk_table.entries[0].memclk_mhz) {
- int max_dcfclk_mhz = 0, max_dispclk_mhz = 0, max_dppclk_mhz = 0, max_phyclk_mhz = 0;
-
- for (i = 0; i < MAX_NUM_DPM_LVL; i++) {
- if (bw_params->clk_table.entries[i].dcfclk_mhz > max_dcfclk_mhz)
- max_dcfclk_mhz = bw_params->clk_table.entries[i].dcfclk_mhz;
- if (bw_params->clk_table.entries[i].dispclk_mhz > max_dispclk_mhz)
- max_dispclk_mhz = bw_params->clk_table.entries[i].dispclk_mhz;
- if (bw_params->clk_table.entries[i].dppclk_mhz > max_dppclk_mhz)
- max_dppclk_mhz = bw_params->clk_table.entries[i].dppclk_mhz;
- if (bw_params->clk_table.entries[i].phyclk_mhz > max_phyclk_mhz)
- max_phyclk_mhz = bw_params->clk_table.entries[i].phyclk_mhz;
- }
- if (!max_dcfclk_mhz)
- max_dcfclk_mhz = dcn3_03_soc.clock_limits[0].dcfclk_mhz;
- if (!max_dispclk_mhz)
- max_dispclk_mhz = dcn3_03_soc.clock_limits[0].dispclk_mhz;
- if (!max_dppclk_mhz)
- max_dppclk_mhz = dcn3_03_soc.clock_limits[0].dppclk_mhz;
- if (!max_phyclk_mhz)
- max_phyclk_mhz = dcn3_03_soc.clock_limits[0].phyclk_mhz;
-
- if (max_dcfclk_mhz > dcfclk_sta_targets[num_dcfclk_sta_targets-1]) {
- dcfclk_sta_targets[num_dcfclk_sta_targets] = max_dcfclk_mhz;
- num_dcfclk_sta_targets++;
- } else if (max_dcfclk_mhz < dcfclk_sta_targets[num_dcfclk_sta_targets-1]) {
- for (i = 0; i < num_dcfclk_sta_targets; i++) {
- if (dcfclk_sta_targets[i] > max_dcfclk_mhz) {
- dcfclk_sta_targets[i] = max_dcfclk_mhz;
- break;
- }
- }
- /* Update size of array since we "removed" duplicates */
- num_dcfclk_sta_targets = i + 1;
- }
-
- num_uclk_states = bw_params->clk_table.num_entries;
-
- /* Calculate optimal dcfclk for each uclk */
- for (i = 0; i < num_uclk_states; i++) {
- dcn303_get_optimal_dcfclk_fclk_for_uclk(bw_params->clk_table.entries[i].memclk_mhz * 16,
- &optimal_dcfclk_for_uclk[i], NULL);
- if (optimal_dcfclk_for_uclk[i] < bw_params->clk_table.entries[0].dcfclk_mhz)
- optimal_dcfclk_for_uclk[i] = bw_params->clk_table.entries[0].dcfclk_mhz;
- }
-
- /* Calculate optimal uclk for each dcfclk sta target */
- for (i = 0; i < num_dcfclk_sta_targets; i++) {
- for (j = 0; j < num_uclk_states; j++) {
- if (dcfclk_sta_targets[i] < optimal_dcfclk_for_uclk[j]) {
- optimal_uclk_for_dcfclk_sta_targets[i] =
- bw_params->clk_table.entries[j].memclk_mhz * 16;
- break;
- }
- }
- }
-
- i = 0;
- j = 0;
- /* create the final dcfclk and uclk table */
- while (i < num_dcfclk_sta_targets && j < num_uclk_states && num_states < DC__VOLTAGE_STATES) {
- if (dcfclk_sta_targets[i] < optimal_dcfclk_for_uclk[j] && i < num_dcfclk_sta_targets) {
- dcfclk_mhz[num_states] = dcfclk_sta_targets[i];
- dram_speed_mts[num_states++] = optimal_uclk_for_dcfclk_sta_targets[i++];
- } else {
- if (j < num_uclk_states && optimal_dcfclk_for_uclk[j] <= max_dcfclk_mhz) {
- dcfclk_mhz[num_states] = optimal_dcfclk_for_uclk[j];
- dram_speed_mts[num_states++] =
- bw_params->clk_table.entries[j++].memclk_mhz * 16;
- } else {
- j = num_uclk_states;
- }
- }
- }
-
- while (i < num_dcfclk_sta_targets && num_states < DC__VOLTAGE_STATES) {
- dcfclk_mhz[num_states] = dcfclk_sta_targets[i];
- dram_speed_mts[num_states++] = optimal_uclk_for_dcfclk_sta_targets[i++];
- }
-
- while (j < num_uclk_states && num_states < DC__VOLTAGE_STATES &&
- optimal_dcfclk_for_uclk[j] <= max_dcfclk_mhz) {
- dcfclk_mhz[num_states] = optimal_dcfclk_for_uclk[j];
- dram_speed_mts[num_states++] = bw_params->clk_table.entries[j++].memclk_mhz * 16;
- }
-
- dcn3_03_soc.num_states = num_states;
- for (i = 0; i < dcn3_03_soc.num_states; i++) {
- dcn3_03_soc.clock_limits[i].state = i;
- dcn3_03_soc.clock_limits[i].dcfclk_mhz = dcfclk_mhz[i];
- dcn3_03_soc.clock_limits[i].fabricclk_mhz = dcfclk_mhz[i];
- dcn3_03_soc.clock_limits[i].dram_speed_mts = dram_speed_mts[i];
-
- /* Fill all states with max values of all other clocks */
- dcn3_03_soc.clock_limits[i].dispclk_mhz = max_dispclk_mhz;
- dcn3_03_soc.clock_limits[i].dppclk_mhz = max_dppclk_mhz;
- dcn3_03_soc.clock_limits[i].phyclk_mhz = max_phyclk_mhz;
- /* Populate from bw_params for DTBCLK, SOCCLK */
- if (!bw_params->clk_table.entries[i].dtbclk_mhz && i > 0)
- dcn3_03_soc.clock_limits[i].dtbclk_mhz = dcn3_03_soc.clock_limits[i-1].dtbclk_mhz;
- else
- dcn3_03_soc.clock_limits[i].dtbclk_mhz = bw_params->clk_table.entries[i].dtbclk_mhz;
- if (!bw_params->clk_table.entries[i].socclk_mhz && i > 0)
- dcn3_03_soc.clock_limits[i].socclk_mhz = dcn3_03_soc.clock_limits[i-1].socclk_mhz;
- else
- dcn3_03_soc.clock_limits[i].socclk_mhz = bw_params->clk_table.entries[i].socclk_mhz;
- /* These clocks cannot come from bw_params, always fill from dcn3_03_soc[1] */
- /* FCLK, PHYCLK_D18, DSCCLK */
- dcn3_03_soc.clock_limits[i].phyclk_d18_mhz = dcn3_03_soc.clock_limits[0].phyclk_d18_mhz;
- dcn3_03_soc.clock_limits[i].dscclk_mhz = dcn3_03_soc.clock_limits[0].dscclk_mhz;
- }
-
- // WA: patch strobe modes to compensate for DCN303 BW issue
- if (dcn3_03_soc.num_chans <= 4) {
- for (i = 0; i < dcn3_03_soc.num_states; i++) {
- if (dcn3_03_soc.clock_limits[i].dram_speed_mts > 1700)
- break;
-
- if (dcn3_03_soc.clock_limits[i].dram_speed_mts >= 1500) {
- dcn3_03_soc.clock_limits[i].dcfclk_mhz = 100;
- dcn3_03_soc.clock_limits[i].fabricclk_mhz = 100;
- }
- }
- }
-
- /* re-init DML with updated bb */
- dml_init_instance(&dc->dml, &dcn3_03_soc, &dcn3_03_ip, DML_PROJECT_DCN30);
- if (dc->current_state)
- dml_init_instance(&dc->current_state->bw_ctx.dml, &dcn3_03_soc, &dcn3_03_ip, DML_PROJECT_DCN30);
- }
+ DC_FP_START();
+ dcn303_fpu_update_bw_bounding_box(dc, bw_params);
+ DC_FP_END();
}
static struct resource_funcs dcn303_res_pool_funcs = {
diff --git a/drivers/gpu/drm/amd/display/dc/dcn303/dcn303_resource.h b/drivers/gpu/drm/amd/display/dc/dcn303/dcn303_resource.h
index 5b590c169763..9c7d79540900 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn303/dcn303_resource.h
+++ b/drivers/gpu/drm/amd/display/dc/dcn303/dcn303_resource.h
@@ -10,6 +10,9 @@
#include "core_types.h"
+extern struct _vcs_dpi_ip_params_st dcn3_03_ip;
+extern struct _vcs_dpi_soc_bounding_box_st dcn3_03_soc;
+
struct resource_pool *dcn303_create_resource_pool(const struct dc_init_data *init_data, struct dc *dc);
void dcn303_update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_params);
diff --git a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dccg.c b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dccg.c
index ea4f8e06b07c..287a1066b547 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dccg.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dccg.c
@@ -121,7 +121,8 @@ static void dccg31_enable_dpstreamclk(struct dccg *dccg, int otg_inst)
return;
}
if (dccg->ctx->dc->debug.root_clock_optimization.bits.dpstream)
- REG_UPDATE(DCCG_GATE_DISABLE_CNTL3,
+ REG_UPDATE_2(DCCG_GATE_DISABLE_CNTL3,
+ DPSTREAMCLK_GATE_DISABLE, 1,
DPSTREAMCLK_ROOT_GATE_DISABLE, 1);
}
@@ -130,8 +131,9 @@ static void dccg31_disable_dpstreamclk(struct dccg *dccg, int otg_inst)
struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
if (dccg->ctx->dc->debug.root_clock_optimization.bits.dpstream)
- REG_UPDATE(DCCG_GATE_DISABLE_CNTL3,
- DPSTREAMCLK_ROOT_GATE_DISABLE, 0);
+ REG_UPDATE_2(DCCG_GATE_DISABLE_CNTL3,
+ DPSTREAMCLK_ROOT_GATE_DISABLE, 0,
+ DPSTREAMCLK_GATE_DISABLE, 0);
switch (otg_inst) {
case 0:
@@ -180,7 +182,8 @@ void dccg31_enable_symclk32_se(
switch (hpo_se_inst) {
case 0:
if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se)
- REG_UPDATE(DCCG_GATE_DISABLE_CNTL3,
+ REG_UPDATE_2(DCCG_GATE_DISABLE_CNTL3,
+ SYMCLK32_SE0_GATE_DISABLE, 1,
SYMCLK32_ROOT_SE0_GATE_DISABLE, 1);
REG_UPDATE_2(SYMCLK32_SE_CNTL,
SYMCLK32_SE0_SRC_SEL, phyd32clk,
@@ -188,7 +191,8 @@ void dccg31_enable_symclk32_se(
break;
case 1:
if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se)
- REG_UPDATE(DCCG_GATE_DISABLE_CNTL3,
+ REG_UPDATE_2(DCCG_GATE_DISABLE_CNTL3,
+ SYMCLK32_SE1_GATE_DISABLE, 1,
SYMCLK32_ROOT_SE1_GATE_DISABLE, 1);
REG_UPDATE_2(SYMCLK32_SE_CNTL,
SYMCLK32_SE1_SRC_SEL, phyd32clk,
@@ -196,7 +200,8 @@ void dccg31_enable_symclk32_se(
break;
case 2:
if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se)
- REG_UPDATE(DCCG_GATE_DISABLE_CNTL3,
+ REG_UPDATE_2(DCCG_GATE_DISABLE_CNTL3,
+ SYMCLK32_SE2_GATE_DISABLE, 1,
SYMCLK32_ROOT_SE2_GATE_DISABLE, 1);
REG_UPDATE_2(SYMCLK32_SE_CNTL,
SYMCLK32_SE2_SRC_SEL, phyd32clk,
@@ -204,7 +209,8 @@ void dccg31_enable_symclk32_se(
break;
case 3:
if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se)
- REG_UPDATE(DCCG_GATE_DISABLE_CNTL3,
+ REG_UPDATE_2(DCCG_GATE_DISABLE_CNTL3,
+ SYMCLK32_SE3_GATE_DISABLE, 1,
SYMCLK32_ROOT_SE3_GATE_DISABLE, 1);
REG_UPDATE_2(SYMCLK32_SE_CNTL,
SYMCLK32_SE3_SRC_SEL, phyd32clk,
@@ -229,7 +235,8 @@ void dccg31_disable_symclk32_se(
SYMCLK32_SE0_SRC_SEL, 0,
SYMCLK32_SE0_EN, 0);
if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se)
- REG_UPDATE(DCCG_GATE_DISABLE_CNTL3,
+ REG_UPDATE_2(DCCG_GATE_DISABLE_CNTL3,
+ SYMCLK32_SE0_GATE_DISABLE, 0,
SYMCLK32_ROOT_SE0_GATE_DISABLE, 0);
break;
case 1:
@@ -237,7 +244,8 @@ void dccg31_disable_symclk32_se(
SYMCLK32_SE1_SRC_SEL, 0,
SYMCLK32_SE1_EN, 0);
if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se)
- REG_UPDATE(DCCG_GATE_DISABLE_CNTL3,
+ REG_UPDATE_2(DCCG_GATE_DISABLE_CNTL3,
+ SYMCLK32_SE1_GATE_DISABLE, 0,
SYMCLK32_ROOT_SE1_GATE_DISABLE, 0);
break;
case 2:
@@ -245,7 +253,8 @@ void dccg31_disable_symclk32_se(
SYMCLK32_SE2_SRC_SEL, 0,
SYMCLK32_SE2_EN, 0);
if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se)
- REG_UPDATE(DCCG_GATE_DISABLE_CNTL3,
+ REG_UPDATE_2(DCCG_GATE_DISABLE_CNTL3,
+ SYMCLK32_SE2_GATE_DISABLE, 0,
SYMCLK32_ROOT_SE2_GATE_DISABLE, 0);
break;
case 3:
@@ -253,7 +262,8 @@ void dccg31_disable_symclk32_se(
SYMCLK32_SE3_SRC_SEL, 0,
SYMCLK32_SE3_EN, 0);
if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se)
- REG_UPDATE(DCCG_GATE_DISABLE_CNTL3,
+ REG_UPDATE_2(DCCG_GATE_DISABLE_CNTL3,
+ SYMCLK32_SE3_GATE_DISABLE, 0,
SYMCLK32_ROOT_SE3_GATE_DISABLE, 0);
break;
default:
@@ -275,7 +285,8 @@ void dccg31_enable_symclk32_le(
switch (hpo_le_inst) {
case 0:
if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_le)
- REG_UPDATE(DCCG_GATE_DISABLE_CNTL3,
+ REG_UPDATE_2(DCCG_GATE_DISABLE_CNTL3,
+ SYMCLK32_LE0_GATE_DISABLE, 1,
SYMCLK32_ROOT_LE0_GATE_DISABLE, 1);
REG_UPDATE_2(SYMCLK32_LE_CNTL,
SYMCLK32_LE0_SRC_SEL, phyd32clk,
@@ -283,7 +294,8 @@ void dccg31_enable_symclk32_le(
break;
case 1:
if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_le)
- REG_UPDATE(DCCG_GATE_DISABLE_CNTL3,
+ REG_UPDATE_2(DCCG_GATE_DISABLE_CNTL3,
+ SYMCLK32_LE1_GATE_DISABLE, 1,
SYMCLK32_ROOT_LE1_GATE_DISABLE, 1);
REG_UPDATE_2(SYMCLK32_LE_CNTL,
SYMCLK32_LE1_SRC_SEL, phyd32clk,
@@ -308,7 +320,8 @@ void dccg31_disable_symclk32_le(
SYMCLK32_LE0_SRC_SEL, 0,
SYMCLK32_LE0_EN, 0);
if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_le)
- REG_UPDATE(DCCG_GATE_DISABLE_CNTL3,
+ REG_UPDATE_2(DCCG_GATE_DISABLE_CNTL3,
+ SYMCLK32_LE0_GATE_DISABLE, 0,
SYMCLK32_ROOT_LE0_GATE_DISABLE, 0);
break;
case 1:
@@ -316,7 +329,8 @@ void dccg31_disable_symclk32_le(
SYMCLK32_LE1_SRC_SEL, 0,
SYMCLK32_LE1_EN, 0);
if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_le)
- REG_UPDATE(DCCG_GATE_DISABLE_CNTL3,
+ REG_UPDATE_2(DCCG_GATE_DISABLE_CNTL3,
+ SYMCLK32_LE1_GATE_DISABLE, 0,
SYMCLK32_ROOT_LE1_GATE_DISABLE, 0);
break;
default:
@@ -406,54 +420,89 @@ void dccg31_set_physymclk(
/* Force PHYSYMCLK on and Select phyd32clk as the source of clock which is output to PHY through DCIO */
switch (phy_inst) {
case 0:
- if (force_enable)
+ if (force_enable) {
REG_UPDATE_2(PHYASYMCLK_CLOCK_CNTL,
PHYASYMCLK_FORCE_EN, 1,
PHYASYMCLK_FORCE_SRC_SEL, clk_src);
- else
+ if (dccg->ctx->dc->debug.root_clock_optimization.bits.physymclk)
+ REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
+ PHYASYMCLK_GATE_DISABLE, 1);
+ } else {
REG_UPDATE_2(PHYASYMCLK_CLOCK_CNTL,
PHYASYMCLK_FORCE_EN, 0,
PHYASYMCLK_FORCE_SRC_SEL, 0);
+ if (dccg->ctx->dc->debug.root_clock_optimization.bits.physymclk)
+ REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
+ PHYASYMCLK_GATE_DISABLE, 0);
+ }
break;
case 1:
- if (force_enable)
+ if (force_enable) {
REG_UPDATE_2(PHYBSYMCLK_CLOCK_CNTL,
PHYBSYMCLK_FORCE_EN, 1,
PHYBSYMCLK_FORCE_SRC_SEL, clk_src);
- else
+ if (dccg->ctx->dc->debug.root_clock_optimization.bits.physymclk)
+ REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
+ PHYBSYMCLK_GATE_DISABLE, 1);
+ } else {
REG_UPDATE_2(PHYBSYMCLK_CLOCK_CNTL,
PHYBSYMCLK_FORCE_EN, 0,
PHYBSYMCLK_FORCE_SRC_SEL, 0);
+ if (dccg->ctx->dc->debug.root_clock_optimization.bits.physymclk)
+ REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
+ PHYBSYMCLK_GATE_DISABLE, 0);
+ }
break;
case 2:
- if (force_enable)
+ if (force_enable) {
REG_UPDATE_2(PHYCSYMCLK_CLOCK_CNTL,
PHYCSYMCLK_FORCE_EN, 1,
PHYCSYMCLK_FORCE_SRC_SEL, clk_src);
- else
+ if (dccg->ctx->dc->debug.root_clock_optimization.bits.physymclk)
+ REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
+ PHYCSYMCLK_GATE_DISABLE, 1);
+ } else {
REG_UPDATE_2(PHYCSYMCLK_CLOCK_CNTL,
PHYCSYMCLK_FORCE_EN, 0,
PHYCSYMCLK_FORCE_SRC_SEL, 0);
+ if (dccg->ctx->dc->debug.root_clock_optimization.bits.physymclk)
+ REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
+ PHYCSYMCLK_GATE_DISABLE, 0);
+ }
break;
case 3:
- if (force_enable)
+ if (force_enable) {
REG_UPDATE_2(PHYDSYMCLK_CLOCK_CNTL,
PHYDSYMCLK_FORCE_EN, 1,
PHYDSYMCLK_FORCE_SRC_SEL, clk_src);
- else
+ if (dccg->ctx->dc->debug.root_clock_optimization.bits.physymclk)
+ REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
+ PHYDSYMCLK_GATE_DISABLE, 1);
+ } else {
REG_UPDATE_2(PHYDSYMCLK_CLOCK_CNTL,
PHYDSYMCLK_FORCE_EN, 0,
PHYDSYMCLK_FORCE_SRC_SEL, 0);
+ if (dccg->ctx->dc->debug.root_clock_optimization.bits.physymclk)
+ REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
+ PHYDSYMCLK_GATE_DISABLE, 0);
+ }
break;
case 4:
- if (force_enable)
+ if (force_enable) {
REG_UPDATE_2(PHYESYMCLK_CLOCK_CNTL,
PHYESYMCLK_FORCE_EN, 1,
PHYESYMCLK_FORCE_SRC_SEL, clk_src);
- else
+ if (dccg->ctx->dc->debug.root_clock_optimization.bits.physymclk)
+ REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
+ PHYESYMCLK_GATE_DISABLE, 1);
+ } else {
REG_UPDATE_2(PHYESYMCLK_CLOCK_CNTL,
PHYESYMCLK_FORCE_EN, 0,
PHYESYMCLK_FORCE_SRC_SEL, 0);
+ if (dccg->ctx->dc->debug.root_clock_optimization.bits.physymclk)
+ REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
+ PHYESYMCLK_GATE_DISABLE, 0);
+ }
break;
default:
BREAK_TO_DEBUGGER();
@@ -615,6 +664,13 @@ void dccg31_init(struct dccg *dccg)
dccg31_disable_dpstreamclk(dccg, 3);
}
+ if (dccg->ctx->dc->debug.root_clock_optimization.bits.physymclk) {
+ dccg31_set_physymclk(dccg, 0, PHYSYMCLK_FORCE_SRC_SYMCLK, false);
+ dccg31_set_physymclk(dccg, 1, PHYSYMCLK_FORCE_SRC_SYMCLK, false);
+ dccg31_set_physymclk(dccg, 2, PHYSYMCLK_FORCE_SRC_SYMCLK, false);
+ dccg31_set_physymclk(dccg, 3, PHYSYMCLK_FORCE_SRC_SYMCLK, false);
+ dccg31_set_physymclk(dccg, 4, PHYSYMCLK_FORCE_SRC_SYMCLK, false);
+ }
}
static const struct dccg_funcs dccg31_funcs = {
diff --git a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dccg.h b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dccg.h
index a013a32bbaf7..269cabbea72a 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dccg.h
+++ b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dccg.h
@@ -66,6 +66,7 @@
SR(DSCCLK1_DTO_PARAM),\
SR(DSCCLK2_DTO_PARAM),\
SR(DSCCLK_DTO_CTRL),\
+ SR(DCCG_GATE_DISABLE_CNTL2),\
SR(DCCG_GATE_DISABLE_CNTL3),\
SR(HDMISTREAMCLK0_DTO_PARAM)
@@ -135,6 +136,11 @@
DCCG_SF(DSCCLK_DTO_CTRL, DSCCLK0_DTO_ENABLE, mask_sh),\
DCCG_SF(DSCCLK_DTO_CTRL, DSCCLK1_DTO_ENABLE, mask_sh),\
DCCG_SF(DSCCLK_DTO_CTRL, DSCCLK2_DTO_ENABLE, mask_sh),\
+ DCCG_SF(DCCG_GATE_DISABLE_CNTL2, PHYASYMCLK_GATE_DISABLE, mask_sh),\
+ DCCG_SF(DCCG_GATE_DISABLE_CNTL2, PHYBSYMCLK_GATE_DISABLE, mask_sh),\
+ DCCG_SF(DCCG_GATE_DISABLE_CNTL2, PHYCSYMCLK_GATE_DISABLE, mask_sh),\
+ DCCG_SF(DCCG_GATE_DISABLE_CNTL2, PHYDSYMCLK_GATE_DISABLE, mask_sh),\
+ DCCG_SF(DCCG_GATE_DISABLE_CNTL2, PHYESYMCLK_GATE_DISABLE, mask_sh),\
DCCG_SF(DCCG_GATE_DISABLE_CNTL3, DPSTREAMCLK_ROOT_GATE_DISABLE, mask_sh),\
DCCG_SF(DCCG_GATE_DISABLE_CNTL3, DPSTREAMCLK_GATE_DISABLE, mask_sh),\
DCCG_SF(DCCG_GATE_DISABLE_CNTL3, SYMCLK32_ROOT_SE0_GATE_DISABLE, mask_sh),\
diff --git a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dio_link_encoder.c b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dio_link_encoder.c
index 8b9b1a5309ba..d94fd1010deb 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dio_link_encoder.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dio_link_encoder.c
@@ -240,18 +240,9 @@ static void enc31_hw_init(struct link_encoder *enc)
// 100MHz -> 0x32
// 48MHz -> 0x18
-#ifdef CLEANUP_FIXME
- /*from display_init*/
- REG_WRITE(RDPCSTX_DEBUG_CONFIG, 0);
-#endif
-
// Set TMDS_CTL0 to 1. This is a legacy setting.
REG_UPDATE(TMDS_CTL_BITS, TMDS_CTL0, 1);
- /*HW default is 5*/
- REG_UPDATE(RDPCSTX_CNTL,
- RDPCS_TX_FIFO_RD_START_DELAY, 4);
-
dcn10_aux_initialize(enc10);
}
diff --git a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hpo_dp_stream_encoder.c b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hpo_dp_stream_encoder.c
index 5065904c7833..23621ff08c90 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hpo_dp_stream_encoder.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hpo_dp_stream_encoder.c
@@ -710,6 +710,16 @@ static void dcn31_hpo_dp_stream_enc_read_state(
}
}
+static void dcn31_set_hblank_min_symbol_width(
+ struct hpo_dp_stream_encoder *enc,
+ uint16_t width)
+{
+ struct dcn31_hpo_dp_stream_encoder *enc3 = DCN3_1_HPO_DP_STREAM_ENC_FROM_HPO_STREAM_ENC(enc);
+
+ REG_SET(DP_SYM32_ENC_HBLANK_CONTROL, 0,
+ HBLANK_MINIMUM_SYMBOL_WIDTH, width);
+}
+
static const struct hpo_dp_stream_encoder_funcs dcn30_str_enc_funcs = {
.enable_stream = dcn31_hpo_dp_stream_enc_enable_stream,
.dp_unblank = dcn31_hpo_dp_stream_enc_dp_unblank,
@@ -725,6 +735,7 @@ static const struct hpo_dp_stream_encoder_funcs dcn30_str_enc_funcs = {
.dp_audio_enable = dcn31_hpo_dp_stream_enc_audio_enable,
.dp_audio_disable = dcn31_hpo_dp_stream_enc_audio_disable,
.read_state = dcn31_hpo_dp_stream_enc_read_state,
+ .set_hblank_min_symbol_width = dcn31_set_hblank_min_symbol_width,
};
void dcn31_hpo_dp_stream_encoder_construct(
diff --git a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hpo_dp_stream_encoder.h b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hpo_dp_stream_encoder.h
index 70b94fc25304..7c77c71591a0 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hpo_dp_stream_encoder.h
+++ b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hpo_dp_stream_encoder.h
@@ -80,7 +80,8 @@
SRI(DP_SYM32_ENC_SDP_GSP_CONTROL11, DP_SYM32_ENC, id),\
SRI(DP_SYM32_ENC_SDP_METADATA_PACKET_CONTROL, DP_SYM32_ENC, id),\
SRI(DP_SYM32_ENC_SDP_AUDIO_CONTROL0, DP_SYM32_ENC, id),\
- SRI(DP_SYM32_ENC_VID_CRC_CONTROL, DP_SYM32_ENC, id)
+ SRI(DP_SYM32_ENC_VID_CRC_CONTROL, DP_SYM32_ENC, id), \
+ SRI(DP_SYM32_ENC_HBLANK_CONTROL, DP_SYM32_ENC, id)
#define DCN3_1_HPO_DP_STREAM_ENC_REGS \
uint32_t DP_STREAM_MAPPER_CONTROL0;\
@@ -116,7 +117,8 @@
uint32_t DP_SYM32_ENC_SDP_GSP_CONTROL11;\
uint32_t DP_SYM32_ENC_SDP_METADATA_PACKET_CONTROL;\
uint32_t DP_SYM32_ENC_SDP_AUDIO_CONTROL0;\
- uint32_t DP_SYM32_ENC_VID_CRC_CONTROL
+ uint32_t DP_SYM32_ENC_VID_CRC_CONTROL;\
+ uint32_t DP_SYM32_ENC_HBLANK_CONTROL
#define DCN3_1_HPO_DP_STREAM_ENC_MASK_SH_LIST(mask_sh)\
@@ -202,7 +204,8 @@
type GSP_SOF_REFERENCE;\
type METADATA_PACKET_ENABLE;\
type CRC_ENABLE;\
- type CRC_CONT_MODE_ENABLE
+ type CRC_CONT_MODE_ENABLE;\
+ type HBLANK_MINIMUM_SYMBOL_WIDTH
struct dcn31_hpo_dp_stream_encoder_registers {
diff --git a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hubbub.c b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hubbub.c
index 90c73a1cb986..3e6d6ebd199e 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hubbub.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hubbub.c
@@ -138,8 +138,11 @@ static uint32_t convert_and_clamp(
ret_val = wm_ns * refclk_mhz;
ret_val /= 1000;
- if (ret_val > clamp_value)
+ if (ret_val > clamp_value) {
+ /* clamping WMs is abnormal, unexpected and may lead to underflow*/
+ ASSERT(0);
ret_val = clamp_value;
+ }
return ret_val;
}
@@ -159,7 +162,7 @@ static bool hubbub31_program_urgent_watermarks(
if (safe_to_lower || watermarks->a.urgent_ns > hubbub2->watermarks.a.urgent_ns) {
hubbub2->watermarks.a.urgent_ns = watermarks->a.urgent_ns;
prog_wm_value = convert_and_clamp(watermarks->a.urgent_ns,
- refclk_mhz, 0x1fffff);
+ refclk_mhz, 0x3fff);
REG_SET(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_A, 0,
DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_A, prog_wm_value);
@@ -193,7 +196,7 @@ static bool hubbub31_program_urgent_watermarks(
if (safe_to_lower || watermarks->a.urgent_latency_ns > hubbub2->watermarks.a.urgent_latency_ns) {
hubbub2->watermarks.a.urgent_latency_ns = watermarks->a.urgent_latency_ns;
prog_wm_value = convert_and_clamp(watermarks->a.urgent_latency_ns,
- refclk_mhz, 0x1fffff);
+ refclk_mhz, 0x3fff);
REG_SET(DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_A, 0,
DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_A, prog_wm_value);
} else if (watermarks->a.urgent_latency_ns < hubbub2->watermarks.a.urgent_latency_ns)
@@ -203,7 +206,7 @@ static bool hubbub31_program_urgent_watermarks(
if (safe_to_lower || watermarks->b.urgent_ns > hubbub2->watermarks.b.urgent_ns) {
hubbub2->watermarks.b.urgent_ns = watermarks->b.urgent_ns;
prog_wm_value = convert_and_clamp(watermarks->b.urgent_ns,
- refclk_mhz, 0x1fffff);
+ refclk_mhz, 0x3fff);
REG_SET(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_B, 0,
DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_B, prog_wm_value);
@@ -237,7 +240,7 @@ static bool hubbub31_program_urgent_watermarks(
if (safe_to_lower || watermarks->b.urgent_latency_ns > hubbub2->watermarks.b.urgent_latency_ns) {
hubbub2->watermarks.b.urgent_latency_ns = watermarks->b.urgent_latency_ns;
prog_wm_value = convert_and_clamp(watermarks->b.urgent_latency_ns,
- refclk_mhz, 0x1fffff);
+ refclk_mhz, 0x3fff);
REG_SET(DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_B, 0,
DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_B, prog_wm_value);
} else if (watermarks->b.urgent_latency_ns < hubbub2->watermarks.b.urgent_latency_ns)
@@ -247,7 +250,7 @@ static bool hubbub31_program_urgent_watermarks(
if (safe_to_lower || watermarks->c.urgent_ns > hubbub2->watermarks.c.urgent_ns) {
hubbub2->watermarks.c.urgent_ns = watermarks->c.urgent_ns;
prog_wm_value = convert_and_clamp(watermarks->c.urgent_ns,
- refclk_mhz, 0x1fffff);
+ refclk_mhz, 0x3fff);
REG_SET(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_C, 0,
DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_C, prog_wm_value);
@@ -281,7 +284,7 @@ static bool hubbub31_program_urgent_watermarks(
if (safe_to_lower || watermarks->c.urgent_latency_ns > hubbub2->watermarks.c.urgent_latency_ns) {
hubbub2->watermarks.c.urgent_latency_ns = watermarks->c.urgent_latency_ns;
prog_wm_value = convert_and_clamp(watermarks->c.urgent_latency_ns,
- refclk_mhz, 0x1fffff);
+ refclk_mhz, 0x3fff);
REG_SET(DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_C, 0,
DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_C, prog_wm_value);
} else if (watermarks->c.urgent_latency_ns < hubbub2->watermarks.c.urgent_latency_ns)
@@ -291,7 +294,7 @@ static bool hubbub31_program_urgent_watermarks(
if (safe_to_lower || watermarks->d.urgent_ns > hubbub2->watermarks.d.urgent_ns) {
hubbub2->watermarks.d.urgent_ns = watermarks->d.urgent_ns;
prog_wm_value = convert_and_clamp(watermarks->d.urgent_ns,
- refclk_mhz, 0x1fffff);
+ refclk_mhz, 0x3fff);
REG_SET(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_D, 0,
DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_D, prog_wm_value);
@@ -325,7 +328,7 @@ static bool hubbub31_program_urgent_watermarks(
if (safe_to_lower || watermarks->d.urgent_latency_ns > hubbub2->watermarks.d.urgent_latency_ns) {
hubbub2->watermarks.d.urgent_latency_ns = watermarks->d.urgent_latency_ns;
prog_wm_value = convert_and_clamp(watermarks->d.urgent_latency_ns,
- refclk_mhz, 0x1fffff);
+ refclk_mhz, 0x3fff);
REG_SET(DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_D, 0,
DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_D, prog_wm_value);
} else if (watermarks->d.urgent_latency_ns < hubbub2->watermarks.d.urgent_latency_ns)
@@ -351,7 +354,7 @@ static bool hubbub31_program_stutter_watermarks(
watermarks->a.cstate_pstate.cstate_enter_plus_exit_ns;
prog_wm_value = convert_and_clamp(
watermarks->a.cstate_pstate.cstate_enter_plus_exit_ns,
- refclk_mhz, 0x1fffff);
+ refclk_mhz, 0xffff);
REG_SET(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_A, 0,
DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_A, prog_wm_value);
DC_LOG_BANDWIDTH_CALCS("SR_ENTER_EXIT_WATERMARK_A calculated =%d\n"
@@ -367,7 +370,7 @@ static bool hubbub31_program_stutter_watermarks(
watermarks->a.cstate_pstate.cstate_exit_ns;
prog_wm_value = convert_and_clamp(
watermarks->a.cstate_pstate.cstate_exit_ns,
- refclk_mhz, 0x1fffff);
+ refclk_mhz, 0xffff);
REG_SET(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_A, 0,
DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_A, prog_wm_value);
DC_LOG_BANDWIDTH_CALCS("SR_EXIT_WATERMARK_A calculated =%d\n"
@@ -383,7 +386,7 @@ static bool hubbub31_program_stutter_watermarks(
watermarks->a.cstate_pstate.cstate_enter_plus_exit_z8_ns;
prog_wm_value = convert_and_clamp(
watermarks->a.cstate_pstate.cstate_enter_plus_exit_z8_ns,
- refclk_mhz, 0x1fffff);
+ refclk_mhz, 0xffff);
REG_SET(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_Z8_A, 0,
DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_Z8_A, prog_wm_value);
DC_LOG_BANDWIDTH_CALCS("SR_ENTER_WATERMARK_Z8_A calculated =%d\n"
@@ -399,7 +402,7 @@ static bool hubbub31_program_stutter_watermarks(
watermarks->a.cstate_pstate.cstate_exit_z8_ns;
prog_wm_value = convert_and_clamp(
watermarks->a.cstate_pstate.cstate_exit_z8_ns,
- refclk_mhz, 0x1fffff);
+ refclk_mhz, 0xffff);
REG_SET(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_Z8_A, 0,
DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_Z8_A, prog_wm_value);
DC_LOG_BANDWIDTH_CALCS("SR_EXIT_WATERMARK_Z8_A calculated =%d\n"
@@ -416,7 +419,7 @@ static bool hubbub31_program_stutter_watermarks(
watermarks->b.cstate_pstate.cstate_enter_plus_exit_ns;
prog_wm_value = convert_and_clamp(
watermarks->b.cstate_pstate.cstate_enter_plus_exit_ns,
- refclk_mhz, 0x1fffff);
+ refclk_mhz, 0xffff);
REG_SET(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_B, 0,
DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_B, prog_wm_value);
DC_LOG_BANDWIDTH_CALCS("SR_ENTER_EXIT_WATERMARK_B calculated =%d\n"
@@ -432,7 +435,7 @@ static bool hubbub31_program_stutter_watermarks(
watermarks->b.cstate_pstate.cstate_exit_ns;
prog_wm_value = convert_and_clamp(
watermarks->b.cstate_pstate.cstate_exit_ns,
- refclk_mhz, 0x1fffff);
+ refclk_mhz, 0xffff);
REG_SET(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_B, 0,
DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_B, prog_wm_value);
DC_LOG_BANDWIDTH_CALCS("SR_EXIT_WATERMARK_B calculated =%d\n"
@@ -448,7 +451,7 @@ static bool hubbub31_program_stutter_watermarks(
watermarks->b.cstate_pstate.cstate_enter_plus_exit_z8_ns;
prog_wm_value = convert_and_clamp(
watermarks->b.cstate_pstate.cstate_enter_plus_exit_z8_ns,
- refclk_mhz, 0x1fffff);
+ refclk_mhz, 0xffff);
REG_SET(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_Z8_B, 0,
DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_Z8_B, prog_wm_value);
DC_LOG_BANDWIDTH_CALCS("SR_ENTER_WATERMARK_Z8_B calculated =%d\n"
@@ -464,7 +467,7 @@ static bool hubbub31_program_stutter_watermarks(
watermarks->b.cstate_pstate.cstate_exit_z8_ns;
prog_wm_value = convert_and_clamp(
watermarks->b.cstate_pstate.cstate_exit_z8_ns,
- refclk_mhz, 0x1fffff);
+ refclk_mhz, 0xffff);
REG_SET(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_Z8_B, 0,
DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_Z8_B, prog_wm_value);
DC_LOG_BANDWIDTH_CALCS("SR_EXIT_WATERMARK_Z8_B calculated =%d\n"
@@ -481,7 +484,7 @@ static bool hubbub31_program_stutter_watermarks(
watermarks->c.cstate_pstate.cstate_enter_plus_exit_ns;
prog_wm_value = convert_and_clamp(
watermarks->c.cstate_pstate.cstate_enter_plus_exit_ns,
- refclk_mhz, 0x1fffff);
+ refclk_mhz, 0xffff);
REG_SET(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_C, 0,
DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_C, prog_wm_value);
DC_LOG_BANDWIDTH_CALCS("SR_ENTER_EXIT_WATERMARK_C calculated =%d\n"
@@ -497,7 +500,7 @@ static bool hubbub31_program_stutter_watermarks(
watermarks->c.cstate_pstate.cstate_exit_ns;
prog_wm_value = convert_and_clamp(
watermarks->c.cstate_pstate.cstate_exit_ns,
- refclk_mhz, 0x1fffff);
+ refclk_mhz, 0xffff);
REG_SET(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_C, 0,
DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_C, prog_wm_value);
DC_LOG_BANDWIDTH_CALCS("SR_EXIT_WATERMARK_C calculated =%d\n"
@@ -513,7 +516,7 @@ static bool hubbub31_program_stutter_watermarks(
watermarks->c.cstate_pstate.cstate_enter_plus_exit_z8_ns;
prog_wm_value = convert_and_clamp(
watermarks->c.cstate_pstate.cstate_enter_plus_exit_z8_ns,
- refclk_mhz, 0x1fffff);
+ refclk_mhz, 0xffff);
REG_SET(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_Z8_C, 0,
DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_Z8_C, prog_wm_value);
DC_LOG_BANDWIDTH_CALCS("SR_ENTER_WATERMARK_Z8_C calculated =%d\n"
@@ -529,7 +532,7 @@ static bool hubbub31_program_stutter_watermarks(
watermarks->c.cstate_pstate.cstate_exit_z8_ns;
prog_wm_value = convert_and_clamp(
watermarks->c.cstate_pstate.cstate_exit_z8_ns,
- refclk_mhz, 0x1fffff);
+ refclk_mhz, 0xffff);
REG_SET(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_Z8_C, 0,
DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_Z8_C, prog_wm_value);
DC_LOG_BANDWIDTH_CALCS("SR_EXIT_WATERMARK_Z8_C calculated =%d\n"
@@ -546,7 +549,7 @@ static bool hubbub31_program_stutter_watermarks(
watermarks->d.cstate_pstate.cstate_enter_plus_exit_ns;
prog_wm_value = convert_and_clamp(
watermarks->d.cstate_pstate.cstate_enter_plus_exit_ns,
- refclk_mhz, 0x1fffff);
+ refclk_mhz, 0xffff);
REG_SET(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_D, 0,
DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_D, prog_wm_value);
DC_LOG_BANDWIDTH_CALCS("SR_ENTER_EXIT_WATERMARK_D calculated =%d\n"
@@ -562,7 +565,7 @@ static bool hubbub31_program_stutter_watermarks(
watermarks->d.cstate_pstate.cstate_exit_ns;
prog_wm_value = convert_and_clamp(
watermarks->d.cstate_pstate.cstate_exit_ns,
- refclk_mhz, 0x1fffff);
+ refclk_mhz, 0xffff);
REG_SET(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_D, 0,
DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_D, prog_wm_value);
DC_LOG_BANDWIDTH_CALCS("SR_EXIT_WATERMARK_D calculated =%d\n"
@@ -578,7 +581,7 @@ static bool hubbub31_program_stutter_watermarks(
watermarks->d.cstate_pstate.cstate_enter_plus_exit_z8_ns;
prog_wm_value = convert_and_clamp(
watermarks->d.cstate_pstate.cstate_enter_plus_exit_z8_ns,
- refclk_mhz, 0x1fffff);
+ refclk_mhz, 0xffff);
REG_SET(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_Z8_D, 0,
DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_Z8_D, prog_wm_value);
DC_LOG_BANDWIDTH_CALCS("SR_ENTER_WATERMARK_Z8_D calculated =%d\n"
@@ -594,7 +597,7 @@ static bool hubbub31_program_stutter_watermarks(
watermarks->d.cstate_pstate.cstate_exit_z8_ns;
prog_wm_value = convert_and_clamp(
watermarks->d.cstate_pstate.cstate_exit_z8_ns,
- refclk_mhz, 0x1fffff);
+ refclk_mhz, 0xffff);
REG_SET(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_Z8_D, 0,
DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_Z8_D, prog_wm_value);
DC_LOG_BANDWIDTH_CALCS("SR_EXIT_WATERMARK_Z8_D calculated =%d\n"
@@ -625,7 +628,7 @@ static bool hubbub31_program_pstate_watermarks(
watermarks->a.cstate_pstate.pstate_change_ns;
prog_wm_value = convert_and_clamp(
watermarks->a.cstate_pstate.pstate_change_ns,
- refclk_mhz, 0x1fffff);
+ refclk_mhz, 0xffff);
REG_SET(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_A, 0,
DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_A, prog_wm_value);
DC_LOG_BANDWIDTH_CALCS("DRAM_CLK_CHANGE_WATERMARK_A calculated =%d\n"
@@ -642,7 +645,7 @@ static bool hubbub31_program_pstate_watermarks(
watermarks->b.cstate_pstate.pstate_change_ns;
prog_wm_value = convert_and_clamp(
watermarks->b.cstate_pstate.pstate_change_ns,
- refclk_mhz, 0x1fffff);
+ refclk_mhz, 0xffff);
REG_SET(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_B, 0,
DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_B, prog_wm_value);
DC_LOG_BANDWIDTH_CALCS("DRAM_CLK_CHANGE_WATERMARK_B calculated =%d\n"
@@ -659,7 +662,7 @@ static bool hubbub31_program_pstate_watermarks(
watermarks->c.cstate_pstate.pstate_change_ns;
prog_wm_value = convert_and_clamp(
watermarks->c.cstate_pstate.pstate_change_ns,
- refclk_mhz, 0x1fffff);
+ refclk_mhz, 0xffff);
REG_SET(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_C, 0,
DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_C, prog_wm_value);
DC_LOG_BANDWIDTH_CALCS("DRAM_CLK_CHANGE_WATERMARK_C calculated =%d\n"
@@ -676,7 +679,7 @@ static bool hubbub31_program_pstate_watermarks(
watermarks->d.cstate_pstate.pstate_change_ns;
prog_wm_value = convert_and_clamp(
watermarks->d.cstate_pstate.pstate_change_ns,
- refclk_mhz, 0x1fffff);
+ refclk_mhz, 0xffff);
REG_SET(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_D, 0,
DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_D, prog_wm_value);
DC_LOG_BANDWIDTH_CALCS("DRAM_CLK_CHANGE_WATERMARK_D calculated =%d\n"
@@ -946,6 +949,65 @@ static void hubbub31_get_dchub_ref_freq(struct hubbub *hubbub,
}
}
+static bool hubbub31_verify_allow_pstate_change_high(struct hubbub *hubbub)
+{
+ struct dcn20_hubbub *hubbub2 = TO_DCN20_HUBBUB(hubbub);
+
+ /*
+ * Pstate latency is ~20us so if we wait over 40us and pstate allow
+ * still not asserted, we are probably stuck and going to hang
+ */
+ const unsigned int pstate_wait_timeout_us = 100;
+ const unsigned int pstate_wait_expected_timeout_us = 40;
+
+ static unsigned int max_sampled_pstate_wait_us; /* data collection */
+ static bool forced_pstate_allow; /* help with revert wa */
+
+ unsigned int debug_data = 0;
+ unsigned int i;
+
+ if (forced_pstate_allow) {
+ /* we hacked to force pstate allow to prevent hang last time
+ * we verify_allow_pstate_change_high. so disable force
+ * here so we can check status
+ */
+ REG_UPDATE_2(DCHUBBUB_ARB_DRAM_STATE_CNTL,
+ DCHUBBUB_ARB_ALLOW_PSTATE_CHANGE_FORCE_VALUE, 0,
+ DCHUBBUB_ARB_ALLOW_PSTATE_CHANGE_FORCE_ENABLE, 0);
+ forced_pstate_allow = false;
+ }
+
+ REG_WRITE(DCHUBBUB_TEST_DEBUG_INDEX, hubbub2->debug_test_index_pstate);
+
+ for (i = 0; i < pstate_wait_timeout_us; i++) {
+ debug_data = REG_READ(DCHUBBUB_TEST_DEBUG_DATA);
+
+ /* Debug bit is specific to ASIC. */
+ if (debug_data & (1 << 26)) {
+ if (i > pstate_wait_expected_timeout_us)
+ DC_LOG_WARNING("pstate took longer than expected ~%dus\n", i);
+ return true;
+ }
+ if (max_sampled_pstate_wait_us < i)
+ max_sampled_pstate_wait_us = i;
+
+ udelay(1);
+ }
+
+ /* force pstate allow to prevent system hang
+ * and break to debugger to investigate
+ */
+ REG_UPDATE_2(DCHUBBUB_ARB_DRAM_STATE_CNTL,
+ DCHUBBUB_ARB_ALLOW_PSTATE_CHANGE_FORCE_VALUE, 1,
+ DCHUBBUB_ARB_ALLOW_PSTATE_CHANGE_FORCE_ENABLE, 1);
+ forced_pstate_allow = true;
+
+ DC_LOG_WARNING("pstate TEST_DEBUG_DATA: 0x%X\n",
+ debug_data);
+
+ return false;
+}
+
static const struct hubbub_funcs hubbub31_funcs = {
.update_dchub = hubbub2_update_dchub,
.init_dchub_sys_ctx = hubbub31_init_dchub_sys_ctx,
@@ -958,6 +1020,7 @@ static const struct hubbub_funcs hubbub31_funcs = {
.program_watermarks = hubbub31_program_watermarks,
.allow_self_refresh_control = hubbub1_allow_self_refresh_control,
.is_allow_self_refresh_enabled = hubbub1_is_allow_self_refresh_enabled,
+ .verify_allow_pstate_change_high = hubbub31_verify_allow_pstate_change_high,
.program_det_size = dcn31_program_det_size,
.program_compbuf_size = dcn31_program_compbuf_size,
.init_crb = dcn31_init_crb,
diff --git a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hwseq.c
index 4206ce5bf9a9..4be228680909 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hwseq.c
@@ -194,11 +194,10 @@ void dcn31_init_hw(struct dc *dc)
/* Enables outbox notifications for usb4 dpia */
if (dc->res_pool->usb4_dpia_count)
- dmub_enable_outbox_notification(dc);
+ dmub_enable_outbox_notification(dc->ctx->dmub_srv);
/* we want to turn off all dp displays before doing detection */
- if (dc->config.power_down_display_on_boot)
- dc_link_blank_all_dp_displays(dc);
+ dc_link_blank_all_dp_displays(dc);
/* If taking control over from VBIOS, we may want to optimize our first
* mode set, so we need to skip powering down pipes until we know which
@@ -206,7 +205,7 @@ void dcn31_init_hw(struct dc *dc)
* Otherwise, if taking control is not possible, we need to power
* everything down.
*/
- if (dcb->funcs->is_accelerated_mode(dcb) || dc->config.power_down_display_on_boot) {
+ if (dcb->funcs->is_accelerated_mode(dcb) || !dc->config.seamless_boot_edp_requested) {
hws->funcs.init_pipes(dc, dc->current_state);
if (dc->res_pool->hubbub->funcs->allow_self_refresh_control)
dc->res_pool->hubbub->funcs->allow_self_refresh_control(dc->res_pool->hubbub,
@@ -340,21 +339,31 @@ void dcn31_enable_power_gating_plane(
{
bool force_on = true; /* disable power gating */
- if (enable)
+ if (enable && !hws->ctx->dc->debug.disable_hubp_power_gate)
force_on = false;
/* DCHUBP0/1/2/3/4/5 */
REG_UPDATE(DOMAIN0_PG_CONFIG, DOMAIN_POWER_FORCEON, force_on);
+ REG_WAIT(DOMAIN0_PG_STATUS, DOMAIN_PGFSM_PWR_STATUS, force_on, 1, 1000);
REG_UPDATE(DOMAIN2_PG_CONFIG, DOMAIN_POWER_FORCEON, force_on);
-
+ REG_WAIT(DOMAIN2_PG_STATUS, DOMAIN_PGFSM_PWR_STATUS, force_on, 1, 1000);
/* DPP0/1/2/3/4/5 */
REG_UPDATE(DOMAIN1_PG_CONFIG, DOMAIN_POWER_FORCEON, force_on);
+ REG_WAIT(DOMAIN1_PG_STATUS, DOMAIN_PGFSM_PWR_STATUS, force_on, 1, 1000);
REG_UPDATE(DOMAIN3_PG_CONFIG, DOMAIN_POWER_FORCEON, force_on);
+ REG_WAIT(DOMAIN3_PG_STATUS, DOMAIN_PGFSM_PWR_STATUS, force_on, 1, 1000);
+
+ force_on = true; /* disable power gating */
+ if (enable && !hws->ctx->dc->debug.disable_dsc_power_gate)
+ force_on = false;
/* DCS0/1/2/3/4/5 */
REG_UPDATE(DOMAIN16_PG_CONFIG, DOMAIN_POWER_FORCEON, force_on);
+ REG_WAIT(DOMAIN16_PG_STATUS, DOMAIN_PGFSM_PWR_STATUS, force_on, 1, 1000);
REG_UPDATE(DOMAIN17_PG_CONFIG, DOMAIN_POWER_FORCEON, force_on);
+ REG_WAIT(DOMAIN17_PG_STATUS, DOMAIN_PGFSM_PWR_STATUS, force_on, 1, 1000);
REG_UPDATE(DOMAIN18_PG_CONFIG, DOMAIN_POWER_FORCEON, force_on);
+ REG_WAIT(DOMAIN18_PG_STATUS, DOMAIN_PGFSM_PWR_STATUS, force_on, 1, 1000);
}
void dcn31_update_info_frame(struct pipe_ctx *pipe_ctx)
@@ -420,12 +429,15 @@ void dcn31_hubp_pg_control(struct dce_hwseq *hws, unsigned int hubp_inst, bool p
{
uint32_t power_gate = power_on ? 0 : 1;
uint32_t pwr_status = power_on ? 0 : 2;
-
+ uint32_t org_ip_request_cntl;
if (hws->ctx->dc->debug.disable_hubp_power_gate)
return;
if (REG(DOMAIN0_PG_CONFIG) == 0)
return;
+ REG_GET(DC_IP_REQUEST_CNTL, IP_REQUEST_EN, &org_ip_request_cntl);
+ if (org_ip_request_cntl == 0)
+ REG_SET(DC_IP_REQUEST_CNTL, 0, IP_REQUEST_EN, 1);
switch (hubp_inst) {
case 0:
@@ -448,6 +460,8 @@ void dcn31_hubp_pg_control(struct dce_hwseq *hws, unsigned int hubp_inst, bool p
BREAK_TO_DEBUGGER();
break;
}
+ if (org_ip_request_cntl == 0)
+ REG_SET(DC_IP_REQUEST_CNTL, 0, IP_REQUEST_EN, 0);
}
int dcn31_init_sys_ctx(struct dce_hwseq *hws, struct dc *dc, struct dc_phy_addr_space_config *pa_config)
diff --git a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_optc.c b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_optc.c
index e8562fa11366..8afe2130d7c5 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_optc.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_optc.c
@@ -161,7 +161,7 @@ static bool optc31_immediate_disable_crtc(struct timing_generator *optc)
return true;
}
-static void optc31_set_drr(
+void optc31_set_drr(
struct timing_generator *optc,
const struct drr_params *params)
{
diff --git a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_optc.h b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_optc.h
index d8ef2f0d0c95..a37b16040c1d 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_optc.h
+++ b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_optc.h
@@ -256,4 +256,6 @@
void dcn31_timing_generator_init(struct optc *optc1);
+void optc31_set_drr(struct timing_generator *optc, const struct drr_params *params);
+
#endif /* __DC_OPTC_DCN31_H__ */
diff --git a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_panel_cntl.c b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_panel_cntl.c
index 83ece02380a8..11ea9d13e312 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_panel_cntl.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_panel_cntl.c
@@ -83,7 +83,8 @@ static uint32_t dcn31_panel_cntl_hw_init(struct panel_cntl *panel_cntl)
cmd.panel_cntl.data.bl_pwm_period_cntl = panel_cntl->stored_backlight_registers.BL_PWM_PERIOD_CNTL;
cmd.panel_cntl.data.bl_pwm_ref_div1 =
panel_cntl->stored_backlight_registers.LVTMA_PWRSEQ_REF_DIV_BL_PWM_REF_DIV;
-
+ cmd.panel_cntl.data.bl_pwm_ref_div2 =
+ panel_cntl->stored_backlight_registers.PANEL_PWRSEQ_REF_DIV2;
if (!dc_dmub_srv_cmd_with_reply_data(dc_dmub_srv, &cmd))
return 0;
@@ -92,6 +93,8 @@ static uint32_t dcn31_panel_cntl_hw_init(struct panel_cntl *panel_cntl)
panel_cntl->stored_backlight_registers.BL_PWM_PERIOD_CNTL = cmd.panel_cntl.data.bl_pwm_period_cntl;
panel_cntl->stored_backlight_registers.LVTMA_PWRSEQ_REF_DIV_BL_PWM_REF_DIV =
cmd.panel_cntl.data.bl_pwm_ref_div1;
+ panel_cntl->stored_backlight_registers.PANEL_PWRSEQ_REF_DIV2 =
+ cmd.panel_cntl.data.bl_pwm_ref_div2;
return cmd.panel_cntl.data.current_backlight;
}
diff --git a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.c b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.c
index 42ed47e8133d..89b7b6b7254a 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.c
@@ -1011,7 +1011,7 @@ static const struct dc_debug_options debug_defaults_drv = {
.max_downscale_src_width = 4096,/*upto true 4K*/
.disable_pplib_wm_range = false,
.scl_reset_length10 = true,
- .sanity_checks = false,
+ .sanity_checks = true,
.underflow_assert_delay_us = 0xFFFFFFFF,
.dwb_fi_phase = -1, // -1 = disable,
.dmub_command_table = true,
@@ -1033,6 +1033,7 @@ static const struct dc_debug_options debug_defaults_drv = {
.optimize_edp_link_rate = true,
.enable_sw_cntl_psr = true,
.apply_vendor_specific_lttpr_wa = true,
+ .enable_z9_disable_interface = true, /* Allow support for the PMFW interface for disable Z9*/
};
static const struct dc_debug_options debug_defaults_diags = {
@@ -1776,7 +1777,7 @@ static bool is_dual_plane(enum surface_pixel_format format)
return format >= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN || format == SURFACE_PIXEL_FORMAT_GRPH_RGBE_ALPHA;
}
-static int dcn31_populate_dml_pipes_from_context(
+int dcn31_populate_dml_pipes_from_context(
struct dc *dc, struct dc_state *context,
display_e2e_pipe_params_st *pipes,
bool fast_validate)
@@ -1786,7 +1787,9 @@ static int dcn31_populate_dml_pipes_from_context(
struct pipe_ctx *pipe;
bool upscaled = false;
+ DC_FP_START();
dcn20_populate_dml_pipes_from_context(dc, context, pipes, fast_validate);
+ DC_FP_END();
for (i = 0, pipe_cnt = 0; i < dc->res_pool->pipe_count; i++) {
struct dc_crtc_timing *timing;
@@ -1809,6 +1812,7 @@ static int dcn31_populate_dml_pipes_from_context(
pipes[pipe_cnt].pipe.src.immediate_flip = true;
pipes[pipe_cnt].pipe.src.unbounded_req_mode = false;
+ pipes[pipe_cnt].pipe.src.hostvm = dc->res_pool->hubbub->riommu_active;
pipes[pipe_cnt].pipe.src.gpuvm = true;
pipes[pipe_cnt].pipe.src.dcc_fraction_of_zs_req_luma = 0;
pipes[pipe_cnt].pipe.src.dcc_fraction_of_zs_req_chroma = 0;
@@ -1841,7 +1845,8 @@ static int dcn31_populate_dml_pipes_from_context(
if (is_dual_plane(pipe->plane_state->format)
&& pipe->plane_state->src_rect.width <= 1920 && pipe->plane_state->src_rect.height <= 1080) {
dc->config.enable_4to1MPC = true;
- } else if (!is_dual_plane(pipe->plane_state->format)) {
+ } else if (!is_dual_plane(pipe->plane_state->format) && pipe->plane_state->src_rect.width <= 5120) {
+ /* Limit to 5k max to avoid forced pipe split when there is not enough detile for swath */
context->bw_ctx.dml.ip.det_buffer_size_kbytes = 192;
pipes[0].pipe.src.unbounded_req_mode = true;
}
@@ -1996,7 +2001,9 @@ static void dcn31_calculate_wm_and_dlg_fp(
pipe_idx++;
}
+ DC_FP_START();
dcn20_calculate_dlg_params(dc, context, pipes, pipe_cnt, vlevel);
+ DC_FP_END();
}
void dcn31_calculate_wm_and_dlg(
@@ -2066,7 +2073,7 @@ static struct dc_cap_funcs cap_funcs = {
.get_dcc_compression_cap = dcn20_get_dcc_compression_cap
};
-static void dcn31_update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_params)
+void dcn31_update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_params)
{
struct clk_limit_table *clk_table = &bw_params->clk_table;
struct _vcs_dpi_voltage_scaling_st clock_limits[DC__VOLTAGE_STATES];
@@ -2174,7 +2181,7 @@ static struct clock_source *dcn30_clock_source_create(
if (!clk_src)
return NULL;
- if (dcn3_clk_src_construct(clk_src, ctx, bios, id,
+ if (dcn31_clk_src_construct(clk_src, ctx, bios, id,
regs, &cs_shift, &cs_mask)) {
clk_src->base.dp_clk_src = dp_clk_src;
return &clk_src->base;
@@ -2260,6 +2267,9 @@ static bool dcn31_resource_construct(
dc->caps.color.mpc.ogam_rom_caps.hlg = 0;
dc->caps.color.mpc.ocsc = 1;
+ /* Use pipe context based otg sync logic */
+ dc->config.use_pipe_ctx_sync_logic = true;
+
/* read VBIOS LTTPR caps */
{
if (ctx->dc_bios->funcs->get_lttpr_caps) {
diff --git a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.h b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.h
index a513363b3326..4b7ab21ea15b 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.h
+++ b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.h
@@ -43,6 +43,11 @@ void dcn31_calculate_wm_and_dlg(
display_e2e_pipe_params_st *pipes,
int pipe_cnt,
int vlevel);
+int dcn31_populate_dml_pipes_from_context(
+ struct dc *dc, struct dc_state *context,
+ display_e2e_pipe_params_st *pipes,
+ bool fast_validate);
+void dcn31_update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_params);
void dcn31_update_soc_for_wm_a(struct dc *dc, struct dc_state *context);
struct resource_pool *dcn31_create_resource_pool(
diff --git a/drivers/gpu/drm/amd/display/dc/calcs/Makefile b/drivers/gpu/drm/amd/display/dc/dcn315/Makefile
index f3c00f479e1c..c831ad46e81c 100644
--- a/drivers/gpu/drm/amd/display/dc/calcs/Makefile
+++ b/drivers/gpu/drm/amd/display/dc/dcn315/Makefile
@@ -1,6 +1,5 @@
#
-# Copyright 2017 Advanced Micro Devices, Inc.
-# Copyright 2019 Raptor Engineering, LLC
+# Copyright © 2021 Advanced Micro Devices, Inc.
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the "Software"),
@@ -20,23 +19,25 @@
# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
# OTHER DEALINGS IN THE SOFTWARE.
#
+# Authors: AMD
#
-# Makefile for the 'calcs' sub-component of DAL.
-# It calculates Bandwidth and Watermarks values for HW programming
-#
+# Makefile for dcn315.
+
+DCN315 = dcn315_resource.o
ifdef CONFIG_X86
-calcs_ccflags := -mhard-float -msse
+CFLAGS_$(AMDDALPATH)/dc/dcn315/dcn315_resource.o := -msse
endif
ifdef CONFIG_PPC64
-calcs_ccflags := -mhard-float -maltivec
+CFLAGS_$(AMDDALPATH)/dc/dcn315/dcn315_resource.o := -mhard-float -maltivec
endif
ifdef CONFIG_CC_IS_GCC
ifeq ($(call cc-ifversion, -lt, 0701, y), y)
IS_OLD_GCC = 1
endif
+CFLAGS_$(AMDDALPATH)/dc/dcn315/dcn315_resource.o += -mhard-float
endif
ifdef CONFIG_X86
@@ -44,25 +45,12 @@ ifdef IS_OLD_GCC
# Stack alignment mismatch, proceed with caution.
# GCC < 7.1 cannot compile code using `double` and -mpreferred-stack-boundary=3
# (8B stack alignment).
-calcs_ccflags += -mpreferred-stack-boundary=4
+CFLAGS_$(AMDDALPATH)/dc/dcn315/dcn315_resource.o += -mpreferred-stack-boundary=4
else
-calcs_ccflags += -msse2
-endif
+CFLAGS_$(AMDDALPATH)/dc/dcn315/dcn315_resource.o += -msse2
endif
-
-CFLAGS_$(AMDDALPATH)/dc/calcs/dcn_calcs.o := $(calcs_ccflags)
-CFLAGS_$(AMDDALPATH)/dc/calcs/dcn_calc_auto.o := $(calcs_ccflags)
-CFLAGS_$(AMDDALPATH)/dc/calcs/dcn_calc_math.o := $(calcs_ccflags) -Wno-tautological-compare
-CFLAGS_REMOVE_$(AMDDALPATH)/dc/calcs/dcn_calcs.o := $(calcs_rcflags)
-CFLAGS_REMOVE_$(AMDDALPATH)/dc/calcs/dcn_calc_auto.o := $(calcs_rcflags)
-CFLAGS_REMOVE_$(AMDDALPATH)/dc/calcs/dcn_calc_math.o := $(calcs_rcflags)
-
-BW_CALCS = dce_calcs.o bw_fixed.o custom_float.o
-
-ifdef CONFIG_DRM_AMD_DC_DCN
-BW_CALCS += dcn_calcs.o dcn_calc_math.o dcn_calc_auto.o
endif
-AMD_DAL_BW_CALCS = $(addprefix $(AMDDALPATH)/dc/calcs/,$(BW_CALCS))
+AMD_DAL_DCN315 = $(addprefix $(AMDDALPATH)/dc/dcn315/,$(DCN315))
-AMD_DISPLAY_FILES += $(AMD_DAL_BW_CALCS)
+AMD_DISPLAY_FILES += $(AMD_DAL_DCN315)
diff --git a/drivers/gpu/drm/amd/display/dc/dcn315/dcn315_resource.c b/drivers/gpu/drm/amd/display/dc/dcn315/dcn315_resource.c
new file mode 100644
index 000000000000..06adb77c206b
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/dc/dcn315/dcn315_resource.c
@@ -0,0 +1,2284 @@
+/*
+ * Copyright 2021 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: AMD
+ *
+ */
+
+
+#include "dm_services.h"
+#include "dc.h"
+
+#include "dcn31/dcn31_init.h"
+
+#include "resource.h"
+#include "include/irq_service_interface.h"
+#include "dcn315_resource.h"
+
+#include "dcn20/dcn20_resource.h"
+#include "dcn30/dcn30_resource.h"
+#include "dcn31/dcn31_resource.h"
+
+#include "dcn10/dcn10_ipp.h"
+#include "dcn30/dcn30_hubbub.h"
+#include "dcn31/dcn31_hubbub.h"
+#include "dcn30/dcn30_mpc.h"
+#include "dcn31/dcn31_hubp.h"
+#include "irq/dcn315/irq_service_dcn315.h"
+#include "dcn30/dcn30_dpp.h"
+#include "dcn31/dcn31_optc.h"
+#include "dcn20/dcn20_hwseq.h"
+#include "dcn30/dcn30_hwseq.h"
+#include "dce110/dce110_hw_sequencer.h"
+#include "dcn30/dcn30_opp.h"
+#include "dcn20/dcn20_dsc.h"
+#include "dcn30/dcn30_vpg.h"
+#include "dcn30/dcn30_afmt.h"
+#include "dcn30/dcn30_dio_stream_encoder.h"
+#include "dcn31/dcn31_hpo_dp_stream_encoder.h"
+#include "dcn31/dcn31_hpo_dp_link_encoder.h"
+#include "dcn31/dcn31_apg.h"
+#include "dcn31/dcn31_dio_link_encoder.h"
+#include "dcn31/dcn31_vpg.h"
+#include "dcn31/dcn31_afmt.h"
+#include "dce/dce_clock_source.h"
+#include "dce/dce_audio.h"
+#include "dce/dce_hwseq.h"
+#include "clk_mgr.h"
+#include "virtual/virtual_stream_encoder.h"
+#include "dce110/dce110_resource.h"
+#include "dml/display_mode_vba.h"
+#include "dcn31/dcn31_dccg.h"
+#include "dcn10/dcn10_resource.h"
+#include "dcn31/dcn31_panel_cntl.h"
+
+#include "dcn30/dcn30_dwb.h"
+#include "dcn30/dcn30_mmhubbub.h"
+
+#include "dcn/dcn_3_1_5_offset.h"
+#include "dcn/dcn_3_1_5_sh_mask.h"
+#include "dpcs/dpcs_4_2_2_offset.h"
+#include "dpcs/dpcs_4_2_2_sh_mask.h"
+
+#define NBIO_BASE__INST0_SEG0 0x00000000
+#define NBIO_BASE__INST0_SEG1 0x00000014
+#define NBIO_BASE__INST0_SEG2 0x00000D20
+#define NBIO_BASE__INST0_SEG3 0x00010400
+#define NBIO_BASE__INST0_SEG4 0x0241B000
+#define NBIO_BASE__INST0_SEG5 0x04040000
+
+#define DPCS_BASE__INST0_SEG0 0x00000012
+#define DPCS_BASE__INST0_SEG1 0x000000C0
+#define DPCS_BASE__INST0_SEG2 0x000034C0
+#define DPCS_BASE__INST0_SEG3 0x00009000
+#define DPCS_BASE__INST0_SEG4 0x02403C00
+#define DPCS_BASE__INST0_SEG5 0
+
+#define DCN_BASE__INST0_SEG0 0x00000012
+#define DCN_BASE__INST0_SEG1 0x000000C0
+#define DCN_BASE__INST0_SEG2 0x000034C0
+#define DCN_BASE__INST0_SEG3 0x00009000
+#define DCN_BASE__INST0_SEG4 0x02403C00
+#define DCN_BASE__INST0_SEG5 0
+
+#define regBIF_BX_PF2_RSMU_INDEX 0x0000
+#define regBIF_BX_PF2_RSMU_INDEX_BASE_IDX 1
+#define regBIF_BX_PF2_RSMU_DATA 0x0001
+#define regBIF_BX_PF2_RSMU_DATA_BASE_IDX 1
+#define regBIF_BX2_BIOS_SCRATCH_6 0x003e
+#define regBIF_BX2_BIOS_SCRATCH_6_BASE_IDX 1
+#define BIF_BX2_BIOS_SCRATCH_6__BIOS_SCRATCH_6__SHIFT 0x0
+#define BIF_BX2_BIOS_SCRATCH_6__BIOS_SCRATCH_6_MASK 0xFFFFFFFFL
+#define regBIF_BX2_BIOS_SCRATCH_2 0x003a
+#define regBIF_BX2_BIOS_SCRATCH_2_BASE_IDX 1
+#define BIF_BX2_BIOS_SCRATCH_2__BIOS_SCRATCH_2__SHIFT 0x0
+#define BIF_BX2_BIOS_SCRATCH_2__BIOS_SCRATCH_2_MASK 0xFFFFFFFFL
+#define regBIF_BX2_BIOS_SCRATCH_3 0x003b
+#define regBIF_BX2_BIOS_SCRATCH_3_BASE_IDX 1
+#define BIF_BX2_BIOS_SCRATCH_3__BIOS_SCRATCH_3__SHIFT 0x0
+#define BIF_BX2_BIOS_SCRATCH_3__BIOS_SCRATCH_3_MASK 0xFFFFFFFFL
+
+#define regDCHUBBUB_DEBUG_CTRL_0 0x04d6
+#define regDCHUBBUB_DEBUG_CTRL_0_BASE_IDX 2
+#define DCHUBBUB_DEBUG_CTRL_0__DET_DEPTH__SHIFT 0x10
+#define DCHUBBUB_DEBUG_CTRL_0__DET_DEPTH_MASK 0x01FF0000L
+
+#include "reg_helper.h"
+#include "dce/dmub_abm.h"
+#include "dce/dmub_psr.h"
+#include "dce/dce_aux.h"
+#include "dce/dce_i2c.h"
+
+#include "dml/dcn30/display_mode_vba_30.h"
+#include "vm_helper.h"
+#include "dcn20/dcn20_vmid.h"
+
+#include "link_enc_cfg.h"
+
+#define DC_LOGGER_INIT(logger)
+
+#define DCN3_15_DEFAULT_DET_SIZE 192
+#define DCN3_15_MAX_DET_SIZE 384
+#define DCN3_15_MIN_COMPBUF_SIZE_KB 128
+#define DCN3_15_CRB_SEGMENT_SIZE_KB 64
+
+struct _vcs_dpi_ip_params_st dcn3_15_ip = {
+ .gpuvm_enable = 1,
+ .gpuvm_max_page_table_levels = 1,
+ .hostvm_enable = 1,
+ .hostvm_max_page_table_levels = 2,
+ .rob_buffer_size_kbytes = 64,
+ .det_buffer_size_kbytes = DCN3_15_DEFAULT_DET_SIZE,
+ .min_comp_buffer_size_kbytes = DCN3_15_MIN_COMPBUF_SIZE_KB,
+ .config_return_buffer_size_in_kbytes = 1024,
+ .compressed_buffer_segment_size_in_kbytes = 64,
+ .meta_fifo_size_in_kentries = 32,
+ .zero_size_buffer_entries = 512,
+ .compbuf_reserved_space_64b = 256,
+ .compbuf_reserved_space_zs = 64,
+ .dpp_output_buffer_pixels = 2560,
+ .opp_output_buffer_lines = 1,
+ .pixel_chunk_size_kbytes = 8,
+ .meta_chunk_size_kbytes = 2,
+ .min_meta_chunk_size_bytes = 256,
+ .writeback_chunk_size_kbytes = 8,
+ .ptoi_supported = false,
+ .num_dsc = 3,
+ .maximum_dsc_bits_per_component = 10,
+ .dsc422_native_support = false,
+ .is_line_buffer_bpp_fixed = true,
+ .line_buffer_fixed_bpp = 49,
+ .line_buffer_size_bits = 789504,
+ .max_line_buffer_lines = 12,
+ .writeback_interface_buffer_size_kbytes = 90,
+ .max_num_dpp = 4,
+ .max_num_otg = 4,
+ .max_num_hdmi_frl_outputs = 1,
+ .max_num_wb = 1,
+ .max_dchub_pscl_bw_pix_per_clk = 4,
+ .max_pscl_lb_bw_pix_per_clk = 2,
+ .max_lb_vscl_bw_pix_per_clk = 4,
+ .max_vscl_hscl_bw_pix_per_clk = 4,
+ .max_hscl_ratio = 6,
+ .max_vscl_ratio = 6,
+ .max_hscl_taps = 8,
+ .max_vscl_taps = 8,
+ .dpte_buffer_size_in_pte_reqs_luma = 64,
+ .dpte_buffer_size_in_pte_reqs_chroma = 34,
+ .dispclk_ramp_margin_percent = 1,
+ .max_inter_dcn_tile_repeaters = 9,
+ .cursor_buffer_size = 16,
+ .cursor_chunk_size = 2,
+ .writeback_line_buffer_buffer_size = 0,
+ .writeback_min_hscl_ratio = 1,
+ .writeback_min_vscl_ratio = 1,
+ .writeback_max_hscl_ratio = 1,
+ .writeback_max_vscl_ratio = 1,
+ .writeback_max_hscl_taps = 1,
+ .writeback_max_vscl_taps = 1,
+ .dppclk_delay_subtotal = 46,
+ .dppclk_delay_scl = 50,
+ .dppclk_delay_scl_lb_only = 16,
+ .dppclk_delay_cnvc_formatter = 27,
+ .dppclk_delay_cnvc_cursor = 6,
+ .dispclk_delay_subtotal = 119,
+ .dynamic_metadata_vm_enabled = false,
+ .odm_combine_4to1_supported = false,
+ .dcc_supported = true,
+};
+
+struct _vcs_dpi_soc_bounding_box_st dcn3_15_soc = {
+ /*TODO: correct dispclk/dppclk voltage level determination*/
+ .clock_limits = {
+ {
+ .state = 0,
+ .dispclk_mhz = 1372.0,
+ .dppclk_mhz = 1372.0,
+ .phyclk_mhz = 810.0,
+ .phyclk_d18_mhz = 667.0,
+ .dscclk_mhz = 417.0,
+ .dtbclk_mhz = 600.0,
+ },
+ {
+ .state = 1,
+ .dispclk_mhz = 1372.0,
+ .dppclk_mhz = 1372.0,
+ .phyclk_mhz = 810.0,
+ .phyclk_d18_mhz = 667.0,
+ .dscclk_mhz = 417.0,
+ .dtbclk_mhz = 600.0,
+ },
+ {
+ .state = 2,
+ .dispclk_mhz = 1372.0,
+ .dppclk_mhz = 1372.0,
+ .phyclk_mhz = 810.0,
+ .phyclk_d18_mhz = 667.0,
+ .dscclk_mhz = 417.0,
+ .dtbclk_mhz = 600.0,
+ },
+ {
+ .state = 3,
+ .dispclk_mhz = 1372.0,
+ .dppclk_mhz = 1372.0,
+ .phyclk_mhz = 810.0,
+ .phyclk_d18_mhz = 667.0,
+ .dscclk_mhz = 417.0,
+ .dtbclk_mhz = 600.0,
+ },
+ {
+ .state = 4,
+ .dispclk_mhz = 1372.0,
+ .dppclk_mhz = 1372.0,
+ .phyclk_mhz = 810.0,
+ .phyclk_d18_mhz = 667.0,
+ .dscclk_mhz = 417.0,
+ .dtbclk_mhz = 600.0,
+ },
+ },
+ .num_states = 5,
+ .sr_exit_time_us = 9.0,
+ .sr_enter_plus_exit_time_us = 11.0,
+ .sr_exit_z8_time_us = 50.0,
+ .sr_enter_plus_exit_z8_time_us = 50.0,
+ .writeback_latency_us = 12.0,
+ .dram_channel_width_bytes = 4,
+ .round_trip_ping_latency_dcfclk_cycles = 106,
+ .urgent_latency_pixel_data_only_us = 4.0,
+ .urgent_latency_pixel_mixed_with_vm_data_us = 4.0,
+ .urgent_latency_vm_data_only_us = 4.0,
+ .urgent_out_of_order_return_per_channel_pixel_only_bytes = 4096,
+ .urgent_out_of_order_return_per_channel_pixel_and_vm_bytes = 4096,
+ .urgent_out_of_order_return_per_channel_vm_only_bytes = 4096,
+ .pct_ideal_sdp_bw_after_urgent = 80.0,
+ .pct_ideal_dram_sdp_bw_after_urgent_pixel_only = 65.0,
+ .pct_ideal_dram_sdp_bw_after_urgent_pixel_and_vm = 60.0,
+ .pct_ideal_dram_sdp_bw_after_urgent_vm_only = 30.0,
+ .max_avg_sdp_bw_use_normal_percent = 60.0,
+ .max_avg_dram_bw_use_normal_percent = 60.0,
+ .fabric_datapath_to_dcn_data_return_bytes = 32,
+ .return_bus_width_bytes = 64,
+ .downspread_percent = 0.38,
+ .dcn_downspread_percent = 0.38,
+ .gpuvm_min_page_size_bytes = 4096,
+ .hostvm_min_page_size_bytes = 4096,
+ .do_urgent_latency_adjustment = false,
+ .urgent_latency_adjustment_fabric_clock_component_us = 0,
+ .urgent_latency_adjustment_fabric_clock_reference_mhz = 0,
+};
+
+enum dcn31_clk_src_array_id {
+ DCN31_CLK_SRC_PLL0,
+ DCN31_CLK_SRC_PLL1,
+ DCN31_CLK_SRC_PLL2,
+ DCN31_CLK_SRC_PLL3,
+ DCN31_CLK_SRC_PLL4,
+ DCN30_CLK_SRC_TOTAL
+};
+
+/* begin *********************
+ * macros to expend register list macro defined in HW object header file
+ */
+
+/* DCN */
+/* TODO awful hack. fixup dcn20_dwb.h */
+#undef BASE_INNER
+#define BASE_INNER(seg) DCN_BASE__INST0_SEG ## seg
+
+#define BASE(seg) BASE_INNER(seg)
+
+#define SR(reg_name)\
+ .reg_name = BASE(reg ## reg_name ## _BASE_IDX) + \
+ reg ## reg_name
+
+#define SRI(reg_name, block, id)\
+ .reg_name = BASE(reg ## block ## id ## _ ## reg_name ## _BASE_IDX) + \
+ reg ## block ## id ## _ ## reg_name
+
+#define SRI2(reg_name, block, id)\
+ .reg_name = BASE(reg ## reg_name ## _BASE_IDX) + \
+ reg ## reg_name
+
+#define SRIR(var_name, reg_name, block, id)\
+ .var_name = BASE(reg ## block ## id ## _ ## reg_name ## _BASE_IDX) + \
+ reg ## block ## id ## _ ## reg_name
+
+#define SRII(reg_name, block, id)\
+ .reg_name[id] = BASE(reg ## block ## id ## _ ## reg_name ## _BASE_IDX) + \
+ reg ## block ## id ## _ ## reg_name
+
+#define SRII_MPC_RMU(reg_name, block, id)\
+ .RMU##_##reg_name[id] = BASE(reg ## block ## id ## _ ## reg_name ## _BASE_IDX) + \
+ reg ## block ## id ## _ ## reg_name
+
+#define SRII_DWB(reg_name, temp_name, block, id)\
+ .reg_name[id] = BASE(reg ## block ## id ## _ ## temp_name ## _BASE_IDX) + \
+ reg ## block ## id ## _ ## temp_name
+
+#define DCCG_SRII(reg_name, block, id)\
+ .block ## _ ## reg_name[id] = BASE(reg ## block ## id ## _ ## reg_name ## _BASE_IDX) + \
+ reg ## block ## id ## _ ## reg_name
+
+#define VUPDATE_SRII(reg_name, block, id)\
+ .reg_name[id] = BASE(reg ## reg_name ## _ ## block ## id ## _BASE_IDX) + \
+ reg ## reg_name ## _ ## block ## id
+
+/* NBIO */
+#define NBIO_BASE_INNER(seg) \
+ NBIO_BASE__INST0_SEG ## seg
+
+#define NBIO_BASE(seg) \
+ NBIO_BASE_INNER(seg)
+
+#define NBIO_SR(reg_name)\
+ .reg_name = NBIO_BASE(regBIF_BX2_ ## reg_name ## _BASE_IDX) + \
+ regBIF_BX2_ ## reg_name
+
+static const struct bios_registers bios_regs = {
+ NBIO_SR(BIOS_SCRATCH_3),
+ NBIO_SR(BIOS_SCRATCH_6)
+};
+
+#define clk_src_regs(index, pllid)\
+[index] = {\
+ CS_COMMON_REG_LIST_DCN3_0(index, pllid),\
+}
+
+static const struct dce110_clk_src_regs clk_src_regs[] = {
+ clk_src_regs(0, A),
+ clk_src_regs(1, B),
+ clk_src_regs(2, C),
+ clk_src_regs(3, D),
+ clk_src_regs(4, E)
+};
+
+static const struct dce110_clk_src_shift cs_shift = {
+ CS_COMMON_MASK_SH_LIST_DCN2_0(__SHIFT)
+};
+
+static const struct dce110_clk_src_mask cs_mask = {
+ CS_COMMON_MASK_SH_LIST_DCN2_0(_MASK)
+};
+
+#define abm_regs(id)\
+[id] = {\
+ ABM_DCN302_REG_LIST(id)\
+}
+
+static const struct dce_abm_registers abm_regs[] = {
+ abm_regs(0),
+ abm_regs(1),
+ abm_regs(2),
+ abm_regs(3),
+};
+
+static const struct dce_abm_shift abm_shift = {
+ ABM_MASK_SH_LIST_DCN30(__SHIFT)
+};
+
+static const struct dce_abm_mask abm_mask = {
+ ABM_MASK_SH_LIST_DCN30(_MASK)
+};
+
+#define audio_regs(id)\
+[id] = {\
+ AUD_COMMON_REG_LIST(id)\
+}
+
+static const struct dce_audio_registers audio_regs[] = {
+ audio_regs(0),
+ audio_regs(1),
+ audio_regs(2),
+ audio_regs(3),
+ audio_regs(4),
+ audio_regs(5),
+ audio_regs(6)
+};
+
+#define DCE120_AUD_COMMON_MASK_SH_LIST(mask_sh)\
+ SF(AZF0ENDPOINT0_AZALIA_F0_CODEC_ENDPOINT_INDEX, AZALIA_ENDPOINT_REG_INDEX, mask_sh),\
+ SF(AZF0ENDPOINT0_AZALIA_F0_CODEC_ENDPOINT_DATA, AZALIA_ENDPOINT_REG_DATA, mask_sh),\
+ AUD_COMMON_MASK_SH_LIST_BASE(mask_sh)
+
+static const struct dce_audio_shift audio_shift = {
+ DCE120_AUD_COMMON_MASK_SH_LIST(__SHIFT)
+};
+
+static const struct dce_audio_mask audio_mask = {
+ DCE120_AUD_COMMON_MASK_SH_LIST(_MASK)
+};
+
+#define vpg_regs(id)\
+[id] = {\
+ VPG_DCN31_REG_LIST(id)\
+}
+
+static const struct dcn31_vpg_registers vpg_regs[] = {
+ vpg_regs(0),
+ vpg_regs(1),
+ vpg_regs(2),
+ vpg_regs(3),
+ vpg_regs(4),
+ vpg_regs(5),
+ vpg_regs(6),
+ vpg_regs(7),
+ vpg_regs(8),
+ vpg_regs(9),
+};
+
+static const struct dcn31_vpg_shift vpg_shift = {
+ DCN31_VPG_MASK_SH_LIST(__SHIFT)
+};
+
+static const struct dcn31_vpg_mask vpg_mask = {
+ DCN31_VPG_MASK_SH_LIST(_MASK)
+};
+
+#define afmt_regs(id)\
+[id] = {\
+ AFMT_DCN31_REG_LIST(id)\
+}
+
+static const struct dcn31_afmt_registers afmt_regs[] = {
+ afmt_regs(0),
+ afmt_regs(1),
+ afmt_regs(2),
+ afmt_regs(3),
+ afmt_regs(4),
+ afmt_regs(5)
+};
+
+static const struct dcn31_afmt_shift afmt_shift = {
+ DCN31_AFMT_MASK_SH_LIST(__SHIFT)
+};
+
+static const struct dcn31_afmt_mask afmt_mask = {
+ DCN31_AFMT_MASK_SH_LIST(_MASK)
+};
+
+#define apg_regs(id)\
+[id] = {\
+ APG_DCN31_REG_LIST(id)\
+}
+
+static const struct dcn31_apg_registers apg_regs[] = {
+ apg_regs(0),
+ apg_regs(1),
+ apg_regs(2),
+ apg_regs(3)
+};
+
+static const struct dcn31_apg_shift apg_shift = {
+ DCN31_APG_MASK_SH_LIST(__SHIFT)
+};
+
+static const struct dcn31_apg_mask apg_mask = {
+ DCN31_APG_MASK_SH_LIST(_MASK)
+};
+
+#define stream_enc_regs(id)\
+[id] = {\
+ SE_DCN3_REG_LIST(id)\
+}
+
+static const struct dcn10_stream_enc_registers stream_enc_regs[] = {
+ stream_enc_regs(0),
+ stream_enc_regs(1),
+ stream_enc_regs(2),
+ stream_enc_regs(3),
+ stream_enc_regs(4)
+};
+
+static const struct dcn10_stream_encoder_shift se_shift = {
+ SE_COMMON_MASK_SH_LIST_DCN30(__SHIFT)
+};
+
+static const struct dcn10_stream_encoder_mask se_mask = {
+ SE_COMMON_MASK_SH_LIST_DCN30(_MASK)
+};
+
+
+#define aux_regs(id)\
+[id] = {\
+ DCN2_AUX_REG_LIST(id)\
+}
+
+static const struct dcn10_link_enc_aux_registers link_enc_aux_regs[] = {
+ aux_regs(0),
+ aux_regs(1),
+ aux_regs(2),
+ aux_regs(3),
+ aux_regs(4)
+};
+
+#define hpd_regs(id)\
+[id] = {\
+ HPD_REG_LIST(id)\
+}
+
+static const struct dcn10_link_enc_hpd_registers link_enc_hpd_regs[] = {
+ hpd_regs(0),
+ hpd_regs(1),
+ hpd_regs(2),
+ hpd_regs(3),
+ hpd_regs(4)
+};
+
+#define link_regs(id, phyid)\
+[id] = {\
+ LE_DCN31_REG_LIST(id), \
+ UNIPHY_DCN2_REG_LIST(phyid), \
+ DPCS_DCN31_REG_LIST(id), \
+}
+
+static const struct dce110_aux_registers_shift aux_shift = {
+ DCN_AUX_MASK_SH_LIST(__SHIFT)
+};
+
+static const struct dce110_aux_registers_mask aux_mask = {
+ DCN_AUX_MASK_SH_LIST(_MASK)
+};
+
+static const struct dcn10_link_enc_registers link_enc_regs[] = {
+ link_regs(0, A),
+ link_regs(1, B),
+ link_regs(2, C),
+ link_regs(3, D),
+ link_regs(4, E)
+};
+
+static const struct dcn10_link_enc_shift le_shift = {
+ LINK_ENCODER_MASK_SH_LIST_DCN31(__SHIFT), \
+ DPCS_DCN31_MASK_SH_LIST(__SHIFT)
+};
+
+static const struct dcn10_link_enc_mask le_mask = {
+ LINK_ENCODER_MASK_SH_LIST_DCN31(_MASK), \
+ DPCS_DCN31_MASK_SH_LIST(_MASK)
+};
+
+#define hpo_dp_stream_encoder_reg_list(id)\
+[id] = {\
+ DCN3_1_HPO_DP_STREAM_ENC_REG_LIST(id)\
+}
+
+static const struct dcn31_hpo_dp_stream_encoder_registers hpo_dp_stream_enc_regs[] = {
+ hpo_dp_stream_encoder_reg_list(0),
+ hpo_dp_stream_encoder_reg_list(1),
+ hpo_dp_stream_encoder_reg_list(2),
+ hpo_dp_stream_encoder_reg_list(3),
+};
+
+static const struct dcn31_hpo_dp_stream_encoder_shift hpo_dp_se_shift = {
+ DCN3_1_HPO_DP_STREAM_ENC_MASK_SH_LIST(__SHIFT)
+};
+
+static const struct dcn31_hpo_dp_stream_encoder_mask hpo_dp_se_mask = {
+ DCN3_1_HPO_DP_STREAM_ENC_MASK_SH_LIST(_MASK)
+};
+
+
+#define hpo_dp_link_encoder_reg_list(id)\
+[id] = {\
+ DCN3_1_HPO_DP_LINK_ENC_REG_LIST(id),\
+ DCN3_1_RDPCSTX_REG_LIST(0),\
+ DCN3_1_RDPCSTX_REG_LIST(1),\
+ DCN3_1_RDPCSTX_REG_LIST(2),\
+ DCN3_1_RDPCSTX_REG_LIST(3),\
+ DCN3_1_RDPCSTX_REG_LIST(4)\
+}
+
+static const struct dcn31_hpo_dp_link_encoder_registers hpo_dp_link_enc_regs[] = {
+ hpo_dp_link_encoder_reg_list(0),
+ hpo_dp_link_encoder_reg_list(1),
+};
+
+static const struct dcn31_hpo_dp_link_encoder_shift hpo_dp_le_shift = {
+ DCN3_1_HPO_DP_LINK_ENC_MASK_SH_LIST(__SHIFT)
+};
+
+static const struct dcn31_hpo_dp_link_encoder_mask hpo_dp_le_mask = {
+ DCN3_1_HPO_DP_LINK_ENC_MASK_SH_LIST(_MASK)
+};
+
+#define dpp_regs(id)\
+[id] = {\
+ DPP_REG_LIST_DCN30(id),\
+}
+
+static const struct dcn3_dpp_registers dpp_regs[] = {
+ dpp_regs(0),
+ dpp_regs(1),
+ dpp_regs(2),
+ dpp_regs(3)
+};
+
+static const struct dcn3_dpp_shift tf_shift = {
+ DPP_REG_LIST_SH_MASK_DCN30(__SHIFT)
+};
+
+static const struct dcn3_dpp_mask tf_mask = {
+ DPP_REG_LIST_SH_MASK_DCN30(_MASK)
+};
+
+#define opp_regs(id)\
+[id] = {\
+ OPP_REG_LIST_DCN30(id),\
+}
+
+static const struct dcn20_opp_registers opp_regs[] = {
+ opp_regs(0),
+ opp_regs(1),
+ opp_regs(2),
+ opp_regs(3)
+};
+
+static const struct dcn20_opp_shift opp_shift = {
+ OPP_MASK_SH_LIST_DCN20(__SHIFT)
+};
+
+static const struct dcn20_opp_mask opp_mask = {
+ OPP_MASK_SH_LIST_DCN20(_MASK)
+};
+
+#define aux_engine_regs(id)\
+[id] = {\
+ AUX_COMMON_REG_LIST0(id), \
+ .AUXN_IMPCAL = 0, \
+ .AUXP_IMPCAL = 0, \
+ .AUX_RESET_MASK = DP_AUX0_AUX_CONTROL__AUX_RESET_MASK, \
+}
+
+static const struct dce110_aux_registers aux_engine_regs[] = {
+ aux_engine_regs(0),
+ aux_engine_regs(1),
+ aux_engine_regs(2),
+ aux_engine_regs(3),
+ aux_engine_regs(4)
+};
+
+#define dwbc_regs_dcn3(id)\
+[id] = {\
+ DWBC_COMMON_REG_LIST_DCN30(id),\
+}
+
+static const struct dcn30_dwbc_registers dwbc30_regs[] = {
+ dwbc_regs_dcn3(0),
+};
+
+static const struct dcn30_dwbc_shift dwbc30_shift = {
+ DWBC_COMMON_MASK_SH_LIST_DCN30(__SHIFT)
+};
+
+static const struct dcn30_dwbc_mask dwbc30_mask = {
+ DWBC_COMMON_MASK_SH_LIST_DCN30(_MASK)
+};
+
+#define mcif_wb_regs_dcn3(id)\
+[id] = {\
+ MCIF_WB_COMMON_REG_LIST_DCN30(id),\
+}
+
+static const struct dcn30_mmhubbub_registers mcif_wb30_regs[] = {
+ mcif_wb_regs_dcn3(0)
+};
+
+static const struct dcn30_mmhubbub_shift mcif_wb30_shift = {
+ MCIF_WB_COMMON_MASK_SH_LIST_DCN30(__SHIFT)
+};
+
+static const struct dcn30_mmhubbub_mask mcif_wb30_mask = {
+ MCIF_WB_COMMON_MASK_SH_LIST_DCN30(_MASK)
+};
+
+#define dsc_regsDCN20(id)\
+[id] = {\
+ DSC_REG_LIST_DCN20(id)\
+}
+
+static const struct dcn20_dsc_registers dsc_regs[] = {
+ dsc_regsDCN20(0),
+ dsc_regsDCN20(1),
+ dsc_regsDCN20(2)
+};
+
+static const struct dcn20_dsc_shift dsc_shift = {
+ DSC_REG_LIST_SH_MASK_DCN20(__SHIFT)
+};
+
+static const struct dcn20_dsc_mask dsc_mask = {
+ DSC_REG_LIST_SH_MASK_DCN20(_MASK)
+};
+
+static const struct dcn30_mpc_registers mpc_regs = {
+ MPC_REG_LIST_DCN3_0(0),
+ MPC_REG_LIST_DCN3_0(1),
+ MPC_REG_LIST_DCN3_0(2),
+ MPC_REG_LIST_DCN3_0(3),
+ MPC_OUT_MUX_REG_LIST_DCN3_0(0),
+ MPC_OUT_MUX_REG_LIST_DCN3_0(1),
+ MPC_OUT_MUX_REG_LIST_DCN3_0(2),
+ MPC_OUT_MUX_REG_LIST_DCN3_0(3),
+ MPC_DWB_MUX_REG_LIST_DCN3_0(0),
+};
+
+static const struct dcn30_mpc_shift mpc_shift = {
+ MPC_COMMON_MASK_SH_LIST_DCN30(__SHIFT)
+};
+
+static const struct dcn30_mpc_mask mpc_mask = {
+ MPC_COMMON_MASK_SH_LIST_DCN30(_MASK)
+};
+
+#define optc_regs(id)\
+[id] = {OPTC_COMMON_REG_LIST_DCN3_1(id)}
+
+static const struct dcn_optc_registers optc_regs[] = {
+ optc_regs(0),
+ optc_regs(1),
+ optc_regs(2),
+ optc_regs(3)
+};
+
+static const struct dcn_optc_shift optc_shift = {
+ OPTC_COMMON_MASK_SH_LIST_DCN3_1(__SHIFT)
+};
+
+static const struct dcn_optc_mask optc_mask = {
+ OPTC_COMMON_MASK_SH_LIST_DCN3_1(_MASK)
+};
+
+#define hubp_regs(id)\
+[id] = {\
+ HUBP_REG_LIST_DCN30(id)\
+}
+
+static const struct dcn_hubp2_registers hubp_regs[] = {
+ hubp_regs(0),
+ hubp_regs(1),
+ hubp_regs(2),
+ hubp_regs(3)
+};
+
+
+static const struct dcn_hubp2_shift hubp_shift = {
+ HUBP_MASK_SH_LIST_DCN31(__SHIFT)
+};
+
+static const struct dcn_hubp2_mask hubp_mask = {
+ HUBP_MASK_SH_LIST_DCN31(_MASK)
+};
+static const struct dcn_hubbub_registers hubbub_reg = {
+ HUBBUB_REG_LIST_DCN31(0)
+};
+
+static const struct dcn_hubbub_shift hubbub_shift = {
+ HUBBUB_MASK_SH_LIST_DCN31(__SHIFT)
+};
+
+static const struct dcn_hubbub_mask hubbub_mask = {
+ HUBBUB_MASK_SH_LIST_DCN31(_MASK)
+};
+
+static const struct dccg_registers dccg_regs = {
+ DCCG_REG_LIST_DCN31()
+};
+
+static const struct dccg_shift dccg_shift = {
+ DCCG_MASK_SH_LIST_DCN31(__SHIFT)
+};
+
+static const struct dccg_mask dccg_mask = {
+ DCCG_MASK_SH_LIST_DCN31(_MASK)
+};
+
+
+#define SRII2(reg_name_pre, reg_name_post, id)\
+ .reg_name_pre ## _ ## reg_name_post[id] = BASE(reg ## reg_name_pre \
+ ## id ## _ ## reg_name_post ## _BASE_IDX) + \
+ reg ## reg_name_pre ## id ## _ ## reg_name_post
+
+
+#define HWSEQ_DCN31_REG_LIST()\
+ SR(DCHUBBUB_GLOBAL_TIMER_CNTL), \
+ SR(DCHUBBUB_ARB_HOSTVM_CNTL), \
+ SR(DIO_MEM_PWR_CTRL), \
+ SR(ODM_MEM_PWR_CTRL3), \
+ SR(DMU_MEM_PWR_CNTL), \
+ SR(MMHUBBUB_MEM_PWR_CNTL), \
+ SR(DCCG_GATE_DISABLE_CNTL), \
+ SR(DCCG_GATE_DISABLE_CNTL2), \
+ SR(DCFCLK_CNTL),\
+ SR(DC_MEM_GLOBAL_PWR_REQ_CNTL), \
+ SRII(PIXEL_RATE_CNTL, OTG, 0), \
+ SRII(PIXEL_RATE_CNTL, OTG, 1),\
+ SRII(PIXEL_RATE_CNTL, OTG, 2),\
+ SRII(PIXEL_RATE_CNTL, OTG, 3),\
+ SRII(PHYPLL_PIXEL_RATE_CNTL, OTG, 0),\
+ SRII(PHYPLL_PIXEL_RATE_CNTL, OTG, 1),\
+ SRII(PHYPLL_PIXEL_RATE_CNTL, OTG, 2),\
+ SRII(PHYPLL_PIXEL_RATE_CNTL, OTG, 3),\
+ SR(MICROSECOND_TIME_BASE_DIV), \
+ SR(MILLISECOND_TIME_BASE_DIV), \
+ SR(DISPCLK_FREQ_CHANGE_CNTL), \
+ SR(RBBMIF_TIMEOUT_DIS), \
+ SR(RBBMIF_TIMEOUT_DIS_2), \
+ SR(DCHUBBUB_CRC_CTRL), \
+ SR(DPP_TOP0_DPP_CRC_CTRL), \
+ SR(DPP_TOP0_DPP_CRC_VAL_B_A), \
+ SR(DPP_TOP0_DPP_CRC_VAL_R_G), \
+ SR(MPC_CRC_CTRL), \
+ SR(MPC_CRC_RESULT_GB), \
+ SR(MPC_CRC_RESULT_C), \
+ SR(MPC_CRC_RESULT_AR), \
+ SR(DOMAIN0_PG_CONFIG), \
+ SR(DOMAIN1_PG_CONFIG), \
+ SR(DOMAIN2_PG_CONFIG), \
+ SR(DOMAIN3_PG_CONFIG), \
+ SR(DOMAIN16_PG_CONFIG), \
+ SR(DOMAIN17_PG_CONFIG), \
+ SR(DOMAIN18_PG_CONFIG), \
+ SR(DOMAIN0_PG_STATUS), \
+ SR(DOMAIN1_PG_STATUS), \
+ SR(DOMAIN2_PG_STATUS), \
+ SR(DOMAIN3_PG_STATUS), \
+ SR(DOMAIN16_PG_STATUS), \
+ SR(DOMAIN17_PG_STATUS), \
+ SR(DOMAIN18_PG_STATUS), \
+ SR(D1VGA_CONTROL), \
+ SR(D2VGA_CONTROL), \
+ SR(D3VGA_CONTROL), \
+ SR(D4VGA_CONTROL), \
+ SR(D5VGA_CONTROL), \
+ SR(D6VGA_CONTROL), \
+ SR(DC_IP_REQUEST_CNTL), \
+ SR(AZALIA_AUDIO_DTO), \
+ SR(AZALIA_CONTROLLER_CLOCK_GATING), \
+ SR(HPO_TOP_HW_CONTROL)
+
+static const struct dce_hwseq_registers hwseq_reg = {
+ HWSEQ_DCN31_REG_LIST()
+};
+
+#define HWSEQ_DCN31_MASK_SH_LIST(mask_sh)\
+ HWSEQ_DCN_MASK_SH_LIST(mask_sh), \
+ HWS_SF(, DCHUBBUB_GLOBAL_TIMER_CNTL, DCHUBBUB_GLOBAL_TIMER_REFDIV, mask_sh), \
+ HWS_SF(, DCHUBBUB_ARB_HOSTVM_CNTL, DISABLE_HOSTVM_FORCE_ALLOW_PSTATE, mask_sh), \
+ HWS_SF(, DOMAIN0_PG_CONFIG, DOMAIN_POWER_FORCEON, mask_sh), \
+ HWS_SF(, DOMAIN0_PG_CONFIG, DOMAIN_POWER_GATE, mask_sh), \
+ HWS_SF(, DOMAIN1_PG_CONFIG, DOMAIN_POWER_FORCEON, mask_sh), \
+ HWS_SF(, DOMAIN1_PG_CONFIG, DOMAIN_POWER_GATE, mask_sh), \
+ HWS_SF(, DOMAIN2_PG_CONFIG, DOMAIN_POWER_FORCEON, mask_sh), \
+ HWS_SF(, DOMAIN2_PG_CONFIG, DOMAIN_POWER_GATE, mask_sh), \
+ HWS_SF(, DOMAIN3_PG_CONFIG, DOMAIN_POWER_FORCEON, mask_sh), \
+ HWS_SF(, DOMAIN3_PG_CONFIG, DOMAIN_POWER_GATE, mask_sh), \
+ HWS_SF(, DOMAIN16_PG_CONFIG, DOMAIN_POWER_FORCEON, mask_sh), \
+ HWS_SF(, DOMAIN16_PG_CONFIG, DOMAIN_POWER_GATE, mask_sh), \
+ HWS_SF(, DOMAIN17_PG_CONFIG, DOMAIN_POWER_FORCEON, mask_sh), \
+ HWS_SF(, DOMAIN17_PG_CONFIG, DOMAIN_POWER_GATE, mask_sh), \
+ HWS_SF(, DOMAIN18_PG_CONFIG, DOMAIN_POWER_FORCEON, mask_sh), \
+ HWS_SF(, DOMAIN18_PG_CONFIG, DOMAIN_POWER_GATE, mask_sh), \
+ HWS_SF(, DOMAIN0_PG_STATUS, DOMAIN_PGFSM_PWR_STATUS, mask_sh), \
+ HWS_SF(, DOMAIN1_PG_STATUS, DOMAIN_PGFSM_PWR_STATUS, mask_sh), \
+ HWS_SF(, DOMAIN2_PG_STATUS, DOMAIN_PGFSM_PWR_STATUS, mask_sh), \
+ HWS_SF(, DOMAIN3_PG_STATUS, DOMAIN_PGFSM_PWR_STATUS, mask_sh), \
+ HWS_SF(, DOMAIN16_PG_STATUS, DOMAIN_PGFSM_PWR_STATUS, mask_sh), \
+ HWS_SF(, DOMAIN17_PG_STATUS, DOMAIN_PGFSM_PWR_STATUS, mask_sh), \
+ HWS_SF(, DOMAIN18_PG_STATUS, DOMAIN_PGFSM_PWR_STATUS, mask_sh), \
+ HWS_SF(, DC_IP_REQUEST_CNTL, IP_REQUEST_EN, mask_sh), \
+ HWS_SF(, AZALIA_AUDIO_DTO, AZALIA_AUDIO_DTO_MODULE, mask_sh), \
+ HWS_SF(, HPO_TOP_CLOCK_CONTROL, HPO_HDMISTREAMCLK_G_GATE_DIS, mask_sh), \
+ HWS_SF(, DMU_MEM_PWR_CNTL, DMCU_ERAM_MEM_PWR_FORCE, mask_sh), \
+ HWS_SF(, ODM_MEM_PWR_CTRL3, ODM_MEM_UNASSIGNED_PWR_MODE, mask_sh), \
+ HWS_SF(, ODM_MEM_PWR_CTRL3, ODM_MEM_VBLANK_PWR_MODE, mask_sh), \
+ HWS_SF(, MMHUBBUB_MEM_PWR_CNTL, VGA_MEM_PWR_FORCE, mask_sh), \
+ HWS_SF(, DIO_MEM_PWR_CTRL, I2C_LIGHT_SLEEP_FORCE, mask_sh), \
+ HWS_SF(, HPO_TOP_HW_CONTROL, HPO_IO_EN, mask_sh)
+
+static const struct dce_hwseq_shift hwseq_shift = {
+ HWSEQ_DCN31_MASK_SH_LIST(__SHIFT)
+};
+
+static const struct dce_hwseq_mask hwseq_mask = {
+ HWSEQ_DCN31_MASK_SH_LIST(_MASK)
+};
+#define vmid_regs(id)\
+[id] = {\
+ DCN20_VMID_REG_LIST(id)\
+}
+
+static const struct dcn_vmid_registers vmid_regs[] = {
+ vmid_regs(0),
+ vmid_regs(1),
+ vmid_regs(2),
+ vmid_regs(3),
+ vmid_regs(4),
+ vmid_regs(5),
+ vmid_regs(6),
+ vmid_regs(7),
+ vmid_regs(8),
+ vmid_regs(9),
+ vmid_regs(10),
+ vmid_regs(11),
+ vmid_regs(12),
+ vmid_regs(13),
+ vmid_regs(14),
+ vmid_regs(15)
+};
+
+static const struct dcn20_vmid_shift vmid_shifts = {
+ DCN20_VMID_MASK_SH_LIST(__SHIFT)
+};
+
+static const struct dcn20_vmid_mask vmid_masks = {
+ DCN20_VMID_MASK_SH_LIST(_MASK)
+};
+
+static const struct resource_caps res_cap_dcn31 = {
+ .num_timing_generator = 4,
+ .num_opp = 4,
+ .num_video_plane = 4,
+ .num_audio = 5,
+ .num_stream_encoder = 5,
+ .num_dig_link_enc = 5,
+ .num_hpo_dp_stream_encoder = 4,
+ .num_hpo_dp_link_encoder = 2,
+ .num_pll = 5,
+ .num_dwb = 1,
+ .num_ddc = 5,
+ .num_vmid = 16,
+ .num_mpc_3dlut = 2,
+ .num_dsc = 3,
+};
+
+static const struct dc_plane_cap plane_cap = {
+ .type = DC_PLANE_TYPE_DCN_UNIVERSAL,
+ .blends_with_above = true,
+ .blends_with_below = true,
+ .per_pixel_alpha = true,
+
+ .pixel_format_support = {
+ .argb8888 = true,
+ .nv12 = true,
+ .fp16 = true,
+ .p010 = true,
+ .ayuv = false,
+ },
+
+ .max_upscale_factor = {
+ .argb8888 = 16000,
+ .nv12 = 16000,
+ .fp16 = 16000
+ },
+
+ // 6:1 downscaling ratio: 1000/6 = 166.666
+ .max_downscale_factor = {
+ .argb8888 = 167,
+ .nv12 = 167,
+ .fp16 = 167
+ },
+ 64,
+ 64
+};
+
+static const struct dc_debug_options debug_defaults_drv = {
+ .disable_z10 = true, /*hw not support it*/
+ .disable_dmcu = true,
+ .force_abm_enable = false,
+ .timing_trace = false,
+ .clock_trace = true,
+ .disable_pplib_clock_request = false,
+ .pipe_split_policy = MPC_SPLIT_DYNAMIC,
+ .force_single_disp_pipe_split = false,
+ .disable_dcc = DCC_ENABLE,
+ .vsr_support = true,
+ .performance_trace = false,
+ .max_downscale_src_width = 4096,/*upto true 4k*/
+ .disable_pplib_wm_range = false,
+ .scl_reset_length10 = true,
+ .sanity_checks = false,
+ .underflow_assert_delay_us = 0xFFFFFFFF,
+ .dwb_fi_phase = -1, // -1 = disable,
+ .dmub_command_table = true,
+ .pstate_enabled = true,
+ .use_max_lb = true,
+ .enable_mem_low_power = {
+ .bits = {
+ .vga = true,
+ .i2c = true,
+ .dmcu = false, // This is previously known to cause hang on S3 cycles if enabled
+ .dscl = true,
+ .cm = true,
+ .mpc = true,
+ .optc = true,
+ .vpg = true,
+ .afmt = true,
+ }
+ },
+ .optimize_edp_link_rate = true,
+ .enable_sw_cntl_psr = true,
+ .psr_power_use_phy_fsm = 0,
+};
+
+static const struct dc_debug_options debug_defaults_diags = {
+ .disable_dmcu = true,
+ .force_abm_enable = false,
+ .timing_trace = true,
+ .clock_trace = true,
+ .disable_dpp_power_gate = true,
+ .disable_hubp_power_gate = true,
+ .disable_clock_gate = true,
+ .disable_pplib_clock_request = true,
+ .disable_pplib_wm_range = true,
+ .disable_stutter = false,
+ .scl_reset_length10 = true,
+ .dwb_fi_phase = -1, // -1 = disable
+ .dmub_command_table = true,
+ .enable_tri_buf = true,
+ .use_max_lb = true
+};
+
+static void dcn31_dpp_destroy(struct dpp **dpp)
+{
+ kfree(TO_DCN20_DPP(*dpp));
+ *dpp = NULL;
+}
+
+static struct dpp *dcn31_dpp_create(
+ struct dc_context *ctx,
+ uint32_t inst)
+{
+ struct dcn3_dpp *dpp =
+ kzalloc(sizeof(struct dcn3_dpp), GFP_KERNEL);
+
+ if (!dpp)
+ return NULL;
+
+ if (dpp3_construct(dpp, ctx, inst,
+ &dpp_regs[inst], &tf_shift, &tf_mask))
+ return &dpp->base;
+
+ BREAK_TO_DEBUGGER();
+ kfree(dpp);
+ return NULL;
+}
+
+static struct output_pixel_processor *dcn31_opp_create(
+ struct dc_context *ctx, uint32_t inst)
+{
+ struct dcn20_opp *opp =
+ kzalloc(sizeof(struct dcn20_opp), GFP_KERNEL);
+
+ if (!opp) {
+ BREAK_TO_DEBUGGER();
+ return NULL;
+ }
+
+ dcn20_opp_construct(opp, ctx, inst,
+ &opp_regs[inst], &opp_shift, &opp_mask);
+ return &opp->base;
+}
+
+static struct dce_aux *dcn31_aux_engine_create(
+ struct dc_context *ctx,
+ uint32_t inst)
+{
+ struct aux_engine_dce110 *aux_engine =
+ kzalloc(sizeof(struct aux_engine_dce110), GFP_KERNEL);
+
+ if (!aux_engine)
+ return NULL;
+
+ dce110_aux_engine_construct(aux_engine, ctx, inst,
+ SW_AUX_TIMEOUT_PERIOD_MULTIPLIER * AUX_TIMEOUT_PERIOD,
+ &aux_engine_regs[inst],
+ &aux_mask,
+ &aux_shift,
+ ctx->dc->caps.extended_aux_timeout_support);
+
+ return &aux_engine->base;
+}
+#define i2c_inst_regs(id) { I2C_HW_ENGINE_COMMON_REG_LIST_DCN30(id) }
+
+static const struct dce_i2c_registers i2c_hw_regs[] = {
+ i2c_inst_regs(1),
+ i2c_inst_regs(2),
+ i2c_inst_regs(3),
+ i2c_inst_regs(4),
+ i2c_inst_regs(5),
+};
+
+static const struct dce_i2c_shift i2c_shifts = {
+ I2C_COMMON_MASK_SH_LIST_DCN30(__SHIFT)
+};
+
+static const struct dce_i2c_mask i2c_masks = {
+ I2C_COMMON_MASK_SH_LIST_DCN30(_MASK)
+};
+
+static struct dce_i2c_hw *dcn31_i2c_hw_create(
+ struct dc_context *ctx,
+ uint32_t inst)
+{
+ struct dce_i2c_hw *dce_i2c_hw =
+ kzalloc(sizeof(struct dce_i2c_hw), GFP_KERNEL);
+
+ if (!dce_i2c_hw)
+ return NULL;
+
+ dcn2_i2c_hw_construct(dce_i2c_hw, ctx, inst,
+ &i2c_hw_regs[inst], &i2c_shifts, &i2c_masks);
+
+ return dce_i2c_hw;
+}
+static struct mpc *dcn31_mpc_create(
+ struct dc_context *ctx,
+ int num_mpcc,
+ int num_rmu)
+{
+ struct dcn30_mpc *mpc30 = kzalloc(sizeof(struct dcn30_mpc),
+ GFP_KERNEL);
+
+ if (!mpc30)
+ return NULL;
+
+ dcn30_mpc_construct(mpc30, ctx,
+ &mpc_regs,
+ &mpc_shift,
+ &mpc_mask,
+ num_mpcc,
+ num_rmu);
+
+ return &mpc30->base;
+}
+
+static struct hubbub *dcn31_hubbub_create(struct dc_context *ctx)
+{
+ int i;
+
+ struct dcn20_hubbub *hubbub3 = kzalloc(sizeof(struct dcn20_hubbub),
+ GFP_KERNEL);
+
+ if (!hubbub3)
+ return NULL;
+
+ hubbub31_construct(hubbub3, ctx,
+ &hubbub_reg,
+ &hubbub_shift,
+ &hubbub_mask,
+ dcn3_15_ip.det_buffer_size_kbytes,
+ dcn3_15_ip.pixel_chunk_size_kbytes,
+ dcn3_15_ip.config_return_buffer_size_in_kbytes);
+
+
+ for (i = 0; i < res_cap_dcn31.num_vmid; i++) {
+ struct dcn20_vmid *vmid = &hubbub3->vmid[i];
+
+ vmid->ctx = ctx;
+
+ vmid->regs = &vmid_regs[i];
+ vmid->shifts = &vmid_shifts;
+ vmid->masks = &vmid_masks;
+ }
+
+ return &hubbub3->base;
+}
+
+static struct timing_generator *dcn31_timing_generator_create(
+ struct dc_context *ctx,
+ uint32_t instance)
+{
+ struct optc *tgn10 =
+ kzalloc(sizeof(struct optc), GFP_KERNEL);
+
+ if (!tgn10)
+ return NULL;
+
+ tgn10->base.inst = instance;
+ tgn10->base.ctx = ctx;
+
+ tgn10->tg_regs = &optc_regs[instance];
+ tgn10->tg_shift = &optc_shift;
+ tgn10->tg_mask = &optc_mask;
+
+ dcn31_timing_generator_init(tgn10);
+
+ return &tgn10->base;
+}
+
+static const struct encoder_feature_support link_enc_feature = {
+ .max_hdmi_deep_color = COLOR_DEPTH_121212,
+ .max_hdmi_pixel_clock = 600000,
+ .hdmi_ycbcr420_supported = true,
+ .dp_ycbcr420_supported = true,
+ .fec_supported = true,
+ .flags.bits.IS_HBR2_CAPABLE = true,
+ .flags.bits.IS_HBR3_CAPABLE = true,
+ .flags.bits.IS_TPS3_CAPABLE = true,
+ .flags.bits.IS_TPS4_CAPABLE = true
+};
+
+static struct link_encoder *dcn31_link_encoder_create(
+ const struct encoder_init_data *enc_init_data)
+{
+ struct dcn20_link_encoder *enc20 =
+ kzalloc(sizeof(struct dcn20_link_encoder), GFP_KERNEL);
+
+ if (!enc20)
+ return NULL;
+
+ dcn31_link_encoder_construct(enc20,
+ enc_init_data,
+ &link_enc_feature,
+ &link_enc_regs[enc_init_data->transmitter],
+ &link_enc_aux_regs[enc_init_data->channel - 1],
+ &link_enc_hpd_regs[enc_init_data->hpd_source],
+ &le_shift,
+ &le_mask);
+
+ return &enc20->enc10.base;
+}
+
+/* Create a minimal link encoder object not associated with a particular
+ * physical connector.
+ * resource_funcs.link_enc_create_minimal
+ */
+static struct link_encoder *dcn31_link_enc_create_minimal(
+ struct dc_context *ctx, enum engine_id eng_id)
+{
+ struct dcn20_link_encoder *enc20;
+
+ if ((eng_id - ENGINE_ID_DIGA) > ctx->dc->res_pool->res_cap->num_dig_link_enc)
+ return NULL;
+
+ enc20 = kzalloc(sizeof(struct dcn20_link_encoder), GFP_KERNEL);
+ if (!enc20)
+ return NULL;
+
+ dcn31_link_encoder_construct_minimal(
+ enc20,
+ ctx,
+ &link_enc_feature,
+ &link_enc_regs[eng_id - ENGINE_ID_DIGA],
+ eng_id);
+
+ return &enc20->enc10.base;
+}
+
+static struct panel_cntl *dcn31_panel_cntl_create(const struct panel_cntl_init_data *init_data)
+{
+ struct dcn31_panel_cntl *panel_cntl =
+ kzalloc(sizeof(struct dcn31_panel_cntl), GFP_KERNEL);
+
+ if (!panel_cntl)
+ return NULL;
+
+ dcn31_panel_cntl_construct(panel_cntl, init_data);
+
+ return &panel_cntl->base;
+}
+
+static void read_dce_straps(
+ struct dc_context *ctx,
+ struct resource_straps *straps)
+{
+ generic_reg_get(ctx, regDC_PINSTRAPS + BASE(regDC_PINSTRAPS_BASE_IDX),
+ FN(DC_PINSTRAPS, DC_PINSTRAPS_AUDIO), &straps->dc_pinstraps_audio);
+
+}
+
+static struct audio *dcn31_create_audio(
+ struct dc_context *ctx, unsigned int inst)
+{
+ return dce_audio_create(ctx, inst,
+ &audio_regs[inst], &audio_shift, &audio_mask);
+}
+
+static struct vpg *dcn31_vpg_create(
+ struct dc_context *ctx,
+ uint32_t inst)
+{
+ struct dcn31_vpg *vpg31 = kzalloc(sizeof(struct dcn31_vpg), GFP_KERNEL);
+
+ if (!vpg31)
+ return NULL;
+
+ vpg31_construct(vpg31, ctx, inst,
+ &vpg_regs[inst],
+ &vpg_shift,
+ &vpg_mask);
+
+ return &vpg31->base;
+}
+
+static struct afmt *dcn31_afmt_create(
+ struct dc_context *ctx,
+ uint32_t inst)
+{
+ struct dcn31_afmt *afmt31 = kzalloc(sizeof(struct dcn31_afmt), GFP_KERNEL);
+
+ if (!afmt31)
+ return NULL;
+
+ afmt31_construct(afmt31, ctx, inst,
+ &afmt_regs[inst],
+ &afmt_shift,
+ &afmt_mask);
+
+ // Light sleep by default, no need to power down here
+
+ return &afmt31->base;
+}
+
+static struct apg *dcn31_apg_create(
+ struct dc_context *ctx,
+ uint32_t inst)
+{
+ struct dcn31_apg *apg31 = kzalloc(sizeof(struct dcn31_apg), GFP_KERNEL);
+
+ if (!apg31)
+ return NULL;
+
+ apg31_construct(apg31, ctx, inst,
+ &apg_regs[inst],
+ &apg_shift,
+ &apg_mask);
+
+ return &apg31->base;
+}
+
+static struct stream_encoder *dcn315_stream_encoder_create(
+ enum engine_id eng_id,
+ struct dc_context *ctx)
+{
+ struct dcn10_stream_encoder *enc1;
+ struct vpg *vpg;
+ struct afmt *afmt;
+ int vpg_inst;
+ int afmt_inst;
+
+ /*PHYB is wired off in HW, allow front end to remapping, otherwise needs more changes*/
+
+ /* Mapping of VPG, AFMT, DME register blocks to DIO block instance */
+ if (eng_id <= ENGINE_ID_DIGF) {
+ vpg_inst = eng_id;
+ afmt_inst = eng_id;
+ } else
+ return NULL;
+
+ enc1 = kzalloc(sizeof(struct dcn10_stream_encoder), GFP_KERNEL);
+ vpg = dcn31_vpg_create(ctx, vpg_inst);
+ afmt = dcn31_afmt_create(ctx, afmt_inst);
+
+ if (!enc1 || !vpg || !afmt) {
+ kfree(enc1);
+ kfree(vpg);
+ kfree(afmt);
+ return NULL;
+ }
+
+ dcn30_dio_stream_encoder_construct(enc1, ctx, ctx->dc_bios,
+ eng_id, vpg, afmt,
+ &stream_enc_regs[eng_id],
+ &se_shift, &se_mask);
+
+ return &enc1->base;
+}
+
+static struct hpo_dp_stream_encoder *dcn31_hpo_dp_stream_encoder_create(
+ enum engine_id eng_id,
+ struct dc_context *ctx)
+{
+ struct dcn31_hpo_dp_stream_encoder *hpo_dp_enc31;
+ struct vpg *vpg;
+ struct apg *apg;
+ uint32_t hpo_dp_inst;
+ uint32_t vpg_inst;
+ uint32_t apg_inst;
+
+ ASSERT((eng_id >= ENGINE_ID_HPO_DP_0) && (eng_id <= ENGINE_ID_HPO_DP_3));
+ hpo_dp_inst = eng_id - ENGINE_ID_HPO_DP_0;
+
+ /* Mapping of VPG register blocks to HPO DP block instance:
+ * VPG[6] -> HPO_DP[0]
+ * VPG[7] -> HPO_DP[1]
+ * VPG[8] -> HPO_DP[2]
+ * VPG[9] -> HPO_DP[3]
+ */
+ vpg_inst = hpo_dp_inst + 6;
+
+ /* Mapping of APG register blocks to HPO DP block instance:
+ * APG[0] -> HPO_DP[0]
+ * APG[1] -> HPO_DP[1]
+ * APG[2] -> HPO_DP[2]
+ * APG[3] -> HPO_DP[3]
+ */
+ apg_inst = hpo_dp_inst;
+
+ /* allocate HPO stream encoder and create VPG sub-block */
+ hpo_dp_enc31 = kzalloc(sizeof(struct dcn31_hpo_dp_stream_encoder), GFP_KERNEL);
+ vpg = dcn31_vpg_create(ctx, vpg_inst);
+ apg = dcn31_apg_create(ctx, apg_inst);
+
+ if (!hpo_dp_enc31 || !vpg || !apg) {
+ kfree(hpo_dp_enc31);
+ kfree(vpg);
+ kfree(apg);
+ return NULL;
+ }
+
+ dcn31_hpo_dp_stream_encoder_construct(hpo_dp_enc31, ctx, ctx->dc_bios,
+ hpo_dp_inst, eng_id, vpg, apg,
+ &hpo_dp_stream_enc_regs[hpo_dp_inst],
+ &hpo_dp_se_shift, &hpo_dp_se_mask);
+
+ return &hpo_dp_enc31->base;
+}
+
+static struct hpo_dp_link_encoder *dcn31_hpo_dp_link_encoder_create(
+ uint8_t inst,
+ struct dc_context *ctx)
+{
+ struct dcn31_hpo_dp_link_encoder *hpo_dp_enc31;
+
+ /* allocate HPO link encoder */
+ hpo_dp_enc31 = kzalloc(sizeof(struct dcn31_hpo_dp_link_encoder), GFP_KERNEL);
+
+ hpo_dp_link_encoder31_construct(hpo_dp_enc31, ctx, inst,
+ &hpo_dp_link_enc_regs[inst],
+ &hpo_dp_le_shift, &hpo_dp_le_mask);
+
+ return &hpo_dp_enc31->base;
+}
+
+static struct dce_hwseq *dcn31_hwseq_create(
+ struct dc_context *ctx)
+{
+ struct dce_hwseq *hws = kzalloc(sizeof(struct dce_hwseq), GFP_KERNEL);
+
+ if (hws) {
+ hws->ctx = ctx;
+ hws->regs = &hwseq_reg;
+ hws->shifts = &hwseq_shift;
+ hws->masks = &hwseq_mask;
+ /* DCN3.1 FPGA Workaround
+ * Need to enable HPO DP Stream Encoder before setting OTG master enable.
+ * To do so, move calling function enable_stream_timing to only be done AFTER calling
+ * function core_link_enable_stream
+ */
+ if (IS_FPGA_MAXIMUS_DC(ctx->dce_environment))
+ hws->wa.dp_hpo_and_otg_sequence = true;
+ }
+ return hws;
+}
+static const struct resource_create_funcs res_create_funcs = {
+ .read_dce_straps = read_dce_straps,
+ .create_audio = dcn31_create_audio,
+ .create_stream_encoder = dcn315_stream_encoder_create,
+ .create_hpo_dp_stream_encoder = dcn31_hpo_dp_stream_encoder_create,
+ .create_hpo_dp_link_encoder = dcn31_hpo_dp_link_encoder_create,
+ .create_hwseq = dcn31_hwseq_create,
+};
+
+static const struct resource_create_funcs res_create_maximus_funcs = {
+ .read_dce_straps = NULL,
+ .create_audio = NULL,
+ .create_stream_encoder = NULL,
+ .create_hpo_dp_stream_encoder = dcn31_hpo_dp_stream_encoder_create,
+ .create_hpo_dp_link_encoder = dcn31_hpo_dp_link_encoder_create,
+ .create_hwseq = dcn31_hwseq_create,
+};
+
+static void dcn315_resource_destruct(struct dcn315_resource_pool *pool)
+{
+ unsigned int i;
+
+ for (i = 0; i < pool->base.stream_enc_count; i++) {
+ if (pool->base.stream_enc[i] != NULL) {
+ if (pool->base.stream_enc[i]->vpg != NULL) {
+ kfree(DCN30_VPG_FROM_VPG(pool->base.stream_enc[i]->vpg));
+ pool->base.stream_enc[i]->vpg = NULL;
+ }
+ if (pool->base.stream_enc[i]->afmt != NULL) {
+ kfree(DCN30_AFMT_FROM_AFMT(pool->base.stream_enc[i]->afmt));
+ pool->base.stream_enc[i]->afmt = NULL;
+ }
+ kfree(DCN10STRENC_FROM_STRENC(pool->base.stream_enc[i]));
+ pool->base.stream_enc[i] = NULL;
+ }
+ }
+
+ for (i = 0; i < pool->base.hpo_dp_stream_enc_count; i++) {
+ if (pool->base.hpo_dp_stream_enc[i] != NULL) {
+ if (pool->base.hpo_dp_stream_enc[i]->vpg != NULL) {
+ kfree(DCN30_VPG_FROM_VPG(pool->base.hpo_dp_stream_enc[i]->vpg));
+ pool->base.hpo_dp_stream_enc[i]->vpg = NULL;
+ }
+ if (pool->base.hpo_dp_stream_enc[i]->apg != NULL) {
+ kfree(DCN31_APG_FROM_APG(pool->base.hpo_dp_stream_enc[i]->apg));
+ pool->base.hpo_dp_stream_enc[i]->apg = NULL;
+ }
+ kfree(DCN3_1_HPO_DP_STREAM_ENC_FROM_HPO_STREAM_ENC(pool->base.hpo_dp_stream_enc[i]));
+ pool->base.hpo_dp_stream_enc[i] = NULL;
+ }
+ }
+
+ for (i = 0; i < pool->base.hpo_dp_link_enc_count; i++) {
+ if (pool->base.hpo_dp_link_enc[i] != NULL) {
+ kfree(DCN3_1_HPO_DP_LINK_ENC_FROM_HPO_LINK_ENC(pool->base.hpo_dp_link_enc[i]));
+ pool->base.hpo_dp_link_enc[i] = NULL;
+ }
+ }
+
+ for (i = 0; i < pool->base.res_cap->num_dsc; i++) {
+ if (pool->base.dscs[i] != NULL)
+ dcn20_dsc_destroy(&pool->base.dscs[i]);
+ }
+
+ if (pool->base.mpc != NULL) {
+ kfree(TO_DCN20_MPC(pool->base.mpc));
+ pool->base.mpc = NULL;
+ }
+ if (pool->base.hubbub != NULL) {
+ kfree(pool->base.hubbub);
+ pool->base.hubbub = NULL;
+ }
+ for (i = 0; i < pool->base.pipe_count; i++) {
+ if (pool->base.dpps[i] != NULL)
+ dcn31_dpp_destroy(&pool->base.dpps[i]);
+
+ if (pool->base.ipps[i] != NULL)
+ pool->base.ipps[i]->funcs->ipp_destroy(&pool->base.ipps[i]);
+
+ if (pool->base.hubps[i] != NULL) {
+ kfree(TO_DCN20_HUBP(pool->base.hubps[i]));
+ pool->base.hubps[i] = NULL;
+ }
+
+ if (pool->base.irqs != NULL) {
+ dal_irq_service_destroy(&pool->base.irqs);
+ }
+ }
+
+ for (i = 0; i < pool->base.res_cap->num_ddc; i++) {
+ if (pool->base.engines[i] != NULL)
+ dce110_engine_destroy(&pool->base.engines[i]);
+ if (pool->base.hw_i2cs[i] != NULL) {
+ kfree(pool->base.hw_i2cs[i]);
+ pool->base.hw_i2cs[i] = NULL;
+ }
+ if (pool->base.sw_i2cs[i] != NULL) {
+ kfree(pool->base.sw_i2cs[i]);
+ pool->base.sw_i2cs[i] = NULL;
+ }
+ }
+
+ for (i = 0; i < pool->base.res_cap->num_opp; i++) {
+ if (pool->base.opps[i] != NULL)
+ pool->base.opps[i]->funcs->opp_destroy(&pool->base.opps[i]);
+ }
+
+ for (i = 0; i < pool->base.res_cap->num_timing_generator; i++) {
+ if (pool->base.timing_generators[i] != NULL) {
+ kfree(DCN10TG_FROM_TG(pool->base.timing_generators[i]));
+ pool->base.timing_generators[i] = NULL;
+ }
+ }
+
+ for (i = 0; i < pool->base.res_cap->num_dwb; i++) {
+ if (pool->base.dwbc[i] != NULL) {
+ kfree(TO_DCN30_DWBC(pool->base.dwbc[i]));
+ pool->base.dwbc[i] = NULL;
+ }
+ if (pool->base.mcif_wb[i] != NULL) {
+ kfree(TO_DCN30_MMHUBBUB(pool->base.mcif_wb[i]));
+ pool->base.mcif_wb[i] = NULL;
+ }
+ }
+
+ for (i = 0; i < pool->base.audio_count; i++) {
+ if (pool->base.audios[i])
+ dce_aud_destroy(&pool->base.audios[i]);
+ }
+
+ for (i = 0; i < pool->base.clk_src_count; i++) {
+ if (pool->base.clock_sources[i] != NULL) {
+ dcn20_clock_source_destroy(&pool->base.clock_sources[i]);
+ pool->base.clock_sources[i] = NULL;
+ }
+ }
+
+ for (i = 0; i < pool->base.res_cap->num_mpc_3dlut; i++) {
+ if (pool->base.mpc_lut[i] != NULL) {
+ dc_3dlut_func_release(pool->base.mpc_lut[i]);
+ pool->base.mpc_lut[i] = NULL;
+ }
+ if (pool->base.mpc_shaper[i] != NULL) {
+ dc_transfer_func_release(pool->base.mpc_shaper[i]);
+ pool->base.mpc_shaper[i] = NULL;
+ }
+ }
+
+ if (pool->base.dp_clock_source != NULL) {
+ dcn20_clock_source_destroy(&pool->base.dp_clock_source);
+ pool->base.dp_clock_source = NULL;
+ }
+
+ for (i = 0; i < pool->base.res_cap->num_timing_generator; i++) {
+ if (pool->base.multiple_abms[i] != NULL)
+ dce_abm_destroy(&pool->base.multiple_abms[i]);
+ }
+
+ if (pool->base.psr != NULL)
+ dmub_psr_destroy(&pool->base.psr);
+
+ if (pool->base.dccg != NULL)
+ dcn_dccg_destroy(&pool->base.dccg);
+}
+
+static struct hubp *dcn31_hubp_create(
+ struct dc_context *ctx,
+ uint32_t inst)
+{
+ struct dcn20_hubp *hubp2 =
+ kzalloc(sizeof(struct dcn20_hubp), GFP_KERNEL);
+
+ if (!hubp2)
+ return NULL;
+
+ if (hubp31_construct(hubp2, ctx, inst,
+ &hubp_regs[inst], &hubp_shift, &hubp_mask))
+ return &hubp2->base;
+
+ BREAK_TO_DEBUGGER();
+ kfree(hubp2);
+ return NULL;
+}
+
+static bool dcn31_dwbc_create(struct dc_context *ctx, struct resource_pool *pool)
+{
+ int i;
+ uint32_t pipe_count = pool->res_cap->num_dwb;
+
+ for (i = 0; i < pipe_count; i++) {
+ struct dcn30_dwbc *dwbc30 = kzalloc(sizeof(struct dcn30_dwbc),
+ GFP_KERNEL);
+
+ if (!dwbc30) {
+ dm_error("DC: failed to create dwbc30!\n");
+ return false;
+ }
+
+ dcn30_dwbc_construct(dwbc30, ctx,
+ &dwbc30_regs[i],
+ &dwbc30_shift,
+ &dwbc30_mask,
+ i);
+
+ pool->dwbc[i] = &dwbc30->base;
+ }
+ return true;
+}
+
+static bool dcn31_mmhubbub_create(struct dc_context *ctx, struct resource_pool *pool)
+{
+ int i;
+ uint32_t pipe_count = pool->res_cap->num_dwb;
+
+ for (i = 0; i < pipe_count; i++) {
+ struct dcn30_mmhubbub *mcif_wb30 = kzalloc(sizeof(struct dcn30_mmhubbub),
+ GFP_KERNEL);
+
+ if (!mcif_wb30) {
+ dm_error("DC: failed to create mcif_wb30!\n");
+ return false;
+ }
+
+ dcn30_mmhubbub_construct(mcif_wb30, ctx,
+ &mcif_wb30_regs[i],
+ &mcif_wb30_shift,
+ &mcif_wb30_mask,
+ i);
+
+ pool->mcif_wb[i] = &mcif_wb30->base;
+ }
+ return true;
+}
+
+static struct display_stream_compressor *dcn31_dsc_create(
+ struct dc_context *ctx, uint32_t inst)
+{
+ struct dcn20_dsc *dsc =
+ kzalloc(sizeof(struct dcn20_dsc), GFP_KERNEL);
+
+ if (!dsc) {
+ BREAK_TO_DEBUGGER();
+ return NULL;
+ }
+
+ dsc2_construct(dsc, ctx, inst, &dsc_regs[inst], &dsc_shift, &dsc_mask);
+ return &dsc->base;
+}
+
+static void dcn315_destroy_resource_pool(struct resource_pool **pool)
+{
+ struct dcn315_resource_pool *dcn31_pool = TO_DCN315_RES_POOL(*pool);
+
+ dcn315_resource_destruct(dcn31_pool);
+ kfree(dcn31_pool);
+ *pool = NULL;
+}
+
+static struct clock_source *dcn31_clock_source_create(
+ struct dc_context *ctx,
+ struct dc_bios *bios,
+ enum clock_source_id id,
+ const struct dce110_clk_src_regs *regs,
+ bool dp_clk_src)
+{
+ struct dce110_clk_src *clk_src =
+ kzalloc(sizeof(struct dce110_clk_src), GFP_KERNEL);
+
+ if (!clk_src)
+ return NULL;
+
+ if (dcn31_clk_src_construct(clk_src, ctx, bios, id,
+ regs, &cs_shift, &cs_mask)) {
+ clk_src->base.dp_clk_src = dp_clk_src;
+ return &clk_src->base;
+ }
+
+ BREAK_TO_DEBUGGER();
+ return NULL;
+}
+
+static bool is_dual_plane(enum surface_pixel_format format)
+{
+ return format >= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN || format == SURFACE_PIXEL_FORMAT_GRPH_RGBE_ALPHA;
+}
+
+static int dcn315_populate_dml_pipes_from_context(
+ struct dc *dc, struct dc_state *context,
+ display_e2e_pipe_params_st *pipes,
+ bool fast_validate)
+{
+ int i, pipe_cnt;
+ struct resource_context *res_ctx = &context->res_ctx;
+ struct pipe_ctx *pipe;
+ const int max_usable_det = context->bw_ctx.dml.ip.config_return_buffer_size_in_kbytes - DCN3_15_MIN_COMPBUF_SIZE_KB;
+
+ DC_FP_START();
+ dcn20_populate_dml_pipes_from_context(dc, context, pipes, fast_validate);
+ DC_FP_END();
+
+ for (i = 0, pipe_cnt = 0; i < dc->res_pool->pipe_count; i++) {
+ struct dc_crtc_timing *timing;
+
+ if (!res_ctx->pipe_ctx[i].stream)
+ continue;
+ pipe = &res_ctx->pipe_ctx[i];
+ timing = &pipe->stream->timing;
+
+ /*
+ * Immediate flip can be set dynamically after enabling the plane.
+ * We need to require support for immediate flip or underflow can be
+ * intermittently experienced depending on peak b/w requirements.
+ */
+ pipes[pipe_cnt].pipe.src.immediate_flip = true;
+
+ pipes[pipe_cnt].pipe.src.unbounded_req_mode = false;
+ pipes[pipe_cnt].pipe.src.gpuvm = true;
+ pipes[pipe_cnt].pipe.src.dcc_fraction_of_zs_req_luma = 0;
+ pipes[pipe_cnt].pipe.src.dcc_fraction_of_zs_req_chroma = 0;
+ pipes[pipe_cnt].pipe.dest.vfront_porch = timing->v_front_porch;
+ pipes[pipe_cnt].pipe.src.dcc_rate = 3;
+ pipes[pipe_cnt].dout.dsc_input_bpc = 0;
+
+ if (pipes[pipe_cnt].dout.dsc_enable) {
+ switch (timing->display_color_depth) {
+ case COLOR_DEPTH_888:
+ pipes[pipe_cnt].dout.dsc_input_bpc = 8;
+ break;
+ case COLOR_DEPTH_101010:
+ pipes[pipe_cnt].dout.dsc_input_bpc = 10;
+ break;
+ case COLOR_DEPTH_121212:
+ pipes[pipe_cnt].dout.dsc_input_bpc = 12;
+ break;
+ default:
+ ASSERT(0);
+ break;
+ }
+ }
+
+ pipe_cnt++;
+ }
+
+ if (pipe_cnt)
+ context->bw_ctx.dml.ip.det_buffer_size_kbytes =
+ (max_usable_det / DCN3_15_CRB_SEGMENT_SIZE_KB / pipe_cnt) * DCN3_15_CRB_SEGMENT_SIZE_KB;
+ if (context->bw_ctx.dml.ip.det_buffer_size_kbytes > DCN3_15_MAX_DET_SIZE)
+ context->bw_ctx.dml.ip.det_buffer_size_kbytes = DCN3_15_MAX_DET_SIZE;
+ ASSERT(context->bw_ctx.dml.ip.det_buffer_size_kbytes >= DCN3_15_DEFAULT_DET_SIZE);
+ dc->config.enable_4to1MPC = false;
+ if (pipe_cnt == 1 && pipe->plane_state && !dc->debug.disable_z9_mpc) {
+ if (is_dual_plane(pipe->plane_state->format)
+ && pipe->plane_state->src_rect.width <= 1920 && pipe->plane_state->src_rect.height <= 1080) {
+ dc->config.enable_4to1MPC = true;
+ context->bw_ctx.dml.ip.det_buffer_size_kbytes =
+ (max_usable_det / DCN3_15_CRB_SEGMENT_SIZE_KB / 4) * DCN3_15_CRB_SEGMENT_SIZE_KB;
+ } else if (!is_dual_plane(pipe->plane_state->format) && pipe->plane_state->src_rect.width <= 5120) {
+ /* Limit to 5k max to avoid forced pipe split when there is not enough detile for swath */
+ context->bw_ctx.dml.ip.det_buffer_size_kbytes = 192;
+ pipes[0].pipe.src.unbounded_req_mode = true;
+ }
+ }
+
+ return pipe_cnt;
+}
+
+static struct dc_cap_funcs cap_funcs = {
+ .get_dcc_compression_cap = dcn20_get_dcc_compression_cap
+};
+
+static void dcn315_update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_params)
+{
+ struct clk_limit_table *clk_table = &bw_params->clk_table;
+ struct _vcs_dpi_voltage_scaling_st clock_limits[DC__VOLTAGE_STATES];
+ unsigned int i, closest_clk_lvl;
+ int max_dispclk_mhz = 0, max_dppclk_mhz = 0;
+ int j;
+
+ // Default clock levels are used for diags, which may lead to overclocking.
+ if (!IS_DIAG_DC(dc->ctx->dce_environment)) {
+
+ dcn3_15_ip.max_num_otg = dc->res_pool->res_cap->num_timing_generator;
+ dcn3_15_ip.max_num_dpp = dc->res_pool->pipe_count;
+ dcn3_15_soc.num_chans = bw_params->num_channels;
+
+ ASSERT(clk_table->num_entries);
+
+ /* Prepass to find max clocks independent of voltage level. */
+ for (i = 0; i < clk_table->num_entries; ++i) {
+ if (clk_table->entries[i].dispclk_mhz > max_dispclk_mhz)
+ max_dispclk_mhz = clk_table->entries[i].dispclk_mhz;
+ if (clk_table->entries[i].dppclk_mhz > max_dppclk_mhz)
+ max_dppclk_mhz = clk_table->entries[i].dppclk_mhz;
+ }
+
+ for (i = 0; i < clk_table->num_entries; i++) {
+ /* loop backwards*/
+ for (closest_clk_lvl = 0, j = dcn3_15_soc.num_states - 1; j >= 0; j--) {
+ if ((unsigned int) dcn3_15_soc.clock_limits[j].dcfclk_mhz <= clk_table->entries[i].dcfclk_mhz) {
+ closest_clk_lvl = j;
+ break;
+ }
+ }
+ if (clk_table->num_entries == 1) {
+ /*smu gives one DPM level, let's take the highest one*/
+ closest_clk_lvl = dcn3_15_soc.num_states - 1;
+ }
+
+ clock_limits[i].state = i;
+
+ /* Clocks dependent on voltage level. */
+ clock_limits[i].dcfclk_mhz = clk_table->entries[i].dcfclk_mhz;
+ if (clk_table->num_entries == 1 &&
+ clock_limits[i].dcfclk_mhz < dcn3_15_soc.clock_limits[closest_clk_lvl].dcfclk_mhz) {
+ /*SMU fix not released yet*/
+ clock_limits[i].dcfclk_mhz = dcn3_15_soc.clock_limits[closest_clk_lvl].dcfclk_mhz;
+ }
+ clock_limits[i].fabricclk_mhz = clk_table->entries[i].fclk_mhz;
+ clock_limits[i].socclk_mhz = clk_table->entries[i].socclk_mhz;
+ clock_limits[i].dram_speed_mts = clk_table->entries[i].memclk_mhz * 2 * clk_table->entries[i].wck_ratio;
+
+ /* Clocks independent of voltage level. */
+ clock_limits[i].dispclk_mhz = max_dispclk_mhz ? max_dispclk_mhz :
+ dcn3_15_soc.clock_limits[closest_clk_lvl].dispclk_mhz;
+
+ clock_limits[i].dppclk_mhz = max_dppclk_mhz ? max_dppclk_mhz :
+ dcn3_15_soc.clock_limits[closest_clk_lvl].dppclk_mhz;
+
+ clock_limits[i].dram_bw_per_chan_gbps = dcn3_15_soc.clock_limits[closest_clk_lvl].dram_bw_per_chan_gbps;
+ clock_limits[i].dscclk_mhz = dcn3_15_soc.clock_limits[closest_clk_lvl].dscclk_mhz;
+ clock_limits[i].dtbclk_mhz = dcn3_15_soc.clock_limits[closest_clk_lvl].dtbclk_mhz;
+ clock_limits[i].phyclk_d18_mhz = dcn3_15_soc.clock_limits[closest_clk_lvl].phyclk_d18_mhz;
+ clock_limits[i].phyclk_mhz = dcn3_15_soc.clock_limits[closest_clk_lvl].phyclk_mhz;
+ }
+ for (i = 0; i < clk_table->num_entries; i++)
+ dcn3_15_soc.clock_limits[i] = clock_limits[i];
+ if (clk_table->num_entries) {
+ dcn3_15_soc.num_states = clk_table->num_entries;
+ }
+ }
+
+ if (max_dispclk_mhz) {
+ dcn3_15_soc.dispclk_dppclk_vco_speed_mhz = max_dispclk_mhz * 2;
+ dc->dml.soc.dispclk_dppclk_vco_speed_mhz = max_dispclk_mhz * 2;
+ }
+
+ if (!IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment))
+ dml_init_instance(&dc->dml, &dcn3_15_soc, &dcn3_15_ip, DML_PROJECT_DCN31);
+ else
+ dml_init_instance(&dc->dml, &dcn3_15_soc, &dcn3_15_ip, DML_PROJECT_DCN31_FPGA);
+}
+
+static struct resource_funcs dcn315_res_pool_funcs = {
+ .destroy = dcn315_destroy_resource_pool,
+ .link_enc_create = dcn31_link_encoder_create,
+ .link_enc_create_minimal = dcn31_link_enc_create_minimal,
+ .link_encs_assign = link_enc_cfg_link_encs_assign,
+ .link_enc_unassign = link_enc_cfg_link_enc_unassign,
+ .panel_cntl_create = dcn31_panel_cntl_create,
+ .validate_bandwidth = dcn31_validate_bandwidth,
+ .calculate_wm_and_dlg = dcn31_calculate_wm_and_dlg,
+ .update_soc_for_wm_a = dcn31_update_soc_for_wm_a,
+ .populate_dml_pipes = dcn315_populate_dml_pipes_from_context,
+ .acquire_idle_pipe_for_layer = dcn20_acquire_idle_pipe_for_layer,
+ .add_stream_to_ctx = dcn30_add_stream_to_ctx,
+ .add_dsc_to_stream_resource = dcn20_add_dsc_to_stream_resource,
+ .remove_stream_from_ctx = dcn20_remove_stream_from_ctx,
+ .populate_dml_writeback_from_context = dcn30_populate_dml_writeback_from_context,
+ .set_mcif_arb_params = dcn30_set_mcif_arb_params,
+ .find_first_free_match_stream_enc_for_link = dcn10_find_first_free_match_stream_enc_for_link,
+ .acquire_post_bldn_3dlut = dcn30_acquire_post_bldn_3dlut,
+ .release_post_bldn_3dlut = dcn30_release_post_bldn_3dlut,
+ .update_bw_bounding_box = dcn315_update_bw_bounding_box,
+ .patch_unknown_plane_state = dcn20_patch_unknown_plane_state,
+};
+
+static bool dcn315_resource_construct(
+ uint8_t num_virtual_links,
+ struct dc *dc,
+ struct dcn315_resource_pool *pool)
+{
+ int i;
+ struct dc_context *ctx = dc->ctx;
+ struct irq_service_init_data init_data;
+
+ ctx->dc_bios->regs = &bios_regs;
+
+ pool->base.res_cap = &res_cap_dcn31;
+
+ pool->base.funcs = &dcn315_res_pool_funcs;
+
+ /*************************************************
+ * Resource + asic cap harcoding *
+ *************************************************/
+ pool->base.underlay_pipe_index = NO_UNDERLAY_PIPE;
+ pool->base.pipe_count = pool->base.res_cap->num_timing_generator;
+ pool->base.mpcc_count = pool->base.res_cap->num_timing_generator;
+ dc->caps.max_downscale_ratio = 600;
+ dc->caps.i2c_speed_in_khz = 100;
+ dc->caps.i2c_speed_in_khz_hdcp = 5; /*1.4 w/a applied by default*/
+ dc->caps.max_cursor_size = 256;
+ dc->caps.min_horizontal_blanking_period = 80;
+ dc->caps.dmdata_alloc_size = 2048;
+
+ dc->caps.max_slave_planes = 1;
+ dc->caps.max_slave_yuv_planes = 1;
+ dc->caps.max_slave_rgb_planes = 1;
+ dc->caps.post_blend_color_processing = true;
+ dc->caps.force_dp_tps4_for_cp2520 = true;
+ dc->caps.dp_hpo = true;
+ dc->caps.edp_dsc_support = true;
+ dc->caps.extended_aux_timeout_support = true;
+ dc->caps.dmcub_support = true;
+ dc->caps.is_apu = true;
+
+ /* Color pipeline capabilities */
+ dc->caps.color.dpp.dcn_arch = 1;
+ dc->caps.color.dpp.input_lut_shared = 0;
+ dc->caps.color.dpp.icsc = 1;
+ dc->caps.color.dpp.dgam_ram = 0; // must use gamma_corr
+ dc->caps.color.dpp.dgam_rom_caps.srgb = 1;
+ dc->caps.color.dpp.dgam_rom_caps.bt2020 = 1;
+ dc->caps.color.dpp.dgam_rom_caps.gamma2_2 = 1;
+ dc->caps.color.dpp.dgam_rom_caps.pq = 1;
+ dc->caps.color.dpp.dgam_rom_caps.hlg = 1;
+ dc->caps.color.dpp.post_csc = 1;
+ dc->caps.color.dpp.gamma_corr = 1;
+ dc->caps.color.dpp.dgam_rom_for_yuv = 0;
+
+ dc->caps.color.dpp.hw_3d_lut = 1;
+ dc->caps.color.dpp.ogam_ram = 1;
+ // no OGAM ROM on DCN301
+ dc->caps.color.dpp.ogam_rom_caps.srgb = 0;
+ dc->caps.color.dpp.ogam_rom_caps.bt2020 = 0;
+ dc->caps.color.dpp.ogam_rom_caps.gamma2_2 = 0;
+ dc->caps.color.dpp.ogam_rom_caps.pq = 0;
+ dc->caps.color.dpp.ogam_rom_caps.hlg = 0;
+ dc->caps.color.dpp.ocsc = 0;
+
+ dc->caps.color.mpc.gamut_remap = 1;
+ dc->caps.color.mpc.num_3dluts = pool->base.res_cap->num_mpc_3dlut; //2
+ dc->caps.color.mpc.ogam_ram = 1;
+ dc->caps.color.mpc.ogam_rom_caps.srgb = 0;
+ dc->caps.color.mpc.ogam_rom_caps.bt2020 = 0;
+ dc->caps.color.mpc.ogam_rom_caps.gamma2_2 = 0;
+ dc->caps.color.mpc.ogam_rom_caps.pq = 0;
+ dc->caps.color.mpc.ogam_rom_caps.hlg = 0;
+ dc->caps.color.mpc.ocsc = 1;
+
+ /* read VBIOS LTTPR caps */
+ {
+ if (ctx->dc_bios->funcs->get_lttpr_caps) {
+ enum bp_result bp_query_result;
+ uint8_t is_vbios_lttpr_enable = 0;
+
+ bp_query_result = ctx->dc_bios->funcs->get_lttpr_caps(ctx->dc_bios, &is_vbios_lttpr_enable);
+ dc->caps.vbios_lttpr_enable = (bp_query_result == BP_RESULT_OK) && !!is_vbios_lttpr_enable;
+ }
+
+ /* interop bit is implicit */
+ {
+ dc->caps.vbios_lttpr_aware = true;
+ }
+ }
+
+ if (dc->ctx->dce_environment == DCE_ENV_PRODUCTION_DRV)
+ dc->debug = debug_defaults_drv;
+ else if (dc->ctx->dce_environment == DCE_ENV_FPGA_MAXIMUS) {
+ dc->debug = debug_defaults_diags;
+ } else
+ dc->debug = debug_defaults_diags;
+ // Init the vm_helper
+ if (dc->vm_helper)
+ vm_helper_init(dc->vm_helper, 16);
+
+ /*************************************************
+ * Create resources *
+ *************************************************/
+
+ /* Clock Sources for Pixel Clock*/
+ pool->base.clock_sources[DCN31_CLK_SRC_PLL0] =
+ dcn31_clock_source_create(ctx, ctx->dc_bios,
+ CLOCK_SOURCE_COMBO_PHY_PLL0,
+ &clk_src_regs[0], false);
+ pool->base.clock_sources[DCN31_CLK_SRC_PLL1] =
+ dcn31_clock_source_create(ctx, ctx->dc_bios,
+ CLOCK_SOURCE_COMBO_PHY_PLL1,
+ &clk_src_regs[1], false);
+ pool->base.clock_sources[DCN31_CLK_SRC_PLL2] =
+ dcn31_clock_source_create(ctx, ctx->dc_bios,
+ CLOCK_SOURCE_COMBO_PHY_PLL2,
+ &clk_src_regs[2], false);
+ pool->base.clock_sources[DCN31_CLK_SRC_PLL3] =
+ dcn31_clock_source_create(ctx, ctx->dc_bios,
+ CLOCK_SOURCE_COMBO_PHY_PLL3,
+ &clk_src_regs[3], false);
+ pool->base.clock_sources[DCN31_CLK_SRC_PLL4] =
+ dcn31_clock_source_create(ctx, ctx->dc_bios,
+ CLOCK_SOURCE_COMBO_PHY_PLL4,
+ &clk_src_regs[4], false);
+
+ pool->base.clk_src_count = DCN30_CLK_SRC_TOTAL;
+
+ /* todo: not reuse phy_pll registers */
+ pool->base.dp_clock_source =
+ dcn31_clock_source_create(ctx, ctx->dc_bios,
+ CLOCK_SOURCE_ID_DP_DTO,
+ &clk_src_regs[0], true);
+
+ for (i = 0; i < pool->base.clk_src_count; i++) {
+ if (pool->base.clock_sources[i] == NULL) {
+ dm_error("DC: failed to create clock sources!\n");
+ BREAK_TO_DEBUGGER();
+ goto create_fail;
+ }
+ }
+
+ /* TODO: DCCG */
+ pool->base.dccg = dccg31_create(ctx, &dccg_regs, &dccg_shift, &dccg_mask);
+ if (pool->base.dccg == NULL) {
+ dm_error("DC: failed to create dccg!\n");
+ BREAK_TO_DEBUGGER();
+ goto create_fail;
+ }
+
+ /* TODO: IRQ */
+ init_data.ctx = dc->ctx;
+ pool->base.irqs = dal_irq_service_dcn315_create(&init_data);
+ if (!pool->base.irqs)
+ goto create_fail;
+
+ /* HUBBUB */
+ pool->base.hubbub = dcn31_hubbub_create(ctx);
+ if (pool->base.hubbub == NULL) {
+ BREAK_TO_DEBUGGER();
+ dm_error("DC: failed to create hubbub!\n");
+ goto create_fail;
+ }
+
+ /* HUBPs, DPPs, OPPs and TGs */
+ for (i = 0; i < pool->base.pipe_count; i++) {
+ pool->base.hubps[i] = dcn31_hubp_create(ctx, i);
+ if (pool->base.hubps[i] == NULL) {
+ BREAK_TO_DEBUGGER();
+ dm_error(
+ "DC: failed to create hubps!\n");
+ goto create_fail;
+ }
+
+ pool->base.dpps[i] = dcn31_dpp_create(ctx, i);
+ if (pool->base.dpps[i] == NULL) {
+ BREAK_TO_DEBUGGER();
+ dm_error(
+ "DC: failed to create dpps!\n");
+ goto create_fail;
+ }
+ }
+
+ for (i = 0; i < pool->base.res_cap->num_opp; i++) {
+ pool->base.opps[i] = dcn31_opp_create(ctx, i);
+ if (pool->base.opps[i] == NULL) {
+ BREAK_TO_DEBUGGER();
+ dm_error(
+ "DC: failed to create output pixel processor!\n");
+ goto create_fail;
+ }
+ }
+
+ for (i = 0; i < pool->base.res_cap->num_timing_generator; i++) {
+ pool->base.timing_generators[i] = dcn31_timing_generator_create(
+ ctx, i);
+ if (pool->base.timing_generators[i] == NULL) {
+ BREAK_TO_DEBUGGER();
+ dm_error("DC: failed to create tg!\n");
+ goto create_fail;
+ }
+ }
+ pool->base.timing_generator_count = i;
+
+ /* PSR */
+ pool->base.psr = dmub_psr_create(ctx);
+ if (pool->base.psr == NULL) {
+ dm_error("DC: failed to create psr obj!\n");
+ BREAK_TO_DEBUGGER();
+ goto create_fail;
+ }
+
+ /* ABM */
+ for (i = 0; i < pool->base.res_cap->num_timing_generator; i++) {
+ pool->base.multiple_abms[i] = dmub_abm_create(ctx,
+ &abm_regs[i],
+ &abm_shift,
+ &abm_mask);
+ if (pool->base.multiple_abms[i] == NULL) {
+ dm_error("DC: failed to create abm for pipe %d!\n", i);
+ BREAK_TO_DEBUGGER();
+ goto create_fail;
+ }
+ }
+
+ /* MPC and DSC */
+ pool->base.mpc = dcn31_mpc_create(ctx, pool->base.mpcc_count, pool->base.res_cap->num_mpc_3dlut);
+ if (pool->base.mpc == NULL) {
+ BREAK_TO_DEBUGGER();
+ dm_error("DC: failed to create mpc!\n");
+ goto create_fail;
+ }
+
+ for (i = 0; i < pool->base.res_cap->num_dsc; i++) {
+ pool->base.dscs[i] = dcn31_dsc_create(ctx, i);
+ if (pool->base.dscs[i] == NULL) {
+ BREAK_TO_DEBUGGER();
+ dm_error("DC: failed to create display stream compressor %d!\n", i);
+ goto create_fail;
+ }
+ }
+
+ /* DWB and MMHUBBUB */
+ if (!dcn31_dwbc_create(ctx, &pool->base)) {
+ BREAK_TO_DEBUGGER();
+ dm_error("DC: failed to create dwbc!\n");
+ goto create_fail;
+ }
+
+ if (!dcn31_mmhubbub_create(ctx, &pool->base)) {
+ BREAK_TO_DEBUGGER();
+ dm_error("DC: failed to create mcif_wb!\n");
+ goto create_fail;
+ }
+
+ /* AUX and I2C */
+ for (i = 0; i < pool->base.res_cap->num_ddc; i++) {
+ pool->base.engines[i] = dcn31_aux_engine_create(ctx, i);
+ if (pool->base.engines[i] == NULL) {
+ BREAK_TO_DEBUGGER();
+ dm_error(
+ "DC:failed to create aux engine!!\n");
+ goto create_fail;
+ }
+ pool->base.hw_i2cs[i] = dcn31_i2c_hw_create(ctx, i);
+ if (pool->base.hw_i2cs[i] == NULL) {
+ BREAK_TO_DEBUGGER();
+ dm_error(
+ "DC:failed to create hw i2c!!\n");
+ goto create_fail;
+ }
+ pool->base.sw_i2cs[i] = NULL;
+ }
+
+ /* Audio, Stream Encoders including HPO and virtual, MPC 3D LUTs */
+ if (!resource_construct(num_virtual_links, dc, &pool->base,
+ (!IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment) ?
+ &res_create_funcs : &res_create_maximus_funcs)))
+ goto create_fail;
+
+ /* HW Sequencer and Plane caps */
+ dcn31_hw_sequencer_construct(dc);
+
+ dc->caps.max_planes = pool->base.pipe_count;
+
+ for (i = 0; i < dc->caps.max_planes; ++i)
+ dc->caps.planes[i] = plane_cap;
+
+ dc->cap_funcs = cap_funcs;
+
+ dc->dcn_ip->max_num_dpp = dcn3_15_ip.max_num_dpp;
+
+ return true;
+
+create_fail:
+
+ dcn315_resource_destruct(pool);
+
+ return false;
+}
+
+struct resource_pool *dcn315_create_resource_pool(
+ const struct dc_init_data *init_data,
+ struct dc *dc)
+{
+ struct dcn315_resource_pool *pool =
+ kzalloc(sizeof(struct dcn315_resource_pool), GFP_KERNEL);
+
+ if (!pool)
+ return NULL;
+
+ if (dcn315_resource_construct(init_data->num_virtual_links, dc, pool))
+ return &pool->base;
+
+ BREAK_TO_DEBUGGER();
+ kfree(pool);
+ return NULL;
+}
diff --git a/drivers/gpu/drm/amd/display/dc/dcn315/dcn315_resource.h b/drivers/gpu/drm/amd/display/dc/dcn315/dcn315_resource.h
new file mode 100644
index 000000000000..f3a36820a31f
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/dc/dcn315/dcn315_resource.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2021 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: AMD
+ *
+ */
+
+#ifndef _DCN315_RESOURCE_H_
+#define _DCN315_RESOURCE_H_
+
+#include "core_types.h"
+
+#define TO_DCN315_RES_POOL(pool)\
+ container_of(pool, struct dcn315_resource_pool, base)
+
+struct dcn315_resource_pool {
+ struct resource_pool base;
+};
+
+struct resource_pool *dcn315_create_resource_pool(
+ const struct dc_init_data *init_data,
+ struct dc *dc);
+
+#endif /* _DCN315_RESOURCE_H_ */
diff --git a/drivers/gpu/drm/amd/display/dc/dcn316/Makefile b/drivers/gpu/drm/amd/display/dc/dcn316/Makefile
new file mode 100644
index 000000000000..cd87b687c5e2
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/dc/dcn316/Makefile
@@ -0,0 +1,56 @@
+#
+# Copyright 2021 Advanced Micro Devices, Inc.
+#
+# Permission is hereby granted, free of charge, to any person obtaining a
+# copy of this software and associated documentation files (the "Software"),
+# to deal in the Software without restriction, including without limitation
+# the rights to use, copy, modify, merge, publish, distribute, sublicense,
+# and/or sell copies of the Software, and to permit persons to whom the
+# Software is furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+# THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+# OTHER DEALINGS IN THE SOFTWARE.
+#
+# Authors: AMD
+#
+# Makefile for dcn316.
+
+DCN316 = dcn316_resource.o
+
+ifdef CONFIG_X86
+CFLAGS_$(AMDDALPATH)/dc/dcn316/dcn316_resource.o := -msse
+endif
+
+ifdef CONFIG_PPC64
+CFLAGS_$(AMDDALPATH)/dc/dcn316/dcn316_resource.o := -mhard-float -maltivec
+endif
+
+ifdef CONFIG_CC_IS_GCC
+ifeq ($(call cc-ifversion, -lt, 0701, y), y)
+IS_OLD_GCC = 1
+endif
+CFLAGS_$(AMDDALPATH)/dc/dcn316/dcn316_resource.o += -mhard-float
+endif
+
+ifdef CONFIG_X86
+ifdef IS_OLD_GCC
+# Stack alignment mismatch, proceed with caution.
+# GCC < 7.1 cannot compile code using `double` and -mpreferred-stack-boundary=3
+# (8B stack alignment).
+CFLAGS_$(AMDDALPATH)/dc/dcn316/dcn316_resource.o += -mpreferred-stack-boundary=4
+else
+CFLAGS_$(AMDDALPATH)/dc/dcn316/dcn316_resource.o += -msse2
+endif
+endif
+
+AMD_DAL_DCN316 = $(addprefix $(AMDDALPATH)/dc/dcn316/,$(DCN316))
+
+AMD_DISPLAY_FILES += $(AMD_DAL_DCN316)
diff --git a/drivers/gpu/drm/amd/display/dc/dcn316/dcn316_resource.c b/drivers/gpu/drm/amd/display/dc/dcn316/dcn316_resource.c
new file mode 100644
index 000000000000..8decc3ccf8ca
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/dc/dcn316/dcn316_resource.c
@@ -0,0 +1,2285 @@
+/*
+ * Copyright 2021 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: AMD
+ *
+ */
+
+
+#include "dm_services.h"
+#include "dc.h"
+
+#include "dcn31/dcn31_init.h"
+
+#include "resource.h"
+#include "include/irq_service_interface.h"
+#include "dcn316_resource.h"
+
+#include "dcn20/dcn20_resource.h"
+#include "dcn30/dcn30_resource.h"
+#include "dcn31/dcn31_resource.h"
+
+#include "dcn10/dcn10_ipp.h"
+#include "dcn30/dcn30_hubbub.h"
+#include "dcn31/dcn31_hubbub.h"
+#include "dcn30/dcn30_mpc.h"
+#include "dcn31/dcn31_hubp.h"
+#include "irq/dcn31/irq_service_dcn31.h"
+#include "dcn30/dcn30_dpp.h"
+#include "dcn31/dcn31_optc.h"
+#include "dcn20/dcn20_hwseq.h"
+#include "dcn30/dcn30_hwseq.h"
+#include "dce110/dce110_hw_sequencer.h"
+#include "dcn30/dcn30_opp.h"
+#include "dcn20/dcn20_dsc.h"
+#include "dcn30/dcn30_vpg.h"
+#include "dcn30/dcn30_afmt.h"
+#include "dcn30/dcn30_dio_stream_encoder.h"
+#include "dcn31/dcn31_hpo_dp_stream_encoder.h"
+#include "dcn31/dcn31_hpo_dp_link_encoder.h"
+#include "dcn31/dcn31_apg.h"
+#include "dcn31/dcn31_dio_link_encoder.h"
+#include "dcn31/dcn31_vpg.h"
+#include "dcn31/dcn31_afmt.h"
+#include "dce/dce_clock_source.h"
+#include "dce/dce_audio.h"
+#include "dce/dce_hwseq.h"
+#include "clk_mgr.h"
+#include "virtual/virtual_stream_encoder.h"
+#include "dce110/dce110_resource.h"
+#include "dml/display_mode_vba.h"
+#include "dcn31/dcn31_dccg.h"
+#include "dcn10/dcn10_resource.h"
+#include "dcn31/dcn31_panel_cntl.h"
+
+#include "dcn30/dcn30_dwb.h"
+#include "dcn30/dcn30_mmhubbub.h"
+
+#include "dcn/dcn_3_1_6_offset.h"
+#include "dcn/dcn_3_1_6_sh_mask.h"
+#include "dpcs/dpcs_4_2_3_offset.h"
+#include "dpcs/dpcs_4_2_3_sh_mask.h"
+
+#define regBIF_BX1_BIOS_SCRATCH_2 0x003a
+#define regBIF_BX1_BIOS_SCRATCH_2_BASE_IDX 1
+#define regBIF_BX1_BIOS_SCRATCH_3 0x003b
+#define regBIF_BX1_BIOS_SCRATCH_3_BASE_IDX 1
+#define regBIF_BX1_BIOS_SCRATCH_6 0x003e
+#define regBIF_BX1_BIOS_SCRATCH_6_BASE_IDX 1
+
+#define regDCHUBBUB_DEBUG_CTRL_0 0x04d6
+#define regDCHUBBUB_DEBUG_CTRL_0_BASE_IDX 2
+#define DCHUBBUB_DEBUG_CTRL_0__DET_DEPTH__SHIFT 0x10
+#define DCHUBBUB_DEBUG_CTRL_0__DET_DEPTH_MASK 0x01FF0000L
+
+#define DCN_BASE__INST0_SEG0 0x00000012
+#define DCN_BASE__INST0_SEG1 0x000000C0
+#define DCN_BASE__INST0_SEG2 0x000034C0
+#define DCN_BASE__INST0_SEG3 0x00009000
+#define DCN_BASE__INST0_SEG4 0x02403C00
+#define DCN_BASE__INST0_SEG5 0
+
+#define DPCS_BASE__INST0_SEG0 0x00000012
+#define DPCS_BASE__INST0_SEG1 0x000000C0
+#define DPCS_BASE__INST0_SEG2 0x000034C0
+#define DPCS_BASE__INST0_SEG3 0x00009000
+#define DPCS_BASE__INST0_SEG4 0x02403C00
+#define DPCS_BASE__INST0_SEG5 0
+
+#define NBIO_BASE__INST0_SEG0 0x00000000
+#define NBIO_BASE__INST0_SEG1 0x00000014
+#define NBIO_BASE__INST0_SEG2 0x00000D20
+#define NBIO_BASE__INST0_SEG3 0x00010400
+#define NBIO_BASE__INST0_SEG4 0x0241B000
+#define NBIO_BASE__INST0_SEG5 0x04040000
+
+#include "reg_helper.h"
+#include "dce/dmub_abm.h"
+#include "dce/dmub_psr.h"
+#include "dce/dce_aux.h"
+#include "dce/dce_i2c.h"
+
+#include "dml/dcn30/display_mode_vba_30.h"
+#include "vm_helper.h"
+#include "dcn20/dcn20_vmid.h"
+
+#include "link_enc_cfg.h"
+
+#define DC_LOGGER_INIT(logger)
+
+#define DCN3_16_DEFAULT_DET_SIZE 192
+#define DCN3_16_MAX_DET_SIZE 384
+#define DCN3_16_MIN_COMPBUF_SIZE_KB 128
+#define DCN3_16_CRB_SEGMENT_SIZE_KB 64
+
+struct _vcs_dpi_ip_params_st dcn3_16_ip = {
+ .gpuvm_enable = 1,
+ .gpuvm_max_page_table_levels = 1,
+ .hostvm_enable = 1,
+ .hostvm_max_page_table_levels = 2,
+ .rob_buffer_size_kbytes = 64,
+ .det_buffer_size_kbytes = DCN3_16_DEFAULT_DET_SIZE,
+ .config_return_buffer_size_in_kbytes = 1024,
+ .compressed_buffer_segment_size_in_kbytes = 64,
+ .meta_fifo_size_in_kentries = 32,
+ .zero_size_buffer_entries = 512,
+ .compbuf_reserved_space_64b = 256,
+ .compbuf_reserved_space_zs = 64,
+ .dpp_output_buffer_pixels = 2560,
+ .opp_output_buffer_lines = 1,
+ .pixel_chunk_size_kbytes = 8,
+ .meta_chunk_size_kbytes = 2,
+ .min_meta_chunk_size_bytes = 256,
+ .writeback_chunk_size_kbytes = 8,
+ .ptoi_supported = false,
+ .num_dsc = 3,
+ .maximum_dsc_bits_per_component = 10,
+ .dsc422_native_support = false,
+ .is_line_buffer_bpp_fixed = true,
+ .line_buffer_fixed_bpp = 48,
+ .line_buffer_size_bits = 789504,
+ .max_line_buffer_lines = 12,
+ .writeback_interface_buffer_size_kbytes = 90,
+ .max_num_dpp = 4,
+ .max_num_otg = 4,
+ .max_num_hdmi_frl_outputs = 1,
+ .max_num_wb = 1,
+ .max_dchub_pscl_bw_pix_per_clk = 4,
+ .max_pscl_lb_bw_pix_per_clk = 2,
+ .max_lb_vscl_bw_pix_per_clk = 4,
+ .max_vscl_hscl_bw_pix_per_clk = 4,
+ .max_hscl_ratio = 6,
+ .max_vscl_ratio = 6,
+ .max_hscl_taps = 8,
+ .max_vscl_taps = 8,
+ .dpte_buffer_size_in_pte_reqs_luma = 64,
+ .dpte_buffer_size_in_pte_reqs_chroma = 34,
+ .dispclk_ramp_margin_percent = 1,
+ .max_inter_dcn_tile_repeaters = 8,
+ .cursor_buffer_size = 16,
+ .cursor_chunk_size = 2,
+ .writeback_line_buffer_buffer_size = 0,
+ .writeback_min_hscl_ratio = 1,
+ .writeback_min_vscl_ratio = 1,
+ .writeback_max_hscl_ratio = 1,
+ .writeback_max_vscl_ratio = 1,
+ .writeback_max_hscl_taps = 1,
+ .writeback_max_vscl_taps = 1,
+ .dppclk_delay_subtotal = 46,
+ .dppclk_delay_scl = 50,
+ .dppclk_delay_scl_lb_only = 16,
+ .dppclk_delay_cnvc_formatter = 27,
+ .dppclk_delay_cnvc_cursor = 6,
+ .dispclk_delay_subtotal = 119,
+ .dynamic_metadata_vm_enabled = false,
+ .odm_combine_4to1_supported = false,
+ .dcc_supported = true,
+};
+
+struct _vcs_dpi_soc_bounding_box_st dcn3_16_soc = {
+ /*TODO: correct dispclk/dppclk voltage level determination*/
+ .clock_limits = {
+ {
+ .state = 0,
+ .dispclk_mhz = 556.0,
+ .dppclk_mhz = 556.0,
+ .phyclk_mhz = 600.0,
+ .phyclk_d18_mhz = 445.0,
+ .dscclk_mhz = 186.0,
+ .dtbclk_mhz = 625.0,
+ },
+ {
+ .state = 1,
+ .dispclk_mhz = 625.0,
+ .dppclk_mhz = 625.0,
+ .phyclk_mhz = 810.0,
+ .phyclk_d18_mhz = 667.0,
+ .dscclk_mhz = 209.0,
+ .dtbclk_mhz = 625.0,
+ },
+ {
+ .state = 2,
+ .dispclk_mhz = 625.0,
+ .dppclk_mhz = 625.0,
+ .phyclk_mhz = 810.0,
+ .phyclk_d18_mhz = 667.0,
+ .dscclk_mhz = 209.0,
+ .dtbclk_mhz = 625.0,
+ },
+ {
+ .state = 3,
+ .dispclk_mhz = 1112.0,
+ .dppclk_mhz = 1112.0,
+ .phyclk_mhz = 810.0,
+ .phyclk_d18_mhz = 667.0,
+ .dscclk_mhz = 371.0,
+ .dtbclk_mhz = 625.0,
+ },
+ {
+ .state = 4,
+ .dispclk_mhz = 1250.0,
+ .dppclk_mhz = 1250.0,
+ .phyclk_mhz = 810.0,
+ .phyclk_d18_mhz = 667.0,
+ .dscclk_mhz = 417.0,
+ .dtbclk_mhz = 625.0,
+ },
+ },
+ .num_states = 5,
+ .sr_exit_time_us = 9.0,
+ .sr_enter_plus_exit_time_us = 11.0,
+ .sr_exit_z8_time_us = 442.0,
+ .sr_enter_plus_exit_z8_time_us = 560.0,
+ .writeback_latency_us = 12.0,
+ .dram_channel_width_bytes = 4,
+ .round_trip_ping_latency_dcfclk_cycles = 106,
+ .urgent_latency_pixel_data_only_us = 4.0,
+ .urgent_latency_pixel_mixed_with_vm_data_us = 4.0,
+ .urgent_latency_vm_data_only_us = 4.0,
+ .urgent_out_of_order_return_per_channel_pixel_only_bytes = 4096,
+ .urgent_out_of_order_return_per_channel_pixel_and_vm_bytes = 4096,
+ .urgent_out_of_order_return_per_channel_vm_only_bytes = 4096,
+ .pct_ideal_sdp_bw_after_urgent = 80.0,
+ .pct_ideal_dram_sdp_bw_after_urgent_pixel_only = 65.0,
+ .pct_ideal_dram_sdp_bw_after_urgent_pixel_and_vm = 60.0,
+ .pct_ideal_dram_sdp_bw_after_urgent_vm_only = 30.0,
+ .max_avg_sdp_bw_use_normal_percent = 60.0,
+ .max_avg_dram_bw_use_normal_percent = 60.0,
+ .fabric_datapath_to_dcn_data_return_bytes = 32,
+ .return_bus_width_bytes = 64,
+ .downspread_percent = 0.38,
+ .dcn_downspread_percent = 0.5,
+ .gpuvm_min_page_size_bytes = 4096,
+ .hostvm_min_page_size_bytes = 4096,
+ .do_urgent_latency_adjustment = false,
+ .urgent_latency_adjustment_fabric_clock_component_us = 0,
+ .urgent_latency_adjustment_fabric_clock_reference_mhz = 0,
+};
+
+enum dcn31_clk_src_array_id {
+ DCN31_CLK_SRC_PLL0,
+ DCN31_CLK_SRC_PLL1,
+ DCN31_CLK_SRC_PLL2,
+ DCN31_CLK_SRC_PLL3,
+ DCN31_CLK_SRC_PLL4,
+ DCN30_CLK_SRC_TOTAL
+};
+
+/* begin *********************
+ * macros to expend register list macro defined in HW object header file
+ */
+
+/* DCN */
+/* TODO awful hack. fixup dcn20_dwb.h */
+#undef BASE_INNER
+#define BASE_INNER(seg) DCN_BASE__INST0_SEG ## seg
+
+#define BASE(seg) BASE_INNER(seg)
+
+#define SR(reg_name)\
+ .reg_name = BASE(reg ## reg_name ## _BASE_IDX) + \
+ reg ## reg_name
+
+#define SRI(reg_name, block, id)\
+ .reg_name = BASE(reg ## block ## id ## _ ## reg_name ## _BASE_IDX) + \
+ reg ## block ## id ## _ ## reg_name
+
+#define SRI2(reg_name, block, id)\
+ .reg_name = BASE(reg ## reg_name ## _BASE_IDX) + \
+ reg ## reg_name
+
+#define SRIR(var_name, reg_name, block, id)\
+ .var_name = BASE(reg ## block ## id ## _ ## reg_name ## _BASE_IDX) + \
+ reg ## block ## id ## _ ## reg_name
+
+#define SRII(reg_name, block, id)\
+ .reg_name[id] = BASE(reg ## block ## id ## _ ## reg_name ## _BASE_IDX) + \
+ reg ## block ## id ## _ ## reg_name
+
+#define SRII_MPC_RMU(reg_name, block, id)\
+ .RMU##_##reg_name[id] = BASE(reg ## block ## id ## _ ## reg_name ## _BASE_IDX) + \
+ reg ## block ## id ## _ ## reg_name
+
+#define SRII_DWB(reg_name, temp_name, block, id)\
+ .reg_name[id] = BASE(reg ## block ## id ## _ ## temp_name ## _BASE_IDX) + \
+ reg ## block ## id ## _ ## temp_name
+
+#define DCCG_SRII(reg_name, block, id)\
+ .block ## _ ## reg_name[id] = BASE(reg ## block ## id ## _ ## reg_name ## _BASE_IDX) + \
+ reg ## block ## id ## _ ## reg_name
+
+#define VUPDATE_SRII(reg_name, block, id)\
+ .reg_name[id] = BASE(reg ## reg_name ## _ ## block ## id ## _BASE_IDX) + \
+ reg ## reg_name ## _ ## block ## id
+
+/* NBIO */
+#define NBIO_BASE_INNER(seg) \
+ NBIO_BASE__INST0_SEG ## seg
+
+#define NBIO_BASE(seg) \
+ NBIO_BASE_INNER(seg)
+
+#define NBIO_SR(reg_name)\
+ .reg_name = NBIO_BASE(regBIF_BX1_ ## reg_name ## _BASE_IDX) + \
+ regBIF_BX1_ ## reg_name
+
+static const struct bios_registers bios_regs = {
+ NBIO_SR(BIOS_SCRATCH_3),
+ NBIO_SR(BIOS_SCRATCH_6)
+};
+
+#define clk_src_regs(index, pllid)\
+[index] = {\
+ CS_COMMON_REG_LIST_DCN3_0(index, pllid),\
+}
+
+static const struct dce110_clk_src_regs clk_src_regs[] = {
+ clk_src_regs(0, A),
+ clk_src_regs(1, B),
+ clk_src_regs(2, C),
+ clk_src_regs(3, D),
+ clk_src_regs(4, E)
+};
+
+static const struct dce110_clk_src_shift cs_shift = {
+ CS_COMMON_MASK_SH_LIST_DCN2_0(__SHIFT)
+};
+
+static const struct dce110_clk_src_mask cs_mask = {
+ CS_COMMON_MASK_SH_LIST_DCN2_0(_MASK)
+};
+
+#define abm_regs(id)\
+[id] = {\
+ ABM_DCN302_REG_LIST(id)\
+}
+
+static const struct dce_abm_registers abm_regs[] = {
+ abm_regs(0),
+ abm_regs(1),
+ abm_regs(2),
+ abm_regs(3),
+};
+
+static const struct dce_abm_shift abm_shift = {
+ ABM_MASK_SH_LIST_DCN30(__SHIFT)
+};
+
+static const struct dce_abm_mask abm_mask = {
+ ABM_MASK_SH_LIST_DCN30(_MASK)
+};
+
+#define audio_regs(id)\
+[id] = {\
+ AUD_COMMON_REG_LIST(id)\
+}
+
+static const struct dce_audio_registers audio_regs[] = {
+ audio_regs(0),
+ audio_regs(1),
+ audio_regs(2),
+ audio_regs(3),
+ audio_regs(4),
+ audio_regs(5),
+ audio_regs(6)
+};
+
+#define DCE120_AUD_COMMON_MASK_SH_LIST(mask_sh)\
+ SF(AZF0ENDPOINT0_AZALIA_F0_CODEC_ENDPOINT_INDEX, AZALIA_ENDPOINT_REG_INDEX, mask_sh),\
+ SF(AZF0ENDPOINT0_AZALIA_F0_CODEC_ENDPOINT_DATA, AZALIA_ENDPOINT_REG_DATA, mask_sh),\
+ AUD_COMMON_MASK_SH_LIST_BASE(mask_sh)
+
+static const struct dce_audio_shift audio_shift = {
+ DCE120_AUD_COMMON_MASK_SH_LIST(__SHIFT)
+};
+
+static const struct dce_audio_mask audio_mask = {
+ DCE120_AUD_COMMON_MASK_SH_LIST(_MASK)
+};
+
+#define vpg_regs(id)\
+[id] = {\
+ VPG_DCN31_REG_LIST(id)\
+}
+
+static const struct dcn31_vpg_registers vpg_regs[] = {
+ vpg_regs(0),
+ vpg_regs(1),
+ vpg_regs(2),
+ vpg_regs(3),
+ vpg_regs(4),
+ vpg_regs(5),
+ vpg_regs(6),
+ vpg_regs(7),
+ vpg_regs(8),
+ vpg_regs(9),
+};
+
+static const struct dcn31_vpg_shift vpg_shift = {
+ DCN31_VPG_MASK_SH_LIST(__SHIFT)
+};
+
+static const struct dcn31_vpg_mask vpg_mask = {
+ DCN31_VPG_MASK_SH_LIST(_MASK)
+};
+
+#define afmt_regs(id)\
+[id] = {\
+ AFMT_DCN31_REG_LIST(id)\
+}
+
+static const struct dcn31_afmt_registers afmt_regs[] = {
+ afmt_regs(0),
+ afmt_regs(1),
+ afmt_regs(2),
+ afmt_regs(3),
+ afmt_regs(4),
+ afmt_regs(5)
+};
+
+static const struct dcn31_afmt_shift afmt_shift = {
+ DCN31_AFMT_MASK_SH_LIST(__SHIFT)
+};
+
+static const struct dcn31_afmt_mask afmt_mask = {
+ DCN31_AFMT_MASK_SH_LIST(_MASK)
+};
+
+
+#define apg_regs(id)\
+[id] = {\
+ APG_DCN31_REG_LIST(id)\
+}
+
+static const struct dcn31_apg_registers apg_regs[] = {
+ apg_regs(0),
+ apg_regs(1),
+ apg_regs(2),
+ apg_regs(3)
+};
+
+static const struct dcn31_apg_shift apg_shift = {
+ DCN31_APG_MASK_SH_LIST(__SHIFT)
+};
+
+static const struct dcn31_apg_mask apg_mask = {
+ DCN31_APG_MASK_SH_LIST(_MASK)
+};
+
+
+#define stream_enc_regs(id)\
+[id] = {\
+ SE_DCN3_REG_LIST(id)\
+}
+
+static const struct dcn10_stream_enc_registers stream_enc_regs[] = {
+ stream_enc_regs(0),
+ stream_enc_regs(1),
+ stream_enc_regs(2),
+ stream_enc_regs(3),
+ stream_enc_regs(4)
+};
+
+static const struct dcn10_stream_encoder_shift se_shift = {
+ SE_COMMON_MASK_SH_LIST_DCN30(__SHIFT)
+};
+
+static const struct dcn10_stream_encoder_mask se_mask = {
+ SE_COMMON_MASK_SH_LIST_DCN30(_MASK)
+};
+
+
+#define aux_regs(id)\
+[id] = {\
+ DCN2_AUX_REG_LIST(id)\
+}
+
+static const struct dcn10_link_enc_aux_registers link_enc_aux_regs[] = {
+ aux_regs(0),
+ aux_regs(1),
+ aux_regs(2),
+ aux_regs(3),
+ aux_regs(4)
+};
+
+#define hpd_regs(id)\
+[id] = {\
+ HPD_REG_LIST(id)\
+}
+
+static const struct dcn10_link_enc_hpd_registers link_enc_hpd_regs[] = {
+ hpd_regs(0),
+ hpd_regs(1),
+ hpd_regs(2),
+ hpd_regs(3),
+ hpd_regs(4)
+};
+
+#define link_regs(id, phyid)\
+[id] = {\
+ LE_DCN31_REG_LIST(id), \
+ UNIPHY_DCN2_REG_LIST(phyid), \
+ DPCS_DCN31_REG_LIST(id), \
+}
+
+static const struct dce110_aux_registers_shift aux_shift = {
+ DCN_AUX_MASK_SH_LIST(__SHIFT)
+};
+
+static const struct dce110_aux_registers_mask aux_mask = {
+ DCN_AUX_MASK_SH_LIST(_MASK)
+};
+
+static const struct dcn10_link_enc_registers link_enc_regs[] = {
+ link_regs(0, A),
+ link_regs(1, B),
+ link_regs(2, C),
+ link_regs(3, D),
+ link_regs(4, E)
+};
+
+static const struct dcn10_link_enc_shift le_shift = {
+ LINK_ENCODER_MASK_SH_LIST_DCN31(__SHIFT), \
+ DPCS_DCN31_MASK_SH_LIST(__SHIFT)
+};
+
+static const struct dcn10_link_enc_mask le_mask = {
+ LINK_ENCODER_MASK_SH_LIST_DCN31(_MASK), \
+ DPCS_DCN31_MASK_SH_LIST(_MASK)
+};
+
+
+
+#define hpo_dp_stream_encoder_reg_list(id)\
+[id] = {\
+ DCN3_1_HPO_DP_STREAM_ENC_REG_LIST(id)\
+}
+
+static const struct dcn31_hpo_dp_stream_encoder_registers hpo_dp_stream_enc_regs[] = {
+ hpo_dp_stream_encoder_reg_list(0),
+ hpo_dp_stream_encoder_reg_list(1),
+ hpo_dp_stream_encoder_reg_list(2),
+ hpo_dp_stream_encoder_reg_list(3),
+};
+
+static const struct dcn31_hpo_dp_stream_encoder_shift hpo_dp_se_shift = {
+ DCN3_1_HPO_DP_STREAM_ENC_MASK_SH_LIST(__SHIFT)
+};
+
+static const struct dcn31_hpo_dp_stream_encoder_mask hpo_dp_se_mask = {
+ DCN3_1_HPO_DP_STREAM_ENC_MASK_SH_LIST(_MASK)
+};
+
+
+#define hpo_dp_link_encoder_reg_list(id)\
+[id] = {\
+ DCN3_1_HPO_DP_LINK_ENC_REG_LIST(id),\
+ DCN3_1_RDPCSTX_REG_LIST(0),\
+ DCN3_1_RDPCSTX_REG_LIST(1),\
+ DCN3_1_RDPCSTX_REG_LIST(2),\
+ DCN3_1_RDPCSTX_REG_LIST(3),\
+ DCN3_1_RDPCSTX_REG_LIST(4)\
+}
+
+static const struct dcn31_hpo_dp_link_encoder_registers hpo_dp_link_enc_regs[] = {
+ hpo_dp_link_encoder_reg_list(0),
+ hpo_dp_link_encoder_reg_list(1),
+};
+
+static const struct dcn31_hpo_dp_link_encoder_shift hpo_dp_le_shift = {
+ DCN3_1_HPO_DP_LINK_ENC_MASK_SH_LIST(__SHIFT)
+};
+
+static const struct dcn31_hpo_dp_link_encoder_mask hpo_dp_le_mask = {
+ DCN3_1_HPO_DP_LINK_ENC_MASK_SH_LIST(_MASK)
+};
+
+
+#define dpp_regs(id)\
+[id] = {\
+ DPP_REG_LIST_DCN30(id),\
+}
+
+static const struct dcn3_dpp_registers dpp_regs[] = {
+ dpp_regs(0),
+ dpp_regs(1),
+ dpp_regs(2),
+ dpp_regs(3)
+};
+
+static const struct dcn3_dpp_shift tf_shift = {
+ DPP_REG_LIST_SH_MASK_DCN30(__SHIFT)
+};
+
+static const struct dcn3_dpp_mask tf_mask = {
+ DPP_REG_LIST_SH_MASK_DCN30(_MASK)
+};
+
+#define opp_regs(id)\
+[id] = {\
+ OPP_REG_LIST_DCN30(id),\
+}
+
+static const struct dcn20_opp_registers opp_regs[] = {
+ opp_regs(0),
+ opp_regs(1),
+ opp_regs(2),
+ opp_regs(3)
+};
+
+static const struct dcn20_opp_shift opp_shift = {
+ OPP_MASK_SH_LIST_DCN20(__SHIFT)
+};
+
+static const struct dcn20_opp_mask opp_mask = {
+ OPP_MASK_SH_LIST_DCN20(_MASK)
+};
+
+#define aux_engine_regs(id)\
+[id] = {\
+ AUX_COMMON_REG_LIST0(id), \
+ .AUXN_IMPCAL = 0, \
+ .AUXP_IMPCAL = 0, \
+ .AUX_RESET_MASK = DP_AUX0_AUX_CONTROL__AUX_RESET_MASK, \
+}
+
+static const struct dce110_aux_registers aux_engine_regs[] = {
+ aux_engine_regs(0),
+ aux_engine_regs(1),
+ aux_engine_regs(2),
+ aux_engine_regs(3),
+ aux_engine_regs(4)
+};
+
+#define dwbc_regs_dcn3(id)\
+[id] = {\
+ DWBC_COMMON_REG_LIST_DCN30(id),\
+}
+
+static const struct dcn30_dwbc_registers dwbc30_regs[] = {
+ dwbc_regs_dcn3(0),
+};
+
+static const struct dcn30_dwbc_shift dwbc30_shift = {
+ DWBC_COMMON_MASK_SH_LIST_DCN30(__SHIFT)
+};
+
+static const struct dcn30_dwbc_mask dwbc30_mask = {
+ DWBC_COMMON_MASK_SH_LIST_DCN30(_MASK)
+};
+
+#define mcif_wb_regs_dcn3(id)\
+[id] = {\
+ MCIF_WB_COMMON_REG_LIST_DCN30(id),\
+}
+
+static const struct dcn30_mmhubbub_registers mcif_wb30_regs[] = {
+ mcif_wb_regs_dcn3(0)
+};
+
+static const struct dcn30_mmhubbub_shift mcif_wb30_shift = {
+ MCIF_WB_COMMON_MASK_SH_LIST_DCN30(__SHIFT)
+};
+
+static const struct dcn30_mmhubbub_mask mcif_wb30_mask = {
+ MCIF_WB_COMMON_MASK_SH_LIST_DCN30(_MASK)
+};
+
+#define dsc_regsDCN20(id)\
+[id] = {\
+ DSC_REG_LIST_DCN20(id)\
+}
+
+static const struct dcn20_dsc_registers dsc_regs[] = {
+ dsc_regsDCN20(0),
+ dsc_regsDCN20(1),
+ dsc_regsDCN20(2)
+};
+
+static const struct dcn20_dsc_shift dsc_shift = {
+ DSC_REG_LIST_SH_MASK_DCN20(__SHIFT)
+};
+
+static const struct dcn20_dsc_mask dsc_mask = {
+ DSC_REG_LIST_SH_MASK_DCN20(_MASK)
+};
+
+static const struct dcn30_mpc_registers mpc_regs = {
+ MPC_REG_LIST_DCN3_0(0),
+ MPC_REG_LIST_DCN3_0(1),
+ MPC_REG_LIST_DCN3_0(2),
+ MPC_REG_LIST_DCN3_0(3),
+ MPC_OUT_MUX_REG_LIST_DCN3_0(0),
+ MPC_OUT_MUX_REG_LIST_DCN3_0(1),
+ MPC_OUT_MUX_REG_LIST_DCN3_0(2),
+ MPC_OUT_MUX_REG_LIST_DCN3_0(3),
+ MPC_RMU_GLOBAL_REG_LIST_DCN3AG,
+ MPC_RMU_REG_LIST_DCN3AG(0),
+ MPC_RMU_REG_LIST_DCN3AG(1),
+ //MPC_RMU_REG_LIST_DCN3AG(2),
+ MPC_DWB_MUX_REG_LIST_DCN3_0(0),
+};
+
+static const struct dcn30_mpc_shift mpc_shift = {
+ MPC_COMMON_MASK_SH_LIST_DCN30(__SHIFT)
+};
+
+static const struct dcn30_mpc_mask mpc_mask = {
+ MPC_COMMON_MASK_SH_LIST_DCN30(_MASK)
+};
+
+#define optc_regs(id)\
+[id] = {OPTC_COMMON_REG_LIST_DCN3_1(id)}
+
+static const struct dcn_optc_registers optc_regs[] = {
+ optc_regs(0),
+ optc_regs(1),
+ optc_regs(2),
+ optc_regs(3)
+};
+
+static const struct dcn_optc_shift optc_shift = {
+ OPTC_COMMON_MASK_SH_LIST_DCN3_1(__SHIFT)
+};
+
+static const struct dcn_optc_mask optc_mask = {
+ OPTC_COMMON_MASK_SH_LIST_DCN3_1(_MASK)
+};
+
+#define hubp_regs(id)\
+[id] = {\
+ HUBP_REG_LIST_DCN30(id)\
+}
+
+static const struct dcn_hubp2_registers hubp_regs[] = {
+ hubp_regs(0),
+ hubp_regs(1),
+ hubp_regs(2),
+ hubp_regs(3)
+};
+
+
+static const struct dcn_hubp2_shift hubp_shift = {
+ HUBP_MASK_SH_LIST_DCN31(__SHIFT)
+};
+
+static const struct dcn_hubp2_mask hubp_mask = {
+ HUBP_MASK_SH_LIST_DCN31(_MASK)
+};
+static const struct dcn_hubbub_registers hubbub_reg = {
+ HUBBUB_REG_LIST_DCN31(0)
+};
+
+static const struct dcn_hubbub_shift hubbub_shift = {
+ HUBBUB_MASK_SH_LIST_DCN31(__SHIFT)
+};
+
+static const struct dcn_hubbub_mask hubbub_mask = {
+ HUBBUB_MASK_SH_LIST_DCN31(_MASK)
+};
+
+static const struct dccg_registers dccg_regs = {
+ DCCG_REG_LIST_DCN31()
+};
+
+static const struct dccg_shift dccg_shift = {
+ DCCG_MASK_SH_LIST_DCN31(__SHIFT)
+};
+
+static const struct dccg_mask dccg_mask = {
+ DCCG_MASK_SH_LIST_DCN31(_MASK)
+};
+
+
+#define SRII2(reg_name_pre, reg_name_post, id)\
+ .reg_name_pre ## _ ## reg_name_post[id] = BASE(reg ## reg_name_pre \
+ ## id ## _ ## reg_name_post ## _BASE_IDX) + \
+ reg ## reg_name_pre ## id ## _ ## reg_name_post
+
+
+#define HWSEQ_DCN31_REG_LIST()\
+ SR(DCHUBBUB_GLOBAL_TIMER_CNTL), \
+ SR(DCHUBBUB_ARB_HOSTVM_CNTL), \
+ SR(DIO_MEM_PWR_CTRL), \
+ SR(ODM_MEM_PWR_CTRL3), \
+ SR(DMU_MEM_PWR_CNTL), \
+ SR(MMHUBBUB_MEM_PWR_CNTL), \
+ SR(DCCG_GATE_DISABLE_CNTL), \
+ SR(DCCG_GATE_DISABLE_CNTL2), \
+ SR(DCFCLK_CNTL),\
+ SR(DC_MEM_GLOBAL_PWR_REQ_CNTL), \
+ SRII(PIXEL_RATE_CNTL, OTG, 0), \
+ SRII(PIXEL_RATE_CNTL, OTG, 1),\
+ SRII(PIXEL_RATE_CNTL, OTG, 2),\
+ SRII(PIXEL_RATE_CNTL, OTG, 3),\
+ SRII(PHYPLL_PIXEL_RATE_CNTL, OTG, 0),\
+ SRII(PHYPLL_PIXEL_RATE_CNTL, OTG, 1),\
+ SRII(PHYPLL_PIXEL_RATE_CNTL, OTG, 2),\
+ SRII(PHYPLL_PIXEL_RATE_CNTL, OTG, 3),\
+ SR(MICROSECOND_TIME_BASE_DIV), \
+ SR(MILLISECOND_TIME_BASE_DIV), \
+ SR(DISPCLK_FREQ_CHANGE_CNTL), \
+ SR(RBBMIF_TIMEOUT_DIS), \
+ SR(RBBMIF_TIMEOUT_DIS_2), \
+ SR(DCHUBBUB_CRC_CTRL), \
+ SR(DPP_TOP0_DPP_CRC_CTRL), \
+ SR(DPP_TOP0_DPP_CRC_VAL_B_A), \
+ SR(DPP_TOP0_DPP_CRC_VAL_R_G), \
+ SR(MPC_CRC_CTRL), \
+ SR(MPC_CRC_RESULT_GB), \
+ SR(MPC_CRC_RESULT_C), \
+ SR(MPC_CRC_RESULT_AR), \
+ SR(DOMAIN0_PG_CONFIG), \
+ SR(DOMAIN1_PG_CONFIG), \
+ SR(DOMAIN2_PG_CONFIG), \
+ SR(DOMAIN3_PG_CONFIG), \
+ SR(DOMAIN16_PG_CONFIG), \
+ SR(DOMAIN17_PG_CONFIG), \
+ SR(DOMAIN18_PG_CONFIG), \
+ SR(DOMAIN0_PG_STATUS), \
+ SR(DOMAIN1_PG_STATUS), \
+ SR(DOMAIN2_PG_STATUS), \
+ SR(DOMAIN3_PG_STATUS), \
+ SR(DOMAIN16_PG_STATUS), \
+ SR(DOMAIN17_PG_STATUS), \
+ SR(DOMAIN18_PG_STATUS), \
+ SR(D1VGA_CONTROL), \
+ SR(D2VGA_CONTROL), \
+ SR(D3VGA_CONTROL), \
+ SR(D4VGA_CONTROL), \
+ SR(D5VGA_CONTROL), \
+ SR(D6VGA_CONTROL), \
+ SR(DC_IP_REQUEST_CNTL), \
+ SR(AZALIA_AUDIO_DTO), \
+ SR(AZALIA_CONTROLLER_CLOCK_GATING), \
+ SR(HPO_TOP_HW_CONTROL)
+
+static const struct dce_hwseq_registers hwseq_reg = {
+ HWSEQ_DCN31_REG_LIST()
+};
+
+#define HWSEQ_DCN31_MASK_SH_LIST(mask_sh)\
+ HWSEQ_DCN_MASK_SH_LIST(mask_sh), \
+ HWS_SF(, DCHUBBUB_GLOBAL_TIMER_CNTL, DCHUBBUB_GLOBAL_TIMER_REFDIV, mask_sh), \
+ HWS_SF(, DCHUBBUB_ARB_HOSTVM_CNTL, DISABLE_HOSTVM_FORCE_ALLOW_PSTATE, mask_sh), \
+ HWS_SF(, DOMAIN0_PG_CONFIG, DOMAIN_POWER_FORCEON, mask_sh), \
+ HWS_SF(, DOMAIN0_PG_CONFIG, DOMAIN_POWER_GATE, mask_sh), \
+ HWS_SF(, DOMAIN1_PG_CONFIG, DOMAIN_POWER_FORCEON, mask_sh), \
+ HWS_SF(, DOMAIN1_PG_CONFIG, DOMAIN_POWER_GATE, mask_sh), \
+ HWS_SF(, DOMAIN2_PG_CONFIG, DOMAIN_POWER_FORCEON, mask_sh), \
+ HWS_SF(, DOMAIN2_PG_CONFIG, DOMAIN_POWER_GATE, mask_sh), \
+ HWS_SF(, DOMAIN3_PG_CONFIG, DOMAIN_POWER_FORCEON, mask_sh), \
+ HWS_SF(, DOMAIN3_PG_CONFIG, DOMAIN_POWER_GATE, mask_sh), \
+ HWS_SF(, DOMAIN16_PG_CONFIG, DOMAIN_POWER_FORCEON, mask_sh), \
+ HWS_SF(, DOMAIN16_PG_CONFIG, DOMAIN_POWER_GATE, mask_sh), \
+ HWS_SF(, DOMAIN17_PG_CONFIG, DOMAIN_POWER_FORCEON, mask_sh), \
+ HWS_SF(, DOMAIN17_PG_CONFIG, DOMAIN_POWER_GATE, mask_sh), \
+ HWS_SF(, DOMAIN18_PG_CONFIG, DOMAIN_POWER_FORCEON, mask_sh), \
+ HWS_SF(, DOMAIN18_PG_CONFIG, DOMAIN_POWER_GATE, mask_sh), \
+ HWS_SF(, DOMAIN0_PG_STATUS, DOMAIN_PGFSM_PWR_STATUS, mask_sh), \
+ HWS_SF(, DOMAIN1_PG_STATUS, DOMAIN_PGFSM_PWR_STATUS, mask_sh), \
+ HWS_SF(, DOMAIN2_PG_STATUS, DOMAIN_PGFSM_PWR_STATUS, mask_sh), \
+ HWS_SF(, DOMAIN3_PG_STATUS, DOMAIN_PGFSM_PWR_STATUS, mask_sh), \
+ HWS_SF(, DOMAIN16_PG_STATUS, DOMAIN_PGFSM_PWR_STATUS, mask_sh), \
+ HWS_SF(, DOMAIN17_PG_STATUS, DOMAIN_PGFSM_PWR_STATUS, mask_sh), \
+ HWS_SF(, DOMAIN18_PG_STATUS, DOMAIN_PGFSM_PWR_STATUS, mask_sh), \
+ HWS_SF(, DC_IP_REQUEST_CNTL, IP_REQUEST_EN, mask_sh), \
+ HWS_SF(, AZALIA_AUDIO_DTO, AZALIA_AUDIO_DTO_MODULE, mask_sh), \
+ HWS_SF(, HPO_TOP_CLOCK_CONTROL, HPO_HDMISTREAMCLK_G_GATE_DIS, mask_sh), \
+ HWS_SF(, DMU_MEM_PWR_CNTL, DMCU_ERAM_MEM_PWR_FORCE, mask_sh), \
+ HWS_SF(, ODM_MEM_PWR_CTRL3, ODM_MEM_UNASSIGNED_PWR_MODE, mask_sh), \
+ HWS_SF(, ODM_MEM_PWR_CTRL3, ODM_MEM_VBLANK_PWR_MODE, mask_sh), \
+ HWS_SF(, MMHUBBUB_MEM_PWR_CNTL, VGA_MEM_PWR_FORCE, mask_sh), \
+ HWS_SF(, DIO_MEM_PWR_CTRL, I2C_LIGHT_SLEEP_FORCE, mask_sh), \
+ HWS_SF(, HPO_TOP_HW_CONTROL, HPO_IO_EN, mask_sh)
+
+static const struct dce_hwseq_shift hwseq_shift = {
+ HWSEQ_DCN31_MASK_SH_LIST(__SHIFT)
+};
+
+static const struct dce_hwseq_mask hwseq_mask = {
+ HWSEQ_DCN31_MASK_SH_LIST(_MASK)
+};
+#define vmid_regs(id)\
+[id] = {\
+ DCN20_VMID_REG_LIST(id)\
+}
+
+static const struct dcn_vmid_registers vmid_regs[] = {
+ vmid_regs(0),
+ vmid_regs(1),
+ vmid_regs(2),
+ vmid_regs(3),
+ vmid_regs(4),
+ vmid_regs(5),
+ vmid_regs(6),
+ vmid_regs(7),
+ vmid_regs(8),
+ vmid_regs(9),
+ vmid_regs(10),
+ vmid_regs(11),
+ vmid_regs(12),
+ vmid_regs(13),
+ vmid_regs(14),
+ vmid_regs(15)
+};
+
+static const struct dcn20_vmid_shift vmid_shifts = {
+ DCN20_VMID_MASK_SH_LIST(__SHIFT)
+};
+
+static const struct dcn20_vmid_mask vmid_masks = {
+ DCN20_VMID_MASK_SH_LIST(_MASK)
+};
+
+static const struct resource_caps res_cap_dcn31 = {
+ .num_timing_generator = 4,
+ .num_opp = 4,
+ .num_video_plane = 4,
+ .num_audio = 5,
+ .num_stream_encoder = 5,
+ .num_dig_link_enc = 5,
+ .num_hpo_dp_stream_encoder = 4,
+ .num_hpo_dp_link_encoder = 2,
+ .num_pll = 5,
+ .num_dwb = 1,
+ .num_ddc = 5,
+ .num_vmid = 16,
+ .num_mpc_3dlut = 2,
+ .num_dsc = 3,
+};
+
+static const struct dc_plane_cap plane_cap = {
+ .type = DC_PLANE_TYPE_DCN_UNIVERSAL,
+ .blends_with_above = true,
+ .blends_with_below = true,
+ .per_pixel_alpha = true,
+
+ .pixel_format_support = {
+ .argb8888 = true,
+ .nv12 = true,
+ .fp16 = true,
+ .p010 = true,
+ .ayuv = false,
+ },
+
+ .max_upscale_factor = {
+ .argb8888 = 16000,
+ .nv12 = 16000,
+ .fp16 = 16000
+ },
+
+ // 6:1 downscaling ratio: 1000/6 = 166.666
+ .max_downscale_factor = {
+ .argb8888 = 167,
+ .nv12 = 167,
+ .fp16 = 167
+ },
+ 64,
+ 64
+};
+
+static const struct dc_debug_options debug_defaults_drv = {
+ .disable_z10 = true, /*hw not support it*/
+ .disable_dmcu = true,
+ .force_abm_enable = false,
+ .timing_trace = false,
+ .clock_trace = true,
+ .disable_pplib_clock_request = false,
+ .pipe_split_policy = MPC_SPLIT_DYNAMIC,
+ .force_single_disp_pipe_split = false,
+ .disable_dcc = DCC_ENABLE,
+ .vsr_support = true,
+ .performance_trace = false,
+ .max_downscale_src_width = 4096,/*upto true 4k*/
+ .disable_pplib_wm_range = false,
+ .scl_reset_length10 = true,
+ .sanity_checks = false,
+ .underflow_assert_delay_us = 0xFFFFFFFF,
+ .dwb_fi_phase = -1, // -1 = disable,
+ .dmub_command_table = true,
+ .pstate_enabled = true,
+ .use_max_lb = true,
+ .enable_mem_low_power = {
+ .bits = {
+ .vga = true,
+ .i2c = true,
+ .dmcu = false, // This is previously known to cause hang on S3 cycles if enabled
+ .dscl = true,
+ .cm = true,
+ .mpc = true,
+ .optc = true,
+ .vpg = true,
+ .afmt = true,
+ }
+ },
+ .optimize_edp_link_rate = true,
+ .enable_sw_cntl_psr = true,
+};
+
+static const struct dc_debug_options debug_defaults_diags = {
+ .disable_dmcu = true,
+ .force_abm_enable = false,
+ .timing_trace = true,
+ .clock_trace = true,
+ .disable_dpp_power_gate = true,
+ .disable_hubp_power_gate = true,
+ .disable_clock_gate = true,
+ .disable_pplib_clock_request = true,
+ .disable_pplib_wm_range = true,
+ .disable_stutter = false,
+ .scl_reset_length10 = true,
+ .dwb_fi_phase = -1, // -1 = disable
+ .dmub_command_table = true,
+ .enable_tri_buf = true,
+ .use_max_lb = true
+};
+
+static void dcn31_dpp_destroy(struct dpp **dpp)
+{
+ kfree(TO_DCN20_DPP(*dpp));
+ *dpp = NULL;
+}
+
+static struct dpp *dcn31_dpp_create(
+ struct dc_context *ctx,
+ uint32_t inst)
+{
+ struct dcn3_dpp *dpp =
+ kzalloc(sizeof(struct dcn3_dpp), GFP_KERNEL);
+
+ if (!dpp)
+ return NULL;
+
+ if (dpp3_construct(dpp, ctx, inst,
+ &dpp_regs[inst], &tf_shift, &tf_mask))
+ return &dpp->base;
+
+ BREAK_TO_DEBUGGER();
+ kfree(dpp);
+ return NULL;
+}
+
+static struct output_pixel_processor *dcn31_opp_create(
+ struct dc_context *ctx, uint32_t inst)
+{
+ struct dcn20_opp *opp =
+ kzalloc(sizeof(struct dcn20_opp), GFP_KERNEL);
+
+ if (!opp) {
+ BREAK_TO_DEBUGGER();
+ return NULL;
+ }
+
+ dcn20_opp_construct(opp, ctx, inst,
+ &opp_regs[inst], &opp_shift, &opp_mask);
+ return &opp->base;
+}
+
+static struct dce_aux *dcn31_aux_engine_create(
+ struct dc_context *ctx,
+ uint32_t inst)
+{
+ struct aux_engine_dce110 *aux_engine =
+ kzalloc(sizeof(struct aux_engine_dce110), GFP_KERNEL);
+
+ if (!aux_engine)
+ return NULL;
+
+ dce110_aux_engine_construct(aux_engine, ctx, inst,
+ SW_AUX_TIMEOUT_PERIOD_MULTIPLIER * AUX_TIMEOUT_PERIOD,
+ &aux_engine_regs[inst],
+ &aux_mask,
+ &aux_shift,
+ ctx->dc->caps.extended_aux_timeout_support);
+
+ return &aux_engine->base;
+}
+#define i2c_inst_regs(id) { I2C_HW_ENGINE_COMMON_REG_LIST_DCN30(id) }
+
+static const struct dce_i2c_registers i2c_hw_regs[] = {
+ i2c_inst_regs(1),
+ i2c_inst_regs(2),
+ i2c_inst_regs(3),
+ i2c_inst_regs(4),
+ i2c_inst_regs(5),
+};
+
+static const struct dce_i2c_shift i2c_shifts = {
+ I2C_COMMON_MASK_SH_LIST_DCN30(__SHIFT)
+};
+
+static const struct dce_i2c_mask i2c_masks = {
+ I2C_COMMON_MASK_SH_LIST_DCN30(_MASK)
+};
+
+static struct dce_i2c_hw *dcn31_i2c_hw_create(
+ struct dc_context *ctx,
+ uint32_t inst)
+{
+ struct dce_i2c_hw *dce_i2c_hw =
+ kzalloc(sizeof(struct dce_i2c_hw), GFP_KERNEL);
+
+ if (!dce_i2c_hw)
+ return NULL;
+
+ dcn2_i2c_hw_construct(dce_i2c_hw, ctx, inst,
+ &i2c_hw_regs[inst], &i2c_shifts, &i2c_masks);
+
+ return dce_i2c_hw;
+}
+static struct mpc *dcn31_mpc_create(
+ struct dc_context *ctx,
+ int num_mpcc,
+ int num_rmu)
+{
+ struct dcn30_mpc *mpc30 = kzalloc(sizeof(struct dcn30_mpc),
+ GFP_KERNEL);
+
+ if (!mpc30)
+ return NULL;
+
+ dcn30_mpc_construct(mpc30, ctx,
+ &mpc_regs,
+ &mpc_shift,
+ &mpc_mask,
+ num_mpcc,
+ num_rmu);
+
+ return &mpc30->base;
+}
+
+static struct hubbub *dcn31_hubbub_create(struct dc_context *ctx)
+{
+ int i;
+
+ struct dcn20_hubbub *hubbub3 = kzalloc(sizeof(struct dcn20_hubbub),
+ GFP_KERNEL);
+
+ if (!hubbub3)
+ return NULL;
+
+ hubbub31_construct(hubbub3, ctx,
+ &hubbub_reg,
+ &hubbub_shift,
+ &hubbub_mask,
+ dcn3_16_ip.det_buffer_size_kbytes,
+ dcn3_16_ip.pixel_chunk_size_kbytes,
+ dcn3_16_ip.config_return_buffer_size_in_kbytes);
+
+
+ for (i = 0; i < res_cap_dcn31.num_vmid; i++) {
+ struct dcn20_vmid *vmid = &hubbub3->vmid[i];
+
+ vmid->ctx = ctx;
+
+ vmid->regs = &vmid_regs[i];
+ vmid->shifts = &vmid_shifts;
+ vmid->masks = &vmid_masks;
+ }
+
+ return &hubbub3->base;
+}
+
+static struct timing_generator *dcn31_timing_generator_create(
+ struct dc_context *ctx,
+ uint32_t instance)
+{
+ struct optc *tgn10 =
+ kzalloc(sizeof(struct optc), GFP_KERNEL);
+
+ if (!tgn10)
+ return NULL;
+
+ tgn10->base.inst = instance;
+ tgn10->base.ctx = ctx;
+
+ tgn10->tg_regs = &optc_regs[instance];
+ tgn10->tg_shift = &optc_shift;
+ tgn10->tg_mask = &optc_mask;
+
+ dcn31_timing_generator_init(tgn10);
+
+ return &tgn10->base;
+}
+
+static const struct encoder_feature_support link_enc_feature = {
+ .max_hdmi_deep_color = COLOR_DEPTH_121212,
+ .max_hdmi_pixel_clock = 600000,
+ .hdmi_ycbcr420_supported = true,
+ .dp_ycbcr420_supported = true,
+ .fec_supported = true,
+ .flags.bits.IS_HBR2_CAPABLE = true,
+ .flags.bits.IS_HBR3_CAPABLE = true,
+ .flags.bits.IS_TPS3_CAPABLE = true,
+ .flags.bits.IS_TPS4_CAPABLE = true
+};
+
+static struct link_encoder *dcn31_link_encoder_create(
+ const struct encoder_init_data *enc_init_data)
+{
+ struct dcn20_link_encoder *enc20 =
+ kzalloc(sizeof(struct dcn20_link_encoder), GFP_KERNEL);
+
+ if (!enc20)
+ return NULL;
+
+ dcn31_link_encoder_construct(enc20,
+ enc_init_data,
+ &link_enc_feature,
+ &link_enc_regs[enc_init_data->transmitter],
+ &link_enc_aux_regs[enc_init_data->channel - 1],
+ &link_enc_hpd_regs[enc_init_data->hpd_source],
+ &le_shift,
+ &le_mask);
+
+ return &enc20->enc10.base;
+}
+
+/* Create a minimal link encoder object not associated with a particular
+ * physical connector.
+ * resource_funcs.link_enc_create_minimal
+ */
+static struct link_encoder *dcn31_link_enc_create_minimal(
+ struct dc_context *ctx, enum engine_id eng_id)
+{
+ struct dcn20_link_encoder *enc20;
+
+ if ((eng_id - ENGINE_ID_DIGA) > ctx->dc->res_pool->res_cap->num_dig_link_enc)
+ return NULL;
+
+ enc20 = kzalloc(sizeof(struct dcn20_link_encoder), GFP_KERNEL);
+ if (!enc20)
+ return NULL;
+
+ dcn31_link_encoder_construct_minimal(
+ enc20,
+ ctx,
+ &link_enc_feature,
+ &link_enc_regs[eng_id - ENGINE_ID_DIGA],
+ eng_id);
+
+ return &enc20->enc10.base;
+}
+
+static struct panel_cntl *dcn31_panel_cntl_create(const struct panel_cntl_init_data *init_data)
+{
+ struct dcn31_panel_cntl *panel_cntl =
+ kzalloc(sizeof(struct dcn31_panel_cntl), GFP_KERNEL);
+
+ if (!panel_cntl)
+ return NULL;
+
+ dcn31_panel_cntl_construct(panel_cntl, init_data);
+
+ return &panel_cntl->base;
+}
+
+static void read_dce_straps(
+ struct dc_context *ctx,
+ struct resource_straps *straps)
+{
+ generic_reg_get(ctx, regDC_PINSTRAPS + BASE(regDC_PINSTRAPS_BASE_IDX),
+ FN(DC_PINSTRAPS, DC_PINSTRAPS_AUDIO), &straps->dc_pinstraps_audio);
+
+}
+
+static struct audio *dcn31_create_audio(
+ struct dc_context *ctx, unsigned int inst)
+{
+ return dce_audio_create(ctx, inst,
+ &audio_regs[inst], &audio_shift, &audio_mask);
+}
+
+static struct vpg *dcn31_vpg_create(
+ struct dc_context *ctx,
+ uint32_t inst)
+{
+ struct dcn31_vpg *vpg31 = kzalloc(sizeof(struct dcn31_vpg), GFP_KERNEL);
+
+ if (!vpg31)
+ return NULL;
+
+ vpg31_construct(vpg31, ctx, inst,
+ &vpg_regs[inst],
+ &vpg_shift,
+ &vpg_mask);
+
+ return &vpg31->base;
+}
+
+static struct afmt *dcn31_afmt_create(
+ struct dc_context *ctx,
+ uint32_t inst)
+{
+ struct dcn31_afmt *afmt31 = kzalloc(sizeof(struct dcn31_afmt), GFP_KERNEL);
+
+ if (!afmt31)
+ return NULL;
+
+ afmt31_construct(afmt31, ctx, inst,
+ &afmt_regs[inst],
+ &afmt_shift,
+ &afmt_mask);
+
+ // Light sleep by default, no need to power down here
+
+ return &afmt31->base;
+}
+
+
+static struct apg *dcn31_apg_create(
+ struct dc_context *ctx,
+ uint32_t inst)
+{
+ struct dcn31_apg *apg31 = kzalloc(sizeof(struct dcn31_apg), GFP_KERNEL);
+
+ if (!apg31)
+ return NULL;
+
+ apg31_construct(apg31, ctx, inst,
+ &apg_regs[inst],
+ &apg_shift,
+ &apg_mask);
+
+ return &apg31->base;
+}
+
+
+static struct stream_encoder *dcn316_stream_encoder_create(
+ enum engine_id eng_id,
+ struct dc_context *ctx)
+{
+ struct dcn10_stream_encoder *enc1;
+ struct vpg *vpg;
+ struct afmt *afmt;
+ int vpg_inst;
+ int afmt_inst;
+
+ /* Mapping of VPG, AFMT, DME register blocks to DIO block instance */
+ if (eng_id <= ENGINE_ID_DIGF) {
+ vpg_inst = eng_id;
+ afmt_inst = eng_id;
+ } else
+ return NULL;
+
+ enc1 = kzalloc(sizeof(struct dcn10_stream_encoder), GFP_KERNEL);
+ vpg = dcn31_vpg_create(ctx, vpg_inst);
+ afmt = dcn31_afmt_create(ctx, afmt_inst);
+
+ if (!enc1 || !vpg || !afmt) {
+ kfree(enc1);
+ kfree(vpg);
+ kfree(afmt);
+ return NULL;
+ }
+
+ dcn30_dio_stream_encoder_construct(enc1, ctx, ctx->dc_bios,
+ eng_id, vpg, afmt,
+ &stream_enc_regs[eng_id],
+ &se_shift, &se_mask);
+
+ return &enc1->base;
+}
+
+
+static struct hpo_dp_stream_encoder *dcn31_hpo_dp_stream_encoder_create(
+ enum engine_id eng_id,
+ struct dc_context *ctx)
+{
+ struct dcn31_hpo_dp_stream_encoder *hpo_dp_enc31;
+ struct vpg *vpg;
+ struct apg *apg;
+ uint32_t hpo_dp_inst;
+ uint32_t vpg_inst;
+ uint32_t apg_inst;
+
+ ASSERT((eng_id >= ENGINE_ID_HPO_DP_0) && (eng_id <= ENGINE_ID_HPO_DP_3));
+ hpo_dp_inst = eng_id - ENGINE_ID_HPO_DP_0;
+
+ /* Mapping of VPG register blocks to HPO DP block instance:
+ * VPG[6] -> HPO_DP[0]
+ * VPG[7] -> HPO_DP[1]
+ * VPG[8] -> HPO_DP[2]
+ * VPG[9] -> HPO_DP[3]
+ */
+ vpg_inst = hpo_dp_inst + 6;
+
+ /* Mapping of APG register blocks to HPO DP block instance:
+ * APG[0] -> HPO_DP[0]
+ * APG[1] -> HPO_DP[1]
+ * APG[2] -> HPO_DP[2]
+ * APG[3] -> HPO_DP[3]
+ */
+ apg_inst = hpo_dp_inst;
+
+ /* allocate HPO stream encoder and create VPG sub-block */
+ hpo_dp_enc31 = kzalloc(sizeof(struct dcn31_hpo_dp_stream_encoder), GFP_KERNEL);
+ vpg = dcn31_vpg_create(ctx, vpg_inst);
+ apg = dcn31_apg_create(ctx, apg_inst);
+
+ if (!hpo_dp_enc31 || !vpg || !apg) {
+ kfree(hpo_dp_enc31);
+ kfree(vpg);
+ kfree(apg);
+ return NULL;
+ }
+
+ dcn31_hpo_dp_stream_encoder_construct(hpo_dp_enc31, ctx, ctx->dc_bios,
+ hpo_dp_inst, eng_id, vpg, apg,
+ &hpo_dp_stream_enc_regs[hpo_dp_inst],
+ &hpo_dp_se_shift, &hpo_dp_se_mask);
+
+ return &hpo_dp_enc31->base;
+}
+
+static struct hpo_dp_link_encoder *dcn31_hpo_dp_link_encoder_create(
+ uint8_t inst,
+ struct dc_context *ctx)
+{
+ struct dcn31_hpo_dp_link_encoder *hpo_dp_enc31;
+
+ /* allocate HPO link encoder */
+ hpo_dp_enc31 = kzalloc(sizeof(struct dcn31_hpo_dp_link_encoder), GFP_KERNEL);
+
+ hpo_dp_link_encoder31_construct(hpo_dp_enc31, ctx, inst,
+ &hpo_dp_link_enc_regs[inst],
+ &hpo_dp_le_shift, &hpo_dp_le_mask);
+
+ return &hpo_dp_enc31->base;
+}
+
+
+static struct dce_hwseq *dcn31_hwseq_create(
+ struct dc_context *ctx)
+{
+ struct dce_hwseq *hws = kzalloc(sizeof(struct dce_hwseq), GFP_KERNEL);
+
+ if (hws) {
+ hws->ctx = ctx;
+ hws->regs = &hwseq_reg;
+ hws->shifts = &hwseq_shift;
+ hws->masks = &hwseq_mask;
+ /* DCN3.1 FPGA Workaround
+ * Need to enable HPO DP Stream Encoder before setting OTG master enable.
+ * To do so, move calling function enable_stream_timing to only be done AFTER calling
+ * function core_link_enable_stream
+ */
+ if (IS_FPGA_MAXIMUS_DC(ctx->dce_environment))
+ hws->wa.dp_hpo_and_otg_sequence = true;
+ }
+ return hws;
+}
+static const struct resource_create_funcs res_create_funcs = {
+ .read_dce_straps = read_dce_straps,
+ .create_audio = dcn31_create_audio,
+ .create_stream_encoder = dcn316_stream_encoder_create,
+ .create_hpo_dp_stream_encoder = dcn31_hpo_dp_stream_encoder_create,
+ .create_hpo_dp_link_encoder = dcn31_hpo_dp_link_encoder_create,
+ .create_hwseq = dcn31_hwseq_create,
+};
+
+static const struct resource_create_funcs res_create_maximus_funcs = {
+ .read_dce_straps = NULL,
+ .create_audio = NULL,
+ .create_stream_encoder = NULL,
+ .create_hpo_dp_stream_encoder = dcn31_hpo_dp_stream_encoder_create,
+ .create_hpo_dp_link_encoder = dcn31_hpo_dp_link_encoder_create,
+ .create_hwseq = dcn31_hwseq_create,
+};
+
+static void dcn316_resource_destruct(struct dcn316_resource_pool *pool)
+{
+ unsigned int i;
+
+ for (i = 0; i < pool->base.stream_enc_count; i++) {
+ if (pool->base.stream_enc[i] != NULL) {
+ if (pool->base.stream_enc[i]->vpg != NULL) {
+ kfree(DCN30_VPG_FROM_VPG(pool->base.stream_enc[i]->vpg));
+ pool->base.stream_enc[i]->vpg = NULL;
+ }
+ if (pool->base.stream_enc[i]->afmt != NULL) {
+ kfree(DCN30_AFMT_FROM_AFMT(pool->base.stream_enc[i]->afmt));
+ pool->base.stream_enc[i]->afmt = NULL;
+ }
+ kfree(DCN10STRENC_FROM_STRENC(pool->base.stream_enc[i]));
+ pool->base.stream_enc[i] = NULL;
+ }
+ }
+
+ for (i = 0; i < pool->base.hpo_dp_stream_enc_count; i++) {
+ if (pool->base.hpo_dp_stream_enc[i] != NULL) {
+ if (pool->base.hpo_dp_stream_enc[i]->vpg != NULL) {
+ kfree(DCN30_VPG_FROM_VPG(pool->base.hpo_dp_stream_enc[i]->vpg));
+ pool->base.hpo_dp_stream_enc[i]->vpg = NULL;
+ }
+ if (pool->base.hpo_dp_stream_enc[i]->apg != NULL) {
+ kfree(DCN31_APG_FROM_APG(pool->base.hpo_dp_stream_enc[i]->apg));
+ pool->base.hpo_dp_stream_enc[i]->apg = NULL;
+ }
+ kfree(DCN3_1_HPO_DP_STREAM_ENC_FROM_HPO_STREAM_ENC(pool->base.hpo_dp_stream_enc[i]));
+ pool->base.hpo_dp_stream_enc[i] = NULL;
+ }
+ }
+
+ for (i = 0; i < pool->base.hpo_dp_link_enc_count; i++) {
+ if (pool->base.hpo_dp_link_enc[i] != NULL) {
+ kfree(DCN3_1_HPO_DP_LINK_ENC_FROM_HPO_LINK_ENC(pool->base.hpo_dp_link_enc[i]));
+ pool->base.hpo_dp_link_enc[i] = NULL;
+ }
+ }
+
+ for (i = 0; i < pool->base.res_cap->num_dsc; i++) {
+ if (pool->base.dscs[i] != NULL)
+ dcn20_dsc_destroy(&pool->base.dscs[i]);
+ }
+
+ if (pool->base.mpc != NULL) {
+ kfree(TO_DCN20_MPC(pool->base.mpc));
+ pool->base.mpc = NULL;
+ }
+ if (pool->base.hubbub != NULL) {
+ kfree(pool->base.hubbub);
+ pool->base.hubbub = NULL;
+ }
+ for (i = 0; i < pool->base.pipe_count; i++) {
+ if (pool->base.dpps[i] != NULL)
+ dcn31_dpp_destroy(&pool->base.dpps[i]);
+
+ if (pool->base.ipps[i] != NULL)
+ pool->base.ipps[i]->funcs->ipp_destroy(&pool->base.ipps[i]);
+
+ if (pool->base.hubps[i] != NULL) {
+ kfree(TO_DCN20_HUBP(pool->base.hubps[i]));
+ pool->base.hubps[i] = NULL;
+ }
+
+ if (pool->base.irqs != NULL) {
+ dal_irq_service_destroy(&pool->base.irqs);
+ }
+ }
+
+ for (i = 0; i < pool->base.res_cap->num_ddc; i++) {
+ if (pool->base.engines[i] != NULL)
+ dce110_engine_destroy(&pool->base.engines[i]);
+ if (pool->base.hw_i2cs[i] != NULL) {
+ kfree(pool->base.hw_i2cs[i]);
+ pool->base.hw_i2cs[i] = NULL;
+ }
+ if (pool->base.sw_i2cs[i] != NULL) {
+ kfree(pool->base.sw_i2cs[i]);
+ pool->base.sw_i2cs[i] = NULL;
+ }
+ }
+
+ for (i = 0; i < pool->base.res_cap->num_opp; i++) {
+ if (pool->base.opps[i] != NULL)
+ pool->base.opps[i]->funcs->opp_destroy(&pool->base.opps[i]);
+ }
+
+ for (i = 0; i < pool->base.res_cap->num_timing_generator; i++) {
+ if (pool->base.timing_generators[i] != NULL) {
+ kfree(DCN10TG_FROM_TG(pool->base.timing_generators[i]));
+ pool->base.timing_generators[i] = NULL;
+ }
+ }
+
+ for (i = 0; i < pool->base.res_cap->num_dwb; i++) {
+ if (pool->base.dwbc[i] != NULL) {
+ kfree(TO_DCN30_DWBC(pool->base.dwbc[i]));
+ pool->base.dwbc[i] = NULL;
+ }
+ if (pool->base.mcif_wb[i] != NULL) {
+ kfree(TO_DCN30_MMHUBBUB(pool->base.mcif_wb[i]));
+ pool->base.mcif_wb[i] = NULL;
+ }
+ }
+
+ for (i = 0; i < pool->base.audio_count; i++) {
+ if (pool->base.audios[i])
+ dce_aud_destroy(&pool->base.audios[i]);
+ }
+
+ for (i = 0; i < pool->base.clk_src_count; i++) {
+ if (pool->base.clock_sources[i] != NULL) {
+ dcn20_clock_source_destroy(&pool->base.clock_sources[i]);
+ pool->base.clock_sources[i] = NULL;
+ }
+ }
+
+ for (i = 0; i < pool->base.res_cap->num_mpc_3dlut; i++) {
+ if (pool->base.mpc_lut[i] != NULL) {
+ dc_3dlut_func_release(pool->base.mpc_lut[i]);
+ pool->base.mpc_lut[i] = NULL;
+ }
+ if (pool->base.mpc_shaper[i] != NULL) {
+ dc_transfer_func_release(pool->base.mpc_shaper[i]);
+ pool->base.mpc_shaper[i] = NULL;
+ }
+ }
+
+ if (pool->base.dp_clock_source != NULL) {
+ dcn20_clock_source_destroy(&pool->base.dp_clock_source);
+ pool->base.dp_clock_source = NULL;
+ }
+
+ for (i = 0; i < pool->base.res_cap->num_timing_generator; i++) {
+ if (pool->base.multiple_abms[i] != NULL)
+ dce_abm_destroy(&pool->base.multiple_abms[i]);
+ }
+
+ if (pool->base.psr != NULL)
+ dmub_psr_destroy(&pool->base.psr);
+
+ if (pool->base.dccg != NULL)
+ dcn_dccg_destroy(&pool->base.dccg);
+}
+
+static struct hubp *dcn31_hubp_create(
+ struct dc_context *ctx,
+ uint32_t inst)
+{
+ struct dcn20_hubp *hubp2 =
+ kzalloc(sizeof(struct dcn20_hubp), GFP_KERNEL);
+
+ if (!hubp2)
+ return NULL;
+
+ if (hubp31_construct(hubp2, ctx, inst,
+ &hubp_regs[inst], &hubp_shift, &hubp_mask))
+ return &hubp2->base;
+
+ BREAK_TO_DEBUGGER();
+ kfree(hubp2);
+ return NULL;
+}
+
+static bool dcn31_dwbc_create(struct dc_context *ctx, struct resource_pool *pool)
+{
+ int i;
+ uint32_t pipe_count = pool->res_cap->num_dwb;
+
+ for (i = 0; i < pipe_count; i++) {
+ struct dcn30_dwbc *dwbc30 = kzalloc(sizeof(struct dcn30_dwbc),
+ GFP_KERNEL);
+
+ if (!dwbc30) {
+ dm_error("DC: failed to create dwbc30!\n");
+ return false;
+ }
+
+ dcn30_dwbc_construct(dwbc30, ctx,
+ &dwbc30_regs[i],
+ &dwbc30_shift,
+ &dwbc30_mask,
+ i);
+
+ pool->dwbc[i] = &dwbc30->base;
+ }
+ return true;
+}
+
+static bool dcn31_mmhubbub_create(struct dc_context *ctx, struct resource_pool *pool)
+{
+ int i;
+ uint32_t pipe_count = pool->res_cap->num_dwb;
+
+ for (i = 0; i < pipe_count; i++) {
+ struct dcn30_mmhubbub *mcif_wb30 = kzalloc(sizeof(struct dcn30_mmhubbub),
+ GFP_KERNEL);
+
+ if (!mcif_wb30) {
+ dm_error("DC: failed to create mcif_wb30!\n");
+ return false;
+ }
+
+ dcn30_mmhubbub_construct(mcif_wb30, ctx,
+ &mcif_wb30_regs[i],
+ &mcif_wb30_shift,
+ &mcif_wb30_mask,
+ i);
+
+ pool->mcif_wb[i] = &mcif_wb30->base;
+ }
+ return true;
+}
+
+static struct display_stream_compressor *dcn31_dsc_create(
+ struct dc_context *ctx, uint32_t inst)
+{
+ struct dcn20_dsc *dsc =
+ kzalloc(sizeof(struct dcn20_dsc), GFP_KERNEL);
+
+ if (!dsc) {
+ BREAK_TO_DEBUGGER();
+ return NULL;
+ }
+
+ dsc2_construct(dsc, ctx, inst, &dsc_regs[inst], &dsc_shift, &dsc_mask);
+ return &dsc->base;
+}
+
+static void dcn316_destroy_resource_pool(struct resource_pool **pool)
+{
+ struct dcn316_resource_pool *dcn31_pool = TO_DCN316_RES_POOL(*pool);
+
+ dcn316_resource_destruct(dcn31_pool);
+ kfree(dcn31_pool);
+ *pool = NULL;
+}
+
+static struct clock_source *dcn31_clock_source_create(
+ struct dc_context *ctx,
+ struct dc_bios *bios,
+ enum clock_source_id id,
+ const struct dce110_clk_src_regs *regs,
+ bool dp_clk_src)
+{
+ struct dce110_clk_src *clk_src =
+ kzalloc(sizeof(struct dce110_clk_src), GFP_KERNEL);
+
+ if (!clk_src)
+ return NULL;
+
+ if (dcn31_clk_src_construct(clk_src, ctx, bios, id,
+ regs, &cs_shift, &cs_mask)) {
+ clk_src->base.dp_clk_src = dp_clk_src;
+ return &clk_src->base;
+ }
+
+ kfree(clk_src);
+
+ BREAK_TO_DEBUGGER();
+ return NULL;
+}
+
+static bool is_dual_plane(enum surface_pixel_format format)
+{
+ return format >= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN || format == SURFACE_PIXEL_FORMAT_GRPH_RGBE_ALPHA;
+}
+
+static int dcn316_populate_dml_pipes_from_context(
+ struct dc *dc, struct dc_state *context,
+ display_e2e_pipe_params_st *pipes,
+ bool fast_validate)
+{
+ int i, pipe_cnt;
+ struct resource_context *res_ctx = &context->res_ctx;
+ struct pipe_ctx *pipe;
+ const int max_usable_det = context->bw_ctx.dml.ip.config_return_buffer_size_in_kbytes - DCN3_16_MIN_COMPBUF_SIZE_KB;
+
+ DC_FP_START();
+ dcn20_populate_dml_pipes_from_context(dc, context, pipes, fast_validate);
+ DC_FP_END();
+
+ for (i = 0, pipe_cnt = 0; i < dc->res_pool->pipe_count; i++) {
+ struct dc_crtc_timing *timing;
+
+ if (!res_ctx->pipe_ctx[i].stream)
+ continue;
+ pipe = &res_ctx->pipe_ctx[i];
+ timing = &pipe->stream->timing;
+
+ /*
+ * Immediate flip can be set dynamically after enabling the plane.
+ * We need to require support for immediate flip or underflow can be
+ * intermittently experienced depending on peak b/w requirements.
+ */
+ pipes[pipe_cnt].pipe.src.immediate_flip = true;
+
+ pipes[pipe_cnt].pipe.src.unbounded_req_mode = false;
+ pipes[pipe_cnt].pipe.src.gpuvm = true;
+ pipes[pipe_cnt].pipe.src.dcc_fraction_of_zs_req_luma = 0;
+ pipes[pipe_cnt].pipe.src.dcc_fraction_of_zs_req_chroma = 0;
+ pipes[pipe_cnt].pipe.dest.vfront_porch = timing->v_front_porch;
+ pipes[pipe_cnt].pipe.src.dcc_rate = 3;
+ pipes[pipe_cnt].dout.dsc_input_bpc = 0;
+
+ if (pipes[pipe_cnt].dout.dsc_enable) {
+ switch (timing->display_color_depth) {
+ case COLOR_DEPTH_888:
+ pipes[pipe_cnt].dout.dsc_input_bpc = 8;
+ break;
+ case COLOR_DEPTH_101010:
+ pipes[pipe_cnt].dout.dsc_input_bpc = 10;
+ break;
+ case COLOR_DEPTH_121212:
+ pipes[pipe_cnt].dout.dsc_input_bpc = 12;
+ break;
+ default:
+ ASSERT(0);
+ break;
+ }
+ }
+
+ pipe_cnt++;
+ }
+
+ if (pipe_cnt)
+ context->bw_ctx.dml.ip.det_buffer_size_kbytes =
+ (max_usable_det / DCN3_16_CRB_SEGMENT_SIZE_KB / pipe_cnt) * DCN3_16_CRB_SEGMENT_SIZE_KB;
+ if (context->bw_ctx.dml.ip.det_buffer_size_kbytes > DCN3_16_MAX_DET_SIZE)
+ context->bw_ctx.dml.ip.det_buffer_size_kbytes = DCN3_16_MAX_DET_SIZE;
+ ASSERT(context->bw_ctx.dml.ip.det_buffer_size_kbytes >= DCN3_16_DEFAULT_DET_SIZE);
+ dc->config.enable_4to1MPC = false;
+ if (pipe_cnt == 1 && pipe->plane_state && !dc->debug.disable_z9_mpc) {
+ if (is_dual_plane(pipe->plane_state->format)
+ && pipe->plane_state->src_rect.width <= 1920 && pipe->plane_state->src_rect.height <= 1080) {
+ dc->config.enable_4to1MPC = true;
+ context->bw_ctx.dml.ip.det_buffer_size_kbytes =
+ (max_usable_det / DCN3_16_CRB_SEGMENT_SIZE_KB / 4) * DCN3_16_CRB_SEGMENT_SIZE_KB;
+ } else if (!is_dual_plane(pipe->plane_state->format)) {
+ context->bw_ctx.dml.ip.det_buffer_size_kbytes = 192;
+ pipes[0].pipe.src.unbounded_req_mode = true;
+ }
+ }
+
+ return pipe_cnt;
+}
+
+static struct dc_cap_funcs cap_funcs = {
+ .get_dcc_compression_cap = dcn20_get_dcc_compression_cap
+};
+
+static void dcn316_update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_params)
+{
+ struct clk_limit_table *clk_table = &bw_params->clk_table;
+ struct _vcs_dpi_voltage_scaling_st clock_limits[DC__VOLTAGE_STATES];
+ unsigned int i, closest_clk_lvl;
+ int max_dispclk_mhz = 0, max_dppclk_mhz = 0;
+ int j;
+
+ // Default clock levels are used for diags, which may lead to overclocking.
+ if (!IS_DIAG_DC(dc->ctx->dce_environment)) {
+
+ dcn3_16_ip.max_num_otg = dc->res_pool->res_cap->num_timing_generator;
+ dcn3_16_ip.max_num_dpp = dc->res_pool->pipe_count;
+ dcn3_16_soc.num_chans = bw_params->num_channels;
+
+ ASSERT(clk_table->num_entries);
+
+ /* Prepass to find max clocks independent of voltage level. */
+ for (i = 0; i < clk_table->num_entries; ++i) {
+ if (clk_table->entries[i].dispclk_mhz > max_dispclk_mhz)
+ max_dispclk_mhz = clk_table->entries[i].dispclk_mhz;
+ if (clk_table->entries[i].dppclk_mhz > max_dppclk_mhz)
+ max_dppclk_mhz = clk_table->entries[i].dppclk_mhz;
+ }
+
+ for (i = 0; i < clk_table->num_entries; i++) {
+ /* loop backwards*/
+ for (closest_clk_lvl = 0, j = dcn3_16_soc.num_states - 1; j >= 0; j--) {
+ if ((unsigned int) dcn3_16_soc.clock_limits[j].dcfclk_mhz <= clk_table->entries[i].dcfclk_mhz) {
+ closest_clk_lvl = j;
+ break;
+ }
+ }
+ // Ported from DCN315
+ if (clk_table->num_entries == 1) {
+ /*smu gives one DPM level, let's take the highest one*/
+ closest_clk_lvl = dcn3_16_soc.num_states - 1;
+ }
+
+ clock_limits[i].state = i;
+
+ /* Clocks dependent on voltage level. */
+ clock_limits[i].dcfclk_mhz = clk_table->entries[i].dcfclk_mhz;
+ if (clk_table->num_entries == 1 &&
+ clock_limits[i].dcfclk_mhz < dcn3_16_soc.clock_limits[closest_clk_lvl].dcfclk_mhz) {
+ /*SMU fix not released yet*/
+ clock_limits[i].dcfclk_mhz = dcn3_16_soc.clock_limits[closest_clk_lvl].dcfclk_mhz;
+ }
+ clock_limits[i].fabricclk_mhz = clk_table->entries[i].fclk_mhz;
+ clock_limits[i].socclk_mhz = clk_table->entries[i].socclk_mhz;
+ clock_limits[i].dram_speed_mts = clk_table->entries[i].memclk_mhz * 2 * clk_table->entries[i].wck_ratio;
+
+ /* Clocks independent of voltage level. */
+ clock_limits[i].dispclk_mhz = max_dispclk_mhz ? max_dispclk_mhz :
+ dcn3_16_soc.clock_limits[closest_clk_lvl].dispclk_mhz;
+
+ clock_limits[i].dppclk_mhz = max_dppclk_mhz ? max_dppclk_mhz :
+ dcn3_16_soc.clock_limits[closest_clk_lvl].dppclk_mhz;
+
+ clock_limits[i].dram_bw_per_chan_gbps = dcn3_16_soc.clock_limits[closest_clk_lvl].dram_bw_per_chan_gbps;
+ clock_limits[i].dscclk_mhz = dcn3_16_soc.clock_limits[closest_clk_lvl].dscclk_mhz;
+ clock_limits[i].dtbclk_mhz = dcn3_16_soc.clock_limits[closest_clk_lvl].dtbclk_mhz;
+ clock_limits[i].phyclk_d18_mhz = dcn3_16_soc.clock_limits[closest_clk_lvl].phyclk_d18_mhz;
+ clock_limits[i].phyclk_mhz = dcn3_16_soc.clock_limits[closest_clk_lvl].phyclk_mhz;
+ }
+ for (i = 0; i < clk_table->num_entries; i++)
+ dcn3_16_soc.clock_limits[i] = clock_limits[i];
+ if (clk_table->num_entries) {
+ dcn3_16_soc.num_states = clk_table->num_entries;
+ }
+ }
+
+ if (max_dispclk_mhz) {
+ dcn3_16_soc.dispclk_dppclk_vco_speed_mhz = max_dispclk_mhz * 2;
+ dc->dml.soc.dispclk_dppclk_vco_speed_mhz = max_dispclk_mhz * 2;
+ }
+
+ if (!IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment))
+ dml_init_instance(&dc->dml, &dcn3_16_soc, &dcn3_16_ip, DML_PROJECT_DCN31);
+ else
+ dml_init_instance(&dc->dml, &dcn3_16_soc, &dcn3_16_ip, DML_PROJECT_DCN31_FPGA);
+}
+
+static struct resource_funcs dcn316_res_pool_funcs = {
+ .destroy = dcn316_destroy_resource_pool,
+ .link_enc_create = dcn31_link_encoder_create,
+ .link_enc_create_minimal = dcn31_link_enc_create_minimal,
+ .link_encs_assign = link_enc_cfg_link_encs_assign,
+ .link_enc_unassign = link_enc_cfg_link_enc_unassign,
+ .panel_cntl_create = dcn31_panel_cntl_create,
+ .validate_bandwidth = dcn31_validate_bandwidth,
+ .calculate_wm_and_dlg = dcn31_calculate_wm_and_dlg,
+ .update_soc_for_wm_a = dcn31_update_soc_for_wm_a,
+ .populate_dml_pipes = dcn316_populate_dml_pipes_from_context,
+ .acquire_idle_pipe_for_layer = dcn20_acquire_idle_pipe_for_layer,
+ .add_stream_to_ctx = dcn30_add_stream_to_ctx,
+ .add_dsc_to_stream_resource = dcn20_add_dsc_to_stream_resource,
+ .remove_stream_from_ctx = dcn20_remove_stream_from_ctx,
+ .populate_dml_writeback_from_context = dcn30_populate_dml_writeback_from_context,
+ .set_mcif_arb_params = dcn30_set_mcif_arb_params,
+ .find_first_free_match_stream_enc_for_link = dcn10_find_first_free_match_stream_enc_for_link,
+ .acquire_post_bldn_3dlut = dcn30_acquire_post_bldn_3dlut,
+ .release_post_bldn_3dlut = dcn30_release_post_bldn_3dlut,
+ .update_bw_bounding_box = dcn316_update_bw_bounding_box,
+ .patch_unknown_plane_state = dcn20_patch_unknown_plane_state,
+};
+
+static bool dcn316_resource_construct(
+ uint8_t num_virtual_links,
+ struct dc *dc,
+ struct dcn316_resource_pool *pool)
+{
+ int i;
+ struct dc_context *ctx = dc->ctx;
+ struct irq_service_init_data init_data;
+
+ ctx->dc_bios->regs = &bios_regs;
+
+ pool->base.res_cap = &res_cap_dcn31;
+
+ pool->base.funcs = &dcn316_res_pool_funcs;
+
+ /*************************************************
+ * Resource + asic cap harcoding *
+ *************************************************/
+ pool->base.underlay_pipe_index = NO_UNDERLAY_PIPE;
+ pool->base.pipe_count = pool->base.res_cap->num_timing_generator;
+ pool->base.mpcc_count = pool->base.res_cap->num_timing_generator;
+ dc->caps.max_downscale_ratio = 600;
+ dc->caps.i2c_speed_in_khz = 100;
+ dc->caps.i2c_speed_in_khz_hdcp = 5; /*1.4 w/a applied by default*/
+ dc->caps.max_cursor_size = 256;
+ dc->caps.min_horizontal_blanking_period = 80;
+ dc->caps.dmdata_alloc_size = 2048;
+
+ dc->caps.max_slave_planes = 1;
+ dc->caps.max_slave_yuv_planes = 1;
+ dc->caps.max_slave_rgb_planes = 1;
+ dc->caps.post_blend_color_processing = true;
+ dc->caps.force_dp_tps4_for_cp2520 = true;
+ dc->caps.dp_hpo = true;
+ dc->caps.edp_dsc_support = true;
+ dc->caps.extended_aux_timeout_support = true;
+ dc->caps.dmcub_support = true;
+ dc->caps.is_apu = true;
+
+ /* Color pipeline capabilities */
+ dc->caps.color.dpp.dcn_arch = 1;
+ dc->caps.color.dpp.input_lut_shared = 0;
+ dc->caps.color.dpp.icsc = 1;
+ dc->caps.color.dpp.dgam_ram = 0; // must use gamma_corr
+ dc->caps.color.dpp.dgam_rom_caps.srgb = 1;
+ dc->caps.color.dpp.dgam_rom_caps.bt2020 = 1;
+ dc->caps.color.dpp.dgam_rom_caps.gamma2_2 = 1;
+ dc->caps.color.dpp.dgam_rom_caps.pq = 1;
+ dc->caps.color.dpp.dgam_rom_caps.hlg = 1;
+ dc->caps.color.dpp.post_csc = 1;
+ dc->caps.color.dpp.gamma_corr = 1;
+ dc->caps.color.dpp.dgam_rom_for_yuv = 0;
+
+ dc->caps.color.dpp.hw_3d_lut = 1;
+ dc->caps.color.dpp.ogam_ram = 1;
+ // no OGAM ROM on DCN301
+ dc->caps.color.dpp.ogam_rom_caps.srgb = 0;
+ dc->caps.color.dpp.ogam_rom_caps.bt2020 = 0;
+ dc->caps.color.dpp.ogam_rom_caps.gamma2_2 = 0;
+ dc->caps.color.dpp.ogam_rom_caps.pq = 0;
+ dc->caps.color.dpp.ogam_rom_caps.hlg = 0;
+ dc->caps.color.dpp.ocsc = 0;
+
+ dc->caps.color.mpc.gamut_remap = 1;
+ dc->caps.color.mpc.num_3dluts = pool->base.res_cap->num_mpc_3dlut; //2
+ dc->caps.color.mpc.ogam_ram = 1;
+ dc->caps.color.mpc.ogam_rom_caps.srgb = 0;
+ dc->caps.color.mpc.ogam_rom_caps.bt2020 = 0;
+ dc->caps.color.mpc.ogam_rom_caps.gamma2_2 = 0;
+ dc->caps.color.mpc.ogam_rom_caps.pq = 0;
+ dc->caps.color.mpc.ogam_rom_caps.hlg = 0;
+ dc->caps.color.mpc.ocsc = 1;
+
+ /* read VBIOS LTTPR caps */
+ {
+ if (ctx->dc_bios->funcs->get_lttpr_caps) {
+ enum bp_result bp_query_result;
+ uint8_t is_vbios_lttpr_enable = 0;
+
+ bp_query_result = ctx->dc_bios->funcs->get_lttpr_caps(ctx->dc_bios, &is_vbios_lttpr_enable);
+ dc->caps.vbios_lttpr_enable = (bp_query_result == BP_RESULT_OK) && !!is_vbios_lttpr_enable;
+ }
+
+ /* interop bit is implicit */
+ {
+ dc->caps.vbios_lttpr_aware = true;
+ }
+ }
+
+ if (dc->ctx->dce_environment == DCE_ENV_PRODUCTION_DRV)
+ dc->debug = debug_defaults_drv;
+ else if (dc->ctx->dce_environment == DCE_ENV_FPGA_MAXIMUS) {
+ dc->debug = debug_defaults_diags;
+ } else
+ dc->debug = debug_defaults_diags;
+ // Init the vm_helper
+ if (dc->vm_helper)
+ vm_helper_init(dc->vm_helper, 16);
+
+ /*************************************************
+ * Create resources *
+ *************************************************/
+
+ /* Clock Sources for Pixel Clock*/
+ pool->base.clock_sources[DCN31_CLK_SRC_PLL0] =
+ dcn31_clock_source_create(ctx, ctx->dc_bios,
+ CLOCK_SOURCE_COMBO_PHY_PLL0,
+ &clk_src_regs[0], false);
+ pool->base.clock_sources[DCN31_CLK_SRC_PLL1] =
+ dcn31_clock_source_create(ctx, ctx->dc_bios,
+ CLOCK_SOURCE_COMBO_PHY_PLL1,
+ &clk_src_regs[1], false);
+ pool->base.clock_sources[DCN31_CLK_SRC_PLL2] =
+ dcn31_clock_source_create(ctx, ctx->dc_bios,
+ CLOCK_SOURCE_COMBO_PHY_PLL2,
+ &clk_src_regs[2], false);
+ pool->base.clock_sources[DCN31_CLK_SRC_PLL3] =
+ dcn31_clock_source_create(ctx, ctx->dc_bios,
+ CLOCK_SOURCE_COMBO_PHY_PLL3,
+ &clk_src_regs[3], false);
+ pool->base.clock_sources[DCN31_CLK_SRC_PLL4] =
+ dcn31_clock_source_create(ctx, ctx->dc_bios,
+ CLOCK_SOURCE_COMBO_PHY_PLL4,
+ &clk_src_regs[4], false);
+
+ pool->base.clk_src_count = DCN30_CLK_SRC_TOTAL;
+
+ /* todo: not reuse phy_pll registers */
+ pool->base.dp_clock_source =
+ dcn31_clock_source_create(ctx, ctx->dc_bios,
+ CLOCK_SOURCE_ID_DP_DTO,
+ &clk_src_regs[0], true);
+
+ for (i = 0; i < pool->base.clk_src_count; i++) {
+ if (pool->base.clock_sources[i] == NULL) {
+ dm_error("DC: failed to create clock sources!\n");
+ BREAK_TO_DEBUGGER();
+ goto create_fail;
+ }
+ }
+
+ /* TODO: DCCG */
+ pool->base.dccg = dccg31_create(ctx, &dccg_regs, &dccg_shift, &dccg_mask);
+ if (pool->base.dccg == NULL) {
+ dm_error("DC: failed to create dccg!\n");
+ BREAK_TO_DEBUGGER();
+ goto create_fail;
+ }
+
+ /* TODO: IRQ */
+ init_data.ctx = dc->ctx;
+ pool->base.irqs = dal_irq_service_dcn31_create(&init_data);
+ if (!pool->base.irqs)
+ goto create_fail;
+
+ /* HUBBUB */
+ pool->base.hubbub = dcn31_hubbub_create(ctx);
+ if (pool->base.hubbub == NULL) {
+ BREAK_TO_DEBUGGER();
+ dm_error("DC: failed to create hubbub!\n");
+ goto create_fail;
+ }
+
+ /* HUBPs, DPPs, OPPs and TGs */
+ for (i = 0; i < pool->base.pipe_count; i++) {
+ pool->base.hubps[i] = dcn31_hubp_create(ctx, i);
+ if (pool->base.hubps[i] == NULL) {
+ BREAK_TO_DEBUGGER();
+ dm_error(
+ "DC: failed to create hubps!\n");
+ goto create_fail;
+ }
+
+ pool->base.dpps[i] = dcn31_dpp_create(ctx, i);
+ if (pool->base.dpps[i] == NULL) {
+ BREAK_TO_DEBUGGER();
+ dm_error(
+ "DC: failed to create dpps!\n");
+ goto create_fail;
+ }
+ }
+
+ for (i = 0; i < pool->base.res_cap->num_opp; i++) {
+ pool->base.opps[i] = dcn31_opp_create(ctx, i);
+ if (pool->base.opps[i] == NULL) {
+ BREAK_TO_DEBUGGER();
+ dm_error(
+ "DC: failed to create output pixel processor!\n");
+ goto create_fail;
+ }
+ }
+
+ for (i = 0; i < pool->base.res_cap->num_timing_generator; i++) {
+ pool->base.timing_generators[i] = dcn31_timing_generator_create(
+ ctx, i);
+ if (pool->base.timing_generators[i] == NULL) {
+ BREAK_TO_DEBUGGER();
+ dm_error("DC: failed to create tg!\n");
+ goto create_fail;
+ }
+ }
+ pool->base.timing_generator_count = i;
+
+ /* PSR */
+ pool->base.psr = dmub_psr_create(ctx);
+ if (pool->base.psr == NULL) {
+ dm_error("DC: failed to create psr obj!\n");
+ BREAK_TO_DEBUGGER();
+ goto create_fail;
+ }
+
+ /* ABM */
+ for (i = 0; i < pool->base.res_cap->num_timing_generator; i++) {
+ pool->base.multiple_abms[i] = dmub_abm_create(ctx,
+ &abm_regs[i],
+ &abm_shift,
+ &abm_mask);
+ if (pool->base.multiple_abms[i] == NULL) {
+ dm_error("DC: failed to create abm for pipe %d!\n", i);
+ BREAK_TO_DEBUGGER();
+ goto create_fail;
+ }
+ }
+
+ /* MPC and DSC */
+ pool->base.mpc = dcn31_mpc_create(ctx, pool->base.mpcc_count, pool->base.res_cap->num_mpc_3dlut);
+ if (pool->base.mpc == NULL) {
+ BREAK_TO_DEBUGGER();
+ dm_error("DC: failed to create mpc!\n");
+ goto create_fail;
+ }
+
+ for (i = 0; i < pool->base.res_cap->num_dsc; i++) {
+ pool->base.dscs[i] = dcn31_dsc_create(ctx, i);
+ if (pool->base.dscs[i] == NULL) {
+ BREAK_TO_DEBUGGER();
+ dm_error("DC: failed to create display stream compressor %d!\n", i);
+ goto create_fail;
+ }
+ }
+
+ /* DWB and MMHUBBUB */
+ if (!dcn31_dwbc_create(ctx, &pool->base)) {
+ BREAK_TO_DEBUGGER();
+ dm_error("DC: failed to create dwbc!\n");
+ goto create_fail;
+ }
+
+ if (!dcn31_mmhubbub_create(ctx, &pool->base)) {
+ BREAK_TO_DEBUGGER();
+ dm_error("DC: failed to create mcif_wb!\n");
+ goto create_fail;
+ }
+
+ /* AUX and I2C */
+ for (i = 0; i < pool->base.res_cap->num_ddc; i++) {
+ pool->base.engines[i] = dcn31_aux_engine_create(ctx, i);
+ if (pool->base.engines[i] == NULL) {
+ BREAK_TO_DEBUGGER();
+ dm_error(
+ "DC:failed to create aux engine!!\n");
+ goto create_fail;
+ }
+ pool->base.hw_i2cs[i] = dcn31_i2c_hw_create(ctx, i);
+ if (pool->base.hw_i2cs[i] == NULL) {
+ BREAK_TO_DEBUGGER();
+ dm_error(
+ "DC:failed to create hw i2c!!\n");
+ goto create_fail;
+ }
+ pool->base.sw_i2cs[i] = NULL;
+ }
+
+ /* Audio, Stream Encoders including HPO and virtual, MPC 3D LUTs */
+ if (!resource_construct(num_virtual_links, dc, &pool->base,
+ (!IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment) ?
+ &res_create_funcs : &res_create_maximus_funcs)))
+ goto create_fail;
+
+ /* HW Sequencer and Plane caps */
+ dcn31_hw_sequencer_construct(dc);
+
+ dc->caps.max_planes = pool->base.pipe_count;
+
+ for (i = 0; i < dc->caps.max_planes; ++i)
+ dc->caps.planes[i] = plane_cap;
+
+ dc->cap_funcs = cap_funcs;
+
+ dc->dcn_ip->max_num_dpp = dcn3_16_ip.max_num_dpp;
+
+ return true;
+
+create_fail:
+
+ dcn316_resource_destruct(pool);
+
+ return false;
+}
+
+struct resource_pool *dcn316_create_resource_pool(
+ const struct dc_init_data *init_data,
+ struct dc *dc)
+{
+ struct dcn316_resource_pool *pool =
+ kzalloc(sizeof(struct dcn316_resource_pool), GFP_KERNEL);
+
+ if (!pool)
+ return NULL;
+
+ if (dcn316_resource_construct(init_data->num_virtual_links, dc, pool))
+ return &pool->base;
+
+ BREAK_TO_DEBUGGER();
+ kfree(pool);
+ return NULL;
+}
diff --git a/drivers/gpu/drm/amd/display/dc/dcn316/dcn316_resource.h b/drivers/gpu/drm/amd/display/dc/dcn316/dcn316_resource.h
new file mode 100644
index 000000000000..9d0d60cb9482
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/dc/dcn316/dcn316_resource.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2021 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: AMD
+ *
+ */
+
+#ifndef _DCN316_RESOURCE_H_
+#define _DCN316_RESOURCE_H_
+
+#include "core_types.h"
+
+#define TO_DCN316_RES_POOL(pool)\
+ container_of(pool, struct dcn316_resource_pool, base)
+
+struct dcn316_resource_pool {
+ struct resource_pool base;
+};
+
+struct resource_pool *dcn316_create_resource_pool(
+ const struct dc_init_data *init_data,
+ struct dc *dc);
+
+#endif /* _DCN316_RESOURCE_H_ */
diff --git a/drivers/gpu/drm/amd/display/dc/dm_helpers.h b/drivers/gpu/drm/amd/display/dc/dm_helpers.h
index 7f94e3f70d7f..31109db02e93 100644
--- a/drivers/gpu/drm/amd/display/dc/dm_helpers.h
+++ b/drivers/gpu/drm/amd/display/dc/dm_helpers.h
@@ -113,7 +113,7 @@ bool dm_helpers_dp_mst_start_top_mgr(
const struct dc_link *link,
bool boot);
-void dm_helpers_dp_mst_stop_top_mgr(
+bool dm_helpers_dp_mst_stop_top_mgr(
struct dc_context *ctx,
struct dc_link *link);
/**
@@ -170,9 +170,9 @@ bool dm_helpers_dmub_outbox_interrupt_control(struct dc_context *ctx, bool enabl
void dm_helpers_smu_timeout(struct dc_context *ctx, unsigned int msg_id, unsigned int param, unsigned int timeout_us);
-// 0x1 = Result_OK, 0xFE = Result_UnkmownCmd
+// 0x1 = Result_OK, 0xFE = Result_UnkmownCmd, 0x0 = Status_Busy
#define IS_SMU_TIMEOUT(result) \
- (!(result == 0x1 || result == 0xFE))
+ (result == 0x0)
int dm_helper_dmub_aux_transfer_sync(
struct dc_context *ctx,
@@ -184,4 +184,7 @@ int dm_helpers_dmub_set_config_sync(struct dc_context *ctx,
const struct dc_link *link,
struct set_config_cmd_payload *payload,
enum set_config_status *operation_result);
+
+enum dc_edid_status dm_helpers_get_sbios_edid(struct dc_link *link, struct dc_edid *edid);
+
#endif /* __DM_HELPERS__ */
diff --git a/drivers/gpu/drm/amd/display/dc/dml/Makefile b/drivers/gpu/drm/amd/display/dc/dml/Makefile
index eee6672bd32d..28978ce62f87 100644
--- a/drivers/gpu/drm/amd/display/dc/dml/Makefile
+++ b/drivers/gpu/drm/amd/display/dc/dml/Makefile
@@ -58,6 +58,7 @@ CFLAGS_$(AMDDALPATH)/dc/dml/display_mode_lib.o := $(dml_ccflags)
ifdef CONFIG_DRM_AMD_DC_DCN
CFLAGS_$(AMDDALPATH)/dc/dml/display_mode_vba.o := $(dml_ccflags)
+CFLAGS_$(AMDDALPATH)/dc/dml/dcn10/dcn10_fpu.o := $(dml_ccflags)
CFLAGS_$(AMDDALPATH)/dc/dml/dcn20/dcn20_fpu.o := $(dml_ccflags)
CFLAGS_$(AMDDALPATH)/dc/dml/dcn20/display_mode_vba_20.o := $(dml_ccflags)
CFLAGS_$(AMDDALPATH)/dc/dml/dcn20/display_mode_vba_20.o := $(dml_ccflags)
@@ -71,8 +72,13 @@ CFLAGS_$(AMDDALPATH)/dc/dml/dcn30/display_rq_dlg_calc_30.o := $(dml_ccflags)
CFLAGS_$(AMDDALPATH)/dc/dml/dcn31/display_mode_vba_31.o := $(dml_ccflags) $(frame_warn_flag)
CFLAGS_$(AMDDALPATH)/dc/dml/dcn31/display_rq_dlg_calc_31.o := $(dml_ccflags)
CFLAGS_$(AMDDALPATH)/dc/dml/dcn301/dcn301_fpu.o := $(dml_ccflags)
+CFLAGS_$(AMDDALPATH)/dc/dml/dcn302/dcn302_fpu.o := $(dml_ccflags)
+CFLAGS_$(AMDDALPATH)/dc/dml/dcn303/dcn303_fpu.o := $(dml_ccflags)
CFLAGS_$(AMDDALPATH)/dc/dml/dsc/rc_calc_fpu.o := $(dml_ccflags)
CFLAGS_$(AMDDALPATH)/dc/dml/display_mode_lib.o := $(dml_ccflags)
+CFLAGS_$(AMDDALPATH)/dc/dml/calcs/dcn_calcs.o := $(dml_ccflags)
+CFLAGS_$(AMDDALPATH)/dc/dml/calcs/dcn_calc_auto.o := $(dml_ccflags)
+CFLAGS_$(AMDDALPATH)/dc/dml/calcs/dcn_calc_math.o := $(dml_ccflags) -Wno-tautological-compare
CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml/display_mode_vba.o := $(dml_rcflags)
CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml/dcn2x/dcn2x.o := $(dml_rcflags)
CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml/dcn20/display_mode_vba_20.o := $(dml_rcflags)
@@ -93,10 +99,15 @@ CFLAGS_$(AMDDALPATH)/dc/dml/dml1_display_rq_dlg_calc.o := $(dml_ccflags)
CFLAGS_$(AMDDALPATH)/dc/dml/display_rq_dlg_helpers.o := $(dml_ccflags)
CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml/dml1_display_rq_dlg_calc.o := $(dml_rcflags)
CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml/display_rq_dlg_helpers.o := $(dml_rcflags)
+CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml/calcs/dcn_calcs.o := $(dml_rcflags)
+CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml/calcs/dcn_calc_auto.o := $(dml_rcflags)
+CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml/calcs/dcn_calc_math.o := $(dml_rcflags)
-DML = display_mode_lib.o display_rq_dlg_helpers.o dml1_display_rq_dlg_calc.o \
+DML = calcs/dce_calcs.o calcs/custom_float.o calcs/bw_fixed.o
ifdef CONFIG_DRM_AMD_DC_DCN
+DML += display_mode_lib.o display_rq_dlg_helpers.o dml1_display_rq_dlg_calc.o
+DML += dcn10/dcn10_fpu.o
DML += dcn20/dcn20_fpu.o
DML += display_mode_vba.o dcn20/display_rq_dlg_calc_20.o dcn20/display_mode_vba_20.o
DML += dcn20/display_rq_dlg_calc_20v2.o dcn20/display_mode_vba_20v2.o
@@ -104,7 +115,10 @@ DML += dcn21/display_rq_dlg_calc_21.o dcn21/display_mode_vba_21.o
DML += dcn30/display_mode_vba_30.o dcn30/display_rq_dlg_calc_30.o
DML += dcn31/display_mode_vba_31.o dcn31/display_rq_dlg_calc_31.o
DML += dcn301/dcn301_fpu.o
+DML += dcn302/dcn302_fpu.o
+DML += dcn303/dcn303_fpu.o
DML += dsc/rc_calc_fpu.o
+DML += calcs/dcn_calcs.o calcs/dcn_calc_math.o calcs/dcn_calc_auto.o
endif
AMD_DAL_DML = $(addprefix $(AMDDALPATH)/dc/dml/,$(DML))
diff --git a/drivers/gpu/drm/amd/display/dc/calcs/bw_fixed.c b/drivers/gpu/drm/amd/display/dc/dml/calcs/bw_fixed.c
index 6ca288fb5fb9..6ca288fb5fb9 100644
--- a/drivers/gpu/drm/amd/display/dc/calcs/bw_fixed.c
+++ b/drivers/gpu/drm/amd/display/dc/dml/calcs/bw_fixed.c
diff --git a/drivers/gpu/drm/amd/display/dc/calcs/calcs_logger.h b/drivers/gpu/drm/amd/display/dc/dml/calcs/calcs_logger.h
index 62435bfc274d..62435bfc274d 100644
--- a/drivers/gpu/drm/amd/display/dc/calcs/calcs_logger.h
+++ b/drivers/gpu/drm/amd/display/dc/dml/calcs/calcs_logger.h
diff --git a/drivers/gpu/drm/amd/display/dc/calcs/custom_float.c b/drivers/gpu/drm/amd/display/dc/dml/calcs/custom_float.c
index 31d167bc548f..31d167bc548f 100644
--- a/drivers/gpu/drm/amd/display/dc/calcs/custom_float.c
+++ b/drivers/gpu/drm/amd/display/dc/dml/calcs/custom_float.c
diff --git a/drivers/gpu/drm/amd/display/dc/calcs/dce_calcs.c b/drivers/gpu/drm/amd/display/dc/dml/calcs/dce_calcs.c
index ff5bb152ef49..0100a6053ab6 100644
--- a/drivers/gpu/drm/amd/display/dc/calcs/dce_calcs.c
+++ b/drivers/gpu/drm/amd/display/dc/dml/calcs/dce_calcs.c
@@ -2033,10 +2033,10 @@ static void calculate_bandwidth(
kfree(surface_type);
free_tiling_mode:
kfree(tiling_mode);
-free_yclk:
- kfree(yclk);
free_sclk:
kfree(sclk);
+free_yclk:
+ kfree(yclk);
}
/*******************************************************************************
@@ -3411,35 +3411,33 @@ bool bw_calcs(struct dc_context *ctx,
calcs_output->stutter_exit_wm_ns[5].c_mark =
bw_fixed_to_int(bw_mul(data->
stutter_exit_watermark[9], bw_int_to_fixed(1000)));
-
- calcs_output->stutter_entry_wm_ns[0].c_mark =
- bw_fixed_to_int(bw_mul(data->
- stutter_entry_watermark[4], bw_int_to_fixed(1000)));
- calcs_output->stutter_entry_wm_ns[1].c_mark =
- bw_fixed_to_int(bw_mul(data->
- stutter_entry_watermark[5], bw_int_to_fixed(1000)));
- calcs_output->stutter_entry_wm_ns[2].c_mark =
- bw_fixed_to_int(bw_mul(data->
- stutter_entry_watermark[6], bw_int_to_fixed(1000)));
- if (ctx->dc->caps.max_slave_planes) {
- calcs_output->stutter_entry_wm_ns[3].c_mark =
+ calcs_output->stutter_entry_wm_ns[0].c_mark =
bw_fixed_to_int(bw_mul(data->
- stutter_entry_watermark[0], bw_int_to_fixed(1000)));
- calcs_output->stutter_entry_wm_ns[4].c_mark =
+ stutter_entry_watermark[4], bw_int_to_fixed(1000)));
+ calcs_output->stutter_entry_wm_ns[1].c_mark =
bw_fixed_to_int(bw_mul(data->
- stutter_entry_watermark[1], bw_int_to_fixed(1000)));
- } else {
- calcs_output->stutter_entry_wm_ns[3].c_mark =
+ stutter_entry_watermark[5], bw_int_to_fixed(1000)));
+ calcs_output->stutter_entry_wm_ns[2].c_mark =
bw_fixed_to_int(bw_mul(data->
- stutter_entry_watermark[7], bw_int_to_fixed(1000)));
- calcs_output->stutter_entry_wm_ns[4].c_mark =
+ stutter_entry_watermark[6], bw_int_to_fixed(1000)));
+ if (ctx->dc->caps.max_slave_planes) {
+ calcs_output->stutter_entry_wm_ns[3].c_mark =
+ bw_fixed_to_int(bw_mul(data->stutter_entry_watermark[0],
+ bw_int_to_fixed(1000)));
+ calcs_output->stutter_entry_wm_ns[4].c_mark =
+ bw_fixed_to_int(bw_mul(data->stutter_entry_watermark[1],
+ bw_int_to_fixed(1000)));
+ } else {
+ calcs_output->stutter_entry_wm_ns[3].c_mark =
+ bw_fixed_to_int(bw_mul(data->stutter_entry_watermark[7],
+ bw_int_to_fixed(1000)));
+ calcs_output->stutter_entry_wm_ns[4].c_mark =
+ bw_fixed_to_int(bw_mul(data->stutter_entry_watermark[8],
+ bw_int_to_fixed(1000)));
+ }
+ calcs_output->stutter_entry_wm_ns[5].c_mark =
bw_fixed_to_int(bw_mul(data->
- stutter_entry_watermark[8], bw_int_to_fixed(1000)));
- }
- calcs_output->stutter_entry_wm_ns[5].c_mark =
- bw_fixed_to_int(bw_mul(data->
- stutter_entry_watermark[9], bw_int_to_fixed(1000)));
-
+ stutter_entry_watermark[9], bw_int_to_fixed(1000)));
calcs_output->urgent_wm_ns[0].c_mark =
bw_fixed_to_int(bw_mul(data->
urgent_watermark[4], bw_int_to_fixed(1000)));
diff --git a/drivers/gpu/drm/amd/display/dc/calcs/dcn_calc_auto.c b/drivers/gpu/drm/amd/display/dc/dml/calcs/dcn_calc_auto.c
index 41284e263325..41284e263325 100644
--- a/drivers/gpu/drm/amd/display/dc/calcs/dcn_calc_auto.c
+++ b/drivers/gpu/drm/amd/display/dc/dml/calcs/dcn_calc_auto.c
diff --git a/drivers/gpu/drm/amd/display/dc/calcs/dcn_calc_auto.h b/drivers/gpu/drm/amd/display/dc/dml/calcs/dcn_calc_auto.h
index ce35de79a6c7..ce35de79a6c7 100644
--- a/drivers/gpu/drm/amd/display/dc/calcs/dcn_calc_auto.h
+++ b/drivers/gpu/drm/amd/display/dc/dml/calcs/dcn_calc_auto.h
diff --git a/drivers/gpu/drm/amd/display/dc/calcs/dcn_calc_math.c b/drivers/gpu/drm/amd/display/dc/dml/calcs/dcn_calc_math.c
index 07d18e78de49..07d18e78de49 100644
--- a/drivers/gpu/drm/amd/display/dc/calcs/dcn_calc_math.c
+++ b/drivers/gpu/drm/amd/display/dc/dml/calcs/dcn_calc_math.c
diff --git a/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c b/drivers/gpu/drm/amd/display/dc/dml/calcs/dcn_calcs.c
index ec19678a0702..e447c74be713 100644
--- a/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c
+++ b/drivers/gpu/drm/amd/display/dc/dml/calcs/dcn_calcs.c
@@ -503,7 +503,6 @@ static void dcn_bw_calc_rq_dlg_ttu(
//input[in_idx].dout.output_standard;
/*todo: soc->sr_enter_plus_exit_time??*/
- dlg_sys_param->t_srx_delay_us = dc->dcn_ip->dcfclk_cstate_latency / v->dcf_clk_deep_sleep;
dml1_rq_dlg_get_rq_params(dml, rq_param, &input->pipe.src);
dml1_extract_rq_regs(dml, rq_regs, rq_param);
diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn10/dcn10_fpu.c b/drivers/gpu/drm/amd/display/dc/dml/dcn10/dcn10_fpu.c
new file mode 100644
index 000000000000..99644d896222
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/dc/dml/dcn10/dcn10_fpu.c
@@ -0,0 +1,123 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright 2021 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: AMD
+ *
+ */
+
+#include "dcn10/dcn10_resource.h"
+
+#include "dcn10_fpu.h"
+
+/**
+ * DOC: DCN10 FPU manipulation Overview
+ *
+ * The DCN architecture relies on FPU operations, which require special
+ * compilation flags and the use of kernel_fpu_begin/end functions; ideally, we
+ * want to avoid spreading FPU access across multiple files. With this idea in
+ * mind, this file aims to centralize DCN10 functions that require FPU access
+ * in a single place. Code in this file follows the following code pattern:
+ *
+ * 1. Functions that use FPU operations should be isolated in static functions.
+ * 2. The FPU functions should have the noinline attribute to ensure anything
+ * that deals with FP register is contained within this call.
+ * 3. All function that needs to be accessed outside this file requires a
+ * public interface that not uses any FPU reference.
+ * 4. Developers **must not** use DC_FP_START/END in this file, but they need
+ * to ensure that the caller invokes it before access any function available
+ * in this file. For this reason, public functions in this file must invoke
+ * dc_assert_fp_enabled();
+ *
+ * Let's expand a little bit more the idea in the code pattern. To fully
+ * isolate FPU operations in a single place, we must avoid situations where
+ * compilers spill FP values to registers due to FP enable in a specific C
+ * file. Note that even if we isolate all FPU functions in a single file and
+ * call its interface from other files, the compiler might enable the use of
+ * FPU before we call DC_FP_START. Nevertheless, it is the programmer's
+ * responsibility to invoke DC_FP_START/END in the correct place. To highlight
+ * situations where developers forgot to use the FP protection before calling
+ * the DC FPU interface functions, we introduce a helper that checks if the
+ * function is invoked under FP protection. If not, it will trigger a kernel
+ * warning.
+ */
+
+struct _vcs_dpi_ip_params_st dcn1_0_ip = {
+ .rob_buffer_size_kbytes = 64,
+ .det_buffer_size_kbytes = 164,
+ .dpte_buffer_size_in_pte_reqs_luma = 42,
+ .dpp_output_buffer_pixels = 2560,
+ .opp_output_buffer_lines = 1,
+ .pixel_chunk_size_kbytes = 8,
+ .pte_enable = 1,
+ .pte_chunk_size_kbytes = 2,
+ .meta_chunk_size_kbytes = 2,
+ .writeback_chunk_size_kbytes = 2,
+ .line_buffer_size_bits = 589824,
+ .max_line_buffer_lines = 12,
+ .IsLineBufferBppFixed = 0,
+ .LineBufferFixedBpp = -1,
+ .writeback_luma_buffer_size_kbytes = 12,
+ .writeback_chroma_buffer_size_kbytes = 8,
+ .max_num_dpp = 4,
+ .max_num_wb = 2,
+ .max_dchub_pscl_bw_pix_per_clk = 4,
+ .max_pscl_lb_bw_pix_per_clk = 2,
+ .max_lb_vscl_bw_pix_per_clk = 4,
+ .max_vscl_hscl_bw_pix_per_clk = 4,
+ .max_hscl_ratio = 4,
+ .max_vscl_ratio = 4,
+ .hscl_mults = 4,
+ .vscl_mults = 4,
+ .max_hscl_taps = 8,
+ .max_vscl_taps = 8,
+ .dispclk_ramp_margin_percent = 1,
+ .underscan_factor = 1.10,
+ .min_vblank_lines = 14,
+ .dppclk_delay_subtotal = 90,
+ .dispclk_delay_subtotal = 42,
+ .dcfclk_cstate_latency = 10,
+ .max_inter_dcn_tile_repeaters = 8,
+ .can_vstartup_lines_exceed_vsync_plus_back_porch_lines_minus_one = 0,
+ .bug_forcing_LC_req_same_size_fixed = 0,
+};
+
+struct _vcs_dpi_soc_bounding_box_st dcn1_0_soc = {
+ .sr_exit_time_us = 9.0,
+ .sr_enter_plus_exit_time_us = 11.0,
+ .urgent_latency_us = 4.0,
+ .writeback_latency_us = 12.0,
+ .ideal_dram_bw_after_urgent_percent = 80.0,
+ .max_request_size_bytes = 256,
+ .downspread_percent = 0.5,
+ .dram_page_open_time_ns = 50.0,
+ .dram_rw_turnaround_time_ns = 17.5,
+ .dram_return_buffer_per_channel_bytes = 8192,
+ .round_trip_ping_latency_dcfclk_cycles = 128,
+ .urgent_out_of_order_return_per_channel_bytes = 256,
+ .channel_interleave_bytes = 256,
+ .num_banks = 8,
+ .num_chans = 2,
+ .vmm_page_size_bytes = 4096,
+ .dram_clock_change_latency_us = 17.0,
+ .writeback_dram_clock_change_latency_us = 23.0,
+ .return_bus_width_bytes = 64,
+};
diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn10/dcn10_fpu.h b/drivers/gpu/drm/amd/display/dc/dml/dcn10/dcn10_fpu.h
new file mode 100644
index 000000000000..e74ed4b4ce5b
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/dc/dml/dcn10/dcn10_fpu.h
@@ -0,0 +1,30 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright 2021 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: AMD
+ *
+ */
+
+#ifndef __DCN10_FPU_H__
+#define __DCN10_FPU_H__
+
+#endif /* __DCN20_FPU_H__ */
diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn20/dcn20_fpu.c b/drivers/gpu/drm/amd/display/dc/dml/dcn20/dcn20_fpu.c
index d590dc917363..2f6122153bdb 100644
--- a/drivers/gpu/drm/amd/display/dc/dml/dcn20/dcn20_fpu.c
+++ b/drivers/gpu/drm/amd/display/dc/dml/dcn20/dcn20_fpu.c
@@ -25,9 +25,23 @@
*/
#include "resource.h"
+#include "clk_mgr.h"
+#include "dc_link_dp.h"
+#include "dchubbub.h"
+#include "dcn20/dcn20_resource.h"
+#include "dcn21/dcn21_resource.h"
#include "dcn20_fpu.h"
+#define DC_LOGGER_INIT(logger)
+
+#ifndef MAX
+#define MAX(X, Y) ((X) > (Y) ? (X) : (Y))
+#endif
+#ifndef MIN
+#define MIN(X, Y) ((X) < (Y) ? (X) : (Y))
+#endif
+
/**
* DOC: DCN2x FPU manipulation Overview
*
@@ -61,6 +75,581 @@
* warning.
*/
+struct _vcs_dpi_ip_params_st dcn2_0_ip = {
+ .odm_capable = 1,
+ .gpuvm_enable = 0,
+ .hostvm_enable = 0,
+ .gpuvm_max_page_table_levels = 4,
+ .hostvm_max_page_table_levels = 4,
+ .hostvm_cached_page_table_levels = 0,
+ .pte_group_size_bytes = 2048,
+ .num_dsc = 6,
+ .rob_buffer_size_kbytes = 168,
+ .det_buffer_size_kbytes = 164,
+ .dpte_buffer_size_in_pte_reqs_luma = 84,
+ .pde_proc_buffer_size_64k_reqs = 48,
+ .dpp_output_buffer_pixels = 2560,
+ .opp_output_buffer_lines = 1,
+ .pixel_chunk_size_kbytes = 8,
+ .pte_chunk_size_kbytes = 2,
+ .meta_chunk_size_kbytes = 2,
+ .writeback_chunk_size_kbytes = 2,
+ .line_buffer_size_bits = 789504,
+ .is_line_buffer_bpp_fixed = 0,
+ .line_buffer_fixed_bpp = 0,
+ .dcc_supported = true,
+ .max_line_buffer_lines = 12,
+ .writeback_luma_buffer_size_kbytes = 12,
+ .writeback_chroma_buffer_size_kbytes = 8,
+ .writeback_chroma_line_buffer_width_pixels = 4,
+ .writeback_max_hscl_ratio = 1,
+ .writeback_max_vscl_ratio = 1,
+ .writeback_min_hscl_ratio = 1,
+ .writeback_min_vscl_ratio = 1,
+ .writeback_max_hscl_taps = 12,
+ .writeback_max_vscl_taps = 12,
+ .writeback_line_buffer_luma_buffer_size = 0,
+ .writeback_line_buffer_chroma_buffer_size = 14643,
+ .cursor_buffer_size = 8,
+ .cursor_chunk_size = 2,
+ .max_num_otg = 6,
+ .max_num_dpp = 6,
+ .max_num_wb = 1,
+ .max_dchub_pscl_bw_pix_per_clk = 4,
+ .max_pscl_lb_bw_pix_per_clk = 2,
+ .max_lb_vscl_bw_pix_per_clk = 4,
+ .max_vscl_hscl_bw_pix_per_clk = 4,
+ .max_hscl_ratio = 8,
+ .max_vscl_ratio = 8,
+ .hscl_mults = 4,
+ .vscl_mults = 4,
+ .max_hscl_taps = 8,
+ .max_vscl_taps = 8,
+ .dispclk_ramp_margin_percent = 1,
+ .underscan_factor = 1.10,
+ .min_vblank_lines = 32, //
+ .dppclk_delay_subtotal = 77, //
+ .dppclk_delay_scl_lb_only = 16,
+ .dppclk_delay_scl = 50,
+ .dppclk_delay_cnvc_formatter = 8,
+ .dppclk_delay_cnvc_cursor = 6,
+ .dispclk_delay_subtotal = 87, //
+ .dcfclk_cstate_latency = 10, // SRExitTime
+ .max_inter_dcn_tile_repeaters = 8,
+ .xfc_supported = true,
+ .xfc_fill_bw_overhead_percent = 10.0,
+ .xfc_fill_constant_bytes = 0,
+ .number_of_cursors = 1,
+};
+
+struct _vcs_dpi_ip_params_st dcn2_0_nv14_ip = {
+ .odm_capable = 1,
+ .gpuvm_enable = 0,
+ .hostvm_enable = 0,
+ .gpuvm_max_page_table_levels = 4,
+ .hostvm_max_page_table_levels = 4,
+ .hostvm_cached_page_table_levels = 0,
+ .num_dsc = 5,
+ .rob_buffer_size_kbytes = 168,
+ .det_buffer_size_kbytes = 164,
+ .dpte_buffer_size_in_pte_reqs_luma = 84,
+ .dpte_buffer_size_in_pte_reqs_chroma = 42,//todo
+ .dpp_output_buffer_pixels = 2560,
+ .opp_output_buffer_lines = 1,
+ .pixel_chunk_size_kbytes = 8,
+ .pte_enable = 1,
+ .max_page_table_levels = 4,
+ .pte_chunk_size_kbytes = 2,
+ .meta_chunk_size_kbytes = 2,
+ .writeback_chunk_size_kbytes = 2,
+ .line_buffer_size_bits = 789504,
+ .is_line_buffer_bpp_fixed = 0,
+ .line_buffer_fixed_bpp = 0,
+ .dcc_supported = true,
+ .max_line_buffer_lines = 12,
+ .writeback_luma_buffer_size_kbytes = 12,
+ .writeback_chroma_buffer_size_kbytes = 8,
+ .writeback_chroma_line_buffer_width_pixels = 4,
+ .writeback_max_hscl_ratio = 1,
+ .writeback_max_vscl_ratio = 1,
+ .writeback_min_hscl_ratio = 1,
+ .writeback_min_vscl_ratio = 1,
+ .writeback_max_hscl_taps = 12,
+ .writeback_max_vscl_taps = 12,
+ .writeback_line_buffer_luma_buffer_size = 0,
+ .writeback_line_buffer_chroma_buffer_size = 14643,
+ .cursor_buffer_size = 8,
+ .cursor_chunk_size = 2,
+ .max_num_otg = 5,
+ .max_num_dpp = 5,
+ .max_num_wb = 1,
+ .max_dchub_pscl_bw_pix_per_clk = 4,
+ .max_pscl_lb_bw_pix_per_clk = 2,
+ .max_lb_vscl_bw_pix_per_clk = 4,
+ .max_vscl_hscl_bw_pix_per_clk = 4,
+ .max_hscl_ratio = 8,
+ .max_vscl_ratio = 8,
+ .hscl_mults = 4,
+ .vscl_mults = 4,
+ .max_hscl_taps = 8,
+ .max_vscl_taps = 8,
+ .dispclk_ramp_margin_percent = 1,
+ .underscan_factor = 1.10,
+ .min_vblank_lines = 32, //
+ .dppclk_delay_subtotal = 77, //
+ .dppclk_delay_scl_lb_only = 16,
+ .dppclk_delay_scl = 50,
+ .dppclk_delay_cnvc_formatter = 8,
+ .dppclk_delay_cnvc_cursor = 6,
+ .dispclk_delay_subtotal = 87, //
+ .dcfclk_cstate_latency = 10, // SRExitTime
+ .max_inter_dcn_tile_repeaters = 8,
+ .xfc_supported = true,
+ .xfc_fill_bw_overhead_percent = 10.0,
+ .xfc_fill_constant_bytes = 0,
+ .ptoi_supported = 0,
+ .number_of_cursors = 1,
+};
+
+struct _vcs_dpi_soc_bounding_box_st dcn2_0_soc = {
+ /* Defaults that get patched on driver load from firmware. */
+ .clock_limits = {
+ {
+ .state = 0,
+ .dcfclk_mhz = 560.0,
+ .fabricclk_mhz = 560.0,
+ .dispclk_mhz = 513.0,
+ .dppclk_mhz = 513.0,
+ .phyclk_mhz = 540.0,
+ .socclk_mhz = 560.0,
+ .dscclk_mhz = 171.0,
+ .dram_speed_mts = 8960.0,
+ },
+ {
+ .state = 1,
+ .dcfclk_mhz = 694.0,
+ .fabricclk_mhz = 694.0,
+ .dispclk_mhz = 642.0,
+ .dppclk_mhz = 642.0,
+ .phyclk_mhz = 600.0,
+ .socclk_mhz = 694.0,
+ .dscclk_mhz = 214.0,
+ .dram_speed_mts = 11104.0,
+ },
+ {
+ .state = 2,
+ .dcfclk_mhz = 875.0,
+ .fabricclk_mhz = 875.0,
+ .dispclk_mhz = 734.0,
+ .dppclk_mhz = 734.0,
+ .phyclk_mhz = 810.0,
+ .socclk_mhz = 875.0,
+ .dscclk_mhz = 245.0,
+ .dram_speed_mts = 14000.0,
+ },
+ {
+ .state = 3,
+ .dcfclk_mhz = 1000.0,
+ .fabricclk_mhz = 1000.0,
+ .dispclk_mhz = 1100.0,
+ .dppclk_mhz = 1100.0,
+ .phyclk_mhz = 810.0,
+ .socclk_mhz = 1000.0,
+ .dscclk_mhz = 367.0,
+ .dram_speed_mts = 16000.0,
+ },
+ {
+ .state = 4,
+ .dcfclk_mhz = 1200.0,
+ .fabricclk_mhz = 1200.0,
+ .dispclk_mhz = 1284.0,
+ .dppclk_mhz = 1284.0,
+ .phyclk_mhz = 810.0,
+ .socclk_mhz = 1200.0,
+ .dscclk_mhz = 428.0,
+ .dram_speed_mts = 16000.0,
+ },
+ /*Extra state, no dispclk ramping*/
+ {
+ .state = 5,
+ .dcfclk_mhz = 1200.0,
+ .fabricclk_mhz = 1200.0,
+ .dispclk_mhz = 1284.0,
+ .dppclk_mhz = 1284.0,
+ .phyclk_mhz = 810.0,
+ .socclk_mhz = 1200.0,
+ .dscclk_mhz = 428.0,
+ .dram_speed_mts = 16000.0,
+ },
+ },
+ .num_states = 5,
+ .sr_exit_time_us = 8.6,
+ .sr_enter_plus_exit_time_us = 10.9,
+ .urgent_latency_us = 4.0,
+ .urgent_latency_pixel_data_only_us = 4.0,
+ .urgent_latency_pixel_mixed_with_vm_data_us = 4.0,
+ .urgent_latency_vm_data_only_us = 4.0,
+ .urgent_out_of_order_return_per_channel_pixel_only_bytes = 4096,
+ .urgent_out_of_order_return_per_channel_pixel_and_vm_bytes = 4096,
+ .urgent_out_of_order_return_per_channel_vm_only_bytes = 4096,
+ .pct_ideal_dram_sdp_bw_after_urgent_pixel_only = 40.0,
+ .pct_ideal_dram_sdp_bw_after_urgent_pixel_and_vm = 40.0,
+ .pct_ideal_dram_sdp_bw_after_urgent_vm_only = 40.0,
+ .max_avg_sdp_bw_use_normal_percent = 40.0,
+ .max_avg_dram_bw_use_normal_percent = 40.0,
+ .writeback_latency_us = 12.0,
+ .ideal_dram_bw_after_urgent_percent = 40.0,
+ .max_request_size_bytes = 256,
+ .dram_channel_width_bytes = 2,
+ .fabric_datapath_to_dcn_data_return_bytes = 64,
+ .dcn_downspread_percent = 0.5,
+ .downspread_percent = 0.38,
+ .dram_page_open_time_ns = 50.0,
+ .dram_rw_turnaround_time_ns = 17.5,
+ .dram_return_buffer_per_channel_bytes = 8192,
+ .round_trip_ping_latency_dcfclk_cycles = 131,
+ .urgent_out_of_order_return_per_channel_bytes = 256,
+ .channel_interleave_bytes = 256,
+ .num_banks = 8,
+ .num_chans = 16,
+ .vmm_page_size_bytes = 4096,
+ .dram_clock_change_latency_us = 404.0,
+ .dummy_pstate_latency_us = 5.0,
+ .writeback_dram_clock_change_latency_us = 23.0,
+ .return_bus_width_bytes = 64,
+ .dispclk_dppclk_vco_speed_mhz = 3850,
+ .xfc_bus_transport_time_us = 20,
+ .xfc_xbuf_latency_tolerance_us = 4,
+ .use_urgent_burst_bw = 0
+};
+
+struct _vcs_dpi_soc_bounding_box_st dcn2_0_nv14_soc = {
+ .clock_limits = {
+ {
+ .state = 0,
+ .dcfclk_mhz = 560.0,
+ .fabricclk_mhz = 560.0,
+ .dispclk_mhz = 513.0,
+ .dppclk_mhz = 513.0,
+ .phyclk_mhz = 540.0,
+ .socclk_mhz = 560.0,
+ .dscclk_mhz = 171.0,
+ .dram_speed_mts = 8960.0,
+ },
+ {
+ .state = 1,
+ .dcfclk_mhz = 694.0,
+ .fabricclk_mhz = 694.0,
+ .dispclk_mhz = 642.0,
+ .dppclk_mhz = 642.0,
+ .phyclk_mhz = 600.0,
+ .socclk_mhz = 694.0,
+ .dscclk_mhz = 214.0,
+ .dram_speed_mts = 11104.0,
+ },
+ {
+ .state = 2,
+ .dcfclk_mhz = 875.0,
+ .fabricclk_mhz = 875.0,
+ .dispclk_mhz = 734.0,
+ .dppclk_mhz = 734.0,
+ .phyclk_mhz = 810.0,
+ .socclk_mhz = 875.0,
+ .dscclk_mhz = 245.0,
+ .dram_speed_mts = 14000.0,
+ },
+ {
+ .state = 3,
+ .dcfclk_mhz = 1000.0,
+ .fabricclk_mhz = 1000.0,
+ .dispclk_mhz = 1100.0,
+ .dppclk_mhz = 1100.0,
+ .phyclk_mhz = 810.0,
+ .socclk_mhz = 1000.0,
+ .dscclk_mhz = 367.0,
+ .dram_speed_mts = 16000.0,
+ },
+ {
+ .state = 4,
+ .dcfclk_mhz = 1200.0,
+ .fabricclk_mhz = 1200.0,
+ .dispclk_mhz = 1284.0,
+ .dppclk_mhz = 1284.0,
+ .phyclk_mhz = 810.0,
+ .socclk_mhz = 1200.0,
+ .dscclk_mhz = 428.0,
+ .dram_speed_mts = 16000.0,
+ },
+ /*Extra state, no dispclk ramping*/
+ {
+ .state = 5,
+ .dcfclk_mhz = 1200.0,
+ .fabricclk_mhz = 1200.0,
+ .dispclk_mhz = 1284.0,
+ .dppclk_mhz = 1284.0,
+ .phyclk_mhz = 810.0,
+ .socclk_mhz = 1200.0,
+ .dscclk_mhz = 428.0,
+ .dram_speed_mts = 16000.0,
+ },
+ },
+ .num_states = 5,
+ .sr_exit_time_us = 11.6,
+ .sr_enter_plus_exit_time_us = 13.9,
+ .urgent_latency_us = 4.0,
+ .urgent_latency_pixel_data_only_us = 4.0,
+ .urgent_latency_pixel_mixed_with_vm_data_us = 4.0,
+ .urgent_latency_vm_data_only_us = 4.0,
+ .urgent_out_of_order_return_per_channel_pixel_only_bytes = 4096,
+ .urgent_out_of_order_return_per_channel_pixel_and_vm_bytes = 4096,
+ .urgent_out_of_order_return_per_channel_vm_only_bytes = 4096,
+ .pct_ideal_dram_sdp_bw_after_urgent_pixel_only = 40.0,
+ .pct_ideal_dram_sdp_bw_after_urgent_pixel_and_vm = 40.0,
+ .pct_ideal_dram_sdp_bw_after_urgent_vm_only = 40.0,
+ .max_avg_sdp_bw_use_normal_percent = 40.0,
+ .max_avg_dram_bw_use_normal_percent = 40.0,
+ .writeback_latency_us = 12.0,
+ .ideal_dram_bw_after_urgent_percent = 40.0,
+ .max_request_size_bytes = 256,
+ .dram_channel_width_bytes = 2,
+ .fabric_datapath_to_dcn_data_return_bytes = 64,
+ .dcn_downspread_percent = 0.5,
+ .downspread_percent = 0.38,
+ .dram_page_open_time_ns = 50.0,
+ .dram_rw_turnaround_time_ns = 17.5,
+ .dram_return_buffer_per_channel_bytes = 8192,
+ .round_trip_ping_latency_dcfclk_cycles = 131,
+ .urgent_out_of_order_return_per_channel_bytes = 256,
+ .channel_interleave_bytes = 256,
+ .num_banks = 8,
+ .num_chans = 8,
+ .vmm_page_size_bytes = 4096,
+ .dram_clock_change_latency_us = 404.0,
+ .dummy_pstate_latency_us = 5.0,
+ .writeback_dram_clock_change_latency_us = 23.0,
+ .return_bus_width_bytes = 64,
+ .dispclk_dppclk_vco_speed_mhz = 3850,
+ .xfc_bus_transport_time_us = 20,
+ .xfc_xbuf_latency_tolerance_us = 4,
+ .use_urgent_burst_bw = 0
+};
+
+struct _vcs_dpi_soc_bounding_box_st dcn2_0_nv12_soc = { 0 };
+
+struct _vcs_dpi_ip_params_st dcn2_1_ip = {
+ .odm_capable = 1,
+ .gpuvm_enable = 1,
+ .hostvm_enable = 1,
+ .gpuvm_max_page_table_levels = 1,
+ .hostvm_max_page_table_levels = 4,
+ .hostvm_cached_page_table_levels = 2,
+ .num_dsc = 3,
+ .rob_buffer_size_kbytes = 168,
+ .det_buffer_size_kbytes = 164,
+ .dpte_buffer_size_in_pte_reqs_luma = 44,
+ .dpte_buffer_size_in_pte_reqs_chroma = 42,//todo
+ .dpp_output_buffer_pixels = 2560,
+ .opp_output_buffer_lines = 1,
+ .pixel_chunk_size_kbytes = 8,
+ .pte_enable = 1,
+ .max_page_table_levels = 4,
+ .pte_chunk_size_kbytes = 2,
+ .meta_chunk_size_kbytes = 2,
+ .min_meta_chunk_size_bytes = 256,
+ .writeback_chunk_size_kbytes = 2,
+ .line_buffer_size_bits = 789504,
+ .is_line_buffer_bpp_fixed = 0,
+ .line_buffer_fixed_bpp = 0,
+ .dcc_supported = true,
+ .max_line_buffer_lines = 12,
+ .writeback_luma_buffer_size_kbytes = 12,
+ .writeback_chroma_buffer_size_kbytes = 8,
+ .writeback_chroma_line_buffer_width_pixels = 4,
+ .writeback_max_hscl_ratio = 1,
+ .writeback_max_vscl_ratio = 1,
+ .writeback_min_hscl_ratio = 1,
+ .writeback_min_vscl_ratio = 1,
+ .writeback_max_hscl_taps = 12,
+ .writeback_max_vscl_taps = 12,
+ .writeback_line_buffer_luma_buffer_size = 0,
+ .writeback_line_buffer_chroma_buffer_size = 14643,
+ .cursor_buffer_size = 8,
+ .cursor_chunk_size = 2,
+ .max_num_otg = 4,
+ .max_num_dpp = 4,
+ .max_num_wb = 1,
+ .max_dchub_pscl_bw_pix_per_clk = 4,
+ .max_pscl_lb_bw_pix_per_clk = 2,
+ .max_lb_vscl_bw_pix_per_clk = 4,
+ .max_vscl_hscl_bw_pix_per_clk = 4,
+ .max_hscl_ratio = 4,
+ .max_vscl_ratio = 4,
+ .hscl_mults = 4,
+ .vscl_mults = 4,
+ .max_hscl_taps = 8,
+ .max_vscl_taps = 8,
+ .dispclk_ramp_margin_percent = 1,
+ .underscan_factor = 1.10,
+ .min_vblank_lines = 32, //
+ .dppclk_delay_subtotal = 77, //
+ .dppclk_delay_scl_lb_only = 16,
+ .dppclk_delay_scl = 50,
+ .dppclk_delay_cnvc_formatter = 8,
+ .dppclk_delay_cnvc_cursor = 6,
+ .dispclk_delay_subtotal = 87, //
+ .dcfclk_cstate_latency = 10, // SRExitTime
+ .max_inter_dcn_tile_repeaters = 8,
+
+ .xfc_supported = false,
+ .xfc_fill_bw_overhead_percent = 10.0,
+ .xfc_fill_constant_bytes = 0,
+ .ptoi_supported = 0,
+ .number_of_cursors = 1,
+};
+
+struct _vcs_dpi_soc_bounding_box_st dcn2_1_soc = {
+ .clock_limits = {
+ {
+ .state = 0,
+ .dcfclk_mhz = 400.0,
+ .fabricclk_mhz = 400.0,
+ .dispclk_mhz = 600.0,
+ .dppclk_mhz = 400.00,
+ .phyclk_mhz = 600.0,
+ .socclk_mhz = 278.0,
+ .dscclk_mhz = 205.67,
+ .dram_speed_mts = 1600.0,
+ },
+ {
+ .state = 1,
+ .dcfclk_mhz = 464.52,
+ .fabricclk_mhz = 800.0,
+ .dispclk_mhz = 654.55,
+ .dppclk_mhz = 626.09,
+ .phyclk_mhz = 600.0,
+ .socclk_mhz = 278.0,
+ .dscclk_mhz = 205.67,
+ .dram_speed_mts = 1600.0,
+ },
+ {
+ .state = 2,
+ .dcfclk_mhz = 514.29,
+ .fabricclk_mhz = 933.0,
+ .dispclk_mhz = 757.89,
+ .dppclk_mhz = 685.71,
+ .phyclk_mhz = 600.0,
+ .socclk_mhz = 278.0,
+ .dscclk_mhz = 287.67,
+ .dram_speed_mts = 1866.0,
+ },
+ {
+ .state = 3,
+ .dcfclk_mhz = 576.00,
+ .fabricclk_mhz = 1067.0,
+ .dispclk_mhz = 847.06,
+ .dppclk_mhz = 757.89,
+ .phyclk_mhz = 600.0,
+ .socclk_mhz = 715.0,
+ .dscclk_mhz = 318.334,
+ .dram_speed_mts = 2134.0,
+ },
+ {
+ .state = 4,
+ .dcfclk_mhz = 626.09,
+ .fabricclk_mhz = 1200.0,
+ .dispclk_mhz = 900.00,
+ .dppclk_mhz = 847.06,
+ .phyclk_mhz = 810.0,
+ .socclk_mhz = 953.0,
+ .dscclk_mhz = 489.0,
+ .dram_speed_mts = 2400.0,
+ },
+ {
+ .state = 5,
+ .dcfclk_mhz = 685.71,
+ .fabricclk_mhz = 1333.0,
+ .dispclk_mhz = 1028.57,
+ .dppclk_mhz = 960.00,
+ .phyclk_mhz = 810.0,
+ .socclk_mhz = 278.0,
+ .dscclk_mhz = 287.67,
+ .dram_speed_mts = 2666.0,
+ },
+ {
+ .state = 6,
+ .dcfclk_mhz = 757.89,
+ .fabricclk_mhz = 1467.0,
+ .dispclk_mhz = 1107.69,
+ .dppclk_mhz = 1028.57,
+ .phyclk_mhz = 810.0,
+ .socclk_mhz = 715.0,
+ .dscclk_mhz = 318.334,
+ .dram_speed_mts = 3200.0,
+ },
+ {
+ .state = 7,
+ .dcfclk_mhz = 847.06,
+ .fabricclk_mhz = 1600.0,
+ .dispclk_mhz = 1395.0,
+ .dppclk_mhz = 1285.00,
+ .phyclk_mhz = 1325.0,
+ .socclk_mhz = 953.0,
+ .dscclk_mhz = 489.0,
+ .dram_speed_mts = 4266.0,
+ },
+ /*Extra state, no dispclk ramping*/
+ {
+ .state = 8,
+ .dcfclk_mhz = 847.06,
+ .fabricclk_mhz = 1600.0,
+ .dispclk_mhz = 1395.0,
+ .dppclk_mhz = 1285.0,
+ .phyclk_mhz = 1325.0,
+ .socclk_mhz = 953.0,
+ .dscclk_mhz = 489.0,
+ .dram_speed_mts = 4266.0,
+ },
+
+ },
+
+ .sr_exit_time_us = 12.5,
+ .sr_enter_plus_exit_time_us = 17.0,
+ .urgent_latency_us = 4.0,
+ .urgent_latency_pixel_data_only_us = 4.0,
+ .urgent_latency_pixel_mixed_with_vm_data_us = 4.0,
+ .urgent_latency_vm_data_only_us = 4.0,
+ .urgent_out_of_order_return_per_channel_pixel_only_bytes = 4096,
+ .urgent_out_of_order_return_per_channel_pixel_and_vm_bytes = 4096,
+ .urgent_out_of_order_return_per_channel_vm_only_bytes = 4096,
+ .pct_ideal_dram_sdp_bw_after_urgent_pixel_only = 80.0,
+ .pct_ideal_dram_sdp_bw_after_urgent_pixel_and_vm = 75.0,
+ .pct_ideal_dram_sdp_bw_after_urgent_vm_only = 40.0,
+ .max_avg_sdp_bw_use_normal_percent = 60.0,
+ .max_avg_dram_bw_use_normal_percent = 100.0,
+ .writeback_latency_us = 12.0,
+ .max_request_size_bytes = 256,
+ .dram_channel_width_bytes = 4,
+ .fabric_datapath_to_dcn_data_return_bytes = 32,
+ .dcn_downspread_percent = 0.5,
+ .downspread_percent = 0.38,
+ .dram_page_open_time_ns = 50.0,
+ .dram_rw_turnaround_time_ns = 17.5,
+ .dram_return_buffer_per_channel_bytes = 8192,
+ .round_trip_ping_latency_dcfclk_cycles = 128,
+ .urgent_out_of_order_return_per_channel_bytes = 4096,
+ .channel_interleave_bytes = 256,
+ .num_banks = 8,
+ .num_chans = 4,
+ .vmm_page_size_bytes = 4096,
+ .dram_clock_change_latency_us = 23.84,
+ .return_bus_width_bytes = 64,
+ .dispclk_dppclk_vco_speed_mhz = 3600,
+ .xfc_bus_transport_time_us = 4,
+ .xfc_xbuf_latency_tolerance_us = 4,
+ .use_urgent_burst_bw = 1,
+ .num_states = 8
+};
+
void dcn20_populate_dml_writeback_from_context(struct dc *dc,
struct resource_context *res_ctx,
display_e2e_pipe_params_st *pipes)
@@ -100,3 +689,1340 @@ void dcn20_populate_dml_writeback_from_context(struct dc *dc,
pipe_cnt++;
}
}
+
+void dcn20_fpu_set_wb_arb_params(struct mcif_arb_params *wb_arb_params,
+ struct dc_state *context,
+ display_e2e_pipe_params_st *pipes,
+ int pipe_cnt, int i)
+{
+ int k;
+
+ dc_assert_fp_enabled();
+
+ for (k = 0; k < sizeof(wb_arb_params->cli_watermark)/sizeof(wb_arb_params->cli_watermark[0]); k++) {
+ wb_arb_params->cli_watermark[k] = get_wm_writeback_urgent(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
+ wb_arb_params->pstate_watermark[k] = get_wm_writeback_dram_clock_change(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
+ }
+ wb_arb_params->time_per_pixel = 16.0 * 1000 / (context->res_ctx.pipe_ctx[i].stream->phy_pix_clk / 1000); /* 4 bit fraction, ms */
+}
+
+static bool is_dtbclk_required(struct dc *dc, struct dc_state *context)
+{
+ int i;
+ for (i = 0; i < dc->res_pool->pipe_count; i++) {
+ if (!context->res_ctx.pipe_ctx[i].stream)
+ continue;
+ if (is_dp_128b_132b_signal(&context->res_ctx.pipe_ctx[i]))
+ return true;
+ }
+ return false;
+}
+
+static enum dcn_zstate_support_state decide_zstate_support(struct dc *dc, struct dc_state *context)
+{
+ int plane_count;
+ int i;
+
+ plane_count = 0;
+ for (i = 0; i < dc->res_pool->pipe_count; i++) {
+ if (context->res_ctx.pipe_ctx[i].plane_state)
+ plane_count++;
+ }
+
+ /*
+ * Z9 and Z10 allowed cases:
+ * 1. 0 Planes enabled
+ * 2. single eDP, on link 0, 1 plane and stutter period > 5ms
+ * Z10 only cases:
+ * 1. single eDP, on link 0, 1 plane and stutter period >= 5ms
+ * Zstate not allowed cases:
+ * 1. Everything else
+ */
+ if (plane_count == 0)
+ return DCN_ZSTATE_SUPPORT_ALLOW;
+ else if (context->stream_count == 1 && context->streams[0]->signal == SIGNAL_TYPE_EDP) {
+ struct dc_link *link = context->streams[0]->sink->link;
+ struct dc_stream_status *stream_status = &context->stream_status[0];
+
+ /* zstate only supported on PWRSEQ0 and when there's <2 planes*/
+ if (link->link_index != 0 || stream_status->plane_count > 1)
+ return DCN_ZSTATE_SUPPORT_DISALLOW;
+
+ if (context->bw_ctx.dml.vba.StutterPeriod > 5000.0)
+ return DCN_ZSTATE_SUPPORT_ALLOW;
+ else if (link->psr_settings.psr_version == DC_PSR_VERSION_1 && !dc->debug.disable_psr)
+ return DCN_ZSTATE_SUPPORT_ALLOW_Z10_ONLY;
+ else
+ return DCN_ZSTATE_SUPPORT_DISALLOW;
+ } else
+ return DCN_ZSTATE_SUPPORT_DISALLOW;
+}
+
+void dcn20_calculate_dlg_params(
+ struct dc *dc, struct dc_state *context,
+ display_e2e_pipe_params_st *pipes,
+ int pipe_cnt,
+ int vlevel)
+{
+ int i, pipe_idx;
+
+ dc_assert_fp_enabled();
+
+ /* Writeback MCIF_WB arbitration parameters */
+ dc->res_pool->funcs->set_mcif_arb_params(dc, context, pipes, pipe_cnt);
+
+ context->bw_ctx.bw.dcn.clk.dispclk_khz = context->bw_ctx.dml.vba.DISPCLK * 1000;
+ context->bw_ctx.bw.dcn.clk.dcfclk_khz = context->bw_ctx.dml.vba.DCFCLK * 1000;
+ context->bw_ctx.bw.dcn.clk.socclk_khz = context->bw_ctx.dml.vba.SOCCLK * 1000;
+ context->bw_ctx.bw.dcn.clk.dramclk_khz = context->bw_ctx.dml.vba.DRAMSpeed * 1000 / 16;
+
+ if (dc->debug.min_dram_clk_khz > context->bw_ctx.bw.dcn.clk.dramclk_khz)
+ context->bw_ctx.bw.dcn.clk.dramclk_khz = dc->debug.min_dram_clk_khz;
+
+ context->bw_ctx.bw.dcn.clk.dcfclk_deep_sleep_khz = context->bw_ctx.dml.vba.DCFCLKDeepSleep * 1000;
+ context->bw_ctx.bw.dcn.clk.fclk_khz = context->bw_ctx.dml.vba.FabricClock * 1000;
+ context->bw_ctx.bw.dcn.clk.p_state_change_support =
+ context->bw_ctx.dml.vba.DRAMClockChangeSupport[vlevel][context->bw_ctx.dml.vba.maxMpcComb]
+ != dm_dram_clock_change_unsupported;
+ context->bw_ctx.bw.dcn.clk.dppclk_khz = 0;
+
+ context->bw_ctx.bw.dcn.clk.zstate_support = decide_zstate_support(dc, context);
+
+ context->bw_ctx.bw.dcn.clk.dtbclk_en = is_dtbclk_required(dc, context);
+
+ if (context->bw_ctx.bw.dcn.clk.dispclk_khz < dc->debug.min_disp_clk_khz)
+ context->bw_ctx.bw.dcn.clk.dispclk_khz = dc->debug.min_disp_clk_khz;
+
+ for (i = 0, pipe_idx = 0; i < dc->res_pool->pipe_count; i++) {
+ if (!context->res_ctx.pipe_ctx[i].stream)
+ continue;
+ pipes[pipe_idx].pipe.dest.vstartup_start = get_vstartup(&context->bw_ctx.dml, pipes, pipe_cnt, pipe_idx);
+ pipes[pipe_idx].pipe.dest.vupdate_offset = get_vupdate_offset(&context->bw_ctx.dml, pipes, pipe_cnt, pipe_idx);
+ pipes[pipe_idx].pipe.dest.vupdate_width = get_vupdate_width(&context->bw_ctx.dml, pipes, pipe_cnt, pipe_idx);
+ pipes[pipe_idx].pipe.dest.vready_offset = get_vready_offset(&context->bw_ctx.dml, pipes, pipe_cnt, pipe_idx);
+ context->res_ctx.pipe_ctx[i].det_buffer_size_kb = context->bw_ctx.dml.ip.det_buffer_size_kbytes;
+ context->res_ctx.pipe_ctx[i].unbounded_req = pipes[pipe_idx].pipe.src.unbounded_req_mode;
+
+ if (context->bw_ctx.bw.dcn.clk.dppclk_khz < pipes[pipe_idx].clks_cfg.dppclk_mhz * 1000)
+ context->bw_ctx.bw.dcn.clk.dppclk_khz = pipes[pipe_idx].clks_cfg.dppclk_mhz * 1000;
+ context->res_ctx.pipe_ctx[i].plane_res.bw.dppclk_khz =
+ pipes[pipe_idx].clks_cfg.dppclk_mhz * 1000;
+ context->res_ctx.pipe_ctx[i].pipe_dlg_param = pipes[pipe_idx].pipe.dest;
+ pipe_idx++;
+ }
+ /*save a original dppclock copy*/
+ context->bw_ctx.bw.dcn.clk.bw_dppclk_khz = context->bw_ctx.bw.dcn.clk.dppclk_khz;
+ context->bw_ctx.bw.dcn.clk.bw_dispclk_khz = context->bw_ctx.bw.dcn.clk.dispclk_khz;
+ context->bw_ctx.bw.dcn.clk.max_supported_dppclk_khz = context->bw_ctx.dml.soc.clock_limits[vlevel].dppclk_mhz * 1000;
+ context->bw_ctx.bw.dcn.clk.max_supported_dispclk_khz = context->bw_ctx.dml.soc.clock_limits[vlevel].dispclk_mhz * 1000;
+
+ context->bw_ctx.bw.dcn.compbuf_size_kb = context->bw_ctx.dml.ip.config_return_buffer_size_in_kbytes
+ - context->bw_ctx.dml.ip.det_buffer_size_kbytes * pipe_idx;
+
+ for (i = 0, pipe_idx = 0; i < dc->res_pool->pipe_count; i++) {
+ bool cstate_en = context->bw_ctx.dml.vba.PrefetchMode[vlevel][context->bw_ctx.dml.vba.maxMpcComb] != 2;
+
+ if (!context->res_ctx.pipe_ctx[i].stream)
+ continue;
+
+ if (dc->ctx->dce_version == DCN_VERSION_2_01)
+ cstate_en = false;
+
+ context->bw_ctx.dml.funcs.rq_dlg_get_dlg_reg(&context->bw_ctx.dml,
+ &context->res_ctx.pipe_ctx[i].dlg_regs,
+ &context->res_ctx.pipe_ctx[i].ttu_regs,
+ pipes,
+ pipe_cnt,
+ pipe_idx,
+ cstate_en,
+ context->bw_ctx.bw.dcn.clk.p_state_change_support,
+ false, false, true);
+
+ context->bw_ctx.dml.funcs.rq_dlg_get_rq_reg(&context->bw_ctx.dml,
+ &context->res_ctx.pipe_ctx[i].rq_regs,
+ &pipes[pipe_idx].pipe);
+ pipe_idx++;
+ }
+}
+
+static void swizzle_to_dml_params(
+ enum swizzle_mode_values swizzle,
+ unsigned int *sw_mode)
+{
+ switch (swizzle) {
+ case DC_SW_LINEAR:
+ *sw_mode = dm_sw_linear;
+ break;
+ case DC_SW_4KB_S:
+ *sw_mode = dm_sw_4kb_s;
+ break;
+ case DC_SW_4KB_S_X:
+ *sw_mode = dm_sw_4kb_s_x;
+ break;
+ case DC_SW_4KB_D:
+ *sw_mode = dm_sw_4kb_d;
+ break;
+ case DC_SW_4KB_D_X:
+ *sw_mode = dm_sw_4kb_d_x;
+ break;
+ case DC_SW_64KB_S:
+ *sw_mode = dm_sw_64kb_s;
+ break;
+ case DC_SW_64KB_S_X:
+ *sw_mode = dm_sw_64kb_s_x;
+ break;
+ case DC_SW_64KB_S_T:
+ *sw_mode = dm_sw_64kb_s_t;
+ break;
+ case DC_SW_64KB_D:
+ *sw_mode = dm_sw_64kb_d;
+ break;
+ case DC_SW_64KB_D_X:
+ *sw_mode = dm_sw_64kb_d_x;
+ break;
+ case DC_SW_64KB_D_T:
+ *sw_mode = dm_sw_64kb_d_t;
+ break;
+ case DC_SW_64KB_R_X:
+ *sw_mode = dm_sw_64kb_r_x;
+ break;
+ case DC_SW_VAR_S:
+ *sw_mode = dm_sw_var_s;
+ break;
+ case DC_SW_VAR_S_X:
+ *sw_mode = dm_sw_var_s_x;
+ break;
+ case DC_SW_VAR_D:
+ *sw_mode = dm_sw_var_d;
+ break;
+ case DC_SW_VAR_D_X:
+ *sw_mode = dm_sw_var_d_x;
+ break;
+ case DC_SW_VAR_R_X:
+ *sw_mode = dm_sw_var_r_x;
+ break;
+ default:
+ ASSERT(0); /* Not supported */
+ break;
+ }
+}
+
+int dcn20_populate_dml_pipes_from_context(
+ struct dc *dc,
+ struct dc_state *context,
+ display_e2e_pipe_params_st *pipes,
+ bool fast_validate)
+{
+ int pipe_cnt, i;
+ bool synchronized_vblank = true;
+ struct resource_context *res_ctx = &context->res_ctx;
+
+ dc_assert_fp_enabled();
+
+ for (i = 0, pipe_cnt = -1; i < dc->res_pool->pipe_count; i++) {
+ if (!res_ctx->pipe_ctx[i].stream)
+ continue;
+
+ if (pipe_cnt < 0) {
+ pipe_cnt = i;
+ continue;
+ }
+
+ if (res_ctx->pipe_ctx[pipe_cnt].stream == res_ctx->pipe_ctx[i].stream)
+ continue;
+
+ if (dc->debug.disable_timing_sync ||
+ (!resource_are_streams_timing_synchronizable(
+ res_ctx->pipe_ctx[pipe_cnt].stream,
+ res_ctx->pipe_ctx[i].stream) &&
+ !resource_are_vblanks_synchronizable(
+ res_ctx->pipe_ctx[pipe_cnt].stream,
+ res_ctx->pipe_ctx[i].stream))) {
+ synchronized_vblank = false;
+ break;
+ }
+ }
+
+ for (i = 0, pipe_cnt = 0; i < dc->res_pool->pipe_count; i++) {
+ struct dc_crtc_timing *timing = &res_ctx->pipe_ctx[i].stream->timing;
+ unsigned int v_total;
+ unsigned int front_porch;
+ int output_bpc;
+ struct audio_check aud_check = {0};
+
+ if (!res_ctx->pipe_ctx[i].stream)
+ continue;
+
+ v_total = timing->v_total;
+ front_porch = timing->v_front_porch;
+
+ /* todo:
+ pipes[pipe_cnt].pipe.src.dynamic_metadata_enable = 0;
+ pipes[pipe_cnt].pipe.src.dcc = 0;
+ pipes[pipe_cnt].pipe.src.vm = 0;*/
+
+ pipes[pipe_cnt].clks_cfg.refclk_mhz = dc->res_pool->ref_clocks.dchub_ref_clock_inKhz / 1000.0;
+
+ pipes[pipe_cnt].dout.dsc_enable = res_ctx->pipe_ctx[i].stream->timing.flags.DSC;
+ /* todo: rotation?*/
+ pipes[pipe_cnt].dout.dsc_slices = res_ctx->pipe_ctx[i].stream->timing.dsc_cfg.num_slices_h;
+ if (res_ctx->pipe_ctx[i].stream->use_dynamic_meta) {
+ pipes[pipe_cnt].pipe.src.dynamic_metadata_enable = true;
+ /* 1/2 vblank */
+ pipes[pipe_cnt].pipe.src.dynamic_metadata_lines_before_active =
+ (v_total - timing->v_addressable
+ - timing->v_border_top - timing->v_border_bottom) / 2;
+ /* 36 bytes dp, 32 hdmi */
+ pipes[pipe_cnt].pipe.src.dynamic_metadata_xmit_bytes =
+ dc_is_dp_signal(res_ctx->pipe_ctx[i].stream->signal) ? 36 : 32;
+ }
+ pipes[pipe_cnt].pipe.src.dcc = false;
+ pipes[pipe_cnt].pipe.src.dcc_rate = 1;
+ pipes[pipe_cnt].pipe.dest.synchronized_vblank_all_planes = synchronized_vblank;
+ pipes[pipe_cnt].pipe.dest.hblank_start = timing->h_total - timing->h_front_porch;
+ pipes[pipe_cnt].pipe.dest.hblank_end = pipes[pipe_cnt].pipe.dest.hblank_start
+ - timing->h_addressable
+ - timing->h_border_left
+ - timing->h_border_right;
+ pipes[pipe_cnt].pipe.dest.vblank_start = v_total - front_porch;
+ pipes[pipe_cnt].pipe.dest.vblank_end = pipes[pipe_cnt].pipe.dest.vblank_start
+ - timing->v_addressable
+ - timing->v_border_top
+ - timing->v_border_bottom;
+ pipes[pipe_cnt].pipe.dest.htotal = timing->h_total;
+ pipes[pipe_cnt].pipe.dest.vtotal = v_total;
+ pipes[pipe_cnt].pipe.dest.hactive =
+ timing->h_addressable + timing->h_border_left + timing->h_border_right;
+ pipes[pipe_cnt].pipe.dest.vactive =
+ timing->v_addressable + timing->v_border_top + timing->v_border_bottom;
+ pipes[pipe_cnt].pipe.dest.interlaced = timing->flags.INTERLACE;
+ pipes[pipe_cnt].pipe.dest.pixel_rate_mhz = timing->pix_clk_100hz/10000.0;
+ if (timing->timing_3d_format == TIMING_3D_FORMAT_HW_FRAME_PACKING)
+ pipes[pipe_cnt].pipe.dest.pixel_rate_mhz *= 2;
+ pipes[pipe_cnt].pipe.dest.otg_inst = res_ctx->pipe_ctx[i].stream_res.tg->inst;
+ pipes[pipe_cnt].dout.dp_lanes = 4;
+ pipes[pipe_cnt].dout.is_virtual = 0;
+ pipes[pipe_cnt].pipe.dest.vtotal_min = res_ctx->pipe_ctx[i].stream->adjust.v_total_min;
+ pipes[pipe_cnt].pipe.dest.vtotal_max = res_ctx->pipe_ctx[i].stream->adjust.v_total_max;
+ switch (get_num_odm_splits(&res_ctx->pipe_ctx[i])) {
+ case 1:
+ pipes[pipe_cnt].pipe.dest.odm_combine = dm_odm_combine_mode_2to1;
+ break;
+ case 3:
+ pipes[pipe_cnt].pipe.dest.odm_combine = dm_odm_combine_mode_4to1;
+ break;
+ default:
+ pipes[pipe_cnt].pipe.dest.odm_combine = dm_odm_combine_mode_disabled;
+ }
+ pipes[pipe_cnt].pipe.src.hsplit_grp = res_ctx->pipe_ctx[i].pipe_idx;
+ if (res_ctx->pipe_ctx[i].top_pipe && res_ctx->pipe_ctx[i].top_pipe->plane_state
+ == res_ctx->pipe_ctx[i].plane_state) {
+ struct pipe_ctx *first_pipe = res_ctx->pipe_ctx[i].top_pipe;
+ int split_idx = 0;
+
+ while (first_pipe->top_pipe && first_pipe->top_pipe->plane_state
+ == res_ctx->pipe_ctx[i].plane_state) {
+ first_pipe = first_pipe->top_pipe;
+ split_idx++;
+ }
+ /* Treat 4to1 mpc combine as an mpo of 2 2-to-1 combines */
+ if (split_idx == 0)
+ pipes[pipe_cnt].pipe.src.hsplit_grp = first_pipe->pipe_idx;
+ else if (split_idx == 1)
+ pipes[pipe_cnt].pipe.src.hsplit_grp = res_ctx->pipe_ctx[i].pipe_idx;
+ else if (split_idx == 2)
+ pipes[pipe_cnt].pipe.src.hsplit_grp = res_ctx->pipe_ctx[i].top_pipe->pipe_idx;
+ } else if (res_ctx->pipe_ctx[i].prev_odm_pipe) {
+ struct pipe_ctx *first_pipe = res_ctx->pipe_ctx[i].prev_odm_pipe;
+
+ while (first_pipe->prev_odm_pipe)
+ first_pipe = first_pipe->prev_odm_pipe;
+ pipes[pipe_cnt].pipe.src.hsplit_grp = first_pipe->pipe_idx;
+ }
+
+ switch (res_ctx->pipe_ctx[i].stream->signal) {
+ case SIGNAL_TYPE_DISPLAY_PORT_MST:
+ case SIGNAL_TYPE_DISPLAY_PORT:
+ pipes[pipe_cnt].dout.output_type = dm_dp;
+ break;
+ case SIGNAL_TYPE_EDP:
+ pipes[pipe_cnt].dout.output_type = dm_edp;
+ break;
+ case SIGNAL_TYPE_HDMI_TYPE_A:
+ case SIGNAL_TYPE_DVI_SINGLE_LINK:
+ case SIGNAL_TYPE_DVI_DUAL_LINK:
+ pipes[pipe_cnt].dout.output_type = dm_hdmi;
+ break;
+ default:
+ /* In case there is no signal, set dp with 4 lanes to allow max config */
+ pipes[pipe_cnt].dout.is_virtual = 1;
+ pipes[pipe_cnt].dout.output_type = dm_dp;
+ pipes[pipe_cnt].dout.dp_lanes = 4;
+ }
+
+ switch (res_ctx->pipe_ctx[i].stream->timing.display_color_depth) {
+ case COLOR_DEPTH_666:
+ output_bpc = 6;
+ break;
+ case COLOR_DEPTH_888:
+ output_bpc = 8;
+ break;
+ case COLOR_DEPTH_101010:
+ output_bpc = 10;
+ break;
+ case COLOR_DEPTH_121212:
+ output_bpc = 12;
+ break;
+ case COLOR_DEPTH_141414:
+ output_bpc = 14;
+ break;
+ case COLOR_DEPTH_161616:
+ output_bpc = 16;
+ break;
+ case COLOR_DEPTH_999:
+ output_bpc = 9;
+ break;
+ case COLOR_DEPTH_111111:
+ output_bpc = 11;
+ break;
+ default:
+ output_bpc = 8;
+ break;
+ }
+
+ switch (res_ctx->pipe_ctx[i].stream->timing.pixel_encoding) {
+ case PIXEL_ENCODING_RGB:
+ case PIXEL_ENCODING_YCBCR444:
+ pipes[pipe_cnt].dout.output_format = dm_444;
+ pipes[pipe_cnt].dout.output_bpp = output_bpc * 3;
+ break;
+ case PIXEL_ENCODING_YCBCR420:
+ pipes[pipe_cnt].dout.output_format = dm_420;
+ pipes[pipe_cnt].dout.output_bpp = (output_bpc * 3.0) / 2;
+ break;
+ case PIXEL_ENCODING_YCBCR422:
+ if (res_ctx->pipe_ctx[i].stream->timing.flags.DSC &&
+ !res_ctx->pipe_ctx[i].stream->timing.dsc_cfg.ycbcr422_simple)
+ pipes[pipe_cnt].dout.output_format = dm_n422;
+ else
+ pipes[pipe_cnt].dout.output_format = dm_s422;
+ pipes[pipe_cnt].dout.output_bpp = output_bpc * 2;
+ break;
+ default:
+ pipes[pipe_cnt].dout.output_format = dm_444;
+ pipes[pipe_cnt].dout.output_bpp = output_bpc * 3;
+ }
+
+ if (res_ctx->pipe_ctx[i].stream->timing.flags.DSC)
+ pipes[pipe_cnt].dout.output_bpp = res_ctx->pipe_ctx[i].stream->timing.dsc_cfg.bits_per_pixel / 16.0;
+
+ /* todo: default max for now, until there is logic reflecting this in dc*/
+ pipes[pipe_cnt].dout.dsc_input_bpc = 12;
+ /*fill up the audio sample rate (unit in kHz)*/
+ get_audio_check(&res_ctx->pipe_ctx[i].stream->audio_info, &aud_check);
+ pipes[pipe_cnt].dout.max_audio_sample_rate = aud_check.max_audiosample_rate / 1000;
+ /*
+ * For graphic plane, cursor number is 1, nv12 is 0
+ * bw calculations due to cursor on/off
+ */
+ if (res_ctx->pipe_ctx[i].plane_state &&
+ res_ctx->pipe_ctx[i].plane_state->address.type == PLN_ADDR_TYPE_VIDEO_PROGRESSIVE)
+ pipes[pipe_cnt].pipe.src.num_cursors = 0;
+ else
+ pipes[pipe_cnt].pipe.src.num_cursors = dc->dml.ip.number_of_cursors;
+
+ pipes[pipe_cnt].pipe.src.cur0_src_width = 256;
+ pipes[pipe_cnt].pipe.src.cur0_bpp = dm_cur_32bit;
+
+ if (!res_ctx->pipe_ctx[i].plane_state) {
+ pipes[pipe_cnt].pipe.src.is_hsplit = pipes[pipe_cnt].pipe.dest.odm_combine != dm_odm_combine_mode_disabled;
+ pipes[pipe_cnt].pipe.src.source_scan = dm_horz;
+ pipes[pipe_cnt].pipe.src.sw_mode = dm_sw_4kb_s;
+ pipes[pipe_cnt].pipe.src.macro_tile_size = dm_64k_tile;
+ pipes[pipe_cnt].pipe.src.viewport_width = timing->h_addressable;
+ if (pipes[pipe_cnt].pipe.src.viewport_width > 1920)
+ pipes[pipe_cnt].pipe.src.viewport_width = 1920;
+ pipes[pipe_cnt].pipe.src.viewport_height = timing->v_addressable;
+ if (pipes[pipe_cnt].pipe.src.viewport_height > 1080)
+ pipes[pipe_cnt].pipe.src.viewport_height = 1080;
+ pipes[pipe_cnt].pipe.src.surface_height_y = pipes[pipe_cnt].pipe.src.viewport_height;
+ pipes[pipe_cnt].pipe.src.surface_width_y = pipes[pipe_cnt].pipe.src.viewport_width;
+ pipes[pipe_cnt].pipe.src.surface_height_c = pipes[pipe_cnt].pipe.src.viewport_height;
+ pipes[pipe_cnt].pipe.src.surface_width_c = pipes[pipe_cnt].pipe.src.viewport_width;
+ pipes[pipe_cnt].pipe.src.data_pitch = ((pipes[pipe_cnt].pipe.src.viewport_width + 255) / 256) * 256;
+ pipes[pipe_cnt].pipe.src.source_format = dm_444_32;
+ pipes[pipe_cnt].pipe.dest.recout_width = pipes[pipe_cnt].pipe.src.viewport_width; /*vp_width/hratio*/
+ pipes[pipe_cnt].pipe.dest.recout_height = pipes[pipe_cnt].pipe.src.viewport_height; /*vp_height/vratio*/
+ pipes[pipe_cnt].pipe.dest.full_recout_width = pipes[pipe_cnt].pipe.dest.recout_width; /*when is_hsplit != 1*/
+ pipes[pipe_cnt].pipe.dest.full_recout_height = pipes[pipe_cnt].pipe.dest.recout_height; /*when is_hsplit != 1*/
+ pipes[pipe_cnt].pipe.scale_ratio_depth.lb_depth = dm_lb_16;
+ pipes[pipe_cnt].pipe.scale_ratio_depth.hscl_ratio = 1.0;
+ pipes[pipe_cnt].pipe.scale_ratio_depth.vscl_ratio = 1.0;
+ pipes[pipe_cnt].pipe.scale_ratio_depth.scl_enable = 0; /*Lb only or Full scl*/
+ pipes[pipe_cnt].pipe.scale_taps.htaps = 1;
+ pipes[pipe_cnt].pipe.scale_taps.vtaps = 1;
+ pipes[pipe_cnt].pipe.dest.vtotal_min = v_total;
+ pipes[pipe_cnt].pipe.dest.vtotal_max = v_total;
+
+ if (pipes[pipe_cnt].pipe.dest.odm_combine == dm_odm_combine_mode_2to1) {
+ pipes[pipe_cnt].pipe.src.viewport_width /= 2;
+ pipes[pipe_cnt].pipe.dest.recout_width /= 2;
+ } else if (pipes[pipe_cnt].pipe.dest.odm_combine == dm_odm_combine_mode_4to1) {
+ pipes[pipe_cnt].pipe.src.viewport_width /= 4;
+ pipes[pipe_cnt].pipe.dest.recout_width /= 4;
+ }
+ } else {
+ struct dc_plane_state *pln = res_ctx->pipe_ctx[i].plane_state;
+ struct scaler_data *scl = &res_ctx->pipe_ctx[i].plane_res.scl_data;
+
+ pipes[pipe_cnt].pipe.src.immediate_flip = pln->flip_immediate;
+ pipes[pipe_cnt].pipe.src.is_hsplit = (res_ctx->pipe_ctx[i].bottom_pipe && res_ctx->pipe_ctx[i].bottom_pipe->plane_state == pln)
+ || (res_ctx->pipe_ctx[i].top_pipe && res_ctx->pipe_ctx[i].top_pipe->plane_state == pln)
+ || pipes[pipe_cnt].pipe.dest.odm_combine != dm_odm_combine_mode_disabled;
+
+ /* stereo is not split */
+ if (pln->stereo_format == PLANE_STEREO_FORMAT_SIDE_BY_SIDE ||
+ pln->stereo_format == PLANE_STEREO_FORMAT_TOP_AND_BOTTOM) {
+ pipes[pipe_cnt].pipe.src.is_hsplit = false;
+ pipes[pipe_cnt].pipe.src.hsplit_grp = res_ctx->pipe_ctx[i].pipe_idx;
+ }
+
+ pipes[pipe_cnt].pipe.src.source_scan = pln->rotation == ROTATION_ANGLE_90
+ || pln->rotation == ROTATION_ANGLE_270 ? dm_vert : dm_horz;
+ pipes[pipe_cnt].pipe.src.viewport_y_y = scl->viewport.y;
+ pipes[pipe_cnt].pipe.src.viewport_y_c = scl->viewport_c.y;
+ pipes[pipe_cnt].pipe.src.viewport_width = scl->viewport.width;
+ pipes[pipe_cnt].pipe.src.viewport_width_c = scl->viewport_c.width;
+ pipes[pipe_cnt].pipe.src.viewport_height = scl->viewport.height;
+ pipes[pipe_cnt].pipe.src.viewport_height_c = scl->viewport_c.height;
+ pipes[pipe_cnt].pipe.src.viewport_width_max = pln->src_rect.width;
+ pipes[pipe_cnt].pipe.src.viewport_height_max = pln->src_rect.height;
+ pipes[pipe_cnt].pipe.src.surface_width_y = pln->plane_size.surface_size.width;
+ pipes[pipe_cnt].pipe.src.surface_height_y = pln->plane_size.surface_size.height;
+ pipes[pipe_cnt].pipe.src.surface_width_c = pln->plane_size.chroma_size.width;
+ pipes[pipe_cnt].pipe.src.surface_height_c = pln->plane_size.chroma_size.height;
+ if (pln->format == SURFACE_PIXEL_FORMAT_GRPH_RGBE_ALPHA
+ || pln->format >= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN) {
+ pipes[pipe_cnt].pipe.src.data_pitch = pln->plane_size.surface_pitch;
+ pipes[pipe_cnt].pipe.src.data_pitch_c = pln->plane_size.chroma_pitch;
+ pipes[pipe_cnt].pipe.src.meta_pitch = pln->dcc.meta_pitch;
+ pipes[pipe_cnt].pipe.src.meta_pitch_c = pln->dcc.meta_pitch_c;
+ } else {
+ pipes[pipe_cnt].pipe.src.data_pitch = pln->plane_size.surface_pitch;
+ pipes[pipe_cnt].pipe.src.meta_pitch = pln->dcc.meta_pitch;
+ }
+ pipes[pipe_cnt].pipe.src.dcc = pln->dcc.enable;
+ pipes[pipe_cnt].pipe.dest.recout_width = scl->recout.width;
+ pipes[pipe_cnt].pipe.dest.recout_height = scl->recout.height;
+ pipes[pipe_cnt].pipe.dest.full_recout_height = scl->recout.height;
+ pipes[pipe_cnt].pipe.dest.full_recout_width = scl->recout.width;
+ if (pipes[pipe_cnt].pipe.dest.odm_combine == dm_odm_combine_mode_2to1)
+ pipes[pipe_cnt].pipe.dest.full_recout_width *= 2;
+ else if (pipes[pipe_cnt].pipe.dest.odm_combine == dm_odm_combine_mode_4to1)
+ pipes[pipe_cnt].pipe.dest.full_recout_width *= 4;
+ else {
+ struct pipe_ctx *split_pipe = res_ctx->pipe_ctx[i].bottom_pipe;
+
+ while (split_pipe && split_pipe->plane_state == pln) {
+ pipes[pipe_cnt].pipe.dest.full_recout_width += split_pipe->plane_res.scl_data.recout.width;
+ split_pipe = split_pipe->bottom_pipe;
+ }
+ split_pipe = res_ctx->pipe_ctx[i].top_pipe;
+ while (split_pipe && split_pipe->plane_state == pln) {
+ pipes[pipe_cnt].pipe.dest.full_recout_width += split_pipe->plane_res.scl_data.recout.width;
+ split_pipe = split_pipe->top_pipe;
+ }
+ }
+
+ pipes[pipe_cnt].pipe.scale_ratio_depth.lb_depth = dm_lb_16;
+ pipes[pipe_cnt].pipe.scale_ratio_depth.hscl_ratio = (double) scl->ratios.horz.value / (1ULL<<32);
+ pipes[pipe_cnt].pipe.scale_ratio_depth.hscl_ratio_c = (double) scl->ratios.horz_c.value / (1ULL<<32);
+ pipes[pipe_cnt].pipe.scale_ratio_depth.vscl_ratio = (double) scl->ratios.vert.value / (1ULL<<32);
+ pipes[pipe_cnt].pipe.scale_ratio_depth.vscl_ratio_c = (double) scl->ratios.vert_c.value / (1ULL<<32);
+ pipes[pipe_cnt].pipe.scale_ratio_depth.scl_enable =
+ scl->ratios.vert.value != dc_fixpt_one.value
+ || scl->ratios.horz.value != dc_fixpt_one.value
+ || scl->ratios.vert_c.value != dc_fixpt_one.value
+ || scl->ratios.horz_c.value != dc_fixpt_one.value /*Lb only or Full scl*/
+ || dc->debug.always_scale; /*support always scale*/
+ pipes[pipe_cnt].pipe.scale_taps.htaps = scl->taps.h_taps;
+ pipes[pipe_cnt].pipe.scale_taps.htaps_c = scl->taps.h_taps_c;
+ pipes[pipe_cnt].pipe.scale_taps.vtaps = scl->taps.v_taps;
+ pipes[pipe_cnt].pipe.scale_taps.vtaps_c = scl->taps.v_taps_c;
+
+ pipes[pipe_cnt].pipe.src.macro_tile_size =
+ swizzle_mode_to_macro_tile_size(pln->tiling_info.gfx9.swizzle);
+ swizzle_to_dml_params(pln->tiling_info.gfx9.swizzle,
+ &pipes[pipe_cnt].pipe.src.sw_mode);
+
+ switch (pln->format) {
+ case SURFACE_PIXEL_FORMAT_VIDEO_420_YCbCr:
+ case SURFACE_PIXEL_FORMAT_VIDEO_420_YCrCb:
+ pipes[pipe_cnt].pipe.src.source_format = dm_420_8;
+ break;
+ case SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCbCr:
+ case SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCrCb:
+ pipes[pipe_cnt].pipe.src.source_format = dm_420_10;
+ break;
+ case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616:
+ case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616:
+ case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616F:
+ case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F:
+ pipes[pipe_cnt].pipe.src.source_format = dm_444_64;
+ break;
+ case SURFACE_PIXEL_FORMAT_GRPH_ARGB1555:
+ case SURFACE_PIXEL_FORMAT_GRPH_RGB565:
+ pipes[pipe_cnt].pipe.src.source_format = dm_444_16;
+ break;
+ case SURFACE_PIXEL_FORMAT_GRPH_PALETA_256_COLORS:
+ pipes[pipe_cnt].pipe.src.source_format = dm_444_8;
+ break;
+ case SURFACE_PIXEL_FORMAT_GRPH_RGBE_ALPHA:
+ pipes[pipe_cnt].pipe.src.source_format = dm_rgbe_alpha;
+ break;
+ default:
+ pipes[pipe_cnt].pipe.src.source_format = dm_444_32;
+ break;
+ }
+ }
+
+ pipe_cnt++;
+ }
+
+ /* populate writeback information */
+ DC_FP_START();
+ dc->res_pool->funcs->populate_dml_writeback_from_context(dc, res_ctx, pipes);
+ DC_FP_END();
+
+ return pipe_cnt;
+}
+
+void dcn20_calculate_wm(
+ struct dc *dc, struct dc_state *context,
+ display_e2e_pipe_params_st *pipes,
+ int *out_pipe_cnt,
+ int *pipe_split_from,
+ int vlevel,
+ bool fast_validate)
+{
+ int pipe_cnt, i, pipe_idx;
+
+ dc_assert_fp_enabled();
+
+ for (i = 0, pipe_idx = 0, pipe_cnt = 0; i < dc->res_pool->pipe_count; i++) {
+ if (!context->res_ctx.pipe_ctx[i].stream)
+ continue;
+
+ pipes[pipe_cnt].clks_cfg.refclk_mhz = dc->res_pool->ref_clocks.dchub_ref_clock_inKhz / 1000.0;
+ pipes[pipe_cnt].clks_cfg.dispclk_mhz = context->bw_ctx.dml.vba.RequiredDISPCLK[vlevel][context->bw_ctx.dml.vba.maxMpcComb];
+
+ if (pipe_split_from[i] < 0) {
+ pipes[pipe_cnt].clks_cfg.dppclk_mhz =
+ context->bw_ctx.dml.vba.RequiredDPPCLK[vlevel][context->bw_ctx.dml.vba.maxMpcComb][pipe_idx];
+ if (context->bw_ctx.dml.vba.BlendingAndTiming[pipe_idx] == pipe_idx)
+ pipes[pipe_cnt].pipe.dest.odm_combine =
+ context->bw_ctx.dml.vba.ODMCombineEnabled[pipe_idx];
+ else
+ pipes[pipe_cnt].pipe.dest.odm_combine = 0;
+ pipe_idx++;
+ } else {
+ pipes[pipe_cnt].clks_cfg.dppclk_mhz =
+ context->bw_ctx.dml.vba.RequiredDPPCLK[vlevel][context->bw_ctx.dml.vba.maxMpcComb][pipe_split_from[i]];
+ if (context->bw_ctx.dml.vba.BlendingAndTiming[pipe_split_from[i]] == pipe_split_from[i])
+ pipes[pipe_cnt].pipe.dest.odm_combine =
+ context->bw_ctx.dml.vba.ODMCombineEnabled[pipe_split_from[i]];
+ else
+ pipes[pipe_cnt].pipe.dest.odm_combine = 0;
+ }
+
+ if (dc->config.forced_clocks) {
+ pipes[pipe_cnt].clks_cfg.dispclk_mhz = context->bw_ctx.dml.soc.clock_limits[0].dispclk_mhz;
+ pipes[pipe_cnt].clks_cfg.dppclk_mhz = context->bw_ctx.dml.soc.clock_limits[0].dppclk_mhz;
+ }
+ if (dc->debug.min_disp_clk_khz > pipes[pipe_cnt].clks_cfg.dispclk_mhz * 1000)
+ pipes[pipe_cnt].clks_cfg.dispclk_mhz = dc->debug.min_disp_clk_khz / 1000.0;
+ if (dc->debug.min_dpp_clk_khz > pipes[pipe_cnt].clks_cfg.dppclk_mhz * 1000)
+ pipes[pipe_cnt].clks_cfg.dppclk_mhz = dc->debug.min_dpp_clk_khz / 1000.0;
+
+ pipe_cnt++;
+ }
+
+ if (pipe_cnt != pipe_idx) {
+ if (dc->res_pool->funcs->populate_dml_pipes)
+ pipe_cnt = dc->res_pool->funcs->populate_dml_pipes(dc,
+ context, pipes, fast_validate);
+ else
+ pipe_cnt = dcn20_populate_dml_pipes_from_context(dc,
+ context, pipes, fast_validate);
+ }
+
+ *out_pipe_cnt = pipe_cnt;
+
+ pipes[0].clks_cfg.voltage = vlevel;
+ pipes[0].clks_cfg.dcfclk_mhz = context->bw_ctx.dml.soc.clock_limits[vlevel].dcfclk_mhz;
+ pipes[0].clks_cfg.socclk_mhz = context->bw_ctx.dml.soc.clock_limits[vlevel].socclk_mhz;
+
+ /* only pipe 0 is read for voltage and dcf/soc clocks */
+ if (vlevel < 1) {
+ pipes[0].clks_cfg.voltage = 1;
+ pipes[0].clks_cfg.dcfclk_mhz = context->bw_ctx.dml.soc.clock_limits[1].dcfclk_mhz;
+ pipes[0].clks_cfg.socclk_mhz = context->bw_ctx.dml.soc.clock_limits[1].socclk_mhz;
+ }
+ context->bw_ctx.bw.dcn.watermarks.b.urgent_ns = get_wm_urgent(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
+ context->bw_ctx.bw.dcn.watermarks.b.cstate_pstate.cstate_enter_plus_exit_ns = get_wm_stutter_enter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
+ context->bw_ctx.bw.dcn.watermarks.b.cstate_pstate.cstate_exit_ns = get_wm_stutter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
+ context->bw_ctx.bw.dcn.watermarks.b.cstate_pstate.pstate_change_ns = get_wm_dram_clock_change(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
+ context->bw_ctx.bw.dcn.watermarks.b.pte_meta_urgent_ns = get_wm_memory_trip(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
+ context->bw_ctx.bw.dcn.watermarks.b.frac_urg_bw_nom = get_fraction_of_urgent_bandwidth(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
+ context->bw_ctx.bw.dcn.watermarks.b.frac_urg_bw_flip = get_fraction_of_urgent_bandwidth_imm_flip(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
+ context->bw_ctx.bw.dcn.watermarks.b.urgent_latency_ns = get_urgent_latency(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
+
+ if (vlevel < 2) {
+ pipes[0].clks_cfg.voltage = 2;
+ pipes[0].clks_cfg.dcfclk_mhz = context->bw_ctx.dml.soc.clock_limits[2].dcfclk_mhz;
+ pipes[0].clks_cfg.socclk_mhz = context->bw_ctx.dml.soc.clock_limits[2].socclk_mhz;
+ }
+ context->bw_ctx.bw.dcn.watermarks.c.urgent_ns = get_wm_urgent(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
+ context->bw_ctx.bw.dcn.watermarks.c.cstate_pstate.cstate_enter_plus_exit_ns = get_wm_stutter_enter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
+ context->bw_ctx.bw.dcn.watermarks.c.cstate_pstate.cstate_exit_ns = get_wm_stutter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
+ context->bw_ctx.bw.dcn.watermarks.c.cstate_pstate.pstate_change_ns = get_wm_dram_clock_change(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
+ context->bw_ctx.bw.dcn.watermarks.c.pte_meta_urgent_ns = get_wm_memory_trip(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
+ context->bw_ctx.bw.dcn.watermarks.c.frac_urg_bw_nom = get_fraction_of_urgent_bandwidth(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
+ context->bw_ctx.bw.dcn.watermarks.c.frac_urg_bw_flip = get_fraction_of_urgent_bandwidth_imm_flip(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
+
+ if (vlevel < 3) {
+ pipes[0].clks_cfg.voltage = 3;
+ pipes[0].clks_cfg.dcfclk_mhz = context->bw_ctx.dml.soc.clock_limits[2].dcfclk_mhz;
+ pipes[0].clks_cfg.socclk_mhz = context->bw_ctx.dml.soc.clock_limits[2].socclk_mhz;
+ }
+ context->bw_ctx.bw.dcn.watermarks.d.urgent_ns = get_wm_urgent(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
+ context->bw_ctx.bw.dcn.watermarks.d.cstate_pstate.cstate_enter_plus_exit_ns = get_wm_stutter_enter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
+ context->bw_ctx.bw.dcn.watermarks.d.cstate_pstate.cstate_exit_ns = get_wm_stutter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
+ context->bw_ctx.bw.dcn.watermarks.d.cstate_pstate.pstate_change_ns = get_wm_dram_clock_change(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
+ context->bw_ctx.bw.dcn.watermarks.d.pte_meta_urgent_ns = get_wm_memory_trip(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
+ context->bw_ctx.bw.dcn.watermarks.d.frac_urg_bw_nom = get_fraction_of_urgent_bandwidth(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
+ context->bw_ctx.bw.dcn.watermarks.d.frac_urg_bw_flip = get_fraction_of_urgent_bandwidth_imm_flip(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
+
+ pipes[0].clks_cfg.voltage = vlevel;
+ pipes[0].clks_cfg.dcfclk_mhz = context->bw_ctx.dml.soc.clock_limits[vlevel].dcfclk_mhz;
+ pipes[0].clks_cfg.socclk_mhz = context->bw_ctx.dml.soc.clock_limits[vlevel].socclk_mhz;
+ context->bw_ctx.bw.dcn.watermarks.a.urgent_ns = get_wm_urgent(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
+ context->bw_ctx.bw.dcn.watermarks.a.cstate_pstate.cstate_enter_plus_exit_ns = get_wm_stutter_enter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
+ context->bw_ctx.bw.dcn.watermarks.a.cstate_pstate.cstate_exit_ns = get_wm_stutter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
+ context->bw_ctx.bw.dcn.watermarks.a.cstate_pstate.pstate_change_ns = get_wm_dram_clock_change(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
+ context->bw_ctx.bw.dcn.watermarks.a.pte_meta_urgent_ns = get_wm_memory_trip(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
+ context->bw_ctx.bw.dcn.watermarks.a.frac_urg_bw_nom = get_fraction_of_urgent_bandwidth(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
+ context->bw_ctx.bw.dcn.watermarks.a.frac_urg_bw_flip = get_fraction_of_urgent_bandwidth_imm_flip(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
+}
+
+void dcn20_update_bounding_box(struct dc *dc, struct _vcs_dpi_soc_bounding_box_st *bb,
+ struct pp_smu_nv_clock_table *max_clocks, unsigned int *uclk_states, unsigned int num_states)
+{
+ struct _vcs_dpi_voltage_scaling_st calculated_states[DC__VOLTAGE_STATES];
+ int i;
+ int num_calculated_states = 0;
+ int min_dcfclk = 0;
+
+ dc_assert_fp_enabled();
+
+ if (num_states == 0)
+ return;
+
+ memset(calculated_states, 0, sizeof(calculated_states));
+
+ if (dc->bb_overrides.min_dcfclk_mhz > 0)
+ min_dcfclk = dc->bb_overrides.min_dcfclk_mhz;
+ else {
+ if (ASICREV_IS_NAVI12_P(dc->ctx->asic_id.hw_internal_rev))
+ min_dcfclk = 310;
+ else
+ // Accounting for SOC/DCF relationship, we can go as high as
+ // 506Mhz in Vmin.
+ min_dcfclk = 506;
+ }
+
+ for (i = 0; i < num_states; i++) {
+ int min_fclk_required_by_uclk;
+ calculated_states[i].state = i;
+ calculated_states[i].dram_speed_mts = uclk_states[i] * 16 / 1000;
+
+ // FCLK:UCLK ratio is 1.08
+ min_fclk_required_by_uclk = div_u64(((unsigned long long)uclk_states[i]) * 1080,
+ 1000000);
+
+ calculated_states[i].fabricclk_mhz = (min_fclk_required_by_uclk < min_dcfclk) ?
+ min_dcfclk : min_fclk_required_by_uclk;
+
+ calculated_states[i].socclk_mhz = (calculated_states[i].fabricclk_mhz > max_clocks->socClockInKhz / 1000) ?
+ max_clocks->socClockInKhz / 1000 : calculated_states[i].fabricclk_mhz;
+
+ calculated_states[i].dcfclk_mhz = (calculated_states[i].fabricclk_mhz > max_clocks->dcfClockInKhz / 1000) ?
+ max_clocks->dcfClockInKhz / 1000 : calculated_states[i].fabricclk_mhz;
+
+ calculated_states[i].dispclk_mhz = max_clocks->displayClockInKhz / 1000;
+ calculated_states[i].dppclk_mhz = max_clocks->displayClockInKhz / 1000;
+ calculated_states[i].dscclk_mhz = max_clocks->displayClockInKhz / (1000 * 3);
+
+ calculated_states[i].phyclk_mhz = max_clocks->phyClockInKhz / 1000;
+
+ num_calculated_states++;
+ }
+
+ calculated_states[num_calculated_states - 1].socclk_mhz = max_clocks->socClockInKhz / 1000;
+ calculated_states[num_calculated_states - 1].fabricclk_mhz = max_clocks->socClockInKhz / 1000;
+ calculated_states[num_calculated_states - 1].dcfclk_mhz = max_clocks->dcfClockInKhz / 1000;
+
+ memcpy(bb->clock_limits, calculated_states, sizeof(bb->clock_limits));
+ bb->num_states = num_calculated_states;
+
+ // Duplicate the last state, DML always an extra state identical to max state to work
+ memcpy(&bb->clock_limits[num_calculated_states], &bb->clock_limits[num_calculated_states - 1], sizeof(struct _vcs_dpi_voltage_scaling_st));
+ bb->clock_limits[num_calculated_states].state = bb->num_states;
+}
+
+void dcn20_cap_soc_clocks(
+ struct _vcs_dpi_soc_bounding_box_st *bb,
+ struct pp_smu_nv_clock_table max_clocks)
+{
+ int i;
+
+ dc_assert_fp_enabled();
+
+ // First pass - cap all clocks higher than the reported max
+ for (i = 0; i < bb->num_states; i++) {
+ if ((bb->clock_limits[i].dcfclk_mhz > (max_clocks.dcfClockInKhz / 1000))
+ && max_clocks.dcfClockInKhz != 0)
+ bb->clock_limits[i].dcfclk_mhz = (max_clocks.dcfClockInKhz / 1000);
+
+ if ((bb->clock_limits[i].dram_speed_mts > (max_clocks.uClockInKhz / 1000) * 16)
+ && max_clocks.uClockInKhz != 0)
+ bb->clock_limits[i].dram_speed_mts = (max_clocks.uClockInKhz / 1000) * 16;
+
+ if ((bb->clock_limits[i].fabricclk_mhz > (max_clocks.fabricClockInKhz / 1000))
+ && max_clocks.fabricClockInKhz != 0)
+ bb->clock_limits[i].fabricclk_mhz = (max_clocks.fabricClockInKhz / 1000);
+
+ if ((bb->clock_limits[i].dispclk_mhz > (max_clocks.displayClockInKhz / 1000))
+ && max_clocks.displayClockInKhz != 0)
+ bb->clock_limits[i].dispclk_mhz = (max_clocks.displayClockInKhz / 1000);
+
+ if ((bb->clock_limits[i].dppclk_mhz > (max_clocks.dppClockInKhz / 1000))
+ && max_clocks.dppClockInKhz != 0)
+ bb->clock_limits[i].dppclk_mhz = (max_clocks.dppClockInKhz / 1000);
+
+ if ((bb->clock_limits[i].phyclk_mhz > (max_clocks.phyClockInKhz / 1000))
+ && max_clocks.phyClockInKhz != 0)
+ bb->clock_limits[i].phyclk_mhz = (max_clocks.phyClockInKhz / 1000);
+
+ if ((bb->clock_limits[i].socclk_mhz > (max_clocks.socClockInKhz / 1000))
+ && max_clocks.socClockInKhz != 0)
+ bb->clock_limits[i].socclk_mhz = (max_clocks.socClockInKhz / 1000);
+
+ if ((bb->clock_limits[i].dscclk_mhz > (max_clocks.dscClockInKhz / 1000))
+ && max_clocks.dscClockInKhz != 0)
+ bb->clock_limits[i].dscclk_mhz = (max_clocks.dscClockInKhz / 1000);
+ }
+
+ // Second pass - remove all duplicate clock states
+ for (i = bb->num_states - 1; i > 1; i--) {
+ bool duplicate = true;
+
+ if (bb->clock_limits[i-1].dcfclk_mhz != bb->clock_limits[i].dcfclk_mhz)
+ duplicate = false;
+ if (bb->clock_limits[i-1].dispclk_mhz != bb->clock_limits[i].dispclk_mhz)
+ duplicate = false;
+ if (bb->clock_limits[i-1].dppclk_mhz != bb->clock_limits[i].dppclk_mhz)
+ duplicate = false;
+ if (bb->clock_limits[i-1].dram_speed_mts != bb->clock_limits[i].dram_speed_mts)
+ duplicate = false;
+ if (bb->clock_limits[i-1].dscclk_mhz != bb->clock_limits[i].dscclk_mhz)
+ duplicate = false;
+ if (bb->clock_limits[i-1].fabricclk_mhz != bb->clock_limits[i].fabricclk_mhz)
+ duplicate = false;
+ if (bb->clock_limits[i-1].phyclk_mhz != bb->clock_limits[i].phyclk_mhz)
+ duplicate = false;
+ if (bb->clock_limits[i-1].socclk_mhz != bb->clock_limits[i].socclk_mhz)
+ duplicate = false;
+
+ if (duplicate)
+ bb->num_states--;
+ }
+}
+
+void dcn20_patch_bounding_box(struct dc *dc, struct _vcs_dpi_soc_bounding_box_st *bb)
+{
+ dc_assert_fp_enabled();
+
+ if ((int)(bb->sr_exit_time_us * 1000) != dc->bb_overrides.sr_exit_time_ns
+ && dc->bb_overrides.sr_exit_time_ns) {
+ bb->sr_exit_time_us = dc->bb_overrides.sr_exit_time_ns / 1000.0;
+ }
+
+ if ((int)(bb->sr_enter_plus_exit_time_us * 1000)
+ != dc->bb_overrides.sr_enter_plus_exit_time_ns
+ && dc->bb_overrides.sr_enter_plus_exit_time_ns) {
+ bb->sr_enter_plus_exit_time_us =
+ dc->bb_overrides.sr_enter_plus_exit_time_ns / 1000.0;
+ }
+
+ if ((int)(bb->urgent_latency_us * 1000) != dc->bb_overrides.urgent_latency_ns
+ && dc->bb_overrides.urgent_latency_ns) {
+ bb->urgent_latency_us = dc->bb_overrides.urgent_latency_ns / 1000.0;
+ }
+
+ if ((int)(bb->dram_clock_change_latency_us * 1000)
+ != dc->bb_overrides.dram_clock_change_latency_ns
+ && dc->bb_overrides.dram_clock_change_latency_ns) {
+ bb->dram_clock_change_latency_us =
+ dc->bb_overrides.dram_clock_change_latency_ns / 1000.0;
+ }
+
+ if ((int)(bb->dummy_pstate_latency_us * 1000)
+ != dc->bb_overrides.dummy_clock_change_latency_ns
+ && dc->bb_overrides.dummy_clock_change_latency_ns) {
+ bb->dummy_pstate_latency_us =
+ dc->bb_overrides.dummy_clock_change_latency_ns / 1000.0;
+ }
+}
+
+static bool dcn20_validate_bandwidth_internal(struct dc *dc, struct dc_state *context,
+ bool fast_validate)
+{
+ bool out = false;
+
+ BW_VAL_TRACE_SETUP();
+
+ int vlevel = 0;
+ int pipe_split_from[MAX_PIPES];
+ int pipe_cnt = 0;
+ display_e2e_pipe_params_st *pipes = kzalloc(dc->res_pool->pipe_count * sizeof(display_e2e_pipe_params_st), GFP_ATOMIC);
+ DC_LOGGER_INIT(dc->ctx->logger);
+
+ BW_VAL_TRACE_COUNT();
+
+ out = dcn20_fast_validate_bw(dc, context, pipes, &pipe_cnt, pipe_split_from, &vlevel, fast_validate);
+
+ if (pipe_cnt == 0)
+ goto validate_out;
+
+ if (!out)
+ goto validate_fail;
+
+ BW_VAL_TRACE_END_VOLTAGE_LEVEL();
+
+ if (fast_validate) {
+ BW_VAL_TRACE_SKIP(fast);
+ goto validate_out;
+ }
+
+ dcn20_calculate_wm(dc, context, pipes, &pipe_cnt, pipe_split_from, vlevel, fast_validate);
+ dcn20_calculate_dlg_params(dc, context, pipes, pipe_cnt, vlevel);
+
+ BW_VAL_TRACE_END_WATERMARKS();
+
+ goto validate_out;
+
+validate_fail:
+ DC_LOG_WARNING("Mode Validation Warning: %s failed validation.\n",
+ dml_get_status_message(context->bw_ctx.dml.vba.ValidationStatus[context->bw_ctx.dml.vba.soc.num_states]));
+
+ BW_VAL_TRACE_SKIP(fail);
+ out = false;
+
+validate_out:
+ kfree(pipes);
+
+ BW_VAL_TRACE_FINISH();
+
+ return out;
+}
+
+bool dcn20_validate_bandwidth_fp(struct dc *dc,
+ struct dc_state *context,
+ bool fast_validate)
+{
+ bool voltage_supported = false;
+ bool full_pstate_supported = false;
+ bool dummy_pstate_supported = false;
+ double p_state_latency_us;
+
+ dc_assert_fp_enabled();
+
+ p_state_latency_us = context->bw_ctx.dml.soc.dram_clock_change_latency_us;
+ context->bw_ctx.dml.soc.disable_dram_clock_change_vactive_support =
+ dc->debug.disable_dram_clock_change_vactive_support;
+ context->bw_ctx.dml.soc.allow_dram_clock_one_display_vactive =
+ dc->debug.enable_dram_clock_change_one_display_vactive;
+
+ /*Unsafe due to current pipe merge and split logic*/
+ ASSERT(context != dc->current_state);
+
+ if (fast_validate) {
+ return dcn20_validate_bandwidth_internal(dc, context, true);
+ }
+
+ // Best case, we support full UCLK switch latency
+ voltage_supported = dcn20_validate_bandwidth_internal(dc, context, false);
+ full_pstate_supported = context->bw_ctx.bw.dcn.clk.p_state_change_support;
+
+ if (context->bw_ctx.dml.soc.dummy_pstate_latency_us == 0 ||
+ (voltage_supported && full_pstate_supported)) {
+ context->bw_ctx.bw.dcn.clk.p_state_change_support = full_pstate_supported;
+ goto restore_dml_state;
+ }
+
+ // Fallback: Try to only support G6 temperature read latency
+ context->bw_ctx.dml.soc.dram_clock_change_latency_us = context->bw_ctx.dml.soc.dummy_pstate_latency_us;
+
+ voltage_supported = dcn20_validate_bandwidth_internal(dc, context, false);
+ dummy_pstate_supported = context->bw_ctx.bw.dcn.clk.p_state_change_support;
+
+ if (voltage_supported && (dummy_pstate_supported || !(context->stream_count))) {
+ context->bw_ctx.bw.dcn.clk.p_state_change_support = false;
+ goto restore_dml_state;
+ }
+
+ // ERROR: fallback is supposed to always work.
+ ASSERT(false);
+
+restore_dml_state:
+ context->bw_ctx.dml.soc.dram_clock_change_latency_us = p_state_latency_us;
+ return voltage_supported;
+}
+
+void dcn20_fpu_set_wm_ranges(int i,
+ struct pp_smu_wm_range_sets *ranges,
+ struct _vcs_dpi_soc_bounding_box_st *loaded_bb)
+{
+ dc_assert_fp_enabled();
+
+ ranges->reader_wm_sets[i].min_fill_clk_mhz = (i > 0) ? (loaded_bb->clock_limits[i - 1].dram_speed_mts / 16) + 1 : 0;
+ ranges->reader_wm_sets[i].max_fill_clk_mhz = loaded_bb->clock_limits[i].dram_speed_mts / 16;
+}
+
+void dcn20_fpu_adjust_dppclk(struct vba_vars_st *v,
+ int vlevel,
+ int max_mpc_comb,
+ int pipe_idx,
+ bool is_validating_bw)
+{
+ dc_assert_fp_enabled();
+
+ if (is_validating_bw)
+ v->RequiredDPPCLK[vlevel][max_mpc_comb][pipe_idx] *= 2;
+ else
+ v->RequiredDPPCLK[vlevel][max_mpc_comb][pipe_idx] /= 2;
+}
+
+int dcn21_populate_dml_pipes_from_context(struct dc *dc,
+ struct dc_state *context,
+ display_e2e_pipe_params_st *pipes,
+ bool fast_validate)
+{
+ uint32_t pipe_cnt;
+ int i;
+
+ dc_assert_fp_enabled();
+
+ pipe_cnt = dcn20_populate_dml_pipes_from_context(dc, context, pipes, fast_validate);
+
+ for (i = 0; i < pipe_cnt; i++) {
+
+ pipes[i].pipe.src.hostvm = dc->res_pool->hubbub->riommu_active;
+ pipes[i].pipe.src.gpuvm = 1;
+ }
+
+ return pipe_cnt;
+}
+
+static void patch_bounding_box(struct dc *dc, struct _vcs_dpi_soc_bounding_box_st *bb)
+{
+ int i;
+
+ if (dc->bb_overrides.sr_exit_time_ns) {
+ for (i = 0; i < WM_SET_COUNT; i++) {
+ dc->clk_mgr->bw_params->wm_table.entries[i].sr_exit_time_us =
+ dc->bb_overrides.sr_exit_time_ns / 1000.0;
+ }
+ }
+
+ if (dc->bb_overrides.sr_enter_plus_exit_time_ns) {
+ for (i = 0; i < WM_SET_COUNT; i++) {
+ dc->clk_mgr->bw_params->wm_table.entries[i].sr_enter_plus_exit_time_us =
+ dc->bb_overrides.sr_enter_plus_exit_time_ns / 1000.0;
+ }
+ }
+
+ if (dc->bb_overrides.urgent_latency_ns) {
+ bb->urgent_latency_us = dc->bb_overrides.urgent_latency_ns / 1000.0;
+ }
+
+ if (dc->bb_overrides.dram_clock_change_latency_ns) {
+ for (i = 0; i < WM_SET_COUNT; i++) {
+ dc->clk_mgr->bw_params->wm_table.entries[i].pstate_latency_us =
+ dc->bb_overrides.dram_clock_change_latency_ns / 1000.0;
+ }
+ }
+}
+
+static void calculate_wm_set_for_vlevel(int vlevel,
+ struct wm_range_table_entry *table_entry,
+ struct dcn_watermarks *wm_set,
+ struct display_mode_lib *dml,
+ display_e2e_pipe_params_st *pipes,
+ int pipe_cnt)
+{
+ double dram_clock_change_latency_cached = dml->soc.dram_clock_change_latency_us;
+
+ ASSERT(vlevel < dml->soc.num_states);
+ /* only pipe 0 is read for voltage and dcf/soc clocks */
+ pipes[0].clks_cfg.voltage = vlevel;
+ pipes[0].clks_cfg.dcfclk_mhz = dml->soc.clock_limits[vlevel].dcfclk_mhz;
+ pipes[0].clks_cfg.socclk_mhz = dml->soc.clock_limits[vlevel].socclk_mhz;
+
+ dml->soc.dram_clock_change_latency_us = table_entry->pstate_latency_us;
+ dml->soc.sr_exit_time_us = table_entry->sr_exit_time_us;
+ dml->soc.sr_enter_plus_exit_time_us = table_entry->sr_enter_plus_exit_time_us;
+
+ wm_set->urgent_ns = get_wm_urgent(dml, pipes, pipe_cnt) * 1000;
+ wm_set->cstate_pstate.cstate_enter_plus_exit_ns = get_wm_stutter_enter_exit(dml, pipes, pipe_cnt) * 1000;
+ wm_set->cstate_pstate.cstate_exit_ns = get_wm_stutter_exit(dml, pipes, pipe_cnt) * 1000;
+ wm_set->cstate_pstate.pstate_change_ns = get_wm_dram_clock_change(dml, pipes, pipe_cnt) * 1000;
+ wm_set->pte_meta_urgent_ns = get_wm_memory_trip(dml, pipes, pipe_cnt) * 1000;
+ wm_set->frac_urg_bw_nom = get_fraction_of_urgent_bandwidth(dml, pipes, pipe_cnt) * 1000;
+ wm_set->frac_urg_bw_flip = get_fraction_of_urgent_bandwidth_imm_flip(dml, pipes, pipe_cnt) * 1000;
+ wm_set->urgent_latency_ns = get_urgent_latency(dml, pipes, pipe_cnt) * 1000;
+ dml->soc.dram_clock_change_latency_us = dram_clock_change_latency_cached;
+}
+
+static void dcn21_calculate_wm(struct dc *dc, struct dc_state *context,
+ display_e2e_pipe_params_st *pipes,
+ int *out_pipe_cnt,
+ int *pipe_split_from,
+ int vlevel_req,
+ bool fast_validate)
+{
+ int pipe_cnt, i, pipe_idx;
+ int vlevel, vlevel_max;
+ struct wm_range_table_entry *table_entry;
+ struct clk_bw_params *bw_params = dc->clk_mgr->bw_params;
+
+ ASSERT(bw_params);
+
+ patch_bounding_box(dc, &context->bw_ctx.dml.soc);
+
+ for (i = 0, pipe_idx = 0, pipe_cnt = 0; i < dc->res_pool->pipe_count; i++) {
+ if (!context->res_ctx.pipe_ctx[i].stream)
+ continue;
+
+ pipes[pipe_cnt].clks_cfg.refclk_mhz = dc->res_pool->ref_clocks.dchub_ref_clock_inKhz / 1000.0;
+ pipes[pipe_cnt].clks_cfg.dispclk_mhz = context->bw_ctx.dml.vba.RequiredDISPCLK[vlevel_req][context->bw_ctx.dml.vba.maxMpcComb];
+
+ if (pipe_split_from[i] < 0) {
+ pipes[pipe_cnt].clks_cfg.dppclk_mhz =
+ context->bw_ctx.dml.vba.RequiredDPPCLK[vlevel_req][context->bw_ctx.dml.vba.maxMpcComb][pipe_idx];
+ if (context->bw_ctx.dml.vba.BlendingAndTiming[pipe_idx] == pipe_idx)
+ pipes[pipe_cnt].pipe.dest.odm_combine =
+ context->bw_ctx.dml.vba.ODMCombineEnablePerState[vlevel_req][pipe_idx];
+ else
+ pipes[pipe_cnt].pipe.dest.odm_combine = 0;
+ pipe_idx++;
+ } else {
+ pipes[pipe_cnt].clks_cfg.dppclk_mhz =
+ context->bw_ctx.dml.vba.RequiredDPPCLK[vlevel_req][context->bw_ctx.dml.vba.maxMpcComb][pipe_split_from[i]];
+ if (context->bw_ctx.dml.vba.BlendingAndTiming[pipe_split_from[i]] == pipe_split_from[i])
+ pipes[pipe_cnt].pipe.dest.odm_combine =
+ context->bw_ctx.dml.vba.ODMCombineEnablePerState[vlevel_req][pipe_split_from[i]];
+ else
+ pipes[pipe_cnt].pipe.dest.odm_combine = 0;
+ }
+ pipe_cnt++;
+ }
+
+ if (pipe_cnt != pipe_idx) {
+ if (dc->res_pool->funcs->populate_dml_pipes)
+ pipe_cnt = dc->res_pool->funcs->populate_dml_pipes(dc,
+ context, pipes, fast_validate);
+ else
+ pipe_cnt = dcn21_populate_dml_pipes_from_context(dc,
+ context, pipes, fast_validate);
+ }
+
+ *out_pipe_cnt = pipe_cnt;
+
+ vlevel_max = bw_params->clk_table.num_entries - 1;
+
+
+ /* WM Set D */
+ table_entry = &bw_params->wm_table.entries[WM_D];
+ if (table_entry->wm_type == WM_TYPE_RETRAINING)
+ vlevel = 0;
+ else
+ vlevel = vlevel_max;
+ calculate_wm_set_for_vlevel(vlevel, table_entry, &context->bw_ctx.bw.dcn.watermarks.d,
+ &context->bw_ctx.dml, pipes, pipe_cnt);
+ /* WM Set C */
+ table_entry = &bw_params->wm_table.entries[WM_C];
+ vlevel = MIN(MAX(vlevel_req, 3), vlevel_max);
+ calculate_wm_set_for_vlevel(vlevel, table_entry, &context->bw_ctx.bw.dcn.watermarks.c,
+ &context->bw_ctx.dml, pipes, pipe_cnt);
+ /* WM Set B */
+ table_entry = &bw_params->wm_table.entries[WM_B];
+ vlevel = MIN(MAX(vlevel_req, 2), vlevel_max);
+ calculate_wm_set_for_vlevel(vlevel, table_entry, &context->bw_ctx.bw.dcn.watermarks.b,
+ &context->bw_ctx.dml, pipes, pipe_cnt);
+
+ /* WM Set A */
+ table_entry = &bw_params->wm_table.entries[WM_A];
+ vlevel = MIN(vlevel_req, vlevel_max);
+ calculate_wm_set_for_vlevel(vlevel, table_entry, &context->bw_ctx.bw.dcn.watermarks.a,
+ &context->bw_ctx.dml, pipes, pipe_cnt);
+}
+
+bool dcn21_validate_bandwidth_fp(struct dc *dc,
+ struct dc_state *context,
+ bool fast_validate)
+{
+ bool out = false;
+
+ BW_VAL_TRACE_SETUP();
+
+ int vlevel = 0;
+ int pipe_split_from[MAX_PIPES];
+ int pipe_cnt = 0;
+ display_e2e_pipe_params_st *pipes = kzalloc(dc->res_pool->pipe_count * sizeof(display_e2e_pipe_params_st), GFP_ATOMIC);
+ DC_LOGGER_INIT(dc->ctx->logger);
+
+ BW_VAL_TRACE_COUNT();
+
+ dc_assert_fp_enabled();
+
+ /*Unsafe due to current pipe merge and split logic*/
+ ASSERT(context != dc->current_state);
+
+ out = dcn21_fast_validate_bw(dc, context, pipes, &pipe_cnt, pipe_split_from, &vlevel, fast_validate);
+
+ if (pipe_cnt == 0)
+ goto validate_out;
+
+ if (!out)
+ goto validate_fail;
+
+ BW_VAL_TRACE_END_VOLTAGE_LEVEL();
+
+ if (fast_validate) {
+ BW_VAL_TRACE_SKIP(fast);
+ goto validate_out;
+ }
+
+ dcn21_calculate_wm(dc, context, pipes, &pipe_cnt, pipe_split_from, vlevel, fast_validate);
+ dcn20_calculate_dlg_params(dc, context, pipes, pipe_cnt, vlevel);
+
+ BW_VAL_TRACE_END_WATERMARKS();
+
+ goto validate_out;
+
+validate_fail:
+ DC_LOG_WARNING("Mode Validation Warning: %s failed validation.\n",
+ dml_get_status_message(context->bw_ctx.dml.vba.ValidationStatus[context->bw_ctx.dml.vba.soc.num_states]));
+
+ BW_VAL_TRACE_SKIP(fail);
+ out = false;
+
+validate_out:
+ kfree(pipes);
+
+ BW_VAL_TRACE_FINISH();
+
+ return out;
+}
+
+static struct _vcs_dpi_voltage_scaling_st construct_low_pstate_lvl(struct clk_limit_table *clk_table, unsigned int high_voltage_lvl)
+{
+ struct _vcs_dpi_voltage_scaling_st low_pstate_lvl;
+ int i;
+
+ low_pstate_lvl.state = 1;
+ low_pstate_lvl.dcfclk_mhz = clk_table->entries[0].dcfclk_mhz;
+ low_pstate_lvl.fabricclk_mhz = clk_table->entries[0].fclk_mhz;
+ low_pstate_lvl.socclk_mhz = clk_table->entries[0].socclk_mhz;
+ low_pstate_lvl.dram_speed_mts = clk_table->entries[0].memclk_mhz * 2;
+
+ low_pstate_lvl.dispclk_mhz = dcn2_1_soc.clock_limits[high_voltage_lvl].dispclk_mhz;
+ low_pstate_lvl.dppclk_mhz = dcn2_1_soc.clock_limits[high_voltage_lvl].dppclk_mhz;
+ low_pstate_lvl.dram_bw_per_chan_gbps = dcn2_1_soc.clock_limits[high_voltage_lvl].dram_bw_per_chan_gbps;
+ low_pstate_lvl.dscclk_mhz = dcn2_1_soc.clock_limits[high_voltage_lvl].dscclk_mhz;
+ low_pstate_lvl.dtbclk_mhz = dcn2_1_soc.clock_limits[high_voltage_lvl].dtbclk_mhz;
+ low_pstate_lvl.phyclk_d18_mhz = dcn2_1_soc.clock_limits[high_voltage_lvl].phyclk_d18_mhz;
+ low_pstate_lvl.phyclk_mhz = dcn2_1_soc.clock_limits[high_voltage_lvl].phyclk_mhz;
+
+ for (i = clk_table->num_entries; i > 1; i--)
+ clk_table->entries[i] = clk_table->entries[i-1];
+ clk_table->entries[1] = clk_table->entries[0];
+ clk_table->num_entries++;
+
+ return low_pstate_lvl;
+}
+
+void dcn21_update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_params)
+{
+ struct dcn21_resource_pool *pool = TO_DCN21_RES_POOL(dc->res_pool);
+ struct clk_limit_table *clk_table = &bw_params->clk_table;
+ struct _vcs_dpi_voltage_scaling_st clock_limits[DC__VOLTAGE_STATES];
+ unsigned int i, closest_clk_lvl = 0, k = 0;
+ int j;
+
+ dc_assert_fp_enabled();
+
+ dcn2_1_ip.max_num_otg = pool->base.res_cap->num_timing_generator;
+ dcn2_1_ip.max_num_dpp = pool->base.pipe_count;
+ dcn2_1_soc.num_chans = bw_params->num_channels;
+
+ ASSERT(clk_table->num_entries);
+ /* Copy dcn2_1_soc.clock_limits to clock_limits to avoid copying over null states later */
+ for (i = 0; i < dcn2_1_soc.num_states + 1; i++) {
+ clock_limits[i] = dcn2_1_soc.clock_limits[i];
+ }
+
+ for (i = 0; i < clk_table->num_entries; i++) {
+ /* loop backwards*/
+ for (closest_clk_lvl = 0, j = dcn2_1_soc.num_states - 1; j >= 0; j--) {
+ if ((unsigned int) dcn2_1_soc.clock_limits[j].dcfclk_mhz <= clk_table->entries[i].dcfclk_mhz) {
+ closest_clk_lvl = j;
+ break;
+ }
+ }
+
+ /* clk_table[1] is reserved for min DF PState. skip here to fill in later. */
+ if (i == 1)
+ k++;
+
+ clock_limits[k].state = k;
+ clock_limits[k].dcfclk_mhz = clk_table->entries[i].dcfclk_mhz;
+ clock_limits[k].fabricclk_mhz = clk_table->entries[i].fclk_mhz;
+ clock_limits[k].socclk_mhz = clk_table->entries[i].socclk_mhz;
+ clock_limits[k].dram_speed_mts = clk_table->entries[i].memclk_mhz * 2;
+
+ clock_limits[k].dispclk_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].dispclk_mhz;
+ clock_limits[k].dppclk_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].dppclk_mhz;
+ clock_limits[k].dram_bw_per_chan_gbps = dcn2_1_soc.clock_limits[closest_clk_lvl].dram_bw_per_chan_gbps;
+ clock_limits[k].dscclk_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].dscclk_mhz;
+ clock_limits[k].dtbclk_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].dtbclk_mhz;
+ clock_limits[k].phyclk_d18_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].phyclk_d18_mhz;
+ clock_limits[k].phyclk_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].phyclk_mhz;
+
+ k++;
+ }
+ for (i = 0; i < clk_table->num_entries + 1; i++)
+ dcn2_1_soc.clock_limits[i] = clock_limits[i];
+ if (clk_table->num_entries) {
+ dcn2_1_soc.num_states = clk_table->num_entries + 1;
+ /* fill in min DF PState */
+ dcn2_1_soc.clock_limits[1] = construct_low_pstate_lvl(clk_table, closest_clk_lvl);
+ /* duplicate last level */
+ dcn2_1_soc.clock_limits[dcn2_1_soc.num_states] = dcn2_1_soc.clock_limits[dcn2_1_soc.num_states - 1];
+ dcn2_1_soc.clock_limits[dcn2_1_soc.num_states].state = dcn2_1_soc.num_states;
+ }
+
+ dml_init_instance(&dc->dml, &dcn2_1_soc, &dcn2_1_ip, DML_PROJECT_DCN21);
+}
diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn20/dcn20_fpu.h b/drivers/gpu/drm/amd/display/dc/dml/dcn20/dcn20_fpu.h
index 36f26126d574..aa892193e485 100644
--- a/drivers/gpu/drm/amd/display/dc/dml/dcn20/dcn20_fpu.h
+++ b/drivers/gpu/drm/amd/display/dc/dml/dcn20/dcn20_fpu.h
@@ -23,6 +23,7 @@
* Authors: AMD
*
*/
+#include "core_types.h"
#ifndef __DCN20_FPU_H__
#define __DCN20_FPU_H__
@@ -31,4 +32,54 @@ void dcn20_populate_dml_writeback_from_context(struct dc *dc,
struct resource_context *res_ctx,
display_e2e_pipe_params_st *pipes);
+void dcn20_fpu_set_wb_arb_params(struct mcif_arb_params *wb_arb_params,
+ struct dc_state *context,
+ display_e2e_pipe_params_st *pipes,
+ int pipe_cnt, int i);
+void dcn20_calculate_dlg_params(struct dc *dc,
+ struct dc_state *context,
+ display_e2e_pipe_params_st *pipes,
+ int pipe_cnt,
+ int vlevel);
+int dcn20_populate_dml_pipes_from_context(struct dc *dc,
+ struct dc_state *context,
+ display_e2e_pipe_params_st *pipes,
+ bool fast_validate);
+void dcn20_calculate_wm(struct dc *dc,
+ struct dc_state *context,
+ display_e2e_pipe_params_st *pipes,
+ int *out_pipe_cnt,
+ int *pipe_split_from,
+ int vlevel,
+ bool fast_validate);
+void dcn20_cap_soc_clocks(struct _vcs_dpi_soc_bounding_box_st *bb,
+ struct pp_smu_nv_clock_table max_clocks);
+void dcn20_update_bounding_box(struct dc *dc,
+ struct _vcs_dpi_soc_bounding_box_st *bb,
+ struct pp_smu_nv_clock_table *max_clocks,
+ unsigned int *uclk_states,
+ unsigned int num_states);
+void dcn20_patch_bounding_box(struct dc *dc,
+ struct _vcs_dpi_soc_bounding_box_st *bb);
+bool dcn20_validate_bandwidth_fp(struct dc *dc,
+ struct dc_state *context,
+ bool fast_validate);
+void dcn20_fpu_set_wm_ranges(int i,
+ struct pp_smu_wm_range_sets *ranges,
+ struct _vcs_dpi_soc_bounding_box_st *loaded_bb);
+void dcn20_fpu_adjust_dppclk(struct vba_vars_st *v,
+ int vlevel,
+ int max_mpc_comb,
+ int pipe_idx,
+ bool is_validating_bw);
+
+int dcn21_populate_dml_pipes_from_context(struct dc *dc,
+ struct dc_state *context,
+ display_e2e_pipe_params_st *pipes,
+ bool fast_validate);
+bool dcn21_validate_bandwidth_fp(struct dc *dc,
+ struct dc_state *context,
+ bool fast_validate);
+void dcn21_update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_params);
+
#endif /* __DCN20_FPU_H__ */
diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20.c b/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20.c
index 246071c72f6b..548cdef8a8ad 100644
--- a/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20.c
+++ b/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20.c
@@ -1576,8 +1576,6 @@ void dml20_rq_dlg_get_dlg_reg(struct display_mode_lib *mode_lib,
dlg_sys_param.total_flip_bytes = get_total_immediate_flip_bytes(mode_lib,
e2e_pipe_param,
num_pipes);
- dlg_sys_param.t_srx_delay_us = mode_lib->ip.dcfclk_cstate_latency
- / dlg_sys_param.deepsleep_dcfclk_mhz; // TODO: Deprecated
print__dlg_sys_params_st(mode_lib, &dlg_sys_param);
diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20v2.c b/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20v2.c
index 015e7f2c0b16..0fc9f3e3ffae 100644
--- a/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20v2.c
+++ b/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20v2.c
@@ -1577,8 +1577,6 @@ void dml20v2_rq_dlg_get_dlg_reg(struct display_mode_lib *mode_lib,
dlg_sys_param.total_flip_bytes = get_total_immediate_flip_bytes(mode_lib,
e2e_pipe_param,
num_pipes);
- dlg_sys_param.t_srx_delay_us = mode_lib->ip.dcfclk_cstate_latency
- / dlg_sys_param.deepsleep_dcfclk_mhz; // TODO: Deprecated
print__dlg_sys_params_st(mode_lib, &dlg_sys_param);
diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn21/display_rq_dlg_calc_21.c b/drivers/gpu/drm/amd/display/dc/dml/dcn21/display_rq_dlg_calc_21.c
index 8bc27de4c104..618f4b682ab1 100644
--- a/drivers/gpu/drm/amd/display/dc/dml/dcn21/display_rq_dlg_calc_21.c
+++ b/drivers/gpu/drm/amd/display/dc/dml/dcn21/display_rq_dlg_calc_21.c
@@ -1688,8 +1688,6 @@ void dml21_rq_dlg_get_dlg_reg(
mode_lib,
e2e_pipe_param,
num_pipes);
- dlg_sys_param.t_srx_delay_us = mode_lib->ip.dcfclk_cstate_latency
- / dlg_sys_param.deepsleep_dcfclk_mhz; // TODO: Deprecated
print__dlg_sys_params_st(mode_lib, &dlg_sys_param);
diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn30/display_rq_dlg_calc_30.c b/drivers/gpu/drm/amd/display/dc/dml/dcn30/display_rq_dlg_calc_30.c
index aef854270054..747167083dea 100644
--- a/drivers/gpu/drm/amd/display/dc/dml/dcn30/display_rq_dlg_calc_30.c
+++ b/drivers/gpu/drm/amd/display/dc/dml/dcn30/display_rq_dlg_calc_30.c
@@ -1858,8 +1858,6 @@ void dml30_rq_dlg_get_dlg_reg(struct display_mode_lib *mode_lib,
dlg_sys_param.total_flip_bytes = get_total_immediate_flip_bytes(mode_lib,
e2e_pipe_param,
num_pipes);
- dlg_sys_param.t_srx_delay_us = mode_lib->ip.dcfclk_cstate_latency
- / dlg_sys_param.deepsleep_dcfclk_mhz; // TODO: Deprecated
print__dlg_sys_params_st(mode_lib, &dlg_sys_param);
diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn301/dcn301_fpu.c b/drivers/gpu/drm/amd/display/dc/dml/dcn301/dcn301_fpu.c
index 94c32832a0e7..0a7a33864973 100644
--- a/drivers/gpu/drm/amd/display/dc/dml/dcn301/dcn301_fpu.c
+++ b/drivers/gpu/drm/amd/display/dc/dml/dcn301/dcn301_fpu.c
@@ -327,7 +327,7 @@ void dcn301_fpu_init_soc_bounding_box(struct bp_soc_bb_info bb_info)
dcn3_01_soc.sr_exit_time_us = bb_info.dram_sr_exit_latency_100ns * 10;
}
-void dcn301_calculate_wm_and_dlg(struct dc *dc,
+void dcn301_calculate_wm_and_dlg_fp(struct dc *dc,
struct dc_state *context,
display_e2e_pipe_params_st *pipes,
int pipe_cnt,
diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn301/dcn301_fpu.h b/drivers/gpu/drm/amd/display/dc/dml/dcn301/dcn301_fpu.h
index fc7065d17842..774b0fdfc80b 100644
--- a/drivers/gpu/drm/amd/display/dc/dml/dcn301/dcn301_fpu.h
+++ b/drivers/gpu/drm/amd/display/dc/dml/dcn301/dcn301_fpu.h
@@ -34,7 +34,7 @@ void dcn301_fpu_set_wm_ranges(int i,
void dcn301_fpu_init_soc_bounding_box(struct bp_soc_bb_info bb_info);
-void dcn301_calculate_wm_and_dlg(struct dc *dc,
+void dcn301_calculate_wm_and_dlg_fp(struct dc *dc,
struct dc_state *context,
display_e2e_pipe_params_st *pipes,
int pipe_cnt,
diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn302/dcn302_fpu.c b/drivers/gpu/drm/amd/display/dc/dml/dcn302/dcn302_fpu.c
new file mode 100644
index 000000000000..e2bcd205aa93
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/dc/dml/dcn302/dcn302_fpu.c
@@ -0,0 +1,357 @@
+/*
+ * Copyright 2021 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: AMD
+ *
+ */
+
+#include "resource.h"
+#include "clk_mgr.h"
+#include "dcn20/dcn20_resource.h"
+#include "dcn302/dcn302_resource.h"
+
+#include "dml/dcn20/dcn20_fpu.h"
+#include "dcn302_fpu.h"
+
+struct _vcs_dpi_ip_params_st dcn3_02_ip = {
+ .use_min_dcfclk = 0,
+ .clamp_min_dcfclk = 0,
+ .odm_capable = 1,
+ .gpuvm_enable = 1,
+ .hostvm_enable = 0,
+ .gpuvm_max_page_table_levels = 4,
+ .hostvm_max_page_table_levels = 4,
+ .hostvm_cached_page_table_levels = 0,
+ .pte_group_size_bytes = 2048,
+ .num_dsc = 5,
+ .rob_buffer_size_kbytes = 184,
+ .det_buffer_size_kbytes = 184,
+ .dpte_buffer_size_in_pte_reqs_luma = 64,
+ .dpte_buffer_size_in_pte_reqs_chroma = 34,
+ .pde_proc_buffer_size_64k_reqs = 48,
+ .dpp_output_buffer_pixels = 2560,
+ .opp_output_buffer_lines = 1,
+ .pixel_chunk_size_kbytes = 8,
+ .pte_enable = 1,
+ .max_page_table_levels = 2,
+ .pte_chunk_size_kbytes = 2, // ?
+ .meta_chunk_size_kbytes = 2,
+ .writeback_chunk_size_kbytes = 8,
+ .line_buffer_size_bits = 789504,
+ .is_line_buffer_bpp_fixed = 0, // ?
+ .line_buffer_fixed_bpp = 0, // ?
+ .dcc_supported = true,
+ .writeback_interface_buffer_size_kbytes = 90,
+ .writeback_line_buffer_buffer_size = 0,
+ .max_line_buffer_lines = 12,
+ .writeback_luma_buffer_size_kbytes = 12, // writeback_line_buffer_buffer_size = 656640
+ .writeback_chroma_buffer_size_kbytes = 8,
+ .writeback_chroma_line_buffer_width_pixels = 4,
+ .writeback_max_hscl_ratio = 1,
+ .writeback_max_vscl_ratio = 1,
+ .writeback_min_hscl_ratio = 1,
+ .writeback_min_vscl_ratio = 1,
+ .writeback_max_hscl_taps = 1,
+ .writeback_max_vscl_taps = 1,
+ .writeback_line_buffer_luma_buffer_size = 0,
+ .writeback_line_buffer_chroma_buffer_size = 14643,
+ .cursor_buffer_size = 8,
+ .cursor_chunk_size = 2,
+ .max_num_otg = 5,
+ .max_num_dpp = 5,
+ .max_num_wb = 1,
+ .max_dchub_pscl_bw_pix_per_clk = 4,
+ .max_pscl_lb_bw_pix_per_clk = 2,
+ .max_lb_vscl_bw_pix_per_clk = 4,
+ .max_vscl_hscl_bw_pix_per_clk = 4,
+ .max_hscl_ratio = 6,
+ .max_vscl_ratio = 6,
+ .hscl_mults = 4,
+ .vscl_mults = 4,
+ .max_hscl_taps = 8,
+ .max_vscl_taps = 8,
+ .dispclk_ramp_margin_percent = 1,
+ .underscan_factor = 1.11,
+ .min_vblank_lines = 32,
+ .dppclk_delay_subtotal = 46,
+ .dynamic_metadata_vm_enabled = true,
+ .dppclk_delay_scl_lb_only = 16,
+ .dppclk_delay_scl = 50,
+ .dppclk_delay_cnvc_formatter = 27,
+ .dppclk_delay_cnvc_cursor = 6,
+ .dispclk_delay_subtotal = 119,
+ .dcfclk_cstate_latency = 5.2, // SRExitTime
+ .max_inter_dcn_tile_repeaters = 8,
+ .max_num_hdmi_frl_outputs = 1,
+ .odm_combine_4to1_supported = true,
+
+ .xfc_supported = false,
+ .xfc_fill_bw_overhead_percent = 10.0,
+ .xfc_fill_constant_bytes = 0,
+ .gfx7_compat_tiling_supported = 0,
+ .number_of_cursors = 1,
+};
+
+struct _vcs_dpi_soc_bounding_box_st dcn3_02_soc = {
+ .clock_limits = {
+ {
+ .state = 0,
+ .dispclk_mhz = 562.0,
+ .dppclk_mhz = 300.0,
+ .phyclk_mhz = 300.0,
+ .phyclk_d18_mhz = 667.0,
+ .dscclk_mhz = 405.6,
+ },
+ },
+
+ .min_dcfclk = 500.0, /* TODO: set this to actual min DCFCLK */
+ .num_states = 1,
+ .sr_exit_time_us = 26.5,
+ .sr_enter_plus_exit_time_us = 31,
+ .urgent_latency_us = 4.0,
+ .urgent_latency_pixel_data_only_us = 4.0,
+ .urgent_latency_pixel_mixed_with_vm_data_us = 4.0,
+ .urgent_latency_vm_data_only_us = 4.0,
+ .urgent_out_of_order_return_per_channel_pixel_only_bytes = 4096,
+ .urgent_out_of_order_return_per_channel_pixel_and_vm_bytes = 4096,
+ .urgent_out_of_order_return_per_channel_vm_only_bytes = 4096,
+ .pct_ideal_dram_sdp_bw_after_urgent_pixel_only = 80.0,
+ .pct_ideal_dram_sdp_bw_after_urgent_pixel_and_vm = 60.0,
+ .pct_ideal_dram_sdp_bw_after_urgent_vm_only = 40.0,
+ .max_avg_sdp_bw_use_normal_percent = 60.0,
+ .max_avg_dram_bw_use_normal_percent = 40.0,
+ .writeback_latency_us = 12.0,
+ .max_request_size_bytes = 256,
+ .fabric_datapath_to_dcn_data_return_bytes = 64,
+ .dcn_downspread_percent = 0.5,
+ .downspread_percent = 0.38,
+ .dram_page_open_time_ns = 50.0,
+ .dram_rw_turnaround_time_ns = 17.5,
+ .dram_return_buffer_per_channel_bytes = 8192,
+ .round_trip_ping_latency_dcfclk_cycles = 156,
+ .urgent_out_of_order_return_per_channel_bytes = 4096,
+ .channel_interleave_bytes = 256,
+ .num_banks = 8,
+ .gpuvm_min_page_size_bytes = 4096,
+ .hostvm_min_page_size_bytes = 4096,
+ .dram_clock_change_latency_us = 404,
+ .dummy_pstate_latency_us = 5,
+ .writeback_dram_clock_change_latency_us = 23.0,
+ .return_bus_width_bytes = 64,
+ .dispclk_dppclk_vco_speed_mhz = 3650,
+ .xfc_bus_transport_time_us = 20, // ?
+ .xfc_xbuf_latency_tolerance_us = 4, // ?
+ .use_urgent_burst_bw = 1, // ?
+ .do_urgent_latency_adjustment = true,
+ .urgent_latency_adjustment_fabric_clock_component_us = 1.0,
+ .urgent_latency_adjustment_fabric_clock_reference_mhz = 1000,
+};
+
+static void dcn302_get_optimal_dcfclk_fclk_for_uclk(unsigned int uclk_mts,
+ unsigned int *optimal_dcfclk,
+ unsigned int *optimal_fclk)
+{
+
+ double bw_from_dram, bw_from_dram1, bw_from_dram2;
+
+ bw_from_dram1 = uclk_mts * dcn3_02_soc.num_chans *
+ dcn3_02_soc.dram_channel_width_bytes *
+ (dcn3_02_soc.max_avg_dram_bw_use_normal_percent / 100);
+ bw_from_dram2 = uclk_mts * dcn3_02_soc.num_chans *
+ dcn3_02_soc.dram_channel_width_bytes *
+ (dcn3_02_soc.max_avg_sdp_bw_use_normal_percent / 100);
+
+ bw_from_dram = (bw_from_dram1 < bw_from_dram2) ? bw_from_dram1 : bw_from_dram2;
+
+ if (optimal_fclk)
+ *optimal_fclk = bw_from_dram /
+ (dcn3_02_soc.fabric_datapath_to_dcn_data_return_bytes *
+ (dcn3_02_soc.max_avg_sdp_bw_use_normal_percent / 100));
+
+ if (optimal_dcfclk)
+ *optimal_dcfclk = bw_from_dram /
+ (dcn3_02_soc.return_bus_width_bytes *
+ (dcn3_02_soc.max_avg_sdp_bw_use_normal_percent / 100));
+}
+
+void dcn302_fpu_update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_params)
+{
+ unsigned int i, j;
+ unsigned int num_states = 0;
+
+ unsigned int dcfclk_mhz[DC__VOLTAGE_STATES] = {0};
+ unsigned int dram_speed_mts[DC__VOLTAGE_STATES] = {0};
+ unsigned int optimal_uclk_for_dcfclk_sta_targets[DC__VOLTAGE_STATES] = {0};
+ unsigned int optimal_dcfclk_for_uclk[DC__VOLTAGE_STATES] = {0};
+
+ unsigned int dcfclk_sta_targets[DC__VOLTAGE_STATES] = {694, 875, 1000, 1200};
+ unsigned int num_dcfclk_sta_targets = 4;
+ unsigned int num_uclk_states;
+
+ dc_assert_fp_enabled();
+
+ if (dc->ctx->dc_bios->vram_info.num_chans)
+ dcn3_02_soc.num_chans = dc->ctx->dc_bios->vram_info.num_chans;
+
+ if (dc->ctx->dc_bios->vram_info.dram_channel_width_bytes)
+ dcn3_02_soc.dram_channel_width_bytes = dc->ctx->dc_bios->vram_info.dram_channel_width_bytes;
+
+ dcn3_02_soc.dispclk_dppclk_vco_speed_mhz = dc->clk_mgr->dentist_vco_freq_khz / 1000.0;
+ dc->dml.soc.dispclk_dppclk_vco_speed_mhz = dc->clk_mgr->dentist_vco_freq_khz / 1000.0;
+
+ if (bw_params->clk_table.entries[0].memclk_mhz) {
+ int max_dcfclk_mhz = 0, max_dispclk_mhz = 0, max_dppclk_mhz = 0, max_phyclk_mhz = 0;
+
+ for (i = 0; i < MAX_NUM_DPM_LVL; i++) {
+ if (bw_params->clk_table.entries[i].dcfclk_mhz > max_dcfclk_mhz)
+ max_dcfclk_mhz = bw_params->clk_table.entries[i].dcfclk_mhz;
+ if (bw_params->clk_table.entries[i].dispclk_mhz > max_dispclk_mhz)
+ max_dispclk_mhz = bw_params->clk_table.entries[i].dispclk_mhz;
+ if (bw_params->clk_table.entries[i].dppclk_mhz > max_dppclk_mhz)
+ max_dppclk_mhz = bw_params->clk_table.entries[i].dppclk_mhz;
+ if (bw_params->clk_table.entries[i].phyclk_mhz > max_phyclk_mhz)
+ max_phyclk_mhz = bw_params->clk_table.entries[i].phyclk_mhz;
+ }
+ if (!max_dcfclk_mhz)
+ max_dcfclk_mhz = dcn3_02_soc.clock_limits[0].dcfclk_mhz;
+ if (!max_dispclk_mhz)
+ max_dispclk_mhz = dcn3_02_soc.clock_limits[0].dispclk_mhz;
+ if (!max_dppclk_mhz)
+ max_dppclk_mhz = dcn3_02_soc.clock_limits[0].dppclk_mhz;
+ if (!max_phyclk_mhz)
+ max_phyclk_mhz = dcn3_02_soc.clock_limits[0].phyclk_mhz;
+
+ if (max_dcfclk_mhz > dcfclk_sta_targets[num_dcfclk_sta_targets-1]) {
+ /* If max DCFCLK is greater than the max DCFCLK STA target, insert into the DCFCLK STA target array */
+ dcfclk_sta_targets[num_dcfclk_sta_targets] = max_dcfclk_mhz;
+ num_dcfclk_sta_targets++;
+ } else if (max_dcfclk_mhz < dcfclk_sta_targets[num_dcfclk_sta_targets-1]) {
+ /* If max DCFCLK is less than the max DCFCLK STA target, cap values and remove duplicates */
+ for (i = 0; i < num_dcfclk_sta_targets; i++) {
+ if (dcfclk_sta_targets[i] > max_dcfclk_mhz) {
+ dcfclk_sta_targets[i] = max_dcfclk_mhz;
+ break;
+ }
+ }
+ /* Update size of array since we "removed" duplicates */
+ num_dcfclk_sta_targets = i + 1;
+ }
+
+ num_uclk_states = bw_params->clk_table.num_entries;
+
+ /* Calculate optimal dcfclk for each uclk */
+ for (i = 0; i < num_uclk_states; i++) {
+ dcn302_get_optimal_dcfclk_fclk_for_uclk(bw_params->clk_table.entries[i].memclk_mhz * 16,
+ &optimal_dcfclk_for_uclk[i], NULL);
+ if (optimal_dcfclk_for_uclk[i] < bw_params->clk_table.entries[0].dcfclk_mhz)
+ optimal_dcfclk_for_uclk[i] = bw_params->clk_table.entries[0].dcfclk_mhz;
+ }
+
+ /* Calculate optimal uclk for each dcfclk sta target */
+ for (i = 0; i < num_dcfclk_sta_targets; i++) {
+ for (j = 0; j < num_uclk_states; j++) {
+ if (dcfclk_sta_targets[i] < optimal_dcfclk_for_uclk[j]) {
+ optimal_uclk_for_dcfclk_sta_targets[i] =
+ bw_params->clk_table.entries[j].memclk_mhz * 16;
+ break;
+ }
+ }
+ }
+
+ i = 0;
+ j = 0;
+ /* create the final dcfclk and uclk table */
+ while (i < num_dcfclk_sta_targets && j < num_uclk_states && num_states < DC__VOLTAGE_STATES) {
+ if (dcfclk_sta_targets[i] < optimal_dcfclk_for_uclk[j] && i < num_dcfclk_sta_targets) {
+ dcfclk_mhz[num_states] = dcfclk_sta_targets[i];
+ dram_speed_mts[num_states++] = optimal_uclk_for_dcfclk_sta_targets[i++];
+ } else {
+ if (j < num_uclk_states && optimal_dcfclk_for_uclk[j] <= max_dcfclk_mhz) {
+ dcfclk_mhz[num_states] = optimal_dcfclk_for_uclk[j];
+ dram_speed_mts[num_states++] = bw_params->clk_table.entries[j++].memclk_mhz * 16;
+ } else {
+ j = num_uclk_states;
+ }
+ }
+ }
+
+ while (i < num_dcfclk_sta_targets && num_states < DC__VOLTAGE_STATES) {
+ dcfclk_mhz[num_states] = dcfclk_sta_targets[i];
+ dram_speed_mts[num_states++] = optimal_uclk_for_dcfclk_sta_targets[i++];
+ }
+
+ while (j < num_uclk_states && num_states < DC__VOLTAGE_STATES &&
+ optimal_dcfclk_for_uclk[j] <= max_dcfclk_mhz) {
+ dcfclk_mhz[num_states] = optimal_dcfclk_for_uclk[j];
+ dram_speed_mts[num_states++] = bw_params->clk_table.entries[j++].memclk_mhz * 16;
+ }
+
+ dcn3_02_soc.num_states = num_states;
+ for (i = 0; i < dcn3_02_soc.num_states; i++) {
+ dcn3_02_soc.clock_limits[i].state = i;
+ dcn3_02_soc.clock_limits[i].dcfclk_mhz = dcfclk_mhz[i];
+ dcn3_02_soc.clock_limits[i].fabricclk_mhz = dcfclk_mhz[i];
+ dcn3_02_soc.clock_limits[i].dram_speed_mts = dram_speed_mts[i];
+
+ /* Fill all states with max values of all other clocks */
+ dcn3_02_soc.clock_limits[i].dispclk_mhz = max_dispclk_mhz;
+ dcn3_02_soc.clock_limits[i].dppclk_mhz = max_dppclk_mhz;
+ dcn3_02_soc.clock_limits[i].phyclk_mhz = max_phyclk_mhz;
+ /* Populate from bw_params for DTBCLK, SOCCLK */
+ if (!bw_params->clk_table.entries[i].dtbclk_mhz && i > 0)
+ dcn3_02_soc.clock_limits[i].dtbclk_mhz = dcn3_02_soc.clock_limits[i-1].dtbclk_mhz;
+ else
+ dcn3_02_soc.clock_limits[i].dtbclk_mhz = bw_params->clk_table.entries[i].dtbclk_mhz;
+ if (!bw_params->clk_table.entries[i].socclk_mhz && i > 0)
+ dcn3_02_soc.clock_limits[i].socclk_mhz = dcn3_02_soc.clock_limits[i-1].socclk_mhz;
+ else
+ dcn3_02_soc.clock_limits[i].socclk_mhz = bw_params->clk_table.entries[i].socclk_mhz;
+ /* These clocks cannot come from bw_params, always fill from dcn3_02_soc[1] */
+ /* FCLK, PHYCLK_D18, DSCCLK */
+ dcn3_02_soc.clock_limits[i].phyclk_d18_mhz = dcn3_02_soc.clock_limits[0].phyclk_d18_mhz;
+ dcn3_02_soc.clock_limits[i].dscclk_mhz = dcn3_02_soc.clock_limits[0].dscclk_mhz;
+ }
+ /* re-init DML with updated bb */
+ dml_init_instance(&dc->dml, &dcn3_02_soc, &dcn3_02_ip, DML_PROJECT_DCN30);
+ if (dc->current_state)
+ dml_init_instance(&dc->current_state->bw_ctx.dml, &dcn3_02_soc, &dcn3_02_ip, DML_PROJECT_DCN30);
+ }
+}
+
+void dcn302_fpu_init_soc_bounding_box(struct bp_soc_bb_info bb_info)
+{
+
+ dc_assert_fp_enabled();
+
+ if (bb_info.dram_clock_change_latency_100ns > 0)
+ dcn3_02_soc.dram_clock_change_latency_us =
+ bb_info.dram_clock_change_latency_100ns * 10;
+
+ if (bb_info.dram_sr_enter_exit_latency_100ns > 0)
+ dcn3_02_soc.sr_enter_plus_exit_time_us =
+ bb_info.dram_sr_enter_exit_latency_100ns * 10;
+
+ if (bb_info.dram_sr_exit_latency_100ns > 0)
+ dcn3_02_soc.sr_exit_time_us =
+ bb_info.dram_sr_exit_latency_100ns * 10;
+}
+
+
diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn302/dcn302_fpu.h b/drivers/gpu/drm/amd/display/dc/dml/dcn302/dcn302_fpu.h
new file mode 100644
index 000000000000..548305d96cee
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/dc/dml/dcn302/dcn302_fpu.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2019-2021 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: AMD
+ *
+ */
+
+#ifndef __DCN302_FPU_H__
+#define __DCN302_FPU_H__
+
+void dcn302_fpu_init_soc_bounding_box(struct bp_soc_bb_info bb_info);
+void dcn302_fpu_update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_params);
+
+#endif /* __DCN302_FPU_H__*/
diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn303/dcn303_fpu.c b/drivers/gpu/drm/amd/display/dc/dml/dcn303/dcn303_fpu.c
new file mode 100644
index 000000000000..8fb14baed208
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/dc/dml/dcn303/dcn303_fpu.c
@@ -0,0 +1,362 @@
+/*
+ * Copyright 2019-2021 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: AMD
+ *
+ */
+#include "resource.h"
+#include "clk_mgr.h"
+#include "dcn20/dcn20_resource.h"
+#include "dcn303/dcn303_resource.h"
+
+#include "dml/dcn20/dcn20_fpu.h"
+#include "dcn303_fpu.h"
+
+struct _vcs_dpi_ip_params_st dcn3_03_ip = {
+ .use_min_dcfclk = 0,
+ .clamp_min_dcfclk = 0,
+ .odm_capable = 1,
+ .gpuvm_enable = 1,
+ .hostvm_enable = 0,
+ .gpuvm_max_page_table_levels = 4,
+ .hostvm_max_page_table_levels = 4,
+ .hostvm_cached_page_table_levels = 0,
+ .pte_group_size_bytes = 2048,
+ .num_dsc = 2,
+ .rob_buffer_size_kbytes = 184,
+ .det_buffer_size_kbytes = 184,
+ .dpte_buffer_size_in_pte_reqs_luma = 64,
+ .dpte_buffer_size_in_pte_reqs_chroma = 34,
+ .pde_proc_buffer_size_64k_reqs = 48,
+ .dpp_output_buffer_pixels = 2560,
+ .opp_output_buffer_lines = 1,
+ .pixel_chunk_size_kbytes = 8,
+ .pte_enable = 1,
+ .max_page_table_levels = 2,
+ .pte_chunk_size_kbytes = 2, // ?
+ .meta_chunk_size_kbytes = 2,
+ .writeback_chunk_size_kbytes = 8,
+ .line_buffer_size_bits = 789504,
+ .is_line_buffer_bpp_fixed = 0, // ?
+ .line_buffer_fixed_bpp = 0, // ?
+ .dcc_supported = true,
+ .writeback_interface_buffer_size_kbytes = 90,
+ .writeback_line_buffer_buffer_size = 0,
+ .max_line_buffer_lines = 12,
+ .writeback_luma_buffer_size_kbytes = 12, // writeback_line_buffer_buffer_size = 656640
+ .writeback_chroma_buffer_size_kbytes = 8,
+ .writeback_chroma_line_buffer_width_pixels = 4,
+ .writeback_max_hscl_ratio = 1,
+ .writeback_max_vscl_ratio = 1,
+ .writeback_min_hscl_ratio = 1,
+ .writeback_min_vscl_ratio = 1,
+ .writeback_max_hscl_taps = 1,
+ .writeback_max_vscl_taps = 1,
+ .writeback_line_buffer_luma_buffer_size = 0,
+ .writeback_line_buffer_chroma_buffer_size = 14643,
+ .cursor_buffer_size = 8,
+ .cursor_chunk_size = 2,
+ .max_num_otg = 2,
+ .max_num_dpp = 2,
+ .max_num_wb = 1,
+ .max_dchub_pscl_bw_pix_per_clk = 4,
+ .max_pscl_lb_bw_pix_per_clk = 2,
+ .max_lb_vscl_bw_pix_per_clk = 4,
+ .max_vscl_hscl_bw_pix_per_clk = 4,
+ .max_hscl_ratio = 6,
+ .max_vscl_ratio = 6,
+ .hscl_mults = 4,
+ .vscl_mults = 4,
+ .max_hscl_taps = 8,
+ .max_vscl_taps = 8,
+ .dispclk_ramp_margin_percent = 1,
+ .underscan_factor = 1.11,
+ .min_vblank_lines = 32,
+ .dppclk_delay_subtotal = 46,
+ .dynamic_metadata_vm_enabled = true,
+ .dppclk_delay_scl_lb_only = 16,
+ .dppclk_delay_scl = 50,
+ .dppclk_delay_cnvc_formatter = 27,
+ .dppclk_delay_cnvc_cursor = 6,
+ .dispclk_delay_subtotal = 119,
+ .dcfclk_cstate_latency = 5.2, // SRExitTime
+ .max_inter_dcn_tile_repeaters = 8,
+ .max_num_hdmi_frl_outputs = 1,
+ .odm_combine_4to1_supported = false,
+
+ .xfc_supported = false,
+ .xfc_fill_bw_overhead_percent = 10.0,
+ .xfc_fill_constant_bytes = 0,
+ .gfx7_compat_tiling_supported = 0,
+ .number_of_cursors = 1,
+};
+
+struct _vcs_dpi_soc_bounding_box_st dcn3_03_soc = {
+ .clock_limits = {
+ {
+ .state = 0,
+ .dispclk_mhz = 562.0,
+ .dppclk_mhz = 300.0,
+ .phyclk_mhz = 300.0,
+ .phyclk_d18_mhz = 667.0,
+ .dscclk_mhz = 405.6,
+ },
+ },
+
+ .min_dcfclk = 500.0, /* TODO: set this to actual min DCFCLK */
+ .num_states = 1,
+ .sr_exit_time_us = 35.5,
+ .sr_enter_plus_exit_time_us = 40,
+ .urgent_latency_us = 4.0,
+ .urgent_latency_pixel_data_only_us = 4.0,
+ .urgent_latency_pixel_mixed_with_vm_data_us = 4.0,
+ .urgent_latency_vm_data_only_us = 4.0,
+ .urgent_out_of_order_return_per_channel_pixel_only_bytes = 4096,
+ .urgent_out_of_order_return_per_channel_pixel_and_vm_bytes = 4096,
+ .urgent_out_of_order_return_per_channel_vm_only_bytes = 4096,
+ .pct_ideal_dram_sdp_bw_after_urgent_pixel_only = 80.0,
+ .pct_ideal_dram_sdp_bw_after_urgent_pixel_and_vm = 60.0,
+ .pct_ideal_dram_sdp_bw_after_urgent_vm_only = 40.0,
+ .max_avg_sdp_bw_use_normal_percent = 60.0,
+ .max_avg_dram_bw_use_normal_percent = 40.0,
+ .writeback_latency_us = 12.0,
+ .max_request_size_bytes = 256,
+ .fabric_datapath_to_dcn_data_return_bytes = 64,
+ .dcn_downspread_percent = 0.5,
+ .downspread_percent = 0.38,
+ .dram_page_open_time_ns = 50.0,
+ .dram_rw_turnaround_time_ns = 17.5,
+ .dram_return_buffer_per_channel_bytes = 8192,
+ .round_trip_ping_latency_dcfclk_cycles = 156,
+ .urgent_out_of_order_return_per_channel_bytes = 4096,
+ .channel_interleave_bytes = 256,
+ .num_banks = 8,
+ .gpuvm_min_page_size_bytes = 4096,
+ .hostvm_min_page_size_bytes = 4096,
+ .dram_clock_change_latency_us = 404,
+ .dummy_pstate_latency_us = 5,
+ .writeback_dram_clock_change_latency_us = 23.0,
+ .return_bus_width_bytes = 64,
+ .dispclk_dppclk_vco_speed_mhz = 3650,
+ .xfc_bus_transport_time_us = 20, // ?
+ .xfc_xbuf_latency_tolerance_us = 4, // ?
+ .use_urgent_burst_bw = 1, // ?
+ .do_urgent_latency_adjustment = true,
+ .urgent_latency_adjustment_fabric_clock_component_us = 1.0,
+ .urgent_latency_adjustment_fabric_clock_reference_mhz = 1000,
+};
+
+static void dcn303_get_optimal_dcfclk_fclk_for_uclk(unsigned int uclk_mts,
+ unsigned int *optimal_dcfclk,
+ unsigned int *optimal_fclk)
+{
+ double bw_from_dram, bw_from_dram1, bw_from_dram2;
+
+ bw_from_dram1 = uclk_mts * dcn3_03_soc.num_chans *
+ dcn3_03_soc.dram_channel_width_bytes * (dcn3_03_soc.max_avg_dram_bw_use_normal_percent / 100);
+ bw_from_dram2 = uclk_mts * dcn3_03_soc.num_chans *
+ dcn3_03_soc.dram_channel_width_bytes * (dcn3_03_soc.max_avg_sdp_bw_use_normal_percent / 100);
+
+ bw_from_dram = (bw_from_dram1 < bw_from_dram2) ? bw_from_dram1 : bw_from_dram2;
+
+ if (optimal_fclk)
+ *optimal_fclk = bw_from_dram /
+ (dcn3_03_soc.fabric_datapath_to_dcn_data_return_bytes *
+ (dcn3_03_soc.max_avg_sdp_bw_use_normal_percent / 100));
+
+ if (optimal_dcfclk)
+ *optimal_dcfclk = bw_from_dram /
+ (dcn3_03_soc.return_bus_width_bytes * (dcn3_03_soc.max_avg_sdp_bw_use_normal_percent / 100));
+}
+
+
+void dcn303_fpu_update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_params)
+{
+ unsigned int i, j;
+ unsigned int num_states = 0;
+
+ unsigned int dcfclk_mhz[DC__VOLTAGE_STATES] = {0};
+ unsigned int dram_speed_mts[DC__VOLTAGE_STATES] = {0};
+ unsigned int optimal_uclk_for_dcfclk_sta_targets[DC__VOLTAGE_STATES] = {0};
+ unsigned int optimal_dcfclk_for_uclk[DC__VOLTAGE_STATES] = {0};
+
+ unsigned int dcfclk_sta_targets[DC__VOLTAGE_STATES] = {694, 875, 1000, 1200};
+ unsigned int num_dcfclk_sta_targets = 4;
+ unsigned int num_uclk_states;
+
+ dc_assert_fp_enabled();
+
+ if (dc->ctx->dc_bios->vram_info.num_chans)
+ dcn3_03_soc.num_chans = dc->ctx->dc_bios->vram_info.num_chans;
+
+ if (dc->ctx->dc_bios->vram_info.dram_channel_width_bytes)
+ dcn3_03_soc.dram_channel_width_bytes = dc->ctx->dc_bios->vram_info.dram_channel_width_bytes;
+
+ dcn3_03_soc.dispclk_dppclk_vco_speed_mhz = dc->clk_mgr->dentist_vco_freq_khz / 1000.0;
+ dc->dml.soc.dispclk_dppclk_vco_speed_mhz = dc->clk_mgr->dentist_vco_freq_khz / 1000.0;
+
+ if (bw_params->clk_table.entries[0].memclk_mhz) {
+ int max_dcfclk_mhz = 0, max_dispclk_mhz = 0, max_dppclk_mhz = 0, max_phyclk_mhz = 0;
+
+ for (i = 0; i < MAX_NUM_DPM_LVL; i++) {
+ if (bw_params->clk_table.entries[i].dcfclk_mhz > max_dcfclk_mhz)
+ max_dcfclk_mhz = bw_params->clk_table.entries[i].dcfclk_mhz;
+ if (bw_params->clk_table.entries[i].dispclk_mhz > max_dispclk_mhz)
+ max_dispclk_mhz = bw_params->clk_table.entries[i].dispclk_mhz;
+ if (bw_params->clk_table.entries[i].dppclk_mhz > max_dppclk_mhz)
+ max_dppclk_mhz = bw_params->clk_table.entries[i].dppclk_mhz;
+ if (bw_params->clk_table.entries[i].phyclk_mhz > max_phyclk_mhz)
+ max_phyclk_mhz = bw_params->clk_table.entries[i].phyclk_mhz;
+ }
+ if (!max_dcfclk_mhz)
+ max_dcfclk_mhz = dcn3_03_soc.clock_limits[0].dcfclk_mhz;
+ if (!max_dispclk_mhz)
+ max_dispclk_mhz = dcn3_03_soc.clock_limits[0].dispclk_mhz;
+ if (!max_dppclk_mhz)
+ max_dppclk_mhz = dcn3_03_soc.clock_limits[0].dppclk_mhz;
+ if (!max_phyclk_mhz)
+ max_phyclk_mhz = dcn3_03_soc.clock_limits[0].phyclk_mhz;
+
+ if (max_dcfclk_mhz > dcfclk_sta_targets[num_dcfclk_sta_targets-1]) {
+ dcfclk_sta_targets[num_dcfclk_sta_targets] = max_dcfclk_mhz;
+ num_dcfclk_sta_targets++;
+ } else if (max_dcfclk_mhz < dcfclk_sta_targets[num_dcfclk_sta_targets-1]) {
+ for (i = 0; i < num_dcfclk_sta_targets; i++) {
+ if (dcfclk_sta_targets[i] > max_dcfclk_mhz) {
+ dcfclk_sta_targets[i] = max_dcfclk_mhz;
+ break;
+ }
+ }
+ /* Update size of array since we "removed" duplicates */
+ num_dcfclk_sta_targets = i + 1;
+ }
+
+ num_uclk_states = bw_params->clk_table.num_entries;
+
+ /* Calculate optimal dcfclk for each uclk */
+ for (i = 0; i < num_uclk_states; i++) {
+ dcn303_get_optimal_dcfclk_fclk_for_uclk(bw_params->clk_table.entries[i].memclk_mhz * 16,
+ &optimal_dcfclk_for_uclk[i], NULL);
+ if (optimal_dcfclk_for_uclk[i] < bw_params->clk_table.entries[0].dcfclk_mhz)
+ optimal_dcfclk_for_uclk[i] = bw_params->clk_table.entries[0].dcfclk_mhz;
+ }
+
+ /* Calculate optimal uclk for each dcfclk sta target */
+ for (i = 0; i < num_dcfclk_sta_targets; i++) {
+ for (j = 0; j < num_uclk_states; j++) {
+ if (dcfclk_sta_targets[i] < optimal_dcfclk_for_uclk[j]) {
+ optimal_uclk_for_dcfclk_sta_targets[i] =
+ bw_params->clk_table.entries[j].memclk_mhz * 16;
+ break;
+ }
+ }
+ }
+
+ i = 0;
+ j = 0;
+ /* create the final dcfclk and uclk table */
+ while (i < num_dcfclk_sta_targets && j < num_uclk_states && num_states < DC__VOLTAGE_STATES) {
+ if (dcfclk_sta_targets[i] < optimal_dcfclk_for_uclk[j] && i < num_dcfclk_sta_targets) {
+ dcfclk_mhz[num_states] = dcfclk_sta_targets[i];
+ dram_speed_mts[num_states++] = optimal_uclk_for_dcfclk_sta_targets[i++];
+ } else {
+ if (j < num_uclk_states && optimal_dcfclk_for_uclk[j] <= max_dcfclk_mhz) {
+ dcfclk_mhz[num_states] = optimal_dcfclk_for_uclk[j];
+ dram_speed_mts[num_states++] =
+ bw_params->clk_table.entries[j++].memclk_mhz * 16;
+ } else {
+ j = num_uclk_states;
+ }
+ }
+ }
+
+ while (i < num_dcfclk_sta_targets && num_states < DC__VOLTAGE_STATES) {
+ dcfclk_mhz[num_states] = dcfclk_sta_targets[i];
+ dram_speed_mts[num_states++] = optimal_uclk_for_dcfclk_sta_targets[i++];
+ }
+
+ while (j < num_uclk_states && num_states < DC__VOLTAGE_STATES &&
+ optimal_dcfclk_for_uclk[j] <= max_dcfclk_mhz) {
+ dcfclk_mhz[num_states] = optimal_dcfclk_for_uclk[j];
+ dram_speed_mts[num_states++] = bw_params->clk_table.entries[j++].memclk_mhz * 16;
+ }
+
+ dcn3_03_soc.num_states = num_states;
+ for (i = 0; i < dcn3_03_soc.num_states; i++) {
+ dcn3_03_soc.clock_limits[i].state = i;
+ dcn3_03_soc.clock_limits[i].dcfclk_mhz = dcfclk_mhz[i];
+ dcn3_03_soc.clock_limits[i].fabricclk_mhz = dcfclk_mhz[i];
+ dcn3_03_soc.clock_limits[i].dram_speed_mts = dram_speed_mts[i];
+
+ /* Fill all states with max values of all other clocks */
+ dcn3_03_soc.clock_limits[i].dispclk_mhz = max_dispclk_mhz;
+ dcn3_03_soc.clock_limits[i].dppclk_mhz = max_dppclk_mhz;
+ dcn3_03_soc.clock_limits[i].phyclk_mhz = max_phyclk_mhz;
+ /* Populate from bw_params for DTBCLK, SOCCLK */
+ if (!bw_params->clk_table.entries[i].dtbclk_mhz && i > 0)
+ dcn3_03_soc.clock_limits[i].dtbclk_mhz = dcn3_03_soc.clock_limits[i-1].dtbclk_mhz;
+ else
+ dcn3_03_soc.clock_limits[i].dtbclk_mhz = bw_params->clk_table.entries[i].dtbclk_mhz;
+ if (!bw_params->clk_table.entries[i].socclk_mhz && i > 0)
+ dcn3_03_soc.clock_limits[i].socclk_mhz = dcn3_03_soc.clock_limits[i-1].socclk_mhz;
+ else
+ dcn3_03_soc.clock_limits[i].socclk_mhz = bw_params->clk_table.entries[i].socclk_mhz;
+ /* These clocks cannot come from bw_params, always fill from dcn3_03_soc[1] */
+ /* FCLK, PHYCLK_D18, DSCCLK */
+ dcn3_03_soc.clock_limits[i].phyclk_d18_mhz = dcn3_03_soc.clock_limits[0].phyclk_d18_mhz;
+ dcn3_03_soc.clock_limits[i].dscclk_mhz = dcn3_03_soc.clock_limits[0].dscclk_mhz;
+ }
+
+ if (dcn3_03_soc.num_chans <= 4) {
+ for (i = 0; i < dcn3_03_soc.num_states; i++) {
+ if (dcn3_03_soc.clock_limits[i].dram_speed_mts > 1700)
+ break;
+
+ if (dcn3_03_soc.clock_limits[i].dram_speed_mts >= 1500) {
+ dcn3_03_soc.clock_limits[i].dcfclk_mhz = 100;
+ dcn3_03_soc.clock_limits[i].fabricclk_mhz = 100;
+ }
+ }
+ }
+
+ /* re-init DML with updated bb */
+ dml_init_instance(&dc->dml, &dcn3_03_soc, &dcn3_03_ip, DML_PROJECT_DCN30);
+ if (dc->current_state)
+ dml_init_instance(&dc->current_state->bw_ctx.dml, &dcn3_03_soc, &dcn3_03_ip, DML_PROJECT_DCN30);
+ }
+}
+
+void dcn303_fpu_init_soc_bounding_box(struct bp_soc_bb_info bb_info)
+{
+ dc_assert_fp_enabled();
+
+ if (bb_info.dram_clock_change_latency_100ns > 0)
+ dcn3_03_soc.dram_clock_change_latency_us =
+ bb_info.dram_clock_change_latency_100ns * 10;
+
+ if (bb_info.dram_sr_enter_exit_latency_100ns > 0)
+ dcn3_03_soc.sr_enter_plus_exit_time_us =
+ bb_info.dram_sr_enter_exit_latency_100ns * 10;
+
+ if (bb_info.dram_sr_exit_latency_100ns > 0)
+ dcn3_03_soc.sr_exit_time_us =
+ bb_info.dram_sr_exit_latency_100ns * 10;
+}
diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn303/dcn303_fpu.h b/drivers/gpu/drm/amd/display/dc/dml/dcn303/dcn303_fpu.h
new file mode 100644
index 000000000000..92ec833fa528
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/dc/dml/dcn303/dcn303_fpu.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2019-2021 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: AMD
+ *
+ */
+
+#ifndef __DCN303_FPU_H__
+#define __DCN303_FPU_H__
+
+void dcn303_fpu_update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_params);
+void dcn303_fpu_init_soc_bounding_box(struct bp_soc_bb_info bb_info);
+
+#endif /* __DCN303_FPU_H__*/
diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn31/display_mode_vba_31.c b/drivers/gpu/drm/amd/display/dc/dml/dcn31/display_mode_vba_31.c
index 6feb23432f8d..e4b9fd31223c 100644
--- a/drivers/gpu/drm/amd/display/dc/dml/dcn31/display_mode_vba_31.c
+++ b/drivers/gpu/drm/amd/display/dc/dml/dcn31/display_mode_vba_31.c
@@ -64,6 +64,8 @@ typedef struct {
double DCFCLKDeepSleep;
unsigned int DPPPerPlane;
bool ScalerEnabled;
+ double VRatio;
+ double VRatioChroma;
enum scan_direction_class SourceScan;
unsigned int BlockWidth256BytesY;
unsigned int BlockHeight256BytesY;
@@ -942,6 +944,7 @@ static bool CalculatePrefetchSchedule(
double dst_y_prefetch_equ;
double Tsw_oto;
double prefetch_bw_oto;
+ double prefetch_bw_pr;
double Tvm_oto;
double Tr0_oto;
double Tvm_oto_lines;
@@ -971,6 +974,7 @@ static bool CalculatePrefetchSchedule(
double min_Lsw;
double Tsw_est1 = 0;
double Tsw_est3 = 0;
+ double max_Tsw = 0;
if (GPUVMEnable == true && HostVMEnable == true) {
HostVMDynamicLevelsTrips = HostVMMaxNonCachedPageTableLevels;
@@ -1111,11 +1115,14 @@ static bool CalculatePrefetchSchedule(
bytes_pp = myPipe->BytePerPixelY + myPipe->BytePerPixelC / 4;
else
bytes_pp = myPipe->BytePerPixelY + myPipe->BytePerPixelC;
-
+ /*rev 99*/
+ prefetch_bw_pr = dml_min(1, bytes_pp * myPipe->PixelClock / (double) myPipe->DPPPerPlane);
+ max_Tsw = dml_max(PrefetchSourceLinesY, PrefetchSourceLinesC) * LineTime;
prefetch_sw_bytes = PrefetchSourceLinesY * swath_width_luma_ub * myPipe->BytePerPixelY + PrefetchSourceLinesC * swath_width_chroma_ub * myPipe->BytePerPixelC;
prefetch_bw_oto = dml_max(bytes_pp * myPipe->PixelClock / myPipe->DPPPerPlane, prefetch_sw_bytes / (dml_max(PrefetchSourceLinesY, PrefetchSourceLinesC) * LineTime));
+ prefetch_bw_oto = dml_max(prefetch_bw_pr, prefetch_sw_bytes / max_Tsw);
- min_Lsw = dml_max(PrefetchSourceLinesY, PrefetchSourceLinesC) / max_vratio_pre;
+ min_Lsw = dml_max(1, dml_max(PrefetchSourceLinesY, PrefetchSourceLinesC) / max_vratio_pre);
Lsw_oto = dml_ceil(4 * dml_max(prefetch_sw_bytes / prefetch_bw_oto / LineTime, min_Lsw), 1) / 4;
Tsw_oto = Lsw_oto * LineTime;
@@ -1389,7 +1396,7 @@ static bool CalculatePrefetchSchedule(
dml_print("DML::%s: SwathHeightC = %d\n", __func__, SwathHeightC);
dml_print("DML::%s: VInitPreFillC = %f\n", __func__, VInitPreFillC);
#endif
- if ((SwathHeightC > 4)) {
+ if ((SwathHeightC > 4) || VInitPreFillC > 3) {
if (LinesToRequestPrefetchPixelData > (VInitPreFillC - 3.0) / 2.0) {
*VRatioPrefetchC = dml_max(
*VRatioPrefetchC,
@@ -2663,6 +2670,8 @@ static void DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerforman
myPipe.DCFCLKDeepSleep = v->DCFCLKDeepSleep;
myPipe.DPPPerPlane = v->DPPPerPlane[k];
myPipe.ScalerEnabled = v->ScalerEnabled[k];
+ myPipe.VRatio = v->VRatio[k];
+ myPipe.VRatioChroma = v->VRatioChroma[k];
myPipe.SourceScan = v->SourceScan[k];
myPipe.BlockWidth256BytesY = v->BlockWidth256BytesY[k];
myPipe.BlockHeight256BytesY = v->BlockHeight256BytesY[k];
@@ -3911,6 +3920,9 @@ static noinline void CalculatePrefetchSchedulePerPlane(
myPipe.DCFCLKDeepSleep = v->ProjectedDCFCLKDeepSleep[i][j];
myPipe.DPPPerPlane = v->NoOfDPP[i][j][k];
myPipe.ScalerEnabled = v->ScalerEnabled[k];
+ myPipe.VRatio = mode_lib->vba.VRatio[k];
+ myPipe.VRatioChroma = mode_lib->vba.VRatioChroma[k];
+
myPipe.SourceScan = v->SourceScan[k];
myPipe.BlockWidth256BytesY = v->Read256BlockWidthY[k];
myPipe.BlockHeight256BytesY = v->Read256BlockHeightY[k];
@@ -4987,6 +4999,17 @@ void dml31_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
&v->meta_row_bandwidth[i][j][k],
&v->dpte_row_bandwidth[i][j][k]);
}
+ /*DCCMetaBufferSizeSupport(i, j) = True
+ For k = 0 To NumberOfActivePlanes - 1
+ If MetaRowBytes(i, j, k) > 24064 Then
+ DCCMetaBufferSizeSupport(i, j) = False
+ End If
+ Next k*/
+ v->DCCMetaBufferSizeSupport[i][j] = true;
+ for (k = 0; k < v->NumberOfActivePlanes; ++k) {
+ if (v->MetaRowBytes[i][j][k] > 24064)
+ v->DCCMetaBufferSizeSupport[i][j] = false;
+ }
v->UrgLatency[i] = CalculateUrgentLatency(
v->UrgentLatencyPixelDataOnly,
v->UrgentLatencyPixelMixedWithVMData,
diff --git a/drivers/gpu/drm/amd/display/dc/dml/display_mode_structs.h b/drivers/gpu/drm/amd/display/dc/dml/display_mode_structs.h
index d46a2733024c..59f0a61c33cf 100644
--- a/drivers/gpu/drm/amd/display/dc/dml/display_mode_structs.h
+++ b/drivers/gpu/drm/amd/display/dc/dml/display_mode_structs.h
@@ -141,6 +141,7 @@ struct _vcs_dpi_ip_params_st {
unsigned int odm_capable;
unsigned int rob_buffer_size_kbytes;
unsigned int det_buffer_size_kbytes;
+ unsigned int min_comp_buffer_size_kbytes;
unsigned int dpte_buffer_size_in_pte_reqs_luma;
unsigned int dpte_buffer_size_in_pte_reqs_chroma;
unsigned int pde_proc_buffer_size_64k_reqs;
@@ -546,7 +547,6 @@ struct _vcs_dpi_display_dlg_sys_params_st {
double t_sr_wm_us;
double t_extra_us;
double mem_trip_us;
- double t_srx_delay_us;
double deepsleep_dcfclk_mhz;
double total_flip_bw;
unsigned int total_flip_bytes;
diff --git a/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.c b/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.c
index 0fad15020c74..c0740dbdcc2e 100644
--- a/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.c
+++ b/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.c
@@ -47,6 +47,7 @@ static void recalculate_params(
unsigned int num_pipes);
static unsigned int CursorBppEnumToBits(enum cursor_bpp ebpp);
+static void cache_debug_params(struct display_mode_lib *mode_lib);
unsigned int dml_get_voltage_level(
struct display_mode_lib *mode_lib,
@@ -73,6 +74,7 @@ unsigned int dml_get_voltage_level(
PixelClockAdjustmentForProgressiveToInterlaceUnit(mode_lib);
}
mode_lib->funcs.validate(mode_lib);
+ cache_debug_params(mode_lib);
return mode_lib->vba.VoltageLevel;
}
@@ -745,6 +747,28 @@ static void fetch_pipe_params(struct display_mode_lib *mode_lib)
mode_lib->vba.HostVMEnable = mode_lib->vba.HostVMEnable && !!ip->hostvm_enable;
}
+/**
+ * ********************************************************************************************
+ * cache_debug_params: Cache any params that needed to be maintained from the initial validation
+ * for debug purposes.
+ *
+ * The DML getters can modify some of the VBA params that we are interested in (for example when
+ * calculating with dummy p-state latency), so cache any params here that we want for debugging
+ *
+ * @param [in] mode_lib: mode_lib input/output of validate call
+ *
+ * @return: void
+ *
+ * ********************************************************************************************
+ */
+static void cache_debug_params(struct display_mode_lib *mode_lib)
+{
+ int k = 0;
+
+ for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; k++)
+ mode_lib->vba.CachedActiveDRAMClockChangeLatencyMargin[k] = mode_lib->vba.ActiveDRAMClockChangeLatencyMargin[k];
+}
+
// in wm mode we pull the parameters needed from the display_e2e_pipe_params_st structs
// rather than working them out as in recalculate_ms
static void recalculate_params(
diff --git a/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.h b/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.h
index 90e87961fe3e..0603b32971a6 100644
--- a/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.h
+++ b/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.h
@@ -195,6 +195,7 @@ struct vba_vars_st {
unsigned int LBLatencyHidingSourceLinesY;
unsigned int LBLatencyHidingSourceLinesC;
double ActiveDRAMClockChangeLatencyMargin[DC__NUM_DPP__MAX];
+ double CachedActiveDRAMClockChangeLatencyMargin[DC__NUM_DPP__MAX]; // Cache in dml_get_voltage_level for debug purposes only
double MinActiveDRAMClockChangeMargin;
double InitFillLevel;
double FinalFillMargin;
@@ -544,6 +545,8 @@ struct vba_vars_st {
bool DTBCLKRequiredMoreThanSupported[DC__VOLTAGE_STATES];
double UrgentRoundTripAndOutOfOrderLatencyPerState[DC__VOLTAGE_STATES];
bool ROBSupport[DC__VOLTAGE_STATES][2];
+ //based on rev 99: Dim DCCMetaBufferSizeSupport(NumberOfStates, 1) As Boolean
+ bool DCCMetaBufferSizeSupport[DC__VOLTAGE_STATES][2];
bool PTEBufferSizeNotExceeded[DC__VOLTAGE_STATES][2];
bool TotalVerticalActiveBandwidthSupport[DC__VOLTAGE_STATES][2];
double MaxTotalVerticalActiveAvailableBandwidth[DC__VOLTAGE_STATES][2];
diff --git a/drivers/gpu/drm/amd/display/dc/dml/display_rq_dlg_helpers.c b/drivers/gpu/drm/amd/display/dc/dml/display_rq_dlg_helpers.c
index 71ea503cb32f..412e75eb4704 100644
--- a/drivers/gpu/drm/amd/display/dc/dml/display_rq_dlg_helpers.c
+++ b/drivers/gpu/drm/amd/display/dc/dml/display_rq_dlg_helpers.c
@@ -142,9 +142,6 @@ void print__dlg_sys_params_st(struct display_mode_lib *mode_lib, const struct _v
dml_print("DML_RQ_DLG_CALC: t_sr_wm_us = %3.2f\n", dlg_sys_param->t_sr_wm_us);
dml_print("DML_RQ_DLG_CALC: t_extra_us = %3.2f\n", dlg_sys_param->t_extra_us);
dml_print(
- "DML_RQ_DLG_CALC: t_srx_delay_us = %3.2f\n",
- dlg_sys_param->t_srx_delay_us);
- dml_print(
"DML_RQ_DLG_CALC: deepsleep_dcfclk_mhz = %3.2f\n",
dlg_sys_param->deepsleep_dcfclk_mhz);
dml_print(
diff --git a/drivers/gpu/drm/amd/display/dc/dml/dml1_display_rq_dlg_calc.c b/drivers/gpu/drm/amd/display/dc/dml/dml1_display_rq_dlg_calc.c
index 59dc2c5b58dd..3df559c591f8 100644
--- a/drivers/gpu/drm/amd/display/dc/dml/dml1_display_rq_dlg_calc.c
+++ b/drivers/gpu/drm/amd/display/dc/dml/dml1_display_rq_dlg_calc.c
@@ -1331,10 +1331,6 @@ void dml1_rq_dlg_get_dlg_params(
if (dual_plane)
DTRACE("DLG: %s: swath_height_c = %d", __func__, swath_height_c);
- DTRACE(
- "DLG: %s: t_srx_delay_us = %3.2f",
- __func__,
- (double) dlg_sys_param->t_srx_delay_us);
DTRACE("DLG: %s: line_time_in_us = %3.2f", __func__, (double) line_time_in_us);
DTRACE("DLG: %s: vupdate_offset = %d", __func__, vupdate_offset);
DTRACE("DLG: %s: vupdate_width = %d", __func__, vupdate_width);
diff --git a/drivers/gpu/drm/amd/display/dc/dml/dsc/rc_calc_fpu.c b/drivers/gpu/drm/amd/display/dc/dml/dsc/rc_calc_fpu.c
index ec636d06e18c..ef75eb7d5adc 100644
--- a/drivers/gpu/drm/amd/display/dc/dml/dsc/rc_calc_fpu.c
+++ b/drivers/gpu/drm/amd/display/dc/dml/dsc/rc_calc_fpu.c
@@ -68,7 +68,7 @@ static void get_qp_set(qp_set qps, enum colour_mode cm, enum bits_per_comp bpc,
int sel = table_hash(mode, bpc, max_min);
int table_size = 0;
int index;
- const struct qp_entry *table = 0L;
+ const struct qp_entry *table = NULL;
// alias enum
enum { min = DAL_MM_MIN, max = DAL_MM_MAX };
diff --git a/drivers/gpu/drm/amd/display/dc/dsc/dc_dsc.c b/drivers/gpu/drm/amd/display/dc/dsc/dc_dsc.c
index 9c74564cbd8d..efc2339f1fa0 100644
--- a/drivers/gpu/drm/amd/display/dc/dsc/dc_dsc.c
+++ b/drivers/gpu/drm/amd/display/dc/dsc/dc_dsc.c
@@ -25,7 +25,7 @@
#include <drm/drm_dsc.h>
#include "dc_hw_types.h"
#include "dsc.h"
-#include <drm/drm_dp_helper.h>
+#include <drm/dp/drm_dp_helper.h>
#include "dc.h"
#include "rc_calc.h"
#include "fixed31_32.h"
diff --git a/drivers/gpu/drm/amd/display/dc/gpio/Makefile b/drivers/gpu/drm/amd/display/dc/gpio/Makefile
index c5ddade8b187..d1c2ec58676d 100644
--- a/drivers/gpu/drm/amd/display/dc/gpio/Makefile
+++ b/drivers/gpu/drm/amd/display/dc/gpio/Makefile
@@ -106,6 +106,14 @@ GPIO_DCN30 = hw_translate_dcn30.o hw_factory_dcn30.o
AMD_DAL_GPIO_DCN30 = $(addprefix $(AMDDALPATH)/dc/gpio/dcn30/,$(GPIO_DCN30))
AMD_DISPLAY_FILES += $(AMD_DAL_GPIO_DCN30)
+###############################################################################
+# DCN 3.15
+###############################################################################
+GPIO_DCN315 = hw_translate_dcn315.o hw_factory_dcn315.o
+
+AMD_DAL_GPIO_DCN315 = $(addprefix $(AMDDALPATH)/dc/gpio/dcn315/,$(GPIO_DCN315))
+
+AMD_DISPLAY_FILES += $(AMD_DAL_GPIO_DCN315)
endif
###############################################################################
# Diagnostics on FPGA
diff --git a/drivers/gpu/drm/amd/display/dc/gpio/dcn30/hw_factory_dcn30.c b/drivers/gpu/drm/amd/display/dc/gpio/dcn30/hw_factory_dcn30.c
index 5f6ae3edb755..3b7df1ac26be 100644
--- a/drivers/gpu/drm/amd/display/dc/gpio/dcn30/hw_factory_dcn30.c
+++ b/drivers/gpu/drm/amd/display/dc/gpio/dcn30/hw_factory_dcn30.c
@@ -42,8 +42,8 @@
#include "nbio/nbio_7_4_offset.h"
-#include "dcn/dpcs_3_0_0_offset.h"
-#include "dcn/dpcs_3_0_0_sh_mask.h"
+#include "dpcs/dpcs_3_0_0_offset.h"
+#include "dpcs/dpcs_3_0_0_sh_mask.h"
#include "mmhub/mmhub_2_0_0_offset.h"
#include "mmhub/mmhub_2_0_0_sh_mask.h"
diff --git a/drivers/gpu/drm/amd/display/dc/gpio/dcn30/hw_translate_dcn30.c b/drivers/gpu/drm/amd/display/dc/gpio/dcn30/hw_translate_dcn30.c
index 0046219a1cc7..6b6b7c7bd12f 100644
--- a/drivers/gpu/drm/amd/display/dc/gpio/dcn30/hw_translate_dcn30.c
+++ b/drivers/gpu/drm/amd/display/dc/gpio/dcn30/hw_translate_dcn30.c
@@ -40,8 +40,8 @@
#include "nbio/nbio_7_4_offset.h"
-#include "dcn/dpcs_3_0_0_offset.h"
-#include "dcn/dpcs_3_0_0_sh_mask.h"
+#include "dpcs/dpcs_3_0_0_offset.h"
+#include "dpcs/dpcs_3_0_0_sh_mask.h"
#include "mmhub/mmhub_2_0_0_offset.h"
#include "mmhub/mmhub_2_0_0_sh_mask.h"
diff --git a/drivers/gpu/drm/amd/display/dc/gpio/dcn315/hw_factory_dcn315.c b/drivers/gpu/drm/amd/display/dc/gpio/dcn315/hw_factory_dcn315.c
new file mode 100644
index 000000000000..5feebb3b95ca
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/dc/gpio/dcn315/hw_factory_dcn315.c
@@ -0,0 +1,260 @@
+/*
+ * Copyright 2021 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: AMD
+ *
+ */
+#include "dm_services.h"
+#include "include/gpio_types.h"
+#include "../hw_factory.h"
+
+
+#include "../hw_gpio.h"
+#include "../hw_ddc.h"
+#include "../hw_hpd.h"
+#include "../hw_generic.h"
+
+#include "hw_factory_dcn315.h"
+
+#include "dcn/dcn_3_1_5_offset.h"
+#include "dcn/dcn_3_1_5_sh_mask.h"
+
+#include "reg_helper.h"
+#include "../hpd_regs.h"
+/* begin *********************
+ * macros to expend register list macro defined in HW object header file */
+
+#define DCN_BASE__INST0_SEG0 0x00000012
+#define DCN_BASE__INST0_SEG1 0x000000C0
+#define DCN_BASE__INST0_SEG2 0x000034C0
+#define DCN_BASE__INST0_SEG3 0x00009000
+#define DCN_BASE__INST0_SEG4 0x02403C00
+#define DCN_BASE__INST0_SEG5 0
+
+/* DCN */
+#define block HPD
+#define reg_num 0
+
+#undef BASE_INNER
+#define BASE_INNER(seg) DCN_BASE__INST0_SEG ## seg
+
+#define BASE(seg) BASE_INNER(seg)
+
+
+
+#define REG(reg_name)\
+ BASE(reg ## reg_name ## _BASE_IDX) + reg ## reg_name
+
+#define SF_HPD(reg_name, field_name, post_fix)\
+ .field_name = HPD0_ ## reg_name ## __ ## field_name ## post_fix
+
+#define REGI(reg_name, block, id)\
+ BASE(reg ## block ## id ## _ ## reg_name ## _BASE_IDX) + \
+ reg ## block ## id ## _ ## reg_name
+
+#define SF(reg_name, field_name, post_fix)\
+ .field_name = reg_name ## __ ## field_name ## post_fix
+
+/* macros to expend register list macro defined in HW object header file
+ * end *********************/
+
+
+
+#define hpd_regs(id) \
+{\
+ HPD_REG_LIST(id)\
+}
+
+static const struct hpd_registers hpd_regs[] = {
+ hpd_regs(0),
+ hpd_regs(1),
+ hpd_regs(2),
+ hpd_regs(3),
+ hpd_regs(4),
+};
+
+static const struct hpd_sh_mask hpd_shift = {
+ HPD_MASK_SH_LIST(__SHIFT)
+};
+
+static const struct hpd_sh_mask hpd_mask = {
+ HPD_MASK_SH_LIST(_MASK)
+};
+
+#include "../ddc_regs.h"
+
+ /* set field name */
+#define SF_DDC(reg_name, field_name, post_fix)\
+ .field_name = reg_name ## __ ## field_name ## post_fix
+
+static const struct ddc_registers ddc_data_regs_dcn[] = {
+ ddc_data_regs_dcn2(1),
+ ddc_data_regs_dcn2(2),
+ ddc_data_regs_dcn2(3),
+ ddc_data_regs_dcn2(4),
+ ddc_data_regs_dcn2(5),
+ {
+ DDC_GPIO_VGA_REG_LIST(DATA),
+ .ddc_setup = 0,
+ .phy_aux_cntl = 0,
+ .dc_gpio_aux_ctrl_5 = 0
+ }
+};
+
+static const struct ddc_registers ddc_clk_regs_dcn[] = {
+ ddc_clk_regs_dcn2(1),
+ ddc_clk_regs_dcn2(2),
+ ddc_clk_regs_dcn2(3),
+ ddc_clk_regs_dcn2(4),
+ ddc_clk_regs_dcn2(5),
+ {
+ DDC_GPIO_VGA_REG_LIST(CLK),
+ .ddc_setup = 0,
+ .phy_aux_cntl = 0,
+ .dc_gpio_aux_ctrl_5 = 0
+ }
+};
+
+static const struct ddc_sh_mask ddc_shift[] = {
+ DDC_MASK_SH_LIST_DCN2(__SHIFT, 1),
+ DDC_MASK_SH_LIST_DCN2(__SHIFT, 2),
+ DDC_MASK_SH_LIST_DCN2(__SHIFT, 3),
+ DDC_MASK_SH_LIST_DCN2(__SHIFT, 4),
+ DDC_MASK_SH_LIST_DCN2(__SHIFT, 5),
+ DDC_MASK_SH_LIST_DCN2(__SHIFT, 6)
+};
+
+static const struct ddc_sh_mask ddc_mask[] = {
+ DDC_MASK_SH_LIST_DCN2(_MASK, 1),
+ DDC_MASK_SH_LIST_DCN2(_MASK, 2),
+ DDC_MASK_SH_LIST_DCN2(_MASK, 3),
+ DDC_MASK_SH_LIST_DCN2(_MASK, 4),
+ DDC_MASK_SH_LIST_DCN2(_MASK, 5),
+ DDC_MASK_SH_LIST_DCN2(_MASK, 6)
+};
+
+#include "../generic_regs.h"
+
+/* set field name */
+#define SF_GENERIC(reg_name, field_name, post_fix)\
+ .field_name = reg_name ## __ ## field_name ## post_fix
+
+#define generic_regs(id) \
+{\
+ GENERIC_REG_LIST(id)\
+}
+
+static const struct generic_registers generic_regs[] = {
+ generic_regs(A),
+ generic_regs(B),
+};
+
+static const struct generic_sh_mask generic_shift[] = {
+ GENERIC_MASK_SH_LIST(__SHIFT, A),
+ GENERIC_MASK_SH_LIST(__SHIFT, B),
+};
+
+static const struct generic_sh_mask generic_mask[] = {
+ GENERIC_MASK_SH_LIST(_MASK, A),
+ GENERIC_MASK_SH_LIST(_MASK, B),
+};
+
+static void define_generic_registers(struct hw_gpio_pin *pin, uint32_t en)
+{
+ struct hw_generic *generic = HW_GENERIC_FROM_BASE(pin);
+
+ generic->regs = &generic_regs[en];
+ generic->shifts = &generic_shift[en];
+ generic->masks = &generic_mask[en];
+ generic->base.regs = &generic_regs[en].gpio;
+}
+
+static void define_ddc_registers(
+ struct hw_gpio_pin *pin,
+ uint32_t en)
+{
+ struct hw_ddc *ddc = HW_DDC_FROM_BASE(pin);
+
+ switch (pin->id) {
+ case GPIO_ID_DDC_DATA:
+ ddc->regs = &ddc_data_regs_dcn[en];
+ ddc->base.regs = &ddc_data_regs_dcn[en].gpio;
+ break;
+ case GPIO_ID_DDC_CLOCK:
+ ddc->regs = &ddc_clk_regs_dcn[en];
+ ddc->base.regs = &ddc_clk_regs_dcn[en].gpio;
+ break;
+ default:
+ ASSERT_CRITICAL(false);
+ return;
+ }
+
+ ddc->shifts = &ddc_shift[en];
+ ddc->masks = &ddc_mask[en];
+
+}
+
+static void define_hpd_registers(struct hw_gpio_pin *pin, uint32_t en)
+{
+ struct hw_hpd *hpd = HW_HPD_FROM_BASE(pin);
+
+ hpd->regs = &hpd_regs[en];
+ hpd->shifts = &hpd_shift;
+ hpd->masks = &hpd_mask;
+ hpd->base.regs = &hpd_regs[en].gpio;
+}
+
+
+/* fucntion table */
+static const struct hw_factory_funcs funcs = {
+ .init_ddc_data = dal_hw_ddc_init,
+ .init_generic = dal_hw_generic_init,
+ .init_hpd = dal_hw_hpd_init,
+ .get_ddc_pin = dal_hw_ddc_get_pin,
+ .get_hpd_pin = dal_hw_hpd_get_pin,
+ .get_generic_pin = dal_hw_generic_get_pin,
+ .define_hpd_registers = define_hpd_registers,
+ .define_ddc_registers = define_ddc_registers,
+ .define_generic_registers = define_generic_registers
+};
+/*
+ * dal_hw_factory_dcn10_init
+ *
+ * @brief
+ * Initialize HW factory function pointers and pin info
+ *
+ * @param
+ * struct hw_factory *factory - [out] struct of function pointers
+ */
+void dal_hw_factory_dcn315_init(struct hw_factory *factory)
+{
+ /*TODO check ASIC CAPs*/
+ factory->number_of_pins[GPIO_ID_DDC_DATA] = 8;
+ factory->number_of_pins[GPIO_ID_DDC_CLOCK] = 8;
+ factory->number_of_pins[GPIO_ID_GENERIC] = 4;
+ factory->number_of_pins[GPIO_ID_HPD] = 6;
+ factory->number_of_pins[GPIO_ID_GPIO_PAD] = 28;
+ factory->number_of_pins[GPIO_ID_VIP_PAD] = 0;
+ factory->number_of_pins[GPIO_ID_SYNC] = 0;
+ factory->number_of_pins[GPIO_ID_GSL] = 0;/*add this*/
+
+ factory->funcs = &funcs;
+}
diff --git a/drivers/gpu/drm/amd/display/dc/gpio/dcn315/hw_factory_dcn315.h b/drivers/gpu/drm/amd/display/dc/gpio/dcn315/hw_factory_dcn315.h
new file mode 100644
index 000000000000..ffa71fa41cd4
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/dc/gpio/dcn315/hw_factory_dcn315.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2021 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: AMD
+ *
+ */
+#ifndef __DAL_HW_FACTORY_DCN315_H__
+#define __DAL_HW_FACTORY_DCN315_H__
+
+/* Initialize HW factory function pointers and pin info */
+void dal_hw_factory_dcn315_init(struct hw_factory *factory);
+
+#endif /* __DAL_HW_FACTORY_DCN315_H__ */
diff --git a/drivers/gpu/drm/amd/display/dc/gpio/dcn315/hw_translate_dcn315.c b/drivers/gpu/drm/amd/display/dc/gpio/dcn315/hw_translate_dcn315.c
new file mode 100644
index 000000000000..fbdaba57f718
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/dc/gpio/dcn315/hw_translate_dcn315.c
@@ -0,0 +1,374 @@
+/*
+ * Copyright 2021 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: AMD
+ *
+ */
+
+#include "hw_translate_dcn315.h"
+
+#include "dm_services.h"
+#include "include/gpio_types.h"
+#include "../hw_translate.h"
+
+#include "dcn/dcn_3_1_5_offset.h"
+#include "dcn/dcn_3_1_5_sh_mask.h"
+
+/* begin *********************
+ * macros to expend register list macro defined in HW object header file */
+
+#define DCN_BASE__INST0_SEG0 0x00000012
+#define DCN_BASE__INST0_SEG1 0x000000C0
+#define DCN_BASE__INST0_SEG2 0x000034C0
+#define DCN_BASE__INST0_SEG3 0x00009000
+#define DCN_BASE__INST0_SEG4 0x02403C00
+#define DCN_BASE__INST0_SEG5 0
+
+/* DCN */
+#define block HPD
+#define reg_num 0
+
+#undef BASE_INNER
+#define BASE_INNER(seg) DCN_BASE__INST0_SEG ## seg
+
+#define BASE(seg) BASE_INNER(seg)
+
+#undef REG
+#define REG(reg_name)\
+ BASE(reg ## reg_name ## _BASE_IDX) + reg ## reg_name
+#define SF_HPD(reg_name, field_name, post_fix)\
+ .field_name = reg_name ## __ ## field_name ## post_fix
+
+
+/* macros to expend register list macro defined in HW object header file
+ * end *********************/
+
+
+static bool offset_to_id(
+ uint32_t offset,
+ uint32_t mask,
+ enum gpio_id *id,
+ uint32_t *en)
+{
+ switch (offset) {
+ /* GENERIC */
+ case REG(DC_GPIO_GENERIC_A):
+ *id = GPIO_ID_GENERIC;
+ switch (mask) {
+ case DC_GPIO_GENERIC_A__DC_GPIO_GENERICA_A_MASK:
+ *en = GPIO_GENERIC_A;
+ return true;
+ case DC_GPIO_GENERIC_A__DC_GPIO_GENERICB_A_MASK:
+ *en = GPIO_GENERIC_B;
+ return true;
+ case DC_GPIO_GENERIC_A__DC_GPIO_GENERICC_A_MASK:
+ *en = GPIO_GENERIC_C;
+ return true;
+ case DC_GPIO_GENERIC_A__DC_GPIO_GENERICD_A_MASK:
+ *en = GPIO_GENERIC_D;
+ return true;
+ case DC_GPIO_GENERIC_A__DC_GPIO_GENERICE_A_MASK:
+ *en = GPIO_GENERIC_E;
+ return true;
+ case DC_GPIO_GENERIC_A__DC_GPIO_GENERICF_A_MASK:
+ *en = GPIO_GENERIC_F;
+ return true;
+ case DC_GPIO_GENERIC_A__DC_GPIO_GENERICG_A_MASK:
+ *en = GPIO_GENERIC_G;
+ return true;
+ default:
+ ASSERT_CRITICAL(false);
+ return false;
+ }
+ break;
+ /* HPD */
+ case REG(DC_GPIO_HPD_A):
+ *id = GPIO_ID_HPD;
+ switch (mask) {
+ case DC_GPIO_HPD_A__DC_GPIO_HPD1_A_MASK:
+ *en = GPIO_HPD_1;
+ return true;
+ case DC_GPIO_HPD_A__DC_GPIO_HPD2_A_MASK:
+ *en = GPIO_HPD_2;
+ return true;
+ case DC_GPIO_HPD_A__DC_GPIO_HPD3_A_MASK:
+ *en = GPIO_HPD_3;
+ return true;
+ case DC_GPIO_HPD_A__DC_GPIO_HPD4_A_MASK:
+ *en = GPIO_HPD_4;
+ return true;
+ case DC_GPIO_HPD_A__DC_GPIO_HPD5_A_MASK:
+ *en = GPIO_HPD_5;
+ return true;
+ case DC_GPIO_HPD_A__DC_GPIO_HPD6_A_MASK:
+ *en = GPIO_HPD_6;
+ return true;
+ default:
+ ASSERT_CRITICAL(false);
+ return false;
+ }
+ break;
+ /* REG(DC_GPIO_GENLK_MASK */
+ case REG(DC_GPIO_GENLK_A):
+ *id = GPIO_ID_GSL;
+ switch (mask) {
+ case DC_GPIO_GENLK_A__DC_GPIO_GENLK_CLK_A_MASK:
+ *en = GPIO_GSL_GENLOCK_CLOCK;
+ return true;
+ case DC_GPIO_GENLK_A__DC_GPIO_GENLK_VSYNC_A_MASK:
+ *en = GPIO_GSL_GENLOCK_VSYNC;
+ return true;
+ case DC_GPIO_GENLK_A__DC_GPIO_SWAPLOCK_A_A_MASK:
+ *en = GPIO_GSL_SWAPLOCK_A;
+ return true;
+ case DC_GPIO_GENLK_A__DC_GPIO_SWAPLOCK_B_A_MASK:
+ *en = GPIO_GSL_SWAPLOCK_B;
+ return true;
+ default:
+ ASSERT_CRITICAL(false);
+ return false;
+ }
+ break;
+ /* DDC */
+ /* we don't care about the GPIO_ID for DDC
+ * in DdcHandle it will use GPIO_ID_DDC_DATA/GPIO_ID_DDC_CLOCK
+ * directly in the create method
+ */
+ case REG(DC_GPIO_DDC1_A):
+ *en = GPIO_DDC_LINE_DDC1;
+ return true;
+ case REG(DC_GPIO_DDC2_A):
+ *en = GPIO_DDC_LINE_DDC2;
+ return true;
+ case REG(DC_GPIO_DDC3_A):
+ *en = GPIO_DDC_LINE_DDC3;
+ return true;
+ case REG(DC_GPIO_DDC4_A):
+ *en = GPIO_DDC_LINE_DDC4;
+ return true;
+ case REG(DC_GPIO_DDC5_A):
+ *en = GPIO_DDC_LINE_DDC5;
+ return true;
+ case REG(DC_GPIO_DDCVGA_A):
+ *en = GPIO_DDC_LINE_DDC_VGA;
+ return true;
+
+/*
+ * case REG(DC_GPIO_I2CPAD_A): not exit
+ * case REG(DC_GPIO_PWRSEQ_A):
+ * case REG(DC_GPIO_PAD_STRENGTH_1):
+ * case REG(DC_GPIO_PAD_STRENGTH_2):
+ * case REG(DC_GPIO_DEBUG):
+ */
+ /* UNEXPECTED */
+ default:
+/* case REG(DC_GPIO_SYNCA_A): not exist */
+ ASSERT_CRITICAL(false);
+ return false;
+ }
+}
+
+static bool id_to_offset(
+ enum gpio_id id,
+ uint32_t en,
+ struct gpio_pin_info *info)
+{
+ bool result = true;
+
+ switch (id) {
+ case GPIO_ID_DDC_DATA:
+ info->mask = DC_GPIO_DDC1_A__DC_GPIO_DDC1DATA_A_MASK;
+ switch (en) {
+ case GPIO_DDC_LINE_DDC1:
+ info->offset = REG(DC_GPIO_DDC1_A);
+ break;
+ case GPIO_DDC_LINE_DDC2:
+ info->offset = REG(DC_GPIO_DDC2_A);
+ break;
+ case GPIO_DDC_LINE_DDC3:
+ info->offset = REG(DC_GPIO_DDC3_A);
+ break;
+ case GPIO_DDC_LINE_DDC4:
+ info->offset = REG(DC_GPIO_DDC4_A);
+ break;
+ case GPIO_DDC_LINE_DDC5:
+ info->offset = REG(DC_GPIO_DDC5_A);
+ break;
+ case GPIO_DDC_LINE_DDC_VGA:
+ info->offset = REG(DC_GPIO_DDCVGA_A);
+ break;
+ case GPIO_DDC_LINE_I2C_PAD:
+ default:
+ ASSERT_CRITICAL(false);
+ result = false;
+ }
+ break;
+ case GPIO_ID_DDC_CLOCK:
+ info->mask = DC_GPIO_DDC1_A__DC_GPIO_DDC1CLK_A_MASK;
+ switch (en) {
+ case GPIO_DDC_LINE_DDC1:
+ info->offset = REG(DC_GPIO_DDC1_A);
+ break;
+ case GPIO_DDC_LINE_DDC2:
+ info->offset = REG(DC_GPIO_DDC2_A);
+ break;
+ case GPIO_DDC_LINE_DDC3:
+ info->offset = REG(DC_GPIO_DDC3_A);
+ break;
+ case GPIO_DDC_LINE_DDC4:
+ info->offset = REG(DC_GPIO_DDC4_A);
+ break;
+ case GPIO_DDC_LINE_DDC5:
+ info->offset = REG(DC_GPIO_DDC5_A);
+ break;
+ case GPIO_DDC_LINE_DDC_VGA:
+ info->offset = REG(DC_GPIO_DDCVGA_A);
+ break;
+ case GPIO_DDC_LINE_I2C_PAD:
+ default:
+ ASSERT_CRITICAL(false);
+ result = false;
+ }
+ break;
+ case GPIO_ID_GENERIC:
+ info->offset = REG(DC_GPIO_GENERIC_A);
+ switch (en) {
+ case GPIO_GENERIC_A:
+ info->mask = DC_GPIO_GENERIC_A__DC_GPIO_GENERICA_A_MASK;
+ break;
+ case GPIO_GENERIC_B:
+ info->mask = DC_GPIO_GENERIC_A__DC_GPIO_GENERICB_A_MASK;
+ break;
+ case GPIO_GENERIC_C:
+ info->mask = DC_GPIO_GENERIC_A__DC_GPIO_GENERICC_A_MASK;
+ break;
+ case GPIO_GENERIC_D:
+ info->mask = DC_GPIO_GENERIC_A__DC_GPIO_GENERICD_A_MASK;
+ break;
+ case GPIO_GENERIC_E:
+ info->mask = DC_GPIO_GENERIC_A__DC_GPIO_GENERICE_A_MASK;
+ break;
+ case GPIO_GENERIC_F:
+ info->mask = DC_GPIO_GENERIC_A__DC_GPIO_GENERICF_A_MASK;
+ break;
+ case GPIO_GENERIC_G:
+ info->mask = DC_GPIO_GENERIC_A__DC_GPIO_GENERICG_A_MASK;
+ break;
+ default:
+ ASSERT_CRITICAL(false);
+ result = false;
+ }
+ break;
+ case GPIO_ID_HPD:
+ info->offset = REG(DC_GPIO_HPD_A);
+ switch (en) {
+ case GPIO_HPD_1:
+ info->mask = DC_GPIO_HPD_A__DC_GPIO_HPD1_A_MASK;
+ break;
+ case GPIO_HPD_2:
+ info->mask = DC_GPIO_HPD_A__DC_GPIO_HPD2_A_MASK;
+ break;
+ case GPIO_HPD_3:
+ info->mask = DC_GPIO_HPD_A__DC_GPIO_HPD3_A_MASK;
+ break;
+ case GPIO_HPD_4:
+ info->mask = DC_GPIO_HPD_A__DC_GPIO_HPD4_A_MASK;
+ break;
+ case GPIO_HPD_5:
+ info->mask = DC_GPIO_HPD_A__DC_GPIO_HPD5_A_MASK;
+ break;
+ case GPIO_HPD_6:
+ info->mask = DC_GPIO_HPD_A__DC_GPIO_HPD6_A_MASK;
+ break;
+ default:
+ ASSERT_CRITICAL(false);
+ result = false;
+ }
+ break;
+ case GPIO_ID_GSL:
+ switch (en) {
+ case GPIO_GSL_GENLOCK_CLOCK:
+ /*not implmented*/
+ ASSERT_CRITICAL(false);
+ result = false;
+ break;
+ case GPIO_GSL_GENLOCK_VSYNC:
+ /*not implmented*/
+ ASSERT_CRITICAL(false);
+ result = false;
+ break;
+ case GPIO_GSL_SWAPLOCK_A:
+ /*not implmented*/
+ ASSERT_CRITICAL(false);
+ result = false;
+ break;
+ case GPIO_GSL_SWAPLOCK_B:
+ /*not implmented*/
+ ASSERT_CRITICAL(false);
+ result = false;
+
+ break;
+ default:
+ ASSERT_CRITICAL(false);
+ result = false;
+ }
+ break;
+ case GPIO_ID_SYNC:
+ case GPIO_ID_VIP_PAD:
+ default:
+ ASSERT_CRITICAL(false);
+ result = false;
+ }
+
+ if (result) {
+ info->offset_y = info->offset + 2;
+ info->offset_en = info->offset + 1;
+ info->offset_mask = info->offset - 1;
+
+ info->mask_y = info->mask;
+ info->mask_en = info->mask;
+ info->mask_mask = info->mask;
+ }
+
+ return result;
+}
+
+/* function table */
+static const struct hw_translate_funcs funcs = {
+ .offset_to_id = offset_to_id,
+ .id_to_offset = id_to_offset,
+};
+
+/*
+ * dal_hw_translate_dcn30_init
+ *
+ * @brief
+ * Initialize Hw translate function pointers.
+ *
+ * @param
+ * struct hw_translate *tr - [out] struct of function pointers
+ *
+ */
+void dal_hw_translate_dcn315_init(struct hw_translate *tr)
+{
+ tr->funcs = &funcs;
+}
+
diff --git a/drivers/gpu/drm/amd/display/dc/gpio/dcn315/hw_translate_dcn315.h b/drivers/gpu/drm/amd/display/dc/gpio/dcn315/hw_translate_dcn315.h
new file mode 100644
index 000000000000..d58def4884b2
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/dc/gpio/dcn315/hw_translate_dcn315.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2021 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: AMD
+ *
+ */
+#ifndef __DAL_HW_TRANSLATE_DCN315_H__
+#define __DAL_HW_TRANSLATE_DCN315_H__
+
+struct hw_translate;
+
+/* Initialize Hw translate function pointers */
+void dal_hw_translate_dcn315_init(struct hw_translate *tr);
+
+#endif /* __DAL_HW_TRANSLATE_DCN315_H__ */
diff --git a/drivers/gpu/drm/amd/display/dc/gpio/gpio_service.c b/drivers/gpu/drm/amd/display/dc/gpio/gpio_service.c
index dae8e489c8cf..778c206f754d 100644
--- a/drivers/gpu/drm/amd/display/dc/gpio/gpio_service.c
+++ b/drivers/gpu/drm/amd/display/dc/gpio/gpio_service.c
@@ -647,7 +647,9 @@ enum gpio_result dal_ddc_set_config(
void dal_ddc_close(
struct ddc *ddc)
{
- dal_gpio_close(ddc->pin_clock);
- dal_gpio_close(ddc->pin_data);
+ if (ddc != NULL) {
+ dal_gpio_close(ddc->pin_clock);
+ dal_gpio_close(ddc->pin_data);
+ }
}
diff --git a/drivers/gpu/drm/amd/display/dc/gpio/hw_factory.c b/drivers/gpu/drm/amd/display/dc/gpio/hw_factory.c
index 5029d4e42dbf..5c00ffde3996 100644
--- a/drivers/gpu/drm/amd/display/dc/gpio/hw_factory.c
+++ b/drivers/gpu/drm/amd/display/dc/gpio/hw_factory.c
@@ -53,6 +53,7 @@
#include "dcn20/hw_factory_dcn20.h"
#include "dcn21/hw_factory_dcn21.h"
#include "dcn30/hw_factory_dcn30.h"
+#include "dcn315/hw_factory_dcn315.h"
#endif
#include "diagnostics/hw_factory_diag.h"
@@ -114,8 +115,12 @@ bool dal_hw_factory_init(
case DCN_VERSION_3_02:
case DCN_VERSION_3_03:
case DCN_VERSION_3_1:
+ case DCN_VERSION_3_16:
dal_hw_factory_dcn30_init(factory);
return true;
+ case DCN_VERSION_3_15:
+ dal_hw_factory_dcn315_init(factory);
+ return true;
#endif
default:
ASSERT_CRITICAL(false);
diff --git a/drivers/gpu/drm/amd/display/dc/gpio/hw_translate.c b/drivers/gpu/drm/amd/display/dc/gpio/hw_translate.c
index 904bd30bed68..7a39cbc01f63 100644
--- a/drivers/gpu/drm/amd/display/dc/gpio/hw_translate.c
+++ b/drivers/gpu/drm/amd/display/dc/gpio/hw_translate.c
@@ -51,6 +51,7 @@
#include "dcn20/hw_translate_dcn20.h"
#include "dcn21/hw_translate_dcn21.h"
#include "dcn30/hw_translate_dcn30.h"
+#include "dcn315/hw_translate_dcn315.h"
#endif
#include "diagnostics/hw_translate_diag.h"
@@ -109,8 +110,12 @@ bool dal_hw_translate_init(
case DCN_VERSION_3_02:
case DCN_VERSION_3_03:
case DCN_VERSION_3_1:
+ case DCN_VERSION_3_16:
dal_hw_translate_dcn30_init(translate);
return true;
+ case DCN_VERSION_3_15:
+ dal_hw_translate_dcn315_init(translate);
+ return true;
#endif
default:
diff --git a/drivers/gpu/drm/amd/display/dc/inc/core_types.h b/drivers/gpu/drm/amd/display/dc/inc/core_types.h
index 890280026e69..951c9b60917d 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/core_types.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/core_types.h
@@ -54,6 +54,7 @@ void enable_surface_flip_reporting(struct dc_plane_state *plane_state,
#ifdef CONFIG_DRM_AMD_DC_HDCP
#include "dm_cp_psp.h"
#endif
+#include "link_hwss.h"
/************ link *****************/
struct link_init_data {
@@ -249,12 +250,10 @@ struct resource_pool {
/* Number of USB4 DPIA (DisplayPort Input Adapter) link objects created.*/
unsigned int usb4_dpia_count;
-#if defined(CONFIG_DRM_AMD_DC_DCN)
unsigned int hpo_dp_stream_enc_count;
struct hpo_dp_stream_encoder *hpo_dp_stream_enc[MAX_HPO_DP2_ENCODERS];
unsigned int hpo_dp_link_enc_count;
struct hpo_dp_link_encoder *hpo_dp_link_enc[MAX_HPO_DP2_LINK_ENCODERS];
-#endif
#if defined(CONFIG_DRM_AMD_DC_DCN)
struct dc_3dlut *mpc_lut[MAX_PIPES];
struct dc_transfer_func *mpc_shaper[MAX_PIPES];
@@ -307,9 +306,7 @@ struct stream_resource {
struct display_stream_compressor *dsc;
struct timing_generator *tg;
struct stream_encoder *stream_enc;
-#if defined(CONFIG_DRM_AMD_DC_DCN)
struct hpo_dp_stream_encoder *hpo_dp_stream_enc;
-#endif
struct audio *audio;
struct pixel_clk_params pix_clk_params;
@@ -334,18 +331,12 @@ struct plane_resource {
struct dcn_fe_bandwidth bw;
};
-#if defined(CONFIG_DRM_AMD_DC_DCN)
#define LINK_RES_HPO_DP_REC_MAP__MASK 0xFFFF
#define LINK_RES_HPO_DP_REC_MAP__SHIFT 0
-#endif
/* all mappable hardware resources used to enable a link */
struct link_resource {
-#if defined(CONFIG_DRM_AMD_DC_DCN)
struct hpo_dp_link_encoder *hpo_dp_link_enc;
-#else
- void *dummy;
-#endif
};
union pipe_update_flags {
@@ -382,6 +373,7 @@ struct pipe_ctx {
struct pll_settings pll_settings;
uint8_t pipe_idx;
+ uint8_t pipe_idx_syncd;
struct pipe_ctx *top_pipe;
struct pipe_ctx *bottom_pipe;
@@ -424,11 +416,9 @@ struct resource_context {
uint8_t dp_clock_source_ref_count;
bool is_dsc_acquired[MAX_PIPES];
struct link_enc_cfg_context link_enc_cfg_ctx;
-#if defined(CONFIG_DRM_AMD_DC_DCN)
bool is_hpo_dp_stream_enc_acquired[MAX_HPO_DP2_ENCODERS];
unsigned int hpo_dp_link_enc_to_link_idx[MAX_HPO_DP2_LINK_ENCODERS];
int hpo_dp_link_enc_ref_cnts[MAX_HPO_DP2_LINK_ENCODERS];
-#endif
#if defined(CONFIG_DRM_AMD_DC_DCN)
bool is_mpc_3dlut_acquired[MAX_PIPES];
#endif
diff --git a/drivers/gpu/drm/amd/display/dc/inc/dc_link_dp.h b/drivers/gpu/drm/amd/display/dc/inc/dc_link_dp.h
index cd52813a8432..ab9939db8cea 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/dc_link_dp.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/dc_link_dp.h
@@ -54,22 +54,13 @@ enum {
PEAK_FACTOR_X1000 = 1006,
};
-bool dp_verify_link_cap(
- struct dc_link *link,
- const struct link_resource *link_res,
- struct dc_link_settings *known_limit_link_setting,
- int *fail_count);
+struct dc_link_settings dp_get_max_link_cap(struct dc_link *link);
bool dp_verify_link_cap_with_retries(
struct dc_link *link,
- const struct link_resource *link_res,
struct dc_link_settings *known_limit_link_setting,
int attempts);
-bool dp_verify_mst_link_cap(
- struct dc_link *link,
- const struct link_resource *link_res);
-
bool dp_validate_mode_timing(
struct dc_link *link,
const struct dc_crtc_timing *timing);
@@ -114,6 +105,9 @@ void dp_set_panel_mode(struct dc_link *link, enum dp_panel_mode panel_mode);
bool dp_overwrite_extended_receiver_cap(struct dc_link *link);
void dpcd_set_source_specific_data(struct dc_link *link);
+
+void dpcd_write_cable_id_to_dprx(struct dc_link *link);
+
/* Write DPCD link configuration data. */
enum dc_status dpcd_set_link_settings(
struct dc_link *link,
@@ -173,7 +167,6 @@ uint8_t dc_dp_initialize_scrambling_data_symbols(
enum dc_status dp_set_fec_ready(struct dc_link *link, const struct link_resource *link_res, bool ready);
void dp_set_fec_enable(struct dc_link *link, bool enable);
-struct link_encoder *dp_get_link_enc(struct dc_link *link);
bool dp_set_dsc_enable(struct pipe_ctx *pipe_ctx, bool enable);
bool dp_set_dsc_pps_sdp(struct pipe_ctx *pipe_ctx, bool enable, bool immediate_update);
void dp_set_dsc_on_stream(struct pipe_ctx *pipe_ctx, bool enable);
@@ -222,8 +215,47 @@ void disable_dp_hpo_output(struct dc_link *link,
enum signal_type signal);
void setup_dp_hpo_stream(struct pipe_ctx *pipe_ctx, bool enable);
bool is_dp_128b_132b_signal(struct pipe_ctx *pipe_ctx);
-void reset_dp_hpo_stream_encoders_for_link(struct dc_link *link);
bool dp_retrieve_lttpr_cap(struct dc_link *link);
void edp_panel_backlight_power_on(struct dc_link *link);
+void dp_receiver_power_ctrl(struct dc_link *link, bool on);
+void dp_source_sequence_trace(struct dc_link *link, uint8_t dp_test_mode);
+void dp_enable_link_phy(
+ struct dc_link *link,
+ const struct link_resource *link_res,
+ enum signal_type signal,
+ enum clock_source_id clock_source,
+ const struct dc_link_settings *link_settings);
+void edp_add_delay_for_T9(struct dc_link *link);
+bool edp_receiver_ready_T9(struct dc_link *link);
+bool edp_receiver_ready_T7(struct dc_link *link);
+
+void dp_disable_link_phy(struct dc_link *link, const struct link_resource *link_res,
+ enum signal_type signal);
+
+void dp_disable_link_phy_mst(struct dc_link *link, const struct link_resource *link_res,
+ enum signal_type signal);
+
+bool dp_set_hw_training_pattern(
+ struct dc_link *link,
+ const struct link_resource *link_res,
+ enum dc_dp_training_pattern pattern,
+ uint32_t offset);
+
+void dp_set_hw_lane_settings(
+ struct dc_link *link,
+ const struct link_resource *link_res,
+ const struct link_training_settings *link_settings,
+ uint32_t offset);
+
+void dp_set_hw_test_pattern(
+ struct dc_link *link,
+ const struct link_resource *link_res,
+ enum dp_test_pattern test_pattern,
+ uint8_t *custom_pattern,
+ uint32_t custom_pattern_size);
+
+void dp_retrain_link_dp_test(struct dc_link *link,
+ struct dc_link_settings *link_setting,
+ bool skip_video_pattern);
#endif /* __DC_LINK_DP_H__ */
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/dccg.h b/drivers/gpu/drm/amd/display/dc/inc/hw/dccg.h
index c940fdfda144..b2fa4de47734 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/hw/dccg.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw/dccg.h
@@ -79,7 +79,7 @@ struct dccg_funcs {
void (*otg_drop_pixel)(struct dccg *dccg,
uint32_t otg_inst);
void (*dccg_init)(struct dccg *dccg);
-#if defined(CONFIG_DRM_AMD_DC_DCN)
+
void (*set_dpstreamclk)(
struct dccg *dccg,
enum hdmistreamclk_source src,
@@ -102,7 +102,7 @@ struct dccg_funcs {
void (*disable_symclk32_le)(
struct dccg *dccg,
int hpo_le_inst);
-#endif
+
void (*set_physymclk)(
struct dccg *dccg,
int phy_inst,
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/dchubbub.h b/drivers/gpu/drm/amd/display/dc/inc/hw/dchubbub.h
index 713f5558f5e1..9195dec294c2 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/hw/dchubbub.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw/dchubbub.h
@@ -154,6 +154,8 @@ struct hubbub_funcs {
bool (*is_allow_self_refresh_enabled)(struct hubbub *hubbub);
void (*allow_self_refresh_control)(struct hubbub *hubbub, bool allow);
+ bool (*verify_allow_pstate_change_high)(struct hubbub *hubbub);
+
void (*apply_DEDCN21_147_wa)(struct hubbub *hubbub);
void (*force_wm_propagate_to_pipes)(struct hubbub *hubbub);
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/hubp.h b/drivers/gpu/drm/amd/display/dc/inc/hw/hubp.h
index 2c031586f4e6..e45b7993c5c5 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/hw/hubp.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw/hubp.h
@@ -195,6 +195,7 @@ struct hubp_funcs {
void (*hubp_set_flip_int)(struct hubp *hubp);
+ void (*hubp_wait_pipe_read_start)(struct hubp *hubp);
};
#endif
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/hw_shared.h b/drivers/gpu/drm/amd/display/dc/inc/hw/hw_shared.h
index 10ecbc667ffa..d89bd55f110f 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/hw/hw_shared.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw/hw_shared.h
@@ -38,10 +38,8 @@
#define MAX_PIPES 6
#define MAX_DIG_LINK_ENCODERS 7
#define MAX_DWB_PIPES 1
-#if defined(CONFIG_DRM_AMD_DC_DCN)
#define MAX_HPO_DP2_ENCODERS 4
#define MAX_HPO_DP2_LINK_ENCODERS 2
-#endif
struct gamma_curve {
uint32_t offset;
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/link_encoder.h b/drivers/gpu/drm/amd/display/dc/inc/hw/link_encoder.h
index 2ce15cd10d80..2013a70603ae 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/hw/link_encoder.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw/link_encoder.h
@@ -162,7 +162,8 @@ struct link_encoder_funcs {
void (*disable_output)(struct link_encoder *link_enc,
enum signal_type signal);
void (*dp_set_lane_settings)(struct link_encoder *enc,
- const struct link_training_settings *link_settings);
+ const struct dc_link_settings *link_settings,
+ const struct dc_lane_settings lane_settings[LANE_COUNT_DP_MAX]);
void (*dp_set_phy_pattern)(struct link_encoder *enc,
const struct encoder_set_dp_phy_pattern_param *para);
void (*update_mst_stream_allocation_table)(
@@ -220,7 +221,6 @@ enum link_enc_cfg_mode {
LINK_ENC_CFG_TRANSIENT /* During commit state - use state to be committed. */
};
-#if defined(CONFIG_DRM_AMD_DC_DCN)
enum dp2_link_mode {
DP2_LINK_TRAINING_TPS1,
DP2_LINK_TRAINING_TPS2,
@@ -306,6 +306,5 @@ struct hpo_dp_link_encoder_funcs {
const struct dc_link_settings *link_settings,
uint8_t ffe_preset);
};
-#endif
#endif /* LINK_ENCODER_H_ */
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/panel_cntl.h b/drivers/gpu/drm/amd/display/dc/inc/hw/panel_cntl.h
index 48eac622c6a0..24af9d80b937 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/hw/panel_cntl.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw/panel_cntl.h
@@ -39,6 +39,7 @@ struct panel_cntl_backlight_registers {
unsigned int BL_PWM_CNTL2;
unsigned int BL_PWM_PERIOD_CNTL;
unsigned int LVTMA_PWRSEQ_REF_DIV_BL_PWM_REF_DIV;
+ unsigned int PANEL_PWRSEQ_REF_DIV2;
};
struct panel_cntl_funcs {
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/stream_encoder.h b/drivers/gpu/drm/amd/display/dc/inc/hw/stream_encoder.h
index 073f8b667eff..678c2065e5e8 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/hw/stream_encoder.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw/stream_encoder.h
@@ -164,10 +164,6 @@ struct stream_encoder_funcs {
void (*stop_dp_info_packets)(
struct stream_encoder *enc);
- void (*reset_fifo)(
- struct stream_encoder *enc
- );
-
void (*dp_blank)(
struct dc_link *link,
struct stream_encoder *enc);
@@ -249,7 +245,6 @@ struct stream_encoder_funcs {
struct stream_encoder *enc);
};
-#if defined(CONFIG_DRM_AMD_DC_DCN)
struct hpo_dp_stream_encoder_state {
uint32_t stream_enc_enabled;
uint32_t vid_stream_enabled;
@@ -328,7 +323,10 @@ struct hpo_dp_stream_encoder_funcs {
void (*read_state)(
struct hpo_dp_stream_encoder *enc,
struct hpo_dp_stream_encoder_state *state);
+
+ void (*set_hblank_min_symbol_width)(
+ struct hpo_dp_stream_encoder *enc,
+ uint16_t width);
};
-#endif
#endif /* STREAM_ENCODER_H_ */
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/timing_generator.h b/drivers/gpu/drm/amd/display/dc/inc/hw/timing_generator.h
index c29320b3855d..59a704781e34 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/hw/timing_generator.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw/timing_generator.h
@@ -100,9 +100,7 @@ enum crc_selection {
enum otg_out_mux_dest {
OUT_MUX_DIO = 0,
-#if defined(CONFIG_DRM_AMD_DC_DCN)
OUT_MUX_HPO_DP = 2,
-#endif
};
enum h_timing_div_mode {
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer_private.h b/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer_private.h
index c2008258c50a..8c2f190c4712 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer_private.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer_private.h
@@ -41,9 +41,8 @@ struct dce_hwseq_wa {
bool DEGVIDCN10_254;
bool DEGVIDCN21;
bool disallow_self_refresh_during_multi_plane_transition;
-#if defined(CONFIG_DRM_AMD_DC_DCN)
bool dp_hpo_and_otg_sequence;
-#endif
+ bool wait_hubpret_read_start_during_mpo_transition;
};
struct hwseq_wa_state {
diff --git a/drivers/gpu/drm/amd/display/dc/inc/link_dpcd.h b/drivers/gpu/drm/amd/display/dc/inc/link_dpcd.h
index 3f12b1600d2a..d561f86d503c 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/link_dpcd.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/link_dpcd.h
@@ -27,7 +27,7 @@
#define __LINK_DPCD_H__
#include <inc/core_status.h>
#include <dc_link.h>
-#include <inc/link_hwss.h>
+#include <dc_link_dp.h>
enum dc_status core_link_read_dpcd(
struct dc_link *link,
diff --git a/drivers/gpu/drm/amd/display/dc/inc/link_enc_cfg.h b/drivers/gpu/drm/amd/display/dc/inc/link_enc_cfg.h
index a4e43b4826e0..c6f6baa6e677 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/link_enc_cfg.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/link_enc_cfg.h
@@ -40,6 +40,11 @@ void link_enc_cfg_init(
struct dc_state *state);
/*
+ * Copies a link encoder assignment from another state.
+ */
+void link_enc_cfg_copy(const struct dc_state *src_ctx, struct dc_state *dst_ctx);
+
+/*
* Algorithm for assigning available DIG link encoders to streams.
*
* Update link_enc_assignments table and link_enc_avail list accordingly in
@@ -96,6 +101,9 @@ struct link_encoder *link_enc_cfg_get_link_enc_used_by_stream(
struct dc *dc,
const struct dc_stream_state *stream);
+/* Return DIG link encoder. NULL if unused. */
+struct link_encoder *link_enc_cfg_get_link_enc(const struct dc_link *link);
+
/* Return true if encoder available to use. */
bool link_enc_cfg_is_link_enc_avail(struct dc *dc, enum engine_id eng_id, struct dc_link *link);
diff --git a/drivers/gpu/drm/amd/display/dc/inc/link_hwss.h b/drivers/gpu/drm/amd/display/dc/inc/link_hwss.h
index 69d63763a10e..3b3090e3d327 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/link_hwss.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/link_hwss.h
@@ -26,50 +26,52 @@
#ifndef __DC_LINK_HWSS_H__
#define __DC_LINK_HWSS_H__
-struct gpio *get_hpd_gpio(struct dc_bios *dcb,
- struct graphics_object_id link_id,
- struct gpio_service *gpio_service);
+/* include basic type headers only */
+#include "dc_dp_types.h"
+#include "signal_types.h"
+#include "grph_object_id.h"
+#include "fixed31_32.h"
-void dp_enable_link_phy(
- struct dc_link *link,
- const struct link_resource *link_res,
- enum signal_type signal,
- enum clock_source_id clock_source,
- const struct dc_link_settings *link_settings);
+/* forward declare dc core types */
+struct dc_link;
+struct link_resource;
+struct pipe_ctx;
+struct encoder_set_dp_phy_pattern_param;
-void dp_receiver_power_ctrl(struct dc_link *link, bool on);
-void dp_source_sequence_trace(struct dc_link *link, uint8_t dp_test_mode);
-void edp_add_delay_for_T9(struct dc_link *link);
-bool edp_receiver_ready_T9(struct dc_link *link);
-bool edp_receiver_ready_T7(struct dc_link *link);
+struct link_hwss_ext {
+ /* function pointers below require check for NULL at all time
+ * *********************************************************************
+ */
+ void (*set_hblank_min_symbol_width)(struct pipe_ctx *pipe_ctx,
+ const struct dc_link_settings *link_settings,
+ struct fixed31_32 throttled_vcp_size);
+ void (*set_throttled_vcp_size)(struct pipe_ctx *pipe_ctx,
+ struct fixed31_32 throttled_vcp_size);
+ void (*enable_dp_link_output)(struct dc_link *link,
+ const struct link_resource *link_res,
+ enum signal_type signal,
+ enum clock_source_id clock_source,
+ const struct dc_link_settings *link_settings);
+ void (*disable_dp_link_output)(struct dc_link *link,
+ const struct link_resource *link_res,
+ enum signal_type signal);
+ void (*set_dp_link_test_pattern)(struct dc_link *link,
+ const struct link_resource *link_res,
+ struct encoder_set_dp_phy_pattern_param *tp_params);
+ void (*set_dp_lane_settings)(struct dc_link *link,
+ const struct link_resource *link_res,
+ const struct dc_link_settings *link_settings,
+ const struct dc_lane_settings lane_settings[LANE_COUNT_DP_MAX]);
+};
-void dp_disable_link_phy(struct dc_link *link, const struct link_resource *link_res,
- enum signal_type signal);
-
-void dp_disable_link_phy_mst(struct dc_link *link, const struct link_resource *link_res,
- enum signal_type signal);
-
-bool dp_set_hw_training_pattern(
- struct dc_link *link,
- const struct link_resource *link_res,
- enum dc_dp_training_pattern pattern,
- uint32_t offset);
-
-void dp_set_hw_lane_settings(
- struct dc_link *link,
- const struct link_resource *link_res,
- const struct link_training_settings *link_settings,
- uint32_t offset);
-
-void dp_set_hw_test_pattern(
- struct dc_link *link,
- const struct link_resource *link_res,
- enum dp_test_pattern test_pattern,
- uint8_t *custom_pattern,
- uint32_t custom_pattern_size);
-
-void dp_retrain_link_dp_test(struct dc_link *link,
- struct dc_link_settings *link_setting,
- bool skip_video_pattern);
+struct link_hwss {
+ struct link_hwss_ext ext;
+ /* function pointers below MUST be assigned to all types of link_hwss
+ * *********************************************************************
+ */
+ void (*setup_stream_encoder)(struct pipe_ctx *pipe_ctx);
+ void (*reset_stream_encoder)(struct pipe_ctx *pipe_ctx);
+};
#endif /* __DC_LINK_HWSS_H__ */
+
diff --git a/drivers/gpu/drm/amd/display/dc/inc/reg_helper.h b/drivers/gpu/drm/amd/display/dc/inc/reg_helper.h
index 2470405e996b..a402df225a76 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/reg_helper.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/reg_helper.h
@@ -498,6 +498,40 @@ uint32_t generic_indirect_reg_update_ex(const struct dc_context *ctx,
uint8_t shift1, uint32_t mask1, uint32_t field_value1,
...);
+/* indirect register access
+ * underlying implementation determines which index/data pair to be used
+ * in a synchronous way
+ */
+#define IX_REG_SET_N_SYNC(index, n, initial_val, ...) \
+ generic_indirect_reg_update_ex_sync(CTX, \
+ IND_REG(index), \
+ initial_val, \
+ n, __VA_ARGS__)
+
+#define IX_REG_SET_2_SYNC(index, init_value, f1, v1, f2, v2) \
+ IX_REG_SET_N_SYNC(index, 2, init_value, \
+ FN(reg, f1), v1,\
+ FN(reg, f2), v2)
+
+#define IX_REG_GET_N_SYNC(index, n, ...) \
+ generic_indirect_reg_get_sync(CTX, \
+ IND_REG(index), \
+ n, __VA_ARGS__)
+
+#define IX_REG_GET_SYNC(index, field, val) \
+ IX_REG_GET_N_SYNC(index, 1, \
+ FN(data_reg_name, field), val)
+
+uint32_t generic_indirect_reg_get_sync(const struct dc_context *ctx,
+ uint32_t index, int n,
+ uint8_t shift1, uint32_t mask1, uint32_t *field_value1,
+ ...);
+
+uint32_t generic_indirect_reg_update_ex_sync(const struct dc_context *ctx,
+ uint32_t index, uint32_t reg_val, int n,
+ uint8_t shift1, uint32_t mask1, uint32_t field_value1,
+ ...);
+
/* register offload macros
*
* instead of MMIO to register directly, in some cases we want
diff --git a/drivers/gpu/drm/amd/display/dc/inc/resource.h b/drivers/gpu/drm/amd/display/dc/inc/resource.h
index 4249bf306e09..2369f38ed06f 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/resource.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/resource.h
@@ -34,6 +34,10 @@
#define MEMORY_TYPE_HBM 2
+#define IS_PIPE_SYNCD_VALID(pipe) ((((pipe)->pipe_idx_syncd) & 0x80)?1:0)
+#define GET_PIPE_SYNCD_FROM_PIPE(pipe) ((pipe)->pipe_idx_syncd & 0x7F)
+#define SET_PIPE_SYNCD_TO_PIPE(pipe, pipe_syncd) ((pipe)->pipe_idx_syncd = (0x80 | pipe_syncd))
+
enum dce_version resource_parse_asic_id(
struct hw_asic_id asic_id);
@@ -50,10 +54,8 @@ struct resource_caps {
int num_dsc;
unsigned int num_dig_link_enc; // Total number of DIGs (digital encoders) in DIO (Display Input/Output).
unsigned int num_usb4_dpia; // Total number of USB4 DPIA (DisplayPort Input Adapters).
-#if defined(CONFIG_DRM_AMD_DC_DCN)
int num_hpo_dp_stream_encoder;
int num_hpo_dp_link_encoder;
-#endif
int num_mpc_3dlut;
};
@@ -73,14 +75,12 @@ struct resource_create_funcs {
struct stream_encoder *(*create_stream_encoder)(
enum engine_id eng_id, struct dc_context *ctx);
-#if defined(CONFIG_DRM_AMD_DC_DCN)
struct hpo_dp_stream_encoder *(*create_hpo_dp_stream_encoder)(
enum engine_id eng_id, struct dc_context *ctx);
struct hpo_dp_link_encoder *(*create_hpo_dp_link_encoder)(
uint8_t inst,
struct dc_context *ctx);
-#endif
struct dce_hwseq *(*create_hwseq)(
struct dc_context *ctx);
@@ -201,13 +201,20 @@ int get_num_mpc_splits(struct pipe_ctx *pipe);
int get_num_odm_splits(struct pipe_ctx *pipe);
-#if defined(CONFIG_DRM_AMD_DC_DCN)
-struct hpo_dp_link_encoder *resource_get_hpo_dp_link_enc_for_det_lt(
- const struct resource_context *res_ctx,
- const struct resource_pool *pool,
- const struct dc_link *link);
-#endif
+bool get_temp_dp_link_res(struct dc_link *link,
+ struct link_resource *link_res,
+ struct dc_link_settings *link_settings);
+
+void reset_syncd_pipes_from_disabled_pipes(struct dc *dc,
+ struct dc_state *context);
+
+void check_syncd_pipes_for_disabled_master_pipe(struct dc *dc,
+ struct dc_state *context,
+ uint8_t disabled_master_pipe_idx);
uint8_t resource_transmitter_to_phy_idx(const struct dc *dc, enum transmitter transmitter);
+const struct link_hwss *get_link_hwss(const struct dc_link *link,
+ const struct link_resource *link_res);
+
#endif /* DRIVERS_GPU_DRM_AMD_DC_DEV_DC_INC_RESOURCE_H_ */
diff --git a/drivers/gpu/drm/amd/display/dc/irq/Makefile b/drivers/gpu/drm/amd/display/dc/irq/Makefile
index fd739aecf104..f305d4c9a122 100644
--- a/drivers/gpu/drm/amd/display/dc/irq/Makefile
+++ b/drivers/gpu/drm/amd/display/dc/irq/Makefile
@@ -137,3 +137,11 @@ AMD_DAL_IRQ_DCN31= $(addprefix $(AMDDALPATH)/dc/irq/dcn31/,$(IRQ_DCN31))
AMD_DISPLAY_FILES += $(AMD_DAL_IRQ_DCN31)
endif
+###############################################################################
+# DCN 315
+###############################################################################
+IRQ_DCN315 = irq_service_dcn315.o
+
+AMD_DAL_IRQ_DCN315= $(addprefix $(AMDDALPATH)/dc/irq/dcn315/,$(IRQ_DCN315))
+
+AMD_DISPLAY_FILES += $(AMD_DAL_IRQ_DCN315)
diff --git a/drivers/gpu/drm/amd/display/dc/irq/dcn20/irq_service_dcn20.c b/drivers/gpu/drm/amd/display/dc/irq/dcn20/irq_service_dcn20.c
index c4b067d01895..93c31111500b 100644
--- a/drivers/gpu/drm/amd/display/dc/irq/dcn20/irq_service_dcn20.c
+++ b/drivers/gpu/drm/amd/display/dc/irq/dcn20/irq_service_dcn20.c
@@ -40,7 +40,7 @@
#include "ivsrcid/dcn/irqsrcs_dcn_1_0.h"
-enum dc_irq_source to_dal_irq_source_dcn20(
+static enum dc_irq_source to_dal_irq_source_dcn20(
struct irq_service *irq_service,
uint32_t src_id,
uint32_t ext_id)
diff --git a/drivers/gpu/drm/amd/display/dc/irq/dcn201/irq_service_dcn201.c b/drivers/gpu/drm/amd/display/dc/irq/dcn201/irq_service_dcn201.c
index aa708b61142f..45f99351a0ab 100644
--- a/drivers/gpu/drm/amd/display/dc/irq/dcn201/irq_service_dcn201.c
+++ b/drivers/gpu/drm/amd/display/dc/irq/dcn201/irq_service_dcn201.c
@@ -138,11 +138,6 @@ static const struct irq_source_info_funcs vupdate_no_lock_irq_info_funcs = {
.ack = NULL
};
-static const struct irq_source_info_funcs dmub_outbox_irq_info_funcs = {
- .set = NULL,
- .ack = NULL
-};
-
#undef BASE_INNER
#define BASE_INNER(seg) DMU_BASE__INST0_SEG ## seg
diff --git a/drivers/gpu/drm/amd/display/dc/irq/dcn21/irq_service_dcn21.c b/drivers/gpu/drm/amd/display/dc/irq/dcn21/irq_service_dcn21.c
index 0f15bcada4e9..717977aec6d0 100644
--- a/drivers/gpu/drm/amd/display/dc/irq/dcn21/irq_service_dcn21.c
+++ b/drivers/gpu/drm/amd/display/dc/irq/dcn21/irq_service_dcn21.c
@@ -265,14 +265,6 @@ static const struct irq_source_info_funcs vline0_irq_info_funcs = {
.funcs = &pflip_irq_info_funcs\
}
-#define vupdate_int_entry(reg_num)\
- [DC_IRQ_SOURCE_VUPDATE1 + reg_num] = {\
- IRQ_REG_ENTRY(OTG, reg_num,\
- OTG_GLOBAL_SYNC_STATUS, VUPDATE_INT_EN,\
- OTG_GLOBAL_SYNC_STATUS, VUPDATE_EVENT_CLEAR),\
- .funcs = &vblank_irq_info_funcs\
- }
-
/* vupdate_no_lock_int_entry maps to DC_IRQ_SOURCE_VUPDATEx, to match semantic
* of DCE's DC_IRQ_SOURCE_VUPDATEx.
*/
@@ -401,12 +393,6 @@ irq_source_info_dcn21[DAL_IRQ_SOURCES_NUMBER] = {
dc_underflow_int_entry(6),
[DC_IRQ_SOURCE_DMCU_SCP] = dummy_irq_entry(),
[DC_IRQ_SOURCE_VBIOS_SW] = dummy_irq_entry(),
- vupdate_int_entry(0),
- vupdate_int_entry(1),
- vupdate_int_entry(2),
- vupdate_int_entry(3),
- vupdate_int_entry(4),
- vupdate_int_entry(5),
vupdate_no_lock_int_entry(0),
vupdate_no_lock_int_entry(1),
vupdate_no_lock_int_entry(2),
diff --git a/drivers/gpu/drm/amd/display/dc/irq/dcn30/irq_service_dcn30.c b/drivers/gpu/drm/amd/display/dc/irq/dcn30/irq_service_dcn30.c
index 914ce2ce1c2f..ac0c6a62d17b 100644
--- a/drivers/gpu/drm/amd/display/dc/irq/dcn30/irq_service_dcn30.c
+++ b/drivers/gpu/drm/amd/display/dc/irq/dcn30/irq_service_dcn30.c
@@ -37,8 +37,8 @@
#include "nbio/nbio_7_4_offset.h"
-#include "dcn/dpcs_3_0_0_offset.h"
-#include "dcn/dpcs_3_0_0_sh_mask.h"
+#include "dpcs/dpcs_3_0_0_offset.h"
+#include "dpcs/dpcs_3_0_0_sh_mask.h"
#include "mmhub/mmhub_2_0_0_offset.h"
#include "mmhub/mmhub_2_0_0_sh_mask.h"
@@ -47,7 +47,7 @@
#include "ivsrcid/dcn/irqsrcs_dcn_1_0.h"
-enum dc_irq_source to_dal_irq_source_dcn30(
+static enum dc_irq_source to_dal_irq_source_dcn30(
struct irq_service *irq_service,
uint32_t src_id,
uint32_t ext_id)
diff --git a/drivers/gpu/drm/amd/display/dc/irq/dcn315/irq_service_dcn315.c b/drivers/gpu/drm/amd/display/dc/irq/dcn315/irq_service_dcn315.c
new file mode 100644
index 000000000000..e722171f0d2d
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/dc/irq/dcn315/irq_service_dcn315.c
@@ -0,0 +1,438 @@
+/*
+ * Copyright 2021 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: AMD
+ *
+ */
+
+#include "dm_services.h"
+#include "include/logger_interface.h"
+#include "../dce110/irq_service_dce110.h"
+
+
+#include "dcn/dcn_3_1_5_offset.h"
+#include "dcn/dcn_3_1_5_sh_mask.h"
+
+#include "irq_service_dcn315.h"
+
+#include "ivsrcid/dcn/irqsrcs_dcn_1_0.h"
+
+#define DCN_BASE__INST0_SEG0 0x00000012
+#define DCN_BASE__INST0_SEG1 0x000000C0
+#define DCN_BASE__INST0_SEG2 0x000034C0
+#define DCN_BASE__INST0_SEG3 0x00009000
+#define DCN_BASE__INST0_SEG4 0x02403C00
+#define DCN_BASE__INST0_SEG5 0
+
+static enum dc_irq_source to_dal_irq_source_dcn315(
+ struct irq_service *irq_service,
+ uint32_t src_id,
+ uint32_t ext_id)
+{
+ switch (src_id) {
+ case DCN_1_0__SRCID__DC_D1_OTG_VSTARTUP:
+ return DC_IRQ_SOURCE_VBLANK1;
+ case DCN_1_0__SRCID__DC_D2_OTG_VSTARTUP:
+ return DC_IRQ_SOURCE_VBLANK2;
+ case DCN_1_0__SRCID__DC_D3_OTG_VSTARTUP:
+ return DC_IRQ_SOURCE_VBLANK3;
+ case DCN_1_0__SRCID__DC_D4_OTG_VSTARTUP:
+ return DC_IRQ_SOURCE_VBLANK4;
+ case DCN_1_0__SRCID__DC_D5_OTG_VSTARTUP:
+ return DC_IRQ_SOURCE_VBLANK5;
+ case DCN_1_0__SRCID__DC_D6_OTG_VSTARTUP:
+ return DC_IRQ_SOURCE_VBLANK6;
+ case DCN_1_0__SRCID__OTG1_VERTICAL_INTERRUPT0_CONTROL:
+ return DC_IRQ_SOURCE_DC1_VLINE0;
+ case DCN_1_0__SRCID__OTG2_VERTICAL_INTERRUPT0_CONTROL:
+ return DC_IRQ_SOURCE_DC2_VLINE0;
+ case DCN_1_0__SRCID__OTG3_VERTICAL_INTERRUPT0_CONTROL:
+ return DC_IRQ_SOURCE_DC3_VLINE0;
+ case DCN_1_0__SRCID__OTG4_VERTICAL_INTERRUPT0_CONTROL:
+ return DC_IRQ_SOURCE_DC4_VLINE0;
+ case DCN_1_0__SRCID__OTG5_VERTICAL_INTERRUPT0_CONTROL:
+ return DC_IRQ_SOURCE_DC5_VLINE0;
+ case DCN_1_0__SRCID__OTG6_VERTICAL_INTERRUPT0_CONTROL:
+ return DC_IRQ_SOURCE_DC6_VLINE0;
+ case DCN_1_0__SRCID__HUBP0_FLIP_INTERRUPT:
+ return DC_IRQ_SOURCE_PFLIP1;
+ case DCN_1_0__SRCID__HUBP1_FLIP_INTERRUPT:
+ return DC_IRQ_SOURCE_PFLIP2;
+ case DCN_1_0__SRCID__HUBP2_FLIP_INTERRUPT:
+ return DC_IRQ_SOURCE_PFLIP3;
+ case DCN_1_0__SRCID__HUBP3_FLIP_INTERRUPT:
+ return DC_IRQ_SOURCE_PFLIP4;
+ case DCN_1_0__SRCID__HUBP4_FLIP_INTERRUPT:
+ return DC_IRQ_SOURCE_PFLIP5;
+ case DCN_1_0__SRCID__HUBP5_FLIP_INTERRUPT:
+ return DC_IRQ_SOURCE_PFLIP6;
+ case DCN_1_0__SRCID__OTG0_IHC_V_UPDATE_NO_LOCK_INTERRUPT:
+ return DC_IRQ_SOURCE_VUPDATE1;
+ case DCN_1_0__SRCID__OTG1_IHC_V_UPDATE_NO_LOCK_INTERRUPT:
+ return DC_IRQ_SOURCE_VUPDATE2;
+ case DCN_1_0__SRCID__OTG2_IHC_V_UPDATE_NO_LOCK_INTERRUPT:
+ return DC_IRQ_SOURCE_VUPDATE3;
+ case DCN_1_0__SRCID__OTG3_IHC_V_UPDATE_NO_LOCK_INTERRUPT:
+ return DC_IRQ_SOURCE_VUPDATE4;
+ case DCN_1_0__SRCID__OTG4_IHC_V_UPDATE_NO_LOCK_INTERRUPT:
+ return DC_IRQ_SOURCE_VUPDATE5;
+ case DCN_1_0__SRCID__OTG5_IHC_V_UPDATE_NO_LOCK_INTERRUPT:
+ return DC_IRQ_SOURCE_VUPDATE6;
+ case DCN_1_0__SRCID__DMCUB_OUTBOX_LOW_PRIORITY_READY_INT:
+ return DC_IRQ_SOURCE_DMCUB_OUTBOX;
+ case DCN_1_0__SRCID__DC_HPD1_INT:
+ /* generic src_id for all HPD and HPDRX interrupts */
+ switch (ext_id) {
+ case DCN_1_0__CTXID__DC_HPD1_INT:
+ return DC_IRQ_SOURCE_HPD1;
+ case DCN_1_0__CTXID__DC_HPD2_INT:
+ return DC_IRQ_SOURCE_HPD2;
+ case DCN_1_0__CTXID__DC_HPD3_INT:
+ return DC_IRQ_SOURCE_HPD3;
+ case DCN_1_0__CTXID__DC_HPD4_INT:
+ return DC_IRQ_SOURCE_HPD4;
+ case DCN_1_0__CTXID__DC_HPD5_INT:
+ return DC_IRQ_SOURCE_HPD5;
+ case DCN_1_0__CTXID__DC_HPD6_INT:
+ return DC_IRQ_SOURCE_HPD6;
+ case DCN_1_0__CTXID__DC_HPD1_RX_INT:
+ return DC_IRQ_SOURCE_HPD1RX;
+ case DCN_1_0__CTXID__DC_HPD2_RX_INT:
+ return DC_IRQ_SOURCE_HPD2RX;
+ case DCN_1_0__CTXID__DC_HPD3_RX_INT:
+ return DC_IRQ_SOURCE_HPD3RX;
+ case DCN_1_0__CTXID__DC_HPD4_RX_INT:
+ return DC_IRQ_SOURCE_HPD4RX;
+ case DCN_1_0__CTXID__DC_HPD5_RX_INT:
+ return DC_IRQ_SOURCE_HPD5RX;
+ case DCN_1_0__CTXID__DC_HPD6_RX_INT:
+ return DC_IRQ_SOURCE_HPD6RX;
+ default:
+ return DC_IRQ_SOURCE_INVALID;
+ }
+ break;
+
+ default:
+ return DC_IRQ_SOURCE_INVALID;
+ }
+}
+
+static bool hpd_ack(
+ struct irq_service *irq_service,
+ const struct irq_source_info *info)
+{
+ uint32_t addr = info->status_reg;
+ uint32_t value = dm_read_reg(irq_service->ctx, addr);
+ uint32_t current_status =
+ get_reg_field_value(
+ value,
+ HPD0_DC_HPD_INT_STATUS,
+ DC_HPD_SENSE_DELAYED);
+
+ dal_irq_service_ack_generic(irq_service, info);
+
+ value = dm_read_reg(irq_service->ctx, info->enable_reg);
+
+ set_reg_field_value(
+ value,
+ current_status ? 0 : 1,
+ HPD0_DC_HPD_INT_CONTROL,
+ DC_HPD_INT_POLARITY);
+
+ dm_write_reg(irq_service->ctx, info->enable_reg, value);
+
+ return true;
+}
+
+static const struct irq_source_info_funcs hpd_irq_info_funcs = {
+ .set = NULL,
+ .ack = hpd_ack
+};
+
+static const struct irq_source_info_funcs hpd_rx_irq_info_funcs = {
+ .set = NULL,
+ .ack = NULL
+};
+
+static const struct irq_source_info_funcs pflip_irq_info_funcs = {
+ .set = NULL,
+ .ack = NULL
+};
+
+static const struct irq_source_info_funcs vupdate_no_lock_irq_info_funcs = {
+ .set = NULL,
+ .ack = NULL
+};
+
+static const struct irq_source_info_funcs vblank_irq_info_funcs = {
+ .set = NULL,
+ .ack = NULL
+};
+
+static const struct irq_source_info_funcs outbox_irq_info_funcs = {
+ .set = NULL,
+ .ack = NULL
+};
+
+static const struct irq_source_info_funcs vline0_irq_info_funcs = {
+ .set = NULL,
+ .ack = NULL
+};
+
+#undef BASE_INNER
+#define BASE_INNER(seg) DCN_BASE__INST0_SEG ## seg
+
+/* compile time expand base address. */
+#define BASE(seg) \
+ BASE_INNER(seg)
+
+#define SRI(reg_name, block, id)\
+ BASE(reg ## block ## id ## _ ## reg_name ## _BASE_IDX) + \
+ reg ## block ## id ## _ ## reg_name
+
+#define SRI_DMUB(reg_name)\
+ BASE(reg ## reg_name ## _BASE_IDX) + \
+ reg ## reg_name
+
+#define IRQ_REG_ENTRY(block, reg_num, reg1, mask1, reg2, mask2)\
+ .enable_reg = SRI(reg1, block, reg_num),\
+ .enable_mask = \
+ block ## reg_num ## _ ## reg1 ## __ ## mask1 ## _MASK,\
+ .enable_value = {\
+ block ## reg_num ## _ ## reg1 ## __ ## mask1 ## _MASK,\
+ ~block ## reg_num ## _ ## reg1 ## __ ## mask1 ## _MASK \
+ },\
+ .ack_reg = SRI(reg2, block, reg_num),\
+ .ack_mask = \
+ block ## reg_num ## _ ## reg2 ## __ ## mask2 ## _MASK,\
+ .ack_value = \
+ block ## reg_num ## _ ## reg2 ## __ ## mask2 ## _MASK \
+
+#define IRQ_REG_ENTRY_DMUB(reg1, mask1, reg2, mask2)\
+ .enable_reg = SRI_DMUB(reg1),\
+ .enable_mask = \
+ reg1 ## __ ## mask1 ## _MASK,\
+ .enable_value = {\
+ reg1 ## __ ## mask1 ## _MASK,\
+ ~reg1 ## __ ## mask1 ## _MASK \
+ },\
+ .ack_reg = SRI_DMUB(reg2),\
+ .ack_mask = \
+ reg2 ## __ ## mask2 ## _MASK,\
+ .ack_value = \
+ reg2 ## __ ## mask2 ## _MASK \
+
+#define hpd_int_entry(reg_num)\
+ [DC_IRQ_SOURCE_HPD1 + reg_num] = {\
+ IRQ_REG_ENTRY(HPD, reg_num,\
+ DC_HPD_INT_CONTROL, DC_HPD_INT_EN,\
+ DC_HPD_INT_CONTROL, DC_HPD_INT_ACK),\
+ .status_reg = SRI(DC_HPD_INT_STATUS, HPD, reg_num),\
+ .funcs = &hpd_irq_info_funcs\
+ }
+
+#define hpd_rx_int_entry(reg_num)\
+ [DC_IRQ_SOURCE_HPD1RX + reg_num] = {\
+ IRQ_REG_ENTRY(HPD, reg_num,\
+ DC_HPD_INT_CONTROL, DC_HPD_RX_INT_EN,\
+ DC_HPD_INT_CONTROL, DC_HPD_RX_INT_ACK),\
+ .status_reg = SRI(DC_HPD_INT_STATUS, HPD, reg_num),\
+ .funcs = &hpd_rx_irq_info_funcs\
+ }
+#define pflip_int_entry(reg_num)\
+ [DC_IRQ_SOURCE_PFLIP1 + reg_num] = {\
+ IRQ_REG_ENTRY(HUBPREQ, reg_num,\
+ DCSURF_SURFACE_FLIP_INTERRUPT, SURFACE_FLIP_INT_MASK,\
+ DCSURF_SURFACE_FLIP_INTERRUPT, SURFACE_FLIP_CLEAR),\
+ .funcs = &pflip_irq_info_funcs\
+ }
+
+/* vupdate_no_lock_int_entry maps to DC_IRQ_SOURCE_VUPDATEx, to match semantic
+ * of DCE's DC_IRQ_SOURCE_VUPDATEx.
+ */
+#define vupdate_no_lock_int_entry(reg_num)\
+ [DC_IRQ_SOURCE_VUPDATE1 + reg_num] = {\
+ IRQ_REG_ENTRY(OTG, reg_num,\
+ OTG_GLOBAL_SYNC_STATUS, VUPDATE_NO_LOCK_INT_EN,\
+ OTG_GLOBAL_SYNC_STATUS, VUPDATE_NO_LOCK_EVENT_CLEAR),\
+ .funcs = &vupdate_no_lock_irq_info_funcs\
+ }
+
+#define vblank_int_entry(reg_num)\
+ [DC_IRQ_SOURCE_VBLANK1 + reg_num] = {\
+ IRQ_REG_ENTRY(OTG, reg_num,\
+ OTG_GLOBAL_SYNC_STATUS, VSTARTUP_INT_EN,\
+ OTG_GLOBAL_SYNC_STATUS, VSTARTUP_EVENT_CLEAR),\
+ .funcs = &vblank_irq_info_funcs\
+ }
+
+#define vline0_int_entry(reg_num)\
+ [DC_IRQ_SOURCE_DC1_VLINE0 + reg_num] = {\
+ IRQ_REG_ENTRY(OTG, reg_num,\
+ OTG_VERTICAL_INTERRUPT0_CONTROL, OTG_VERTICAL_INTERRUPT0_INT_ENABLE,\
+ OTG_VERTICAL_INTERRUPT0_CONTROL, OTG_VERTICAL_INTERRUPT0_CLEAR),\
+ .funcs = &vline0_irq_info_funcs\
+ }
+#define dmub_outbox_int_entry()\
+ [DC_IRQ_SOURCE_DMCUB_OUTBOX] = {\
+ IRQ_REG_ENTRY_DMUB(\
+ DMCUB_INTERRUPT_ENABLE, DMCUB_OUTBOX1_READY_INT_EN,\
+ DMCUB_INTERRUPT_ACK, DMCUB_OUTBOX1_READY_INT_ACK),\
+ .funcs = &outbox_irq_info_funcs\
+ }
+
+#define dummy_irq_entry() \
+ {\
+ .funcs = &dummy_irq_info_funcs\
+ }
+
+#define i2c_int_entry(reg_num) \
+ [DC_IRQ_SOURCE_I2C_DDC ## reg_num] = dummy_irq_entry()
+
+#define dp_sink_int_entry(reg_num) \
+ [DC_IRQ_SOURCE_DPSINK ## reg_num] = dummy_irq_entry()
+
+#define gpio_pad_int_entry(reg_num) \
+ [DC_IRQ_SOURCE_GPIOPAD ## reg_num] = dummy_irq_entry()
+
+#define dc_underflow_int_entry(reg_num) \
+ [DC_IRQ_SOURCE_DC ## reg_num ## UNDERFLOW] = dummy_irq_entry()
+
+static const struct irq_source_info_funcs dummy_irq_info_funcs = {
+ .set = dal_irq_service_dummy_set,
+ .ack = dal_irq_service_dummy_ack
+};
+
+static const struct irq_source_info
+irq_source_info_dcn315[DAL_IRQ_SOURCES_NUMBER] = {
+ [DC_IRQ_SOURCE_INVALID] = dummy_irq_entry(),
+ hpd_int_entry(0),
+ hpd_int_entry(1),
+ hpd_int_entry(2),
+ hpd_int_entry(3),
+ hpd_int_entry(4),
+ hpd_rx_int_entry(0),
+ hpd_rx_int_entry(1),
+ hpd_rx_int_entry(2),
+ hpd_rx_int_entry(3),
+ hpd_rx_int_entry(4),
+ i2c_int_entry(1),
+ i2c_int_entry(2),
+ i2c_int_entry(3),
+ i2c_int_entry(4),
+ i2c_int_entry(5),
+ i2c_int_entry(6),
+ dp_sink_int_entry(1),
+ dp_sink_int_entry(2),
+ dp_sink_int_entry(3),
+ dp_sink_int_entry(4),
+ dp_sink_int_entry(5),
+ dp_sink_int_entry(6),
+ [DC_IRQ_SOURCE_TIMER] = dummy_irq_entry(),
+ pflip_int_entry(0),
+ pflip_int_entry(1),
+ pflip_int_entry(2),
+ pflip_int_entry(3),
+ [DC_IRQ_SOURCE_PFLIP5] = dummy_irq_entry(),
+ [DC_IRQ_SOURCE_PFLIP6] = dummy_irq_entry(),
+ [DC_IRQ_SOURCE_PFLIP_UNDERLAY0] = dummy_irq_entry(),
+ gpio_pad_int_entry(0),
+ gpio_pad_int_entry(1),
+ gpio_pad_int_entry(2),
+ gpio_pad_int_entry(3),
+ gpio_pad_int_entry(4),
+ gpio_pad_int_entry(5),
+ gpio_pad_int_entry(6),
+ gpio_pad_int_entry(7),
+ gpio_pad_int_entry(8),
+ gpio_pad_int_entry(9),
+ gpio_pad_int_entry(10),
+ gpio_pad_int_entry(11),
+ gpio_pad_int_entry(12),
+ gpio_pad_int_entry(13),
+ gpio_pad_int_entry(14),
+ gpio_pad_int_entry(15),
+ gpio_pad_int_entry(16),
+ gpio_pad_int_entry(17),
+ gpio_pad_int_entry(18),
+ gpio_pad_int_entry(19),
+ gpio_pad_int_entry(20),
+ gpio_pad_int_entry(21),
+ gpio_pad_int_entry(22),
+ gpio_pad_int_entry(23),
+ gpio_pad_int_entry(24),
+ gpio_pad_int_entry(25),
+ gpio_pad_int_entry(26),
+ gpio_pad_int_entry(27),
+ gpio_pad_int_entry(28),
+ gpio_pad_int_entry(29),
+ gpio_pad_int_entry(30),
+ dc_underflow_int_entry(1),
+ dc_underflow_int_entry(2),
+ dc_underflow_int_entry(3),
+ dc_underflow_int_entry(4),
+ dc_underflow_int_entry(5),
+ dc_underflow_int_entry(6),
+ [DC_IRQ_SOURCE_DMCU_SCP] = dummy_irq_entry(),
+ [DC_IRQ_SOURCE_VBIOS_SW] = dummy_irq_entry(),
+ vupdate_no_lock_int_entry(0),
+ vupdate_no_lock_int_entry(1),
+ vupdate_no_lock_int_entry(2),
+ vupdate_no_lock_int_entry(3),
+ vblank_int_entry(0),
+ vblank_int_entry(1),
+ vblank_int_entry(2),
+ vblank_int_entry(3),
+ vline0_int_entry(0),
+ vline0_int_entry(1),
+ vline0_int_entry(2),
+ vline0_int_entry(3),
+ [DC_IRQ_SOURCE_DC5_VLINE1] = dummy_irq_entry(),
+ [DC_IRQ_SOURCE_DC6_VLINE1] = dummy_irq_entry(),
+ dmub_outbox_int_entry(),
+};
+
+static const struct irq_service_funcs irq_service_funcs_dcn315 = {
+ .to_dal_irq_source = to_dal_irq_source_dcn315
+};
+
+static void dcn315_irq_construct(
+ struct irq_service *irq_service,
+ struct irq_service_init_data *init_data)
+{
+ dal_irq_service_construct(irq_service, init_data);
+
+ irq_service->info = irq_source_info_dcn315;
+ irq_service->funcs = &irq_service_funcs_dcn315;
+}
+
+struct irq_service *dal_irq_service_dcn315_create(
+ struct irq_service_init_data *init_data)
+{
+ struct irq_service *irq_service = kzalloc(sizeof(*irq_service),
+ GFP_KERNEL);
+
+ if (!irq_service)
+ return NULL;
+
+ dcn315_irq_construct(irq_service, init_data);
+ return irq_service;
+}
diff --git a/drivers/gpu/drm/amd/display/dc/irq/dcn315/irq_service_dcn315.h b/drivers/gpu/drm/amd/display/dc/irq/dcn315/irq_service_dcn315.h
new file mode 100644
index 000000000000..a5a80486a8d6
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/dc/irq/dcn315/irq_service_dcn315.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2021 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: AMD
+ *
+ */
+
+#ifndef __DAL_IRQ_SERVICE_DCN315_H__
+#define __DAL_IRQ_SERVICE_DCN315_H__
+
+#include "../irq_service.h"
+
+struct irq_service *dal_irq_service_dcn315_create(
+ struct irq_service_init_data *init_data);
+
+#endif /* __DAL_IRQ_SERVICE_DCN315_H__ */
diff --git a/drivers/gpu/drm/amd/display/dc/link/Makefile b/drivers/gpu/drm/amd/display/dc/link/Makefile
new file mode 100644
index 000000000000..054c2a727eb2
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/dc/link/Makefile
@@ -0,0 +1,30 @@
+#
+# Copyright 2022 Advanced Micro Devices, Inc.
+#
+# Permission is hereby granted, free of charge, to any person obtaining a
+# copy of this software and associated documentation files (the "Software"),
+# to deal in the Software without restriction, including without limitation
+# the rights to use, copy, modify, merge, publish, distribute, sublicense,
+# and/or sell copies of the Software, and to permit persons to whom the
+# Software is furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+# THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+# OTHER DEALINGS IN THE SOFTWARE.
+#
+# Makefile for the link sub-component of DAL.
+# It abstracts the control and status of back end pipe such as DIO, HPO, DPIA,
+# PHY, HPD, DDC and etc).
+
+LINK = link_hwss_dio.o link_hwss_dpia.o link_hwss_hpo_dp.o link_dp_trace.o
+
+AMD_DAL_LINK = $(addprefix $(AMDDALPATH)/dc/link/,$(LINK))
+
+AMD_DISPLAY_FILES += $(AMD_DAL_LINK)
diff --git a/drivers/gpu/drm/amd/display/dc/link/link_dp_trace.c b/drivers/gpu/drm/amd/display/dc/link/link_dp_trace.c
new file mode 100644
index 000000000000..e7047391934b
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/dc/link/link_dp_trace.c
@@ -0,0 +1,146 @@
+/*
+ * Copyright 2022 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: AMD
+ *
+ */
+#include "dc_link.h"
+#include "link_dp_trace.h"
+
+void dp_trace_init(struct dc_link *link)
+{
+ memset(&link->dp_trace, 0, sizeof(link->dp_trace));
+ link->dp_trace.is_initialized = true;
+}
+
+void dp_trace_reset(struct dc_link *link)
+{
+ memset(&link->dp_trace, 0, sizeof(link->dp_trace));
+}
+
+bool dc_dp_trace_is_initialized(struct dc_link *link)
+{
+ return link->dp_trace.is_initialized;
+}
+
+void dp_trace_detect_lt_init(struct dc_link *link)
+{
+ memset(&link->dp_trace.detect_lt_trace, 0, sizeof(link->dp_trace.detect_lt_trace));
+}
+
+void dp_trace_commit_lt_init(struct dc_link *link)
+{
+ memset(&link->dp_trace.commit_lt_trace, 0, sizeof(link->dp_trace.commit_lt_trace));
+}
+
+void dp_trace_link_loss_increment(struct dc_link *link)
+{
+ link->dp_trace.link_loss_count++;
+}
+
+void dp_trace_lt_fail_count_update(struct dc_link *link,
+ unsigned int fail_count,
+ bool in_detection)
+{
+ if (in_detection)
+ link->dp_trace.detect_lt_trace.counts.fail = fail_count;
+ else
+ link->dp_trace.commit_lt_trace.counts.fail = fail_count;
+}
+
+void dp_trace_lt_total_count_increment(struct dc_link *link,
+ bool in_detection)
+{
+ if (in_detection)
+ link->dp_trace.detect_lt_trace.counts.total++;
+ else
+ link->dp_trace.commit_lt_trace.counts.total++;
+}
+
+void dc_dp_trace_set_is_logged_flag(struct dc_link *link,
+ bool in_detection,
+ bool is_logged)
+{
+ if (in_detection)
+ link->dp_trace.detect_lt_trace.is_logged = is_logged;
+ else
+ link->dp_trace.commit_lt_trace.is_logged = is_logged;
+}
+
+bool dc_dp_trace_is_logged(struct dc_link *link,
+ bool in_detection)
+{
+ if (in_detection)
+ return link->dp_trace.detect_lt_trace.is_logged;
+ else
+ return link->dp_trace.commit_lt_trace.is_logged;
+}
+
+void dp_trace_lt_result_update(struct dc_link *link,
+ enum link_training_result result,
+ bool in_detection)
+{
+ if (in_detection)
+ link->dp_trace.detect_lt_trace.result = result;
+ else
+ link->dp_trace.commit_lt_trace.result = result;
+}
+
+void dp_trace_set_lt_start_timestamp(struct dc_link *link,
+ bool in_detection)
+{
+ if (in_detection)
+ link->dp_trace.detect_lt_trace.timestamps.start = dm_get_timestamp(link->dc->ctx);
+ else
+ link->dp_trace.commit_lt_trace.timestamps.start = dm_get_timestamp(link->dc->ctx);
+}
+
+void dp_trace_set_lt_end_timestamp(struct dc_link *link,
+ bool in_detection)
+{
+ if (in_detection)
+ link->dp_trace.detect_lt_trace.timestamps.end = dm_get_timestamp(link->dc->ctx);
+ else
+ link->dp_trace.commit_lt_trace.timestamps.end = dm_get_timestamp(link->dc->ctx);
+}
+
+unsigned long long dc_dp_trace_get_lt_end_timestamp(struct dc_link *link,
+ bool in_detection)
+{
+ if (in_detection)
+ return link->dp_trace.detect_lt_trace.timestamps.end;
+ else
+ return link->dp_trace.commit_lt_trace.timestamps.end;
+}
+
+struct dp_trace_lt_counts *dc_dp_trace_get_lt_counts(struct dc_link *link,
+ bool in_detection)
+{
+ if (in_detection)
+ return &link->dp_trace.detect_lt_trace.counts;
+ else
+ return &link->dp_trace.commit_lt_trace.counts;
+}
+
+unsigned int dc_dp_trace_get_link_loss_count(struct dc_link *link)
+{
+ return link->dp_trace.link_loss_count;
+}
diff --git a/drivers/gpu/drm/amd/display/dc/link/link_dp_trace.h b/drivers/gpu/drm/amd/display/dc/link/link_dp_trace.h
new file mode 100644
index 000000000000..702f97c6ead0
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/dc/link/link_dp_trace.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2022 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: AMD
+ *
+ */
+#ifndef __LINK_DP_TRACE_H__
+#define __LINK_DP_TRACE_H__
+
+void dp_trace_init(struct dc_link *link);
+void dp_trace_reset(struct dc_link *link);
+bool dc_dp_trace_is_initialized(struct dc_link *link);
+void dp_trace_detect_lt_init(struct dc_link *link);
+void dp_trace_commit_lt_init(struct dc_link *link);
+void dp_trace_link_loss_increment(struct dc_link *link);
+void dp_trace_lt_fail_count_update(struct dc_link *link,
+ unsigned int fail_count,
+ bool in_detection);
+void dp_trace_lt_total_count_increment(struct dc_link *link,
+ bool in_detection);
+void dc_dp_trace_set_is_logged_flag(struct dc_link *link,
+ bool in_detection,
+ bool is_logged);
+bool dc_dp_trace_is_logged(struct dc_link *link,
+ bool in_detection);
+void dp_trace_lt_result_update(struct dc_link *link,
+ enum link_training_result result,
+ bool in_detection);
+void dp_trace_set_lt_start_timestamp(struct dc_link *link,
+ bool in_detection);
+void dp_trace_set_lt_end_timestamp(struct dc_link *link,
+ bool in_detection);
+unsigned long long dc_dp_trace_get_lt_end_timestamp(struct dc_link *link,
+ bool in_detection);
+struct dp_trace_lt_counts *dc_dp_trace_get_lt_counts(struct dc_link *link,
+ bool in_detection);
+unsigned int dc_dp_trace_get_link_loss_count(struct dc_link *link);
+
+#endif /* __LINK_DP_TRACE_H__ */
diff --git a/drivers/gpu/drm/amd/display/dc/link/link_hwss_dio.c b/drivers/gpu/drm/amd/display/dc/link/link_hwss_dio.c
new file mode 100644
index 000000000000..0f845113a6aa
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/dc/link/link_hwss_dio.c
@@ -0,0 +1,137 @@
+/*
+ * Copyright 2022 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: AMD
+ *
+ */
+#include "link_hwss_dio.h"
+#include "core_types.h"
+#include "dc_link_dp.h"
+#include "link_enc_cfg.h"
+
+void set_dio_throttled_vcp_size(struct pipe_ctx *pipe_ctx,
+ struct fixed31_32 throttled_vcp_size)
+{
+ struct stream_encoder *stream_encoder = pipe_ctx->stream_res.stream_enc;
+
+ stream_encoder->funcs->set_throttled_vcp_size(
+ stream_encoder,
+ throttled_vcp_size);
+}
+
+void setup_dio_stream_encoder(struct pipe_ctx *pipe_ctx)
+{
+ struct link_encoder *link_enc = link_enc_cfg_get_link_enc(pipe_ctx->stream->link);
+
+ link_enc->funcs->connect_dig_be_to_fe(link_enc,
+ pipe_ctx->stream_res.stream_enc->id, true);
+ if (dc_is_dp_signal(pipe_ctx->stream->signal))
+ dp_source_sequence_trace(pipe_ctx->stream->link,
+ DPCD_SOURCE_SEQ_AFTER_CONNECT_DIG_FE_BE);
+}
+
+void reset_dio_stream_encoder(struct pipe_ctx *pipe_ctx)
+{
+ struct link_encoder *link_enc = link_enc_cfg_get_link_enc(pipe_ctx->stream->link);
+
+ link_enc->funcs->connect_dig_be_to_fe(
+ link_enc,
+ pipe_ctx->stream_res.stream_enc->id,
+ false);
+ if (dc_is_dp_signal(pipe_ctx->stream->signal))
+ dp_source_sequence_trace(pipe_ctx->stream->link,
+ DPCD_SOURCE_SEQ_AFTER_DISCONNECT_DIG_FE_BE);
+
+}
+
+void enable_dio_dp_link_output(struct dc_link *link,
+ const struct link_resource *link_res,
+ enum signal_type signal,
+ enum clock_source_id clock_source,
+ const struct dc_link_settings *link_settings)
+{
+ struct link_encoder *link_enc = link_enc_cfg_get_link_enc(link);
+
+ if (dc_is_dp_sst_signal(signal))
+ link_enc->funcs->enable_dp_output(
+ link_enc,
+ link_settings,
+ clock_source);
+ else
+ link_enc->funcs->enable_dp_mst_output(
+ link_enc,
+ link_settings,
+ clock_source);
+ dp_source_sequence_trace(link, DPCD_SOURCE_SEQ_AFTER_ENABLE_LINK_PHY);
+}
+
+void disable_dio_dp_link_output(struct dc_link *link,
+ const struct link_resource *link_res,
+ enum signal_type signal)
+{
+ struct link_encoder *link_enc = link_enc_cfg_get_link_enc(link);
+
+ link_enc->funcs->disable_output(link_enc, signal);
+ dp_source_sequence_trace(link, DPCD_SOURCE_SEQ_AFTER_DISABLE_LINK_PHY);
+}
+
+void set_dio_dp_link_test_pattern(struct dc_link *link,
+ const struct link_resource *link_res,
+ struct encoder_set_dp_phy_pattern_param *tp_params)
+{
+ struct link_encoder *link_enc = link_enc_cfg_get_link_enc(link);
+
+ link_enc->funcs->dp_set_phy_pattern(link_enc, tp_params);
+ dp_source_sequence_trace(link, DPCD_SOURCE_SEQ_AFTER_SET_SOURCE_PATTERN);
+}
+
+void set_dio_dp_lane_settings(struct dc_link *link,
+ const struct link_resource *link_res,
+ const struct dc_link_settings *link_settings,
+ const struct dc_lane_settings lane_settings[LANE_COUNT_DP_MAX])
+{
+ struct link_encoder *link_enc = link_enc_cfg_get_link_enc(link);
+
+ link_enc->funcs->dp_set_lane_settings(link_enc, link_settings, lane_settings);
+}
+
+static const struct link_hwss dio_link_hwss = {
+ .setup_stream_encoder = setup_dio_stream_encoder,
+ .reset_stream_encoder = reset_dio_stream_encoder,
+ .ext = {
+ .set_throttled_vcp_size = set_dio_throttled_vcp_size,
+ .enable_dp_link_output = enable_dio_dp_link_output,
+ .disable_dp_link_output = disable_dio_dp_link_output,
+ .set_dp_link_test_pattern = set_dio_dp_link_test_pattern,
+ .set_dp_lane_settings = set_dio_dp_lane_settings,
+ },
+};
+
+bool can_use_dio_link_hwss(const struct dc_link *link,
+ const struct link_resource *link_res)
+{
+ return link->link_enc != NULL;
+}
+
+const struct link_hwss *get_dio_link_hwss(void)
+{
+ return &dio_link_hwss;
+}
diff --git a/drivers/gpu/drm/amd/display/dc/link/link_hwss_dio.h b/drivers/gpu/drm/amd/display/dc/link/link_hwss_dio.h
new file mode 100644
index 000000000000..680df20b1fa3
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/dc/link/link_hwss_dio.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2022 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: AMD
+ *
+ */
+#ifndef __LINK_HWSS_DIO_H__
+#define __LINK_HWSS_DIO_H__
+
+#include "link_hwss.h"
+
+const struct link_hwss *get_dio_link_hwss(void);
+bool can_use_dio_link_hwss(const struct dc_link *link,
+ const struct link_resource *link_res);
+void set_dio_throttled_vcp_size(struct pipe_ctx *pipe_ctx,
+ struct fixed31_32 throttled_vcp_size);
+void setup_dio_stream_encoder(struct pipe_ctx *pipe_ctx);
+void reset_dio_stream_encoder(struct pipe_ctx *pipe_ctx);
+void enable_dio_dp_link_output(struct dc_link *link,
+ const struct link_resource *link_res,
+ enum signal_type signal,
+ enum clock_source_id clock_source,
+ const struct dc_link_settings *link_settings);
+void disable_dio_dp_link_output(struct dc_link *link,
+ const struct link_resource *link_res,
+ enum signal_type signal);
+void set_dio_dp_link_test_pattern(struct dc_link *link,
+ const struct link_resource *link_res,
+ struct encoder_set_dp_phy_pattern_param *tp_params);
+void set_dio_dp_lane_settings(struct dc_link *link,
+ const struct link_resource *link_res,
+ const struct dc_link_settings *link_settings,
+ const struct dc_lane_settings lane_settings[LANE_COUNT_DP_MAX]);
+
+#endif /* __LINK_HWSS_DIO_H__ */
diff --git a/drivers/gpu/drm/amd/display/dc/link/link_hwss_dpia.c b/drivers/gpu/drm/amd/display/dc/link/link_hwss_dpia.c
new file mode 100644
index 000000000000..35b206225201
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/dc/link/link_hwss_dpia.c
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2022 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: AMD
+ *
+ */
+#include "link_hwss_dpia.h"
+#include "core_types.h"
+#include "link_hwss_dio.h"
+
+static const struct link_hwss dpia_link_hwss = {
+ .setup_stream_encoder = setup_dio_stream_encoder,
+ .reset_stream_encoder = reset_dio_stream_encoder,
+ .ext = {
+ .set_throttled_vcp_size = set_dio_throttled_vcp_size,
+ .enable_dp_link_output = enable_dio_dp_link_output,
+ .disable_dp_link_output = disable_dio_dp_link_output,
+ .set_dp_link_test_pattern = set_dio_dp_link_test_pattern,
+ .set_dp_lane_settings = set_dio_dp_lane_settings,
+ },
+};
+
+bool can_use_dpia_link_hwss(const struct dc_link *link,
+ const struct link_resource *link_res)
+{
+ return link->is_dig_mapping_flexible &&
+ link->dc->res_pool->funcs->link_encs_assign;
+}
+
+const struct link_hwss *get_dpia_link_hwss(void)
+{
+ return &dpia_link_hwss;
+}
diff --git a/drivers/gpu/drm/amd/display/dc/link/link_hwss_dpia.h b/drivers/gpu/drm/amd/display/dc/link/link_hwss_dpia.h
new file mode 100644
index 000000000000..ad16ec5d9bb7
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/dc/link/link_hwss_dpia.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2022 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: AMD
+ *
+ */
+#ifndef __LINK_HWSS_DPIA_H__
+#define __LINK_HWSS_DPIA_H__
+
+#include "link_hwss.h"
+
+const struct link_hwss *get_dpia_link_hwss(void);
+bool can_use_dpia_link_hwss(const struct dc_link *link,
+ const struct link_resource *link_res);
+
+#endif /* __LINK_HWSS_DPIA_H__ */
diff --git a/drivers/gpu/drm/amd/display/dc/link/link_hwss_hpo_dp.c b/drivers/gpu/drm/amd/display/dc/link/link_hwss_hpo_dp.c
new file mode 100644
index 000000000000..74919491675f
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/dc/link/link_hwss_hpo_dp.c
@@ -0,0 +1,254 @@
+/*
+ * Copyright 2022 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: AMD
+ *
+ */
+#include "link_hwss_hpo_dp.h"
+#include "dm_helpers.h"
+#include "core_types.h"
+#include "dccg.h"
+#include "dc_link_dp.h"
+
+static enum phyd32clk_clock_source get_phyd32clk_src(struct dc_link *link)
+{
+ switch (link->link_enc->transmitter) {
+ case TRANSMITTER_UNIPHY_A:
+ return PHYD32CLKA;
+ case TRANSMITTER_UNIPHY_B:
+ return PHYD32CLKB;
+ case TRANSMITTER_UNIPHY_C:
+ return PHYD32CLKC;
+ case TRANSMITTER_UNIPHY_D:
+ return PHYD32CLKD;
+ case TRANSMITTER_UNIPHY_E:
+ return PHYD32CLKE;
+ default:
+ return PHYD32CLKA;
+ }
+}
+
+static void set_hpo_dp_throttled_vcp_size(struct pipe_ctx *pipe_ctx,
+ struct fixed31_32 throttled_vcp_size)
+{
+ struct hpo_dp_stream_encoder *hpo_dp_stream_encoder =
+ pipe_ctx->stream_res.hpo_dp_stream_enc;
+ struct hpo_dp_link_encoder *hpo_dp_link_encoder =
+ pipe_ctx->link_res.hpo_dp_link_enc;
+
+ hpo_dp_link_encoder->funcs->set_throttled_vcp_size(hpo_dp_link_encoder,
+ hpo_dp_stream_encoder->inst,
+ throttled_vcp_size);
+}
+
+static void set_hpo_dp_hblank_min_symbol_width(struct pipe_ctx *pipe_ctx,
+ const struct dc_link_settings *link_settings,
+ struct fixed31_32 throttled_vcp_size)
+{
+ struct hpo_dp_stream_encoder *hpo_dp_stream_encoder =
+ pipe_ctx->stream_res.hpo_dp_stream_enc;
+ struct dc_crtc_timing *timing = &pipe_ctx->stream->timing;
+ struct fixed31_32 h_blank_in_ms, time_slot_in_ms, mtp_cnt_per_h_blank;
+ uint32_t link_bw_in_kbps =
+ dc_link_bandwidth_kbps(pipe_ctx->stream->link, link_settings);
+ uint16_t hblank_min_symbol_width = 0;
+
+ if (link_bw_in_kbps > 0) {
+ h_blank_in_ms = dc_fixpt_div(dc_fixpt_from_int(
+ timing->h_total - timing->h_addressable),
+ dc_fixpt_from_fraction(timing->pix_clk_100hz, 10));
+ time_slot_in_ms = dc_fixpt_from_fraction(32 * 4, link_bw_in_kbps);
+ mtp_cnt_per_h_blank = dc_fixpt_div(h_blank_in_ms,
+ dc_fixpt_mul_int(time_slot_in_ms, 64));
+ hblank_min_symbol_width = dc_fixpt_floor(
+ dc_fixpt_mul(mtp_cnt_per_h_blank, throttled_vcp_size));
+ }
+
+ hpo_dp_stream_encoder->funcs->set_hblank_min_symbol_width(hpo_dp_stream_encoder,
+ hblank_min_symbol_width);
+}
+
+static int get_odm_segment_count(struct pipe_ctx *pipe_ctx)
+{
+ struct pipe_ctx *odm_pipe = pipe_ctx->next_odm_pipe;
+ int count = 1;
+
+ while (odm_pipe != NULL) {
+ count++;
+ odm_pipe = odm_pipe->next_odm_pipe;
+ }
+
+ return count;
+}
+
+static void setup_hpo_dp_stream_encoder(struct pipe_ctx *pipe_ctx)
+{
+ struct dc *dc = pipe_ctx->stream->ctx->dc;
+ struct hpo_dp_stream_encoder *stream_enc = pipe_ctx->stream_res.hpo_dp_stream_enc;
+ struct hpo_dp_link_encoder *link_enc = pipe_ctx->link_res.hpo_dp_link_enc;
+ struct dccg *dccg = dc->res_pool->dccg;
+ struct timing_generator *tg = pipe_ctx->stream_res.tg;
+ int odm_segment_count = get_odm_segment_count(pipe_ctx);
+ enum phyd32clk_clock_source phyd32clk = get_phyd32clk_src(pipe_ctx->stream->link);
+
+ dccg->funcs->set_dpstreamclk(dccg, DTBCLK0, tg->inst);
+ dccg->funcs->enable_symclk32_se(dccg, stream_enc->inst, phyd32clk);
+ dccg->funcs->set_dtbclk_dto(dccg, tg->inst, pipe_ctx->stream->phy_pix_clk,
+ odm_segment_count,
+ &pipe_ctx->stream->timing);
+ stream_enc->funcs->enable_stream(stream_enc);
+ stream_enc->funcs->map_stream_to_link(stream_enc, stream_enc->inst, link_enc->inst);
+}
+
+static void reset_hpo_dp_stream_encoder(struct pipe_ctx *pipe_ctx)
+{
+ struct dc *dc = pipe_ctx->stream->ctx->dc;
+ struct hpo_dp_stream_encoder *stream_enc = pipe_ctx->stream_res.hpo_dp_stream_enc;
+ struct dccg *dccg = dc->res_pool->dccg;
+ struct timing_generator *tg = pipe_ctx->stream_res.tg;
+
+ stream_enc->funcs->disable(stream_enc);
+ dccg->funcs->set_dtbclk_dto(dccg, tg->inst, 0, 0, &pipe_ctx->stream->timing);
+ dccg->funcs->disable_symclk32_se(dccg, stream_enc->inst);
+ dccg->funcs->set_dpstreamclk(dccg, REFCLK, tg->inst);
+}
+
+static void enable_hpo_dp_fpga_link_output(struct dc_link *link,
+ const struct link_resource *link_res,
+ enum signal_type signal,
+ enum clock_source_id clock_source,
+ const struct dc_link_settings *link_settings)
+{
+ const struct dc *dc = link->dc;
+ enum phyd32clk_clock_source phyd32clk = get_phyd32clk_src(link);
+ int phyd32clk_freq_khz = link_settings->link_rate == LINK_RATE_UHBR10 ? 312500 :
+ link_settings->link_rate == LINK_RATE_UHBR13_5 ? 412875 :
+ link_settings->link_rate == LINK_RATE_UHBR20 ? 625000 : 0;
+
+ dm_set_phyd32clk(dc->ctx, phyd32clk_freq_khz);
+ dc->res_pool->dccg->funcs->set_physymclk(
+ dc->res_pool->dccg,
+ link->link_enc_hw_inst,
+ PHYSYMCLK_FORCE_SRC_PHYD32CLK,
+ true);
+ dc->res_pool->dccg->funcs->enable_symclk32_le(
+ dc->res_pool->dccg,
+ link_res->hpo_dp_link_enc->inst,
+ phyd32clk);
+ link_res->hpo_dp_link_enc->funcs->link_enable(
+ link_res->hpo_dp_link_enc,
+ link_settings->lane_count);
+
+}
+
+static void enable_hpo_dp_link_output(struct dc_link *link,
+ const struct link_resource *link_res,
+ enum signal_type signal,
+ enum clock_source_id clock_source,
+ const struct dc_link_settings *link_settings)
+{
+ if (IS_FPGA_MAXIMUS_DC(link->dc->ctx->dce_environment))
+ enable_hpo_dp_fpga_link_output(link, link_res, signal,
+ clock_source, link_settings);
+ else
+ link_res->hpo_dp_link_enc->funcs->enable_link_phy(
+ link_res->hpo_dp_link_enc,
+ link_settings,
+ link->link_enc->transmitter,
+ link->link_enc->hpd_source);
+}
+
+
+static void disable_hpo_dp_fpga_link_output(struct dc_link *link,
+ const struct link_resource *link_res,
+ enum signal_type signal)
+{
+ const struct dc *dc = link->dc;
+
+ link_res->hpo_dp_link_enc->funcs->link_disable(link_res->hpo_dp_link_enc);
+ dc->res_pool->dccg->funcs->disable_symclk32_le(
+ dc->res_pool->dccg,
+ link_res->hpo_dp_link_enc->inst);
+ dc->res_pool->dccg->funcs->set_physymclk(
+ dc->res_pool->dccg,
+ link->link_enc_hw_inst,
+ PHYSYMCLK_FORCE_SRC_SYMCLK,
+ false);
+ dm_set_phyd32clk(dc->ctx, 0);
+}
+
+static void disable_hpo_dp_link_output(struct dc_link *link,
+ const struct link_resource *link_res,
+ enum signal_type signal)
+{
+ if (IS_FPGA_MAXIMUS_DC(link->dc->ctx->dce_environment)) {
+ disable_hpo_dp_fpga_link_output(link, link_res, signal);
+ } else {
+ link_res->hpo_dp_link_enc->funcs->link_disable(link_res->hpo_dp_link_enc);
+ link_res->hpo_dp_link_enc->funcs->disable_link_phy(
+ link_res->hpo_dp_link_enc, signal);
+ }
+}
+
+static void set_hpo_dp_link_test_pattern(struct dc_link *link,
+ const struct link_resource *link_res,
+ struct encoder_set_dp_phy_pattern_param *tp_params)
+{
+ link_res->hpo_dp_link_enc->funcs->set_link_test_pattern(
+ link_res->hpo_dp_link_enc, tp_params);
+ dp_source_sequence_trace(link, DPCD_SOURCE_SEQ_AFTER_SET_SOURCE_PATTERN);
+}
+
+static void set_hpo_dp_lane_settings(struct dc_link *link,
+ const struct link_resource *link_res,
+ const struct dc_link_settings *link_settings,
+ const struct dc_lane_settings lane_settings[LANE_COUNT_DP_MAX])
+{
+ link_res->hpo_dp_link_enc->funcs->set_ffe(
+ link_res->hpo_dp_link_enc,
+ link_settings,
+ lane_settings[0].FFE_PRESET.raw);
+}
+
+static const struct link_hwss hpo_dp_link_hwss = {
+ .setup_stream_encoder = setup_hpo_dp_stream_encoder,
+ .reset_stream_encoder = reset_hpo_dp_stream_encoder,
+ .ext = {
+ .set_throttled_vcp_size = set_hpo_dp_throttled_vcp_size,
+ .set_hblank_min_symbol_width = set_hpo_dp_hblank_min_symbol_width,
+ .enable_dp_link_output = enable_hpo_dp_link_output,
+ .disable_dp_link_output = disable_hpo_dp_link_output,
+ .set_dp_link_test_pattern = set_hpo_dp_link_test_pattern,
+ .set_dp_lane_settings = set_hpo_dp_lane_settings,
+ },
+};
+
+bool can_use_hpo_dp_link_hwss(const struct dc_link *link,
+ const struct link_resource *link_res)
+{
+ return link_res->hpo_dp_link_enc != NULL;
+}
+
+const struct link_hwss *get_hpo_dp_link_hwss(void)
+{
+ return &hpo_dp_link_hwss;
+}
+
diff --git a/drivers/gpu/drm/amd/display/dc/link/link_hwss_hpo_dp.h b/drivers/gpu/drm/amd/display/dc/link/link_hwss_hpo_dp.h
new file mode 100644
index 000000000000..57d447ec27b8
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/dc/link/link_hwss_hpo_dp.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2022 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: AMD
+ *
+ */
+#ifndef __LINK_HWSS_HPO_DP_H__
+#define __LINK_HWSS_HPO_DP_H__
+
+#include "link_hwss.h"
+
+bool can_use_hpo_dp_link_hwss(const struct dc_link *link,
+ const struct link_resource *link_res);
+const struct link_hwss *get_hpo_dp_link_hwss(void);
+
+
+#endif /* __LINK_HWSS_HPO_DP_H__ */
diff --git a/drivers/gpu/drm/amd/display/dc/link/link_hwss_hpo_frl.c b/drivers/gpu/drm/amd/display/dc/link/link_hwss_hpo_frl.c
new file mode 100644
index 000000000000..9df273ca699b
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/dc/link/link_hwss_hpo_frl.c
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2022 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: AMD
+ *
+ */
+#include "link_hwss_hpo_frl.h"
+#include "core_types.h"
+#include "virtual/virtual_link_hwss.h"
+
+static const struct link_hwss hpo_frl_link_hwss = {
+ .setup_stream_encoder = virtual_setup_stream_encoder,
+ .reset_stream_encoder = virtual_reset_stream_encoder,
+};
+
+bool can_use_hpo_frl_link_hwss(const struct dc_link *link,
+ const struct link_resource *link_res)
+{
+ return link_res->hpo_frl_link_enc != NULL;
+}
+
+const struct link_hwss *get_hpo_frl_link_hwss(void)
+{
+ return &hpo_frl_link_hwss;
+}
diff --git a/drivers/gpu/drm/amd/display/dc/link/link_hwss_hpo_frl.h b/drivers/gpu/drm/amd/display/dc/link/link_hwss_hpo_frl.h
new file mode 100644
index 000000000000..ea8d9760132f
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/dc/link/link_hwss_hpo_frl.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2022 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: AMD
+ *
+ */
+#ifndef __LINK_HWSS_HPO_FRL_H__
+#define __LINK_HWSS_HPO_FRL_H__
+
+#include "link_hwss.h"
+
+bool can_use_hpo_frl_link_hwss(const struct dc_link *link,
+ const struct link_resource *link_res);
+const struct link_hwss *get_hpo_frl_link_hwss(void);
+
+#endif /* __LINK_HWSS_HPO_FRL_H__ */
diff --git a/drivers/gpu/drm/amd/display/dc/os_types.h b/drivers/gpu/drm/amd/display/dc/os_types.h
index 5df1d80c8341..17d05071b809 100644
--- a/drivers/gpu/drm/amd/display/dc/os_types.h
+++ b/drivers/gpu/drm/amd/display/dc/os_types.h
@@ -36,7 +36,7 @@
#include <asm/byteorder.h>
#include <drm/drm_print.h>
-#include <drm/drm_dp_helper.h>
+#include <drm/dp/drm_dp_helper.h>
#include "cgs_common.h"
diff --git a/drivers/gpu/drm/amd/display/dc/virtual/Makefile b/drivers/gpu/drm/amd/display/dc/virtual/Makefile
index 07326d244d50..931facd4dab5 100644
--- a/drivers/gpu/drm/amd/display/dc/virtual/Makefile
+++ b/drivers/gpu/drm/amd/display/dc/virtual/Makefile
@@ -23,7 +23,7 @@
# Makefile for the virtual sub-component of DAL.
# It provides the control and status of HW CRTC block.
-VIRTUAL = virtual_link_encoder.o virtual_stream_encoder.o
+VIRTUAL = virtual_link_encoder.o virtual_stream_encoder.o virtual_link_hwss.o
AMD_DAL_VIRTUAL = $(addprefix $(AMDDALPATH)/dc/virtual/,$(VIRTUAL))
diff --git a/drivers/gpu/drm/amd/display/dc/virtual/virtual_link_encoder.c b/drivers/gpu/drm/amd/display/dc/virtual/virtual_link_encoder.c
index 348e9a600a72..df8bc44bc4be 100644
--- a/drivers/gpu/drm/amd/display/dc/virtual/virtual_link_encoder.c
+++ b/drivers/gpu/drm/amd/display/dc/virtual/virtual_link_encoder.c
@@ -63,7 +63,8 @@ static void virtual_link_encoder_disable_output(
static void virtual_link_encoder_dp_set_lane_settings(
struct link_encoder *enc,
- const struct link_training_settings *link_settings) {}
+ const struct dc_link_settings *link_settings,
+ const struct dc_lane_settings lane_settings[LANE_COUNT_DP_MAX]) {}
static void virtual_link_encoder_dp_set_phy_pattern(
struct link_encoder *enc,
diff --git a/drivers/gpu/drm/amd/display/dc/virtual/virtual_link_hwss.c b/drivers/gpu/drm/amd/display/dc/virtual/virtual_link_hwss.c
new file mode 100644
index 000000000000..525eba2a3354
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/dc/virtual/virtual_link_hwss.c
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2022 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: AMD
+ *
+ */
+
+#include "virtual_link_hwss.h"
+
+void virtual_setup_stream_encoder(struct pipe_ctx *pipe_ctx)
+{
+}
+
+void virtual_reset_stream_encoder(struct pipe_ctx *pipe_ctx)
+{
+}
+static const struct link_hwss virtual_link_hwss = {
+ .setup_stream_encoder = virtual_setup_stream_encoder,
+ .reset_stream_encoder = virtual_reset_stream_encoder,
+};
+
+const struct link_hwss *get_virtual_link_hwss(void)
+{
+ return &virtual_link_hwss;
+}
diff --git a/drivers/gpu/drm/amd/display/dc/virtual/virtual_link_hwss.h b/drivers/gpu/drm/amd/display/dc/virtual/virtual_link_hwss.h
new file mode 100644
index 000000000000..e6bcb4bb0f3a
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/dc/virtual/virtual_link_hwss.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2022 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: AMD
+ *
+ */
+#ifndef __DC_VIRTUAL_LINK_HWSS_H__
+#define __DC_VIRTUAL_LINK_HWSS_H__
+
+#include "core_types.h"
+
+void virtual_setup_stream_encoder(struct pipe_ctx *pipe_ctx);
+void virtual_reset_stream_encoder(struct pipe_ctx *pipe_ctx);
+const struct link_hwss *get_virtual_link_hwss(void);
+
+#endif /* __DC_VIRTUAL_LINK_HWSS_H__ */
diff --git a/drivers/gpu/drm/amd/display/dmub/dmub_srv.h b/drivers/gpu/drm/amd/display/dmub/dmub_srv.h
index 83855b8a32e9..56757a286a03 100644
--- a/drivers/gpu/drm/amd/display/dmub/dmub_srv.h
+++ b/drivers/gpu/drm/amd/display/dmub/dmub_srv.h
@@ -98,6 +98,8 @@ enum dmub_asic {
DMUB_ASIC_DCN303,
DMUB_ASIC_DCN31,
DMUB_ASIC_DCN31B,
+ DMUB_ASIC_DCN315,
+ DMUB_ASIC_DCN316,
DMUB_ASIC_MAX,
};
diff --git a/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h b/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h
index 873ecd04e01d..71214c7a60fc 100644
--- a/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h
+++ b/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h
@@ -46,10 +46,10 @@
/* Firmware versioning. */
#ifdef DMUB_EXPOSE_VERSION
-#define DMUB_FW_VERSION_GIT_HASH 0xbaf06b95
+#define DMUB_FW_VERSION_GIT_HASH 0x929554ba
#define DMUB_FW_VERSION_MAJOR 0
#define DMUB_FW_VERSION_MINOR 0
-#define DMUB_FW_VERSION_REVISION 98
+#define DMUB_FW_VERSION_REVISION 108
#define DMUB_FW_VERSION_TEST 0
#define DMUB_FW_VERSION_VBIOS 0
#define DMUB_FW_VERSION_HOTFIX 0
@@ -367,8 +367,9 @@ union dmub_fw_boot_options {
/**< 1 if all root clock gating is enabled and low power memory is enabled*/
uint32_t power_optimization: 1;
uint32_t diag_env: 1; /* 1 if diagnostic environment */
+ uint32_t gpint_scratch8: 1; /* 1 if GPINT is in scratch8*/
- uint32_t reserved : 19; /**< reserved */
+ uint32_t reserved : 18; /**< reserved */
} bits; /**< boot bits */
uint32_t all; /**< 32-bit access to bits */
};
@@ -523,7 +524,7 @@ union dmub_inbox0_cmd_lock_hw {
uint32_t command_code: 8;
/* NOTE: Must be have enough bits to match: enum hw_lock_client */
- uint32_t hw_lock_client: 1;
+ uint32_t hw_lock_client: 2;
/* NOTE: Below fields must match with: struct dmub_hw_lock_inst_flags */
uint32_t otg_inst: 3;
@@ -538,7 +539,7 @@ union dmub_inbox0_cmd_lock_hw {
uint32_t lock: 1; /**< Lock */
uint32_t should_release: 1; /**< Release */
- uint32_t reserved: 8; /**< Reserved for extending more clients, HW, etc. */
+ uint32_t reserved: 7; /**< Reserved for extending more clients, HW, etc. */
} bits;
uint32_t all;
};
@@ -644,6 +645,7 @@ enum dmub_cmd_type {
* Command type used for OUTBOX1 notification enable
*/
DMUB_CMD__OUTBOX1_ENABLE = 71,
+
/**
* Command type used for all idle optimization commands.
*/
@@ -656,6 +658,7 @@ enum dmub_cmd_type {
* Command type used for all panel control commands.
*/
DMUB_CMD__PANEL_CNTL = 74,
+
/**
* Command type used for interfacing with DPIA.
*/
@@ -665,6 +668,10 @@ enum dmub_cmd_type {
*/
DMUB_CMD__EDID_CEA = 79,
/**
+ * Command type used for getting usbc cable ID
+ */
+ DMUB_CMD_GET_USBC_CABLE_ID = 81,
+ /**
* Command type used for all VBIOS interface commands.
*/
DMUB_CMD__VBIOS = 128,
@@ -1443,6 +1450,80 @@ enum dmub_cmd_mall_type {
DMUB_CMD__MALL_ACTION_NO_DF_REQ = 3,
};
+/**
+ * PHY Link rate for DP.
+ */
+enum phy_link_rate {
+ /**
+ * not supported.
+ */
+ PHY_RATE_UNKNOWN = 0,
+ /**
+ * Rate_1 (RBR) - 1.62 Gbps/Lane
+ */
+ PHY_RATE_162 = 1,
+ /**
+ * Rate_2 - 2.16 Gbps/Lane
+ */
+ PHY_RATE_216 = 2,
+ /**
+ * Rate_3 - 2.43 Gbps/Lane
+ */
+ PHY_RATE_243 = 3,
+ /**
+ * Rate_4 (HBR) - 2.70 Gbps/Lane
+ */
+ PHY_RATE_270 = 4,
+ /**
+ * Rate_5 (RBR2)- 3.24 Gbps/Lane
+ */
+ PHY_RATE_324 = 5,
+ /**
+ * Rate_6 - 4.32 Gbps/Lane
+ */
+ PHY_RATE_432 = 6,
+ /**
+ * Rate_7 (HBR2)- 5.40 Gbps/Lane
+ */
+ PHY_RATE_540 = 7,
+ /**
+ * Rate_8 (HBR3)- 8.10 Gbps/Lane
+ */
+ PHY_RATE_810 = 8,
+ /**
+ * UHBR10 - 10.0 Gbps/Lane
+ */
+ PHY_RATE_1000 = 9,
+ /**
+ * UHBR13.5 - 13.5 Gbps/Lane
+ */
+ PHY_RATE_1350 = 10,
+ /**
+ * UHBR10 - 20.0 Gbps/Lane
+ */
+ PHY_RATE_2000 = 11,
+};
+
+/**
+ * enum dmub_phy_fsm_state - PHY FSM states.
+ * PHY FSM state to transit to during PSR enable/disable.
+ */
+enum dmub_phy_fsm_state {
+ DMUB_PHY_FSM_POWER_UP_DEFAULT = 0,
+ DMUB_PHY_FSM_RESET,
+ DMUB_PHY_FSM_RESET_RELEASED,
+ DMUB_PHY_FSM_SRAM_LOAD_DONE,
+ DMUB_PHY_FSM_INITIALIZED,
+ DMUB_PHY_FSM_CALIBRATED,
+ DMUB_PHY_FSM_CALIBRATED_LP,
+ DMUB_PHY_FSM_CALIBRATED_PG,
+ DMUB_PHY_FSM_POWER_DOWN,
+ DMUB_PHY_FSM_PLL_EN,
+ DMUB_PHY_FSM_TX_EN,
+ DMUB_PHY_FSM_FAST_LP,
+};
+
+
/**
* Data passed from driver to FW in a DMUB_CMD__PSR_COPY_SETTINGS command.
@@ -1553,10 +1634,14 @@ struct dmub_cmd_psr_copy_settings_data {
* DSC enable status in driver
*/
uint8_t dsc_enable_status;
+ /*
+ * Use FSM state for PSR power up/down
+ */
+ uint8_t use_phy_fsm;
/**
- * Explicit padding to 3 byte boundary.
+ * Explicit padding to 2 byte boundary.
*/
- uint8_t pad3[3];
+ uint8_t pad3[2];
};
/**
@@ -1687,9 +1772,16 @@ struct dmub_cmd_psr_force_static_data {
*/
uint8_t panel_inst;
/**
- * Explicit padding to 4 byte boundary.
+ * Phy state to enter.
+ * Values to use are defined in dmub_phy_fsm_state
*/
- uint8_t pad[2];
+ uint8_t phy_fsm_state;
+ /**
+ * Phy rate for DP - RBR/HBR/HBR2/HBR3.
+ * Set this using enum phy_link_rate.
+ * This does not support HDMI/DP2 for now.
+ */
+ uint8_t phy_rate;
};
/**
@@ -2366,6 +2458,9 @@ struct dmub_cmd_panel_cntl_data {
uint32_t bl_pwm_ref_div1; /* in/out */
uint8_t is_backlight_on : 1; /* in/out */
uint8_t is_powered_on : 1; /* in/out */
+ uint8_t padding[3];
+ uint32_t bl_pwm_ref_div2; /* in/out */
+ uint8_t reserved[4];
};
/**
@@ -2481,6 +2576,38 @@ struct dmub_rb_cmd_edid_cea {
};
/**
+ * struct dmub_cmd_cable_id_input - Defines the input of DMUB_CMD_GET_USBC_CABLE_ID command.
+ */
+struct dmub_cmd_cable_id_input {
+ uint8_t phy_inst; /**< phy inst for cable id data */
+};
+
+/**
+ * struct dmub_cmd_cable_id_input - Defines the output of DMUB_CMD_GET_USBC_CABLE_ID command.
+ */
+struct dmub_cmd_cable_id_output {
+ uint8_t UHBR10_20_CAPABILITY :2; /**< b'01 for UHBR10 support, b'10 for both UHBR10 and UHBR20 support */
+ uint8_t UHBR13_5_CAPABILITY :1; /**< b'1 for UHBR13.5 support */
+ uint8_t CABLE_TYPE :3; /**< b'01 for passive cable, b'10 for active LRD cable, b'11 for active retimer cable */
+ uint8_t RESERVED :2; /**< reserved means not defined */
+};
+
+/**
+ * Definition of a DMUB_CMD_GET_USBC_CABLE_ID command
+ */
+struct dmub_rb_cmd_get_usbc_cable_id {
+ struct dmub_cmd_header header; /**< Command header */
+ /**
+ * Data passed from driver to FW in a DMUB_CMD_GET_USBC_CABLE_ID command.
+ */
+ union dmub_cmd_cable_id_data {
+ struct dmub_cmd_cable_id_input input; /**< Input */
+ struct dmub_cmd_cable_id_output output; /**< Output */
+ uint8_t output_raw; /**< Raw data output */
+ } data;
+};
+
+/**
* union dmub_rb_cmd - DMUB inbox command.
*/
union dmub_rb_cmd {
@@ -2645,6 +2772,10 @@ union dmub_rb_cmd {
* Definition of a DMUB_CMD__EDID_CEA command.
*/
struct dmub_rb_cmd_edid_cea edid_cea;
+ /**
+ * Definition of a DMUB_CMD_GET_USBC_CABLE_ID command.
+ */
+ struct dmub_rb_cmd_get_usbc_cable_id cable_id;
};
/**
@@ -2918,6 +3049,10 @@ static inline void dmub_rb_flush_pending(const struct dmub_rb *rb)
uint64_t temp;
uint8_t i;
+ /* Don't remove this.
+ * The contents need to actually be read from the ring buffer
+ * for this function to be effective.
+ */
for (i = 0; i < DMUB_RB_CMD_SIZE / sizeof(uint64_t); i++)
temp = *data++;
diff --git a/drivers/gpu/drm/amd/display/dmub/src/Makefile b/drivers/gpu/drm/amd/display/dmub/src/Makefile
index 0495bcdd3463..856c7f48de7a 100644
--- a/drivers/gpu/drm/amd/display/dmub/src/Makefile
+++ b/drivers/gpu/drm/amd/display/dmub/src/Makefile
@@ -22,7 +22,7 @@
DMUB = dmub_srv.o dmub_srv_stat.o dmub_reg.o dmub_dcn20.o dmub_dcn21.o
DMUB += dmub_dcn30.o dmub_dcn301.o dmub_dcn302.o dmub_dcn303.o
-DMUB += dmub_dcn31.o
+DMUB += dmub_dcn31.o dmub_dcn315.o dmub_dcn316.o
AMD_DAL_DMUB = $(addprefix $(AMDDALPATH)/dmub/src/,$(DMUB))
diff --git a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn31.c b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn31.c
index fa0569174aec..82c651535628 100644
--- a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn31.c
+++ b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn31.c
@@ -441,7 +441,7 @@ void dmub_dcn31_get_diagnostic_data(struct dmub_srv *dmub, struct dmub_diagnosti
bool dmub_dcn31_should_detect(struct dmub_srv *dmub)
{
uint32_t fw_boot_status = REG_READ(DMCUB_SCRATCH0);
- bool should_detect = fw_boot_status & DMUB_FW_BOOT_STATUS_BIT_DETECTION_REQUIRED;
+ bool should_detect = (fw_boot_status & DMUB_FW_BOOT_STATUS_BIT_DETECTION_REQUIRED) != 0;
return should_detect;
}
diff --git a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn315.c b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn315.c
new file mode 100644
index 000000000000..4dbb15c898aa
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn315.c
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2021 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: AMD
+ *
+ */
+
+#include "../dmub_srv.h"
+#include "dmub_reg.h"
+#include "dmub_dcn315.h"
+
+#include "dcn/dcn_3_1_5_offset.h"
+#include "dcn/dcn_3_1_5_sh_mask.h"
+
+#define DCN_BASE__INST0_SEG0 0x00000012
+#define DCN_BASE__INST0_SEG1 0x000000C0
+#define DCN_BASE__INST0_SEG2 0x000034C0
+#define DCN_BASE__INST0_SEG3 0x00009000
+#define DCN_BASE__INST0_SEG4 0x02403C00
+#define DCN_BASE__INST0_SEG5 0
+
+#define BASE_INNER(seg) DCN_BASE__INST0_SEG##seg
+#define CTX dmub
+#define REGS dmub->regs_dcn31
+#define REG_OFFSET_EXP(reg_name) (BASE(reg##reg_name##_BASE_IDX) + reg##reg_name)
+
+/* Registers. */
+
+const struct dmub_srv_dcn31_regs dmub_srv_dcn315_regs = {
+#define DMUB_SR(reg) REG_OFFSET_EXP(reg),
+ {
+ DMUB_DCN31_REGS()
+ DMCUB_INTERNAL_REGS()
+ },
+#undef DMUB_SR
+
+#define DMUB_SF(reg, field) FD_MASK(reg, field),
+ { DMUB_DCN315_FIELDS() },
+#undef DMUB_SF
+
+#define DMUB_SF(reg, field) FD_SHIFT(reg, field),
+ { DMUB_DCN315_FIELDS() },
+#undef DMUB_SF
+};
diff --git a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn315.h b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn315.h
new file mode 100644
index 000000000000..0049ae96aa7e
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn315.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2021 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: AMD
+ *
+ */
+
+#ifndef _DMUB_DCN315_H_
+#define _DMUB_DCN315_H_
+
+#include "dmub_dcn31.h"
+
+#define DMUB_DCN315_FIELDS() \
+ DMUB_SF(DMCUB_CNTL, DMCUB_ENABLE) \
+ DMUB_SF(DMCUB_CNTL, DMCUB_TRACEPORT_EN) \
+ DMUB_SF(DMCUB_CNTL2, DMCUB_SOFT_RESET) \
+ DMUB_SF(DMCUB_SEC_CNTL, DMCUB_SEC_RESET) \
+ DMUB_SF(DMCUB_SEC_CNTL, DMCUB_MEM_UNIT_ID) \
+ DMUB_SF(DMCUB_SEC_CNTL, DMCUB_SEC_RESET_STATUS) \
+ DMUB_SF(DMCUB_REGION3_CW0_TOP_ADDRESS, DMCUB_REGION3_CW0_TOP_ADDRESS) \
+ DMUB_SF(DMCUB_REGION3_CW0_TOP_ADDRESS, DMCUB_REGION3_CW0_ENABLE) \
+ DMUB_SF(DMCUB_REGION3_CW1_TOP_ADDRESS, DMCUB_REGION3_CW1_TOP_ADDRESS) \
+ DMUB_SF(DMCUB_REGION3_CW1_TOP_ADDRESS, DMCUB_REGION3_CW1_ENABLE) \
+ DMUB_SF(DMCUB_REGION3_CW2_TOP_ADDRESS, DMCUB_REGION3_CW2_TOP_ADDRESS) \
+ DMUB_SF(DMCUB_REGION3_CW2_TOP_ADDRESS, DMCUB_REGION3_CW2_ENABLE) \
+ DMUB_SF(DMCUB_REGION3_CW3_TOP_ADDRESS, DMCUB_REGION3_CW3_TOP_ADDRESS) \
+ DMUB_SF(DMCUB_REGION3_CW3_TOP_ADDRESS, DMCUB_REGION3_CW3_ENABLE) \
+ DMUB_SF(DMCUB_REGION3_CW4_TOP_ADDRESS, DMCUB_REGION3_CW4_TOP_ADDRESS) \
+ DMUB_SF(DMCUB_REGION3_CW4_TOP_ADDRESS, DMCUB_REGION3_CW4_ENABLE) \
+ DMUB_SF(DMCUB_REGION3_CW5_TOP_ADDRESS, DMCUB_REGION3_CW5_TOP_ADDRESS) \
+ DMUB_SF(DMCUB_REGION3_CW5_TOP_ADDRESS, DMCUB_REGION3_CW5_ENABLE) \
+ DMUB_SF(DMCUB_REGION3_CW6_TOP_ADDRESS, DMCUB_REGION3_CW6_TOP_ADDRESS) \
+ DMUB_SF(DMCUB_REGION3_CW6_TOP_ADDRESS, DMCUB_REGION3_CW6_ENABLE) \
+ DMUB_SF(DMCUB_REGION3_CW7_TOP_ADDRESS, DMCUB_REGION3_CW7_TOP_ADDRESS) \
+ DMUB_SF(DMCUB_REGION3_CW7_TOP_ADDRESS, DMCUB_REGION3_CW7_ENABLE) \
+ DMUB_SF(DMCUB_REGION4_TOP_ADDRESS, DMCUB_REGION4_TOP_ADDRESS) \
+ DMUB_SF(DMCUB_REGION4_TOP_ADDRESS, DMCUB_REGION4_ENABLE) \
+ DMUB_SF(DMCUB_REGION5_TOP_ADDRESS, DMCUB_REGION5_TOP_ADDRESS) \
+ DMUB_SF(DMCUB_REGION5_TOP_ADDRESS, DMCUB_REGION5_ENABLE) \
+ DMUB_SF(CC_DC_PIPE_DIS, DC_DMCUB_ENABLE) \
+ DMUB_SF(MMHUBBUB_SOFT_RESET, DMUIF_SOFT_RESET) \
+ DMUB_SF(DCN_VM_FB_LOCATION_BASE, FB_BASE) \
+ DMUB_SF(DCN_VM_FB_OFFSET, FB_OFFSET) \
+ DMUB_SF(DMCUB_INBOX0_WPTR, DMCUB_INBOX0_WPTR) \
+ DMUB_SF(DMCUB_INTERRUPT_ENABLE, DMCUB_GPINT2_INT_EN) \
+ DMUB_SF(DMCUB_INTERRUPT_ACK, DMCUB_GPINT2_INT_ACK)
+
+extern const struct dmub_srv_dcn31_regs dmub_srv_dcn315_regs;
+
+#endif /* _DMUB_DCN315_H_ */
diff --git a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn316.c b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn316.c
new file mode 100644
index 000000000000..c43d1e3819e0
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn316.c
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2021 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: AMD
+ *
+ */
+
+#include "../dmub_srv.h"
+#include "dmub_reg.h"
+#include "dmub_dcn316.h"
+
+#include "dcn/dcn_3_1_6_offset.h"
+#include "dcn/dcn_3_1_6_sh_mask.h"
+
+#define DCN_BASE__INST0_SEG0 0x00000012
+#define DCN_BASE__INST0_SEG1 0x000000C0
+#define DCN_BASE__INST0_SEG2 0x000034C0
+#define DCN_BASE__INST0_SEG3 0x00009000
+#define DCN_BASE__INST0_SEG4 0x02403C00
+#define DCN_BASE__INST0_SEG5 0
+
+#define BASE_INNER(seg) DCN_BASE__INST0_SEG##seg
+#define CTX dmub
+#define REGS dmub->regs_dcn31
+#define REG_OFFSET_EXP(reg_name) (BASE(reg##reg_name##_BASE_IDX) + reg##reg_name)
+
+/* Registers. */
+
+const struct dmub_srv_dcn31_regs dmub_srv_dcn316_regs = {
+#define DMUB_SR(reg) REG_OFFSET_EXP(reg),
+ {
+ DMUB_DCN31_REGS()
+ DMCUB_INTERNAL_REGS()
+ },
+#undef DMUB_SR
+
+#define DMUB_SF(reg, field) FD_MASK(reg, field),
+ { DMUB_DCN31_FIELDS() },
+#undef DMUB_SF
+
+#define DMUB_SF(reg, field) FD_SHIFT(reg, field),
+ { DMUB_DCN31_FIELDS() },
+#undef DMUB_SF
+};
diff --git a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn316.h b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn316.h
new file mode 100644
index 000000000000..9e7d109129ea
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn316.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2021 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: AMD
+ *
+ */
+
+#ifndef _DMUB_DCN316_H_
+#define _DMUB_DCN316_H_
+
+#include "dmub_dcn31.h"
+
+extern const struct dmub_srv_dcn31_regs dmub_srv_dcn316_regs;
+
+#endif /* _DMUB_DCN316_H_ */
diff --git a/drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c b/drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c
index 9280f2abd973..66db5e538c7f 100644
--- a/drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c
+++ b/drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c
@@ -32,6 +32,8 @@
#include "dmub_dcn302.h"
#include "dmub_dcn303.h"
#include "dmub_dcn31.h"
+#include "dmub_dcn315.h"
+#include "dmub_dcn316.h"
#include "os_types.h"
/*
* Note: the DMUB service is standalone. No additional headers should be
@@ -220,7 +222,14 @@ static bool dmub_srv_hw_setup(struct dmub_srv *dmub, enum dmub_asic asic)
case DMUB_ASIC_DCN31:
case DMUB_ASIC_DCN31B:
- dmub->regs_dcn31 = &dmub_srv_dcn31_regs;
+ case DMUB_ASIC_DCN315:
+ case DMUB_ASIC_DCN316:
+ if (asic == DMUB_ASIC_DCN315)
+ dmub->regs_dcn31 = &dmub_srv_dcn315_regs;
+ else if (asic == DMUB_ASIC_DCN316)
+ dmub->regs_dcn31 = &dmub_srv_dcn316_regs;
+ else
+ dmub->regs_dcn31 = &dmub_srv_dcn31_regs;
funcs->reset = dmub_dcn31_reset;
funcs->reset_release = dmub_dcn31_reset_release;
funcs->backdoor_load = dmub_dcn31_backdoor_load;
diff --git a/drivers/gpu/drm/amd/display/include/bios_parser_types.h b/drivers/gpu/drm/amd/display/include/bios_parser_types.h
index b8ffb216ebc4..cf4027cc3f4c 100644
--- a/drivers/gpu/drm/amd/display/include/bios_parser_types.h
+++ b/drivers/gpu/drm/amd/display/include/bios_parser_types.h
@@ -152,10 +152,8 @@ struct bp_transmitter_control {
enum signal_type signal;
enum dc_color_depth color_depth; /* not used for DCE6.0 */
enum hpd_source_id hpd_sel; /* ucHPDSel, used for DCe6.0 */
-#if defined(CONFIG_DRM_AMD_DC_DCN)
enum tx_ffe_id txffe_sel; /* used for DCN3 */
enum engine_id hpo_engine_id; /* used for DCN3 */
-#endif
struct graphics_object_id connector_obj_id;
/* symClock; in 10kHz, pixel clock, in HDMI deep color mode, it should
* be pixel clock * deep_color_ratio (in KHz)
diff --git a/drivers/gpu/drm/amd/display/include/dal_asic_id.h b/drivers/gpu/drm/amd/display/include/dal_asic_id.h
index e4a2dfacab4c..310f8779db67 100644
--- a/drivers/gpu/drm/amd/display/include/dal_asic_id.h
+++ b/drivers/gpu/drm/amd/display/include/dal_asic_id.h
@@ -212,6 +212,7 @@ enum {
#define ASICREV_IS_GREEN_SARDINE(eChipRev) ((eChipRev >= GREEN_SARDINE_A0) && (eChipRev < 0xFF))
#endif
#define DEVICE_ID_NV_13FE 0x13FE // CYAN_SKILLFISH
+#define DEVICE_ID_NV_143F 0x143F
#define FAMILY_VGH 144
#define DEVICE_ID_VGH_163F 0x163F
#define VANGOGH_A0 0x01
@@ -226,7 +227,6 @@ enum {
#endif
#define FAMILY_YELLOW_CARP 146
-
#define YELLOW_CARP_A0 0x01
#define YELLOW_CARP_B0 0x20
#define YELLOW_CARP_UNKNOWN 0xFF
@@ -235,6 +235,17 @@ enum {
#define ASICREV_IS_YELLOW_CARP(eChipRev) ((eChipRev >= YELLOW_CARP_A0) && (eChipRev < YELLOW_CARP_UNKNOWN))
#endif
+#define AMDGPU_FAMILY_GC_10_3_6 149
+#define GC_10_3_6_A0 0x01
+#define GC_10_3_6_UNKNOWN 0xFF
+
+#define ASICREV_IS_GC_10_3_6(eChipRev) ((eChipRev >= GC_10_3_6_A0) && (eChipRev < GC_10_3_6_UNKNOWN))
+
+#define AMDGPU_FAMILY_GC_10_3_7 151
+#define GC_10_3_7_A0 0x01
+#define GC_10_3_7_UNKNOWN 0xFF
+
+#define ASICREV_IS_GC_10_3_7(eChipRev) ((eChipRev >= GC_10_3_7_A0) && (eChipRev < GC_10_3_7_UNKNOWN))
/*
* ASIC chip ID
diff --git a/drivers/gpu/drm/amd/display/include/dal_types.h b/drivers/gpu/drm/amd/display/include/dal_types.h
index 012b7c61798c..bf9085fc5105 100644
--- a/drivers/gpu/drm/amd/display/include/dal_types.h
+++ b/drivers/gpu/drm/amd/display/include/dal_types.h
@@ -57,6 +57,8 @@ enum dce_version {
DCN_VERSION_3_02,
DCN_VERSION_3_03,
DCN_VERSION_3_1,
+ DCN_VERSION_3_15,
+ DCN_VERSION_3_16,
DCN_VERSION_MAX
};
diff --git a/drivers/gpu/drm/amd/display/include/ddc_service_types.h b/drivers/gpu/drm/amd/display/include/ddc_service_types.h
index a2b80514d83e..f883d87791fe 100644
--- a/drivers/gpu/drm/amd/display/include/ddc_service_types.h
+++ b/drivers/gpu/drm/amd/display/include/ddc_service_types.h
@@ -34,6 +34,9 @@
#define DP_BRANCH_DEVICE_ID_90CC24 0x90CC24
#define DP_BRANCH_DEVICE_ID_00E04C 0x00E04C
#define DP_BRANCH_DEVICE_ID_006037 0x006037
+#define DP_BRANCH_DEVICE_ID_001CF8 0x001CF8
+#define DP_BRANCH_HW_REV_10 0x10
+#define DP_BRANCH_HW_REV_20 0x20
#define DP_DEVICE_ID_38EC11 0x38EC11
enum ddc_result {
@@ -61,6 +64,7 @@ enum ddc_service_type {
struct display_sink_capability {
/* dongle type (DP converter, CV smart dongle) */
enum display_dongle_type dongle_type;
+ bool is_dongle_type_one;
/**********************************************************
capabilities going INTO SINK DEVICE (stream capabilities)
@@ -121,4 +125,7 @@ struct av_sync_data {
static const uint8_t DP_SINK_DEVICE_STR_ID_1[] = {7, 1, 8, 7, 3, 0};
static const uint8_t DP_SINK_DEVICE_STR_ID_2[] = {7, 1, 8, 7, 5, 0};
+/*MST Dock*/
+static const uint8_t SYNAPTICS_DEVICE_ID[] = "SYNA";
+
#endif /* __DAL_DDC_SERVICE_TYPES_H__ */
diff --git a/drivers/gpu/drm/amd/display/include/dpcd_defs.h b/drivers/gpu/drm/amd/display/include/dpcd_defs.h
index ffd0df1701e6..ac822181359c 100644
--- a/drivers/gpu/drm/amd/display/include/dpcd_defs.h
+++ b/drivers/gpu/drm/amd/display/include/dpcd_defs.h
@@ -26,7 +26,7 @@
#ifndef __DAL_DPCD_DEFS_H__
#define __DAL_DPCD_DEFS_H__
-#include <drm/drm_dp_helper.h>
+#include <drm/dp/drm_dp_helper.h>
#ifndef DP_SINK_HW_REVISION_START // can remove this once the define gets into linux drm_dp_helper.h
#define DP_SINK_HW_REVISION_START 0x409
#endif
@@ -144,14 +144,10 @@ enum dpcd_training_patterns {
DPCD_TRAINING_PATTERN_1,
DPCD_TRAINING_PATTERN_2,
DPCD_TRAINING_PATTERN_3,
-#if defined(CONFIG_DRM_AMD_DC_DCN)
DPCD_TRAINING_PATTERN_4 = 7,
DPCD_128b_132b_TPS1 = 1,
DPCD_128b_132b_TPS2 = 2,
DPCD_128b_132b_TPS2_CDS = 3,
-#else
- DPCD_TRAINING_PATTERN_4 = 7
-#endif
};
/* This enum is for use with PsrSinkPsrStatus.bits.sinkSelfRefreshStatus
diff --git a/drivers/gpu/drm/amd/display/include/grph_object_ctrl_defs.h b/drivers/gpu/drm/amd/display/include/grph_object_ctrl_defs.h
index dd974c428d23..bc96d0211360 100644
--- a/drivers/gpu/drm/amd/display/include/grph_object_ctrl_defs.h
+++ b/drivers/gpu/drm/amd/display/include/grph_object_ctrl_defs.h
@@ -419,28 +419,6 @@ struct integrated_info {
struct edp_info edp2_info;
};
-/**
-* Power source ids.
-*/
-enum power_source {
- POWER_SOURCE_AC = 0,
- POWER_SOURCE_DC,
- POWER_SOURCE_LIMITED_POWER,
- POWER_SOURCE_LIMITED_POWER_2,
- POWER_SOURCE_MAX
-};
-
-struct bios_event_info {
- uint32_t thermal_state;
- uint32_t backlight_level;
- enum power_source powerSource;
- bool has_thermal_state_changed;
- bool has_power_source_changed;
- bool has_forced_mode_changed;
- bool forced_mode;
- bool backlight_changed;
-};
-
/*
* DFS-bypass flag
*/
diff --git a/drivers/gpu/drm/amd/display/include/grph_object_defs.h b/drivers/gpu/drm/amd/display/include/grph_object_defs.h
index 84b299ff500a..05ba188a7c3b 100644
--- a/drivers/gpu/drm/amd/display/include/grph_object_defs.h
+++ b/drivers/gpu/drm/amd/display/include/grph_object_defs.h
@@ -140,7 +140,6 @@ enum sync_source {
SYNC_SOURCE_DUAL_GPU_PIN
};
-#if defined(CONFIG_DRM_AMD_DC_DCN)
enum tx_ffe_id {
TX_FFE0 = 0,
TX_FFE1,
@@ -150,7 +149,6 @@ enum tx_ffe_id {
TX_FFE_PreShoot_Only,
TX_FFE_No_FFE,
};
-#endif
/* connector sizes in millimeters - from BiosParserTypes.hpp */
#define CONNECTOR_SIZE_DVI 40
diff --git a/drivers/gpu/drm/amd/display/include/grph_object_id.h b/drivers/gpu/drm/amd/display/include/grph_object_id.h
index 01775417cf4b..fed1edc038d8 100644
--- a/drivers/gpu/drm/amd/display/include/grph_object_id.h
+++ b/drivers/gpu/drm/amd/display/include/grph_object_id.h
@@ -184,14 +184,12 @@ enum engine_id {
ENGINE_ID_DACA,
ENGINE_ID_DACB,
ENGINE_ID_VCE, /* wireless display pseudo-encoder */
-#if defined(CONFIG_DRM_AMD_DC_DCN)
ENGINE_ID_HPO_0,
ENGINE_ID_HPO_1,
ENGINE_ID_HPO_DP_0,
ENGINE_ID_HPO_DP_1,
ENGINE_ID_HPO_DP_2,
ENGINE_ID_HPO_DP_3,
-#endif
ENGINE_ID_VIRTUAL,
ENGINE_ID_COUNT,
diff --git a/drivers/gpu/drm/amd/display/include/link_service_types.h b/drivers/gpu/drm/amd/display/include/link_service_types.h
index 424bccd36434..447a56286dd0 100644
--- a/drivers/gpu/drm/amd/display/include/link_service_types.h
+++ b/drivers/gpu/drm/amd/display/include/link_service_types.h
@@ -74,12 +74,10 @@ enum link_training_result {
LINK_TRAINING_LINK_LOSS,
/* Abort link training (because sink unplugged) */
LINK_TRAINING_ABORT,
-#if defined(CONFIG_DRM_AMD_DC_DCN)
DP_128b_132b_LT_FAILED,
DP_128b_132b_MAX_LOOP_COUNT_REACHED,
DP_128b_132b_CHANNEL_EQ_DONE_TIMEOUT,
DP_128b_132b_CDS_DONE_TIMEOUT,
-#endif
};
enum lttpr_mode {
@@ -99,23 +97,19 @@ struct link_training_settings {
enum dc_pre_emphasis *pre_emphasis;
enum dc_post_cursor2 *post_cursor2;
bool should_set_fec_ready;
-#if defined(CONFIG_DRM_AMD_DC_DCN)
/* TODO - factor lane_settings out because it changes during LT */
union dc_dp_ffe_preset *ffe_preset;
-#endif
uint16_t cr_pattern_time;
uint16_t eq_pattern_time;
uint16_t cds_pattern_time;
enum dc_dp_training_pattern pattern_for_cr;
enum dc_dp_training_pattern pattern_for_eq;
-#if defined(CONFIG_DRM_AMD_DC_DCN)
enum dc_dp_training_pattern pattern_for_cds;
uint32_t eq_wait_time_limit;
uint8_t eq_loop_count_limit;
uint32_t cds_wait_time_limit;
-#endif
bool enhanced_framing;
enum lttpr_mode lttpr_mode;
@@ -161,7 +155,6 @@ enum dp_test_pattern {
DP_TEST_PATTERN_CP2520_2,
DP_TEST_PATTERN_HBR2_COMPLIANCE_EYE = DP_TEST_PATTERN_CP2520_2,
DP_TEST_PATTERN_CP2520_3,
-#if defined(CONFIG_DRM_AMD_DC_DCN)
DP_TEST_PATTERN_128b_132b_TPS1,
DP_TEST_PATTERN_128b_132b_TPS2,
DP_TEST_PATTERN_PRBS9,
@@ -171,20 +164,15 @@ enum dp_test_pattern {
DP_TEST_PATTERN_PRBS31,
DP_TEST_PATTERN_264BIT_CUSTOM,
DP_TEST_PATTERN_SQUARE_PULSE,
-#endif
/* Link Training Patterns */
DP_TEST_PATTERN_TRAINING_PATTERN1,
DP_TEST_PATTERN_TRAINING_PATTERN2,
DP_TEST_PATTERN_TRAINING_PATTERN3,
DP_TEST_PATTERN_TRAINING_PATTERN4,
-#if defined(CONFIG_DRM_AMD_DC_DCN)
DP_TEST_PATTERN_128b_132b_TPS1_TRAINING_MODE,
DP_TEST_PATTERN_128b_132b_TPS2_TRAINING_MODE,
DP_TEST_PATTERN_PHY_PATTERN_END = DP_TEST_PATTERN_128b_132b_TPS2_TRAINING_MODE,
-#else
- DP_TEST_PATTERN_PHY_PATTERN_END = DP_TEST_PATTERN_TRAINING_PATTERN4,
-#endif
/* link test patterns*/
DP_TEST_PATTERN_COLOR_SQUARES,
diff --git a/drivers/gpu/drm/amd/display/modules/hdcp/hdcp.h b/drivers/gpu/drm/amd/display/modules/hdcp/hdcp.h
index 399fbca8947b..8502263d2968 100644
--- a/drivers/gpu/drm/amd/display/modules/hdcp/hdcp.h
+++ b/drivers/gpu/drm/amd/display/modules/hdcp/hdcp.h
@@ -30,7 +30,7 @@
#include "hdcp_log.h"
#include <drm/drm_hdcp.h>
-#include <drm/drm_dp_helper.h>
+#include <drm/dp/drm_dp_helper.h>
enum mod_hdcp_trans_input_result {
UNKNOWN = 0,
diff --git a/drivers/gpu/drm/amd/display/modules/inc/mod_info_packet.h b/drivers/gpu/drm/amd/display/modules/inc/mod_info_packet.h
index 1ab813b4fd14..1d8b746b02f2 100644
--- a/drivers/gpu/drm/amd/display/modules/inc/mod_info_packet.h
+++ b/drivers/gpu/drm/amd/display/modules/inc/mod_info_packet.h
@@ -34,7 +34,8 @@ struct dc_info_packet;
struct mod_vrr_params;
void mod_build_vsc_infopacket(const struct dc_stream_state *stream,
- struct dc_info_packet *info_packet);
+ struct dc_info_packet *info_packet,
+ enum dc_color_space cs);
void mod_build_hf_vsif_infopacket(const struct dc_stream_state *stream,
struct dc_info_packet *info_packet);
diff --git a/drivers/gpu/drm/amd/display/modules/info_packet/info_packet.c b/drivers/gpu/drm/amd/display/modules/info_packet/info_packet.c
index 57f198de5e2c..b691aa45e84f 100644
--- a/drivers/gpu/drm/amd/display/modules/info_packet/info_packet.c
+++ b/drivers/gpu/drm/amd/display/modules/info_packet/info_packet.c
@@ -130,7 +130,8 @@ enum ColorimetryYCCDP {
};
void mod_build_vsc_infopacket(const struct dc_stream_state *stream,
- struct dc_info_packet *info_packet)
+ struct dc_info_packet *info_packet,
+ enum dc_color_space cs)
{
unsigned int vsc_packet_revision = vsc_packet_undefined;
unsigned int i;
@@ -331,13 +332,13 @@ void mod_build_vsc_infopacket(const struct dc_stream_state *stream,
/* Set Colorimetry format based on pixel encoding */
switch (stream->timing.pixel_encoding) {
case PIXEL_ENCODING_RGB:
- if ((stream->output_color_space == COLOR_SPACE_SRGB) ||
- (stream->output_color_space == COLOR_SPACE_SRGB_LIMITED))
+ if ((cs == COLOR_SPACE_SRGB) ||
+ (cs == COLOR_SPACE_SRGB_LIMITED))
colorimetryFormat = ColorimetryRGB_DP_sRGB;
- else if (stream->output_color_space == COLOR_SPACE_ADOBERGB)
+ else if (cs == COLOR_SPACE_ADOBERGB)
colorimetryFormat = ColorimetryRGB_DP_AdobeRGB;
- else if ((stream->output_color_space == COLOR_SPACE_2020_RGB_FULLRANGE) ||
- (stream->output_color_space == COLOR_SPACE_2020_RGB_LIMITEDRANGE))
+ else if ((cs == COLOR_SPACE_2020_RGB_FULLRANGE) ||
+ (cs == COLOR_SPACE_2020_RGB_LIMITEDRANGE))
colorimetryFormat = ColorimetryRGB_DP_ITU_R_BT2020RGB;
break;
@@ -347,13 +348,13 @@ void mod_build_vsc_infopacket(const struct dc_stream_state *stream,
/* Note: xvYCC probably not supported correctly here on DP since colorspace translation
* loses distinction between BT601 vs xvYCC601 in translation
*/
- if (stream->output_color_space == COLOR_SPACE_YCBCR601)
+ if (cs == COLOR_SPACE_YCBCR601)
colorimetryFormat = ColorimetryYCC_DP_ITU601;
- else if (stream->output_color_space == COLOR_SPACE_YCBCR709)
+ else if (cs == COLOR_SPACE_YCBCR709)
colorimetryFormat = ColorimetryYCC_DP_ITU709;
- else if (stream->output_color_space == COLOR_SPACE_ADOBERGB)
+ else if (cs == COLOR_SPACE_ADOBERGB)
colorimetryFormat = ColorimetryYCC_DP_AdobeYCC;
- else if (stream->output_color_space == COLOR_SPACE_2020_YCBCR)
+ else if (cs == COLOR_SPACE_2020_YCBCR)
colorimetryFormat = ColorimetryYCC_DP_ITU2020YCbCr;
break;
@@ -391,8 +392,8 @@ void mod_build_vsc_infopacket(const struct dc_stream_state *stream,
}
/* all YCbCr are always limited range */
- if ((stream->output_color_space == COLOR_SPACE_SRGB_LIMITED) ||
- (stream->output_color_space == COLOR_SPACE_2020_RGB_LIMITEDRANGE) ||
+ if ((cs == COLOR_SPACE_SRGB_LIMITED) ||
+ (cs == COLOR_SPACE_2020_RGB_LIMITEDRANGE) ||
(pixelEncoding != 0x0)) {
info_packet->sb[17] |= 0x80; /* DB17 bit 7 set to 1 for CEA timing. */
}
diff --git a/drivers/gpu/drm/amd/include/amd_shared.h b/drivers/gpu/drm/amd/include/amd_shared.h
index f57a1478f0fe..fe4e585781bb 100644
--- a/drivers/gpu/drm/amd/include/amd_shared.h
+++ b/drivers/gpu/drm/amd/include/amd_shared.h
@@ -83,6 +83,7 @@ enum amd_apu_flags {
* @AMD_IP_BLOCK_TYPE_VCN: Video Core/Codec Next
* @AMD_IP_BLOCK_TYPE_MES: Micro-Engine Scheduler
* @AMD_IP_BLOCK_TYPE_JPEG: JPEG Engine
+* @AMD_IP_BLOCK_TYPE_NUM: Total number of IP block types
*/
enum amd_ip_block_type {
AMD_IP_BLOCK_TYPE_COMMON,
@@ -268,7 +269,6 @@ enum amd_dpm_forced_level;
* @set_clockgating_state: enable/disable cg for the IP block
* @set_powergating_state: enable/disable pg for the IP block
* @get_clockgating_state: get current clockgating status
- * @enable_umd_pstate: enable UMD powerstate
*
* These hooks provide an interface for controlling the operational state
* of IP blocks. After acquiring a list of IP blocks for the GPU in use,
@@ -299,7 +299,6 @@ struct amd_ip_funcs {
int (*set_powergating_state)(void *handle,
enum amd_powergating_state state);
void (*get_clockgating_state)(void *handle, u32 *flags);
- int (*enable_umd_pstate)(void *handle, enum amd_dpm_forced_level *level);
};
diff --git a/drivers/gpu/drm/amd/include/asic_reg/dcn/dcn_3_1_5_offset.h b/drivers/gpu/drm/amd/include/asic_reg/dcn/dcn_3_1_5_offset.h
new file mode 100644
index 000000000000..50c34d88c17c
--- /dev/null
+++ b/drivers/gpu/drm/amd/include/asic_reg/dcn/dcn_3_1_5_offset.h
@@ -0,0 +1,15191 @@
+/*
+ * Copyright (C) 2022 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#ifndef _dcn_3_1_5_OFFSET_HEADER
+#define _dcn_3_1_5_OFFSET_HEADER
+
+
+
+// addressBlock: dce_dc_dccg_dccg_dfs_dispdec
+// base address: 0x0
+#define regDENTIST_DISPCLK_CNTL 0x0064
+#define regDENTIST_DISPCLK_CNTL_BASE_IDX 1
+
+
+// addressBlock: dce_dc_dccg_dccg_dispdec
+// base address: 0x0
+#define regPHYPLLA_PIXCLK_RESYNC_CNTL 0x0040
+#define regPHYPLLA_PIXCLK_RESYNC_CNTL_BASE_IDX 1
+#define regPHYPLLB_PIXCLK_RESYNC_CNTL 0x0041
+#define regPHYPLLB_PIXCLK_RESYNC_CNTL_BASE_IDX 1
+#define regPHYPLLC_PIXCLK_RESYNC_CNTL 0x0042
+#define regPHYPLLC_PIXCLK_RESYNC_CNTL_BASE_IDX 1
+#define regPHYPLLD_PIXCLK_RESYNC_CNTL 0x0043
+#define regPHYPLLD_PIXCLK_RESYNC_CNTL_BASE_IDX 1
+#define regDP_DTO_DBUF_EN 0x0044
+#define regDP_DTO_DBUF_EN_BASE_IDX 1
+#define regDPREFCLK_CGTT_BLK_CTRL_REG 0x0048
+#define regDPREFCLK_CGTT_BLK_CTRL_REG_BASE_IDX 1
+#define regDCCG_GATE_DISABLE_CNTL4 0x0049
+#define regDCCG_GATE_DISABLE_CNTL4_BASE_IDX 1
+#define regDPSTREAMCLK_CNTL 0x004a
+#define regDPSTREAMCLK_CNTL_BASE_IDX 1
+#define regREFCLK_CGTT_BLK_CTRL_REG 0x004b
+#define regREFCLK_CGTT_BLK_CTRL_REG_BASE_IDX 1
+#define regPHYPLLE_PIXCLK_RESYNC_CNTL 0x004c
+#define regPHYPLLE_PIXCLK_RESYNC_CNTL_BASE_IDX 1
+#define regDCCG_PERFMON_CNTL2 0x004e
+#define regDCCG_PERFMON_CNTL2_BASE_IDX 1
+#define regDCCG_DS_DTO_INCR 0x0053
+#define regDCCG_DS_DTO_INCR_BASE_IDX 1
+#define regDCCG_DS_DTO_MODULO 0x0054
+#define regDCCG_DS_DTO_MODULO_BASE_IDX 1
+#define regDCCG_DS_CNTL 0x0055
+#define regDCCG_DS_CNTL_BASE_IDX 1
+#define regDCCG_DS_HW_CAL_INTERVAL 0x0056
+#define regDCCG_DS_HW_CAL_INTERVAL_BASE_IDX 1
+#define regDPREFCLK_CNTL 0x0058
+#define regDPREFCLK_CNTL_BASE_IDX 1
+#define regDCE_VERSION 0x005e
+#define regDCE_VERSION_BASE_IDX 1
+#define regDCCG_GTC_CNTL 0x0060
+#define regDCCG_GTC_CNTL_BASE_IDX 1
+#define regDCCG_GTC_DTO_INCR 0x0061
+#define regDCCG_GTC_DTO_INCR_BASE_IDX 1
+#define regDCCG_GTC_DTO_MODULO 0x0062
+#define regDCCG_GTC_DTO_MODULO_BASE_IDX 1
+#define regDCCG_GTC_CURRENT 0x0063
+#define regDCCG_GTC_CURRENT_BASE_IDX 1
+#define regSYMCLK32_SE_CNTL 0x0065
+#define regSYMCLK32_SE_CNTL_BASE_IDX 1
+#define regSYMCLK32_LE_CNTL 0x0066
+#define regSYMCLK32_LE_CNTL_BASE_IDX 1
+#define regDSCCLK0_DTO_PARAM 0x006c
+#define regDSCCLK0_DTO_PARAM_BASE_IDX 1
+#define regDSCCLK1_DTO_PARAM 0x006d
+#define regDSCCLK1_DTO_PARAM_BASE_IDX 1
+#define regDSCCLK2_DTO_PARAM 0x006e
+#define regDSCCLK2_DTO_PARAM_BASE_IDX 1
+#define regMILLISECOND_TIME_BASE_DIV 0x0070
+#define regMILLISECOND_TIME_BASE_DIV_BASE_IDX 1
+#define regDISPCLK_FREQ_CHANGE_CNTL 0x0071
+#define regDISPCLK_FREQ_CHANGE_CNTL_BASE_IDX 1
+#define regDC_MEM_GLOBAL_PWR_REQ_CNTL 0x0072
+#define regDC_MEM_GLOBAL_PWR_REQ_CNTL_BASE_IDX 1
+#define regDCCG_PERFMON_CNTL 0x0073
+#define regDCCG_PERFMON_CNTL_BASE_IDX 1
+#define regDCCG_GATE_DISABLE_CNTL 0x0074
+#define regDCCG_GATE_DISABLE_CNTL_BASE_IDX 1
+#define regDISPCLK_CGTT_BLK_CTRL_REG 0x0075
+#define regDISPCLK_CGTT_BLK_CTRL_REG_BASE_IDX 1
+#define regSOCCLK_CGTT_BLK_CTRL_REG 0x0076
+#define regSOCCLK_CGTT_BLK_CTRL_REG_BASE_IDX 1
+#define regDCCG_CAC_STATUS 0x0077
+#define regDCCG_CAC_STATUS_BASE_IDX 1
+#define regMICROSECOND_TIME_BASE_DIV 0x007b
+#define regMICROSECOND_TIME_BASE_DIV_BASE_IDX 1
+#define regDCCG_GATE_DISABLE_CNTL2 0x007c
+#define regDCCG_GATE_DISABLE_CNTL2_BASE_IDX 1
+#define regSYMCLK_CGTT_BLK_CTRL_REG 0x007d
+#define regSYMCLK_CGTT_BLK_CTRL_REG_BASE_IDX 1
+#define regDCCG_DISP_CNTL_REG 0x007f
+#define regDCCG_DISP_CNTL_REG_BASE_IDX 1
+#define regOTG0_PIXEL_RATE_CNTL 0x0080
+#define regOTG0_PIXEL_RATE_CNTL_BASE_IDX 1
+#define regDP_DTO0_PHASE 0x0081
+#define regDP_DTO0_PHASE_BASE_IDX 1
+#define regDP_DTO0_MODULO 0x0082
+#define regDP_DTO0_MODULO_BASE_IDX 1
+#define regOTG0_PHYPLL_PIXEL_RATE_CNTL 0x0083
+#define regOTG0_PHYPLL_PIXEL_RATE_CNTL_BASE_IDX 1
+#define regOTG1_PIXEL_RATE_CNTL 0x0084
+#define regOTG1_PIXEL_RATE_CNTL_BASE_IDX 1
+#define regDP_DTO1_PHASE 0x0085
+#define regDP_DTO1_PHASE_BASE_IDX 1
+#define regDP_DTO1_MODULO 0x0086
+#define regDP_DTO1_MODULO_BASE_IDX 1
+#define regOTG1_PHYPLL_PIXEL_RATE_CNTL 0x0087
+#define regOTG1_PHYPLL_PIXEL_RATE_CNTL_BASE_IDX 1
+#define regOTG2_PIXEL_RATE_CNTL 0x0088
+#define regOTG2_PIXEL_RATE_CNTL_BASE_IDX 1
+#define regDP_DTO2_PHASE 0x0089
+#define regDP_DTO2_PHASE_BASE_IDX 1
+#define regDP_DTO2_MODULO 0x008a
+#define regDP_DTO2_MODULO_BASE_IDX 1
+#define regOTG2_PHYPLL_PIXEL_RATE_CNTL 0x008b
+#define regOTG2_PHYPLL_PIXEL_RATE_CNTL_BASE_IDX 1
+#define regOTG3_PIXEL_RATE_CNTL 0x008c
+#define regOTG3_PIXEL_RATE_CNTL_BASE_IDX 1
+#define regDP_DTO3_PHASE 0x008d
+#define regDP_DTO3_PHASE_BASE_IDX 1
+#define regDP_DTO3_MODULO 0x008e
+#define regDP_DTO3_MODULO_BASE_IDX 1
+#define regOTG3_PHYPLL_PIXEL_RATE_CNTL 0x008f
+#define regOTG3_PHYPLL_PIXEL_RATE_CNTL_BASE_IDX 1
+#define regDPPCLK_CGTT_BLK_CTRL_REG 0x0098
+#define regDPPCLK_CGTT_BLK_CTRL_REG_BASE_IDX 1
+#define regDPPCLK0_DTO_PARAM 0x0099
+#define regDPPCLK0_DTO_PARAM_BASE_IDX 1
+#define regDPPCLK1_DTO_PARAM 0x009a
+#define regDPPCLK1_DTO_PARAM_BASE_IDX 1
+#define regDPPCLK2_DTO_PARAM 0x009b
+#define regDPPCLK2_DTO_PARAM_BASE_IDX 1
+#define regDPPCLK3_DTO_PARAM 0x009c
+#define regDPPCLK3_DTO_PARAM_BASE_IDX 1
+#define regDCCG_CAC_STATUS2 0x009f
+#define regDCCG_CAC_STATUS2_BASE_IDX 1
+#define regSYMCLKA_CLOCK_ENABLE 0x00a0
+#define regSYMCLKA_CLOCK_ENABLE_BASE_IDX 1
+#define regSYMCLKB_CLOCK_ENABLE 0x00a1
+#define regSYMCLKB_CLOCK_ENABLE_BASE_IDX 1
+#define regSYMCLKC_CLOCK_ENABLE 0x00a2
+#define regSYMCLKC_CLOCK_ENABLE_BASE_IDX 1
+#define regSYMCLKD_CLOCK_ENABLE 0x00a3
+#define regSYMCLKD_CLOCK_ENABLE_BASE_IDX 1
+#define regSYMCLKE_CLOCK_ENABLE 0x00a4
+#define regSYMCLKE_CLOCK_ENABLE_BASE_IDX 1
+#define regDCCG_SOFT_RESET 0x00a6
+#define regDCCG_SOFT_RESET_BASE_IDX 1
+#define regDSCCLK_DTO_CTRL 0x00a7
+#define regDSCCLK_DTO_CTRL_BASE_IDX 1
+#define regDCCG_AUDIO_DTO_SOURCE 0x00ab
+#define regDCCG_AUDIO_DTO_SOURCE_BASE_IDX 1
+#define regDCCG_AUDIO_DTO0_PHASE 0x00ac
+#define regDCCG_AUDIO_DTO0_PHASE_BASE_IDX 1
+#define regDCCG_AUDIO_DTO0_MODULE 0x00ad
+#define regDCCG_AUDIO_DTO0_MODULE_BASE_IDX 1
+#define regDCCG_AUDIO_DTO1_PHASE 0x00ae
+#define regDCCG_AUDIO_DTO1_PHASE_BASE_IDX 1
+#define regDCCG_AUDIO_DTO1_MODULE 0x00af
+#define regDCCG_AUDIO_DTO1_MODULE_BASE_IDX 1
+#define regDCCG_VSYNC_OTG0_LATCH_VALUE 0x00b0
+#define regDCCG_VSYNC_OTG0_LATCH_VALUE_BASE_IDX 1
+#define regDCCG_VSYNC_OTG1_LATCH_VALUE 0x00b1
+#define regDCCG_VSYNC_OTG1_LATCH_VALUE_BASE_IDX 1
+#define regDCCG_VSYNC_OTG2_LATCH_VALUE 0x00b2
+#define regDCCG_VSYNC_OTG2_LATCH_VALUE_BASE_IDX 1
+#define regDCCG_VSYNC_OTG3_LATCH_VALUE 0x00b3
+#define regDCCG_VSYNC_OTG3_LATCH_VALUE_BASE_IDX 1
+#define regDCCG_VSYNC_OTG4_LATCH_VALUE 0x00b4
+#define regDCCG_VSYNC_OTG4_LATCH_VALUE_BASE_IDX 1
+#define regDCCG_VSYNC_OTG5_LATCH_VALUE 0x00b5
+#define regDCCG_VSYNC_OTG5_LATCH_VALUE_BASE_IDX 1
+#define regDPPCLK_DTO_CTRL 0x00b6
+#define regDPPCLK_DTO_CTRL_BASE_IDX 1
+#define regDCCG_VSYNC_CNT_CTRL 0x00b8
+#define regDCCG_VSYNC_CNT_CTRL_BASE_IDX 1
+#define regDCCG_VSYNC_CNT_INT_CTRL 0x00b9
+#define regDCCG_VSYNC_CNT_INT_CTRL_BASE_IDX 1
+#define regFORCE_SYMCLK_DISABLE 0x00ba
+#define regFORCE_SYMCLK_DISABLE_BASE_IDX 1
+#define regDCCG_TEST_CLK_SEL 0x00be
+#define regDCCG_TEST_CLK_SEL_BASE_IDX 1
+#define regDTBCLK_DTO0_PHASE 0x0018
+#define regDTBCLK_DTO0_PHASE_BASE_IDX 2
+#define regDTBCLK_DTO1_PHASE 0x0019
+#define regDTBCLK_DTO1_PHASE_BASE_IDX 2
+#define regDTBCLK_DTO2_PHASE 0x001a
+#define regDTBCLK_DTO2_PHASE_BASE_IDX 2
+#define regDTBCLK_DTO3_PHASE 0x001b
+#define regDTBCLK_DTO3_PHASE_BASE_IDX 2
+#define regDTBCLK_DTO0_MODULO 0x001f
+#define regDTBCLK_DTO0_MODULO_BASE_IDX 2
+#define regDTBCLK_DTO1_MODULO 0x0020
+#define regDTBCLK_DTO1_MODULO_BASE_IDX 2
+#define regDTBCLK_DTO2_MODULO 0x0021
+#define regDTBCLK_DTO2_MODULO_BASE_IDX 2
+#define regDTBCLK_DTO3_MODULO 0x0022
+#define regDTBCLK_DTO3_MODULO_BASE_IDX 2
+#define regPHYASYMCLK_CLOCK_CNTL 0x0052
+#define regPHYASYMCLK_CLOCK_CNTL_BASE_IDX 2
+#define regPHYBSYMCLK_CLOCK_CNTL 0x0053
+#define regPHYBSYMCLK_CLOCK_CNTL_BASE_IDX 2
+#define regPHYCSYMCLK_CLOCK_CNTL 0x0054
+#define regPHYCSYMCLK_CLOCK_CNTL_BASE_IDX 2
+#define regPHYDSYMCLK_CLOCK_CNTL 0x0055
+#define regPHYDSYMCLK_CLOCK_CNTL_BASE_IDX 2
+#define regPHYESYMCLK_CLOCK_CNTL 0x0056
+#define regPHYESYMCLK_CLOCK_CNTL_BASE_IDX 2
+#define regDCCG_GATE_DISABLE_CNTL3 0x005a
+#define regDCCG_GATE_DISABLE_CNTL3_BASE_IDX 2
+#define regHDMISTREAMCLK0_DTO_PARAM 0x005b
+#define regHDMISTREAMCLK0_DTO_PARAM_BASE_IDX 2
+#define regDCCG_AUDIO_DTBCLK_DTO_PHASE 0x0061
+#define regDCCG_AUDIO_DTBCLK_DTO_PHASE_BASE_IDX 2
+#define regDCCG_AUDIO_DTBCLK_DTO_MODULO 0x0062
+#define regDCCG_AUDIO_DTBCLK_DTO_MODULO_BASE_IDX 2
+#define regDTBCLK_DTO_DBUF_EN 0x0063
+#define regDTBCLK_DTO_DBUF_EN_BASE_IDX 2
+
+
+// addressBlock: dce_dc_dccg_dccg_dcperfmon0_dc_perfmon_dispdec
+// base address: 0x0
+#define regDC_PERFMON0_PERFCOUNTER_CNTL 0x0000
+#define regDC_PERFMON0_PERFCOUNTER_CNTL_BASE_IDX 2
+#define regDC_PERFMON0_PERFCOUNTER_CNTL2 0x0001
+#define regDC_PERFMON0_PERFCOUNTER_CNTL2_BASE_IDX 2
+#define regDC_PERFMON0_PERFCOUNTER_STATE 0x0002
+#define regDC_PERFMON0_PERFCOUNTER_STATE_BASE_IDX 2
+#define regDC_PERFMON0_PERFMON_CNTL 0x0003
+#define regDC_PERFMON0_PERFMON_CNTL_BASE_IDX 2
+#define regDC_PERFMON0_PERFMON_CNTL2 0x0004
+#define regDC_PERFMON0_PERFMON_CNTL2_BASE_IDX 2
+#define regDC_PERFMON0_PERFMON_CVALUE_INT_MISC 0x0005
+#define regDC_PERFMON0_PERFMON_CVALUE_INT_MISC_BASE_IDX 2
+#define regDC_PERFMON0_PERFMON_CVALUE_LOW 0x0006
+#define regDC_PERFMON0_PERFMON_CVALUE_LOW_BASE_IDX 2
+#define regDC_PERFMON0_PERFMON_HI 0x0007
+#define regDC_PERFMON0_PERFMON_HI_BASE_IDX 2
+#define regDC_PERFMON0_PERFMON_LOW 0x0008
+#define regDC_PERFMON0_PERFMON_LOW_BASE_IDX 2
+
+
+// addressBlock: dce_dc_dccg_dccg_dcperfmon1_dc_perfmon_dispdec
+// base address: 0x30
+#define regDC_PERFMON1_PERFCOUNTER_CNTL 0x000c
+#define regDC_PERFMON1_PERFCOUNTER_CNTL_BASE_IDX 2
+#define regDC_PERFMON1_PERFCOUNTER_CNTL2 0x000d
+#define regDC_PERFMON1_PERFCOUNTER_CNTL2_BASE_IDX 2
+#define regDC_PERFMON1_PERFCOUNTER_STATE 0x000e
+#define regDC_PERFMON1_PERFCOUNTER_STATE_BASE_IDX 2
+#define regDC_PERFMON1_PERFMON_CNTL 0x000f
+#define regDC_PERFMON1_PERFMON_CNTL_BASE_IDX 2
+#define regDC_PERFMON1_PERFMON_CNTL2 0x0010
+#define regDC_PERFMON1_PERFMON_CNTL2_BASE_IDX 2
+#define regDC_PERFMON1_PERFMON_CVALUE_INT_MISC 0x0011
+#define regDC_PERFMON1_PERFMON_CVALUE_INT_MISC_BASE_IDX 2
+#define regDC_PERFMON1_PERFMON_CVALUE_LOW 0x0012
+#define regDC_PERFMON1_PERFMON_CVALUE_LOW_BASE_IDX 2
+#define regDC_PERFMON1_PERFMON_HI 0x0013
+#define regDC_PERFMON1_PERFMON_HI_BASE_IDX 2
+#define regDC_PERFMON1_PERFMON_LOW 0x0014
+#define regDC_PERFMON1_PERFMON_LOW_BASE_IDX 2
+
+
+// addressBlock: dce_dc_dmu_dmcu_dispdec
+// base address: 0x0
+#define regDMCU_CTRL 0x00da
+#define regDMCU_CTRL_BASE_IDX 2
+#define regDMCU_STATUS 0x00db
+#define regDMCU_STATUS_BASE_IDX 2
+#define regDMCU_PC_START_ADDR 0x00dc
+#define regDMCU_PC_START_ADDR_BASE_IDX 2
+#define regDMCU_FW_START_ADDR 0x00dd
+#define regDMCU_FW_START_ADDR_BASE_IDX 2
+#define regDMCU_FW_END_ADDR 0x00de
+#define regDMCU_FW_END_ADDR_BASE_IDX 2
+#define regDMCU_FW_ISR_START_ADDR 0x00df
+#define regDMCU_FW_ISR_START_ADDR_BASE_IDX 2
+#define regDMCU_FW_CS_HI 0x00e0
+#define regDMCU_FW_CS_HI_BASE_IDX 2
+#define regDMCU_FW_CS_LO 0x00e1
+#define regDMCU_FW_CS_LO_BASE_IDX 2
+#define regDMCU_RAM_ACCESS_CTRL 0x00e2
+#define regDMCU_RAM_ACCESS_CTRL_BASE_IDX 2
+#define regDMCU_ERAM_WR_CTRL 0x00e3
+#define regDMCU_ERAM_WR_CTRL_BASE_IDX 2
+#define regDMCU_ERAM_WR_DATA 0x00e4
+#define regDMCU_ERAM_WR_DATA_BASE_IDX 2
+#define regDMCU_ERAM_RD_CTRL 0x00e5
+#define regDMCU_ERAM_RD_CTRL_BASE_IDX 2
+#define regDMCU_ERAM_RD_DATA 0x00e6
+#define regDMCU_ERAM_RD_DATA_BASE_IDX 2
+#define regDMCU_IRAM_WR_CTRL 0x00e7
+#define regDMCU_IRAM_WR_CTRL_BASE_IDX 2
+#define regDMCU_IRAM_WR_DATA 0x00e8
+#define regDMCU_IRAM_WR_DATA_BASE_IDX 2
+#define regDMCU_IRAM_RD_CTRL 0x00e9
+#define regDMCU_IRAM_RD_CTRL_BASE_IDX 2
+#define regDMCU_IRAM_RD_DATA 0x00ea
+#define regDMCU_IRAM_RD_DATA_BASE_IDX 2
+#define regDMCU_EVENT_TRIGGER 0x00eb
+#define regDMCU_EVENT_TRIGGER_BASE_IDX 2
+#define regDMCU_UC_INTERNAL_INT_STATUS 0x00ec
+#define regDMCU_UC_INTERNAL_INT_STATUS_BASE_IDX 2
+#define regDMCU_SS_INTERRUPT_CNTL_STATUS 0x00ed
+#define regDMCU_SS_INTERRUPT_CNTL_STATUS_BASE_IDX 2
+#define regDMCU_INTERRUPT_TO_HOST_EN_MASK 0x00f0
+#define regDMCU_INTERRUPT_TO_HOST_EN_MASK_BASE_IDX 2
+#define regDMCU_INTERRUPT_TO_UC_EN_MASK 0x00f1
+#define regDMCU_INTERRUPT_TO_UC_EN_MASK_BASE_IDX 2
+#define regDMCU_INTERRUPT_TO_UC_EN_MASK_1 0x00f2
+#define regDMCU_INTERRUPT_TO_UC_EN_MASK_1_BASE_IDX 2
+#define regDMCU_INTERRUPT_TO_UC_XIRQ_IRQ_SEL 0x00f3
+#define regDMCU_INTERRUPT_TO_UC_XIRQ_IRQ_SEL_BASE_IDX 2
+#define regDMCU_INTERRUPT_TO_UC_XIRQ_IRQ_SEL_1 0x00f4
+#define regDMCU_INTERRUPT_TO_UC_XIRQ_IRQ_SEL_1_BASE_IDX 2
+#define regDC_DMCU_SCRATCH 0x00f5
+#define regDC_DMCU_SCRATCH_BASE_IDX 2
+#define regDMCU_INT_CNT 0x00f6
+#define regDMCU_INT_CNT_BASE_IDX 2
+#define regDMCU_FW_CHECKSUM_SMPL_BYTE_POS 0x00f7
+#define regDMCU_FW_CHECKSUM_SMPL_BYTE_POS_BASE_IDX 2
+#define regDMCU_UC_CLK_GATING_CNTL 0x00f8
+#define regDMCU_UC_CLK_GATING_CNTL_BASE_IDX 2
+#define regMASTER_COMM_DATA_REG1 0x00f9
+#define regMASTER_COMM_DATA_REG1_BASE_IDX 2
+#define regMASTER_COMM_DATA_REG2 0x00fa
+#define regMASTER_COMM_DATA_REG2_BASE_IDX 2
+#define regMASTER_COMM_DATA_REG3 0x00fb
+#define regMASTER_COMM_DATA_REG3_BASE_IDX 2
+#define regMASTER_COMM_CMD_REG 0x00fc
+#define regMASTER_COMM_CMD_REG_BASE_IDX 2
+#define regMASTER_COMM_CNTL_REG 0x00fd
+#define regMASTER_COMM_CNTL_REG_BASE_IDX 2
+#define regSLAVE_COMM_DATA_REG1 0x00fe
+#define regSLAVE_COMM_DATA_REG1_BASE_IDX 2
+#define regSLAVE_COMM_DATA_REG2 0x00ff
+#define regSLAVE_COMM_DATA_REG2_BASE_IDX 2
+#define regSLAVE_COMM_DATA_REG3 0x0100
+#define regSLAVE_COMM_DATA_REG3_BASE_IDX 2
+#define regSLAVE_COMM_CMD_REG 0x0101
+#define regSLAVE_COMM_CMD_REG_BASE_IDX 2
+#define regSLAVE_COMM_CNTL_REG 0x0102
+#define regSLAVE_COMM_CNTL_REG_BASE_IDX 2
+#define regDMCU_PERFMON_INTERRUPT_TO_UC_EN_MASK1 0x010a
+#define regDMCU_PERFMON_INTERRUPT_TO_UC_EN_MASK1_BASE_IDX 2
+#define regDMCU_PERFMON_INTERRUPT_TO_UC_EN_MASK2 0x010b
+#define regDMCU_PERFMON_INTERRUPT_TO_UC_EN_MASK2_BASE_IDX 2
+#define regDMCU_PERFMON_INTERRUPT_TO_UC_EN_MASK3 0x010c
+#define regDMCU_PERFMON_INTERRUPT_TO_UC_EN_MASK3_BASE_IDX 2
+#define regDMCU_PERFMON_INTERRUPT_TO_UC_EN_MASK4 0x010d
+#define regDMCU_PERFMON_INTERRUPT_TO_UC_EN_MASK4_BASE_IDX 2
+#define regDMCU_PERFMON_INTERRUPT_TO_UC_EN_MASK5 0x010e
+#define regDMCU_PERFMON_INTERRUPT_TO_UC_EN_MASK5_BASE_IDX 2
+#define regDMCU_PERFMON_INTERRUPT_TO_UC_XIRQ_IRQ_SEL1 0x010f
+#define regDMCU_PERFMON_INTERRUPT_TO_UC_XIRQ_IRQ_SEL1_BASE_IDX 2
+#define regDMCU_PERFMON_INTERRUPT_TO_UC_XIRQ_IRQ_SEL2 0x0110
+#define regDMCU_PERFMON_INTERRUPT_TO_UC_XIRQ_IRQ_SEL2_BASE_IDX 2
+#define regDMCU_PERFMON_INTERRUPT_TO_UC_XIRQ_IRQ_SEL3 0x0111
+#define regDMCU_PERFMON_INTERRUPT_TO_UC_XIRQ_IRQ_SEL3_BASE_IDX 2
+#define regDMCU_PERFMON_INTERRUPT_TO_UC_XIRQ_IRQ_SEL4 0x0112
+#define regDMCU_PERFMON_INTERRUPT_TO_UC_XIRQ_IRQ_SEL4_BASE_IDX 2
+#define regDMCU_PERFMON_INTERRUPT_TO_UC_XIRQ_IRQ_SEL5 0x0113
+#define regDMCU_PERFMON_INTERRUPT_TO_UC_XIRQ_IRQ_SEL5_BASE_IDX 2
+#define regDMCU_DPRX_INTERRUPT_TO_UC_EN_MASK1 0x0115
+#define regDMCU_DPRX_INTERRUPT_TO_UC_EN_MASK1_BASE_IDX 2
+#define regDMCU_DPRX_INTERRUPT_TO_UC_XIRQ_IRQ_SEL1 0x0116
+#define regDMCU_DPRX_INTERRUPT_TO_UC_XIRQ_IRQ_SEL1_BASE_IDX 2
+#define regDMCU_INTERRUPT_TO_UC_EN_MASK_CONTINUE 0x011a
+#define regDMCU_INTERRUPT_TO_UC_EN_MASK_CONTINUE_BASE_IDX 2
+#define regDMCU_INTERRUPT_TO_UC_XIRQ_IRQ_SEL_CONTINUE 0x011b
+#define regDMCU_INTERRUPT_TO_UC_XIRQ_IRQ_SEL_CONTINUE_BASE_IDX 2
+#define regDMCU_INT_CNT_CONTINUE 0x011c
+#define regDMCU_INT_CNT_CONTINUE_BASE_IDX 2
+#define regDMCU_INTERRUPT_TO_UC_XIRQ_IRQ_SEL_CONT2 0x011d
+#define regDMCU_INTERRUPT_TO_UC_XIRQ_IRQ_SEL_CONT2_BASE_IDX 2
+#define regDMCU_INTERRUPT_TO_UC_EN_MASK_2 0x011f
+#define regDMCU_INTERRUPT_TO_UC_EN_MASK_2_BASE_IDX 2
+#define regDMCU_INT_CNT_CONT2 0x0120
+#define regDMCU_INT_CNT_CONT2_BASE_IDX 2
+#define regDMCU_INT_CNT_CONT3 0x0121
+#define regDMCU_INT_CNT_CONT3_BASE_IDX 2
+
+
+// addressBlock: dce_dc_dmu_fgsec_dispdec
+// base address: 0x0
+#define regDMCUB_RBBMIF_SEC_CNTL 0x017a
+#define regDMCUB_RBBMIF_SEC_CNTL_BASE_IDX 2
+
+
+// addressBlock: dce_dc_dmu_rbbmif_dispdec
+// base address: 0x0
+#define regRBBMIF_TIMEOUT 0x017f
+#define regRBBMIF_TIMEOUT_BASE_IDX 2
+#define regRBBMIF_STATUS 0x0180
+#define regRBBMIF_STATUS_BASE_IDX 2
+#define regRBBMIF_STATUS_2 0x0181
+#define regRBBMIF_STATUS_2_BASE_IDX 2
+#define regRBBMIF_INT_STATUS 0x0182
+#define regRBBMIF_INT_STATUS_BASE_IDX 2
+#define regRBBMIF_TIMEOUT_DIS 0x0183
+#define regRBBMIF_TIMEOUT_DIS_BASE_IDX 2
+#define regRBBMIF_TIMEOUT_DIS_2 0x0184
+#define regRBBMIF_TIMEOUT_DIS_2_BASE_IDX 2
+#define regRBBMIF_STATUS_FLAG 0x0185
+#define regRBBMIF_STATUS_FLAG_BASE_IDX 2
+
+
+// addressBlock: dce_dc_dmu_dmu_dcperfmon_dc_perfmon_dispdec
+// base address: 0x2f8
+#define regDC_PERFMON2_PERFCOUNTER_CNTL 0x00be
+#define regDC_PERFMON2_PERFCOUNTER_CNTL_BASE_IDX 2
+#define regDC_PERFMON2_PERFCOUNTER_CNTL2 0x00bf
+#define regDC_PERFMON2_PERFCOUNTER_CNTL2_BASE_IDX 2
+#define regDC_PERFMON2_PERFCOUNTER_STATE 0x00c0
+#define regDC_PERFMON2_PERFCOUNTER_STATE_BASE_IDX 2
+#define regDC_PERFMON2_PERFMON_CNTL 0x00c1
+#define regDC_PERFMON2_PERFMON_CNTL_BASE_IDX 2
+#define regDC_PERFMON2_PERFMON_CNTL2 0x00c2
+#define regDC_PERFMON2_PERFMON_CNTL2_BASE_IDX 2
+#define regDC_PERFMON2_PERFMON_CVALUE_INT_MISC 0x00c3
+#define regDC_PERFMON2_PERFMON_CVALUE_INT_MISC_BASE_IDX 2
+#define regDC_PERFMON2_PERFMON_CVALUE_LOW 0x00c4
+#define regDC_PERFMON2_PERFMON_CVALUE_LOW_BASE_IDX 2
+#define regDC_PERFMON2_PERFMON_HI 0x00c5
+#define regDC_PERFMON2_PERFMON_HI_BASE_IDX 2
+#define regDC_PERFMON2_PERFMON_LOW 0x00c6
+#define regDC_PERFMON2_PERFMON_LOW_BASE_IDX 2
+
+
+// addressBlock: dce_dc_dmu_ihc_dispdec
+// base address: 0x0
+#define regDC_GPU_TIMER_START_POSITION_V_UPDATE 0x0126
+#define regDC_GPU_TIMER_START_POSITION_V_UPDATE_BASE_IDX 2
+#define regDC_GPU_TIMER_START_POSITION_VSTARTUP 0x0127
+#define regDC_GPU_TIMER_START_POSITION_VSTARTUP_BASE_IDX 2
+#define regDC_GPU_TIMER_READ 0x0128
+#define regDC_GPU_TIMER_READ_BASE_IDX 2
+#define regDC_GPU_TIMER_READ_CNTL 0x0129
+#define regDC_GPU_TIMER_READ_CNTL_BASE_IDX 2
+#define regDC_GPU_TIMER_START_POSITION_VREADY 0x0141
+#define regDC_GPU_TIMER_START_POSITION_VREADY_BASE_IDX 2
+#define regDC_GPU_TIMER_START_POSITION_FLIP 0x0142
+#define regDC_GPU_TIMER_START_POSITION_FLIP_BASE_IDX 2
+#define regDC_GPU_TIMER_START_POSITION_V_UPDATE_NO_LOCK 0x0143
+#define regDC_GPU_TIMER_START_POSITION_V_UPDATE_NO_LOCK_BASE_IDX 2
+#define regDC_GPU_TIMER_START_POSITION_FLIP_AWAY 0x0144
+#define regDC_GPU_TIMER_START_POSITION_FLIP_AWAY_BASE_IDX 2
+#define regDCCG_INTERRUPT_DEST 0x0148
+#define regDCCG_INTERRUPT_DEST_BASE_IDX 2
+#define regDMU_INTERRUPT_DEST 0x0149
+#define regDMU_INTERRUPT_DEST_BASE_IDX 2
+#define regDMU_INTERRUPT_DEST2 0x014a
+#define regDMU_INTERRUPT_DEST2_BASE_IDX 2
+#define regDCPG_INTERRUPT_DEST 0x014b
+#define regDCPG_INTERRUPT_DEST_BASE_IDX 2
+#define regDCPG_INTERRUPT_DEST2 0x014c
+#define regDCPG_INTERRUPT_DEST2_BASE_IDX 2
+#define regMMHUBBUB_INTERRUPT_DEST 0x014d
+#define regMMHUBBUB_INTERRUPT_DEST_BASE_IDX 2
+#define regWB_INTERRUPT_DEST 0x014e
+#define regWB_INTERRUPT_DEST_BASE_IDX 2
+#define regDCHUB_INTERRUPT_DEST 0x014f
+#define regDCHUB_INTERRUPT_DEST_BASE_IDX 2
+#define regDCHUB_PERFCOUNTER_INTERRUPT_DEST 0x0150
+#define regDCHUB_PERFCOUNTER_INTERRUPT_DEST_BASE_IDX 2
+#define regDCHUB_INTERRUPT_DEST2 0x0151
+#define regDCHUB_INTERRUPT_DEST2_BASE_IDX 2
+#define regDPP_PERFCOUNTER_INTERRUPT_DEST 0x0152
+#define regDPP_PERFCOUNTER_INTERRUPT_DEST_BASE_IDX 2
+#define regMPC_INTERRUPT_DEST 0x0153
+#define regMPC_INTERRUPT_DEST_BASE_IDX 2
+#define regOPP_INTERRUPT_DEST 0x0154
+#define regOPP_INTERRUPT_DEST_BASE_IDX 2
+#define regOPTC_INTERRUPT_DEST 0x0155
+#define regOPTC_INTERRUPT_DEST_BASE_IDX 2
+#define regOTG0_INTERRUPT_DEST 0x0156
+#define regOTG0_INTERRUPT_DEST_BASE_IDX 2
+#define regOTG1_INTERRUPT_DEST 0x0157
+#define regOTG1_INTERRUPT_DEST_BASE_IDX 2
+#define regOTG2_INTERRUPT_DEST 0x0158
+#define regOTG2_INTERRUPT_DEST_BASE_IDX 2
+#define regOTG3_INTERRUPT_DEST 0x0159
+#define regOTG3_INTERRUPT_DEST_BASE_IDX 2
+#define regOTG4_INTERRUPT_DEST 0x015a
+#define regOTG4_INTERRUPT_DEST_BASE_IDX 2
+#define regOTG5_INTERRUPT_DEST 0x015b
+#define regOTG5_INTERRUPT_DEST_BASE_IDX 2
+#define regDIG_INTERRUPT_DEST 0x015c
+#define regDIG_INTERRUPT_DEST_BASE_IDX 2
+#define regI2C_DDC_HPD_INTERRUPT_DEST 0x015d
+#define regI2C_DDC_HPD_INTERRUPT_DEST_BASE_IDX 2
+#define regDIO_INTERRUPT_DEST 0x015f
+#define regDIO_INTERRUPT_DEST_BASE_IDX 2
+#define regDCIO_INTERRUPT_DEST 0x0160
+#define regDCIO_INTERRUPT_DEST_BASE_IDX 2
+#define regHPD_INTERRUPT_DEST 0x0161
+#define regHPD_INTERRUPT_DEST_BASE_IDX 2
+#define regAZ_INTERRUPT_DEST 0x0162
+#define regAZ_INTERRUPT_DEST_BASE_IDX 2
+#define regAUX_INTERRUPT_DEST 0x0163
+#define regAUX_INTERRUPT_DEST_BASE_IDX 2
+#define regDSC_INTERRUPT_DEST 0x0164
+#define regDSC_INTERRUPT_DEST_BASE_IDX 2
+#define regHPO_INTERRUPT_DEST 0x0165
+#define regHPO_INTERRUPT_DEST_BASE_IDX 2
+
+
+// addressBlock: dce_dc_dmu_dmu_misc_dispdec
+// base address: 0x0
+#define regCC_DC_PIPE_DIS 0x00ca
+#define regCC_DC_PIPE_DIS_BASE_IDX 2
+#define regDMU_CLK_CNTL 0x00cb
+#define regDMU_CLK_CNTL_BASE_IDX 2
+#define regDMU_MEM_PWR_CNTL 0x00cc
+#define regDMU_MEM_PWR_CNTL_BASE_IDX 2
+#define regDMCU_SMU_INTERRUPT_CNTL 0x00cd
+#define regDMCU_SMU_INTERRUPT_CNTL_BASE_IDX 2
+#define regZSC_CNTL 0x00cf
+#define regZSC_CNTL_BASE_IDX 2
+#define regZSC_CNTL2 0x00d0
+#define regZSC_CNTL2_BASE_IDX 2
+#define regDMU_MISC_ALLOW_DS_FORCE 0x00d6
+#define regDMU_MISC_ALLOW_DS_FORCE_BASE_IDX 2
+#define regZSC_STATUS 0x00d7
+#define regZSC_STATUS_BASE_IDX 2
+
+
+// addressBlock: dce_dc_dmu_dc_pg_dispdec
+// base address: 0x0
+#define regDOMAIN0_PG_CONFIG 0x0080
+#define regDOMAIN0_PG_CONFIG_BASE_IDX 2
+#define regDOMAIN0_PG_STATUS 0x0081
+#define regDOMAIN0_PG_STATUS_BASE_IDX 2
+#define regDOMAIN1_PG_CONFIG 0x0082
+#define regDOMAIN1_PG_CONFIG_BASE_IDX 2
+#define regDOMAIN1_PG_STATUS 0x0083
+#define regDOMAIN1_PG_STATUS_BASE_IDX 2
+#define regDOMAIN2_PG_CONFIG 0x0084
+#define regDOMAIN2_PG_CONFIG_BASE_IDX 2
+#define regDOMAIN2_PG_STATUS 0x0085
+#define regDOMAIN2_PG_STATUS_BASE_IDX 2
+#define regDOMAIN3_PG_CONFIG 0x0086
+#define regDOMAIN3_PG_CONFIG_BASE_IDX 2
+#define regDOMAIN3_PG_STATUS 0x0087
+#define regDOMAIN3_PG_STATUS_BASE_IDX 2
+#define regDOMAIN16_PG_CONFIG 0x0089
+#define regDOMAIN16_PG_CONFIG_BASE_IDX 2
+#define regDOMAIN16_PG_STATUS 0x008a
+#define regDOMAIN16_PG_STATUS_BASE_IDX 2
+#define regDOMAIN17_PG_CONFIG 0x008b
+#define regDOMAIN17_PG_CONFIG_BASE_IDX 2
+#define regDOMAIN17_PG_STATUS 0x008c
+#define regDOMAIN17_PG_STATUS_BASE_IDX 2
+#define regDOMAIN18_PG_CONFIG 0x008d
+#define regDOMAIN18_PG_CONFIG_BASE_IDX 2
+#define regDOMAIN18_PG_STATUS 0x008e
+#define regDOMAIN18_PG_STATUS_BASE_IDX 2
+#define regDC_IP_REQUEST_CNTL 0x0093
+#define regDC_IP_REQUEST_CNTL_BASE_IDX 2
+
+
+// addressBlock: dce_dc_dmu_dmcub_dispdec
+// base address: 0x0
+#define regDMCUB_REGION0_OFFSET 0x018e
+#define regDMCUB_REGION0_OFFSET_BASE_IDX 2
+#define regDMCUB_REGION0_OFFSET_HIGH 0x018f
+#define regDMCUB_REGION0_OFFSET_HIGH_BASE_IDX 2
+#define regDMCUB_REGION1_OFFSET 0x0190
+#define regDMCUB_REGION1_OFFSET_BASE_IDX 2
+#define regDMCUB_REGION1_OFFSET_HIGH 0x0191
+#define regDMCUB_REGION1_OFFSET_HIGH_BASE_IDX 2
+#define regDMCUB_REGION2_OFFSET 0x0192
+#define regDMCUB_REGION2_OFFSET_BASE_IDX 2
+#define regDMCUB_REGION2_OFFSET_HIGH 0x0193
+#define regDMCUB_REGION2_OFFSET_HIGH_BASE_IDX 2
+#define regDMCUB_REGION4_OFFSET 0x0196
+#define regDMCUB_REGION4_OFFSET_BASE_IDX 2
+#define regDMCUB_REGION4_OFFSET_HIGH 0x0197
+#define regDMCUB_REGION4_OFFSET_HIGH_BASE_IDX 2
+#define regDMCUB_REGION5_OFFSET 0x0198
+#define regDMCUB_REGION5_OFFSET_BASE_IDX 2
+#define regDMCUB_REGION5_OFFSET_HIGH 0x0199
+#define regDMCUB_REGION5_OFFSET_HIGH_BASE_IDX 2
+#define regDMCUB_REGION6_OFFSET 0x019a
+#define regDMCUB_REGION6_OFFSET_BASE_IDX 2
+#define regDMCUB_REGION6_OFFSET_HIGH 0x019b
+#define regDMCUB_REGION6_OFFSET_HIGH_BASE_IDX 2
+#define regDMCUB_REGION7_OFFSET 0x019c
+#define regDMCUB_REGION7_OFFSET_BASE_IDX 2
+#define regDMCUB_REGION7_OFFSET_HIGH 0x019d
+#define regDMCUB_REGION7_OFFSET_HIGH_BASE_IDX 2
+#define regDMCUB_REGION0_TOP_ADDRESS 0x019e
+#define regDMCUB_REGION0_TOP_ADDRESS_BASE_IDX 2
+#define regDMCUB_REGION1_TOP_ADDRESS 0x019f
+#define regDMCUB_REGION1_TOP_ADDRESS_BASE_IDX 2
+#define regDMCUB_REGION2_TOP_ADDRESS 0x01a0
+#define regDMCUB_REGION2_TOP_ADDRESS_BASE_IDX 2
+#define regDMCUB_REGION4_TOP_ADDRESS 0x01a1
+#define regDMCUB_REGION4_TOP_ADDRESS_BASE_IDX 2
+#define regDMCUB_REGION5_TOP_ADDRESS 0x01a2
+#define regDMCUB_REGION5_TOP_ADDRESS_BASE_IDX 2
+#define regDMCUB_REGION6_TOP_ADDRESS 0x01a3
+#define regDMCUB_REGION6_TOP_ADDRESS_BASE_IDX 2
+#define regDMCUB_REGION7_TOP_ADDRESS 0x01a4
+#define regDMCUB_REGION7_TOP_ADDRESS_BASE_IDX 2
+#define regDMCUB_REGION3_CW0_BASE_ADDRESS 0x01a5
+#define regDMCUB_REGION3_CW0_BASE_ADDRESS_BASE_IDX 2
+#define regDMCUB_REGION3_CW1_BASE_ADDRESS 0x01a6
+#define regDMCUB_REGION3_CW1_BASE_ADDRESS_BASE_IDX 2
+#define regDMCUB_REGION3_CW2_BASE_ADDRESS 0x01a7
+#define regDMCUB_REGION3_CW2_BASE_ADDRESS_BASE_IDX 2
+#define regDMCUB_REGION3_CW3_BASE_ADDRESS 0x01a8
+#define regDMCUB_REGION3_CW3_BASE_ADDRESS_BASE_IDX 2
+#define regDMCUB_REGION3_CW4_BASE_ADDRESS 0x01a9
+#define regDMCUB_REGION3_CW4_BASE_ADDRESS_BASE_IDX 2
+#define regDMCUB_REGION3_CW5_BASE_ADDRESS 0x01aa
+#define regDMCUB_REGION3_CW5_BASE_ADDRESS_BASE_IDX 2
+#define regDMCUB_REGION3_CW6_BASE_ADDRESS 0x01ab
+#define regDMCUB_REGION3_CW6_BASE_ADDRESS_BASE_IDX 2
+#define regDMCUB_REGION3_CW7_BASE_ADDRESS 0x01ac
+#define regDMCUB_REGION3_CW7_BASE_ADDRESS_BASE_IDX 2
+#define regDMCUB_REGION3_CW0_TOP_ADDRESS 0x01ad
+#define regDMCUB_REGION3_CW0_TOP_ADDRESS_BASE_IDX 2
+#define regDMCUB_REGION3_CW1_TOP_ADDRESS 0x01ae
+#define regDMCUB_REGION3_CW1_TOP_ADDRESS_BASE_IDX 2
+#define regDMCUB_REGION3_CW2_TOP_ADDRESS 0x01af
+#define regDMCUB_REGION3_CW2_TOP_ADDRESS_BASE_IDX 2
+#define regDMCUB_REGION3_CW3_TOP_ADDRESS 0x01b0
+#define regDMCUB_REGION3_CW3_TOP_ADDRESS_BASE_IDX 2
+#define regDMCUB_REGION3_CW4_TOP_ADDRESS 0x01b1
+#define regDMCUB_REGION3_CW4_TOP_ADDRESS_BASE_IDX 2
+#define regDMCUB_REGION3_CW5_TOP_ADDRESS 0x01b2
+#define regDMCUB_REGION3_CW5_TOP_ADDRESS_BASE_IDX 2
+#define regDMCUB_REGION3_CW6_TOP_ADDRESS 0x01b3
+#define regDMCUB_REGION3_CW6_TOP_ADDRESS_BASE_IDX 2
+#define regDMCUB_REGION3_CW7_TOP_ADDRESS 0x01b4
+#define regDMCUB_REGION3_CW7_TOP_ADDRESS_BASE_IDX 2
+#define regDMCUB_REGION3_CW0_OFFSET 0x01b5
+#define regDMCUB_REGION3_CW0_OFFSET_BASE_IDX 2
+#define regDMCUB_REGION3_CW0_OFFSET_HIGH 0x01b6
+#define regDMCUB_REGION3_CW0_OFFSET_HIGH_BASE_IDX 2
+#define regDMCUB_REGION3_CW1_OFFSET 0x01b7
+#define regDMCUB_REGION3_CW1_OFFSET_BASE_IDX 2
+#define regDMCUB_REGION3_CW1_OFFSET_HIGH 0x01b8
+#define regDMCUB_REGION3_CW1_OFFSET_HIGH_BASE_IDX 2
+#define regDMCUB_REGION3_CW2_OFFSET 0x01b9
+#define regDMCUB_REGION3_CW2_OFFSET_BASE_IDX 2
+#define regDMCUB_REGION3_CW2_OFFSET_HIGH 0x01ba
+#define regDMCUB_REGION3_CW2_OFFSET_HIGH_BASE_IDX 2
+#define regDMCUB_REGION3_CW3_OFFSET 0x01bb
+#define regDMCUB_REGION3_CW3_OFFSET_BASE_IDX 2
+#define regDMCUB_REGION3_CW3_OFFSET_HIGH 0x01bc
+#define regDMCUB_REGION3_CW3_OFFSET_HIGH_BASE_IDX 2
+#define regDMCUB_REGION3_CW4_OFFSET 0x01bd
+#define regDMCUB_REGION3_CW4_OFFSET_BASE_IDX 2
+#define regDMCUB_REGION3_CW4_OFFSET_HIGH 0x01be
+#define regDMCUB_REGION3_CW4_OFFSET_HIGH_BASE_IDX 2
+#define regDMCUB_REGION3_CW5_OFFSET 0x01bf
+#define regDMCUB_REGION3_CW5_OFFSET_BASE_IDX 2
+#define regDMCUB_REGION3_CW5_OFFSET_HIGH 0x01c0
+#define regDMCUB_REGION3_CW5_OFFSET_HIGH_BASE_IDX 2
+#define regDMCUB_REGION3_CW6_OFFSET 0x01c1
+#define regDMCUB_REGION3_CW6_OFFSET_BASE_IDX 2
+#define regDMCUB_REGION3_CW6_OFFSET_HIGH 0x01c2
+#define regDMCUB_REGION3_CW6_OFFSET_HIGH_BASE_IDX 2
+#define regDMCUB_REGION3_CW7_OFFSET 0x01c3
+#define regDMCUB_REGION3_CW7_OFFSET_BASE_IDX 2
+#define regDMCUB_REGION3_CW7_OFFSET_HIGH 0x01c4
+#define regDMCUB_REGION3_CW7_OFFSET_HIGH_BASE_IDX 2
+#define regDMCUB_INTERRUPT_ENABLE 0x01c5
+#define regDMCUB_INTERRUPT_ENABLE_BASE_IDX 2
+#define regDMCUB_INTERRUPT_ACK 0x01c6
+#define regDMCUB_INTERRUPT_ACK_BASE_IDX 2
+#define regDMCUB_INTERRUPT_TYPE 0x01c8
+#define regDMCUB_INTERRUPT_TYPE_BASE_IDX 2
+#define regDMCUB_EXT_INTERRUPT_CTXID 0x01ca
+#define regDMCUB_EXT_INTERRUPT_CTXID_BASE_IDX 2
+#define regDMCUB_EXT_INTERRUPT_ACK 0x01cb
+#define regDMCUB_EXT_INTERRUPT_ACK_BASE_IDX 2
+#define regDMCUB_INST_FETCH_FAULT_ADDR 0x01cc
+#define regDMCUB_INST_FETCH_FAULT_ADDR_BASE_IDX 2
+#define regDMCUB_DATA_WRITE_FAULT_ADDR 0x01cd
+#define regDMCUB_DATA_WRITE_FAULT_ADDR_BASE_IDX 2
+#define regDMCUB_SEC_CNTL 0x01ce
+#define regDMCUB_SEC_CNTL_BASE_IDX 2
+#define regDMCUB_MEM_CNTL 0x01cf
+#define regDMCUB_MEM_CNTL_BASE_IDX 2
+#define regDMCUB_INBOX0_BASE_ADDRESS 0x01d0
+#define regDMCUB_INBOX0_BASE_ADDRESS_BASE_IDX 2
+#define regDMCUB_INBOX0_SIZE 0x01d1
+#define regDMCUB_INBOX0_SIZE_BASE_IDX 2
+#define regDMCUB_INBOX0_WPTR 0x01d2
+#define regDMCUB_INBOX0_WPTR_BASE_IDX 2
+#define regDMCUB_INBOX0_RPTR 0x01d3
+#define regDMCUB_INBOX0_RPTR_BASE_IDX 2
+#define regDMCUB_INBOX1_BASE_ADDRESS 0x01d4
+#define regDMCUB_INBOX1_BASE_ADDRESS_BASE_IDX 2
+#define regDMCUB_INBOX1_SIZE 0x01d5
+#define regDMCUB_INBOX1_SIZE_BASE_IDX 2
+#define regDMCUB_INBOX1_WPTR 0x01d6
+#define regDMCUB_INBOX1_WPTR_BASE_IDX 2
+#define regDMCUB_INBOX1_RPTR 0x01d7
+#define regDMCUB_INBOX1_RPTR_BASE_IDX 2
+#define regDMCUB_OUTBOX0_BASE_ADDRESS 0x01d8
+#define regDMCUB_OUTBOX0_BASE_ADDRESS_BASE_IDX 2
+#define regDMCUB_OUTBOX0_SIZE 0x01d9
+#define regDMCUB_OUTBOX0_SIZE_BASE_IDX 2
+#define regDMCUB_OUTBOX0_WPTR 0x01da
+#define regDMCUB_OUTBOX0_WPTR_BASE_IDX 2
+#define regDMCUB_OUTBOX0_RPTR 0x01db
+#define regDMCUB_OUTBOX0_RPTR_BASE_IDX 2
+#define regDMCUB_OUTBOX1_BASE_ADDRESS 0x01dc
+#define regDMCUB_OUTBOX1_BASE_ADDRESS_BASE_IDX 2
+#define regDMCUB_OUTBOX1_SIZE 0x01dd
+#define regDMCUB_OUTBOX1_SIZE_BASE_IDX 2
+#define regDMCUB_OUTBOX1_WPTR 0x01de
+#define regDMCUB_OUTBOX1_WPTR_BASE_IDX 2
+#define regDMCUB_OUTBOX1_RPTR 0x01df
+#define regDMCUB_OUTBOX1_RPTR_BASE_IDX 2
+#define regDMCUB_TIMER_TRIGGER0 0x01e0
+#define regDMCUB_TIMER_TRIGGER0_BASE_IDX 2
+#define regDMCUB_TIMER_TRIGGER1 0x01e1
+#define regDMCUB_TIMER_TRIGGER1_BASE_IDX 2
+#define regDMCUB_TIMER_WINDOW 0x01e2
+#define regDMCUB_TIMER_WINDOW_BASE_IDX 2
+#define regDMCUB_SCRATCH0 0x01e3
+#define regDMCUB_SCRATCH0_BASE_IDX 2
+#define regDMCUB_SCRATCH1 0x01e4
+#define regDMCUB_SCRATCH1_BASE_IDX 2
+#define regDMCUB_SCRATCH2 0x01e5
+#define regDMCUB_SCRATCH2_BASE_IDX 2
+#define regDMCUB_SCRATCH3 0x01e6
+#define regDMCUB_SCRATCH3_BASE_IDX 2
+#define regDMCUB_SCRATCH4 0x01e7
+#define regDMCUB_SCRATCH4_BASE_IDX 2
+#define regDMCUB_SCRATCH5 0x01e8
+#define regDMCUB_SCRATCH5_BASE_IDX 2
+#define regDMCUB_SCRATCH6 0x01e9
+#define regDMCUB_SCRATCH6_BASE_IDX 2
+#define regDMCUB_SCRATCH7 0x01ea
+#define regDMCUB_SCRATCH7_BASE_IDX 2
+#define regDMCUB_SCRATCH8 0x01eb
+#define regDMCUB_SCRATCH8_BASE_IDX 2
+#define regDMCUB_SCRATCH9 0x01ec
+#define regDMCUB_SCRATCH9_BASE_IDX 2
+#define regDMCUB_SCRATCH10 0x01ed
+#define regDMCUB_SCRATCH10_BASE_IDX 2
+#define regDMCUB_SCRATCH11 0x01ee
+#define regDMCUB_SCRATCH11_BASE_IDX 2
+#define regDMCUB_SCRATCH12 0x01ef
+#define regDMCUB_SCRATCH12_BASE_IDX 2
+#define regDMCUB_SCRATCH13 0x01f0
+#define regDMCUB_SCRATCH13_BASE_IDX 2
+#define regDMCUB_SCRATCH14 0x01f1
+#define regDMCUB_SCRATCH14_BASE_IDX 2
+#define regDMCUB_SCRATCH15 0x01f2
+#define regDMCUB_SCRATCH15_BASE_IDX 2
+#define regDMCUB_CNTL 0x01f6
+#define regDMCUB_CNTL_BASE_IDX 2
+#define regDMCUB_GPINT_DATAIN0 0x01f7
+#define regDMCUB_GPINT_DATAIN0_BASE_IDX 2
+#define regDMCUB_GPINT_DATAIN1 0x01f8
+#define regDMCUB_GPINT_DATAIN1_BASE_IDX 2
+#define regDMCUB_GPINT_DATAOUT 0x01f9
+#define regDMCUB_GPINT_DATAOUT_BASE_IDX 2
+#define regDMCUB_UNDEFINED_ADDRESS_FAULT_ADDR 0x01fa
+#define regDMCUB_UNDEFINED_ADDRESS_FAULT_ADDR_BASE_IDX 2
+#define regDMCUB_LS_WAKE_INT_ENABLE 0x01fb
+#define regDMCUB_LS_WAKE_INT_ENABLE_BASE_IDX 2
+#define regDMCUB_MEM_PWR_CNTL 0x01fc
+#define regDMCUB_MEM_PWR_CNTL_BASE_IDX 2
+#define regDMCUB_TIMER_CURRENT 0x01fd
+#define regDMCUB_TIMER_CURRENT_BASE_IDX 2
+#define regDMCUB_PROC_ID 0x01ff
+#define regDMCUB_PROC_ID_BASE_IDX 2
+#define regDMCUB_CNTL2 0x0200
+#define regDMCUB_CNTL2_BASE_IDX 2
+
+
+// addressBlock: dce_dc_wb0_dispdec_dwb_top_dispdec
+// base address: 0x0
+#define regDWB_ENABLE_CLK_CTRL 0x3228
+#define regDWB_ENABLE_CLK_CTRL_BASE_IDX 2
+#define regDWB_MEM_PWR_CTRL 0x3229
+#define regDWB_MEM_PWR_CTRL_BASE_IDX 2
+#define regFC_MODE_CTRL 0x322a
+#define regFC_MODE_CTRL_BASE_IDX 2
+#define regFC_FLOW_CTRL 0x322b
+#define regFC_FLOW_CTRL_BASE_IDX 2
+#define regFC_WINDOW_START 0x322c
+#define regFC_WINDOW_START_BASE_IDX 2
+#define regFC_WINDOW_SIZE 0x322d
+#define regFC_WINDOW_SIZE_BASE_IDX 2
+#define regFC_SOURCE_SIZE 0x322e
+#define regFC_SOURCE_SIZE_BASE_IDX 2
+#define regDWB_UPDATE_CTRL 0x322f
+#define regDWB_UPDATE_CTRL_BASE_IDX 2
+#define regDWB_CRC_CTRL 0x3230
+#define regDWB_CRC_CTRL_BASE_IDX 2
+#define regDWB_CRC_MASK_R_G 0x3231
+#define regDWB_CRC_MASK_R_G_BASE_IDX 2
+#define regDWB_CRC_MASK_B_A 0x3232
+#define regDWB_CRC_MASK_B_A_BASE_IDX 2
+#define regDWB_CRC_VAL_R_G 0x3233
+#define regDWB_CRC_VAL_R_G_BASE_IDX 2
+#define regDWB_CRC_VAL_B_A 0x3234
+#define regDWB_CRC_VAL_B_A_BASE_IDX 2
+#define regDWB_OUT_CTRL 0x3235
+#define regDWB_OUT_CTRL_BASE_IDX 2
+#define regDWB_MMHUBBUB_BACKPRESSURE_CNT_EN 0x3236
+#define regDWB_MMHUBBUB_BACKPRESSURE_CNT_EN_BASE_IDX 2
+#define regDWB_MMHUBBUB_BACKPRESSURE_CNT 0x3237
+#define regDWB_MMHUBBUB_BACKPRESSURE_CNT_BASE_IDX 2
+#define regDWB_HOST_READ_CONTROL 0x3238
+#define regDWB_HOST_READ_CONTROL_BASE_IDX 2
+#define regDWB_OVERFLOW_STATUS 0x3239
+#define regDWB_OVERFLOW_STATUS_BASE_IDX 2
+#define regDWB_OVERFLOW_COUNTER 0x323a
+#define regDWB_OVERFLOW_COUNTER_BASE_IDX 2
+#define regDWB_SOFT_RESET 0x323b
+#define regDWB_SOFT_RESET_BASE_IDX 2
+#define regDWB_DEBUG_CTRL 0x323c
+#define regDWB_DEBUG_CTRL_BASE_IDX 2
+
+
+// addressBlock: dce_dc_wb0_dispdec_dwbcp_dispdec
+// base address: 0x0
+#define regDWB_HDR_MULT_COEF 0x3294
+#define regDWB_HDR_MULT_COEF_BASE_IDX 2
+#define regDWB_GAMUT_REMAP_MODE 0x3295
+#define regDWB_GAMUT_REMAP_MODE_BASE_IDX 2
+#define regDWB_GAMUT_REMAP_COEF_FORMAT 0x3296
+#define regDWB_GAMUT_REMAP_COEF_FORMAT_BASE_IDX 2
+#define regDWB_GAMUT_REMAPA_C11_C12 0x3297
+#define regDWB_GAMUT_REMAPA_C11_C12_BASE_IDX 2
+#define regDWB_GAMUT_REMAPA_C13_C14 0x3298
+#define regDWB_GAMUT_REMAPA_C13_C14_BASE_IDX 2
+#define regDWB_GAMUT_REMAPA_C21_C22 0x3299
+#define regDWB_GAMUT_REMAPA_C21_C22_BASE_IDX 2
+#define regDWB_GAMUT_REMAPA_C23_C24 0x329a
+#define regDWB_GAMUT_REMAPA_C23_C24_BASE_IDX 2
+#define regDWB_GAMUT_REMAPA_C31_C32 0x329b
+#define regDWB_GAMUT_REMAPA_C31_C32_BASE_IDX 2
+#define regDWB_GAMUT_REMAPA_C33_C34 0x329c
+#define regDWB_GAMUT_REMAPA_C33_C34_BASE_IDX 2
+#define regDWB_GAMUT_REMAPB_C11_C12 0x329d
+#define regDWB_GAMUT_REMAPB_C11_C12_BASE_IDX 2
+#define regDWB_GAMUT_REMAPB_C13_C14 0x329e
+#define regDWB_GAMUT_REMAPB_C13_C14_BASE_IDX 2
+#define regDWB_GAMUT_REMAPB_C21_C22 0x329f
+#define regDWB_GAMUT_REMAPB_C21_C22_BASE_IDX 2
+#define regDWB_GAMUT_REMAPB_C23_C24 0x32a0
+#define regDWB_GAMUT_REMAPB_C23_C24_BASE_IDX 2
+#define regDWB_GAMUT_REMAPB_C31_C32 0x32a1
+#define regDWB_GAMUT_REMAPB_C31_C32_BASE_IDX 2
+#define regDWB_GAMUT_REMAPB_C33_C34 0x32a2
+#define regDWB_GAMUT_REMAPB_C33_C34_BASE_IDX 2
+#define regDWB_OGAM_CONTROL 0x32a3
+#define regDWB_OGAM_CONTROL_BASE_IDX 2
+#define regDWB_OGAM_LUT_INDEX 0x32a4
+#define regDWB_OGAM_LUT_INDEX_BASE_IDX 2
+#define regDWB_OGAM_LUT_DATA 0x32a5
+#define regDWB_OGAM_LUT_DATA_BASE_IDX 2
+#define regDWB_OGAM_LUT_CONTROL 0x32a6
+#define regDWB_OGAM_LUT_CONTROL_BASE_IDX 2
+#define regDWB_OGAM_RAMA_START_CNTL_B 0x32a7
+#define regDWB_OGAM_RAMA_START_CNTL_B_BASE_IDX 2
+#define regDWB_OGAM_RAMA_START_CNTL_G 0x32a8
+#define regDWB_OGAM_RAMA_START_CNTL_G_BASE_IDX 2
+#define regDWB_OGAM_RAMA_START_CNTL_R 0x32a9
+#define regDWB_OGAM_RAMA_START_CNTL_R_BASE_IDX 2
+#define regDWB_OGAM_RAMA_START_BASE_CNTL_B 0x32aa
+#define regDWB_OGAM_RAMA_START_BASE_CNTL_B_BASE_IDX 2
+#define regDWB_OGAM_RAMA_START_SLOPE_CNTL_B 0x32ab
+#define regDWB_OGAM_RAMA_START_SLOPE_CNTL_B_BASE_IDX 2
+#define regDWB_OGAM_RAMA_START_BASE_CNTL_G 0x32ac
+#define regDWB_OGAM_RAMA_START_BASE_CNTL_G_BASE_IDX 2
+#define regDWB_OGAM_RAMA_START_SLOPE_CNTL_G 0x32ad
+#define regDWB_OGAM_RAMA_START_SLOPE_CNTL_G_BASE_IDX 2
+#define regDWB_OGAM_RAMA_START_BASE_CNTL_R 0x32ae
+#define regDWB_OGAM_RAMA_START_BASE_CNTL_R_BASE_IDX 2
+#define regDWB_OGAM_RAMA_START_SLOPE_CNTL_R 0x32af
+#define regDWB_OGAM_RAMA_START_SLOPE_CNTL_R_BASE_IDX 2
+#define regDWB_OGAM_RAMA_END_CNTL1_B 0x32b0
+#define regDWB_OGAM_RAMA_END_CNTL1_B_BASE_IDX 2
+#define regDWB_OGAM_RAMA_END_CNTL2_B 0x32b1
+#define regDWB_OGAM_RAMA_END_CNTL2_B_BASE_IDX 2
+#define regDWB_OGAM_RAMA_END_CNTL1_G 0x32b2
+#define regDWB_OGAM_RAMA_END_CNTL1_G_BASE_IDX 2
+#define regDWB_OGAM_RAMA_END_CNTL2_G 0x32b3
+#define regDWB_OGAM_RAMA_END_CNTL2_G_BASE_IDX 2
+#define regDWB_OGAM_RAMA_END_CNTL1_R 0x32b4
+#define regDWB_OGAM_RAMA_END_CNTL1_R_BASE_IDX 2
+#define regDWB_OGAM_RAMA_END_CNTL2_R 0x32b5
+#define regDWB_OGAM_RAMA_END_CNTL2_R_BASE_IDX 2
+#define regDWB_OGAM_RAMA_OFFSET_B 0x32b6
+#define regDWB_OGAM_RAMA_OFFSET_B_BASE_IDX 2
+#define regDWB_OGAM_RAMA_OFFSET_G 0x32b7
+#define regDWB_OGAM_RAMA_OFFSET_G_BASE_IDX 2
+#define regDWB_OGAM_RAMA_OFFSET_R 0x32b8
+#define regDWB_OGAM_RAMA_OFFSET_R_BASE_IDX 2
+#define regDWB_OGAM_RAMA_REGION_0_1 0x32b9
+#define regDWB_OGAM_RAMA_REGION_0_1_BASE_IDX 2
+#define regDWB_OGAM_RAMA_REGION_2_3 0x32ba
+#define regDWB_OGAM_RAMA_REGION_2_3_BASE_IDX 2
+#define regDWB_OGAM_RAMA_REGION_4_5 0x32bb
+#define regDWB_OGAM_RAMA_REGION_4_5_BASE_IDX 2
+#define regDWB_OGAM_RAMA_REGION_6_7 0x32bc
+#define regDWB_OGAM_RAMA_REGION_6_7_BASE_IDX 2
+#define regDWB_OGAM_RAMA_REGION_8_9 0x32bd
+#define regDWB_OGAM_RAMA_REGION_8_9_BASE_IDX 2
+#define regDWB_OGAM_RAMA_REGION_10_11 0x32be
+#define regDWB_OGAM_RAMA_REGION_10_11_BASE_IDX 2
+#define regDWB_OGAM_RAMA_REGION_12_13 0x32bf
+#define regDWB_OGAM_RAMA_REGION_12_13_BASE_IDX 2
+#define regDWB_OGAM_RAMA_REGION_14_15 0x32c0
+#define regDWB_OGAM_RAMA_REGION_14_15_BASE_IDX 2
+#define regDWB_OGAM_RAMA_REGION_16_17 0x32c1
+#define regDWB_OGAM_RAMA_REGION_16_17_BASE_IDX 2
+#define regDWB_OGAM_RAMA_REGION_18_19 0x32c2
+#define regDWB_OGAM_RAMA_REGION_18_19_BASE_IDX 2
+#define regDWB_OGAM_RAMA_REGION_20_21 0x32c3
+#define regDWB_OGAM_RAMA_REGION_20_21_BASE_IDX 2
+#define regDWB_OGAM_RAMA_REGION_22_23 0x32c4
+#define regDWB_OGAM_RAMA_REGION_22_23_BASE_IDX 2
+#define regDWB_OGAM_RAMA_REGION_24_25 0x32c5
+#define regDWB_OGAM_RAMA_REGION_24_25_BASE_IDX 2
+#define regDWB_OGAM_RAMA_REGION_26_27 0x32c6
+#define regDWB_OGAM_RAMA_REGION_26_27_BASE_IDX 2
+#define regDWB_OGAM_RAMA_REGION_28_29 0x32c7
+#define regDWB_OGAM_RAMA_REGION_28_29_BASE_IDX 2
+#define regDWB_OGAM_RAMA_REGION_30_31 0x32c8
+#define regDWB_OGAM_RAMA_REGION_30_31_BASE_IDX 2
+#define regDWB_OGAM_RAMA_REGION_32_33 0x32c9
+#define regDWB_OGAM_RAMA_REGION_32_33_BASE_IDX 2
+#define regDWB_OGAM_RAMB_START_CNTL_B 0x32ca
+#define regDWB_OGAM_RAMB_START_CNTL_B_BASE_IDX 2
+#define regDWB_OGAM_RAMB_START_CNTL_G 0x32cb
+#define regDWB_OGAM_RAMB_START_CNTL_G_BASE_IDX 2
+#define regDWB_OGAM_RAMB_START_CNTL_R 0x32cc
+#define regDWB_OGAM_RAMB_START_CNTL_R_BASE_IDX 2
+#define regDWB_OGAM_RAMB_START_BASE_CNTL_B 0x32cd
+#define regDWB_OGAM_RAMB_START_BASE_CNTL_B_BASE_IDX 2
+#define regDWB_OGAM_RAMB_START_SLOPE_CNTL_B 0x32ce
+#define regDWB_OGAM_RAMB_START_SLOPE_CNTL_B_BASE_IDX 2
+#define regDWB_OGAM_RAMB_START_BASE_CNTL_G 0x32cf
+#define regDWB_OGAM_RAMB_START_BASE_CNTL_G_BASE_IDX 2
+#define regDWB_OGAM_RAMB_START_SLOPE_CNTL_G 0x32d0
+#define regDWB_OGAM_RAMB_START_SLOPE_CNTL_G_BASE_IDX 2
+#define regDWB_OGAM_RAMB_START_BASE_CNTL_R 0x32d1
+#define regDWB_OGAM_RAMB_START_BASE_CNTL_R_BASE_IDX 2
+#define regDWB_OGAM_RAMB_START_SLOPE_CNTL_R 0x32d2
+#define regDWB_OGAM_RAMB_START_SLOPE_CNTL_R_BASE_IDX 2
+#define regDWB_OGAM_RAMB_END_CNTL1_B 0x32d3
+#define regDWB_OGAM_RAMB_END_CNTL1_B_BASE_IDX 2
+#define regDWB_OGAM_RAMB_END_CNTL2_B 0x32d4
+#define regDWB_OGAM_RAMB_END_CNTL2_B_BASE_IDX 2
+#define regDWB_OGAM_RAMB_END_CNTL1_G 0x32d5
+#define regDWB_OGAM_RAMB_END_CNTL1_G_BASE_IDX 2
+#define regDWB_OGAM_RAMB_END_CNTL2_G 0x32d6
+#define regDWB_OGAM_RAMB_END_CNTL2_G_BASE_IDX 2
+#define regDWB_OGAM_RAMB_END_CNTL1_R 0x32d7
+#define regDWB_OGAM_RAMB_END_CNTL1_R_BASE_IDX 2
+#define regDWB_OGAM_RAMB_END_CNTL2_R 0x32d8
+#define regDWB_OGAM_RAMB_END_CNTL2_R_BASE_IDX 2
+#define regDWB_OGAM_RAMB_OFFSET_B 0x32d9
+#define regDWB_OGAM_RAMB_OFFSET_B_BASE_IDX 2
+#define regDWB_OGAM_RAMB_OFFSET_G 0x32da
+#define regDWB_OGAM_RAMB_OFFSET_G_BASE_IDX 2
+#define regDWB_OGAM_RAMB_OFFSET_R 0x32db
+#define regDWB_OGAM_RAMB_OFFSET_R_BASE_IDX 2
+#define regDWB_OGAM_RAMB_REGION_0_1 0x32dc
+#define regDWB_OGAM_RAMB_REGION_0_1_BASE_IDX 2
+#define regDWB_OGAM_RAMB_REGION_2_3 0x32dd
+#define regDWB_OGAM_RAMB_REGION_2_3_BASE_IDX 2
+#define regDWB_OGAM_RAMB_REGION_4_5 0x32de
+#define regDWB_OGAM_RAMB_REGION_4_5_BASE_IDX 2
+#define regDWB_OGAM_RAMB_REGION_6_7 0x32df
+#define regDWB_OGAM_RAMB_REGION_6_7_BASE_IDX 2
+#define regDWB_OGAM_RAMB_REGION_8_9 0x32e0
+#define regDWB_OGAM_RAMB_REGION_8_9_BASE_IDX 2
+#define regDWB_OGAM_RAMB_REGION_10_11 0x32e1
+#define regDWB_OGAM_RAMB_REGION_10_11_BASE_IDX 2
+#define regDWB_OGAM_RAMB_REGION_12_13 0x32e2
+#define regDWB_OGAM_RAMB_REGION_12_13_BASE_IDX 2
+#define regDWB_OGAM_RAMB_REGION_14_15 0x32e3
+#define regDWB_OGAM_RAMB_REGION_14_15_BASE_IDX 2
+#define regDWB_OGAM_RAMB_REGION_16_17 0x32e4
+#define regDWB_OGAM_RAMB_REGION_16_17_BASE_IDX 2
+#define regDWB_OGAM_RAMB_REGION_18_19 0x32e5
+#define regDWB_OGAM_RAMB_REGION_18_19_BASE_IDX 2
+#define regDWB_OGAM_RAMB_REGION_20_21 0x32e6
+#define regDWB_OGAM_RAMB_REGION_20_21_BASE_IDX 2
+#define regDWB_OGAM_RAMB_REGION_22_23 0x32e7
+#define regDWB_OGAM_RAMB_REGION_22_23_BASE_IDX 2
+#define regDWB_OGAM_RAMB_REGION_24_25 0x32e8
+#define regDWB_OGAM_RAMB_REGION_24_25_BASE_IDX 2
+#define regDWB_OGAM_RAMB_REGION_26_27 0x32e9
+#define regDWB_OGAM_RAMB_REGION_26_27_BASE_IDX 2
+#define regDWB_OGAM_RAMB_REGION_28_29 0x32ea
+#define regDWB_OGAM_RAMB_REGION_28_29_BASE_IDX 2
+#define regDWB_OGAM_RAMB_REGION_30_31 0x32eb
+#define regDWB_OGAM_RAMB_REGION_30_31_BASE_IDX 2
+#define regDWB_OGAM_RAMB_REGION_32_33 0x32ec
+#define regDWB_OGAM_RAMB_REGION_32_33_BASE_IDX 2
+
+
+// addressBlock: dce_dc_wb0_dispdec_wb_dcperfmon_dc_perfmon_dispdec
+// base address: 0xca20
+#define regDC_PERFMON3_PERFCOUNTER_CNTL 0x3288
+#define regDC_PERFMON3_PERFCOUNTER_CNTL_BASE_IDX 2
+#define regDC_PERFMON3_PERFCOUNTER_CNTL2 0x3289
+#define regDC_PERFMON3_PERFCOUNTER_CNTL2_BASE_IDX 2
+#define regDC_PERFMON3_PERFCOUNTER_STATE 0x328a
+#define regDC_PERFMON3_PERFCOUNTER_STATE_BASE_IDX 2
+#define regDC_PERFMON3_PERFMON_CNTL 0x328b
+#define regDC_PERFMON3_PERFMON_CNTL_BASE_IDX 2
+#define regDC_PERFMON3_PERFMON_CNTL2 0x328c
+#define regDC_PERFMON3_PERFMON_CNTL2_BASE_IDX 2
+#define regDC_PERFMON3_PERFMON_CVALUE_INT_MISC 0x328d
+#define regDC_PERFMON3_PERFMON_CVALUE_INT_MISC_BASE_IDX 2
+#define regDC_PERFMON3_PERFMON_CVALUE_LOW 0x328e
+#define regDC_PERFMON3_PERFMON_CVALUE_LOW_BASE_IDX 2
+#define regDC_PERFMON3_PERFMON_HI 0x328f
+#define regDC_PERFMON3_PERFMON_HI_BASE_IDX 2
+#define regDC_PERFMON3_PERFMON_LOW 0x3290
+#define regDC_PERFMON3_PERFMON_LOW_BASE_IDX 2
+
+
+// addressBlock: dce_dc_mmhubbub_vga_dispdec
+// base address: 0x0
+#define regVGA_MEM_WRITE_PAGE_ADDR 0x0000
+#define regVGA_MEM_WRITE_PAGE_ADDR_BASE_IDX 0
+#define regVGA_MEM_READ_PAGE_ADDR 0x0001
+#define regVGA_MEM_READ_PAGE_ADDR_BASE_IDX 0
+#define regVGA_RENDER_CONTROL 0x0000
+#define regVGA_RENDER_CONTROL_BASE_IDX 1
+#define regVGA_SEQUENCER_RESET_CONTROL 0x0001
+#define regVGA_SEQUENCER_RESET_CONTROL_BASE_IDX 1
+#define regVGA_MODE_CONTROL 0x0002
+#define regVGA_MODE_CONTROL_BASE_IDX 1
+#define regVGA_SURFACE_PITCH_SELECT 0x0003
+#define regVGA_SURFACE_PITCH_SELECT_BASE_IDX 1
+#define regVGA_MEMORY_BASE_ADDRESS 0x0004
+#define regVGA_MEMORY_BASE_ADDRESS_BASE_IDX 1
+#define regVGA_TEST_DEBUG_INDEX 0x0005
+#define regVGA_TEST_DEBUG_INDEX_BASE_IDX 1
+#define regVGA_DISPBUF1_SURFACE_ADDR 0x0006
+#define regVGA_DISPBUF1_SURFACE_ADDR_BASE_IDX 1
+#define regVGA_TEST_DEBUG_DATA 0x0007
+#define regVGA_TEST_DEBUG_DATA_BASE_IDX 1
+#define regVGA_DISPBUF2_SURFACE_ADDR 0x0008
+#define regVGA_DISPBUF2_SURFACE_ADDR_BASE_IDX 1
+#define regVGA_MEMORY_BASE_ADDRESS_HIGH 0x0009
+#define regVGA_MEMORY_BASE_ADDRESS_HIGH_BASE_IDX 1
+#define regVGA_HDP_CONTROL 0x000a
+#define regVGA_HDP_CONTROL_BASE_IDX 1
+#define regVGA_CACHE_CONTROL 0x000b
+#define regVGA_CACHE_CONTROL_BASE_IDX 1
+#define regD1VGA_CONTROL 0x000c
+#define regD1VGA_CONTROL_BASE_IDX 1
+#define regVGA_SECURITY_LEVEL 0x000d
+#define regVGA_SECURITY_LEVEL_BASE_IDX 1
+#define regD2VGA_CONTROL 0x000e
+#define regD2VGA_CONTROL_BASE_IDX 1
+#define regVGA_HW_DEBUG 0x000f
+#define regVGA_HW_DEBUG_BASE_IDX 1
+#define regVGA_STATUS 0x0010
+#define regVGA_STATUS_BASE_IDX 1
+#define regVGA_STATUS_CLEAR 0x0012
+#define regVGA_STATUS_CLEAR_BASE_IDX 1
+#define regVGA_MAIN_CONTROL 0x0014
+#define regVGA_MAIN_CONTROL_BASE_IDX 1
+#define regVGA_TEST_CONTROL 0x0015
+#define regVGA_TEST_CONTROL_BASE_IDX 1
+#define regVGA_DEBUG_READBACK_INDEX 0x0016
+#define regVGA_DEBUG_READBACK_INDEX_BASE_IDX 1
+#define regVGA_DEBUG_READBACK_DATA 0x0017
+#define regVGA_DEBUG_READBACK_DATA_BASE_IDX 1
+#define regVGA_QOS_CTRL 0x0018
+#define regVGA_QOS_CTRL_BASE_IDX 1
+#define regCRTC8_IDX 0x002d
+#define regCRTC8_IDX_BASE_IDX 1
+#define regCRTC8_DATA 0x002d
+#define regCRTC8_DATA_BASE_IDX 1
+#define regGENFC_WT 0x002e
+#define regGENFC_WT_BASE_IDX 1
+#define regGENS1 0x002e
+#define regGENS1_BASE_IDX 1
+#define regATTRDW 0x0030
+#define regATTRDW_BASE_IDX 1
+#define regATTRX 0x0030
+#define regATTRX_BASE_IDX 1
+#define regATTRDR 0x0030
+#define regATTRDR_BASE_IDX 1
+#define regGENMO_WT 0x0030
+#define regGENMO_WT_BASE_IDX 1
+#define regGENS0 0x0030
+#define regGENS0_BASE_IDX 1
+#define regGENENB 0x0030
+#define regGENENB_BASE_IDX 1
+#define regSEQ8_IDX 0x0031
+#define regSEQ8_IDX_BASE_IDX 1
+#define regSEQ8_DATA 0x0031
+#define regSEQ8_DATA_BASE_IDX 1
+#define regDAC_MASK 0x0031
+#define regDAC_MASK_BASE_IDX 1
+#define regDAC_R_INDEX 0x0031
+#define regDAC_R_INDEX_BASE_IDX 1
+#define regDAC_W_INDEX 0x0032
+#define regDAC_W_INDEX_BASE_IDX 1
+#define regDAC_DATA 0x0032
+#define regDAC_DATA_BASE_IDX 1
+#define regGENFC_RD 0x0032
+#define regGENFC_RD_BASE_IDX 1
+#define regGENMO_RD 0x0033
+#define regGENMO_RD_BASE_IDX 1
+#define regGRPH8_IDX 0x0033
+#define regGRPH8_IDX_BASE_IDX 1
+#define regGRPH8_DATA 0x0033
+#define regGRPH8_DATA_BASE_IDX 1
+#define regCRTC8_IDX_1 0x0035
+#define regCRTC8_IDX_1_BASE_IDX 1
+#define regCRTC8_DATA_1 0x0035
+#define regCRTC8_DATA_1_BASE_IDX 1
+#define regGENFC_WT_1 0x0036
+#define regGENFC_WT_1_BASE_IDX 1
+#define regGENS1_1 0x0036
+#define regGENS1_1_BASE_IDX 1
+#define regD3VGA_CONTROL 0x0038
+#define regD3VGA_CONTROL_BASE_IDX 1
+#define regD4VGA_CONTROL 0x0039
+#define regD4VGA_CONTROL_BASE_IDX 1
+#define regD5VGA_CONTROL 0x003a
+#define regD5VGA_CONTROL_BASE_IDX 1
+#define regD6VGA_CONTROL 0x003b
+#define regD6VGA_CONTROL_BASE_IDX 1
+#define regVGA_SOURCE_SELECT 0x003c
+#define regVGA_SOURCE_SELECT_BASE_IDX 1
+
+
+// addressBlock: dce_dc_mmhubbub_vgaif_dispdec
+// base address: 0x0
+#define regMCIF_CONTROL 0x034a
+#define regMCIF_CONTROL_BASE_IDX 2
+#define regMCIF_WRITE_COMBINE_CONTROL 0x034b
+#define regMCIF_WRITE_COMBINE_CONTROL_BASE_IDX 2
+#define regMCIF_PHASE0_OUTSTANDING_COUNTER 0x034e
+#define regMCIF_PHASE0_OUTSTANDING_COUNTER_BASE_IDX 2
+#define regMCIF_PHASE1_OUTSTANDING_COUNTER 0x034f
+#define regMCIF_PHASE1_OUTSTANDING_COUNTER_BASE_IDX 2
+#define regMCIF_PHASE2_OUTSTANDING_COUNTER 0x0350
+#define regMCIF_PHASE2_OUTSTANDING_COUNTER_BASE_IDX 2
+
+
+// addressBlock: dce_dc_mmhubbub_mcif_wb0_dispdec
+// base address: 0x0
+#define regMCIF_WB_BUFMGR_SW_CONTROL 0x0272
+#define regMCIF_WB_BUFMGR_SW_CONTROL_BASE_IDX 2
+#define regMCIF_WB_BUFMGR_STATUS 0x0274
+#define regMCIF_WB_BUFMGR_STATUS_BASE_IDX 2
+#define regMCIF_WB_BUF_PITCH 0x0275
+#define regMCIF_WB_BUF_PITCH_BASE_IDX 2
+#define regMCIF_WB_BUF_1_STATUS 0x0276
+#define regMCIF_WB_BUF_1_STATUS_BASE_IDX 2
+#define regMCIF_WB_BUF_1_STATUS2 0x0277
+#define regMCIF_WB_BUF_1_STATUS2_BASE_IDX 2
+#define regMCIF_WB_BUF_2_STATUS 0x0278
+#define regMCIF_WB_BUF_2_STATUS_BASE_IDX 2
+#define regMCIF_WB_BUF_2_STATUS2 0x0279
+#define regMCIF_WB_BUF_2_STATUS2_BASE_IDX 2
+#define regMCIF_WB_BUF_3_STATUS 0x027a
+#define regMCIF_WB_BUF_3_STATUS_BASE_IDX 2
+#define regMCIF_WB_BUF_3_STATUS2 0x027b
+#define regMCIF_WB_BUF_3_STATUS2_BASE_IDX 2
+#define regMCIF_WB_BUF_4_STATUS 0x027c
+#define regMCIF_WB_BUF_4_STATUS_BASE_IDX 2
+#define regMCIF_WB_BUF_4_STATUS2 0x027d
+#define regMCIF_WB_BUF_4_STATUS2_BASE_IDX 2
+#define regMCIF_WB_ARBITRATION_CONTROL 0x027e
+#define regMCIF_WB_ARBITRATION_CONTROL_BASE_IDX 2
+#define regMCIF_WB_SCLK_CHANGE 0x027f
+#define regMCIF_WB_SCLK_CHANGE_BASE_IDX 2
+#define regMCIF_WB_TEST_DEBUG_INDEX 0x0280
+#define regMCIF_WB_TEST_DEBUG_INDEX_BASE_IDX 2
+#define regMCIF_WB_TEST_DEBUG_DATA 0x0281
+#define regMCIF_WB_TEST_DEBUG_DATA_BASE_IDX 2
+#define regMCIF_WB_BUF_1_ADDR_Y 0x0282
+#define regMCIF_WB_BUF_1_ADDR_Y_BASE_IDX 2
+#define regMCIF_WB_BUF_1_ADDR_C 0x0284
+#define regMCIF_WB_BUF_1_ADDR_C_BASE_IDX 2
+#define regMCIF_WB_BUF_2_ADDR_Y 0x0286
+#define regMCIF_WB_BUF_2_ADDR_Y_BASE_IDX 2
+#define regMCIF_WB_BUF_2_ADDR_C 0x0288
+#define regMCIF_WB_BUF_2_ADDR_C_BASE_IDX 2
+#define regMCIF_WB_BUF_3_ADDR_Y 0x028a
+#define regMCIF_WB_BUF_3_ADDR_Y_BASE_IDX 2
+#define regMCIF_WB_BUF_3_ADDR_C 0x028c
+#define regMCIF_WB_BUF_3_ADDR_C_BASE_IDX 2
+#define regMCIF_WB_BUF_4_ADDR_Y 0x028e
+#define regMCIF_WB_BUF_4_ADDR_Y_BASE_IDX 2
+#define regMCIF_WB_BUF_4_ADDR_C 0x0290
+#define regMCIF_WB_BUF_4_ADDR_C_BASE_IDX 2
+#define regMCIF_WB_BUFMGR_VCE_CONTROL 0x0292
+#define regMCIF_WB_BUFMGR_VCE_CONTROL_BASE_IDX 2
+#define regMCIF_WB_NB_PSTATE_CONTROL 0x0293
+#define regMCIF_WB_NB_PSTATE_CONTROL_BASE_IDX 2
+#define regMCIF_WB_CLOCK_GATER_CONTROL 0x0294
+#define regMCIF_WB_CLOCK_GATER_CONTROL_BASE_IDX 2
+#define regMCIF_WB_SELF_REFRESH_CONTROL 0x0296
+#define regMCIF_WB_SELF_REFRESH_CONTROL_BASE_IDX 2
+#define regMULTI_LEVEL_QOS_CTRL 0x0297
+#define regMULTI_LEVEL_QOS_CTRL_BASE_IDX 2
+#define regMCIF_WB_BUF_LUMA_SIZE 0x0299
+#define regMCIF_WB_BUF_LUMA_SIZE_BASE_IDX 2
+#define regMCIF_WB_BUF_CHROMA_SIZE 0x029a
+#define regMCIF_WB_BUF_CHROMA_SIZE_BASE_IDX 2
+#define regMCIF_WB_BUF_1_ADDR_Y_HIGH 0x029b
+#define regMCIF_WB_BUF_1_ADDR_Y_HIGH_BASE_IDX 2
+#define regMCIF_WB_BUF_1_ADDR_C_HIGH 0x029c
+#define regMCIF_WB_BUF_1_ADDR_C_HIGH_BASE_IDX 2
+#define regMCIF_WB_BUF_2_ADDR_Y_HIGH 0x029d
+#define regMCIF_WB_BUF_2_ADDR_Y_HIGH_BASE_IDX 2
+#define regMCIF_WB_BUF_2_ADDR_C_HIGH 0x029e
+#define regMCIF_WB_BUF_2_ADDR_C_HIGH_BASE_IDX 2
+#define regMCIF_WB_BUF_3_ADDR_Y_HIGH 0x029f
+#define regMCIF_WB_BUF_3_ADDR_Y_HIGH_BASE_IDX 2
+#define regMCIF_WB_BUF_3_ADDR_C_HIGH 0x02a0
+#define regMCIF_WB_BUF_3_ADDR_C_HIGH_BASE_IDX 2
+#define regMCIF_WB_BUF_4_ADDR_Y_HIGH 0x02a1
+#define regMCIF_WB_BUF_4_ADDR_Y_HIGH_BASE_IDX 2
+#define regMCIF_WB_BUF_4_ADDR_C_HIGH 0x02a2
+#define regMCIF_WB_BUF_4_ADDR_C_HIGH_BASE_IDX 2
+#define regMCIF_WB_BUF_1_RESOLUTION 0x02a3
+#define regMCIF_WB_BUF_1_RESOLUTION_BASE_IDX 2
+#define regMCIF_WB_BUF_2_RESOLUTION 0x02a4
+#define regMCIF_WB_BUF_2_RESOLUTION_BASE_IDX 2
+#define regMCIF_WB_BUF_3_RESOLUTION 0x02a5
+#define regMCIF_WB_BUF_3_RESOLUTION_BASE_IDX 2
+#define regMCIF_WB_BUF_4_RESOLUTION 0x02a6
+#define regMCIF_WB_BUF_4_RESOLUTION_BASE_IDX 2
+#define regMCIF_WB_DRAM_SPEED_CHANGE_DURATION_VBI 0x02a7
+#define regMCIF_WB_DRAM_SPEED_CHANGE_DURATION_VBI_BASE_IDX 2
+#define regMCIF_WB_VMID_CONTROL 0x02a8
+#define regMCIF_WB_VMID_CONTROL_BASE_IDX 2
+#define regMCIF_WB_MIN_TTO 0x02a9
+#define regMCIF_WB_MIN_TTO_BASE_IDX 2
+
+
+// addressBlock: dce_dc_mmhubbub_mmhubbub_dcperfmon_dc_perfmon_dispdec
+// base address: 0xd48
+#define regDC_PERFMON4_PERFCOUNTER_CNTL 0x0352
+#define regDC_PERFMON4_PERFCOUNTER_CNTL_BASE_IDX 2
+#define regDC_PERFMON4_PERFCOUNTER_CNTL2 0x0353
+#define regDC_PERFMON4_PERFCOUNTER_CNTL2_BASE_IDX 2
+#define regDC_PERFMON4_PERFCOUNTER_STATE 0x0354
+#define regDC_PERFMON4_PERFCOUNTER_STATE_BASE_IDX 2
+#define regDC_PERFMON4_PERFMON_CNTL 0x0355
+#define regDC_PERFMON4_PERFMON_CNTL_BASE_IDX 2
+#define regDC_PERFMON4_PERFMON_CNTL2 0x0356
+#define regDC_PERFMON4_PERFMON_CNTL2_BASE_IDX 2
+#define regDC_PERFMON4_PERFMON_CVALUE_INT_MISC 0x0357
+#define regDC_PERFMON4_PERFMON_CVALUE_INT_MISC_BASE_IDX 2
+#define regDC_PERFMON4_PERFMON_CVALUE_LOW 0x0358
+#define regDC_PERFMON4_PERFMON_CVALUE_LOW_BASE_IDX 2
+#define regDC_PERFMON4_PERFMON_HI 0x0359
+#define regDC_PERFMON4_PERFMON_HI_BASE_IDX 2
+#define regDC_PERFMON4_PERFMON_LOW 0x035a
+#define regDC_PERFMON4_PERFMON_LOW_BASE_IDX 2
+
+
+// addressBlock: dce_dc_mmhubbub_mmhubbub_dispdec
+// base address: 0x0
+#define regMCIF_WB_NB_PSTATE_LATENCY_WATERMARK 0x02aa
+#define regMCIF_WB_NB_PSTATE_LATENCY_WATERMARK_BASE_IDX 2
+#define regMCIF_WB_WATERMARK 0x02ab
+#define regMCIF_WB_WATERMARK_BASE_IDX 2
+#define regMMHUBBUB_WARMUP_CONFIG 0x02ac
+#define regMMHUBBUB_WARMUP_CONFIG_BASE_IDX 2
+#define regMMHUBBUB_WARMUP_CONTROL_STATUS 0x02ad
+#define regMMHUBBUB_WARMUP_CONTROL_STATUS_BASE_IDX 2
+#define regMMHUBBUB_WARMUP_BASE_ADDR_LOW 0x02ae
+#define regMMHUBBUB_WARMUP_BASE_ADDR_LOW_BASE_IDX 2
+#define regMMHUBBUB_WARMUP_BASE_ADDR_HIGH 0x02af
+#define regMMHUBBUB_WARMUP_BASE_ADDR_HIGH_BASE_IDX 2
+#define regMMHUBBUB_WARMUP_ADDR_REGION 0x02b0
+#define regMMHUBBUB_WARMUP_ADDR_REGION_BASE_IDX 2
+#define regMMHUBBUB_MIN_TTO 0x02b1
+#define regMMHUBBUB_MIN_TTO_BASE_IDX 2
+#define regMMHUBBUB_CTRL 0x0333
+#define regMMHUBBUB_CTRL_BASE_IDX 2
+#define regWBIF_SMU_WM_CONTROL 0x0334
+#define regWBIF_SMU_WM_CONTROL_BASE_IDX 2
+#define regWBIF0_MISC_CTRL 0x0335
+#define regWBIF0_MISC_CTRL_BASE_IDX 2
+#define regWBIF0_PHASE0_OUTSTANDING_COUNTER 0x0336
+#define regWBIF0_PHASE0_OUTSTANDING_COUNTER_BASE_IDX 2
+#define regWBIF0_PHASE1_OUTSTANDING_COUNTER 0x0337
+#define regWBIF0_PHASE1_OUTSTANDING_COUNTER_BASE_IDX 2
+#define regVGA_SRC_SPLIT_CNTL 0x033e
+#define regVGA_SRC_SPLIT_CNTL_BASE_IDX 2
+#define regMMHUBBUB_MEM_PWR_STATUS 0x033f
+#define regMMHUBBUB_MEM_PWR_STATUS_BASE_IDX 2
+#define regMMHUBBUB_MEM_PWR_CNTL 0x0340
+#define regMMHUBBUB_MEM_PWR_CNTL_BASE_IDX 2
+#define regMMHUBBUB_CLOCK_CNTL 0x0341
+#define regMMHUBBUB_CLOCK_CNTL_BASE_IDX 2
+#define regMMHUBBUB_SOFT_RESET 0x0342
+#define regMMHUBBUB_SOFT_RESET_BASE_IDX 2
+#define regDMU_IF_ERR_STATUS 0x0346
+#define regDMU_IF_ERR_STATUS_BASE_IDX 2
+#define regMMHUBBUB_CLIENT_UNIT_ID 0x0347
+#define regMMHUBBUB_CLIENT_UNIT_ID_BASE_IDX 2
+#define regMMHUBBUB_WARMUP_VMID_CONTROL 0x0349
+#define regMMHUBBUB_WARMUP_VMID_CONTROL_BASE_IDX 2
+
+
+// addressBlock: dce_dc_hda_azf0controller_dispdec
+// base address: 0x0
+#define regAZALIA_CONTROLLER_CLOCK_GATING 0x03c2
+#define regAZALIA_CONTROLLER_CLOCK_GATING_BASE_IDX 2
+#define regAZALIA_AUDIO_DTO 0x03c3
+#define regAZALIA_AUDIO_DTO_BASE_IDX 2
+#define regAZALIA_AUDIO_DTO_CONTROL 0x03c4
+#define regAZALIA_AUDIO_DTO_CONTROL_BASE_IDX 2
+#define regAZALIA_SOCCLK_CONTROL 0x03c5
+#define regAZALIA_SOCCLK_CONTROL_BASE_IDX 2
+#define regAZALIA_UNDERFLOW_FILLER_SAMPLE 0x03c6
+#define regAZALIA_UNDERFLOW_FILLER_SAMPLE_BASE_IDX 2
+#define regAZALIA_DATA_DMA_CONTROL 0x03c7
+#define regAZALIA_DATA_DMA_CONTROL_BASE_IDX 2
+#define regAZALIA_BDL_DMA_CONTROL 0x03c8
+#define regAZALIA_BDL_DMA_CONTROL_BASE_IDX 2
+#define regAZALIA_RIRB_AND_DP_CONTROL 0x03c9
+#define regAZALIA_RIRB_AND_DP_CONTROL_BASE_IDX 2
+#define regAZALIA_CORB_DMA_CONTROL 0x03ca
+#define regAZALIA_CORB_DMA_CONTROL_BASE_IDX 2
+#define regAZALIA_APPLICATION_POSITION_IN_CYCLIC_BUFFER 0x03d1
+#define regAZALIA_APPLICATION_POSITION_IN_CYCLIC_BUFFER_BASE_IDX 2
+#define regAZALIA_CYCLIC_BUFFER_SYNC 0x03d2
+#define regAZALIA_CYCLIC_BUFFER_SYNC_BASE_IDX 2
+#define regAZALIA_OUTPUT_STREAM_ARBITER_CONTROL 0x03d5
+#define regAZALIA_OUTPUT_STREAM_ARBITER_CONTROL_BASE_IDX 2
+#define regAZALIA_INPUT_CRC0_CONTROL0 0x03d9
+#define regAZALIA_INPUT_CRC0_CONTROL0_BASE_IDX 2
+#define regAZALIA_INPUT_CRC0_CONTROL1 0x03da
+#define regAZALIA_INPUT_CRC0_CONTROL1_BASE_IDX 2
+#define regAZALIA_INPUT_CRC0_CONTROL2 0x03db
+#define regAZALIA_INPUT_CRC0_CONTROL2_BASE_IDX 2
+#define regAZALIA_INPUT_CRC0_CONTROL3 0x03dc
+#define regAZALIA_INPUT_CRC0_CONTROL3_BASE_IDX 2
+#define regAZALIA_INPUT_CRC0_RESULT 0x03dd
+#define regAZALIA_INPUT_CRC0_RESULT_BASE_IDX 2
+#define regAZALIA_INPUT_CRC1_CONTROL0 0x03de
+#define regAZALIA_INPUT_CRC1_CONTROL0_BASE_IDX 2
+#define regAZALIA_INPUT_CRC1_CONTROL1 0x03df
+#define regAZALIA_INPUT_CRC1_CONTROL1_BASE_IDX 2
+#define regAZALIA_INPUT_CRC1_CONTROL2 0x03e0
+#define regAZALIA_INPUT_CRC1_CONTROL2_BASE_IDX 2
+#define regAZALIA_INPUT_CRC1_CONTROL3 0x03e1
+#define regAZALIA_INPUT_CRC1_CONTROL3_BASE_IDX 2
+#define regAZALIA_INPUT_CRC1_RESULT 0x03e2
+#define regAZALIA_INPUT_CRC1_RESULT_BASE_IDX 2
+#define regAZALIA_CRC0_CONTROL0 0x03e3
+#define regAZALIA_CRC0_CONTROL0_BASE_IDX 2
+#define regAZALIA_CRC0_CONTROL1 0x03e4
+#define regAZALIA_CRC0_CONTROL1_BASE_IDX 2
+#define regAZALIA_CRC0_CONTROL2 0x03e5
+#define regAZALIA_CRC0_CONTROL2_BASE_IDX 2
+#define regAZALIA_CRC0_CONTROL3 0x03e6
+#define regAZALIA_CRC0_CONTROL3_BASE_IDX 2
+#define regAZALIA_CRC0_RESULT 0x03e7
+#define regAZALIA_CRC0_RESULT_BASE_IDX 2
+#define regAZALIA_CRC1_CONTROL0 0x03e8
+#define regAZALIA_CRC1_CONTROL0_BASE_IDX 2
+#define regAZALIA_CRC1_CONTROL1 0x03e9
+#define regAZALIA_CRC1_CONTROL1_BASE_IDX 2
+#define regAZALIA_CRC1_CONTROL2 0x03ea
+#define regAZALIA_CRC1_CONTROL2_BASE_IDX 2
+#define regAZALIA_CRC1_CONTROL3 0x03eb
+#define regAZALIA_CRC1_CONTROL3_BASE_IDX 2
+#define regAZALIA_CRC1_RESULT 0x03ec
+#define regAZALIA_CRC1_RESULT_BASE_IDX 2
+#define regAZALIA_MEM_PWR_CTRL 0x03ee
+#define regAZALIA_MEM_PWR_CTRL_BASE_IDX 2
+#define regAZALIA_MEM_PWR_STATUS 0x03ef
+#define regAZALIA_MEM_PWR_STATUS_BASE_IDX 2
+
+
+// addressBlock: dce_dc_hda_azf0root_dispdec
+// base address: 0x0
+#define regAZALIA_F0_CODEC_ROOT_PARAMETER_VENDOR_AND_DEVICE_ID 0x0406
+#define regAZALIA_F0_CODEC_ROOT_PARAMETER_VENDOR_AND_DEVICE_ID_BASE_IDX 2
+#define regAZALIA_F0_CODEC_ROOT_PARAMETER_REVISION_ID 0x0407
+#define regAZALIA_F0_CODEC_ROOT_PARAMETER_REVISION_ID_BASE_IDX 2
+#define regAZALIA_F0_CODEC_CHANNEL_COUNT_CONTROL 0x0408
+#define regAZALIA_F0_CODEC_CHANNEL_COUNT_CONTROL_BASE_IDX 2
+#define regAZALIA_F0_CODEC_RESYNC_FIFO_CONTROL 0x0409
+#define regAZALIA_F0_CODEC_RESYNC_FIFO_CONTROL_BASE_IDX 2
+#define regAZALIA_F0_CODEC_FUNCTION_PARAMETER_GROUP_TYPE 0x040a
+#define regAZALIA_F0_CODEC_FUNCTION_PARAMETER_GROUP_TYPE_BASE_IDX 2
+#define regAZALIA_F0_CODEC_FUNCTION_PARAMETER_SUPPORTED_SIZE_RATES 0x040b
+#define regAZALIA_F0_CODEC_FUNCTION_PARAMETER_SUPPORTED_SIZE_RATES_BASE_IDX 2
+#define regAZALIA_F0_CODEC_FUNCTION_PARAMETER_STREAM_FORMATS 0x040c
+#define regAZALIA_F0_CODEC_FUNCTION_PARAMETER_STREAM_FORMATS_BASE_IDX 2
+#define regAZALIA_F0_CODEC_FUNCTION_PARAMETER_POWER_STATES 0x040d
+#define regAZALIA_F0_CODEC_FUNCTION_PARAMETER_POWER_STATES_BASE_IDX 2
+#define regAZALIA_F0_CODEC_FUNCTION_CONTROL_POWER_STATE 0x040e
+#define regAZALIA_F0_CODEC_FUNCTION_CONTROL_POWER_STATE_BASE_IDX 2
+#define regAZALIA_F0_CODEC_FUNCTION_CONTROL_RESET 0x040f
+#define regAZALIA_F0_CODEC_FUNCTION_CONTROL_RESET_BASE_IDX 2
+#define regAZALIA_F0_CODEC_FUNCTION_CONTROL_RESPONSE_SUBSYSTEM_ID 0x0410
+#define regAZALIA_F0_CODEC_FUNCTION_CONTROL_RESPONSE_SUBSYSTEM_ID_BASE_IDX 2
+#define regAZALIA_F0_CODEC_FUNCTION_CONTROL_CONVERTER_SYNCHRONIZATION 0x0411
+#define regAZALIA_F0_CODEC_FUNCTION_CONTROL_CONVERTER_SYNCHRONIZATION_BASE_IDX 2
+#define regCC_RCU_DC_AUDIO_PORT_CONNECTIVITY 0x0412
+#define regCC_RCU_DC_AUDIO_PORT_CONNECTIVITY_BASE_IDX 2
+#define regCC_RCU_DC_AUDIO_INPUT_PORT_CONNECTIVITY 0x0413
+#define regCC_RCU_DC_AUDIO_INPUT_PORT_CONNECTIVITY_BASE_IDX 2
+#define regAZALIA_F0_GTC_GROUP_OFFSET0 0x0415
+#define regAZALIA_F0_GTC_GROUP_OFFSET0_BASE_IDX 2
+#define regAZALIA_F0_GTC_GROUP_OFFSET1 0x0416
+#define regAZALIA_F0_GTC_GROUP_OFFSET1_BASE_IDX 2
+#define regAZALIA_F0_GTC_GROUP_OFFSET2 0x0417
+#define regAZALIA_F0_GTC_GROUP_OFFSET2_BASE_IDX 2
+#define regAZALIA_F0_GTC_GROUP_OFFSET3 0x0418
+#define regAZALIA_F0_GTC_GROUP_OFFSET3_BASE_IDX 2
+#define regAZALIA_F0_GTC_GROUP_OFFSET4 0x0419
+#define regAZALIA_F0_GTC_GROUP_OFFSET4_BASE_IDX 2
+#define regAZALIA_F0_GTC_GROUP_OFFSET5 0x041a
+#define regAZALIA_F0_GTC_GROUP_OFFSET5_BASE_IDX 2
+#define regAZALIA_F0_GTC_GROUP_OFFSET6 0x041b
+#define regAZALIA_F0_GTC_GROUP_OFFSET6_BASE_IDX 2
+#define regREG_DC_AUDIO_PORT_CONNECTIVITY 0x041c
+#define regREG_DC_AUDIO_PORT_CONNECTIVITY_BASE_IDX 2
+#define regREG_DC_AUDIO_INPUT_PORT_CONNECTIVITY 0x041d
+#define regREG_DC_AUDIO_INPUT_PORT_CONNECTIVITY_BASE_IDX 2
+
+
+// addressBlock: dce_dc_hda_az_misc_dispdec
+// base address: 0x0
+#define regAZ_CLOCK_CNTL 0x0372
+#define regAZ_CLOCK_CNTL_BASE_IDX 2
+
+
+// addressBlock: dce_dc_hda_az_dcperfmon_dc_perfmon_dispdec
+// base address: 0xde8
+#define regDC_PERFMON5_PERFCOUNTER_CNTL 0x037a
+#define regDC_PERFMON5_PERFCOUNTER_CNTL_BASE_IDX 2
+#define regDC_PERFMON5_PERFCOUNTER_CNTL2 0x037b
+#define regDC_PERFMON5_PERFCOUNTER_CNTL2_BASE_IDX 2
+#define regDC_PERFMON5_PERFCOUNTER_STATE 0x037c
+#define regDC_PERFMON5_PERFCOUNTER_STATE_BASE_IDX 2
+#define regDC_PERFMON5_PERFMON_CNTL 0x037d
+#define regDC_PERFMON5_PERFMON_CNTL_BASE_IDX 2
+#define regDC_PERFMON5_PERFMON_CNTL2 0x037e
+#define regDC_PERFMON5_PERFMON_CNTL2_BASE_IDX 2
+#define regDC_PERFMON5_PERFMON_CVALUE_INT_MISC 0x037f
+#define regDC_PERFMON5_PERFMON_CVALUE_INT_MISC_BASE_IDX 2
+#define regDC_PERFMON5_PERFMON_CVALUE_LOW 0x0380
+#define regDC_PERFMON5_PERFMON_CVALUE_LOW_BASE_IDX 2
+#define regDC_PERFMON5_PERFMON_HI 0x0381
+#define regDC_PERFMON5_PERFMON_HI_BASE_IDX 2
+#define regDC_PERFMON5_PERFMON_LOW 0x0382
+#define regDC_PERFMON5_PERFMON_LOW_BASE_IDX 2
+
+
+// addressBlock: dce_dc_hda_azf0stream0_dispdec
+// base address: 0x0
+#define regAZF0STREAM0_AZALIA_STREAM_INDEX 0x035e
+#define regAZF0STREAM0_AZALIA_STREAM_INDEX_BASE_IDX 2
+#define regAZF0STREAM0_AZALIA_STREAM_DATA 0x035f
+#define regAZF0STREAM0_AZALIA_STREAM_DATA_BASE_IDX 2
+
+
+// addressBlock: dce_dc_hda_azf0stream1_dispdec
+// base address: 0x8
+#define regAZF0STREAM1_AZALIA_STREAM_INDEX 0x0360
+#define regAZF0STREAM1_AZALIA_STREAM_INDEX_BASE_IDX 2
+#define regAZF0STREAM1_AZALIA_STREAM_DATA 0x0361
+#define regAZF0STREAM1_AZALIA_STREAM_DATA_BASE_IDX 2
+
+
+// addressBlock: dce_dc_hda_azf0stream2_dispdec
+// base address: 0x10
+#define regAZF0STREAM2_AZALIA_STREAM_INDEX 0x0362
+#define regAZF0STREAM2_AZALIA_STREAM_INDEX_BASE_IDX 2
+#define regAZF0STREAM2_AZALIA_STREAM_DATA 0x0363
+#define regAZF0STREAM2_AZALIA_STREAM_DATA_BASE_IDX 2
+
+
+// addressBlock: dce_dc_hda_azf0stream3_dispdec
+// base address: 0x18
+#define regAZF0STREAM3_AZALIA_STREAM_INDEX 0x0364
+#define regAZF0STREAM3_AZALIA_STREAM_INDEX_BASE_IDX 2
+#define regAZF0STREAM3_AZALIA_STREAM_DATA 0x0365
+#define regAZF0STREAM3_AZALIA_STREAM_DATA_BASE_IDX 2
+
+
+// addressBlock: dce_dc_hda_azf0stream4_dispdec
+// base address: 0x20
+#define regAZF0STREAM4_AZALIA_STREAM_INDEX 0x0366
+#define regAZF0STREAM4_AZALIA_STREAM_INDEX_BASE_IDX 2
+#define regAZF0STREAM4_AZALIA_STREAM_DATA 0x0367
+#define regAZF0STREAM4_AZALIA_STREAM_DATA_BASE_IDX 2
+
+
+// addressBlock: dce_dc_hda_azf0stream5_dispdec
+// base address: 0x28
+#define regAZF0STREAM5_AZALIA_STREAM_INDEX 0x0368
+#define regAZF0STREAM5_AZALIA_STREAM_INDEX_BASE_IDX 2
+#define regAZF0STREAM5_AZALIA_STREAM_DATA 0x0369
+#define regAZF0STREAM5_AZALIA_STREAM_DATA_BASE_IDX 2
+
+
+// addressBlock: dce_dc_hda_azf0stream6_dispdec
+// base address: 0x30
+#define regAZF0STREAM6_AZALIA_STREAM_INDEX 0x036a
+#define regAZF0STREAM6_AZALIA_STREAM_INDEX_BASE_IDX 2
+#define regAZF0STREAM6_AZALIA_STREAM_DATA 0x036b
+#define regAZF0STREAM6_AZALIA_STREAM_DATA_BASE_IDX 2
+
+
+// addressBlock: dce_dc_hda_azf0stream7_dispdec
+// base address: 0x38
+#define regAZF0STREAM7_AZALIA_STREAM_INDEX 0x036c
+#define regAZF0STREAM7_AZALIA_STREAM_INDEX_BASE_IDX 2
+#define regAZF0STREAM7_AZALIA_STREAM_DATA 0x036d
+#define regAZF0STREAM7_AZALIA_STREAM_DATA_BASE_IDX 2
+
+
+// addressBlock: dce_dc_hda_azf0stream8_dispdec
+// base address: 0x320
+#define regAZF0STREAM8_AZALIA_STREAM_INDEX 0x0426
+#define regAZF0STREAM8_AZALIA_STREAM_INDEX_BASE_IDX 2
+#define regAZF0STREAM8_AZALIA_STREAM_DATA 0x0427
+#define regAZF0STREAM8_AZALIA_STREAM_DATA_BASE_IDX 2
+
+
+// addressBlock: dce_dc_hda_azf0stream9_dispdec
+// base address: 0x328
+#define regAZF0STREAM9_AZALIA_STREAM_INDEX 0x0428
+#define regAZF0STREAM9_AZALIA_STREAM_INDEX_BASE_IDX 2
+#define regAZF0STREAM9_AZALIA_STREAM_DATA 0x0429
+#define regAZF0STREAM9_AZALIA_STREAM_DATA_BASE_IDX 2
+
+
+// addressBlock: dce_dc_hda_azf0stream10_dispdec
+// base address: 0x330
+#define regAZF0STREAM10_AZALIA_STREAM_INDEX 0x042a
+#define regAZF0STREAM10_AZALIA_STREAM_INDEX_BASE_IDX 2
+#define regAZF0STREAM10_AZALIA_STREAM_DATA 0x042b
+#define regAZF0STREAM10_AZALIA_STREAM_DATA_BASE_IDX 2
+
+
+// addressBlock: dce_dc_hda_azf0stream11_dispdec
+// base address: 0x338
+#define regAZF0STREAM11_AZALIA_STREAM_INDEX 0x042c
+#define regAZF0STREAM11_AZALIA_STREAM_INDEX_BASE_IDX 2
+#define regAZF0STREAM11_AZALIA_STREAM_DATA 0x042d
+#define regAZF0STREAM11_AZALIA_STREAM_DATA_BASE_IDX 2
+
+
+// addressBlock: dce_dc_hda_azf0stream12_dispdec
+// base address: 0x340
+#define regAZF0STREAM12_AZALIA_STREAM_INDEX 0x042e
+#define regAZF0STREAM12_AZALIA_STREAM_INDEX_BASE_IDX 2
+#define regAZF0STREAM12_AZALIA_STREAM_DATA 0x042f
+#define regAZF0STREAM12_AZALIA_STREAM_DATA_BASE_IDX 2
+
+
+// addressBlock: dce_dc_hda_azf0stream13_dispdec
+// base address: 0x348
+#define regAZF0STREAM13_AZALIA_STREAM_INDEX 0x0430
+#define regAZF0STREAM13_AZALIA_STREAM_INDEX_BASE_IDX 2
+#define regAZF0STREAM13_AZALIA_STREAM_DATA 0x0431
+#define regAZF0STREAM13_AZALIA_STREAM_DATA_BASE_IDX 2
+
+
+// addressBlock: dce_dc_hda_azf0stream14_dispdec
+// base address: 0x350
+#define regAZF0STREAM14_AZALIA_STREAM_INDEX 0x0432
+#define regAZF0STREAM14_AZALIA_STREAM_INDEX_BASE_IDX 2
+#define regAZF0STREAM14_AZALIA_STREAM_DATA 0x0433
+#define regAZF0STREAM14_AZALIA_STREAM_DATA_BASE_IDX 2
+
+
+// addressBlock: dce_dc_hda_azf0stream15_dispdec
+// base address: 0x358
+#define regAZF0STREAM15_AZALIA_STREAM_INDEX 0x0434
+#define regAZF0STREAM15_AZALIA_STREAM_INDEX_BASE_IDX 2
+#define regAZF0STREAM15_AZALIA_STREAM_DATA 0x0435
+#define regAZF0STREAM15_AZALIA_STREAM_DATA_BASE_IDX 2
+
+
+// addressBlock: dce_dc_hda_azf0endpoint0_dispdec
+// base address: 0x0
+#define regAZF0ENDPOINT0_AZALIA_F0_CODEC_ENDPOINT_INDEX 0x0386
+#define regAZF0ENDPOINT0_AZALIA_F0_CODEC_ENDPOINT_INDEX_BASE_IDX 2
+#define regAZF0ENDPOINT0_AZALIA_F0_CODEC_ENDPOINT_DATA 0x0387
+#define regAZF0ENDPOINT0_AZALIA_F0_CODEC_ENDPOINT_DATA_BASE_IDX 2
+
+
+// addressBlock: dce_dc_hda_azf0endpoint1_dispdec
+// base address: 0x18
+#define regAZF0ENDPOINT1_AZALIA_F0_CODEC_ENDPOINT_INDEX 0x038c
+#define regAZF0ENDPOINT1_AZALIA_F0_CODEC_ENDPOINT_INDEX_BASE_IDX 2
+#define regAZF0ENDPOINT1_AZALIA_F0_CODEC_ENDPOINT_DATA 0x038d
+#define regAZF0ENDPOINT1_AZALIA_F0_CODEC_ENDPOINT_DATA_BASE_IDX 2
+
+
+// addressBlock: dce_dc_hda_azf0endpoint2_dispdec
+// base address: 0x30
+#define regAZF0ENDPOINT2_AZALIA_F0_CODEC_ENDPOINT_INDEX 0x0392
+#define regAZF0ENDPOINT2_AZALIA_F0_CODEC_ENDPOINT_INDEX_BASE_IDX 2
+#define regAZF0ENDPOINT2_AZALIA_F0_CODEC_ENDPOINT_DATA 0x0393
+#define regAZF0ENDPOINT2_AZALIA_F0_CODEC_ENDPOINT_DATA_BASE_IDX 2
+
+
+// addressBlock: dce_dc_hda_azf0endpoint3_dispdec
+// base address: 0x48
+#define regAZF0ENDPOINT3_AZALIA_F0_CODEC_ENDPOINT_INDEX 0x0398
+#define regAZF0ENDPOINT3_AZALIA_F0_CODEC_ENDPOINT_INDEX_BASE_IDX 2
+#define regAZF0ENDPOINT3_AZALIA_F0_CODEC_ENDPOINT_DATA 0x0399
+#define regAZF0ENDPOINT3_AZALIA_F0_CODEC_ENDPOINT_DATA_BASE_IDX 2
+
+
+// addressBlock: dce_dc_hda_azf0endpoint4_dispdec
+// base address: 0x60
+#define regAZF0ENDPOINT4_AZALIA_F0_CODEC_ENDPOINT_INDEX 0x039e
+#define regAZF0ENDPOINT4_AZALIA_F0_CODEC_ENDPOINT_INDEX_BASE_IDX 2
+#define regAZF0ENDPOINT4_AZALIA_F0_CODEC_ENDPOINT_DATA 0x039f
+#define regAZF0ENDPOINT4_AZALIA_F0_CODEC_ENDPOINT_DATA_BASE_IDX 2
+
+
+// addressBlock: dce_dc_hda_azf0endpoint5_dispdec
+// base address: 0x78
+#define regAZF0ENDPOINT5_AZALIA_F0_CODEC_ENDPOINT_INDEX 0x03a4
+#define regAZF0ENDPOINT5_AZALIA_F0_CODEC_ENDPOINT_INDEX_BASE_IDX 2
+#define regAZF0ENDPOINT5_AZALIA_F0_CODEC_ENDPOINT_DATA 0x03a5
+#define regAZF0ENDPOINT5_AZALIA_F0_CODEC_ENDPOINT_DATA_BASE_IDX 2
+
+
+// addressBlock: dce_dc_hda_azf0endpoint6_dispdec
+// base address: 0x90
+#define regAZF0ENDPOINT6_AZALIA_F0_CODEC_ENDPOINT_INDEX 0x03aa
+#define regAZF0ENDPOINT6_AZALIA_F0_CODEC_ENDPOINT_INDEX_BASE_IDX 2
+#define regAZF0ENDPOINT6_AZALIA_F0_CODEC_ENDPOINT_DATA 0x03ab
+#define regAZF0ENDPOINT6_AZALIA_F0_CODEC_ENDPOINT_DATA_BASE_IDX 2
+
+
+// addressBlock: dce_dc_hda_azf0endpoint7_dispdec
+// base address: 0xa8
+#define regAZF0ENDPOINT7_AZALIA_F0_CODEC_ENDPOINT_INDEX 0x03b0
+#define regAZF0ENDPOINT7_AZALIA_F0_CODEC_ENDPOINT_INDEX_BASE_IDX 2
+#define regAZF0ENDPOINT7_AZALIA_F0_CODEC_ENDPOINT_DATA 0x03b1
+#define regAZF0ENDPOINT7_AZALIA_F0_CODEC_ENDPOINT_DATA_BASE_IDX 2
+
+
+// addressBlock: dce_dc_hda_azf0inputendpoint0_dispdec
+// base address: 0x0
+#define regAZF0INPUTENDPOINT0_AZALIA_F0_CODEC_INPUT_ENDPOINT_INDEX 0x043a
+#define regAZF0INPUTENDPOINT0_AZALIA_F0_CODEC_INPUT_ENDPOINT_INDEX_BASE_IDX 2
+#define regAZF0INPUTENDPOINT0_AZALIA_F0_CODEC_INPUT_ENDPOINT_DATA 0x043b
+#define regAZF0INPUTENDPOINT0_AZALIA_F0_CODEC_INPUT_ENDPOINT_DATA_BASE_IDX 2
+
+
+// addressBlock: dce_dc_hda_azf0inputendpoint1_dispdec
+// base address: 0x10
+#define regAZF0INPUTENDPOINT1_AZALIA_F0_CODEC_INPUT_ENDPOINT_INDEX 0x043e
+#define regAZF0INPUTENDPOINT1_AZALIA_F0_CODEC_INPUT_ENDPOINT_INDEX_BASE_IDX 2
+#define regAZF0INPUTENDPOINT1_AZALIA_F0_CODEC_INPUT_ENDPOINT_DATA 0x043f
+#define regAZF0INPUTENDPOINT1_AZALIA_F0_CODEC_INPUT_ENDPOINT_DATA_BASE_IDX 2
+
+
+// addressBlock: dce_dc_hda_azf0inputendpoint2_dispdec
+// base address: 0x20
+#define regAZF0INPUTENDPOINT2_AZALIA_F0_CODEC_INPUT_ENDPOINT_INDEX 0x0442
+#define regAZF0INPUTENDPOINT2_AZALIA_F0_CODEC_INPUT_ENDPOINT_INDEX_BASE_IDX 2
+#define regAZF0INPUTENDPOINT2_AZALIA_F0_CODEC_INPUT_ENDPOINT_DATA 0x0443
+#define regAZF0INPUTENDPOINT2_AZALIA_F0_CODEC_INPUT_ENDPOINT_DATA_BASE_IDX 2
+
+
+// addressBlock: dce_dc_hda_azf0inputendpoint3_dispdec
+// base address: 0x30
+#define regAZF0INPUTENDPOINT3_AZALIA_F0_CODEC_INPUT_ENDPOINT_INDEX 0x0446
+#define regAZF0INPUTENDPOINT3_AZALIA_F0_CODEC_INPUT_ENDPOINT_INDEX_BASE_IDX 2
+#define regAZF0INPUTENDPOINT3_AZALIA_F0_CODEC_INPUT_ENDPOINT_DATA 0x0447
+#define regAZF0INPUTENDPOINT3_AZALIA_F0_CODEC_INPUT_ENDPOINT_DATA_BASE_IDX 2
+
+
+// addressBlock: dce_dc_hda_azf0inputendpoint4_dispdec
+// base address: 0x40
+#define regAZF0INPUTENDPOINT4_AZALIA_F0_CODEC_INPUT_ENDPOINT_INDEX 0x044a
+#define regAZF0INPUTENDPOINT4_AZALIA_F0_CODEC_INPUT_ENDPOINT_INDEX_BASE_IDX 2
+#define regAZF0INPUTENDPOINT4_AZALIA_F0_CODEC_INPUT_ENDPOINT_DATA 0x044b
+#define regAZF0INPUTENDPOINT4_AZALIA_F0_CODEC_INPUT_ENDPOINT_DATA_BASE_IDX 2
+
+
+// addressBlock: dce_dc_hda_azf0inputendpoint5_dispdec
+// base address: 0x50
+#define regAZF0INPUTENDPOINT5_AZALIA_F0_CODEC_INPUT_ENDPOINT_INDEX 0x044e
+#define regAZF0INPUTENDPOINT5_AZALIA_F0_CODEC_INPUT_ENDPOINT_INDEX_BASE_IDX 2
+#define regAZF0INPUTENDPOINT5_AZALIA_F0_CODEC_INPUT_ENDPOINT_DATA 0x044f
+#define regAZF0INPUTENDPOINT5_AZALIA_F0_CODEC_INPUT_ENDPOINT_DATA_BASE_IDX 2
+
+
+// addressBlock: dce_dc_hda_azf0inputendpoint6_dispdec
+// base address: 0x60
+#define regAZF0INPUTENDPOINT6_AZALIA_F0_CODEC_INPUT_ENDPOINT_INDEX 0x0452
+#define regAZF0INPUTENDPOINT6_AZALIA_F0_CODEC_INPUT_ENDPOINT_INDEX_BASE_IDX 2
+#define regAZF0INPUTENDPOINT6_AZALIA_F0_CODEC_INPUT_ENDPOINT_DATA 0x0453
+#define regAZF0INPUTENDPOINT6_AZALIA_F0_CODEC_INPUT_ENDPOINT_DATA_BASE_IDX 2
+
+
+// addressBlock: dce_dc_hda_azf0inputendpoint7_dispdec
+// base address: 0x70
+#define regAZF0INPUTENDPOINT7_AZALIA_F0_CODEC_INPUT_ENDPOINT_INDEX 0x0456
+#define regAZF0INPUTENDPOINT7_AZALIA_F0_CODEC_INPUT_ENDPOINT_INDEX_BASE_IDX 2
+#define regAZF0INPUTENDPOINT7_AZALIA_F0_CODEC_INPUT_ENDPOINT_DATA 0x0457
+#define regAZF0INPUTENDPOINT7_AZALIA_F0_CODEC_INPUT_ENDPOINT_DATA_BASE_IDX 2
+
+
+// addressBlock: dce_dc_dchubbubl_hubbub_dispdec
+// base address: 0x0
+#define regDCHUBBUB_ARB_DF_REQ_OUTSTAND 0x04f9
+#define regDCHUBBUB_ARB_DF_REQ_OUTSTAND_BASE_IDX 2
+#define regDCHUBBUB_ARB_SAT_LEVEL 0x04fa
+#define regDCHUBBUB_ARB_SAT_LEVEL_BASE_IDX 2
+#define regDCHUBBUB_ARB_QOS_FORCE 0x04fb
+#define regDCHUBBUB_ARB_QOS_FORCE_BASE_IDX 2
+#define regDCHUBBUB_ARB_DRAM_STATE_CNTL 0x04fc
+#define regDCHUBBUB_ARB_DRAM_STATE_CNTL_BASE_IDX 2
+#define regDCHUBBUB_ARB_DATA_URGENCY_WATERMARK_A 0x04fd
+#define regDCHUBBUB_ARB_DATA_URGENCY_WATERMARK_A_BASE_IDX 2
+#define regDCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_A 0x04fe
+#define regDCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_A_BASE_IDX 2
+#define regDCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_A 0x04ff
+#define regDCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_A_BASE_IDX 2
+#define regDCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_Z8_A 0x0500
+#define regDCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_Z8_A_BASE_IDX 2
+#define regDCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_A 0x0501
+#define regDCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_A_BASE_IDX 2
+#define regDCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_Z8_A 0x0502
+#define regDCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_Z8_A_BASE_IDX 2
+#define regDCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_A 0x0503
+#define regDCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_A_BASE_IDX 2
+#define regDCHUBBUB_ARB_FRAC_URG_BW_NOM_A 0x0504
+#define regDCHUBBUB_ARB_FRAC_URG_BW_NOM_A_BASE_IDX 2
+#define regDCHUBBUB_ARB_FRAC_URG_BW_FLIP_A 0x0505
+#define regDCHUBBUB_ARB_FRAC_URG_BW_FLIP_A_BASE_IDX 2
+#define regDCHUBBUB_ARB_DATA_URGENCY_WATERMARK_B 0x0506
+#define regDCHUBBUB_ARB_DATA_URGENCY_WATERMARK_B_BASE_IDX 2
+#define regDCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_B 0x0507
+#define regDCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_B_BASE_IDX 2
+#define regDCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_B 0x0508
+#define regDCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_B_BASE_IDX 2
+#define regDCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_Z8_B 0x0509
+#define regDCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_Z8_B_BASE_IDX 2
+#define regDCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_B 0x050a
+#define regDCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_B_BASE_IDX 2
+#define regDCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_Z8_B 0x050b
+#define regDCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_Z8_B_BASE_IDX 2
+#define regDCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_B 0x050c
+#define regDCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_B_BASE_IDX 2
+#define regDCHUBBUB_ARB_FRAC_URG_BW_NOM_B 0x050d
+#define regDCHUBBUB_ARB_FRAC_URG_BW_NOM_B_BASE_IDX 2
+#define regDCHUBBUB_ARB_FRAC_URG_BW_FLIP_B 0x050e
+#define regDCHUBBUB_ARB_FRAC_URG_BW_FLIP_B_BASE_IDX 2
+#define regDCHUBBUB_ARB_DATA_URGENCY_WATERMARK_C 0x050f
+#define regDCHUBBUB_ARB_DATA_URGENCY_WATERMARK_C_BASE_IDX 2
+#define regDCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_C 0x0510
+#define regDCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_C_BASE_IDX 2
+#define regDCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_C 0x0511
+#define regDCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_C_BASE_IDX 2
+#define regDCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_Z8_C 0x0512
+#define regDCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_Z8_C_BASE_IDX 2
+#define regDCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_C 0x0513
+#define regDCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_C_BASE_IDX 2
+#define regDCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_Z8_C 0x0514
+#define regDCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_Z8_C_BASE_IDX 2
+#define regDCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_C 0x0515
+#define regDCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_C_BASE_IDX 2
+#define regDCHUBBUB_ARB_FRAC_URG_BW_NOM_C 0x0516
+#define regDCHUBBUB_ARB_FRAC_URG_BW_NOM_C_BASE_IDX 2
+#define regDCHUBBUB_ARB_FRAC_URG_BW_FLIP_C 0x0517
+#define regDCHUBBUB_ARB_FRAC_URG_BW_FLIP_C_BASE_IDX 2
+#define regDCHUBBUB_ARB_DATA_URGENCY_WATERMARK_D 0x0518
+#define regDCHUBBUB_ARB_DATA_URGENCY_WATERMARK_D_BASE_IDX 2
+#define regDCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_D 0x0519
+#define regDCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_D_BASE_IDX 2
+#define regDCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_D 0x051a
+#define regDCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_D_BASE_IDX 2
+#define regDCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_Z8_D 0x051b
+#define regDCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_Z8_D_BASE_IDX 2
+#define regDCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_D 0x051c
+#define regDCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_D_BASE_IDX 2
+#define regDCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_Z8_D 0x051d
+#define regDCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_Z8_D_BASE_IDX 2
+#define regDCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_D 0x051e
+#define regDCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_D_BASE_IDX 2
+#define regDCHUBBUB_ARB_FRAC_URG_BW_NOM_D 0x051f
+#define regDCHUBBUB_ARB_FRAC_URG_BW_NOM_D_BASE_IDX 2
+#define regDCHUBBUB_ARB_FRAC_URG_BW_FLIP_D 0x0520
+#define regDCHUBBUB_ARB_FRAC_URG_BW_FLIP_D_BASE_IDX 2
+#define regDCHUBBUB_ARB_HOSTVM_CNTL 0x0521
+#define regDCHUBBUB_ARB_HOSTVM_CNTL_BASE_IDX 2
+#define regDCHUBBUB_ARB_WATERMARK_CHANGE_CNTL 0x0522
+#define regDCHUBBUB_ARB_WATERMARK_CHANGE_CNTL_BASE_IDX 2
+#define regDCHUBBUB_ARB_TIMEOUT_ENABLE 0x0523
+#define regDCHUBBUB_ARB_TIMEOUT_ENABLE_BASE_IDX 2
+#define regDCHUBBUB_GLOBAL_TIMER_CNTL 0x0524
+#define regDCHUBBUB_GLOBAL_TIMER_CNTL_BASE_IDX 2
+#define regSURFACE_CHECK0_ADDRESS_LSB 0x0525
+#define regSURFACE_CHECK0_ADDRESS_LSB_BASE_IDX 2
+#define regSURFACE_CHECK0_ADDRESS_MSB 0x0526
+#define regSURFACE_CHECK0_ADDRESS_MSB_BASE_IDX 2
+#define regSURFACE_CHECK1_ADDRESS_LSB 0x0527
+#define regSURFACE_CHECK1_ADDRESS_LSB_BASE_IDX 2
+#define regSURFACE_CHECK1_ADDRESS_MSB 0x0528
+#define regSURFACE_CHECK1_ADDRESS_MSB_BASE_IDX 2
+#define regSURFACE_CHECK2_ADDRESS_LSB 0x0529
+#define regSURFACE_CHECK2_ADDRESS_LSB_BASE_IDX 2
+#define regSURFACE_CHECK2_ADDRESS_MSB 0x052a
+#define regSURFACE_CHECK2_ADDRESS_MSB_BASE_IDX 2
+#define regSURFACE_CHECK3_ADDRESS_LSB 0x052b
+#define regSURFACE_CHECK3_ADDRESS_LSB_BASE_IDX 2
+#define regSURFACE_CHECK3_ADDRESS_MSB 0x052c
+#define regSURFACE_CHECK3_ADDRESS_MSB_BASE_IDX 2
+#define regVTG0_CONTROL 0x052d
+#define regVTG0_CONTROL_BASE_IDX 2
+#define regVTG1_CONTROL 0x052e
+#define regVTG1_CONTROL_BASE_IDX 2
+#define regVTG2_CONTROL 0x052f
+#define regVTG2_CONTROL_BASE_IDX 2
+#define regVTG3_CONTROL 0x0530
+#define regVTG3_CONTROL_BASE_IDX 2
+#define regDCHUBBUB_SOFT_RESET 0x0531
+#define regDCHUBBUB_SOFT_RESET_BASE_IDX 2
+#define regDCHUBBUB_CLOCK_CNTL 0x0532
+#define regDCHUBBUB_CLOCK_CNTL_BASE_IDX 2
+#define regDCFCLK_CNTL 0x0533
+#define regDCFCLK_CNTL_BASE_IDX 2
+#define regDCHUBBUB_PERFORMANCE_MEASUREMENT_CNTL 0x0534
+#define regDCHUBBUB_PERFORMANCE_MEASUREMENT_CNTL_BASE_IDX 2
+#define regDCHUBBUB_PERFORMANCE_MEASUREMENT_CNTL2 0x0535
+#define regDCHUBBUB_PERFORMANCE_MEASUREMENT_CNTL2_BASE_IDX 2
+#define regDCHUBBUB_VLINE_SNAPSHOT 0x0536
+#define regDCHUBBUB_VLINE_SNAPSHOT_BASE_IDX 2
+#define regDCHUBBUB_CTRL_STATUS 0x0537
+#define regDCHUBBUB_CTRL_STATUS_BASE_IDX 2
+#define regDCHUBBUB_TIMEOUT_DETECTION_CTRL1 0x053d
+#define regDCHUBBUB_TIMEOUT_DETECTION_CTRL1_BASE_IDX 2
+#define regDCHUBBUB_TIMEOUT_DETECTION_CTRL2 0x053e
+#define regDCHUBBUB_TIMEOUT_DETECTION_CTRL2_BASE_IDX 2
+#define regFMON_CTRL 0x0540
+#define regFMON_CTRL_BASE_IDX 2
+#define regDCHUBBUB_TEST_DEBUG_INDEX 0x0541
+#define regDCHUBBUB_TEST_DEBUG_INDEX_BASE_IDX 2
+#define regDCHUBBUB_TEST_DEBUG_DATA 0x0542
+#define regDCHUBBUB_TEST_DEBUG_DATA_BASE_IDX 2
+
+
+// addressBlock: dce_dc_dchubbubl_hubbub_sdpif_dispdec
+// base address: 0x0
+#define regDCHUBBUB_SDPIF_CFG0 0x046f
+#define regDCHUBBUB_SDPIF_CFG0_BASE_IDX 2
+#define regDCHUBBUB_SDPIF_CFG1 0x0470
+#define regDCHUBBUB_SDPIF_CFG1_BASE_IDX 2
+#define regDCHUBBUB_SDPIF_CFG2 0x0471
+#define regDCHUBBUB_SDPIF_CFG2_BASE_IDX 2
+#define regVM_REQUEST_PHYSICAL 0x0472
+#define regVM_REQUEST_PHYSICAL_BASE_IDX 2
+#define regDCHUBBUB_FORCE_IO_STATUS_0 0x0473
+#define regDCHUBBUB_FORCE_IO_STATUS_0_BASE_IDX 2
+#define regDCHUBBUB_FORCE_IO_STATUS_1 0x0474
+#define regDCHUBBUB_FORCE_IO_STATUS_1_BASE_IDX 2
+#define regDCN_VM_FB_LOCATION_BASE 0x0475
+#define regDCN_VM_FB_LOCATION_BASE_BASE_IDX 2
+#define regDCN_VM_FB_LOCATION_TOP 0x0476
+#define regDCN_VM_FB_LOCATION_TOP_BASE_IDX 2
+#define regDCN_VM_FB_OFFSET 0x0477
+#define regDCN_VM_FB_OFFSET_BASE_IDX 2
+#define regDCN_VM_AGP_BOT 0x0478
+#define regDCN_VM_AGP_BOT_BASE_IDX 2
+#define regDCN_VM_AGP_TOP 0x0479
+#define regDCN_VM_AGP_TOP_BASE_IDX 2
+#define regDCN_VM_AGP_BASE 0x047a
+#define regDCN_VM_AGP_BASE_BASE_IDX 2
+#define regDCN_VM_LOCAL_HBM_ADDRESS_START 0x047b
+#define regDCN_VM_LOCAL_HBM_ADDRESS_START_BASE_IDX 2
+#define regDCN_VM_LOCAL_HBM_ADDRESS_END 0x047c
+#define regDCN_VM_LOCAL_HBM_ADDRESS_END_BASE_IDX 2
+#define regDCN_VM_LOCAL_HBM_ADDRESS_LOCK_CNTL 0x047d
+#define regDCN_VM_LOCAL_HBM_ADDRESS_LOCK_CNTL_BASE_IDX 2
+#define regDCHUBBUB_SDPIF_PIPE_SEC_LVL 0x047e
+#define regDCHUBBUB_SDPIF_PIPE_SEC_LVL_BASE_IDX 2
+#define regDCHUBBUB_SDPIF_PIPE_DMDATA_SEC_LVL 0x047f
+#define regDCHUBBUB_SDPIF_PIPE_DMDATA_SEC_LVL_BASE_IDX 2
+#define regDCHUBBUB_SDPIF_MEM_PWR_CTRL 0x0483
+#define regDCHUBBUB_SDPIF_MEM_PWR_CTRL_BASE_IDX 2
+#define regDCHUBBUB_SDPIF_MEM_PWR_STATUS 0x0484
+#define regDCHUBBUB_SDPIF_MEM_PWR_STATUS_BASE_IDX 2
+
+
+// addressBlock: dce_dc_dchubbubl_hubbub_ret_path_dispdec
+// base address: 0x0
+#define regDCHUBBUB_RET_PATH_DCC_CFG 0x04af
+#define regDCHUBBUB_RET_PATH_DCC_CFG_BASE_IDX 2
+#define regDCHUBBUB_RET_PATH_DCC_CFG0_0 0x04b0
+#define regDCHUBBUB_RET_PATH_DCC_CFG0_0_BASE_IDX 2
+#define regDCHUBBUB_RET_PATH_DCC_CFG0_1 0x04b1
+#define regDCHUBBUB_RET_PATH_DCC_CFG0_1_BASE_IDX 2
+#define regDCHUBBUB_RET_PATH_DCC_CFG1_0 0x04b2
+#define regDCHUBBUB_RET_PATH_DCC_CFG1_0_BASE_IDX 2
+#define regDCHUBBUB_RET_PATH_DCC_CFG1_1 0x04b3
+#define regDCHUBBUB_RET_PATH_DCC_CFG1_1_BASE_IDX 2
+#define regDCHUBBUB_RET_PATH_DCC_CFG2_0 0x04b4
+#define regDCHUBBUB_RET_PATH_DCC_CFG2_0_BASE_IDX 2
+#define regDCHUBBUB_RET_PATH_DCC_CFG2_1 0x04b5
+#define regDCHUBBUB_RET_PATH_DCC_CFG2_1_BASE_IDX 2
+#define regDCHUBBUB_RET_PATH_DCC_CFG3_0 0x04b6
+#define regDCHUBBUB_RET_PATH_DCC_CFG3_0_BASE_IDX 2
+#define regDCHUBBUB_RET_PATH_DCC_CFG3_1 0x04b7
+#define regDCHUBBUB_RET_PATH_DCC_CFG3_1_BASE_IDX 2
+#define regDCHUBBUB_RET_PATH_DCC_CFG4_0 0x04b8
+#define regDCHUBBUB_RET_PATH_DCC_CFG4_0_BASE_IDX 2
+#define regDCHUBBUB_RET_PATH_DCC_CFG4_1 0x04b9
+#define regDCHUBBUB_RET_PATH_DCC_CFG4_1_BASE_IDX 2
+#define regDCHUBBUB_RET_PATH_DCC_CFG5_0 0x04ba
+#define regDCHUBBUB_RET_PATH_DCC_CFG5_0_BASE_IDX 2
+#define regDCHUBBUB_RET_PATH_DCC_CFG5_1 0x04bb
+#define regDCHUBBUB_RET_PATH_DCC_CFG5_1_BASE_IDX 2
+#define regDCHUBBUB_RET_PATH_DCC_CFG6_0 0x04bc
+#define regDCHUBBUB_RET_PATH_DCC_CFG6_0_BASE_IDX 2
+#define regDCHUBBUB_RET_PATH_DCC_CFG6_1 0x04bd
+#define regDCHUBBUB_RET_PATH_DCC_CFG6_1_BASE_IDX 2
+#define regDCHUBBUB_RET_PATH_DCC_CFG7_0 0x04be
+#define regDCHUBBUB_RET_PATH_DCC_CFG7_0_BASE_IDX 2
+#define regDCHUBBUB_RET_PATH_DCC_CFG7_1 0x04bf
+#define regDCHUBBUB_RET_PATH_DCC_CFG7_1_BASE_IDX 2
+#define regDCHUBBUB_RET_PATH_MEM_PWR_CTRL 0x04c0
+#define regDCHUBBUB_RET_PATH_MEM_PWR_CTRL_BASE_IDX 2
+#define regDCHUBBUB_RET_PATH_MEM_PWR_STATUS 0x04c1
+#define regDCHUBBUB_RET_PATH_MEM_PWR_STATUS_BASE_IDX 2
+#define regDCHUBBUB_CRC_CTRL 0x04c2
+#define regDCHUBBUB_CRC_CTRL_BASE_IDX 2
+#define regDCHUBBUB_CRC0_VAL_R_G 0x04c3
+#define regDCHUBBUB_CRC0_VAL_R_G_BASE_IDX 2
+#define regDCHUBBUB_CRC0_VAL_B_A 0x04c4
+#define regDCHUBBUB_CRC0_VAL_B_A_BASE_IDX 2
+#define regDCHUBBUB_CRC1_VAL_R_G 0x04c5
+#define regDCHUBBUB_CRC1_VAL_R_G_BASE_IDX 2
+#define regDCHUBBUB_CRC1_VAL_B_A 0x04c6
+#define regDCHUBBUB_CRC1_VAL_B_A_BASE_IDX 2
+#define regDCHUBBUB_DCC_STAT_CNTL 0x04c7
+#define regDCHUBBUB_DCC_STAT_CNTL_BASE_IDX 2
+#define regDCHUBBUB_DCC_STAT0 0x04c8
+#define regDCHUBBUB_DCC_STAT0_BASE_IDX 2
+#define regDCHUBBUB_DCC_STAT1 0x04c9
+#define regDCHUBBUB_DCC_STAT1_BASE_IDX 2
+#define regDCHUBBUB_DCC_STAT2 0x04ca
+#define regDCHUBBUB_DCC_STAT2_BASE_IDX 2
+#define regDCHUBBUB_COMPBUF_CTRL 0x04cb
+#define regDCHUBBUB_COMPBUF_CTRL_BASE_IDX 2
+#define regDCHUBBUB_DET0_CTRL 0x04cc
+#define regDCHUBBUB_DET0_CTRL_BASE_IDX 2
+#define regDCHUBBUB_DET1_CTRL 0x04cd
+#define regDCHUBBUB_DET1_CTRL_BASE_IDX 2
+#define regDCHUBBUB_DET2_CTRL 0x04ce
+#define regDCHUBBUB_DET2_CTRL_BASE_IDX 2
+#define regDCHUBBUB_DET3_CTRL 0x04cf
+#define regDCHUBBUB_DET3_CTRL_BASE_IDX 2
+#define regDCHUBBUB_MEM_PWR_MODE_CTRL 0x04d1
+#define regDCHUBBUB_MEM_PWR_MODE_CTRL_BASE_IDX 2
+#define regCOMPBUF_MEM_PWR_CTRL_1 0x04d2
+#define regCOMPBUF_MEM_PWR_CTRL_1_BASE_IDX 2
+#define regCOMPBUF_MEM_PWR_CTRL_2 0x04d3
+#define regCOMPBUF_MEM_PWR_CTRL_2_BASE_IDX 2
+#define regDCHUBBUB_MEM_PWR_STATUS 0x04d4
+#define regDCHUBBUB_MEM_PWR_STATUS_BASE_IDX 2
+#define regCOMPBUF_RESERVED_SPACE 0x04d5
+#define regCOMPBUF_RESERVED_SPACE_BASE_IDX 2
+
+
+// addressBlock: dce_dc_dchubbubl_hubbub_vmrq_if_dispdec
+// base address: 0x0
+#define regDCN_VM_CONTEXT0_CNTL 0x0559
+#define regDCN_VM_CONTEXT0_CNTL_BASE_IDX 2
+#define regDCN_VM_CONTEXT0_PAGE_TABLE_BASE_ADDR_HI32 0x055a
+#define regDCN_VM_CONTEXT0_PAGE_TABLE_BASE_ADDR_HI32_BASE_IDX 2
+#define regDCN_VM_CONTEXT0_PAGE_TABLE_BASE_ADDR_LO32 0x055b
+#define regDCN_VM_CONTEXT0_PAGE_TABLE_BASE_ADDR_LO32_BASE_IDX 2
+#define regDCN_VM_CONTEXT0_PAGE_TABLE_START_ADDR_HI32 0x055c
+#define regDCN_VM_CONTEXT0_PAGE_TABLE_START_ADDR_HI32_BASE_IDX 2
+#define regDCN_VM_CONTEXT0_PAGE_TABLE_START_ADDR_LO32 0x055d
+#define regDCN_VM_CONTEXT0_PAGE_TABLE_START_ADDR_LO32_BASE_IDX 2
+#define regDCN_VM_CONTEXT0_PAGE_TABLE_END_ADDR_HI32 0x055e
+#define regDCN_VM_CONTEXT0_PAGE_TABLE_END_ADDR_HI32_BASE_IDX 2
+#define regDCN_VM_CONTEXT0_PAGE_TABLE_END_ADDR_LO32 0x055f
+#define regDCN_VM_CONTEXT0_PAGE_TABLE_END_ADDR_LO32_BASE_IDX 2
+#define regDCN_VM_CONTEXT1_CNTL 0x0560
+#define regDCN_VM_CONTEXT1_CNTL_BASE_IDX 2
+#define regDCN_VM_CONTEXT1_PAGE_TABLE_BASE_ADDR_HI32 0x0561
+#define regDCN_VM_CONTEXT1_PAGE_TABLE_BASE_ADDR_HI32_BASE_IDX 2
+#define regDCN_VM_CONTEXT1_PAGE_TABLE_BASE_ADDR_LO32 0x0562
+#define regDCN_VM_CONTEXT1_PAGE_TABLE_BASE_ADDR_LO32_BASE_IDX 2
+#define regDCN_VM_CONTEXT1_PAGE_TABLE_START_ADDR_HI32 0x0563
+#define regDCN_VM_CONTEXT1_PAGE_TABLE_START_ADDR_HI32_BASE_IDX 2
+#define regDCN_VM_CONTEXT1_PAGE_TABLE_START_ADDR_LO32 0x0564
+#define regDCN_VM_CONTEXT1_PAGE_TABLE_START_ADDR_LO32_BASE_IDX 2
+#define regDCN_VM_CONTEXT1_PAGE_TABLE_END_ADDR_HI32 0x0565
+#define regDCN_VM_CONTEXT1_PAGE_TABLE_END_ADDR_HI32_BASE_IDX 2
+#define regDCN_VM_CONTEXT1_PAGE_TABLE_END_ADDR_LO32 0x0566
+#define regDCN_VM_CONTEXT1_PAGE_TABLE_END_ADDR_LO32_BASE_IDX 2
+#define regDCN_VM_CONTEXT2_CNTL 0x0567
+#define regDCN_VM_CONTEXT2_CNTL_BASE_IDX 2
+#define regDCN_VM_CONTEXT2_PAGE_TABLE_BASE_ADDR_HI32 0x0568
+#define regDCN_VM_CONTEXT2_PAGE_TABLE_BASE_ADDR_HI32_BASE_IDX 2
+#define regDCN_VM_CONTEXT2_PAGE_TABLE_BASE_ADDR_LO32 0x0569
+#define regDCN_VM_CONTEXT2_PAGE_TABLE_BASE_ADDR_LO32_BASE_IDX 2
+#define regDCN_VM_CONTEXT2_PAGE_TABLE_START_ADDR_HI32 0x056a
+#define regDCN_VM_CONTEXT2_PAGE_TABLE_START_ADDR_HI32_BASE_IDX 2
+#define regDCN_VM_CONTEXT2_PAGE_TABLE_START_ADDR_LO32 0x056b
+#define regDCN_VM_CONTEXT2_PAGE_TABLE_START_ADDR_LO32_BASE_IDX 2
+#define regDCN_VM_CONTEXT2_PAGE_TABLE_END_ADDR_HI32 0x056c
+#define regDCN_VM_CONTEXT2_PAGE_TABLE_END_ADDR_HI32_BASE_IDX 2
+#define regDCN_VM_CONTEXT2_PAGE_TABLE_END_ADDR_LO32 0x056d
+#define regDCN_VM_CONTEXT2_PAGE_TABLE_END_ADDR_LO32_BASE_IDX 2
+#define regDCN_VM_CONTEXT3_CNTL 0x056e
+#define regDCN_VM_CONTEXT3_CNTL_BASE_IDX 2
+#define regDCN_VM_CONTEXT3_PAGE_TABLE_BASE_ADDR_HI32 0x056f
+#define regDCN_VM_CONTEXT3_PAGE_TABLE_BASE_ADDR_HI32_BASE_IDX 2
+#define regDCN_VM_CONTEXT3_PAGE_TABLE_BASE_ADDR_LO32 0x0570
+#define regDCN_VM_CONTEXT3_PAGE_TABLE_BASE_ADDR_LO32_BASE_IDX 2
+#define regDCN_VM_CONTEXT3_PAGE_TABLE_START_ADDR_HI32 0x0571
+#define regDCN_VM_CONTEXT3_PAGE_TABLE_START_ADDR_HI32_BASE_IDX 2
+#define regDCN_VM_CONTEXT3_PAGE_TABLE_START_ADDR_LO32 0x0572
+#define regDCN_VM_CONTEXT3_PAGE_TABLE_START_ADDR_LO32_BASE_IDX 2
+#define regDCN_VM_CONTEXT3_PAGE_TABLE_END_ADDR_HI32 0x0573
+#define regDCN_VM_CONTEXT3_PAGE_TABLE_END_ADDR_HI32_BASE_IDX 2
+#define regDCN_VM_CONTEXT3_PAGE_TABLE_END_ADDR_LO32 0x0574
+#define regDCN_VM_CONTEXT3_PAGE_TABLE_END_ADDR_LO32_BASE_IDX 2
+#define regDCN_VM_CONTEXT4_CNTL 0x0575
+#define regDCN_VM_CONTEXT4_CNTL_BASE_IDX 2
+#define regDCN_VM_CONTEXT4_PAGE_TABLE_BASE_ADDR_HI32 0x0576
+#define regDCN_VM_CONTEXT4_PAGE_TABLE_BASE_ADDR_HI32_BASE_IDX 2
+#define regDCN_VM_CONTEXT4_PAGE_TABLE_BASE_ADDR_LO32 0x0577
+#define regDCN_VM_CONTEXT4_PAGE_TABLE_BASE_ADDR_LO32_BASE_IDX 2
+#define regDCN_VM_CONTEXT4_PAGE_TABLE_START_ADDR_HI32 0x0578
+#define regDCN_VM_CONTEXT4_PAGE_TABLE_START_ADDR_HI32_BASE_IDX 2
+#define regDCN_VM_CONTEXT4_PAGE_TABLE_START_ADDR_LO32 0x0579
+#define regDCN_VM_CONTEXT4_PAGE_TABLE_START_ADDR_LO32_BASE_IDX 2
+#define regDCN_VM_CONTEXT4_PAGE_TABLE_END_ADDR_HI32 0x057a
+#define regDCN_VM_CONTEXT4_PAGE_TABLE_END_ADDR_HI32_BASE_IDX 2
+#define regDCN_VM_CONTEXT4_PAGE_TABLE_END_ADDR_LO32 0x057b
+#define regDCN_VM_CONTEXT4_PAGE_TABLE_END_ADDR_LO32_BASE_IDX 2
+#define regDCN_VM_CONTEXT5_CNTL 0x057c
+#define regDCN_VM_CONTEXT5_CNTL_BASE_IDX 2
+#define regDCN_VM_CONTEXT5_PAGE_TABLE_BASE_ADDR_HI32 0x057d
+#define regDCN_VM_CONTEXT5_PAGE_TABLE_BASE_ADDR_HI32_BASE_IDX 2
+#define regDCN_VM_CONTEXT5_PAGE_TABLE_BASE_ADDR_LO32 0x057e
+#define regDCN_VM_CONTEXT5_PAGE_TABLE_BASE_ADDR_LO32_BASE_IDX 2
+#define regDCN_VM_CONTEXT5_PAGE_TABLE_START_ADDR_HI32 0x057f
+#define regDCN_VM_CONTEXT5_PAGE_TABLE_START_ADDR_HI32_BASE_IDX 2
+#define regDCN_VM_CONTEXT5_PAGE_TABLE_START_ADDR_LO32 0x0580
+#define regDCN_VM_CONTEXT5_PAGE_TABLE_START_ADDR_LO32_BASE_IDX 2
+#define regDCN_VM_CONTEXT5_PAGE_TABLE_END_ADDR_HI32 0x0581
+#define regDCN_VM_CONTEXT5_PAGE_TABLE_END_ADDR_HI32_BASE_IDX 2
+#define regDCN_VM_CONTEXT5_PAGE_TABLE_END_ADDR_LO32 0x0582
+#define regDCN_VM_CONTEXT5_PAGE_TABLE_END_ADDR_LO32_BASE_IDX 2
+#define regDCN_VM_CONTEXT6_CNTL 0x0583
+#define regDCN_VM_CONTEXT6_CNTL_BASE_IDX 2
+#define regDCN_VM_CONTEXT6_PAGE_TABLE_BASE_ADDR_HI32 0x0584
+#define regDCN_VM_CONTEXT6_PAGE_TABLE_BASE_ADDR_HI32_BASE_IDX 2
+#define regDCN_VM_CONTEXT6_PAGE_TABLE_BASE_ADDR_LO32 0x0585
+#define regDCN_VM_CONTEXT6_PAGE_TABLE_BASE_ADDR_LO32_BASE_IDX 2
+#define regDCN_VM_CONTEXT6_PAGE_TABLE_START_ADDR_HI32 0x0586
+#define regDCN_VM_CONTEXT6_PAGE_TABLE_START_ADDR_HI32_BASE_IDX 2
+#define regDCN_VM_CONTEXT6_PAGE_TABLE_START_ADDR_LO32 0x0587
+#define regDCN_VM_CONTEXT6_PAGE_TABLE_START_ADDR_LO32_BASE_IDX 2
+#define regDCN_VM_CONTEXT6_PAGE_TABLE_END_ADDR_HI32 0x0588
+#define regDCN_VM_CONTEXT6_PAGE_TABLE_END_ADDR_HI32_BASE_IDX 2
+#define regDCN_VM_CONTEXT6_PAGE_TABLE_END_ADDR_LO32 0x0589
+#define regDCN_VM_CONTEXT6_PAGE_TABLE_END_ADDR_LO32_BASE_IDX 2
+#define regDCN_VM_CONTEXT7_CNTL 0x058a
+#define regDCN_VM_CONTEXT7_CNTL_BASE_IDX 2
+#define regDCN_VM_CONTEXT7_PAGE_TABLE_BASE_ADDR_HI32 0x058b
+#define regDCN_VM_CONTEXT7_PAGE_TABLE_BASE_ADDR_HI32_BASE_IDX 2
+#define regDCN_VM_CONTEXT7_PAGE_TABLE_BASE_ADDR_LO32 0x058c
+#define regDCN_VM_CONTEXT7_PAGE_TABLE_BASE_ADDR_LO32_BASE_IDX 2
+#define regDCN_VM_CONTEXT7_PAGE_TABLE_START_ADDR_HI32 0x058d
+#define regDCN_VM_CONTEXT7_PAGE_TABLE_START_ADDR_HI32_BASE_IDX 2
+#define regDCN_VM_CONTEXT7_PAGE_TABLE_START_ADDR_LO32 0x058e
+#define regDCN_VM_CONTEXT7_PAGE_TABLE_START_ADDR_LO32_BASE_IDX 2
+#define regDCN_VM_CONTEXT7_PAGE_TABLE_END_ADDR_HI32 0x058f
+#define regDCN_VM_CONTEXT7_PAGE_TABLE_END_ADDR_HI32_BASE_IDX 2
+#define regDCN_VM_CONTEXT7_PAGE_TABLE_END_ADDR_LO32 0x0590
+#define regDCN_VM_CONTEXT7_PAGE_TABLE_END_ADDR_LO32_BASE_IDX 2
+#define regDCN_VM_CONTEXT8_CNTL 0x0591
+#define regDCN_VM_CONTEXT8_CNTL_BASE_IDX 2
+#define regDCN_VM_CONTEXT8_PAGE_TABLE_BASE_ADDR_HI32 0x0592
+#define regDCN_VM_CONTEXT8_PAGE_TABLE_BASE_ADDR_HI32_BASE_IDX 2
+#define regDCN_VM_CONTEXT8_PAGE_TABLE_BASE_ADDR_LO32 0x0593
+#define regDCN_VM_CONTEXT8_PAGE_TABLE_BASE_ADDR_LO32_BASE_IDX 2
+#define regDCN_VM_CONTEXT8_PAGE_TABLE_START_ADDR_HI32 0x0594
+#define regDCN_VM_CONTEXT8_PAGE_TABLE_START_ADDR_HI32_BASE_IDX 2
+#define regDCN_VM_CONTEXT8_PAGE_TABLE_START_ADDR_LO32 0x0595
+#define regDCN_VM_CONTEXT8_PAGE_TABLE_START_ADDR_LO32_BASE_IDX 2
+#define regDCN_VM_CONTEXT8_PAGE_TABLE_END_ADDR_HI32 0x0596
+#define regDCN_VM_CONTEXT8_PAGE_TABLE_END_ADDR_HI32_BASE_IDX 2
+#define regDCN_VM_CONTEXT8_PAGE_TABLE_END_ADDR_LO32 0x0597
+#define regDCN_VM_CONTEXT8_PAGE_TABLE_END_ADDR_LO32_BASE_IDX 2
+#define regDCN_VM_CONTEXT9_CNTL 0x0598
+#define regDCN_VM_CONTEXT9_CNTL_BASE_IDX 2
+#define regDCN_VM_CONTEXT9_PAGE_TABLE_BASE_ADDR_HI32 0x0599
+#define regDCN_VM_CONTEXT9_PAGE_TABLE_BASE_ADDR_HI32_BASE_IDX 2
+#define regDCN_VM_CONTEXT9_PAGE_TABLE_BASE_ADDR_LO32 0x059a
+#define regDCN_VM_CONTEXT9_PAGE_TABLE_BASE_ADDR_LO32_BASE_IDX 2
+#define regDCN_VM_CONTEXT9_PAGE_TABLE_START_ADDR_HI32 0x059b
+#define regDCN_VM_CONTEXT9_PAGE_TABLE_START_ADDR_HI32_BASE_IDX 2
+#define regDCN_VM_CONTEXT9_PAGE_TABLE_START_ADDR_LO32 0x059c
+#define regDCN_VM_CONTEXT9_PAGE_TABLE_START_ADDR_LO32_BASE_IDX 2
+#define regDCN_VM_CONTEXT9_PAGE_TABLE_END_ADDR_HI32 0x059d
+#define regDCN_VM_CONTEXT9_PAGE_TABLE_END_ADDR_HI32_BASE_IDX 2
+#define regDCN_VM_CONTEXT9_PAGE_TABLE_END_ADDR_LO32 0x059e
+#define regDCN_VM_CONTEXT9_PAGE_TABLE_END_ADDR_LO32_BASE_IDX 2
+#define regDCN_VM_CONTEXT10_CNTL 0x059f
+#define regDCN_VM_CONTEXT10_CNTL_BASE_IDX 2
+#define regDCN_VM_CONTEXT10_PAGE_TABLE_BASE_ADDR_HI32 0x05a0
+#define regDCN_VM_CONTEXT10_PAGE_TABLE_BASE_ADDR_HI32_BASE_IDX 2
+#define regDCN_VM_CONTEXT10_PAGE_TABLE_BASE_ADDR_LO32 0x05a1
+#define regDCN_VM_CONTEXT10_PAGE_TABLE_BASE_ADDR_LO32_BASE_IDX 2
+#define regDCN_VM_CONTEXT10_PAGE_TABLE_START_ADDR_HI32 0x05a2
+#define regDCN_VM_CONTEXT10_PAGE_TABLE_START_ADDR_HI32_BASE_IDX 2
+#define regDCN_VM_CONTEXT10_PAGE_TABLE_START_ADDR_LO32 0x05a3
+#define regDCN_VM_CONTEXT10_PAGE_TABLE_START_ADDR_LO32_BASE_IDX 2
+#define regDCN_VM_CONTEXT10_PAGE_TABLE_END_ADDR_HI32 0x05a4
+#define regDCN_VM_CONTEXT10_PAGE_TABLE_END_ADDR_HI32_BASE_IDX 2
+#define regDCN_VM_CONTEXT10_PAGE_TABLE_END_ADDR_LO32 0x05a5
+#define regDCN_VM_CONTEXT10_PAGE_TABLE_END_ADDR_LO32_BASE_IDX 2
+#define regDCN_VM_CONTEXT11_CNTL 0x05a6
+#define regDCN_VM_CONTEXT11_CNTL_BASE_IDX 2
+#define regDCN_VM_CONTEXT11_PAGE_TABLE_BASE_ADDR_HI32 0x05a7
+#define regDCN_VM_CONTEXT11_PAGE_TABLE_BASE_ADDR_HI32_BASE_IDX 2
+#define regDCN_VM_CONTEXT11_PAGE_TABLE_BASE_ADDR_LO32 0x05a8
+#define regDCN_VM_CONTEXT11_PAGE_TABLE_BASE_ADDR_LO32_BASE_IDX 2
+#define regDCN_VM_CONTEXT11_PAGE_TABLE_START_ADDR_HI32 0x05a9
+#define regDCN_VM_CONTEXT11_PAGE_TABLE_START_ADDR_HI32_BASE_IDX 2
+#define regDCN_VM_CONTEXT11_PAGE_TABLE_START_ADDR_LO32 0x05aa
+#define regDCN_VM_CONTEXT11_PAGE_TABLE_START_ADDR_LO32_BASE_IDX 2
+#define regDCN_VM_CONTEXT11_PAGE_TABLE_END_ADDR_HI32 0x05ab
+#define regDCN_VM_CONTEXT11_PAGE_TABLE_END_ADDR_HI32_BASE_IDX 2
+#define regDCN_VM_CONTEXT11_PAGE_TABLE_END_ADDR_LO32 0x05ac
+#define regDCN_VM_CONTEXT11_PAGE_TABLE_END_ADDR_LO32_BASE_IDX 2
+#define regDCN_VM_CONTEXT12_CNTL 0x05ad
+#define regDCN_VM_CONTEXT12_CNTL_BASE_IDX 2
+#define regDCN_VM_CONTEXT12_PAGE_TABLE_BASE_ADDR_HI32 0x05ae
+#define regDCN_VM_CONTEXT12_PAGE_TABLE_BASE_ADDR_HI32_BASE_IDX 2
+#define regDCN_VM_CONTEXT12_PAGE_TABLE_BASE_ADDR_LO32 0x05af
+#define regDCN_VM_CONTEXT12_PAGE_TABLE_BASE_ADDR_LO32_BASE_IDX 2
+#define regDCN_VM_CONTEXT12_PAGE_TABLE_START_ADDR_HI32 0x05b0
+#define regDCN_VM_CONTEXT12_PAGE_TABLE_START_ADDR_HI32_BASE_IDX 2
+#define regDCN_VM_CONTEXT12_PAGE_TABLE_START_ADDR_LO32 0x05b1
+#define regDCN_VM_CONTEXT12_PAGE_TABLE_START_ADDR_LO32_BASE_IDX 2
+#define regDCN_VM_CONTEXT12_PAGE_TABLE_END_ADDR_HI32 0x05b2
+#define regDCN_VM_CONTEXT12_PAGE_TABLE_END_ADDR_HI32_BASE_IDX 2
+#define regDCN_VM_CONTEXT12_PAGE_TABLE_END_ADDR_LO32 0x05b3
+#define regDCN_VM_CONTEXT12_PAGE_TABLE_END_ADDR_LO32_BASE_IDX 2
+#define regDCN_VM_CONTEXT13_CNTL 0x05b4
+#define regDCN_VM_CONTEXT13_CNTL_BASE_IDX 2
+#define regDCN_VM_CONTEXT13_PAGE_TABLE_BASE_ADDR_HI32 0x05b5
+#define regDCN_VM_CONTEXT13_PAGE_TABLE_BASE_ADDR_HI32_BASE_IDX 2
+#define regDCN_VM_CONTEXT13_PAGE_TABLE_BASE_ADDR_LO32 0x05b6
+#define regDCN_VM_CONTEXT13_PAGE_TABLE_BASE_ADDR_LO32_BASE_IDX 2
+#define regDCN_VM_CONTEXT13_PAGE_TABLE_START_ADDR_HI32 0x05b7
+#define regDCN_VM_CONTEXT13_PAGE_TABLE_START_ADDR_HI32_BASE_IDX 2
+#define regDCN_VM_CONTEXT13_PAGE_TABLE_START_ADDR_LO32 0x05b8
+#define regDCN_VM_CONTEXT13_PAGE_TABLE_START_ADDR_LO32_BASE_IDX 2
+#define regDCN_VM_CONTEXT13_PAGE_TABLE_END_ADDR_HI32 0x05b9
+#define regDCN_VM_CONTEXT13_PAGE_TABLE_END_ADDR_HI32_BASE_IDX 2
+#define regDCN_VM_CONTEXT13_PAGE_TABLE_END_ADDR_LO32 0x05ba
+#define regDCN_VM_CONTEXT13_PAGE_TABLE_END_ADDR_LO32_BASE_IDX 2
+#define regDCN_VM_CONTEXT14_CNTL 0x05bb
+#define regDCN_VM_CONTEXT14_CNTL_BASE_IDX 2
+#define regDCN_VM_CONTEXT14_PAGE_TABLE_BASE_ADDR_HI32 0x05bc
+#define regDCN_VM_CONTEXT14_PAGE_TABLE_BASE_ADDR_HI32_BASE_IDX 2
+#define regDCN_VM_CONTEXT14_PAGE_TABLE_BASE_ADDR_LO32 0x05bd
+#define regDCN_VM_CONTEXT14_PAGE_TABLE_BASE_ADDR_LO32_BASE_IDX 2
+#define regDCN_VM_CONTEXT14_PAGE_TABLE_START_ADDR_HI32 0x05be
+#define regDCN_VM_CONTEXT14_PAGE_TABLE_START_ADDR_HI32_BASE_IDX 2
+#define regDCN_VM_CONTEXT14_PAGE_TABLE_START_ADDR_LO32 0x05bf
+#define regDCN_VM_CONTEXT14_PAGE_TABLE_START_ADDR_LO32_BASE_IDX 2
+#define regDCN_VM_CONTEXT14_PAGE_TABLE_END_ADDR_HI32 0x05c0
+#define regDCN_VM_CONTEXT14_PAGE_TABLE_END_ADDR_HI32_BASE_IDX 2
+#define regDCN_VM_CONTEXT14_PAGE_TABLE_END_ADDR_LO32 0x05c1
+#define regDCN_VM_CONTEXT14_PAGE_TABLE_END_ADDR_LO32_BASE_IDX 2
+#define regDCN_VM_CONTEXT15_CNTL 0x05c2
+#define regDCN_VM_CONTEXT15_CNTL_BASE_IDX 2
+#define regDCN_VM_CONTEXT15_PAGE_TABLE_BASE_ADDR_HI32 0x05c3
+#define regDCN_VM_CONTEXT15_PAGE_TABLE_BASE_ADDR_HI32_BASE_IDX 2
+#define regDCN_VM_CONTEXT15_PAGE_TABLE_BASE_ADDR_LO32 0x05c4
+#define regDCN_VM_CONTEXT15_PAGE_TABLE_BASE_ADDR_LO32_BASE_IDX 2
+#define regDCN_VM_CONTEXT15_PAGE_TABLE_START_ADDR_HI32 0x05c5
+#define regDCN_VM_CONTEXT15_PAGE_TABLE_START_ADDR_HI32_BASE_IDX 2
+#define regDCN_VM_CONTEXT15_PAGE_TABLE_START_ADDR_LO32 0x05c6
+#define regDCN_VM_CONTEXT15_PAGE_TABLE_START_ADDR_LO32_BASE_IDX 2
+#define regDCN_VM_CONTEXT15_PAGE_TABLE_END_ADDR_HI32 0x05c7
+#define regDCN_VM_CONTEXT15_PAGE_TABLE_END_ADDR_HI32_BASE_IDX 2
+#define regDCN_VM_CONTEXT15_PAGE_TABLE_END_ADDR_LO32 0x05c8
+#define regDCN_VM_CONTEXT15_PAGE_TABLE_END_ADDR_LO32_BASE_IDX 2
+#define regDCN_VM_DEFAULT_ADDR_MSB 0x05c9
+#define regDCN_VM_DEFAULT_ADDR_MSB_BASE_IDX 2
+#define regDCN_VM_DEFAULT_ADDR_LSB 0x05ca
+#define regDCN_VM_DEFAULT_ADDR_LSB_BASE_IDX 2
+#define regDCN_VM_FAULT_CNTL 0x05cb
+#define regDCN_VM_FAULT_CNTL_BASE_IDX 2
+#define regDCN_VM_FAULT_STATUS 0x05cc
+#define regDCN_VM_FAULT_STATUS_BASE_IDX 2
+#define regDCN_VM_FAULT_ADDR_MSB 0x05cd
+#define regDCN_VM_FAULT_ADDR_MSB_BASE_IDX 2
+#define regDCN_VM_FAULT_ADDR_LSB 0x05ce
+#define regDCN_VM_FAULT_ADDR_LSB_BASE_IDX 2
+
+
+// addressBlock: dce_dc_dchubbubl_dchubbub_dcperfmon_dc_perfmon_dispdec
+// base address: 0x1534
+#define regDC_PERFMON6_PERFCOUNTER_CNTL 0x054d
+#define regDC_PERFMON6_PERFCOUNTER_CNTL_BASE_IDX 2
+#define regDC_PERFMON6_PERFCOUNTER_CNTL2 0x054e
+#define regDC_PERFMON6_PERFCOUNTER_CNTL2_BASE_IDX 2
+#define regDC_PERFMON6_PERFCOUNTER_STATE 0x054f
+#define regDC_PERFMON6_PERFCOUNTER_STATE_BASE_IDX 2
+#define regDC_PERFMON6_PERFMON_CNTL 0x0550
+#define regDC_PERFMON6_PERFMON_CNTL_BASE_IDX 2
+#define regDC_PERFMON6_PERFMON_CNTL2 0x0551
+#define regDC_PERFMON6_PERFMON_CNTL2_BASE_IDX 2
+#define regDC_PERFMON6_PERFMON_CVALUE_INT_MISC 0x0552
+#define regDC_PERFMON6_PERFMON_CVALUE_INT_MISC_BASE_IDX 2
+#define regDC_PERFMON6_PERFMON_CVALUE_LOW 0x0553
+#define regDC_PERFMON6_PERFMON_CVALUE_LOW_BASE_IDX 2
+#define regDC_PERFMON6_PERFMON_HI 0x0554
+#define regDC_PERFMON6_PERFMON_HI_BASE_IDX 2
+#define regDC_PERFMON6_PERFMON_LOW 0x0555
+#define regDC_PERFMON6_PERFMON_LOW_BASE_IDX 2
+
+
+// addressBlock: dce_dc_dcbubp0_dispdec_hubp_dispdec
+// base address: 0x0
+#define regHUBP0_DCSURF_SURFACE_CONFIG 0x05e5
+#define regHUBP0_DCSURF_SURFACE_CONFIG_BASE_IDX 2
+#define regHUBP0_DCSURF_ADDR_CONFIG 0x05e6
+#define regHUBP0_DCSURF_ADDR_CONFIG_BASE_IDX 2
+#define regHUBP0_DCSURF_TILING_CONFIG 0x05e7
+#define regHUBP0_DCSURF_TILING_CONFIG_BASE_IDX 2
+#define regHUBP0_DCSURF_PRI_VIEWPORT_START 0x05e9
+#define regHUBP0_DCSURF_PRI_VIEWPORT_START_BASE_IDX 2
+#define regHUBP0_DCSURF_PRI_VIEWPORT_DIMENSION 0x05ea
+#define regHUBP0_DCSURF_PRI_VIEWPORT_DIMENSION_BASE_IDX 2
+#define regHUBP0_DCSURF_PRI_VIEWPORT_START_C 0x05eb
+#define regHUBP0_DCSURF_PRI_VIEWPORT_START_C_BASE_IDX 2
+#define regHUBP0_DCSURF_PRI_VIEWPORT_DIMENSION_C 0x05ec
+#define regHUBP0_DCSURF_PRI_VIEWPORT_DIMENSION_C_BASE_IDX 2
+#define regHUBP0_DCSURF_SEC_VIEWPORT_START 0x05ed
+#define regHUBP0_DCSURF_SEC_VIEWPORT_START_BASE_IDX 2
+#define regHUBP0_DCSURF_SEC_VIEWPORT_DIMENSION 0x05ee
+#define regHUBP0_DCSURF_SEC_VIEWPORT_DIMENSION_BASE_IDX 2
+#define regHUBP0_DCSURF_SEC_VIEWPORT_START_C 0x05ef
+#define regHUBP0_DCSURF_SEC_VIEWPORT_START_C_BASE_IDX 2
+#define regHUBP0_DCSURF_SEC_VIEWPORT_DIMENSION_C 0x05f0
+#define regHUBP0_DCSURF_SEC_VIEWPORT_DIMENSION_C_BASE_IDX 2
+#define regHUBP0_DCHUBP_REQ_SIZE_CONFIG 0x05f1
+#define regHUBP0_DCHUBP_REQ_SIZE_CONFIG_BASE_IDX 2
+#define regHUBP0_DCHUBP_REQ_SIZE_CONFIG_C 0x05f2
+#define regHUBP0_DCHUBP_REQ_SIZE_CONFIG_C_BASE_IDX 2
+#define regHUBP0_DCHUBP_CNTL 0x05f3
+#define regHUBP0_DCHUBP_CNTL_BASE_IDX 2
+#define regHUBP0_HUBP_CLK_CNTL 0x05f4
+#define regHUBP0_HUBP_CLK_CNTL_BASE_IDX 2
+#define regHUBP0_DCHUBP_VMPG_CONFIG 0x05f5
+#define regHUBP0_DCHUBP_VMPG_CONFIG_BASE_IDX 2
+#define regHUBP0_HUBPREQ_DEBUG_DB 0x05f6
+#define regHUBP0_HUBPREQ_DEBUG_DB_BASE_IDX 2
+#define regHUBP0_HUBPREQ_DEBUG 0x05f7
+#define regHUBP0_HUBPREQ_DEBUG_BASE_IDX 2
+#define regHUBP0_HUBP_MEASURE_WIN_CTRL_DCFCLK 0x05fb
+#define regHUBP0_HUBP_MEASURE_WIN_CTRL_DCFCLK_BASE_IDX 2
+#define regHUBP0_HUBP_MEASURE_WIN_CTRL_DPPCLK 0x05fc
+#define regHUBP0_HUBP_MEASURE_WIN_CTRL_DPPCLK_BASE_IDX 2
+
+
+// addressBlock: dce_dc_dcbubp0_dispdec_hubpreq_dispdec
+// base address: 0x0
+#define regHUBPREQ0_DCSURF_SURFACE_PITCH 0x0607
+#define regHUBPREQ0_DCSURF_SURFACE_PITCH_BASE_IDX 2
+#define regHUBPREQ0_DCSURF_SURFACE_PITCH_C 0x0608
+#define regHUBPREQ0_DCSURF_SURFACE_PITCH_C_BASE_IDX 2
+#define regHUBPREQ0_VMID_SETTINGS_0 0x0609
+#define regHUBPREQ0_VMID_SETTINGS_0_BASE_IDX 2
+#define regHUBPREQ0_DCSURF_PRIMARY_SURFACE_ADDRESS 0x060a
+#define regHUBPREQ0_DCSURF_PRIMARY_SURFACE_ADDRESS_BASE_IDX 2
+#define regHUBPREQ0_DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH 0x060b
+#define regHUBPREQ0_DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH_BASE_IDX 2
+#define regHUBPREQ0_DCSURF_PRIMARY_SURFACE_ADDRESS_C 0x060c
+#define regHUBPREQ0_DCSURF_PRIMARY_SURFACE_ADDRESS_C_BASE_IDX 2
+#define regHUBPREQ0_DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH_C 0x060d
+#define regHUBPREQ0_DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH_C_BASE_IDX 2
+#define regHUBPREQ0_DCSURF_SECONDARY_SURFACE_ADDRESS 0x060e
+#define regHUBPREQ0_DCSURF_SECONDARY_SURFACE_ADDRESS_BASE_IDX 2
+#define regHUBPREQ0_DCSURF_SECONDARY_SURFACE_ADDRESS_HIGH 0x060f
+#define regHUBPREQ0_DCSURF_SECONDARY_SURFACE_ADDRESS_HIGH_BASE_IDX 2
+#define regHUBPREQ0_DCSURF_SECONDARY_SURFACE_ADDRESS_C 0x0610
+#define regHUBPREQ0_DCSURF_SECONDARY_SURFACE_ADDRESS_C_BASE_IDX 2
+#define regHUBPREQ0_DCSURF_SECONDARY_SURFACE_ADDRESS_HIGH_C 0x0611
+#define regHUBPREQ0_DCSURF_SECONDARY_SURFACE_ADDRESS_HIGH_C_BASE_IDX 2
+#define regHUBPREQ0_DCSURF_PRIMARY_META_SURFACE_ADDRESS 0x0612
+#define regHUBPREQ0_DCSURF_PRIMARY_META_SURFACE_ADDRESS_BASE_IDX 2
+#define regHUBPREQ0_DCSURF_PRIMARY_META_SURFACE_ADDRESS_HIGH 0x0613
+#define regHUBPREQ0_DCSURF_PRIMARY_META_SURFACE_ADDRESS_HIGH_BASE_IDX 2
+#define regHUBPREQ0_DCSURF_PRIMARY_META_SURFACE_ADDRESS_C 0x0614
+#define regHUBPREQ0_DCSURF_PRIMARY_META_SURFACE_ADDRESS_C_BASE_IDX 2
+#define regHUBPREQ0_DCSURF_PRIMARY_META_SURFACE_ADDRESS_HIGH_C 0x0615
+#define regHUBPREQ0_DCSURF_PRIMARY_META_SURFACE_ADDRESS_HIGH_C_BASE_IDX 2
+#define regHUBPREQ0_DCSURF_SECONDARY_META_SURFACE_ADDRESS 0x0616
+#define regHUBPREQ0_DCSURF_SECONDARY_META_SURFACE_ADDRESS_BASE_IDX 2
+#define regHUBPREQ0_DCSURF_SECONDARY_META_SURFACE_ADDRESS_HIGH 0x0617
+#define regHUBPREQ0_DCSURF_SECONDARY_META_SURFACE_ADDRESS_HIGH_BASE_IDX 2
+#define regHUBPREQ0_DCSURF_SECONDARY_META_SURFACE_ADDRESS_C 0x0618
+#define regHUBPREQ0_DCSURF_SECONDARY_META_SURFACE_ADDRESS_C_BASE_IDX 2
+#define regHUBPREQ0_DCSURF_SECONDARY_META_SURFACE_ADDRESS_HIGH_C 0x0619
+#define regHUBPREQ0_DCSURF_SECONDARY_META_SURFACE_ADDRESS_HIGH_C_BASE_IDX 2
+#define regHUBPREQ0_DCSURF_SURFACE_CONTROL 0x061a
+#define regHUBPREQ0_DCSURF_SURFACE_CONTROL_BASE_IDX 2
+#define regHUBPREQ0_DCSURF_FLIP_CONTROL 0x061b
+#define regHUBPREQ0_DCSURF_FLIP_CONTROL_BASE_IDX 2
+#define regHUBPREQ0_DCSURF_FLIP_CONTROL2 0x061c
+#define regHUBPREQ0_DCSURF_FLIP_CONTROL2_BASE_IDX 2
+#define regHUBPREQ0_DCSURF_SURFACE_FLIP_INTERRUPT 0x0620
+#define regHUBPREQ0_DCSURF_SURFACE_FLIP_INTERRUPT_BASE_IDX 2
+#define regHUBPREQ0_DCSURF_SURFACE_INUSE 0x0621
+#define regHUBPREQ0_DCSURF_SURFACE_INUSE_BASE_IDX 2
+#define regHUBPREQ0_DCSURF_SURFACE_INUSE_HIGH 0x0622
+#define regHUBPREQ0_DCSURF_SURFACE_INUSE_HIGH_BASE_IDX 2
+#define regHUBPREQ0_DCSURF_SURFACE_INUSE_C 0x0623
+#define regHUBPREQ0_DCSURF_SURFACE_INUSE_C_BASE_IDX 2
+#define regHUBPREQ0_DCSURF_SURFACE_INUSE_HIGH_C 0x0624
+#define regHUBPREQ0_DCSURF_SURFACE_INUSE_HIGH_C_BASE_IDX 2
+#define regHUBPREQ0_DCSURF_SURFACE_EARLIEST_INUSE 0x0625
+#define regHUBPREQ0_DCSURF_SURFACE_EARLIEST_INUSE_BASE_IDX 2
+#define regHUBPREQ0_DCSURF_SURFACE_EARLIEST_INUSE_HIGH 0x0626
+#define regHUBPREQ0_DCSURF_SURFACE_EARLIEST_INUSE_HIGH_BASE_IDX 2
+#define regHUBPREQ0_DCSURF_SURFACE_EARLIEST_INUSE_C 0x0627
+#define regHUBPREQ0_DCSURF_SURFACE_EARLIEST_INUSE_C_BASE_IDX 2
+#define regHUBPREQ0_DCSURF_SURFACE_EARLIEST_INUSE_HIGH_C 0x0628
+#define regHUBPREQ0_DCSURF_SURFACE_EARLIEST_INUSE_HIGH_C_BASE_IDX 2
+#define regHUBPREQ0_DCN_EXPANSION_MODE 0x0629
+#define regHUBPREQ0_DCN_EXPANSION_MODE_BASE_IDX 2
+#define regHUBPREQ0_DCN_TTU_QOS_WM 0x062a
+#define regHUBPREQ0_DCN_TTU_QOS_WM_BASE_IDX 2
+#define regHUBPREQ0_DCN_GLOBAL_TTU_CNTL 0x062b
+#define regHUBPREQ0_DCN_GLOBAL_TTU_CNTL_BASE_IDX 2
+#define regHUBPREQ0_DCN_SURF0_TTU_CNTL0 0x062c
+#define regHUBPREQ0_DCN_SURF0_TTU_CNTL0_BASE_IDX 2
+#define regHUBPREQ0_DCN_SURF0_TTU_CNTL1 0x062d
+#define regHUBPREQ0_DCN_SURF0_TTU_CNTL1_BASE_IDX 2
+#define regHUBPREQ0_DCN_SURF1_TTU_CNTL0 0x062e
+#define regHUBPREQ0_DCN_SURF1_TTU_CNTL0_BASE_IDX 2
+#define regHUBPREQ0_DCN_SURF1_TTU_CNTL1 0x062f
+#define regHUBPREQ0_DCN_SURF1_TTU_CNTL1_BASE_IDX 2
+#define regHUBPREQ0_DCN_CUR0_TTU_CNTL0 0x0630
+#define regHUBPREQ0_DCN_CUR0_TTU_CNTL0_BASE_IDX 2
+#define regHUBPREQ0_DCN_CUR0_TTU_CNTL1 0x0631
+#define regHUBPREQ0_DCN_CUR0_TTU_CNTL1_BASE_IDX 2
+#define regHUBPREQ0_DCN_CUR1_TTU_CNTL0 0x0632
+#define regHUBPREQ0_DCN_CUR1_TTU_CNTL0_BASE_IDX 2
+#define regHUBPREQ0_DCN_CUR1_TTU_CNTL1 0x0633
+#define regHUBPREQ0_DCN_CUR1_TTU_CNTL1_BASE_IDX 2
+#define regHUBPREQ0_DCN_DMDATA_VM_CNTL 0x0634
+#define regHUBPREQ0_DCN_DMDATA_VM_CNTL_BASE_IDX 2
+#define regHUBPREQ0_DCN_VM_SYSTEM_APERTURE_LOW_ADDR 0x0635
+#define regHUBPREQ0_DCN_VM_SYSTEM_APERTURE_LOW_ADDR_BASE_IDX 2
+#define regHUBPREQ0_DCN_VM_SYSTEM_APERTURE_HIGH_ADDR 0x0636
+#define regHUBPREQ0_DCN_VM_SYSTEM_APERTURE_HIGH_ADDR_BASE_IDX 2
+#define regHUBPREQ0_DCN_VM_MX_L1_TLB_CNTL 0x0643
+#define regHUBPREQ0_DCN_VM_MX_L1_TLB_CNTL_BASE_IDX 2
+#define regHUBPREQ0_BLANK_OFFSET_0 0x0644
+#define regHUBPREQ0_BLANK_OFFSET_0_BASE_IDX 2
+#define regHUBPREQ0_BLANK_OFFSET_1 0x0645
+#define regHUBPREQ0_BLANK_OFFSET_1_BASE_IDX 2
+#define regHUBPREQ0_DST_DIMENSIONS 0x0646
+#define regHUBPREQ0_DST_DIMENSIONS_BASE_IDX 2
+#define regHUBPREQ0_DST_AFTER_SCALER 0x0647
+#define regHUBPREQ0_DST_AFTER_SCALER_BASE_IDX 2
+#define regHUBPREQ0_PREFETCH_SETTINGS 0x0648
+#define regHUBPREQ0_PREFETCH_SETTINGS_BASE_IDX 2
+#define regHUBPREQ0_PREFETCH_SETTINGS_C 0x0649
+#define regHUBPREQ0_PREFETCH_SETTINGS_C_BASE_IDX 2
+#define regHUBPREQ0_VBLANK_PARAMETERS_0 0x064a
+#define regHUBPREQ0_VBLANK_PARAMETERS_0_BASE_IDX 2
+#define regHUBPREQ0_VBLANK_PARAMETERS_1 0x064b
+#define regHUBPREQ0_VBLANK_PARAMETERS_1_BASE_IDX 2
+#define regHUBPREQ0_VBLANK_PARAMETERS_2 0x064c
+#define regHUBPREQ0_VBLANK_PARAMETERS_2_BASE_IDX 2
+#define regHUBPREQ0_VBLANK_PARAMETERS_3 0x064d
+#define regHUBPREQ0_VBLANK_PARAMETERS_3_BASE_IDX 2
+#define regHUBPREQ0_VBLANK_PARAMETERS_4 0x064e
+#define regHUBPREQ0_VBLANK_PARAMETERS_4_BASE_IDX 2
+#define regHUBPREQ0_FLIP_PARAMETERS_0 0x064f
+#define regHUBPREQ0_FLIP_PARAMETERS_0_BASE_IDX 2
+#define regHUBPREQ0_FLIP_PARAMETERS_1 0x0650
+#define regHUBPREQ0_FLIP_PARAMETERS_1_BASE_IDX 2
+#define regHUBPREQ0_FLIP_PARAMETERS_2 0x0651
+#define regHUBPREQ0_FLIP_PARAMETERS_2_BASE_IDX 2
+#define regHUBPREQ0_NOM_PARAMETERS_0 0x0652
+#define regHUBPREQ0_NOM_PARAMETERS_0_BASE_IDX 2
+#define regHUBPREQ0_NOM_PARAMETERS_1 0x0653
+#define regHUBPREQ0_NOM_PARAMETERS_1_BASE_IDX 2
+#define regHUBPREQ0_NOM_PARAMETERS_2 0x0654
+#define regHUBPREQ0_NOM_PARAMETERS_2_BASE_IDX 2
+#define regHUBPREQ0_NOM_PARAMETERS_3 0x0655
+#define regHUBPREQ0_NOM_PARAMETERS_3_BASE_IDX 2
+#define regHUBPREQ0_NOM_PARAMETERS_4 0x0656
+#define regHUBPREQ0_NOM_PARAMETERS_4_BASE_IDX 2
+#define regHUBPREQ0_NOM_PARAMETERS_5 0x0657
+#define regHUBPREQ0_NOM_PARAMETERS_5_BASE_IDX 2
+#define regHUBPREQ0_NOM_PARAMETERS_6 0x0658
+#define regHUBPREQ0_NOM_PARAMETERS_6_BASE_IDX 2
+#define regHUBPREQ0_NOM_PARAMETERS_7 0x0659
+#define regHUBPREQ0_NOM_PARAMETERS_7_BASE_IDX 2
+#define regHUBPREQ0_PER_LINE_DELIVERY_PRE 0x065a
+#define regHUBPREQ0_PER_LINE_DELIVERY_PRE_BASE_IDX 2
+#define regHUBPREQ0_PER_LINE_DELIVERY 0x065b
+#define regHUBPREQ0_PER_LINE_DELIVERY_BASE_IDX 2
+#define regHUBPREQ0_CURSOR_SETTINGS 0x065c
+#define regHUBPREQ0_CURSOR_SETTINGS_BASE_IDX 2
+#define regHUBPREQ0_REF_FREQ_TO_PIX_FREQ 0x065d
+#define regHUBPREQ0_REF_FREQ_TO_PIX_FREQ_BASE_IDX 2
+#define regHUBPREQ0_DST_Y_DELTA_DRQ_LIMIT 0x065e
+#define regHUBPREQ0_DST_Y_DELTA_DRQ_LIMIT_BASE_IDX 2
+#define regHUBPREQ0_HUBPREQ_MEM_PWR_CTRL 0x065f
+#define regHUBPREQ0_HUBPREQ_MEM_PWR_CTRL_BASE_IDX 2
+#define regHUBPREQ0_HUBPREQ_MEM_PWR_STATUS 0x0660
+#define regHUBPREQ0_HUBPREQ_MEM_PWR_STATUS_BASE_IDX 2
+#define regHUBPREQ0_VBLANK_PARAMETERS_5 0x0663
+#define regHUBPREQ0_VBLANK_PARAMETERS_5_BASE_IDX 2
+#define regHUBPREQ0_VBLANK_PARAMETERS_6 0x0664
+#define regHUBPREQ0_VBLANK_PARAMETERS_6_BASE_IDX 2
+#define regHUBPREQ0_FLIP_PARAMETERS_3 0x0665
+#define regHUBPREQ0_FLIP_PARAMETERS_3_BASE_IDX 2
+#define regHUBPREQ0_FLIP_PARAMETERS_4 0x0666
+#define regHUBPREQ0_FLIP_PARAMETERS_4_BASE_IDX 2
+#define regHUBPREQ0_FLIP_PARAMETERS_5 0x0667
+#define regHUBPREQ0_FLIP_PARAMETERS_5_BASE_IDX 2
+#define regHUBPREQ0_FLIP_PARAMETERS_6 0x0668
+#define regHUBPREQ0_FLIP_PARAMETERS_6_BASE_IDX 2
+
+
+// addressBlock: dce_dc_dcbubp0_dispdec_hubpret_dispdec
+// base address: 0x0
+#define regHUBPRET0_HUBPRET_CONTROL 0x066c
+#define regHUBPRET0_HUBPRET_CONTROL_BASE_IDX 2
+#define regHUBPRET0_HUBPRET_MEM_PWR_CTRL 0x066d
+#define regHUBPRET0_HUBPRET_MEM_PWR_CTRL_BASE_IDX 2
+#define regHUBPRET0_HUBPRET_MEM_PWR_STATUS 0x066e
+#define regHUBPRET0_HUBPRET_MEM_PWR_STATUS_BASE_IDX 2
+#define regHUBPRET0_HUBPRET_READ_LINE_CTRL0 0x066f
+#define regHUBPRET0_HUBPRET_READ_LINE_CTRL0_BASE_IDX 2
+#define regHUBPRET0_HUBPRET_READ_LINE_CTRL1 0x0670
+#define regHUBPRET0_HUBPRET_READ_LINE_CTRL1_BASE_IDX 2
+#define regHUBPRET0_HUBPRET_READ_LINE0 0x0671
+#define regHUBPRET0_HUBPRET_READ_LINE0_BASE_IDX 2
+#define regHUBPRET0_HUBPRET_READ_LINE1 0x0672
+#define regHUBPRET0_HUBPRET_READ_LINE1_BASE_IDX 2
+#define regHUBPRET0_HUBPRET_INTERRUPT 0x0673
+#define regHUBPRET0_HUBPRET_INTERRUPT_BASE_IDX 2
+#define regHUBPRET0_HUBPRET_READ_LINE_VALUE 0x0674
+#define regHUBPRET0_HUBPRET_READ_LINE_VALUE_BASE_IDX 2
+#define regHUBPRET0_HUBPRET_READ_LINE_STATUS 0x0675
+#define regHUBPRET0_HUBPRET_READ_LINE_STATUS_BASE_IDX 2
+
+
+// addressBlock: dce_dc_dcbubp0_dispdec_cursor0_dispdec
+// base address: 0x0
+#define regCURSOR0_0_CURSOR_CONTROL 0x0678
+#define regCURSOR0_0_CURSOR_CONTROL_BASE_IDX 2
+#define regCURSOR0_0_CURSOR_SURFACE_ADDRESS 0x0679
+#define regCURSOR0_0_CURSOR_SURFACE_ADDRESS_BASE_IDX 2
+#define regCURSOR0_0_CURSOR_SURFACE_ADDRESS_HIGH 0x067a
+#define regCURSOR0_0_CURSOR_SURFACE_ADDRESS_HIGH_BASE_IDX 2
+#define regCURSOR0_0_CURSOR_SIZE 0x067b
+#define regCURSOR0_0_CURSOR_SIZE_BASE_IDX 2
+#define regCURSOR0_0_CURSOR_POSITION 0x067c
+#define regCURSOR0_0_CURSOR_POSITION_BASE_IDX 2
+#define regCURSOR0_0_CURSOR_HOT_SPOT 0x067d
+#define regCURSOR0_0_CURSOR_HOT_SPOT_BASE_IDX 2
+#define regCURSOR0_0_CURSOR_STEREO_CONTROL 0x067e
+#define regCURSOR0_0_CURSOR_STEREO_CONTROL_BASE_IDX 2
+#define regCURSOR0_0_CURSOR_DST_OFFSET 0x067f
+#define regCURSOR0_0_CURSOR_DST_OFFSET_BASE_IDX 2
+#define regCURSOR0_0_CURSOR_MEM_PWR_CTRL 0x0680
+#define regCURSOR0_0_CURSOR_MEM_PWR_CTRL_BASE_IDX 2
+#define regCURSOR0_0_CURSOR_MEM_PWR_STATUS 0x0681
+#define regCURSOR0_0_CURSOR_MEM_PWR_STATUS_BASE_IDX 2
+#define regCURSOR0_0_DMDATA_ADDRESS_HIGH 0x0682
+#define regCURSOR0_0_DMDATA_ADDRESS_HIGH_BASE_IDX 2
+#define regCURSOR0_0_DMDATA_ADDRESS_LOW 0x0683
+#define regCURSOR0_0_DMDATA_ADDRESS_LOW_BASE_IDX 2
+#define regCURSOR0_0_DMDATA_CNTL 0x0684
+#define regCURSOR0_0_DMDATA_CNTL_BASE_IDX 2
+#define regCURSOR0_0_DMDATA_QOS_CNTL 0x0685
+#define regCURSOR0_0_DMDATA_QOS_CNTL_BASE_IDX 2
+#define regCURSOR0_0_DMDATA_STATUS 0x0686
+#define regCURSOR0_0_DMDATA_STATUS_BASE_IDX 2
+#define regCURSOR0_0_DMDATA_SW_CNTL 0x0687
+#define regCURSOR0_0_DMDATA_SW_CNTL_BASE_IDX 2
+#define regCURSOR0_0_DMDATA_SW_DATA 0x0688
+#define regCURSOR0_0_DMDATA_SW_DATA_BASE_IDX 2
+
+
+// addressBlock: dce_dc_dcbubp0_dispdec_hubp_dcperfmon_dc_perfmon_dispdec
+// base address: 0x1a74
+#define regDC_PERFMON7_PERFCOUNTER_CNTL 0x069d
+#define regDC_PERFMON7_PERFCOUNTER_CNTL_BASE_IDX 2
+#define regDC_PERFMON7_PERFCOUNTER_CNTL2 0x069e
+#define regDC_PERFMON7_PERFCOUNTER_CNTL2_BASE_IDX 2
+#define regDC_PERFMON7_PERFCOUNTER_STATE 0x069f
+#define regDC_PERFMON7_PERFCOUNTER_STATE_BASE_IDX 2
+#define regDC_PERFMON7_PERFMON_CNTL 0x06a0
+#define regDC_PERFMON7_PERFMON_CNTL_BASE_IDX 2
+#define regDC_PERFMON7_PERFMON_CNTL2 0x06a1
+#define regDC_PERFMON7_PERFMON_CNTL2_BASE_IDX 2
+#define regDC_PERFMON7_PERFMON_CVALUE_INT_MISC 0x06a2
+#define regDC_PERFMON7_PERFMON_CVALUE_INT_MISC_BASE_IDX 2
+#define regDC_PERFMON7_PERFMON_CVALUE_LOW 0x06a3
+#define regDC_PERFMON7_PERFMON_CVALUE_LOW_BASE_IDX 2
+#define regDC_PERFMON7_PERFMON_HI 0x06a4
+#define regDC_PERFMON7_PERFMON_HI_BASE_IDX 2
+#define regDC_PERFMON7_PERFMON_LOW 0x06a5
+#define regDC_PERFMON7_PERFMON_LOW_BASE_IDX 2
+
+
+// addressBlock: dce_dc_dcbubp1_dispdec_hubp_dispdec
+// base address: 0x370
+#define regHUBP1_DCSURF_SURFACE_CONFIG 0x06c1
+#define regHUBP1_DCSURF_SURFACE_CONFIG_BASE_IDX 2
+#define regHUBP1_DCSURF_ADDR_CONFIG 0x06c2
+#define regHUBP1_DCSURF_ADDR_CONFIG_BASE_IDX 2
+#define regHUBP1_DCSURF_TILING_CONFIG 0x06c3
+#define regHUBP1_DCSURF_TILING_CONFIG_BASE_IDX 2
+#define regHUBP1_DCSURF_PRI_VIEWPORT_START 0x06c5
+#define regHUBP1_DCSURF_PRI_VIEWPORT_START_BASE_IDX 2
+#define regHUBP1_DCSURF_PRI_VIEWPORT_DIMENSION 0x06c6
+#define regHUBP1_DCSURF_PRI_VIEWPORT_DIMENSION_BASE_IDX 2
+#define regHUBP1_DCSURF_PRI_VIEWPORT_START_C 0x06c7
+#define regHUBP1_DCSURF_PRI_VIEWPORT_START_C_BASE_IDX 2
+#define regHUBP1_DCSURF_PRI_VIEWPORT_DIMENSION_C 0x06c8
+#define regHUBP1_DCSURF_PRI_VIEWPORT_DIMENSION_C_BASE_IDX 2
+#define regHUBP1_DCSURF_SEC_VIEWPORT_START 0x06c9
+#define regHUBP1_DCSURF_SEC_VIEWPORT_START_BASE_IDX 2
+#define regHUBP1_DCSURF_SEC_VIEWPORT_DIMENSION 0x06ca
+#define regHUBP1_DCSURF_SEC_VIEWPORT_DIMENSION_BASE_IDX 2
+#define regHUBP1_DCSURF_SEC_VIEWPORT_START_C 0x06cb
+#define regHUBP1_DCSURF_SEC_VIEWPORT_START_C_BASE_IDX 2
+#define regHUBP1_DCSURF_SEC_VIEWPORT_DIMENSION_C 0x06cc
+#define regHUBP1_DCSURF_SEC_VIEWPORT_DIMENSION_C_BASE_IDX 2
+#define regHUBP1_DCHUBP_REQ_SIZE_CONFIG 0x06cd
+#define regHUBP1_DCHUBP_REQ_SIZE_CONFIG_BASE_IDX 2
+#define regHUBP1_DCHUBP_REQ_SIZE_CONFIG_C 0x06ce
+#define regHUBP1_DCHUBP_REQ_SIZE_CONFIG_C_BASE_IDX 2
+#define regHUBP1_DCHUBP_CNTL 0x06cf
+#define regHUBP1_DCHUBP_CNTL_BASE_IDX 2
+#define regHUBP1_HUBP_CLK_CNTL 0x06d0
+#define regHUBP1_HUBP_CLK_CNTL_BASE_IDX 2
+#define regHUBP1_DCHUBP_VMPG_CONFIG 0x06d1
+#define regHUBP1_DCHUBP_VMPG_CONFIG_BASE_IDX 2
+#define regHUBP1_HUBPREQ_DEBUG_DB 0x06d2
+#define regHUBP1_HUBPREQ_DEBUG_DB_BASE_IDX 2
+#define regHUBP1_HUBPREQ_DEBUG 0x06d3
+#define regHUBP1_HUBPREQ_DEBUG_BASE_IDX 2
+#define regHUBP1_HUBP_MEASURE_WIN_CTRL_DCFCLK 0x06d7
+#define regHUBP1_HUBP_MEASURE_WIN_CTRL_DCFCLK_BASE_IDX 2
+#define regHUBP1_HUBP_MEASURE_WIN_CTRL_DPPCLK 0x06d8
+#define regHUBP1_HUBP_MEASURE_WIN_CTRL_DPPCLK_BASE_IDX 2
+
+
+// addressBlock: dce_dc_dcbubp1_dispdec_hubpreq_dispdec
+// base address: 0x370
+#define regHUBPREQ1_DCSURF_SURFACE_PITCH 0x06e3
+#define regHUBPREQ1_DCSURF_SURFACE_PITCH_BASE_IDX 2
+#define regHUBPREQ1_DCSURF_SURFACE_PITCH_C 0x06e4
+#define regHUBPREQ1_DCSURF_SURFACE_PITCH_C_BASE_IDX 2
+#define regHUBPREQ1_VMID_SETTINGS_0 0x06e5
+#define regHUBPREQ1_VMID_SETTINGS_0_BASE_IDX 2
+#define regHUBPREQ1_DCSURF_PRIMARY_SURFACE_ADDRESS 0x06e6
+#define regHUBPREQ1_DCSURF_PRIMARY_SURFACE_ADDRESS_BASE_IDX 2
+#define regHUBPREQ1_DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH 0x06e7
+#define regHUBPREQ1_DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH_BASE_IDX 2
+#define regHUBPREQ1_DCSURF_PRIMARY_SURFACE_ADDRESS_C 0x06e8
+#define regHUBPREQ1_DCSURF_PRIMARY_SURFACE_ADDRESS_C_BASE_IDX 2
+#define regHUBPREQ1_DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH_C 0x06e9
+#define regHUBPREQ1_DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH_C_BASE_IDX 2
+#define regHUBPREQ1_DCSURF_SECONDARY_SURFACE_ADDRESS 0x06ea
+#define regHUBPREQ1_DCSURF_SECONDARY_SURFACE_ADDRESS_BASE_IDX 2
+#define regHUBPREQ1_DCSURF_SECONDARY_SURFACE_ADDRESS_HIGH 0x06eb
+#define regHUBPREQ1_DCSURF_SECONDARY_SURFACE_ADDRESS_HIGH_BASE_IDX 2
+#define regHUBPREQ1_DCSURF_SECONDARY_SURFACE_ADDRESS_C 0x06ec
+#define regHUBPREQ1_DCSURF_SECONDARY_SURFACE_ADDRESS_C_BASE_IDX 2
+#define regHUBPREQ1_DCSURF_SECONDARY_SURFACE_ADDRESS_HIGH_C 0x06ed
+#define regHUBPREQ1_DCSURF_SECONDARY_SURFACE_ADDRESS_HIGH_C_BASE_IDX 2
+#define regHUBPREQ1_DCSURF_PRIMARY_META_SURFACE_ADDRESS 0x06ee
+#define regHUBPREQ1_DCSURF_PRIMARY_META_SURFACE_ADDRESS_BASE_IDX 2
+#define regHUBPREQ1_DCSURF_PRIMARY_META_SURFACE_ADDRESS_HIGH 0x06ef
+#define regHUBPREQ1_DCSURF_PRIMARY_META_SURFACE_ADDRESS_HIGH_BASE_IDX 2
+#define regHUBPREQ1_DCSURF_PRIMARY_META_SURFACE_ADDRESS_C 0x06f0
+#define regHUBPREQ1_DCSURF_PRIMARY_META_SURFACE_ADDRESS_C_BASE_IDX 2
+#define regHUBPREQ1_DCSURF_PRIMARY_META_SURFACE_ADDRESS_HIGH_C 0x06f1
+#define regHUBPREQ1_DCSURF_PRIMARY_META_SURFACE_ADDRESS_HIGH_C_BASE_IDX 2
+#define regHUBPREQ1_DCSURF_SECONDARY_META_SURFACE_ADDRESS 0x06f2
+#define regHUBPREQ1_DCSURF_SECONDARY_META_SURFACE_ADDRESS_BASE_IDX 2
+#define regHUBPREQ1_DCSURF_SECONDARY_META_SURFACE_ADDRESS_HIGH 0x06f3
+#define regHUBPREQ1_DCSURF_SECONDARY_META_SURFACE_ADDRESS_HIGH_BASE_IDX 2
+#define regHUBPREQ1_DCSURF_SECONDARY_META_SURFACE_ADDRESS_C 0x06f4
+#define regHUBPREQ1_DCSURF_SECONDARY_META_SURFACE_ADDRESS_C_BASE_IDX 2
+#define regHUBPREQ1_DCSURF_SECONDARY_META_SURFACE_ADDRESS_HIGH_C 0x06f5
+#define regHUBPREQ1_DCSURF_SECONDARY_META_SURFACE_ADDRESS_HIGH_C_BASE_IDX 2
+#define regHUBPREQ1_DCSURF_SURFACE_CONTROL 0x06f6
+#define regHUBPREQ1_DCSURF_SURFACE_CONTROL_BASE_IDX 2
+#define regHUBPREQ1_DCSURF_FLIP_CONTROL 0x06f7
+#define regHUBPREQ1_DCSURF_FLIP_CONTROL_BASE_IDX 2
+#define regHUBPREQ1_DCSURF_FLIP_CONTROL2 0x06f8
+#define regHUBPREQ1_DCSURF_FLIP_CONTROL2_BASE_IDX 2
+#define regHUBPREQ1_DCSURF_SURFACE_FLIP_INTERRUPT 0x06fc
+#define regHUBPREQ1_DCSURF_SURFACE_FLIP_INTERRUPT_BASE_IDX 2
+#define regHUBPREQ1_DCSURF_SURFACE_INUSE 0x06fd
+#define regHUBPREQ1_DCSURF_SURFACE_INUSE_BASE_IDX 2
+#define regHUBPREQ1_DCSURF_SURFACE_INUSE_HIGH 0x06fe
+#define regHUBPREQ1_DCSURF_SURFACE_INUSE_HIGH_BASE_IDX 2
+#define regHUBPREQ1_DCSURF_SURFACE_INUSE_C 0x06ff
+#define regHUBPREQ1_DCSURF_SURFACE_INUSE_C_BASE_IDX 2
+#define regHUBPREQ1_DCSURF_SURFACE_INUSE_HIGH_C 0x0700
+#define regHUBPREQ1_DCSURF_SURFACE_INUSE_HIGH_C_BASE_IDX 2
+#define regHUBPREQ1_DCSURF_SURFACE_EARLIEST_INUSE 0x0701
+#define regHUBPREQ1_DCSURF_SURFACE_EARLIEST_INUSE_BASE_IDX 2
+#define regHUBPREQ1_DCSURF_SURFACE_EARLIEST_INUSE_HIGH 0x0702
+#define regHUBPREQ1_DCSURF_SURFACE_EARLIEST_INUSE_HIGH_BASE_IDX 2
+#define regHUBPREQ1_DCSURF_SURFACE_EARLIEST_INUSE_C 0x0703
+#define regHUBPREQ1_DCSURF_SURFACE_EARLIEST_INUSE_C_BASE_IDX 2
+#define regHUBPREQ1_DCSURF_SURFACE_EARLIEST_INUSE_HIGH_C 0x0704
+#define regHUBPREQ1_DCSURF_SURFACE_EARLIEST_INUSE_HIGH_C_BASE_IDX 2
+#define regHUBPREQ1_DCN_EXPANSION_MODE 0x0705
+#define regHUBPREQ1_DCN_EXPANSION_MODE_BASE_IDX 2
+#define regHUBPREQ1_DCN_TTU_QOS_WM 0x0706
+#define regHUBPREQ1_DCN_TTU_QOS_WM_BASE_IDX 2
+#define regHUBPREQ1_DCN_GLOBAL_TTU_CNTL 0x0707
+#define regHUBPREQ1_DCN_GLOBAL_TTU_CNTL_BASE_IDX 2
+#define regHUBPREQ1_DCN_SURF0_TTU_CNTL0 0x0708
+#define regHUBPREQ1_DCN_SURF0_TTU_CNTL0_BASE_IDX 2
+#define regHUBPREQ1_DCN_SURF0_TTU_CNTL1 0x0709
+#define regHUBPREQ1_DCN_SURF0_TTU_CNTL1_BASE_IDX 2
+#define regHUBPREQ1_DCN_SURF1_TTU_CNTL0 0x070a
+#define regHUBPREQ1_DCN_SURF1_TTU_CNTL0_BASE_IDX 2
+#define regHUBPREQ1_DCN_SURF1_TTU_CNTL1 0x070b
+#define regHUBPREQ1_DCN_SURF1_TTU_CNTL1_BASE_IDX 2
+#define regHUBPREQ1_DCN_CUR0_TTU_CNTL0 0x070c
+#define regHUBPREQ1_DCN_CUR0_TTU_CNTL0_BASE_IDX 2
+#define regHUBPREQ1_DCN_CUR0_TTU_CNTL1 0x070d
+#define regHUBPREQ1_DCN_CUR0_TTU_CNTL1_BASE_IDX 2
+#define regHUBPREQ1_DCN_CUR1_TTU_CNTL0 0x070e
+#define regHUBPREQ1_DCN_CUR1_TTU_CNTL0_BASE_IDX 2
+#define regHUBPREQ1_DCN_CUR1_TTU_CNTL1 0x070f
+#define regHUBPREQ1_DCN_CUR1_TTU_CNTL1_BASE_IDX 2
+#define regHUBPREQ1_DCN_DMDATA_VM_CNTL 0x0710
+#define regHUBPREQ1_DCN_DMDATA_VM_CNTL_BASE_IDX 2
+#define regHUBPREQ1_DCN_VM_SYSTEM_APERTURE_LOW_ADDR 0x0711
+#define regHUBPREQ1_DCN_VM_SYSTEM_APERTURE_LOW_ADDR_BASE_IDX 2
+#define regHUBPREQ1_DCN_VM_SYSTEM_APERTURE_HIGH_ADDR 0x0712
+#define regHUBPREQ1_DCN_VM_SYSTEM_APERTURE_HIGH_ADDR_BASE_IDX 2
+#define regHUBPREQ1_DCN_VM_MX_L1_TLB_CNTL 0x071f
+#define regHUBPREQ1_DCN_VM_MX_L1_TLB_CNTL_BASE_IDX 2
+#define regHUBPREQ1_BLANK_OFFSET_0 0x0720
+#define regHUBPREQ1_BLANK_OFFSET_0_BASE_IDX 2
+#define regHUBPREQ1_BLANK_OFFSET_1 0x0721
+#define regHUBPREQ1_BLANK_OFFSET_1_BASE_IDX 2
+#define regHUBPREQ1_DST_DIMENSIONS 0x0722
+#define regHUBPREQ1_DST_DIMENSIONS_BASE_IDX 2
+#define regHUBPREQ1_DST_AFTER_SCALER 0x0723
+#define regHUBPREQ1_DST_AFTER_SCALER_BASE_IDX 2
+#define regHUBPREQ1_PREFETCH_SETTINGS 0x0724
+#define regHUBPREQ1_PREFETCH_SETTINGS_BASE_IDX 2
+#define regHUBPREQ1_PREFETCH_SETTINGS_C 0x0725
+#define regHUBPREQ1_PREFETCH_SETTINGS_C_BASE_IDX 2
+#define regHUBPREQ1_VBLANK_PARAMETERS_0 0x0726
+#define regHUBPREQ1_VBLANK_PARAMETERS_0_BASE_IDX 2
+#define regHUBPREQ1_VBLANK_PARAMETERS_1 0x0727
+#define regHUBPREQ1_VBLANK_PARAMETERS_1_BASE_IDX 2
+#define regHUBPREQ1_VBLANK_PARAMETERS_2 0x0728
+#define regHUBPREQ1_VBLANK_PARAMETERS_2_BASE_IDX 2
+#define regHUBPREQ1_VBLANK_PARAMETERS_3 0x0729
+#define regHUBPREQ1_VBLANK_PARAMETERS_3_BASE_IDX 2
+#define regHUBPREQ1_VBLANK_PARAMETERS_4 0x072a
+#define regHUBPREQ1_VBLANK_PARAMETERS_4_BASE_IDX 2
+#define regHUBPREQ1_FLIP_PARAMETERS_0 0x072b
+#define regHUBPREQ1_FLIP_PARAMETERS_0_BASE_IDX 2
+#define regHUBPREQ1_FLIP_PARAMETERS_1 0x072c
+#define regHUBPREQ1_FLIP_PARAMETERS_1_BASE_IDX 2
+#define regHUBPREQ1_FLIP_PARAMETERS_2 0x072d
+#define regHUBPREQ1_FLIP_PARAMETERS_2_BASE_IDX 2
+#define regHUBPREQ1_NOM_PARAMETERS_0 0x072e
+#define regHUBPREQ1_NOM_PARAMETERS_0_BASE_IDX 2
+#define regHUBPREQ1_NOM_PARAMETERS_1 0x072f
+#define regHUBPREQ1_NOM_PARAMETERS_1_BASE_IDX 2
+#define regHUBPREQ1_NOM_PARAMETERS_2 0x0730
+#define regHUBPREQ1_NOM_PARAMETERS_2_BASE_IDX 2
+#define regHUBPREQ1_NOM_PARAMETERS_3 0x0731
+#define regHUBPREQ1_NOM_PARAMETERS_3_BASE_IDX 2
+#define regHUBPREQ1_NOM_PARAMETERS_4 0x0732
+#define regHUBPREQ1_NOM_PARAMETERS_4_BASE_IDX 2
+#define regHUBPREQ1_NOM_PARAMETERS_5 0x0733
+#define regHUBPREQ1_NOM_PARAMETERS_5_BASE_IDX 2
+#define regHUBPREQ1_NOM_PARAMETERS_6 0x0734
+#define regHUBPREQ1_NOM_PARAMETERS_6_BASE_IDX 2
+#define regHUBPREQ1_NOM_PARAMETERS_7 0x0735
+#define regHUBPREQ1_NOM_PARAMETERS_7_BASE_IDX 2
+#define regHUBPREQ1_PER_LINE_DELIVERY_PRE 0x0736
+#define regHUBPREQ1_PER_LINE_DELIVERY_PRE_BASE_IDX 2
+#define regHUBPREQ1_PER_LINE_DELIVERY 0x0737
+#define regHUBPREQ1_PER_LINE_DELIVERY_BASE_IDX 2
+#define regHUBPREQ1_CURSOR_SETTINGS 0x0738
+#define regHUBPREQ1_CURSOR_SETTINGS_BASE_IDX 2
+#define regHUBPREQ1_REF_FREQ_TO_PIX_FREQ 0x0739
+#define regHUBPREQ1_REF_FREQ_TO_PIX_FREQ_BASE_IDX 2
+#define regHUBPREQ1_DST_Y_DELTA_DRQ_LIMIT 0x073a
+#define regHUBPREQ1_DST_Y_DELTA_DRQ_LIMIT_BASE_IDX 2
+#define regHUBPREQ1_HUBPREQ_MEM_PWR_CTRL 0x073b
+#define regHUBPREQ1_HUBPREQ_MEM_PWR_CTRL_BASE_IDX 2
+#define regHUBPREQ1_HUBPREQ_MEM_PWR_STATUS 0x073c
+#define regHUBPREQ1_HUBPREQ_MEM_PWR_STATUS_BASE_IDX 2
+#define regHUBPREQ1_VBLANK_PARAMETERS_5 0x073f
+#define regHUBPREQ1_VBLANK_PARAMETERS_5_BASE_IDX 2
+#define regHUBPREQ1_VBLANK_PARAMETERS_6 0x0740
+#define regHUBPREQ1_VBLANK_PARAMETERS_6_BASE_IDX 2
+#define regHUBPREQ1_FLIP_PARAMETERS_3 0x0741
+#define regHUBPREQ1_FLIP_PARAMETERS_3_BASE_IDX 2
+#define regHUBPREQ1_FLIP_PARAMETERS_4 0x0742
+#define regHUBPREQ1_FLIP_PARAMETERS_4_BASE_IDX 2
+#define regHUBPREQ1_FLIP_PARAMETERS_5 0x0743
+#define regHUBPREQ1_FLIP_PARAMETERS_5_BASE_IDX 2
+#define regHUBPREQ1_FLIP_PARAMETERS_6 0x0744
+#define regHUBPREQ1_FLIP_PARAMETERS_6_BASE_IDX 2
+
+
+// addressBlock: dce_dc_dcbubp1_dispdec_hubpret_dispdec
+// base address: 0x370
+#define regHUBPRET1_HUBPRET_CONTROL 0x0748
+#define regHUBPRET1_HUBPRET_CONTROL_BASE_IDX 2
+#define regHUBPRET1_HUBPRET_MEM_PWR_CTRL 0x0749
+#define regHUBPRET1_HUBPRET_MEM_PWR_CTRL_BASE_IDX 2
+#define regHUBPRET1_HUBPRET_MEM_PWR_STATUS 0x074a
+#define regHUBPRET1_HUBPRET_MEM_PWR_STATUS_BASE_IDX 2
+#define regHUBPRET1_HUBPRET_READ_LINE_CTRL0 0x074b
+#define regHUBPRET1_HUBPRET_READ_LINE_CTRL0_BASE_IDX 2
+#define regHUBPRET1_HUBPRET_READ_LINE_CTRL1 0x074c
+#define regHUBPRET1_HUBPRET_READ_LINE_CTRL1_BASE_IDX 2
+#define regHUBPRET1_HUBPRET_READ_LINE0 0x074d
+#define regHUBPRET1_HUBPRET_READ_LINE0_BASE_IDX 2
+#define regHUBPRET1_HUBPRET_READ_LINE1 0x074e
+#define regHUBPRET1_HUBPRET_READ_LINE1_BASE_IDX 2
+#define regHUBPRET1_HUBPRET_INTERRUPT 0x074f
+#define regHUBPRET1_HUBPRET_INTERRUPT_BASE_IDX 2
+#define regHUBPRET1_HUBPRET_READ_LINE_VALUE 0x0750
+#define regHUBPRET1_HUBPRET_READ_LINE_VALUE_BASE_IDX 2
+#define regHUBPRET1_HUBPRET_READ_LINE_STATUS 0x0751
+#define regHUBPRET1_HUBPRET_READ_LINE_STATUS_BASE_IDX 2
+
+
+// addressBlock: dce_dc_dcbubp1_dispdec_cursor0_dispdec
+// base address: 0x370
+#define regCURSOR0_1_CURSOR_CONTROL 0x0754
+#define regCURSOR0_1_CURSOR_CONTROL_BASE_IDX 2
+#define regCURSOR0_1_CURSOR_SURFACE_ADDRESS 0x0755
+#define regCURSOR0_1_CURSOR_SURFACE_ADDRESS_BASE_IDX 2
+#define regCURSOR0_1_CURSOR_SURFACE_ADDRESS_HIGH 0x0756
+#define regCURSOR0_1_CURSOR_SURFACE_ADDRESS_HIGH_BASE_IDX 2
+#define regCURSOR0_1_CURSOR_SIZE 0x0757
+#define regCURSOR0_1_CURSOR_SIZE_BASE_IDX 2
+#define regCURSOR0_1_CURSOR_POSITION 0x0758
+#define regCURSOR0_1_CURSOR_POSITION_BASE_IDX 2
+#define regCURSOR0_1_CURSOR_HOT_SPOT 0x0759
+#define regCURSOR0_1_CURSOR_HOT_SPOT_BASE_IDX 2
+#define regCURSOR0_1_CURSOR_STEREO_CONTROL 0x075a
+#define regCURSOR0_1_CURSOR_STEREO_CONTROL_BASE_IDX 2
+#define regCURSOR0_1_CURSOR_DST_OFFSET 0x075b
+#define regCURSOR0_1_CURSOR_DST_OFFSET_BASE_IDX 2
+#define regCURSOR0_1_CURSOR_MEM_PWR_CTRL 0x075c
+#define regCURSOR0_1_CURSOR_MEM_PWR_CTRL_BASE_IDX 2
+#define regCURSOR0_1_CURSOR_MEM_PWR_STATUS 0x075d
+#define regCURSOR0_1_CURSOR_MEM_PWR_STATUS_BASE_IDX 2
+#define regCURSOR0_1_DMDATA_ADDRESS_HIGH 0x075e
+#define regCURSOR0_1_DMDATA_ADDRESS_HIGH_BASE_IDX 2
+#define regCURSOR0_1_DMDATA_ADDRESS_LOW 0x075f
+#define regCURSOR0_1_DMDATA_ADDRESS_LOW_BASE_IDX 2
+#define regCURSOR0_1_DMDATA_CNTL 0x0760
+#define regCURSOR0_1_DMDATA_CNTL_BASE_IDX 2
+#define regCURSOR0_1_DMDATA_QOS_CNTL 0x0761
+#define regCURSOR0_1_DMDATA_QOS_CNTL_BASE_IDX 2
+#define regCURSOR0_1_DMDATA_STATUS 0x0762
+#define regCURSOR0_1_DMDATA_STATUS_BASE_IDX 2
+#define regCURSOR0_1_DMDATA_SW_CNTL 0x0763
+#define regCURSOR0_1_DMDATA_SW_CNTL_BASE_IDX 2
+#define regCURSOR0_1_DMDATA_SW_DATA 0x0764
+#define regCURSOR0_1_DMDATA_SW_DATA_BASE_IDX 2
+
+
+// addressBlock: dce_dc_dcbubp1_dispdec_hubp_dcperfmon_dc_perfmon_dispdec
+// base address: 0x1de4
+#define regDC_PERFMON8_PERFCOUNTER_CNTL 0x0779
+#define regDC_PERFMON8_PERFCOUNTER_CNTL_BASE_IDX 2
+#define regDC_PERFMON8_PERFCOUNTER_CNTL2 0x077a
+#define regDC_PERFMON8_PERFCOUNTER_CNTL2_BASE_IDX 2
+#define regDC_PERFMON8_PERFCOUNTER_STATE 0x077b
+#define regDC_PERFMON8_PERFCOUNTER_STATE_BASE_IDX 2
+#define regDC_PERFMON8_PERFMON_CNTL 0x077c
+#define regDC_PERFMON8_PERFMON_CNTL_BASE_IDX 2
+#define regDC_PERFMON8_PERFMON_CNTL2 0x077d
+#define regDC_PERFMON8_PERFMON_CNTL2_BASE_IDX 2
+#define regDC_PERFMON8_PERFMON_CVALUE_INT_MISC 0x077e
+#define regDC_PERFMON8_PERFMON_CVALUE_INT_MISC_BASE_IDX 2
+#define regDC_PERFMON8_PERFMON_CVALUE_LOW 0x077f
+#define regDC_PERFMON8_PERFMON_CVALUE_LOW_BASE_IDX 2
+#define regDC_PERFMON8_PERFMON_HI 0x0780
+#define regDC_PERFMON8_PERFMON_HI_BASE_IDX 2
+#define regDC_PERFMON8_PERFMON_LOW 0x0781
+#define regDC_PERFMON8_PERFMON_LOW_BASE_IDX 2
+
+
+// addressBlock: dce_dc_dcbubp2_dispdec_hubp_dispdec
+// base address: 0x6e0
+#define regHUBP2_DCSURF_SURFACE_CONFIG 0x079d
+#define regHUBP2_DCSURF_SURFACE_CONFIG_BASE_IDX 2
+#define regHUBP2_DCSURF_ADDR_CONFIG 0x079e
+#define regHUBP2_DCSURF_ADDR_CONFIG_BASE_IDX 2
+#define regHUBP2_DCSURF_TILING_CONFIG 0x079f
+#define regHUBP2_DCSURF_TILING_CONFIG_BASE_IDX 2
+#define regHUBP2_DCSURF_PRI_VIEWPORT_START 0x07a1
+#define regHUBP2_DCSURF_PRI_VIEWPORT_START_BASE_IDX 2
+#define regHUBP2_DCSURF_PRI_VIEWPORT_DIMENSION 0x07a2
+#define regHUBP2_DCSURF_PRI_VIEWPORT_DIMENSION_BASE_IDX 2
+#define regHUBP2_DCSURF_PRI_VIEWPORT_START_C 0x07a3
+#define regHUBP2_DCSURF_PRI_VIEWPORT_START_C_BASE_IDX 2
+#define regHUBP2_DCSURF_PRI_VIEWPORT_DIMENSION_C 0x07a4
+#define regHUBP2_DCSURF_PRI_VIEWPORT_DIMENSION_C_BASE_IDX 2
+#define regHUBP2_DCSURF_SEC_VIEWPORT_START 0x07a5
+#define regHUBP2_DCSURF_SEC_VIEWPORT_START_BASE_IDX 2
+#define regHUBP2_DCSURF_SEC_VIEWPORT_DIMENSION 0x07a6
+#define regHUBP2_DCSURF_SEC_VIEWPORT_DIMENSION_BASE_IDX 2
+#define regHUBP2_DCSURF_SEC_VIEWPORT_START_C 0x07a7
+#define regHUBP2_DCSURF_SEC_VIEWPORT_START_C_BASE_IDX 2
+#define regHUBP2_DCSURF_SEC_VIEWPORT_DIMENSION_C 0x07a8
+#define regHUBP2_DCSURF_SEC_VIEWPORT_DIMENSION_C_BASE_IDX 2
+#define regHUBP2_DCHUBP_REQ_SIZE_CONFIG 0x07a9
+#define regHUBP2_DCHUBP_REQ_SIZE_CONFIG_BASE_IDX 2
+#define regHUBP2_DCHUBP_REQ_SIZE_CONFIG_C 0x07aa
+#define regHUBP2_DCHUBP_REQ_SIZE_CONFIG_C_BASE_IDX 2
+#define regHUBP2_DCHUBP_CNTL 0x07ab
+#define regHUBP2_DCHUBP_CNTL_BASE_IDX 2
+#define regHUBP2_HUBP_CLK_CNTL 0x07ac
+#define regHUBP2_HUBP_CLK_CNTL_BASE_IDX 2
+#define regHUBP2_DCHUBP_VMPG_CONFIG 0x07ad
+#define regHUBP2_DCHUBP_VMPG_CONFIG_BASE_IDX 2
+#define regHUBP2_HUBPREQ_DEBUG_DB 0x07ae
+#define regHUBP2_HUBPREQ_DEBUG_DB_BASE_IDX 2
+#define regHUBP2_HUBPREQ_DEBUG 0x07af
+#define regHUBP2_HUBPREQ_DEBUG_BASE_IDX 2
+#define regHUBP2_HUBP_MEASURE_WIN_CTRL_DCFCLK 0x07b3
+#define regHUBP2_HUBP_MEASURE_WIN_CTRL_DCFCLK_BASE_IDX 2
+#define regHUBP2_HUBP_MEASURE_WIN_CTRL_DPPCLK 0x07b4
+#define regHUBP2_HUBP_MEASURE_WIN_CTRL_DPPCLK_BASE_IDX 2
+
+
+// addressBlock: dce_dc_dcbubp2_dispdec_hubpreq_dispdec
+// base address: 0x6e0
+#define regHUBPREQ2_DCSURF_SURFACE_PITCH 0x07bf
+#define regHUBPREQ2_DCSURF_SURFACE_PITCH_BASE_IDX 2
+#define regHUBPREQ2_DCSURF_SURFACE_PITCH_C 0x07c0
+#define regHUBPREQ2_DCSURF_SURFACE_PITCH_C_BASE_IDX 2
+#define regHUBPREQ2_VMID_SETTINGS_0 0x07c1
+#define regHUBPREQ2_VMID_SETTINGS_0_BASE_IDX 2
+#define regHUBPREQ2_DCSURF_PRIMARY_SURFACE_ADDRESS 0x07c2
+#define regHUBPREQ2_DCSURF_PRIMARY_SURFACE_ADDRESS_BASE_IDX 2
+#define regHUBPREQ2_DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH 0x07c3
+#define regHUBPREQ2_DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH_BASE_IDX 2
+#define regHUBPREQ2_DCSURF_PRIMARY_SURFACE_ADDRESS_C 0x07c4
+#define regHUBPREQ2_DCSURF_PRIMARY_SURFACE_ADDRESS_C_BASE_IDX 2
+#define regHUBPREQ2_DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH_C 0x07c5
+#define regHUBPREQ2_DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH_C_BASE_IDX 2
+#define regHUBPREQ2_DCSURF_SECONDARY_SURFACE_ADDRESS 0x07c6
+#define regHUBPREQ2_DCSURF_SECONDARY_SURFACE_ADDRESS_BASE_IDX 2
+#define regHUBPREQ2_DCSURF_SECONDARY_SURFACE_ADDRESS_HIGH 0x07c7
+#define regHUBPREQ2_DCSURF_SECONDARY_SURFACE_ADDRESS_HIGH_BASE_IDX 2
+#define regHUBPREQ2_DCSURF_SECONDARY_SURFACE_ADDRESS_C 0x07c8
+#define regHUBPREQ2_DCSURF_SECONDARY_SURFACE_ADDRESS_C_BASE_IDX 2
+#define regHUBPREQ2_DCSURF_SECONDARY_SURFACE_ADDRESS_HIGH_C 0x07c9
+#define regHUBPREQ2_DCSURF_SECONDARY_SURFACE_ADDRESS_HIGH_C_BASE_IDX 2
+#define regHUBPREQ2_DCSURF_PRIMARY_META_SURFACE_ADDRESS 0x07ca
+#define regHUBPREQ2_DCSURF_PRIMARY_META_SURFACE_ADDRESS_BASE_IDX 2
+#define regHUBPREQ2_DCSURF_PRIMARY_META_SURFACE_ADDRESS_HIGH 0x07cb
+#define regHUBPREQ2_DCSURF_PRIMARY_META_SURFACE_ADDRESS_HIGH_BASE_IDX 2
+#define regHUBPREQ2_DCSURF_PRIMARY_META_SURFACE_ADDRESS_C 0x07cc
+#define regHUBPREQ2_DCSURF_PRIMARY_META_SURFACE_ADDRESS_C_BASE_IDX 2
+#define regHUBPREQ2_DCSURF_PRIMARY_META_SURFACE_ADDRESS_HIGH_C 0x07cd
+#define regHUBPREQ2_DCSURF_PRIMARY_META_SURFACE_ADDRESS_HIGH_C_BASE_IDX 2
+#define regHUBPREQ2_DCSURF_SECONDARY_META_SURFACE_ADDRESS 0x07ce
+#define regHUBPREQ2_DCSURF_SECONDARY_META_SURFACE_ADDRESS_BASE_IDX 2
+#define regHUBPREQ2_DCSURF_SECONDARY_META_SURFACE_ADDRESS_HIGH 0x07cf
+#define regHUBPREQ2_DCSURF_SECONDARY_META_SURFACE_ADDRESS_HIGH_BASE_IDX 2
+#define regHUBPREQ2_DCSURF_SECONDARY_META_SURFACE_ADDRESS_C 0x07d0
+#define regHUBPREQ2_DCSURF_SECONDARY_META_SURFACE_ADDRESS_C_BASE_IDX 2
+#define regHUBPREQ2_DCSURF_SECONDARY_META_SURFACE_ADDRESS_HIGH_C 0x07d1
+#define regHUBPREQ2_DCSURF_SECONDARY_META_SURFACE_ADDRESS_HIGH_C_BASE_IDX 2
+#define regHUBPREQ2_DCSURF_SURFACE_CONTROL 0x07d2
+#define regHUBPREQ2_DCSURF_SURFACE_CONTROL_BASE_IDX 2
+#define regHUBPREQ2_DCSURF_FLIP_CONTROL 0x07d3
+#define regHUBPREQ2_DCSURF_FLIP_CONTROL_BASE_IDX 2
+#define regHUBPREQ2_DCSURF_FLIP_CONTROL2 0x07d4
+#define regHUBPREQ2_DCSURF_FLIP_CONTROL2_BASE_IDX 2
+#define regHUBPREQ2_DCSURF_SURFACE_FLIP_INTERRUPT 0x07d8
+#define regHUBPREQ2_DCSURF_SURFACE_FLIP_INTERRUPT_BASE_IDX 2
+#define regHUBPREQ2_DCSURF_SURFACE_INUSE 0x07d9
+#define regHUBPREQ2_DCSURF_SURFACE_INUSE_BASE_IDX 2
+#define regHUBPREQ2_DCSURF_SURFACE_INUSE_HIGH 0x07da
+#define regHUBPREQ2_DCSURF_SURFACE_INUSE_HIGH_BASE_IDX 2
+#define regHUBPREQ2_DCSURF_SURFACE_INUSE_C 0x07db
+#define regHUBPREQ2_DCSURF_SURFACE_INUSE_C_BASE_IDX 2
+#define regHUBPREQ2_DCSURF_SURFACE_INUSE_HIGH_C 0x07dc
+#define regHUBPREQ2_DCSURF_SURFACE_INUSE_HIGH_C_BASE_IDX 2
+#define regHUBPREQ2_DCSURF_SURFACE_EARLIEST_INUSE 0x07dd
+#define regHUBPREQ2_DCSURF_SURFACE_EARLIEST_INUSE_BASE_IDX 2
+#define regHUBPREQ2_DCSURF_SURFACE_EARLIEST_INUSE_HIGH 0x07de
+#define regHUBPREQ2_DCSURF_SURFACE_EARLIEST_INUSE_HIGH_BASE_IDX 2
+#define regHUBPREQ2_DCSURF_SURFACE_EARLIEST_INUSE_C 0x07df
+#define regHUBPREQ2_DCSURF_SURFACE_EARLIEST_INUSE_C_BASE_IDX 2
+#define regHUBPREQ2_DCSURF_SURFACE_EARLIEST_INUSE_HIGH_C 0x07e0
+#define regHUBPREQ2_DCSURF_SURFACE_EARLIEST_INUSE_HIGH_C_BASE_IDX 2
+#define regHUBPREQ2_DCN_EXPANSION_MODE 0x07e1
+#define regHUBPREQ2_DCN_EXPANSION_MODE_BASE_IDX 2
+#define regHUBPREQ2_DCN_TTU_QOS_WM 0x07e2
+#define regHUBPREQ2_DCN_TTU_QOS_WM_BASE_IDX 2
+#define regHUBPREQ2_DCN_GLOBAL_TTU_CNTL 0x07e3
+#define regHUBPREQ2_DCN_GLOBAL_TTU_CNTL_BASE_IDX 2
+#define regHUBPREQ2_DCN_SURF0_TTU_CNTL0 0x07e4
+#define regHUBPREQ2_DCN_SURF0_TTU_CNTL0_BASE_IDX 2
+#define regHUBPREQ2_DCN_SURF0_TTU_CNTL1 0x07e5
+#define regHUBPREQ2_DCN_SURF0_TTU_CNTL1_BASE_IDX 2
+#define regHUBPREQ2_DCN_SURF1_TTU_CNTL0 0x07e6
+#define regHUBPREQ2_DCN_SURF1_TTU_CNTL0_BASE_IDX 2
+#define regHUBPREQ2_DCN_SURF1_TTU_CNTL1 0x07e7
+#define regHUBPREQ2_DCN_SURF1_TTU_CNTL1_BASE_IDX 2
+#define regHUBPREQ2_DCN_CUR0_TTU_CNTL0 0x07e8
+#define regHUBPREQ2_DCN_CUR0_TTU_CNTL0_BASE_IDX 2
+#define regHUBPREQ2_DCN_CUR0_TTU_CNTL1 0x07e9
+#define regHUBPREQ2_DCN_CUR0_TTU_CNTL1_BASE_IDX 2
+#define regHUBPREQ2_DCN_CUR1_TTU_CNTL0 0x07ea
+#define regHUBPREQ2_DCN_CUR1_TTU_CNTL0_BASE_IDX 2
+#define regHUBPREQ2_DCN_CUR1_TTU_CNTL1 0x07eb
+#define regHUBPREQ2_DCN_CUR1_TTU_CNTL1_BASE_IDX 2
+#define regHUBPREQ2_DCN_DMDATA_VM_CNTL 0x07ec
+#define regHUBPREQ2_DCN_DMDATA_VM_CNTL_BASE_IDX 2
+#define regHUBPREQ2_DCN_VM_SYSTEM_APERTURE_LOW_ADDR 0x07ed
+#define regHUBPREQ2_DCN_VM_SYSTEM_APERTURE_LOW_ADDR_BASE_IDX 2
+#define regHUBPREQ2_DCN_VM_SYSTEM_APERTURE_HIGH_ADDR 0x07ee
+#define regHUBPREQ2_DCN_VM_SYSTEM_APERTURE_HIGH_ADDR_BASE_IDX 2
+#define regHUBPREQ2_DCN_VM_MX_L1_TLB_CNTL 0x07fb
+#define regHUBPREQ2_DCN_VM_MX_L1_TLB_CNTL_BASE_IDX 2
+#define regHUBPREQ2_BLANK_OFFSET_0 0x07fc
+#define regHUBPREQ2_BLANK_OFFSET_0_BASE_IDX 2
+#define regHUBPREQ2_BLANK_OFFSET_1 0x07fd
+#define regHUBPREQ2_BLANK_OFFSET_1_BASE_IDX 2
+#define regHUBPREQ2_DST_DIMENSIONS 0x07fe
+#define regHUBPREQ2_DST_DIMENSIONS_BASE_IDX 2
+#define regHUBPREQ2_DST_AFTER_SCALER 0x07ff
+#define regHUBPREQ2_DST_AFTER_SCALER_BASE_IDX 2
+#define regHUBPREQ2_PREFETCH_SETTINGS 0x0800
+#define regHUBPREQ2_PREFETCH_SETTINGS_BASE_IDX 2
+#define regHUBPREQ2_PREFETCH_SETTINGS_C 0x0801
+#define regHUBPREQ2_PREFETCH_SETTINGS_C_BASE_IDX 2
+#define regHUBPREQ2_VBLANK_PARAMETERS_0 0x0802
+#define regHUBPREQ2_VBLANK_PARAMETERS_0_BASE_IDX 2
+#define regHUBPREQ2_VBLANK_PARAMETERS_1 0x0803
+#define regHUBPREQ2_VBLANK_PARAMETERS_1_BASE_IDX 2
+#define regHUBPREQ2_VBLANK_PARAMETERS_2 0x0804
+#define regHUBPREQ2_VBLANK_PARAMETERS_2_BASE_IDX 2
+#define regHUBPREQ2_VBLANK_PARAMETERS_3 0x0805
+#define regHUBPREQ2_VBLANK_PARAMETERS_3_BASE_IDX 2
+#define regHUBPREQ2_VBLANK_PARAMETERS_4 0x0806
+#define regHUBPREQ2_VBLANK_PARAMETERS_4_BASE_IDX 2
+#define regHUBPREQ2_FLIP_PARAMETERS_0 0x0807
+#define regHUBPREQ2_FLIP_PARAMETERS_0_BASE_IDX 2
+#define regHUBPREQ2_FLIP_PARAMETERS_1 0x0808
+#define regHUBPREQ2_FLIP_PARAMETERS_1_BASE_IDX 2
+#define regHUBPREQ2_FLIP_PARAMETERS_2 0x0809
+#define regHUBPREQ2_FLIP_PARAMETERS_2_BASE_IDX 2
+#define regHUBPREQ2_NOM_PARAMETERS_0 0x080a
+#define regHUBPREQ2_NOM_PARAMETERS_0_BASE_IDX 2
+#define regHUBPREQ2_NOM_PARAMETERS_1 0x080b
+#define regHUBPREQ2_NOM_PARAMETERS_1_BASE_IDX 2
+#define regHUBPREQ2_NOM_PARAMETERS_2 0x080c
+#define regHUBPREQ2_NOM_PARAMETERS_2_BASE_IDX 2
+#define regHUBPREQ2_NOM_PARAMETERS_3 0x080d
+#define regHUBPREQ2_NOM_PARAMETERS_3_BASE_IDX 2
+#define regHUBPREQ2_NOM_PARAMETERS_4 0x080e
+#define regHUBPREQ2_NOM_PARAMETERS_4_BASE_IDX 2
+#define regHUBPREQ2_NOM_PARAMETERS_5 0x080f
+#define regHUBPREQ2_NOM_PARAMETERS_5_BASE_IDX 2
+#define regHUBPREQ2_NOM_PARAMETERS_6 0x0810
+#define regHUBPREQ2_NOM_PARAMETERS_6_BASE_IDX 2
+#define regHUBPREQ2_NOM_PARAMETERS_7 0x0811
+#define regHUBPREQ2_NOM_PARAMETERS_7_BASE_IDX 2
+#define regHUBPREQ2_PER_LINE_DELIVERY_PRE 0x0812
+#define regHUBPREQ2_PER_LINE_DELIVERY_PRE_BASE_IDX 2
+#define regHUBPREQ2_PER_LINE_DELIVERY 0x0813
+#define regHUBPREQ2_PER_LINE_DELIVERY_BASE_IDX 2
+#define regHUBPREQ2_CURSOR_SETTINGS 0x0814
+#define regHUBPREQ2_CURSOR_SETTINGS_BASE_IDX 2
+#define regHUBPREQ2_REF_FREQ_TO_PIX_FREQ 0x0815
+#define regHUBPREQ2_REF_FREQ_TO_PIX_FREQ_BASE_IDX 2
+#define regHUBPREQ2_DST_Y_DELTA_DRQ_LIMIT 0x0816
+#define regHUBPREQ2_DST_Y_DELTA_DRQ_LIMIT_BASE_IDX 2
+#define regHUBPREQ2_HUBPREQ_MEM_PWR_CTRL 0x0817
+#define regHUBPREQ2_HUBPREQ_MEM_PWR_CTRL_BASE_IDX 2
+#define regHUBPREQ2_HUBPREQ_MEM_PWR_STATUS 0x0818
+#define regHUBPREQ2_HUBPREQ_MEM_PWR_STATUS_BASE_IDX 2
+#define regHUBPREQ2_VBLANK_PARAMETERS_5 0x081b
+#define regHUBPREQ2_VBLANK_PARAMETERS_5_BASE_IDX 2
+#define regHUBPREQ2_VBLANK_PARAMETERS_6 0x081c
+#define regHUBPREQ2_VBLANK_PARAMETERS_6_BASE_IDX 2
+#define regHUBPREQ2_FLIP_PARAMETERS_3 0x081d
+#define regHUBPREQ2_FLIP_PARAMETERS_3_BASE_IDX 2
+#define regHUBPREQ2_FLIP_PARAMETERS_4 0x081e
+#define regHUBPREQ2_FLIP_PARAMETERS_4_BASE_IDX 2
+#define regHUBPREQ2_FLIP_PARAMETERS_5 0x081f
+#define regHUBPREQ2_FLIP_PARAMETERS_5_BASE_IDX 2
+#define regHUBPREQ2_FLIP_PARAMETERS_6 0x0820
+#define regHUBPREQ2_FLIP_PARAMETERS_6_BASE_IDX 2
+
+
+// addressBlock: dce_dc_dcbubp2_dispdec_hubpret_dispdec
+// base address: 0x6e0
+#define regHUBPRET2_HUBPRET_CONTROL 0x0824
+#define regHUBPRET2_HUBPRET_CONTROL_BASE_IDX 2
+#define regHUBPRET2_HUBPRET_MEM_PWR_CTRL 0x0825
+#define regHUBPRET2_HUBPRET_MEM_PWR_CTRL_BASE_IDX 2
+#define regHUBPRET2_HUBPRET_MEM_PWR_STATUS 0x0826
+#define regHUBPRET2_HUBPRET_MEM_PWR_STATUS_BASE_IDX 2
+#define regHUBPRET2_HUBPRET_READ_LINE_CTRL0 0x0827
+#define regHUBPRET2_HUBPRET_READ_LINE_CTRL0_BASE_IDX 2
+#define regHUBPRET2_HUBPRET_READ_LINE_CTRL1 0x0828
+#define regHUBPRET2_HUBPRET_READ_LINE_CTRL1_BASE_IDX 2
+#define regHUBPRET2_HUBPRET_READ_LINE0 0x0829
+#define regHUBPRET2_HUBPRET_READ_LINE0_BASE_IDX 2
+#define regHUBPRET2_HUBPRET_READ_LINE1 0x082a
+#define regHUBPRET2_HUBPRET_READ_LINE1_BASE_IDX 2
+#define regHUBPRET2_HUBPRET_INTERRUPT 0x082b
+#define regHUBPRET2_HUBPRET_INTERRUPT_BASE_IDX 2
+#define regHUBPRET2_HUBPRET_READ_LINE_VALUE 0x082c
+#define regHUBPRET2_HUBPRET_READ_LINE_VALUE_BASE_IDX 2
+#define regHUBPRET2_HUBPRET_READ_LINE_STATUS 0x082d
+#define regHUBPRET2_HUBPRET_READ_LINE_STATUS_BASE_IDX 2
+
+
+// addressBlock: dce_dc_dcbubp2_dispdec_cursor0_dispdec
+// base address: 0x6e0
+#define regCURSOR0_2_CURSOR_CONTROL 0x0830
+#define regCURSOR0_2_CURSOR_CONTROL_BASE_IDX 2
+#define regCURSOR0_2_CURSOR_SURFACE_ADDRESS 0x0831
+#define regCURSOR0_2_CURSOR_SURFACE_ADDRESS_BASE_IDX 2
+#define regCURSOR0_2_CURSOR_SURFACE_ADDRESS_HIGH 0x0832
+#define regCURSOR0_2_CURSOR_SURFACE_ADDRESS_HIGH_BASE_IDX 2
+#define regCURSOR0_2_CURSOR_SIZE 0x0833
+#define regCURSOR0_2_CURSOR_SIZE_BASE_IDX 2
+#define regCURSOR0_2_CURSOR_POSITION 0x0834
+#define regCURSOR0_2_CURSOR_POSITION_BASE_IDX 2
+#define regCURSOR0_2_CURSOR_HOT_SPOT 0x0835
+#define regCURSOR0_2_CURSOR_HOT_SPOT_BASE_IDX 2
+#define regCURSOR0_2_CURSOR_STEREO_CONTROL 0x0836
+#define regCURSOR0_2_CURSOR_STEREO_CONTROL_BASE_IDX 2
+#define regCURSOR0_2_CURSOR_DST_OFFSET 0x0837
+#define regCURSOR0_2_CURSOR_DST_OFFSET_BASE_IDX 2
+#define regCURSOR0_2_CURSOR_MEM_PWR_CTRL 0x0838
+#define regCURSOR0_2_CURSOR_MEM_PWR_CTRL_BASE_IDX 2
+#define regCURSOR0_2_CURSOR_MEM_PWR_STATUS 0x0839
+#define regCURSOR0_2_CURSOR_MEM_PWR_STATUS_BASE_IDX 2
+#define regCURSOR0_2_DMDATA_ADDRESS_HIGH 0x083a
+#define regCURSOR0_2_DMDATA_ADDRESS_HIGH_BASE_IDX 2
+#define regCURSOR0_2_DMDATA_ADDRESS_LOW 0x083b
+#define regCURSOR0_2_DMDATA_ADDRESS_LOW_BASE_IDX 2
+#define regCURSOR0_2_DMDATA_CNTL 0x083c
+#define regCURSOR0_2_DMDATA_CNTL_BASE_IDX 2
+#define regCURSOR0_2_DMDATA_QOS_CNTL 0x083d
+#define regCURSOR0_2_DMDATA_QOS_CNTL_BASE_IDX 2
+#define regCURSOR0_2_DMDATA_STATUS 0x083e
+#define regCURSOR0_2_DMDATA_STATUS_BASE_IDX 2
+#define regCURSOR0_2_DMDATA_SW_CNTL 0x083f
+#define regCURSOR0_2_DMDATA_SW_CNTL_BASE_IDX 2
+#define regCURSOR0_2_DMDATA_SW_DATA 0x0840
+#define regCURSOR0_2_DMDATA_SW_DATA_BASE_IDX 2
+
+
+// addressBlock: dce_dc_dcbubp2_dispdec_hubp_dcperfmon_dc_perfmon_dispdec
+// base address: 0x2154
+#define regDC_PERFMON9_PERFCOUNTER_CNTL 0x0855
+#define regDC_PERFMON9_PERFCOUNTER_CNTL_BASE_IDX 2
+#define regDC_PERFMON9_PERFCOUNTER_CNTL2 0x0856
+#define regDC_PERFMON9_PERFCOUNTER_CNTL2_BASE_IDX 2
+#define regDC_PERFMON9_PERFCOUNTER_STATE 0x0857
+#define regDC_PERFMON9_PERFCOUNTER_STATE_BASE_IDX 2
+#define regDC_PERFMON9_PERFMON_CNTL 0x0858
+#define regDC_PERFMON9_PERFMON_CNTL_BASE_IDX 2
+#define regDC_PERFMON9_PERFMON_CNTL2 0x0859
+#define regDC_PERFMON9_PERFMON_CNTL2_BASE_IDX 2
+#define regDC_PERFMON9_PERFMON_CVALUE_INT_MISC 0x085a
+#define regDC_PERFMON9_PERFMON_CVALUE_INT_MISC_BASE_IDX 2
+#define regDC_PERFMON9_PERFMON_CVALUE_LOW 0x085b
+#define regDC_PERFMON9_PERFMON_CVALUE_LOW_BASE_IDX 2
+#define regDC_PERFMON9_PERFMON_HI 0x085c
+#define regDC_PERFMON9_PERFMON_HI_BASE_IDX 2
+#define regDC_PERFMON9_PERFMON_LOW 0x085d
+#define regDC_PERFMON9_PERFMON_LOW_BASE_IDX 2
+
+
+// addressBlock: dce_dc_dcbubp3_dispdec_hubp_dispdec
+// base address: 0xa50
+#define regHUBP3_DCSURF_SURFACE_CONFIG 0x0879
+#define regHUBP3_DCSURF_SURFACE_CONFIG_BASE_IDX 2
+#define regHUBP3_DCSURF_ADDR_CONFIG 0x087a
+#define regHUBP3_DCSURF_ADDR_CONFIG_BASE_IDX 2
+#define regHUBP3_DCSURF_TILING_CONFIG 0x087b
+#define regHUBP3_DCSURF_TILING_CONFIG_BASE_IDX 2
+#define regHUBP3_DCSURF_PRI_VIEWPORT_START 0x087d
+#define regHUBP3_DCSURF_PRI_VIEWPORT_START_BASE_IDX 2
+#define regHUBP3_DCSURF_PRI_VIEWPORT_DIMENSION 0x087e
+#define regHUBP3_DCSURF_PRI_VIEWPORT_DIMENSION_BASE_IDX 2
+#define regHUBP3_DCSURF_PRI_VIEWPORT_START_C 0x087f
+#define regHUBP3_DCSURF_PRI_VIEWPORT_START_C_BASE_IDX 2
+#define regHUBP3_DCSURF_PRI_VIEWPORT_DIMENSION_C 0x0880
+#define regHUBP3_DCSURF_PRI_VIEWPORT_DIMENSION_C_BASE_IDX 2
+#define regHUBP3_DCSURF_SEC_VIEWPORT_START 0x0881
+#define regHUBP3_DCSURF_SEC_VIEWPORT_START_BASE_IDX 2
+#define regHUBP3_DCSURF_SEC_VIEWPORT_DIMENSION 0x0882
+#define regHUBP3_DCSURF_SEC_VIEWPORT_DIMENSION_BASE_IDX 2
+#define regHUBP3_DCSURF_SEC_VIEWPORT_START_C 0x0883
+#define regHUBP3_DCSURF_SEC_VIEWPORT_START_C_BASE_IDX 2
+#define regHUBP3_DCSURF_SEC_VIEWPORT_DIMENSION_C 0x0884
+#define regHUBP3_DCSURF_SEC_VIEWPORT_DIMENSION_C_BASE_IDX 2
+#define regHUBP3_DCHUBP_REQ_SIZE_CONFIG 0x0885
+#define regHUBP3_DCHUBP_REQ_SIZE_CONFIG_BASE_IDX 2
+#define regHUBP3_DCHUBP_REQ_SIZE_CONFIG_C 0x0886
+#define regHUBP3_DCHUBP_REQ_SIZE_CONFIG_C_BASE_IDX 2
+#define regHUBP3_DCHUBP_CNTL 0x0887
+#define regHUBP3_DCHUBP_CNTL_BASE_IDX 2
+#define regHUBP3_HUBP_CLK_CNTL 0x0888
+#define regHUBP3_HUBP_CLK_CNTL_BASE_IDX 2
+#define regHUBP3_DCHUBP_VMPG_CONFIG 0x0889
+#define regHUBP3_DCHUBP_VMPG_CONFIG_BASE_IDX 2
+#define regHUBP3_HUBPREQ_DEBUG_DB 0x088a
+#define regHUBP3_HUBPREQ_DEBUG_DB_BASE_IDX 2
+#define regHUBP3_HUBPREQ_DEBUG 0x088b
+#define regHUBP3_HUBPREQ_DEBUG_BASE_IDX 2
+#define regHUBP3_HUBP_MEASURE_WIN_CTRL_DCFCLK 0x088f
+#define regHUBP3_HUBP_MEASURE_WIN_CTRL_DCFCLK_BASE_IDX 2
+#define regHUBP3_HUBP_MEASURE_WIN_CTRL_DPPCLK 0x0890
+#define regHUBP3_HUBP_MEASURE_WIN_CTRL_DPPCLK_BASE_IDX 2
+
+
+// addressBlock: dce_dc_dcbubp3_dispdec_hubpreq_dispdec
+// base address: 0xa50
+#define regHUBPREQ3_DCSURF_SURFACE_PITCH 0x089b
+#define regHUBPREQ3_DCSURF_SURFACE_PITCH_BASE_IDX 2
+#define regHUBPREQ3_DCSURF_SURFACE_PITCH_C 0x089c
+#define regHUBPREQ3_DCSURF_SURFACE_PITCH_C_BASE_IDX 2
+#define regHUBPREQ3_VMID_SETTINGS_0 0x089d
+#define regHUBPREQ3_VMID_SETTINGS_0_BASE_IDX 2
+#define regHUBPREQ3_DCSURF_PRIMARY_SURFACE_ADDRESS 0x089e
+#define regHUBPREQ3_DCSURF_PRIMARY_SURFACE_ADDRESS_BASE_IDX 2
+#define regHUBPREQ3_DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH 0x089f
+#define regHUBPREQ3_DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH_BASE_IDX 2
+#define regHUBPREQ3_DCSURF_PRIMARY_SURFACE_ADDRESS_C 0x08a0
+#define regHUBPREQ3_DCSURF_PRIMARY_SURFACE_ADDRESS_C_BASE_IDX 2
+#define regHUBPREQ3_DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH_C 0x08a1
+#define regHUBPREQ3_DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH_C_BASE_IDX 2
+#define regHUBPREQ3_DCSURF_SECONDARY_SURFACE_ADDRESS 0x08a2
+#define regHUBPREQ3_DCSURF_SECONDARY_SURFACE_ADDRESS_BASE_IDX 2
+#define regHUBPREQ3_DCSURF_SECONDARY_SURFACE_ADDRESS_HIGH 0x08a3
+#define regHUBPREQ3_DCSURF_SECONDARY_SURFACE_ADDRESS_HIGH_BASE_IDX 2
+#define regHUBPREQ3_DCSURF_SECONDARY_SURFACE_ADDRESS_C 0x08a4
+#define regHUBPREQ3_DCSURF_SECONDARY_SURFACE_ADDRESS_C_BASE_IDX 2
+#define regHUBPREQ3_DCSURF_SECONDARY_SURFACE_ADDRESS_HIGH_C 0x08a5
+#define regHUBPREQ3_DCSURF_SECONDARY_SURFACE_ADDRESS_HIGH_C_BASE_IDX 2
+#define regHUBPREQ3_DCSURF_PRIMARY_META_SURFACE_ADDRESS 0x08a6
+#define regHUBPREQ3_DCSURF_PRIMARY_META_SURFACE_ADDRESS_BASE_IDX 2
+#define regHUBPREQ3_DCSURF_PRIMARY_META_SURFACE_ADDRESS_HIGH 0x08a7
+#define regHUBPREQ3_DCSURF_PRIMARY_META_SURFACE_ADDRESS_HIGH_BASE_IDX 2
+#define regHUBPREQ3_DCSURF_PRIMARY_META_SURFACE_ADDRESS_C 0x08a8
+#define regHUBPREQ3_DCSURF_PRIMARY_META_SURFACE_ADDRESS_C_BASE_IDX 2
+#define regHUBPREQ3_DCSURF_PRIMARY_META_SURFACE_ADDRESS_HIGH_C 0x08a9
+#define regHUBPREQ3_DCSURF_PRIMARY_META_SURFACE_ADDRESS_HIGH_C_BASE_IDX 2
+#define regHUBPREQ3_DCSURF_SECONDARY_META_SURFACE_ADDRESS 0x08aa
+#define regHUBPREQ3_DCSURF_SECONDARY_META_SURFACE_ADDRESS_BASE_IDX 2
+#define regHUBPREQ3_DCSURF_SECONDARY_META_SURFACE_ADDRESS_HIGH 0x08ab
+#define regHUBPREQ3_DCSURF_SECONDARY_META_SURFACE_ADDRESS_HIGH_BASE_IDX 2
+#define regHUBPREQ3_DCSURF_SECONDARY_META_SURFACE_ADDRESS_C 0x08ac
+#define regHUBPREQ3_DCSURF_SECONDARY_META_SURFACE_ADDRESS_C_BASE_IDX 2
+#define regHUBPREQ3_DCSURF_SECONDARY_META_SURFACE_ADDRESS_HIGH_C 0x08ad
+#define regHUBPREQ3_DCSURF_SECONDARY_META_SURFACE_ADDRESS_HIGH_C_BASE_IDX 2
+#define regHUBPREQ3_DCSURF_SURFACE_CONTROL 0x08ae
+#define regHUBPREQ3_DCSURF_SURFACE_CONTROL_BASE_IDX 2
+#define regHUBPREQ3_DCSURF_FLIP_CONTROL 0x08af
+#define regHUBPREQ3_DCSURF_FLIP_CONTROL_BASE_IDX 2
+#define regHUBPREQ3_DCSURF_FLIP_CONTROL2 0x08b0
+#define regHUBPREQ3_DCSURF_FLIP_CONTROL2_BASE_IDX 2
+#define regHUBPREQ3_DCSURF_SURFACE_FLIP_INTERRUPT 0x08b4
+#define regHUBPREQ3_DCSURF_SURFACE_FLIP_INTERRUPT_BASE_IDX 2
+#define regHUBPREQ3_DCSURF_SURFACE_INUSE 0x08b5
+#define regHUBPREQ3_DCSURF_SURFACE_INUSE_BASE_IDX 2
+#define regHUBPREQ3_DCSURF_SURFACE_INUSE_HIGH 0x08b6
+#define regHUBPREQ3_DCSURF_SURFACE_INUSE_HIGH_BASE_IDX 2
+#define regHUBPREQ3_DCSURF_SURFACE_INUSE_C 0x08b7
+#define regHUBPREQ3_DCSURF_SURFACE_INUSE_C_BASE_IDX 2
+#define regHUBPREQ3_DCSURF_SURFACE_INUSE_HIGH_C 0x08b8
+#define regHUBPREQ3_DCSURF_SURFACE_INUSE_HIGH_C_BASE_IDX 2
+#define regHUBPREQ3_DCSURF_SURFACE_EARLIEST_INUSE 0x08b9
+#define regHUBPREQ3_DCSURF_SURFACE_EARLIEST_INUSE_BASE_IDX 2
+#define regHUBPREQ3_DCSURF_SURFACE_EARLIEST_INUSE_HIGH 0x08ba
+#define regHUBPREQ3_DCSURF_SURFACE_EARLIEST_INUSE_HIGH_BASE_IDX 2
+#define regHUBPREQ3_DCSURF_SURFACE_EARLIEST_INUSE_C 0x08bb
+#define regHUBPREQ3_DCSURF_SURFACE_EARLIEST_INUSE_C_BASE_IDX 2
+#define regHUBPREQ3_DCSURF_SURFACE_EARLIEST_INUSE_HIGH_C 0x08bc
+#define regHUBPREQ3_DCSURF_SURFACE_EARLIEST_INUSE_HIGH_C_BASE_IDX 2
+#define regHUBPREQ3_DCN_EXPANSION_MODE 0x08bd
+#define regHUBPREQ3_DCN_EXPANSION_MODE_BASE_IDX 2
+#define regHUBPREQ3_DCN_TTU_QOS_WM 0x08be
+#define regHUBPREQ3_DCN_TTU_QOS_WM_BASE_IDX 2
+#define regHUBPREQ3_DCN_GLOBAL_TTU_CNTL 0x08bf
+#define regHUBPREQ3_DCN_GLOBAL_TTU_CNTL_BASE_IDX 2
+#define regHUBPREQ3_DCN_SURF0_TTU_CNTL0 0x08c0
+#define regHUBPREQ3_DCN_SURF0_TTU_CNTL0_BASE_IDX 2
+#define regHUBPREQ3_DCN_SURF0_TTU_CNTL1 0x08c1
+#define regHUBPREQ3_DCN_SURF0_TTU_CNTL1_BASE_IDX 2
+#define regHUBPREQ3_DCN_SURF1_TTU_CNTL0 0x08c2
+#define regHUBPREQ3_DCN_SURF1_TTU_CNTL0_BASE_IDX 2
+#define regHUBPREQ3_DCN_SURF1_TTU_CNTL1 0x08c3
+#define regHUBPREQ3_DCN_SURF1_TTU_CNTL1_BASE_IDX 2
+#define regHUBPREQ3_DCN_CUR0_TTU_CNTL0 0x08c4
+#define regHUBPREQ3_DCN_CUR0_TTU_CNTL0_BASE_IDX 2
+#define regHUBPREQ3_DCN_CUR0_TTU_CNTL1 0x08c5
+#define regHUBPREQ3_DCN_CUR0_TTU_CNTL1_BASE_IDX 2
+#define regHUBPREQ3_DCN_CUR1_TTU_CNTL0 0x08c6
+#define regHUBPREQ3_DCN_CUR1_TTU_CNTL0_BASE_IDX 2
+#define regHUBPREQ3_DCN_CUR1_TTU_CNTL1 0x08c7
+#define regHUBPREQ3_DCN_CUR1_TTU_CNTL1_BASE_IDX 2
+#define regHUBPREQ3_DCN_DMDATA_VM_CNTL 0x08c8
+#define regHUBPREQ3_DCN_DMDATA_VM_CNTL_BASE_IDX 2
+#define regHUBPREQ3_DCN_VM_SYSTEM_APERTURE_LOW_ADDR 0x08c9
+#define regHUBPREQ3_DCN_VM_SYSTEM_APERTURE_LOW_ADDR_BASE_IDX 2
+#define regHUBPREQ3_DCN_VM_SYSTEM_APERTURE_HIGH_ADDR 0x08ca
+#define regHUBPREQ3_DCN_VM_SYSTEM_APERTURE_HIGH_ADDR_BASE_IDX 2
+#define regHUBPREQ3_DCN_VM_MX_L1_TLB_CNTL 0x08d7
+#define regHUBPREQ3_DCN_VM_MX_L1_TLB_CNTL_BASE_IDX 2
+#define regHUBPREQ3_BLANK_OFFSET_0 0x08d8
+#define regHUBPREQ3_BLANK_OFFSET_0_BASE_IDX 2
+#define regHUBPREQ3_BLANK_OFFSET_1 0x08d9
+#define regHUBPREQ3_BLANK_OFFSET_1_BASE_IDX 2
+#define regHUBPREQ3_DST_DIMENSIONS 0x08da
+#define regHUBPREQ3_DST_DIMENSIONS_BASE_IDX 2
+#define regHUBPREQ3_DST_AFTER_SCALER 0x08db
+#define regHUBPREQ3_DST_AFTER_SCALER_BASE_IDX 2
+#define regHUBPREQ3_PREFETCH_SETTINGS 0x08dc
+#define regHUBPREQ3_PREFETCH_SETTINGS_BASE_IDX 2
+#define regHUBPREQ3_PREFETCH_SETTINGS_C 0x08dd
+#define regHUBPREQ3_PREFETCH_SETTINGS_C_BASE_IDX 2
+#define regHUBPREQ3_VBLANK_PARAMETERS_0 0x08de
+#define regHUBPREQ3_VBLANK_PARAMETERS_0_BASE_IDX 2
+#define regHUBPREQ3_VBLANK_PARAMETERS_1 0x08df
+#define regHUBPREQ3_VBLANK_PARAMETERS_1_BASE_IDX 2
+#define regHUBPREQ3_VBLANK_PARAMETERS_2 0x08e0
+#define regHUBPREQ3_VBLANK_PARAMETERS_2_BASE_IDX 2
+#define regHUBPREQ3_VBLANK_PARAMETERS_3 0x08e1
+#define regHUBPREQ3_VBLANK_PARAMETERS_3_BASE_IDX 2
+#define regHUBPREQ3_VBLANK_PARAMETERS_4 0x08e2
+#define regHUBPREQ3_VBLANK_PARAMETERS_4_BASE_IDX 2
+#define regHUBPREQ3_FLIP_PARAMETERS_0 0x08e3
+#define regHUBPREQ3_FLIP_PARAMETERS_0_BASE_IDX 2
+#define regHUBPREQ3_FLIP_PARAMETERS_1 0x08e4
+#define regHUBPREQ3_FLIP_PARAMETERS_1_BASE_IDX 2
+#define regHUBPREQ3_FLIP_PARAMETERS_2 0x08e5
+#define regHUBPREQ3_FLIP_PARAMETERS_2_BASE_IDX 2
+#define regHUBPREQ3_NOM_PARAMETERS_0 0x08e6
+#define regHUBPREQ3_NOM_PARAMETERS_0_BASE_IDX 2
+#define regHUBPREQ3_NOM_PARAMETERS_1 0x08e7
+#define regHUBPREQ3_NOM_PARAMETERS_1_BASE_IDX 2
+#define regHUBPREQ3_NOM_PARAMETERS_2 0x08e8
+#define regHUBPREQ3_NOM_PARAMETERS_2_BASE_IDX 2
+#define regHUBPREQ3_NOM_PARAMETERS_3 0x08e9
+#define regHUBPREQ3_NOM_PARAMETERS_3_BASE_IDX 2
+#define regHUBPREQ3_NOM_PARAMETERS_4 0x08ea
+#define regHUBPREQ3_NOM_PARAMETERS_4_BASE_IDX 2
+#define regHUBPREQ3_NOM_PARAMETERS_5 0x08eb
+#define regHUBPREQ3_NOM_PARAMETERS_5_BASE_IDX 2
+#define regHUBPREQ3_NOM_PARAMETERS_6 0x08ec
+#define regHUBPREQ3_NOM_PARAMETERS_6_BASE_IDX 2
+#define regHUBPREQ3_NOM_PARAMETERS_7 0x08ed
+#define regHUBPREQ3_NOM_PARAMETERS_7_BASE_IDX 2
+#define regHUBPREQ3_PER_LINE_DELIVERY_PRE 0x08ee
+#define regHUBPREQ3_PER_LINE_DELIVERY_PRE_BASE_IDX 2
+#define regHUBPREQ3_PER_LINE_DELIVERY 0x08ef
+#define regHUBPREQ3_PER_LINE_DELIVERY_BASE_IDX 2
+#define regHUBPREQ3_CURSOR_SETTINGS 0x08f0
+#define regHUBPREQ3_CURSOR_SETTINGS_BASE_IDX 2
+#define regHUBPREQ3_REF_FREQ_TO_PIX_FREQ 0x08f1
+#define regHUBPREQ3_REF_FREQ_TO_PIX_FREQ_BASE_IDX 2
+#define regHUBPREQ3_DST_Y_DELTA_DRQ_LIMIT 0x08f2
+#define regHUBPREQ3_DST_Y_DELTA_DRQ_LIMIT_BASE_IDX 2
+#define regHUBPREQ3_HUBPREQ_MEM_PWR_CTRL 0x08f3
+#define regHUBPREQ3_HUBPREQ_MEM_PWR_CTRL_BASE_IDX 2
+#define regHUBPREQ3_HUBPREQ_MEM_PWR_STATUS 0x08f4
+#define regHUBPREQ3_HUBPREQ_MEM_PWR_STATUS_BASE_IDX 2
+#define regHUBPREQ3_VBLANK_PARAMETERS_5 0x08f7
+#define regHUBPREQ3_VBLANK_PARAMETERS_5_BASE_IDX 2
+#define regHUBPREQ3_VBLANK_PARAMETERS_6 0x08f8
+#define regHUBPREQ3_VBLANK_PARAMETERS_6_BASE_IDX 2
+#define regHUBPREQ3_FLIP_PARAMETERS_3 0x08f9
+#define regHUBPREQ3_FLIP_PARAMETERS_3_BASE_IDX 2
+#define regHUBPREQ3_FLIP_PARAMETERS_4 0x08fa
+#define regHUBPREQ3_FLIP_PARAMETERS_4_BASE_IDX 2
+#define regHUBPREQ3_FLIP_PARAMETERS_5 0x08fb
+#define regHUBPREQ3_FLIP_PARAMETERS_5_BASE_IDX 2
+#define regHUBPREQ3_FLIP_PARAMETERS_6 0x08fc
+#define regHUBPREQ3_FLIP_PARAMETERS_6_BASE_IDX 2
+
+
+// addressBlock: dce_dc_dcbubp3_dispdec_hubpret_dispdec
+// base address: 0xa50
+#define regHUBPRET3_HUBPRET_CONTROL 0x0900
+#define regHUBPRET3_HUBPRET_CONTROL_BASE_IDX 2
+#define regHUBPRET3_HUBPRET_MEM_PWR_CTRL 0x0901
+#define regHUBPRET3_HUBPRET_MEM_PWR_CTRL_BASE_IDX 2
+#define regHUBPRET3_HUBPRET_MEM_PWR_STATUS 0x0902
+#define regHUBPRET3_HUBPRET_MEM_PWR_STATUS_BASE_IDX 2
+#define regHUBPRET3_HUBPRET_READ_LINE_CTRL0 0x0903
+#define regHUBPRET3_HUBPRET_READ_LINE_CTRL0_BASE_IDX 2
+#define regHUBPRET3_HUBPRET_READ_LINE_CTRL1 0x0904
+#define regHUBPRET3_HUBPRET_READ_LINE_CTRL1_BASE_IDX 2
+#define regHUBPRET3_HUBPRET_READ_LINE0 0x0905
+#define regHUBPRET3_HUBPRET_READ_LINE0_BASE_IDX 2
+#define regHUBPRET3_HUBPRET_READ_LINE1 0x0906
+#define regHUBPRET3_HUBPRET_READ_LINE1_BASE_IDX 2
+#define regHUBPRET3_HUBPRET_INTERRUPT 0x0907
+#define regHUBPRET3_HUBPRET_INTERRUPT_BASE_IDX 2
+#define regHUBPRET3_HUBPRET_READ_LINE_VALUE 0x0908
+#define regHUBPRET3_HUBPRET_READ_LINE_VALUE_BASE_IDX 2
+#define regHUBPRET3_HUBPRET_READ_LINE_STATUS 0x0909
+#define regHUBPRET3_HUBPRET_READ_LINE_STATUS_BASE_IDX 2
+
+
+// addressBlock: dce_dc_dcbubp3_dispdec_cursor0_dispdec
+// base address: 0xa50
+#define regCURSOR0_3_CURSOR_CONTROL 0x090c
+#define regCURSOR0_3_CURSOR_CONTROL_BASE_IDX 2
+#define regCURSOR0_3_CURSOR_SURFACE_ADDRESS 0x090d
+#define regCURSOR0_3_CURSOR_SURFACE_ADDRESS_BASE_IDX 2
+#define regCURSOR0_3_CURSOR_SURFACE_ADDRESS_HIGH 0x090e
+#define regCURSOR0_3_CURSOR_SURFACE_ADDRESS_HIGH_BASE_IDX 2
+#define regCURSOR0_3_CURSOR_SIZE 0x090f
+#define regCURSOR0_3_CURSOR_SIZE_BASE_IDX 2
+#define regCURSOR0_3_CURSOR_POSITION 0x0910
+#define regCURSOR0_3_CURSOR_POSITION_BASE_IDX 2
+#define regCURSOR0_3_CURSOR_HOT_SPOT 0x0911
+#define regCURSOR0_3_CURSOR_HOT_SPOT_BASE_IDX 2
+#define regCURSOR0_3_CURSOR_STEREO_CONTROL 0x0912
+#define regCURSOR0_3_CURSOR_STEREO_CONTROL_BASE_IDX 2
+#define regCURSOR0_3_CURSOR_DST_OFFSET 0x0913
+#define regCURSOR0_3_CURSOR_DST_OFFSET_BASE_IDX 2
+#define regCURSOR0_3_CURSOR_MEM_PWR_CTRL 0x0914
+#define regCURSOR0_3_CURSOR_MEM_PWR_CTRL_BASE_IDX 2
+#define regCURSOR0_3_CURSOR_MEM_PWR_STATUS 0x0915
+#define regCURSOR0_3_CURSOR_MEM_PWR_STATUS_BASE_IDX 2
+#define regCURSOR0_3_DMDATA_ADDRESS_HIGH 0x0916
+#define regCURSOR0_3_DMDATA_ADDRESS_HIGH_BASE_IDX 2
+#define regCURSOR0_3_DMDATA_ADDRESS_LOW 0x0917
+#define regCURSOR0_3_DMDATA_ADDRESS_LOW_BASE_IDX 2
+#define regCURSOR0_3_DMDATA_CNTL 0x0918
+#define regCURSOR0_3_DMDATA_CNTL_BASE_IDX 2
+#define regCURSOR0_3_DMDATA_QOS_CNTL 0x0919
+#define regCURSOR0_3_DMDATA_QOS_CNTL_BASE_IDX 2
+#define regCURSOR0_3_DMDATA_STATUS 0x091a
+#define regCURSOR0_3_DMDATA_STATUS_BASE_IDX 2
+#define regCURSOR0_3_DMDATA_SW_CNTL 0x091b
+#define regCURSOR0_3_DMDATA_SW_CNTL_BASE_IDX 2
+#define regCURSOR0_3_DMDATA_SW_DATA 0x091c
+#define regCURSOR0_3_DMDATA_SW_DATA_BASE_IDX 2
+
+
+// addressBlock: dce_dc_dcbubp3_dispdec_hubp_dcperfmon_dc_perfmon_dispdec
+// base address: 0x24c4
+#define regDC_PERFMON10_PERFCOUNTER_CNTL 0x0931
+#define regDC_PERFMON10_PERFCOUNTER_CNTL_BASE_IDX 2
+#define regDC_PERFMON10_PERFCOUNTER_CNTL2 0x0932
+#define regDC_PERFMON10_PERFCOUNTER_CNTL2_BASE_IDX 2
+#define regDC_PERFMON10_PERFCOUNTER_STATE 0x0933
+#define regDC_PERFMON10_PERFCOUNTER_STATE_BASE_IDX 2
+#define regDC_PERFMON10_PERFMON_CNTL 0x0934
+#define regDC_PERFMON10_PERFMON_CNTL_BASE_IDX 2
+#define regDC_PERFMON10_PERFMON_CNTL2 0x0935
+#define regDC_PERFMON10_PERFMON_CNTL2_BASE_IDX 2
+#define regDC_PERFMON10_PERFMON_CVALUE_INT_MISC 0x0936
+#define regDC_PERFMON10_PERFMON_CVALUE_INT_MISC_BASE_IDX 2
+#define regDC_PERFMON10_PERFMON_CVALUE_LOW 0x0937
+#define regDC_PERFMON10_PERFMON_CVALUE_LOW_BASE_IDX 2
+#define regDC_PERFMON10_PERFMON_HI 0x0938
+#define regDC_PERFMON10_PERFMON_HI_BASE_IDX 2
+#define regDC_PERFMON10_PERFMON_LOW 0x0939
+#define regDC_PERFMON10_PERFMON_LOW_BASE_IDX 2
+
+
+// addressBlock: dce_dc_dpp0_dispdec_cnvc_cfg_dispdec
+// base address: 0x0
+#define regCNVC_CFG0_CNVC_SURFACE_PIXEL_FORMAT 0x0ccf
+#define regCNVC_CFG0_CNVC_SURFACE_PIXEL_FORMAT_BASE_IDX 2
+#define regCNVC_CFG0_FORMAT_CONTROL 0x0cd0
+#define regCNVC_CFG0_FORMAT_CONTROL_BASE_IDX 2
+#define regCNVC_CFG0_FCNV_FP_BIAS_R 0x0cd1
+#define regCNVC_CFG0_FCNV_FP_BIAS_R_BASE_IDX 2
+#define regCNVC_CFG0_FCNV_FP_BIAS_G 0x0cd2
+#define regCNVC_CFG0_FCNV_FP_BIAS_G_BASE_IDX 2
+#define regCNVC_CFG0_FCNV_FP_BIAS_B 0x0cd3
+#define regCNVC_CFG0_FCNV_FP_BIAS_B_BASE_IDX 2
+#define regCNVC_CFG0_FCNV_FP_SCALE_R 0x0cd4
+#define regCNVC_CFG0_FCNV_FP_SCALE_R_BASE_IDX 2
+#define regCNVC_CFG0_FCNV_FP_SCALE_G 0x0cd5
+#define regCNVC_CFG0_FCNV_FP_SCALE_G_BASE_IDX 2
+#define regCNVC_CFG0_FCNV_FP_SCALE_B 0x0cd6
+#define regCNVC_CFG0_FCNV_FP_SCALE_B_BASE_IDX 2
+#define regCNVC_CFG0_COLOR_KEYER_CONTROL 0x0cd7
+#define regCNVC_CFG0_COLOR_KEYER_CONTROL_BASE_IDX 2
+#define regCNVC_CFG0_COLOR_KEYER_ALPHA 0x0cd8
+#define regCNVC_CFG0_COLOR_KEYER_ALPHA_BASE_IDX 2
+#define regCNVC_CFG0_COLOR_KEYER_RED 0x0cd9
+#define regCNVC_CFG0_COLOR_KEYER_RED_BASE_IDX 2
+#define regCNVC_CFG0_COLOR_KEYER_GREEN 0x0cda
+#define regCNVC_CFG0_COLOR_KEYER_GREEN_BASE_IDX 2
+#define regCNVC_CFG0_COLOR_KEYER_BLUE 0x0cdb
+#define regCNVC_CFG0_COLOR_KEYER_BLUE_BASE_IDX 2
+#define regCNVC_CFG0_ALPHA_2BIT_LUT 0x0cdd
+#define regCNVC_CFG0_ALPHA_2BIT_LUT_BASE_IDX 2
+#define regCNVC_CFG0_PRE_DEALPHA 0x0cde
+#define regCNVC_CFG0_PRE_DEALPHA_BASE_IDX 2
+#define regCNVC_CFG0_PRE_CSC_MODE 0x0cdf
+#define regCNVC_CFG0_PRE_CSC_MODE_BASE_IDX 2
+#define regCNVC_CFG0_PRE_CSC_C11_C12 0x0ce0
+#define regCNVC_CFG0_PRE_CSC_C11_C12_BASE_IDX 2
+#define regCNVC_CFG0_PRE_CSC_C13_C14 0x0ce1
+#define regCNVC_CFG0_PRE_CSC_C13_C14_BASE_IDX 2
+#define regCNVC_CFG0_PRE_CSC_C21_C22 0x0ce2
+#define regCNVC_CFG0_PRE_CSC_C21_C22_BASE_IDX 2
+#define regCNVC_CFG0_PRE_CSC_C23_C24 0x0ce3
+#define regCNVC_CFG0_PRE_CSC_C23_C24_BASE_IDX 2
+#define regCNVC_CFG0_PRE_CSC_C31_C32 0x0ce4
+#define regCNVC_CFG0_PRE_CSC_C31_C32_BASE_IDX 2
+#define regCNVC_CFG0_PRE_CSC_C33_C34 0x0ce5
+#define regCNVC_CFG0_PRE_CSC_C33_C34_BASE_IDX 2
+#define regCNVC_CFG0_PRE_CSC_B_C11_C12 0x0ce6
+#define regCNVC_CFG0_PRE_CSC_B_C11_C12_BASE_IDX 2
+#define regCNVC_CFG0_PRE_CSC_B_C13_C14 0x0ce7
+#define regCNVC_CFG0_PRE_CSC_B_C13_C14_BASE_IDX 2
+#define regCNVC_CFG0_PRE_CSC_B_C21_C22 0x0ce8
+#define regCNVC_CFG0_PRE_CSC_B_C21_C22_BASE_IDX 2
+#define regCNVC_CFG0_PRE_CSC_B_C23_C24 0x0ce9
+#define regCNVC_CFG0_PRE_CSC_B_C23_C24_BASE_IDX 2
+#define regCNVC_CFG0_PRE_CSC_B_C31_C32 0x0cea
+#define regCNVC_CFG0_PRE_CSC_B_C31_C32_BASE_IDX 2
+#define regCNVC_CFG0_PRE_CSC_B_C33_C34 0x0ceb
+#define regCNVC_CFG0_PRE_CSC_B_C33_C34_BASE_IDX 2
+#define regCNVC_CFG0_CNVC_COEF_FORMAT 0x0cec
+#define regCNVC_CFG0_CNVC_COEF_FORMAT_BASE_IDX 2
+#define regCNVC_CFG0_PRE_DEGAM 0x0ced
+#define regCNVC_CFG0_PRE_DEGAM_BASE_IDX 2
+#define regCNVC_CFG0_PRE_REALPHA 0x0cee
+#define regCNVC_CFG0_PRE_REALPHA_BASE_IDX 2
+
+
+// addressBlock: dce_dc_dpp0_dispdec_cnvc_cur_dispdec
+// base address: 0x0
+#define regCNVC_CUR0_CURSOR0_CONTROL 0x0cf1
+#define regCNVC_CUR0_CURSOR0_CONTROL_BASE_IDX 2
+#define regCNVC_CUR0_CURSOR0_COLOR0 0x0cf2
+#define regCNVC_CUR0_CURSOR0_COLOR0_BASE_IDX 2
+#define regCNVC_CUR0_CURSOR0_COLOR1 0x0cf3
+#define regCNVC_CUR0_CURSOR0_COLOR1_BASE_IDX 2
+#define regCNVC_CUR0_CURSOR0_FP_SCALE_BIAS 0x0cf4
+#define regCNVC_CUR0_CURSOR0_FP_SCALE_BIAS_BASE_IDX 2
+
+
+// addressBlock: dce_dc_dpp0_dispdec_dscl_dispdec
+// base address: 0x0
+#define regDSCL0_SCL_COEF_RAM_TAP_SELECT 0x0cf9
+#define regDSCL0_SCL_COEF_RAM_TAP_SELECT_BASE_IDX 2
+#define regDSCL0_SCL_COEF_RAM_TAP_DATA 0x0cfa
+#define regDSCL0_SCL_COEF_RAM_TAP_DATA_BASE_IDX 2
+#define regDSCL0_SCL_MODE 0x0cfb
+#define regDSCL0_SCL_MODE_BASE_IDX 2
+#define regDSCL0_SCL_TAP_CONTROL 0x0cfc
+#define regDSCL0_SCL_TAP_CONTROL_BASE_IDX 2
+#define regDSCL0_DSCL_CONTROL 0x0cfd
+#define regDSCL0_DSCL_CONTROL_BASE_IDX 2
+#define regDSCL0_DSCL_2TAP_CONTROL 0x0cfe
+#define regDSCL0_DSCL_2TAP_CONTROL_BASE_IDX 2
+#define regDSCL0_SCL_MANUAL_REPLICATE_CONTROL 0x0cff
+#define regDSCL0_SCL_MANUAL_REPLICATE_CONTROL_BASE_IDX 2
+#define regDSCL0_SCL_HORZ_FILTER_SCALE_RATIO 0x0d00
+#define regDSCL0_SCL_HORZ_FILTER_SCALE_RATIO_BASE_IDX 2
+#define regDSCL0_SCL_HORZ_FILTER_INIT 0x0d01
+#define regDSCL0_SCL_HORZ_FILTER_INIT_BASE_IDX 2
+#define regDSCL0_SCL_HORZ_FILTER_SCALE_RATIO_C 0x0d02
+#define regDSCL0_SCL_HORZ_FILTER_SCALE_RATIO_C_BASE_IDX 2
+#define regDSCL0_SCL_HORZ_FILTER_INIT_C 0x0d03
+#define regDSCL0_SCL_HORZ_FILTER_INIT_C_BASE_IDX 2
+#define regDSCL0_SCL_VERT_FILTER_SCALE_RATIO 0x0d04
+#define regDSCL0_SCL_VERT_FILTER_SCALE_RATIO_BASE_IDX 2
+#define regDSCL0_SCL_VERT_FILTER_INIT 0x0d05
+#define regDSCL0_SCL_VERT_FILTER_INIT_BASE_IDX 2
+#define regDSCL0_SCL_VERT_FILTER_INIT_BOT 0x0d06
+#define regDSCL0_SCL_VERT_FILTER_INIT_BOT_BASE_IDX 2
+#define regDSCL0_SCL_VERT_FILTER_SCALE_RATIO_C 0x0d07
+#define regDSCL0_SCL_VERT_FILTER_SCALE_RATIO_C_BASE_IDX 2
+#define regDSCL0_SCL_VERT_FILTER_INIT_C 0x0d08
+#define regDSCL0_SCL_VERT_FILTER_INIT_C_BASE_IDX 2
+#define regDSCL0_SCL_VERT_FILTER_INIT_BOT_C 0x0d09
+#define regDSCL0_SCL_VERT_FILTER_INIT_BOT_C_BASE_IDX 2
+#define regDSCL0_SCL_BLACK_COLOR 0x0d0a
+#define regDSCL0_SCL_BLACK_COLOR_BASE_IDX 2
+#define regDSCL0_DSCL_UPDATE 0x0d0b
+#define regDSCL0_DSCL_UPDATE_BASE_IDX 2
+#define regDSCL0_DSCL_AUTOCAL 0x0d0c
+#define regDSCL0_DSCL_AUTOCAL_BASE_IDX 2
+#define regDSCL0_DSCL_EXT_OVERSCAN_LEFT_RIGHT 0x0d0d
+#define regDSCL0_DSCL_EXT_OVERSCAN_LEFT_RIGHT_BASE_IDX 2
+#define regDSCL0_DSCL_EXT_OVERSCAN_TOP_BOTTOM 0x0d0e
+#define regDSCL0_DSCL_EXT_OVERSCAN_TOP_BOTTOM_BASE_IDX 2
+#define regDSCL0_OTG_H_BLANK 0x0d0f
+#define regDSCL0_OTG_H_BLANK_BASE_IDX 2
+#define regDSCL0_OTG_V_BLANK 0x0d10
+#define regDSCL0_OTG_V_BLANK_BASE_IDX 2
+#define regDSCL0_RECOUT_START 0x0d11
+#define regDSCL0_RECOUT_START_BASE_IDX 2
+#define regDSCL0_RECOUT_SIZE 0x0d12
+#define regDSCL0_RECOUT_SIZE_BASE_IDX 2
+#define regDSCL0_MPC_SIZE 0x0d13
+#define regDSCL0_MPC_SIZE_BASE_IDX 2
+#define regDSCL0_LB_DATA_FORMAT 0x0d14
+#define regDSCL0_LB_DATA_FORMAT_BASE_IDX 2
+#define regDSCL0_LB_MEMORY_CTRL 0x0d15
+#define regDSCL0_LB_MEMORY_CTRL_BASE_IDX 2
+#define regDSCL0_LB_V_COUNTER 0x0d16
+#define regDSCL0_LB_V_COUNTER_BASE_IDX 2
+#define regDSCL0_DSCL_MEM_PWR_CTRL 0x0d17
+#define regDSCL0_DSCL_MEM_PWR_CTRL_BASE_IDX 2
+#define regDSCL0_DSCL_MEM_PWR_STATUS 0x0d18
+#define regDSCL0_DSCL_MEM_PWR_STATUS_BASE_IDX 2
+#define regDSCL0_OBUF_CONTROL 0x0d19
+#define regDSCL0_OBUF_CONTROL_BASE_IDX 2
+#define regDSCL0_OBUF_MEM_PWR_CTRL 0x0d1a
+#define regDSCL0_OBUF_MEM_PWR_CTRL_BASE_IDX 2
+
+
+// addressBlock: dce_dc_dpp0_dispdec_cm_dispdec
+// base address: 0x0
+#define regCM0_CM_CONTROL 0x0d20
+#define regCM0_CM_CONTROL_BASE_IDX 2
+#define regCM0_CM_POST_CSC_CONTROL 0x0d21
+#define regCM0_CM_POST_CSC_CONTROL_BASE_IDX 2
+#define regCM0_CM_POST_CSC_C11_C12 0x0d22
+#define regCM0_CM_POST_CSC_C11_C12_BASE_IDX 2
+#define regCM0_CM_POST_CSC_C13_C14 0x0d23
+#define regCM0_CM_POST_CSC_C13_C14_BASE_IDX 2
+#define regCM0_CM_POST_CSC_C21_C22 0x0d24
+#define regCM0_CM_POST_CSC_C21_C22_BASE_IDX 2
+#define regCM0_CM_POST_CSC_C23_C24 0x0d25
+#define regCM0_CM_POST_CSC_C23_C24_BASE_IDX 2
+#define regCM0_CM_POST_CSC_C31_C32 0x0d26
+#define regCM0_CM_POST_CSC_C31_C32_BASE_IDX 2
+#define regCM0_CM_POST_CSC_C33_C34 0x0d27
+#define regCM0_CM_POST_CSC_C33_C34_BASE_IDX 2
+#define regCM0_CM_POST_CSC_B_C11_C12 0x0d28
+#define regCM0_CM_POST_CSC_B_C11_C12_BASE_IDX 2
+#define regCM0_CM_POST_CSC_B_C13_C14 0x0d29
+#define regCM0_CM_POST_CSC_B_C13_C14_BASE_IDX 2
+#define regCM0_CM_POST_CSC_B_C21_C22 0x0d2a
+#define regCM0_CM_POST_CSC_B_C21_C22_BASE_IDX 2
+#define regCM0_CM_POST_CSC_B_C23_C24 0x0d2b
+#define regCM0_CM_POST_CSC_B_C23_C24_BASE_IDX 2
+#define regCM0_CM_POST_CSC_B_C31_C32 0x0d2c
+#define regCM0_CM_POST_CSC_B_C31_C32_BASE_IDX 2
+#define regCM0_CM_POST_CSC_B_C33_C34 0x0d2d
+#define regCM0_CM_POST_CSC_B_C33_C34_BASE_IDX 2
+#define regCM0_CM_GAMUT_REMAP_CONTROL 0x0d2e
+#define regCM0_CM_GAMUT_REMAP_CONTROL_BASE_IDX 2
+#define regCM0_CM_GAMUT_REMAP_C11_C12 0x0d2f
+#define regCM0_CM_GAMUT_REMAP_C11_C12_BASE_IDX 2
+#define regCM0_CM_GAMUT_REMAP_C13_C14 0x0d30
+#define regCM0_CM_GAMUT_REMAP_C13_C14_BASE_IDX 2
+#define regCM0_CM_GAMUT_REMAP_C21_C22 0x0d31
+#define regCM0_CM_GAMUT_REMAP_C21_C22_BASE_IDX 2
+#define regCM0_CM_GAMUT_REMAP_C23_C24 0x0d32
+#define regCM0_CM_GAMUT_REMAP_C23_C24_BASE_IDX 2
+#define regCM0_CM_GAMUT_REMAP_C31_C32 0x0d33
+#define regCM0_CM_GAMUT_REMAP_C31_C32_BASE_IDX 2
+#define regCM0_CM_GAMUT_REMAP_C33_C34 0x0d34
+#define regCM0_CM_GAMUT_REMAP_C33_C34_BASE_IDX 2
+#define regCM0_CM_GAMUT_REMAP_B_C11_C12 0x0d35
+#define regCM0_CM_GAMUT_REMAP_B_C11_C12_BASE_IDX 2
+#define regCM0_CM_GAMUT_REMAP_B_C13_C14 0x0d36
+#define regCM0_CM_GAMUT_REMAP_B_C13_C14_BASE_IDX 2
+#define regCM0_CM_GAMUT_REMAP_B_C21_C22 0x0d37
+#define regCM0_CM_GAMUT_REMAP_B_C21_C22_BASE_IDX 2
+#define regCM0_CM_GAMUT_REMAP_B_C23_C24 0x0d38
+#define regCM0_CM_GAMUT_REMAP_B_C23_C24_BASE_IDX 2
+#define regCM0_CM_GAMUT_REMAP_B_C31_C32 0x0d39
+#define regCM0_CM_GAMUT_REMAP_B_C31_C32_BASE_IDX 2
+#define regCM0_CM_GAMUT_REMAP_B_C33_C34 0x0d3a
+#define regCM0_CM_GAMUT_REMAP_B_C33_C34_BASE_IDX 2
+#define regCM0_CM_BIAS_CR_R 0x0d3b
+#define regCM0_CM_BIAS_CR_R_BASE_IDX 2
+#define regCM0_CM_BIAS_Y_G_CB_B 0x0d3c
+#define regCM0_CM_BIAS_Y_G_CB_B_BASE_IDX 2
+#define regCM0_CM_GAMCOR_CONTROL 0x0d3d
+#define regCM0_CM_GAMCOR_CONTROL_BASE_IDX 2
+#define regCM0_CM_GAMCOR_LUT_INDEX 0x0d3e
+#define regCM0_CM_GAMCOR_LUT_INDEX_BASE_IDX 2
+#define regCM0_CM_GAMCOR_LUT_DATA 0x0d3f
+#define regCM0_CM_GAMCOR_LUT_DATA_BASE_IDX 2
+#define regCM0_CM_GAMCOR_LUT_CONTROL 0x0d40
+#define regCM0_CM_GAMCOR_LUT_CONTROL_BASE_IDX 2
+#define regCM0_CM_GAMCOR_RAMA_START_CNTL_B 0x0d41
+#define regCM0_CM_GAMCOR_RAMA_START_CNTL_B_BASE_IDX 2
+#define regCM0_CM_GAMCOR_RAMA_START_CNTL_G 0x0d42
+#define regCM0_CM_GAMCOR_RAMA_START_CNTL_G_BASE_IDX 2
+#define regCM0_CM_GAMCOR_RAMA_START_CNTL_R 0x0d43
+#define regCM0_CM_GAMCOR_RAMA_START_CNTL_R_BASE_IDX 2
+#define regCM0_CM_GAMCOR_RAMA_START_SLOPE_CNTL_B 0x0d44
+#define regCM0_CM_GAMCOR_RAMA_START_SLOPE_CNTL_B_BASE_IDX 2
+#define regCM0_CM_GAMCOR_RAMA_START_SLOPE_CNTL_G 0x0d45
+#define regCM0_CM_GAMCOR_RAMA_START_SLOPE_CNTL_G_BASE_IDX 2
+#define regCM0_CM_GAMCOR_RAMA_START_SLOPE_CNTL_R 0x0d46
+#define regCM0_CM_GAMCOR_RAMA_START_SLOPE_CNTL_R_BASE_IDX 2
+#define regCM0_CM_GAMCOR_RAMA_START_BASE_CNTL_B 0x0d47
+#define regCM0_CM_GAMCOR_RAMA_START_BASE_CNTL_B_BASE_IDX 2
+#define regCM0_CM_GAMCOR_RAMA_START_BASE_CNTL_G 0x0d48
+#define regCM0_CM_GAMCOR_RAMA_START_BASE_CNTL_G_BASE_IDX 2
+#define regCM0_CM_GAMCOR_RAMA_START_BASE_CNTL_R 0x0d49
+#define regCM0_CM_GAMCOR_RAMA_START_BASE_CNTL_R_BASE_IDX 2
+#define regCM0_CM_GAMCOR_RAMA_END_CNTL1_B 0x0d4a
+#define regCM0_CM_GAMCOR_RAMA_END_CNTL1_B_BASE_IDX 2
+#define regCM0_CM_GAMCOR_RAMA_END_CNTL2_B 0x0d4b
+#define regCM0_CM_GAMCOR_RAMA_END_CNTL2_B_BASE_IDX 2
+#define regCM0_CM_GAMCOR_RAMA_END_CNTL1_G 0x0d4c
+#define regCM0_CM_GAMCOR_RAMA_END_CNTL1_G_BASE_IDX 2
+#define regCM0_CM_GAMCOR_RAMA_END_CNTL2_G 0x0d4d
+#define regCM0_CM_GAMCOR_RAMA_END_CNTL2_G_BASE_IDX 2
+#define regCM0_CM_GAMCOR_RAMA_END_CNTL1_R 0x0d4e
+#define regCM0_CM_GAMCOR_RAMA_END_CNTL1_R_BASE_IDX 2
+#define regCM0_CM_GAMCOR_RAMA_END_CNTL2_R 0x0d4f
+#define regCM0_CM_GAMCOR_RAMA_END_CNTL2_R_BASE_IDX 2
+#define regCM0_CM_GAMCOR_RAMA_OFFSET_B 0x0d50
+#define regCM0_CM_GAMCOR_RAMA_OFFSET_B_BASE_IDX 2
+#define regCM0_CM_GAMCOR_RAMA_OFFSET_G 0x0d51
+#define regCM0_CM_GAMCOR_RAMA_OFFSET_G_BASE_IDX 2
+#define regCM0_CM_GAMCOR_RAMA_OFFSET_R 0x0d52
+#define regCM0_CM_GAMCOR_RAMA_OFFSET_R_BASE_IDX 2
+#define regCM0_CM_GAMCOR_RAMA_REGION_0_1 0x0d53
+#define regCM0_CM_GAMCOR_RAMA_REGION_0_1_BASE_IDX 2
+#define regCM0_CM_GAMCOR_RAMA_REGION_2_3 0x0d54
+#define regCM0_CM_GAMCOR_RAMA_REGION_2_3_BASE_IDX 2
+#define regCM0_CM_GAMCOR_RAMA_REGION_4_5 0x0d55
+#define regCM0_CM_GAMCOR_RAMA_REGION_4_5_BASE_IDX 2
+#define regCM0_CM_GAMCOR_RAMA_REGION_6_7 0x0d56
+#define regCM0_CM_GAMCOR_RAMA_REGION_6_7_BASE_IDX 2
+#define regCM0_CM_GAMCOR_RAMA_REGION_8_9 0x0d57
+#define regCM0_CM_GAMCOR_RAMA_REGION_8_9_BASE_IDX 2
+#define regCM0_CM_GAMCOR_RAMA_REGION_10_11 0x0d58
+#define regCM0_CM_GAMCOR_RAMA_REGION_10_11_BASE_IDX 2
+#define regCM0_CM_GAMCOR_RAMA_REGION_12_13 0x0d59
+#define regCM0_CM_GAMCOR_RAMA_REGION_12_13_BASE_IDX 2
+#define regCM0_CM_GAMCOR_RAMA_REGION_14_15 0x0d5a
+#define regCM0_CM_GAMCOR_RAMA_REGION_14_15_BASE_IDX 2
+#define regCM0_CM_GAMCOR_RAMA_REGION_16_17 0x0d5b
+#define regCM0_CM_GAMCOR_RAMA_REGION_16_17_BASE_IDX 2
+#define regCM0_CM_GAMCOR_RAMA_REGION_18_19 0x0d5c
+#define regCM0_CM_GAMCOR_RAMA_REGION_18_19_BASE_IDX 2
+#define regCM0_CM_GAMCOR_RAMA_REGION_20_21 0x0d5d
+#define regCM0_CM_GAMCOR_RAMA_REGION_20_21_BASE_IDX 2
+#define regCM0_CM_GAMCOR_RAMA_REGION_22_23 0x0d5e
+#define regCM0_CM_GAMCOR_RAMA_REGION_22_23_BASE_IDX 2
+#define regCM0_CM_GAMCOR_RAMA_REGION_24_25 0x0d5f
+#define regCM0_CM_GAMCOR_RAMA_REGION_24_25_BASE_IDX 2
+#define regCM0_CM_GAMCOR_RAMA_REGION_26_27 0x0d60
+#define regCM0_CM_GAMCOR_RAMA_REGION_26_27_BASE_IDX 2
+#define regCM0_CM_GAMCOR_RAMA_REGION_28_29 0x0d61
+#define regCM0_CM_GAMCOR_RAMA_REGION_28_29_BASE_IDX 2
+#define regCM0_CM_GAMCOR_RAMA_REGION_30_31 0x0d62
+#define regCM0_CM_GAMCOR_RAMA_REGION_30_31_BASE_IDX 2
+#define regCM0_CM_GAMCOR_RAMA_REGION_32_33 0x0d63
+#define regCM0_CM_GAMCOR_RAMA_REGION_32_33_BASE_IDX 2
+#define regCM0_CM_GAMCOR_RAMB_START_CNTL_B 0x0d64
+#define regCM0_CM_GAMCOR_RAMB_START_CNTL_B_BASE_IDX 2
+#define regCM0_CM_GAMCOR_RAMB_START_CNTL_G 0x0d65
+#define regCM0_CM_GAMCOR_RAMB_START_CNTL_G_BASE_IDX 2
+#define regCM0_CM_GAMCOR_RAMB_START_CNTL_R 0x0d66
+#define regCM0_CM_GAMCOR_RAMB_START_CNTL_R_BASE_IDX 2
+#define regCM0_CM_GAMCOR_RAMB_START_SLOPE_CNTL_B 0x0d67
+#define regCM0_CM_GAMCOR_RAMB_START_SLOPE_CNTL_B_BASE_IDX 2
+#define regCM0_CM_GAMCOR_RAMB_START_SLOPE_CNTL_G 0x0d68
+#define regCM0_CM_GAMCOR_RAMB_START_SLOPE_CNTL_G_BASE_IDX 2
+#define regCM0_CM_GAMCOR_RAMB_START_SLOPE_CNTL_R 0x0d69
+#define regCM0_CM_GAMCOR_RAMB_START_SLOPE_CNTL_R_BASE_IDX 2
+#define regCM0_CM_GAMCOR_RAMB_START_BASE_CNTL_B 0x0d6a
+#define regCM0_CM_GAMCOR_RAMB_START_BASE_CNTL_B_BASE_IDX 2
+#define regCM0_CM_GAMCOR_RAMB_START_BASE_CNTL_G 0x0d6b
+#define regCM0_CM_GAMCOR_RAMB_START_BASE_CNTL_G_BASE_IDX 2
+#define regCM0_CM_GAMCOR_RAMB_START_BASE_CNTL_R 0x0d6c
+#define regCM0_CM_GAMCOR_RAMB_START_BASE_CNTL_R_BASE_IDX 2
+#define regCM0_CM_GAMCOR_RAMB_END_CNTL1_B 0x0d6d
+#define regCM0_CM_GAMCOR_RAMB_END_CNTL1_B_BASE_IDX 2
+#define regCM0_CM_GAMCOR_RAMB_END_CNTL2_B 0x0d6e
+#define regCM0_CM_GAMCOR_RAMB_END_CNTL2_B_BASE_IDX 2
+#define regCM0_CM_GAMCOR_RAMB_END_CNTL1_G 0x0d6f
+#define regCM0_CM_GAMCOR_RAMB_END_CNTL1_G_BASE_IDX 2
+#define regCM0_CM_GAMCOR_RAMB_END_CNTL2_G 0x0d70
+#define regCM0_CM_GAMCOR_RAMB_END_CNTL2_G_BASE_IDX 2
+#define regCM0_CM_GAMCOR_RAMB_END_CNTL1_R 0x0d71
+#define regCM0_CM_GAMCOR_RAMB_END_CNTL1_R_BASE_IDX 2
+#define regCM0_CM_GAMCOR_RAMB_END_CNTL2_R 0x0d72
+#define regCM0_CM_GAMCOR_RAMB_END_CNTL2_R_BASE_IDX 2
+#define regCM0_CM_GAMCOR_RAMB_OFFSET_B 0x0d73
+#define regCM0_CM_GAMCOR_RAMB_OFFSET_B_BASE_IDX 2
+#define regCM0_CM_GAMCOR_RAMB_OFFSET_G 0x0d74
+#define regCM0_CM_GAMCOR_RAMB_OFFSET_G_BASE_IDX 2
+#define regCM0_CM_GAMCOR_RAMB_OFFSET_R 0x0d75
+#define regCM0_CM_GAMCOR_RAMB_OFFSET_R_BASE_IDX 2
+#define regCM0_CM_GAMCOR_RAMB_REGION_0_1 0x0d76
+#define regCM0_CM_GAMCOR_RAMB_REGION_0_1_BASE_IDX 2
+#define regCM0_CM_GAMCOR_RAMB_REGION_2_3 0x0d77
+#define regCM0_CM_GAMCOR_RAMB_REGION_2_3_BASE_IDX 2
+#define regCM0_CM_GAMCOR_RAMB_REGION_4_5 0x0d78
+#define regCM0_CM_GAMCOR_RAMB_REGION_4_5_BASE_IDX 2
+#define regCM0_CM_GAMCOR_RAMB_REGION_6_7 0x0d79
+#define regCM0_CM_GAMCOR_RAMB_REGION_6_7_BASE_IDX 2
+#define regCM0_CM_GAMCOR_RAMB_REGION_8_9 0x0d7a
+#define regCM0_CM_GAMCOR_RAMB_REGION_8_9_BASE_IDX 2
+#define regCM0_CM_GAMCOR_RAMB_REGION_10_11 0x0d7b
+#define regCM0_CM_GAMCOR_RAMB_REGION_10_11_BASE_IDX 2
+#define regCM0_CM_GAMCOR_RAMB_REGION_12_13 0x0d7c
+#define regCM0_CM_GAMCOR_RAMB_REGION_12_13_BASE_IDX 2
+#define regCM0_CM_GAMCOR_RAMB_REGION_14_15 0x0d7d
+#define regCM0_CM_GAMCOR_RAMB_REGION_14_15_BASE_IDX 2
+#define regCM0_CM_GAMCOR_RAMB_REGION_16_17 0x0d7e
+#define regCM0_CM_GAMCOR_RAMB_REGION_16_17_BASE_IDX 2
+#define regCM0_CM_GAMCOR_RAMB_REGION_18_19 0x0d7f
+#define regCM0_CM_GAMCOR_RAMB_REGION_18_19_BASE_IDX 2
+#define regCM0_CM_GAMCOR_RAMB_REGION_20_21 0x0d80
+#define regCM0_CM_GAMCOR_RAMB_REGION_20_21_BASE_IDX 2
+#define regCM0_CM_GAMCOR_RAMB_REGION_22_23 0x0d81
+#define regCM0_CM_GAMCOR_RAMB_REGION_22_23_BASE_IDX 2
+#define regCM0_CM_GAMCOR_RAMB_REGION_24_25 0x0d82
+#define regCM0_CM_GAMCOR_RAMB_REGION_24_25_BASE_IDX 2
+#define regCM0_CM_GAMCOR_RAMB_REGION_26_27 0x0d83
+#define regCM0_CM_GAMCOR_RAMB_REGION_26_27_BASE_IDX 2
+#define regCM0_CM_GAMCOR_RAMB_REGION_28_29 0x0d84
+#define regCM0_CM_GAMCOR_RAMB_REGION_28_29_BASE_IDX 2
+#define regCM0_CM_GAMCOR_RAMB_REGION_30_31 0x0d85
+#define regCM0_CM_GAMCOR_RAMB_REGION_30_31_BASE_IDX 2
+#define regCM0_CM_GAMCOR_RAMB_REGION_32_33 0x0d86
+#define regCM0_CM_GAMCOR_RAMB_REGION_32_33_BASE_IDX 2
+#define regCM0_CM_BLNDGAM_CONTROL 0x0d87
+#define regCM0_CM_BLNDGAM_CONTROL_BASE_IDX 2
+#define regCM0_CM_BLNDGAM_LUT_INDEX 0x0d88
+#define regCM0_CM_BLNDGAM_LUT_INDEX_BASE_IDX 2
+#define regCM0_CM_BLNDGAM_LUT_DATA 0x0d89
+#define regCM0_CM_BLNDGAM_LUT_DATA_BASE_IDX 2
+#define regCM0_CM_BLNDGAM_LUT_CONTROL 0x0d8a
+#define regCM0_CM_BLNDGAM_LUT_CONTROL_BASE_IDX 2
+#define regCM0_CM_BLNDGAM_RAMA_START_CNTL_B 0x0d8b
+#define regCM0_CM_BLNDGAM_RAMA_START_CNTL_B_BASE_IDX 2
+#define regCM0_CM_BLNDGAM_RAMA_START_CNTL_G 0x0d8c
+#define regCM0_CM_BLNDGAM_RAMA_START_CNTL_G_BASE_IDX 2
+#define regCM0_CM_BLNDGAM_RAMA_START_CNTL_R 0x0d8d
+#define regCM0_CM_BLNDGAM_RAMA_START_CNTL_R_BASE_IDX 2
+#define regCM0_CM_BLNDGAM_RAMA_START_SLOPE_CNTL_B 0x0d8e
+#define regCM0_CM_BLNDGAM_RAMA_START_SLOPE_CNTL_B_BASE_IDX 2
+#define regCM0_CM_BLNDGAM_RAMA_START_SLOPE_CNTL_G 0x0d8f
+#define regCM0_CM_BLNDGAM_RAMA_START_SLOPE_CNTL_G_BASE_IDX 2
+#define regCM0_CM_BLNDGAM_RAMA_START_SLOPE_CNTL_R 0x0d90
+#define regCM0_CM_BLNDGAM_RAMA_START_SLOPE_CNTL_R_BASE_IDX 2
+#define regCM0_CM_BLNDGAM_RAMA_START_BASE_CNTL_B 0x0d91
+#define regCM0_CM_BLNDGAM_RAMA_START_BASE_CNTL_B_BASE_IDX 2
+#define regCM0_CM_BLNDGAM_RAMA_START_BASE_CNTL_G 0x0d92
+#define regCM0_CM_BLNDGAM_RAMA_START_BASE_CNTL_G_BASE_IDX 2
+#define regCM0_CM_BLNDGAM_RAMA_START_BASE_CNTL_R 0x0d93
+#define regCM0_CM_BLNDGAM_RAMA_START_BASE_CNTL_R_BASE_IDX 2
+#define regCM0_CM_BLNDGAM_RAMA_END_CNTL1_B 0x0d94
+#define regCM0_CM_BLNDGAM_RAMA_END_CNTL1_B_BASE_IDX 2
+#define regCM0_CM_BLNDGAM_RAMA_END_CNTL2_B 0x0d95
+#define regCM0_CM_BLNDGAM_RAMA_END_CNTL2_B_BASE_IDX 2
+#define regCM0_CM_BLNDGAM_RAMA_END_CNTL1_G 0x0d96
+#define regCM0_CM_BLNDGAM_RAMA_END_CNTL1_G_BASE_IDX 2
+#define regCM0_CM_BLNDGAM_RAMA_END_CNTL2_G 0x0d97
+#define regCM0_CM_BLNDGAM_RAMA_END_CNTL2_G_BASE_IDX 2
+#define regCM0_CM_BLNDGAM_RAMA_END_CNTL1_R 0x0d98
+#define regCM0_CM_BLNDGAM_RAMA_END_CNTL1_R_BASE_IDX 2
+#define regCM0_CM_BLNDGAM_RAMA_END_CNTL2_R 0x0d99
+#define regCM0_CM_BLNDGAM_RAMA_END_CNTL2_R_BASE_IDX 2
+#define regCM0_CM_BLNDGAM_RAMA_OFFSET_B 0x0d9a
+#define regCM0_CM_BLNDGAM_RAMA_OFFSET_B_BASE_IDX 2
+#define regCM0_CM_BLNDGAM_RAMA_OFFSET_G 0x0d9b
+#define regCM0_CM_BLNDGAM_RAMA_OFFSET_G_BASE_IDX 2
+#define regCM0_CM_BLNDGAM_RAMA_OFFSET_R 0x0d9c
+#define regCM0_CM_BLNDGAM_RAMA_OFFSET_R_BASE_IDX 2
+#define regCM0_CM_BLNDGAM_RAMA_REGION_0_1 0x0d9d
+#define regCM0_CM_BLNDGAM_RAMA_REGION_0_1_BASE_IDX 2
+#define regCM0_CM_BLNDGAM_RAMA_REGION_2_3 0x0d9e
+#define regCM0_CM_BLNDGAM_RAMA_REGION_2_3_BASE_IDX 2
+#define regCM0_CM_BLNDGAM_RAMA_REGION_4_5 0x0d9f
+#define regCM0_CM_BLNDGAM_RAMA_REGION_4_5_BASE_IDX 2
+#define regCM0_CM_BLNDGAM_RAMA_REGION_6_7 0x0da0
+#define regCM0_CM_BLNDGAM_RAMA_REGION_6_7_BASE_IDX 2
+#define regCM0_CM_BLNDGAM_RAMA_REGION_8_9 0x0da1
+#define regCM0_CM_BLNDGAM_RAMA_REGION_8_9_BASE_IDX 2
+#define regCM0_CM_BLNDGAM_RAMA_REGION_10_11 0x0da2
+#define regCM0_CM_BLNDGAM_RAMA_REGION_10_11_BASE_IDX 2
+#define regCM0_CM_BLNDGAM_RAMA_REGION_12_13 0x0da3
+#define regCM0_CM_BLNDGAM_RAMA_REGION_12_13_BASE_IDX 2
+#define regCM0_CM_BLNDGAM_RAMA_REGION_14_15 0x0da4
+#define regCM0_CM_BLNDGAM_RAMA_REGION_14_15_BASE_IDX 2
+#define regCM0_CM_BLNDGAM_RAMA_REGION_16_17 0x0da5
+#define regCM0_CM_BLNDGAM_RAMA_REGION_16_17_BASE_IDX 2
+#define regCM0_CM_BLNDGAM_RAMA_REGION_18_19 0x0da6
+#define regCM0_CM_BLNDGAM_RAMA_REGION_18_19_BASE_IDX 2
+#define regCM0_CM_BLNDGAM_RAMA_REGION_20_21 0x0da7
+#define regCM0_CM_BLNDGAM_RAMA_REGION_20_21_BASE_IDX 2
+#define regCM0_CM_BLNDGAM_RAMA_REGION_22_23 0x0da8
+#define regCM0_CM_BLNDGAM_RAMA_REGION_22_23_BASE_IDX 2
+#define regCM0_CM_BLNDGAM_RAMA_REGION_24_25 0x0da9
+#define regCM0_CM_BLNDGAM_RAMA_REGION_24_25_BASE_IDX 2
+#define regCM0_CM_BLNDGAM_RAMA_REGION_26_27 0x0daa
+#define regCM0_CM_BLNDGAM_RAMA_REGION_26_27_BASE_IDX 2
+#define regCM0_CM_BLNDGAM_RAMA_REGION_28_29 0x0dab
+#define regCM0_CM_BLNDGAM_RAMA_REGION_28_29_BASE_IDX 2
+#define regCM0_CM_BLNDGAM_RAMA_REGION_30_31 0x0dac
+#define regCM0_CM_BLNDGAM_RAMA_REGION_30_31_BASE_IDX 2
+#define regCM0_CM_BLNDGAM_RAMA_REGION_32_33 0x0dad
+#define regCM0_CM_BLNDGAM_RAMA_REGION_32_33_BASE_IDX 2
+#define regCM0_CM_BLNDGAM_RAMB_START_CNTL_B 0x0dae
+#define regCM0_CM_BLNDGAM_RAMB_START_CNTL_B_BASE_IDX 2
+#define regCM0_CM_BLNDGAM_RAMB_START_CNTL_G 0x0daf
+#define regCM0_CM_BLNDGAM_RAMB_START_CNTL_G_BASE_IDX 2
+#define regCM0_CM_BLNDGAM_RAMB_START_CNTL_R 0x0db0
+#define regCM0_CM_BLNDGAM_RAMB_START_CNTL_R_BASE_IDX 2
+#define regCM0_CM_BLNDGAM_RAMB_START_SLOPE_CNTL_B 0x0db1
+#define regCM0_CM_BLNDGAM_RAMB_START_SLOPE_CNTL_B_BASE_IDX 2
+#define regCM0_CM_BLNDGAM_RAMB_START_SLOPE_CNTL_G 0x0db2
+#define regCM0_CM_BLNDGAM_RAMB_START_SLOPE_CNTL_G_BASE_IDX 2
+#define regCM0_CM_BLNDGAM_RAMB_START_SLOPE_CNTL_R 0x0db3
+#define regCM0_CM_BLNDGAM_RAMB_START_SLOPE_CNTL_R_BASE_IDX 2
+#define regCM0_CM_BLNDGAM_RAMB_START_BASE_CNTL_B 0x0db4
+#define regCM0_CM_BLNDGAM_RAMB_START_BASE_CNTL_B_BASE_IDX 2
+#define regCM0_CM_BLNDGAM_RAMB_START_BASE_CNTL_G 0x0db5
+#define regCM0_CM_BLNDGAM_RAMB_START_BASE_CNTL_G_BASE_IDX 2
+#define regCM0_CM_BLNDGAM_RAMB_START_BASE_CNTL_R 0x0db6
+#define regCM0_CM_BLNDGAM_RAMB_START_BASE_CNTL_R_BASE_IDX 2
+#define regCM0_CM_BLNDGAM_RAMB_END_CNTL1_B 0x0db7
+#define regCM0_CM_BLNDGAM_RAMB_END_CNTL1_B_BASE_IDX 2
+#define regCM0_CM_BLNDGAM_RAMB_END_CNTL2_B 0x0db8
+#define regCM0_CM_BLNDGAM_RAMB_END_CNTL2_B_BASE_IDX 2
+#define regCM0_CM_BLNDGAM_RAMB_END_CNTL1_G 0x0db9
+#define regCM0_CM_BLNDGAM_RAMB_END_CNTL1_G_BASE_IDX 2
+#define regCM0_CM_BLNDGAM_RAMB_END_CNTL2_G 0x0dba
+#define regCM0_CM_BLNDGAM_RAMB_END_CNTL2_G_BASE_IDX 2
+#define regCM0_CM_BLNDGAM_RAMB_END_CNTL1_R 0x0dbb
+#define regCM0_CM_BLNDGAM_RAMB_END_CNTL1_R_BASE_IDX 2
+#define regCM0_CM_BLNDGAM_RAMB_END_CNTL2_R 0x0dbc
+#define regCM0_CM_BLNDGAM_RAMB_END_CNTL2_R_BASE_IDX 2
+#define regCM0_CM_BLNDGAM_RAMB_OFFSET_B 0x0dbd
+#define regCM0_CM_BLNDGAM_RAMB_OFFSET_B_BASE_IDX 2
+#define regCM0_CM_BLNDGAM_RAMB_OFFSET_G 0x0dbe
+#define regCM0_CM_BLNDGAM_RAMB_OFFSET_G_BASE_IDX 2
+#define regCM0_CM_BLNDGAM_RAMB_OFFSET_R 0x0dbf
+#define regCM0_CM_BLNDGAM_RAMB_OFFSET_R_BASE_IDX 2
+#define regCM0_CM_BLNDGAM_RAMB_REGION_0_1 0x0dc0
+#define regCM0_CM_BLNDGAM_RAMB_REGION_0_1_BASE_IDX 2
+#define regCM0_CM_BLNDGAM_RAMB_REGION_2_3 0x0dc1
+#define regCM0_CM_BLNDGAM_RAMB_REGION_2_3_BASE_IDX 2
+#define regCM0_CM_BLNDGAM_RAMB_REGION_4_5 0x0dc2
+#define regCM0_CM_BLNDGAM_RAMB_REGION_4_5_BASE_IDX 2
+#define regCM0_CM_BLNDGAM_RAMB_REGION_6_7 0x0dc3
+#define regCM0_CM_BLNDGAM_RAMB_REGION_6_7_BASE_IDX 2
+#define regCM0_CM_BLNDGAM_RAMB_REGION_8_9 0x0dc4
+#define regCM0_CM_BLNDGAM_RAMB_REGION_8_9_BASE_IDX 2
+#define regCM0_CM_BLNDGAM_RAMB_REGION_10_11 0x0dc5
+#define regCM0_CM_BLNDGAM_RAMB_REGION_10_11_BASE_IDX 2
+#define regCM0_CM_BLNDGAM_RAMB_REGION_12_13 0x0dc6
+#define regCM0_CM_BLNDGAM_RAMB_REGION_12_13_BASE_IDX 2
+#define regCM0_CM_BLNDGAM_RAMB_REGION_14_15 0x0dc7
+#define regCM0_CM_BLNDGAM_RAMB_REGION_14_15_BASE_IDX 2
+#define regCM0_CM_BLNDGAM_RAMB_REGION_16_17 0x0dc8
+#define regCM0_CM_BLNDGAM_RAMB_REGION_16_17_BASE_IDX 2
+#define regCM0_CM_BLNDGAM_RAMB_REGION_18_19 0x0dc9
+#define regCM0_CM_BLNDGAM_RAMB_REGION_18_19_BASE_IDX 2
+#define regCM0_CM_BLNDGAM_RAMB_REGION_20_21 0x0dca
+#define regCM0_CM_BLNDGAM_RAMB_REGION_20_21_BASE_IDX 2
+#define regCM0_CM_BLNDGAM_RAMB_REGION_22_23 0x0dcb
+#define regCM0_CM_BLNDGAM_RAMB_REGION_22_23_BASE_IDX 2
+#define regCM0_CM_BLNDGAM_RAMB_REGION_24_25 0x0dcc
+#define regCM0_CM_BLNDGAM_RAMB_REGION_24_25_BASE_IDX 2
+#define regCM0_CM_BLNDGAM_RAMB_REGION_26_27 0x0dcd
+#define regCM0_CM_BLNDGAM_RAMB_REGION_26_27_BASE_IDX 2
+#define regCM0_CM_BLNDGAM_RAMB_REGION_28_29 0x0dce
+#define regCM0_CM_BLNDGAM_RAMB_REGION_28_29_BASE_IDX 2
+#define regCM0_CM_BLNDGAM_RAMB_REGION_30_31 0x0dcf
+#define regCM0_CM_BLNDGAM_RAMB_REGION_30_31_BASE_IDX 2
+#define regCM0_CM_BLNDGAM_RAMB_REGION_32_33 0x0dd0
+#define regCM0_CM_BLNDGAM_RAMB_REGION_32_33_BASE_IDX 2
+#define regCM0_CM_HDR_MULT_COEF 0x0dd1
+#define regCM0_CM_HDR_MULT_COEF_BASE_IDX 2
+#define regCM0_CM_MEM_PWR_CTRL 0x0dd2
+#define regCM0_CM_MEM_PWR_CTRL_BASE_IDX 2
+#define regCM0_CM_MEM_PWR_STATUS 0x0dd3
+#define regCM0_CM_MEM_PWR_STATUS_BASE_IDX 2
+#define regCM0_CM_DEALPHA 0x0dd5
+#define regCM0_CM_DEALPHA_BASE_IDX 2
+#define regCM0_CM_COEF_FORMAT 0x0dd6
+#define regCM0_CM_COEF_FORMAT_BASE_IDX 2
+#define regCM0_CM_SHAPER_CONTROL 0x0dd7
+#define regCM0_CM_SHAPER_CONTROL_BASE_IDX 2
+#define regCM0_CM_SHAPER_OFFSET_R 0x0dd8
+#define regCM0_CM_SHAPER_OFFSET_R_BASE_IDX 2
+#define regCM0_CM_SHAPER_OFFSET_G 0x0dd9
+#define regCM0_CM_SHAPER_OFFSET_G_BASE_IDX 2
+#define regCM0_CM_SHAPER_OFFSET_B 0x0dda
+#define regCM0_CM_SHAPER_OFFSET_B_BASE_IDX 2
+#define regCM0_CM_SHAPER_SCALE_R 0x0ddb
+#define regCM0_CM_SHAPER_SCALE_R_BASE_IDX 2
+#define regCM0_CM_SHAPER_SCALE_G_B 0x0ddc
+#define regCM0_CM_SHAPER_SCALE_G_B_BASE_IDX 2
+#define regCM0_CM_SHAPER_LUT_INDEX 0x0ddd
+#define regCM0_CM_SHAPER_LUT_INDEX_BASE_IDX 2
+#define regCM0_CM_SHAPER_LUT_DATA 0x0dde
+#define regCM0_CM_SHAPER_LUT_DATA_BASE_IDX 2
+#define regCM0_CM_SHAPER_LUT_WRITE_EN_MASK 0x0ddf
+#define regCM0_CM_SHAPER_LUT_WRITE_EN_MASK_BASE_IDX 2
+#define regCM0_CM_SHAPER_RAMA_START_CNTL_B 0x0de0
+#define regCM0_CM_SHAPER_RAMA_START_CNTL_B_BASE_IDX 2
+#define regCM0_CM_SHAPER_RAMA_START_CNTL_G 0x0de1
+#define regCM0_CM_SHAPER_RAMA_START_CNTL_G_BASE_IDX 2
+#define regCM0_CM_SHAPER_RAMA_START_CNTL_R 0x0de2
+#define regCM0_CM_SHAPER_RAMA_START_CNTL_R_BASE_IDX 2
+#define regCM0_CM_SHAPER_RAMA_END_CNTL_B 0x0de3
+#define regCM0_CM_SHAPER_RAMA_END_CNTL_B_BASE_IDX 2
+#define regCM0_CM_SHAPER_RAMA_END_CNTL_G 0x0de4
+#define regCM0_CM_SHAPER_RAMA_END_CNTL_G_BASE_IDX 2
+#define regCM0_CM_SHAPER_RAMA_END_CNTL_R 0x0de5
+#define regCM0_CM_SHAPER_RAMA_END_CNTL_R_BASE_IDX 2
+#define regCM0_CM_SHAPER_RAMA_REGION_0_1 0x0de6
+#define regCM0_CM_SHAPER_RAMA_REGION_0_1_BASE_IDX 2
+#define regCM0_CM_SHAPER_RAMA_REGION_2_3 0x0de7
+#define regCM0_CM_SHAPER_RAMA_REGION_2_3_BASE_IDX 2
+#define regCM0_CM_SHAPER_RAMA_REGION_4_5 0x0de8
+#define regCM0_CM_SHAPER_RAMA_REGION_4_5_BASE_IDX 2
+#define regCM0_CM_SHAPER_RAMA_REGION_6_7 0x0de9
+#define regCM0_CM_SHAPER_RAMA_REGION_6_7_BASE_IDX 2
+#define regCM0_CM_SHAPER_RAMA_REGION_8_9 0x0dea
+#define regCM0_CM_SHAPER_RAMA_REGION_8_9_BASE_IDX 2
+#define regCM0_CM_SHAPER_RAMA_REGION_10_11 0x0deb
+#define regCM0_CM_SHAPER_RAMA_REGION_10_11_BASE_IDX 2
+#define regCM0_CM_SHAPER_RAMA_REGION_12_13 0x0dec
+#define regCM0_CM_SHAPER_RAMA_REGION_12_13_BASE_IDX 2
+#define regCM0_CM_SHAPER_RAMA_REGION_14_15 0x0ded
+#define regCM0_CM_SHAPER_RAMA_REGION_14_15_BASE_IDX 2
+#define regCM0_CM_SHAPER_RAMA_REGION_16_17 0x0dee
+#define regCM0_CM_SHAPER_RAMA_REGION_16_17_BASE_IDX 2
+#define regCM0_CM_SHAPER_RAMA_REGION_18_19 0x0def
+#define regCM0_CM_SHAPER_RAMA_REGION_18_19_BASE_IDX 2
+#define regCM0_CM_SHAPER_RAMA_REGION_20_21 0x0df0
+#define regCM0_CM_SHAPER_RAMA_REGION_20_21_BASE_IDX 2
+#define regCM0_CM_SHAPER_RAMA_REGION_22_23 0x0df1
+#define regCM0_CM_SHAPER_RAMA_REGION_22_23_BASE_IDX 2
+#define regCM0_CM_SHAPER_RAMA_REGION_24_25 0x0df2
+#define regCM0_CM_SHAPER_RAMA_REGION_24_25_BASE_IDX 2
+#define regCM0_CM_SHAPER_RAMA_REGION_26_27 0x0df3
+#define regCM0_CM_SHAPER_RAMA_REGION_26_27_BASE_IDX 2
+#define regCM0_CM_SHAPER_RAMA_REGION_28_29 0x0df4
+#define regCM0_CM_SHAPER_RAMA_REGION_28_29_BASE_IDX 2
+#define regCM0_CM_SHAPER_RAMA_REGION_30_31 0x0df5
+#define regCM0_CM_SHAPER_RAMA_REGION_30_31_BASE_IDX 2
+#define regCM0_CM_SHAPER_RAMA_REGION_32_33 0x0df6
+#define regCM0_CM_SHAPER_RAMA_REGION_32_33_BASE_IDX 2
+#define regCM0_CM_SHAPER_RAMB_START_CNTL_B 0x0df7
+#define regCM0_CM_SHAPER_RAMB_START_CNTL_B_BASE_IDX 2
+#define regCM0_CM_SHAPER_RAMB_START_CNTL_G 0x0df8
+#define regCM0_CM_SHAPER_RAMB_START_CNTL_G_BASE_IDX 2
+#define regCM0_CM_SHAPER_RAMB_START_CNTL_R 0x0df9
+#define regCM0_CM_SHAPER_RAMB_START_CNTL_R_BASE_IDX 2
+#define regCM0_CM_SHAPER_RAMB_END_CNTL_B 0x0dfa
+#define regCM0_CM_SHAPER_RAMB_END_CNTL_B_BASE_IDX 2
+#define regCM0_CM_SHAPER_RAMB_END_CNTL_G 0x0dfb
+#define regCM0_CM_SHAPER_RAMB_END_CNTL_G_BASE_IDX 2
+#define regCM0_CM_SHAPER_RAMB_END_CNTL_R 0x0dfc
+#define regCM0_CM_SHAPER_RAMB_END_CNTL_R_BASE_IDX 2
+#define regCM0_CM_SHAPER_RAMB_REGION_0_1 0x0dfd
+#define regCM0_CM_SHAPER_RAMB_REGION_0_1_BASE_IDX 2
+#define regCM0_CM_SHAPER_RAMB_REGION_2_3 0x0dfe
+#define regCM0_CM_SHAPER_RAMB_REGION_2_3_BASE_IDX 2
+#define regCM0_CM_SHAPER_RAMB_REGION_4_5 0x0dff
+#define regCM0_CM_SHAPER_RAMB_REGION_4_5_BASE_IDX 2
+#define regCM0_CM_SHAPER_RAMB_REGION_6_7 0x0e00
+#define regCM0_CM_SHAPER_RAMB_REGION_6_7_BASE_IDX 2
+#define regCM0_CM_SHAPER_RAMB_REGION_8_9 0x0e01
+#define regCM0_CM_SHAPER_RAMB_REGION_8_9_BASE_IDX 2
+#define regCM0_CM_SHAPER_RAMB_REGION_10_11 0x0e02
+#define regCM0_CM_SHAPER_RAMB_REGION_10_11_BASE_IDX 2
+#define regCM0_CM_SHAPER_RAMB_REGION_12_13 0x0e03
+#define regCM0_CM_SHAPER_RAMB_REGION_12_13_BASE_IDX 2
+#define regCM0_CM_SHAPER_RAMB_REGION_14_15 0x0e04
+#define regCM0_CM_SHAPER_RAMB_REGION_14_15_BASE_IDX 2
+#define regCM0_CM_SHAPER_RAMB_REGION_16_17 0x0e05
+#define regCM0_CM_SHAPER_RAMB_REGION_16_17_BASE_IDX 2
+#define regCM0_CM_SHAPER_RAMB_REGION_18_19 0x0e06
+#define regCM0_CM_SHAPER_RAMB_REGION_18_19_BASE_IDX 2
+#define regCM0_CM_SHAPER_RAMB_REGION_20_21 0x0e07
+#define regCM0_CM_SHAPER_RAMB_REGION_20_21_BASE_IDX 2
+#define regCM0_CM_SHAPER_RAMB_REGION_22_23 0x0e08
+#define regCM0_CM_SHAPER_RAMB_REGION_22_23_BASE_IDX 2
+#define regCM0_CM_SHAPER_RAMB_REGION_24_25 0x0e09
+#define regCM0_CM_SHAPER_RAMB_REGION_24_25_BASE_IDX 2
+#define regCM0_CM_SHAPER_RAMB_REGION_26_27 0x0e0a
+#define regCM0_CM_SHAPER_RAMB_REGION_26_27_BASE_IDX 2
+#define regCM0_CM_SHAPER_RAMB_REGION_28_29 0x0e0b
+#define regCM0_CM_SHAPER_RAMB_REGION_28_29_BASE_IDX 2
+#define regCM0_CM_SHAPER_RAMB_REGION_30_31 0x0e0c
+#define regCM0_CM_SHAPER_RAMB_REGION_30_31_BASE_IDX 2
+#define regCM0_CM_SHAPER_RAMB_REGION_32_33 0x0e0d
+#define regCM0_CM_SHAPER_RAMB_REGION_32_33_BASE_IDX 2
+#define regCM0_CM_MEM_PWR_CTRL2 0x0e0e
+#define regCM0_CM_MEM_PWR_CTRL2_BASE_IDX 2
+#define regCM0_CM_MEM_PWR_STATUS2 0x0e0f
+#define regCM0_CM_MEM_PWR_STATUS2_BASE_IDX 2
+#define regCM0_CM_3DLUT_MODE 0x0e10
+#define regCM0_CM_3DLUT_MODE_BASE_IDX 2
+#define regCM0_CM_3DLUT_INDEX 0x0e11
+#define regCM0_CM_3DLUT_INDEX_BASE_IDX 2
+#define regCM0_CM_3DLUT_DATA 0x0e12
+#define regCM0_CM_3DLUT_DATA_BASE_IDX 2
+#define regCM0_CM_3DLUT_DATA_30BIT 0x0e13
+#define regCM0_CM_3DLUT_DATA_30BIT_BASE_IDX 2
+#define regCM0_CM_3DLUT_READ_WRITE_CONTROL 0x0e14
+#define regCM0_CM_3DLUT_READ_WRITE_CONTROL_BASE_IDX 2
+#define regCM0_CM_3DLUT_OUT_NORM_FACTOR 0x0e15
+#define regCM0_CM_3DLUT_OUT_NORM_FACTOR_BASE_IDX 2
+#define regCM0_CM_3DLUT_OUT_OFFSET_R 0x0e16
+#define regCM0_CM_3DLUT_OUT_OFFSET_R_BASE_IDX 2
+#define regCM0_CM_3DLUT_OUT_OFFSET_G 0x0e17
+#define regCM0_CM_3DLUT_OUT_OFFSET_G_BASE_IDX 2
+#define regCM0_CM_3DLUT_OUT_OFFSET_B 0x0e18
+#define regCM0_CM_3DLUT_OUT_OFFSET_B_BASE_IDX 2
+#define regCM0_CM_TEST_DEBUG_INDEX 0x0e19
+#define regCM0_CM_TEST_DEBUG_INDEX_BASE_IDX 2
+#define regCM0_CM_TEST_DEBUG_DATA 0x0e1a
+#define regCM0_CM_TEST_DEBUG_DATA_BASE_IDX 2
+
+
+// addressBlock: dce_dc_dpp0_dispdec_dpp_top_dispdec
+// base address: 0x0
+#define regDPP_TOP0_DPP_CONTROL 0x0cc5
+#define regDPP_TOP0_DPP_CONTROL_BASE_IDX 2
+#define regDPP_TOP0_DPP_SOFT_RESET 0x0cc6
+#define regDPP_TOP0_DPP_SOFT_RESET_BASE_IDX 2
+#define regDPP_TOP0_DPP_CRC_VAL_R_G 0x0cc7
+#define regDPP_TOP0_DPP_CRC_VAL_R_G_BASE_IDX 2
+#define regDPP_TOP0_DPP_CRC_VAL_B_A 0x0cc8
+#define regDPP_TOP0_DPP_CRC_VAL_B_A_BASE_IDX 2
+#define regDPP_TOP0_DPP_CRC_CTRL 0x0cc9
+#define regDPP_TOP0_DPP_CRC_CTRL_BASE_IDX 2
+#define regDPP_TOP0_HOST_READ_CONTROL 0x0cca
+#define regDPP_TOP0_HOST_READ_CONTROL_BASE_IDX 2
+
+
+// addressBlock: dce_dc_dpp0_dispdec_dpp_dcperfmon_dc_perfmon_dispdec
+// base address: 0x3890
+#define regDC_PERFMON11_PERFCOUNTER_CNTL 0x0e24
+#define regDC_PERFMON11_PERFCOUNTER_CNTL_BASE_IDX 2
+#define regDC_PERFMON11_PERFCOUNTER_CNTL2 0x0e25
+#define regDC_PERFMON11_PERFCOUNTER_CNTL2_BASE_IDX 2
+#define regDC_PERFMON11_PERFCOUNTER_STATE 0x0e26
+#define regDC_PERFMON11_PERFCOUNTER_STATE_BASE_IDX 2
+#define regDC_PERFMON11_PERFMON_CNTL 0x0e27
+#define regDC_PERFMON11_PERFMON_CNTL_BASE_IDX 2
+#define regDC_PERFMON11_PERFMON_CNTL2 0x0e28
+#define regDC_PERFMON11_PERFMON_CNTL2_BASE_IDX 2
+#define regDC_PERFMON11_PERFMON_CVALUE_INT_MISC 0x0e29
+#define regDC_PERFMON11_PERFMON_CVALUE_INT_MISC_BASE_IDX 2
+#define regDC_PERFMON11_PERFMON_CVALUE_LOW 0x0e2a
+#define regDC_PERFMON11_PERFMON_CVALUE_LOW_BASE_IDX 2
+#define regDC_PERFMON11_PERFMON_HI 0x0e2b
+#define regDC_PERFMON11_PERFMON_HI_BASE_IDX 2
+#define regDC_PERFMON11_PERFMON_LOW 0x0e2c
+#define regDC_PERFMON11_PERFMON_LOW_BASE_IDX 2
+
+
+// addressBlock: dce_dc_dpp1_dispdec_cnvc_cfg_dispdec
+// base address: 0x5ac
+#define regCNVC_CFG1_CNVC_SURFACE_PIXEL_FORMAT 0x0e3a
+#define regCNVC_CFG1_CNVC_SURFACE_PIXEL_FORMAT_BASE_IDX 2
+#define regCNVC_CFG1_FORMAT_CONTROL 0x0e3b
+#define regCNVC_CFG1_FORMAT_CONTROL_BASE_IDX 2
+#define regCNVC_CFG1_FCNV_FP_BIAS_R 0x0e3c
+#define regCNVC_CFG1_FCNV_FP_BIAS_R_BASE_IDX 2
+#define regCNVC_CFG1_FCNV_FP_BIAS_G 0x0e3d
+#define regCNVC_CFG1_FCNV_FP_BIAS_G_BASE_IDX 2
+#define regCNVC_CFG1_FCNV_FP_BIAS_B 0x0e3e
+#define regCNVC_CFG1_FCNV_FP_BIAS_B_BASE_IDX 2
+#define regCNVC_CFG1_FCNV_FP_SCALE_R 0x0e3f
+#define regCNVC_CFG1_FCNV_FP_SCALE_R_BASE_IDX 2
+#define regCNVC_CFG1_FCNV_FP_SCALE_G 0x0e40
+#define regCNVC_CFG1_FCNV_FP_SCALE_G_BASE_IDX 2
+#define regCNVC_CFG1_FCNV_FP_SCALE_B 0x0e41
+#define regCNVC_CFG1_FCNV_FP_SCALE_B_BASE_IDX 2
+#define regCNVC_CFG1_COLOR_KEYER_CONTROL 0x0e42
+#define regCNVC_CFG1_COLOR_KEYER_CONTROL_BASE_IDX 2
+#define regCNVC_CFG1_COLOR_KEYER_ALPHA 0x0e43
+#define regCNVC_CFG1_COLOR_KEYER_ALPHA_BASE_IDX 2
+#define regCNVC_CFG1_COLOR_KEYER_RED 0x0e44
+#define regCNVC_CFG1_COLOR_KEYER_RED_BASE_IDX 2
+#define regCNVC_CFG1_COLOR_KEYER_GREEN 0x0e45
+#define regCNVC_CFG1_COLOR_KEYER_GREEN_BASE_IDX 2
+#define regCNVC_CFG1_COLOR_KEYER_BLUE 0x0e46
+#define regCNVC_CFG1_COLOR_KEYER_BLUE_BASE_IDX 2
+#define regCNVC_CFG1_ALPHA_2BIT_LUT 0x0e48
+#define regCNVC_CFG1_ALPHA_2BIT_LUT_BASE_IDX 2
+#define regCNVC_CFG1_PRE_DEALPHA 0x0e49
+#define regCNVC_CFG1_PRE_DEALPHA_BASE_IDX 2
+#define regCNVC_CFG1_PRE_CSC_MODE 0x0e4a
+#define regCNVC_CFG1_PRE_CSC_MODE_BASE_IDX 2
+#define regCNVC_CFG1_PRE_CSC_C11_C12 0x0e4b
+#define regCNVC_CFG1_PRE_CSC_C11_C12_BASE_IDX 2
+#define regCNVC_CFG1_PRE_CSC_C13_C14 0x0e4c
+#define regCNVC_CFG1_PRE_CSC_C13_C14_BASE_IDX 2
+#define regCNVC_CFG1_PRE_CSC_C21_C22 0x0e4d
+#define regCNVC_CFG1_PRE_CSC_C21_C22_BASE_IDX 2
+#define regCNVC_CFG1_PRE_CSC_C23_C24 0x0e4e
+#define regCNVC_CFG1_PRE_CSC_C23_C24_BASE_IDX 2
+#define regCNVC_CFG1_PRE_CSC_C31_C32 0x0e4f
+#define regCNVC_CFG1_PRE_CSC_C31_C32_BASE_IDX 2
+#define regCNVC_CFG1_PRE_CSC_C33_C34 0x0e50
+#define regCNVC_CFG1_PRE_CSC_C33_C34_BASE_IDX 2
+#define regCNVC_CFG1_PRE_CSC_B_C11_C12 0x0e51
+#define regCNVC_CFG1_PRE_CSC_B_C11_C12_BASE_IDX 2
+#define regCNVC_CFG1_PRE_CSC_B_C13_C14 0x0e52
+#define regCNVC_CFG1_PRE_CSC_B_C13_C14_BASE_IDX 2
+#define regCNVC_CFG1_PRE_CSC_B_C21_C22 0x0e53
+#define regCNVC_CFG1_PRE_CSC_B_C21_C22_BASE_IDX 2
+#define regCNVC_CFG1_PRE_CSC_B_C23_C24 0x0e54
+#define regCNVC_CFG1_PRE_CSC_B_C23_C24_BASE_IDX 2
+#define regCNVC_CFG1_PRE_CSC_B_C31_C32 0x0e55
+#define regCNVC_CFG1_PRE_CSC_B_C31_C32_BASE_IDX 2
+#define regCNVC_CFG1_PRE_CSC_B_C33_C34 0x0e56
+#define regCNVC_CFG1_PRE_CSC_B_C33_C34_BASE_IDX 2
+#define regCNVC_CFG1_CNVC_COEF_FORMAT 0x0e57
+#define regCNVC_CFG1_CNVC_COEF_FORMAT_BASE_IDX 2
+#define regCNVC_CFG1_PRE_DEGAM 0x0e58
+#define regCNVC_CFG1_PRE_DEGAM_BASE_IDX 2
+#define regCNVC_CFG1_PRE_REALPHA 0x0e59
+#define regCNVC_CFG1_PRE_REALPHA_BASE_IDX 2
+
+
+// addressBlock: dce_dc_dpp1_dispdec_cnvc_cur_dispdec
+// base address: 0x5ac
+#define regCNVC_CUR1_CURSOR0_CONTROL 0x0e5c
+#define regCNVC_CUR1_CURSOR0_CONTROL_BASE_IDX 2
+#define regCNVC_CUR1_CURSOR0_COLOR0 0x0e5d
+#define regCNVC_CUR1_CURSOR0_COLOR0_BASE_IDX 2
+#define regCNVC_CUR1_CURSOR0_COLOR1 0x0e5e
+#define regCNVC_CUR1_CURSOR0_COLOR1_BASE_IDX 2
+#define regCNVC_CUR1_CURSOR0_FP_SCALE_BIAS 0x0e5f
+#define regCNVC_CUR1_CURSOR0_FP_SCALE_BIAS_BASE_IDX 2
+
+
+// addressBlock: dce_dc_dpp1_dispdec_dscl_dispdec
+// base address: 0x5ac
+#define regDSCL1_SCL_COEF_RAM_TAP_SELECT 0x0e64
+#define regDSCL1_SCL_COEF_RAM_TAP_SELECT_BASE_IDX 2
+#define regDSCL1_SCL_COEF_RAM_TAP_DATA 0x0e65
+#define regDSCL1_SCL_COEF_RAM_TAP_DATA_BASE_IDX 2
+#define regDSCL1_SCL_MODE 0x0e66
+#define regDSCL1_SCL_MODE_BASE_IDX 2
+#define regDSCL1_SCL_TAP_CONTROL 0x0e67
+#define regDSCL1_SCL_TAP_CONTROL_BASE_IDX 2
+#define regDSCL1_DSCL_CONTROL 0x0e68
+#define regDSCL1_DSCL_CONTROL_BASE_IDX 2
+#define regDSCL1_DSCL_2TAP_CONTROL 0x0e69
+#define regDSCL1_DSCL_2TAP_CONTROL_BASE_IDX 2
+#define regDSCL1_SCL_MANUAL_REPLICATE_CONTROL 0x0e6a
+#define regDSCL1_SCL_MANUAL_REPLICATE_CONTROL_BASE_IDX 2
+#define regDSCL1_SCL_HORZ_FILTER_SCALE_RATIO 0x0e6b
+#define regDSCL1_SCL_HORZ_FILTER_SCALE_RATIO_BASE_IDX 2
+#define regDSCL1_SCL_HORZ_FILTER_INIT 0x0e6c
+#define regDSCL1_SCL_HORZ_FILTER_INIT_BASE_IDX 2
+#define regDSCL1_SCL_HORZ_FILTER_SCALE_RATIO_C 0x0e6d
+#define regDSCL1_SCL_HORZ_FILTER_SCALE_RATIO_C_BASE_IDX 2
+#define regDSCL1_SCL_HORZ_FILTER_INIT_C 0x0e6e
+#define regDSCL1_SCL_HORZ_FILTER_INIT_C_BASE_IDX 2
+#define regDSCL1_SCL_VERT_FILTER_SCALE_RATIO 0x0e6f
+#define regDSCL1_SCL_VERT_FILTER_SCALE_RATIO_BASE_IDX 2
+#define regDSCL1_SCL_VERT_FILTER_INIT 0x0e70
+#define regDSCL1_SCL_VERT_FILTER_INIT_BASE_IDX 2
+#define regDSCL1_SCL_VERT_FILTER_INIT_BOT 0x0e71
+#define regDSCL1_SCL_VERT_FILTER_INIT_BOT_BASE_IDX 2
+#define regDSCL1_SCL_VERT_FILTER_SCALE_RATIO_C 0x0e72
+#define regDSCL1_SCL_VERT_FILTER_SCALE_RATIO_C_BASE_IDX 2
+#define regDSCL1_SCL_VERT_FILTER_INIT_C 0x0e73
+#define regDSCL1_SCL_VERT_FILTER_INIT_C_BASE_IDX 2
+#define regDSCL1_SCL_VERT_FILTER_INIT_BOT_C 0x0e74
+#define regDSCL1_SCL_VERT_FILTER_INIT_BOT_C_BASE_IDX 2
+#define regDSCL1_SCL_BLACK_COLOR 0x0e75
+#define regDSCL1_SCL_BLACK_COLOR_BASE_IDX 2
+#define regDSCL1_DSCL_UPDATE 0x0e76
+#define regDSCL1_DSCL_UPDATE_BASE_IDX 2
+#define regDSCL1_DSCL_AUTOCAL 0x0e77
+#define regDSCL1_DSCL_AUTOCAL_BASE_IDX 2
+#define regDSCL1_DSCL_EXT_OVERSCAN_LEFT_RIGHT 0x0e78
+#define regDSCL1_DSCL_EXT_OVERSCAN_LEFT_RIGHT_BASE_IDX 2
+#define regDSCL1_DSCL_EXT_OVERSCAN_TOP_BOTTOM 0x0e79
+#define regDSCL1_DSCL_EXT_OVERSCAN_TOP_BOTTOM_BASE_IDX 2
+#define regDSCL1_OTG_H_BLANK 0x0e7a
+#define regDSCL1_OTG_H_BLANK_BASE_IDX 2
+#define regDSCL1_OTG_V_BLANK 0x0e7b
+#define regDSCL1_OTG_V_BLANK_BASE_IDX 2
+#define regDSCL1_RECOUT_START 0x0e7c
+#define regDSCL1_RECOUT_START_BASE_IDX 2
+#define regDSCL1_RECOUT_SIZE 0x0e7d
+#define regDSCL1_RECOUT_SIZE_BASE_IDX 2
+#define regDSCL1_MPC_SIZE 0x0e7e
+#define regDSCL1_MPC_SIZE_BASE_IDX 2
+#define regDSCL1_LB_DATA_FORMAT 0x0e7f
+#define regDSCL1_LB_DATA_FORMAT_BASE_IDX 2
+#define regDSCL1_LB_MEMORY_CTRL 0x0e80
+#define regDSCL1_LB_MEMORY_CTRL_BASE_IDX 2
+#define regDSCL1_LB_V_COUNTER 0x0e81
+#define regDSCL1_LB_V_COUNTER_BASE_IDX 2
+#define regDSCL1_DSCL_MEM_PWR_CTRL 0x0e82
+#define regDSCL1_DSCL_MEM_PWR_CTRL_BASE_IDX 2
+#define regDSCL1_DSCL_MEM_PWR_STATUS 0x0e83
+#define regDSCL1_DSCL_MEM_PWR_STATUS_BASE_IDX 2
+#define regDSCL1_OBUF_CONTROL 0x0e84
+#define regDSCL1_OBUF_CONTROL_BASE_IDX 2
+#define regDSCL1_OBUF_MEM_PWR_CTRL 0x0e85
+#define regDSCL1_OBUF_MEM_PWR_CTRL_BASE_IDX 2
+
+
+// addressBlock: dce_dc_dpp1_dispdec_cm_dispdec
+// base address: 0x5ac
+#define regCM1_CM_CONTROL 0x0e8b
+#define regCM1_CM_CONTROL_BASE_IDX 2
+#define regCM1_CM_POST_CSC_CONTROL 0x0e8c
+#define regCM1_CM_POST_CSC_CONTROL_BASE_IDX 2
+#define regCM1_CM_POST_CSC_C11_C12 0x0e8d
+#define regCM1_CM_POST_CSC_C11_C12_BASE_IDX 2
+#define regCM1_CM_POST_CSC_C13_C14 0x0e8e
+#define regCM1_CM_POST_CSC_C13_C14_BASE_IDX 2
+#define regCM1_CM_POST_CSC_C21_C22 0x0e8f
+#define regCM1_CM_POST_CSC_C21_C22_BASE_IDX 2
+#define regCM1_CM_POST_CSC_C23_C24 0x0e90
+#define regCM1_CM_POST_CSC_C23_C24_BASE_IDX 2
+#define regCM1_CM_POST_CSC_C31_C32 0x0e91
+#define regCM1_CM_POST_CSC_C31_C32_BASE_IDX 2
+#define regCM1_CM_POST_CSC_C33_C34 0x0e92
+#define regCM1_CM_POST_CSC_C33_C34_BASE_IDX 2
+#define regCM1_CM_POST_CSC_B_C11_C12 0x0e93
+#define regCM1_CM_POST_CSC_B_C11_C12_BASE_IDX 2
+#define regCM1_CM_POST_CSC_B_C13_C14 0x0e94
+#define regCM1_CM_POST_CSC_B_C13_C14_BASE_IDX 2
+#define regCM1_CM_POST_CSC_B_C21_C22 0x0e95
+#define regCM1_CM_POST_CSC_B_C21_C22_BASE_IDX 2
+#define regCM1_CM_POST_CSC_B_C23_C24 0x0e96
+#define regCM1_CM_POST_CSC_B_C23_C24_BASE_IDX 2
+#define regCM1_CM_POST_CSC_B_C31_C32 0x0e97
+#define regCM1_CM_POST_CSC_B_C31_C32_BASE_IDX 2
+#define regCM1_CM_POST_CSC_B_C33_C34 0x0e98
+#define regCM1_CM_POST_CSC_B_C33_C34_BASE_IDX 2
+#define regCM1_CM_GAMUT_REMAP_CONTROL 0x0e99
+#define regCM1_CM_GAMUT_REMAP_CONTROL_BASE_IDX 2
+#define regCM1_CM_GAMUT_REMAP_C11_C12 0x0e9a
+#define regCM1_CM_GAMUT_REMAP_C11_C12_BASE_IDX 2
+#define regCM1_CM_GAMUT_REMAP_C13_C14 0x0e9b
+#define regCM1_CM_GAMUT_REMAP_C13_C14_BASE_IDX 2
+#define regCM1_CM_GAMUT_REMAP_C21_C22 0x0e9c
+#define regCM1_CM_GAMUT_REMAP_C21_C22_BASE_IDX 2
+#define regCM1_CM_GAMUT_REMAP_C23_C24 0x0e9d
+#define regCM1_CM_GAMUT_REMAP_C23_C24_BASE_IDX 2
+#define regCM1_CM_GAMUT_REMAP_C31_C32 0x0e9e
+#define regCM1_CM_GAMUT_REMAP_C31_C32_BASE_IDX 2
+#define regCM1_CM_GAMUT_REMAP_C33_C34 0x0e9f
+#define regCM1_CM_GAMUT_REMAP_C33_C34_BASE_IDX 2
+#define regCM1_CM_GAMUT_REMAP_B_C11_C12 0x0ea0
+#define regCM1_CM_GAMUT_REMAP_B_C11_C12_BASE_IDX 2
+#define regCM1_CM_GAMUT_REMAP_B_C13_C14 0x0ea1
+#define regCM1_CM_GAMUT_REMAP_B_C13_C14_BASE_IDX 2
+#define regCM1_CM_GAMUT_REMAP_B_C21_C22 0x0ea2
+#define regCM1_CM_GAMUT_REMAP_B_C21_C22_BASE_IDX 2
+#define regCM1_CM_GAMUT_REMAP_B_C23_C24 0x0ea3
+#define regCM1_CM_GAMUT_REMAP_B_C23_C24_BASE_IDX 2
+#define regCM1_CM_GAMUT_REMAP_B_C31_C32 0x0ea4
+#define regCM1_CM_GAMUT_REMAP_B_C31_C32_BASE_IDX 2
+#define regCM1_CM_GAMUT_REMAP_B_C33_C34 0x0ea5
+#define regCM1_CM_GAMUT_REMAP_B_C33_C34_BASE_IDX 2
+#define regCM1_CM_BIAS_CR_R 0x0ea6
+#define regCM1_CM_BIAS_CR_R_BASE_IDX 2
+#define regCM1_CM_BIAS_Y_G_CB_B 0x0ea7
+#define regCM1_CM_BIAS_Y_G_CB_B_BASE_IDX 2
+#define regCM1_CM_GAMCOR_CONTROL 0x0ea8
+#define regCM1_CM_GAMCOR_CONTROL_BASE_IDX 2
+#define regCM1_CM_GAMCOR_LUT_INDEX 0x0ea9
+#define regCM1_CM_GAMCOR_LUT_INDEX_BASE_IDX 2
+#define regCM1_CM_GAMCOR_LUT_DATA 0x0eaa
+#define regCM1_CM_GAMCOR_LUT_DATA_BASE_IDX 2
+#define regCM1_CM_GAMCOR_LUT_CONTROL 0x0eab
+#define regCM1_CM_GAMCOR_LUT_CONTROL_BASE_IDX 2
+#define regCM1_CM_GAMCOR_RAMA_START_CNTL_B 0x0eac
+#define regCM1_CM_GAMCOR_RAMA_START_CNTL_B_BASE_IDX 2
+#define regCM1_CM_GAMCOR_RAMA_START_CNTL_G 0x0ead
+#define regCM1_CM_GAMCOR_RAMA_START_CNTL_G_BASE_IDX 2
+#define regCM1_CM_GAMCOR_RAMA_START_CNTL_R 0x0eae
+#define regCM1_CM_GAMCOR_RAMA_START_CNTL_R_BASE_IDX 2
+#define regCM1_CM_GAMCOR_RAMA_START_SLOPE_CNTL_B 0x0eaf
+#define regCM1_CM_GAMCOR_RAMA_START_SLOPE_CNTL_B_BASE_IDX 2
+#define regCM1_CM_GAMCOR_RAMA_START_SLOPE_CNTL_G 0x0eb0
+#define regCM1_CM_GAMCOR_RAMA_START_SLOPE_CNTL_G_BASE_IDX 2
+#define regCM1_CM_GAMCOR_RAMA_START_SLOPE_CNTL_R 0x0eb1
+#define regCM1_CM_GAMCOR_RAMA_START_SLOPE_CNTL_R_BASE_IDX 2
+#define regCM1_CM_GAMCOR_RAMA_START_BASE_CNTL_B 0x0eb2
+#define regCM1_CM_GAMCOR_RAMA_START_BASE_CNTL_B_BASE_IDX 2
+#define regCM1_CM_GAMCOR_RAMA_START_BASE_CNTL_G 0x0eb3
+#define regCM1_CM_GAMCOR_RAMA_START_BASE_CNTL_G_BASE_IDX 2
+#define regCM1_CM_GAMCOR_RAMA_START_BASE_CNTL_R 0x0eb4
+#define regCM1_CM_GAMCOR_RAMA_START_BASE_CNTL_R_BASE_IDX 2
+#define regCM1_CM_GAMCOR_RAMA_END_CNTL1_B 0x0eb5
+#define regCM1_CM_GAMCOR_RAMA_END_CNTL1_B_BASE_IDX 2
+#define regCM1_CM_GAMCOR_RAMA_END_CNTL2_B 0x0eb6
+#define regCM1_CM_GAMCOR_RAMA_END_CNTL2_B_BASE_IDX 2
+#define regCM1_CM_GAMCOR_RAMA_END_CNTL1_G 0x0eb7
+#define regCM1_CM_GAMCOR_RAMA_END_CNTL1_G_BASE_IDX 2
+#define regCM1_CM_GAMCOR_RAMA_END_CNTL2_G 0x0eb8
+#define regCM1_CM_GAMCOR_RAMA_END_CNTL2_G_BASE_IDX 2
+#define regCM1_CM_GAMCOR_RAMA_END_CNTL1_R 0x0eb9
+#define regCM1_CM_GAMCOR_RAMA_END_CNTL1_R_BASE_IDX 2
+#define regCM1_CM_GAMCOR_RAMA_END_CNTL2_R 0x0eba
+#define regCM1_CM_GAMCOR_RAMA_END_CNTL2_R_BASE_IDX 2
+#define regCM1_CM_GAMCOR_RAMA_OFFSET_B 0x0ebb
+#define regCM1_CM_GAMCOR_RAMA_OFFSET_B_BASE_IDX 2
+#define regCM1_CM_GAMCOR_RAMA_OFFSET_G 0x0ebc
+#define regCM1_CM_GAMCOR_RAMA_OFFSET_G_BASE_IDX 2
+#define regCM1_CM_GAMCOR_RAMA_OFFSET_R 0x0ebd
+#define regCM1_CM_GAMCOR_RAMA_OFFSET_R_BASE_IDX 2
+#define regCM1_CM_GAMCOR_RAMA_REGION_0_1 0x0ebe
+#define regCM1_CM_GAMCOR_RAMA_REGION_0_1_BASE_IDX 2
+#define regCM1_CM_GAMCOR_RAMA_REGION_2_3 0x0ebf
+#define regCM1_CM_GAMCOR_RAMA_REGION_2_3_BASE_IDX 2
+#define regCM1_CM_GAMCOR_RAMA_REGION_4_5 0x0ec0
+#define regCM1_CM_GAMCOR_RAMA_REGION_4_5_BASE_IDX 2
+#define regCM1_CM_GAMCOR_RAMA_REGION_6_7 0x0ec1
+#define regCM1_CM_GAMCOR_RAMA_REGION_6_7_BASE_IDX 2
+#define regCM1_CM_GAMCOR_RAMA_REGION_8_9 0x0ec2
+#define regCM1_CM_GAMCOR_RAMA_REGION_8_9_BASE_IDX 2
+#define regCM1_CM_GAMCOR_RAMA_REGION_10_11 0x0ec3
+#define regCM1_CM_GAMCOR_RAMA_REGION_10_11_BASE_IDX 2
+#define regCM1_CM_GAMCOR_RAMA_REGION_12_13 0x0ec4
+#define regCM1_CM_GAMCOR_RAMA_REGION_12_13_BASE_IDX 2
+#define regCM1_CM_GAMCOR_RAMA_REGION_14_15 0x0ec5
+#define regCM1_CM_GAMCOR_RAMA_REGION_14_15_BASE_IDX 2
+#define regCM1_CM_GAMCOR_RAMA_REGION_16_17 0x0ec6
+#define regCM1_CM_GAMCOR_RAMA_REGION_16_17_BASE_IDX 2
+#define regCM1_CM_GAMCOR_RAMA_REGION_18_19 0x0ec7
+#define regCM1_CM_GAMCOR_RAMA_REGION_18_19_BASE_IDX 2
+#define regCM1_CM_GAMCOR_RAMA_REGION_20_21 0x0ec8
+#define regCM1_CM_GAMCOR_RAMA_REGION_20_21_BASE_IDX 2
+#define regCM1_CM_GAMCOR_RAMA_REGION_22_23 0x0ec9
+#define regCM1_CM_GAMCOR_RAMA_REGION_22_23_BASE_IDX 2
+#define regCM1_CM_GAMCOR_RAMA_REGION_24_25 0x0eca
+#define regCM1_CM_GAMCOR_RAMA_REGION_24_25_BASE_IDX 2
+#define regCM1_CM_GAMCOR_RAMA_REGION_26_27 0x0ecb
+#define regCM1_CM_GAMCOR_RAMA_REGION_26_27_BASE_IDX 2
+#define regCM1_CM_GAMCOR_RAMA_REGION_28_29 0x0ecc
+#define regCM1_CM_GAMCOR_RAMA_REGION_28_29_BASE_IDX 2
+#define regCM1_CM_GAMCOR_RAMA_REGION_30_31 0x0ecd
+#define regCM1_CM_GAMCOR_RAMA_REGION_30_31_BASE_IDX 2
+#define regCM1_CM_GAMCOR_RAMA_REGION_32_33 0x0ece
+#define regCM1_CM_GAMCOR_RAMA_REGION_32_33_BASE_IDX 2
+#define regCM1_CM_GAMCOR_RAMB_START_CNTL_B 0x0ecf
+#define regCM1_CM_GAMCOR_RAMB_START_CNTL_B_BASE_IDX 2
+#define regCM1_CM_GAMCOR_RAMB_START_CNTL_G 0x0ed0
+#define regCM1_CM_GAMCOR_RAMB_START_CNTL_G_BASE_IDX 2
+#define regCM1_CM_GAMCOR_RAMB_START_CNTL_R 0x0ed1
+#define regCM1_CM_GAMCOR_RAMB_START_CNTL_R_BASE_IDX 2
+#define regCM1_CM_GAMCOR_RAMB_START_SLOPE_CNTL_B 0x0ed2
+#define regCM1_CM_GAMCOR_RAMB_START_SLOPE_CNTL_B_BASE_IDX 2
+#define regCM1_CM_GAMCOR_RAMB_START_SLOPE_CNTL_G 0x0ed3
+#define regCM1_CM_GAMCOR_RAMB_START_SLOPE_CNTL_G_BASE_IDX 2
+#define regCM1_CM_GAMCOR_RAMB_START_SLOPE_CNTL_R 0x0ed4
+#define regCM1_CM_GAMCOR_RAMB_START_SLOPE_CNTL_R_BASE_IDX 2
+#define regCM1_CM_GAMCOR_RAMB_START_BASE_CNTL_B 0x0ed5
+#define regCM1_CM_GAMCOR_RAMB_START_BASE_CNTL_B_BASE_IDX 2
+#define regCM1_CM_GAMCOR_RAMB_START_BASE_CNTL_G 0x0ed6
+#define regCM1_CM_GAMCOR_RAMB_START_BASE_CNTL_G_BASE_IDX 2
+#define regCM1_CM_GAMCOR_RAMB_START_BASE_CNTL_R 0x0ed7
+#define regCM1_CM_GAMCOR_RAMB_START_BASE_CNTL_R_BASE_IDX 2
+#define regCM1_CM_GAMCOR_RAMB_END_CNTL1_B 0x0ed8
+#define regCM1_CM_GAMCOR_RAMB_END_CNTL1_B_BASE_IDX 2
+#define regCM1_CM_GAMCOR_RAMB_END_CNTL2_B 0x0ed9
+#define regCM1_CM_GAMCOR_RAMB_END_CNTL2_B_BASE_IDX 2
+#define regCM1_CM_GAMCOR_RAMB_END_CNTL1_G 0x0eda
+#define regCM1_CM_GAMCOR_RAMB_END_CNTL1_G_BASE_IDX 2
+#define regCM1_CM_GAMCOR_RAMB_END_CNTL2_G 0x0edb
+#define regCM1_CM_GAMCOR_RAMB_END_CNTL2_G_BASE_IDX 2
+#define regCM1_CM_GAMCOR_RAMB_END_CNTL1_R 0x0edc
+#define regCM1_CM_GAMCOR_RAMB_END_CNTL1_R_BASE_IDX 2
+#define regCM1_CM_GAMCOR_RAMB_END_CNTL2_R 0x0edd
+#define regCM1_CM_GAMCOR_RAMB_END_CNTL2_R_BASE_IDX 2
+#define regCM1_CM_GAMCOR_RAMB_OFFSET_B 0x0ede
+#define regCM1_CM_GAMCOR_RAMB_OFFSET_B_BASE_IDX 2
+#define regCM1_CM_GAMCOR_RAMB_OFFSET_G 0x0edf
+#define regCM1_CM_GAMCOR_RAMB_OFFSET_G_BASE_IDX 2
+#define regCM1_CM_GAMCOR_RAMB_OFFSET_R 0x0ee0
+#define regCM1_CM_GAMCOR_RAMB_OFFSET_R_BASE_IDX 2
+#define regCM1_CM_GAMCOR_RAMB_REGION_0_1 0x0ee1
+#define regCM1_CM_GAMCOR_RAMB_REGION_0_1_BASE_IDX 2
+#define regCM1_CM_GAMCOR_RAMB_REGION_2_3 0x0ee2
+#define regCM1_CM_GAMCOR_RAMB_REGION_2_3_BASE_IDX 2
+#define regCM1_CM_GAMCOR_RAMB_REGION_4_5 0x0ee3
+#define regCM1_CM_GAMCOR_RAMB_REGION_4_5_BASE_IDX 2
+#define regCM1_CM_GAMCOR_RAMB_REGION_6_7 0x0ee4
+#define regCM1_CM_GAMCOR_RAMB_REGION_6_7_BASE_IDX 2
+#define regCM1_CM_GAMCOR_RAMB_REGION_8_9 0x0ee5
+#define regCM1_CM_GAMCOR_RAMB_REGION_8_9_BASE_IDX 2
+#define regCM1_CM_GAMCOR_RAMB_REGION_10_11 0x0ee6
+#define regCM1_CM_GAMCOR_RAMB_REGION_10_11_BASE_IDX 2
+#define regCM1_CM_GAMCOR_RAMB_REGION_12_13 0x0ee7
+#define regCM1_CM_GAMCOR_RAMB_REGION_12_13_BASE_IDX 2
+#define regCM1_CM_GAMCOR_RAMB_REGION_14_15 0x0ee8
+#define regCM1_CM_GAMCOR_RAMB_REGION_14_15_BASE_IDX 2
+#define regCM1_CM_GAMCOR_RAMB_REGION_16_17 0x0ee9
+#define regCM1_CM_GAMCOR_RAMB_REGION_16_17_BASE_IDX 2
+#define regCM1_CM_GAMCOR_RAMB_REGION_18_19 0x0eea
+#define regCM1_CM_GAMCOR_RAMB_REGION_18_19_BASE_IDX 2
+#define regCM1_CM_GAMCOR_RAMB_REGION_20_21 0x0eeb
+#define regCM1_CM_GAMCOR_RAMB_REGION_20_21_BASE_IDX 2
+#define regCM1_CM_GAMCOR_RAMB_REGION_22_23 0x0eec
+#define regCM1_CM_GAMCOR_RAMB_REGION_22_23_BASE_IDX 2
+#define regCM1_CM_GAMCOR_RAMB_REGION_24_25 0x0eed
+#define regCM1_CM_GAMCOR_RAMB_REGION_24_25_BASE_IDX 2
+#define regCM1_CM_GAMCOR_RAMB_REGION_26_27 0x0eee
+#define regCM1_CM_GAMCOR_RAMB_REGION_26_27_BASE_IDX 2
+#define regCM1_CM_GAMCOR_RAMB_REGION_28_29 0x0eef
+#define regCM1_CM_GAMCOR_RAMB_REGION_28_29_BASE_IDX 2
+#define regCM1_CM_GAMCOR_RAMB_REGION_30_31 0x0ef0
+#define regCM1_CM_GAMCOR_RAMB_REGION_30_31_BASE_IDX 2
+#define regCM1_CM_GAMCOR_RAMB_REGION_32_33 0x0ef1
+#define regCM1_CM_GAMCOR_RAMB_REGION_32_33_BASE_IDX 2
+#define regCM1_CM_BLNDGAM_CONTROL 0x0ef2
+#define regCM1_CM_BLNDGAM_CONTROL_BASE_IDX 2
+#define regCM1_CM_BLNDGAM_LUT_INDEX 0x0ef3
+#define regCM1_CM_BLNDGAM_LUT_INDEX_BASE_IDX 2
+#define regCM1_CM_BLNDGAM_LUT_DATA 0x0ef4
+#define regCM1_CM_BLNDGAM_LUT_DATA_BASE_IDX 2
+#define regCM1_CM_BLNDGAM_LUT_CONTROL 0x0ef5
+#define regCM1_CM_BLNDGAM_LUT_CONTROL_BASE_IDX 2
+#define regCM1_CM_BLNDGAM_RAMA_START_CNTL_B 0x0ef6
+#define regCM1_CM_BLNDGAM_RAMA_START_CNTL_B_BASE_IDX 2
+#define regCM1_CM_BLNDGAM_RAMA_START_CNTL_G 0x0ef7
+#define regCM1_CM_BLNDGAM_RAMA_START_CNTL_G_BASE_IDX 2
+#define regCM1_CM_BLNDGAM_RAMA_START_CNTL_R 0x0ef8
+#define regCM1_CM_BLNDGAM_RAMA_START_CNTL_R_BASE_IDX 2
+#define regCM1_CM_BLNDGAM_RAMA_START_SLOPE_CNTL_B 0x0ef9
+#define regCM1_CM_BLNDGAM_RAMA_START_SLOPE_CNTL_B_BASE_IDX 2
+#define regCM1_CM_BLNDGAM_RAMA_START_SLOPE_CNTL_G 0x0efa
+#define regCM1_CM_BLNDGAM_RAMA_START_SLOPE_CNTL_G_BASE_IDX 2
+#define regCM1_CM_BLNDGAM_RAMA_START_SLOPE_CNTL_R 0x0efb
+#define regCM1_CM_BLNDGAM_RAMA_START_SLOPE_CNTL_R_BASE_IDX 2
+#define regCM1_CM_BLNDGAM_RAMA_START_BASE_CNTL_B 0x0efc
+#define regCM1_CM_BLNDGAM_RAMA_START_BASE_CNTL_B_BASE_IDX 2
+#define regCM1_CM_BLNDGAM_RAMA_START_BASE_CNTL_G 0x0efd
+#define regCM1_CM_BLNDGAM_RAMA_START_BASE_CNTL_G_BASE_IDX 2
+#define regCM1_CM_BLNDGAM_RAMA_START_BASE_CNTL_R 0x0efe
+#define regCM1_CM_BLNDGAM_RAMA_START_BASE_CNTL_R_BASE_IDX 2
+#define regCM1_CM_BLNDGAM_RAMA_END_CNTL1_B 0x0eff
+#define regCM1_CM_BLNDGAM_RAMA_END_CNTL1_B_BASE_IDX 2
+#define regCM1_CM_BLNDGAM_RAMA_END_CNTL2_B 0x0f00
+#define regCM1_CM_BLNDGAM_RAMA_END_CNTL2_B_BASE_IDX 2
+#define regCM1_CM_BLNDGAM_RAMA_END_CNTL1_G 0x0f01
+#define regCM1_CM_BLNDGAM_RAMA_END_CNTL1_G_BASE_IDX 2
+#define regCM1_CM_BLNDGAM_RAMA_END_CNTL2_G 0x0f02
+#define regCM1_CM_BLNDGAM_RAMA_END_CNTL2_G_BASE_IDX 2
+#define regCM1_CM_BLNDGAM_RAMA_END_CNTL1_R 0x0f03
+#define regCM1_CM_BLNDGAM_RAMA_END_CNTL1_R_BASE_IDX 2
+#define regCM1_CM_BLNDGAM_RAMA_END_CNTL2_R 0x0f04
+#define regCM1_CM_BLNDGAM_RAMA_END_CNTL2_R_BASE_IDX 2
+#define regCM1_CM_BLNDGAM_RAMA_OFFSET_B 0x0f05
+#define regCM1_CM_BLNDGAM_RAMA_OFFSET_B_BASE_IDX 2
+#define regCM1_CM_BLNDGAM_RAMA_OFFSET_G 0x0f06
+#define regCM1_CM_BLNDGAM_RAMA_OFFSET_G_BASE_IDX 2
+#define regCM1_CM_BLNDGAM_RAMA_OFFSET_R 0x0f07
+#define regCM1_CM_BLNDGAM_RAMA_OFFSET_R_BASE_IDX 2
+#define regCM1_CM_BLNDGAM_RAMA_REGION_0_1 0x0f08
+#define regCM1_CM_BLNDGAM_RAMA_REGION_0_1_BASE_IDX 2
+#define regCM1_CM_BLNDGAM_RAMA_REGION_2_3 0x0f09
+#define regCM1_CM_BLNDGAM_RAMA_REGION_2_3_BASE_IDX 2
+#define regCM1_CM_BLNDGAM_RAMA_REGION_4_5 0x0f0a
+#define regCM1_CM_BLNDGAM_RAMA_REGION_4_5_BASE_IDX 2
+#define regCM1_CM_BLNDGAM_RAMA_REGION_6_7 0x0f0b
+#define regCM1_CM_BLNDGAM_RAMA_REGION_6_7_BASE_IDX 2
+#define regCM1_CM_BLNDGAM_RAMA_REGION_8_9 0x0f0c
+#define regCM1_CM_BLNDGAM_RAMA_REGION_8_9_BASE_IDX 2
+#define regCM1_CM_BLNDGAM_RAMA_REGION_10_11 0x0f0d
+#define regCM1_CM_BLNDGAM_RAMA_REGION_10_11_BASE_IDX 2
+#define regCM1_CM_BLNDGAM_RAMA_REGION_12_13 0x0f0e
+#define regCM1_CM_BLNDGAM_RAMA_REGION_12_13_BASE_IDX 2
+#define regCM1_CM_BLNDGAM_RAMA_REGION_14_15 0x0f0f
+#define regCM1_CM_BLNDGAM_RAMA_REGION_14_15_BASE_IDX 2
+#define regCM1_CM_BLNDGAM_RAMA_REGION_16_17 0x0f10
+#define regCM1_CM_BLNDGAM_RAMA_REGION_16_17_BASE_IDX 2
+#define regCM1_CM_BLNDGAM_RAMA_REGION_18_19 0x0f11
+#define regCM1_CM_BLNDGAM_RAMA_REGION_18_19_BASE_IDX 2
+#define regCM1_CM_BLNDGAM_RAMA_REGION_20_21 0x0f12
+#define regCM1_CM_BLNDGAM_RAMA_REGION_20_21_BASE_IDX 2
+#define regCM1_CM_BLNDGAM_RAMA_REGION_22_23 0x0f13
+#define regCM1_CM_BLNDGAM_RAMA_REGION_22_23_BASE_IDX 2
+#define regCM1_CM_BLNDGAM_RAMA_REGION_24_25 0x0f14
+#define regCM1_CM_BLNDGAM_RAMA_REGION_24_25_BASE_IDX 2
+#define regCM1_CM_BLNDGAM_RAMA_REGION_26_27 0x0f15
+#define regCM1_CM_BLNDGAM_RAMA_REGION_26_27_BASE_IDX 2
+#define regCM1_CM_BLNDGAM_RAMA_REGION_28_29 0x0f16
+#define regCM1_CM_BLNDGAM_RAMA_REGION_28_29_BASE_IDX 2
+#define regCM1_CM_BLNDGAM_RAMA_REGION_30_31 0x0f17
+#define regCM1_CM_BLNDGAM_RAMA_REGION_30_31_BASE_IDX 2
+#define regCM1_CM_BLNDGAM_RAMA_REGION_32_33 0x0f18
+#define regCM1_CM_BLNDGAM_RAMA_REGION_32_33_BASE_IDX 2
+#define regCM1_CM_BLNDGAM_RAMB_START_CNTL_B 0x0f19
+#define regCM1_CM_BLNDGAM_RAMB_START_CNTL_B_BASE_IDX 2
+#define regCM1_CM_BLNDGAM_RAMB_START_CNTL_G 0x0f1a
+#define regCM1_CM_BLNDGAM_RAMB_START_CNTL_G_BASE_IDX 2
+#define regCM1_CM_BLNDGAM_RAMB_START_CNTL_R 0x0f1b
+#define regCM1_CM_BLNDGAM_RAMB_START_CNTL_R_BASE_IDX 2
+#define regCM1_CM_BLNDGAM_RAMB_START_SLOPE_CNTL_B 0x0f1c
+#define regCM1_CM_BLNDGAM_RAMB_START_SLOPE_CNTL_B_BASE_IDX 2
+#define regCM1_CM_BLNDGAM_RAMB_START_SLOPE_CNTL_G 0x0f1d
+#define regCM1_CM_BLNDGAM_RAMB_START_SLOPE_CNTL_G_BASE_IDX 2
+#define regCM1_CM_BLNDGAM_RAMB_START_SLOPE_CNTL_R 0x0f1e
+#define regCM1_CM_BLNDGAM_RAMB_START_SLOPE_CNTL_R_BASE_IDX 2
+#define regCM1_CM_BLNDGAM_RAMB_START_BASE_CNTL_B 0x0f1f
+#define regCM1_CM_BLNDGAM_RAMB_START_BASE_CNTL_B_BASE_IDX 2
+#define regCM1_CM_BLNDGAM_RAMB_START_BASE_CNTL_G 0x0f20
+#define regCM1_CM_BLNDGAM_RAMB_START_BASE_CNTL_G_BASE_IDX 2
+#define regCM1_CM_BLNDGAM_RAMB_START_BASE_CNTL_R 0x0f21
+#define regCM1_CM_BLNDGAM_RAMB_START_BASE_CNTL_R_BASE_IDX 2
+#define regCM1_CM_BLNDGAM_RAMB_END_CNTL1_B 0x0f22
+#define regCM1_CM_BLNDGAM_RAMB_END_CNTL1_B_BASE_IDX 2
+#define regCM1_CM_BLNDGAM_RAMB_END_CNTL2_B 0x0f23
+#define regCM1_CM_BLNDGAM_RAMB_END_CNTL2_B_BASE_IDX 2
+#define regCM1_CM_BLNDGAM_RAMB_END_CNTL1_G 0x0f24
+#define regCM1_CM_BLNDGAM_RAMB_END_CNTL1_G_BASE_IDX 2
+#define regCM1_CM_BLNDGAM_RAMB_END_CNTL2_G 0x0f25
+#define regCM1_CM_BLNDGAM_RAMB_END_CNTL2_G_BASE_IDX 2
+#define regCM1_CM_BLNDGAM_RAMB_END_CNTL1_R 0x0f26
+#define regCM1_CM_BLNDGAM_RAMB_END_CNTL1_R_BASE_IDX 2
+#define regCM1_CM_BLNDGAM_RAMB_END_CNTL2_R 0x0f27
+#define regCM1_CM_BLNDGAM_RAMB_END_CNTL2_R_BASE_IDX 2
+#define regCM1_CM_BLNDGAM_RAMB_OFFSET_B 0x0f28
+#define regCM1_CM_BLNDGAM_RAMB_OFFSET_B_BASE_IDX 2
+#define regCM1_CM_BLNDGAM_RAMB_OFFSET_G 0x0f29
+#define regCM1_CM_BLNDGAM_RAMB_OFFSET_G_BASE_IDX 2
+#define regCM1_CM_BLNDGAM_RAMB_OFFSET_R 0x0f2a
+#define regCM1_CM_BLNDGAM_RAMB_OFFSET_R_BASE_IDX 2
+#define regCM1_CM_BLNDGAM_RAMB_REGION_0_1 0x0f2b
+#define regCM1_CM_BLNDGAM_RAMB_REGION_0_1_BASE_IDX 2
+#define regCM1_CM_BLNDGAM_RAMB_REGION_2_3 0x0f2c
+#define regCM1_CM_BLNDGAM_RAMB_REGION_2_3_BASE_IDX 2
+#define regCM1_CM_BLNDGAM_RAMB_REGION_4_5 0x0f2d
+#define regCM1_CM_BLNDGAM_RAMB_REGION_4_5_BASE_IDX 2
+#define regCM1_CM_BLNDGAM_RAMB_REGION_6_7 0x0f2e
+#define regCM1_CM_BLNDGAM_RAMB_REGION_6_7_BASE_IDX 2
+#define regCM1_CM_BLNDGAM_RAMB_REGION_8_9 0x0f2f
+#define regCM1_CM_BLNDGAM_RAMB_REGION_8_9_BASE_IDX 2
+#define regCM1_CM_BLNDGAM_RAMB_REGION_10_11 0x0f30
+#define regCM1_CM_BLNDGAM_RAMB_REGION_10_11_BASE_IDX 2
+#define regCM1_CM_BLNDGAM_RAMB_REGION_12_13 0x0f31
+#define regCM1_CM_BLNDGAM_RAMB_REGION_12_13_BASE_IDX 2
+#define regCM1_CM_BLNDGAM_RAMB_REGION_14_15 0x0f32
+#define regCM1_CM_BLNDGAM_RAMB_REGION_14_15_BASE_IDX 2
+#define regCM1_CM_BLNDGAM_RAMB_REGION_16_17 0x0f33
+#define regCM1_CM_BLNDGAM_RAMB_REGION_16_17_BASE_IDX 2
+#define regCM1_CM_BLNDGAM_RAMB_REGION_18_19 0x0f34
+#define regCM1_CM_BLNDGAM_RAMB_REGION_18_19_BASE_IDX 2
+#define regCM1_CM_BLNDGAM_RAMB_REGION_20_21 0x0f35
+#define regCM1_CM_BLNDGAM_RAMB_REGION_20_21_BASE_IDX 2
+#define regCM1_CM_BLNDGAM_RAMB_REGION_22_23 0x0f36
+#define regCM1_CM_BLNDGAM_RAMB_REGION_22_23_BASE_IDX 2
+#define regCM1_CM_BLNDGAM_RAMB_REGION_24_25 0x0f37
+#define regCM1_CM_BLNDGAM_RAMB_REGION_24_25_BASE_IDX 2
+#define regCM1_CM_BLNDGAM_RAMB_REGION_26_27 0x0f38
+#define regCM1_CM_BLNDGAM_RAMB_REGION_26_27_BASE_IDX 2
+#define regCM1_CM_BLNDGAM_RAMB_REGION_28_29 0x0f39
+#define regCM1_CM_BLNDGAM_RAMB_REGION_28_29_BASE_IDX 2
+#define regCM1_CM_BLNDGAM_RAMB_REGION_30_31 0x0f3a
+#define regCM1_CM_BLNDGAM_RAMB_REGION_30_31_BASE_IDX 2
+#define regCM1_CM_BLNDGAM_RAMB_REGION_32_33 0x0f3b
+#define regCM1_CM_BLNDGAM_RAMB_REGION_32_33_BASE_IDX 2
+#define regCM1_CM_HDR_MULT_COEF 0x0f3c
+#define regCM1_CM_HDR_MULT_COEF_BASE_IDX 2
+#define regCM1_CM_MEM_PWR_CTRL 0x0f3d
+#define regCM1_CM_MEM_PWR_CTRL_BASE_IDX 2
+#define regCM1_CM_MEM_PWR_STATUS 0x0f3e
+#define regCM1_CM_MEM_PWR_STATUS_BASE_IDX 2
+#define regCM1_CM_DEALPHA 0x0f40
+#define regCM1_CM_DEALPHA_BASE_IDX 2
+#define regCM1_CM_COEF_FORMAT 0x0f41
+#define regCM1_CM_COEF_FORMAT_BASE_IDX 2
+#define regCM1_CM_SHAPER_CONTROL 0x0f42
+#define regCM1_CM_SHAPER_CONTROL_BASE_IDX 2
+#define regCM1_CM_SHAPER_OFFSET_R 0x0f43
+#define regCM1_CM_SHAPER_OFFSET_R_BASE_IDX 2
+#define regCM1_CM_SHAPER_OFFSET_G 0x0f44
+#define regCM1_CM_SHAPER_OFFSET_G_BASE_IDX 2
+#define regCM1_CM_SHAPER_OFFSET_B 0x0f45
+#define regCM1_CM_SHAPER_OFFSET_B_BASE_IDX 2
+#define regCM1_CM_SHAPER_SCALE_R 0x0f46
+#define regCM1_CM_SHAPER_SCALE_R_BASE_IDX 2
+#define regCM1_CM_SHAPER_SCALE_G_B 0x0f47
+#define regCM1_CM_SHAPER_SCALE_G_B_BASE_IDX 2
+#define regCM1_CM_SHAPER_LUT_INDEX 0x0f48
+#define regCM1_CM_SHAPER_LUT_INDEX_BASE_IDX 2
+#define regCM1_CM_SHAPER_LUT_DATA 0x0f49
+#define regCM1_CM_SHAPER_LUT_DATA_BASE_IDX 2
+#define regCM1_CM_SHAPER_LUT_WRITE_EN_MASK 0x0f4a
+#define regCM1_CM_SHAPER_LUT_WRITE_EN_MASK_BASE_IDX 2
+#define regCM1_CM_SHAPER_RAMA_START_CNTL_B 0x0f4b
+#define regCM1_CM_SHAPER_RAMA_START_CNTL_B_BASE_IDX 2
+#define regCM1_CM_SHAPER_RAMA_START_CNTL_G 0x0f4c
+#define regCM1_CM_SHAPER_RAMA_START_CNTL_G_BASE_IDX 2
+#define regCM1_CM_SHAPER_RAMA_START_CNTL_R 0x0f4d
+#define regCM1_CM_SHAPER_RAMA_START_CNTL_R_BASE_IDX 2
+#define regCM1_CM_SHAPER_RAMA_END_CNTL_B 0x0f4e
+#define regCM1_CM_SHAPER_RAMA_END_CNTL_B_BASE_IDX 2
+#define regCM1_CM_SHAPER_RAMA_END_CNTL_G 0x0f4f
+#define regCM1_CM_SHAPER_RAMA_END_CNTL_G_BASE_IDX 2
+#define regCM1_CM_SHAPER_RAMA_END_CNTL_R 0x0f50
+#define regCM1_CM_SHAPER_RAMA_END_CNTL_R_BASE_IDX 2
+#define regCM1_CM_SHAPER_RAMA_REGION_0_1 0x0f51
+#define regCM1_CM_SHAPER_RAMA_REGION_0_1_BASE_IDX 2
+#define regCM1_CM_SHAPER_RAMA_REGION_2_3 0x0f52
+#define regCM1_CM_SHAPER_RAMA_REGION_2_3_BASE_IDX 2
+#define regCM1_CM_SHAPER_RAMA_REGION_4_5 0x0f53
+#define regCM1_CM_SHAPER_RAMA_REGION_4_5_BASE_IDX 2
+#define regCM1_CM_SHAPER_RAMA_REGION_6_7 0x0f54
+#define regCM1_CM_SHAPER_RAMA_REGION_6_7_BASE_IDX 2
+#define regCM1_CM_SHAPER_RAMA_REGION_8_9 0x0f55
+#define regCM1_CM_SHAPER_RAMA_REGION_8_9_BASE_IDX 2
+#define regCM1_CM_SHAPER_RAMA_REGION_10_11 0x0f56
+#define regCM1_CM_SHAPER_RAMA_REGION_10_11_BASE_IDX 2
+#define regCM1_CM_SHAPER_RAMA_REGION_12_13 0x0f57
+#define regCM1_CM_SHAPER_RAMA_REGION_12_13_BASE_IDX 2
+#define regCM1_CM_SHAPER_RAMA_REGION_14_15 0x0f58
+#define regCM1_CM_SHAPER_RAMA_REGION_14_15_BASE_IDX 2
+#define regCM1_CM_SHAPER_RAMA_REGION_16_17 0x0f59
+#define regCM1_CM_SHAPER_RAMA_REGION_16_17_BASE_IDX 2
+#define regCM1_CM_SHAPER_RAMA_REGION_18_19 0x0f5a
+#define regCM1_CM_SHAPER_RAMA_REGION_18_19_BASE_IDX 2
+#define regCM1_CM_SHAPER_RAMA_REGION_20_21 0x0f5b
+#define regCM1_CM_SHAPER_RAMA_REGION_20_21_BASE_IDX 2
+#define regCM1_CM_SHAPER_RAMA_REGION_22_23 0x0f5c
+#define regCM1_CM_SHAPER_RAMA_REGION_22_23_BASE_IDX 2
+#define regCM1_CM_SHAPER_RAMA_REGION_24_25 0x0f5d
+#define regCM1_CM_SHAPER_RAMA_REGION_24_25_BASE_IDX 2
+#define regCM1_CM_SHAPER_RAMA_REGION_26_27 0x0f5e
+#define regCM1_CM_SHAPER_RAMA_REGION_26_27_BASE_IDX 2
+#define regCM1_CM_SHAPER_RAMA_REGION_28_29 0x0f5f
+#define regCM1_CM_SHAPER_RAMA_REGION_28_29_BASE_IDX 2
+#define regCM1_CM_SHAPER_RAMA_REGION_30_31 0x0f60
+#define regCM1_CM_SHAPER_RAMA_REGION_30_31_BASE_IDX 2
+#define regCM1_CM_SHAPER_RAMA_REGION_32_33 0x0f61
+#define regCM1_CM_SHAPER_RAMA_REGION_32_33_BASE_IDX 2
+#define regCM1_CM_SHAPER_RAMB_START_CNTL_B 0x0f62
+#define regCM1_CM_SHAPER_RAMB_START_CNTL_B_BASE_IDX 2
+#define regCM1_CM_SHAPER_RAMB_START_CNTL_G 0x0f63
+#define regCM1_CM_SHAPER_RAMB_START_CNTL_G_BASE_IDX 2
+#define regCM1_CM_SHAPER_RAMB_START_CNTL_R 0x0f64
+#define regCM1_CM_SHAPER_RAMB_START_CNTL_R_BASE_IDX 2
+#define regCM1_CM_SHAPER_RAMB_END_CNTL_B 0x0f65
+#define regCM1_CM_SHAPER_RAMB_END_CNTL_B_BASE_IDX 2
+#define regCM1_CM_SHAPER_RAMB_END_CNTL_G 0x0f66
+#define regCM1_CM_SHAPER_RAMB_END_CNTL_G_BASE_IDX 2
+#define regCM1_CM_SHAPER_RAMB_END_CNTL_R 0x0f67
+#define regCM1_CM_SHAPER_RAMB_END_CNTL_R_BASE_IDX 2
+#define regCM1_CM_SHAPER_RAMB_REGION_0_1 0x0f68
+#define regCM1_CM_SHAPER_RAMB_REGION_0_1_BASE_IDX 2
+#define regCM1_CM_SHAPER_RAMB_REGION_2_3 0x0f69
+#define regCM1_CM_SHAPER_RAMB_REGION_2_3_BASE_IDX 2
+#define regCM1_CM_SHAPER_RAMB_REGION_4_5 0x0f6a
+#define regCM1_CM_SHAPER_RAMB_REGION_4_5_BASE_IDX 2
+#define regCM1_CM_SHAPER_RAMB_REGION_6_7 0x0f6b
+#define regCM1_CM_SHAPER_RAMB_REGION_6_7_BASE_IDX 2
+#define regCM1_CM_SHAPER_RAMB_REGION_8_9 0x0f6c
+#define regCM1_CM_SHAPER_RAMB_REGION_8_9_BASE_IDX 2
+#define regCM1_CM_SHAPER_RAMB_REGION_10_11 0x0f6d
+#define regCM1_CM_SHAPER_RAMB_REGION_10_11_BASE_IDX 2
+#define regCM1_CM_SHAPER_RAMB_REGION_12_13 0x0f6e
+#define regCM1_CM_SHAPER_RAMB_REGION_12_13_BASE_IDX 2
+#define regCM1_CM_SHAPER_RAMB_REGION_14_15 0x0f6f
+#define regCM1_CM_SHAPER_RAMB_REGION_14_15_BASE_IDX 2
+#define regCM1_CM_SHAPER_RAMB_REGION_16_17 0x0f70
+#define regCM1_CM_SHAPER_RAMB_REGION_16_17_BASE_IDX 2
+#define regCM1_CM_SHAPER_RAMB_REGION_18_19 0x0f71
+#define regCM1_CM_SHAPER_RAMB_REGION_18_19_BASE_IDX 2
+#define regCM1_CM_SHAPER_RAMB_REGION_20_21 0x0f72
+#define regCM1_CM_SHAPER_RAMB_REGION_20_21_BASE_IDX 2
+#define regCM1_CM_SHAPER_RAMB_REGION_22_23 0x0f73
+#define regCM1_CM_SHAPER_RAMB_REGION_22_23_BASE_IDX 2
+#define regCM1_CM_SHAPER_RAMB_REGION_24_25 0x0f74
+#define regCM1_CM_SHAPER_RAMB_REGION_24_25_BASE_IDX 2
+#define regCM1_CM_SHAPER_RAMB_REGION_26_27 0x0f75
+#define regCM1_CM_SHAPER_RAMB_REGION_26_27_BASE_IDX 2
+#define regCM1_CM_SHAPER_RAMB_REGION_28_29 0x0f76
+#define regCM1_CM_SHAPER_RAMB_REGION_28_29_BASE_IDX 2
+#define regCM1_CM_SHAPER_RAMB_REGION_30_31 0x0f77
+#define regCM1_CM_SHAPER_RAMB_REGION_30_31_BASE_IDX 2
+#define regCM1_CM_SHAPER_RAMB_REGION_32_33 0x0f78
+#define regCM1_CM_SHAPER_RAMB_REGION_32_33_BASE_IDX 2
+#define regCM1_CM_MEM_PWR_CTRL2 0x0f79
+#define regCM1_CM_MEM_PWR_CTRL2_BASE_IDX 2
+#define regCM1_CM_MEM_PWR_STATUS2 0x0f7a
+#define regCM1_CM_MEM_PWR_STATUS2_BASE_IDX 2
+#define regCM1_CM_3DLUT_MODE 0x0f7b
+#define regCM1_CM_3DLUT_MODE_BASE_IDX 2
+#define regCM1_CM_3DLUT_INDEX 0x0f7c
+#define regCM1_CM_3DLUT_INDEX_BASE_IDX 2
+#define regCM1_CM_3DLUT_DATA 0x0f7d
+#define regCM1_CM_3DLUT_DATA_BASE_IDX 2
+#define regCM1_CM_3DLUT_DATA_30BIT 0x0f7e
+#define regCM1_CM_3DLUT_DATA_30BIT_BASE_IDX 2
+#define regCM1_CM_3DLUT_READ_WRITE_CONTROL 0x0f7f
+#define regCM1_CM_3DLUT_READ_WRITE_CONTROL_BASE_IDX 2
+#define regCM1_CM_3DLUT_OUT_NORM_FACTOR 0x0f80
+#define regCM1_CM_3DLUT_OUT_NORM_FACTOR_BASE_IDX 2
+#define regCM1_CM_3DLUT_OUT_OFFSET_R 0x0f81
+#define regCM1_CM_3DLUT_OUT_OFFSET_R_BASE_IDX 2
+#define regCM1_CM_3DLUT_OUT_OFFSET_G 0x0f82
+#define regCM1_CM_3DLUT_OUT_OFFSET_G_BASE_IDX 2
+#define regCM1_CM_3DLUT_OUT_OFFSET_B 0x0f83
+#define regCM1_CM_3DLUT_OUT_OFFSET_B_BASE_IDX 2
+#define regCM1_CM_TEST_DEBUG_INDEX 0x0f84
+#define regCM1_CM_TEST_DEBUG_INDEX_BASE_IDX 2
+#define regCM1_CM_TEST_DEBUG_DATA 0x0f85
+#define regCM1_CM_TEST_DEBUG_DATA_BASE_IDX 2
+
+
+// addressBlock: dce_dc_dpp1_dispdec_dpp_top_dispdec
+// base address: 0x5ac
+#define regDPP_TOP1_DPP_CONTROL 0x0e30
+#define regDPP_TOP1_DPP_CONTROL_BASE_IDX 2
+#define regDPP_TOP1_DPP_SOFT_RESET 0x0e31
+#define regDPP_TOP1_DPP_SOFT_RESET_BASE_IDX 2
+#define regDPP_TOP1_DPP_CRC_VAL_R_G 0x0e32
+#define regDPP_TOP1_DPP_CRC_VAL_R_G_BASE_IDX 2
+#define regDPP_TOP1_DPP_CRC_VAL_B_A 0x0e33
+#define regDPP_TOP1_DPP_CRC_VAL_B_A_BASE_IDX 2
+#define regDPP_TOP1_DPP_CRC_CTRL 0x0e34
+#define regDPP_TOP1_DPP_CRC_CTRL_BASE_IDX 2
+#define regDPP_TOP1_HOST_READ_CONTROL 0x0e35
+#define regDPP_TOP1_HOST_READ_CONTROL_BASE_IDX 2
+
+
+// addressBlock: dce_dc_dpp1_dispdec_dpp_dcperfmon_dc_perfmon_dispdec
+// base address: 0x3e3c
+#define regDC_PERFMON12_PERFCOUNTER_CNTL 0x0f8f
+#define regDC_PERFMON12_PERFCOUNTER_CNTL_BASE_IDX 2
+#define regDC_PERFMON12_PERFCOUNTER_CNTL2 0x0f90
+#define regDC_PERFMON12_PERFCOUNTER_CNTL2_BASE_IDX 2
+#define regDC_PERFMON12_PERFCOUNTER_STATE 0x0f91
+#define regDC_PERFMON12_PERFCOUNTER_STATE_BASE_IDX 2
+#define regDC_PERFMON12_PERFMON_CNTL 0x0f92
+#define regDC_PERFMON12_PERFMON_CNTL_BASE_IDX 2
+#define regDC_PERFMON12_PERFMON_CNTL2 0x0f93
+#define regDC_PERFMON12_PERFMON_CNTL2_BASE_IDX 2
+#define regDC_PERFMON12_PERFMON_CVALUE_INT_MISC 0x0f94
+#define regDC_PERFMON12_PERFMON_CVALUE_INT_MISC_BASE_IDX 2
+#define regDC_PERFMON12_PERFMON_CVALUE_LOW 0x0f95
+#define regDC_PERFMON12_PERFMON_CVALUE_LOW_BASE_IDX 2
+#define regDC_PERFMON12_PERFMON_HI 0x0f96
+#define regDC_PERFMON12_PERFMON_HI_BASE_IDX 2
+#define regDC_PERFMON12_PERFMON_LOW 0x0f97
+#define regDC_PERFMON12_PERFMON_LOW_BASE_IDX 2
+
+
+// addressBlock: dce_dc_dpp2_dispdec_cnvc_cfg_dispdec
+// base address: 0xb58
+#define regCNVC_CFG2_CNVC_SURFACE_PIXEL_FORMAT 0x0fa5
+#define regCNVC_CFG2_CNVC_SURFACE_PIXEL_FORMAT_BASE_IDX 2
+#define regCNVC_CFG2_FORMAT_CONTROL 0x0fa6
+#define regCNVC_CFG2_FORMAT_CONTROL_BASE_IDX 2
+#define regCNVC_CFG2_FCNV_FP_BIAS_R 0x0fa7
+#define regCNVC_CFG2_FCNV_FP_BIAS_R_BASE_IDX 2
+#define regCNVC_CFG2_FCNV_FP_BIAS_G 0x0fa8
+#define regCNVC_CFG2_FCNV_FP_BIAS_G_BASE_IDX 2
+#define regCNVC_CFG2_FCNV_FP_BIAS_B 0x0fa9
+#define regCNVC_CFG2_FCNV_FP_BIAS_B_BASE_IDX 2
+#define regCNVC_CFG2_FCNV_FP_SCALE_R 0x0faa
+#define regCNVC_CFG2_FCNV_FP_SCALE_R_BASE_IDX 2
+#define regCNVC_CFG2_FCNV_FP_SCALE_G 0x0fab
+#define regCNVC_CFG2_FCNV_FP_SCALE_G_BASE_IDX 2
+#define regCNVC_CFG2_FCNV_FP_SCALE_B 0x0fac
+#define regCNVC_CFG2_FCNV_FP_SCALE_B_BASE_IDX 2
+#define regCNVC_CFG2_COLOR_KEYER_CONTROL 0x0fad
+#define regCNVC_CFG2_COLOR_KEYER_CONTROL_BASE_IDX 2
+#define regCNVC_CFG2_COLOR_KEYER_ALPHA 0x0fae
+#define regCNVC_CFG2_COLOR_KEYER_ALPHA_BASE_IDX 2
+#define regCNVC_CFG2_COLOR_KEYER_RED 0x0faf
+#define regCNVC_CFG2_COLOR_KEYER_RED_BASE_IDX 2
+#define regCNVC_CFG2_COLOR_KEYER_GREEN 0x0fb0
+#define regCNVC_CFG2_COLOR_KEYER_GREEN_BASE_IDX 2
+#define regCNVC_CFG2_COLOR_KEYER_BLUE 0x0fb1
+#define regCNVC_CFG2_COLOR_KEYER_BLUE_BASE_IDX 2
+#define regCNVC_CFG2_ALPHA_2BIT_LUT 0x0fb3
+#define regCNVC_CFG2_ALPHA_2BIT_LUT_BASE_IDX 2
+#define regCNVC_CFG2_PRE_DEALPHA 0x0fb4
+#define regCNVC_CFG2_PRE_DEALPHA_BASE_IDX 2
+#define regCNVC_CFG2_PRE_CSC_MODE 0x0fb5
+#define regCNVC_CFG2_PRE_CSC_MODE_BASE_IDX 2
+#define regCNVC_CFG2_PRE_CSC_C11_C12 0x0fb6
+#define regCNVC_CFG2_PRE_CSC_C11_C12_BASE_IDX 2
+#define regCNVC_CFG2_PRE_CSC_C13_C14 0x0fb7
+#define regCNVC_CFG2_PRE_CSC_C13_C14_BASE_IDX 2
+#define regCNVC_CFG2_PRE_CSC_C21_C22 0x0fb8
+#define regCNVC_CFG2_PRE_CSC_C21_C22_BASE_IDX 2
+#define regCNVC_CFG2_PRE_CSC_C23_C24 0x0fb9
+#define regCNVC_CFG2_PRE_CSC_C23_C24_BASE_IDX 2
+#define regCNVC_CFG2_PRE_CSC_C31_C32 0x0fba
+#define regCNVC_CFG2_PRE_CSC_C31_C32_BASE_IDX 2
+#define regCNVC_CFG2_PRE_CSC_C33_C34 0x0fbb
+#define regCNVC_CFG2_PRE_CSC_C33_C34_BASE_IDX 2
+#define regCNVC_CFG2_PRE_CSC_B_C11_C12 0x0fbc
+#define regCNVC_CFG2_PRE_CSC_B_C11_C12_BASE_IDX 2
+#define regCNVC_CFG2_PRE_CSC_B_C13_C14 0x0fbd
+#define regCNVC_CFG2_PRE_CSC_B_C13_C14_BASE_IDX 2
+#define regCNVC_CFG2_PRE_CSC_B_C21_C22 0x0fbe
+#define regCNVC_CFG2_PRE_CSC_B_C21_C22_BASE_IDX 2
+#define regCNVC_CFG2_PRE_CSC_B_C23_C24 0x0fbf
+#define regCNVC_CFG2_PRE_CSC_B_C23_C24_BASE_IDX 2
+#define regCNVC_CFG2_PRE_CSC_B_C31_C32 0x0fc0
+#define regCNVC_CFG2_PRE_CSC_B_C31_C32_BASE_IDX 2
+#define regCNVC_CFG2_PRE_CSC_B_C33_C34 0x0fc1
+#define regCNVC_CFG2_PRE_CSC_B_C33_C34_BASE_IDX 2
+#define regCNVC_CFG2_CNVC_COEF_FORMAT 0x0fc2
+#define regCNVC_CFG2_CNVC_COEF_FORMAT_BASE_IDX 2
+#define regCNVC_CFG2_PRE_DEGAM 0x0fc3
+#define regCNVC_CFG2_PRE_DEGAM_BASE_IDX 2
+#define regCNVC_CFG2_PRE_REALPHA 0x0fc4
+#define regCNVC_CFG2_PRE_REALPHA_BASE_IDX 2
+
+
+// addressBlock: dce_dc_dpp2_dispdec_cnvc_cur_dispdec
+// base address: 0xb58
+#define regCNVC_CUR2_CURSOR0_CONTROL 0x0fc7
+#define regCNVC_CUR2_CURSOR0_CONTROL_BASE_IDX 2
+#define regCNVC_CUR2_CURSOR0_COLOR0 0x0fc8
+#define regCNVC_CUR2_CURSOR0_COLOR0_BASE_IDX 2
+#define regCNVC_CUR2_CURSOR0_COLOR1 0x0fc9
+#define regCNVC_CUR2_CURSOR0_COLOR1_BASE_IDX 2
+#define regCNVC_CUR2_CURSOR0_FP_SCALE_BIAS 0x0fca
+#define regCNVC_CUR2_CURSOR0_FP_SCALE_BIAS_BASE_IDX 2
+
+
+// addressBlock: dce_dc_dpp2_dispdec_dscl_dispdec
+// base address: 0xb58
+#define regDSCL2_SCL_COEF_RAM_TAP_SELECT 0x0fcf
+#define regDSCL2_SCL_COEF_RAM_TAP_SELECT_BASE_IDX 2
+#define regDSCL2_SCL_COEF_RAM_TAP_DATA 0x0fd0
+#define regDSCL2_SCL_COEF_RAM_TAP_DATA_BASE_IDX 2
+#define regDSCL2_SCL_MODE 0x0fd1
+#define regDSCL2_SCL_MODE_BASE_IDX 2
+#define regDSCL2_SCL_TAP_CONTROL 0x0fd2
+#define regDSCL2_SCL_TAP_CONTROL_BASE_IDX 2
+#define regDSCL2_DSCL_CONTROL 0x0fd3
+#define regDSCL2_DSCL_CONTROL_BASE_IDX 2
+#define regDSCL2_DSCL_2TAP_CONTROL 0x0fd4
+#define regDSCL2_DSCL_2TAP_CONTROL_BASE_IDX 2
+#define regDSCL2_SCL_MANUAL_REPLICATE_CONTROL 0x0fd5
+#define regDSCL2_SCL_MANUAL_REPLICATE_CONTROL_BASE_IDX 2
+#define regDSCL2_SCL_HORZ_FILTER_SCALE_RATIO 0x0fd6
+#define regDSCL2_SCL_HORZ_FILTER_SCALE_RATIO_BASE_IDX 2
+#define regDSCL2_SCL_HORZ_FILTER_INIT 0x0fd7
+#define regDSCL2_SCL_HORZ_FILTER_INIT_BASE_IDX 2
+#define regDSCL2_SCL_HORZ_FILTER_SCALE_RATIO_C 0x0fd8
+#define regDSCL2_SCL_HORZ_FILTER_SCALE_RATIO_C_BASE_IDX 2
+#define regDSCL2_SCL_HORZ_FILTER_INIT_C 0x0fd9
+#define regDSCL2_SCL_HORZ_FILTER_INIT_C_BASE_IDX 2
+#define regDSCL2_SCL_VERT_FILTER_SCALE_RATIO 0x0fda
+#define regDSCL2_SCL_VERT_FILTER_SCALE_RATIO_BASE_IDX 2
+#define regDSCL2_SCL_VERT_FILTER_INIT 0x0fdb
+#define regDSCL2_SCL_VERT_FILTER_INIT_BASE_IDX 2
+#define regDSCL2_SCL_VERT_FILTER_INIT_BOT 0x0fdc
+#define regDSCL2_SCL_VERT_FILTER_INIT_BOT_BASE_IDX 2
+#define regDSCL2_SCL_VERT_FILTER_SCALE_RATIO_C 0x0fdd
+#define regDSCL2_SCL_VERT_FILTER_SCALE_RATIO_C_BASE_IDX 2
+#define regDSCL2_SCL_VERT_FILTER_INIT_C 0x0fde
+#define regDSCL2_SCL_VERT_FILTER_INIT_C_BASE_IDX 2
+#define regDSCL2_SCL_VERT_FILTER_INIT_BOT_C 0x0fdf
+#define regDSCL2_SCL_VERT_FILTER_INIT_BOT_C_BASE_IDX 2
+#define regDSCL2_SCL_BLACK_COLOR 0x0fe0
+#define regDSCL2_SCL_BLACK_COLOR_BASE_IDX 2
+#define regDSCL2_DSCL_UPDATE 0x0fe1
+#define regDSCL2_DSCL_UPDATE_BASE_IDX 2
+#define regDSCL2_DSCL_AUTOCAL 0x0fe2
+#define regDSCL2_DSCL_AUTOCAL_BASE_IDX 2
+#define regDSCL2_DSCL_EXT_OVERSCAN_LEFT_RIGHT 0x0fe3
+#define regDSCL2_DSCL_EXT_OVERSCAN_LEFT_RIGHT_BASE_IDX 2
+#define regDSCL2_DSCL_EXT_OVERSCAN_TOP_BOTTOM 0x0fe4
+#define regDSCL2_DSCL_EXT_OVERSCAN_TOP_BOTTOM_BASE_IDX 2
+#define regDSCL2_OTG_H_BLANK 0x0fe5
+#define regDSCL2_OTG_H_BLANK_BASE_IDX 2
+#define regDSCL2_OTG_V_BLANK 0x0fe6
+#define regDSCL2_OTG_V_BLANK_BASE_IDX 2
+#define regDSCL2_RECOUT_START 0x0fe7
+#define regDSCL2_RECOUT_START_BASE_IDX 2
+#define regDSCL2_RECOUT_SIZE 0x0fe8
+#define regDSCL2_RECOUT_SIZE_BASE_IDX 2
+#define regDSCL2_MPC_SIZE 0x0fe9
+#define regDSCL2_MPC_SIZE_BASE_IDX 2
+#define regDSCL2_LB_DATA_FORMAT 0x0fea
+#define regDSCL2_LB_DATA_FORMAT_BASE_IDX 2
+#define regDSCL2_LB_MEMORY_CTRL 0x0feb
+#define regDSCL2_LB_MEMORY_CTRL_BASE_IDX 2
+#define regDSCL2_LB_V_COUNTER 0x0fec
+#define regDSCL2_LB_V_COUNTER_BASE_IDX 2
+#define regDSCL2_DSCL_MEM_PWR_CTRL 0x0fed
+#define regDSCL2_DSCL_MEM_PWR_CTRL_BASE_IDX 2
+#define regDSCL2_DSCL_MEM_PWR_STATUS 0x0fee
+#define regDSCL2_DSCL_MEM_PWR_STATUS_BASE_IDX 2
+#define regDSCL2_OBUF_CONTROL 0x0fef
+#define regDSCL2_OBUF_CONTROL_BASE_IDX 2
+#define regDSCL2_OBUF_MEM_PWR_CTRL 0x0ff0
+#define regDSCL2_OBUF_MEM_PWR_CTRL_BASE_IDX 2
+
+
+// addressBlock: dce_dc_dpp2_dispdec_cm_dispdec
+// base address: 0xb58
+#define regCM2_CM_CONTROL 0x0ff6
+#define regCM2_CM_CONTROL_BASE_IDX 2
+#define regCM2_CM_POST_CSC_CONTROL 0x0ff7
+#define regCM2_CM_POST_CSC_CONTROL_BASE_IDX 2
+#define regCM2_CM_POST_CSC_C11_C12 0x0ff8
+#define regCM2_CM_POST_CSC_C11_C12_BASE_IDX 2
+#define regCM2_CM_POST_CSC_C13_C14 0x0ff9
+#define regCM2_CM_POST_CSC_C13_C14_BASE_IDX 2
+#define regCM2_CM_POST_CSC_C21_C22 0x0ffa
+#define regCM2_CM_POST_CSC_C21_C22_BASE_IDX 2
+#define regCM2_CM_POST_CSC_C23_C24 0x0ffb
+#define regCM2_CM_POST_CSC_C23_C24_BASE_IDX 2
+#define regCM2_CM_POST_CSC_C31_C32 0x0ffc
+#define regCM2_CM_POST_CSC_C31_C32_BASE_IDX 2
+#define regCM2_CM_POST_CSC_C33_C34 0x0ffd
+#define regCM2_CM_POST_CSC_C33_C34_BASE_IDX 2
+#define regCM2_CM_POST_CSC_B_C11_C12 0x0ffe
+#define regCM2_CM_POST_CSC_B_C11_C12_BASE_IDX 2
+#define regCM2_CM_POST_CSC_B_C13_C14 0x0fff
+#define regCM2_CM_POST_CSC_B_C13_C14_BASE_IDX 2
+#define regCM2_CM_POST_CSC_B_C21_C22 0x1000
+#define regCM2_CM_POST_CSC_B_C21_C22_BASE_IDX 2
+#define regCM2_CM_POST_CSC_B_C23_C24 0x1001
+#define regCM2_CM_POST_CSC_B_C23_C24_BASE_IDX 2
+#define regCM2_CM_POST_CSC_B_C31_C32 0x1002
+#define regCM2_CM_POST_CSC_B_C31_C32_BASE_IDX 2
+#define regCM2_CM_POST_CSC_B_C33_C34 0x1003
+#define regCM2_CM_POST_CSC_B_C33_C34_BASE_IDX 2
+#define regCM2_CM_GAMUT_REMAP_CONTROL 0x1004
+#define regCM2_CM_GAMUT_REMAP_CONTROL_BASE_IDX 2
+#define regCM2_CM_GAMUT_REMAP_C11_C12 0x1005
+#define regCM2_CM_GAMUT_REMAP_C11_C12_BASE_IDX 2
+#define regCM2_CM_GAMUT_REMAP_C13_C14 0x1006
+#define regCM2_CM_GAMUT_REMAP_C13_C14_BASE_IDX 2
+#define regCM2_CM_GAMUT_REMAP_C21_C22 0x1007
+#define regCM2_CM_GAMUT_REMAP_C21_C22_BASE_IDX 2
+#define regCM2_CM_GAMUT_REMAP_C23_C24 0x1008
+#define regCM2_CM_GAMUT_REMAP_C23_C24_BASE_IDX 2
+#define regCM2_CM_GAMUT_REMAP_C31_C32 0x1009
+#define regCM2_CM_GAMUT_REMAP_C31_C32_BASE_IDX 2
+#define regCM2_CM_GAMUT_REMAP_C33_C34 0x100a
+#define regCM2_CM_GAMUT_REMAP_C33_C34_BASE_IDX 2
+#define regCM2_CM_GAMUT_REMAP_B_C11_C12 0x100b
+#define regCM2_CM_GAMUT_REMAP_B_C11_C12_BASE_IDX 2
+#define regCM2_CM_GAMUT_REMAP_B_C13_C14 0x100c
+#define regCM2_CM_GAMUT_REMAP_B_C13_C14_BASE_IDX 2
+#define regCM2_CM_GAMUT_REMAP_B_C21_C22 0x100d
+#define regCM2_CM_GAMUT_REMAP_B_C21_C22_BASE_IDX 2
+#define regCM2_CM_GAMUT_REMAP_B_C23_C24 0x100e
+#define regCM2_CM_GAMUT_REMAP_B_C23_C24_BASE_IDX 2
+#define regCM2_CM_GAMUT_REMAP_B_C31_C32 0x100f
+#define regCM2_CM_GAMUT_REMAP_B_C31_C32_BASE_IDX 2
+#define regCM2_CM_GAMUT_REMAP_B_C33_C34 0x1010
+#define regCM2_CM_GAMUT_REMAP_B_C33_C34_BASE_IDX 2
+#define regCM2_CM_BIAS_CR_R 0x1011
+#define regCM2_CM_BIAS_CR_R_BASE_IDX 2
+#define regCM2_CM_BIAS_Y_G_CB_B 0x1012
+#define regCM2_CM_BIAS_Y_G_CB_B_BASE_IDX 2
+#define regCM2_CM_GAMCOR_CONTROL 0x1013
+#define regCM2_CM_GAMCOR_CONTROL_BASE_IDX 2
+#define regCM2_CM_GAMCOR_LUT_INDEX 0x1014
+#define regCM2_CM_GAMCOR_LUT_INDEX_BASE_IDX 2
+#define regCM2_CM_GAMCOR_LUT_DATA 0x1015
+#define regCM2_CM_GAMCOR_LUT_DATA_BASE_IDX 2
+#define regCM2_CM_GAMCOR_LUT_CONTROL 0x1016
+#define regCM2_CM_GAMCOR_LUT_CONTROL_BASE_IDX 2
+#define regCM2_CM_GAMCOR_RAMA_START_CNTL_B 0x1017
+#define regCM2_CM_GAMCOR_RAMA_START_CNTL_B_BASE_IDX 2
+#define regCM2_CM_GAMCOR_RAMA_START_CNTL_G 0x1018
+#define regCM2_CM_GAMCOR_RAMA_START_CNTL_G_BASE_IDX 2
+#define regCM2_CM_GAMCOR_RAMA_START_CNTL_R 0x1019
+#define regCM2_CM_GAMCOR_RAMA_START_CNTL_R_BASE_IDX 2
+#define regCM2_CM_GAMCOR_RAMA_START_SLOPE_CNTL_B 0x101a
+#define regCM2_CM_GAMCOR_RAMA_START_SLOPE_CNTL_B_BASE_IDX 2
+#define regCM2_CM_GAMCOR_RAMA_START_SLOPE_CNTL_G 0x101b
+#define regCM2_CM_GAMCOR_RAMA_START_SLOPE_CNTL_G_BASE_IDX 2
+#define regCM2_CM_GAMCOR_RAMA_START_SLOPE_CNTL_R 0x101c
+#define regCM2_CM_GAMCOR_RAMA_START_SLOPE_CNTL_R_BASE_IDX 2
+#define regCM2_CM_GAMCOR_RAMA_START_BASE_CNTL_B 0x101d
+#define regCM2_CM_GAMCOR_RAMA_START_BASE_CNTL_B_BASE_IDX 2
+#define regCM2_CM_GAMCOR_RAMA_START_BASE_CNTL_G 0x101e
+#define regCM2_CM_GAMCOR_RAMA_START_BASE_CNTL_G_BASE_IDX 2
+#define regCM2_CM_GAMCOR_RAMA_START_BASE_CNTL_R 0x101f
+#define regCM2_CM_GAMCOR_RAMA_START_BASE_CNTL_R_BASE_IDX 2
+#define regCM2_CM_GAMCOR_RAMA_END_CNTL1_B 0x1020
+#define regCM2_CM_GAMCOR_RAMA_END_CNTL1_B_BASE_IDX 2
+#define regCM2_CM_GAMCOR_RAMA_END_CNTL2_B 0x1021
+#define regCM2_CM_GAMCOR_RAMA_END_CNTL2_B_BASE_IDX 2
+#define regCM2_CM_GAMCOR_RAMA_END_CNTL1_G 0x1022
+#define regCM2_CM_GAMCOR_RAMA_END_CNTL1_G_BASE_IDX 2
+#define regCM2_CM_GAMCOR_RAMA_END_CNTL2_G 0x1023
+#define regCM2_CM_GAMCOR_RAMA_END_CNTL2_G_BASE_IDX 2
+#define regCM2_CM_GAMCOR_RAMA_END_CNTL1_R 0x1024
+#define regCM2_CM_GAMCOR_RAMA_END_CNTL1_R_BASE_IDX 2
+#define regCM2_CM_GAMCOR_RAMA_END_CNTL2_R 0x1025
+#define regCM2_CM_GAMCOR_RAMA_END_CNTL2_R_BASE_IDX 2
+#define regCM2_CM_GAMCOR_RAMA_OFFSET_B 0x1026
+#define regCM2_CM_GAMCOR_RAMA_OFFSET_B_BASE_IDX 2
+#define regCM2_CM_GAMCOR_RAMA_OFFSET_G 0x1027
+#define regCM2_CM_GAMCOR_RAMA_OFFSET_G_BASE_IDX 2
+#define regCM2_CM_GAMCOR_RAMA_OFFSET_R 0x1028
+#define regCM2_CM_GAMCOR_RAMA_OFFSET_R_BASE_IDX 2
+#define regCM2_CM_GAMCOR_RAMA_REGION_0_1 0x1029
+#define regCM2_CM_GAMCOR_RAMA_REGION_0_1_BASE_IDX 2
+#define regCM2_CM_GAMCOR_RAMA_REGION_2_3 0x102a
+#define regCM2_CM_GAMCOR_RAMA_REGION_2_3_BASE_IDX 2
+#define regCM2_CM_GAMCOR_RAMA_REGION_4_5 0x102b
+#define regCM2_CM_GAMCOR_RAMA_REGION_4_5_BASE_IDX 2
+#define regCM2_CM_GAMCOR_RAMA_REGION_6_7 0x102c
+#define regCM2_CM_GAMCOR_RAMA_REGION_6_7_BASE_IDX 2
+#define regCM2_CM_GAMCOR_RAMA_REGION_8_9 0x102d
+#define regCM2_CM_GAMCOR_RAMA_REGION_8_9_BASE_IDX 2
+#define regCM2_CM_GAMCOR_RAMA_REGION_10_11 0x102e
+#define regCM2_CM_GAMCOR_RAMA_REGION_10_11_BASE_IDX 2
+#define regCM2_CM_GAMCOR_RAMA_REGION_12_13 0x102f
+#define regCM2_CM_GAMCOR_RAMA_REGION_12_13_BASE_IDX 2
+#define regCM2_CM_GAMCOR_RAMA_REGION_14_15 0x1030
+#define regCM2_CM_GAMCOR_RAMA_REGION_14_15_BASE_IDX 2
+#define regCM2_CM_GAMCOR_RAMA_REGION_16_17 0x1031
+#define regCM2_CM_GAMCOR_RAMA_REGION_16_17_BASE_IDX 2
+#define regCM2_CM_GAMCOR_RAMA_REGION_18_19 0x1032
+#define regCM2_CM_GAMCOR_RAMA_REGION_18_19_BASE_IDX 2
+#define regCM2_CM_GAMCOR_RAMA_REGION_20_21 0x1033
+#define regCM2_CM_GAMCOR_RAMA_REGION_20_21_BASE_IDX 2
+#define regCM2_CM_GAMCOR_RAMA_REGION_22_23 0x1034
+#define regCM2_CM_GAMCOR_RAMA_REGION_22_23_BASE_IDX 2
+#define regCM2_CM_GAMCOR_RAMA_REGION_24_25 0x1035
+#define regCM2_CM_GAMCOR_RAMA_REGION_24_25_BASE_IDX 2
+#define regCM2_CM_GAMCOR_RAMA_REGION_26_27 0x1036
+#define regCM2_CM_GAMCOR_RAMA_REGION_26_27_BASE_IDX 2
+#define regCM2_CM_GAMCOR_RAMA_REGION_28_29 0x1037
+#define regCM2_CM_GAMCOR_RAMA_REGION_28_29_BASE_IDX 2
+#define regCM2_CM_GAMCOR_RAMA_REGION_30_31 0x1038
+#define regCM2_CM_GAMCOR_RAMA_REGION_30_31_BASE_IDX 2
+#define regCM2_CM_GAMCOR_RAMA_REGION_32_33 0x1039
+#define regCM2_CM_GAMCOR_RAMA_REGION_32_33_BASE_IDX 2
+#define regCM2_CM_GAMCOR_RAMB_START_CNTL_B 0x103a
+#define regCM2_CM_GAMCOR_RAMB_START_CNTL_B_BASE_IDX 2
+#define regCM2_CM_GAMCOR_RAMB_START_CNTL_G 0x103b
+#define regCM2_CM_GAMCOR_RAMB_START_CNTL_G_BASE_IDX 2
+#define regCM2_CM_GAMCOR_RAMB_START_CNTL_R 0x103c
+#define regCM2_CM_GAMCOR_RAMB_START_CNTL_R_BASE_IDX 2
+#define regCM2_CM_GAMCOR_RAMB_START_SLOPE_CNTL_B 0x103d
+#define regCM2_CM_GAMCOR_RAMB_START_SLOPE_CNTL_B_BASE_IDX 2
+#define regCM2_CM_GAMCOR_RAMB_START_SLOPE_CNTL_G 0x103e
+#define regCM2_CM_GAMCOR_RAMB_START_SLOPE_CNTL_G_BASE_IDX 2
+#define regCM2_CM_GAMCOR_RAMB_START_SLOPE_CNTL_R 0x103f
+#define regCM2_CM_GAMCOR_RAMB_START_SLOPE_CNTL_R_BASE_IDX 2
+#define regCM2_CM_GAMCOR_RAMB_START_BASE_CNTL_B 0x1040
+#define regCM2_CM_GAMCOR_RAMB_START_BASE_CNTL_B_BASE_IDX 2
+#define regCM2_CM_GAMCOR_RAMB_START_BASE_CNTL_G 0x1041
+#define regCM2_CM_GAMCOR_RAMB_START_BASE_CNTL_G_BASE_IDX 2
+#define regCM2_CM_GAMCOR_RAMB_START_BASE_CNTL_R 0x1042
+#define regCM2_CM_GAMCOR_RAMB_START_BASE_CNTL_R_BASE_IDX 2
+#define regCM2_CM_GAMCOR_RAMB_END_CNTL1_B 0x1043
+#define regCM2_CM_GAMCOR_RAMB_END_CNTL1_B_BASE_IDX 2
+#define regCM2_CM_GAMCOR_RAMB_END_CNTL2_B 0x1044
+#define regCM2_CM_GAMCOR_RAMB_END_CNTL2_B_BASE_IDX 2
+#define regCM2_CM_GAMCOR_RAMB_END_CNTL1_G 0x1045
+#define regCM2_CM_GAMCOR_RAMB_END_CNTL1_G_BASE_IDX 2
+#define regCM2_CM_GAMCOR_RAMB_END_CNTL2_G 0x1046
+#define regCM2_CM_GAMCOR_RAMB_END_CNTL2_G_BASE_IDX 2
+#define regCM2_CM_GAMCOR_RAMB_END_CNTL1_R 0x1047
+#define regCM2_CM_GAMCOR_RAMB_END_CNTL1_R_BASE_IDX 2
+#define regCM2_CM_GAMCOR_RAMB_END_CNTL2_R 0x1048
+#define regCM2_CM_GAMCOR_RAMB_END_CNTL2_R_BASE_IDX 2
+#define regCM2_CM_GAMCOR_RAMB_OFFSET_B 0x1049
+#define regCM2_CM_GAMCOR_RAMB_OFFSET_B_BASE_IDX 2
+#define regCM2_CM_GAMCOR_RAMB_OFFSET_G 0x104a
+#define regCM2_CM_GAMCOR_RAMB_OFFSET_G_BASE_IDX 2
+#define regCM2_CM_GAMCOR_RAMB_OFFSET_R 0x104b
+#define regCM2_CM_GAMCOR_RAMB_OFFSET_R_BASE_IDX 2
+#define regCM2_CM_GAMCOR_RAMB_REGION_0_1 0x104c
+#define regCM2_CM_GAMCOR_RAMB_REGION_0_1_BASE_IDX 2
+#define regCM2_CM_GAMCOR_RAMB_REGION_2_3 0x104d
+#define regCM2_CM_GAMCOR_RAMB_REGION_2_3_BASE_IDX 2
+#define regCM2_CM_GAMCOR_RAMB_REGION_4_5 0x104e
+#define regCM2_CM_GAMCOR_RAMB_REGION_4_5_BASE_IDX 2
+#define regCM2_CM_GAMCOR_RAMB_REGION_6_7 0x104f
+#define regCM2_CM_GAMCOR_RAMB_REGION_6_7_BASE_IDX 2
+#define regCM2_CM_GAMCOR_RAMB_REGION_8_9 0x1050
+#define regCM2_CM_GAMCOR_RAMB_REGION_8_9_BASE_IDX 2
+#define regCM2_CM_GAMCOR_RAMB_REGION_10_11 0x1051
+#define regCM2_CM_GAMCOR_RAMB_REGION_10_11_BASE_IDX 2
+#define regCM2_CM_GAMCOR_RAMB_REGION_12_13 0x1052
+#define regCM2_CM_GAMCOR_RAMB_REGION_12_13_BASE_IDX 2
+#define regCM2_CM_GAMCOR_RAMB_REGION_14_15 0x1053
+#define regCM2_CM_GAMCOR_RAMB_REGION_14_15_BASE_IDX 2
+#define regCM2_CM_GAMCOR_RAMB_REGION_16_17 0x1054
+#define regCM2_CM_GAMCOR_RAMB_REGION_16_17_BASE_IDX 2
+#define regCM2_CM_GAMCOR_RAMB_REGION_18_19 0x1055
+#define regCM2_CM_GAMCOR_RAMB_REGION_18_19_BASE_IDX 2
+#define regCM2_CM_GAMCOR_RAMB_REGION_20_21 0x1056
+#define regCM2_CM_GAMCOR_RAMB_REGION_20_21_BASE_IDX 2
+#define regCM2_CM_GAMCOR_RAMB_REGION_22_23 0x1057
+#define regCM2_CM_GAMCOR_RAMB_REGION_22_23_BASE_IDX 2
+#define regCM2_CM_GAMCOR_RAMB_REGION_24_25 0x1058
+#define regCM2_CM_GAMCOR_RAMB_REGION_24_25_BASE_IDX 2
+#define regCM2_CM_GAMCOR_RAMB_REGION_26_27 0x1059
+#define regCM2_CM_GAMCOR_RAMB_REGION_26_27_BASE_IDX 2
+#define regCM2_CM_GAMCOR_RAMB_REGION_28_29 0x105a
+#define regCM2_CM_GAMCOR_RAMB_REGION_28_29_BASE_IDX 2
+#define regCM2_CM_GAMCOR_RAMB_REGION_30_31 0x105b
+#define regCM2_CM_GAMCOR_RAMB_REGION_30_31_BASE_IDX 2
+#define regCM2_CM_GAMCOR_RAMB_REGION_32_33 0x105c
+#define regCM2_CM_GAMCOR_RAMB_REGION_32_33_BASE_IDX 2
+#define regCM2_CM_BLNDGAM_CONTROL 0x105d
+#define regCM2_CM_BLNDGAM_CONTROL_BASE_IDX 2
+#define regCM2_CM_BLNDGAM_LUT_INDEX 0x105e
+#define regCM2_CM_BLNDGAM_LUT_INDEX_BASE_IDX 2
+#define regCM2_CM_BLNDGAM_LUT_DATA 0x105f
+#define regCM2_CM_BLNDGAM_LUT_DATA_BASE_IDX 2
+#define regCM2_CM_BLNDGAM_LUT_CONTROL 0x1060
+#define regCM2_CM_BLNDGAM_LUT_CONTROL_BASE_IDX 2
+#define regCM2_CM_BLNDGAM_RAMA_START_CNTL_B 0x1061
+#define regCM2_CM_BLNDGAM_RAMA_START_CNTL_B_BASE_IDX 2
+#define regCM2_CM_BLNDGAM_RAMA_START_CNTL_G 0x1062
+#define regCM2_CM_BLNDGAM_RAMA_START_CNTL_G_BASE_IDX 2
+#define regCM2_CM_BLNDGAM_RAMA_START_CNTL_R 0x1063
+#define regCM2_CM_BLNDGAM_RAMA_START_CNTL_R_BASE_IDX 2
+#define regCM2_CM_BLNDGAM_RAMA_START_SLOPE_CNTL_B 0x1064
+#define regCM2_CM_BLNDGAM_RAMA_START_SLOPE_CNTL_B_BASE_IDX 2
+#define regCM2_CM_BLNDGAM_RAMA_START_SLOPE_CNTL_G 0x1065
+#define regCM2_CM_BLNDGAM_RAMA_START_SLOPE_CNTL_G_BASE_IDX 2
+#define regCM2_CM_BLNDGAM_RAMA_START_SLOPE_CNTL_R 0x1066
+#define regCM2_CM_BLNDGAM_RAMA_START_SLOPE_CNTL_R_BASE_IDX 2
+#define regCM2_CM_BLNDGAM_RAMA_START_BASE_CNTL_B 0x1067
+#define regCM2_CM_BLNDGAM_RAMA_START_BASE_CNTL_B_BASE_IDX 2
+#define regCM2_CM_BLNDGAM_RAMA_START_BASE_CNTL_G 0x1068
+#define regCM2_CM_BLNDGAM_RAMA_START_BASE_CNTL_G_BASE_IDX 2
+#define regCM2_CM_BLNDGAM_RAMA_START_BASE_CNTL_R 0x1069
+#define regCM2_CM_BLNDGAM_RAMA_START_BASE_CNTL_R_BASE_IDX 2
+#define regCM2_CM_BLNDGAM_RAMA_END_CNTL1_B 0x106a
+#define regCM2_CM_BLNDGAM_RAMA_END_CNTL1_B_BASE_IDX 2
+#define regCM2_CM_BLNDGAM_RAMA_END_CNTL2_B 0x106b
+#define regCM2_CM_BLNDGAM_RAMA_END_CNTL2_B_BASE_IDX 2
+#define regCM2_CM_BLNDGAM_RAMA_END_CNTL1_G 0x106c
+#define regCM2_CM_BLNDGAM_RAMA_END_CNTL1_G_BASE_IDX 2
+#define regCM2_CM_BLNDGAM_RAMA_END_CNTL2_G 0x106d
+#define regCM2_CM_BLNDGAM_RAMA_END_CNTL2_G_BASE_IDX 2
+#define regCM2_CM_BLNDGAM_RAMA_END_CNTL1_R 0x106e
+#define regCM2_CM_BLNDGAM_RAMA_END_CNTL1_R_BASE_IDX 2
+#define regCM2_CM_BLNDGAM_RAMA_END_CNTL2_R 0x106f
+#define regCM2_CM_BLNDGAM_RAMA_END_CNTL2_R_BASE_IDX 2
+#define regCM2_CM_BLNDGAM_RAMA_OFFSET_B 0x1070
+#define regCM2_CM_BLNDGAM_RAMA_OFFSET_B_BASE_IDX 2
+#define regCM2_CM_BLNDGAM_RAMA_OFFSET_G 0x1071
+#define regCM2_CM_BLNDGAM_RAMA_OFFSET_G_BASE_IDX 2
+#define regCM2_CM_BLNDGAM_RAMA_OFFSET_R 0x1072
+#define regCM2_CM_BLNDGAM_RAMA_OFFSET_R_BASE_IDX 2
+#define regCM2_CM_BLNDGAM_RAMA_REGION_0_1 0x1073
+#define regCM2_CM_BLNDGAM_RAMA_REGION_0_1_BASE_IDX 2
+#define regCM2_CM_BLNDGAM_RAMA_REGION_2_3 0x1074
+#define regCM2_CM_BLNDGAM_RAMA_REGION_2_3_BASE_IDX 2
+#define regCM2_CM_BLNDGAM_RAMA_REGION_4_5 0x1075
+#define regCM2_CM_BLNDGAM_RAMA_REGION_4_5_BASE_IDX 2
+#define regCM2_CM_BLNDGAM_RAMA_REGION_6_7 0x1076
+#define regCM2_CM_BLNDGAM_RAMA_REGION_6_7_BASE_IDX 2
+#define regCM2_CM_BLNDGAM_RAMA_REGION_8_9 0x1077
+#define regCM2_CM_BLNDGAM_RAMA_REGION_8_9_BASE_IDX 2
+#define regCM2_CM_BLNDGAM_RAMA_REGION_10_11 0x1078
+#define regCM2_CM_BLNDGAM_RAMA_REGION_10_11_BASE_IDX 2
+#define regCM2_CM_BLNDGAM_RAMA_REGION_12_13 0x1079
+#define regCM2_CM_BLNDGAM_RAMA_REGION_12_13_BASE_IDX 2
+#define regCM2_CM_BLNDGAM_RAMA_REGION_14_15 0x107a
+#define regCM2_CM_BLNDGAM_RAMA_REGION_14_15_BASE_IDX 2
+#define regCM2_CM_BLNDGAM_RAMA_REGION_16_17 0x107b
+#define regCM2_CM_BLNDGAM_RAMA_REGION_16_17_BASE_IDX 2
+#define regCM2_CM_BLNDGAM_RAMA_REGION_18_19 0x107c
+#define regCM2_CM_BLNDGAM_RAMA_REGION_18_19_BASE_IDX 2
+#define regCM2_CM_BLNDGAM_RAMA_REGION_20_21 0x107d
+#define regCM2_CM_BLNDGAM_RAMA_REGION_20_21_BASE_IDX 2
+#define regCM2_CM_BLNDGAM_RAMA_REGION_22_23 0x107e
+#define regCM2_CM_BLNDGAM_RAMA_REGION_22_23_BASE_IDX 2
+#define regCM2_CM_BLNDGAM_RAMA_REGION_24_25 0x107f
+#define regCM2_CM_BLNDGAM_RAMA_REGION_24_25_BASE_IDX 2
+#define regCM2_CM_BLNDGAM_RAMA_REGION_26_27 0x1080
+#define regCM2_CM_BLNDGAM_RAMA_REGION_26_27_BASE_IDX 2
+#define regCM2_CM_BLNDGAM_RAMA_REGION_28_29 0x1081
+#define regCM2_CM_BLNDGAM_RAMA_REGION_28_29_BASE_IDX 2
+#define regCM2_CM_BLNDGAM_RAMA_REGION_30_31 0x1082
+#define regCM2_CM_BLNDGAM_RAMA_REGION_30_31_BASE_IDX 2
+#define regCM2_CM_BLNDGAM_RAMA_REGION_32_33 0x1083
+#define regCM2_CM_BLNDGAM_RAMA_REGION_32_33_BASE_IDX 2
+#define regCM2_CM_BLNDGAM_RAMB_START_CNTL_B 0x1084
+#define regCM2_CM_BLNDGAM_RAMB_START_CNTL_B_BASE_IDX 2
+#define regCM2_CM_BLNDGAM_RAMB_START_CNTL_G 0x1085
+#define regCM2_CM_BLNDGAM_RAMB_START_CNTL_G_BASE_IDX 2
+#define regCM2_CM_BLNDGAM_RAMB_START_CNTL_R 0x1086
+#define regCM2_CM_BLNDGAM_RAMB_START_CNTL_R_BASE_IDX 2
+#define regCM2_CM_BLNDGAM_RAMB_START_SLOPE_CNTL_B 0x1087
+#define regCM2_CM_BLNDGAM_RAMB_START_SLOPE_CNTL_B_BASE_IDX 2
+#define regCM2_CM_BLNDGAM_RAMB_START_SLOPE_CNTL_G 0x1088
+#define regCM2_CM_BLNDGAM_RAMB_START_SLOPE_CNTL_G_BASE_IDX 2
+#define regCM2_CM_BLNDGAM_RAMB_START_SLOPE_CNTL_R 0x1089
+#define regCM2_CM_BLNDGAM_RAMB_START_SLOPE_CNTL_R_BASE_IDX 2
+#define regCM2_CM_BLNDGAM_RAMB_START_BASE_CNTL_B 0x108a
+#define regCM2_CM_BLNDGAM_RAMB_START_BASE_CNTL_B_BASE_IDX 2
+#define regCM2_CM_BLNDGAM_RAMB_START_BASE_CNTL_G 0x108b
+#define regCM2_CM_BLNDGAM_RAMB_START_BASE_CNTL_G_BASE_IDX 2
+#define regCM2_CM_BLNDGAM_RAMB_START_BASE_CNTL_R 0x108c
+#define regCM2_CM_BLNDGAM_RAMB_START_BASE_CNTL_R_BASE_IDX 2
+#define regCM2_CM_BLNDGAM_RAMB_END_CNTL1_B 0x108d
+#define regCM2_CM_BLNDGAM_RAMB_END_CNTL1_B_BASE_IDX 2
+#define regCM2_CM_BLNDGAM_RAMB_END_CNTL2_B 0x108e
+#define regCM2_CM_BLNDGAM_RAMB_END_CNTL2_B_BASE_IDX 2
+#define regCM2_CM_BLNDGAM_RAMB_END_CNTL1_G 0x108f
+#define regCM2_CM_BLNDGAM_RAMB_END_CNTL1_G_BASE_IDX 2
+#define regCM2_CM_BLNDGAM_RAMB_END_CNTL2_G 0x1090
+#define regCM2_CM_BLNDGAM_RAMB_END_CNTL2_G_BASE_IDX 2
+#define regCM2_CM_BLNDGAM_RAMB_END_CNTL1_R 0x1091
+#define regCM2_CM_BLNDGAM_RAMB_END_CNTL1_R_BASE_IDX 2
+#define regCM2_CM_BLNDGAM_RAMB_END_CNTL2_R 0x1092
+#define regCM2_CM_BLNDGAM_RAMB_END_CNTL2_R_BASE_IDX 2
+#define regCM2_CM_BLNDGAM_RAMB_OFFSET_B 0x1093
+#define regCM2_CM_BLNDGAM_RAMB_OFFSET_B_BASE_IDX 2
+#define regCM2_CM_BLNDGAM_RAMB_OFFSET_G 0x1094
+#define regCM2_CM_BLNDGAM_RAMB_OFFSET_G_BASE_IDX 2
+#define regCM2_CM_BLNDGAM_RAMB_OFFSET_R 0x1095
+#define regCM2_CM_BLNDGAM_RAMB_OFFSET_R_BASE_IDX 2
+#define regCM2_CM_BLNDGAM_RAMB_REGION_0_1 0x1096
+#define regCM2_CM_BLNDGAM_RAMB_REGION_0_1_BASE_IDX 2
+#define regCM2_CM_BLNDGAM_RAMB_REGION_2_3 0x1097
+#define regCM2_CM_BLNDGAM_RAMB_REGION_2_3_BASE_IDX 2
+#define regCM2_CM_BLNDGAM_RAMB_REGION_4_5 0x1098
+#define regCM2_CM_BLNDGAM_RAMB_REGION_4_5_BASE_IDX 2
+#define regCM2_CM_BLNDGAM_RAMB_REGION_6_7 0x1099
+#define regCM2_CM_BLNDGAM_RAMB_REGION_6_7_BASE_IDX 2
+#define regCM2_CM_BLNDGAM_RAMB_REGION_8_9 0x109a
+#define regCM2_CM_BLNDGAM_RAMB_REGION_8_9_BASE_IDX 2
+#define regCM2_CM_BLNDGAM_RAMB_REGION_10_11 0x109b
+#define regCM2_CM_BLNDGAM_RAMB_REGION_10_11_BASE_IDX 2
+#define regCM2_CM_BLNDGAM_RAMB_REGION_12_13 0x109c
+#define regCM2_CM_BLNDGAM_RAMB_REGION_12_13_BASE_IDX 2
+#define regCM2_CM_BLNDGAM_RAMB_REGION_14_15 0x109d
+#define regCM2_CM_BLNDGAM_RAMB_REGION_14_15_BASE_IDX 2
+#define regCM2_CM_BLNDGAM_RAMB_REGION_16_17 0x109e
+#define regCM2_CM_BLNDGAM_RAMB_REGION_16_17_BASE_IDX 2
+#define regCM2_CM_BLNDGAM_RAMB_REGION_18_19 0x109f
+#define regCM2_CM_BLNDGAM_RAMB_REGION_18_19_BASE_IDX 2
+#define regCM2_CM_BLNDGAM_RAMB_REGION_20_21 0x10a0
+#define regCM2_CM_BLNDGAM_RAMB_REGION_20_21_BASE_IDX 2
+#define regCM2_CM_BLNDGAM_RAMB_REGION_22_23 0x10a1
+#define regCM2_CM_BLNDGAM_RAMB_REGION_22_23_BASE_IDX 2
+#define regCM2_CM_BLNDGAM_RAMB_REGION_24_25 0x10a2
+#define regCM2_CM_BLNDGAM_RAMB_REGION_24_25_BASE_IDX 2
+#define regCM2_CM_BLNDGAM_RAMB_REGION_26_27 0x10a3
+#define regCM2_CM_BLNDGAM_RAMB_REGION_26_27_BASE_IDX 2
+#define regCM2_CM_BLNDGAM_RAMB_REGION_28_29 0x10a4
+#define regCM2_CM_BLNDGAM_RAMB_REGION_28_29_BASE_IDX 2
+#define regCM2_CM_BLNDGAM_RAMB_REGION_30_31 0x10a5
+#define regCM2_CM_BLNDGAM_RAMB_REGION_30_31_BASE_IDX 2
+#define regCM2_CM_BLNDGAM_RAMB_REGION_32_33 0x10a6
+#define regCM2_CM_BLNDGAM_RAMB_REGION_32_33_BASE_IDX 2
+#define regCM2_CM_HDR_MULT_COEF 0x10a7
+#define regCM2_CM_HDR_MULT_COEF_BASE_IDX 2
+#define regCM2_CM_MEM_PWR_CTRL 0x10a8
+#define regCM2_CM_MEM_PWR_CTRL_BASE_IDX 2
+#define regCM2_CM_MEM_PWR_STATUS 0x10a9
+#define regCM2_CM_MEM_PWR_STATUS_BASE_IDX 2
+#define regCM2_CM_DEALPHA 0x10ab
+#define regCM2_CM_DEALPHA_BASE_IDX 2
+#define regCM2_CM_COEF_FORMAT 0x10ac
+#define regCM2_CM_COEF_FORMAT_BASE_IDX 2
+#define regCM2_CM_SHAPER_CONTROL 0x10ad
+#define regCM2_CM_SHAPER_CONTROL_BASE_IDX 2
+#define regCM2_CM_SHAPER_OFFSET_R 0x10ae
+#define regCM2_CM_SHAPER_OFFSET_R_BASE_IDX 2
+#define regCM2_CM_SHAPER_OFFSET_G 0x10af
+#define regCM2_CM_SHAPER_OFFSET_G_BASE_IDX 2
+#define regCM2_CM_SHAPER_OFFSET_B 0x10b0
+#define regCM2_CM_SHAPER_OFFSET_B_BASE_IDX 2
+#define regCM2_CM_SHAPER_SCALE_R 0x10b1
+#define regCM2_CM_SHAPER_SCALE_R_BASE_IDX 2
+#define regCM2_CM_SHAPER_SCALE_G_B 0x10b2
+#define regCM2_CM_SHAPER_SCALE_G_B_BASE_IDX 2
+#define regCM2_CM_SHAPER_LUT_INDEX 0x10b3
+#define regCM2_CM_SHAPER_LUT_INDEX_BASE_IDX 2
+#define regCM2_CM_SHAPER_LUT_DATA 0x10b4
+#define regCM2_CM_SHAPER_LUT_DATA_BASE_IDX 2
+#define regCM2_CM_SHAPER_LUT_WRITE_EN_MASK 0x10b5
+#define regCM2_CM_SHAPER_LUT_WRITE_EN_MASK_BASE_IDX 2
+#define regCM2_CM_SHAPER_RAMA_START_CNTL_B 0x10b6
+#define regCM2_CM_SHAPER_RAMA_START_CNTL_B_BASE_IDX 2
+#define regCM2_CM_SHAPER_RAMA_START_CNTL_G 0x10b7
+#define regCM2_CM_SHAPER_RAMA_START_CNTL_G_BASE_IDX 2
+#define regCM2_CM_SHAPER_RAMA_START_CNTL_R 0x10b8
+#define regCM2_CM_SHAPER_RAMA_START_CNTL_R_BASE_IDX 2
+#define regCM2_CM_SHAPER_RAMA_END_CNTL_B 0x10b9
+#define regCM2_CM_SHAPER_RAMA_END_CNTL_B_BASE_IDX 2
+#define regCM2_CM_SHAPER_RAMA_END_CNTL_G 0x10ba
+#define regCM2_CM_SHAPER_RAMA_END_CNTL_G_BASE_IDX 2
+#define regCM2_CM_SHAPER_RAMA_END_CNTL_R 0x10bb
+#define regCM2_CM_SHAPER_RAMA_END_CNTL_R_BASE_IDX 2
+#define regCM2_CM_SHAPER_RAMA_REGION_0_1 0x10bc
+#define regCM2_CM_SHAPER_RAMA_REGION_0_1_BASE_IDX 2
+#define regCM2_CM_SHAPER_RAMA_REGION_2_3 0x10bd
+#define regCM2_CM_SHAPER_RAMA_REGION_2_3_BASE_IDX 2
+#define regCM2_CM_SHAPER_RAMA_REGION_4_5 0x10be
+#define regCM2_CM_SHAPER_RAMA_REGION_4_5_BASE_IDX 2
+#define regCM2_CM_SHAPER_RAMA_REGION_6_7 0x10bf
+#define regCM2_CM_SHAPER_RAMA_REGION_6_7_BASE_IDX 2
+#define regCM2_CM_SHAPER_RAMA_REGION_8_9 0x10c0
+#define regCM2_CM_SHAPER_RAMA_REGION_8_9_BASE_IDX 2
+#define regCM2_CM_SHAPER_RAMA_REGION_10_11 0x10c1
+#define regCM2_CM_SHAPER_RAMA_REGION_10_11_BASE_IDX 2
+#define regCM2_CM_SHAPER_RAMA_REGION_12_13 0x10c2
+#define regCM2_CM_SHAPER_RAMA_REGION_12_13_BASE_IDX 2
+#define regCM2_CM_SHAPER_RAMA_REGION_14_15 0x10c3
+#define regCM2_CM_SHAPER_RAMA_REGION_14_15_BASE_IDX 2
+#define regCM2_CM_SHAPER_RAMA_REGION_16_17 0x10c4
+#define regCM2_CM_SHAPER_RAMA_REGION_16_17_BASE_IDX 2
+#define regCM2_CM_SHAPER_RAMA_REGION_18_19 0x10c5
+#define regCM2_CM_SHAPER_RAMA_REGION_18_19_BASE_IDX 2
+#define regCM2_CM_SHAPER_RAMA_REGION_20_21 0x10c6
+#define regCM2_CM_SHAPER_RAMA_REGION_20_21_BASE_IDX 2
+#define regCM2_CM_SHAPER_RAMA_REGION_22_23 0x10c7
+#define regCM2_CM_SHAPER_RAMA_REGION_22_23_BASE_IDX 2
+#define regCM2_CM_SHAPER_RAMA_REGION_24_25 0x10c8
+#define regCM2_CM_SHAPER_RAMA_REGION_24_25_BASE_IDX 2
+#define regCM2_CM_SHAPER_RAMA_REGION_26_27 0x10c9
+#define regCM2_CM_SHAPER_RAMA_REGION_26_27_BASE_IDX 2
+#define regCM2_CM_SHAPER_RAMA_REGION_28_29 0x10ca
+#define regCM2_CM_SHAPER_RAMA_REGION_28_29_BASE_IDX 2
+#define regCM2_CM_SHAPER_RAMA_REGION_30_31 0x10cb
+#define regCM2_CM_SHAPER_RAMA_REGION_30_31_BASE_IDX 2
+#define regCM2_CM_SHAPER_RAMA_REGION_32_33 0x10cc
+#define regCM2_CM_SHAPER_RAMA_REGION_32_33_BASE_IDX 2
+#define regCM2_CM_SHAPER_RAMB_START_CNTL_B 0x10cd
+#define regCM2_CM_SHAPER_RAMB_START_CNTL_B_BASE_IDX 2
+#define regCM2_CM_SHAPER_RAMB_START_CNTL_G 0x10ce
+#define regCM2_CM_SHAPER_RAMB_START_CNTL_G_BASE_IDX 2
+#define regCM2_CM_SHAPER_RAMB_START_CNTL_R 0x10cf
+#define regCM2_CM_SHAPER_RAMB_START_CNTL_R_BASE_IDX 2
+#define regCM2_CM_SHAPER_RAMB_END_CNTL_B 0x10d0
+#define regCM2_CM_SHAPER_RAMB_END_CNTL_B_BASE_IDX 2
+#define regCM2_CM_SHAPER_RAMB_END_CNTL_G 0x10d1
+#define regCM2_CM_SHAPER_RAMB_END_CNTL_G_BASE_IDX 2
+#define regCM2_CM_SHAPER_RAMB_END_CNTL_R 0x10d2
+#define regCM2_CM_SHAPER_RAMB_END_CNTL_R_BASE_IDX 2
+#define regCM2_CM_SHAPER_RAMB_REGION_0_1 0x10d3
+#define regCM2_CM_SHAPER_RAMB_REGION_0_1_BASE_IDX 2
+#define regCM2_CM_SHAPER_RAMB_REGION_2_3 0x10d4
+#define regCM2_CM_SHAPER_RAMB_REGION_2_3_BASE_IDX 2
+#define regCM2_CM_SHAPER_RAMB_REGION_4_5 0x10d5
+#define regCM2_CM_SHAPER_RAMB_REGION_4_5_BASE_IDX 2
+#define regCM2_CM_SHAPER_RAMB_REGION_6_7 0x10d6
+#define regCM2_CM_SHAPER_RAMB_REGION_6_7_BASE_IDX 2
+#define regCM2_CM_SHAPER_RAMB_REGION_8_9 0x10d7
+#define regCM2_CM_SHAPER_RAMB_REGION_8_9_BASE_IDX 2
+#define regCM2_CM_SHAPER_RAMB_REGION_10_11 0x10d8
+#define regCM2_CM_SHAPER_RAMB_REGION_10_11_BASE_IDX 2
+#define regCM2_CM_SHAPER_RAMB_REGION_12_13 0x10d9
+#define regCM2_CM_SHAPER_RAMB_REGION_12_13_BASE_IDX 2
+#define regCM2_CM_SHAPER_RAMB_REGION_14_15 0x10da
+#define regCM2_CM_SHAPER_RAMB_REGION_14_15_BASE_IDX 2
+#define regCM2_CM_SHAPER_RAMB_REGION_16_17 0x10db
+#define regCM2_CM_SHAPER_RAMB_REGION_16_17_BASE_IDX 2
+#define regCM2_CM_SHAPER_RAMB_REGION_18_19 0x10dc
+#define regCM2_CM_SHAPER_RAMB_REGION_18_19_BASE_IDX 2
+#define regCM2_CM_SHAPER_RAMB_REGION_20_21 0x10dd
+#define regCM2_CM_SHAPER_RAMB_REGION_20_21_BASE_IDX 2
+#define regCM2_CM_SHAPER_RAMB_REGION_22_23 0x10de
+#define regCM2_CM_SHAPER_RAMB_REGION_22_23_BASE_IDX 2
+#define regCM2_CM_SHAPER_RAMB_REGION_24_25 0x10df
+#define regCM2_CM_SHAPER_RAMB_REGION_24_25_BASE_IDX 2
+#define regCM2_CM_SHAPER_RAMB_REGION_26_27 0x10e0
+#define regCM2_CM_SHAPER_RAMB_REGION_26_27_BASE_IDX 2
+#define regCM2_CM_SHAPER_RAMB_REGION_28_29 0x10e1
+#define regCM2_CM_SHAPER_RAMB_REGION_28_29_BASE_IDX 2
+#define regCM2_CM_SHAPER_RAMB_REGION_30_31 0x10e2
+#define regCM2_CM_SHAPER_RAMB_REGION_30_31_BASE_IDX 2
+#define regCM2_CM_SHAPER_RAMB_REGION_32_33 0x10e3
+#define regCM2_CM_SHAPER_RAMB_REGION_32_33_BASE_IDX 2
+#define regCM2_CM_MEM_PWR_CTRL2 0x10e4
+#define regCM2_CM_MEM_PWR_CTRL2_BASE_IDX 2
+#define regCM2_CM_MEM_PWR_STATUS2 0x10e5
+#define regCM2_CM_MEM_PWR_STATUS2_BASE_IDX 2
+#define regCM2_CM_3DLUT_MODE 0x10e6
+#define regCM2_CM_3DLUT_MODE_BASE_IDX 2
+#define regCM2_CM_3DLUT_INDEX 0x10e7
+#define regCM2_CM_3DLUT_INDEX_BASE_IDX 2
+#define regCM2_CM_3DLUT_DATA 0x10e8
+#define regCM2_CM_3DLUT_DATA_BASE_IDX 2
+#define regCM2_CM_3DLUT_DATA_30BIT 0x10e9
+#define regCM2_CM_3DLUT_DATA_30BIT_BASE_IDX 2
+#define regCM2_CM_3DLUT_READ_WRITE_CONTROL 0x10ea
+#define regCM2_CM_3DLUT_READ_WRITE_CONTROL_BASE_IDX 2
+#define regCM2_CM_3DLUT_OUT_NORM_FACTOR 0x10eb
+#define regCM2_CM_3DLUT_OUT_NORM_FACTOR_BASE_IDX 2
+#define regCM2_CM_3DLUT_OUT_OFFSET_R 0x10ec
+#define regCM2_CM_3DLUT_OUT_OFFSET_R_BASE_IDX 2
+#define regCM2_CM_3DLUT_OUT_OFFSET_G 0x10ed
+#define regCM2_CM_3DLUT_OUT_OFFSET_G_BASE_IDX 2
+#define regCM2_CM_3DLUT_OUT_OFFSET_B 0x10ee
+#define regCM2_CM_3DLUT_OUT_OFFSET_B_BASE_IDX 2
+#define regCM2_CM_TEST_DEBUG_INDEX 0x10ef
+#define regCM2_CM_TEST_DEBUG_INDEX_BASE_IDX 2
+#define regCM2_CM_TEST_DEBUG_DATA 0x10f0
+#define regCM2_CM_TEST_DEBUG_DATA_BASE_IDX 2
+
+
+// addressBlock: dce_dc_dpp2_dispdec_dpp_top_dispdec
+// base address: 0xb58
+#define regDPP_TOP2_DPP_CONTROL 0x0f9b
+#define regDPP_TOP2_DPP_CONTROL_BASE_IDX 2
+#define regDPP_TOP2_DPP_SOFT_RESET 0x0f9c
+#define regDPP_TOP2_DPP_SOFT_RESET_BASE_IDX 2
+#define regDPP_TOP2_DPP_CRC_VAL_R_G 0x0f9d
+#define regDPP_TOP2_DPP_CRC_VAL_R_G_BASE_IDX 2
+#define regDPP_TOP2_DPP_CRC_VAL_B_A 0x0f9e
+#define regDPP_TOP2_DPP_CRC_VAL_B_A_BASE_IDX 2
+#define regDPP_TOP2_DPP_CRC_CTRL 0x0f9f
+#define regDPP_TOP2_DPP_CRC_CTRL_BASE_IDX 2
+#define regDPP_TOP2_HOST_READ_CONTROL 0x0fa0
+#define regDPP_TOP2_HOST_READ_CONTROL_BASE_IDX 2
+
+
+// addressBlock: dce_dc_dpp2_dispdec_dpp_dcperfmon_dc_perfmon_dispdec
+// base address: 0x43e8
+#define regDC_PERFMON13_PERFCOUNTER_CNTL 0x10fa
+#define regDC_PERFMON13_PERFCOUNTER_CNTL_BASE_IDX 2
+#define regDC_PERFMON13_PERFCOUNTER_CNTL2 0x10fb
+#define regDC_PERFMON13_PERFCOUNTER_CNTL2_BASE_IDX 2
+#define regDC_PERFMON13_PERFCOUNTER_STATE 0x10fc
+#define regDC_PERFMON13_PERFCOUNTER_STATE_BASE_IDX 2
+#define regDC_PERFMON13_PERFMON_CNTL 0x10fd
+#define regDC_PERFMON13_PERFMON_CNTL_BASE_IDX 2
+#define regDC_PERFMON13_PERFMON_CNTL2 0x10fe
+#define regDC_PERFMON13_PERFMON_CNTL2_BASE_IDX 2
+#define regDC_PERFMON13_PERFMON_CVALUE_INT_MISC 0x10ff
+#define regDC_PERFMON13_PERFMON_CVALUE_INT_MISC_BASE_IDX 2
+#define regDC_PERFMON13_PERFMON_CVALUE_LOW 0x1100
+#define regDC_PERFMON13_PERFMON_CVALUE_LOW_BASE_IDX 2
+#define regDC_PERFMON13_PERFMON_HI 0x1101
+#define regDC_PERFMON13_PERFMON_HI_BASE_IDX 2
+#define regDC_PERFMON13_PERFMON_LOW 0x1102
+#define regDC_PERFMON13_PERFMON_LOW_BASE_IDX 2
+
+
+// addressBlock: dce_dc_dpp3_dispdec_cnvc_cfg_dispdec
+// base address: 0x1104
+#define regCNVC_CFG3_CNVC_SURFACE_PIXEL_FORMAT 0x1110
+#define regCNVC_CFG3_CNVC_SURFACE_PIXEL_FORMAT_BASE_IDX 2
+#define regCNVC_CFG3_FORMAT_CONTROL 0x1111
+#define regCNVC_CFG3_FORMAT_CONTROL_BASE_IDX 2
+#define regCNVC_CFG3_FCNV_FP_BIAS_R 0x1112
+#define regCNVC_CFG3_FCNV_FP_BIAS_R_BASE_IDX 2
+#define regCNVC_CFG3_FCNV_FP_BIAS_G 0x1113
+#define regCNVC_CFG3_FCNV_FP_BIAS_G_BASE_IDX 2
+#define regCNVC_CFG3_FCNV_FP_BIAS_B 0x1114
+#define regCNVC_CFG3_FCNV_FP_BIAS_B_BASE_IDX 2
+#define regCNVC_CFG3_FCNV_FP_SCALE_R 0x1115
+#define regCNVC_CFG3_FCNV_FP_SCALE_R_BASE_IDX 2
+#define regCNVC_CFG3_FCNV_FP_SCALE_G 0x1116
+#define regCNVC_CFG3_FCNV_FP_SCALE_G_BASE_IDX 2
+#define regCNVC_CFG3_FCNV_FP_SCALE_B 0x1117
+#define regCNVC_CFG3_FCNV_FP_SCALE_B_BASE_IDX 2
+#define regCNVC_CFG3_COLOR_KEYER_CONTROL 0x1118
+#define regCNVC_CFG3_COLOR_KEYER_CONTROL_BASE_IDX 2
+#define regCNVC_CFG3_COLOR_KEYER_ALPHA 0x1119
+#define regCNVC_CFG3_COLOR_KEYER_ALPHA_BASE_IDX 2
+#define regCNVC_CFG3_COLOR_KEYER_RED 0x111a
+#define regCNVC_CFG3_COLOR_KEYER_RED_BASE_IDX 2
+#define regCNVC_CFG3_COLOR_KEYER_GREEN 0x111b
+#define regCNVC_CFG3_COLOR_KEYER_GREEN_BASE_IDX 2
+#define regCNVC_CFG3_COLOR_KEYER_BLUE 0x111c
+#define regCNVC_CFG3_COLOR_KEYER_BLUE_BASE_IDX 2
+#define regCNVC_CFG3_ALPHA_2BIT_LUT 0x111e
+#define regCNVC_CFG3_ALPHA_2BIT_LUT_BASE_IDX 2
+#define regCNVC_CFG3_PRE_DEALPHA 0x111f
+#define regCNVC_CFG3_PRE_DEALPHA_BASE_IDX 2
+#define regCNVC_CFG3_PRE_CSC_MODE 0x1120
+#define regCNVC_CFG3_PRE_CSC_MODE_BASE_IDX 2
+#define regCNVC_CFG3_PRE_CSC_C11_C12 0x1121
+#define regCNVC_CFG3_PRE_CSC_C11_C12_BASE_IDX 2
+#define regCNVC_CFG3_PRE_CSC_C13_C14 0x1122
+#define regCNVC_CFG3_PRE_CSC_C13_C14_BASE_IDX 2
+#define regCNVC_CFG3_PRE_CSC_C21_C22 0x1123
+#define regCNVC_CFG3_PRE_CSC_C21_C22_BASE_IDX 2
+#define regCNVC_CFG3_PRE_CSC_C23_C24 0x1124
+#define regCNVC_CFG3_PRE_CSC_C23_C24_BASE_IDX 2
+#define regCNVC_CFG3_PRE_CSC_C31_C32 0x1125
+#define regCNVC_CFG3_PRE_CSC_C31_C32_BASE_IDX 2
+#define regCNVC_CFG3_PRE_CSC_C33_C34 0x1126
+#define regCNVC_CFG3_PRE_CSC_C33_C34_BASE_IDX 2
+#define regCNVC_CFG3_PRE_CSC_B_C11_C12 0x1127
+#define regCNVC_CFG3_PRE_CSC_B_C11_C12_BASE_IDX 2
+#define regCNVC_CFG3_PRE_CSC_B_C13_C14 0x1128
+#define regCNVC_CFG3_PRE_CSC_B_C13_C14_BASE_IDX 2
+#define regCNVC_CFG3_PRE_CSC_B_C21_C22 0x1129
+#define regCNVC_CFG3_PRE_CSC_B_C21_C22_BASE_IDX 2
+#define regCNVC_CFG3_PRE_CSC_B_C23_C24 0x112a
+#define regCNVC_CFG3_PRE_CSC_B_C23_C24_BASE_IDX 2
+#define regCNVC_CFG3_PRE_CSC_B_C31_C32 0x112b
+#define regCNVC_CFG3_PRE_CSC_B_C31_C32_BASE_IDX 2
+#define regCNVC_CFG3_PRE_CSC_B_C33_C34 0x112c
+#define regCNVC_CFG3_PRE_CSC_B_C33_C34_BASE_IDX 2
+#define regCNVC_CFG3_CNVC_COEF_FORMAT 0x112d
+#define regCNVC_CFG3_CNVC_COEF_FORMAT_BASE_IDX 2
+#define regCNVC_CFG3_PRE_DEGAM 0x112e
+#define regCNVC_CFG3_PRE_DEGAM_BASE_IDX 2
+#define regCNVC_CFG3_PRE_REALPHA 0x112f
+#define regCNVC_CFG3_PRE_REALPHA_BASE_IDX 2
+
+
+// addressBlock: dce_dc_dpp3_dispdec_cnvc_cur_dispdec
+// base address: 0x1104
+#define regCNVC_CUR3_CURSOR0_CONTROL 0x1132
+#define regCNVC_CUR3_CURSOR0_CONTROL_BASE_IDX 2
+#define regCNVC_CUR3_CURSOR0_COLOR0 0x1133
+#define regCNVC_CUR3_CURSOR0_COLOR0_BASE_IDX 2
+#define regCNVC_CUR3_CURSOR0_COLOR1 0x1134
+#define regCNVC_CUR3_CURSOR0_COLOR1_BASE_IDX 2
+#define regCNVC_CUR3_CURSOR0_FP_SCALE_BIAS 0x1135
+#define regCNVC_CUR3_CURSOR0_FP_SCALE_BIAS_BASE_IDX 2
+
+
+// addressBlock: dce_dc_dpp3_dispdec_dscl_dispdec
+// base address: 0x1104
+#define regDSCL3_SCL_COEF_RAM_TAP_SELECT 0x113a
+#define regDSCL3_SCL_COEF_RAM_TAP_SELECT_BASE_IDX 2
+#define regDSCL3_SCL_COEF_RAM_TAP_DATA 0x113b
+#define regDSCL3_SCL_COEF_RAM_TAP_DATA_BASE_IDX 2
+#define regDSCL3_SCL_MODE 0x113c
+#define regDSCL3_SCL_MODE_BASE_IDX 2
+#define regDSCL3_SCL_TAP_CONTROL 0x113d
+#define regDSCL3_SCL_TAP_CONTROL_BASE_IDX 2
+#define regDSCL3_DSCL_CONTROL 0x113e
+#define regDSCL3_DSCL_CONTROL_BASE_IDX 2
+#define regDSCL3_DSCL_2TAP_CONTROL 0x113f
+#define regDSCL3_DSCL_2TAP_CONTROL_BASE_IDX 2
+#define regDSCL3_SCL_MANUAL_REPLICATE_CONTROL 0x1140
+#define regDSCL3_SCL_MANUAL_REPLICATE_CONTROL_BASE_IDX 2
+#define regDSCL3_SCL_HORZ_FILTER_SCALE_RATIO 0x1141
+#define regDSCL3_SCL_HORZ_FILTER_SCALE_RATIO_BASE_IDX 2
+#define regDSCL3_SCL_HORZ_FILTER_INIT 0x1142
+#define regDSCL3_SCL_HORZ_FILTER_INIT_BASE_IDX 2
+#define regDSCL3_SCL_HORZ_FILTER_SCALE_RATIO_C 0x1143
+#define regDSCL3_SCL_HORZ_FILTER_SCALE_RATIO_C_BASE_IDX 2
+#define regDSCL3_SCL_HORZ_FILTER_INIT_C 0x1144
+#define regDSCL3_SCL_HORZ_FILTER_INIT_C_BASE_IDX 2
+#define regDSCL3_SCL_VERT_FILTER_SCALE_RATIO 0x1145
+#define regDSCL3_SCL_VERT_FILTER_SCALE_RATIO_BASE_IDX 2
+#define regDSCL3_SCL_VERT_FILTER_INIT 0x1146
+#define regDSCL3_SCL_VERT_FILTER_INIT_BASE_IDX 2
+#define regDSCL3_SCL_VERT_FILTER_INIT_BOT 0x1147
+#define regDSCL3_SCL_VERT_FILTER_INIT_BOT_BASE_IDX 2
+#define regDSCL3_SCL_VERT_FILTER_SCALE_RATIO_C 0x1148
+#define regDSCL3_SCL_VERT_FILTER_SCALE_RATIO_C_BASE_IDX 2
+#define regDSCL3_SCL_VERT_FILTER_INIT_C 0x1149
+#define regDSCL3_SCL_VERT_FILTER_INIT_C_BASE_IDX 2
+#define regDSCL3_SCL_VERT_FILTER_INIT_BOT_C 0x114a
+#define regDSCL3_SCL_VERT_FILTER_INIT_BOT_C_BASE_IDX 2
+#define regDSCL3_SCL_BLACK_COLOR 0x114b
+#define regDSCL3_SCL_BLACK_COLOR_BASE_IDX 2
+#define regDSCL3_DSCL_UPDATE 0x114c
+#define regDSCL3_DSCL_UPDATE_BASE_IDX 2
+#define regDSCL3_DSCL_AUTOCAL 0x114d
+#define regDSCL3_DSCL_AUTOCAL_BASE_IDX 2
+#define regDSCL3_DSCL_EXT_OVERSCAN_LEFT_RIGHT 0x114e
+#define regDSCL3_DSCL_EXT_OVERSCAN_LEFT_RIGHT_BASE_IDX 2
+#define regDSCL3_DSCL_EXT_OVERSCAN_TOP_BOTTOM 0x114f
+#define regDSCL3_DSCL_EXT_OVERSCAN_TOP_BOTTOM_BASE_IDX 2
+#define regDSCL3_OTG_H_BLANK 0x1150
+#define regDSCL3_OTG_H_BLANK_BASE_IDX 2
+#define regDSCL3_OTG_V_BLANK 0x1151
+#define regDSCL3_OTG_V_BLANK_BASE_IDX 2
+#define regDSCL3_RECOUT_START 0x1152
+#define regDSCL3_RECOUT_START_BASE_IDX 2
+#define regDSCL3_RECOUT_SIZE 0x1153
+#define regDSCL3_RECOUT_SIZE_BASE_IDX 2
+#define regDSCL3_MPC_SIZE 0x1154
+#define regDSCL3_MPC_SIZE_BASE_IDX 2
+#define regDSCL3_LB_DATA_FORMAT 0x1155
+#define regDSCL3_LB_DATA_FORMAT_BASE_IDX 2
+#define regDSCL3_LB_MEMORY_CTRL 0x1156
+#define regDSCL3_LB_MEMORY_CTRL_BASE_IDX 2
+#define regDSCL3_LB_V_COUNTER 0x1157
+#define regDSCL3_LB_V_COUNTER_BASE_IDX 2
+#define regDSCL3_DSCL_MEM_PWR_CTRL 0x1158
+#define regDSCL3_DSCL_MEM_PWR_CTRL_BASE_IDX 2
+#define regDSCL3_DSCL_MEM_PWR_STATUS 0x1159
+#define regDSCL3_DSCL_MEM_PWR_STATUS_BASE_IDX 2
+#define regDSCL3_OBUF_CONTROL 0x115a
+#define regDSCL3_OBUF_CONTROL_BASE_IDX 2
+#define regDSCL3_OBUF_MEM_PWR_CTRL 0x115b
+#define regDSCL3_OBUF_MEM_PWR_CTRL_BASE_IDX 2
+
+
+// addressBlock: dce_dc_dpp3_dispdec_cm_dispdec
+// base address: 0x1104
+#define regCM3_CM_CONTROL 0x1161
+#define regCM3_CM_CONTROL_BASE_IDX 2
+#define regCM3_CM_POST_CSC_CONTROL 0x1162
+#define regCM3_CM_POST_CSC_CONTROL_BASE_IDX 2
+#define regCM3_CM_POST_CSC_C11_C12 0x1163
+#define regCM3_CM_POST_CSC_C11_C12_BASE_IDX 2
+#define regCM3_CM_POST_CSC_C13_C14 0x1164
+#define regCM3_CM_POST_CSC_C13_C14_BASE_IDX 2
+#define regCM3_CM_POST_CSC_C21_C22 0x1165
+#define regCM3_CM_POST_CSC_C21_C22_BASE_IDX 2
+#define regCM3_CM_POST_CSC_C23_C24 0x1166
+#define regCM3_CM_POST_CSC_C23_C24_BASE_IDX 2
+#define regCM3_CM_POST_CSC_C31_C32 0x1167
+#define regCM3_CM_POST_CSC_C31_C32_BASE_IDX 2
+#define regCM3_CM_POST_CSC_C33_C34 0x1168
+#define regCM3_CM_POST_CSC_C33_C34_BASE_IDX 2
+#define regCM3_CM_POST_CSC_B_C11_C12 0x1169
+#define regCM3_CM_POST_CSC_B_C11_C12_BASE_IDX 2
+#define regCM3_CM_POST_CSC_B_C13_C14 0x116a
+#define regCM3_CM_POST_CSC_B_C13_C14_BASE_IDX 2
+#define regCM3_CM_POST_CSC_B_C21_C22 0x116b
+#define regCM3_CM_POST_CSC_B_C21_C22_BASE_IDX 2
+#define regCM3_CM_POST_CSC_B_C23_C24 0x116c
+#define regCM3_CM_POST_CSC_B_C23_C24_BASE_IDX 2
+#define regCM3_CM_POST_CSC_B_C31_C32 0x116d
+#define regCM3_CM_POST_CSC_B_C31_C32_BASE_IDX 2
+#define regCM3_CM_POST_CSC_B_C33_C34 0x116e
+#define regCM3_CM_POST_CSC_B_C33_C34_BASE_IDX 2
+#define regCM3_CM_GAMUT_REMAP_CONTROL 0x116f
+#define regCM3_CM_GAMUT_REMAP_CONTROL_BASE_IDX 2
+#define regCM3_CM_GAMUT_REMAP_C11_C12 0x1170
+#define regCM3_CM_GAMUT_REMAP_C11_C12_BASE_IDX 2
+#define regCM3_CM_GAMUT_REMAP_C13_C14 0x1171
+#define regCM3_CM_GAMUT_REMAP_C13_C14_BASE_IDX 2
+#define regCM3_CM_GAMUT_REMAP_C21_C22 0x1172
+#define regCM3_CM_GAMUT_REMAP_C21_C22_BASE_IDX 2
+#define regCM3_CM_GAMUT_REMAP_C23_C24 0x1173
+#define regCM3_CM_GAMUT_REMAP_C23_C24_BASE_IDX 2
+#define regCM3_CM_GAMUT_REMAP_C31_C32 0x1174
+#define regCM3_CM_GAMUT_REMAP_C31_C32_BASE_IDX 2
+#define regCM3_CM_GAMUT_REMAP_C33_C34 0x1175
+#define regCM3_CM_GAMUT_REMAP_C33_C34_BASE_IDX 2
+#define regCM3_CM_GAMUT_REMAP_B_C11_C12 0x1176
+#define regCM3_CM_GAMUT_REMAP_B_C11_C12_BASE_IDX 2
+#define regCM3_CM_GAMUT_REMAP_B_C13_C14 0x1177
+#define regCM3_CM_GAMUT_REMAP_B_C13_C14_BASE_IDX 2
+#define regCM3_CM_GAMUT_REMAP_B_C21_C22 0x1178
+#define regCM3_CM_GAMUT_REMAP_B_C21_C22_BASE_IDX 2
+#define regCM3_CM_GAMUT_REMAP_B_C23_C24 0x1179
+#define regCM3_CM_GAMUT_REMAP_B_C23_C24_BASE_IDX 2
+#define regCM3_CM_GAMUT_REMAP_B_C31_C32 0x117a
+#define regCM3_CM_GAMUT_REMAP_B_C31_C32_BASE_IDX 2
+#define regCM3_CM_GAMUT_REMAP_B_C33_C34 0x117b
+#define regCM3_CM_GAMUT_REMAP_B_C33_C34_BASE_IDX 2
+#define regCM3_CM_BIAS_CR_R 0x117c
+#define regCM3_CM_BIAS_CR_R_BASE_IDX 2
+#define regCM3_CM_BIAS_Y_G_CB_B 0x117d
+#define regCM3_CM_BIAS_Y_G_CB_B_BASE_IDX 2
+#define regCM3_CM_GAMCOR_CONTROL 0x117e
+#define regCM3_CM_GAMCOR_CONTROL_BASE_IDX 2
+#define regCM3_CM_GAMCOR_LUT_INDEX 0x117f
+#define regCM3_CM_GAMCOR_LUT_INDEX_BASE_IDX 2
+#define regCM3_CM_GAMCOR_LUT_DATA 0x1180
+#define regCM3_CM_GAMCOR_LUT_DATA_BASE_IDX 2
+#define regCM3_CM_GAMCOR_LUT_CONTROL 0x1181
+#define regCM3_CM_GAMCOR_LUT_CONTROL_BASE_IDX 2
+#define regCM3_CM_GAMCOR_RAMA_START_CNTL_B 0x1182
+#define regCM3_CM_GAMCOR_RAMA_START_CNTL_B_BASE_IDX 2
+#define regCM3_CM_GAMCOR_RAMA_START_CNTL_G 0x1183
+#define regCM3_CM_GAMCOR_RAMA_START_CNTL_G_BASE_IDX 2
+#define regCM3_CM_GAMCOR_RAMA_START_CNTL_R 0x1184
+#define regCM3_CM_GAMCOR_RAMA_START_CNTL_R_BASE_IDX 2
+#define regCM3_CM_GAMCOR_RAMA_START_SLOPE_CNTL_B 0x1185
+#define regCM3_CM_GAMCOR_RAMA_START_SLOPE_CNTL_B_BASE_IDX 2
+#define regCM3_CM_GAMCOR_RAMA_START_SLOPE_CNTL_G 0x1186
+#define regCM3_CM_GAMCOR_RAMA_START_SLOPE_CNTL_G_BASE_IDX 2
+#define regCM3_CM_GAMCOR_RAMA_START_SLOPE_CNTL_R 0x1187
+#define regCM3_CM_GAMCOR_RAMA_START_SLOPE_CNTL_R_BASE_IDX 2
+#define regCM3_CM_GAMCOR_RAMA_START_BASE_CNTL_B 0x1188
+#define regCM3_CM_GAMCOR_RAMA_START_BASE_CNTL_B_BASE_IDX 2
+#define regCM3_CM_GAMCOR_RAMA_START_BASE_CNTL_G 0x1189
+#define regCM3_CM_GAMCOR_RAMA_START_BASE_CNTL_G_BASE_IDX 2
+#define regCM3_CM_GAMCOR_RAMA_START_BASE_CNTL_R 0x118a
+#define regCM3_CM_GAMCOR_RAMA_START_BASE_CNTL_R_BASE_IDX 2
+#define regCM3_CM_GAMCOR_RAMA_END_CNTL1_B 0x118b
+#define regCM3_CM_GAMCOR_RAMA_END_CNTL1_B_BASE_IDX 2
+#define regCM3_CM_GAMCOR_RAMA_END_CNTL2_B 0x118c
+#define regCM3_CM_GAMCOR_RAMA_END_CNTL2_B_BASE_IDX 2
+#define regCM3_CM_GAMCOR_RAMA_END_CNTL1_G 0x118d
+#define regCM3_CM_GAMCOR_RAMA_END_CNTL1_G_BASE_IDX 2
+#define regCM3_CM_GAMCOR_RAMA_END_CNTL2_G 0x118e
+#define regCM3_CM_GAMCOR_RAMA_END_CNTL2_G_BASE_IDX 2
+#define regCM3_CM_GAMCOR_RAMA_END_CNTL1_R 0x118f
+#define regCM3_CM_GAMCOR_RAMA_END_CNTL1_R_BASE_IDX 2
+#define regCM3_CM_GAMCOR_RAMA_END_CNTL2_R 0x1190
+#define regCM3_CM_GAMCOR_RAMA_END_CNTL2_R_BASE_IDX 2
+#define regCM3_CM_GAMCOR_RAMA_OFFSET_B 0x1191
+#define regCM3_CM_GAMCOR_RAMA_OFFSET_B_BASE_IDX 2
+#define regCM3_CM_GAMCOR_RAMA_OFFSET_G 0x1192
+#define regCM3_CM_GAMCOR_RAMA_OFFSET_G_BASE_IDX 2
+#define regCM3_CM_GAMCOR_RAMA_OFFSET_R 0x1193
+#define regCM3_CM_GAMCOR_RAMA_OFFSET_R_BASE_IDX 2
+#define regCM3_CM_GAMCOR_RAMA_REGION_0_1 0x1194
+#define regCM3_CM_GAMCOR_RAMA_REGION_0_1_BASE_IDX 2
+#define regCM3_CM_GAMCOR_RAMA_REGION_2_3 0x1195
+#define regCM3_CM_GAMCOR_RAMA_REGION_2_3_BASE_IDX 2
+#define regCM3_CM_GAMCOR_RAMA_REGION_4_5 0x1196
+#define regCM3_CM_GAMCOR_RAMA_REGION_4_5_BASE_IDX 2
+#define regCM3_CM_GAMCOR_RAMA_REGION_6_7 0x1197
+#define regCM3_CM_GAMCOR_RAMA_REGION_6_7_BASE_IDX 2
+#define regCM3_CM_GAMCOR_RAMA_REGION_8_9 0x1198
+#define regCM3_CM_GAMCOR_RAMA_REGION_8_9_BASE_IDX 2
+#define regCM3_CM_GAMCOR_RAMA_REGION_10_11 0x1199
+#define regCM3_CM_GAMCOR_RAMA_REGION_10_11_BASE_IDX 2
+#define regCM3_CM_GAMCOR_RAMA_REGION_12_13 0x119a
+#define regCM3_CM_GAMCOR_RAMA_REGION_12_13_BASE_IDX 2
+#define regCM3_CM_GAMCOR_RAMA_REGION_14_15 0x119b
+#define regCM3_CM_GAMCOR_RAMA_REGION_14_15_BASE_IDX 2
+#define regCM3_CM_GAMCOR_RAMA_REGION_16_17 0x119c
+#define regCM3_CM_GAMCOR_RAMA_REGION_16_17_BASE_IDX 2
+#define regCM3_CM_GAMCOR_RAMA_REGION_18_19 0x119d
+#define regCM3_CM_GAMCOR_RAMA_REGION_18_19_BASE_IDX 2
+#define regCM3_CM_GAMCOR_RAMA_REGION_20_21 0x119e
+#define regCM3_CM_GAMCOR_RAMA_REGION_20_21_BASE_IDX 2
+#define regCM3_CM_GAMCOR_RAMA_REGION_22_23 0x119f
+#define regCM3_CM_GAMCOR_RAMA_REGION_22_23_BASE_IDX 2
+#define regCM3_CM_GAMCOR_RAMA_REGION_24_25 0x11a0
+#define regCM3_CM_GAMCOR_RAMA_REGION_24_25_BASE_IDX 2
+#define regCM3_CM_GAMCOR_RAMA_REGION_26_27 0x11a1
+#define regCM3_CM_GAMCOR_RAMA_REGION_26_27_BASE_IDX 2
+#define regCM3_CM_GAMCOR_RAMA_REGION_28_29 0x11a2
+#define regCM3_CM_GAMCOR_RAMA_REGION_28_29_BASE_IDX 2
+#define regCM3_CM_GAMCOR_RAMA_REGION_30_31 0x11a3
+#define regCM3_CM_GAMCOR_RAMA_REGION_30_31_BASE_IDX 2
+#define regCM3_CM_GAMCOR_RAMA_REGION_32_33 0x11a4
+#define regCM3_CM_GAMCOR_RAMA_REGION_32_33_BASE_IDX 2
+#define regCM3_CM_GAMCOR_RAMB_START_CNTL_B 0x11a5
+#define regCM3_CM_GAMCOR_RAMB_START_CNTL_B_BASE_IDX 2
+#define regCM3_CM_GAMCOR_RAMB_START_CNTL_G 0x11a6
+#define regCM3_CM_GAMCOR_RAMB_START_CNTL_G_BASE_IDX 2
+#define regCM3_CM_GAMCOR_RAMB_START_CNTL_R 0x11a7
+#define regCM3_CM_GAMCOR_RAMB_START_CNTL_R_BASE_IDX 2
+#define regCM3_CM_GAMCOR_RAMB_START_SLOPE_CNTL_B 0x11a8
+#define regCM3_CM_GAMCOR_RAMB_START_SLOPE_CNTL_B_BASE_IDX 2
+#define regCM3_CM_GAMCOR_RAMB_START_SLOPE_CNTL_G 0x11a9
+#define regCM3_CM_GAMCOR_RAMB_START_SLOPE_CNTL_G_BASE_IDX 2
+#define regCM3_CM_GAMCOR_RAMB_START_SLOPE_CNTL_R 0x11aa
+#define regCM3_CM_GAMCOR_RAMB_START_SLOPE_CNTL_R_BASE_IDX 2
+#define regCM3_CM_GAMCOR_RAMB_START_BASE_CNTL_B 0x11ab
+#define regCM3_CM_GAMCOR_RAMB_START_BASE_CNTL_B_BASE_IDX 2
+#define regCM3_CM_GAMCOR_RAMB_START_BASE_CNTL_G 0x11ac
+#define regCM3_CM_GAMCOR_RAMB_START_BASE_CNTL_G_BASE_IDX 2
+#define regCM3_CM_GAMCOR_RAMB_START_BASE_CNTL_R 0x11ad
+#define regCM3_CM_GAMCOR_RAMB_START_BASE_CNTL_R_BASE_IDX 2
+#define regCM3_CM_GAMCOR_RAMB_END_CNTL1_B 0x11ae
+#define regCM3_CM_GAMCOR_RAMB_END_CNTL1_B_BASE_IDX 2
+#define regCM3_CM_GAMCOR_RAMB_END_CNTL2_B 0x11af
+#define regCM3_CM_GAMCOR_RAMB_END_CNTL2_B_BASE_IDX 2
+#define regCM3_CM_GAMCOR_RAMB_END_CNTL1_G 0x11b0
+#define regCM3_CM_GAMCOR_RAMB_END_CNTL1_G_BASE_IDX 2
+#define regCM3_CM_GAMCOR_RAMB_END_CNTL2_G 0x11b1
+#define regCM3_CM_GAMCOR_RAMB_END_CNTL2_G_BASE_IDX 2
+#define regCM3_CM_GAMCOR_RAMB_END_CNTL1_R 0x11b2
+#define regCM3_CM_GAMCOR_RAMB_END_CNTL1_R_BASE_IDX 2
+#define regCM3_CM_GAMCOR_RAMB_END_CNTL2_R 0x11b3
+#define regCM3_CM_GAMCOR_RAMB_END_CNTL2_R_BASE_IDX 2
+#define regCM3_CM_GAMCOR_RAMB_OFFSET_B 0x11b4
+#define regCM3_CM_GAMCOR_RAMB_OFFSET_B_BASE_IDX 2
+#define regCM3_CM_GAMCOR_RAMB_OFFSET_G 0x11b5
+#define regCM3_CM_GAMCOR_RAMB_OFFSET_G_BASE_IDX 2
+#define regCM3_CM_GAMCOR_RAMB_OFFSET_R 0x11b6
+#define regCM3_CM_GAMCOR_RAMB_OFFSET_R_BASE_IDX 2
+#define regCM3_CM_GAMCOR_RAMB_REGION_0_1 0x11b7
+#define regCM3_CM_GAMCOR_RAMB_REGION_0_1_BASE_IDX 2
+#define regCM3_CM_GAMCOR_RAMB_REGION_2_3 0x11b8
+#define regCM3_CM_GAMCOR_RAMB_REGION_2_3_BASE_IDX 2
+#define regCM3_CM_GAMCOR_RAMB_REGION_4_5 0x11b9
+#define regCM3_CM_GAMCOR_RAMB_REGION_4_5_BASE_IDX 2
+#define regCM3_CM_GAMCOR_RAMB_REGION_6_7 0x11ba
+#define regCM3_CM_GAMCOR_RAMB_REGION_6_7_BASE_IDX 2
+#define regCM3_CM_GAMCOR_RAMB_REGION_8_9 0x11bb
+#define regCM3_CM_GAMCOR_RAMB_REGION_8_9_BASE_IDX 2
+#define regCM3_CM_GAMCOR_RAMB_REGION_10_11 0x11bc
+#define regCM3_CM_GAMCOR_RAMB_REGION_10_11_BASE_IDX 2
+#define regCM3_CM_GAMCOR_RAMB_REGION_12_13 0x11bd
+#define regCM3_CM_GAMCOR_RAMB_REGION_12_13_BASE_IDX 2
+#define regCM3_CM_GAMCOR_RAMB_REGION_14_15 0x11be
+#define regCM3_CM_GAMCOR_RAMB_REGION_14_15_BASE_IDX 2
+#define regCM3_CM_GAMCOR_RAMB_REGION_16_17 0x11bf
+#define regCM3_CM_GAMCOR_RAMB_REGION_16_17_BASE_IDX 2
+#define regCM3_CM_GAMCOR_RAMB_REGION_18_19 0x11c0
+#define regCM3_CM_GAMCOR_RAMB_REGION_18_19_BASE_IDX 2
+#define regCM3_CM_GAMCOR_RAMB_REGION_20_21 0x11c1
+#define regCM3_CM_GAMCOR_RAMB_REGION_20_21_BASE_IDX 2
+#define regCM3_CM_GAMCOR_RAMB_REGION_22_23 0x11c2
+#define regCM3_CM_GAMCOR_RAMB_REGION_22_23_BASE_IDX 2
+#define regCM3_CM_GAMCOR_RAMB_REGION_24_25 0x11c3
+#define regCM3_CM_GAMCOR_RAMB_REGION_24_25_BASE_IDX 2
+#define regCM3_CM_GAMCOR_RAMB_REGION_26_27 0x11c4
+#define regCM3_CM_GAMCOR_RAMB_REGION_26_27_BASE_IDX 2
+#define regCM3_CM_GAMCOR_RAMB_REGION_28_29 0x11c5
+#define regCM3_CM_GAMCOR_RAMB_REGION_28_29_BASE_IDX 2
+#define regCM3_CM_GAMCOR_RAMB_REGION_30_31 0x11c6
+#define regCM3_CM_GAMCOR_RAMB_REGION_30_31_BASE_IDX 2
+#define regCM3_CM_GAMCOR_RAMB_REGION_32_33 0x11c7
+#define regCM3_CM_GAMCOR_RAMB_REGION_32_33_BASE_IDX 2
+#define regCM3_CM_BLNDGAM_CONTROL 0x11c8
+#define regCM3_CM_BLNDGAM_CONTROL_BASE_IDX 2
+#define regCM3_CM_BLNDGAM_LUT_INDEX 0x11c9
+#define regCM3_CM_BLNDGAM_LUT_INDEX_BASE_IDX 2
+#define regCM3_CM_BLNDGAM_LUT_DATA 0x11ca
+#define regCM3_CM_BLNDGAM_LUT_DATA_BASE_IDX 2
+#define regCM3_CM_BLNDGAM_LUT_CONTROL 0x11cb
+#define regCM3_CM_BLNDGAM_LUT_CONTROL_BASE_IDX 2
+#define regCM3_CM_BLNDGAM_RAMA_START_CNTL_B 0x11cc
+#define regCM3_CM_BLNDGAM_RAMA_START_CNTL_B_BASE_IDX 2
+#define regCM3_CM_BLNDGAM_RAMA_START_CNTL_G 0x11cd
+#define regCM3_CM_BLNDGAM_RAMA_START_CNTL_G_BASE_IDX 2
+#define regCM3_CM_BLNDGAM_RAMA_START_CNTL_R 0x11ce
+#define regCM3_CM_BLNDGAM_RAMA_START_CNTL_R_BASE_IDX 2
+#define regCM3_CM_BLNDGAM_RAMA_START_SLOPE_CNTL_B 0x11cf
+#define regCM3_CM_BLNDGAM_RAMA_START_SLOPE_CNTL_B_BASE_IDX 2
+#define regCM3_CM_BLNDGAM_RAMA_START_SLOPE_CNTL_G 0x11d0
+#define regCM3_CM_BLNDGAM_RAMA_START_SLOPE_CNTL_G_BASE_IDX 2
+#define regCM3_CM_BLNDGAM_RAMA_START_SLOPE_CNTL_R 0x11d1
+#define regCM3_CM_BLNDGAM_RAMA_START_SLOPE_CNTL_R_BASE_IDX 2
+#define regCM3_CM_BLNDGAM_RAMA_START_BASE_CNTL_B 0x11d2
+#define regCM3_CM_BLNDGAM_RAMA_START_BASE_CNTL_B_BASE_IDX 2
+#define regCM3_CM_BLNDGAM_RAMA_START_BASE_CNTL_G 0x11d3
+#define regCM3_CM_BLNDGAM_RAMA_START_BASE_CNTL_G_BASE_IDX 2
+#define regCM3_CM_BLNDGAM_RAMA_START_BASE_CNTL_R 0x11d4
+#define regCM3_CM_BLNDGAM_RAMA_START_BASE_CNTL_R_BASE_IDX 2
+#define regCM3_CM_BLNDGAM_RAMA_END_CNTL1_B 0x11d5
+#define regCM3_CM_BLNDGAM_RAMA_END_CNTL1_B_BASE_IDX 2
+#define regCM3_CM_BLNDGAM_RAMA_END_CNTL2_B 0x11d6
+#define regCM3_CM_BLNDGAM_RAMA_END_CNTL2_B_BASE_IDX 2
+#define regCM3_CM_BLNDGAM_RAMA_END_CNTL1_G 0x11d7
+#define regCM3_CM_BLNDGAM_RAMA_END_CNTL1_G_BASE_IDX 2
+#define regCM3_CM_BLNDGAM_RAMA_END_CNTL2_G 0x11d8
+#define regCM3_CM_BLNDGAM_RAMA_END_CNTL2_G_BASE_IDX 2
+#define regCM3_CM_BLNDGAM_RAMA_END_CNTL1_R 0x11d9
+#define regCM3_CM_BLNDGAM_RAMA_END_CNTL1_R_BASE_IDX 2
+#define regCM3_CM_BLNDGAM_RAMA_END_CNTL2_R 0x11da
+#define regCM3_CM_BLNDGAM_RAMA_END_CNTL2_R_BASE_IDX 2
+#define regCM3_CM_BLNDGAM_RAMA_OFFSET_B 0x11db
+#define regCM3_CM_BLNDGAM_RAMA_OFFSET_B_BASE_IDX 2
+#define regCM3_CM_BLNDGAM_RAMA_OFFSET_G 0x11dc
+#define regCM3_CM_BLNDGAM_RAMA_OFFSET_G_BASE_IDX 2
+#define regCM3_CM_BLNDGAM_RAMA_OFFSET_R 0x11dd
+#define regCM3_CM_BLNDGAM_RAMA_OFFSET_R_BASE_IDX 2
+#define regCM3_CM_BLNDGAM_RAMA_REGION_0_1 0x11de
+#define regCM3_CM_BLNDGAM_RAMA_REGION_0_1_BASE_IDX 2
+#define regCM3_CM_BLNDGAM_RAMA_REGION_2_3 0x11df
+#define regCM3_CM_BLNDGAM_RAMA_REGION_2_3_BASE_IDX 2
+#define regCM3_CM_BLNDGAM_RAMA_REGION_4_5 0x11e0
+#define regCM3_CM_BLNDGAM_RAMA_REGION_4_5_BASE_IDX 2
+#define regCM3_CM_BLNDGAM_RAMA_REGION_6_7 0x11e1
+#define regCM3_CM_BLNDGAM_RAMA_REGION_6_7_BASE_IDX 2
+#define regCM3_CM_BLNDGAM_RAMA_REGION_8_9 0x11e2
+#define regCM3_CM_BLNDGAM_RAMA_REGION_8_9_BASE_IDX 2
+#define regCM3_CM_BLNDGAM_RAMA_REGION_10_11 0x11e3
+#define regCM3_CM_BLNDGAM_RAMA_REGION_10_11_BASE_IDX 2
+#define regCM3_CM_BLNDGAM_RAMA_REGION_12_13 0x11e4
+#define regCM3_CM_BLNDGAM_RAMA_REGION_12_13_BASE_IDX 2
+#define regCM3_CM_BLNDGAM_RAMA_REGION_14_15 0x11e5
+#define regCM3_CM_BLNDGAM_RAMA_REGION_14_15_BASE_IDX 2
+#define regCM3_CM_BLNDGAM_RAMA_REGION_16_17 0x11e6
+#define regCM3_CM_BLNDGAM_RAMA_REGION_16_17_BASE_IDX 2
+#define regCM3_CM_BLNDGAM_RAMA_REGION_18_19 0x11e7
+#define regCM3_CM_BLNDGAM_RAMA_REGION_18_19_BASE_IDX 2
+#define regCM3_CM_BLNDGAM_RAMA_REGION_20_21 0x11e8
+#define regCM3_CM_BLNDGAM_RAMA_REGION_20_21_BASE_IDX 2
+#define regCM3_CM_BLNDGAM_RAMA_REGION_22_23 0x11e9
+#define regCM3_CM_BLNDGAM_RAMA_REGION_22_23_BASE_IDX 2
+#define regCM3_CM_BLNDGAM_RAMA_REGION_24_25 0x11ea
+#define regCM3_CM_BLNDGAM_RAMA_REGION_24_25_BASE_IDX 2
+#define regCM3_CM_BLNDGAM_RAMA_REGION_26_27 0x11eb
+#define regCM3_CM_BLNDGAM_RAMA_REGION_26_27_BASE_IDX 2
+#define regCM3_CM_BLNDGAM_RAMA_REGION_28_29 0x11ec
+#define regCM3_CM_BLNDGAM_RAMA_REGION_28_29_BASE_IDX 2
+#define regCM3_CM_BLNDGAM_RAMA_REGION_30_31 0x11ed
+#define regCM3_CM_BLNDGAM_RAMA_REGION_30_31_BASE_IDX 2
+#define regCM3_CM_BLNDGAM_RAMA_REGION_32_33 0x11ee
+#define regCM3_CM_BLNDGAM_RAMA_REGION_32_33_BASE_IDX 2
+#define regCM3_CM_BLNDGAM_RAMB_START_CNTL_B 0x11ef
+#define regCM3_CM_BLNDGAM_RAMB_START_CNTL_B_BASE_IDX 2
+#define regCM3_CM_BLNDGAM_RAMB_START_CNTL_G 0x11f0
+#define regCM3_CM_BLNDGAM_RAMB_START_CNTL_G_BASE_IDX 2
+#define regCM3_CM_BLNDGAM_RAMB_START_CNTL_R 0x11f1
+#define regCM3_CM_BLNDGAM_RAMB_START_CNTL_R_BASE_IDX 2
+#define regCM3_CM_BLNDGAM_RAMB_START_SLOPE_CNTL_B 0x11f2
+#define regCM3_CM_BLNDGAM_RAMB_START_SLOPE_CNTL_B_BASE_IDX 2
+#define regCM3_CM_BLNDGAM_RAMB_START_SLOPE_CNTL_G 0x11f3
+#define regCM3_CM_BLNDGAM_RAMB_START_SLOPE_CNTL_G_BASE_IDX 2
+#define regCM3_CM_BLNDGAM_RAMB_START_SLOPE_CNTL_R 0x11f4
+#define regCM3_CM_BLNDGAM_RAMB_START_SLOPE_CNTL_R_BASE_IDX 2
+#define regCM3_CM_BLNDGAM_RAMB_START_BASE_CNTL_B 0x11f5
+#define regCM3_CM_BLNDGAM_RAMB_START_BASE_CNTL_B_BASE_IDX 2
+#define regCM3_CM_BLNDGAM_RAMB_START_BASE_CNTL_G 0x11f6
+#define regCM3_CM_BLNDGAM_RAMB_START_BASE_CNTL_G_BASE_IDX 2
+#define regCM3_CM_BLNDGAM_RAMB_START_BASE_CNTL_R 0x11f7
+#define regCM3_CM_BLNDGAM_RAMB_START_BASE_CNTL_R_BASE_IDX 2
+#define regCM3_CM_BLNDGAM_RAMB_END_CNTL1_B 0x11f8
+#define regCM3_CM_BLNDGAM_RAMB_END_CNTL1_B_BASE_IDX 2
+#define regCM3_CM_BLNDGAM_RAMB_END_CNTL2_B 0x11f9
+#define regCM3_CM_BLNDGAM_RAMB_END_CNTL2_B_BASE_IDX 2
+#define regCM3_CM_BLNDGAM_RAMB_END_CNTL1_G 0x11fa
+#define regCM3_CM_BLNDGAM_RAMB_END_CNTL1_G_BASE_IDX 2
+#define regCM3_CM_BLNDGAM_RAMB_END_CNTL2_G 0x11fb
+#define regCM3_CM_BLNDGAM_RAMB_END_CNTL2_G_BASE_IDX 2
+#define regCM3_CM_BLNDGAM_RAMB_END_CNTL1_R 0x11fc
+#define regCM3_CM_BLNDGAM_RAMB_END_CNTL1_R_BASE_IDX 2
+#define regCM3_CM_BLNDGAM_RAMB_END_CNTL2_R 0x11fd
+#define regCM3_CM_BLNDGAM_RAMB_END_CNTL2_R_BASE_IDX 2
+#define regCM3_CM_BLNDGAM_RAMB_OFFSET_B 0x11fe
+#define regCM3_CM_BLNDGAM_RAMB_OFFSET_B_BASE_IDX 2
+#define regCM3_CM_BLNDGAM_RAMB_OFFSET_G 0x11ff
+#define regCM3_CM_BLNDGAM_RAMB_OFFSET_G_BASE_IDX 2
+#define regCM3_CM_BLNDGAM_RAMB_OFFSET_R 0x1200
+#define regCM3_CM_BLNDGAM_RAMB_OFFSET_R_BASE_IDX 2
+#define regCM3_CM_BLNDGAM_RAMB_REGION_0_1 0x1201
+#define regCM3_CM_BLNDGAM_RAMB_REGION_0_1_BASE_IDX 2
+#define regCM3_CM_BLNDGAM_RAMB_REGION_2_3 0x1202
+#define regCM3_CM_BLNDGAM_RAMB_REGION_2_3_BASE_IDX 2
+#define regCM3_CM_BLNDGAM_RAMB_REGION_4_5 0x1203
+#define regCM3_CM_BLNDGAM_RAMB_REGION_4_5_BASE_IDX 2
+#define regCM3_CM_BLNDGAM_RAMB_REGION_6_7 0x1204
+#define regCM3_CM_BLNDGAM_RAMB_REGION_6_7_BASE_IDX 2
+#define regCM3_CM_BLNDGAM_RAMB_REGION_8_9 0x1205
+#define regCM3_CM_BLNDGAM_RAMB_REGION_8_9_BASE_IDX 2
+#define regCM3_CM_BLNDGAM_RAMB_REGION_10_11 0x1206
+#define regCM3_CM_BLNDGAM_RAMB_REGION_10_11_BASE_IDX 2
+#define regCM3_CM_BLNDGAM_RAMB_REGION_12_13 0x1207
+#define regCM3_CM_BLNDGAM_RAMB_REGION_12_13_BASE_IDX 2
+#define regCM3_CM_BLNDGAM_RAMB_REGION_14_15 0x1208
+#define regCM3_CM_BLNDGAM_RAMB_REGION_14_15_BASE_IDX 2
+#define regCM3_CM_BLNDGAM_RAMB_REGION_16_17 0x1209
+#define regCM3_CM_BLNDGAM_RAMB_REGION_16_17_BASE_IDX 2
+#define regCM3_CM_BLNDGAM_RAMB_REGION_18_19 0x120a
+#define regCM3_CM_BLNDGAM_RAMB_REGION_18_19_BASE_IDX 2
+#define regCM3_CM_BLNDGAM_RAMB_REGION_20_21 0x120b
+#define regCM3_CM_BLNDGAM_RAMB_REGION_20_21_BASE_IDX 2
+#define regCM3_CM_BLNDGAM_RAMB_REGION_22_23 0x120c
+#define regCM3_CM_BLNDGAM_RAMB_REGION_22_23_BASE_IDX 2
+#define regCM3_CM_BLNDGAM_RAMB_REGION_24_25 0x120d
+#define regCM3_CM_BLNDGAM_RAMB_REGION_24_25_BASE_IDX 2
+#define regCM3_CM_BLNDGAM_RAMB_REGION_26_27 0x120e
+#define regCM3_CM_BLNDGAM_RAMB_REGION_26_27_BASE_IDX 2
+#define regCM3_CM_BLNDGAM_RAMB_REGION_28_29 0x120f
+#define regCM3_CM_BLNDGAM_RAMB_REGION_28_29_BASE_IDX 2
+#define regCM3_CM_BLNDGAM_RAMB_REGION_30_31 0x1210
+#define regCM3_CM_BLNDGAM_RAMB_REGION_30_31_BASE_IDX 2
+#define regCM3_CM_BLNDGAM_RAMB_REGION_32_33 0x1211
+#define regCM3_CM_BLNDGAM_RAMB_REGION_32_33_BASE_IDX 2
+#define regCM3_CM_HDR_MULT_COEF 0x1212
+#define regCM3_CM_HDR_MULT_COEF_BASE_IDX 2
+#define regCM3_CM_MEM_PWR_CTRL 0x1213
+#define regCM3_CM_MEM_PWR_CTRL_BASE_IDX 2
+#define regCM3_CM_MEM_PWR_STATUS 0x1214
+#define regCM3_CM_MEM_PWR_STATUS_BASE_IDX 2
+#define regCM3_CM_DEALPHA 0x1216
+#define regCM3_CM_DEALPHA_BASE_IDX 2
+#define regCM3_CM_COEF_FORMAT 0x1217
+#define regCM3_CM_COEF_FORMAT_BASE_IDX 2
+#define regCM3_CM_SHAPER_CONTROL 0x1218
+#define regCM3_CM_SHAPER_CONTROL_BASE_IDX 2
+#define regCM3_CM_SHAPER_OFFSET_R 0x1219
+#define regCM3_CM_SHAPER_OFFSET_R_BASE_IDX 2
+#define regCM3_CM_SHAPER_OFFSET_G 0x121a
+#define regCM3_CM_SHAPER_OFFSET_G_BASE_IDX 2
+#define regCM3_CM_SHAPER_OFFSET_B 0x121b
+#define regCM3_CM_SHAPER_OFFSET_B_BASE_IDX 2
+#define regCM3_CM_SHAPER_SCALE_R 0x121c
+#define regCM3_CM_SHAPER_SCALE_R_BASE_IDX 2
+#define regCM3_CM_SHAPER_SCALE_G_B 0x121d
+#define regCM3_CM_SHAPER_SCALE_G_B_BASE_IDX 2
+#define regCM3_CM_SHAPER_LUT_INDEX 0x121e
+#define regCM3_CM_SHAPER_LUT_INDEX_BASE_IDX 2
+#define regCM3_CM_SHAPER_LUT_DATA 0x121f
+#define regCM3_CM_SHAPER_LUT_DATA_BASE_IDX 2
+#define regCM3_CM_SHAPER_LUT_WRITE_EN_MASK 0x1220
+#define regCM3_CM_SHAPER_LUT_WRITE_EN_MASK_BASE_IDX 2
+#define regCM3_CM_SHAPER_RAMA_START_CNTL_B 0x1221
+#define regCM3_CM_SHAPER_RAMA_START_CNTL_B_BASE_IDX 2
+#define regCM3_CM_SHAPER_RAMA_START_CNTL_G 0x1222
+#define regCM3_CM_SHAPER_RAMA_START_CNTL_G_BASE_IDX 2
+#define regCM3_CM_SHAPER_RAMA_START_CNTL_R 0x1223
+#define regCM3_CM_SHAPER_RAMA_START_CNTL_R_BASE_IDX 2
+#define regCM3_CM_SHAPER_RAMA_END_CNTL_B 0x1224
+#define regCM3_CM_SHAPER_RAMA_END_CNTL_B_BASE_IDX 2
+#define regCM3_CM_SHAPER_RAMA_END_CNTL_G 0x1225
+#define regCM3_CM_SHAPER_RAMA_END_CNTL_G_BASE_IDX 2
+#define regCM3_CM_SHAPER_RAMA_END_CNTL_R 0x1226
+#define regCM3_CM_SHAPER_RAMA_END_CNTL_R_BASE_IDX 2
+#define regCM3_CM_SHAPER_RAMA_REGION_0_1 0x1227
+#define regCM3_CM_SHAPER_RAMA_REGION_0_1_BASE_IDX 2
+#define regCM3_CM_SHAPER_RAMA_REGION_2_3 0x1228
+#define regCM3_CM_SHAPER_RAMA_REGION_2_3_BASE_IDX 2
+#define regCM3_CM_SHAPER_RAMA_REGION_4_5 0x1229
+#define regCM3_CM_SHAPER_RAMA_REGION_4_5_BASE_IDX 2
+#define regCM3_CM_SHAPER_RAMA_REGION_6_7 0x122a
+#define regCM3_CM_SHAPER_RAMA_REGION_6_7_BASE_IDX 2
+#define regCM3_CM_SHAPER_RAMA_REGION_8_9 0x122b
+#define regCM3_CM_SHAPER_RAMA_REGION_8_9_BASE_IDX 2
+#define regCM3_CM_SHAPER_RAMA_REGION_10_11 0x122c
+#define regCM3_CM_SHAPER_RAMA_REGION_10_11_BASE_IDX 2
+#define regCM3_CM_SHAPER_RAMA_REGION_12_13 0x122d
+#define regCM3_CM_SHAPER_RAMA_REGION_12_13_BASE_IDX 2
+#define regCM3_CM_SHAPER_RAMA_REGION_14_15 0x122e
+#define regCM3_CM_SHAPER_RAMA_REGION_14_15_BASE_IDX 2
+#define regCM3_CM_SHAPER_RAMA_REGION_16_17 0x122f
+#define regCM3_CM_SHAPER_RAMA_REGION_16_17_BASE_IDX 2
+#define regCM3_CM_SHAPER_RAMA_REGION_18_19 0x1230
+#define regCM3_CM_SHAPER_RAMA_REGION_18_19_BASE_IDX 2
+#define regCM3_CM_SHAPER_RAMA_REGION_20_21 0x1231
+#define regCM3_CM_SHAPER_RAMA_REGION_20_21_BASE_IDX 2
+#define regCM3_CM_SHAPER_RAMA_REGION_22_23 0x1232
+#define regCM3_CM_SHAPER_RAMA_REGION_22_23_BASE_IDX 2
+#define regCM3_CM_SHAPER_RAMA_REGION_24_25 0x1233
+#define regCM3_CM_SHAPER_RAMA_REGION_24_25_BASE_IDX 2
+#define regCM3_CM_SHAPER_RAMA_REGION_26_27 0x1234
+#define regCM3_CM_SHAPER_RAMA_REGION_26_27_BASE_IDX 2
+#define regCM3_CM_SHAPER_RAMA_REGION_28_29 0x1235
+#define regCM3_CM_SHAPER_RAMA_REGION_28_29_BASE_IDX 2
+#define regCM3_CM_SHAPER_RAMA_REGION_30_31 0x1236
+#define regCM3_CM_SHAPER_RAMA_REGION_30_31_BASE_IDX 2
+#define regCM3_CM_SHAPER_RAMA_REGION_32_33 0x1237
+#define regCM3_CM_SHAPER_RAMA_REGION_32_33_BASE_IDX 2
+#define regCM3_CM_SHAPER_RAMB_START_CNTL_B 0x1238
+#define regCM3_CM_SHAPER_RAMB_START_CNTL_B_BASE_IDX 2
+#define regCM3_CM_SHAPER_RAMB_START_CNTL_G 0x1239
+#define regCM3_CM_SHAPER_RAMB_START_CNTL_G_BASE_IDX 2
+#define regCM3_CM_SHAPER_RAMB_START_CNTL_R 0x123a
+#define regCM3_CM_SHAPER_RAMB_START_CNTL_R_BASE_IDX 2
+#define regCM3_CM_SHAPER_RAMB_END_CNTL_B 0x123b
+#define regCM3_CM_SHAPER_RAMB_END_CNTL_B_BASE_IDX 2
+#define regCM3_CM_SHAPER_RAMB_END_CNTL_G 0x123c
+#define regCM3_CM_SHAPER_RAMB_END_CNTL_G_BASE_IDX 2
+#define regCM3_CM_SHAPER_RAMB_END_CNTL_R 0x123d
+#define regCM3_CM_SHAPER_RAMB_END_CNTL_R_BASE_IDX 2
+#define regCM3_CM_SHAPER_RAMB_REGION_0_1 0x123e
+#define regCM3_CM_SHAPER_RAMB_REGION_0_1_BASE_IDX 2
+#define regCM3_CM_SHAPER_RAMB_REGION_2_3 0x123f
+#define regCM3_CM_SHAPER_RAMB_REGION_2_3_BASE_IDX 2
+#define regCM3_CM_SHAPER_RAMB_REGION_4_5 0x1240
+#define regCM3_CM_SHAPER_RAMB_REGION_4_5_BASE_IDX 2
+#define regCM3_CM_SHAPER_RAMB_REGION_6_7 0x1241
+#define regCM3_CM_SHAPER_RAMB_REGION_6_7_BASE_IDX 2
+#define regCM3_CM_SHAPER_RAMB_REGION_8_9 0x1242
+#define regCM3_CM_SHAPER_RAMB_REGION_8_9_BASE_IDX 2
+#define regCM3_CM_SHAPER_RAMB_REGION_10_11 0x1243
+#define regCM3_CM_SHAPER_RAMB_REGION_10_11_BASE_IDX 2
+#define regCM3_CM_SHAPER_RAMB_REGION_12_13 0x1244
+#define regCM3_CM_SHAPER_RAMB_REGION_12_13_BASE_IDX 2
+#define regCM3_CM_SHAPER_RAMB_REGION_14_15 0x1245
+#define regCM3_CM_SHAPER_RAMB_REGION_14_15_BASE_IDX 2
+#define regCM3_CM_SHAPER_RAMB_REGION_16_17 0x1246
+#define regCM3_CM_SHAPER_RAMB_REGION_16_17_BASE_IDX 2
+#define regCM3_CM_SHAPER_RAMB_REGION_18_19 0x1247
+#define regCM3_CM_SHAPER_RAMB_REGION_18_19_BASE_IDX 2
+#define regCM3_CM_SHAPER_RAMB_REGION_20_21 0x1248
+#define regCM3_CM_SHAPER_RAMB_REGION_20_21_BASE_IDX 2
+#define regCM3_CM_SHAPER_RAMB_REGION_22_23 0x1249
+#define regCM3_CM_SHAPER_RAMB_REGION_22_23_BASE_IDX 2
+#define regCM3_CM_SHAPER_RAMB_REGION_24_25 0x124a
+#define regCM3_CM_SHAPER_RAMB_REGION_24_25_BASE_IDX 2
+#define regCM3_CM_SHAPER_RAMB_REGION_26_27 0x124b
+#define regCM3_CM_SHAPER_RAMB_REGION_26_27_BASE_IDX 2
+#define regCM3_CM_SHAPER_RAMB_REGION_28_29 0x124c
+#define regCM3_CM_SHAPER_RAMB_REGION_28_29_BASE_IDX 2
+#define regCM3_CM_SHAPER_RAMB_REGION_30_31 0x124d
+#define regCM3_CM_SHAPER_RAMB_REGION_30_31_BASE_IDX 2
+#define regCM3_CM_SHAPER_RAMB_REGION_32_33 0x124e
+#define regCM3_CM_SHAPER_RAMB_REGION_32_33_BASE_IDX 2
+#define regCM3_CM_MEM_PWR_CTRL2 0x124f
+#define regCM3_CM_MEM_PWR_CTRL2_BASE_IDX 2
+#define regCM3_CM_MEM_PWR_STATUS2 0x1250
+#define regCM3_CM_MEM_PWR_STATUS2_BASE_IDX 2
+#define regCM3_CM_3DLUT_MODE 0x1251
+#define regCM3_CM_3DLUT_MODE_BASE_IDX 2
+#define regCM3_CM_3DLUT_INDEX 0x1252
+#define regCM3_CM_3DLUT_INDEX_BASE_IDX 2
+#define regCM3_CM_3DLUT_DATA 0x1253
+#define regCM3_CM_3DLUT_DATA_BASE_IDX 2
+#define regCM3_CM_3DLUT_DATA_30BIT 0x1254
+#define regCM3_CM_3DLUT_DATA_30BIT_BASE_IDX 2
+#define regCM3_CM_3DLUT_READ_WRITE_CONTROL 0x1255
+#define regCM3_CM_3DLUT_READ_WRITE_CONTROL_BASE_IDX 2
+#define regCM3_CM_3DLUT_OUT_NORM_FACTOR 0x1256
+#define regCM3_CM_3DLUT_OUT_NORM_FACTOR_BASE_IDX 2
+#define regCM3_CM_3DLUT_OUT_OFFSET_R 0x1257
+#define regCM3_CM_3DLUT_OUT_OFFSET_R_BASE_IDX 2
+#define regCM3_CM_3DLUT_OUT_OFFSET_G 0x1258
+#define regCM3_CM_3DLUT_OUT_OFFSET_G_BASE_IDX 2
+#define regCM3_CM_3DLUT_OUT_OFFSET_B 0x1259
+#define regCM3_CM_3DLUT_OUT_OFFSET_B_BASE_IDX 2
+#define regCM3_CM_TEST_DEBUG_INDEX 0x125a
+#define regCM3_CM_TEST_DEBUG_INDEX_BASE_IDX 2
+#define regCM3_CM_TEST_DEBUG_DATA 0x125b
+#define regCM3_CM_TEST_DEBUG_DATA_BASE_IDX 2
+
+
+// addressBlock: dce_dc_dpp3_dispdec_dpp_top_dispdec
+// base address: 0x1104
+#define regDPP_TOP3_DPP_CONTROL 0x1106
+#define regDPP_TOP3_DPP_CONTROL_BASE_IDX 2
+#define regDPP_TOP3_DPP_SOFT_RESET 0x1107
+#define regDPP_TOP3_DPP_SOFT_RESET_BASE_IDX 2
+#define regDPP_TOP3_DPP_CRC_VAL_R_G 0x1108
+#define regDPP_TOP3_DPP_CRC_VAL_R_G_BASE_IDX 2
+#define regDPP_TOP3_DPP_CRC_VAL_B_A 0x1109
+#define regDPP_TOP3_DPP_CRC_VAL_B_A_BASE_IDX 2
+#define regDPP_TOP3_DPP_CRC_CTRL 0x110a
+#define regDPP_TOP3_DPP_CRC_CTRL_BASE_IDX 2
+#define regDPP_TOP3_HOST_READ_CONTROL 0x110b
+#define regDPP_TOP3_HOST_READ_CONTROL_BASE_IDX 2
+
+
+// addressBlock: dce_dc_dpp3_dispdec_dpp_dcperfmon_dc_perfmon_dispdec
+// base address: 0x4994
+#define regDC_PERFMON14_PERFCOUNTER_CNTL 0x1265
+#define regDC_PERFMON14_PERFCOUNTER_CNTL_BASE_IDX 2
+#define regDC_PERFMON14_PERFCOUNTER_CNTL2 0x1266
+#define regDC_PERFMON14_PERFCOUNTER_CNTL2_BASE_IDX 2
+#define regDC_PERFMON14_PERFCOUNTER_STATE 0x1267
+#define regDC_PERFMON14_PERFCOUNTER_STATE_BASE_IDX 2
+#define regDC_PERFMON14_PERFMON_CNTL 0x1268
+#define regDC_PERFMON14_PERFMON_CNTL_BASE_IDX 2
+#define regDC_PERFMON14_PERFMON_CNTL2 0x1269
+#define regDC_PERFMON14_PERFMON_CNTL2_BASE_IDX 2
+#define regDC_PERFMON14_PERFMON_CVALUE_INT_MISC 0x126a
+#define regDC_PERFMON14_PERFMON_CVALUE_INT_MISC_BASE_IDX 2
+#define regDC_PERFMON14_PERFMON_CVALUE_LOW 0x126b
+#define regDC_PERFMON14_PERFMON_CVALUE_LOW_BASE_IDX 2
+#define regDC_PERFMON14_PERFMON_HI 0x126c
+#define regDC_PERFMON14_PERFMON_HI_BASE_IDX 2
+#define regDC_PERFMON14_PERFMON_LOW 0x126d
+#define regDC_PERFMON14_PERFMON_LOW_BASE_IDX 2
+
+
+// addressBlock: dce_dc_mpc_mpcc0_dispdec
+// base address: 0x0
+#define regMPCC0_MPCC_TOP_SEL 0x0000
+#define regMPCC0_MPCC_TOP_SEL_BASE_IDX 3
+#define regMPCC0_MPCC_BOT_SEL 0x0001
+#define regMPCC0_MPCC_BOT_SEL_BASE_IDX 3
+#define regMPCC0_MPCC_OPP_ID 0x0002
+#define regMPCC0_MPCC_OPP_ID_BASE_IDX 3
+#define regMPCC0_MPCC_CONTROL 0x0003
+#define regMPCC0_MPCC_CONTROL_BASE_IDX 3
+#define regMPCC0_MPCC_SM_CONTROL 0x0004
+#define regMPCC0_MPCC_SM_CONTROL_BASE_IDX 3
+#define regMPCC0_MPCC_UPDATE_LOCK_SEL 0x0005
+#define regMPCC0_MPCC_UPDATE_LOCK_SEL_BASE_IDX 3
+#define regMPCC0_MPCC_TOP_GAIN 0x0006
+#define regMPCC0_MPCC_TOP_GAIN_BASE_IDX 3
+#define regMPCC0_MPCC_BOT_GAIN_INSIDE 0x0007
+#define regMPCC0_MPCC_BOT_GAIN_INSIDE_BASE_IDX 3
+#define regMPCC0_MPCC_BOT_GAIN_OUTSIDE 0x0008
+#define regMPCC0_MPCC_BOT_GAIN_OUTSIDE_BASE_IDX 3
+#define regMPCC0_MPCC_BG_R_CR 0x0009
+#define regMPCC0_MPCC_BG_R_CR_BASE_IDX 3
+#define regMPCC0_MPCC_BG_G_Y 0x000a
+#define regMPCC0_MPCC_BG_G_Y_BASE_IDX 3
+#define regMPCC0_MPCC_BG_B_CB 0x000b
+#define regMPCC0_MPCC_BG_B_CB_BASE_IDX 3
+#define regMPCC0_MPCC_MEM_PWR_CTRL 0x000c
+#define regMPCC0_MPCC_MEM_PWR_CTRL_BASE_IDX 3
+#define regMPCC0_MPCC_STATUS 0x000d
+#define regMPCC0_MPCC_STATUS_BASE_IDX 3
+
+
+// addressBlock: dce_dc_mpc_mpcc1_dispdec
+// base address: 0x80
+#define regMPCC1_MPCC_TOP_SEL 0x0020
+#define regMPCC1_MPCC_TOP_SEL_BASE_IDX 3
+#define regMPCC1_MPCC_BOT_SEL 0x0021
+#define regMPCC1_MPCC_BOT_SEL_BASE_IDX 3
+#define regMPCC1_MPCC_OPP_ID 0x0022
+#define regMPCC1_MPCC_OPP_ID_BASE_IDX 3
+#define regMPCC1_MPCC_CONTROL 0x0023
+#define regMPCC1_MPCC_CONTROL_BASE_IDX 3
+#define regMPCC1_MPCC_SM_CONTROL 0x0024
+#define regMPCC1_MPCC_SM_CONTROL_BASE_IDX 3
+#define regMPCC1_MPCC_UPDATE_LOCK_SEL 0x0025
+#define regMPCC1_MPCC_UPDATE_LOCK_SEL_BASE_IDX 3
+#define regMPCC1_MPCC_TOP_GAIN 0x0026
+#define regMPCC1_MPCC_TOP_GAIN_BASE_IDX 3
+#define regMPCC1_MPCC_BOT_GAIN_INSIDE 0x0027
+#define regMPCC1_MPCC_BOT_GAIN_INSIDE_BASE_IDX 3
+#define regMPCC1_MPCC_BOT_GAIN_OUTSIDE 0x0028
+#define regMPCC1_MPCC_BOT_GAIN_OUTSIDE_BASE_IDX 3
+#define regMPCC1_MPCC_BG_R_CR 0x0029
+#define regMPCC1_MPCC_BG_R_CR_BASE_IDX 3
+#define regMPCC1_MPCC_BG_G_Y 0x002a
+#define regMPCC1_MPCC_BG_G_Y_BASE_IDX 3
+#define regMPCC1_MPCC_BG_B_CB 0x002b
+#define regMPCC1_MPCC_BG_B_CB_BASE_IDX 3
+#define regMPCC1_MPCC_MEM_PWR_CTRL 0x002c
+#define regMPCC1_MPCC_MEM_PWR_CTRL_BASE_IDX 3
+#define regMPCC1_MPCC_STATUS 0x002d
+#define regMPCC1_MPCC_STATUS_BASE_IDX 3
+
+
+// addressBlock: dce_dc_mpc_mpcc2_dispdec
+// base address: 0x100
+#define regMPCC2_MPCC_TOP_SEL 0x0040
+#define regMPCC2_MPCC_TOP_SEL_BASE_IDX 3
+#define regMPCC2_MPCC_BOT_SEL 0x0041
+#define regMPCC2_MPCC_BOT_SEL_BASE_IDX 3
+#define regMPCC2_MPCC_OPP_ID 0x0042
+#define regMPCC2_MPCC_OPP_ID_BASE_IDX 3
+#define regMPCC2_MPCC_CONTROL 0x0043
+#define regMPCC2_MPCC_CONTROL_BASE_IDX 3
+#define regMPCC2_MPCC_SM_CONTROL 0x0044
+#define regMPCC2_MPCC_SM_CONTROL_BASE_IDX 3
+#define regMPCC2_MPCC_UPDATE_LOCK_SEL 0x0045
+#define regMPCC2_MPCC_UPDATE_LOCK_SEL_BASE_IDX 3
+#define regMPCC2_MPCC_TOP_GAIN 0x0046
+#define regMPCC2_MPCC_TOP_GAIN_BASE_IDX 3
+#define regMPCC2_MPCC_BOT_GAIN_INSIDE 0x0047
+#define regMPCC2_MPCC_BOT_GAIN_INSIDE_BASE_IDX 3
+#define regMPCC2_MPCC_BOT_GAIN_OUTSIDE 0x0048
+#define regMPCC2_MPCC_BOT_GAIN_OUTSIDE_BASE_IDX 3
+#define regMPCC2_MPCC_BG_R_CR 0x0049
+#define regMPCC2_MPCC_BG_R_CR_BASE_IDX 3
+#define regMPCC2_MPCC_BG_G_Y 0x004a
+#define regMPCC2_MPCC_BG_G_Y_BASE_IDX 3
+#define regMPCC2_MPCC_BG_B_CB 0x004b
+#define regMPCC2_MPCC_BG_B_CB_BASE_IDX 3
+#define regMPCC2_MPCC_MEM_PWR_CTRL 0x004c
+#define regMPCC2_MPCC_MEM_PWR_CTRL_BASE_IDX 3
+#define regMPCC2_MPCC_STATUS 0x004d
+#define regMPCC2_MPCC_STATUS_BASE_IDX 3
+
+
+// addressBlock: dce_dc_mpc_mpcc3_dispdec
+// base address: 0x180
+#define regMPCC3_MPCC_TOP_SEL 0x0060
+#define regMPCC3_MPCC_TOP_SEL_BASE_IDX 3
+#define regMPCC3_MPCC_BOT_SEL 0x0061
+#define regMPCC3_MPCC_BOT_SEL_BASE_IDX 3
+#define regMPCC3_MPCC_OPP_ID 0x0062
+#define regMPCC3_MPCC_OPP_ID_BASE_IDX 3
+#define regMPCC3_MPCC_CONTROL 0x0063
+#define regMPCC3_MPCC_CONTROL_BASE_IDX 3
+#define regMPCC3_MPCC_SM_CONTROL 0x0064
+#define regMPCC3_MPCC_SM_CONTROL_BASE_IDX 3
+#define regMPCC3_MPCC_UPDATE_LOCK_SEL 0x0065
+#define regMPCC3_MPCC_UPDATE_LOCK_SEL_BASE_IDX 3
+#define regMPCC3_MPCC_TOP_GAIN 0x0066
+#define regMPCC3_MPCC_TOP_GAIN_BASE_IDX 3
+#define regMPCC3_MPCC_BOT_GAIN_INSIDE 0x0067
+#define regMPCC3_MPCC_BOT_GAIN_INSIDE_BASE_IDX 3
+#define regMPCC3_MPCC_BOT_GAIN_OUTSIDE 0x0068
+#define regMPCC3_MPCC_BOT_GAIN_OUTSIDE_BASE_IDX 3
+#define regMPCC3_MPCC_BG_R_CR 0x0069
+#define regMPCC3_MPCC_BG_R_CR_BASE_IDX 3
+#define regMPCC3_MPCC_BG_G_Y 0x006a
+#define regMPCC3_MPCC_BG_G_Y_BASE_IDX 3
+#define regMPCC3_MPCC_BG_B_CB 0x006b
+#define regMPCC3_MPCC_BG_B_CB_BASE_IDX 3
+#define regMPCC3_MPCC_MEM_PWR_CTRL 0x006c
+#define regMPCC3_MPCC_MEM_PWR_CTRL_BASE_IDX 3
+#define regMPCC3_MPCC_STATUS 0x006d
+#define regMPCC3_MPCC_STATUS_BASE_IDX 3
+
+
+// addressBlock: dce_dc_mpc_mpc_cfg_dispdec
+// base address: 0x0
+#define regMPC_CLOCK_CONTROL 0x0500
+#define regMPC_CLOCK_CONTROL_BASE_IDX 3
+#define regMPC_SOFT_RESET 0x0501
+#define regMPC_SOFT_RESET_BASE_IDX 3
+#define regMPC_CRC_CTRL 0x0502
+#define regMPC_CRC_CTRL_BASE_IDX 3
+#define regMPC_CRC_SEL_CONTROL 0x0503
+#define regMPC_CRC_SEL_CONTROL_BASE_IDX 3
+#define regMPC_CRC_RESULT_AR 0x0504
+#define regMPC_CRC_RESULT_AR_BASE_IDX 3
+#define regMPC_CRC_RESULT_GB 0x0505
+#define regMPC_CRC_RESULT_GB_BASE_IDX 3
+#define regMPC_CRC_RESULT_C 0x0506
+#define regMPC_CRC_RESULT_C_BASE_IDX 3
+#define regMPC_PERFMON_EVENT_CTRL 0x0509
+#define regMPC_PERFMON_EVENT_CTRL_BASE_IDX 3
+#define regMPC_BYPASS_BG_AR 0x050a
+#define regMPC_BYPASS_BG_AR_BASE_IDX 3
+#define regMPC_BYPASS_BG_GB 0x050b
+#define regMPC_BYPASS_BG_GB_BASE_IDX 3
+#define regMPC_HOST_READ_CONTROL 0x050c
+#define regMPC_HOST_READ_CONTROL_BASE_IDX 3
+#define regMPC_DPP_PENDING_STATUS 0x050d
+#define regMPC_DPP_PENDING_STATUS_BASE_IDX 3
+#define regMPC_PENDING_STATUS_MISC 0x050e
+#define regMPC_PENDING_STATUS_MISC_BASE_IDX 3
+#define regADR_CFG_CUR_VUPDATE_LOCK_SET0 0x050f
+#define regADR_CFG_CUR_VUPDATE_LOCK_SET0_BASE_IDX 3
+#define regADR_CFG_VUPDATE_LOCK_SET0 0x0510
+#define regADR_CFG_VUPDATE_LOCK_SET0_BASE_IDX 3
+#define regADR_VUPDATE_LOCK_SET0 0x0511
+#define regADR_VUPDATE_LOCK_SET0_BASE_IDX 3
+#define regCFG_VUPDATE_LOCK_SET0 0x0512
+#define regCFG_VUPDATE_LOCK_SET0_BASE_IDX 3
+#define regCUR_VUPDATE_LOCK_SET0 0x0513
+#define regCUR_VUPDATE_LOCK_SET0_BASE_IDX 3
+#define regADR_CFG_CUR_VUPDATE_LOCK_SET1 0x0514
+#define regADR_CFG_CUR_VUPDATE_LOCK_SET1_BASE_IDX 3
+#define regADR_CFG_VUPDATE_LOCK_SET1 0x0515
+#define regADR_CFG_VUPDATE_LOCK_SET1_BASE_IDX 3
+#define regADR_VUPDATE_LOCK_SET1 0x0516
+#define regADR_VUPDATE_LOCK_SET1_BASE_IDX 3
+#define regCFG_VUPDATE_LOCK_SET1 0x0517
+#define regCFG_VUPDATE_LOCK_SET1_BASE_IDX 3
+#define regCUR_VUPDATE_LOCK_SET1 0x0518
+#define regCUR_VUPDATE_LOCK_SET1_BASE_IDX 3
+#define regADR_CFG_CUR_VUPDATE_LOCK_SET2 0x0519
+#define regADR_CFG_CUR_VUPDATE_LOCK_SET2_BASE_IDX 3
+#define regADR_CFG_VUPDATE_LOCK_SET2 0x051a
+#define regADR_CFG_VUPDATE_LOCK_SET2_BASE_IDX 3
+#define regADR_VUPDATE_LOCK_SET2 0x051b
+#define regADR_VUPDATE_LOCK_SET2_BASE_IDX 3
+#define regCFG_VUPDATE_LOCK_SET2 0x051c
+#define regCFG_VUPDATE_LOCK_SET2_BASE_IDX 3
+#define regCUR_VUPDATE_LOCK_SET2 0x051d
+#define regCUR_VUPDATE_LOCK_SET2_BASE_IDX 3
+#define regADR_CFG_CUR_VUPDATE_LOCK_SET3 0x051e
+#define regADR_CFG_CUR_VUPDATE_LOCK_SET3_BASE_IDX 3
+#define regADR_CFG_VUPDATE_LOCK_SET3 0x051f
+#define regADR_CFG_VUPDATE_LOCK_SET3_BASE_IDX 3
+#define regADR_VUPDATE_LOCK_SET3 0x0520
+#define regADR_VUPDATE_LOCK_SET3_BASE_IDX 3
+#define regCFG_VUPDATE_LOCK_SET3 0x0521
+#define regCFG_VUPDATE_LOCK_SET3_BASE_IDX 3
+#define regCUR_VUPDATE_LOCK_SET3 0x0522
+#define regCUR_VUPDATE_LOCK_SET3_BASE_IDX 3
+#define regMPC_DWB0_MUX 0x055c
+#define regMPC_DWB0_MUX_BASE_IDX 3
+
+
+// addressBlock: dce_dc_mpc_mpc_dcperfmon_dc_perfmon_dispdec
+// base address: 0x1901c
+#define regDC_PERFMON15_PERFCOUNTER_CNTL 0x08c7
+#define regDC_PERFMON15_PERFCOUNTER_CNTL_BASE_IDX 3
+#define regDC_PERFMON15_PERFCOUNTER_CNTL2 0x08c8
+#define regDC_PERFMON15_PERFCOUNTER_CNTL2_BASE_IDX 3
+#define regDC_PERFMON15_PERFCOUNTER_STATE 0x08c9
+#define regDC_PERFMON15_PERFCOUNTER_STATE_BASE_IDX 3
+#define regDC_PERFMON15_PERFMON_CNTL 0x08ca
+#define regDC_PERFMON15_PERFMON_CNTL_BASE_IDX 3
+#define regDC_PERFMON15_PERFMON_CNTL2 0x08cb
+#define regDC_PERFMON15_PERFMON_CNTL2_BASE_IDX 3
+#define regDC_PERFMON15_PERFMON_CVALUE_INT_MISC 0x08cc
+#define regDC_PERFMON15_PERFMON_CVALUE_INT_MISC_BASE_IDX 3
+#define regDC_PERFMON15_PERFMON_CVALUE_LOW 0x08cd
+#define regDC_PERFMON15_PERFMON_CVALUE_LOW_BASE_IDX 3
+#define regDC_PERFMON15_PERFMON_HI 0x08ce
+#define regDC_PERFMON15_PERFMON_HI_BASE_IDX 3
+#define regDC_PERFMON15_PERFMON_LOW 0x08cf
+#define regDC_PERFMON15_PERFMON_LOW_BASE_IDX 3
+
+
+// addressBlock: dce_dc_mpc_mpcc_ogam0_dispdec
+// base address: 0x0
+#define regMPCC_OGAM0_MPCC_OGAM_CONTROL 0x0100
+#define regMPCC_OGAM0_MPCC_OGAM_CONTROL_BASE_IDX 3
+#define regMPCC_OGAM0_MPCC_OGAM_LUT_INDEX 0x0101
+#define regMPCC_OGAM0_MPCC_OGAM_LUT_INDEX_BASE_IDX 3
+#define regMPCC_OGAM0_MPCC_OGAM_LUT_DATA 0x0102
+#define regMPCC_OGAM0_MPCC_OGAM_LUT_DATA_BASE_IDX 3
+#define regMPCC_OGAM0_MPCC_OGAM_LUT_CONTROL 0x0103
+#define regMPCC_OGAM0_MPCC_OGAM_LUT_CONTROL_BASE_IDX 3
+#define regMPCC_OGAM0_MPCC_OGAM_RAMA_START_CNTL_B 0x0104
+#define regMPCC_OGAM0_MPCC_OGAM_RAMA_START_CNTL_B_BASE_IDX 3
+#define regMPCC_OGAM0_MPCC_OGAM_RAMA_START_CNTL_G 0x0105
+#define regMPCC_OGAM0_MPCC_OGAM_RAMA_START_CNTL_G_BASE_IDX 3
+#define regMPCC_OGAM0_MPCC_OGAM_RAMA_START_CNTL_R 0x0106
+#define regMPCC_OGAM0_MPCC_OGAM_RAMA_START_CNTL_R_BASE_IDX 3
+#define regMPCC_OGAM0_MPCC_OGAM_RAMA_START_SLOPE_CNTL_B 0x0107
+#define regMPCC_OGAM0_MPCC_OGAM_RAMA_START_SLOPE_CNTL_B_BASE_IDX 3
+#define regMPCC_OGAM0_MPCC_OGAM_RAMA_START_SLOPE_CNTL_G 0x0108
+#define regMPCC_OGAM0_MPCC_OGAM_RAMA_START_SLOPE_CNTL_G_BASE_IDX 3
+#define regMPCC_OGAM0_MPCC_OGAM_RAMA_START_SLOPE_CNTL_R 0x0109
+#define regMPCC_OGAM0_MPCC_OGAM_RAMA_START_SLOPE_CNTL_R_BASE_IDX 3
+#define regMPCC_OGAM0_MPCC_OGAM_RAMA_START_BASE_CNTL_B 0x010a
+#define regMPCC_OGAM0_MPCC_OGAM_RAMA_START_BASE_CNTL_B_BASE_IDX 3
+#define regMPCC_OGAM0_MPCC_OGAM_RAMA_START_BASE_CNTL_G 0x010b
+#define regMPCC_OGAM0_MPCC_OGAM_RAMA_START_BASE_CNTL_G_BASE_IDX 3
+#define regMPCC_OGAM0_MPCC_OGAM_RAMA_START_BASE_CNTL_R 0x010c
+#define regMPCC_OGAM0_MPCC_OGAM_RAMA_START_BASE_CNTL_R_BASE_IDX 3
+#define regMPCC_OGAM0_MPCC_OGAM_RAMA_END_CNTL1_B 0x010d
+#define regMPCC_OGAM0_MPCC_OGAM_RAMA_END_CNTL1_B_BASE_IDX 3
+#define regMPCC_OGAM0_MPCC_OGAM_RAMA_END_CNTL2_B 0x010e
+#define regMPCC_OGAM0_MPCC_OGAM_RAMA_END_CNTL2_B_BASE_IDX 3
+#define regMPCC_OGAM0_MPCC_OGAM_RAMA_END_CNTL1_G 0x010f
+#define regMPCC_OGAM0_MPCC_OGAM_RAMA_END_CNTL1_G_BASE_IDX 3
+#define regMPCC_OGAM0_MPCC_OGAM_RAMA_END_CNTL2_G 0x0110
+#define regMPCC_OGAM0_MPCC_OGAM_RAMA_END_CNTL2_G_BASE_IDX 3
+#define regMPCC_OGAM0_MPCC_OGAM_RAMA_END_CNTL1_R 0x0111
+#define regMPCC_OGAM0_MPCC_OGAM_RAMA_END_CNTL1_R_BASE_IDX 3
+#define regMPCC_OGAM0_MPCC_OGAM_RAMA_END_CNTL2_R 0x0112
+#define regMPCC_OGAM0_MPCC_OGAM_RAMA_END_CNTL2_R_BASE_IDX 3
+#define regMPCC_OGAM0_MPCC_OGAM_RAMA_OFFSET_B 0x0113
+#define regMPCC_OGAM0_MPCC_OGAM_RAMA_OFFSET_B_BASE_IDX 3
+#define regMPCC_OGAM0_MPCC_OGAM_RAMA_OFFSET_G 0x0114
+#define regMPCC_OGAM0_MPCC_OGAM_RAMA_OFFSET_G_BASE_IDX 3
+#define regMPCC_OGAM0_MPCC_OGAM_RAMA_OFFSET_R 0x0115
+#define regMPCC_OGAM0_MPCC_OGAM_RAMA_OFFSET_R_BASE_IDX 3
+#define regMPCC_OGAM0_MPCC_OGAM_RAMA_REGION_0_1 0x0116
+#define regMPCC_OGAM0_MPCC_OGAM_RAMA_REGION_0_1_BASE_IDX 3
+#define regMPCC_OGAM0_MPCC_OGAM_RAMA_REGION_2_3 0x0117
+#define regMPCC_OGAM0_MPCC_OGAM_RAMA_REGION_2_3_BASE_IDX 3
+#define regMPCC_OGAM0_MPCC_OGAM_RAMA_REGION_4_5 0x0118
+#define regMPCC_OGAM0_MPCC_OGAM_RAMA_REGION_4_5_BASE_IDX 3
+#define regMPCC_OGAM0_MPCC_OGAM_RAMA_REGION_6_7 0x0119
+#define regMPCC_OGAM0_MPCC_OGAM_RAMA_REGION_6_7_BASE_IDX 3
+#define regMPCC_OGAM0_MPCC_OGAM_RAMA_REGION_8_9 0x011a
+#define regMPCC_OGAM0_MPCC_OGAM_RAMA_REGION_8_9_BASE_IDX 3
+#define regMPCC_OGAM0_MPCC_OGAM_RAMA_REGION_10_11 0x011b
+#define regMPCC_OGAM0_MPCC_OGAM_RAMA_REGION_10_11_BASE_IDX 3
+#define regMPCC_OGAM0_MPCC_OGAM_RAMA_REGION_12_13 0x011c
+#define regMPCC_OGAM0_MPCC_OGAM_RAMA_REGION_12_13_BASE_IDX 3
+#define regMPCC_OGAM0_MPCC_OGAM_RAMA_REGION_14_15 0x011d
+#define regMPCC_OGAM0_MPCC_OGAM_RAMA_REGION_14_15_BASE_IDX 3
+#define regMPCC_OGAM0_MPCC_OGAM_RAMA_REGION_16_17 0x011e
+#define regMPCC_OGAM0_MPCC_OGAM_RAMA_REGION_16_17_BASE_IDX 3
+#define regMPCC_OGAM0_MPCC_OGAM_RAMA_REGION_18_19 0x011f
+#define regMPCC_OGAM0_MPCC_OGAM_RAMA_REGION_18_19_BASE_IDX 3
+#define regMPCC_OGAM0_MPCC_OGAM_RAMA_REGION_20_21 0x0120
+#define regMPCC_OGAM0_MPCC_OGAM_RAMA_REGION_20_21_BASE_IDX 3
+#define regMPCC_OGAM0_MPCC_OGAM_RAMA_REGION_22_23 0x0121
+#define regMPCC_OGAM0_MPCC_OGAM_RAMA_REGION_22_23_BASE_IDX 3
+#define regMPCC_OGAM0_MPCC_OGAM_RAMA_REGION_24_25 0x0122
+#define regMPCC_OGAM0_MPCC_OGAM_RAMA_REGION_24_25_BASE_IDX 3
+#define regMPCC_OGAM0_MPCC_OGAM_RAMA_REGION_26_27 0x0123
+#define regMPCC_OGAM0_MPCC_OGAM_RAMA_REGION_26_27_BASE_IDX 3
+#define regMPCC_OGAM0_MPCC_OGAM_RAMA_REGION_28_29 0x0124
+#define regMPCC_OGAM0_MPCC_OGAM_RAMA_REGION_28_29_BASE_IDX 3
+#define regMPCC_OGAM0_MPCC_OGAM_RAMA_REGION_30_31 0x0125
+#define regMPCC_OGAM0_MPCC_OGAM_RAMA_REGION_30_31_BASE_IDX 3
+#define regMPCC_OGAM0_MPCC_OGAM_RAMA_REGION_32_33 0x0126
+#define regMPCC_OGAM0_MPCC_OGAM_RAMA_REGION_32_33_BASE_IDX 3
+#define regMPCC_OGAM0_MPCC_OGAM_RAMB_START_CNTL_B 0x0127
+#define regMPCC_OGAM0_MPCC_OGAM_RAMB_START_CNTL_B_BASE_IDX 3
+#define regMPCC_OGAM0_MPCC_OGAM_RAMB_START_CNTL_G 0x0128
+#define regMPCC_OGAM0_MPCC_OGAM_RAMB_START_CNTL_G_BASE_IDX 3
+#define regMPCC_OGAM0_MPCC_OGAM_RAMB_START_CNTL_R 0x0129
+#define regMPCC_OGAM0_MPCC_OGAM_RAMB_START_CNTL_R_BASE_IDX 3
+#define regMPCC_OGAM0_MPCC_OGAM_RAMB_START_SLOPE_CNTL_B 0x012a
+#define regMPCC_OGAM0_MPCC_OGAM_RAMB_START_SLOPE_CNTL_B_BASE_IDX 3
+#define regMPCC_OGAM0_MPCC_OGAM_RAMB_START_SLOPE_CNTL_G 0x012b
+#define regMPCC_OGAM0_MPCC_OGAM_RAMB_START_SLOPE_CNTL_G_BASE_IDX 3
+#define regMPCC_OGAM0_MPCC_OGAM_RAMB_START_SLOPE_CNTL_R 0x012c
+#define regMPCC_OGAM0_MPCC_OGAM_RAMB_START_SLOPE_CNTL_R_BASE_IDX 3
+#define regMPCC_OGAM0_MPCC_OGAM_RAMB_START_BASE_CNTL_B 0x012d
+#define regMPCC_OGAM0_MPCC_OGAM_RAMB_START_BASE_CNTL_B_BASE_IDX 3
+#define regMPCC_OGAM0_MPCC_OGAM_RAMB_START_BASE_CNTL_G 0x012e
+#define regMPCC_OGAM0_MPCC_OGAM_RAMB_START_BASE_CNTL_G_BASE_IDX 3
+#define regMPCC_OGAM0_MPCC_OGAM_RAMB_START_BASE_CNTL_R 0x012f
+#define regMPCC_OGAM0_MPCC_OGAM_RAMB_START_BASE_CNTL_R_BASE_IDX 3
+#define regMPCC_OGAM0_MPCC_OGAM_RAMB_END_CNTL1_B 0x0130
+#define regMPCC_OGAM0_MPCC_OGAM_RAMB_END_CNTL1_B_BASE_IDX 3
+#define regMPCC_OGAM0_MPCC_OGAM_RAMB_END_CNTL2_B 0x0131
+#define regMPCC_OGAM0_MPCC_OGAM_RAMB_END_CNTL2_B_BASE_IDX 3
+#define regMPCC_OGAM0_MPCC_OGAM_RAMB_END_CNTL1_G 0x0132
+#define regMPCC_OGAM0_MPCC_OGAM_RAMB_END_CNTL1_G_BASE_IDX 3
+#define regMPCC_OGAM0_MPCC_OGAM_RAMB_END_CNTL2_G 0x0133
+#define regMPCC_OGAM0_MPCC_OGAM_RAMB_END_CNTL2_G_BASE_IDX 3
+#define regMPCC_OGAM0_MPCC_OGAM_RAMB_END_CNTL1_R 0x0134
+#define regMPCC_OGAM0_MPCC_OGAM_RAMB_END_CNTL1_R_BASE_IDX 3
+#define regMPCC_OGAM0_MPCC_OGAM_RAMB_END_CNTL2_R 0x0135
+#define regMPCC_OGAM0_MPCC_OGAM_RAMB_END_CNTL2_R_BASE_IDX 3
+#define regMPCC_OGAM0_MPCC_OGAM_RAMB_OFFSET_B 0x0136
+#define regMPCC_OGAM0_MPCC_OGAM_RAMB_OFFSET_B_BASE_IDX 3
+#define regMPCC_OGAM0_MPCC_OGAM_RAMB_OFFSET_G 0x0137
+#define regMPCC_OGAM0_MPCC_OGAM_RAMB_OFFSET_G_BASE_IDX 3
+#define regMPCC_OGAM0_MPCC_OGAM_RAMB_OFFSET_R 0x0138
+#define regMPCC_OGAM0_MPCC_OGAM_RAMB_OFFSET_R_BASE_IDX 3
+#define regMPCC_OGAM0_MPCC_OGAM_RAMB_REGION_0_1 0x0139
+#define regMPCC_OGAM0_MPCC_OGAM_RAMB_REGION_0_1_BASE_IDX 3
+#define regMPCC_OGAM0_MPCC_OGAM_RAMB_REGION_2_3 0x013a
+#define regMPCC_OGAM0_MPCC_OGAM_RAMB_REGION_2_3_BASE_IDX 3
+#define regMPCC_OGAM0_MPCC_OGAM_RAMB_REGION_4_5 0x013b
+#define regMPCC_OGAM0_MPCC_OGAM_RAMB_REGION_4_5_BASE_IDX 3
+#define regMPCC_OGAM0_MPCC_OGAM_RAMB_REGION_6_7 0x013c
+#define regMPCC_OGAM0_MPCC_OGAM_RAMB_REGION_6_7_BASE_IDX 3
+#define regMPCC_OGAM0_MPCC_OGAM_RAMB_REGION_8_9 0x013d
+#define regMPCC_OGAM0_MPCC_OGAM_RAMB_REGION_8_9_BASE_IDX 3
+#define regMPCC_OGAM0_MPCC_OGAM_RAMB_REGION_10_11 0x013e
+#define regMPCC_OGAM0_MPCC_OGAM_RAMB_REGION_10_11_BASE_IDX 3
+#define regMPCC_OGAM0_MPCC_OGAM_RAMB_REGION_12_13 0x013f
+#define regMPCC_OGAM0_MPCC_OGAM_RAMB_REGION_12_13_BASE_IDX 3
+#define regMPCC_OGAM0_MPCC_OGAM_RAMB_REGION_14_15 0x0140
+#define regMPCC_OGAM0_MPCC_OGAM_RAMB_REGION_14_15_BASE_IDX 3
+#define regMPCC_OGAM0_MPCC_OGAM_RAMB_REGION_16_17 0x0141
+#define regMPCC_OGAM0_MPCC_OGAM_RAMB_REGION_16_17_BASE_IDX 3
+#define regMPCC_OGAM0_MPCC_OGAM_RAMB_REGION_18_19 0x0142
+#define regMPCC_OGAM0_MPCC_OGAM_RAMB_REGION_18_19_BASE_IDX 3
+#define regMPCC_OGAM0_MPCC_OGAM_RAMB_REGION_20_21 0x0143
+#define regMPCC_OGAM0_MPCC_OGAM_RAMB_REGION_20_21_BASE_IDX 3
+#define regMPCC_OGAM0_MPCC_OGAM_RAMB_REGION_22_23 0x0144
+#define regMPCC_OGAM0_MPCC_OGAM_RAMB_REGION_22_23_BASE_IDX 3
+#define regMPCC_OGAM0_MPCC_OGAM_RAMB_REGION_24_25 0x0145
+#define regMPCC_OGAM0_MPCC_OGAM_RAMB_REGION_24_25_BASE_IDX 3
+#define regMPCC_OGAM0_MPCC_OGAM_RAMB_REGION_26_27 0x0146
+#define regMPCC_OGAM0_MPCC_OGAM_RAMB_REGION_26_27_BASE_IDX 3
+#define regMPCC_OGAM0_MPCC_OGAM_RAMB_REGION_28_29 0x0147
+#define regMPCC_OGAM0_MPCC_OGAM_RAMB_REGION_28_29_BASE_IDX 3
+#define regMPCC_OGAM0_MPCC_OGAM_RAMB_REGION_30_31 0x0148
+#define regMPCC_OGAM0_MPCC_OGAM_RAMB_REGION_30_31_BASE_IDX 3
+#define regMPCC_OGAM0_MPCC_OGAM_RAMB_REGION_32_33 0x0149
+#define regMPCC_OGAM0_MPCC_OGAM_RAMB_REGION_32_33_BASE_IDX 3
+#define regMPCC_OGAM0_MPCC_GAMUT_REMAP_COEF_FORMAT 0x014a
+#define regMPCC_OGAM0_MPCC_GAMUT_REMAP_COEF_FORMAT_BASE_IDX 3
+#define regMPCC_OGAM0_MPCC_GAMUT_REMAP_MODE 0x014b
+#define regMPCC_OGAM0_MPCC_GAMUT_REMAP_MODE_BASE_IDX 3
+#define regMPCC_OGAM0_MPC_GAMUT_REMAP_C11_C12_A 0x014c
+#define regMPCC_OGAM0_MPC_GAMUT_REMAP_C11_C12_A_BASE_IDX 3
+#define regMPCC_OGAM0_MPC_GAMUT_REMAP_C13_C14_A 0x014d
+#define regMPCC_OGAM0_MPC_GAMUT_REMAP_C13_C14_A_BASE_IDX 3
+#define regMPCC_OGAM0_MPC_GAMUT_REMAP_C21_C22_A 0x014e
+#define regMPCC_OGAM0_MPC_GAMUT_REMAP_C21_C22_A_BASE_IDX 3
+#define regMPCC_OGAM0_MPC_GAMUT_REMAP_C23_C24_A 0x014f
+#define regMPCC_OGAM0_MPC_GAMUT_REMAP_C23_C24_A_BASE_IDX 3
+#define regMPCC_OGAM0_MPC_GAMUT_REMAP_C31_C32_A 0x0150
+#define regMPCC_OGAM0_MPC_GAMUT_REMAP_C31_C32_A_BASE_IDX 3
+#define regMPCC_OGAM0_MPC_GAMUT_REMAP_C33_C34_A 0x0151
+#define regMPCC_OGAM0_MPC_GAMUT_REMAP_C33_C34_A_BASE_IDX 3
+#define regMPCC_OGAM0_MPC_GAMUT_REMAP_C11_C12_B 0x0152
+#define regMPCC_OGAM0_MPC_GAMUT_REMAP_C11_C12_B_BASE_IDX 3
+#define regMPCC_OGAM0_MPC_GAMUT_REMAP_C13_C14_B 0x0153
+#define regMPCC_OGAM0_MPC_GAMUT_REMAP_C13_C14_B_BASE_IDX 3
+#define regMPCC_OGAM0_MPC_GAMUT_REMAP_C21_C22_B 0x0154
+#define regMPCC_OGAM0_MPC_GAMUT_REMAP_C21_C22_B_BASE_IDX 3
+#define regMPCC_OGAM0_MPC_GAMUT_REMAP_C23_C24_B 0x0155
+#define regMPCC_OGAM0_MPC_GAMUT_REMAP_C23_C24_B_BASE_IDX 3
+#define regMPCC_OGAM0_MPC_GAMUT_REMAP_C31_C32_B 0x0156
+#define regMPCC_OGAM0_MPC_GAMUT_REMAP_C31_C32_B_BASE_IDX 3
+#define regMPCC_OGAM0_MPC_GAMUT_REMAP_C33_C34_B 0x0157
+#define regMPCC_OGAM0_MPC_GAMUT_REMAP_C33_C34_B_BASE_IDX 3
+
+
+// addressBlock: dce_dc_mpc_mpcc_ogam1_dispdec
+// base address: 0x200
+#define regMPCC_OGAM1_MPCC_OGAM_CONTROL 0x0180
+#define regMPCC_OGAM1_MPCC_OGAM_CONTROL_BASE_IDX 3
+#define regMPCC_OGAM1_MPCC_OGAM_LUT_INDEX 0x0181
+#define regMPCC_OGAM1_MPCC_OGAM_LUT_INDEX_BASE_IDX 3
+#define regMPCC_OGAM1_MPCC_OGAM_LUT_DATA 0x0182
+#define regMPCC_OGAM1_MPCC_OGAM_LUT_DATA_BASE_IDX 3
+#define regMPCC_OGAM1_MPCC_OGAM_LUT_CONTROL 0x0183
+#define regMPCC_OGAM1_MPCC_OGAM_LUT_CONTROL_BASE_IDX 3
+#define regMPCC_OGAM1_MPCC_OGAM_RAMA_START_CNTL_B 0x0184
+#define regMPCC_OGAM1_MPCC_OGAM_RAMA_START_CNTL_B_BASE_IDX 3
+#define regMPCC_OGAM1_MPCC_OGAM_RAMA_START_CNTL_G 0x0185
+#define regMPCC_OGAM1_MPCC_OGAM_RAMA_START_CNTL_G_BASE_IDX 3
+#define regMPCC_OGAM1_MPCC_OGAM_RAMA_START_CNTL_R 0x0186
+#define regMPCC_OGAM1_MPCC_OGAM_RAMA_START_CNTL_R_BASE_IDX 3
+#define regMPCC_OGAM1_MPCC_OGAM_RAMA_START_SLOPE_CNTL_B 0x0187
+#define regMPCC_OGAM1_MPCC_OGAM_RAMA_START_SLOPE_CNTL_B_BASE_IDX 3
+#define regMPCC_OGAM1_MPCC_OGAM_RAMA_START_SLOPE_CNTL_G 0x0188
+#define regMPCC_OGAM1_MPCC_OGAM_RAMA_START_SLOPE_CNTL_G_BASE_IDX 3
+#define regMPCC_OGAM1_MPCC_OGAM_RAMA_START_SLOPE_CNTL_R 0x0189
+#define regMPCC_OGAM1_MPCC_OGAM_RAMA_START_SLOPE_CNTL_R_BASE_IDX 3
+#define regMPCC_OGAM1_MPCC_OGAM_RAMA_START_BASE_CNTL_B 0x018a
+#define regMPCC_OGAM1_MPCC_OGAM_RAMA_START_BASE_CNTL_B_BASE_IDX 3
+#define regMPCC_OGAM1_MPCC_OGAM_RAMA_START_BASE_CNTL_G 0x018b
+#define regMPCC_OGAM1_MPCC_OGAM_RAMA_START_BASE_CNTL_G_BASE_IDX 3
+#define regMPCC_OGAM1_MPCC_OGAM_RAMA_START_BASE_CNTL_R 0x018c
+#define regMPCC_OGAM1_MPCC_OGAM_RAMA_START_BASE_CNTL_R_BASE_IDX 3
+#define regMPCC_OGAM1_MPCC_OGAM_RAMA_END_CNTL1_B 0x018d
+#define regMPCC_OGAM1_MPCC_OGAM_RAMA_END_CNTL1_B_BASE_IDX 3
+#define regMPCC_OGAM1_MPCC_OGAM_RAMA_END_CNTL2_B 0x018e
+#define regMPCC_OGAM1_MPCC_OGAM_RAMA_END_CNTL2_B_BASE_IDX 3
+#define regMPCC_OGAM1_MPCC_OGAM_RAMA_END_CNTL1_G 0x018f
+#define regMPCC_OGAM1_MPCC_OGAM_RAMA_END_CNTL1_G_BASE_IDX 3
+#define regMPCC_OGAM1_MPCC_OGAM_RAMA_END_CNTL2_G 0x0190
+#define regMPCC_OGAM1_MPCC_OGAM_RAMA_END_CNTL2_G_BASE_IDX 3
+#define regMPCC_OGAM1_MPCC_OGAM_RAMA_END_CNTL1_R 0x0191
+#define regMPCC_OGAM1_MPCC_OGAM_RAMA_END_CNTL1_R_BASE_IDX 3
+#define regMPCC_OGAM1_MPCC_OGAM_RAMA_END_CNTL2_R 0x0192
+#define regMPCC_OGAM1_MPCC_OGAM_RAMA_END_CNTL2_R_BASE_IDX 3
+#define regMPCC_OGAM1_MPCC_OGAM_RAMA_OFFSET_B 0x0193
+#define regMPCC_OGAM1_MPCC_OGAM_RAMA_OFFSET_B_BASE_IDX 3
+#define regMPCC_OGAM1_MPCC_OGAM_RAMA_OFFSET_G 0x0194
+#define regMPCC_OGAM1_MPCC_OGAM_RAMA_OFFSET_G_BASE_IDX 3
+#define regMPCC_OGAM1_MPCC_OGAM_RAMA_OFFSET_R 0x0195
+#define regMPCC_OGAM1_MPCC_OGAM_RAMA_OFFSET_R_BASE_IDX 3
+#define regMPCC_OGAM1_MPCC_OGAM_RAMA_REGION_0_1 0x0196
+#define regMPCC_OGAM1_MPCC_OGAM_RAMA_REGION_0_1_BASE_IDX 3
+#define regMPCC_OGAM1_MPCC_OGAM_RAMA_REGION_2_3 0x0197
+#define regMPCC_OGAM1_MPCC_OGAM_RAMA_REGION_2_3_BASE_IDX 3
+#define regMPCC_OGAM1_MPCC_OGAM_RAMA_REGION_4_5 0x0198
+#define regMPCC_OGAM1_MPCC_OGAM_RAMA_REGION_4_5_BASE_IDX 3
+#define regMPCC_OGAM1_MPCC_OGAM_RAMA_REGION_6_7 0x0199
+#define regMPCC_OGAM1_MPCC_OGAM_RAMA_REGION_6_7_BASE_IDX 3
+#define regMPCC_OGAM1_MPCC_OGAM_RAMA_REGION_8_9 0x019a
+#define regMPCC_OGAM1_MPCC_OGAM_RAMA_REGION_8_9_BASE_IDX 3
+#define regMPCC_OGAM1_MPCC_OGAM_RAMA_REGION_10_11 0x019b
+#define regMPCC_OGAM1_MPCC_OGAM_RAMA_REGION_10_11_BASE_IDX 3
+#define regMPCC_OGAM1_MPCC_OGAM_RAMA_REGION_12_13 0x019c
+#define regMPCC_OGAM1_MPCC_OGAM_RAMA_REGION_12_13_BASE_IDX 3
+#define regMPCC_OGAM1_MPCC_OGAM_RAMA_REGION_14_15 0x019d
+#define regMPCC_OGAM1_MPCC_OGAM_RAMA_REGION_14_15_BASE_IDX 3
+#define regMPCC_OGAM1_MPCC_OGAM_RAMA_REGION_16_17 0x019e
+#define regMPCC_OGAM1_MPCC_OGAM_RAMA_REGION_16_17_BASE_IDX 3
+#define regMPCC_OGAM1_MPCC_OGAM_RAMA_REGION_18_19 0x019f
+#define regMPCC_OGAM1_MPCC_OGAM_RAMA_REGION_18_19_BASE_IDX 3
+#define regMPCC_OGAM1_MPCC_OGAM_RAMA_REGION_20_21 0x01a0
+#define regMPCC_OGAM1_MPCC_OGAM_RAMA_REGION_20_21_BASE_IDX 3
+#define regMPCC_OGAM1_MPCC_OGAM_RAMA_REGION_22_23 0x01a1
+#define regMPCC_OGAM1_MPCC_OGAM_RAMA_REGION_22_23_BASE_IDX 3
+#define regMPCC_OGAM1_MPCC_OGAM_RAMA_REGION_24_25 0x01a2
+#define regMPCC_OGAM1_MPCC_OGAM_RAMA_REGION_24_25_BASE_IDX 3
+#define regMPCC_OGAM1_MPCC_OGAM_RAMA_REGION_26_27 0x01a3
+#define regMPCC_OGAM1_MPCC_OGAM_RAMA_REGION_26_27_BASE_IDX 3
+#define regMPCC_OGAM1_MPCC_OGAM_RAMA_REGION_28_29 0x01a4
+#define regMPCC_OGAM1_MPCC_OGAM_RAMA_REGION_28_29_BASE_IDX 3
+#define regMPCC_OGAM1_MPCC_OGAM_RAMA_REGION_30_31 0x01a5
+#define regMPCC_OGAM1_MPCC_OGAM_RAMA_REGION_30_31_BASE_IDX 3
+#define regMPCC_OGAM1_MPCC_OGAM_RAMA_REGION_32_33 0x01a6
+#define regMPCC_OGAM1_MPCC_OGAM_RAMA_REGION_32_33_BASE_IDX 3
+#define regMPCC_OGAM1_MPCC_OGAM_RAMB_START_CNTL_B 0x01a7
+#define regMPCC_OGAM1_MPCC_OGAM_RAMB_START_CNTL_B_BASE_IDX 3
+#define regMPCC_OGAM1_MPCC_OGAM_RAMB_START_CNTL_G 0x01a8
+#define regMPCC_OGAM1_MPCC_OGAM_RAMB_START_CNTL_G_BASE_IDX 3
+#define regMPCC_OGAM1_MPCC_OGAM_RAMB_START_CNTL_R 0x01a9
+#define regMPCC_OGAM1_MPCC_OGAM_RAMB_START_CNTL_R_BASE_IDX 3
+#define regMPCC_OGAM1_MPCC_OGAM_RAMB_START_SLOPE_CNTL_B 0x01aa
+#define regMPCC_OGAM1_MPCC_OGAM_RAMB_START_SLOPE_CNTL_B_BASE_IDX 3
+#define regMPCC_OGAM1_MPCC_OGAM_RAMB_START_SLOPE_CNTL_G 0x01ab
+#define regMPCC_OGAM1_MPCC_OGAM_RAMB_START_SLOPE_CNTL_G_BASE_IDX 3
+#define regMPCC_OGAM1_MPCC_OGAM_RAMB_START_SLOPE_CNTL_R 0x01ac
+#define regMPCC_OGAM1_MPCC_OGAM_RAMB_START_SLOPE_CNTL_R_BASE_IDX 3
+#define regMPCC_OGAM1_MPCC_OGAM_RAMB_START_BASE_CNTL_B 0x01ad
+#define regMPCC_OGAM1_MPCC_OGAM_RAMB_START_BASE_CNTL_B_BASE_IDX 3
+#define regMPCC_OGAM1_MPCC_OGAM_RAMB_START_BASE_CNTL_G 0x01ae
+#define regMPCC_OGAM1_MPCC_OGAM_RAMB_START_BASE_CNTL_G_BASE_IDX 3
+#define regMPCC_OGAM1_MPCC_OGAM_RAMB_START_BASE_CNTL_R 0x01af
+#define regMPCC_OGAM1_MPCC_OGAM_RAMB_START_BASE_CNTL_R_BASE_IDX 3
+#define regMPCC_OGAM1_MPCC_OGAM_RAMB_END_CNTL1_B 0x01b0
+#define regMPCC_OGAM1_MPCC_OGAM_RAMB_END_CNTL1_B_BASE_IDX 3
+#define regMPCC_OGAM1_MPCC_OGAM_RAMB_END_CNTL2_B 0x01b1
+#define regMPCC_OGAM1_MPCC_OGAM_RAMB_END_CNTL2_B_BASE_IDX 3
+#define regMPCC_OGAM1_MPCC_OGAM_RAMB_END_CNTL1_G 0x01b2
+#define regMPCC_OGAM1_MPCC_OGAM_RAMB_END_CNTL1_G_BASE_IDX 3
+#define regMPCC_OGAM1_MPCC_OGAM_RAMB_END_CNTL2_G 0x01b3
+#define regMPCC_OGAM1_MPCC_OGAM_RAMB_END_CNTL2_G_BASE_IDX 3
+#define regMPCC_OGAM1_MPCC_OGAM_RAMB_END_CNTL1_R 0x01b4
+#define regMPCC_OGAM1_MPCC_OGAM_RAMB_END_CNTL1_R_BASE_IDX 3
+#define regMPCC_OGAM1_MPCC_OGAM_RAMB_END_CNTL2_R 0x01b5
+#define regMPCC_OGAM1_MPCC_OGAM_RAMB_END_CNTL2_R_BASE_IDX 3
+#define regMPCC_OGAM1_MPCC_OGAM_RAMB_OFFSET_B 0x01b6
+#define regMPCC_OGAM1_MPCC_OGAM_RAMB_OFFSET_B_BASE_IDX 3
+#define regMPCC_OGAM1_MPCC_OGAM_RAMB_OFFSET_G 0x01b7
+#define regMPCC_OGAM1_MPCC_OGAM_RAMB_OFFSET_G_BASE_IDX 3
+#define regMPCC_OGAM1_MPCC_OGAM_RAMB_OFFSET_R 0x01b8
+#define regMPCC_OGAM1_MPCC_OGAM_RAMB_OFFSET_R_BASE_IDX 3
+#define regMPCC_OGAM1_MPCC_OGAM_RAMB_REGION_0_1 0x01b9
+#define regMPCC_OGAM1_MPCC_OGAM_RAMB_REGION_0_1_BASE_IDX 3
+#define regMPCC_OGAM1_MPCC_OGAM_RAMB_REGION_2_3 0x01ba
+#define regMPCC_OGAM1_MPCC_OGAM_RAMB_REGION_2_3_BASE_IDX 3
+#define regMPCC_OGAM1_MPCC_OGAM_RAMB_REGION_4_5 0x01bb
+#define regMPCC_OGAM1_MPCC_OGAM_RAMB_REGION_4_5_BASE_IDX 3
+#define regMPCC_OGAM1_MPCC_OGAM_RAMB_REGION_6_7 0x01bc
+#define regMPCC_OGAM1_MPCC_OGAM_RAMB_REGION_6_7_BASE_IDX 3
+#define regMPCC_OGAM1_MPCC_OGAM_RAMB_REGION_8_9 0x01bd
+#define regMPCC_OGAM1_MPCC_OGAM_RAMB_REGION_8_9_BASE_IDX 3
+#define regMPCC_OGAM1_MPCC_OGAM_RAMB_REGION_10_11 0x01be
+#define regMPCC_OGAM1_MPCC_OGAM_RAMB_REGION_10_11_BASE_IDX 3
+#define regMPCC_OGAM1_MPCC_OGAM_RAMB_REGION_12_13 0x01bf
+#define regMPCC_OGAM1_MPCC_OGAM_RAMB_REGION_12_13_BASE_IDX 3
+#define regMPCC_OGAM1_MPCC_OGAM_RAMB_REGION_14_15 0x01c0
+#define regMPCC_OGAM1_MPCC_OGAM_RAMB_REGION_14_15_BASE_IDX 3
+#define regMPCC_OGAM1_MPCC_OGAM_RAMB_REGION_16_17 0x01c1
+#define regMPCC_OGAM1_MPCC_OGAM_RAMB_REGION_16_17_BASE_IDX 3
+#define regMPCC_OGAM1_MPCC_OGAM_RAMB_REGION_18_19 0x01c2
+#define regMPCC_OGAM1_MPCC_OGAM_RAMB_REGION_18_19_BASE_IDX 3
+#define regMPCC_OGAM1_MPCC_OGAM_RAMB_REGION_20_21 0x01c3
+#define regMPCC_OGAM1_MPCC_OGAM_RAMB_REGION_20_21_BASE_IDX 3
+#define regMPCC_OGAM1_MPCC_OGAM_RAMB_REGION_22_23 0x01c4
+#define regMPCC_OGAM1_MPCC_OGAM_RAMB_REGION_22_23_BASE_IDX 3
+#define regMPCC_OGAM1_MPCC_OGAM_RAMB_REGION_24_25 0x01c5
+#define regMPCC_OGAM1_MPCC_OGAM_RAMB_REGION_24_25_BASE_IDX 3
+#define regMPCC_OGAM1_MPCC_OGAM_RAMB_REGION_26_27 0x01c6
+#define regMPCC_OGAM1_MPCC_OGAM_RAMB_REGION_26_27_BASE_IDX 3
+#define regMPCC_OGAM1_MPCC_OGAM_RAMB_REGION_28_29 0x01c7
+#define regMPCC_OGAM1_MPCC_OGAM_RAMB_REGION_28_29_BASE_IDX 3
+#define regMPCC_OGAM1_MPCC_OGAM_RAMB_REGION_30_31 0x01c8
+#define regMPCC_OGAM1_MPCC_OGAM_RAMB_REGION_30_31_BASE_IDX 3
+#define regMPCC_OGAM1_MPCC_OGAM_RAMB_REGION_32_33 0x01c9
+#define regMPCC_OGAM1_MPCC_OGAM_RAMB_REGION_32_33_BASE_IDX 3
+#define regMPCC_OGAM1_MPCC_GAMUT_REMAP_COEF_FORMAT 0x01ca
+#define regMPCC_OGAM1_MPCC_GAMUT_REMAP_COEF_FORMAT_BASE_IDX 3
+#define regMPCC_OGAM1_MPCC_GAMUT_REMAP_MODE 0x01cb
+#define regMPCC_OGAM1_MPCC_GAMUT_REMAP_MODE_BASE_IDX 3
+#define regMPCC_OGAM1_MPC_GAMUT_REMAP_C11_C12_A 0x01cc
+#define regMPCC_OGAM1_MPC_GAMUT_REMAP_C11_C12_A_BASE_IDX 3
+#define regMPCC_OGAM1_MPC_GAMUT_REMAP_C13_C14_A 0x01cd
+#define regMPCC_OGAM1_MPC_GAMUT_REMAP_C13_C14_A_BASE_IDX 3
+#define regMPCC_OGAM1_MPC_GAMUT_REMAP_C21_C22_A 0x01ce
+#define regMPCC_OGAM1_MPC_GAMUT_REMAP_C21_C22_A_BASE_IDX 3
+#define regMPCC_OGAM1_MPC_GAMUT_REMAP_C23_C24_A 0x01cf
+#define regMPCC_OGAM1_MPC_GAMUT_REMAP_C23_C24_A_BASE_IDX 3
+#define regMPCC_OGAM1_MPC_GAMUT_REMAP_C31_C32_A 0x01d0
+#define regMPCC_OGAM1_MPC_GAMUT_REMAP_C31_C32_A_BASE_IDX 3
+#define regMPCC_OGAM1_MPC_GAMUT_REMAP_C33_C34_A 0x01d1
+#define regMPCC_OGAM1_MPC_GAMUT_REMAP_C33_C34_A_BASE_IDX 3
+#define regMPCC_OGAM1_MPC_GAMUT_REMAP_C11_C12_B 0x01d2
+#define regMPCC_OGAM1_MPC_GAMUT_REMAP_C11_C12_B_BASE_IDX 3
+#define regMPCC_OGAM1_MPC_GAMUT_REMAP_C13_C14_B 0x01d3
+#define regMPCC_OGAM1_MPC_GAMUT_REMAP_C13_C14_B_BASE_IDX 3
+#define regMPCC_OGAM1_MPC_GAMUT_REMAP_C21_C22_B 0x01d4
+#define regMPCC_OGAM1_MPC_GAMUT_REMAP_C21_C22_B_BASE_IDX 3
+#define regMPCC_OGAM1_MPC_GAMUT_REMAP_C23_C24_B 0x01d5
+#define regMPCC_OGAM1_MPC_GAMUT_REMAP_C23_C24_B_BASE_IDX 3
+#define regMPCC_OGAM1_MPC_GAMUT_REMAP_C31_C32_B 0x01d6
+#define regMPCC_OGAM1_MPC_GAMUT_REMAP_C31_C32_B_BASE_IDX 3
+#define regMPCC_OGAM1_MPC_GAMUT_REMAP_C33_C34_B 0x01d7
+#define regMPCC_OGAM1_MPC_GAMUT_REMAP_C33_C34_B_BASE_IDX 3
+
+
+// addressBlock: dce_dc_mpc_mpcc_ogam2_dispdec
+// base address: 0x400
+#define regMPCC_OGAM2_MPCC_OGAM_CONTROL 0x0200
+#define regMPCC_OGAM2_MPCC_OGAM_CONTROL_BASE_IDX 3
+#define regMPCC_OGAM2_MPCC_OGAM_LUT_INDEX 0x0201
+#define regMPCC_OGAM2_MPCC_OGAM_LUT_INDEX_BASE_IDX 3
+#define regMPCC_OGAM2_MPCC_OGAM_LUT_DATA 0x0202
+#define regMPCC_OGAM2_MPCC_OGAM_LUT_DATA_BASE_IDX 3
+#define regMPCC_OGAM2_MPCC_OGAM_LUT_CONTROL 0x0203
+#define regMPCC_OGAM2_MPCC_OGAM_LUT_CONTROL_BASE_IDX 3
+#define regMPCC_OGAM2_MPCC_OGAM_RAMA_START_CNTL_B 0x0204
+#define regMPCC_OGAM2_MPCC_OGAM_RAMA_START_CNTL_B_BASE_IDX 3
+#define regMPCC_OGAM2_MPCC_OGAM_RAMA_START_CNTL_G 0x0205
+#define regMPCC_OGAM2_MPCC_OGAM_RAMA_START_CNTL_G_BASE_IDX 3
+#define regMPCC_OGAM2_MPCC_OGAM_RAMA_START_CNTL_R 0x0206
+#define regMPCC_OGAM2_MPCC_OGAM_RAMA_START_CNTL_R_BASE_IDX 3
+#define regMPCC_OGAM2_MPCC_OGAM_RAMA_START_SLOPE_CNTL_B 0x0207
+#define regMPCC_OGAM2_MPCC_OGAM_RAMA_START_SLOPE_CNTL_B_BASE_IDX 3
+#define regMPCC_OGAM2_MPCC_OGAM_RAMA_START_SLOPE_CNTL_G 0x0208
+#define regMPCC_OGAM2_MPCC_OGAM_RAMA_START_SLOPE_CNTL_G_BASE_IDX 3
+#define regMPCC_OGAM2_MPCC_OGAM_RAMA_START_SLOPE_CNTL_R 0x0209
+#define regMPCC_OGAM2_MPCC_OGAM_RAMA_START_SLOPE_CNTL_R_BASE_IDX 3
+#define regMPCC_OGAM2_MPCC_OGAM_RAMA_START_BASE_CNTL_B 0x020a
+#define regMPCC_OGAM2_MPCC_OGAM_RAMA_START_BASE_CNTL_B_BASE_IDX 3
+#define regMPCC_OGAM2_MPCC_OGAM_RAMA_START_BASE_CNTL_G 0x020b
+#define regMPCC_OGAM2_MPCC_OGAM_RAMA_START_BASE_CNTL_G_BASE_IDX 3
+#define regMPCC_OGAM2_MPCC_OGAM_RAMA_START_BASE_CNTL_R 0x020c
+#define regMPCC_OGAM2_MPCC_OGAM_RAMA_START_BASE_CNTL_R_BASE_IDX 3
+#define regMPCC_OGAM2_MPCC_OGAM_RAMA_END_CNTL1_B 0x020d
+#define regMPCC_OGAM2_MPCC_OGAM_RAMA_END_CNTL1_B_BASE_IDX 3
+#define regMPCC_OGAM2_MPCC_OGAM_RAMA_END_CNTL2_B 0x020e
+#define regMPCC_OGAM2_MPCC_OGAM_RAMA_END_CNTL2_B_BASE_IDX 3
+#define regMPCC_OGAM2_MPCC_OGAM_RAMA_END_CNTL1_G 0x020f
+#define regMPCC_OGAM2_MPCC_OGAM_RAMA_END_CNTL1_G_BASE_IDX 3
+#define regMPCC_OGAM2_MPCC_OGAM_RAMA_END_CNTL2_G 0x0210
+#define regMPCC_OGAM2_MPCC_OGAM_RAMA_END_CNTL2_G_BASE_IDX 3
+#define regMPCC_OGAM2_MPCC_OGAM_RAMA_END_CNTL1_R 0x0211
+#define regMPCC_OGAM2_MPCC_OGAM_RAMA_END_CNTL1_R_BASE_IDX 3
+#define regMPCC_OGAM2_MPCC_OGAM_RAMA_END_CNTL2_R 0x0212
+#define regMPCC_OGAM2_MPCC_OGAM_RAMA_END_CNTL2_R_BASE_IDX 3
+#define regMPCC_OGAM2_MPCC_OGAM_RAMA_OFFSET_B 0x0213
+#define regMPCC_OGAM2_MPCC_OGAM_RAMA_OFFSET_B_BASE_IDX 3
+#define regMPCC_OGAM2_MPCC_OGAM_RAMA_OFFSET_G 0x0214
+#define regMPCC_OGAM2_MPCC_OGAM_RAMA_OFFSET_G_BASE_IDX 3
+#define regMPCC_OGAM2_MPCC_OGAM_RAMA_OFFSET_R 0x0215
+#define regMPCC_OGAM2_MPCC_OGAM_RAMA_OFFSET_R_BASE_IDX 3
+#define regMPCC_OGAM2_MPCC_OGAM_RAMA_REGION_0_1 0x0216
+#define regMPCC_OGAM2_MPCC_OGAM_RAMA_REGION_0_1_BASE_IDX 3
+#define regMPCC_OGAM2_MPCC_OGAM_RAMA_REGION_2_3 0x0217
+#define regMPCC_OGAM2_MPCC_OGAM_RAMA_REGION_2_3_BASE_IDX 3
+#define regMPCC_OGAM2_MPCC_OGAM_RAMA_REGION_4_5 0x0218
+#define regMPCC_OGAM2_MPCC_OGAM_RAMA_REGION_4_5_BASE_IDX 3
+#define regMPCC_OGAM2_MPCC_OGAM_RAMA_REGION_6_7 0x0219
+#define regMPCC_OGAM2_MPCC_OGAM_RAMA_REGION_6_7_BASE_IDX 3
+#define regMPCC_OGAM2_MPCC_OGAM_RAMA_REGION_8_9 0x021a
+#define regMPCC_OGAM2_MPCC_OGAM_RAMA_REGION_8_9_BASE_IDX 3
+#define regMPCC_OGAM2_MPCC_OGAM_RAMA_REGION_10_11 0x021b
+#define regMPCC_OGAM2_MPCC_OGAM_RAMA_REGION_10_11_BASE_IDX 3
+#define regMPCC_OGAM2_MPCC_OGAM_RAMA_REGION_12_13 0x021c
+#define regMPCC_OGAM2_MPCC_OGAM_RAMA_REGION_12_13_BASE_IDX 3
+#define regMPCC_OGAM2_MPCC_OGAM_RAMA_REGION_14_15 0x021d
+#define regMPCC_OGAM2_MPCC_OGAM_RAMA_REGION_14_15_BASE_IDX 3
+#define regMPCC_OGAM2_MPCC_OGAM_RAMA_REGION_16_17 0x021e
+#define regMPCC_OGAM2_MPCC_OGAM_RAMA_REGION_16_17_BASE_IDX 3
+#define regMPCC_OGAM2_MPCC_OGAM_RAMA_REGION_18_19 0x021f
+#define regMPCC_OGAM2_MPCC_OGAM_RAMA_REGION_18_19_BASE_IDX 3
+#define regMPCC_OGAM2_MPCC_OGAM_RAMA_REGION_20_21 0x0220
+#define regMPCC_OGAM2_MPCC_OGAM_RAMA_REGION_20_21_BASE_IDX 3
+#define regMPCC_OGAM2_MPCC_OGAM_RAMA_REGION_22_23 0x0221
+#define regMPCC_OGAM2_MPCC_OGAM_RAMA_REGION_22_23_BASE_IDX 3
+#define regMPCC_OGAM2_MPCC_OGAM_RAMA_REGION_24_25 0x0222
+#define regMPCC_OGAM2_MPCC_OGAM_RAMA_REGION_24_25_BASE_IDX 3
+#define regMPCC_OGAM2_MPCC_OGAM_RAMA_REGION_26_27 0x0223
+#define regMPCC_OGAM2_MPCC_OGAM_RAMA_REGION_26_27_BASE_IDX 3
+#define regMPCC_OGAM2_MPCC_OGAM_RAMA_REGION_28_29 0x0224
+#define regMPCC_OGAM2_MPCC_OGAM_RAMA_REGION_28_29_BASE_IDX 3
+#define regMPCC_OGAM2_MPCC_OGAM_RAMA_REGION_30_31 0x0225
+#define regMPCC_OGAM2_MPCC_OGAM_RAMA_REGION_30_31_BASE_IDX 3
+#define regMPCC_OGAM2_MPCC_OGAM_RAMA_REGION_32_33 0x0226
+#define regMPCC_OGAM2_MPCC_OGAM_RAMA_REGION_32_33_BASE_IDX 3
+#define regMPCC_OGAM2_MPCC_OGAM_RAMB_START_CNTL_B 0x0227
+#define regMPCC_OGAM2_MPCC_OGAM_RAMB_START_CNTL_B_BASE_IDX 3
+#define regMPCC_OGAM2_MPCC_OGAM_RAMB_START_CNTL_G 0x0228
+#define regMPCC_OGAM2_MPCC_OGAM_RAMB_START_CNTL_G_BASE_IDX 3
+#define regMPCC_OGAM2_MPCC_OGAM_RAMB_START_CNTL_R 0x0229
+#define regMPCC_OGAM2_MPCC_OGAM_RAMB_START_CNTL_R_BASE_IDX 3
+#define regMPCC_OGAM2_MPCC_OGAM_RAMB_START_SLOPE_CNTL_B 0x022a
+#define regMPCC_OGAM2_MPCC_OGAM_RAMB_START_SLOPE_CNTL_B_BASE_IDX 3
+#define regMPCC_OGAM2_MPCC_OGAM_RAMB_START_SLOPE_CNTL_G 0x022b
+#define regMPCC_OGAM2_MPCC_OGAM_RAMB_START_SLOPE_CNTL_G_BASE_IDX 3
+#define regMPCC_OGAM2_MPCC_OGAM_RAMB_START_SLOPE_CNTL_R 0x022c
+#define regMPCC_OGAM2_MPCC_OGAM_RAMB_START_SLOPE_CNTL_R_BASE_IDX 3
+#define regMPCC_OGAM2_MPCC_OGAM_RAMB_START_BASE_CNTL_B 0x022d
+#define regMPCC_OGAM2_MPCC_OGAM_RAMB_START_BASE_CNTL_B_BASE_IDX 3
+#define regMPCC_OGAM2_MPCC_OGAM_RAMB_START_BASE_CNTL_G 0x022e
+#define regMPCC_OGAM2_MPCC_OGAM_RAMB_START_BASE_CNTL_G_BASE_IDX 3
+#define regMPCC_OGAM2_MPCC_OGAM_RAMB_START_BASE_CNTL_R 0x022f
+#define regMPCC_OGAM2_MPCC_OGAM_RAMB_START_BASE_CNTL_R_BASE_IDX 3
+#define regMPCC_OGAM2_MPCC_OGAM_RAMB_END_CNTL1_B 0x0230
+#define regMPCC_OGAM2_MPCC_OGAM_RAMB_END_CNTL1_B_BASE_IDX 3
+#define regMPCC_OGAM2_MPCC_OGAM_RAMB_END_CNTL2_B 0x0231
+#define regMPCC_OGAM2_MPCC_OGAM_RAMB_END_CNTL2_B_BASE_IDX 3
+#define regMPCC_OGAM2_MPCC_OGAM_RAMB_END_CNTL1_G 0x0232
+#define regMPCC_OGAM2_MPCC_OGAM_RAMB_END_CNTL1_G_BASE_IDX 3
+#define regMPCC_OGAM2_MPCC_OGAM_RAMB_END_CNTL2_G 0x0233
+#define regMPCC_OGAM2_MPCC_OGAM_RAMB_END_CNTL2_G_BASE_IDX 3
+#define regMPCC_OGAM2_MPCC_OGAM_RAMB_END_CNTL1_R 0x0234
+#define regMPCC_OGAM2_MPCC_OGAM_RAMB_END_CNTL1_R_BASE_IDX 3
+#define regMPCC_OGAM2_MPCC_OGAM_RAMB_END_CNTL2_R 0x0235
+#define regMPCC_OGAM2_MPCC_OGAM_RAMB_END_CNTL2_R_BASE_IDX 3
+#define regMPCC_OGAM2_MPCC_OGAM_RAMB_OFFSET_B 0x0236
+#define regMPCC_OGAM2_MPCC_OGAM_RAMB_OFFSET_B_BASE_IDX 3
+#define regMPCC_OGAM2_MPCC_OGAM_RAMB_OFFSET_G 0x0237
+#define regMPCC_OGAM2_MPCC_OGAM_RAMB_OFFSET_G_BASE_IDX 3
+#define regMPCC_OGAM2_MPCC_OGAM_RAMB_OFFSET_R 0x0238
+#define regMPCC_OGAM2_MPCC_OGAM_RAMB_OFFSET_R_BASE_IDX 3
+#define regMPCC_OGAM2_MPCC_OGAM_RAMB_REGION_0_1 0x0239
+#define regMPCC_OGAM2_MPCC_OGAM_RAMB_REGION_0_1_BASE_IDX 3
+#define regMPCC_OGAM2_MPCC_OGAM_RAMB_REGION_2_3 0x023a
+#define regMPCC_OGAM2_MPCC_OGAM_RAMB_REGION_2_3_BASE_IDX 3
+#define regMPCC_OGAM2_MPCC_OGAM_RAMB_REGION_4_5 0x023b
+#define regMPCC_OGAM2_MPCC_OGAM_RAMB_REGION_4_5_BASE_IDX 3
+#define regMPCC_OGAM2_MPCC_OGAM_RAMB_REGION_6_7 0x023c
+#define regMPCC_OGAM2_MPCC_OGAM_RAMB_REGION_6_7_BASE_IDX 3
+#define regMPCC_OGAM2_MPCC_OGAM_RAMB_REGION_8_9 0x023d
+#define regMPCC_OGAM2_MPCC_OGAM_RAMB_REGION_8_9_BASE_IDX 3
+#define regMPCC_OGAM2_MPCC_OGAM_RAMB_REGION_10_11 0x023e
+#define regMPCC_OGAM2_MPCC_OGAM_RAMB_REGION_10_11_BASE_IDX 3
+#define regMPCC_OGAM2_MPCC_OGAM_RAMB_REGION_12_13 0x023f
+#define regMPCC_OGAM2_MPCC_OGAM_RAMB_REGION_12_13_BASE_IDX 3
+#define regMPCC_OGAM2_MPCC_OGAM_RAMB_REGION_14_15 0x0240
+#define regMPCC_OGAM2_MPCC_OGAM_RAMB_REGION_14_15_BASE_IDX 3
+#define regMPCC_OGAM2_MPCC_OGAM_RAMB_REGION_16_17 0x0241
+#define regMPCC_OGAM2_MPCC_OGAM_RAMB_REGION_16_17_BASE_IDX 3
+#define regMPCC_OGAM2_MPCC_OGAM_RAMB_REGION_18_19 0x0242
+#define regMPCC_OGAM2_MPCC_OGAM_RAMB_REGION_18_19_BASE_IDX 3
+#define regMPCC_OGAM2_MPCC_OGAM_RAMB_REGION_20_21 0x0243
+#define regMPCC_OGAM2_MPCC_OGAM_RAMB_REGION_20_21_BASE_IDX 3
+#define regMPCC_OGAM2_MPCC_OGAM_RAMB_REGION_22_23 0x0244
+#define regMPCC_OGAM2_MPCC_OGAM_RAMB_REGION_22_23_BASE_IDX 3
+#define regMPCC_OGAM2_MPCC_OGAM_RAMB_REGION_24_25 0x0245
+#define regMPCC_OGAM2_MPCC_OGAM_RAMB_REGION_24_25_BASE_IDX 3
+#define regMPCC_OGAM2_MPCC_OGAM_RAMB_REGION_26_27 0x0246
+#define regMPCC_OGAM2_MPCC_OGAM_RAMB_REGION_26_27_BASE_IDX 3
+#define regMPCC_OGAM2_MPCC_OGAM_RAMB_REGION_28_29 0x0247
+#define regMPCC_OGAM2_MPCC_OGAM_RAMB_REGION_28_29_BASE_IDX 3
+#define regMPCC_OGAM2_MPCC_OGAM_RAMB_REGION_30_31 0x0248
+#define regMPCC_OGAM2_MPCC_OGAM_RAMB_REGION_30_31_BASE_IDX 3
+#define regMPCC_OGAM2_MPCC_OGAM_RAMB_REGION_32_33 0x0249
+#define regMPCC_OGAM2_MPCC_OGAM_RAMB_REGION_32_33_BASE_IDX 3
+#define regMPCC_OGAM2_MPCC_GAMUT_REMAP_COEF_FORMAT 0x024a
+#define regMPCC_OGAM2_MPCC_GAMUT_REMAP_COEF_FORMAT_BASE_IDX 3
+#define regMPCC_OGAM2_MPCC_GAMUT_REMAP_MODE 0x024b
+#define regMPCC_OGAM2_MPCC_GAMUT_REMAP_MODE_BASE_IDX 3
+#define regMPCC_OGAM2_MPC_GAMUT_REMAP_C11_C12_A 0x024c
+#define regMPCC_OGAM2_MPC_GAMUT_REMAP_C11_C12_A_BASE_IDX 3
+#define regMPCC_OGAM2_MPC_GAMUT_REMAP_C13_C14_A 0x024d
+#define regMPCC_OGAM2_MPC_GAMUT_REMAP_C13_C14_A_BASE_IDX 3
+#define regMPCC_OGAM2_MPC_GAMUT_REMAP_C21_C22_A 0x024e
+#define regMPCC_OGAM2_MPC_GAMUT_REMAP_C21_C22_A_BASE_IDX 3
+#define regMPCC_OGAM2_MPC_GAMUT_REMAP_C23_C24_A 0x024f
+#define regMPCC_OGAM2_MPC_GAMUT_REMAP_C23_C24_A_BASE_IDX 3
+#define regMPCC_OGAM2_MPC_GAMUT_REMAP_C31_C32_A 0x0250
+#define regMPCC_OGAM2_MPC_GAMUT_REMAP_C31_C32_A_BASE_IDX 3
+#define regMPCC_OGAM2_MPC_GAMUT_REMAP_C33_C34_A 0x0251
+#define regMPCC_OGAM2_MPC_GAMUT_REMAP_C33_C34_A_BASE_IDX 3
+#define regMPCC_OGAM2_MPC_GAMUT_REMAP_C11_C12_B 0x0252
+#define regMPCC_OGAM2_MPC_GAMUT_REMAP_C11_C12_B_BASE_IDX 3
+#define regMPCC_OGAM2_MPC_GAMUT_REMAP_C13_C14_B 0x0253
+#define regMPCC_OGAM2_MPC_GAMUT_REMAP_C13_C14_B_BASE_IDX 3
+#define regMPCC_OGAM2_MPC_GAMUT_REMAP_C21_C22_B 0x0254
+#define regMPCC_OGAM2_MPC_GAMUT_REMAP_C21_C22_B_BASE_IDX 3
+#define regMPCC_OGAM2_MPC_GAMUT_REMAP_C23_C24_B 0x0255
+#define regMPCC_OGAM2_MPC_GAMUT_REMAP_C23_C24_B_BASE_IDX 3
+#define regMPCC_OGAM2_MPC_GAMUT_REMAP_C31_C32_B 0x0256
+#define regMPCC_OGAM2_MPC_GAMUT_REMAP_C31_C32_B_BASE_IDX 3
+#define regMPCC_OGAM2_MPC_GAMUT_REMAP_C33_C34_B 0x0257
+#define regMPCC_OGAM2_MPC_GAMUT_REMAP_C33_C34_B_BASE_IDX 3
+
+
+// addressBlock: dce_dc_mpc_mpcc_ogam3_dispdec
+// base address: 0x600
+#define regMPCC_OGAM3_MPCC_OGAM_CONTROL 0x0280
+#define regMPCC_OGAM3_MPCC_OGAM_CONTROL_BASE_IDX 3
+#define regMPCC_OGAM3_MPCC_OGAM_LUT_INDEX 0x0281
+#define regMPCC_OGAM3_MPCC_OGAM_LUT_INDEX_BASE_IDX 3
+#define regMPCC_OGAM3_MPCC_OGAM_LUT_DATA 0x0282
+#define regMPCC_OGAM3_MPCC_OGAM_LUT_DATA_BASE_IDX 3
+#define regMPCC_OGAM3_MPCC_OGAM_LUT_CONTROL 0x0283
+#define regMPCC_OGAM3_MPCC_OGAM_LUT_CONTROL_BASE_IDX 3
+#define regMPCC_OGAM3_MPCC_OGAM_RAMA_START_CNTL_B 0x0284
+#define regMPCC_OGAM3_MPCC_OGAM_RAMA_START_CNTL_B_BASE_IDX 3
+#define regMPCC_OGAM3_MPCC_OGAM_RAMA_START_CNTL_G 0x0285
+#define regMPCC_OGAM3_MPCC_OGAM_RAMA_START_CNTL_G_BASE_IDX 3
+#define regMPCC_OGAM3_MPCC_OGAM_RAMA_START_CNTL_R 0x0286
+#define regMPCC_OGAM3_MPCC_OGAM_RAMA_START_CNTL_R_BASE_IDX 3
+#define regMPCC_OGAM3_MPCC_OGAM_RAMA_START_SLOPE_CNTL_B 0x0287
+#define regMPCC_OGAM3_MPCC_OGAM_RAMA_START_SLOPE_CNTL_B_BASE_IDX 3
+#define regMPCC_OGAM3_MPCC_OGAM_RAMA_START_SLOPE_CNTL_G 0x0288
+#define regMPCC_OGAM3_MPCC_OGAM_RAMA_START_SLOPE_CNTL_G_BASE_IDX 3
+#define regMPCC_OGAM3_MPCC_OGAM_RAMA_START_SLOPE_CNTL_R 0x0289
+#define regMPCC_OGAM3_MPCC_OGAM_RAMA_START_SLOPE_CNTL_R_BASE_IDX 3
+#define regMPCC_OGAM3_MPCC_OGAM_RAMA_START_BASE_CNTL_B 0x028a
+#define regMPCC_OGAM3_MPCC_OGAM_RAMA_START_BASE_CNTL_B_BASE_IDX 3
+#define regMPCC_OGAM3_MPCC_OGAM_RAMA_START_BASE_CNTL_G 0x028b
+#define regMPCC_OGAM3_MPCC_OGAM_RAMA_START_BASE_CNTL_G_BASE_IDX 3
+#define regMPCC_OGAM3_MPCC_OGAM_RAMA_START_BASE_CNTL_R 0x028c
+#define regMPCC_OGAM3_MPCC_OGAM_RAMA_START_BASE_CNTL_R_BASE_IDX 3
+#define regMPCC_OGAM3_MPCC_OGAM_RAMA_END_CNTL1_B 0x028d
+#define regMPCC_OGAM3_MPCC_OGAM_RAMA_END_CNTL1_B_BASE_IDX 3
+#define regMPCC_OGAM3_MPCC_OGAM_RAMA_END_CNTL2_B 0x028e
+#define regMPCC_OGAM3_MPCC_OGAM_RAMA_END_CNTL2_B_BASE_IDX 3
+#define regMPCC_OGAM3_MPCC_OGAM_RAMA_END_CNTL1_G 0x028f
+#define regMPCC_OGAM3_MPCC_OGAM_RAMA_END_CNTL1_G_BASE_IDX 3
+#define regMPCC_OGAM3_MPCC_OGAM_RAMA_END_CNTL2_G 0x0290
+#define regMPCC_OGAM3_MPCC_OGAM_RAMA_END_CNTL2_G_BASE_IDX 3
+#define regMPCC_OGAM3_MPCC_OGAM_RAMA_END_CNTL1_R 0x0291
+#define regMPCC_OGAM3_MPCC_OGAM_RAMA_END_CNTL1_R_BASE_IDX 3
+#define regMPCC_OGAM3_MPCC_OGAM_RAMA_END_CNTL2_R 0x0292
+#define regMPCC_OGAM3_MPCC_OGAM_RAMA_END_CNTL2_R_BASE_IDX 3
+#define regMPCC_OGAM3_MPCC_OGAM_RAMA_OFFSET_B 0x0293
+#define regMPCC_OGAM3_MPCC_OGAM_RAMA_OFFSET_B_BASE_IDX 3
+#define regMPCC_OGAM3_MPCC_OGAM_RAMA_OFFSET_G 0x0294
+#define regMPCC_OGAM3_MPCC_OGAM_RAMA_OFFSET_G_BASE_IDX 3
+#define regMPCC_OGAM3_MPCC_OGAM_RAMA_OFFSET_R 0x0295
+#define regMPCC_OGAM3_MPCC_OGAM_RAMA_OFFSET_R_BASE_IDX 3
+#define regMPCC_OGAM3_MPCC_OGAM_RAMA_REGION_0_1 0x0296
+#define regMPCC_OGAM3_MPCC_OGAM_RAMA_REGION_0_1_BASE_IDX 3
+#define regMPCC_OGAM3_MPCC_OGAM_RAMA_REGION_2_3 0x0297
+#define regMPCC_OGAM3_MPCC_OGAM_RAMA_REGION_2_3_BASE_IDX 3
+#define regMPCC_OGAM3_MPCC_OGAM_RAMA_REGION_4_5 0x0298
+#define regMPCC_OGAM3_MPCC_OGAM_RAMA_REGION_4_5_BASE_IDX 3
+#define regMPCC_OGAM3_MPCC_OGAM_RAMA_REGION_6_7 0x0299
+#define regMPCC_OGAM3_MPCC_OGAM_RAMA_REGION_6_7_BASE_IDX 3
+#define regMPCC_OGAM3_MPCC_OGAM_RAMA_REGION_8_9 0x029a
+#define regMPCC_OGAM3_MPCC_OGAM_RAMA_REGION_8_9_BASE_IDX 3
+#define regMPCC_OGAM3_MPCC_OGAM_RAMA_REGION_10_11 0x029b
+#define regMPCC_OGAM3_MPCC_OGAM_RAMA_REGION_10_11_BASE_IDX 3
+#define regMPCC_OGAM3_MPCC_OGAM_RAMA_REGION_12_13 0x029c
+#define regMPCC_OGAM3_MPCC_OGAM_RAMA_REGION_12_13_BASE_IDX 3
+#define regMPCC_OGAM3_MPCC_OGAM_RAMA_REGION_14_15 0x029d
+#define regMPCC_OGAM3_MPCC_OGAM_RAMA_REGION_14_15_BASE_IDX 3
+#define regMPCC_OGAM3_MPCC_OGAM_RAMA_REGION_16_17 0x029e
+#define regMPCC_OGAM3_MPCC_OGAM_RAMA_REGION_16_17_BASE_IDX 3
+#define regMPCC_OGAM3_MPCC_OGAM_RAMA_REGION_18_19 0x029f
+#define regMPCC_OGAM3_MPCC_OGAM_RAMA_REGION_18_19_BASE_IDX 3
+#define regMPCC_OGAM3_MPCC_OGAM_RAMA_REGION_20_21 0x02a0
+#define regMPCC_OGAM3_MPCC_OGAM_RAMA_REGION_20_21_BASE_IDX 3
+#define regMPCC_OGAM3_MPCC_OGAM_RAMA_REGION_22_23 0x02a1
+#define regMPCC_OGAM3_MPCC_OGAM_RAMA_REGION_22_23_BASE_IDX 3
+#define regMPCC_OGAM3_MPCC_OGAM_RAMA_REGION_24_25 0x02a2
+#define regMPCC_OGAM3_MPCC_OGAM_RAMA_REGION_24_25_BASE_IDX 3
+#define regMPCC_OGAM3_MPCC_OGAM_RAMA_REGION_26_27 0x02a3
+#define regMPCC_OGAM3_MPCC_OGAM_RAMA_REGION_26_27_BASE_IDX 3
+#define regMPCC_OGAM3_MPCC_OGAM_RAMA_REGION_28_29 0x02a4
+#define regMPCC_OGAM3_MPCC_OGAM_RAMA_REGION_28_29_BASE_IDX 3
+#define regMPCC_OGAM3_MPCC_OGAM_RAMA_REGION_30_31 0x02a5
+#define regMPCC_OGAM3_MPCC_OGAM_RAMA_REGION_30_31_BASE_IDX 3
+#define regMPCC_OGAM3_MPCC_OGAM_RAMA_REGION_32_33 0x02a6
+#define regMPCC_OGAM3_MPCC_OGAM_RAMA_REGION_32_33_BASE_IDX 3
+#define regMPCC_OGAM3_MPCC_OGAM_RAMB_START_CNTL_B 0x02a7
+#define regMPCC_OGAM3_MPCC_OGAM_RAMB_START_CNTL_B_BASE_IDX 3
+#define regMPCC_OGAM3_MPCC_OGAM_RAMB_START_CNTL_G 0x02a8
+#define regMPCC_OGAM3_MPCC_OGAM_RAMB_START_CNTL_G_BASE_IDX 3
+#define regMPCC_OGAM3_MPCC_OGAM_RAMB_START_CNTL_R 0x02a9
+#define regMPCC_OGAM3_MPCC_OGAM_RAMB_START_CNTL_R_BASE_IDX 3
+#define regMPCC_OGAM3_MPCC_OGAM_RAMB_START_SLOPE_CNTL_B 0x02aa
+#define regMPCC_OGAM3_MPCC_OGAM_RAMB_START_SLOPE_CNTL_B_BASE_IDX 3
+#define regMPCC_OGAM3_MPCC_OGAM_RAMB_START_SLOPE_CNTL_G 0x02ab
+#define regMPCC_OGAM3_MPCC_OGAM_RAMB_START_SLOPE_CNTL_G_BASE_IDX 3
+#define regMPCC_OGAM3_MPCC_OGAM_RAMB_START_SLOPE_CNTL_R 0x02ac
+#define regMPCC_OGAM3_MPCC_OGAM_RAMB_START_SLOPE_CNTL_R_BASE_IDX 3
+#define regMPCC_OGAM3_MPCC_OGAM_RAMB_START_BASE_CNTL_B 0x02ad
+#define regMPCC_OGAM3_MPCC_OGAM_RAMB_START_BASE_CNTL_B_BASE_IDX 3
+#define regMPCC_OGAM3_MPCC_OGAM_RAMB_START_BASE_CNTL_G 0x02ae
+#define regMPCC_OGAM3_MPCC_OGAM_RAMB_START_BASE_CNTL_G_BASE_IDX 3
+#define regMPCC_OGAM3_MPCC_OGAM_RAMB_START_BASE_CNTL_R 0x02af
+#define regMPCC_OGAM3_MPCC_OGAM_RAMB_START_BASE_CNTL_R_BASE_IDX 3
+#define regMPCC_OGAM3_MPCC_OGAM_RAMB_END_CNTL1_B 0x02b0
+#define regMPCC_OGAM3_MPCC_OGAM_RAMB_END_CNTL1_B_BASE_IDX 3
+#define regMPCC_OGAM3_MPCC_OGAM_RAMB_END_CNTL2_B 0x02b1
+#define regMPCC_OGAM3_MPCC_OGAM_RAMB_END_CNTL2_B_BASE_IDX 3
+#define regMPCC_OGAM3_MPCC_OGAM_RAMB_END_CNTL1_G 0x02b2
+#define regMPCC_OGAM3_MPCC_OGAM_RAMB_END_CNTL1_G_BASE_IDX 3
+#define regMPCC_OGAM3_MPCC_OGAM_RAMB_END_CNTL2_G 0x02b3
+#define regMPCC_OGAM3_MPCC_OGAM_RAMB_END_CNTL2_G_BASE_IDX 3
+#define regMPCC_OGAM3_MPCC_OGAM_RAMB_END_CNTL1_R 0x02b4
+#define regMPCC_OGAM3_MPCC_OGAM_RAMB_END_CNTL1_R_BASE_IDX 3
+#define regMPCC_OGAM3_MPCC_OGAM_RAMB_END_CNTL2_R 0x02b5
+#define regMPCC_OGAM3_MPCC_OGAM_RAMB_END_CNTL2_R_BASE_IDX 3
+#define regMPCC_OGAM3_MPCC_OGAM_RAMB_OFFSET_B 0x02b6
+#define regMPCC_OGAM3_MPCC_OGAM_RAMB_OFFSET_B_BASE_IDX 3
+#define regMPCC_OGAM3_MPCC_OGAM_RAMB_OFFSET_G 0x02b7
+#define regMPCC_OGAM3_MPCC_OGAM_RAMB_OFFSET_G_BASE_IDX 3
+#define regMPCC_OGAM3_MPCC_OGAM_RAMB_OFFSET_R 0x02b8
+#define regMPCC_OGAM3_MPCC_OGAM_RAMB_OFFSET_R_BASE_IDX 3
+#define regMPCC_OGAM3_MPCC_OGAM_RAMB_REGION_0_1 0x02b9
+#define regMPCC_OGAM3_MPCC_OGAM_RAMB_REGION_0_1_BASE_IDX 3
+#define regMPCC_OGAM3_MPCC_OGAM_RAMB_REGION_2_3 0x02ba
+#define regMPCC_OGAM3_MPCC_OGAM_RAMB_REGION_2_3_BASE_IDX 3
+#define regMPCC_OGAM3_MPCC_OGAM_RAMB_REGION_4_5 0x02bb
+#define regMPCC_OGAM3_MPCC_OGAM_RAMB_REGION_4_5_BASE_IDX 3
+#define regMPCC_OGAM3_MPCC_OGAM_RAMB_REGION_6_7 0x02bc
+#define regMPCC_OGAM3_MPCC_OGAM_RAMB_REGION_6_7_BASE_IDX 3
+#define regMPCC_OGAM3_MPCC_OGAM_RAMB_REGION_8_9 0x02bd
+#define regMPCC_OGAM3_MPCC_OGAM_RAMB_REGION_8_9_BASE_IDX 3
+#define regMPCC_OGAM3_MPCC_OGAM_RAMB_REGION_10_11 0x02be
+#define regMPCC_OGAM3_MPCC_OGAM_RAMB_REGION_10_11_BASE_IDX 3
+#define regMPCC_OGAM3_MPCC_OGAM_RAMB_REGION_12_13 0x02bf
+#define regMPCC_OGAM3_MPCC_OGAM_RAMB_REGION_12_13_BASE_IDX 3
+#define regMPCC_OGAM3_MPCC_OGAM_RAMB_REGION_14_15 0x02c0
+#define regMPCC_OGAM3_MPCC_OGAM_RAMB_REGION_14_15_BASE_IDX 3
+#define regMPCC_OGAM3_MPCC_OGAM_RAMB_REGION_16_17 0x02c1
+#define regMPCC_OGAM3_MPCC_OGAM_RAMB_REGION_16_17_BASE_IDX 3
+#define regMPCC_OGAM3_MPCC_OGAM_RAMB_REGION_18_19 0x02c2
+#define regMPCC_OGAM3_MPCC_OGAM_RAMB_REGION_18_19_BASE_IDX 3
+#define regMPCC_OGAM3_MPCC_OGAM_RAMB_REGION_20_21 0x02c3
+#define regMPCC_OGAM3_MPCC_OGAM_RAMB_REGION_20_21_BASE_IDX 3
+#define regMPCC_OGAM3_MPCC_OGAM_RAMB_REGION_22_23 0x02c4
+#define regMPCC_OGAM3_MPCC_OGAM_RAMB_REGION_22_23_BASE_IDX 3
+#define regMPCC_OGAM3_MPCC_OGAM_RAMB_REGION_24_25 0x02c5
+#define regMPCC_OGAM3_MPCC_OGAM_RAMB_REGION_24_25_BASE_IDX 3
+#define regMPCC_OGAM3_MPCC_OGAM_RAMB_REGION_26_27 0x02c6
+#define regMPCC_OGAM3_MPCC_OGAM_RAMB_REGION_26_27_BASE_IDX 3
+#define regMPCC_OGAM3_MPCC_OGAM_RAMB_REGION_28_29 0x02c7
+#define regMPCC_OGAM3_MPCC_OGAM_RAMB_REGION_28_29_BASE_IDX 3
+#define regMPCC_OGAM3_MPCC_OGAM_RAMB_REGION_30_31 0x02c8
+#define regMPCC_OGAM3_MPCC_OGAM_RAMB_REGION_30_31_BASE_IDX 3
+#define regMPCC_OGAM3_MPCC_OGAM_RAMB_REGION_32_33 0x02c9
+#define regMPCC_OGAM3_MPCC_OGAM_RAMB_REGION_32_33_BASE_IDX 3
+#define regMPCC_OGAM3_MPCC_GAMUT_REMAP_COEF_FORMAT 0x02ca
+#define regMPCC_OGAM3_MPCC_GAMUT_REMAP_COEF_FORMAT_BASE_IDX 3
+#define regMPCC_OGAM3_MPCC_GAMUT_REMAP_MODE 0x02cb
+#define regMPCC_OGAM3_MPCC_GAMUT_REMAP_MODE_BASE_IDX 3
+#define regMPCC_OGAM3_MPC_GAMUT_REMAP_C11_C12_A 0x02cc
+#define regMPCC_OGAM3_MPC_GAMUT_REMAP_C11_C12_A_BASE_IDX 3
+#define regMPCC_OGAM3_MPC_GAMUT_REMAP_C13_C14_A 0x02cd
+#define regMPCC_OGAM3_MPC_GAMUT_REMAP_C13_C14_A_BASE_IDX 3
+#define regMPCC_OGAM3_MPC_GAMUT_REMAP_C21_C22_A 0x02ce
+#define regMPCC_OGAM3_MPC_GAMUT_REMAP_C21_C22_A_BASE_IDX 3
+#define regMPCC_OGAM3_MPC_GAMUT_REMAP_C23_C24_A 0x02cf
+#define regMPCC_OGAM3_MPC_GAMUT_REMAP_C23_C24_A_BASE_IDX 3
+#define regMPCC_OGAM3_MPC_GAMUT_REMAP_C31_C32_A 0x02d0
+#define regMPCC_OGAM3_MPC_GAMUT_REMAP_C31_C32_A_BASE_IDX 3
+#define regMPCC_OGAM3_MPC_GAMUT_REMAP_C33_C34_A 0x02d1
+#define regMPCC_OGAM3_MPC_GAMUT_REMAP_C33_C34_A_BASE_IDX 3
+#define regMPCC_OGAM3_MPC_GAMUT_REMAP_C11_C12_B 0x02d2
+#define regMPCC_OGAM3_MPC_GAMUT_REMAP_C11_C12_B_BASE_IDX 3
+#define regMPCC_OGAM3_MPC_GAMUT_REMAP_C13_C14_B 0x02d3
+#define regMPCC_OGAM3_MPC_GAMUT_REMAP_C13_C14_B_BASE_IDX 3
+#define regMPCC_OGAM3_MPC_GAMUT_REMAP_C21_C22_B 0x02d4
+#define regMPCC_OGAM3_MPC_GAMUT_REMAP_C21_C22_B_BASE_IDX 3
+#define regMPCC_OGAM3_MPC_GAMUT_REMAP_C23_C24_B 0x02d5
+#define regMPCC_OGAM3_MPC_GAMUT_REMAP_C23_C24_B_BASE_IDX 3
+#define regMPCC_OGAM3_MPC_GAMUT_REMAP_C31_C32_B 0x02d6
+#define regMPCC_OGAM3_MPC_GAMUT_REMAP_C31_C32_B_BASE_IDX 3
+#define regMPCC_OGAM3_MPC_GAMUT_REMAP_C33_C34_B 0x02d7
+#define regMPCC_OGAM3_MPC_GAMUT_REMAP_C33_C34_B_BASE_IDX 3
+
+
+// addressBlock: dce_dc_mpc_mpc_ocsc_dispdec
+// base address: 0x0
+#define regMPC_OUT0_MUX 0x0580
+#define regMPC_OUT0_MUX_BASE_IDX 3
+#define regMPC_OUT0_DENORM_CONTROL 0x0581
+#define regMPC_OUT0_DENORM_CONTROL_BASE_IDX 3
+#define regMPC_OUT0_DENORM_CLAMP_G_Y 0x0582
+#define regMPC_OUT0_DENORM_CLAMP_G_Y_BASE_IDX 3
+#define regMPC_OUT0_DENORM_CLAMP_B_CB 0x0583
+#define regMPC_OUT0_DENORM_CLAMP_B_CB_BASE_IDX 3
+#define regMPC_OUT1_MUX 0x0584
+#define regMPC_OUT1_MUX_BASE_IDX 3
+#define regMPC_OUT1_DENORM_CONTROL 0x0585
+#define regMPC_OUT1_DENORM_CONTROL_BASE_IDX 3
+#define regMPC_OUT1_DENORM_CLAMP_G_Y 0x0586
+#define regMPC_OUT1_DENORM_CLAMP_G_Y_BASE_IDX 3
+#define regMPC_OUT1_DENORM_CLAMP_B_CB 0x0587
+#define regMPC_OUT1_DENORM_CLAMP_B_CB_BASE_IDX 3
+#define regMPC_OUT2_MUX 0x0588
+#define regMPC_OUT2_MUX_BASE_IDX 3
+#define regMPC_OUT2_DENORM_CONTROL 0x0589
+#define regMPC_OUT2_DENORM_CONTROL_BASE_IDX 3
+#define regMPC_OUT2_DENORM_CLAMP_G_Y 0x058a
+#define regMPC_OUT2_DENORM_CLAMP_G_Y_BASE_IDX 3
+#define regMPC_OUT2_DENORM_CLAMP_B_CB 0x058b
+#define regMPC_OUT2_DENORM_CLAMP_B_CB_BASE_IDX 3
+#define regMPC_OUT3_MUX 0x058c
+#define regMPC_OUT3_MUX_BASE_IDX 3
+#define regMPC_OUT3_DENORM_CONTROL 0x058d
+#define regMPC_OUT3_DENORM_CONTROL_BASE_IDX 3
+#define regMPC_OUT3_DENORM_CLAMP_G_Y 0x058e
+#define regMPC_OUT3_DENORM_CLAMP_G_Y_BASE_IDX 3
+#define regMPC_OUT3_DENORM_CLAMP_B_CB 0x058f
+#define regMPC_OUT3_DENORM_CLAMP_B_CB_BASE_IDX 3
+#define regMPC_OUT_CSC_COEF_FORMAT 0x05a0
+#define regMPC_OUT_CSC_COEF_FORMAT_BASE_IDX 3
+#define regMPC_OUT0_CSC_MODE 0x05a1
+#define regMPC_OUT0_CSC_MODE_BASE_IDX 3
+#define regMPC_OUT0_CSC_C11_C12_A 0x05a2
+#define regMPC_OUT0_CSC_C11_C12_A_BASE_IDX 3
+#define regMPC_OUT0_CSC_C13_C14_A 0x05a3
+#define regMPC_OUT0_CSC_C13_C14_A_BASE_IDX 3
+#define regMPC_OUT0_CSC_C21_C22_A 0x05a4
+#define regMPC_OUT0_CSC_C21_C22_A_BASE_IDX 3
+#define regMPC_OUT0_CSC_C23_C24_A 0x05a5
+#define regMPC_OUT0_CSC_C23_C24_A_BASE_IDX 3
+#define regMPC_OUT0_CSC_C31_C32_A 0x05a6
+#define regMPC_OUT0_CSC_C31_C32_A_BASE_IDX 3
+#define regMPC_OUT0_CSC_C33_C34_A 0x05a7
+#define regMPC_OUT0_CSC_C33_C34_A_BASE_IDX 3
+#define regMPC_OUT0_CSC_C11_C12_B 0x05a8
+#define regMPC_OUT0_CSC_C11_C12_B_BASE_IDX 3
+#define regMPC_OUT0_CSC_C13_C14_B 0x05a9
+#define regMPC_OUT0_CSC_C13_C14_B_BASE_IDX 3
+#define regMPC_OUT0_CSC_C21_C22_B 0x05aa
+#define regMPC_OUT0_CSC_C21_C22_B_BASE_IDX 3
+#define regMPC_OUT0_CSC_C23_C24_B 0x05ab
+#define regMPC_OUT0_CSC_C23_C24_B_BASE_IDX 3
+#define regMPC_OUT0_CSC_C31_C32_B 0x05ac
+#define regMPC_OUT0_CSC_C31_C32_B_BASE_IDX 3
+#define regMPC_OUT0_CSC_C33_C34_B 0x05ad
+#define regMPC_OUT0_CSC_C33_C34_B_BASE_IDX 3
+#define regMPC_OUT1_CSC_MODE 0x05ae
+#define regMPC_OUT1_CSC_MODE_BASE_IDX 3
+#define regMPC_OUT1_CSC_C11_C12_A 0x05af
+#define regMPC_OUT1_CSC_C11_C12_A_BASE_IDX 3
+#define regMPC_OUT1_CSC_C13_C14_A 0x05b0
+#define regMPC_OUT1_CSC_C13_C14_A_BASE_IDX 3
+#define regMPC_OUT1_CSC_C21_C22_A 0x05b1
+#define regMPC_OUT1_CSC_C21_C22_A_BASE_IDX 3
+#define regMPC_OUT1_CSC_C23_C24_A 0x05b2
+#define regMPC_OUT1_CSC_C23_C24_A_BASE_IDX 3
+#define regMPC_OUT1_CSC_C31_C32_A 0x05b3
+#define regMPC_OUT1_CSC_C31_C32_A_BASE_IDX 3
+#define regMPC_OUT1_CSC_C33_C34_A 0x05b4
+#define regMPC_OUT1_CSC_C33_C34_A_BASE_IDX 3
+#define regMPC_OUT1_CSC_C11_C12_B 0x05b5
+#define regMPC_OUT1_CSC_C11_C12_B_BASE_IDX 3
+#define regMPC_OUT1_CSC_C13_C14_B 0x05b6
+#define regMPC_OUT1_CSC_C13_C14_B_BASE_IDX 3
+#define regMPC_OUT1_CSC_C21_C22_B 0x05b7
+#define regMPC_OUT1_CSC_C21_C22_B_BASE_IDX 3
+#define regMPC_OUT1_CSC_C23_C24_B 0x05b8
+#define regMPC_OUT1_CSC_C23_C24_B_BASE_IDX 3
+#define regMPC_OUT1_CSC_C31_C32_B 0x05b9
+#define regMPC_OUT1_CSC_C31_C32_B_BASE_IDX 3
+#define regMPC_OUT1_CSC_C33_C34_B 0x05ba
+#define regMPC_OUT1_CSC_C33_C34_B_BASE_IDX 3
+#define regMPC_OUT2_CSC_MODE 0x05bb
+#define regMPC_OUT2_CSC_MODE_BASE_IDX 3
+#define regMPC_OUT2_CSC_C11_C12_A 0x05bc
+#define regMPC_OUT2_CSC_C11_C12_A_BASE_IDX 3
+#define regMPC_OUT2_CSC_C13_C14_A 0x05bd
+#define regMPC_OUT2_CSC_C13_C14_A_BASE_IDX 3
+#define regMPC_OUT2_CSC_C21_C22_A 0x05be
+#define regMPC_OUT2_CSC_C21_C22_A_BASE_IDX 3
+#define regMPC_OUT2_CSC_C23_C24_A 0x05bf
+#define regMPC_OUT2_CSC_C23_C24_A_BASE_IDX 3
+#define regMPC_OUT2_CSC_C31_C32_A 0x05c0
+#define regMPC_OUT2_CSC_C31_C32_A_BASE_IDX 3
+#define regMPC_OUT2_CSC_C33_C34_A 0x05c1
+#define regMPC_OUT2_CSC_C33_C34_A_BASE_IDX 3
+#define regMPC_OUT2_CSC_C11_C12_B 0x05c2
+#define regMPC_OUT2_CSC_C11_C12_B_BASE_IDX 3
+#define regMPC_OUT2_CSC_C13_C14_B 0x05c3
+#define regMPC_OUT2_CSC_C13_C14_B_BASE_IDX 3
+#define regMPC_OUT2_CSC_C21_C22_B 0x05c4
+#define regMPC_OUT2_CSC_C21_C22_B_BASE_IDX 3
+#define regMPC_OUT2_CSC_C23_C24_B 0x05c5
+#define regMPC_OUT2_CSC_C23_C24_B_BASE_IDX 3
+#define regMPC_OUT2_CSC_C31_C32_B 0x05c6
+#define regMPC_OUT2_CSC_C31_C32_B_BASE_IDX 3
+#define regMPC_OUT2_CSC_C33_C34_B 0x05c7
+#define regMPC_OUT2_CSC_C33_C34_B_BASE_IDX 3
+#define regMPC_OUT3_CSC_MODE 0x05c8
+#define regMPC_OUT3_CSC_MODE_BASE_IDX 3
+#define regMPC_OUT3_CSC_C11_C12_A 0x05c9
+#define regMPC_OUT3_CSC_C11_C12_A_BASE_IDX 3
+#define regMPC_OUT3_CSC_C13_C14_A 0x05ca
+#define regMPC_OUT3_CSC_C13_C14_A_BASE_IDX 3
+#define regMPC_OUT3_CSC_C21_C22_A 0x05cb
+#define regMPC_OUT3_CSC_C21_C22_A_BASE_IDX 3
+#define regMPC_OUT3_CSC_C23_C24_A 0x05cc
+#define regMPC_OUT3_CSC_C23_C24_A_BASE_IDX 3
+#define regMPC_OUT3_CSC_C31_C32_A 0x05cd
+#define regMPC_OUT3_CSC_C31_C32_A_BASE_IDX 3
+#define regMPC_OUT3_CSC_C33_C34_A 0x05ce
+#define regMPC_OUT3_CSC_C33_C34_A_BASE_IDX 3
+#define regMPC_OUT3_CSC_C11_C12_B 0x05cf
+#define regMPC_OUT3_CSC_C11_C12_B_BASE_IDX 3
+#define regMPC_OUT3_CSC_C13_C14_B 0x05d0
+#define regMPC_OUT3_CSC_C13_C14_B_BASE_IDX 3
+#define regMPC_OUT3_CSC_C21_C22_B 0x05d1
+#define regMPC_OUT3_CSC_C21_C22_B_BASE_IDX 3
+#define regMPC_OUT3_CSC_C23_C24_B 0x05d2
+#define regMPC_OUT3_CSC_C23_C24_B_BASE_IDX 3
+#define regMPC_OUT3_CSC_C31_C32_B 0x05d3
+#define regMPC_OUT3_CSC_C31_C32_B_BASE_IDX 3
+#define regMPC_OUT3_CSC_C33_C34_B 0x05d4
+#define regMPC_OUT3_CSC_C33_C34_B_BASE_IDX 3
+#define regMPC_OCSC_TEST_DEBUG_INDEX 0x0605
+#define regMPC_OCSC_TEST_DEBUG_INDEX_BASE_IDX 3
+#define regMPC_OCSC_TEST_DEBUG_DATA 0x0606
+#define regMPC_OCSC_TEST_DEBUG_DATA_BASE_IDX 3
+
+
+// addressBlock: dce_dc_mpc_mpc_rmu_dispdec
+// base address: 0x0
+#define regMPC_RMU_CONTROL 0x0680
+#define regMPC_RMU_CONTROL_BASE_IDX 3
+#define regMPC_RMU_MEM_PWR_CTRL 0x0681
+#define regMPC_RMU_MEM_PWR_CTRL_BASE_IDX 3
+#define regMPC_RMU0_SHAPER_CONTROL 0x0682
+#define regMPC_RMU0_SHAPER_CONTROL_BASE_IDX 3
+#define regMPC_RMU0_SHAPER_OFFSET_R 0x0683
+#define regMPC_RMU0_SHAPER_OFFSET_R_BASE_IDX 3
+#define regMPC_RMU0_SHAPER_OFFSET_G 0x0684
+#define regMPC_RMU0_SHAPER_OFFSET_G_BASE_IDX 3
+#define regMPC_RMU0_SHAPER_OFFSET_B 0x0685
+#define regMPC_RMU0_SHAPER_OFFSET_B_BASE_IDX 3
+#define regMPC_RMU0_SHAPER_SCALE_R 0x0686
+#define regMPC_RMU0_SHAPER_SCALE_R_BASE_IDX 3
+#define regMPC_RMU0_SHAPER_SCALE_G_B 0x0687
+#define regMPC_RMU0_SHAPER_SCALE_G_B_BASE_IDX 3
+#define regMPC_RMU0_SHAPER_LUT_INDEX 0x0688
+#define regMPC_RMU0_SHAPER_LUT_INDEX_BASE_IDX 3
+#define regMPC_RMU0_SHAPER_LUT_DATA 0x0689
+#define regMPC_RMU0_SHAPER_LUT_DATA_BASE_IDX 3
+#define regMPC_RMU0_SHAPER_LUT_WRITE_EN_MASK 0x068a
+#define regMPC_RMU0_SHAPER_LUT_WRITE_EN_MASK_BASE_IDX 3
+#define regMPC_RMU0_SHAPER_RAMA_START_CNTL_B 0x068b
+#define regMPC_RMU0_SHAPER_RAMA_START_CNTL_B_BASE_IDX 3
+#define regMPC_RMU0_SHAPER_RAMA_START_CNTL_G 0x068c
+#define regMPC_RMU0_SHAPER_RAMA_START_CNTL_G_BASE_IDX 3
+#define regMPC_RMU0_SHAPER_RAMA_START_CNTL_R 0x068d
+#define regMPC_RMU0_SHAPER_RAMA_START_CNTL_R_BASE_IDX 3
+#define regMPC_RMU0_SHAPER_RAMA_END_CNTL_B 0x068e
+#define regMPC_RMU0_SHAPER_RAMA_END_CNTL_B_BASE_IDX 3
+#define regMPC_RMU0_SHAPER_RAMA_END_CNTL_G 0x068f
+#define regMPC_RMU0_SHAPER_RAMA_END_CNTL_G_BASE_IDX 3
+#define regMPC_RMU0_SHAPER_RAMA_END_CNTL_R 0x0690
+#define regMPC_RMU0_SHAPER_RAMA_END_CNTL_R_BASE_IDX 3
+#define regMPC_RMU0_SHAPER_RAMA_REGION_0_1 0x0691
+#define regMPC_RMU0_SHAPER_RAMA_REGION_0_1_BASE_IDX 3
+#define regMPC_RMU0_SHAPER_RAMA_REGION_2_3 0x0692
+#define regMPC_RMU0_SHAPER_RAMA_REGION_2_3_BASE_IDX 3
+#define regMPC_RMU0_SHAPER_RAMA_REGION_4_5 0x0693
+#define regMPC_RMU0_SHAPER_RAMA_REGION_4_5_BASE_IDX 3
+#define regMPC_RMU0_SHAPER_RAMA_REGION_6_7 0x0694
+#define regMPC_RMU0_SHAPER_RAMA_REGION_6_7_BASE_IDX 3
+#define regMPC_RMU0_SHAPER_RAMA_REGION_8_9 0x0695
+#define regMPC_RMU0_SHAPER_RAMA_REGION_8_9_BASE_IDX 3
+#define regMPC_RMU0_SHAPER_RAMA_REGION_10_11 0x0696
+#define regMPC_RMU0_SHAPER_RAMA_REGION_10_11_BASE_IDX 3
+#define regMPC_RMU0_SHAPER_RAMA_REGION_12_13 0x0697
+#define regMPC_RMU0_SHAPER_RAMA_REGION_12_13_BASE_IDX 3
+#define regMPC_RMU0_SHAPER_RAMA_REGION_14_15 0x0698
+#define regMPC_RMU0_SHAPER_RAMA_REGION_14_15_BASE_IDX 3
+#define regMPC_RMU0_SHAPER_RAMA_REGION_16_17 0x0699
+#define regMPC_RMU0_SHAPER_RAMA_REGION_16_17_BASE_IDX 3
+#define regMPC_RMU0_SHAPER_RAMA_REGION_18_19 0x069a
+#define regMPC_RMU0_SHAPER_RAMA_REGION_18_19_BASE_IDX 3
+#define regMPC_RMU0_SHAPER_RAMA_REGION_20_21 0x069b
+#define regMPC_RMU0_SHAPER_RAMA_REGION_20_21_BASE_IDX 3
+#define regMPC_RMU0_SHAPER_RAMA_REGION_22_23 0x069c
+#define regMPC_RMU0_SHAPER_RAMA_REGION_22_23_BASE_IDX 3
+#define regMPC_RMU0_SHAPER_RAMA_REGION_24_25 0x069d
+#define regMPC_RMU0_SHAPER_RAMA_REGION_24_25_BASE_IDX 3
+#define regMPC_RMU0_SHAPER_RAMA_REGION_26_27 0x069e
+#define regMPC_RMU0_SHAPER_RAMA_REGION_26_27_BASE_IDX 3
+#define regMPC_RMU0_SHAPER_RAMA_REGION_28_29 0x069f
+#define regMPC_RMU0_SHAPER_RAMA_REGION_28_29_BASE_IDX 3
+#define regMPC_RMU0_SHAPER_RAMA_REGION_30_31 0x06a0
+#define regMPC_RMU0_SHAPER_RAMA_REGION_30_31_BASE_IDX 3
+#define regMPC_RMU0_SHAPER_RAMA_REGION_32_33 0x06a1
+#define regMPC_RMU0_SHAPER_RAMA_REGION_32_33_BASE_IDX 3
+#define regMPC_RMU0_SHAPER_RAMB_START_CNTL_B 0x06a2
+#define regMPC_RMU0_SHAPER_RAMB_START_CNTL_B_BASE_IDX 3
+#define regMPC_RMU0_SHAPER_RAMB_START_CNTL_G 0x06a3
+#define regMPC_RMU0_SHAPER_RAMB_START_CNTL_G_BASE_IDX 3
+#define regMPC_RMU0_SHAPER_RAMB_START_CNTL_R 0x06a4
+#define regMPC_RMU0_SHAPER_RAMB_START_CNTL_R_BASE_IDX 3
+#define regMPC_RMU0_SHAPER_RAMB_END_CNTL_B 0x06a5
+#define regMPC_RMU0_SHAPER_RAMB_END_CNTL_B_BASE_IDX 3
+#define regMPC_RMU0_SHAPER_RAMB_END_CNTL_G 0x06a6
+#define regMPC_RMU0_SHAPER_RAMB_END_CNTL_G_BASE_IDX 3
+#define regMPC_RMU0_SHAPER_RAMB_END_CNTL_R 0x06a7
+#define regMPC_RMU0_SHAPER_RAMB_END_CNTL_R_BASE_IDX 3
+#define regMPC_RMU0_SHAPER_RAMB_REGION_0_1 0x06a8
+#define regMPC_RMU0_SHAPER_RAMB_REGION_0_1_BASE_IDX 3
+#define regMPC_RMU0_SHAPER_RAMB_REGION_2_3 0x06a9
+#define regMPC_RMU0_SHAPER_RAMB_REGION_2_3_BASE_IDX 3
+#define regMPC_RMU0_SHAPER_RAMB_REGION_4_5 0x06aa
+#define regMPC_RMU0_SHAPER_RAMB_REGION_4_5_BASE_IDX 3
+#define regMPC_RMU0_SHAPER_RAMB_REGION_6_7 0x06ab
+#define regMPC_RMU0_SHAPER_RAMB_REGION_6_7_BASE_IDX 3
+#define regMPC_RMU0_SHAPER_RAMB_REGION_8_9 0x06ac
+#define regMPC_RMU0_SHAPER_RAMB_REGION_8_9_BASE_IDX 3
+#define regMPC_RMU0_SHAPER_RAMB_REGION_10_11 0x06ad
+#define regMPC_RMU0_SHAPER_RAMB_REGION_10_11_BASE_IDX 3
+#define regMPC_RMU0_SHAPER_RAMB_REGION_12_13 0x06ae
+#define regMPC_RMU0_SHAPER_RAMB_REGION_12_13_BASE_IDX 3
+#define regMPC_RMU0_SHAPER_RAMB_REGION_14_15 0x06af
+#define regMPC_RMU0_SHAPER_RAMB_REGION_14_15_BASE_IDX 3
+#define regMPC_RMU0_SHAPER_RAMB_REGION_16_17 0x06b0
+#define regMPC_RMU0_SHAPER_RAMB_REGION_16_17_BASE_IDX 3
+#define regMPC_RMU0_SHAPER_RAMB_REGION_18_19 0x06b1
+#define regMPC_RMU0_SHAPER_RAMB_REGION_18_19_BASE_IDX 3
+#define regMPC_RMU0_SHAPER_RAMB_REGION_20_21 0x06b2
+#define regMPC_RMU0_SHAPER_RAMB_REGION_20_21_BASE_IDX 3
+#define regMPC_RMU0_SHAPER_RAMB_REGION_22_23 0x06b3
+#define regMPC_RMU0_SHAPER_RAMB_REGION_22_23_BASE_IDX 3
+#define regMPC_RMU0_SHAPER_RAMB_REGION_24_25 0x06b4
+#define regMPC_RMU0_SHAPER_RAMB_REGION_24_25_BASE_IDX 3
+#define regMPC_RMU0_SHAPER_RAMB_REGION_26_27 0x06b5
+#define regMPC_RMU0_SHAPER_RAMB_REGION_26_27_BASE_IDX 3
+#define regMPC_RMU0_SHAPER_RAMB_REGION_28_29 0x06b6
+#define regMPC_RMU0_SHAPER_RAMB_REGION_28_29_BASE_IDX 3
+#define regMPC_RMU0_SHAPER_RAMB_REGION_30_31 0x06b7
+#define regMPC_RMU0_SHAPER_RAMB_REGION_30_31_BASE_IDX 3
+#define regMPC_RMU0_SHAPER_RAMB_REGION_32_33 0x06b8
+#define regMPC_RMU0_SHAPER_RAMB_REGION_32_33_BASE_IDX 3
+#define regMPC_RMU0_3DLUT_MODE 0x06b9
+#define regMPC_RMU0_3DLUT_MODE_BASE_IDX 3
+#define regMPC_RMU0_3DLUT_INDEX 0x06ba
+#define regMPC_RMU0_3DLUT_INDEX_BASE_IDX 3
+#define regMPC_RMU0_3DLUT_DATA 0x06bb
+#define regMPC_RMU0_3DLUT_DATA_BASE_IDX 3
+#define regMPC_RMU0_3DLUT_DATA_30BIT 0x06bc
+#define regMPC_RMU0_3DLUT_DATA_30BIT_BASE_IDX 3
+#define regMPC_RMU0_3DLUT_READ_WRITE_CONTROL 0x06bd
+#define regMPC_RMU0_3DLUT_READ_WRITE_CONTROL_BASE_IDX 3
+#define regMPC_RMU0_3DLUT_OUT_NORM_FACTOR 0x06be
+#define regMPC_RMU0_3DLUT_OUT_NORM_FACTOR_BASE_IDX 3
+#define regMPC_RMU0_3DLUT_OUT_OFFSET_R 0x06bf
+#define regMPC_RMU0_3DLUT_OUT_OFFSET_R_BASE_IDX 3
+#define regMPC_RMU0_3DLUT_OUT_OFFSET_G 0x06c0
+#define regMPC_RMU0_3DLUT_OUT_OFFSET_G_BASE_IDX 3
+#define regMPC_RMU0_3DLUT_OUT_OFFSET_B 0x06c1
+#define regMPC_RMU0_3DLUT_OUT_OFFSET_B_BASE_IDX 3
+#define regMPC_RMU1_SHAPER_CONTROL 0x06c2
+#define regMPC_RMU1_SHAPER_CONTROL_BASE_IDX 3
+#define regMPC_RMU1_SHAPER_OFFSET_R 0x06c3
+#define regMPC_RMU1_SHAPER_OFFSET_R_BASE_IDX 3
+#define regMPC_RMU1_SHAPER_OFFSET_G 0x06c4
+#define regMPC_RMU1_SHAPER_OFFSET_G_BASE_IDX 3
+#define regMPC_RMU1_SHAPER_OFFSET_B 0x06c5
+#define regMPC_RMU1_SHAPER_OFFSET_B_BASE_IDX 3
+#define regMPC_RMU1_SHAPER_SCALE_R 0x06c6
+#define regMPC_RMU1_SHAPER_SCALE_R_BASE_IDX 3
+#define regMPC_RMU1_SHAPER_SCALE_G_B 0x06c7
+#define regMPC_RMU1_SHAPER_SCALE_G_B_BASE_IDX 3
+#define regMPC_RMU1_SHAPER_LUT_INDEX 0x06c8
+#define regMPC_RMU1_SHAPER_LUT_INDEX_BASE_IDX 3
+#define regMPC_RMU1_SHAPER_LUT_DATA 0x06c9
+#define regMPC_RMU1_SHAPER_LUT_DATA_BASE_IDX 3
+#define regMPC_RMU1_SHAPER_LUT_WRITE_EN_MASK 0x06ca
+#define regMPC_RMU1_SHAPER_LUT_WRITE_EN_MASK_BASE_IDX 3
+#define regMPC_RMU1_SHAPER_RAMA_START_CNTL_B 0x06cb
+#define regMPC_RMU1_SHAPER_RAMA_START_CNTL_B_BASE_IDX 3
+#define regMPC_RMU1_SHAPER_RAMA_START_CNTL_G 0x06cc
+#define regMPC_RMU1_SHAPER_RAMA_START_CNTL_G_BASE_IDX 3
+#define regMPC_RMU1_SHAPER_RAMA_START_CNTL_R 0x06cd
+#define regMPC_RMU1_SHAPER_RAMA_START_CNTL_R_BASE_IDX 3
+#define regMPC_RMU1_SHAPER_RAMA_END_CNTL_B 0x06ce
+#define regMPC_RMU1_SHAPER_RAMA_END_CNTL_B_BASE_IDX 3
+#define regMPC_RMU1_SHAPER_RAMA_END_CNTL_G 0x06cf
+#define regMPC_RMU1_SHAPER_RAMA_END_CNTL_G_BASE_IDX 3
+#define regMPC_RMU1_SHAPER_RAMA_END_CNTL_R 0x06d0
+#define regMPC_RMU1_SHAPER_RAMA_END_CNTL_R_BASE_IDX 3
+#define regMPC_RMU1_SHAPER_RAMA_REGION_0_1 0x06d1
+#define regMPC_RMU1_SHAPER_RAMA_REGION_0_1_BASE_IDX 3
+#define regMPC_RMU1_SHAPER_RAMA_REGION_2_3 0x06d2
+#define regMPC_RMU1_SHAPER_RAMA_REGION_2_3_BASE_IDX 3
+#define regMPC_RMU1_SHAPER_RAMA_REGION_4_5 0x06d3
+#define regMPC_RMU1_SHAPER_RAMA_REGION_4_5_BASE_IDX 3
+#define regMPC_RMU1_SHAPER_RAMA_REGION_6_7 0x06d4
+#define regMPC_RMU1_SHAPER_RAMA_REGION_6_7_BASE_IDX 3
+#define regMPC_RMU1_SHAPER_RAMA_REGION_8_9 0x06d5
+#define regMPC_RMU1_SHAPER_RAMA_REGION_8_9_BASE_IDX 3
+#define regMPC_RMU1_SHAPER_RAMA_REGION_10_11 0x06d6
+#define regMPC_RMU1_SHAPER_RAMA_REGION_10_11_BASE_IDX 3
+#define regMPC_RMU1_SHAPER_RAMA_REGION_12_13 0x06d7
+#define regMPC_RMU1_SHAPER_RAMA_REGION_12_13_BASE_IDX 3
+#define regMPC_RMU1_SHAPER_RAMA_REGION_14_15 0x06d8
+#define regMPC_RMU1_SHAPER_RAMA_REGION_14_15_BASE_IDX 3
+#define regMPC_RMU1_SHAPER_RAMA_REGION_16_17 0x06d9
+#define regMPC_RMU1_SHAPER_RAMA_REGION_16_17_BASE_IDX 3
+#define regMPC_RMU1_SHAPER_RAMA_REGION_18_19 0x06da
+#define regMPC_RMU1_SHAPER_RAMA_REGION_18_19_BASE_IDX 3
+#define regMPC_RMU1_SHAPER_RAMA_REGION_20_21 0x06db
+#define regMPC_RMU1_SHAPER_RAMA_REGION_20_21_BASE_IDX 3
+#define regMPC_RMU1_SHAPER_RAMA_REGION_22_23 0x06dc
+#define regMPC_RMU1_SHAPER_RAMA_REGION_22_23_BASE_IDX 3
+#define regMPC_RMU1_SHAPER_RAMA_REGION_24_25 0x06dd
+#define regMPC_RMU1_SHAPER_RAMA_REGION_24_25_BASE_IDX 3
+#define regMPC_RMU1_SHAPER_RAMA_REGION_26_27 0x06de
+#define regMPC_RMU1_SHAPER_RAMA_REGION_26_27_BASE_IDX 3
+#define regMPC_RMU1_SHAPER_RAMA_REGION_28_29 0x06df
+#define regMPC_RMU1_SHAPER_RAMA_REGION_28_29_BASE_IDX 3
+#define regMPC_RMU1_SHAPER_RAMA_REGION_30_31 0x06e0
+#define regMPC_RMU1_SHAPER_RAMA_REGION_30_31_BASE_IDX 3
+#define regMPC_RMU1_SHAPER_RAMA_REGION_32_33 0x06e1
+#define regMPC_RMU1_SHAPER_RAMA_REGION_32_33_BASE_IDX 3
+#define regMPC_RMU1_SHAPER_RAMB_START_CNTL_B 0x06e2
+#define regMPC_RMU1_SHAPER_RAMB_START_CNTL_B_BASE_IDX 3
+#define regMPC_RMU1_SHAPER_RAMB_START_CNTL_G 0x06e3
+#define regMPC_RMU1_SHAPER_RAMB_START_CNTL_G_BASE_IDX 3
+#define regMPC_RMU1_SHAPER_RAMB_START_CNTL_R 0x06e4
+#define regMPC_RMU1_SHAPER_RAMB_START_CNTL_R_BASE_IDX 3
+#define regMPC_RMU1_SHAPER_RAMB_END_CNTL_B 0x06e5
+#define regMPC_RMU1_SHAPER_RAMB_END_CNTL_B_BASE_IDX 3
+#define regMPC_RMU1_SHAPER_RAMB_END_CNTL_G 0x06e6
+#define regMPC_RMU1_SHAPER_RAMB_END_CNTL_G_BASE_IDX 3
+#define regMPC_RMU1_SHAPER_RAMB_END_CNTL_R 0x06e7
+#define regMPC_RMU1_SHAPER_RAMB_END_CNTL_R_BASE_IDX 3
+#define regMPC_RMU1_SHAPER_RAMB_REGION_0_1 0x06e8
+#define regMPC_RMU1_SHAPER_RAMB_REGION_0_1_BASE_IDX 3
+#define regMPC_RMU1_SHAPER_RAMB_REGION_2_3 0x06e9
+#define regMPC_RMU1_SHAPER_RAMB_REGION_2_3_BASE_IDX 3
+#define regMPC_RMU1_SHAPER_RAMB_REGION_4_5 0x06ea
+#define regMPC_RMU1_SHAPER_RAMB_REGION_4_5_BASE_IDX 3
+#define regMPC_RMU1_SHAPER_RAMB_REGION_6_7 0x06eb
+#define regMPC_RMU1_SHAPER_RAMB_REGION_6_7_BASE_IDX 3
+#define regMPC_RMU1_SHAPER_RAMB_REGION_8_9 0x06ec
+#define regMPC_RMU1_SHAPER_RAMB_REGION_8_9_BASE_IDX 3
+#define regMPC_RMU1_SHAPER_RAMB_REGION_10_11 0x06ed
+#define regMPC_RMU1_SHAPER_RAMB_REGION_10_11_BASE_IDX 3
+#define regMPC_RMU1_SHAPER_RAMB_REGION_12_13 0x06ee
+#define regMPC_RMU1_SHAPER_RAMB_REGION_12_13_BASE_IDX 3
+#define regMPC_RMU1_SHAPER_RAMB_REGION_14_15 0x06ef
+#define regMPC_RMU1_SHAPER_RAMB_REGION_14_15_BASE_IDX 3
+#define regMPC_RMU1_SHAPER_RAMB_REGION_16_17 0x06f0
+#define regMPC_RMU1_SHAPER_RAMB_REGION_16_17_BASE_IDX 3
+#define regMPC_RMU1_SHAPER_RAMB_REGION_18_19 0x06f1
+#define regMPC_RMU1_SHAPER_RAMB_REGION_18_19_BASE_IDX 3
+#define regMPC_RMU1_SHAPER_RAMB_REGION_20_21 0x06f2
+#define regMPC_RMU1_SHAPER_RAMB_REGION_20_21_BASE_IDX 3
+#define regMPC_RMU1_SHAPER_RAMB_REGION_22_23 0x06f3
+#define regMPC_RMU1_SHAPER_RAMB_REGION_22_23_BASE_IDX 3
+#define regMPC_RMU1_SHAPER_RAMB_REGION_24_25 0x06f4
+#define regMPC_RMU1_SHAPER_RAMB_REGION_24_25_BASE_IDX 3
+#define regMPC_RMU1_SHAPER_RAMB_REGION_26_27 0x06f5
+#define regMPC_RMU1_SHAPER_RAMB_REGION_26_27_BASE_IDX 3
+#define regMPC_RMU1_SHAPER_RAMB_REGION_28_29 0x06f6
+#define regMPC_RMU1_SHAPER_RAMB_REGION_28_29_BASE_IDX 3
+#define regMPC_RMU1_SHAPER_RAMB_REGION_30_31 0x06f7
+#define regMPC_RMU1_SHAPER_RAMB_REGION_30_31_BASE_IDX 3
+#define regMPC_RMU1_SHAPER_RAMB_REGION_32_33 0x06f8
+#define regMPC_RMU1_SHAPER_RAMB_REGION_32_33_BASE_IDX 3
+#define regMPC_RMU1_3DLUT_MODE 0x06f9
+#define regMPC_RMU1_3DLUT_MODE_BASE_IDX 3
+#define regMPC_RMU1_3DLUT_INDEX 0x06fa
+#define regMPC_RMU1_3DLUT_INDEX_BASE_IDX 3
+#define regMPC_RMU1_3DLUT_DATA 0x06fb
+#define regMPC_RMU1_3DLUT_DATA_BASE_IDX 3
+#define regMPC_RMU1_3DLUT_DATA_30BIT 0x06fc
+#define regMPC_RMU1_3DLUT_DATA_30BIT_BASE_IDX 3
+#define regMPC_RMU1_3DLUT_READ_WRITE_CONTROL 0x06fd
+#define regMPC_RMU1_3DLUT_READ_WRITE_CONTROL_BASE_IDX 3
+#define regMPC_RMU1_3DLUT_OUT_NORM_FACTOR 0x06fe
+#define regMPC_RMU1_3DLUT_OUT_NORM_FACTOR_BASE_IDX 3
+#define regMPC_RMU1_3DLUT_OUT_OFFSET_R 0x06ff
+#define regMPC_RMU1_3DLUT_OUT_OFFSET_R_BASE_IDX 3
+#define regMPC_RMU1_3DLUT_OUT_OFFSET_G 0x0700
+#define regMPC_RMU1_3DLUT_OUT_OFFSET_G_BASE_IDX 3
+#define regMPC_RMU1_3DLUT_OUT_OFFSET_B 0x0701
+#define regMPC_RMU1_3DLUT_OUT_OFFSET_B_BASE_IDX 3
+
+
+// addressBlock: dce_dc_opp_abm0_dispdec
+// base address: 0x0
+#define regABM0_BL1_PWM_AMBIENT_LIGHT_LEVEL 0x0e7a
+#define regABM0_BL1_PWM_AMBIENT_LIGHT_LEVEL_BASE_IDX 3
+#define regABM0_BL1_PWM_USER_LEVEL 0x0e7b
+#define regABM0_BL1_PWM_USER_LEVEL_BASE_IDX 3
+#define regABM0_BL1_PWM_TARGET_ABM_LEVEL 0x0e7c
+#define regABM0_BL1_PWM_TARGET_ABM_LEVEL_BASE_IDX 3
+#define regABM0_BL1_PWM_CURRENT_ABM_LEVEL 0x0e7d
+#define regABM0_BL1_PWM_CURRENT_ABM_LEVEL_BASE_IDX 3
+#define regABM0_BL1_PWM_FINAL_DUTY_CYCLE 0x0e7e
+#define regABM0_BL1_PWM_FINAL_DUTY_CYCLE_BASE_IDX 3
+#define regABM0_BL1_PWM_MINIMUM_DUTY_CYCLE 0x0e7f
+#define regABM0_BL1_PWM_MINIMUM_DUTY_CYCLE_BASE_IDX 3
+#define regABM0_BL1_PWM_ABM_CNTL 0x0e80
+#define regABM0_BL1_PWM_ABM_CNTL_BASE_IDX 3
+#define regABM0_BL1_PWM_BL_UPDATE_SAMPLE_RATE 0x0e81
+#define regABM0_BL1_PWM_BL_UPDATE_SAMPLE_RATE_BASE_IDX 3
+#define regABM0_BL1_PWM_GRP2_REG_LOCK 0x0e82
+#define regABM0_BL1_PWM_GRP2_REG_LOCK_BASE_IDX 3
+#define regABM0_DC_ABM1_CNTL 0x0e83
+#define regABM0_DC_ABM1_CNTL_BASE_IDX 3
+#define regABM0_DC_ABM1_IPCSC_COEFF_SEL 0x0e84
+#define regABM0_DC_ABM1_IPCSC_COEFF_SEL_BASE_IDX 3
+#define regABM0_DC_ABM1_ACE_OFFSET_SLOPE_0 0x0e85
+#define regABM0_DC_ABM1_ACE_OFFSET_SLOPE_0_BASE_IDX 3
+#define regABM0_DC_ABM1_ACE_OFFSET_SLOPE_1 0x0e86
+#define regABM0_DC_ABM1_ACE_OFFSET_SLOPE_1_BASE_IDX 3
+#define regABM0_DC_ABM1_ACE_OFFSET_SLOPE_2 0x0e87
+#define regABM0_DC_ABM1_ACE_OFFSET_SLOPE_2_BASE_IDX 3
+#define regABM0_DC_ABM1_ACE_OFFSET_SLOPE_3 0x0e88
+#define regABM0_DC_ABM1_ACE_OFFSET_SLOPE_3_BASE_IDX 3
+#define regABM0_DC_ABM1_ACE_OFFSET_SLOPE_4 0x0e89
+#define regABM0_DC_ABM1_ACE_OFFSET_SLOPE_4_BASE_IDX 3
+#define regABM0_DC_ABM1_ACE_THRES_12 0x0e8a
+#define regABM0_DC_ABM1_ACE_THRES_12_BASE_IDX 3
+#define regABM0_DC_ABM1_ACE_THRES_34 0x0e8b
+#define regABM0_DC_ABM1_ACE_THRES_34_BASE_IDX 3
+#define regABM0_DC_ABM1_ACE_CNTL_MISC 0x0e8c
+#define regABM0_DC_ABM1_ACE_CNTL_MISC_BASE_IDX 3
+#define regABM0_DC_ABM1_HGLS_REG_READ_PROGRESS 0x0e8e
+#define regABM0_DC_ABM1_HGLS_REG_READ_PROGRESS_BASE_IDX 3
+#define regABM0_DC_ABM1_HG_MISC_CTRL 0x0e8f
+#define regABM0_DC_ABM1_HG_MISC_CTRL_BASE_IDX 3
+#define regABM0_DC_ABM1_LS_SUM_OF_LUMA 0x0e90
+#define regABM0_DC_ABM1_LS_SUM_OF_LUMA_BASE_IDX 3
+#define regABM0_DC_ABM1_LS_MIN_MAX_LUMA 0x0e91
+#define regABM0_DC_ABM1_LS_MIN_MAX_LUMA_BASE_IDX 3
+#define regABM0_DC_ABM1_LS_FILTERED_MIN_MAX_LUMA 0x0e92
+#define regABM0_DC_ABM1_LS_FILTERED_MIN_MAX_LUMA_BASE_IDX 3
+#define regABM0_DC_ABM1_LS_PIXEL_COUNT 0x0e93
+#define regABM0_DC_ABM1_LS_PIXEL_COUNT_BASE_IDX 3
+#define regABM0_DC_ABM1_LS_MIN_MAX_PIXEL_VALUE_THRES 0x0e94
+#define regABM0_DC_ABM1_LS_MIN_MAX_PIXEL_VALUE_THRES_BASE_IDX 3
+#define regABM0_DC_ABM1_LS_MIN_PIXEL_VALUE_COUNT 0x0e95
+#define regABM0_DC_ABM1_LS_MIN_PIXEL_VALUE_COUNT_BASE_IDX 3
+#define regABM0_DC_ABM1_LS_MAX_PIXEL_VALUE_COUNT 0x0e96
+#define regABM0_DC_ABM1_LS_MAX_PIXEL_VALUE_COUNT_BASE_IDX 3
+#define regABM0_DC_ABM1_HG_SAMPLE_RATE 0x0e97
+#define regABM0_DC_ABM1_HG_SAMPLE_RATE_BASE_IDX 3
+#define regABM0_DC_ABM1_LS_SAMPLE_RATE 0x0e98
+#define regABM0_DC_ABM1_LS_SAMPLE_RATE_BASE_IDX 3
+#define regABM0_DC_ABM1_HG_BIN_1_32_SHIFT_FLAG 0x0e99
+#define regABM0_DC_ABM1_HG_BIN_1_32_SHIFT_FLAG_BASE_IDX 3
+#define regABM0_DC_ABM1_HG_BIN_1_8_SHIFT_INDEX 0x0e9a
+#define regABM0_DC_ABM1_HG_BIN_1_8_SHIFT_INDEX_BASE_IDX 3
+#define regABM0_DC_ABM1_HG_BIN_9_16_SHIFT_INDEX 0x0e9b
+#define regABM0_DC_ABM1_HG_BIN_9_16_SHIFT_INDEX_BASE_IDX 3
+#define regABM0_DC_ABM1_HG_BIN_17_24_SHIFT_INDEX 0x0e9c
+#define regABM0_DC_ABM1_HG_BIN_17_24_SHIFT_INDEX_BASE_IDX 3
+#define regABM0_DC_ABM1_HG_BIN_25_32_SHIFT_INDEX 0x0e9d
+#define regABM0_DC_ABM1_HG_BIN_25_32_SHIFT_INDEX_BASE_IDX 3
+#define regABM0_DC_ABM1_HG_RESULT_1 0x0e9e
+#define regABM0_DC_ABM1_HG_RESULT_1_BASE_IDX 3
+#define regABM0_DC_ABM1_HG_RESULT_2 0x0e9f
+#define regABM0_DC_ABM1_HG_RESULT_2_BASE_IDX 3
+#define regABM0_DC_ABM1_HG_RESULT_3 0x0ea0
+#define regABM0_DC_ABM1_HG_RESULT_3_BASE_IDX 3
+#define regABM0_DC_ABM1_HG_RESULT_4 0x0ea1
+#define regABM0_DC_ABM1_HG_RESULT_4_BASE_IDX 3
+#define regABM0_DC_ABM1_HG_RESULT_5 0x0ea2
+#define regABM0_DC_ABM1_HG_RESULT_5_BASE_IDX 3
+#define regABM0_DC_ABM1_HG_RESULT_6 0x0ea3
+#define regABM0_DC_ABM1_HG_RESULT_6_BASE_IDX 3
+#define regABM0_DC_ABM1_HG_RESULT_7 0x0ea4
+#define regABM0_DC_ABM1_HG_RESULT_7_BASE_IDX 3
+#define regABM0_DC_ABM1_HG_RESULT_8 0x0ea5
+#define regABM0_DC_ABM1_HG_RESULT_8_BASE_IDX 3
+#define regABM0_DC_ABM1_HG_RESULT_9 0x0ea6
+#define regABM0_DC_ABM1_HG_RESULT_9_BASE_IDX 3
+#define regABM0_DC_ABM1_HG_RESULT_10 0x0ea7
+#define regABM0_DC_ABM1_HG_RESULT_10_BASE_IDX 3
+#define regABM0_DC_ABM1_HG_RESULT_11 0x0ea8
+#define regABM0_DC_ABM1_HG_RESULT_11_BASE_IDX 3
+#define regABM0_DC_ABM1_HG_RESULT_12 0x0ea9
+#define regABM0_DC_ABM1_HG_RESULT_12_BASE_IDX 3
+#define regABM0_DC_ABM1_HG_RESULT_13 0x0eaa
+#define regABM0_DC_ABM1_HG_RESULT_13_BASE_IDX 3
+#define regABM0_DC_ABM1_HG_RESULT_14 0x0eab
+#define regABM0_DC_ABM1_HG_RESULT_14_BASE_IDX 3
+#define regABM0_DC_ABM1_HG_RESULT_15 0x0eac
+#define regABM0_DC_ABM1_HG_RESULT_15_BASE_IDX 3
+#define regABM0_DC_ABM1_HG_RESULT_16 0x0ead
+#define regABM0_DC_ABM1_HG_RESULT_16_BASE_IDX 3
+#define regABM0_DC_ABM1_HG_RESULT_17 0x0eae
+#define regABM0_DC_ABM1_HG_RESULT_17_BASE_IDX 3
+#define regABM0_DC_ABM1_HG_RESULT_18 0x0eaf
+#define regABM0_DC_ABM1_HG_RESULT_18_BASE_IDX 3
+#define regABM0_DC_ABM1_HG_RESULT_19 0x0eb0
+#define regABM0_DC_ABM1_HG_RESULT_19_BASE_IDX 3
+#define regABM0_DC_ABM1_HG_RESULT_20 0x0eb1
+#define regABM0_DC_ABM1_HG_RESULT_20_BASE_IDX 3
+#define regABM0_DC_ABM1_HG_RESULT_21 0x0eb2
+#define regABM0_DC_ABM1_HG_RESULT_21_BASE_IDX 3
+#define regABM0_DC_ABM1_HG_RESULT_22 0x0eb3
+#define regABM0_DC_ABM1_HG_RESULT_22_BASE_IDX 3
+#define regABM0_DC_ABM1_HG_RESULT_23 0x0eb4
+#define regABM0_DC_ABM1_HG_RESULT_23_BASE_IDX 3
+#define regABM0_DC_ABM1_HG_RESULT_24 0x0eb5
+#define regABM0_DC_ABM1_HG_RESULT_24_BASE_IDX 3
+#define regABM0_DC_ABM1_BL_MASTER_LOCK 0x0eb6
+#define regABM0_DC_ABM1_BL_MASTER_LOCK_BASE_IDX 3
+
+
+// addressBlock: dce_dc_opp_abm1_dispdec
+// base address: 0x104
+#define regABM1_BL1_PWM_AMBIENT_LIGHT_LEVEL 0x0ebb
+#define regABM1_BL1_PWM_AMBIENT_LIGHT_LEVEL_BASE_IDX 3
+#define regABM1_BL1_PWM_USER_LEVEL 0x0ebc
+#define regABM1_BL1_PWM_USER_LEVEL_BASE_IDX 3
+#define regABM1_BL1_PWM_TARGET_ABM_LEVEL 0x0ebd
+#define regABM1_BL1_PWM_TARGET_ABM_LEVEL_BASE_IDX 3
+#define regABM1_BL1_PWM_CURRENT_ABM_LEVEL 0x0ebe
+#define regABM1_BL1_PWM_CURRENT_ABM_LEVEL_BASE_IDX 3
+#define regABM1_BL1_PWM_FINAL_DUTY_CYCLE 0x0ebf
+#define regABM1_BL1_PWM_FINAL_DUTY_CYCLE_BASE_IDX 3
+#define regABM1_BL1_PWM_MINIMUM_DUTY_CYCLE 0x0ec0
+#define regABM1_BL1_PWM_MINIMUM_DUTY_CYCLE_BASE_IDX 3
+#define regABM1_BL1_PWM_ABM_CNTL 0x0ec1
+#define regABM1_BL1_PWM_ABM_CNTL_BASE_IDX 3
+#define regABM1_BL1_PWM_BL_UPDATE_SAMPLE_RATE 0x0ec2
+#define regABM1_BL1_PWM_BL_UPDATE_SAMPLE_RATE_BASE_IDX 3
+#define regABM1_BL1_PWM_GRP2_REG_LOCK 0x0ec3
+#define regABM1_BL1_PWM_GRP2_REG_LOCK_BASE_IDX 3
+#define regABM1_DC_ABM1_CNTL 0x0ec4
+#define regABM1_DC_ABM1_CNTL_BASE_IDX 3
+#define regABM1_DC_ABM1_IPCSC_COEFF_SEL 0x0ec5
+#define regABM1_DC_ABM1_IPCSC_COEFF_SEL_BASE_IDX 3
+#define regABM1_DC_ABM1_ACE_OFFSET_SLOPE_0 0x0ec6
+#define regABM1_DC_ABM1_ACE_OFFSET_SLOPE_0_BASE_IDX 3
+#define regABM1_DC_ABM1_ACE_OFFSET_SLOPE_1 0x0ec7
+#define regABM1_DC_ABM1_ACE_OFFSET_SLOPE_1_BASE_IDX 3
+#define regABM1_DC_ABM1_ACE_OFFSET_SLOPE_2 0x0ec8
+#define regABM1_DC_ABM1_ACE_OFFSET_SLOPE_2_BASE_IDX 3
+#define regABM1_DC_ABM1_ACE_OFFSET_SLOPE_3 0x0ec9
+#define regABM1_DC_ABM1_ACE_OFFSET_SLOPE_3_BASE_IDX 3
+#define regABM1_DC_ABM1_ACE_OFFSET_SLOPE_4 0x0eca
+#define regABM1_DC_ABM1_ACE_OFFSET_SLOPE_4_BASE_IDX 3
+#define regABM1_DC_ABM1_ACE_THRES_12 0x0ecb
+#define regABM1_DC_ABM1_ACE_THRES_12_BASE_IDX 3
+#define regABM1_DC_ABM1_ACE_THRES_34 0x0ecc
+#define regABM1_DC_ABM1_ACE_THRES_34_BASE_IDX 3
+#define regABM1_DC_ABM1_ACE_CNTL_MISC 0x0ecd
+#define regABM1_DC_ABM1_ACE_CNTL_MISC_BASE_IDX 3
+#define regABM1_DC_ABM1_HGLS_REG_READ_PROGRESS 0x0ecf
+#define regABM1_DC_ABM1_HGLS_REG_READ_PROGRESS_BASE_IDX 3
+#define regABM1_DC_ABM1_HG_MISC_CTRL 0x0ed0
+#define regABM1_DC_ABM1_HG_MISC_CTRL_BASE_IDX 3
+#define regABM1_DC_ABM1_LS_SUM_OF_LUMA 0x0ed1
+#define regABM1_DC_ABM1_LS_SUM_OF_LUMA_BASE_IDX 3
+#define regABM1_DC_ABM1_LS_MIN_MAX_LUMA 0x0ed2
+#define regABM1_DC_ABM1_LS_MIN_MAX_LUMA_BASE_IDX 3
+#define regABM1_DC_ABM1_LS_FILTERED_MIN_MAX_LUMA 0x0ed3
+#define regABM1_DC_ABM1_LS_FILTERED_MIN_MAX_LUMA_BASE_IDX 3
+#define regABM1_DC_ABM1_LS_PIXEL_COUNT 0x0ed4
+#define regABM1_DC_ABM1_LS_PIXEL_COUNT_BASE_IDX 3
+#define regABM1_DC_ABM1_LS_MIN_MAX_PIXEL_VALUE_THRES 0x0ed5
+#define regABM1_DC_ABM1_LS_MIN_MAX_PIXEL_VALUE_THRES_BASE_IDX 3
+#define regABM1_DC_ABM1_LS_MIN_PIXEL_VALUE_COUNT 0x0ed6
+#define regABM1_DC_ABM1_LS_MIN_PIXEL_VALUE_COUNT_BASE_IDX 3
+#define regABM1_DC_ABM1_LS_MAX_PIXEL_VALUE_COUNT 0x0ed7
+#define regABM1_DC_ABM1_LS_MAX_PIXEL_VALUE_COUNT_BASE_IDX 3
+#define regABM1_DC_ABM1_HG_SAMPLE_RATE 0x0ed8
+#define regABM1_DC_ABM1_HG_SAMPLE_RATE_BASE_IDX 3
+#define regABM1_DC_ABM1_LS_SAMPLE_RATE 0x0ed9
+#define regABM1_DC_ABM1_LS_SAMPLE_RATE_BASE_IDX 3
+#define regABM1_DC_ABM1_HG_BIN_1_32_SHIFT_FLAG 0x0eda
+#define regABM1_DC_ABM1_HG_BIN_1_32_SHIFT_FLAG_BASE_IDX 3
+#define regABM1_DC_ABM1_HG_BIN_1_8_SHIFT_INDEX 0x0edb
+#define regABM1_DC_ABM1_HG_BIN_1_8_SHIFT_INDEX_BASE_IDX 3
+#define regABM1_DC_ABM1_HG_BIN_9_16_SHIFT_INDEX 0x0edc
+#define regABM1_DC_ABM1_HG_BIN_9_16_SHIFT_INDEX_BASE_IDX 3
+#define regABM1_DC_ABM1_HG_BIN_17_24_SHIFT_INDEX 0x0edd
+#define regABM1_DC_ABM1_HG_BIN_17_24_SHIFT_INDEX_BASE_IDX 3
+#define regABM1_DC_ABM1_HG_BIN_25_32_SHIFT_INDEX 0x0ede
+#define regABM1_DC_ABM1_HG_BIN_25_32_SHIFT_INDEX_BASE_IDX 3
+#define regABM1_DC_ABM1_HG_RESULT_1 0x0edf
+#define regABM1_DC_ABM1_HG_RESULT_1_BASE_IDX 3
+#define regABM1_DC_ABM1_HG_RESULT_2 0x0ee0
+#define regABM1_DC_ABM1_HG_RESULT_2_BASE_IDX 3
+#define regABM1_DC_ABM1_HG_RESULT_3 0x0ee1
+#define regABM1_DC_ABM1_HG_RESULT_3_BASE_IDX 3
+#define regABM1_DC_ABM1_HG_RESULT_4 0x0ee2
+#define regABM1_DC_ABM1_HG_RESULT_4_BASE_IDX 3
+#define regABM1_DC_ABM1_HG_RESULT_5 0x0ee3
+#define regABM1_DC_ABM1_HG_RESULT_5_BASE_IDX 3
+#define regABM1_DC_ABM1_HG_RESULT_6 0x0ee4
+#define regABM1_DC_ABM1_HG_RESULT_6_BASE_IDX 3
+#define regABM1_DC_ABM1_HG_RESULT_7 0x0ee5
+#define regABM1_DC_ABM1_HG_RESULT_7_BASE_IDX 3
+#define regABM1_DC_ABM1_HG_RESULT_8 0x0ee6
+#define regABM1_DC_ABM1_HG_RESULT_8_BASE_IDX 3
+#define regABM1_DC_ABM1_HG_RESULT_9 0x0ee7
+#define regABM1_DC_ABM1_HG_RESULT_9_BASE_IDX 3
+#define regABM1_DC_ABM1_HG_RESULT_10 0x0ee8
+#define regABM1_DC_ABM1_HG_RESULT_10_BASE_IDX 3
+#define regABM1_DC_ABM1_HG_RESULT_11 0x0ee9
+#define regABM1_DC_ABM1_HG_RESULT_11_BASE_IDX 3
+#define regABM1_DC_ABM1_HG_RESULT_12 0x0eea
+#define regABM1_DC_ABM1_HG_RESULT_12_BASE_IDX 3
+#define regABM1_DC_ABM1_HG_RESULT_13 0x0eeb
+#define regABM1_DC_ABM1_HG_RESULT_13_BASE_IDX 3
+#define regABM1_DC_ABM1_HG_RESULT_14 0x0eec
+#define regABM1_DC_ABM1_HG_RESULT_14_BASE_IDX 3
+#define regABM1_DC_ABM1_HG_RESULT_15 0x0eed
+#define regABM1_DC_ABM1_HG_RESULT_15_BASE_IDX 3
+#define regABM1_DC_ABM1_HG_RESULT_16 0x0eee
+#define regABM1_DC_ABM1_HG_RESULT_16_BASE_IDX 3
+#define regABM1_DC_ABM1_HG_RESULT_17 0x0eef
+#define regABM1_DC_ABM1_HG_RESULT_17_BASE_IDX 3
+#define regABM1_DC_ABM1_HG_RESULT_18 0x0ef0
+#define regABM1_DC_ABM1_HG_RESULT_18_BASE_IDX 3
+#define regABM1_DC_ABM1_HG_RESULT_19 0x0ef1
+#define regABM1_DC_ABM1_HG_RESULT_19_BASE_IDX 3
+#define regABM1_DC_ABM1_HG_RESULT_20 0x0ef2
+#define regABM1_DC_ABM1_HG_RESULT_20_BASE_IDX 3
+#define regABM1_DC_ABM1_HG_RESULT_21 0x0ef3
+#define regABM1_DC_ABM1_HG_RESULT_21_BASE_IDX 3
+#define regABM1_DC_ABM1_HG_RESULT_22 0x0ef4
+#define regABM1_DC_ABM1_HG_RESULT_22_BASE_IDX 3
+#define regABM1_DC_ABM1_HG_RESULT_23 0x0ef5
+#define regABM1_DC_ABM1_HG_RESULT_23_BASE_IDX 3
+#define regABM1_DC_ABM1_HG_RESULT_24 0x0ef6
+#define regABM1_DC_ABM1_HG_RESULT_24_BASE_IDX 3
+#define regABM1_DC_ABM1_BL_MASTER_LOCK 0x0ef7
+#define regABM1_DC_ABM1_BL_MASTER_LOCK_BASE_IDX 3
+
+
+// addressBlock: dce_dc_opp_abm2_dispdec
+// base address: 0x208
+#define regABM2_BL1_PWM_AMBIENT_LIGHT_LEVEL 0x0efc
+#define regABM2_BL1_PWM_AMBIENT_LIGHT_LEVEL_BASE_IDX 3
+#define regABM2_BL1_PWM_USER_LEVEL 0x0efd
+#define regABM2_BL1_PWM_USER_LEVEL_BASE_IDX 3
+#define regABM2_BL1_PWM_TARGET_ABM_LEVEL 0x0efe
+#define regABM2_BL1_PWM_TARGET_ABM_LEVEL_BASE_IDX 3
+#define regABM2_BL1_PWM_CURRENT_ABM_LEVEL 0x0eff
+#define regABM2_BL1_PWM_CURRENT_ABM_LEVEL_BASE_IDX 3
+#define regABM2_BL1_PWM_FINAL_DUTY_CYCLE 0x0f00
+#define regABM2_BL1_PWM_FINAL_DUTY_CYCLE_BASE_IDX 3
+#define regABM2_BL1_PWM_MINIMUM_DUTY_CYCLE 0x0f01
+#define regABM2_BL1_PWM_MINIMUM_DUTY_CYCLE_BASE_IDX 3
+#define regABM2_BL1_PWM_ABM_CNTL 0x0f02
+#define regABM2_BL1_PWM_ABM_CNTL_BASE_IDX 3
+#define regABM2_BL1_PWM_BL_UPDATE_SAMPLE_RATE 0x0f03
+#define regABM2_BL1_PWM_BL_UPDATE_SAMPLE_RATE_BASE_IDX 3
+#define regABM2_BL1_PWM_GRP2_REG_LOCK 0x0f04
+#define regABM2_BL1_PWM_GRP2_REG_LOCK_BASE_IDX 3
+#define regABM2_DC_ABM1_CNTL 0x0f05
+#define regABM2_DC_ABM1_CNTL_BASE_IDX 3
+#define regABM2_DC_ABM1_IPCSC_COEFF_SEL 0x0f06
+#define regABM2_DC_ABM1_IPCSC_COEFF_SEL_BASE_IDX 3
+#define regABM2_DC_ABM1_ACE_OFFSET_SLOPE_0 0x0f07
+#define regABM2_DC_ABM1_ACE_OFFSET_SLOPE_0_BASE_IDX 3
+#define regABM2_DC_ABM1_ACE_OFFSET_SLOPE_1 0x0f08
+#define regABM2_DC_ABM1_ACE_OFFSET_SLOPE_1_BASE_IDX 3
+#define regABM2_DC_ABM1_ACE_OFFSET_SLOPE_2 0x0f09
+#define regABM2_DC_ABM1_ACE_OFFSET_SLOPE_2_BASE_IDX 3
+#define regABM2_DC_ABM1_ACE_OFFSET_SLOPE_3 0x0f0a
+#define regABM2_DC_ABM1_ACE_OFFSET_SLOPE_3_BASE_IDX 3
+#define regABM2_DC_ABM1_ACE_OFFSET_SLOPE_4 0x0f0b
+#define regABM2_DC_ABM1_ACE_OFFSET_SLOPE_4_BASE_IDX 3
+#define regABM2_DC_ABM1_ACE_THRES_12 0x0f0c
+#define regABM2_DC_ABM1_ACE_THRES_12_BASE_IDX 3
+#define regABM2_DC_ABM1_ACE_THRES_34 0x0f0d
+#define regABM2_DC_ABM1_ACE_THRES_34_BASE_IDX 3
+#define regABM2_DC_ABM1_ACE_CNTL_MISC 0x0f0e
+#define regABM2_DC_ABM1_ACE_CNTL_MISC_BASE_IDX 3
+#define regABM2_DC_ABM1_HGLS_REG_READ_PROGRESS 0x0f10
+#define regABM2_DC_ABM1_HGLS_REG_READ_PROGRESS_BASE_IDX 3
+#define regABM2_DC_ABM1_HG_MISC_CTRL 0x0f11
+#define regABM2_DC_ABM1_HG_MISC_CTRL_BASE_IDX 3
+#define regABM2_DC_ABM1_LS_SUM_OF_LUMA 0x0f12
+#define regABM2_DC_ABM1_LS_SUM_OF_LUMA_BASE_IDX 3
+#define regABM2_DC_ABM1_LS_MIN_MAX_LUMA 0x0f13
+#define regABM2_DC_ABM1_LS_MIN_MAX_LUMA_BASE_IDX 3
+#define regABM2_DC_ABM1_LS_FILTERED_MIN_MAX_LUMA 0x0f14
+#define regABM2_DC_ABM1_LS_FILTERED_MIN_MAX_LUMA_BASE_IDX 3
+#define regABM2_DC_ABM1_LS_PIXEL_COUNT 0x0f15
+#define regABM2_DC_ABM1_LS_PIXEL_COUNT_BASE_IDX 3
+#define regABM2_DC_ABM1_LS_MIN_MAX_PIXEL_VALUE_THRES 0x0f16
+#define regABM2_DC_ABM1_LS_MIN_MAX_PIXEL_VALUE_THRES_BASE_IDX 3
+#define regABM2_DC_ABM1_LS_MIN_PIXEL_VALUE_COUNT 0x0f17
+#define regABM2_DC_ABM1_LS_MIN_PIXEL_VALUE_COUNT_BASE_IDX 3
+#define regABM2_DC_ABM1_LS_MAX_PIXEL_VALUE_COUNT 0x0f18
+#define regABM2_DC_ABM1_LS_MAX_PIXEL_VALUE_COUNT_BASE_IDX 3
+#define regABM2_DC_ABM1_HG_SAMPLE_RATE 0x0f19
+#define regABM2_DC_ABM1_HG_SAMPLE_RATE_BASE_IDX 3
+#define regABM2_DC_ABM1_LS_SAMPLE_RATE 0x0f1a
+#define regABM2_DC_ABM1_LS_SAMPLE_RATE_BASE_IDX 3
+#define regABM2_DC_ABM1_HG_BIN_1_32_SHIFT_FLAG 0x0f1b
+#define regABM2_DC_ABM1_HG_BIN_1_32_SHIFT_FLAG_BASE_IDX 3
+#define regABM2_DC_ABM1_HG_BIN_1_8_SHIFT_INDEX 0x0f1c
+#define regABM2_DC_ABM1_HG_BIN_1_8_SHIFT_INDEX_BASE_IDX 3
+#define regABM2_DC_ABM1_HG_BIN_9_16_SHIFT_INDEX 0x0f1d
+#define regABM2_DC_ABM1_HG_BIN_9_16_SHIFT_INDEX_BASE_IDX 3
+#define regABM2_DC_ABM1_HG_BIN_17_24_SHIFT_INDEX 0x0f1e
+#define regABM2_DC_ABM1_HG_BIN_17_24_SHIFT_INDEX_BASE_IDX 3
+#define regABM2_DC_ABM1_HG_BIN_25_32_SHIFT_INDEX 0x0f1f
+#define regABM2_DC_ABM1_HG_BIN_25_32_SHIFT_INDEX_BASE_IDX 3
+#define regABM2_DC_ABM1_HG_RESULT_1 0x0f20
+#define regABM2_DC_ABM1_HG_RESULT_1_BASE_IDX 3
+#define regABM2_DC_ABM1_HG_RESULT_2 0x0f21
+#define regABM2_DC_ABM1_HG_RESULT_2_BASE_IDX 3
+#define regABM2_DC_ABM1_HG_RESULT_3 0x0f22
+#define regABM2_DC_ABM1_HG_RESULT_3_BASE_IDX 3
+#define regABM2_DC_ABM1_HG_RESULT_4 0x0f23
+#define regABM2_DC_ABM1_HG_RESULT_4_BASE_IDX 3
+#define regABM2_DC_ABM1_HG_RESULT_5 0x0f24
+#define regABM2_DC_ABM1_HG_RESULT_5_BASE_IDX 3
+#define regABM2_DC_ABM1_HG_RESULT_6 0x0f25
+#define regABM2_DC_ABM1_HG_RESULT_6_BASE_IDX 3
+#define regABM2_DC_ABM1_HG_RESULT_7 0x0f26
+#define regABM2_DC_ABM1_HG_RESULT_7_BASE_IDX 3
+#define regABM2_DC_ABM1_HG_RESULT_8 0x0f27
+#define regABM2_DC_ABM1_HG_RESULT_8_BASE_IDX 3
+#define regABM2_DC_ABM1_HG_RESULT_9 0x0f28
+#define regABM2_DC_ABM1_HG_RESULT_9_BASE_IDX 3
+#define regABM2_DC_ABM1_HG_RESULT_10 0x0f29
+#define regABM2_DC_ABM1_HG_RESULT_10_BASE_IDX 3
+#define regABM2_DC_ABM1_HG_RESULT_11 0x0f2a
+#define regABM2_DC_ABM1_HG_RESULT_11_BASE_IDX 3
+#define regABM2_DC_ABM1_HG_RESULT_12 0x0f2b
+#define regABM2_DC_ABM1_HG_RESULT_12_BASE_IDX 3
+#define regABM2_DC_ABM1_HG_RESULT_13 0x0f2c
+#define regABM2_DC_ABM1_HG_RESULT_13_BASE_IDX 3
+#define regABM2_DC_ABM1_HG_RESULT_14 0x0f2d
+#define regABM2_DC_ABM1_HG_RESULT_14_BASE_IDX 3
+#define regABM2_DC_ABM1_HG_RESULT_15 0x0f2e
+#define regABM2_DC_ABM1_HG_RESULT_15_BASE_IDX 3
+#define regABM2_DC_ABM1_HG_RESULT_16 0x0f2f
+#define regABM2_DC_ABM1_HG_RESULT_16_BASE_IDX 3
+#define regABM2_DC_ABM1_HG_RESULT_17 0x0f30
+#define regABM2_DC_ABM1_HG_RESULT_17_BASE_IDX 3
+#define regABM2_DC_ABM1_HG_RESULT_18 0x0f31
+#define regABM2_DC_ABM1_HG_RESULT_18_BASE_IDX 3
+#define regABM2_DC_ABM1_HG_RESULT_19 0x0f32
+#define regABM2_DC_ABM1_HG_RESULT_19_BASE_IDX 3
+#define regABM2_DC_ABM1_HG_RESULT_20 0x0f33
+#define regABM2_DC_ABM1_HG_RESULT_20_BASE_IDX 3
+#define regABM2_DC_ABM1_HG_RESULT_21 0x0f34
+#define regABM2_DC_ABM1_HG_RESULT_21_BASE_IDX 3
+#define regABM2_DC_ABM1_HG_RESULT_22 0x0f35
+#define regABM2_DC_ABM1_HG_RESULT_22_BASE_IDX 3
+#define regABM2_DC_ABM1_HG_RESULT_23 0x0f36
+#define regABM2_DC_ABM1_HG_RESULT_23_BASE_IDX 3
+#define regABM2_DC_ABM1_HG_RESULT_24 0x0f37
+#define regABM2_DC_ABM1_HG_RESULT_24_BASE_IDX 3
+#define regABM2_DC_ABM1_BL_MASTER_LOCK 0x0f38
+#define regABM2_DC_ABM1_BL_MASTER_LOCK_BASE_IDX 3
+
+
+// addressBlock: dce_dc_opp_abm3_dispdec
+// base address: 0x30c
+#define regABM3_BL1_PWM_AMBIENT_LIGHT_LEVEL 0x0f3d
+#define regABM3_BL1_PWM_AMBIENT_LIGHT_LEVEL_BASE_IDX 3
+#define regABM3_BL1_PWM_USER_LEVEL 0x0f3e
+#define regABM3_BL1_PWM_USER_LEVEL_BASE_IDX 3
+#define regABM3_BL1_PWM_TARGET_ABM_LEVEL 0x0f3f
+#define regABM3_BL1_PWM_TARGET_ABM_LEVEL_BASE_IDX 3
+#define regABM3_BL1_PWM_CURRENT_ABM_LEVEL 0x0f40
+#define regABM3_BL1_PWM_CURRENT_ABM_LEVEL_BASE_IDX 3
+#define regABM3_BL1_PWM_FINAL_DUTY_CYCLE 0x0f41
+#define regABM3_BL1_PWM_FINAL_DUTY_CYCLE_BASE_IDX 3
+#define regABM3_BL1_PWM_MINIMUM_DUTY_CYCLE 0x0f42
+#define regABM3_BL1_PWM_MINIMUM_DUTY_CYCLE_BASE_IDX 3
+#define regABM3_BL1_PWM_ABM_CNTL 0x0f43
+#define regABM3_BL1_PWM_ABM_CNTL_BASE_IDX 3
+#define regABM3_BL1_PWM_BL_UPDATE_SAMPLE_RATE 0x0f44
+#define regABM3_BL1_PWM_BL_UPDATE_SAMPLE_RATE_BASE_IDX 3
+#define regABM3_BL1_PWM_GRP2_REG_LOCK 0x0f45
+#define regABM3_BL1_PWM_GRP2_REG_LOCK_BASE_IDX 3
+#define regABM3_DC_ABM1_CNTL 0x0f46
+#define regABM3_DC_ABM1_CNTL_BASE_IDX 3
+#define regABM3_DC_ABM1_IPCSC_COEFF_SEL 0x0f47
+#define regABM3_DC_ABM1_IPCSC_COEFF_SEL_BASE_IDX 3
+#define regABM3_DC_ABM1_ACE_OFFSET_SLOPE_0 0x0f48
+#define regABM3_DC_ABM1_ACE_OFFSET_SLOPE_0_BASE_IDX 3
+#define regABM3_DC_ABM1_ACE_OFFSET_SLOPE_1 0x0f49
+#define regABM3_DC_ABM1_ACE_OFFSET_SLOPE_1_BASE_IDX 3
+#define regABM3_DC_ABM1_ACE_OFFSET_SLOPE_2 0x0f4a
+#define regABM3_DC_ABM1_ACE_OFFSET_SLOPE_2_BASE_IDX 3
+#define regABM3_DC_ABM1_ACE_OFFSET_SLOPE_3 0x0f4b
+#define regABM3_DC_ABM1_ACE_OFFSET_SLOPE_3_BASE_IDX 3
+#define regABM3_DC_ABM1_ACE_OFFSET_SLOPE_4 0x0f4c
+#define regABM3_DC_ABM1_ACE_OFFSET_SLOPE_4_BASE_IDX 3
+#define regABM3_DC_ABM1_ACE_THRES_12 0x0f4d
+#define regABM3_DC_ABM1_ACE_THRES_12_BASE_IDX 3
+#define regABM3_DC_ABM1_ACE_THRES_34 0x0f4e
+#define regABM3_DC_ABM1_ACE_THRES_34_BASE_IDX 3
+#define regABM3_DC_ABM1_ACE_CNTL_MISC 0x0f4f
+#define regABM3_DC_ABM1_ACE_CNTL_MISC_BASE_IDX 3
+#define regABM3_DC_ABM1_HGLS_REG_READ_PROGRESS 0x0f51
+#define regABM3_DC_ABM1_HGLS_REG_READ_PROGRESS_BASE_IDX 3
+#define regABM3_DC_ABM1_HG_MISC_CTRL 0x0f52
+#define regABM3_DC_ABM1_HG_MISC_CTRL_BASE_IDX 3
+#define regABM3_DC_ABM1_LS_SUM_OF_LUMA 0x0f53
+#define regABM3_DC_ABM1_LS_SUM_OF_LUMA_BASE_IDX 3
+#define regABM3_DC_ABM1_LS_MIN_MAX_LUMA 0x0f54
+#define regABM3_DC_ABM1_LS_MIN_MAX_LUMA_BASE_IDX 3
+#define regABM3_DC_ABM1_LS_FILTERED_MIN_MAX_LUMA 0x0f55
+#define regABM3_DC_ABM1_LS_FILTERED_MIN_MAX_LUMA_BASE_IDX 3
+#define regABM3_DC_ABM1_LS_PIXEL_COUNT 0x0f56
+#define regABM3_DC_ABM1_LS_PIXEL_COUNT_BASE_IDX 3
+#define regABM3_DC_ABM1_LS_MIN_MAX_PIXEL_VALUE_THRES 0x0f57
+#define regABM3_DC_ABM1_LS_MIN_MAX_PIXEL_VALUE_THRES_BASE_IDX 3
+#define regABM3_DC_ABM1_LS_MIN_PIXEL_VALUE_COUNT 0x0f58
+#define regABM3_DC_ABM1_LS_MIN_PIXEL_VALUE_COUNT_BASE_IDX 3
+#define regABM3_DC_ABM1_LS_MAX_PIXEL_VALUE_COUNT 0x0f59
+#define regABM3_DC_ABM1_LS_MAX_PIXEL_VALUE_COUNT_BASE_IDX 3
+#define regABM3_DC_ABM1_HG_SAMPLE_RATE 0x0f5a
+#define regABM3_DC_ABM1_HG_SAMPLE_RATE_BASE_IDX 3
+#define regABM3_DC_ABM1_LS_SAMPLE_RATE 0x0f5b
+#define regABM3_DC_ABM1_LS_SAMPLE_RATE_BASE_IDX 3
+#define regABM3_DC_ABM1_HG_BIN_1_32_SHIFT_FLAG 0x0f5c
+#define regABM3_DC_ABM1_HG_BIN_1_32_SHIFT_FLAG_BASE_IDX 3
+#define regABM3_DC_ABM1_HG_BIN_1_8_SHIFT_INDEX 0x0f5d
+#define regABM3_DC_ABM1_HG_BIN_1_8_SHIFT_INDEX_BASE_IDX 3
+#define regABM3_DC_ABM1_HG_BIN_9_16_SHIFT_INDEX 0x0f5e
+#define regABM3_DC_ABM1_HG_BIN_9_16_SHIFT_INDEX_BASE_IDX 3
+#define regABM3_DC_ABM1_HG_BIN_17_24_SHIFT_INDEX 0x0f5f
+#define regABM3_DC_ABM1_HG_BIN_17_24_SHIFT_INDEX_BASE_IDX 3
+#define regABM3_DC_ABM1_HG_BIN_25_32_SHIFT_INDEX 0x0f60
+#define regABM3_DC_ABM1_HG_BIN_25_32_SHIFT_INDEX_BASE_IDX 3
+#define regABM3_DC_ABM1_HG_RESULT_1 0x0f61
+#define regABM3_DC_ABM1_HG_RESULT_1_BASE_IDX 3
+#define regABM3_DC_ABM1_HG_RESULT_2 0x0f62
+#define regABM3_DC_ABM1_HG_RESULT_2_BASE_IDX 3
+#define regABM3_DC_ABM1_HG_RESULT_3 0x0f63
+#define regABM3_DC_ABM1_HG_RESULT_3_BASE_IDX 3
+#define regABM3_DC_ABM1_HG_RESULT_4 0x0f64
+#define regABM3_DC_ABM1_HG_RESULT_4_BASE_IDX 3
+#define regABM3_DC_ABM1_HG_RESULT_5 0x0f65
+#define regABM3_DC_ABM1_HG_RESULT_5_BASE_IDX 3
+#define regABM3_DC_ABM1_HG_RESULT_6 0x0f66
+#define regABM3_DC_ABM1_HG_RESULT_6_BASE_IDX 3
+#define regABM3_DC_ABM1_HG_RESULT_7 0x0f67
+#define regABM3_DC_ABM1_HG_RESULT_7_BASE_IDX 3
+#define regABM3_DC_ABM1_HG_RESULT_8 0x0f68
+#define regABM3_DC_ABM1_HG_RESULT_8_BASE_IDX 3
+#define regABM3_DC_ABM1_HG_RESULT_9 0x0f69
+#define regABM3_DC_ABM1_HG_RESULT_9_BASE_IDX 3
+#define regABM3_DC_ABM1_HG_RESULT_10 0x0f6a
+#define regABM3_DC_ABM1_HG_RESULT_10_BASE_IDX 3
+#define regABM3_DC_ABM1_HG_RESULT_11 0x0f6b
+#define regABM3_DC_ABM1_HG_RESULT_11_BASE_IDX 3
+#define regABM3_DC_ABM1_HG_RESULT_12 0x0f6c
+#define regABM3_DC_ABM1_HG_RESULT_12_BASE_IDX 3
+#define regABM3_DC_ABM1_HG_RESULT_13 0x0f6d
+#define regABM3_DC_ABM1_HG_RESULT_13_BASE_IDX 3
+#define regABM3_DC_ABM1_HG_RESULT_14 0x0f6e
+#define regABM3_DC_ABM1_HG_RESULT_14_BASE_IDX 3
+#define regABM3_DC_ABM1_HG_RESULT_15 0x0f6f
+#define regABM3_DC_ABM1_HG_RESULT_15_BASE_IDX 3
+#define regABM3_DC_ABM1_HG_RESULT_16 0x0f70
+#define regABM3_DC_ABM1_HG_RESULT_16_BASE_IDX 3
+#define regABM3_DC_ABM1_HG_RESULT_17 0x0f71
+#define regABM3_DC_ABM1_HG_RESULT_17_BASE_IDX 3
+#define regABM3_DC_ABM1_HG_RESULT_18 0x0f72
+#define regABM3_DC_ABM1_HG_RESULT_18_BASE_IDX 3
+#define regABM3_DC_ABM1_HG_RESULT_19 0x0f73
+#define regABM3_DC_ABM1_HG_RESULT_19_BASE_IDX 3
+#define regABM3_DC_ABM1_HG_RESULT_20 0x0f74
+#define regABM3_DC_ABM1_HG_RESULT_20_BASE_IDX 3
+#define regABM3_DC_ABM1_HG_RESULT_21 0x0f75
+#define regABM3_DC_ABM1_HG_RESULT_21_BASE_IDX 3
+#define regABM3_DC_ABM1_HG_RESULT_22 0x0f76
+#define regABM3_DC_ABM1_HG_RESULT_22_BASE_IDX 3
+#define regABM3_DC_ABM1_HG_RESULT_23 0x0f77
+#define regABM3_DC_ABM1_HG_RESULT_23_BASE_IDX 3
+#define regABM3_DC_ABM1_HG_RESULT_24 0x0f78
+#define regABM3_DC_ABM1_HG_RESULT_24_BASE_IDX 3
+#define regABM3_DC_ABM1_BL_MASTER_LOCK 0x0f79
+#define regABM3_DC_ABM1_BL_MASTER_LOCK_BASE_IDX 3
+
+
+// addressBlock: dce_dc_opp_dpg0_dispdec
+// base address: 0x0
+#define regDPG0_DPG_CONTROL 0x1854
+#define regDPG0_DPG_CONTROL_BASE_IDX 2
+#define regDPG0_DPG_RAMP_CONTROL 0x1855
+#define regDPG0_DPG_RAMP_CONTROL_BASE_IDX 2
+#define regDPG0_DPG_DIMENSIONS 0x1856
+#define regDPG0_DPG_DIMENSIONS_BASE_IDX 2
+#define regDPG0_DPG_COLOUR_R_CR 0x1857
+#define regDPG0_DPG_COLOUR_R_CR_BASE_IDX 2
+#define regDPG0_DPG_COLOUR_G_Y 0x1858
+#define regDPG0_DPG_COLOUR_G_Y_BASE_IDX 2
+#define regDPG0_DPG_COLOUR_B_CB 0x1859
+#define regDPG0_DPG_COLOUR_B_CB_BASE_IDX 2
+#define regDPG0_DPG_OFFSET_SEGMENT 0x185a
+#define regDPG0_DPG_OFFSET_SEGMENT_BASE_IDX 2
+#define regDPG0_DPG_STATUS 0x185b
+#define regDPG0_DPG_STATUS_BASE_IDX 2
+
+
+// addressBlock: dce_dc_opp_fmt0_dispdec
+// base address: 0x0
+#define regFMT0_FMT_CLAMP_COMPONENT_R 0x183c
+#define regFMT0_FMT_CLAMP_COMPONENT_R_BASE_IDX 2
+#define regFMT0_FMT_CLAMP_COMPONENT_G 0x183d
+#define regFMT0_FMT_CLAMP_COMPONENT_G_BASE_IDX 2
+#define regFMT0_FMT_CLAMP_COMPONENT_B 0x183e
+#define regFMT0_FMT_CLAMP_COMPONENT_B_BASE_IDX 2
+#define regFMT0_FMT_DYNAMIC_EXP_CNTL 0x183f
+#define regFMT0_FMT_DYNAMIC_EXP_CNTL_BASE_IDX 2
+#define regFMT0_FMT_CONTROL 0x1840
+#define regFMT0_FMT_CONTROL_BASE_IDX 2
+#define regFMT0_FMT_BIT_DEPTH_CONTROL 0x1841
+#define regFMT0_FMT_BIT_DEPTH_CONTROL_BASE_IDX 2
+#define regFMT0_FMT_DITHER_RAND_R_SEED 0x1842
+#define regFMT0_FMT_DITHER_RAND_R_SEED_BASE_IDX 2
+#define regFMT0_FMT_DITHER_RAND_G_SEED 0x1843
+#define regFMT0_FMT_DITHER_RAND_G_SEED_BASE_IDX 2
+#define regFMT0_FMT_DITHER_RAND_B_SEED 0x1844
+#define regFMT0_FMT_DITHER_RAND_B_SEED_BASE_IDX 2
+#define regFMT0_FMT_CLAMP_CNTL 0x1845
+#define regFMT0_FMT_CLAMP_CNTL_BASE_IDX 2
+#define regFMT0_FMT_SIDE_BY_SIDE_STEREO_CONTROL 0x1846
+#define regFMT0_FMT_SIDE_BY_SIDE_STEREO_CONTROL_BASE_IDX 2
+#define regFMT0_FMT_MAP420_MEMORY_CONTROL 0x1847
+#define regFMT0_FMT_MAP420_MEMORY_CONTROL_BASE_IDX 2
+#define regFMT0_FMT_422_CONTROL 0x1849
+#define regFMT0_FMT_422_CONTROL_BASE_IDX 2
+
+
+// addressBlock: dce_dc_opp_oppbuf0_dispdec
+// base address: 0x0
+#define regOPPBUF0_OPPBUF_CONTROL 0x1884
+#define regOPPBUF0_OPPBUF_CONTROL_BASE_IDX 2
+#define regOPPBUF0_OPPBUF_3D_PARAMETERS_0 0x1885
+#define regOPPBUF0_OPPBUF_3D_PARAMETERS_0_BASE_IDX 2
+#define regOPPBUF0_OPPBUF_3D_PARAMETERS_1 0x1886
+#define regOPPBUF0_OPPBUF_3D_PARAMETERS_1_BASE_IDX 2
+#define regOPPBUF0_OPPBUF_CONTROL1 0x1889
+#define regOPPBUF0_OPPBUF_CONTROL1_BASE_IDX 2
+
+
+// addressBlock: dce_dc_opp_opp_pipe0_dispdec
+// base address: 0x0
+#define regOPP_PIPE0_OPP_PIPE_CONTROL 0x188c
+#define regOPP_PIPE0_OPP_PIPE_CONTROL_BASE_IDX 2
+
+
+// addressBlock: dce_dc_opp_opp_pipe_crc0_dispdec
+// base address: 0x0
+#define regOPP_PIPE_CRC0_OPP_PIPE_CRC_CONTROL 0x1891
+#define regOPP_PIPE_CRC0_OPP_PIPE_CRC_CONTROL_BASE_IDX 2
+#define regOPP_PIPE_CRC0_OPP_PIPE_CRC_MASK 0x1892
+#define regOPP_PIPE_CRC0_OPP_PIPE_CRC_MASK_BASE_IDX 2
+#define regOPP_PIPE_CRC0_OPP_PIPE_CRC_RESULT0 0x1893
+#define regOPP_PIPE_CRC0_OPP_PIPE_CRC_RESULT0_BASE_IDX 2
+#define regOPP_PIPE_CRC0_OPP_PIPE_CRC_RESULT1 0x1894
+#define regOPP_PIPE_CRC0_OPP_PIPE_CRC_RESULT1_BASE_IDX 2
+#define regOPP_PIPE_CRC0_OPP_PIPE_CRC_RESULT2 0x1895
+#define regOPP_PIPE_CRC0_OPP_PIPE_CRC_RESULT2_BASE_IDX 2
+
+
+// addressBlock: dce_dc_opp_dpg1_dispdec
+// base address: 0x168
+#define regDPG1_DPG_CONTROL 0x18ae
+#define regDPG1_DPG_CONTROL_BASE_IDX 2
+#define regDPG1_DPG_RAMP_CONTROL 0x18af
+#define regDPG1_DPG_RAMP_CONTROL_BASE_IDX 2
+#define regDPG1_DPG_DIMENSIONS 0x18b0
+#define regDPG1_DPG_DIMENSIONS_BASE_IDX 2
+#define regDPG1_DPG_COLOUR_R_CR 0x18b1
+#define regDPG1_DPG_COLOUR_R_CR_BASE_IDX 2
+#define regDPG1_DPG_COLOUR_G_Y 0x18b2
+#define regDPG1_DPG_COLOUR_G_Y_BASE_IDX 2
+#define regDPG1_DPG_COLOUR_B_CB 0x18b3
+#define regDPG1_DPG_COLOUR_B_CB_BASE_IDX 2
+#define regDPG1_DPG_OFFSET_SEGMENT 0x18b4
+#define regDPG1_DPG_OFFSET_SEGMENT_BASE_IDX 2
+#define regDPG1_DPG_STATUS 0x18b5
+#define regDPG1_DPG_STATUS_BASE_IDX 2
+
+
+// addressBlock: dce_dc_opp_fmt1_dispdec
+// base address: 0x168
+#define regFMT1_FMT_CLAMP_COMPONENT_R 0x1896
+#define regFMT1_FMT_CLAMP_COMPONENT_R_BASE_IDX 2
+#define regFMT1_FMT_CLAMP_COMPONENT_G 0x1897
+#define regFMT1_FMT_CLAMP_COMPONENT_G_BASE_IDX 2
+#define regFMT1_FMT_CLAMP_COMPONENT_B 0x1898
+#define regFMT1_FMT_CLAMP_COMPONENT_B_BASE_IDX 2
+#define regFMT1_FMT_DYNAMIC_EXP_CNTL 0x1899
+#define regFMT1_FMT_DYNAMIC_EXP_CNTL_BASE_IDX 2
+#define regFMT1_FMT_CONTROL 0x189a
+#define regFMT1_FMT_CONTROL_BASE_IDX 2
+#define regFMT1_FMT_BIT_DEPTH_CONTROL 0x189b
+#define regFMT1_FMT_BIT_DEPTH_CONTROL_BASE_IDX 2
+#define regFMT1_FMT_DITHER_RAND_R_SEED 0x189c
+#define regFMT1_FMT_DITHER_RAND_R_SEED_BASE_IDX 2
+#define regFMT1_FMT_DITHER_RAND_G_SEED 0x189d
+#define regFMT1_FMT_DITHER_RAND_G_SEED_BASE_IDX 2
+#define regFMT1_FMT_DITHER_RAND_B_SEED 0x189e
+#define regFMT1_FMT_DITHER_RAND_B_SEED_BASE_IDX 2
+#define regFMT1_FMT_CLAMP_CNTL 0x189f
+#define regFMT1_FMT_CLAMP_CNTL_BASE_IDX 2
+#define regFMT1_FMT_SIDE_BY_SIDE_STEREO_CONTROL 0x18a0
+#define regFMT1_FMT_SIDE_BY_SIDE_STEREO_CONTROL_BASE_IDX 2
+#define regFMT1_FMT_MAP420_MEMORY_CONTROL 0x18a1
+#define regFMT1_FMT_MAP420_MEMORY_CONTROL_BASE_IDX 2
+#define regFMT1_FMT_422_CONTROL 0x18a3
+#define regFMT1_FMT_422_CONTROL_BASE_IDX 2
+
+
+// addressBlock: dce_dc_opp_oppbuf1_dispdec
+// base address: 0x168
+#define regOPPBUF1_OPPBUF_CONTROL 0x18de
+#define regOPPBUF1_OPPBUF_CONTROL_BASE_IDX 2
+#define regOPPBUF1_OPPBUF_3D_PARAMETERS_0 0x18df
+#define regOPPBUF1_OPPBUF_3D_PARAMETERS_0_BASE_IDX 2
+#define regOPPBUF1_OPPBUF_3D_PARAMETERS_1 0x18e0
+#define regOPPBUF1_OPPBUF_3D_PARAMETERS_1_BASE_IDX 2
+#define regOPPBUF1_OPPBUF_CONTROL1 0x18e3
+#define regOPPBUF1_OPPBUF_CONTROL1_BASE_IDX 2
+
+
+// addressBlock: dce_dc_opp_opp_pipe1_dispdec
+// base address: 0x168
+#define regOPP_PIPE1_OPP_PIPE_CONTROL 0x18e6
+#define regOPP_PIPE1_OPP_PIPE_CONTROL_BASE_IDX 2
+
+
+// addressBlock: dce_dc_opp_opp_pipe_crc1_dispdec
+// base address: 0x168
+#define regOPP_PIPE_CRC1_OPP_PIPE_CRC_CONTROL 0x18eb
+#define regOPP_PIPE_CRC1_OPP_PIPE_CRC_CONTROL_BASE_IDX 2
+#define regOPP_PIPE_CRC1_OPP_PIPE_CRC_MASK 0x18ec
+#define regOPP_PIPE_CRC1_OPP_PIPE_CRC_MASK_BASE_IDX 2
+#define regOPP_PIPE_CRC1_OPP_PIPE_CRC_RESULT0 0x18ed
+#define regOPP_PIPE_CRC1_OPP_PIPE_CRC_RESULT0_BASE_IDX 2
+#define regOPP_PIPE_CRC1_OPP_PIPE_CRC_RESULT1 0x18ee
+#define regOPP_PIPE_CRC1_OPP_PIPE_CRC_RESULT1_BASE_IDX 2
+#define regOPP_PIPE_CRC1_OPP_PIPE_CRC_RESULT2 0x18ef
+#define regOPP_PIPE_CRC1_OPP_PIPE_CRC_RESULT2_BASE_IDX 2
+
+
+// addressBlock: dce_dc_opp_dpg2_dispdec
+// base address: 0x2d0
+#define regDPG2_DPG_CONTROL 0x1908
+#define regDPG2_DPG_CONTROL_BASE_IDX 2
+#define regDPG2_DPG_RAMP_CONTROL 0x1909
+#define regDPG2_DPG_RAMP_CONTROL_BASE_IDX 2
+#define regDPG2_DPG_DIMENSIONS 0x190a
+#define regDPG2_DPG_DIMENSIONS_BASE_IDX 2
+#define regDPG2_DPG_COLOUR_R_CR 0x190b
+#define regDPG2_DPG_COLOUR_R_CR_BASE_IDX 2
+#define regDPG2_DPG_COLOUR_G_Y 0x190c
+#define regDPG2_DPG_COLOUR_G_Y_BASE_IDX 2
+#define regDPG2_DPG_COLOUR_B_CB 0x190d
+#define regDPG2_DPG_COLOUR_B_CB_BASE_IDX 2
+#define regDPG2_DPG_OFFSET_SEGMENT 0x190e
+#define regDPG2_DPG_OFFSET_SEGMENT_BASE_IDX 2
+#define regDPG2_DPG_STATUS 0x190f
+#define regDPG2_DPG_STATUS_BASE_IDX 2
+
+
+// addressBlock: dce_dc_opp_fmt2_dispdec
+// base address: 0x2d0
+#define regFMT2_FMT_CLAMP_COMPONENT_R 0x18f0
+#define regFMT2_FMT_CLAMP_COMPONENT_R_BASE_IDX 2
+#define regFMT2_FMT_CLAMP_COMPONENT_G 0x18f1
+#define regFMT2_FMT_CLAMP_COMPONENT_G_BASE_IDX 2
+#define regFMT2_FMT_CLAMP_COMPONENT_B 0x18f2
+#define regFMT2_FMT_CLAMP_COMPONENT_B_BASE_IDX 2
+#define regFMT2_FMT_DYNAMIC_EXP_CNTL 0x18f3
+#define regFMT2_FMT_DYNAMIC_EXP_CNTL_BASE_IDX 2
+#define regFMT2_FMT_CONTROL 0x18f4
+#define regFMT2_FMT_CONTROL_BASE_IDX 2
+#define regFMT2_FMT_BIT_DEPTH_CONTROL 0x18f5
+#define regFMT2_FMT_BIT_DEPTH_CONTROL_BASE_IDX 2
+#define regFMT2_FMT_DITHER_RAND_R_SEED 0x18f6
+#define regFMT2_FMT_DITHER_RAND_R_SEED_BASE_IDX 2
+#define regFMT2_FMT_DITHER_RAND_G_SEED 0x18f7
+#define regFMT2_FMT_DITHER_RAND_G_SEED_BASE_IDX 2
+#define regFMT2_FMT_DITHER_RAND_B_SEED 0x18f8
+#define regFMT2_FMT_DITHER_RAND_B_SEED_BASE_IDX 2
+#define regFMT2_FMT_CLAMP_CNTL 0x18f9
+#define regFMT2_FMT_CLAMP_CNTL_BASE_IDX 2
+#define regFMT2_FMT_SIDE_BY_SIDE_STEREO_CONTROL 0x18fa
+#define regFMT2_FMT_SIDE_BY_SIDE_STEREO_CONTROL_BASE_IDX 2
+#define regFMT2_FMT_MAP420_MEMORY_CONTROL 0x18fb
+#define regFMT2_FMT_MAP420_MEMORY_CONTROL_BASE_IDX 2
+#define regFMT2_FMT_422_CONTROL 0x18fd
+#define regFMT2_FMT_422_CONTROL_BASE_IDX 2
+
+
+// addressBlock: dce_dc_opp_oppbuf2_dispdec
+// base address: 0x2d0
+#define regOPPBUF2_OPPBUF_CONTROL 0x1938
+#define regOPPBUF2_OPPBUF_CONTROL_BASE_IDX 2
+#define regOPPBUF2_OPPBUF_3D_PARAMETERS_0 0x1939
+#define regOPPBUF2_OPPBUF_3D_PARAMETERS_0_BASE_IDX 2
+#define regOPPBUF2_OPPBUF_3D_PARAMETERS_1 0x193a
+#define regOPPBUF2_OPPBUF_3D_PARAMETERS_1_BASE_IDX 2
+#define regOPPBUF2_OPPBUF_CONTROL1 0x193d
+#define regOPPBUF2_OPPBUF_CONTROL1_BASE_IDX 2
+
+
+// addressBlock: dce_dc_opp_opp_pipe2_dispdec
+// base address: 0x2d0
+#define regOPP_PIPE2_OPP_PIPE_CONTROL 0x1940
+#define regOPP_PIPE2_OPP_PIPE_CONTROL_BASE_IDX 2
+
+
+// addressBlock: dce_dc_opp_opp_pipe_crc2_dispdec
+// base address: 0x2d0
+#define regOPP_PIPE_CRC2_OPP_PIPE_CRC_CONTROL 0x1945
+#define regOPP_PIPE_CRC2_OPP_PIPE_CRC_CONTROL_BASE_IDX 2
+#define regOPP_PIPE_CRC2_OPP_PIPE_CRC_MASK 0x1946
+#define regOPP_PIPE_CRC2_OPP_PIPE_CRC_MASK_BASE_IDX 2
+#define regOPP_PIPE_CRC2_OPP_PIPE_CRC_RESULT0 0x1947
+#define regOPP_PIPE_CRC2_OPP_PIPE_CRC_RESULT0_BASE_IDX 2
+#define regOPP_PIPE_CRC2_OPP_PIPE_CRC_RESULT1 0x1948
+#define regOPP_PIPE_CRC2_OPP_PIPE_CRC_RESULT1_BASE_IDX 2
+#define regOPP_PIPE_CRC2_OPP_PIPE_CRC_RESULT2 0x1949
+#define regOPP_PIPE_CRC2_OPP_PIPE_CRC_RESULT2_BASE_IDX 2
+
+
+// addressBlock: dce_dc_opp_dpg3_dispdec
+// base address: 0x438
+#define regDPG3_DPG_CONTROL 0x1962
+#define regDPG3_DPG_CONTROL_BASE_IDX 2
+#define regDPG3_DPG_RAMP_CONTROL 0x1963
+#define regDPG3_DPG_RAMP_CONTROL_BASE_IDX 2
+#define regDPG3_DPG_DIMENSIONS 0x1964
+#define regDPG3_DPG_DIMENSIONS_BASE_IDX 2
+#define regDPG3_DPG_COLOUR_R_CR 0x1965
+#define regDPG3_DPG_COLOUR_R_CR_BASE_IDX 2
+#define regDPG3_DPG_COLOUR_G_Y 0x1966
+#define regDPG3_DPG_COLOUR_G_Y_BASE_IDX 2
+#define regDPG3_DPG_COLOUR_B_CB 0x1967
+#define regDPG3_DPG_COLOUR_B_CB_BASE_IDX 2
+#define regDPG3_DPG_OFFSET_SEGMENT 0x1968
+#define regDPG3_DPG_OFFSET_SEGMENT_BASE_IDX 2
+#define regDPG3_DPG_STATUS 0x1969
+#define regDPG3_DPG_STATUS_BASE_IDX 2
+
+
+// addressBlock: dce_dc_opp_fmt3_dispdec
+// base address: 0x438
+#define regFMT3_FMT_CLAMP_COMPONENT_R 0x194a
+#define regFMT3_FMT_CLAMP_COMPONENT_R_BASE_IDX 2
+#define regFMT3_FMT_CLAMP_COMPONENT_G 0x194b
+#define regFMT3_FMT_CLAMP_COMPONENT_G_BASE_IDX 2
+#define regFMT3_FMT_CLAMP_COMPONENT_B 0x194c
+#define regFMT3_FMT_CLAMP_COMPONENT_B_BASE_IDX 2
+#define regFMT3_FMT_DYNAMIC_EXP_CNTL 0x194d
+#define regFMT3_FMT_DYNAMIC_EXP_CNTL_BASE_IDX 2
+#define regFMT3_FMT_CONTROL 0x194e
+#define regFMT3_FMT_CONTROL_BASE_IDX 2
+#define regFMT3_FMT_BIT_DEPTH_CONTROL 0x194f
+#define regFMT3_FMT_BIT_DEPTH_CONTROL_BASE_IDX 2
+#define regFMT3_FMT_DITHER_RAND_R_SEED 0x1950
+#define regFMT3_FMT_DITHER_RAND_R_SEED_BASE_IDX 2
+#define regFMT3_FMT_DITHER_RAND_G_SEED 0x1951
+#define regFMT3_FMT_DITHER_RAND_G_SEED_BASE_IDX 2
+#define regFMT3_FMT_DITHER_RAND_B_SEED 0x1952
+#define regFMT3_FMT_DITHER_RAND_B_SEED_BASE_IDX 2
+#define regFMT3_FMT_CLAMP_CNTL 0x1953
+#define regFMT3_FMT_CLAMP_CNTL_BASE_IDX 2
+#define regFMT3_FMT_SIDE_BY_SIDE_STEREO_CONTROL 0x1954
+#define regFMT3_FMT_SIDE_BY_SIDE_STEREO_CONTROL_BASE_IDX 2
+#define regFMT3_FMT_MAP420_MEMORY_CONTROL 0x1955
+#define regFMT3_FMT_MAP420_MEMORY_CONTROL_BASE_IDX 2
+#define regFMT3_FMT_422_CONTROL 0x1957
+#define regFMT3_FMT_422_CONTROL_BASE_IDX 2
+
+
+// addressBlock: dce_dc_opp_oppbuf3_dispdec
+// base address: 0x438
+#define regOPPBUF3_OPPBUF_CONTROL 0x1992
+#define regOPPBUF3_OPPBUF_CONTROL_BASE_IDX 2
+#define regOPPBUF3_OPPBUF_3D_PARAMETERS_0 0x1993
+#define regOPPBUF3_OPPBUF_3D_PARAMETERS_0_BASE_IDX 2
+#define regOPPBUF3_OPPBUF_3D_PARAMETERS_1 0x1994
+#define regOPPBUF3_OPPBUF_3D_PARAMETERS_1_BASE_IDX 2
+#define regOPPBUF3_OPPBUF_CONTROL1 0x1997
+#define regOPPBUF3_OPPBUF_CONTROL1_BASE_IDX 2
+
+
+// addressBlock: dce_dc_opp_opp_pipe3_dispdec
+// base address: 0x438
+#define regOPP_PIPE3_OPP_PIPE_CONTROL 0x199a
+#define regOPP_PIPE3_OPP_PIPE_CONTROL_BASE_IDX 2
+
+
+// addressBlock: dce_dc_opp_opp_pipe_crc3_dispdec
+// base address: 0x438
+#define regOPP_PIPE_CRC3_OPP_PIPE_CRC_CONTROL 0x199f
+#define regOPP_PIPE_CRC3_OPP_PIPE_CRC_CONTROL_BASE_IDX 2
+#define regOPP_PIPE_CRC3_OPP_PIPE_CRC_MASK 0x19a0
+#define regOPP_PIPE_CRC3_OPP_PIPE_CRC_MASK_BASE_IDX 2
+#define regOPP_PIPE_CRC3_OPP_PIPE_CRC_RESULT0 0x19a1
+#define regOPP_PIPE_CRC3_OPP_PIPE_CRC_RESULT0_BASE_IDX 2
+#define regOPP_PIPE_CRC3_OPP_PIPE_CRC_RESULT1 0x19a2
+#define regOPP_PIPE_CRC3_OPP_PIPE_CRC_RESULT1_BASE_IDX 2
+#define regOPP_PIPE_CRC3_OPP_PIPE_CRC_RESULT2 0x19a3
+#define regOPP_PIPE_CRC3_OPP_PIPE_CRC_RESULT2_BASE_IDX 2
+
+
+// addressBlock: dce_dc_opp_dscrm0_dispdec
+// base address: 0x0
+#define regDSCRM0_DSCRM_DSC_FORWARD_CONFIG 0x1a64
+#define regDSCRM0_DSCRM_DSC_FORWARD_CONFIG_BASE_IDX 2
+
+
+// addressBlock: dce_dc_opp_dscrm1_dispdec
+// base address: 0x4
+#define regDSCRM1_DSCRM_DSC_FORWARD_CONFIG 0x1a65
+#define regDSCRM1_DSCRM_DSC_FORWARD_CONFIG_BASE_IDX 2
+
+
+// addressBlock: dce_dc_opp_dscrm2_dispdec
+// base address: 0x8
+#define regDSCRM2_DSCRM_DSC_FORWARD_CONFIG 0x1a66
+#define regDSCRM2_DSCRM_DSC_FORWARD_CONFIG_BASE_IDX 2
+
+
+// addressBlock: dce_dc_opp_opp_top_dispdec
+// base address: 0x0
+#define regOPP_TOP_CLK_CONTROL 0x1a5e
+#define regOPP_TOP_CLK_CONTROL_BASE_IDX 2
+#define regOPP_ABM_CONTROL 0x1a60
+#define regOPP_ABM_CONTROL_BASE_IDX 2
+
+
+// addressBlock: dce_dc_opp_opp_dcperfmon_dc_perfmon_dispdec
+// base address: 0x6af8
+#define regDC_PERFMON16_PERFCOUNTER_CNTL 0x1abe
+#define regDC_PERFMON16_PERFCOUNTER_CNTL_BASE_IDX 2
+#define regDC_PERFMON16_PERFCOUNTER_CNTL2 0x1abf
+#define regDC_PERFMON16_PERFCOUNTER_CNTL2_BASE_IDX 2
+#define regDC_PERFMON16_PERFCOUNTER_STATE 0x1ac0
+#define regDC_PERFMON16_PERFCOUNTER_STATE_BASE_IDX 2
+#define regDC_PERFMON16_PERFMON_CNTL 0x1ac1
+#define regDC_PERFMON16_PERFMON_CNTL_BASE_IDX 2
+#define regDC_PERFMON16_PERFMON_CNTL2 0x1ac2
+#define regDC_PERFMON16_PERFMON_CNTL2_BASE_IDX 2
+#define regDC_PERFMON16_PERFMON_CVALUE_INT_MISC 0x1ac3
+#define regDC_PERFMON16_PERFMON_CVALUE_INT_MISC_BASE_IDX 2
+#define regDC_PERFMON16_PERFMON_CVALUE_LOW 0x1ac4
+#define regDC_PERFMON16_PERFMON_CVALUE_LOW_BASE_IDX 2
+#define regDC_PERFMON16_PERFMON_HI 0x1ac5
+#define regDC_PERFMON16_PERFMON_HI_BASE_IDX 2
+#define regDC_PERFMON16_PERFMON_LOW 0x1ac6
+#define regDC_PERFMON16_PERFMON_LOW_BASE_IDX 2
+
+
+// addressBlock: dce_dc_optc_odm0_dispdec
+// base address: 0x0
+#define regODM0_OPTC_INPUT_GLOBAL_CONTROL 0x1aca
+#define regODM0_OPTC_INPUT_GLOBAL_CONTROL_BASE_IDX 2
+#define regODM0_OPTC_DATA_SOURCE_SELECT 0x1acb
+#define regODM0_OPTC_DATA_SOURCE_SELECT_BASE_IDX 2
+#define regODM0_OPTC_DATA_FORMAT_CONTROL 0x1acc
+#define regODM0_OPTC_DATA_FORMAT_CONTROL_BASE_IDX 2
+#define regODM0_OPTC_BYTES_PER_PIXEL 0x1acd
+#define regODM0_OPTC_BYTES_PER_PIXEL_BASE_IDX 2
+#define regODM0_OPTC_WIDTH_CONTROL 0x1ace
+#define regODM0_OPTC_WIDTH_CONTROL_BASE_IDX 2
+#define regODM0_OPTC_INPUT_CLOCK_CONTROL 0x1acf
+#define regODM0_OPTC_INPUT_CLOCK_CONTROL_BASE_IDX 2
+#define regODM0_OPTC_MEMORY_CONFIG 0x1ad0
+#define regODM0_OPTC_MEMORY_CONFIG_BASE_IDX 2
+#define regODM0_OPTC_INPUT_SPARE_REGISTER 0x1ad1
+#define regODM0_OPTC_INPUT_SPARE_REGISTER_BASE_IDX 2
+
+
+// addressBlock: dce_dc_optc_odm1_dispdec
+// base address: 0x40
+#define regODM1_OPTC_INPUT_GLOBAL_CONTROL 0x1ada
+#define regODM1_OPTC_INPUT_GLOBAL_CONTROL_BASE_IDX 2
+#define regODM1_OPTC_DATA_SOURCE_SELECT 0x1adb
+#define regODM1_OPTC_DATA_SOURCE_SELECT_BASE_IDX 2
+#define regODM1_OPTC_DATA_FORMAT_CONTROL 0x1adc
+#define regODM1_OPTC_DATA_FORMAT_CONTROL_BASE_IDX 2
+#define regODM1_OPTC_BYTES_PER_PIXEL 0x1add
+#define regODM1_OPTC_BYTES_PER_PIXEL_BASE_IDX 2
+#define regODM1_OPTC_WIDTH_CONTROL 0x1ade
+#define regODM1_OPTC_WIDTH_CONTROL_BASE_IDX 2
+#define regODM1_OPTC_INPUT_CLOCK_CONTROL 0x1adf
+#define regODM1_OPTC_INPUT_CLOCK_CONTROL_BASE_IDX 2
+#define regODM1_OPTC_MEMORY_CONFIG 0x1ae0
+#define regODM1_OPTC_MEMORY_CONFIG_BASE_IDX 2
+#define regODM1_OPTC_INPUT_SPARE_REGISTER 0x1ae1
+#define regODM1_OPTC_INPUT_SPARE_REGISTER_BASE_IDX 2
+
+
+// addressBlock: dce_dc_optc_odm2_dispdec
+// base address: 0x80
+#define regODM2_OPTC_INPUT_GLOBAL_CONTROL 0x1aea
+#define regODM2_OPTC_INPUT_GLOBAL_CONTROL_BASE_IDX 2
+#define regODM2_OPTC_DATA_SOURCE_SELECT 0x1aeb
+#define regODM2_OPTC_DATA_SOURCE_SELECT_BASE_IDX 2
+#define regODM2_OPTC_DATA_FORMAT_CONTROL 0x1aec
+#define regODM2_OPTC_DATA_FORMAT_CONTROL_BASE_IDX 2
+#define regODM2_OPTC_BYTES_PER_PIXEL 0x1aed
+#define regODM2_OPTC_BYTES_PER_PIXEL_BASE_IDX 2
+#define regODM2_OPTC_WIDTH_CONTROL 0x1aee
+#define regODM2_OPTC_WIDTH_CONTROL_BASE_IDX 2
+#define regODM2_OPTC_INPUT_CLOCK_CONTROL 0x1aef
+#define regODM2_OPTC_INPUT_CLOCK_CONTROL_BASE_IDX 2
+#define regODM2_OPTC_MEMORY_CONFIG 0x1af0
+#define regODM2_OPTC_MEMORY_CONFIG_BASE_IDX 2
+#define regODM2_OPTC_INPUT_SPARE_REGISTER 0x1af1
+#define regODM2_OPTC_INPUT_SPARE_REGISTER_BASE_IDX 2
+
+
+// addressBlock: dce_dc_optc_odm3_dispdec
+// base address: 0xc0
+#define regODM3_OPTC_INPUT_GLOBAL_CONTROL 0x1afa
+#define regODM3_OPTC_INPUT_GLOBAL_CONTROL_BASE_IDX 2
+#define regODM3_OPTC_DATA_SOURCE_SELECT 0x1afb
+#define regODM3_OPTC_DATA_SOURCE_SELECT_BASE_IDX 2
+#define regODM3_OPTC_DATA_FORMAT_CONTROL 0x1afc
+#define regODM3_OPTC_DATA_FORMAT_CONTROL_BASE_IDX 2
+#define regODM3_OPTC_BYTES_PER_PIXEL 0x1afd
+#define regODM3_OPTC_BYTES_PER_PIXEL_BASE_IDX 2
+#define regODM3_OPTC_WIDTH_CONTROL 0x1afe
+#define regODM3_OPTC_WIDTH_CONTROL_BASE_IDX 2
+#define regODM3_OPTC_INPUT_CLOCK_CONTROL 0x1aff
+#define regODM3_OPTC_INPUT_CLOCK_CONTROL_BASE_IDX 2
+#define regODM3_OPTC_MEMORY_CONFIG 0x1b00
+#define regODM3_OPTC_MEMORY_CONFIG_BASE_IDX 2
+#define regODM3_OPTC_INPUT_SPARE_REGISTER 0x1b01
+#define regODM3_OPTC_INPUT_SPARE_REGISTER_BASE_IDX 2
+
+
+// addressBlock: dce_dc_optc_otg0_dispdec
+// base address: 0x0
+#define regOTG0_OTG_H_TOTAL 0x1b2a
+#define regOTG0_OTG_H_TOTAL_BASE_IDX 2
+#define regOTG0_OTG_H_BLANK_START_END 0x1b2b
+#define regOTG0_OTG_H_BLANK_START_END_BASE_IDX 2
+#define regOTG0_OTG_H_SYNC_A 0x1b2c
+#define regOTG0_OTG_H_SYNC_A_BASE_IDX 2
+#define regOTG0_OTG_H_SYNC_A_CNTL 0x1b2d
+#define regOTG0_OTG_H_SYNC_A_CNTL_BASE_IDX 2
+#define regOTG0_OTG_H_TIMING_CNTL 0x1b2e
+#define regOTG0_OTG_H_TIMING_CNTL_BASE_IDX 2
+#define regOTG0_OTG_V_TOTAL 0x1b2f
+#define regOTG0_OTG_V_TOTAL_BASE_IDX 2
+#define regOTG0_OTG_V_TOTAL_MIN 0x1b30
+#define regOTG0_OTG_V_TOTAL_MIN_BASE_IDX 2
+#define regOTG0_OTG_V_TOTAL_MAX 0x1b31
+#define regOTG0_OTG_V_TOTAL_MAX_BASE_IDX 2
+#define regOTG0_OTG_V_TOTAL_MID 0x1b32
+#define regOTG0_OTG_V_TOTAL_MID_BASE_IDX 2
+#define regOTG0_OTG_V_TOTAL_CONTROL 0x1b33
+#define regOTG0_OTG_V_TOTAL_CONTROL_BASE_IDX 2
+#define regOTG0_OTG_V_TOTAL_INT_STATUS 0x1b34
+#define regOTG0_OTG_V_TOTAL_INT_STATUS_BASE_IDX 2
+#define regOTG0_OTG_VSYNC_NOM_INT_STATUS 0x1b35
+#define regOTG0_OTG_VSYNC_NOM_INT_STATUS_BASE_IDX 2
+#define regOTG0_OTG_V_BLANK_START_END 0x1b36
+#define regOTG0_OTG_V_BLANK_START_END_BASE_IDX 2
+#define regOTG0_OTG_V_SYNC_A 0x1b37
+#define regOTG0_OTG_V_SYNC_A_BASE_IDX 2
+#define regOTG0_OTG_V_SYNC_A_CNTL 0x1b38
+#define regOTG0_OTG_V_SYNC_A_CNTL_BASE_IDX 2
+#define regOTG0_OTG_TRIGA_CNTL 0x1b39
+#define regOTG0_OTG_TRIGA_CNTL_BASE_IDX 2
+#define regOTG0_OTG_TRIGA_MANUAL_TRIG 0x1b3a
+#define regOTG0_OTG_TRIGA_MANUAL_TRIG_BASE_IDX 2
+#define regOTG0_OTG_TRIGB_CNTL 0x1b3b
+#define regOTG0_OTG_TRIGB_CNTL_BASE_IDX 2
+#define regOTG0_OTG_TRIGB_MANUAL_TRIG 0x1b3c
+#define regOTG0_OTG_TRIGB_MANUAL_TRIG_BASE_IDX 2
+#define regOTG0_OTG_FORCE_COUNT_NOW_CNTL 0x1b3d
+#define regOTG0_OTG_FORCE_COUNT_NOW_CNTL_BASE_IDX 2
+#define regOTG0_OTG_FLOW_CONTROL 0x1b3e
+#define regOTG0_OTG_FLOW_CONTROL_BASE_IDX 2
+#define regOTG0_OTG_STEREO_FORCE_NEXT_EYE 0x1b3f
+#define regOTG0_OTG_STEREO_FORCE_NEXT_EYE_BASE_IDX 2
+#define regOTG0_OTG_CONTROL 0x1b41
+#define regOTG0_OTG_CONTROL_BASE_IDX 2
+#define regOTG0_OTG_INTERLACE_CONTROL 0x1b44
+#define regOTG0_OTG_INTERLACE_CONTROL_BASE_IDX 2
+#define regOTG0_OTG_INTERLACE_STATUS 0x1b45
+#define regOTG0_OTG_INTERLACE_STATUS_BASE_IDX 2
+#define regOTG0_OTG_PIXEL_DATA_READBACK0 0x1b47
+#define regOTG0_OTG_PIXEL_DATA_READBACK0_BASE_IDX 2
+#define regOTG0_OTG_PIXEL_DATA_READBACK1 0x1b48
+#define regOTG0_OTG_PIXEL_DATA_READBACK1_BASE_IDX 2
+#define regOTG0_OTG_STATUS 0x1b49
+#define regOTG0_OTG_STATUS_BASE_IDX 2
+#define regOTG0_OTG_STATUS_POSITION 0x1b4a
+#define regOTG0_OTG_STATUS_POSITION_BASE_IDX 2
+#define regOTG0_OTG_NOM_VERT_POSITION 0x1b4b
+#define regOTG0_OTG_NOM_VERT_POSITION_BASE_IDX 2
+#define regOTG0_OTG_STATUS_FRAME_COUNT 0x1b4c
+#define regOTG0_OTG_STATUS_FRAME_COUNT_BASE_IDX 2
+#define regOTG0_OTG_STATUS_VF_COUNT 0x1b4d
+#define regOTG0_OTG_STATUS_VF_COUNT_BASE_IDX 2
+#define regOTG0_OTG_STATUS_HV_COUNT 0x1b4e
+#define regOTG0_OTG_STATUS_HV_COUNT_BASE_IDX 2
+#define regOTG0_OTG_COUNT_CONTROL 0x1b4f
+#define regOTG0_OTG_COUNT_CONTROL_BASE_IDX 2
+#define regOTG0_OTG_COUNT_RESET 0x1b50
+#define regOTG0_OTG_COUNT_RESET_BASE_IDX 2
+#define regOTG0_OTG_MANUAL_FORCE_VSYNC_NEXT_LINE 0x1b51
+#define regOTG0_OTG_MANUAL_FORCE_VSYNC_NEXT_LINE_BASE_IDX 2
+#define regOTG0_OTG_VERT_SYNC_CONTROL 0x1b52
+#define regOTG0_OTG_VERT_SYNC_CONTROL_BASE_IDX 2
+#define regOTG0_OTG_STEREO_STATUS 0x1b53
+#define regOTG0_OTG_STEREO_STATUS_BASE_IDX 2
+#define regOTG0_OTG_STEREO_CONTROL 0x1b54
+#define regOTG0_OTG_STEREO_CONTROL_BASE_IDX 2
+#define regOTG0_OTG_SNAPSHOT_STATUS 0x1b55
+#define regOTG0_OTG_SNAPSHOT_STATUS_BASE_IDX 2
+#define regOTG0_OTG_SNAPSHOT_CONTROL 0x1b56
+#define regOTG0_OTG_SNAPSHOT_CONTROL_BASE_IDX 2
+#define regOTG0_OTG_SNAPSHOT_POSITION 0x1b57
+#define regOTG0_OTG_SNAPSHOT_POSITION_BASE_IDX 2
+#define regOTG0_OTG_SNAPSHOT_FRAME 0x1b58
+#define regOTG0_OTG_SNAPSHOT_FRAME_BASE_IDX 2
+#define regOTG0_OTG_UPDATE_LOCK 0x1b5a
+#define regOTG0_OTG_UPDATE_LOCK_BASE_IDX 2
+#define regOTG0_OTG_DOUBLE_BUFFER_CONTROL 0x1b5b
+#define regOTG0_OTG_DOUBLE_BUFFER_CONTROL_BASE_IDX 2
+#define regOTG0_OTG_MASTER_EN 0x1b5c
+#define regOTG0_OTG_MASTER_EN_BASE_IDX 2
+#define regOTG0_OTG_VERTICAL_INTERRUPT0_POSITION 0x1b62
+#define regOTG0_OTG_VERTICAL_INTERRUPT0_POSITION_BASE_IDX 2
+#define regOTG0_OTG_VERTICAL_INTERRUPT0_CONTROL 0x1b63
+#define regOTG0_OTG_VERTICAL_INTERRUPT0_CONTROL_BASE_IDX 2
+#define regOTG0_OTG_VERTICAL_INTERRUPT1_POSITION 0x1b64
+#define regOTG0_OTG_VERTICAL_INTERRUPT1_POSITION_BASE_IDX 2
+#define regOTG0_OTG_VERTICAL_INTERRUPT1_CONTROL 0x1b65
+#define regOTG0_OTG_VERTICAL_INTERRUPT1_CONTROL_BASE_IDX 2
+#define regOTG0_OTG_VERTICAL_INTERRUPT2_POSITION 0x1b66
+#define regOTG0_OTG_VERTICAL_INTERRUPT2_POSITION_BASE_IDX 2
+#define regOTG0_OTG_VERTICAL_INTERRUPT2_CONTROL 0x1b67
+#define regOTG0_OTG_VERTICAL_INTERRUPT2_CONTROL_BASE_IDX 2
+#define regOTG0_OTG_CRC_CNTL 0x1b68
+#define regOTG0_OTG_CRC_CNTL_BASE_IDX 2
+#define regOTG0_OTG_CRC_CNTL2 0x1b69
+#define regOTG0_OTG_CRC_CNTL2_BASE_IDX 2
+#define regOTG0_OTG_CRC0_WINDOWA_X_CONTROL 0x1b6a
+#define regOTG0_OTG_CRC0_WINDOWA_X_CONTROL_BASE_IDX 2
+#define regOTG0_OTG_CRC0_WINDOWA_Y_CONTROL 0x1b6b
+#define regOTG0_OTG_CRC0_WINDOWA_Y_CONTROL_BASE_IDX 2
+#define regOTG0_OTG_CRC0_WINDOWB_X_CONTROL 0x1b6c
+#define regOTG0_OTG_CRC0_WINDOWB_X_CONTROL_BASE_IDX 2
+#define regOTG0_OTG_CRC0_WINDOWB_Y_CONTROL 0x1b6d
+#define regOTG0_OTG_CRC0_WINDOWB_Y_CONTROL_BASE_IDX 2
+#define regOTG0_OTG_CRC0_DATA_RG 0x1b6e
+#define regOTG0_OTG_CRC0_DATA_RG_BASE_IDX 2
+#define regOTG0_OTG_CRC0_DATA_B 0x1b6f
+#define regOTG0_OTG_CRC0_DATA_B_BASE_IDX 2
+#define regOTG0_OTG_CRC1_WINDOWA_X_CONTROL 0x1b70
+#define regOTG0_OTG_CRC1_WINDOWA_X_CONTROL_BASE_IDX 2
+#define regOTG0_OTG_CRC1_WINDOWA_Y_CONTROL 0x1b71
+#define regOTG0_OTG_CRC1_WINDOWA_Y_CONTROL_BASE_IDX 2
+#define regOTG0_OTG_CRC1_WINDOWB_X_CONTROL 0x1b72
+#define regOTG0_OTG_CRC1_WINDOWB_X_CONTROL_BASE_IDX 2
+#define regOTG0_OTG_CRC1_WINDOWB_Y_CONTROL 0x1b73
+#define regOTG0_OTG_CRC1_WINDOWB_Y_CONTROL_BASE_IDX 2
+#define regOTG0_OTG_CRC1_DATA_RG 0x1b74
+#define regOTG0_OTG_CRC1_DATA_RG_BASE_IDX 2
+#define regOTG0_OTG_CRC1_DATA_B 0x1b75
+#define regOTG0_OTG_CRC1_DATA_B_BASE_IDX 2
+#define regOTG0_OTG_CRC2_DATA_RG 0x1b76
+#define regOTG0_OTG_CRC2_DATA_RG_BASE_IDX 2
+#define regOTG0_OTG_CRC2_DATA_B 0x1b77
+#define regOTG0_OTG_CRC2_DATA_B_BASE_IDX 2
+#define regOTG0_OTG_CRC3_DATA_RG 0x1b78
+#define regOTG0_OTG_CRC3_DATA_RG_BASE_IDX 2
+#define regOTG0_OTG_CRC3_DATA_B 0x1b79
+#define regOTG0_OTG_CRC3_DATA_B_BASE_IDX 2
+#define regOTG0_OTG_CRC_SIG_RED_GREEN_MASK 0x1b7a
+#define regOTG0_OTG_CRC_SIG_RED_GREEN_MASK_BASE_IDX 2
+#define regOTG0_OTG_CRC_SIG_BLUE_CONTROL_MASK 0x1b7b
+#define regOTG0_OTG_CRC_SIG_BLUE_CONTROL_MASK_BASE_IDX 2
+#define regOTG0_OTG_STATIC_SCREEN_CONTROL 0x1b82
+#define regOTG0_OTG_STATIC_SCREEN_CONTROL_BASE_IDX 2
+#define regOTG0_OTG_3D_STRUCTURE_CONTROL 0x1b83
+#define regOTG0_OTG_3D_STRUCTURE_CONTROL_BASE_IDX 2
+#define regOTG0_OTG_GSL_VSYNC_GAP 0x1b84
+#define regOTG0_OTG_GSL_VSYNC_GAP_BASE_IDX 2
+#define regOTG0_OTG_MASTER_UPDATE_MODE 0x1b85
+#define regOTG0_OTG_MASTER_UPDATE_MODE_BASE_IDX 2
+#define regOTG0_OTG_CLOCK_CONTROL 0x1b86
+#define regOTG0_OTG_CLOCK_CONTROL_BASE_IDX 2
+#define regOTG0_OTG_VSTARTUP_PARAM 0x1b87
+#define regOTG0_OTG_VSTARTUP_PARAM_BASE_IDX 2
+#define regOTG0_OTG_VUPDATE_PARAM 0x1b88
+#define regOTG0_OTG_VUPDATE_PARAM_BASE_IDX 2
+#define regOTG0_OTG_VREADY_PARAM 0x1b89
+#define regOTG0_OTG_VREADY_PARAM_BASE_IDX 2
+#define regOTG0_OTG_GLOBAL_SYNC_STATUS 0x1b8a
+#define regOTG0_OTG_GLOBAL_SYNC_STATUS_BASE_IDX 2
+#define regOTG0_OTG_MASTER_UPDATE_LOCK 0x1b8b
+#define regOTG0_OTG_MASTER_UPDATE_LOCK_BASE_IDX 2
+#define regOTG0_OTG_GSL_CONTROL 0x1b8c
+#define regOTG0_OTG_GSL_CONTROL_BASE_IDX 2
+#define regOTG0_OTG_GSL_WINDOW_X 0x1b8d
+#define regOTG0_OTG_GSL_WINDOW_X_BASE_IDX 2
+#define regOTG0_OTG_GSL_WINDOW_Y 0x1b8e
+#define regOTG0_OTG_GSL_WINDOW_Y_BASE_IDX 2
+#define regOTG0_OTG_VUPDATE_KEEPOUT 0x1b8f
+#define regOTG0_OTG_VUPDATE_KEEPOUT_BASE_IDX 2
+#define regOTG0_OTG_GLOBAL_CONTROL0 0x1b90
+#define regOTG0_OTG_GLOBAL_CONTROL0_BASE_IDX 2
+#define regOTG0_OTG_GLOBAL_CONTROL1 0x1b91
+#define regOTG0_OTG_GLOBAL_CONTROL1_BASE_IDX 2
+#define regOTG0_OTG_GLOBAL_CONTROL2 0x1b92
+#define regOTG0_OTG_GLOBAL_CONTROL2_BASE_IDX 2
+#define regOTG0_OTG_GLOBAL_CONTROL3 0x1b93
+#define regOTG0_OTG_GLOBAL_CONTROL3_BASE_IDX 2
+#define regOTG0_OTG_GLOBAL_CONTROL4 0x1b94
+#define regOTG0_OTG_GLOBAL_CONTROL4_BASE_IDX 2
+#define regOTG0_OTG_TRIG_MANUAL_CONTROL 0x1b95
+#define regOTG0_OTG_TRIG_MANUAL_CONTROL_BASE_IDX 2
+#define regOTG0_OTG_MANUAL_FLOW_CONTROL 0x1b96
+#define regOTG0_OTG_MANUAL_FLOW_CONTROL_BASE_IDX 2
+#define regOTG0_OTG_DRR_TIMING_INT_STATUS 0x1b97
+#define regOTG0_OTG_DRR_TIMING_INT_STATUS_BASE_IDX 2
+#define regOTG0_OTG_DRR_V_TOTAL_REACH_RANGE 0x1b98
+#define regOTG0_OTG_DRR_V_TOTAL_REACH_RANGE_BASE_IDX 2
+#define regOTG0_OTG_DRR_V_TOTAL_CHANGE 0x1b99
+#define regOTG0_OTG_DRR_V_TOTAL_CHANGE_BASE_IDX 2
+#define regOTG0_OTG_DRR_TRIGGER_WINDOW 0x1b9a
+#define regOTG0_OTG_DRR_TRIGGER_WINDOW_BASE_IDX 2
+#define regOTG0_OTG_DRR_CONTROL 0x1b9b
+#define regOTG0_OTG_DRR_CONTROL_BASE_IDX 2
+#define regOTG0_OTG_M_CONST_DTO0 0x1b9c
+#define regOTG0_OTG_M_CONST_DTO0_BASE_IDX 2
+#define regOTG0_OTG_M_CONST_DTO1 0x1b9d
+#define regOTG0_OTG_M_CONST_DTO1_BASE_IDX 2
+#define regOTG0_OTG_REQUEST_CONTROL 0x1b9e
+#define regOTG0_OTG_REQUEST_CONTROL_BASE_IDX 2
+#define regOTG0_OTG_DSC_START_POSITION 0x1b9f
+#define regOTG0_OTG_DSC_START_POSITION_BASE_IDX 2
+#define regOTG0_OTG_PIPE_UPDATE_STATUS 0x1ba0
+#define regOTG0_OTG_PIPE_UPDATE_STATUS_BASE_IDX 2
+#define regOTG0_OTG_SPARE_REGISTER 0x1ba2
+#define regOTG0_OTG_SPARE_REGISTER_BASE_IDX 2
+
+
+// addressBlock: dce_dc_optc_otg1_dispdec
+// base address: 0x200
+#define regOTG1_OTG_H_TOTAL 0x1baa
+#define regOTG1_OTG_H_TOTAL_BASE_IDX 2
+#define regOTG1_OTG_H_BLANK_START_END 0x1bab
+#define regOTG1_OTG_H_BLANK_START_END_BASE_IDX 2
+#define regOTG1_OTG_H_SYNC_A 0x1bac
+#define regOTG1_OTG_H_SYNC_A_BASE_IDX 2
+#define regOTG1_OTG_H_SYNC_A_CNTL 0x1bad
+#define regOTG1_OTG_H_SYNC_A_CNTL_BASE_IDX 2
+#define regOTG1_OTG_H_TIMING_CNTL 0x1bae
+#define regOTG1_OTG_H_TIMING_CNTL_BASE_IDX 2
+#define regOTG1_OTG_V_TOTAL 0x1baf
+#define regOTG1_OTG_V_TOTAL_BASE_IDX 2
+#define regOTG1_OTG_V_TOTAL_MIN 0x1bb0
+#define regOTG1_OTG_V_TOTAL_MIN_BASE_IDX 2
+#define regOTG1_OTG_V_TOTAL_MAX 0x1bb1
+#define regOTG1_OTG_V_TOTAL_MAX_BASE_IDX 2
+#define regOTG1_OTG_V_TOTAL_MID 0x1bb2
+#define regOTG1_OTG_V_TOTAL_MID_BASE_IDX 2
+#define regOTG1_OTG_V_TOTAL_CONTROL 0x1bb3
+#define regOTG1_OTG_V_TOTAL_CONTROL_BASE_IDX 2
+#define regOTG1_OTG_V_TOTAL_INT_STATUS 0x1bb4
+#define regOTG1_OTG_V_TOTAL_INT_STATUS_BASE_IDX 2
+#define regOTG1_OTG_VSYNC_NOM_INT_STATUS 0x1bb5
+#define regOTG1_OTG_VSYNC_NOM_INT_STATUS_BASE_IDX 2
+#define regOTG1_OTG_V_BLANK_START_END 0x1bb6
+#define regOTG1_OTG_V_BLANK_START_END_BASE_IDX 2
+#define regOTG1_OTG_V_SYNC_A 0x1bb7
+#define regOTG1_OTG_V_SYNC_A_BASE_IDX 2
+#define regOTG1_OTG_V_SYNC_A_CNTL 0x1bb8
+#define regOTG1_OTG_V_SYNC_A_CNTL_BASE_IDX 2
+#define regOTG1_OTG_TRIGA_CNTL 0x1bb9
+#define regOTG1_OTG_TRIGA_CNTL_BASE_IDX 2
+#define regOTG1_OTG_TRIGA_MANUAL_TRIG 0x1bba
+#define regOTG1_OTG_TRIGA_MANUAL_TRIG_BASE_IDX 2
+#define regOTG1_OTG_TRIGB_CNTL 0x1bbb
+#define regOTG1_OTG_TRIGB_CNTL_BASE_IDX 2
+#define regOTG1_OTG_TRIGB_MANUAL_TRIG 0x1bbc
+#define regOTG1_OTG_TRIGB_MANUAL_TRIG_BASE_IDX 2
+#define regOTG1_OTG_FORCE_COUNT_NOW_CNTL 0x1bbd
+#define regOTG1_OTG_FORCE_COUNT_NOW_CNTL_BASE_IDX 2
+#define regOTG1_OTG_FLOW_CONTROL 0x1bbe
+#define regOTG1_OTG_FLOW_CONTROL_BASE_IDX 2
+#define regOTG1_OTG_STEREO_FORCE_NEXT_EYE 0x1bbf
+#define regOTG1_OTG_STEREO_FORCE_NEXT_EYE_BASE_IDX 2
+#define regOTG1_OTG_CONTROL 0x1bc1
+#define regOTG1_OTG_CONTROL_BASE_IDX 2
+#define regOTG1_OTG_INTERLACE_CONTROL 0x1bc4
+#define regOTG1_OTG_INTERLACE_CONTROL_BASE_IDX 2
+#define regOTG1_OTG_INTERLACE_STATUS 0x1bc5
+#define regOTG1_OTG_INTERLACE_STATUS_BASE_IDX 2
+#define regOTG1_OTG_PIXEL_DATA_READBACK0 0x1bc7
+#define regOTG1_OTG_PIXEL_DATA_READBACK0_BASE_IDX 2
+#define regOTG1_OTG_PIXEL_DATA_READBACK1 0x1bc8
+#define regOTG1_OTG_PIXEL_DATA_READBACK1_BASE_IDX 2
+#define regOTG1_OTG_STATUS 0x1bc9
+#define regOTG1_OTG_STATUS_BASE_IDX 2
+#define regOTG1_OTG_STATUS_POSITION 0x1bca
+#define regOTG1_OTG_STATUS_POSITION_BASE_IDX 2
+#define regOTG1_OTG_NOM_VERT_POSITION 0x1bcb
+#define regOTG1_OTG_NOM_VERT_POSITION_BASE_IDX 2
+#define regOTG1_OTG_STATUS_FRAME_COUNT 0x1bcc
+#define regOTG1_OTG_STATUS_FRAME_COUNT_BASE_IDX 2
+#define regOTG1_OTG_STATUS_VF_COUNT 0x1bcd
+#define regOTG1_OTG_STATUS_VF_COUNT_BASE_IDX 2
+#define regOTG1_OTG_STATUS_HV_COUNT 0x1bce
+#define regOTG1_OTG_STATUS_HV_COUNT_BASE_IDX 2
+#define regOTG1_OTG_COUNT_CONTROL 0x1bcf
+#define regOTG1_OTG_COUNT_CONTROL_BASE_IDX 2
+#define regOTG1_OTG_COUNT_RESET 0x1bd0
+#define regOTG1_OTG_COUNT_RESET_BASE_IDX 2
+#define regOTG1_OTG_MANUAL_FORCE_VSYNC_NEXT_LINE 0x1bd1
+#define regOTG1_OTG_MANUAL_FORCE_VSYNC_NEXT_LINE_BASE_IDX 2
+#define regOTG1_OTG_VERT_SYNC_CONTROL 0x1bd2
+#define regOTG1_OTG_VERT_SYNC_CONTROL_BASE_IDX 2
+#define regOTG1_OTG_STEREO_STATUS 0x1bd3
+#define regOTG1_OTG_STEREO_STATUS_BASE_IDX 2
+#define regOTG1_OTG_STEREO_CONTROL 0x1bd4
+#define regOTG1_OTG_STEREO_CONTROL_BASE_IDX 2
+#define regOTG1_OTG_SNAPSHOT_STATUS 0x1bd5
+#define regOTG1_OTG_SNAPSHOT_STATUS_BASE_IDX 2
+#define regOTG1_OTG_SNAPSHOT_CONTROL 0x1bd6
+#define regOTG1_OTG_SNAPSHOT_CONTROL_BASE_IDX 2
+#define regOTG1_OTG_SNAPSHOT_POSITION 0x1bd7
+#define regOTG1_OTG_SNAPSHOT_POSITION_BASE_IDX 2
+#define regOTG1_OTG_SNAPSHOT_FRAME 0x1bd8
+#define regOTG1_OTG_SNAPSHOT_FRAME_BASE_IDX 2
+#define regOTG1_OTG_UPDATE_LOCK 0x1bda
+#define regOTG1_OTG_UPDATE_LOCK_BASE_IDX 2
+#define regOTG1_OTG_DOUBLE_BUFFER_CONTROL 0x1bdb
+#define regOTG1_OTG_DOUBLE_BUFFER_CONTROL_BASE_IDX 2
+#define regOTG1_OTG_MASTER_EN 0x1bdc
+#define regOTG1_OTG_MASTER_EN_BASE_IDX 2
+#define regOTG1_OTG_VERTICAL_INTERRUPT0_POSITION 0x1be2
+#define regOTG1_OTG_VERTICAL_INTERRUPT0_POSITION_BASE_IDX 2
+#define regOTG1_OTG_VERTICAL_INTERRUPT0_CONTROL 0x1be3
+#define regOTG1_OTG_VERTICAL_INTERRUPT0_CONTROL_BASE_IDX 2
+#define regOTG1_OTG_VERTICAL_INTERRUPT1_POSITION 0x1be4
+#define regOTG1_OTG_VERTICAL_INTERRUPT1_POSITION_BASE_IDX 2
+#define regOTG1_OTG_VERTICAL_INTERRUPT1_CONTROL 0x1be5
+#define regOTG1_OTG_VERTICAL_INTERRUPT1_CONTROL_BASE_IDX 2
+#define regOTG1_OTG_VERTICAL_INTERRUPT2_POSITION 0x1be6
+#define regOTG1_OTG_VERTICAL_INTERRUPT2_POSITION_BASE_IDX 2
+#define regOTG1_OTG_VERTICAL_INTERRUPT2_CONTROL 0x1be7
+#define regOTG1_OTG_VERTICAL_INTERRUPT2_CONTROL_BASE_IDX 2
+#define regOTG1_OTG_CRC_CNTL 0x1be8
+#define regOTG1_OTG_CRC_CNTL_BASE_IDX 2
+#define regOTG1_OTG_CRC_CNTL2 0x1be9
+#define regOTG1_OTG_CRC_CNTL2_BASE_IDX 2
+#define regOTG1_OTG_CRC0_WINDOWA_X_CONTROL 0x1bea
+#define regOTG1_OTG_CRC0_WINDOWA_X_CONTROL_BASE_IDX 2
+#define regOTG1_OTG_CRC0_WINDOWA_Y_CONTROL 0x1beb
+#define regOTG1_OTG_CRC0_WINDOWA_Y_CONTROL_BASE_IDX 2
+#define regOTG1_OTG_CRC0_WINDOWB_X_CONTROL 0x1bec
+#define regOTG1_OTG_CRC0_WINDOWB_X_CONTROL_BASE_IDX 2
+#define regOTG1_OTG_CRC0_WINDOWB_Y_CONTROL 0x1bed
+#define regOTG1_OTG_CRC0_WINDOWB_Y_CONTROL_BASE_IDX 2
+#define regOTG1_OTG_CRC0_DATA_RG 0x1bee
+#define regOTG1_OTG_CRC0_DATA_RG_BASE_IDX 2
+#define regOTG1_OTG_CRC0_DATA_B 0x1bef
+#define regOTG1_OTG_CRC0_DATA_B_BASE_IDX 2
+#define regOTG1_OTG_CRC1_WINDOWA_X_CONTROL 0x1bf0
+#define regOTG1_OTG_CRC1_WINDOWA_X_CONTROL_BASE_IDX 2
+#define regOTG1_OTG_CRC1_WINDOWA_Y_CONTROL 0x1bf1
+#define regOTG1_OTG_CRC1_WINDOWA_Y_CONTROL_BASE_IDX 2
+#define regOTG1_OTG_CRC1_WINDOWB_X_CONTROL 0x1bf2
+#define regOTG1_OTG_CRC1_WINDOWB_X_CONTROL_BASE_IDX 2
+#define regOTG1_OTG_CRC1_WINDOWB_Y_CONTROL 0x1bf3
+#define regOTG1_OTG_CRC1_WINDOWB_Y_CONTROL_BASE_IDX 2
+#define regOTG1_OTG_CRC1_DATA_RG 0x1bf4
+#define regOTG1_OTG_CRC1_DATA_RG_BASE_IDX 2
+#define regOTG1_OTG_CRC1_DATA_B 0x1bf5
+#define regOTG1_OTG_CRC1_DATA_B_BASE_IDX 2
+#define regOTG1_OTG_CRC2_DATA_RG 0x1bf6
+#define regOTG1_OTG_CRC2_DATA_RG_BASE_IDX 2
+#define regOTG1_OTG_CRC2_DATA_B 0x1bf7
+#define regOTG1_OTG_CRC2_DATA_B_BASE_IDX 2
+#define regOTG1_OTG_CRC3_DATA_RG 0x1bf8
+#define regOTG1_OTG_CRC3_DATA_RG_BASE_IDX 2
+#define regOTG1_OTG_CRC3_DATA_B 0x1bf9
+#define regOTG1_OTG_CRC3_DATA_B_BASE_IDX 2
+#define regOTG1_OTG_CRC_SIG_RED_GREEN_MASK 0x1bfa
+#define regOTG1_OTG_CRC_SIG_RED_GREEN_MASK_BASE_IDX 2
+#define regOTG1_OTG_CRC_SIG_BLUE_CONTROL_MASK 0x1bfb
+#define regOTG1_OTG_CRC_SIG_BLUE_CONTROL_MASK_BASE_IDX 2
+#define regOTG1_OTG_STATIC_SCREEN_CONTROL 0x1c02
+#define regOTG1_OTG_STATIC_SCREEN_CONTROL_BASE_IDX 2
+#define regOTG1_OTG_3D_STRUCTURE_CONTROL 0x1c03
+#define regOTG1_OTG_3D_STRUCTURE_CONTROL_BASE_IDX 2
+#define regOTG1_OTG_GSL_VSYNC_GAP 0x1c04
+#define regOTG1_OTG_GSL_VSYNC_GAP_BASE_IDX 2
+#define regOTG1_OTG_MASTER_UPDATE_MODE 0x1c05
+#define regOTG1_OTG_MASTER_UPDATE_MODE_BASE_IDX 2
+#define regOTG1_OTG_CLOCK_CONTROL 0x1c06
+#define regOTG1_OTG_CLOCK_CONTROL_BASE_IDX 2
+#define regOTG1_OTG_VSTARTUP_PARAM 0x1c07
+#define regOTG1_OTG_VSTARTUP_PARAM_BASE_IDX 2
+#define regOTG1_OTG_VUPDATE_PARAM 0x1c08
+#define regOTG1_OTG_VUPDATE_PARAM_BASE_IDX 2
+#define regOTG1_OTG_VREADY_PARAM 0x1c09
+#define regOTG1_OTG_VREADY_PARAM_BASE_IDX 2
+#define regOTG1_OTG_GLOBAL_SYNC_STATUS 0x1c0a
+#define regOTG1_OTG_GLOBAL_SYNC_STATUS_BASE_IDX 2
+#define regOTG1_OTG_MASTER_UPDATE_LOCK 0x1c0b
+#define regOTG1_OTG_MASTER_UPDATE_LOCK_BASE_IDX 2
+#define regOTG1_OTG_GSL_CONTROL 0x1c0c
+#define regOTG1_OTG_GSL_CONTROL_BASE_IDX 2
+#define regOTG1_OTG_GSL_WINDOW_X 0x1c0d
+#define regOTG1_OTG_GSL_WINDOW_X_BASE_IDX 2
+#define regOTG1_OTG_GSL_WINDOW_Y 0x1c0e
+#define regOTG1_OTG_GSL_WINDOW_Y_BASE_IDX 2
+#define regOTG1_OTG_VUPDATE_KEEPOUT 0x1c0f
+#define regOTG1_OTG_VUPDATE_KEEPOUT_BASE_IDX 2
+#define regOTG1_OTG_GLOBAL_CONTROL0 0x1c10
+#define regOTG1_OTG_GLOBAL_CONTROL0_BASE_IDX 2
+#define regOTG1_OTG_GLOBAL_CONTROL1 0x1c11
+#define regOTG1_OTG_GLOBAL_CONTROL1_BASE_IDX 2
+#define regOTG1_OTG_GLOBAL_CONTROL2 0x1c12
+#define regOTG1_OTG_GLOBAL_CONTROL2_BASE_IDX 2
+#define regOTG1_OTG_GLOBAL_CONTROL3 0x1c13
+#define regOTG1_OTG_GLOBAL_CONTROL3_BASE_IDX 2
+#define regOTG1_OTG_GLOBAL_CONTROL4 0x1c14
+#define regOTG1_OTG_GLOBAL_CONTROL4_BASE_IDX 2
+#define regOTG1_OTG_TRIG_MANUAL_CONTROL 0x1c15
+#define regOTG1_OTG_TRIG_MANUAL_CONTROL_BASE_IDX 2
+#define regOTG1_OTG_MANUAL_FLOW_CONTROL 0x1c16
+#define regOTG1_OTG_MANUAL_FLOW_CONTROL_BASE_IDX 2
+#define regOTG1_OTG_DRR_TIMING_INT_STATUS 0x1c17
+#define regOTG1_OTG_DRR_TIMING_INT_STATUS_BASE_IDX 2
+#define regOTG1_OTG_DRR_V_TOTAL_REACH_RANGE 0x1c18
+#define regOTG1_OTG_DRR_V_TOTAL_REACH_RANGE_BASE_IDX 2
+#define regOTG1_OTG_DRR_V_TOTAL_CHANGE 0x1c19
+#define regOTG1_OTG_DRR_V_TOTAL_CHANGE_BASE_IDX 2
+#define regOTG1_OTG_DRR_TRIGGER_WINDOW 0x1c1a
+#define regOTG1_OTG_DRR_TRIGGER_WINDOW_BASE_IDX 2
+#define regOTG1_OTG_DRR_CONTROL 0x1c1b
+#define regOTG1_OTG_DRR_CONTROL_BASE_IDX 2
+#define regOTG1_OTG_M_CONST_DTO0 0x1c1c
+#define regOTG1_OTG_M_CONST_DTO0_BASE_IDX 2
+#define regOTG1_OTG_M_CONST_DTO1 0x1c1d
+#define regOTG1_OTG_M_CONST_DTO1_BASE_IDX 2
+#define regOTG1_OTG_REQUEST_CONTROL 0x1c1e
+#define regOTG1_OTG_REQUEST_CONTROL_BASE_IDX 2
+#define regOTG1_OTG_DSC_START_POSITION 0x1c1f
+#define regOTG1_OTG_DSC_START_POSITION_BASE_IDX 2
+#define regOTG1_OTG_PIPE_UPDATE_STATUS 0x1c20
+#define regOTG1_OTG_PIPE_UPDATE_STATUS_BASE_IDX 2
+#define regOTG1_OTG_SPARE_REGISTER 0x1c22
+#define regOTG1_OTG_SPARE_REGISTER_BASE_IDX 2
+
+
+// addressBlock: dce_dc_optc_otg2_dispdec
+// base address: 0x400
+#define regOTG2_OTG_H_TOTAL 0x1c2a
+#define regOTG2_OTG_H_TOTAL_BASE_IDX 2
+#define regOTG2_OTG_H_BLANK_START_END 0x1c2b
+#define regOTG2_OTG_H_BLANK_START_END_BASE_IDX 2
+#define regOTG2_OTG_H_SYNC_A 0x1c2c
+#define regOTG2_OTG_H_SYNC_A_BASE_IDX 2
+#define regOTG2_OTG_H_SYNC_A_CNTL 0x1c2d
+#define regOTG2_OTG_H_SYNC_A_CNTL_BASE_IDX 2
+#define regOTG2_OTG_H_TIMING_CNTL 0x1c2e
+#define regOTG2_OTG_H_TIMING_CNTL_BASE_IDX 2
+#define regOTG2_OTG_V_TOTAL 0x1c2f
+#define regOTG2_OTG_V_TOTAL_BASE_IDX 2
+#define regOTG2_OTG_V_TOTAL_MIN 0x1c30
+#define regOTG2_OTG_V_TOTAL_MIN_BASE_IDX 2
+#define regOTG2_OTG_V_TOTAL_MAX 0x1c31
+#define regOTG2_OTG_V_TOTAL_MAX_BASE_IDX 2
+#define regOTG2_OTG_V_TOTAL_MID 0x1c32
+#define regOTG2_OTG_V_TOTAL_MID_BASE_IDX 2
+#define regOTG2_OTG_V_TOTAL_CONTROL 0x1c33
+#define regOTG2_OTG_V_TOTAL_CONTROL_BASE_IDX 2
+#define regOTG2_OTG_V_TOTAL_INT_STATUS 0x1c34
+#define regOTG2_OTG_V_TOTAL_INT_STATUS_BASE_IDX 2
+#define regOTG2_OTG_VSYNC_NOM_INT_STATUS 0x1c35
+#define regOTG2_OTG_VSYNC_NOM_INT_STATUS_BASE_IDX 2
+#define regOTG2_OTG_V_BLANK_START_END 0x1c36
+#define regOTG2_OTG_V_BLANK_START_END_BASE_IDX 2
+#define regOTG2_OTG_V_SYNC_A 0x1c37
+#define regOTG2_OTG_V_SYNC_A_BASE_IDX 2
+#define regOTG2_OTG_V_SYNC_A_CNTL 0x1c38
+#define regOTG2_OTG_V_SYNC_A_CNTL_BASE_IDX 2
+#define regOTG2_OTG_TRIGA_CNTL 0x1c39
+#define regOTG2_OTG_TRIGA_CNTL_BASE_IDX 2
+#define regOTG2_OTG_TRIGA_MANUAL_TRIG 0x1c3a
+#define regOTG2_OTG_TRIGA_MANUAL_TRIG_BASE_IDX 2
+#define regOTG2_OTG_TRIGB_CNTL 0x1c3b
+#define regOTG2_OTG_TRIGB_CNTL_BASE_IDX 2
+#define regOTG2_OTG_TRIGB_MANUAL_TRIG 0x1c3c
+#define regOTG2_OTG_TRIGB_MANUAL_TRIG_BASE_IDX 2
+#define regOTG2_OTG_FORCE_COUNT_NOW_CNTL 0x1c3d
+#define regOTG2_OTG_FORCE_COUNT_NOW_CNTL_BASE_IDX 2
+#define regOTG2_OTG_FLOW_CONTROL 0x1c3e
+#define regOTG2_OTG_FLOW_CONTROL_BASE_IDX 2
+#define regOTG2_OTG_STEREO_FORCE_NEXT_EYE 0x1c3f
+#define regOTG2_OTG_STEREO_FORCE_NEXT_EYE_BASE_IDX 2
+#define regOTG2_OTG_CONTROL 0x1c41
+#define regOTG2_OTG_CONTROL_BASE_IDX 2
+#define regOTG2_OTG_INTERLACE_CONTROL 0x1c44
+#define regOTG2_OTG_INTERLACE_CONTROL_BASE_IDX 2
+#define regOTG2_OTG_INTERLACE_STATUS 0x1c45
+#define regOTG2_OTG_INTERLACE_STATUS_BASE_IDX 2
+#define regOTG2_OTG_PIXEL_DATA_READBACK0 0x1c47
+#define regOTG2_OTG_PIXEL_DATA_READBACK0_BASE_IDX 2
+#define regOTG2_OTG_PIXEL_DATA_READBACK1 0x1c48
+#define regOTG2_OTG_PIXEL_DATA_READBACK1_BASE_IDX 2
+#define regOTG2_OTG_STATUS 0x1c49
+#define regOTG2_OTG_STATUS_BASE_IDX 2
+#define regOTG2_OTG_STATUS_POSITION 0x1c4a
+#define regOTG2_OTG_STATUS_POSITION_BASE_IDX 2
+#define regOTG2_OTG_NOM_VERT_POSITION 0x1c4b
+#define regOTG2_OTG_NOM_VERT_POSITION_BASE_IDX 2
+#define regOTG2_OTG_STATUS_FRAME_COUNT 0x1c4c
+#define regOTG2_OTG_STATUS_FRAME_COUNT_BASE_IDX 2
+#define regOTG2_OTG_STATUS_VF_COUNT 0x1c4d
+#define regOTG2_OTG_STATUS_VF_COUNT_BASE_IDX 2
+#define regOTG2_OTG_STATUS_HV_COUNT 0x1c4e
+#define regOTG2_OTG_STATUS_HV_COUNT_BASE_IDX 2
+#define regOTG2_OTG_COUNT_CONTROL 0x1c4f
+#define regOTG2_OTG_COUNT_CONTROL_BASE_IDX 2
+#define regOTG2_OTG_COUNT_RESET 0x1c50
+#define regOTG2_OTG_COUNT_RESET_BASE_IDX 2
+#define regOTG2_OTG_MANUAL_FORCE_VSYNC_NEXT_LINE 0x1c51
+#define regOTG2_OTG_MANUAL_FORCE_VSYNC_NEXT_LINE_BASE_IDX 2
+#define regOTG2_OTG_VERT_SYNC_CONTROL 0x1c52
+#define regOTG2_OTG_VERT_SYNC_CONTROL_BASE_IDX 2
+#define regOTG2_OTG_STEREO_STATUS 0x1c53
+#define regOTG2_OTG_STEREO_STATUS_BASE_IDX 2
+#define regOTG2_OTG_STEREO_CONTROL 0x1c54
+#define regOTG2_OTG_STEREO_CONTROL_BASE_IDX 2
+#define regOTG2_OTG_SNAPSHOT_STATUS 0x1c55
+#define regOTG2_OTG_SNAPSHOT_STATUS_BASE_IDX 2
+#define regOTG2_OTG_SNAPSHOT_CONTROL 0x1c56
+#define regOTG2_OTG_SNAPSHOT_CONTROL_BASE_IDX 2
+#define regOTG2_OTG_SNAPSHOT_POSITION 0x1c57
+#define regOTG2_OTG_SNAPSHOT_POSITION_BASE_IDX 2
+#define regOTG2_OTG_SNAPSHOT_FRAME 0x1c58
+#define regOTG2_OTG_SNAPSHOT_FRAME_BASE_IDX 2
+#define regOTG2_OTG_UPDATE_LOCK 0x1c5a
+#define regOTG2_OTG_UPDATE_LOCK_BASE_IDX 2
+#define regOTG2_OTG_DOUBLE_BUFFER_CONTROL 0x1c5b
+#define regOTG2_OTG_DOUBLE_BUFFER_CONTROL_BASE_IDX 2
+#define regOTG2_OTG_MASTER_EN 0x1c5c
+#define regOTG2_OTG_MASTER_EN_BASE_IDX 2
+#define regOTG2_OTG_VERTICAL_INTERRUPT0_POSITION 0x1c62
+#define regOTG2_OTG_VERTICAL_INTERRUPT0_POSITION_BASE_IDX 2
+#define regOTG2_OTG_VERTICAL_INTERRUPT0_CONTROL 0x1c63
+#define regOTG2_OTG_VERTICAL_INTERRUPT0_CONTROL_BASE_IDX 2
+#define regOTG2_OTG_VERTICAL_INTERRUPT1_POSITION 0x1c64
+#define regOTG2_OTG_VERTICAL_INTERRUPT1_POSITION_BASE_IDX 2
+#define regOTG2_OTG_VERTICAL_INTERRUPT1_CONTROL 0x1c65
+#define regOTG2_OTG_VERTICAL_INTERRUPT1_CONTROL_BASE_IDX 2
+#define regOTG2_OTG_VERTICAL_INTERRUPT2_POSITION 0x1c66
+#define regOTG2_OTG_VERTICAL_INTERRUPT2_POSITION_BASE_IDX 2
+#define regOTG2_OTG_VERTICAL_INTERRUPT2_CONTROL 0x1c67
+#define regOTG2_OTG_VERTICAL_INTERRUPT2_CONTROL_BASE_IDX 2
+#define regOTG2_OTG_CRC_CNTL 0x1c68
+#define regOTG2_OTG_CRC_CNTL_BASE_IDX 2
+#define regOTG2_OTG_CRC_CNTL2 0x1c69
+#define regOTG2_OTG_CRC_CNTL2_BASE_IDX 2
+#define regOTG2_OTG_CRC0_WINDOWA_X_CONTROL 0x1c6a
+#define regOTG2_OTG_CRC0_WINDOWA_X_CONTROL_BASE_IDX 2
+#define regOTG2_OTG_CRC0_WINDOWA_Y_CONTROL 0x1c6b
+#define regOTG2_OTG_CRC0_WINDOWA_Y_CONTROL_BASE_IDX 2
+#define regOTG2_OTG_CRC0_WINDOWB_X_CONTROL 0x1c6c
+#define regOTG2_OTG_CRC0_WINDOWB_X_CONTROL_BASE_IDX 2
+#define regOTG2_OTG_CRC0_WINDOWB_Y_CONTROL 0x1c6d
+#define regOTG2_OTG_CRC0_WINDOWB_Y_CONTROL_BASE_IDX 2
+#define regOTG2_OTG_CRC0_DATA_RG 0x1c6e
+#define regOTG2_OTG_CRC0_DATA_RG_BASE_IDX 2
+#define regOTG2_OTG_CRC0_DATA_B 0x1c6f
+#define regOTG2_OTG_CRC0_DATA_B_BASE_IDX 2
+#define regOTG2_OTG_CRC1_WINDOWA_X_CONTROL 0x1c70
+#define regOTG2_OTG_CRC1_WINDOWA_X_CONTROL_BASE_IDX 2
+#define regOTG2_OTG_CRC1_WINDOWA_Y_CONTROL 0x1c71
+#define regOTG2_OTG_CRC1_WINDOWA_Y_CONTROL_BASE_IDX 2
+#define regOTG2_OTG_CRC1_WINDOWB_X_CONTROL 0x1c72
+#define regOTG2_OTG_CRC1_WINDOWB_X_CONTROL_BASE_IDX 2
+#define regOTG2_OTG_CRC1_WINDOWB_Y_CONTROL 0x1c73
+#define regOTG2_OTG_CRC1_WINDOWB_Y_CONTROL_BASE_IDX 2
+#define regOTG2_OTG_CRC1_DATA_RG 0x1c74
+#define regOTG2_OTG_CRC1_DATA_RG_BASE_IDX 2
+#define regOTG2_OTG_CRC1_DATA_B 0x1c75
+#define regOTG2_OTG_CRC1_DATA_B_BASE_IDX 2
+#define regOTG2_OTG_CRC2_DATA_RG 0x1c76
+#define regOTG2_OTG_CRC2_DATA_RG_BASE_IDX 2
+#define regOTG2_OTG_CRC2_DATA_B 0x1c77
+#define regOTG2_OTG_CRC2_DATA_B_BASE_IDX 2
+#define regOTG2_OTG_CRC3_DATA_RG 0x1c78
+#define regOTG2_OTG_CRC3_DATA_RG_BASE_IDX 2
+#define regOTG2_OTG_CRC3_DATA_B 0x1c79
+#define regOTG2_OTG_CRC3_DATA_B_BASE_IDX 2
+#define regOTG2_OTG_CRC_SIG_RED_GREEN_MASK 0x1c7a
+#define regOTG2_OTG_CRC_SIG_RED_GREEN_MASK_BASE_IDX 2
+#define regOTG2_OTG_CRC_SIG_BLUE_CONTROL_MASK 0x1c7b
+#define regOTG2_OTG_CRC_SIG_BLUE_CONTROL_MASK_BASE_IDX 2
+#define regOTG2_OTG_STATIC_SCREEN_CONTROL 0x1c82
+#define regOTG2_OTG_STATIC_SCREEN_CONTROL_BASE_IDX 2
+#define regOTG2_OTG_3D_STRUCTURE_CONTROL 0x1c83
+#define regOTG2_OTG_3D_STRUCTURE_CONTROL_BASE_IDX 2
+#define regOTG2_OTG_GSL_VSYNC_GAP 0x1c84
+#define regOTG2_OTG_GSL_VSYNC_GAP_BASE_IDX 2
+#define regOTG2_OTG_MASTER_UPDATE_MODE 0x1c85
+#define regOTG2_OTG_MASTER_UPDATE_MODE_BASE_IDX 2
+#define regOTG2_OTG_CLOCK_CONTROL 0x1c86
+#define regOTG2_OTG_CLOCK_CONTROL_BASE_IDX 2
+#define regOTG2_OTG_VSTARTUP_PARAM 0x1c87
+#define regOTG2_OTG_VSTARTUP_PARAM_BASE_IDX 2
+#define regOTG2_OTG_VUPDATE_PARAM 0x1c88
+#define regOTG2_OTG_VUPDATE_PARAM_BASE_IDX 2
+#define regOTG2_OTG_VREADY_PARAM 0x1c89
+#define regOTG2_OTG_VREADY_PARAM_BASE_IDX 2
+#define regOTG2_OTG_GLOBAL_SYNC_STATUS 0x1c8a
+#define regOTG2_OTG_GLOBAL_SYNC_STATUS_BASE_IDX 2
+#define regOTG2_OTG_MASTER_UPDATE_LOCK 0x1c8b
+#define regOTG2_OTG_MASTER_UPDATE_LOCK_BASE_IDX 2
+#define regOTG2_OTG_GSL_CONTROL 0x1c8c
+#define regOTG2_OTG_GSL_CONTROL_BASE_IDX 2
+#define regOTG2_OTG_GSL_WINDOW_X 0x1c8d
+#define regOTG2_OTG_GSL_WINDOW_X_BASE_IDX 2
+#define regOTG2_OTG_GSL_WINDOW_Y 0x1c8e
+#define regOTG2_OTG_GSL_WINDOW_Y_BASE_IDX 2
+#define regOTG2_OTG_VUPDATE_KEEPOUT 0x1c8f
+#define regOTG2_OTG_VUPDATE_KEEPOUT_BASE_IDX 2
+#define regOTG2_OTG_GLOBAL_CONTROL0 0x1c90
+#define regOTG2_OTG_GLOBAL_CONTROL0_BASE_IDX 2
+#define regOTG2_OTG_GLOBAL_CONTROL1 0x1c91
+#define regOTG2_OTG_GLOBAL_CONTROL1_BASE_IDX 2
+#define regOTG2_OTG_GLOBAL_CONTROL2 0x1c92
+#define regOTG2_OTG_GLOBAL_CONTROL2_BASE_IDX 2
+#define regOTG2_OTG_GLOBAL_CONTROL3 0x1c93
+#define regOTG2_OTG_GLOBAL_CONTROL3_BASE_IDX 2
+#define regOTG2_OTG_GLOBAL_CONTROL4 0x1c94
+#define regOTG2_OTG_GLOBAL_CONTROL4_BASE_IDX 2
+#define regOTG2_OTG_TRIG_MANUAL_CONTROL 0x1c95
+#define regOTG2_OTG_TRIG_MANUAL_CONTROL_BASE_IDX 2
+#define regOTG2_OTG_MANUAL_FLOW_CONTROL 0x1c96
+#define regOTG2_OTG_MANUAL_FLOW_CONTROL_BASE_IDX 2
+#define regOTG2_OTG_DRR_TIMING_INT_STATUS 0x1c97
+#define regOTG2_OTG_DRR_TIMING_INT_STATUS_BASE_IDX 2
+#define regOTG2_OTG_DRR_V_TOTAL_REACH_RANGE 0x1c98
+#define regOTG2_OTG_DRR_V_TOTAL_REACH_RANGE_BASE_IDX 2
+#define regOTG2_OTG_DRR_V_TOTAL_CHANGE 0x1c99
+#define regOTG2_OTG_DRR_V_TOTAL_CHANGE_BASE_IDX 2
+#define regOTG2_OTG_DRR_TRIGGER_WINDOW 0x1c9a
+#define regOTG2_OTG_DRR_TRIGGER_WINDOW_BASE_IDX 2
+#define regOTG2_OTG_DRR_CONTROL 0x1c9b
+#define regOTG2_OTG_DRR_CONTROL_BASE_IDX 2
+#define regOTG2_OTG_M_CONST_DTO0 0x1c9c
+#define regOTG2_OTG_M_CONST_DTO0_BASE_IDX 2
+#define regOTG2_OTG_M_CONST_DTO1 0x1c9d
+#define regOTG2_OTG_M_CONST_DTO1_BASE_IDX 2
+#define regOTG2_OTG_REQUEST_CONTROL 0x1c9e
+#define regOTG2_OTG_REQUEST_CONTROL_BASE_IDX 2
+#define regOTG2_OTG_DSC_START_POSITION 0x1c9f
+#define regOTG2_OTG_DSC_START_POSITION_BASE_IDX 2
+#define regOTG2_OTG_PIPE_UPDATE_STATUS 0x1ca0
+#define regOTG2_OTG_PIPE_UPDATE_STATUS_BASE_IDX 2
+#define regOTG2_OTG_SPARE_REGISTER 0x1ca2
+#define regOTG2_OTG_SPARE_REGISTER_BASE_IDX 2
+
+
+// addressBlock: dce_dc_optc_otg3_dispdec
+// base address: 0x600
+#define regOTG3_OTG_H_TOTAL 0x1caa
+#define regOTG3_OTG_H_TOTAL_BASE_IDX 2
+#define regOTG3_OTG_H_BLANK_START_END 0x1cab
+#define regOTG3_OTG_H_BLANK_START_END_BASE_IDX 2
+#define regOTG3_OTG_H_SYNC_A 0x1cac
+#define regOTG3_OTG_H_SYNC_A_BASE_IDX 2
+#define regOTG3_OTG_H_SYNC_A_CNTL 0x1cad
+#define regOTG3_OTG_H_SYNC_A_CNTL_BASE_IDX 2
+#define regOTG3_OTG_H_TIMING_CNTL 0x1cae
+#define regOTG3_OTG_H_TIMING_CNTL_BASE_IDX 2
+#define regOTG3_OTG_V_TOTAL 0x1caf
+#define regOTG3_OTG_V_TOTAL_BASE_IDX 2
+#define regOTG3_OTG_V_TOTAL_MIN 0x1cb0
+#define regOTG3_OTG_V_TOTAL_MIN_BASE_IDX 2
+#define regOTG3_OTG_V_TOTAL_MAX 0x1cb1
+#define regOTG3_OTG_V_TOTAL_MAX_BASE_IDX 2
+#define regOTG3_OTG_V_TOTAL_MID 0x1cb2
+#define regOTG3_OTG_V_TOTAL_MID_BASE_IDX 2
+#define regOTG3_OTG_V_TOTAL_CONTROL 0x1cb3
+#define regOTG3_OTG_V_TOTAL_CONTROL_BASE_IDX 2
+#define regOTG3_OTG_V_TOTAL_INT_STATUS 0x1cb4
+#define regOTG3_OTG_V_TOTAL_INT_STATUS_BASE_IDX 2
+#define regOTG3_OTG_VSYNC_NOM_INT_STATUS 0x1cb5
+#define regOTG3_OTG_VSYNC_NOM_INT_STATUS_BASE_IDX 2
+#define regOTG3_OTG_V_BLANK_START_END 0x1cb6
+#define regOTG3_OTG_V_BLANK_START_END_BASE_IDX 2
+#define regOTG3_OTG_V_SYNC_A 0x1cb7
+#define regOTG3_OTG_V_SYNC_A_BASE_IDX 2
+#define regOTG3_OTG_V_SYNC_A_CNTL 0x1cb8
+#define regOTG3_OTG_V_SYNC_A_CNTL_BASE_IDX 2
+#define regOTG3_OTG_TRIGA_CNTL 0x1cb9
+#define regOTG3_OTG_TRIGA_CNTL_BASE_IDX 2
+#define regOTG3_OTG_TRIGA_MANUAL_TRIG 0x1cba
+#define regOTG3_OTG_TRIGA_MANUAL_TRIG_BASE_IDX 2
+#define regOTG3_OTG_TRIGB_CNTL 0x1cbb
+#define regOTG3_OTG_TRIGB_CNTL_BASE_IDX 2
+#define regOTG3_OTG_TRIGB_MANUAL_TRIG 0x1cbc
+#define regOTG3_OTG_TRIGB_MANUAL_TRIG_BASE_IDX 2
+#define regOTG3_OTG_FORCE_COUNT_NOW_CNTL 0x1cbd
+#define regOTG3_OTG_FORCE_COUNT_NOW_CNTL_BASE_IDX 2
+#define regOTG3_OTG_FLOW_CONTROL 0x1cbe
+#define regOTG3_OTG_FLOW_CONTROL_BASE_IDX 2
+#define regOTG3_OTG_STEREO_FORCE_NEXT_EYE 0x1cbf
+#define regOTG3_OTG_STEREO_FORCE_NEXT_EYE_BASE_IDX 2
+#define regOTG3_OTG_CONTROL 0x1cc1
+#define regOTG3_OTG_CONTROL_BASE_IDX 2
+#define regOTG3_OTG_INTERLACE_CONTROL 0x1cc4
+#define regOTG3_OTG_INTERLACE_CONTROL_BASE_IDX 2
+#define regOTG3_OTG_INTERLACE_STATUS 0x1cc5
+#define regOTG3_OTG_INTERLACE_STATUS_BASE_IDX 2
+#define regOTG3_OTG_PIXEL_DATA_READBACK0 0x1cc7
+#define regOTG3_OTG_PIXEL_DATA_READBACK0_BASE_IDX 2
+#define regOTG3_OTG_PIXEL_DATA_READBACK1 0x1cc8
+#define regOTG3_OTG_PIXEL_DATA_READBACK1_BASE_IDX 2
+#define regOTG3_OTG_STATUS 0x1cc9
+#define regOTG3_OTG_STATUS_BASE_IDX 2
+#define regOTG3_OTG_STATUS_POSITION 0x1cca
+#define regOTG3_OTG_STATUS_POSITION_BASE_IDX 2
+#define regOTG3_OTG_NOM_VERT_POSITION 0x1ccb
+#define regOTG3_OTG_NOM_VERT_POSITION_BASE_IDX 2
+#define regOTG3_OTG_STATUS_FRAME_COUNT 0x1ccc
+#define regOTG3_OTG_STATUS_FRAME_COUNT_BASE_IDX 2
+#define regOTG3_OTG_STATUS_VF_COUNT 0x1ccd
+#define regOTG3_OTG_STATUS_VF_COUNT_BASE_IDX 2
+#define regOTG3_OTG_STATUS_HV_COUNT 0x1cce
+#define regOTG3_OTG_STATUS_HV_COUNT_BASE_IDX 2
+#define regOTG3_OTG_COUNT_CONTROL 0x1ccf
+#define regOTG3_OTG_COUNT_CONTROL_BASE_IDX 2
+#define regOTG3_OTG_COUNT_RESET 0x1cd0
+#define regOTG3_OTG_COUNT_RESET_BASE_IDX 2
+#define regOTG3_OTG_MANUAL_FORCE_VSYNC_NEXT_LINE 0x1cd1
+#define regOTG3_OTG_MANUAL_FORCE_VSYNC_NEXT_LINE_BASE_IDX 2
+#define regOTG3_OTG_VERT_SYNC_CONTROL 0x1cd2
+#define regOTG3_OTG_VERT_SYNC_CONTROL_BASE_IDX 2
+#define regOTG3_OTG_STEREO_STATUS 0x1cd3
+#define regOTG3_OTG_STEREO_STATUS_BASE_IDX 2
+#define regOTG3_OTG_STEREO_CONTROL 0x1cd4
+#define regOTG3_OTG_STEREO_CONTROL_BASE_IDX 2
+#define regOTG3_OTG_SNAPSHOT_STATUS 0x1cd5
+#define regOTG3_OTG_SNAPSHOT_STATUS_BASE_IDX 2
+#define regOTG3_OTG_SNAPSHOT_CONTROL 0x1cd6
+#define regOTG3_OTG_SNAPSHOT_CONTROL_BASE_IDX 2
+#define regOTG3_OTG_SNAPSHOT_POSITION 0x1cd7
+#define regOTG3_OTG_SNAPSHOT_POSITION_BASE_IDX 2
+#define regOTG3_OTG_SNAPSHOT_FRAME 0x1cd8
+#define regOTG3_OTG_SNAPSHOT_FRAME_BASE_IDX 2
+#define regOTG3_OTG_UPDATE_LOCK 0x1cda
+#define regOTG3_OTG_UPDATE_LOCK_BASE_IDX 2
+#define regOTG3_OTG_DOUBLE_BUFFER_CONTROL 0x1cdb
+#define regOTG3_OTG_DOUBLE_BUFFER_CONTROL_BASE_IDX 2
+#define regOTG3_OTG_MASTER_EN 0x1cdc
+#define regOTG3_OTG_MASTER_EN_BASE_IDX 2
+#define regOTG3_OTG_VERTICAL_INTERRUPT0_POSITION 0x1ce2
+#define regOTG3_OTG_VERTICAL_INTERRUPT0_POSITION_BASE_IDX 2
+#define regOTG3_OTG_VERTICAL_INTERRUPT0_CONTROL 0x1ce3
+#define regOTG3_OTG_VERTICAL_INTERRUPT0_CONTROL_BASE_IDX 2
+#define regOTG3_OTG_VERTICAL_INTERRUPT1_POSITION 0x1ce4
+#define regOTG3_OTG_VERTICAL_INTERRUPT1_POSITION_BASE_IDX 2
+#define regOTG3_OTG_VERTICAL_INTERRUPT1_CONTROL 0x1ce5
+#define regOTG3_OTG_VERTICAL_INTERRUPT1_CONTROL_BASE_IDX 2
+#define regOTG3_OTG_VERTICAL_INTERRUPT2_POSITION 0x1ce6
+#define regOTG3_OTG_VERTICAL_INTERRUPT2_POSITION_BASE_IDX 2
+#define regOTG3_OTG_VERTICAL_INTERRUPT2_CONTROL 0x1ce7
+#define regOTG3_OTG_VERTICAL_INTERRUPT2_CONTROL_BASE_IDX 2
+#define regOTG3_OTG_CRC_CNTL 0x1ce8
+#define regOTG3_OTG_CRC_CNTL_BASE_IDX 2
+#define regOTG3_OTG_CRC_CNTL2 0x1ce9
+#define regOTG3_OTG_CRC_CNTL2_BASE_IDX 2
+#define regOTG3_OTG_CRC0_WINDOWA_X_CONTROL 0x1cea
+#define regOTG3_OTG_CRC0_WINDOWA_X_CONTROL_BASE_IDX 2
+#define regOTG3_OTG_CRC0_WINDOWA_Y_CONTROL 0x1ceb
+#define regOTG3_OTG_CRC0_WINDOWA_Y_CONTROL_BASE_IDX 2
+#define regOTG3_OTG_CRC0_WINDOWB_X_CONTROL 0x1cec
+#define regOTG3_OTG_CRC0_WINDOWB_X_CONTROL_BASE_IDX 2
+#define regOTG3_OTG_CRC0_WINDOWB_Y_CONTROL 0x1ced
+#define regOTG3_OTG_CRC0_WINDOWB_Y_CONTROL_BASE_IDX 2
+#define regOTG3_OTG_CRC0_DATA_RG 0x1cee
+#define regOTG3_OTG_CRC0_DATA_RG_BASE_IDX 2
+#define regOTG3_OTG_CRC0_DATA_B 0x1cef
+#define regOTG3_OTG_CRC0_DATA_B_BASE_IDX 2
+#define regOTG3_OTG_CRC1_WINDOWA_X_CONTROL 0x1cf0
+#define regOTG3_OTG_CRC1_WINDOWA_X_CONTROL_BASE_IDX 2
+#define regOTG3_OTG_CRC1_WINDOWA_Y_CONTROL 0x1cf1
+#define regOTG3_OTG_CRC1_WINDOWA_Y_CONTROL_BASE_IDX 2
+#define regOTG3_OTG_CRC1_WINDOWB_X_CONTROL 0x1cf2
+#define regOTG3_OTG_CRC1_WINDOWB_X_CONTROL_BASE_IDX 2
+#define regOTG3_OTG_CRC1_WINDOWB_Y_CONTROL 0x1cf3
+#define regOTG3_OTG_CRC1_WINDOWB_Y_CONTROL_BASE_IDX 2
+#define regOTG3_OTG_CRC1_DATA_RG 0x1cf4
+#define regOTG3_OTG_CRC1_DATA_RG_BASE_IDX 2
+#define regOTG3_OTG_CRC1_DATA_B 0x1cf5
+#define regOTG3_OTG_CRC1_DATA_B_BASE_IDX 2
+#define regOTG3_OTG_CRC2_DATA_RG 0x1cf6
+#define regOTG3_OTG_CRC2_DATA_RG_BASE_IDX 2
+#define regOTG3_OTG_CRC2_DATA_B 0x1cf7
+#define regOTG3_OTG_CRC2_DATA_B_BASE_IDX 2
+#define regOTG3_OTG_CRC3_DATA_RG 0x1cf8
+#define regOTG3_OTG_CRC3_DATA_RG_BASE_IDX 2
+#define regOTG3_OTG_CRC3_DATA_B 0x1cf9
+#define regOTG3_OTG_CRC3_DATA_B_BASE_IDX 2
+#define regOTG3_OTG_CRC_SIG_RED_GREEN_MASK 0x1cfa
+#define regOTG3_OTG_CRC_SIG_RED_GREEN_MASK_BASE_IDX 2
+#define regOTG3_OTG_CRC_SIG_BLUE_CONTROL_MASK 0x1cfb
+#define regOTG3_OTG_CRC_SIG_BLUE_CONTROL_MASK_BASE_IDX 2
+#define regOTG3_OTG_STATIC_SCREEN_CONTROL 0x1d02
+#define regOTG3_OTG_STATIC_SCREEN_CONTROL_BASE_IDX 2
+#define regOTG3_OTG_3D_STRUCTURE_CONTROL 0x1d03
+#define regOTG3_OTG_3D_STRUCTURE_CONTROL_BASE_IDX 2
+#define regOTG3_OTG_GSL_VSYNC_GAP 0x1d04
+#define regOTG3_OTG_GSL_VSYNC_GAP_BASE_IDX 2
+#define regOTG3_OTG_MASTER_UPDATE_MODE 0x1d05
+#define regOTG3_OTG_MASTER_UPDATE_MODE_BASE_IDX 2
+#define regOTG3_OTG_CLOCK_CONTROL 0x1d06
+#define regOTG3_OTG_CLOCK_CONTROL_BASE_IDX 2
+#define regOTG3_OTG_VSTARTUP_PARAM 0x1d07
+#define regOTG3_OTG_VSTARTUP_PARAM_BASE_IDX 2
+#define regOTG3_OTG_VUPDATE_PARAM 0x1d08
+#define regOTG3_OTG_VUPDATE_PARAM_BASE_IDX 2
+#define regOTG3_OTG_VREADY_PARAM 0x1d09
+#define regOTG3_OTG_VREADY_PARAM_BASE_IDX 2
+#define regOTG3_OTG_GLOBAL_SYNC_STATUS 0x1d0a
+#define regOTG3_OTG_GLOBAL_SYNC_STATUS_BASE_IDX 2
+#define regOTG3_OTG_MASTER_UPDATE_LOCK 0x1d0b
+#define regOTG3_OTG_MASTER_UPDATE_LOCK_BASE_IDX 2
+#define regOTG3_OTG_GSL_CONTROL 0x1d0c
+#define regOTG3_OTG_GSL_CONTROL_BASE_IDX 2
+#define regOTG3_OTG_GSL_WINDOW_X 0x1d0d
+#define regOTG3_OTG_GSL_WINDOW_X_BASE_IDX 2
+#define regOTG3_OTG_GSL_WINDOW_Y 0x1d0e
+#define regOTG3_OTG_GSL_WINDOW_Y_BASE_IDX 2
+#define regOTG3_OTG_VUPDATE_KEEPOUT 0x1d0f
+#define regOTG3_OTG_VUPDATE_KEEPOUT_BASE_IDX 2
+#define regOTG3_OTG_GLOBAL_CONTROL0 0x1d10
+#define regOTG3_OTG_GLOBAL_CONTROL0_BASE_IDX 2
+#define regOTG3_OTG_GLOBAL_CONTROL1 0x1d11
+#define regOTG3_OTG_GLOBAL_CONTROL1_BASE_IDX 2
+#define regOTG3_OTG_GLOBAL_CONTROL2 0x1d12
+#define regOTG3_OTG_GLOBAL_CONTROL2_BASE_IDX 2
+#define regOTG3_OTG_GLOBAL_CONTROL3 0x1d13
+#define regOTG3_OTG_GLOBAL_CONTROL3_BASE_IDX 2
+#define regOTG3_OTG_GLOBAL_CONTROL4 0x1d14
+#define regOTG3_OTG_GLOBAL_CONTROL4_BASE_IDX 2
+#define regOTG3_OTG_TRIG_MANUAL_CONTROL 0x1d15
+#define regOTG3_OTG_TRIG_MANUAL_CONTROL_BASE_IDX 2
+#define regOTG3_OTG_MANUAL_FLOW_CONTROL 0x1d16
+#define regOTG3_OTG_MANUAL_FLOW_CONTROL_BASE_IDX 2
+#define regOTG3_OTG_DRR_TIMING_INT_STATUS 0x1d17
+#define regOTG3_OTG_DRR_TIMING_INT_STATUS_BASE_IDX 2
+#define regOTG3_OTG_DRR_V_TOTAL_REACH_RANGE 0x1d18
+#define regOTG3_OTG_DRR_V_TOTAL_REACH_RANGE_BASE_IDX 2
+#define regOTG3_OTG_DRR_V_TOTAL_CHANGE 0x1d19
+#define regOTG3_OTG_DRR_V_TOTAL_CHANGE_BASE_IDX 2
+#define regOTG3_OTG_DRR_TRIGGER_WINDOW 0x1d1a
+#define regOTG3_OTG_DRR_TRIGGER_WINDOW_BASE_IDX 2
+#define regOTG3_OTG_DRR_CONTROL 0x1d1b
+#define regOTG3_OTG_DRR_CONTROL_BASE_IDX 2
+#define regOTG3_OTG_M_CONST_DTO0 0x1d1c
+#define regOTG3_OTG_M_CONST_DTO0_BASE_IDX 2
+#define regOTG3_OTG_M_CONST_DTO1 0x1d1d
+#define regOTG3_OTG_M_CONST_DTO1_BASE_IDX 2
+#define regOTG3_OTG_REQUEST_CONTROL 0x1d1e
+#define regOTG3_OTG_REQUEST_CONTROL_BASE_IDX 2
+#define regOTG3_OTG_DSC_START_POSITION 0x1d1f
+#define regOTG3_OTG_DSC_START_POSITION_BASE_IDX 2
+#define regOTG3_OTG_PIPE_UPDATE_STATUS 0x1d20
+#define regOTG3_OTG_PIPE_UPDATE_STATUS_BASE_IDX 2
+#define regOTG3_OTG_SPARE_REGISTER 0x1d22
+#define regOTG3_OTG_SPARE_REGISTER_BASE_IDX 2
+
+
+// addressBlock: dce_dc_optc_optc_misc_dispdec
+// base address: 0x0
+#define regDWB_SOURCE_SELECT 0x1e2a
+#define regDWB_SOURCE_SELECT_BASE_IDX 2
+#define regGSL_SOURCE_SELECT 0x1e2b
+#define regGSL_SOURCE_SELECT_BASE_IDX 2
+#define regOPTC_CLOCK_CONTROL 0x1e2c
+#define regOPTC_CLOCK_CONTROL_BASE_IDX 2
+#define regODM_MEM_PWR_CTRL 0x1e2d
+#define regODM_MEM_PWR_CTRL_BASE_IDX 2
+#define regODM_MEM_PWR_CTRL3 0x1e2f
+#define regODM_MEM_PWR_CTRL3_BASE_IDX 2
+#define regODM_MEM_PWR_STATUS 0x1e30
+#define regODM_MEM_PWR_STATUS_BASE_IDX 2
+#define regOPTC_MISC_SPARE_REGISTER 0x1e31
+#define regOPTC_MISC_SPARE_REGISTER_BASE_IDX 2
+
+
+// addressBlock: dce_dc_optc_optc_dcperfmon_dc_perfmon_dispdec
+// base address: 0x79a8
+#define regDC_PERFMON17_PERFCOUNTER_CNTL 0x1e6a
+#define regDC_PERFMON17_PERFCOUNTER_CNTL_BASE_IDX 2
+#define regDC_PERFMON17_PERFCOUNTER_CNTL2 0x1e6b
+#define regDC_PERFMON17_PERFCOUNTER_CNTL2_BASE_IDX 2
+#define regDC_PERFMON17_PERFCOUNTER_STATE 0x1e6c
+#define regDC_PERFMON17_PERFCOUNTER_STATE_BASE_IDX 2
+#define regDC_PERFMON17_PERFMON_CNTL 0x1e6d
+#define regDC_PERFMON17_PERFMON_CNTL_BASE_IDX 2
+#define regDC_PERFMON17_PERFMON_CNTL2 0x1e6e
+#define regDC_PERFMON17_PERFMON_CNTL2_BASE_IDX 2
+#define regDC_PERFMON17_PERFMON_CVALUE_INT_MISC 0x1e6f
+#define regDC_PERFMON17_PERFMON_CVALUE_INT_MISC_BASE_IDX 2
+#define regDC_PERFMON17_PERFMON_CVALUE_LOW 0x1e70
+#define regDC_PERFMON17_PERFMON_CVALUE_LOW_BASE_IDX 2
+#define regDC_PERFMON17_PERFMON_HI 0x1e71
+#define regDC_PERFMON17_PERFMON_HI_BASE_IDX 2
+#define regDC_PERFMON17_PERFMON_LOW 0x1e72
+#define regDC_PERFMON17_PERFMON_LOW_BASE_IDX 2
+
+
+// addressBlock: dce_dc_dio_hpd0_dispdec
+// base address: 0x0
+#define regHPD0_DC_HPD_INT_STATUS 0x1f14
+#define regHPD0_DC_HPD_INT_STATUS_BASE_IDX 2
+#define regHPD0_DC_HPD_INT_CONTROL 0x1f15
+#define regHPD0_DC_HPD_INT_CONTROL_BASE_IDX 2
+#define regHPD0_DC_HPD_CONTROL 0x1f16
+#define regHPD0_DC_HPD_CONTROL_BASE_IDX 2
+#define regHPD0_DC_HPD_FAST_TRAIN_CNTL 0x1f17
+#define regHPD0_DC_HPD_FAST_TRAIN_CNTL_BASE_IDX 2
+#define regHPD0_DC_HPD_TOGGLE_FILT_CNTL 0x1f18
+#define regHPD0_DC_HPD_TOGGLE_FILT_CNTL_BASE_IDX 2
+
+
+// addressBlock: dce_dc_dio_hpd1_dispdec
+// base address: 0x20
+#define regHPD1_DC_HPD_INT_STATUS 0x1f1c
+#define regHPD1_DC_HPD_INT_STATUS_BASE_IDX 2
+#define regHPD1_DC_HPD_INT_CONTROL 0x1f1d
+#define regHPD1_DC_HPD_INT_CONTROL_BASE_IDX 2
+#define regHPD1_DC_HPD_CONTROL 0x1f1e
+#define regHPD1_DC_HPD_CONTROL_BASE_IDX 2
+#define regHPD1_DC_HPD_FAST_TRAIN_CNTL 0x1f1f
+#define regHPD1_DC_HPD_FAST_TRAIN_CNTL_BASE_IDX 2
+#define regHPD1_DC_HPD_TOGGLE_FILT_CNTL 0x1f20
+#define regHPD1_DC_HPD_TOGGLE_FILT_CNTL_BASE_IDX 2
+
+
+// addressBlock: dce_dc_dio_hpd2_dispdec
+// base address: 0x40
+#define regHPD2_DC_HPD_INT_STATUS 0x1f24
+#define regHPD2_DC_HPD_INT_STATUS_BASE_IDX 2
+#define regHPD2_DC_HPD_INT_CONTROL 0x1f25
+#define regHPD2_DC_HPD_INT_CONTROL_BASE_IDX 2
+#define regHPD2_DC_HPD_CONTROL 0x1f26
+#define regHPD2_DC_HPD_CONTROL_BASE_IDX 2
+#define regHPD2_DC_HPD_FAST_TRAIN_CNTL 0x1f27
+#define regHPD2_DC_HPD_FAST_TRAIN_CNTL_BASE_IDX 2
+#define regHPD2_DC_HPD_TOGGLE_FILT_CNTL 0x1f28
+#define regHPD2_DC_HPD_TOGGLE_FILT_CNTL_BASE_IDX 2
+
+
+// addressBlock: dce_dc_dio_hpd3_dispdec
+// base address: 0x60
+#define regHPD3_DC_HPD_INT_STATUS 0x1f2c
+#define regHPD3_DC_HPD_INT_STATUS_BASE_IDX 2
+#define regHPD3_DC_HPD_INT_CONTROL 0x1f2d
+#define regHPD3_DC_HPD_INT_CONTROL_BASE_IDX 2
+#define regHPD3_DC_HPD_CONTROL 0x1f2e
+#define regHPD3_DC_HPD_CONTROL_BASE_IDX 2
+#define regHPD3_DC_HPD_FAST_TRAIN_CNTL 0x1f2f
+#define regHPD3_DC_HPD_FAST_TRAIN_CNTL_BASE_IDX 2
+#define regHPD3_DC_HPD_TOGGLE_FILT_CNTL 0x1f30
+#define regHPD3_DC_HPD_TOGGLE_FILT_CNTL_BASE_IDX 2
+
+
+// addressBlock: dce_dc_dio_hpd4_dispdec
+// base address: 0x80
+#define regHPD4_DC_HPD_INT_STATUS 0x1f34
+#define regHPD4_DC_HPD_INT_STATUS_BASE_IDX 2
+#define regHPD4_DC_HPD_INT_CONTROL 0x1f35
+#define regHPD4_DC_HPD_INT_CONTROL_BASE_IDX 2
+#define regHPD4_DC_HPD_CONTROL 0x1f36
+#define regHPD4_DC_HPD_CONTROL_BASE_IDX 2
+#define regHPD4_DC_HPD_FAST_TRAIN_CNTL 0x1f37
+#define regHPD4_DC_HPD_FAST_TRAIN_CNTL_BASE_IDX 2
+#define regHPD4_DC_HPD_TOGGLE_FILT_CNTL 0x1f38
+#define regHPD4_DC_HPD_TOGGLE_FILT_CNTL_BASE_IDX 2
+
+
+// addressBlock: dce_dc_dio_dp0_dispdec
+// base address: 0x0
+#define regDP0_DP_LINK_CNTL 0x2108
+#define regDP0_DP_LINK_CNTL_BASE_IDX 2
+#define regDP0_DP_PIXEL_FORMAT 0x2109
+#define regDP0_DP_PIXEL_FORMAT_BASE_IDX 2
+#define regDP0_DP_MSA_COLORIMETRY 0x210a
+#define regDP0_DP_MSA_COLORIMETRY_BASE_IDX 2
+#define regDP0_DP_CONFIG 0x210b
+#define regDP0_DP_CONFIG_BASE_IDX 2
+#define regDP0_DP_VID_STREAM_CNTL 0x210c
+#define regDP0_DP_VID_STREAM_CNTL_BASE_IDX 2
+#define regDP0_DP_STEER_FIFO 0x210d
+#define regDP0_DP_STEER_FIFO_BASE_IDX 2
+#define regDP0_DP_MSA_MISC 0x210e
+#define regDP0_DP_MSA_MISC_BASE_IDX 2
+#define regDP0_DP_DPHY_INTERNAL_CTRL 0x210f
+#define regDP0_DP_DPHY_INTERNAL_CTRL_BASE_IDX 2
+#define regDP0_DP_VID_TIMING 0x2110
+#define regDP0_DP_VID_TIMING_BASE_IDX 2
+#define regDP0_DP_VID_N 0x2111
+#define regDP0_DP_VID_N_BASE_IDX 2
+#define regDP0_DP_VID_M 0x2112
+#define regDP0_DP_VID_M_BASE_IDX 2
+#define regDP0_DP_LINK_FRAMING_CNTL 0x2113
+#define regDP0_DP_LINK_FRAMING_CNTL_BASE_IDX 2
+#define regDP0_DP_HBR2_EYE_PATTERN 0x2114
+#define regDP0_DP_HBR2_EYE_PATTERN_BASE_IDX 2
+#define regDP0_DP_VID_MSA_VBID 0x2115
+#define regDP0_DP_VID_MSA_VBID_BASE_IDX 2
+#define regDP0_DP_VID_INTERRUPT_CNTL 0x2116
+#define regDP0_DP_VID_INTERRUPT_CNTL_BASE_IDX 2
+#define regDP0_DP_DPHY_CNTL 0x2117
+#define regDP0_DP_DPHY_CNTL_BASE_IDX 2
+#define regDP0_DP_DPHY_TRAINING_PATTERN_SEL 0x2118
+#define regDP0_DP_DPHY_TRAINING_PATTERN_SEL_BASE_IDX 2
+#define regDP0_DP_DPHY_SYM0 0x2119
+#define regDP0_DP_DPHY_SYM0_BASE_IDX 2
+#define regDP0_DP_DPHY_SYM1 0x211a
+#define regDP0_DP_DPHY_SYM1_BASE_IDX 2
+#define regDP0_DP_DPHY_SYM2 0x211b
+#define regDP0_DP_DPHY_SYM2_BASE_IDX 2
+#define regDP0_DP_DPHY_8B10B_CNTL 0x211c
+#define regDP0_DP_DPHY_8B10B_CNTL_BASE_IDX 2
+#define regDP0_DP_DPHY_PRBS_CNTL 0x211d
+#define regDP0_DP_DPHY_PRBS_CNTL_BASE_IDX 2
+#define regDP0_DP_DPHY_SCRAM_CNTL 0x211e
+#define regDP0_DP_DPHY_SCRAM_CNTL_BASE_IDX 2
+#define regDP0_DP_DPHY_CRC_EN 0x211f
+#define regDP0_DP_DPHY_CRC_EN_BASE_IDX 2
+#define regDP0_DP_DPHY_CRC_CNTL 0x2120
+#define regDP0_DP_DPHY_CRC_CNTL_BASE_IDX 2
+#define regDP0_DP_DPHY_CRC_RESULT 0x2121
+#define regDP0_DP_DPHY_CRC_RESULT_BASE_IDX 2
+#define regDP0_DP_DPHY_CRC_MST_CNTL 0x2122
+#define regDP0_DP_DPHY_CRC_MST_CNTL_BASE_IDX 2
+#define regDP0_DP_DPHY_CRC_MST_STATUS 0x2123
+#define regDP0_DP_DPHY_CRC_MST_STATUS_BASE_IDX 2
+#define regDP0_DP_DPHY_FAST_TRAINING 0x2124
+#define regDP0_DP_DPHY_FAST_TRAINING_BASE_IDX 2
+#define regDP0_DP_DPHY_FAST_TRAINING_STATUS 0x2125
+#define regDP0_DP_DPHY_FAST_TRAINING_STATUS_BASE_IDX 2
+#define regDP0_DP_SEC_CNTL 0x212b
+#define regDP0_DP_SEC_CNTL_BASE_IDX 2
+#define regDP0_DP_SEC_CNTL1 0x212c
+#define regDP0_DP_SEC_CNTL1_BASE_IDX 2
+#define regDP0_DP_SEC_FRAMING1 0x212d
+#define regDP0_DP_SEC_FRAMING1_BASE_IDX 2
+#define regDP0_DP_SEC_FRAMING2 0x212e
+#define regDP0_DP_SEC_FRAMING2_BASE_IDX 2
+#define regDP0_DP_SEC_FRAMING3 0x212f
+#define regDP0_DP_SEC_FRAMING3_BASE_IDX 2
+#define regDP0_DP_SEC_FRAMING4 0x2130
+#define regDP0_DP_SEC_FRAMING4_BASE_IDX 2
+#define regDP0_DP_SEC_AUD_N 0x2131
+#define regDP0_DP_SEC_AUD_N_BASE_IDX 2
+#define regDP0_DP_SEC_AUD_N_READBACK 0x2132
+#define regDP0_DP_SEC_AUD_N_READBACK_BASE_IDX 2
+#define regDP0_DP_SEC_AUD_M 0x2133
+#define regDP0_DP_SEC_AUD_M_BASE_IDX 2
+#define regDP0_DP_SEC_AUD_M_READBACK 0x2134
+#define regDP0_DP_SEC_AUD_M_READBACK_BASE_IDX 2
+#define regDP0_DP_SEC_TIMESTAMP 0x2135
+#define regDP0_DP_SEC_TIMESTAMP_BASE_IDX 2
+#define regDP0_DP_SEC_PACKET_CNTL 0x2136
+#define regDP0_DP_SEC_PACKET_CNTL_BASE_IDX 2
+#define regDP0_DP_MSE_RATE_CNTL 0x2137
+#define regDP0_DP_MSE_RATE_CNTL_BASE_IDX 2
+#define regDP0_DP_MSE_RATE_UPDATE 0x2139
+#define regDP0_DP_MSE_RATE_UPDATE_BASE_IDX 2
+#define regDP0_DP_MSE_SAT0 0x213a
+#define regDP0_DP_MSE_SAT0_BASE_IDX 2
+#define regDP0_DP_MSE_SAT1 0x213b
+#define regDP0_DP_MSE_SAT1_BASE_IDX 2
+#define regDP0_DP_MSE_SAT2 0x213c
+#define regDP0_DP_MSE_SAT2_BASE_IDX 2
+#define regDP0_DP_MSE_SAT_UPDATE 0x213d
+#define regDP0_DP_MSE_SAT_UPDATE_BASE_IDX 2
+#define regDP0_DP_MSE_LINK_TIMING 0x213e
+#define regDP0_DP_MSE_LINK_TIMING_BASE_IDX 2
+#define regDP0_DP_MSE_MISC_CNTL 0x213f
+#define regDP0_DP_MSE_MISC_CNTL_BASE_IDX 2
+#define regDP0_DP_DPHY_BS_SR_SWAP_CNTL 0x2144
+#define regDP0_DP_DPHY_BS_SR_SWAP_CNTL_BASE_IDX 2
+#define regDP0_DP_DPHY_HBR2_PATTERN_CONTROL 0x2145
+#define regDP0_DP_DPHY_HBR2_PATTERN_CONTROL_BASE_IDX 2
+#define regDP0_DP_MSE_SAT0_STATUS 0x2147
+#define regDP0_DP_MSE_SAT0_STATUS_BASE_IDX 2
+#define regDP0_DP_MSE_SAT1_STATUS 0x2148
+#define regDP0_DP_MSE_SAT1_STATUS_BASE_IDX 2
+#define regDP0_DP_MSE_SAT2_STATUS 0x2149
+#define regDP0_DP_MSE_SAT2_STATUS_BASE_IDX 2
+#define regDP0_DP_MSA_TIMING_PARAM1 0x214c
+#define regDP0_DP_MSA_TIMING_PARAM1_BASE_IDX 2
+#define regDP0_DP_MSA_TIMING_PARAM2 0x214d
+#define regDP0_DP_MSA_TIMING_PARAM2_BASE_IDX 2
+#define regDP0_DP_MSA_TIMING_PARAM3 0x214e
+#define regDP0_DP_MSA_TIMING_PARAM3_BASE_IDX 2
+#define regDP0_DP_MSA_TIMING_PARAM4 0x214f
+#define regDP0_DP_MSA_TIMING_PARAM4_BASE_IDX 2
+#define regDP0_DP_MSO_CNTL 0x2150
+#define regDP0_DP_MSO_CNTL_BASE_IDX 2
+#define regDP0_DP_MSO_CNTL1 0x2151
+#define regDP0_DP_MSO_CNTL1_BASE_IDX 2
+#define regDP0_DP_DSC_CNTL 0x2152
+#define regDP0_DP_DSC_CNTL_BASE_IDX 2
+#define regDP0_DP_SEC_CNTL2 0x2153
+#define regDP0_DP_SEC_CNTL2_BASE_IDX 2
+#define regDP0_DP_SEC_CNTL3 0x2154
+#define regDP0_DP_SEC_CNTL3_BASE_IDX 2
+#define regDP0_DP_SEC_CNTL4 0x2155
+#define regDP0_DP_SEC_CNTL4_BASE_IDX 2
+#define regDP0_DP_SEC_CNTL5 0x2156
+#define regDP0_DP_SEC_CNTL5_BASE_IDX 2
+#define regDP0_DP_SEC_CNTL6 0x2157
+#define regDP0_DP_SEC_CNTL6_BASE_IDX 2
+#define regDP0_DP_SEC_CNTL7 0x2158
+#define regDP0_DP_SEC_CNTL7_BASE_IDX 2
+#define regDP0_DP_DB_CNTL 0x2159
+#define regDP0_DP_DB_CNTL_BASE_IDX 2
+#define regDP0_DP_MSA_VBID_MISC 0x215a
+#define regDP0_DP_MSA_VBID_MISC_BASE_IDX 2
+#define regDP0_DP_SEC_METADATA_TRANSMISSION 0x215b
+#define regDP0_DP_SEC_METADATA_TRANSMISSION_BASE_IDX 2
+#define regDP0_DP_DSC_BYTES_PER_PIXEL 0x215c
+#define regDP0_DP_DSC_BYTES_PER_PIXEL_BASE_IDX 2
+#define regDP0_DP_ALPM_CNTL 0x215d
+#define regDP0_DP_ALPM_CNTL_BASE_IDX 2
+#define regDP0_DP_GSP8_CNTL 0x215e
+#define regDP0_DP_GSP8_CNTL_BASE_IDX 2
+#define regDP0_DP_GSP9_CNTL 0x215f
+#define regDP0_DP_GSP9_CNTL_BASE_IDX 2
+#define regDP0_DP_GSP10_CNTL 0x2160
+#define regDP0_DP_GSP10_CNTL_BASE_IDX 2
+#define regDP0_DP_GSP11_CNTL 0x2161
+#define regDP0_DP_GSP11_CNTL_BASE_IDX 2
+#define regDP0_DP_GSP_EN_DB_STATUS 0x2162
+#define regDP0_DP_GSP_EN_DB_STATUS_BASE_IDX 2
+
+
+// addressBlock: dce_dc_dio_dig0_dispdec
+// base address: 0x0
+#define regDIG0_DIG_FE_CNTL 0x208b
+#define regDIG0_DIG_FE_CNTL_BASE_IDX 2
+#define regDIG0_DIG_OUTPUT_CRC_CNTL 0x208c
+#define regDIG0_DIG_OUTPUT_CRC_CNTL_BASE_IDX 2
+#define regDIG0_DIG_OUTPUT_CRC_RESULT 0x208d
+#define regDIG0_DIG_OUTPUT_CRC_RESULT_BASE_IDX 2
+#define regDIG0_DIG_CLOCK_PATTERN 0x208e
+#define regDIG0_DIG_CLOCK_PATTERN_BASE_IDX 2
+#define regDIG0_DIG_TEST_PATTERN 0x208f
+#define regDIG0_DIG_TEST_PATTERN_BASE_IDX 2
+#define regDIG0_DIG_RANDOM_PATTERN_SEED 0x2090
+#define regDIG0_DIG_RANDOM_PATTERN_SEED_BASE_IDX 2
+#define regDIG0_DIG_FIFO_STATUS 0x2091
+#define regDIG0_DIG_FIFO_STATUS_BASE_IDX 2
+#define regDIG0_HDMI_METADATA_PACKET_CONTROL 0x2092
+#define regDIG0_HDMI_METADATA_PACKET_CONTROL_BASE_IDX 2
+#define regDIG0_HDMI_CONTROL 0x2093
+#define regDIG0_HDMI_CONTROL_BASE_IDX 2
+#define regDIG0_HDMI_STATUS 0x2094
+#define regDIG0_HDMI_STATUS_BASE_IDX 2
+#define regDIG0_HDMI_AUDIO_PACKET_CONTROL 0x2095
+#define regDIG0_HDMI_AUDIO_PACKET_CONTROL_BASE_IDX 2
+#define regDIG0_HDMI_ACR_PACKET_CONTROL 0x2096
+#define regDIG0_HDMI_ACR_PACKET_CONTROL_BASE_IDX 2
+#define regDIG0_HDMI_VBI_PACKET_CONTROL 0x2097
+#define regDIG0_HDMI_VBI_PACKET_CONTROL_BASE_IDX 2
+#define regDIG0_HDMI_INFOFRAME_CONTROL0 0x2098
+#define regDIG0_HDMI_INFOFRAME_CONTROL0_BASE_IDX 2
+#define regDIG0_HDMI_INFOFRAME_CONTROL1 0x2099
+#define regDIG0_HDMI_INFOFRAME_CONTROL1_BASE_IDX 2
+#define regDIG0_HDMI_GENERIC_PACKET_CONTROL0 0x209a
+#define regDIG0_HDMI_GENERIC_PACKET_CONTROL0_BASE_IDX 2
+#define regDIG0_HDMI_GENERIC_PACKET_CONTROL6 0x209b
+#define regDIG0_HDMI_GENERIC_PACKET_CONTROL6_BASE_IDX 2
+#define regDIG0_HDMI_GENERIC_PACKET_CONTROL5 0x209c
+#define regDIG0_HDMI_GENERIC_PACKET_CONTROL5_BASE_IDX 2
+#define regDIG0_HDMI_GC 0x209d
+#define regDIG0_HDMI_GC_BASE_IDX 2
+#define regDIG0_HDMI_GENERIC_PACKET_CONTROL1 0x209e
+#define regDIG0_HDMI_GENERIC_PACKET_CONTROL1_BASE_IDX 2
+#define regDIG0_HDMI_GENERIC_PACKET_CONTROL2 0x209f
+#define regDIG0_HDMI_GENERIC_PACKET_CONTROL2_BASE_IDX 2
+#define regDIG0_HDMI_GENERIC_PACKET_CONTROL3 0x20a0
+#define regDIG0_HDMI_GENERIC_PACKET_CONTROL3_BASE_IDX 2
+#define regDIG0_HDMI_GENERIC_PACKET_CONTROL4 0x20a1
+#define regDIG0_HDMI_GENERIC_PACKET_CONTROL4_BASE_IDX 2
+#define regDIG0_HDMI_GENERIC_PACKET_CONTROL7 0x20a2
+#define regDIG0_HDMI_GENERIC_PACKET_CONTROL7_BASE_IDX 2
+#define regDIG0_HDMI_GENERIC_PACKET_CONTROL8 0x20a3
+#define regDIG0_HDMI_GENERIC_PACKET_CONTROL8_BASE_IDX 2
+#define regDIG0_HDMI_GENERIC_PACKET_CONTROL9 0x20a4
+#define regDIG0_HDMI_GENERIC_PACKET_CONTROL9_BASE_IDX 2
+#define regDIG0_HDMI_GENERIC_PACKET_CONTROL10 0x20a5
+#define regDIG0_HDMI_GENERIC_PACKET_CONTROL10_BASE_IDX 2
+#define regDIG0_HDMI_DB_CONTROL 0x20a6
+#define regDIG0_HDMI_DB_CONTROL_BASE_IDX 2
+#define regDIG0_HDMI_ACR_32_0 0x20a7
+#define regDIG0_HDMI_ACR_32_0_BASE_IDX 2
+#define regDIG0_HDMI_ACR_32_1 0x20a8
+#define regDIG0_HDMI_ACR_32_1_BASE_IDX 2
+#define regDIG0_HDMI_ACR_44_0 0x20a9
+#define regDIG0_HDMI_ACR_44_0_BASE_IDX 2
+#define regDIG0_HDMI_ACR_44_1 0x20aa
+#define regDIG0_HDMI_ACR_44_1_BASE_IDX 2
+#define regDIG0_HDMI_ACR_48_0 0x20ab
+#define regDIG0_HDMI_ACR_48_0_BASE_IDX 2
+#define regDIG0_HDMI_ACR_48_1 0x20ac
+#define regDIG0_HDMI_ACR_48_1_BASE_IDX 2
+#define regDIG0_HDMI_ACR_STATUS_0 0x20ad
+#define regDIG0_HDMI_ACR_STATUS_0_BASE_IDX 2
+#define regDIG0_HDMI_ACR_STATUS_1 0x20ae
+#define regDIG0_HDMI_ACR_STATUS_1_BASE_IDX 2
+#define regDIG0_AFMT_CNTL 0x20af
+#define regDIG0_AFMT_CNTL_BASE_IDX 2
+#define regDIG0_DIG_BE_CNTL 0x20b0
+#define regDIG0_DIG_BE_CNTL_BASE_IDX 2
+#define regDIG0_DIG_BE_EN_CNTL 0x20b1
+#define regDIG0_DIG_BE_EN_CNTL_BASE_IDX 2
+#define regDIG0_TMDS_CNTL 0x20d7
+#define regDIG0_TMDS_CNTL_BASE_IDX 2
+#define regDIG0_TMDS_CONTROL_CHAR 0x20d8
+#define regDIG0_TMDS_CONTROL_CHAR_BASE_IDX 2
+#define regDIG0_TMDS_CONTROL0_FEEDBACK 0x20d9
+#define regDIG0_TMDS_CONTROL0_FEEDBACK_BASE_IDX 2
+#define regDIG0_TMDS_STEREOSYNC_CTL_SEL 0x20da
+#define regDIG0_TMDS_STEREOSYNC_CTL_SEL_BASE_IDX 2
+#define regDIG0_TMDS_SYNC_CHAR_PATTERN_0_1 0x20db
+#define regDIG0_TMDS_SYNC_CHAR_PATTERN_0_1_BASE_IDX 2
+#define regDIG0_TMDS_SYNC_CHAR_PATTERN_2_3 0x20dc
+#define regDIG0_TMDS_SYNC_CHAR_PATTERN_2_3_BASE_IDX 2
+#define regDIG0_TMDS_CTL_BITS 0x20de
+#define regDIG0_TMDS_CTL_BITS_BASE_IDX 2
+#define regDIG0_TMDS_DCBALANCER_CONTROL 0x20df
+#define regDIG0_TMDS_DCBALANCER_CONTROL_BASE_IDX 2
+#define regDIG0_TMDS_SYNC_DCBALANCE_CHAR 0x20e0
+#define regDIG0_TMDS_SYNC_DCBALANCE_CHAR_BASE_IDX 2
+#define regDIG0_TMDS_CTL0_1_GEN_CNTL 0x20e1
+#define regDIG0_TMDS_CTL0_1_GEN_CNTL_BASE_IDX 2
+#define regDIG0_TMDS_CTL2_3_GEN_CNTL 0x20e2
+#define regDIG0_TMDS_CTL2_3_GEN_CNTL_BASE_IDX 2
+#define regDIG0_DIG_VERSION 0x20e4
+#define regDIG0_DIG_VERSION_BASE_IDX 2
+#define regDIG0_FORCE_DIG_DISABLE 0x20e5
+#define regDIG0_FORCE_DIG_DISABLE_BASE_IDX 2
+
+
+// addressBlock: dce_dc_dio_dp1_dispdec
+// base address: 0x400
+#define regDP1_DP_LINK_CNTL 0x2208
+#define regDP1_DP_LINK_CNTL_BASE_IDX 2
+#define regDP1_DP_PIXEL_FORMAT 0x2209
+#define regDP1_DP_PIXEL_FORMAT_BASE_IDX 2
+#define regDP1_DP_MSA_COLORIMETRY 0x220a
+#define regDP1_DP_MSA_COLORIMETRY_BASE_IDX 2
+#define regDP1_DP_CONFIG 0x220b
+#define regDP1_DP_CONFIG_BASE_IDX 2
+#define regDP1_DP_VID_STREAM_CNTL 0x220c
+#define regDP1_DP_VID_STREAM_CNTL_BASE_IDX 2
+#define regDP1_DP_STEER_FIFO 0x220d
+#define regDP1_DP_STEER_FIFO_BASE_IDX 2
+#define regDP1_DP_MSA_MISC 0x220e
+#define regDP1_DP_MSA_MISC_BASE_IDX 2
+#define regDP1_DP_DPHY_INTERNAL_CTRL 0x220f
+#define regDP1_DP_DPHY_INTERNAL_CTRL_BASE_IDX 2
+#define regDP1_DP_VID_TIMING 0x2210
+#define regDP1_DP_VID_TIMING_BASE_IDX 2
+#define regDP1_DP_VID_N 0x2211
+#define regDP1_DP_VID_N_BASE_IDX 2
+#define regDP1_DP_VID_M 0x2212
+#define regDP1_DP_VID_M_BASE_IDX 2
+#define regDP1_DP_LINK_FRAMING_CNTL 0x2213
+#define regDP1_DP_LINK_FRAMING_CNTL_BASE_IDX 2
+#define regDP1_DP_HBR2_EYE_PATTERN 0x2214
+#define regDP1_DP_HBR2_EYE_PATTERN_BASE_IDX 2
+#define regDP1_DP_VID_MSA_VBID 0x2215
+#define regDP1_DP_VID_MSA_VBID_BASE_IDX 2
+#define regDP1_DP_VID_INTERRUPT_CNTL 0x2216
+#define regDP1_DP_VID_INTERRUPT_CNTL_BASE_IDX 2
+#define regDP1_DP_DPHY_CNTL 0x2217
+#define regDP1_DP_DPHY_CNTL_BASE_IDX 2
+#define regDP1_DP_DPHY_TRAINING_PATTERN_SEL 0x2218
+#define regDP1_DP_DPHY_TRAINING_PATTERN_SEL_BASE_IDX 2
+#define regDP1_DP_DPHY_SYM0 0x2219
+#define regDP1_DP_DPHY_SYM0_BASE_IDX 2
+#define regDP1_DP_DPHY_SYM1 0x221a
+#define regDP1_DP_DPHY_SYM1_BASE_IDX 2
+#define regDP1_DP_DPHY_SYM2 0x221b
+#define regDP1_DP_DPHY_SYM2_BASE_IDX 2
+#define regDP1_DP_DPHY_8B10B_CNTL 0x221c
+#define regDP1_DP_DPHY_8B10B_CNTL_BASE_IDX 2
+#define regDP1_DP_DPHY_PRBS_CNTL 0x221d
+#define regDP1_DP_DPHY_PRBS_CNTL_BASE_IDX 2
+#define regDP1_DP_DPHY_SCRAM_CNTL 0x221e
+#define regDP1_DP_DPHY_SCRAM_CNTL_BASE_IDX 2
+#define regDP1_DP_DPHY_CRC_EN 0x221f
+#define regDP1_DP_DPHY_CRC_EN_BASE_IDX 2
+#define regDP1_DP_DPHY_CRC_CNTL 0x2220
+#define regDP1_DP_DPHY_CRC_CNTL_BASE_IDX 2
+#define regDP1_DP_DPHY_CRC_RESULT 0x2221
+#define regDP1_DP_DPHY_CRC_RESULT_BASE_IDX 2
+#define regDP1_DP_DPHY_CRC_MST_CNTL 0x2222
+#define regDP1_DP_DPHY_CRC_MST_CNTL_BASE_IDX 2
+#define regDP1_DP_DPHY_CRC_MST_STATUS 0x2223
+#define regDP1_DP_DPHY_CRC_MST_STATUS_BASE_IDX 2
+#define regDP1_DP_DPHY_FAST_TRAINING 0x2224
+#define regDP1_DP_DPHY_FAST_TRAINING_BASE_IDX 2
+#define regDP1_DP_DPHY_FAST_TRAINING_STATUS 0x2225
+#define regDP1_DP_DPHY_FAST_TRAINING_STATUS_BASE_IDX 2
+#define regDP1_DP_SEC_CNTL 0x222b
+#define regDP1_DP_SEC_CNTL_BASE_IDX 2
+#define regDP1_DP_SEC_CNTL1 0x222c
+#define regDP1_DP_SEC_CNTL1_BASE_IDX 2
+#define regDP1_DP_SEC_FRAMING1 0x222d
+#define regDP1_DP_SEC_FRAMING1_BASE_IDX 2
+#define regDP1_DP_SEC_FRAMING2 0x222e
+#define regDP1_DP_SEC_FRAMING2_BASE_IDX 2
+#define regDP1_DP_SEC_FRAMING3 0x222f
+#define regDP1_DP_SEC_FRAMING3_BASE_IDX 2
+#define regDP1_DP_SEC_FRAMING4 0x2230
+#define regDP1_DP_SEC_FRAMING4_BASE_IDX 2
+#define regDP1_DP_SEC_AUD_N 0x2231
+#define regDP1_DP_SEC_AUD_N_BASE_IDX 2
+#define regDP1_DP_SEC_AUD_N_READBACK 0x2232
+#define regDP1_DP_SEC_AUD_N_READBACK_BASE_IDX 2
+#define regDP1_DP_SEC_AUD_M 0x2233
+#define regDP1_DP_SEC_AUD_M_BASE_IDX 2
+#define regDP1_DP_SEC_AUD_M_READBACK 0x2234
+#define regDP1_DP_SEC_AUD_M_READBACK_BASE_IDX 2
+#define regDP1_DP_SEC_TIMESTAMP 0x2235
+#define regDP1_DP_SEC_TIMESTAMP_BASE_IDX 2
+#define regDP1_DP_SEC_PACKET_CNTL 0x2236
+#define regDP1_DP_SEC_PACKET_CNTL_BASE_IDX 2
+#define regDP1_DP_MSE_RATE_CNTL 0x2237
+#define regDP1_DP_MSE_RATE_CNTL_BASE_IDX 2
+#define regDP1_DP_MSE_RATE_UPDATE 0x2239
+#define regDP1_DP_MSE_RATE_UPDATE_BASE_IDX 2
+#define regDP1_DP_MSE_SAT0 0x223a
+#define regDP1_DP_MSE_SAT0_BASE_IDX 2
+#define regDP1_DP_MSE_SAT1 0x223b
+#define regDP1_DP_MSE_SAT1_BASE_IDX 2
+#define regDP1_DP_MSE_SAT2 0x223c
+#define regDP1_DP_MSE_SAT2_BASE_IDX 2
+#define regDP1_DP_MSE_SAT_UPDATE 0x223d
+#define regDP1_DP_MSE_SAT_UPDATE_BASE_IDX 2
+#define regDP1_DP_MSE_LINK_TIMING 0x223e
+#define regDP1_DP_MSE_LINK_TIMING_BASE_IDX 2
+#define regDP1_DP_MSE_MISC_CNTL 0x223f
+#define regDP1_DP_MSE_MISC_CNTL_BASE_IDX 2
+#define regDP1_DP_DPHY_BS_SR_SWAP_CNTL 0x2244
+#define regDP1_DP_DPHY_BS_SR_SWAP_CNTL_BASE_IDX 2
+#define regDP1_DP_DPHY_HBR2_PATTERN_CONTROL 0x2245
+#define regDP1_DP_DPHY_HBR2_PATTERN_CONTROL_BASE_IDX 2
+#define regDP1_DP_MSE_SAT0_STATUS 0x2247
+#define regDP1_DP_MSE_SAT0_STATUS_BASE_IDX 2
+#define regDP1_DP_MSE_SAT1_STATUS 0x2248
+#define regDP1_DP_MSE_SAT1_STATUS_BASE_IDX 2
+#define regDP1_DP_MSE_SAT2_STATUS 0x2249
+#define regDP1_DP_MSE_SAT2_STATUS_BASE_IDX 2
+#define regDP1_DP_MSA_TIMING_PARAM1 0x224c
+#define regDP1_DP_MSA_TIMING_PARAM1_BASE_IDX 2
+#define regDP1_DP_MSA_TIMING_PARAM2 0x224d
+#define regDP1_DP_MSA_TIMING_PARAM2_BASE_IDX 2
+#define regDP1_DP_MSA_TIMING_PARAM3 0x224e
+#define regDP1_DP_MSA_TIMING_PARAM3_BASE_IDX 2
+#define regDP1_DP_MSA_TIMING_PARAM4 0x224f
+#define regDP1_DP_MSA_TIMING_PARAM4_BASE_IDX 2
+#define regDP1_DP_MSO_CNTL 0x2250
+#define regDP1_DP_MSO_CNTL_BASE_IDX 2
+#define regDP1_DP_MSO_CNTL1 0x2251
+#define regDP1_DP_MSO_CNTL1_BASE_IDX 2
+#define regDP1_DP_DSC_CNTL 0x2252
+#define regDP1_DP_DSC_CNTL_BASE_IDX 2
+#define regDP1_DP_SEC_CNTL2 0x2253
+#define regDP1_DP_SEC_CNTL2_BASE_IDX 2
+#define regDP1_DP_SEC_CNTL3 0x2254
+#define regDP1_DP_SEC_CNTL3_BASE_IDX 2
+#define regDP1_DP_SEC_CNTL4 0x2255
+#define regDP1_DP_SEC_CNTL4_BASE_IDX 2
+#define regDP1_DP_SEC_CNTL5 0x2256
+#define regDP1_DP_SEC_CNTL5_BASE_IDX 2
+#define regDP1_DP_SEC_CNTL6 0x2257
+#define regDP1_DP_SEC_CNTL6_BASE_IDX 2
+#define regDP1_DP_SEC_CNTL7 0x2258
+#define regDP1_DP_SEC_CNTL7_BASE_IDX 2
+#define regDP1_DP_DB_CNTL 0x2259
+#define regDP1_DP_DB_CNTL_BASE_IDX 2
+#define regDP1_DP_MSA_VBID_MISC 0x225a
+#define regDP1_DP_MSA_VBID_MISC_BASE_IDX 2
+#define regDP1_DP_SEC_METADATA_TRANSMISSION 0x225b
+#define regDP1_DP_SEC_METADATA_TRANSMISSION_BASE_IDX 2
+#define regDP1_DP_DSC_BYTES_PER_PIXEL 0x225c
+#define regDP1_DP_DSC_BYTES_PER_PIXEL_BASE_IDX 2
+#define regDP1_DP_ALPM_CNTL 0x225d
+#define regDP1_DP_ALPM_CNTL_BASE_IDX 2
+#define regDP1_DP_GSP8_CNTL 0x225e
+#define regDP1_DP_GSP8_CNTL_BASE_IDX 2
+#define regDP1_DP_GSP9_CNTL 0x225f
+#define regDP1_DP_GSP9_CNTL_BASE_IDX 2
+#define regDP1_DP_GSP10_CNTL 0x2260
+#define regDP1_DP_GSP10_CNTL_BASE_IDX 2
+#define regDP1_DP_GSP11_CNTL 0x2261
+#define regDP1_DP_GSP11_CNTL_BASE_IDX 2
+#define regDP1_DP_GSP_EN_DB_STATUS 0x2262
+#define regDP1_DP_GSP_EN_DB_STATUS_BASE_IDX 2
+
+
+// addressBlock: dce_dc_dio_dig1_dispdec
+// base address: 0x400
+#define regDIG1_DIG_FE_CNTL 0x218b
+#define regDIG1_DIG_FE_CNTL_BASE_IDX 2
+#define regDIG1_DIG_OUTPUT_CRC_CNTL 0x218c
+#define regDIG1_DIG_OUTPUT_CRC_CNTL_BASE_IDX 2
+#define regDIG1_DIG_OUTPUT_CRC_RESULT 0x218d
+#define regDIG1_DIG_OUTPUT_CRC_RESULT_BASE_IDX 2
+#define regDIG1_DIG_CLOCK_PATTERN 0x218e
+#define regDIG1_DIG_CLOCK_PATTERN_BASE_IDX 2
+#define regDIG1_DIG_TEST_PATTERN 0x218f
+#define regDIG1_DIG_TEST_PATTERN_BASE_IDX 2
+#define regDIG1_DIG_RANDOM_PATTERN_SEED 0x2190
+#define regDIG1_DIG_RANDOM_PATTERN_SEED_BASE_IDX 2
+#define regDIG1_DIG_FIFO_STATUS 0x2191
+#define regDIG1_DIG_FIFO_STATUS_BASE_IDX 2
+#define regDIG1_HDMI_METADATA_PACKET_CONTROL 0x2192
+#define regDIG1_HDMI_METADATA_PACKET_CONTROL_BASE_IDX 2
+#define regDIG1_HDMI_CONTROL 0x2193
+#define regDIG1_HDMI_CONTROL_BASE_IDX 2
+#define regDIG1_HDMI_STATUS 0x2194
+#define regDIG1_HDMI_STATUS_BASE_IDX 2
+#define regDIG1_HDMI_AUDIO_PACKET_CONTROL 0x2195
+#define regDIG1_HDMI_AUDIO_PACKET_CONTROL_BASE_IDX 2
+#define regDIG1_HDMI_ACR_PACKET_CONTROL 0x2196
+#define regDIG1_HDMI_ACR_PACKET_CONTROL_BASE_IDX 2
+#define regDIG1_HDMI_VBI_PACKET_CONTROL 0x2197
+#define regDIG1_HDMI_VBI_PACKET_CONTROL_BASE_IDX 2
+#define regDIG1_HDMI_INFOFRAME_CONTROL0 0x2198
+#define regDIG1_HDMI_INFOFRAME_CONTROL0_BASE_IDX 2
+#define regDIG1_HDMI_INFOFRAME_CONTROL1 0x2199
+#define regDIG1_HDMI_INFOFRAME_CONTROL1_BASE_IDX 2
+#define regDIG1_HDMI_GENERIC_PACKET_CONTROL0 0x219a
+#define regDIG1_HDMI_GENERIC_PACKET_CONTROL0_BASE_IDX 2
+#define regDIG1_HDMI_GENERIC_PACKET_CONTROL6 0x219b
+#define regDIG1_HDMI_GENERIC_PACKET_CONTROL6_BASE_IDX 2
+#define regDIG1_HDMI_GENERIC_PACKET_CONTROL5 0x219c
+#define regDIG1_HDMI_GENERIC_PACKET_CONTROL5_BASE_IDX 2
+#define regDIG1_HDMI_GC 0x219d
+#define regDIG1_HDMI_GC_BASE_IDX 2
+#define regDIG1_HDMI_GENERIC_PACKET_CONTROL1 0x219e
+#define regDIG1_HDMI_GENERIC_PACKET_CONTROL1_BASE_IDX 2
+#define regDIG1_HDMI_GENERIC_PACKET_CONTROL2 0x219f
+#define regDIG1_HDMI_GENERIC_PACKET_CONTROL2_BASE_IDX 2
+#define regDIG1_HDMI_GENERIC_PACKET_CONTROL3 0x21a0
+#define regDIG1_HDMI_GENERIC_PACKET_CONTROL3_BASE_IDX 2
+#define regDIG1_HDMI_GENERIC_PACKET_CONTROL4 0x21a1
+#define regDIG1_HDMI_GENERIC_PACKET_CONTROL4_BASE_IDX 2
+#define regDIG1_HDMI_GENERIC_PACKET_CONTROL7 0x21a2
+#define regDIG1_HDMI_GENERIC_PACKET_CONTROL7_BASE_IDX 2
+#define regDIG1_HDMI_GENERIC_PACKET_CONTROL8 0x21a3
+#define regDIG1_HDMI_GENERIC_PACKET_CONTROL8_BASE_IDX 2
+#define regDIG1_HDMI_GENERIC_PACKET_CONTROL9 0x21a4
+#define regDIG1_HDMI_GENERIC_PACKET_CONTROL9_BASE_IDX 2
+#define regDIG1_HDMI_GENERIC_PACKET_CONTROL10 0x21a5
+#define regDIG1_HDMI_GENERIC_PACKET_CONTROL10_BASE_IDX 2
+#define regDIG1_HDMI_DB_CONTROL 0x21a6
+#define regDIG1_HDMI_DB_CONTROL_BASE_IDX 2
+#define regDIG1_HDMI_ACR_32_0 0x21a7
+#define regDIG1_HDMI_ACR_32_0_BASE_IDX 2
+#define regDIG1_HDMI_ACR_32_1 0x21a8
+#define regDIG1_HDMI_ACR_32_1_BASE_IDX 2
+#define regDIG1_HDMI_ACR_44_0 0x21a9
+#define regDIG1_HDMI_ACR_44_0_BASE_IDX 2
+#define regDIG1_HDMI_ACR_44_1 0x21aa
+#define regDIG1_HDMI_ACR_44_1_BASE_IDX 2
+#define regDIG1_HDMI_ACR_48_0 0x21ab
+#define regDIG1_HDMI_ACR_48_0_BASE_IDX 2
+#define regDIG1_HDMI_ACR_48_1 0x21ac
+#define regDIG1_HDMI_ACR_48_1_BASE_IDX 2
+#define regDIG1_HDMI_ACR_STATUS_0 0x21ad
+#define regDIG1_HDMI_ACR_STATUS_0_BASE_IDX 2
+#define regDIG1_HDMI_ACR_STATUS_1 0x21ae
+#define regDIG1_HDMI_ACR_STATUS_1_BASE_IDX 2
+#define regDIG1_AFMT_CNTL 0x21af
+#define regDIG1_AFMT_CNTL_BASE_IDX 2
+#define regDIG1_DIG_BE_CNTL 0x21b0
+#define regDIG1_DIG_BE_CNTL_BASE_IDX 2
+#define regDIG1_DIG_BE_EN_CNTL 0x21b1
+#define regDIG1_DIG_BE_EN_CNTL_BASE_IDX 2
+#define regDIG1_TMDS_CNTL 0x21d7
+#define regDIG1_TMDS_CNTL_BASE_IDX 2
+#define regDIG1_TMDS_CONTROL_CHAR 0x21d8
+#define regDIG1_TMDS_CONTROL_CHAR_BASE_IDX 2
+#define regDIG1_TMDS_CONTROL0_FEEDBACK 0x21d9
+#define regDIG1_TMDS_CONTROL0_FEEDBACK_BASE_IDX 2
+#define regDIG1_TMDS_STEREOSYNC_CTL_SEL 0x21da
+#define regDIG1_TMDS_STEREOSYNC_CTL_SEL_BASE_IDX 2
+#define regDIG1_TMDS_SYNC_CHAR_PATTERN_0_1 0x21db
+#define regDIG1_TMDS_SYNC_CHAR_PATTERN_0_1_BASE_IDX 2
+#define regDIG1_TMDS_SYNC_CHAR_PATTERN_2_3 0x21dc
+#define regDIG1_TMDS_SYNC_CHAR_PATTERN_2_3_BASE_IDX 2
+#define regDIG1_TMDS_CTL_BITS 0x21de
+#define regDIG1_TMDS_CTL_BITS_BASE_IDX 2
+#define regDIG1_TMDS_DCBALANCER_CONTROL 0x21df
+#define regDIG1_TMDS_DCBALANCER_CONTROL_BASE_IDX 2
+#define regDIG1_TMDS_SYNC_DCBALANCE_CHAR 0x21e0
+#define regDIG1_TMDS_SYNC_DCBALANCE_CHAR_BASE_IDX 2
+#define regDIG1_TMDS_CTL0_1_GEN_CNTL 0x21e1
+#define regDIG1_TMDS_CTL0_1_GEN_CNTL_BASE_IDX 2
+#define regDIG1_TMDS_CTL2_3_GEN_CNTL 0x21e2
+#define regDIG1_TMDS_CTL2_3_GEN_CNTL_BASE_IDX 2
+#define regDIG1_DIG_VERSION 0x21e4
+#define regDIG1_DIG_VERSION_BASE_IDX 2
+#define regDIG1_FORCE_DIG_DISABLE 0x21e5
+#define regDIG1_FORCE_DIG_DISABLE_BASE_IDX 2
+
+
+// addressBlock: dce_dc_dio_dp2_dispdec
+// base address: 0x800
+#define regDP2_DP_LINK_CNTL 0x2308
+#define regDP2_DP_LINK_CNTL_BASE_IDX 2
+#define regDP2_DP_PIXEL_FORMAT 0x2309
+#define regDP2_DP_PIXEL_FORMAT_BASE_IDX 2
+#define regDP2_DP_MSA_COLORIMETRY 0x230a
+#define regDP2_DP_MSA_COLORIMETRY_BASE_IDX 2
+#define regDP2_DP_CONFIG 0x230b
+#define regDP2_DP_CONFIG_BASE_IDX 2
+#define regDP2_DP_VID_STREAM_CNTL 0x230c
+#define regDP2_DP_VID_STREAM_CNTL_BASE_IDX 2
+#define regDP2_DP_STEER_FIFO 0x230d
+#define regDP2_DP_STEER_FIFO_BASE_IDX 2
+#define regDP2_DP_MSA_MISC 0x230e
+#define regDP2_DP_MSA_MISC_BASE_IDX 2
+#define regDP2_DP_DPHY_INTERNAL_CTRL 0x230f
+#define regDP2_DP_DPHY_INTERNAL_CTRL_BASE_IDX 2
+#define regDP2_DP_VID_TIMING 0x2310
+#define regDP2_DP_VID_TIMING_BASE_IDX 2
+#define regDP2_DP_VID_N 0x2311
+#define regDP2_DP_VID_N_BASE_IDX 2
+#define regDP2_DP_VID_M 0x2312
+#define regDP2_DP_VID_M_BASE_IDX 2
+#define regDP2_DP_LINK_FRAMING_CNTL 0x2313
+#define regDP2_DP_LINK_FRAMING_CNTL_BASE_IDX 2
+#define regDP2_DP_HBR2_EYE_PATTERN 0x2314
+#define regDP2_DP_HBR2_EYE_PATTERN_BASE_IDX 2
+#define regDP2_DP_VID_MSA_VBID 0x2315
+#define regDP2_DP_VID_MSA_VBID_BASE_IDX 2
+#define regDP2_DP_VID_INTERRUPT_CNTL 0x2316
+#define regDP2_DP_VID_INTERRUPT_CNTL_BASE_IDX 2
+#define regDP2_DP_DPHY_CNTL 0x2317
+#define regDP2_DP_DPHY_CNTL_BASE_IDX 2
+#define regDP2_DP_DPHY_TRAINING_PATTERN_SEL 0x2318
+#define regDP2_DP_DPHY_TRAINING_PATTERN_SEL_BASE_IDX 2
+#define regDP2_DP_DPHY_SYM0 0x2319
+#define regDP2_DP_DPHY_SYM0_BASE_IDX 2
+#define regDP2_DP_DPHY_SYM1 0x231a
+#define regDP2_DP_DPHY_SYM1_BASE_IDX 2
+#define regDP2_DP_DPHY_SYM2 0x231b
+#define regDP2_DP_DPHY_SYM2_BASE_IDX 2
+#define regDP2_DP_DPHY_8B10B_CNTL 0x231c
+#define regDP2_DP_DPHY_8B10B_CNTL_BASE_IDX 2
+#define regDP2_DP_DPHY_PRBS_CNTL 0x231d
+#define regDP2_DP_DPHY_PRBS_CNTL_BASE_IDX 2
+#define regDP2_DP_DPHY_SCRAM_CNTL 0x231e
+#define regDP2_DP_DPHY_SCRAM_CNTL_BASE_IDX 2
+#define regDP2_DP_DPHY_CRC_EN 0x231f
+#define regDP2_DP_DPHY_CRC_EN_BASE_IDX 2
+#define regDP2_DP_DPHY_CRC_CNTL 0x2320
+#define regDP2_DP_DPHY_CRC_CNTL_BASE_IDX 2
+#define regDP2_DP_DPHY_CRC_RESULT 0x2321
+#define regDP2_DP_DPHY_CRC_RESULT_BASE_IDX 2
+#define regDP2_DP_DPHY_CRC_MST_CNTL 0x2322
+#define regDP2_DP_DPHY_CRC_MST_CNTL_BASE_IDX 2
+#define regDP2_DP_DPHY_CRC_MST_STATUS 0x2323
+#define regDP2_DP_DPHY_CRC_MST_STATUS_BASE_IDX 2
+#define regDP2_DP_DPHY_FAST_TRAINING 0x2324
+#define regDP2_DP_DPHY_FAST_TRAINING_BASE_IDX 2
+#define regDP2_DP_DPHY_FAST_TRAINING_STATUS 0x2325
+#define regDP2_DP_DPHY_FAST_TRAINING_STATUS_BASE_IDX 2
+#define regDP2_DP_SEC_CNTL 0x232b
+#define regDP2_DP_SEC_CNTL_BASE_IDX 2
+#define regDP2_DP_SEC_CNTL1 0x232c
+#define regDP2_DP_SEC_CNTL1_BASE_IDX 2
+#define regDP2_DP_SEC_FRAMING1 0x232d
+#define regDP2_DP_SEC_FRAMING1_BASE_IDX 2
+#define regDP2_DP_SEC_FRAMING2 0x232e
+#define regDP2_DP_SEC_FRAMING2_BASE_IDX 2
+#define regDP2_DP_SEC_FRAMING3 0x232f
+#define regDP2_DP_SEC_FRAMING3_BASE_IDX 2
+#define regDP2_DP_SEC_FRAMING4 0x2330
+#define regDP2_DP_SEC_FRAMING4_BASE_IDX 2
+#define regDP2_DP_SEC_AUD_N 0x2331
+#define regDP2_DP_SEC_AUD_N_BASE_IDX 2
+#define regDP2_DP_SEC_AUD_N_READBACK 0x2332
+#define regDP2_DP_SEC_AUD_N_READBACK_BASE_IDX 2
+#define regDP2_DP_SEC_AUD_M 0x2333
+#define regDP2_DP_SEC_AUD_M_BASE_IDX 2
+#define regDP2_DP_SEC_AUD_M_READBACK 0x2334
+#define regDP2_DP_SEC_AUD_M_READBACK_BASE_IDX 2
+#define regDP2_DP_SEC_TIMESTAMP 0x2335
+#define regDP2_DP_SEC_TIMESTAMP_BASE_IDX 2
+#define regDP2_DP_SEC_PACKET_CNTL 0x2336
+#define regDP2_DP_SEC_PACKET_CNTL_BASE_IDX 2
+#define regDP2_DP_MSE_RATE_CNTL 0x2337
+#define regDP2_DP_MSE_RATE_CNTL_BASE_IDX 2
+#define regDP2_DP_MSE_RATE_UPDATE 0x2339
+#define regDP2_DP_MSE_RATE_UPDATE_BASE_IDX 2
+#define regDP2_DP_MSE_SAT0 0x233a
+#define regDP2_DP_MSE_SAT0_BASE_IDX 2
+#define regDP2_DP_MSE_SAT1 0x233b
+#define regDP2_DP_MSE_SAT1_BASE_IDX 2
+#define regDP2_DP_MSE_SAT2 0x233c
+#define regDP2_DP_MSE_SAT2_BASE_IDX 2
+#define regDP2_DP_MSE_SAT_UPDATE 0x233d
+#define regDP2_DP_MSE_SAT_UPDATE_BASE_IDX 2
+#define regDP2_DP_MSE_LINK_TIMING 0x233e
+#define regDP2_DP_MSE_LINK_TIMING_BASE_IDX 2
+#define regDP2_DP_MSE_MISC_CNTL 0x233f
+#define regDP2_DP_MSE_MISC_CNTL_BASE_IDX 2
+#define regDP2_DP_DPHY_BS_SR_SWAP_CNTL 0x2344
+#define regDP2_DP_DPHY_BS_SR_SWAP_CNTL_BASE_IDX 2
+#define regDP2_DP_DPHY_HBR2_PATTERN_CONTROL 0x2345
+#define regDP2_DP_DPHY_HBR2_PATTERN_CONTROL_BASE_IDX 2
+#define regDP2_DP_MSE_SAT0_STATUS 0x2347
+#define regDP2_DP_MSE_SAT0_STATUS_BASE_IDX 2
+#define regDP2_DP_MSE_SAT1_STATUS 0x2348
+#define regDP2_DP_MSE_SAT1_STATUS_BASE_IDX 2
+#define regDP2_DP_MSE_SAT2_STATUS 0x2349
+#define regDP2_DP_MSE_SAT2_STATUS_BASE_IDX 2
+#define regDP2_DP_MSA_TIMING_PARAM1 0x234c
+#define regDP2_DP_MSA_TIMING_PARAM1_BASE_IDX 2
+#define regDP2_DP_MSA_TIMING_PARAM2 0x234d
+#define regDP2_DP_MSA_TIMING_PARAM2_BASE_IDX 2
+#define regDP2_DP_MSA_TIMING_PARAM3 0x234e
+#define regDP2_DP_MSA_TIMING_PARAM3_BASE_IDX 2
+#define regDP2_DP_MSA_TIMING_PARAM4 0x234f
+#define regDP2_DP_MSA_TIMING_PARAM4_BASE_IDX 2
+#define regDP2_DP_MSO_CNTL 0x2350
+#define regDP2_DP_MSO_CNTL_BASE_IDX 2
+#define regDP2_DP_MSO_CNTL1 0x2351
+#define regDP2_DP_MSO_CNTL1_BASE_IDX 2
+#define regDP2_DP_DSC_CNTL 0x2352
+#define regDP2_DP_DSC_CNTL_BASE_IDX 2
+#define regDP2_DP_SEC_CNTL2 0x2353
+#define regDP2_DP_SEC_CNTL2_BASE_IDX 2
+#define regDP2_DP_SEC_CNTL3 0x2354
+#define regDP2_DP_SEC_CNTL3_BASE_IDX 2
+#define regDP2_DP_SEC_CNTL4 0x2355
+#define regDP2_DP_SEC_CNTL4_BASE_IDX 2
+#define regDP2_DP_SEC_CNTL5 0x2356
+#define regDP2_DP_SEC_CNTL5_BASE_IDX 2
+#define regDP2_DP_SEC_CNTL6 0x2357
+#define regDP2_DP_SEC_CNTL6_BASE_IDX 2
+#define regDP2_DP_SEC_CNTL7 0x2358
+#define regDP2_DP_SEC_CNTL7_BASE_IDX 2
+#define regDP2_DP_DB_CNTL 0x2359
+#define regDP2_DP_DB_CNTL_BASE_IDX 2
+#define regDP2_DP_MSA_VBID_MISC 0x235a
+#define regDP2_DP_MSA_VBID_MISC_BASE_IDX 2
+#define regDP2_DP_SEC_METADATA_TRANSMISSION 0x235b
+#define regDP2_DP_SEC_METADATA_TRANSMISSION_BASE_IDX 2
+#define regDP2_DP_DSC_BYTES_PER_PIXEL 0x235c
+#define regDP2_DP_DSC_BYTES_PER_PIXEL_BASE_IDX 2
+#define regDP2_DP_ALPM_CNTL 0x235d
+#define regDP2_DP_ALPM_CNTL_BASE_IDX 2
+#define regDP2_DP_GSP8_CNTL 0x235e
+#define regDP2_DP_GSP8_CNTL_BASE_IDX 2
+#define regDP2_DP_GSP9_CNTL 0x235f
+#define regDP2_DP_GSP9_CNTL_BASE_IDX 2
+#define regDP2_DP_GSP10_CNTL 0x2360
+#define regDP2_DP_GSP10_CNTL_BASE_IDX 2
+#define regDP2_DP_GSP11_CNTL 0x2361
+#define regDP2_DP_GSP11_CNTL_BASE_IDX 2
+#define regDP2_DP_GSP_EN_DB_STATUS 0x2362
+#define regDP2_DP_GSP_EN_DB_STATUS_BASE_IDX 2
+
+
+// addressBlock: dce_dc_dio_dig2_dispdec
+// base address: 0x800
+#define regDIG2_DIG_FE_CNTL 0x228b
+#define regDIG2_DIG_FE_CNTL_BASE_IDX 2
+#define regDIG2_DIG_OUTPUT_CRC_CNTL 0x228c
+#define regDIG2_DIG_OUTPUT_CRC_CNTL_BASE_IDX 2
+#define regDIG2_DIG_OUTPUT_CRC_RESULT 0x228d
+#define regDIG2_DIG_OUTPUT_CRC_RESULT_BASE_IDX 2
+#define regDIG2_DIG_CLOCK_PATTERN 0x228e
+#define regDIG2_DIG_CLOCK_PATTERN_BASE_IDX 2
+#define regDIG2_DIG_TEST_PATTERN 0x228f
+#define regDIG2_DIG_TEST_PATTERN_BASE_IDX 2
+#define regDIG2_DIG_RANDOM_PATTERN_SEED 0x2290
+#define regDIG2_DIG_RANDOM_PATTERN_SEED_BASE_IDX 2
+#define regDIG2_DIG_FIFO_STATUS 0x2291
+#define regDIG2_DIG_FIFO_STATUS_BASE_IDX 2
+#define regDIG2_HDMI_METADATA_PACKET_CONTROL 0x2292
+#define regDIG2_HDMI_METADATA_PACKET_CONTROL_BASE_IDX 2
+#define regDIG2_HDMI_CONTROL 0x2293
+#define regDIG2_HDMI_CONTROL_BASE_IDX 2
+#define regDIG2_HDMI_STATUS 0x2294
+#define regDIG2_HDMI_STATUS_BASE_IDX 2
+#define regDIG2_HDMI_AUDIO_PACKET_CONTROL 0x2295
+#define regDIG2_HDMI_AUDIO_PACKET_CONTROL_BASE_IDX 2
+#define regDIG2_HDMI_ACR_PACKET_CONTROL 0x2296
+#define regDIG2_HDMI_ACR_PACKET_CONTROL_BASE_IDX 2
+#define regDIG2_HDMI_VBI_PACKET_CONTROL 0x2297
+#define regDIG2_HDMI_VBI_PACKET_CONTROL_BASE_IDX 2
+#define regDIG2_HDMI_INFOFRAME_CONTROL0 0x2298
+#define regDIG2_HDMI_INFOFRAME_CONTROL0_BASE_IDX 2
+#define regDIG2_HDMI_INFOFRAME_CONTROL1 0x2299
+#define regDIG2_HDMI_INFOFRAME_CONTROL1_BASE_IDX 2
+#define regDIG2_HDMI_GENERIC_PACKET_CONTROL0 0x229a
+#define regDIG2_HDMI_GENERIC_PACKET_CONTROL0_BASE_IDX 2
+#define regDIG2_HDMI_GENERIC_PACKET_CONTROL6 0x229b
+#define regDIG2_HDMI_GENERIC_PACKET_CONTROL6_BASE_IDX 2
+#define regDIG2_HDMI_GENERIC_PACKET_CONTROL5 0x229c
+#define regDIG2_HDMI_GENERIC_PACKET_CONTROL5_BASE_IDX 2
+#define regDIG2_HDMI_GC 0x229d
+#define regDIG2_HDMI_GC_BASE_IDX 2
+#define regDIG2_HDMI_GENERIC_PACKET_CONTROL1 0x229e
+#define regDIG2_HDMI_GENERIC_PACKET_CONTROL1_BASE_IDX 2
+#define regDIG2_HDMI_GENERIC_PACKET_CONTROL2 0x229f
+#define regDIG2_HDMI_GENERIC_PACKET_CONTROL2_BASE_IDX 2
+#define regDIG2_HDMI_GENERIC_PACKET_CONTROL3 0x22a0
+#define regDIG2_HDMI_GENERIC_PACKET_CONTROL3_BASE_IDX 2
+#define regDIG2_HDMI_GENERIC_PACKET_CONTROL4 0x22a1
+#define regDIG2_HDMI_GENERIC_PACKET_CONTROL4_BASE_IDX 2
+#define regDIG2_HDMI_GENERIC_PACKET_CONTROL7 0x22a2
+#define regDIG2_HDMI_GENERIC_PACKET_CONTROL7_BASE_IDX 2
+#define regDIG2_HDMI_GENERIC_PACKET_CONTROL8 0x22a3
+#define regDIG2_HDMI_GENERIC_PACKET_CONTROL8_BASE_IDX 2
+#define regDIG2_HDMI_GENERIC_PACKET_CONTROL9 0x22a4
+#define regDIG2_HDMI_GENERIC_PACKET_CONTROL9_BASE_IDX 2
+#define regDIG2_HDMI_GENERIC_PACKET_CONTROL10 0x22a5
+#define regDIG2_HDMI_GENERIC_PACKET_CONTROL10_BASE_IDX 2
+#define regDIG2_HDMI_DB_CONTROL 0x22a6
+#define regDIG2_HDMI_DB_CONTROL_BASE_IDX 2
+#define regDIG2_HDMI_ACR_32_0 0x22a7
+#define regDIG2_HDMI_ACR_32_0_BASE_IDX 2
+#define regDIG2_HDMI_ACR_32_1 0x22a8
+#define regDIG2_HDMI_ACR_32_1_BASE_IDX 2
+#define regDIG2_HDMI_ACR_44_0 0x22a9
+#define regDIG2_HDMI_ACR_44_0_BASE_IDX 2
+#define regDIG2_HDMI_ACR_44_1 0x22aa
+#define regDIG2_HDMI_ACR_44_1_BASE_IDX 2
+#define regDIG2_HDMI_ACR_48_0 0x22ab
+#define regDIG2_HDMI_ACR_48_0_BASE_IDX 2
+#define regDIG2_HDMI_ACR_48_1 0x22ac
+#define regDIG2_HDMI_ACR_48_1_BASE_IDX 2
+#define regDIG2_HDMI_ACR_STATUS_0 0x22ad
+#define regDIG2_HDMI_ACR_STATUS_0_BASE_IDX 2
+#define regDIG2_HDMI_ACR_STATUS_1 0x22ae
+#define regDIG2_HDMI_ACR_STATUS_1_BASE_IDX 2
+#define regDIG2_AFMT_CNTL 0x22af
+#define regDIG2_AFMT_CNTL_BASE_IDX 2
+#define regDIG2_DIG_BE_CNTL 0x22b0
+#define regDIG2_DIG_BE_CNTL_BASE_IDX 2
+#define regDIG2_DIG_BE_EN_CNTL 0x22b1
+#define regDIG2_DIG_BE_EN_CNTL_BASE_IDX 2
+#define regDIG2_TMDS_CNTL 0x22d7
+#define regDIG2_TMDS_CNTL_BASE_IDX 2
+#define regDIG2_TMDS_CONTROL_CHAR 0x22d8
+#define regDIG2_TMDS_CONTROL_CHAR_BASE_IDX 2
+#define regDIG2_TMDS_CONTROL0_FEEDBACK 0x22d9
+#define regDIG2_TMDS_CONTROL0_FEEDBACK_BASE_IDX 2
+#define regDIG2_TMDS_STEREOSYNC_CTL_SEL 0x22da
+#define regDIG2_TMDS_STEREOSYNC_CTL_SEL_BASE_IDX 2
+#define regDIG2_TMDS_SYNC_CHAR_PATTERN_0_1 0x22db
+#define regDIG2_TMDS_SYNC_CHAR_PATTERN_0_1_BASE_IDX 2
+#define regDIG2_TMDS_SYNC_CHAR_PATTERN_2_3 0x22dc
+#define regDIG2_TMDS_SYNC_CHAR_PATTERN_2_3_BASE_IDX 2
+#define regDIG2_TMDS_CTL_BITS 0x22de
+#define regDIG2_TMDS_CTL_BITS_BASE_IDX 2
+#define regDIG2_TMDS_DCBALANCER_CONTROL 0x22df
+#define regDIG2_TMDS_DCBALANCER_CONTROL_BASE_IDX 2
+#define regDIG2_TMDS_SYNC_DCBALANCE_CHAR 0x22e0
+#define regDIG2_TMDS_SYNC_DCBALANCE_CHAR_BASE_IDX 2
+#define regDIG2_TMDS_CTL0_1_GEN_CNTL 0x22e1
+#define regDIG2_TMDS_CTL0_1_GEN_CNTL_BASE_IDX 2
+#define regDIG2_TMDS_CTL2_3_GEN_CNTL 0x22e2
+#define regDIG2_TMDS_CTL2_3_GEN_CNTL_BASE_IDX 2
+#define regDIG2_DIG_VERSION 0x22e4
+#define regDIG2_DIG_VERSION_BASE_IDX 2
+#define regDIG2_FORCE_DIG_DISABLE 0x22e5
+#define regDIG2_FORCE_DIG_DISABLE_BASE_IDX 2
+
+
+// addressBlock: dce_dc_dio_dp3_dispdec
+// base address: 0xc00
+#define regDP3_DP_LINK_CNTL 0x2408
+#define regDP3_DP_LINK_CNTL_BASE_IDX 2
+#define regDP3_DP_PIXEL_FORMAT 0x2409
+#define regDP3_DP_PIXEL_FORMAT_BASE_IDX 2
+#define regDP3_DP_MSA_COLORIMETRY 0x240a
+#define regDP3_DP_MSA_COLORIMETRY_BASE_IDX 2
+#define regDP3_DP_CONFIG 0x240b
+#define regDP3_DP_CONFIG_BASE_IDX 2
+#define regDP3_DP_VID_STREAM_CNTL 0x240c
+#define regDP3_DP_VID_STREAM_CNTL_BASE_IDX 2
+#define regDP3_DP_STEER_FIFO 0x240d
+#define regDP3_DP_STEER_FIFO_BASE_IDX 2
+#define regDP3_DP_MSA_MISC 0x240e
+#define regDP3_DP_MSA_MISC_BASE_IDX 2
+#define regDP3_DP_DPHY_INTERNAL_CTRL 0x240f
+#define regDP3_DP_DPHY_INTERNAL_CTRL_BASE_IDX 2
+#define regDP3_DP_VID_TIMING 0x2410
+#define regDP3_DP_VID_TIMING_BASE_IDX 2
+#define regDP3_DP_VID_N 0x2411
+#define regDP3_DP_VID_N_BASE_IDX 2
+#define regDP3_DP_VID_M 0x2412
+#define regDP3_DP_VID_M_BASE_IDX 2
+#define regDP3_DP_LINK_FRAMING_CNTL 0x2413
+#define regDP3_DP_LINK_FRAMING_CNTL_BASE_IDX 2
+#define regDP3_DP_HBR2_EYE_PATTERN 0x2414
+#define regDP3_DP_HBR2_EYE_PATTERN_BASE_IDX 2
+#define regDP3_DP_VID_MSA_VBID 0x2415
+#define regDP3_DP_VID_MSA_VBID_BASE_IDX 2
+#define regDP3_DP_VID_INTERRUPT_CNTL 0x2416
+#define regDP3_DP_VID_INTERRUPT_CNTL_BASE_IDX 2
+#define regDP3_DP_DPHY_CNTL 0x2417
+#define regDP3_DP_DPHY_CNTL_BASE_IDX 2
+#define regDP3_DP_DPHY_TRAINING_PATTERN_SEL 0x2418
+#define regDP3_DP_DPHY_TRAINING_PATTERN_SEL_BASE_IDX 2
+#define regDP3_DP_DPHY_SYM0 0x2419
+#define regDP3_DP_DPHY_SYM0_BASE_IDX 2
+#define regDP3_DP_DPHY_SYM1 0x241a
+#define regDP3_DP_DPHY_SYM1_BASE_IDX 2
+#define regDP3_DP_DPHY_SYM2 0x241b
+#define regDP3_DP_DPHY_SYM2_BASE_IDX 2
+#define regDP3_DP_DPHY_8B10B_CNTL 0x241c
+#define regDP3_DP_DPHY_8B10B_CNTL_BASE_IDX 2
+#define regDP3_DP_DPHY_PRBS_CNTL 0x241d
+#define regDP3_DP_DPHY_PRBS_CNTL_BASE_IDX 2
+#define regDP3_DP_DPHY_SCRAM_CNTL 0x241e
+#define regDP3_DP_DPHY_SCRAM_CNTL_BASE_IDX 2
+#define regDP3_DP_DPHY_CRC_EN 0x241f
+#define regDP3_DP_DPHY_CRC_EN_BASE_IDX 2
+#define regDP3_DP_DPHY_CRC_CNTL 0x2420
+#define regDP3_DP_DPHY_CRC_CNTL_BASE_IDX 2
+#define regDP3_DP_DPHY_CRC_RESULT 0x2421
+#define regDP3_DP_DPHY_CRC_RESULT_BASE_IDX 2
+#define regDP3_DP_DPHY_CRC_MST_CNTL 0x2422
+#define regDP3_DP_DPHY_CRC_MST_CNTL_BASE_IDX 2
+#define regDP3_DP_DPHY_CRC_MST_STATUS 0x2423
+#define regDP3_DP_DPHY_CRC_MST_STATUS_BASE_IDX 2
+#define regDP3_DP_DPHY_FAST_TRAINING 0x2424
+#define regDP3_DP_DPHY_FAST_TRAINING_BASE_IDX 2
+#define regDP3_DP_DPHY_FAST_TRAINING_STATUS 0x2425
+#define regDP3_DP_DPHY_FAST_TRAINING_STATUS_BASE_IDX 2
+#define regDP3_DP_SEC_CNTL 0x242b
+#define regDP3_DP_SEC_CNTL_BASE_IDX 2
+#define regDP3_DP_SEC_CNTL1 0x242c
+#define regDP3_DP_SEC_CNTL1_BASE_IDX 2
+#define regDP3_DP_SEC_FRAMING1 0x242d
+#define regDP3_DP_SEC_FRAMING1_BASE_IDX 2
+#define regDP3_DP_SEC_FRAMING2 0x242e
+#define regDP3_DP_SEC_FRAMING2_BASE_IDX 2
+#define regDP3_DP_SEC_FRAMING3 0x242f
+#define regDP3_DP_SEC_FRAMING3_BASE_IDX 2
+#define regDP3_DP_SEC_FRAMING4 0x2430
+#define regDP3_DP_SEC_FRAMING4_BASE_IDX 2
+#define regDP3_DP_SEC_AUD_N 0x2431
+#define regDP3_DP_SEC_AUD_N_BASE_IDX 2
+#define regDP3_DP_SEC_AUD_N_READBACK 0x2432
+#define regDP3_DP_SEC_AUD_N_READBACK_BASE_IDX 2
+#define regDP3_DP_SEC_AUD_M 0x2433
+#define regDP3_DP_SEC_AUD_M_BASE_IDX 2
+#define regDP3_DP_SEC_AUD_M_READBACK 0x2434
+#define regDP3_DP_SEC_AUD_M_READBACK_BASE_IDX 2
+#define regDP3_DP_SEC_TIMESTAMP 0x2435
+#define regDP3_DP_SEC_TIMESTAMP_BASE_IDX 2
+#define regDP3_DP_SEC_PACKET_CNTL 0x2436
+#define regDP3_DP_SEC_PACKET_CNTL_BASE_IDX 2
+#define regDP3_DP_MSE_RATE_CNTL 0x2437
+#define regDP3_DP_MSE_RATE_CNTL_BASE_IDX 2
+#define regDP3_DP_MSE_RATE_UPDATE 0x2439
+#define regDP3_DP_MSE_RATE_UPDATE_BASE_IDX 2
+#define regDP3_DP_MSE_SAT0 0x243a
+#define regDP3_DP_MSE_SAT0_BASE_IDX 2
+#define regDP3_DP_MSE_SAT1 0x243b
+#define regDP3_DP_MSE_SAT1_BASE_IDX 2
+#define regDP3_DP_MSE_SAT2 0x243c
+#define regDP3_DP_MSE_SAT2_BASE_IDX 2
+#define regDP3_DP_MSE_SAT_UPDATE 0x243d
+#define regDP3_DP_MSE_SAT_UPDATE_BASE_IDX 2
+#define regDP3_DP_MSE_LINK_TIMING 0x243e
+#define regDP3_DP_MSE_LINK_TIMING_BASE_IDX 2
+#define regDP3_DP_MSE_MISC_CNTL 0x243f
+#define regDP3_DP_MSE_MISC_CNTL_BASE_IDX 2
+#define regDP3_DP_DPHY_BS_SR_SWAP_CNTL 0x2444
+#define regDP3_DP_DPHY_BS_SR_SWAP_CNTL_BASE_IDX 2
+#define regDP3_DP_DPHY_HBR2_PATTERN_CONTROL 0x2445
+#define regDP3_DP_DPHY_HBR2_PATTERN_CONTROL_BASE_IDX 2
+#define regDP3_DP_MSE_SAT0_STATUS 0x2447
+#define regDP3_DP_MSE_SAT0_STATUS_BASE_IDX 2
+#define regDP3_DP_MSE_SAT1_STATUS 0x2448
+#define regDP3_DP_MSE_SAT1_STATUS_BASE_IDX 2
+#define regDP3_DP_MSE_SAT2_STATUS 0x2449
+#define regDP3_DP_MSE_SAT2_STATUS_BASE_IDX 2
+#define regDP3_DP_MSA_TIMING_PARAM1 0x244c
+#define regDP3_DP_MSA_TIMING_PARAM1_BASE_IDX 2
+#define regDP3_DP_MSA_TIMING_PARAM2 0x244d
+#define regDP3_DP_MSA_TIMING_PARAM2_BASE_IDX 2
+#define regDP3_DP_MSA_TIMING_PARAM3 0x244e
+#define regDP3_DP_MSA_TIMING_PARAM3_BASE_IDX 2
+#define regDP3_DP_MSA_TIMING_PARAM4 0x244f
+#define regDP3_DP_MSA_TIMING_PARAM4_BASE_IDX 2
+#define regDP3_DP_MSO_CNTL 0x2450
+#define regDP3_DP_MSO_CNTL_BASE_IDX 2
+#define regDP3_DP_MSO_CNTL1 0x2451
+#define regDP3_DP_MSO_CNTL1_BASE_IDX 2
+#define regDP3_DP_DSC_CNTL 0x2452
+#define regDP3_DP_DSC_CNTL_BASE_IDX 2
+#define regDP3_DP_SEC_CNTL2 0x2453
+#define regDP3_DP_SEC_CNTL2_BASE_IDX 2
+#define regDP3_DP_SEC_CNTL3 0x2454
+#define regDP3_DP_SEC_CNTL3_BASE_IDX 2
+#define regDP3_DP_SEC_CNTL4 0x2455
+#define regDP3_DP_SEC_CNTL4_BASE_IDX 2
+#define regDP3_DP_SEC_CNTL5 0x2456
+#define regDP3_DP_SEC_CNTL5_BASE_IDX 2
+#define regDP3_DP_SEC_CNTL6 0x2457
+#define regDP3_DP_SEC_CNTL6_BASE_IDX 2
+#define regDP3_DP_SEC_CNTL7 0x2458
+#define regDP3_DP_SEC_CNTL7_BASE_IDX 2
+#define regDP3_DP_DB_CNTL 0x2459
+#define regDP3_DP_DB_CNTL_BASE_IDX 2
+#define regDP3_DP_MSA_VBID_MISC 0x245a
+#define regDP3_DP_MSA_VBID_MISC_BASE_IDX 2
+#define regDP3_DP_SEC_METADATA_TRANSMISSION 0x245b
+#define regDP3_DP_SEC_METADATA_TRANSMISSION_BASE_IDX 2
+#define regDP3_DP_DSC_BYTES_PER_PIXEL 0x245c
+#define regDP3_DP_DSC_BYTES_PER_PIXEL_BASE_IDX 2
+#define regDP3_DP_ALPM_CNTL 0x245d
+#define regDP3_DP_ALPM_CNTL_BASE_IDX 2
+#define regDP3_DP_GSP8_CNTL 0x245e
+#define regDP3_DP_GSP8_CNTL_BASE_IDX 2
+#define regDP3_DP_GSP9_CNTL 0x245f
+#define regDP3_DP_GSP9_CNTL_BASE_IDX 2
+#define regDP3_DP_GSP10_CNTL 0x2460
+#define regDP3_DP_GSP10_CNTL_BASE_IDX 2
+#define regDP3_DP_GSP11_CNTL 0x2461
+#define regDP3_DP_GSP11_CNTL_BASE_IDX 2
+#define regDP3_DP_GSP_EN_DB_STATUS 0x2462
+#define regDP3_DP_GSP_EN_DB_STATUS_BASE_IDX 2
+
+
+// addressBlock: dce_dc_dio_dig3_dispdec
+// base address: 0xc00
+#define regDIG3_DIG_FE_CNTL 0x238b
+#define regDIG3_DIG_FE_CNTL_BASE_IDX 2
+#define regDIG3_DIG_OUTPUT_CRC_CNTL 0x238c
+#define regDIG3_DIG_OUTPUT_CRC_CNTL_BASE_IDX 2
+#define regDIG3_DIG_OUTPUT_CRC_RESULT 0x238d
+#define regDIG3_DIG_OUTPUT_CRC_RESULT_BASE_IDX 2
+#define regDIG3_DIG_CLOCK_PATTERN 0x238e
+#define regDIG3_DIG_CLOCK_PATTERN_BASE_IDX 2
+#define regDIG3_DIG_TEST_PATTERN 0x238f
+#define regDIG3_DIG_TEST_PATTERN_BASE_IDX 2
+#define regDIG3_DIG_RANDOM_PATTERN_SEED 0x2390
+#define regDIG3_DIG_RANDOM_PATTERN_SEED_BASE_IDX 2
+#define regDIG3_DIG_FIFO_STATUS 0x2391
+#define regDIG3_DIG_FIFO_STATUS_BASE_IDX 2
+#define regDIG3_HDMI_METADATA_PACKET_CONTROL 0x2392
+#define regDIG3_HDMI_METADATA_PACKET_CONTROL_BASE_IDX 2
+#define regDIG3_HDMI_CONTROL 0x2393
+#define regDIG3_HDMI_CONTROL_BASE_IDX 2
+#define regDIG3_HDMI_STATUS 0x2394
+#define regDIG3_HDMI_STATUS_BASE_IDX 2
+#define regDIG3_HDMI_AUDIO_PACKET_CONTROL 0x2395
+#define regDIG3_HDMI_AUDIO_PACKET_CONTROL_BASE_IDX 2
+#define regDIG3_HDMI_ACR_PACKET_CONTROL 0x2396
+#define regDIG3_HDMI_ACR_PACKET_CONTROL_BASE_IDX 2
+#define regDIG3_HDMI_VBI_PACKET_CONTROL 0x2397
+#define regDIG3_HDMI_VBI_PACKET_CONTROL_BASE_IDX 2
+#define regDIG3_HDMI_INFOFRAME_CONTROL0 0x2398
+#define regDIG3_HDMI_INFOFRAME_CONTROL0_BASE_IDX 2
+#define regDIG3_HDMI_INFOFRAME_CONTROL1 0x2399
+#define regDIG3_HDMI_INFOFRAME_CONTROL1_BASE_IDX 2
+#define regDIG3_HDMI_GENERIC_PACKET_CONTROL0 0x239a
+#define regDIG3_HDMI_GENERIC_PACKET_CONTROL0_BASE_IDX 2
+#define regDIG3_HDMI_GENERIC_PACKET_CONTROL6 0x239b
+#define regDIG3_HDMI_GENERIC_PACKET_CONTROL6_BASE_IDX 2
+#define regDIG3_HDMI_GENERIC_PACKET_CONTROL5 0x239c
+#define regDIG3_HDMI_GENERIC_PACKET_CONTROL5_BASE_IDX 2
+#define regDIG3_HDMI_GC 0x239d
+#define regDIG3_HDMI_GC_BASE_IDX 2
+#define regDIG3_HDMI_GENERIC_PACKET_CONTROL1 0x239e
+#define regDIG3_HDMI_GENERIC_PACKET_CONTROL1_BASE_IDX 2
+#define regDIG3_HDMI_GENERIC_PACKET_CONTROL2 0x239f
+#define regDIG3_HDMI_GENERIC_PACKET_CONTROL2_BASE_IDX 2
+#define regDIG3_HDMI_GENERIC_PACKET_CONTROL3 0x23a0
+#define regDIG3_HDMI_GENERIC_PACKET_CONTROL3_BASE_IDX 2
+#define regDIG3_HDMI_GENERIC_PACKET_CONTROL4 0x23a1
+#define regDIG3_HDMI_GENERIC_PACKET_CONTROL4_BASE_IDX 2
+#define regDIG3_HDMI_GENERIC_PACKET_CONTROL7 0x23a2
+#define regDIG3_HDMI_GENERIC_PACKET_CONTROL7_BASE_IDX 2
+#define regDIG3_HDMI_GENERIC_PACKET_CONTROL8 0x23a3
+#define regDIG3_HDMI_GENERIC_PACKET_CONTROL8_BASE_IDX 2
+#define regDIG3_HDMI_GENERIC_PACKET_CONTROL9 0x23a4
+#define regDIG3_HDMI_GENERIC_PACKET_CONTROL9_BASE_IDX 2
+#define regDIG3_HDMI_GENERIC_PACKET_CONTROL10 0x23a5
+#define regDIG3_HDMI_GENERIC_PACKET_CONTROL10_BASE_IDX 2
+#define regDIG3_HDMI_DB_CONTROL 0x23a6
+#define regDIG3_HDMI_DB_CONTROL_BASE_IDX 2
+#define regDIG3_HDMI_ACR_32_0 0x23a7
+#define regDIG3_HDMI_ACR_32_0_BASE_IDX 2
+#define regDIG3_HDMI_ACR_32_1 0x23a8
+#define regDIG3_HDMI_ACR_32_1_BASE_IDX 2
+#define regDIG3_HDMI_ACR_44_0 0x23a9
+#define regDIG3_HDMI_ACR_44_0_BASE_IDX 2
+#define regDIG3_HDMI_ACR_44_1 0x23aa
+#define regDIG3_HDMI_ACR_44_1_BASE_IDX 2
+#define regDIG3_HDMI_ACR_48_0 0x23ab
+#define regDIG3_HDMI_ACR_48_0_BASE_IDX 2
+#define regDIG3_HDMI_ACR_48_1 0x23ac
+#define regDIG3_HDMI_ACR_48_1_BASE_IDX 2
+#define regDIG3_HDMI_ACR_STATUS_0 0x23ad
+#define regDIG3_HDMI_ACR_STATUS_0_BASE_IDX 2
+#define regDIG3_HDMI_ACR_STATUS_1 0x23ae
+#define regDIG3_HDMI_ACR_STATUS_1_BASE_IDX 2
+#define regDIG3_AFMT_CNTL 0x23af
+#define regDIG3_AFMT_CNTL_BASE_IDX 2
+#define regDIG3_DIG_BE_CNTL 0x23b0
+#define regDIG3_DIG_BE_CNTL_BASE_IDX 2
+#define regDIG3_DIG_BE_EN_CNTL 0x23b1
+#define regDIG3_DIG_BE_EN_CNTL_BASE_IDX 2
+#define regDIG3_TMDS_CNTL 0x23d7
+#define regDIG3_TMDS_CNTL_BASE_IDX 2
+#define regDIG3_TMDS_CONTROL_CHAR 0x23d8
+#define regDIG3_TMDS_CONTROL_CHAR_BASE_IDX 2
+#define regDIG3_TMDS_CONTROL0_FEEDBACK 0x23d9
+#define regDIG3_TMDS_CONTROL0_FEEDBACK_BASE_IDX 2
+#define regDIG3_TMDS_STEREOSYNC_CTL_SEL 0x23da
+#define regDIG3_TMDS_STEREOSYNC_CTL_SEL_BASE_IDX 2
+#define regDIG3_TMDS_SYNC_CHAR_PATTERN_0_1 0x23db
+#define regDIG3_TMDS_SYNC_CHAR_PATTERN_0_1_BASE_IDX 2
+#define regDIG3_TMDS_SYNC_CHAR_PATTERN_2_3 0x23dc
+#define regDIG3_TMDS_SYNC_CHAR_PATTERN_2_3_BASE_IDX 2
+#define regDIG3_TMDS_CTL_BITS 0x23de
+#define regDIG3_TMDS_CTL_BITS_BASE_IDX 2
+#define regDIG3_TMDS_DCBALANCER_CONTROL 0x23df
+#define regDIG3_TMDS_DCBALANCER_CONTROL_BASE_IDX 2
+#define regDIG3_TMDS_SYNC_DCBALANCE_CHAR 0x23e0
+#define regDIG3_TMDS_SYNC_DCBALANCE_CHAR_BASE_IDX 2
+#define regDIG3_TMDS_CTL0_1_GEN_CNTL 0x23e1
+#define regDIG3_TMDS_CTL0_1_GEN_CNTL_BASE_IDX 2
+#define regDIG3_TMDS_CTL2_3_GEN_CNTL 0x23e2
+#define regDIG3_TMDS_CTL2_3_GEN_CNTL_BASE_IDX 2
+#define regDIG3_DIG_VERSION 0x23e4
+#define regDIG3_DIG_VERSION_BASE_IDX 2
+#define regDIG3_FORCE_DIG_DISABLE 0x23e5
+#define regDIG3_FORCE_DIG_DISABLE_BASE_IDX 2
+
+
+// addressBlock: dce_dc_dio_dp4_dispdec
+// base address: 0x1000
+#define regDP4_DP_LINK_CNTL 0x2508
+#define regDP4_DP_LINK_CNTL_BASE_IDX 2
+#define regDP4_DP_PIXEL_FORMAT 0x2509
+#define regDP4_DP_PIXEL_FORMAT_BASE_IDX 2
+#define regDP4_DP_MSA_COLORIMETRY 0x250a
+#define regDP4_DP_MSA_COLORIMETRY_BASE_IDX 2
+#define regDP4_DP_CONFIG 0x250b
+#define regDP4_DP_CONFIG_BASE_IDX 2
+#define regDP4_DP_VID_STREAM_CNTL 0x250c
+#define regDP4_DP_VID_STREAM_CNTL_BASE_IDX 2
+#define regDP4_DP_STEER_FIFO 0x250d
+#define regDP4_DP_STEER_FIFO_BASE_IDX 2
+#define regDP4_DP_MSA_MISC 0x250e
+#define regDP4_DP_MSA_MISC_BASE_IDX 2
+#define regDP4_DP_DPHY_INTERNAL_CTRL 0x250f
+#define regDP4_DP_DPHY_INTERNAL_CTRL_BASE_IDX 2
+#define regDP4_DP_VID_TIMING 0x2510
+#define regDP4_DP_VID_TIMING_BASE_IDX 2
+#define regDP4_DP_VID_N 0x2511
+#define regDP4_DP_VID_N_BASE_IDX 2
+#define regDP4_DP_VID_M 0x2512
+#define regDP4_DP_VID_M_BASE_IDX 2
+#define regDP4_DP_LINK_FRAMING_CNTL 0x2513
+#define regDP4_DP_LINK_FRAMING_CNTL_BASE_IDX 2
+#define regDP4_DP_HBR2_EYE_PATTERN 0x2514
+#define regDP4_DP_HBR2_EYE_PATTERN_BASE_IDX 2
+#define regDP4_DP_VID_MSA_VBID 0x2515
+#define regDP4_DP_VID_MSA_VBID_BASE_IDX 2
+#define regDP4_DP_VID_INTERRUPT_CNTL 0x2516
+#define regDP4_DP_VID_INTERRUPT_CNTL_BASE_IDX 2
+#define regDP4_DP_DPHY_CNTL 0x2517
+#define regDP4_DP_DPHY_CNTL_BASE_IDX 2
+#define regDP4_DP_DPHY_TRAINING_PATTERN_SEL 0x2518
+#define regDP4_DP_DPHY_TRAINING_PATTERN_SEL_BASE_IDX 2
+#define regDP4_DP_DPHY_SYM0 0x2519
+#define regDP4_DP_DPHY_SYM0_BASE_IDX 2
+#define regDP4_DP_DPHY_SYM1 0x251a
+#define regDP4_DP_DPHY_SYM1_BASE_IDX 2
+#define regDP4_DP_DPHY_SYM2 0x251b
+#define regDP4_DP_DPHY_SYM2_BASE_IDX 2
+#define regDP4_DP_DPHY_8B10B_CNTL 0x251c
+#define regDP4_DP_DPHY_8B10B_CNTL_BASE_IDX 2
+#define regDP4_DP_DPHY_PRBS_CNTL 0x251d
+#define regDP4_DP_DPHY_PRBS_CNTL_BASE_IDX 2
+#define regDP4_DP_DPHY_SCRAM_CNTL 0x251e
+#define regDP4_DP_DPHY_SCRAM_CNTL_BASE_IDX 2
+#define regDP4_DP_DPHY_CRC_EN 0x251f
+#define regDP4_DP_DPHY_CRC_EN_BASE_IDX 2
+#define regDP4_DP_DPHY_CRC_CNTL 0x2520
+#define regDP4_DP_DPHY_CRC_CNTL_BASE_IDX 2
+#define regDP4_DP_DPHY_CRC_RESULT 0x2521
+#define regDP4_DP_DPHY_CRC_RESULT_BASE_IDX 2
+#define regDP4_DP_DPHY_CRC_MST_CNTL 0x2522
+#define regDP4_DP_DPHY_CRC_MST_CNTL_BASE_IDX 2
+#define regDP4_DP_DPHY_CRC_MST_STATUS 0x2523
+#define regDP4_DP_DPHY_CRC_MST_STATUS_BASE_IDX 2
+#define regDP4_DP_DPHY_FAST_TRAINING 0x2524
+#define regDP4_DP_DPHY_FAST_TRAINING_BASE_IDX 2
+#define regDP4_DP_DPHY_FAST_TRAINING_STATUS 0x2525
+#define regDP4_DP_DPHY_FAST_TRAINING_STATUS_BASE_IDX 2
+#define regDP4_DP_SEC_CNTL 0x252b
+#define regDP4_DP_SEC_CNTL_BASE_IDX 2
+#define regDP4_DP_SEC_CNTL1 0x252c
+#define regDP4_DP_SEC_CNTL1_BASE_IDX 2
+#define regDP4_DP_SEC_FRAMING1 0x252d
+#define regDP4_DP_SEC_FRAMING1_BASE_IDX 2
+#define regDP4_DP_SEC_FRAMING2 0x252e
+#define regDP4_DP_SEC_FRAMING2_BASE_IDX 2
+#define regDP4_DP_SEC_FRAMING3 0x252f
+#define regDP4_DP_SEC_FRAMING3_BASE_IDX 2
+#define regDP4_DP_SEC_FRAMING4 0x2530
+#define regDP4_DP_SEC_FRAMING4_BASE_IDX 2
+#define regDP4_DP_SEC_AUD_N 0x2531
+#define regDP4_DP_SEC_AUD_N_BASE_IDX 2
+#define regDP4_DP_SEC_AUD_N_READBACK 0x2532
+#define regDP4_DP_SEC_AUD_N_READBACK_BASE_IDX 2
+#define regDP4_DP_SEC_AUD_M 0x2533
+#define regDP4_DP_SEC_AUD_M_BASE_IDX 2
+#define regDP4_DP_SEC_AUD_M_READBACK 0x2534
+#define regDP4_DP_SEC_AUD_M_READBACK_BASE_IDX 2
+#define regDP4_DP_SEC_TIMESTAMP 0x2535
+#define regDP4_DP_SEC_TIMESTAMP_BASE_IDX 2
+#define regDP4_DP_SEC_PACKET_CNTL 0x2536
+#define regDP4_DP_SEC_PACKET_CNTL_BASE_IDX 2
+#define regDP4_DP_MSE_RATE_CNTL 0x2537
+#define regDP4_DP_MSE_RATE_CNTL_BASE_IDX 2
+#define regDP4_DP_MSE_RATE_UPDATE 0x2539
+#define regDP4_DP_MSE_RATE_UPDATE_BASE_IDX 2
+#define regDP4_DP_MSE_SAT0 0x253a
+#define regDP4_DP_MSE_SAT0_BASE_IDX 2
+#define regDP4_DP_MSE_SAT1 0x253b
+#define regDP4_DP_MSE_SAT1_BASE_IDX 2
+#define regDP4_DP_MSE_SAT2 0x253c
+#define regDP4_DP_MSE_SAT2_BASE_IDX 2
+#define regDP4_DP_MSE_SAT_UPDATE 0x253d
+#define regDP4_DP_MSE_SAT_UPDATE_BASE_IDX 2
+#define regDP4_DP_MSE_LINK_TIMING 0x253e
+#define regDP4_DP_MSE_LINK_TIMING_BASE_IDX 2
+#define regDP4_DP_MSE_MISC_CNTL 0x253f
+#define regDP4_DP_MSE_MISC_CNTL_BASE_IDX 2
+#define regDP4_DP_DPHY_BS_SR_SWAP_CNTL 0x2544
+#define regDP4_DP_DPHY_BS_SR_SWAP_CNTL_BASE_IDX 2
+#define regDP4_DP_DPHY_HBR2_PATTERN_CONTROL 0x2545
+#define regDP4_DP_DPHY_HBR2_PATTERN_CONTROL_BASE_IDX 2
+#define regDP4_DP_MSE_SAT0_STATUS 0x2547
+#define regDP4_DP_MSE_SAT0_STATUS_BASE_IDX 2
+#define regDP4_DP_MSE_SAT1_STATUS 0x2548
+#define regDP4_DP_MSE_SAT1_STATUS_BASE_IDX 2
+#define regDP4_DP_MSE_SAT2_STATUS 0x2549
+#define regDP4_DP_MSE_SAT2_STATUS_BASE_IDX 2
+#define regDP4_DP_MSA_TIMING_PARAM1 0x254c
+#define regDP4_DP_MSA_TIMING_PARAM1_BASE_IDX 2
+#define regDP4_DP_MSA_TIMING_PARAM2 0x254d
+#define regDP4_DP_MSA_TIMING_PARAM2_BASE_IDX 2
+#define regDP4_DP_MSA_TIMING_PARAM3 0x254e
+#define regDP4_DP_MSA_TIMING_PARAM3_BASE_IDX 2
+#define regDP4_DP_MSA_TIMING_PARAM4 0x254f
+#define regDP4_DP_MSA_TIMING_PARAM4_BASE_IDX 2
+#define regDP4_DP_MSO_CNTL 0x2550
+#define regDP4_DP_MSO_CNTL_BASE_IDX 2
+#define regDP4_DP_MSO_CNTL1 0x2551
+#define regDP4_DP_MSO_CNTL1_BASE_IDX 2
+#define regDP4_DP_DSC_CNTL 0x2552
+#define regDP4_DP_DSC_CNTL_BASE_IDX 2
+#define regDP4_DP_SEC_CNTL2 0x2553
+#define regDP4_DP_SEC_CNTL2_BASE_IDX 2
+#define regDP4_DP_SEC_CNTL3 0x2554
+#define regDP4_DP_SEC_CNTL3_BASE_IDX 2
+#define regDP4_DP_SEC_CNTL4 0x2555
+#define regDP4_DP_SEC_CNTL4_BASE_IDX 2
+#define regDP4_DP_SEC_CNTL5 0x2556
+#define regDP4_DP_SEC_CNTL5_BASE_IDX 2
+#define regDP4_DP_SEC_CNTL6 0x2557
+#define regDP4_DP_SEC_CNTL6_BASE_IDX 2
+#define regDP4_DP_SEC_CNTL7 0x2558
+#define regDP4_DP_SEC_CNTL7_BASE_IDX 2
+#define regDP4_DP_DB_CNTL 0x2559
+#define regDP4_DP_DB_CNTL_BASE_IDX 2
+#define regDP4_DP_MSA_VBID_MISC 0x255a
+#define regDP4_DP_MSA_VBID_MISC_BASE_IDX 2
+#define regDP4_DP_SEC_METADATA_TRANSMISSION 0x255b
+#define regDP4_DP_SEC_METADATA_TRANSMISSION_BASE_IDX 2
+#define regDP4_DP_DSC_BYTES_PER_PIXEL 0x255c
+#define regDP4_DP_DSC_BYTES_PER_PIXEL_BASE_IDX 2
+#define regDP4_DP_ALPM_CNTL 0x255d
+#define regDP4_DP_ALPM_CNTL_BASE_IDX 2
+#define regDP4_DP_GSP8_CNTL 0x255e
+#define regDP4_DP_GSP8_CNTL_BASE_IDX 2
+#define regDP4_DP_GSP9_CNTL 0x255f
+#define regDP4_DP_GSP9_CNTL_BASE_IDX 2
+#define regDP4_DP_GSP10_CNTL 0x2560
+#define regDP4_DP_GSP10_CNTL_BASE_IDX 2
+#define regDP4_DP_GSP11_CNTL 0x2561
+#define regDP4_DP_GSP11_CNTL_BASE_IDX 2
+#define regDP4_DP_GSP_EN_DB_STATUS 0x2562
+#define regDP4_DP_GSP_EN_DB_STATUS_BASE_IDX 2
+
+
+// addressBlock: dce_dc_dio_dig4_dispdec
+// base address: 0x1000
+#define regDIG4_DIG_FE_CNTL 0x248b
+#define regDIG4_DIG_FE_CNTL_BASE_IDX 2
+#define regDIG4_DIG_OUTPUT_CRC_CNTL 0x248c
+#define regDIG4_DIG_OUTPUT_CRC_CNTL_BASE_IDX 2
+#define regDIG4_DIG_OUTPUT_CRC_RESULT 0x248d
+#define regDIG4_DIG_OUTPUT_CRC_RESULT_BASE_IDX 2
+#define regDIG4_DIG_CLOCK_PATTERN 0x248e
+#define regDIG4_DIG_CLOCK_PATTERN_BASE_IDX 2
+#define regDIG4_DIG_TEST_PATTERN 0x248f
+#define regDIG4_DIG_TEST_PATTERN_BASE_IDX 2
+#define regDIG4_DIG_RANDOM_PATTERN_SEED 0x2490
+#define regDIG4_DIG_RANDOM_PATTERN_SEED_BASE_IDX 2
+#define regDIG4_DIG_FIFO_STATUS 0x2491
+#define regDIG4_DIG_FIFO_STATUS_BASE_IDX 2
+#define regDIG4_HDMI_METADATA_PACKET_CONTROL 0x2492
+#define regDIG4_HDMI_METADATA_PACKET_CONTROL_BASE_IDX 2
+#define regDIG4_HDMI_CONTROL 0x2493
+#define regDIG4_HDMI_CONTROL_BASE_IDX 2
+#define regDIG4_HDMI_STATUS 0x2494
+#define regDIG4_HDMI_STATUS_BASE_IDX 2
+#define regDIG4_HDMI_AUDIO_PACKET_CONTROL 0x2495
+#define regDIG4_HDMI_AUDIO_PACKET_CONTROL_BASE_IDX 2
+#define regDIG4_HDMI_ACR_PACKET_CONTROL 0x2496
+#define regDIG4_HDMI_ACR_PACKET_CONTROL_BASE_IDX 2
+#define regDIG4_HDMI_VBI_PACKET_CONTROL 0x2497
+#define regDIG4_HDMI_VBI_PACKET_CONTROL_BASE_IDX 2
+#define regDIG4_HDMI_INFOFRAME_CONTROL0 0x2498
+#define regDIG4_HDMI_INFOFRAME_CONTROL0_BASE_IDX 2
+#define regDIG4_HDMI_INFOFRAME_CONTROL1 0x2499
+#define regDIG4_HDMI_INFOFRAME_CONTROL1_BASE_IDX 2
+#define regDIG4_HDMI_GENERIC_PACKET_CONTROL0 0x249a
+#define regDIG4_HDMI_GENERIC_PACKET_CONTROL0_BASE_IDX 2
+#define regDIG4_HDMI_GENERIC_PACKET_CONTROL6 0x249b
+#define regDIG4_HDMI_GENERIC_PACKET_CONTROL6_BASE_IDX 2
+#define regDIG4_HDMI_GENERIC_PACKET_CONTROL5 0x249c
+#define regDIG4_HDMI_GENERIC_PACKET_CONTROL5_BASE_IDX 2
+#define regDIG4_HDMI_GC 0x249d
+#define regDIG4_HDMI_GC_BASE_IDX 2
+#define regDIG4_HDMI_GENERIC_PACKET_CONTROL1 0x249e
+#define regDIG4_HDMI_GENERIC_PACKET_CONTROL1_BASE_IDX 2
+#define regDIG4_HDMI_GENERIC_PACKET_CONTROL2 0x249f
+#define regDIG4_HDMI_GENERIC_PACKET_CONTROL2_BASE_IDX 2
+#define regDIG4_HDMI_GENERIC_PACKET_CONTROL3 0x24a0
+#define regDIG4_HDMI_GENERIC_PACKET_CONTROL3_BASE_IDX 2
+#define regDIG4_HDMI_GENERIC_PACKET_CONTROL4 0x24a1
+#define regDIG4_HDMI_GENERIC_PACKET_CONTROL4_BASE_IDX 2
+#define regDIG4_HDMI_GENERIC_PACKET_CONTROL7 0x24a2
+#define regDIG4_HDMI_GENERIC_PACKET_CONTROL7_BASE_IDX 2
+#define regDIG4_HDMI_GENERIC_PACKET_CONTROL8 0x24a3
+#define regDIG4_HDMI_GENERIC_PACKET_CONTROL8_BASE_IDX 2
+#define regDIG4_HDMI_GENERIC_PACKET_CONTROL9 0x24a4
+#define regDIG4_HDMI_GENERIC_PACKET_CONTROL9_BASE_IDX 2
+#define regDIG4_HDMI_GENERIC_PACKET_CONTROL10 0x24a5
+#define regDIG4_HDMI_GENERIC_PACKET_CONTROL10_BASE_IDX 2
+#define regDIG4_HDMI_DB_CONTROL 0x24a6
+#define regDIG4_HDMI_DB_CONTROL_BASE_IDX 2
+#define regDIG4_HDMI_ACR_32_0 0x24a7
+#define regDIG4_HDMI_ACR_32_0_BASE_IDX 2
+#define regDIG4_HDMI_ACR_32_1 0x24a8
+#define regDIG4_HDMI_ACR_32_1_BASE_IDX 2
+#define regDIG4_HDMI_ACR_44_0 0x24a9
+#define regDIG4_HDMI_ACR_44_0_BASE_IDX 2
+#define regDIG4_HDMI_ACR_44_1 0x24aa
+#define regDIG4_HDMI_ACR_44_1_BASE_IDX 2
+#define regDIG4_HDMI_ACR_48_0 0x24ab
+#define regDIG4_HDMI_ACR_48_0_BASE_IDX 2
+#define regDIG4_HDMI_ACR_48_1 0x24ac
+#define regDIG4_HDMI_ACR_48_1_BASE_IDX 2
+#define regDIG4_HDMI_ACR_STATUS_0 0x24ad
+#define regDIG4_HDMI_ACR_STATUS_0_BASE_IDX 2
+#define regDIG4_HDMI_ACR_STATUS_1 0x24ae
+#define regDIG4_HDMI_ACR_STATUS_1_BASE_IDX 2
+#define regDIG4_AFMT_CNTL 0x24af
+#define regDIG4_AFMT_CNTL_BASE_IDX 2
+#define regDIG4_DIG_BE_CNTL 0x24b0
+#define regDIG4_DIG_BE_CNTL_BASE_IDX 2
+#define regDIG4_DIG_BE_EN_CNTL 0x24b1
+#define regDIG4_DIG_BE_EN_CNTL_BASE_IDX 2
+#define regDIG4_TMDS_CNTL 0x24d7
+#define regDIG4_TMDS_CNTL_BASE_IDX 2
+#define regDIG4_TMDS_CONTROL_CHAR 0x24d8
+#define regDIG4_TMDS_CONTROL_CHAR_BASE_IDX 2
+#define regDIG4_TMDS_CONTROL0_FEEDBACK 0x24d9
+#define regDIG4_TMDS_CONTROL0_FEEDBACK_BASE_IDX 2
+#define regDIG4_TMDS_STEREOSYNC_CTL_SEL 0x24da
+#define regDIG4_TMDS_STEREOSYNC_CTL_SEL_BASE_IDX 2
+#define regDIG4_TMDS_SYNC_CHAR_PATTERN_0_1 0x24db
+#define regDIG4_TMDS_SYNC_CHAR_PATTERN_0_1_BASE_IDX 2
+#define regDIG4_TMDS_SYNC_CHAR_PATTERN_2_3 0x24dc
+#define regDIG4_TMDS_SYNC_CHAR_PATTERN_2_3_BASE_IDX 2
+#define regDIG4_TMDS_CTL_BITS 0x24de
+#define regDIG4_TMDS_CTL_BITS_BASE_IDX 2
+#define regDIG4_TMDS_DCBALANCER_CONTROL 0x24df
+#define regDIG4_TMDS_DCBALANCER_CONTROL_BASE_IDX 2
+#define regDIG4_TMDS_SYNC_DCBALANCE_CHAR 0x24e0
+#define regDIG4_TMDS_SYNC_DCBALANCE_CHAR_BASE_IDX 2
+#define regDIG4_TMDS_CTL0_1_GEN_CNTL 0x24e1
+#define regDIG4_TMDS_CTL0_1_GEN_CNTL_BASE_IDX 2
+#define regDIG4_TMDS_CTL2_3_GEN_CNTL 0x24e2
+#define regDIG4_TMDS_CTL2_3_GEN_CNTL_BASE_IDX 2
+#define regDIG4_DIG_VERSION 0x24e4
+#define regDIG4_DIG_VERSION_BASE_IDX 2
+#define regDIG4_FORCE_DIG_DISABLE 0x24e5
+#define regDIG4_FORCE_DIG_DISABLE_BASE_IDX 2
+
+
+// addressBlock: dce_dc_dio_dig0_afmt_afmt_dispdec
+// base address: 0x154cc
+#define regAFMT0_AFMT_VBI_PACKET_CONTROL 0x2074
+#define regAFMT0_AFMT_VBI_PACKET_CONTROL_BASE_IDX 2
+#define regAFMT0_AFMT_AUDIO_PACKET_CONTROL2 0x2075
+#define regAFMT0_AFMT_AUDIO_PACKET_CONTROL2_BASE_IDX 2
+#define regAFMT0_AFMT_AUDIO_INFO0 0x2076
+#define regAFMT0_AFMT_AUDIO_INFO0_BASE_IDX 2
+#define regAFMT0_AFMT_AUDIO_INFO1 0x2077
+#define regAFMT0_AFMT_AUDIO_INFO1_BASE_IDX 2
+#define regAFMT0_AFMT_60958_0 0x2078
+#define regAFMT0_AFMT_60958_0_BASE_IDX 2
+#define regAFMT0_AFMT_60958_1 0x2079
+#define regAFMT0_AFMT_60958_1_BASE_IDX 2
+#define regAFMT0_AFMT_AUDIO_CRC_CONTROL 0x207a
+#define regAFMT0_AFMT_AUDIO_CRC_CONTROL_BASE_IDX 2
+#define regAFMT0_AFMT_RAMP_CONTROL0 0x207b
+#define regAFMT0_AFMT_RAMP_CONTROL0_BASE_IDX 2
+#define regAFMT0_AFMT_RAMP_CONTROL1 0x207c
+#define regAFMT0_AFMT_RAMP_CONTROL1_BASE_IDX 2
+#define regAFMT0_AFMT_RAMP_CONTROL2 0x207d
+#define regAFMT0_AFMT_RAMP_CONTROL2_BASE_IDX 2
+#define regAFMT0_AFMT_RAMP_CONTROL3 0x207e
+#define regAFMT0_AFMT_RAMP_CONTROL3_BASE_IDX 2
+#define regAFMT0_AFMT_60958_2 0x207f
+#define regAFMT0_AFMT_60958_2_BASE_IDX 2
+#define regAFMT0_AFMT_AUDIO_CRC_RESULT 0x2080
+#define regAFMT0_AFMT_AUDIO_CRC_RESULT_BASE_IDX 2
+#define regAFMT0_AFMT_STATUS 0x2081
+#define regAFMT0_AFMT_STATUS_BASE_IDX 2
+#define regAFMT0_AFMT_AUDIO_PACKET_CONTROL 0x2082
+#define regAFMT0_AFMT_AUDIO_PACKET_CONTROL_BASE_IDX 2
+#define regAFMT0_AFMT_INFOFRAME_CONTROL0 0x2083
+#define regAFMT0_AFMT_INFOFRAME_CONTROL0_BASE_IDX 2
+#define regAFMT0_AFMT_AUDIO_SRC_CONTROL 0x2085
+#define regAFMT0_AFMT_AUDIO_SRC_CONTROL_BASE_IDX 2
+#define regAFMT0_AFMT_MEM_PWR 0x2087
+#define regAFMT0_AFMT_MEM_PWR_BASE_IDX 2
+
+
+// addressBlock: dce_dc_dio_dig1_afmt_afmt_dispdec
+// base address: 0x158cc
+#define regAFMT1_AFMT_VBI_PACKET_CONTROL 0x2174
+#define regAFMT1_AFMT_VBI_PACKET_CONTROL_BASE_IDX 2
+#define regAFMT1_AFMT_AUDIO_PACKET_CONTROL2 0x2175
+#define regAFMT1_AFMT_AUDIO_PACKET_CONTROL2_BASE_IDX 2
+#define regAFMT1_AFMT_AUDIO_INFO0 0x2176
+#define regAFMT1_AFMT_AUDIO_INFO0_BASE_IDX 2
+#define regAFMT1_AFMT_AUDIO_INFO1 0x2177
+#define regAFMT1_AFMT_AUDIO_INFO1_BASE_IDX 2
+#define regAFMT1_AFMT_60958_0 0x2178
+#define regAFMT1_AFMT_60958_0_BASE_IDX 2
+#define regAFMT1_AFMT_60958_1 0x2179
+#define regAFMT1_AFMT_60958_1_BASE_IDX 2
+#define regAFMT1_AFMT_AUDIO_CRC_CONTROL 0x217a
+#define regAFMT1_AFMT_AUDIO_CRC_CONTROL_BASE_IDX 2
+#define regAFMT1_AFMT_RAMP_CONTROL0 0x217b
+#define regAFMT1_AFMT_RAMP_CONTROL0_BASE_IDX 2
+#define regAFMT1_AFMT_RAMP_CONTROL1 0x217c
+#define regAFMT1_AFMT_RAMP_CONTROL1_BASE_IDX 2
+#define regAFMT1_AFMT_RAMP_CONTROL2 0x217d
+#define regAFMT1_AFMT_RAMP_CONTROL2_BASE_IDX 2
+#define regAFMT1_AFMT_RAMP_CONTROL3 0x217e
+#define regAFMT1_AFMT_RAMP_CONTROL3_BASE_IDX 2
+#define regAFMT1_AFMT_60958_2 0x217f
+#define regAFMT1_AFMT_60958_2_BASE_IDX 2
+#define regAFMT1_AFMT_AUDIO_CRC_RESULT 0x2180
+#define regAFMT1_AFMT_AUDIO_CRC_RESULT_BASE_IDX 2
+#define regAFMT1_AFMT_STATUS 0x2181
+#define regAFMT1_AFMT_STATUS_BASE_IDX 2
+#define regAFMT1_AFMT_AUDIO_PACKET_CONTROL 0x2182
+#define regAFMT1_AFMT_AUDIO_PACKET_CONTROL_BASE_IDX 2
+#define regAFMT1_AFMT_INFOFRAME_CONTROL0 0x2183
+#define regAFMT1_AFMT_INFOFRAME_CONTROL0_BASE_IDX 2
+#define regAFMT1_AFMT_AUDIO_SRC_CONTROL 0x2185
+#define regAFMT1_AFMT_AUDIO_SRC_CONTROL_BASE_IDX 2
+#define regAFMT1_AFMT_MEM_PWR 0x2187
+#define regAFMT1_AFMT_MEM_PWR_BASE_IDX 2
+
+
+// addressBlock: dce_dc_dio_dig2_afmt_afmt_dispdec
+// base address: 0x15ccc
+#define regAFMT2_AFMT_VBI_PACKET_CONTROL 0x2274
+#define regAFMT2_AFMT_VBI_PACKET_CONTROL_BASE_IDX 2
+#define regAFMT2_AFMT_AUDIO_PACKET_CONTROL2 0x2275
+#define regAFMT2_AFMT_AUDIO_PACKET_CONTROL2_BASE_IDX 2
+#define regAFMT2_AFMT_AUDIO_INFO0 0x2276
+#define regAFMT2_AFMT_AUDIO_INFO0_BASE_IDX 2
+#define regAFMT2_AFMT_AUDIO_INFO1 0x2277
+#define regAFMT2_AFMT_AUDIO_INFO1_BASE_IDX 2
+#define regAFMT2_AFMT_60958_0 0x2278
+#define regAFMT2_AFMT_60958_0_BASE_IDX 2
+#define regAFMT2_AFMT_60958_1 0x2279
+#define regAFMT2_AFMT_60958_1_BASE_IDX 2
+#define regAFMT2_AFMT_AUDIO_CRC_CONTROL 0x227a
+#define regAFMT2_AFMT_AUDIO_CRC_CONTROL_BASE_IDX 2
+#define regAFMT2_AFMT_RAMP_CONTROL0 0x227b
+#define regAFMT2_AFMT_RAMP_CONTROL0_BASE_IDX 2
+#define regAFMT2_AFMT_RAMP_CONTROL1 0x227c
+#define regAFMT2_AFMT_RAMP_CONTROL1_BASE_IDX 2
+#define regAFMT2_AFMT_RAMP_CONTROL2 0x227d
+#define regAFMT2_AFMT_RAMP_CONTROL2_BASE_IDX 2
+#define regAFMT2_AFMT_RAMP_CONTROL3 0x227e
+#define regAFMT2_AFMT_RAMP_CONTROL3_BASE_IDX 2
+#define regAFMT2_AFMT_60958_2 0x227f
+#define regAFMT2_AFMT_60958_2_BASE_IDX 2
+#define regAFMT2_AFMT_AUDIO_CRC_RESULT 0x2280
+#define regAFMT2_AFMT_AUDIO_CRC_RESULT_BASE_IDX 2
+#define regAFMT2_AFMT_STATUS 0x2281
+#define regAFMT2_AFMT_STATUS_BASE_IDX 2
+#define regAFMT2_AFMT_AUDIO_PACKET_CONTROL 0x2282
+#define regAFMT2_AFMT_AUDIO_PACKET_CONTROL_BASE_IDX 2
+#define regAFMT2_AFMT_INFOFRAME_CONTROL0 0x2283
+#define regAFMT2_AFMT_INFOFRAME_CONTROL0_BASE_IDX 2
+#define regAFMT2_AFMT_AUDIO_SRC_CONTROL 0x2285
+#define regAFMT2_AFMT_AUDIO_SRC_CONTROL_BASE_IDX 2
+#define regAFMT2_AFMT_MEM_PWR 0x2287
+#define regAFMT2_AFMT_MEM_PWR_BASE_IDX 2
+
+
+// addressBlock: dce_dc_dio_dig3_afmt_afmt_dispdec
+// base address: 0x160cc
+#define regAFMT3_AFMT_VBI_PACKET_CONTROL 0x2374
+#define regAFMT3_AFMT_VBI_PACKET_CONTROL_BASE_IDX 2
+#define regAFMT3_AFMT_AUDIO_PACKET_CONTROL2 0x2375
+#define regAFMT3_AFMT_AUDIO_PACKET_CONTROL2_BASE_IDX 2
+#define regAFMT3_AFMT_AUDIO_INFO0 0x2376
+#define regAFMT3_AFMT_AUDIO_INFO0_BASE_IDX 2
+#define regAFMT3_AFMT_AUDIO_INFO1 0x2377
+#define regAFMT3_AFMT_AUDIO_INFO1_BASE_IDX 2
+#define regAFMT3_AFMT_60958_0 0x2378
+#define regAFMT3_AFMT_60958_0_BASE_IDX 2
+#define regAFMT3_AFMT_60958_1 0x2379
+#define regAFMT3_AFMT_60958_1_BASE_IDX 2
+#define regAFMT3_AFMT_AUDIO_CRC_CONTROL 0x237a
+#define regAFMT3_AFMT_AUDIO_CRC_CONTROL_BASE_IDX 2
+#define regAFMT3_AFMT_RAMP_CONTROL0 0x237b
+#define regAFMT3_AFMT_RAMP_CONTROL0_BASE_IDX 2
+#define regAFMT3_AFMT_RAMP_CONTROL1 0x237c
+#define regAFMT3_AFMT_RAMP_CONTROL1_BASE_IDX 2
+#define regAFMT3_AFMT_RAMP_CONTROL2 0x237d
+#define regAFMT3_AFMT_RAMP_CONTROL2_BASE_IDX 2
+#define regAFMT3_AFMT_RAMP_CONTROL3 0x237e
+#define regAFMT3_AFMT_RAMP_CONTROL3_BASE_IDX 2
+#define regAFMT3_AFMT_60958_2 0x237f
+#define regAFMT3_AFMT_60958_2_BASE_IDX 2
+#define regAFMT3_AFMT_AUDIO_CRC_RESULT 0x2380
+#define regAFMT3_AFMT_AUDIO_CRC_RESULT_BASE_IDX 2
+#define regAFMT3_AFMT_STATUS 0x2381
+#define regAFMT3_AFMT_STATUS_BASE_IDX 2
+#define regAFMT3_AFMT_AUDIO_PACKET_CONTROL 0x2382
+#define regAFMT3_AFMT_AUDIO_PACKET_CONTROL_BASE_IDX 2
+#define regAFMT3_AFMT_INFOFRAME_CONTROL0 0x2383
+#define regAFMT3_AFMT_INFOFRAME_CONTROL0_BASE_IDX 2
+#define regAFMT3_AFMT_AUDIO_SRC_CONTROL 0x2385
+#define regAFMT3_AFMT_AUDIO_SRC_CONTROL_BASE_IDX 2
+#define regAFMT3_AFMT_MEM_PWR 0x2387
+#define regAFMT3_AFMT_MEM_PWR_BASE_IDX 2
+
+
+// addressBlock: dce_dc_dio_dig4_afmt_afmt_dispdec
+// base address: 0x164cc
+#define regAFMT4_AFMT_VBI_PACKET_CONTROL 0x2474
+#define regAFMT4_AFMT_VBI_PACKET_CONTROL_BASE_IDX 2
+#define regAFMT4_AFMT_AUDIO_PACKET_CONTROL2 0x2475
+#define regAFMT4_AFMT_AUDIO_PACKET_CONTROL2_BASE_IDX 2
+#define regAFMT4_AFMT_AUDIO_INFO0 0x2476
+#define regAFMT4_AFMT_AUDIO_INFO0_BASE_IDX 2
+#define regAFMT4_AFMT_AUDIO_INFO1 0x2477
+#define regAFMT4_AFMT_AUDIO_INFO1_BASE_IDX 2
+#define regAFMT4_AFMT_60958_0 0x2478
+#define regAFMT4_AFMT_60958_0_BASE_IDX 2
+#define regAFMT4_AFMT_60958_1 0x2479
+#define regAFMT4_AFMT_60958_1_BASE_IDX 2
+#define regAFMT4_AFMT_AUDIO_CRC_CONTROL 0x247a
+#define regAFMT4_AFMT_AUDIO_CRC_CONTROL_BASE_IDX 2
+#define regAFMT4_AFMT_RAMP_CONTROL0 0x247b
+#define regAFMT4_AFMT_RAMP_CONTROL0_BASE_IDX 2
+#define regAFMT4_AFMT_RAMP_CONTROL1 0x247c
+#define regAFMT4_AFMT_RAMP_CONTROL1_BASE_IDX 2
+#define regAFMT4_AFMT_RAMP_CONTROL2 0x247d
+#define regAFMT4_AFMT_RAMP_CONTROL2_BASE_IDX 2
+#define regAFMT4_AFMT_RAMP_CONTROL3 0x247e
+#define regAFMT4_AFMT_RAMP_CONTROL3_BASE_IDX 2
+#define regAFMT4_AFMT_60958_2 0x247f
+#define regAFMT4_AFMT_60958_2_BASE_IDX 2
+#define regAFMT4_AFMT_AUDIO_CRC_RESULT 0x2480
+#define regAFMT4_AFMT_AUDIO_CRC_RESULT_BASE_IDX 2
+#define regAFMT4_AFMT_STATUS 0x2481
+#define regAFMT4_AFMT_STATUS_BASE_IDX 2
+#define regAFMT4_AFMT_AUDIO_PACKET_CONTROL 0x2482
+#define regAFMT4_AFMT_AUDIO_PACKET_CONTROL_BASE_IDX 2
+#define regAFMT4_AFMT_INFOFRAME_CONTROL0 0x2483
+#define regAFMT4_AFMT_INFOFRAME_CONTROL0_BASE_IDX 2
+#define regAFMT4_AFMT_AUDIO_SRC_CONTROL 0x2485
+#define regAFMT4_AFMT_AUDIO_SRC_CONTROL_BASE_IDX 2
+#define regAFMT4_AFMT_MEM_PWR 0x2487
+#define regAFMT4_AFMT_MEM_PWR_BASE_IDX 2
+
+
+// addressBlock: dce_dc_dio_dig0_dme_dme_dispdec
+// base address: 0x15524
+#define regDME0_DME_CONTROL 0x2089
+#define regDME0_DME_CONTROL_BASE_IDX 2
+#define regDME0_DME_MEMORY_CONTROL 0x208a
+#define regDME0_DME_MEMORY_CONTROL_BASE_IDX 2
+
+
+// addressBlock: dce_dc_dio_dig0_vpg_vpg_dispdec
+// base address: 0x154a0
+#define regVPG0_VPG_GENERIC_PACKET_ACCESS_CTRL 0x2068
+#define regVPG0_VPG_GENERIC_PACKET_ACCESS_CTRL_BASE_IDX 2
+#define regVPG0_VPG_GENERIC_PACKET_DATA 0x2069
+#define regVPG0_VPG_GENERIC_PACKET_DATA_BASE_IDX 2
+#define regVPG0_VPG_GSP_FRAME_UPDATE_CTRL 0x206a
+#define regVPG0_VPG_GSP_FRAME_UPDATE_CTRL_BASE_IDX 2
+#define regVPG0_VPG_GSP_IMMEDIATE_UPDATE_CTRL 0x206b
+#define regVPG0_VPG_GSP_IMMEDIATE_UPDATE_CTRL_BASE_IDX 2
+#define regVPG0_VPG_GENERIC_STATUS 0x206c
+#define regVPG0_VPG_GENERIC_STATUS_BASE_IDX 2
+#define regVPG0_VPG_MEM_PWR 0x206d
+#define regVPG0_VPG_MEM_PWR_BASE_IDX 2
+#define regVPG0_VPG_ISRC1_2_ACCESS_CTRL 0x206e
+#define regVPG0_VPG_ISRC1_2_ACCESS_CTRL_BASE_IDX 2
+#define regVPG0_VPG_ISRC1_2_DATA 0x206f
+#define regVPG0_VPG_ISRC1_2_DATA_BASE_IDX 2
+#define regVPG0_VPG_MPEG_INFO0 0x2070
+#define regVPG0_VPG_MPEG_INFO0_BASE_IDX 2
+#define regVPG0_VPG_MPEG_INFO1 0x2071
+#define regVPG0_VPG_MPEG_INFO1_BASE_IDX 2
+
+
+// addressBlock: dce_dc_dio_dig1_dme_dme_dispdec
+// base address: 0x15924
+#define regDME1_DME_CONTROL 0x2189
+#define regDME1_DME_CONTROL_BASE_IDX 2
+#define regDME1_DME_MEMORY_CONTROL 0x218a
+#define regDME1_DME_MEMORY_CONTROL_BASE_IDX 2
+
+
+// addressBlock: dce_dc_dio_dig1_vpg_vpg_dispdec
+// base address: 0x158a0
+#define regVPG1_VPG_GENERIC_PACKET_ACCESS_CTRL 0x2168
+#define regVPG1_VPG_GENERIC_PACKET_ACCESS_CTRL_BASE_IDX 2
+#define regVPG1_VPG_GENERIC_PACKET_DATA 0x2169
+#define regVPG1_VPG_GENERIC_PACKET_DATA_BASE_IDX 2
+#define regVPG1_VPG_GSP_FRAME_UPDATE_CTRL 0x216a
+#define regVPG1_VPG_GSP_FRAME_UPDATE_CTRL_BASE_IDX 2
+#define regVPG1_VPG_GSP_IMMEDIATE_UPDATE_CTRL 0x216b
+#define regVPG1_VPG_GSP_IMMEDIATE_UPDATE_CTRL_BASE_IDX 2
+#define regVPG1_VPG_GENERIC_STATUS 0x216c
+#define regVPG1_VPG_GENERIC_STATUS_BASE_IDX 2
+#define regVPG1_VPG_MEM_PWR 0x216d
+#define regVPG1_VPG_MEM_PWR_BASE_IDX 2
+#define regVPG1_VPG_ISRC1_2_ACCESS_CTRL 0x216e
+#define regVPG1_VPG_ISRC1_2_ACCESS_CTRL_BASE_IDX 2
+#define regVPG1_VPG_ISRC1_2_DATA 0x216f
+#define regVPG1_VPG_ISRC1_2_DATA_BASE_IDX 2
+#define regVPG1_VPG_MPEG_INFO0 0x2170
+#define regVPG1_VPG_MPEG_INFO0_BASE_IDX 2
+#define regVPG1_VPG_MPEG_INFO1 0x2171
+#define regVPG1_VPG_MPEG_INFO1_BASE_IDX 2
+
+
+// addressBlock: dce_dc_dio_dig2_dme_dme_dispdec
+// base address: 0x15d24
+#define regDME2_DME_CONTROL 0x2289
+#define regDME2_DME_CONTROL_BASE_IDX 2
+#define regDME2_DME_MEMORY_CONTROL 0x228a
+#define regDME2_DME_MEMORY_CONTROL_BASE_IDX 2
+
+
+// addressBlock: dce_dc_dio_dig2_vpg_vpg_dispdec
+// base address: 0x15ca0
+#define regVPG2_VPG_GENERIC_PACKET_ACCESS_CTRL 0x2268
+#define regVPG2_VPG_GENERIC_PACKET_ACCESS_CTRL_BASE_IDX 2
+#define regVPG2_VPG_GENERIC_PACKET_DATA 0x2269
+#define regVPG2_VPG_GENERIC_PACKET_DATA_BASE_IDX 2
+#define regVPG2_VPG_GSP_FRAME_UPDATE_CTRL 0x226a
+#define regVPG2_VPG_GSP_FRAME_UPDATE_CTRL_BASE_IDX 2
+#define regVPG2_VPG_GSP_IMMEDIATE_UPDATE_CTRL 0x226b
+#define regVPG2_VPG_GSP_IMMEDIATE_UPDATE_CTRL_BASE_IDX 2
+#define regVPG2_VPG_GENERIC_STATUS 0x226c
+#define regVPG2_VPG_GENERIC_STATUS_BASE_IDX 2
+#define regVPG2_VPG_MEM_PWR 0x226d
+#define regVPG2_VPG_MEM_PWR_BASE_IDX 2
+#define regVPG2_VPG_ISRC1_2_ACCESS_CTRL 0x226e
+#define regVPG2_VPG_ISRC1_2_ACCESS_CTRL_BASE_IDX 2
+#define regVPG2_VPG_ISRC1_2_DATA 0x226f
+#define regVPG2_VPG_ISRC1_2_DATA_BASE_IDX 2
+#define regVPG2_VPG_MPEG_INFO0 0x2270
+#define regVPG2_VPG_MPEG_INFO0_BASE_IDX 2
+#define regVPG2_VPG_MPEG_INFO1 0x2271
+#define regVPG2_VPG_MPEG_INFO1_BASE_IDX 2
+
+
+// addressBlock: dce_dc_dio_dig3_dme_dme_dispdec
+// base address: 0x16124
+#define regDME3_DME_CONTROL 0x2389
+#define regDME3_DME_CONTROL_BASE_IDX 2
+#define regDME3_DME_MEMORY_CONTROL 0x238a
+#define regDME3_DME_MEMORY_CONTROL_BASE_IDX 2
+
+
+// addressBlock: dce_dc_dio_dig3_vpg_vpg_dispdec
+// base address: 0x160a0
+#define regVPG3_VPG_GENERIC_PACKET_ACCESS_CTRL 0x2368
+#define regVPG3_VPG_GENERIC_PACKET_ACCESS_CTRL_BASE_IDX 2
+#define regVPG3_VPG_GENERIC_PACKET_DATA 0x2369
+#define regVPG3_VPG_GENERIC_PACKET_DATA_BASE_IDX 2
+#define regVPG3_VPG_GSP_FRAME_UPDATE_CTRL 0x236a
+#define regVPG3_VPG_GSP_FRAME_UPDATE_CTRL_BASE_IDX 2
+#define regVPG3_VPG_GSP_IMMEDIATE_UPDATE_CTRL 0x236b
+#define regVPG3_VPG_GSP_IMMEDIATE_UPDATE_CTRL_BASE_IDX 2
+#define regVPG3_VPG_GENERIC_STATUS 0x236c
+#define regVPG3_VPG_GENERIC_STATUS_BASE_IDX 2
+#define regVPG3_VPG_MEM_PWR 0x236d
+#define regVPG3_VPG_MEM_PWR_BASE_IDX 2
+#define regVPG3_VPG_ISRC1_2_ACCESS_CTRL 0x236e
+#define regVPG3_VPG_ISRC1_2_ACCESS_CTRL_BASE_IDX 2
+#define regVPG3_VPG_ISRC1_2_DATA 0x236f
+#define regVPG3_VPG_ISRC1_2_DATA_BASE_IDX 2
+#define regVPG3_VPG_MPEG_INFO0 0x2370
+#define regVPG3_VPG_MPEG_INFO0_BASE_IDX 2
+#define regVPG3_VPG_MPEG_INFO1 0x2371
+#define regVPG3_VPG_MPEG_INFO1_BASE_IDX 2
+
+
+// addressBlock: dce_dc_dio_dig4_dme_dme_dispdec
+// base address: 0x16524
+#define regDME4_DME_CONTROL 0x2489
+#define regDME4_DME_CONTROL_BASE_IDX 2
+#define regDME4_DME_MEMORY_CONTROL 0x248a
+#define regDME4_DME_MEMORY_CONTROL_BASE_IDX 2
+
+
+// addressBlock: dce_dc_dio_dig4_vpg_vpg_dispdec
+// base address: 0x164a0
+#define regVPG4_VPG_GENERIC_PACKET_ACCESS_CTRL 0x2468
+#define regVPG4_VPG_GENERIC_PACKET_ACCESS_CTRL_BASE_IDX 2
+#define regVPG4_VPG_GENERIC_PACKET_DATA 0x2469
+#define regVPG4_VPG_GENERIC_PACKET_DATA_BASE_IDX 2
+#define regVPG4_VPG_GSP_FRAME_UPDATE_CTRL 0x246a
+#define regVPG4_VPG_GSP_FRAME_UPDATE_CTRL_BASE_IDX 2
+#define regVPG4_VPG_GSP_IMMEDIATE_UPDATE_CTRL 0x246b
+#define regVPG4_VPG_GSP_IMMEDIATE_UPDATE_CTRL_BASE_IDX 2
+#define regVPG4_VPG_GENERIC_STATUS 0x246c
+#define regVPG4_VPG_GENERIC_STATUS_BASE_IDX 2
+#define regVPG4_VPG_MEM_PWR 0x246d
+#define regVPG4_VPG_MEM_PWR_BASE_IDX 2
+#define regVPG4_VPG_ISRC1_2_ACCESS_CTRL 0x246e
+#define regVPG4_VPG_ISRC1_2_ACCESS_CTRL_BASE_IDX 2
+#define regVPG4_VPG_ISRC1_2_DATA 0x246f
+#define regVPG4_VPG_ISRC1_2_DATA_BASE_IDX 2
+#define regVPG4_VPG_MPEG_INFO0 0x2470
+#define regVPG4_VPG_MPEG_INFO0_BASE_IDX 2
+#define regVPG4_VPG_MPEG_INFO1 0x2471
+#define regVPG4_VPG_MPEG_INFO1_BASE_IDX 2
+
+
+// addressBlock: dce_dc_dio_dp_aux0_dispdec
+// base address: 0x0
+#define regDP_AUX0_AUX_CONTROL 0x1f50
+#define regDP_AUX0_AUX_CONTROL_BASE_IDX 2
+#define regDP_AUX0_AUX_SW_CONTROL 0x1f51
+#define regDP_AUX0_AUX_SW_CONTROL_BASE_IDX 2
+#define regDP_AUX0_AUX_ARB_CONTROL 0x1f52
+#define regDP_AUX0_AUX_ARB_CONTROL_BASE_IDX 2
+#define regDP_AUX0_AUX_INTERRUPT_CONTROL 0x1f53
+#define regDP_AUX0_AUX_INTERRUPT_CONTROL_BASE_IDX 2
+#define regDP_AUX0_AUX_SW_STATUS 0x1f54
+#define regDP_AUX0_AUX_SW_STATUS_BASE_IDX 2
+#define regDP_AUX0_AUX_LS_STATUS 0x1f55
+#define regDP_AUX0_AUX_LS_STATUS_BASE_IDX 2
+#define regDP_AUX0_AUX_SW_DATA 0x1f56
+#define regDP_AUX0_AUX_SW_DATA_BASE_IDX 2
+#define regDP_AUX0_AUX_LS_DATA 0x1f57
+#define regDP_AUX0_AUX_LS_DATA_BASE_IDX 2
+#define regDP_AUX0_AUX_DPHY_TX_REF_CONTROL 0x1f58
+#define regDP_AUX0_AUX_DPHY_TX_REF_CONTROL_BASE_IDX 2
+#define regDP_AUX0_AUX_DPHY_TX_CONTROL 0x1f59
+#define regDP_AUX0_AUX_DPHY_TX_CONTROL_BASE_IDX 2
+#define regDP_AUX0_AUX_DPHY_RX_CONTROL0 0x1f5a
+#define regDP_AUX0_AUX_DPHY_RX_CONTROL0_BASE_IDX 2
+#define regDP_AUX0_AUX_DPHY_RX_CONTROL1 0x1f5b
+#define regDP_AUX0_AUX_DPHY_RX_CONTROL1_BASE_IDX 2
+#define regDP_AUX0_AUX_DPHY_TX_STATUS 0x1f5c
+#define regDP_AUX0_AUX_DPHY_TX_STATUS_BASE_IDX 2
+#define regDP_AUX0_AUX_DPHY_RX_STATUS 0x1f5d
+#define regDP_AUX0_AUX_DPHY_RX_STATUS_BASE_IDX 2
+#define regDP_AUX0_AUX_GTC_SYNC_CONTROL 0x1f5e
+#define regDP_AUX0_AUX_GTC_SYNC_CONTROL_BASE_IDX 2
+#define regDP_AUX0_AUX_GTC_SYNC_ERROR_CONTROL 0x1f5f
+#define regDP_AUX0_AUX_GTC_SYNC_ERROR_CONTROL_BASE_IDX 2
+#define regDP_AUX0_AUX_GTC_SYNC_CONTROLLER_STATUS 0x1f60
+#define regDP_AUX0_AUX_GTC_SYNC_CONTROLLER_STATUS_BASE_IDX 2
+#define regDP_AUX0_AUX_GTC_SYNC_STATUS 0x1f61
+#define regDP_AUX0_AUX_GTC_SYNC_STATUS_BASE_IDX 2
+#define regDP_AUX0_AUX_PHY_WAKE_CNTL 0x1f66
+#define regDP_AUX0_AUX_PHY_WAKE_CNTL_BASE_IDX 2
+
+
+// addressBlock: dce_dc_dio_dp_aux1_dispdec
+// base address: 0x70
+#define regDP_AUX1_AUX_CONTROL 0x1f6c
+#define regDP_AUX1_AUX_CONTROL_BASE_IDX 2
+#define regDP_AUX1_AUX_SW_CONTROL 0x1f6d
+#define regDP_AUX1_AUX_SW_CONTROL_BASE_IDX 2
+#define regDP_AUX1_AUX_ARB_CONTROL 0x1f6e
+#define regDP_AUX1_AUX_ARB_CONTROL_BASE_IDX 2
+#define regDP_AUX1_AUX_INTERRUPT_CONTROL 0x1f6f
+#define regDP_AUX1_AUX_INTERRUPT_CONTROL_BASE_IDX 2
+#define regDP_AUX1_AUX_SW_STATUS 0x1f70
+#define regDP_AUX1_AUX_SW_STATUS_BASE_IDX 2
+#define regDP_AUX1_AUX_LS_STATUS 0x1f71
+#define regDP_AUX1_AUX_LS_STATUS_BASE_IDX 2
+#define regDP_AUX1_AUX_SW_DATA 0x1f72
+#define regDP_AUX1_AUX_SW_DATA_BASE_IDX 2
+#define regDP_AUX1_AUX_LS_DATA 0x1f73
+#define regDP_AUX1_AUX_LS_DATA_BASE_IDX 2
+#define regDP_AUX1_AUX_DPHY_TX_REF_CONTROL 0x1f74
+#define regDP_AUX1_AUX_DPHY_TX_REF_CONTROL_BASE_IDX 2
+#define regDP_AUX1_AUX_DPHY_TX_CONTROL 0x1f75
+#define regDP_AUX1_AUX_DPHY_TX_CONTROL_BASE_IDX 2
+#define regDP_AUX1_AUX_DPHY_RX_CONTROL0 0x1f76
+#define regDP_AUX1_AUX_DPHY_RX_CONTROL0_BASE_IDX 2
+#define regDP_AUX1_AUX_DPHY_RX_CONTROL1 0x1f77
+#define regDP_AUX1_AUX_DPHY_RX_CONTROL1_BASE_IDX 2
+#define regDP_AUX1_AUX_DPHY_TX_STATUS 0x1f78
+#define regDP_AUX1_AUX_DPHY_TX_STATUS_BASE_IDX 2
+#define regDP_AUX1_AUX_DPHY_RX_STATUS 0x1f79
+#define regDP_AUX1_AUX_DPHY_RX_STATUS_BASE_IDX 2
+#define regDP_AUX1_AUX_GTC_SYNC_CONTROL 0x1f7a
+#define regDP_AUX1_AUX_GTC_SYNC_CONTROL_BASE_IDX 2
+#define regDP_AUX1_AUX_GTC_SYNC_ERROR_CONTROL 0x1f7b
+#define regDP_AUX1_AUX_GTC_SYNC_ERROR_CONTROL_BASE_IDX 2
+#define regDP_AUX1_AUX_GTC_SYNC_CONTROLLER_STATUS 0x1f7c
+#define regDP_AUX1_AUX_GTC_SYNC_CONTROLLER_STATUS_BASE_IDX 2
+#define regDP_AUX1_AUX_GTC_SYNC_STATUS 0x1f7d
+#define regDP_AUX1_AUX_GTC_SYNC_STATUS_BASE_IDX 2
+#define regDP_AUX1_AUX_PHY_WAKE_CNTL 0x1f82
+#define regDP_AUX1_AUX_PHY_WAKE_CNTL_BASE_IDX 2
+
+
+// addressBlock: dce_dc_dio_dp_aux2_dispdec
+// base address: 0xe0
+#define regDP_AUX2_AUX_CONTROL 0x1f88
+#define regDP_AUX2_AUX_CONTROL_BASE_IDX 2
+#define regDP_AUX2_AUX_SW_CONTROL 0x1f89
+#define regDP_AUX2_AUX_SW_CONTROL_BASE_IDX 2
+#define regDP_AUX2_AUX_ARB_CONTROL 0x1f8a
+#define regDP_AUX2_AUX_ARB_CONTROL_BASE_IDX 2
+#define regDP_AUX2_AUX_INTERRUPT_CONTROL 0x1f8b
+#define regDP_AUX2_AUX_INTERRUPT_CONTROL_BASE_IDX 2
+#define regDP_AUX2_AUX_SW_STATUS 0x1f8c
+#define regDP_AUX2_AUX_SW_STATUS_BASE_IDX 2
+#define regDP_AUX2_AUX_LS_STATUS 0x1f8d
+#define regDP_AUX2_AUX_LS_STATUS_BASE_IDX 2
+#define regDP_AUX2_AUX_SW_DATA 0x1f8e
+#define regDP_AUX2_AUX_SW_DATA_BASE_IDX 2
+#define regDP_AUX2_AUX_LS_DATA 0x1f8f
+#define regDP_AUX2_AUX_LS_DATA_BASE_IDX 2
+#define regDP_AUX2_AUX_DPHY_TX_REF_CONTROL 0x1f90
+#define regDP_AUX2_AUX_DPHY_TX_REF_CONTROL_BASE_IDX 2
+#define regDP_AUX2_AUX_DPHY_TX_CONTROL 0x1f91
+#define regDP_AUX2_AUX_DPHY_TX_CONTROL_BASE_IDX 2
+#define regDP_AUX2_AUX_DPHY_RX_CONTROL0 0x1f92
+#define regDP_AUX2_AUX_DPHY_RX_CONTROL0_BASE_IDX 2
+#define regDP_AUX2_AUX_DPHY_RX_CONTROL1 0x1f93
+#define regDP_AUX2_AUX_DPHY_RX_CONTROL1_BASE_IDX 2
+#define regDP_AUX2_AUX_DPHY_TX_STATUS 0x1f94
+#define regDP_AUX2_AUX_DPHY_TX_STATUS_BASE_IDX 2
+#define regDP_AUX2_AUX_DPHY_RX_STATUS 0x1f95
+#define regDP_AUX2_AUX_DPHY_RX_STATUS_BASE_IDX 2
+#define regDP_AUX2_AUX_GTC_SYNC_CONTROL 0x1f96
+#define regDP_AUX2_AUX_GTC_SYNC_CONTROL_BASE_IDX 2
+#define regDP_AUX2_AUX_GTC_SYNC_ERROR_CONTROL 0x1f97
+#define regDP_AUX2_AUX_GTC_SYNC_ERROR_CONTROL_BASE_IDX 2
+#define regDP_AUX2_AUX_GTC_SYNC_CONTROLLER_STATUS 0x1f98
+#define regDP_AUX2_AUX_GTC_SYNC_CONTROLLER_STATUS_BASE_IDX 2
+#define regDP_AUX2_AUX_GTC_SYNC_STATUS 0x1f99
+#define regDP_AUX2_AUX_GTC_SYNC_STATUS_BASE_IDX 2
+#define regDP_AUX2_AUX_PHY_WAKE_CNTL 0x1f9e
+#define regDP_AUX2_AUX_PHY_WAKE_CNTL_BASE_IDX 2
+
+
+// addressBlock: dce_dc_dio_dp_aux3_dispdec
+// base address: 0x150
+#define regDP_AUX3_AUX_CONTROL 0x1fa4
+#define regDP_AUX3_AUX_CONTROL_BASE_IDX 2
+#define regDP_AUX3_AUX_SW_CONTROL 0x1fa5
+#define regDP_AUX3_AUX_SW_CONTROL_BASE_IDX 2
+#define regDP_AUX3_AUX_ARB_CONTROL 0x1fa6
+#define regDP_AUX3_AUX_ARB_CONTROL_BASE_IDX 2
+#define regDP_AUX3_AUX_INTERRUPT_CONTROL 0x1fa7
+#define regDP_AUX3_AUX_INTERRUPT_CONTROL_BASE_IDX 2
+#define regDP_AUX3_AUX_SW_STATUS 0x1fa8
+#define regDP_AUX3_AUX_SW_STATUS_BASE_IDX 2
+#define regDP_AUX3_AUX_LS_STATUS 0x1fa9
+#define regDP_AUX3_AUX_LS_STATUS_BASE_IDX 2
+#define regDP_AUX3_AUX_SW_DATA 0x1faa
+#define regDP_AUX3_AUX_SW_DATA_BASE_IDX 2
+#define regDP_AUX3_AUX_LS_DATA 0x1fab
+#define regDP_AUX3_AUX_LS_DATA_BASE_IDX 2
+#define regDP_AUX3_AUX_DPHY_TX_REF_CONTROL 0x1fac
+#define regDP_AUX3_AUX_DPHY_TX_REF_CONTROL_BASE_IDX 2
+#define regDP_AUX3_AUX_DPHY_TX_CONTROL 0x1fad
+#define regDP_AUX3_AUX_DPHY_TX_CONTROL_BASE_IDX 2
+#define regDP_AUX3_AUX_DPHY_RX_CONTROL0 0x1fae
+#define regDP_AUX3_AUX_DPHY_RX_CONTROL0_BASE_IDX 2
+#define regDP_AUX3_AUX_DPHY_RX_CONTROL1 0x1faf
+#define regDP_AUX3_AUX_DPHY_RX_CONTROL1_BASE_IDX 2
+#define regDP_AUX3_AUX_DPHY_TX_STATUS 0x1fb0
+#define regDP_AUX3_AUX_DPHY_TX_STATUS_BASE_IDX 2
+#define regDP_AUX3_AUX_DPHY_RX_STATUS 0x1fb1
+#define regDP_AUX3_AUX_DPHY_RX_STATUS_BASE_IDX 2
+#define regDP_AUX3_AUX_GTC_SYNC_CONTROL 0x1fb2
+#define regDP_AUX3_AUX_GTC_SYNC_CONTROL_BASE_IDX 2
+#define regDP_AUX3_AUX_GTC_SYNC_ERROR_CONTROL 0x1fb3
+#define regDP_AUX3_AUX_GTC_SYNC_ERROR_CONTROL_BASE_IDX 2
+#define regDP_AUX3_AUX_GTC_SYNC_CONTROLLER_STATUS 0x1fb4
+#define regDP_AUX3_AUX_GTC_SYNC_CONTROLLER_STATUS_BASE_IDX 2
+#define regDP_AUX3_AUX_GTC_SYNC_STATUS 0x1fb5
+#define regDP_AUX3_AUX_GTC_SYNC_STATUS_BASE_IDX 2
+#define regDP_AUX3_AUX_PHY_WAKE_CNTL 0x1fba
+#define regDP_AUX3_AUX_PHY_WAKE_CNTL_BASE_IDX 2
+
+
+// addressBlock: dce_dc_dio_dp_aux4_dispdec
+// base address: 0x1c0
+#define regDP_AUX4_AUX_CONTROL 0x1fc0
+#define regDP_AUX4_AUX_CONTROL_BASE_IDX 2
+#define regDP_AUX4_AUX_SW_CONTROL 0x1fc1
+#define regDP_AUX4_AUX_SW_CONTROL_BASE_IDX 2
+#define regDP_AUX4_AUX_ARB_CONTROL 0x1fc2
+#define regDP_AUX4_AUX_ARB_CONTROL_BASE_IDX 2
+#define regDP_AUX4_AUX_INTERRUPT_CONTROL 0x1fc3
+#define regDP_AUX4_AUX_INTERRUPT_CONTROL_BASE_IDX 2
+#define regDP_AUX4_AUX_SW_STATUS 0x1fc4
+#define regDP_AUX4_AUX_SW_STATUS_BASE_IDX 2
+#define regDP_AUX4_AUX_LS_STATUS 0x1fc5
+#define regDP_AUX4_AUX_LS_STATUS_BASE_IDX 2
+#define regDP_AUX4_AUX_SW_DATA 0x1fc6
+#define regDP_AUX4_AUX_SW_DATA_BASE_IDX 2
+#define regDP_AUX4_AUX_LS_DATA 0x1fc7
+#define regDP_AUX4_AUX_LS_DATA_BASE_IDX 2
+#define regDP_AUX4_AUX_DPHY_TX_REF_CONTROL 0x1fc8
+#define regDP_AUX4_AUX_DPHY_TX_REF_CONTROL_BASE_IDX 2
+#define regDP_AUX4_AUX_DPHY_TX_CONTROL 0x1fc9
+#define regDP_AUX4_AUX_DPHY_TX_CONTROL_BASE_IDX 2
+#define regDP_AUX4_AUX_DPHY_RX_CONTROL0 0x1fca
+#define regDP_AUX4_AUX_DPHY_RX_CONTROL0_BASE_IDX 2
+#define regDP_AUX4_AUX_DPHY_RX_CONTROL1 0x1fcb
+#define regDP_AUX4_AUX_DPHY_RX_CONTROL1_BASE_IDX 2
+#define regDP_AUX4_AUX_DPHY_TX_STATUS 0x1fcc
+#define regDP_AUX4_AUX_DPHY_TX_STATUS_BASE_IDX 2
+#define regDP_AUX4_AUX_DPHY_RX_STATUS 0x1fcd
+#define regDP_AUX4_AUX_DPHY_RX_STATUS_BASE_IDX 2
+#define regDP_AUX4_AUX_GTC_SYNC_CONTROL 0x1fce
+#define regDP_AUX4_AUX_GTC_SYNC_CONTROL_BASE_IDX 2
+#define regDP_AUX4_AUX_GTC_SYNC_ERROR_CONTROL 0x1fcf
+#define regDP_AUX4_AUX_GTC_SYNC_ERROR_CONTROL_BASE_IDX 2
+#define regDP_AUX4_AUX_GTC_SYNC_CONTROLLER_STATUS 0x1fd0
+#define regDP_AUX4_AUX_GTC_SYNC_CONTROLLER_STATUS_BASE_IDX 2
+#define regDP_AUX4_AUX_GTC_SYNC_STATUS 0x1fd1
+#define regDP_AUX4_AUX_GTC_SYNC_STATUS_BASE_IDX 2
+#define regDP_AUX4_AUX_PHY_WAKE_CNTL 0x1fd6
+#define regDP_AUX4_AUX_PHY_WAKE_CNTL_BASE_IDX 2
+
+
+// addressBlock: dce_dc_dio_dout_i2c_dispdec
+// base address: 0x0
+#define regDC_I2C_CONTROL 0x1e98
+#define regDC_I2C_CONTROL_BASE_IDX 2
+#define regDC_I2C_ARBITRATION 0x1e99
+#define regDC_I2C_ARBITRATION_BASE_IDX 2
+#define regDC_I2C_SW_STATUS 0x1e9b
+#define regDC_I2C_SW_STATUS_BASE_IDX 2
+#define regDC_I2C_DDC1_HW_STATUS 0x1e9c
+#define regDC_I2C_DDC1_HW_STATUS_BASE_IDX 2
+#define regDC_I2C_DDC2_HW_STATUS 0x1e9d
+#define regDC_I2C_DDC2_HW_STATUS_BASE_IDX 2
+#define regDC_I2C_DDC3_HW_STATUS 0x1e9e
+#define regDC_I2C_DDC3_HW_STATUS_BASE_IDX 2
+#define regDC_I2C_DDC4_HW_STATUS 0x1e9f
+#define regDC_I2C_DDC4_HW_STATUS_BASE_IDX 2
+#define regDC_I2C_DDC5_HW_STATUS 0x1ea0
+#define regDC_I2C_DDC5_HW_STATUS_BASE_IDX 2
+#define regDC_I2C_DDC1_SPEED 0x1ea2
+#define regDC_I2C_DDC1_SPEED_BASE_IDX 2
+#define regDC_I2C_DDC1_SETUP 0x1ea3
+#define regDC_I2C_DDC1_SETUP_BASE_IDX 2
+#define regDC_I2C_DDC2_SPEED 0x1ea4
+#define regDC_I2C_DDC2_SPEED_BASE_IDX 2
+#define regDC_I2C_DDC2_SETUP 0x1ea5
+#define regDC_I2C_DDC2_SETUP_BASE_IDX 2
+#define regDC_I2C_DDC3_SPEED 0x1ea6
+#define regDC_I2C_DDC3_SPEED_BASE_IDX 2
+#define regDC_I2C_DDC3_SETUP 0x1ea7
+#define regDC_I2C_DDC3_SETUP_BASE_IDX 2
+#define regDC_I2C_DDC4_SPEED 0x1ea8
+#define regDC_I2C_DDC4_SPEED_BASE_IDX 2
+#define regDC_I2C_DDC4_SETUP 0x1ea9
+#define regDC_I2C_DDC4_SETUP_BASE_IDX 2
+#define regDC_I2C_DDC5_SPEED 0x1eaa
+#define regDC_I2C_DDC5_SPEED_BASE_IDX 2
+#define regDC_I2C_DDC5_SETUP 0x1eab
+#define regDC_I2C_DDC5_SETUP_BASE_IDX 2
+#define regDC_I2C_TRANSACTION0 0x1eae
+#define regDC_I2C_TRANSACTION0_BASE_IDX 2
+#define regDC_I2C_TRANSACTION1 0x1eaf
+#define regDC_I2C_TRANSACTION1_BASE_IDX 2
+#define regDC_I2C_TRANSACTION2 0x1eb0
+#define regDC_I2C_TRANSACTION2_BASE_IDX 2
+#define regDC_I2C_TRANSACTION3 0x1eb1
+#define regDC_I2C_TRANSACTION3_BASE_IDX 2
+#define regDC_I2C_DATA 0x1eb2
+#define regDC_I2C_DATA_BASE_IDX 2
+#define regDC_I2C_EDID_DETECT_CTRL 0x1eb6
+#define regDC_I2C_EDID_DETECT_CTRL_BASE_IDX 2
+#define regDC_I2C_READ_REQUEST_INTERRUPT 0x1eb7
+#define regDC_I2C_READ_REQUEST_INTERRUPT_BASE_IDX 2
+
+
+// addressBlock: dce_dc_dio_dio_misc_dispdec
+// base address: 0x0
+#define regDIO_SCRATCH0 0x1eca
+#define regDIO_SCRATCH0_BASE_IDX 2
+#define regDIO_SCRATCH1 0x1ecb
+#define regDIO_SCRATCH1_BASE_IDX 2
+#define regDIO_SCRATCH2 0x1ecc
+#define regDIO_SCRATCH2_BASE_IDX 2
+#define regDIO_SCRATCH3 0x1ecd
+#define regDIO_SCRATCH3_BASE_IDX 2
+#define regDIO_SCRATCH4 0x1ece
+#define regDIO_SCRATCH4_BASE_IDX 2
+#define regDIO_SCRATCH5 0x1ecf
+#define regDIO_SCRATCH5_BASE_IDX 2
+#define regDIO_SCRATCH6 0x1ed0
+#define regDIO_SCRATCH6_BASE_IDX 2
+#define regDIO_SCRATCH7 0x1ed1
+#define regDIO_SCRATCH7_BASE_IDX 2
+#define regDIO_MEM_PWR_STATUS 0x1edd
+#define regDIO_MEM_PWR_STATUS_BASE_IDX 2
+#define regDIO_MEM_PWR_CTRL 0x1ede
+#define regDIO_MEM_PWR_CTRL_BASE_IDX 2
+#define regDIO_MEM_PWR_CTRL2 0x1edf
+#define regDIO_MEM_PWR_CTRL2_BASE_IDX 2
+#define regDIO_CLK_CNTL 0x1ee0
+#define regDIO_CLK_CNTL_BASE_IDX 2
+#define regDIO_POWER_MANAGEMENT_CNTL 0x1ee4
+#define regDIO_POWER_MANAGEMENT_CNTL_BASE_IDX 2
+#define regDIG_SOFT_RESET 0x1eee
+#define regDIG_SOFT_RESET_BASE_IDX 2
+#define regDIO_CLK_CNTL2 0x1ef2
+#define regDIO_CLK_CNTL2_BASE_IDX 2
+#define regDIO_CLK_CNTL3 0x1ef3
+#define regDIO_CLK_CNTL3_BASE_IDX 2
+#define regDIO_HDMI_RXSTATUS_TIMER_CONTROL 0x1eff
+#define regDIO_HDMI_RXSTATUS_TIMER_CONTROL_BASE_IDX 2
+#define regDIO_PSP_INTERRUPT_CLEAR 0x1f01
+#define regDIO_PSP_INTERRUPT_CLEAR_BASE_IDX 2
+#define regDIO_GENERIC_INTERRUPT_MESSAGE 0x1f02
+#define regDIO_GENERIC_INTERRUPT_MESSAGE_BASE_IDX 2
+#define regDIO_GENERIC_INTERRUPT_CLEAR 0x1f03
+#define regDIO_GENERIC_INTERRUPT_CLEAR_BASE_IDX 2
+#define regDIO_LINKA_CNTL 0x1f04
+#define regDIO_LINKA_CNTL_BASE_IDX 2
+#define regDIO_LINKB_CNTL 0x1f05
+#define regDIO_LINKB_CNTL_BASE_IDX 2
+#define regDIO_LINKC_CNTL 0x1f06
+#define regDIO_LINKC_CNTL_BASE_IDX 2
+#define regDIO_LINKD_CNTL 0x1f07
+#define regDIO_LINKD_CNTL_BASE_IDX 2
+#define regDIO_LINKE_CNTL 0x1f08
+#define regDIO_LINKE_CNTL_BASE_IDX 2
+#define regDIO_LINKF_CNTL 0x1f09
+#define regDIO_LINKF_CNTL_BASE_IDX 2
+
+
+// addressBlock: dce_dc_dio_dio_dcperfmon_dc_perfmon_dispdec
+// base address: 0x7d10
+#define regDC_PERFMON18_PERFCOUNTER_CNTL 0x1f44
+#define regDC_PERFMON18_PERFCOUNTER_CNTL_BASE_IDX 2
+#define regDC_PERFMON18_PERFCOUNTER_CNTL2 0x1f45
+#define regDC_PERFMON18_PERFCOUNTER_CNTL2_BASE_IDX 2
+#define regDC_PERFMON18_PERFCOUNTER_STATE 0x1f46
+#define regDC_PERFMON18_PERFCOUNTER_STATE_BASE_IDX 2
+#define regDC_PERFMON18_PERFMON_CNTL 0x1f47
+#define regDC_PERFMON18_PERFMON_CNTL_BASE_IDX 2
+#define regDC_PERFMON18_PERFMON_CNTL2 0x1f48
+#define regDC_PERFMON18_PERFMON_CNTL2_BASE_IDX 2
+#define regDC_PERFMON18_PERFMON_CVALUE_INT_MISC 0x1f49
+#define regDC_PERFMON18_PERFMON_CVALUE_INT_MISC_BASE_IDX 2
+#define regDC_PERFMON18_PERFMON_CVALUE_LOW 0x1f4a
+#define regDC_PERFMON18_PERFMON_CVALUE_LOW_BASE_IDX 2
+#define regDC_PERFMON18_PERFMON_HI 0x1f4b
+#define regDC_PERFMON18_PERFMON_HI_BASE_IDX 2
+#define regDC_PERFMON18_PERFMON_LOW 0x1f4c
+#define regDC_PERFMON18_PERFMON_LOW_BASE_IDX 2
+
+
+// addressBlock: dce_dc_dcio_dcio_dispdec
+// base address: 0x0
+#define regDC_GENERICA 0x2868
+#define regDC_GENERICA_BASE_IDX 2
+#define regDC_GENERICB 0x2869
+#define regDC_GENERICB_BASE_IDX 2
+#define regDCIO_CLOCK_CNTL 0x286a
+#define regDCIO_CLOCK_CNTL_BASE_IDX 2
+#define regDC_REF_CLK_CNTL 0x286b
+#define regDC_REF_CLK_CNTL_BASE_IDX 2
+#define regUNIPHYA_LINK_CNTL 0x286d
+#define regUNIPHYA_LINK_CNTL_BASE_IDX 2
+#define regUNIPHYA_CHANNEL_XBAR_CNTL 0x286e
+#define regUNIPHYA_CHANNEL_XBAR_CNTL_BASE_IDX 2
+#define regUNIPHYB_LINK_CNTL 0x286f
+#define regUNIPHYB_LINK_CNTL_BASE_IDX 2
+#define regUNIPHYB_CHANNEL_XBAR_CNTL 0x2870
+#define regUNIPHYB_CHANNEL_XBAR_CNTL_BASE_IDX 2
+#define regUNIPHYC_LINK_CNTL 0x2871
+#define regUNIPHYC_LINK_CNTL_BASE_IDX 2
+#define regUNIPHYC_CHANNEL_XBAR_CNTL 0x2872
+#define regUNIPHYC_CHANNEL_XBAR_CNTL_BASE_IDX 2
+#define regUNIPHYD_LINK_CNTL 0x2873
+#define regUNIPHYD_LINK_CNTL_BASE_IDX 2
+#define regUNIPHYD_CHANNEL_XBAR_CNTL 0x2874
+#define regUNIPHYD_CHANNEL_XBAR_CNTL_BASE_IDX 2
+#define regUNIPHYE_LINK_CNTL 0x2875
+#define regUNIPHYE_LINK_CNTL_BASE_IDX 2
+#define regUNIPHYE_CHANNEL_XBAR_CNTL 0x2876
+#define regUNIPHYE_CHANNEL_XBAR_CNTL_BASE_IDX 2
+#define regDCIO_WRCMD_DELAY 0x287e
+#define regDCIO_WRCMD_DELAY_BASE_IDX 2
+#define regDC_PINSTRAPS 0x2880
+#define regDC_PINSTRAPS_BASE_IDX 2
+#define regINTERCEPT_STATE 0x2884
+#define regINTERCEPT_STATE_BASE_IDX 2
+#define regDCIO_BL_PWM_FRAME_START_DISP_SEL 0x288b
+#define regDCIO_BL_PWM_FRAME_START_DISP_SEL_BASE_IDX 2
+#define regDCIO_GSL_GENLK_PAD_CNTL 0x288c
+#define regDCIO_GSL_GENLK_PAD_CNTL_BASE_IDX 2
+#define regDCIO_GSL_SWAPLOCK_PAD_CNTL 0x288d
+#define regDCIO_GSL_SWAPLOCK_PAD_CNTL_BASE_IDX 2
+#define regDCIO_SOFT_RESET 0x289e
+#define regDCIO_SOFT_RESET_BASE_IDX 2
+
+
+// addressBlock: dce_dc_dcio_dcio_chip_dispdec
+// base address: 0x0
+#define regDC_GPIO_GENERIC_MASK 0x28c8
+#define regDC_GPIO_GENERIC_MASK_BASE_IDX 2
+#define regDC_GPIO_GENERIC_A 0x28c9
+#define regDC_GPIO_GENERIC_A_BASE_IDX 2
+#define regDC_GPIO_GENERIC_EN 0x28ca
+#define regDC_GPIO_GENERIC_EN_BASE_IDX 2
+#define regDC_GPIO_GENERIC_Y 0x28cb
+#define regDC_GPIO_GENERIC_Y_BASE_IDX 2
+#define regDC_GPIO_DDC1_MASK 0x28d0
+#define regDC_GPIO_DDC1_MASK_BASE_IDX 2
+#define regDC_GPIO_DDC1_A 0x28d1
+#define regDC_GPIO_DDC1_A_BASE_IDX 2
+#define regDC_GPIO_DDC1_EN 0x28d2
+#define regDC_GPIO_DDC1_EN_BASE_IDX 2
+#define regDC_GPIO_DDC1_Y 0x28d3
+#define regDC_GPIO_DDC1_Y_BASE_IDX 2
+#define regDC_GPIO_DDC2_MASK 0x28d4
+#define regDC_GPIO_DDC2_MASK_BASE_IDX 2
+#define regDC_GPIO_DDC2_A 0x28d5
+#define regDC_GPIO_DDC2_A_BASE_IDX 2
+#define regDC_GPIO_DDC2_EN 0x28d6
+#define regDC_GPIO_DDC2_EN_BASE_IDX 2
+#define regDC_GPIO_DDC2_Y 0x28d7
+#define regDC_GPIO_DDC2_Y_BASE_IDX 2
+#define regDC_GPIO_DDC3_MASK 0x28d8
+#define regDC_GPIO_DDC3_MASK_BASE_IDX 2
+#define regDC_GPIO_DDC3_A 0x28d9
+#define regDC_GPIO_DDC3_A_BASE_IDX 2
+#define regDC_GPIO_DDC3_EN 0x28da
+#define regDC_GPIO_DDC3_EN_BASE_IDX 2
+#define regDC_GPIO_DDC3_Y 0x28db
+#define regDC_GPIO_DDC3_Y_BASE_IDX 2
+#define regDC_GPIO_DDC4_MASK 0x28dc
+#define regDC_GPIO_DDC4_MASK_BASE_IDX 2
+#define regDC_GPIO_DDC4_A 0x28dd
+#define regDC_GPIO_DDC4_A_BASE_IDX 2
+#define regDC_GPIO_DDC4_EN 0x28de
+#define regDC_GPIO_DDC4_EN_BASE_IDX 2
+#define regDC_GPIO_DDC4_Y 0x28df
+#define regDC_GPIO_DDC4_Y_BASE_IDX 2
+#define regDC_GPIO_DDC5_MASK 0x28e0
+#define regDC_GPIO_DDC5_MASK_BASE_IDX 2
+#define regDC_GPIO_DDC5_A 0x28e1
+#define regDC_GPIO_DDC5_A_BASE_IDX 2
+#define regDC_GPIO_DDC5_EN 0x28e2
+#define regDC_GPIO_DDC5_EN_BASE_IDX 2
+#define regDC_GPIO_DDC5_Y 0x28e3
+#define regDC_GPIO_DDC5_Y_BASE_IDX 2
+#define regDC_GPIO_DDCVGA_MASK 0x28e8
+#define regDC_GPIO_DDCVGA_MASK_BASE_IDX 2
+#define regDC_GPIO_DDCVGA_A 0x28e9
+#define regDC_GPIO_DDCVGA_A_BASE_IDX 2
+#define regDC_GPIO_DDCVGA_EN 0x28ea
+#define regDC_GPIO_DDCVGA_EN_BASE_IDX 2
+#define regDC_GPIO_DDCVGA_Y 0x28eb
+#define regDC_GPIO_DDCVGA_Y_BASE_IDX 2
+#define regDC_GPIO_GENLK_MASK 0x28f0
+#define regDC_GPIO_GENLK_MASK_BASE_IDX 2
+#define regDC_GPIO_GENLK_A 0x28f1
+#define regDC_GPIO_GENLK_A_BASE_IDX 2
+#define regDC_GPIO_GENLK_EN 0x28f2
+#define regDC_GPIO_GENLK_EN_BASE_IDX 2
+#define regDC_GPIO_GENLK_Y 0x28f3
+#define regDC_GPIO_GENLK_Y_BASE_IDX 2
+#define regDC_GPIO_HPD_MASK 0x28f4
+#define regDC_GPIO_HPD_MASK_BASE_IDX 2
+#define regDC_GPIO_HPD_A 0x28f5
+#define regDC_GPIO_HPD_A_BASE_IDX 2
+#define regDC_GPIO_HPD_EN 0x28f6
+#define regDC_GPIO_HPD_EN_BASE_IDX 2
+#define regDC_GPIO_HPD_Y 0x28f7
+#define regDC_GPIO_HPD_Y_BASE_IDX 2
+#define regDC_GPIO_PWRSEQ0_EN 0x28fa
+#define regDC_GPIO_PWRSEQ0_EN_BASE_IDX 2
+#define regDC_GPIO_PAD_STRENGTH_1 0x28fc
+#define regDC_GPIO_PAD_STRENGTH_1_BASE_IDX 2
+#define regDC_GPIO_PAD_STRENGTH_2 0x28fd
+#define regDC_GPIO_PAD_STRENGTH_2_BASE_IDX 2
+#define regPHY_AUX_CNTL 0x28ff
+#define regPHY_AUX_CNTL_BASE_IDX 2
+#define regDC_GPIO_PWRSEQ1_EN 0x2902
+#define regDC_GPIO_PWRSEQ1_EN_BASE_IDX 2
+#define regDC_GPIO_TX12_EN 0x2915
+#define regDC_GPIO_TX12_EN_BASE_IDX 2
+#define regDC_GPIO_AUX_CTRL_0 0x2916
+#define regDC_GPIO_AUX_CTRL_0_BASE_IDX 2
+#define regDC_GPIO_AUX_CTRL_1 0x2917
+#define regDC_GPIO_AUX_CTRL_1_BASE_IDX 2
+#define regDC_GPIO_AUX_CTRL_2 0x2918
+#define regDC_GPIO_AUX_CTRL_2_BASE_IDX 2
+#define regDC_GPIO_RXEN 0x2919
+#define regDC_GPIO_RXEN_BASE_IDX 2
+#define regDC_GPIO_PULLUPEN 0x291a
+#define regDC_GPIO_PULLUPEN_BASE_IDX 2
+#define regDC_GPIO_AUX_CTRL_3 0x291b
+#define regDC_GPIO_AUX_CTRL_3_BASE_IDX 2
+#define regDC_GPIO_AUX_CTRL_4 0x291c
+#define regDC_GPIO_AUX_CTRL_4_BASE_IDX 2
+#define regDC_GPIO_AUX_CTRL_5 0x291d
+#define regDC_GPIO_AUX_CTRL_5_BASE_IDX 2
+#define regAUXI2C_PAD_ALL_PWR_OK 0x291e
+#define regAUXI2C_PAD_ALL_PWR_OK_BASE_IDX 2
+
+
+// addressBlock: dce_dc_dcio_dcio_uniphy0_dispdec
+// base address: 0x0
+#define regDCIO_UNIPHY0_UNIPHY_MACRO_CNTL_RESERVED0 0x2928
+#define regDCIO_UNIPHY0_UNIPHY_MACRO_CNTL_RESERVED0_BASE_IDX 2
+#define regDCIO_UNIPHY0_UNIPHY_MACRO_CNTL_RESERVED1 0x2929
+#define regDCIO_UNIPHY0_UNIPHY_MACRO_CNTL_RESERVED1_BASE_IDX 2
+#define regDCIO_UNIPHY0_UNIPHY_MACRO_CNTL_RESERVED2 0x292a
+#define regDCIO_UNIPHY0_UNIPHY_MACRO_CNTL_RESERVED2_BASE_IDX 2
+#define regDCIO_UNIPHY0_UNIPHY_MACRO_CNTL_RESERVED3 0x292b
+#define regDCIO_UNIPHY0_UNIPHY_MACRO_CNTL_RESERVED3_BASE_IDX 2
+#define regDCIO_UNIPHY0_UNIPHY_MACRO_CNTL_RESERVED4 0x292c
+#define regDCIO_UNIPHY0_UNIPHY_MACRO_CNTL_RESERVED4_BASE_IDX 2
+#define regDCIO_UNIPHY0_UNIPHY_MACRO_CNTL_RESERVED5 0x292d
+#define regDCIO_UNIPHY0_UNIPHY_MACRO_CNTL_RESERVED5_BASE_IDX 2
+#define regDCIO_UNIPHY0_UNIPHY_MACRO_CNTL_RESERVED6 0x292e
+#define regDCIO_UNIPHY0_UNIPHY_MACRO_CNTL_RESERVED6_BASE_IDX 2
+#define regDCIO_UNIPHY0_UNIPHY_MACRO_CNTL_RESERVED7 0x292f
+#define regDCIO_UNIPHY0_UNIPHY_MACRO_CNTL_RESERVED7_BASE_IDX 2
+#define regDCIO_UNIPHY0_UNIPHY_MACRO_CNTL_RESERVED8 0x2930
+#define regDCIO_UNIPHY0_UNIPHY_MACRO_CNTL_RESERVED8_BASE_IDX 2
+#define regDCIO_UNIPHY0_UNIPHY_MACRO_CNTL_RESERVED9 0x2931
+#define regDCIO_UNIPHY0_UNIPHY_MACRO_CNTL_RESERVED9_BASE_IDX 2
+#define regDCIO_UNIPHY0_UNIPHY_MACRO_CNTL_RESERVED10 0x2932
+#define regDCIO_UNIPHY0_UNIPHY_MACRO_CNTL_RESERVED10_BASE_IDX 2
+#define regDCIO_UNIPHY0_UNIPHY_MACRO_CNTL_RESERVED11 0x2933
+#define regDCIO_UNIPHY0_UNIPHY_MACRO_CNTL_RESERVED11_BASE_IDX 2
+#define regDCIO_UNIPHY0_UNIPHY_MACRO_CNTL_RESERVED12 0x2934
+#define regDCIO_UNIPHY0_UNIPHY_MACRO_CNTL_RESERVED12_BASE_IDX 2
+#define regDCIO_UNIPHY0_UNIPHY_MACRO_CNTL_RESERVED13 0x2935
+#define regDCIO_UNIPHY0_UNIPHY_MACRO_CNTL_RESERVED13_BASE_IDX 2
+#define regDCIO_UNIPHY0_UNIPHY_MACRO_CNTL_RESERVED14 0x2936
+#define regDCIO_UNIPHY0_UNIPHY_MACRO_CNTL_RESERVED14_BASE_IDX 2
+#define regDCIO_UNIPHY0_UNIPHY_MACRO_CNTL_RESERVED15 0x2937
+#define regDCIO_UNIPHY0_UNIPHY_MACRO_CNTL_RESERVED15_BASE_IDX 2
+#define regDCIO_UNIPHY0_UNIPHY_MACRO_CNTL_RESERVED16 0x2938
+#define regDCIO_UNIPHY0_UNIPHY_MACRO_CNTL_RESERVED16_BASE_IDX 2
+#define regDCIO_UNIPHY0_UNIPHY_MACRO_CNTL_RESERVED17 0x2939
+#define regDCIO_UNIPHY0_UNIPHY_MACRO_CNTL_RESERVED17_BASE_IDX 2
+#define regDCIO_UNIPHY0_UNIPHY_MACRO_CNTL_RESERVED18 0x293a
+#define regDCIO_UNIPHY0_UNIPHY_MACRO_CNTL_RESERVED18_BASE_IDX 2
+#define regDCIO_UNIPHY0_UNIPHY_MACRO_CNTL_RESERVED19 0x293b
+#define regDCIO_UNIPHY0_UNIPHY_MACRO_CNTL_RESERVED19_BASE_IDX 2
+#define regDCIO_UNIPHY0_UNIPHY_MACRO_CNTL_RESERVED20 0x293c
+#define regDCIO_UNIPHY0_UNIPHY_MACRO_CNTL_RESERVED20_BASE_IDX 2
+#define regDCIO_UNIPHY0_UNIPHY_MACRO_CNTL_RESERVED21 0x293d
+#define regDCIO_UNIPHY0_UNIPHY_MACRO_CNTL_RESERVED21_BASE_IDX 2
+#define regDCIO_UNIPHY0_UNIPHY_MACRO_CNTL_RESERVED22 0x293e
+#define regDCIO_UNIPHY0_UNIPHY_MACRO_CNTL_RESERVED22_BASE_IDX 2
+#define regDCIO_UNIPHY0_UNIPHY_MACRO_CNTL_RESERVED23 0x293f
+#define regDCIO_UNIPHY0_UNIPHY_MACRO_CNTL_RESERVED23_BASE_IDX 2
+#define regDCIO_UNIPHY0_UNIPHY_MACRO_CNTL_RESERVED24 0x2940
+#define regDCIO_UNIPHY0_UNIPHY_MACRO_CNTL_RESERVED24_BASE_IDX 2
+#define regDCIO_UNIPHY0_UNIPHY_MACRO_CNTL_RESERVED25 0x2941
+#define regDCIO_UNIPHY0_UNIPHY_MACRO_CNTL_RESERVED25_BASE_IDX 2
+#define regDCIO_UNIPHY0_UNIPHY_MACRO_CNTL_RESERVED26 0x2942
+#define regDCIO_UNIPHY0_UNIPHY_MACRO_CNTL_RESERVED26_BASE_IDX 2
+#define regDCIO_UNIPHY0_UNIPHY_MACRO_CNTL_RESERVED27 0x2943
+#define regDCIO_UNIPHY0_UNIPHY_MACRO_CNTL_RESERVED27_BASE_IDX 2
+#define regDCIO_UNIPHY0_UNIPHY_MACRO_CNTL_RESERVED28 0x2944
+#define regDCIO_UNIPHY0_UNIPHY_MACRO_CNTL_RESERVED28_BASE_IDX 2
+#define regDCIO_UNIPHY0_UNIPHY_MACRO_CNTL_RESERVED29 0x2945
+#define regDCIO_UNIPHY0_UNIPHY_MACRO_CNTL_RESERVED29_BASE_IDX 2
+#define regDCIO_UNIPHY0_UNIPHY_MACRO_CNTL_RESERVED30 0x2946
+#define regDCIO_UNIPHY0_UNIPHY_MACRO_CNTL_RESERVED30_BASE_IDX 2
+#define regDCIO_UNIPHY0_UNIPHY_MACRO_CNTL_RESERVED31 0x2947
+#define regDCIO_UNIPHY0_UNIPHY_MACRO_CNTL_RESERVED31_BASE_IDX 2
+#define regDCIO_UNIPHY0_UNIPHY_MACRO_CNTL_RESERVED32 0x2948
+#define regDCIO_UNIPHY0_UNIPHY_MACRO_CNTL_RESERVED32_BASE_IDX 2
+#define regDCIO_UNIPHY0_UNIPHY_MACRO_CNTL_RESERVED33 0x2949
+#define regDCIO_UNIPHY0_UNIPHY_MACRO_CNTL_RESERVED33_BASE_IDX 2
+#define regDCIO_UNIPHY0_UNIPHY_MACRO_CNTL_RESERVED34 0x294a
+#define regDCIO_UNIPHY0_UNIPHY_MACRO_CNTL_RESERVED34_BASE_IDX 2
+#define regDCIO_UNIPHY0_UNIPHY_MACRO_CNTL_RESERVED35 0x294b
+#define regDCIO_UNIPHY0_UNIPHY_MACRO_CNTL_RESERVED35_BASE_IDX 2
+#define regDCIO_UNIPHY0_UNIPHY_MACRO_CNTL_RESERVED36 0x294c
+#define regDCIO_UNIPHY0_UNIPHY_MACRO_CNTL_RESERVED36_BASE_IDX 2
+#define regDCIO_UNIPHY0_UNIPHY_MACRO_CNTL_RESERVED37 0x294d
+#define regDCIO_UNIPHY0_UNIPHY_MACRO_CNTL_RESERVED37_BASE_IDX 2
+#define regDCIO_UNIPHY0_UNIPHY_MACRO_CNTL_RESERVED38 0x294e
+#define regDCIO_UNIPHY0_UNIPHY_MACRO_CNTL_RESERVED38_BASE_IDX 2
+#define regDCIO_UNIPHY0_UNIPHY_MACRO_CNTL_RESERVED39 0x294f
+#define regDCIO_UNIPHY0_UNIPHY_MACRO_CNTL_RESERVED39_BASE_IDX 2
+#define regDCIO_UNIPHY0_UNIPHY_MACRO_CNTL_RESERVED40 0x2950
+#define regDCIO_UNIPHY0_UNIPHY_MACRO_CNTL_RESERVED40_BASE_IDX 2
+#define regDCIO_UNIPHY0_UNIPHY_MACRO_CNTL_RESERVED41 0x2951
+#define regDCIO_UNIPHY0_UNIPHY_MACRO_CNTL_RESERVED41_BASE_IDX 2
+#define regDCIO_UNIPHY0_UNIPHY_MACRO_CNTL_RESERVED42 0x2952
+#define regDCIO_UNIPHY0_UNIPHY_MACRO_CNTL_RESERVED42_BASE_IDX 2
+#define regDCIO_UNIPHY0_UNIPHY_MACRO_CNTL_RESERVED43 0x2953
+#define regDCIO_UNIPHY0_UNIPHY_MACRO_CNTL_RESERVED43_BASE_IDX 2
+#define regDCIO_UNIPHY0_UNIPHY_MACRO_CNTL_RESERVED44 0x2954
+#define regDCIO_UNIPHY0_UNIPHY_MACRO_CNTL_RESERVED44_BASE_IDX 2
+#define regDCIO_UNIPHY0_UNIPHY_MACRO_CNTL_RESERVED45 0x2955
+#define regDCIO_UNIPHY0_UNIPHY_MACRO_CNTL_RESERVED45_BASE_IDX 2
+#define regDCIO_UNIPHY0_UNIPHY_MACRO_CNTL_RESERVED46 0x2956
+#define regDCIO_UNIPHY0_UNIPHY_MACRO_CNTL_RESERVED46_BASE_IDX 2
+#define regDCIO_UNIPHY0_UNIPHY_MACRO_CNTL_RESERVED47 0x2957
+#define regDCIO_UNIPHY0_UNIPHY_MACRO_CNTL_RESERVED47_BASE_IDX 2
+#define regDCIO_UNIPHY0_UNIPHY_MACRO_CNTL_RESERVED48 0x2958
+#define regDCIO_UNIPHY0_UNIPHY_MACRO_CNTL_RESERVED48_BASE_IDX 2
+#define regDCIO_UNIPHY0_UNIPHY_MACRO_CNTL_RESERVED49 0x2959
+#define regDCIO_UNIPHY0_UNIPHY_MACRO_CNTL_RESERVED49_BASE_IDX 2
+#define regDCIO_UNIPHY0_UNIPHY_MACRO_CNTL_RESERVED50 0x295a
+#define regDCIO_UNIPHY0_UNIPHY_MACRO_CNTL_RESERVED50_BASE_IDX 2
+#define regDCIO_UNIPHY0_UNIPHY_MACRO_CNTL_RESERVED51 0x295b
+#define regDCIO_UNIPHY0_UNIPHY_MACRO_CNTL_RESERVED51_BASE_IDX 2
+#define regDCIO_UNIPHY0_UNIPHY_MACRO_CNTL_RESERVED52 0x295c
+#define regDCIO_UNIPHY0_UNIPHY_MACRO_CNTL_RESERVED52_BASE_IDX 2
+#define regDCIO_UNIPHY0_UNIPHY_MACRO_CNTL_RESERVED53 0x295d
+#define regDCIO_UNIPHY0_UNIPHY_MACRO_CNTL_RESERVED53_BASE_IDX 2
+#define regDCIO_UNIPHY0_UNIPHY_MACRO_CNTL_RESERVED54 0x295e
+#define regDCIO_UNIPHY0_UNIPHY_MACRO_CNTL_RESERVED54_BASE_IDX 2
+#define regDCIO_UNIPHY0_UNIPHY_MACRO_CNTL_RESERVED55 0x295f
+#define regDCIO_UNIPHY0_UNIPHY_MACRO_CNTL_RESERVED55_BASE_IDX 2
+#define regDCIO_UNIPHY0_UNIPHY_MACRO_CNTL_RESERVED56 0x2960
+#define regDCIO_UNIPHY0_UNIPHY_MACRO_CNTL_RESERVED56_BASE_IDX 2
+#define regDCIO_UNIPHY0_UNIPHY_MACRO_CNTL_RESERVED57 0x2961
+#define regDCIO_UNIPHY0_UNIPHY_MACRO_CNTL_RESERVED57_BASE_IDX 2
+
+
+// addressBlock: dce_dc_dcio_dcio_uniphy1_dispdec
+// base address: 0x360
+#define regDCIO_UNIPHY1_UNIPHY_MACRO_CNTL_RESERVED0 0x2a00
+#define regDCIO_UNIPHY1_UNIPHY_MACRO_CNTL_RESERVED0_BASE_IDX 2
+#define regDCIO_UNIPHY1_UNIPHY_MACRO_CNTL_RESERVED1 0x2a01
+#define regDCIO_UNIPHY1_UNIPHY_MACRO_CNTL_RESERVED1_BASE_IDX 2
+#define regDCIO_UNIPHY1_UNIPHY_MACRO_CNTL_RESERVED2 0x2a02
+#define regDCIO_UNIPHY1_UNIPHY_MACRO_CNTL_RESERVED2_BASE_IDX 2
+#define regDCIO_UNIPHY1_UNIPHY_MACRO_CNTL_RESERVED3 0x2a03
+#define regDCIO_UNIPHY1_UNIPHY_MACRO_CNTL_RESERVED3_BASE_IDX 2
+#define regDCIO_UNIPHY1_UNIPHY_MACRO_CNTL_RESERVED4 0x2a04
+#define regDCIO_UNIPHY1_UNIPHY_MACRO_CNTL_RESERVED4_BASE_IDX 2
+#define regDCIO_UNIPHY1_UNIPHY_MACRO_CNTL_RESERVED5 0x2a05
+#define regDCIO_UNIPHY1_UNIPHY_MACRO_CNTL_RESERVED5_BASE_IDX 2
+#define regDCIO_UNIPHY1_UNIPHY_MACRO_CNTL_RESERVED6 0x2a06
+#define regDCIO_UNIPHY1_UNIPHY_MACRO_CNTL_RESERVED6_BASE_IDX 2
+#define regDCIO_UNIPHY1_UNIPHY_MACRO_CNTL_RESERVED7 0x2a07
+#define regDCIO_UNIPHY1_UNIPHY_MACRO_CNTL_RESERVED7_BASE_IDX 2
+#define regDCIO_UNIPHY1_UNIPHY_MACRO_CNTL_RESERVED8 0x2a08
+#define regDCIO_UNIPHY1_UNIPHY_MACRO_CNTL_RESERVED8_BASE_IDX 2
+#define regDCIO_UNIPHY1_UNIPHY_MACRO_CNTL_RESERVED9 0x2a09
+#define regDCIO_UNIPHY1_UNIPHY_MACRO_CNTL_RESERVED9_BASE_IDX 2
+#define regDCIO_UNIPHY1_UNIPHY_MACRO_CNTL_RESERVED10 0x2a0a
+#define regDCIO_UNIPHY1_UNIPHY_MACRO_CNTL_RESERVED10_BASE_IDX 2
+#define regDCIO_UNIPHY1_UNIPHY_MACRO_CNTL_RESERVED11 0x2a0b
+#define regDCIO_UNIPHY1_UNIPHY_MACRO_CNTL_RESERVED11_BASE_IDX 2
+#define regDCIO_UNIPHY1_UNIPHY_MACRO_CNTL_RESERVED12 0x2a0c
+#define regDCIO_UNIPHY1_UNIPHY_MACRO_CNTL_RESERVED12_BASE_IDX 2
+#define regDCIO_UNIPHY1_UNIPHY_MACRO_CNTL_RESERVED13 0x2a0d
+#define regDCIO_UNIPHY1_UNIPHY_MACRO_CNTL_RESERVED13_BASE_IDX 2
+#define regDCIO_UNIPHY1_UNIPHY_MACRO_CNTL_RESERVED14 0x2a0e
+#define regDCIO_UNIPHY1_UNIPHY_MACRO_CNTL_RESERVED14_BASE_IDX 2
+#define regDCIO_UNIPHY1_UNIPHY_MACRO_CNTL_RESERVED15 0x2a0f
+#define regDCIO_UNIPHY1_UNIPHY_MACRO_CNTL_RESERVED15_BASE_IDX 2
+#define regDCIO_UNIPHY1_UNIPHY_MACRO_CNTL_RESERVED16 0x2a10
+#define regDCIO_UNIPHY1_UNIPHY_MACRO_CNTL_RESERVED16_BASE_IDX 2
+#define regDCIO_UNIPHY1_UNIPHY_MACRO_CNTL_RESERVED17 0x2a11
+#define regDCIO_UNIPHY1_UNIPHY_MACRO_CNTL_RESERVED17_BASE_IDX 2
+#define regDCIO_UNIPHY1_UNIPHY_MACRO_CNTL_RESERVED18 0x2a12
+#define regDCIO_UNIPHY1_UNIPHY_MACRO_CNTL_RESERVED18_BASE_IDX 2
+#define regDCIO_UNIPHY1_UNIPHY_MACRO_CNTL_RESERVED19 0x2a13
+#define regDCIO_UNIPHY1_UNIPHY_MACRO_CNTL_RESERVED19_BASE_IDX 2
+#define regDCIO_UNIPHY1_UNIPHY_MACRO_CNTL_RESERVED20 0x2a14
+#define regDCIO_UNIPHY1_UNIPHY_MACRO_CNTL_RESERVED20_BASE_IDX 2
+#define regDCIO_UNIPHY1_UNIPHY_MACRO_CNTL_RESERVED21 0x2a15
+#define regDCIO_UNIPHY1_UNIPHY_MACRO_CNTL_RESERVED21_BASE_IDX 2
+#define regDCIO_UNIPHY1_UNIPHY_MACRO_CNTL_RESERVED22 0x2a16
+#define regDCIO_UNIPHY1_UNIPHY_MACRO_CNTL_RESERVED22_BASE_IDX 2
+#define regDCIO_UNIPHY1_UNIPHY_MACRO_CNTL_RESERVED23 0x2a17
+#define regDCIO_UNIPHY1_UNIPHY_MACRO_CNTL_RESERVED23_BASE_IDX 2
+#define regDCIO_UNIPHY1_UNIPHY_MACRO_CNTL_RESERVED24 0x2a18
+#define regDCIO_UNIPHY1_UNIPHY_MACRO_CNTL_RESERVED24_BASE_IDX 2
+#define regDCIO_UNIPHY1_UNIPHY_MACRO_CNTL_RESERVED25 0x2a19
+#define regDCIO_UNIPHY1_UNIPHY_MACRO_CNTL_RESERVED25_BASE_IDX 2
+#define regDCIO_UNIPHY1_UNIPHY_MACRO_CNTL_RESERVED26 0x2a1a
+#define regDCIO_UNIPHY1_UNIPHY_MACRO_CNTL_RESERVED26_BASE_IDX 2
+#define regDCIO_UNIPHY1_UNIPHY_MACRO_CNTL_RESERVED27 0x2a1b
+#define regDCIO_UNIPHY1_UNIPHY_MACRO_CNTL_RESERVED27_BASE_IDX 2
+#define regDCIO_UNIPHY1_UNIPHY_MACRO_CNTL_RESERVED28 0x2a1c
+#define regDCIO_UNIPHY1_UNIPHY_MACRO_CNTL_RESERVED28_BASE_IDX 2
+#define regDCIO_UNIPHY1_UNIPHY_MACRO_CNTL_RESERVED29 0x2a1d
+#define regDCIO_UNIPHY1_UNIPHY_MACRO_CNTL_RESERVED29_BASE_IDX 2
+#define regDCIO_UNIPHY1_UNIPHY_MACRO_CNTL_RESERVED30 0x2a1e
+#define regDCIO_UNIPHY1_UNIPHY_MACRO_CNTL_RESERVED30_BASE_IDX 2
+#define regDCIO_UNIPHY1_UNIPHY_MACRO_CNTL_RESERVED31 0x2a1f
+#define regDCIO_UNIPHY1_UNIPHY_MACRO_CNTL_RESERVED31_BASE_IDX 2
+#define regDCIO_UNIPHY1_UNIPHY_MACRO_CNTL_RESERVED32 0x2a20
+#define regDCIO_UNIPHY1_UNIPHY_MACRO_CNTL_RESERVED32_BASE_IDX 2
+#define regDCIO_UNIPHY1_UNIPHY_MACRO_CNTL_RESERVED33 0x2a21
+#define regDCIO_UNIPHY1_UNIPHY_MACRO_CNTL_RESERVED33_BASE_IDX 2
+#define regDCIO_UNIPHY1_UNIPHY_MACRO_CNTL_RESERVED34 0x2a22
+#define regDCIO_UNIPHY1_UNIPHY_MACRO_CNTL_RESERVED34_BASE_IDX 2
+#define regDCIO_UNIPHY1_UNIPHY_MACRO_CNTL_RESERVED35 0x2a23
+#define regDCIO_UNIPHY1_UNIPHY_MACRO_CNTL_RESERVED35_BASE_IDX 2
+#define regDCIO_UNIPHY1_UNIPHY_MACRO_CNTL_RESERVED36 0x2a24
+#define regDCIO_UNIPHY1_UNIPHY_MACRO_CNTL_RESERVED36_BASE_IDX 2
+#define regDCIO_UNIPHY1_UNIPHY_MACRO_CNTL_RESERVED37 0x2a25
+#define regDCIO_UNIPHY1_UNIPHY_MACRO_CNTL_RESERVED37_BASE_IDX 2
+#define regDCIO_UNIPHY1_UNIPHY_MACRO_CNTL_RESERVED38 0x2a26
+#define regDCIO_UNIPHY1_UNIPHY_MACRO_CNTL_RESERVED38_BASE_IDX 2
+#define regDCIO_UNIPHY1_UNIPHY_MACRO_CNTL_RESERVED39 0x2a27
+#define regDCIO_UNIPHY1_UNIPHY_MACRO_CNTL_RESERVED39_BASE_IDX 2
+#define regDCIO_UNIPHY1_UNIPHY_MACRO_CNTL_RESERVED40 0x2a28
+#define regDCIO_UNIPHY1_UNIPHY_MACRO_CNTL_RESERVED40_BASE_IDX 2
+#define regDCIO_UNIPHY1_UNIPHY_MACRO_CNTL_RESERVED41 0x2a29
+#define regDCIO_UNIPHY1_UNIPHY_MACRO_CNTL_RESERVED41_BASE_IDX 2
+#define regDCIO_UNIPHY1_UNIPHY_MACRO_CNTL_RESERVED42 0x2a2a
+#define regDCIO_UNIPHY1_UNIPHY_MACRO_CNTL_RESERVED42_BASE_IDX 2
+#define regDCIO_UNIPHY1_UNIPHY_MACRO_CNTL_RESERVED43 0x2a2b
+#define regDCIO_UNIPHY1_UNIPHY_MACRO_CNTL_RESERVED43_BASE_IDX 2
+#define regDCIO_UNIPHY1_UNIPHY_MACRO_CNTL_RESERVED44 0x2a2c
+#define regDCIO_UNIPHY1_UNIPHY_MACRO_CNTL_RESERVED44_BASE_IDX 2
+#define regDCIO_UNIPHY1_UNIPHY_MACRO_CNTL_RESERVED45 0x2a2d
+#define regDCIO_UNIPHY1_UNIPHY_MACRO_CNTL_RESERVED45_BASE_IDX 2
+#define regDCIO_UNIPHY1_UNIPHY_MACRO_CNTL_RESERVED46 0x2a2e
+#define regDCIO_UNIPHY1_UNIPHY_MACRO_CNTL_RESERVED46_BASE_IDX 2
+#define regDCIO_UNIPHY1_UNIPHY_MACRO_CNTL_RESERVED47 0x2a2f
+#define regDCIO_UNIPHY1_UNIPHY_MACRO_CNTL_RESERVED47_BASE_IDX 2
+#define regDCIO_UNIPHY1_UNIPHY_MACRO_CNTL_RESERVED48 0x2a30
+#define regDCIO_UNIPHY1_UNIPHY_MACRO_CNTL_RESERVED48_BASE_IDX 2
+#define regDCIO_UNIPHY1_UNIPHY_MACRO_CNTL_RESERVED49 0x2a31
+#define regDCIO_UNIPHY1_UNIPHY_MACRO_CNTL_RESERVED49_BASE_IDX 2
+#define regDCIO_UNIPHY1_UNIPHY_MACRO_CNTL_RESERVED50 0x2a32
+#define regDCIO_UNIPHY1_UNIPHY_MACRO_CNTL_RESERVED50_BASE_IDX 2
+#define regDCIO_UNIPHY1_UNIPHY_MACRO_CNTL_RESERVED51 0x2a33
+#define regDCIO_UNIPHY1_UNIPHY_MACRO_CNTL_RESERVED51_BASE_IDX 2
+#define regDCIO_UNIPHY1_UNIPHY_MACRO_CNTL_RESERVED52 0x2a34
+#define regDCIO_UNIPHY1_UNIPHY_MACRO_CNTL_RESERVED52_BASE_IDX 2
+#define regDCIO_UNIPHY1_UNIPHY_MACRO_CNTL_RESERVED53 0x2a35
+#define regDCIO_UNIPHY1_UNIPHY_MACRO_CNTL_RESERVED53_BASE_IDX 2
+#define regDCIO_UNIPHY1_UNIPHY_MACRO_CNTL_RESERVED54 0x2a36
+#define regDCIO_UNIPHY1_UNIPHY_MACRO_CNTL_RESERVED54_BASE_IDX 2
+#define regDCIO_UNIPHY1_UNIPHY_MACRO_CNTL_RESERVED55 0x2a37
+#define regDCIO_UNIPHY1_UNIPHY_MACRO_CNTL_RESERVED55_BASE_IDX 2
+#define regDCIO_UNIPHY1_UNIPHY_MACRO_CNTL_RESERVED56 0x2a38
+#define regDCIO_UNIPHY1_UNIPHY_MACRO_CNTL_RESERVED56_BASE_IDX 2
+#define regDCIO_UNIPHY1_UNIPHY_MACRO_CNTL_RESERVED57 0x2a39
+#define regDCIO_UNIPHY1_UNIPHY_MACRO_CNTL_RESERVED57_BASE_IDX 2
+
+
+// addressBlock: dce_dc_dcio_dcio_uniphy2_dispdec
+// base address: 0x6c0
+#define regDCIO_UNIPHY2_UNIPHY_MACRO_CNTL_RESERVED0 0x2ad8
+#define regDCIO_UNIPHY2_UNIPHY_MACRO_CNTL_RESERVED0_BASE_IDX 2
+#define regDCIO_UNIPHY2_UNIPHY_MACRO_CNTL_RESERVED1 0x2ad9
+#define regDCIO_UNIPHY2_UNIPHY_MACRO_CNTL_RESERVED1_BASE_IDX 2
+#define regDCIO_UNIPHY2_UNIPHY_MACRO_CNTL_RESERVED2 0x2ada
+#define regDCIO_UNIPHY2_UNIPHY_MACRO_CNTL_RESERVED2_BASE_IDX 2
+#define regDCIO_UNIPHY2_UNIPHY_MACRO_CNTL_RESERVED3 0x2adb
+#define regDCIO_UNIPHY2_UNIPHY_MACRO_CNTL_RESERVED3_BASE_IDX 2
+#define regDCIO_UNIPHY2_UNIPHY_MACRO_CNTL_RESERVED4 0x2adc
+#define regDCIO_UNIPHY2_UNIPHY_MACRO_CNTL_RESERVED4_BASE_IDX 2
+#define regDCIO_UNIPHY2_UNIPHY_MACRO_CNTL_RESERVED5 0x2add
+#define regDCIO_UNIPHY2_UNIPHY_MACRO_CNTL_RESERVED5_BASE_IDX 2
+#define regDCIO_UNIPHY2_UNIPHY_MACRO_CNTL_RESERVED6 0x2ade
+#define regDCIO_UNIPHY2_UNIPHY_MACRO_CNTL_RESERVED6_BASE_IDX 2
+#define regDCIO_UNIPHY2_UNIPHY_MACRO_CNTL_RESERVED7 0x2adf
+#define regDCIO_UNIPHY2_UNIPHY_MACRO_CNTL_RESERVED7_BASE_IDX 2
+#define regDCIO_UNIPHY2_UNIPHY_MACRO_CNTL_RESERVED8 0x2ae0
+#define regDCIO_UNIPHY2_UNIPHY_MACRO_CNTL_RESERVED8_BASE_IDX 2
+#define regDCIO_UNIPHY2_UNIPHY_MACRO_CNTL_RESERVED9 0x2ae1
+#define regDCIO_UNIPHY2_UNIPHY_MACRO_CNTL_RESERVED9_BASE_IDX 2
+#define regDCIO_UNIPHY2_UNIPHY_MACRO_CNTL_RESERVED10 0x2ae2
+#define regDCIO_UNIPHY2_UNIPHY_MACRO_CNTL_RESERVED10_BASE_IDX 2
+#define regDCIO_UNIPHY2_UNIPHY_MACRO_CNTL_RESERVED11 0x2ae3
+#define regDCIO_UNIPHY2_UNIPHY_MACRO_CNTL_RESERVED11_BASE_IDX 2
+#define regDCIO_UNIPHY2_UNIPHY_MACRO_CNTL_RESERVED12 0x2ae4
+#define regDCIO_UNIPHY2_UNIPHY_MACRO_CNTL_RESERVED12_BASE_IDX 2
+#define regDCIO_UNIPHY2_UNIPHY_MACRO_CNTL_RESERVED13 0x2ae5
+#define regDCIO_UNIPHY2_UNIPHY_MACRO_CNTL_RESERVED13_BASE_IDX 2
+#define regDCIO_UNIPHY2_UNIPHY_MACRO_CNTL_RESERVED14 0x2ae6
+#define regDCIO_UNIPHY2_UNIPHY_MACRO_CNTL_RESERVED14_BASE_IDX 2
+#define regDCIO_UNIPHY2_UNIPHY_MACRO_CNTL_RESERVED15 0x2ae7
+#define regDCIO_UNIPHY2_UNIPHY_MACRO_CNTL_RESERVED15_BASE_IDX 2
+#define regDCIO_UNIPHY2_UNIPHY_MACRO_CNTL_RESERVED16 0x2ae8
+#define regDCIO_UNIPHY2_UNIPHY_MACRO_CNTL_RESERVED16_BASE_IDX 2
+#define regDCIO_UNIPHY2_UNIPHY_MACRO_CNTL_RESERVED17 0x2ae9
+#define regDCIO_UNIPHY2_UNIPHY_MACRO_CNTL_RESERVED17_BASE_IDX 2
+#define regDCIO_UNIPHY2_UNIPHY_MACRO_CNTL_RESERVED18 0x2aea
+#define regDCIO_UNIPHY2_UNIPHY_MACRO_CNTL_RESERVED18_BASE_IDX 2
+#define regDCIO_UNIPHY2_UNIPHY_MACRO_CNTL_RESERVED19 0x2aeb
+#define regDCIO_UNIPHY2_UNIPHY_MACRO_CNTL_RESERVED19_BASE_IDX 2
+#define regDCIO_UNIPHY2_UNIPHY_MACRO_CNTL_RESERVED20 0x2aec
+#define regDCIO_UNIPHY2_UNIPHY_MACRO_CNTL_RESERVED20_BASE_IDX 2
+#define regDCIO_UNIPHY2_UNIPHY_MACRO_CNTL_RESERVED21 0x2aed
+#define regDCIO_UNIPHY2_UNIPHY_MACRO_CNTL_RESERVED21_BASE_IDX 2
+#define regDCIO_UNIPHY2_UNIPHY_MACRO_CNTL_RESERVED22 0x2aee
+#define regDCIO_UNIPHY2_UNIPHY_MACRO_CNTL_RESERVED22_BASE_IDX 2
+#define regDCIO_UNIPHY2_UNIPHY_MACRO_CNTL_RESERVED23 0x2aef
+#define regDCIO_UNIPHY2_UNIPHY_MACRO_CNTL_RESERVED23_BASE_IDX 2
+#define regDCIO_UNIPHY2_UNIPHY_MACRO_CNTL_RESERVED24 0x2af0
+#define regDCIO_UNIPHY2_UNIPHY_MACRO_CNTL_RESERVED24_BASE_IDX 2
+#define regDCIO_UNIPHY2_UNIPHY_MACRO_CNTL_RESERVED25 0x2af1
+#define regDCIO_UNIPHY2_UNIPHY_MACRO_CNTL_RESERVED25_BASE_IDX 2
+#define regDCIO_UNIPHY2_UNIPHY_MACRO_CNTL_RESERVED26 0x2af2
+#define regDCIO_UNIPHY2_UNIPHY_MACRO_CNTL_RESERVED26_BASE_IDX 2
+#define regDCIO_UNIPHY2_UNIPHY_MACRO_CNTL_RESERVED27 0x2af3
+#define regDCIO_UNIPHY2_UNIPHY_MACRO_CNTL_RESERVED27_BASE_IDX 2
+#define regDCIO_UNIPHY2_UNIPHY_MACRO_CNTL_RESERVED28 0x2af4
+#define regDCIO_UNIPHY2_UNIPHY_MACRO_CNTL_RESERVED28_BASE_IDX 2
+#define regDCIO_UNIPHY2_UNIPHY_MACRO_CNTL_RESERVED29 0x2af5
+#define regDCIO_UNIPHY2_UNIPHY_MACRO_CNTL_RESERVED29_BASE_IDX 2
+#define regDCIO_UNIPHY2_UNIPHY_MACRO_CNTL_RESERVED30 0x2af6
+#define regDCIO_UNIPHY2_UNIPHY_MACRO_CNTL_RESERVED30_BASE_IDX 2
+#define regDCIO_UNIPHY2_UNIPHY_MACRO_CNTL_RESERVED31 0x2af7
+#define regDCIO_UNIPHY2_UNIPHY_MACRO_CNTL_RESERVED31_BASE_IDX 2
+#define regDCIO_UNIPHY2_UNIPHY_MACRO_CNTL_RESERVED32 0x2af8
+#define regDCIO_UNIPHY2_UNIPHY_MACRO_CNTL_RESERVED32_BASE_IDX 2
+#define regDCIO_UNIPHY2_UNIPHY_MACRO_CNTL_RESERVED33 0x2af9
+#define regDCIO_UNIPHY2_UNIPHY_MACRO_CNTL_RESERVED33_BASE_IDX 2
+#define regDCIO_UNIPHY2_UNIPHY_MACRO_CNTL_RESERVED34 0x2afa
+#define regDCIO_UNIPHY2_UNIPHY_MACRO_CNTL_RESERVED34_BASE_IDX 2
+#define regDCIO_UNIPHY2_UNIPHY_MACRO_CNTL_RESERVED35 0x2afb
+#define regDCIO_UNIPHY2_UNIPHY_MACRO_CNTL_RESERVED35_BASE_IDX 2
+#define regDCIO_UNIPHY2_UNIPHY_MACRO_CNTL_RESERVED36 0x2afc
+#define regDCIO_UNIPHY2_UNIPHY_MACRO_CNTL_RESERVED36_BASE_IDX 2
+#define regDCIO_UNIPHY2_UNIPHY_MACRO_CNTL_RESERVED37 0x2afd
+#define regDCIO_UNIPHY2_UNIPHY_MACRO_CNTL_RESERVED37_BASE_IDX 2
+#define regDCIO_UNIPHY2_UNIPHY_MACRO_CNTL_RESERVED38 0x2afe
+#define regDCIO_UNIPHY2_UNIPHY_MACRO_CNTL_RESERVED38_BASE_IDX 2
+#define regDCIO_UNIPHY2_UNIPHY_MACRO_CNTL_RESERVED39 0x2aff
+#define regDCIO_UNIPHY2_UNIPHY_MACRO_CNTL_RESERVED39_BASE_IDX 2
+#define regDCIO_UNIPHY2_UNIPHY_MACRO_CNTL_RESERVED40 0x2b00
+#define regDCIO_UNIPHY2_UNIPHY_MACRO_CNTL_RESERVED40_BASE_IDX 2
+#define regDCIO_UNIPHY2_UNIPHY_MACRO_CNTL_RESERVED41 0x2b01
+#define regDCIO_UNIPHY2_UNIPHY_MACRO_CNTL_RESERVED41_BASE_IDX 2
+#define regDCIO_UNIPHY2_UNIPHY_MACRO_CNTL_RESERVED42 0x2b02
+#define regDCIO_UNIPHY2_UNIPHY_MACRO_CNTL_RESERVED42_BASE_IDX 2
+#define regDCIO_UNIPHY2_UNIPHY_MACRO_CNTL_RESERVED43 0x2b03
+#define regDCIO_UNIPHY2_UNIPHY_MACRO_CNTL_RESERVED43_BASE_IDX 2
+#define regDCIO_UNIPHY2_UNIPHY_MACRO_CNTL_RESERVED44 0x2b04
+#define regDCIO_UNIPHY2_UNIPHY_MACRO_CNTL_RESERVED44_BASE_IDX 2
+#define regDCIO_UNIPHY2_UNIPHY_MACRO_CNTL_RESERVED45 0x2b05
+#define regDCIO_UNIPHY2_UNIPHY_MACRO_CNTL_RESERVED45_BASE_IDX 2
+#define regDCIO_UNIPHY2_UNIPHY_MACRO_CNTL_RESERVED46 0x2b06
+#define regDCIO_UNIPHY2_UNIPHY_MACRO_CNTL_RESERVED46_BASE_IDX 2
+#define regDCIO_UNIPHY2_UNIPHY_MACRO_CNTL_RESERVED47 0x2b07
+#define regDCIO_UNIPHY2_UNIPHY_MACRO_CNTL_RESERVED47_BASE_IDX 2
+#define regDCIO_UNIPHY2_UNIPHY_MACRO_CNTL_RESERVED48 0x2b08
+#define regDCIO_UNIPHY2_UNIPHY_MACRO_CNTL_RESERVED48_BASE_IDX 2
+#define regDCIO_UNIPHY2_UNIPHY_MACRO_CNTL_RESERVED49 0x2b09
+#define regDCIO_UNIPHY2_UNIPHY_MACRO_CNTL_RESERVED49_BASE_IDX 2
+#define regDCIO_UNIPHY2_UNIPHY_MACRO_CNTL_RESERVED50 0x2b0a
+#define regDCIO_UNIPHY2_UNIPHY_MACRO_CNTL_RESERVED50_BASE_IDX 2
+#define regDCIO_UNIPHY2_UNIPHY_MACRO_CNTL_RESERVED51 0x2b0b
+#define regDCIO_UNIPHY2_UNIPHY_MACRO_CNTL_RESERVED51_BASE_IDX 2
+#define regDCIO_UNIPHY2_UNIPHY_MACRO_CNTL_RESERVED52 0x2b0c
+#define regDCIO_UNIPHY2_UNIPHY_MACRO_CNTL_RESERVED52_BASE_IDX 2
+#define regDCIO_UNIPHY2_UNIPHY_MACRO_CNTL_RESERVED53 0x2b0d
+#define regDCIO_UNIPHY2_UNIPHY_MACRO_CNTL_RESERVED53_BASE_IDX 2
+#define regDCIO_UNIPHY2_UNIPHY_MACRO_CNTL_RESERVED54 0x2b0e
+#define regDCIO_UNIPHY2_UNIPHY_MACRO_CNTL_RESERVED54_BASE_IDX 2
+#define regDCIO_UNIPHY2_UNIPHY_MACRO_CNTL_RESERVED55 0x2b0f
+#define regDCIO_UNIPHY2_UNIPHY_MACRO_CNTL_RESERVED55_BASE_IDX 2
+#define regDCIO_UNIPHY2_UNIPHY_MACRO_CNTL_RESERVED56 0x2b10
+#define regDCIO_UNIPHY2_UNIPHY_MACRO_CNTL_RESERVED56_BASE_IDX 2
+#define regDCIO_UNIPHY2_UNIPHY_MACRO_CNTL_RESERVED57 0x2b11
+#define regDCIO_UNIPHY2_UNIPHY_MACRO_CNTL_RESERVED57_BASE_IDX 2
+
+
+// addressBlock: dce_dc_dcio_dcio_uniphy3_dispdec
+// base address: 0xa20
+#define regDCIO_UNIPHY3_UNIPHY_MACRO_CNTL_RESERVED0 0x2bb0
+#define regDCIO_UNIPHY3_UNIPHY_MACRO_CNTL_RESERVED0_BASE_IDX 2
+#define regDCIO_UNIPHY3_UNIPHY_MACRO_CNTL_RESERVED1 0x2bb1
+#define regDCIO_UNIPHY3_UNIPHY_MACRO_CNTL_RESERVED1_BASE_IDX 2
+#define regDCIO_UNIPHY3_UNIPHY_MACRO_CNTL_RESERVED2 0x2bb2
+#define regDCIO_UNIPHY3_UNIPHY_MACRO_CNTL_RESERVED2_BASE_IDX 2
+#define regDCIO_UNIPHY3_UNIPHY_MACRO_CNTL_RESERVED3 0x2bb3
+#define regDCIO_UNIPHY3_UNIPHY_MACRO_CNTL_RESERVED3_BASE_IDX 2
+#define regDCIO_UNIPHY3_UNIPHY_MACRO_CNTL_RESERVED4 0x2bb4
+#define regDCIO_UNIPHY3_UNIPHY_MACRO_CNTL_RESERVED4_BASE_IDX 2
+#define regDCIO_UNIPHY3_UNIPHY_MACRO_CNTL_RESERVED5 0x2bb5
+#define regDCIO_UNIPHY3_UNIPHY_MACRO_CNTL_RESERVED5_BASE_IDX 2
+#define regDCIO_UNIPHY3_UNIPHY_MACRO_CNTL_RESERVED6 0x2bb6
+#define regDCIO_UNIPHY3_UNIPHY_MACRO_CNTL_RESERVED6_BASE_IDX 2
+#define regDCIO_UNIPHY3_UNIPHY_MACRO_CNTL_RESERVED7 0x2bb7
+#define regDCIO_UNIPHY3_UNIPHY_MACRO_CNTL_RESERVED7_BASE_IDX 2
+#define regDCIO_UNIPHY3_UNIPHY_MACRO_CNTL_RESERVED8 0x2bb8
+#define regDCIO_UNIPHY3_UNIPHY_MACRO_CNTL_RESERVED8_BASE_IDX 2
+#define regDCIO_UNIPHY3_UNIPHY_MACRO_CNTL_RESERVED9 0x2bb9
+#define regDCIO_UNIPHY3_UNIPHY_MACRO_CNTL_RESERVED9_BASE_IDX 2
+#define regDCIO_UNIPHY3_UNIPHY_MACRO_CNTL_RESERVED10 0x2bba
+#define regDCIO_UNIPHY3_UNIPHY_MACRO_CNTL_RESERVED10_BASE_IDX 2
+#define regDCIO_UNIPHY3_UNIPHY_MACRO_CNTL_RESERVED11 0x2bbb
+#define regDCIO_UNIPHY3_UNIPHY_MACRO_CNTL_RESERVED11_BASE_IDX 2
+#define regDCIO_UNIPHY3_UNIPHY_MACRO_CNTL_RESERVED12 0x2bbc
+#define regDCIO_UNIPHY3_UNIPHY_MACRO_CNTL_RESERVED12_BASE_IDX 2
+#define regDCIO_UNIPHY3_UNIPHY_MACRO_CNTL_RESERVED13 0x2bbd
+#define regDCIO_UNIPHY3_UNIPHY_MACRO_CNTL_RESERVED13_BASE_IDX 2
+#define regDCIO_UNIPHY3_UNIPHY_MACRO_CNTL_RESERVED14 0x2bbe
+#define regDCIO_UNIPHY3_UNIPHY_MACRO_CNTL_RESERVED14_BASE_IDX 2
+#define regDCIO_UNIPHY3_UNIPHY_MACRO_CNTL_RESERVED15 0x2bbf
+#define regDCIO_UNIPHY3_UNIPHY_MACRO_CNTL_RESERVED15_BASE_IDX 2
+#define regDCIO_UNIPHY3_UNIPHY_MACRO_CNTL_RESERVED16 0x2bc0
+#define regDCIO_UNIPHY3_UNIPHY_MACRO_CNTL_RESERVED16_BASE_IDX 2
+#define regDCIO_UNIPHY3_UNIPHY_MACRO_CNTL_RESERVED17 0x2bc1
+#define regDCIO_UNIPHY3_UNIPHY_MACRO_CNTL_RESERVED17_BASE_IDX 2
+#define regDCIO_UNIPHY3_UNIPHY_MACRO_CNTL_RESERVED18 0x2bc2
+#define regDCIO_UNIPHY3_UNIPHY_MACRO_CNTL_RESERVED18_BASE_IDX 2
+#define regDCIO_UNIPHY3_UNIPHY_MACRO_CNTL_RESERVED19 0x2bc3
+#define regDCIO_UNIPHY3_UNIPHY_MACRO_CNTL_RESERVED19_BASE_IDX 2
+#define regDCIO_UNIPHY3_UNIPHY_MACRO_CNTL_RESERVED20 0x2bc4
+#define regDCIO_UNIPHY3_UNIPHY_MACRO_CNTL_RESERVED20_BASE_IDX 2
+#define regDCIO_UNIPHY3_UNIPHY_MACRO_CNTL_RESERVED21 0x2bc5
+#define regDCIO_UNIPHY3_UNIPHY_MACRO_CNTL_RESERVED21_BASE_IDX 2
+#define regDCIO_UNIPHY3_UNIPHY_MACRO_CNTL_RESERVED22 0x2bc6
+#define regDCIO_UNIPHY3_UNIPHY_MACRO_CNTL_RESERVED22_BASE_IDX 2
+#define regDCIO_UNIPHY3_UNIPHY_MACRO_CNTL_RESERVED23 0x2bc7
+#define regDCIO_UNIPHY3_UNIPHY_MACRO_CNTL_RESERVED23_BASE_IDX 2
+#define regDCIO_UNIPHY3_UNIPHY_MACRO_CNTL_RESERVED24 0x2bc8
+#define regDCIO_UNIPHY3_UNIPHY_MACRO_CNTL_RESERVED24_BASE_IDX 2
+#define regDCIO_UNIPHY3_UNIPHY_MACRO_CNTL_RESERVED25 0x2bc9
+#define regDCIO_UNIPHY3_UNIPHY_MACRO_CNTL_RESERVED25_BASE_IDX 2
+#define regDCIO_UNIPHY3_UNIPHY_MACRO_CNTL_RESERVED26 0x2bca
+#define regDCIO_UNIPHY3_UNIPHY_MACRO_CNTL_RESERVED26_BASE_IDX 2
+#define regDCIO_UNIPHY3_UNIPHY_MACRO_CNTL_RESERVED27 0x2bcb
+#define regDCIO_UNIPHY3_UNIPHY_MACRO_CNTL_RESERVED27_BASE_IDX 2
+#define regDCIO_UNIPHY3_UNIPHY_MACRO_CNTL_RESERVED28 0x2bcc
+#define regDCIO_UNIPHY3_UNIPHY_MACRO_CNTL_RESERVED28_BASE_IDX 2
+#define regDCIO_UNIPHY3_UNIPHY_MACRO_CNTL_RESERVED29 0x2bcd
+#define regDCIO_UNIPHY3_UNIPHY_MACRO_CNTL_RESERVED29_BASE_IDX 2
+#define regDCIO_UNIPHY3_UNIPHY_MACRO_CNTL_RESERVED30 0x2bce
+#define regDCIO_UNIPHY3_UNIPHY_MACRO_CNTL_RESERVED30_BASE_IDX 2
+#define regDCIO_UNIPHY3_UNIPHY_MACRO_CNTL_RESERVED31 0x2bcf
+#define regDCIO_UNIPHY3_UNIPHY_MACRO_CNTL_RESERVED31_BASE_IDX 2
+#define regDCIO_UNIPHY3_UNIPHY_MACRO_CNTL_RESERVED32 0x2bd0
+#define regDCIO_UNIPHY3_UNIPHY_MACRO_CNTL_RESERVED32_BASE_IDX 2
+#define regDCIO_UNIPHY3_UNIPHY_MACRO_CNTL_RESERVED33 0x2bd1
+#define regDCIO_UNIPHY3_UNIPHY_MACRO_CNTL_RESERVED33_BASE_IDX 2
+#define regDCIO_UNIPHY3_UNIPHY_MACRO_CNTL_RESERVED34 0x2bd2
+#define regDCIO_UNIPHY3_UNIPHY_MACRO_CNTL_RESERVED34_BASE_IDX 2
+#define regDCIO_UNIPHY3_UNIPHY_MACRO_CNTL_RESERVED35 0x2bd3
+#define regDCIO_UNIPHY3_UNIPHY_MACRO_CNTL_RESERVED35_BASE_IDX 2
+#define regDCIO_UNIPHY3_UNIPHY_MACRO_CNTL_RESERVED36 0x2bd4
+#define regDCIO_UNIPHY3_UNIPHY_MACRO_CNTL_RESERVED36_BASE_IDX 2
+#define regDCIO_UNIPHY3_UNIPHY_MACRO_CNTL_RESERVED37 0x2bd5
+#define regDCIO_UNIPHY3_UNIPHY_MACRO_CNTL_RESERVED37_BASE_IDX 2
+#define regDCIO_UNIPHY3_UNIPHY_MACRO_CNTL_RESERVED38 0x2bd6
+#define regDCIO_UNIPHY3_UNIPHY_MACRO_CNTL_RESERVED38_BASE_IDX 2
+#define regDCIO_UNIPHY3_UNIPHY_MACRO_CNTL_RESERVED39 0x2bd7
+#define regDCIO_UNIPHY3_UNIPHY_MACRO_CNTL_RESERVED39_BASE_IDX 2
+#define regDCIO_UNIPHY3_UNIPHY_MACRO_CNTL_RESERVED40 0x2bd8
+#define regDCIO_UNIPHY3_UNIPHY_MACRO_CNTL_RESERVED40_BASE_IDX 2
+#define regDCIO_UNIPHY3_UNIPHY_MACRO_CNTL_RESERVED41 0x2bd9
+#define regDCIO_UNIPHY3_UNIPHY_MACRO_CNTL_RESERVED41_BASE_IDX 2
+#define regDCIO_UNIPHY3_UNIPHY_MACRO_CNTL_RESERVED42 0x2bda
+#define regDCIO_UNIPHY3_UNIPHY_MACRO_CNTL_RESERVED42_BASE_IDX 2
+#define regDCIO_UNIPHY3_UNIPHY_MACRO_CNTL_RESERVED43 0x2bdb
+#define regDCIO_UNIPHY3_UNIPHY_MACRO_CNTL_RESERVED43_BASE_IDX 2
+#define regDCIO_UNIPHY3_UNIPHY_MACRO_CNTL_RESERVED44 0x2bdc
+#define regDCIO_UNIPHY3_UNIPHY_MACRO_CNTL_RESERVED44_BASE_IDX 2
+#define regDCIO_UNIPHY3_UNIPHY_MACRO_CNTL_RESERVED45 0x2bdd
+#define regDCIO_UNIPHY3_UNIPHY_MACRO_CNTL_RESERVED45_BASE_IDX 2
+#define regDCIO_UNIPHY3_UNIPHY_MACRO_CNTL_RESERVED46 0x2bde
+#define regDCIO_UNIPHY3_UNIPHY_MACRO_CNTL_RESERVED46_BASE_IDX 2
+#define regDCIO_UNIPHY3_UNIPHY_MACRO_CNTL_RESERVED47 0x2bdf
+#define regDCIO_UNIPHY3_UNIPHY_MACRO_CNTL_RESERVED47_BASE_IDX 2
+#define regDCIO_UNIPHY3_UNIPHY_MACRO_CNTL_RESERVED48 0x2be0
+#define regDCIO_UNIPHY3_UNIPHY_MACRO_CNTL_RESERVED48_BASE_IDX 2
+#define regDCIO_UNIPHY3_UNIPHY_MACRO_CNTL_RESERVED49 0x2be1
+#define regDCIO_UNIPHY3_UNIPHY_MACRO_CNTL_RESERVED49_BASE_IDX 2
+#define regDCIO_UNIPHY3_UNIPHY_MACRO_CNTL_RESERVED50 0x2be2
+#define regDCIO_UNIPHY3_UNIPHY_MACRO_CNTL_RESERVED50_BASE_IDX 2
+#define regDCIO_UNIPHY3_UNIPHY_MACRO_CNTL_RESERVED51 0x2be3
+#define regDCIO_UNIPHY3_UNIPHY_MACRO_CNTL_RESERVED51_BASE_IDX 2
+#define regDCIO_UNIPHY3_UNIPHY_MACRO_CNTL_RESERVED52 0x2be4
+#define regDCIO_UNIPHY3_UNIPHY_MACRO_CNTL_RESERVED52_BASE_IDX 2
+#define regDCIO_UNIPHY3_UNIPHY_MACRO_CNTL_RESERVED53 0x2be5
+#define regDCIO_UNIPHY3_UNIPHY_MACRO_CNTL_RESERVED53_BASE_IDX 2
+#define regDCIO_UNIPHY3_UNIPHY_MACRO_CNTL_RESERVED54 0x2be6
+#define regDCIO_UNIPHY3_UNIPHY_MACRO_CNTL_RESERVED54_BASE_IDX 2
+#define regDCIO_UNIPHY3_UNIPHY_MACRO_CNTL_RESERVED55 0x2be7
+#define regDCIO_UNIPHY3_UNIPHY_MACRO_CNTL_RESERVED55_BASE_IDX 2
+#define regDCIO_UNIPHY3_UNIPHY_MACRO_CNTL_RESERVED56 0x2be8
+#define regDCIO_UNIPHY3_UNIPHY_MACRO_CNTL_RESERVED56_BASE_IDX 2
+#define regDCIO_UNIPHY3_UNIPHY_MACRO_CNTL_RESERVED57 0x2be9
+#define regDCIO_UNIPHY3_UNIPHY_MACRO_CNTL_RESERVED57_BASE_IDX 2
+
+
+// addressBlock: dce_dc_dcio_dcio_uniphy4_dispdec
+// base address: 0xd80
+#define regDCIO_UNIPHY4_UNIPHY_MACRO_CNTL_RESERVED0 0x2c88
+#define regDCIO_UNIPHY4_UNIPHY_MACRO_CNTL_RESERVED0_BASE_IDX 2
+#define regDCIO_UNIPHY4_UNIPHY_MACRO_CNTL_RESERVED1 0x2c89
+#define regDCIO_UNIPHY4_UNIPHY_MACRO_CNTL_RESERVED1_BASE_IDX 2
+#define regDCIO_UNIPHY4_UNIPHY_MACRO_CNTL_RESERVED2 0x2c8a
+#define regDCIO_UNIPHY4_UNIPHY_MACRO_CNTL_RESERVED2_BASE_IDX 2
+#define regDCIO_UNIPHY4_UNIPHY_MACRO_CNTL_RESERVED3 0x2c8b
+#define regDCIO_UNIPHY4_UNIPHY_MACRO_CNTL_RESERVED3_BASE_IDX 2
+#define regDCIO_UNIPHY4_UNIPHY_MACRO_CNTL_RESERVED4 0x2c8c
+#define regDCIO_UNIPHY4_UNIPHY_MACRO_CNTL_RESERVED4_BASE_IDX 2
+#define regDCIO_UNIPHY4_UNIPHY_MACRO_CNTL_RESERVED5 0x2c8d
+#define regDCIO_UNIPHY4_UNIPHY_MACRO_CNTL_RESERVED5_BASE_IDX 2
+#define regDCIO_UNIPHY4_UNIPHY_MACRO_CNTL_RESERVED6 0x2c8e
+#define regDCIO_UNIPHY4_UNIPHY_MACRO_CNTL_RESERVED6_BASE_IDX 2
+#define regDCIO_UNIPHY4_UNIPHY_MACRO_CNTL_RESERVED7 0x2c8f
+#define regDCIO_UNIPHY4_UNIPHY_MACRO_CNTL_RESERVED7_BASE_IDX 2
+#define regDCIO_UNIPHY4_UNIPHY_MACRO_CNTL_RESERVED8 0x2c90
+#define regDCIO_UNIPHY4_UNIPHY_MACRO_CNTL_RESERVED8_BASE_IDX 2
+#define regDCIO_UNIPHY4_UNIPHY_MACRO_CNTL_RESERVED9 0x2c91
+#define regDCIO_UNIPHY4_UNIPHY_MACRO_CNTL_RESERVED9_BASE_IDX 2
+#define regDCIO_UNIPHY4_UNIPHY_MACRO_CNTL_RESERVED10 0x2c92
+#define regDCIO_UNIPHY4_UNIPHY_MACRO_CNTL_RESERVED10_BASE_IDX 2
+#define regDCIO_UNIPHY4_UNIPHY_MACRO_CNTL_RESERVED11 0x2c93
+#define regDCIO_UNIPHY4_UNIPHY_MACRO_CNTL_RESERVED11_BASE_IDX 2
+#define regDCIO_UNIPHY4_UNIPHY_MACRO_CNTL_RESERVED12 0x2c94
+#define regDCIO_UNIPHY4_UNIPHY_MACRO_CNTL_RESERVED12_BASE_IDX 2
+#define regDCIO_UNIPHY4_UNIPHY_MACRO_CNTL_RESERVED13 0x2c95
+#define regDCIO_UNIPHY4_UNIPHY_MACRO_CNTL_RESERVED13_BASE_IDX 2
+#define regDCIO_UNIPHY4_UNIPHY_MACRO_CNTL_RESERVED14 0x2c96
+#define regDCIO_UNIPHY4_UNIPHY_MACRO_CNTL_RESERVED14_BASE_IDX 2
+#define regDCIO_UNIPHY4_UNIPHY_MACRO_CNTL_RESERVED15 0x2c97
+#define regDCIO_UNIPHY4_UNIPHY_MACRO_CNTL_RESERVED15_BASE_IDX 2
+#define regDCIO_UNIPHY4_UNIPHY_MACRO_CNTL_RESERVED16 0x2c98
+#define regDCIO_UNIPHY4_UNIPHY_MACRO_CNTL_RESERVED16_BASE_IDX 2
+#define regDCIO_UNIPHY4_UNIPHY_MACRO_CNTL_RESERVED17 0x2c99
+#define regDCIO_UNIPHY4_UNIPHY_MACRO_CNTL_RESERVED17_BASE_IDX 2
+#define regDCIO_UNIPHY4_UNIPHY_MACRO_CNTL_RESERVED18 0x2c9a
+#define regDCIO_UNIPHY4_UNIPHY_MACRO_CNTL_RESERVED18_BASE_IDX 2
+#define regDCIO_UNIPHY4_UNIPHY_MACRO_CNTL_RESERVED19 0x2c9b
+#define regDCIO_UNIPHY4_UNIPHY_MACRO_CNTL_RESERVED19_BASE_IDX 2
+#define regDCIO_UNIPHY4_UNIPHY_MACRO_CNTL_RESERVED20 0x2c9c
+#define regDCIO_UNIPHY4_UNIPHY_MACRO_CNTL_RESERVED20_BASE_IDX 2
+#define regDCIO_UNIPHY4_UNIPHY_MACRO_CNTL_RESERVED21 0x2c9d
+#define regDCIO_UNIPHY4_UNIPHY_MACRO_CNTL_RESERVED21_BASE_IDX 2
+#define regDCIO_UNIPHY4_UNIPHY_MACRO_CNTL_RESERVED22 0x2c9e
+#define regDCIO_UNIPHY4_UNIPHY_MACRO_CNTL_RESERVED22_BASE_IDX 2
+#define regDCIO_UNIPHY4_UNIPHY_MACRO_CNTL_RESERVED23 0x2c9f
+#define regDCIO_UNIPHY4_UNIPHY_MACRO_CNTL_RESERVED23_BASE_IDX 2
+#define regDCIO_UNIPHY4_UNIPHY_MACRO_CNTL_RESERVED24 0x2ca0
+#define regDCIO_UNIPHY4_UNIPHY_MACRO_CNTL_RESERVED24_BASE_IDX 2
+#define regDCIO_UNIPHY4_UNIPHY_MACRO_CNTL_RESERVED25 0x2ca1
+#define regDCIO_UNIPHY4_UNIPHY_MACRO_CNTL_RESERVED25_BASE_IDX 2
+#define regDCIO_UNIPHY4_UNIPHY_MACRO_CNTL_RESERVED26 0x2ca2
+#define regDCIO_UNIPHY4_UNIPHY_MACRO_CNTL_RESERVED26_BASE_IDX 2
+#define regDCIO_UNIPHY4_UNIPHY_MACRO_CNTL_RESERVED27 0x2ca3
+#define regDCIO_UNIPHY4_UNIPHY_MACRO_CNTL_RESERVED27_BASE_IDX 2
+#define regDCIO_UNIPHY4_UNIPHY_MACRO_CNTL_RESERVED28 0x2ca4
+#define regDCIO_UNIPHY4_UNIPHY_MACRO_CNTL_RESERVED28_BASE_IDX 2
+#define regDCIO_UNIPHY4_UNIPHY_MACRO_CNTL_RESERVED29 0x2ca5
+#define regDCIO_UNIPHY4_UNIPHY_MACRO_CNTL_RESERVED29_BASE_IDX 2
+#define regDCIO_UNIPHY4_UNIPHY_MACRO_CNTL_RESERVED30 0x2ca6
+#define regDCIO_UNIPHY4_UNIPHY_MACRO_CNTL_RESERVED30_BASE_IDX 2
+#define regDCIO_UNIPHY4_UNIPHY_MACRO_CNTL_RESERVED31 0x2ca7
+#define regDCIO_UNIPHY4_UNIPHY_MACRO_CNTL_RESERVED31_BASE_IDX 2
+#define regDCIO_UNIPHY4_UNIPHY_MACRO_CNTL_RESERVED32 0x2ca8
+#define regDCIO_UNIPHY4_UNIPHY_MACRO_CNTL_RESERVED32_BASE_IDX 2
+#define regDCIO_UNIPHY4_UNIPHY_MACRO_CNTL_RESERVED33 0x2ca9
+#define regDCIO_UNIPHY4_UNIPHY_MACRO_CNTL_RESERVED33_BASE_IDX 2
+#define regDCIO_UNIPHY4_UNIPHY_MACRO_CNTL_RESERVED34 0x2caa
+#define regDCIO_UNIPHY4_UNIPHY_MACRO_CNTL_RESERVED34_BASE_IDX 2
+#define regDCIO_UNIPHY4_UNIPHY_MACRO_CNTL_RESERVED35 0x2cab
+#define regDCIO_UNIPHY4_UNIPHY_MACRO_CNTL_RESERVED35_BASE_IDX 2
+#define regDCIO_UNIPHY4_UNIPHY_MACRO_CNTL_RESERVED36 0x2cac
+#define regDCIO_UNIPHY4_UNIPHY_MACRO_CNTL_RESERVED36_BASE_IDX 2
+#define regDCIO_UNIPHY4_UNIPHY_MACRO_CNTL_RESERVED37 0x2cad
+#define regDCIO_UNIPHY4_UNIPHY_MACRO_CNTL_RESERVED37_BASE_IDX 2
+#define regDCIO_UNIPHY4_UNIPHY_MACRO_CNTL_RESERVED38 0x2cae
+#define regDCIO_UNIPHY4_UNIPHY_MACRO_CNTL_RESERVED38_BASE_IDX 2
+#define regDCIO_UNIPHY4_UNIPHY_MACRO_CNTL_RESERVED39 0x2caf
+#define regDCIO_UNIPHY4_UNIPHY_MACRO_CNTL_RESERVED39_BASE_IDX 2
+#define regDCIO_UNIPHY4_UNIPHY_MACRO_CNTL_RESERVED40 0x2cb0
+#define regDCIO_UNIPHY4_UNIPHY_MACRO_CNTL_RESERVED40_BASE_IDX 2
+#define regDCIO_UNIPHY4_UNIPHY_MACRO_CNTL_RESERVED41 0x2cb1
+#define regDCIO_UNIPHY4_UNIPHY_MACRO_CNTL_RESERVED41_BASE_IDX 2
+#define regDCIO_UNIPHY4_UNIPHY_MACRO_CNTL_RESERVED42 0x2cb2
+#define regDCIO_UNIPHY4_UNIPHY_MACRO_CNTL_RESERVED42_BASE_IDX 2
+#define regDCIO_UNIPHY4_UNIPHY_MACRO_CNTL_RESERVED43 0x2cb3
+#define regDCIO_UNIPHY4_UNIPHY_MACRO_CNTL_RESERVED43_BASE_IDX 2
+#define regDCIO_UNIPHY4_UNIPHY_MACRO_CNTL_RESERVED44 0x2cb4
+#define regDCIO_UNIPHY4_UNIPHY_MACRO_CNTL_RESERVED44_BASE_IDX 2
+#define regDCIO_UNIPHY4_UNIPHY_MACRO_CNTL_RESERVED45 0x2cb5
+#define regDCIO_UNIPHY4_UNIPHY_MACRO_CNTL_RESERVED45_BASE_IDX 2
+#define regDCIO_UNIPHY4_UNIPHY_MACRO_CNTL_RESERVED46 0x2cb6
+#define regDCIO_UNIPHY4_UNIPHY_MACRO_CNTL_RESERVED46_BASE_IDX 2
+#define regDCIO_UNIPHY4_UNIPHY_MACRO_CNTL_RESERVED47 0x2cb7
+#define regDCIO_UNIPHY4_UNIPHY_MACRO_CNTL_RESERVED47_BASE_IDX 2
+#define regDCIO_UNIPHY4_UNIPHY_MACRO_CNTL_RESERVED48 0x2cb8
+#define regDCIO_UNIPHY4_UNIPHY_MACRO_CNTL_RESERVED48_BASE_IDX 2
+#define regDCIO_UNIPHY4_UNIPHY_MACRO_CNTL_RESERVED49 0x2cb9
+#define regDCIO_UNIPHY4_UNIPHY_MACRO_CNTL_RESERVED49_BASE_IDX 2
+#define regDCIO_UNIPHY4_UNIPHY_MACRO_CNTL_RESERVED50 0x2cba
+#define regDCIO_UNIPHY4_UNIPHY_MACRO_CNTL_RESERVED50_BASE_IDX 2
+#define regDCIO_UNIPHY4_UNIPHY_MACRO_CNTL_RESERVED51 0x2cbb
+#define regDCIO_UNIPHY4_UNIPHY_MACRO_CNTL_RESERVED51_BASE_IDX 2
+#define regDCIO_UNIPHY4_UNIPHY_MACRO_CNTL_RESERVED52 0x2cbc
+#define regDCIO_UNIPHY4_UNIPHY_MACRO_CNTL_RESERVED52_BASE_IDX 2
+#define regDCIO_UNIPHY4_UNIPHY_MACRO_CNTL_RESERVED53 0x2cbd
+#define regDCIO_UNIPHY4_UNIPHY_MACRO_CNTL_RESERVED53_BASE_IDX 2
+#define regDCIO_UNIPHY4_UNIPHY_MACRO_CNTL_RESERVED54 0x2cbe
+#define regDCIO_UNIPHY4_UNIPHY_MACRO_CNTL_RESERVED54_BASE_IDX 2
+#define regDCIO_UNIPHY4_UNIPHY_MACRO_CNTL_RESERVED55 0x2cbf
+#define regDCIO_UNIPHY4_UNIPHY_MACRO_CNTL_RESERVED55_BASE_IDX 2
+#define regDCIO_UNIPHY4_UNIPHY_MACRO_CNTL_RESERVED56 0x2cc0
+#define regDCIO_UNIPHY4_UNIPHY_MACRO_CNTL_RESERVED56_BASE_IDX 2
+#define regDCIO_UNIPHY4_UNIPHY_MACRO_CNTL_RESERVED57 0x2cc1
+#define regDCIO_UNIPHY4_UNIPHY_MACRO_CNTL_RESERVED57_BASE_IDX 2
+
+
+// addressBlock: dce_dc_pwrseq0_dispdec_pwrseq_dispdec
+// base address: 0x0
+#define regPWRSEQ0_DC_GPIO_PWRSEQ_EN 0x2f10
+#define regPWRSEQ0_DC_GPIO_PWRSEQ_EN_BASE_IDX 2
+#define regPWRSEQ0_DC_GPIO_PWRSEQ_CTRL 0x2f11
+#define regPWRSEQ0_DC_GPIO_PWRSEQ_CTRL_BASE_IDX 2
+#define regPWRSEQ0_DC_GPIO_PWRSEQ_MASK 0x2f12
+#define regPWRSEQ0_DC_GPIO_PWRSEQ_MASK_BASE_IDX 2
+#define regPWRSEQ0_DC_GPIO_PWRSEQ_A_Y 0x2f13
+#define regPWRSEQ0_DC_GPIO_PWRSEQ_A_Y_BASE_IDX 2
+#define regPWRSEQ0_PANEL_PWRSEQ_CNTL 0x2f14
+#define regPWRSEQ0_PANEL_PWRSEQ_CNTL_BASE_IDX 2
+#define regPWRSEQ0_PANEL_PWRSEQ_STATE 0x2f15
+#define regPWRSEQ0_PANEL_PWRSEQ_STATE_BASE_IDX 2
+#define regPWRSEQ0_PANEL_PWRSEQ_DELAY1 0x2f16
+#define regPWRSEQ0_PANEL_PWRSEQ_DELAY1_BASE_IDX 2
+#define regPWRSEQ0_PANEL_PWRSEQ_DELAY2 0x2f17
+#define regPWRSEQ0_PANEL_PWRSEQ_DELAY2_BASE_IDX 2
+#define regPWRSEQ0_PANEL_PWRSEQ_REF_DIV1 0x2f18
+#define regPWRSEQ0_PANEL_PWRSEQ_REF_DIV1_BASE_IDX 2
+#define regPWRSEQ0_BL_PWM_CNTL 0x2f19
+#define regPWRSEQ0_BL_PWM_CNTL_BASE_IDX 2
+#define regPWRSEQ0_BL_PWM_CNTL2 0x2f1a
+#define regPWRSEQ0_BL_PWM_CNTL2_BASE_IDX 2
+#define regPWRSEQ0_BL_PWM_PERIOD_CNTL 0x2f1b
+#define regPWRSEQ0_BL_PWM_PERIOD_CNTL_BASE_IDX 2
+#define regPWRSEQ0_BL_PWM_GRP1_REG_LOCK 0x2f1c
+#define regPWRSEQ0_BL_PWM_GRP1_REG_LOCK_BASE_IDX 2
+#define regPWRSEQ0_PANEL_PWRSEQ_REF_DIV2 0x2f1d
+#define regPWRSEQ0_PANEL_PWRSEQ_REF_DIV2_BASE_IDX 2
+#define regPWRSEQ0_PWRSEQ_SPARE 0x2f21
+#define regPWRSEQ0_PWRSEQ_SPARE_BASE_IDX 2
+
+
+// addressBlock: dce_dc_pwrseq1_dispdec_pwrseq_dispdec
+// base address: 0x1b0
+#define regPWRSEQ1_DC_GPIO_PWRSEQ_EN 0x2f7c
+#define regPWRSEQ1_DC_GPIO_PWRSEQ_EN_BASE_IDX 2
+#define regPWRSEQ1_DC_GPIO_PWRSEQ_CTRL 0x2f7d
+#define regPWRSEQ1_DC_GPIO_PWRSEQ_CTRL_BASE_IDX 2
+#define regPWRSEQ1_DC_GPIO_PWRSEQ_MASK 0x2f7e
+#define regPWRSEQ1_DC_GPIO_PWRSEQ_MASK_BASE_IDX 2
+#define regPWRSEQ1_DC_GPIO_PWRSEQ_A_Y 0x2f7f
+#define regPWRSEQ1_DC_GPIO_PWRSEQ_A_Y_BASE_IDX 2
+#define regPWRSEQ1_PANEL_PWRSEQ_CNTL 0x2f80
+#define regPWRSEQ1_PANEL_PWRSEQ_CNTL_BASE_IDX 2
+#define regPWRSEQ1_PANEL_PWRSEQ_STATE 0x2f81
+#define regPWRSEQ1_PANEL_PWRSEQ_STATE_BASE_IDX 2
+#define regPWRSEQ1_PANEL_PWRSEQ_DELAY1 0x2f82
+#define regPWRSEQ1_PANEL_PWRSEQ_DELAY1_BASE_IDX 2
+#define regPWRSEQ1_PANEL_PWRSEQ_DELAY2 0x2f83
+#define regPWRSEQ1_PANEL_PWRSEQ_DELAY2_BASE_IDX 2
+#define regPWRSEQ1_PANEL_PWRSEQ_REF_DIV1 0x2f84
+#define regPWRSEQ1_PANEL_PWRSEQ_REF_DIV1_BASE_IDX 2
+#define regPWRSEQ1_BL_PWM_CNTL 0x2f85
+#define regPWRSEQ1_BL_PWM_CNTL_BASE_IDX 2
+#define regPWRSEQ1_BL_PWM_CNTL2 0x2f86
+#define regPWRSEQ1_BL_PWM_CNTL2_BASE_IDX 2
+#define regPWRSEQ1_BL_PWM_PERIOD_CNTL 0x2f87
+#define regPWRSEQ1_BL_PWM_PERIOD_CNTL_BASE_IDX 2
+#define regPWRSEQ1_BL_PWM_GRP1_REG_LOCK 0x2f88
+#define regPWRSEQ1_BL_PWM_GRP1_REG_LOCK_BASE_IDX 2
+#define regPWRSEQ1_PANEL_PWRSEQ_REF_DIV2 0x2f89
+#define regPWRSEQ1_PANEL_PWRSEQ_REF_DIV2_BASE_IDX 2
+#define regPWRSEQ1_PWRSEQ_SPARE 0x2f8d
+#define regPWRSEQ1_PWRSEQ_SPARE_BASE_IDX 2
+
+
+// addressBlock: dce_dc_dsc0_dispdec_dscc_dispdec
+// base address: 0x0
+#define regDSCC0_DSCC_CONFIG0 0x300a
+#define regDSCC0_DSCC_CONFIG0_BASE_IDX 2
+#define regDSCC0_DSCC_CONFIG1 0x300b
+#define regDSCC0_DSCC_CONFIG1_BASE_IDX 2
+#define regDSCC0_DSCC_STATUS 0x300c
+#define regDSCC0_DSCC_STATUS_BASE_IDX 2
+#define regDSCC0_DSCC_INTERRUPT_CONTROL_STATUS 0x300d
+#define regDSCC0_DSCC_INTERRUPT_CONTROL_STATUS_BASE_IDX 2
+#define regDSCC0_DSCC_PPS_CONFIG0 0x300e
+#define regDSCC0_DSCC_PPS_CONFIG0_BASE_IDX 2
+#define regDSCC0_DSCC_PPS_CONFIG1 0x300f
+#define regDSCC0_DSCC_PPS_CONFIG1_BASE_IDX 2
+#define regDSCC0_DSCC_PPS_CONFIG2 0x3010
+#define regDSCC0_DSCC_PPS_CONFIG2_BASE_IDX 2
+#define regDSCC0_DSCC_PPS_CONFIG3 0x3011
+#define regDSCC0_DSCC_PPS_CONFIG3_BASE_IDX 2
+#define regDSCC0_DSCC_PPS_CONFIG4 0x3012
+#define regDSCC0_DSCC_PPS_CONFIG4_BASE_IDX 2
+#define regDSCC0_DSCC_PPS_CONFIG5 0x3013
+#define regDSCC0_DSCC_PPS_CONFIG5_BASE_IDX 2
+#define regDSCC0_DSCC_PPS_CONFIG6 0x3014
+#define regDSCC0_DSCC_PPS_CONFIG6_BASE_IDX 2
+#define regDSCC0_DSCC_PPS_CONFIG7 0x3015
+#define regDSCC0_DSCC_PPS_CONFIG7_BASE_IDX 2
+#define regDSCC0_DSCC_PPS_CONFIG8 0x3016
+#define regDSCC0_DSCC_PPS_CONFIG8_BASE_IDX 2
+#define regDSCC0_DSCC_PPS_CONFIG9 0x3017
+#define regDSCC0_DSCC_PPS_CONFIG9_BASE_IDX 2
+#define regDSCC0_DSCC_PPS_CONFIG10 0x3018
+#define regDSCC0_DSCC_PPS_CONFIG10_BASE_IDX 2
+#define regDSCC0_DSCC_PPS_CONFIG11 0x3019
+#define regDSCC0_DSCC_PPS_CONFIG11_BASE_IDX 2
+#define regDSCC0_DSCC_PPS_CONFIG12 0x301a
+#define regDSCC0_DSCC_PPS_CONFIG12_BASE_IDX 2
+#define regDSCC0_DSCC_PPS_CONFIG13 0x301b
+#define regDSCC0_DSCC_PPS_CONFIG13_BASE_IDX 2
+#define regDSCC0_DSCC_PPS_CONFIG14 0x301c
+#define regDSCC0_DSCC_PPS_CONFIG14_BASE_IDX 2
+#define regDSCC0_DSCC_PPS_CONFIG15 0x301d
+#define regDSCC0_DSCC_PPS_CONFIG15_BASE_IDX 2
+#define regDSCC0_DSCC_PPS_CONFIG16 0x301e
+#define regDSCC0_DSCC_PPS_CONFIG16_BASE_IDX 2
+#define regDSCC0_DSCC_PPS_CONFIG17 0x301f
+#define regDSCC0_DSCC_PPS_CONFIG17_BASE_IDX 2
+#define regDSCC0_DSCC_PPS_CONFIG18 0x3020
+#define regDSCC0_DSCC_PPS_CONFIG18_BASE_IDX 2
+#define regDSCC0_DSCC_PPS_CONFIG19 0x3021
+#define regDSCC0_DSCC_PPS_CONFIG19_BASE_IDX 2
+#define regDSCC0_DSCC_PPS_CONFIG20 0x3022
+#define regDSCC0_DSCC_PPS_CONFIG20_BASE_IDX 2
+#define regDSCC0_DSCC_PPS_CONFIG21 0x3023
+#define regDSCC0_DSCC_PPS_CONFIG21_BASE_IDX 2
+#define regDSCC0_DSCC_PPS_CONFIG22 0x3024
+#define regDSCC0_DSCC_PPS_CONFIG22_BASE_IDX 2
+#define regDSCC0_DSCC_MEM_POWER_CONTROL 0x3025
+#define regDSCC0_DSCC_MEM_POWER_CONTROL_BASE_IDX 2
+#define regDSCC0_DSCC_R_Y_SQUARED_ERROR_LOWER 0x3026
+#define regDSCC0_DSCC_R_Y_SQUARED_ERROR_LOWER_BASE_IDX 2
+#define regDSCC0_DSCC_R_Y_SQUARED_ERROR_UPPER 0x3027
+#define regDSCC0_DSCC_R_Y_SQUARED_ERROR_UPPER_BASE_IDX 2
+#define regDSCC0_DSCC_G_CB_SQUARED_ERROR_LOWER 0x3028
+#define regDSCC0_DSCC_G_CB_SQUARED_ERROR_LOWER_BASE_IDX 2
+#define regDSCC0_DSCC_G_CB_SQUARED_ERROR_UPPER 0x3029
+#define regDSCC0_DSCC_G_CB_SQUARED_ERROR_UPPER_BASE_IDX 2
+#define regDSCC0_DSCC_B_CR_SQUARED_ERROR_LOWER 0x302a
+#define regDSCC0_DSCC_B_CR_SQUARED_ERROR_LOWER_BASE_IDX 2
+#define regDSCC0_DSCC_B_CR_SQUARED_ERROR_UPPER 0x302b
+#define regDSCC0_DSCC_B_CR_SQUARED_ERROR_UPPER_BASE_IDX 2
+#define regDSCC0_DSCC_MAX_ABS_ERROR0 0x302c
+#define regDSCC0_DSCC_MAX_ABS_ERROR0_BASE_IDX 2
+#define regDSCC0_DSCC_MAX_ABS_ERROR1 0x302d
+#define regDSCC0_DSCC_MAX_ABS_ERROR1_BASE_IDX 2
+#define regDSCC0_DSCC_RATE_BUFFER0_MAX_FULLNESS_LEVEL 0x302e
+#define regDSCC0_DSCC_RATE_BUFFER0_MAX_FULLNESS_LEVEL_BASE_IDX 2
+#define regDSCC0_DSCC_RATE_BUFFER1_MAX_FULLNESS_LEVEL 0x302f
+#define regDSCC0_DSCC_RATE_BUFFER1_MAX_FULLNESS_LEVEL_BASE_IDX 2
+#define regDSCC0_DSCC_RATE_BUFFER2_MAX_FULLNESS_LEVEL 0x3030
+#define regDSCC0_DSCC_RATE_BUFFER2_MAX_FULLNESS_LEVEL_BASE_IDX 2
+#define regDSCC0_DSCC_RATE_BUFFER3_MAX_FULLNESS_LEVEL 0x3031
+#define regDSCC0_DSCC_RATE_BUFFER3_MAX_FULLNESS_LEVEL_BASE_IDX 2
+#define regDSCC0_DSCC_RATE_CONTROL_BUFFER0_MAX_FULLNESS_LEVEL 0x3032
+#define regDSCC0_DSCC_RATE_CONTROL_BUFFER0_MAX_FULLNESS_LEVEL_BASE_IDX 2
+#define regDSCC0_DSCC_RATE_CONTROL_BUFFER1_MAX_FULLNESS_LEVEL 0x3033
+#define regDSCC0_DSCC_RATE_CONTROL_BUFFER1_MAX_FULLNESS_LEVEL_BASE_IDX 2
+#define regDSCC0_DSCC_RATE_CONTROL_BUFFER2_MAX_FULLNESS_LEVEL 0x3034
+#define regDSCC0_DSCC_RATE_CONTROL_BUFFER2_MAX_FULLNESS_LEVEL_BASE_IDX 2
+#define regDSCC0_DSCC_RATE_CONTROL_BUFFER3_MAX_FULLNESS_LEVEL 0x3035
+#define regDSCC0_DSCC_RATE_CONTROL_BUFFER3_MAX_FULLNESS_LEVEL_BASE_IDX 2
+#define regDSCC0_DSCC_TEST_DEBUG_BUS_ROTATE 0x303a
+#define regDSCC0_DSCC_TEST_DEBUG_BUS_ROTATE_BASE_IDX 2
+
+
+// addressBlock: dce_dc_dsc0_dispdec_dsccif_dispdec
+// base address: 0x0
+#define regDSCCIF0_DSCCIF_CONFIG0 0x3005
+#define regDSCCIF0_DSCCIF_CONFIG0_BASE_IDX 2
+#define regDSCCIF0_DSCCIF_CONFIG1 0x3006
+#define regDSCCIF0_DSCCIF_CONFIG1_BASE_IDX 2
+
+
+// addressBlock: dce_dc_dsc0_dispdec_dsc_top_dispdec
+// base address: 0x0
+#define regDSC_TOP0_DSC_TOP_CONTROL 0x3000
+#define regDSC_TOP0_DSC_TOP_CONTROL_BASE_IDX 2
+#define regDSC_TOP0_DSC_DEBUG_CONTROL 0x3001
+#define regDSC_TOP0_DSC_DEBUG_CONTROL_BASE_IDX 2
+
+
+// addressBlock: dce_dc_dsc0_dispdec_dsc_dcperfmon_dc_perfmon_dispdec
+// base address: 0xc140
+#define regDC_PERFMON19_PERFCOUNTER_CNTL 0x3050
+#define regDC_PERFMON19_PERFCOUNTER_CNTL_BASE_IDX 2
+#define regDC_PERFMON19_PERFCOUNTER_CNTL2 0x3051
+#define regDC_PERFMON19_PERFCOUNTER_CNTL2_BASE_IDX 2
+#define regDC_PERFMON19_PERFCOUNTER_STATE 0x3052
+#define regDC_PERFMON19_PERFCOUNTER_STATE_BASE_IDX 2
+#define regDC_PERFMON19_PERFMON_CNTL 0x3053
+#define regDC_PERFMON19_PERFMON_CNTL_BASE_IDX 2
+#define regDC_PERFMON19_PERFMON_CNTL2 0x3054
+#define regDC_PERFMON19_PERFMON_CNTL2_BASE_IDX 2
+#define regDC_PERFMON19_PERFMON_CVALUE_INT_MISC 0x3055
+#define regDC_PERFMON19_PERFMON_CVALUE_INT_MISC_BASE_IDX 2
+#define regDC_PERFMON19_PERFMON_CVALUE_LOW 0x3056
+#define regDC_PERFMON19_PERFMON_CVALUE_LOW_BASE_IDX 2
+#define regDC_PERFMON19_PERFMON_HI 0x3057
+#define regDC_PERFMON19_PERFMON_HI_BASE_IDX 2
+#define regDC_PERFMON19_PERFMON_LOW 0x3058
+#define regDC_PERFMON19_PERFMON_LOW_BASE_IDX 2
+
+
+// addressBlock: dce_dc_dsc1_dispdec_dscc_dispdec
+// base address: 0x170
+#define regDSCC1_DSCC_CONFIG0 0x3066
+#define regDSCC1_DSCC_CONFIG0_BASE_IDX 2
+#define regDSCC1_DSCC_CONFIG1 0x3067
+#define regDSCC1_DSCC_CONFIG1_BASE_IDX 2
+#define regDSCC1_DSCC_STATUS 0x3068
+#define regDSCC1_DSCC_STATUS_BASE_IDX 2
+#define regDSCC1_DSCC_INTERRUPT_CONTROL_STATUS 0x3069
+#define regDSCC1_DSCC_INTERRUPT_CONTROL_STATUS_BASE_IDX 2
+#define regDSCC1_DSCC_PPS_CONFIG0 0x306a
+#define regDSCC1_DSCC_PPS_CONFIG0_BASE_IDX 2
+#define regDSCC1_DSCC_PPS_CONFIG1 0x306b
+#define regDSCC1_DSCC_PPS_CONFIG1_BASE_IDX 2
+#define regDSCC1_DSCC_PPS_CONFIG2 0x306c
+#define regDSCC1_DSCC_PPS_CONFIG2_BASE_IDX 2
+#define regDSCC1_DSCC_PPS_CONFIG3 0x306d
+#define regDSCC1_DSCC_PPS_CONFIG3_BASE_IDX 2
+#define regDSCC1_DSCC_PPS_CONFIG4 0x306e
+#define regDSCC1_DSCC_PPS_CONFIG4_BASE_IDX 2
+#define regDSCC1_DSCC_PPS_CONFIG5 0x306f
+#define regDSCC1_DSCC_PPS_CONFIG5_BASE_IDX 2
+#define regDSCC1_DSCC_PPS_CONFIG6 0x3070
+#define regDSCC1_DSCC_PPS_CONFIG6_BASE_IDX 2
+#define regDSCC1_DSCC_PPS_CONFIG7 0x3071
+#define regDSCC1_DSCC_PPS_CONFIG7_BASE_IDX 2
+#define regDSCC1_DSCC_PPS_CONFIG8 0x3072
+#define regDSCC1_DSCC_PPS_CONFIG8_BASE_IDX 2
+#define regDSCC1_DSCC_PPS_CONFIG9 0x3073
+#define regDSCC1_DSCC_PPS_CONFIG9_BASE_IDX 2
+#define regDSCC1_DSCC_PPS_CONFIG10 0x3074
+#define regDSCC1_DSCC_PPS_CONFIG10_BASE_IDX 2
+#define regDSCC1_DSCC_PPS_CONFIG11 0x3075
+#define regDSCC1_DSCC_PPS_CONFIG11_BASE_IDX 2
+#define regDSCC1_DSCC_PPS_CONFIG12 0x3076
+#define regDSCC1_DSCC_PPS_CONFIG12_BASE_IDX 2
+#define regDSCC1_DSCC_PPS_CONFIG13 0x3077
+#define regDSCC1_DSCC_PPS_CONFIG13_BASE_IDX 2
+#define regDSCC1_DSCC_PPS_CONFIG14 0x3078
+#define regDSCC1_DSCC_PPS_CONFIG14_BASE_IDX 2
+#define regDSCC1_DSCC_PPS_CONFIG15 0x3079
+#define regDSCC1_DSCC_PPS_CONFIG15_BASE_IDX 2
+#define regDSCC1_DSCC_PPS_CONFIG16 0x307a
+#define regDSCC1_DSCC_PPS_CONFIG16_BASE_IDX 2
+#define regDSCC1_DSCC_PPS_CONFIG17 0x307b
+#define regDSCC1_DSCC_PPS_CONFIG17_BASE_IDX 2
+#define regDSCC1_DSCC_PPS_CONFIG18 0x307c
+#define regDSCC1_DSCC_PPS_CONFIG18_BASE_IDX 2
+#define regDSCC1_DSCC_PPS_CONFIG19 0x307d
+#define regDSCC1_DSCC_PPS_CONFIG19_BASE_IDX 2
+#define regDSCC1_DSCC_PPS_CONFIG20 0x307e
+#define regDSCC1_DSCC_PPS_CONFIG20_BASE_IDX 2
+#define regDSCC1_DSCC_PPS_CONFIG21 0x307f
+#define regDSCC1_DSCC_PPS_CONFIG21_BASE_IDX 2
+#define regDSCC1_DSCC_PPS_CONFIG22 0x3080
+#define regDSCC1_DSCC_PPS_CONFIG22_BASE_IDX 2
+#define regDSCC1_DSCC_MEM_POWER_CONTROL 0x3081
+#define regDSCC1_DSCC_MEM_POWER_CONTROL_BASE_IDX 2
+#define regDSCC1_DSCC_R_Y_SQUARED_ERROR_LOWER 0x3082
+#define regDSCC1_DSCC_R_Y_SQUARED_ERROR_LOWER_BASE_IDX 2
+#define regDSCC1_DSCC_R_Y_SQUARED_ERROR_UPPER 0x3083
+#define regDSCC1_DSCC_R_Y_SQUARED_ERROR_UPPER_BASE_IDX 2
+#define regDSCC1_DSCC_G_CB_SQUARED_ERROR_LOWER 0x3084
+#define regDSCC1_DSCC_G_CB_SQUARED_ERROR_LOWER_BASE_IDX 2
+#define regDSCC1_DSCC_G_CB_SQUARED_ERROR_UPPER 0x3085
+#define regDSCC1_DSCC_G_CB_SQUARED_ERROR_UPPER_BASE_IDX 2
+#define regDSCC1_DSCC_B_CR_SQUARED_ERROR_LOWER 0x3086
+#define regDSCC1_DSCC_B_CR_SQUARED_ERROR_LOWER_BASE_IDX 2
+#define regDSCC1_DSCC_B_CR_SQUARED_ERROR_UPPER 0x3087
+#define regDSCC1_DSCC_B_CR_SQUARED_ERROR_UPPER_BASE_IDX 2
+#define regDSCC1_DSCC_MAX_ABS_ERROR0 0x3088
+#define regDSCC1_DSCC_MAX_ABS_ERROR0_BASE_IDX 2
+#define regDSCC1_DSCC_MAX_ABS_ERROR1 0x3089
+#define regDSCC1_DSCC_MAX_ABS_ERROR1_BASE_IDX 2
+#define regDSCC1_DSCC_RATE_BUFFER0_MAX_FULLNESS_LEVEL 0x308a
+#define regDSCC1_DSCC_RATE_BUFFER0_MAX_FULLNESS_LEVEL_BASE_IDX 2
+#define regDSCC1_DSCC_RATE_BUFFER1_MAX_FULLNESS_LEVEL 0x308b
+#define regDSCC1_DSCC_RATE_BUFFER1_MAX_FULLNESS_LEVEL_BASE_IDX 2
+#define regDSCC1_DSCC_RATE_BUFFER2_MAX_FULLNESS_LEVEL 0x308c
+#define regDSCC1_DSCC_RATE_BUFFER2_MAX_FULLNESS_LEVEL_BASE_IDX 2
+#define regDSCC1_DSCC_RATE_BUFFER3_MAX_FULLNESS_LEVEL 0x308d
+#define regDSCC1_DSCC_RATE_BUFFER3_MAX_FULLNESS_LEVEL_BASE_IDX 2
+#define regDSCC1_DSCC_RATE_CONTROL_BUFFER0_MAX_FULLNESS_LEVEL 0x308e
+#define regDSCC1_DSCC_RATE_CONTROL_BUFFER0_MAX_FULLNESS_LEVEL_BASE_IDX 2
+#define regDSCC1_DSCC_RATE_CONTROL_BUFFER1_MAX_FULLNESS_LEVEL 0x308f
+#define regDSCC1_DSCC_RATE_CONTROL_BUFFER1_MAX_FULLNESS_LEVEL_BASE_IDX 2
+#define regDSCC1_DSCC_RATE_CONTROL_BUFFER2_MAX_FULLNESS_LEVEL 0x3090
+#define regDSCC1_DSCC_RATE_CONTROL_BUFFER2_MAX_FULLNESS_LEVEL_BASE_IDX 2
+#define regDSCC1_DSCC_RATE_CONTROL_BUFFER3_MAX_FULLNESS_LEVEL 0x3091
+#define regDSCC1_DSCC_RATE_CONTROL_BUFFER3_MAX_FULLNESS_LEVEL_BASE_IDX 2
+#define regDSCC1_DSCC_TEST_DEBUG_BUS_ROTATE 0x3096
+#define regDSCC1_DSCC_TEST_DEBUG_BUS_ROTATE_BASE_IDX 2
+
+
+// addressBlock: dce_dc_dsc1_dispdec_dsccif_dispdec
+// base address: 0x170
+#define regDSCCIF1_DSCCIF_CONFIG0 0x3061
+#define regDSCCIF1_DSCCIF_CONFIG0_BASE_IDX 2
+#define regDSCCIF1_DSCCIF_CONFIG1 0x3062
+#define regDSCCIF1_DSCCIF_CONFIG1_BASE_IDX 2
+
+
+// addressBlock: dce_dc_dsc1_dispdec_dsc_top_dispdec
+// base address: 0x170
+#define regDSC_TOP1_DSC_TOP_CONTROL 0x305c
+#define regDSC_TOP1_DSC_TOP_CONTROL_BASE_IDX 2
+#define regDSC_TOP1_DSC_DEBUG_CONTROL 0x305d
+#define regDSC_TOP1_DSC_DEBUG_CONTROL_BASE_IDX 2
+
+
+// addressBlock: dce_dc_dsc1_dispdec_dsc_dcperfmon_dc_perfmon_dispdec
+// base address: 0xc2b0
+#define regDC_PERFMON20_PERFCOUNTER_CNTL 0x30ac
+#define regDC_PERFMON20_PERFCOUNTER_CNTL_BASE_IDX 2
+#define regDC_PERFMON20_PERFCOUNTER_CNTL2 0x30ad
+#define regDC_PERFMON20_PERFCOUNTER_CNTL2_BASE_IDX 2
+#define regDC_PERFMON20_PERFCOUNTER_STATE 0x30ae
+#define regDC_PERFMON20_PERFCOUNTER_STATE_BASE_IDX 2
+#define regDC_PERFMON20_PERFMON_CNTL 0x30af
+#define regDC_PERFMON20_PERFMON_CNTL_BASE_IDX 2
+#define regDC_PERFMON20_PERFMON_CNTL2 0x30b0
+#define regDC_PERFMON20_PERFMON_CNTL2_BASE_IDX 2
+#define regDC_PERFMON20_PERFMON_CVALUE_INT_MISC 0x30b1
+#define regDC_PERFMON20_PERFMON_CVALUE_INT_MISC_BASE_IDX 2
+#define regDC_PERFMON20_PERFMON_CVALUE_LOW 0x30b2
+#define regDC_PERFMON20_PERFMON_CVALUE_LOW_BASE_IDX 2
+#define regDC_PERFMON20_PERFMON_HI 0x30b3
+#define regDC_PERFMON20_PERFMON_HI_BASE_IDX 2
+#define regDC_PERFMON20_PERFMON_LOW 0x30b4
+#define regDC_PERFMON20_PERFMON_LOW_BASE_IDX 2
+
+
+// addressBlock: dce_dc_dsc2_dispdec_dscc_dispdec
+// base address: 0x2e0
+#define regDSCC2_DSCC_CONFIG0 0x30c2
+#define regDSCC2_DSCC_CONFIG0_BASE_IDX 2
+#define regDSCC2_DSCC_CONFIG1 0x30c3
+#define regDSCC2_DSCC_CONFIG1_BASE_IDX 2
+#define regDSCC2_DSCC_STATUS 0x30c4
+#define regDSCC2_DSCC_STATUS_BASE_IDX 2
+#define regDSCC2_DSCC_INTERRUPT_CONTROL_STATUS 0x30c5
+#define regDSCC2_DSCC_INTERRUPT_CONTROL_STATUS_BASE_IDX 2
+#define regDSCC2_DSCC_PPS_CONFIG0 0x30c6
+#define regDSCC2_DSCC_PPS_CONFIG0_BASE_IDX 2
+#define regDSCC2_DSCC_PPS_CONFIG1 0x30c7
+#define regDSCC2_DSCC_PPS_CONFIG1_BASE_IDX 2
+#define regDSCC2_DSCC_PPS_CONFIG2 0x30c8
+#define regDSCC2_DSCC_PPS_CONFIG2_BASE_IDX 2
+#define regDSCC2_DSCC_PPS_CONFIG3 0x30c9
+#define regDSCC2_DSCC_PPS_CONFIG3_BASE_IDX 2
+#define regDSCC2_DSCC_PPS_CONFIG4 0x30ca
+#define regDSCC2_DSCC_PPS_CONFIG4_BASE_IDX 2
+#define regDSCC2_DSCC_PPS_CONFIG5 0x30cb
+#define regDSCC2_DSCC_PPS_CONFIG5_BASE_IDX 2
+#define regDSCC2_DSCC_PPS_CONFIG6 0x30cc
+#define regDSCC2_DSCC_PPS_CONFIG6_BASE_IDX 2
+#define regDSCC2_DSCC_PPS_CONFIG7 0x30cd
+#define regDSCC2_DSCC_PPS_CONFIG7_BASE_IDX 2
+#define regDSCC2_DSCC_PPS_CONFIG8 0x30ce
+#define regDSCC2_DSCC_PPS_CONFIG8_BASE_IDX 2
+#define regDSCC2_DSCC_PPS_CONFIG9 0x30cf
+#define regDSCC2_DSCC_PPS_CONFIG9_BASE_IDX 2
+#define regDSCC2_DSCC_PPS_CONFIG10 0x30d0
+#define regDSCC2_DSCC_PPS_CONFIG10_BASE_IDX 2
+#define regDSCC2_DSCC_PPS_CONFIG11 0x30d1
+#define regDSCC2_DSCC_PPS_CONFIG11_BASE_IDX 2
+#define regDSCC2_DSCC_PPS_CONFIG12 0x30d2
+#define regDSCC2_DSCC_PPS_CONFIG12_BASE_IDX 2
+#define regDSCC2_DSCC_PPS_CONFIG13 0x30d3
+#define regDSCC2_DSCC_PPS_CONFIG13_BASE_IDX 2
+#define regDSCC2_DSCC_PPS_CONFIG14 0x30d4
+#define regDSCC2_DSCC_PPS_CONFIG14_BASE_IDX 2
+#define regDSCC2_DSCC_PPS_CONFIG15 0x30d5
+#define regDSCC2_DSCC_PPS_CONFIG15_BASE_IDX 2
+#define regDSCC2_DSCC_PPS_CONFIG16 0x30d6
+#define regDSCC2_DSCC_PPS_CONFIG16_BASE_IDX 2
+#define regDSCC2_DSCC_PPS_CONFIG17 0x30d7
+#define regDSCC2_DSCC_PPS_CONFIG17_BASE_IDX 2
+#define regDSCC2_DSCC_PPS_CONFIG18 0x30d8
+#define regDSCC2_DSCC_PPS_CONFIG18_BASE_IDX 2
+#define regDSCC2_DSCC_PPS_CONFIG19 0x30d9
+#define regDSCC2_DSCC_PPS_CONFIG19_BASE_IDX 2
+#define regDSCC2_DSCC_PPS_CONFIG20 0x30da
+#define regDSCC2_DSCC_PPS_CONFIG20_BASE_IDX 2
+#define regDSCC2_DSCC_PPS_CONFIG21 0x30db
+#define regDSCC2_DSCC_PPS_CONFIG21_BASE_IDX 2
+#define regDSCC2_DSCC_PPS_CONFIG22 0x30dc
+#define regDSCC2_DSCC_PPS_CONFIG22_BASE_IDX 2
+#define regDSCC2_DSCC_MEM_POWER_CONTROL 0x30dd
+#define regDSCC2_DSCC_MEM_POWER_CONTROL_BASE_IDX 2
+#define regDSCC2_DSCC_R_Y_SQUARED_ERROR_LOWER 0x30de
+#define regDSCC2_DSCC_R_Y_SQUARED_ERROR_LOWER_BASE_IDX 2
+#define regDSCC2_DSCC_R_Y_SQUARED_ERROR_UPPER 0x30df
+#define regDSCC2_DSCC_R_Y_SQUARED_ERROR_UPPER_BASE_IDX 2
+#define regDSCC2_DSCC_G_CB_SQUARED_ERROR_LOWER 0x30e0
+#define regDSCC2_DSCC_G_CB_SQUARED_ERROR_LOWER_BASE_IDX 2
+#define regDSCC2_DSCC_G_CB_SQUARED_ERROR_UPPER 0x30e1
+#define regDSCC2_DSCC_G_CB_SQUARED_ERROR_UPPER_BASE_IDX 2
+#define regDSCC2_DSCC_B_CR_SQUARED_ERROR_LOWER 0x30e2
+#define regDSCC2_DSCC_B_CR_SQUARED_ERROR_LOWER_BASE_IDX 2
+#define regDSCC2_DSCC_B_CR_SQUARED_ERROR_UPPER 0x30e3
+#define regDSCC2_DSCC_B_CR_SQUARED_ERROR_UPPER_BASE_IDX 2
+#define regDSCC2_DSCC_MAX_ABS_ERROR0 0x30e4
+#define regDSCC2_DSCC_MAX_ABS_ERROR0_BASE_IDX 2
+#define regDSCC2_DSCC_MAX_ABS_ERROR1 0x30e5
+#define regDSCC2_DSCC_MAX_ABS_ERROR1_BASE_IDX 2
+#define regDSCC2_DSCC_RATE_BUFFER0_MAX_FULLNESS_LEVEL 0x30e6
+#define regDSCC2_DSCC_RATE_BUFFER0_MAX_FULLNESS_LEVEL_BASE_IDX 2
+#define regDSCC2_DSCC_RATE_BUFFER1_MAX_FULLNESS_LEVEL 0x30e7
+#define regDSCC2_DSCC_RATE_BUFFER1_MAX_FULLNESS_LEVEL_BASE_IDX 2
+#define regDSCC2_DSCC_RATE_BUFFER2_MAX_FULLNESS_LEVEL 0x30e8
+#define regDSCC2_DSCC_RATE_BUFFER2_MAX_FULLNESS_LEVEL_BASE_IDX 2
+#define regDSCC2_DSCC_RATE_BUFFER3_MAX_FULLNESS_LEVEL 0x30e9
+#define regDSCC2_DSCC_RATE_BUFFER3_MAX_FULLNESS_LEVEL_BASE_IDX 2
+#define regDSCC2_DSCC_RATE_CONTROL_BUFFER0_MAX_FULLNESS_LEVEL 0x30ea
+#define regDSCC2_DSCC_RATE_CONTROL_BUFFER0_MAX_FULLNESS_LEVEL_BASE_IDX 2
+#define regDSCC2_DSCC_RATE_CONTROL_BUFFER1_MAX_FULLNESS_LEVEL 0x30eb
+#define regDSCC2_DSCC_RATE_CONTROL_BUFFER1_MAX_FULLNESS_LEVEL_BASE_IDX 2
+#define regDSCC2_DSCC_RATE_CONTROL_BUFFER2_MAX_FULLNESS_LEVEL 0x30ec
+#define regDSCC2_DSCC_RATE_CONTROL_BUFFER2_MAX_FULLNESS_LEVEL_BASE_IDX 2
+#define regDSCC2_DSCC_RATE_CONTROL_BUFFER3_MAX_FULLNESS_LEVEL 0x30ed
+#define regDSCC2_DSCC_RATE_CONTROL_BUFFER3_MAX_FULLNESS_LEVEL_BASE_IDX 2
+#define regDSCC2_DSCC_TEST_DEBUG_BUS_ROTATE 0x30f2
+#define regDSCC2_DSCC_TEST_DEBUG_BUS_ROTATE_BASE_IDX 2
+
+
+// addressBlock: dce_dc_dsc2_dispdec_dsccif_dispdec
+// base address: 0x2e0
+#define regDSCCIF2_DSCCIF_CONFIG0 0x30bd
+#define regDSCCIF2_DSCCIF_CONFIG0_BASE_IDX 2
+#define regDSCCIF2_DSCCIF_CONFIG1 0x30be
+#define regDSCCIF2_DSCCIF_CONFIG1_BASE_IDX 2
+
+
+// addressBlock: dce_dc_dsc2_dispdec_dsc_top_dispdec
+// base address: 0x2e0
+#define regDSC_TOP2_DSC_TOP_CONTROL 0x30b8
+#define regDSC_TOP2_DSC_TOP_CONTROL_BASE_IDX 2
+#define regDSC_TOP2_DSC_DEBUG_CONTROL 0x30b9
+#define regDSC_TOP2_DSC_DEBUG_CONTROL_BASE_IDX 2
+
+
+// addressBlock: dce_dc_dsc2_dispdec_dsc_dcperfmon_dc_perfmon_dispdec
+// base address: 0xc420
+#define regDC_PERFMON21_PERFCOUNTER_CNTL 0x3108
+#define regDC_PERFMON21_PERFCOUNTER_CNTL_BASE_IDX 2
+#define regDC_PERFMON21_PERFCOUNTER_CNTL2 0x3109
+#define regDC_PERFMON21_PERFCOUNTER_CNTL2_BASE_IDX 2
+#define regDC_PERFMON21_PERFCOUNTER_STATE 0x310a
+#define regDC_PERFMON21_PERFCOUNTER_STATE_BASE_IDX 2
+#define regDC_PERFMON21_PERFMON_CNTL 0x310b
+#define regDC_PERFMON21_PERFMON_CNTL_BASE_IDX 2
+#define regDC_PERFMON21_PERFMON_CNTL2 0x310c
+#define regDC_PERFMON21_PERFMON_CNTL2_BASE_IDX 2
+#define regDC_PERFMON21_PERFMON_CVALUE_INT_MISC 0x310d
+#define regDC_PERFMON21_PERFMON_CVALUE_INT_MISC_BASE_IDX 2
+#define regDC_PERFMON21_PERFMON_CVALUE_LOW 0x310e
+#define regDC_PERFMON21_PERFMON_CVALUE_LOW_BASE_IDX 2
+#define regDC_PERFMON21_PERFMON_HI 0x310f
+#define regDC_PERFMON21_PERFMON_HI_BASE_IDX 2
+#define regDC_PERFMON21_PERFMON_LOW 0x3110
+#define regDC_PERFMON21_PERFMON_LOW_BASE_IDX 2
+
+
+// addressBlock: dce_dc_hpo_hpo_top_dispdec
+// base address: 0x2790c
+#define regHPO_TOP_CLOCK_CONTROL 0x0e43
+#define regHPO_TOP_CLOCK_CONTROL_BASE_IDX 3
+#define regHPO_TOP_HW_CONTROL 0x0e4a
+#define regHPO_TOP_HW_CONTROL_BASE_IDX 3
+
+
+// addressBlock: dce_dc_hpo_dp_stream_mapper_dispdec
+// base address: 0x27958
+#define regDP_STREAM_MAPPER_CONTROL0 0x0e56
+#define regDP_STREAM_MAPPER_CONTROL0_BASE_IDX 3
+#define regDP_STREAM_MAPPER_CONTROL1 0x0e57
+#define regDP_STREAM_MAPPER_CONTROL1_BASE_IDX 3
+#define regDP_STREAM_MAPPER_CONTROL2 0x0e58
+#define regDP_STREAM_MAPPER_CONTROL2_BASE_IDX 3
+#define regDP_STREAM_MAPPER_CONTROL3 0x0e59
+#define regDP_STREAM_MAPPER_CONTROL3_BASE_IDX 3
+
+
+// addressBlock: dce_dc_hpo_hpo_dcperfmon_dc_perfmon_dispdec
+// base address: 0x1a698
+#define regDC_PERFMON22_PERFCOUNTER_CNTL 0x0e66
+#define regDC_PERFMON22_PERFCOUNTER_CNTL_BASE_IDX 3
+#define regDC_PERFMON22_PERFCOUNTER_CNTL2 0x0e67
+#define regDC_PERFMON22_PERFCOUNTER_CNTL2_BASE_IDX 3
+#define regDC_PERFMON22_PERFCOUNTER_STATE 0x0e68
+#define regDC_PERFMON22_PERFCOUNTER_STATE_BASE_IDX 3
+#define regDC_PERFMON22_PERFMON_CNTL 0x0e69
+#define regDC_PERFMON22_PERFMON_CNTL_BASE_IDX 3
+#define regDC_PERFMON22_PERFMON_CNTL2 0x0e6a
+#define regDC_PERFMON22_PERFMON_CNTL2_BASE_IDX 3
+#define regDC_PERFMON22_PERFMON_CVALUE_INT_MISC 0x0e6b
+#define regDC_PERFMON22_PERFMON_CVALUE_INT_MISC_BASE_IDX 3
+#define regDC_PERFMON22_PERFMON_CVALUE_LOW 0x0e6c
+#define regDC_PERFMON22_PERFMON_CVALUE_LOW_BASE_IDX 3
+#define regDC_PERFMON22_PERFMON_HI 0x0e6d
+#define regDC_PERFMON22_PERFMON_HI_BASE_IDX 3
+#define regDC_PERFMON22_PERFMON_LOW 0x0e6e
+#define regDC_PERFMON22_PERFMON_LOW_BASE_IDX 3
+
+
+// addressBlock: dce_dc_hpo_hdmi_stream_enc0_afmt_afmt_dispdec
+// base address: 0x2646c
+#define regAFMT5_AFMT_VBI_PACKET_CONTROL 0x091c
+#define regAFMT5_AFMT_VBI_PACKET_CONTROL_BASE_IDX 3
+#define regAFMT5_AFMT_AUDIO_PACKET_CONTROL2 0x091d
+#define regAFMT5_AFMT_AUDIO_PACKET_CONTROL2_BASE_IDX 3
+#define regAFMT5_AFMT_AUDIO_INFO0 0x091e
+#define regAFMT5_AFMT_AUDIO_INFO0_BASE_IDX 3
+#define regAFMT5_AFMT_AUDIO_INFO1 0x091f
+#define regAFMT5_AFMT_AUDIO_INFO1_BASE_IDX 3
+#define regAFMT5_AFMT_60958_0 0x0920
+#define regAFMT5_AFMT_60958_0_BASE_IDX 3
+#define regAFMT5_AFMT_60958_1 0x0921
+#define regAFMT5_AFMT_60958_1_BASE_IDX 3
+#define regAFMT5_AFMT_AUDIO_CRC_CONTROL 0x0922
+#define regAFMT5_AFMT_AUDIO_CRC_CONTROL_BASE_IDX 3
+#define regAFMT5_AFMT_RAMP_CONTROL0 0x0923
+#define regAFMT5_AFMT_RAMP_CONTROL0_BASE_IDX 3
+#define regAFMT5_AFMT_RAMP_CONTROL1 0x0924
+#define regAFMT5_AFMT_RAMP_CONTROL1_BASE_IDX 3
+#define regAFMT5_AFMT_RAMP_CONTROL2 0x0925
+#define regAFMT5_AFMT_RAMP_CONTROL2_BASE_IDX 3
+#define regAFMT5_AFMT_RAMP_CONTROL3 0x0926
+#define regAFMT5_AFMT_RAMP_CONTROL3_BASE_IDX 3
+#define regAFMT5_AFMT_60958_2 0x0927
+#define regAFMT5_AFMT_60958_2_BASE_IDX 3
+#define regAFMT5_AFMT_AUDIO_CRC_RESULT 0x0928
+#define regAFMT5_AFMT_AUDIO_CRC_RESULT_BASE_IDX 3
+#define regAFMT5_AFMT_STATUS 0x0929
+#define regAFMT5_AFMT_STATUS_BASE_IDX 3
+#define regAFMT5_AFMT_AUDIO_PACKET_CONTROL 0x092a
+#define regAFMT5_AFMT_AUDIO_PACKET_CONTROL_BASE_IDX 3
+#define regAFMT5_AFMT_INFOFRAME_CONTROL0 0x092b
+#define regAFMT5_AFMT_INFOFRAME_CONTROL0_BASE_IDX 3
+#define regAFMT5_AFMT_AUDIO_SRC_CONTROL 0x092d
+#define regAFMT5_AFMT_AUDIO_SRC_CONTROL_BASE_IDX 3
+#define regAFMT5_AFMT_MEM_PWR 0x092f
+#define regAFMT5_AFMT_MEM_PWR_BASE_IDX 3
+
+
+// addressBlock: dce_dc_hpo_hdmi_stream_enc0_dme_dme_dispdec
+// base address: 0x264f0
+#define regDME5_DME_CONTROL 0x093c
+#define regDME5_DME_CONTROL_BASE_IDX 3
+#define regDME5_DME_MEMORY_CONTROL 0x093d
+#define regDME5_DME_MEMORY_CONTROL_BASE_IDX 3
+
+
+// addressBlock: dce_dc_hpo_hdmi_stream_enc0_vpg_vpg_dispdec
+// base address: 0x264c4
+#define regVPG5_VPG_GENERIC_PACKET_ACCESS_CTRL 0x0931
+#define regVPG5_VPG_GENERIC_PACKET_ACCESS_CTRL_BASE_IDX 3
+#define regVPG5_VPG_GENERIC_PACKET_DATA 0x0932
+#define regVPG5_VPG_GENERIC_PACKET_DATA_BASE_IDX 3
+#define regVPG5_VPG_GSP_FRAME_UPDATE_CTRL 0x0933
+#define regVPG5_VPG_GSP_FRAME_UPDATE_CTRL_BASE_IDX 3
+#define regVPG5_VPG_GSP_IMMEDIATE_UPDATE_CTRL 0x0934
+#define regVPG5_VPG_GSP_IMMEDIATE_UPDATE_CTRL_BASE_IDX 3
+#define regVPG5_VPG_GENERIC_STATUS 0x0935
+#define regVPG5_VPG_GENERIC_STATUS_BASE_IDX 3
+#define regVPG5_VPG_MEM_PWR 0x0936
+#define regVPG5_VPG_MEM_PWR_BASE_IDX 3
+#define regVPG5_VPG_ISRC1_2_ACCESS_CTRL 0x0937
+#define regVPG5_VPG_ISRC1_2_ACCESS_CTRL_BASE_IDX 3
+#define regVPG5_VPG_ISRC1_2_DATA 0x0938
+#define regVPG5_VPG_ISRC1_2_DATA_BASE_IDX 3
+#define regVPG5_VPG_MPEG_INFO0 0x0939
+#define regVPG5_VPG_MPEG_INFO0_BASE_IDX 3
+#define regVPG5_VPG_MPEG_INFO1 0x093a
+#define regVPG5_VPG_MPEG_INFO1_BASE_IDX 3
+
+
+// addressBlock: dce_dc_hpo_dp_stream_enc0_dispdec
+// base address: 0x1ab8c
+#define regDP_STREAM_ENC0_DP_STREAM_ENC_CLOCK_CONTROL 0x3623
+#define regDP_STREAM_ENC0_DP_STREAM_ENC_CLOCK_CONTROL_BASE_IDX 2
+#define regDP_STREAM_ENC0_DP_STREAM_ENC_INPUT_MUX_CONTROL 0x3624
+#define regDP_STREAM_ENC0_DP_STREAM_ENC_INPUT_MUX_CONTROL_BASE_IDX 2
+#define regDP_STREAM_ENC0_DP_STREAM_ENC_AUDIO_CONTROL 0x3625
+#define regDP_STREAM_ENC0_DP_STREAM_ENC_AUDIO_CONTROL_BASE_IDX 2
+#define regDP_STREAM_ENC0_DP_STREAM_ENC_CLOCK_RAMP_ADJUSTER_FIFO_STATUS_CONTROL0 0x3626
+#define regDP_STREAM_ENC0_DP_STREAM_ENC_CLOCK_RAMP_ADJUSTER_FIFO_STATUS_CONTROL0_BASE_IDX 2
+#define regDP_STREAM_ENC0_DP_STREAM_ENC_CLOCK_RAMP_ADJUSTER_FIFO_STATUS_CONTROL1 0x3627
+#define regDP_STREAM_ENC0_DP_STREAM_ENC_CLOCK_RAMP_ADJUSTER_FIFO_STATUS_CONTROL1_BASE_IDX 2
+#define regDP_STREAM_ENC0_DP_STREAM_ENC_SPARE 0x3628
+#define regDP_STREAM_ENC0_DP_STREAM_ENC_SPARE_BASE_IDX 2
+
+
+// addressBlock: dce_dc_hpo_dp_stream_enc0_apg_apg_dispdec
+// base address: 0x1abc0
+#define regAPG0_APG_CONTROL 0x3630
+#define regAPG0_APG_CONTROL_BASE_IDX 2
+#define regAPG0_APG_CONTROL2 0x3631
+#define regAPG0_APG_CONTROL2_BASE_IDX 2
+#define regAPG0_APG_DBG_GEN_CONTROL 0x3632
+#define regAPG0_APG_DBG_GEN_CONTROL_BASE_IDX 2
+#define regAPG0_APG_PACKET_CONTROL 0x3633
+#define regAPG0_APG_PACKET_CONTROL_BASE_IDX 2
+#define regAPG0_APG_AUDIO_CRC_CONTROL 0x363a
+#define regAPG0_APG_AUDIO_CRC_CONTROL_BASE_IDX 2
+#define regAPG0_APG_AUDIO_CRC_CONTROL2 0x363b
+#define regAPG0_APG_AUDIO_CRC_CONTROL2_BASE_IDX 2
+#define regAPG0_APG_AUDIO_CRC_RESULT 0x363c
+#define regAPG0_APG_AUDIO_CRC_RESULT_BASE_IDX 2
+#define regAPG0_APG_STATUS 0x3641
+#define regAPG0_APG_STATUS_BASE_IDX 2
+#define regAPG0_APG_STATUS2 0x3642
+#define regAPG0_APG_STATUS2_BASE_IDX 2
+#define regAPG0_APG_MEM_PWR 0x3644
+#define regAPG0_APG_MEM_PWR_BASE_IDX 2
+#define regAPG0_APG_SPARE 0x3646
+#define regAPG0_APG_SPARE_BASE_IDX 2
+
+
+// addressBlock: dce_dc_hpo_dp_stream_enc0_dme_dme_dispdec
+// base address: 0x1ac38
+#define regDME6_DME_CONTROL 0x364e
+#define regDME6_DME_CONTROL_BASE_IDX 2
+#define regDME6_DME_MEMORY_CONTROL 0x364f
+#define regDME6_DME_MEMORY_CONTROL_BASE_IDX 2
+
+
+// addressBlock: dce_dc_hpo_dp_stream_enc0_vpg_vpg_dispdec
+// base address: 0x1ac44
+#define regVPG6_VPG_GENERIC_PACKET_ACCESS_CTRL 0x3651
+#define regVPG6_VPG_GENERIC_PACKET_ACCESS_CTRL_BASE_IDX 2
+#define regVPG6_VPG_GENERIC_PACKET_DATA 0x3652
+#define regVPG6_VPG_GENERIC_PACKET_DATA_BASE_IDX 2
+#define regVPG6_VPG_GSP_FRAME_UPDATE_CTRL 0x3653
+#define regVPG6_VPG_GSP_FRAME_UPDATE_CTRL_BASE_IDX 2
+#define regVPG6_VPG_GSP_IMMEDIATE_UPDATE_CTRL 0x3654
+#define regVPG6_VPG_GSP_IMMEDIATE_UPDATE_CTRL_BASE_IDX 2
+#define regVPG6_VPG_GENERIC_STATUS 0x3655
+#define regVPG6_VPG_GENERIC_STATUS_BASE_IDX 2
+#define regVPG6_VPG_MEM_PWR 0x3656
+#define regVPG6_VPG_MEM_PWR_BASE_IDX 2
+#define regVPG6_VPG_ISRC1_2_ACCESS_CTRL 0x3657
+#define regVPG6_VPG_ISRC1_2_ACCESS_CTRL_BASE_IDX 2
+#define regVPG6_VPG_ISRC1_2_DATA 0x3658
+#define regVPG6_VPG_ISRC1_2_DATA_BASE_IDX 2
+#define regVPG6_VPG_MPEG_INFO0 0x3659
+#define regVPG6_VPG_MPEG_INFO0_BASE_IDX 2
+#define regVPG6_VPG_MPEG_INFO1 0x365a
+#define regVPG6_VPG_MPEG_INFO1_BASE_IDX 2
+
+
+// addressBlock: dce_dc_hpo_dp_sym32_enc0_dispdec
+// base address: 0x1ac74
+#define regDP_SYM32_ENC0_DP_SYM32_ENC_CONTROL 0x365d
+#define regDP_SYM32_ENC0_DP_SYM32_ENC_CONTROL_BASE_IDX 2
+#define regDP_SYM32_ENC0_DP_SYM32_ENC_VID_FIFO_CONTROL 0x365e
+#define regDP_SYM32_ENC0_DP_SYM32_ENC_VID_FIFO_CONTROL_BASE_IDX 2
+#define regDP_SYM32_ENC0_DP_SYM32_ENC_VID_MSA_DOUBLE_BUFFER_CONTROL 0x365f
+#define regDP_SYM32_ENC0_DP_SYM32_ENC_VID_MSA_DOUBLE_BUFFER_CONTROL_BASE_IDX 2
+#define regDP_SYM32_ENC0_DP_SYM32_ENC_VID_PIXEL_FORMAT_DOUBLE_BUFFER_CONTROL 0x3660
+#define regDP_SYM32_ENC0_DP_SYM32_ENC_VID_PIXEL_FORMAT_DOUBLE_BUFFER_CONTROL_BASE_IDX 2
+#define regDP_SYM32_ENC0_DP_SYM32_ENC_VID_PIXEL_FORMAT 0x3661
+#define regDP_SYM32_ENC0_DP_SYM32_ENC_VID_PIXEL_FORMAT_BASE_IDX 2
+#define regDP_SYM32_ENC0_DP_SYM32_ENC_VID_MSA0 0x3662
+#define regDP_SYM32_ENC0_DP_SYM32_ENC_VID_MSA0_BASE_IDX 2
+#define regDP_SYM32_ENC0_DP_SYM32_ENC_VID_MSA1 0x3663
+#define regDP_SYM32_ENC0_DP_SYM32_ENC_VID_MSA1_BASE_IDX 2
+#define regDP_SYM32_ENC0_DP_SYM32_ENC_VID_MSA2 0x3664
+#define regDP_SYM32_ENC0_DP_SYM32_ENC_VID_MSA2_BASE_IDX 2
+#define regDP_SYM32_ENC0_DP_SYM32_ENC_VID_MSA3 0x3665
+#define regDP_SYM32_ENC0_DP_SYM32_ENC_VID_MSA3_BASE_IDX 2
+#define regDP_SYM32_ENC0_DP_SYM32_ENC_VID_MSA4 0x3666
+#define regDP_SYM32_ENC0_DP_SYM32_ENC_VID_MSA4_BASE_IDX 2
+#define regDP_SYM32_ENC0_DP_SYM32_ENC_VID_MSA5 0x3667
+#define regDP_SYM32_ENC0_DP_SYM32_ENC_VID_MSA5_BASE_IDX 2
+#define regDP_SYM32_ENC0_DP_SYM32_ENC_VID_MSA6 0x3668
+#define regDP_SYM32_ENC0_DP_SYM32_ENC_VID_MSA6_BASE_IDX 2
+#define regDP_SYM32_ENC0_DP_SYM32_ENC_VID_MSA7 0x3669
+#define regDP_SYM32_ENC0_DP_SYM32_ENC_VID_MSA7_BASE_IDX 2
+#define regDP_SYM32_ENC0_DP_SYM32_ENC_VID_MSA8 0x366a
+#define regDP_SYM32_ENC0_DP_SYM32_ENC_VID_MSA8_BASE_IDX 2
+#define regDP_SYM32_ENC0_DP_SYM32_ENC_HBLANK_CONTROL 0x366b
+#define regDP_SYM32_ENC0_DP_SYM32_ENC_HBLANK_CONTROL_BASE_IDX 2
+#define regDP_SYM32_ENC0_DP_SYM32_ENC_SDP_GSP_CONTROL0 0x366c
+#define regDP_SYM32_ENC0_DP_SYM32_ENC_SDP_GSP_CONTROL0_BASE_IDX 2
+#define regDP_SYM32_ENC0_DP_SYM32_ENC_SDP_GSP_CONTROL1 0x366d
+#define regDP_SYM32_ENC0_DP_SYM32_ENC_SDP_GSP_CONTROL1_BASE_IDX 2
+#define regDP_SYM32_ENC0_DP_SYM32_ENC_SDP_GSP_CONTROL2 0x366e
+#define regDP_SYM32_ENC0_DP_SYM32_ENC_SDP_GSP_CONTROL2_BASE_IDX 2
+#define regDP_SYM32_ENC0_DP_SYM32_ENC_SDP_GSP_CONTROL3 0x366f
+#define regDP_SYM32_ENC0_DP_SYM32_ENC_SDP_GSP_CONTROL3_BASE_IDX 2
+#define regDP_SYM32_ENC0_DP_SYM32_ENC_SDP_GSP_CONTROL4 0x3670
+#define regDP_SYM32_ENC0_DP_SYM32_ENC_SDP_GSP_CONTROL4_BASE_IDX 2
+#define regDP_SYM32_ENC0_DP_SYM32_ENC_SDP_GSP_CONTROL5 0x3671
+#define regDP_SYM32_ENC0_DP_SYM32_ENC_SDP_GSP_CONTROL5_BASE_IDX 2
+#define regDP_SYM32_ENC0_DP_SYM32_ENC_SDP_GSP_CONTROL6 0x3672
+#define regDP_SYM32_ENC0_DP_SYM32_ENC_SDP_GSP_CONTROL6_BASE_IDX 2
+#define regDP_SYM32_ENC0_DP_SYM32_ENC_SDP_GSP_CONTROL7 0x3673
+#define regDP_SYM32_ENC0_DP_SYM32_ENC_SDP_GSP_CONTROL7_BASE_IDX 2
+#define regDP_SYM32_ENC0_DP_SYM32_ENC_SDP_GSP_CONTROL8 0x3674
+#define regDP_SYM32_ENC0_DP_SYM32_ENC_SDP_GSP_CONTROL8_BASE_IDX 2
+#define regDP_SYM32_ENC0_DP_SYM32_ENC_SDP_GSP_CONTROL9 0x3675
+#define regDP_SYM32_ENC0_DP_SYM32_ENC_SDP_GSP_CONTROL9_BASE_IDX 2
+#define regDP_SYM32_ENC0_DP_SYM32_ENC_SDP_GSP_CONTROL10 0x3676
+#define regDP_SYM32_ENC0_DP_SYM32_ENC_SDP_GSP_CONTROL10_BASE_IDX 2
+#define regDP_SYM32_ENC0_DP_SYM32_ENC_SDP_GSP_CONTROL11 0x3677
+#define regDP_SYM32_ENC0_DP_SYM32_ENC_SDP_GSP_CONTROL11_BASE_IDX 2
+#define regDP_SYM32_ENC0_DP_SYM32_ENC_SDP_GSP_CONTROL12 0x3678
+#define regDP_SYM32_ENC0_DP_SYM32_ENC_SDP_GSP_CONTROL12_BASE_IDX 2
+#define regDP_SYM32_ENC0_DP_SYM32_ENC_SDP_GSP_CONTROL13 0x3679
+#define regDP_SYM32_ENC0_DP_SYM32_ENC_SDP_GSP_CONTROL13_BASE_IDX 2
+#define regDP_SYM32_ENC0_DP_SYM32_ENC_SDP_GSP_CONTROL14 0x367a
+#define regDP_SYM32_ENC0_DP_SYM32_ENC_SDP_GSP_CONTROL14_BASE_IDX 2
+#define regDP_SYM32_ENC0_DP_SYM32_ENC_SDP_CONTROL 0x367b
+#define regDP_SYM32_ENC0_DP_SYM32_ENC_SDP_CONTROL_BASE_IDX 2
+#define regDP_SYM32_ENC0_DP_SYM32_ENC_SDP_AUDIO_CONTROL0 0x367c
+#define regDP_SYM32_ENC0_DP_SYM32_ENC_SDP_AUDIO_CONTROL0_BASE_IDX 2
+#define regDP_SYM32_ENC0_DP_SYM32_ENC_SDP_AUDIO_CONTROL1 0x367d
+#define regDP_SYM32_ENC0_DP_SYM32_ENC_SDP_AUDIO_CONTROL1_BASE_IDX 2
+#define regDP_SYM32_ENC0_DP_SYM32_ENC_SDP_METADATA_PACKET_CONTROL 0x367e
+#define regDP_SYM32_ENC0_DP_SYM32_ENC_SDP_METADATA_PACKET_CONTROL_BASE_IDX 2
+#define regDP_SYM32_ENC0_DP_SYM32_ENC_VID_MSA_CONTROL 0x3683
+#define regDP_SYM32_ENC0_DP_SYM32_ENC_VID_MSA_CONTROL_BASE_IDX 2
+#define regDP_SYM32_ENC0_DP_SYM32_ENC_VID_VBID_CONTROL 0x3684
+#define regDP_SYM32_ENC0_DP_SYM32_ENC_VID_VBID_CONTROL_BASE_IDX 2
+#define regDP_SYM32_ENC0_DP_SYM32_ENC_VID_STREAM_CONTROL 0x3685
+#define regDP_SYM32_ENC0_DP_SYM32_ENC_VID_STREAM_CONTROL_BASE_IDX 2
+#define regDP_SYM32_ENC0_DP_SYM32_ENC_VID_PANEL_REPLAY_CONTROL 0x3686
+#define regDP_SYM32_ENC0_DP_SYM32_ENC_VID_PANEL_REPLAY_CONTROL_BASE_IDX 2
+#define regDP_SYM32_ENC0_DP_SYM32_ENC_VID_CRC_CONTROL 0x3687
+#define regDP_SYM32_ENC0_DP_SYM32_ENC_VID_CRC_CONTROL_BASE_IDX 2
+#define regDP_SYM32_ENC0_DP_SYM32_ENC_VID_CRC_RESULT0 0x3688
+#define regDP_SYM32_ENC0_DP_SYM32_ENC_VID_CRC_RESULT0_BASE_IDX 2
+#define regDP_SYM32_ENC0_DP_SYM32_ENC_VID_CRC_RESULT1 0x3689
+#define regDP_SYM32_ENC0_DP_SYM32_ENC_VID_CRC_RESULT1_BASE_IDX 2
+#define regDP_SYM32_ENC0_DP_SYM32_ENC_VID_CRC_STATUS 0x368a
+#define regDP_SYM32_ENC0_DP_SYM32_ENC_VID_CRC_STATUS_BASE_IDX 2
+#define regDP_SYM32_ENC0_DP_SYM32_ENC_MEM_POWER_CONTROL 0x368b
+#define regDP_SYM32_ENC0_DP_SYM32_ENC_MEM_POWER_CONTROL_BASE_IDX 2
+#define regDP_SYM32_ENC0_DP_SYM32_ENC_SPARE 0x368c
+#define regDP_SYM32_ENC0_DP_SYM32_ENC_SPARE_BASE_IDX 2
+
+
+// addressBlock: dce_dc_hpo_dp_stream_enc1_dispdec
+// base address: 0x1aedc
+#define regDP_STREAM_ENC1_DP_STREAM_ENC_CLOCK_CONTROL 0x36f7
+#define regDP_STREAM_ENC1_DP_STREAM_ENC_CLOCK_CONTROL_BASE_IDX 2
+#define regDP_STREAM_ENC1_DP_STREAM_ENC_INPUT_MUX_CONTROL 0x36f8
+#define regDP_STREAM_ENC1_DP_STREAM_ENC_INPUT_MUX_CONTROL_BASE_IDX 2
+#define regDP_STREAM_ENC1_DP_STREAM_ENC_AUDIO_CONTROL 0x36f9
+#define regDP_STREAM_ENC1_DP_STREAM_ENC_AUDIO_CONTROL_BASE_IDX 2
+#define regDP_STREAM_ENC1_DP_STREAM_ENC_CLOCK_RAMP_ADJUSTER_FIFO_STATUS_CONTROL0 0x36fa
+#define regDP_STREAM_ENC1_DP_STREAM_ENC_CLOCK_RAMP_ADJUSTER_FIFO_STATUS_CONTROL0_BASE_IDX 2
+#define regDP_STREAM_ENC1_DP_STREAM_ENC_CLOCK_RAMP_ADJUSTER_FIFO_STATUS_CONTROL1 0x36fb
+#define regDP_STREAM_ENC1_DP_STREAM_ENC_CLOCK_RAMP_ADJUSTER_FIFO_STATUS_CONTROL1_BASE_IDX 2
+#define regDP_STREAM_ENC1_DP_STREAM_ENC_SPARE 0x36fc
+#define regDP_STREAM_ENC1_DP_STREAM_ENC_SPARE_BASE_IDX 2
+
+
+// addressBlock: dce_dc_hpo_dp_stream_enc1_apg_apg_dispdec
+// base address: 0x1af10
+#define regAPG1_APG_CONTROL 0x3704
+#define regAPG1_APG_CONTROL_BASE_IDX 2
+#define regAPG1_APG_CONTROL2 0x3705
+#define regAPG1_APG_CONTROL2_BASE_IDX 2
+#define regAPG1_APG_DBG_GEN_CONTROL 0x3706
+#define regAPG1_APG_DBG_GEN_CONTROL_BASE_IDX 2
+#define regAPG1_APG_PACKET_CONTROL 0x3707
+#define regAPG1_APG_PACKET_CONTROL_BASE_IDX 2
+#define regAPG1_APG_AUDIO_CRC_CONTROL 0x370e
+#define regAPG1_APG_AUDIO_CRC_CONTROL_BASE_IDX 2
+#define regAPG1_APG_AUDIO_CRC_CONTROL2 0x370f
+#define regAPG1_APG_AUDIO_CRC_CONTROL2_BASE_IDX 2
+#define regAPG1_APG_AUDIO_CRC_RESULT 0x3710
+#define regAPG1_APG_AUDIO_CRC_RESULT_BASE_IDX 2
+#define regAPG1_APG_STATUS 0x3715
+#define regAPG1_APG_STATUS_BASE_IDX 2
+#define regAPG1_APG_STATUS2 0x3716
+#define regAPG1_APG_STATUS2_BASE_IDX 2
+#define regAPG1_APG_MEM_PWR 0x3718
+#define regAPG1_APG_MEM_PWR_BASE_IDX 2
+#define regAPG1_APG_SPARE 0x371a
+#define regAPG1_APG_SPARE_BASE_IDX 2
+
+
+// addressBlock: dce_dc_hpo_dp_stream_enc1_dme_dme_dispdec
+// base address: 0x1af88
+#define regDME7_DME_CONTROL 0x3722
+#define regDME7_DME_CONTROL_BASE_IDX 2
+#define regDME7_DME_MEMORY_CONTROL 0x3723
+#define regDME7_DME_MEMORY_CONTROL_BASE_IDX 2
+
+
+// addressBlock: dce_dc_hpo_dp_stream_enc1_vpg_vpg_dispdec
+// base address: 0x1af94
+#define regVPG7_VPG_GENERIC_PACKET_ACCESS_CTRL 0x3725
+#define regVPG7_VPG_GENERIC_PACKET_ACCESS_CTRL_BASE_IDX 2
+#define regVPG7_VPG_GENERIC_PACKET_DATA 0x3726
+#define regVPG7_VPG_GENERIC_PACKET_DATA_BASE_IDX 2
+#define regVPG7_VPG_GSP_FRAME_UPDATE_CTRL 0x3727
+#define regVPG7_VPG_GSP_FRAME_UPDATE_CTRL_BASE_IDX 2
+#define regVPG7_VPG_GSP_IMMEDIATE_UPDATE_CTRL 0x3728
+#define regVPG7_VPG_GSP_IMMEDIATE_UPDATE_CTRL_BASE_IDX 2
+#define regVPG7_VPG_GENERIC_STATUS 0x3729
+#define regVPG7_VPG_GENERIC_STATUS_BASE_IDX 2
+#define regVPG7_VPG_MEM_PWR 0x372a
+#define regVPG7_VPG_MEM_PWR_BASE_IDX 2
+#define regVPG7_VPG_ISRC1_2_ACCESS_CTRL 0x372b
+#define regVPG7_VPG_ISRC1_2_ACCESS_CTRL_BASE_IDX 2
+#define regVPG7_VPG_ISRC1_2_DATA 0x372c
+#define regVPG7_VPG_ISRC1_2_DATA_BASE_IDX 2
+#define regVPG7_VPG_MPEG_INFO0 0x372d
+#define regVPG7_VPG_MPEG_INFO0_BASE_IDX 2
+#define regVPG7_VPG_MPEG_INFO1 0x372e
+#define regVPG7_VPG_MPEG_INFO1_BASE_IDX 2
+
+
+// addressBlock: dce_dc_hpo_dp_sym32_enc1_dispdec
+// base address: 0x1afc4
+#define regDP_SYM32_ENC1_DP_SYM32_ENC_CONTROL 0x3731
+#define regDP_SYM32_ENC1_DP_SYM32_ENC_CONTROL_BASE_IDX 2
+#define regDP_SYM32_ENC1_DP_SYM32_ENC_VID_FIFO_CONTROL 0x3732
+#define regDP_SYM32_ENC1_DP_SYM32_ENC_VID_FIFO_CONTROL_BASE_IDX 2
+#define regDP_SYM32_ENC1_DP_SYM32_ENC_VID_MSA_DOUBLE_BUFFER_CONTROL 0x3733
+#define regDP_SYM32_ENC1_DP_SYM32_ENC_VID_MSA_DOUBLE_BUFFER_CONTROL_BASE_IDX 2
+#define regDP_SYM32_ENC1_DP_SYM32_ENC_VID_PIXEL_FORMAT_DOUBLE_BUFFER_CONTROL 0x3734
+#define regDP_SYM32_ENC1_DP_SYM32_ENC_VID_PIXEL_FORMAT_DOUBLE_BUFFER_CONTROL_BASE_IDX 2
+#define regDP_SYM32_ENC1_DP_SYM32_ENC_VID_PIXEL_FORMAT 0x3735
+#define regDP_SYM32_ENC1_DP_SYM32_ENC_VID_PIXEL_FORMAT_BASE_IDX 2
+#define regDP_SYM32_ENC1_DP_SYM32_ENC_VID_MSA0 0x3736
+#define regDP_SYM32_ENC1_DP_SYM32_ENC_VID_MSA0_BASE_IDX 2
+#define regDP_SYM32_ENC1_DP_SYM32_ENC_VID_MSA1 0x3737
+#define regDP_SYM32_ENC1_DP_SYM32_ENC_VID_MSA1_BASE_IDX 2
+#define regDP_SYM32_ENC1_DP_SYM32_ENC_VID_MSA2 0x3738
+#define regDP_SYM32_ENC1_DP_SYM32_ENC_VID_MSA2_BASE_IDX 2
+#define regDP_SYM32_ENC1_DP_SYM32_ENC_VID_MSA3 0x3739
+#define regDP_SYM32_ENC1_DP_SYM32_ENC_VID_MSA3_BASE_IDX 2
+#define regDP_SYM32_ENC1_DP_SYM32_ENC_VID_MSA4 0x373a
+#define regDP_SYM32_ENC1_DP_SYM32_ENC_VID_MSA4_BASE_IDX 2
+#define regDP_SYM32_ENC1_DP_SYM32_ENC_VID_MSA5 0x373b
+#define regDP_SYM32_ENC1_DP_SYM32_ENC_VID_MSA5_BASE_IDX 2
+#define regDP_SYM32_ENC1_DP_SYM32_ENC_VID_MSA6 0x373c
+#define regDP_SYM32_ENC1_DP_SYM32_ENC_VID_MSA6_BASE_IDX 2
+#define regDP_SYM32_ENC1_DP_SYM32_ENC_VID_MSA7 0x373d
+#define regDP_SYM32_ENC1_DP_SYM32_ENC_VID_MSA7_BASE_IDX 2
+#define regDP_SYM32_ENC1_DP_SYM32_ENC_VID_MSA8 0x373e
+#define regDP_SYM32_ENC1_DP_SYM32_ENC_VID_MSA8_BASE_IDX 2
+#define regDP_SYM32_ENC1_DP_SYM32_ENC_HBLANK_CONTROL 0x373f
+#define regDP_SYM32_ENC1_DP_SYM32_ENC_HBLANK_CONTROL_BASE_IDX 2
+#define regDP_SYM32_ENC1_DP_SYM32_ENC_SDP_GSP_CONTROL0 0x3740
+#define regDP_SYM32_ENC1_DP_SYM32_ENC_SDP_GSP_CONTROL0_BASE_IDX 2
+#define regDP_SYM32_ENC1_DP_SYM32_ENC_SDP_GSP_CONTROL1 0x3741
+#define regDP_SYM32_ENC1_DP_SYM32_ENC_SDP_GSP_CONTROL1_BASE_IDX 2
+#define regDP_SYM32_ENC1_DP_SYM32_ENC_SDP_GSP_CONTROL2 0x3742
+#define regDP_SYM32_ENC1_DP_SYM32_ENC_SDP_GSP_CONTROL2_BASE_IDX 2
+#define regDP_SYM32_ENC1_DP_SYM32_ENC_SDP_GSP_CONTROL3 0x3743
+#define regDP_SYM32_ENC1_DP_SYM32_ENC_SDP_GSP_CONTROL3_BASE_IDX 2
+#define regDP_SYM32_ENC1_DP_SYM32_ENC_SDP_GSP_CONTROL4 0x3744
+#define regDP_SYM32_ENC1_DP_SYM32_ENC_SDP_GSP_CONTROL4_BASE_IDX 2
+#define regDP_SYM32_ENC1_DP_SYM32_ENC_SDP_GSP_CONTROL5 0x3745
+#define regDP_SYM32_ENC1_DP_SYM32_ENC_SDP_GSP_CONTROL5_BASE_IDX 2
+#define regDP_SYM32_ENC1_DP_SYM32_ENC_SDP_GSP_CONTROL6 0x3746
+#define regDP_SYM32_ENC1_DP_SYM32_ENC_SDP_GSP_CONTROL6_BASE_IDX 2
+#define regDP_SYM32_ENC1_DP_SYM32_ENC_SDP_GSP_CONTROL7 0x3747
+#define regDP_SYM32_ENC1_DP_SYM32_ENC_SDP_GSP_CONTROL7_BASE_IDX 2
+#define regDP_SYM32_ENC1_DP_SYM32_ENC_SDP_GSP_CONTROL8 0x3748
+#define regDP_SYM32_ENC1_DP_SYM32_ENC_SDP_GSP_CONTROL8_BASE_IDX 2
+#define regDP_SYM32_ENC1_DP_SYM32_ENC_SDP_GSP_CONTROL9 0x3749
+#define regDP_SYM32_ENC1_DP_SYM32_ENC_SDP_GSP_CONTROL9_BASE_IDX 2
+#define regDP_SYM32_ENC1_DP_SYM32_ENC_SDP_GSP_CONTROL10 0x374a
+#define regDP_SYM32_ENC1_DP_SYM32_ENC_SDP_GSP_CONTROL10_BASE_IDX 2
+#define regDP_SYM32_ENC1_DP_SYM32_ENC_SDP_GSP_CONTROL11 0x374b
+#define regDP_SYM32_ENC1_DP_SYM32_ENC_SDP_GSP_CONTROL11_BASE_IDX 2
+#define regDP_SYM32_ENC1_DP_SYM32_ENC_SDP_GSP_CONTROL12 0x374c
+#define regDP_SYM32_ENC1_DP_SYM32_ENC_SDP_GSP_CONTROL12_BASE_IDX 2
+#define regDP_SYM32_ENC1_DP_SYM32_ENC_SDP_GSP_CONTROL13 0x374d
+#define regDP_SYM32_ENC1_DP_SYM32_ENC_SDP_GSP_CONTROL13_BASE_IDX 2
+#define regDP_SYM32_ENC1_DP_SYM32_ENC_SDP_GSP_CONTROL14 0x374e
+#define regDP_SYM32_ENC1_DP_SYM32_ENC_SDP_GSP_CONTROL14_BASE_IDX 2
+#define regDP_SYM32_ENC1_DP_SYM32_ENC_SDP_CONTROL 0x374f
+#define regDP_SYM32_ENC1_DP_SYM32_ENC_SDP_CONTROL_BASE_IDX 2
+#define regDP_SYM32_ENC1_DP_SYM32_ENC_SDP_AUDIO_CONTROL0 0x3750
+#define regDP_SYM32_ENC1_DP_SYM32_ENC_SDP_AUDIO_CONTROL0_BASE_IDX 2
+#define regDP_SYM32_ENC1_DP_SYM32_ENC_SDP_AUDIO_CONTROL1 0x3751
+#define regDP_SYM32_ENC1_DP_SYM32_ENC_SDP_AUDIO_CONTROL1_BASE_IDX 2
+#define regDP_SYM32_ENC1_DP_SYM32_ENC_SDP_METADATA_PACKET_CONTROL 0x3752
+#define regDP_SYM32_ENC1_DP_SYM32_ENC_SDP_METADATA_PACKET_CONTROL_BASE_IDX 2
+#define regDP_SYM32_ENC1_DP_SYM32_ENC_VID_MSA_CONTROL 0x3757
+#define regDP_SYM32_ENC1_DP_SYM32_ENC_VID_MSA_CONTROL_BASE_IDX 2
+#define regDP_SYM32_ENC1_DP_SYM32_ENC_VID_VBID_CONTROL 0x3758
+#define regDP_SYM32_ENC1_DP_SYM32_ENC_VID_VBID_CONTROL_BASE_IDX 2
+#define regDP_SYM32_ENC1_DP_SYM32_ENC_VID_STREAM_CONTROL 0x3759
+#define regDP_SYM32_ENC1_DP_SYM32_ENC_VID_STREAM_CONTROL_BASE_IDX 2
+#define regDP_SYM32_ENC1_DP_SYM32_ENC_VID_PANEL_REPLAY_CONTROL 0x375a
+#define regDP_SYM32_ENC1_DP_SYM32_ENC_VID_PANEL_REPLAY_CONTROL_BASE_IDX 2
+#define regDP_SYM32_ENC1_DP_SYM32_ENC_VID_CRC_CONTROL 0x375b
+#define regDP_SYM32_ENC1_DP_SYM32_ENC_VID_CRC_CONTROL_BASE_IDX 2
+#define regDP_SYM32_ENC1_DP_SYM32_ENC_VID_CRC_RESULT0 0x375c
+#define regDP_SYM32_ENC1_DP_SYM32_ENC_VID_CRC_RESULT0_BASE_IDX 2
+#define regDP_SYM32_ENC1_DP_SYM32_ENC_VID_CRC_RESULT1 0x375d
+#define regDP_SYM32_ENC1_DP_SYM32_ENC_VID_CRC_RESULT1_BASE_IDX 2
+#define regDP_SYM32_ENC1_DP_SYM32_ENC_VID_CRC_STATUS 0x375e
+#define regDP_SYM32_ENC1_DP_SYM32_ENC_VID_CRC_STATUS_BASE_IDX 2
+#define regDP_SYM32_ENC1_DP_SYM32_ENC_MEM_POWER_CONTROL 0x375f
+#define regDP_SYM32_ENC1_DP_SYM32_ENC_MEM_POWER_CONTROL_BASE_IDX 2
+#define regDP_SYM32_ENC1_DP_SYM32_ENC_SPARE 0x3760
+#define regDP_SYM32_ENC1_DP_SYM32_ENC_SPARE_BASE_IDX 2
+
+
+// addressBlock: dce_dc_hpo_dp_stream_enc2_dispdec
+// base address: 0x1b22c
+#define regDP_STREAM_ENC2_DP_STREAM_ENC_CLOCK_CONTROL 0x37cb
+#define regDP_STREAM_ENC2_DP_STREAM_ENC_CLOCK_CONTROL_BASE_IDX 2
+#define regDP_STREAM_ENC2_DP_STREAM_ENC_INPUT_MUX_CONTROL 0x37cc
+#define regDP_STREAM_ENC2_DP_STREAM_ENC_INPUT_MUX_CONTROL_BASE_IDX 2
+#define regDP_STREAM_ENC2_DP_STREAM_ENC_AUDIO_CONTROL 0x37cd
+#define regDP_STREAM_ENC2_DP_STREAM_ENC_AUDIO_CONTROL_BASE_IDX 2
+#define regDP_STREAM_ENC2_DP_STREAM_ENC_CLOCK_RAMP_ADJUSTER_FIFO_STATUS_CONTROL0 0x37ce
+#define regDP_STREAM_ENC2_DP_STREAM_ENC_CLOCK_RAMP_ADJUSTER_FIFO_STATUS_CONTROL0_BASE_IDX 2
+#define regDP_STREAM_ENC2_DP_STREAM_ENC_CLOCK_RAMP_ADJUSTER_FIFO_STATUS_CONTROL1 0x37cf
+#define regDP_STREAM_ENC2_DP_STREAM_ENC_CLOCK_RAMP_ADJUSTER_FIFO_STATUS_CONTROL1_BASE_IDX 2
+#define regDP_STREAM_ENC2_DP_STREAM_ENC_SPARE 0x37d0
+#define regDP_STREAM_ENC2_DP_STREAM_ENC_SPARE_BASE_IDX 2
+
+
+// addressBlock: dce_dc_hpo_dp_stream_enc2_apg_apg_dispdec
+// base address: 0x1b260
+#define regAPG2_APG_CONTROL 0x37d8
+#define regAPG2_APG_CONTROL_BASE_IDX 2
+#define regAPG2_APG_CONTROL2 0x37d9
+#define regAPG2_APG_CONTROL2_BASE_IDX 2
+#define regAPG2_APG_DBG_GEN_CONTROL 0x37da
+#define regAPG2_APG_DBG_GEN_CONTROL_BASE_IDX 2
+#define regAPG2_APG_PACKET_CONTROL 0x37db
+#define regAPG2_APG_PACKET_CONTROL_BASE_IDX 2
+#define regAPG2_APG_AUDIO_CRC_CONTROL 0x37e2
+#define regAPG2_APG_AUDIO_CRC_CONTROL_BASE_IDX 2
+#define regAPG2_APG_AUDIO_CRC_CONTROL2 0x37e3
+#define regAPG2_APG_AUDIO_CRC_CONTROL2_BASE_IDX 2
+#define regAPG2_APG_AUDIO_CRC_RESULT 0x37e4
+#define regAPG2_APG_AUDIO_CRC_RESULT_BASE_IDX 2
+#define regAPG2_APG_STATUS 0x37e9
+#define regAPG2_APG_STATUS_BASE_IDX 2
+#define regAPG2_APG_STATUS2 0x37ea
+#define regAPG2_APG_STATUS2_BASE_IDX 2
+#define regAPG2_APG_MEM_PWR 0x37ec
+#define regAPG2_APG_MEM_PWR_BASE_IDX 2
+#define regAPG2_APG_SPARE 0x37ee
+#define regAPG2_APG_SPARE_BASE_IDX 2
+
+
+// addressBlock: dce_dc_hpo_dp_stream_enc2_dme_dme_dispdec
+// base address: 0x1b2d8
+#define regDME8_DME_CONTROL 0x37f6
+#define regDME8_DME_CONTROL_BASE_IDX 2
+#define regDME8_DME_MEMORY_CONTROL 0x37f7
+#define regDME8_DME_MEMORY_CONTROL_BASE_IDX 2
+
+
+// addressBlock: dce_dc_hpo_dp_stream_enc2_vpg_vpg_dispdec
+// base address: 0x1b2e4
+#define regVPG8_VPG_GENERIC_PACKET_ACCESS_CTRL 0x37f9
+#define regVPG8_VPG_GENERIC_PACKET_ACCESS_CTRL_BASE_IDX 2
+#define regVPG8_VPG_GENERIC_PACKET_DATA 0x37fa
+#define regVPG8_VPG_GENERIC_PACKET_DATA_BASE_IDX 2
+#define regVPG8_VPG_GSP_FRAME_UPDATE_CTRL 0x37fb
+#define regVPG8_VPG_GSP_FRAME_UPDATE_CTRL_BASE_IDX 2
+#define regVPG8_VPG_GSP_IMMEDIATE_UPDATE_CTRL 0x37fc
+#define regVPG8_VPG_GSP_IMMEDIATE_UPDATE_CTRL_BASE_IDX 2
+#define regVPG8_VPG_GENERIC_STATUS 0x37fd
+#define regVPG8_VPG_GENERIC_STATUS_BASE_IDX 2
+#define regVPG8_VPG_MEM_PWR 0x37fe
+#define regVPG8_VPG_MEM_PWR_BASE_IDX 2
+#define regVPG8_VPG_ISRC1_2_ACCESS_CTRL 0x37ff
+#define regVPG8_VPG_ISRC1_2_ACCESS_CTRL_BASE_IDX 2
+#define regVPG8_VPG_ISRC1_2_DATA 0x3800
+#define regVPG8_VPG_ISRC1_2_DATA_BASE_IDX 2
+#define regVPG8_VPG_MPEG_INFO0 0x3801
+#define regVPG8_VPG_MPEG_INFO0_BASE_IDX 2
+#define regVPG8_VPG_MPEG_INFO1 0x3802
+#define regVPG8_VPG_MPEG_INFO1_BASE_IDX 2
+
+
+// addressBlock: dce_dc_hpo_dp_sym32_enc2_dispdec
+// base address: 0x1b314
+#define regDP_SYM32_ENC2_DP_SYM32_ENC_CONTROL 0x3805
+#define regDP_SYM32_ENC2_DP_SYM32_ENC_CONTROL_BASE_IDX 2
+#define regDP_SYM32_ENC2_DP_SYM32_ENC_VID_FIFO_CONTROL 0x3806
+#define regDP_SYM32_ENC2_DP_SYM32_ENC_VID_FIFO_CONTROL_BASE_IDX 2
+#define regDP_SYM32_ENC2_DP_SYM32_ENC_VID_MSA_DOUBLE_BUFFER_CONTROL 0x3807
+#define regDP_SYM32_ENC2_DP_SYM32_ENC_VID_MSA_DOUBLE_BUFFER_CONTROL_BASE_IDX 2
+#define regDP_SYM32_ENC2_DP_SYM32_ENC_VID_PIXEL_FORMAT_DOUBLE_BUFFER_CONTROL 0x3808
+#define regDP_SYM32_ENC2_DP_SYM32_ENC_VID_PIXEL_FORMAT_DOUBLE_BUFFER_CONTROL_BASE_IDX 2
+#define regDP_SYM32_ENC2_DP_SYM32_ENC_VID_PIXEL_FORMAT 0x3809
+#define regDP_SYM32_ENC2_DP_SYM32_ENC_VID_PIXEL_FORMAT_BASE_IDX 2
+#define regDP_SYM32_ENC2_DP_SYM32_ENC_VID_MSA0 0x380a
+#define regDP_SYM32_ENC2_DP_SYM32_ENC_VID_MSA0_BASE_IDX 2
+#define regDP_SYM32_ENC2_DP_SYM32_ENC_VID_MSA1 0x380b
+#define regDP_SYM32_ENC2_DP_SYM32_ENC_VID_MSA1_BASE_IDX 2
+#define regDP_SYM32_ENC2_DP_SYM32_ENC_VID_MSA2 0x380c
+#define regDP_SYM32_ENC2_DP_SYM32_ENC_VID_MSA2_BASE_IDX 2
+#define regDP_SYM32_ENC2_DP_SYM32_ENC_VID_MSA3 0x380d
+#define regDP_SYM32_ENC2_DP_SYM32_ENC_VID_MSA3_BASE_IDX 2
+#define regDP_SYM32_ENC2_DP_SYM32_ENC_VID_MSA4 0x380e
+#define regDP_SYM32_ENC2_DP_SYM32_ENC_VID_MSA4_BASE_IDX 2
+#define regDP_SYM32_ENC2_DP_SYM32_ENC_VID_MSA5 0x380f
+#define regDP_SYM32_ENC2_DP_SYM32_ENC_VID_MSA5_BASE_IDX 2
+#define regDP_SYM32_ENC2_DP_SYM32_ENC_VID_MSA6 0x3810
+#define regDP_SYM32_ENC2_DP_SYM32_ENC_VID_MSA6_BASE_IDX 2
+#define regDP_SYM32_ENC2_DP_SYM32_ENC_VID_MSA7 0x3811
+#define regDP_SYM32_ENC2_DP_SYM32_ENC_VID_MSA7_BASE_IDX 2
+#define regDP_SYM32_ENC2_DP_SYM32_ENC_VID_MSA8 0x3812
+#define regDP_SYM32_ENC2_DP_SYM32_ENC_VID_MSA8_BASE_IDX 2
+#define regDP_SYM32_ENC2_DP_SYM32_ENC_HBLANK_CONTROL 0x3813
+#define regDP_SYM32_ENC2_DP_SYM32_ENC_HBLANK_CONTROL_BASE_IDX 2
+#define regDP_SYM32_ENC2_DP_SYM32_ENC_SDP_GSP_CONTROL0 0x3814
+#define regDP_SYM32_ENC2_DP_SYM32_ENC_SDP_GSP_CONTROL0_BASE_IDX 2
+#define regDP_SYM32_ENC2_DP_SYM32_ENC_SDP_GSP_CONTROL1 0x3815
+#define regDP_SYM32_ENC2_DP_SYM32_ENC_SDP_GSP_CONTROL1_BASE_IDX 2
+#define regDP_SYM32_ENC2_DP_SYM32_ENC_SDP_GSP_CONTROL2 0x3816
+#define regDP_SYM32_ENC2_DP_SYM32_ENC_SDP_GSP_CONTROL2_BASE_IDX 2
+#define regDP_SYM32_ENC2_DP_SYM32_ENC_SDP_GSP_CONTROL3 0x3817
+#define regDP_SYM32_ENC2_DP_SYM32_ENC_SDP_GSP_CONTROL3_BASE_IDX 2
+#define regDP_SYM32_ENC2_DP_SYM32_ENC_SDP_GSP_CONTROL4 0x3818
+#define regDP_SYM32_ENC2_DP_SYM32_ENC_SDP_GSP_CONTROL4_BASE_IDX 2
+#define regDP_SYM32_ENC2_DP_SYM32_ENC_SDP_GSP_CONTROL5 0x3819
+#define regDP_SYM32_ENC2_DP_SYM32_ENC_SDP_GSP_CONTROL5_BASE_IDX 2
+#define regDP_SYM32_ENC2_DP_SYM32_ENC_SDP_GSP_CONTROL6 0x381a
+#define regDP_SYM32_ENC2_DP_SYM32_ENC_SDP_GSP_CONTROL6_BASE_IDX 2
+#define regDP_SYM32_ENC2_DP_SYM32_ENC_SDP_GSP_CONTROL7 0x381b
+#define regDP_SYM32_ENC2_DP_SYM32_ENC_SDP_GSP_CONTROL7_BASE_IDX 2
+#define regDP_SYM32_ENC2_DP_SYM32_ENC_SDP_GSP_CONTROL8 0x381c
+#define regDP_SYM32_ENC2_DP_SYM32_ENC_SDP_GSP_CONTROL8_BASE_IDX 2
+#define regDP_SYM32_ENC2_DP_SYM32_ENC_SDP_GSP_CONTROL9 0x381d
+#define regDP_SYM32_ENC2_DP_SYM32_ENC_SDP_GSP_CONTROL9_BASE_IDX 2
+#define regDP_SYM32_ENC2_DP_SYM32_ENC_SDP_GSP_CONTROL10 0x381e
+#define regDP_SYM32_ENC2_DP_SYM32_ENC_SDP_GSP_CONTROL10_BASE_IDX 2
+#define regDP_SYM32_ENC2_DP_SYM32_ENC_SDP_GSP_CONTROL11 0x381f
+#define regDP_SYM32_ENC2_DP_SYM32_ENC_SDP_GSP_CONTROL11_BASE_IDX 2
+#define regDP_SYM32_ENC2_DP_SYM32_ENC_SDP_GSP_CONTROL12 0x3820
+#define regDP_SYM32_ENC2_DP_SYM32_ENC_SDP_GSP_CONTROL12_BASE_IDX 2
+#define regDP_SYM32_ENC2_DP_SYM32_ENC_SDP_GSP_CONTROL13 0x3821
+#define regDP_SYM32_ENC2_DP_SYM32_ENC_SDP_GSP_CONTROL13_BASE_IDX 2
+#define regDP_SYM32_ENC2_DP_SYM32_ENC_SDP_GSP_CONTROL14 0x3822
+#define regDP_SYM32_ENC2_DP_SYM32_ENC_SDP_GSP_CONTROL14_BASE_IDX 2
+#define regDP_SYM32_ENC2_DP_SYM32_ENC_SDP_CONTROL 0x3823
+#define regDP_SYM32_ENC2_DP_SYM32_ENC_SDP_CONTROL_BASE_IDX 2
+#define regDP_SYM32_ENC2_DP_SYM32_ENC_SDP_AUDIO_CONTROL0 0x3824
+#define regDP_SYM32_ENC2_DP_SYM32_ENC_SDP_AUDIO_CONTROL0_BASE_IDX 2
+#define regDP_SYM32_ENC2_DP_SYM32_ENC_SDP_AUDIO_CONTROL1 0x3825
+#define regDP_SYM32_ENC2_DP_SYM32_ENC_SDP_AUDIO_CONTROL1_BASE_IDX 2
+#define regDP_SYM32_ENC2_DP_SYM32_ENC_SDP_METADATA_PACKET_CONTROL 0x3826
+#define regDP_SYM32_ENC2_DP_SYM32_ENC_SDP_METADATA_PACKET_CONTROL_BASE_IDX 2
+#define regDP_SYM32_ENC2_DP_SYM32_ENC_VID_MSA_CONTROL 0x382b
+#define regDP_SYM32_ENC2_DP_SYM32_ENC_VID_MSA_CONTROL_BASE_IDX 2
+#define regDP_SYM32_ENC2_DP_SYM32_ENC_VID_VBID_CONTROL 0x382c
+#define regDP_SYM32_ENC2_DP_SYM32_ENC_VID_VBID_CONTROL_BASE_IDX 2
+#define regDP_SYM32_ENC2_DP_SYM32_ENC_VID_STREAM_CONTROL 0x382d
+#define regDP_SYM32_ENC2_DP_SYM32_ENC_VID_STREAM_CONTROL_BASE_IDX 2
+#define regDP_SYM32_ENC2_DP_SYM32_ENC_VID_PANEL_REPLAY_CONTROL 0x382e
+#define regDP_SYM32_ENC2_DP_SYM32_ENC_VID_PANEL_REPLAY_CONTROL_BASE_IDX 2
+#define regDP_SYM32_ENC2_DP_SYM32_ENC_VID_CRC_CONTROL 0x382f
+#define regDP_SYM32_ENC2_DP_SYM32_ENC_VID_CRC_CONTROL_BASE_IDX 2
+#define regDP_SYM32_ENC2_DP_SYM32_ENC_VID_CRC_RESULT0 0x3830
+#define regDP_SYM32_ENC2_DP_SYM32_ENC_VID_CRC_RESULT0_BASE_IDX 2
+#define regDP_SYM32_ENC2_DP_SYM32_ENC_VID_CRC_RESULT1 0x3831
+#define regDP_SYM32_ENC2_DP_SYM32_ENC_VID_CRC_RESULT1_BASE_IDX 2
+#define regDP_SYM32_ENC2_DP_SYM32_ENC_VID_CRC_STATUS 0x3832
+#define regDP_SYM32_ENC2_DP_SYM32_ENC_VID_CRC_STATUS_BASE_IDX 2
+#define regDP_SYM32_ENC2_DP_SYM32_ENC_MEM_POWER_CONTROL 0x3833
+#define regDP_SYM32_ENC2_DP_SYM32_ENC_MEM_POWER_CONTROL_BASE_IDX 2
+#define regDP_SYM32_ENC2_DP_SYM32_ENC_SPARE 0x3834
+#define regDP_SYM32_ENC2_DP_SYM32_ENC_SPARE_BASE_IDX 2
+
+
+// addressBlock: dce_dc_hpo_dp_stream_enc3_dispdec
+// base address: 0x1b57c
+#define regDP_STREAM_ENC3_DP_STREAM_ENC_CLOCK_CONTROL 0x389f
+#define regDP_STREAM_ENC3_DP_STREAM_ENC_CLOCK_CONTROL_BASE_IDX 2
+#define regDP_STREAM_ENC3_DP_STREAM_ENC_INPUT_MUX_CONTROL 0x38a0
+#define regDP_STREAM_ENC3_DP_STREAM_ENC_INPUT_MUX_CONTROL_BASE_IDX 2
+#define regDP_STREAM_ENC3_DP_STREAM_ENC_AUDIO_CONTROL 0x38a1
+#define regDP_STREAM_ENC3_DP_STREAM_ENC_AUDIO_CONTROL_BASE_IDX 2
+#define regDP_STREAM_ENC3_DP_STREAM_ENC_CLOCK_RAMP_ADJUSTER_FIFO_STATUS_CONTROL0 0x38a2
+#define regDP_STREAM_ENC3_DP_STREAM_ENC_CLOCK_RAMP_ADJUSTER_FIFO_STATUS_CONTROL0_BASE_IDX 2
+#define regDP_STREAM_ENC3_DP_STREAM_ENC_CLOCK_RAMP_ADJUSTER_FIFO_STATUS_CONTROL1 0x38a3
+#define regDP_STREAM_ENC3_DP_STREAM_ENC_CLOCK_RAMP_ADJUSTER_FIFO_STATUS_CONTROL1_BASE_IDX 2
+#define regDP_STREAM_ENC3_DP_STREAM_ENC_SPARE 0x38a4
+#define regDP_STREAM_ENC3_DP_STREAM_ENC_SPARE_BASE_IDX 2
+
+
+// addressBlock: dce_dc_hpo_dp_stream_enc3_apg_apg_dispdec
+// base address: 0x1b5b0
+#define regAPG3_APG_CONTROL 0x38ac
+#define regAPG3_APG_CONTROL_BASE_IDX 2
+#define regAPG3_APG_CONTROL2 0x38ad
+#define regAPG3_APG_CONTROL2_BASE_IDX 2
+#define regAPG3_APG_DBG_GEN_CONTROL 0x38ae
+#define regAPG3_APG_DBG_GEN_CONTROL_BASE_IDX 2
+#define regAPG3_APG_PACKET_CONTROL 0x38af
+#define regAPG3_APG_PACKET_CONTROL_BASE_IDX 2
+#define regAPG3_APG_AUDIO_CRC_CONTROL 0x38b6
+#define regAPG3_APG_AUDIO_CRC_CONTROL_BASE_IDX 2
+#define regAPG3_APG_AUDIO_CRC_CONTROL2 0x38b7
+#define regAPG3_APG_AUDIO_CRC_CONTROL2_BASE_IDX 2
+#define regAPG3_APG_AUDIO_CRC_RESULT 0x38b8
+#define regAPG3_APG_AUDIO_CRC_RESULT_BASE_IDX 2
+#define regAPG3_APG_STATUS 0x38bd
+#define regAPG3_APG_STATUS_BASE_IDX 2
+#define regAPG3_APG_STATUS2 0x38be
+#define regAPG3_APG_STATUS2_BASE_IDX 2
+#define regAPG3_APG_MEM_PWR 0x38c0
+#define regAPG3_APG_MEM_PWR_BASE_IDX 2
+#define regAPG3_APG_SPARE 0x38c2
+#define regAPG3_APG_SPARE_BASE_IDX 2
+
+
+// addressBlock: dce_dc_hpo_dp_stream_enc3_dme_dme_dispdec
+// base address: 0x1b628
+#define regDME9_DME_CONTROL 0x38ca
+#define regDME9_DME_CONTROL_BASE_IDX 2
+#define regDME9_DME_MEMORY_CONTROL 0x38cb
+#define regDME9_DME_MEMORY_CONTROL_BASE_IDX 2
+
+
+// addressBlock: dce_dc_hpo_dp_stream_enc3_vpg_vpg_dispdec
+// base address: 0x1b634
+#define regVPG9_VPG_GENERIC_PACKET_ACCESS_CTRL 0x38cd
+#define regVPG9_VPG_GENERIC_PACKET_ACCESS_CTRL_BASE_IDX 2
+#define regVPG9_VPG_GENERIC_PACKET_DATA 0x38ce
+#define regVPG9_VPG_GENERIC_PACKET_DATA_BASE_IDX 2
+#define regVPG9_VPG_GSP_FRAME_UPDATE_CTRL 0x38cf
+#define regVPG9_VPG_GSP_FRAME_UPDATE_CTRL_BASE_IDX 2
+#define regVPG9_VPG_GSP_IMMEDIATE_UPDATE_CTRL 0x38d0
+#define regVPG9_VPG_GSP_IMMEDIATE_UPDATE_CTRL_BASE_IDX 2
+#define regVPG9_VPG_GENERIC_STATUS 0x38d1
+#define regVPG9_VPG_GENERIC_STATUS_BASE_IDX 2
+#define regVPG9_VPG_MEM_PWR 0x38d2
+#define regVPG9_VPG_MEM_PWR_BASE_IDX 2
+#define regVPG9_VPG_ISRC1_2_ACCESS_CTRL 0x38d3
+#define regVPG9_VPG_ISRC1_2_ACCESS_CTRL_BASE_IDX 2
+#define regVPG9_VPG_ISRC1_2_DATA 0x38d4
+#define regVPG9_VPG_ISRC1_2_DATA_BASE_IDX 2
+#define regVPG9_VPG_MPEG_INFO0 0x38d5
+#define regVPG9_VPG_MPEG_INFO0_BASE_IDX 2
+#define regVPG9_VPG_MPEG_INFO1 0x38d6
+#define regVPG9_VPG_MPEG_INFO1_BASE_IDX 2
+
+
+// addressBlock: dce_dc_hpo_dp_sym32_enc3_dispdec
+// base address: 0x1b664
+#define regDP_SYM32_ENC3_DP_SYM32_ENC_CONTROL 0x38d9
+#define regDP_SYM32_ENC3_DP_SYM32_ENC_CONTROL_BASE_IDX 2
+#define regDP_SYM32_ENC3_DP_SYM32_ENC_VID_FIFO_CONTROL 0x38da
+#define regDP_SYM32_ENC3_DP_SYM32_ENC_VID_FIFO_CONTROL_BASE_IDX 2
+#define regDP_SYM32_ENC3_DP_SYM32_ENC_VID_MSA_DOUBLE_BUFFER_CONTROL 0x38db
+#define regDP_SYM32_ENC3_DP_SYM32_ENC_VID_MSA_DOUBLE_BUFFER_CONTROL_BASE_IDX 2
+#define regDP_SYM32_ENC3_DP_SYM32_ENC_VID_PIXEL_FORMAT_DOUBLE_BUFFER_CONTROL 0x38dc
+#define regDP_SYM32_ENC3_DP_SYM32_ENC_VID_PIXEL_FORMAT_DOUBLE_BUFFER_CONTROL_BASE_IDX 2
+#define regDP_SYM32_ENC3_DP_SYM32_ENC_VID_PIXEL_FORMAT 0x38dd
+#define regDP_SYM32_ENC3_DP_SYM32_ENC_VID_PIXEL_FORMAT_BASE_IDX 2
+#define regDP_SYM32_ENC3_DP_SYM32_ENC_VID_MSA0 0x38de
+#define regDP_SYM32_ENC3_DP_SYM32_ENC_VID_MSA0_BASE_IDX 2
+#define regDP_SYM32_ENC3_DP_SYM32_ENC_VID_MSA1 0x38df
+#define regDP_SYM32_ENC3_DP_SYM32_ENC_VID_MSA1_BASE_IDX 2
+#define regDP_SYM32_ENC3_DP_SYM32_ENC_VID_MSA2 0x38e0
+#define regDP_SYM32_ENC3_DP_SYM32_ENC_VID_MSA2_BASE_IDX 2
+#define regDP_SYM32_ENC3_DP_SYM32_ENC_VID_MSA3 0x38e1
+#define regDP_SYM32_ENC3_DP_SYM32_ENC_VID_MSA3_BASE_IDX 2
+#define regDP_SYM32_ENC3_DP_SYM32_ENC_VID_MSA4 0x38e2
+#define regDP_SYM32_ENC3_DP_SYM32_ENC_VID_MSA4_BASE_IDX 2
+#define regDP_SYM32_ENC3_DP_SYM32_ENC_VID_MSA5 0x38e3
+#define regDP_SYM32_ENC3_DP_SYM32_ENC_VID_MSA5_BASE_IDX 2
+#define regDP_SYM32_ENC3_DP_SYM32_ENC_VID_MSA6 0x38e4
+#define regDP_SYM32_ENC3_DP_SYM32_ENC_VID_MSA6_BASE_IDX 2
+#define regDP_SYM32_ENC3_DP_SYM32_ENC_VID_MSA7 0x38e5
+#define regDP_SYM32_ENC3_DP_SYM32_ENC_VID_MSA7_BASE_IDX 2
+#define regDP_SYM32_ENC3_DP_SYM32_ENC_VID_MSA8 0x38e6
+#define regDP_SYM32_ENC3_DP_SYM32_ENC_VID_MSA8_BASE_IDX 2
+#define regDP_SYM32_ENC3_DP_SYM32_ENC_HBLANK_CONTROL 0x38e7
+#define regDP_SYM32_ENC3_DP_SYM32_ENC_HBLANK_CONTROL_BASE_IDX 2
+#define regDP_SYM32_ENC3_DP_SYM32_ENC_SDP_GSP_CONTROL0 0x38e8
+#define regDP_SYM32_ENC3_DP_SYM32_ENC_SDP_GSP_CONTROL0_BASE_IDX 2
+#define regDP_SYM32_ENC3_DP_SYM32_ENC_SDP_GSP_CONTROL1 0x38e9
+#define regDP_SYM32_ENC3_DP_SYM32_ENC_SDP_GSP_CONTROL1_BASE_IDX 2
+#define regDP_SYM32_ENC3_DP_SYM32_ENC_SDP_GSP_CONTROL2 0x38ea
+#define regDP_SYM32_ENC3_DP_SYM32_ENC_SDP_GSP_CONTROL2_BASE_IDX 2
+#define regDP_SYM32_ENC3_DP_SYM32_ENC_SDP_GSP_CONTROL3 0x38eb
+#define regDP_SYM32_ENC3_DP_SYM32_ENC_SDP_GSP_CONTROL3_BASE_IDX 2
+#define regDP_SYM32_ENC3_DP_SYM32_ENC_SDP_GSP_CONTROL4 0x38ec
+#define regDP_SYM32_ENC3_DP_SYM32_ENC_SDP_GSP_CONTROL4_BASE_IDX 2
+#define regDP_SYM32_ENC3_DP_SYM32_ENC_SDP_GSP_CONTROL5 0x38ed
+#define regDP_SYM32_ENC3_DP_SYM32_ENC_SDP_GSP_CONTROL5_BASE_IDX 2
+#define regDP_SYM32_ENC3_DP_SYM32_ENC_SDP_GSP_CONTROL6 0x38ee
+#define regDP_SYM32_ENC3_DP_SYM32_ENC_SDP_GSP_CONTROL6_BASE_IDX 2
+#define regDP_SYM32_ENC3_DP_SYM32_ENC_SDP_GSP_CONTROL7 0x38ef
+#define regDP_SYM32_ENC3_DP_SYM32_ENC_SDP_GSP_CONTROL7_BASE_IDX 2
+#define regDP_SYM32_ENC3_DP_SYM32_ENC_SDP_GSP_CONTROL8 0x38f0
+#define regDP_SYM32_ENC3_DP_SYM32_ENC_SDP_GSP_CONTROL8_BASE_IDX 2
+#define regDP_SYM32_ENC3_DP_SYM32_ENC_SDP_GSP_CONTROL9 0x38f1
+#define regDP_SYM32_ENC3_DP_SYM32_ENC_SDP_GSP_CONTROL9_BASE_IDX 2
+#define regDP_SYM32_ENC3_DP_SYM32_ENC_SDP_GSP_CONTROL10 0x38f2
+#define regDP_SYM32_ENC3_DP_SYM32_ENC_SDP_GSP_CONTROL10_BASE_IDX 2
+#define regDP_SYM32_ENC3_DP_SYM32_ENC_SDP_GSP_CONTROL11 0x38f3
+#define regDP_SYM32_ENC3_DP_SYM32_ENC_SDP_GSP_CONTROL11_BASE_IDX 2
+#define regDP_SYM32_ENC3_DP_SYM32_ENC_SDP_GSP_CONTROL12 0x38f4
+#define regDP_SYM32_ENC3_DP_SYM32_ENC_SDP_GSP_CONTROL12_BASE_IDX 2
+#define regDP_SYM32_ENC3_DP_SYM32_ENC_SDP_GSP_CONTROL13 0x38f5
+#define regDP_SYM32_ENC3_DP_SYM32_ENC_SDP_GSP_CONTROL13_BASE_IDX 2
+#define regDP_SYM32_ENC3_DP_SYM32_ENC_SDP_GSP_CONTROL14 0x38f6
+#define regDP_SYM32_ENC3_DP_SYM32_ENC_SDP_GSP_CONTROL14_BASE_IDX 2
+#define regDP_SYM32_ENC3_DP_SYM32_ENC_SDP_CONTROL 0x38f7
+#define regDP_SYM32_ENC3_DP_SYM32_ENC_SDP_CONTROL_BASE_IDX 2
+#define regDP_SYM32_ENC3_DP_SYM32_ENC_SDP_AUDIO_CONTROL0 0x38f8
+#define regDP_SYM32_ENC3_DP_SYM32_ENC_SDP_AUDIO_CONTROL0_BASE_IDX 2
+#define regDP_SYM32_ENC3_DP_SYM32_ENC_SDP_AUDIO_CONTROL1 0x38f9
+#define regDP_SYM32_ENC3_DP_SYM32_ENC_SDP_AUDIO_CONTROL1_BASE_IDX 2
+#define regDP_SYM32_ENC3_DP_SYM32_ENC_SDP_METADATA_PACKET_CONTROL 0x38fa
+#define regDP_SYM32_ENC3_DP_SYM32_ENC_SDP_METADATA_PACKET_CONTROL_BASE_IDX 2
+#define regDP_SYM32_ENC3_DP_SYM32_ENC_VID_MSA_CONTROL 0x38ff
+#define regDP_SYM32_ENC3_DP_SYM32_ENC_VID_MSA_CONTROL_BASE_IDX 2
+#define regDP_SYM32_ENC3_DP_SYM32_ENC_VID_VBID_CONTROL 0x3900
+#define regDP_SYM32_ENC3_DP_SYM32_ENC_VID_VBID_CONTROL_BASE_IDX 2
+#define regDP_SYM32_ENC3_DP_SYM32_ENC_VID_STREAM_CONTROL 0x3901
+#define regDP_SYM32_ENC3_DP_SYM32_ENC_VID_STREAM_CONTROL_BASE_IDX 2
+#define regDP_SYM32_ENC3_DP_SYM32_ENC_VID_PANEL_REPLAY_CONTROL 0x3902
+#define regDP_SYM32_ENC3_DP_SYM32_ENC_VID_PANEL_REPLAY_CONTROL_BASE_IDX 2
+#define regDP_SYM32_ENC3_DP_SYM32_ENC_VID_CRC_CONTROL 0x3903
+#define regDP_SYM32_ENC3_DP_SYM32_ENC_VID_CRC_CONTROL_BASE_IDX 2
+#define regDP_SYM32_ENC3_DP_SYM32_ENC_VID_CRC_RESULT0 0x3904
+#define regDP_SYM32_ENC3_DP_SYM32_ENC_VID_CRC_RESULT0_BASE_IDX 2
+#define regDP_SYM32_ENC3_DP_SYM32_ENC_VID_CRC_RESULT1 0x3905
+#define regDP_SYM32_ENC3_DP_SYM32_ENC_VID_CRC_RESULT1_BASE_IDX 2
+#define regDP_SYM32_ENC3_DP_SYM32_ENC_VID_CRC_STATUS 0x3906
+#define regDP_SYM32_ENC3_DP_SYM32_ENC_VID_CRC_STATUS_BASE_IDX 2
+#define regDP_SYM32_ENC3_DP_SYM32_ENC_MEM_POWER_CONTROL 0x3907
+#define regDP_SYM32_ENC3_DP_SYM32_ENC_MEM_POWER_CONTROL_BASE_IDX 2
+#define regDP_SYM32_ENC3_DP_SYM32_ENC_SPARE 0x3908
+#define regDP_SYM32_ENC3_DP_SYM32_ENC_SPARE_BASE_IDX 2
+
+
+// addressBlock: dce_dc_hpo_dp_link_enc0_dispdec
+// base address: 0x1ad5c
+#define regDP_LINK_ENC0_DP_LINK_ENC_CLOCK_CONTROL 0x3697
+#define regDP_LINK_ENC0_DP_LINK_ENC_CLOCK_CONTROL_BASE_IDX 2
+#define regDP_LINK_ENC0_DP_LINK_ENC_SPARE 0x3698
+#define regDP_LINK_ENC0_DP_LINK_ENC_SPARE_BASE_IDX 2
+
+
+// addressBlock: dce_dc_hpo_dp_dphy_sym320_dispdec
+// base address: 0x1ae00
+#define regDP_DPHY_SYM320_DP_DPHY_SYM32_CONTROL 0x36c0
+#define regDP_DPHY_SYM320_DP_DPHY_SYM32_CONTROL_BASE_IDX 2
+#define regDP_DPHY_SYM320_DP_DPHY_SYM32_STATUS 0x36c1
+#define regDP_DPHY_SYM320_DP_DPHY_SYM32_STATUS_BASE_IDX 2
+#define regDP_DPHY_SYM320_DP_DPHY_SYM32_SAT_UPDATE 0x36c4
+#define regDP_DPHY_SYM320_DP_DPHY_SYM32_SAT_UPDATE_BASE_IDX 2
+#define regDP_DPHY_SYM320_DP_DPHY_SYM32_VC_RATE_CNTL0 0x36c5
+#define regDP_DPHY_SYM320_DP_DPHY_SYM32_VC_RATE_CNTL0_BASE_IDX 2
+#define regDP_DPHY_SYM320_DP_DPHY_SYM32_VC_RATE_CNTL1 0x36c6
+#define regDP_DPHY_SYM320_DP_DPHY_SYM32_VC_RATE_CNTL1_BASE_IDX 2
+#define regDP_DPHY_SYM320_DP_DPHY_SYM32_VC_RATE_CNTL2 0x36c7
+#define regDP_DPHY_SYM320_DP_DPHY_SYM32_VC_RATE_CNTL2_BASE_IDX 2
+#define regDP_DPHY_SYM320_DP_DPHY_SYM32_VC_RATE_CNTL3 0x36c8
+#define regDP_DPHY_SYM320_DP_DPHY_SYM32_VC_RATE_CNTL3_BASE_IDX 2
+#define regDP_DPHY_SYM320_DP_DPHY_SYM32_SAT_VC0 0x36cb
+#define regDP_DPHY_SYM320_DP_DPHY_SYM32_SAT_VC0_BASE_IDX 2
+#define regDP_DPHY_SYM320_DP_DPHY_SYM32_SAT_VC1 0x36cc
+#define regDP_DPHY_SYM320_DP_DPHY_SYM32_SAT_VC1_BASE_IDX 2
+#define regDP_DPHY_SYM320_DP_DPHY_SYM32_SAT_VC2 0x36cd
+#define regDP_DPHY_SYM320_DP_DPHY_SYM32_SAT_VC2_BASE_IDX 2
+#define regDP_DPHY_SYM320_DP_DPHY_SYM32_SAT_VC3 0x36ce
+#define regDP_DPHY_SYM320_DP_DPHY_SYM32_SAT_VC3_BASE_IDX 2
+#define regDP_DPHY_SYM320_DP_DPHY_SYM32_SAT_VC_STATUS0 0x36d1
+#define regDP_DPHY_SYM320_DP_DPHY_SYM32_SAT_VC_STATUS0_BASE_IDX 2
+#define regDP_DPHY_SYM320_DP_DPHY_SYM32_SAT_VC_STATUS1 0x36d2
+#define regDP_DPHY_SYM320_DP_DPHY_SYM32_SAT_VC_STATUS1_BASE_IDX 2
+#define regDP_DPHY_SYM320_DP_DPHY_SYM32_SAT_VC_STATUS2 0x36d3
+#define regDP_DPHY_SYM320_DP_DPHY_SYM32_SAT_VC_STATUS2_BASE_IDX 2
+#define regDP_DPHY_SYM320_DP_DPHY_SYM32_SAT_VC_STATUS3 0x36d4
+#define regDP_DPHY_SYM320_DP_DPHY_SYM32_SAT_VC_STATUS3_BASE_IDX 2
+#define regDP_DPHY_SYM320_DP_DPHY_SYM32_TP_CONFIG 0x36d7
+#define regDP_DPHY_SYM320_DP_DPHY_SYM32_TP_CONFIG_BASE_IDX 2
+#define regDP_DPHY_SYM320_DP_DPHY_SYM32_TP_PRBS_SEED0 0x36d8
+#define regDP_DPHY_SYM320_DP_DPHY_SYM32_TP_PRBS_SEED0_BASE_IDX 2
+#define regDP_DPHY_SYM320_DP_DPHY_SYM32_TP_PRBS_SEED1 0x36d9
+#define regDP_DPHY_SYM320_DP_DPHY_SYM32_TP_PRBS_SEED1_BASE_IDX 2
+#define regDP_DPHY_SYM320_DP_DPHY_SYM32_TP_PRBS_SEED2 0x36da
+#define regDP_DPHY_SYM320_DP_DPHY_SYM32_TP_PRBS_SEED2_BASE_IDX 2
+#define regDP_DPHY_SYM320_DP_DPHY_SYM32_TP_PRBS_SEED3 0x36db
+#define regDP_DPHY_SYM320_DP_DPHY_SYM32_TP_PRBS_SEED3_BASE_IDX 2
+#define regDP_DPHY_SYM320_DP_DPHY_SYM32_TP_SQ_PULSE 0x36dc
+#define regDP_DPHY_SYM320_DP_DPHY_SYM32_TP_SQ_PULSE_BASE_IDX 2
+#define regDP_DPHY_SYM320_DP_DPHY_SYM32_TP_CUSTOM0 0x36dd
+#define regDP_DPHY_SYM320_DP_DPHY_SYM32_TP_CUSTOM0_BASE_IDX 2
+#define regDP_DPHY_SYM320_DP_DPHY_SYM32_TP_CUSTOM1 0x36de
+#define regDP_DPHY_SYM320_DP_DPHY_SYM32_TP_CUSTOM1_BASE_IDX 2
+#define regDP_DPHY_SYM320_DP_DPHY_SYM32_TP_CUSTOM2 0x36df
+#define regDP_DPHY_SYM320_DP_DPHY_SYM32_TP_CUSTOM2_BASE_IDX 2
+#define regDP_DPHY_SYM320_DP_DPHY_SYM32_TP_CUSTOM3 0x36e0
+#define regDP_DPHY_SYM320_DP_DPHY_SYM32_TP_CUSTOM3_BASE_IDX 2
+#define regDP_DPHY_SYM320_DP_DPHY_SYM32_TP_CUSTOM4 0x36e1
+#define regDP_DPHY_SYM320_DP_DPHY_SYM32_TP_CUSTOM4_BASE_IDX 2
+#define regDP_DPHY_SYM320_DP_DPHY_SYM32_TP_CUSTOM5 0x36e2
+#define regDP_DPHY_SYM320_DP_DPHY_SYM32_TP_CUSTOM5_BASE_IDX 2
+#define regDP_DPHY_SYM320_DP_DPHY_SYM32_TP_CUSTOM6 0x36e3
+#define regDP_DPHY_SYM320_DP_DPHY_SYM32_TP_CUSTOM6_BASE_IDX 2
+#define regDP_DPHY_SYM320_DP_DPHY_SYM32_TP_CUSTOM7 0x36e4
+#define regDP_DPHY_SYM320_DP_DPHY_SYM32_TP_CUSTOM7_BASE_IDX 2
+#define regDP_DPHY_SYM320_DP_DPHY_SYM32_TP_CUSTOM8 0x36e5
+#define regDP_DPHY_SYM320_DP_DPHY_SYM32_TP_CUSTOM8_BASE_IDX 2
+#define regDP_DPHY_SYM320_DP_DPHY_SYM32_TP_CUSTOM9 0x36e6
+#define regDP_DPHY_SYM320_DP_DPHY_SYM32_TP_CUSTOM9_BASE_IDX 2
+#define regDP_DPHY_SYM320_DP_DPHY_SYM32_TP_CUSTOM10 0x36e7
+#define regDP_DPHY_SYM320_DP_DPHY_SYM32_TP_CUSTOM10_BASE_IDX 2
+#define regDP_DPHY_SYM320_DP_DPHY_SYM32_ERROR_STATUS 0x36e8
+#define regDP_DPHY_SYM320_DP_DPHY_SYM32_ERROR_STATUS_BASE_IDX 2
+#define regDP_DPHY_SYM320_DP_DPHY_SYM32_SYMBOL_OVERRIDE 0x36ea
+#define regDP_DPHY_SYM320_DP_DPHY_SYM32_SYMBOL_OVERRIDE_BASE_IDX 2
+#define regDP_DPHY_SYM320_DP_DPHY_SYM32_CRC_CONFIG0 0x36eb
+#define regDP_DPHY_SYM320_DP_DPHY_SYM32_CRC_CONFIG0_BASE_IDX 2
+#define regDP_DPHY_SYM320_DP_DPHY_SYM32_CRC_CONFIG1 0x36ec
+#define regDP_DPHY_SYM320_DP_DPHY_SYM32_CRC_CONFIG1_BASE_IDX 2
+#define regDP_DPHY_SYM320_DP_DPHY_SYM32_CRC_STATUS 0x36ed
+#define regDP_DPHY_SYM320_DP_DPHY_SYM32_CRC_STATUS_BASE_IDX 2
+#define regDP_DPHY_SYM320_DP_DPHY_SYM32_CRC_COUNT 0x36ee
+#define regDP_DPHY_SYM320_DP_DPHY_SYM32_CRC_COUNT_BASE_IDX 2
+
+
+// addressBlock: dce_dc_hpo_dp_link_enc1_dispdec
+// base address: 0x1b0ac
+#define regDP_LINK_ENC1_DP_LINK_ENC_CLOCK_CONTROL 0x376b
+#define regDP_LINK_ENC1_DP_LINK_ENC_CLOCK_CONTROL_BASE_IDX 2
+#define regDP_LINK_ENC1_DP_LINK_ENC_SPARE 0x376c
+#define regDP_LINK_ENC1_DP_LINK_ENC_SPARE_BASE_IDX 2
+
+
+// addressBlock: dce_dc_hpo_dp_dphy_sym321_dispdec
+// base address: 0x1b150
+#define regDP_DPHY_SYM321_DP_DPHY_SYM32_CONTROL 0x3794
+#define regDP_DPHY_SYM321_DP_DPHY_SYM32_CONTROL_BASE_IDX 2
+#define regDP_DPHY_SYM321_DP_DPHY_SYM32_STATUS 0x3795
+#define regDP_DPHY_SYM321_DP_DPHY_SYM32_STATUS_BASE_IDX 2
+#define regDP_DPHY_SYM321_DP_DPHY_SYM32_SAT_UPDATE 0x3798
+#define regDP_DPHY_SYM321_DP_DPHY_SYM32_SAT_UPDATE_BASE_IDX 2
+#define regDP_DPHY_SYM321_DP_DPHY_SYM32_VC_RATE_CNTL0 0x3799
+#define regDP_DPHY_SYM321_DP_DPHY_SYM32_VC_RATE_CNTL0_BASE_IDX 2
+#define regDP_DPHY_SYM321_DP_DPHY_SYM32_VC_RATE_CNTL1 0x379a
+#define regDP_DPHY_SYM321_DP_DPHY_SYM32_VC_RATE_CNTL1_BASE_IDX 2
+#define regDP_DPHY_SYM321_DP_DPHY_SYM32_VC_RATE_CNTL2 0x379b
+#define regDP_DPHY_SYM321_DP_DPHY_SYM32_VC_RATE_CNTL2_BASE_IDX 2
+#define regDP_DPHY_SYM321_DP_DPHY_SYM32_VC_RATE_CNTL3 0x379c
+#define regDP_DPHY_SYM321_DP_DPHY_SYM32_VC_RATE_CNTL3_BASE_IDX 2
+#define regDP_DPHY_SYM321_DP_DPHY_SYM32_SAT_VC0 0x379f
+#define regDP_DPHY_SYM321_DP_DPHY_SYM32_SAT_VC0_BASE_IDX 2
+#define regDP_DPHY_SYM321_DP_DPHY_SYM32_SAT_VC1 0x37a0
+#define regDP_DPHY_SYM321_DP_DPHY_SYM32_SAT_VC1_BASE_IDX 2
+#define regDP_DPHY_SYM321_DP_DPHY_SYM32_SAT_VC2 0x37a1
+#define regDP_DPHY_SYM321_DP_DPHY_SYM32_SAT_VC2_BASE_IDX 2
+#define regDP_DPHY_SYM321_DP_DPHY_SYM32_SAT_VC3 0x37a2
+#define regDP_DPHY_SYM321_DP_DPHY_SYM32_SAT_VC3_BASE_IDX 2
+#define regDP_DPHY_SYM321_DP_DPHY_SYM32_SAT_VC_STATUS0 0x37a5
+#define regDP_DPHY_SYM321_DP_DPHY_SYM32_SAT_VC_STATUS0_BASE_IDX 2
+#define regDP_DPHY_SYM321_DP_DPHY_SYM32_SAT_VC_STATUS1 0x37a6
+#define regDP_DPHY_SYM321_DP_DPHY_SYM32_SAT_VC_STATUS1_BASE_IDX 2
+#define regDP_DPHY_SYM321_DP_DPHY_SYM32_SAT_VC_STATUS2 0x37a7
+#define regDP_DPHY_SYM321_DP_DPHY_SYM32_SAT_VC_STATUS2_BASE_IDX 2
+#define regDP_DPHY_SYM321_DP_DPHY_SYM32_SAT_VC_STATUS3 0x37a8
+#define regDP_DPHY_SYM321_DP_DPHY_SYM32_SAT_VC_STATUS3_BASE_IDX 2
+#define regDP_DPHY_SYM321_DP_DPHY_SYM32_TP_CONFIG 0x37ab
+#define regDP_DPHY_SYM321_DP_DPHY_SYM32_TP_CONFIG_BASE_IDX 2
+#define regDP_DPHY_SYM321_DP_DPHY_SYM32_TP_PRBS_SEED0 0x37ac
+#define regDP_DPHY_SYM321_DP_DPHY_SYM32_TP_PRBS_SEED0_BASE_IDX 2
+#define regDP_DPHY_SYM321_DP_DPHY_SYM32_TP_PRBS_SEED1 0x37ad
+#define regDP_DPHY_SYM321_DP_DPHY_SYM32_TP_PRBS_SEED1_BASE_IDX 2
+#define regDP_DPHY_SYM321_DP_DPHY_SYM32_TP_PRBS_SEED2 0x37ae
+#define regDP_DPHY_SYM321_DP_DPHY_SYM32_TP_PRBS_SEED2_BASE_IDX 2
+#define regDP_DPHY_SYM321_DP_DPHY_SYM32_TP_PRBS_SEED3 0x37af
+#define regDP_DPHY_SYM321_DP_DPHY_SYM32_TP_PRBS_SEED3_BASE_IDX 2
+#define regDP_DPHY_SYM321_DP_DPHY_SYM32_TP_SQ_PULSE 0x37b0
+#define regDP_DPHY_SYM321_DP_DPHY_SYM32_TP_SQ_PULSE_BASE_IDX 2
+#define regDP_DPHY_SYM321_DP_DPHY_SYM32_TP_CUSTOM0 0x37b1
+#define regDP_DPHY_SYM321_DP_DPHY_SYM32_TP_CUSTOM0_BASE_IDX 2
+#define regDP_DPHY_SYM321_DP_DPHY_SYM32_TP_CUSTOM1 0x37b2
+#define regDP_DPHY_SYM321_DP_DPHY_SYM32_TP_CUSTOM1_BASE_IDX 2
+#define regDP_DPHY_SYM321_DP_DPHY_SYM32_TP_CUSTOM2 0x37b3
+#define regDP_DPHY_SYM321_DP_DPHY_SYM32_TP_CUSTOM2_BASE_IDX 2
+#define regDP_DPHY_SYM321_DP_DPHY_SYM32_TP_CUSTOM3 0x37b4
+#define regDP_DPHY_SYM321_DP_DPHY_SYM32_TP_CUSTOM3_BASE_IDX 2
+#define regDP_DPHY_SYM321_DP_DPHY_SYM32_TP_CUSTOM4 0x37b5
+#define regDP_DPHY_SYM321_DP_DPHY_SYM32_TP_CUSTOM4_BASE_IDX 2
+#define regDP_DPHY_SYM321_DP_DPHY_SYM32_TP_CUSTOM5 0x37b6
+#define regDP_DPHY_SYM321_DP_DPHY_SYM32_TP_CUSTOM5_BASE_IDX 2
+#define regDP_DPHY_SYM321_DP_DPHY_SYM32_TP_CUSTOM6 0x37b7
+#define regDP_DPHY_SYM321_DP_DPHY_SYM32_TP_CUSTOM6_BASE_IDX 2
+#define regDP_DPHY_SYM321_DP_DPHY_SYM32_TP_CUSTOM7 0x37b8
+#define regDP_DPHY_SYM321_DP_DPHY_SYM32_TP_CUSTOM7_BASE_IDX 2
+#define regDP_DPHY_SYM321_DP_DPHY_SYM32_TP_CUSTOM8 0x37b9
+#define regDP_DPHY_SYM321_DP_DPHY_SYM32_TP_CUSTOM8_BASE_IDX 2
+#define regDP_DPHY_SYM321_DP_DPHY_SYM32_TP_CUSTOM9 0x37ba
+#define regDP_DPHY_SYM321_DP_DPHY_SYM32_TP_CUSTOM9_BASE_IDX 2
+#define regDP_DPHY_SYM321_DP_DPHY_SYM32_TP_CUSTOM10 0x37bb
+#define regDP_DPHY_SYM321_DP_DPHY_SYM32_TP_CUSTOM10_BASE_IDX 2
+#define regDP_DPHY_SYM321_DP_DPHY_SYM32_ERROR_STATUS 0x37bc
+#define regDP_DPHY_SYM321_DP_DPHY_SYM32_ERROR_STATUS_BASE_IDX 2
+#define regDP_DPHY_SYM321_DP_DPHY_SYM32_SYMBOL_OVERRIDE 0x37be
+#define regDP_DPHY_SYM321_DP_DPHY_SYM32_SYMBOL_OVERRIDE_BASE_IDX 2
+#define regDP_DPHY_SYM321_DP_DPHY_SYM32_CRC_CONFIG0 0x37bf
+#define regDP_DPHY_SYM321_DP_DPHY_SYM32_CRC_CONFIG0_BASE_IDX 2
+#define regDP_DPHY_SYM321_DP_DPHY_SYM32_CRC_CONFIG1 0x37c0
+#define regDP_DPHY_SYM321_DP_DPHY_SYM32_CRC_CONFIG1_BASE_IDX 2
+#define regDP_DPHY_SYM321_DP_DPHY_SYM32_CRC_STATUS 0x37c1
+#define regDP_DPHY_SYM321_DP_DPHY_SYM32_CRC_STATUS_BASE_IDX 2
+#define regDP_DPHY_SYM321_DP_DPHY_SYM32_CRC_COUNT 0x37c2
+#define regDP_DPHY_SYM321_DP_DPHY_SYM32_CRC_COUNT_BASE_IDX 2
+
+
+// addressBlock: dce_dc_dchvm_hvm_dispdec
+// base address: 0x0
+#define regDCHVM_CTRL0 0x3603
+#define regDCHVM_CTRL0_BASE_IDX 2
+#define regDCHVM_CTRL1 0x3604
+#define regDCHVM_CTRL1_BASE_IDX 2
+#define regDCHVM_CLK_CTRL 0x3605
+#define regDCHVM_CLK_CTRL_BASE_IDX 2
+#define regDCHVM_MEM_CTRL 0x3606
+#define regDCHVM_MEM_CTRL_BASE_IDX 2
+#define regDCHVM_RIOMMU_CTRL0 0x3607
+#define regDCHVM_RIOMMU_CTRL0_BASE_IDX 2
+#define regDCHVM_RIOMMU_STAT0 0x3608
+#define regDCHVM_RIOMMU_STAT0_BASE_IDX 2
+
+
+// addressBlock: dce_dc_hda_azcontroller_azdec
+// base address: 0x1300000
+#define regCORB_WRITE_POINTER 0x4b7012
+#define regCORB_WRITE_POINTER_BASE_IDX 3
+#define regCORB_READ_POINTER 0x4b7012
+#define regCORB_READ_POINTER_BASE_IDX 3
+#define regCORB_CONTROL 0x4b7013
+#define regCORB_CONTROL_BASE_IDX 3
+#define regCORB_STATUS 0x4b7013
+#define regCORB_STATUS_BASE_IDX 3
+#define regCORB_SIZE 0x4b7013
+#define regCORB_SIZE_BASE_IDX 3
+#define regRIRB_LOWER_BASE_ADDRESS 0x4b7014
+#define regRIRB_LOWER_BASE_ADDRESS_BASE_IDX 3
+#define regRIRB_UPPER_BASE_ADDRESS 0x4b7015
+#define regRIRB_UPPER_BASE_ADDRESS_BASE_IDX 3
+#define regRIRB_WRITE_POINTER 0x4b7016
+#define regRIRB_WRITE_POINTER_BASE_IDX 3
+#define regRESPONSE_INTERRUPT_COUNT 0x4b7016
+#define regRESPONSE_INTERRUPT_COUNT_BASE_IDX 3
+#define regRIRB_CONTROL 0x4b7017
+#define regRIRB_CONTROL_BASE_IDX 3
+#define regRIRB_STATUS 0x4b7017
+#define regRIRB_STATUS_BASE_IDX 3
+#define regRIRB_SIZE 0x4b7017
+#define regRIRB_SIZE_BASE_IDX 3
+#define regIMMEDIATE_COMMAND_OUTPUT_INTERFACE 0x4b7018
+#define regIMMEDIATE_COMMAND_OUTPUT_INTERFACE_BASE_IDX 3
+#define regIMMEDIATE_COMMAND_OUTPUT_INTERFACE_DATA 0x4b7018
+#define regIMMEDIATE_COMMAND_OUTPUT_INTERFACE_DATA_BASE_IDX 3
+#define regIMMEDIATE_COMMAND_OUTPUT_INTERFACE_INDEX 0x4b7018
+#define regIMMEDIATE_COMMAND_OUTPUT_INTERFACE_INDEX_BASE_IDX 3
+#define regIMMEDIATE_RESPONSE_INPUT_INTERFACE 0x4b7019
+#define regIMMEDIATE_RESPONSE_INPUT_INTERFACE_BASE_IDX 3
+#define regIMMEDIATE_COMMAND_STATUS 0x4b701a
+#define regIMMEDIATE_COMMAND_STATUS_BASE_IDX 3
+#define regDMA_POSITION_LOWER_BASE_ADDRESS 0x4b701c
+#define regDMA_POSITION_LOWER_BASE_ADDRESS_BASE_IDX 3
+#define regDMA_POSITION_UPPER_BASE_ADDRESS 0x4b701d
+#define regDMA_POSITION_UPPER_BASE_ADDRESS_BASE_IDX 3
+
+
+// addressBlock: dce_dc_hda_azendpoint_azdec
+// base address: 0x1300000
+#define regAZENDPOINT_IMMEDIATE_COMMAND_OUTPUT_INTERFACE_DATA 0x4b7018
+#define regAZENDPOINT_IMMEDIATE_COMMAND_OUTPUT_INTERFACE_DATA_BASE_IDX 3
+#define regAZENDPOINT_IMMEDIATE_COMMAND_OUTPUT_INTERFACE_INDEX 0x4b7018
+#define regAZENDPOINT_IMMEDIATE_COMMAND_OUTPUT_INTERFACE_INDEX_BASE_IDX 3
+
+
+// addressBlock: dce_dc_hda_azinputendpoint_azdec
+// base address: 0x1300000
+#define regAZENDPOINT_IMMEDIATE_COMMAND_INPUT_INTERFACE_DATA 0x4b7018
+#define regAZENDPOINT_IMMEDIATE_COMMAND_INPUT_INTERFACE_DATA_BASE_IDX 3
+#define regAZENDPOINT_IMMEDIATE_COMMAND_INPUT_INTERFACE_INDEX 0x4b7018
+#define regAZENDPOINT_IMMEDIATE_COMMAND_INPUT_INTERFACE_INDEX_BASE_IDX 3
+
+
+// addressBlock: dce_dc_hda_azroot_azdec
+// base address: 0x1300000
+#define regAZROOT_IMMEDIATE_COMMAND_OUTPUT_INTERFACE_DATA 0x4b7018
+#define regAZROOT_IMMEDIATE_COMMAND_OUTPUT_INTERFACE_DATA_BASE_IDX 3
+#define regAZROOT_IMMEDIATE_COMMAND_OUTPUT_INTERFACE_INDEX 0x4b7018
+#define regAZROOT_IMMEDIATE_COMMAND_OUTPUT_INTERFACE_INDEX_BASE_IDX 3
+
+
+// addressBlock: dce_dc_hda_azstream0_azdec
+// base address: 0x1300000
+#define regAZSTREAM0_OUTPUT_STREAM_DESCRIPTOR_CONTROL_AND_STATUS 0x4b7020
+#define regAZSTREAM0_OUTPUT_STREAM_DESCRIPTOR_CONTROL_AND_STATUS_BASE_IDX 3
+#define regAZSTREAM0_OUTPUT_STREAM_DESCRIPTOR_LINK_POSITION_IN_CURRENT_BUFFER 0x4b7021
+#define regAZSTREAM0_OUTPUT_STREAM_DESCRIPTOR_LINK_POSITION_IN_CURRENT_BUFFER_BASE_IDX 3
+#define regAZSTREAM0_OUTPUT_STREAM_DESCRIPTOR_CYCLIC_BUFFER_LENGTH 0x4b7022
+#define regAZSTREAM0_OUTPUT_STREAM_DESCRIPTOR_CYCLIC_BUFFER_LENGTH_BASE_IDX 3
+#define regAZSTREAM0_OUTPUT_STREAM_DESCRIPTOR_LAST_VALID_INDEX 0x4b7023
+#define regAZSTREAM0_OUTPUT_STREAM_DESCRIPTOR_LAST_VALID_INDEX_BASE_IDX 3
+#define regAZSTREAM0_OUTPUT_STREAM_DESCRIPTOR_FIFO_SIZE 0x4b7024
+#define regAZSTREAM0_OUTPUT_STREAM_DESCRIPTOR_FIFO_SIZE_BASE_IDX 3
+#define regAZSTREAM0_OUTPUT_STREAM_DESCRIPTOR_FORMAT 0x4b7024
+#define regAZSTREAM0_OUTPUT_STREAM_DESCRIPTOR_FORMAT_BASE_IDX 3
+#define regAZSTREAM0_OUTPUT_STREAM_DESCRIPTOR_BDL_POINTER_LOWER_BASE_ADDRESS 0x4b7026
+#define regAZSTREAM0_OUTPUT_STREAM_DESCRIPTOR_BDL_POINTER_LOWER_BASE_ADDRESS_BASE_IDX 3
+#define regAZSTREAM0_OUTPUT_STREAM_DESCRIPTOR_BDL_POINTER_UPPER_BASE_ADDRESS 0x4b7027
+#define regAZSTREAM0_OUTPUT_STREAM_DESCRIPTOR_BDL_POINTER_UPPER_BASE_ADDRESS_BASE_IDX 3
+#define regAZSTREAM0_OUTPUT_STREAM_DESCRIPTOR_LINK_POSITION_IN_CURRENT_BUFFER_ALIAS 0x4b7821
+#define regAZSTREAM0_OUTPUT_STREAM_DESCRIPTOR_LINK_POSITION_IN_CURRENT_BUFFER_ALIAS_BASE_IDX 3
+
+
+// addressBlock: dce_dc_hda_azstream1_azdec
+// base address: 0x1300020
+#define regAZSTREAM1_OUTPUT_STREAM_DESCRIPTOR_CONTROL_AND_STATUS 0x4b7028
+#define regAZSTREAM1_OUTPUT_STREAM_DESCRIPTOR_CONTROL_AND_STATUS_BASE_IDX 3
+#define regAZSTREAM1_OUTPUT_STREAM_DESCRIPTOR_LINK_POSITION_IN_CURRENT_BUFFER 0x4b7029
+#define regAZSTREAM1_OUTPUT_STREAM_DESCRIPTOR_LINK_POSITION_IN_CURRENT_BUFFER_BASE_IDX 3
+#define regAZSTREAM1_OUTPUT_STREAM_DESCRIPTOR_CYCLIC_BUFFER_LENGTH 0x4b702a
+#define regAZSTREAM1_OUTPUT_STREAM_DESCRIPTOR_CYCLIC_BUFFER_LENGTH_BASE_IDX 3
+#define regAZSTREAM1_OUTPUT_STREAM_DESCRIPTOR_LAST_VALID_INDEX 0x4b702b
+#define regAZSTREAM1_OUTPUT_STREAM_DESCRIPTOR_LAST_VALID_INDEX_BASE_IDX 3
+#define regAZSTREAM1_OUTPUT_STREAM_DESCRIPTOR_FIFO_SIZE 0x4b702c
+#define regAZSTREAM1_OUTPUT_STREAM_DESCRIPTOR_FIFO_SIZE_BASE_IDX 3
+#define regAZSTREAM1_OUTPUT_STREAM_DESCRIPTOR_FORMAT 0x4b702c
+#define regAZSTREAM1_OUTPUT_STREAM_DESCRIPTOR_FORMAT_BASE_IDX 3
+#define regAZSTREAM1_OUTPUT_STREAM_DESCRIPTOR_BDL_POINTER_LOWER_BASE_ADDRESS 0x4b702e
+#define regAZSTREAM1_OUTPUT_STREAM_DESCRIPTOR_BDL_POINTER_LOWER_BASE_ADDRESS_BASE_IDX 3
+#define regAZSTREAM1_OUTPUT_STREAM_DESCRIPTOR_BDL_POINTER_UPPER_BASE_ADDRESS 0x4b702f
+#define regAZSTREAM1_OUTPUT_STREAM_DESCRIPTOR_BDL_POINTER_UPPER_BASE_ADDRESS_BASE_IDX 3
+#define regAZSTREAM1_OUTPUT_STREAM_DESCRIPTOR_LINK_POSITION_IN_CURRENT_BUFFER_ALIAS 0x4b7829
+#define regAZSTREAM1_OUTPUT_STREAM_DESCRIPTOR_LINK_POSITION_IN_CURRENT_BUFFER_ALIAS_BASE_IDX 3
+
+
+// addressBlock: dce_dc_hda_azstream2_azdec
+// base address: 0x1300040
+#define regAZSTREAM2_OUTPUT_STREAM_DESCRIPTOR_CONTROL_AND_STATUS 0x4b7030
+#define regAZSTREAM2_OUTPUT_STREAM_DESCRIPTOR_CONTROL_AND_STATUS_BASE_IDX 3
+#define regAZSTREAM2_OUTPUT_STREAM_DESCRIPTOR_LINK_POSITION_IN_CURRENT_BUFFER 0x4b7031
+#define regAZSTREAM2_OUTPUT_STREAM_DESCRIPTOR_LINK_POSITION_IN_CURRENT_BUFFER_BASE_IDX 3
+#define regAZSTREAM2_OUTPUT_STREAM_DESCRIPTOR_CYCLIC_BUFFER_LENGTH 0x4b7032
+#define regAZSTREAM2_OUTPUT_STREAM_DESCRIPTOR_CYCLIC_BUFFER_LENGTH_BASE_IDX 3
+#define regAZSTREAM2_OUTPUT_STREAM_DESCRIPTOR_LAST_VALID_INDEX 0x4b7033
+#define regAZSTREAM2_OUTPUT_STREAM_DESCRIPTOR_LAST_VALID_INDEX_BASE_IDX 3
+#define regAZSTREAM2_OUTPUT_STREAM_DESCRIPTOR_FIFO_SIZE 0x4b7034
+#define regAZSTREAM2_OUTPUT_STREAM_DESCRIPTOR_FIFO_SIZE_BASE_IDX 3
+#define regAZSTREAM2_OUTPUT_STREAM_DESCRIPTOR_FORMAT 0x4b7034
+#define regAZSTREAM2_OUTPUT_STREAM_DESCRIPTOR_FORMAT_BASE_IDX 3
+#define regAZSTREAM2_OUTPUT_STREAM_DESCRIPTOR_BDL_POINTER_LOWER_BASE_ADDRESS 0x4b7036
+#define regAZSTREAM2_OUTPUT_STREAM_DESCRIPTOR_BDL_POINTER_LOWER_BASE_ADDRESS_BASE_IDX 3
+#define regAZSTREAM2_OUTPUT_STREAM_DESCRIPTOR_BDL_POINTER_UPPER_BASE_ADDRESS 0x4b7037
+#define regAZSTREAM2_OUTPUT_STREAM_DESCRIPTOR_BDL_POINTER_UPPER_BASE_ADDRESS_BASE_IDX 3
+#define regAZSTREAM2_OUTPUT_STREAM_DESCRIPTOR_LINK_POSITION_IN_CURRENT_BUFFER_ALIAS 0x4b7831
+#define regAZSTREAM2_OUTPUT_STREAM_DESCRIPTOR_LINK_POSITION_IN_CURRENT_BUFFER_ALIAS_BASE_IDX 3
+
+
+// addressBlock: dce_dc_hda_azstream3_azdec
+// base address: 0x1300060
+#define regAZSTREAM3_OUTPUT_STREAM_DESCRIPTOR_CONTROL_AND_STATUS 0x4b7038
+#define regAZSTREAM3_OUTPUT_STREAM_DESCRIPTOR_CONTROL_AND_STATUS_BASE_IDX 3
+#define regAZSTREAM3_OUTPUT_STREAM_DESCRIPTOR_LINK_POSITION_IN_CURRENT_BUFFER 0x4b7039
+#define regAZSTREAM3_OUTPUT_STREAM_DESCRIPTOR_LINK_POSITION_IN_CURRENT_BUFFER_BASE_IDX 3
+#define regAZSTREAM3_OUTPUT_STREAM_DESCRIPTOR_CYCLIC_BUFFER_LENGTH 0x4b703a
+#define regAZSTREAM3_OUTPUT_STREAM_DESCRIPTOR_CYCLIC_BUFFER_LENGTH_BASE_IDX 3
+#define regAZSTREAM3_OUTPUT_STREAM_DESCRIPTOR_LAST_VALID_INDEX 0x4b703b
+#define regAZSTREAM3_OUTPUT_STREAM_DESCRIPTOR_LAST_VALID_INDEX_BASE_IDX 3
+#define regAZSTREAM3_OUTPUT_STREAM_DESCRIPTOR_FIFO_SIZE 0x4b703c
+#define regAZSTREAM3_OUTPUT_STREAM_DESCRIPTOR_FIFO_SIZE_BASE_IDX 3
+#define regAZSTREAM3_OUTPUT_STREAM_DESCRIPTOR_FORMAT 0x4b703c
+#define regAZSTREAM3_OUTPUT_STREAM_DESCRIPTOR_FORMAT_BASE_IDX 3
+#define regAZSTREAM3_OUTPUT_STREAM_DESCRIPTOR_BDL_POINTER_LOWER_BASE_ADDRESS 0x4b703e
+#define regAZSTREAM3_OUTPUT_STREAM_DESCRIPTOR_BDL_POINTER_LOWER_BASE_ADDRESS_BASE_IDX 3
+#define regAZSTREAM3_OUTPUT_STREAM_DESCRIPTOR_BDL_POINTER_UPPER_BASE_ADDRESS 0x4b703f
+#define regAZSTREAM3_OUTPUT_STREAM_DESCRIPTOR_BDL_POINTER_UPPER_BASE_ADDRESS_BASE_IDX 3
+#define regAZSTREAM3_OUTPUT_STREAM_DESCRIPTOR_LINK_POSITION_IN_CURRENT_BUFFER_ALIAS 0x4b7839
+#define regAZSTREAM3_OUTPUT_STREAM_DESCRIPTOR_LINK_POSITION_IN_CURRENT_BUFFER_ALIAS_BASE_IDX 3
+
+
+// addressBlock: dce_dc_hda_azstream4_azdec
+// base address: 0x1300080
+#define regAZSTREAM4_OUTPUT_STREAM_DESCRIPTOR_CONTROL_AND_STATUS 0x4b7040
+#define regAZSTREAM4_OUTPUT_STREAM_DESCRIPTOR_CONTROL_AND_STATUS_BASE_IDX 3
+#define regAZSTREAM4_OUTPUT_STREAM_DESCRIPTOR_LINK_POSITION_IN_CURRENT_BUFFER 0x4b7041
+#define regAZSTREAM4_OUTPUT_STREAM_DESCRIPTOR_LINK_POSITION_IN_CURRENT_BUFFER_BASE_IDX 3
+#define regAZSTREAM4_OUTPUT_STREAM_DESCRIPTOR_CYCLIC_BUFFER_LENGTH 0x4b7042
+#define regAZSTREAM4_OUTPUT_STREAM_DESCRIPTOR_CYCLIC_BUFFER_LENGTH_BASE_IDX 3
+#define regAZSTREAM4_OUTPUT_STREAM_DESCRIPTOR_LAST_VALID_INDEX 0x4b7043
+#define regAZSTREAM4_OUTPUT_STREAM_DESCRIPTOR_LAST_VALID_INDEX_BASE_IDX 3
+#define regAZSTREAM4_OUTPUT_STREAM_DESCRIPTOR_FIFO_SIZE 0x4b7044
+#define regAZSTREAM4_OUTPUT_STREAM_DESCRIPTOR_FIFO_SIZE_BASE_IDX 3
+#define regAZSTREAM4_OUTPUT_STREAM_DESCRIPTOR_FORMAT 0x4b7044
+#define regAZSTREAM4_OUTPUT_STREAM_DESCRIPTOR_FORMAT_BASE_IDX 3
+#define regAZSTREAM4_OUTPUT_STREAM_DESCRIPTOR_BDL_POINTER_LOWER_BASE_ADDRESS 0x4b7046
+#define regAZSTREAM4_OUTPUT_STREAM_DESCRIPTOR_BDL_POINTER_LOWER_BASE_ADDRESS_BASE_IDX 3
+#define regAZSTREAM4_OUTPUT_STREAM_DESCRIPTOR_BDL_POINTER_UPPER_BASE_ADDRESS 0x4b7047
+#define regAZSTREAM4_OUTPUT_STREAM_DESCRIPTOR_BDL_POINTER_UPPER_BASE_ADDRESS_BASE_IDX 3
+#define regAZSTREAM4_OUTPUT_STREAM_DESCRIPTOR_LINK_POSITION_IN_CURRENT_BUFFER_ALIAS 0x4b7841
+#define regAZSTREAM4_OUTPUT_STREAM_DESCRIPTOR_LINK_POSITION_IN_CURRENT_BUFFER_ALIAS_BASE_IDX 3
+
+
+// addressBlock: dce_dc_hda_azstream5_azdec
+// base address: 0x13000a0
+#define regAZSTREAM5_OUTPUT_STREAM_DESCRIPTOR_CONTROL_AND_STATUS 0x4b7048
+#define regAZSTREAM5_OUTPUT_STREAM_DESCRIPTOR_CONTROL_AND_STATUS_BASE_IDX 3
+#define regAZSTREAM5_OUTPUT_STREAM_DESCRIPTOR_LINK_POSITION_IN_CURRENT_BUFFER 0x4b7049
+#define regAZSTREAM5_OUTPUT_STREAM_DESCRIPTOR_LINK_POSITION_IN_CURRENT_BUFFER_BASE_IDX 3
+#define regAZSTREAM5_OUTPUT_STREAM_DESCRIPTOR_CYCLIC_BUFFER_LENGTH 0x4b704a
+#define regAZSTREAM5_OUTPUT_STREAM_DESCRIPTOR_CYCLIC_BUFFER_LENGTH_BASE_IDX 3
+#define regAZSTREAM5_OUTPUT_STREAM_DESCRIPTOR_LAST_VALID_INDEX 0x4b704b
+#define regAZSTREAM5_OUTPUT_STREAM_DESCRIPTOR_LAST_VALID_INDEX_BASE_IDX 3
+#define regAZSTREAM5_OUTPUT_STREAM_DESCRIPTOR_FIFO_SIZE 0x4b704c
+#define regAZSTREAM5_OUTPUT_STREAM_DESCRIPTOR_FIFO_SIZE_BASE_IDX 3
+#define regAZSTREAM5_OUTPUT_STREAM_DESCRIPTOR_FORMAT 0x4b704c
+#define regAZSTREAM5_OUTPUT_STREAM_DESCRIPTOR_FORMAT_BASE_IDX 3
+#define regAZSTREAM5_OUTPUT_STREAM_DESCRIPTOR_BDL_POINTER_LOWER_BASE_ADDRESS 0x4b704e
+#define regAZSTREAM5_OUTPUT_STREAM_DESCRIPTOR_BDL_POINTER_LOWER_BASE_ADDRESS_BASE_IDX 3
+#define regAZSTREAM5_OUTPUT_STREAM_DESCRIPTOR_BDL_POINTER_UPPER_BASE_ADDRESS 0x4b704f
+#define regAZSTREAM5_OUTPUT_STREAM_DESCRIPTOR_BDL_POINTER_UPPER_BASE_ADDRESS_BASE_IDX 3
+#define regAZSTREAM5_OUTPUT_STREAM_DESCRIPTOR_LINK_POSITION_IN_CURRENT_BUFFER_ALIAS 0x4b7849
+#define regAZSTREAM5_OUTPUT_STREAM_DESCRIPTOR_LINK_POSITION_IN_CURRENT_BUFFER_ALIAS_BASE_IDX 3
+
+
+// addressBlock: dce_dc_hda_azstream6_azdec
+// base address: 0x13000c0
+#define regAZSTREAM6_OUTPUT_STREAM_DESCRIPTOR_CONTROL_AND_STATUS 0x4b7050
+#define regAZSTREAM6_OUTPUT_STREAM_DESCRIPTOR_CONTROL_AND_STATUS_BASE_IDX 3
+#define regAZSTREAM6_OUTPUT_STREAM_DESCRIPTOR_LINK_POSITION_IN_CURRENT_BUFFER 0x4b7051
+#define regAZSTREAM6_OUTPUT_STREAM_DESCRIPTOR_LINK_POSITION_IN_CURRENT_BUFFER_BASE_IDX 3
+#define regAZSTREAM6_OUTPUT_STREAM_DESCRIPTOR_CYCLIC_BUFFER_LENGTH 0x4b7052
+#define regAZSTREAM6_OUTPUT_STREAM_DESCRIPTOR_CYCLIC_BUFFER_LENGTH_BASE_IDX 3
+#define regAZSTREAM6_OUTPUT_STREAM_DESCRIPTOR_LAST_VALID_INDEX 0x4b7053
+#define regAZSTREAM6_OUTPUT_STREAM_DESCRIPTOR_LAST_VALID_INDEX_BASE_IDX 3
+#define regAZSTREAM6_OUTPUT_STREAM_DESCRIPTOR_FIFO_SIZE 0x4b7054
+#define regAZSTREAM6_OUTPUT_STREAM_DESCRIPTOR_FIFO_SIZE_BASE_IDX 3
+#define regAZSTREAM6_OUTPUT_STREAM_DESCRIPTOR_FORMAT 0x4b7054
+#define regAZSTREAM6_OUTPUT_STREAM_DESCRIPTOR_FORMAT_BASE_IDX 3
+#define regAZSTREAM6_OUTPUT_STREAM_DESCRIPTOR_BDL_POINTER_LOWER_BASE_ADDRESS 0x4b7056
+#define regAZSTREAM6_OUTPUT_STREAM_DESCRIPTOR_BDL_POINTER_LOWER_BASE_ADDRESS_BASE_IDX 3
+#define regAZSTREAM6_OUTPUT_STREAM_DESCRIPTOR_BDL_POINTER_UPPER_BASE_ADDRESS 0x4b7057
+#define regAZSTREAM6_OUTPUT_STREAM_DESCRIPTOR_BDL_POINTER_UPPER_BASE_ADDRESS_BASE_IDX 3
+#define regAZSTREAM6_OUTPUT_STREAM_DESCRIPTOR_LINK_POSITION_IN_CURRENT_BUFFER_ALIAS 0x4b7851
+#define regAZSTREAM6_OUTPUT_STREAM_DESCRIPTOR_LINK_POSITION_IN_CURRENT_BUFFER_ALIAS_BASE_IDX 3
+
+
+// addressBlock: dce_dc_hda_azstream7_azdec
+// base address: 0x13000e0
+#define regAZSTREAM7_OUTPUT_STREAM_DESCRIPTOR_CONTROL_AND_STATUS 0x4b7058
+#define regAZSTREAM7_OUTPUT_STREAM_DESCRIPTOR_CONTROL_AND_STATUS_BASE_IDX 3
+#define regAZSTREAM7_OUTPUT_STREAM_DESCRIPTOR_LINK_POSITION_IN_CURRENT_BUFFER 0x4b7059
+#define regAZSTREAM7_OUTPUT_STREAM_DESCRIPTOR_LINK_POSITION_IN_CURRENT_BUFFER_BASE_IDX 3
+#define regAZSTREAM7_OUTPUT_STREAM_DESCRIPTOR_CYCLIC_BUFFER_LENGTH 0x4b705a
+#define regAZSTREAM7_OUTPUT_STREAM_DESCRIPTOR_CYCLIC_BUFFER_LENGTH_BASE_IDX 3
+#define regAZSTREAM7_OUTPUT_STREAM_DESCRIPTOR_LAST_VALID_INDEX 0x4b705b
+#define regAZSTREAM7_OUTPUT_STREAM_DESCRIPTOR_LAST_VALID_INDEX_BASE_IDX 3
+#define regAZSTREAM7_OUTPUT_STREAM_DESCRIPTOR_FIFO_SIZE 0x4b705c
+#define regAZSTREAM7_OUTPUT_STREAM_DESCRIPTOR_FIFO_SIZE_BASE_IDX 3
+#define regAZSTREAM7_OUTPUT_STREAM_DESCRIPTOR_FORMAT 0x4b705c
+#define regAZSTREAM7_OUTPUT_STREAM_DESCRIPTOR_FORMAT_BASE_IDX 3
+#define regAZSTREAM7_OUTPUT_STREAM_DESCRIPTOR_BDL_POINTER_LOWER_BASE_ADDRESS 0x4b705e
+#define regAZSTREAM7_OUTPUT_STREAM_DESCRIPTOR_BDL_POINTER_LOWER_BASE_ADDRESS_BASE_IDX 3
+#define regAZSTREAM7_OUTPUT_STREAM_DESCRIPTOR_BDL_POINTER_UPPER_BASE_ADDRESS 0x4b705f
+#define regAZSTREAM7_OUTPUT_STREAM_DESCRIPTOR_BDL_POINTER_UPPER_BASE_ADDRESS_BASE_IDX 3
+#define regAZSTREAM7_OUTPUT_STREAM_DESCRIPTOR_LINK_POSITION_IN_CURRENT_BUFFER_ALIAS 0x4b7859
+#define regAZSTREAM7_OUTPUT_STREAM_DESCRIPTOR_LINK_POSITION_IN_CURRENT_BUFFER_ALIAS_BASE_IDX 3
+
+
+// addressBlock: vga_vgaseqind
+// base address: 0x0
+#define ixSEQ00 0x0000
+#define ixSEQ01 0x0001
+#define ixSEQ02 0x0002
+#define ixSEQ03 0x0003
+#define ixSEQ04 0x0004
+
+
+// addressBlock: vga_vgacrtind
+// base address: 0x0
+#define ixCRT00 0x0000
+#define ixCRT01 0x0001
+#define ixCRT02 0x0002
+#define ixCRT03 0x0003
+#define ixCRT04 0x0004
+#define ixCRT05 0x0005
+#define ixCRT06 0x0006
+#define ixCRT07 0x0007
+#define ixCRT08 0x0008
+#define ixCRT09 0x0009
+#define ixCRT0A 0x000a
+#define ixCRT0B 0x000b
+#define ixCRT0C 0x000c
+#define ixCRT0D 0x000d
+#define ixCRT0E 0x000e
+#define ixCRT0F 0x000f
+#define ixCRT10 0x0010
+#define ixCRT11 0x0011
+#define ixCRT12 0x0012
+#define ixCRT13 0x0013
+#define ixCRT14 0x0014
+#define ixCRT15 0x0015
+#define ixCRT16 0x0016
+#define ixCRT17 0x0017
+#define ixCRT18 0x0018
+#define ixCRT1E 0x001e
+#define ixCRT1F 0x001f
+#define ixCRT22 0x0022
+
+
+// addressBlock: vga_vgagrphind
+// base address: 0x0
+#define ixGRA00 0x0000
+#define ixGRA01 0x0001
+#define ixGRA02 0x0002
+#define ixGRA03 0x0003
+#define ixGRA04 0x0004
+#define ixGRA05 0x0005
+#define ixGRA06 0x0006
+#define ixGRA07 0x0007
+#define ixGRA08 0x0008
+
+
+// addressBlock: vga_vgaattrind
+// base address: 0x0
+#define ixATTR00 0x0000
+#define ixATTR01 0x0001
+#define ixATTR02 0x0002
+#define ixATTR03 0x0003
+#define ixATTR04 0x0004
+#define ixATTR05 0x0005
+#define ixATTR06 0x0006
+#define ixATTR07 0x0007
+#define ixATTR08 0x0008
+#define ixATTR09 0x0009
+#define ixATTR0A 0x000a
+#define ixATTR0B 0x000b
+#define ixATTR0C 0x000c
+#define ixATTR0D 0x000d
+#define ixATTR0E 0x000e
+#define ixATTR0F 0x000f
+#define ixATTR10 0x0010
+#define ixATTR11 0x0011
+#define ixATTR12 0x0012
+#define ixATTR13 0x0013
+#define ixATTR14 0x0014
+
+
+// addressBlock: azendpoint_f2codecind
+// base address: 0x0
+#define ixAZALIA_F2_CODEC_CONVERTER_CONTROL_CONVERTER_FORMAT 0x2200
+#define ixAZALIA_F2_CODEC_CONVERTER_CONTROL_CHANNEL_STREAM_ID 0x2706
+#define ixAZALIA_F2_CODEC_CONVERTER_CONTROL_DIGITAL_CONVERTER 0x270d
+#define ixAZALIA_F2_CODEC_CONVERTER_CONTROL_DIGITAL_CONVERTER_2 0x270e
+#define ixAZALIA_F2_CODEC_CONVERTER_STRIPE_CONTROL 0x2724
+#define ixAZALIA_F2_CODEC_CONVERTER_CONTROL_DIGITAL_CONVERTER_3 0x273e
+#define ixAZALIA_F2_CODEC_CONVERTER_CONTROL_RAMP_RATE 0x2770
+#define ixAZALIA_F2_CODEC_CONVERTER_CONTROL_GTC_EMBEDDING 0x2771
+#define ixAZALIA_F2_CODEC_CONVERTER_PARAMETER_AUDIO_WIDGET_CAPABILITIES 0x2f09
+#define ixAZALIA_F2_CODEC_CONVERTER_PARAMETER_SUPPORTED_SIZE_RATES 0x2f0a
+#define ixAZALIA_F2_CODEC_CONVERTER_PARAMETER_STREAM_FORMATS 0x2f0b
+#define ixAZALIA_F2_CODEC_PIN_CONTROL_RESPONSE_CONNECTION_LIST_ENTRY 0x3702
+#define ixAZALIA_F2_CODEC_PIN_CONTROL_WIDGET_CONTROL 0x3707
+#define ixAZALIA_F2_CODEC_PIN_CONTROL_UNSOLICITED_RESPONSE 0x3708
+#define ixAZALIA_F2_CODEC_PIN_CONTROL_RESPONSE_PIN_SENSE 0x3709
+#define ixAZALIA_F2_CODEC_PIN_CONTROL_RESPONSE_CONFIGURATION_DEFAULT 0x371c
+#define ixAZALIA_F2_CODEC_PIN_CONTROL_RESPONSE_CONFIGURATION_DEFAULT_2 0x371d
+#define ixAZALIA_F2_CODEC_PIN_CONTROL_RESPONSE_CONFIGURATION_DEFAULT_3 0x371e
+#define ixAZALIA_F2_CODEC_PIN_CONTROL_RESPONSE_CONFIGURATION_DEFAULT_4 0x371f
+#define ixAZALIA_F2_CODEC_PIN_CONTROL_RESPONSE_SPEAKER_ALLOCATION 0x3770
+#define ixAZALIA_F2_CODEC_PIN_CONTROL_CHANNEL_ALLOCATION 0x3771
+#define ixAZALIA_F2_CODEC_PIN_CONTROL_DOWN_MIX_INFO 0x3772
+#define ixAZALIA_F2_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR 0x3776
+#define ixAZALIA_F2_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR_DATA 0x3776
+#define ixAZALIA_F2_CODEC_PIN_CONTROL_MULTICHANNEL01_ENABLE 0x3777
+#define ixAZALIA_F2_CODEC_PIN_CONTROL_MULTICHANNEL23_ENABLE 0x3778
+#define ixAZALIA_F2_CODEC_PIN_CONTROL_MULTICHANNEL45_ENABLE 0x3779
+#define ixAZALIA_F2_CODEC_PIN_CONTROL_MULTICHANNEL67_ENABLE 0x377a
+#define ixAZALIA_F2_CODEC_PIN_CONTROL_LIPSYNC 0x377b
+#define ixAZALIA_F2_CODEC_PIN_CONTROL_HBR 0x377c
+#define ixAZALIA_F2_CODEC_PIN_CONTROL_AUDIO_SINK_INFO_INDEX 0x3780
+#define ixAZALIA_F2_CODEC_PIN_CONTROL_AUDIO_SINK_INFO_DATA 0x3781
+#define ixAZALIA_F2_CODEC_PIN_CONTROL_MULTICHANNEL1_ENABLE 0x3785
+#define ixAZALIA_F2_CODEC_PIN_CONTROL_MULTICHANNEL3_ENABLE 0x3786
+#define ixAZALIA_F2_CODEC_PIN_CONTROL_MULTICHANNEL5_ENABLE 0x3787
+#define ixAZALIA_F2_CODEC_PIN_CONTROL_MULTICHANNEL7_ENABLE 0x3788
+#define ixAZALIA_F2_CODEC_PIN_CONTROL_MULTICHANNEL_MODE 0x3789
+#define ixAZALIA_F2_PIN_CONTROL_CODEC_CS_OVERRIDE_0 0x378a
+#define ixAZALIA_F2_PIN_CONTROL_CODEC_CS_OVERRIDE_1 0x378b
+#define ixAZALIA_F2_PIN_CONTROL_CODEC_CS_OVERRIDE_2 0x378c
+#define ixAZALIA_F2_PIN_CONTROL_CODEC_CS_OVERRIDE_3 0x378d
+#define ixAZALIA_F2_PIN_CONTROL_CODEC_CS_OVERRIDE_4 0x378e
+#define ixAZALIA_F2_PIN_CONTROL_CODEC_CS_OVERRIDE_5 0x378f
+#define ixAZALIA_F2_PIN_CONTROL_CODEC_CS_OVERRIDE_6 0x3790
+#define ixAZALIA_F2_PIN_CONTROL_CODEC_CS_OVERRIDE_7 0x3791
+#define ixAZALIA_F2_PIN_CONTROL_CODEC_CS_OVERRIDE_8 0x3792
+#define ixAZALIA_F2_CODEC_PIN_ASSOCIATION_INFO 0x3793
+#define ixAZALIA_F2_CODEC_PIN_CONTROL_DIGITAL_OUTPUT_STATUS 0x3797
+#define ixAZALIA_F2_CODEC_PIN_CONTROL_LPIB_SNAPSHOT_CONTROL 0x3798
+#define ixAZALIA_F2_CODEC_PIN_CONTROL_LPIB 0x3799
+#define ixAZALIA_F2_CODEC_PIN_CONTROL_LPIB_TIMER_SNAPSHOT 0x379a
+#define ixAZALIA_F2_CODEC_PIN_CONTROL_CODING_TYPE 0x379b
+#define ixAZALIA_F2_CODEC_PIN_CONTROL_FORMAT_CHANGED 0x379c
+#define ixAZALIA_F2_CODEC_PIN_CONTROL_WIRELESS_DISPLAY_IDENTIFICATION 0x379d
+#define ixAZALIA_F2_CODEC_PIN_CONTROL_REMOTE_KEEPALIVE 0x379e
+#define ixAZALIA_F2_CODEC_PIN_PARAMETER_AUDIO_WIDGET_CAPABILITIES 0x3f09
+#define ixAZALIA_F2_CODEC_PIN_PARAMETER_CAPABILITIES 0x3f0c
+#define ixAZALIA_F2_CODEC_PIN_PARAMETER_CONNECTION_LIST_LENGTH 0x3f0e
+
+
+// addressBlock: azendpoint_descriptorind
+// base address: 0x0
+#define ixAUDIO_DESCRIPTOR0 0x0001
+#define ixAUDIO_DESCRIPTOR1 0x0002
+#define ixAUDIO_DESCRIPTOR2 0x0003
+#define ixAUDIO_DESCRIPTOR3 0x0004
+#define ixAUDIO_DESCRIPTOR4 0x0005
+#define ixAUDIO_DESCRIPTOR5 0x0006
+#define ixAUDIO_DESCRIPTOR6 0x0007
+#define ixAUDIO_DESCRIPTOR7 0x0008
+#define ixAUDIO_DESCRIPTOR8 0x0009
+#define ixAUDIO_DESCRIPTOR9 0x000a
+#define ixAUDIO_DESCRIPTOR10 0x000b
+#define ixAUDIO_DESCRIPTOR11 0x000c
+#define ixAUDIO_DESCRIPTOR12 0x000d
+#define ixAUDIO_DESCRIPTOR13 0x000e
+
+
+// addressBlock: azendpoint_sinkinfoind
+// base address: 0x0
+#define ixAZALIA_F2_CODEC_PIN_CONTROL_MANUFACTURER_ID 0x0000
+#define ixAZALIA_F2_CODEC_PIN_CONTROL_PRODUCT_ID 0x0001
+#define ixAZALIA_F2_CODEC_PIN_CONTROL_SINK_DESCRIPTION_LEN 0x0002
+#define ixAZALIA_F2_CODEC_PIN_CONTROL_PORTID0 0x0003
+#define ixAZALIA_F2_CODEC_PIN_CONTROL_PORTID1 0x0004
+#define ixSINK_DESCRIPTION0 0x0005
+#define ixSINK_DESCRIPTION1 0x0006
+#define ixSINK_DESCRIPTION2 0x0007
+#define ixSINK_DESCRIPTION3 0x0008
+#define ixSINK_DESCRIPTION4 0x0009
+#define ixSINK_DESCRIPTION5 0x000a
+#define ixSINK_DESCRIPTION6 0x000b
+#define ixSINK_DESCRIPTION7 0x000c
+#define ixSINK_DESCRIPTION8 0x000d
+#define ixSINK_DESCRIPTION9 0x000e
+#define ixSINK_DESCRIPTION10 0x000f
+#define ixSINK_DESCRIPTION11 0x0010
+#define ixSINK_DESCRIPTION12 0x0011
+#define ixSINK_DESCRIPTION13 0x0012
+#define ixSINK_DESCRIPTION14 0x0013
+#define ixSINK_DESCRIPTION15 0x0014
+#define ixSINK_DESCRIPTION16 0x0015
+#define ixSINK_DESCRIPTION17 0x0016
+
+
+// addressBlock: azf0controller_azinputcrc0resultind
+// base address: 0x0
+#define ixAZALIA_INPUT_CRC0_CHANNEL0 0x0000
+#define ixAZALIA_INPUT_CRC0_CHANNEL1 0x0001
+#define ixAZALIA_INPUT_CRC0_CHANNEL2 0x0002
+#define ixAZALIA_INPUT_CRC0_CHANNEL3 0x0003
+#define ixAZALIA_INPUT_CRC0_CHANNEL4 0x0004
+#define ixAZALIA_INPUT_CRC0_CHANNEL5 0x0005
+#define ixAZALIA_INPUT_CRC0_CHANNEL6 0x0006
+#define ixAZALIA_INPUT_CRC0_CHANNEL7 0x0007
+
+
+// addressBlock: azf0controller_azinputcrc1resultind
+// base address: 0x0
+#define ixAZALIA_INPUT_CRC1_CHANNEL0 0x0000
+#define ixAZALIA_INPUT_CRC1_CHANNEL1 0x0001
+#define ixAZALIA_INPUT_CRC1_CHANNEL2 0x0002
+#define ixAZALIA_INPUT_CRC1_CHANNEL3 0x0003
+#define ixAZALIA_INPUT_CRC1_CHANNEL4 0x0004
+#define ixAZALIA_INPUT_CRC1_CHANNEL5 0x0005
+#define ixAZALIA_INPUT_CRC1_CHANNEL6 0x0006
+#define ixAZALIA_INPUT_CRC1_CHANNEL7 0x0007
+
+
+// addressBlock: azf0controller_azcrc0resultind
+// base address: 0x0
+#define ixAZALIA_CRC0_CHANNEL0 0x0000
+#define ixAZALIA_CRC0_CHANNEL1 0x0001
+#define ixAZALIA_CRC0_CHANNEL2 0x0002
+#define ixAZALIA_CRC0_CHANNEL3 0x0003
+#define ixAZALIA_CRC0_CHANNEL4 0x0004
+#define ixAZALIA_CRC0_CHANNEL5 0x0005
+#define ixAZALIA_CRC0_CHANNEL6 0x0006
+#define ixAZALIA_CRC0_CHANNEL7 0x0007
+
+
+// addressBlock: azf0controller_azcrc1resultind
+// base address: 0x0
+#define ixAZALIA_CRC1_CHANNEL0 0x0000
+#define ixAZALIA_CRC1_CHANNEL1 0x0001
+#define ixAZALIA_CRC1_CHANNEL2 0x0002
+#define ixAZALIA_CRC1_CHANNEL3 0x0003
+#define ixAZALIA_CRC1_CHANNEL4 0x0004
+#define ixAZALIA_CRC1_CHANNEL5 0x0005
+#define ixAZALIA_CRC1_CHANNEL6 0x0006
+#define ixAZALIA_CRC1_CHANNEL7 0x0007
+
+
+// addressBlock: azinputendpoint_f2codecind
+// base address: 0x0
+#define ixAZALIA_F2_CODEC_INPUT_CONVERTER_CONTROL_CONVERTER_FORMAT 0x6200
+#define ixAZALIA_F2_CODEC_INPUT_CONVERTER_CONTROL_CHANNEL_STREAM_ID 0x6706
+#define ixAZALIA_F2_CODEC_INPUT_CONVERTER_CONTROL_DIGITAL_CONVERTER 0x670d
+#define ixAZALIA_F2_CODEC_INPUT_CONVERTER_PARAMETER_AUDIO_WIDGET_CAPABILITIES 0x6f09
+#define ixAZALIA_F2_CODEC_INPUT_CONVERTER_PARAMETER_SUPPORTED_SIZE_RATES 0x6f0a
+#define ixAZALIA_F2_CODEC_INPUT_CONVERTER_PARAMETER_STREAM_FORMATS 0x6f0b
+#define ixAZALIA_F2_CODEC_INPUT_PIN_CONTROL_WIDGET_CONTROL 0x7707
+#define ixAZALIA_F2_CODEC_INPUT_PIN_CONTROL_UNSOLICITED_RESPONSE 0x7708
+#define ixAZALIA_F2_CODEC_INPUT_PIN_CONTROL_RESPONSE_PIN_SENSE 0x7709
+#define ixAZALIA_F2_CODEC_INPUT_PIN_CONTROL_RESPONSE_CONFIGURATION_DEFAULT 0x771c
+#define ixAZALIA_F2_CODEC_INPUT_PIN_CONTROL_RESPONSE_CONFIGURATION_DEFAULT_2 0x771d
+#define ixAZALIA_F2_CODEC_INPUT_PIN_CONTROL_RESPONSE_CONFIGURATION_DEFAULT_3 0x771e
+#define ixAZALIA_F2_CODEC_INPUT_PIN_CONTROL_RESPONSE_CONFIGURATION_DEFAULT_4 0x771f
+#define ixAZALIA_F2_CODEC_INPUT_PIN_CONTROL_CHANNEL_ALLOCATION 0x7771
+#define ixAZALIA_F2_CODEC_INPUT_PIN_CONTROL_MULTICHANNEL0_ENABLE 0x7777
+#define ixAZALIA_F2_CODEC_INPUT_PIN_CONTROL_MULTICHANNEL2_ENABLE 0x7778
+#define ixAZALIA_F2_CODEC_INPUT_PIN_CONTROL_MULTICHANNEL4_ENABLE 0x7779
+#define ixAZALIA_F2_CODEC_INPUT_PIN_CONTROL_MULTICHANNEL6_ENABLE 0x777a
+#define ixAZALIA_F2_CODEC_INPUT_PIN_CONTROL_HBR 0x777c
+#define ixAZALIA_F2_CODEC_INPUT_PIN_CONTROL_MULTICHANNEL1_ENABLE 0x7785
+#define ixAZALIA_F2_CODEC_INPUT_PIN_CONTROL_MULTICHANNEL3_ENABLE 0x7786
+#define ixAZALIA_F2_CODEC_INPUT_PIN_CONTROL_MULTICHANNEL5_ENABLE 0x7787
+#define ixAZALIA_F2_CODEC_INPUT_PIN_CONTROL_MULTICHANNEL7_ENABLE 0x7788
+#define ixAZALIA_F2_CODEC_INPUT_PIN_CONTROL_LPIB_SNAPSHOT_CONTROL 0x7798
+#define ixAZALIA_F2_CODEC_INPUT_PIN_CONTROL_LPIB 0x7799
+#define ixAZALIA_F2_CODEC_INPUT_PIN_CONTROL_LPIB_TIMER_SNAPSHOT 0x779a
+#define ixAZALIA_F2_CODEC_INPUT_PIN_CONTROL_INPUT_STATUS_CONTROL 0x779b
+#define ixAZALIA_F2_CODEC_INPUT_PIN_CONTROL_INFOFRAME 0x779c
+#define ixAZALIA_F2_CODEC_INPUT_PIN_CONTROL_CHANNEL_STATUS_L 0x779d
+#define ixAZALIA_F2_CODEC_INPUT_PIN_CONTROL_CHANNEL_STATUS_H 0x779e
+#define ixAZALIA_F2_CODEC_INPUT_PIN_PARAMETER_AUDIO_WIDGET_CAPABILITIES 0x7f09
+#define ixAZALIA_F2_CODEC_INPUT_PIN_PARAMETER_CAPABILITIES 0x7f0c
+
+
+// addressBlock: azroot_f2codecind
+// base address: 0x0
+#define ixAZALIA_F2_CODEC_ROOT_PARAMETER_VENDOR_AND_DEVICE_ID 0x0f00
+#define ixAZALIA_F2_CODEC_ROOT_PARAMETER_REVISION_ID 0x0f02
+#define ixAZALIA_F2_CODEC_ROOT_PARAMETER_SUBORDINATE_NODE_COUNT 0x0f04
+#define ixAZALIA_F2_CODEC_FUNCTION_CONTROL_POWER_STATE 0x1705
+#define ixAZALIA_F2_CODEC_FUNCTION_CONTROL_RESPONSE_SUBSYSTEM_ID 0x1720
+#define ixAZALIA_F2_CODEC_FUNCTION_CONTROL_RESPONSE_SUBSYSTEM_ID_2 0x1721
+#define ixAZALIA_F2_CODEC_FUNCTION_CONTROL_RESPONSE_SUBSYSTEM_ID_3 0x1722
+#define ixAZALIA_F2_CODEC_FUNCTION_CONTROL_RESPONSE_SUBSYSTEM_ID_4 0x1723
+#define ixAZALIA_F2_CODEC_FUNCTION_CONTROL_CONVERTER_SYNCHRONIZATION 0x1770
+#define ixAZALIA_F2_CODEC_FUNCTION_CONTROL_RESET 0x17ff
+#define ixAZALIA_F2_CODEC_FUNCTION_PARAMETER_SUBORDINATE_NODE_COUNT 0x1f04
+#define ixAZALIA_F2_CODEC_FUNCTION_PARAMETER_GROUP_TYPE 0x1f05
+#define ixAZALIA_F2_CODEC_FUNCTION_PARAMETER_SUPPORTED_SIZE_RATES 0x1f0a
+#define ixAZALIA_F2_CODEC_FUNCTION_PARAMETER_STREAM_FORMATS 0x1f0b
+#define ixAZALIA_F2_CODEC_FUNCTION_PARAMETER_POWER_STATES 0x1f0f
+
+
+// addressBlock: azf0stream0_streamind
+// base address: 0x0
+#define ixAZF0STREAM0_AZALIA_FIFO_SIZE_CONTROL 0x0000
+#define ixAZF0STREAM0_AZALIA_LATENCY_COUNTER_CONTROL 0x0001
+#define ixAZF0STREAM0_AZALIA_WORSTCASE_LATENCY_COUNT 0x0002
+#define ixAZF0STREAM0_AZALIA_CUMULATIVE_LATENCY_COUNT 0x0003
+#define ixAZF0STREAM0_AZALIA_CUMULATIVE_REQUEST_COUNT 0x0004
+
+
+// addressBlock: azf0stream1_streamind
+// base address: 0x0
+#define ixAZF0STREAM1_AZALIA_FIFO_SIZE_CONTROL 0x0000
+#define ixAZF0STREAM1_AZALIA_LATENCY_COUNTER_CONTROL 0x0001
+#define ixAZF0STREAM1_AZALIA_WORSTCASE_LATENCY_COUNT 0x0002
+#define ixAZF0STREAM1_AZALIA_CUMULATIVE_LATENCY_COUNT 0x0003
+#define ixAZF0STREAM1_AZALIA_CUMULATIVE_REQUEST_COUNT 0x0004
+
+
+// addressBlock: azf0stream2_streamind
+// base address: 0x0
+#define ixAZF0STREAM2_AZALIA_FIFO_SIZE_CONTROL 0x0000
+#define ixAZF0STREAM2_AZALIA_LATENCY_COUNTER_CONTROL 0x0001
+#define ixAZF0STREAM2_AZALIA_WORSTCASE_LATENCY_COUNT 0x0002
+#define ixAZF0STREAM2_AZALIA_CUMULATIVE_LATENCY_COUNT 0x0003
+#define ixAZF0STREAM2_AZALIA_CUMULATIVE_REQUEST_COUNT 0x0004
+
+
+// addressBlock: azf0stream3_streamind
+// base address: 0x0
+#define ixAZF0STREAM3_AZALIA_FIFO_SIZE_CONTROL 0x0000
+#define ixAZF0STREAM3_AZALIA_LATENCY_COUNTER_CONTROL 0x0001
+#define ixAZF0STREAM3_AZALIA_WORSTCASE_LATENCY_COUNT 0x0002
+#define ixAZF0STREAM3_AZALIA_CUMULATIVE_LATENCY_COUNT 0x0003
+#define ixAZF0STREAM3_AZALIA_CUMULATIVE_REQUEST_COUNT 0x0004
+
+
+// addressBlock: azf0stream4_streamind
+// base address: 0x0
+#define ixAZF0STREAM4_AZALIA_FIFO_SIZE_CONTROL 0x0000
+#define ixAZF0STREAM4_AZALIA_LATENCY_COUNTER_CONTROL 0x0001
+#define ixAZF0STREAM4_AZALIA_WORSTCASE_LATENCY_COUNT 0x0002
+#define ixAZF0STREAM4_AZALIA_CUMULATIVE_LATENCY_COUNT 0x0003
+#define ixAZF0STREAM4_AZALIA_CUMULATIVE_REQUEST_COUNT 0x0004
+
+
+// addressBlock: azf0stream5_streamind
+// base address: 0x0
+#define ixAZF0STREAM5_AZALIA_FIFO_SIZE_CONTROL 0x0000
+#define ixAZF0STREAM5_AZALIA_LATENCY_COUNTER_CONTROL 0x0001
+#define ixAZF0STREAM5_AZALIA_WORSTCASE_LATENCY_COUNT 0x0002
+#define ixAZF0STREAM5_AZALIA_CUMULATIVE_LATENCY_COUNT 0x0003
+#define ixAZF0STREAM5_AZALIA_CUMULATIVE_REQUEST_COUNT 0x0004
+
+
+// addressBlock: azf0stream6_streamind
+// base address: 0x0
+#define ixAZF0STREAM6_AZALIA_FIFO_SIZE_CONTROL 0x0000
+#define ixAZF0STREAM6_AZALIA_LATENCY_COUNTER_CONTROL 0x0001
+#define ixAZF0STREAM6_AZALIA_WORSTCASE_LATENCY_COUNT 0x0002
+#define ixAZF0STREAM6_AZALIA_CUMULATIVE_LATENCY_COUNT 0x0003
+#define ixAZF0STREAM6_AZALIA_CUMULATIVE_REQUEST_COUNT 0x0004
+
+
+// addressBlock: azf0stream7_streamind
+// base address: 0x0
+#define ixAZF0STREAM7_AZALIA_FIFO_SIZE_CONTROL 0x0000
+#define ixAZF0STREAM7_AZALIA_LATENCY_COUNTER_CONTROL 0x0001
+#define ixAZF0STREAM7_AZALIA_WORSTCASE_LATENCY_COUNT 0x0002
+#define ixAZF0STREAM7_AZALIA_CUMULATIVE_LATENCY_COUNT 0x0003
+#define ixAZF0STREAM7_AZALIA_CUMULATIVE_REQUEST_COUNT 0x0004
+
+
+// addressBlock: azf0stream8_streamind
+// base address: 0x0
+#define ixAZF0STREAM8_AZALIA_FIFO_SIZE_CONTROL 0x0000
+#define ixAZF0STREAM8_AZALIA_LATENCY_COUNTER_CONTROL 0x0001
+#define ixAZF0STREAM8_AZALIA_WORSTCASE_LATENCY_COUNT 0x0002
+#define ixAZF0STREAM8_AZALIA_CUMULATIVE_LATENCY_COUNT 0x0003
+#define ixAZF0STREAM8_AZALIA_CUMULATIVE_REQUEST_COUNT 0x0004
+
+
+// addressBlock: azf0stream9_streamind
+// base address: 0x0
+#define ixAZF0STREAM9_AZALIA_FIFO_SIZE_CONTROL 0x0000
+#define ixAZF0STREAM9_AZALIA_LATENCY_COUNTER_CONTROL 0x0001
+#define ixAZF0STREAM9_AZALIA_WORSTCASE_LATENCY_COUNT 0x0002
+#define ixAZF0STREAM9_AZALIA_CUMULATIVE_LATENCY_COUNT 0x0003
+#define ixAZF0STREAM9_AZALIA_CUMULATIVE_REQUEST_COUNT 0x0004
+
+
+// addressBlock: azf0stream10_streamind
+// base address: 0x0
+#define ixAZF0STREAM10_AZALIA_FIFO_SIZE_CONTROL 0x0000
+#define ixAZF0STREAM10_AZALIA_LATENCY_COUNTER_CONTROL 0x0001
+#define ixAZF0STREAM10_AZALIA_WORSTCASE_LATENCY_COUNT 0x0002
+#define ixAZF0STREAM10_AZALIA_CUMULATIVE_LATENCY_COUNT 0x0003
+#define ixAZF0STREAM10_AZALIA_CUMULATIVE_REQUEST_COUNT 0x0004
+
+
+// addressBlock: azf0stream11_streamind
+// base address: 0x0
+#define ixAZF0STREAM11_AZALIA_FIFO_SIZE_CONTROL 0x0000
+#define ixAZF0STREAM11_AZALIA_LATENCY_COUNTER_CONTROL 0x0001
+#define ixAZF0STREAM11_AZALIA_WORSTCASE_LATENCY_COUNT 0x0002
+#define ixAZF0STREAM11_AZALIA_CUMULATIVE_LATENCY_COUNT 0x0003
+#define ixAZF0STREAM11_AZALIA_CUMULATIVE_REQUEST_COUNT 0x0004
+
+
+// addressBlock: azf0stream12_streamind
+// base address: 0x0
+#define ixAZF0STREAM12_AZALIA_FIFO_SIZE_CONTROL 0x0000
+#define ixAZF0STREAM12_AZALIA_LATENCY_COUNTER_CONTROL 0x0001
+#define ixAZF0STREAM12_AZALIA_WORSTCASE_LATENCY_COUNT 0x0002
+#define ixAZF0STREAM12_AZALIA_CUMULATIVE_LATENCY_COUNT 0x0003
+#define ixAZF0STREAM12_AZALIA_CUMULATIVE_REQUEST_COUNT 0x0004
+
+
+// addressBlock: azf0stream13_streamind
+// base address: 0x0
+#define ixAZF0STREAM13_AZALIA_FIFO_SIZE_CONTROL 0x0000
+#define ixAZF0STREAM13_AZALIA_LATENCY_COUNTER_CONTROL 0x0001
+#define ixAZF0STREAM13_AZALIA_WORSTCASE_LATENCY_COUNT 0x0002
+#define ixAZF0STREAM13_AZALIA_CUMULATIVE_LATENCY_COUNT 0x0003
+#define ixAZF0STREAM13_AZALIA_CUMULATIVE_REQUEST_COUNT 0x0004
+
+
+// addressBlock: azf0stream14_streamind
+// base address: 0x0
+#define ixAZF0STREAM14_AZALIA_FIFO_SIZE_CONTROL 0x0000
+#define ixAZF0STREAM14_AZALIA_LATENCY_COUNTER_CONTROL 0x0001
+#define ixAZF0STREAM14_AZALIA_WORSTCASE_LATENCY_COUNT 0x0002
+#define ixAZF0STREAM14_AZALIA_CUMULATIVE_LATENCY_COUNT 0x0003
+#define ixAZF0STREAM14_AZALIA_CUMULATIVE_REQUEST_COUNT 0x0004
+
+
+// addressBlock: azf0stream15_streamind
+// base address: 0x0
+#define ixAZF0STREAM15_AZALIA_FIFO_SIZE_CONTROL 0x0000
+#define ixAZF0STREAM15_AZALIA_LATENCY_COUNTER_CONTROL 0x0001
+#define ixAZF0STREAM15_AZALIA_WORSTCASE_LATENCY_COUNT 0x0002
+#define ixAZF0STREAM15_AZALIA_CUMULATIVE_LATENCY_COUNT 0x0003
+#define ixAZF0STREAM15_AZALIA_CUMULATIVE_REQUEST_COUNT 0x0004
+
+
+// addressBlock: azf0endpoint0_endpointind
+// base address: 0x0
+#define ixAZF0ENDPOINT0_AZALIA_F0_CODEC_CONVERTER_PARAMETER_AUDIO_WIDGET_CAPABILITIES 0x0001
+#define ixAZF0ENDPOINT0_AZALIA_F0_CODEC_CONVERTER_CONTROL_CONVERTER_FORMAT 0x0002
+#define ixAZF0ENDPOINT0_AZALIA_F0_CODEC_CONVERTER_CONTROL_CHANNEL_STREAM_ID 0x0003
+#define ixAZF0ENDPOINT0_AZALIA_F0_CODEC_CONVERTER_CONTROL_DIGITAL_CONVERTER 0x0004
+#define ixAZF0ENDPOINT0_AZALIA_F0_CODEC_CONVERTER_PARAMETER_STREAM_FORMATS 0x0005
+#define ixAZF0ENDPOINT0_AZALIA_F0_CODEC_CONVERTER_PARAMETER_SUPPORTED_SIZE_RATES 0x0006
+#define ixAZF0ENDPOINT0_AZALIA_F0_CODEC_CONVERTER_STRIPE_CONTROL 0x0007
+#define ixAZF0ENDPOINT0_AZALIA_F0_CODEC_CONVERTER_CONTROL_RAMP_RATE 0x0008
+#define ixAZF0ENDPOINT0_AZALIA_F0_CODEC_CONVERTER_CONTROL_GTC_EMBEDDING 0x0009
+#define ixAZF0ENDPOINT0_AZALIA_F0_CODEC_CONVERTER_GTC_COUNTER_DELTA 0x000c
+#define ixAZF0ENDPOINT0_AZALIA_F0_CODEC_CONVERTER_GTC_COUNTER_DELTA_MIN 0x000d
+#define ixAZF0ENDPOINT0_AZALIA_F0_CODEC_CONVERTER_GTC_COUNTER_DELTA_MAX 0x000e
+#define ixAZF0ENDPOINT0_AZALIA_F0_CODEC_PIN_PARAMETER_AUDIO_WIDGET_CAPABILITIES 0x0020
+#define ixAZF0ENDPOINT0_AZALIA_F0_CODEC_PIN_PARAMETER_CAPABILITIES 0x0021
+#define ixAZF0ENDPOINT0_AZALIA_F0_CODEC_PIN_CONTROL_UNSOLICITED_RESPONSE 0x0022
+#define ixAZF0ENDPOINT0_AZALIA_F0_CODEC_PIN_CONTROL_RESPONSE_PIN_SENSE 0x0023
+#define ixAZF0ENDPOINT0_AZALIA_F0_CODEC_PIN_CONTROL_WIDGET_CONTROL 0x0024
+#define ixAZF0ENDPOINT0_AZALIA_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER 0x0025
+#define ixAZF0ENDPOINT0_AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR0 0x0028
+#define ixAZF0ENDPOINT0_AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR1 0x0029
+#define ixAZF0ENDPOINT0_AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR2 0x002a
+#define ixAZF0ENDPOINT0_AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR3 0x002b
+#define ixAZF0ENDPOINT0_AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR4 0x002c
+#define ixAZF0ENDPOINT0_AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR5 0x002d
+#define ixAZF0ENDPOINT0_AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR6 0x002e
+#define ixAZF0ENDPOINT0_AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR7 0x002f
+#define ixAZF0ENDPOINT0_AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR8 0x0030
+#define ixAZF0ENDPOINT0_AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR9 0x0031
+#define ixAZF0ENDPOINT0_AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR10 0x0032
+#define ixAZF0ENDPOINT0_AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR11 0x0033
+#define ixAZF0ENDPOINT0_AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR12 0x0034
+#define ixAZF0ENDPOINT0_AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR13 0x0035
+#define ixAZF0ENDPOINT0_AZALIA_F0_CODEC_PIN_CONTROL_MULTICHANNEL_ENABLE 0x0036
+#define ixAZF0ENDPOINT0_AZALIA_F0_CODEC_PIN_CONTROL_RESPONSE_LIPSYNC 0x0037
+#define ixAZF0ENDPOINT0_AZALIA_F0_CODEC_PIN_CONTROL_RESPONSE_HBR 0x0038
+#define ixAZF0ENDPOINT0_AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO0 0x003a
+#define ixAZF0ENDPOINT0_AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO1 0x003b
+#define ixAZF0ENDPOINT0_AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO2 0x003c
+#define ixAZF0ENDPOINT0_AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO3 0x003d
+#define ixAZF0ENDPOINT0_AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO4 0x003e
+#define ixAZF0ENDPOINT0_AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO5 0x003f
+#define ixAZF0ENDPOINT0_AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO6 0x0040
+#define ixAZF0ENDPOINT0_AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO7 0x0041
+#define ixAZF0ENDPOINT0_AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO8 0x0042
+#define ixAZF0ENDPOINT0_AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL 0x0054
+#define ixAZF0ENDPOINT0_AZALIA_F0_CODEC_PIN_CONTROL_UNSOLICITED_RESPONSE_FORCE 0x0055
+#define ixAZF0ENDPOINT0_AZALIA_F0_CODEC_PIN_CONTROL_RESPONSE_CONFIGURATION_DEFAULT 0x0056
+#define ixAZF0ENDPOINT0_AZALIA_F0_CODEC_PIN_CONTROL_MULTICHANNEL_ENABLE2 0x0057
+#define ixAZF0ENDPOINT0_AZALIA_F0_CODEC_PIN_CONTROL_MULTICHANNEL_MODE 0x0058
+#define ixAZF0ENDPOINT0_AZALIA_F0_PIN_CONTROL_CODEC_CS_OVERRIDE_0 0x0059
+#define ixAZF0ENDPOINT0_AZALIA_F0_PIN_CONTROL_CODEC_CS_OVERRIDE_1 0x005a
+#define ixAZF0ENDPOINT0_AZALIA_F0_PIN_CONTROL_CODEC_CS_OVERRIDE_2 0x005b
+#define ixAZF0ENDPOINT0_AZALIA_F0_PIN_CONTROL_CODEC_CS_OVERRIDE_3 0x005c
+#define ixAZF0ENDPOINT0_AZALIA_F0_PIN_CONTROL_CODEC_CS_OVERRIDE_4 0x005d
+#define ixAZF0ENDPOINT0_AZALIA_F0_PIN_CONTROL_CODEC_CS_OVERRIDE_5 0x005e
+#define ixAZF0ENDPOINT0_AZALIA_F0_PIN_CONTROL_CODEC_CS_OVERRIDE_6 0x005f
+#define ixAZF0ENDPOINT0_AZALIA_F0_PIN_CONTROL_CODEC_CS_OVERRIDE_7 0x0060
+#define ixAZF0ENDPOINT0_AZALIA_F0_PIN_CONTROL_CODEC_CS_OVERRIDE_8 0x0061
+#define ixAZF0ENDPOINT0_AZALIA_F0_CODEC_PIN_ASSOCIATION_INFO 0x0062
+#define ixAZF0ENDPOINT0_AZALIA_F0_CODEC_PIN_CONTROL_DIGITAL_OUTPUT_STATUS 0x0063
+#define ixAZF0ENDPOINT0_AZALIA_F0_CODEC_PIN_CONTROL_LPIB_SNAPSHOT_CONTROL 0x0064
+#define ixAZF0ENDPOINT0_AZALIA_F0_CODEC_PIN_CONTROL_LPIB 0x0065
+#define ixAZF0ENDPOINT0_AZALIA_F0_CODEC_PIN_CONTROL_LPIB_TIMER_SNAPSHOT 0x0066
+#define ixAZF0ENDPOINT0_AZALIA_F0_CODEC_PIN_CONTROL_CODING_TYPE 0x0067
+#define ixAZF0ENDPOINT0_AZALIA_F0_CODEC_PIN_CONTROL_FORMAT_CHANGED 0x0068
+#define ixAZF0ENDPOINT0_AZALIA_F0_CODEC_PIN_CONTROL_WIRELESS_DISPLAY_IDENTIFICATION 0x0069
+#define ixAZF0ENDPOINT0_AZALIA_F0_CODEC_PIN_CONTROL_REMOTE_KEEPALIVE 0x006a
+#define ixAZF0ENDPOINT0_AZALIA_F0_AUDIO_ENABLE_STATUS 0x006b
+#define ixAZF0ENDPOINT0_AZALIA_F0_AUDIO_ENABLED_INT_STATUS 0x006c
+#define ixAZF0ENDPOINT0_AZALIA_F0_AUDIO_DISABLED_INT_STATUS 0x006d
+#define ixAZF0ENDPOINT0_AZALIA_F0_AUDIO_FORMAT_CHANGED_INT_STATUS 0x006e
+
+
+// addressBlock: azf0endpoint1_endpointind
+// base address: 0x0
+#define ixAZF0ENDPOINT1_AZALIA_F0_CODEC_CONVERTER_PARAMETER_AUDIO_WIDGET_CAPABILITIES 0x0001
+#define ixAZF0ENDPOINT1_AZALIA_F0_CODEC_CONVERTER_CONTROL_CONVERTER_FORMAT 0x0002
+#define ixAZF0ENDPOINT1_AZALIA_F0_CODEC_CONVERTER_CONTROL_CHANNEL_STREAM_ID 0x0003
+#define ixAZF0ENDPOINT1_AZALIA_F0_CODEC_CONVERTER_CONTROL_DIGITAL_CONVERTER 0x0004
+#define ixAZF0ENDPOINT1_AZALIA_F0_CODEC_CONVERTER_PARAMETER_STREAM_FORMATS 0x0005
+#define ixAZF0ENDPOINT1_AZALIA_F0_CODEC_CONVERTER_PARAMETER_SUPPORTED_SIZE_RATES 0x0006
+#define ixAZF0ENDPOINT1_AZALIA_F0_CODEC_CONVERTER_STRIPE_CONTROL 0x0007
+#define ixAZF0ENDPOINT1_AZALIA_F0_CODEC_CONVERTER_CONTROL_RAMP_RATE 0x0008
+#define ixAZF0ENDPOINT1_AZALIA_F0_CODEC_CONVERTER_CONTROL_GTC_EMBEDDING 0x0009
+#define ixAZF0ENDPOINT1_AZALIA_F0_CODEC_CONVERTER_GTC_COUNTER_DELTA 0x000c
+#define ixAZF0ENDPOINT1_AZALIA_F0_CODEC_CONVERTER_GTC_COUNTER_DELTA_MIN 0x000d
+#define ixAZF0ENDPOINT1_AZALIA_F0_CODEC_CONVERTER_GTC_COUNTER_DELTA_MAX 0x000e
+#define ixAZF0ENDPOINT1_AZALIA_F0_CODEC_PIN_PARAMETER_AUDIO_WIDGET_CAPABILITIES 0x0020
+#define ixAZF0ENDPOINT1_AZALIA_F0_CODEC_PIN_PARAMETER_CAPABILITIES 0x0021
+#define ixAZF0ENDPOINT1_AZALIA_F0_CODEC_PIN_CONTROL_UNSOLICITED_RESPONSE 0x0022
+#define ixAZF0ENDPOINT1_AZALIA_F0_CODEC_PIN_CONTROL_RESPONSE_PIN_SENSE 0x0023
+#define ixAZF0ENDPOINT1_AZALIA_F0_CODEC_PIN_CONTROL_WIDGET_CONTROL 0x0024
+#define ixAZF0ENDPOINT1_AZALIA_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER 0x0025
+#define ixAZF0ENDPOINT1_AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR0 0x0028
+#define ixAZF0ENDPOINT1_AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR1 0x0029
+#define ixAZF0ENDPOINT1_AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR2 0x002a
+#define ixAZF0ENDPOINT1_AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR3 0x002b
+#define ixAZF0ENDPOINT1_AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR4 0x002c
+#define ixAZF0ENDPOINT1_AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR5 0x002d
+#define ixAZF0ENDPOINT1_AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR6 0x002e
+#define ixAZF0ENDPOINT1_AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR7 0x002f
+#define ixAZF0ENDPOINT1_AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR8 0x0030
+#define ixAZF0ENDPOINT1_AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR9 0x0031
+#define ixAZF0ENDPOINT1_AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR10 0x0032
+#define ixAZF0ENDPOINT1_AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR11 0x0033
+#define ixAZF0ENDPOINT1_AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR12 0x0034
+#define ixAZF0ENDPOINT1_AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR13 0x0035
+#define ixAZF0ENDPOINT1_AZALIA_F0_CODEC_PIN_CONTROL_MULTICHANNEL_ENABLE 0x0036
+#define ixAZF0ENDPOINT1_AZALIA_F0_CODEC_PIN_CONTROL_RESPONSE_LIPSYNC 0x0037
+#define ixAZF0ENDPOINT1_AZALIA_F0_CODEC_PIN_CONTROL_RESPONSE_HBR 0x0038
+#define ixAZF0ENDPOINT1_AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO0 0x003a
+#define ixAZF0ENDPOINT1_AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO1 0x003b
+#define ixAZF0ENDPOINT1_AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO2 0x003c
+#define ixAZF0ENDPOINT1_AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO3 0x003d
+#define ixAZF0ENDPOINT1_AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO4 0x003e
+#define ixAZF0ENDPOINT1_AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO5 0x003f
+#define ixAZF0ENDPOINT1_AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO6 0x0040
+#define ixAZF0ENDPOINT1_AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO7 0x0041
+#define ixAZF0ENDPOINT1_AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO8 0x0042
+#define ixAZF0ENDPOINT1_AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL 0x0054
+#define ixAZF0ENDPOINT1_AZALIA_F0_CODEC_PIN_CONTROL_UNSOLICITED_RESPONSE_FORCE 0x0055
+#define ixAZF0ENDPOINT1_AZALIA_F0_CODEC_PIN_CONTROL_RESPONSE_CONFIGURATION_DEFAULT 0x0056
+#define ixAZF0ENDPOINT1_AZALIA_F0_CODEC_PIN_CONTROL_MULTICHANNEL_ENABLE2 0x0057
+#define ixAZF0ENDPOINT1_AZALIA_F0_CODEC_PIN_CONTROL_MULTICHANNEL_MODE 0x0058
+#define ixAZF0ENDPOINT1_AZALIA_F0_PIN_CONTROL_CODEC_CS_OVERRIDE_0 0x0059
+#define ixAZF0ENDPOINT1_AZALIA_F0_PIN_CONTROL_CODEC_CS_OVERRIDE_1 0x005a
+#define ixAZF0ENDPOINT1_AZALIA_F0_PIN_CONTROL_CODEC_CS_OVERRIDE_2 0x005b
+#define ixAZF0ENDPOINT1_AZALIA_F0_PIN_CONTROL_CODEC_CS_OVERRIDE_3 0x005c
+#define ixAZF0ENDPOINT1_AZALIA_F0_PIN_CONTROL_CODEC_CS_OVERRIDE_4 0x005d
+#define ixAZF0ENDPOINT1_AZALIA_F0_PIN_CONTROL_CODEC_CS_OVERRIDE_5 0x005e
+#define ixAZF0ENDPOINT1_AZALIA_F0_PIN_CONTROL_CODEC_CS_OVERRIDE_6 0x005f
+#define ixAZF0ENDPOINT1_AZALIA_F0_PIN_CONTROL_CODEC_CS_OVERRIDE_7 0x0060
+#define ixAZF0ENDPOINT1_AZALIA_F0_PIN_CONTROL_CODEC_CS_OVERRIDE_8 0x0061
+#define ixAZF0ENDPOINT1_AZALIA_F0_CODEC_PIN_ASSOCIATION_INFO 0x0062
+#define ixAZF0ENDPOINT1_AZALIA_F0_CODEC_PIN_CONTROL_DIGITAL_OUTPUT_STATUS 0x0063
+#define ixAZF0ENDPOINT1_AZALIA_F0_CODEC_PIN_CONTROL_LPIB_SNAPSHOT_CONTROL 0x0064
+#define ixAZF0ENDPOINT1_AZALIA_F0_CODEC_PIN_CONTROL_LPIB 0x0065
+#define ixAZF0ENDPOINT1_AZALIA_F0_CODEC_PIN_CONTROL_LPIB_TIMER_SNAPSHOT 0x0066
+#define ixAZF0ENDPOINT1_AZALIA_F0_CODEC_PIN_CONTROL_CODING_TYPE 0x0067
+#define ixAZF0ENDPOINT1_AZALIA_F0_CODEC_PIN_CONTROL_FORMAT_CHANGED 0x0068
+#define ixAZF0ENDPOINT1_AZALIA_F0_CODEC_PIN_CONTROL_WIRELESS_DISPLAY_IDENTIFICATION 0x0069
+#define ixAZF0ENDPOINT1_AZALIA_F0_CODEC_PIN_CONTROL_REMOTE_KEEPALIVE 0x006a
+#define ixAZF0ENDPOINT1_AZALIA_F0_AUDIO_ENABLE_STATUS 0x006b
+#define ixAZF0ENDPOINT1_AZALIA_F0_AUDIO_ENABLED_INT_STATUS 0x006c
+#define ixAZF0ENDPOINT1_AZALIA_F0_AUDIO_DISABLED_INT_STATUS 0x006d
+#define ixAZF0ENDPOINT1_AZALIA_F0_AUDIO_FORMAT_CHANGED_INT_STATUS 0x006e
+
+
+// addressBlock: azf0endpoint2_endpointind
+// base address: 0x0
+#define ixAZF0ENDPOINT2_AZALIA_F0_CODEC_CONVERTER_PARAMETER_AUDIO_WIDGET_CAPABILITIES 0x0001
+#define ixAZF0ENDPOINT2_AZALIA_F0_CODEC_CONVERTER_CONTROL_CONVERTER_FORMAT 0x0002
+#define ixAZF0ENDPOINT2_AZALIA_F0_CODEC_CONVERTER_CONTROL_CHANNEL_STREAM_ID 0x0003
+#define ixAZF0ENDPOINT2_AZALIA_F0_CODEC_CONVERTER_CONTROL_DIGITAL_CONVERTER 0x0004
+#define ixAZF0ENDPOINT2_AZALIA_F0_CODEC_CONVERTER_PARAMETER_STREAM_FORMATS 0x0005
+#define ixAZF0ENDPOINT2_AZALIA_F0_CODEC_CONVERTER_PARAMETER_SUPPORTED_SIZE_RATES 0x0006
+#define ixAZF0ENDPOINT2_AZALIA_F0_CODEC_CONVERTER_STRIPE_CONTROL 0x0007
+#define ixAZF0ENDPOINT2_AZALIA_F0_CODEC_CONVERTER_CONTROL_RAMP_RATE 0x0008
+#define ixAZF0ENDPOINT2_AZALIA_F0_CODEC_CONVERTER_CONTROL_GTC_EMBEDDING 0x0009
+#define ixAZF0ENDPOINT2_AZALIA_F0_CODEC_CONVERTER_GTC_COUNTER_DELTA 0x000c
+#define ixAZF0ENDPOINT2_AZALIA_F0_CODEC_CONVERTER_GTC_COUNTER_DELTA_MIN 0x000d
+#define ixAZF0ENDPOINT2_AZALIA_F0_CODEC_CONVERTER_GTC_COUNTER_DELTA_MAX 0x000e
+#define ixAZF0ENDPOINT2_AZALIA_F0_CODEC_PIN_PARAMETER_AUDIO_WIDGET_CAPABILITIES 0x0020
+#define ixAZF0ENDPOINT2_AZALIA_F0_CODEC_PIN_PARAMETER_CAPABILITIES 0x0021
+#define ixAZF0ENDPOINT2_AZALIA_F0_CODEC_PIN_CONTROL_UNSOLICITED_RESPONSE 0x0022
+#define ixAZF0ENDPOINT2_AZALIA_F0_CODEC_PIN_CONTROL_RESPONSE_PIN_SENSE 0x0023
+#define ixAZF0ENDPOINT2_AZALIA_F0_CODEC_PIN_CONTROL_WIDGET_CONTROL 0x0024
+#define ixAZF0ENDPOINT2_AZALIA_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER 0x0025
+#define ixAZF0ENDPOINT2_AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR0 0x0028
+#define ixAZF0ENDPOINT2_AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR1 0x0029
+#define ixAZF0ENDPOINT2_AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR2 0x002a
+#define ixAZF0ENDPOINT2_AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR3 0x002b
+#define ixAZF0ENDPOINT2_AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR4 0x002c
+#define ixAZF0ENDPOINT2_AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR5 0x002d
+#define ixAZF0ENDPOINT2_AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR6 0x002e
+#define ixAZF0ENDPOINT2_AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR7 0x002f
+#define ixAZF0ENDPOINT2_AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR8 0x0030
+#define ixAZF0ENDPOINT2_AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR9 0x0031
+#define ixAZF0ENDPOINT2_AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR10 0x0032
+#define ixAZF0ENDPOINT2_AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR11 0x0033
+#define ixAZF0ENDPOINT2_AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR12 0x0034
+#define ixAZF0ENDPOINT2_AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR13 0x0035
+#define ixAZF0ENDPOINT2_AZALIA_F0_CODEC_PIN_CONTROL_MULTICHANNEL_ENABLE 0x0036
+#define ixAZF0ENDPOINT2_AZALIA_F0_CODEC_PIN_CONTROL_RESPONSE_LIPSYNC 0x0037
+#define ixAZF0ENDPOINT2_AZALIA_F0_CODEC_PIN_CONTROL_RESPONSE_HBR 0x0038
+#define ixAZF0ENDPOINT2_AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO0 0x003a
+#define ixAZF0ENDPOINT2_AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO1 0x003b
+#define ixAZF0ENDPOINT2_AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO2 0x003c
+#define ixAZF0ENDPOINT2_AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO3 0x003d
+#define ixAZF0ENDPOINT2_AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO4 0x003e
+#define ixAZF0ENDPOINT2_AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO5 0x003f
+#define ixAZF0ENDPOINT2_AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO6 0x0040
+#define ixAZF0ENDPOINT2_AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO7 0x0041
+#define ixAZF0ENDPOINT2_AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO8 0x0042
+#define ixAZF0ENDPOINT2_AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL 0x0054
+#define ixAZF0ENDPOINT2_AZALIA_F0_CODEC_PIN_CONTROL_UNSOLICITED_RESPONSE_FORCE 0x0055
+#define ixAZF0ENDPOINT2_AZALIA_F0_CODEC_PIN_CONTROL_RESPONSE_CONFIGURATION_DEFAULT 0x0056
+#define ixAZF0ENDPOINT2_AZALIA_F0_CODEC_PIN_CONTROL_MULTICHANNEL_ENABLE2 0x0057
+#define ixAZF0ENDPOINT2_AZALIA_F0_CODEC_PIN_CONTROL_MULTICHANNEL_MODE 0x0058
+#define ixAZF0ENDPOINT2_AZALIA_F0_PIN_CONTROL_CODEC_CS_OVERRIDE_0 0x0059
+#define ixAZF0ENDPOINT2_AZALIA_F0_PIN_CONTROL_CODEC_CS_OVERRIDE_1 0x005a
+#define ixAZF0ENDPOINT2_AZALIA_F0_PIN_CONTROL_CODEC_CS_OVERRIDE_2 0x005b
+#define ixAZF0ENDPOINT2_AZALIA_F0_PIN_CONTROL_CODEC_CS_OVERRIDE_3 0x005c
+#define ixAZF0ENDPOINT2_AZALIA_F0_PIN_CONTROL_CODEC_CS_OVERRIDE_4 0x005d
+#define ixAZF0ENDPOINT2_AZALIA_F0_PIN_CONTROL_CODEC_CS_OVERRIDE_5 0x005e
+#define ixAZF0ENDPOINT2_AZALIA_F0_PIN_CONTROL_CODEC_CS_OVERRIDE_6 0x005f
+#define ixAZF0ENDPOINT2_AZALIA_F0_PIN_CONTROL_CODEC_CS_OVERRIDE_7 0x0060
+#define ixAZF0ENDPOINT2_AZALIA_F0_PIN_CONTROL_CODEC_CS_OVERRIDE_8 0x0061
+#define ixAZF0ENDPOINT2_AZALIA_F0_CODEC_PIN_ASSOCIATION_INFO 0x0062
+#define ixAZF0ENDPOINT2_AZALIA_F0_CODEC_PIN_CONTROL_DIGITAL_OUTPUT_STATUS 0x0063
+#define ixAZF0ENDPOINT2_AZALIA_F0_CODEC_PIN_CONTROL_LPIB_SNAPSHOT_CONTROL 0x0064
+#define ixAZF0ENDPOINT2_AZALIA_F0_CODEC_PIN_CONTROL_LPIB 0x0065
+#define ixAZF0ENDPOINT2_AZALIA_F0_CODEC_PIN_CONTROL_LPIB_TIMER_SNAPSHOT 0x0066
+#define ixAZF0ENDPOINT2_AZALIA_F0_CODEC_PIN_CONTROL_CODING_TYPE 0x0067
+#define ixAZF0ENDPOINT2_AZALIA_F0_CODEC_PIN_CONTROL_FORMAT_CHANGED 0x0068
+#define ixAZF0ENDPOINT2_AZALIA_F0_CODEC_PIN_CONTROL_WIRELESS_DISPLAY_IDENTIFICATION 0x0069
+#define ixAZF0ENDPOINT2_AZALIA_F0_CODEC_PIN_CONTROL_REMOTE_KEEPALIVE 0x006a
+#define ixAZF0ENDPOINT2_AZALIA_F0_AUDIO_ENABLE_STATUS 0x006b
+#define ixAZF0ENDPOINT2_AZALIA_F0_AUDIO_ENABLED_INT_STATUS 0x006c
+#define ixAZF0ENDPOINT2_AZALIA_F0_AUDIO_DISABLED_INT_STATUS 0x006d
+#define ixAZF0ENDPOINT2_AZALIA_F0_AUDIO_FORMAT_CHANGED_INT_STATUS 0x006e
+
+
+// addressBlock: azf0endpoint3_endpointind
+// base address: 0x0
+#define ixAZF0ENDPOINT3_AZALIA_F0_CODEC_CONVERTER_PARAMETER_AUDIO_WIDGET_CAPABILITIES 0x0001
+#define ixAZF0ENDPOINT3_AZALIA_F0_CODEC_CONVERTER_CONTROL_CONVERTER_FORMAT 0x0002
+#define ixAZF0ENDPOINT3_AZALIA_F0_CODEC_CONVERTER_CONTROL_CHANNEL_STREAM_ID 0x0003
+#define ixAZF0ENDPOINT3_AZALIA_F0_CODEC_CONVERTER_CONTROL_DIGITAL_CONVERTER 0x0004
+#define ixAZF0ENDPOINT3_AZALIA_F0_CODEC_CONVERTER_PARAMETER_STREAM_FORMATS 0x0005
+#define ixAZF0ENDPOINT3_AZALIA_F0_CODEC_CONVERTER_PARAMETER_SUPPORTED_SIZE_RATES 0x0006
+#define ixAZF0ENDPOINT3_AZALIA_F0_CODEC_CONVERTER_STRIPE_CONTROL 0x0007
+#define ixAZF0ENDPOINT3_AZALIA_F0_CODEC_CONVERTER_CONTROL_RAMP_RATE 0x0008
+#define ixAZF0ENDPOINT3_AZALIA_F0_CODEC_CONVERTER_CONTROL_GTC_EMBEDDING 0x0009
+#define ixAZF0ENDPOINT3_AZALIA_F0_CODEC_CONVERTER_GTC_COUNTER_DELTA 0x000c
+#define ixAZF0ENDPOINT3_AZALIA_F0_CODEC_CONVERTER_GTC_COUNTER_DELTA_MIN 0x000d
+#define ixAZF0ENDPOINT3_AZALIA_F0_CODEC_CONVERTER_GTC_COUNTER_DELTA_MAX 0x000e
+#define ixAZF0ENDPOINT3_AZALIA_F0_CODEC_PIN_PARAMETER_AUDIO_WIDGET_CAPABILITIES 0x0020
+#define ixAZF0ENDPOINT3_AZALIA_F0_CODEC_PIN_PARAMETER_CAPABILITIES 0x0021
+#define ixAZF0ENDPOINT3_AZALIA_F0_CODEC_PIN_CONTROL_UNSOLICITED_RESPONSE 0x0022
+#define ixAZF0ENDPOINT3_AZALIA_F0_CODEC_PIN_CONTROL_RESPONSE_PIN_SENSE 0x0023
+#define ixAZF0ENDPOINT3_AZALIA_F0_CODEC_PIN_CONTROL_WIDGET_CONTROL 0x0024
+#define ixAZF0ENDPOINT3_AZALIA_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER 0x0025
+#define ixAZF0ENDPOINT3_AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR0 0x0028
+#define ixAZF0ENDPOINT3_AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR1 0x0029
+#define ixAZF0ENDPOINT3_AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR2 0x002a
+#define ixAZF0ENDPOINT3_AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR3 0x002b
+#define ixAZF0ENDPOINT3_AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR4 0x002c
+#define ixAZF0ENDPOINT3_AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR5 0x002d
+#define ixAZF0ENDPOINT3_AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR6 0x002e
+#define ixAZF0ENDPOINT3_AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR7 0x002f
+#define ixAZF0ENDPOINT3_AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR8 0x0030
+#define ixAZF0ENDPOINT3_AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR9 0x0031
+#define ixAZF0ENDPOINT3_AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR10 0x0032
+#define ixAZF0ENDPOINT3_AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR11 0x0033
+#define ixAZF0ENDPOINT3_AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR12 0x0034
+#define ixAZF0ENDPOINT3_AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR13 0x0035
+#define ixAZF0ENDPOINT3_AZALIA_F0_CODEC_PIN_CONTROL_MULTICHANNEL_ENABLE 0x0036
+#define ixAZF0ENDPOINT3_AZALIA_F0_CODEC_PIN_CONTROL_RESPONSE_LIPSYNC 0x0037
+#define ixAZF0ENDPOINT3_AZALIA_F0_CODEC_PIN_CONTROL_RESPONSE_HBR 0x0038
+#define ixAZF0ENDPOINT3_AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO0 0x003a
+#define ixAZF0ENDPOINT3_AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO1 0x003b
+#define ixAZF0ENDPOINT3_AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO2 0x003c
+#define ixAZF0ENDPOINT3_AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO3 0x003d
+#define ixAZF0ENDPOINT3_AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO4 0x003e
+#define ixAZF0ENDPOINT3_AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO5 0x003f
+#define ixAZF0ENDPOINT3_AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO6 0x0040
+#define ixAZF0ENDPOINT3_AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO7 0x0041
+#define ixAZF0ENDPOINT3_AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO8 0x0042
+#define ixAZF0ENDPOINT3_AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL 0x0054
+#define ixAZF0ENDPOINT3_AZALIA_F0_CODEC_PIN_CONTROL_UNSOLICITED_RESPONSE_FORCE 0x0055
+#define ixAZF0ENDPOINT3_AZALIA_F0_CODEC_PIN_CONTROL_RESPONSE_CONFIGURATION_DEFAULT 0x0056
+#define ixAZF0ENDPOINT3_AZALIA_F0_CODEC_PIN_CONTROL_MULTICHANNEL_ENABLE2 0x0057
+#define ixAZF0ENDPOINT3_AZALIA_F0_CODEC_PIN_CONTROL_MULTICHANNEL_MODE 0x0058
+#define ixAZF0ENDPOINT3_AZALIA_F0_PIN_CONTROL_CODEC_CS_OVERRIDE_0 0x0059
+#define ixAZF0ENDPOINT3_AZALIA_F0_PIN_CONTROL_CODEC_CS_OVERRIDE_1 0x005a
+#define ixAZF0ENDPOINT3_AZALIA_F0_PIN_CONTROL_CODEC_CS_OVERRIDE_2 0x005b
+#define ixAZF0ENDPOINT3_AZALIA_F0_PIN_CONTROL_CODEC_CS_OVERRIDE_3 0x005c
+#define ixAZF0ENDPOINT3_AZALIA_F0_PIN_CONTROL_CODEC_CS_OVERRIDE_4 0x005d
+#define ixAZF0ENDPOINT3_AZALIA_F0_PIN_CONTROL_CODEC_CS_OVERRIDE_5 0x005e
+#define ixAZF0ENDPOINT3_AZALIA_F0_PIN_CONTROL_CODEC_CS_OVERRIDE_6 0x005f
+#define ixAZF0ENDPOINT3_AZALIA_F0_PIN_CONTROL_CODEC_CS_OVERRIDE_7 0x0060
+#define ixAZF0ENDPOINT3_AZALIA_F0_PIN_CONTROL_CODEC_CS_OVERRIDE_8 0x0061
+#define ixAZF0ENDPOINT3_AZALIA_F0_CODEC_PIN_ASSOCIATION_INFO 0x0062
+#define ixAZF0ENDPOINT3_AZALIA_F0_CODEC_PIN_CONTROL_DIGITAL_OUTPUT_STATUS 0x0063
+#define ixAZF0ENDPOINT3_AZALIA_F0_CODEC_PIN_CONTROL_LPIB_SNAPSHOT_CONTROL 0x0064
+#define ixAZF0ENDPOINT3_AZALIA_F0_CODEC_PIN_CONTROL_LPIB 0x0065
+#define ixAZF0ENDPOINT3_AZALIA_F0_CODEC_PIN_CONTROL_LPIB_TIMER_SNAPSHOT 0x0066
+#define ixAZF0ENDPOINT3_AZALIA_F0_CODEC_PIN_CONTROL_CODING_TYPE 0x0067
+#define ixAZF0ENDPOINT3_AZALIA_F0_CODEC_PIN_CONTROL_FORMAT_CHANGED 0x0068
+#define ixAZF0ENDPOINT3_AZALIA_F0_CODEC_PIN_CONTROL_WIRELESS_DISPLAY_IDENTIFICATION 0x0069
+#define ixAZF0ENDPOINT3_AZALIA_F0_CODEC_PIN_CONTROL_REMOTE_KEEPALIVE 0x006a
+#define ixAZF0ENDPOINT3_AZALIA_F0_AUDIO_ENABLE_STATUS 0x006b
+#define ixAZF0ENDPOINT3_AZALIA_F0_AUDIO_ENABLED_INT_STATUS 0x006c
+#define ixAZF0ENDPOINT3_AZALIA_F0_AUDIO_DISABLED_INT_STATUS 0x006d
+#define ixAZF0ENDPOINT3_AZALIA_F0_AUDIO_FORMAT_CHANGED_INT_STATUS 0x006e
+
+
+// addressBlock: azf0endpoint4_endpointind
+// base address: 0x0
+#define ixAZF0ENDPOINT4_AZALIA_F0_CODEC_CONVERTER_PARAMETER_AUDIO_WIDGET_CAPABILITIES 0x0001
+#define ixAZF0ENDPOINT4_AZALIA_F0_CODEC_CONVERTER_CONTROL_CONVERTER_FORMAT 0x0002
+#define ixAZF0ENDPOINT4_AZALIA_F0_CODEC_CONVERTER_CONTROL_CHANNEL_STREAM_ID 0x0003
+#define ixAZF0ENDPOINT4_AZALIA_F0_CODEC_CONVERTER_CONTROL_DIGITAL_CONVERTER 0x0004
+#define ixAZF0ENDPOINT4_AZALIA_F0_CODEC_CONVERTER_PARAMETER_STREAM_FORMATS 0x0005
+#define ixAZF0ENDPOINT4_AZALIA_F0_CODEC_CONVERTER_PARAMETER_SUPPORTED_SIZE_RATES 0x0006
+#define ixAZF0ENDPOINT4_AZALIA_F0_CODEC_CONVERTER_STRIPE_CONTROL 0x0007
+#define ixAZF0ENDPOINT4_AZALIA_F0_CODEC_CONVERTER_CONTROL_RAMP_RATE 0x0008
+#define ixAZF0ENDPOINT4_AZALIA_F0_CODEC_CONVERTER_CONTROL_GTC_EMBEDDING 0x0009
+#define ixAZF0ENDPOINT4_AZALIA_F0_CODEC_CONVERTER_GTC_COUNTER_DELTA 0x000c
+#define ixAZF0ENDPOINT4_AZALIA_F0_CODEC_CONVERTER_GTC_COUNTER_DELTA_MIN 0x000d
+#define ixAZF0ENDPOINT4_AZALIA_F0_CODEC_CONVERTER_GTC_COUNTER_DELTA_MAX 0x000e
+#define ixAZF0ENDPOINT4_AZALIA_F0_CODEC_PIN_PARAMETER_AUDIO_WIDGET_CAPABILITIES 0x0020
+#define ixAZF0ENDPOINT4_AZALIA_F0_CODEC_PIN_PARAMETER_CAPABILITIES 0x0021
+#define ixAZF0ENDPOINT4_AZALIA_F0_CODEC_PIN_CONTROL_UNSOLICITED_RESPONSE 0x0022
+#define ixAZF0ENDPOINT4_AZALIA_F0_CODEC_PIN_CONTROL_RESPONSE_PIN_SENSE 0x0023
+#define ixAZF0ENDPOINT4_AZALIA_F0_CODEC_PIN_CONTROL_WIDGET_CONTROL 0x0024
+#define ixAZF0ENDPOINT4_AZALIA_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER 0x0025
+#define ixAZF0ENDPOINT4_AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR0 0x0028
+#define ixAZF0ENDPOINT4_AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR1 0x0029
+#define ixAZF0ENDPOINT4_AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR2 0x002a
+#define ixAZF0ENDPOINT4_AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR3 0x002b
+#define ixAZF0ENDPOINT4_AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR4 0x002c
+#define ixAZF0ENDPOINT4_AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR5 0x002d
+#define ixAZF0ENDPOINT4_AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR6 0x002e
+#define ixAZF0ENDPOINT4_AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR7 0x002f
+#define ixAZF0ENDPOINT4_AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR8 0x0030
+#define ixAZF0ENDPOINT4_AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR9 0x0031
+#define ixAZF0ENDPOINT4_AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR10 0x0032
+#define ixAZF0ENDPOINT4_AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR11 0x0033
+#define ixAZF0ENDPOINT4_AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR12 0x0034
+#define ixAZF0ENDPOINT4_AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR13 0x0035
+#define ixAZF0ENDPOINT4_AZALIA_F0_CODEC_PIN_CONTROL_MULTICHANNEL_ENABLE 0x0036
+#define ixAZF0ENDPOINT4_AZALIA_F0_CODEC_PIN_CONTROL_RESPONSE_LIPSYNC 0x0037
+#define ixAZF0ENDPOINT4_AZALIA_F0_CODEC_PIN_CONTROL_RESPONSE_HBR 0x0038
+#define ixAZF0ENDPOINT4_AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO0 0x003a
+#define ixAZF0ENDPOINT4_AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO1 0x003b
+#define ixAZF0ENDPOINT4_AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO2 0x003c
+#define ixAZF0ENDPOINT4_AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO3 0x003d
+#define ixAZF0ENDPOINT4_AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO4 0x003e
+#define ixAZF0ENDPOINT4_AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO5 0x003f
+#define ixAZF0ENDPOINT4_AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO6 0x0040
+#define ixAZF0ENDPOINT4_AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO7 0x0041
+#define ixAZF0ENDPOINT4_AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO8 0x0042
+#define ixAZF0ENDPOINT4_AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL 0x0054
+#define ixAZF0ENDPOINT4_AZALIA_F0_CODEC_PIN_CONTROL_UNSOLICITED_RESPONSE_FORCE 0x0055
+#define ixAZF0ENDPOINT4_AZALIA_F0_CODEC_PIN_CONTROL_RESPONSE_CONFIGURATION_DEFAULT 0x0056
+#define ixAZF0ENDPOINT4_AZALIA_F0_CODEC_PIN_CONTROL_MULTICHANNEL_ENABLE2 0x0057
+#define ixAZF0ENDPOINT4_AZALIA_F0_CODEC_PIN_CONTROL_MULTICHANNEL_MODE 0x0058
+#define ixAZF0ENDPOINT4_AZALIA_F0_PIN_CONTROL_CODEC_CS_OVERRIDE_0 0x0059
+#define ixAZF0ENDPOINT4_AZALIA_F0_PIN_CONTROL_CODEC_CS_OVERRIDE_1 0x005a
+#define ixAZF0ENDPOINT4_AZALIA_F0_PIN_CONTROL_CODEC_CS_OVERRIDE_2 0x005b
+#define ixAZF0ENDPOINT4_AZALIA_F0_PIN_CONTROL_CODEC_CS_OVERRIDE_3 0x005c
+#define ixAZF0ENDPOINT4_AZALIA_F0_PIN_CONTROL_CODEC_CS_OVERRIDE_4 0x005d
+#define ixAZF0ENDPOINT4_AZALIA_F0_PIN_CONTROL_CODEC_CS_OVERRIDE_5 0x005e
+#define ixAZF0ENDPOINT4_AZALIA_F0_PIN_CONTROL_CODEC_CS_OVERRIDE_6 0x005f
+#define ixAZF0ENDPOINT4_AZALIA_F0_PIN_CONTROL_CODEC_CS_OVERRIDE_7 0x0060
+#define ixAZF0ENDPOINT4_AZALIA_F0_PIN_CONTROL_CODEC_CS_OVERRIDE_8 0x0061
+#define ixAZF0ENDPOINT4_AZALIA_F0_CODEC_PIN_ASSOCIATION_INFO 0x0062
+#define ixAZF0ENDPOINT4_AZALIA_F0_CODEC_PIN_CONTROL_DIGITAL_OUTPUT_STATUS 0x0063
+#define ixAZF0ENDPOINT4_AZALIA_F0_CODEC_PIN_CONTROL_LPIB_SNAPSHOT_CONTROL 0x0064
+#define ixAZF0ENDPOINT4_AZALIA_F0_CODEC_PIN_CONTROL_LPIB 0x0065
+#define ixAZF0ENDPOINT4_AZALIA_F0_CODEC_PIN_CONTROL_LPIB_TIMER_SNAPSHOT 0x0066
+#define ixAZF0ENDPOINT4_AZALIA_F0_CODEC_PIN_CONTROL_CODING_TYPE 0x0067
+#define ixAZF0ENDPOINT4_AZALIA_F0_CODEC_PIN_CONTROL_FORMAT_CHANGED 0x0068
+#define ixAZF0ENDPOINT4_AZALIA_F0_CODEC_PIN_CONTROL_WIRELESS_DISPLAY_IDENTIFICATION 0x0069
+#define ixAZF0ENDPOINT4_AZALIA_F0_CODEC_PIN_CONTROL_REMOTE_KEEPALIVE 0x006a
+#define ixAZF0ENDPOINT4_AZALIA_F0_AUDIO_ENABLE_STATUS 0x006b
+#define ixAZF0ENDPOINT4_AZALIA_F0_AUDIO_ENABLED_INT_STATUS 0x006c
+#define ixAZF0ENDPOINT4_AZALIA_F0_AUDIO_DISABLED_INT_STATUS 0x006d
+#define ixAZF0ENDPOINT4_AZALIA_F0_AUDIO_FORMAT_CHANGED_INT_STATUS 0x006e
+
+
+// addressBlock: azf0endpoint5_endpointind
+// base address: 0x0
+#define ixAZF0ENDPOINT5_AZALIA_F0_CODEC_CONVERTER_PARAMETER_AUDIO_WIDGET_CAPABILITIES 0x0001
+#define ixAZF0ENDPOINT5_AZALIA_F0_CODEC_CONVERTER_CONTROL_CONVERTER_FORMAT 0x0002
+#define ixAZF0ENDPOINT5_AZALIA_F0_CODEC_CONVERTER_CONTROL_CHANNEL_STREAM_ID 0x0003
+#define ixAZF0ENDPOINT5_AZALIA_F0_CODEC_CONVERTER_CONTROL_DIGITAL_CONVERTER 0x0004
+#define ixAZF0ENDPOINT5_AZALIA_F0_CODEC_CONVERTER_PARAMETER_STREAM_FORMATS 0x0005
+#define ixAZF0ENDPOINT5_AZALIA_F0_CODEC_CONVERTER_PARAMETER_SUPPORTED_SIZE_RATES 0x0006
+#define ixAZF0ENDPOINT5_AZALIA_F0_CODEC_CONVERTER_STRIPE_CONTROL 0x0007
+#define ixAZF0ENDPOINT5_AZALIA_F0_CODEC_CONVERTER_CONTROL_RAMP_RATE 0x0008
+#define ixAZF0ENDPOINT5_AZALIA_F0_CODEC_CONVERTER_CONTROL_GTC_EMBEDDING 0x0009
+#define ixAZF0ENDPOINT5_AZALIA_F0_CODEC_CONVERTER_GTC_COUNTER_DELTA 0x000c
+#define ixAZF0ENDPOINT5_AZALIA_F0_CODEC_CONVERTER_GTC_COUNTER_DELTA_MIN 0x000d
+#define ixAZF0ENDPOINT5_AZALIA_F0_CODEC_CONVERTER_GTC_COUNTER_DELTA_MAX 0x000e
+#define ixAZF0ENDPOINT5_AZALIA_F0_CODEC_PIN_PARAMETER_AUDIO_WIDGET_CAPABILITIES 0x0020
+#define ixAZF0ENDPOINT5_AZALIA_F0_CODEC_PIN_PARAMETER_CAPABILITIES 0x0021
+#define ixAZF0ENDPOINT5_AZALIA_F0_CODEC_PIN_CONTROL_UNSOLICITED_RESPONSE 0x0022
+#define ixAZF0ENDPOINT5_AZALIA_F0_CODEC_PIN_CONTROL_RESPONSE_PIN_SENSE 0x0023
+#define ixAZF0ENDPOINT5_AZALIA_F0_CODEC_PIN_CONTROL_WIDGET_CONTROL 0x0024
+#define ixAZF0ENDPOINT5_AZALIA_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER 0x0025
+#define ixAZF0ENDPOINT5_AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR0 0x0028
+#define ixAZF0ENDPOINT5_AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR1 0x0029
+#define ixAZF0ENDPOINT5_AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR2 0x002a
+#define ixAZF0ENDPOINT5_AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR3 0x002b
+#define ixAZF0ENDPOINT5_AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR4 0x002c
+#define ixAZF0ENDPOINT5_AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR5 0x002d
+#define ixAZF0ENDPOINT5_AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR6 0x002e
+#define ixAZF0ENDPOINT5_AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR7 0x002f
+#define ixAZF0ENDPOINT5_AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR8 0x0030
+#define ixAZF0ENDPOINT5_AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR9 0x0031
+#define ixAZF0ENDPOINT5_AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR10 0x0032
+#define ixAZF0ENDPOINT5_AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR11 0x0033
+#define ixAZF0ENDPOINT5_AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR12 0x0034
+#define ixAZF0ENDPOINT5_AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR13 0x0035
+#define ixAZF0ENDPOINT5_AZALIA_F0_CODEC_PIN_CONTROL_MULTICHANNEL_ENABLE 0x0036
+#define ixAZF0ENDPOINT5_AZALIA_F0_CODEC_PIN_CONTROL_RESPONSE_LIPSYNC 0x0037
+#define ixAZF0ENDPOINT5_AZALIA_F0_CODEC_PIN_CONTROL_RESPONSE_HBR 0x0038
+#define ixAZF0ENDPOINT5_AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO0 0x003a
+#define ixAZF0ENDPOINT5_AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO1 0x003b
+#define ixAZF0ENDPOINT5_AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO2 0x003c
+#define ixAZF0ENDPOINT5_AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO3 0x003d
+#define ixAZF0ENDPOINT5_AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO4 0x003e
+#define ixAZF0ENDPOINT5_AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO5 0x003f
+#define ixAZF0ENDPOINT5_AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO6 0x0040
+#define ixAZF0ENDPOINT5_AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO7 0x0041
+#define ixAZF0ENDPOINT5_AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO8 0x0042
+#define ixAZF0ENDPOINT5_AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL 0x0054
+#define ixAZF0ENDPOINT5_AZALIA_F0_CODEC_PIN_CONTROL_UNSOLICITED_RESPONSE_FORCE 0x0055
+#define ixAZF0ENDPOINT5_AZALIA_F0_CODEC_PIN_CONTROL_RESPONSE_CONFIGURATION_DEFAULT 0x0056
+#define ixAZF0ENDPOINT5_AZALIA_F0_CODEC_PIN_CONTROL_MULTICHANNEL_ENABLE2 0x0057
+#define ixAZF0ENDPOINT5_AZALIA_F0_CODEC_PIN_CONTROL_MULTICHANNEL_MODE 0x0058
+#define ixAZF0ENDPOINT5_AZALIA_F0_PIN_CONTROL_CODEC_CS_OVERRIDE_0 0x0059
+#define ixAZF0ENDPOINT5_AZALIA_F0_PIN_CONTROL_CODEC_CS_OVERRIDE_1 0x005a
+#define ixAZF0ENDPOINT5_AZALIA_F0_PIN_CONTROL_CODEC_CS_OVERRIDE_2 0x005b
+#define ixAZF0ENDPOINT5_AZALIA_F0_PIN_CONTROL_CODEC_CS_OVERRIDE_3 0x005c
+#define ixAZF0ENDPOINT5_AZALIA_F0_PIN_CONTROL_CODEC_CS_OVERRIDE_4 0x005d
+#define ixAZF0ENDPOINT5_AZALIA_F0_PIN_CONTROL_CODEC_CS_OVERRIDE_5 0x005e
+#define ixAZF0ENDPOINT5_AZALIA_F0_PIN_CONTROL_CODEC_CS_OVERRIDE_6 0x005f
+#define ixAZF0ENDPOINT5_AZALIA_F0_PIN_CONTROL_CODEC_CS_OVERRIDE_7 0x0060
+#define ixAZF0ENDPOINT5_AZALIA_F0_PIN_CONTROL_CODEC_CS_OVERRIDE_8 0x0061
+#define ixAZF0ENDPOINT5_AZALIA_F0_CODEC_PIN_ASSOCIATION_INFO 0x0062
+#define ixAZF0ENDPOINT5_AZALIA_F0_CODEC_PIN_CONTROL_DIGITAL_OUTPUT_STATUS 0x0063
+#define ixAZF0ENDPOINT5_AZALIA_F0_CODEC_PIN_CONTROL_LPIB_SNAPSHOT_CONTROL 0x0064
+#define ixAZF0ENDPOINT5_AZALIA_F0_CODEC_PIN_CONTROL_LPIB 0x0065
+#define ixAZF0ENDPOINT5_AZALIA_F0_CODEC_PIN_CONTROL_LPIB_TIMER_SNAPSHOT 0x0066
+#define ixAZF0ENDPOINT5_AZALIA_F0_CODEC_PIN_CONTROL_CODING_TYPE 0x0067
+#define ixAZF0ENDPOINT5_AZALIA_F0_CODEC_PIN_CONTROL_FORMAT_CHANGED 0x0068
+#define ixAZF0ENDPOINT5_AZALIA_F0_CODEC_PIN_CONTROL_WIRELESS_DISPLAY_IDENTIFICATION 0x0069
+#define ixAZF0ENDPOINT5_AZALIA_F0_CODEC_PIN_CONTROL_REMOTE_KEEPALIVE 0x006a
+#define ixAZF0ENDPOINT5_AZALIA_F0_AUDIO_ENABLE_STATUS 0x006b
+#define ixAZF0ENDPOINT5_AZALIA_F0_AUDIO_ENABLED_INT_STATUS 0x006c
+#define ixAZF0ENDPOINT5_AZALIA_F0_AUDIO_DISABLED_INT_STATUS 0x006d
+#define ixAZF0ENDPOINT5_AZALIA_F0_AUDIO_FORMAT_CHANGED_INT_STATUS 0x006e
+
+
+// addressBlock: azf0endpoint6_endpointind
+// base address: 0x0
+#define ixAZF0ENDPOINT6_AZALIA_F0_CODEC_CONVERTER_PARAMETER_AUDIO_WIDGET_CAPABILITIES 0x0001
+#define ixAZF0ENDPOINT6_AZALIA_F0_CODEC_CONVERTER_CONTROL_CONVERTER_FORMAT 0x0002
+#define ixAZF0ENDPOINT6_AZALIA_F0_CODEC_CONVERTER_CONTROL_CHANNEL_STREAM_ID 0x0003
+#define ixAZF0ENDPOINT6_AZALIA_F0_CODEC_CONVERTER_CONTROL_DIGITAL_CONVERTER 0x0004
+#define ixAZF0ENDPOINT6_AZALIA_F0_CODEC_CONVERTER_PARAMETER_STREAM_FORMATS 0x0005
+#define ixAZF0ENDPOINT6_AZALIA_F0_CODEC_CONVERTER_PARAMETER_SUPPORTED_SIZE_RATES 0x0006
+#define ixAZF0ENDPOINT6_AZALIA_F0_CODEC_CONVERTER_STRIPE_CONTROL 0x0007
+#define ixAZF0ENDPOINT6_AZALIA_F0_CODEC_CONVERTER_CONTROL_RAMP_RATE 0x0008
+#define ixAZF0ENDPOINT6_AZALIA_F0_CODEC_CONVERTER_CONTROL_GTC_EMBEDDING 0x0009
+#define ixAZF0ENDPOINT6_AZALIA_F0_CODEC_CONVERTER_GTC_COUNTER_DELTA 0x000c
+#define ixAZF0ENDPOINT6_AZALIA_F0_CODEC_CONVERTER_GTC_COUNTER_DELTA_MIN 0x000d
+#define ixAZF0ENDPOINT6_AZALIA_F0_CODEC_CONVERTER_GTC_COUNTER_DELTA_MAX 0x000e
+#define ixAZF0ENDPOINT6_AZALIA_F0_CODEC_PIN_PARAMETER_AUDIO_WIDGET_CAPABILITIES 0x0020
+#define ixAZF0ENDPOINT6_AZALIA_F0_CODEC_PIN_PARAMETER_CAPABILITIES 0x0021
+#define ixAZF0ENDPOINT6_AZALIA_F0_CODEC_PIN_CONTROL_UNSOLICITED_RESPONSE 0x0022
+#define ixAZF0ENDPOINT6_AZALIA_F0_CODEC_PIN_CONTROL_RESPONSE_PIN_SENSE 0x0023
+#define ixAZF0ENDPOINT6_AZALIA_F0_CODEC_PIN_CONTROL_WIDGET_CONTROL 0x0024
+#define ixAZF0ENDPOINT6_AZALIA_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER 0x0025
+#define ixAZF0ENDPOINT6_AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR0 0x0028
+#define ixAZF0ENDPOINT6_AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR1 0x0029
+#define ixAZF0ENDPOINT6_AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR2 0x002a
+#define ixAZF0ENDPOINT6_AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR3 0x002b
+#define ixAZF0ENDPOINT6_AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR4 0x002c
+#define ixAZF0ENDPOINT6_AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR5 0x002d
+#define ixAZF0ENDPOINT6_AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR6 0x002e
+#define ixAZF0ENDPOINT6_AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR7 0x002f
+#define ixAZF0ENDPOINT6_AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR8 0x0030
+#define ixAZF0ENDPOINT6_AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR9 0x0031
+#define ixAZF0ENDPOINT6_AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR10 0x0032
+#define ixAZF0ENDPOINT6_AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR11 0x0033
+#define ixAZF0ENDPOINT6_AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR12 0x0034
+#define ixAZF0ENDPOINT6_AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR13 0x0035
+#define ixAZF0ENDPOINT6_AZALIA_F0_CODEC_PIN_CONTROL_MULTICHANNEL_ENABLE 0x0036
+#define ixAZF0ENDPOINT6_AZALIA_F0_CODEC_PIN_CONTROL_RESPONSE_LIPSYNC 0x0037
+#define ixAZF0ENDPOINT6_AZALIA_F0_CODEC_PIN_CONTROL_RESPONSE_HBR 0x0038
+#define ixAZF0ENDPOINT6_AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO0 0x003a
+#define ixAZF0ENDPOINT6_AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO1 0x003b
+#define ixAZF0ENDPOINT6_AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO2 0x003c
+#define ixAZF0ENDPOINT6_AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO3 0x003d
+#define ixAZF0ENDPOINT6_AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO4 0x003e
+#define ixAZF0ENDPOINT6_AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO5 0x003f
+#define ixAZF0ENDPOINT6_AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO6 0x0040
+#define ixAZF0ENDPOINT6_AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO7 0x0041
+#define ixAZF0ENDPOINT6_AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO8 0x0042
+#define ixAZF0ENDPOINT6_AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL 0x0054
+#define ixAZF0ENDPOINT6_AZALIA_F0_CODEC_PIN_CONTROL_UNSOLICITED_RESPONSE_FORCE 0x0055
+#define ixAZF0ENDPOINT6_AZALIA_F0_CODEC_PIN_CONTROL_RESPONSE_CONFIGURATION_DEFAULT 0x0056
+#define ixAZF0ENDPOINT6_AZALIA_F0_CODEC_PIN_CONTROL_MULTICHANNEL_ENABLE2 0x0057
+#define ixAZF0ENDPOINT6_AZALIA_F0_CODEC_PIN_CONTROL_MULTICHANNEL_MODE 0x0058
+#define ixAZF0ENDPOINT6_AZALIA_F0_PIN_CONTROL_CODEC_CS_OVERRIDE_0 0x0059
+#define ixAZF0ENDPOINT6_AZALIA_F0_PIN_CONTROL_CODEC_CS_OVERRIDE_1 0x005a
+#define ixAZF0ENDPOINT6_AZALIA_F0_PIN_CONTROL_CODEC_CS_OVERRIDE_2 0x005b
+#define ixAZF0ENDPOINT6_AZALIA_F0_PIN_CONTROL_CODEC_CS_OVERRIDE_3 0x005c
+#define ixAZF0ENDPOINT6_AZALIA_F0_PIN_CONTROL_CODEC_CS_OVERRIDE_4 0x005d
+#define ixAZF0ENDPOINT6_AZALIA_F0_PIN_CONTROL_CODEC_CS_OVERRIDE_5 0x005e
+#define ixAZF0ENDPOINT6_AZALIA_F0_PIN_CONTROL_CODEC_CS_OVERRIDE_6 0x005f
+#define ixAZF0ENDPOINT6_AZALIA_F0_PIN_CONTROL_CODEC_CS_OVERRIDE_7 0x0060
+#define ixAZF0ENDPOINT6_AZALIA_F0_PIN_CONTROL_CODEC_CS_OVERRIDE_8 0x0061
+#define ixAZF0ENDPOINT6_AZALIA_F0_CODEC_PIN_ASSOCIATION_INFO 0x0062
+#define ixAZF0ENDPOINT6_AZALIA_F0_CODEC_PIN_CONTROL_DIGITAL_OUTPUT_STATUS 0x0063
+#define ixAZF0ENDPOINT6_AZALIA_F0_CODEC_PIN_CONTROL_LPIB_SNAPSHOT_CONTROL 0x0064
+#define ixAZF0ENDPOINT6_AZALIA_F0_CODEC_PIN_CONTROL_LPIB 0x0065
+#define ixAZF0ENDPOINT6_AZALIA_F0_CODEC_PIN_CONTROL_LPIB_TIMER_SNAPSHOT 0x0066
+#define ixAZF0ENDPOINT6_AZALIA_F0_CODEC_PIN_CONTROL_CODING_TYPE 0x0067
+#define ixAZF0ENDPOINT6_AZALIA_F0_CODEC_PIN_CONTROL_FORMAT_CHANGED 0x0068
+#define ixAZF0ENDPOINT6_AZALIA_F0_CODEC_PIN_CONTROL_WIRELESS_DISPLAY_IDENTIFICATION 0x0069
+#define ixAZF0ENDPOINT6_AZALIA_F0_CODEC_PIN_CONTROL_REMOTE_KEEPALIVE 0x006a
+#define ixAZF0ENDPOINT6_AZALIA_F0_AUDIO_ENABLE_STATUS 0x006b
+#define ixAZF0ENDPOINT6_AZALIA_F0_AUDIO_ENABLED_INT_STATUS 0x006c
+#define ixAZF0ENDPOINT6_AZALIA_F0_AUDIO_DISABLED_INT_STATUS 0x006d
+#define ixAZF0ENDPOINT6_AZALIA_F0_AUDIO_FORMAT_CHANGED_INT_STATUS 0x006e
+
+
+// addressBlock: azf0endpoint7_endpointind
+// base address: 0x0
+#define ixAZF0ENDPOINT7_AZALIA_F0_CODEC_CONVERTER_PARAMETER_AUDIO_WIDGET_CAPABILITIES 0x0001
+#define ixAZF0ENDPOINT7_AZALIA_F0_CODEC_CONVERTER_CONTROL_CONVERTER_FORMAT 0x0002
+#define ixAZF0ENDPOINT7_AZALIA_F0_CODEC_CONVERTER_CONTROL_CHANNEL_STREAM_ID 0x0003
+#define ixAZF0ENDPOINT7_AZALIA_F0_CODEC_CONVERTER_CONTROL_DIGITAL_CONVERTER 0x0004
+#define ixAZF0ENDPOINT7_AZALIA_F0_CODEC_CONVERTER_PARAMETER_STREAM_FORMATS 0x0005
+#define ixAZF0ENDPOINT7_AZALIA_F0_CODEC_CONVERTER_PARAMETER_SUPPORTED_SIZE_RATES 0x0006
+#define ixAZF0ENDPOINT7_AZALIA_F0_CODEC_CONVERTER_STRIPE_CONTROL 0x0007
+#define ixAZF0ENDPOINT7_AZALIA_F0_CODEC_CONVERTER_CONTROL_RAMP_RATE 0x0008
+#define ixAZF0ENDPOINT7_AZALIA_F0_CODEC_CONVERTER_CONTROL_GTC_EMBEDDING 0x0009
+#define ixAZF0ENDPOINT7_AZALIA_F0_CODEC_CONVERTER_GTC_COUNTER_DELTA 0x000c
+#define ixAZF0ENDPOINT7_AZALIA_F0_CODEC_CONVERTER_GTC_COUNTER_DELTA_MIN 0x000d
+#define ixAZF0ENDPOINT7_AZALIA_F0_CODEC_CONVERTER_GTC_COUNTER_DELTA_MAX 0x000e
+#define ixAZF0ENDPOINT7_AZALIA_F0_CODEC_PIN_PARAMETER_AUDIO_WIDGET_CAPABILITIES 0x0020
+#define ixAZF0ENDPOINT7_AZALIA_F0_CODEC_PIN_PARAMETER_CAPABILITIES 0x0021
+#define ixAZF0ENDPOINT7_AZALIA_F0_CODEC_PIN_CONTROL_UNSOLICITED_RESPONSE 0x0022
+#define ixAZF0ENDPOINT7_AZALIA_F0_CODEC_PIN_CONTROL_RESPONSE_PIN_SENSE 0x0023
+#define ixAZF0ENDPOINT7_AZALIA_F0_CODEC_PIN_CONTROL_WIDGET_CONTROL 0x0024
+#define ixAZF0ENDPOINT7_AZALIA_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER 0x0025
+#define ixAZF0ENDPOINT7_AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR0 0x0028
+#define ixAZF0ENDPOINT7_AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR1 0x0029
+#define ixAZF0ENDPOINT7_AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR2 0x002a
+#define ixAZF0ENDPOINT7_AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR3 0x002b
+#define ixAZF0ENDPOINT7_AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR4 0x002c
+#define ixAZF0ENDPOINT7_AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR5 0x002d
+#define ixAZF0ENDPOINT7_AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR6 0x002e
+#define ixAZF0ENDPOINT7_AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR7 0x002f
+#define ixAZF0ENDPOINT7_AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR8 0x0030
+#define ixAZF0ENDPOINT7_AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR9 0x0031
+#define ixAZF0ENDPOINT7_AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR10 0x0032
+#define ixAZF0ENDPOINT7_AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR11 0x0033
+#define ixAZF0ENDPOINT7_AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR12 0x0034
+#define ixAZF0ENDPOINT7_AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR13 0x0035
+#define ixAZF0ENDPOINT7_AZALIA_F0_CODEC_PIN_CONTROL_MULTICHANNEL_ENABLE 0x0036
+#define ixAZF0ENDPOINT7_AZALIA_F0_CODEC_PIN_CONTROL_RESPONSE_LIPSYNC 0x0037
+#define ixAZF0ENDPOINT7_AZALIA_F0_CODEC_PIN_CONTROL_RESPONSE_HBR 0x0038
+#define ixAZF0ENDPOINT7_AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO0 0x003a
+#define ixAZF0ENDPOINT7_AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO1 0x003b
+#define ixAZF0ENDPOINT7_AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO2 0x003c
+#define ixAZF0ENDPOINT7_AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO3 0x003d
+#define ixAZF0ENDPOINT7_AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO4 0x003e
+#define ixAZF0ENDPOINT7_AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO5 0x003f
+#define ixAZF0ENDPOINT7_AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO6 0x0040
+#define ixAZF0ENDPOINT7_AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO7 0x0041
+#define ixAZF0ENDPOINT7_AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO8 0x0042
+#define ixAZF0ENDPOINT7_AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL 0x0054
+#define ixAZF0ENDPOINT7_AZALIA_F0_CODEC_PIN_CONTROL_UNSOLICITED_RESPONSE_FORCE 0x0055
+#define ixAZF0ENDPOINT7_AZALIA_F0_CODEC_PIN_CONTROL_RESPONSE_CONFIGURATION_DEFAULT 0x0056
+#define ixAZF0ENDPOINT7_AZALIA_F0_CODEC_PIN_CONTROL_MULTICHANNEL_ENABLE2 0x0057
+#define ixAZF0ENDPOINT7_AZALIA_F0_CODEC_PIN_CONTROL_MULTICHANNEL_MODE 0x0058
+#define ixAZF0ENDPOINT7_AZALIA_F0_PIN_CONTROL_CODEC_CS_OVERRIDE_0 0x0059
+#define ixAZF0ENDPOINT7_AZALIA_F0_PIN_CONTROL_CODEC_CS_OVERRIDE_1 0x005a
+#define ixAZF0ENDPOINT7_AZALIA_F0_PIN_CONTROL_CODEC_CS_OVERRIDE_2 0x005b
+#define ixAZF0ENDPOINT7_AZALIA_F0_PIN_CONTROL_CODEC_CS_OVERRIDE_3 0x005c
+#define ixAZF0ENDPOINT7_AZALIA_F0_PIN_CONTROL_CODEC_CS_OVERRIDE_4 0x005d
+#define ixAZF0ENDPOINT7_AZALIA_F0_PIN_CONTROL_CODEC_CS_OVERRIDE_5 0x005e
+#define ixAZF0ENDPOINT7_AZALIA_F0_PIN_CONTROL_CODEC_CS_OVERRIDE_6 0x005f
+#define ixAZF0ENDPOINT7_AZALIA_F0_PIN_CONTROL_CODEC_CS_OVERRIDE_7 0x0060
+#define ixAZF0ENDPOINT7_AZALIA_F0_PIN_CONTROL_CODEC_CS_OVERRIDE_8 0x0061
+#define ixAZF0ENDPOINT7_AZALIA_F0_CODEC_PIN_ASSOCIATION_INFO 0x0062
+#define ixAZF0ENDPOINT7_AZALIA_F0_CODEC_PIN_CONTROL_DIGITAL_OUTPUT_STATUS 0x0063
+#define ixAZF0ENDPOINT7_AZALIA_F0_CODEC_PIN_CONTROL_LPIB_SNAPSHOT_CONTROL 0x0064
+#define ixAZF0ENDPOINT7_AZALIA_F0_CODEC_PIN_CONTROL_LPIB 0x0065
+#define ixAZF0ENDPOINT7_AZALIA_F0_CODEC_PIN_CONTROL_LPIB_TIMER_SNAPSHOT 0x0066
+#define ixAZF0ENDPOINT7_AZALIA_F0_CODEC_PIN_CONTROL_CODING_TYPE 0x0067
+#define ixAZF0ENDPOINT7_AZALIA_F0_CODEC_PIN_CONTROL_FORMAT_CHANGED 0x0068
+#define ixAZF0ENDPOINT7_AZALIA_F0_CODEC_PIN_CONTROL_WIRELESS_DISPLAY_IDENTIFICATION 0x0069
+#define ixAZF0ENDPOINT7_AZALIA_F0_CODEC_PIN_CONTROL_REMOTE_KEEPALIVE 0x006a
+#define ixAZF0ENDPOINT7_AZALIA_F0_AUDIO_ENABLE_STATUS 0x006b
+#define ixAZF0ENDPOINT7_AZALIA_F0_AUDIO_ENABLED_INT_STATUS 0x006c
+#define ixAZF0ENDPOINT7_AZALIA_F0_AUDIO_DISABLED_INT_STATUS 0x006d
+#define ixAZF0ENDPOINT7_AZALIA_F0_AUDIO_FORMAT_CHANGED_INT_STATUS 0x006e
+
+
+// addressBlock: azf0inputendpoint0_inputendpointind
+// base address: 0x0
+#define ixAZF0INPUTENDPOINT0_AZALIA_F0_CODEC_INPUT_CONVERTER_PARAMETER_AUDIO_WIDGET_CAPABILITIES 0x0001
+#define ixAZF0INPUTENDPOINT0_AZALIA_F0_CODEC_INPUT_CONVERTER_CONTROL_CONVERTER_FORMAT 0x0002
+#define ixAZF0INPUTENDPOINT0_AZALIA_F0_CODEC_INPUT_CONVERTER_CONTROL_CHANNEL_STREAM_ID 0x0003
+#define ixAZF0INPUTENDPOINT0_AZALIA_F0_CODEC_INPUT_CONVERTER_CONTROL_DIGITAL_CONVERTER 0x0004
+#define ixAZF0INPUTENDPOINT0_AZALIA_F0_CODEC_INPUT_CONVERTER_PARAMETER_STREAM_FORMATS 0x0005
+#define ixAZF0INPUTENDPOINT0_AZALIA_F0_CODEC_INPUT_CONVERTER_PARAMETER_SUPPORTED_SIZE_RATES 0x0006
+#define ixAZF0INPUTENDPOINT0_AZALIA_F0_CODEC_INPUT_PIN_PARAMETER_AUDIO_WIDGET_CAPABILITIES 0x0020
+#define ixAZF0INPUTENDPOINT0_AZALIA_F0_CODEC_INPUT_PIN_PARAMETER_CAPABILITIES 0x0021
+#define ixAZF0INPUTENDPOINT0_AZALIA_F0_CODEC_INPUT_PIN_CONTROL_UNSOLICITED_RESPONSE 0x0022
+#define ixAZF0INPUTENDPOINT0_AZALIA_F0_CODEC_INPUT_PIN_CONTROL_RESPONSE_INPUT_PIN_SENSE 0x0023
+#define ixAZF0INPUTENDPOINT0_AZALIA_F0_CODEC_INPUT_PIN_CONTROL_WIDGET_CONTROL 0x0024
+#define ixAZF0INPUTENDPOINT0_AZALIA_F0_CODEC_INPUT_PIN_CONTROL_MULTICHANNEL_ENABLE 0x0036
+#define ixAZF0INPUTENDPOINT0_AZALIA_F0_CODEC_INPUT_PIN_CONTROL_MULTICHANNEL_ENABLE2 0x0037
+#define ixAZF0INPUTENDPOINT0_AZALIA_F0_CODEC_INPUT_PIN_CONTROL_RESPONSE_HBR 0x0038
+#define ixAZF0INPUTENDPOINT0_AZALIA_F0_CODEC_INPUT_PIN_CONTROL_CHANNEL_ALLOCATION 0x0053
+#define ixAZF0INPUTENDPOINT0_AZALIA_F0_CODEC_INPUT_PIN_CONTROL_HOT_PLUG_CONTROL 0x0054
+#define ixAZF0INPUTENDPOINT0_AZALIA_F0_CODEC_INPUT_PIN_CONTROL_UNSOLICITED_RESPONSE_FORCE 0x0055
+#define ixAZF0INPUTENDPOINT0_AZALIA_F0_CODEC_INPUT_PIN_CONTROL_RESPONSE_CONFIGURATION_DEFAULT 0x0056
+#define ixAZF0INPUTENDPOINT0_AZALIA_F0_CODEC_INPUT_PIN_CONTROL_LPIB_SNAPSHOT_CONTROL 0x0064
+#define ixAZF0INPUTENDPOINT0_AZALIA_F0_CODEC_INPUT_PIN_CONTROL_LPIB 0x0065
+#define ixAZF0INPUTENDPOINT0_AZALIA_F0_CODEC_INPUT_PIN_CONTROL_LPIB_TIMER_SNAPSHOT 0x0066
+#define ixAZF0INPUTENDPOINT0_AZALIA_F0_CODEC_INPUT_PIN_CONTROL_INPUT_STATUS_CONTROL 0x0067
+#define ixAZF0INPUTENDPOINT0_AZALIA_F0_CODEC_INPUT_PIN_CONTROL_INFOFRAME 0x0068
+
+
+// addressBlock: azf0inputendpoint1_inputendpointind
+// base address: 0x0
+#define ixAZF0INPUTENDPOINT1_AZALIA_F0_CODEC_INPUT_CONVERTER_PARAMETER_AUDIO_WIDGET_CAPABILITIES 0x0001
+#define ixAZF0INPUTENDPOINT1_AZALIA_F0_CODEC_INPUT_CONVERTER_CONTROL_CONVERTER_FORMAT 0x0002
+#define ixAZF0INPUTENDPOINT1_AZALIA_F0_CODEC_INPUT_CONVERTER_CONTROL_CHANNEL_STREAM_ID 0x0003
+#define ixAZF0INPUTENDPOINT1_AZALIA_F0_CODEC_INPUT_CONVERTER_CONTROL_DIGITAL_CONVERTER 0x0004
+#define ixAZF0INPUTENDPOINT1_AZALIA_F0_CODEC_INPUT_CONVERTER_PARAMETER_STREAM_FORMATS 0x0005
+#define ixAZF0INPUTENDPOINT1_AZALIA_F0_CODEC_INPUT_CONVERTER_PARAMETER_SUPPORTED_SIZE_RATES 0x0006
+#define ixAZF0INPUTENDPOINT1_AZALIA_F0_CODEC_INPUT_PIN_PARAMETER_AUDIO_WIDGET_CAPABILITIES 0x0020
+#define ixAZF0INPUTENDPOINT1_AZALIA_F0_CODEC_INPUT_PIN_PARAMETER_CAPABILITIES 0x0021
+#define ixAZF0INPUTENDPOINT1_AZALIA_F0_CODEC_INPUT_PIN_CONTROL_UNSOLICITED_RESPONSE 0x0022
+#define ixAZF0INPUTENDPOINT1_AZALIA_F0_CODEC_INPUT_PIN_CONTROL_RESPONSE_INPUT_PIN_SENSE 0x0023
+#define ixAZF0INPUTENDPOINT1_AZALIA_F0_CODEC_INPUT_PIN_CONTROL_WIDGET_CONTROL 0x0024
+#define ixAZF0INPUTENDPOINT1_AZALIA_F0_CODEC_INPUT_PIN_CONTROL_MULTICHANNEL_ENABLE 0x0036
+#define ixAZF0INPUTENDPOINT1_AZALIA_F0_CODEC_INPUT_PIN_CONTROL_MULTICHANNEL_ENABLE2 0x0037
+#define ixAZF0INPUTENDPOINT1_AZALIA_F0_CODEC_INPUT_PIN_CONTROL_RESPONSE_HBR 0x0038
+#define ixAZF0INPUTENDPOINT1_AZALIA_F0_CODEC_INPUT_PIN_CONTROL_CHANNEL_ALLOCATION 0x0053
+#define ixAZF0INPUTENDPOINT1_AZALIA_F0_CODEC_INPUT_PIN_CONTROL_HOT_PLUG_CONTROL 0x0054
+#define ixAZF0INPUTENDPOINT1_AZALIA_F0_CODEC_INPUT_PIN_CONTROL_UNSOLICITED_RESPONSE_FORCE 0x0055
+#define ixAZF0INPUTENDPOINT1_AZALIA_F0_CODEC_INPUT_PIN_CONTROL_RESPONSE_CONFIGURATION_DEFAULT 0x0056
+#define ixAZF0INPUTENDPOINT1_AZALIA_F0_CODEC_INPUT_PIN_CONTROL_LPIB_SNAPSHOT_CONTROL 0x0064
+#define ixAZF0INPUTENDPOINT1_AZALIA_F0_CODEC_INPUT_PIN_CONTROL_LPIB 0x0065
+#define ixAZF0INPUTENDPOINT1_AZALIA_F0_CODEC_INPUT_PIN_CONTROL_LPIB_TIMER_SNAPSHOT 0x0066
+#define ixAZF0INPUTENDPOINT1_AZALIA_F0_CODEC_INPUT_PIN_CONTROL_INPUT_STATUS_CONTROL 0x0067
+#define ixAZF0INPUTENDPOINT1_AZALIA_F0_CODEC_INPUT_PIN_CONTROL_INFOFRAME 0x0068
+
+
+// addressBlock: azf0inputendpoint2_inputendpointind
+// base address: 0x0
+#define ixAZF0INPUTENDPOINT2_AZALIA_F0_CODEC_INPUT_CONVERTER_PARAMETER_AUDIO_WIDGET_CAPABILITIES 0x0001
+#define ixAZF0INPUTENDPOINT2_AZALIA_F0_CODEC_INPUT_CONVERTER_CONTROL_CONVERTER_FORMAT 0x0002
+#define ixAZF0INPUTENDPOINT2_AZALIA_F0_CODEC_INPUT_CONVERTER_CONTROL_CHANNEL_STREAM_ID 0x0003
+#define ixAZF0INPUTENDPOINT2_AZALIA_F0_CODEC_INPUT_CONVERTER_CONTROL_DIGITAL_CONVERTER 0x0004
+#define ixAZF0INPUTENDPOINT2_AZALIA_F0_CODEC_INPUT_CONVERTER_PARAMETER_STREAM_FORMATS 0x0005
+#define ixAZF0INPUTENDPOINT2_AZALIA_F0_CODEC_INPUT_CONVERTER_PARAMETER_SUPPORTED_SIZE_RATES 0x0006
+#define ixAZF0INPUTENDPOINT2_AZALIA_F0_CODEC_INPUT_PIN_PARAMETER_AUDIO_WIDGET_CAPABILITIES 0x0020
+#define ixAZF0INPUTENDPOINT2_AZALIA_F0_CODEC_INPUT_PIN_PARAMETER_CAPABILITIES 0x0021
+#define ixAZF0INPUTENDPOINT2_AZALIA_F0_CODEC_INPUT_PIN_CONTROL_UNSOLICITED_RESPONSE 0x0022
+#define ixAZF0INPUTENDPOINT2_AZALIA_F0_CODEC_INPUT_PIN_CONTROL_RESPONSE_INPUT_PIN_SENSE 0x0023
+#define ixAZF0INPUTENDPOINT2_AZALIA_F0_CODEC_INPUT_PIN_CONTROL_WIDGET_CONTROL 0x0024
+#define ixAZF0INPUTENDPOINT2_AZALIA_F0_CODEC_INPUT_PIN_CONTROL_MULTICHANNEL_ENABLE 0x0036
+#define ixAZF0INPUTENDPOINT2_AZALIA_F0_CODEC_INPUT_PIN_CONTROL_MULTICHANNEL_ENABLE2 0x0037
+#define ixAZF0INPUTENDPOINT2_AZALIA_F0_CODEC_INPUT_PIN_CONTROL_RESPONSE_HBR 0x0038
+#define ixAZF0INPUTENDPOINT2_AZALIA_F0_CODEC_INPUT_PIN_CONTROL_CHANNEL_ALLOCATION 0x0053
+#define ixAZF0INPUTENDPOINT2_AZALIA_F0_CODEC_INPUT_PIN_CONTROL_HOT_PLUG_CONTROL 0x0054
+#define ixAZF0INPUTENDPOINT2_AZALIA_F0_CODEC_INPUT_PIN_CONTROL_UNSOLICITED_RESPONSE_FORCE 0x0055
+#define ixAZF0INPUTENDPOINT2_AZALIA_F0_CODEC_INPUT_PIN_CONTROL_RESPONSE_CONFIGURATION_DEFAULT 0x0056
+#define ixAZF0INPUTENDPOINT2_AZALIA_F0_CODEC_INPUT_PIN_CONTROL_LPIB_SNAPSHOT_CONTROL 0x0064
+#define ixAZF0INPUTENDPOINT2_AZALIA_F0_CODEC_INPUT_PIN_CONTROL_LPIB 0x0065
+#define ixAZF0INPUTENDPOINT2_AZALIA_F0_CODEC_INPUT_PIN_CONTROL_LPIB_TIMER_SNAPSHOT 0x0066
+#define ixAZF0INPUTENDPOINT2_AZALIA_F0_CODEC_INPUT_PIN_CONTROL_INPUT_STATUS_CONTROL 0x0067
+#define ixAZF0INPUTENDPOINT2_AZALIA_F0_CODEC_INPUT_PIN_CONTROL_INFOFRAME 0x0068
+
+
+// addressBlock: azf0inputendpoint3_inputendpointind
+// base address: 0x0
+#define ixAZF0INPUTENDPOINT3_AZALIA_F0_CODEC_INPUT_CONVERTER_PARAMETER_AUDIO_WIDGET_CAPABILITIES 0x0001
+#define ixAZF0INPUTENDPOINT3_AZALIA_F0_CODEC_INPUT_CONVERTER_CONTROL_CONVERTER_FORMAT 0x0002
+#define ixAZF0INPUTENDPOINT3_AZALIA_F0_CODEC_INPUT_CONVERTER_CONTROL_CHANNEL_STREAM_ID 0x0003
+#define ixAZF0INPUTENDPOINT3_AZALIA_F0_CODEC_INPUT_CONVERTER_CONTROL_DIGITAL_CONVERTER 0x0004
+#define ixAZF0INPUTENDPOINT3_AZALIA_F0_CODEC_INPUT_CONVERTER_PARAMETER_STREAM_FORMATS 0x0005
+#define ixAZF0INPUTENDPOINT3_AZALIA_F0_CODEC_INPUT_CONVERTER_PARAMETER_SUPPORTED_SIZE_RATES 0x0006
+#define ixAZF0INPUTENDPOINT3_AZALIA_F0_CODEC_INPUT_PIN_PARAMETER_AUDIO_WIDGET_CAPABILITIES 0x0020
+#define ixAZF0INPUTENDPOINT3_AZALIA_F0_CODEC_INPUT_PIN_PARAMETER_CAPABILITIES 0x0021
+#define ixAZF0INPUTENDPOINT3_AZALIA_F0_CODEC_INPUT_PIN_CONTROL_UNSOLICITED_RESPONSE 0x0022
+#define ixAZF0INPUTENDPOINT3_AZALIA_F0_CODEC_INPUT_PIN_CONTROL_RESPONSE_INPUT_PIN_SENSE 0x0023
+#define ixAZF0INPUTENDPOINT3_AZALIA_F0_CODEC_INPUT_PIN_CONTROL_WIDGET_CONTROL 0x0024
+#define ixAZF0INPUTENDPOINT3_AZALIA_F0_CODEC_INPUT_PIN_CONTROL_MULTICHANNEL_ENABLE 0x0036
+#define ixAZF0INPUTENDPOINT3_AZALIA_F0_CODEC_INPUT_PIN_CONTROL_MULTICHANNEL_ENABLE2 0x0037
+#define ixAZF0INPUTENDPOINT3_AZALIA_F0_CODEC_INPUT_PIN_CONTROL_RESPONSE_HBR 0x0038
+#define ixAZF0INPUTENDPOINT3_AZALIA_F0_CODEC_INPUT_PIN_CONTROL_CHANNEL_ALLOCATION 0x0053
+#define ixAZF0INPUTENDPOINT3_AZALIA_F0_CODEC_INPUT_PIN_CONTROL_HOT_PLUG_CONTROL 0x0054
+#define ixAZF0INPUTENDPOINT3_AZALIA_F0_CODEC_INPUT_PIN_CONTROL_UNSOLICITED_RESPONSE_FORCE 0x0055
+#define ixAZF0INPUTENDPOINT3_AZALIA_F0_CODEC_INPUT_PIN_CONTROL_RESPONSE_CONFIGURATION_DEFAULT 0x0056
+#define ixAZF0INPUTENDPOINT3_AZALIA_F0_CODEC_INPUT_PIN_CONTROL_LPIB_SNAPSHOT_CONTROL 0x0064
+#define ixAZF0INPUTENDPOINT3_AZALIA_F0_CODEC_INPUT_PIN_CONTROL_LPIB 0x0065
+#define ixAZF0INPUTENDPOINT3_AZALIA_F0_CODEC_INPUT_PIN_CONTROL_LPIB_TIMER_SNAPSHOT 0x0066
+#define ixAZF0INPUTENDPOINT3_AZALIA_F0_CODEC_INPUT_PIN_CONTROL_INPUT_STATUS_CONTROL 0x0067
+#define ixAZF0INPUTENDPOINT3_AZALIA_F0_CODEC_INPUT_PIN_CONTROL_INFOFRAME 0x0068
+
+
+// addressBlock: azf0inputendpoint4_inputendpointind
+// base address: 0x0
+#define ixAZF0INPUTENDPOINT4_AZALIA_F0_CODEC_INPUT_CONVERTER_PARAMETER_AUDIO_WIDGET_CAPABILITIES 0x0001
+#define ixAZF0INPUTENDPOINT4_AZALIA_F0_CODEC_INPUT_CONVERTER_CONTROL_CONVERTER_FORMAT 0x0002
+#define ixAZF0INPUTENDPOINT4_AZALIA_F0_CODEC_INPUT_CONVERTER_CONTROL_CHANNEL_STREAM_ID 0x0003
+#define ixAZF0INPUTENDPOINT4_AZALIA_F0_CODEC_INPUT_CONVERTER_CONTROL_DIGITAL_CONVERTER 0x0004
+#define ixAZF0INPUTENDPOINT4_AZALIA_F0_CODEC_INPUT_CONVERTER_PARAMETER_STREAM_FORMATS 0x0005
+#define ixAZF0INPUTENDPOINT4_AZALIA_F0_CODEC_INPUT_CONVERTER_PARAMETER_SUPPORTED_SIZE_RATES 0x0006
+#define ixAZF0INPUTENDPOINT4_AZALIA_F0_CODEC_INPUT_PIN_PARAMETER_AUDIO_WIDGET_CAPABILITIES 0x0020
+#define ixAZF0INPUTENDPOINT4_AZALIA_F0_CODEC_INPUT_PIN_PARAMETER_CAPABILITIES 0x0021
+#define ixAZF0INPUTENDPOINT4_AZALIA_F0_CODEC_INPUT_PIN_CONTROL_UNSOLICITED_RESPONSE 0x0022
+#define ixAZF0INPUTENDPOINT4_AZALIA_F0_CODEC_INPUT_PIN_CONTROL_RESPONSE_INPUT_PIN_SENSE 0x0023
+#define ixAZF0INPUTENDPOINT4_AZALIA_F0_CODEC_INPUT_PIN_CONTROL_WIDGET_CONTROL 0x0024
+#define ixAZF0INPUTENDPOINT4_AZALIA_F0_CODEC_INPUT_PIN_CONTROL_MULTICHANNEL_ENABLE 0x0036
+#define ixAZF0INPUTENDPOINT4_AZALIA_F0_CODEC_INPUT_PIN_CONTROL_MULTICHANNEL_ENABLE2 0x0037
+#define ixAZF0INPUTENDPOINT4_AZALIA_F0_CODEC_INPUT_PIN_CONTROL_RESPONSE_HBR 0x0038
+#define ixAZF0INPUTENDPOINT4_AZALIA_F0_CODEC_INPUT_PIN_CONTROL_CHANNEL_ALLOCATION 0x0053
+#define ixAZF0INPUTENDPOINT4_AZALIA_F0_CODEC_INPUT_PIN_CONTROL_HOT_PLUG_CONTROL 0x0054
+#define ixAZF0INPUTENDPOINT4_AZALIA_F0_CODEC_INPUT_PIN_CONTROL_UNSOLICITED_RESPONSE_FORCE 0x0055
+#define ixAZF0INPUTENDPOINT4_AZALIA_F0_CODEC_INPUT_PIN_CONTROL_RESPONSE_CONFIGURATION_DEFAULT 0x0056
+#define ixAZF0INPUTENDPOINT4_AZALIA_F0_CODEC_INPUT_PIN_CONTROL_LPIB_SNAPSHOT_CONTROL 0x0064
+#define ixAZF0INPUTENDPOINT4_AZALIA_F0_CODEC_INPUT_PIN_CONTROL_LPIB 0x0065
+#define ixAZF0INPUTENDPOINT4_AZALIA_F0_CODEC_INPUT_PIN_CONTROL_LPIB_TIMER_SNAPSHOT 0x0066
+#define ixAZF0INPUTENDPOINT4_AZALIA_F0_CODEC_INPUT_PIN_CONTROL_INPUT_STATUS_CONTROL 0x0067
+#define ixAZF0INPUTENDPOINT4_AZALIA_F0_CODEC_INPUT_PIN_CONTROL_INFOFRAME 0x0068
+
+
+// addressBlock: azf0inputendpoint5_inputendpointind
+// base address: 0x0
+#define ixAZF0INPUTENDPOINT5_AZALIA_F0_CODEC_INPUT_CONVERTER_PARAMETER_AUDIO_WIDGET_CAPABILITIES 0x0001
+#define ixAZF0INPUTENDPOINT5_AZALIA_F0_CODEC_INPUT_CONVERTER_CONTROL_CONVERTER_FORMAT 0x0002
+#define ixAZF0INPUTENDPOINT5_AZALIA_F0_CODEC_INPUT_CONVERTER_CONTROL_CHANNEL_STREAM_ID 0x0003
+#define ixAZF0INPUTENDPOINT5_AZALIA_F0_CODEC_INPUT_CONVERTER_CONTROL_DIGITAL_CONVERTER 0x0004
+#define ixAZF0INPUTENDPOINT5_AZALIA_F0_CODEC_INPUT_CONVERTER_PARAMETER_STREAM_FORMATS 0x0005
+#define ixAZF0INPUTENDPOINT5_AZALIA_F0_CODEC_INPUT_CONVERTER_PARAMETER_SUPPORTED_SIZE_RATES 0x0006
+#define ixAZF0INPUTENDPOINT5_AZALIA_F0_CODEC_INPUT_PIN_PARAMETER_AUDIO_WIDGET_CAPABILITIES 0x0020
+#define ixAZF0INPUTENDPOINT5_AZALIA_F0_CODEC_INPUT_PIN_PARAMETER_CAPABILITIES 0x0021
+#define ixAZF0INPUTENDPOINT5_AZALIA_F0_CODEC_INPUT_PIN_CONTROL_UNSOLICITED_RESPONSE 0x0022
+#define ixAZF0INPUTENDPOINT5_AZALIA_F0_CODEC_INPUT_PIN_CONTROL_RESPONSE_INPUT_PIN_SENSE 0x0023
+#define ixAZF0INPUTENDPOINT5_AZALIA_F0_CODEC_INPUT_PIN_CONTROL_WIDGET_CONTROL 0x0024
+#define ixAZF0INPUTENDPOINT5_AZALIA_F0_CODEC_INPUT_PIN_CONTROL_MULTICHANNEL_ENABLE 0x0036
+#define ixAZF0INPUTENDPOINT5_AZALIA_F0_CODEC_INPUT_PIN_CONTROL_MULTICHANNEL_ENABLE2 0x0037
+#define ixAZF0INPUTENDPOINT5_AZALIA_F0_CODEC_INPUT_PIN_CONTROL_RESPONSE_HBR 0x0038
+#define ixAZF0INPUTENDPOINT5_AZALIA_F0_CODEC_INPUT_PIN_CONTROL_CHANNEL_ALLOCATION 0x0053
+#define ixAZF0INPUTENDPOINT5_AZALIA_F0_CODEC_INPUT_PIN_CONTROL_HOT_PLUG_CONTROL 0x0054
+#define ixAZF0INPUTENDPOINT5_AZALIA_F0_CODEC_INPUT_PIN_CONTROL_UNSOLICITED_RESPONSE_FORCE 0x0055
+#define ixAZF0INPUTENDPOINT5_AZALIA_F0_CODEC_INPUT_PIN_CONTROL_RESPONSE_CONFIGURATION_DEFAULT 0x0056
+#define ixAZF0INPUTENDPOINT5_AZALIA_F0_CODEC_INPUT_PIN_CONTROL_LPIB_SNAPSHOT_CONTROL 0x0064
+#define ixAZF0INPUTENDPOINT5_AZALIA_F0_CODEC_INPUT_PIN_CONTROL_LPIB 0x0065
+#define ixAZF0INPUTENDPOINT5_AZALIA_F0_CODEC_INPUT_PIN_CONTROL_LPIB_TIMER_SNAPSHOT 0x0066
+#define ixAZF0INPUTENDPOINT5_AZALIA_F0_CODEC_INPUT_PIN_CONTROL_INPUT_STATUS_CONTROL 0x0067
+#define ixAZF0INPUTENDPOINT5_AZALIA_F0_CODEC_INPUT_PIN_CONTROL_INFOFRAME 0x0068
+
+
+// addressBlock: azf0inputendpoint6_inputendpointind
+// base address: 0x0
+#define ixAZF0INPUTENDPOINT6_AZALIA_F0_CODEC_INPUT_CONVERTER_PARAMETER_AUDIO_WIDGET_CAPABILITIES 0x0001
+#define ixAZF0INPUTENDPOINT6_AZALIA_F0_CODEC_INPUT_CONVERTER_CONTROL_CONVERTER_FORMAT 0x0002
+#define ixAZF0INPUTENDPOINT6_AZALIA_F0_CODEC_INPUT_CONVERTER_CONTROL_CHANNEL_STREAM_ID 0x0003
+#define ixAZF0INPUTENDPOINT6_AZALIA_F0_CODEC_INPUT_CONVERTER_CONTROL_DIGITAL_CONVERTER 0x0004
+#define ixAZF0INPUTENDPOINT6_AZALIA_F0_CODEC_INPUT_CONVERTER_PARAMETER_STREAM_FORMATS 0x0005
+#define ixAZF0INPUTENDPOINT6_AZALIA_F0_CODEC_INPUT_CONVERTER_PARAMETER_SUPPORTED_SIZE_RATES 0x0006
+#define ixAZF0INPUTENDPOINT6_AZALIA_F0_CODEC_INPUT_PIN_PARAMETER_AUDIO_WIDGET_CAPABILITIES 0x0020
+#define ixAZF0INPUTENDPOINT6_AZALIA_F0_CODEC_INPUT_PIN_PARAMETER_CAPABILITIES 0x0021
+#define ixAZF0INPUTENDPOINT6_AZALIA_F0_CODEC_INPUT_PIN_CONTROL_UNSOLICITED_RESPONSE 0x0022
+#define ixAZF0INPUTENDPOINT6_AZALIA_F0_CODEC_INPUT_PIN_CONTROL_RESPONSE_INPUT_PIN_SENSE 0x0023
+#define ixAZF0INPUTENDPOINT6_AZALIA_F0_CODEC_INPUT_PIN_CONTROL_WIDGET_CONTROL 0x0024
+#define ixAZF0INPUTENDPOINT6_AZALIA_F0_CODEC_INPUT_PIN_CONTROL_MULTICHANNEL_ENABLE 0x0036
+#define ixAZF0INPUTENDPOINT6_AZALIA_F0_CODEC_INPUT_PIN_CONTROL_MULTICHANNEL_ENABLE2 0x0037
+#define ixAZF0INPUTENDPOINT6_AZALIA_F0_CODEC_INPUT_PIN_CONTROL_RESPONSE_HBR 0x0038
+#define ixAZF0INPUTENDPOINT6_AZALIA_F0_CODEC_INPUT_PIN_CONTROL_CHANNEL_ALLOCATION 0x0053
+#define ixAZF0INPUTENDPOINT6_AZALIA_F0_CODEC_INPUT_PIN_CONTROL_HOT_PLUG_CONTROL 0x0054
+#define ixAZF0INPUTENDPOINT6_AZALIA_F0_CODEC_INPUT_PIN_CONTROL_UNSOLICITED_RESPONSE_FORCE 0x0055
+#define ixAZF0INPUTENDPOINT6_AZALIA_F0_CODEC_INPUT_PIN_CONTROL_RESPONSE_CONFIGURATION_DEFAULT 0x0056
+#define ixAZF0INPUTENDPOINT6_AZALIA_F0_CODEC_INPUT_PIN_CONTROL_LPIB_SNAPSHOT_CONTROL 0x0064
+#define ixAZF0INPUTENDPOINT6_AZALIA_F0_CODEC_INPUT_PIN_CONTROL_LPIB 0x0065
+#define ixAZF0INPUTENDPOINT6_AZALIA_F0_CODEC_INPUT_PIN_CONTROL_LPIB_TIMER_SNAPSHOT 0x0066
+#define ixAZF0INPUTENDPOINT6_AZALIA_F0_CODEC_INPUT_PIN_CONTROL_INPUT_STATUS_CONTROL 0x0067
+#define ixAZF0INPUTENDPOINT6_AZALIA_F0_CODEC_INPUT_PIN_CONTROL_INFOFRAME 0x0068
+
+
+// addressBlock: azf0inputendpoint7_inputendpointind
+// base address: 0x0
+#define ixAZF0INPUTENDPOINT7_AZALIA_F0_CODEC_INPUT_CONVERTER_PARAMETER_AUDIO_WIDGET_CAPABILITIES 0x0001
+#define ixAZF0INPUTENDPOINT7_AZALIA_F0_CODEC_INPUT_CONVERTER_CONTROL_CONVERTER_FORMAT 0x0002
+#define ixAZF0INPUTENDPOINT7_AZALIA_F0_CODEC_INPUT_CONVERTER_CONTROL_CHANNEL_STREAM_ID 0x0003
+#define ixAZF0INPUTENDPOINT7_AZALIA_F0_CODEC_INPUT_CONVERTER_CONTROL_DIGITAL_CONVERTER 0x0004
+#define ixAZF0INPUTENDPOINT7_AZALIA_F0_CODEC_INPUT_CONVERTER_PARAMETER_STREAM_FORMATS 0x0005
+#define ixAZF0INPUTENDPOINT7_AZALIA_F0_CODEC_INPUT_CONVERTER_PARAMETER_SUPPORTED_SIZE_RATES 0x0006
+#define ixAZF0INPUTENDPOINT7_AZALIA_F0_CODEC_INPUT_PIN_PARAMETER_AUDIO_WIDGET_CAPABILITIES 0x0020
+#define ixAZF0INPUTENDPOINT7_AZALIA_F0_CODEC_INPUT_PIN_PARAMETER_CAPABILITIES 0x0021
+#define ixAZF0INPUTENDPOINT7_AZALIA_F0_CODEC_INPUT_PIN_CONTROL_UNSOLICITED_RESPONSE 0x0022
+#define ixAZF0INPUTENDPOINT7_AZALIA_F0_CODEC_INPUT_PIN_CONTROL_RESPONSE_INPUT_PIN_SENSE 0x0023
+#define ixAZF0INPUTENDPOINT7_AZALIA_F0_CODEC_INPUT_PIN_CONTROL_WIDGET_CONTROL 0x0024
+#define ixAZF0INPUTENDPOINT7_AZALIA_F0_CODEC_INPUT_PIN_CONTROL_MULTICHANNEL_ENABLE 0x0036
+#define ixAZF0INPUTENDPOINT7_AZALIA_F0_CODEC_INPUT_PIN_CONTROL_MULTICHANNEL_ENABLE2 0x0037
+#define ixAZF0INPUTENDPOINT7_AZALIA_F0_CODEC_INPUT_PIN_CONTROL_RESPONSE_HBR 0x0038
+#define ixAZF0INPUTENDPOINT7_AZALIA_F0_CODEC_INPUT_PIN_CONTROL_CHANNEL_ALLOCATION 0x0053
+#define ixAZF0INPUTENDPOINT7_AZALIA_F0_CODEC_INPUT_PIN_CONTROL_HOT_PLUG_CONTROL 0x0054
+#define ixAZF0INPUTENDPOINT7_AZALIA_F0_CODEC_INPUT_PIN_CONTROL_UNSOLICITED_RESPONSE_FORCE 0x0055
+#define ixAZF0INPUTENDPOINT7_AZALIA_F0_CODEC_INPUT_PIN_CONTROL_RESPONSE_CONFIGURATION_DEFAULT 0x0056
+#define ixAZF0INPUTENDPOINT7_AZALIA_F0_CODEC_INPUT_PIN_CONTROL_LPIB_SNAPSHOT_CONTROL 0x0064
+#define ixAZF0INPUTENDPOINT7_AZALIA_F0_CODEC_INPUT_PIN_CONTROL_LPIB 0x0065
+#define ixAZF0INPUTENDPOINT7_AZALIA_F0_CODEC_INPUT_PIN_CONTROL_LPIB_TIMER_SNAPSHOT 0x0066
+#define ixAZF0INPUTENDPOINT7_AZALIA_F0_CODEC_INPUT_PIN_CONTROL_INPUT_STATUS_CONTROL 0x0067
+#define ixAZF0INPUTENDPOINT7_AZALIA_F0_CODEC_INPUT_PIN_CONTROL_INFOFRAME 0x0068
+
+
+#endif
diff --git a/drivers/gpu/drm/amd/include/asic_reg/dcn/dcn_3_1_5_sh_mask.h b/drivers/gpu/drm/amd/include/asic_reg/dcn/dcn_3_1_5_sh_mask.h
new file mode 100644
index 000000000000..295e0dac9ffa
--- /dev/null
+++ b/drivers/gpu/drm/amd/include/asic_reg/dcn/dcn_3_1_5_sh_mask.h