* Sat Apr 18 2026 Justin M. Forbes <jforbes@fedoraproject.org> [6.19.13-0] - Linux v6.19.13 Resolves: Signed-off-by: Justin M. Forbes <jforbes@fedoraproject.org>
3973 lines
129 KiB
Diff
3973 lines
129 KiB
Diff
Documentation/hid/intel-ish-hid.rst | 19 +-
|
|
Makefile | 30 +
|
|
arch/arm/Kconfig | 4 +-
|
|
arch/arm64/Kconfig | 2 +-
|
|
arch/arm64/boot/dts/broadcom/bcm2712-d-rpi-5-b.dts | 14 +
|
|
.../boot/dts/broadcom/bcm2712-rpi-5-b-base.dtsi | 46 +-
|
|
arch/arm64/boot/dts/broadcom/bcm2712-rpi-5-b.dts | 24 +
|
|
arch/arm64/boot/dts/broadcom/bcm2712.dtsi | 36 +
|
|
arch/arm64/boot/dts/broadcom/rp1-common.dtsi | 105 +++
|
|
arch/arm64/boot/dts/freescale/Makefile | 1 +
|
|
arch/arm64/boot/dts/freescale/imx93-11x11-frdm.dts | 807 +++++++++++++++++++++
|
|
arch/arm64/kernel/setup.c | 27 +
|
|
arch/s390/include/asm/ipl.h | 1 +
|
|
arch/s390/kernel/ipl.c | 5 +
|
|
arch/s390/kernel/setup.c | 4 +
|
|
arch/x86/kernel/setup.c | 22 +-
|
|
crypto/akcipher.c | 3 +-
|
|
crypto/dh.c | 25 +
|
|
crypto/seqiv.c | 15 +-
|
|
crypto/sig.c | 3 +-
|
|
crypto/testmgr.c | 6 +-
|
|
drivers/acpi/apei/hest.c | 8 +
|
|
drivers/acpi/irq.c | 17 +-
|
|
drivers/acpi/scan.c | 9 +
|
|
drivers/ata/libahci.c | 18 +
|
|
drivers/firmware/efi/Makefile | 1 +
|
|
drivers/firmware/efi/efi.c | 124 +++-
|
|
drivers/firmware/efi/libstub/fdt.c | 5 +
|
|
drivers/firmware/efi/libstub/secureboot.c | 14 +-
|
|
drivers/firmware/efi/secureboot.c | 38 +
|
|
drivers/gpu/drm/i915/display/intel_alpm.c | 6 +-
|
|
drivers/gpu/drm/i915/display/intel_display.c | 8 -
|
|
drivers/gpu/drm/i915/display/intel_display_types.h | 45 +-
|
|
drivers/gpu/drm/i915/display/intel_dp.c | 17 +-
|
|
drivers/gpu/drm/i915/display/intel_plane.c | 10 +-
|
|
drivers/gpu/drm/i915/display/intel_psr.c | 310 ++++----
|
|
drivers/gpu/drm/i915/display/intel_psr.h | 2 +-
|
|
drivers/hid/hid-rmi.c | 66 --
|
|
drivers/hid/intel-ish-hid/ishtp/loader.c | 58 +-
|
|
drivers/hwtracing/coresight/coresight-etm4x-core.c | 19 +
|
|
drivers/input/rmi4/rmi_driver.c | 124 ++--
|
|
drivers/iommu/iommu.c | 22 +
|
|
drivers/media/pci/intel/ipu-bridge.c | 14 +
|
|
drivers/mfd/bcm2835-pm.c | 9 +-
|
|
drivers/net/ethernet/cadence/macb_main.c | 29 +-
|
|
drivers/pci/quirks.c | 24 +
|
|
drivers/scsi/sd.c | 10 +
|
|
drivers/usb/core/hub.c | 7 +
|
|
include/drm/display/drm_dp.h | 2 +
|
|
include/linux/crypto.h | 2 +
|
|
include/linux/efi.h | 22 +-
|
|
include/linux/lsm_hook_defs.h | 1 +
|
|
include/linux/mfd/bcm2835-pm.h | 7 +
|
|
include/linux/rmi.h | 1 +
|
|
include/linux/security.h | 9 +
|
|
kernel/module/signing.c | 9 +-
|
|
scripts/Makefile.lib | 3 +
|
|
scripts/tags.sh | 2 +
|
|
security/integrity/platform_certs/load_uefi.c | 6 +-
|
|
security/lockdown/Kconfig | 13 +
|
|
security/lockdown/lockdown.c | 11 +
|
|
sound/soc/sdca/sdca_class_function.c | 13 +
|
|
tools/testing/selftests/bpf/Makefile | 2 +-
|
|
tools/testing/selftests/bpf/prog_tests/ksyms_btf.c | 31 -
|
|
64 files changed, 1905 insertions(+), 442 deletions(-)
|
|
|
|
diff --git a/Documentation/hid/intel-ish-hid.rst b/Documentation/hid/intel-ish-hid.rst
|
|
index 2adc174fb576c..068a5906b1774 100644
|
|
--- a/Documentation/hid/intel-ish-hid.rst
|
|
+++ b/Documentation/hid/intel-ish-hid.rst
|
|
@@ -413,6 +413,10 @@ Vendors who wish to upstream their custom firmware should follow these guideline
|
|
|
|
- The firmware filename should use one of the following patterns:
|
|
|
|
+ - ``ish_${intel_plat_gen}_${SYS_VENDOR_CRC32}_${PRODUCT_FAMILY_CRC32}_${PRODUCT_NAME_CRC32}_${PRODUCT_SKU_CRC32}.bin``
|
|
+ - ``ish_${intel_plat_gen}_${SYS_VENDOR_CRC32}_${PRODUCT_FAMILY_CRC32}_${PRODUCT_SKU_CRC32}.bin``
|
|
+ - ``ish_${intel_plat_gen}_${SYS_VENDOR_CRC32}_${PRODUCT_FAMILY_CRC32}_${PRODUCT_NAME_CRC32}.bin``
|
|
+ - ``ish_${intel_plat_gen}_${SYS_VENDOR_CRC32}_${PRODUCT_FAMILY_CRC32}.bin``
|
|
- ``ish_${intel_plat_gen}_${SYS_VENDOR_CRC32}_${PRODUCT_NAME_CRC32}_${PRODUCT_SKU_CRC32}.bin``
|
|
- ``ish_${intel_plat_gen}_${SYS_VENDOR_CRC32}_${PRODUCT_SKU_CRC32}.bin``
|
|
- ``ish_${intel_plat_gen}_${SYS_VENDOR_CRC32}_${PRODUCT_NAME_CRC32}.bin``
|
|
@@ -420,16 +424,21 @@ Vendors who wish to upstream their custom firmware should follow these guideline
|
|
|
|
- ``${intel_plat_gen}`` indicates the Intel platform generation (e.g., ``lnlm`` for Lunar Lake) and must not exceed 8 characters in length.
|
|
- ``${SYS_VENDOR_CRC32}`` is the CRC32 checksum of the ``sys_vendor`` value from the DMI field ``DMI_SYS_VENDOR``.
|
|
+- ``${PRODUCT_FAMILY_CRC32}`` is the CRC32 checksum of the ``product_family`` value from the DMI field ``DMI_PRODUCT_FAMILY``.
|
|
- ``${PRODUCT_NAME_CRC32}`` is the CRC32 checksum of the ``product_name`` value from the DMI field ``DMI_PRODUCT_NAME``.
|
|
- ``${PRODUCT_SKU_CRC32}`` is the CRC32 checksum of the ``product_sku`` value from the DMI field ``DMI_PRODUCT_SKU``.
|
|
|
|
During system boot, the ISH Linux driver will attempt to load the firmware in the following order, prioritizing custom firmware with more precise matching patterns:
|
|
|
|
-1. ``intel/ish/ish_${intel_plat_gen}_${SYS_VENDOR_CRC32}_${PRODUCT_NAME_CRC32}_${PRODUCT_SKU_CRC32}.bin``
|
|
-2. ``intel/ish/ish_${intel_plat_gen}_${SYS_VENDOR_CRC32}_${PRODUCT_SKU_CRC32}.bin``
|
|
-3. ``intel/ish/ish_${intel_plat_gen}_${SYS_VENDOR_CRC32}_${PRODUCT_NAME_CRC32}.bin``
|
|
-4. ``intel/ish/ish_${intel_plat_gen}_${SYS_VENDOR_CRC32}.bin``
|
|
-5. ``intel/ish/ish_${intel_plat_gen}.bin``
|
|
+1. ``intel/ish/ish_${intel_plat_gen}_${SYS_VENDOR_CRC32}_${PRODUCT_FAMILY_CRC32}_${PRODUCT_NAME_CRC32}_${PRODUCT_SKU_CRC32}.bin``
|
|
+2. ``intel/ish/ish_${intel_plat_gen}_${SYS_VENDOR_CRC32}_${PRODUCT_FAMILY_CRC32}_${PRODUCT_SKU_CRC32}.bin``
|
|
+3. ``intel/ish/ish_${intel_plat_gen}_${SYS_VENDOR_CRC32}_${PRODUCT_FAMILY_CRC32}_${PRODUCT_NAME_CRC32}.bin``
|
|
+4. ``intel/ish/ish_${intel_plat_gen}_${SYS_VENDOR_CRC32}_${PRODUCT_FAMILY_CRC32}.bin``
|
|
+5. ``intel/ish/ish_${intel_plat_gen}_${SYS_VENDOR_CRC32}_${PRODUCT_NAME_CRC32}_${PRODUCT_SKU_CRC32}.bin``
|
|
+6. ``intel/ish/ish_${intel_plat_gen}_${SYS_VENDOR_CRC32}_${PRODUCT_SKU_CRC32}.bin``
|
|
+7. ``intel/ish/ish_${intel_plat_gen}_${SYS_VENDOR_CRC32}_${PRODUCT_NAME_CRC32}.bin``
|
|
+8. ``intel/ish/ish_${intel_plat_gen}_${SYS_VENDOR_CRC32}.bin``
|
|
+9. ``intel/ish/ish_${intel_plat_gen}.bin``
|
|
|
|
The driver will load the first matching firmware and skip the rest. If no matching firmware is found, it will proceed to the next pattern in the specified order. If all searches fail, the default Intel firmware, listed last in the order above, will be loaded.
|
|
|
|
diff --git a/Makefile b/Makefile
|
|
index 7441da122752c..2aaffdd4a717c 100644
|
|
--- a/Makefile
|
|
+++ b/Makefile
|
|
@@ -355,6 +355,17 @@ ifneq ($(filter install,$(MAKECMDGOALS)),)
|
|
endif
|
|
endif
|
|
|
|
+# CKI/cross compilation hack
|
|
+# Do we need to rebuild scripts after cross compilation?
|
|
+# If kernel was cross-compiled, these scripts have arch of build host.
|
|
+REBUILD_SCRIPTS_FOR_CROSS:=0
|
|
+
|
|
+# Regenerating config with incomplete source tree will produce different
|
|
+# config options. Disable it.
|
|
+ifeq ($(REBUILD_SCRIPTS_FOR_CROSS),1)
|
|
+may-sync-config:=
|
|
+endif
|
|
+
|
|
ifdef mixed-build
|
|
# ===========================================================================
|
|
# We're called with mixed targets (*config and build targets).
|
|
@@ -1339,6 +1350,8 @@ uapi-asm-generic:
|
|
# Generate some files
|
|
# ---------------------------------------------------------------------------
|
|
|
|
+include $(srctree)/Makefile.rhelver
|
|
+
|
|
# KERNELRELEASE can change from a few different places, meaning version.h
|
|
# needs to be updated, so this check is forced on all builds
|
|
|
|
@@ -1986,6 +1999,23 @@ endif
|
|
|
|
ifdef CONFIG_MODULES
|
|
|
|
+scripts_build:
|
|
+ $(MAKE) $(build)=scripts/basic
|
|
+ $(MAKE) $(build)=scripts/mod
|
|
+ $(MAKE) $(build)=scripts scripts/module.lds
|
|
+ $(MAKE) $(build)=scripts scripts/unifdef
|
|
+ $(MAKE) $(build)=scripts
|
|
+
|
|
+prepare_after_cross:
|
|
+ # disable STACK_VALIDATION to avoid building objtool
|
|
+ sed -i '/^CONFIG_STACK_VALIDATION/d' ./include/config/auto.conf || true
|
|
+ # build minimum set of scripts and resolve_btfids to allow building
|
|
+ # external modules
|
|
+ $(MAKE) KBUILD_EXTMOD="" M="" scripts_build V=1
|
|
+ $(MAKE) -C tools/bpf/resolve_btfids
|
|
+
|
|
+PHONY += prepare_after_cross scripts_build
|
|
+
|
|
modules.order: $(build-dir)
|
|
@:
|
|
|
|
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
|
|
index fa83c040ee2d4..96c9bcf9e7b17 100644
|
|
--- a/arch/arm/Kconfig
|
|
+++ b/arch/arm/Kconfig
|
|
@@ -1212,9 +1212,9 @@ config HIGHMEM
|
|
If unsure, say n.
|
|
|
|
config HIGHPTE
|
|
- bool "Allocate 2nd-level pagetables from highmem" if EXPERT
|
|
+ bool "Allocate 2nd-level pagetables from highmem"
|
|
depends on HIGHMEM && !PREEMPT_RT
|
|
- default y
|
|
+ default n
|
|
help
|
|
The VM uses one page of physical memory for each page table.
|
|
For systems with a lot of processes, this can use a lot of
|
|
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
|
|
index 93173f0a09c7d..8f992962ccd35 100644
|
|
--- a/arch/arm64/Kconfig
|
|
+++ b/arch/arm64/Kconfig
|
|
@@ -1433,7 +1433,7 @@ endchoice
|
|
|
|
config ARM64_FORCE_52BIT
|
|
bool "Force 52-bit virtual addresses for userspace"
|
|
- depends on ARM64_VA_BITS_52 && EXPERT
|
|
+ depends on ARM64_VA_BITS_52
|
|
help
|
|
For systems with 52-bit userspace VAs enabled, the kernel will attempt
|
|
to maintain compatibility with older software by providing 48-bit VAs
|
|
diff --git a/arch/arm64/boot/dts/broadcom/bcm2712-d-rpi-5-b.dts b/arch/arm64/boot/dts/broadcom/bcm2712-d-rpi-5-b.dts
|
|
index 7de24d60bcd1a..127be0fc27c22 100644
|
|
--- a/arch/arm64/boot/dts/broadcom/bcm2712-d-rpi-5-b.dts
|
|
+++ b/arch/arm64/boot/dts/broadcom/bcm2712-d-rpi-5-b.dts
|
|
@@ -35,3 +35,17 @@ &gio_aon {
|
|
"PMIC_SCL", // AON_SGPIO_04
|
|
"PMIC_SDA"; // AON_SGPIO_05
|
|
};
|
|
+
|
|
+&pinctrl {
|
|
+ compatible = "brcm,bcm2712d0-pinctrl";
|
|
+ reg = <0x7d504100 0x20>;
|
|
+};
|
|
+
|
|
+&pinctrl_aon {
|
|
+ compatible = "brcm,bcm2712d0-aon-pinctrl";
|
|
+ reg = <0x7d510700 0x1c>;
|
|
+};
|
|
+
|
|
+&uart10 {
|
|
+ interrupts = <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>;
|
|
+};
|
|
diff --git a/arch/arm64/boot/dts/broadcom/bcm2712-rpi-5-b-base.dtsi b/arch/arm64/boot/dts/broadcom/bcm2712-rpi-5-b-base.dtsi
|
|
index 04738bf281ebd..eddaf72c4e734 100644
|
|
--- a/arch/arm64/boot/dts/broadcom/bcm2712-rpi-5-b-base.dtsi
|
|
+++ b/arch/arm64/boot/dts/broadcom/bcm2712-rpi-5-b-base.dtsi
|
|
@@ -190,30 +190,32 @@ wifi: wifi@1 {
|
|
};
|
|
|
|
&soc {
|
|
- firmware: firmware {
|
|
- compatible = "raspberrypi,bcm2835-firmware", "simple-mfd";
|
|
- #address-cells = <1>;
|
|
- #size-cells = <1>;
|
|
-
|
|
- mboxes = <&mailbox>;
|
|
- dma-ranges;
|
|
-
|
|
- firmware_clocks: clocks {
|
|
- compatible = "raspberrypi,firmware-clocks";
|
|
- #clock-cells = <1>;
|
|
+ firmware {
|
|
+ firmware: rpi-firmware {
|
|
+ compatible = "raspberrypi,bcm2835-firmware", "simple-mfd";
|
|
+ #address-cells = <1>;
|
|
+ #size-cells = <1>;
|
|
+
|
|
+ mboxes = <&mailbox>;
|
|
+ dma-ranges;
|
|
+
|
|
+ firmware_clocks: clocks {
|
|
+ compatible = "raspberrypi,firmware-clocks";
|
|
+ #clock-cells = <1>;
|
|
+ };
|
|
+
|
|
+ reset: reset {
|
|
+ compatible = "raspberrypi,firmware-reset";
|
|
+ #reset-cells = <1>;
|
|
+ };
|
|
};
|
|
|
|
- reset: reset {
|
|
- compatible = "raspberrypi,firmware-reset";
|
|
- #reset-cells = <1>;
|
|
+ power: power {
|
|
+ compatible = "raspberrypi,bcm2835-power";
|
|
+ firmware = <&firmware>;
|
|
+ #power-domain-cells = <1>;
|
|
};
|
|
};
|
|
-
|
|
- power: power {
|
|
- compatible = "raspberrypi,bcm2835-power";
|
|
- firmware = <&firmware>;
|
|
- #power-domain-cells = <1>;
|
|
- };
|
|
};
|
|
|
|
/* uarta communicates with the BT module */
|
|
@@ -252,3 +254,7 @@ &pcie1 {
|
|
&pcie2 {
|
|
status = "okay";
|
|
};
|
|
+
|
|
+&v3d {
|
|
+ clocks = <&firmware_clocks 5>;
|
|
+};
|
|
diff --git a/arch/arm64/boot/dts/broadcom/bcm2712-rpi-5-b.dts b/arch/arm64/boot/dts/broadcom/bcm2712-rpi-5-b.dts
|
|
index 2856082814462..0fc57e72632ed 100644
|
|
--- a/arch/arm64/boot/dts/broadcom/bcm2712-rpi-5-b.dts
|
|
+++ b/arch/arm64/boot/dts/broadcom/bcm2712-rpi-5-b.dts
|
|
@@ -68,6 +68,30 @@ usb_vbus_default_state: usb-vbus-default-state {
|
|
function = "vbus1";
|
|
groups = "vbus1";
|
|
};
|
|
+
|
|
+ rp1_i2c4_default_state: rp1-i2c4-default-state {
|
|
+ function = "i2c4";
|
|
+ groups = "i2c4_2";
|
|
+ drive-strength = <12>;
|
|
+ bias-pull-up;
|
|
+ };
|
|
+
|
|
+ rp1_i2c6_default_state: rp1-i2c6-default-state {
|
|
+ function = "i2c6";
|
|
+ groups = "i2c6_0";
|
|
+ drive-strength = <12>;
|
|
+ bias-pull-up;
|
|
+ };
|
|
+};
|
|
+
|
|
+&rp1_i2c4 {
|
|
+ pinctrl-0 = <&rp1_i2c4_default_state>;
|
|
+ pinctrl-names = "default";
|
|
+};
|
|
+
|
|
+&rp1_i2c6 {
|
|
+ pinctrl-0 = <&rp1_i2c6_default_state>;
|
|
+ pinctrl-names = "default";
|
|
};
|
|
|
|
&rp1_usb0 {
|
|
diff --git a/arch/arm64/boot/dts/broadcom/bcm2712.dtsi b/arch/arm64/boot/dts/broadcom/bcm2712.dtsi
|
|
index 205b87f557d6d..98cb2173137ec 100644
|
|
--- a/arch/arm64/boot/dts/broadcom/bcm2712.dtsi
|
|
+++ b/arch/arm64/boot/dts/broadcom/bcm2712.dtsi
|
|
@@ -1,5 +1,6 @@
|
|
// SPDX-License-Identifier: (GPL-2.0 OR MIT)
|
|
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
|
+#include <dt-bindings/soc/bcm2835-pm.h>
|
|
|
|
/ {
|
|
compatible = "brcm,bcm2712";
|
|
@@ -250,6 +251,15 @@ uart10: serial@7d001000 {
|
|
status = "disabled";
|
|
};
|
|
|
|
+ pm: watchdog@7d200000 {
|
|
+ compatible = "brcm,bcm2712-pm", "brcm,bcm2835-pm-wdt";
|
|
+ reg = <0x7d200000 0x604>;
|
|
+ reg-names = "pm";
|
|
+ #power-domain-cells = <1>;
|
|
+ #reset-cells = <1>;
|
|
+ system-power-controller;
|
|
+ };
|
|
+
|
|
pinctrl: pinctrl@7d504100 {
|
|
compatible = "brcm,bcm2712c0-pinctrl";
|
|
reg = <0x7d504100 0x30>;
|
|
@@ -283,6 +293,12 @@ pinctrl_aon: pinctrl@7d510700 {
|
|
reg = <0x7d510700 0x20>;
|
|
};
|
|
|
|
+ random: rng@7d208000 {
|
|
+ compatible = "brcm,bcm2711-rng200";
|
|
+ reg = <0x7d208000 0x28>;
|
|
+ status = "okay";
|
|
+ };
|
|
+
|
|
interrupt-controller@7d517000 {
|
|
compatible = "brcm,bcm7271-l2-intc";
|
|
reg = <0x7d517000 0x10>;
|
|
@@ -631,6 +647,26 @@ mip1: msi-controller@1000131000 {
|
|
msi-ranges = <&gicv2 GIC_SPI 247 IRQ_TYPE_EDGE_RISING 8>;
|
|
brcm,msi-offset = <8>;
|
|
};
|
|
+
|
|
+ isp: isp@1000880000 {
|
|
+ compatible = "brcm,bcm2712-pispbe", "raspberrypi,pispbe";
|
|
+ reg = <0x10 0x00880000 0x0 0x4000>;
|
|
+ interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>;
|
|
+ clocks = <&firmware_clocks 7>;
|
|
+ };
|
|
+
|
|
+ v3d: gpu@1002000000 {
|
|
+ compatible = "brcm,2712-v3d";
|
|
+ reg = <0x10 0x02000000 0x00 0x4000>,
|
|
+ <0x10 0x02008000 0x00 0x6000>,
|
|
+ <0x10 0x02030800 0x00 0x0700>;
|
|
+ reg-names = "hub", "core0", "sms";
|
|
+
|
|
+ power-domains = <&pm BCM2835_POWER_DOMAIN_GRAFX_V3D>;
|
|
+ resets = <&pm BCM2835_RESET_V3D>;
|
|
+ interrupts = <GIC_SPI 250 IRQ_TYPE_LEVEL_HIGH>,
|
|
+ <GIC_SPI 249 IRQ_TYPE_LEVEL_HIGH>;
|
|
+ };
|
|
};
|
|
|
|
timer {
|
|
diff --git a/arch/arm64/boot/dts/broadcom/rp1-common.dtsi b/arch/arm64/boot/dts/broadcom/rp1-common.dtsi
|
|
index 5a815c3797945..16f5359395835 100644
|
|
--- a/arch/arm64/boot/dts/broadcom/rp1-common.dtsi
|
|
+++ b/arch/arm64/boot/dts/broadcom/rp1-common.dtsi
|
|
@@ -26,6 +26,83 @@ rp1_clocks: clocks@40018000 {
|
|
<200000000>; // RP1_CLK_SYS
|
|
};
|
|
|
|
+ rp1_i2c0: i2c@40070000 {
|
|
+ compatible = "snps,designware-i2c";
|
|
+ reg = <0x0 0x40070000 0x0 0x1000>;
|
|
+ interrupts = <7 IRQ_TYPE_LEVEL_HIGH>;
|
|
+ clocks = <&rp1_clocks RP1_CLK_SYS>;
|
|
+ i2c-scl-rising-time-ns = <65>;
|
|
+ i2c-scl-falling-time-ns = <100>;
|
|
+
|
|
+ status = "disabled";
|
|
+ };
|
|
+
|
|
+ rp1_i2c1: i2c@40074000 {
|
|
+ compatible = "snps,designware-i2c";
|
|
+ reg = <0x0 0x40074000 0x0 0x1000>;
|
|
+ interrupts = <8 IRQ_TYPE_LEVEL_HIGH>;
|
|
+ clocks = <&rp1_clocks RP1_CLK_SYS>;
|
|
+ i2c-scl-rising-time-ns = <65>;
|
|
+ i2c-scl-falling-time-ns = <100>;
|
|
+
|
|
+ status = "disabled";
|
|
+ };
|
|
+
|
|
+ rp1_i2c2: i2c@40078000 {
|
|
+ compatible = "snps,designware-i2c";
|
|
+ reg = <0x0 0x40078000 0x0 0x1000>;
|
|
+ interrupts = <9 IRQ_TYPE_LEVEL_HIGH>;
|
|
+ clocks = <&rp1_clocks RP1_CLK_SYS>;
|
|
+ i2c-scl-rising-time-ns = <65>;
|
|
+ i2c-scl-falling-time-ns = <100>;
|
|
+
|
|
+ status = "disabled";
|
|
+ };
|
|
+
|
|
+ rp1_i2c3: i2c@4007c000 {
|
|
+ compatible = "snps,designware-i2c";
|
|
+ reg = <0x0 0x4007c000 0x0 0x1000>;
|
|
+ interrupts = <10 IRQ_TYPE_LEVEL_HIGH>;
|
|
+ clocks = <&rp1_clocks RP1_CLK_SYS>;
|
|
+ i2c-scl-rising-time-ns = <65>;
|
|
+ i2c-scl-falling-time-ns = <100>;
|
|
+
|
|
+ status = "disabled";
|
|
+ };
|
|
+
|
|
+ rp1_i2c4: i2c@40080000 {
|
|
+ compatible = "snps,designware-i2c";
|
|
+ reg = <0x0 0x40080000 0x0 0x1000>;
|
|
+ interrupts = <11 IRQ_TYPE_LEVEL_HIGH>;
|
|
+ clocks = <&rp1_clocks RP1_CLK_SYS>;
|
|
+ i2c-scl-rising-time-ns = <65>;
|
|
+ i2c-scl-falling-time-ns = <100>;
|
|
+
|
|
+ status = "disabled";
|
|
+ };
|
|
+
|
|
+ rp1_i2c5: i2c@40084000 {
|
|
+ compatible = "snps,designware-i2c";
|
|
+ reg = <0x0 0x40084000 0x0 0x1000>;
|
|
+ interrupts = <12 IRQ_TYPE_LEVEL_HIGH>;
|
|
+ clocks = <&rp1_clocks RP1_CLK_SYS>;
|
|
+ i2c-scl-rising-time-ns = <65>;
|
|
+ i2c-scl-falling-time-ns = <100>;
|
|
+
|
|
+ status = "disabled";
|
|
+ };
|
|
+
|
|
+ rp1_i2c6: i2c@40088000 {
|
|
+ compatible = "snps,designware-i2c";
|
|
+ reg = <0x0 0x40088000 0x0 0x1000>;
|
|
+ interrupts = <13 IRQ_TYPE_LEVEL_HIGH>;
|
|
+ clocks = <&rp1_clocks RP1_CLK_SYS>;
|
|
+ i2c-scl-rising-time-ns = <65>;
|
|
+ i2c-scl-falling-time-ns = <100>;
|
|
+
|
|
+ status = "disabled";
|
|
+ };
|
|
+
|
|
rp1_gpio: pinctrl@400d0000 {
|
|
compatible = "raspberrypi,rp1-gpio";
|
|
reg = <0x00 0x400d0000 0x0 0xc000>,
|
|
@@ -56,6 +133,34 @@ rp1_eth: ethernet@40100000 {
|
|
#size-cells = <0>;
|
|
};
|
|
|
|
+ rp1_csi0: csi@40110000 {
|
|
+ compatible = "raspberrypi,rp1-cfe";
|
|
+ reg = <0x0 0x40110000 0x0 0x100>, // CSI2 DMA address
|
|
+ <0x0 0x40114000 0x0 0x100>, // PHY/CSI Host address
|
|
+ <0x0 0x40120000 0x0 0x100>, // MIPI CFG address
|
|
+ <0x0 0x40124000 0x0 0x1000>; // PiSP FE address
|
|
+ interrupts = <47 IRQ_TYPE_LEVEL_HIGH>;
|
|
+ clocks = <&rp1_clocks RP1_CLK_MIPI0_CFG>;
|
|
+ assigned-clocks = <&rp1_clocks RP1_CLK_MIPI0_CFG>;
|
|
+ assigned-clock-rates = <25000000>;
|
|
+
|
|
+ status = "disabled";
|
|
+ };
|
|
+
|
|
+ rp1_csi1: csi@40128000 {
|
|
+ compatible = "raspberrypi,rp1-cfe";
|
|
+ reg = <0x0 0x40128000 0x0 0x100>, // CSI2 DMA address
|
|
+ <0x0 0x4012c000 0x0 0x100>, // PHY/CSI Host address
|
|
+ <0x0 0x40138000 0x0 0x100>, // MIPI CFG address
|
|
+ <0x0 0x4013c000 0x0 0x1000>; // PiSP FE address
|
|
+ interrupts = <48 IRQ_TYPE_LEVEL_HIGH>;
|
|
+ clocks = <&rp1_clocks RP1_CLK_MIPI1_CFG>;
|
|
+ assigned-clocks = <&rp1_clocks RP1_CLK_MIPI1_CFG>;
|
|
+ assigned-clock-rates = <25000000>;
|
|
+
|
|
+ status = "disabled";
|
|
+ };
|
|
+
|
|
rp1_usb0: usb@40200000 {
|
|
compatible = "snps,dwc3";
|
|
reg = <0x00 0x40200000 0x0 0x100000>;
|
|
diff --git a/arch/arm64/boot/dts/freescale/Makefile b/arch/arm64/boot/dts/freescale/Makefile
|
|
index f30d3fd724d0c..c08e23545d4b6 100644
|
|
--- a/arch/arm64/boot/dts/freescale/Makefile
|
|
+++ b/arch/arm64/boot/dts/freescale/Makefile
|
|
@@ -376,6 +376,7 @@ imx93-9x9-qsb-i3c-dtbs += imx93-9x9-qsb.dtb imx93-9x9-qsb-i3c.dtbo
|
|
dtb-$(CONFIG_ARCH_MXC) += imx93-9x9-qsb-i3c.dtb
|
|
|
|
dtb-$(CONFIG_ARCH_MXC) += imx93-11x11-evk.dtb
|
|
+dtb-$(CONFIG_ARCH_MXC) += imx93-11x11-frdm.dtb
|
|
dtb-$(CONFIG_ARCH_MXC) += imx93-14x14-evk.dtb
|
|
dtb-$(CONFIG_ARCH_MXC) += imx93-kontron-bl-osm-s.dtb
|
|
dtb-$(CONFIG_ARCH_MXC) += imx93-phyboard-nash.dtb
|
|
diff --git a/arch/arm64/boot/dts/freescale/imx93-11x11-frdm.dts b/arch/arm64/boot/dts/freescale/imx93-11x11-frdm.dts
|
|
new file mode 100644
|
|
index 0000000000000..bd14ba28690c0
|
|
--- /dev/null
|
|
+++ b/arch/arm64/boot/dts/freescale/imx93-11x11-frdm.dts
|
|
@@ -0,0 +1,807 @@
|
|
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
|
|
+/dts-v1/;
|
|
+
|
|
+#include <dt-bindings/usb/pd.h>
|
|
+#include "imx93.dtsi"
|
|
+
|
|
+/ {
|
|
+ compatible = "fsl,imx93-11x11-frdm", "fsl,imx93";
|
|
+ model = "NXP i.MX93 11X11 FRDM board";
|
|
+
|
|
+ aliases {
|
|
+ can0 = &flexcan2;
|
|
+ ethernet0 = &fec;
|
|
+ ethernet1 = &eqos;
|
|
+ i2c0 = &lpi2c1;
|
|
+ i2c1 = &lpi2c2;
|
|
+ i2c2 = &lpi2c3;
|
|
+ mmc0 = &usdhc1; /* EMMC */
|
|
+ mmc1 = &usdhc2; /* uSD */
|
|
+ rtc0 = &pcf2131;
|
|
+ serial0 = &lpuart1;
|
|
+ serial4 = &lpuart5;
|
|
+ };
|
|
+
|
|
+ chosen {
|
|
+ stdout-path = &lpuart1;
|
|
+ };
|
|
+
|
|
+ flexcan2_phy: can-phy {
|
|
+ compatible = "nxp,tja1051";
|
|
+ #phy-cells = <0>;
|
|
+ max-bitrate = <5000000>;
|
|
+ silent-gpios = <&pcal6524 23 GPIO_ACTIVE_HIGH>;
|
|
+ };
|
|
+
|
|
+ gpio-keys {
|
|
+ compatible = "gpio-keys";
|
|
+
|
|
+ button-k2 {
|
|
+ label = "Button K2";
|
|
+ linux,code = <BTN_1>;
|
|
+ gpios = <&pcal6524 5 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>;
|
|
+ interrupt-parent = <&pcal6524>;
|
|
+ interrupts = <5 IRQ_TYPE_EDGE_FALLING>;
|
|
+ };
|
|
+
|
|
+ button-k3 {
|
|
+ label = "Button K3";
|
|
+ linux,code = <BTN_2>;
|
|
+ gpios = <&pcal6524 6 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>;
|
|
+ interrupt-parent = <&pcal6524>;
|
|
+ interrupts = <6 IRQ_TYPE_EDGE_FALLING>;
|
|
+ };
|
|
+ };
|
|
+
|
|
+ reg_usdhc2_vmmc: regulator-usdhc2 {
|
|
+ compatible = "regulator-fixed";
|
|
+ off-on-delay-us = <12000>;
|
|
+ pinctrl-0 = <&pinctrl_reg_usdhc2_vmmc>;
|
|
+ pinctrl-names = "default";
|
|
+ regulator-min-microvolt = <3300000>;
|
|
+ regulator-max-microvolt = <3300000>;
|
|
+ regulator-name = "VSD_3V3";
|
|
+ vin-supply = <&buck4>;
|
|
+ gpio = <&gpio3 7 GPIO_ACTIVE_HIGH>;
|
|
+ enable-active-high;
|
|
+ };
|
|
+
|
|
+ reg_usdhc3_vmmc: regulator-usdhc3 {
|
|
+ compatible = "regulator-fixed";
|
|
+ regulator-name = "VPCIe_3V3";
|
|
+ regulator-min-microvolt = <3300000>;
|
|
+ regulator-max-microvolt = <3300000>;
|
|
+ startup-delay-us = <20000>;
|
|
+ gpio = <&pcal6524 13 GPIO_ACTIVE_HIGH>;
|
|
+ enable-active-high;
|
|
+ };
|
|
+
|
|
+ reserved-memory {
|
|
+ ranges;
|
|
+ #address-cells = <2>;
|
|
+ #size-cells = <2>;
|
|
+
|
|
+ linux,cma {
|
|
+ compatible = "shared-dma-pool";
|
|
+ alloc-ranges = <0 0x80000000 0 0x30000000>;
|
|
+ reusable;
|
|
+ size = <0 0x10000000>;
|
|
+ linux,cma-default;
|
|
+ };
|
|
+
|
|
+ rsc_table: rsc-table@2021e000 {
|
|
+ reg = <0 0x2021e000 0 0x1000>;
|
|
+ no-map;
|
|
+ };
|
|
+
|
|
+ vdev0vring0: vdev0vring0@a4000000 {
|
|
+ reg = <0 0xa4000000 0 0x8000>;
|
|
+ no-map;
|
|
+ };
|
|
+
|
|
+ vdev0vring1: vdev0vring1@a4008000 {
|
|
+ reg = <0 0xa4008000 0 0x8000>;
|
|
+ no-map;
|
|
+ };
|
|
+
|
|
+ vdev1vring0: vdev1vring0@a4010000 {
|
|
+ reg = <0 0xa4010000 0 0x8000>;
|
|
+ no-map;
|
|
+ };
|
|
+
|
|
+ vdev1vring1: vdev1vring1@a4018000 {
|
|
+ reg = <0 0xa4018000 0 0x8000>;
|
|
+ no-map;
|
|
+ };
|
|
+
|
|
+ vdevbuffer: vdevbuffer@a4020000 {
|
|
+ compatible = "shared-dma-pool";
|
|
+ reg = <0 0xa4020000 0 0x100000>;
|
|
+ no-map;
|
|
+ };
|
|
+ };
|
|
+
|
|
+ sound-mqs {
|
|
+ compatible = "fsl,imx-audio-mqs";
|
|
+ model = "mqs-audio";
|
|
+ audio-cpu = <&sai1>;
|
|
+ audio-codec = <&mqs1>;
|
|
+ };
|
|
+
|
|
+ usdhc3_pwrseq: mmc-pwrseq {
|
|
+ compatible = "mmc-pwrseq-simple";
|
|
+ reset-gpios = <&pcal6524 12 GPIO_ACTIVE_LOW>;
|
|
+ };
|
|
+};
|
|
+
|
|
+&adc1 {
|
|
+ vref-supply = <&buck5>;
|
|
+ status = "okay";
|
|
+};
|
|
+
|
|
+&mu1 {
|
|
+ status = "okay";
|
|
+};
|
|
+
|
|
+&cm33 {
|
|
+ mboxes = <&mu1 0 1>,
|
|
+ <&mu1 1 1>,
|
|
+ <&mu1 3 1>;
|
|
+ mbox-names = "tx", "rx", "rxdb";
|
|
+ memory-region = <&vdevbuffer>, <&vdev0vring0>, <&vdev0vring1>,
|
|
+ <&vdev1vring0>, <&vdev1vring1>, <&rsc_table>;
|
|
+ status = "okay";
|
|
+};
|
|
+
|
|
+&eqos {
|
|
+ pinctrl-names = "default", "sleep";
|
|
+ pinctrl-0 = <&pinctrl_eqos>;
|
|
+ pinctrl-1 = <&pinctrl_eqos_sleep>;
|
|
+ phy-handle = <ðphy1>;
|
|
+ phy-mode = "rgmii-id";
|
|
+ status = "okay";
|
|
+
|
|
+ mdio {
|
|
+ compatible = "snps,dwmac-mdio";
|
|
+ #address-cells = <1>;
|
|
+ #size-cells = <0>;
|
|
+ clock-frequency = <5000000>;
|
|
+
|
|
+ ethphy1: ethernet-phy@1 {
|
|
+ reg = <1>;
|
|
+ reset-assert-us = <10000>;
|
|
+ reset-deassert-us = <80000>;
|
|
+ reset-gpios = <&pcal6524 15 GPIO_ACTIVE_LOW>;
|
|
+ realtek,clkout-disable;
|
|
+ };
|
|
+ };
|
|
+};
|
|
+
|
|
+&fec {
|
|
+ pinctrl-names = "default", "sleep";
|
|
+ pinctrl-0 = <&pinctrl_fec>;
|
|
+ pinctrl-1 = <&pinctrl_fec_sleep>;
|
|
+ phy-mode = "rgmii-id";
|
|
+ phy-handle = <ðphy2>;
|
|
+ fsl,magic-packet;
|
|
+ status = "okay";
|
|
+
|
|
+ mdio {
|
|
+ #address-cells = <1>;
|
|
+ #size-cells = <0>;
|
|
+ clock-frequency = <5000000>;
|
|
+
|
|
+ ethphy2: ethernet-phy@2 {
|
|
+ reg = <2>;
|
|
+ reset-assert-us = <10000>;
|
|
+ reset-deassert-us = <80000>;
|
|
+ reset-gpios = <&pcal6524 16 GPIO_ACTIVE_LOW>;
|
|
+ realtek,clkout-disable;
|
|
+ };
|
|
+ };
|
|
+};
|
|
+
|
|
+&flexcan2 {
|
|
+ phys = <&flexcan2_phy>;
|
|
+ pinctrl-0 = <&pinctrl_flexcan2>;
|
|
+ pinctrl-1 = <&pinctrl_flexcan2_sleep>;
|
|
+ pinctrl-names = "default", "sleep";
|
|
+ status = "okay";
|
|
+};
|
|
+
|
|
+&lpi2c1 {
|
|
+ clock-frequency = <400000>;
|
|
+ pinctrl-0 = <&pinctrl_lpi2c1>;
|
|
+ pinctrl-names = "default";
|
|
+ status = "okay";
|
|
+
|
|
+ pcal6408: gpio@20 {
|
|
+ compatible = "nxp,pcal6408";
|
|
+ reg = <0x20>;
|
|
+ #gpio-cells = <2>;
|
|
+ gpio-controller;
|
|
+ reset-gpios = <&pcal6524 20 GPIO_ACTIVE_LOW>;
|
|
+ };
|
|
+};
|
|
+
|
|
+&lpi2c2 {
|
|
+ clock-frequency = <400000>;
|
|
+ pinctrl-0 = <&pinctrl_lpi2c2>;
|
|
+ pinctrl-names = "default";
|
|
+ status = "okay";
|
|
+
|
|
+ pcal6524: gpio@22 {
|
|
+ compatible = "nxp,pcal6524";
|
|
+ reg = <0x22>;
|
|
+ #interrupt-cells = <2>;
|
|
+ interrupt-controller;
|
|
+ interrupt-parent = <&gpio3>;
|
|
+ interrupts = <27 IRQ_TYPE_LEVEL_LOW>;
|
|
+ #gpio-cells = <2>;
|
|
+ gpio-controller;
|
|
+ pinctrl-0 = <&pinctrl_pcal6524>;
|
|
+ pinctrl-names = "default";
|
|
+ /* does not boot with supplier set, because it is the bucks interrupt parent */
|
|
+ /* vcc-supply = <&buck4>; */
|
|
+ };
|
|
+
|
|
+ pmic@25 {
|
|
+ compatible = "nxp,pca9451a";
|
|
+ reg = <0x25>;
|
|
+ interrupt-parent = <&pcal6524>;
|
|
+ interrupts = <11 IRQ_TYPE_EDGE_FALLING>;
|
|
+
|
|
+ regulators {
|
|
+
|
|
+ buck1: BUCK1 {
|
|
+ regulator-name = "VDD_SOC_0V8";
|
|
+ regulator-min-microvolt = <610000>;
|
|
+ regulator-max-microvolt = <950000>;
|
|
+ regulator-always-on;
|
|
+ regulator-boot-on;
|
|
+ regulator-ramp-delay = <3125>;
|
|
+ };
|
|
+
|
|
+ buck2: BUCK2 {
|
|
+ regulator-name = "LPD4_x_VDDQ_0V6";
|
|
+ regulator-min-microvolt = <600000>;
|
|
+ regulator-max-microvolt = <670000>;
|
|
+ regulator-always-on;
|
|
+ regulator-boot-on;
|
|
+ regulator-ramp-delay = <3125>;
|
|
+ };
|
|
+
|
|
+ buck4: BUCK4 {
|
|
+ regulator-name = "VDD_3V3";
|
|
+ regulator-min-microvolt = <3300000>;
|
|
+ regulator-max-microvolt = <3300000>;
|
|
+ regulator-always-on;
|
|
+ regulator-boot-on;
|
|
+ };
|
|
+
|
|
+ buck5: BUCK5 {
|
|
+ regulator-name = "VDD_1V8";
|
|
+ regulator-min-microvolt = <1800000>;
|
|
+ regulator-max-microvolt = <1800000>;
|
|
+ regulator-always-on;
|
|
+ regulator-boot-on;
|
|
+ };
|
|
+
|
|
+ buck6: BUCK6 {
|
|
+ regulator-name = "LPD4_x_VDD2_1V1";
|
|
+ regulator-min-microvolt = <1060000>;
|
|
+ regulator-max-microvolt = <1140000>;
|
|
+ regulator-always-on;
|
|
+ regulator-boot-on;
|
|
+ };
|
|
+
|
|
+ ldo1: LDO1 {
|
|
+ regulator-name = "NVCC_BBSM_1V8";
|
|
+ regulator-min-microvolt = <1620000>;
|
|
+ regulator-max-microvolt = <1980000>;
|
|
+ regulator-always-on;
|
|
+ regulator-boot-on;
|
|
+ };
|
|
+
|
|
+ ldo4: LDO4 {
|
|
+ regulator-name = "VDD_ANA_0V8";
|
|
+ regulator-min-microvolt = <800000>;
|
|
+ regulator-max-microvolt = <840000>;
|
|
+ regulator-always-on;
|
|
+ regulator-boot-on;
|
|
+ };
|
|
+
|
|
+ ldo5: LDO5 {
|
|
+ regulator-name = "NVCC_SD";
|
|
+ regulator-min-microvolt = <1800000>;
|
|
+ regulator-max-microvolt = <3300000>;
|
|
+ regulator-always-on;
|
|
+ regulator-boot-on;
|
|
+ };
|
|
+ };
|
|
+ };
|
|
+
|
|
+ eeprom: eeprom@50 {
|
|
+ compatible = "atmel,24c256";
|
|
+ reg = <0x50>;
|
|
+ pagesize = <64>;
|
|
+ vcc-supply = <&buck4>;
|
|
+ };
|
|
+};
|
|
+
|
|
+&lpi2c3 {
|
|
+ clock-frequency = <400000>;
|
|
+ pinctrl-0 = <&pinctrl_lpi2c3>;
|
|
+ pinctrl-names = "default";
|
|
+ status = "okay";
|
|
+
|
|
+ ptn5110: tcpc@50 {
|
|
+ compatible = "nxp,ptn5110", "tcpci";
|
|
+ reg = <0x50>;
|
|
+ interrupt-parent = <&gpio3>;
|
|
+ interrupts = <27 IRQ_TYPE_LEVEL_LOW>;
|
|
+
|
|
+ typec1_con: connector {
|
|
+ compatible = "usb-c-connector";
|
|
+ data-role = "dual";
|
|
+ label = "USB-C";
|
|
+ op-sink-microwatt = <15000000>;
|
|
+ power-role = "dual";
|
|
+ self-powered;
|
|
+ sink-pdos = <PDO_FIXED(5000, 3000, PDO_FIXED_USB_COMM)
|
|
+ PDO_VAR(5000, 20000, 3000)>;
|
|
+ source-pdos = <PDO_FIXED(5000, 3000, PDO_FIXED_USB_COMM)>;
|
|
+ try-power-role = "sink";
|
|
+
|
|
+ ports {
|
|
+ #address-cells = <1>;
|
|
+ #size-cells = <0>;
|
|
+
|
|
+ port@0 {
|
|
+ reg = <0>;
|
|
+
|
|
+ typec1_dr_sw: endpoint {
|
|
+ remote-endpoint = <&usb1_drd_sw>;
|
|
+ };
|
|
+ };
|
|
+ };
|
|
+ };
|
|
+ };
|
|
+
|
|
+ pcf2131: rtc@53 {
|
|
+ compatible = "nxp,pcf2131";
|
|
+ reg = <0x53>;
|
|
+ interrupt-parent = <&pcal6524>;
|
|
+ interrupts = <1 IRQ_TYPE_EDGE_FALLING>;
|
|
+ };
|
|
+};
|
|
+
|
|
+&lpuart1 { /* console */
|
|
+ pinctrl-0 = <&pinctrl_uart1>;
|
|
+ pinctrl-names = "default";
|
|
+ status = "okay";
|
|
+};
|
|
+
|
|
+&lpuart5 {
|
|
+ pinctrl-0 = <&pinctrl_uart5>;
|
|
+ pinctrl-names = "default";
|
|
+ status = "okay";
|
|
+
|
|
+ uart-has-rtscts;
|
|
+
|
|
+ bluetooth {
|
|
+ compatible = "nxp,88w8987-bt";
|
|
+ device-wakeup-gpios = <&pcal6408 3 GPIO_ACTIVE_HIGH>;
|
|
+ reset-gpios = <&pcal6524 19 GPIO_ACTIVE_LOW>;
|
|
+ vcc-supply = <®_usdhc3_vmmc>;
|
|
+ };
|
|
+};
|
|
+
|
|
+&mqs1 {
|
|
+ pinctrl-names = "default";
|
|
+ pinctrl-0 = <&pinctrl_mqs1>;
|
|
+ clocks = <&clk IMX93_CLK_MQS1_GATE>;
|
|
+ clock-names = "mclk";
|
|
+ status = "okay";
|
|
+};
|
|
+
|
|
+&sai1 {
|
|
+ #sound-dai-cells = <0>;
|
|
+ clocks = <&clk IMX93_CLK_SAI1_IPG>, <&clk IMX93_CLK_DUMMY>,
|
|
+ <&clk IMX93_CLK_SAI1_GATE>, <&clk IMX93_CLK_DUMMY>,
|
|
+ <&clk IMX93_CLK_DUMMY>, <&clk IMX93_CLK_AUDIO_PLL>;
|
|
+ clock-names = "bus", "mclk0", "mclk1", "mclk2", "mclk3", "pll8k";
|
|
+ assigned-clocks = <&clk IMX93_CLK_SAI1>;
|
|
+ assigned-clock-parents = <&clk IMX93_CLK_AUDIO_PLL>;
|
|
+ assigned-clock-rates = <24576000>;
|
|
+ fsl,sai-mclk-direction-output;
|
|
+ status = "okay";
|
|
+};
|
|
+
|
|
+&usbotg1 {
|
|
+ adp-disable;
|
|
+ disable-over-current;
|
|
+ dr_mode = "otg";
|
|
+ hnp-disable;
|
|
+ srp-disable;
|
|
+ usb-role-switch;
|
|
+ samsung,picophy-dc-vol-level-adjust = <7>;
|
|
+ samsung,picophy-pre-emp-curr-control = <3>;
|
|
+ status = "okay";
|
|
+
|
|
+ port {
|
|
+ usb1_drd_sw: endpoint {
|
|
+ remote-endpoint = <&typec1_dr_sw>;
|
|
+ };
|
|
+ };
|
|
+};
|
|
+
|
|
+&usbotg2 {
|
|
+ disable-over-current;
|
|
+ dr_mode = "host";
|
|
+ samsung,picophy-dc-vol-level-adjust = <7>;
|
|
+ samsung,picophy-pre-emp-curr-control = <3>;
|
|
+ status = "okay";
|
|
+};
|
|
+
|
|
+&usdhc1 {
|
|
+ bus-width = <8>;
|
|
+ non-removable;
|
|
+ pinctrl-0 = <&pinctrl_usdhc1>;
|
|
+ pinctrl-1 = <&pinctrl_usdhc1_100mhz>;
|
|
+ pinctrl-2 = <&pinctrl_usdhc1_200mhz>;
|
|
+ pinctrl-names = "default", "state_100mhz", "state_200mhz";
|
|
+ vmmc-supply = <&buck4>;
|
|
+ status = "okay";
|
|
+};
|
|
+
|
|
+&usdhc2 {
|
|
+ bus-width = <4>;
|
|
+ cd-gpios = <&gpio3 00 GPIO_ACTIVE_LOW>;
|
|
+ no-mmc;
|
|
+ no-sdio;
|
|
+ pinctrl-0 = <&pinctrl_usdhc2>, <&pinctrl_usdhc2_gpio>;
|
|
+ pinctrl-1 = <&pinctrl_usdhc2_100mhz>, <&pinctrl_usdhc2_gpio>;
|
|
+ pinctrl-2 = <&pinctrl_usdhc2_200mhz>, <&pinctrl_usdhc2_gpio>;
|
|
+ pinctrl-3 = <&pinctrl_usdhc2_sleep>, <&pinctrl_usdhc2_gpio_sleep>;
|
|
+ pinctrl-names = "default", "state_100mhz", "state_200mhz", "sleep";
|
|
+ vmmc-supply = <®_usdhc2_vmmc>;
|
|
+ status = "okay";
|
|
+};
|
|
+
|
|
+&usdhc3 {
|
|
+ bus-width = <4>;
|
|
+ keep-power-in-suspend;
|
|
+ mmc-pwrseq = <&usdhc3_pwrseq>;
|
|
+ non-removable;
|
|
+ pinctrl-0 = <&pinctrl_usdhc3>;
|
|
+ pinctrl-1 = <&pinctrl_usdhc3_100mhz>;
|
|
+ pinctrl-2 = <&pinctrl_usdhc3_200mhz>;
|
|
+ pinctrl-3 = <&pinctrl_usdhc3_sleep>;
|
|
+ pinctrl-names = "default", "state_100mhz", "state_200mhz", "sleep";
|
|
+ vmmc-supply = <®_usdhc3_vmmc>;
|
|
+ status = "okay";
|
|
+};
|
|
+
|
|
+&wdog3 {
|
|
+ pinctrl-names = "default";
|
|
+ pinctrl-0 = <&pinctrl_wdog>;
|
|
+ fsl,ext-reset-output;
|
|
+ status = "okay";
|
|
+};
|
|
+
|
|
+&iomuxc {
|
|
+
|
|
+ pinctrl_eqos: eqosgrp {
|
|
+ fsl,pins = <
|
|
+ MX93_PAD_ENET1_MDC__ENET_QOS_MDC 0x57e
|
|
+ MX93_PAD_ENET1_MDIO__ENET_QOS_MDIO 0x57e
|
|
+ MX93_PAD_ENET1_RD0__ENET_QOS_RGMII_RD0 0x57e
|
|
+ MX93_PAD_ENET1_RD1__ENET_QOS_RGMII_RD1 0x57e
|
|
+ MX93_PAD_ENET1_RD2__ENET_QOS_RGMII_RD2 0x57e
|
|
+ MX93_PAD_ENET1_RD3__ENET_QOS_RGMII_RD3 0x57e
|
|
+ MX93_PAD_ENET1_RXC__CCM_ENET_QOS_CLOCK_GENERATE_RX_CLK 0x58e
|
|
+ MX93_PAD_ENET1_RX_CTL__ENET_QOS_RGMII_RX_CTL 0x57e
|
|
+ MX93_PAD_ENET1_TD0__ENET_QOS_RGMII_TD0 0x57e
|
|
+ MX93_PAD_ENET1_TD1__ENET_QOS_RGMII_TD1 0x57e
|
|
+ MX93_PAD_ENET1_TD2__ENET_QOS_RGMII_TD2 0x57e
|
|
+ MX93_PAD_ENET1_TD3__ENET_QOS_RGMII_TD3 0x57e
|
|
+ MX93_PAD_ENET1_TXC__CCM_ENET_QOS_CLOCK_GENERATE_TX_CLK 0x58e
|
|
+ MX93_PAD_ENET1_TX_CTL__ENET_QOS_RGMII_TX_CTL 0x57e
|
|
+ >;
|
|
+ };
|
|
+
|
|
+ pinctrl_eqos_sleep: eqossleepgrp {
|
|
+ fsl,pins = <
|
|
+ MX93_PAD_ENET1_MDC__GPIO4_IO00 0x31e
|
|
+ MX93_PAD_ENET1_MDIO__GPIO4_IO01 0x31e
|
|
+ MX93_PAD_ENET1_RD0__GPIO4_IO10 0x31e
|
|
+ MX93_PAD_ENET1_RD1__GPIO4_IO11 0x31e
|
|
+ MX93_PAD_ENET1_RD2__GPIO4_IO12 0x31e
|
|
+ MX93_PAD_ENET1_RD3__GPIO4_IO13 0x31e
|
|
+ MX93_PAD_ENET1_RXC__GPIO4_IO09 0x31e
|
|
+ MX93_PAD_ENET1_RX_CTL__GPIO4_IO08 0x31e
|
|
+ MX93_PAD_ENET1_TD0__GPIO4_IO05 0x31e
|
|
+ MX93_PAD_ENET1_TD1__GPIO4_IO04 0x31e
|
|
+ MX93_PAD_ENET1_TD2__GPIO4_IO03 0x31e
|
|
+ MX93_PAD_ENET1_TD3__GPIO4_IO02 0x31e
|
|
+ MX93_PAD_ENET1_TXC__GPIO4_IO07 0x31e
|
|
+ MX93_PAD_ENET1_TX_CTL__GPIO4_IO06 0x31e
|
|
+ >;
|
|
+ };
|
|
+
|
|
+ pinctrl_fec: fecgrp {
|
|
+ fsl,pins = <
|
|
+ MX93_PAD_ENET2_MDC__ENET1_MDC 0x57e
|
|
+ MX93_PAD_ENET2_MDIO__ENET1_MDIO 0x57e
|
|
+ MX93_PAD_ENET2_RD0__ENET1_RGMII_RD0 0x57e
|
|
+ MX93_PAD_ENET2_RD1__ENET1_RGMII_RD1 0x57e
|
|
+ MX93_PAD_ENET2_RD2__ENET1_RGMII_RD2 0x57e
|
|
+ MX93_PAD_ENET2_RD3__ENET1_RGMII_RD3 0x57e
|
|
+ MX93_PAD_ENET2_RXC__ENET1_RGMII_RXC 0x58e
|
|
+ MX93_PAD_ENET2_RX_CTL__ENET1_RGMII_RX_CTL 0x57e
|
|
+ MX93_PAD_ENET2_TD0__ENET1_RGMII_TD0 0x57e
|
|
+ MX93_PAD_ENET2_TD1__ENET1_RGMII_TD1 0x57e
|
|
+ MX93_PAD_ENET2_TD2__ENET1_RGMII_TD2 0x57e
|
|
+ MX93_PAD_ENET2_TD3__ENET1_RGMII_TD3 0x57e
|
|
+ MX93_PAD_ENET2_TXC__ENET1_RGMII_TXC 0x58e
|
|
+ MX93_PAD_ENET2_TX_CTL__ENET1_RGMII_TX_CTL 0x57e
|
|
+ >;
|
|
+ };
|
|
+
|
|
+ pinctrl_fec_sleep: fecsleepgrp {
|
|
+ fsl,pins = <
|
|
+ MX93_PAD_ENET2_MDC__GPIO4_IO14 0x51e
|
|
+ MX93_PAD_ENET2_MDIO__GPIO4_IO15 0x51e
|
|
+ MX93_PAD_ENET2_RD0__GPIO4_IO24 0x51e
|
|
+ MX93_PAD_ENET2_RD1__GPIO4_IO25 0x51e
|
|
+ MX93_PAD_ENET2_RD2__GPIO4_IO26 0x51e
|
|
+ MX93_PAD_ENET2_RD3__GPIO4_IO27 0x51e
|
|
+ MX93_PAD_ENET2_RXC__GPIO4_IO23 0x51e
|
|
+ MX93_PAD_ENET2_RX_CTL__GPIO4_IO22 0x51e
|
|
+ MX93_PAD_ENET2_TD0__GPIO4_IO19 0x51e
|
|
+ MX93_PAD_ENET2_TD1__GPIO4_IO18 0x51e
|
|
+ MX93_PAD_ENET2_TD2__GPIO4_IO17 0x51e
|
|
+ MX93_PAD_ENET2_TD3__GPIO4_IO16 0x51e
|
|
+ MX93_PAD_ENET2_TXC__GPIO4_IO21 0x51e
|
|
+ MX93_PAD_ENET2_TX_CTL__GPIO4_IO20 0x51e
|
|
+ >;
|
|
+ };
|
|
+
|
|
+ pinctrl_flexcan2: flexcan2grp {
|
|
+ fsl,pins = <
|
|
+ MX93_PAD_GPIO_IO25__CAN2_TX 0x139e
|
|
+ MX93_PAD_GPIO_IO27__CAN2_RX 0x139e
|
|
+ >;
|
|
+ };
|
|
+
|
|
+ pinctrl_flexcan2_sleep: flexcan2sleepgrp {
|
|
+ fsl,pins = <
|
|
+ MX93_PAD_GPIO_IO25__GPIO2_IO25 0x31e
|
|
+ MX93_PAD_GPIO_IO27__GPIO2_IO27 0x31e
|
|
+ >;
|
|
+ };
|
|
+
|
|
+ pinctrl_lpi2c1: lpi2c1grp {
|
|
+ fsl,pins = <
|
|
+ MX93_PAD_I2C1_SCL__LPI2C1_SCL 0x40000b9e
|
|
+ MX93_PAD_I2C1_SDA__LPI2C1_SDA 0x40000b9e
|
|
+ >;
|
|
+ };
|
|
+
|
|
+ pinctrl_lpi2c2: lpi2c2grp {
|
|
+ fsl,pins = <
|
|
+ MX93_PAD_I2C2_SCL__LPI2C2_SCL 0x40000b9e
|
|
+ MX93_PAD_I2C2_SDA__LPI2C2_SDA 0x40000b9e
|
|
+ >;
|
|
+ };
|
|
+
|
|
+ pinctrl_lpi2c3: lpi2c3grp {
|
|
+ fsl,pins = <
|
|
+ MX93_PAD_GPIO_IO28__LPI2C3_SDA 0x40000b9e
|
|
+ MX93_PAD_GPIO_IO29__LPI2C3_SCL 0x40000b9e
|
|
+ >;
|
|
+ };
|
|
+
|
|
+ pinctrl_mqs1: mqs1grp {
|
|
+ fsl,pins = <
|
|
+ MX93_PAD_PDM_CLK__MQS1_LEFT 0x31e
|
|
+ MX93_PAD_PDM_BIT_STREAM0__MQS1_RIGHT 0x31e
|
|
+ >;
|
|
+ };
|
|
+
|
|
+ pinctrl_pcal6524: pcal6524grp {
|
|
+ fsl,pins = <
|
|
+ MX93_PAD_CCM_CLKO2__GPIO3_IO27 0x31e
|
|
+ >;
|
|
+ };
|
|
+
|
|
+ pinctrl_reg_usdhc2_vmmc: regusdhc2vmmcgrp {
|
|
+ fsl,pins = <
|
|
+ MX93_PAD_SD2_RESET_B__GPIO3_IO07 0x31e
|
|
+ >;
|
|
+ };
|
|
+
|
|
+ pinctrl_uart1: uart1grp {
|
|
+ fsl,pins = <
|
|
+ MX93_PAD_UART1_RXD__LPUART1_RX 0x31e
|
|
+ MX93_PAD_UART1_TXD__LPUART1_TX 0x31e
|
|
+ >;
|
|
+ };
|
|
+
|
|
+ pinctrl_uart5: uart5grp {
|
|
+ fsl,pins = <
|
|
+ MX93_PAD_DAP_TDO_TRACESWO__LPUART5_TX 0x31e
|
|
+ MX93_PAD_DAP_TDI__LPUART5_RX 0x31e
|
|
+ MX93_PAD_DAP_TMS_SWDIO__LPUART5_RTS_B 0x31e
|
|
+ MX93_PAD_DAP_TCLK_SWCLK__LPUART5_CTS_B 0x31e
|
|
+ >;
|
|
+ };
|
|
+
|
|
+ /* need to config the SION for data and cmd pad, refer to ERR052021 */
|
|
+ pinctrl_usdhc1: usdhc1grp {
|
|
+ fsl,pins = <
|
|
+ MX93_PAD_SD1_CLK__USDHC1_CLK 0x1582
|
|
+ MX93_PAD_SD1_CMD__USDHC1_CMD 0x40001382
|
|
+ MX93_PAD_SD1_DATA0__USDHC1_DATA0 0x40001382
|
|
+ MX93_PAD_SD1_DATA1__USDHC1_DATA1 0x40001382
|
|
+ MX93_PAD_SD1_DATA2__USDHC1_DATA2 0x40001382
|
|
+ MX93_PAD_SD1_DATA3__USDHC1_DATA3 0x40001382
|
|
+ MX93_PAD_SD1_DATA4__USDHC1_DATA4 0x40001382
|
|
+ MX93_PAD_SD1_DATA5__USDHC1_DATA5 0x40001382
|
|
+ MX93_PAD_SD1_DATA6__USDHC1_DATA6 0x40001382
|
|
+ MX93_PAD_SD1_DATA7__USDHC1_DATA7 0x40001382
|
|
+ MX93_PAD_SD1_STROBE__USDHC1_STROBE 0x1582
|
|
+ >;
|
|
+ };
|
|
+
|
|
+ /* need to config the SION for data and cmd pad, refer to ERR052021 */
|
|
+ pinctrl_usdhc1_100mhz: usdhc1-100mhzgrp {
|
|
+ fsl,pins = <
|
|
+ MX93_PAD_SD1_CLK__USDHC1_CLK 0x158e
|
|
+ MX93_PAD_SD1_CMD__USDHC1_CMD 0x4000138e
|
|
+ MX93_PAD_SD1_DATA0__USDHC1_DATA0 0x4000138e
|
|
+ MX93_PAD_SD1_DATA1__USDHC1_DATA1 0x4000138e
|
|
+ MX93_PAD_SD1_DATA2__USDHC1_DATA2 0x4000138e
|
|
+ MX93_PAD_SD1_DATA3__USDHC1_DATA3 0x4000138e
|
|
+ MX93_PAD_SD1_DATA4__USDHC1_DATA4 0x4000138e
|
|
+ MX93_PAD_SD1_DATA5__USDHC1_DATA5 0x4000138e
|
|
+ MX93_PAD_SD1_DATA6__USDHC1_DATA6 0x4000138e
|
|
+ MX93_PAD_SD1_DATA7__USDHC1_DATA7 0x4000138e
|
|
+ MX93_PAD_SD1_STROBE__USDHC1_STROBE 0x158e
|
|
+ >;
|
|
+ };
|
|
+
|
|
+ /* need to config the SION for data and cmd pad, refer to ERR052021 */
|
|
+ pinctrl_usdhc1_200mhz: usdhc1-200mhzgrp {
|
|
+ fsl,pins = <
|
|
+ MX93_PAD_SD1_CLK__USDHC1_CLK 0x15fe
|
|
+ MX93_PAD_SD1_CMD__USDHC1_CMD 0x400013fe
|
|
+ MX93_PAD_SD1_DATA0__USDHC1_DATA0 0x400013fe
|
|
+ MX93_PAD_SD1_DATA1__USDHC1_DATA1 0x400013fe
|
|
+ MX93_PAD_SD1_DATA2__USDHC1_DATA2 0x400013fe
|
|
+ MX93_PAD_SD1_DATA3__USDHC1_DATA3 0x400013fe
|
|
+ MX93_PAD_SD1_DATA4__USDHC1_DATA4 0x400013fe
|
|
+ MX93_PAD_SD1_DATA5__USDHC1_DATA5 0x400013fe
|
|
+ MX93_PAD_SD1_DATA6__USDHC1_DATA6 0x400013fe
|
|
+ MX93_PAD_SD1_DATA7__USDHC1_DATA7 0x400013fe
|
|
+ MX93_PAD_SD1_STROBE__USDHC1_STROBE 0x15fe
|
|
+ >;
|
|
+ };
|
|
+
|
|
+ pinctrl_usdhc2_gpio: usdhc2gpiogrp {
|
|
+ fsl,pins = <
|
|
+ MX93_PAD_SD2_CD_B__GPIO3_IO00 0x31e
|
|
+ >;
|
|
+ };
|
|
+
|
|
+ pinctrl_usdhc2_gpio_sleep: usdhc2gpiosleepgrp {
|
|
+ fsl,pins = <
|
|
+ MX93_PAD_SD2_CD_B__GPIO3_IO00 0x51e
|
|
+ >;
|
|
+ };
|
|
+
|
|
+ /* need to config the SION for data and cmd pad, refer to ERR052021 */
|
|
+ pinctrl_usdhc2: usdhc2grp {
|
|
+ fsl,pins = <
|
|
+ MX93_PAD_SD2_CLK__USDHC2_CLK 0x1582
|
|
+ MX93_PAD_SD2_CMD__USDHC2_CMD 0x40001382
|
|
+ MX93_PAD_SD2_DATA0__USDHC2_DATA0 0x40001382
|
|
+ MX93_PAD_SD2_DATA1__USDHC2_DATA1 0x40001382
|
|
+ MX93_PAD_SD2_DATA2__USDHC2_DATA2 0x40001382
|
|
+ MX93_PAD_SD2_DATA3__USDHC2_DATA3 0x40001382
|
|
+ MX93_PAD_SD2_VSELECT__USDHC2_VSELECT 0x51e
|
|
+ >;
|
|
+ };
|
|
+
|
|
+ /* need to config the SION for data and cmd pad, refer to ERR052021 */
|
|
+ pinctrl_usdhc2_100mhz: usdhc2-100mhzgrp {
|
|
+ fsl,pins = <
|
|
+ MX93_PAD_SD2_CLK__USDHC2_CLK 0x158e
|
|
+ MX93_PAD_SD2_CMD__USDHC2_CMD 0x4000138e
|
|
+ MX93_PAD_SD2_DATA0__USDHC2_DATA0 0x4000138e
|
|
+ MX93_PAD_SD2_DATA1__USDHC2_DATA1 0x4000138e
|
|
+ MX93_PAD_SD2_DATA2__USDHC2_DATA2 0x4000138e
|
|
+ MX93_PAD_SD2_DATA3__USDHC2_DATA3 0x4000138e
|
|
+ MX93_PAD_SD2_VSELECT__USDHC2_VSELECT 0x51e
|
|
+ >;
|
|
+ };
|
|
+
|
|
+ /* need to config the SION for data and cmd pad, refer to ERR052021 */
|
|
+ pinctrl_usdhc2_200mhz: usdhc2-200mhzgrp {
|
|
+ fsl,pins = <
|
|
+ MX93_PAD_SD2_CLK__USDHC2_CLK 0x15fe
|
|
+ MX93_PAD_SD2_CMD__USDHC2_CMD 0x400013fe
|
|
+ MX93_PAD_SD2_DATA0__USDHC2_DATA0 0x400013fe
|
|
+ MX93_PAD_SD2_DATA1__USDHC2_DATA1 0x400013fe
|
|
+ MX93_PAD_SD2_DATA2__USDHC2_DATA2 0x400013fe
|
|
+ MX93_PAD_SD2_DATA3__USDHC2_DATA3 0x400013fe
|
|
+ MX93_PAD_SD2_VSELECT__USDHC2_VSELECT 0x51e
|
|
+ >;
|
|
+ };
|
|
+
|
|
+ pinctrl_usdhc2_sleep: usdhc2-sleepgrp {
|
|
+ fsl,pins = <
|
|
+ MX93_PAD_SD2_CLK__GPIO3_IO01 0x51e
|
|
+ MX93_PAD_SD2_CMD__GPIO3_IO02 0x51e
|
|
+ MX93_PAD_SD2_DATA0__GPIO3_IO03 0x51e
|
|
+ MX93_PAD_SD2_DATA1__GPIO3_IO04 0x51e
|
|
+ MX93_PAD_SD2_DATA2__GPIO3_IO05 0x51e
|
|
+ MX93_PAD_SD2_DATA3__GPIO3_IO06 0x51e
|
|
+ MX93_PAD_SD2_VSELECT__GPIO3_IO19 0x51e
|
|
+ >;
|
|
+ };
|
|
+
|
|
+ /* need to config the SION for data and cmd pad, refer to ERR052021 */
|
|
+ pinctrl_usdhc3: usdhc3grp {
|
|
+ fsl,pins = <
|
|
+ MX93_PAD_SD3_CLK__USDHC3_CLK 0x1582
|
|
+ MX93_PAD_SD3_CMD__USDHC3_CMD 0x40001382
|
|
+ MX93_PAD_SD3_DATA0__USDHC3_DATA0 0x40001382
|
|
+ MX93_PAD_SD3_DATA1__USDHC3_DATA1 0x40001382
|
|
+ MX93_PAD_SD3_DATA2__USDHC3_DATA2 0x40001382
|
|
+ MX93_PAD_SD3_DATA3__USDHC3_DATA3 0x40001382
|
|
+ >;
|
|
+ };
|
|
+
|
|
+ /* need to config the SION for data and cmd pad, refer to ERR052021 */
|
|
+ pinctrl_usdhc3_100mhz: usdhc3-100mhzgrp {
|
|
+ fsl,pins = <
|
|
+ MX93_PAD_SD3_CLK__USDHC3_CLK 0x158e
|
|
+ MX93_PAD_SD3_CMD__USDHC3_CMD 0x4000138e
|
|
+ MX93_PAD_SD3_DATA0__USDHC3_DATA0 0x4000138e
|
|
+ MX93_PAD_SD3_DATA1__USDHC3_DATA1 0x4000138e
|
|
+ MX93_PAD_SD3_DATA2__USDHC3_DATA2 0x4000138e
|
|
+ MX93_PAD_SD3_DATA3__USDHC3_DATA3 0x4000138e
|
|
+ >;
|
|
+ };
|
|
+
|
|
+ /* need to config the SION for data and cmd pad, refer to ERR052021 */
|
|
+ pinctrl_usdhc3_200mhz: usdhc3-200mhzgrp {
|
|
+ fsl,pins = <
|
|
+ MX93_PAD_SD3_CLK__USDHC3_CLK 0x15fe
|
|
+ MX93_PAD_SD3_CMD__USDHC3_CMD 0x400013fe
|
|
+ MX93_PAD_SD3_DATA0__USDHC3_DATA0 0x400013fe
|
|
+ MX93_PAD_SD3_DATA1__USDHC3_DATA1 0x400013fe
|
|
+ MX93_PAD_SD3_DATA2__USDHC3_DATA2 0x400013fe
|
|
+ MX93_PAD_SD3_DATA3__USDHC3_DATA3 0x400013fe
|
|
+ >;
|
|
+ };
|
|
+
|
|
+ pinctrl_usdhc3_sleep: usdhc3grpsleepgrp {
|
|
+ fsl,pins = <
|
|
+ MX93_PAD_SD3_CLK__GPIO3_IO20 0x31e
|
|
+ MX93_PAD_SD3_CMD__GPIO3_IO21 0x31e
|
|
+ MX93_PAD_SD3_DATA0__GPIO3_IO22 0x31e
|
|
+ MX93_PAD_SD3_DATA1__GPIO3_IO23 0x31e
|
|
+ MX93_PAD_SD3_DATA2__GPIO3_IO24 0x31e
|
|
+ MX93_PAD_SD3_DATA3__GPIO3_IO25 0x31e
|
|
+ >;
|
|
+ };
|
|
+
|
|
+ pinctrl_wdog: wdoggrp {
|
|
+ fsl,pins = <
|
|
+ MX93_PAD_WDOG_ANY__WDOG1_WDOG_ANY 0x31e
|
|
+ >;
|
|
+ };
|
|
+};
|
|
diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
|
|
index 23c05dc7a8f2a..d7b7b2f39e169 100644
|
|
--- a/arch/arm64/kernel/setup.c
|
|
+++ b/arch/arm64/kernel/setup.c
|
|
@@ -32,6 +32,8 @@
|
|
#include <linux/sched/task.h>
|
|
#include <linux/scs.h>
|
|
#include <linux/mm.h>
|
|
+#include <linux/security.h>
|
|
+#include <linux/libfdt.h>
|
|
|
|
#include <asm/acpi.h>
|
|
#include <asm/fixmap.h>
|
|
@@ -207,6 +209,24 @@ static void __init setup_machine_fdt(phys_addr_t dt_phys)
|
|
dump_stack_set_arch_desc("%s (DT)", name);
|
|
}
|
|
|
|
+static void __init init_secureboot_mode(void)
|
|
+{
|
|
+ void *fdt = initial_boot_params;
|
|
+ u64 chosen;
|
|
+ const __be32 *prop;
|
|
+ int len;
|
|
+
|
|
+ chosen = fdt_path_offset(fdt, "/chosen");
|
|
+ if (chosen < 0)
|
|
+ return;
|
|
+
|
|
+ prop = fdt_getprop(fdt, chosen, "secure-boot-mode", &len);
|
|
+ if (!prop || len != sizeof(u32))
|
|
+ return;
|
|
+
|
|
+ efi_set_secure_boot((enum efi_secureboot_mode)fdt32_to_cpu(*prop));
|
|
+}
|
|
+
|
|
static void __init request_standard_resources(void)
|
|
{
|
|
struct memblock_region *region;
|
|
@@ -327,6 +347,13 @@ void __init __no_sanitize_address setup_arch(char **cmdline_p)
|
|
pr_warn(FW_BUG "Kernel image misaligned at boot, please fix your bootloader!");
|
|
WARN_TAINT(mmu_enabled_at_boot, TAINT_FIRMWARE_WORKAROUND,
|
|
FW_BUG "Booted with MMU enabled!");
|
|
+ } else {
|
|
+ init_secureboot_mode();
|
|
+
|
|
+#ifdef CONFIG_LOCK_DOWN_IN_EFI_SECURE_BOOT
|
|
+ if (efi_enabled(EFI_SECURE_BOOT))
|
|
+ security_lock_kernel_down("EFI Secure Boot mode", LOCKDOWN_INTEGRITY_MAX);
|
|
+#endif
|
|
}
|
|
|
|
arm64_memblock_init();
|
|
diff --git a/arch/s390/include/asm/ipl.h b/arch/s390/include/asm/ipl.h
|
|
index b0d00032479d6..afb9544fb0074 100644
|
|
--- a/arch/s390/include/asm/ipl.h
|
|
+++ b/arch/s390/include/asm/ipl.h
|
|
@@ -139,6 +139,7 @@ int ipl_report_add_component(struct ipl_report *report, struct kexec_buf *kbuf,
|
|
unsigned char flags, unsigned short cert);
|
|
int ipl_report_add_certificate(struct ipl_report *report, void *key,
|
|
unsigned long addr, unsigned long len);
|
|
+bool ipl_get_secureboot(void);
|
|
|
|
/*
|
|
* DIAG 308 support
|
|
diff --git a/arch/s390/kernel/ipl.c b/arch/s390/kernel/ipl.c
|
|
index 049c557c452ff..4c9fffbe62613 100644
|
|
--- a/arch/s390/kernel/ipl.c
|
|
+++ b/arch/s390/kernel/ipl.c
|
|
@@ -2521,3 +2521,8 @@ int ipl_report_free(struct ipl_report *report)
|
|
}
|
|
|
|
#endif
|
|
+
|
|
+bool ipl_get_secureboot(void)
|
|
+{
|
|
+ return !!ipl_secure_flag;
|
|
+}
|
|
diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c
|
|
index c1fe0b53c5ac5..8e17bfe788cb9 100644
|
|
--- a/arch/s390/kernel/setup.c
|
|
+++ b/arch/s390/kernel/setup.c
|
|
@@ -47,6 +47,7 @@
|
|
#include <linux/crash_dump.h>
|
|
#include <linux/memory.h>
|
|
#include <linux/start_kernel.h>
|
|
+#include <linux/security.h>
|
|
#include <linux/hugetlb.h>
|
|
#include <linux/kmemleak.h>
|
|
|
|
@@ -917,6 +918,9 @@ void __init setup_arch(char **cmdline_p)
|
|
|
|
log_component_list();
|
|
|
|
+ if (ipl_get_secureboot())
|
|
+ security_lock_kernel_down("Secure IPL mode", LOCKDOWN_INTEGRITY_MAX);
|
|
+
|
|
/* Have one command line that is parsed and saved in /proc/cmdline */
|
|
/* boot_command_line has been already set up in early.c */
|
|
*cmdline_p = boot_command_line;
|
|
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
|
|
index 383d4a4784f5b..45f428436e2d9 100644
|
|
--- a/arch/x86/kernel/setup.c
|
|
+++ b/arch/x86/kernel/setup.c
|
|
@@ -21,6 +21,7 @@
|
|
#include <linux/pci.h>
|
|
#include <linux/random.h>
|
|
#include <linux/root_dev.h>
|
|
+#include <linux/security.h>
|
|
#include <linux/static_call.h>
|
|
#include <linux/swiotlb.h>
|
|
#include <linux/tboot.h>
|
|
@@ -997,6 +998,13 @@ void __init setup_arch(char **cmdline_p)
|
|
if (efi_enabled(EFI_BOOT))
|
|
efi_init();
|
|
|
|
+ efi_set_secure_boot(boot_params.secure_boot);
|
|
+
|
|
+#ifdef CONFIG_LOCK_DOWN_IN_EFI_SECURE_BOOT
|
|
+ if (efi_enabled(EFI_SECURE_BOOT))
|
|
+ security_lock_kernel_down("EFI Secure Boot mode", LOCKDOWN_INTEGRITY_MAX);
|
|
+#endif
|
|
+
|
|
reserve_ibft_region();
|
|
x86_init.resources.dmi_setup();
|
|
|
|
@@ -1160,19 +1168,7 @@ void __init setup_arch(char **cmdline_p)
|
|
/* Allocate bigger log buffer */
|
|
setup_log_buf(1);
|
|
|
|
- if (efi_enabled(EFI_BOOT)) {
|
|
- switch (boot_params.secure_boot) {
|
|
- case efi_secureboot_mode_disabled:
|
|
- pr_info("Secure boot disabled\n");
|
|
- break;
|
|
- case efi_secureboot_mode_enabled:
|
|
- pr_info("Secure boot enabled\n");
|
|
- break;
|
|
- default:
|
|
- pr_info("Secure boot could not be determined\n");
|
|
- break;
|
|
- }
|
|
- }
|
|
+ efi_set_secure_boot(boot_params.secure_boot);
|
|
|
|
reserve_initrd();
|
|
|
|
diff --git a/crypto/akcipher.c b/crypto/akcipher.c
|
|
index a36f50c838278..f4f421e6cff20 100644
|
|
--- a/crypto/akcipher.c
|
|
+++ b/crypto/akcipher.c
|
|
@@ -142,8 +142,7 @@ int crypto_register_akcipher(struct akcipher_alg *alg)
|
|
|
|
if (!alg->encrypt)
|
|
alg->encrypt = akcipher_default_op;
|
|
- if (!alg->decrypt)
|
|
- alg->decrypt = akcipher_default_op;
|
|
+ alg->decrypt = akcipher_default_op;
|
|
if (!alg->set_priv_key)
|
|
alg->set_priv_key = akcipher_default_set_key;
|
|
|
|
diff --git a/crypto/dh.c b/crypto/dh.c
|
|
index 8250eeeebd0fe..01f0f3963a740 100644
|
|
--- a/crypto/dh.c
|
|
+++ b/crypto/dh.c
|
|
@@ -227,10 +227,35 @@ static int dh_compute_value(struct kpp_request *req)
|
|
|
|
/* SP800-56A rev 3 5.6.2.1.3 key check */
|
|
} else {
|
|
+ MPI val_pct;
|
|
+
|
|
if (dh_is_pubkey_valid(ctx, val)) {
|
|
ret = -EAGAIN;
|
|
goto err_free_val;
|
|
}
|
|
+
|
|
+ /*
|
|
+ * SP800-56Arev3, 5.6.2.1.4: ("Owner Assurance
|
|
+ * of Pair-wise Consistency"): recompute the
|
|
+ * public key and check if the results match.
|
|
+ */
|
|
+ val_pct = mpi_alloc(0);
|
|
+ if (!val_pct) {
|
|
+ ret = -ENOMEM;
|
|
+ goto err_free_val;
|
|
+ }
|
|
+
|
|
+ ret = _compute_val(ctx, base, val_pct);
|
|
+ if (ret) {
|
|
+ mpi_free(val_pct);
|
|
+ goto err_free_val;
|
|
+ }
|
|
+
|
|
+ if (mpi_cmp(val, val_pct) != 0) {
|
|
+ fips_fail_notify();
|
|
+ panic("dh: pair-wise consistency test failed\n");
|
|
+ }
|
|
+ mpi_free(val_pct);
|
|
}
|
|
}
|
|
|
|
diff --git a/crypto/seqiv.c b/crypto/seqiv.c
|
|
index 678bb4145d783..fcc059e7d3db5 100644
|
|
--- a/crypto/seqiv.c
|
|
+++ b/crypto/seqiv.c
|
|
@@ -123,6 +123,19 @@ static int seqiv_aead_decrypt(struct aead_request *req)
|
|
return crypto_aead_decrypt(subreq);
|
|
}
|
|
|
|
+static int aead_init_seqiv(struct crypto_aead *aead)
|
|
+{
|
|
+ int err;
|
|
+
|
|
+ err = aead_init_geniv(aead);
|
|
+ if (err)
|
|
+ return err;
|
|
+
|
|
+ crypto_aead_set_flags(aead, CRYPTO_TFM_FIPS_COMPLIANCE);
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
static int seqiv_aead_create(struct crypto_template *tmpl, struct rtattr **tb)
|
|
{
|
|
struct aead_instance *inst;
|
|
@@ -140,7 +153,7 @@ static int seqiv_aead_create(struct crypto_template *tmpl, struct rtattr **tb)
|
|
inst->alg.encrypt = seqiv_aead_encrypt;
|
|
inst->alg.decrypt = seqiv_aead_decrypt;
|
|
|
|
- inst->alg.init = aead_init_geniv;
|
|
+ inst->alg.init = aead_init_seqiv;
|
|
inst->alg.exit = aead_exit_geniv;
|
|
|
|
inst->alg.base.cra_ctxsize = sizeof(struct aead_geniv_ctx);
|
|
diff --git a/crypto/sig.c b/crypto/sig.c
|
|
index beba745b64057..fd41f6d3abf9a 100644
|
|
--- a/crypto/sig.c
|
|
+++ b/crypto/sig.c
|
|
@@ -112,8 +112,7 @@ static int sig_prepare_alg(struct sig_alg *alg)
|
|
{
|
|
struct crypto_alg *base = &alg->base;
|
|
|
|
- if (!alg->sign)
|
|
- alg->sign = sig_default_sign;
|
|
+ alg->sign = sig_default_sign;
|
|
if (!alg->verify)
|
|
alg->verify = sig_default_verify;
|
|
if (!alg->set_priv_key)
|
|
diff --git a/crypto/testmgr.c b/crypto/testmgr.c
|
|
index a302be53896d3..ade6307dbf899 100644
|
|
--- a/crypto/testmgr.c
|
|
+++ b/crypto/testmgr.c
|
|
@@ -3843,7 +3843,7 @@ static int test_akcipher_one(struct crypto_akcipher *tfm,
|
|
* Don't invoke decrypt test which requires a private key
|
|
* for vectors with only a public key.
|
|
*/
|
|
- if (vecs->public_key_vec) {
|
|
+ if (1 || vecs->public_key_vec) {
|
|
err = 0;
|
|
goto free_all;
|
|
}
|
|
@@ -3979,7 +3979,7 @@ static int test_sig_one(struct crypto_sig *tfm, const struct sig_testvec *vecs)
|
|
* Don't invoke sign test (which requires a private key)
|
|
* for vectors with only a public key.
|
|
*/
|
|
- if (vecs->public_key_vec)
|
|
+ if (1 || vecs->public_key_vec)
|
|
return 0;
|
|
|
|
sig_size = crypto_sig_maxsize(tfm);
|
|
@@ -4835,14 +4835,12 @@ static const struct alg_test_desc alg_test_descs[] = {
|
|
}, {
|
|
.alg = "ecdh-nist-p256",
|
|
.test = alg_test_kpp,
|
|
- .fips_allowed = 1,
|
|
.suite = {
|
|
.kpp = __VECS(ecdh_p256_tv_template)
|
|
}
|
|
}, {
|
|
.alg = "ecdh-nist-p384",
|
|
.test = alg_test_kpp,
|
|
- .fips_allowed = 1,
|
|
.suite = {
|
|
.kpp = __VECS(ecdh_p384_tv_template)
|
|
}
|
|
diff --git a/drivers/acpi/apei/hest.c b/drivers/acpi/apei/hest.c
|
|
index 20d757687e3d9..90a13f20f052b 100644
|
|
--- a/drivers/acpi/apei/hest.c
|
|
+++ b/drivers/acpi/apei/hest.c
|
|
@@ -142,6 +142,14 @@ static int apei_hest_parse(apei_hest_func_t func, void *data)
|
|
if (hest_disable || !hest_tab)
|
|
return -EINVAL;
|
|
|
|
+#ifdef CONFIG_ARM64
|
|
+ /* Ignore broken firmware */
|
|
+ if (!strncmp(hest_tab->header.oem_id, "HPE ", 6) &&
|
|
+ !strncmp(hest_tab->header.oem_table_id, "ProLiant", 8) &&
|
|
+ MIDR_IMPLEMENTOR(read_cpuid_id()) == ARM_CPU_IMP_APM)
|
|
+ return -EINVAL;
|
|
+#endif
|
|
+
|
|
hest_hdr = (struct acpi_hest_header *)(hest_tab + 1);
|
|
for (i = 0; i < hest_tab->error_source_count; i++) {
|
|
len = hest_esrc_len(hest_hdr);
|
|
diff --git a/drivers/acpi/irq.c b/drivers/acpi/irq.c
|
|
index d1595156c86a4..9485212f1a6d6 100644
|
|
--- a/drivers/acpi/irq.c
|
|
+++ b/drivers/acpi/irq.c
|
|
@@ -143,6 +143,7 @@ struct acpi_irq_parse_one_ctx {
|
|
unsigned int index;
|
|
unsigned long *res_flags;
|
|
struct irq_fwspec *fwspec;
|
|
+ bool skip_producer_check;
|
|
};
|
|
|
|
/**
|
|
@@ -216,7 +217,8 @@ static acpi_status acpi_irq_parse_one_cb(struct acpi_resource *ares,
|
|
return AE_CTRL_TERMINATE;
|
|
case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
|
|
eirq = &ares->data.extended_irq;
|
|
- if (eirq->producer_consumer == ACPI_PRODUCER)
|
|
+ if (!ctx->skip_producer_check &&
|
|
+ eirq->producer_consumer == ACPI_PRODUCER)
|
|
return AE_OK;
|
|
if (ctx->index >= eirq->interrupt_count) {
|
|
ctx->index -= eirq->interrupt_count;
|
|
@@ -252,8 +254,19 @@ static acpi_status acpi_irq_parse_one_cb(struct acpi_resource *ares,
|
|
static int acpi_irq_parse_one(acpi_handle handle, unsigned int index,
|
|
struct irq_fwspec *fwspec, unsigned long *flags)
|
|
{
|
|
- struct acpi_irq_parse_one_ctx ctx = { -EINVAL, index, flags, fwspec };
|
|
+ struct acpi_irq_parse_one_ctx ctx = { -EINVAL, index, flags, fwspec, false };
|
|
|
|
+ /*
|
|
+ * Firmware on arm64-based HPE m400 platform incorrectly marks
|
|
+ * its UART interrupt as ACPI_PRODUCER rather than ACPI_CONSUMER.
|
|
+ * Don't do the producer/consumer check for that device.
|
|
+ */
|
|
+ if (IS_ENABLED(CONFIG_ARM64)) {
|
|
+ struct acpi_device *adev = acpi_get_acpi_dev(handle);
|
|
+
|
|
+ if (adev && !strcmp(acpi_device_hid(adev), "APMC0D08"))
|
|
+ ctx.skip_producer_check = true;
|
|
+ }
|
|
acpi_walk_resources(handle, METHOD_NAME__CRS, acpi_irq_parse_one_cb, &ctx);
|
|
return ctx.rc;
|
|
}
|
|
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
|
|
index b78f6be2f9468..8bf534f6f8933 100644
|
|
--- a/drivers/acpi/scan.c
|
|
+++ b/drivers/acpi/scan.c
|
|
@@ -1803,6 +1803,15 @@ static bool acpi_device_enumeration_by_parent(struct acpi_device *device)
|
|
if (!acpi_match_device_ids(device, ignore_serial_bus_ids))
|
|
return false;
|
|
|
|
+ /*
|
|
+ * Firmware on some arm64 X-Gene platforms will make the UART
|
|
+ * device appear as both a UART and a slave of that UART. Just
|
|
+ * bail out here for X-Gene UARTs.
|
|
+ */
|
|
+ if (IS_ENABLED(CONFIG_ARM64) &&
|
|
+ !strcmp(acpi_device_hid(device), "APMC0D08"))
|
|
+ return false;
|
|
+
|
|
INIT_LIST_HEAD(&resource_list);
|
|
acpi_dev_get_resources(device, &resource_list,
|
|
acpi_check_serial_bus_slave,
|
|
diff --git a/drivers/ata/libahci.c b/drivers/ata/libahci.c
|
|
index c79abdfcd7a9b..e23bfb7f94c72 100644
|
|
--- a/drivers/ata/libahci.c
|
|
+++ b/drivers/ata/libahci.c
|
|
@@ -731,6 +731,24 @@ int ahci_stop_engine(struct ata_port *ap)
|
|
tmp &= ~PORT_CMD_START;
|
|
writel(tmp, port_mmio + PORT_CMD);
|
|
|
|
+#ifdef CONFIG_ARM64
|
|
+ /* Rev Ax of Cavium CN99XX needs a hack for port stop */
|
|
+ if (dev_is_pci(ap->host->dev) &&
|
|
+ to_pci_dev(ap->host->dev)->vendor == 0x14e4 &&
|
|
+ to_pci_dev(ap->host->dev)->device == 0x9027 &&
|
|
+ midr_is_cpu_model_range(read_cpuid_id(),
|
|
+ MIDR_CPU_MODEL(ARM_CPU_IMP_BRCM, BRCM_CPU_PART_VULCAN),
|
|
+ MIDR_CPU_VAR_REV(0, 0),
|
|
+ MIDR_CPU_VAR_REV(0, MIDR_REVISION_MASK))) {
|
|
+ tmp = readl(hpriv->mmio + 0x8000);
|
|
+ udelay(100);
|
|
+ writel(tmp | (1 << 26), hpriv->mmio + 0x8000);
|
|
+ udelay(100);
|
|
+ writel(tmp & ~(1 << 26), hpriv->mmio + 0x8000);
|
|
+ dev_warn(ap->host->dev, "CN99XX SATA reset workaround applied\n");
|
|
+ }
|
|
+#endif
|
|
+
|
|
/* wait for engine to stop. This could be as long as 500 msec */
|
|
tmp = ata_wait_register(ap, port_mmio + PORT_CMD,
|
|
PORT_CMD_LIST_ON, PORT_CMD_LIST_ON, 1, 500);
|
|
diff --git a/drivers/firmware/efi/Makefile b/drivers/firmware/efi/Makefile
|
|
index 8efbcf699e4ff..96d5a1ca981df 100644
|
|
--- a/drivers/firmware/efi/Makefile
|
|
+++ b/drivers/firmware/efi/Makefile
|
|
@@ -25,6 +25,7 @@ subdir-$(CONFIG_EFI_STUB) += libstub
|
|
obj-$(CONFIG_EFI_BOOTLOADER_CONTROL) += efibc.o
|
|
obj-$(CONFIG_EFI_TEST) += test/
|
|
obj-$(CONFIG_EFI_DEV_PATH_PARSER) += dev-path-parser.o
|
|
+obj-$(CONFIG_EFI) += secureboot.o
|
|
obj-$(CONFIG_APPLE_PROPERTIES) += apple-properties.o
|
|
obj-$(CONFIG_EFI_RCI2_TABLE) += rci2-table.o
|
|
obj-$(CONFIG_EFI_EMBEDDED_FIRMWARE) += embedded-firmware.o
|
|
diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c
|
|
index 92e91c3eb4690..aa4845ea0acb3 100644
|
|
--- a/drivers/firmware/efi/efi.c
|
|
+++ b/drivers/firmware/efi/efi.c
|
|
@@ -33,6 +33,7 @@
|
|
#include <linux/memblock.h>
|
|
#include <linux/security.h>
|
|
#include <linux/notifier.h>
|
|
+#include <linux/bsearch.h>
|
|
|
|
#include <asm/early_ioremap.h>
|
|
|
|
@@ -1021,40 +1022,101 @@ int efi_mem_type(unsigned long phys_addr)
|
|
return -EINVAL;
|
|
}
|
|
|
|
+struct efi_error_code {
|
|
+ efi_status_t status;
|
|
+ int errno;
|
|
+ const char *description;
|
|
+};
|
|
+
|
|
+static const struct efi_error_code efi_error_codes[] = {
|
|
+ { EFI_SUCCESS, 0, "Success"},
|
|
+#if 0
|
|
+ { EFI_LOAD_ERROR, -EPICK_AN_ERRNO, "Load Error"},
|
|
+#endif
|
|
+ { EFI_INVALID_PARAMETER, -EINVAL, "Invalid Parameter"},
|
|
+ { EFI_UNSUPPORTED, -ENOSYS, "Unsupported"},
|
|
+ { EFI_BAD_BUFFER_SIZE, -ENOSPC, "Bad Buffer Size"},
|
|
+ { EFI_BUFFER_TOO_SMALL, -ENOSPC, "Buffer Too Small"},
|
|
+ { EFI_NOT_READY, -EAGAIN, "Not Ready"},
|
|
+ { EFI_DEVICE_ERROR, -EIO, "Device Error"},
|
|
+ { EFI_WRITE_PROTECTED, -EROFS, "Write Protected"},
|
|
+ { EFI_OUT_OF_RESOURCES, -ENOMEM, "Out of Resources"},
|
|
+#if 0
|
|
+ { EFI_VOLUME_CORRUPTED, -EPICK_AN_ERRNO, "Volume Corrupt"},
|
|
+ { EFI_VOLUME_FULL, -EPICK_AN_ERRNO, "Volume Full"},
|
|
+ { EFI_NO_MEDIA, -EPICK_AN_ERRNO, "No Media"},
|
|
+ { EFI_MEDIA_CHANGED, -EPICK_AN_ERRNO, "Media changed"},
|
|
+#endif
|
|
+ { EFI_NOT_FOUND, -ENOENT, "Not Found"},
|
|
+#if 0
|
|
+ { EFI_ACCESS_DENIED, -EPICK_AN_ERRNO, "Access Denied"},
|
|
+ { EFI_NO_RESPONSE, -EPICK_AN_ERRNO, "No Response"},
|
|
+ { EFI_NO_MAPPING, -EPICK_AN_ERRNO, "No mapping"},
|
|
+ { EFI_TIMEOUT, -EPICK_AN_ERRNO, "Time out"},
|
|
+ { EFI_NOT_STARTED, -EPICK_AN_ERRNO, "Not started"},
|
|
+ { EFI_ALREADY_STARTED, -EPICK_AN_ERRNO, "Already started"},
|
|
+#endif
|
|
+ { EFI_ABORTED, -EINTR, "Aborted"},
|
|
+#if 0
|
|
+ { EFI_ICMP_ERROR, -EPICK_AN_ERRNO, "ICMP Error"},
|
|
+ { EFI_TFTP_ERROR, -EPICK_AN_ERRNO, "TFTP Error"},
|
|
+ { EFI_PROTOCOL_ERROR, -EPICK_AN_ERRNO, "Protocol Error"},
|
|
+ { EFI_INCOMPATIBLE_VERSION, -EPICK_AN_ERRNO, "Incompatible Version"},
|
|
+#endif
|
|
+ { EFI_SECURITY_VIOLATION, -EACCES, "Security Policy Violation"},
|
|
+#if 0
|
|
+ { EFI_CRC_ERROR, -EPICK_AN_ERRNO, "CRC Error"},
|
|
+ { EFI_END_OF_MEDIA, -EPICK_AN_ERRNO, "End of Media"},
|
|
+ { EFI_END_OF_FILE, -EPICK_AN_ERRNO, "End of File"},
|
|
+ { EFI_INVALID_LANGUAGE, -EPICK_AN_ERRNO, "Invalid Languages"},
|
|
+ { EFI_COMPROMISED_DATA, -EPICK_AN_ERRNO, "Compromised Data"},
|
|
+
|
|
+ // warnings
|
|
+ { EFI_WARN_UNKOWN_GLYPH, -EPICK_AN_ERRNO, "Warning Unknown Glyph"},
|
|
+ { EFI_WARN_DELETE_FAILURE, -EPICK_AN_ERRNO, "Warning Delete Failure"},
|
|
+ { EFI_WARN_WRITE_FAILURE, -EPICK_AN_ERRNO, "Warning Write Failure"},
|
|
+ { EFI_WARN_BUFFER_TOO_SMALL, -EPICK_AN_ERRNO, "Warning Buffer Too Small"},
|
|
+#endif
|
|
+};
|
|
+
|
|
+static int
|
|
+efi_status_cmp_bsearch(const void *key, const void *item)
|
|
+{
|
|
+ u64 status = (u64)(uintptr_t)key;
|
|
+ struct efi_error_code *code = (struct efi_error_code *)item;
|
|
+
|
|
+ if (status < code->status)
|
|
+ return -1;
|
|
+ if (status > code->status)
|
|
+ return 1;
|
|
+ return 0;
|
|
+}
|
|
+
|
|
int efi_status_to_err(efi_status_t status)
|
|
{
|
|
- int err;
|
|
-
|
|
- switch (status) {
|
|
- case EFI_SUCCESS:
|
|
- err = 0;
|
|
- break;
|
|
- case EFI_INVALID_PARAMETER:
|
|
- err = -EINVAL;
|
|
- break;
|
|
- case EFI_OUT_OF_RESOURCES:
|
|
- err = -ENOSPC;
|
|
- break;
|
|
- case EFI_DEVICE_ERROR:
|
|
- err = -EIO;
|
|
- break;
|
|
- case EFI_WRITE_PROTECTED:
|
|
- err = -EROFS;
|
|
- break;
|
|
- case EFI_SECURITY_VIOLATION:
|
|
- err = -EACCES;
|
|
- break;
|
|
- case EFI_NOT_FOUND:
|
|
- err = -ENOENT;
|
|
- break;
|
|
- case EFI_ABORTED:
|
|
- err = -EINTR;
|
|
- break;
|
|
- default:
|
|
- err = -EINVAL;
|
|
- }
|
|
+ struct efi_error_code *found;
|
|
+ size_t num = sizeof(efi_error_codes) / sizeof(struct efi_error_code);
|
|
|
|
- return err;
|
|
+ found = bsearch((void *)(uintptr_t)status, efi_error_codes,
|
|
+ num, sizeof(struct efi_error_code),
|
|
+ efi_status_cmp_bsearch);
|
|
+ if (!found)
|
|
+ return -EINVAL;
|
|
+ return found->errno;
|
|
+}
|
|
+
|
|
+const char *
|
|
+efi_status_to_str(efi_status_t status)
|
|
+{
|
|
+ struct efi_error_code *found;
|
|
+ size_t num = sizeof(efi_error_codes) / sizeof(struct efi_error_code);
|
|
+
|
|
+ found = bsearch((void *)(uintptr_t)status, efi_error_codes,
|
|
+ num, sizeof(struct efi_error_code),
|
|
+ efi_status_cmp_bsearch);
|
|
+ if (!found)
|
|
+ return "Unknown error code";
|
|
+ return found->description;
|
|
}
|
|
EXPORT_SYMBOL_GPL(efi_status_to_err);
|
|
|
|
diff --git a/drivers/firmware/efi/libstub/fdt.c b/drivers/firmware/efi/libstub/fdt.c
|
|
index 6a337f1f8787b..89244e0d9fa86 100644
|
|
--- a/drivers/firmware/efi/libstub/fdt.c
|
|
+++ b/drivers/firmware/efi/libstub/fdt.c
|
|
@@ -132,6 +132,11 @@ static efi_status_t update_fdt(void *orig_fdt, unsigned long orig_fdt_size,
|
|
}
|
|
}
|
|
|
|
+ fdt_val32 = cpu_to_fdt32((u32)efi_get_secureboot());
|
|
+ status = fdt_setprop_var(fdt, node, "secure-boot-mode", fdt_val32);
|
|
+ if (status)
|
|
+ goto fdt_set_fail;
|
|
+
|
|
/* Shrink the FDT back to its minimum size: */
|
|
fdt_pack(fdt);
|
|
|
|
diff --git a/drivers/firmware/efi/libstub/secureboot.c b/drivers/firmware/efi/libstub/secureboot.c
|
|
index 516f4f0069bd2..380354755108b 100644
|
|
--- a/drivers/firmware/efi/libstub/secureboot.c
|
|
+++ b/drivers/firmware/efi/libstub/secureboot.c
|
|
@@ -29,10 +29,13 @@ enum efi_secureboot_mode efi_get_secureboot(void)
|
|
{
|
|
u32 attr;
|
|
unsigned long size;
|
|
- enum efi_secureboot_mode mode;
|
|
+ static enum efi_secureboot_mode mode;
|
|
efi_status_t status;
|
|
u8 moksbstate;
|
|
|
|
+ if (mode != efi_secureboot_mode_unset)
|
|
+ return mode;
|
|
+
|
|
mode = efi_get_secureboot_mode(get_var);
|
|
if (mode == efi_secureboot_mode_unknown) {
|
|
efi_err("Could not determine UEFI Secure Boot status.\n");
|
|
@@ -53,10 +56,13 @@ enum efi_secureboot_mode efi_get_secureboot(void)
|
|
/* If it fails, we don't care why. Default to secure */
|
|
if (status != EFI_SUCCESS)
|
|
goto secure_boot_enabled;
|
|
- if (!(attr & EFI_VARIABLE_NON_VOLATILE) && moksbstate == 1)
|
|
- return efi_secureboot_mode_disabled;
|
|
+ if (!(attr & EFI_VARIABLE_NON_VOLATILE) && moksbstate == 1) {
|
|
+ mode = efi_secureboot_mode_disabled;
|
|
+ return mode;
|
|
+ }
|
|
|
|
secure_boot_enabled:
|
|
efi_info("UEFI Secure Boot is enabled.\n");
|
|
- return efi_secureboot_mode_enabled;
|
|
+ mode = efi_secureboot_mode_enabled;
|
|
+ return mode;
|
|
}
|
|
diff --git a/drivers/firmware/efi/secureboot.c b/drivers/firmware/efi/secureboot.c
|
|
new file mode 100644
|
|
index 0000000000000..de0a3714a5d44
|
|
--- /dev/null
|
|
+++ b/drivers/firmware/efi/secureboot.c
|
|
@@ -0,0 +1,38 @@
|
|
+/* Core kernel secure boot support.
|
|
+ *
|
|
+ * Copyright (C) 2017 Red Hat, Inc. All Rights Reserved.
|
|
+ * Written by David Howells (dhowells@redhat.com)
|
|
+ *
|
|
+ * This program is free software; you can redistribute it and/or
|
|
+ * modify it under the terms of the GNU General Public Licence
|
|
+ * as published by the Free Software Foundation; either version
|
|
+ * 2 of the Licence, or (at your option) any later version.
|
|
+ */
|
|
+
|
|
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
|
+
|
|
+#include <linux/efi.h>
|
|
+#include <linux/kernel.h>
|
|
+#include <linux/printk.h>
|
|
+
|
|
+/*
|
|
+ * Decide what to do when UEFI secure boot mode is enabled.
|
|
+ */
|
|
+void __init efi_set_secure_boot(enum efi_secureboot_mode mode)
|
|
+{
|
|
+ if (efi_enabled(EFI_BOOT)) {
|
|
+ switch (mode) {
|
|
+ case efi_secureboot_mode_disabled:
|
|
+ pr_info("Secure boot disabled\n");
|
|
+ break;
|
|
+ case efi_secureboot_mode_enabled:
|
|
+ set_bit(EFI_SECURE_BOOT, &efi.flags);
|
|
+ pr_info("Secure boot enabled\n");
|
|
+ break;
|
|
+ default:
|
|
+ pr_warn("Secure boot could not be determined (mode %u)\n",
|
|
+ mode);
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+}
|
|
diff --git a/drivers/gpu/drm/i915/display/intel_alpm.c b/drivers/gpu/drm/i915/display/intel_alpm.c
|
|
index affa3daefd594..f4f1b68f75435 100644
|
|
--- a/drivers/gpu/drm/i915/display/intel_alpm.c
|
|
+++ b/drivers/gpu/drm/i915/display/intel_alpm.c
|
|
@@ -320,11 +320,9 @@ static void lnl_alpm_configure(struct intel_dp *intel_dp,
|
|
if (intel_dp->as_sdp_supported) {
|
|
u32 pr_alpm_ctl = PR_ALPM_CTL_ADAPTIVE_SYNC_SDP_POSITION_T1;
|
|
|
|
- if (intel_dp->pr_dpcd[INTEL_PR_DPCD_INDEX(DP_PANEL_REPLAY_CAP_CAPABILITY)] &
|
|
- DP_PANEL_REPLAY_LINK_OFF_SUPPORTED_IN_PR_AFTER_ADAPTIVE_SYNC_SDP)
|
|
+ if (crtc_state->link_off_after_as_sdp_when_pr_active)
|
|
pr_alpm_ctl |= PR_ALPM_CTL_ALLOW_LINK_OFF_BETWEEN_AS_SDP_AND_SU;
|
|
- if (!(intel_dp->pr_dpcd[INTEL_PR_DPCD_INDEX(DP_PANEL_REPLAY_CAP_CAPABILITY)] &
|
|
- DP_PANEL_REPLAY_ASYNC_VIDEO_TIMING_NOT_SUPPORTED_IN_PR))
|
|
+ if (crtc_state->disable_as_sdp_when_pr_active)
|
|
pr_alpm_ctl |= PR_ALPM_CTL_AS_SDP_TRANSMISSION_IN_ACTIVE_DISABLE;
|
|
|
|
intel_de_write(display, PR_ALPM_CTL(display, cpu_transcoder),
|
|
diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
|
|
index 2b8a77ddcefc3..107ba232ad453 100644
|
|
--- a/drivers/gpu/drm/i915/display/intel_display.c
|
|
+++ b/drivers/gpu/drm/i915/display/intel_display.c
|
|
@@ -6037,14 +6037,6 @@ static int intel_async_flip_check_uapi(struct intel_atomic_state *state,
|
|
return -EINVAL;
|
|
}
|
|
|
|
- /* FIXME: selective fetch should be disabled for async flips */
|
|
- if (new_crtc_state->enable_psr2_sel_fetch) {
|
|
- drm_dbg_kms(display->drm,
|
|
- "[CRTC:%d:%s] async flip disallowed with PSR2 selective fetch\n",
|
|
- crtc->base.base.id, crtc->base.name);
|
|
- return -EINVAL;
|
|
- }
|
|
-
|
|
for_each_oldnew_intel_plane_in_state(state, plane, old_plane_state,
|
|
new_plane_state, i) {
|
|
if (plane->pipe != crtc->pipe)
|
|
diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
|
|
index 1a7188970f24e..a83620b8618f2 100644
|
|
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
|
|
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
|
|
@@ -510,6 +510,12 @@ struct intel_hdcp {
|
|
bool force_hdcp14;
|
|
};
|
|
|
|
+enum intel_panel_replay_dsc_support {
|
|
+ INTEL_DP_PANEL_REPLAY_DSC_NOT_SUPPORTED,
|
|
+ INTEL_DP_PANEL_REPLAY_DSC_FULL_FRAME_ONLY,
|
|
+ INTEL_DP_PANEL_REPLAY_DSC_SELECTIVE_UPDATE,
|
|
+};
|
|
+
|
|
struct intel_connector {
|
|
struct drm_connector base;
|
|
/*
|
|
@@ -562,6 +568,30 @@ struct intel_connector {
|
|
} overall_throughput;
|
|
int max_line_width;
|
|
} dsc_branch_caps;
|
|
+
|
|
+ struct {
|
|
+ u8 dpcd[DP_PANEL_REPLAY_CAP_SIZE];
|
|
+#define INTEL_PR_DPCD_INDEX(pr_dpcd_register) ((pr_dpcd_register) - DP_PANEL_REPLAY_CAP_SUPPORT)
|
|
+
|
|
+ bool support;
|
|
+ bool su_support;
|
|
+ enum intel_panel_replay_dsc_support dsc_support;
|
|
+
|
|
+ u16 su_w_granularity;
|
|
+ u16 su_y_granularity;
|
|
+ } panel_replay_caps;
|
|
+
|
|
+ struct {
|
|
+ u8 dpcd[EDP_PSR_RECEIVER_CAP_SIZE];
|
|
+
|
|
+ bool support;
|
|
+ bool su_support;
|
|
+
|
|
+ u16 su_w_granularity;
|
|
+ u16 su_y_granularity;
|
|
+
|
|
+ u8 sync_latency;
|
|
+ } psr_caps;
|
|
} dp;
|
|
|
|
struct {
|
|
@@ -956,12 +986,6 @@ struct intel_csc_matrix {
|
|
u16 postoff[3];
|
|
};
|
|
|
|
-enum intel_panel_replay_dsc_support {
|
|
- INTEL_DP_PANEL_REPLAY_DSC_NOT_SUPPORTED,
|
|
- INTEL_DP_PANEL_REPLAY_DSC_FULL_FRAME_ONLY,
|
|
- INTEL_DP_PANEL_REPLAY_DSC_SELECTIVE_UPDATE,
|
|
-};
|
|
-
|
|
struct scaler_filter_coeff {
|
|
u16 sign;
|
|
u16 exp;
|
|
@@ -1153,6 +1177,8 @@ struct intel_crtc_state {
|
|
bool enable_psr2_su_region_et;
|
|
bool req_psr2_sdp_prior_scanline;
|
|
bool has_panel_replay;
|
|
+ bool link_off_after_as_sdp_when_pr_active;
|
|
+ bool disable_as_sdp_when_pr_active;
|
|
bool wm_level_disabled;
|
|
bool pkg_c_latency_used;
|
|
/* Only used for state verification. */
|
|
@@ -1718,14 +1744,12 @@ struct intel_psr {
|
|
bool active;
|
|
struct work_struct work;
|
|
unsigned int busy_frontbuffer_bits;
|
|
- bool sink_psr2_support;
|
|
bool link_standby;
|
|
bool sel_update_enabled;
|
|
bool psr2_sel_fetch_enabled;
|
|
bool psr2_sel_fetch_cff_enabled;
|
|
bool su_region_et_enabled;
|
|
bool req_psr2_sdp_prior_scanline;
|
|
- u8 sink_sync_latency;
|
|
ktime_t last_entry_attempt;
|
|
ktime_t last_exit;
|
|
bool sink_not_reliable;
|
|
@@ -1734,8 +1758,6 @@ struct intel_psr {
|
|
u16 su_y_granularity;
|
|
bool source_panel_replay_support;
|
|
bool sink_panel_replay_support;
|
|
- bool sink_panel_replay_su_support;
|
|
- enum intel_panel_replay_dsc_support sink_panel_replay_dsc_support;
|
|
bool panel_replay_enabled;
|
|
u32 dc3co_exitline;
|
|
u32 dc3co_exit_delay;
|
|
@@ -1762,9 +1784,6 @@ struct intel_dp {
|
|
bool needs_modeset_retry;
|
|
bool use_max_params;
|
|
u8 dpcd[DP_RECEIVER_CAP_SIZE];
|
|
- u8 psr_dpcd[EDP_PSR_RECEIVER_CAP_SIZE];
|
|
- u8 pr_dpcd[DP_PANEL_REPLAY_CAP_SIZE];
|
|
-#define INTEL_PR_DPCD_INDEX(pr_dpcd_register) ((pr_dpcd_register) - DP_PANEL_REPLAY_CAP_SUPPORT)
|
|
|
|
u8 downstream_ports[DP_MAX_DOWNSTREAM_PORTS];
|
|
u8 edp_dpcd[EDP_DISPLAY_CTL_CAP_SIZE];
|
|
diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
|
|
index b6ce11267b92d..8c68fb56c8982 100644
|
|
--- a/drivers/gpu/drm/i915/display/intel_dp.c
|
|
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
|
|
@@ -4597,7 +4597,7 @@ intel_edp_init_dpcd(struct intel_dp *intel_dp, struct intel_connector *connector
|
|
* This has to be called after intel_dp->edp_dpcd is filled, PSR checks
|
|
* for SET_POWER_CAPABLE bit in intel_dp->edp_dpcd[1]
|
|
*/
|
|
- intel_psr_init_dpcd(intel_dp);
|
|
+ intel_psr_init_dpcd(intel_dp, connector);
|
|
|
|
intel_edp_set_sink_rates(intel_dp);
|
|
intel_dp_set_max_sink_lane_count(intel_dp);
|
|
@@ -6084,10 +6084,19 @@ intel_dp_detect(struct drm_connector *_connector,
|
|
|
|
if (status == connector_status_disconnected) {
|
|
intel_dp_test_reset(intel_dp);
|
|
+ /*
|
|
+ * FIXME: Resetting these caps here cause
|
|
+ * state computation fail if the connector need to be
|
|
+ * modeset after sink disconnect. Move resetting them
|
|
+ * to where new sink is connected.
|
|
+ */
|
|
memset(connector->dp.dsc_dpcd, 0, sizeof(connector->dp.dsc_dpcd));
|
|
+ memset(connector->dp.panel_replay_caps.dpcd, 0,
|
|
+ sizeof(connector->dp.panel_replay_caps.dpcd));
|
|
intel_dp->psr.sink_panel_replay_support = false;
|
|
- intel_dp->psr.sink_panel_replay_su_support = false;
|
|
- intel_dp->psr.sink_panel_replay_dsc_support =
|
|
+ connector->dp.panel_replay_caps.support = false;
|
|
+ connector->dp.panel_replay_caps.su_support = false;
|
|
+ connector->dp.panel_replay_caps.dsc_support =
|
|
INTEL_DP_PANEL_REPLAY_DSC_NOT_SUPPORTED;
|
|
|
|
intel_dp_mst_disconnect(intel_dp);
|
|
@@ -6110,7 +6119,7 @@ intel_dp_detect(struct drm_connector *_connector,
|
|
connector->base.epoch_counter++;
|
|
|
|
if (!intel_dp_is_edp(intel_dp))
|
|
- intel_psr_init_dpcd(intel_dp);
|
|
+ intel_psr_init_dpcd(intel_dp, connector);
|
|
|
|
intel_dp_detect_dsc_caps(intel_dp, connector);
|
|
|
|
diff --git a/drivers/gpu/drm/i915/display/intel_plane.c b/drivers/gpu/drm/i915/display/intel_plane.c
|
|
index 79910d52dc8fb..3a6c1f78b3d40 100644
|
|
--- a/drivers/gpu/drm/i915/display/intel_plane.c
|
|
+++ b/drivers/gpu/drm/i915/display/intel_plane.c
|
|
@@ -656,11 +656,10 @@ static int intel_plane_atomic_calc_changes(const struct intel_crtc_state *old_cr
|
|
ilk_must_disable_cxsr(new_crtc_state, old_plane_state, new_plane_state))
|
|
new_crtc_state->disable_cxsr = true;
|
|
|
|
- if (intel_plane_do_async_flip(plane, old_crtc_state, new_crtc_state)) {
|
|
+ if (intel_plane_do_async_flip(plane, old_crtc_state, new_crtc_state))
|
|
new_crtc_state->do_async_flip = true;
|
|
- new_crtc_state->async_flip_planes |= BIT(plane->id);
|
|
- } else if (plane->need_async_flip_toggle_wa &&
|
|
- new_crtc_state->uapi.async_flip) {
|
|
+
|
|
+ if (new_crtc_state->uapi.async_flip) {
|
|
/*
|
|
* On platforms with double buffered async flip bit we
|
|
* set the bit already one frame early during the sync
|
|
@@ -668,6 +667,9 @@ static int intel_plane_atomic_calc_changes(const struct intel_crtc_state *old_cr
|
|
* hardware will therefore be ready to perform a real
|
|
* async flip during the next commit, without having
|
|
* to wait yet another frame for the bit to latch.
|
|
+ *
|
|
+ * async_flip_planes bitmask is also used by selective
|
|
+ * fetch calculation to choose full frame update.
|
|
*/
|
|
new_crtc_state->async_flip_planes |= BIT(plane->id);
|
|
}
|
|
diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c
|
|
index 6dddeb4421ba2..14ddf33e4e0e9 100644
|
|
--- a/drivers/gpu/drm/i915/display/intel_psr.c
|
|
+++ b/drivers/gpu/drm/i915/display/intel_psr.c
|
|
@@ -494,82 +494,37 @@ static u8 intel_dp_get_sink_sync_latency(struct intel_dp *intel_dp)
|
|
return val;
|
|
}
|
|
|
|
-static u8 intel_dp_get_su_capability(struct intel_dp *intel_dp)
|
|
-{
|
|
- u8 su_capability = 0;
|
|
-
|
|
- if (intel_dp->psr.sink_panel_replay_su_support) {
|
|
- if (drm_dp_dpcd_read_byte(&intel_dp->aux,
|
|
- DP_PANEL_REPLAY_CAP_CAPABILITY,
|
|
- &su_capability) < 0)
|
|
- return 0;
|
|
- } else {
|
|
- su_capability = intel_dp->psr_dpcd[1];
|
|
- }
|
|
-
|
|
- return su_capability;
|
|
-}
|
|
-
|
|
-static unsigned int
|
|
-intel_dp_get_su_x_granularity_offset(struct intel_dp *intel_dp)
|
|
-{
|
|
- return intel_dp->psr.sink_panel_replay_su_support ?
|
|
- DP_PANEL_REPLAY_CAP_X_GRANULARITY :
|
|
- DP_PSR2_SU_X_GRANULARITY;
|
|
-}
|
|
-
|
|
-static unsigned int
|
|
-intel_dp_get_su_y_granularity_offset(struct intel_dp *intel_dp)
|
|
-{
|
|
- return intel_dp->psr.sink_panel_replay_su_support ?
|
|
- DP_PANEL_REPLAY_CAP_Y_GRANULARITY :
|
|
- DP_PSR2_SU_Y_GRANULARITY;
|
|
-}
|
|
-
|
|
-/*
|
|
- * Note: Bits related to granularity are same in panel replay and psr
|
|
- * registers. Rely on PSR definitions on these "common" bits.
|
|
- */
|
|
-static void intel_dp_get_su_granularity(struct intel_dp *intel_dp)
|
|
+static void _psr_compute_su_granularity(struct intel_dp *intel_dp,
|
|
+ struct intel_connector *connector)
|
|
{
|
|
struct intel_display *display = to_intel_display(intel_dp);
|
|
ssize_t r;
|
|
- u16 w;
|
|
+ __le16 w;
|
|
u8 y;
|
|
|
|
- /*
|
|
- * TODO: Do we need to take into account panel supporting both PSR and
|
|
- * Panel replay?
|
|
- */
|
|
-
|
|
/*
|
|
* If sink don't have specific granularity requirements set legacy
|
|
* ones.
|
|
*/
|
|
- if (!(intel_dp_get_su_capability(intel_dp) &
|
|
- DP_PSR2_SU_GRANULARITY_REQUIRED)) {
|
|
+ if (!(connector->dp.psr_caps.dpcd[1] & DP_PSR2_SU_GRANULARITY_REQUIRED)) {
|
|
/* As PSR2 HW sends full lines, we do not care about x granularity */
|
|
- w = 4;
|
|
+ w = cpu_to_le16(4);
|
|
y = 4;
|
|
goto exit;
|
|
}
|
|
|
|
- r = drm_dp_dpcd_read(&intel_dp->aux,
|
|
- intel_dp_get_su_x_granularity_offset(intel_dp),
|
|
- &w, 2);
|
|
- if (r != 2)
|
|
+ r = drm_dp_dpcd_read(&intel_dp->aux, DP_PSR2_SU_X_GRANULARITY, &w, sizeof(w));
|
|
+ if (r != sizeof(w))
|
|
drm_dbg_kms(display->drm,
|
|
"Unable to read selective update x granularity\n");
|
|
/*
|
|
* Spec says that if the value read is 0 the default granularity should
|
|
* be used instead.
|
|
*/
|
|
- if (r != 2 || w == 0)
|
|
- w = 4;
|
|
+ if (r != sizeof(w) || w == 0)
|
|
+ w = cpu_to_le16(4);
|
|
|
|
- r = drm_dp_dpcd_read(&intel_dp->aux,
|
|
- intel_dp_get_su_y_granularity_offset(intel_dp),
|
|
- &y, 1);
|
|
+ r = drm_dp_dpcd_read(&intel_dp->aux, DP_PSR2_SU_Y_GRANULARITY, &y, 1);
|
|
if (r != 1) {
|
|
drm_dbg_kms(display->drm,
|
|
"Unable to read selective update y granularity\n");
|
|
@@ -579,17 +534,17 @@ static void intel_dp_get_su_granularity(struct intel_dp *intel_dp)
|
|
y = 1;
|
|
|
|
exit:
|
|
- intel_dp->psr.su_w_granularity = w;
|
|
- intel_dp->psr.su_y_granularity = y;
|
|
+ connector->dp.psr_caps.su_w_granularity = le16_to_cpu(w);
|
|
+ connector->dp.psr_caps.su_y_granularity = y;
|
|
}
|
|
|
|
static enum intel_panel_replay_dsc_support
|
|
-compute_pr_dsc_support(struct intel_dp *intel_dp)
|
|
+compute_pr_dsc_support(struct intel_connector *connector)
|
|
{
|
|
u8 pr_dsc_mode;
|
|
u8 val;
|
|
|
|
- val = intel_dp->pr_dpcd[INTEL_PR_DPCD_INDEX(DP_PANEL_REPLAY_CAP_CAPABILITY)];
|
|
+ val = connector->dp.panel_replay_caps.dpcd[INTEL_PR_DPCD_INDEX(DP_PANEL_REPLAY_CAP_CAPABILITY)];
|
|
pr_dsc_mode = REG_FIELD_GET8(DP_PANEL_REPLAY_DSC_DECODE_CAPABILITY_IN_PR_MASK, val);
|
|
|
|
switch (pr_dsc_mode) {
|
|
@@ -621,7 +576,31 @@ static const char *panel_replay_dsc_support_str(enum intel_panel_replay_dsc_supp
|
|
};
|
|
}
|
|
|
|
-static void _panel_replay_init_dpcd(struct intel_dp *intel_dp)
|
|
+static void _panel_replay_compute_su_granularity(struct intel_connector *connector)
|
|
+{
|
|
+ u16 w;
|
|
+ u8 y;
|
|
+
|
|
+ if (!(connector->dp.panel_replay_caps.dpcd[INTEL_PR_DPCD_INDEX(DP_PANEL_REPLAY_CAP_CAPABILITY)] &
|
|
+ DP_PANEL_REPLAY_SU_GRANULARITY_REQUIRED)) {
|
|
+ w = 4;
|
|
+ y = 4;
|
|
+ goto exit;
|
|
+ }
|
|
+
|
|
+ /*
|
|
+ * Spec says that if the value read is 0 the default granularity should
|
|
+ * be used instead.
|
|
+ */
|
|
+ w = le16_to_cpu(*(__le16 *)&connector->dp.panel_replay_caps.dpcd[INTEL_PR_DPCD_INDEX(DP_PANEL_REPLAY_CAP_X_GRANULARITY)]) ? : 4;
|
|
+ y = connector->dp.panel_replay_caps.dpcd[INTEL_PR_DPCD_INDEX(DP_PANEL_REPLAY_CAP_Y_GRANULARITY)] ? : 1;
|
|
+
|
|
+exit:
|
|
+ connector->dp.panel_replay_caps.su_w_granularity = w;
|
|
+ connector->dp.panel_replay_caps.su_y_granularity = y;
|
|
+}
|
|
+
|
|
+static void _panel_replay_init_dpcd(struct intel_dp *intel_dp, struct intel_connector *connector)
|
|
{
|
|
struct intel_display *display = to_intel_display(intel_dp);
|
|
int ret;
|
|
@@ -631,11 +610,12 @@ static void _panel_replay_init_dpcd(struct intel_dp *intel_dp)
|
|
return;
|
|
|
|
ret = drm_dp_dpcd_read_data(&intel_dp->aux, DP_PANEL_REPLAY_CAP_SUPPORT,
|
|
- &intel_dp->pr_dpcd, sizeof(intel_dp->pr_dpcd));
|
|
+ &connector->dp.panel_replay_caps.dpcd,
|
|
+ sizeof(connector->dp.panel_replay_caps.dpcd));
|
|
if (ret < 0)
|
|
return;
|
|
|
|
- if (!(intel_dp->pr_dpcd[INTEL_PR_DPCD_INDEX(DP_PANEL_REPLAY_CAP_SUPPORT)] &
|
|
+ if (!(connector->dp.panel_replay_caps.dpcd[INTEL_PR_DPCD_INDEX(DP_PANEL_REPLAY_CAP_SUPPORT)] &
|
|
DP_PANEL_REPLAY_SUPPORT))
|
|
return;
|
|
|
|
@@ -646,7 +626,7 @@ static void _panel_replay_init_dpcd(struct intel_dp *intel_dp)
|
|
return;
|
|
}
|
|
|
|
- if (!(intel_dp->pr_dpcd[INTEL_PR_DPCD_INDEX(DP_PANEL_REPLAY_CAP_SUPPORT)] &
|
|
+ if (!(connector->dp.panel_replay_caps.dpcd[INTEL_PR_DPCD_INDEX(DP_PANEL_REPLAY_CAP_SUPPORT)] &
|
|
DP_PANEL_REPLAY_EARLY_TRANSPORT_SUPPORT)) {
|
|
drm_dbg_kms(display->drm,
|
|
"Panel doesn't support early transport, eDP Panel Replay not possible\n");
|
|
@@ -654,36 +634,40 @@ static void _panel_replay_init_dpcd(struct intel_dp *intel_dp)
|
|
}
|
|
}
|
|
|
|
+ connector->dp.panel_replay_caps.support = true;
|
|
intel_dp->psr.sink_panel_replay_support = true;
|
|
|
|
- if (intel_dp->pr_dpcd[INTEL_PR_DPCD_INDEX(DP_PANEL_REPLAY_CAP_SUPPORT)] &
|
|
- DP_PANEL_REPLAY_SU_SUPPORT)
|
|
- intel_dp->psr.sink_panel_replay_su_support = true;
|
|
+ if (connector->dp.panel_replay_caps.dpcd[INTEL_PR_DPCD_INDEX(DP_PANEL_REPLAY_CAP_SUPPORT)] &
|
|
+ DP_PANEL_REPLAY_SU_SUPPORT) {
|
|
+ connector->dp.panel_replay_caps.su_support = true;
|
|
|
|
- intel_dp->psr.sink_panel_replay_dsc_support = compute_pr_dsc_support(intel_dp);
|
|
+ _panel_replay_compute_su_granularity(connector);
|
|
+ }
|
|
+
|
|
+ connector->dp.panel_replay_caps.dsc_support = compute_pr_dsc_support(connector);
|
|
|
|
drm_dbg_kms(display->drm,
|
|
"Panel replay %sis supported by panel (in DSC mode: %s)\n",
|
|
- intel_dp->psr.sink_panel_replay_su_support ?
|
|
+ connector->dp.panel_replay_caps.su_support ?
|
|
"selective_update " : "",
|
|
- panel_replay_dsc_support_str(intel_dp->psr.sink_panel_replay_dsc_support));
|
|
+ panel_replay_dsc_support_str(connector->dp.panel_replay_caps.dsc_support));
|
|
}
|
|
|
|
-static void _psr_init_dpcd(struct intel_dp *intel_dp)
|
|
+static void _psr_init_dpcd(struct intel_dp *intel_dp, struct intel_connector *connector)
|
|
{
|
|
struct intel_display *display = to_intel_display(intel_dp);
|
|
int ret;
|
|
|
|
- ret = drm_dp_dpcd_read_data(&intel_dp->aux, DP_PSR_SUPPORT, intel_dp->psr_dpcd,
|
|
- sizeof(intel_dp->psr_dpcd));
|
|
+ ret = drm_dp_dpcd_read_data(&intel_dp->aux, DP_PSR_SUPPORT, connector->dp.psr_caps.dpcd,
|
|
+ sizeof(connector->dp.psr_caps.dpcd));
|
|
if (ret < 0)
|
|
return;
|
|
|
|
- if (!intel_dp->psr_dpcd[0])
|
|
+ if (!connector->dp.psr_caps.dpcd[0])
|
|
return;
|
|
|
|
drm_dbg_kms(display->drm, "eDP panel supports PSR version %x\n",
|
|
- intel_dp->psr_dpcd[0]);
|
|
+ connector->dp.psr_caps.dpcd[0]);
|
|
|
|
if (drm_dp_has_quirk(&intel_dp->desc, DP_DPCD_QUIRK_NO_PSR)) {
|
|
drm_dbg_kms(display->drm,
|
|
@@ -697,13 +681,14 @@ static void _psr_init_dpcd(struct intel_dp *intel_dp)
|
|
return;
|
|
}
|
|
|
|
+ connector->dp.psr_caps.support = true;
|
|
intel_dp->psr.sink_support = true;
|
|
- intel_dp->psr.sink_sync_latency =
|
|
- intel_dp_get_sink_sync_latency(intel_dp);
|
|
+
|
|
+ connector->dp.psr_caps.sync_latency = intel_dp_get_sink_sync_latency(intel_dp);
|
|
|
|
if (DISPLAY_VER(display) >= 9 &&
|
|
- intel_dp->psr_dpcd[0] >= DP_PSR2_WITH_Y_COORD_IS_SUPPORTED) {
|
|
- bool y_req = intel_dp->psr_dpcd[1] &
|
|
+ connector->dp.psr_caps.dpcd[0] >= DP_PSR2_WITH_Y_COORD_IS_SUPPORTED) {
|
|
+ bool y_req = connector->dp.psr_caps.dpcd[1] &
|
|
DP_PSR2_SU_Y_COORDINATE_REQUIRED;
|
|
|
|
/*
|
|
@@ -717,22 +702,21 @@ static void _psr_init_dpcd(struct intel_dp *intel_dp)
|
|
* Y-coordinate requirement panels we would need to enable
|
|
* GTC first.
|
|
*/
|
|
- intel_dp->psr.sink_psr2_support = y_req &&
|
|
+ connector->dp.psr_caps.su_support = y_req &&
|
|
intel_alpm_aux_wake_supported(intel_dp);
|
|
drm_dbg_kms(display->drm, "PSR2 %ssupported\n",
|
|
- intel_dp->psr.sink_psr2_support ? "" : "not ");
|
|
+ connector->dp.psr_caps.su_support ? "" : "not ");
|
|
}
|
|
+
|
|
+ if (connector->dp.psr_caps.su_support)
|
|
+ _psr_compute_su_granularity(intel_dp, connector);
|
|
}
|
|
|
|
-void intel_psr_init_dpcd(struct intel_dp *intel_dp)
|
|
+void intel_psr_init_dpcd(struct intel_dp *intel_dp, struct intel_connector *connector)
|
|
{
|
|
- _psr_init_dpcd(intel_dp);
|
|
+ _psr_init_dpcd(intel_dp, connector);
|
|
|
|
- _panel_replay_init_dpcd(intel_dp);
|
|
-
|
|
- if (intel_dp->psr.sink_psr2_support ||
|
|
- intel_dp->psr.sink_panel_replay_su_support)
|
|
- intel_dp_get_su_granularity(intel_dp);
|
|
+ _panel_replay_init_dpcd(intel_dp, connector);
|
|
}
|
|
|
|
static void hsw_psr_setup_aux(struct intel_dp *intel_dp)
|
|
@@ -772,8 +756,9 @@ static void hsw_psr_setup_aux(struct intel_dp *intel_dp)
|
|
aux_ctl);
|
|
}
|
|
|
|
-static bool psr2_su_region_et_valid(struct intel_dp *intel_dp, bool panel_replay)
|
|
+static bool psr2_su_region_et_valid(struct intel_connector *connector, bool panel_replay)
|
|
{
|
|
+ struct intel_dp *intel_dp = intel_attached_dp(connector);
|
|
struct intel_display *display = to_intel_display(intel_dp);
|
|
|
|
if (DISPLAY_VER(display) < 20 || !intel_dp_is_edp(intel_dp) ||
|
|
@@ -781,9 +766,9 @@ static bool psr2_su_region_et_valid(struct intel_dp *intel_dp, bool panel_replay
|
|
return false;
|
|
|
|
return panel_replay ?
|
|
- intel_dp->pr_dpcd[INTEL_PR_DPCD_INDEX(DP_PANEL_REPLAY_CAP_SUPPORT)] &
|
|
+ connector->dp.panel_replay_caps.dpcd[INTEL_PR_DPCD_INDEX(DP_PANEL_REPLAY_CAP_SUPPORT)] &
|
|
DP_PANEL_REPLAY_EARLY_TRANSPORT_SUPPORT :
|
|
- intel_dp->psr_dpcd[0] == DP_PSR2_WITH_Y_COORD_ET_SUPPORTED;
|
|
+ connector->dp.psr_caps.dpcd[0] == DP_PSR2_WITH_Y_COORD_ET_SUPPORTED;
|
|
}
|
|
|
|
static void _panel_replay_enable_sink(struct intel_dp *intel_dp,
|
|
@@ -929,7 +914,7 @@ static u8 psr_compute_idle_frames(struct intel_dp *intel_dp)
|
|
* off-by-one issue that HW has in some cases.
|
|
*/
|
|
idle_frames = max(6, connector->panel.vbt.psr.idle_frames);
|
|
- idle_frames = max(idle_frames, intel_dp->psr.sink_sync_latency + 1);
|
|
+ idle_frames = max(idle_frames, connector->dp.psr_caps.sync_latency + 1);
|
|
|
|
if (drm_WARN_ON(display->drm, idle_frames > 0xf))
|
|
idle_frames = 0xf;
|
|
@@ -1024,10 +1009,11 @@ static int psr2_block_count(struct intel_dp *intel_dp)
|
|
|
|
static u8 frames_before_su_entry(struct intel_dp *intel_dp)
|
|
{
|
|
+ struct intel_connector *connector = intel_dp->attached_connector;
|
|
u8 frames_before_su_entry;
|
|
|
|
frames_before_su_entry = max_t(u8,
|
|
- intel_dp->psr.sink_sync_latency + 1,
|
|
+ connector->dp.psr_caps.sync_latency + 1,
|
|
2);
|
|
|
|
/* Entry setup frames must be at least 1 less than frames before SU entry */
|
|
@@ -1309,25 +1295,37 @@ static bool intel_psr2_sel_fetch_config_valid(struct intel_dp *intel_dp,
|
|
return crtc_state->enable_psr2_sel_fetch = true;
|
|
}
|
|
|
|
-static bool psr2_granularity_check(struct intel_dp *intel_dp,
|
|
- struct intel_crtc_state *crtc_state)
|
|
+static bool psr2_granularity_check(struct intel_crtc_state *crtc_state,
|
|
+ struct intel_connector *connector)
|
|
{
|
|
+ struct intel_dp *intel_dp = intel_attached_dp(connector);
|
|
struct intel_display *display = to_intel_display(intel_dp);
|
|
const struct drm_dsc_config *vdsc_cfg = &crtc_state->dsc.config;
|
|
const int crtc_hdisplay = crtc_state->hw.adjusted_mode.crtc_hdisplay;
|
|
const int crtc_vdisplay = crtc_state->hw.adjusted_mode.crtc_vdisplay;
|
|
u16 y_granularity = 0;
|
|
+ u16 sink_y_granularity = crtc_state->has_panel_replay ?
|
|
+ connector->dp.panel_replay_caps.su_y_granularity :
|
|
+ connector->dp.psr_caps.su_y_granularity;
|
|
+ u16 sink_w_granularity;
|
|
+
|
|
+ if (crtc_state->has_panel_replay)
|
|
+ sink_w_granularity = connector->dp.panel_replay_caps.su_w_granularity ==
|
|
+ DP_PANEL_REPLAY_FULL_LINE_GRANULARITY ?
|
|
+ crtc_hdisplay : connector->dp.panel_replay_caps.su_w_granularity;
|
|
+ else
|
|
+ sink_w_granularity = connector->dp.psr_caps.su_w_granularity;
|
|
|
|
/* PSR2 HW only send full lines so we only need to validate the width */
|
|
- if (crtc_hdisplay % intel_dp->psr.su_w_granularity)
|
|
+ if (crtc_hdisplay % sink_w_granularity)
|
|
return false;
|
|
|
|
- if (crtc_vdisplay % intel_dp->psr.su_y_granularity)
|
|
+ if (crtc_vdisplay % sink_y_granularity)
|
|
return false;
|
|
|
|
/* HW tracking is only aligned to 4 lines */
|
|
if (!crtc_state->enable_psr2_sel_fetch)
|
|
- return intel_dp->psr.su_y_granularity == 4;
|
|
+ return sink_y_granularity == 4;
|
|
|
|
/*
|
|
* adl_p and mtl platforms have 1 line granularity.
|
|
@@ -1335,11 +1333,11 @@ static bool psr2_granularity_check(struct intel_dp *intel_dp,
|
|
* to match sink requirement if multiple of 4.
|
|
*/
|
|
if (display->platform.alderlake_p || DISPLAY_VER(display) >= 14)
|
|
- y_granularity = intel_dp->psr.su_y_granularity;
|
|
- else if (intel_dp->psr.su_y_granularity <= 2)
|
|
+ y_granularity = sink_y_granularity;
|
|
+ else if (sink_y_granularity <= 2)
|
|
y_granularity = 4;
|
|
- else if ((intel_dp->psr.su_y_granularity % 4) == 0)
|
|
- y_granularity = intel_dp->psr.su_y_granularity;
|
|
+ else if ((sink_y_granularity % 4) == 0)
|
|
+ y_granularity = sink_y_granularity;
|
|
|
|
if (y_granularity == 0 || crtc_vdisplay % y_granularity)
|
|
return false;
|
|
@@ -1377,16 +1375,18 @@ static bool _compute_psr2_sdp_prior_scanline_indication(struct intel_dp *intel_d
|
|
}
|
|
|
|
static int intel_psr_entry_setup_frames(struct intel_dp *intel_dp,
|
|
+ struct drm_connector_state *conn_state,
|
|
const struct drm_display_mode *adjusted_mode)
|
|
{
|
|
struct intel_display *display = to_intel_display(intel_dp);
|
|
- int psr_setup_time = drm_dp_psr_setup_time(intel_dp->psr_dpcd);
|
|
+ struct intel_connector *connector = to_intel_connector(conn_state->connector);
|
|
+ int psr_setup_time = drm_dp_psr_setup_time(connector->dp.psr_caps.dpcd);
|
|
int entry_setup_frames = 0;
|
|
|
|
if (psr_setup_time < 0) {
|
|
drm_dbg_kms(display->drm,
|
|
"PSR condition failed: Invalid PSR setup time (0x%02x)\n",
|
|
- intel_dp->psr_dpcd[1]);
|
|
+ connector->dp.psr_caps.dpcd[1]);
|
|
return -ETIME;
|
|
}
|
|
|
|
@@ -1527,14 +1527,16 @@ static bool alpm_config_valid(struct intel_dp *intel_dp,
|
|
}
|
|
|
|
static bool intel_psr2_config_valid(struct intel_dp *intel_dp,
|
|
- struct intel_crtc_state *crtc_state)
|
|
+ struct intel_crtc_state *crtc_state,
|
|
+ struct drm_connector_state *conn_state)
|
|
{
|
|
struct intel_display *display = to_intel_display(intel_dp);
|
|
+ struct intel_connector *connector = to_intel_connector(conn_state->connector);
|
|
int crtc_hdisplay = crtc_state->hw.adjusted_mode.crtc_hdisplay;
|
|
int crtc_vdisplay = crtc_state->hw.adjusted_mode.crtc_vdisplay;
|
|
int psr_max_h = 0, psr_max_v = 0, max_bpp = 0;
|
|
|
|
- if (!intel_dp->psr.sink_psr2_support || display->params.enable_psr == 1)
|
|
+ if (!connector->dp.psr_caps.su_support || display->params.enable_psr == 1)
|
|
return false;
|
|
|
|
/* JSL and EHL only supports eDP 1.3 */
|
|
@@ -1626,9 +1628,11 @@ static bool intel_psr2_config_valid(struct intel_dp *intel_dp,
|
|
return true;
|
|
}
|
|
|
|
-static bool intel_sel_update_config_valid(struct intel_dp *intel_dp,
|
|
- struct intel_crtc_state *crtc_state)
|
|
+static bool intel_sel_update_config_valid(struct intel_crtc_state *crtc_state,
|
|
+ struct drm_connector_state *conn_state)
|
|
{
|
|
+ struct intel_connector *connector = to_intel_connector(conn_state->connector);
|
|
+ struct intel_dp *intel_dp = intel_attached_dp(connector);
|
|
struct intel_display *display = to_intel_display(intel_dp);
|
|
|
|
if (HAS_PSR2_SEL_FETCH(display) &&
|
|
@@ -1645,7 +1649,8 @@ static bool intel_sel_update_config_valid(struct intel_dp *intel_dp,
|
|
goto unsupported;
|
|
}
|
|
|
|
- if (!crtc_state->has_panel_replay && !intel_psr2_config_valid(intel_dp, crtc_state))
|
|
+ if (!crtc_state->has_panel_replay && !intel_psr2_config_valid(intel_dp, crtc_state,
|
|
+ conn_state))
|
|
goto unsupported;
|
|
|
|
if (!_compute_psr2_sdp_prior_scanline_indication(intel_dp, crtc_state)) {
|
|
@@ -1658,11 +1663,11 @@ static bool intel_sel_update_config_valid(struct intel_dp *intel_dp,
|
|
if (DISPLAY_VER(display) < 14)
|
|
goto unsupported;
|
|
|
|
- if (!intel_dp->psr.sink_panel_replay_su_support)
|
|
+ if (!connector->dp.panel_replay_caps.su_support)
|
|
goto unsupported;
|
|
|
|
if (intel_dsc_enabled_on_link(crtc_state) &&
|
|
- intel_dp->psr.sink_panel_replay_dsc_support !=
|
|
+ connector->dp.panel_replay_caps.dsc_support !=
|
|
INTEL_DP_PANEL_REPLAY_DSC_SELECTIVE_UPDATE) {
|
|
drm_dbg_kms(display->drm,
|
|
"Selective update with Panel Replay not enabled because it's not supported with DSC\n");
|
|
@@ -1676,14 +1681,14 @@ static bool intel_sel_update_config_valid(struct intel_dp *intel_dp,
|
|
goto unsupported;
|
|
}
|
|
|
|
- if (!psr2_granularity_check(intel_dp, crtc_state)) {
|
|
+ if (!psr2_granularity_check(crtc_state, connector)) {
|
|
drm_dbg_kms(display->drm,
|
|
"Selective update not enabled, SU granularity not compatible\n");
|
|
goto unsupported;
|
|
}
|
|
|
|
- crtc_state->enable_psr2_su_region_et =
|
|
- psr2_su_region_et_valid(intel_dp, crtc_state->has_panel_replay);
|
|
+ crtc_state->enable_psr2_su_region_et = psr2_su_region_et_valid(connector,
|
|
+ crtc_state->has_panel_replay);
|
|
|
|
return true;
|
|
|
|
@@ -1693,7 +1698,8 @@ static bool intel_sel_update_config_valid(struct intel_dp *intel_dp,
|
|
}
|
|
|
|
static bool _psr_compute_config(struct intel_dp *intel_dp,
|
|
- struct intel_crtc_state *crtc_state)
|
|
+ struct intel_crtc_state *crtc_state,
|
|
+ struct drm_connector_state *conn_state)
|
|
{
|
|
struct intel_display *display = to_intel_display(intel_dp);
|
|
const struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode;
|
|
@@ -1708,7 +1714,7 @@ static bool _psr_compute_config(struct intel_dp *intel_dp,
|
|
if (crtc_state->vrr.enable)
|
|
return false;
|
|
|
|
- entry_setup_frames = intel_psr_entry_setup_frames(intel_dp, adjusted_mode);
|
|
+ entry_setup_frames = intel_psr_entry_setup_frames(intel_dp, conn_state, adjusted_mode);
|
|
|
|
if (entry_setup_frames >= 0) {
|
|
crtc_state->entry_setup_frames = entry_setup_frames;
|
|
@@ -1722,19 +1728,33 @@ static bool _psr_compute_config(struct intel_dp *intel_dp,
|
|
return true;
|
|
}
|
|
|
|
-static bool
|
|
-_panel_replay_compute_config(struct intel_dp *intel_dp,
|
|
- struct intel_crtc_state *crtc_state,
|
|
- const struct drm_connector_state *conn_state)
|
|
+static inline bool compute_link_off_after_as_sdp_when_pr_active(struct intel_connector *connector)
|
|
+{
|
|
+ return (connector->dp.panel_replay_caps.dpcd[INTEL_PR_DPCD_INDEX(DP_PANEL_REPLAY_CAP_CAPABILITY)] &
|
|
+ DP_PANEL_REPLAY_LINK_OFF_SUPPORTED_IN_PR_AFTER_ADAPTIVE_SYNC_SDP);
|
|
+}
|
|
+
|
|
+static inline bool compute_disable_as_sdp_when_pr_active(struct intel_connector *connector)
|
|
+{
|
|
+ return !(connector->dp.panel_replay_caps.dpcd[INTEL_PR_DPCD_INDEX(DP_PANEL_REPLAY_CAP_CAPABILITY)] &
|
|
+ DP_PANEL_REPLAY_ASYNC_VIDEO_TIMING_NOT_SUPPORTED_IN_PR);
|
|
+}
|
|
+
|
|
+static bool _panel_replay_compute_config(struct intel_crtc_state *crtc_state,
|
|
+ const struct drm_connector_state *conn_state)
|
|
{
|
|
- struct intel_display *display = to_intel_display(intel_dp);
|
|
struct intel_connector *connector =
|
|
to_intel_connector(conn_state->connector);
|
|
+ struct intel_dp *intel_dp = intel_attached_dp(connector);
|
|
+ struct intel_display *display = to_intel_display(intel_dp);
|
|
struct intel_hdcp *hdcp = &connector->hdcp;
|
|
|
|
if (!CAN_PANEL_REPLAY(intel_dp))
|
|
return false;
|
|
|
|
+ if (!connector->dp.panel_replay_caps.support)
|
|
+ return false;
|
|
+
|
|
if (!panel_replay_global_enabled(intel_dp)) {
|
|
drm_dbg_kms(display->drm, "Panel Replay disabled by flag\n");
|
|
return false;
|
|
@@ -1747,13 +1767,16 @@ _panel_replay_compute_config(struct intel_dp *intel_dp,
|
|
}
|
|
|
|
if (intel_dsc_enabled_on_link(crtc_state) &&
|
|
- intel_dp->psr.sink_panel_replay_dsc_support ==
|
|
+ connector->dp.panel_replay_caps.dsc_support ==
|
|
INTEL_DP_PANEL_REPLAY_DSC_NOT_SUPPORTED) {
|
|
drm_dbg_kms(display->drm,
|
|
"Panel Replay not enabled because it's not supported with DSC\n");
|
|
return false;
|
|
}
|
|
|
|
+ crtc_state->link_off_after_as_sdp_when_pr_active = compute_link_off_after_as_sdp_when_pr_active(connector);
|
|
+ crtc_state->disable_as_sdp_when_pr_active = compute_disable_as_sdp_when_pr_active(connector);
|
|
+
|
|
if (!intel_dp_is_edp(intel_dp))
|
|
return true;
|
|
|
|
@@ -1829,6 +1852,7 @@ void intel_psr_compute_config(struct intel_dp *intel_dp,
|
|
struct drm_connector_state *conn_state)
|
|
{
|
|
struct intel_display *display = to_intel_display(intel_dp);
|
|
+ struct intel_connector *connector = to_intel_connector(conn_state->connector);
|
|
const struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode;
|
|
|
|
if (!psr_global_enabled(intel_dp)) {
|
|
@@ -1860,18 +1884,16 @@ void intel_psr_compute_config(struct intel_dp *intel_dp,
|
|
}
|
|
|
|
/* Only used for state verification. */
|
|
- crtc_state->panel_replay_dsc_support = intel_dp->psr.sink_panel_replay_dsc_support;
|
|
- crtc_state->has_panel_replay = _panel_replay_compute_config(intel_dp,
|
|
- crtc_state,
|
|
- conn_state);
|
|
+ crtc_state->panel_replay_dsc_support = connector->dp.panel_replay_caps.dsc_support;
|
|
+ crtc_state->has_panel_replay = _panel_replay_compute_config(crtc_state, conn_state);
|
|
|
|
crtc_state->has_psr = crtc_state->has_panel_replay ? true :
|
|
- _psr_compute_config(intel_dp, crtc_state);
|
|
+ _psr_compute_config(intel_dp, crtc_state, conn_state);
|
|
|
|
if (!crtc_state->has_psr)
|
|
return;
|
|
|
|
- crtc_state->has_sel_update = intel_sel_update_config_valid(intel_dp, crtc_state);
|
|
+ crtc_state->has_sel_update = intel_sel_update_config_valid(crtc_state, conn_state);
|
|
}
|
|
|
|
void intel_psr_get_config(struct intel_encoder *encoder,
|
|
@@ -2771,7 +2793,8 @@ static bool psr2_sel_fetch_plane_state_supported(const struct intel_plane_state
|
|
*/
|
|
static bool psr2_sel_fetch_pipe_state_supported(const struct intel_crtc_state *crtc_state)
|
|
{
|
|
- if (crtc_state->scaler_state.scaler_id >= 0)
|
|
+ if (crtc_state->scaler_state.scaler_id >= 0 ||
|
|
+ crtc_state->async_flip_planes)
|
|
return false;
|
|
|
|
return true;
|
|
@@ -4161,24 +4184,22 @@ psr_source_status(struct intel_dp *intel_dp, struct seq_file *m)
|
|
seq_printf(m, "Source PSR/PanelReplay status: %s [0x%08x]\n", status, val);
|
|
}
|
|
|
|
-static void intel_psr_sink_capability(struct intel_dp *intel_dp,
|
|
+static void intel_psr_sink_capability(struct intel_connector *connector,
|
|
struct seq_file *m)
|
|
{
|
|
- struct intel_psr *psr = &intel_dp->psr;
|
|
-
|
|
seq_printf(m, "Sink support: PSR = %s",
|
|
- str_yes_no(psr->sink_support));
|
|
+ str_yes_no(connector->dp.psr_caps.support));
|
|
|
|
- if (psr->sink_support)
|
|
- seq_printf(m, " [0x%02x]", intel_dp->psr_dpcd[0]);
|
|
- if (intel_dp->psr_dpcd[0] == DP_PSR2_WITH_Y_COORD_ET_SUPPORTED)
|
|
+ if (connector->dp.psr_caps.support)
|
|
+ seq_printf(m, " [0x%02x]", connector->dp.psr_caps.dpcd[0]);
|
|
+ if (connector->dp.psr_caps.dpcd[0] == DP_PSR2_WITH_Y_COORD_ET_SUPPORTED)
|
|
seq_printf(m, " (Early Transport)");
|
|
- seq_printf(m, ", Panel Replay = %s", str_yes_no(psr->sink_panel_replay_support));
|
|
+ seq_printf(m, ", Panel Replay = %s", str_yes_no(connector->dp.panel_replay_caps.support));
|
|
seq_printf(m, ", Panel Replay Selective Update = %s",
|
|
- str_yes_no(psr->sink_panel_replay_su_support));
|
|
+ str_yes_no(connector->dp.panel_replay_caps.su_support));
|
|
seq_printf(m, ", Panel Replay DSC support = %s",
|
|
- panel_replay_dsc_support_str(psr->sink_panel_replay_dsc_support));
|
|
- if (intel_dp->pr_dpcd[INTEL_PR_DPCD_INDEX(DP_PANEL_REPLAY_CAP_SUPPORT)] &
|
|
+ panel_replay_dsc_support_str(connector->dp.panel_replay_caps.dsc_support));
|
|
+ if (connector->dp.panel_replay_caps.dpcd[INTEL_PR_DPCD_INDEX(DP_PANEL_REPLAY_CAP_SUPPORT)] &
|
|
DP_PANEL_REPLAY_EARLY_TRANSPORT_SUPPORT)
|
|
seq_printf(m, " (Early Transport)");
|
|
seq_printf(m, "\n");
|
|
@@ -4216,7 +4237,8 @@ static void intel_psr_print_mode(struct intel_dp *intel_dp,
|
|
seq_printf(m, " %s\n", psr->no_psr_reason);
|
|
}
|
|
|
|
-static int intel_psr_status(struct seq_file *m, struct intel_dp *intel_dp)
|
|
+static int intel_psr_status(struct seq_file *m, struct intel_dp *intel_dp,
|
|
+ struct intel_connector *connector)
|
|
{
|
|
struct intel_display *display = to_intel_display(intel_dp);
|
|
enum transcoder cpu_transcoder = intel_dp->psr.transcoder;
|
|
@@ -4225,9 +4247,9 @@ static int intel_psr_status(struct seq_file *m, struct intel_dp *intel_dp)
|
|
bool enabled;
|
|
u32 val, psr2_ctl;
|
|
|
|
- intel_psr_sink_capability(intel_dp, m);
|
|
+ intel_psr_sink_capability(connector, m);
|
|
|
|
- if (!(psr->sink_support || psr->sink_panel_replay_support))
|
|
+ if (!(connector->dp.psr_caps.support || connector->dp.panel_replay_caps.support))
|
|
return 0;
|
|
|
|
wakeref = intel_display_rpm_get(display);
|
|
@@ -4341,7 +4363,7 @@ static int i915_edp_psr_status_show(struct seq_file *m, void *data)
|
|
if (!intel_dp)
|
|
return -ENODEV;
|
|
|
|
- return intel_psr_status(m, intel_dp);
|
|
+ return intel_psr_status(m, intel_dp, intel_dp->attached_connector);
|
|
}
|
|
DEFINE_SHOW_ATTRIBUTE(i915_edp_psr_status);
|
|
|
|
@@ -4475,7 +4497,7 @@ static int i915_psr_status_show(struct seq_file *m, void *data)
|
|
struct intel_connector *connector = m->private;
|
|
struct intel_dp *intel_dp = intel_attached_dp(connector);
|
|
|
|
- return intel_psr_status(m, intel_dp);
|
|
+ return intel_psr_status(m, intel_dp, connector);
|
|
}
|
|
DEFINE_SHOW_ATTRIBUTE(i915_psr_status);
|
|
|
|
diff --git a/drivers/gpu/drm/i915/display/intel_psr.h b/drivers/gpu/drm/i915/display/intel_psr.h
|
|
index 620b359288326..688ca3e73cdda 100644
|
|
--- a/drivers/gpu/drm/i915/display/intel_psr.h
|
|
+++ b/drivers/gpu/drm/i915/display/intel_psr.h
|
|
@@ -28,7 +28,7 @@ struct intel_plane_state;
|
|
bool intel_encoder_can_psr(struct intel_encoder *encoder);
|
|
bool intel_psr_needs_aux_io_power(struct intel_encoder *encoder,
|
|
const struct intel_crtc_state *crtc_state);
|
|
-void intel_psr_init_dpcd(struct intel_dp *intel_dp);
|
|
+void intel_psr_init_dpcd(struct intel_dp *intel_dp, struct intel_connector *connector);
|
|
void intel_psr_panel_replay_enable_sink(struct intel_dp *intel_dp);
|
|
void intel_psr_pre_plane_update(struct intel_atomic_state *state,
|
|
struct intel_crtc *crtc);
|
|
diff --git a/drivers/hid/hid-rmi.c b/drivers/hid/hid-rmi.c
|
|
index d4af17fdba467..154f0403cbf4c 100644
|
|
--- a/drivers/hid/hid-rmi.c
|
|
+++ b/drivers/hid/hid-rmi.c
|
|
@@ -321,21 +321,12 @@ static int rmi_input_event(struct hid_device *hdev, u8 *data, int size)
|
|
{
|
|
struct rmi_data *hdata = hid_get_drvdata(hdev);
|
|
struct rmi_device *rmi_dev = hdata->xport.rmi_dev;
|
|
- unsigned long flags;
|
|
|
|
if (!(test_bit(RMI_STARTED, &hdata->flags)))
|
|
return 0;
|
|
|
|
- pm_wakeup_event(hdev->dev.parent, 0);
|
|
-
|
|
- local_irq_save(flags);
|
|
-
|
|
rmi_set_attn_data(rmi_dev, data[1], &data[2], size - 2);
|
|
|
|
- generic_handle_irq(hdata->rmi_irq);
|
|
-
|
|
- local_irq_restore(flags);
|
|
-
|
|
return 1;
|
|
}
|
|
|
|
@@ -589,56 +580,6 @@ static const struct rmi_transport_ops hid_rmi_ops = {
|
|
.reset = rmi_hid_reset,
|
|
};
|
|
|
|
-static void rmi_irq_teardown(void *data)
|
|
-{
|
|
- struct rmi_data *hdata = data;
|
|
- struct irq_domain *domain = hdata->domain;
|
|
-
|
|
- if (!domain)
|
|
- return;
|
|
-
|
|
- irq_dispose_mapping(irq_find_mapping(domain, 0));
|
|
-
|
|
- irq_domain_remove(domain);
|
|
- hdata->domain = NULL;
|
|
- hdata->rmi_irq = 0;
|
|
-}
|
|
-
|
|
-static int rmi_irq_map(struct irq_domain *h, unsigned int virq,
|
|
- irq_hw_number_t hw_irq_num)
|
|
-{
|
|
- irq_set_chip_and_handler(virq, &dummy_irq_chip, handle_simple_irq);
|
|
-
|
|
- return 0;
|
|
-}
|
|
-
|
|
-static const struct irq_domain_ops rmi_irq_ops = {
|
|
- .map = rmi_irq_map,
|
|
-};
|
|
-
|
|
-static int rmi_setup_irq_domain(struct hid_device *hdev)
|
|
-{
|
|
- struct rmi_data *hdata = hid_get_drvdata(hdev);
|
|
- int ret;
|
|
-
|
|
- hdata->domain = irq_domain_create_linear(hdev->dev.fwnode, 1,
|
|
- &rmi_irq_ops, hdata);
|
|
- if (!hdata->domain)
|
|
- return -ENOMEM;
|
|
-
|
|
- ret = devm_add_action_or_reset(&hdev->dev, &rmi_irq_teardown, hdata);
|
|
- if (ret)
|
|
- return ret;
|
|
-
|
|
- hdata->rmi_irq = irq_create_mapping(hdata->domain, 0);
|
|
- if (hdata->rmi_irq <= 0) {
|
|
- hid_err(hdev, "Can't allocate an IRQ\n");
|
|
- return hdata->rmi_irq < 0 ? hdata->rmi_irq : -ENXIO;
|
|
- }
|
|
-
|
|
- return 0;
|
|
-}
|
|
-
|
|
static int rmi_probe(struct hid_device *hdev, const struct hid_device_id *id)
|
|
{
|
|
struct rmi_data *data = NULL;
|
|
@@ -711,18 +652,11 @@ static int rmi_probe(struct hid_device *hdev, const struct hid_device_id *id)
|
|
|
|
mutex_init(&data->page_mutex);
|
|
|
|
- ret = rmi_setup_irq_domain(hdev);
|
|
- if (ret) {
|
|
- hid_err(hdev, "failed to allocate IRQ domain\n");
|
|
- return ret;
|
|
- }
|
|
-
|
|
if (data->device_flags & RMI_DEVICE_HAS_PHYS_BUTTONS)
|
|
rmi_hid_pdata.gpio_data.disable = true;
|
|
|
|
data->xport.dev = hdev->dev.parent;
|
|
data->xport.pdata = rmi_hid_pdata;
|
|
- data->xport.pdata.irq = data->rmi_irq;
|
|
data->xport.proto_name = "hid";
|
|
data->xport.ops = &hid_rmi_ops;
|
|
|
|
diff --git a/drivers/hid/intel-ish-hid/ishtp/loader.c b/drivers/hid/intel-ish-hid/ishtp/loader.c
|
|
index f34086b29cf08..ffa2042bb316e 100644
|
|
--- a/drivers/hid/intel-ish-hid/ishtp/loader.c
|
|
+++ b/drivers/hid/intel-ish-hid/ishtp/loader.c
|
|
@@ -195,13 +195,19 @@ static int prepare_dma_bufs(struct ishtp_device *dev,
|
|
return 0;
|
|
}
|
|
|
|
+/* Patterns with PRODUCT_FAMILY */
|
|
+#define ISH_FW_FILE_VENDOR_FAMILY_NAME_SKU_FMT "intel/ish/ish_%s_%08x_%08x_%08x_%08x.bin"
|
|
+#define ISH_FW_FILE_VENDOR_FAMILY_SKU_FMT "intel/ish/ish_%s_%08x_%08x_%08x.bin"
|
|
+#define ISH_FW_FILE_VENDOR_FAMILY_NAME_FMT "intel/ish/ish_%s_%08x_%08x_%08x.bin"
|
|
+#define ISH_FW_FILE_VENDOR_FAMILY_FMT "intel/ish/ish_%s_%08x_%08x.bin"
|
|
+
|
|
#define ISH_FW_FILE_VENDOR_NAME_SKU_FMT "intel/ish/ish_%s_%08x_%08x_%08x.bin"
|
|
#define ISH_FW_FILE_VENDOR_SKU_FMT "intel/ish/ish_%s_%08x_%08x.bin"
|
|
#define ISH_FW_FILE_VENDOR_NAME_FMT "intel/ish/ish_%s_%08x_%08x.bin"
|
|
#define ISH_FW_FILE_VENDOR_FMT "intel/ish/ish_%s_%08x.bin"
|
|
#define ISH_FW_FILE_DEFAULT_FMT "intel/ish/ish_%s.bin"
|
|
|
|
-#define ISH_FW_FILENAME_LEN_MAX 56
|
|
+#define ISH_FW_FILENAME_LEN_MAX 72
|
|
|
|
#define ISH_CRC_INIT (~0u)
|
|
#define ISH_CRC_XOROUT (~0u)
|
|
@@ -228,6 +234,12 @@ static int _request_ish_firmware(const struct firmware **firmware_p,
|
|
* for the given device in the following order, prioritizing custom firmware
|
|
* with more precise matching patterns:
|
|
*
|
|
+ * ish_${fw_generation}_${SYS_VENDOR_CRC32}_$(PRODUCT_FAMILY_CRC32)
|
|
+ * _$(PRODUCT_NAME_CRC32)_${PRODUCT_SKU_CRC32}.bin
|
|
+ *
|
|
+ * ish_${fw_generation}_${SYS_VENDOR_CRC32}_$(PRODUCT_FAMILY_CRC32)_${PRODUCT_SKU_CRC32}.bin
|
|
+ * ish_${fw_generation}_${SYS_VENDOR_CRC32}_$(PRODUCT_FAMILY_CRC32)_$(PRODUCT_NAME_CRC32).bin
|
|
+ * ish_${fw_generation}_${SYS_VENDOR_CRC32}_$(PRODUCT_FAMILY_CRC32).bin
|
|
* ish_${fw_generation}_${SYS_VENDOR_CRC32}_$(PRODUCT_NAME_CRC32)_${PRODUCT_SKU_CRC32}.bin
|
|
* ish_${fw_generation}_${SYS_VENDOR_CRC32}_${PRODUCT_SKU_CRC32}.bin
|
|
* ish_${fw_generation}_${SYS_VENDOR_CRC32}_$(PRODUCT_NAME_CRC32).bin
|
|
@@ -256,8 +268,9 @@ static int request_ish_firmware(const struct firmware **firmware_p,
|
|
struct device *dev)
|
|
{
|
|
const char *gen, *sys_vendor, *product_name, *product_sku;
|
|
+ const char *product_family;
|
|
struct ishtp_device *ishtp = dev_get_drvdata(dev);
|
|
- u32 vendor_crc, name_crc, sku_crc;
|
|
+ u32 vendor_crc, name_crc, sku_crc, family_crc;
|
|
char filename[ISH_FW_FILENAME_LEN_MAX];
|
|
int ret;
|
|
|
|
@@ -265,14 +278,55 @@ static int request_ish_firmware(const struct firmware **firmware_p,
|
|
sys_vendor = dmi_get_system_info(DMI_SYS_VENDOR);
|
|
product_name = dmi_get_system_info(DMI_PRODUCT_NAME);
|
|
product_sku = dmi_get_system_info(DMI_PRODUCT_SKU);
|
|
+ product_family = dmi_get_system_info(DMI_PRODUCT_FAMILY);
|
|
|
|
if (sys_vendor)
|
|
vendor_crc = crc32(ISH_CRC_INIT, sys_vendor, strlen(sys_vendor)) ^ ISH_CRC_XOROUT;
|
|
+ if (product_family)
|
|
+ family_crc = crc32(ISH_CRC_INIT, product_family,
|
|
+ strlen(product_family)) ^ ISH_CRC_XOROUT;
|
|
if (product_name)
|
|
name_crc = crc32(ISH_CRC_INIT, product_name, strlen(product_name)) ^ ISH_CRC_XOROUT;
|
|
if (product_sku)
|
|
sku_crc = crc32(ISH_CRC_INIT, product_sku, strlen(product_sku)) ^ ISH_CRC_XOROUT;
|
|
|
|
+ /* PRODUCT_FAMILY-extended matching */
|
|
+ if (sys_vendor && product_family && product_name && product_sku) {
|
|
+ snprintf(filename, sizeof(filename),
|
|
+ ISH_FW_FILE_VENDOR_FAMILY_NAME_SKU_FMT,
|
|
+ gen, vendor_crc, family_crc, name_crc, sku_crc);
|
|
+ ret = _request_ish_firmware(firmware_p, filename, dev);
|
|
+ if (!ret)
|
|
+ return 0;
|
|
+ }
|
|
+
|
|
+ if (sys_vendor && product_family && product_sku) {
|
|
+ snprintf(filename, sizeof(filename),
|
|
+ ISH_FW_FILE_VENDOR_FAMILY_SKU_FMT,
|
|
+ gen, vendor_crc, family_crc, sku_crc);
|
|
+ ret = _request_ish_firmware(firmware_p, filename, dev);
|
|
+ if (!ret)
|
|
+ return 0;
|
|
+ }
|
|
+
|
|
+ if (sys_vendor && product_family && product_name) {
|
|
+ snprintf(filename, sizeof(filename),
|
|
+ ISH_FW_FILE_VENDOR_FAMILY_NAME_FMT,
|
|
+ gen, vendor_crc, family_crc, name_crc);
|
|
+ ret = _request_ish_firmware(firmware_p, filename, dev);
|
|
+ if (!ret)
|
|
+ return 0;
|
|
+ }
|
|
+
|
|
+ if (sys_vendor && product_family) {
|
|
+ snprintf(filename, sizeof(filename),
|
|
+ ISH_FW_FILE_VENDOR_FAMILY_FMT,
|
|
+ gen, vendor_crc, family_crc);
|
|
+ ret = _request_ish_firmware(firmware_p, filename, dev);
|
|
+ if (!ret)
|
|
+ return 0;
|
|
+}
|
|
+
|
|
if (sys_vendor && product_name && product_sku) {
|
|
snprintf(filename, sizeof(filename), ISH_FW_FILE_VENDOR_NAME_SKU_FMT, gen,
|
|
vendor_crc, name_crc, sku_crc);
|
|
diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c b/drivers/hwtracing/coresight/coresight-etm4x-core.c
|
|
index 560975b70474c..995bf2da877ce 100644
|
|
--- a/drivers/hwtracing/coresight/coresight-etm4x-core.c
|
|
+++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c
|
|
@@ -12,6 +12,7 @@
|
|
#include <linux/init.h>
|
|
#include <linux/types.h>
|
|
#include <linux/device.h>
|
|
+#include <linux/dmi.h>
|
|
#include <linux/io.h>
|
|
#include <linux/err.h>
|
|
#include <linux/fs.h>
|
|
@@ -2498,6 +2499,16 @@ static const struct amba_id etm4_ids[] = {
|
|
{},
|
|
};
|
|
|
|
+static const struct dmi_system_id broken_coresight[] = {
|
|
+ {
|
|
+ .matches = {
|
|
+ DMI_MATCH(DMI_SYS_VENDOR, "HPE"),
|
|
+ DMI_MATCH(DMI_PRODUCT_NAME, "Apollo 70"),
|
|
+ },
|
|
+ },
|
|
+ { } /* terminating entry */
|
|
+};
|
|
+
|
|
MODULE_DEVICE_TABLE(amba, etm4_ids);
|
|
|
|
static struct amba_driver etm4x_amba_driver = {
|
|
@@ -2572,6 +2583,11 @@ static int __init etm4x_init(void)
|
|
{
|
|
int ret;
|
|
|
|
+ if (dmi_check_system(broken_coresight)) {
|
|
+ pr_info("ETM4 disabled due to firmware bug\n");
|
|
+ return 0;
|
|
+ }
|
|
+
|
|
ret = etm4_pm_setup();
|
|
|
|
/* etm4_pm_setup() does its own cleanup - exit on error */
|
|
@@ -2598,6 +2614,9 @@ static int __init etm4x_init(void)
|
|
|
|
static void __exit etm4x_exit(void)
|
|
{
|
|
+ if (dmi_check_system(broken_coresight))
|
|
+ return;
|
|
+
|
|
amba_driver_unregister(&etm4x_amba_driver);
|
|
platform_driver_unregister(&etm4_platform_driver);
|
|
etm4_pm_clear();
|
|
diff --git a/drivers/input/rmi4/rmi_driver.c b/drivers/input/rmi4/rmi_driver.c
|
|
index ccd9338a44dbe..5c54e522e8a47 100644
|
|
--- a/drivers/input/rmi4/rmi_driver.c
|
|
+++ b/drivers/input/rmi4/rmi_driver.c
|
|
@@ -183,34 +183,47 @@ void rmi_set_attn_data(struct rmi_device *rmi_dev, unsigned long irq_status,
|
|
attn_data.data = fifo_data;
|
|
|
|
kfifo_put(&drvdata->attn_fifo, attn_data);
|
|
+
|
|
+ schedule_work(&drvdata->attn_work);
|
|
}
|
|
EXPORT_SYMBOL_GPL(rmi_set_attn_data);
|
|
|
|
-static irqreturn_t rmi_irq_fn(int irq, void *dev_id)
|
|
+static void attn_callback(struct work_struct *work)
|
|
{
|
|
- struct rmi_device *rmi_dev = dev_id;
|
|
- struct rmi_driver_data *drvdata = dev_get_drvdata(&rmi_dev->dev);
|
|
+ struct rmi_driver_data *drvdata = container_of(work,
|
|
+ struct rmi_driver_data,
|
|
+ attn_work);
|
|
struct rmi4_attn_data attn_data = {0};
|
|
int ret, count;
|
|
|
|
count = kfifo_get(&drvdata->attn_fifo, &attn_data);
|
|
- if (count) {
|
|
- *(drvdata->irq_status) = attn_data.irq_status;
|
|
- drvdata->attn_data = attn_data;
|
|
- }
|
|
+ if (!count)
|
|
+ return;
|
|
|
|
- ret = rmi_process_interrupt_requests(rmi_dev);
|
|
+ *(drvdata->irq_status) = attn_data.irq_status;
|
|
+ drvdata->attn_data = attn_data;
|
|
+
|
|
+ ret = rmi_process_interrupt_requests(drvdata->rmi_dev);
|
|
if (ret)
|
|
- rmi_dbg(RMI_DEBUG_CORE, &rmi_dev->dev,
|
|
+ rmi_dbg(RMI_DEBUG_CORE, &drvdata->rmi_dev->dev,
|
|
"Failed to process interrupt request: %d\n", ret);
|
|
|
|
- if (count) {
|
|
- kfree(attn_data.data);
|
|
- drvdata->attn_data.data = NULL;
|
|
- }
|
|
+ kfree(attn_data.data);
|
|
+ drvdata->attn_data.data = NULL;
|
|
|
|
if (!kfifo_is_empty(&drvdata->attn_fifo))
|
|
- return rmi_irq_fn(irq, dev_id);
|
|
+ schedule_work(&drvdata->attn_work);
|
|
+}
|
|
+
|
|
+static irqreturn_t rmi_irq_fn(int irq, void *dev_id)
|
|
+{
|
|
+ struct rmi_device *rmi_dev = dev_id;
|
|
+ int ret;
|
|
+
|
|
+ ret = rmi_process_interrupt_requests(rmi_dev);
|
|
+ if (ret)
|
|
+ rmi_dbg(RMI_DEBUG_CORE, &rmi_dev->dev,
|
|
+ "Failed to process interrupt request: %d\n", ret);
|
|
|
|
return IRQ_HANDLED;
|
|
}
|
|
@@ -218,7 +231,6 @@ static irqreturn_t rmi_irq_fn(int irq, void *dev_id)
|
|
static int rmi_irq_init(struct rmi_device *rmi_dev)
|
|
{
|
|
struct rmi_device_platform_data *pdata = rmi_get_platform_data(rmi_dev);
|
|
- struct rmi_driver_data *data = dev_get_drvdata(&rmi_dev->dev);
|
|
int irq_flags = irq_get_trigger_type(pdata->irq);
|
|
int ret;
|
|
|
|
@@ -236,8 +248,6 @@ static int rmi_irq_init(struct rmi_device *rmi_dev)
|
|
return ret;
|
|
}
|
|
|
|
- data->enabled = true;
|
|
-
|
|
return 0;
|
|
}
|
|
|
|
@@ -887,23 +897,27 @@ void rmi_enable_irq(struct rmi_device *rmi_dev, bool clear_wake)
|
|
if (data->enabled)
|
|
goto out;
|
|
|
|
- enable_irq(irq);
|
|
- data->enabled = true;
|
|
- if (clear_wake && device_may_wakeup(rmi_dev->xport->dev)) {
|
|
- retval = disable_irq_wake(irq);
|
|
- if (retval)
|
|
- dev_warn(&rmi_dev->dev,
|
|
- "Failed to disable irq for wake: %d\n",
|
|
- retval);
|
|
- }
|
|
+ if (irq) {
|
|
+ enable_irq(irq);
|
|
+ data->enabled = true;
|
|
+ if (clear_wake && device_may_wakeup(rmi_dev->xport->dev)) {
|
|
+ retval = disable_irq_wake(irq);
|
|
+ if (retval)
|
|
+ dev_warn(&rmi_dev->dev,
|
|
+ "Failed to disable irq for wake: %d\n",
|
|
+ retval);
|
|
+ }
|
|
|
|
- /*
|
|
- * Call rmi_process_interrupt_requests() after enabling irq,
|
|
- * otherwise we may lose interrupt on edge-triggered systems.
|
|
- */
|
|
- irq_flags = irq_get_trigger_type(pdata->irq);
|
|
- if (irq_flags & IRQ_TYPE_EDGE_BOTH)
|
|
- rmi_process_interrupt_requests(rmi_dev);
|
|
+ /*
|
|
+ * Call rmi_process_interrupt_requests() after enabling irq,
|
|
+ * otherwise we may lose interrupt on edge-triggered systems.
|
|
+ */
|
|
+ irq_flags = irq_get_trigger_type(pdata->irq);
|
|
+ if (irq_flags & IRQ_TYPE_EDGE_BOTH)
|
|
+ rmi_process_interrupt_requests(rmi_dev);
|
|
+ } else {
|
|
+ data->enabled = true;
|
|
+ }
|
|
|
|
out:
|
|
mutex_unlock(&data->enabled_mutex);
|
|
@@ -923,20 +937,22 @@ void rmi_disable_irq(struct rmi_device *rmi_dev, bool enable_wake)
|
|
goto out;
|
|
|
|
data->enabled = false;
|
|
- disable_irq(irq);
|
|
- if (enable_wake && device_may_wakeup(rmi_dev->xport->dev)) {
|
|
- retval = enable_irq_wake(irq);
|
|
- if (retval)
|
|
- dev_warn(&rmi_dev->dev,
|
|
- "Failed to enable irq for wake: %d\n",
|
|
- retval);
|
|
- }
|
|
-
|
|
- /* make sure the fifo is clean */
|
|
- while (!kfifo_is_empty(&data->attn_fifo)) {
|
|
- count = kfifo_get(&data->attn_fifo, &attn_data);
|
|
- if (count)
|
|
- kfree(attn_data.data);
|
|
+ if (irq) {
|
|
+ disable_irq(irq);
|
|
+ if (enable_wake && device_may_wakeup(rmi_dev->xport->dev)) {
|
|
+ retval = enable_irq_wake(irq);
|
|
+ if (retval)
|
|
+ dev_warn(&rmi_dev->dev,
|
|
+ "Failed to enable irq for wake: %d\n",
|
|
+ retval);
|
|
+ }
|
|
+ } else {
|
|
+ /* make sure the fifo is clean */
|
|
+ while (!kfifo_is_empty(&data->attn_fifo)) {
|
|
+ count = kfifo_get(&data->attn_fifo, &attn_data);
|
|
+ if (count)
|
|
+ kfree(attn_data.data);
|
|
+ }
|
|
}
|
|
|
|
out:
|
|
@@ -979,6 +995,8 @@ static int rmi_driver_remove(struct device *dev)
|
|
|
|
rmi_disable_irq(rmi_dev, false);
|
|
|
|
+ cancel_work_sync(&data->attn_work);
|
|
+
|
|
rmi_f34_remove_sysfs(rmi_dev);
|
|
rmi_free_function_list(rmi_dev);
|
|
|
|
@@ -1224,9 +1242,15 @@ static int rmi_driver_probe(struct device *dev)
|
|
}
|
|
}
|
|
|
|
- retval = rmi_irq_init(rmi_dev);
|
|
- if (retval < 0)
|
|
- goto err_destroy_functions;
|
|
+ if (pdata->irq) {
|
|
+ retval = rmi_irq_init(rmi_dev);
|
|
+ if (retval < 0)
|
|
+ goto err_destroy_functions;
|
|
+ }
|
|
+
|
|
+ data->enabled = true;
|
|
+
|
|
+ INIT_WORK(&data->attn_work, attn_callback);
|
|
|
|
if (data->f01_container->dev.driver) {
|
|
/* Driver already bound, so enable ATTN now. */
|
|
diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
|
|
index 3a0c0e4b42fff..24c31555fb69a 100644
|
|
--- a/drivers/iommu/iommu.c
|
|
+++ b/drivers/iommu/iommu.c
|
|
@@ -8,6 +8,7 @@
|
|
|
|
#include <linux/amba/bus.h>
|
|
#include <linux/device.h>
|
|
+#include <linux/dmi.h>
|
|
#include <linux/kernel.h>
|
|
#include <linux/bits.h>
|
|
#include <linux/bug.h>
|
|
@@ -2989,6 +2990,27 @@ int iommu_fwspec_add_ids(struct device *dev, const u32 *ids, int num_ids)
|
|
}
|
|
EXPORT_SYMBOL_GPL(iommu_fwspec_add_ids);
|
|
|
|
+#ifdef CONFIG_ARM64
|
|
+static int __init iommu_quirks(void)
|
|
+{
|
|
+ const char *vendor, *name;
|
|
+
|
|
+ vendor = dmi_get_system_info(DMI_SYS_VENDOR);
|
|
+ name = dmi_get_system_info(DMI_PRODUCT_NAME);
|
|
+
|
|
+ if (vendor &&
|
|
+ (strncmp(vendor, "GIGABYTE", 8) == 0 && name &&
|
|
+ (strncmp(name, "R120", 4) == 0 ||
|
|
+ strncmp(name, "R270", 4) == 0))) {
|
|
+ pr_warn("Gigabyte %s detected, force iommu passthrough mode", name);
|
|
+ iommu_def_domain_type = IOMMU_DOMAIN_IDENTITY;
|
|
+ }
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+arch_initcall(iommu_quirks);
|
|
+#endif
|
|
+
|
|
/**
|
|
* iommu_setup_default_domain - Set the default_domain for the group
|
|
* @group: Group to change
|
|
diff --git a/drivers/media/pci/intel/ipu-bridge.c b/drivers/media/pci/intel/ipu-bridge.c
|
|
index b2b710094914c..fd3c46aa0350e 100644
|
|
--- a/drivers/media/pci/intel/ipu-bridge.c
|
|
+++ b/drivers/media/pci/intel/ipu-bridge.c
|
|
@@ -104,6 +104,13 @@ static const struct ipu_sensor_config ipu_supported_sensors[] = {
|
|
* without reporting a rotation of 180° in neither the SSDB nor the _PLD.
|
|
*/
|
|
static const struct dmi_system_id upside_down_sensor_dmi_ids[] = {
|
|
+ {
|
|
+ .matches = {
|
|
+ DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
|
|
+ DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "XPS 13 9340"),
|
|
+ },
|
|
+ .driver_data = "OVTI02C1",
|
|
+ },
|
|
{
|
|
.matches = {
|
|
DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
|
|
@@ -111,6 +118,13 @@ static const struct dmi_system_id upside_down_sensor_dmi_ids[] = {
|
|
},
|
|
.driver_data = "OVTI02C1",
|
|
},
|
|
+ {
|
|
+ .matches = {
|
|
+ DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
|
|
+ DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "XPS 14 9440"),
|
|
+ },
|
|
+ .driver_data = "OVTI02C1",
|
|
+ },
|
|
{
|
|
.matches = {
|
|
DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
|
|
diff --git a/drivers/mfd/bcm2835-pm.c b/drivers/mfd/bcm2835-pm.c
|
|
index 8bed59816e82e..9e8e3dcf4bceb 100644
|
|
--- a/drivers/mfd/bcm2835-pm.c
|
|
+++ b/drivers/mfd/bcm2835-pm.c
|
|
@@ -81,6 +81,7 @@ static int bcm2835_pm_probe(struct platform_device *pdev)
|
|
platform_set_drvdata(pdev, pm);
|
|
|
|
pm->dev = dev;
|
|
+ pm->soc = (uintptr_t)device_get_match_data(dev);
|
|
|
|
ret = bcm2835_pm_get_pdata(pdev, pm);
|
|
if (ret)
|
|
@@ -97,7 +98,7 @@ static int bcm2835_pm_probe(struct platform_device *pdev)
|
|
* bcm2835-pm binding as the key for whether we can reference
|
|
* the full PM register range and support power domains.
|
|
*/
|
|
- if (pm->asb)
|
|
+ if (pm->asb || pm->soc == BCM2835_PM_SOC_BCM2712)
|
|
return devm_mfd_add_devices(dev, -1, bcm2835_power_devs,
|
|
ARRAY_SIZE(bcm2835_power_devs),
|
|
NULL, 0, NULL);
|
|
@@ -106,9 +107,9 @@ static int bcm2835_pm_probe(struct platform_device *pdev)
|
|
|
|
static const struct of_device_id bcm2835_pm_of_match[] = {
|
|
{ .compatible = "brcm,bcm2835-pm-wdt", },
|
|
- { .compatible = "brcm,bcm2835-pm", },
|
|
- { .compatible = "brcm,bcm2711-pm", },
|
|
- { .compatible = "brcm,bcm2712-pm", },
|
|
+ { .compatible = "brcm,bcm2835-pm", .data = (void *)BCM2835_PM_SOC_BCM2835 },
|
|
+ { .compatible = "brcm,bcm2711-pm", .data = (void *)BCM2835_PM_SOC_BCM2711 },
|
|
+ { .compatible = "brcm,bcm2712-pm", .data = (void *)BCM2835_PM_SOC_BCM2712 },
|
|
{},
|
|
};
|
|
MODULE_DEVICE_TABLE(of, bcm2835_pm_of_match);
|
|
diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c
|
|
index ba794f2325f10..ddf2bb4d25194 100644
|
|
--- a/drivers/net/ethernet/cadence/macb_main.c
|
|
+++ b/drivers/net/ethernet/cadence/macb_main.c
|
|
@@ -3946,6 +3946,13 @@ static int gem_get_all_flow_entries(struct net_device *netdev,
|
|
return 0;
|
|
}
|
|
|
|
+static u32 gem_get_rx_ring_count(struct net_device *netdev)
|
|
+{
|
|
+ struct macb *bp = netdev_priv(netdev);
|
|
+
|
|
+ return bp->num_queues;
|
|
+}
|
|
+
|
|
static int gem_get_rxnfc(struct net_device *netdev, struct ethtool_rxnfc *cmd,
|
|
u32 *rule_locs)
|
|
{
|
|
@@ -3953,9 +3960,6 @@ static int gem_get_rxnfc(struct net_device *netdev, struct ethtool_rxnfc *cmd,
|
|
int ret = 0;
|
|
|
|
switch (cmd->cmd) {
|
|
- case ETHTOOL_GRXRINGS:
|
|
- cmd->data = bp->num_queues;
|
|
- break;
|
|
case ETHTOOL_GRXCLSRLCNT:
|
|
cmd->rule_cnt = bp->rx_fs_list.count;
|
|
break;
|
|
@@ -4040,6 +4044,7 @@ static const struct ethtool_ops gem_ethtool_ops = {
|
|
.set_ringparam = macb_set_ringparam,
|
|
.get_rxnfc = gem_get_rxnfc,
|
|
.set_rxnfc = gem_set_rxnfc,
|
|
+ .get_rx_ring_count = gem_get_rx_ring_count,
|
|
};
|
|
|
|
static int macb_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
|
|
@@ -4910,7 +4915,9 @@ static int at91ether_close(struct net_device *dev)
|
|
|
|
at91ether_stop(lp);
|
|
|
|
- return pm_runtime_put(&lp->pdev->dev);
|
|
+ pm_runtime_put(&lp->pdev->dev);
|
|
+
|
|
+ return 0;
|
|
}
|
|
|
|
/* Transmit packet */
|
|
@@ -5530,9 +5537,9 @@ static const struct macb_config default_gem_config = {
|
|
|
|
static int macb_probe(struct platform_device *pdev)
|
|
{
|
|
- const struct macb_config *macb_config = &default_gem_config;
|
|
- struct device_node *np = pdev->dev.of_node;
|
|
struct clk *pclk, *hclk = NULL, *tx_clk = NULL, *rx_clk = NULL;
|
|
+ struct device_node *np = pdev->dev.of_node;
|
|
+ const struct macb_config *macb_config;
|
|
struct clk *tsu_clk = NULL;
|
|
phy_interface_t interface;
|
|
struct net_device *dev;
|
|
@@ -5548,13 +5555,9 @@ static int macb_probe(struct platform_device *pdev)
|
|
if (IS_ERR(mem))
|
|
return PTR_ERR(mem);
|
|
|
|
- if (np) {
|
|
- const struct of_device_id *match;
|
|
-
|
|
- match = of_match_node(macb_dt_ids, np);
|
|
- if (match && match->data)
|
|
- macb_config = match->data;
|
|
- }
|
|
+ macb_config = of_device_get_match_data(&pdev->dev);
|
|
+ if (!macb_config)
|
|
+ macb_config = &default_gem_config;
|
|
|
|
err = macb_config->clk_init(pdev, &pclk, &hclk, &tx_clk, &rx_clk, &tsu_clk);
|
|
if (err)
|
|
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
|
|
index fd86f72f54aef..34dbf67c104b0 100644
|
|
--- a/drivers/pci/quirks.c
|
|
+++ b/drivers/pci/quirks.c
|
|
@@ -4481,6 +4481,30 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_BROADCOM, 0x9000,
|
|
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_BROADCOM, 0x9084,
|
|
quirk_bridge_cavm_thrx2_pcie_root);
|
|
|
|
+/*
|
|
+ * PCI BAR 5 is not setup correctly for the on-board AHCI controller
|
|
+ * on Broadcom's Vulcan processor. Added a quirk to fix BAR 5 by
|
|
+ * using BAR 4's resources which are populated correctly and NOT
|
|
+ * actually used by the AHCI controller.
|
|
+ */
|
|
+static void quirk_fix_vulcan_ahci_bars(struct pci_dev *dev)
|
|
+{
|
|
+ struct resource *r = &dev->resource[4];
|
|
+
|
|
+ if (!(r->flags & IORESOURCE_MEM) || (r->start == 0))
|
|
+ return;
|
|
+
|
|
+ /* Set BAR5 resource to BAR4 */
|
|
+ dev->resource[5] = *r;
|
|
+
|
|
+ /* Update BAR5 in pci config space */
|
|
+ pci_write_config_dword(dev, PCI_BASE_ADDRESS_5, r->start);
|
|
+
|
|
+ /* Clear BAR4's resource */
|
|
+ memset(r, 0, sizeof(*r));
|
|
+}
|
|
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_BROADCOM, 0x9027, quirk_fix_vulcan_ahci_bars);
|
|
+
|
|
/*
|
|
* Intersil/Techwell TW686[4589]-based video capture cards have an empty (zero)
|
|
* class code. Fix it.
|
|
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
|
|
index f50b92e632018..f1ca4960fc592 100644
|
|
--- a/drivers/scsi/sd.c
|
|
+++ b/drivers/scsi/sd.c
|
|
@@ -121,6 +121,14 @@ static const char *sd_cache_types[] = {
|
|
"write back, no read (daft)"
|
|
};
|
|
|
|
+static const char *sd_probe_types[] = { "async", "sync" };
|
|
+
|
|
+static char sd_probe_type[6] = "async";
|
|
+module_param_string(probe, sd_probe_type, sizeof(sd_probe_type),
|
|
+ S_IRUGO|S_IWUSR);
|
|
+MODULE_PARM_DESC(probe, "async or sync. Setting to 'sync' disables asynchronous "
|
|
+ "device number assignments (sda, sdb, ...).");
|
|
+
|
|
static void sd_set_flush_flag(struct scsi_disk *sdkp,
|
|
struct queue_limits *lim)
|
|
{
|
|
@@ -4417,6 +4425,8 @@ static int __init init_sd(void)
|
|
goto err_out_class;
|
|
}
|
|
|
|
+ if (!strcmp(sd_probe_type, "sync"))
|
|
+ sd_template.gendrv.probe_type = PROBE_FORCE_SYNCHRONOUS;
|
|
err = scsi_register_driver(&sd_template.gendrv);
|
|
if (err)
|
|
goto err_out_driver;
|
|
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
|
|
index be50d03034a96..9ce9b6518acd5 100644
|
|
--- a/drivers/usb/core/hub.c
|
|
+++ b/drivers/usb/core/hub.c
|
|
@@ -5894,6 +5894,13 @@ static void hub_event(struct work_struct *work)
|
|
(u16) hub->change_bits[0],
|
|
(u16) hub->event_bits[0]);
|
|
|
|
+ /* Don't disconnect USB-SATA on TrimSlice */
|
|
+ if (strcmp(dev_name(hdev->bus->controller), "tegra-ehci.0") == 0) {
|
|
+ if ((hdev->state == 7) && (hub->change_bits[0] == 0) &&
|
|
+ (hub->event_bits[0] == 0x2))
|
|
+ hub->event_bits[0] = 0;
|
|
+ }
|
|
+
|
|
/* Lock the device, then check to see if we were
|
|
* disconnected while waiting for the lock to succeed. */
|
|
usb_lock_device(hdev);
|
|
diff --git a/include/drm/display/drm_dp.h b/include/drm/display/drm_dp.h
|
|
index e4eebabab9759..8b15d3eeb716a 100644
|
|
--- a/include/drm/display/drm_dp.h
|
|
+++ b/include/drm/display/drm_dp.h
|
|
@@ -571,6 +571,8 @@
|
|
# define DP_PANEL_REPLAY_LINK_OFF_SUPPORTED_IN_PR_AFTER_ADAPTIVE_SYNC_SDP (1 << 7)
|
|
|
|
#define DP_PANEL_REPLAY_CAP_X_GRANULARITY 0xb2
|
|
+# define DP_PANEL_REPLAY_FULL_LINE_GRANULARITY 0xffff
|
|
+
|
|
#define DP_PANEL_REPLAY_CAP_Y_GRANULARITY 0xb4
|
|
|
|
/* Link Configuration */
|
|
diff --git a/include/linux/crypto.h b/include/linux/crypto.h
|
|
index a2137e19be7d8..79ccb6fabc108 100644
|
|
--- a/include/linux/crypto.h
|
|
+++ b/include/linux/crypto.h
|
|
@@ -152,6 +152,8 @@
|
|
#define CRYPTO_TFM_REQ_MAY_BACKLOG 0x00000400
|
|
#define CRYPTO_TFM_REQ_ON_STACK 0x00000800
|
|
|
|
+#define CRYPTO_TFM_FIPS_COMPLIANCE 0x80000000
|
|
+
|
|
/*
|
|
* Miscellaneous stuff.
|
|
*/
|
|
diff --git a/include/linux/efi.h b/include/linux/efi.h
|
|
index 2a43094e23f70..4fcf05f8232c6 100644
|
|
--- a/include/linux/efi.h
|
|
+++ b/include/linux/efi.h
|
|
@@ -45,6 +45,8 @@ struct screen_info;
|
|
#define EFI_ABORTED (21 | (1UL << (BITS_PER_LONG-1)))
|
|
#define EFI_SECURITY_VIOLATION (26 | (1UL << (BITS_PER_LONG-1)))
|
|
|
|
+#define EFI_IS_ERROR(x) ((x) & (1UL << (BITS_PER_LONG-1)))
|
|
+
|
|
typedef unsigned long efi_status_t;
|
|
typedef u8 efi_bool_t;
|
|
typedef u16 efi_char16_t; /* UNICODE character */
|
|
@@ -867,6 +869,14 @@ static inline int efi_range_is_wc(unsigned long start, unsigned long len)
|
|
#define EFI_MEM_ATTR 9 /* Did firmware publish an EFI_MEMORY_ATTRIBUTES table? */
|
|
#define EFI_MEM_NO_SOFT_RESERVE 10 /* Is the kernel configured to ignore soft reservations? */
|
|
#define EFI_PRESERVE_BS_REGIONS 11 /* Are EFI boot-services memory segments available? */
|
|
+#define EFI_SECURE_BOOT 12 /* Are we in Secure Boot mode? */
|
|
+
|
|
+enum efi_secureboot_mode {
|
|
+ efi_secureboot_mode_unset,
|
|
+ efi_secureboot_mode_unknown,
|
|
+ efi_secureboot_mode_disabled,
|
|
+ efi_secureboot_mode_enabled,
|
|
+};
|
|
|
|
#ifdef CONFIG_EFI
|
|
/*
|
|
@@ -878,6 +888,8 @@ static inline bool efi_enabled(int feature)
|
|
}
|
|
extern void efi_reboot(enum reboot_mode reboot_mode, const char *__unused);
|
|
|
|
+extern void __init efi_set_secure_boot(enum efi_secureboot_mode mode);
|
|
+
|
|
bool __pure __efi_soft_reserve_enabled(void);
|
|
|
|
static inline bool __pure efi_soft_reserve_enabled(void)
|
|
@@ -899,6 +911,8 @@ static inline bool efi_enabled(int feature)
|
|
static inline void
|
|
efi_reboot(enum reboot_mode reboot_mode, const char *__unused) {}
|
|
|
|
+static inline void efi_set_secure_boot(enum efi_secureboot_mode mode) {}
|
|
+
|
|
static inline bool efi_soft_reserve_enabled(void)
|
|
{
|
|
return false;
|
|
@@ -913,6 +927,7 @@ static inline void efi_find_mirror(void) {}
|
|
#endif
|
|
|
|
extern int efi_status_to_err(efi_status_t status);
|
|
+extern const char *efi_status_to_str(efi_status_t status);
|
|
|
|
/*
|
|
* Variable Attributes
|
|
@@ -1130,13 +1145,6 @@ extern unsigned long efi_call_virt_save_flags(void);
|
|
|
|
void efi_runtime_assert_lock_held(void);
|
|
|
|
-enum efi_secureboot_mode {
|
|
- efi_secureboot_mode_unset,
|
|
- efi_secureboot_mode_unknown,
|
|
- efi_secureboot_mode_disabled,
|
|
- efi_secureboot_mode_enabled,
|
|
-};
|
|
-
|
|
static inline
|
|
enum efi_secureboot_mode efi_get_secureboot_mode(efi_get_variable_t *get_var)
|
|
{
|
|
diff --git a/include/linux/lsm_hook_defs.h b/include/linux/lsm_hook_defs.h
|
|
index 8c42b4bde09c0..694ce5c5bcd43 100644
|
|
--- a/include/linux/lsm_hook_defs.h
|
|
+++ b/include/linux/lsm_hook_defs.h
|
|
@@ -446,6 +446,7 @@ LSM_HOOK(int, 0, bpf_token_capable, const struct bpf_token *token, int cap)
|
|
|
|
LSM_HOOK(int, 0, locked_down, enum lockdown_reason what)
|
|
|
|
+
|
|
#ifdef CONFIG_PERF_EVENTS
|
|
LSM_HOOK(int, 0, perf_event_open, int type)
|
|
LSM_HOOK(int, 0, perf_event_alloc, struct perf_event *event)
|
|
diff --git a/include/linux/mfd/bcm2835-pm.h b/include/linux/mfd/bcm2835-pm.h
|
|
index f70a810c55f7d..d2e17ab1dbfc5 100644
|
|
--- a/include/linux/mfd/bcm2835-pm.h
|
|
+++ b/include/linux/mfd/bcm2835-pm.h
|
|
@@ -5,11 +5,18 @@
|
|
|
|
#include <linux/regmap.h>
|
|
|
|
+enum bcm2835_soc {
|
|
+ BCM2835_PM_SOC_BCM2835,
|
|
+ BCM2835_PM_SOC_BCM2711,
|
|
+ BCM2835_PM_SOC_BCM2712,
|
|
+};
|
|
+
|
|
struct bcm2835_pm {
|
|
struct device *dev;
|
|
void __iomem *base;
|
|
void __iomem *asb;
|
|
void __iomem *rpivid_asb;
|
|
+ enum bcm2835_soc soc;
|
|
};
|
|
|
|
#endif /* BCM2835_MFD_PM_H */
|
|
diff --git a/include/linux/rmi.h b/include/linux/rmi.h
|
|
index ab7eea01ab427..fff7c5f737fc8 100644
|
|
--- a/include/linux/rmi.h
|
|
+++ b/include/linux/rmi.h
|
|
@@ -364,6 +364,7 @@ struct rmi_driver_data {
|
|
|
|
struct rmi4_attn_data attn_data;
|
|
DECLARE_KFIFO(attn_fifo, struct rmi4_attn_data, 16);
|
|
+ struct work_struct attn_work;
|
|
};
|
|
|
|
int rmi_register_transport_device(struct rmi_transport_dev *xport);
|
|
diff --git a/include/linux/security.h b/include/linux/security.h
|
|
index ee88dd2d2d1f7..5c816f0b8b671 100644
|
|
--- a/include/linux/security.h
|
|
+++ b/include/linux/security.h
|
|
@@ -2405,4 +2405,13 @@ static inline void security_initramfs_populated(void)
|
|
}
|
|
#endif /* CONFIG_SECURITY */
|
|
|
|
+#ifdef CONFIG_SECURITY_LOCKDOWN_LSM
|
|
+extern int security_lock_kernel_down(const char *where, enum lockdown_reason level);
|
|
+#else
|
|
+static inline int security_lock_kernel_down(const char *where, enum lockdown_reason level)
|
|
+{
|
|
+ return 0;
|
|
+}
|
|
+#endif /* CONFIG_SECURITY_LOCKDOWN_LSM */
|
|
+
|
|
#endif /* ! __LINUX_SECURITY_H */
|
|
diff --git a/kernel/module/signing.c b/kernel/module/signing.c
|
|
index a2ff4242e623d..f0d2be1ee4f1c 100644
|
|
--- a/kernel/module/signing.c
|
|
+++ b/kernel/module/signing.c
|
|
@@ -61,10 +61,17 @@ int mod_verify_sig(const void *mod, struct load_info *info)
|
|
modlen -= sig_len + sizeof(ms);
|
|
info->len = modlen;
|
|
|
|
- return verify_pkcs7_signature(mod, modlen, mod + modlen, sig_len,
|
|
+ ret = verify_pkcs7_signature(mod, modlen, mod + modlen, sig_len,
|
|
VERIFY_USE_SECONDARY_KEYRING,
|
|
VERIFYING_MODULE_SIGNATURE,
|
|
NULL, NULL);
|
|
+ if (ret == -ENOKEY && IS_ENABLED(CONFIG_INTEGRITY_PLATFORM_KEYRING)) {
|
|
+ ret = verify_pkcs7_signature(mod, modlen, mod + modlen, sig_len,
|
|
+ VERIFY_USE_PLATFORM_KEYRING,
|
|
+ VERIFYING_MODULE_SIGNATURE,
|
|
+ NULL, NULL);
|
|
+ }
|
|
+ return ret;
|
|
}
|
|
|
|
int module_sig_check(struct load_info *info, int flags)
|
|
diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib
|
|
index 28a1c08e3b221..3126a6fa63282 100644
|
|
--- a/scripts/Makefile.lib
|
|
+++ b/scripts/Makefile.lib
|
|
@@ -191,7 +191,10 @@ objtool-args-$(CONFIG_HAVE_STATIC_CALL_INLINE) += --static-call
|
|
objtool-args-$(CONFIG_HAVE_UACCESS_VALIDATION) += --uaccess
|
|
objtool-args-$(or $(CONFIG_GCOV_KERNEL),$(CONFIG_KCOV)) += --no-unreachable
|
|
objtool-args-$(CONFIG_PREFIX_SYMBOLS) += --prefix=$(CONFIG_FUNCTION_PADDING_BYTES)
|
|
+# RHEL-only: don't enforce OBJTOOL_WERROR for out of tree modules
|
|
+ifeq ($(KBUILD_EXTMOD),)
|
|
objtool-args-$(CONFIG_OBJTOOL_WERROR) += --werror
|
|
+endif
|
|
|
|
objtool-args = $(objtool-args-y) \
|
|
$(if $(delay-objtool), --link) \
|
|
diff --git a/scripts/tags.sh b/scripts/tags.sh
|
|
index 99ce427d9a69d..f191cd9d7ee6e 100755
|
|
--- a/scripts/tags.sh
|
|
+++ b/scripts/tags.sh
|
|
@@ -16,6 +16,8 @@ fi
|
|
ignore="$(echo "$RCS_FIND_IGNORE" | sed 's|\\||g' )"
|
|
# tags and cscope files should also ignore MODVERSION *.mod.c files
|
|
ignore="$ignore ( -name *.mod.c ) -prune -o"
|
|
+# RHEL tags and cscope should also ignore redhat/rpm
|
|
+ignore="$ignore ( -path redhat/rpm ) -prune -o"
|
|
|
|
# ignore arbitrary directories
|
|
if [ -n "${IGNORE_DIRS}" ]; then
|
|
diff --git a/security/integrity/platform_certs/load_uefi.c b/security/integrity/platform_certs/load_uefi.c
|
|
index d1fdd113450a6..182e8090cfe85 100644
|
|
--- a/security/integrity/platform_certs/load_uefi.c
|
|
+++ b/security/integrity/platform_certs/load_uefi.c
|
|
@@ -74,7 +74,8 @@ static __init void *get_cert_list(efi_char16_t *name, efi_guid_t *guid,
|
|
return NULL;
|
|
|
|
if (*status != EFI_BUFFER_TOO_SMALL) {
|
|
- pr_err("Couldn't get size: 0x%lx\n", *status);
|
|
+ pr_err("Couldn't get size: %s (0x%lx)\n",
|
|
+ efi_status_to_str(*status), *status);
|
|
return NULL;
|
|
}
|
|
|
|
@@ -85,7 +86,8 @@ static __init void *get_cert_list(efi_char16_t *name, efi_guid_t *guid,
|
|
*status = efi.get_variable(name, guid, NULL, &lsize, db);
|
|
if (*status != EFI_SUCCESS) {
|
|
kfree(db);
|
|
- pr_err("Error reading db var: 0x%lx\n", *status);
|
|
+ pr_err("Error reading db var: %s (0x%lx)\n",
|
|
+ efi_status_to_str(*status), *status);
|
|
return NULL;
|
|
}
|
|
|
|
diff --git a/security/lockdown/Kconfig b/security/lockdown/Kconfig
|
|
index e84ddf4840101..d0501353a4b95 100644
|
|
--- a/security/lockdown/Kconfig
|
|
+++ b/security/lockdown/Kconfig
|
|
@@ -16,6 +16,19 @@ config SECURITY_LOCKDOWN_LSM_EARLY
|
|
subsystem is fully initialised. If enabled, lockdown will
|
|
unconditionally be called before any other LSMs.
|
|
|
|
+config LOCK_DOWN_IN_EFI_SECURE_BOOT
|
|
+ bool "Lock down the kernel in EFI Secure Boot mode"
|
|
+ default n
|
|
+ depends on EFI && SECURITY_LOCKDOWN_LSM_EARLY
|
|
+ help
|
|
+ UEFI Secure Boot provides a mechanism for ensuring that the firmware
|
|
+ will only load signed bootloaders and kernels. Secure boot mode may
|
|
+ be determined from EFI variables provided by the system firmware if
|
|
+ not indicated by the boot parameters.
|
|
+
|
|
+ Enabling this option results in kernel lockdown being triggered if
|
|
+ EFI Secure Boot is set.
|
|
+
|
|
choice
|
|
prompt "Kernel default lockdown mode"
|
|
default LOCK_DOWN_KERNEL_FORCE_NONE
|
|
diff --git a/security/lockdown/lockdown.c b/security/lockdown/lockdown.c
|
|
index 8d46886d2cca0..14a9cdff942b9 100644
|
|
--- a/security/lockdown/lockdown.c
|
|
+++ b/security/lockdown/lockdown.c
|
|
@@ -72,6 +72,17 @@ static int lockdown_is_locked_down(enum lockdown_reason what)
|
|
return 0;
|
|
}
|
|
|
|
+/**
|
|
+ * security_lock_kernel_down() - Put the kernel into lock-down mode.
|
|
+ *
|
|
+ * @where: Where the lock-down is originating from (e.g. command line option)
|
|
+ * @level: The lock-down level (can only increase)
|
|
+ */
|
|
+int security_lock_kernel_down(const char *where, enum lockdown_reason level)
|
|
+{
|
|
+ return lock_kernel_down(where, level);
|
|
+}
|
|
+
|
|
static struct security_hook_list lockdown_hooks[] __ro_after_init = {
|
|
LSM_HOOK_INIT(locked_down, lockdown_is_locked_down),
|
|
};
|
|
diff --git a/sound/soc/sdca/sdca_class_function.c b/sound/soc/sdca/sdca_class_function.c
|
|
index 0028482a1e752..416948cfb5cb9 100644
|
|
--- a/sound/soc/sdca/sdca_class_function.c
|
|
+++ b/sound/soc/sdca/sdca_class_function.c
|
|
@@ -19,6 +19,7 @@
|
|
#include <sound/sdca_fdl.h>
|
|
#include <sound/sdca_function.h>
|
|
#include <sound/sdca_interrupts.h>
|
|
+#include <sound/sdca_jack.h>
|
|
#include <sound/sdca_regmap.h>
|
|
#include <sound/sdw.h>
|
|
#include <sound/soc-component.h>
|
|
@@ -195,6 +196,15 @@ static int class_function_component_probe(struct snd_soc_component *component)
|
|
return sdca_irq_populate(drv->function, component, core->irq_info);
|
|
}
|
|
|
|
+static int class_function_set_jack(struct snd_soc_component *component,
|
|
+ struct snd_soc_jack *jack, void *d)
|
|
+{
|
|
+ struct class_function_drv *drv = snd_soc_component_get_drvdata(component);
|
|
+ struct sdca_class_drv *core = drv->core;
|
|
+
|
|
+ return sdca_jack_set_jack(core->irq_info, jack);
|
|
+}
|
|
+
|
|
static const struct snd_soc_component_driver class_function_component_drv = {
|
|
.probe = class_function_component_probe,
|
|
.endianness = 1,
|
|
@@ -351,6 +361,9 @@ static int class_function_probe(struct auxiliary_device *auxdev,
|
|
return dev_err_probe(dev, PTR_ERR(drv->regmap),
|
|
"failed to create regmap");
|
|
|
|
+ if (desc->type == SDCA_FUNCTION_TYPE_UAJ)
|
|
+ cmp_drv->set_jack = class_function_set_jack;
|
|
+
|
|
ret = sdca_asoc_populate_component(dev, drv->function, cmp_drv,
|
|
&dais, &num_dais,
|
|
&class_function_sdw_ops);
|
|
diff --git a/tools/testing/selftests/bpf/Makefile b/tools/testing/selftests/bpf/Makefile
|
|
index 4aa60e83ff191..eaceb09e40290 100644
|
|
--- a/tools/testing/selftests/bpf/Makefile
|
|
+++ b/tools/testing/selftests/bpf/Makefile
|
|
@@ -492,7 +492,7 @@ LSKELS := fexit_sleep.c trace_printk.c trace_vprintk.c map_ptr_kern.c \
|
|
LSKELS_SIGNED := fentry_test.c fexit_test.c atomics.c
|
|
|
|
# Generate both light skeleton and libbpf skeleton for these
|
|
-LSKELS_EXTRA := test_ksyms_module.c test_ksyms_weak.c kfunc_call_test.c \
|
|
+LSKELS_EXTRA := test_ksyms_module.c kfunc_call_test.c \
|
|
kfunc_call_test_subprog.c
|
|
SKEL_BLACKLIST += $$(LSKELS) $$(LSKELS_SIGNED)
|
|
|
|
diff --git a/tools/testing/selftests/bpf/prog_tests/ksyms_btf.c b/tools/testing/selftests/bpf/prog_tests/ksyms_btf.c
|
|
index 1d7a2f1e07317..b22f3a9cb8b80 100644
|
|
--- a/tools/testing/selftests/bpf/prog_tests/ksyms_btf.c
|
|
+++ b/tools/testing/selftests/bpf/prog_tests/ksyms_btf.c
|
|
@@ -7,7 +7,6 @@
|
|
#include "test_ksyms_btf.skel.h"
|
|
#include "test_ksyms_btf_null_check.skel.h"
|
|
#include "test_ksyms_weak.skel.h"
|
|
-#include "test_ksyms_weak.lskel.h"
|
|
#include "test_ksyms_btf_write_check.skel.h"
|
|
|
|
static int duration;
|
|
@@ -111,33 +110,6 @@ static void test_weak_syms(void)
|
|
test_ksyms_weak__destroy(skel);
|
|
}
|
|
|
|
-static void test_weak_syms_lskel(void)
|
|
-{
|
|
- struct test_ksyms_weak_lskel *skel;
|
|
- struct test_ksyms_weak_lskel__data *data;
|
|
- int err;
|
|
-
|
|
- skel = test_ksyms_weak_lskel__open_and_load();
|
|
- if (!ASSERT_OK_PTR(skel, "test_ksyms_weak_lskel__open_and_load"))
|
|
- return;
|
|
-
|
|
- err = test_ksyms_weak_lskel__attach(skel);
|
|
- if (!ASSERT_OK(err, "test_ksyms_weak_lskel__attach"))
|
|
- goto cleanup;
|
|
-
|
|
- /* trigger tracepoint */
|
|
- usleep(1);
|
|
-
|
|
- data = skel->data;
|
|
- ASSERT_EQ(data->out__existing_typed, 0, "existing typed ksym");
|
|
- ASSERT_NEQ(data->out__existing_typeless, -1, "existing typeless ksym");
|
|
- ASSERT_EQ(data->out__non_existent_typeless, 0, "nonexistent typeless ksym");
|
|
- ASSERT_EQ(data->out__non_existent_typed, 0, "nonexistent typed ksym");
|
|
-
|
|
-cleanup:
|
|
- test_ksyms_weak_lskel__destroy(skel);
|
|
-}
|
|
-
|
|
static void test_write_check(bool test_handler1)
|
|
{
|
|
struct test_ksyms_btf_write_check *skel;
|
|
@@ -180,9 +152,6 @@ void test_ksyms_btf(void)
|
|
if (test__start_subtest("weak_ksyms"))
|
|
test_weak_syms();
|
|
|
|
- if (test__start_subtest("weak_ksyms_lskel"))
|
|
- test_weak_syms_lskel();
|
|
-
|
|
if (test__start_subtest("write_check1"))
|
|
test_write_check(true);
|
|
|